summaryrefslogtreecommitdiff
path: root/bfd
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@baserock.org>2014-12-23 14:38:46 +0000
committer <>2015-05-26 15:48:41 +0000
commit5500a97a2ad1735db5b35bc51cfb825c1f4c38df (patch)
treecc6e777c26142b88456ff03a672e1cb69215fc32 /bfd
downloadbinutils-tarball-master.tar.gz
Imported from /home/lorry/working-area/delta_binutils-tarball/binutils-2.25.tar.bz2.HEADbinutils-2.25master
Diffstat (limited to 'bfd')
-rw-r--r--bfd/.gitignore40
-rw-r--r--bfd/COPYING674
-rw-r--r--bfd/ChangeLog2796
-rw-r--r--bfd/ChangeLog-00019598
-rw-r--r--bfd/ChangeLog-020311411
-rw-r--r--bfd/ChangeLog-20045069
-rw-r--r--bfd/ChangeLog-20055275
-rw-r--r--bfd/ChangeLog-20063607
-rw-r--r--bfd/ChangeLog-20073567
-rw-r--r--bfd/ChangeLog-20083392
-rw-r--r--bfd/ChangeLog-20095161
-rw-r--r--bfd/ChangeLog-20103568
-rw-r--r--bfd/ChangeLog-20113389
-rw-r--r--bfd/ChangeLog-20123300
-rw-r--r--bfd/ChangeLog-20133239
-rw-r--r--bfd/ChangeLog-91937854
-rw-r--r--bfd/ChangeLog-949510049
-rw-r--r--bfd/ChangeLog-96976735
-rw-r--r--bfd/ChangeLog-98995605
-rw-r--r--bfd/MAINTAINERS7
-rw-r--r--bfd/Makefile.am1059
-rw-r--r--bfd/Makefile.in2123
-rw-r--r--bfd/PORTING89
-rw-r--r--bfd/README55
-rw-r--r--bfd/TODO27
-rw-r--r--bfd/acinclude.m491
-rw-r--r--bfd/aclocal.m4989
-rw-r--r--bfd/aix386-core.c269
-rw-r--r--bfd/aix5ppc-core.c357
-rw-r--r--bfd/aout-adobe.c518
-rw-r--r--bfd/aout-arm.c548
-rw-r--r--bfd/aout-cris.c289
-rw-r--r--bfd/aout-ns32k.c364
-rw-r--r--bfd/aout-sparcle.c37
-rw-r--r--bfd/aout-target.h680
-rw-r--r--bfd/aout-tic30.c1112
-rw-r--r--bfd/aout0.c38
-rw-r--r--bfd/aout32.c24
-rw-r--r--bfd/aout64.c32
-rw-r--r--bfd/aoutf1.h792
-rw-r--r--bfd/aoutx.h5650
-rw-r--r--bfd/archive.c2766
-rw-r--r--bfd/archive64.c240
-rw-r--r--bfd/archures.c1401
-rw-r--r--bfd/armnetbsd.c39
-rw-r--r--bfd/bfd-in.h1013
-rw-r--r--bfd/bfd-in2.h7279
-rw-r--r--bfd/bfd.c1925
-rw-r--r--bfd/bfd.m461
-rw-r--r--bfd/bfdio.c621
-rw-r--r--bfd/bfdwin.c263
-rw-r--r--bfd/binary.c368
-rw-r--r--bfd/bout.c1481
-rw-r--r--bfd/cache.c644
-rw-r--r--bfd/cf-i386lynx.c34
-rw-r--r--bfd/cf-sparclynx.c29
-rw-r--r--bfd/cisco-core.c418
-rw-r--r--bfd/coff-alpha.c2392
-rw-r--r--bfd/coff-apollo.c120
-rw-r--r--bfd/coff-arm.c2560
-rw-r--r--bfd/coff-aux.c145
-rw-r--r--bfd/coff-go32.c45
-rw-r--r--bfd/coff-h8300.c1417
-rw-r--r--bfd/coff-h8500.c304
-rw-r--r--bfd/coff-i386.c679
-rw-r--r--bfd/coff-i860.c709
-rw-r--r--bfd/coff-i960.c659
-rw-r--r--bfd/coff-ia64.c202
-rw-r--r--bfd/coff-m68k.c542
-rw-r--r--bfd/coff-m88k.c284
-rw-r--r--bfd/coff-mcore.c560
-rw-r--r--bfd/coff-mips.c1500
-rw-r--r--bfd/coff-ppc.c2592
-rw-r--r--bfd/coff-rs6000.c4400
-rw-r--r--bfd/coff-sh.c3206
-rw-r--r--bfd/coff-sparc.c208
-rw-r--r--bfd/coff-stgo32.c424
-rw-r--r--bfd/coff-svm68k.c27
-rw-r--r--bfd/coff-tic30.c222
-rw-r--r--bfd/coff-tic4x.c290
-rw-r--r--bfd/coff-tic54x.c672
-rw-r--r--bfd/coff-tic80.c712
-rw-r--r--bfd/coff-u68k.c36
-rw-r--r--bfd/coff-w65.c377
-rw-r--r--bfd/coff-we32k.c73
-rw-r--r--bfd/coff-x86_64.c799
-rw-r--r--bfd/coff-z80.c289
-rw-r--r--bfd/coff-z8k.c387
-rw-r--r--bfd/coff64-rs6000.c3021
-rw-r--r--bfd/coffcode.h6134
-rw-r--r--bfd/coffgen.c2681
-rw-r--r--bfd/cofflink.c3119
-rw-r--r--bfd/coffswap.h840
-rw-r--r--bfd/compress.c438
-rw-r--r--bfd/config.bfd1759
-rw-r--r--bfd/config.in386
-rwxr-xr-xbfd/configure18897
-rw-r--r--bfd/configure.ac1199
-rw-r--r--bfd/configure.com407
-rw-r--r--bfd/configure.host102
-rw-r--r--bfd/corefile.c190
-rw-r--r--bfd/cpu-aarch64.c127
-rw-r--r--bfd/cpu-alpha.c53
-rw-r--r--bfd/cpu-arc.c71
-rw-r--r--bfd/cpu-arm.c433
-rw-r--r--bfd/cpu-avr.c163
-rw-r--r--bfd/cpu-bfin.c41
-rw-r--r--bfd/cpu-cr16.c41
-rw-r--r--bfd/cpu-cr16c.c40
-rw-r--r--bfd/cpu-cris.c109
-rw-r--r--bfd/cpu-crx.c41
-rw-r--r--bfd/cpu-d10v.c75
-rw-r--r--bfd/cpu-d30v.c41
-rw-r--r--bfd/cpu-dlx.c41
-rw-r--r--bfd/cpu-epiphany.c58
-rw-r--r--bfd/cpu-fr30.c40
-rw-r--r--bfd/cpu-frv.c65
-rw-r--r--bfd/cpu-h8300.c268
-rw-r--r--bfd/cpu-h8500.c59
-rw-r--r--bfd/cpu-hppa.c93
-rw-r--r--bfd/cpu-i370.c77
-rw-r--r--bfd/cpu-i386.c302
-rw-r--r--bfd/cpu-i860.c42
-rw-r--r--bfd/cpu-i960.c172
-rw-r--r--bfd/cpu-ia64-opc.c669
-rw-r--r--bfd/cpu-ia64.c60
-rw-r--r--bfd/cpu-ip2k.c57
-rw-r--r--bfd/cpu-iq2000.c59
-rw-r--r--bfd/cpu-k1om.c60
-rw-r--r--bfd/cpu-l1om.c60
-rw-r--r--bfd/cpu-lm32.c42
-rw-r--r--bfd/cpu-m10200.c40
-rw-r--r--bfd/cpu-m10300.c74
-rw-r--r--bfd/cpu-m32c.c72
-rw-r--r--bfd/cpu-m32r.c39
-rw-r--r--bfd/cpu-m68hc11.c40
-rw-r--r--bfd/cpu-m68hc12.c57
-rw-r--r--bfd/cpu-m68k.c273
-rw-r--r--bfd/cpu-m88k.c41
-rw-r--r--bfd/cpu-m9s12x.c41
-rw-r--r--bfd/cpu-m9s12xg.c41
-rw-r--r--bfd/cpu-mcore.c40
-rw-r--r--bfd/cpu-mep.c30
-rw-r--r--bfd/cpu-metag.c41
-rw-r--r--bfd/cpu-microblaze.c41
-rw-r--r--bfd/cpu-mips.c164
-rw-r--r--bfd/cpu-mmix.c43
-rw-r--r--bfd/cpu-moxie.c41
-rw-r--r--bfd/cpu-msp430.c138
-rw-r--r--bfd/cpu-mt.c75
-rw-r--r--bfd/cpu-nds32.c45
-rw-r--r--bfd/cpu-nios2.c44
-rw-r--r--bfd/cpu-ns32k.c809
-rw-r--r--bfd/cpu-or1k.c59
-rw-r--r--bfd/cpu-pdp11.c41
-rw-r--r--bfd/cpu-pj.c41
-rw-r--r--bfd/cpu-plugin.c40
-rw-r--r--bfd/cpu-powerpc.c418
-rw-r--r--bfd/cpu-rl78.c40
-rw-r--r--bfd/cpu-rs6000.c113
-rw-r--r--bfd/cpu-rx.c59
-rw-r--r--bfd/cpu-s390.c66
-rw-r--r--bfd/cpu-score.c69
-rw-r--r--bfd/cpu-sh.c545
-rw-r--r--bfd/cpu-sparc.c179
-rw-r--r--bfd/cpu-spu.c55
-rw-r--r--bfd/cpu-tic30.c40
-rw-r--r--bfd/cpu-tic4x.c83
-rw-r--r--bfd/cpu-tic54x.c40
-rw-r--r--bfd/cpu-tic6x.c40
-rw-r--r--bfd/cpu-tic80.c41
-rw-r--r--bfd/cpu-tilegx.c57
-rw-r--r--bfd/cpu-tilepro.c40
-rw-r--r--bfd/cpu-v850.c46
-rw-r--r--bfd/cpu-v850_rh850.c41
-rw-r--r--bfd/cpu-vax.c41
-rw-r--r--bfd/cpu-w65.c52
-rw-r--r--bfd/cpu-we32k.c41
-rw-r--r--bfd/cpu-xc16x.c76
-rw-r--r--bfd/cpu-xgate.c40
-rw-r--r--bfd/cpu-xstormy16.c40
-rw-r--r--bfd/cpu-xtensa.c40
-rw-r--r--bfd/cpu-z80.c57
-rw-r--r--bfd/cpu-z8k.c48
-rw-r--r--bfd/demo64.c30
-rw-r--r--bfd/dep-in.sed28
-rw-r--r--bfd/development.sh19
-rw-r--r--bfd/doc/ChangeLog318
-rw-r--r--bfd/doc/ChangeLog-9103600
-rw-r--r--bfd/doc/Makefile.am348
-rw-r--r--bfd/doc/Makefile.in987
-rw-r--r--bfd/doc/aoutx.texi213
-rw-r--r--bfd/doc/archive.texi105
-rw-r--r--bfd/doc/archures.texi720
-rw-r--r--bfd/doc/bfd.info13716
-rw-r--r--bfd/doc/bfd.texinfo341
-rw-r--r--bfd/doc/bfdint.texi1898
-rw-r--r--bfd/doc/bfdio.texi95
-rw-r--r--bfd/doc/bfdsumm.texi150
-rw-r--r--bfd/doc/bfdt.texi896
-rw-r--r--bfd/doc/bfdver.texi4
-rw-r--r--bfd/doc/bfdwin.texi2
-rw-r--r--bfd/doc/cache.texi65
-rw-r--r--bfd/doc/chew.c1585
-rw-r--r--bfd/doc/coffcode.texi693
-rw-r--r--bfd/doc/core.texi70
-rw-r--r--bfd/doc/doc.str158
-rw-r--r--bfd/doc/elf.texi9
-rw-r--r--bfd/doc/elfcode.texi0
-rw-r--r--bfd/doc/fdl.texi506
-rw-r--r--bfd/doc/format.texi112
-rw-r--r--bfd/doc/hash.texi247
-rw-r--r--bfd/doc/header.sed13
-rw-r--r--bfd/doc/init.texi16
-rw-r--r--bfd/doc/libbfd.texi179
-rw-r--r--bfd/doc/linker.texi420
-rw-r--r--bfd/doc/makefile.vms22
-rw-r--r--bfd/doc/mmo.texi369
-rw-r--r--bfd/doc/opncls.texi456
-rw-r--r--bfd/doc/proto.str135
-rw-r--r--bfd/doc/reloc.texi4104
-rw-r--r--bfd/doc/section.texi1062
-rw-r--r--bfd/doc/syms.texi480
-rw-r--r--bfd/doc/targets.texi614
-rw-r--r--bfd/dwarf1.c563
-rw-r--r--bfd/dwarf2.c3987
-rw-r--r--bfd/ecoff.c4454
-rw-r--r--bfd/ecofflink.c2477
-rw-r--r--bfd/ecoffswap.h772
-rw-r--r--bfd/elf-attrs.c705
-rw-r--r--bfd/elf-bfd.h2531
-rw-r--r--bfd/elf-eh-frame.c1920
-rw-r--r--bfd/elf-hppa.h1219
-rw-r--r--bfd/elf-ifunc.c400
-rw-r--r--bfd/elf-linux-psinfo.h127
-rw-r--r--bfd/elf-m10200.c1394
-rw-r--r--bfd/elf-m10300.c5628
-rw-r--r--bfd/elf-nacl.c355
-rw-r--r--bfd/elf-nacl.h25
-rw-r--r--bfd/elf-s390-common.c244
-rw-r--r--bfd/elf-strtab.c420
-rw-r--r--bfd/elf-vxworks.c301
-rw-r--r--bfd/elf-vxworks.h38
-rw-r--r--bfd/elf.c10171
-rw-r--r--bfd/elf32-am33lin.c105
-rw-r--r--bfd/elf32-arc.c252
-rw-r--r--bfd/elf32-arm.c16758
-rw-r--r--bfd/elf32-avr.c3348
-rw-r--r--bfd/elf32-avr.h38
-rw-r--r--bfd/elf32-bfin.c5753
-rw-r--r--bfd/elf32-cr16.c2992
-rw-r--r--bfd/elf32-cr16c.c961
-rw-r--r--bfd/elf32-cris.c4412
-rw-r--r--bfd/elf32-crx.c1330
-rw-r--r--bfd/elf32-d10v.c556
-rw-r--r--bfd/elf32-d30v.c550
-rw-r--r--bfd/elf32-dlx.c580
-rw-r--r--bfd/elf32-epiphany.c608
-rw-r--r--bfd/elf32-fr30.c721
-rw-r--r--bfd/elf32-frv.c6878
-rw-r--r--bfd/elf32-gen.c102
-rw-r--r--bfd/elf32-h8300.c1746
-rw-r--r--bfd/elf32-hppa.c4693
-rw-r--r--bfd/elf32-hppa.h77
-rw-r--r--bfd/elf32-i370.c1408
-rw-r--r--bfd/elf32-i386.c5441
-rw-r--r--bfd/elf32-i860.c1268
-rw-r--r--bfd/elf32-i960.c167
-rw-r--r--bfd/elf32-ip2k.c1518
-rw-r--r--bfd/elf32-iq2000.c915
-rw-r--r--bfd/elf32-lm32.c2726
-rw-r--r--bfd/elf32-m32c.c2080
-rw-r--r--bfd/elf32-m32r.c4082
-rw-r--r--bfd/elf32-m68hc11.c1314
-rw-r--r--bfd/elf32-m68hc12.c664
-rw-r--r--bfd/elf32-m68hc1x.c1501
-rw-r--r--bfd/elf32-m68hc1x.h192
-rw-r--r--bfd/elf32-m68k.c4902
-rw-r--r--bfd/elf32-m88k.c38
-rw-r--r--bfd/elf32-mcore.c675
-rw-r--r--bfd/elf32-mep.c769
-rw-r--r--bfd/elf32-metag.c4329
-rw-r--r--bfd/elf32-metag.h38
-rw-r--r--bfd/elf32-microblaze.c3509
-rw-r--r--bfd/elf32-mips.c2624
-rw-r--r--bfd/elf32-moxie.c389
-rw-r--r--bfd/elf32-msp430.c2477
-rw-r--r--bfd/elf32-mt.c601
-rw-r--r--bfd/elf32-nds32.c15722
-rw-r--r--bfd/elf32-nds32.h155
-rw-r--r--bfd/elf32-nios2.c5311
-rw-r--r--bfd/elf32-nios2.h38
-rw-r--r--bfd/elf32-or1k.c2853
-rw-r--r--bfd/elf32-pj.c352
-rw-r--r--bfd/elf32-ppc.c10521
-rw-r--r--bfd/elf32-ppc.h56
-rw-r--r--bfd/elf32-rl78.c2459
-rw-r--r--bfd/elf32-rx.c3987
-rw-r--r--bfd/elf32-rx.h21
-rw-r--r--bfd/elf32-s390.c4035
-rw-r--r--bfd/elf32-score.c4515
-rw-r--r--bfd/elf32-score.h152
-rw-r--r--bfd/elf32-score7.c3885
-rw-r--r--bfd/elf32-sh-relocs.h1880
-rw-r--r--bfd/elf32-sh-symbian.c612
-rw-r--r--bfd/elf32-sh.c7578
-rw-r--r--bfd/elf32-sh64-com.c245
-rw-r--r--bfd/elf32-sh64.c813
-rw-r--r--bfd/elf32-sh64.h88
-rw-r--r--bfd/elf32-sparc.c330
-rw-r--r--bfd/elf32-spu.c5484
-rw-r--r--bfd/elf32-spu.h124
-rw-r--r--bfd/elf32-tic6x.c4445
-rw-r--r--bfd/elf32-tic6x.h34
-rw-r--r--bfd/elf32-tilegx.c134
-rw-r--r--bfd/elf32-tilegx.h38
-rw-r--r--bfd/elf32-tilepro.c4066
-rw-r--r--bfd/elf32-tilepro.h38
-rw-r--r--bfd/elf32-v850.c3929
-rw-r--r--bfd/elf32-vax.c2063
-rw-r--r--bfd/elf32-xc16x.c477
-rw-r--r--bfd/elf32-xgate.c729
-rw-r--r--bfd/elf32-xgate.h143
-rw-r--r--bfd/elf32-xstormy16.c1040
-rw-r--r--bfd/elf32-xtensa.c10857
-rw-r--r--bfd/elf32.c23
-rw-r--r--bfd/elf64-alpha.c5598
-rw-r--r--bfd/elf64-gen.c102
-rw-r--r--bfd/elf64-hppa.c4112
-rw-r--r--bfd/elf64-hppa.h51
-rw-r--r--bfd/elf64-ia64-vms.c5608
-rw-r--r--bfd/elf64-mips.c4549
-rw-r--r--bfd/elf64-mmix.c2938
-rw-r--r--bfd/elf64-ppc.c15261
-rw-r--r--bfd/elf64-ppc.h95
-rw-r--r--bfd/elf64-s390.c3862
-rw-r--r--bfd/elf64-sh64.c4060
-rw-r--r--bfd/elf64-sparc.c956
-rw-r--r--bfd/elf64-tilegx.c135
-rw-r--r--bfd/elf64-tilegx.h38
-rw-r--r--bfd/elf64-x86-64.c6129
-rw-r--r--bfd/elf64.c23
-rw-r--r--bfd/elfcode.h1900
-rw-r--r--bfd/elfcore.h319
-rw-r--r--bfd/elflink.c13064
-rw-r--r--bfd/elfn32-mips.c3742
-rw-r--r--bfd/elfnn-aarch64.c7966
-rw-r--r--bfd/elfnn-ia64.c5110
-rw-r--r--bfd/elfxx-aarch64.c604
-rw-r--r--bfd/elfxx-aarch64.h54
-rw-r--r--bfd/elfxx-ia64.c764
-rw-r--r--bfd/elfxx-ia64.h33
-rw-r--r--bfd/elfxx-mips.c16088
-rw-r--r--bfd/elfxx-mips.h191
-rw-r--r--bfd/elfxx-sparc.c4926
-rw-r--r--bfd/elfxx-sparc.h148
-rw-r--r--bfd/elfxx-target.h998
-rw-r--r--bfd/elfxx-tilegx.c4440
-rw-r--r--bfd/elfxx-tilegx.h99
-rw-r--r--bfd/epoc-pe-arm.c38
-rw-r--r--bfd/epoc-pei-arm.c31
-rw-r--r--bfd/format.c560
-rw-r--r--bfd/freebsd.h106
-rw-r--r--bfd/gen-aout.c120
-rw-r--r--bfd/genlink.h110
-rw-r--r--bfd/go32stub.h128
-rw-r--r--bfd/hash.c912
-rw-r--r--bfd/host-aout.c87
-rw-r--r--bfd/hosts/alphalinux.h25
-rw-r--r--bfd/hosts/alphavms.h62
-rw-r--r--bfd/hosts/decstation.h36
-rw-r--r--bfd/hosts/delta68.h33
-rw-r--r--bfd/hosts/dpx2.h27
-rw-r--r--bfd/hosts/hp300bsd.h32
-rw-r--r--bfd/hosts/i386bsd.h51
-rw-r--r--bfd/hosts/i386linux.h27
-rw-r--r--bfd/hosts/i386mach3.h44
-rw-r--r--bfd/hosts/i386sco.h38
-rw-r--r--bfd/hosts/i860mach3.h46
-rw-r--r--bfd/hosts/m68kaux.h35
-rw-r--r--bfd/hosts/m68klinux.h25
-rw-r--r--bfd/hosts/m88kmach3.h30
-rw-r--r--bfd/hosts/mipsbsd.h31
-rw-r--r--bfd/hosts/mipsmach3.h29
-rw-r--r--bfd/hosts/news-mips.h31
-rw-r--r--bfd/hosts/news.h28
-rw-r--r--bfd/hosts/pc532mach.h43
-rw-r--r--bfd/hosts/riscos.h29
-rw-r--r--bfd/hosts/symmetry.h39
-rw-r--r--bfd/hosts/tahoe.h31
-rw-r--r--bfd/hosts/vaxbsd.h31
-rw-r--r--bfd/hosts/vaxlinux.h21
-rw-r--r--bfd/hosts/vaxult.h27
-rw-r--r--bfd/hosts/vaxult2.h27
-rw-r--r--bfd/hosts/x86-64linux.h232
-rw-r--r--bfd/hp300bsd.c40
-rw-r--r--bfd/hp300hpux.c857
-rw-r--r--bfd/hppabsd-core.c269
-rw-r--r--bfd/hpux-core.c428
-rw-r--r--bfd/i386aout.c88
-rw-r--r--bfd/i386bsd.c50
-rw-r--r--bfd/i386dynix.c82
-rw-r--r--bfd/i386freebsd.c38
-rw-r--r--bfd/i386linux.c733
-rw-r--r--bfd/i386lynx.c550
-rw-r--r--bfd/i386mach3.c73
-rw-r--r--bfd/i386msdos.c233
-rw-r--r--bfd/i386netbsd.c38
-rw-r--r--bfd/i386os9k.c224
-rw-r--r--bfd/ieee.c3854
-rw-r--r--bfd/ihex.c1000
-rw-r--r--bfd/init.c54
-rw-r--r--bfd/irix-core.c333
-rw-r--r--bfd/libaout.h689
-rw-r--r--bfd/libbfd-in.h839
-rw-r--r--bfd/libbfd.c1115
-rw-r--r--bfd/libbfd.h3001
-rw-r--r--bfd/libcoff-in.h623
-rw-r--r--bfd/libcoff.h982
-rw-r--r--bfd/libecoff.h346
-rw-r--r--bfd/libhppa.h594
-rw-r--r--bfd/libieee.h135
-rw-r--r--bfd/libnlm.h222
-rw-r--r--bfd/liboasys.h83
-rw-r--r--bfd/libpei.h367
-rw-r--r--bfd/libxcoff.h260
-rw-r--r--bfd/linker.c3303
-rw-r--r--bfd/lynx-core.c226
-rw-r--r--bfd/m68k4knetbsd.c36
-rw-r--r--bfd/m68klinux.c736
-rw-r--r--bfd/m68knetbsd.c38
-rw-r--r--bfd/m88kmach3.c41
-rw-r--r--bfd/m88kopenbsd.c34
-rw-r--r--bfd/mach-o-i386.c404
-rw-r--r--bfd/mach-o-target.c189
-rw-r--r--bfd/mach-o-x86-64.c363
-rw-r--r--bfd/mach-o.c5797
-rw-r--r--bfd/mach-o.h749
-rw-r--r--bfd/makefile.vms66
-rwxr-xr-xbfd/mep-relocs.pl275
-rw-r--r--bfd/merge.c900
-rw-r--r--bfd/mipsbsd.c485
-rw-r--r--bfd/mmo.c3313
-rw-r--r--bfd/netbsd-core.c318
-rw-r--r--bfd/netbsd.h119
-rw-r--r--bfd/newsos3.c43
-rw-r--r--bfd/nlm-target.h261
-rw-r--r--bfd/nlm.c55
-rw-r--r--bfd/nlm32-alpha.c859
-rw-r--r--bfd/nlm32-i386.c429
-rw-r--r--bfd/nlm32-ppc.c986
-rw-r--r--bfd/nlm32-sparc.c378
-rw-r--r--bfd/nlm32.c22
-rw-r--r--bfd/nlm64.c22
-rw-r--r--bfd/nlmcode.h1980
-rw-r--r--bfd/nlmswap.h153
-rw-r--r--bfd/ns32k.h30
-rw-r--r--bfd/ns32knetbsd.c53
-rw-r--r--bfd/oasys.c1250
-rw-r--r--bfd/opncls.c1691
-rw-r--r--bfd/osf-core.c225
-rw-r--r--bfd/pc532-mach.c108
-rw-r--r--bfd/pdp11.c4547
-rw-r--r--bfd/pe-arm-wince.c45
-rw-r--r--bfd/pe-arm.c67
-rw-r--r--bfd/pe-i386.c45
-rw-r--r--bfd/pe-mcore.c41
-rw-r--r--bfd/pe-mips.c922
-rw-r--r--bfd/pe-ppc.c47
-rw-r--r--bfd/pe-sh.c31
-rw-r--r--bfd/pe-x86_64.c114
-rw-r--r--bfd/peXXigen.c4470
-rw-r--r--bfd/pef-traceback.h216
-rw-r--r--bfd/pef.c1198
-rw-r--r--bfd/pef.h187
-rw-r--r--bfd/pei-arm-wince.c31
-rw-r--r--bfd/pei-arm.c55
-rw-r--r--bfd/pei-i386.c45
-rw-r--r--bfd/pei-ia64.c38
-rw-r--r--bfd/pei-mcore.c43
-rw-r--r--bfd/pei-mips.c32
-rw-r--r--bfd/pei-ppc.c50
-rw-r--r--bfd/pei-sh.c35
-rw-r--r--bfd/pei-x86_64.c656
-rw-r--r--bfd/peicode.h1356
-rw-r--r--bfd/plugin.c561
-rw-r--r--bfd/plugin.h36
-rw-r--r--bfd/po/BLD-POTFILES.in12
-rw-r--r--bfd/po/Make-in298
-rw-r--r--bfd/po/SRC-POTFILES.in378
-rw-r--r--bfd/po/bfd.pot6710
-rw-r--r--bfd/po/da.gmobin0 -> 134131 bytes
-rw-r--r--bfd/po/da.po6159
-rw-r--r--bfd/po/es.gmobin0 -> 150305 bytes
-rw-r--r--bfd/po/es.po6693
-rw-r--r--bfd/po/fi.gmobin0 -> 162650 bytes
-rw-r--r--bfd/po/fi.po6918
-rw-r--r--bfd/po/fr.gmobin0 -> 151850 bytes
-rw-r--r--bfd/po/fr.po6352
-rw-r--r--bfd/po/id.gmobin0 -> 105891 bytes
-rw-r--r--bfd/po/id.po4163
-rw-r--r--bfd/po/ja.gmobin0 -> 134623 bytes
-rw-r--r--bfd/po/ja.po6182
-rw-r--r--bfd/po/ro.gmobin0 -> 69038 bytes
-rw-r--r--bfd/po/ro.po3026
-rw-r--r--bfd/po/ru.gmobin0 -> 186835 bytes
-rw-r--r--bfd/po/ru.po6350
-rw-r--r--bfd/po/rw.gmobin0 -> 429 bytes
-rw-r--r--bfd/po/rw.po3101
-rw-r--r--bfd/po/sv.gmobin0 -> 67266 bytes
-rw-r--r--bfd/po/sv.po3221
-rw-r--r--bfd/po/tr.gmobin0 -> 69529 bytes
-rw-r--r--bfd/po/tr.po3193
-rw-r--r--bfd/po/uk.gmobin0 -> 190915 bytes
-rw-r--r--bfd/po/uk.po6256
-rw-r--r--bfd/po/vi.gmobin0 -> 159371 bytes
-rw-r--r--bfd/po/vi.po6344
-rw-r--r--bfd/po/zh_CN.gmobin0 -> 28121 bytes
-rw-r--r--bfd/po/zh_CN.po2702
-rw-r--r--bfd/ppcboot.c526
-rw-r--r--bfd/ptrace-core.c217
-rw-r--r--bfd/reloc.c7673
-rw-r--r--bfd/reloc16.c332
-rw-r--r--bfd/riscix.c655
-rw-r--r--bfd/rs6000-core.c751
-rw-r--r--bfd/sco5-core.c396
-rw-r--r--bfd/section.c1657
-rw-r--r--bfd/simple.c285
-rw-r--r--bfd/som.c6814
-rw-r--r--bfd/som.h238
-rw-r--r--bfd/sparclinux.c729
-rw-r--r--bfd/sparclynx.c246
-rw-r--r--bfd/sparcnetbsd.c39
-rw-r--r--bfd/srec.c1392
-rw-r--r--bfd/stab-syms.c59
-rw-r--r--bfd/stabs.c788
-rw-r--r--bfd/stamp-h.in1
-rw-r--r--bfd/sunos.c2845
-rw-r--r--bfd/syms.c1413
-rw-r--r--bfd/sysdep.h213
-rw-r--r--bfd/targets.c1814
-rw-r--r--bfd/targmatch.sed33
-rw-r--r--bfd/tekhex.c1035
-rw-r--r--bfd/trad-core.c317
-rw-r--r--bfd/vax1knetbsd.c38
-rw-r--r--bfd/vaxbsd.c40
-rw-r--r--bfd/vaxnetbsd.c38
-rw-r--r--bfd/verilog.c373
-rw-r--r--bfd/versados.c877
-rw-r--r--bfd/version.h4
-rw-r--r--bfd/version.m41
-rw-r--r--bfd/vms-alpha.c9278
-rw-r--r--bfd/vms-lib.c2351
-rw-r--r--bfd/vms-misc.c670
-rw-r--r--bfd/vms.h142
-rw-r--r--bfd/warning.m480
-rw-r--r--bfd/xcofflink.c6453
-rw-r--r--bfd/xsym.c2354
-rw-r--r--bfd/xsym.h700
-rw-r--r--bfd/xtensa-isa.c1793
-rw-r--r--bfd/xtensa-modules.c21292
561 files changed, 798357 insertions, 0 deletions
diff --git a/bfd/.gitignore b/bfd/.gitignore
new file mode 100644
index 0000000..3316133
--- /dev/null
+++ b/bfd/.gitignore
@@ -0,0 +1,40 @@
+/bfd-in3.h
+/bfd.h
+/bfd_stdint.h
+/bfdver.h
+/elf32-ia64.c
+/elf32-target.h
+/elf64-ia64.c
+/elf64-target.h
+/libtool-soversion
+/ofiles
+/peigen.c
+/pepigen.c
+/pex64igen.c
+/stmp-bfd-h
+/targmatch.h
+
+/doc/aoutx.texi
+/doc/archive.texi
+/doc/archures.texi
+/doc/bfdio.texi
+/doc/bfdt.texi
+/doc/bfdver.texi
+/doc/bfdwin.texi
+/doc/cache.texi
+/doc/chew
+/doc/coffcode.texi
+/doc/core.texi
+/doc/elf.texi
+/doc/elfcode.texi
+/doc/format.texi
+/doc/hash.texi
+/doc/init.texi
+/doc/libbfd.texi
+/doc/linker.texi
+/doc/mmo.texi
+/doc/opncls.texi
+/doc/reloc.texi
+/doc/section.texi
+/doc/syms.texi
+/doc/targets.texi
diff --git a/bfd/COPYING b/bfd/COPYING
new file mode 100644
index 0000000..94a9ed0
--- /dev/null
+++ b/bfd/COPYING
@@ -0,0 +1,674 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. 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
+them 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 prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. 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.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey 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;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If 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 convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Use with the GNU Affero General Public License.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU 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 that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ 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.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+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.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ 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
+state 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) <year> <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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+ <program> Copyright (C) <year> <name of author>
+ This program 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, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+<http://www.gnu.org/licenses/>.
+
+ The GNU 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 Lesser General
+Public License instead of this License. But first, please read
+<http://www.gnu.org/philosophy/why-not-lgpl.html>.
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
new file mode 100644
index 0000000..f2ee1ba
--- /dev/null
+++ b/bfd/ChangeLog
@@ -0,0 +1,2796 @@
+2014-12-23 Tristan Gingold <gingold@adacore.com>
+
+ * version.m4: Bump version to 2.25
+ * configure: Regenerate.
+
+2014-12-19 Andrew Bennett <andrew.bennett@imgtec.com>
+
+ * elfxx-mips.c (mips_elf_calculate_relocation): Only check for
+ overflow on non-weak undefined symbols.
+
+2014-12-15 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/17713
+ * elflink.c (_bfd_elf_gc_mark_rsec): Check corrupt input.
+
+2014-12-13 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/17689
+ * elf64-x86-64.c (elf_x86_64_link_hash_entry): Add needs_copy.
+ Change has_bnd_reloc to bit field.
+ (elf_x86_64_link_hash_newfunc): Initialize needs_copy and
+ has_bnd_reloc to 0.
+ (elf_x86_64_check_relocs): Set has_bnd_reloc to 1 instead
+ of TRUE.
+ (elf_x86_64_adjust_dynamic_symbol): Copy needs_copy from the
+ real definition to a weak symbol.
+ (elf_x86_64_allocate_dynrelocs): Also check needs_copy of a
+ weak symbol for PIE when discarding space for relocs against
+ symbols which turn out to need copy relocs.
+ (elf_x86_64_relocate_section): Also check needs_copy of a
+ weak symbol for PIE with copy reloc.
+
+2014-12-12 Alan Modra <amodra@gmail.com>
+
+ PR 15228
+ * elflink.c (_bfd_elf_adjust_dynamic_copy): Call bfd_set_error.
+
+2014-12-10 Alan Modra <amodra@gmail.com>
+
+ * dwarf2.c (read_address): Check bfd_target_elf_flavour before
+ calling get_elf_backend_data.
+ (_bfd_dwarf2_find_nearest_line): Fix parens.
+
+2014-12-05 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf64-x86-64.c (bfd_elf32_get_synthetic_symtab): New.
+
+2014-12-04 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR binutils/17677
+ * elf-bfd.h (_bfd_elf_ifunc_get_synthetic_symtab): New prototype.
+ * elf-ifunc.c (_bfd_elf_ifunc_get_synthetic_symtab): New
+ function.
+ * elf32-i386.c (elf_i386_plt_sym_val): Removed.
+ (elf_backend_plt_sym_val): Likewise.
+ (elf_i386_get_plt_sym_val): New.
+ (elf_i386_get_synthetic_symtab): Likewise.
+ (bfd_elf32_get_synthetic_symtab): Likewise.
+ * elf64-x86-64.c (elf_x86_64_plt_sym_val): Removed.
+ (elf_x86_64_plt_sym_val_offset_plt_bnd): Likewise.
+ (elf_backend_plt_sym_val): Likewise.
+ (elf_x86_64_get_plt_sym_val): New.
+ (elf_x86_64_get_synthetic_symtab): Use
+ _bfd_elf_ifunc_get_synthetic_symtab.
+ (bfd_elf64_get_synthetic_symtab): Don't undefine for NaCl.
+
+2014-12-03 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf64-x86-64.c (elf_x86_64_create_dynamic_sections): Reformat.
+
+2014-12-02 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf64-x86-64.c (elf_x86_64_relocate_section): Check
+ info->executable for symbols which need copy relocs.
+
+2014-12-02 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf64-x86-64.c (elf_x86_64_check_relocs): Revert the last
+ change.
+ (elf_x86_64_adjust_dynamic_symbol): Don't check !info->shared
+ with ELIMINATE_COPY_RELOCS.
+ (elf_x86_64_allocate_dynrelocs): For PIE, discard space for
+ relocs against symbols which turn out to need copy relocs.
+
+2014-12-02 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf64-x86-64.c (elf_x86_64_create_dynamic_sections): Always
+ allow copy relocs for building executables.
+ (elf_x86_64_check_relocs): Allow copy relocs for non-GOT
+ pc-relative relocation in shared object.
+ (elf_x86_64_adjust_dynamic_symbol): Allocate copy relocs for
+ PIE.
+ (elf_x86_64_relocate_section): Don't copy a pc-relative
+ relocation into the output file if the symbol needs copy reloc.
+
+2014-11-30 Alan Modra <amodra@gmail.com>
+
+ PR 16452, 16457
+ * elflink.c (_bfd_elf_link_find_version_dependencies): Exclude
+ symbols from libraries that won't be listed in DT_NEEDED.
+ (elf_link_output_extsym): Don't output verdefs for such symbols.
+
+2014-11-24 Tejas Belagod <tejas.belagod@arm.com>
+
+ * elfnn-aarch64.c (elf_aarch64_compare_mapping): New.
+ (erratum_835769_scan): Sort map list.
+
+2014-11-24 Alan Modra <amodra@gmail.com>
+
+ * elf64-ppc.c (plt_stub_pad): Correct.
+
+2014-11-20 Alan Modra <amodra@gmail.com>
+
+ * elf64-ppc.c (group_sections): Init stub14_group_size from
+ --stub-group-size parameter divided by 1024.
+
+2014-11-20 Alan Modra <amodra@gmail.com>
+
+ * elf32-ppc.c (ppc_elf_relax_section): Correct ppc476 workaround
+ alignment calculation.
+
+2014-11-20 Alan Modra <amodra@gmail.com>
+
+ * elf64-ppc.c (ppc64_elf_size_stubs): Add __go_go to thread_starters.
+
+2014-11-18 Igor Zamyatin <igor.zamyatin@intel.com>
+
+ * elf64-x86-64.c (elf_x86_64_check_relocs): Enable MPX PLT only
+ for -z bndplt.
+
+2014-11-17 Nick Clifton <nickc@redhat.com>
+
+ Apply trunk patches:
+
+ 2014-11-14 Nick Clifton <nickc@redhat.com>
+
+ PR binutils/17597
+ * opncls.c (bfd_get_debug_link_info): Avoid reading off the end of
+ the section.
+ (bfd_get_alt_debug_link_info): Likewise.
+
+ 2014-11-14 Nick Clifton <nickc@redhat.com>
+
+ PR binutils/17512
+ * ieee.c (ieee_archive_p) Skip processing if no bytes are read at
+ all.
+ (ieee_object_p): Likewise.
+
+ 2014-11-13 H.J. Lu <hongjiu.lu@intel.com>
+
+ * coffcode.h (coff_slurp_line_table): Add cast to unsigned int.
+
+ 2014-11-13 H.J. Lu <hongjiu.lu@intel.com>
+
+ * coffcode.h (coff_pointerize_aux_hook): Fix a typo.
+
+ 2014-11-13 Nick Clifton <nickc@redhat.com>
+
+ PR binutils/17512
+ * coffcode.h (coff_ptr_struct): Add is_sym field.
+ (coff_new_section_hook): Set the is_sym field.
+ (coff_pointerize_aux_hook): Check the is_sym field.
+ (coff_print_aux): Likewise.
+ (coff_compute_section_file_positions): Likewise.
+ (coff_write_object_contents): Likewise.
+ (coff_slurp_line_table): Likewise.
+ (coff_slurp_symbol_table): Likewise.
+ (CALC_ADDEND): Likewise.
+ * coffgen.c (coff_renumber_symbols): Likewise.
+ (coff_mangle_symbols): Likewise.
+ (coff_fix_symbol_name): Likewise.
+ (coff_write_symbol): Likewise.
+ (coff_write_alien_symbol): Likewise.
+ (coff_write_native_symbol): Likewise.
+ (coff_write_symbols): Likewise.
+ (coff_write_linenumbers): Likewise.
+ (coff_pointerize_aux): Likewise.
+ (coff_get_normalized_symtab): Likewise.
+ (coff_get_symbol_info): Likewise.
+ (bfd_coff_get_syment): Likewise.
+ (bfd_coff_get_auxent): Likewise.
+ (coff_print_symbol): Likewise.
+ (coff_find_nearest_line_with_names): Likewise.
+ (bfd_coff_set_symbol_class): Likewise.
+ (coff_make_empty_symbol): Set the is_sym field.
+ (coff_bfd_make_debug_symbol): Likewise.
+ * peicode.h (pe_ILF_make_a_symbol): Likewise.
+ * libcoff.h: Regenerate.
+ * libcoff-in.h: Regenerate.
+
+ 2014-11-12 Nick Clifton <nickc@redhat.com>
+
+ PR binutils/17512
+ * coffcode.h (coff_slurp_line_table): Set the line number of
+ corrupt entries to -1.
+ (coff_slurp_symbol_table): Alway initialise the value of the
+ symbol.
+ * coffgen.c (coff_print_symbol): Check that the combined pointer
+ is valid.
+ (coff_print_symbol): Do not print negative line numbers.
+ * peXXigen.c (pe_print_idata): Add range checking displaying
+ member names.
+
+ 2014-11-12 Alan Modra <amodra@gmail.com>
+
+ PR binutils/17512
+ * coffcode.h (coff_slurp_line_table): Drop line number info
+ not preceded by a valid function entry. Revert last change.
+
+ 2014-11-11 Nick Clifton <nickc@redhat.com>
+
+ PR binutils/17512
+ * coffcode.h (coff_slurp_line_table): Initialise the parts of the
+ line number cache that would not be initialised by the copy from
+ the new line number table.
+ (coff_classify_symbol): Allow for _bfd_coff_internal_syment_name
+ returning NULL.
+ * coffgen.c (coff_get_normalized_symbols): Get the external
+ symbols before allocating space for the internal symbols, in case
+ the get fails.
+ * elf.c (_bfd_elf_slurp_version_tables): Only allocate a verref
+ array if one is needed. Likewise with the verdef array.
+ * peXXigen.c (_bfd_XXi_swap_sym_in): Replace abort()'s with error
+ messages.
+ (_bfd_XXi_swap_aux_in): Make sure that all fields of the aux
+ structure are initialised.
+ (pe_print_edata): Avoid reading off the end of the data buffer.
+
+ 2014-11-11 Alan Modra <amodra@gmail.com>
+
+ PR binutils/17512
+ * coffcode.h (coff_slurp_line_table): Use updated lineno_count
+ when building func_table.
+
+ 2014-11-11 Alan Modra <amodra@gmail.com>
+
+ PR binutils/17512
+ * coffcode.h (coff_slurp_line_table): Don't bfd_zalloc, just
+ memset the particular bits we need. Update src after hitting loop
+ "continue". Don't count lineno omitted due to invalid symbols in
+ nbr_func, and update lineno_count. Init entire terminating
+ lineno. Don't both allocating terminator in n_lineno_cache.
+ Redirect sym->lineno pointer to where n_lineno_cache will be
+ copied, and free n_lineno_cache.
+ * pe-mips.c (NUM_HOWTOS): Typo fix.
+
+ 2014-11-10 Nick Clifton <nickc@redhat.com>
+
+ PR binutils/17521
+ * coff-i386.c (NUM_HOWTOS): New define.
+ (RTYPE2HOWTO): Use it.
+ (coff_i386_rtype_to_howto): Likewise.
+ (coff_i386_reloc_name_lookup): Likewise.
+ (CALC_ADDEND): Check that reloc r_type field is valid.
+ * coff-x86_64.c (NUM_HOWTOS): New define.
+ (RTYPE2HOWTO): Use it.
+ (coff_amd64_rtype_to_howto): Likewise.
+ (coff_amd64_reloc_name_lookup): Likewise.
+ (CALC_ADDEND): Check that reloc r_type field is valid.
+ * coffcode.h (coff_slurp_line_table): Check for symbol table
+ indexing underflow.
+ (coff_slurp_symbol_table): Use zalloc to ensure that all table
+ entries are initialised.
+ * coffgen.c (_bfd_coff_read_string_table): Initialise unused bits
+ in the string table. Also ensure that the table is 0 terminated.
+ (coff_get_normalized_symtab): Check for symbol table indexing
+ underflow.
+ * opncls.c (bfd_alloc): Catch the case where a small negative size
+ can result in only 1 byte being allocated.
+ (bfd_alloc2): Use bfd_alloc.
+ * pe-mips.c (NUM_HOWTOS): New define.
+ (coff_mips_reloc_name_lookup): Use it.
+ (CALC_ADDEND): Check that reloc r_type field is valid.
+ * peXXigen.c (_bfd_XXi_swap_aouthdr_in): Initialise unused entries
+ in the DataDirectory.
+ (pe_print_idata): Avoid reading beyond the end of the data block
+ wen printing strings.
+ (pe_print_edata): Likewise.
+ Check for table indexing underflow.
+ * peicode.h (pe_mkobject): Initialise the pe_opthdr field.
+ (pe_bfd_object_p): Allocate and initialize enough space to hold a
+ PEAOUTHDR, even if the opt_hdr field specified less.
+
+ 2014-11-08 Alan Modra <amodra@gmail.com>
+
+ * peXXigen.c (pe_print_idata): Revert last patch, cast lhs instead.
+
+ 2014-11-07 H.J. Lu <hongjiu.lu@intel.com>
+
+ * peXXigen.c (pe_print_idata): Cast to unsigned long in range
+ checks.
+
+ 2014-11-07 Alan Modra <amodra@gmail.com>
+
+ * tekhex.c (tekhex_set_arch_mach): Ignore unknown arch errors.
+
+ 2014-11-07 Alan Modra <amodra@gmail.com>
+
+ * tekhex.c (CHUNK_SPAN): Define.
+ (struct data_struct <chunk_init>): Use one byte per span, update
+ all code accessing this field.
+ (find_chunk): Add create param, don't create new entry unless set.
+ (insert_byte): Don't save zeros.
+ (first_phase): Set section SEC_CODE or SEC_DATA flag depending
+ on symbol type. Create an alternate section if both types of
+ symbol are given. Attach type '2' and '6' symbols to absolute
+ section.
+ (move_section_contents): Fix caching of chunk. Don't create chunk
+ when reading, or for writing zeros.
+ (tekhex_set_section_contents): Don't create initial chunks.
+ (tekhex_write_object_contents): Use CHUNK_SPAN.
+
+ 2014-11-07 Alan Modra <amodra@gmail.com>
+
+ * aoutx.h (aout_get_external_symbols): Tidy allocation of symbol buffer.
+
+ 2014-11-07 Alan Modra <amodra@gmail.com>
+
+ * archive.c (_bfd_slurp_extended_name_table): Revert bfd_get_size check.
+ * coffcode.h (coff_set_alignment_hook): Likewise.
+ (coff_slurp_line_table): Likewise.
+ * coffgen.c (coff_get_normalized_symtab): Likewise.
+ (_bfd_coff_get_external_symbols): Likewise.
+ * elf.c (bfd_elf_get_str_section): Likewise.
+ * tekhex.c (first_phase): Likewise.
+
+ 2014-11-06 Nick Clifton <nickc@redhat.com>
+
+ * aoutx.h (slurp_symbol_table): Revert previous delta.
+ (slurp_reloc_table): Likewise.
+ * compress.c (bfd_get_full_section_contents): Remove file size
+ test.
+ * coffgen.c (coff_get_normalized_symtab): Allow zero-sized symtabs
+ and do not complain about linker generated files.
+
+ 2014-11-04 Nick Clifton <nickc@redhat.com>
+
+ PR binutils/17512
+ * coffcode.h (handle_COMDAT): Replace abort with BFD_ASSERT.
+ Replace another abort with an error message.
+ (coff_slurp_line_table): Add more range checking.
+ * peXXigen.c (pe_print_debugdata): Add range checking.
+
+ 2014-11-05 Nick Clifton <nickc@redhat.com>
+
+ PR binutils/17512
+ * coffcode.h (coff_set_alignment_hook): Warn if the file lies
+ about the number of relocations it contains.
+ (coff_sort_func_alent): Return 0 if the pointers are NULL.
+ (coff_slurp_line_table): Add more range checks. Do not free new
+ tables created when sorting line numbers.
+ * peXXigen.c (pe_print_idata): Add range checks.
+ (pe_print_edata): Likewise.
+ (rsrc_print_resource_entries): Likewise. Avoid printing control
+ characters. Terminate priniting if corruption is detected.
+ (rsrc_print_resource_directory): Terminate printing if an unknown
+ directory type is encountered.
+ (pe_print_debugdata): Fix off-by-one error.
+ (rsrc_count_entries): Add range checking.
+ (rsrc_parse_entry): Likewise.
+
+ 2014-11-04 Nick Clifton <nickc@redhat.com>
+
+ PR binutils/17512
+ * compress.c (bfd_get_full_section_contents): Improve test for
+ linker created objects.
+
+ PR binutils/17533
+ * archive.c (_bfd_slurp_extended_name_table): Handle archives with
+ corrupt extended name tables.
+
+ 2014-11-03 Nick Clifton <nickc@redhat.com>
+
+ PR binutils/17512
+ * aoutx.h (slurp_symbol_table): Check that computed table size is
+ not bigger than the file from which is it being read.
+ (slurp_reloc_table): Likewise.
+ * coffcode.h (coff_slurp_line_table): Remove unneeded local
+ 'warned'. Do not try to print the details of a symbol with an
+ invalid index.
+ * coffgen.c (make_a_sectiobn_from_file): Check computed string
+ index against length of string table.
+ (bfd_coff_internal_syment_name): Check read in string offset
+ against length of string table.
+ (build_debug_section): Return a pointer to the section used.
+ (_bfd_coff_read_string_table): Store the length of the string
+ table in the coff_tdata structure.
+ (bfd_coff_free_symbols): Set the length of the string table to
+ zero when it is freed.
+ (coff_get_normalized_symtab): Check offsets against string table
+ or data table lengths as appropriate.
+ * cofflink.c (_bfd_coff_link_input_bfd): Check offset against
+ length of string table.
+ * compress.c (bfd_get_full_section_contents): Check computed size
+ against the size of the file.
+ * libcoff-in.h (obj_coff_strings_len): Define.
+ (struct coff_tdata): Add strings_len field.
+ * libcoff.h: Regenerate.
+ * peXXigen.c (pe_print_debugdata): Do not attempt to print the
+ data if the debug section is too small.
+ * xcofflink.c (xcoff_link_input_bfd): Check offset against
+ length of string table.
+
+ 2014-10-31 Nick Clifton <nickc@redhat.com>
+
+ PR binutils/17512
+ * coffgen.c (_bfd_coff_get_external_symbols): Do not try to load a
+ symbol table bigger than the file.
+ * elf.c (bfd_elf_get_str_section): Do not try to load a string
+ table bigger than the file.
+ * tekhex.c (first_phase): Check that the section range is sane.
+
+2014-11-11 Alan Modra <amodra@gmail.com>
+
+ * elf-eh-frame.c (_bfd_elf_write_section_eh_frame): Adjust section
+ size check to account for possible zero terminator.
+
+2014-11-10 Matthew Fortune <matthew.fortune@imgtec.com>
+
+ Apply trunk patch:
+ * elfxx-mips.c (update_mips_abiflags_isa): Add E_MIPS_ARCH_32R6
+ and E_MIPS_ARCH_64R6 support.
+
+2014-11-07 H.J. Lu <hongjiu.lu@intel.com>
+
+ Apply trunk patch:
+ 2014-11-07 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/17482
+ * elf64-x86-64.c (elf_x86_64_relocate_section): Update comments
+ for IE->LE transition.
+
+2014-11-04 Tristan Gingold <gingold@adacore.com>
+
+ * development.sh: Set development to false.
+
+2014-11-03 Nick Clifton <nickc@redhat.com>
+
+ * po/fi.po: Updated Finnish translation.
+
+2014-10-31 Nick Clifton <nickc@redhat.com>
+
+ Apply trunk patch:
+
+ 2014-10-30 Nick Clifton <nickc@redhat.com>
+ PR binutils/17512
+ * ihex.c (ihex_scan): Fix typo in invocation of ihex_bad_byte.
+ * coffgen.c (coff_get_normalized_symtab): Prevent buffer overrun.
+
+2014-10-30 Nick Clifton <nickc@redhat.com>
+
+ Appy trunk patch:
+
+ 2014-10-29 Nick Clifton <nickc@redhat.com>
+ * elf.c (bfd_section_from_shdr): Fix heap use after free memory
+ leak.
+
+2014-10-28 Matthew Fortune <matthew.fortune@imgtec.com>
+
+ Apply trunk patches:
+
+ 2014-10-22 Matthew Fortune <matthew.fortune@imgtec.com>
+ * elfxx-mips.c (print_mips_ases): Print unknown ASEs.
+ (print_mips_isa_ext): Print the value of an unknown extension.
+
+2014-10-28 Nick Clifton <nickc@redhat.com>
+
+ Apply trunk patches:
+
+ 2014-10-28 Nick Clifton <nickc@redhat.com>
+ PR binutils/17512
+ * elf.c (bfd_section_from_shdr): Allocate and free the recursion
+ detection table on a per-bfd basis.
+ * peXXigen.c (pe_print_edata): Handle binaries with a truncated
+ export table.
+
+ 2014-10-28 Andreas Schwab <schwab@suse.de>
+ Nick Clifton <nickc@redhat.com>
+ PR binutils/17510
+ * srec.c (srec_bad_byte): Increase size of buf to allow for
+ negative values.
+ (srec_scan): Use an unsigned char buffer to hold header bytes.
+
+ 2014-10-27 Nick Clifton <nickc@redhat.com>
+ PR binutils/17512
+ * elf.c (bfd_section_from_shdr): Detect and warn about ELF
+ binaries with a group of sections linked by the string table
+ indicies.
+ * peXXigen.c (_bfd_XXi_swap_aouthdr_in): Handle corrupt binaries
+ with an invalid value for NumberOfRvaAndSizes.
+ (pe_print_edata): Detect out of range rvas and entry counts for
+ the Export Address table, Name Pointer table and Ordinal table.
+
+ PR binutils/17510
+ * elf.c (setup_group): Improve handling of corrupt group
+ sections.
+
+2014-10-28 Alan Modra <amodra@gmail.com>
+
+ Apply trunk patches:
+
+ 2014-10-21 Alan Modra <amodra@gmail.com>
+ * elf64-ppc.c (ppc64_elf_tls_optimize): Ignore relocs against toc
+ entries that aren't a multiple of 8 rather than failing assertion.
+
+ 2014-10-21 Alan Modra <amodra@gmail.com>
+ * elf64-ppc.c (ppc64_elf_size_stubs): Add gcc-4.9 libgomp functions
+ to thread_starter.
+
+ 2014-10-18 Alan Modra <amodra@gmail.com>
+ * elf64-ppc.c (ppc64_elf_add_symbol_hook): If function code
+ section for function symbols defined in .opd is discarded, let
+ the symbol appear to be undefined.
+ (opd_entry_value): Ensure the result section is that for the
+ function code section in the same object as the OPD entry.
+
+ 2014-10-16 Alan Modra <amodra@gmail.com>
+ PR 17492
+ * elf32-arm.c (elf32_arm_add_symbol_hook): Only set has_gnu_symbols
+ on ELF output bfd.
+ * elf32-i386.c (elf_i386_add_symbol_hook): Likewise.
+ * elf32-m68k.c (elf_m68k_add_symbol_hook): Likewise.
+ * elf32-ppc.c (ppc_elf_add_symbol_hook): Likewise.
+ * elf32-sparc.c (elf32_sparc_add_symbol_hook): Likewise.
+ * elf64-ppc.c (ppc64_elf_add_symbol_hook): Likewise.
+ * elf64-sparc.c (elf64_sparc_add_symbol_hook): Likewise.
+ * elf64-x86-64.c (elf_x86_64_add_symbol_hook): Likewise.
+ * elfxx-aarch64.c (_bfd_aarch64_elf_add_symbol_hook): Likewise.
+ * elf-s390-common.c (elf_s390_add_symbol_hook): Likewise. Handle
+ STB_GNU_UNIQUE too.
+
+ 2014-10-16 Alan Modra <amodra@gmail.com>
+ * elf64-ppc.c (ppc64_elf_before_check_relocs): Do .opd processing
+ even when output is not ppc64 ELF. Remove redundant tests on
+ type of input bfd.
+
+ 2014-10-15 Alan Modra <amodra@gmail.com>
+ PR 17481
+ * aoutx.h (NAME (aout, find_nearest_line)): Add "discriminator_ptr"
+ param, group "section" and "offset" params. Zero discriminator.
+ * bfd.c (bfd_find_nearest_line): Implement with new
+ _bfd_find_nearest_line.
+ (bfd_find_nearest_line_discriminator): Likewise.
+ * coff-i386.c (_bfd_generic_find_nearest_line_discriminator): Don't
+ define.
+ * coff-rs6000.c (xcoff_find_nearest_line,
+ xcoff_find_nearest_line_discriminator): Delete.
+ (_bfd_xcoff_find_nearest_line): Don't define.
+ (_bfd_xcoff_find_nearest_line): Define as coff_find_nearest_line.
+ * coff-x86_64.c (_bfd_generic_find_nearest_line_discriminator): Don't
+ define.
+ * coff64-rs6000.c (rs6000_xcoff64_vec, rs6000_xcoff64_aix_vec): Adjust.
+ * coffgen.c (coff_find_nearest_line_with_names): Reorder params,
+ adjust _bfd_dwarf2_find_nearest_line call.
+ (coff_find_nearest_line): Add "discriminator_ptr" param, reorder
+ others. Set discriminator. Adjust call.
+ (coff_find_nearest_line_discriminator): Delete.
+ * dwarf1.c (_bfd_dwarf1_find_nearest_line): Reorder params.
+ * dwarf2.c (find_line): Rename to..
+ (_bfd_dwarf2_find_nearest_line): ..this, reordering params.
+ Simplify setting of do_line. Delete old function.
+ (_bfd_dwarf2_find_line): Delete.
+ * ecoff.c (_bfd_ecoff_find_nearest_line): Reorder params, add
+ discriminator_ptr and set it.
+ * elf-bfd.h (_bfd_elf_find_nearest_line): Update prototype.
+ (_bfd_elf_find_nearest_line_discriminator): Delete.
+ (_bfd_elf_find_line_discriminator): Delete.
+ (_bfd_generic_find_nearest_line_discriminator): Don't define.
+ * elf.c (elf_find_function): Reorder params.
+ (_bfd_elf_find_nearest_line): Reorder params, add discriminator_ptr.
+ Adjust calls.
+ (_bfd_elf_find_nearest_line_discriminator): Delete.
+ (_bfd_elf_find_line): Adjust call.
+ * elf32-arm.c (arm_elf_find_function): Reorder params.
+ (elf32_arm_find_nearest_line): Reorder params, add discriminator_ptr.
+ Adjust calls.
+ * elf64-alpha.c (elf64_alpha_find_nearest_line): Similarly.
+ * elfnn-aarch64.c (aarch64_elf_find_function): Reorder params.
+ (elfNN_aarch64_find_nearest_line): Reorder params, add
+ discriminator_ptr. Adjust calls.
+ * elfxx-mips.c (_bfd_mips_elf_find_nearest_line): Similarly.
+ * elfxx-mips.h (_bfd_mips_elf_find_nearest_line): Update prototype.
+ * libaout.h (NAME (aout, find_nearest_line)): Update prototype.
+ * libbfd-in.h (_bfd_nosymbols_find_nearest_line): Update.
+ (_bfd_dwarf1_find_nearest_line): Likewise.
+ (_bfd_dwarf2_find_nearest_line): Likewise.
+ (_bfd_dwarf2_find_line): Delete.
+ (_bfd_generic_find_nearest_line_discriminator): Delete.
+ * libbfd.c (_bfd_generic_find_nearest_line_discriminator): Delete.
+ * libcoff-in.h (coff_find_nearest_line): Update prototype.
+ (coff_find_nearest_line_discriminator): Delete.
+ (coff_find_nearest_line_with_names): Update prototype.
+ * libecoff.h (_bfd_ecoff_find_nearest_line): Update prototype.
+ * mach-o.c (bfd_mach_o_find_nearest_line): Reorder params, add
+ discriminator_ptr. Adjust calls.
+ * mach-o.h (bfd_mach_o_find_nearest_line): Update prototype.
+ * pdp11.c (NAME (aout, find_nearest_line)): Reorder params, add
+ discriminator_ptr and set.
+ * som.c (som_find_nearest_line): Similarly.
+ * targets.c (BFD_JUMP_TABLE_SYMBOLS): Delete entry for
+ _bfd_find_nearest_line_discriminator.
+ (struct bfd_target <_bfd_find_nearest_line>): Adjust prototype.
+ (struct bfd_target <_bfd_find_nearest_line_discriminator>): Delete.
+ * vms-alpha.c (_bfd_vms_find_nearest_dst_line): Rename to..
+ (_bfd_vms_find_nearest_line): ..this. Reorder params, add
+ "discriminator" and set.
+ (_bfd_vms_find_nearest_line_discriminator): Delete.
+ (_bfd_generic_find_nearest_line_discriminator): Don't define.
+ (alpha_vms_find_nearest_line): Update define.
+ * bfd-in2.h: Regenerate.
+ * libbfd.h: Regenerate.
+ * libcoff.h: Regenerate.
+
+ 2014-10-15 Alan Modra <amodra@gmail.com>
+ * targets.c (BFD_JUMP_TABLE_SYMBOLS): Use NAME##_find_line.
+ * aout-adobe.c (aout_32_find_line): Define.
+ (aout_32_bfd_make_debug_symbol, aout_32_bfd_reloc_type_lookup,
+ aout_32_bfd_reloc_name_lookup): Define using _bfd_nosymbols define.
+ * aout-target.h (MY_find_line): Define.
+ * aout-tic30.c (MY_find_line): Define.
+ * binary.c (binary_find_line): Define.
+ * bout.c (aout_32_find_line): Define.
+ * coff-rs6000.c (_bfd_xcoff_find_line): Define.
+ * coff64-rs6000.c (rs6000_xcoff64_vec): Use coff_find_line.
+ (rs6000_xcoff64_aix_vec): Likewise.
+ * elf-bfd.h (_bfd_generic_find_line): Don't define.
+ * elfxx-target.h (bfd_elfNN_find_line): Define.
+ * i386msdos.c (msdos_find_line): Define.
+ * i386os9k.c (aout_32_find_line): Define.
+ * ieee.c (ieee_find_nearest_line, ieee_find_inliner_info): Delete func.
+ (ieee_find_nearest_line, ieee_find_line,
+ ieee_find_inliner_info): Define.
+ * ihex.c (ihex_find_line): Define.
+ * libbfd-in.h (_bfd_nosymbols_find_line): Define.
+ (_bfd_generic_find_line): Don't define.
+ * libbfd.c (_bfd_generic_find_line): Delete.
+ * libcoff-in.h (coff_find_line): Define.
+ * libecoff.h (_bfd_ecoff_find_line): Define.
+ * mach-o.h (bfd_mach_o_find_line): Define.
+ * mmo.c (mmo_find_line): Define.
+ * nlm-target.h (nlm_find_line): Define.
+ * oasys.c (oasys_find_nearest_line, oasys_find_inliner_info): Delete.
+ (oasys_find_nearest_line, oasys_find_line,
+ oasys_find_inliner_info): Define.
+ * pef.c (bfd_pef_find_line): Define.
+ * plugin.c (bfd_plugin_find_line): Define.
+ * ppcboot.c (ppcboot_find_line): Define.
+ * som.c (som_find_line): Define.
+ * srec.c (srec_find_line): Define.
+ * tekhex.c (tekhex_find_line): Define.
+ * versados.c (versados_find_line): Define.
+ * vms-alpha.c (alpha_vms_find_line): Define.
+ * xsym.c (bfd_sym_find_line): Define.
+ * bfd-in2.h: Regenerate.
+ * libbfd.h: Regenerate.
+ * libcoff.h: Regenerate.
+
+2014-10-24 Tejas Belagod <tejas.belagod@arm.com>
+
+ * bfd-in.h (bfd_elf64_aarch64_set_options): Add a parameter.
+ * bfd-in2.h (bfd_elf64_aarch64_set_options): Likewise.
+ * elfnn-aarch64.c (aarch64_erratum_835769_stub): New.
+ (elf_aarch64_stub_type): Add new type
+ aarch64_stub_erratum_835769_veneer.
+ (elf_aarch64_stub_hash_entry): New fields for erratum 835769.
+ (aarch64_erratum_835769_fix): New data struct to record erratum
+ 835769.
+ (elf_aarch64_link_hash_table: Global flags for 835769.
+ (aarch64_build_one_stub): Add case for 835769.
+ (aarch64_size_one_stub): Likewise.
+ (aarch64_mem_op_p, aarch64_mlxl_p,
+ aarch64_erratum_sequence,erratum_835769_scan):
+ New. Decode and scan functions for erratum 835769.
+ (elf_aarch64_create_or_find_stub_sec): New.
+ (elfNN_aarch64_size_stubs): Look for erratum 835769 and record
+ them.
+ (bfd_elfNN_aarch64_set_options: Set global flag for 835769.
+ (erratum_835769_branch_to_stub_data,
+ make_branch_to_erratum_835769_stub):New. Connect up all the
+ erratum stubs to occurances by branches.
+ (elfNN_aarch64_write_section): New hook.
+ (aarch64_map_one_stub): Output erratum stub symbol.
+ (elfNN_aarch64_size_dynamic_sections): Init mapping symbol
+ information for erratum 835769.
+ (elf_backend_write_section): Define.
+
+2014-10-14 Tristan Gingold <gingold@adacore.com>
+
+ * version.m4: Bump version to 2.24.90
+ * configure: Regenerate.
+
+2014-10-14 Alan Modra <amodra@gmail.com>
+
+ PR 17453
+ * libbfd.c (COERCE16, COERCE32, COERCE64): Use unsigned types.
+ (EIGHT_GAZILLION): Delete.
+
+2014-10-13 Alan Modra <amodra@gmail.com>
+
+ PR 17467
+ * elf-eh-frame.c (ENSURE_NO_RELOCS): Don't stop at first NONE reloc.
+ (_bfd_elf_parse_eh_frame): When relocatable output, don't set
+ flags enabling conversion of CIEs and FDEs to use relative encoding.
+ (find_merged_cie): Similarly.
+ (_bfd_elf_write_section_eh_frame): Don't edit FDEs when
+ relocatable, except for CIE pointer.
+ * elflink.c (bfd_elf_reloc_symbol_deleted_p): Return true for
+ relocs against symbols in dropped comdat group sections.
+ (bfd_elf_discard_info): Do some eh_frame optimisation when
+ relocatable.
+
+2014-10-09 Jose E. Marchesi <jose.marchesi@oracle.com>
+
+ * elfxx-sparc.c (_bfd_sparc_elf_merge_private_bfd_data): Handle
+ the hwcaps2 object attribute.
+
+2014-10-04 Alan Modra <amodra@gmail.com>
+
+ PR 17447
+ * elf-bfd.h (struct eh_cie_fde): Comment re NULL u.fde.cie_inf.
+ * elf-eh-frame.c (_bfd_elf_parse_eh_frame): Mark zero address
+ range FDEs for discarding.
+ (vma_compare): Sort on range after address.
+ (_bfd_elf_gc_mark_fdes): Test for NULL u.fde.cie_inf.
+ (_bfd_elf_discard_section_eh_frame): Likewise. Write "FDE" in
+ error message rather than "fde".
+ (_bfd_elf_write_section_eh_frame_hdr): Write "PC" and "FDE" in
+ error message.
+
+2014-09-29 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/17440
+ * elf32-i386.c (elf_i386_fbsd_post_process_headers): Fix build
+ for OLD_FREEBSD_ABI_LABEL.
+
+2014-09-24 Markus Trippelsdorf <markus@trippelsdorf.de>
+
+ PR 17422
+ * plugin.c (try_claim): New function. Moved from
+ bfd_plugin_object_p.
+ (try_load_plugin): Pass through bfd. Add test.
+ (load_plugin): Pass through bfd.
+ (bfd_plugin_object_p): Move logic to try_claim.
+
+2014-09-23 Sterling Augustine <augustine.sterling@gmail.com>
+
+ * elf32-xtensa.c (is_resolvable_asm_expansion): for cross-section
+ call relaxation use furthermost addresses where call source and
+ destination can be to check whether it's in the range of a direct
+ call.
+
+2014-09-22 Alan Modra <amodra@gmail.com>
+
+ * elf-eh-frame.c (_bfd_elf_write_section_eh_frame_hdr): Don't return
+ false for overflow or overlapping FDEs. Give more detail in
+ error messages.
+
+2014-09-22 Andrew Bennett <andrew.bennett@imgtec.com>
+
+ * elfxx-mips.c (mips_elf_calculate_relocation): Don't sign extend
+ the addend if relocations are RELA.
+
+2014-09-22 Kuan-Lin Chen <kuanlinchentw@gmail.com>
+
+ * elf32-nds32.c (nds32_elf_ex9_build_hash_table,
+ nds32_elf_ex9_relocation_check): Synchronize the argument type.
+
+2014-09-19 Andreas Krebbel <krebbel@linux.vnet.ibm.com>
+
+ * elf32-s390.c: Don't replace R_390_TLS_LE32 with R_390_TLS_TPOFF
+ for PIE.
+ * elf64-s390.c: Don't replace R_390_TLS_LE64 with R_390_TLS_TPOFF
+ for PIE.
+
+2014-09-18 Jan Kratochvil <jan.kratochvil@redhat.com>
+
+ PR gdb/17407
+ * elfcode.h (bfd_from_remote_memory): Use SIZE for HIGH_OFFSET.
+
+2014-09-16 Terry Guo <terry.guo@arm.com>
+
+ * elf32-arm.c (elf32_arm_merge_eabi_attributes): Return false if
+ failed to merge.
+
+2014-09-16 Kuan-Lin Chen <kuanlinchentw@gmail.com>
+
+ * bfd-in2.h: Regenerate.
+ * elf32-nds32.c (nds32_elf_mkobject): Hook bfd_elf32_mkobject.
+ (nds32_elf_relax_section): Code refactoring.
+ (nds32_elf_relax_longcall1, nds32_elf_relax_longcall2,
+ nds32_elf_relax_longcall3, nds32_elf_relax_longcall4,
+ nds32_elf_relax_longcall5, nds32_elf_relax_longcall6): Relax call
+ pattern. The first three is moved from nds32_elf_relax_section,
+ and the last three is new function.
+ (nds32_elf_relax_longjump1, nds32_elf_relax_longjump2,
+ nds32_elf_relax_longjump3, nds32_elf_relax_longjump4,
+ nds32_elf_relax_longjump5, nds32_elf_relax_longjump6,
+ nds32_elf_relax_longjump7): Relax condition branch pattern. The first
+ three is moved from nds32_elf_relax_section, and the last four
+ is new function.
+ (nds32_elf_relax_loadstore, nds32_elf_relax_lo12): Relax load-store
+ pattern and address setting pattern.
+ (nds32_elf_relax_piclo12, nds32_elf_relax_ptr,
+ nds32_elf_relax_pltgot_suff, nds32_elf_relax_got_suff,
+ nds32_elf_relax_gotoff_suff): Relax pic pattern.
+ (nds32_elf_relax_letlslo12, nds32_elf_relax_letlsadd,
+ nds32_elf_relax_letlsls): Relax TLS pattern.
+ (nds32_relax_adjust_label): Adjust alignment and nop.
+ (nds32_elf_pick_relax): Choose relaxation optimization.
+ (nds32_elf_get_relocated_section_contents): New hook.
+ (nds32_elf_order_insn_times, nds32_elf_ex9_build_itable): Release ex9
+ table 234th entry.
+ * elf32-nds32.h: Declare.
+ * libbfd.h: Regenerate.
+ * reloc.c: Add nds32 new relocations.
+
+2014-09-15 Chen Gang <gang.chen.5i5j@gmail.com>
+
+ * dwarf2.c (find_abstract_instance_name): Use 'form' instead of
+ 'name' for the typo issue, which related with commit
+ 60d77146a249ae9b51d7ce98930cdbedb2cfa352.
+
+2014-09-15 Andrew Bennett <andrew.bennett@imgtec.com>
+ Matthew Fortune <matthew.fortune@imgtec.com>
+
+ * aoutx.h (NAME (aout, machine_type)): Add mips32r6 and mips64r6.
+ * archures.c (bfd_architecture): Likewise.
+ * bfd-in2.h (bfd_architecture): Likewise.
+ (bfd_reloc_code_real): Add relocs BFD_RELOC_MIPS_21_PCREL_S2,
+ BFD_RELOC_MIPS_26_PCREL_S2, BFD_RELOC_MIPS_18_PCREL_S3 and
+ BFD_RELOC_MIPS_19_PCREL_S2.
+ * cpu-mips.c (arch_info_struct): Add mips32r6 and mips64r6.
+ * elf32-mips.c: Define relocs R_MIPS_PC21_S2, R_MIPS_PC26_S2
+ R_MIPS_PC18_S3, R_MIPS_PC19_S2, R_MIPS_PCHI16 and R_MIPS_PCLO16.
+ (mips_reloc_map): Add entries for BFD_RELOC_MIPS_21_PCREL_S2,
+ BFD_RELOC_MIPS_26_PCREL_S2, BFD_RELOC_MIPS_18_PCREL_S3,
+ BFD_RELOC_MIPS_19_PCREL_S2, BFD_RELOC_HI16_S_PCREL and
+ BFD_RELOC_LO16_PCREL.
+ * elf64-mips.c: Define REL, and RELA relocations R_MIPS_PC21_S2,
+ R_MIPS_PC26_S2, R_MIPS_PC18_S3, R_MIPS_PC19_S2, R_MIPS_PCHI16
+ and R_MIPS_PCLO16.
+ (mips_reloc_map): Add entries for BFD_RELOC_MIPS_21_PCREL_S2,
+ BFD_RELOC_MIPS_26_PCREL_S2, BFD_RELOC_MIPS_18_PCREL_S3,
+ BFD_RELOC_MIPS_19_PCREL_S2, BFD_RELOC_HI16_S_PCREL and
+ BFD_RELOC_LO16_PCREL.
+ * elfn32-mips.c: Likewise.
+ * elfxx-mips.c (MIPSR6_P): New define.
+ (mipsr6_exec_plt_entry): New array.
+ (hi16_reloc_p): Add support for R_MIPS_PCHI16.
+ (lo16_reloc_p): Add support for R_MIPS_PCLO16.
+ (aligned_pcrel_reloc_p): New function.
+ (mips_elf_relocation_needs_la25_stub): Add support for relocs:
+ R_MIPS_PC21_S2 and R_MIPS_PC26_S2.
+ (mips_elf_calculate_relocation): Add support for relocs:
+ R_MIPS_PC21_S2, R_MIPS_PC26_S2, R_MIPS_PC18_S3, R_MIPS_PC19_S2,
+ R_MIPS_PCHI16 and R_MIPS_PCLO16.
+ (_bfd_elf_mips_mach): Add support for mips32r6 and mips64r6.
+ (mips_elf_add_lo16_rel_addend): Add support for R_MIPS_PCHI16.
+ (_bfd_mips_elf_check_relocs): Add support for relocs:
+ R_MIPS_PC21_S2 and R_MIPS_PC26_S2.
+ (_bfd_mips_elf_relocate_section): Add a check for unaligned
+ pc relative relocs.
+ (_bfd_mips_elf_finish_dynamic_symbol): Add support for MIPS r6
+ plt entry.
+ (mips_set_isa_flags): Add support for mips32r6 and mips64r6.
+ (_bfd_mips_elf_print_private_bfd_data): Likewise.
+ (mips_32bit_flags_p): Add support for mips32r6.
+ * libbfd.h (bfd_reloc_code_real_names): Add entries for
+ BFD_RELOC_MIPS_21_PCREL_S2, BFD_RELOC_MIPS_26_PCREL_S2,
+ BFD_RELOC_MIPS_18_PCREL_S3 and BFD_RELOC_MIPS_19_PCREL_S2.
+ * reloc.c: Document relocs BFD_RELOC_MIPS_21_PCREL_S2,
+ BFD_RELOC_MIPS_26_PCREL_S2, BFD_RELOC_MIPS_18_PCREL_S3 and
+ BFD_RELOC_MIPS_19_PCREL_S2.
+ * config.bfd: Add mips*-img-elf* target triple.
+
+2014-09-12 Andrew Bennett <andrew.bennett@imgtec.com>
+
+ * config.bfd: Add mips*-img-elf* target triple.
+
+2014-09-12 Alan Modra <amodra@gmail.com>
+
+ * elf-bfd.h (struct eh_frame_array_ent): Add "range".
+ * elf-eh-frame.c (_bfd_elf_write_section_eh_frame): Stash address
+ range of FDEs to hdr_info->array.
+ (_bfd_elf_write_section_eh_frame_hdr): Report overflow in
+ .eh_frame_hdr entries, and overlapping FDEs.
+
+2014-09-10 Alan Modra <amodra@gmail.com>
+
+ * elf.c (assign_file_positions_except_relocs): Move section header
+ placement to..
+ (_bfd_elf_assign_file_positions_for_relocs): ..here. Make static.
+ * elf-bfd.h (_bfd_elf_assign_file_positions_for_relocs): Delete.
+ * elflink.c (bfd_elf_final_link): Don't call above function.
+
+2014-08-30 Alan Modra <amodra@gmail.com>
+
+ * elf32-ppc.c (ppc_elf_relax_section): Fix off by one error.
+
+2014-08-29 Alan Modra <amodra@gmail.com>
+
+ * elf64-ppc.c (ppc64_elf_relocate_section): Report a different
+ error for calls via a toc adjusting stub without a nop.
+
+2014-08-29 Alan Modra <amodra@gmail.com>
+
+ * vms-alpha.c (alpha_vma_object_p): Don't return file_truncated
+ error. Remove redundant bfd_set_error.
+
+2014-08-29 Alan Modra <amodra@gmail.com>
+
+ * srec.c (srec_scan): Revert last change. Report an error for
+ S-records with less than the miniumum byte count.
+
+2014-08-28 H.J. Lu <hongjiu.lu@intel.com>
+
+ * srec.c (srec_scan): Return error for 0 size.
+
+2014-08-27 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/17306
+ * elf32-i386.c (elf_i386_convert_mov_to_lea): Use bfd_is_abs_section
+ to check discarded input section.
+ * elf64-x86-64.c (elf_x86_64_convert_mov_to_lea): Likewise.
+
+2014-08-27 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/17313
+ * elflink.c (elf_link_add_object_symbols): Don't attach dynamic
+ sections to input from ld --just-symbols.
+
+2014-08-26 DJ Delorie <dj@redhat.com>
+
+ * elf32-rl78.c (rl78_elf_relax_section): Disambiguate test for
+ relaxation type.
+
+2014-08-26 Jiong Wang <jiong.wang@arm.com>
+
+ * elfnn-aarch64.c (elfNN_aarch64_check_relocs): Initialize non_got_ref
+ properly for MOVW_G0/1/2_NC and MOVW_G3. Reject them when linking
+ shared library.
+ (elfNN_aarch64_gc_sweep_hook): Add check on these relocs.
+
+2014-08-26 Nick Clifton <nickc@redhat.com>
+
+ * config.bfd: Fix typo in or1knd selection.
+
+2014-08-22 Kai Tietz <ktietz@redhat.com>
+
+ PR binutils/11822
+ * coffcode.h (coff_compute_section_file_positions): Keep
+ FileAlignment valid as set.
+
+2014-08-22 Alan Modra <amodra@gmail.com>
+
+ * elf-eh-frame.c (struct cie): Delete "output_sec" field.
+ (cie_eq, cie_compute_hash): Use output_section from cie_inf instead.
+
+2014-08-22 Alan Modra <amodra@gmail.com>
+
+ * elf-bfd.h (struct eh_frame_hdr_info): Delete merge_cies and
+ parsed_eh_frames.
+ (_bfd_elf_begin_eh_frame_parsing): Delete.
+ (_bfd_elf_end_eh_frame_parsing): Delete.
+ * elf-eh-frame.c (_bfd_elf_begin_eh_frame_parsing): Delete.
+ (_bfd_elf_end_eh_frame_parsing): Delete.
+ (_bfd_elf_parse_eh_frame): Don't test parsed_eh_frame. Test
+ !info->relocatable in place of merge_cies.
+ * elflink.c (bfd_elf_gc_sections, bfd_elf_discard_info): Adjust.
+ * elf64-ppc.c (glink_eh_frame_cie): Pad to multiple of 8.
+ (ppc64_elf_size_stubs): Likewise pad stub FDE.
+ (ppc64_elf_build_stubs): Move code setting glink .eh_frame to..
+ (ppc64_elf_size_stubs): ..here and..
+ (ppc64_elf_finish_dynamic_sections): ..here.
+
+2014-08-21 Maciej W. Rozycki <macro@codesourcery.com>
+
+ * elf64-ppc.h (ppc64_elf_set_toc): Fix indentation.
+
+2014-08-21 Tony Wang <tony.wang@arm.com>
+
+ * elf32-arm.c (elf32_arm_final_link_relocate): Implement
+ the veneer routine for R_ARM_THM_JUMP19.
+ (arm_type_of_stub): Add conditional clause for R_ARM_THM_JUMP19
+ (elf32_arm_size_stub): Ditto.
+
+2014-08-20 Roland McGrath <mcgrathr@google.com>
+
+ PR ld/17277
+ * elf32-arm.c (elf32_arm_check_relocs): Increment P->pc_count for
+ all reloc types with pc_relative set in the howto, not just for
+ R_ARM_REL32 and R_ARM_REL32_NOI.
+ (allocate_dynrelocs_for_symbol): Update comment.
+ (elf32_arm_gc_sweep_hook): For all reloc types with pc_relative
+ set in the howto, set call_reloc_p and may_need_local_target_p but
+ not may_become_dynamic_p; not only for R_ARM_REL32 and R_ARM_REL32_NOI.
+ (elf32_arm_check_relocs): Likewise.
+
+2014-08-20 Will Newton <will.newton@linaro.org>
+
+ * config.bfd: Default armeb-*-eabi* to big endian.
+
+2014-08-19 Alan Modra <amodra@gmail.com>
+
+ * configure: Regenerate.
+
+2014-08-18 Alan Modra <amodra@gmail.com>
+
+ * elf64-ppc.c (ppc64_elf_adjust_dynamic_symbol): Don't attempt to
+ use dynrelocs for ifunc.
+ * elf32-ppc.c (ppc_elf_adjust_dynamic_symbol): Similarly.
+
+2014-08-18 Alan Modra <amodra@gmail.com>
+
+ PR 17287
+ * elflink.c (on_needed_list): Only consider libraries that have
+ been loaded.
+
+2014-08-18 Alan Modra <amodra@gmail.com>
+
+ * elflink.c (bfd_elf_discard_info): Return int error status.
+ * stabs.c (_bfd_discard_section_stabs): Comment typo fix.
+ * bfd-in.h (bfd_elf_discard_info): Updata prototype.
+ * bfd-in2.h: Regenerate.
+
+2014-08-14 Alan Modra <amodra@gmail.com>
+
+ * peXXigen.c (pe_print_reloc): Protect against access past end
+ of .reloc section.
+
+2014-08-14 Alan Modra <amodra@gmail.com>
+
+ PR 16563
+ * elflink.c (bfd_elf_discard_info): Process .eh_frame and .stab
+ in the order they are mapped to output sections.
+
+2014-08-14 Alan Modra <amodra@gmail.com>
+
+ * configure.ac: Delete redundant plugin related checks.
+ * configure: Regenerate.
+
+2014-08-13 Stefan Kristiansson <stefan.kristiansson@saunalahti.fi>
+
+ * elf32-or1k.c (or1k_elf_relocate_section, or1k_elf_check_relocs,
+ allocate_dynrelocs): Use SYMBOL_REFERENCES_LOCAL, SYMBOL_CALLS_LOCAL
+ and SYMBOLIC_BIND.
+
+2014-08-12 Alan Modra <amodra@gmail.com>
+
+ * coff-aux.c (coff_m68k_aux_link_add_one_symbol): Only call "notice"
+ here when not calling the generic add_symbol function. Formatting.
+ Correct handling of indirect symbols. Update notice call.
+ * elflink.c (_bfd_elf_notice_as_needed): Update notice call.
+ * linker.c (_bfd_generic_link_add_one_symbol): Create indirect
+ symbols early. Update notice call. Add comments regarding weak
+ symbols vs. indirect.
+
+2014-08-12 Alan Modra <amodra@gmail.com>
+
+ PR ld/16746
+ * linker.c (_bfd_generic_link_add_one_symbol <WARN>): Handle
+ !lto_plugin_active.
+
+2014-08-07 Chen Gang <gang.chen.5i5j@gmail.com>
+
+ * coff-ppc.c (coff_ppc_relocate_section): Ensure local symbols are
+ zero terminated.
+
+2014-08-07 H.J. Lu <hongjiu.lu@intel.com>
+ Alan Modra <amodra@gmail.com>
+
+ PR ld/16746
+ * linker.c (_bfd_generic_link_add_one_symbol): Don't issue a
+ warning for references in LTO IR to warning symbols.
+
+2014-08-07 Alan Modra <amodra@gmail.com>
+
+ * linker.c (WARN, CWARN): Collapse these states to WARN.
+ (_bfd_generic_link_add_one_symbol): Use old CWARN case for
+ new WARN.
+
+2014-08-05 Doug Evans <dje@google.com>
+
+ * bfd-in2.h: Regenerate.
+ * libcoff.h: Regenerate.
+
+2014-08-05 Maciej W. Rozycki <macro@codesourcery.com>
+
+ * elfxx-mips.c (_bfd_mips_elf_discard_info): Set section's
+ rawsize if changing size.
+
+2014-08-05 Alan Modra <amodra@gmail.com>
+
+ PR ld/17226
+ * elfxx-sparc.c (_bfd_sparc_elf_gc_sweep_hook): Typo fix.
+
+2014-08-05 Alan Modra <amodra@gmail.com>
+
+ * linker.c (generic_link_check_archive_element): Move handling
+ of command link -u symbols with a common symbol def to the
+ code handling non-common symbols so that archive element symbols
+ are loaded. Use generic_link_add_object_symbols.
+
+2014-08-05 Alan Modra <amodra@gmail.com>
+
+ PR 13557
+ * linker.c (struct archive_list, struct archive_hash_entry,
+ struct archive_hash_table, archive_hash_newfunc,
+ archive_hash_table_init, archive_hash_lookup, archive_hash_allocate,
+ archive_hash_table_free): Delete.
+ (_bfd_generic_link_add_archive_symbols): Add h and name params to
+ checkfn. Rewrite using a straight-forward scan over archive map.
+ (generic_link_check_archive_element_no_collect,
+ generic_link_check_archive_element_collect,
+ generic_link_check_archive_element): Add h and name params.
+ * aoutx.h (aout_link_check_archive_element): Likewise.
+ * pdp11.c (aout_link_check_archive_element): Likewise.
+ * xcofflink.c (xcoff_link_check_archive_element): Likewise.
+ * cofflink.c (coff_link_check_archive_element): Likewise. Don't
+ scan symbols, simply add archive element whenever h is undefined.
+ (coff_link_check_ar_symbols): Delete.
+ * ecoff.c (read_ext_syms_and_strs): Delete.
+ (reread_ext_syms_and_strs): Delete.
+ (ecoff_link_check_archive_element): Add h and name param. Don't
+ scan symbols, simply add based on h. Use ecoff_link_add_object_symbols.
+ * elflink.c (elf_link_is_defined_archive_symbol): Don't test
+ archive_pass.
+ (elf_link_add_archive_symbols): Delete "defined" array, merge
+ functionality into "included". Make "included" a char array. Don't
+ set or test archive_pass.
+ * libbfd-in.h (_bfd_generic_link_add_archive_symbols): Update.
+ * libbfd.h: Regenerate.
+
+2014-08-01 Takashi Yoshii <yoshii.takashi@renesas.com>
+
+ PR 10373
+ * elf32-sh.c (sh_elf_relax_section): Add jmp to bra relaxing.
+
+2014-07-29 Matthew Fortune <matthew.fortune@imgtec.com>
+
+ * elfxx-mips.c (ABI_O32_P, MIPS_ELF_ABIFLAGS_SECTION_NAME_P): New macro.
+ (mips_elf_obj_tdata): Add abiflags and abiflags_valid fields.
+ (bfd_mips_elf_swap_abiflags_v0_in): New function.
+ (bfd_mips_elf_swap_abiflags_v0_out): Likewise.
+ (_bfd_mips_elf_section_from_shdr): Handle SHT_MIPS_ABIFLAGS.
+ (_bfd_mips_elf_fake_sections): Likewise.
+ (_bfd_mips_elf_always_size_sections): Handle .MIPS.abiflags.
+ (_bfd_mips_elf_additional_program_headers): Account for new
+ PT_MIPS_ABIFLAGS program header.
+ (_bfd_mips_elf_modify_segment_map): Create PT_MIPS_ABIFLAGS segment and
+ associate with .MIPS.abiflags.
+ (_bfd_mips_elf_gc_mark_extra_sections): New function.
+ (bfd_mips_isa_ext, update_mips_abiflags_isa): New static function.
+ (infer_mips_abiflags): Likewise.
+ (_bfd_mips_elf_final_link): Handle .MIPS.abiflags.
+ (mips_32bit_flags_p): Moved higher.
+ (mips_elf_merge_obj_attributes, _bfd_mips_fp_abi_string): Error
+ checking for FP ABIs.
+ (_bfd_mips_elf_merge_private_bfd_data): Restructure and add abiflags
+ checks. Check EF_MIPS_FP64 flag consistency.
+ (print_mips_ases, print_mips_isa_ext): New static function.
+ (print_mips_fp_abi_value, get_mips_reg_size): Likewise.
+ (_bfd_mips_elf_print_private_bfd_data): Display abiflags data.
+ (_bfd_mips_post_process_headers): Set EI_ABIVERSION = 3 for
+ Val_GNU_MIPS_ABI_FP_64 or Val_GNU_MIPS_ABI_FP_64A.
+ * elfxx-mips.h (_bfd_mips_elf_gc_mark_extra_sections): New prototype.
+ * elf32-mips.c (elf_backend_gc_mark_extra_sections): Implement.
+ * elfn32-mips.c (elf_backend_gc_mark_extra_sections): Implement.
+ * elf64-mips.c (elf_backend_gc_mark_extra_sections): Implement.
+
+2014-07-28 Alan Modra <amodra@gmail.com>
+
+ PR 13227
+ * archive.c (_bfd_compute_and_write_armap): Warn on adding
+ __gnu_lto_slim to armap.
+ * linker.c (_bfd_generic_link_add_one_symbol): Warn on adding
+ __gnu_lto_slim to linker hash table.
+
+2014-07-27 Anthony Green <green@moxielogic.org>
+
+ * config.bfd: Add moxie-*-moxiebox*.
+
+2014-07-21 Joel Sherrill <joel.sherrill@oarcorp.com>
+
+ Add or reactivate or1k-*-rtems*
+ * config.bfd (or1k-*-rtems*): Reactivate.
+
+2014-07-16 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf32-i386.c (elf_i386_plt_sym_val): Match PLT entry only for
+ ELFOSABI_GNU input.
+ * elf64-x86-64.c (elf_x86_64_plt_sym_val): Likewise.
+ (elf_x86_64_plt_sym_val_offset_plt_bnd): Likewise.
+
+2014-07-16 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR binutils/17154
+ * elf32-i386.c (elf_i386_plt_sym_val): Only match R_*_JUMP_SLOT
+ and R_*_IRELATIVE relocation offset with PLT entry.
+ * elf64-x86-64.c (elf_x86_64_plt_sym_val): Likewise.
+ (elf_x86_64_plt_sym_val_offset_plt_bnd): New.
+ (elf_x86_64_get_synthetic_symtab): Use it.
+
+2014-07-15 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/17057
+ * elf32-i386.c (elf_i386_compute_jump_table_size): Replace
+ next_tls_desc_index with elf.srelplt->reloc_count.
+
+2014-07-15 Alan Modra <amodra@gmail.com>
+
+ * cache.c (cache_bread_1): Don't return -1 when fread returns
+ a positive value.
+
+2014-07-15 Alan Modra <amodra@gmail.com>
+
+ * elflink.c (elf_merge_st_other): Update comments. Simplify
+ visibility handling. Make isym const. Move code modifying
+ isym->st_other for --exclude-libs to..
+ (elf_link_add_object_symbols): ..here.
+
+2014-07-11 Maks Naumov <maksqwe1@ukr.net>
+
+ PR 17141
+ * elf.c (_bfd_elf_strtab_add): Check strtab name for failure.
+
+2014-07-08 Nick Clifton <nickc@redhat.com>
+
+ PR ld/17110
+ * elf32-sh.c (sh_elf_osec_to_segment): Do not look for output
+ segments in input bfds.
+
+2014-07-08 Will Newton <will.newton@linaro.org>
+
+ * elf32-arm.c (ELF_MAXPAGESIZE): Increase the default
+ value to 64kB and remove custom setting for NaCl.
+
+2014-07-08 Alan Modra <amodra@gmail.com>
+
+ * elflink.c (_bfd_elf_copy_link_hash_symbol_type): Copy st_other
+ bits from source to dest.
+ * linker.c (_bfd_generic_copy_link_hash_symbol_type): Update comment.
+ * targets.c (struct bfd_target <_bfd_copy_link_hash_symbol_type>):
+ Likewise.
+ * bfd-in2.h: Regenerate.
+
+2014-07-08 Jiong Wang <jiong.wang@arm.com>
+
+ * elfnn-aarch64.c (elf_backend_rela_normal): Set to 1.
+ (elfNN_aarch64_relocate_section): Remove duplicated addend adjustment
+ when info->relocatable be true.
+
+2014-07-07 Barney Stratford <barney_stratford@fastmail.fm>
+
+ * elf32-avr.c: Handle R_AVR_PORT5 and R_AVR_PORT6.
+ * reloc.c: Add BFD_RELOC_AVR_PORT5 and BFD_RELOC_AVR_PORT6.
+ * bfd-in2.h: Regenerate.
+ * libbfd.h: Regenerate.
+
+2014-07-04 Alan Modra <amodra@gmail.com>
+
+ * Makefile.am: Update "configure.in" comments.
+ * PORTING: Likewise.
+ * aoutx.h: Likewise.
+ * configure.host: Likewise.
+ * doc/bfdint.texi: Likewise.
+ * targets.c: Likewise.
+ * warning.m4: Likewise.
+ * Makefile.in: Regenerate.
+
+2014-07-04 Alan Modra <amodra@gmail.com>
+
+ * configure.ac: Rename from configure.in.
+ * Makefile.in: Regenerate.
+ * config.in: Regenerate.
+ * doc/Makefile.in: Regenerate.
+
+2014-07-04 Alan Modra <amodra@gmail.com>
+
+ * Makefile.am (CONFIG_STATUS_DEPENDENCIES): Remove configure.in.
+ * Makefile.in: Regenerate.
+
+2014-07-04 Alan Modra <amodra@gmail.com>
+
+ * version.m4: New file.
+ * configure.in: Include version.m4.
+ (AC_INIT): Update.
+ * Makefile.am (RELEASE): Delete.
+ (bfdver.h): Depend on development.sh, use instead of RELEASE.
+ * Makefile.in: Regenerate.
+ * doc/Makefile.in: Regenerate.
+
+2014-07-02 Alan Modra <amodra@gmail.com>
+
+ * elf32-ppc.c (ppc_elf_adjust_dynamic_symbol): Clear
+ pointer_equality_needed when !readonly_dynrelocs.
+ * elf64-ppc.c (ppc64_elf_adjust_dynamic_symbol): Likewise.
+
+2014-07-02 Alan Modra <amodra@gmail.com>
+
+ * elf32-ppc.c (ppc_elf_check_relocs): Set DF_STATIC_TLS for PIEs too.
+ * elf64-ppc.c (ppc64_elf_check_relocs): Likewise.
+
+2014-07-01 Alan Modra <amodra@gmail.com>
+
+ * bfd.c (struct bfd): Reorganise for better packing. Delete
+ "ifd" field. Make "format", "direction" and "flags" bitfields.
+ (HAS_LOAD_PAGE): Delete, renumber following flags.
+ * bfd-in2.h: Regenerate.
+ * coff-tic4x.c: Remove HAS_LOAD_PAGE from extra flags in target vecs.
+
+2014-07-01 Alan Modra <amodra@gmail.com>
+
+ * elf64-ppc.c (ppc_stub_type): Add ppc_stub_global_entry.
+ (struct ppc_link_hash_table): Increase size of stub_count array.
+ (build_global_entry_stubs): Emit symbol on global entry stub.
+ (ppc64_elf_build_stubs): NULL check htab->brlt. Add global entry
+ stub stats.
+
+2014-07-01 Alan Modra <amodra@gmail.com>
+
+ * elf64-ppc.c (abiversion, set_abiversion): Move earlier.
+ (ppc64_elf_branch_reloc): Adjust addend for ELFv2 local offset.
+ (ppc64_elf_set_toc): Set ".TOC." symbol value when using
+ generic linker.
+ (ppc64_elf_relocate_section): Disable ELFv2 function entry
+ optimisation when --traditional-format.
+
+2014-07-01 Barney Stratford <barney_stratford@fastmail.fm>
+ Senthil Kumar Selvaraj <senthil_kumar.selvaraj@atmel.com>
+ Pitchumani Sivanupandi <pitchumani.s@atmel.com>
+ Soundararajan <Sounderarajan.D@atmel.com>
+
+ * archures.c: Add avrtiny architecture for avr target.
+ * cpu-avr.c (arch_info_struct): Add avrtiny arch info.
+ * elf32-avr.c (elf_avr_howto_table): New relocation R_AVR_LDS_STS_16
+ added for 16 bit LDS/STS instruction of avrtiny arch.
+ (avr_reloc_map): Reloc R_AVR_LDS_STS_16 is mapped to
+ BFD_RELOC_AVR_LDS_STS_16.
+ (bfd_elf_avr_final_write_processing): Select machine number
+ avrtiny arch.
+ (elf32_avr_object_p): Set machine number for avrtiny arch.
+ * reloc.c: Add documentation for BFD_RELOC_AVR_LDS_STS_16 reloc.
+ * bfd-in2.h: Regenerate.
+ * libbfd.h: Regenerate.
+
+2014-06-26 Nick Clifton <nickc@redhat.com>
+
+ PR binutils/16949
+ * dwarf2.c (is_str_attr): New function.
+ (find_abstract_instance_name): Use it to determine when an
+ attribute has a string value.
+
+2014-06-24 Alan Modra <amodra@gmail.com>
+
+ * elf32-ppc.c (ppc_elf_size_dynamic_sections): Arrange to keep
+ .sdata/.sdata2 when _SDA_BASE_/_SDA2_BASE_ should be output
+ for --emit-relocs.
+
+2014-06-21 Philippe De Muyter <phdm@macqel.be>
+
+ * targets.c (_bfd_target_vector): Add missing #ifdef BFD64 for
+ a number of targets.
+
+2014-06-20 Kyle McMartin <kyle@redhat.com>
+
+ * elf32-arm.c (elf32_arm_check_relocs): Set DF_STATIC_TLS when
+ emitting initial-exec relocs when not linking an executable.
+
+2014-06-16 Will Newton <will.newton@linaro.org>
+
+ * elf32-arm.c (elf32_arm_allocate_plt_entry): Increment
+ htab->next_tls_desc_index in the non-IPLT case.
+ Calculate GOT offset correctly for the non-IPLT case.
+ (allocate_dynrelocs_for_symbol): Don't increment
+ htab->next_tls_desc_index here.
+
+2014-06-16 Alan Modra <amodra@gmail.com>
+
+ * elf32-vax.c (elf_vax_size_dynamic_sections): Clear linker
+ created sections.
+
+2014-06-13 Omair Javaid <omair.javaid@linaro.org>
+
+ * elfxx-aarch64.c (stdarg.h): Include.
+ (string.h): Include.
+ (_bfd_aarch64_elf_grok_prstatus): Updated.
+ (_bfd_aarch64_elf_grok_psinfo): New function.
+ (_bfd_aarch64_elf_write_core_note): New function.
+ * elfxx-aarch64.h (elf_backend_grok_psinfo): Define.
+ (elf_backend_write_core_note): Define.
+
+2014-06-13 Alan Modra <amodra@gmail.com>
+
+ * archive.c: Include bfdlink.h.
+ (_bfd_archive_close_and_cleanup): Call linker hash_table_free.
+ * bfd.c (struct bfd): Add is_linker_output field.
+ * elf-bfd.h (_bfd_elf_link_hash_table_free): Update prototype.
+ * linker.c (_bfd_link_hash_table_init): Set up hash_table_free,
+ link.hash and is_linker_output.
+ (_bfd_generic_link_hash_table_free): Replace bfd_link_hash_table*
+ param with bfd*. Assert is_linker_output and link.hash, and
+ clear them before exit.
+ * elf-m10300.c (elf32_mn10300_link_hash_table_free): Replace
+ bfd_link_hash_table* param with bfd*. Hack is_linker_output
+ and link.hash so we can free two linker hash tables.
+ (elf32_mn10300_link_hash_table_create): Create static_hash_table
+ first. Clean up on errors. Set hash_table_free pointer.
+ * elf32-arm.c (elf32_arm_link_hash_table_free): Replace
+ bfd_link_hash_table* param with bfd*.
+ (elf32_arm_link_hash_table_create): Clean up on errors. Set
+ hash_table_free pointer.
+ * elf32-avr.c, * elf32-hppa.c, * elf32-i386.c, * elf32-m68hc1x.c,
+ * elf32-m68k.c, * elf32-metag.c, * elf32-nios2.c, * elf32-xgate.c,
+ * elf64-ia64-vms.c, * elf64-ppc.c, * elf64-x86-64.c, * elflink.c,
+ * elfnn-aarch64.c, * elfnn-ia64.c, * elfxx-sparc.c,
+ * xcofflink.c: Similarly.
+ * simple.c (bfd_simple_get_relocated_section_contents): Save and
+ clear link.next before creating linker hash table. Clean up on
+ errors, and restore link.next on exit.
+ * elf32-m68hc1x.h (m68hc11_elf_bfd_link_hash_table_free): Delete.
+ * elf32-xgate.h (xgate_elf_bfd_link_hash_table_free): Delete.
+ * elfxx-sparc.h (_bfd_sparc_elf_link_hash_table_free): Delete.
+ * libcoff-in.h (_bfd_xcoff_bfd_link_hash_table_free): Delete.
+ * hash.c (bfd_hash_table_init_n): Free table on error.
+ * libbfd-in.h (_bfd_generic_link_hash_table_free): Update proto.
+ * bfd-in2.h: Regenerate.
+ * libbfd.h: Regenerate.
+ * libcoff.h: Regenerate.
+
+2014-06-13 Alan Modra <amodra@gmail.com>
+
+ PR 17047
+ * targets.c (BFD_JUMP_TABLE): Delete NAME##_bfd_link_hash_table_free.
+ (struct bfd_target <_bfd_link_hash_table_free>): Delete.
+ * bfd.c (bfd_link_hash_table_free): Don't define.
+ * aout-adobe.c, * aout-target.h, * aout-tic30.c, * binary.c, * bout.c,
+ * coff64-rs6000.c, * coffcode.h, * elf-m10300.c, * elf32-arm.c,
+ * elf32-avr.c, * elf32-hppa.c, * elf32-i386.c, * elf32-m68hc11.c,
+ * elf32-m68hc12.c, * elf32-m68k.c, * elf32-metag.c, * elf32-nios2.c,
+ * elf32-sparc.c, * elf32-xgate.c, * elf64-ia64-vms.c, * elf64-ppc.c,
+ * elf64-sparc.c, * elf64-x86-64.c, * elfnn-aarch64.c, * elfnn-ia64.c,
+ * elfxx-target.h, * i386msdos.c, * i386os9k.c, * ieee.c, * ihex.c,
+ * libbfd-in.h, * libecoff.h, * mach-o-target.c, * mmo.c,
+ * nlm-target.h, * oasys.c, * pef.c, * plugin.c, * ppcboot.c, * som.c,
+ * srec.c, * tekhex.c, * verilog.c, * versados.c, * vms-alpha.c,
+ * xsym.c: Don't define various link_hash_table_free defines, and
+ remove from bfd_target vars. Temporarily reference some of the
+ target link_hash_table_free functions to avoid warnings.
+ * bfd-in2.h: Regenerate.
+ * libbfd.h: Regenerate.
+
+2014-06-13 Alan Modra <amodra@gmail.com>
+
+ * elf-m10300.c, * elf32-arm.c, * elf32-avr.c, * elf32-hppa.c,
+ * elf32-i386.c, * elf32-m68hc1x.c, * elf32-m68k.c, * elf32-metag.c,
+ * elf32-nios2.c, * elf64-ia64-vms.c, * elf64-ppc.c, * elf64-x86-64.c,
+ * elfnn-aarch64.c, * elfnn-ia64.c, * elfxx-sparc.c, * xcofflink.c:
+ Move link_hash_table_free functions before their corresponding
+ link_hash_table_create functions.
+
+2014-06-13 Alan Modra <amodra@gmail.com>
+
+ * bfd.c (struct bfd): Replace link_next with a union.
+ * aoutx.h, * bfd.c, * coff-ppc.c, * coff-rs6000.c, * cofflink.c,
+ * ecoff.c, * elf-m10300.c, * elf32-arm.c, * elf32-avr.c,
+ * elf32-hppa.c, * elf32-i386.c, * elf32-lm32.c, * elf32-m32c.c,
+ * elf32-m32r.c, * elf32-m68hc1x.c, * elf32-metag.c,
+ * elf32-microblaze.c, * elf32-nds32.c, * elf32-nios2.c,
+ * elf32-or1k.c, * elf32-ppc.c, * elf32-rl78.c, * elf32-s390.c,
+ * elf32-score.c, * elf32-score7.c, * elf32-sh.c, * elf32-spu.c,
+ * elf32-tic6x.c, * elf32-tilepro.c, * elf32-xstormy16.c,
+ * elf32-xtensa.c, * elf64-alpha.c, * elf64-hppa.c, * elf64-ia64-vms.c,
+ * elf64-mmix.c, * elf64-ppc.c, * elf64-s390.c, * elf64-x86-64.c,
+ * elflink.c, * elfnn-aarch64.c, * elfxx-mips.c, * elfxx-sparc.c,
+ * elfxx-tilegx.c, * linker.c, * pdp11.c, * peXXigen.c, * simple.c,
+ * sunos.c, * vms-alpha.c, * xcofflink.c: Update for above.
+ * bfd-in2.h: Regenerate.
+
+2014-06-11 Alan Modra <amodra@gmail.com>
+
+ * linker.c (unwrap_hash_lookup): Add missing parens.
+
+2014-06-11 Kai Tietz <ktietz@redhat.com>
+
+ * libcoff-in.h (coff_tdata): Make relocbase member unsigned.
+ * libcoff.h: Regenerated.
+
+2014-06-10 Alan Modra <amodra@gmail.com>
+
+ PR ld/16910
+ * linker.c (unwrap_hash_lookup): New function.
+ * elf-bfd.h (RELOC_FOR_GLOBAL_SYMBOL): Call unwrap_hash_lookup.
+ * elf32-i370.c (i370_elf_relocate_section): Likewise.
+ * elf32-m32c.c (m32c_elf_relocate_section): Likewise.
+ * elf32-m32r.c (m32r_elf_relocate_section): Likewise.
+ * elf32-score.c (s3_bfd_score_elf_relocate_section): Likewise.
+ * elf32-score7.c (s7_bfd_score_elf_relocate_section): Likewise.
+ * elf32-spu.c (spu_elf_relocate_section): Likewise.
+ * elf64-hppa.c (elf64_hppa_relocate_section): Likewise.
+
+2014-06-07 Alan Modra <amodra@gmail.com>
+
+ * elf32-ppc.c (ppc_elf_relocate_section): Treat field of cmpli
+ insn as a bitfield; Use complain_overflow_bitfield.
+ * elf64-ppc.c (ppc64_elf_relocate_section): Likewise.
+
+2014-06-05 Joel Brobecker <brobecker@adacore.com>
+
+ * development.sh: New file.
+ * warning.m4 (AM_BINUTILS_WARNINGS): Source bfd/development.sh.
+ Make -Werror the default with GCC only if DEVELOPMENT is true.
+ * Makefile.am (CONFIG_STATUS_DEPENDENCIES): Add
+ $(srcdir)/development.sh.
+ * Makefile.in, configure: Regenerate.
+
+2014-06-04 Will Newton <will.newton@linaro.org>
+
+ * elfnn-aarch64.c (tpoff_base): Make test of tls_sec
+ being non-NULL into an assert.
+ (elfNN_aarch64_tls_relax): Remove unused code.
+
+2014-06-03 DJ Delorie <dj@redhat.com>
+
+ * elf32-rx.c (rx_table_map): Use BFD_VMA_FMT for portability.
+
+2014-06-03 Nick Clifton <nickc@redhat.com>
+
+ PR ld/16807
+ * peXXigen.c (rsrc_process_section): Page align the new contents
+ befgore writing out.
+
+2014-06-03 Alan Modra <amodra@gmail.com>
+
+ * elf64-ppc.c (ADDIS_R12_R2): Define.
+ (build_plt_stub): Support fusion on ELFv2 stub.
+ (ppc_build_one_stub): Likewise for plt branch stubs.
+
+2014-05-28 Alan Modra <amodra@gmail.com>
+
+ * elf32-rx.c (rx_table_map): Delete set but not used variables.
+
+2014-05-28 Tristan Gingold <gingold@adacore.com>
+
+ * dwarf2.c (lookup_address_in_function_table): Add best_fit_len
+ to keep the length of the best fit range.
+ (lookup_symbol_in_function_table, info_hash_lookup_funcinfo):
+ Likewise.
+
+2014-05-27 DJ Delorie <dj@redhat.com>
+
+ * elf32-rx.c (get_symbol_value_maybe): New.
+ (rx_elf_relocate_section): If we find a reloc against
+ $tableentry$default$<name>, redirect it to the appropriate
+ $tableentry$<n>$.
+ (RX_Table_Info): New.
+ (rx_table_find): New. Check all tables and SEC_KEEP all sections
+ with table parts in them.
+ (rx_check_directives): New.
+ (rx_table_map_2): New.
+ (rx_table_map): New.
+ (rx_additional_link_map_text): New. Called to dump tables to the
+ map file.
+ * elf32-rx.h: New.
+
+2014-05-20 DJ Delorie <dj@redhat.com>
+
+ * elf32-msp430.c (msp430_elf_relax_adjust_locals): Avoid overflow.
+
+2014-05-20 Alan Modra <amodra@gmail.com>
+
+ PR 16952
+ * elf32-ppc.c (ppc_elf_create_linker_section): Move earlier.
+ Remove redundant setting of htab->elf.dynobj. Don't align.
+ Define .sdata symbols using _bfd_elf_define_linkage_sym.
+ (ppc_elf_create_glink): Call ppc_elf_create_linker_section.
+ (create_sdata_sym): Delete.
+ (elf_allocate_pointer_linker_section): Rename from
+ elf_create_pointer_linker_section. Align section.
+ (ppc_elf_check_relocs): Don't call ppc_elf_creat_linker_section
+ directly here, or create_sdata_sym. Set ref_regular on _SDA_BASE_
+ and _SDA2_BASE_.
+ (ppc_elf_size_dynamic_sections): Remove ATTRIBUTE_UNUSED on param.
+ Remove unnecessary tests on _SDA_BASE_ sym.
+ (maybe_strip_sdasym, ppc_elf_maybe_strip_sdata_syms): New functions.
+ (ppc_elf_relocate_section): Tighten SDA reloc symbol section checks.
+ * elf32-ppc.h (ppc_elf_set_sdata_syms): Delete.
+ (ppc_elf_maybe_strip_sdata_syms): Declare.
+
+2014-05-16 Ryan Mansfield <rmansfield@qnx.com>
+
+ * config.bfd: Move QNX target_cflags from arm-*-netbsd* to arm-*-nto*.
+
+2014-05-16 Jon Turney <jon.turney@dronecode.org.uk>
+
+ * peXXigen.c (pe_print_debugdata): Don't interpret debug directory
+ in a section with no contents.
+ (is_vma_in_section, find_section_by_vma): New functions.
+ (_bfd_XX_bfd_copy_private_bfd_data_common): Recalculate file
+ offsets in the debug directory.
+ (_bfd_XXi_slurp_codeview_record, _bfd_XXi_write_codeview_record):
+ Byte-swap GUID from little-endian to big-endian order for
+ consistent and conventional display.
+
+2014-05-16 Kaushik Phata <Kaushik.Phatak@kpit.com>
+
+ * elf32-rl78.c (rl78_elf_merge_private_bfd_data): Complain if
+ 64-bit doubles objects mix with 32-bit doubles objects.
+ (rl78_elf_print_private_bfd_data): Describe 64-bit doubles flag.
+
+2014-05-08 Hans-Peter Nilsson <hp@bitrange.com>
+
+ * mmo.c: Update URLs in documentation comments.
+
+2014-05-02 Volodymyr Arbatov <arbatov@cadence.com>
+ David Weatherford <weath@cadence.com>
+ Max Filippov <jcmvbkbc@gmail.com>
+
+ * elf32-xtensa.c (relax_section): treat R_XTENSA_DIFF* relocations as
+ signed.
+
+2014-05-07 Andreas Tobler <andreast@fgznet.ch>
+
+ * config.bfd: Add proper arm config for *-*-freebsd*.
+
+2014-05-07 Andrew Bennett <andrew.bennett@imgtec.com>
+
+ * aoutx.h (NAME (aout, machine_type)): Add mips32r3, mips64r3,
+ mips32r5 and mips64r5.
+ * archures.c (bfd_architecture): Likewise.
+ * bfd-in2.h (bfd_architecture): Likewise.
+ * cpu-mips.c (arch_info_struct): Likewise.
+ * elfxx-mips.c (mips_set_isa_flags): Likewise.
+
+2014-05-06 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * elfxx-mips.h (elfxx-mips.h): Declare.
+ * elfxx-mips.c (mips_elf_merge_obj_attributes): Use it to report
+ Tag_GNU_MIPS_ABI_FP mismatches.
+ (_bfd_mips_fp_abi_string): New function.
+
+2014-05-02 Alan Modra <amodra@gmail.com>
+
+ * targets.c: Sort bfd_target vectors somewhat alphabetically.
+ * configure.in: Likewise.
+ * configure: Regenerate.
+
+2014-05-02 Alan Modra <amodra@gmail.com>
+
+ * aix386-core.c, * aout-adobe.c, * aout-arm.c, * aout-ns32k.c,
+ * aout-sparcle.c, * aout0.c, * aoutx.h, * armnetbsd.c, * bout.c,
+ * cf-i386lynx.c, * cf-sparclynx.c, * cisco-core.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-mips.c,
+ * coff-rs6000.c, * coff-sh.c, * coff-sparc.c, * coff-stgo32.c,
+ * coff-svm68k.c, * coff-tic80.c, * coff-u68k.c, * coff-w65.c,
+ * coff-we32k.c, * coff-x86_64.c, * coff-z80.c, * coff-z8k.c,
+ * coff64-rs6000.c, * config.bfd, * configure.com, * configure.in,
+ * demo64.c, * elf-m10200.c, * elf-m10300.c, * elf32-am33lin.c,
+ * elf32-arc.c, * elf32-arm.c, * elf32-avr.c, * elf32-bfin.c,
+ * elf32-cr16.c, * elf32-cr16c.c, * elf32-cris.c, * elf32-crx.c,
+ * elf32-d10v.c, * elf32-d30v.c, * elf32-dlx.c, * elf32-epiphany.c,
+ * elf32-fr30.c, * elf32-frv.c, * elf32-gen.c, * elf32-h8300.c,
+ * elf32-hppa.c, * elf32-i370.c, * elf32-i386.c, * elf32-i860.c,
+ * elf32-i960.c, * elf32-ip2k.c, * elf32-iq2000.c, * elf32-lm32.c,
+ * elf32-m32c.c, * elf32-m32r.c, * elf32-m68hc11.c, * elf32-m68hc12.c,
+ * elf32-m68k.c, * elf32-m88k.c, * elf32-mcore.c, * elf32-mep.c,
+ * elf32-metag.c, * elf32-microblaze.c, * elf32-mips.c, * elf32-moxie.c,
+ * elf32-msp430.c, * elf32-mt.c, * elf32-nds32.c, * elf32-nios2.c,
+ * elf32-or1k.c, * elf32-pj.c, * elf32-ppc.c, * elf32-rl78.c,
+ * elf32-rx.c, * elf32-s390.c, * elf32-score.c, * elf32-sh-symbian.c,
+ * elf32-sh.c, * elf32-sh64.c, * elf32-sparc.c, * elf32-spu.c,
+ * elf32-tic6x.c, * elf32-tilegx.c, * elf32-tilepro.c, * elf32-v850.c,
+ * elf32-vax.c, * elf32-xc16x.c, * elf32-xgate.c, * elf32-xstormy16.c,
+ * elf32-xtensa.c, * elf64-alpha.c, * elf64-gen.c, * elf64-hppa.c,
+ * elf64-ia64-vms.c, * elf64-mips.c, * elf64-mmix.c, * elf64-ppc.c,
+ * elf64-s390.c, * elf64-sh64.c, * elf64-sparc.c, * elf64-tilegx.c,
+ * elf64-x86-64.c, * elfn32-mips.c, * elfnn-aarch64.c, * elfnn-ia64.c,
+ * epoc-pe-arm.c, * epoc-pei-arm.c, * hp300bsd.c, * hp300hpux.c,
+ * 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,
+ * irix-core.c, * m68k4knetbsd.c, * m68klinux.c, * m68knetbsd.c,
+ * m88kmach3.c, * m88kopenbsd.c, * mach-o-i386.c, * mach-o-x86-64.c,
+ * makefile.vms, * mipsbsd.c, * mmo.c, * netbsd-core.c, * newsos3.c,
+ * nlm32-alpha.c, * nlm32-i386.c, * nlm32-ppc.c, * nlm32-sparc.c,
+ * ns32knetbsd.c, * osf-core.c, * pc532-mach.c, * pe-arm-wince.c,
+ * pe-arm.c, * pe-i386.c, * pe-mcore.c, * pe-mips.c, * pe-ppc.c,
+ * pe-sh.c, * pe-x86_64.c, * pei-arm-wince.c, * pei-arm.c,
+ * pei-i386.c, * pei-ia64.c, * pei-mcore.c, * pei-mips.c, * pei-ppc.c,
+ * pei-sh.c, * pei-x86_64.c, * ppcboot.c, * ptrace-core.c, * riscix.c,
+ * sco5-core.c, * som.c, * sparclinux.c, * sparclynx.c,
+ * sparcnetbsd.c, * sunos.c, * targets.c, * trad-core.c,
+ * vax1knetbsd.c, * vaxbsd.c, * vaxnetbsd.c, * versados.c,
+ * vms-alpha.c, * vms-lib.c: Rename bfd targets to
+ <cpu>_<format>_<other>_<endian>_vec. Adjust associated MY macros
+ on aout targets.
+ * configure: Regenerate.
+
+2014-05-01 Hans-Peter Nilsson <hp@bitrange.com>
+
+ * mmo.c (mmo File layout documentation): Add note about low bits
+ of address.
+ (mmo_write_chunk): When handling data remainder, assert that
+ previous remaining data is flushed.
+ (mmo_write_loc_chunk): Only look for trailing and leading zeros
+ when dealing with an aligned VMA and for aligned lengths. Don't skip
+ the last 32-bit-word of zeros.
+ (mmo_write_loc_chunk): Emit an error if the VMA is not aligned.
+ (mmo_scan) <case LOP_QUOTE>: Move re-alignment of vma before
+ emitting data, not after updating it.
+ <case LOP_LOC>: Call mmo_decide_section with aligned vma.
+
+2014-04-30 Nick Clifton <nickc@redhat.com>
+
+ * compress.c (bfd_is_section_compressed): When checking the
+ .debug_str section, also check the fifth byte in the section is
+ not part of a string.
+
+2014-04-30 Alan Modra <amodra@gmail.com>
+
+ * elf-eh-frame.c (struct cie.personality): Replace val with sym.
+ (find_merged_cie): Identify personality functions by (bfd_id,index)
+ pair when a local sym is used.
+
+2014-04-29 Christian Svensson <blue@cmd.nu>
+
+ * elf32-or1k.c: Fix a bug where non-TLS relocations would be forced
+ into .rela.got if it contained TLS relocations as well.
+
+2014-04-28 Nick Clifton <nickc@redhat.com>
+
+ PR ld/16821
+ * peXXigen.c (_bfd_XXi_swap_sym_out): Rework fix to avoid compile
+ time warning.
+
+2014-04-26 Alan Modra <amodra@gmail.com>
+
+ * po/SRC-POTFILES.in: Regenerate.
+ * configure: Regenerate.
+
+2014-04-25 Nick Clifton <nickc@redhat.com>
+
+ PR ld/16821
+ * peXXigen.c (_bfd_XXi_swap_sym_out): Another fix for building on
+ a 342-bit host. This time for older versions of gcc.
+
+2014-04-24 Nick Clifton <nickc@redhat.com>
+
+ * peXXigen.c (rsrc_print_section): Fix compile time warning for
+ 32-bit hosts.
+
+2014-04-24 Alan Modra <amodra@gmail.com>
+
+ PR 16867
+ * dwarf2.c: Formatting.
+ (struct dwarf2_debug): Make adjusted_section_count signed.
+ (unset_sections): Make i signed.
+ (set_debug_vma): New function.
+ (place_sections): Handle separate debug object file. Set VMA
+ on debug sections, even if they have an output section. Also
+ set VMA on zero size sections, and non-load but alloc sections.
+ Set adjusted_section_count to -1 when no section adjustment.
+ Malloc adjusted_sections. Don't double last_vma. Transfer
+ alloc section VMAs to separate debug file.
+ (_bfd_dwarf2_cleanup_debug_info): Free adjusted_sections.
+ (_bfd_dwarf2_slurp_debug_info): Add do_place parameter. Drop
+ test on symbols being the same before using old stash. Read
+ and use separate debug file symbols. Call place_sections.
+ (find_line): Don't call place_sections here.
+ * libbfd-in.h (_bfd_dwarf2_slurp_debug_info): Update proto.
+ * libbfd.h: Regenerate.
+ * mach-o.c (bfd_mach_o_find_nearest_line): Adjust
+ _bfd_dwarf2_slurp_debug_info call.
+ * simple.c (simple_save_output_info): Clarify comment.
+
+2014-04-24 Nick Clifton <nickc@redhat.com>
+
+ PR ld/16807
+ * peXXigen.c (struct rsrc_regions): New structure.
+ (rsrc_print_resource_directory): Use new structure. Include
+ offset of directory in listing.
+ (rsrc_print_resource_entry): Likewise.
+ (rsrc_print_section): Likewise.
+ (rsrc_count_entries): Do not increment sizeof_strings or
+ sizeof_leaves.
+ (rsrc_count_directory): Do not increment sizeof_tables.
+ (rsrc_compute_region_sizes): New function.
+ (rsrc_write_leaf): Maintain 8-byte alignment for resource data.
+ (rsrc_process_section): Compute size of regions after merging
+ entries.
+
+2014-04-23 Alan Modra <amodra@gmail.com>
+
+ PR ld/16787
+ * dwarf2.c (struct dwarf2_debug): Add sec_vma field.
+ (place_sections): Do not modify VMA of sections when called from
+ linker after sections have been placed in output sections. Short
+ circuit single section case.
+ (save_section_vma, section_vma_same): New functions.
+ (_bfd_dwarf2_slurp_debug_info): Throw away stash if section VMAs
+ change.
+ * reloc.c (bfd_perform_relocation): Do not modify reloc addend
+ when non-relocatable.
+
+2014-04-22 Nick Clifton <nickc@redhat.com>
+
+ PR ld/16821
+ * peXXigen.c (_bfd_XXi_swap_sym_out): Fix for 32-bit hosts.
+
+2014-04-22 Christian Svensson <blue@cmd.nu>
+
+ * Makefile.am: Remove openrisc and or32 support. Add support for or1k.
+ * archures.c: Likewise.
+ * coffcode.h: Likewise.
+ * config.bfd: Likewise.
+ * configure.in: Likewise.
+ * reloc.c: Likewise.
+ * targets.c: Likewise.
+ * cpu-or1k.c: New file.
+ * elf32-or1k.c: New file.
+ * coff-or32.c: Delete.
+ * cpu-openrisc.c: Delete.
+ * cpu-or32.c: Delete.
+ * elf32-openrisc.c: Delete.
+ * elf32-or32.c: Delete.
+ * Makefile.in: Regenerate.
+ * bfd-in2.h: Regenerate.
+ * configure: Regenerate.
+ * libbfd.h: Regenerate.
+
+2014-04-22 Yuanhui Zhang <asmwarrior@gmail.com>
+
+ PR ld/16821
+ * peXXigen.c (abs_finder): Fix for 32-bit host builds.
+
+2014-04-22 Will Newton <will.newton@linaro.org>
+
+ * elfnn-aarch64.c (elfNN_aarch64_section_flags): Remove
+ function. (elf_backend_section_flags): Remove define.
+
+2014-04-21 Richard Henderson <rth@redhat.com>
+
+ * elf64-alpha.c (elf64_alpha_size_got_sections): New may_merge
+ parameter; honor it and disable got merging when false.
+ (elf64_alpha_relax_got_load): Do not relax to GPREL relocs during
+ the first pass of relaxation.
+ (elf64_alpha_relax_with_lituse): Likewise. Move relaxed relocs to
+ the end of the LITERAL+LITUSE chain.
+ (elf64_alpha_relax_section): Only process LITERAL relocs during the
+ second pass of relaxation.
+
+ * configure.ac (use_secureplt): Enable by default.
+ * configure: Rebuild.
+
+2014-04-18 Tristan Gingold <gingold@adacore.com>
+
+ * mach-o.h (bfd_mach_o_dyld_info_command): Add rebase_content,
+ bind_content, weak_bind_content, lazy_bind_content,
+ export_content.
+ (bfd_mach_o_load_command): Add comments, add next field.
+ (mach_o_data_struct): Replace commands field by first_command
+ and last_command.
+ * mach-o.c (bfd_mach_o_append_command): New function.
+ (bfd_mach_o_bfd_copy_private_symbol_data): Add blank lines.
+ (bfd_mach_o_bfd_copy_private_section_data): Check flavour,
+ copy fields.
+ (bfd_mach_o_bfd_copy_private_header_data): Copy load commands.
+ (bfd_mach_o_pad4, bfd_mach_o_pad_command): New functions.
+ (bfd_mach_o_write_thread): Use macro instead of literal.
+ (bfd_mach_o_write_dylinker, bfd_mach_o_write_dylib)
+ (bfd_mach_o_write_main, bfd_mach_o_write_dyld_info): New
+ functions.
+ (bfd_mach_o_write_symtab_content): New function (extracted
+ from bfd_mach_o_write_symtab).
+ (bfd_mach_o_write_symtab): Split.
+ (bfd_mach_o_count_indirect_symbols): Move
+ (bfd_mach_o_build_dysymtab): Remove layout code.
+ (bfd_mach_o_write_contents): Rewritten to build commands in order.
+ (bfd_mach_o_count_sections_for_seg): Remove.
+ (bfd_mach_o_build_obj_seg_command): New function (extracted from
+ bfd_mach_o_build_seg_command).
+ (bfd_mach_o_build_exec_seg_command): New function.
+ (bfd_mach_o_build_dysymtab_command): Remove.
+ (bfd_mach_o_layout_commands): New function.
+ (bfd_mach_o_init_segment): New function.
+ (bfd_mach_o_build_commands): Major rework to handle non-object
+ files.
+ (bfd_mach_o_alloc_and_read, bfd_mach_o_read_dyld_content): New
+ function.
+ (bfd_mach_o_read_dyld_info): Clear content fields.
+ (bfd_mach_o_read_segment): Adjust call.
+ (bfd_mach_o_flatten_sections): Adjust as now load commands are
+ chained.
+ (bfd_mach_o_scan_start_address, bfd_mach_o_scan)
+ (bfd_mach_o_mkobject_init, bfd_mach_o_get_base_address)
+ (bfd_mach_o_lookup_command, bfd_mach_o_core_fetch_environment):
+ Likewise.
+
+2014-04-18 Tristan Gingold <gingold@adacore.com>
+
+ * mach-o-target.c (bfd_mach_o_bfd_copy_private_header_data):
+ Define instead of bfd_mach_o_bfd_copy_private_bfd_data.
+ * mach-o.c (bfd_mach_o_bfd_copy_private_bfd_data): Rename.
+ * mach-o.h (bfd_mach_o_bfd_copy_private_bfd_data): Likewise.
+
+2014-04-18 Tristan Gingold <gingold@adacore.com>
+
+ * mach-o.h (bfd_mach_o_dylinker_command)
+ (bfd_mach_o_dylib_command, bfd_mach_o_fvmlib_command): Remove
+ name_len field.
+ * mach-o.c (bfd_mach_o_read_dylinker, bfd_mach_o_read_dylib)
+ (bfd_mach_o_read_fvmlib): Adjust after name_len removal.
+
+2014-04-18 Tristan Gingold <gingold@adacore.com>
+
+ * mach-o.h (bfd_mach_o_backend_data): Add page_size field.
+ * mach-o-target.c: Check TARGET_PAGESIZE is defined.
+ (TARGET_NAME_BACKEND): Add TARGET_PAGESIZE.
+ * mach-o.c (TARGET_PAGESIZE): Define and undefined for
+ each targets declared.
+ * mach-o-x86-64.c (TARGET_PAGESIZE): Define.
+ * mach-o-i386.c (TARGET_PAGESIZE): Define.
+
+2014-04-18 Tristan Gingold <gingold@adacore.com>
+
+ * mach-o.c (bfd_mach_o_write_thread)
+ (bfd_mach_o_write_section_32, bfd_mach_o_write_section_64)
+ (bfd_mach_o_write_segment_32, bfd_mach_o_write_segment_64)
+ (bfd_mach_o_read_dylinker, bfd_mach_o_read_dylib)
+ (bfd_mach_o_read_prebound_dylib, bfd_mach_o_read_prebind_cksum)
+ (bfd_mach_o_read_twolevel_hints, bfd_mach_o_read_fvmlib)
+ (bfd_mach_o_read_thread, bfd_mach_o_read_dysymtab)
+ (bfd_mach_o_read_symtab, bfd_mach_o_read_uuid)
+ (bfd_mach_o_read_linkedit, bfd_mach_o_read_str)
+ (bfd_mach_o_read_dyld_info, bfd_mach_o_read_segment)
+ (bfd_mach_o_read_segment_32, bfd_mach_o_read_segment_64)
+ (bfd_mach_o_read_command): Now return a boolean status.
+ Adjust return statements.
+ (bfd_mach_o_write_contents, bfd_mach_o_scan): Adjust tests.
+ (bfd_mach_o_core_file_failing_command): Remove useless initialization.
+
+2014-04-17 Kwok Cheung Yeung <kcy@codesourcery.com>
+
+ * elfxx-mips.c (struct mips_got_info): Delete assigned_gotno
+ field. Add assigned_low_gotno and assigned_high_gotno fields.
+ (mips_elf_create_local_got_entry): Update out-of-space condition.
+ Set index of new GOT entry to assigned_low_gotno if required by
+ the current relocation, else set it to assigned_high_gotno.
+ (mips_elf_set_global_gotidx): Replace uses of assigned_gotno
+ with assigned_low_gotno.
+ (mips_elf_multi_got): Initialize assigned_low_gotno and
+ assigned_high_gotno in secondary GOTs. Use assigned_low_gotno
+ in place of assigned_gotno when handling global GOT entries.
+ (mips_elf_lay_out_got): Initialize assigned_low_gotno and
+ assigned_high_gotno.
+ (_bfd_mips_elf_finish_dynamic_sections): Account for a possible
+ gap in the middle of local GOT space.
+
+2014-04-17 Alan Modra <amodra@gmail.com>
+
+ PR 16846
+ * elflink.c (_bfd_elf_merge_symbol): Ignore TLS mismatch when
+ current bfd is a plugin. Don't always set type_change_ok
+ when old bfd is a plugin.
+
+2014-04-16 Tristan Gingold <gingold@adacore.com>
+
+ * mach-o-x86-64.c (bfd_mach_o_x86_64_mkobject): Adjust cpusubtype
+ flag.
+
+2014-04-16 Alan Modra <amodra@gmail.com>
+
+ * elf32-ppc.c (ppc_elf_relocate_section): Fill 476 fixup area
+ with "ba 0" rather than zeros.
+
+2014-04-15 Marcus Shawcroft <marcus.shawcroft@arm.com>
+
+ * (elfNN_aarch64_tls_relax): Fix instruction mask.
+
+2014-04-14 Alan Modra <amodra@gmail.com>
+
+ * elf32-ppc.c (BA): Define
+ (ppc_elf_link_hash_table_create): Correct default_params.
+ (write_glink_stub): Pad small plt call stub with "ba 0" rather
+ than "nop" for ppc476_workaround.
+ (ppc_elf_finish_dynamic_sections): Likewise for branch table
+ and __glink_PLTresolve. Ensure plt call stub at end of page
+ doesn't allow fall-thru prefetch.
+
+2014-04-11 Nick Clifton <nickc@redhat.com>
+
+ PR ld/16821
+ * peXXigen.c (abs_finder): New function.
+ (_bfd_XXi_swap_sym_out): For absolute symbols with values larger
+ than 1^32 try to convert them into section relative values
+ instead.
+
+2014-04-11 Nick Clifton <nickc@redhat.com>
+
+ * bfd-in2.h: Regenerate.
+ * libbfd.h: Regenerate.
+
+2014-04-10 Cesar Philippidis <cesar@codesourcery.com>
+
+ * elf32-nios2.c (nios2_elf32_build_stubs): Ignore dynobjs
+ when building function stubs.
+
+2014-04-10 Senthil Kumar Selvaraj <senthil_kumar.selvaraj@atmel.com>
+
+ * elf32-avr.c: Add DIFF relocations for AVR.
+ (avr_final_link_relocate): Handle the DIFF relocs.
+ (bfd_elf_avr_diff_reloc): New.
+ (elf32_avr_is_diff_reloc): New.
+ (elf32_avr_adjust_diff_reloc_value): Reduce difference value.
+ (elf32_avr_relax_delete_bytes): Recompute difference after deleting
+ bytes.
+
+ * reloc.c: Add BFD_RELOC_AVR_DIFF8/16/32 relocations
+
+2014-04-09 Alan Modra <amodra@gmail.com>
+
+ * libcoff.h: Regenerate.
+
+2014-04-09 Alan Modra <amodra@gmail.com>
+
+ * elf32-ppc.c (ppc_elf_relocate_section): Remove bctr from list
+ of safe ppc476 insns at end of page. Also remove non-branch insns.
+ Expand comments.
+
+2014-04-08 Jon Turney <jon.turney@dronecode.org.uk>
+
+ * peXXigen.c (pe_print_debugdata): New function: Displays the
+ contents of the debug directory and decodes codeview entries.
+ (_bfd_XXi_swap_debugdir_in, _bfd_XXi_swap_debugdir_out)
+ (_bfd_XXi_slurp_codeview_record, _bfd_XXi_write_codeview_record):
+ Add functions for reading and writing debugdir and codeview
+ records.
+ * libpei.h (_bfd_XXi_swap_debugdir_in, _bfd_XXi_swap_debugdir_out)
+ (_bfd_XXi_write_codeview_record): Add prototypes and macros.
+ * libcoff-in.h (pe_tdata): Add build-id data.
+ * libcoff.h: Regenerate.
+ * coffcode.h (coff_write_object_contents): Run build_id
+ after_write_object_contents hook.
+
+2014-04-05 Alan Modra <amodra@gmail.com>
+
+ * elflink.c (_bfd_elf_add_default_symbol): Pass poldbfd when
+ merging non-default sym.
+
+2014-04-04 Tristan Gingold <gingold@adacore.com>
+
+ * mach-o.c (bfd_mach_o_header_p): Reject 64 bit target when not
+ configured for.
+
+2014-04-04 Tristan Gingold <gingold@adacore.com>
+
+ * mach-o.c (bfd_mach_o_convert_section_name_to_mach_o): Fix
+ thinko on names length.
+
+2014-04-04 Tristan Gingold <gingold@adacore.com>
+
+ * mach-o-i386.c (bfd_mach_o_i386_swap_reloc_out): Use target index
+ of output_section.
+ * mach-o-x86-64.c (bfd_mach_o_x86_64_swap_reloc_out): Ditto.
+
+2014-04-04 Tristan Gingold <gingold@adacore.com>
+
+ * bfd.c (bfd_get_arch_size): Default is taken from arch.
+
+2014-04-03 Jon Turney <jon.turney@dronecode.org.uk>
+
+ * peXXigen.c (pe_print_edata): Verify edt.name lies inside
+ section before dereferencing.
+ (pe_print_idata, pe_print_edata, pe_print_reloc)
+ (rsrc_print_section): Don't bother interpreting the contents
+ of sections which have no contents.
+
+2014-04-03 Maria Guseva <m.guseva@samsung.com>
+
+ PR ld/16803
+ * elf.c (_bfd_elf_set_section_contents): Use correct type to hold
+ file position.
+
+2014-04-03 Tristan Gingold <gingold@adacore.com>
+
+ * mach-o.c (bfd_mach_o_mangle_symbols): Use index from
+ output_section.
+ (bfd_mach_o_build_seg_command): Add comment. Realign segment.
+ Fix style.
+ (bfd_mach_o_build_commands, bfd_mach_o_read_thread): Fix style.
+
+2014-04-03 Alan Modra <amodra@gmail.com>
+
+ * elf-bfd.h (struct elf_backend_data
+ <elf_backend_bfd_from_remote_memory>): Replace "size_t size"
+ with "bfd_size_type size".
+ (_bfd_elf32_bfd_from_remote_memory): Likewise.
+ (_bfd_elf64_bfd_from_remote_memory): Likewise.
+ * elf.c (bfd_elf_bfd_from_remote_memory): Likewise.
+ * elfcode.h (bfd_from_remote_memory): Likewise.
+ * bfd-in.h (bfd_elf_bfd_from_remote_memory): Likewise.
+ * bfd-in2.h: Regenerate.
+
+2014-04-02 Tristan Gingold <gingold@adacore.com>
+
+ * mach-o.h (bfd_mach_o_twolevel_hints_command)
+ (bfd_mach_o_prebind_cksum_command): New types.
+ (bfd_mach_o_prebound_dylib_command): Rewrite.
+ (bfd_mach_o_load_command): Add prebind_cksum and twolevel_hints
+ fields.
+ * mach-o.c (bfd_mach_o_read_prebound_dylib): Read and decode the
+ command.
+ (bfd_mach_o_read_prebind_cksum): New function.
+ (bfd_mach_o_read_twolevel_hints): Ditto.
+ (bfd_mach_o_read_command): Handle prebind cksum and twolevel hints
+ commands.
+
+2014-04-02 Alan Modra <amodra@gmail.com>
+
+ * elfcode.h (bfd_from_remote_memory): Add "size" parameter.
+ Consolidate code handling possible section headers past end of
+ segment. Don't use p_align for page size guess, instead use
+ minpagesize. Take note of ld.so clearing section headers when
+ p_memsz > p_filesz. Handle file header specifying no section
+ headers. Handle zero p_align throughout. Default loadbase to
+ zero. Add comments. Rename contents_size to high_offset, and
+ make it a bfd_vma. Delete unnecessary bfd_set_error calls.
+ * bfd-in.h (bfd_elf_bfd_from_remote_memory): Update prototpe.
+ * elf-bfd.h (struct elf_backend_data <elf_backend_from_remote_memory>):
+ Likewise.
+ (_bfd_elf32_bfd_from_remote_memory): Likewise.
+ (_bfd_elf64_bfd_from_remote_memory): Likewise.
+ * elf.c (bfd_elf_bfd_from_remote_memory): Adjust.
+ * bfd-in2.h: Regnerate.
+
+2014-04-01 Tristan Gingold <gingold@adacore.com>
+
+ * mach-o.c (bfd_mach_o_canonicalize_one_reloc): Avoid to crash
+ when num == 0.
+
+2014-03-27 Yury Gribov <y.gribov@samsung.com>
+ Pavel Fedin <p.fedin@samsung.com>
+
+ * elf32-arm.c: Add support for limited pretty-printing of PLT
+ entries on eabi and nacl targets.
+ (elf32_arm_get_synthetic_symtab): Add new callback.
+ (elf32_arm_nacl_plt_sym_val): Likewise.
+ (elf32_arm_plt0_size): Add helper function.
+ (elf32_arm_plt_size): Likewise.
+
+2014-03-27 Tristan Gingold <gingold@adacore.com>
+
+ * mach-o.c (bfd_mach_o_read_dylinker): Remove assert.
+ (bfd_mach_o_read_command): Handle BFD_MACH_O_LC_DYLD_ENVIRONMENT.
+
+2014-03-27 Tristan Gingold <gingold@adacore.com>
+
+ * mach-o.h (bfd_mach_o_get_base_address): New prototype.
+ * mach-o.c (bfd_mach_o_write_symtab)
+ (bfd_mach_o_write_contents)
+ (bfd_mach_o_set_section_flags_from_bfd)
+ (bfd_mach_o_build_seg_command): Fix indentation.
+ (bfd_mach_o_get_base_address): New function.
+
+2014-03-26 Nick Clifton <nickc@redhat.com>
+
+ * cofflink.c (_bfd_coff_generic_relocate_section): Skip
+ relocations in discarded sections.
+
+2014-03-26 Tristan Gingold <gingold@adacore.com>
+
+ * mach-o.c (bfd_mach_o_convert_architecture): Add
+ BFD_MACH_O_CPU_TYPE_ARM64.
+
+2014-03-26 Alan Modra <amodra@gmail.com>
+
+ * elf64-ppc.c (ppc64_elf_check_relocs): Account for possibly
+ needed plt entries when taking the address of functions for
+ abiversion == 0 (ie. unknown) as well as abiversion == 2.
+ Move opd setup and abiversion checks to..
+ (ppc64_elf_before_check_relocs): ..here. Renamed from
+ ppc64_elf_process_dot_syms. Set output abiversion from input and
+ input abiversion from output, if either is not set.
+ (ppc64_elf_merge_private_bfd_data): Don't merge flags here.
+ (elf_backend_check_directives): Update.
+
+2014-03-25 Will Newton <will.newton@linaro.org>
+
+ * elfnn-aarch64.c (elfNN_aarch64_finish_dynamic_sections):
+ Set value of DT_PLTRELSZ and DT_RELASZ based on the size
+ of input sections rather than output sections.
+
+2014-03-20 Will Newton <will.newton@linaro.org>
+
+ PR ld/16715
+ * elf32-arm.c (elf32_arm_check_relocs): Set
+ pointer_equality_needed for absolute references within
+ executable links.
+ (elf32_arm_finish_dynamic_symbol): Set st_value to zero
+ unless pointer_equality_needed is set.
+
+2014-03-19 Nick Clifton <nickc@redhat.com>
+
+ * peXXigen.c (rsrc_process_section): Add code to scan input
+ sections and record their lengths. Use these lengths to find the
+ start of each merged .rsrc section.
+
+2014-03-17 Tristan Gingold <gingold@adacore.com>
+
+ * mach-o.c (bfd_mach_o_read_dylib): Handle lazy load dylib.
+ (bfd_mach_o_read_command): Ditto.
+
+2014-03-14 Meador Inge <meadori@codesourcery.com>
+
+ * configure.in: Add strnlen to AC_CHECK_DECLS.
+ * config.in: Regenerate.
+ * configure: Regenerate.
+ * sysdep.h (strnlen): Add prototype.
+
+2014-03-14 Alan Modra <amodra@gmail.com>
+
+ * elf32-ppc.c (ppc_elf_relocate_section): Correct overflow
+ handling for VLE_SDA21 relocs.
+
+2014-03-13 Tristan Gingold <gingold@adacore.com>
+
+ * peicode.h (pe_ILF_object_p): Adjust, as the version number
+ has been read.
+ (pe_bfd_object_p): Also read version number to detect ILF.
+ * pe-x86_64.c (COFF_WITH_PE_BIGOBJ): Define.
+ (x86_64pe_bigobj_vec): Define
+ * coffcode.h (bfd_coff_backend_data): Add _bfd_coff_max_nscns field.
+ (bfd_coff_max_nscns): New macro.
+ (coff_compute_section_file_positions): Use unsigned int for
+ target_index. Compare with bfd_coff_max_nscns.
+ (bfd_coff_std_swap_table, ticoff0_swap_table, ticoff1_swap_table):
+ Set a value for _bfd_coff_max_nscns.
+ (header_bigobj_classid): New constant.
+ (coff_bigobj_swap_filehdr_in, coff_bigobj_swap_filehdr_out)
+ (coff_bigobj_swap_sym_in, coff_bigobj_swap_sym_out)
+ (coff_bigobj_swap_aux_in, coff_bigobj_swap_aux_out): New
+ functions.
+ (bigobj_swap_table): New table.
+ * libcoff.h: Regenerate.
+ * coff-sh.c (bfd_coff_small_swap_table): Likewise.
+ * coff-alpha.c (alpha_ecoff_backend_data): Add value for
+ _bfd_coff_max_nscns.
+ * coff-mips.c (mips_ecoff_backend_data): Likewise.
+ * coff-rs6000.c (bfd_xcoff_backend_data)
+ (bfd_pmac_xcoff_backend_data): Likewise.
+ * coff64-rs6000.c (bfd_xcoff_backend_data)
+ (bfd_xcoff_aix5_backend_data): Likewise.
+ * targets.c (x86_64pe_bigobj_vec): Declare.
+ * configure.in (x86_64pe_bigobj_vec): New vector.
+ * configure: Regenerate.
+ * config.bfd: Add bigobj object format for Windows targets.
+
+2014-03-12 Nick Clifton <nickc@redhat.com>
+
+ PR ld/16671
+ * elf32-arm.c (elf32_arm_add_symbol_hook): Check for ARM format
+ before testing for vxworks.
+
+2014-03-12 Alan Modra <amodra@gmail.com>
+
+ * Makefile.in: Regenerate.
+
+2014-03-12 Alan Modra <amodra@gmail.com>
+
+ PR 16690
+ * elf.c (copy_elf_program_header): Ignore first section lma if
+ non-alloc.
+
+2014-03-11 Alan Modra <amodra@gmail.com>
+
+ PR 16686
+ * coff-rs6000.c: Include stdint.h.
+ * coff64-rs6000.c: Likewise.
+
+2014-03-10 Tristan Gingold <gingold@adacore.com>
+
+ * ticoff.h: Removed.
+
+2014-03-08 Alan Modra <amodra@gmail.com>
+
+ * elf32-ppc.c (ppc_elf_howto_raw): Correct overflow check for
+ many relocations. Correct bitsize and rightshift too for a number
+ of VLE relocs. Describe R_PPC_VLE_SDA21 and R_PPC_VLE_SDA21_LO.
+ Correct dst_mask on R_PPC_VLE_SDA21_LO.
+ (ppc_elf_vle_split16): Tidy, delete unnecessary prototype.
+ (ppc_elf_relocate_section): Modify overflow test for 16-bit
+ fields in instructions to signed/unsigned according to whether
+ the field takes a signed or unsigned value. Tidy vle split16 code.
+ Correct R_PPC_VLE_SDA21 and R_PPC_VLE_SDA21_LO handling.
+
+2014-03-08 Alan Modra <amodra@gmail.com>
+
+ * elf64-ppc.c (ppc64_elf_howto_raw): Use complain_overflow_signed
+ for R_PPC64_ADDR14, R_PPC64_ADDR14_BRTAKEN, R_PPC64_ADDR14_BRNTAKEN,
+ R_PPC64_SECTOFF, R_PPC64_ADDR16_DS, R_PPC64_SECTOFF_DS,
+ R_PPC64_REL16 entries. Use complain_overflow_dont for R_PPC64_TOC.
+ (ppc64_elf_relocate_section): Modify overflow test for 16-bit
+ fields in instructions to signed/unsigned according to whether
+ the field takes a signed or unsigned value.
+
+2014-03-07 Pedro Alves <palves@redhat.com>
+
+ PR gdb/16696
+ * rs6000-core.c (rs6000coff_core_p): Cast pointers to bfd_vma
+ through ptr_to_uint instead of through long.
+
+2014-03-06 Nick Clifton <nickc@redhat.com>
+
+ PR 16664
+ * elf-attrs.c (_bfd_elf_parse_attributes): Add checks for corrupt
+ attribute section names.
+
+2014-03-05 Alan Modra <amodra@gmail.com>
+
+ Update copyright years.
+
+2014-03-05 Alan Modra <amodra@gmail.com>
+
+ * elf64-ppc.c (ppc64_elf_howto_raw): Add R_PPC64_ADDR64_LOCAL entry.
+ (ppc64_elf_reloc_type_lookup): Support R_PPC64_ADDR64_LOCAL.
+ (ppc64_elf_check_relocs): Likewise.
+ (ppc64_elf_relocate_section): Likewise.
+ * Add BFD_RELOC_PPC64_ADDR64_LOCAL.
+ * bfd-in2.h: Regenerate.
+ * libbfd.h: Regenerate.
+
+2014-03-04 Heiher <r@hev.cc>
+
+ * elfxx-mips.c (mips_set_isa_flags): Use E_MIPS_ARCH_64R2 for
+ Loongson-3A.
+ (mips_mach_extensions): Make bfd_mach_mips_loongson_3a an
+ extension of bfd_mach_mipsisa64r2.
+
+2014-03-04 Nick Clifton <nickc@redhat.com>
+
+ PR ld/16017
+ * elf32-arm.c (elf32_thumb2_plt0_entry): New array.
+ (elf32_thumb2_plt_entry): New array.
+ (elf32_arm_create_dynamic_sections): Set PLT entry sizes when
+ using thumb2 based PLT.
+ (elf32_arm_populate_plt_entry): Handle generating Thumb2 based PLT
+ entries.
+ (elf32_arm_final_link_relocate): Do not bias jumps to Thumb based
+ PLT entries.
+ (elf32_arm_finish_dynamic_sections): Handle creation of Thumb2
+ based PLT 0-entry.
+ (elf32_arm_output_plt_map_1): Handle creation of local symbols for
+ Thumb2 based PLT 0-entry.
+ (elf32_arm_output_arch_local_syms): Handle creation of local
+ symbols for Thumb2 based PLT entries.
+
+2014-02-28 Alan Modra <amodra@gmail.com>
+
+ PR ld/16643
+ * elflink.c (elf_gc_sweep): Call gc_sweep_hook for exactly
+ the same conditions we called check_relocs.
+
+2014-02-27 Yuri Gribov <y.gribov@samsung.com>
+
+ * bfd-in.h: Add export of bfd_elf32_arm_use_long_plt.
+ * bfd-in2.h: Regenerate.
+ * elf32-arm.c (elf32_arm_plt_entry_long): New array.
+ (elf32_arm_link_hash_table_create): Set plt_entry_size to 16 if
+ using long PLT entries.
+ (bfd_elf32_arm_use_long_plt): New function.
+ (elf32_arm_populate_plt_entry): Add support for long PLT entries.
+
+2014-02-27 Alan Modra <amodra@gmail.com>
+
+ * elf32-ppc.c (ppc_elf_link_hash_table_create): Provide default
+ params for targets that don't use ppc32elf.em.
+
+2014-02-20 Chung-Lin Tang <cltang@codesourcery.com>
+
+ * elf32-nios2.c (nios2_elf32_relocate_section): Fix calculation
+ of GOTOFF relocations.
+
+2014-02-19 Igor Zamyatin <igor.zamyatin@intel.com>
+ H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf64-x86-64.c (elf_x86_64_bnd_plt0_entry): New.
+ (elf_x86_64_legacy_plt_entry): Likewise.
+ (elf_x86_64_bnd_plt_entry): Likewise.
+ (elf_x86_64_legacy_plt2_entry): Likewise.
+ (elf_x86_64_bnd_plt2_entry): Likewise.
+ (elf_x86_64_bnd_arch_bed): Likewise.
+ (elf_x86_64_link_hash_entry): Add has_bnd_reloc and plt_bnd.
+ (elf_x86_64_link_hash_table): Add plt_bnd.
+ (elf_x86_64_link_hash_newfunc): Initialize has_bnd_reloc and
+ plt_bnd.
+ (elf_x86_64_copy_indirect_symbol): Also copy has_bnd_reloc.
+ (elf_x86_64_check_relocs): Create the second PLT for Intel MPX
+ in 64-bit mode.
+ (elf_x86_64_allocate_dynrelocs): Handle the second PLT for IFUNC
+ symbols. Resolve call to the second PLT if it is created.
+ (elf_x86_64_size_dynamic_sections): Keep the second PLT section.
+ (elf_x86_64_relocate_section): Resolve PLT references to the
+ second PLT if it is created.
+ (elf_x86_64_finish_dynamic_symbol): Use BND PLT0 and fill the
+ second PLT entry for BND relocation.
+ (elf_x86_64_finish_dynamic_sections): Use MPX backend data if
+ the second PLT is created.
+ (elf_x86_64_get_synthetic_symtab): New.
+ (bfd_elf64_get_synthetic_symtab): Likewise. Undefine for NaCl.
+
+2014-02-19 Alan Modra <amodra@gmail.com>
+
+ * elf64-ppc.h (struct ppc64_elf_params): Add save_restore_funcs.
+ * elf64-ppc.c (ppc64_elf_func_desc_adjust): Use it to control
+ provision of out-of-line register save/restore routines.
+
+2014-02-18 Jack Carter <jack.carter@imgtec.com>
+
+ * elfxx-mips.c(_bfd_mips_elf_modify_segment_map): Deleted hard coding of
+ PT_DYNAMIC segment flags.
+
+2014-02-17 Jan Kratochvil <jan.kratochvil@redhat.com>
+
+ PR binutils/16595
+ * simple.c (struct saved_offsets): New.
+ (simple_save_output_info): Use it for ptr.
+ (simple_restore_output_info): Use it for ptr. Check section_count.
+ (bfd_simple_get_relocated_section_contents): Use it for saved_offsets.
+
+2014-02-17 Alan Modra <amodra@gmail.com>
+
+ * elf64-ppc.h (struct ppc64_elf_params): Define.
+ (ppc64_elf_init_stub_bfd, ppc64_elf_edit_opd, ppc64_elf_tls_setup,
+ ppc64_elf_setup_section_lists, ppc64_elf_size_stubs,
+ ppc64_elf_build_stubs): Update prototype.
+ * elf64-ppp.c (struct ppc_link_hash_table): Add params, delete other
+ fields now in params. Adjust code throughout file.
+ (ppc64_elf_init_stub_bfd): Delete "abfd" parameter, add "params".
+ Save params pointer in htab.
+ (ppc64_elf_edit_opd, ppc64_elf_tls_setup,
+ ppc64_elf_setup_section_lists, ppc64_elf_size_stubs,
+ ppc64_elf_build_stubs): Remove parameters now in "params".
+
+2014-02-17 Alan Modra <amodra@gmail.com>
+
+ * elf32-ppc.c (ppc_elf_relocate_section): Move relocs on insns
+ patched for ppc476 workaround. Reapply branch taken/not taken
+ relocs.
+
+2014-02-12 Alan Modra <amodra@gmail.com>
+
+ * elf32-ppc.c (ppc_elf_relax_section): Don't build long-branch
+ stubs for calls to __tls_get_addr that we know will later be
+ optimised away.
+
+2014-02-12 Alan Modra <amodra@gmail.com>
+
+ * elf32-ppc.c (ppc_elf_relax_section): Enable ppc476 workaround
+ for ld -r, when code sections are sufficiently aligned.
+ * elf32-ppc.h (struct ppc_elf_params): Delete pagesize. Add
+ pagesize_p2.
+
+2014-02-12 Alan Modra <amodra@gmail.com>
+
+ PR gold/15530
+ * elf64-ppc.c (ppc64_elf_gc_mark_dynamic_ref): Support
+ --export-dynamic and --dynamic-list marking of symbols.
+ * elflink.c (bfd_elf_gc_mark_dynamic_ref_symbol): Reorder
+ cheap tests first.
+
+2014-02-10 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR gold/16530
+ * elflink.c (bfd_elf_gc_mark_dynamic_ref_symbol): Mark symbol in
+ executables if it matches dynamic_list.
+
+2014-02-10 Alan Modra <amodra@gmail.com>
+
+ * po/SRC-POTFILES.in: Regenerate.
+ * po/bfd.pot: Regenerate.
+
+2014-02-09 Alan Modra <amodra@gmail.com>
+
+ * elf-bfd.h (struct elf_backend_data): Add caches_rawsize.
+ * elfxx-target.h (elf_backend_caches_rawsize): Define.
+ (elfNN_bed): Init new field.
+ * elflink.c (elf_link_input_bfd): Handle caches_rawsize.
+ * elf32-ppc.c (shared_stub_entry): Zero addi offset.
+ (ppc_elf_relax_section): Don't reallocate section here, write
+ stubs, or write out relocs for ld -r here..
+ (ppc_elf_relocate_section): ..instead write stubs here, and use
+ existing code to write out relocs for ld -r. Fix offset
+ adjustment on reloc for little-endian.
+ (elf_backend_caches_rawsize): Define.
+
+2014-02-07 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
+
+ PR build/16550
+ * cache.c (bfd_cache_max_open): Cast RLIM_INFINITY to rlim_t.
+
+2014-02-04 Jan Kratochvil <jan.kratochvil@redhat.com>
+
+ * coff-rs6000.c (xcoff_write_archive_contents_big): Free OFFSETS in
+ return paths. Three times.
+ * elf64-ppc.c (ppc64_elf_link_hash_table_create): Free HTAB in all
+ return paths.
+ (ppc64_elf_tls_optimize): Free TOC_REF in return path.
+ (ppc64_elf_edit_toc): Free USED in return path.
+
+2014-02-03 Sandra Loosemore <sandra@codesourcery.com>
+
+ * reloc.c (BFD_RELOC_NIOS2_GOT_LO, BFD_RELOC_NIOS2_GOT_HA): New.
+ (BFD_RELOC_NIOS2_CALL_LO, BFD_RELOC_NIOS2_CALL_HA): New.
+ * libbfd.h: Regenerated.
+ * bfd-in2.h: Regenerated.
+ * elf32-nios2.c (elf_nios2_howto_table_rel): Add new relocations.
+ (nios2_reloc_map): Likewise.
+ (GOT_USED, CALL_USED): Renamed from GOT16_USED and CALL16_USED.
+ Fixed all references.
+ (nios2_elf32_relocate_section): Add new relocations.
+ (nios2_elf32_check_relocs): Likewise.
+ (nios2_elf32_gc_sweep_hook): Likewise.
+
+2014-02-03 Alan Modra <amodra@gmail.com>
+
+ * elf32-ppc.c (struct ppc_elf_link_hash_table): Add params.
+ Delete emit_stub_syms, no_tls_get_addr_opt. Update all uses.
+ (ppc_elf_link_params): New function.
+ (ppc_elf_create_glink): Align .glink to 64 bytes for ppc476
+ workaround.
+ (ppc_elf_select_plt_layout): Remove plt_style and emit_stub_syms
+ parameters. Use htab->params instead.
+ (ppc_elf_tls_setup): Remove no_tls_get_addr_opt parameter.
+ (ppc_elf_size_dynamic_sections): Align __glink_PLTresolve to
+ 64 bytes for ppc476 workaround.
+ (struct ppc_elf_relax_info): New.
+ (ppc_elf_relax_section): Exclude linker created sections and
+ those too small to hold one instruction. Don't add another
+ branch around trampolines on later relax passes. Don't
+ generate trampolines for undefined symbols when !relocatable,
+ nor for plugin symbols. Allocate space for ppc476 workaround
+ patch area. Free fixups on error return path.
+ (ppc_elf_relocate_section): Handle ppc476 workaround patching.
+ * elf32-ppc.h (struct ppc_elf_params): New.
+ (ppc_elf_select_plt_layout, ppc_elf_tls_setup): Update prototype.
+ (ppc_elf_link_params): Declare.
+ * section.c (SEC_INFO_TYPE_TARGET): Define.
+ * bfd-in2.h: Regenerate.
+
+2014-02-02 Sandra Loosemore <sandra@codesourcery.com>
+
+ * elf32-nios2.c (struct elf32_nios2_link_hash_table): Add
+ h_gp_got field.
+ (nios2_elf32_relocate_section): Use got_base to adjust
+ GOT-pointer-relative relocations relative to _gp_got.
+ (create_got_section): Create _gp_got symbol.
+ (nios2_elf32_finish_dynamic_symbol): Make _gp_got absolute.
+ (nios2_elf32_size_dynamic_sections): Set _gp_got offset.
+
+2014-01-30 Sandra Loosemore <sandra@codesourcery.com>
+
+ * bfd-in2.h: Update from reloc.c.
+ * elf32-nios2.c: Include elf32-nios2.h.
+ (elf_nios2_howto_table_rel): Add entry for R_NIOS2_CALL26_NOAT.
+ (nios2_reloc_map): Likewise.
+ (enum elf32_nios2_stub_type): Declare.
+ (struct elf32_nios2_stub_hash_entry): Declare.
+ (nios2_stub_hash_entry, nios2_stub_hash_lookup): New macros.
+ (struct elf32_nios2_link_hash_entry): Add hsh_cache field.
+ (struct elf32_nios2_link_hash_table): Add new fields bstab,
+ stub_bfd, add_stub_section, layout_sections_again, stub_group,
+ bfd_count, top_index, input_list, all_local_syms.
+ (nios2_call26_stub_entry): New.
+ (nios2_elf32_install_imm16): Move up in file.
+ (nios2_elf32_install_data): Move up in file.
+ (hiadj): Move up in file.
+ (stub_hash_newfunc): New.
+ (link_hash_newfunc): Initialize hsh_cache field.
+ (STUB_SUFFIX): New.
+ (nios2_stub_name): New.
+ (nios2_get_stub_entry): New.
+ (nios2_add_stub): New.
+ (nios2_elf32_setup_section_lists): New.
+ (nios2_elf32_next_input_section): New.
+ (CALL26_SEGMENT): New.
+ (MAX_STUB_SECTION_SIZE): New.
+ (group_sections): New.
+ (nios2_type_of_stub): New.
+ (nios2_build_one_stub): New.
+ (nios2_size_one_stub): New.
+ (get_local_syms): New.
+ (nios2_elf32_size_stubs): New.
+ (nios2_elf32_build_stubs): New.
+ (nios2_elf32_do_call26_relocate): Correct CALL26 overflow test.
+ (nios2_elf32_relocate_section): Handle R_NIOS2_CALL26_NOAT. Add
+ trampolines for R_NIOS2_CALL26 stubs.
+ (nios2_elf32_check_relocs): Handle R_NIOS2_CALL26_NOAT.
+ (nios2_elf32_gc_sweep_hook): Likewise.
+ (nios2_elf32_link_hash_table_create): Initialize the stub hash table.
+ (nios2_elf32_link_hash_table_free): New.
+ (bfd_elf32_bfd_link_hash_table_free): Define.
+ * elf32-nios2.h: New file.
+ * libbfd.h: Update from reloc.c.
+ * reloc.c (BFD_RELOC_NIOS2_CALL26_NOAT): New.
+
+2014-01-29 Nick Clifton <nickc@redhat.com>
+
+ PR binutils/16318
+ * elf32-metag.c (elf_metag_post_process_headers): Call
+ _bfd_elf_post_process_headers.
+ * elf32-sh64.c (sh64_elf_copy_private_data): Call
+ _bfd_elf_copy_private_data.
+ * elf64-sh64.c (sh_elf64_copy_private_data_internal): Likewise.
+
+2014-01-29 Nick Clifton <nickc@redhat.com>
+
+ * bfd-in.h (bfd_set_section_vma): Delete.
+ (bfd_set_section_alignment): Delete.
+ (bfd_set_section_userdata): Delete.
+ (bfd_set_cacheable): Delete.
+ * bfd.c (bfd_set_cacheable): New static inline function.
+ * section.c (bfd_set_section_userdata): Likewise.
+ (bfd_set_section_vma): Likewise.
+ (bfd_set_section_alignment): Likewise.
+ * bfd-in2.h: Regenerate.
+
+2014-01-28 Nick Clifton <nickc@redhat.com>
+
+ * dwarf2.c (find_abstract_instance_name): For DW_FORM_ref_addr
+ attributes select the CU containing the abbreviation, which may not
+ be the current CU.
+
+2014-01-24 Alan Modra <amodra@gmail.com>
+
+ * elf64-ppc.c (ppc_build_one_stub): Correct reloc count passed
+ to get_relocs for ELFv2.
+
+2014-01-23 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/16498
+ * elf.c (_bfd_elf_map_sections_to_segments): Issue a linker error
+ if TLS sections are not adjacent.
+
+2014-01-22 Alan Modra <amodra@gmail.com>
+
+ * elflink.c (elf_link_add_object_symbols): Call minfo for --as-needed.
+
+2014-01-22 Alan Modra <amodra@gmail.com>
+
+ * elf64-ppc.c (STK_LINKER): Comment typo fix.
+
+2014-01-21 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/16467
+ * elflink.c (_bfd_elf_merge_symbol): When types of the existing
+ regular default symbol definition and the versioned dynamic
+ symbol definition mismatch, skip the default symbol definition
+ if one of them is IFUNC.
+
+2014-01-21 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/2404
+ * elflink.c (_bfd_elf_merge_symbol): Don't check info->shared,
+ info->export_dynamic nor h->ref_dynamic for type mismatch when
+ adding the default version.
+
+2014-01-16 Alan Modra <amodra@gmail.com>
+
+ * elfxx-mips.c (mips_elf_record_got_page_entry): Pass in a
+ mips_elf_traverse_got_arg* rather than mips_got_info*.
+ Adjust caller. Alloc on output_bfd rather than symbol section
+ owner.
+
+2014-01-15 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf32-i386.c (elf_i386_allocate_dynrelocs): Revert the last
+ change.
+ * elf64-x86-64.c (elf_x86_64_allocate_dynrelocs): Likewise.
+
+2014-01-14 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/16428
+ * elf32-i386.c (elf_i386_allocate_dynrelocs): Don't discard relocs
+ against __ehdr_start.
+ * elf64-x86-64.c (elf_x86_64_allocate_dynrelocs): Likewise.
+
+2014-01-14 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf32-i386.c (elf_i386_allocate_dynrelocs): Revert the last
+ change.
+ * elf64-x86-64.c (elf_x86_64_allocate_dynrelocs): Likewise.
+
+2014-01-14 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/16428
+ * elf32-i386.c (elf_i386_allocate_dynrelocs): Don't update reloc
+ count if there are any non pc-relative relocs.
+ * elf64-x86-64.c (elf_x86_64_allocate_dynrelocs): Likewise.
+
+2014-01-14 Michael Hudson-Doyle <michael.hudson@linaro.org>
+ Kugan Vivekanandarajah <kugan.vivekanandarajah@linaro.org>
+
+ * elfnn-aarch64.c (elfNN_aarch64_final_link_relocate): Use correct
+ offset while calculating relocation address.
+ (elfNN_aarch64_create_small_pltn_entry): Likewise.
+ (elfNN_aarch64_init_small_plt0_entry): Likewise.
+
+2014-01-13 Ma Jiang <ma.jiang@zte.com.cn>
+
+ PR ld/16202
+ * elf32-arm.c (elf32_arm_final_link_relocate): Refetch addends for
+ R_ARM_ABS8 and R_ARM_ABS16.
+
+2014-01-13 Alan Modra <amodra@gmail.com>
+
+ * elf32-ppc.c (ppc_elf_check_relocs): For @local call to ifunc,
+ error when shared and force a plt call otherwise.
+ (ppc_elf_size_dynamic_sections): Don't emit DT_PPC_GOT unless
+ plt_type == PLT_NEW.
+ (ppc_elf_relocate_section): Add missing test to resolve ifuncs to
+ the appropriate call stub.
+
+2014-01-10 Alan Modra <amodra@gmail.com>
+
+ PR ld/14207
+ PR ld/16322
+ PR binutils/16323
+ * elf.c (assign_file_positions_for_load_sections): Revert last change.
+ (assign_file_positions_for_non_load_sections): When setting up
+ PT_GNU_RELRO header, don't require a corresponding PT_LOAD
+ header that completely covers the relro region.
+
+2014-01-09 Tristan Gingold <gingold@adacore.com>
+
+ * coff-rs6000.c (rs6000coff_vec, pmac_xcoff_vec): use jump
+ table macros and add macros to initializa the structure.
+
+2014-01-08 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/14207
+ PR ld/16322
+ PR binutils/16323
+ * elf.c (_bfd_elf_map_sections_to_segments): Don't check section
+ size for PT_GNU_RELRO segment.
+ (assign_file_positions_for_load_sections): If PT_LOAD segment
+ doesn't fit PT_GNU_RELRO segment, adjust its p_filesz and p_memsz.
+
+2014-01-07 Tom Tromey <tromey@redhat.com>
+
+ * elf32-xtensa.c (vsprint_msg): Don't use old VA_* compatibility
+ wrappers.
+
+2014-01-03 Nick Clifton <nickc@redhat.com>
+
+ PR binutils/16199
+ * elf.c (vma_page_aligned_bias): Handle a maxpagesize value of
+ zero.
+
+2014-01-02 Yuanhui Zhang <asmwarrior@gmail.com>
+
+ PR binutils/14289
+ * pef.c (bfd_pef_xlib_read_header): Increase buffer size to 80.
+
+2014-01-02 Nick Clifton <nickc@redhat.com>
+
+ PR binutils/11983
+ * archive.c (_bfd_get_elt_at_filepos): Store a copy of the
+ filename in the bfd's filename field.
+ * elfcode.h (bfd_from_remote_memory): Likewise.
+ * ieee.c (ieee_object_p): Likewise.
+ * mach-o.c (bfd_mach_o_fat_member_init): Likewise.
+ * oasys.c (oasys_openr_next_archived_file): Likewise.
+ * vms-lib.c (_bfd_vms_lib_get_module): Likewise.
+ * opncls.c (bfd_fopen): Likewise.
+ (bfd_openstreamr): Likewise.
+ (bfd_openr_iovec): Likewise.
+ (bfd_openw): Likewise.
+ (bfd_create): Likewise.
+ (_bfd_delete_bfd): Free filename.
+
+For older changes see ChangeLog-2013
+
+Copyright (C) 2014 Free Software Foundation, Inc.
+
+Copying and distribution of this file, with or without modification,
+are permitted in any medium without royalty provided the copyright
+notice and this notice are preserved.
+
+Local Variables:
+mode: change-log
+left-margin: 8
+fill-column: 74
+version-control: never
+End:
diff --git a/bfd/ChangeLog-0001 b/bfd/ChangeLog-0001
new file mode 100644
index 0000000..63015db
--- /dev/null
+++ b/bfd/ChangeLog-0001
@@ -0,0 +1,9598 @@
+2001-12-31 Jakub Jelinek <jakub@redhat.com>
+
+ * elflink.h (elf_bfd_final_link): Check if dynobj is not NULL
+ before looking for .eh_frame_hdr section.
+ * elf-eh-frame.c (_bfd_elf_write_section_eh_frame_hdr): If
+ .eh_frame_hdr section is being stripped from output, don't do
+ anything.
+
+2001-12-27 Tom Rix <trix@redhat.com>
+
+ * coff-rs6000.c (xcoff_generate_rtinit): Clean data_buffer alloc/free.
+ * coff64-rs6000.c (xcoff64_generate_rtinit): Same.
+ (xcoff_write_archive_contents_big): Rewrite.
+ (xcoff_write_armap_big): Rewrite.
+ (xcoff_write_one_armap_big): Delete.
+ * libxcoff.h : Clean up.
+
+2001-12-21 Tom Rix <trix@redhat.com>
+
+ * xcofflink.c (bfd_xcoff_link_generate_rtinit): New function.
+ Interface to linker for generation of __rtinit.
+ * libxcoff.h (struct xcoff_backend_data_rec): Add new ops to xcoff
+ backend to generate special linker symbol __rtinit.
+ * coff-rs6000.c (bfd_xcoff_backend_data, bfd_pmac_xcoff_backend_data)
+ : Add new rtinit ops
+ * coff64-rs6000.c (bfd_xcoff_aix5_backend_data,
+ bfd_xcoff_backend_data): Same.
+ * bfd-in.h: Add bfd_xcoff_link_generate_rtinit.
+ * bfd-in2.h : Regenerate.
+
+2001-12-21 Jakub Jelinek <jakub@redhat.com>
+
+ * elf32-sparc.c (_bfd_sparc_elf_howto_table): Fix dst_mask for
+ R_SPARC_DISP32. Support R_SPARC_PLT32.
+ (sparc_reloc_map): Add BFD_RELOC_16_PCREL and BFD_RELOC_SPARC_PLT32.
+ (elf32_sparc_check_relocs): Handle R_SPARC_PLT32.
+ (elf32_sparc_relocate_section): Likewise.
+ * elf64-sparc.c (sparc64_elf_howto_table): Fix dst_mask for
+ R_SPARC_DISP32. Support R_SPARC_PLT32 and R_SPARC_PLT64.
+ (sparc_reloc_map): Add BFD_RELOC_16_PCREL, BFD_RELOC_64_PCREL
+ and BFD_RELOC_SPARC_PLT32.
+ (sparc64_elf_check_relocs): Handle R_SPARC_PLT32 and R_SPARC_PLT64.
+ (sparc64_elf_relocate_section): Likewise.
+ * reloc.c (bfd_reloc_code_type): Add BFD_RELOC_SPARC_PLT32.
+ * bfd-in2.h, libbfd.h: Rebuilt.
+
+2001-12-20 Tom Rix <trix@redhat.com>
+
+ * coffcode.h (coff_compute_section_file_positions): Add special AIX
+ loader alignment of text section.
+
+2001-12-20 Jason Thorpe <thorpej@wasabisystems.com>
+
+ * config.bfd (mips-dec-netbsd*): Delete alias for mips*el-*-netbsd*.
+
+ * config.bfd (arm-*-netbsdelf*): Add target.
+ * configure.in: Include netbsd-core.lo for native arm-*-netbsd*.
+ * configure: Regenerate.
+
+2001-12-20 Alan Modra <amodra@bigpond.net.au>
+
+ * elfcode.h (elf_slurp_symbol_table): Test elf_elfsections for NULL,
+ as can happen with a core file, before dereferencing.
+
+2001-12-19 Michael Snyder <msnyder@redhat.com>
+
+ * elf32-i386.c (elf_i386_grok_psinfo): Fix copy-and-paste error:
+ target is i386 (not mips), and size of descdata is 124 (not 128).
+
+2001-12-19 Jakub Jelinek <jakub@redhat.com>
+
+ * elf-eh-frame.c (_bfd_elf_discard_section_eh_frame): If new_size
+ is 0, temporarily grow it to minimal CIE size.
+ (_bfd_elf_write_section_eh_frame): If input .eh_frame section would
+ end up empty, build a fake minimal CIE.
+
+2001-12-19 Steve Ellcey <sje@cup.hp.com>
+
+ * config.bfd (bfd_elf32_ia64_hpux_big_vec): New vector for
+ ia64*-*-hpux* target.
+ (bfd_elf64_ia64_hpux_big_vec): Likewise.
+ * targets.c: Ditto.
+ * configure.in: Ditto.
+ * configure: Regenerate
+ * elfxx-ia64.c (elfNN_ia64_final_write_processing): Replace use of
+ alloca with bfd_malloc.
+ (get_local_sym_hash): Likewise.
+ (elfNN_hpux_post_process_headers): New function.
+ #include elfNN-target.h again with values for IA64 HP-UX vector.
+
+2001-12-18 Michael Snyder <msnyder@redhat.com>
+
+ * elf.c (assign_file_positions_for_segments): Don't sort PT_NOTE
+ sections of corefiles. Also it makes no sense to sort if count == 1.
+
+2001-12-18 H.J. Lu <hjl@gnu.org>
+
+ * elf.c (_bfd_elf_copy_private_bfd_data): Also copy GP.
+
+2001-12-18 H.J. Lu <hjl@gnu.org>
+
+ * elf.c (_bfd_elf_copy_private_bfd_data): Update comments.
+
+2001-12-18 H.J. Lu <hjl@gnu.org>
+
+ * elf-bfd.h (_bfd_elf_copy_private_bfd_data): New. Prototype.
+ (_bfd_mips_elf_copy_private_bfd_data): Removed.
+
+ * elf.c (_bfd_elf_copy_private_bfd_data): New. Copy e_flags in
+ the ELF header.
+
+ * elf32-i370.c (??_elf_copy_private_bfd_data): Removed.
+ (bfd_elf??_bfd_copy_private_bfd_data): Removed.
+ * elf32-m32r.c: Likewise.
+ * elf32-m68k.c: Likewise.
+ * elf32-mcore.c: Likewise.
+ * elf32-mips.c: Likewise.
+ * elf32-ppc.c: Likewise.
+ * elf32-v850.c: Likewise.
+ * elf64-ppc.c: Likewise.
+ * elf64-sparc.c: Likewise.
+ * elfxx-ia64.c: Likewise.
+
+ * elf64-mips.c (bfd_elf64_bfd_copy_private_bfd_data): Removed.
+
+ * elfxx-target.h (bfd_elfNN_bfd_copy_private_bfd_data): Defined
+ to _bfd_elf_copy_private_bfd_data.
+
+2001-12-18 Martin Schwidefsky <schwidefsky@de.ibm.com>
+
+ * elf32-s390 (elf_s390_check_relocs): Pass addend to
+ gc_record_vtentry.
+ * elf64-s390 (elf_s390_check_relocs): Likewise.
+ Fix by Andreas Jaeger <aj@suse.de>.
+
+2001-12-18 Jason Thorpe <thorpej@wasabisystems.com>
+
+ * configure.host: Correctly match all NetBSD/mips
+ hosts.
+
+2001-12-18 matthew green <mrg@eterna.com.au>
+
+ * config.bfd (m68*-*-netbsdelf*): New target.
+ (m68*-*-netbsd): Also include bfd_elf32_m68k_vec.
+ (m68*-*-netbsdaout*): New alias for m68*-*-netbsd.
+
+2001-12-18 Jakub Jelinek <jakub@redhat.com>
+
+ * elflink.h (size_dynamic_sections): Skip anonymous version tag.
+ (elf_link_assign_sym_version): Don't count anonymous version tag.
+
+2001-12-18 Jakub Jelinek <jakub@redhat.com>
+
+ * elf-eh-frame.c (struct cie): Add make_lsda_relative.
+ (struct eh_cie_fde): Add lsda_encoding, lsda_offset,
+ make_lsda_relative.
+ (read_value, write_value): New.
+ (_bfd_elf_discard_section_eh_frame): Inicialize
+ lsda_encoding, lsda_offset and make_lsda_relative.
+ (_bfd_elf_eh_frame_section_offset): If make_lsda_relative,
+ request no dynamic reloc for LSDA field of FDE.
+ (_bfd_elf_write_section_eh_frame): Handle make_lsda_relative.
+ If a non-DW_EH_PE_absptr value is 0, don't adjust it by base
+ or pcrel. Fix address computation for DW_EH_PE_pcrel relocs.
+ Update LSDA field if LSDA encoding is DW_EH_PE_pcrel, because
+ . might have changed due to deleted FDE or CIEs.
+
+2001-12-18 Jakub Jelinek <jakub@redhat.com>
+
+ * elf-strtab.c (struct elf_strtab_hash_entry): Add u.next.
+ (last_eq): Remove.
+ (_bfd_elf_strtab_finalize): Don't use a hash table for last
+ character chains, instead use an array.
+
+2001-12-18 Jason Thorpe <thorpej@wasabisystems.com>
+
+ * elf.c (elfcore_netbsd_get_lwpid): New function.
+ (elfcore_grok_netbsd_procinfo): New function.
+ (elfcore_grok_netbsd_note): New function.
+ (elfcore_read_notes): Call elfcore_grok_netbsd_note to process
+ NetBSD ELF core file notes.
+
+2001-12-18 Alan Modra <amodra@bigpond.net.au>
+
+ * elfcode.h (struct bfd_preserve): New.
+ (elf_object_p): Replace preserved_* vars with instance of above.
+ Save and restore arch_info pointer rather than arch, mach so that
+ more cases can be restored. Save and restore new section_tail,
+ section_htab structure, and init appropriately. Move "rest of
+ section header" code so that i_shdrp needs no NULL initialisation.
+ Free old section_htab on success.
+ * elfcore.h (elf_core_file_p): Likewise.
+
+2001-12-17 Tom Rix <trix@redhat.com>
+
+ * coffcode.h (sec_to_styp_flags): Add STYP_EXCEPT and STYP_TYPCHK for
+ xcoff.
+
+2001-12-17 Jakub Jelinek <jakub@redhat.com>
+
+ * elf-bfd.h (elf_discarded_section): Define.
+ * elflink.h (elf_link_input_bfd): Use it.
+ (elf_reloc_symbol_deleted_p): Likewise.
+
+ * elf64-alpha.c (elf64_alpha_relocate_section): Don't warn about
+ overflows for pc relative relocs against discarded sections.
+
+2001-12-17 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * elf32-mips.c (_bfd_mips_elf_relocate_section): Formatting.
+ * elf64-mips.c: Add most of the fixes and tweaks done in elf32-mips.c
+ over the last months. Add some code for mips16 handling.
+ (mips_elf64_check_mips16_stubs): New function.
+ (mips_elf64_stub_section_p): Likewise.
+ (mips_elf64_calculate_relocation): Change interface to support mips16.
+ (mips_elf64_perform_relocation): Likewise.
+
+2001-12-17 Alan Modra <amodra@bigpond.net.au>
+
+ Support for more than 64k ELF sections.
+ * elf-bfd.h (elf_size_info <swap_symbol_out>): Add shndx param.
+ (bfd_elf32_swap_symbol_in): Likewise.
+ (bfd_elf32_swap_symbol_out): Likewise.
+ (bfd_elf64_swap_symbol_in): Likewise.
+ (bfd_elf64_swap_symbol_out): Likewise.
+ (elf_reloc_cookie): Add locsym_shndx field. Make locsyms a PTR.
+ (elf_obj_tdata): Add num_elf_sections, symtab_shndx_hdr and
+ symtab_shndx_section.
+ (elf_numsections): Define.
+ (elf_symtab_shndx): Define.
+ * elf.c (setup_group): Use elf_numsections rather than header e_shnum.
+ (bfd_elf_find_section): Likewise.
+ (bfd_section_from_elf_index): Likewise.
+ (bfd_section_from_shdr): Likewise. Handle SHT_SYMTAB_SHNDX.
+ (bfd_section_from_r_symndx): Read symbol shndx extension, and
+ translate st_shndx for > SHN_HIRESERVE.
+ (assign_section_numbers): Skip reserved sections. Assign
+ symtab_shndx_section and elf_numsections. Exclude reserved
+ sections from e_shnum. Set up symtab_shndx_hdr.
+ (_bfd_elf_compute_section_file_positions): Handle symtab_shndx_hdr.
+ (map_sections_to_segments): Don't map eh_frame_hdr unless required.
+ (assign_file_positions_except_relocs): Use elf_numsections rather
+ than header e_shnum. Skip reserved sections and symtab_shndx_section.
+ (prep_headers): Set name for symtab_shndx_hdr.
+ (_bfd_elf_assign_file_positions_for_relocs): Use elf_numsections.
+ (_bfd_elf_write_object_contents): Likewise. Skip reserved sections.
+ (_bfd_elf_section_from_bfd_section): Check bfd_{abs,com,und}_section
+ first. Use elf_section_data if available. Use elf_numsections.
+ Start scan at index 1.
+ (copy_private_bfd_data ): Comment fixes.
+ (MAP_ONESYMTAB): Define above SHN_HIOS.
+ (MAP_DYNSYMTAB): Likewise.
+ (MAP_STRTAB): Likewise.
+ (MAP_SHSTRTAB): Likewise.
+ (MAP_SYM_SHNDX): New define.
+ (_bfd_elf_copy_private_symbol_data): Handle symtab_shndx_section.
+ (swap_out_syms): Swap out SHT_SYMTAB_SHNDX section too.
+ * elfcode.h (elf_swap_symbol_in): Add shndx param, and handle shndx
+ extension.
+ (elf_swap_symbol_out): Likewise.
+ (elf_object_p): Set elf_numsections, and use instead of e_shnum.
+ Initialialise reserved elf_elfsections to point at shdr[0]. Remove
+ redundant bfd_release calls.
+ (elf_slurp_symbol_table): Read symbol shndx extension, and use with
+ elf_swap_symbol_in. Translate st_shndx for > SHN_HIRESERVE too.
+ * elflink.h (elf_link_is_defined_archive_symbol): Read symbol shndx
+ extension, and use with elf_swap_symbol_in.
+ (elf_link_record_local_dynamic_symbol): Likewise.
+ (elf_link_add_object_symbols): Likewise. Also translate st_shndx
+ for elf sections > SHN_HIRESERVE.
+ (NAME(bfd_elf,size_dynamic_sections)): Adjust elf_swap_symbol_out
+ call.
+ (struct elf_final_link_info): Add locsym_shndx and symshndxbuf.
+ (elf_bfd_final_link): Allocate the above, and tidy code allocating
+ other buffers. Use elf_numsections instead of e_shnum. Adjust
+ elf_swap_symbol_out calls.
+ (elf_link_output_sym): Swap out symbol shndx extension too.
+ (elf_link_flush_output_syms): And flush them to disk.
+ (elf_link_output_extsym): Use SHN_BAD. Adjust elf_swap_symbol_out
+ calls.
+ (elf_gc_mark): Read symbol shndx extension, and use with
+ elf_swap_symbol_in.
+ (elf_link_input_bfd): Likewise, Translate st_shndx for elf sections
+ > SHN_HIRESERVE too. Use SHN_BAD.
+ (elf_reloc_symbol_deleted_p): Use symbol shndx extensions with
+ elf_swap_symbol_in. Translate st_shndx > SHN_HIRESERVE too.
+ (elf_bfd_discard_info): Read symbol shndx extension. Don't attempt
+ to continue after a bfd error.
+ * elf-m10200.c (mn10200_elf_relax_section): Only read local syms.
+ Stash them immediately to symtab_hdr->contents rather than later
+ in multiple places. Clean up afterwards. Read symbol shndx
+ extension, and use with swap_symbol_in. Translate SHN_UNDEF,
+ SHN_ABS, SHN_COMMON and elf sections > SHN_HIRESERVE to bfd
+ sections too. Remove dead code.
+ (mn10200_elf_relax_delete_bytes): Use symbol shndx extension
+ when swapping in symbols. Tidy code adjusting global syms.
+ Don't swap in global syms.
+ (mn10200_elf_symbol_address_p): Likewise. Remove extsyms param.
+ (mn10200_elf_get_relocated_section_contents): Read symbol shndx
+ extension, and use with swap_symbol_in. Rename "size" -> "amt"
+ to maximize code in common with other files. Translate st_shndx
+ for > SHN_HIRESERVE too. Remove dead code.
+ * elf-m10300.c (mn10300_elf_relax_section): Only read local syms.
+ Stash them immediately to symtab_hdr->contents rather than later
+ in multiple places. Clean up afterwards. Read symbol shndx
+ extension, and use with swap_symbol_in. Remove dead code.
+ (mn10300_elf_relax_delete_bytes): As for elf-m10200.c.
+ (mn10300_elf_symbol_address_p): Likewise.
+ (mn10300_elf_get_relocated_section_contents): Likewise.
+ * elf32-h8300.c (elf32_h8_relax_section): As for elf-m10300.c.
+ (elf32_h8_relax_delete_bytes): Likewise.
+ (elf32_h8_symbol_address_p): Likewise.
+ (elf32_h8_get_relocated_section_contents): Likewise.
+ * elf32-hppa.c (elf32_hppa_size_stubs): Read symbol shndx
+ extension, and use with swap_symbol_in.
+ * elf64-hppa.c (elf64_hppa_check_relocs): Likewise.
+ * elf32-i370.c (i370_elf_finish_dynamic_sections): Adjust call to
+ bfd_elf32_swap_symbol_out.
+ * elf32-m32r.c (m32r_elf_get_relocated_section_contents): Translate
+ elf sections > SHN_HIRESERVE too.
+ * elf32-m68k.c (bfd_m68k_elf32_create_embedded_relocs): Only read
+ local syms. Read symbol shndx extension, and use with swap_symbol_in.
+ * elf32-mips.c (_bfd_mips_elf_final_write_processing): Use
+ elf_numsections rather than header e_shnum.
+ * elf32-sh.c (sh_elf_relax_section): As for elf-m10300.c.
+ (sh_elf_relax_delete_bytes): Likewise.
+ (sh_elf_get_relocated_section_contents): Likewise. Only read local
+ symbols.
+ * elf32-v850.c (v850_elf_symbol_processing): Use an unsigned int to
+ hold section index. Use elf_numsections rather than e_shnum.
+ Rename "index" -> "indx" to avoid shadowing warning.
+ (v850_elf_add_symbol_hook): Likewise.
+ * elf64-alpha.c (elf64_alpha_relax_section): Only read local syms.
+ Read symbol shndx extension, and use with swap_symbol_in.
+ * elf32-xstormy16.c (xstormy16_elf_relax_section): Likewise.
+ Translate SHN_COMMON and elf sections > SHN_HIRESERVE too.
+ * elfxx-ia64.c (elfNN_ia64_relax_section): Likewise.
+ (elfNN_ia64_aix_add_symbol_hook): Use elf_numsections.
+
+ * elf-m10300.c (mn10300_elf_gc_mark_hook): Remove unnecessary checks
+ before calling bfd_section_from_elf_index on local syms.
+ * elf32-arm.h (elf32_arm_gc_mark_hook): Likewise.
+ * elf32-avr.c (elf32_avr_gc_mark_hook): Likewise.
+ * elf32-cris.c (cris_elf_gc_mark_hook): Likewise.
+ * elf32-d10v.c (elf32_d10v_gc_mark_hook): Likewise.
+ * elf32-fr30.c (fr30_elf_gc_mark_hook): Likewise.
+ * elf32-hppa.c (elf32_hppa_gc_mark_hook): Likewise.
+ * elf32-i386.c (elf_i386_gc_mark_hook): Likewise.
+ * elf32-m32r.c (m32r_elf_gc_mark_hook): Likewise.
+ * elf32-m68k.c (elf_m68k_gc_mark_hook): Likewise.
+ * elf32-mcore.c (mcore_elf_gc_mark_hook): Likewise.
+ * elf32-mips.c (_bfd_mips_elf_gc_mark_hook): Likewise.
+ * elf32-openrisc.c (openrisc_elf_gc_mark_hook): Likewise.
+ * elf32-ppc.c (ppc_elf_gc_mark_hook): Likewise.
+ * elf32-s390.c (elf_s390_gc_mark_hook): Likewise.
+ * elf32-sh.c (sh_elf_gc_mark_hook): Likewise.
+ * elf32-sparc.c (elf32_sparc_gc_mark_hook): Likewise.
+ * elf32-v850.c (v850_elf_gc_mark_hook): Likewise.
+ * elf32-xstormy16.c (xstormy16_elf_gc_mark_hook): Likewise.
+ * elf64-mips.c (mips_elf64_gc_mark_hook): Likewise.
+ * elf64-mmix.c (mmix_elf_gc_mark_hook): Likewise.
+ * elf64-ppc.c (ppc64_elf_gc_mark_hook): Likewise.
+ * elf64-s390.c (elf_s390_gc_mark_hook): Likewise.
+ * elf64-x86-64.c (elf64_x86_64_gc_mark_hook): Likewise.
+
+2001-12-17 Alan Modra <amodra@bigpond.net.au>
+
+ Hash bfd sections for fast lookup and create.
+ * bfd.c (struct _bfd): Add section_htab, section_tail.
+ * libbfd-in.h (_bfd_delete_bfd): Declare.
+ (bfd_section_hash_newfunc): Declare.
+ * opncls.c (_bfd_new_bfd): Free memory on failure. Init
+ section_htab and section_tail.
+ (_bfd_delete_bfd): New function.
+ (bfd_openr): Use it.
+ (bfd_fdopenr): Likewise.
+ (bfd_openstreamr): Likewise.
+ (bfd_openw): Likewise.
+ (bfd_close): Likewise.
+ (bfd_close_all_done): Likewise.
+ (bfd_release): Comment.
+ * section.c (struct section_hash_entry): New.
+ (bfd_section_hash_newfunc): New function.
+ (section_hash_lookup): Define.
+ (bfd_section_init): New function, split out from
+ bfd_make_section_anyway.
+ (bfd_get_section_by_name): Lookup via hash table.
+ (bfd_get_unique_section_name): Likewise.
+ (bfd_make_section_old_way): Rewrite to use hash table.
+ (bfd_make_section_anyway): Likewise.
+ (bfd_make_section): Likewise. Return NULL for attempts to make
+ BFD_{ABS,COM,UND,IND}_SECTION_NAME.
+ (_bfd_strip_section_from_output): Adjust section_tail if needed.
+ * configure.in: Bump bfd version.
+ * configure: Regenerate.
+ * libbfd.h: Regenerate.
+ * bfd-in2.h: Regenerate.
+
+2001-12-15 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * elf64-mips.c (mips_elf64_link_hash_entry): New link hash.
+ (mips_elf64_high): New Function.
+ (mips_elf64_higher): Likewise.
+ (mips_elf64_highest): Likewise.
+ (mips_elf64_info_to_howto_rel): Likewise.
+ (mips_elf64_info_to_howto_rela): Likewise.
+ (mips_elf64_write_rel): Likewise.
+ (mips_elf64_write_rela): Likewise.
+ (mips_elf64_link_hash_newfunc): Likewise.
+ (mips_elf64_hi16_reloc): Likewise.
+ (mips_elf64_higher_reloc): Likewise.
+ (mips_elf64_highest_reloc): Likewise.
+ (mips_elf64_gprel16_reloc): Likewise.
+ (mips_elf64_gprel16_reloca): Likewise.
+ (mips_elf64_literal_reloc): Likewise.
+ (mips_elf64_gprel32_reloc): Likewise.
+ (mips_elf64_shift6_reloc): Likewise.
+ (mips_elf64_got16_reloc): Likewise.
+ (mips_elf64_assign_gp): Likewise.
+ (mips_elf64_final_gp): Likewise.
+ (gprel16_with_gp): Likewise.
+ (mips_elf64_additional_program_headers): Likewise.
+ (mips_elf64_link_hash_table_create): Likewise.
+ (mips_elf64_got_offset_from_index): Likewise.
+ (_mips_elf64_got_info): Likewise.
+ (mips_elf64_sign_extend): Likewise.
+ (mips_elf64_overflow_p): Likewise.
+ (mips_elf64_global_got_index): Likewise.
+ (mips_elf64_sort_hash_table_f): Likewise.
+ (mips_elf64_sort_hash_table): Likewise.
+ (mips_elf64_swap_msym_out): Likewise.
+ (mips_elf64_create_local_got_entry): Likewise.
+ (mips_elf64_local_got_index): Likewise.
+ (mips_elf64_got_page): Likewise.
+ (mips_elf64_got16_entry): Likewise.
+ (mips_elf64_local_relocation_p): Likewise.
+ (mips_elf64_next_relocation): Likewise.
+ (mips_elf64_create_dynamic_relocation): Likewise.
+ (mips_elf64_calculate_relocation): Likewise.
+ (mips_elf64_obtain_contents): Likewise.
+ (mips_elf64_perform_relocation): Likewise.
+ (mips_elf64_relocate_section): Likewise.
+ (mips_elf64_create_dynamic_sections): Likewise.
+ (mips_elf64_adjust_dynamic_symbol): Likewise.
+ (mips_elf64_always_size_sections): Likewise.
+ (mips_elf64_size_dynamic_sections): Likewise.
+ (mips_elf64_finish_dynamic_symbol): Likewise.
+ (mips_elf64_finish_dynamic_sections): Likewise.
+ (mips_elf64_gc_mark_hook): Likewise.
+ (mips_elf64_gc_sweep_hook): Likewise.
+ (mips_elf64_create_got_section): Likewise.
+ (mips_elf64_record_global_got_symbol): Likewise.
+ (mips_elf64_create_msym_section): Likewise.
+ (mips_elf64_allocate_dynamic_relocations): Likewise.
+ (mips_elf64_check_relocs): Likewise.
+ (mips_elf64_output_extsym): Likewise.
+ (mips_elf64_swap_gptab_in): Likewise.
+ (mips_elf64_swap_gptab_out): Likewise.
+ (gptab_compare): Likewise.
+ (mips_elf64_final_link): Likewise.
+ (prev_reloc_addend): Remenber addend of previous parts of a combined
+ reloc.
+ (ELF_MIPS_GP_OFFSET): New define.
+ (STUB_LW,STUB_MOVE,STUB_JALR,STUB_LI16): Likewise.
+ (MIPS_FUNCTION_STUB_SIZE): Likewise.
+ (mips_elf64_howto_rel): Fix HOWTO defines.
+ (mips_elf64_howto_rela): Likewise.
+ (mips_elf64_swap_reloca_out): Fix signedness.
+ (mips_elf64_be_swap_reloc_in): Use ELF64* instead of ELF32*.
+ (mips_elf64_be_swap_reloca_in): Likewise.
+ (mips_elf64_be_swap_reloc_out): Likewise. Preserve extended type info.
+ (mips_elf64_be_swap_reloca_out): Likewise.
+
+2001-12-15 Jakub Jelinek <jakub@redhat.com>
+
+ * elf-bfd.h (_bfd_elf_maybe_strip_eh_frame_hdr): New prototype.
+ * elf-eh-frame.c (struct eh_frame_hdr_info): Add strip.
+ (_bfd_elf_discard_section_eh_frame): Don't create .eh_frame_hdr
+ sec_info here. Free ehbuf.
+ (_bfd_elf_discard_section_eh_frame_hdr): Don't size the section
+ if hdr_info->strip.
+ (_bfd_elf_maybe_strip_eh_frame_hdr): New.
+ * elflink.h (size_dynamic_sections): Call it.
+
+2001-12-14 Alan Modra <amodra@bigpond.net.au>
+
+ * elflink.h (elf_bfd_discard_info): Fix segfault when dynobj NULL.
+
+2001-12-13 Jakub Jelinek <jakub@redhat.com>
+
+ * elf-bfd.h (enum elf_link_info_type): New.
+ (struct bfd_elf_section_data): Remove stab_info and merge_info
+ fields, add sec_info and sec_info_type.
+ (struct elf_obj_tdata): Add eh_frame_hdr field.
+ (_bfd_elf_discard_section_eh_frame): New prototype.
+ (_bfd_elf_discard_section_eh_frame_hdr): Likewise.
+ (_bfd_elf_eh_frame_section_offset): Likewise.
+ (_bfd_elf_write_section_eh_frame): Likewise.
+ (_bfd_elf_write_section_eh_frame_hdr): Likewise.
+ * Makefile.am (BFD32_BACKENDS): Add elf-eh-frame.lo.
+ (BFD32_BACKENDS_CFILES): Add elf-eh-frame.c.
+ (elf-eh-frame.lo): New.
+ * Makefile.in: Rebuilt.
+ * configure.in (elf): Add elf-eh-frame.lo.
+ * configure: Rebuilt.
+ * elf.c (_bfd_elf_print_private_bfd_data): Support PT_GNU_EH_FRAME.
+ (map_sections_to_segments): Create PT_GNU_EH_FRAME if requested.
+ (get_program_header_size): Take into account PT_GNU_EH_FRAME
+ segment.
+ (_bfd_elf_rela_local_sym): Use sec_info_type and sec_info.
+ (_bfd_elf_rel_local_sym): Likewise.
+ (_bfd_elf_section_offset): Likewise. Call
+ _bfd_elf_eh_frame_section_offset too.
+ * elfxx-ia64.c (elfNN_ia64_relocate_section): Use sec_info_type and
+ sec_info.
+ * elf64-alpha.c (elf64_alpha_relocate_section): Likewise.
+ * elf-eh-frame.c: New file.
+ * elflink.h (elf_link_add_object_symbols): Don't optimize SHF_MERGE
+ .stab sections. Set sec_info_type, use sec_info instead
+ of merge_info and stab_info.
+ (elf_link_create_dynamic_sections): Create .eh_frame_hdr section
+ if --eh-frame-hdr.
+ (elf_bfd_final_link): Write .eh_frame_hdr section.
+ (elf_link_sec_merge_syms): Use sec_info_type and sec_info.
+ (elf_link_input_bfd): Likewise.
+ Call _bfd_elf_write_section_eh_frame to write .eh_frame sections.
+ (elf_bfd_discard_info): Add output_bfd argument.
+ Call _bfd_elf_discard_section_eh_frame and
+ _bfd_elf_discard_section_eh_frame_hdr.
+ (elf_section_ignore_discarded_relocs): Use sec_info_type, not section
+ names.
+ * bfd-in.h (bfd_elf32_discard_info, bfd_elf64_discard_info): Adjust
+ prototypes.
+ * bfd-in2.h (bfd_elf32_discard_info, bfd_elf64_discard_info): Likewise.
+
+2001-12-12 Richard Henderson <rth@redhat.com>
+
+ * syms.c (_bfd_generic_read_minisymbols): Early return for
+ no symbols. Patch from FreeBSD folk; exact origin unknown.
+
+2001-12-11 Alan Modra <amodra@bigpond.net.au>
+
+ * elfcode.h (elf_swap_ehdr_out): Adjust value written for e_shnum
+ and e_shstrndx if out of range.
+ (elf_object_p): Read extended values for e_shnum and e_shstrndx
+ from the first section header. Allocate space in elf_elfsections
+ for reserved sections and set to NULLs.
+ (elf_write_shdrs_and_ehdr): Set overflow fields in first section
+ header. Skip reserved sections in elf_elfsections. Remove
+ duplicate size calculation.
+
+2001-12-07 Geoffrey Keating <geoffk@redhat.com>
+ Richard Henderson <rth@redhat.com>
+ Corinna Vinschen <vinschen@redhat.com>
+
+ * Makefile.am: Add support for xstormy16.
+ * archures.c: Add support for xstormy16.
+ * config.bfd: Add support for xstormy16.
+ * configure.in: Add support for xstormy16.
+ * reloc.c: Add support for xstormy16.
+ * targets.c: Add support for xstormy16.
+ * cpu-xstormy16.c: New file.
+ * elf32-xstormy16.c: New file.
+ * Makefile.in: Regenerated.
+ * bfd-in2.h: Regenerated.
+ * configure: Regenerated.
+ * libbfd.h: Regenerated.
+
+2001-12-07 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * elf.c (assign_file_positions_for_segments): Combine sentance
+ fragments into a single sentance in order to permit better
+ translation into foreign languages.
+
+2001-12-07 Jim Blandy <jimb@redhat.com>
+
+ * elf32-s390.c (elf32_s390_grok_prstatus): New function.
+ (elf_backend_grok_prstatus): Define.
+
+2001-12-07 Jakub Jelinek <jakub@redhat.com>
+
+ * elf32-sparc.c (elf32_sparc_relocate_section): Revert
+ 2001-09-14 change.
+
+2001-12-07 Jakub Jelinek <jakub@redhat.com>
+
+ * elf.c (_bfd_elf_rela_local_sym): Only call
+ _bfd_merged_section_offset if merge_info is non-NULL.
+ (_bfd_elf_rel_local_sym, _bfd_elf_section_offset): New.
+ * elf-bfd.h (_bfd_elf_rel_local_sym, _bfd_elf_section_offset): New
+ prototypes.
+ * elf32-arm.h (elf32_arm_final_link_relocate): Use
+ _bfd_elf_section_offset.
+ (elf32_arm_relocate_section): Use _bfd_elf_rel_local_sym.
+ * elf32-i386.c (elf_i386_relocate_section): Use
+ _bfd_elf_section_offset and _bfd_elf_rel_local_sym.
+ * elf32-sh.c (sh_elf_relocate_section): Likewise.
+ * elf32-sparc.c (elf32_sparc_relocate_section): Use
+ _bfd_elf_section_offset.
+ * elf32-cris.c (cris_elf_relocate_section): Likewise.
+ * elf32-hppa.c (elf32_hppa_relocate_section): Likewise.
+ * elf32-i370.c (i370_elf_relocate_section): Likewise.
+ * elf32-m68k.c (elf_m68k_relocate_section): Likewise.
+ * elf32-mips.c (mips_elf_create_dynamic_relocation): Likewise.
+ * elf32-ppc.c (ppc_elf_relocate_section): Likewise.
+ * elf32-s390.c (elf_s390_relocate_section): Likewise.
+ * elf64-alpha.c (elf64_alpha_relocate_section): Likewise.
+ * elf64-ppc.c (ppc64_elf_relocate_section): Likewise.
+ * elf64-s390.c (elf_s390_relocate_section): Likewise.
+ * elf64-sparc.c (sparc64_elf_relocate_section): Likewise.
+ * elf64-x86-64.c (elf64_x86_64_relocate_section): Likewise.
+ * elfxx-ia64.c (elfNN_ia64_install_dyn_reloc): Likewise.
+
+2001-12-07 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-hppa.c (clobber_millicode_symbols): Don't do anything if
+ already forced local.
+
+2001-12-05 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * elf32-arm.h (elf32_arm_merge_private_bfd_data): Combine
+ fragmented sentence parts into a whole sentence to permit
+ better translation into foreign languages.
+
+2001-12-06 Hans-Peter Nilsson <hp@bitrange.com>
+
+ * configure: Regenerate.
+ * Makefile.in: Regenerate.
+
+2001-12-05 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * Makefile.am: split up BFD_LIBS like statements in BFD32_LIBS and
+ BFD64_LIBS, make the latter depending on the availability of BFD64.
+ Add archive64.c source file.
+ * archive64.c: New file implementing bfd_elf64_archive_slurp_armap
+ and bfd_elf64_archive_write_armap, code from elf64-mips.c
+ * archive.c (bfd_slurp_armap): Add ELF64 archive support.
+ * config.bfd (mips*-*-irix6*): Allow with BFD64 only.
+ (mips64*el-*-linux*): Likewise.
+ (mips*el-*-linux*): Likewise. Reorder entries.
+ * configure.in (bfd_libs): Define in dependency of BFD64 and
+ AC_SUBST it.
+ * elf64-mips.c (mips_elf64_slurp_armap): Remove, use
+ bfd_elf64_archive_slurp_armap instead.
+ (mips_elf64_write_armap): Remove, use bfd_elf64_archive_write_armap
+ instead.
+
+2001-12-04 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * config.bfd: Remove trailing blanks.
+ * elf32-mips.c (gprel16_with_gp): Remove superfluous casts.
+
+2001-12-04 Alexandre Oliva <aoliva@redhat.com>
+
+ * elf32-d10v.c (elf_d10v_howto_table): Adjust bit-size of
+ R_D10V_10_PCREL_L, R_D10V_10_PCREL_R, R_D10V_18,
+ R_D10V_18_PCREL. Check 10_PCREL relocations as signed.
+ Disable pointless overflow checking of NONE and 32.
+
+2001-12-04 Alan Modra <amodra@bigpond.net.au>
+
+ * reloc.c (bfd_install_relocation): Correct reloc address test.
+ (bfd_perform_relocation): Formatting fix.
+ * bfd-in2.h: Regenerate for 2001-12-02 reloc.c change.
+
+2001-12-03 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * configure.in (LINGUAS): Add tr.
+ * configure: Regenerate.
+ * po/tr.po: Import from translation project's web site.
+
+2001-12-03 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-hppa.c (hppa_get_stub_entry): Remove debug message that
+ happens to trigger on undefined symbols.
+ (final_link_relocate): Return bfd_reloc_undefined for undefined
+ stubs.
+ (elf32_hppa_relocate_section): Don't say we can't handle a reloc
+ if we have already warned about an undefined symbol.
+
+2001-12-02 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * elf32-mips.c (NEWABI_P): New define.
+ (USE_REL): Remove, replaced by
+ (elf_backend_may_use_rel_p): New define.
+ (elf_backend_may_use_rela_p): Likewise.
+ (elf_backend_default_use_rela_p): Likewise.
+ (elf_mips_howto_table): Rename to elf_mips_howto_table_rel.
+ Fix some relocation definitions.
+ (elf_mips_howto_table_rela): New RELA relocation definitions for
+ NewABI support.
+ (mips32_64bit_reloc): Use the renamed elf_mips_howto_table_rel.
+ (bfd_elf32_bfd_reloc_type_lookup): Likewise.
+ (mips_rtype_to_howto): Likewise.
+ (_bfd_mips_elf_relocate_section): Likewise.
+ (_bfd_mips_elf_object_p): Typo.
+ (elf_backend_sign_extend_vma): Reordered together with many other
+ defines nearby to resemble the order of declaration in the header
+ file.
+
+2001-12-02 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * coff-mips.c (mips_bfd_reloc_type_lookup): Replace
+ BFD_RELOC_MIPS_GPREL by BFD_RELOC_GPREL16.
+ * pe-mips.c (mips_bfd_reloc_type_lookup): Likewise.
+ * elf32-mips.c (mips_reloc_map): Likewise. Replace
+ BFD_RELOC_MIPS_GPREL32 by BFD_RELOC_GPREL32.
+ * elf64-mips.c (mips_reloc_map): Likewise.
+ * reloc.c (BFD_RELOC_MIPS_GPREL): Remove.
+ (BFD_RELOC_MIPS_GPREL32): Remove.
+
+2001-11-30 H.J. Lu <hjl@gnu.org>
+
+ * elflink.h (elf_add_default_symbol): New.
+ (elf_link_add_object_symbols): Call elf_add_default_symbol ()
+ to create an indirect symbol from the default for the symbol
+ with the default version if needed.
+
+2001-11-29 "Peter.Schauer" <Peter.Schauer@regent.e-technik.tu-muenchen.de>
+
+ * elf.c (elfcore_grok_prstatus): Do not overwite the core signal
+ if it has already been set by another thread.
+
+2001-11-28 Jakub Jelinek <jakub@redhat.com>
+
+ * elf64-alpha.c (ALPHA_ELF_GOT_ENTRY_RELOCS_XLATED): Defined.
+ (elf64_alpha_relocate_section): Translate local_got_entries
+ for STT_SECTION symbol to SHF_MERGE section the first time
+ we see it.
+ * elfxx-ia64.c (struct elfNN_ia64_local_hash_entry): Add
+ sec_merge_done.
+ (get_local_sym_hash): New, extracted from get_dyn_sym_info.
+ (get_dyn_sym_info): Use it.
+ (elfNN_ia64_relocate_section): Translate local dyn entries
+ for STT_SECTION symbol to SHF_MERGE section the first time
+ we see it.
+
+2001-11-27 H.J. Lu <hjl@gnu.org>
+
+ * elflink.h (elf_bfd_discard_info): Skip if the input bfd isn't
+ ELF.
+
+2001-11-26 Jeffrey A Law (law@cygnus.com)
+
+ * stabs.c (_bfd_discard_section_stabs): Use PARAMS in function
+ prototypes.
+
+2001-11-24 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-hppa.c (elf32_hppa_size_stubs): Decrease default stub
+ group sizes to accommodate c++.
+
+2001-11-23 Jakub Jelinek <jakub@redhat.com>
+
+ * elf32-sparc.c (elf32_sparc_relocate_section): Don't clear
+ relocations in non-alloced sections against global symbols
+ defined in shared library being built.
+ * elf64-sparc.c (sparc64_elf_relocate_section): Likewise.
+
+2001-11-23 Jakub Jelinek <jakub@redhat.com>
+
+ * elf.c (_bfd_elf_rela_local_sym): New.
+ * elflink.h (elf_link_input_bfd): Don't consider empty
+ merged sections as removed in relocation tests.
+ * elf-bfd.h (_bfd_elf_rela_local_sym): Add prototype.
+ * elf32-i386.c (elf_i386_relocate_section): Handle relocs
+ against STT_SECTION symbol of SHF_MERGE section.
+ * elf32-arm.h (elf32_arm_relocate_section): Likewise.
+ * elf32-avr.c (elf32_avr_relocate_section): Call
+ _bfd_elf_rela_local_sym.
+ * elf32-cris.c (cris_elf_relocate_section): Likewise.
+ * elf32-d10v.c (elf32_d10v_relocate_section): Likewise.
+ * elf32-fr30.c (fr30_final_link_relocate): Likewise.
+ * elf32-h8300.c (elf32_h8_relocate_section): Likewise.
+ * elf32-hppa.c (elf32_hppa_relocate_section): Likewise.
+ * elf32-i370.c (i370_elf_relocate_section): Likewise.
+ * elf32-i860.c (elf32_i860_relocate_section): Likewise.
+ * elf32-m32r.c (m32r_elf_relocate_section): Likewise.
+ * elf32-m68k.c (elf_m68k_relocate_section): Likewise.
+ * elf32-mcore.c (mcore_elf_relocate_section): Likewise.
+ * elf32-openrisc.c (openrisc_elf_relocate_section): Likewise.
+ * elf32-ppc.c (ppc_elf_relocate_section): Likewise.
+ * elf32-s390.c (elf_s390_relocate_section): Likewise.
+ * elf32-sparc.c (elf32_sparc_relocate_section): Likewise.
+ * elf32-v850.c (v850_elf_relocate_section): Likewise.
+ * elf64-alpha.c (elf64_alpha_relocate_section): Likewise.
+ * elf64-mmix.c (mmix_elf_relocate_section): Likewise.
+ * elf64-ppc.c (ppc64_elf_relocate_section): Likewise.
+ * elf64-s390.c (elf_s390_relocate_section): Likewise.
+ * elf64-sparc.c (sparc64_elf_relocate_section): Likewise.
+ * elf64-x86-64.c (elf64_x86_64_relocate_section): Likewise.
+ * elf-hppa.h (elf_hppa_relocate_section): Likewise.
+ * elf-m10200.c (mn10200_elf_relocate_section): Likewise.
+ * elf-m10300.c (mn10300_elf_relocate_section): Likewise.
+ * elfxx-ia64.c (elfNN_ia64_relocate_section): Likewise.
+ * elf32-sh.c (sh_elf_relocate_section): Likewise for
+ !partial_inplace relocs. Handle relocs against STT_SECTION
+ symbol of SHF_MERGE for partial_inplace relocs.
+
+2001-11-21 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * po/Make-in (distclean): Move SRC-POTFILES.in and
+ BLD-POTFILES.in to maintainer-clean target.
+
+2001-11-21 Alan Modra <amodra@bigpond.net.au>
+
+ * elfxx-ia64.c (elfNN_ia64_relocate_section): Test r_symndx rather
+ than sym_sec->output_section to detect relocs against discarded
+ sections.
+
+2001-11-19 H.J. Lu <hjl@gnu.org>
+
+ * elflink.h (elf_link_input_bfd): Assert r_symndx != 0 when
+ discarding relocations.
+
+2001-11-19 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * section.c (bfd_is_const_section): New macro. Return true if the
+ given seciton is one of the special, constant, sections.
+ * bfd-in2.h: Regenerate.
+ * coffgen.c (coff_count_linenumbers): Use bfd_is_const_section.
+ (coff_write_native_symbol): Use bfd_is_const_section.
+
+2001-11-19 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-hppa.c (clobber_millicode_symbols): Dec dynstr refcount.
+
+ * elf32-hppa.c (elf32_hppa_size_stubs): Don't consider undefined
+ millicode syms as candidates for import stubs.
+
+ * elf32-hppa.c (PLABEL_PLT_ENTRY_SIZE): Delete.
+ (allocate_PIC_calls): Rename to allocate_plt_static.
+ (allocate_dynrelocs): Move most of code handling .plt entries to..
+ (allocate_plt_static): ..here. Don't drop plabel entries.
+
+2001-11-19 Hans-Peter Nilsson <hp@bitrange.com>
+
+ * mmo.c: Adjust documentation tags to use texinfo 4 features.
+
+2001-11-16 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * section.c (bfd_is_const_section): New macro. Return true if the
+ section pointer refers to one of the special, constant sections.
+ * bfd-in2.h: Regenerate.
+
+ * coffgen.c (coff_count_linenumbers): Only update the line number
+ count in non-special sections.
+ (coff_write_native_symbol): Only update the line number file
+ position in non-special sections.
+
+2001-11-15 Daniel Jacobowitz <drow@mvista.com>
+
+ * elflink.h (elf_reloc_symbol_deleted_p): Catch all relocs against
+ local syms from discarded sections. Update comment.
+
+2001-11-15 Alan Modra <amodra@bigpond.net.au>
+
+ * po/SRC-POTFILES.in: Regenerate.
+
+ * elflink.h (elf_link_input_bfd): Complain about all relocs
+ against local syms from discarded sections. K&R fixes.
+ (elf_reloc_symbol_deleted_p): Don't try to swap in external syms.
+ K&R fixes.
+
+2001-11-15 Alexandre Oliva <aoliva@redhat.com>
+
+ * elf64-sparc.c (sparc64_elf_relocate_section): Disregard
+ overflows in the .stab section.
+
+2001-11-14 Daniel Jacobowitz <drow@mvista.com>
+
+ * bfd-in.h (bfd_elf32_discard_info): Add prototype.
+ (bfd_elf64_discard_info): Likewise.
+ * bfd-in2.h: Regenerate.
+ * elf-bfd.h (struct elf_reloc_cookie): New.
+ (struct elf_backend_data): Add elf_backend_discard_info,
+ elf_backend_ignore_discarded_relocs, and elf_backend_write_section.
+ (_bfd_elf32_reloc_symbol_deleted_p): Add prototype.
+ (_bfd_elf64_reloc_symbol_deleted_p): Likewise.
+ * elf32-mips.c (_bfd_elf32_mips_discard_info): New.
+ (_bfd_elf32_mips_ignore_discarded_relocs): New.
+ (_bfd_elf32_mips_write_section): New.
+ (elf_backend_discard_info): Define.
+ (elf_backend_ignore_discarded_relocs): Define.
+ (elf_backend_write_section): Define.
+ * elfcode.h (elf_bfd_discard_info): Define.
+ (elf_reloc_symbol_deleted_p): Define.
+ * elflink.h (elf_link_input_bfd): Check
+ elf_section_ignore_discarded_relocs. Call
+ bed->elf_backend_write_section if available.
+ (elf_reloc_symbol_deleted_p): New.
+ (elf_bfd_discard_info): New.
+ (elf_section_ignore_discarded_relocs): New.
+ * elfxx-target.h (elf_backend_discard_info): Define.
+ (elf_backend_ignore_discarded_relocs): Define.
+ (elf_backend_write_section): Define.
+ (elfNN_bed): Add elf_backend_discard_info,
+ elf_backend_ignore_discarded_relocs, and
+ elf_backend_write_section.
+ * libbfd-in.h (_bfd_discard_section_stabs): Add prototype.
+ * libbfd.h: Regenerate.
+ * stabs.c (_bfd_discard_section_stabs): New.
+
+2001-11-14 Martin Schwidefsky <schwidefsky@de.ibm.com>
+
+ * elf32-s390.c (elf_s390_relocate_section): Use the "unresolved_reloc"
+ scheme to get rid of an ugly complicated test.
+ * elf64-s390.c (elf_s390_relocate_section): Likewise.
+
+2001-11-14 Andreas Jaeger <aj@suse.de>
+
+ * cpu-i386.c (bfd_x86_64_arch_intel_syntax,bfd_x86_64_arch): Use
+ x86-64 for display.
+
+2001-11-14 Jakub Jelinek <jakub@redhat.com>
+
+ * dwarf2.c (struct line_head) [total_length]: Change type to
+ bfd_vma.
+ (struct dwarf2_debug): Add dwarf_str_buffer and dwarf_str_size.
+ (struct comp_unit): Add stash and offset_size.
+ (read_8_bytes): Return bfd_vma.
+ (read_indirect_string): New.
+ (read_attribute): Handle DW_FORM_strp.
+ (decode_line_info): Support 64-bit DWARF format.
+ (_bfd_dwarf2_find_nearest_line): Likewise.
+ (parse_comp_unit): Set offset_size and stash.
+
+2001-11-13 Keith Walker <keith.walker@arm.com>
+
+ * dwarf2.c (read_attribute_value): New function to handle
+ DW_FORM_indirect.
+ (read_attribute): Use it.
+
+2001-11-13 Geoffrey Keating <geoffk@redhat.com>
+
+ * dwarf2.c (decode_line_info): Properly deal with unknown standard
+ opcodes.
+
+2001-11-13 John Marshall <jmarshall@acm.org>
+ Alan Modra <amodra@bigpond.net.au>
+
+ * section.c (bfd_make_section_anyway): Don't increment section_id
+ and the BFD's section_count if adding the section failed.
+ * vms.c (vms_new_section_hook): Adjust for bfd_make_section_anyway
+ change.
+
+2001-11-12 Orjan Friberg <orjanf@axis.com>
+
+ * elf32-cris.c (cris_elf_grok_prstatus): Adjust values to match new
+ core dump format.
+
+2001-11-11 H.J. Lu <hjl@gnu.org>
+
+ * elf32-mips.c (_bfd_mips_elf_finish_dynamic_sections): Call
+ _bfd_elf_strtab_size instead of _bfd_stringtab_size.
+
+ * elf64-sparc.c (sparc64_elf_size_dynamic_sections): Change
+ dynstr type to `struct elf_strtab_hash *'.
+
+2001-11-11 Hans-Peter Nilsson <hp@bitrange.com>
+
+ * elf-strtab.c (_bfd_elf_strtab_finalize): Make first variable i
+ size_t. Rename second i to j.
+
+2001-11-10 Jeffrey A Law (law@cygnus.com)
+
+ * binary.c: Include safe-ctype.h after bfd.h and sysdep.h.
+
+2001-11-10 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-arm.h (elf32_arm_final_link_relocate): Don't copy STN_UNDEF
+ relocs into shared libs.
+ * elf32-cris.c (cris_elf_relocate_section): Likewise.
+ * elf32-i370.c (i370_elf_relocate_section): Likewise.
+ * elf32-m68k.c (elf_m68k_relocate_section): Likewise.
+ * elf32-mips.c (mips_elf_calculate_relocation): Likewise.
+ * elf32-ppc.c (ppc_elf_relocate_section): Likewise.
+ * elf32-sh.c (sh_elf_relocate_section): Likewise.
+ * elf32-sparc.c (elf32_sparc_relocate_section): Likewise.
+ * elf64-alpha.c (elf64_alpha_relocate_section): Likewise.
+ * elf64-s390.c (elf_s390_relocate_section): Likewise.
+ * elf64-sparc.c (sparc64_elf_relocate_section): Likewise.
+ * elf64-x86-64.c (elf64_x86_64_relocate_section): Likewise.
+ * elfxx-ia64.c (elfNN_ia64_relocate_section): Likewise.
+
+ * elf.c (bfd_section_from_r_symndx): New function.
+ * elf-bfd.h (LOCAL_SYM_CACHE_SIZE): Define.
+ (struct sym_sec_cache): New.
+ (bfd_section_from_r_symndx): Declare.
+ (struct bfd_elf_section_data): Change local_dynrel type to PTR.
+ * elflink.h (elf_link_input_bfd): Don't test for removed linkonce
+ relocs when relocatable. Don't zero entire reloc, just zero the
+ addend and sym.
+ * elf32-hppa.c (struct elf32_hppa_link_hash_table): Add sym_sec.
+ (elf32_hppa_link_hash_table_create): Init it.
+ (elf32_hppa_check_relocs): Track dynamic relocs needed for local
+ syms on a per-section basis as we do for globals.
+ (elf32_hppa_gc_sweep_hook): Update for local_dynrel change.
+ (allocate_dynrelocs): Warning fix.
+ (elf32_hppa_size_dynamic_sections): Don't allocate relocs when
+ section has been discarded.
+ (elf32_hppa_relocate_section): Don't copy STN_UNDEF relocs
+ into shared libs.
+ * elf32-i386.c (struct elf_i386_link_hash_table): Add sym_sec.
+ (elf_i386_link_hash_table_create): Init it.
+ (elf_i386_check_relocs): Track dynamic relocs needed for local
+ syms on a per-section basis as we do for globals.
+ (elf_i386_gc_sweep_hook): Update for local_dynrel change.
+ Remove dead code.
+ (allocate_dynrelocs): Warning fix.
+ (elf_i386_size_dynamic_sections): Don't allocate relocs when
+ section has been discarded.
+ (elf_i386_relocate_section): Don't copy STN_UNDEF relocs
+ into shared libs.
+ * elf32-s390.c (struct elf_s390_link_hash_table): Add sym_sec.
+ (elf_s390_link_hash_table_create): Init it.
+ (elf_s390_check_relocs): Track dynamic relocs needed for local
+ syms on a per-section basis as we do for globals.
+ (elf_s390_gc_sweep_hook): Update for local_dynrel change.
+ Remove dead code.
+ (allocate_dynrelocs): Warning fix.
+ (elf_s390_size_dynamic_sections): Don't allocate relocs when
+ section has been discarded.
+ (elf_s390_relocate_section): Don't copy STN_UNDEF relocs
+ into shared libs.
+ * elf64-ppc.c (struct ppc_link_hash_table): Add sym_sec.
+ (ppc64_link_hash_table_create): Init it.
+ (ppc64_elf_check_relocs): Track dynamic relocs needed for local
+ syms on a per-section basis as we do for globals.
+ (ppc64_elf_gc_sweep_hook): Update for local_dynrel change.
+ (allocate_dynrelocs): Call the correct record_dynamic_dymbol
+ function. Warning fix.
+ (ppc64_elf_size_dynamic_sections): Don't allocate relocs when
+ section has been discarded.
+ (ppc64_elf_relocate_section): Don't copy STN_UNDEF relocs
+ into shared libs.
+ * elf64-s390.c (struct elf_s390_link_hash_table): Add sym_sec.
+ (elf_s390_link_hash_table_create): Init it.
+ (elf_s390_check_relocs): Track dynamic relocs needed for local
+ syms on a per-section basis as we do for globals.
+ (elf_s390_gc_sweep_hook): Update for local_dynrel change.
+ Remove dead code.
+ (allocate_dynrelocs): Warning fix.
+ (elf_s390_size_dynamic_sections): Don't allocate relocs when
+ section has been discarded.
+ (elf_s390_relocate_section): Don't copy STN_UNDEF relocs
+ into shared libs.
+
+2001-11-08 Martin Schwidefsky <schwidefsky@de.ibm.com>
+
+ * elf32-s390: Major rework that introduces all recent changes to
+ the s390 backends. Get a closer match to elf32-i386.
+ (elf_s390_relocate_section): Make use of dynamic section short-cuts.
+ Localise vars, and delay setting. Better error reporting, replace
+ BFD_ASSERT with abort. Check ELF_LINK_HASH_DEF_DYNAMIC to see if a
+ symbol is not defined in the regular object file and tread the weak
+ definition as the normal one. Don't discard relocs for undefweak or
+ undefined symbols and check !DEF_REGULAR as well as DEF_DYNAMIC in
+ test for avoided copy relocs. Reinstate fudge for unresolved relocs
+ in debugging sections.
+ (elf32_s390_adjust_dynamic_symbol): Handle nocopyreloc. Don't do copy
+ reloc processing for weakdefs. Remove redundant casts and aborts.
+ Delay setting of vars until needed. Move creation of dynamic symbols
+ and allocation of .plt and .rela.plt to allocate_dynrelocs. Replace
+ BFD_ASSERT with abort. Discard .plt entries for everything with
+ plt.refcount <= 0.
+ (elf_s390_check_relocs): Don't allocate space for dynamic relocs,
+ .got or .relgot here but do it in allocate_dynrelocs. Reference count
+ possible .plt and .got entries. Don't test input section SEC_READONLY
+ here to try to avoid copy relocs, and keep dyn_relocs regardless of
+ ELF_LINK_NON_GOT_REF. Don't set DF_TEXTREL here. Delay setting of
+ variables until needed. Remove separate switch stmt for creating .got
+ section. Initialise local_got_refcounts to 0. Cache pointer to
+ "sreloc" section in elf_section_data. Tweak condition under which .got
+ created. Report files with bad relocation section names.
+ (elf_s390_finish_dynamic_symbol): Don't copy relocs for symbols that
+ have been forced local. Use same test to decide if we can use a
+ relative reloc for got as elf_s390_relocate_section. Expand SHN_UNDEF
+ comment. Move expressions out of function calls. Replace BFD_ASSERT
+ with abort.
+ (elf_s390_finish_dynamic_sections): Migrate common code out of switch
+ statement. Replace BFD_ASSERT with abort.
+ (elf_s390_size_dynamic_sections): Call readonly_dynrelocs. Rename "i"
+ to "ibfd". Allocate space for local dyn relocs. Use DF_TEXTREL flag
+ instead of looking up section names for DT_TEXTREL. Replace
+ BFD_ASSERT with abort. Zero out the dynamic allocated content space.
+ Add a comment to remind us that one day this ought to be fixed.
+ (struct elf_s390_link_hash_entry): Rename "root" to "elf".
+ (struct elf_s390_link_hash_table): Likewise.
+ (elf_s390_link_hash_newfunc): Rename to link_hash_newfunc and get
+ rid of unnecessary casts.
+ (struct elf_s390_dyn_relocs): Add "sec", and "pc_count" fields.
+ Remove "section" field.
+ (elf_s390_gc_sweep_hook): Sweep dyn_relocs and local_dynrel.
+ Reference count possible .plt entries. Don't deallocate .got and
+ .relgot space here.
+ (struct elf_s390_pcrel_relocs_copied): Rename to elf_s390_dyn_relocs.
+ Update comment.
+ (struct elf_s390_link_hash_entry): Rename pcrel_relocs_copied to
+ dyn_relocs.
+ (elf_s390_discard_copies): Delete.
+ (elf_s390_link_hash_traverse): Delete.
+ (bfd_elf32_bfd_final_link): Delete. (ie. use regular final link
+ rather than gc variety).
+ (struct elf_s390_link_hash_table): Add sgot, sgotplt, srelgot, splt,
+ srelplt, sdynbss, srelbss fields.
+ (elf_s390_link_hash_table_create): Init them.
+ (WILL_CALL_FINISH_DYNAMIC_SYMBOL): Define.
+ (allocate_dynrelocs): New function.
+ (create_got_section): New function.
+ (elf_backend_can_refcount): Define.
+ (elf_backend_copy_indirect_symbol): Define.
+ (elf_s390_copy_indirect_symbol): New function.
+ (elf_s390_create_dynamic_sections): New function.
+ (readonly_dynrelocs): New function.
+ * elf64-s390.c: Likewise.
+
+2001-11-07 Jakub Jelinek <jakub@redhat.com>
+
+ * Makefile.am (BFD32_BACKENDS): Add elf-strtab.lo.
+ (BFD32_BACKENDS_CFILES): Add elf-strtab.c.
+ (elf-strtab.lo): Add rule.
+ * Makefile.in: Rebuilt.
+ * configure.in (elf): Add elf-strtab.lo.
+ * configure: Rebuilt.
+ * elf-bfd.h (elf_strtab_hash): Forward declare.
+ (struct elf_link_hash_table): Change dynstr type to
+ struct elf_strtab_hash *.
+ (struct elf_obj_tdata): Change strtab_ptr type to
+ struct elf_strtab_hash *.
+ (_bfd_elf_strtab_init, _bfd_elf_strtab_free, _bfd_elf_strtab_add,
+ _bfd_elf_strtab_addref, _bfd_elf_strtab_delref,
+ _bfd_elf_strtab_clear_all_refs, _bfd_elf_strtab_size,
+ _bfd_elf_strtab_offset, _bfd_elf_strtab_emit,
+ _bfd_elf_strtab_finalize): New prototypes.
+ * elf-strtab.c: New file.
+ * elflink.h (elf_link_add_object_symbols): Use _bfd_elf_strtab_add
+ and _bfd_elf_strtab_size instead of _bfd_stringtab calls.
+ Call _bfd_elf_strtab_delref if DT_NEEDED entry is not needed or
+ when forcing dynamic symbol to local.
+ (elf_link_create_dynamic_sections): Call
+ _bfd_elf_strtab_init instead of elf_stringtab_init.
+ (elf_link_record_local_dynamic_symbol): Likewise, change
+ dynstr type. Use _bfd_elf_strtab functions instead of
+ _bfd_stringtab calls.
+ (size_dynamic_sections): Use _bfd_elf_strtab functions instead of
+ _bfd_stringtab calls. For DT_RUNPATH and Verdaux vda_name fields,
+ call _bfd_elf_strtab_addref. Call elf_finalize_dynstr.
+ (elf_adjust_dynstr_offsets, elf_finalize_dynstr): New functions.
+ (elf_fix_symbol_flags): Call _bfd_elf_strtab_delref when forcing
+ dynamic symbol to local.
+ (elf_link_assign_sym_version): Likewise.
+ (elf_bfd_final_link): Call _bfd_elf_strtab_emit instead of
+ _bfd_stringtab_emit.
+ * elflink.c (_bfd_elf_link_record_dynamic_symbol): Change dynstr
+ type. Call _bfd_elf_strtab functions instead of
+ _bfd_stringtab functions.
+ * elf64-sparc.c (sparc64_elf_size_dynamic_sections): Likewise.
+ * elf.c (_bfd_elf_init_reloc_shdr): Likewise.
+ (elf_fake_sections): Likewise.
+ (assign_section_numbers): Call _bfd_elf_strtab_clear_all_refs
+ on shstrtab hash table, call _bfd_elf_strtab_addref on each section
+ name in the output. Call _bfd_elf_strtab_finalize and
+ use _bfd_elf_strtab_offset to finalize sh_name section header fields.
+ (_bfd_elf_compute_section_file_positions): Use _bfd_elf_strtab_size
+ instead of _bfd_stringtab_size.
+ (prep_headers): Change shstrtab type.
+ Use _bfd_elf_strtab calls instead of _bfd_stringtab calls.
+
+2001-11-07 Alan Modra <amodra@bigpond.net.au>
+
+ * elflink.h (elf_link_input_bfd <removed linkonce relocs>): Fix
+ bad symtab segfault. Formatting and warning fixes. Improve
+ error message for internationalisation.
+
+2001-11-06 H.J. Lu (hjl@gnu.org)
+
+ * elflink.h (elf_link_input_bfd): Complain about relocs against
+ discarded sections.
+
+2001-11-03 Alan Modra <amodra@bigpond.net.au>
+
+ * elfxx-target.h (elfNN_bed): Correct want_got_sym, want_dynbss order.
+
+2001-11-02 H.J. Lu <hjl@gnu.org>
+
+ * elf32-mips.c (mips_elf_calculate_relocation): Don't create
+ dynamic relocation for symbols defined in regular objects when
+ creating executables.
+
+2001-11-02 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * configure.in (ALL_LINGUAS): Add "fr".
+ * configure: Regenerate.
+ * po/fr.po: New file.
+
+ * coffgen.c (coff_object_p): Add comment to H.J.'s recent patch.
+
+2001-11-02 John David Anglin <dave@hiauly1.hia.nrc.ca>
+
+ * som.c (setup_sections): Initialize subspace_sections.
+
+2001-11-02 H.J. Lu (hjl@gnu.org)
+
+ * coffgen.c (coff_object_p): Return 0 if the header is too big.
+
+2001-11-02 Hans-Peter Nilsson <hp@axis.com>
+
+ * elfcore.h (elf_core_file_p): Preserve and clear abfd section
+ information. Save bfd arch and mach values. Restore on error.
+
+2001-11-02 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-hppa.c (hppa_handle_PIC_calls): Rename to mark_PIC_calls.
+ (allocate_PIC_calls): New function.
+ (allocate_dynrelocs): Don't allocate pic_call plt entries here.
+ (elf32_hppa_size_dynamic_sections): Call allocate_PIC_calls.
+ (elf32_hppa_finish_dynamic_symbol): Remove dead code.
+
+2001-11-02 Hans-Peter Nilsson <hp@axis.com>
+
+ * elf32-cris.c (cris_elf_grok_prstatus): New function.
+ (cris_elf_grok_psinfo): New function.
+ (elf_backend_grok_prstatus): Define.
+ (elf_backend_grok_psinfo): Define.
+
+2001-11-01 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (ppc64_elf_relocate_section): Correct branch
+ prediction bits.
+
+2001-10-31 Chris Demetriou <cgd@demetriou.com>
+
+ * elf32-mips.c (_bfd_mips_elf_hi16_reloc): Handle PC-relative
+ relocations properly.
+
+2001-10-31 H.J. Lu <hjl@gnu.org>
+
+ * elflink.h (elf_link_output_extsym): Don't clear the visibility
+ field for relocateable.
+
+2001-11-01 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-hppa.c (elf32_hppa_finish_dynamic_sections): Don't count
+ .plt relocs in DT_RELASZ.
+
+2001-10-29 NIIBE Yutaka <gniibe@m17n.org>
+
+ * config.bfd: Supports sh3/sh4/sh3eb/sh4eb-unknown-linux-gnu
+ targets.
+
+2001-10-31 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * targets.c: Fix typo: bfd_mmo_mmix_vec => bfd_mmo_vec.
+
+2001-10-30 Hans-Peter Nilsson <hp@bitrange.com>
+
+ * Makefile.am (ALL_MACHINES): Add cpu-mmix.lo.
+ (BFD64_BACKENDS): Add elf64-mmix.lo and mmo.lo.
+ (BFD64_BACKENDS_CFILES): Add elf64-mmix.c and mmo.c.
+ Regenerate dependencies.
+ * configure.in (bfd_elf64_mmix_vec, bfd_mmo_vec): New vectors.
+ * config.bfd: [BFD64] (mmix-*-*): New case.
+ * cpu-mmix.c, mmo.c, elf64-mmix.c: New files.
+ * archures.c (enum bfd_architecture): Add bfd_arch_mmix.
+ (bfd_mmix_arch): Declare.
+ (bfd_archures_list): Add bfd_mmix_arch.
+ * targets.c (enum bfd_flavour): Add bfd_target_mmo_flavour.
+ (bfd_elf64_mmix_vec, bfd_mmo_vec): Declare.
+ (bfd_target_vect) [BFD64]: Add bfd_elf64_mmix_vec and
+ bfd_mmo_mmix_vec.
+ * reloc.c: Add MMIX relocations.
+ * bfd.c (struct _bfd, tdata): Add mmo_data.
+ * Makefile.in: Regenerate.
+ * configure: Regenerate.
+ * libbfd.h: Regenerate.
+ * bfd-in2.h: Regenerate.
+ * configure: Rebuild.
+
+2001-10-30 Richard Earnshaw (rearnsha@arm.com)
+
+ * elf.c (_bfd_elf_make_section_from_shdr): Set the LMA based on the
+ p_paddr of the segment that contains it.
+ (copy_private_bfd_data): If the LMA for a segment is known, use it
+ for matching sections to segments.
+ (assign_file_positions_for_segments): Use the LMA when adjusting
+ for inter-section alignment padding.
+
+2001-10-29 Kazu Hirata <kazu@hxi.com>
+
+ * README: Fix a typo.
+
+2001-10-24 Richard Henderson <rth@redhat.com>
+
+ * peXXigen.c (_bfd_XX_print_private_bfd_data_common): Copy
+ timestamp to time_t for ctime.
+
+2001-10-24 Hans-Peter Nilsson <hp@axis.com>
+
+ * elf32-cris.c (cris_reloc_type_lookup): Change loop to use
+ unsigned, increasing index.
+
+2001-10-23 H.J. Lu <hjl@gnu.org>
+
+ * elf32-mips.c (_bfd_mips_elf_modify_segment_map): Check
+ m != NULL before accessing it.
+
+2001-10-23 Alan Modra <amodra@bigpond.net.au>
+
+ * elflink.h (elf_link_input_bfd): Zero the reloc instead of doing
+ bfd_reloc_type_lookup (bfd, BFD_RELOC_NONE) as bfd_reloc_type_lookup
+ doesn't accept BFD_RELOC_* on some targets, eg. hppa.
+
+ * elf32-hppa.c (elf32_hppa_link_hash_entry): Remove plt_abs.
+ (hppa_link_hash_newfunc): Likewise.
+ (elf32_hppa_finish_dynamic_symbol): Likewise.
+ (allocate_dynrelocs): Always allocate .got relocs if shared.
+ (elf32_hppa_relocate_section): Output them too. Similarly
+ consolidate .plt reloc code, and no longer initialise .plt
+ when a reloc is output.
+ (elf32_hppa_finish_dynamic_symbol): Only initialise .plt entries
+ when no reloc is output.
+
+ From Herbert Xu <herbert@gondor.apana.org.au>
+ * elf32-hppa.c (final_link_relocate): Call bfd_set_error for
+ unreachable branches.
+
+2001-10-22 H.J. Lu <hjl@gnu.org>
+
+ * configure.in (WIN32LIBADD): Use -L../libiberty for
+ mips*-*-linux*.
+ * configure: Rebuild.
+
+2001-10-21 H.J. Lu <hjl@gnu.org>
+
+ * configure.in (WIN32LIBADD): Include -L../libiberty/pic -liberty
+ if shared library is enabled only for Linux hosts.
+ * configure: Rebuild.
+
+2001-10-21 H.J. Lu <hjl@gnu.org>
+
+ * configure.in (WIN32LIBADD): Check if PICFLAG is defined in
+ ../libiberty/Makefile instead of $enable_shared.
+ * configure: Rebuild.
+
+2001-10-21 H.J. Lu <hjl@gnu.org>
+
+ * elf32-cris.c (cris_reloc_type_lookup): Use int for index. Cover
+ index 0.
+
+2001-10-20 H.J. Lu <hjl@gnu.org>
+
+ * configure.in (WIN32LIBADD): Include -L../libiberty/pic -liberty
+ if shared library is enabled.
+ * configure: Rebuild.
+
+2001-10-20 H.J. Lu <hjl@gnu.org>
+
+ * elf32-cris.c (cris_reloc_type_lookup): Allow index 0.
+
+2001-10-19 H.J. Lu <hjl@gnu.org>
+
+ * elfcode.h (elf_object_p): Don't clear D_PAGED if the section
+ size is empty.
+
+2001-10-18 H.J. Lu <hjl@gnu.org>
+
+ * elf32-i370.c (i370_elf_relocate_section): Ignore R_XXX_NONE.
+ * elf32-ppc.c (ppc_elf_relocate_section): Likewise.
+
+2001-10-18 Jakub Jelinek <jakub@redhat.com>
+
+ * section.c (_bfd_strip_section_from_output): Don't count
+ SEC_EXCLUDE sections as references. Set SEC_EXCLUDE.
+
+2001-10-17 Alan Modra <amodra@bigpond.net.au>
+
+ * elf-m10200.c (mn10200_elf_relax_section): Cast assignment to
+ Elf_Internal_Shdr.contents now that it's no longer a PTR.
+ * elf-m10300.c (mn10300_elf_relax_section): Likewise.
+ * elf32-h8300.c (elf32_h8_relax_section): Likewise.
+ * elf32-m68k.c (bfd_m68k_elf32_create_embedded_relocs): Likewise.
+ * elf32-sh.c (sh_elf_relax_section): Likewise.
+ * elf64-alpha.c (elf64_alpha_relax_section): Likewise.
+ * elfxx-ia64.c (elfNN_ia64_relax_section): Likewise.
+ * elf.c (setup_group): Warning fixes.
+ * elflink.h (elf_link_sort_relocs): Likewise.
+ * pdp11.c (slurp_reloc_table): Likewise.
+
+2001-10-16 Jeff Holcomb <jeffh@redhat.com>
+
+ * elflink.h (elf_link_sort_relocs): Remove unnecessary pointer
+ casts.
+
+2001-10-15 H.J. Lu <hjl@gnu.org>
+
+ * elflink.h (elf_link_input_bfd): Set type to BFD_RELOC_NONE
+ for relocations against discarded link-once section.
+
+2001-10-15 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-i386.c (elf_i386_relocate_section): Report some detail on
+ bfd_reloc_outofrange and similar errors.
+
+ * elf.c (_bfd_elf_link_hash_copy_indirect): Test ind->root.type
+ rather than ind->weakdef.
+ * elf32-hppa.c (elf32_hppa_copy_indirect_symbol): Likewise.
+ * elf32-i386.c (elf_i386_copy_indirect_symbol): Likewise.
+ * elf32-mips.c (_bfd_mips_elf_copy_indirect_symbol): Likewise.
+ * elf64-ppc.c (ppc64_elf_copy_indirect_symbol): Likewise.
+ * elfxx-ia64.c (elfNN_ia64_hash_copy_indirect): Likewise.
+
+2001-10-15 Alan Modra <amodra@bigpond.net.au>
+ H.J. Lu <hjl@gnu.org>
+
+ * elf32-hppa.c (elf32_hppa_copy_indirect_symbol): Merge dyn_reloc
+ counts for aliases instead of aborting.
+ * elf32-i386.c (elf_i386_copy_indirect_symbol): Likewise.
+ * elf64-ppc.c (ppc64_elf_copy_indirect_symbol): Likewise.
+
+ * elf32-hppa.c (elf32_hppa_adjust_dynamic_symbol): Set plt.offset
+ to -1 for non-function symbols.
+ * elf32-ppc.c (ppc_elf_adjust_dynamic_symbol): Likewise.
+ * elf32-s390.c (elf_s390_adjust_dynamic_symbol): Likewise.
+ * elf64-ppc.c (ppc64_elf_adjust_dynamic_symbol): Likewise.
+ * elf64-s390.c (elf_s390_adjust_dynamic_symbol): Likewise.
+ * elf64-x86-64.c (elf64_x86_64_adjust_dynamic_symbol): Likewise.
+ * elf32-i386.c (elf_i386_adjust_dynamic_symbol): Refer to
+ plt.offset instead of plt.refcount when setting to -1.
+
+2001-10-12 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * elf32-arm.h (elf32_arm_relocate_section): Treat R_ARM_THM_PC22
+ like R_ARM_PC24. Include reloc number in error message about
+ unresolvable relocs.
+
+2001-10-10 Jakub Jelinek <jakub@redhat.com>
+
+ * elflink.h (elf_link_sort_cmp2): Don't mix PLT and non-PLT
+ relocations against the same symbol in .rel{,a}.dyn section.
+
+2001-10-10 Kazu Hirata <kazu@hxi.com>
+
+ * aout-encap.c: Fix comment typos.
+ * aoutx.h: Likewise.
+ * archive.c: Likewise.
+ * bout.c: Likewise.
+ * coff64-rs6000.c: Likewise.
+ * coffcode.h: Likewise.
+ * coffgen.c: Likewise.
+ * cofflink.c: Likewise.
+ * coff-mips.c: Likewise.
+ * ecoff.c: Likewise.
+ * elf32-m32r.c: Likewise.
+ * libcoff-in.h: Likewise.
+ * libecoff.h: Likewise.
+ * libxcoff.h: Likewise.
+ * nlm32-i386.c: Likewise.
+ * pdp11.c: Likewise.
+ * section.c: Likewise.
+ * som.c: Likewise.
+ * som.h: Likewise.
+ * bfd-in2.h: Regenerate.
+ * libcoff.h: Likewise.
+
+2001-10-10 Alan Modra <amodra@bigpond.net.au>
+
+ * elf.c (elf_map_symbols): Don't create new section symbols; Use
+ existing section syms. Update comments.
+ (copy_private_bfd_data): Formatting fixes.
+ (elfcore_grok_win32pstatus): Likewise.
+ (swap_out_syms): Likewise. Remove unnecessary level of braces.
+
+2001-10-09 Alan Modra <amodra@bigpond.net.au>
+
+ * elf-bfd.h (struct bfd_elf_section_data): Rename "group" to
+ "group_name".
+ (elf_group_name): Define.
+ (elf_next_in_group): Define.
+ * elf.c: Make use of elf_group_name and elf_next_in_group throughout.
+ (setup_group): Don't use sec->lineno for SHT_GROUP section to store
+ first member section; Instead use elf_next_in_group.
+ (bfd_section_from_shdr): Likewise.
+ (set_group_contents): Likewise. Use elf_section_syms, not sec->symbol.
+
+2001-10-09 Alan Modra <amodra@bigpond.net.au>
+
+ * elf-bfd.h (struct bfd_elf_section_data): Add "group" and
+ "next_in_group". Fix gp and gp_size comments.
+ * elf.c (union elf_internal_group): New.
+ (setup_group): New function.
+ (_bfd_elf_make_section_from_shdr): Set BFD flags for SHT_GROUP.
+ Call setup_group for SHF_GROUP sections.
+ (bfd_section_from_shdr): Build a BFD section for SHT_GROUP.
+ (elf_fake_sections): Set header type for SEC_GROUP, and header
+ flags for sections in a group.
+ (set_group_contents): New function.
+ (_bfd_elf_compute_section_file_positions): Call it.
+ (assign_section_numbers): Set sh_link for SHT_GROUP.
+
+ * elflink.h (gc_mark_hook): Handle section groups.
+ * elfxx-target.h: Add SEC_GROUP to applicable_flags.
+ * section.c (SEC_GROUP): Define.
+ (struct sec): Comment fixes.
+ * bfd-in2.h: Regenerate.
+
+ * elf.c (bfd_elf_print_symbol): Formatting fix; migrate expression
+ out of function args.
+ (_bfd_elf_canonicalize_reloc): Similarly.
+ (_bfd_elf_get_symtab): Here too.
+ (_bfd_elf_canonicalize_dynamic_symtab): And here.
+ * elfcode.h (elf_slurp_symbol_table): Don't recalculate size for
+ bfd_bread, and remove unnecessary cast.
+
+2001-10-08 Aldy Hernandez <aldyh@redhat.com>
+
+ * config.bfd (targ_cpu): Add arm9e-*-elf.
+
+2001-10-06 Stephane Carrez <Stephane.Carrez@worldnet.fr>
+
+ * dwarf2.c (comp_unit_find_nearest_line): Check for end of
+ compilation unit.
+
+2001-10-06 Alan Modra <amodra@bigpond.net.au>
+
+ * bfd.c (bfd_assert): Report bfd version.
+ (_bfd_abort): Likewise.
+
+ * elflink.h (elf_link_input_bfd): Don't zero discarded link-once
+ section sym values. Instead replace any relocs against them with
+ relocs against STN_UNDEF, which has a zero value.
+
+ * elf32-arc.c (elf_arc_howto_table): Set partial_inplace for all
+ relocs.
+
+2001-10-05 Jeff Law <law@redhat.com>
+
+ * som.h (som_exec_data): New field "version_id".
+ * som.c (som_object_setup): Record the version_id if it
+ exists.
+ (som_prep_headers): Do not initialize version_id here.
+ (som_finish_writing): Initialize version_id here.
+
+2000-10-05 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * elf32-mips.c (elf_mips_howto_table): Fix some relocation howtos
+ according to the MIPS/SGI ELF64 ABI Draft.
+ (mips_elf_sort_hash_table): Typo.
+
+2001-10-04 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-mips.c (_bfd_mips_elf_copy_indirect_symbol): Comment typo.
+
+ * elf32-mips.c (_bfd_mips_elf_copy_indirect_symbol): Bail out after
+ copying flags if this is a weakdef.
+
+2001-10-04 Alan Modra <amodra@bigpond.net.au>
+
+ * elf-bfd.h (struct elf_link_hash_entry): Reorganise for better
+ packing.
+
+ * elf32-mips.c (mips_elf_record_global_got_symbol): Set got.offset
+ to 1 rather than 0 to avoid confusing copy_indirect_symbol.
+ (mips_elf_sort_hash_table_f): Compare got.offset against 1.
+
+ * Makefile.am (BFD_H_DEPS): Add symcat.h. Ensure everything
+ depends on $(BFD_H) $(BFD_H_DEPS) $(LOCAL_H_DEPS), not just those
+ backends we configure. Run "make dep-am".
+ (install-data-local): Install symcat.h.
+ * dep-in.sed: Remove symcat.h from dependencies.
+ * Makefile.in: Regenerate.
+
+2001-10-03 Vassili Karpov <malc@pulsesoft.com>
+
+ * elf32-i386.c (elf_i386_adjust_dynamic_symbol): Handle nocopyreloc.
+
+2001-10-03 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * elf64-mips.c (elf_backend_may_use_rela_p): New define.
+ (elf_backend_default_use_rela_p): New define.
+
+2001-10-03 Alan Modra <amodra@bigpond.net.au>
+
+ * elfxx-ia64.c (elfNN_ia64_hash_copy_indirect): Fix typos in last
+ change.
+
+ * configure.in (AC_OUTPUT <bfd-in3.h>): Remove version.h.
+ * configure: Regenerate.
+ * Makefile.am (BFD_H_FILES): Add version.h.
+ * Makefile.in: Regenerate.
+ * po/SRC-POTFILES.in: Regenerate.
+
+ * elflink.h (elf_fix_symbol_flags): Copy flags to weakdef using
+ elf_backend_copy_indirect_symbol so that backend has a chance to
+ copy other necessary fields.
+ * elf-bfd.h (struct elf_backend_data): Update description of
+ elf_backend_copy_indirect_symbol.
+ * elf.c (_bfd_elf_link_hash_copy_indirect): Bail out after
+ copying flags if this is a weakdef.
+ * elfxx-ia64.c (elfNN_ia64_hash_copy_indirect): Likewise.
+ (elfNN_ia64_aix_add_symbol_hook): Use elf_link_hash_lookup rather
+ than bfd_link_hash_lookup.
+ * elf32-i386.c (elf_i386_adjust_dynamic_symbol): Don't do copy
+ reloc processing for weakdefs.
+ * elf32-hppa.c (elf32_hppa_adjust_dynamic_symbol): Likewise.
+ * elf64-ppc.c (ppc64_elf_adjust_dynamic_symbol): Likewise.
+
+2001-10-02 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (ppc64_elf_check_relocs): Use a local var and cast
+ result of ELF64_R_TYPE to enum before using in a switch.
+ (ppc64_elf_gc_mark_hook): Likewise.
+ (ppc64_elf_gc_sweep_hook): Likewise.
+ (ppc64_elf_reloc_type_class): Likewise.
+
+2001-10-02 Alan Modra <amodra@bigpond.net.au>
+
+ * version.h: New file.
+ * bfd-in.h: (BFD_VERSION): Substitute bfd_version.
+ (BFD_VERSION_DATE): Define.
+ (BFD_VERSION_STRING): Define.
+ * configure.in: AC_SUBST bfd_version, bfd_version_date and
+ bfd_version_string.
+ (AC_OUTPUT <bfd-in3.h>): Depend on version.h.
+ * bfd-in2.h: Regenerate.
+ * configure: Regenerate.
+ * Makefile.am: Run "make dep-am".
+ * Makefile.in: Regenerate.
+
+ * bfd-in.h: Include "symcat.h".
+ (CONCAT4): Redefine as for old CAT4.
+ * aout-arm.c: Use equivalent CONCAT* macro in place of CAT* macros.
+ Add warning regarding whitespace.
+ * aout-cris.c: Likewise.
+ * aout-ns32k.c: Likewise.
+ * aout-sparcle.c: Likewise.
+ * aout-tic30.c: Likewise.
+ * aout0.c: Likewise.
+ * armnetbsd.c: Likewise.
+ * demo64.c: Likewise.
+ * elf-bfd.h: Likewise.
+ * gen-aout.c: Likewise.
+ * host-aout.c: Likewise.
+ * hp300bsd.c: Likewise.
+ * hp300hpux.c: Likewise.
+ * i386aout.c: Likewise.
+ * i386bsd.c: Likewise.
+ * i386dynix.c: Likewise.
+ * i386freebsd.c: Likewise.
+ * i386linux.c: Likewise.
+ * i386lynx.c: Likewise.
+ * i386mach3.c: Likewise.
+ * i386netbsd.c: Likewise.
+ * libaout.h: Likewise.
+ * m68k4knetbsd.c: Likewise.
+ * m68klinux.c: Likewise.
+ * m68klynx.c: Likewise.
+ * m68knetbsd.c: Likewise.
+ * m88kmach3.c: Likewise.
+ * mipsbsd.c: Likewise.
+ * newsos3.c: Likewise.
+ * ns32knetbsd.c: Likewise.
+ * pc532-mach.c: Likewise.
+ * pdp11.c: Likewise.
+ * riscix.c: Likewise.
+ * sparclinux.c: Likewise.
+ * sparclynx.c: Likewise.
+ * sparcnetbsd.c: Likewise.
+ * sunos.c: Likewise.
+ * targets.c: Likewise.
+ * vaxnetbsd.c: Likewise.
+ * vms-hdr.c: Likewise.
+
+2001-10-01 Alan Modra <amodra@bigpond.net.au>
+
+ * bfd-in.h: Remove comments regarding generated files.
+ * libbfd-in.h: Likewise.
+ * libcoff-in.h: Likewise.
+ * bfd-in2.h: Regenerate.
+ * libbfd.h: Likewise.
+ * libcoff.h: Likewise.
+
+2001-09-30 kaz Kojima <kkojima@rr.iij4u.or.jp>
+ Hans-Peter Nilsson <hp@bitrange.com>
+
+ * elf32-sh.c (sh_elf_howto_table, R_SH_REL32): Make
+ partial_inplace, matching assembler output. Set src_mask to
+ all ones.
+ (sh_elf_relocate_section): Delete misplaced comment.
+ For relocatable linking against section symbol, call
+ _bfd_relocate_contents for partial_inplace relocs and adjust
+ rel->r_addend for others.
+ <case R_SH_DIR32, R_SH_REL32>: Fetch partial_inplace addend with
+ bfd_get_32, not at rel->r_addend.
+
+2001-09-30 Alan Modra <amodra@bigpond.net.au>
+
+ * elf.c (_bfd_elf_link_hash_copy_indirect): Set ind refcounts to
+ the old dir refcount, so we indirectly set them to init_refcount.
+ Short-circuit asserts when we've just verified they are true.
+
+2001-09-29 Alan Modra <amodra@bigpond.net.au>
+
+ * section.c (struct sec): Remove kept_section.
+ (STD_SECTION): Remove kept_section initialisation.
+ (bfd_make_section_anyway): Here too.
+ * ecoff.c (bfd_debug_section): Remove kept_section initialisation.
+ * cofflink.c (_bfd_coff_link_input_bfd): Don't test kept_section.
+ * elflink.h (elf_link_input_bfd): Set discarded link-once section
+ symbols to zero, and remove all code involved with kept_section
+ and tracking section symbol values.
+ * bfd-in2.h: Regenerate.
+ * configure.in: Bump version number.
+ * configure: Regenerate.
+
+2001-09-29 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (struct ppc_dyn_relocs): New.
+ (IS_ABSOLUTE_RELOC): Define.
+ (struct ppc_link_hash_entry): New.
+ (struct ppc_link_hash_table): New.
+ (ppc_hash_table): Define.
+ (link_hash_newfunc): New function.
+ (ppc64_elf_link_hash_table_create): New function.
+ (create_got_section): New function.
+ (ppc64_elf_create_dynamic_sections): Call create_got_section. Stash
+ pointers to our dynamic sections in hash table.
+ (ppc64_elf_copy_indirect_symbol): New function.
+ (ppc64_elf_check_relocs): Remove DEBUG code. Use short-cuts to
+ dynamic sections. Localise vars. Modify code for refcounts
+ starting from zero. Don't allocate here, or force symbols dynamic.
+ Don't copy all relocs if shared, select ones we need. Add code
+ to track possible copy relocs for non-shared link.
+ (ppc64_elf_gc_mark_hook): Update comment.
+ (ppc64_elf_gc_sweep_hook): Sweep dynrelocs too.
+ (ppc64_elf_adjust_dynamic_symbol): Remove DEBUG code. Rewrite .plt
+ code for reference counting garbage collection. Don't create .plt
+ entries for functions that don't comply with ABI naming convention,
+ and don't allocate .plt space here. Use short-cuts to dynamic
+ sections. If possible, keep dynamic relocations instead of using
+ copy relocs. Remove confused comments.
+ (ppc_adjust_dynindx): Delete.
+ (WILL_CALL_FINISH_DYNAMIC_SYMBOL): Define.
+ (allocate_dynrelocs): New function.
+ (readonly_dynrelocs): New function.
+ (ppc64_elf_size_dynamic_sections): Rewrite. Allocate local .got
+ space here, and call allocate_dynrelocs to allocate space for
+ global .plt, .got and reloc sections. Use short-cuts to dynamic
+ sections. Call readonly_dynrelocs to determine whether we need
+ DT_TEXTREL. Don't generate section symbols here, the generic
+ ELF linker code does it for us.
+ (ppc64_elf_final_link): Call regular ELF backend linker rather than
+ gc variety, since we do our own .got handling.
+ (ppc64_elf_relocate_section): Remove DEBUG code. Make use of
+ dynamic section short-cuts. Localise vars, and delay setting.
+ Handle unknown relocs in main switch statement. Replace ugly
+ complicated tests for unresolvable relocs with a simple direct
+ scheme using "unresolved_reloc" var. Test ELF_ST_VISIBILITY
+ before allowing an undefined sym in a shared lib. Do R_*_DS tests
+ after main switch, when we've set addend. Do non-addend insn
+ tweaks before main swithc. Ignore input_section->vma when
+ calculating reloc offsets as it's always zero. Rewrite dynamic
+ reloc handling. Consolidate R_*_HA handling. Handle more relocs.
+ (ppc64_elf_finish_dynamic_symbol): Remove DEBUG code. Make use
+ of dynamic section short-cuts. Reorganise .plt handling code.
+ Remove confused comments. Take note of ELF_LINK_FORCED_LOCAL.
+ Move expressions out of swap_reloca_out function calls.
+ (ppc64_elf_reloc_type_class): New function.
+ (ppc64_elf_info_to_howto): Move common expression to local var.
+ (ppc64_elf_finish_dynamic_sections): Remove DEBUG code. Make use
+ of dynamic section short-cuts. Don't fiddle with section syms
+ here as the ELF linker does it for us.
+ (elf_backend_can_refcount): Define.
+ (bfd_elf64_bfd_link_hash_table_create): Define.
+ (elf_backend_copy_indirect_symbol): Define.
+ (elf_backend_reloc_type_class): Define.
+ (elf_backend_*, bfd_elf64_bfd_* defines): Sort.
+
+2001-09-29 Alan Modra <amodra@bigpond.net.au>
+
+ * elf-bfd.h (struct elf_link_local_dynamic_entry): Add init_refcount.
+ (struct elf_backend_data): Add can_refcount.
+ * elf.c (_bfd_elf_link_hash_newfunc): Get rid of a few casts. Set
+ got.refcount and plt.refcount from init_refcount.
+ (_bfd_elf_link_hash_table_init): Set up init_refcount.
+ (_bfd_elf_link_hash_copy_indirect): Reference got/plt.refcount
+ rather than got/plt.offset, and test for <= 0 rather than -1.
+ * elflink.h (size_dynamic_sections): Set init_refcount to -1.
+ * elfxx-target.h (elf_backend_can_refcount): Define.
+ (elfNN_bed): Init can_refcount.
+ * linker.c (_bfd_link_hash_newfunc): Get rid of a few casts.
+ (_bfd_generic_link_hash_newfunc): Likewise.
+ * elf32-cris.c (cris_elf_check_relocs): Modify for refcounts
+ starting from zero.
+ (elf_backend_can_refcount): Define.
+ * elf32-hppa.c (elf32_hppa_check_relocs): Modify for refcounts
+ starting from zero.
+ (elf32_hppa_copy_indirect_symbol): Make static to agree with
+ prototype.
+ (elf_backend_can_refcount): Define.
+ * elf32-i386.c (elf_i386_check_relocs): Modify for refcounts
+ starting from zero.
+ (allocate_dynrelocs): Set plt/got.offset rather than *.refcount.
+ (elf_i386_finish_dynamic_symbol): Expand SHN_UNDEF comment.
+ (elf_i386_finish_dynamic_sections): Use local var so line < 80 chars.
+ (elf_backend_can_refcount): Define.
+ (elf_i386_copy_indirect_symbol): Make static to agree with
+ prototype. Formatting fix.
+ * elf32-m68k.c (elf_m68k_check_relocs): Modify for refcounts
+ starting from zero.
+ (elf_backend_can_refcount): Define.
+ * elf32-ppc.c (ppc_elf_check_relocs): Modify for refcounts
+ starting from zero.
+ (elf_backend_can_refcount): Define.
+ * elf32-s390.c (elf_s390_check_relocs): Modify for refcounts
+ starting from zero.
+ (elf_backend_can_refcount): Define.
+ * elf64-s390.c (elf_s390_check_relocs): Modify for refcounts
+ starting from zero.
+ (elf_backend_can_refcount): Define.
+ * elf64-x86-64.c (elf64_x86_64_check_relocs): Modify for refcounts
+ starting from zero.
+ (elf_backend_can_refcount): Define.
+
+ * som.c (som_write_symbol_strings): Cast current_offset in
+ bfd_seek call to match param type.
+
+2001-09-28 J. Brobecker <brobecker@gnat.com>
+
+ * som.c (som_write_symbol_strings): Fix incorrect type of
+ current_offset to match the function definition. Fixes a build
+ failure on HPUX-11.00.
+
+2001-09-28 Richard Henderson <rth@redhat.com>
+
+ * elfxx-target.h [section_flags]: Add SEC_ARCH_BIT_0, SEC_SMALL_DATA,
+ SEC_MERGE, SEC_STRINGS.
+
+ * section.c (SEC_ARCH_BIT_0): New; replace unused SEC_BALIGN.
+ * bfd-in2.h: Rebuild.
+
+2001-09-28 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-x86-64.c (elf64_x86_64_reloc_type_lookup): Don't map bfd
+ reloc code using x86_64_reloc_map.
+
+ * elf32-hppa.c (elf32_hppa_check_relocs): Update comment since we
+ no longer allocate here. Localise some vars to blocks where they
+ are used.
+ (elf32_hppa_adjust_dynamic_symbol): Correct a comment. Delay
+ setting of vars until needed.
+ (allocate_dynrelocs): Don't create a .plt entry without a reloc
+ when symbol visibilty makes a function local.
+ (elf32_hppa_finish_dynamic_symbol): Move expressions out of
+ swap_reloca_out function calls.
+ (elf32_hppa_relocate_section): Likewies. Comment typo fix.
+ (elf32_hppa_finish_dynamic_sections): Migrate common code out of
+ switch statement.
+
+ * elf32-i386.c (elf_i386_check_relocs): Update comment since we
+ no longer allocate here. Localise some vars to blocks where they
+ are used. Remove separate switch stmt for creating .got sec.
+ (elf_i386_adjust_dynamic_symbol): Correct a comment. Remove
+ redundant casts and aborts. Delay setting of vars until needed.
+ (allocate_dynrelocs): Remove redundant casts and aborts.
+ (elf_i386_size_dynamic_sections): Move comment.
+ (elf_i386_finish_dynamic_symbol): Move expressions out of function
+ calls.
+ (elf_i386_relocate_section): Likewise. Comment typo fix.
+ (elf_i386_finish_dynamic_sections): Migrate common code out of
+ switch statement.
+ (elf_backend_* defines): Sort.
+
+ * elf32-i386.c (allocate_dynrelocs): Don't create a .plt entry
+ without a reloc when symbol visibilty makes a function local.
+
+2001-09-27 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * elf32-arm.h (elf32_arm_merge_private_bfd_data): Fix detection of
+ conflicting float flags.
+
+2001-09-26 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-i386 (elf_i386_copy_indirect_symbol): New function.
+ (elf_backend_copy_indirect_symbol): Define.
+ (struct elf_i386_link_hash_entry): Rename "root" to "elf".
+ (struct elf_i386_link_hash_table): Likewise.
+ (link_hash_newfunc): Get rid of unnecessary casts.
+ (elf_i386_link_hash_table_create): Likewise.
+ (elf_i386_check_relocs): Initialise local_got_refcounts to 0.
+ Don't test input section SEC_READONLY here to try to avoid copy
+ relocs, and keep dyn_relocs regardleas of ELF_LINK_NON_GOT_REF.
+ (elf_i386_adjust_dynamic_symbol): Check output section SEC_READONLY
+ here to properly test whether we need copy relocs. Do so for weak
+ syms too.
+
+ * elf32-hppa (elf32_hppa_copy_indirect_symbol): New function.
+ (elf_backend_copy_indirect_symbol): Define.
+ (struct elf32_hppa_link_hash_table): Rename "root" to "elf".
+ (stub_hash_newfunc): Get rid of unnecessary casts.
+ (hppa_link_hash_newfunc): Likewise.
+ (elf32_hppa_check_relocs): Initialise local_got_refcounts to 0.
+ Don't test input section SEC_READONLY here to try to avoid copy
+ relocs, and keep dyn_relocs regardleas of ELF_LINK_NON_GOT_REF.
+ (elf32_hppa_adjust_dynamic_symbol): Check output section SEC_READONLY
+ here to properly test whether we need copy relocs. Do so for weak
+ syms too.
+
+2001-09-26 Alan Modra <amodra@bigpond.net.au>
+
+ * bfd.c (_bfd_default_error_handlerl): Define using VPARAMS,
+ VA_OPEN, VA_FIXEDARG, VA_CLOSE.
+ (bfd_archive_filename): Cast bfd_malloc arg to the correct size.
+
+2001-09-25 Jakub Jelinek <jakub@redhat.com>
+
+ * elf64-sparc.c (sparc64_elf_build_plt): Fix .plt[32768+] slot
+ computation.
+
+2001-09-25 H.J. Lu <hjl@gnu.org>
+
+ * bfd-in2.h: Regenerated.
+
+2001-09-25 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-i386.c: Add comment re linker function names and ordering.
+ (elf_i386_link_hash_newfunc): Rename to link_hash_newfunc.
+ (elf_i386_grok_prstatus): Move before linker functions.
+ (elf_i386_grok_psinfo): Likewise.
+ (elf_i386_fake_sections): Move so that functions are ordered.
+ (elf_i386_reloc_type_class): Likewise. Comment function purpose.
+
+2001-09-25 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-hppa.c: Rename occurrences of "hplink" to "htab"
+ throughout file.
+
+ * elf32-hppa.c: (LONG_BRANCH_PIC_IN_SHLIB): Delete. Remove all
+ code handling this option.
+ (LONG_BRANCH_VIA_PLT): Likewise.
+ (RELATIVE_DYNRELOCS): Define as zero.
+ (struct elf32_hppa_dyn_reloc_entry): Add "sec", and
+ "pc_count" fields. Remove "section" field.
+ (elf32_hppa_link_hash_entry): Rename reloc_entries to dyn_relocs.
+ (elf32_hppa_check_relocs): Don't allocate space for dynamic
+ relocs here. Instead, record all needed dynamic relocs via
+ dyn_relocs and local_dynrel. Cache pointer to "sreloc" section
+ in elf_section_data.
+ (elf32_hppa_gc_sweep_hook): Sweep dyn_relocs and local_dynrel.
+ (allocate_plt_and_got_and_discard_relocs): Rename to
+ allocate_dynrelocs. Allocate rather than discarding dyn relocs.
+ (readonly_dynrelocs): New function.
+ (elf32_hppa_size_dynamic_sections): Mark output_bfd unused.
+ Call readonly_dynrelocs to determine need for DT_TEXTREL.
+ Rename "i" to "ibfd". Allocate space for local dyn relocs.
+ (elf32_hppa_relocate_section): Make use of cached sreloc.
+ (elf32_hppa_reloc_type_class): New function.
+ (elf_backend_reloc_type_class): Define.
+
+2001-09-25 Alan Modra <amodra@bigpond.net.au>
+
+ * elf-bfd.h (struct bfd_elf_section_data): Add "local_dynrel"
+ and "sreloc" fields.
+ * elf32-i386.c (struct elf_i386_dyn_relocs): Add "sec", and
+ "pc_count" fields. Remove "section" field.
+ (elf_i386_check_relocs): Don't set DF_TEXTREL here. Don't
+ allocate space for dynamic relocs here. Instead, record all
+ needed dynamic relocs via dyn_relocs and local_dynrel. Cache
+ pointer to "sreloc" section in elf_section_data.
+ (elf_i386_gc_sweep_hook): Sweep dyn_relocs and local_dynrel.
+ (allocate_plt_and_got_and_discard_relocs): Rename to
+ allocate_dynrelocs. Allocate rather than discarding dyn relocs.
+ (readonly_dynrelocs): New function.
+ (elf_i386_size_dynamic_sections): Call readonly_dynrelocs.
+ Rename "i" to "ibfd". Allocate space for local dyn relocs.
+ (elf_i386_relocate_section): Make use of cached sreloc.
+
+2001-09-24 Alan Modra <amodra@bigpond.net.au>
+
+ * elf-bfd.h (elf_backend_reloc_type_class): Pass in the entire
+ reloc rather than just the type.
+ (_bfd_elf_reloc_type_class): Likewise.
+ * elf.c (_bfd_elf_reloc_type_class): Likewise.
+ * elf32-arm.h (elf32_arm_reloc_type_class): Likewise.
+ * elf32-cris.c (elf_cris_reloc_type_class): Likewise.
+ * elf32-i386.c (elf_i386_reloc_type_class): Likewise.
+ * elf32-m68k.c (elf32_m68k_reloc_type_class): Likewise.
+ * elf32-ppc.c (ppc_elf_reloc_type_class): Likewise.
+ * elf32-s390.c (elf_s390_reloc_type_class): Likewise.
+ * elf32-sh.c (sh_elf_reloc_type_class): Likewise.
+ * elf32-sparc.c (elf32_sparc_reloc_type_class): Likewise.
+ * elf64-alpha.c (elf64_alpha_reloc_type_class): Likewise.
+ * elf64-s390.c (elf_s390_reloc_type_class): Likewise.
+ * elf64-sparc.c (sparc64_elf_reloc_type_class): Likewise.
+ * elf64-x86-64.c (elf64_x86_64_reloc_type_class): Likewise.
+ * elfxx-ia64.c (elfNN_ia64_reloc_type_class): Likewise.
+ * elflink.h: Formatting fixes.
+ (elf_link_sort_relocs): Make "count" and "size" bfd_size_type.
+ Call bfd_zmalloc rather than calloc. Remove unnecessary cast of
+ o->contents to PTR. Update call to elf_backend_reloc_type_class.
+
+2001-09-22 John Reiser <jreiser@BitWagon.com>
+
+ * elfcode.h (elf_object_p): Allow for no section header at all in
+ non-ET_REL files. Honor 0 for e_shnum, e_shstrndx, e_shoff.
+
+2001-09-21 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * elfxx-ia64.c: Fix compile time warning messages.
+ * coff-mcore.c: Fix compile time warning messages.
+ * coff-ppc.c: Fix compile time warning messages.
+ * coffcode.h: Fix compile time warning messages.
+ * elf32-mips.c: Fix compile time warning messages.
+ * elf64-alpha.c: Fix compile time warning messages.
+ * libbfd.c: Fix compile time warning messages.
+ * bfd-in2.h: Regenerate.
+
+2001-09-21 Alan Modra <amodra@bigpond.net.au>
+
+ * Makefile.am: Run "make dep-am".
+ * Makefile.in: Regenerate.
+
+ * aoutx.h: Formatting fixes.
+ * merge.c (_bfd_merged_section_offset): Break line at 80 chars.
+
+ * linker.c: Replace bfd_get_filename with bfd_archive_filename
+ in error message.
+
+2001-09-21 Alan Modra <amodra@bigpond.net.au>
+
+ * bfd.c (bfd_archive_filename): New function.
+ * bfd-in2.h: Regenerate.
+ * aout-adobe.c: Replace bfd_get_filename with bfd_archive_filename
+ in error messages where the bfd is an input bfd.
+ * aout-cris.c: Likewise.
+ * coff-arm.c: Likewise.
+ * coff-mcore.c: Likewise.
+ * coff-ppc.c: Likewise.
+ * coff-rs6000.c: Likewise.
+ * coff-sh.c: Likewise.
+ * coff-tic54x.c: Likewise.
+ * coff-tic80.c: Likewise.
+ * coff64-rs6000.c: Likewise.
+ * coffcode.h: Likewise.
+ * coffgen.c: Likewise.
+ * cofflink.c: Likewise.
+ * ecofflink.c: Likewise.
+ * elf-hppa.h: Likewise.
+ * elf.c: Likewise.
+ * elf32-arm.h: Likewise.
+ * elf32-cris.c: Likewise.
+ * elf32-gen.c: Likewise.
+ * elf32-hppa.c: Likewise.
+ * elf32-i370.c: Likewise.
+ * elf32-i386.c: Likewise.
+ * elf32-m32r.c: Likewise.
+ * elf32-mcore.c: Likewise.
+ * elf32-mips.c: Likewise.
+ * elf32-ppc.c: Likewise.
+ * elf32-s390.c: Likewise.
+ * elf32-sh.c: Likewise.
+ * elf32-sparc.c: Likewise.
+ * elf32-v850.c: Likewise.
+ * elf64-alpha.c: Likewise.
+ * elf64-gen.c: Likewise.
+ * elf64-ppc.c: Likewise.
+ * elf64-s390.c: Likewise.
+ * elf64-sparc.c: Likewise.
+ * elf64-x86-64.c: Likewise.
+ * elflink.h: Likewise.
+ * elfxx-ia64.c: Likewise.
+ * ieee.c: Likewise.
+ * ihex.c: Likewise.
+ * libbfd.c: Likewise.
+ * pdp11.c: Likewise.
+ * pe-mips.c: Likewise.
+ * peicode.h: Likewise.
+ * srec.c: Likewise.
+ * xcofflink.c: Likewise.
+
+ * elf32-arm.h: Make _bfd_error_handler calls K&R compatible.
+
+ * elflink.c (_bfd_elf_create_linker_section): Better grammar for
+ error message.
+
+ * coff-mcore.c (coff_mcore_relocate_section): Internalionalise
+ error message.
+
+ * elf64-sparc.c (sparc64_elf_add_symbol_hook): Constify stt_types.
+ Consolidate error messages, and split long messages to two lines.
+
+2001-09-20 John Reiser <jreiser@BitWagon.com>
+
+ * elf32-i386.c (elf_i386_relocate_section): Coordinate info->symbolic
+ and info->allow_shlib_undefined.
+ * elf32-cris.c: Likewise.
+ * elf32-hppa.c: Likewise.
+ * elf32-m68k.c: Likewise.
+ * elf32-mips.c: Likewise.
+ * elf32-ppc.c: Likewise.
+ * elf32-s390.c: Likewise.
+ * elf32-sh.c: Likewise.
+ * elf32-sparc.c: Likewise.
+ * elf64-alpha.c: Likewise.
+ * elf64-hppa.c: Likewise.
+ * elf64-ppc.c: Likewise.
+ * elf64-s390.c: Likewise.
+ * elf64-sparc.c: Likewise.
+ * elf64-x86-64.c: Likewise.
+ * elfxx-ia64.c: Likewise.
+
+2001-09-18 Bruno Haible <haible@clisp.cons.org>
+
+ * aoutx.h: Include "safe-ctype.h" instead of <ctype.h>.
+ (aout_link_write_symbols): Use ISDIGIT instead of isdigit.
+ * archive.c: Include "safe-ctype.h" instead of <ctype.h>.
+ (_bfd_generic_read_ar_hdr_mag): Use ISDIGIT instead of isdigit.
+ * archures.c: Include "safe-ctype.h" instead of <ctype.h>.
+ (bfd_default_scan): Use ISDIGIT instead of isdigit.
+ * bfd.c: Include "safe-ctype.h" instead of <ctype.h>.
+ (bfd_scan_vma): Use ISXDIGIT/ISDIGIT/ISLOWER instead of
+ isxdigit/isdigit/islower.
+ * binary.c: Include "safe-ctype.h" instead of <ctype.h>.
+ (mangle_name): Use ISALNUM instead of isalnum.
+ * cpu-v850.c: Include "safe-ctype.h" instead of <ctype.h>.
+ (scan): Use ISDIGIT instead of isdigit.
+ * hosts/alphavms.h: Don't include <ctype.h>.
+ * ieee.c: Include "safe-ctype.h" instead of <ctype.h>.
+ (ieee_object_p): Use TOUPPER instead of toupper.
+ * ihex.c: Include "safe-ctype.h" instead of <ctype.h>.
+ (ihex_bad_byte): Use ISPRINT instead of isprint.
+ * merge.c: Don't include <ctype.h>.
+ * oasys.c: Include "safe-ctype.h" instead of <ctype.h>.
+ (oasys_write_sections): Use ISDIGIT instead of isdigit.
+ * pdp11.c: Include "safe-ctype.h" instead of <ctype.h>.
+ (aout_link_write_symbols): Use ISDIGIT instead of isdigit.
+ * ppcboot.c: Include "safe-ctype.h" instead of <ctype.h>.
+ (mangle_name): Use ISALNUM instead of isalnum.
+ * som.c: Include "safe-ctype.h" instead of <ctype.h>.
+ (som_set_reloc_info): Use ISUPPER/ISLOWER/ISDIGIT instead of
+ isupper/islower/isdigit.
+ (som_decode_symclass): Use TOUPPER instead of toupper.
+ * srec.c: Include "safe-ctype.h" instead of <ctype.h>.
+ (srec_bad_byte): Use ISPRINT instead of isprint.
+ (srec_scan): Use ISSPACE instead of isspace.
+ * stabs.c: Include "safe-ctype.h" instead of <ctype.h>.
+ (_bfd_link_section_stabs): Use ISDIGIT instead of isdigit.
+ * syms.c: Include "safe-ctype.h"
+ (islower, toupper): Remove macro definitions.
+ (bfd_decode_symclass): Use TOUPPER instead of toupper.
+ * vms-gsd.c: Don't include <ctype.h>.
+ * vms-hdr.c: Include "safe-ctype.h" instead of <ctype.h>.
+ (_bfd_vms_write_hdr): Use ISLOWER/TOUPPER instead of
+ islower/toupper.
+ * vms-tir.c: Don't include <ctype.h>.
+
+2001-09-18 Alan Modra <amodra@bigpond.net.au>
+
+ * libbfd.c (bfd_bread): New function replacing bfd_read without
+ redundant params. Allow reads up to (size_t) -2 in length.
+ (bfd_bwrite): Similarly for bfd_write.
+ (real_read): Return a size_t.
+ (bfd_read): Call bfd_bread.
+ (bfd_write): Call bfd_bwrite.
+ (warn_deprecated): New function to annoy everybody.
+ (bfd_get_file_window): Don't call bfd_set_error unnecessarily.
+ * bfd-in.h (bfd_bread, bfd_bwrite, warn_deprecated): Declare.
+ (bfd_read, bfd_write): Define as macro.
+ * aix386-core.c: Replace calls to bfd_read with bfd_bread, and
+ likewise for bfd_write. Ensure function args are correct size by
+ using casts or local vars. In some cases, remove unnecessary
+ casts. Formatting fixes, in some cases removing a large expression
+ from function args by using a local var. Replace CONST with const.
+ Modify variable types to avoid warings. Use casts to avoid
+ warnings when using negative numbers in unsigned expressions.
+ * aout-adobe.c: Likewise.
+ * aout-arm.c: Likewise.
+ * aout-cris.c: Likewise.
+ * aout-encap.c: Likewise.
+ * aout-ns32k.c: Likewise.
+ * aout-target.h: Likewise.
+ * aout-tic30.c: Likewise.
+ * aoutf1.h: Likewise.
+ * aoutx.h: Likewise.
+ * archive.c: Likewise.
+ * archures.c: Likewise.
+ * bfd-in.h: Likewise.
+ * bfd.c: Likewise.
+ * binary.c: Likewise.
+ * bout.c: Likewise.
+ * cache.c: Likewise.
+ * cisco-core.c: Likewise.
+ * coff-a29k.c: Likewise.
+ * coff-alpha.c: Likewise.
+ * coff-arm.c: Likewise.
+ * coff-h8300.c: Likewise.
+ * coff-h8500.c: Likewise.
+ * coff-i386.c: Likewise.
+ * coff-i860.c: Likewise.
+ * coff-i960.c: Likewise.
+ * coff-ia64.c: Likewise.
+ * coff-m68k.c: Likewise.
+ * coff-m88k.c: Likewise.
+ * coff-mcore.c: Likewise.
+ * coff-mips.c: Likewise.
+ * coff-ppc.c: Likewise.
+ * coff-rs6000.c: Likewise.
+ * coff-sh.c: Likewise.
+ * coff-sparc.c: Likewise.
+ * coff-stgo32.c: Likewise.
+ * coff-tic30.c: Likewise.
+ * coff-tic54x.c: Likewise.
+ * coff-tic80.c: Likewise.
+ * coff-w65.c: Likewise.
+ * coff-z8k.c: Likewise.
+ * coff64-rs6000.c: Likewise.
+ * coffcode.h: Likewise.
+ * coffgen.c: Likewise.
+ * cofflink.c: Likewise.
+ * coffswap.h: Likewise.
+ * corefile.c: Likewise.
+ * cpu-arc.c: Likewise.
+ * cpu-h8300.c: Likewise.
+ * cpu-h8500.c: Likewise.
+ * cpu-i960.c: Likewise.
+ * cpu-ia64-opc.c: Likewise.
+ * cpu-ns32k.c: Likewise.
+ * cpu-pdp11.c: Likewise.
+ * cpu-pj.c: Likewise.
+ * cpu-sh.c: Likewise.
+ * cpu-w65.c: Likewise.
+ * cpu-z8k.c: Likewise.
+ * dwarf1.c: Likewise.
+ * dwarf2.c: Likewise.
+ * ecoff.c: Likewise.
+ * ecofflink.c: Likewise.
+ * ecoffswap.h: Likewise.
+ * elf-bfd.h: Likewise.
+ * elf-hppa.h: Likewise.
+ * elf-m10200.c: Likewise.
+ * elf-m10300.c: Likewise.
+ * elf.c: Likewise.
+ * elf32-arc.c: Likewise.
+ * elf32-arm.h: Likewise.
+ * elf32-avr.c: Likewise.
+ * elf32-cris.c: Likewise.
+ * elf32-fr30.c: Likewise.
+ * elf32-gen.c: Likewise.
+ * elf32-h8300.c: Likewise.
+ * elf32-hppa.c: Likewise.
+ * elf32-i370.c: Likewise.
+ * elf32-i386.c: Likewise.
+ * elf32-i860.c: Likewise.
+ * elf32-m32r.c: Likewise.
+ * elf32-m68k.c: Likewise.
+ * elf32-mcore.c: Likewise.
+ * elf32-mips.c: Likewise.
+ * elf32-openrisc.c: Likewise.
+ * elf32-pj.c: Likewise.
+ * elf32-ppc.c: Likewise.
+ * elf32-s390.c: Likewise.
+ * elf32-sh-lin.c: Likewise.
+ * elf32-sh.c: Likewise.
+ * elf32-sparc.c: Likewise.
+ * elf32-v850.c: Likewise.
+ * elf64-alpha.c: Likewise.
+ * elf64-hppa.c: Likewise.
+ * elf64-mips.c: Likewise.
+ * elf64-ppc.c: Likewise.
+ * elf64-s390.c: Likewise.
+ * elf64-sparc.c: Likewise.
+ * elf64-x86-64.c: Likewise.
+ * elfarm-nabi.c: Likewise.
+ * elfcode.h: Likewise.
+ * elfcore.h: Likewise.
+ * elflink.c: Likewise.
+ * elflink.h: Likewise.
+ * elfxx-ia64.c: Likewise.
+ * elfxx-target.h: Likewise.
+ * format.c: Likewise.
+ * hash.c: Likewise.
+ * hp300hpux.c: Likewise.
+ * hppabsd-core.c: Likewise.
+ * hpux-core.c: Likewise.
+ * i386aout.c: Likewise.
+ * i386dynix.c: Likewise.
+ * i386linux.c: Likewise.
+ * i386lynx.c: Likewise.
+ * i386mach3.c: Likewise.
+ * i386msdos.c: Likewise.
+ * i386os9k.c: Likewise.
+ * ieee.c: Likewise.
+ * ihex.c: Likewise.
+ * irix-core.c: Likewise.
+ * libaout.h: Likewise.
+ * libbfd-in.h: Likewise.
+ * libbfd.c: Likewise.
+ * libcoff-in.h: Likewise.
+ * libecoff.h: Likewise.
+ * libieee.h: Likewise.
+ * libnlm.h: Likewise.
+ * libpei.h: Likewise.
+ * libxcoff.h: Likewise.
+ * linker.c: Likewise.
+ * lynx-core.c: Likewise.
+ * m68klinux.c: Likewise.
+ * merge.c: Likewise.
+ * mipsbsd.c: Likewise.
+ * netbsd-core.c: Likewise.
+ * nlm.c: Likewise.
+ * nlm32-alpha.c: Likewise.
+ * nlm32-i386.c: Likewise.
+ * nlm32-ppc.c: Likewise.
+ * nlm32-sparc.c: Likewise.
+ * nlmcode.h: Likewise.
+ * nlmswap.h: Likewise.
+ * ns32k.h: Likewise.
+ * oasys.c: Likewise.
+ * opncls.c: Likewise.
+ * osf-core.c: Likewise.
+ * pc532-mach.c: Likewise.
+ * pdp11.c: Likewise.
+ * pe-mips.c: Likewise.
+ * peXXigen.c: Likewise.
+ * peicode.h: Likewise.
+ * ppcboot.c: Likewise.
+ * ptrace-core.c: Likewise.
+ * reloc.c: Likewise.
+ * reloc16.c: Likewise.
+ * riscix.c: Likewise.
+ * rs6000-core.c: Likewise.
+ * sco5-core.c: Likewise.
+ * section.c: Likewise.
+ * som.c: Likewise.
+ * sparclinux.c: Likewise.
+ * sparclynx.c: Likewise.
+ * srec.c: Likewise.
+ * stabs.c: Likewise.
+ * sunos.c: Likewise.
+ * syms.c: Likewise.
+ * targets.c: Likewise.
+ * tekhex.c: Likewise.
+ * trad-core.c: Likewise.
+ * versados.c: Likewise.
+ * vms-gsd.c: Likewise.
+ * vms-hdr.c: Likewise.
+ * vms-misc.c: Likewise.
+ * vms-tir.c: Likewise.
+ * vms.c: Likewise.
+ * vms.h: Likewise.
+ * xcofflink.c: Likewise.
+ * bfd-in2.h: Regenerate.
+ * libbfd.h: Regenerate.
+ * libcoff.h: Regenerate.
+
+ * bfd.c (struct _bfd): Make "where" and "origin" unsigned.
+ * bfd-in.h (file_ptr): Change from a long int to a bfd_signed_vma.
+ (ufile_ptr): Define.
+ (bfd_tell): Return a ufile_ptr.
+ * libbfd.c (bfd_tell): Likewise.
+ (bfd_seek): Use bfd_size_type locals. Don't call bfd_set_error
+ unnecessarily.
+ * aix386-core.c: Test != 0 for bfd_seek errors rather than < 0.
+ * aoutf1.h: Likewise.
+ * som.c: Likewise.
+ * cache.c (bfd_cache_lookup_worker): Guard against abfd->where
+ larger than unsigned long can represent.
+
+ * libbfd.c (bfd_malloc): Take a bfd_size_type arg. Error if
+ size overflows size_t.
+ (bfd_realloc): Likewise.
+ (bfd_zmalloc): Likewise.
+ * opncls.c (bfd_alloc): Likewise.
+ (bfd_zalloc): Likewise.
+ * libbfd-in.h (bfd_malloc, bfd_realloc, bfd_zmalloc): Update.
+ (bfd_alloc, bfd_zalloc): Update.
+
+ * libbfd.c (bfd_get_8): Mask with 0xff in case char is more than
+ 8 bits.
+ (bfd_get_signed_8): Likewise.
+ (H_PUT_64, H_PUT_32, H_PUT_16, H_PUT_8,
+ H_PUT_S64, H_PUT_S32, H_PUT_S16, H_PUT_S8,
+ H_GET_64, H_GET_32, H_GET_16, H_GET_8,
+ H_GET_S64, H_GET_S32, H_GET_S16, H_GET_S8): Define and use.
+ * libaout.h: Likewise define and use here.
+ * aout-adobe.c: Use H_GET_* and H_PUT_* macros.
+ * aout-arm.c: Likewise.
+ * aout-encap.c: Likewise.
+ * aout-ns32k.c: Likewise.
+ * aout-tic30.c: Likewise.
+ * aoutf1.h: Likewise.
+ * aoutx.h: Likewise.
+ * bout.c: Likewise.
+ * coff-alpha.c: Likewise.
+ * coff-h8300.c: Likewise.
+ * coff-h8500.c: Likewise.
+ * coff-i960.c: Likewise.
+ * coff-ia64.c: Likewise.
+ * coff-m88k.c: Likewise.
+ * coff-mips.c: Likewise.
+ * coff-ppc.c: Likewise.
+ * coff-rs6000.c: Likewise.
+ * coff-sh.c: Likewise.
+ * coff-sparc.c: Likewise.
+ * coff-stgo32.c: Likewise.
+ * coff-tic30.c: Likewise.
+ * coff-tic80.c: Likewise.
+ * coff-w65.c: Likewise.
+ * coff-z8k.c: Likewise.
+ * coff64-rs6000.c: Likewise.
+ * coffgen.c: Likewise.
+ * cofflink.c: Likewise.
+ * coffswap.h: Likewise.
+ * ecoff.c: Likewise.
+ * ecoffswap.h: Likewise.
+ * elf.c: Likewise.
+ * elf32-mips.c: Likewise.
+ * elf64-mips.c: Likewise.
+ * hp300hpux.c: Likewise.
+ * i386dynix.c: Likewise.
+ * i386lynx.c: Likewise.
+ * i386msdos.c: Likewise.
+ * i386os9k.c: Likewise.
+ * libpei.h: Likewise.
+ * nlm32-alpha.c: Likewise.
+ * nlm32-i386.c: Likewise.
+ * nlm32-ppc.c: Likewise.
+ * nlmcode.h: Likewise.
+ * nlmswap.h: Likewise.
+ * oasys.c: Likewise.
+ * pdp11.c: Likewise.
+ * pe-mips.c: Likewise.
+ * peXXigen.c: Likewise.
+ * peicode.h: Likewise.
+ * riscix.c: Likewise.
+ * sunos.c: Likewise.
+ * xcofflink.c: Likewise.
+ * elfcode.h: (put_word, get_word, put_signed_word, get_signed_word):
+ Rename to H_PUT_WORD, H_GET_WORD, H_PUT_SIGNED_WORD, H_GET_SIGNED_WORD.
+ * coff-rs6000.c (PUTWORD, PUTHALF, PUTBYTE): Don't define. Use
+ equivalent H_PUT_* macro instead.
+ (GETWORD, GETHALF, GETBYTE): Similarly.
+ * coff64-rs6000.c (PUTWORD, PUTHALF, PUTBYTE): Likewise.
+ (GETWORD, GETHALF, GETBYTE): Likewise.
+ * coffswap.h (PUTWORD, PUTHALF, PUTBYTE): Likewise.
+
+ * bfd-in.h (struct orl): Change "pos" to a union.
+ * archive.c (_bfd_compute_and_write_armap): Use it instead of casts.
+ (bsd_write_armap): Here too.
+ (coff_write_armap): And here.
+ * coff-rs6000.c (xcoff_write_armap_old): And here.
+ (xcoff_write_one_armap_big): And here.
+ (xcoff_write_armap_big): And here.
+ * ecoff.c (_bfd_ecoff_write_armap): And here.
+ * elf64-mips.c (mips_elf64_write_armap): And here.
+
+ * aoutf1.h (sunos_set_arch_mach): Make "mach" param an enum.
+ * elf-m10300.c (elf_mn10300_mach): Return an unsigned long.
+ * elf32-h8300.c (elf32_h8_mach): Likewise.
+ * elf32-mips.c (elf_mips_mach): Likewise.
+ * sparclynx.c (NAME(lynx,set_arch_mach)): Likewise.
+
+ * aix386-core.c (aix386_core_file_p): Remove redundant bfd_release
+ calls.
+ (aix386_core_vec): Typo fix.
+
+ * aout-arm.c: Include libaout.h and aout/aout64.h after N_TXTADDR
+ etc. to avoid redefined macro warning.
+ (MY(put_reloc)): Use bfd_vma for "value" rather than long.
+ (MY(fix_pcrel_26)): Likewise.
+ * aout-ns32k.c (MY(put_reloc)): Likewise.
+ * aout-cris.c (MY(swap_ext_reloc_out)): Likewise for r_addend.
+ * aoutx.h (NAME(aout,swap_ext_reloc_out)): Likewise.
+ * coff-arm.c (coff_arm_relocate_section): Likewise for my_offset.
+
+ * aout-encap.c: Include "file", not <file> for binutils headers.
+ (encap_object_p): Half baked attempt to fix compile errors in
+ code dealing with "magic".
+
+ * aout-ns32k.c: Include "file", not <file> for binutils headers.
+ (_bfd_ns32k_relocate_contents): get_data and put_data manipulate
+ bfd_vma's rather than longs.
+ * cpu-ns32k.c (ns32k_sign_extend): Delete.
+ (_bfd_ns32k_get_displacement): Return a bfd_vma, don't pass in offset.
+ (_bfd_ns32k_get_immediate): Likewise. Add code for 8 byte values,
+ remove case 3.
+ (_bfd_ns32k_put_displacement): Accept a bfd_vma, don't pass in offset.
+ Use unsigned comparisons.
+ (bfd_ns32k_put_immediate): Likewise, and add code for 8 byte values.
+ (do_ns32k_reloc): get_data and put_data operate on bfd_vma's.
+ (_bfd_do_ns32k_reloc_contents): Likewise.
+ * ns32k.h (_bfd_ns32k_get_displacement): Update prototype.
+ (_bfd_ns32k_get_immediate): Likewise.
+ (_bfd_ns32k_put_displacement): Likewise.
+ (_bfd_ns32k_put_immediate): Likewise.
+ (bfd_reloc_status_type): Likewise.
+
+ * aoutx.h (NAME(aout,find_nearest_line)): Rename 'p' to 'colon'
+ to avoid shadowing.
+ * pdp11.c (NAME(aout,find_nearest_line)): Likewise.
+ * coff-h8300.c (h8300_reloc16_extra_cases): Remove shadowing "value".
+ * coff-ppc.c (enum ref_category): Rename "data" to "tocdata" to
+ avoid shadowing.
+ (record_toc): Use a bfd_signed_vma for our_toc_offset.
+ * coffcode.h (coff_write_relocs): Rename "i" to avoid shadowing.
+ * elf.c (bfd_elf_get_bfd_needed_list): Rename "link" var to avoid
+ shadow warning.
+ (_bfd_elfcore_strndup): Likewise for "dup".
+ * elf32-cris.c (cris_elf_relocate_section): "symname" instead of
+ "name" to avoid shadowing.
+ * elf32-hppa.c (elf32_hppa_relocate_section): Remove duplicate
+ definition of "off".
+ * elf32-i386.c (elf_i386_relocate_section): Likewise.
+ * elf32-mips.c (_bfd_mips_elf_modify_segment_map): Remove duplicate
+ definition of "s".
+ (_bfd_mips_elf_final_link): Rename "i" to "j". Remove duplicate
+ "secpp".
+ * elf64-x86-64.c (elf64_x86_64_relocate_section): Rename inner "indx"
+ to avoid shadowing.
+ * elflink.h (elf_link_add_object_symbols): Rename "link" to "shlink"
+ to avoid shadowing.
+ (elf_link_input_bfd): Likewise.
+ (elf_bfd_final_link): Remove duplicate innermost "off" var.
+ * oasys.c (oasys_write_data): Rename innermost "p" to "sym".
+ * reloc16.c (bfd_coff_reloc16_relax_section): Rename "i" param to
+ "input_section".
+ * som.c (som_prep_for_fixups): Rename inner "i" to "j".
+ * sunos.c (sunos_add_dynamic_symbols): Localise "s" var.
+ (sunos_write_dynamic_symbol): Remove unused vars.
+ * syms.c (_bfd_stab_section_find_nearest_line): Remove duplicate
+ innermost "directory_name" and "file_name" vars.
+ * tekhex.c (first_phase): Rename local var "type" to "stype".
+ (tekhex_write_object_contents): Rename innermost "s" to "sym".
+ * vms-gsd.c (vms_secflag_by_name): Change "size" param to "hassize",
+ doing comparison at caller.
+ (vms_esecflag_by_name): Likewise.
+ * vms-tir.c (etir_sto): Rename innermost "psect" to "psect1".
+ * xcofflink.c (xcoff_link_input_bfd): Delete duplicate innermost "o".
+ (xcoff_write_global_symbol): Rename "p" param to "inf".
+
+ * cisco-core.c: Add missing prototypes.
+ (cisco_core_file_failing_command): Add ATTRIBUTE_UNUSED.
+ (cisco_core_file_failing_signal): Likewise.
+ (cisco_core_file_matches_executable_p): Likewise.
+ * hpux-core.c (hpux_core_core_file_failing_signal): Likewise.
+ * netbsd-core.c (netbsd_core_file_matches_executable_p): Likewise.
+ * osf-core.c (osf_core_core_file_matches_executable_p): Likewise.
+ * sco5-core.c (sco5_core_file_matches_executable_p): Likewise.
+
+ * coff-arm.c (coff_arm_link_hash_table): Use bfd_size_type for
+ thumb_glue_size and arm_glue_size.
+ * elf32-arm.h (elf32_arm_link_hash_table): Likewise here.
+
+ * coff64-rs6000.c: Group prototypes together.
+
+ * coffcode.h (coff_set_arch_mach): Add ATTRIBUTE_UNUSED.
+ (buy_and_read): Remove "seek" param. Change "size" to bfd_size_type.
+
+ * cpu-arc.c: Add missing prototypes.
+ * cpu-h8500.c: Likewise.
+ * cpu-i960.c: Likewise.
+ * cpu-pj.c: Likewise.
+ * cpu-sh.c: Likewise.
+ * cpu-w65.c: Likewise.
+ * cpu-z8k.c: Likewise.
+ * elf32-fr30.c: Likewise.
+ * elf32-h8300.c: Likewise.
+ * elf32-i370.c: Likewise.
+ * hpux-core.c: Likewise.
+ * versados.c: Likewise.
+
+ * cpu-h8300.c (bfd_default_scan_num_mach): Don't declare.
+ * cpu-h8500.c: Likewise.
+ * cpu-i960.c: Likewise.
+ * cpu-z8k.c: Likewise.
+
+ * cpu-ia64-opc.c: Correct comment.
+
+ * dwarf2.c (_bfd_dwarf2_find_nearest_line): Remove unused var.
+
+ * elf-bfd.h (elf_size_info): Change count param of write_out_phdrs
+ to unsigned.
+ (bfd_elf32_write_out_phdrs): Likewise.
+ (bfd_elf64_write_out_phdrs): Likewise.
+ (elf_linker_section_pointers): Change addend to bfd_vma.
+ (_bfd_elf_find_pointer_linker_section): Likewise.
+ (_bfd_elfcore_make_pseudosection): Change size param to size_t and
+ filepos to unsigned file_ptr.
+ (_bfd_elfcore_strndup): Change max param to size_t.
+ * elf.c (_bfd_elfcore_make_pseudosection): As above.
+ (_bfd_elfcore_strndup): Likewise.
+ (_bfd_elf_find_pointer_linker_section): Likewise.
+
+ * elf-hppa.h (elf_hppa_relocate_insn): Return an int, and change
+ insn and sym_value to ints.
+
+ * elf.c (elf_read): Make "offset" param a file_ptr, "size" a
+ bfd_size_type.
+ (elfcore_read_notes): Likewise.
+
+ * elf32-arm.h (elf32_arm_final_link_relocate): Change sym_flags
+ param from unsigned char to int.
+ (elf32_arm_relocate_section): If USE_REL, cast "rel" appropriately
+ for info_to_howto call.
+ (add_dynamic_entry): Define macro.
+ (elf32_arm_size_dynamic_sections): Use add_dynamic_entry.
+
+ * elf32-cris.c (add_dynamic_entry): Define macro.
+ (elf_cris_size_dynamic_sections): Use add_dynamic_entry.
+
+ * elf32-h8300.c (elf32_h8_final_write_processing): Make static.
+ (elf32_h8_object_p): Likewise.
+ (elf32_h8_merge_private_bfd_data): Likewise.
+ (elf32_h8_relax_section): Cast gap to int so signed comparisons work.
+
+ * elf32-hppa.c (add_dynamic_entry): Define macro.
+ (elf32_hppa_size_dynamic_sections): Use it.
+ * elf32-i370.c (add_dynamic_entry): Define macro.
+ (i370_elf_size_dynamic_sections): Use it.
+ (i370_noop): Make static.
+ * elf32-i386.c (add_dynamic_entry): Define macro.
+ (elf_i386_size_dynamic_sections): Use it.
+ * elf32-m68k.c (add_dynamic_entry): Define macro.
+ (elf_m68k_size_dynamic_sections): Use it.
+ * elf32-ppc.c (add_dynamic_entry): Define macro.
+ (ppc_elf_size_dynamic_sections): Use it.
+ * elf32-s390.c (add_dynamic_entry): Define macro.
+ (elf_s390_size_dynamic_sections): Use it.
+ * elf64-alpha.c (add_dynamic_entry): Define macro.
+ (elf64_alpha_size_dynamic_sections): Use it.
+ * elf64-hppa.c (add_dynamic_entry): Define macro.
+ (elf64_hppa_size_dynamic_sections): Use it.
+ * elf64-ppc.c (add_dynamic_entry): Define macro.
+ (ppc64_elf_size_dynamic_sections): Use it.
+ * elf64-s390.c (add_dynamic_entry): Define macro.
+ (elf_s390_size_dynamic_sections): Use it.
+ * elf64-sparc.c (add_dynamic_entry): Define macro.
+ (sparc64_elf_size_dynamic_sections): Use it.
+ * elf64-x86-64.c (add_dynamic_entry): Define macro.
+ (elf64_x86_64_size_dynamic_sections): Use it.
+ * elfxx-ia64.c (add_dynamic_entry): Define macro.
+ (elfNN_ia64_size_dynamic_sections): Use it.
+
+ * elf32-v850.c (SEXT24): Modify to avoid signed/unsigned warning.
+ (v850_elf_perform_relocation): Make "r_type" param unsigned.
+
+ * elf64-mips.c (mips_elf64_slurp_one_reloc_table): Just return
+ false if the first malloc fails rather than going via error_return.
+
+ * elf64-sparc.c (sparc64_elf_plt_entry_offset): Use a bfd_vma for
+ "index" param.
+ (sparc64_elf_plt_ptr_offset): Likewise, and for "max" param too.
+
+ * elflink.h (elf_link_input_bfd): s/ingored/ignored/ in error message.
+
+ * elfxx-ia64.c (global_sym_index): Return a long.
+
+ * ieee.c (get_symbol): Use int rather than char param.
+ (ieee_slurp_sections): Move "section" var to inner blocks.
+ (copy_expression): Don't init "value" to zero or worry about
+ clearing to zero after using.
+ (ieee_write_debug_part): Rename "output_buffer" to "obuff" to avoid
+ shadowing.
+
+ * ihex.c (ihex_write_record): Make "count" var a size_t, "addr" an
+ unsigned int.
+
+ * libbfd-in.h (BFD_ALIGN): Add cast to avoid signed/unsigned warning.
+ (bfd_write_bigendian_4byte_int): Pass an unsigned int value param.
+
+ * mipsbsd.c (mips_fix_jmp_addr): Add "error_message" param.
+
+ * pc532-mach.c (MYNSX): Delete.
+ (ns32kaout_bfd_reloc_type_lookup): Define prototype without MYNSX.
+ (write_object_contents): Correct prototype.
+
+ * peicode.h (pe_ILF_build_a_bfd): Use an unsigned int param rather
+ than unsigned short.
+
+ * section.c (bfd_set_section_contents): Remove redundant
+ "offset < 0" test. Check that "count" doesn't overflow size_t.
+ (bfd_get_section_contents): Likewise.
+
+ * som.c (som_fixup_formats): Add missing braces.
+ (som_reloc_addend): Pass a bfd_vma for "addend".
+
+ * srec.c (srec_write_record): Pass "type" as an unsigned int.
+ (srec_write_symbols): Remove an unnecessary var.
+
+ * targets.c (_bfd_target_vector): Sort entries. Sort externs
+ to match.
+ * configure.in: Sort to match. Bump version number.
+ * configure: Regenerate.
+
+ * tekhex.c (move_section_contents): Assert offset == 0.
+
+ * versados.c (new_symbol_string): Constify arg.
+ (process_esd): Use bfd_und_section_ptr rather than &bfd_und_section.
+ (versados_get_symbol_info): Make static.
+ (versados_print_symbol): Likewise.
+ (versados_get_reloc_upper_bound): Likewise.
+ (versados_canonicalize_reloc): Likewise.
+
+2001-09-18 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * elflink.h (elf_link_input_bfd): Fix typo in error message.
+
+2001-09-17 H.J. Lu <hjl@gnu.org>
+
+ * dwarf1.c (parse_die): Take a new arg for the end of the
+ section. Return false if die is beyond the section.
+ (parse_functions_in_unit): Pass the end of the section to
+ parse_die ().
+ (_bfd_dwarf1_find_nearest_line): Likewise.
+
+2001-09-14 Michael Rauch <mrauch@netbsd.org>
+
+ * elf32-sparc.c (elf32_sparc_relocate_section): Treat R_SPARC_UA32
+ just like R_SPARC_32.
+
+2001-09-14 Kevin Lo <kevlo@openbsd.org>
+
+ * configure.bfd: Add arm-openbsd target.
+
+2001-09-14 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * config.bfd: Change machine triplets from mips*el*-* to mips*el-*.
+ Add support for mips64.
+
+2001-09-13 Alexandre Oliva <aoliva@redhat.com>
+
+ * elf32-openrisc.c (ELF_MACHINE_ALT1): Define as EM_OPENRISC_OLD.
+
+2001-09-12 Alexandre Oliva <aoliva@redhat.com>
+
+ * elf.c (prep_headers): Get the machine code from the elf
+ backend data.
+ * elf-m10200.c (ELF_MACHINE_CODE): Redefine to EM_MN10200.
+ (ELF_MACHINE_ALT1): Define to EM_CYGNUS_MN10200.
+ * elf-m10300.c (ELF_MACHINE_CODE): Redefine to EM_MN10300.
+ (ELF_MACHINE_ALT1): Define to EM_CYGNUS_MN10300.
+ * elf-arc.c (arc_elf_final_write_processing): Don't override
+ e_machine, it's now properly set in prep_headers.
+ * elf32-avr.c (elf32_avr_object_p): Accept both EM_AVR and
+ EM_AVR_OLD.
+ (ELF_MACHINE_ALT1): Define to EM_AVR_OLD.
+ * elf-d10v.c (ELF_MACHINE_CODE): Redefine to EM_D10V.
+ (ELF_MACHINE_ALT1): Define to EM_CYGNUS_D10V.
+ * elf-d30v.c (ELF_MACHINE_CODE): Redefine to EM_D30V.
+ (ELF_MACHINE_ALT1): Define to EM_CYGNUS_D30V.
+ * elf-fr30.c (ELF_MACHINE_CODE): Redefine to EM_FR30.
+ (ELF_MACHINE_ALT1): Define to EM_CYGNUS_FR30.
+ * elf-m32r.c (ELF_MACHINE_CODE): Redefine to EM_M32R.
+ (ELF_MACHINE_ALT1): Define to EM_CYGNUS_M32R.
+ * elf32-pj.c (ELF_MACHINE_ALT1): DEfine to EM_PJ_OLD.
+ * elf-v850.c (ELF_MACHINE_CODE): Redefine to EM_V850.
+ (ELF_MACHINE_ALT1): Define to EM_CYGNUS_V850.
+
+2001-09-11 Richard Henderson <rth@redhat.com>
+
+ * elf64-alpha.c (elf64_alpha_section_flags): New.
+ (elf64_alpha_fake_sections): Map SEC_SMALL_DATA to SHF_ALPHA_GPREL.
+
+2001-09-11 Richard Henderson <rth@redhat.com>
+
+ * elf64-alpha.c (elf64_alpha_relocate_section): Do not
+ apply HINT relocations against dynamic symbols.
+
+2001-09-11 H.J. Lu <hjl@gnu.org>
+
+ * linker.c (link_action): Change COMMON_ROW\defw from CREF to COM.
+
+2001-09-09 Richard Henderson <rth@redhat.com>
+
+ * elf64-alpha.c: Delete all unused ERIC_neverdef and rth_notdef code.
+
+ * elf64-alpha.c (elf64_alpha_relax_with_lituse): Nop out gpdisp
+ following a call to a near function.
+
+2001-09-08 Richard Henderson <rth@redhat.com>
+
+ * elf64-alpha.c (elf64_alpha_relocate_section): Soft fail
+ relocation errors. Fail gp-relative relocations against
+ dynamic symbols.
+
+2001-09-08 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-i386.c (elf_i386_relocate_section): Check !DEF_REGULAR
+ as well as DEF_DYNAMIC in test for avoided copy relocs.
+ (allocate_plt_and_got_and_discard_relocs): Likewise.
+ * elf32-hppa.c (elf_i386_relocate_section): Likewise.
+ (allocate_plt_and_got_and_discard_relocs): Likewise.
+
+2001-09-07 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * elf32-mips.c (mips_elf_calculate_relocation): Fix overflow handling
+ of R_MIPS_PC16.
+
+2001-09-06 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * elf64-mips.c (mips_elf64_howto_table_rel): Fix relocation HOWTO
+ definitions.
+ (mips_elf64_howto_table_rel): Likewise.
+
+2001-09-05 Tom Rix <trix@redhat.com>
+
+ * xcofflink.c (bfd_xcoff_import_symbol): Handle import file XMC_XO
+ and syscall symbols.
+ (write_global_symbol) : Same.
+ (bfd_xcoff_export_symbol): Remove unused syscall param.
+ * libxcoff.h: Change prototype of bfd_xcoff_export symbol and
+ bfd_xcoff_import_symbol.
+ * bfd-in.h: Same.
+ * bfd-in2.h : Regenerate.
+
+2001-09-04 Richard Henderson <rth@redhat.com>
+
+ * elf64-alpha.c (SKIP_HOWTO): New.
+ (elf64_alpha_howto_table): Use it to remove dead ECOFF relocs.
+ Fix sizes of 16-bit mem format relocs.
+ (elf64_alpha_reloc_map): Update to match.
+ (elf64_alpha_relax_with_lituse): Use GPREL16 as appropriate.
+ (elf64_alpha_relax_without_lituse): Likewise.
+ (elf64_alpha_check_relocs): Handle GPREL16.
+ (elf64_alpha_relocate_section): Likewise.
+ * reloc.c (BFD_RELOC_ALPHA_USER_*): Remove.
+ (BFD_RELOC_ALPHA_GPREL_HI16, BFD_RELOC_ALPHA_GPREL_LO16): New.
+ * bfd-in2.h, libbfd.h: Rebuild.
+
+2001-09-04 Jeff Law <law@redhat.com>
+
+ * elf32-h8300.c (elf32_h8_relax_section): New function.
+ (elf32_h8_relax_delete_bytes): Likewise.
+ (elf32_h8_symbol_address_p): Likewise.
+ (elf32_h8_get_relocated_section_contents): Likewise.
+ (bfd_elf32_bfd_relax_section): Define.
+ (bfd_elf32_bfd_get_relocated_section_contents): Likewise.
+
+ * elf32-h8300.c (special): New function.
+ (h8_elf_howto_table): Use it for SPECIAL_FUNCTION field in
+ all relocations.
+ (elf32_h8_final_link_relocate): Treat R_H8_DIR24A8 like 32bit
+ relocations. Fix problems with the true 24bit reloc R_H8_DIR24R8.
+ Fix minor problems with 8bit and 16bit PC relative relocations.
+
+2001-09-01 Andreas Jaeger <aj@suse.de>
+
+ * vms-tir.c: Add missing prototypes.
+ * vms-hdr.c: Likewise.
+ * vms-gsd.c: Likewise.
+ * vms-misc.c: Likewise.
+
+2001-08-31 H.J. Lu <hjl@gnu.org>
+
+ * elf32-mips.c (_bfd_mips_elf_check_relocs): Report filename
+ with bad relocation.
+
+2001-08-31 Eric Christopher <echristo@redhat.com>
+ Jason Eckhardt <jle@redhat.com>
+
+ * archures.c: Add mipsisa32 and mipsisa64. Remove mips32,
+ mips32_4k and mips64.
+ * aoutx.h: Remove bfd_mach_mips32, bfd_mach_mips32_4k,
+ bfd_mach_mips64. Add bfd_mach_mipsisa32, bfd_mach_mipsisa64.
+ * cpu-mips.c: Ditto.
+ * elf32-mips.c (_bfd_mips_elf_final_write_processing): Ditto.
+ * bfd-in2.h: Regenerate.
+
+2001-08-31 Jakub Jelinek <jakub@redhat.com>
+
+ * elf64-alpha.c (elf64_alpha_relocate_section): Duplicate memory
+ value into R_ALPHA_RELATIVE's addend.
+ (elf64_alpha_finish_dynamic_symbol): Likewise.
+
+2001-08-31 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * elf32-arm.h (elf32_arm_relocate_section): Do not rightshift
+ recomputed addend during relocatable link if not USE_REL.
+
+ * elflink.h (elf_gc_propagate_vtable_entries_used): Fix off-by-one
+ error.
+
+2001-08-30 H.J. Lu <hjl@gnu.org>
+
+ * elf32-mips.c (mips_elf_calculate_relocation): Revert the last
+ 2 changes.
+ (_bfd_mips_elf_adjust_dynamic_symbol): Allocate dynamic
+ relocations for weak definitions.
+
+2001-08-30 H.J. Lu <hjl@gnu.org>
+
+ * Makefile.am (BFD32_BACKENDS): Add elf32-h8300.lo.
+ (BFD32_BACKENDS_CFILES): Add elf32-h8300.c.
+ * Makefile.in: Rebuild.
+
+2001-08-30 H.J. Lu <hjl@gnu.org>
+
+ * elf32-mips.c (mips_elf_calculate_relocation): Don't create
+ dynamic relocation for undefined weak symbols when creating
+ executables. Check h->root.root.type, instead of h->root.type.
+
+2001-08-29 Joel Sherrill <joel@OARcorp.com>
+
+ * config.bfd (i[3456]86-*-rtems*, m68*-*-rtems*): Change
+ default from coff to elf.
+
+2001-08-29 Jeff Law <law@redhat.com>
+
+ * elf32-h8300.c (h8_elf_howto_table): Add new PC relative
+ relocations.
+ (h8_reloc_map): Similarly.
+ (elf32_h8_final_link_relocate): Remove incorrect overflow tests.
+ Add support for PC relative relocations.
+
+ * elf32-h8300.c: Put all prototypes together.
+ (elf32_h8_info_to_howto): Parameter elf_reloc is used.
+ (elf32_h8_final_link_relocate): New function for linker.
+ (elf32_h8_relocate_section): Similarly.
+ (elf_backend_relocate_section): Define.
+
+ * cpu-h8300.c (h8300_scan, compatible): Prototype.
+ (h8300_scan): Handle architecture:machine encodings typically
+ found in linker scripts.
+ * elf.c (prep_headers): Do not try to do H8 machine recognition
+ here.
+ * elf32-h8300.c: Add some missing prototypes.
+ (elf32_h8_mach, elf32_h8_final_write_processing): New functions.
+ (elf32_h8_object_p): Similarly.
+
+2001-08-29 Tom Rix <trix@redhat.com>
+
+ * xcofflink.c (xcoff_link_add_symbols): Fix XTY_LD symbol that
+ does not follow a XTY_SD.
+
+2001-08-29 Alan Modra <amodra@bigpond.net.au>
+
+ * targmatch.sed: Delete case statements.
+ * config.bfd <powerpc-*-aix* entry>: Select 64 bit xcoff for
+ aix4.3 and above.
+
+2001-08-29 J"orn Rennecke <amylaar@redhat.com>
+
+ * Makefile.am (elf32-h8300.lo): New target.
+ * config.bfd (h8300*-*-elf): New case.
+ * configure.in (bfd_elf32_h8300_vec): New case.
+ * elf.c (prep_headers): Add case for bfd_arch_h8300.
+ * reloc.c (BFD_RELOC_H8_DIR16A8): New relocation.
+ (BFD_RELOC_H8_DIR16R8, BFD_RELOC_H8_DIR24A8): Likewise.
+ (BFD_RELOC_H8_DIR24R8, BFD_RELOC_H8_DIR32A16): Likewise.
+ * targets.c (bfd_target bfd_elf32_h8300_vec): New extern declaration.
+ * elf32-h8300.c: New file.
+ * Makefile.in, bfd-in2.h, libbfd.h, configure: Regenerated.
+
+2001-08-28 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * sparclynx.c: Add missing prototypes.
+ * coff-mcore.c: Add missing prototypes.
+ * elf32-pj.c: Add missing prototypes.
+ * nlm32-sparc.c: Add missing prototypes.
+ * oasys.c: Add missing prototypes.
+ * pdp11.c: Add missing prototypes.
+ * pe-mips.c: Add missing prototypes.
+ * riscix.c: Add missing prototypes.
+
+2001-08-27 Daniel Jacobowitz <drow@mvista.com>
+
+ * elf32-i386.c: Add missing prototypes.
+ * elf32-ppc.c: Likewise.
+ * elf32-sh-lin.c: Likewise.
+ * elfarm-nabi.c: Likewise.
+
+2001-08-27 Daniel Jacobowitz <drow@mvista.com>
+
+ * elf32-i386.c (elf_i386_grok_prstatus): New function.
+ (elf_i386_grok_psinfo): New function.
+ (elf_backend_grok_prstatus): Define.
+ (elf_backend_grok_psinfo): Likewise.
+ * elf32-ppc.c (ppc_elf_grok_prstatus): New function.
+ (ppc_elf_grok_psinfo): New function.
+ (elf_backend_grok_prstatus): Define.
+ (elf_backend_grok_psinfo): Likewise.
+ * elf32-sh-lin.c (elf32_shlin_grok_prstatus): New function.
+ (elf32_shlin_grok_psinfo): New function.
+ (elf_backend_grok_prstatus): Define.
+ (elf_backend_grok_psinfo): Likewise.
+ * elfarm-nabi.c (elf32_arm_nabi_grok_prstatus): New function.
+ (elf32_arm_nabi_grok_psinfo): New function.
+ (elf_backend_grok_prstatus): Define.
+ (elf_backend_grok_psinfo): Likewise.
+
+2001-08-27 H.J. Lu <hjl@gnu.org>
+
+ * elf32-mips.c (mips_elf_create_dynamic_relocation): Add more
+ sanity check.
+ (mips_elf_calculate_relocation): Create dynamic relocation for
+ symbols with weak definition or the ELF_LINK_HASH_DEF_REGULAR
+ bit is not set.
+
+2001-08-27 H.J. Lu <hjl@gnu.org>
+
+ * elf32-mips.c (_bfd_mips_elf_hide_symbol): Add prototype.
+ (_bfd_mips_elf_copy_indirect_symbol): Likewise.
+ (_bfd_elf32_mips_grok_prstatus): Likewise.
+ (_bfd_elf32_mips_grok_psinfo): Likewise.
+ (_bfd_mips_elf_hide_symbol): Make it static and cast to
+ `struct mips_elf_link_hash_entry *'.
+ (_bfd_mips_elf_copy_indirect_symbol): Make it static.
+
+2001-08-27 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * mipsbsd.c: Add missing prototypes.
+ * hp300hpux.c: Add missing prototypes.
+ * i386aout.c: Add missing prototypes.
+ * i386lynx.c: Add missing prototypes.
+ * i386mach3.c: Add missing prototypes.
+ * i386msdos.c: Add missing prototypes.
+ * i386os9k.c: Add missing prototypes.
+
+2001-08-27 Linus Nordberg <linus@swox.se>
+ Torbjorn Granlund <tege@swox.com>
+ Staffan Ulfberg <staffanu@swox.se>
+ Alan Modra <amodra@bigpond.net.au>
+
+ * config.bfd: Add powerpc64 target. Add powerpc64 vectors to
+ targ64_selvecs for 32 bit powerpc targets.
+ * Makefile.am (BFD64_BACKENDS): Add elf64-ppc.lo.
+ (BFD64_BACKENDS_CFILES): Add elf64-ppc.c.
+ Run "make dep-am".
+ * Makefile.in: Regenerate.
+ * configure.in: Add elf64_powerpc vecs.
+ * configure: Regenerate.
+ * cpu-powerpc.c: Default to bfd_mach_ppc_620 entry for 64 bit.
+ * elf.c (prep_headers): EM_PPC64 for 64 bit ppc elf target.
+ * targets.c: Add bfd_elf64_powerpc_vec and bfd_elf64_powerpcle_vec.
+ * elf64-ppc.c: New file.
+ * reloc.c: Add powerpc64 relocs.
+ * libbfd.h: Regenerate.
+ * bfd-in2.h: Regenerate.
+
+2001-08-27 Andreas Schwab <schwab@suse.de>
+
+ * elf32-m68k.c (elf32_m68k_check_relocs): Set DF_TEXTREL if the
+ reloc is against read-only section.
+ (elf32_m68k_size_dynamic_sections): Use DF_TEXTREL flag instead of
+ looking up section names for DT_TEXTREL.
+ (elf32_m68k_reloc_type_class): New function.
+ (elf_backend_reloc_type_class): Define.
+
+2001-08-27 Andreas Jaeger <aj@suse.de>
+
+ * elf64-s390.c (elf_s390_check_relocs): Set DF_TEXTREL if the
+ reloc is against read-only section.
+ (elf_s390_size_dynamic_sections): Use DF_TEXTREL flag instead of
+ looking up section names for DT_TEXTREL.
+ (elf_s390_reloc_type_class): New.
+ (elf_backend_reloc_type_class): Define.
+
+ * elf32-s390.c (elf_s390_check_relocs): Set DF_TEXTREL if the
+ reloc is against read-only section.
+ (elf_s390_size_dynamic_sections): Use DF_TEXTREL flag instead of
+ looking up section names for DT_TEXTREL.
+ (elf_s390_reloc_type_class): New.
+ (elf_backend_reloc_type_class): Define.
+
+ * elf32-ppc.c (ppc_elf_check_relocs): Set DF_TEXTREL if the reloc
+ is against read-only section.
+ (ppc_elf_size_dynamic_sections): Use DF_TEXTREL flag instead of
+ looking up section names for DT_TEXTREL.
+ (ppc_elf_reloc_type_class): New.
+ (elf_backend_reloc_type_class): Define.
+
+2001-08-26 Andreas Jaeger <aj@suse.de>
+
+ * elf32-cris.c (cris_elf_check_relocs): Set DF_TEXTREL if the
+ reloc is against read-only section.
+ (elf_cris_size_dynamic_sections): Use DF_TEXTREL flag instead of
+ looking up section names for DT_TEXTREL.
+ (elf_cris_reloc_type_class): New.
+ (elf_backend_reloc_type_class): Define.
+
+ * elf32-sh.c (sh_elf_check_relocs): Set DF_TEXTREL if the reloc is
+ against read-only section.
+ (elf_backend_reloc_type_class): Define.
+ (sh_elf_reloc_type_class): New.
+ (sh_elf_size_dynamic_sections): Use DF_TEXTREL flag instead of
+ looking up section names for DT_TEXTREL.
+
+ * elf32-arm.h (elf32_arm_check_relocs): Set DF_TEXTREL if the
+ reloc is against read-only section.
+ (elf32_arm_size_dynamic_sections): Use DF_TEXTREL flag instead of
+ looking up section names for DT_TEXTREL.
+ (elf32_arm_reloc_type_class): New.
+ (elf_backend_reloc_type_class): Define.
+
+2001-08-25 Andreas Jaeger <aj@suse.de>
+
+ * oasys.c: Add missing prototypes.
+
+ * elf64-alpha.c (elf64_alpha_size_dynamic_sections): Add unused
+ attribute for parameter.
+ * elf.c (_bfd_elf_reloc_type_class): Likewise.
+
+ * versados.c (get_4): Make static.
+ (get_10): Make static.
+ Add missing prototypes.
+ (process_esd): Fix call to versados_new_symbol.
+
+2001-08-25 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * coff-a29k.c: Add missing prototypes.
+ * coff-apollo.c: Add missing prototypes.
+ * coff-arm.c: Add missing prototypes.
+ * coff-i860.c: Add missing prototypes.
+ * coff-rs6000.c: Add missing prototypes.
+ * coff-tic80.c: Add missing prototypes.
+ * elf-m10200.c: Add missing prototypes.
+ * elf-m10300.c: Add missing prototypes.
+ * elf32-arm.h: Add missing prototypes.
+ * elf32-d10v.c: Add missing prototypes.
+ * elf32-m32r.c: Add missing prototypes.
+ * elf32-mcore.c: Add missing prototypes.
+ * elf32-openrisc.c: Add missing prototypes.
+ * elf32-sh.c: Add missing prototypes.
+ * elf32-sparc.c: Add missing prototypes.
+ * elf32-v850.c: Add missing prototypes.
+ * elfarm-nabi.c: Add missing prototypes.
+ * elfarm-oabi.c: Add missing prototypes.
+
+2001-08-25 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * elf32-mips.c (elf_mips_abi_name): Return the right ABI string for
+ E_MIPS_ABI_O64 and E_MIPS_ABI_EABI64
+
+2001-08-24 H.J. Lu <hjl@gnu.org>
+
+ * elf.c (_bfd_elf_merge_sections): Fail if not using an ELF
+ hash structure.
+
+2001-08-24 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * elf-bfd.h (elf_hash_table): Revert definition.
+ (is_elf_hash_table): New macro.
+ * elflink.h (elf_link_add_object_symbols): Test
+ is_elf_hash_table before accessing ELF only fields in hash
+ structure.
+ (elf_link_create_dynamic_sections): Fail if not using an ELF
+ hash structure.
+ (elf_add_dynamic_entry): Fail if not using an ELF hash
+ structure.
+ (elf_link_record_local_dynamic_symbol): Fail if not using an
+ ELF hash structure.
+ (size_dynamic_sections): Fail if not using an ELF hash
+ structure.
+ (elf_adjust_dynamic_symbol): Fail if not using an ELF
+ hash structure.
+ (elf_bfd_final_link): Fail if not using an ELF hash
+ structure.
+
+2001-08-24 H.J. Lu <hjl@gnu.org>
+
+ * elf-bfd.h (elf_hash_table): Return NULL if the linker hash
+ table is not an ELF linker hash table.
+
+ * elf.c (_bfd_elf_link_hash_table_init): Set the linker hash
+ table type to bfd_link_elf_hash_table.
+
+ * elfxx-target.h (bfd_elfNN_bfd_link_hash_table_create): Revert
+ the last change.
+
+ * linker.c (_bfd_link_hash_table_init): Set the linker hash
+ table type to bfd_link_generic_hash_table.
+
+2001-08-24 Alexandre Oliva <aoliva@redhat.com>
+
+ * bfd.c (bfd_alt_mach_code): New function.
+ * bfd-in2.h: Rebuilt.
+
+2001-08-24 Alexandre Oliva <aoliva@redhat.com>
+
+ * elf-m10300.c (mn10300_elf_relocate_section): Test the right
+ `type' field in the hash entry when deciding whether to follow a
+ link.
+
+2001-08-24 Jakub Jelinek <jakub@redhat.com>
+
+ * elflink.h (elf_link_sort_cmp1): Sort RELATIVE relocs first, not
+ last.
+ (elf_link_sort_relocs): Adjust accordingly.
+
+ * elf64-alpha.c (struct alpha_elf_link_hash_entry): Add reltext flag.
+ (elf64_alpha_check_relocs): Set it if section this reloc is against
+ is read-only. Set DF_TEXTREL if a RELATIVE reloc is needed against
+ read-only section.
+ (elf64_alpha_calc_dynrel_sizes): Set DF_TEXTREL flag if relocation
+ is is against read-only section.
+ (elf64_alpha_size_dynamic_sections): Use DF_TEXTREL flag, don't
+ check section names.
+ (elf64_alpha_reloc_type_class): New.
+ (elf_backend_reloc_type_class): Define.
+
+2001-08-24 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * linker.c (_bfd_generic_link_add_archive_symbols): Replace alloca()
+ by bfd_malloc().
+
+2001-08-23 Andreas Jaeger <aj@suse.de>
+
+ * elf64-x86-64.c (elf64_x86_64_check_relocs): Set DF_TEXTREL if
+ the reloc is against read-only section.
+ (elf64_x86_64_size_dynamic_sections): Use DF_TEXTREL flag instead
+ of looking up section names for DT_TEXTREL.
+ (elf64_x86_64_reloc_type_class): New.
+ (elf_backend_reloc_type_class): Define.
+
+2001-08-23 H.J. Lu <hjl@gnu.org>
+
+ * syms.c (bfd_print_symbol_vandf): Add abfd to arg.
+ * bfd-in2.h (bfd_print_symbol_vandf): Regenerated.
+
+ * aoutx.h (NAME(aout,print_symbol)): Pass abfd to
+ bfd_print_symbol_vandf.
+ * coffgen.c (coff_print_symbol): Likewise.
+ * elf.c (bfd_elf_print_symbol): Likewise.
+ * ieee.c (ieee_print_symbol): Likewise.
+ * nlmcode.h (nlm_print_symbol): Likewise.
+ * oasys.c (oasys_print_symbol): Likewise.
+ * pdp11.c (NAME(aout,print_symbol)): Likewise.
+ * som.c (som_print_symbol): Likewise.
+ * srec.c (srec_print_symbol): Likewise.
+ * tekhex.c (tekhex_print_symbol): Likewise.
+ * versados.c (versados_print_symbol): Likewise.
+ * vms.c (vms_print_symbol): Likewise.
+
+ * elf.c (_bfd_elf_print_private_bfd_data): Replace fprintf_vma
+ with bfd_fprintf_vma.
+ (bfd_elf_print_symbol): Likewise.
+ * syms.c (bfd_print_symbol_vandf): Likewise.
+
+2001-08-23 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * aoutf1.h (sunos_write_object_contents): Silence compile time
+ warning.
+ * libaout.h (N_SET_DYNAMIC): Silence compile time warning.
+
+ * bout.c: Add missing function prototypes. Fix formatting.
+ * coff-z8k.c: Add missing function prototypes. Fix formatting.
+ * coff-w65.c: Add missing function prototypes. Fix formatting.
+ * coff-h8500.c: Add missing function prototypes. Fix formatting.
+ * coff-h8300.c: Add missing function prototypes. Fix formatting.
+ * coff-tic54x.c: Add missing function prototypes. Fix formatting.
+ * coff-tic30.c: Add missing function prototypes. Fix formatting.
+ * coff-m68k.c: Add missing function prototypes. Fix formatting.
+ * coff-rs6000.c: Add missing function prototypes. Fix formatting.
+ * coff-sh.c: Add missing function prototypes. Fix formatting.
+
+2001-08-23 Jakub Jelinek <jakub@redhat.com>
+
+ * elf-bfd.h (enum elf_reloc_type_class): New.
+ (struct elf_backend_data): Add elf_backend_reloc_type_class.
+ (_bfd_elf_reloc_type_class): New.
+ * elfxx-target.h (elf_backend_reloc_type_class): Define.
+ (elfNN_bed): Add elf_backend_reloc_type_class.
+ * elf.c (_bfd_elf_reloc_type_class): New.
+ * elf32-i386.c (elf_i386_check_relocs): Set DF_TEXTREL if the reloc
+ is against read-only section.
+ (elf_i386_size_dynamic_sections): Use DF_TEXTREL flag instead of
+ looking up section names for DT_TEXTREL.
+ (elf_i386_reloc_type_class): New.
+ (elf_backend_reloc_type_class): Define.
+ * elf32-sparc.c (elf32_sparc_check_relocs): Set DF_TEXTREL if the
+ reloc is against read-only section.
+ (elf32_sparc_size_dynamic_sections): Use DF_TEXTREL flag instead of
+ looking up section names for DT_TEXTREL.
+ (elf32_sparc_reloc_type_class): New.
+ (elf_backend_reloc_type_class): Define.
+ * elf64-sparc.c (sparc64_elf_check_relocs): Set DF_TEXTREL if the
+ reloc is against read-only section.
+ (sparc64_elf_size_dynamic_sections): Use DF_TEXTREL flag instead of
+ looking up section names for DT_TEXTREL.
+ (sparc64_elf_reloc_type_class): New.
+ (elf_backend_reloc_type_class): Define.
+ * elfxx-ia64.c (struct elfNN_ia64_link_hash_table): Add reltext field.
+ (elfNN_ia64_hash_table_create): Clear ia64_info.
+ (get_reloc_section): Set DF_TEXTREL if the reloc is against read-only
+ section.
+ (elfNN_ia64_size_dynamic_sections): Use ia64_info->reltext flag
+ instead of looking up section names for DT_TEXTREL.
+ (elfNN_ia64_reloc_type_class): New.
+ (elf_backend_reloc_type_class): Define.
+ * elflink.h (size_dynamic_sections): Add spare DT_NULL tags.
+ (struct elf_link_sort_rela): New.
+ (elf_link_sort_cmp1, elf_link_sort_cmp2, elf_link_sort_relocs): New.
+ (elf_bfd_final_link): Call elf_link_sort_relocs.
+ Convert one spare DT_NULL into DT_RELCOUNT resp. DT_RELACOUNT if
+ necessary.
+
+2001-08-23 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * configure.in (x86-bsdi): No corefile support.
+ * configure: Regenerate.
+
+2001-08-22 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * coff-stgo32.c (COFF_SECTION_ALIGNMENT_ENTRIES): Add missing
+ comma.
+
+2001-08-21 Mark Elbrecht <snowball3@bigfoot.com>
+
+ * coff-go32.c: Make DWARF2 sections use an alignment of 0. Set
+ the alignment of dwarf2 linkonce sections to 0.
+ * coff-sto32.c: Likewise.
+
+2001-08-20 Andreas Jaeger <aj@suse.de>
+
+ * coff-sparc.c: Add missing prototypes.
+ * elf32-s390.c: Likewise.
+ * elf32-i960.c: Likewise.
+ * aout-target.h: Likewise.
+
+2001-08-20 H.J. Lu <hjl@gnu.org>
+
+ * elf-bfd.h (elf_obj_tdata): Add num_section_syms.
+ (elf_num_section_syms): New for num_section_syms.
+
+ * elf.c (elf_map_symbols): Set num_section_syms.
+ (_bfd_elf_symbol_from_bfd_symbol): Check num_section_syms for
+ the section symbol index.
+
+2001-08-20 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * elfxx-target.h (bfd_elfNN_bfd_link_hash_table_create): Never
+ select the generic has table creator. All elf backends need elf
+ specific fields in the hash table.
+
+2001-08-20 Alan Modra <amodra@bigpond.net.au>
+
+ * archive.c (offsetof): Remove define.
+ * elf.c: Likewise.
+ * oasys.c: Likewise
+ * sysdep.h (offsetof): Define.
+
+2001-08-17 Alan Modra <amodra@bigpond.net.au>
+
+ * bfd.c (bfd_get_gp_size): Return an unsigned int.
+ (bfd_set_gp_size): Make param unsigned.
+ * bfd-in2.h: Regenerate.
+ * elf32-ppc.c (ppc_elf_add_symbol_hook): Use elf_gp_size rather
+ than calling bfd_get_gp_size.
+ * elf64-alpha.c (elf64_alpha_add_symbol_hook): Likewise.
+ * elfxx-ia64.c (elfNN_ia64_add_symbol_hook): Likewise.
+
+2001-08-17 Alan Modra <amodra@bigpond.net.au>
+
+ * linker.c (default_fill_link_order): Handle four byte fill value.
+
+2001-08-17 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-sparc.c (sparc64_elf_output_arch_syms): Add missing
+ prototype.
+ * nlm32-alpha.c (nlm_alpha_write_external): Fix warning.
+
+ * elf64-mips.c (UNUSED_RELOC): Define.
+ (mips_elf64_howto_table_rel): Use it.
+ (mips_elf64_howto_table_rela): Here too.
+ (mips_elf64_write_relocs): Fix signed/unsigned warning.
+
+ * coffcode.h (coff_write_object_contents): Add ATTRIBUTE_UNUSED to
+ silence warning.
+ * coffgen.c (coff_print_symbol): Fix warnings.
+ (coff_find_nearest_line): Likewise.
+ * cofflink.c (_bfd_coff_link_input_bfd): Likewise.
+ * coff-alpha.c (alpha_convert_external_reloc): Likewise.
+ * format.c (bfd_check_format_matches): Likewise.
+ (bfd_set_format): Likewise.
+ * coff-ia64.c: Add missing prototypes.
+ * elf64-alpha.c (struct alpha_elf_link_hash_entry): Make addend
+ signed to silence warnings.
+ (elf64_alpha_relocate_section): Likewise.
+ (elf64_alpha_find_reloc_at_ofs): Fix warnings.
+ (elf64_alpha_add_symbol_hook): Likewise.
+ (elf64_alpha_final_link): Likewise.
+ (elf64_alpha_relax_section): Remove redundant assign to info.gotent.
+ (elf64_alpha_merge_gots): Add ATTRIBUTE_UNUSED to unused args.
+ (elf64_alpha_size_got_sections): Likewise.
+ * elfxx-ia64.c: Add missing prototypes.
+ (elfNN_ia64_relocate_section): Fix warning.
+ (elfNN_ia64_unwind_entry_compare): Make params const.
+
+2001-08-17 Alan Modra <amodra@bigpond.net.au>
+
+ * config.bfd (targ64_selvecs): New.
+ <powerpc-*-aix* entry>: Use it here instead of ineffectual #ifdef.
+
+ * bfd-in.h (BFD_VERSION): Remove wrong comment.
+ (BFD_DEFAULT_TARGET_SIZE): New.
+ (BFD_ARCH_SIZE): Comment.
+ * configure.in (target_size): New. Set instead of target64 in
+ selvecs case statement. Set target64 from it.
+ (bfd_default_target_size): New. Set from taget_size. AC_SUBST.
+ * bfd-in2.h: Regenerate.
+ * configure: Regenerate.
+
+2001-08-17 Alan Modra <amodra@bigpond.net.au>
+
+ * bfd.c (enum bfd_error): Add bfd_error_wrong_object_format.
+ (bfd_errmsgs): Add corresponding message.
+ * archive.c (bfd_generic_archive_p): Don't release bfd_ardata when
+ finding an archive that contains different format object files.
+ Return bfd_error_wrong_object_format for this case.
+ * format.c: Formatting fixes. s/CONST/const/.
+ (bfd_check_format_matches): Accept archives that give
+ bfd_error_wrong_object_format if no full match is found. Tidy
+ code handling matching_vector. Don't return a pointer to freed
+ memory in `matching'. Handle ambiguous matches as for partial
+ archive matches.
+ * bfd-in2.h: Regenerate.
+
+2001-08-15 Alan Modra <amodra@bigpond.net.au>
+
+ * libieee.h (common_header_type): Add last_byte field.
+
+ * ieee.c: Add missing prototypes. Some format fixes.
+ (struct output_buffer_struct): Move for availability to prototypes.
+ (ieee_part_after): New function.
+ (ieee_slurp_debug): Use it here.
+ (ieee_seek): Pass in ieee_data_struct rather than bfd. Use
+ ieee_part_after to set last_byte to one past end of current part.
+ Update callers.
+ (ieee_pos): Pass in ieee_data_struct rather than bfd.
+ Update callers.
+ (parse_expression): Don't go beyond the end of the current part.
+ (ieee_slurp_external_symbols): Correct type passed to read_2bytes.
+ (ieee_get_symtab_upper_bound, ieee_get_symtab,
+ ieee_get_symbol_info, ieee_print_symbol, ieee_new_section_hook,
+ ieee_get_reloc_upper_bound, ieee_canonicalize_reloc, block,
+ ieee_set_section_contents, ieee_write_object_contents,
+ ieee_make_empty_symbol): Make static.
+ (ieee_archive_p): Correct comments regarding bfd_read.
+ (ieee_object_p): Similarly.
+ (ieee_mkobject): Move it. Clear output_ptr_start, output_ptr,
+ output_ptr_end, input_ptr_start, input_ptr, input_ptr_end,
+ input_bfd, output_bfd, output_buffer.
+ (do_as_repeat): Write out ieee_set_current_pc_enum value as for
+ do_with_relocs, ie. as a symbol for relocatable files.
+ (ieee_vec): Add comments showing functions referenced by macros.
+
+2001-08-14 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * aout-tic30.c: Add missing prototypes. Fix formatting.
+ * aout-ns32k.c: Add missing prototypes. Fix formatting.
+ * peXXigen.c: Add missining prototypes. Fix formatting.
+ * aout-adobe.c: Add missining prototypes. Fix formatting.
+
+2001-08-13 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * elf32-v850.c: Add missing function prototypes.
+ Fix some formatting.
+
+ * cpu-v850.c: Add missing function prototype.
+ Fix some formatting.
+
+2001-08-11 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * elf-bfd.h (struct elf_backend_data): Add new fields
+ 'elf_backend_sprintf_vma' and 'elf_backend_fprintf_vma'.
+ (bfd_elf_sprintf_vma): Rename function prototype to
+ '_bfd_elf_sprintf_vma'.
+ (bfd_elf_fprintf_vma): Rename function prototype to
+ '_bfd_elf_fprintf_vma'.
+ * bfd.c (bfd_sprintf_vma): Do not invoke bfd_elf_sprintf_vma
+ directly, instead indirect via the elf_backend_data structure.
+ (bfd_fprintf_vma): Do not invoke bfd_elf_fprintf_vma directly,
+ instead indirect via the elf_backend_data structure.
+ * elf.c (bfd_elf_sprintf_vma): Rename to _bfd_elf_sprintf_vma.
+ (bfd_elf_fprintf_vma): Rename to _bfd_elf_fprintf_vma.
+ * elfxx-target.h (elf_backend_sprintf_vma): Initialise if not
+ already defined.
+ (elf_backend_fprintf_vma): Initialise if not already defined.
+ (struct elf_backend_data): Initialise the
+ elf_backend_sprintf_vma and elf_backend_fprintf_vma fields.
+
+2001-08-10 Andreas Jaeger <aj@suse.de>
+
+ * elf64-sparc.c: Add missing prototypes.
+ * elf32-cris.c: Likewise.
+ * elf32-i370.c: Likewise.
+ * elf64-hppa.c: Likewise.
+ * elf64-s390.c: Likewise.
+
+2001-08-10 Andreas Jaeger <aj@suse.de>
+
+ * elf64-x86-64.c (elf64_x86_64_elf_object_p): Make static.
+ Add prototypes where needed.
+
+2001-08-10 H.J. Lu <hjl@gnu.org>
+
+ * bfd.c (bfd_sprintf_vma): Fix a typo in the last change.
+ (bfd_fprintf_vma): Likewise.
+
+2001-08-10 H.J. Lu <hjl@gnu.org>
+
+ * bfd.c (bfd_sprintf_vma): Don't return void.
+ (bfd_fprintf_vma): Likewise.
+
+2001-08-10 Andreas Jaeger <aj@suse.de>
+
+ * configure.in: Add -Wstrict-prototypes and -Wmissing-prototypes
+ to build warnings.
+ * configure: Regenerate.
+
+2001-08-10 Alan Modra <amodra@bigpond.net.au>
+
+ * elf.c (bfd_elf_sprintf_vma): Add ATTRIBUTE_UNUSED to quiet
+ warning if not BFD64. Add braces so emacs auto format works.
+ (bfd_elf_fprintf_vma): Likewise.
+
+ * libxcoff.h (struct xcoff_backend_data_rec): Constify src param
+ of _xcoff_swap_ld*.
+ * coff-rs6000.c (xcoff_swap_ldhdr_in): Modify type of external
+ param to agree with libxcoff.h.
+ (xcoff_swap_ldhdr_out): Likewise.
+ (xcoff_swap_ldsym_in): Likewise.
+ (xcoff_swap_ldsym_out): Likewise.
+ (xcoff_swap_ldrel_in): Likewise.
+ (xcoff_swap_ldrel_out): Likewise.
+ (xcoff_create_csect_from_smclas): Likewise.
+ * coff64-rs6000.c: Add missing prototypes.
+ (xcoff64_swap_ldhdr_in): Modify type of external param to agree
+ with libxcoff.h.
+ (xcoff64_swap_ldhdr_out): Likewise.
+ (xcoff64_swap_ldsym_in): Likewise.
+ (xcoff64_swap_ldsym_out): Likewise.
+ (xcoff64_swap_ldrel_in): Likewise.
+ (xcoff64_swap_ldrel_out): Likewise.
+ (xcoff64_ppc_relocate_section): Make static.
+ (xcoff64_slurp_armap): Likewise.
+ (xcoff64_archive_p): Likewise.
+ (xcoff64_openr_next_archived_file): Likewise.
+ (xcoff64_sizeof_headers): Likewise.
+ (xcoff64_is_lineno_count_overflow): Likewise.
+ (xcoff64_is_reloc_count_overflow): Likewise.
+ (xcoff64_loader_symbol_offset): Likewise.
+ (xcoff64_loader_reloc_offset): Likewise.
+ * elf64-gen.c: Add missing prototypes.
+
+2001-08-09 H.J. Lu <hjl@gnu.org>
+
+ * elf.c (bfd_elf_sprintf_vma): Check ELFCLASS64 only in BFD64.
+ (bfd_elf_fprintf_vma): Likewise.
+
+2001-08-09 H.J. Lu <hjl@gnu.org>
+
+ * bfd-in.h (bfd_elf_sprintf_vma, bfd_elf_fprintf_vma): Moved
+ to ...
+ * elf-bfd.h: Here.
+ * bfd-in2.h: Regenerated.
+
+2001-08-09 H.J. Lu <hjl@gnu.org>
+
+ * bfd-in.h (bfd_sprintf_vma): New prototype.
+ (bfd_fprintf_vma): Likewise.
+ (bfd_elf_sprintf_vma): Likewise.
+ (bfd_elf_fprintf_vma): Likewise.
+ (bfd_printf_vma): New. Defined with bfd_fprintf_vma.
+ * bfd-in2.h: Regenerated.
+
+ * bfd.c (bfd_sprintf_vma): New. Defined.
+ (bfd_fprintf_vma): Likewise.
+
+ * elf.c (bfd_elf_sprintf_vma): New. Defined.
+ (bfd_elf_fprintf_vma): Likewise.
+
+2001-08-09 Alan Modra <amodra@bigpond.net.au>
+
+ * coff-rs6000.c: Add missing prototypes.
+ (xcoff_ppc_relocate_section, xcoff_is_lineno_count_overflow,
+ xcoff_is_reloc_count_overflow, xcoff_loader_symbol_offset,
+ xcoff_loader_reloc_offset): Make static.
+ * dwarf1.c: Add missing prototypes.
+ * dwarf2.c: Add missing prototypes.
+ (struct abbrev_info): Move definition.
+ (struct attr_abbrev, ABBREV_HASH_SIZE, ATTR_ALLOC_CHUNK): Likewise.
+ * elf.c: Add missing prototypes.
+ * elf32-gen.c: Likewise.
+ * elf32-i386.c: Likewise.
+ * elf32-ppc.c: Likewise.
+ (ppc_elf_sort_rela): Use PTR instead of "void *".
+ * elflink.h: Add missing prototypes. Formatting fixes.
+ * merge.c: Add missing prototypes.
+ (last4_eq): Use PTR instead of "void *".
+ (last_eq): Likewise.
+ * syms.c: Add missing prototypes.
+
+2001-08-09 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * bfd.c: Fix formatting.
+ * bfd-in2.h: Regenerate.
+
+2001-08-09 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * elf32-arc.c (R_ARC_B22_PCREL): Change 'partial_inplace' to
+ true (this target uses REL relocations) and 'pcrel_offset' to
+ false (the PC is implied, not stored in the offset).
+
+2001-08-08 Alan Modra <amodra@bigpond.net.au>
+
+ 1999-10-19 Linus Nordberg <linus@swox.se>
+ * elf-bfd.h (struct elf_backend_data): Add want_got_sym.
+ * elfxx-target.h (elf_backend_want_got_sym): Define.
+ (elfNN_bed): Add elf_backend_want_got_sym.
+ * elflink.c (_bfd_elf_create_got_section): Define
+ _GLOBAL_OFFSET_TABLE_ only if bed->want_got_sym.
+
+2001-08-08 Alexandre Oliva <aoliva@redhat.com>
+
+ * dwarf2.c (struct dwarf2_debug): Add sec, sec_info_ptr and syms.
+ (find_rela_addend): New function.
+ (parse_comp_unit): Call it to find the abbrev offset addend.
+ (_bfd_dwarf2_find_nearest_line): Initialize and maintain the new
+ members of dwarf2_debug as debugging information is read.
+
+2001-08-07 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * coff-sh.c (sh_coff_reloc_type_lookup): Provide for sh-coff
+ targets as well as sh-pe.
+
+2001-08-03 Ben Harris <bjh21@netbsd.org>
+
+ * elf32-arm.h (elf32_arm_final_link_relocate): Include offset of
+ reloc from start of section when computing value for R_ARM_REL32
+ reloc.
+
+2001-08-03 Alan Modra <amodra@bigpond.net.au>
+
+ From H.J. Lu <hjl@gnu.org>
+ * elf32-i386.c (allocate_plt_and_got_and_discard_relocs): Don't
+ keep relocs for undefined syms if there are no dynamic sections in
+ executable.
+ * elf32-hppa.c (allocate_plt_and_got_and_discard_relocs): Likewise.
+
+2001-08-02 Paul Sokolovsky <paul.sokolovsky@technologist.com>
+
+ * cofflink.c (coff_link_check_ar_symbols): also search for
+ __imp__symbol as well as _symbol.
+ * linker.c (_bfd_generic_link_add_archive_symbols): also
+ search for __imp__symbol as well as _symbol.
+
+2001-08-01 Adam Nemet <anemet@lnxw.com>
+
+ * elf.c (elf_sort_sections): Return zero only as the last step.
+
+2001-08-01 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * config.bfd (arm-vxworks): Change name of define from VXWORKS to
+ ARM_COFF_BUGFIX.
+ (arm-epoc-pe): Define ARM_COFF_BUGFIX.
+ coff-arm.c (coff_arm_relocate_section): Replace VXWORKS with
+ ARM_COFF_BUGFIX.
+
+2001-07-30 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * libecoff.h (_bfd_ecoff_styp_to_sec_flags): Changed return type
+ to match corresponding bfd_coff_backend data member.
+
+2001-07-24 Alan Modra <amodra@bigpond.net.au>
+
+ * Makefile.am: Update dependencies with "make dep-am".
+ * Makefile.in: Regenerate
+
+2001-07-15 H.J. Lu <hjl@gnu.org>
+
+ * Makefile.am (po/SRC-POTFILES.in): Use tmp.src instead of tmp.
+ (po/BLD-POTFILES.in): Use tmp.bld instead of tmp.
+ * Makefile.in: Regenerate.
+
+2001-07-11 H.J. Lu <hjl@gnu.org>
+
+ * elf64-alpha.c (elf64_alpha_check_relocs): Set the ALLOC|LOAD
+ flags when creating the reloc section if the ALLOC flag in the
+ source section is set.
+
+2001-07-11 Steve Ellcey <sje@cup.hp.com>
+
+ * reloc.c (bfd_reloc_code_type): Add IA64 relocs
+ BFD_RELOC_IA64_LTOFF_FPTR32MSB and BFD_RELOC_IA64_LTOFF_FPTR32LSB
+ * bfd-in2.h: Regenerate.
+ * libbfd.h: Regenerate.
+ * elfxx-ia64.c (ia64_howto_table): Define how to handle
+ new relocations.
+ (elfNN_ia64_reloc_type_lookup): Handle new relocations.
+ (elfNN_ia64_check_relocs): Likewise.
+ (elfNN_ia64_install_value): Likewise.
+ (elfNN_ia64_relocate_section): Likewise.
+
+2001-07-11 Jakub Jelinek <jakub@redhat.com>
+
+ * elf32-sparc.c (_bfd_sparc_elf_howto_table): Remove support for
+ R_SPARC_UA64.
+ (elf32_sparc_check_relocs): Likewise.
+ Only create .rela section for alloced sections in shared libraries.
+ (elf32_sparc_relocate_section): Likewise.
+ Remove redundant check.
+ Optimize unaligned reloc usage.
+ * elf64-sparc.c (sparc64_elf_relocate_section): Remove redundant
+ check.
+
+2001-07-11 H.J. Lu <hjl@gnu.org>
+
+ * elf64-alpha.c (elf64_alpha_check_relocs): Only use the same
+ ALLOC|LOAD flags as the source section for debugging sections
+ when creating the reloc section.
+
+2001-07-05 Jim Wilson <wilson@redhat.com>
+
+ * linker.c (_bfd_generic_link_add_one_symbol, case BIG): Use
+ the section of the bigger symbol.
+
+ * syms.c (bfd_is_local_label): Return false if BSF_SECTION_SYM.
+
+2001-07-05 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * peicode.h (coff_swap_scnhdr_in): For sections containing
+ uninitialised data, only set their size to s_paddr if this does
+ not reset their size to zero. MS's latest compilers will set
+ s_paddr to zero.
+
+2001-07-04 H.J. Lu <hjl@gnu.org>
+
+ * elf32-mips.c (_bfd_mips_elf_final_write_processing):
+ Handle bfd_mach_mips4400, bfd_mach_mips4600 and
+ bfd_mach_mips5000.
+
+2001-07-03 Mark Elbrecht <snowball3@softhome.net>
+
+ * bfd.c (bfd_get_sign_extend_vma): Support DJGPP COFF targets.
+
+ * cofflink.c (_bfd_coff_link_input_bfd): Skip section symbols from
+ sections being discarded.
+
+2001-06-30 Alan Modra <amodra@bigpond.net.au>
+
+ * elfcore.h (elf_core_file_p): Call bfd_section_from_phdr directly
+ instead of _bfd_elfcore_section_from_phdr.
+ * elf-bfd.h (_bfd_elfcore_section_from_phdr): Remove.
+ * elf.c (_bfd_elfcore_section_from_phdr): Remove.
+ (_bfd_elfcore_make_pseudosection): Expedite tail-call.
+ (elfcore_grok_prstatus): Likewise.
+ (elfcore_grok_lwpstatus): Likewise.
+ (bfd_get_elf_phdr_upper_bound): Likewise.
+ (elfcore_make_note_pseudosection): Formatting.
+ (_bfd_elfcore_strndup): Formatting.
+ * elf32-mips.c (mips_elf_sym_is_global): Formatting.
+ (_bfd_elf32_mips_grok_prstatus): Expedite tail-call.
+
+2001-06-29 Daniel Jacobowitz <drow@mvista.com>
+
+ * elf-bfd.h: Add prototypes for _bfd_elfcore_make_pseudosection
+ and _bfd_elfcore_strndup.
+ (struct elf_backend_data): Add elf_backend_grok_prstatus
+ and elf_backend_grok_psinfo.
+ * elf.c (_bfd_elfcore_make_pseudosection): New function.
+ (elfcore_grok_prstatus): Use it.
+ (elfcore_make_note_pseudosection): Likewise.
+ (elfcore_strndup): Rename to...
+ (_bfd_elfcore_strndup): Here, and make global.
+ (elfcore_grok_psinfo): Use _bfd_elfcore_strndup.
+ (elfcore_grok_note): Call elf_backend_grok_prstatus
+ and elf_backend_grok_psinfo if available.
+ * elf32-mips.c (_bfd_elf32_mips_grok_prstatus): New function.
+ (_bfd_elf32_mips_grok_psinfo): New function.
+ (elf_backend_grok_prstatus): Define.
+ (elf_backend_grok_psinfo): Define.
+ * elfxx-target.h (elf_backend_grok_prstatus): Default to NULL.
+ (elf_backend_grok_psinfo): Likewise.
+ (elfNN_bed): Include elf_backend_grok_prstatus and
+ elf_backend_grok_psinfo.
+
+2001-06-29 H.J. Lu <hjl@gnu.org>
+
+ * elf32-hppa.c (elf32_hppa_finish_dynamic_sections): Check if
+ hplink->sgot is NULL before filling GOT. Check if hplink->splt
+ is NULL before filling PLT.
+
+2001-06-29 Alan Modra <amodra@bigpond.net.au>
+
+ * elflink.h (elf_link_output_extsym): Revert 1999-04-10.
+
+2001-06-27 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-hppa.c (elf32_hppa_check_relocs): Don't make syms dynamic
+ here..
+ (elf32_hppa_adjust_dynamic_symbol): ..nor here..
+ (allocate_plt_and_got_and_discard_relocs): .. instead do so here
+ after gc has run.
+
+ * elf32-hppa.c (RELATIVE_DYNAMIC_RELOCS): Delete.
+ (IS_ABSOLUTE_RELOC): Define.
+ (elf32_hppa_link_hash_entry): Always include reloc_entries field.
+ (hppa_link_hash_newfunc): Always init it.
+ (elf32_hppa_check_relocs): Mark symbols as ELF_LINK_NON_GOT_REF to
+ create COPY relocs only when the reloc is in a read-only section.
+ Instead, allocate space for a dynamic reloc to reference the
+ library symbol directly. Keep track of space we allocate using
+ relocs_entries.
+ (hppa_discard_copies): Delete, and move code to..
+ (allocate_plt_and_got): ..here. Rename to
+ allocate_plt_and_got_and_discard_relocs. Remove unneeded dynamic
+ relocs for non-shared link.
+ (elf32_hppa_size_dynamic_sections): Update calls to above.
+ (elf32_hppa_relocate_section): Write out the dynamic relocs used
+ in lieu of COPY relocs.
+
+ * elf32-i386.c (elf_i386_check_relocs): Don't make syms dynamic
+ here..
+ (elf_i386_adjust_dynamic_symbol): ..nor here..
+ (allocate_plt_and_got_and_discard_relocs): .. instead do so here
+ after gc has run.
+ (elf_i386_size_dynamic_sections): Fix a comment.
+ (elf_i386_relocate_section <R_386_32, R_386_PC32>): Rearrange code
+ involved in writing reloc out.
+
+2001-06-25 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-i386.c (elf_i386_check_relocs <R_386_32, R_386_PC32>):
+ Ensure syms are dynamic if we might be emitting a reloc.
+ (allocate_plt_and_got_and_discard_relocs): Don't discard relocs
+ for undefweak or undefined syms..
+ (elf_i386_relocate_section <R_386_32, R_386_PC32>): .. and emit.
+
+ * elf32-i386.c (allocate_plt_and_got_and_discard_relocs): Discard
+ relocs without ELF_LINK_HASH_DEF_DYNAMIC set.
+ (elf_i386_relocate_section <R_386_32, R_386_PC32>): Remove
+ redundant bfd_link_hash_defined, bfd_link_hash_defweak test.
+
+2001-06-24 H.J. Lu <hjl@gnu.org>
+
+ * cpu-i960.c (scan_960_mach): Don't modify const char *. Use
+ strncasecmp/strcasecmp instead of strncmp/strcmp.
+
+2001-06-23 H.J. Lu <hjl@gnu.org>
+
+ * elf32-i386.c (elf_i386_relocate_section <R_386_32, R_386_PC32>):
+ Check ELF_LINK_HASH_DEF_DYNAMIC to see if a symbol is not defined
+ in the regular object file and treat the weak definition as
+ the normal one.
+
+2001-06-23 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-i386.c (elf_i386_relocate_section <R_386_GOT32>): Tighten
+ unresolved_reloc test to exclude cases where we use "relocation"
+ before setting it to point into the .got. Reinstate fudge for
+ unresolved relocs in debugging sections.
+
+ * elf32-i386.c (elf_i386_relocate_section): Replace ugly
+ complicated tests for unresolvable relocs with a simple direct
+ scheme using "unresolved_reloc" var.
+
+ * elf32-i386.c (struct elf_i386_pcrel_relocs_copied): Rename to
+ elf_i386_dyn_relocs. Update comment.
+ (struct elf_i386_link_hash_entry): Rename pcrel_relocs_copied to
+ dyn_relocs.
+ (elf_i386_adjust_dynamic_symbol): Remove a BFD_ASSERT, change
+ others to aborts.
+ (allocate_plt_and_got_and_discard_relocs): Replace BFD_ASSERT with
+ abort.
+ (elf_i386_size_dynamic_sections): Likewise.
+ (elf_i386_finish_dynamic_symbol): Likewise.
+ (elf_i386_finish_dynamic_sections): Likewise.
+ (elf_i386_relocate_section): Likewise. Tidy R_386_GOT32 and error
+ handling code.
+
+ Avoid creating COPY relocs if possible.
+ * elf32-i386.c (elf_i386_check_relocs): Tweak condition under
+ which .got created. Mark symbols used by R_386_32 and R_386_PC32
+ relocs as ELF_LINK_NON_GOT_REF to create COPY relocs only when the
+ reloc is in a read-only section. Instead, allocate space for a
+ dynamic reloc to reference the library symbol directly. Keep
+ track of space we allocate using pcrel_relocs_copied.
+ (discard_copies): Delete, and move code to ..
+ (allocate_plt_and_got): ..here. Rename to
+ allocate_plt_and_got_and_discard_relocs. Remove unneeded dynamic
+ relocs for non-shared link.
+ (elf_i386_size_dynamic_sections): Update calls to above functions.
+ (elf_i386_relocate_section): Write out the dynamic relocs. Add
+ more ugly logic to avoid "unresolvable relocation" error. Use
+ htab shortcut in place of elf_hash_table macro.
+ (elf_i386_finish_dynamic_sections): Allow that dynamic .got may
+ not always be created now.
+
+2001-06-20 Bo Thorsen <bo@suse.co.uk>
+
+ * elf64-x86-64.c (elf64_x86_64_relocate_section): Fix linking of
+ shared libraries.
+
+2001-06-18 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * configure.host (mips64-*-linux): Reformat.
+
+2001-06-21 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-hppa.c (elf32_hppa_size_dynamic_sections): Always
+ allocate local .got space. Use shortcuts from hash table for .got
+ and .plt rather than comparing section names.
+ (elf32_hppa_check_relocs): Use local_plt_refcounts var rather than
+ adjusting index into local_got_refcounts to document what we are
+ really doing.
+ (elf32_hppa_relocate_section): Similarly for local_plt_offsets.
+ Tidy .got and .plt error checking.
+
+2001-06-20 Catherine Moore <clm@redhat.com>
+
+ * elf-bfd.h (struct elf_backend_data):
+ elf_backend_emit_relocs: New field: Function for emitting
+ relocs.
+ elf_backend_count_relocs: New field: Function for determining
+ the number of relocs to be emitted.
+ * elfxx-target.h: Provide default (NULL) values for
+ elf_backend_emit_relocs and elf_backend_count_relocs.
+ * elflink.h (elf_link_size_reloc_section): Make the hash table
+ big enough to hold the relocs counted by either reloc_count or
+ o->reloc_count.
+ (elf_bfd_final_link) emit_relocs: New boolean, set if relocs
+ should be emitted, either because of a command line option
+ stored in the info structure or because the target provides a
+ special reloc emitting function.
+ If the target provides a reloc counting function use it,
+ unless performing a relocatable link or emitting all relocs.
+ Also set the SEC_RELOC flag on any output section which will
+ contain relocs.
+ (elf_link_input_bfd): emit_relocs: New boolean, set if relocs
+ should be emitted, either because of a command line option
+ stored in the info structure or because the target provides a
+ special reloc emitting function.
+ If the target provides a reloc emitting function, use it,
+ unless performing a relocatable link or emitting all relocs.
+
+2001-06-20 H.J. Lu <hjl@gnu.org>
+
+ * elf32-i386.c (elf_i386_size_dynamic_sections): Always
+ allocate local .got space.
+
+2001-06-19 Andreas Jaeger <aj@suse.de>
+
+ * elf64-x86-64.c (elf64_x86_64_relocate_section): Fix creation of
+ dynamic symbols.
+
+2001-06-18 Hans-Peter Nilsson <hp@axis.com>
+
+ * elflink.h (struct elf_assign_sym_version_info): Remove member
+ export_dynamic. All users changed to use info member.
+ NAME(bfd_elf,size_dynamic_sections)): Remove parameter
+ export_dynamic, instead use member in parameter info.
+ * bfd-in.h (bfd_elf32_size_dynamic_sections,
+ bfd_elf64_size_dynamic_sections): Update prototype.
+ * bfd-in2.h: Regenerate.
+
+2001-06-18 H.J. Lu <hjl@gnu.org>
+
+ * elflink.h (elf_info_failed): Add a new field, verdefs.
+ (NAME(bfd_elf,size_dynamic_sections): Pass verdefs to
+ elf_export_symbol.
+ (elf_export_symbol): Check eif->verdefs to decide if a symbol
+ should be exported.
+
+2001-06-17 H.J. Lu <hjl@gnu.org>
+
+ * elf32-mips.c (mips_elf_link_hash_entry): Add a new field,
+ readonly_reloc, to record if a relocation in the .rel.dyn
+ section is against a read-only section.
+ (mips_elf_link_hash_newfunc): Initialize the readonly_reloc
+ field to false.
+ (_bfd_mips_elf_check_relocs): Record if there is a relocation
+ in the .rel.dyn section against a read-only section by setting
+ DF_TEXTREL or readonly_reloc.
+ (_bfd_mips_elf_copy_indirect_symbol): Copy readonly_reloc if
+ it is true.
+ (_bfd_mips_elf_adjust_dynamic_symbol): Record DF_TEXTREL if
+ there is a relocation in the .rel.dyn section against a
+ read-only section.
+ (_bfd_mips_elf_size_dynamic_sections): Set DT_TEXTREL if
+ DF_TEXTREL is set.
+
+2001-06-12 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * coffcode.h (styp_flags_to_sec_flags): Change to a boolean
+ function. Move flagword result into parameter list. Remove
+ comment about setting bfd_error_handler to intercept failure
+ results.
+ * coffgen.c (make_a_section_from_file): Examine result of
+ calling bfd_coff_styp_to_sec_flags and pass a failure back to
+ caller.
+ * ecoff.h (styp_flags_to_sec_flags): Change to a boolean
+ function. Move flagword result into parameter list.
+ * libcoff.h: Regenerate.
+ * libecoff.h: Regenerate.
+
+2001-06-13 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * aoutx.h (adjust_z_magic): Only pad the tesxt section if the data
+ section is going to follow it.
+
+2001-06-12 Catherine Moore <clm@redhat.com>
+
+ * elflink.h (elf_gc_propagate_vtable_entries): Replace FILE_ALIGN
+ with the file_align entry from elf_backend_data.
+ (elf_gc_smash_unused_vtentry_relocs): Likewise.
+ (elf_gc_record_vtentry): Likewise.
+
+2001-06-10 Alan Modra <amodra@bigpond.net.au>
+
+ * elflink.h: Whitespace changes.
+ (elf_link_read_relocs_from_section): Use "unsigned int" iterator
+ rather than "unsigned char".
+ (elf_link_output_relocs): Likewise.
+ (elf_link_input_bfd): Likewise.
+ (elf_reloc_link_order): LIkewise.
+ * elf.c: s/CONST/const/. Whitespace changes.
+ * elf32-mips.c: Formatting fix.
+
+ * Makefile.am (SOURCE_HFILES): Include xcoff-target.h, remove xcoff.h.
+ * Makefile.in: Regenerate.
+ * po/Make-in: Remove trailing tab.
+
+2001-06-09 Philip Blundell <philb@gnu.org>
+
+ * elf32-arm.h (elf32_arm_plt0_entry): Correct error in last
+ change.
+ (elf32_arm_plt_entry): Likewise.
+
+2001-06-08 H.J. Lu <hjl@gnu.org>
+
+ * elf.c (swap_out_syms): Keep names for global section symbols.
+
+2001-06-07 H.J. Lu <hjl@gnu.org>
+
+ * config.bfd: Put back ecoff for Linux/mips. Firmwares on some
+ MIPS-based machines need it.
+
+2001-06-07 H.J. Lu <hjl@gnu.org>
+
+ * elf32-mips.c (_bfd_mips_elf_object_p): Set the bad symtab
+ for SGI only.
+
+ * config.bfd: Remove ecoff from Linux/mips.
+
+2001-06-07 Andreas Jaeger <aj@suse.de>
+
+ * elf64-x86-64.c (elf64_x86_64_finish_dynamic_symbol): Add an
+ assertion.
+ (elf64_x86_64_check_relocs): Fix VTENTRY relocation; set an
+ alignment of 8 for .rela sections; handle further relocations.
+
+2001-06-06 Christian Groessler <cpg@aladdin.de>
+
+ * coff-z8k.c: Fix formatting.
+ Fix howtos: howto->size was always 1.
+
+2001-06-05 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * configure.host (mips64*-*-linux*): Define.
+
+2001-06-05 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-i386.c (elf_i386_discard_copies): Rename to
+ discard_copies, and use elf_link_hash_entry arg rather than
+ elf_i386_link_hash_entry.
+ (elf_i386_link_hash_traverse): Delete.
+ (elf_i386_size_dynamic_sections): Adjust call to discard_copies.
+ Tidy sizing of dynamic sections.
+ (elf_i386_check_relocs <R_386_32, R_386_PC32>): Reference count
+ possible .plt entries.
+ (elf_i386_gc_sweep_hook): Likewise.
+ (elf_i386_adjust_dynamic_symbol): Discard .plt entries for
+ everything with plt.refcount <= 0.
+
+ * elf32-i386.c (elf_i386_check_relocs): Don't allocate .got and
+ .relgot space here.
+ (elf_i386_gc_sweep_hook): ..and no need to deallocate here..
+ (elf_i386_adjust_dynamic_symbol): ..and don't allocate .plt and
+ .rel.plt here..
+ (allocate_plt_and_got): ..instead do it all here. New function.
+ (elf_i386_size_dynamic_sections): Allocate local .got space and
+ call allocate_plt_and_got. No need to zap .relgot if not dynamic.
+ (bfd_elf32_bfd_final_link): Delete. (ie. use regular final link
+ rather than gc variety).
+ (WILL_CALL_FINISH_DYNAMIC_SYMBOL): Define.
+ (elf_i386_relocate_section): Use it here and correct handling of
+ R_386_GOT32. Provide section and offset for "unresolvable
+ relocation" error message.
+ (elf_i386_finish_dynamic_symbol): Correct handling of R_386_GOT32.
+
+ * elf32-i386.c (struct elf_i386_link_hash_table): Add sgot,
+ sgotplt, srelgot, splt, srelplt, sdynbss, srelbss fields.
+ (elf_i386_link_hash_table_create): Init them.
+ (create_got_section): New function.
+ (elf_i386_create_dynamic_sections): New function.
+ (elf_backend_create_dynamic_sections): Set to above.
+ (elf_i386_check_relocs): Use shortcuts from hash table rather than
+ calling bfd_get_section_by_name.
+ (elf_i386_gc_sweep_hook): Likewise.
+ (elf_i386_adjust_dynamic_symbol): Likewise.
+ (elf_i386_size_dynamic_sections): Likewise.
+ (elf_i386_relocate_section): Likewise.
+ (elf_i386_finish_dynamic_sections): Likewise.
+
+ * elf32-hppa.c (allocate_plt_and_got): Skip indirect and warning syms.
+
+2001-06-02 H.J. Lu <hjl@gnu.org>
+
+ * elf32-hppa.c (elf32_hppa_object_p): Check ELFOSABI_LINUX
+ and ELFOSABI_HPUX.
+ * elf64-hppa.c (elf64_hppa_object_p): Likewise.
+
+2001-06-02 H.J. Lu <hjl@gnu.org>
+
+ * aout-cris.c (MACHTYPE_OK): New. Defined.
+
+2001-06-02 Hans-Peter Nilsson <hp@axis.com>
+
+ * section.c (_bfd_strip_section_from_output): Handle NULL
+ output_section.
+
+2001-06-02 H.J. Lu <hjl@gnu.org>
+
+ * config.bfd (powerpc-*-aix*, powerpc-*-beos*, rs6000-*-*): Add
+ rs6000coff64_vec only if BFD64 is defined.
+ (powerpc64-*-aix*): Enable only if BFD64 is defined.
+
+2001-06-02 H.J. Lu <hjl@gnu.org>
+
+ * coff-ia64.c (ia64coff_object_p): Rewrite with
+ external_PEI_DOS_hdr and external_PEI_IMAGE_hdr.
+
+2001-06-01 Andreas Jaeger <aj@suse.de>
+
+ * elf64-x86-64.c (elf64_x86_64_relocate_section): Add PC8
+ relocation, small reformatting.
+
+2001-05-29 Andreas Jaeger <aj@suse.de>
+
+ * elf64-x86-64.c (elf64_x86_64_check_relocs): Handle R_X86_64_64.
+ (elf64_x86_64_relocate_section): Likewise.
+
+2001-05-30 Alan Modra <amodra@one.net.au>
+
+ * elf32-hppa.c (elf32_hppa_check_relocs): Don't NEED_PLT for
+ millicode. Don't allocate .got and .rela.got space here..
+ (elf32_hppa_gc_sweep_hook): ..and no need to deallocate here..
+ (elf32_hppa_adjust_dynamic_symbol): ..and don't allocate .plt and
+ .rela.plt here..
+ (hppa_handle_PIC_calls): ..nor here..
+ (allocate_plt_and_got): ..instead do it all here. New function.
+ (elf32_hppa_size_dynamic_sections): Allocate local .got space and
+ call allocate_plt_and_got. No need to zap .got if not dynamic.
+ (elf32_hppa_final_link): Call regular bfd_final_link instead of
+ gc_common_final_link.
+ (WILL_CALL_FINISH_DYNAMIC_SYMBOL): Define.
+ (elf32_hppa_relocate_section): Use it here.
+ (elf32_hppa_finish_dynamic_symbol): Remove superfluous test of
+ dynamic_sections_created.
+ (hppa_type_of_stub): Don't LONG_BRANCH_VIA_PLT if millicode sym.
+
+2001-05-28 Andreas Jaeger <aj@suse.de>
+
+ * elf64-x86-64.c (elf64_86_64_size_info): Remove, we can use the
+ generic version since we want a hashsize of 4.
+ (elf_backend_size_info): Likewise.
+
+2001-05-28 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * elflink.h (elf_link_size_reloc_section): Use bfd_zmalloc instead of
+ a zeroing loop.
+ (elf_link_output_relocs): Handle MIPS ELF64 relocations correctly.
+ (elf_link_input_bfd): Likewise.
+ (elf_reloc_link_order): Likewise.
+ (elf_finish_pointer_linker_section): Typo. Handle MIPS ELF64
+ relocations correctly.
+
+2001-05-28 Nicolas Pitre <nico@cam.org>
+
+ * elf32-arm.h: fix PLT generation for big endian ARM
+
+2001-05-28 Alan Modra <amodra@one.net.au>
+
+ * elf32-hppa.c (elf32_hppa_relocate_section): Set up .plt entries
+ for symbols forced local that need plabels.
+ (elf32_hppa_adjust_dynamic_symbol): Don't allocate space in
+ .plt.rela for local syms if non-shared.
+ (hppa_build_one_stub): Mask lsb of plt.offset.
+ (elf32_hppa_finish_dynamic_symbol): Abort if lsb of plt.offset set.
+ (clobber_millicode_symbols): Correct comment.
+ (elf32_hppa_relocate_section): Likewise.
+ (elf32_hppa_finish_dynamic_symbol): Likewise.
+
+2001-05-28 Jeff Sturm <jsturm@one-point.com>
+
+ * reloc.c: Add BFD_RELOC_SPARC_UA16 and BFD_RELOC_SPARC_UA64.
+ * bfd-in2.h: Regenerate.
+ * libbfd.h: Regenerate.
+ * elf32-sparc.c: Enable BFD_RELOC_SPARC_UA16, BFD_RELOC_SPARC_UA32
+ and BFD_RELOC_SPARC_UA64 mapping
+ * elf64-sparc.c: Likewise.
+
+2001-05-25 H.J. Lu <hjl@gnu.org>
+
+ * Makefile.am (BFD32_BACKENDS): Remove coff-pmac.lo.
+ (BFD32_BACKENDS_CFILES): Remove coff-pmac.c.
+ (coff-rs6000.lo): Remove the old dependency.
+ * Makefile.in: Rebuild.
+
+ * configure.in (pmac_xcoff_vec): Replace coff-pmac.lo with
+ coff-rs6000.lo.
+
+2001-05-25 H.J. Lu <hjl@gnu.org>
+
+ * coff-rs6000.c (rs6000coff_vec): Use rs6000coff_core_p,
+ rs6000coff_core_file_matches_executable_p,
+ rs6000coff_core_file_failing_command and
+ rs6000coff_core_file_failing_signal only if AIX_CORE is
+ defined.
+ (pmac_xcoff_vec): Likewise.
+ * coff64-rs6000.c (rs6000coff64_vec): Likewise.
+
+2001-05-25 Timothy Wall <twall@redhat.com>
+
+ * elfxx-ia64.c (allocate_dynrel_entries): Don't allocate an entry
+ for __GLOB_DATA_PTR on AIX5. Clean up some relocation bugs.
+
+2001-05-25 H.J. Lu <hjl@gnu.org>
+
+ * bfd-in2.h: Regenerated.
+ * libcoff.h: Likewise.
+
+2001-05-25 Alan Modra <amodra@one.net.au>
+
+ * elf32-hppa.c (elf32_hppa_relocate_section): Don't allow
+ undefined millicode syms in shared libs.
+ (hppa_build_one_stub): Turn BFD_ASSERTs into aborts.
+ (elf32_hppa_check_relocs): Likewise.
+ (elf32_hppa_adjust_dynamic_symbol): Likewise.
+ (elf32_hppa_size_dynamic_sections): Likewise.
+ (elf32_hppa_relocate_section): Likewise.
+ (elf32_hppa_finish_dynamic_symbol): Likewise.
+ (elf32_hppa_finish_dynamic_sections): Likewise.
+
+2001-05-24 Tom Rix <trix@redhat.com>
+
+ * Makefile.am coff-pmac bfd now defined in coff-rs6000.c
+ xcoff-target.h not used to define rs6000 or ppc bfd.
+ * Makefile.in same
+
+ * bfd-in.h : (struct lineno_cache_entry) promote element "offset"
+ to 64 bit.
+
+ * coff-rs6000.c : Many changes for 64 bit support. Move common
+ 32/64 code to xcofflink.c. Explictly define the rs6000coff_vec
+ and pmac_xcoff_vec
+
+ * coff64-rs6000.c : Many changes for 64 bit support. 64 bit
+ linker now supported. Explictly define the rs6000coff64_vec.
+
+ * coffcode.h : (coff_set_arch_mach_hook) xcoff 64 bit support
+ (coff_print_aux) same
+ (coff_write_object_contents) same
+ (coff_slurp_line_table) same
+
+ * coffgen.c : (coff_fix_symbol_name) formatting
+ (coff_mangle_symbols) xcoff 64 bit support
+ (coff_write_symbol) same
+ (coff_write_alien_symbol) same
+ (coff_write_native_symbol) same
+ (coff_write_symbols) same
+ (coff_get_symbol_info) same
+ (bfd_coff_get_syment) same
+ (coff_print_symbol) same
+
+ * config.bfd : add powerpc64-*-aix* target
+
+ * libcoff-in.h : formatting
+
+ * libcoff.h : move xcoff extern declarations to libxcoff.h
+
+ * libxcoff.h : New file
+
+ * xcofflink.c : Many changes for xcoff64 support. Move common
+ structures to include/coff/xcoff.h. Move specific structure to
+ backends coff-rs6000.c and coff64-rs6000.c. Use new backend
+ functions, defined in libxcoff.h, to isolate 32/64 dependencies.
+
+ (bfd_xcoff_size_dynamic_sections) : special __rtinit symbol for
+ aix4.2+ -binitfini.
+
+ (xcoff_build_ldsyms) : handle special __rtinit symbol.
+
+2001-05-23 Alexandre Oliva <aoliva@redhat.com>
+
+ * elf64-sparc.c (sparc64_elf_slurp_reloc_table): Fix typo
+ s/ENTIRES/ENTRIES/.
+
+2001-05-23 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * reloc.c (bfd_reloc_code_real): Add MIPS ELF64 relocations.
+ * libbfd.h: Regenerate.
+ * bfd-in2.h: Regenerate.
+
+ * aoutx.h (aout_@var{size}_machine_type): Add MIPS r12k support.
+ * archures.c (bfd_mach_mips12000): Define.
+ * cpu-mips.c (arch_info_struct): Add MIPS r12k support.
+ * elf32-mips.c (_bfd_mips_elf_final_write_processing): Add MIPS r12k
+ support.
+ (_bfd_mips_elf_size_dynamic_sections): Use official bfd typedef.
+ * bfd-in2.h: Regenerate.
+ * elfxx-target.h: Do not redefine bfd_elfNN_bfd_make_debug_symbol.
+
+2001-05-23 kaz Kojima <kkojima@rr.iij4u.or.jp>
+
+ * elf32-sh.c (elf_sh_plt0_entry_be, elf_sh_plt0_entry,
+ elf_sh_plt_entry_be, elf_sh_plt_entry, elf_sh_pic_plt_entry_be,
+ elf_sh_pic_plt_entry): New PLT code, that does not use r2, since
+ that is used by GCC.
+
+2001-05-23 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * elf-bfd.h (NUM_SHDR_ENTRIES): New macro: compute the number
+ of entries in a structured section.
+ * elf.c: Use new macro.
+ * elf32-i386.c: Use new macro.
+ * elf32-mips.c: Use new macro.
+ * elf64-alpha.c: Use new macro.
+ * elf64-sparc.c: Use new macro.
+ * elfcode.h: Use new macro.
+ * elflink.h: Use new macro.
+
+2001-05-23 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * bfdint.texi: Replace -oformat with --oformat.
+
+2001-05-21 Andreas Jaeger <aj@suse.de>
+
+ * dwarf2.c (decode_line_info): Fix error message.
+ (read_abbrevs): Fix test for offset as suggested by Alan Modra and
+ adjust error message.
+
+2001-05-18 H.J. Lu <hjl@gnu.org>
+
+ * elflink.h (elf_link_add_object_symbols): Revert the last
+ change.
+
+2001-05-17 Alan Modra <amodra@one.net.au>
+
+ * elf32-hppa.c (clobber_millicode_symbols): Temporarily set
+ ELF_LINK_FORCED_LOCAL to suit 2001-04-30 change.
+ (hppa_build_one_stub): Add an assert to check plt.offset.
+
+2001-05-17 H.J. Lu <hjl@gnu.org>
+
+ * elflink.h (NAME(bfd_elf,size_dynamic_sections)): Set the
+ version definition to basename of the output filename.
+
+2001-05-17 H.J. Lu <hjl@gnu.org>
+
+ * elflink.h (elf_link_add_object_symbols): Set DT_NEEDED to
+ basename of the bfd filename.
+
+2001-05-16 Alan Modra <amodra@one.net.au>
+
+ * section.c (asection): Add linker_has_input field.
+ (STD_SECTION): Adjust initialization to suit.
+ * ecoff.c (bfd_debug_section): Likewise.
+ * bfd-in2.h: Regenerate.
+
+2001-05-15 Alexandre Oliva <aoliva@redhat.com>
+
+ * elf-m10300.c (mn10300_elf_relax_section): Don't relax
+ negative 32-bit operands to 16 operands when the operand is
+ going to be zero-extended by the modified opcode.
+
+2001-05-12 Peter Targett <peter.targett@arccores.com>
+
+ * cpu-arc.c (arch_info_struct): Add entry 'base' representing old
+ name for 'arc5' core versions.
+ (bfd_arc_arch): Make bfd_mach_arc_6 default.
+
+ * elf32-arc.c (arc_elf_object_p): Make E_ARC_MACH_ARC6 default
+ architecture.
+ (arc_elf_final_write_processing): Make bfd_mach_arc_6 default.
+
+2001-05-11 Jakub Jelinek <jakub@redhat.com>
+
+ * elfxx-ia64.c (is_unwind_section_name): Consider linkonce unwind
+ sections as well.
+ (elfNN_ia64_final_write_processing): Map .gnu.linkonce.ia64unw.FOO
+ to .gnu.linkonce.t.FOO text section.
+
+2001-05-11 Jakub Jelinek <jakub@redhat.com>
+
+ * merge.c (struct sec_merge_hash_entry): Add u.entsize and u.suffix
+ fields, change sec into secinfo.
+ (struct sec_merge_info): Add chain, remove last fields.
+ (struct sec_merge_sec_info): Add next, sec, psecinfo fields.
+ (sec_merge_hash_lookup): If lookup could not use a string only
+ because it has bad alignment, mark the old string for deletion.
+ (sec_merge_add): Add secinfo argument. Don't compute entry's
+ position, instead record the section.
+ (sec_merge_emit): Update for the sec into secinfo change in
+ struct sec_merge_hash_entry.
+ (_bfd_merge_section): Only record the section for merging, defer
+ putting strings into the hash table.
+ (cmplengthentry, last4_eq, last_eq, record_section, merge_strings,
+ _bfd_merge_sections): New functions.
+ (_bfd_merged_section_offset): Update for the sec_merge_hash_entry
+ changes.
+ * libbfd-in.h (_bfd_merge_sections): Add prototype.
+ (_bfd_nolink_bfd_merge_sections): Define.
+ * libbfd.h: Likewise.
+ (bfd_generic_merge_sections): Add prototype.
+ * targets.c (BFD_JUMP_TABLE_LINK): Add _bfd_merge_sections.
+ (struct bfd_target): Likewise.
+ * bfd.c (bfd_merge_sections): Define.
+ * bfd-in2.h: Rebuilt.
+ * elf.c (_bfd_elf_merge_sections): New function.
+ * elf-bfd.h (_bfd_elf_merge_sections): Add prototype.
+ * elfxx-target.h (bfd_elfNN_bfd_merge_sections): Define.
+ * reloc.c (bfd_generic_merge_sections): New function.
+ * vms.c (vms_bfd_merge_sections): New function.
+ * aout-adobe.c (aout_32_bfd_merge_sections): Define.
+ * aout-target.h (MY_bfd_merge_sections): Define.
+ * aout-tic30.c (MY_bfd_merge_sections): Define.
+ * binary.c (binary_bfd_merge_sections): Define.
+ * bout.c (b_out_bfd_merge_sections): Define.
+ * coff-alpha.c (_bfd_ecoff_bfd_merge_sections): Define.
+ * coffcode.c (coff_bfd_merge_sections): Define.
+ * coff-mips.c (_bfd_ecoff_bfd_merge_sections): Define.
+ * i386msdos.c (msdos_bfd_merge_sections): Define.
+ * i386os9k.c (os9k_bfd_merge_sections): Define.
+ * ieee.c (ieee_bfd_merge_sections): Define.
+ * ihex.c (ihex_bfd_merge_sections): Define.
+ * nlm-target.h (nlm_bfd_merge_sections): Define.
+ * oasys.c (oasys_bfd_merge_sections): Define.
+ * ppcboot.c (ppcboot_bfd_merge_sections): Define.
+ * som.c (som_bfd_merge_sections): Define.
+ * srec.c (srec_bfd_merge_sections): Define.
+ * tekhex.c (tekhex_bfd_merge_sections): Define.
+ * versados.c (versados_bfd_merge_sections): Define.
+ * xcoff-target.h (_bfd_xcoff_bfd_merge_sections): Define.
+
+2001-05-11 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * dwarf1.c (_bfd_dwarf1_find_nearest_line): Change type of 'addr'
+ to be unsigned long, in order to match its use.
+
+2001-05-10 H.J. Lu <hjl@gnu.org>
+
+ * linker.c (_bfd_generic_link_add_one_symbol): Check loop on
+ indirect symbols.
+
+2001-05-09 H.J. Lu <hjl@gnu.org>
+
+ * elflink.h (elf_link_add_object_symbols): Fix a typo. Allocate
+ versymhdr->sh_size bytes for extversym instead of hdr->sh_size.
+ Remove the unused veriable `dynver'.
+
+2001-05-08 Ian Lance Taylor <ian@zembu.com>
+
+ * coff-i386.c (coff_i386_reloc): Don't dump core if output_bfd is
+ NULL or is not COFF.
+ (coff_i386_rtype_to_howto): Don't dump core if output section
+ owner is not COFF.
+
+2001-05-07 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * ecoff.c (bfd_debug_section): Fix initialization.
+ * elf.c (_bfd_elf_slurp_version_tables): Change maxidx to unsigned, it
+ is always a positive integer. Cast away sign mismatch.
+ * elf32-mips.c: Fix misleading comment and typo.
+ (_bfd_mips_elf_section_from_bfd_section): Remove unused attribute, use
+ correct data type.
+ * elflink.c: Fix typo.
+ (_bfd_elf_create_dynamic_sections): Remove superfluous initialization.
+ * ecoffswap.h (ecoff_swap_fdr_in): Cast away sign mismatch.
+
+2001-05-04 Richard Henderson <rth@redhat.com>
+
+ * elf64-alpha.c (SREL16, SREL32, SREL64): Set pcrel_offset true.
+
+2001-05-04 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * elf32-arm.h (elf32_arm_final_link_relocate): Set
+ EF_ARM_HASENTRY if the start address is set.
+
+2001-05-03 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * targets.c (_bfd_target_vector_entries): Compute value based on
+ the size of the _bfd_target_vector and not bfd_target_vector.
+
+2001-05-03 H.J. Lu <hjl@gnu.org>
+
+ * elfcode.h: Include "libiberty.h".
+
+ * elflink.h (elf_link_add_object_symbols): Set
+ elf_dt_name (abfd) to basename of the bfd filename.
+ (NAME(bfd_elf,size_dynamic_sections)): Set vn_file to basename
+ of the bfd filename.
+
+2001-05-03 Andreas Jaeger <aj@suse.de>
+
+ * elf64-gen.c (elf_generic_info_to_howto): Add unused attribute.
+ (elf_generic_info_to_howto_rel): Likewise.
+ * coff-alpha.c (reloc_nil): Likewise.
+ (alpha_ecoff_bad_format_hook): Likewise.
+ (alpha_adjust_reloc_out): Likewise.
+ (alpha_bfd_reloc_type_lookup): Likewise.
+ (alpha_convert_external_reloc): Likewise.
+ * elf64-alpha.c (elf64_alpha_reloc_nil): Likewise.
+ (elf64_alpha_reloc_bad): Likewise.
+ (elf64_alpha_reloc_gpdisp): Likewise.
+ (elf64_alpha_bfd_reloc_type_lookup): Likewise.
+ (elf64_alpha_info_to_howto): Likewise.
+ (elf64_alpha_add_symbol_hook): Likewise.
+ (elf64_alpha_create_got_section): Likewise.
+ (elf64_alpha_is_local_label_name): Likewise.
+ (elf64_alpha_merge_ind_symbols): Likewise.
+ * elf64-mips.c (mips_elf64_reloc_type_lookup): Likewise.
+ (mips_elf64_get_reloc_upper_bound): Likewise.
+ * nlm32-alpha.c (nlm_alpha_mangle_relocs): Likewise.
+ (nlm_alpha_get_public_offset): Likewise.
+
+2001-05-02 Johan Rydberg <jrydberg@opencores.org>
+
+ * elf32-openrisc.c (openrisc_elf_howto_table): Do not complain
+ about overflow in R_OPENRISC_LO_16_IN_INSN and
+ R_OPENRISC_HI_16_IN_INSN.
+
+2001-04-30 H.J. Lu <hjl@gnu.org>
+
+ * elf.c (_bfd_elf_link_hash_hide_symbol): Set dynindx to -1
+ only for ELF_LINK_FORCED_LOCAL.
+ * elf32-hppa.c (elf32_hppa_hide_symbol): Likewise.
+ * elf32-mips.c (_bfd_mips_elf_hide_symbol): Likewise.
+ * elfxx-ia64.c (elfNN_ia64_hash_hide_symbol): Likewise.
+
+ * elflink.h (elf_fix_symbol_flags): Set ELF_LINK_FORCED_LOCAL
+ if the symbol has hidden or internal visibility.
+
+2001-04-30 Alan Modra <amodra@one.net.au>
+
+ * elf32-hppa.c (final_link_relocate): Branch to .+8 for
+ calls to undefined weak symbols.
+
+2001-04-30 Andreas Jaeger <aj@suse.de>, Andreas Schwab <schwab@suse.de>
+
+ * elf64-x86-64.c (elf64_x86_64_relocate_section): Correct test for
+ R_X86_64_GOTPCREL, don't use assignments instead of comparisons.
+
+2001-04-27 Andreas Jaeger <aj@suse.de>
+
+ * elf64-x86-64.c (elf64_x86_64_finish_dynamic_sections): Only swap
+ out handled entries.
+ (elf64_x86_64_finish_dynamic_symbol): Set up GOT entries.
+ (elf64_x86_64_relocate_section): Fix GOTPCREL calculation.
+ (elf64_x86_64_relocate_section): Merge entries for GOTPCREL and
+ GOT32.
+
+2001-04-27 Sean McNeil <sean@mcneil.com>
+
+ * config.bfd: Add arm-vxworks target.
+ * coff-arm (coff_arm_relocate_section): Add in symbol value to
+ addend (fro VXworks targets).
+
+2001-04-26 H.J. Lu <hjl@gnu.org>
+
+ * elf32-i386.c (elf_i386_check_relocs): Verify if r_symndx is
+ valid.
+
+2001-04-25 Frank Ch. Eigler <fche@redhat.com>
+
+ * bfd-in.h (bfd_cache_close): Declare newly exported function.
+ * bfd-in2.h: Regenerated.
+
+2001-04-24 Jakub Jelinek <jakub@redhat.com>
+
+ * merge.c (struct sec_merge_hash_entry): Add alignment field.
+ (struct sec_merge_hash): Remove alignment_power.
+ (sec_merge_hash_newfunc): Clear alignment.
+ (sec_merge_hash_lookup): Pass alignment as argument.
+ Use hashp->root.next, not hashp->next to walk the hash chain.
+ If a string already in the hashtable does not have required
+ alignment, create a new hashtable entry.
+ (sec_merge_init): Remove alignment_power argument.
+ (sec_merge_add): Add alignment argument.
+ (sec_merge_emit): Alignment is now a per-entity thing, not per
+ section.
+ (_bfd_merge_section): Sanity check even non-SEC_STRINGS sections
+ for proper alignment.
+ Pass alignment information to sec_merge_add.
+
+2001-04-24 Christian Groessler <cpg@aladdin.de>
+
+ * coff-z8k.c (extra_case): added handler for R_DISP7, R_CALLR
+ and R_REL16 reloc types; accept odd values for R_REL16 type
+
+2001-04-24 Johan Rydberg <jrydberg@opencores.org>
+
+ * cpu-openrisc.c: New file.
+ * elf32-openrisc.c: Likewise.
+
+ * Makefile.am (ALL_MACHINES): Add cpu-openrisc.lo.
+ (ALL_MACHINES_CFILES): Add cpu-openrisc.c.
+ (BFD32_BACKENDS): Add elf32-openrisc.lo.
+ (BFD32_BACKENDS_CFILES): Add elf32-openrisc.c.
+ (cpu-openrisc.lo, elf32-openrisc.lo): New rules.
+ * Makefile.in: Regenerated.
+ * config.bfd: (openrisc-*-elf): New target.
+ * configure.in (bfd_elf32_openrisc_vec): New vector.
+ * configure: Regenerated.
+ * libbfd.h: Regenerated.
+ * bfd-in2.h: Regenerated.
+ * reloc.c: Add OpenRISC relocations.
+ * targets.c (bfd_elf32_openrisc_vec): Declare.
+ (bfd_target_vect): Add bfd_elf32_openrisc_vec.
+ * archures.c (enum bfd_architecture): Add bfd_arch_openrisc.
+ (bfd_openrisc_arch): Declare.
+ (bfd_archures_list): Add bfd_openrisc_arch.
+ * elf.c (prep_headers): Add bfd_arch_openrisc.
+
+2001-04-23 Bo Thorsen <bo@suse.de>
+
+ * elf64-x86-64.c: Add c++ vtable hack.
+ Small whitespace and comment changes.
+
+2001-04-19 Andreas Jaeger <aj@suse.de>
+
+ * elf64-x86-64.c (elf64_x86_64_plt0_entry): Fix instructions.
+ (elf64_x86_64_plt_entry): Likewise.
+ (elf64_x86_64_finish_dynamic_sections): Fix PLT0 generation.
+ (elf64_x86_64_finish_dynamic_symbol): Fix PLT generation.
+
+2001-04-17 Hans-Peter Nilsson <hp@axis.com>
+
+ * elf32-cris.c: Tweak comments related to dynamic linking.
+ (cris_elf_relocate_section): When not creating shared object, fill
+ in the .got table for any symbol not in the dynamic symbol table.
+ (elf_cris_finish_dynamic_symbol): When not creating shared object,
+ only emit a .got.rela reloc if the symbol is in the dynamic symbol
+ table.
+ (cris_elf_check_relocs): Use variable r_type in all places rather
+ than the original expression. Add default case in switch for
+ reloc types.
+ (elf_cris_size_dynamic_sections): Iterate over
+ elf_cris_discard_excess_program_dynamics when not creating shared
+ library.
+ (elf_cris_discard_excess_dso_dynamics): Renamed from
+ elf_cris_discard_copies. Correct typo, s/Rel/Rela/.
+ (elf_cris_discard_excess_program_dynamics): New.
+
+2001-04-14 Mark Elbrecht <snowball3@bigfoot.com>
+
+ * coffcode.h (coff_write_object_contents): Use
+ bfd_coff_swap_filehdr_out instead of coff_swap_filehdr_out.
+
+2001-04-14 H.J. Lu <hjl@gnu.org>
+
+ * bfd-in2.h: Regenerate.
+
+2001-04-14 Jakub Jelinek <jakub@redhat.com>
+
+ * section.c (STD_SECTION): Add entsize.
+
+2001-04-13 H.J. Lu <hjl@gnu.org>
+
+ * section.c (SEC_MERGE): Define new flag for merging.
+ (SEC_STRINGS): Likewise.
+ (entsize): New field.
+
+2001-04-13 Roger Sayle <roger@metaphorics.com>
+
+ * coff-i386.c (TARGET_SYM): SEC_READONLY is an applicable section
+ flag on pe-i386 targets.
+
+2001-04-13 Jakub Jelinek <jakub@redhat.com>
+
+ * libbfd-in.h (_bfd_merge_section): New.
+ (_bfd_write_merged_section): New.
+ (_bfd_merged_section_offset): New.
+ * libbfd.h: Rebuilt.
+ * linker.c (_bfd_generic_link_output_symbols): Handle
+ discard_sec_merge.
+ * aoutx.h (aout_link_write_symbols): Likewise.
+ * pdp11.c (aout_link_write_symbols): Likewise.
+ * elflink.h (elf_link_add_object_symbols): Call _bfd_merge_section.
+ (elf_bfd_final_link): Adjust global symbols pointing into SEC_MERGE
+ sections.
+ (elf_link_sec_merge_syms): New.
+ (elf_link_input_bfd): Call _bfd_merged_section_offset
+ and _bfd_write_merged_section.
+ Handle discard_sec_merge.
+ * elf-bfd.h (struct elf_link_hash_table): Add merge_info
+ field.
+ (struct bfd_elf_section_data): Likewise.
+ * elf.c (_bfd_elf_make_section_from_shdr): Set SEC_MERGE and
+ SEC_STRINGS section flags and entsize from their ELF counterparts.
+ (_bfd_elf_link_hash_table_init): Initialize merge_info.
+ (elf_fake_sections): Set SHF_MERGE, SHF_STRINGS and sh_entsize
+ from their BFD counterparts.
+ * merge.c: New file.
+ * Makefile.am: Add strtab.lo.
+ * Makefile.in: Rebuilt.
+
+2001-04-09 Hans-Peter Nilsson <hp@axis.com>
+
+ * elflink.h (elf_fix_symbol_flags): For non-default visibilities,
+ only hide symbols marked STV_INTERNAL or STV_HIDDEN.
+
+2001-04-05 Steven J. Hill <sjhill@cotw.com>
+
+ * config.bfd (mips*el*-*-linux-gnu*): Use traditional little
+ endian MIPS ELF target.
+ * config.bfd (mips*-*-linux-gnu*): Use traditional big endian
+ MIPS ELF target.
+
+ * configure.in (bfd_elf64_tradbigmips_vec): New. Traditional
+ 64bit big endian MIPS ELF target.
+ (bfd_elf64_tradlittlemips_vec): New. Traditional 64bit little
+ endian MIPS ELF target.
+ * configure: Regenerated.
+
+ * elf32-mips.c (IRIX_COMPAT): Handle traditional 64bit and
+ little endian targets.
+ (mips_elf_sym_is_global): Handle traditional targets.
+
+ * elf64-mips.c (bfd_elf64_tradbigmips_vec): New. Traditional
+ 64bit big endian MIPS ELF target.
+ (bfd_elf64_tradlittlemips_vec): New. Traditional 64bit little
+ endian MIPS ELF target.
+
+ * targets.c: (_bfd_target_vector): Add bfd_elf64_tradbigmips_vec
+ and bfd_elf64_tradlittlemips_vec.
+
+2001-04-05 David Mosberger <davidm@hpl.hp.com>
+
+ * elf32-i386.c (elf_i386_fake_sections): Treat ".reloc" as an
+ ordinary "progbits" section.
+
+2001-04-04 Alan Modra <alan@linuxcare.com.au>
+
+ * elflink.h (elf_fix_symbol_flags): Call elf_backend_hide_symbol
+ when -Bsymbolic causes a symbol to no longer need a .plt entry.
+
+2001-04-03 David Mosberger <davidm@hpl.hp.com>
+
+ * efi-app-ia32.c (ALIGN_SECTIONS_IN_FILE): Deleted.
+
+2001-03-30 H.J. Lu <hjl@gnu.org>
+
+ * efi-app-ia32.c (PEI_TARGET_SUBSYSTEM): Rename from ...
+ (PEI_DEFAULT_TARGET_SUBSYSTEM): This.
+
+2001-03-26 H.J. Lu <hjl@gnu.org>
+
+ * elf32-gen.c (elf32_generic_link_add_symbols): New. Check
+ if there are any relocations for generic ELF.
+ (bfd_elf32_bfd_link_add_symbols): Defined to
+ elf32_generic_link_add_symbols.
+ * elf64-gen.c (elf64_generic_link_add_symbols): New. Check
+ if there are any relocations for generic ELF.
+ (bfd_elf64_bfd_link_add_symbols): Defined to
+ elf64_generic_link_add_symbols.
+
+2001-03-23 Nick Clifton <nickc@redhat.com>
+
+ * Makefile.am (BUILD_CFILES): New variable: List of C source
+ files created in build directory.
+ (BUILD_HFILES): New variable: List of header files created in
+ build directory.
+ (POTFILES): Delete.
+ (po/POTFILES.in): Replace rule with empty entry.
+ (po/SRC-POTFILES.in): New rule: Create a list of source files
+ in the source directory.
+ (po/BLD-POTFILES.in): New rule: Create a list of source files
+ in the build directory.
+ (MOSTLYCLEAN): Do not delete source files created in build
+ directory.
+ * Makefile.in: Regenerate.
+ * configure.in: Insert SRC-POTFILES.in and BLD-POTFILES.in
+ into po/Makefile.
+ * configure: Regenerate.
+
+ * po/Make-in: Replace occurrences of POTFILES with SRC-POTFILES
+ and BLD_POTFILES.
+ Add .. to the search path when building bfd.pot.
+ Delete POTFILES when performing distclean.
+ Add comment describing why distclean is broken in maintainer mode.
+ * po/POTFILES.in: Delete.
+ * po/SRC-POTFILES.in: New file.
+ * po/BLD-POTFILES.in: New file.
+ * po/bfd.pot: Regenerate.
+
+2001-03-22 Hans-Peter Nilsson <hp@axis.com>
+
+ * elf32-cris.c: Shlib and PIC support. PCREL tweaks.
+ (elf_cris_discard_copies, elf_cris_adjust_gotplt_to_got,
+ elf_cris_try_fold_plt_to_got, elf_cris_link_hash_newfunc,
+ elf_cris_link_hash_table_create, elf_cris_adjust_dynamic_symbol,
+ elf_cris_size_dynamic_sections, elf_cris_finish_dynamic_symbol,
+ elf_cris_finish_dynamic_sections,elf_cris_hide_symbol): New
+ functions.
+ (cris_elf_howto_table) <R_CRIS_8_PCREL, R_CRIS_16_PCREL,
+ R_CRIS_32_PCREL>: Correct comments. Set pcrel_offset to false.
+ <R_CRIS_COPY, R_CRIS_GLOB_DAT, R_CRIS_JUMP_SLOT, R_CRIS_RELATIVE,
+ R_CRIS_16_GOT, R_CRIS_32_GOT, R_CRIS_16_GOTPLT, R_CRIS_32_GOTPLT,
+ R_CRIS_32_GOTREL, R_CRIS_32_PLT_GOTREL, R_CRIS_32_PLT_PCREL>:
+ New HOWTO members for new relocs.
+ (cris_reloc_map): Map new relocs.
+ (ELF_DYNAMIC_INTERPRETER): Define.
+ (PLT_ENTRY_SIZE): Define.
+ (elf_cris_plt0_entry, elf_cris_plt_entry, elf_cris_pic_plt0_entry,
+ elf_cris_pic_plt_entry): New, PLT templates.
+ (struct elf_cris_pcrel_relocs_copied, struct
+ elf_cris_link_hash_entry, struct elf_cris_link_hash_table): New.
+ (elf_cris_link_hash_traverse, elf_cris_hash_table): Define.
+ (cris_final_link_relocate): Check that 16-bit GOT relocs have
+ positive values. Adjust PCREL relocs to be relative to location
+ after relocation.
+ (cris_elf_relocate_section): Handle relocations to dynamic
+ objects. Handle new relocations. Call error handler when seeing
+ non-PIC relocation for read-only sections while generating shared
+ object.
+ (cris_elf_check_relocs): Set reference counts for GOT and PLT
+ entries.
+ (bfd_elf32_bfd_link_hash_table_create,
+ elf_backend_adjust_dynamic_symbol,
+ elf_backend_size_dynamic_sections,
+ elf_backend_finish_dynamic_symbol,
+ elf_backend_finish_dynamic_sections,
+ elf_backend_create_dynamic_sections, bfd_elf32_bfd_final_link,
+ elf_backend_hide_symbol, elf_backend_want_got_plt,
+ elf_backend_plt_readonly, elf_backend_want_plt_sym,
+ elf_backend_got_header_size, elf_backend_plt_header_size):
+ Define.
+
+ * reloc.c: (BFD_RELOC_CRIS_COPY, BFD_RELOC_CRIS_GLOB_DAT,
+ BFD_RELOC_CRIS_JUMP_SLOT, BFD_RELOC_CRIS_RELATIVE,
+ BFD_RELOC_CRIS_32_GOT, BFD_RELOC_CRIS_16_GOT,
+ BFD_RELOC_CRIS_32_GOTPLT, BFD_RELOC_CRIS_16_GOTPLT,
+ BFD_RELOC_CRIS_32_GOTREL, BFD_RELOC_CRIS_32_PLT_GOTREL,
+ BFD_RELOC_CRIS_32_PLT_PCREL): New relocs.
+ * bfd-in2.h, libbfd.h: Regenerate.
+
+2001-03-21 Diego Novillo <dnovillo@redhat.com>
+
+ (_bfd_mips_elf_relocate_section): Give a better error message when
+ a relocation is not recognized.
+
+2001-03-21 Alan Modra <alan@linuxcare.com.au>
+
+ * elf32-hppa.c (elf32_hppa_set_gp): Check sec->output_section
+ non-NULL before attempting to dereference.
+
+2001-03-20 H.J. Lu <hjl@gnu.org>
+
+ * configure.in: Remove the redundent AC_ARG_PROGRAM.
+ * configure: Rebuild.
+
+2001-03-20 Andreas Schwab <schwab@suse.de>
+
+ * elf32-m68k.c (elf_m68k_relocate_section): Don't need the
+ relocation value when resolving a reference from a debugging
+ section.
+
+2001-03-16 Scott Thomason <SThomaso@hii.com>
+
+ * coff64-rs6000.c (xcoff64_swap_sym_out): Fix syntax errors.
+ (xcoff64_swap_sym_out): Fix syntax errors.
+
+2001-03-16 Richard Sandiford <rsandifo@redhat.com>
+
+ * elf32-arm.h (elf32_arm_merge_private_bfd_data): Fix warning.
+
+2001-03-15 Alan Modra <alan@linuxcare.com.au>
+
+ * elf32-hppa.c (elf32_hppa_link_hash_entry): Add maybe_pic_call.
+ (hppa_link_hash_newfunc): Init it.
+ (hppa_type_of_stub): Only use non-PIC to PIC call stub if caller
+ section appears to be non-PIC.
+ (final_link_relocate): Likewise.
+ (elf32_hppa_adjust_dynamic_symbol): Set maybe_pic_call for any
+ possible candidate function, and set pic_call for those that will
+ only have a .plt entry for the PIC call stub.
+ (hppa_handle_PIC_calls): Set maybe_pic_call.
+
+2001-03-12 DJ Delorie <dj@redhat.com>
+
+ * elf32-sh.c (sh_elf_relocate_section): Only relocation
+ R_SH_DIR8WP* relocs if they're against external symbols, else
+ they're just for relaxing. Validate the reloc values.
+
+2001-03-12 Stefan Geuken <mail@stefan-geuken.de>
+
+ * binary.c (bfd_external_binary_architecture): Declare.
+ (binary_object_p): If bfd_external_binary_architecture is defined,
+ set the architecture to this string.
+
+2001-03-11 Philip Blundell <philb@gnu.org>
+
+ * elf32-arm.h (elf32_arm_finish_dynamic_symbol): Don't make PLT
+ entries that could serve as a definition for a weak symbol.
+
+2001-03-08 Nick Clifton <nickc@redhat.com>
+
+ * Most files: Update copyright notices using Perl script created
+ by Kevin Buettner <kevinb@redhat.com>.
+
+2001-03-07 Nick Clifton <nickc@redhat.com>
+
+ * elf32-arm.h (elf32_arm_final_link_relocate): Conditionalise
+ prior patch on ! defined OLD_ARM_ABI.
+
+2001-03-07 Andreas Jaeger <aj@suse.de>
+
+ * elf64-x86-64.c (elf64_x86_64_relocate_section): Fix handling of
+ some relocation values.
+
+2001-03-06 Nick Clifton <nickc@redhat.com>
+
+ * elf32-arm.h (elf32_arm_final_link_relocate): Clear bit zero
+ of offset in BLX(1) instruction.
+ * coff-arm.c (coff_arm_relocate_section): Clear bit zero of
+ offset in BLX(1) instruction.
+ Fix formatting.
+
+2001-03-06 Nick Clifton <nickc@redhat.com>
+
+ * coff-arm.c (coff_arm_reloc_type_lookup): Add
+ BFD_RELOC_THUMB_PCREL_BLX.
+
+2001-03-06 Igor Shevlyakov <igor@windriver.com>
+
+ * archures.c (bfd_default_scan): Add Coldfire CPUs.
+ * bfd-in2.h: Regenerate.
+ * cpu-m68k.c: Add Coldfire CPUs for arch table.
+ * ieee.c (ieee_write_processor): Set proper id for
+ Coldfire CPUs.
+
+2001-03-01 D.J. Barrow <djbarrow@de.ibm.com,barrow_dj@yahoo.com>
+
+ * configure.in: Add s390 target.
+ * configure: Regenerate.
+
+2001-02-28 Andreas Jaeger <aj@suse.de>
+
+ * elf64-x86-64.c (elf64_x86_64_relocate_section): Add relocation
+ to addend.
+
+2001-02-28 Philip Blundell <pb@futuretv.com>
+
+ * elf32-arm.h: Update mentions of renamed EF_xx constants.
+ (elf32_arm_print_private_bfd_data): Handle ARM EABI version 2.
+
+2001-02-27 H.J. Lu <hjl@gnu.org>
+
+ * aoutx.h (NAME(aout,bfd_free_cached_info)): Return true if
+ abfd->tdata.aout_data == NULL.
+
+2001-02-27 Alan Modra <alan@linuxcare.com.au>
+
+ * elf32-hppa.c: Correct field selector in stub comments.
+ (clobber_millicode_symbols): Formatting fix.
+
+ * configure.in: Bump version to 2.11.90.
+ * configure: Regenerate.
+ * Makefile.am (CFILES): Rename to SOURCE_CFILES.
+ (CFILES): $SOURCE_CFILES + generated C files.
+ (POTFILES): Include $HFILES not $SOURCE_HFILES.
+ Run "make dep-am"
+ * Makefile.in: Regenerate.
+ * doc/Makefile.in: This too.
+
+2001-02-26 Timothy Wall <twall@cygnus.com>
+
+ * elfxx-ia64.c (elfNN_ia64_aix_add_symbol_hook): Remove obsolete
+ comments.
+
+2001-02-26 Nick Clifton <nickc@redhat.com>
+
+ * coffcode.h (styp_to_sec_flags) [COFF_WITH_PE version]: Tidy
+ up, replacing multiple if statements with a switch.
+ (handle_COMDAT): New function.
+
+2001-02-26 H.J. Lu <hjl@gnu.org>
+
+ * coffcode.h (styp_to_sec_flags) [COFF_WITH_PE version]: Issue
+ a warning for section flags we do not handle instead of
+ aborting.
+
+2001-02-26 Andreas Jaeger <aj@suse.de>
+
+ * elf64-x86-64.c (x86_64_elf_howto_table): Fix order of entries.
+
+2001-02-22 Timothy Wall <twall@cygnus.com>
+
+ * config.bfd (targ_cpu): Add vectors for ia64-*-aix* (aka Monterey).
+ * configure.in: Add objects for elf64_ia64_aix vectors.
+ * configure: Regenerated.
+ * configure.host: Recognize ia64-*-aix*.
+ * elfxx-ia64.c: Add hooks for ELF64 on AIX5. Define new vectors
+ for AIX. AIX5 requires most relocations to be dynamic (*all*
+ binaries are somewhat similar to shared libraries).
+ * targets.c: Add elf64_ia64_aix vectors.
+
+2001-02-21 David Mosberger <davidm@hpl.hp.com>
+
+ * cpu-ia64-opc.c (elf64_ia64_operands}: Fix typo: error string for
+ C8 said "1" instead of "8". Clarify error string for IMM22:
+ "signed integer" instead of just "integer".
+
+2001-02-20 Andreas Jaeger <aj@suse.de>
+
+ * elf64-x86-64.c (elf64_x86_64_finish_dynamic_symbol): Don't make
+ PLT entries that could serve as a definition for a weak symbol.
+
+2001-02-19 Jakub Jelinek <jakub@redhat.com>
+
+ * elf32-sparc.c (elf32_sparc_finish_dynamic_symbol): Don't make PLT
+ entries that could serve as a definition for a weak symbol.
+ * elf64-sparc.c (sparc64_elf_finish_dynamic_symbol): Likewise.
+
+2001-02-18 David O'Brien <obrien@FreeBSD>
+
+ * configure.in: Recognize FreeBSD/arm, FreeBSD/PowerPC, and treat
+ FreeBSD/i386-CURRENT differently until I can figure out the needed
+ corefile changes.
+ * configure: Regenerate.
+ * config.bfd: Recognize FreeBSD/x86-64, FreeBSD/ia64, FreeBSD/arm,
+ FreeBSD/PowerPC, and FreeBSD/sparc64.
+
+2001-02-18 lars brinkhoff <lars@nocrew.org>
+
+ * Makefile.am: Add PDP-11 a.out target.
+ * config.bfd: Likewise.
+ * configure.in: Likewise.
+ * targets.c: Likewise.
+ * archures.c: Likewise.
+ * bfd-in2.h: Likewise. Add PDP-11 relocations.
+ * libbfd.h: Add PDP-11 relocations.
+ * reloc.c: Likewise.
+ * cpu-pdp11.c: New file.
+ * pdp11.c: New file.
+
+ * libaout.h (GET_WORD) [ARCH_SIZE==16]: Define.
+ (GET_SWORD) [ARCH_SIZE==16]: Likewise.
+ (GET_SWORD) [ARCH_SIZE==16]: Likewise.
+ (PUT_WORD) [ARCH_SIZE==16]: Likewise.
+ (GET_MAGIC): New macro.
+ (PUT_MAGIC): Likewise.
+ * aout-target.h (MY(object_p)): Use GET_MAGIC to read magic word.
+
+2001-02-18 Jim Kingdon <jkingdon@engr.sgi.com>
+
+ * irix-core.c (irix_core_core_file_p): Set the architecture (GDB
+ multiarch needs it).
+
+2001-02-18 H.J. Lu <hjl@gnu.org>
+
+ * elflink.h (elf_link_input_bfd): Ignore invalid section symbol
+ index.
+
+2001-02-18 Kazu Hirata <kazu@hxi.com>
+
+ * vms-misc.c: Fix formatting.
+
+2001-02-16 Kazu Hirata <kazu@hxi.com>
+
+ * vms.c: Fix formatting.
+
+2001-02-14 H.J. Lu <hjl@gnu.org>
+
+ * elf.c (elf_find_function): New function.
+ (_bfd_elf_find_nearest_line): Call elf_find_function () to find
+ the file name and function name.
+
+2001-02-14 Nick Clifton <nickc@redhat.com>
+
+ * ecoff.c (bfd_debug_section): Update to initialise new fields in
+ asection structure.
+
+ * Makefile.am (BFD32_BACKENDS_CFILES): Remove peigen.c
+ (BFD64_BACKENDS): Add pepigen.c
+ Add rules to create peigen.c and pepigen.c from peXXigen.c.
+
+ * Makefile.in: Regenerate.
+ * configure: Regenerate.
+ * po/POTFILES.in: Regenerate.
+ * po/bfd.pot: Regenerate.
+
+2001-02-14 H.J. Lu <hjl@gnu.org>
+
+ * libcoff-in.h (pe_tdata): Add members target_subsystem and
+ force_minimum_alignment.
+
+2001-02-14 Bo Thorsen <bo@suse.de>
+
+ * elf64-x86-64.c: Small formatting fixes and rearrangements of code.
+ (elf64_86_64_size_info): Struct added to fix a problem
+ with the hashtable string entries.
+ (elf64_x86_64_adjust_dynamic_symbol): Add generation of .got.plt.
+ (elf64_x86_64_size_dynamic_sections): A FIXME removed.
+ (elf64_x86_64_size_dynamic_sections): Fix a dynamic entry and
+ remove the FIXME for this.
+ (elf64_x86_64_adjust_dynamic_symbol): Fix check for unneeded .plt
+ section. Also removed the FIXME for it.
+ (x86_64_elf_howto_table): Use bfd_elf_generic_reloc.
+ (ELF_DYNAMIC_INTERPRETER): Fix the name of the dynamic linker.
+ (elf64_x86_64_finish_dynamic_sections): Enable .got.plt writing.
+
+2001-02-13 Richard Henderson <rth@redhat.com>
+
+ * elfxx-ia64.c (elfNN_ia64_final_link): Set __gp if required
+ and not user provided.
+
+2001-02-13 Kazu Hirata <kazu@hxi.com>
+
+ * vms.c (vms_print_symbol): Remove unreachable code.
+
+ * rs6000-core.c: Fix formatting.
+
+2001-02-13 David Mosberger <davidm@hpl.hp.com>
+
+ * peicode.h (coff_swap_filehdr_out) [COFF_IMAGE_WITH_PE]: Define
+ as _bfd_XXi_only_swap_filehdr_out.
+ (pe_mkobject) [PEI_FORCE_MINIMUM_ALIGNMENT]: Set
+ pe->force_minimum_alignment to TRUE.
+ (pe_mkobject) [PEI_TARGET_SUBSYSTEM]: Set pe->target_subsystem to
+ PEI_TARGET_SUBSYSTEM.
+ (pe_print_private_bfd_data): Call
+ _bfd_XX_print_private_bfd_data_common() instead of
+ _bfd_pe_print_private_bfd_data_common().
+ (pe_bfd_copy_private_bfd_data): Call
+ _bfd_XX_bfd_copy_private_bfd_data_common() instead of
+ _bfd_pe_bfd_copy_private_bfd_data_common().
+ (coff_bfd_copy_private_section_data): Define as
+ _bfd_XX_bfd_copy_private_section_data instead of
+ _bfd_pe_bfd_copy_private_section_data.
+ (coff_get_symbol_info): Define as _bfd_XX_get_symbol_info instead
+ of a _bfd_pe_get_symbol_info.
+
+ * peigen.c: Delete.
+
+ * peXXigen.c: Renamed from peigen.c.
+ (COFF_WITH_XX): Define this macro (will get expanded into
+ COFF_WITH_pep or COFF_WITH_pe, depending on whether this is being
+ compiled as peigen.c or pepigen.c.
+ [COFF_WITH_pep]: Include "coff/ia64.h" instead of "coff/i386.h" to
+ define the canonical PEP structures and definitions.
+ (_bfd_XXi_swap_aouthdr_out): If pe->force_minimum_alignment is in
+ effect, enforce minimum file and section alignments. If
+ extra->Subsystem is IMAGE_SUBSYSTEM_UNKNOWN, set it to
+ pe->target_subsystem (this defaults to IMAGE_SUBSYSTEM_UNKNOWN,
+ so, by default, this is a no-op).
+
+ * libpei.h: Rename COFF_WITH_PEP to COFF_WITH_pep.
+ (_bfd_XX_bfd_copy_private_bfd_data_common): Add macros to map
+ _bfd_XXfoo to _bfd_pepfoo if COFF_WIT_PEP is defined and to
+ _bfd_pefoo if it's not defined. Use these macros to define
+ coff swap macros.
+
+ * libcoff.h (pe_tdata): Add members target_subsystem and
+ force_minimum_alignment.
+
+ * efi-app-ia64.c (COFF_WITH_pep): Rename COFF_WITH_PEP to
+ COFF_WITH_pep.
+ (PEI_TARGET_SUBSYSTEM): Rename from PEI_DEFAULT_TARGET_SUBSYSTEM.
+
+ * configure.in (bfd_efi_app_ia64_vec): Use pepigen.lo instead of
+ peigen.lo.
+
+ * coff-ia64.c: Rename COFF_WITH_PEP to COFF_WITH_pep.
+ (AOUTSZ): Rename PEP64AOUTSZ and PEP64AOUTHDR to PEPAOUTSZ and
+ PEPAOUTHDR.
+
+ * Makefile.in (BFD64_BACKENDS): Mention pepigen.lo.
+ (BFD64_BACKENDS_CFILES): Mention pepigen.c
+ (peigen.c): Add rule to generate from peXXigen.c.
+ (pepigen.c): Ditto.
+ (pepigen.lo): List dependencies for pepigen.lo.
+
+2001-02-13 Alan Modra <alan@linuxcare.com.au>
+
+ * elf32-hppa.c (elf32_hppa_set_gp): Handle weak $global$. If
+ $global$ referenced but not defined, set its value here.
+
+2001-02-09 Bo Thorsen <bo@suse.de>
+
+ * elf64-x86-64.c (elf64_x86_64_check_relocs): Set .rela.got section
+ alignment to 3.
+ (elf64_x86_64_check_relocs): Write R_X86_64_GOTPCREL GOT entry
+ and relocation.
+ (elf64_x86_64_relocate_section): Fix formatting.
+ (elf64_x86_64_relocate_section): Fix addend for relocation of
+ R_X86_64_(8|16|32|PC8|PC16|PC32).
+
+2001-02-12 Jan Hubicka <jh@suse.cz>
+
+ * elf64-x86-64.c (x86_64_elf_howto): Fix name of R_X86_64_GOTPCREL.
+
+2001-02-11 H.J. Lu <hjl@gnu.org>
+
+ * elflink.h (elf_bfd_final_link): Use file_align for SYMTAB
+ alignment.
+
+2001-02-11 Maciej W. Rozycki <macro@ds2.pg.gda.pl>
+
+ * elf32-mips.c (mips_elf_create_dynamic_relocation): Undo patch
+ from 2000-10-13. Do not add the symbol's value for R_MIPS_REL32
+ relocations against dynsym symbols.
+
+ * elf32-mips.c (elf_mips_howto_table): Fix the comment on
+ the R_MIPS_26 relocation.
+ (mips_elf_calculate_relocation): Use (p + 4) instead of p for
+ the R_MIPS_26 relocation.
+ (mips_elf_perform_relocation): Fix the comment on the R_MIPS16_26
+ relocation.
+ * elf64-mips.c (mips_elf64_howto_table_rel): Fix the comment on
+ the R_MIPS_26 relocation.
+ (mips_elf64_howto_table_rela): Likewise.
+
+ * elf32-mips.c (struct mips_elf_link_hash_entry): Added no_fn_stub
+ member to mark symbols that have non-CALL relocations against
+ them.
+ (mips_elf_link_hash_newfunc): Initialize no_fn_stub.
+ (mips_elf_calculate_relocation): Handle R_MIPS_CALL16 like
+ R_MIPS_GOT16.
+ (_bfd_mips_elf_check_relocs): Set no_fn_stub for a symbol if a
+ non-CALL relocation against it is encountered.
+ (_bfd_mips_elf_copy_indirect_symbol): Merge no_fn_stub as well.
+ (_bfd_mips_elf_adjust_dynamic_symbol): Only create a stub if
+ no_fn_stub is not set.
+
+ * elf32-mips.c (mips_elf_output_extsym): Get the output section
+ information from the real symbol for indirect ones.
+ Check no_fn_stub to find out if a symbol has a function stub
+ indeed.
+
+2001-02-11 Michael Sokolov <msokolov@ivan.Harhan.ORG>
+
+ * Makefile.am (stamp-lib): ranlib the libbfd.a in the build directory.
+ * Makefile.in: Regenerate.
+
+2001-02-09 David Mosberger <davidm@hpl.hp.com>
+
+ * elfxx-ia64.c (is_unwind_section_name): New function. Returns
+ true if section name is an unwind table section name.
+ (elfNN_ia64_additional_program_headers): Count each unwind section
+ separately.
+ (elfNN_ia64_modify_segment_map): Install one unwind program header
+ for each unwind separate section. Note: normally the linker
+ script merges the unwind sections that go into a single segment,
+ so this still generates at most one unwind program header per
+ segment.
+
+ * elfxx-ia64.c (elfNN_ia64_section_from_shdr): Accept any section
+ name for SHT_IA_64_UNWIND, not just .IA_64.unwind.
+ (elfNN_ia64_fake_sections): Mark sections with names that start
+ with .IA_64.unwind but not with .IA_64.unwind_info as an IA-64
+ unwind section.
+
+ * elfxx-ia64.c (elfNN_ia64_final_write_processing): New function.
+ Use it to make sh_info in unwind section point to the text section
+ it applies to.
+
+2001-02-09 Martin Schwidefsky <schwidefsky@de.ibm.com>
+
+ * Makefile.am: Add linux target for S/390.
+ * archures.c: Likewise.
+ * bfd-in2.h: Likewise.
+ * config.bfd: Likewise.
+ * configure.in: Likewise.
+ * elf.c: Likewise.
+ * libbfd.h: Likewise.
+ * targets.c: Likewise.
+ * cpu-s390.c: New file.
+ * elf32-s390.c: New file.
+ * elf64-s390.c: New file.
+
+2001-02-09 Nick Clifton <nickc@redhat.com>
+
+ * peigen.c (_bfd_pe_get_symbol_info): Suppress addition of
+ ImageBase. This has already been done by coff_swap_hdr_in.
+
+2001-02-09 Jakub Jelinek <jakub@redhat.com>
+
+ * elf64-sparc.c (sparc64_elf_copy_private_bfd_data): New function.
+
+2001-02-09 Jakub Jelinek <jakub@redhat.com>
+
+ * elf64-sparc.c (sparc64_elf_check_relocs): Don't trust reloc_count.
+ (sparc64_elf_relocate_section): Likewise.
+
+2001-02-09 Mark Kettenis <kettenis@gnu.org>
+
+ * elf32-sparc.c (_bfd_sparc_elf_howto_table): Treat R_SPARC_UA32
+ similar to R_SPARC_32.
+ * elf64-sparc.c (sparc64_elf_howto_table): Likewise.
+
+2001-02-08 H.J. Lu <hjl@gnu.org>
+
+ * elf32-i386.c (elf_i386_check_relocs): Reserve R_386_PC32
+ relocation entries for weak definitions when building DSO with
+ -Bsymbolic.
+
+2001-02-08 Richard Henderson <rth@redhat.com>
+
+ * elf64-alpha.c (alpha_elf_dynamic_symbol_p): Respect weakness
+ before visibility. Locally defined protected symbols are not
+ dynamic.
+
+2001-02-08 Geoffrey Keating <geoffk@redhat.com>
+
+ * config.bfd: Enable coff64 for rs6000-*. Patch from
+ <hzoli@austin.ibm.com>.
+
+2001-02-07 Mark Elbrecht <snowball3@bigfoot.com>
+
+ * coffgen.c (coff_find_nearest_line): If stabs info is successfully
+ found, do not attempt to find dwarf2 info before returning.
+
+2001-02-07 Jakub Jelinek <jakub@redhat.com>
+
+ * elflink.h (is_global_symbol_definition): Rename to
+ is_global_data_symbol_definition and have it reject function
+ symbols.
+ (elf_link_is_defined_archive_symbol): Use renamed function.
+
+2001-02-07 Todd Vierling <tv@wasabisystems.com>
+
+ * libbfd-in.h (bfd_target_vector): Change extern array to pointer.
+ * libbfd.h (bfd_target_vector): Likewise.
+ * targets.c (bfd_target_vector): Rename to _bfd_target_vector and
+ make static; create pointer reference named bfd_target_vector.
+ (_bfd_target_vector_entries): Calculate this based on the array
+ typed _bfd_target_vector.
+
+2001-02-06 H.J. Lu <hjl@gnu.org>
+
+ * elfxx-ia64.c (elfNN_ia64_dynamic_symbol_p): Only hidden and
+ internal symbols are not dynamic.
+ * elf64-alpha.c (alpha_elf_dynamic_symbol_p): Likewise.
+
+2001-02-06 Nick Clifton <nickc@redhat.com>
+
+ * Makefile.am (BFD64_BACKENDS_CFILES): Remove elf64-ia64.c, so
+ that it will not be pulled into the list of files that make up
+ po/POTFILES.in.
+ * Makefile.in: Regenerate.
+ * po/bfd.pot: Regenerate.
+
+2001-02-06 H.J. Lu <hjl@gnu.org>
+
+ * peicode.h (coff_swap_filehdr_in): Remove the e_magic
+ checking.
+ (pe_bfd_object_p): Rewrite with external_PEI_DOS_hdr and
+ external_PEI_IMAGE_hdr.
+
+2001-02-06 Kazu Hirata <kazu@hxi.com>
+
+ * elf-m10200.c: Fix formatting.
+
+2001-02-04 Nick Clifton <nickc@redhat.com>
+
+ * elf32-v850.c (v850_elf_reloc): Do not convert reloc addend to PC
+ rel, it will be handled later on.
+
+2001-02-02 Fred Fish <fnf@ninemoons.com>
+
+ * Makefile.in: Fix typo.
+
+2001-02-01 Kazu Hirata <kazu@hxi.com>
+
+ * elf-m10300.c: Fix formatting.
+
+2001-01-30 Alan Modra <alan@linuxcare.com.au>
+
+ * elf64-hppa.c (elf64_hppa_elf_get_symbol_type): New function.
+ (elf_backend_get_symbol_type): Define.
+ (elf64_hppa_object_p): Set architecture and machine from elf
+ header flags.
+
+2001-01-30 Curtis L. Janssen <cljanss@ca.sandia.gov>
+
+ * elf64-alpha.c (elf64_alpha_find_nearest_line): Query dwarf2
+ before mdebug.
+
+2001-01-26 Richard Henderson <rth@redhat.com>
+
+ * elfxx-ia64.c (elfNN_ia64_dynamic_symbol_p): Return false
+ for non-default visibility.
+ * elf64-alpha.c (alpha_elf_dynamic_symbol_p): Likewise, but
+ delete ugly macro and replace with pretty function.
+
+2001-01-25 Mark Elbrecht <snowball3@bigfoot.com>
+
+ * coff-go32.c: Update copyright.
+ * coff-stgo32.c: Likewise.
+ * coff-go32.c (COFF_LONG_FILENAMES): Define.
+ * coff-stgo32.c (COFF_LONG_FILENAMES): Likewise.
+ * coff-go32.c (COFF_SECTION_ALIGNMENT_ENTRIES): Remove .bss entry.
+ * coff-stgo32.c (COFF_SECTION_ALIGNMENT_ENTRIES): Likewise.
+
+2001-01-25 Kazu Hirata <kazu@hxi.com>
+
+ * bfd-in2.h: Rebuild.
+ * libbfd.h: Likewise.
+
+2001-01-23 H.J. Lu <hjl@gnu.org>
+
+ * bfd-in2.h: Rebuild.
+
+2001-01-23 H.J. Lu <hjl@gnu.org>
+
+ * vms-misc.c (_bfd_vms_next_record): Return -1 if PRIV(vms_buf)
+ is NULL or PRIV(vms_rec) is outside of the buffer.
+
+2001-01-23 Kazu Hirata <kazu@hxi.com>
+
+ * coff64-rs6000.c: Fix formatting.
+ * coff-arm.c: Likewise.
+ * coffgen.c: Likewise.
+ * cofflink.c: Likewise.
+ * coff-mcore.c: Likewise.
+ * coff-mips.c: Likewise.
+ * coff-pmac.c: Likewise.
+ * coff-ppc.c: Likewise.
+ * coff-rs6000.c: Likewise.
+ * elf32.c: Likewise.
+ * elf32-fr30.c: Likewise.
+ * elf32-i370.c: Likewise.
+ * elf32-i860.c: Likewise.
+ * elf32-m32r.c: Likewise.
+ * elf32-m68k.c: Likewise.
+ * elf32-mcore.c: Likewise.
+ * elf32-ppc.c: Likewise.
+ * elf32-sh.c: Likewise.
+ * elf32-v850.c: Likewise.
+ * elf64-alpha.c: Likewise.
+ * elf64-sparc.c: Likewise.
+ * elflink.c: Likewise.
+ * elflink.h: Likewise.
+ * elf-m10200.c: Likewise.
+ * elf-m10300.c: Likewise.
+ * elfxx-ia64.c: Likewise.
+
+ * aoutx.h: Fix formatting.
+ * bfd.c: Likewise.
+ * bfd-in2.h: Likewise.
+ * bfd-in.h: Likewise.
+ * cpu-i386.c: Likewise.
+ * cpu-m68hc11.c: Likewise.
+ * dwarf2.c: Likewise.
+ * elf64-x86-64.c: Likewise.
+ * format.c: Likewise.
+ * freebsd.h: Likewise.
+ * hash.c: Likewise.
+ * hp300hpux.c: Likewise.
+ * hppabsd-core.c: Likewise.
+ * hpux-core.c: Likewise.
+
+2001-01-22 Bo Thorsen <bo@suse.de>
+
+ * elf64-x86-64.c: Added PIC support for X86-64.
+ (elf64_x86_64_link_hash_newfunc): Function added.
+ (elf64_x86_64_link_hash_table_create): Likewise.
+ (elf64_x86_64_check_relocs): Likewise.
+ (elf64_x86_64_gc_mark_hook): Likewise.
+ (elf64_x86_64_gc_sweep_hook): Likewise.
+ (elf64_x86_64_adjust_dynamic_symbol): Likewise.
+ (elf64_x86_64_size_dynamic_sections): Likewise.
+ (elf64_x86_64_discard_copies): Likewise.
+ (elf64_x86_64_finish_dynamic_symbol): Likewise.
+ (elf64_x86_64_finish_dynamic_sections): Likewise.
+ (elf64_x86_64_relocate_section): Add relocation of PIC sections.
+
+2001-01-21 Maciej W. Rozycki <macro@ds2.pg.gda.pl>
+
+ * Makefile.am (install-data-local): Make use of $(DESTDIR).
+ * Makefile.in: Regenerate.
+
+2001-01-21 Kazu Hirata <kazu@hxi.com>
+
+ * coff-a29k.c: Fix formatting.
+
+2001-01-19 H.J. Lu <hjl@gnu.org>
+
+ * elf32-i386.c (elf_i386_check_relocs): Report files with bad
+ relocation section names.
+ (elf_i386_relocate_section): Report files with bad relocation
+ section names and return false.
+
+2001-01-17 Bo Thorsen <bo@suse.de>
+
+ * targets.c: Alphabetize list of xvecs.
+
+2001-01-14 Alan Modra <alan@linuxcare.com.au>
+
+ * config.bfd: Add linux target variant for elfxx-hppa.
+ * configure.in: Recognize bfd_elf32_hppa_linux_vec and
+ bfd_elf64_hppa_linux_vec.
+ * configure: Regenerate.
+ * elf64-hppa.c: Include elf64-target.h again to support linux
+ target variant.
+ (elf64_hppa_post_process_headers): Set ELFOSABI_LINUX for linux.
+ * elf32-hppa.c: Include elf32-target.h again to support linux
+ target variant.
+ (elf32_hppa_post_process_headers): New function.
+ (elf_backend_post_process_headers): Define.
+ * targets.c (bfd_target_vector): Add bfd_elf64_hppa_linux_vec and
+ bfd_elf32_hppa_linux_vec.
+
+ * elf32-hppa.c (elf32_hppa_link_hash_table): Add text_segment_base,
+ and data_segment_base fields.
+ (elf32_hppa_link_hash_table_create ): Init them.
+ (elf32_hppa_check_relocs): Update comments.
+ (hppa_record_segment_addr): New function.
+ (elf32_hppa_relocate_section): Call it.
+ (final_link_relocate): Handle R_PARISC_SEGREL32.
+ (elf32_hppa_final_link): New function.
+ (bfd_elf32_bfd_final_link): Define to call it.
+ (hppa_unwind_entry_compare): New function.
+ * cache.c (bfd_open_file): Create files in write+read mode.
+
+ * elf-hppa.h (elf_hppa_howto_table): Set bitsize value for
+ SEGREL32 and numerous other relocs. Change duplicate
+ R_PARISC_NONE relocs to R_PARISC_UNIMPLEMENTED.
+
+ * opncls.c (bfd_fdopenr): Add parens like the comment says around
+ O_ACCMODE.
+
+ * elf32-hppa.c (elf32_hppa_size_dynamic_sections): Don't create
+ .plt entries for DT_INIT and DT_FINI.
+ (elf32_hppa_finish_dynamic_sections): Remove special handling of
+ DT_INIT and DT_FINI.
+
+ * elf64-hppa.c (elf64_hppa_finish_dynamic_symbol): Use 16-bit
+ offsets for stub .plt access if wide mode. Check offset in range.
+
+2001-01-13 Nick Clifton <nickc@redhat.com>
+
+ * elf32-fr30.c (fr30_elf_howto_table): Remove spurious blank
+ line.
+
+ * coffcode.h (coff_canonicalize_reloc): Remove spurious blank
+ line.
+
+2001-01-12 Alan Modra <alan@linuxcare.com.au>
+
+ * configure.in ([bfd_elf64_x86_64_vec]): Set target64.
+ * configure: Regenerate.
+
+2001-01-11 Peter Targett <peter.targett@arccores.com>
+
+ * bfd-in2.h (bfd_architecture): Add bfd_mach_arc_5,
+ bfd_mach_arc_6, bfd_mach_arc_7, bfd_mach_arc_8 for ARC variants.
+ * cpu-arc.c (arch_info_struct): Add entries for variants.
+ (bfd_arc_arch) Set default to bfd_mach_arc_5.
+ (arc_get_mach) Don't assume machine names prefixed arc- before
+ testing.
+ * elf32-arc.c (arc_elf_object_p): Set machine number based on new
+ selections.
+ (arc_elf_final_write_processing) Likewise.
+ (ELF_MACHINE_CODE) Use EM_ARC.
+
+2001-01-10 Nick Clifton <nickc@redhat.com>
+
+ * coff-arm.c (LOCAL_LABEL_PREFIX): Change definition to "".
+
+2001-01-07 Philip Blundell <philb@gnu.org>
+
+ * README: Replace `bug-gnu-utils@gnu.org' with
+ `bug-binutils@gnu.org'.
+
+2001-01-04 Kazu Hirata <kazu@hxi.com>
+
+ * som.c: Fix formatting.
+
+2001-01-03 Kazu Hirata <kazu@hxi.com>
+
+ * ecoffswap.h: Fix formatting.
+ * elf-bfd.h: Likewise.
+ * elfarm-nabi.c: Likewise.
+ * elfarm-oabi.c: Likewise.
+ * elfcode.h: Likewise.
+ * elfcore.h: Likewise.
+ * elflink.c: Likewise.
+ * elflink.h: Likewise.
+ * elfxx-ia64.c: Likewise.
+ * elfxx-target.h: Likewise.
+ * libbfd.c: Likewise
+ * linker.c: Likewise.
+ * lynx-core.c: Likewise.
+
+2001-01-02 Kazu Hirata <kazu@hxi.com>
+
+ * pc532-mach.c: Fix formatting.
+ * pe-arm.c: Likewise.
+ * pe-i386.c: Likewise.
+ * pe-mips.c: Likewise.
+ * pe-ppc.c: Likewise.
+ * pe-sh.c: Likewise.
+ * pei-mips.c: Likewise.
+ * pei-sh.c: Likewise.
+ * peicode.h: Likewise.
+ * ppcboot.c: Likewise.
+ * ptrace-core.c: Likewise.
+
+2001-01-01 Kazu Hirata <kazu@hxi.com>
+
+ * reloc.c: Fix formatting.
+ * riscix.c: Likewise.
+ * rs6000-core.c: Likewise.
+ * xcoff-target.h: Likewise.
+
+2000-12-29 Hans-Peter Nilsson <hp@bitrange.com>
+
+ * elfcode.h (elf_object_p): Also restore the bfd mach field on
+ error, by calling bfd_default_set_arch_mach with incoming
+ values.
+
+2000-12-26 Kazu Hirata <kazu@hxi.com>
+
+ * vaxnetbsd.c: Fix formatting.
+ * versados.c: Likewise.
+ * vms-gsd.c: Likewise.
+ * vms-hdr.c: Likewise.
+ * vms-misc.c: Likewise.
+
+2000-12-25 Alexandre Oliva <aoliva@redhat.com>
+
+ * archive.c (coff_write_armap): Don't write more than symbol_count
+ `archive_member_file_ptr's.
+
+2000-12-25 Kazu Hirata <kazu@hxi.com>
+
+ * vms-tir.c: Fix formatting.
+
+2000-12-23 Kazu Hirata <kazu@hxi.com>
+
+ * vms.c: Fix formatting.
+ * vms.h: Likewise.
+
+2000-12-21 Santeri Paavolainen <santtu@ssh.com>
+
+ * vms-hdr.c: Include alloca.h if HAVE_ALLOCA_H is defined.
+
+ * peicode.h (pe_ILF_object_p): Add const to import of TARGET_LITTLE_SYM.
+
+ * elf32-m32r.c (m32r_elf_generic_reloc): Add cast to avoid (void *)
+ arithmetic.
+
+ * elf32-fr30.c: Add casts to avoid (void *) arithmetic.
+
+ * coffcode.h (styp_to_sec_flags): Add empty statement after label.
+
+2000-12-21 Richard Sandiford <rsandifo@redhat.com>
+
+ * libbfd.c (bfd_get_bits): Added
+ (bfd_put_bits): Likewise
+ * bfd-in.h: Declared the above.
+ * bfd-in2.h: Regenerated.
+
+2000-12-20 Kazu Hirata <kazu@hxi.com>
+
+ * targets.c: Fix formatting.
+ * tekhex.c: Likewise.
+ * trad-core.c: Likewise.
+
+2000-12-19 Kazu Hirata <kazu@hxi.com>
+
+ * sco5-core.c: Fix formatting.
+ * section.c: Likewise.
+ * sparclinux.c: Likewise.
+ * sparclynx.c: Likewise.
+ * sparcnetbsd.c: Likewise.
+ * srec.c: Likewise.
+ * stabs.c: Likewise.
+ * stab-syms.c: Likewise.
+ * sunos.c: Likewise.
+ * syms.c: Likewise.
+ * sysdep.h: Likewise.
+
+2000-12-18 Nick Clifton <nickc@redhat.com>
+
+ * coff-arm.c (EXTRA_S_FLAGS): Only define if not already
+ defined.
+ * epoc-pe-arm.c (EXTRA_S_FLAGS): Define.
+ * epoc-pei-arm.c (EXTRA_S_FLAGS): Define.
+
+2000-12-18 Nick Clifton <nickc@redhat.com>
+
+ * vms-misc.c (_bfd_vms_get_record): Add default case to
+ file_format switch.
+
+2000-12-15 Miloslav Trmac <mitr@volny.cz>
+
+ * elfcore.h (elf_core_file_p): Move to the start of the program
+ headers before attempting to read them.
+
+2000-12-14 Kazu Hirata <kazu@hxi.com>
+
+ * peigen.c: Fix formatting.
+ * som.c: Likewise.
+ * som.h: Likewise.
+
+2000-12-13 Kazu Hirata <kazu@hxi.com>
+
+ * peigen.c: Fix formatting.
+
+2000-12-12 Jim Wilson <wilson@redhat.com>
+
+ * elfxx-ia64.c (get_dyn_sym_info): Cast %p argument to void *.
+
+2000-12-08 Mark Salter <msalter@redhat.com>
+
+ * binary.c (binary_set_section_contents): Ignore sections
+ with zero size.
+
+2000-12-12 Kazu Hirata <kazu@hxi.com>
+
+ * m68klinux.c: Fix formatting.
+ * m68knetbsd.c: Likewise.
+ * mipsbsd.c: Likewise.
+ * netbsd-core.c: Likewise.
+ * netbsd.h: Likewise.
+ * newsos3.c: Likewise.
+ * nlm32-alpha.c: Likewise.
+ * nlm32-i386.c: Likewise.
+ * nlm32-ppc.c: Likewise.
+ * nlm32-sparc.c: Likewise.
+ * nlmcode.h: Likewise.
+ * nlmswap.h: Likewise.
+ * nlm-target.h: Likewise.
+ * ns32knetbsd.c: Likewise.
+
+2000-12-10 Fred Fish <fnf@be.com>
+
+ * elflink.h (elf_link_output_extsym): Don't complain about undefined
+ symbols in shared objects if allow_shlib_undefined is true.
+
+2000-12-12 Nick Clifton <nickc@redhat.com>
+
+ * cpu-sh.c: Fix formattng.
+ * elf.c: Fix formattng.
+ * elf32-mips.c: Fix formattng.
+ * elf32-sh.c: Fix formattng.
+ * elf64-alpha.c: Fix formattng.
+
+2000-12-09 Nick Clifton <nickc@redhat.com>
+
+ * elf32-mips.c (_bfd_mips_elf_find_nearest_line): Pass
+ dwarf2_find_line_info as last parameter to invocation of
+ _bfd_dwarf2_find_nearest_line.
+ * elf32-arm.h (elf32_arm_find_nearest_line): Pass
+ dwarf2_find_line_info as last parameter to invocation of
+ _bfd_dwarf2_find_nearest_line.
+
+2000-12-08 Mark Elbrecht <snowball3@bigfoot.com>
+
+ * Makefile.am (BFD32_BACKENDS): Move dwarf2.lo from here...
+ (BFD_LIBS): ...to here.
+ (BFD32_BACKENDS_CFILES): Move dwarf2.c from here...
+ (BFD_LIBS_CFILES): ...to here.
+ * Makefile.in: Regenerate.
+ * configure.in: Remove dwarf.lo from the elf shell variable.
+ * configure: Regenerate.
+ * libcoff-in.h (coff_tdata): Add pointer dwarf2_find_line_info.
+ * libcoff.h: Regenerate.
+ * coffgen.c (coff_find_nearest_line): Call
+ _bfd_dwarf2_find_nearest_line.
+ * dwarf2.c (_bfd_dwarf2_find_nearest_line): Add parameter. Update
+ accordingly.
+ (read_abbrevs): Likewise
+ (decode_line_info): Likewise.
+ (parse_comp_unit): Likewise.
+ (comp_unit_find_nearest_line): Likewise.
+ * libbfd-in.h (_bfd_dwarf2_find_nearest_line): Update prototype.
+ * libbfd.h: Regenerate.
+ * elf.c (_bfd_elf_find_nearest_line): Update call.
+ * elf-bfd.h (elf_obj_tdata): Change dwarf2_find_line_info to type PTR.
+ * dwarf2.c (concat_filename): Use IS_ABSOLUTE_PATH.
+ * coffcode.h (STYP_XCOFF_DEBUG, STYP_DEBUG_INFO): New macros.
+ (sec_to_styp_flags): Use them. Handle DWARF2 sections.
+ (styp_to_sec_flags): Handle DWARF2 sections.
+ * elf32-arm.h (elf32_arm_find_nearest_line): Add parameter to call
+ to _bfd_find_nearest_line.
+ * elf32-mips.c (_bfd_mips_elf_find_nearest_line): Add parameter to
+ call to _bfd_find_nearest_line.
+
+2000-12-08 Kazu Hirata <kazu@hxi.com>
+
+ * coffgen.c: Fix formatting.
+ * elf-m10300.c: Likewise.
+ * elf32-i386.c: Likewise.
+ * elf32-i960.c: Likewise.
+ * elf32-m68k.c: Likewise.
+ * elf32-mcore.c: Likewise.
+ * elf32-ppc.c: Likewise.
+ * elf32-sh.c: Likewise.
+ * elf32-sparc.c: Likewise.
+ * elf32-v850.c: Likewise.
+ * elf64-alpha.c: Likewise.
+ * elf64-hppa.c: Likewise.
+ * elf64-mips.c: Likewise.
+ * elf64-sparc.c: Likewise.
+
+2000-12-07 Kazu Hirata <kazu@hxi.com>
+
+ * elf32-ppc.c: Fix formatting.
+ * elf64-x86-64.c: Likewise.
+
+2000-12-06 Ulf Carlsson <ulfc@engr.sgi.com>
+
+ From Ralf Baechle <ralf@gnu.org>
+
+ * elf32-mips.c (elf32_mips_merge_private_bfd_data): Always permit
+ BFDs containing no sections or empty .text, .data or .bss sections
+ to be merged, regardless of their flags.
+
+2000-12-06 Kazu Hirata <kazu@hxi.com>
+
+ * elf32-m32r.c: Fix formatting.
+ * elf32-m68hc11.c: Likewise.
+ * elf32-m68hc12.c: Likewise.
+ * elf32-m68k.c: Likewise.
+ * elf32-mcore.c: Likewise.
+ * elf32-pj.c: Likewise.
+ * elf32-ppc.c: Likewise.
+
+2000-12-05 Kazu Hirata <kazu@hxi.com>
+
+ * elf32-fr30.c: Fix formatting.
+ * elf32-hppa.c: Likewise.
+ * elf32-i370.c: Likewise.
+ * elf32-i386.c: Likewise.
+ * elf32-i860.c: Likewise.
+ * elf32-i960.c: Likewise.
+
+2000-12-03 Kazu Hirata <kazu@hxi.com>
+
+ * elf32-arm.h: Fix formatting.
+ * elf32-avr.c: Likewise.
+ * elf32-cris.c: Likewise.
+ * elf32-d10v.c: Likewise.
+ * elf32-d30v.c: Likewise.
+ * elf-hppa.h: Likewise.
+ * elf-m10200.c: Likewise.
+ * elf-m10300.c: Likewise.
+
+2000-12-01 Chris Demetriou <cgd@sibyte.com>
+
+ * aoutx.h (NAME(aout,machine_type)): Add bfd_mach_mips32 and
+ bfd_mach_mips32_4k. Update FIXME comment.
+ * archures.c (bfd_mach_mips32): New constant.
+ (bfd_mach_mips4K, bfd_mach_mips32_4k) Rename the former to
+ the latter, renumber it.
+ * bfd-in2.h (bfd_mach_mips32): New constant.
+ (bfd_mach_mips4K, bfd_mach_mips32_4k) Rename the former to
+ the latter, renumber it.
+ * cpu-mips.c (I_mips32): New constant.
+ (I_mips4K, I_mips32_4k): Rename the former to the latter.
+ (arch_info_struct): Add bfd_mach_mips32 entry, replace
+ bfd_mach_mips4K entry with bfd_mach_mips32_4k entry.
+ * elf32-mips.c (elf_mips_isa): Add E_MIPS_ARCH_32 case.
+ (elf_mips_mach): Likewise. Also, replace E_MIPS_MACH_MIPS32
+ with E_MIPS_MACH_MIPS32_4K.
+ (_bfd_mips_elf_final_write_processing): Replace
+ bfd_mach_mips4K with bfd_mach_mips32_4k case, add
+ bfd_mach_mips32 case.
+ (_bfd_mips_elf_merge_private_bfd_data): Generalize ISA mixing
+ comparison with support for MIPS32.
+ (_bfd_mips_elf_print_private_bfd_data): Print ISA name for
+ MIPS32.
+
+ * aoutx.h (NAME(aout,machine_type)): Add cases for
+ bfd_mach_mips5 and bfd_mach_mips64.
+ * archures.c (bfd_mach_mips5, bfd_mach_mips64): New constants.
+ * bfd-in2.h (bfd_mach_mips5, bfd_mach_mips64): Likewise.
+ * cpu_mips.c (I_mips5, I_mips64): New definitions.
+ (arch_info_struct): Add entries for bfd_mach_mips5 and
+ bfd_mach_mips64.
+ * elf32-mips.c (elf_mips_isa, elf_mips_mach,
+ _bfd_mips_elf_print_private_bfd_data): Add cases for
+ E_MIPS_ARCH_5 and E_MIPS_ARCH_64.
+ (_bfd_mips_elf_final_write_processing): Add cases for
+ bfd_mach_mips5 and bfd_mach_mips64.
+
+ * aoutx.h (NAME(aout,machine_type)): Add a
+ bfd_mach_mips_sb1 case.
+ * archures.c (bfd_mach_mips_sb1): New constant.
+ * bfd-in2.h (bfd_mach_mips_sb1): New constant.
+ * cpu-mips.c (I_sb1): New constant.
+ (arch_info_struct): Add entry for bfd_mach_mips_sb1.
+ * elf32-mips.c (elf_mips_mach): Add case for
+ E_MIPS_MACH_SB1.
+ (_bfd_mips_elf_final_write_processing): Add case for
+ bfd_mach_mips_sb1.
+
+2000-12-01 Joel Sherrill <joel@OARcorp.com>
+
+ * config.bfd (arm-*-rtems*, a29k-*rtems*): New targets.
+ (sparc*-*-rtemself*, sparc*-*-rtemsaout*): New targets.
+ (sparc*-*-rtems*): Switched from a.out to ELF.
+
+2000-11-30 Jan Hubicka <jh@suse.cz>
+
+ * Makefile.am (BFD64_BACKENDS): Add elf64-x86-64.lo
+ BFD64_BACKENDS_CFILES): Add elf64-x86-64.c
+ (elf64-x86-64.lo): Add dependencies.
+ * archures.c (DESCRIPTION): Add bfd_mach_x86_64,
+ bfd_mach_x86_64_intel_syntax.
+ * elf.c (prep_headers): Use EM_x86_64 for 64bit output.
+ * config.bfd (x86_64): Add.
+ * configure.in: Add support for bfd_elf64_x86_64_vec.
+ * cpu-i386.c (bfd_x86_64_arch_intel_syntax, bfd_x86_64_arch): Add.
+ (bfd_i386_arch, i8086_ar): Link in.
+ * elf64-x86-64.c: New file.
+ * reloc.c (ENUMDOC): Add BFD_RELOC_X86_64*.
+ * targets.c (bfd_elf64_x86_64_vec): Add.
+ (bfd_target_vect): Add bfd_elf64_x86_64_vec.
+
+2000-11-30 Kazu Hirata <kazu@hxi.com>
+
+ * xcofflink.c: Fix formatting.
+
+2000-11-28 Kazu Hirata <kazu@hxi.com>
+
+ * aoutx.h: Fix formatting.
+ * bfd-in.h: Likewise.
+ * bfd-in2.h: Likewise.
+ * cache.c: Likewise.
+ * cisco-core.c: Likewise.
+ * coff64-rs6000.c: Likewise.
+ * coffcode.h: Likewise.
+ * coffswap.h: Likewise.
+ * corefile.c: Likewise.
+ * elf32-mips.c: Likewise.
+
+2000-11-27 Kazu Hirata <kazu@hxi.com>
+
+ * aout-adobe.c: Fix formatting.
+ * coff64-rs6000.c: Likewise.
+ * coffgen.c: Likewise.
+ * cofflink.c: Likewise.
+
+2000-11-27 Philip Blundell <pb@futuretv.com>
+
+ * libcoff-in.h (coff_tdata): Add `strings_written' flag.
+ (obj_coff_strings_written): New accessor macro for above.
+ * libcoff.h: Regenerate.
+ * cofflink.c (_bfd_coff_final_link): Say that we wrote the
+ strings.
+ * coffcode.h (coff_write_object_contents): No need to write out
+ the string table if it's already been done.
+
+2000-11-22 Philip Blundell <pb@futuretv.com>
+
+ * cofflink.c (_bfd_coff_generic_relocate_section): Don't object to
+ weak undefined symbols.
+
+2000-11-24 Nick Clifton <nickc@redhat.com>
+
+ * archures.c (bfd_mach_arm_5TE): Define.
+ (bfd_mach_arm+XScale): Define.
+ * bfd-in2.h: Regenerate.
+
+ * coff-arm.c (coff_arm_reloc_type_lookup): Accept
+ BFD_RELOC_ARM_PCREL_BLX.
+
+ * coffcode.h (coff_set_flags): Set flags for 5t, 5te and
+ XScale machine numbers.
+
+ * config.bfd (xscale-elf): Add target.
+ (xscale-coff): Add target.
+
+ * cpu-arm.c: Add xscale machine name.
+ Add v5t, v5te and XScale machine numbers.
+
+2000-11-23 Kazu Hirata <kazu@hxi.com>
+
+ * aix386-core.c: Fix formatting.
+
+2000-11-22 Jim Wilson <wilson@redhat.com>
+
+ * coff-ia64.c (howto_table): Use EMPTY_HOWTO.
+ (in_reloc_p): Add ATTRIBUTE_UNUSED to unused parameters.
+ * cpu-ia64-opc.c (ins_rsvd, ext_rsvd, ins_const, ext_const): Likewise.
+ (ins_imms_scaled): Initialize sign_bit at function entry.
+ (elf64_ia64_operands): Add missing initializers.
+ * elfxx-ia64.c (elfNN_ia64_reloc, elfNN_ia64_reloc_type_lookup,
+ elfNN_ia64_info_to_howto, elfNN_ia64_fake_sections,
+ elfNN_ia64_add_symbol_hook, elfNN_ia64_is_local_label_name,
+ elfNN_ia64_local_hash_table_init, get_fptr, get_pltoff,
+ elfNN_ia64_adjust_dynamic_symbol): Add ATTRIBUTE_UNUSED for unused
+ parameters.
+ (elfNN_ia64_info_to_howto): Initialize free_relocs, free_contents,
+ and free_extsyms at function entry.
+ (elfNN_add_symbol_hook): Add unsigned cast to bfd_get_gp_size result.
+ (elfNN_ia64_create_dynamic_sections): Delete unused local h.
+ (get_got): Delete unused local srel.
+ (elfNN_ia64_check_relocs): Initialize dynrel_type when declared.
+ (elfNN_ia64_relocate_section): Delete unused local dynindx.
+
+2000-11-21 Kazu Hirata <kazu@hxi.com>
+
+ * coff-a29k.c: Fix formatting.
+ * coff-h8500.c: Likewise.
+ * coff-i960.c: Likewise.
+ * coff-ppc.c: Likewise.
+ * coff-rs6000.c: Likewise.
+ * coff-stgo32.c: Likewise.
+ * coff-tic54x.c: Likewise.
+ * coff-w65.c: Likewise.
+ * cpu-h8500.c: Likewise.
+ * cpu-hppa.c: Likewise.
+ * cpu-ns32k.c: Likewise.
+ * ecoff.c: Likewise.
+ * ecofflink.c: Likewise.
+
+2000-11-21 Nick Clifton <nickc@redhat.com>
+
+ * elf32-sh.c (sh_elf_reloc_loop): Fix compile time warning, and
+ remove possibility of infinite loop.
+
+2000-11-20 Kazu Hirata <kazu@hxi.com>
+
+ * aix386-core.c: Fix formatting.
+ * aout-adobe.c: Likewise.
+ * aout-arm.c: Likewise.
+ * aout-encap.c: Likewise.
+ * aout-ns32k.c: Likewise.
+ * aout-target.h: Likewise.
+ * aout-tic30.c: Likewise.
+ * aoutf1.h: Likewise.
+ * aoutx.h: Likewise.
+ * archive.c: Likewise.
+ * bfd-in.h: Likewise.
+ * bfd-in2.h: Likewise.
+ * bfd.c: Likewise.
+ * bout.c: Likewise.
+
+2000-11-17 H.J. Lu <hjl@gnu.org>
+
+ * elfxx-ia64.c (elfNN_ia64_size_dynamic_sections): Don't create
+ pltoff entries for DT_INIT and DT_FINI.
+ (elfNN_ia64_final_link): Don't set DT_INIT/FINI entries.
+ (elfNN_ia64_finish_dynamic_sections): Don't fill in DT_INIT/FINI
+ entries.
+
+2000-11-16 Richard Henderson <rth@redhat.com>
+
+ * elfxx-ia64.c (elfNN_ia64_check_relocs): Handle IPLT relocs.
+ (allocate_dynrel_entries): Likewise.
+ (elfNN_ia64_relocate_section): Likewise. Set REL addends correctly.
+ (set_pltoff_entry): Likewise.
+ (ia64_howto_table): Remove R_IA64_SEGBASE, and R_IA64_EPLT[ML]SB
+ (elfNN_ia64_reloc_type_lookup): Likewise.
+ (elfNN_ia64_install_value): Likewise.
+ (elfNN_ia64_relocate_section): Likewise.
+ * reloc.c (BFD_RELOC_IA64_SEGBASE): Remove.
+ (BFD_RELOC_IA64_EPLTMSB, BFD_RELOC_IA64_EPLTLSB): Remove.
+
+2000-11-16 Kazu Hirata <kazu@hxi.com>
+
+ * cpu-a29k.c: Fix formatting.
+ * cpu-alpha.c: Likewise.
+ * cpu-arm.c: Likewise.
+ * cpu-avr.c: Likewise.
+ * cpu-d10v.c: Likewise.
+ * cpu-h8500.c: Likewise.
+ * cpu-hppa.c: Likewise.
+ * cpu-i370.c: Likewise.
+ * cpu-i386.c: Likewise.
+ * cpu-i960.c: Likewise.
+ * cpu-ia64-opc.c: Likewise.
+ * cpu-ia64.c: Likewise.
+ * cpu-m32r.c: Likewise.
+ * cpu-m68hc11.c: Likewise.
+ * cpu-m68hc12.c: Likewise.
+ * cpu-m68k.c: Likewise.
+ * cpu-m88k.c: Likewise.
+ * cpu-mips.c: Likewise.
+ * cpu-ns32k.c: Likewise.
+ * cpu-pj.c: Likewise.
+ * cpu-powerpc.c: Likewise.
+ * cpu-sh.c: Likewise.
+ * cpu-sparc.c: Likewise.
+ * cpu-tic54x.c: Likewise.
+ * cpu-v850.c: Likewise.
+ * cpu-vax.c: Likewise.
+ * cpu-w65.c: Likewise.
+ * cpu-we32k.c: Likewise.
+ * cpu-z8k.c: Likewise.
+ * dwarf1.c: Likewise.
+ * dwarf2.c: Likewise.
+
+2000-11-15 Kazu Hirata <kazu@hxi.com>
+
+ * coff-arm.c: Fix formatting.
+ * coff-ppc.c: Likewise.
+ * coff-rs6000.c: Likewise.
+ * coff-sh.c: Likewise.
+ * coff-sparc.c: Likewise.
+ * coff-tic30.c: Likewise.
+ * coff-tic54x.c: Likewise.
+ * coff-tic80.c: Likewise.
+ * coff-w65.c: Likewise.
+ * coff-we32k.c: Likewise.
+ * coff-z8k.c: Likewise.
+
+2000-11-15 Richard Henderson <rth@redhat.com>
+
+ * elf64-alpha.c (elf64_alpha_check_relocs): Create the reloc
+ section with the same ALLOC|LOAD flags as the source section.
+
+2000-11-14 Jakub Jelinek <jakub@redhat.com>
+
+ * elf64-alpha.c (elf64_alpha_relax_opt_call): Only check bits used
+ by STO_ALPHA constants.
+
+2000-11-14 Kazu Hirata <kazu@hxi.com>
+
+ * coff-pmac.c: Fix formatting.
+ * coff-ppc.c: Likewise.
+
+2000-11-13 H.J. Lu <hjl@gnu.org>
+
+ * elflink.h (elf_link_add_object_symbols): Also add indirect
+ symbols for common symbols with the default version.
+
+2000-11-09 Philip Blundell <pb@futuretv.com>
+
+ * section.c (STD_SECTION): Set gc_mark flag.
+
+2000-11-11 Kazu Hirata <kazu@hxi.com>
+
+ * coff-i960.c: Likewise.
+ * coff-m68k.c: Likewise.
+ * coff-m88k.c: Likewise.
+ * coff-mcore.c: Likewise.
+ * coff-mips.c: Likewise.
+
+2000-11-11 Bernd Schmidt <bernds@cygnus.co.uk>
+
+ * elf32-sh.c (sh_elf_relocate_section): Ignore R_SH_NONE relocs.
+
+2000-11-10 Kazu Hirata <kazu@hxi.com>
+
+ * coff-h8300.c: Fix formatting.
+ * coff-h8500.c: Likewise.
+ * coff-i386.c: Likewise.
+ * coff-i860.c: Likewise.
+ * coff-i960.c: Likewise.
+ * coff-ia64.c: Likewise.
+
+2000-11-09 Kazu Hirata <kazu@hxi.com>
+
+ * archive.c: Fix formatting.
+ * archures.c: Likewise.
+
+2000-11-07 Richard Henderson <rth@redhat.com>
+
+ * elfxx-ia64.c (elf64_ia64_final_link): New local unwind_output_sec.
+ Set it before bfd_elf64_bfd_final_link call. Use it after the call.
+ * section.c (bfd_set_section_contents): Call memcpy if
+ section->contents set and location not equal to contents plus offset.
+
+2000-11-08 Kazu Hirata <kazu@hxi.com>
+
+ * bfd-in.h: Fix formatting.
+ * bfd-in2.h: Likewise.
+ * bfd.c: Likewise.
+ * binary.c: Likewise.
+ * bout.c: Likewise.
+ * coff-a29k.c: Likewise.
+ * coff-alpha.c: Likewise.
+ * coff-apollo.c: Likewise.
+ * coff-aux.c: Likewise.
+
+2000-11-07 Kazu Hirata <kazu@hxi.com>
+
+ * aix386-core.c: Fix formatting.
+ * aoutf1.h: Likewise.
+ * aoutx.h: Likewise.
+ * archures.c: Likewise.
+ * armnetbsd.c: Likewise.
+
+2000-11-07 Alan Modra <alan@linuxcare.com.au>
+
+ * coff-h8300.c (special): Adjust reloc address.
+
+2000-11-06 Steve Ellcey <sje@cup.hp.com>
+
+ * archures.c (bfd_mach_ia64_elf64, bfd_mach_ia64_elf32): Add defines
+ to differentiate elf32 and elf64 on ia64.
+ * bfd-in2.h: Regenerate.
+ * config.bfd: Add target for "ia64*-*-hpux*".
+ * configure.in: Add bfd_elf32_ia64_big_vec to selvecs switch.
+ * configure: Regenerate.
+ * cpu-ia64.c (bfd_ia64_elf32_arch): Add elf32 arch info structure.
+ * targets.c: Add bfd_target bfd_elf32_ia64_big_vec.
+
+ * Makefile.am: Make elf32-ia64.c and elf64-ia64.c derived objects
+ from elfxx-ia64.c. Add depenency rules for making elf32-ia64.lo.
+ * Makefile.in: Regnerate.
+ * elf64-ia64.c: Deleted.
+ * elfxx-ia64.c: New file, paramaterized version of elf64-ia64.c.
+
+2000-11-06 Kazu Hirata <kazu@hxi.com>
+
+ * aout-adobe.c: Fix formatting.
+ * aout-arm.c: Likewise.
+ * aout-cris.c: Likewise.
+ * aout-encap.c: Likewise.
+ * aout-ns32k.c: Likewise.
+ * aout-target.h: Likewise.
+ * aout-tic30.c: Likewise.
+
+2000-11-05 Philip Blundell <philb@gnu.org>
+
+ * elf32-arm.h (elf32_arm_merge_private_bfd_data): Always permit
+ BFDs containing no sections to be merged, regardless of their flags.
+
+2000-11-04 Philip Blundell <philb@gnu.org>
+
+ * elf32-arm.h (elf32_arm_relocate_section): Suppress error message
+ if a relocation for an undefined symbol also results in an
+ overflow.
+
+2000-11-06 Christopher Faylor <cgf@cygnus.com>
+
+ * config.bfd: Add support for Sun Chorus.
+
+2000-11-05 David O'Brien <obrien@FreeBSD.org>
+
+ * configure.in: Recognize alpha-*-freebsd*.
+ * configure: Regenerate.
+
+2000-11-02 Luciano Gemme <ishitawa@yahoo.com>
+
+ * srec.c (CHUNK): Rename to DEFAULT_CHUNK.
+ (Chunk): New global variable set by a parameter in objcopy.c.
+ (S3Forced): New global variable set by a parameter in
+ objcopy.c.
+ (srec_set_section_contents): If S3Forced is true, always generate
+ S3 records.
+ (srec_write_section): Use 'Chunk' to limit maximum length of S
+ records.
+
+2000-11-02 Per Lundberg <plundis@chaosdev.org>
+
+ * config.bfd: Add support for i[3456]86-chaosdev-storm-chaos.
+ * Makefile.in: Regenerate.
+ * bfd-in2.h: Regenerate.
+ * po/bfd.pot: Regenerate.
+
+2000-10-31 Philip Blundell <philb@gnu.org>
+
+ * elf32-arm.h (elf32_arm_merge_private_bfd_data): Only handle
+ EF_SOFT_FLOAT if it is defined.
+
+2000-10-27 Philip Blundell <philb@gnu.org>
+
+ * elf32-arm.h (elf32_arm_copy_private_bfd_data): Don't refuse
+ attempts to mix PIC code with non-PIC, just mark the output as
+ being position dependent.
+ (elf32_arm_merge_private_bfd_data): Likewise. Print an error
+ message for EF_SOFT_FLOAT mismatches. Display diagnostics for
+ all mismatches, not just the first one.
+
+2000-10-25 Chris Demetriou <cgd@sibyte.com>
+
+ * ieee.c (ieee_archive_p): Plug one of many possible
+ memory leaks in error handling.
+
+2000-10-20 Jakub Jelinek <jakub@redhat.com>
+
+ * elf32-sparc.c (elf32_sparc_merge_private_bfd_data,
+ elf32_sparc_object_p, elf32_sparc_final_write_processing):
+ Support v8plusb.
+ * elf64-sparc.c (sparc64_elf_merge_private_bfd_data,
+ sparc64_elf_object_p): Support v9b.
+ * archures.c: Declare v8plusb and v9b machines.
+ * bfd-in2.h: Ditto.
+ * cpu-sparc.c: Ditto.
+
+2000-10-16 Geoffrey Keating <geoffk@shoggoth.cygnus.com>
+
+ * elf64-sparc.c (sparc64_elf_relocate_section): Clear the location
+ of a GOT reloc.
+
+ * elf32-ppc.c (SYMBOL_REFERENCES_LOCAL): New macro.
+ (SYMBOL_CALLS_LOCAL): New macro.
+ (ppc_elf_adjust_dynamic_symbol): Use SYMBOL_CALLS_LOCAL.
+ (ppc_elf_check_relocs): Use SYMBOL_REFERENCES_LOCAL.
+ (ppc_elf_finish_dynamic_symbol): Use SYMBOL_REFERENCES_LOCAL.
+ (ppc_elf_relocate_section): Use flag variable to determine
+ whether the relocation refers to a local symbol.
+ Test whether a PLTREL24 reloc will produce a reloc by looking
+ to see whether a PLT entry was made.
+
+2000-10-14 Geoffrey Keating <geoffk@shoggoth.cygnus.com>
+
+ * elf32-ppc.c (ppc_elf_finish_dynamic_symbol): Don't make PLT
+ entries that could serve as a definition for a weak symbol.
+
+2000-10-13 Ulf Carlsson <ulfc@engr.sgi.com>
+
+ From Ralf Baechle <ralf@gnu.org>
+
+ * elf32-mips.c (mips_elf_create_dynamic_relocation): New argument
+ local_p. Add symbol value only for non-R_MIPS_REL32 relocations
+ against local symbols.
+ (_bfd_mips_elf_finish_dynamic_sections): Undo patch from 2000-10-01.
+
+2000-10-12 Alan Modra <alan@linuxcare.com.au>
+
+ * section.c (struct sec): Add kept_section.
+ (struct bfd_comdat_info): Remove sec, we can use above.
+ (STD_SECTION): Add initializer.
+ (bfd_make_section_anyway): Init here too.
+
+ * bfd-in2.h: Regenerate.
+
+ * elflink.h (elf_link_add_object_symbols): Remove unnecessary
+ zeroing of `flags'.
+ (elf_link_input_bfd): Set all asection->symbol->value's here, and
+ fudge values for discarded link-once section symbols.
+
+ * elf64-hppa.c: Include alloca-conf.h
+
+2000-10-11 Alan Modra <alan@linuxcare.com.au>
+
+ * elf.c (swap_out_syms): Revert 2000-10-07 changes.
+
+ * ieee.c (ieee_make_empty_symbol): Oops, bfd_zalloc needs another arg.
+
+2000-10-10 Alan Modra <alan@linuxcare.com.au>
+
+ * ieee.c (ieee_make_empty_symbol): Use bfd_zalloc, not bfd_zmalloc.
+
+2000-10-10 Tom Rix <trix@redhat.com>
+
+ * section.c (bfd_make_section_anyway): Release newsect ptr when
+ newsect->symbol fails to alloc. Use bfd_release instead of free.
+
+2000-10-09 Richard Henderson <rth@cygnus.com
+
+ * elf64-ia64.c (elf64_ia64_unwind_entry_compare_bfd): New.
+ (elf64_ia64_unwind_entry_compare): New.
+ (elf64_ia64_final_link): Sort the .IA_64.unwind section.
+
+2000-10-07 Alan Modra <alan@linuxcare.com.au>
+
+ * elflink.h (size_dynamic_sections): Don't create various tags if
+ .dynstr is excluded from the link. Don't set first dynsym entry
+ if dynsymcount is zero.
+ (elf_bfd_final_link): Don't try to swap out dynamic syms if
+ .dynsym excluded from the link. Don't try to write any dynamic
+ sections excluded from the link.
+
+ * elf.c (swap_out_syms): Handle global section symbols.
+
+2000-10-05 DJ Delorie <dj@redhat.com>
+
+ * peigen.c (_bfd_pei_swap_scnhdr_out): note extended relocs
+ * coffcode.h (coff_set_alignment_hook): read extended reloc count
+ (coff_write_relocs): write extended reloc count
+ (coff_write_object_contents): account for extended relocs
+
+2000-10-05 Jim Wilson <wilson@cygnus.com>
+
+ * elf-bfd.h (struct elf_backend_data): Add elf_backend_section_flags
+ field.
+ * elf.c (_bfd_elf_make_section_from_shdr): Call the
+ elf_backend_section_flags function.
+ * elf64-ia64.c (elf64_ia64_section_from_shdr): Delete flag conversion
+ code.
+ (elf64_ia64_section_flags): New function containing flag conversion
+ code.
+ (elf_backend_section_flags): Define to elf64_ia64_section_flags.
+ * elfxx-target.h (elf_backend_section_flags): Define.
+ (elfNN_bed): Initialize elf_backend_section_flags field.
+
+2000-10-02 Alan Modra <alan@linuxcare.com.au>
+
+ * elf32-hppa.c (elf32_hppa_check_relocs): Correct call to
+ _bfd_elf32_gc_record_vtable. Correct a comment.
+
+2000-10-01 Ulf Carlsson <ulfc@engr.sgi.com>
+
+ From Ralf Baechle <ralf@gnu.org>
+
+ * elf32-mips.c (_bfd_mips_elf_finish_dynamic_sections): Mark gld
+ produces binaries with got[1] = 0x80000001 to differenciate them
+ for the dynamic linker from the broken binaries produced by old
+ versions.
+
+2000-09-30 Petr Sorfa <petrs@sco.com>
+
+ * elf.c (elfcore_grok_pstatus): Check for size of pxstatus_t.
+ (elfcore_grok_lwpstatus): Check for size of lwpxstatus_t.
+ * configure.in: Add check for pxstatus_t and lwpxstatus_t.
+ * configure: Regenerate.
+
+2000-09-27 Hans-Peter Nilsson <hp@axis.com>
+
+ Define two bfd_targets for absence and presence of leading
+ underscore on symbols. Make sure to only link same kind.
+ * elf32-cris.c (cris_elf_object_p,
+ cris_elf_final_write_processing, cris_elf_print_private_bfd_data,
+ cris_elf_merge_private_bfd_data): New.
+ (elf_backend_object_p, elf_backend_final_write_processing,
+ bfd_elf32_bfd_print_private_bfd_data,
+ bfd_elf32_bfd_merge_private_bfd_data): Define.
+ <Target vector definition>: Include elf32-target.h twice with
+ different macro settings:
+ (TARGET_LITTLE_SYM): First as bfd_elf32_cris_vec, then as
+ bfd_elf32_us_cris_vec.
+ (TARGET_LITTLE_NAME): First as "elf32-cris", then "elf32-us-cris".
+ (elf_symbol_leading_char): First as 0, then '_'.
+ (INCLUDED_TARGET_FILE): Define for second include of elf32-target.h.
+ * config.bfd (cris-*-*): Add bfd_elf32_us_cris_vec to targ_selvecs.
+ * configure.in (bfd_elf32_cris_vec, cris_aout_vec): New vector.
+ * configure: Regenerate.
+ * targets.c: Declare bfd_elf32_us_cris_vec.
+ * po/bfd.pot: Regenerate.
+
+2000-09-29 Momchil Velikov <velco@fadata.bg>
+
+ * elf32-arm.h (arm_add_to_rel): Correctly adjust the addend for
+ R_ARM_THM_PC22 relocations.
+
+2000-09-29 NIIBE Yutaka <gniibe@chroot.org>
+
+ * elflink.h (elf_link_add_object_symbols): Don't bfd_release runpath.
+
+2000-09-29 Momchil Velikov <velco@fadata.bg>
+
+ * elf.c (elf_fake_sections): Do not mark the section SHT_NOBITS if
+ is has the SEC_HAS_CONTENTS flag set.
+
+2000-09-28 Örjan Friberg <orjanf@axis.com>
+ Hans-Peter Nilsson <hp@axis.com>
+
+ * aout-cris.c (N_TXTADDR): Define.
+
+2000-09-28 John David Anglin <dave@hiauly1.hia.nrc.ca>
+
+ * som.c: Include alloca-conf.h.
+ * Makefile.am: "make dep-am"
+ * Makefile.in: Regenerate.
+
+2000-09-27 Alan Modra <alan@linuxcare.com.au>
+
+ * elf32-hppa.c (plt_stub): New.
+ (PLT_STUB_ENTRY): Define.
+ (elf32_hppa_link_hash_table): Change multi_subspace to packed
+ boolean. Add need_plt_stub, has_12bit_branch and has_17bit_branch.
+ (elf32_hppa_link_hash_table_create): Init to suit.
+ (elf32_hppa_check_relocs): Set has_12bit_branch and
+ has_17bit_branch as appropriate.
+ (elf32_hppa_adjust_dynamic_symbol): Set need_plt_stub for
+ non-local functions.
+ (elf32_hppa_size_dynamic_sections): Correct setting of reltext.
+ Add space for plt_stub as needed.
+ (elf32_hppa_finish_dynamic_symbol): Point .plt entries for global
+ functions at plt_stub.
+ (elf32_hppa_finish_dynamic_sections): Write plt_stub.
+ (elf32_hppa_create_dynamic_sections): Leave .plt executable.
+
+ * elf32-hppa.h (elf32_hppa_size_stubs): Add group_size param.
+ * elf32-hppa.c (elf32_hppa_size_stubs): Likewise. Use it instead
+ of fixed size, and if negative, disable handling of input sections
+ before stub section. Set up default stub group size depending
+ on detected branch relocs.
+ (hppa_build_one_stub): Use lrsel and rrsel for import stubs to
+ ensure different offsets from sym_value aren't rounded to
+ different 2k blocks. Use lrsel and rrsel for other stubs too for
+ consistency rather than necessity.
+ (elf32_hppa_check_relocs): Handle R_PARISC_DIR14F.
+ (final_link_relocate): Likewise.
+ (elf32_hppa_relocate_section): Likewise.
+
+ * elf-hppa.h (elf_hppa_howto_table): Add R_PARISC_DIR14F reloc.
+ (_bfd_elf_hppa_gen_reloc_type): Generate them.
+ (elf_hppa_final_link_relocate): Handle them.
+ (elf_hppa_relocate_insn): Likewise.
+ (_bfd_elf_hppa_gen_reloc_type): Add missing e_ldsel and e_rdsel cases.
+
+2000-09-26 Hans-Peter Nilsson <hp@axis.com>
+
+ * elfcode.h (elf_object_p): Preserve and clear abfd section
+ information. Restore at error.
+
+2000-09-26 Paul Sokolovsky <Paul.Sokolovsky@technologist.com>
+
+ * peigen.c (_bfd_pei_swap_aouthdr_in): If some DataDirectory
+ is empty, make sure that its rva also 0. NT loader dislikes
+ having otherwise.
+
+2000-09-26 Steve Ellcey <sje@cup.hp.com>
+
+ * som.c (som_bfd_derive_misc_symbol_info): Make weak symbols
+ global by default.
+
+2000-09-21 Alan Modra <alan@linuxcare.com.au>
+
+ * elf32-hppa.c (elf32_hppa_check_relocs): Fix weak sym handling in
+ currently unused RELATIVE_DYNAMIC_RELOCS code.
+ (hppa_discard_copies): Likewise.
+ (elf32_hppa_size_stubs): Size `input_list' array correctly. Correct
+ comments. Don't check non-code output sections for stub grouping.
+
+2000-09-20 Alan Modra <alan@linuxcare.com.au>
+
+ * section.c (bfd_get_unique_section_name): Return NULL if
+ bfd_malloc fails.
+
+2000-09-19 Michael Sokolov <msokolov@ivan.Harhan.ORG>
+
+ * elf32-m68k.c (elf_cpu32_plt0_entry): Change the PLT entry 0
+ instruction sequence to actually work.
+ (elf_m68k_finish_dynamic_sections): Change the patch-in offset
+ accordingly.
+
+2000-09-18 Alexandre Oliva <aoliva@redhat.com>
+
+ * elf32-sh.c (sh_elf_relocate_section): Use
+ _bfd_final_link_relocate to apply the relocation against a section
+ symbol, when doing relocatable links.
+
+2000-09-18 Alan Modra <alan@linuxcare.com.au>
+
+ * elf32-hppa.c (elf32_hppa_stub_hash_entry): Rename input_section
+ to id_sec.
+ (stub_hash_newfunc): Here too.
+ (hppa_add_stub): And here.
+ (elf32_hppa_link_hash_table): Remove stub_section_created,
+ reloc_section_created, first_init_sec and first_fini_sec. Add
+ stub_group.
+ (elf32_hppa_link_hash_table_create): Init to suit.
+ (hppa_get_stub_entry): Add support for grouping stub sections.
+ (hppa_add_stub): Likewise. Remove sec_count param and init/fini
+ section code. Index stub vars by section->id.
+ (elf32_hppa_size_stubs): Likewise. Remove duplicated function
+ exit paths. Zap allocation of above removed vars. Refine
+ link-once test.
+
+ * elf32-hppa.h (elf32_hppa_size_stubs): Add output_bfd param.
+ * elf32-hppa.c (elf32_hppa_size_stubs): Likewise.
+ (hppa_get_stub_entry): Pass in pointer to elf32_hppa_link_hash_table
+ rather than pointer to bfd_link_info.
+ (hppa_add_stub): Likewise.
+ (final_link_relocate): Likewise.
+
+2000-09-17 David Huggins-Daines <dhd@linuxcare.com>
+
+ (elf32_hppa_size_stubs): Don't try to build stubs for discarded
+ link-once sections.
+
+2000-09-16 Alexandre Oliva <aoliva@redhat.com>
+
+ * elf32-sh.c (ELF_MAXPAGESIZE): Define to 128, to match
+ ld/emulparams/shelf.sh.
+
+2000-09-10 Michael Sokolov <msokolov@ivan.Harhan.ORG>
+
+ * elf32-m68k.c (bfd_m68k_elf32_create_embedded_relocs): New function.
+ * bfd-in.h (bfd_m68k_elf32_create_embedded_relocs): Add declaration.
+ * bfd-in2.h: Regenerate.
+
+2000-09-15 Kenneth Block <Kenneth.Block@compaq.com>
+
+ * elf64-alpha.c (elf64_alpha_relax_with_lituse): ld performs
+ LITUSE relocations incorrectly if -relax is specified on the ld
+ command line and the displacement field of the load or store
+ instruction is non-zero. (Patch by paul.winalski@compaq.com)
+
+2000-09-15 Alan Modra <alan@linuxcare.com.au>
+
+ * elf32-hppa.c (hppa_add_stub): Dont set first_init_sec and
+ first_fini_sec here.
+ (elf32_hppa_size_stubs): Instead correctly find the first .init
+ and .fini section here.
+
+2000-09-15 David Huggins-Daines <dhd@linuxcare.com>
+
+ * elf32-hppa.c (clobber_millicode_symbols): New function.
+ (elf32_hppa_size_dynamic_sections): Call it.
+
+2000-09-14 Alan Modra <alan@linuxcare.com.au>
+
+ * elf32-hppa.c (elf32_hppa_link_hash_entry): Make pic_call
+ packed. Add plabel, plt_abs packed booleans.
+ (hppa_link_hash_newfunc): Init new fields.
+ (PLABEL_PLT_ENTRY_SIZE): Define.
+ (hppa_stub_name): Use size_t len vars.
+ (hppa_add_stub): Likewise.
+ (elf32_hppa_build_stubs): Likewise.
+ (hppa_build_one_stub): Kill some compiler warnings.
+ (elf32_hppa_check_relocs): Always generate a plt entry for PLABELs
+ if dynamic linking. Munge the local plt offsets into
+ local_got_refcounts. Set h->plabel for all global PLABELs. Use
+ size_t len vars. Add assert for plabel addend.
+ (elf32_hppa_gc_sweep_hook): Sweep local plt entries too.
+ (elf32_hppa_hide_symbol): New function.
+ (elf_backend_hide_symbol): Define.
+ (elf32_hppa_adjust_dynamic_symbol): Don't throw away plt entries
+ with h->plabel set. Don't make plt entries to have dynamic syms
+ when they have been forced local. If plt entry is used by a
+ plabel, make it PLABEL_PLT_ENTRY_SIZE.
+ (elf32_hppa_size_dynamic_sections): Set plt_abs for init fns.
+ Set up .plt offsets for local syms.
+ (elf32_hppa_relocate_section): Initialise plt entries for local
+ syms. Leave weak undefined plabels zero. Make global plabel
+ relocs against function symbol, and leave the addend zero.
+ Use *ABS* DIR32 relocs instead of SEGREL32 for dynamic got relocs.
+ (elf32_hppa_finish_dynamic_symbol): Set up IPLT relocs for
+ non-dynamic syms. Init extra plt for plabels. Use *ABS* DIR32
+ relocs instead of SEGREL32 for dynamic got relocs.
+ (elf32_hppa_finish_dynamic_sections): Reserve one more .got entry.
+ (elf_backend_got_header_size): Adjust.
+ (elf32_hppa_set_gp): Calculate an "ideal" LTP.
+
+ * elf32-hppa.c (LONG_BRANCH_VIA_PLT): Define.
+ (hppa_type_of_stub): Use it instead of #if 0
+ (hppa_discard_copies): Use it here too.
+ (elf32_hppa_size_dynamic_sections): And here.
+
+ * elf32-hppa.c (elf32_hppa_link_hash_table): Remove `offset' field.
+ (elf32_hppa_link_hash_table_create): And here.
+ (hppa_build_one_stub): And here. Instead keep track of stub
+ offset using _raw_size.
+ (elf32_hppa_size_stubs): Likewise.
+ (elf32_hppa_build_stubs): Likewise.
+ (hppa_size_one_stub): Likewise. Resize reloc section too.
+
+ * elf32-hppa.c (hppa_add_stub): Correct first_init_sec and
+ first_fini_sec handling. Don't search for reloc section or set
+ hplink->reloc_section_created here.
+ (elf32_hppa_size_stubs): Instead search for reloc sections, and
+ set reloc_section_created here.
+ (hppa_handle_PIC_calls): Set ELF_LINK_HASH_NEEDS_PLT.
+ (elf32_hppa_size_dynamic_sections): Make a .plt entry for DT_INIT
+ and DT_FINI.
+ (elf32_hppa_finish_dynamic_sections): Set DT_INIT and DT_FINI.
+
+ * elf32-hppa.c (hppa_build_one_stub): Replace `elf_hash_table (info)'
+ with `hplink->root.'.
+ (elf32_hppa_check_relocs): Likewise.
+ (elf32_hppa_gc_sweep_hook): Likewise.
+ (elf32_hppa_adjust_dynamic_symbol): Likewise.
+ (hppa_handle_PIC_calls): Likewise.
+ (elf32_hppa_size_dynamic_sections): Likewise.
+ (elf32_hppa_set_gp): Likewise.
+ (elf32_hppa_relocate_section): Likewise.
+ (elf32_hppa_finish_dynamic_symbol): Likewise.
+ (elf32_hppa_finish_dynamic_sections): Likewise.
+
+ From David Huggins-Daines <dhd@linuxcare.com>
+ * elf32-hppa.c (hppa_type_of_stub): Generate import stubs for
+ defined weak symbols in shared links.
+ (final_link_relocate): Calls to defined weak symbols in shared
+ objects must go via import stubs, as the target might not be known
+ at link time.
+
+2000-09-14 Alexandre Oliva <aoliva@redhat.com>
+
+ * elf32-sh.c (sh_elf_howto_table): Moved R_SH_GOT32, R_SH_PLT32,
+ R_SH_COPY, R_SH_GLOB_DAT, R_SH_JMP_SLOT, R_SH_RELATIVE,
+ R_SH_GOTOFF, R_SH_GOTPC) to the range from 160 to 167. Replaced
+ the original entries with EMPTY_HOWTOs, and added new ones to fill
+ in the gap.
+ (sh_elf_info_to_howto): Make sure the new gap isn't used.
+ (sh_elf_relocate_section): Likewise.
+
+2000-09-13 Anders Norlander <anorland@acc.umu.se>
+
+ * cpu-mips.c (arch_info_struct): Add mips:4K
+ * bfd-in2.h (bfd_mach_mips4K): New define.
+ * archures.c: Add bfd_mach_mips4K to comment.
+ * elf32-mips.c (_bfd_mips_elf_final_write_processing): Return
+ E_MIPS_ARCH_2 for bfd_mach_mips4K.
+
+2000-09-13 Marco Franzen <marcof@thyron.com>
+
+ * som.c (som_write_symbol_strings): Do not used fixed buffers,
+ use size_t as a counter.
+ (som_write_space_strings): Similarly.
+
+2000-09-12 Jason Eckhardt <jle@cygnus.com>
+
+ * elf32-i860.c (elf32_i860_relocate_pc26): New function
+ and prototype.
+ (elf32_i860_relocate_section): Invoke new function from here.
+
+2000-09-11 Michael Sokolov <msokolov@ivan.Harhan.ORG>
+
+ * elf.c (_bfd_elf_make_section_from_shdr): Make debug_sec_names
+ static.
+
+2000-09-10 Michael Sokolov <msokolov@ivan.Harhan.ORG>
+
+ * coff-m68k.c (bfd_m68k_coff_create_embedded_relocs): Emit 8 NULs for
+ target section name instead of dumping core when the target symbol is
+ undefined.
+
+2000-09-09 Kazu Hirata <kazu@hxi.com>
+
+ * riscix.c: Remove DEFUN.
+
+2000-09-08 Nick Clifton <nickc@redhat.com>
+
+ * elf32-arm.h (elf32_arm_merge_private_bfd_data): Do not
+ initialise flags in output bfd if the input bfd is the default
+ architecture with the default flags.
+
+2000-09-08 Kazu Hirata <kazu@hxi.com>
+
+ * archive.c: Fix formatting.
+ * coff-arm.c: Likewise.
+ * doc/chew.c: Likewise.
+
+2000-09-08 Alan Modra <alan@linuxcare.com.au>
+
+ * section.c (bfd_get_unique_section_name): Put a dot before the
+ numeric suffix.
+
+2000-09-07 Kazu Hirata <kazu@hxi.com>
+
+ * doc/chew.c: Remove all uses of DEFUN and DEFUN_VOID.
+ * elf.c: Fix formatting.
+
+2000-09-07 Alexandre Oliva <aoliva@redhat.com>
+
+ * config.bfd (sh-*-linux*): Added.
+ * configure.in (bfd_elf32_shlin_vec, bfd_elf32_shblin_vec): New.
+ * targets.c: Declare them.
+ * elf32-sh-lin.c: New file.
+ * Makefile.am: Compile it.
+ * elf32-sh.c: Don't override defines from elf32-sh-lin.c.
+ * configure, Makefile.in: Rebuilt.
+
+2000-09-06 Geoffrey Keating <geoffk@cygnus.com>
+
+ * xcofflink.c (xcoff_link_input_bfd): Include the .tocbss
+ pseduo-section when determining where the TOC ends.
+
+ * coff-rs6000.c (_bfd_xcoff_swap_aux_out): Use bfd_h_put_16 to
+ output x_tvndx as it is only two bytes wide.
+
+ * coff-rs6000.c (xcoff_howto_table): A modifiable branch-absolute
+ reloc is 26 or 32 bits wide.
+
+ * coff-rs6000.c (_bfd_xcoff_rtype2howto): The bitsize is irrelevant
+ for relocs that don't change anything. Also look at the full
+ 6 bits of bitsize.
+
+2000-09-06 Philip Blundell <philb@gnu.org>
+
+ * config.bfd (arm*-*-uclinux*): New target.
+
+2000-09-06 Alexandre Oliva <aoliva@redhat.com>
+
+ * configure: Rebuilt with new libtool.m4.
+
+2000-09-06 Alan Modra <alan@linuxcare.com.au>
+
+ * section.c (bfd_get_unique_section_name): Avoid c++ reserved
+ word for variable name.
+ * bfd-in2.h: Regenerate.
+
+2000-09-05 Nick Clifton <nickc@redhat.com>
+
+ * config.in: Regenerate.
+ * libbfd.h: Regenerate.
+ * po/bfd.pot: Regenerate.
+ * doc/bfdint.texi: Remove CVS date string - it foils compares with
+ local versions.
+
+2000-09-05 Steven Johnson <sbjohnson@ozemail.com.au>
+
+ * cpu-powerpc.c (arch_info_struct): Added MPC860 Family entry.
+
+2000-09-05 Alan Modra <alan@linuxcare.com.au>
+
+ Shared library and PIC support.
+ * elf32-hppa.c (PLT_ENTRY_SIZE): New.
+ (GOT_ENTRY_SIZE): New.
+ (ELF_DYNAMIC_INTERPRETER): New.
+ (STUB_SUFFIX): Define.
+ (LONG_BRANCH_PIC_IN_SHLIB): Define.
+ (RELATIVE_DYNAMIC_RELOCS): Define.
+ (enum elf32_hppa_stub_type): New.
+ (struct elf32_hppa_stub_hash_entry): Rename offset to
+ stub_offset. Add a number of new fields.
+ (struct elf32_hppa_link_hash_entry): New.
+ (struct elf32_hppa_link_hash_table): Add numerous fields. Remove
+ global_value.
+ (elf32_hppa_hash_table): Rename to hppa_link_hash_table.
+ (elf32_hppa_stub_hash_lookup): Rename to hppa_stub_hash_lookup.
+ (elf32_hppa_stub_hash_newfunc): Rename to stub_hash_newfunc. Init
+ new fields.
+ (hppa_link_hash_newfunc): New function.
+ (elf32_hppa_link_hash_table_create): Use above function. Init new
+ fields.
+ (elf32_hppa_stub_name): Rename to hppa_stub_name. Pass in reloc
+ instead of addend, and remove sym_name from args. Don't use
+ symbol name for local syms, instead use sym index.
+ (elf32_hppa_size_of_stub): Rename to hppa_type_of_stub, and return
+ stub type rather than size. Pass in hash and handle import stub
+ case. Also pass in reloc instead of offset so we can calculate
+ PCREL22F and PCREL12F branches properly.
+ (elf32_hppa_build_one_stub): Rename to hppa_build_one_stub. Build
+ import and export stubs too.
+ (elf32_hppa_size_one_stub): Rename to hppa_size_one_stub. Handle
+ import and export stub sizing.
+ (elf32_hppa_check_relocs): New function.
+ (elf32_hppa_adjust_dynamic_symbol): New function.
+ (hppa_discard_copies): New function.
+ (elf32_hppa_size_dynamic_sections): New function.
+ (elf_backend_size_dynamic_sections): Define.
+ (elf32_hppa_finish_dynamic_symbol): New function.
+ (elf_backend_finish_dynamic_symbol): Define.
+ (elf32_hppa_size_stubs): Stash params in link hash table, and move
+ some local vars into the link hash table too. For shared links,
+ trundle over function syms, generating export stubs. Handle
+ PCREL22F branches. Break out stub creation code from here..
+ (hppa_add_stub): .. to here. New function.
+ (elf32_hppa_final_link): Rename to elf32_hppa_set_gp, and don't
+ call the bfd linker. Use elf_gp to record global pointer.
+ Calculate a value from sections if $global$ is missing.
+ (bfd_elf32_bfd_final_link): Define as _bfd_elf32_gc_common_final_link.
+ (elf32_hppa_gc_mark_hook): New function.
+ (elf_backend_gc_mark_hook): Define.
+ (elf32_hppa_gc_sweep_hook): New function.
+ (elf_backend_gc_sweep_hook): Define.
+ (elf32_hppa_bfd_final_link_relocate): Rename to final_link_relocate.
+ Add rel to args, and remove howto, input_bfd, offset, addend,
+ sym_name as we can recalculate these locally. Handle calls to
+ dynamic objects, extra PIC relocs, PCREL22F branches. Change
+ handling of undefined weak syms. Check that stubs are in range.
+ Only look for import stubs on PCREL17F and PCREL22F relocs. Add
+ message on hitting a DPREL21L reloc that needs fixing. Subtract
+ off PC for PCREL14F. Break out code that does a stub lookup from
+ here..
+ (hppa_get_stub_entry): ..to here. New function.
+ (elf32_hppa_relocate_insn): Merge into final_link_relocate.
+ (elf32_hppa_relocate_section): Handle got and plt relocs, dynamic
+ relocs, etc. etc.
+ (elf32_hppa_finish_dynamic_sections): New function.
+ (elf_backend_finish_dynamic_sections): Define.
+ (elf_backend_final_write_processing) Define.
+ (hppa_handle_PIC_calls): New function.
+ (elf32_hppa_build_stubs): Call it. Pass link_info to
+ hppa_build_one_stub.
+ (elf32_hppa_create_dynamic_sections): New function
+ to create .plt and .got then set .plt flags correctly.
+ (elf_backend_create_dynamic_sections): Define.
+ (elf32_hppa_object_p): New function.
+ (elf_backend_object_p): Define.
+ (elf32_hppa_elf_get_symbol_type): New function.
+ (elf_backend_get_symbol_type): Define.
+ (elf_backend_can_gc_sections): Define.
+ (elf_backend_want_got_plt): Define.
+ (elf_backend_plt_alignment): Set to 2.
+ (elf_backend_plt_readonly): Define.
+ (elf_backend_want_plt_sym): Define.
+ (elf_backend_got_header_size): Reserve one entry.
+
+ * elf32-hppa.h (elf32_hppa_build_stubs): Don't pass stub bfd.
+ (elf32_hppa_size_stubs): Pass in multi_subspace.
+ (elf32_hppa_set_gp): Declare.
+
+ * section.c (SEC_HAS_GOT_REF): Define new flag for asection.
+ (bfd_get_unique_section_name): New function.
+ * bfd-in2.h: Regenerate.
+
+ * elf64-hppa.c (elf64_hppa_check_relocs): Handle R_PARISC_PCREL12F.
+ (elf64_hppa_size_dynamic_sections): Remove the FIXME at bfd_zalloc
+ comment.
+
+ From David Huggins-Daines <dhd@linuxcare.com>
+ * elf64-hppa.c (elf64_hppa_check_relocs): Fix a warning.
+ (elf64_hppa_mark_exported_functions): Set dyn_h->st_shndx.
+ (elf64_hppa_link_output_symbol_hook): Test dyn_h->st_shndx has
+ been updated in finish_dynamic_symbol before modifying function
+ symbol.
+
+ * elf-hppa.h (elf_hppa_howto_table): Restructure into groups of
+ eight entries. Replace NULL with bfd_elf_generic_reloc. Add
+ R_PARISC_GNU_VTENTRY, R_PARISC_GNU_VTINHERIT and R_PARISC_PCREL12F.
+ (_bfd_elf_hppa_gen_reloc_type): Handle R_PARISC_GNU_VT*. Add some
+ comments. Handle format == 12 for R_HPPA_PCREL_CALL.
+ (elf_hppa_final_link_relocate): Handle R_PARISC_PCREL12F.
+ (elf_hppa_relocate_insn): Likewise. Reformat some comments.
+ (elf_hppa_final_write_processing): Expose it for ARCH_SIZE == 32.
+
+ From David Huggins-Daines <dhd@linuxcare.com>
+ * elf-hppa.h (elf_hppa_is_local_label_name): Accept the SysV/ELF
+ style of local labels as well.
+
+2000-09-03 Philip Blundell <philb@gnu.org>
+
+ * elf32-arm.h (elf32_arm_relocate_section): Don't try to relocate
+ references to undefined symbols in debugging sections.
+
+2000-09-02 H.J. Lu <hjl@gnu.org>
+
+ * reloc.c (BFD_RELOC_SH_COPY, BFD_RELOC_SH_GLOB_DAT,
+ BFD_RELOC_SH_JMP_SLOT, BFD_RELOC_SH_RELATIVE,
+ BFD_RELOC_SH_GOTPC): Move them from the MIPS section to the SH
+ section.
+
+2000-09-02 Jason Eckhardt <jle@cygnus.com>
+
+ * elf32-i860.c (bfd_elf32_bfd_is_local_label_name): Define macro.
+ (elf32_i860_is_local_label_name): New function and prototype.
+
+2000-09-02 Nick Clifton <nickc@redhat.com>
+
+ * configure.in: Increase version number to 2.10.91.
+ * configure: Regenerate.
+ * aclocal.m4: Regenerate.
+ * config.in: Regenerate.
+ * po/bfd.pot: Regenerate.
+
+2000-09-02 Daniel Berlin <dberlin@redhat.com>
+
+ * elf.c (_bfd_elf_make_section_from_shdr): Add
+ .gnu.linkobce.wi. to the list of debug section names.
+
+2000-09-02 Nick Clifton <nickc@redhat.com>
+
+ * dwarf2.c (find_debug_info): New function: Locate a section
+ containing dwarf2 debug information.
+ (bfd_dwarf2_find_nearest_line): Find all sections containing
+ debug information and include them in the stash.
+
+2000-09-01 Niibe Yutaka <gniibe@m17n.org>, Kaz Kojima <kkojima@rr.iij4u.or.jp>, Alexandre Oliva <aoliva@redhat.com>
+
+ * elf32-sh.c (R_SH_GOT32, R_SH_PLT32, R_SH_COPY, R_SH_GLOB_DAT,
+ R_SH_JMP_SLOT, R_SH_RELATIVE, R_SH_GOTOFF, R_SH_GOTPC): New.
+ (sh_reloc_map): Add new relocs.
+ (sh_elf_check_relocs, sh_elf_link_hash_newfunc,
+ sh_elf_link_hash_table_create, sh_elf_adjust_dynamic_symbol,
+ sh_elf_size_dynamic_sections, sh_elf_finish_dynamic_symbol,
+ sh_elf_finishe_dynamic_sections, sh_elf_discard_copies): New
+ functions.
+ (ELF_DYNAMIC_INTERPRETER, PLT_ENTRY_SIZE): Define.
+ (elf_sh_plt0_entry_be, elf_sh_plt0_entry_le,
+ elf_sh_plt_entry_be, elf_sh_plt_entry_le,
+ elf_sh_pic_plt_entry_be, elf_sh_pic_plt_entry_le):
+ New array constants.
+ (elf_sh_plt0_entry, elf_sh_plt_entry, elf_sh_pic_plt_entry):
+ New variables.
+ (elf_sh_sizeof_plt, elf_sh_plt_plt0_offset,
+ elf_sh_plt0_linker_offset, elf_sh_plt0_gotid_offset,
+ elf_sh_plt_temp_offset, elf_sh_plt_symbol_offset,
+ elf_sh_plt_reloc_offset): Define.
+ (elf_sh_pcrel_relocs_copied, elf_sh_link_hash_entry,
+ elf_sh_link_hash_table): New structs.
+ (sh_elf_link_hash_traverse, sh_elf_hash_table): New macros.
+ (sh_elf_relocate_section, sh_elf_check_relocs): Handle new
+ relocation types.
+ (elf_backend_create_dynamic_sections,
+ bfd_elf32_bfd_link_hash_table_create,
+ elf_backend_adjust_dynamic_symbol,
+ elf_backend_size_dynamic_sections,
+ elf_backend_finish_dynamic_symbol,
+ elf_backend_finish_dynamic_sections, elf_backend_want_got_plt,
+ elf_backend_plt_readonly, elf_backend_want_plt_sym,
+ elf_backend_got_header_size, elf_backend_plt_header_size):
+ Define.
+ * reloc.c (BFD_RELOC_SH_COPY, BFD_RELOC_SH_GLOB_DAT,
+ BFD_RELOC_SH_JMP_SLOT, BFD_RELOC_SH_RELATIVE, BFD_RELOC_SH_GOTPC):
+ New relocs.
+ * bfd-in2.h, libbfd.h: Rebuilt.
+
+2000-09-01 Alan Modra <alan@linuxcare.com.au>
+
+ * elf32-i386.c (elf_i386_finish_dynamic_symbol): Revert 2000-08-27
+ change.
+
+2000-08-31 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * elf32-sh.c (sh_elf_merge_private_data): If ibfd's elf header flags
+ not initialized, set them to indicate the SH1 instruction set.
+
+2000-08-31 Alexandre Oliva <aoliva@redhat.com>
+
+ * acinclude.m4: Include libtool and gettext macros from the
+ top level.
+ * aclocal.m4, configure: Rebuilt.
+
+2000-08-29 Michael Snyder <msnyder@seadog.cygnus.com>
+
+ * elf.c: Eliminate references to __sparcv9 macro; replace with
+ autoconf variables HAVE_PSINFO32_T etc.
+ * configure.in: Auto-configure HAVE_PSINFO_32_T, HAVE_PRPSINFO32_T,
+ HAVE_PSTATUS32_T, HAVE_PRSTATUS32_T, HAVE_PRSTATUS32_T_PR_WHO.
+ * config.in: Ditto.
+ * acinclude.m4 (BFD_HAVE_SYS_PROCFS_TYPE) define _SYSCALL32 so it can
+ detect the above typedefs. (BFD_HAVE_SYS_PROCFS_TYPE_MEMBER): Ditto.
+ * aclocal.m4: Ditto.
+ * configure: Regenerate.
+
+2000-08-27 Alan Modra <alan@linuxcare.com.au>
+
+ * elf32-i386.c (elf_i386_check_relocs): Keep info on relocs copied
+ for any shared link, not just shared -Bsymbolic.
+ (elf_i386_size_dynamic_sections): Call elf_i386_discard_copies on
+ any shared link, and pass link info to it.
+ (elf_i386_size_dynamic_sections): Update comment.
+ (elf_i386_discard_copies): Modify to discard relocs for symbols
+ that have been forced local.
+ (elf_i386_finish_dynamic_symbol): Don't copy relocs for symbols
+ that have been forced local.
+
+2000-08-24 Denis Chertykov <denisc@overta.ru> & Nick Clifton <nickc@redhat.com>
+
+ * elflink.h (elf_link_add_object_symbols): Allow common
+ symbols to have an alignment of 1 if explicitly requested, and
+ not overridden by other definitions.
+
+2000-08-22 Doug Kwan <dkwan@transmeta.com>
+
+ * coff-w65.c (CREATE_LITTLE_COFF_TARGET): Fix typo.
+ * coffcode.h (coff_set_flags): Add detection of w65 architecture.
+
+2000-08-22 H.J. Lu <hjl@gnu.org>
+
+ * elf-bfd.h (elf_link_hash_table): Add runpath.
+
+ * bfd-in.h (bfd_elf_get_runpath_list): New prototype.
+ * bfd-in2.h: Rebuilt.
+
+ * elf.c (_bfd_elf_link_hash_table_init): Initialize the
+ "runpath" field to NULL.
+ (bfd_elf_get_runpath_list): New function.
+
+ * elflink.h (elf_link_add_object_symbols): Record DT_RPATH and
+ DT_RUNPATH entries.
+
+2000-08-22 Alexandre Oliva <aoliva@redhat.com>
+
+ * elf32-sh.c (sh_elf_relocate_section) [R_SH_IND12W,
+ R_SH_DIR8WPN, R_SH_DIR8WPZ, R_SH_DIR8WPL]: Handle them
+ explicitly. Improve validation of r_type.
+
+2000-08-21 H.J. Lu <hjl@gnu.org>
+
+ * elf32-i386.c (elf_i386_size_dynamic_sections): Zero out the
+ dynamic allocated content space. Add a comment to remind us that
+ one day this ought to be fixed.
+ * elf32-m68k.c (elf_m68k_size_dynamic_sections): Likewise.
+ * elf32-sparc.c (elf32_sparc_size_dynamic_sections): Likewise.
+ * elf64-hppa.c (elf64_hppa_size_dynamic_sections): Likewise.
+
+2000-08-21 Jason Eckhardt <jle@cygnus.com>
+
+ * elf32-i860.c (elf32_i860_relocate_pc16): Just write the immediate
+ field with the newly relocated value instead of adding it to the
+ existing immediate field.
+ (elf32_i860_relocate_splitn): Likewise.
+ (elf32_i860_relocate_highadj): Likewise.
+
+2000-08-16 Jason Eckhardt <jle@cygnus.com>
+
+ * elf32-i860.c (elf32_i860_relocate_pc16): Implemented function (it
+ was previously just a stub).
+
+2000-08-16 Alexandre Oliva <aoliva@redhat.com>
+
+ * elflink.c (_bfd_elf_create_got_section): Don't abort().
+ Formatting fixes.
+ (_bfd_elf_create_dynamic_sections): Likewise.
+
+2000-08-16 Andrew Macleod <amacleod@cygnus.com>
+
+ * elf64-sparc.c (sparc64_elf_relocate_section): Set relocation address
+ for undefined symbols to be the beginning of the section.
+
+ * elf64-sparc.c (sparc64_elf_adjust_dynamic_symbol): Don't allocate
+ four extra entries at the beginning of the .rela.plt section.
+ (sparc64_elf_finish_dynamic_symbol): Adjust the offset in the .rela.plt
+ section to account for the four reserved entries in the .plt section.
+
+2000-08-15 Geoffrey Keating <geoffk@cygnus.com>
+
+ * xcofflink.c (_bfd_ppc_xcoff_relocate_section): Add ori r0,r0,0
+ to the list of NOPs we recognize after a branch-and-link.
+ Use the ori NOP when one is needed.
+
+ * coff-rs6000.c (_bfd_xcoff_slurp_armap): Finish implementation
+ for large archives.
+
+2000-08-14 Jim Wilson <wilson@cygnus.com>
+
+ * elf64-ia64.c (elf64_ia64_merge_private_bfd_data): Handle
+ EF_IA_64_REDUCEDFP, EF_IA_64_CONS_GP, and EF_IA_64_NOFUNCDESC_CONS_GP.
+ (elf64_ia64_print_private_bfd_data): Likewise. Also handle
+ EF_IA_64_ABSOLUTE.
+
+2000-08-11 Alexandre Oliva <aoliva@redhat.com>
+
+ * elf32-sh.c (sh_elf_set_mach_from_flags): Make it static.
+
+2000-08-10 Jason Eckhardt <jle@cygnus.com>
+
+ * elf32-i860.c (elf32_i860_relocate_section): New function.
+ (i860_final_link_relocate): New function.
+ (elf32_i860_relocate_splitn): New function.
+ (elf32_i860_relocate_pc16): New function.
+ (elf32_i860_relocate_highadj): New function.
+ (elf32_i860_howto): Minor adjustments to some relocations.
+ (elf_info_to_howto_rel): Define.
+ (elf_backend_relocate_section): Define.
+
+2000-08-10 Nick Clifton <nickc@cygnus.com>
+
+ * elf32-arm.h: Fix formatting.
+
+2000-08-10 Bernd Schmidt <bernds@cygnus.co.uk>
+
+ * elf32-sh.c (sh_elf_reloc_loop): Make LAST_SYMBOL_SECTION static.
+
+2000-08-08 Jason Eckhardt <jle@cygnus.com>
+
+ * elf32-i860.c (elf32_i860_howto_table): Updated some fields.
+
+2000-08-07 Kazu Hirata <kazu@hxi.com>
+
+ * ieee.c (ieee_write_debug_part): Rewrite a comment.
+ * elf64-ia64.c: Fix a typo.
+
+2000-08-05 Jason Eckhardt <jle@cygnus.com>
+
+ * elf32-i860.c (elf32_i860_howto_table): New structure.
+ (lookup_howto): New function.
+ (elf32_i860_reloc_type_lookup): New function.
+ (elf32_i860_info_to_howto_rela): New function.
+ (elf_code_to_howto_index): New structure.
+ (elf_info_to_howto): Re-define as elf32_i860_info_to_howto_rela.
+ (bfd_elf32_bfd_reloc_type_lookup): Re-define as
+ elf32_i860_reloc_type_lookup.
+
+2000-08-04 Rodney Brown <RodneyBrown@pmsc.com>
+
+ * som.c (struct fixup_format): Constify `format'.
+ (som_hppa_howto_table): Use SOM_HOWTO macro.
+ (try_prev_fixup, hppa_som_reloc): Decorate unused parameter.
+ (som_bfd_reloc_type_lookup): Likewise.
+ (compare_subspaces): Remove unused `count1', `count2'.
+ (som_begin_writing): Remove unused `total_reloc_size'.
+ (som_bfd_derive_misc_symbol_info): Decorate unused parameter.
+ (som_print_symbol, som_bfd_is_local_label_name): Likewise.
+ (som_set_reloc_info): Constify `cp'. Remove unused `addend'.
+ (som_find_nearest_line): Decorate unused parameter(s).
+ (som_sizeof_headers, som_get_symbol_info, som_write_armap): Likewise.
+ (som_bfd_link_split_section): Likewise.
+
+2000-08-03 Nick Clifton <nickc@cygnus.com>
+
+ * section.c: Restore backed out code.
+ * elf.c: Restore backed out code.
+ (copy_private_bfd_data): Fix bug preventing stipped dynamic
+ binaries from working.
+ * bfd-in2.h: Regenerate.
+
+2000-08-03 H.J. Lu <hjl@gnu.org>
+
+ * section.c: Back out the change made by Nick Clifton
+ <nickc@cygnus.com> on 2000-07-31. It breaks stripping dynamic
+ binaries.
+ * bfd-in2.h: Likewise.
+ * elf.c: Likewise.
+
+2000-08-03 Alexandre Oliva <aoliva@redhat.com>
+
+ * elf32-sh.c (sh_elf_reloc_loop): Warning removal.
+
+2000-07-31 Jason Eckhardt <jle@cygnus.com>
+
+ * reloc.c (BFD_RELOC_860_*): New bfd relocs for i860.
+ * bfd-in2.h, libbfd.h: Regenerate.
+
+2000-07-31 Nick Clifton <nickc@cygnus.com>
+
+ * section.c (struct sec): Add new boolean field 'segment_mark'.
+ (STD_SECTION): Initialise new field to zero.
+
+ * bfd-in2.h: Regenerate.
+
+ * elf.c (copy_private_bfd_data): Reorganise section to segment
+ mapping to cope with moved sections requiring new segments,
+ and overlapping segments.
+ (SEGMENT_END): New macro: Return the end address of a segment.
+ (IS_CONTAINED_BY_VMA): New macro: Determine if a segment
+ contains a section by comparing their VMA addresses.
+ (IS_CONTAINED_BY_LMA): New macro: Determine if a segment
+ contains a section by comparing their LMA addresses.
+ (INCLUDE_SECTION_IN_SEGMENT): New macro: Determine if a
+ section should be included in a segment.
+ (SEGMENT_AFTER_SEGMENT): New macro: Determine if one segment
+ follows another in memory.
+ (SEGMENT_OVERLAPS_SEGMENT): New macro: Determine if two
+ segments overlap.
+
+2000-07-22 Jason Eckhardt <jle@cygnus.com>
+
+ * cpu-i860.c: Added comments.
+
+ * elf32-i860.c (TARGET_LITTLE_SYM): Defined to
+ bfd_elf32_i860_little_vec.
+ (TARGET_LITTLE_NAME): Defined to "elf32-i860-little".
+ (ELF_MAXPAGESIZE): Changed to 4096.
+
+ * targets.c (bfd_elf32_i860_little_vec): Declaration of
+ new target.
+ (bfd_target_vector): Added bfd_elf32_i860_little_vec.
+
+ * config.bfd (i860-stardent-sysv4*, i860-stardent-elf*): Added
+ config for little endian elf32 i860.
+ (targ_defvec): Define for the new config above
+ as "bfd_elf32_i860_little_vec".
+ (targ_selvecs): Define for the new config above
+ as "bfd_elf32_i860_vec bfd_elf32_i860_little_vec"
+
+ * configure.in (bfd_elf32_i860_little_vec): Added recognition
+ of new target vec.
+
+ * configure: Regenerated.
+
+2000-07-27 H.J. Lu <hjl@gnu.org>
+
+ * elflink.h (elf_merge_symbol): Take one more argument,
+ dt_needed, to indicate if the symbol comes from a DT_NEEDED
+ entry. Don't overide the existing weak definition if dt_needed
+ is true.
+ (elf_link_add_object_symbols): Pass dt_needed to
+ elf_merge_symbol ().
+
+2000-07-27 Nick Clifton <nickc@cygnus.com>
+
+ * elflink.h (elf_link_size_reloc_section): Zeroes the section's
+ allocated contents.
+
+2000-07-25 Geoffrey Keating <geoffk@cygnus.com>
+
+ * configure.host (*-*-aix*): AIX has 'long long' always.
+
+ * coff-rs6000.c (xcoff_write_one_armap_big): New procedure.
+ (xcoff_write_armap_big): Write both 32-bit and 64-bit armaps.
+ (xcoff_write_archive_contents_big): Don't update the offset
+ of the symbol table, xcoff_write_armap will do it.
+
+2000-07-23 Ulf Carlsson <ulfc@engr.sgi.com>
+
+ * elf32-mips.c (_bfd_mips_elf_check_relocs): Use abfd instead
+ of dynobj for SGI_COMPAT checks.
+
+2000-07-21 Michael Sokolov <msokolov@ivan.Harhan.ORG>
+
+ * coff-m68k.c (bfd_m68k_coff_create_embedded_relocs): New function.
+ * bfd-in.h (bfd_m68k_coff_create_embedded_relocs): Add declaration.
+ * bfd-in2.h: Regenerate.
+
+2000-07-21 Nick Clifton <nickc@cygnus.com>
+
+ * elf32-mips.c (_bfd_mips_elf_check_relocs): Detect out of
+ range symbol indices in relocs and issue an error message.
+
+2000-07-20 H.J. Lu <hjl@gnu.org>
+
+ * elflink.h (NAME(bfd_elf,size_dynamic_sections)): Don't check
+ info->new_dtags when setting DT_FLAGS_1. It will only be set
+ by the new linker options. It shouldn't break anything.
+
+2000-07-20 H.J. Lu <hjl@gnu.org>
+
+ * elflink.h (NAME(bfd_elf,size_dynamic_sections)): Set DT_FLAGS_1
+ only if info->new_dtags is true.
+
+2000-07-20 H.J. Lu <hjl@gnu.org>
+
+ * elflink.h (NAME(bfd_elf,size_dynamic_sections)): Set
+ DT_RUNPATH and DT_FLAGS only if info->new_dtags is true.
+
+2000-07-20 Hans-Peter Nilsson <hp@axis.com>
+
+ * Makefile.am (ALL_MACHINES): Add cpu-cris.lo.
+ (ALL_MACHINES_CFILES): Add cpu-cris.c.
+ (BFD32_BACKENDS): Add aout-cris.lo and elf32-cris.lo.
+ (BFD32_BACKENDS_CFILES): Add aout-cris.c and elf32-cris.c.
+ (cpu-cris.lo, aout-cris.lo, elf32-cris.lo): New rules.
+ * Makefile.in: Rebuild.
+ * aclocal.m4: Rebuild.
+ * aoutx.h (NAME(aout,machine_type)): Add case for bfd_arch_cris.
+ * archures.c (enum bfd_architecture): Add bfd_arch_cris.
+ (bfd_cris_arch): Declare.
+ (bfd_archures_list): Add bfd_cris_arch.
+ * bfd-in2.h: Rebuild.
+ * config.bfd: (cris-*-*): New target.
+ * configure.in (bfd_elf32_cris_vec, cris_aout_vec): New vectors.
+ * configure: Rebuild.
+ * elf.c (prep_headers): Add bfd_arch_cris.
+ * libbfd.h: Rebuild.
+ * libaout.h (enum machine_type): Add M_CRIS.
+ * reloc.c: Add CRIS relocations.
+ * targets.c (bfd_elf32_cris_vec, cris_aout_vec): Declare.
+ (bfd_target_vect): Add bfd_elf32_cris_vec and cris_aout_vec.
+ * cpu-cris.c, aout-cris.c, elf32-cris.c: New files.
+ * po/POTFILES.in, po/bfd.pot: Regenerate.
+
+2000-07-19 H.J. Lu <hjl@gnu.org>
+
+ * elf32-arm.h (elf32_arm_size_dynamic_sections): Also set
+ DF_TEXTREL if DT_TEXTREL is set.
+ * elf32-i370.c (i370_elf_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 (_bfd_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.
+ * elf64-hppa.c (elf64_hppa_size_dynamic_sections): Likewise.
+ * elf64-ia64.c (elf64_ia64_size_dynamic_sections): Likewise.
+ * elf64-sparc.c (sparc64_elf_size_dynamic_sections): Likewise.
+
+ * elflink.h (NAME(bfd_elf,size_dynamic_sections)): Also
+ set DF_SYMBOLIC for symbolic link. Also set DT_RUNPATH if
+ DT_RPATH is set.
+ Set the DT_FLAGS and DT_FLAGS_1 entries if necessary.
+
+2000-07-19 H.J. Lu <hjl@gnu.org>
+
+ * bfd-in.h (bfd_elf_set_dt_needed_soname): New.
+ * bfd-in2.h: Rebuild.
+
+ * elf-bfd.h (elf_obj_tdata): Add dt_soname.
+ (elf_dt_soname): New.
+
+ * elf.c (bfd_elf_set_dt_needed_soname): New.
+
+ * elflink.h (elf_link_add_object_symbols): Add the DT_NEEDED
+ entry if the shared object loaded by DT_NEEDED is used to
+ resolve the reference in a regular object.
+
+2000-07-19 H.J. Lu <hjl@gnu.org>
+
+ * elf.c (_bfd_elf_print_private_bfd_data): Handle DT_CONFIG,
+ DT_DEPAUDIT and DT_AUDIT as strings.
+
+2000-07-19 Nick Clifton <nickc@cygnus.com>
+
+ * format.c: Fix formatting.
+
+2000-07-19 H.J. Lu <hjl@gnu.org>
+
+ * elf.c (_bfd_elf_print_private_bfd_data): Fix DT_CHECKSUM.
+
+2000-07-19 H.J. Lu <hjl@gnu.org>
+
+ * elf.c (_bfd_elf_print_private_bfd_data): Handle DT_BIND_NOW,
+ DT_INIT_ARRAY, DT_FINI_ARRAY, DT_INIT_ARRAYSZ, DT_FINI_ARRAYSZ,
+ DT_RUNPATH, DT_FLAGS, DT_PREINIT_ARRAY, DT_PREINIT_ARRAYSZ,
+ DT_PLTPADSZ, DT_MOVEENT, DT_MOVESZ, DT_FEATURE, DT_POSFLAG_1,
+ DT_SYMINSZ, DT_SYMINENT, DT_CONFIG, DT_DEPAUDIT, DT_AUDIT,
+ DT_PLTPAD, DT_MOVETAB, DT_SYMINFO, DT_RELACOUNT, DT_RELCOUNT,
+ DT_FLAGS_1, DT_USED and DT_CHECKSUM.
+
+2000-07-18 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * elf.c (bfd_elf_get_sign_extend_vma, bfd_elf_get_arch_size): Move
+ renamed functions from here...
+ (assign_section_numbers): Use renamed functions.
+ (prep_headers): Use renamed functions.
+
+ * bfd.c (bfd_get_sign_extend_vma, bfd_get_arch_size): ...To here.
+ * bfd-in.h (bfd_get_sign_extend_vma, bfd_get_arch_size): Update.
+ * bfd-in2.h: Regenerate.
+
+2000-07-18 Ulf Carlsson <ulfc@engr.sgi.com>
+
+ * elf32-mips.c (_bfd_mips_elf_finish_dynamic_symbol): Add
+ parenthesis in if statement.
+
+2000-07-17 Koundinya K <kk@ddeorg.soft.net>
+
+ Enable the support for Traditional MIPS.
+ * elf32-mips.c (IRIX_COMPAT): Recognize bfd_elf32_tradbigmips_vecand
+ return ict_none appropriately for traditional mips targets.
+ (STUB_LW): Change 0x8f998000 to 0x8f998010 for traditional mips.
+ (STUB_MOVE): Conditionalize for traditonal mips.
+ (STUB_LI16): Likewise.
+ (_bfd_mips_elf_modify_segment_map): Conditionalize to avoid making
+ room for RTPROC header.
+ (_bfd_mips_elf_modify_segment_map): For a normal mips executable set
+ the permission for the PT_DYNAMIC as read, write and execute.
+ (mips_elf_calculate_relocation): Check for the symbol _DYNAMIC_LINKING
+ for traditonal mips.
+ (_bfd_mips_elf_create_dynamic_sections): Add the symbol
+ _DYNAMIC_LINKING for traditonal mips.
+ (_bfd_mips_elf_create_dynamic_sections): Add the symbol __RLD_MAP
+ in case of traditonal mips.
+ (_bfd_mips_elf_adjust_dynamic_symbol): Create a stub only if a PLT
+ entry is required. For a function if PLT is not required then set the
+ corresponding hash table entry to 0.
+ (_bfd_mips_elf_size_dynamic_sections): Add DT_DEBUG entry for
+ traditonal mips.
+ (_bfd_mips_elf_finish_dynamic_symbol): for a undefined symbol in a
+ shared object set the value to 0.
+ (_bfd_mips_elf_finish_dynamic_symbol): Check for the symbol
+ _DYNAMIC_LINKING for traditonal mips.
+ (_bfd_mips_elf_finish_dynamic_symbol): Check for the symbol __RLD_MAP
+ for traditonal mips.
+
+2000-07-15 H.J. Lu <hjl@gnu.org>
+
+ * aoutx.h (translate_to_native_sym_flags): Handle BSF_LOCAL.
+
+2000-07-12 Charles Wilson <cwilson@ece.gatech.edu>
+
+ * libbfd.c (bfd_seek): fix 'seek beyond EOF' error when writing
+ out a structure that is BFD_IN_MEMORY.
+
+2000-07-11 Alan Modra <alan@linuxcare.com.au>
+
+ * elf64-hppa.c (get_dyn_name): Pass in section pointer instead of
+ bfd pointer. Print section id instead of bfd pointer for local
+ syms. Prefix addend with `+' for global syms as well as local.
+ Correct calculation of name component lengths.
+ (elf64_hppa_check_relocs): Update call to get_dyn_name.
+
+ From David Huggins-Daines <dhd@linuxcare.com>
+ * elf-hppa.h (elf_hppa_relocate_section): Update calls here too.
+ * elf64-hppa.c (elf64_hppa_check_relocs): Fix some warnings.
+ (elf64_hppa_modify_segment_map): Likewise.
+
+2000-07-11 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * elf.c (bfd_elf_get_sign_extend_vma): Return tendency of VMA
+ addresses to be "naturally" sign extended. Return -1 if unknown.
+ * bfd-in.h (bfd_elf_get_sign_extend_vma): Add declaration.
+ * bfd-in2.h: Regenerate.
+
+2000-07-11 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * ecoffswap.h (ecoff_get_off, ecoff_put_off): Add ECOFF_SIGNED_32
+ and ECOF_SIGNED_64 to list ways to extract an offset.
+ (ecoff_swap_fdr_in, ecoff_swap_fdr_out, ecoff_swap_pdr_in,
+ ecoff_swap_pdr_out, ecoff_swap_ext_in, ecoff_swap_ext_out):
+ Update.
+ * elf64-mips.c (ECOFF_SIGNED_64): Define instead of ECOFF_64.
+ * elf32-mips.c (ECOFF_SIGNED_32): Define instead of ECOFF_32.
+
+2000-07-11 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * elfcode.h (elf_object_p): Use bfd_set_start_address and not
+ bfd_get_start_address.
+ (elf_swap_ehdr_in): Sign extend e_entry when applicable.
+ (elf_swap_ehdr_out): Ditto.
+
+2000-07-10 Alexander Aganichev <AAganichev@hypercom.com>
+
+ * archures.c (bfd_default_scan): Add set of bfd_mach_ cases for
+ compatibility with older binutils.
+
+2000-07-10 Alan Modra <alan@linuxcare.com.au>
+
+ * section.c (bfd_make_section_anyway): Start section_id at 0x10.
+ (STD_SECTION): Avoid negative ids, instead use 0 to 3.
+
+ From Ryan Bradetich <rbradetich@uswest.net>
+ * dwarf1.c (parse_die): Cure signed/unsigned char warnings.
+ (parse_line_table): Ditto.
+ (_bfd_dwarf1_find_nearest_line): Ditto.
+ * syms.c (cmpindexentry): Remove extra `*' from params.
+
+2000-07-09 Koundinya K <kk@ddeorg.soft.net>
+
+ * elf32-mips.c (sort_dynamic_relocs): New Function.
+ (_bfd_mips_elf_finish_dynamic_sections): Call sort_dynamic_relocs
+ via qsort to sort the dynamic relocations in increasing r_symndx
+ value.
+
+2000-07-09 Alan Modra <alan@linuxcare.com.au>
+
+ * elf64-hppa.c (elf64_hppa_dyn_hash_table_init): Add
+ ATTRIBUTE_UNUSED to unused args.
+ (get_opd): Likewise.
+ (get_plt): Likewise.
+ (get_dlt): Likewise.
+ (get_stub): Likewise.
+ (elf64_hppa_adjust_dynamic_symbol): Likewise.
+ (elf64_hppa_link_output_symbol_hook): Likewise.
+ (elf64_hppa_check_relocs): Delete unused var.
+ (elf64_hppa_size_dynamic_sections): Likewise.
+ (elf64_hppa_finalize_opd): Likewise.
+ (elf64_hppa_finalize_dynreloc): Likewise.
+ (elf64_hppa_modify_segment_map): Likewise.
+ (elf64_hppa_finish_dynamic_sections): Likewise.
+
+ * elf-hppa.h (elf_hppa_final_write_processing): Add
+ ATTRIBUTE_UNUSED to unused args.
+ (elf_hppa_final_link_relocate): Likewise.
+ (elf_hppa_record_segment_addrs): Add paretheses.
+ (elf_hppa_relocate_section): Constify dyn_name.
+
+ From David Huggins-Daines <dhd@linuxcare.com>
+ * config.bfd: Add hppa*64*-*-linux-gnu 64-bit target, and
+ rearrange case statement so that it gets preferred to 32-bit ones.
+
+ * elf32-hppa.c (elf32_hppa_bfd_final_link_relocate): Use
+ asection->id instead of address of asection structure.
+ (elf32_hppa_size_stubs): Likewise.
+
+ * elf32-hppa.c (elf32_hppa_size_stubs): Use just one stub section
+ for .init* and .fini*.
+
+ * elf32-hppa.c (elf32_hppa_bfd_final_link_relocate): Mask pointers
+ and addends used in stub names to 32 bits.
+ (elf32_hppa_size_stubs): Likewise.
+
+ * elf-hppa.h (elf_hppa_final_link_relocate): Don't sum addend
+ twice for R_PARISC_GPREL64. Use bfd_put_32 for R_PARISC_PCREL32,
+ not bfd_put_64. Fix minor comment typo and formatting.
+
+ Changes to create multiple linker stubs, positioned immediately
+ before the section where they are required.
+ * elf32-hppa.c: Don't include hppa_stubs.h.
+ (elf32_hppa_stub_hash_entry): Add a pointer to the stub section.
+ (elf32_hppa_stub_hash_table): Delete.
+ (elf32_hppa_link_hash_entry): Delete.
+ (elf32_hppa_link_hash_table): Use plain bfd_hash_table for
+ stub_hash_table, and store the struct here rather than a pointer.
+ Delete output_symbol_count. Add offset array. Change
+ global_value to a bfd_vma.
+ (elf32_hppa_stub_hash_lookup): Use table instead of table->root.
+ (elf32_hppa_stub_hash_traverse): Delete.
+ (elf32_hppa_name_of_stub): Delete.
+ (elf32_hppa_link_hash_lookup): Delete.
+ (elf32_hppa_link_hash_traverse): Delete.
+ (elf32_hppa_stub_hash_table_init): Delete.
+ (elf32_hppa_size_of_stub): Pass input section and offset rather
+ than location and calculate location here. Don't pass name as all
+ stubs are now the same size.
+ (elf32_hppa_stub_hash_newfunc): Init new fields.
+ (elf32_hppa_link_hash_table_create): Likewise, and stub_hash_table
+ too.
+ (elf32_hppa_bfd_final_link_relocate): Cast enums to int before
+ comparing against ints. Rewrite stub handling code.
+ (elf32_hppa_relocate_section): Make r_type and r_symndx unsigned.
+ Case enums to int before comparing against ints. Remove
+ bfd_reloc_dangerous case.
+ (elf32_hppa_build_one_stub): Rewrite.
+ (elf32_hppa_size_one_stub): New function.
+ (elf32_hppa_build_stubs): Rewrite.
+ (elf32_hppa_size_stubs): Pass in linker call-back functions.
+ Rewrite stub-handling specific code.
+
+ * elf32-hppa.h (elf32_hppa_size_stubs): Update prototype.
+
+ * elf64-hppa.c (elf64_hppa_dyn_hash_entry): Fix a comment typo.
+
+ * hppa_stubs.h: Delete.
+ * Makefile.am (SOURCE_HFILES): Remove hppa_stubs.h
+ (elf32-hppa.lo): Remove hppa_stubs.h from dependencies.
+ * Makefile.in: Regenerate.
+
+ * elf-hppa.h (_bfd_elf_hppa_gen_reloc_type): Handle e_nlsel and
+ e_nlrsel.
+
+ * libhppa.h (hppa_field_adjust): Correct e_nsel case.
+
+ * elf32-hppa.c (elf32_hppa_relocate_section): Mention the offset
+ and section name for bfd_reloc_notsupported error message.
+ (elf32_hppa_bfd_final_link_relocate): Print reasons for returning
+ bfd_reloc_notsupported.
+ (elf32_hppa_relocate_section): Add ATTRIBUTE_UNUSED to output_bfd.
+
+ * elf32-hppa.c (elf32_hppa_bfd_final_link_relocate): Handle
+ undefined weak symbols for all relocs.
+ (elf32_hppa_size_of_stub): Adjust calculation by 8 since branch
+ offsets are relative to one past the delay slot.
+ (elf32_hppa_size_stubs): Account for reloc addend when calculating
+ branch destination. Put addend into stub name too.
+ (elf32_hppa_bfd_final_link_relocate): Account for reloc addend and
+ adjust by 8 when deciding whether a linker stub is needed. Put
+ addend into stub name as for above.
+
+ * elf32-hppa.c (hppa_elf_relocate_insn): Change signed/unsigned on
+ various args and vars.
+ (elf32_hppa_bfd_final_link_relocate): Here too.
+ (elf32_hppa_size_stubs): Rename index -> indx. Use e_indx for
+ inner block var to avoid shadowing.
+
+ * elf32-hppa.h (_bfd_elf32_hppa_gen_reloc_type): Make `field' arg
+ unsigned.
+ * elf64-hppa.h (_bfd_elf64_hppa_gen_reloc_type): Ditto.
+ * elf-hppa.h (_bfd_elf_hppa_gen_reloc_type): Ditto.
+ (elf_hppa_fake_sections): Rename local var to avoid shadowing.
+
+ * libhppa.h: Change practically all unsigned ints to plain ints.
+ Remove tests on gcc version. Instead use ATTRIBUTE_UNUSED for
+ prototypes.
+
+ From Ryan Bradetich <rbradetich@uswest.net>
+ * libhppa.h (hppa_opcode_type): New enum to replace #define's.
+ * elf32-hppa.c (elf32_hppa_bfd_final_link_relocate): Modify to
+ suit above.
+ From David Huggins-Daines <dhd@linuxcare.com>
+ * elf-hppa.h (elf_hppa_relocate_insn): Update the opcode constants
+ to the new OP_* ones.
+
+ * elf32-hppa.c (elf32_hppa_size_stubs): Consolidate freeing on
+ error exit. Bail out earlier on plabel relocs that we aren't
+ interested in. Don't tell elf32_hppa_stub_hash_lookup to copy
+ string, and then don't free our copy.
+ (elf32_hppa_build_one_stub): Make insn unsigned int.
+
+ * libhppa.h (bfd_hppa_insn2fmt): 22 bit branches are only
+ available with BL, not BE and BLE.
+
+ * elf32-hppa.c (hppa_elf_relocate_insn): Add some more example
+ code for elf arg relocs.
+ (elf32_hppa_bfd_final_link_relocate): Replace boolean is_local
+ argument with elf_link_hash_entry h. Handle undefined weak
+ symbols. Move $global$ lookup from here...
+ (elf32_hppa_relocate_section): ...to here. Return correct error
+ message for non-handled relocs.
+ (elf32_hppa_size_of_stub): Correctly test branch range. Previous
+ wrong test was -0x3ffff to +0x40000.
+
+ * elf-hppa.h (elf_hppa_final_link_relocate): R_PARISC_DIR17R,
+ R_PARISC_DIR17F, and R_PARISC_DIR21L are for absolute branches;
+ Handle them as such.
+ (elf_hppa_relocate_insn): Fix a typo.
+
+ * libhppa.h (GET_FIELD, GET_BIT, MASK, CATENATE, ELEVEN): Delete.
+ (assemble_3, assemble_6, assemble_12, assemble_16, assemble_16a,
+ assemble_17, assemble_21): Delete.
+ Supply defines for all 64 possible opcodes.
+ (bfd_hppa_insn2fmt): Add bfd argument, and use to select wide mode
+ formats. Handle COMICLR.
+ (hppa_rebuild_insn): Delete bfd argument. Handle formats 10, -11,
+ -10, -16, 16, 22.
+
+ * elf32-hppa.c (hppa_elf_relocate_insn): Complete rewrite.
+ (elf32_hppa_bfd_final_link_relocate): Major rewrite.
+ (elf32_hppa_build_one_stub): Modify hppa_elf_relocate_insn calls
+ to suit.
+ (elf32_hppa_size_stubs): Don't free stub_name twice. Read in all
+ the local syms - did this code get deleted accidentally? Ignore
+ undefined and undefweak syms.
+
+ * elf-hppa.h (elf_hppa_final_link): Move hppa_info to outermost
+ block. Use it instead of elf64_hppa_hash_table (info).
+ (elf_hppa_final_link_relocate): Use hppa_info instead of
+ elf64_hppa_hash_table (info).
+
+ * libhppa.h (re_assemble_3, re_assemble_12, re_assemble_16,
+ re_assemble_17, re_assemble_21, re_assemble_22): Don't mask insn.
+ (hppa_rebuild_insn): Mask immediate bits here instead.
+ * elf-hppa.h (elf_hppa_relocate_insn): Mask here too.
+
+2000-07-08 Alan Modra <alan@linuxcare.com.au>
+
+ * section.c (struct sec): Add id field. Tidy comment formatting.
+ (bfd_make_section_anyway): Set id.
+ (STD_SECTION): Init id too.
+ Change CONST to const throughout.
+ * archures.c (bfd_arch_info): Tidy comment.
+ (bfd_arch_list): Change a CONST to const.
+ * libbfd-in.h: Tidy comments and replace CONST with const.
+ * elf-bfd.h: Likewise.
+ * libbfd.h: Regenerate.
+ * bfd-in2.h: Regenerate.
+ * libcoff.h: Regenerate.
+
+2000-07-07 DJ Delorie <dj@redhat.com>
+
+ * archive.c (_bfd_write_archive_contents): Add an informative
+ comment.
+
+2000-07-06 Kazu Hirata <kazu@hxi.com>
+
+ * srec.c: Fix formatting.
+
+2000-06-05 DJ Delorie <dj@redhat.com>
+
+ * MAINTAINERS: new
+
+2000-07-04 Alexandre Oliva <aoliva@redhat.com>
+
+ * coff-arm.c (coff_arm_relocate_section): Do not ignore the symbol
+ value of PC-relative offsets.
+
+2000-07-03 Jim Wilson <wilson@cygnus.com>
+
+ * elf64-alpha.c (alpha_elf_size_info): New.
+ (elf_backend_size_info): Define to alpha_elf_size_info.
+ * elfcode.h (elf_size_info): Change hash bucket size to 4.
+
+2000-07-03 Ulf Carlsson <ulfc@engr.sgi.com>
+
+ * elf32-mips.c: Include elf32-target.h again for the traditional
+ MIPS targets.
+
+2000-07-03 Marek Michalkiewicz <marekm@linux.org.pl>
+
+ * elf32-avr.c (bfd_elf32_bfd_reloc_type_lookup):
+ Add ATTRIBUTE_UNUSED to unused arguments to avoid warnings.
+ (avr_info_to_howto_rela): Likewise.
+ (elf32_avr_gc_mark_hook): Likewise.
+ (elf32_avr_gc_sweep_hook): Likewise.
+ (elf32_avr_relocate_section): Likewise.
+
+2000-07-03 Mark Elbrecht <snowball3@bigfoot.com>
+
+ * cofflink.c (_bfd_coff_write_global_sym): Turn a weak symbol into
+ an external symbol for a non-shared, non-relocatable link.
+
+2000-07-03 Nick Clifton <nickc@redhat.com>
+
+ * cofflink.c (IS_EXTERNAL): New macro: Return true if the symbol
+ is an external symbol.
+ (IS_WEAK_EXTERNAL): New macro: Return true if the symbol is a weak
+ external symbol.
+
+2000-07-03 Kazu Hirata <kazu@hxi.com>
+
+ * reloc16.c: Fix formatting.
+
+2000-07-01 Koundinya K <kk@ddeorg.soft.net>
+
+ * config.bfd: Change targ_defvec and targ_selvecs for mips*-*-sysv4*
+ to add a new target for traditional mips i.e
+ bfd_elf32_tradbigmips_vec and bfd_elf32_tradlittlemips_vec.
+ * configure.in: Likewise.
+ * configure: Rebuild.
+ * targets.c (bfd_elf32_tradbigmips_vec): Declare and put in
+ bfd_target_vector.
+ (bfd_elf32_tradlittlemips_vec): Likewise.
+ * elfxx-target.h: Add macro INCLUDED_TARGET_FILE which is more a test
+ to see that elfNN_bed does not get redefined even if the target file
+ is included twice for a chip. See elf32-mips.c.
+
+2000-07-01 Alan Modra <alan@linuxcare.com.au>
+
+ * Makefile.am (DEP): Fix 2000-06-22. grep after running dep.sed
+ (CLEANFILES): Add DEPA.
+ * Makefile.in: Regenerate.
+
+2000-06-30 DJ Delorie <dj@cygnus.com>
+
+ * peicode.h (coff_swap_filehdr_in): can't use e_magic because we
+ can't assume the PE header is at 0x80.
+
+2000-06-29 Mark Elbrecht <snowball3@bigfoot.com>
+
+ * syms.c (_bfd_stab_section_find_nearest_line): Use IS_ABSOLUTE_PATH.
+
+2000-06-28 Mark Elbrecht <snowball3@bigfoot.com>
+
+ * go32stub.h: Update stub.
+
+2000-06-26 Marek Michalkiewicz <marekm@linux.org.pl>
+
+ * archures.c (bfd_mach_avr5): Define.
+ * bfd-in2.h (bfd_mach_avr5): Define.
+ * cpu-avr.c (arch_info_struct): Rename bfd_mach_avr4 to
+ bfd_mach_avr5, add bfd_mach_avr4. Update comments.
+ (compatible): Update comment. Add missing test.
+ * elf32-avr.c (avr_final_link_relocate): Support 8K wrap
+ for avr2 and avr4. Simplify 8K wrap code.
+ (bfd_elf_avr_final_write_processing): Recognize bfd_mach_avr5.
+ (elf32_avr_object_p): Recognize E_AVR_MACH_AVR5.
+
+2000-06-26 Kazu Hirata <kazu@hxi.com>
+
+ * coff-h8300.c: Fix formatting.
+ * cpu-h8300.c: Likewise.
+
+2000-06-24 Alexandre Oliva <aoliva@redhat.com>
+
+ * elf32-arm.h (elf32_arm_final_link_relocate): Print `(local)'
+ for local symbols whose names are unknown.
+
+2000-06-22 Alan Modra <alan@linuxcare.com.au>
+
+ * Makefile.am (DEP): grep for leading `/' in DEP1, and fail if we
+ find one.
+ * Makefile.in: Regenerate.
+ * doc/Makefile.in: Regenerate.
+
+2000-06-20 H.J. Lu <hjl@gnu.org>
+
+ * Makefile.am: Rebuild dependency.
+ * Makefile.in: Rebuild.
+
+2000-06-20 Maciej W. Rozycki <macro@ds2.pg.gda.pl>
+
+ * elf32-mips.c (_bfd_mips_elf_copy_indirect_symbol): New function.
+ (elf_backend_copy_indirect_symbol): Map to the new function.
+
+2000-06-20 Alan Modra <alan@linuxcare.com.au>
+
+ * archive.c (normalize): Correct pointer comparison when checking
+ for backslashes.
+ (bfd_bsd_truncate_arname): Likewise.
+ (bfd_gnu_truncate_arname): Likewise.
+
+2000-06-20 Ulf Carlsson <ulfc@engr.sgi.com>
+
+ * elf-bfd.h (struct elf_obj_tdata): Define per BFD Irix 5 virtual
+ sections elf_{text,data}_{section,symbol}.
+ * elf32-mips.c: mips_elf_{text,data}_{section,symbol}{,_ptr}: Remove.
+ (_bfd_mips_elf_hide_symbol): New function.
+ (elf_backend_hide_symbol): Map to the new function.
+ (_bfd_mips_elf_add_symbol_hook): Change to use new per BFD
+ definitions of mips_elf_{text,data}_{section,symbol}.
+ (mips_elf_local_relocation_p): Try to find the direct symbol
+ based on new check_forced argument.
+ (mips_elf_calculate_relocation): Use new version of
+ mips_elf_local_relocation_p.
+ (mips_elf_relocate_section): Likewise.
+ (_bfd_mips_elf_relocate_section): Likewise.
+ (mips_elf_sort_hash_table): Only assert that have enough GOT
+ space.
+ (mips_elf_got16_entry): Match all 32 bits to the existing GOT
+ entry if the relocation based on the new external argument.
+ (mips_elf_create_dynamic_relocation): Assert that we have a
+ section contents allocated where we can swap out the dynamic
+ relocations.
+ (mips_elf_calculate_relocation): Find the real hash-table entry
+ correctly by using h->root.root.type. Only create a dynamic
+ relocation entry if the symbol is defined in a shared library.
+ Create an external GOT entry for the GOT16 relocation if the
+ symbol was forced local.
+ (_bfd_mips_elf_finish_dynamic_symbol): Don't assert there is a
+ dynamic index if the symbol was forced local.
+
+2000-06-20 Maciej W. Rozycki <macro@ds2.pg.gda.pl>
+
+ * elf32-mips.c: Fix typos in comments.
+
+2000-06-19 Mark Kettenis <kettenis@gnu.org>
+
+ * rs6000-core.c: Wrap definition of `union VmInfo' within #ifdef
+ CORE_VERSION_1.
+
+2000-06-18 Stephane Carrez <stcarrez@worldnet.fr>
+
+ * Makefile.in, bfd-in2.h, libbfd.h, configure: Rebuild.
+ * Makefile.am (ALL_MACHINES, ALL_MACHINES_CFILES, BFD32_BACKENDS,
+ BFD32_BACKENDS_CFILES): Add 68hc12, 68hc11 files.
+ * configure.in (bfd_elf32_m68hc12_vec): Recognize.
+ (bfd_elf32_m68hc11_vec): Likewise.
+ * config.bfd (targ_cpu): Recognize 68hc12 and 68hc11.
+ Supports 68hc11 & 68hc12 at the same time.
+ * targets.c (bfd_elf32_m68hc12_vec): Declare and put in
+ bfd_target_vector.
+ (bfd_elf32_m68hc11_vec): Likewise.
+ * elf.c (prep_headers): Recognize bfd_arch_m68hc12 and 68hc11.
+ * archures.c (bfd_m68hc12_arch): Define and register in global list
+ (bfd_m68hc11_arch): Likewise.
+ * reloc.c (BFD_RELOC_M68HC11_HI8, BFD_RELOC_M68HC11_LO8,
+ BFD_RELOC_M68HC11_3B): Define.
+ * cpu-m68hc12.c, elf32-m68hc12.c: New files for 68hc12 support.
+ * cpu-m68hc11.c, elf32-m68hc11.c: New files for 68hc11 support.
+
+2000-06-18 Ulf Carlsson <ulfc@engr.sgi.com>
+
+ * elf_bfd.h (struct elf_backend_data): Add info argument to
+ elf_backend_hide_symbol.
+ (_bfd_elf_link_hash_hide_symbol): Likewise.
+ * elf.c (_bfd_elf_link_hash_hide_symbol): Likewise.
+ * elf64-ia64.c (elf64_ia64_hash_hide_symbol): Likewise.
+ * elflink.h (elf_link_add_object_symbols): Likewise.
+ (elf_link_assign_sym_version): Likewise.
+
+2000-06-18 H.J. Lu <hjl@gnu.org>
+
+ * coff-i386.c (coff_i386_reloc): Don't return in case of
+ output_bfd == (bfd *) NULL if COFF_WITH_PE is defined.
+ Compensate PE relocations when linking with non-PE object
+ files to generate a non-PE executable.
+
+2000-06-17 Ulf Carlsson <ulfc@engr.sgi.com>
+
+ * elf32-mips.c (mips_elf_calculate_relocation): Explicitly write
+ GOT entries if we're doing a static link or -Bsymbolic link.
+
+2000-06-15 Ulf Carlsson <ulfc@engr.sgi.com>
+
+ * elflink.h (elf_link_adjust_relocs): Check for and call backend
+ specifific swap_reloc_{in,out} and swap_reloca_{in,out} if
+ available.
+ (elf_link_output_relocs): Likewise.
+ (elf_reloc_link_order): Likewise.
+
+2000-06-16 Nicholas Duffek <nsd@redhat.com>
+
+ * archures.c (enum bfd_architecture): #define constants for
+ PowerPc and RS6000 machine numbers.
+ * bfd-in2.h: Regenerate.
+ * coffcode.h (coff_set_arch_mach_hook): #ifdef XCOFF64, set arch
+ to bfd_arch_powerpc instead of bfd_arch_rs6000. Refer to PowerPc
+ and RS6000 machine numbers using #defined constants from
+ archures.c.
+ * cpu-powerpc.c (arch_info_struct): Refer to PowerPc and RS6000
+ machine numbers using #defined constants from archures.c. Add
+ entries for EC603e, 630, A35, RS64II, RS64III, 7400. Specify
+ 64-bit words in 620 entry.
+ * cpu-rs6000.c (arch_info_struct): Create with entries for RS1,
+ RSC, and RS2.
+ (bfd_rs6000_arch): Change default machine to 0 (bfd_mach_rs6k).
+
+2000-06-16 Nicholas Duffek <nsd@cygnus.com>
+
+ * coffcode.h (coff_mkobject_hook): Set xcoff_tdata.xcoff64.
+ * libcoff-in.h (struct xcoff_tdata): Define xcoff64 field.
+ * libcoff.h (struct xcoff_tdata): Define xcoff64 field.
+
+2000-06-16 Nicholas Duffek <nsd@redhat.com>
+
+ * bfd-in.h (bfd_family_coff): Define.
+ * bfd-in2.h: Regenerate.
+ * coffgen.c (coff_count_linenumbers, coff_symbol_from,
+ coff_find_nearest_line): Check COFFness using bfd_family_coff()
+ instead of bfd_target_coff_flavour.
+ * cofflink.c (_bfd_coff_final_link): Likewise.
+ * cpu-ns32k.c (do_ns32k_reloc): Don't strcmp() target name to
+ exclude XCOFF files.
+ * reloc.c (bfd_perform_relocation, bfd_install_relocation):
+ Likewise.
+ * targets.c (enum bfd_flavour): Add bfd_target_xcoff_flavour.
+ * xcoff-target.h (TARGET_SYM): Use bfd_target_xcoff_flavour.
+ * xcofflink.c (XCOFF_XVECP): Delete.
+ (bfd_xcoff_link_record_set, bfd_xcoff_import_symbol,
+ bfd_xcoff_export_symbol, bfd_xcoff_link_count_reloc,
+ bfd_xcoff_record_link_assignment,
+ bfd_xcoff_size_dynamic_sections): Replace XCOFF_XVECP() with
+ check for bfd_target_xcoff_flavour.
+
+2000-06-16 Nicholas Duffek <nsd@redhat.com>
+
+ * rs6000-core.c: Support 64-bit core files, support pre-4.3 core
+ files on AIX 4.3.
+ (read_hdr): New function.
+ (rs6000coff_core_p): Store mstsave or __context64 struct instead
+ of trying to extract individual registers. Set abfd->arch_info
+ to match the architecture that created the core file.
+ (rs6000coff_get_section_contents): Delete.
+ * xcoff-target.h (rs6000coff_get_section_contents): Delete.
+
+2000-06-14 H.J. Lu <hjl@gnu.org>
+
+ * vms-misc.c (_bfd_vms_next_record): Return -1 if PRIV(vms_rec)
+ is NULL.
+
+2000-06-13 H.J. Lu <hjl@gnu.org>
+
+ * configure: Regenerate.
+
+2000-06-13 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * peicode.h (pe_ILF_object_p): Use TARGET_LITTLE_SYM instead of
+ armpei_little_vec.
+
+2000-06-08 David O'Brien <obrien@FreeBSD.org>
+
+ * configure.in (VERSION): Update to show this is the CVS mainline.
+
+2000-06-07 Alan Modra <alan@linuxcare.com.au>
+
+ * elf32-d10v.c: Include elf/d10v.h
+ (enum reloc_type): Delete.
+ * elf32-d30v.c: Include elf/d30v.h
+ (enum reloc_type): Delete.
+
+ * Makefile.am: Run "make dep-am" to regenerate dependencies.
+ * Makefile.in: Regenerate.
+
+ * elf32-i386.c (elf_howto_table): Remove EMPTY_HOWTOs.
+ (elf32_i386_vtinherit_howto, elf32_i386_vtentry_howto): Delete and
+ move HOWTOs into elf_howto_table.
+ (R_386_standard, R_386_ext_offset): Define.
+ (R_386_ext, R_386_vt_offset, R_386_vt): Define.
+ (elf_i386_reloc_type_lookup): Modify calculation of index into
+ elf_howto_table since we've removed the padding.
+ (elf_i386_info_to_howto_rel): Likewise.
+ (elf_i386_relocate_section): Likewise.
+
+2000-06-06 Michael Snyder <msnyder@seadog.cygnus.com>
+
+ * elf.c (elf_grok_pr_status): Eliminate reference to prgregset_t.
+
+2000-06-05 H.J. Lu <hjl@gnu.org>
+
+ * elflink.c (_bfd_elf_link_record_dynamic_symbol): Don't flag
+ an error when seeing an undefined symbol with hidden/internal
+ attribute. It is handled in *_relocate_section ().
+
+2000-06-05 H.J. Lu <hjl@gnu.org>
+
+ * elflink.h (elf_fix_symbol_flags): Follow the link for the
+ indirect symbol for the ELF_LINK_NON_ELF bit.
+ (elf_link_output_extsym): Don't output the indirect symbol even
+ if the ELF_LINK_NON_ELF bit is set.
+
+2000-06-01 J.T. Conklin <jtc@redback.com>
+
+ * config.bfd (i[3456]86-*-netbsdelf*): New target.
+ (i[3456]86-*-netbsdaout*): New target.
+ (i[3456]86-*-netbsd*): Add bfd_elf32_i386_vec to targ_selvecs.
+ (i[3456]86-*-openbsd*): Likewise.
+
+2000-05-30 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * trad-core.c: From hpux-core.c, include <dirent.h> or
+ <sys/ndir.h> when possible.
+
+2000-05-31 Ulrich Drepper <drepper@redhat.com>
+
+ * elf.c (_bfd_elf_slurp_version_tables): Correct reading of version
+ definitions. We must not assume they are sorted in the file
+ according to their index numbers.
+
+2000-05-31 Alan Modra <alan@linuxcare.com.au>
+
+ * elf-hppa.h: (elf_hppa_final_link_relocate): Use e_rsel field
+ selector for R_PARISC_PCREL17R. R_PARISC_DIR17R and
+ R_PARISC_DIR17F are for absolute branches; Handle them as such.
+
+2000-05-30 Nick Clifton <nickc@cygnus.com>
+
+ * cpu-i960.c (scan_960_mach): Accept 80960KA, 80960KB,
+ 80960CA, 80960MC as valid machine names.
+
+2000-05-30 H.J. Lu <hjl@gnu.org>
+
+ * elflink.c (_bfd_elf_link_record_dynamic_symbol): Clear the
+ visibility bits if the symbol is undefined. Correctly handle
+ weak undefined symbols with hidden and internal attributes.
+
+ * elflink.h (elf_link_add_object_symbols): Always turn the
+ symbol into local if it has the hidden or internal attribute.
+
+2000-05-29 Philip Blundell <philb@gnu.org>
+
+ * ppcboot.c: Add packed attribute if compiling with GCC.
+
+2000-05-29 Anatoly Vorobey <mellon@pobox.com>
+
+ * elf.c (_bfd_elf_link_hash_table_init): Initialize dynlocal.
+
+2000-05-26 Michael Snyder <msnyder@seadog.cygnus.com>
+
+ * elf.c (elfcore_grok_prstatus, elfcore_grok_pstatus,
+ elfcore_grok_psinfo): Add code to allow debugging a 32-bit
+ corefile on a 64-bit (Sparc Solaris) host. Also clean up
+ a few old comments.
+
+2000-05-26 Alan Modra <alan@linuxcare.com.au>
+
+ * Makefile.am: Update dependencies with "make dep-am"
+ * Makefile.in: Regenerate.
+
+ * sysdep.h (gettext, dgettext, dcgettext, textdomain,
+ bindtextdomain): Replace defines with those from intl/libgettext.h
+ to quieten gcc warnings.
+
+2000-05-26 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * aoutx.h (find_nearest_line): Use IS_ABSOLUTE_PATH.
+
+ * archive.c (normalize, bfd_bsd_truncate_arname,
+ bfd_gnu_truncate_arname) [HAVE_DOS_BASED_FILE_SYSTEM]: Support
+ file names with backslashes.
+
+ * cache.c (bfd_open_file) [__MSDOS__]: Don't unlink the file
+ before opening it.
+
+ * sysdep.h: Include filenames.h.
+
+2000-05-26 Alan Modra <alan@linuxcare.com.au>
+
+ * opncls.c (bfd_close_all_done): Mask file perms with 0777 not 0x777.
+
+2000-05-26 Jakub Jelinek <jakub@redhat.com>
+
+ * elf64-sparc.c (sparc64_elf_relax_section): New.
+ (sparc64_elf_relocate_section): Optimize tail call into branch always
+ if possible.
+ * elf32-sparc.c (elf32_sparc_relocate_section): Likewise.
+ (elf32_sparc_relax_section): New.
+
+2000-05-26 Jakub Jelinek <jakub@redhat.com>
+
+ * elf64-sparc.c: Add ATTRIBUTE_UNUSED to unused function parameters.
+ Remove unusued variables.
+ (sparc64_elf_relocate_section): Change r_symndx type to unsigned long.
+ (sparc64_elf_merge_private_bfd_data): Fix shared library case from
+ previous fix, so that shared libs really don't influence targets
+ extension mask and memory model.
+
+2000-05-23 H.J. Lu <hjl@gnu.org>
+
+ * elf64-alpha.c (elf64_alpha_relocate_section): Check
+ h->root.other not h->other.
+ * elf32-mips.c (mips_elf_calculate_relocation): Likewise.
+
+ * elf32-ppc.c (ppc_elf_relocate_section): Fix a typo.
+
+2000-05-23 H.J. Lu <hjl@gnu.org>
+
+ * elf32-i386.c (elf_i386_relocate_section): Don't allow the
+ undefined symbol with the non-default visibility attributes.
+ * elf-hppa.h (elf_hppa_relocate_section): Likewise.
+ * elf32-arm.h (elf32_arm_relocate_section): Likewise.
+ * elf32-i370.c (i370_elf_relocate_section): Likewise.
+ * elf32-m68k.c (elf_m68k_relocate_section): Likewise.
+ * elf32-mcore.c (mcore_elf_relocate_section): Likewise.
+ * elf32-mips.c (mips_elf_calculate_relocation): 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-ia64.c (elf64_ia64_relocate_section): Likewise.
+ * elf64-sparc.c (sparc64_elf_relocate_section): Likewise.
+
+2000-05-22 Richard Henderson <rth@cygnus.com>
+
+ * elf64-ia64.c (ia64_howto_table): Add PCREL60B, PCREL21BI,
+ PCREL22, PCREL64I. Zero size of special relocs.
+ (elf64_ia64_reloc_type_lookup): Likewise.
+ (USE_BRL, oor_brl, oor_ip): New.
+ (elf64_ia64_relax_section): New.
+ (elf64_ia64_check_relocs): Handle PCREL60B, PCREL22, PCREL64I.
+ (elf64_ia64_install_value): Likewise, plus PCREL21BI.
+ (elf64_ia64_relocate_section): Likewise.
+ (bfd_elf64_bfd_relax_section): New.
+ * reloc.c (BFD_RELOC_IA64_PCREL21BI): New.
+ (BFD_RELOC_IA64_{PCREL22,PCREL60B,PCREL64I}): New.
+ * bfd-in2.h, libbfd.h: Regenerate.
+
+2000-05-22 Nick Clifton <nickc@cygnus.com>
+
+ * configure.in : Add peigen.lo to MIPS PE targets.
+ * configure: Regenerate.
+
+2000-05-22 Momchil Velikov <velco@fadata.bg>
+
+ * libbfd.c (_bfd_generic_verify_endian_match): Compare endianess
+ only if it is known for both input and output bfds. Separate
+ error message strings as in some languages, it may be necessary
+ to change more than one place in the string to change between
+ 'big' and 'little'.
+
+ * elf32-ppc.c (ppc_elf_merge_private_bfd_data): Remove inline
+ endianess checks, call _bfd_generic_verify_endian_match() instead.
+
+ * elf32-mips.c (_bfd_mips_elf_merge_private_bfd_data): Likewise.
+
+ * elf32-mcore.c (mcore_elf_merge_private_bfd_data): Likewise.
+
+ * elf32-arm.h (elf32_arm_merge_private_bfd_data): Likewise. Verify
+ endianess before checking bfd flavours.
+
+2000-05-22 H.J. Lu <hjl@gnu.org>
+
+ * elflink.h (elf_link_output_extsym): Clear the visibility
+ field for symbols not defined locally.
+
+2000-05-18 Alan Modra <alan@linuxcare.com.au>
+
+ * libhppa.h (re_assemble_3, re_assemble_12, re_assemble_16,
+ re_assemble_17, re_assemble_21, re_assemble_22): Don't mask insn.
+ (hppa_rebuild_insn): Mask immediate bits here instead.
+ * elf-hppa.h (elf_hppa_relocate_insn): Mask here too.
+
+2000-05-18 Momchil Velikov <velco@fadata.bg>
+
+ * elflink.h (elf_bfd_final_link, elf_link_input_bfd): When emiting
+ relocs for an executable, ensure that they are virtual addresses.
+
+2000-05-18 Jeffrey A Law (law@cygnus.com)
+
+ * config.bfd (hppa*64*-*-hpux11*): New target triplet.
+
+2000-05-17 S. Bharadwaj Yadavalli <sby@scrugs.lkg.dec.com>
+ Rick Gorton <gorton@scrugs.lkg.dec.com>
+
+ * elflink.h: Add emitrelocations support: when enabled, relocation
+ information and relocation sections are put into final output
+ executables. If the emitrelocations flag is set, do the following:
+ (elf_bfd_final_link): Emit relocation sections.
+ (elf_link_input_bfd): Compute relocation section contents.
+ (elf_gc_sections): Don't clean relocation sections.
+
+2000-05-16 Catherine Moore <clm@cygnus.com>
+
+ * som.c (som_decode_symclass): Recognize weak symbols.
+
+2000-05-16 Szabolcs Szakacsits <szaka@F-Secure.com>
+
+ * peigen.c (pe_print_idata): Undo part of 2000-05-12 change that
+ read idata section only from dataoff.
+ (pe_print_edata): Correctly check for valid eat_member.
+
+2000-05-16 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * elf32-sh.c (sh_elf_relax_delete_bytes): Handle R_SH_SWITCH8.
+
+2000-05-14 Philip Blundell <philb@gnu.org>
+
+ * config.bfd (armeb-*-elf, arm*b-*-linux-gnu*): New targets.
+
+2000-05-12 Alan Modra <alan@linuxcare.com.au>
+
+ * targets.c (bfd_target_vector): #ifdef BFD64 rs6000coff64_vec
+
+ * peigen.c (pe_print_idata): Look for .idata section and print
+ info even if data directory has zero entries. Read idata section
+ starting from dataoff, and adjust all data offsets to suit. Cast
+ all bfd_vma vars to unsigned long before passing to fprintf.
+ * peigen.c (pe_print_edata): Similarly, look for .edata section
+ and print info even if data directory has zero entries. Cast
+ all bfd_vma vars to unsigned long before passing to fprintf.
+
+ From Szabolcs Szakacsits <szaka@F-Secure.com>
+ * peigen.c (pe_print_idata): Use bfd_section_size rather than data
+ directory size which may be bogus.
+ * peigen.c (pe_print_edata): Similarly.
+
+2000-05-09 Alan Modra <alan@linuxcare.com.au>
+
+ * elf.c (bfd_section_from_shdr): Don't set use_rela_p if rela
+ section is empty.
+ (copy_private_bfd_data): Allow for space possibly taken up by elf
+ headers when calculating segment physical address from lma.
+
+2000-05-08 Alan Modra <alan@linuxcare.com.au>
+
+ * versados.c (versados_scan): Init stringlen and pass_2_done.
+
+ * trad-core.c (trad_unix_core_file_p): Return
+ bfd_error_wrong_format rather than bfd_error_file_truncated.
+
+ * peigen.c (_bfd_pei_swap_aouthdr_out): Pass ImageBase to
+ add_data_entry. DataDirectory virtual address is relative.
+ (pe_print_idata): Account for relative DataDirectory virtual
+ addresses. Don't trash datasize inside POWERPC_LE_PE code.
+ (pe_print_edata): Similarly.
+
+ From Szabolcs Szakacsits <szaka@F-Secure.com>
+ * peigen.c (dir_names): Add Delay Import Directory.
+ (pe_print_idata): Always search for bfd section containing
+ idata address rather than looking up section name. Print this
+ section name rather than .idata.
+ (pe_print_edata): Similarly. Also print some fields as %08lx.
+ (_bfd_pe_print_private_bfd_data_common): Print Reserved1 field as
+ Win32Version.
+
+2000-05-05 Clinton Popetz <cpopetz@cygnus.com>
+
+ * xcoff.h: Rename to xcoff-target.h
+ * Makefile.am: Change all instances of xcoff.h to xcoff-target.h
+ * coff-rs6000.c: Ditto.
+ * coff64-rs6000.c: Ditto.
+ * coff-pmac.c: Ditto.
+ * Makefile.in: Regenerate.
+
+2000-05-05 Clinton Popetz <cpopetz@cygnus.com>
+
+ * coffcode.h (coff_set_arch_mach_hook, coff_set_flags):
+ Change U802TOC64MAGIC to U803XTOCMAGIC.
+
+2000-05-04 Michael Snyder <msnyder@seadog.cygnus.com>
+
+ * elf.c (bfd_elf_get_arch_size): New function, return 32 | 64 | -1.
+ * bfd-in.h: Prototype bfd_elf_get_arch_size.
+ * bfd-in2.h: Prototype bfd_elf_get_arch_size.
+
+2000-05-04 Alan Modra <alan@linuxcare.com.au>
+
+ * libhppa.h (HPPA_R_CONSTANT): Cast argument to bfd_signed_vma.
+
+2000-05-03 Martin v. Löwis <loewis@informatik.hu-berlin.de>
+
+ * elflink.h (elf_link_add_object_symbols): Reset dynindx for
+ hidden and internal symbols.
+ (elf_fix_symbol_flags): Clear NEEDS_PLT for symbols with
+ visibility.
+ * elflink.c (_bfd_elf_link_record_dynamic_symbol): Do not
+ assign a PLT or GOT entry to symbols with hidden and
+ internal visibility.
+
+2000-05-03 Mark Elbrecht <snowball3@bigfoot.com>
+
+ * coff-go32.c (COFF_SECTION_ALIGNMENT_ENTRIES): Add entry for
+ the .bss section.
+ * coff-stgo32.c (COFF_SECTION_ALIGNMENT_ENTRIES): Likewise.
+
+2000-05-02 H.J. Lu <hjl@gnu.org>
+
+ * elf.c (prep_headers): Use ELFOSABI_NONE instead of
+ ELFOSABI_SYSV.
+
+2000-05-02 Alan Modra <alan@linuxcare.com.au>
+
+ * targets.c (bfd_target_vector): Restore bfd_elf32_hppa_vec.
+ * Makefile.am (BFD32_BACKENDS): Restore elf32-hppa.lo. Regenerate
+ dependencies.
+ * Makefile.in: Regenerate.
+
+2000-05-01 Jim Wilson <wilson@cygnus.com>
+
+ * Makefile.am (BFD32_BACKENDS): Add efi-app-ia32.lo.
+ (BFD32_BACKENDS_CFILES): Add efi-app-ia32.c.
+ (BFD64_BACKENDS): Delete coff-ia64.lo. Add efi-app-ia64.lo.
+ (BFD64_BACKENDS_CFILES): Delete coff-ia64.c. Add efi-app-ia64.c.
+ * Makefile.in: Rebuild.
+
+2000-05-02 Alan Modra <alan@linuxcare.com.au>
+
+ * config.bfd: Re-enable elf32-hppa. It now compiles, even if it
+ doesn't work very well.
+
+ * elf-hppa.h (elf_hppa_internal_shdr): Define.
+ (elf_hppa_fake_sections): hdr is elf_hppa_internal_shdr.
+ Set hdr->s_type to 1 if ARCH_SIZE == 32.
+ (_bfd_elf_hppa_gen_reloc_type): Add prototype.
+ (elf_hppa_info_to_howto): Likewise.
+ (elf_hppa_info_to_howto_rel): Likewise.
+ (elf_hppa_reloc_type_lookup): Likewise.
+ (elf_hppa_is_local_label_name): Likewise.
+ (elf_hppa_fake_sections): Likewise.
+ (elf_hppa_final_write_processing): Likewise.
+ (elf_hppa_howto_table): Fully initialise all entries.
+ (_bfd_elf_hppa_gen_reloc_type): Add ATTRIBUTE_UNUSED to args.
+ (elf_hppa_info_to_howto): Likewise.
+ (elf_hppa_info_to_howto_rel): Likewise.
+ (elf_hppa_reloc_type_lookup): Likewise.
+ (elf_hppa_final_write_processing, elf_hppa_add_symbol_hook,
+ elf_hppa_unmark_useless_dynamic_symbols,
+ elf_hppa_remark_useless_dynamic_symbols,
+ elf_hppa_record_segment_addrs, elf_hppa_final_link,
+ elf_hppa_relocate_section, elf_hppa_final_link_relocate,
+ elf_hppa_relocate_insn): Compile only if ARCH_SIZE == 64 until
+ elf32-hppa.c mess is cleaned up.
+ (elf_hppa_final_link_relocate): Make insn and r_type unsigned
+ int. Delete r_field. In case R_PARISC_PCREL21L, don't set
+ r_field then call hppa_field_adjust inline func with variable
+ r_field arg, instead call hppa_field_adjust with fixed arg.
+ In case R_PARISC_PCREL22F, don't set r_field.
+ (elf_hppa_relocate_insn): Change args and return type to unsigned
+ int. Call re_assemble_* funcs to do the work.
+
+ * elf32-hppa.c (hppa_elf_relocate_insn): Don't assume 32 bit when
+ sign extending.
+
+ * libhppa.h (HPPA_R_CONSTANT): Don't assume 32 bit when sign
+ extending.
+ (sign_extend): Mask first before sign extending.
+ (low_sign_extend): Rewrite without condition expression.
+ (ones, dis_assemble_3, dis_assemble_12, dis_assemble_16,
+ dis_assemble_17, dis_assemble_21, dis_assemble_22): Delete.
+ (assemble_3, assemble_6, assemble_12, assemble_16, assemble_16a,
+ assemble_17, assemble_21, sign_unext, low_sign_unext): Return
+ result as function return value rather than through pointer arg.
+ Accept unsigned int args, and return unsigned int.
+ (re_assemble_3): New. Combines function of dis_assemble_3 with
+ re-assembly of opcode and immediate.
+ (re_assemble_12): Likewise.
+ (re_assemble_16): Likewise.
+ (re_assemble_17): Likewise.
+ (re_assemble_21): Likewise.
+ (re_assemble_22): Likewise.
+ (hppa_field_adjust): Rewrite and document, paying attention to
+ size of types and signed/unsigned issues.
+ (get_opcode): Shift before masking.
+ (FDLW): Rename to FLDW.
+ (bfd_hppa_insn2fmt): Change arg to unsigned int. Delete fmt.
+ (hppa_rebuild_insn): Change args and return value to unsigned
+ int. Make use of re_assemble_*. Correct case 11.
+
+ * dep-in.sed: Handle ../opcodes/.
+ * Makefile.am (SOURCE_HFILES): Add elf-hppa.h, elf32-hppa.h,
+ elf64-hppa.h, hppa_stubs.h, xcoff.h.
+ (BFD32_BACKENDS_CFILES): Restore elf32-hppa.c.
+ Remove elf64-hppa.lo, cpu-ia64.lo, elf64-ia64.lo, elfarm-oabi.lo,
+ elfarm-nabi.lo dependencies outside of auto-dependency area.
+ Regenerate dependencies.
+ * Makefile.in: Regenerate.
+
+ * configure.in (TRAD_HEADER): Test non-null before
+ AC_DEFINE_UNQUOTED.
+ * configure: Regenerate.
+
+ * reloc.c: Fix mis-spelling in comment.
+
+2000-05-01 Alan Modra <alan@linuxcare.com.au>
+
+ * coff-sh.c (bfd_coff_small_swap_table): Fix Fri Apr 28 change.
+ * vms.c (vms_openr_next_archived_file): Return NULL.
+
+2000-04-28 Clinton Popetz <cpopetz@cygnus.com>
+
+ * coffcode.h Copy changes mistakenly done to libcoff.h in
+ 4/24/2000 patch.
+
+2000-04-29 Andreas Jaeger <aj@suse.de>
+
+ * libbfd-in.h: Correctly check GCC version.
+ * bfd-in.h: Likewise.
+ * libhppa.h: Likewise.
+ * libbfd.h: Regenerate.
+ * bfd-in2.h: Regenerate.
+
+2000-04-28 Clinton Popetz <cpopetz@cygnus.com>
+
+ * Makefile.am (BFD64_BACKENDS, BFD64_BACKENDS_CFILES): Add
+ coffdu-rs6000.{lo,c}.
+ (coff-pmac.lo, coff-rs6000.lo, coff64-rs6000.lo): Add dependency
+ on xcoff.h
+ * Makefile.in: Regenerate.
+ * xcoff.h: New file.
+ * coff-pmac.c: Use xcoff.h instead of coff-rs6000.c.
+ * coff-rs6000.c: Move all declarations and defines that are
+ common to the xcoff backends into xcoff.h
+ * coff64-rs6000.c: Ditto,
+
+2000-04-28 Clinton Popetz <cpopetz@cygnus.com>
+
+ * coff-mips.c (mips_ecoff_backend_data): Add initialization of
+ _bfd_coff_force_symnames in strings and
+ _bfd_coff_debug_string_prefix_length to their default values.
+ * coff-sh.c: (bfd_coff_small_swap_table): Ditto.
+
+2000-04-28 Clinton Popetz <cpopetz@cygnus.com>
+
+ * coff-alpha.c (alpha_ecoff_backend_data): Add initialization of
+ _bfd_coff_force_symnames in strings and
+ _bfd_coff_debug_string_prefix_length to their default values.
+
+2000-04-27 Alan Modra <alan@linuxcare.com.au>
+
+ * elf32-m68k.c (elf_m68k_gc_sweep_hook): Return if dynobj NULL.
+ Check local_got_refcounts before dereferencing.
+
+ * elf32-ppc.c (ppc_elf_relocate_section): Check splt != NULL
+ before deciding we don't need R_PPC_PLT32 relocation.
+ (ppc_elf_gc_sweep_hook): Check local_got_refcounts before
+ dereferencing.
+
+ * elflink.h (elf_gc_common_finalize_got_offsets): Fix comment.
+
+ * elf32-i386.c (elf_i386_check_relocs): Reference count .got and
+ .plt entries.
+ (elf_i386_gc_sweep_hook): Garbage collect .got and .plt entries.
+ (elf_i386_adjust_dynamic_symbol): Recognize unused .plt entries.
+ (elf_i386_relocate_section): Allow for .plt to go missing.
+ (elf_i386_finish_dynamic_symbol): Use same test to decide if we
+ can use a relative reloc for got as elf_i386_relocate_section.
+ (bfd_elf32_bfd_final_link): Define to use gc form of final link.
+
+2000-04-26 Clinton Popetz <cpopetz@cygnus.com>
+
+ * config.bfd: Remove extraneous bfd_powerpc_64_arch.
+
+2000-04-24 Clinton Popetz <cpopetz@cygnus.com>
+
+ * Makefile.am (coff64-rs6000.lo): New rule.
+ * Makefile.in: Regenerate.
+ * coff-rs6000.c (xcoff_mkobject, xcoff_copy_private_bfd_data,
+ xcoff_is_local_label_name, xcoff_rtype2howto,
+ xcoff_reloc_type_lookup, xcoff_slurp_armap, xcoff_archive_p,
+ xcoff_read_ar_hdr, xcoff_openr_next_archived_file, xcoff_write_armap,
+ xcoff_write_archive_contents): No longer static, and prefix with _bfd_.
+ (NO_COFF_SYMBOLS): Define.
+ (xcoff64_swap_sym_in, xcoff64_swap_sym_out, xcoff64_swap_aux_in,
+ xcoff64_swap_aux_out): New functions; handle xcoff symbol tables
+ internally.
+ (MINUS_ONE): New macro.
+ (xcoff_howto_tabl, xcoff_reloc_type_lookup): Add 64 bit POS
+ relocation.
+ (coff_SWAP_sym_in, coff_SWAP_sym_out, coff_SWAP_aux_in,
+ coff_SWAP_aux_out): Map to the new functions.
+ * coff64-rs6000.c: New file.
+ * libcoff.h (bfd_coff_backend_data): Add new fields
+ _bfd_coff_force_symnames_in_strings and
+ _bfd_coff_debug_string_prefix_length.
+ (bfd_coff_force_symnames_in_strings,
+ bfd_coff_debug_string_prefix_length): New macros for above fields.
+ * coffcode.h (coff_set_arch_mach_hook): Handle XCOFF64 magic.
+ Set machine to 620 for XCOFF64. Use bfd_coff_swap_sym_in instead
+ of using coff_swap_sym_in directly.
+ (FORCE_SYMNAMES_IN_STRINGS): New macro, defined for XCOFF64.
+ (coff_set_flags) Set magic for XCOFF64.
+ (coff_compute_section_file_positions): Add symbol name length to
+ string section length if bfd_coff_debug_string_prefix_length is
+ true.
+ (coff_write_object_contents): Don't do reloc overflow for XCOFF64.
+ (coff_slurp_line_table): Use bfd_coff_swap_lineno_in instead of
+ using coff_swap_lineno_in directly.
+ (bfd_coff_backend_data): Add _bfd_coff_force_symnames_in_strings
+ and _bfd_coff_debug_string_prefix_length fields.
+ * coffgen.c (coff_fix_symbol_name, coff_write_symbols): Force
+ symbol names into strings table when
+ bfd_coff_force_symnames_in_strings is true.
+ * coffswap.h (MAX_SCNHDR_NRELOC, MAX_SCNHDR_NLNNO, GET_RELOC_VADDR,
+ SET_RELOC_VADDR): New macros.
+ (coff_swap_reloc_in, coff_swap_reloc_out): Use above macros.
+ (coff_swap_aux_in, coff_swap_aux_out): Remove RS6000COFF_C
+ code.
+ (coff_swap_aouthdr_in, coff_swap_aouthdr_out): Handle XCOFF64
+ changes within RS6000COFF_C specific code.
+ (coff_swap_scnhdr_out): Use PUT_SCNHDR_NLNNO, PUT_SCNHDR_NRELOC,
+ MAX_SCNHDR_NRELOC, and MAX_SCNHDR_NLNNO.
+ * reloc.c (bfd_perform_relocation, bfd_install_relocation):
+ Extend existing hack on target name.
+ * xcofflink.c (XCOFF_XVECP): Extend existing hack on
+ target name.
+ * coff-tic54x.c (ticof): Keep up to date with new fields
+ in bfd_coff_backend_data.
+ * config.bfd: Add bfd_powerpc_64_arch to targ_arch and define
+ targ_selvecs to include rs6000coff64_vec for rs6000.
+ * configure.in: Add rs6000coff64_vec case.
+ * cpu-powerpc.c: New bfd_arch_info_type.
+
+2000-04-24 Jeffrey A Law (law@cygnus.com)
+
+ * config.bfd: Only disable elf32-hppa vectors, not all of the
+ BSD and OSF configuration support. Provide (disabled) clauses
+ for PA64 support.
+ * configure.in: Add clause for PA64 support.
+ * configure: Rebuilt.
+
+ * targets.c (bfd_target_vector): Add bfd_elf64_hppa_vec.
+ (bfd_elf64_hppa_vec): Declare.
+
+ * Makefile.am (BFD64_BACKENDS): Add elf64-hppa.lo
+ (BFD64_BACKENDS_CFILES): Add elf64-hppa.c
+ (elf64-hppa.lo): Add dependencies.
+ * Makefile.in: Rebuilt.
+
+ * elf64-hppa.c, elf64-hppa.h: New files with PA64 support.
+
+2000-04-24 Jason Eckhardt <jle@cygnus.com>
+
+ * libhppa.h (dis_assemble_16): New function.
+ (pa_arch): Added pa20w element.
+
+2000-04-24 Ulrich Drepper <drepper@cygnus.com>
+
+ * elf-bfd.h: Add prototypes for bfd_elf32_write_relocs,
+ bfd_elf32_slurp_reloc_table, bfd_elf64_write_relocs, and
+ bfd_elf64_slurp_reloc_table.
+
+ * elfcode.h (elf_write_relocs, elf_slurp_reloc_table): New
+ definitions to get external names.
+ (elf_write_relocs): Renamed from write_relocs and make global.
+ (elf_slurp_reloc_table): Make global.
+ (_bfd_elf,size_info): Use elf_write_relocs instead of write_relocs.
+
+ * archive.c (hpux_uid_gid_encode): New function.
+ (bfd_ar_hdr_from_filesystem): Use it if HPUX_LARGE_AR_IDS is
+ defined and the ID is greater than 99999.
+ (bfd_generic_stat_arch_elt): If HPUX_LARGE_AR_IDS is defined decode
+ special uid/gid fields into 32 bit values.
+
+2000-04-21 Matthew Green <mrg@cygnus.com>
+
+ * config.bfd: Add NetBSD/sparc64 support.
+
+2000-04-21 Richard Henderson <rth@cygnus.com>
+ David Mosberger <davidm@hpl.hp.com>
+ Timothy Wall <twall@cygnus.com>
+ Jim Wilson <wilson@cygnus.com>
+
+ * Makefile.am (ALL_MACHINES): Add cpu-ia64.lo.
+ (ALL_MACHINES_CFILES): Add cpu-ia64.c.
+ (BFD64_BACKENDS): Add elf64-ia64.lo.
+ (BFD64_BACKENDS_CFILES): Add elf64-ia64.c.
+ (cpu-ia64.lo, elf64-ia64.lo): New rules.
+ * Makefile.in: Rebuild.
+ * archures.c (enum bfd_architecture): Add bfd_arch_ia64.
+ (bfd_ia64_arch): Declare.
+ (bfd_archures_list): Add bfd_ia64_arch.
+ * bfd-in2.h: Rebuild.
+ * config.bfd: (ia64*-*-linux-gnu*, ia64*-*-elf*): New targets.
+ * configure: Rebuild.
+ * configure.host: (ia64-*-linux*): New host.
+ * configure.in (bfd_elf64_ia64_little_vec, bfd_elf64_ia64_big_vec,
+ bfd_efi_app_ia64_vec, bfd_efi_app_ia64_vec): New vectors.
+ * elf.c (prep_headers): Add bfd_arch_ia64.
+ * libbfd.h: Rebuild.
+ * reloc.c: Add IA-64 relocations.
+ * targets.c (bfd_elf64_ia64_little_vec, bfd_elf64_ia64_big_vec):
+ Declare.
+ (bfd_target_vect): Add bfd_elf64_ia64_little_vec.
+ * cpu-ia64-opc.c, cpu-ia64.c, elf64-ia64.c: New files.
+
+2000-04-21 Richard Henderson <rth@cygnus.com>
+
+ * elf32-d30v.c (bfd_elf_d30v_reloc): Don't modify section
+ contents when performing a partial link.
+ (bfd_elf_d30v_reloc_21): Likewise.
+
+2000-04-20 H.J. Lu <hjl@gnu.org>
+
+ * elf32-i386.c (elf_i386_relocate_section): Restrict 1998-12-10
+ patch to symbols defined by a shared object.
+ * elf32-ppc.c (ppc_elf_relocate_section): Similarly.
+
+2000-04-19 Michael Sokolov <msokolov@ivan.Harhan.ORG>
+
+ K&R compiler fixes.
+ * dwarf2.c (concat_filename): Avoid string literal concatenation.
+ * ieee.c (ieee_get_symtab): Don't initialise union in struct.
+
+2000-04-11 David Mosberger <davidm@hpl.hp.com>
+
+ * Makefile.am (BFD64_BACKENDS): Mention coff-ia64.lo.
+ (BFD64_BACKENDS_CFILES): Mention coff-ia64.c
+ (coff-ia64.lo): Add dependency.
+ * Makefile.in: Regenerate.
+ * coff-ia64.c: New file.
+ * efi-app-ia32.c: Ditto.
+ * efi-app-ia64.c: Ditto.
+ * coffcode.h (coff_set_arch_mach_hook): Handle IA64MAGIC.
+ (coff_set_flags): Ditto.
+ (coff_write_object_contents) [IA64]: Set magic number to ZMAGIC.
+ * config.bfd (i[3456]86-*-linux-gnu*): Mention bfd_efi_app_ia32_vec.
+ * configure.in (elf): Handle bfd_efi_app_ia32 and bfd_efi_app_ia64_vec.
+ * configure: Regenerate.
+ * libpei.h (GET_OPTHDR_IMAGE_BASE): New macro.
+ (PUT_OPTHDR_IMAGE_BASE): Ditto.
+ (GET_OPTHDR_SIZE_OF_STACK_RESERVE): Ditto.
+ (PUT_OPTHDR_SIZE_OF_STACK_RESERVE): Ditto.
+ (GET_OPTHDR_SIZE_OF_STACK_COMMIT): Ditto.
+ (PUT_OPTHDR_SIZE_OF_STACK_COMMIT): Ditto.
+ (GET_OPTHDR_SIZE_OF_HEAP_RESERVE): Ditto.
+ (PUT_OPTHDR_SIZE_OF_HEAP_RESERVE): Ditto.
+ (GET_OPTHDR_SIZE_OF_HEAP_COMMIT): Ditto.
+ (PUT_OPTHDR_SIZE_OF_HEAP_COMMIT): Ditto.
+ (GET_PDATA_ENTRY): Ditto.
+ * peigen.c (_bfd_pei_swap_aouthdr_in) [COFF_WITH_PEP64]: Don't read
+ data_start. Use above macros to read fields that are 64 bit wide for
+ COFF_WITH_PEP64. Don't truncate entry and text_start to 32 bits.
+ (_bfd_pei_swap_aouthdr_out) [PEI_FORCE_MINIMUM_ALIGNMENT]: Force
+ FileAlignment and SectionAlignment to minimum alignment if they
+ are zero.
+ (_bfd_pei_swap_aouthdr_out) [PEI_DEFAULT_TARGET_SUBSYSTEM]: Set
+ Subsystem to default PEI_DEFAULT_TARGET_SUBSYSTEM.
+ (_bfd_pei_swap_aouthdr_out) [COFF_WITH_PEP64]: Don't set data_start.
+ Use above macros to write fields that are 64 bit wide for
+ COFF_WITH_PEP64.
+ (pe_print_pdata): Set PDATA_ROW_SIZE to 3*8 for COFF_WITH_PEP64,
+ 5*4 otherwise. This should be right for IA-32 and IA-64, but may
+ be wrong for platforms. Use PDATA_ROW_SIZE instead of hardcoded
+ value of 20 bytes. Modify printing for COFF_WITH_PEP64 to print
+ begin address, end address, and unwind info address only. Use
+ GET_PDATA_ENTRY() to read .pdata entries. Use fprintf_vma() to
+ print addresses.
+ (tbl): Add SECTION, REL32, RESERVED1, MIPS_JMPADDR16, DIR64, and
+ HIGH3ADJ relocation names.
+ (_bfd_pe_print_private_bfd_data): Print Subsystem name in legible form.
+ * targets.c: Declare bfd_efi_app_ia32_vec and
+ bfd_efi_app_ia64_vec.
+ (bfd_target_vector): Mention bfd_efi_app_ia32_vec and
+ bfd_efi_app_ia64_vec.
+
+2000-04-17 Timothy Wall <twall@cygnus.com>
+
+ * bfd-in2.h: Add prototypes for tic54x load page access.
+ * bfd-in.h: Regenerate.
+ * coff-tic54x.c: Add load page functions; allow bfd_arch_unknown
+ in customized _set_arch_mach function.
+ * coffcode.h (coff_set_alignment_hook): Set section load page if
+ the appropriate macro is defined.
+ (write_object_contents): Read section load page.
+
+2000-04-13 Alan Modra <alan@linuxcare.com.au>
+
+ * elf32-hppa.h: Update copyright date.
+
+ * elf32-fr30.c (fr30_elf_i20_reloc): Don't use U suffix.
+ * elf32-mips.c (_bfd_mips_elf_relocate_section): And here.
+
+ * elf32-d30v.c (MAX32): Don't use LL suffix.
+ (MIN32): Define in terms of MAX32.
+ (bfd_elf_d30v_reloc): Make relocation a bfd_signed_vma.
+
+ * coff-a29k.c (SIGN_EXTEND_HWORD): Replace with more concise
+ expression.
+
+ * peicode.h (pe_ILF_build_a_bfd): Remove UL from hex constants.
+
+2000-04-12 Alan Modra <alan@linuxcare.com.au>
+
+ * dep-in.sed: Match space before file name, not after.
+ * Makefile.am: Regenerate dependencies.
+ * Makefile.in: Regenerate.
+
+ * reloc.c (_bfd_relocate_contents): In complain_overflow_bitfield
+ case, allow address wrap-around stupidly removed 2000-03-17. Sign
+ extend without an if statement.
+
+2000-04-11 Alan Modra <alan@linuxcare.com.au>
+
+ * coff-mips.c (mips_gprel_reloc): Test for 16 bit range using
+ signed quantites.
+ * elf32-mips.c (gprel16_with_gp): Likewise.
+ * elf32-hppa.c (elf32_hppa_bfd_final_link_relocate): Test range
+ here using -0x40000, not (int)0xfffc0000.
+ (elf32_hppa_size_of_stub): Likewise.
+
+2000-04-11 Timothy Wall <twall@cygnus.com>
+
+ * coff-tic54x.c: Now builds with all targets.
+ * Makefile.am: Add coff/tic54x.h to coff-tic54x.o dependencies.
+ * Makefile.in: Regenerate.
+ * coffcode.h (coff_set_arch_mach_hook): Eliminate warning on
+ unitialized variable.
+
+2000-04-07 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * configure.in (WARN_CFLAGS): Set to -W -Wall by default. Add
+ --enable-build-warnings option.
+ * Makefile.am (AM_CFLAGS, WARN_CFLAGS): Add definitions.
+ * Makefile.in, configure: Re-generate.
+
+2000-04-07 Nick Clifton <nickc@cygnus.com>
+
+ * reloc.c: Add BFD_RELOC_ARM_PCREL_BLX and
+ BFD_RELOC_THUMB_PCREL_BLX.
+
+ * elf32-arm.h (elf32_arm_final_link_relocate): Handle
+ R_ARM_XPC25 and R_ARM_THM_PC22.
+
+ * elfarm-nabi.c (elf32_arm_howto_): Fix definitions of
+ R_ARM_XPC25 and R_ARM_THM_XPC22.
+ (elf32_arm_reloc_map): Make BFD_RELOC_{ARM|THUMB}_PCREL_BLX to
+ R_ARM_[XPC25|THM_XPC22].
+
+ * elfarm-oabi.c: Define OLD_ARM_ABI and change include from
+ elf/arm-oabi.h to elf/arm.h
+
+ * Makefile.am: Fix dependency for elfarm-oabi.c
+ * Makefile.in: Regenerate.
+
+ * bfd-in2.h: Regenerate.
+ * libbfd.h: Regenerate.
+
+2000-04-06 Michael Snyder <msnyder@seadog.cygnus.com>
+
+ * elfcore.h (elf_core_file_p): preserve value of tdata at entry,
+ and restore it on failure. Release newly allocated tdata on
+ failure.
+
+2000-04-07 Jim Wilson <wilson@cygnus.com>
+
+ * dwarf2.c (struct dwarf2_debug): New field dwarf_line_size.
+ (decode_line_info): Set it. Report error if unit->line_offset is
+ equal to or larger than it.
+
+2000-04-07 Timothy Wall <twall@cygnus.com>
+
+ * targets.c: Added vecs for tic54x.
+ * reloc.c: Added relocs for tic54x.
+ * libbfd.h: Regenerated.
+ * configure: Add TI COFF vecs for tic54x.
+ * configure.in: Ditto.
+ * config.bfd (targ_cpu): Recognize new tic54x target.
+ * coffcode.h (coff_slurp_symbol_table): Additions for TI COFF handling.
+ * bfd-in2.h: Add tic54x target and relocations.
+ * Makefile.am, Makefile.in: Add tic54x target.
+ * archures.c (bfd_archures_list): Add tic54x target.
+ * coff-tic54x.c: New.
+ * cpu-tic54x.c: New.
+
+2000-04-06 Michael Snyder <msnyder@seadog.cygnus.com>
+
+ * elfcore.h (elf_core_file_p): call backend_object_p which
+ thereby gets an opportunity to update the arch/machine type.
+
+2000-04-06 Timothy Wall <twall@cygnus.com>
+
+ * coffcode.h (coff_slurp_symbol_table): Handle C_STATLAB storage
+ class. Handle SEC_CLINK and SEC_BLOCK flags.
+ * section.c: Add SEC_CLINK and SEC_BLOCK flags.
+ * bfd-in2.h: Add SEC_CLINK and SEC_BLOCK flags.
+
+2000-04-06 Nick Clifton <nickc@cygnus.com>
+
+ * elf32-arm.h (elf32_arm_set_private_flags): Only check for
+ EF_INTERWORK if this is an unknown EABI.
+ (elf32_arm_merge_private_bfd_data): Check EABI version
+ numbers. Only check EF_xxx flags if the EABI version number
+ is unknown.
+ (elf32_arm_check_private_bfd_data): Only check EF_xxx flags
+ if the EABI version number is unknown.
+ (elf32_arm_print_private_bfd_data): Only decode EF_xxx flags
+ if the EABI version number is unknown.
+
+2000-04-05 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * reloc.c (_bfd_relocate_contents): Add BFD_RELOC_SH_LOOP_START and
+ BFD_RELOC_SH_LOOP_END.
+ * elf32-sh.c (sh_elf_howto_tab): Change special_func to
+ sh_elf_ignore_reloc for all entries that sh_elf_reloc used to ignore.
+ Add entries for R_SH_LOOP_START and R_SH_LOOP_END.
+ (sh_elf_reloc_loop): New function.
+ (sh_elf_reloc): No need to test for always-to-be-ignored relocs
+ any more.
+ (sh_rel): Add entries for BFD_RELOC_SH_LOOP_{START,END}.
+ (sh_elf_relocate_section): Handle BFD_RELOC_SH_LOOP_{START,END}.
+ * bfd-in2.h, libbfd.h: Regenerate.
+
+2000-04-04 Alan Modra <alan@linuxcare.com.au>
+
+ * po/bfd.pot: Regenerate.
+
+ * Makefile.am: Remove extraneous mkdep comment.
+ (MKDEP): Use gcc -MM rather than mkdep.
+ (DEP): Quote when passing vars to sub-make. Add warning
+ message to end.
+ (DEP1): Rewrite for "gcc -MM".
+ (CLEANFILES): Add DEP2.
+ Update dependencies.
+ * Makefile.in: Regenerate.
+
+2000-04-03 Kevin Buettner <kevinb@redhat.com>
+
+ * configure.in: Added corefile support for AIX 4.3. In particular,
+ AIX_CORE_DUMPX_CORE will be defined in addition to AIX_CORE when
+ compiling rs6000-core.c.
+ * configure: Regenerated.
+
+2000-04-03 H.J. Lu <hjl@gnu.org>
+
+ * cache.c (bfd_open_file): Unlink the output file only if
+ it has non-zero size.
+
+2000-04-01 Ken Block USG <block@zk3.dec.com>
+
+ * elf64-alpha.c (elf64_alpha_relocate_section): Don't emit
+ relative relocations for non-loaded sections in shared objects.
+ (elf64_alpha_check_relocs): Similarly.
+
+2000-04-03 Hans-Peter Nilsson <hp@axis.com>
+
+ * aoutx.h (NAME(aout,reloc_type_lookup)): Add BFD_RELOC_8 and
+ BFD_RELOC_16 to switch for extended relocs.
+ (MY_swap_ext_reloc_in): New.
+ (MY_swap_ext_reloc_out): New.
+ (NAME(aout,slurp_reloc_table)): Use MY_swap_ext_reloc_in rather
+ than NAME(aout,swap_ext_reloc_in) for extended relocs.
+ (NAME(aout,squirt_out_relocs)): Similarly use
+ MY_swap_ext_reloc_out.
+ (aout_link_reloc_link_order): Use MY_put_ext_reloc if defined.
+
+2000-04-03 Kazu Hirata <kazu@hxi.com>
+
+ * coff-h8300.c (h8300_reloc16_extra_cases): Add bsr:16 -> bsr:8 to
+ the R_PCRWORD_B case.
+
+2000-03-31 Thomas de Lellis <tdel@wrs.com>
+
+ * srec.c : Set CHUNK size to 16 bytes to prevent download failures
+ on some targets.
+ * ihex.c : Ditto.
+
+2000-03-30 Donald Lindsay <dlindsay@cygnus.com>
+
+ * elf32-m32r.c (m32r_elf_generic_reloc): new function. All
+ HOWTO references to bfd_elf_generic_reloc, that have
+ partial_inplace == true, now use the new function. The function
+ is based on the recent rewrite of m32r_elf_lo16_reloc(), and
+ extends its fixes to the R_M32R_{16,24,32} relocs.
+ The new logic in m32r_elf_lo16_reloc() has been removed, and
+ it instead calls the new routine to obtain that functionality.
+
+2000-03-27 Alan Modra <alan@linuxcare.com.au>
+
+ * elf32-avr.c (elf32_avr_gc_mark_hook, elf32_avr_gc_sweep_hook,
+ elf32_avr_check_relocs, avr_final_link_relocate,
+ elf32_avr_relocate_section, bfd_elf_avr_final_write_processing,
+ elf32_avr_object_p): Add prototypes.
+ (elf32_avr_gc_mark_hook): Add default for h->root.type.
+ (bfd_elf_avr_final_write_processing): Make static.
+
+2000-03-27 Denis Chertykov <denisc@overta.ru>
+
+ * cpu-avr.c: New file. BFD support routines for AVR architecture.
+ * archures.c (bfd_architecture): Add AVR architecture.
+ (bfd_archures_list): Add reference to AVR architecture info.
+ * elf.c (prep_headers): Handle bfd_arch_avr.
+ * reloc.c: Add various AVR relocation enums.
+ * targets.c (bfd_elf32_avr_vec): Declare and add to target vector
+ list.
+ * Makefile.am: Add support for AVR elf.
+ * configure.in: Likewise.
+ * config.bfd: Likewise.
+ * Makefile.in: Regenerate.
+ * configure: This too.
+ * bfd-in2.h: And this.
+ * libbfd.h: And this.
+
+2000-03-24 H.J. Lu <hjl@gnu.org>
+
+ * elf64-alpha.c (elf64_alpha_merge_ind_symbols): Add prototype.
+ (elf64_alpha_find_reloc_at_ofs): Likewise.
+
+2000-03-17 Alan Modra <alan@linuxcare.com.au>
+
+ * reloc.c (bfd_check_overflow): In case complain_overflow_bitfield,
+ flag an overflow if the bitfield is outside -2**n to 2**n-1. The
+ allowable range used to be -2**(n-1) to 2**n-1.
+ * reloc.c (_bfd_relocate_contents): Same here. Also replace
+ "boolean overflow" with "bfd_reloc_status_type flag".
+
+2000-03-14 Doug Evans <dje@casey.transmeta.com>
+
+ * elf32-m32r.c (m32r_elf_lo16_reloc): Rewrite.
+
+2000-03-14 Kazu Hirata <kazu@hxi.com>
+
+ * reloc16.c (bfd_coff_reloc16_relax_section): Count the total number
+ of shrinks properly, including the last reloc.
+
+2000-03-13 Kazu Hirata <kazu@hxi.com>
+
+ * coff-h8300.c (h8300_reloc16_extra_cases): Fix the sanity
+ check for R_MOVL2.
+
+2000-03-11 Alan Modra <alan@linuxcare.com.au>
+
+ * ieee.c (ieee_archive_p): Return bfd_error_wrong_format on
+ a format mismatch rather than an "error" from bfd_read such as
+ bfd_error_file_truncated.
+
+2000-03-10 Geoff Keating <geoffk@cygnus.com>
+
+ * elf32-mips.c (_bfd_mips_elf_relocate_section): Do proper
+ sign-extension and big-endian compensation for
+ R_MIPS_64 even in ld -r.
+
+2000-03-10 Geoffrey Keating <geoffk@cygnus.com>
+
+ * elf32-mips.c (mips_elf_next_relocation): Rename from
+ mips_elf_next_lo16_relocation, and generalize to look
+ for any relocation type.
+ (elf_mips_howto_table): Make R_MIPS_PC16 pcrel_offset.
+ (elf_mips_gnu_rel_hi16): Howto for R_MIPS_GNU_REL_HI16.
+ (elf_mips_gnu_rel_lo16): Howto for R_MIPS_GNU_REL_LO16.
+ (elf_mips_gnu_rel16_s2): Howto for R_MIPS_GNU_REL16_S2.
+ (elf_mips_gnu_pcrel64): Howto for R_MIPS_PC64.
+ (elf_mips_gnu_pcrel32): Howto for R_MIPS_PC32.
+ (bfd_elf32_bfd_reloc_type_lookup): Add new relocs.
+ (mips_rtype_to_howto): Likewise.
+ (mips_elf_calculate_relocation): Handle new relocs.
+ (_bfd_mips_elf_relocate_section): REL_HI16/REL_LO16 relocs
+ are paired. The addend for R_MIPS_GNU_REL16_S2
+ is shifted right two bits.
+
+2000-03-10 Alan Modra <alan@linuxcare.com.au>
+
+ * reloc.c (bfd_perform_relocation): Undo emacs formatting of
+ comment, and ensure it doesn't happen again.
+ (bfd_install_relocation): Same here.
+ (_bfd_relocate_contents): Don't bother assigning unused signmask
+ shift result. Fix typos in comments.
+ Remove trailing whitespace throughout file.
+
+2000-03-07 Doug Evans <dje@casey.transmeta.com>
+
+ * reloc.c (reloc_howto_struct): Fix partial_inplace comment.
+ * bfd-in2.h: Rebuild.
+
+2000-03-06 Nick Clifton <nickc@cygnus.com>
+
+ * peicode.h (struct pe_ILF_vars): Add sym_ptr_table and
+ sym_ptr_ptr fields.
+ (SIZEOF_ILF_SYM_PTR_TABLE): Define.
+ (SIZEOF_ILF_STRINGS): Redefine.
+ (pe_ILF_make_a_symbol-reloc): New function. Creates a symbol
+ relative reloc, as opposed to a section relative reloc.
+ (pe_ILF_make_a_symbol): Set the class of local symbols to C_STAT
+ not C_LABEL.
+ Add length of symbol's prefix to string pointer.
+ Store a pointer to the symbol in the symbol pointer table.
+ (pe_ILF_build_a_bfd): Do not build .idata$2 or .idata$7.
+ Initialise the symbol pointer table.
+ Store the hint in the Hint/Name table.
+ Make the jump reloc be symbol realtive, not section relative.
+ Create an import symbol for imported code.
+
+2000-03-06 Catherine Moore <clm@cygnus.com>
+
+ * elf.c (swap_out_syms): Check for null type_ptr.
+
+2000-03-01 Hans-Peter Nilsson <hp@axis.com>
+
+ * aout-target.h (MY(write_object_contents)): Remove unused
+ and unusable "#if CHOOSE_RELOC_SIZE".
+ * pc532-mach.c (MY(write_object_contents)): Ditto.
+ * netbsd.h (MY(write_object_contents)): Ditto.
+ * hp300hpux.c (MY(write_object_contents)): Ditto.
+ * freebsd.h (MY(write_object_contents)): Ditto.
+ * aout-tic30.c (tic30_aout_write_object_contents): Ditto.
+
+2000-02-29 H.J. Lu <hjl@gnu.org>
+
+ * peicode.h (jtab): Make it static.
+
+ * coff-sh.c (sh_align_load_span): Declared if COFF_WITH_PE is
+ defined and COFF_IMAGE_WITH_PE is not defined.
+ (_bfd_sh_align_load_span): Defined as sh_align_load_span if
+ COFF_WITH_PE is defined and COFF_IMAGE_WITH_PE is not defined.
+
+2000-03-01 Nick Clifton <nickc@cygnus.com>
+
+ * coff-arm.c (bfd_arm_process_before_allocation): Make
+ 'symndx' signed to prevent compile time warning.
+
+ * coff-mcore.c: Remove unused prototype for pe_object_p.
+
+ * coff-sh.c: Add "#ifndef COFF_IMAGE_WITH_PE" around static
+ functions that are not used when COFF_IMAGE_WITH_PE is
+ defined.
+ (struct sh_opcode): Change type of 'flags' field to unsigned
+ long so that it can hold the USESAS flag.
+
+ * coffcode.h (styp_to_sec_flags): Initialise 'target_name'.
+
+ * elf-m10300.c (mn10300_elf_relax_section): Initialise
+ 'sym_sec'.
+
+ * elf32-i370.c: Add ATTRIBUTE_UNUSED to unused function
+ parameters.
+ Remove unusued variables and code.
+ (elf_backend_add_symbol_hook): Fix prototype.
+
+ * elf32-m68k.c (elf_m68k_gc_sweep_hook): Initialise 'sgot' and
+ 'srelgot'.
+
+ * elf32-mcore.c (mcore_elf_relocate_section): Initialise
+ 'oldinst'.
+
+ * elf32-mips.c: Add ATTRIBUTE_UNUSED to unused function
+ parameters.
+ Remove unusued variables and code.
+ (elf_backend_add_symbol_hook): Fix prototype.
+
+ * elf32-sh.c (sh_elf_set_mach_from_flags): Use 'flags'.
+
+ * elflink.h (elf_bfd_link_add_symbols): Add ATTRIBUTE_UNUSED
+ to unused function parameter.
+
+ * pe-mips.c: Add ATTRIBUTE_UNUSED to unused function
+ parameters.
+ Use EMPTY_HOWTO to initialise empty howto slots.
+ Remove unused variables.
+
+ * peicode.h (pe_ILF_build_a_bfd): Initialise id6.
+
+2000-03-01 H.J. Lu <hjl@gnu.org>
+
+ * aoutx.h (aout_link_input_section_std): Pass "true" to
+ the undefined_symbol callback.
+ (aout_link_input_section_ext): Likewise.
+ * bout.c (get_value): Likewise.
+ * coff-a29k.c (coff_a29k_relocate_section): Likewise.
+ * coff-alpha.c (alpha_ecoff_get_relocated_section_conten):
+ Likewise.
+ (alpha_relocate_section): Likewise.
+ * coff-arm.c (coff_arm_relocate_section): Likewise.
+ * coff-i960.c (coff_i960_relocate_section): Likewise.
+ * coff-mcore.c (coff_mcore_relocate_section): Likewise.
+ * coff-mips.c (mips_relocate_section): Likewise.
+ * coff-ppc.c (coff_ppc_relocate_section): Likewise.
+ * coff-sh.c (sh_relocate_section): Likewise.
+ * coff-tic80.c (coff_tic80_relocate_section): Likewise.
+ * cofflink.c (_bfd_coff_generic_relocate_section): Likewise.
+ * elf-m10200.c (mn10200_elf_relocate_section): Likewise.
+ * elf-m10300.c (mn10300_elf_relocate_section): Likewise.
+ * elf32-d10v.c (elf32_d10v_relocate_section): Likewise.
+ * elf32-fr30.c (fr30_elf_relocate_section): Likewise.
+ * elf32-hppa.c (elf32_hppa_relocate_section): Likewise.
+ * elf32-i370.c (i370_elf_relocate_section): Likewise.
+ * elf32-m32r.c (m32r_elf_relocate_section): Likewise.
+ * elf32-mcore.c (mcore_elf_relocate_section): Likewise.
+ * elf32-sh.c (sh_elf_relocate_section): Likewise.
+ * elf32-v850.c (v850_elf_relocate_section): Likewise.
+ * elflink.c (_bfd_elf_link_record_dynamic_symbol): Likewise.
+ * elflink.h (elf_link_output_extsym): Likewise.
+ * pe-mips.c (coff_pe_mips_relocate_section): Likewise.
+ * reloc.c (bfd_generic_get_relocated_section_conten): Likewise.
+ * reloc16.c (_bfd_ppc_xcoff_relocate_section): Likewise.
+
+ * elf-hppa.h (elf_hppa_relocate_section): Pass "false" to the
+ undefined_symbol callback when building shared library with
+ -Bsymbolic and undefined symbols are allowed. Otherwise, pass
+ "true".
+ * elf32-arm.h (elf32_arm_relocate_section): Likewise.
+ * elf32-i386.c (elf_i386_relocate_section): Likewise.
+ * elf32-m68k.c (elf_m68k_relocate_section): Likewise.
+ * elf32-mips.c (mips_elf_calculate_relocation): Likewise.
+ (elf32_mips_get_relocated_section_content): 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.
+
+2000-02-28 Nick Clifton <nickc@cygnus.com>
+
+ * Makefile.am: Add rules to build pe[i]-{sh|mips}.lo objects.
+ * Makefile.in: Regenerate.
+
+ * configure.in: Add support for mips and sh pe vectors.
+ * configure: regenerate.
+
+ * config.bfd: Add support for arm-wince, mips-pe and sh-pe
+ targets.
+
+ * targets.c: Add mips and sh pe vectors.
+
+ * libpei.h (coff_final_link_postscript): Only define if not
+ already defined.
+
+ * coffcode.h: Add support for WinCE magic numbers.
+
+ * peigen.c (pe_print_reloc): Update comment and rearrange
+ appending of newline character.
+
+ * peicode.h: Add support for Image Library Format.
+ (pe_ILF_vars): Structure containing data used by ILF code.
+ (pe_ILF_make_a_section): New function. Create a section based
+ on ILF data.
+ (pe_ILF_make_a_reloc): New function. Create a reloc based on
+ ILF data.
+ (pe_ILF_make_a_symbol): New function. Create a symbol based
+ on ILF data.
+ (pe_ILF_save_relocs): New function. Store the relocs created
+ by pe_ILF_make_a_reloc in a section.
+ (pe_ILF_build_a_bfd): New function. Create a BFD describing
+ an ILF object.
+ (pe_ILF_object_p): New function. Return a bfd_target pointer
+ for an ILF object.
+ (pe_bfd_object_p): If an ILF object is detected call
+ pe_ILF_object_p on it.
+
+ * coff-arm.c: Add support for WinCE relocs which are different
+ from normal ARM COFF relocs.
+ * pe-arm.c: Unset TARGET_UNDERSCORE for a WinCE target.
+
+ * coff-sh.c: Add support for sh-pe target.
+ * pe-sh.c: New file. Support code for sh-pe target.
+ * pei-sh.c: New file. Support code for sh-pe target.
+
+ * pe-mips.c: New file. Support code for mips-pe target.
+ * pei-mips.c: New file. Support code for mips-pe target.
+
+2000-02-27 Jakub Jelinek <jakub@redhat.com>
+
+ * elf32-sparc.c (elf32_sparc_merge_private_bfd_data): Don't bump
+ architecture if the object causing the bump is dynamic.
+ * elf64-sparc.c (sparc64_elf_merge_private_bfd_data): Likewise,
+ and also don't it for memory ordering.
+ (sparc64_elf_write_relocs): Take src_rela out of the loop.
+
+2000-02-27 Ian Lance Taylor <ian@zembu.com>
+
+ * dwarf2.c (read_abbrevs): Use _raw_size directly rather than
+ calling bfd_get_section_size_before_reloc.
+ (decode_line_info): Likewise.
+ (_bfd_dwarf2_find_nearest_line): Likewise.
+
+2000-02-27 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * Makefile.am (stamp-lib): Use $(LIBTOOL) --config to get the
+ name of the libtool directory.
+ * Makefile.in: Rebuild.
+
+2000-02-25 Rodney Brown (RodneyBrown@pmsc.com)
+
+ * som.c (SOM_HOWTO): Define.
+ (som_hppa_howto_table): Use it.
+
+2000-02-25 Alexandre Oliva <oliva@lsd.ic.unicamp.br>
+
+ * config.bfd: Enable 64 bit support for GNU/Linux/sparc.
+
+ * config.bfd: Enable 64 bit support for Solaris7+/sparc.
+
+2000-02-24 Catherine Moore <clm@cygnus.com>
+
+ * som.c (som_misc_symbol_info): Add field
+ secondary_def.
+ (som_bfd_derive_misc_symbol_info): Initialize
+ secondary_def.
+ (som_build_and_write_symbol_table): Keep track
+ of secondary_def field.
+ (som_slurp_symbol_table): Set BSF_WEAK symbol flag
+ if secondary_def field is set.
+ (som_bfd_ar_write_symbol_stuff): Initialize
+ secondary_def.
+
+2000-02-23 Stephane Carrez <stcarrez@worldnet.fr>
+
+ * dwarf2.c (read_address): Read 16-bits addresses.
+ (parse_comp_unit): Accept addr_size == 2.
+
+2000-02-23 Alan Modra <alan@spri.levels.unisa.edu.au>
+
+ * bfd-in.h: Update copyright date.
+
+2000-02-23 Linas Vepstas <linas@linas.org>
+
+ * cpu-i370.c: New file.
+ * elf32-i370.c: New file.
+ * archures.c (enum bfd_architecture): Add bfd_arch_i370.
+ (bfd_i370_arch): New.
+ (bfd_archures_list): Add bfd_i370_arch.
+ * elf.c (prep_headers): Add bfd_arch_i370.
+ * Makefile.am: Add support for IBM 370 elf.
+ * config.bfd: Likewise.
+ * configure.in: Likewise.
+ * libbfd.h (bfd_reloc_code_real_names): Likewise.
+ * reloc.c (bfd_reloc_code_type): Likewise.
+ * targets.c: Likewise.
+
+ * Makefile.in: Regenerate.
+ * configure: Regenerate.
+ * bfd-in2.h: Regenerate.
+
+2000-02-22 Ian Lance Taylor <ian@zembu.com>
+
+ * elf32-i386.c (elf_i386_info_to_howto_rel): Give a warning for
+ invalid relocation types, and change them to R_386_NONE.
+
+2000-02-22 H.J. Lu <hjl@gnu.org>
+
+ * elflink.h (elf_link_add_object_symbols): If a version symbol is
+ not defined, don't add a second ELF_VER_CHR.
+
+ * elflink.h (elf_bfd_final_link): Call output_extsym for global
+ symbols converted to local symbols even when stripping all
+ symbols.
+ (elf_link_output_extsym): Process global symbols converted to
+ local symbols even if they are being stripped.
+
+2000-02-21 Alan Modra <alan@spri.levels.unisa.edu.au>
+
+ * archures.c (bfd_octets_per_byte): Return unsigned int.
+ (bfd_arch_mach_octets_per_byte): Ditto.
+ * libbfd.c (bfd_read, bfd_seek): Quell signed vs. unsigned
+ comparison warning.
+ * section.c (bfd_get_section_size_before_reloc): Quell signed
+ vs. unsigned comparison warning.
+ (bfd_get_section_size_after_reloc): Same here. Fix parentheses too.
+ * trad-core.c (trad_unix_core_file_p): Correct 2000-01-27
+ change. What was I thinking?
+ * bfd-in2.h: Regenerate.
+
+ * elflink.h (elf_gc_sweep): Skip non-elf input bfds.
+ (elf_gc_sections): Same here.
+ (elf_gc_common_finalize_got_offsets): And here.
+
+2000-02-21 Ian Lance Taylor <ian@zembu.com>
+
+ ELF HPPA doesn't work at present; remove it until it does.
+ * config.bfd: Comment out setting targ_defvec to
+ bfd_elf32_hppa_vec.
+ * Makefile.am: Rebuild dependencies.
+ (BFD32_BACKENDS): Remove elf32-hppa.lo.
+ (BFD32_BACKENDS_CFILES): Remove elf32-hppa.c.
+ (SOURCE_HFILES): Remove elf32-hppa.h and hppa_stubs.h.
+ * Makefile.in: Rebuild.
+ * targets.c (bfd_target_vector): Comment out bfd_elf32_hppa_vec.
+
+2000-02-18 Geoff Keating <geoffk@cygnus.com>
+
+ * coffcode.h (coff_set_arch_mach_hook): Use free(), because there
+ is no bfd_free(). Revert bfd_free part of previous change.
+
+2000-02-18 Geoff Keating <geoffk@cygnus.com>
+
+ * coffcode.h (coff_set_arch_mach_hook): Don't use variable-size
+ arrays.
+ (coff_compute_section_file_positions): Use bfd_free to pair
+ bfd_malloc.
+ (coff_write_object_contents): Likewise.
+
+ * coff-rs6000.c (xcoff_howto_table_16): New variable.
+ (xcoff_rtype2howto): Handle 16-bit variants of 32-bit relocs.
+
+2000-02-18 Ulrich Drepper <drepper@cygnus.com>
+
+ * coff-rs6000.c (XCOFFARMAGBIG): New macro.
+ (xcoff_ar_file_hdr_big): New structure.
+ (SIZEOF_AR_FILE_HDR_BIG): New macro.
+ (xcoff_ar_hdr_big): New structure.
+ (SIZEOF_AR_HDR_BIG): New macro.
+ (xcoff_big_format_p): New macro.
+ (xcoff_ardata_big): New macro.
+ (arch_xhdr_big): New macro.
+ (xcoff_slurp_armap): Handle large archives.
+ (xcoff_archive_p): Detect large archives.
+ (xcoff_read_ar_hdr): Handle large archives.
+ (xcoff_openr_next_archived_file): Handle large archives.
+ (xcoff_generic_stat_arch_elt): Handle large archives.
+ (xcoff_write_armap_old): Rename from xcoff_write_armap.
+ (xcoff_write_armap_big): New function.
+ (xcoff_write_armap): New function, dispatch to _old or _big.
+ (xcoff_write_archive_contents_old): Rename from
+ xcoff_write_archive_contents.
+ (xcoff_write_archive_contents_big): New function.
+ (xcoff_write_archive_contents): New function, dispatch to _old or
+ _big.
+
+2000-02-18 Richard Henderson <rth@cygnus.com>
+
+ * elf-bfd.h (struct elf_link_hash_table): Remove copy_indirect
+ and hide_symbol members.
+ (elf_link_hash_copy_indirect): Remove.
+ (elf_link_hash_hide_symbol): Remove.
+ (struct elf_backend_data): Add elf_backend_copy_indirect_symbol
+ and elf_backend_hide_symbol.
+ (_bfd_elf_link_hash_copy_indirect): Declare.
+ (_bfd_elf_link_hash_hide_symbol): Declare.
+ * elf.c (_bfd_elf_link_hash_copy_indirect): Remove table argument.
+ (_bfd_elf_link_hash_hide_symbol): Likewise.
+ (_bfd_elf_link_hash_table_init): Don't init killed members.
+ * elflink.h (elf_link_add_object_symbols): Use the bed function
+ pointers not elf_link_hash_{copy_indirect,hide_symbol}.
+ (elf_link_assign_sym_version): Likewise.
+ * elfxx-target.h (elf_backend_copy_indirect_symbol): Default.
+ (elf_backend_hide_symbol): Likewise.
+ (elfNN_bed): Update for new members.
+
+2000-02-17 Kevin Buettner <kevinb@redhat.com>
+
+ * rs6000-core.c (CORE_DATA_SIZE_FIELD, CORE_COMM_FIELD, SAVE_FIELD,
+ STACK_END_ADDR): Define for new core file format.
+ (LOADER_OFFSET_FIELD, LOADER_REGION_SIZE, CORE_DUMP): New defines
+ for handling the vagaries of the various core file structures used
+ by AIX over the years.
+ (rs6000coff_core_p, rs6000coff_core_file_matches_executable,
+ Rs6kCorData): Use above defines to adapt code to use AIX 4.3's
+ core_dumpx structure.
+
+2000-02-17 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * archures.c (bfd_mach_sh2, bfd_mach_sh_dsp): New macros.
+ (bfd_mach_sh3_dsp): Likewise.
+ (bfd_mach_sh4): Reinstate.
+ (bfd_default_scan): Recognize 7410, 7708, 7729 and 7750.
+ * bfd-in2.h: Regenerate.
+ * coff-sh.c (struct sh_opcode): flags is no longer short.
+ (USESAS, USESAS_REG, USESR8, SETSAS, SETSAS_REG): New macros.
+ (sh_opcode41, sh_opcode42): Integrate as sh_opcode41.
+ (sh_opcode01, sh_opcode02, sh_opcode40): Add sh-dsp opcodes.
+ (sh_opcode41, sh_opcode4, sh_opcode80): Likewise.
+ (sh_opcodes): No longer const.
+ (sh_dsp_opcodef0, sh_dsp_opcodef): New arrays.
+ (sh_insn_uses_reg): Check for USESAS and USESR8.
+ (sh_insn_sets_reg, sh_insns_conflict): Check for SETSAS.
+ (_bfd_sh_align_load_span): Return early for SH4.
+ Modify sh_opcodes lookup table for sh-dsp / sh3-dsp.
+ Take into account that field b of a parallel processing insn
+ could be mistaken for a separate insn.
+ * cpu-sh.c (arch_info_struct): New array elements for
+ sh2, sh-dsp and sh3-dsp.
+ Reinstate element for sh4.
+ (SH2_NEXT, SH_DSP_NEXT, SH3_DSP_NEXT): New macros.
+ (SH4_NEXT): Reinstate.
+ (SH3_NEXT, SH3E_NEXT): Adjust.
+ * elf-bfd.h (_sh_elf_set_mach_from_flags): Declare.
+ * elf32-sh.c (sh_elf_set_private_flags): New function.
+ (sh_elf_copy_private_data, sh_elf_set_mach_from_flags): Likewise.
+ (sh_elf_merge_private_data): New function.
+ (elf_backend_object_p, bfd_elf32_bfd_set_private_bfd_flags): Define.
+ (bfd_elf32_bfd_copy_private_bfd_data): Define.
+ (bfd_elf32_bfd_merge_private_bfd_data): Change to
+ sh_elf_merge_private_data.
+
+2000-02-13 Richard Henderson <rth@cygnus.com>
+
+ * elf-bfd.h (struct elf_link_hash_table): Add copy_indirect and
+ hide_symbol members.
+ (elf_link_hash_copy_indirect): New.
+ (elf_link_hash_hide_symbol): New.
+ * elflink.h (elf_link_add_object_symbols): Break out copy from
+ indirect new new symbol to elf.c.
+ (elf_link_assign_sym_version): Break out privatization of
+ non-exported symbol to elf.c.
+ * elf.c (_bfd_elf_link_hash_copy_indirect): New.
+ (_bfd_elf_link_hash_hide_symbol): New.
+ (_bfd_elf_link_hash_table_init): Init copy_indirect and hide_symbol.
+
+2000-02-13 Ian Lance Taylor <ian@zembu.com>
+
+ * section.c (_bfd_strip_section_from_output): Add info parameter.
+ If it passed as non-NULL, use it to check whether any input BFD
+ has an input section which uses this output section. Change all
+ callers.
+ * bfd-in2.h: Rebuild.
+
+ * bfd-in.h: Move declarations of bfd_get_elf_phdr_upper_bound and
+ bfd_get_elf_phdrs in from bfd-in2.h, correcting patch of
+ 1999-11-29.
+ * bfd-in2.h: Rebuild.
+
+2000-02-10 Timothy Wall <twall@cygnus.com>
+
+ * coffswap.h (coff_swap_sym_in): Add hook SWAP_SYM_IN_POST to
+ allow final modifications of swapped-in symbol.
+ (coff_swap_sym_out): Ditto with SWAP_SYM_OUT_POST.
+ * coffcode.h (coff_write_relocs): Use macro
+ SECTION_RELATIVE_ABSOLUTE_SYMBOL_P if defined to determine whether
+ symbol index should be set to -1.
+
+2000-02-10 Toshiyasu Morita (toshi.morita@sega.com)
+
+ * coff-sh.c (USES1_REG, USES2_REG, SETS1_REG, SETS2_REG,
+ USESF1_REG, USESF2_REG, SETSF1_REG, SETSF2_REG): New macros.
+ * (sh_insn_sets_reg, sh_insn_sets_freg): New prototypes.
+ * (sh_insn_sets_reg, sh_insn_uses_or_sets_reg, sh_insns_sets_freg,
+ sh_insns_uses_or_sets_freg): New functions.
+ * (sh_insn_uses_reg, sh_insn_uses_freg): Use new macros.
+ * (sh_insns_conflict): Use new functions and new macros to
+ detect conflicts when two instructions both set same integer registers,
+ both set same fp register, and both set special register.
+
+2000-02-09 Timothy Wall <twall@cygnus.com>
+
+ * coffgen.c (coff_real_object_p): Set arch/mach info prior to
+ swapping in sections, so that the swapping routines have access to
+ the arch/mach info.
+
+2000-02-08 Mark Elbrecht <snowball3@bigfoot.com>
+
+ * coff-go32.c: Update comment. Update copyright.
+
+2000-01-27 Thomas de Lellis <tdel@windriver.com>
+
+ * syms.c (bfd_decode_symclass)
+ Two new class characters were added - 'V' and 'v'. The
+ meaning of 'W' is now restricted to just weak non-object
+ symbols. This allows differentiation between, for example,
+ weak functions vs weak objects. nm for example now dumps:
+ 'W' = weak global
+ 'w' = weak unresolved
+ 'V' = weak global object
+ 'v' = weak unresolved object
+
+ (bfd_is_undefined_symclass): New function. Return true if the
+ given symbol class represents and undefined/unresolved symbol.
+
+ (bfd_symbol_info): Use bfd_is_undefined_symclass to check for
+ unresolved symbols.
+
+ * bfd-in2.h: Add prototype for bfd_is_undefined_symbol().
+
+ * elf32-arm.h (elf32_arm_get_symbol_type): If a symbol has the
+ STT_ARM_16BIT flag set, but it is not attached to a data object
+ return STT_ARM_16BIT so that it will be treated as code by the
+ disassembler.
+
+2000-01-27 Alan Modra <alan@spri.levels.unisa.edu.au>
+
+ * coff-i386.c (i3coff_object_p): Remove prototype.
+ Update copyright.
+
+ * elflink.c (_bfd_elf_link_record_dynamic_symbol): Add const
+ to name. Update copyright.
+
+ * trad-core.c (trad_unix_core_file_p): Cast core_regsec
+ assignment to avoid warning. Update copyright.
+
+2000-01-24 Robert Lipe (robertl@sco.com)
+
+ * coffcode.h (coff_write_object_contents): Get buff via bfd_malloc
+ instead of using GNU C extension.
+
+2000-01-21 Nick Clifton <nickc@cygnus.com>
+
+ * libbfd.c (bfd_read): Do not attempt to get a negativly sized
+ amount from a bfd_in_memory structure.
+ (bfd_seek): Do not allow seeks past the end of a bfd_in_memory
+ structure.
+
+2000-01-14 Nick Clifton <nickc@cygnus.com>
+
+ * linker.c (default_indirect_link_order): oops - fix incorrectly
+ applied patch from Tim Wall.
+
+2000-01-13 Timothy Wall (twall@tiac.net>
+
+ * coffcode.h: Use bfd_coff_xxx instead of the macro XXX (where xxx
+ = scnhsz, filhsz, relsz, aoutsz, etc)
+
+ * coffswap.h: Ditto.
+
+2000-01-13 Nick Clifton <nickc@cygnus.com>
+
+ * elf32-arm.h (elf32_thumb_to_arm_stub): Fix offset in branch to
+ interwork thumb to arm stub.
+
+2000-01-13 Timothy Wall (twall@tiac.net>
+
+ * archures.c (bfd_octets_per_byte): New function: Return
+ target byte size.
+ (bfd_arch_mach_octets_per_byte): New function: Return target
+ byte size.
+
+ * section.c: Distinguish between octets and bytes for usage of
+ _cooked_size, _raw_size, and output_offset. Clarify
+ description of bfd_set_section_contents.
+
+ * bfd-in2.h: Regenerate.
+
+ * coffgen.c: Indicate that the offset parameter is in bytes, not
+ octets.
+
+ * cofflink.c (bfd_coff_link_input_bfd): Use bfd_octets_per_byte
+ where appropriate to get the octet offset when calling
+ bfd_set_section_contents.
+ (bfd_coff_reloc_link_order): Ditto.
+
+ * linker.c (bfd_generic_reloc_link_order): Ditto.
+ (_bfd_default_link_order): Ditto.
+
+ * reloc.c (bfd_perform_relocation): Distinguish between octets
+ and bytes. Use octets when indexing into octet data; use bytes
+ when calculating target addresses.
+ (bfd_install_relocation): Ditto.
+
+ * srec.c (srec_write_section): Ditto.
+
+2000-01-13 Nick Clifton <nickc@cygnus.com>
+
+ * coff-mcore.c (COFF_DEFAULT_SECTION_ALIGNMENT_POWER): Change from
+ 3 to 2. This allows 4 byte sized sections, which is necessary for
+ dlltool to build functioning DLLs.
+
+2000-01-10 Philip Blundell <pb@futuretv.com>
+
+ * config.bfd (arm*-*-linux-gnu*): Match instead of arm*-*-linux-gnu.
+ (arm*-*-conix*): New target.
+
+2000-01-10 Egor Duda <deo@logos-m.ru>
+
+ * config.bfd: Include elf32_i386 vector to target list for cygwin
+ and mingw.
+
+ * config.in: Undefine HAVE_WIN32_PSTATUS_T.
+ * configure.in: Test for structure win32_pstatus_t in
+ <sys/procfs.h>
+ * configure: Regenerate.
+
+ * elf.c (elfcore_grok_win32pstatus): New function: process
+ win32_pstatus_t notes in elf core file.
+ (elfcore_grok_note): Detect win32_pstatus notes.
+
+2000-01-03 Martin v. Loewis <loewis@informatik.hu-berlin.de>
+
+ * elflink.c (_bfd_elf_link_record_dynamic_symbol): Process symbol
+ visibility.
+ * elflink.h (elf_link_add_object_symbols): Combine visibilities.
+ * elf.c (bfd_elf_print_symbol): Interpret st_other as visibility.
+
+For older changes see ChangeLog-9899
+
+Copyright (C) 2002 Free Software Foundation, Inc.
+
+Copying and distribution of this file, with or without modification,
+are permitted in any medium without royalty provided the copyright
+notice and this notice are preserved.
+
+Local Variables:
+mode: change-log
+left-margin: 8
+fill-column: 74
+version-control: never
+End:
diff --git a/bfd/ChangeLog-0203 b/bfd/ChangeLog-0203
new file mode 100644
index 0000000..dc98795
--- /dev/null
+++ b/bfd/ChangeLog-0203
@@ -0,0 +1,11411 @@
+2003-12-19 Kazuhiro Inaoka <inaoka.kazuhiro@renesas.com>
+
+ Adfd m32r-linux and PIC support. Add new ABI that uses RELA.
+ * config.bfd (m32r*-*-linux*, m32r*le-*-linux*, m32r*le-*-*): Added.
+ * configure.in (bfd_elf32_m32rlin_vec, bfd_elf32_m32rlelin_vec,
+ bfd_elf32_m32rle_vec): Added
+ * configure: Regenerated.
+ * elf32-m32r.c (m32r_info_to_howto, m32r_elf_adjust_dynamic_symbol,
+ m32r_elf_size_dynamic_sections, m32r_elf_create_dynamic_sections,
+ m32r_elf_finish_dynamic_sections, m32r_elf_finish_dynamic_symbol,
+ allocate_dynrelocs, readonly_dynrelocs, m32r_elf_reloc_type_class,
+ m32r_elf_fake_sections): Added.
+ (m32r_elf_howto_table): Added
+ R_M32R_16_RELA, R_M32R_32_RELA, R_M32R_24_RELA,
+ R_M32R_10_PCREL_RELA, R_M32R_18_PCREL_RELA,
+ R_M32R_26_PCREL_RELA, R_M32R_HI16_ULO_RELA,
+ R_M32R_HI16_SLO_RELA, R_M32R_LO16_RELA,
+ R_M32R_SDA16_RELA, R_M32R_RELA_GNU_VTINHERIT,
+ R_M32R_RELA_GNU_VTENTRY, R_M32R_GOT24,
+ R_M32R_26_PLTREL, R_M32R_COPY, R_M32R_GLOB_DAT,
+ R_M32R_JMP_SLOT, R_M32R_RELATIVE, R_M32R_GOTOFF,
+ R_M32R_GOTPC24, R_M32R_GOT16_HI_ULO,
+ R_M32R_GOT16_HI_SLO, R_M32R_GOT16_LO,
+ R_M32R_GOTPC_HI_ULO, R_M32R_GOTPC_HI_SLO,
+ R_M32R_GOTPC_LO.
+ (m32r_elf_relocate_section, m32r_elf_check_relocs): Changed for
+ New ABI.
+ * reloc.c: Add BFD_RELOC_M32R_GOT24, BFD_RELOC_M32R_26_PLTREL,
+ BFD_RELOC_M32R_COPY, BFD_RELOC_M32R_GLOB_DAT,
+ BFD_RELOC_M32R_JMP_SLOT, BFD_RELOC_M32R_RELATIVE,
+ BFD_RELOC_M32R_GOTOFF, BFD_RELOC_M32R_GOTPC24,
+ BFD_RELOC_M32R_GOT16_HI_ULO, BFD_RELOC_M32R_GOT16_HI_SLO,
+ BFD_RELOC_M32R_GOT16_LO, BFD_RELOC_M32R_GOTPC_HI_ULO,
+ BFD_RELOC_M32R_GOTPC_HI_SLO, BFD_RELOC_M32R_GOTPC_LO.
+ * targets.c (bfd_elf32_m32rlin_vec, bfd_elf32_m32rlelin_vec,
+ bfd_elf32_m32rle_vec): Added.
+ * bfd-in2.h: Regenerated.
+ * libbfd.h: Regenerated.
+
+2003-12-19 Danny Smith <dannysmith@users.sourceforge.net>
+
+ * coffcode.h (styp_to_sec_flags): Don't treat .reloc section
+ as SEC_DEBUGGING.
+
+2003-12-18 Richard Sandiford <rsandifo@redhat.com>
+
+ * elf32-mips.c (elf_mips_howto_table_rel): Replace all uses of
+ mips_elf_generic_reloc with _bfd_mips_elf_generic_reloc. Use
+ _bfd_mips_elf_hi16_reloc for R_MIPS_HI16 and R_MIPS_GNU_REL_HI16,
+ _bfd_mips_elf_lo16_reloc for R_MIPS_LO16 and R_MIPS_GNU_REL_LO16,
+ and _bfd_mips_elf_got16_reloc for R_MIPS_GOT16. Change rightshift
+ to 16 for R_MIPS_HI16 and R_MIPS_GNU_REL_HI16.
+ (mips_elf_generic_reloc, struct mips_hi16, mips_elf_hi16_reloc)
+ (mips_elf_lo16_reloc, mips_elf_got16_reloc): Delete.
+ (_bfd_mips_elf32_gprel16_reloc): Remove special case.
+ (mips_elf_gprel32_reloc, mips32_64bit_reloc): Likewise.
+
+ * elf64-mips.c (mips_elf64_howto_table_rel): Replace all uses of
+ mips_elf_generic_reloc with _bfd_mips_elf_generic_reloc. Use
+ _bfd_mips_elf_hi16_reloc for R_MIPS_HI16, _bfd_mips_elf_lo16_reloc
+ for R_MIPS_LO16 and _bfd_mips_elf_got16_reloc for R_MIPS_GOT16.
+ Change R_MIPS_HI16's rightshift to 16.
+ (mips_elf64_howto_table_rela): Replace all uses of
+ mips_elf_generic_reloc with _bfd_mips_elf_generic_reloc.
+ Use _bfd_mips_elf_generic_reloc for R_MIPS_GOT16 as well.
+ (mips_elf64_hi16_reloc, mips_elf64_got16_reloc): Delete.
+ (mips_elf64_shift6_reloc): Remove special case. Use
+ _bfd_mips_elf_generic_reloc instead of returning bfd_reloc_continue.
+
+ * elfn32-mips.c (prev_reloc_section): Delete.
+ (prev_reloc_address, prev_reloc_addend): Delete.
+ (elf_mips_howto_table_rel, elf_mips_howto_table_rela): As for
+ elf64-mips.c
+ (GET_RELOC_ADDEND, SET_RELOC_ADDEND): Delete.
+ (mips_elf_generic_reloc, struct mips_hi16, mips_elf_hi16_reloc)
+ (mips_elf_lo16_reloc, mips_elf_got16_reloc): Delete.
+ (mips_elf_gprel16_reloc): Delete use of GET_RELOC_ADDEND.
+ (mips_elf_literal_reloc, mips_elf_gprel32_reloc): Likewise.
+ (mips16_jump_reloc, mips16_gprel_reloc): Likewise.
+ (mips_elf_shift6_reloc): Likewise. Delete use of SET_RELOC_ADDEND.
+
+ * elfxx-mips.c (_bfd_mips_elf_gprel16_with_gp): Use
+ _bfd_relocate_contents to install an in-place addend.
+ (mips_hi16): New structure.
+ (mips_hi16_list): Moved from elf32-mips.c.
+ (_bfd_mips_elf_hi16_reloc, _bfd_mips_elf_got16_reloc): New functions.
+ (_bfd_mips_elf_lo16_reloc, _bfd_mips_elf_generic_reloc): New functions.
+ (mips_elf_calculate_relocation): Assume addend is unshifted.
+ (_bfd_mips_elf_relocate_section): Don't apply the howto rightshift
+ on top of the usual high-part shift. Don't shift the addend right
+ before calling mips_elf_calculate_relocation.
+
+ * elfxx-mips.h (_bfd_mips_elf_hi16_reloc): Declare.
+ (_bfd_mips_elf_got16_reloc, _bfd_mips_elf_lo16_reloc): Declare.
+ (_bfd_mips_elf_generic_reloc): Declare.
+
+2003-12-16 Eric Youngdale <eric@mkssoftware.com>
+ Nick Clifton <nickc@redhat.com>
+
+ * peicode.h (pe_ILF_build_a_bfd): Only skip one instance of each
+ prefix character, if they are present.
+
+2003-12-15 Dmitry Semyonov <Dmitry.Semyonov@oktet.ru>
+ Nick Clifton <nickc@redhat.com>
+
+ * peXXigen.c (_bfd_XXi_swap_scnhdr_out): Ensure that correct flags
+ are set on known section types.
+
+2003-12-12 Nick Clifton <nickc@redhat.com>
+
+ * po/ro.po: Updated translation.
+
+2003-12-12 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-hppa.c (elf64_hppa_link_output_symbol_hook): Check for
+ NULL dyn_h.
+
+2003-12-11 Nick Clifton <nickc@redhat.com>
+
+ * elf.c (INCLUDE_SECTION_IN_SEGMENT): Skip PT_GNU_STACK segments.
+
+2003-12-08 Richard Sandiford <rsandifo@redhat.com>
+
+ * elfxx-mips.h, elfxx-mips.c, cpu-mips.c: Convert prototypes.
+ Remove casts that were only needed for K&R compatibility.
+
+2003-12-08 Alan Modra <amodra@bigpond.net.au>
+
+ * elf-bfd.h (struct elf_backend_data): Remove "bfd *" and add
+ "elflink_hash_entry *" param to elf_backend_link_output_symbol_hook.
+ Add "elflink_hash_entry *" param to elf_backend_output_arch_syms.
+ * elflink.h (elf_link_output_sym): Add "elflink_hash_entry *" param,
+ and pass to output_symbol_hook.
+ (elf_bfd_final_link): Adjust elf_link_output_sym calls.
+ (elf_link_output_extsym): Likewise.
+ (elf_link_input_bfd): Likewise.
+ * elf32-sh64.c (sh64_elf_link_output_symbol_hook): Adjust.
+ * elf32-v850.c (v850_elf_link_output_symbol_hook): Likewise.
+ * elf64-mmix.c (mmix_elf_link_output_symbol_hook): Likewise.
+ * elf64-sh64.c (sh64_elf64_link_output_symbol_hook): Likewise.
+ * elfxx-mips.c (_bfd_mips_elf_link_output_symbol_hook): Likewise.
+ * elfxx-mips.h (_bfd_mips_elf_link_output_symbol_hook): Likewise.
+ * elf64-sparc.c (sparc64_elf_output_arch_syms): Likewise.
+ * elf64-hppa.c (elf64_hppa_link_output_symbol_hook): Likewise.
+ Validate dynh->h against h.
+ * elf64-ppc.c (struct ppc_link_hash_entry): Add adjust_done bitfield.
+ (link_hash_newfunc): Init it.
+ (adjust_opd_syms): New function.
+ (ppc64_elf_edit_opd): Set adjust_done when global .opd sym adjusted.
+ Set opd.adjust for all .opd relocs. Call adjust_opd_syms.
+ (ppc64_elf_tls_optimize): Adjust possible .opd sym values here.
+ (ppc64_elf_relocate_section): Also adjust syms not a multiple of 24.
+ (ppc64_elf_output_symbol_hook): New function.
+ (elf_backend_link_output_symbol_hook): Define.
+
+2003-12-07 Richard Sandiford <rsandifo@redhat.com>
+
+ * elf32-mips.c, elfn32-mips.c, elf64-mips.c: Convert prototypes.
+ Remove casts that were only needed for K&R compatibility.
+
+2003-12-05 Dmitry Semyonov <Dmitry.Semyonov@oktet.ru>
+
+ * coff-arm.c (aoutarm_std_reloc_howto [ARM_WINCE]): Set
+ partial_inplace for these relocs to FALSE for comptability with
+ the MS linker.
+ Remap ARM_26D relocation from 5 to 0. This fixes "bad fixup" error
+ generated by MS linker, and brings the relocation in line the MS
+ PE documentation.
+
+2003-12-04 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf32-ppc.c (ppc_elf_relax_section): Don't check relax_finalizing.
+
+2003-12-04 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elfxx-ia64.c (elfNN_ia64_relax_section): Use the
+ need_relax_finalize field in link_info instead of
+ relax_finalizing to check if the relax finalize pass is being
+ done.
+
+2003-12-04 Dmitry Semyonov <Dmitry.Semyonov@oktet.ru>
+
+ * coff-arm.c (coff_arm_relocate_section, bfd_arm_process_before_allocation):
+ Change ARM26* to ARM_26* in comments to match definitions.
+ (coff_arm_adjust_symndx): Replace hard-coded constants with
+ appropriate definitions (ARM_26*).
+
+2003-12-04 Alan Modra <amodra@bigpond.net.au>
+
+ * coff-i860.c (coff_i860_reloc_nyi): Return bfd_reloc_not_supported.
+ * elf-m10300.c (elf32_mn10300_finish_hash_table_entry): Warning fixes.
+ (mn10300_elf_relax_section): Likewise.
+ * nlm32-alpha.c (ONES): Define.
+ (nlm32_alpha_howto_table): Use it to avoid warnings.
+
+2003-12-04 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-i386.c (elf_i386_object_p): Delete.
+ (elf_backend_object_p): Don't define.
+ * elf32-s390.c (elf_s390_object_p): No need to alloc tdata here.
+ * elf32-sh.c (sh_elf_object_p): Likewise.
+ * elf32-sparc.c (elf32_sparc_object_p): Likewise.
+ * elf64-alpha.c (elf64_alpha_object_p): Likewise.
+ * elf64-s390.c (elf_s390_object_p): Likewise.
+ * elf64-x86-64.c (elf64_x86_64_elf_object_p): Likewise.
+
+2003-12-03 Kazuhiro Inaoka <inaoka.kazuhiro@renesas.com>
+
+ * archures.c (bfd_mach_m32r2): Add new machine type.
+ * bfd-in2.h: Regenerate.
+ * cpu-m32r.c : Add new machine type.
+ * elf32-m32r.c (m32r_elf_object_p, m32r_elf_final_write_processing,
+ m32r_elf_merge_private_bfd_data): Add support for new machine
+ type.
+
+2003-12-03 Dave Airlie <airlied@linux.ie>
+
+ * config.bfd: Add vax-linux-gnu target.
+ * configure.in: Likewise.
+ * configure: Regenerate.
+
+2003-12-03 Alan Modra <amodra@bigpond.net.au>
+
+ * ecoff.c (ecoff_link_add_archive_symbols): Update for renamed
+ bfd_link_hash_entry field "next" -> "und_next".
+ * linker.c (_bfd_link_hash_newfunc): Likewise.
+ (bfd_link_add_undef): Likewise.
+ (_bfd_generic_link_add_archive_symbols): Likewise.
+ (_bfd_generic_link_add_one_symbol): Likewise.
+ * xcofflink.c (xcoff_link_add_symbols): Likewise.
+
+2003-12-02 Nick Clifton <nickc@redhat.com>
+
+ * configure.in (ALL_LINGUAS): Add ro.
+ * po/ro.po: New Romanian translation.
+
+2003-12-02 Alan Modra <amodra@bigpond.net.au>
+
+ * Makefile.am: Run "make dep-am".
+ * Makefile.in: Regenerate.
+
+2003-12-01 Dmitry Semyonov <Dmitry.Semyonov@oktet.ru>
+
+ * coffcode.h (coff_compute_section_file_positions): Set page_size
+ to 1 instead of 0 in the case file alignment value is zero.
+
+2003-12-01 Kazu Hirata <kazu@cs.umass.edu>
+
+ * coff-rs6000.c: Remove ARGSUSED and VARARGS.
+ * coff64-rs6000.c: Likewise.
+ * coffcode.h: Likewise.
+ * elf32-vax.c: Likewise.
+ * hash.c: Likewise.
+ * hppabsd-core.c: Likewise.
+ * hpux-core.c: Likewise.
+ * ihex.c: Likewise.
+ * netbsd-core.c: Likewise.
+ * osf-core.c: Likewise.
+ * pdp11.c: Likewise.
+ * ptrace-core.c: Likewise.
+ * sco5-core.c: Likewise.
+ * section.c: Likewise.
+ * sunos.c: Likewise.
+ * trad-core.c: Likewise.
+
+2003-12-01 Alan Modra <amodra@bigpond.net.au>
+
+ * elf-bfd.h (is_elf_hash_table): Take hash tab rather than info arg.
+ * elf.c (_bfd_elf_merge_sections): Adjust to suit.
+ (_bfd_elf_link_just_syms): Likewise.
+ (bfd_elf_get_needed_list): Likewise.
+ (bfd_elf_get_runpath_list): Likewise.
+ (_bfd_elf_link_hash_copy_indirect): Remove unneeded parens.
+ * elf32-hppa.c (elf32_hppa_setup_section_lists): Don't check hash tab
+ creator flavour.
+ (elf32_hppa_set_gp): Look up output sections rather than using htab.
+ * elf32-i960.c: Comment fix. Formatting.
+ * elf32-m32r.c (m32r_elf_add_symbol_hook): Use is_elf_hash_table
+ rather than testing creator flavour.
+ * elf32-sh64.c (sh64_elf_add_symbol_hook): Likewise.
+ * elf64-sh64.c (sh64_elf64_add_symbol_hook): Likewise.
+ * elflink.c (_bfd_elf_link_create_dynamic_sections): Adjust for
+ is_elf_hash_table change. Remove redundant test.
+ (bfd_elf_record_link_assignment): Use is_elf_hash_table rather than
+ testing creator flavour.
+ (elf_link_record_local_dynamic_symbol): Adjust for is_elf_hash_table.
+ (_bfd_elf_fix_symbol_flags): Likewise.
+ (_bfd_elf_adjust_dynamic_symbol): Likewise.
+ * elflink.h (elf_link_add_object_symbols): Likewise. Remove redundant
+ checks. Use is_elf_hash_table rather than testing creator flavour.
+ Use hash_table throughout in place of info->hash.
+ (elf_add_dynamic_entry): Adjust for is_elf_hash_table change.
+ (NAME(bfd_elf,size_dynamic_sections)): Likewise. Remove redundant
+ check.
+ (elf_bfd_final_link): Adjust for is_elf_hash_table change.
+ (elf_link_check_versioned_symbol): Use is_elf_hash_table rather than
+ testing creator flavour.
+ (elf_gc_sections): Add is_elf_hash_table check.
+ (elf_gc_common_finalize_got_offsets): Likewise.
+ (elf_bfd_discard_info): Adjust for is_elf_hash_table change. Remove
+ redundant check.
+ * elfxx-ia64.c (elfNN_ia64_relax_section): Use is_elf_hash_table
+ rather than testing creator flavour.
+
+2003-11-28 Christian Groessler <chris@groessler.org>
+
+ * cpu-z8k.c: Convert to ISO C90.
+ * coff-z8k.c: Likewise.
+
+2003-11-27 Alexandre Oliva <aoliva@redhat.com>
+
+ * elf-bfd.h (elf_backend_data::elf_backend_modify_segment_map):
+ Add link info argument.
+ * elf32-i370.c (elf_backend_modify_segment_map): Likewise.
+ * elf32-ppc.c (ppc_elf_modify_segment_map): Likewise.
+ * elf32-xtensa.c (elf_xtensa_modify_segment_map): Likewise.
+ * elf64-hppa.c (elf64_hppa_modify_segment_map): Likewise.
+ * elfxx-ia64.c (elfNN_ia64_modify_segment_map): Likewise.
+ * elfxx-mips.c (_bfd_mips_elf_modify_segment_map): Likewise.
+ * elfxx-mips.h (_bfd_mips_elf_modify_segment_map): Likewise.
+ * elf.c (assign_file_positions_except_relocs,
+ assign_file_positions_for_segments): Likewise. Adjust calls.
+
+2003-11-27 Mark Kettenis <kettenis@gnu.org>
+
+ * elf.c (elfcore_grok_netbsd_procinfo): Make a pseudosection out
+ of the note.
+
+2003-11-26 Daniel Jacobowitz <drow@mvista.com>
+ Richard Sandiford <rsandifo@redhat.com>
+
+ * elfxx-mips.c (mips_elf_set_global_got_offset): Don't set no_fn_stub.
+ (mips_elf_set_no_stub): New function.
+ (mips_elf_multi_got): Call it.
+ (_bfd_mips_elf_finish_dynamic_symbol): If a relocation is needed for
+ a secondary GOT entry, create an R_MIPS_32 or R_MIPS_64 relocation and
+ use mips_elf_create_dynamic_relocation to deal with any compatibility
+ issues. Store the adjusted addend in the GOT slot.
+
+2003-11-25 Mattias Engdegård <mattias@virtutech.se>
+
+ * stabs.c (_bfd_link_section_stabs): Skip N_EXCL stabs when
+ procesing N_BINCL stabs.
+
+2003-11-25 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (ppc_type_of_stub): Disallow stubs other than
+ ppc_stub_plt_call to symbols defined in shared libs.
+
+2003-11-22 Jakub Jelinek <jakub@redhat.com>
+
+ * elf-bfd.h (ELF_LINK_POINTER_EQUALITY_NEEDED): Define new flag.
+ * elf.c (_bfd_elf_link_hash_copy_indirect): Copy it.
+ * elf32-i386.c (elf_i386_copy_indirect_symbol): Likewise.
+ (elf_i386_check_relocs): Set it.
+ (elf_i386_finish_dynamic_symbol): If it is not set,
+ clear st_value of SHN_UNDEF symbol.
+
+2003-11-20 Jim Blandy <jimb@redhat.com>
+
+ * cpu-powerpc.c (powerpc_compatible): Any ISA in the PowerPC
+ family is a superset of <bfd_arch_rs6000,bfd_mach_rs6k>.
+
+2003-11-20 Martin Schwidefsky <schwidefsky@de.ibm.com>
+
+ * elf32-s390.c (elf_s390_relocate_section): Don't recalculate symbol
+ section for reloc output and subtract the output section's address
+ from the addend when converting a relocation into one against a
+ section symbol.
+ * elf64-s390.c (elf_s390_relocate_section): Likewise.
+
+2003-11-18 James E Wilson <wilson@specifixinc.com>
+
+ * elfxx-ia64.c (get_fptr): For fptr_rel, use dynobj not abfd.
+ (elfNN_ia64_size_dynamic_sections): When stripping sections, check
+ for ia64_info->rel_fptr_sec.
+
+2003-11-18 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (toc_adjusting_stub_needed): Exit early if section
+ size is zero.
+
+2003-11-17 Daniel Jacobowitz <drow@mvista.com>
+
+ * elf.c (_bfd_elf_link_hash_copy_indirect): Copy
+ ELF_LINK_HASH_NEEDS_PLT. Fix formatting.
+ * elf32-hppa.c (elf32_hppa_copy_indirect_symbol): Likewise.
+ * elf32-i386.c (elf_i386_copy_indirect_symbol): Likewise.
+ * elf32-ppc.c (ppc_elf_copy_indirect_symbol): Likewise.
+ * elf32-s390.c (elf_s390_copy_indirect_symbol): Likewise.
+ * elf32-sh.c (sh_elf_copy_indirect_symbol): Likewise.
+ * elf64-ppc.c (ppc64_elf_copy_indirect_symbol): Likewise.
+ * elf64-s390.c (elf_s390_copy_indirect_symbol): Likewise.
+ * elf64-x86-64.c (elf64_x86_64_copy_indirect_symbol): Likewise.
+ * elfxx-ia64.c (elfNN_ia64_hash_copy_indirect): Likewise.
+ * elf32-xtensa.c (elf_xtensa_copy_indirect_symbol): Remove.
+ (elf_backend_copy_indirect_symbol): Don't define.
+
+2003-11-14 Daniel Jacobowitz <drow@mvista.com>
+
+ * elfxx-mips.c (mips_elf_merge_gots): Weaken assert for local
+ GOT entries.
+
+2003-11-13 Martin Schwidefsky <schwidefsky@de.ibm.com>
+
+ * elf32-s390.c (elf_s390_relocate_section): Only convert R_390_32
+ to R_390_RELATIVE. Convert the other relocations against local
+ symbols to relocations against the start of the section.
+ * elf64-s390.c (elf_s390_relocate_section): Only convert R_390_64
+ to R_390_RELATIVE. Convert the other relocations against local
+ symbols to relocations against the start of the section.
+
+2003-11-11 Nick Clifton <nickc@redhat.com>
+
+ * elf-m10300.c (bfd_mn10300_elf_size_dynamic_sections): Use
+ info->executable not info->shared to decide if a .interp section
+ should be present.
+ * elf32-arm.h (elf32_arm_size_dynamic_sections): Likewise.
+ * elf32-cris.c (elf_cris_size_dynamic_sections): Likewise.
+ * elf32-hppa.c (elf32_hppa_size_dynamic_sections): Likewise.
+ * elf32-i370.c (i370_elf_size_dynamic_sections): Likewise.
+ * elf32-m68k.c (elf_m68k_size_dynamic_sections): Likewise.
+ * elf32-vax.c (elf_vax_size_dynamic_sections): Likewise.
+ * elf32-xtensa.c (elf_xtensa_size_dynamic_sections): Likewise.
+ * elf64-hppa.c (elf64_hppa_size_dynamic_sections): Likewise.
+ * elfxx-mips.c (_bfd_mips_size_dynamic_sections): Likewise.
+ * elflink.h (size_dynamic_sections): Likewise.
+
+2003-11-10 Jonathan Wilson <jonwil@tpgi.com.au>
+
+ * peXXigen.c (_bfd_XXi_swap_aouthdr_out): Swap out tls pointer.
+ (_bfd_XXi_final_link_postscript): Look for __tks_used symbol. If
+ found initialise the tls data directory entry.
+
+2003-11-07 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-ppc.c (ppc_elf_install_value): Delete.
+ (shared_stub_entry, stub_entry): Make them arrays of ints.
+ Remove initial branch.
+ (ppc_elf_relax_section): Write one branch around all trampolines
+ instead. Correct bogus R_PPC_PLTREL24 handling. Correct
+ branch range check. Only use shared_stub_entry when shared.
+ Test that branches can reach stubs. Write trampolines out at
+ end so that just one realloc is used. Handle little-endian
+ mode. Move relevant code from ppc_elf_install_value to here.
+ (ppc_elf_relocate_section): Move code handling RELAX32 from
+ ppc_elf_install_value to here.
+
+2003-11-06 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-ppc.c (ppc_elf_howto_raw); Add entry for R_PPC_RELAX32PC.
+ (ppc_elf_install_value): Handle R_PPC_RELAX32PC. Merge duplicate
+ cases.
+ (shared_stub_entry): Correct opcode.
+ (ppc_elf_relax_section): Generate R_PPC_RELAX32PC relocs.
+ (ppc_elf_relocate_section): Handle them.
+
+2003-11-05 Alan Modra <amodra@bigpond.net.au>
+
+ * elf.c (_bfd_elf_rela_local_sym): Accept asection **, and return
+ updated section in case of merged section.
+ * elf-bfd.h (_bfd_elf_rela_local_sym): Update declaration.
+ * elf-hppa.h (elf_hppa_relocate_section): Adjust call.
+ * elf-m10200.c (mn10200_elf_relocate_section): Likewise.
+ * elf-m10300.c (mn10300_elf_relocate_section): Likewise.
+ * elf32-arm.h (elf32_arm_relocate_section): Likewise.
+ * elf32-avr.c (elf32_avr_relocate_section): Likewise.
+ * elf32-cris.c (cris_elf_relocate_section): Likewise.
+ * elf32-fr30.c (fr30_elf_relocate_section): Likewise.
+ * elf32-frv.c (elf32_frv_relocate_section): Likewise.
+ * elf32-h8300.c (elf32_h8_relocate_section): Likewise.
+ * elf32-hppa.c (elf32_hppa_relocate_section): Likewise.
+ * elf32-i370.c (i370_elf_relocate_section): Likewise.
+ * elf32-i860.c (elf32_i860_relocate_section): Likewise.
+ * elf32-m32r.c (m32r_elf_relocate_section): Likewise.
+ * elf32-m68k.c (elf_m68k_relocate_section): Likewise.
+ * elf32-mcore.c (mcore_elf_relocate_section): Likewise.
+ * elf32-msp430.c (elf32_msp430_relocate_section): Likewise.
+ * elf32-openrisc.c (openrisc_elf_relocate_section): Likewise.
+ * elf32-ppc.c (ppc_elf_relocate_section): Likewise.
+ * elf32-s390.c (elf_s390_relocate_section): Likewise.
+ * elf32-sh.c (sh_elf_relocate_section): Likewise.
+ * elf32-sparc.c (elf32_sparc_relocate_section): Likewise.
+ * elf32-v850.c (v850_elf_relocate_section) Likewise.
+ * elf32-vax.c (elf_vax_relocate_section): Likewise.
+ * elf32-xstormy16.c (xstormy16_elf_relocate_section): Likewise.
+ * elf32-xtensa.c (elf_xtensa_relocate_section): Likewise.
+ * elf64-alpha.c (elf64_alpha_relocate_section): Likewise.
+ * elf64-mmix.c (mmix_elf_relocate_section): Likewise.
+ * elf64-ppc.c (ppc64_elf_relocate_section): Likewise.
+ * elf64-s390.c (elf_s390_relocate_section): Likewise.
+ * elf64-sh64.c (sh_elf64_relocate_section): Likewise.
+ * elf64-sparc.c (sparc64_elf_relocate_section): Likewise.
+ * elf64-x86-64.c (elf64_x86_64_relocate_section): Likewise.
+ * elfxx-ia64.c (elfNN_ia64_relocate_section): Likewise.
+
+ * elf32-cris.c (cris_elf_relocate_section): Don't recalculate symbol
+ section for reloc output.
+ * elf32-i370.c (i370_elf_relocate_section): Likewise.
+ * elf32-m68k.c (elf_m68k_relocate_section): Likewise.
+ * elf32-sparc.c (elf32_sparc_relocate_section): Likewise.
+ * elf32-vax.c (elf_vax_relocate_section): Likewise.
+ * elf64-sparc.c (sparc64_elf_relocate_section): Likewise.
+ * elf64-x86-64.c (elf64_x86_64_relocate_section): Likewise.
+
+ * elf32-ppc.c (ppc_elf_relocate_section): Don't recalculate everything
+ for R_PPC_RELAX32 reloc. Don't bother checking ppc_elf_install_value
+ return value.
+ * elf64-ppc.c (ppc64_elf_relocate_section <R_PPC64_TOC>): Sanity check
+ sec->id.
+
+2003-11-05 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-d10v.c (extract_rel_addend, insert_rel_addend): New functions.
+ (elf32_d10v_relocate_section): Use them to handle -r reloc
+ adjustments, and in place of _bfd_elf_rela_local_sym.
+
+ * cpu-iq2000.c (arch_info_struct): Warning fix.
+
+2003-11-05 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-hppa.c (ELIMINATE_COPY_RELOCS): Define.
+ (elf32_hppa_copy_indirect_symbol): Don't copy NON_GOT_REF on
+ weakdefs.
+ (elf32_hppa_check_relocs): Use ELIMINATE_COPY_RELOCS.
+ (elf32_hppa_adjust_dynamic_symbol): Likewise. Copy weakdef
+ NON_GOT_REF.
+ (allocate_dynrelocs): Use ELIMINATE_COPY_RELOCS and
+ SYMBOL_CALLS_LOCAL. Discard relocs for undef weak syms with
+ non-default visibility.
+ (elf32_hppa_relocate_section): Use ELIMINATE_COPY_RELOCS and
+ SYMBOL_CALLS_LOCAL.
+
+2003-11-04 Alan Modra <amodra@bigpond.net.au>
+
+ * aout-target.h, aoutf1.h, bfdio.c, bfdwin.c: Update copyright date.
+ * coff-apollo.c, coff-sparc.c, coff-w65.c, coff-we32k.c: Ditto.
+ * coff-z8k.c, coffgen.c, cpu-frv.c, cpu-h8500.c, cpu-hppa.c: Ditto.
+ * cpu-ia64-opc.c, cpu-m10300.c, cpu-mips.c, cpu-msp430.c: Ditto.
+ * cpu-rs6000.c, cpu-z8k.c, efi-app-ia32.c, elf32-am33lin.c: Ditto.
+ * gen-aout.c, hash.c, hp300hpux.c, init.c, mach-o.c: Ditto.
+ * nlm-target.h, nlm.c, som.h, stabs.c, sysdep.h, xsym.h: Ditto.
+
+ * elf-m10300.c (_bfd_mn10300_elf_create_got_section): Fix
+ "dereferencing type-punned pointer" warnings.
+
+ * aout-adobe.c (aout_adobe_set_section_contents): Constify location.
+ * aoutx.h (NAME(aout,set_section_contents)): Ditto.
+ * bfd-in2.h: Regenerate.
+ * binary.c (binary_set_section_contents): Ditto.
+ * bout.c (b_out_set_section_contents): Ditto.
+ * coff-tic54x.c (tic54x_set_section_contents): Ditto.
+ * coffcode.h (coff_set_section_contents): Ditto.
+ * ecoff.c (_bfd_ecoff_set_section_contents): Ditto.
+ * elf-bfd.h (_bfd_elf_set_section_contents): Ditto.
+ * elf.c (_bfd_elf_set_section_contents): Ditto.
+ * elfxx-mips.c (_bfd_mips_elf_set_section_contents): Ditto.
+ * elfxx-mips.h (_bfd_mips_elf_set_section_contents): Ditto.
+ * i386msdos.c (msdos_set_section_contents): Ditto.
+ * ieee.c (ieee_set_section_contents): Ditto.
+ * ihex.c (ihex_set_section_contents): Ditto.
+ * libaout.h (NAME(aout,set_section_contents)): Ditto.
+ * libbfd-in.h (_bfd_nowrite_set_section_contents): Ditto.
+ (_bfd_generic_set_section_contents): Ditto.
+ * libbfd.h: Regenerate.
+ * libbfd.c (_bfd_generic_set_section_contents): Ditto.
+ * libecoff.h (_bfd_ecoff_set_section_contents): Ditto.
+ * libnlm.h (nlmNAME(set_section_contents)): Ditto.
+ (struct nlm_backend_data <nlm_mangle_relocs>): Ditto.
+ * mmo.c (mmo_set_section_contents): Ditto.
+ * nlm32-alpha.c (nlm_alpha_mangle_relocs): Ditto.
+ * nlm32-i386.c (nlm_i386_mangle_relocs): Ditto.
+ * nlm32-ppc.c (nlm_powerpc_mangle_relocs): Ditto.
+ * nlm32-sparc.c (nlm_sparc_mangle_relocs): Ditto.
+ * nlmcode.h (nlm_set_section_contents): Ditto.
+ * oasys.c (oasys_set_section_contents): Ditto.
+ * pdp11.c (NAME(aout,set_section_contents)): Ditto.
+ * ppcboot.c (ppcboot_set_section_contents): Ditto.
+ * srec.c (srec_set_section_contents): Ditto.
+ * targets.c (BFD_JUMP_TABLE_WRITE <_bfd_set_section_contents>): Ditto.
+ * tekhex.c (tekhex_set_section_contents): Ditto.
+ (move_section_contents): Ditto.
+ * versados.c (versados_set_section_contents): Ditto.
+ * vms-misc.c (_bfd_save_vms_section): Ditto.
+ * vms.c (vms_set_section_contents): Ditto.
+ * vms.h (_bfd_save_vms_section): Ditto.
+
+2003-11-04 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (ppc_size_one_stub): Size relbrlt. Accept info arg
+ rather than htab.
+ (ppc64_elf_size_stubs): Adjust ppc_size_one_stub traversal. Zero
+ relbrlt size.
+ (ppc64_elf_build_stubs): Allocate space for relbrlt.
+
+2003-11-04 Alan Modra <amodra@bigpond.net.au>
+
+ * bfd-in.h (_bfd_elf_tls_setup): Declare.
+ * bfd-in2.h: Regenerate.
+ * elf-bfd.h (struct elf_link_tls_segment): Delete.
+ (struct elf_link_hash_table): Add tls_sec and tls_size.
+ * elf.c (_bfd_elf_link_hash_table_init): Init tls_sec and tls_size.
+ * elflink.c (_bfd_elf_tls_setup): New function.
+ * elflink.h (struct elf_final_link_info): Remove first_tls_sec.
+ (elf_bfd_final_link): Don't set first_tls_sec here. Update code
+ saving tls segment info, round segment size up.
+ (elf_link_output_extsym): Adjust code using tls segment info.
+ (elf_link_input_bfd): Likewise.
+ * elf32-i386.c (dtpoff_base, tpoff): Likewise.
+ * elf32-s390.c (dtpoff_base, tpoff): Likewise.
+ * elf32-sh.c (dtpoff_base, tpoff): Likewise.
+ * elf32-sparc.c (dtpoff_base, tpoff): Likewise.
+ * elf64-s390.c (dtpoff_base, tpoff): Likewise.
+ * elf64-x86-64.c (dtpoff_base, tpoff): Likewise.
+ * elfxx-ia64.c (elfNN_ia64_tprel_base): Likewise.
+ (elfNN_ia64_dtprel_base): Likewise.
+ * elf64-alpha.c (alpha_get_dtprel_base): Likewise.
+ (alpha_get_tprel_base): Likewise.
+ (struct alpha_relax_info): Remove tls_segment.
+ (elf64_alpha_relax_got_load): Adjust invocation of
+ alpha_get_dtprel_base and alpha_get_tprel_base.
+ (elf64_alpha_relax_tls_get_addr): Likewise.
+ (elf64_alpha_relax_section): Likewise.
+ (elf64_alpha_relocate_section): Likewise.
+ (elf64_alpha_relax_find_tls_segment): Delete.
+ * elf32-ppc.c (struct ppc_elf_link_hash_table): Remove tls_sec.
+ (ppc_elf_tls_setup): Call _bfd_elf_tls_setup. Return section.
+ (ppc_elf_relocate_section): Adjust to use elf.tls_sec.
+ * elf32-ppc.h (ppc_elf_tls_setup): Update.
+ * elf64-ppc.c (struct ppc_link_hash_table): Remove tls_sec.
+ (ppc64_elf_tls_setup): Call _bfd_elf_tls_setup. Return section.
+ (ppc64_elf_tls_optimize): Adjust to use elf.tls_sec.
+ (ppc64_elf_relocate_section): Likewise.
+ * elf64-ppc.h (ppc64_elf_tls_setup): Update.
+
+2003-11-03 Daniel Jacobowitz <drow@mvista.com>
+
+ * elf-bfd.h (struct elf_backend_data): Remove plt_header_size.
+ * elf-m10300.c (elf_backend_plt_header_size): Don't define.
+ * elf32-arm.h (elf_backend_plt_header_size): Don't define.
+ * elf32-cris.c (elf_backend_plt_header_size): Don't define.
+ * elf32-i386.c (elf_backend_plt_header_size): Don't define.
+ * elf32-mips.c (elf_backend_plt_header_size): Don't define.
+ * elf32-ppc.c (elf_backend_plt_header_size): Don't define.
+ * elf32-s390.c (elf_backend_plt_header_size): Don't define.
+ * elf32-sh.c (elf_backend_plt_header_size): Don't define.
+ * elf32-sparc.c (elf_backend_plt_header_size): Don't define.
+ * elf64-alpha.c (elf_backend_plt_header_size): Don't define.
+ * elf64-hppa.c (elf_backend_plt_header_size): Don't define.
+ * elf64-mips.c (elf_backend_plt_header_size): Don't define.
+ * elf64-ppc.c (elf_backend_plt_header_size): Don't define.
+ * elf64-s390.c (elf_backend_plt_header_size): Don't define.
+ * elf64-sh64.c (elf_backend_plt_header_size): Don't define.
+ * elf64-sparc.c (elf_backend_plt_header_size): Don't define.
+ * elf64-x86-64.c (elf_backend_plt_header_size): Don't define.
+ * elfn32-mips.c (elf_backend_plt_header_size): Don't define.
+ * elfxx-ia64.c (elf_backend_plt_header_size): Don't define.
+ * elfxx-target.h (elf_backend_plt_header_size): Don't define
+ or include in target initializer.
+
+2003-11-03 Andrew Cagney <cagney@redhat.com>
+
+ * section.c (bfd_set_section_contents): Make the "location" buffer
+ constant.
+ * bfd-in2.h: Re-generate.
+
+2003-10-30 Andrew Cagney <cagney@redhat.com>
+
+ * syms.c: Replace "struct symbol_cache_entry" with "struct
+ bfd_symbol".
+ * vms.h, targets.c, section.c, reloc.c, peicode.h: Ditto.
+ * mipsbsd.c, elf.c, linker.c, elf-bfd.h, ecoff.c: Ditto.
+ * cpu-z8k.c, cpu-ns32k.c, cpu-h8500.c, bfd.c, bfd-in.h: Ditto.
+ * bfd-in2.h: Re-generate.
+
+2003-10-30 Jakub Jelinek <jakub@redhat.com>
+
+ * elfxx-ia64.c: Include objalloc.h, hashtab.h.
+ (struct elfNN_ia64_local_hash_entry): Remove root. Add id and r_sym
+ fields.
+ (struct elfNN_ia64_local_hash_table): Remove.
+ (struct elfNN_ia64_link_hash_table): Change loc_hash_table's type
+ to htab_t. Add loc_hash_memory field.
+ (elfNN_ia64_local_hash_table_init, elfNN_ia64_new_loc_hash_entry):
+ Removed.
+ (elfNN_ia64_local_htab_hash, elfNN_ia64_local_htab_eq): New
+ functions.
+ (elfNN_ia64_hash_table_create): Use hashtab.h hashtable for
+ loc_hash_table. Initialize loc_hash_memory.
+ (elfNN_ia64_hash_table_free): New function.
+ (elfNN_ia64_local_hash_lookup): Remove.
+ (elfNN_ia64_local_dyn_sym_thunk): Change into htab_traverse
+ callback.
+ (elfNN_ia64_dyn_sym_traverse): Use htab_traverse.
+ (get_local_sym_hash): Use hashtab.h hashtable for loc_hash_table.
+ (bfd_elfNN_bfd_link_hash_table_free): Define.
+
+2003-10-30 Alan Modra <amodra@bigpond.net.au>
+
+ * elflink.c (_bfd_elf_link_record_dynamic_symbol): Modify versioned
+ symbol string in place.
+
+2003-10-30 Jim Blandy <jimb@redhat.com>
+
+ * cpu-rs6000.c (rs6000_compatible): Check the correct arch_info
+ object's mach field: all PowerPC machines are supersets of the
+ original rs6000, but not later rs6000 machines.
+
+2003-10-30 Alan Modra <amodra@bigpond.net.au>
+
+ * dwarf2.c (struct attribute): Delete "unsnd", "snd" and "addr".
+ Add "val" and "sval" fields.
+ (DW_STRING, DW_UNSND, DW_BLOCK, DW_SND, DW_ADDR): Delete.
+ (read_attribute_value): Expand and adjust DW_* occurrences.
+ (scan_unit_for_functions, parse_comp_unit): Likewise.
+
+2003-10-30 Phil Edwards <phil@codesourcery.com>
+
+ * config.bfd (arm-*-vxworks): Remove separate stanza; merge with
+ other common ELF triples.
+ (i[3-7]86-*-vxworks): Change to ELF format.
+ (mips*-*-windiss): New triple, add to common MIPS/ELF stanza.
+ (sh-*-vxworks): New stanza.
+
+2003-10-30 Lars Knoll <lars@trolltech.com>
+ Michael Matz <matz@suse.de>
+ Jakub Jelinek <jakub@redhat.com>
+ Alan Modra <amodra@bigpond.net.au>
+
+ * merge.c (struct sec_merge_sec_info): Update comment.
+ (struct sec_merge_hash_entry): Remove entsize.
+ (sec_merge_hash_lookup): Only adjust alignment when creating.
+ (sec_merge_emit): Remove register keyword.
+ (cmplengthentry, last4_eq, last_eq): Delete.
+ (strrevcmp, strrevcmp_align, is_suffix): New.
+ (merge_strings): Use them to implement fast suffix merging.
+ * elf-strtab.c (struct elf_strtab_hash_entry): Update comments.
+ Make "len" signed.
+ (_bfd_elf_strtab_add): Lose on >2G strings.
+ (_bfd_elf_strtab_emit): Don't emit strings with len < 0.
+ (cmplengthentry, last4_eq): Delete.
+ (strrevcmp, is_suffix): New.
+ (_bfd_elf_strtab_finalize): Rework to implement fast suffix merging.
+
+2003-10-29 Daniel Jacobowitz <drow@mvista.com>
+
+ * elf32-arm.h (elf32_arm_final_link_relocate): Move check for
+ SEC_ALLOC.
+
+2003-10-29 Philip Blundell <philb@gnu.org>
+
+ * elf32-arm.h (elf32_arm_plt0_entry, elf32_arm_plt_entry): New
+ code sequence.
+ (PLT_HEADER_SIZE): New.
+ (struct elf32_arm_pcrel_relocs_copied): Rename to ...
+ (struct elf32_arm_relocs_copied): ... this. Count both
+ pcrel and non-pcrel relocs. All uses updated.
+ (struct elf32_arm_link_hash_table): Add pointers to dynamic linker
+ sections and symbol/section mapping cache.
+ (create_got_section): New.
+ (elf32_arm_create_dynamic_sections): New.
+ (elf_backend_create_dynamic_sections): Use it.
+ (elf32_arm_final_link_relocate): Support garbage collection of relocs.
+ (elf32_arm_check_relocs): Likewise.
+ (elf32_arm_adjust_dynamic_symbol): Likewise.
+ (elf32_arm_copy_indirect_symbol): New.
+ (elf32_arm_link_hash_table_create): Initialise new fields.
+ (elf32_arm_gc_sweep_hook): Implement.
+ (elf32_arm_discard_copies): Delete.
+ (elf32_arm_finish_dynamic_symbol): Use new PLT code.
+ (elf32_arm_finish_dynamic_sections): Likewise.
+ (elf_backend_can_refcount): Define.
+ (elf_backend_copy_indirect_symbol): Likewise.
+ (elf_backend_plt_header_size): Set to PLT_HEADER_SIZE.
+
+2003-10-29 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (elf_backend_grok_prstatus): Define.
+ (elf_backend_grok_psinfo): Define.
+ (ppc64_elf_grok_prstatus, ppc64_elf_grok_psinfo): New functions.
+
+ * elf.c (_bfd_elfcore_make_pseudosection): Allow multiple
+ sections with the same name.
+ (elfcore_grok_lwpstatus): Likewise.
+ (elfcore_grok_win32pstatus): Likewise.
+ (elfcore_grok_note): Likewise.
+ (elfcore_grok_nto_status): Likewise.
+ (elfcore_grok_nto_gregs): Likewise.
+
+2003-10-27 Daniel Jacobowitz <drow@mvista.com>
+
+ * elf32-arm.h (elf32_arm_merge_private_bfd_data): Never skip dynamic
+ objects.
+
+2003-10-14 Richard Sandiford <rsandifo@redhat.com>
+
+ * elfxx-mips.c (mips_elf_create_got_section): Initialize global_gotno.
+
+2003-10-24 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elflink.h (NAME(bfd_elf,size_dynamic_sections)): Look up
+ hash table for real symbols.
+
+2003-10-23 Michael Snyder <msnyder@redhat.com>
+
+ * section.c (asection): Fix typo in comment.
+
+2003-10-23 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (get_tls_mask): Add toc_symndx param, save toc
+ reloc symbol index to it. Don't allow gd syms in shared libs
+ to be optimized.
+ (ppc64_elf_tls_optimize): Adjust get_tls_mask call.
+ (ppc64_elf_size_stubs): Likewise.
+ (ppc64_elf_relocate_section): Check that tls relocs are only used
+ with tls syms, and similarly for non-tls. Correct symbol used
+ when optimizing toc tls code.
+
+2003-10-22 Nick Clifton <nickc@redhat.com>
+
+ * peicode.h (coff_swap_scnhdr_in): Only remove padding when
+ processing an executable.
+
+2003-10-22 Jakub Jelinek <jakub@redhat.com>
+
+ * elflink.c (_bfd_elf_export_symbol): Adjust for globals and locals
+ field changes.
+ (_bfd_elf_link_assign_sym_version): Likewise.
+ * elflink.h (size_dynamic_sections): Likewise.
+
+2003-10-21 Alexandre Oliva <aoliva@redhat.com>,
+ Michael Snyder <msnyder@redhat.com>
+
+ * archures.c (bfd_mach_sh4a, bfd_mach_sh4al_dsp, bfd_mach_sh4_nofpu,
+ bfd_mach_sh4a_nofpu): New machine types.
+ * bfd-in2.h: Rebuilt.
+ * cpu-sh.c (compatible): Remove unused function.
+ (SH4A_NEXT, SH4AL_DSP_NEXT, SH4_NOFPU_NEXT, SH4A_NOFPU_NEXT): New.
+ (arch_info_struct): Add sh4a, sh4al_dsp, sh4-nofpu and sh4a-nofpu.
+ * elf32-sh.c (sh_elf_set_mach_from_flags): Handle them.
+
+2003-10-21 Wouter van Heyst <wouter@vidicode.nl>
+
+ * elf32-arm.h (elf32_arm_merge_private_bfd_data): Correct text
+ describing mismatched formats involving the Maverick FP type.
+
+2003-10-21 Anil Paranjpe <anilp1@KPITCummins.com>
+
+ * binary.c (binary_object_p): Pass machine flag along with
+ architecture.
+
+2003-10-21 Thorsten Brehm <brehm@gmx.net>
+
+ * archures.c (bfd_default_scan): Add support for mcf528x.
+ * ieee.c (ieee_write_processor): Likewise.
+
+2003-10-21 Peter Barada <pbarada@mail.wm.sps.mot.com>
+ Bernardo Innocenti <bernie@develer.com>
+
+ * archures.c: Add MCF528x (MCFv4) support.
+ * cpu-m68k.c (arch_info_struct): Likewise.
+ * bfd-in2.h: Regenerate.
+
+2003-10-20 Andrew Cagney <cagney@redhat.com>
+
+ * targets.c: Replace "struct sec" with "struct bfd_section"
+ * syms.c, sparclynx.c, section.c, opncls.c: Ditto.
+ * libcoff-in.h, libbfd-in.h, elfxx-target.h: Ditto.
+ * elf.c, coffgen.c, bfd.c, bfd-in.h, aoutf1.h: Ditto.
+ * aout-tic30.c, aout-target.h:
+ * bfd-in2.h, libcoff.h, libbfd.h: Regenerate.
+
+2003-10-18 Hans-Peter Nilsson <hp@bitrange.com>
+
+ Support linker relaxation of new R_MMIX_PUSHJ_STUBBABLE relocs.
+ * elf64-mmix.c (MAX_PUSHJ_STUB_SIZE): New macro.
+ (struct _mmix_elf_section_data): New member pjs.
+ (mmix_set_relaxable_size, mmix_elf_get_section_contents): New
+ functions.
+ (elf_mmix_howto_table): New entry for R_MMIX_PUSHJ_STUBBABLE.
+ (mmix_reloc_map): Ditto.
+ (mmix_elf_relocate_section): Handle R_MMIX_PUSHJ_STUBBABLE.
+ (mmix_final_link_relocate, mmix_elf_check_common_relocs): Ditto.
+ (mmix_elf_perform_relocation): Ditto. Don't mark parameter addr
+ unused.
+ (mmix_elf_check_relocs): Move early return to after
+ mmix_elf_check_common_relocs call.
+ (mmix_elf_symbol_processing): Fix cut-and-pasto in head comment.
+ (_bfd_mmix_before_linker_allocation): Rename from
+ _bfd_mmix_prepare_linker_allocated_gregs. All referers changed.
+ Arrange to set the initial relaxable size of sections.
+ (_bfd_mmix_after_linker_allocation): Rename from
+ _bfd_mmix_finalize_linker_allocated_gregs.
+ (mmix_elf_relax_section): Relax a R_MMIX_PUSHJ_STUBBABLE reloc.
+ (bfd_elf64_get_section_contents): Define.
+ * reloc.c: Add ENUMX for BFD_RELOC_MMIX_PUSHJ_STUBBABLE.
+ * libbfd.h, bfd-in2.h: Regenerate.
+
+ * reloc.c (bfd_generic_relax_section): Default-set
+ section->_cooked_size here.
+ (bfd_generic_get_relocated_section_contents): Don't set it here.
+ Explain why.
+
+2003-10-17 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ * elf32-hppa.c (elf32_hppa_relocate_section): Skip relocation if
+ output section has been discarded.
+
+2003-10-17 Shrinivas Atre <shrinivasa@KPITCummins.com>
+
+ * coff-h8300.c (funcvec_hash_newfunc): Handle normal mode.
+ (h8300_reloc16_extra_cases): Likewise.
+ (h8300_bfd_link_add_symbols): Likewise.
+
+2003-10-17 Dhananjay Deshpande <dhananjayd@kpitcummins.com>
+
+ * cpu-h8300.c (h8300sxn_info_struct): Correct address size.
+ (h8300sn_info_struct): Likewise.
+ (h8300hn_info_struct): Likewise.
+
+2003-10-16 Pavel Roskin <proski@gnu.org>
+
+ * peXXigen.c (_bfd_XXi_swap_aouthdr_out): Don't calculate image size
+ for sections which lack size info.
+
+2003-10-17 Danny Smith <dannysmith@users.sourceforge.net>
+
+ * configure.host: Add __USE_MINGW_FSEEK to HDEFINES for
+ mingw32.
+
+2003-10-16 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elflink.h (NAME(bfd_elf,size_dynamic_sections)): Also warn
+ undefined patterns with '*'.
+
+2003-10-16 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf-eh-frame.c (_bfd_elf_discard_section_eh_frame): Don't
+ use the last CIE from a different section.
+ (_bfd_elf_write_section_eh_frame): Don't pad beyond the raw
+ size of the output section.
+
+2003-10-07 Roland McGrath <roland@redhat.com>
+
+ * elf.c (_bfd_elf_make_section_from_phdr): Set alignment_power of
+ new section from p_align header field.
+
+2003-10-16 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf32-xtensa.c (xtensa_read_table_entries): The external size
+ of entry is 8 bytes.
+
+2003-10-15 Andrew Cagney <cagney@redhat.com>
+
+ * targets.c (BFD_JUMP_TABLE_SYMBOLS): Replace NAME##_get_symtab
+ with NAME##_canonicalize_symtab.
+ * libcoff-in.h (coff_canonicalize_symtab): Update.
+ * xsym.h (bfd_sym_canonicalize_symtab): Update.
+ * elf-bfd.h (_bfd_elf_canonicalize_symtab): Update.
+ * coffgen.c (coff_canonicalize_symtab): Update.
+ * libbfd-in.h (_bfd_nosymbols_canonicalize_symtab): Update.
+ * libnlm.h (nlmNAME(canonicalize_symtab)): Update.
+ * ieee.c (ieee_vec): Update comment.
+ * libecoff.h (_bfd_ecoff_canonicalize_symtab): Update.
+ * mmo.c (mmo_canonicalize_symtab): Update.
+ * nlm-target.h (nlm_canonicalize_symtab): Update.
+ * nlmcode.h (nlm_canonicalize_symtab): Update.
+ * i386msdos.c (msdos_canonicalize_symtab): Update.
+ * hp300hpux.c (MY (canonicalize_symtab)): Update.
+ * oasys.c (oasys_canonicalize_symtab): Update.
+ * som.c (som_canonicalize_symtab): Update.
+ * pef.c (bfd_pef_canonicalize_symtab): Update.
+ * nlmcode.h (nlm_canonicalize_symtab): Update.
+ * xsym.c (bfd_sym_canonicalize_symtab): Update.
+ * vms.c (vms_canonicalize_symtab): Update.
+ * versados.c (versados_canonicalize_symtab): Update.
+ * mach-o.c (bfd_mach_o_canonicalize_symtab): Update.
+ * ieee.c (ieee_canonicalize_symtab): Update.
+ * pdp11.c (NAME(aout,canonicalize_symtab)): Update.
+ * reloc.c: Update comment.
+ * libaout.h (NAME(aout,canonicalize_symtab)): Update.
+ * coff64-rs6000.c (aix5coff64_vec): Update.
+ * coff64-rs6000.c (bfd_xcoff_aix5_backend_data): Update.
+ * coff-rs6000.c (rs6000coff_vec, pmac_xcoff_vec): Update.
+ * aoutx.h (NAME(aout,canonicalize_symtab)): Update.
+ * elfxx-target.h (bfd_elfNN_canonicalize_symtab): Update.
+ * hp300hpux.c (MY_canonicalize_symtab): Update.
+ * ecoff.c (_bfd_ecoff_canonicalize_symtab): Update.
+ * aout-tic30.c (MY_canonicalize_symtab): Update.
+ * aout-target.h (MY_canonicalize_symtab): Update.
+ * ppcboot.c (ppcboot_canonicalize_symtab): Update.
+ * elf.c (_bfd_elf_canonicalize_symtab): Update.
+ * elfcode.h (elf_canonicalize_symtab): Update.
+ * ihex.c (ihex_canonicalize_symtab): Update.
+ * tekhex.c (tekhex_canonicalize_symtab): Update.
+ * binary.c (binary_canonicalize_symtab): Update.
+ * srec.c (srec_canonicalize_symtab): Update.
+
+2003-10-15 Kazu Hirata <kazu@cs.umass.edu>
+
+ * elf32-h8300.c (elf_reloc_map): Fix a comment typo.
+
+2003-10-15 Kaz Kojima <kkojima@rr.iij4u.or.jp>
+
+ * elf32-sh.c (sh_elf_relocate_section): Handle R_SH_IMM_*_PCREL
+ relocations.
+ (sh_elf_check_relocs): Likewise.
+
+ * elf32-sh64.c (elf_backend_merge_symbol_attribute): Define.
+ (sh64_elf_merge_symbol_attribute): New.
+ * elf64-sh64.c (elf_backend_merge_symbol_attribute): Define.
+ (sh64_elf64_merge_symbol_attribute): New.
+
+2003-10-14 Kaz Kojima <kkojima@rr.iij4u.or.jp>
+
+ * elf-bfd.h (struct elf_backend_data): New function pointer member
+ elf_backend_merge_symbol_attribute.
+ * elflink.h (elf_link_add_object_symbols): Adjust call to
+ elf_backend_merge_symbol_attribute if the backend defined it.
+ * elfxx-target.h (elf_backend_merge_symbol_attribute): New macro.
+ (elfNN_bed): Add that to the initializer.
+
+2003-10-14 Bob Wilson <bob.wilson@acm.org>
+
+ * elf32-xtensa.c (get_is_linkonce_section): Delete.
+ (xtensa_is_property_section, xtensa_is_littable_section): Use
+ XTENSA_INSN_SEC_NAME and XTENSA_LIT_SEC_NAME macros. Do not recognize
+ linkonce sections containing ".xt.insn" and ".xt.lit" substrings.
+ (xtensa_get_property_section_name): Check section name instead of
+ calling get_is_linkonce_section. Remove unused bfd parameter. Use
+ XTENSA_INSN_SEC_NAME and XTENSA_LIT_SEC_NAME macros. Never generate
+ linkonce section names by appending ".xt.insn" or ".xt.lit".
+ (xtensa_read_table_entries): Remove bfd argument in call to
+ xtensa_get_property_section_name. Free section name when done.
+ (elf_xtensa_combine_prop_entries): Free leaking table.
+
+2003-10-13 Richard Sandiford <rsandifo@redht.com>
+
+ * elfxx-mips.c (_bfd_mips_elf_size_dynamic_sections): Don't add
+ DT_MIPS_LIBLIST or DT_MIPS_CONFLICT entries.
+ (_bfd_mips_elf_finish_dynamic_symbol): Don't handle them. Don't
+ handle DT_MIPS_MSYM. Set DT_RELSZ based on the number of relocations
+ that were needed.
+ (_bfd_mips_elf_modify_segment_map): Fix placement of PT_MIPS_OPTIONS.
+ (_bfd_mips_elf_merge_private_bfd_data): Ignore EF_MIPS_UCODE.
+
+2003-10-13 H.J. Lu <hongjiu.lu@intel.com>
+
+ * bfd-in.h (bfd_elf32_ia64_after_parse): New prototype.
+ (bfd_elf64_ia64_after_parse): Likewise.
+ * bfd-in2.h: Regenerated.
+
+ * elfxx-ia64.c (oor_ip): New.
+ (oor_branch_size): Likewise.
+ (bfd_elfNN_ia64_after_parse): Likewise.
+ (elfNN_ia64_relax_section): Use oor_ip if oor_branch_size
+ equals sizeof (oor_ip).
+
+2003-10-12 Kaz Kojima <kkojima@rr.iij4u.or.jp>
+
+ * elf64-sh64.c (sh_elf64_relocate_section): Tidy up for the
+ renumbering of some relocation numbers.
+
+2003-10-11 Alan Modra <amodra@bigpond.net.au>
+
+ * coff-sh.c: Move definition of MAP and guard more code with
+ COFF_IMAGE_WITH_PE.
+
+ * section.c (bfd_get_section_size_before_reloc): Ignore reloc_done.
+ * bfd-in2.h: Regenerate.
+
+2003-10-10 H.J. Lu <hongjiu.lu@intel.com>
+
+ * Makefile.am: Run "make dep-am".
+ * Makefile.in: Regenerate.
+ * doc/Makefile.in: Likewise.
+
+2003-10-09 H.J. Lu <hongjiu.lu@intel.com>
+
+ * cofflink.c: Include "safe-ctype.h".
+ (coff_link_add_symbols): Use ISDIGIT instead of isdigit.
+
+2003-10-08 Dave Brolley <brolley@redhat.com>
+ On behalf of Michael Snyder <msnyder@redhat.com>
+
+ * archures.c: Add FRV fr550 machine.
+ * cpu-frv.c: Ditto.
+ * elf32-frv.c: Ditto.
+ * bfd-in2.h: Regenerate.
+
+2003-10-08 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * elfxx-mips.c (STUB_MOVE,STUB_LI16): Fix stub code
+ for non-SGI N64 ABI. Improve code consitency.
+
+2003-10-07 Alexandre Oliva <aoliva@redhat.com>
+
+ * elf32-frv.c (elf32_frv_howto_table): Set R_FRV_LABEL16's
+ rightshift to 2.
+
+2003-10-07 Nathan Sidwell <nathan@codesourcery.com>
+
+ * libbfd-in.h (_bfd_link_section_stabs): Add string offset
+ parameter.
+ * cofflink.c (coff_link_add_symbols): Deal with split stab
+ sections.
+ * elflink.h (elf_link_add_object_symbols): Deal with split stab
+ sections.
+ * stabs.c (_bfd_link_section_stabs): Add string offset parameter.
+ * libbfd.h: Regenerated.
+
+ * coffcode.h (coff_set_alignment_hook): With PE_COFF reloc
+ overflow, set reloc start position to after the count
+ reloc. Subtract one from num relocs. Give error on 0xffff relocs
+ and no overflow.
+ * cofflink.c (_bfd_coff_final_link): Deal with PE_COFF reloc
+ overflow.
+ * peXXigen.c (_bfd_XXi_swap_scnhdr_out): Do overflow if >=
+ 0xffff.
+
+2003-10-06 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf-eh-frame.c (_bfd_elf_write_section_eh_frame): Pad the
+ last CIE/FDE if needed.
+
+2003-10-06 Nick Clifton <nickc@redhat.com>
+
+ * targets.c (_bfd_target_vector): Include bfd_elf64_sparc_vec if
+ BFD64 is enabled.
+
+2003-10-06 Matt Thomas <matt@3am-software.com>
+
+ * config.bfd: Move the hppa*-*-netbsd* case to the hppa*-*-linux* case.
+
+2003-10-06 Robert Millan <robertmh@gnu.org>
+
+ * configure.in: Match GNU/KNetBSD with new knetbsd*-gnu triplet.
+ * config.bfd: Likewise.
+ * configure: Regenerate.
+
+2003-10-04 Christian Groessler <chris@groessler.org>
+
+ * coff-z8k.c (extra_case): Fix displacement length check for R_JR
+ and R_CALLR.
+
+2003-10-04 Stephane Carrez <stcarrez@nerim.fr>
+
+ * elf32-m68hc1x.c: Update to ISO C90; replace PTR with void*.
+ * elf32-m68hc11.c: Likewise.
+ * elf32-m68hc12.c: Likewise.
+ * elf32-m68hc1x.h: Likewise.
+
+2003-10-04 Stephane Carrez <stcarrez@nerim.fr>
+
+ * elf32-m68hc1x.c (_bfd_m68hc11_elf_merge_private_bfd_data): Fix merge
+ of flags between HC12 and HCS12.
+
+2003-10-04 Bryce McKinlay <bryce@mckinlay.net.nz>
+
+ * merge.c (_bfd_merge_sections): Set SEC_EXCLUDE flag on sections
+ which become empty after merging.
+
+2003-09-30 Jakub Jelinek <jakub@redhat.com>
+
+ * elfxx-ia64.c (ia64_howto_table): Fix size of R_IA64_TPREL64[LM]SB,
+ R_IA64_DTPREL{32,64}[LM]SB and R_IA64_DTPMOD64[LM]SB.
+
+2003-09-30 Chris Demetriou <cgd@broadcom.com>
+
+ * archures.c (bfd_mach_mipsisa64r2): New define.
+ * bfd-in2.h: Regenerate.
+ * aoutx.h (NAME(aout,machine_type)): Handle bfd_mach_mipsisa64r2.
+ * cpu-mips.c (I_mipsisa64r2): New enum value.
+ (arch_info_struct): Add entry for I_mipsisa64r2.
+ * elfxx-mips.c (_bfd_elf_mips_mach)
+ (_bfd_mips_elf_print_private_bfd_data): Handle E_MIPS_ARCH_64R2.
+ (mips_set_isa_flags): Add bfd_mach_mipsisa64r2 case.
+ (mips_mach_extensions): Add entry for bfd_mach_mipsisa64r2.
+
+2003-09-29 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elfxx-ia64.c (elfNN_hpux_backend_symbol_processing): New.
+ Handle SHN_IA_64_ANSI_COMMON.
+ (elf_backend_section_from_bfd_section): Defined.
+
+2003-09-26 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elflink.c (elf_link_read_relocs_from_section): Add an argument
+ of a pointer to section. Check bad symbol index.
+ (_bfd_elf_link_read_relocs): Modify calls to
+ elf_link_read_relocs_from_section.
+
+2003-09-23 DJ Delorie <dj@redhat.com>
+
+ * elf32-sh.c (sh_elf_howto_table): R_SH_SWITCH8,
+ R_SH_GNU_VTINHERIT, R_SH_GNU_VTENTRY,
+ R_SH_LOOP_START,R_SH_LOOP_END moved to "reserved" spaces,
+ R_SH_DIR16, R_SH_DIR8, R_SH_DIR8UL, R_SH_DIR8UW, R_SH_DIR8U,
+ R_SH_DIR8SW, R_SH_DIR8S, R_SH_DIR4UL, R_SH_DIR4UW, R_SH_DIR4U,
+ R_SH_PSHA, R_SH_PSHL added.
+ (sh_reloc_map): Add R_SH_DIR16 and R_SH_DIR8.
+ (sh_elf_relocate_section): Support new relocs.
+
+2003-09-23 Bob Wilson <bob.wilson@acm.org>
+
+ * elf32-xtensa.c (elf_xtensa_relocate_section): Fix typo that clobbered
+ dynamic relocation offsets.
+
+2003-09-23 Alan Modra <amodra@bigpond.net.au>
+
+ * simple.c (bfd_simple_get_relocated_section_contents): Free the
+ hash table using _bfd_generic_link_hash_table_free.
+
+2003-09-23 Alan Modra <amodra@bigpond.net.au>
+
+ * elf-bfd.h (struct bfd_elf_special_section): Remove "suffix". Change
+ type of prefix_length and suffix_length to int. Rename "attributes"
+ to "attr". Comment.
+ (_bfd_elf_get_sec_type_attr): Update prototype.
+ * elf.c (get_special_section): Rewrite.
+ (_bfd_elf_get_sec_type_attr): Return struct rather than passing in
+ attr and type pointers.
+ (_bfd_elf_new_section_hook): Adjust for above.
+ (special_sections): Merge suffix with prefix. Set
+ prefix_length for all entries. Set suffix_length appropriately.
+ * elf32-m32r.c (m32r_elf_special_sections): Likewise.
+ * elf32-m68hc11.c (elf32_m68hc11_special_sections): Likewise.
+ * elf32-m68hc12.c (elf32_m68hc12_special_sections): Likewise.
+ * elf32-mcore.c (mcore_elf_special_sections): Likewise.
+ * elf32-sh64.c (sh64_elf_special_sections): Likewise.
+ * elf32-v850.c (v850_elf_special_sections): Likewise.
+ * elf32-xtensa.c (elf_xtensa_special_sections): Likewise.
+ * elf64-alpha.c (elf64_alpha_special_sections): Likewise.
+ * elf64-hppa.c (elf64_hppa_special_sections): Likewise.
+ * elf64-ppc.c (ppc64_elf_special_sections): Likewise.
+ * elf64-sh64.c (sh64_elf64_special_sections): Likewise.
+ * elfxx-ia64.c (elfNN_ia64_special_sections): Likewise.
+ * elfxx-mips.c (_bfd_mips_elf_special_sections): Likewise.
+ * elf32-ppc.c (ppc_elf_special_sections): Likewise. Fix .plt flags.
+
+2003-09-21 Daniel Jacobowitz <drow@mvista.com>
+
+ * elf64-alpha.c (elf64_alpha_create_got_section): Initialize
+ ->got if the section already exists.
+
+2003-09-19 Nathan Sidwell <nathan@codesourcery.com>
+
+ * dwarf2.c (decode_line_info): Cope with an initially empty
+ filename table.
+
+2003-09-18 H.J. Lu <hongjiu.lu@intel.com>
+
+ * acinclude.m4: Include ../config/accross.m4.
+ * aclocal.m4: Regenerated.
+
+ * configure.host (HOST_64BIT_TYPE): Remove if it is set to long
+ or long long.
+ (HOST_U_64BIT_TYPE): Remove if it is set to unsigned long long.
+ (host64): Remove if HOST_64BIT_TYPE is set to long.
+
+ * configure.in (HOST_64BIT_TYPE): Set according to the size of
+ long and long long.
+ (HOST_U_64BIT_TYPE): Likewise.
+ (host64): Likewise.
+ * configure: Regenerated.
+
+2003-09-19 Alan Modra <amodra@bigpond.net.au>
+
+ * elf.c (elfcore_write_note): Don't use sizeof(Elf_External_note)
+ since some ABIs round up the size of the struct.
+
+2003-09-18 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elflink.c (_bfd_elf_merge_symbol): Allow type change if
+ the old symbol is undefined and the new symbol is defined.
+
+2003-09-18 Andreas Schwab <schwab@suse.de>
+
+ * simple.c (bfd_simple_get_relocated_section_contents): Use
+ _bfd_generic_link_hash_table_create instead of
+ bfd_link_hash_table_create.
+
+2003-09-10 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elfxx-ia64.c (elfNN_ia64_special_sections): Mark all sections
+ started with ".sbss" or "".sdata" as SHF_IA_64_SHORT.
+
+2003-09-10 John David Anglin <dave.anglin@nrc-cnrc.nrc.ca>
+ Randolph Chung <randolph@tausq.org>
+
+ * elf32-hppa.c (struct elf32_hppa_link_hash_entry,
+ hppa_link_hash_newfunc, hppa_build_one_stub,
+ elf32_hppa_adjust_dynamic_symbol, mark_PIC_calls, allocate_plt_static,
+ allocate_dynrelocs, elf32_hppa_size_dynamic_sections,
+ elf32_hppa_finish_dynamic_symbol): Remove pic_call field and all code
+ for generating import stubs for calls to statically linked PIC
+ functions.
+ (hppa_type_of_stub): Don't generate an import stub for calls to
+ statically linked pic functions. Generate import stubs for calls
+ in a shared object, to functions not in a regular file, and to
+ defined weak functions. Add new argument INFO.
+ (hppa_build_one_stub): Don't undef ADDIL_DP.
+ (elf32_hppa_check_relocs): Don't set SEC_HAS_GOT_REF flag.
+ (elf32_hppa_size_stubs): Pass info to hppa_type_of_stub.
+ (final_link_relocate): Change all DLTIND relocs to DPREL relocs in a
+ non-shared link. Convert instructions that use the linkage table
+ pointer, or a facsimile thereof, to use the global data pointer when
+ the reloc has been changed.
+
+2003-09-08 Joel Brobecker <brobecker@gnat.com>
+
+ * archures.c: Add new machine names for hppa.
+ * bfd-in2.h: Regenerate.
+ * cpu-hppa.c: Use the new machine names.
+
+2003-09-06 Stephane Carrez <stcarrez@nerim.fr>
+
+ * elf32-m68hc1x.h (struct m68hc11_elf_link_hash_table): Remove
+ all_local_syms member.
+ * elf32-m68hc1x.c (elf32_m68hc11_size_stubs): Use bfd_elf_get_elf_syms
+ to get the local symbols.
+
+2003-09-06 Stephane Carrez <stcarrez@nerim.fr>
+
+ * elf32-m68hc12.c (elf32_m68hc12_special_sections): New for hc11.
+ (elf_backend_special_sections): Define.a
+
+ PR savannah/4950:
+ * elf32-m68hc11.c (elf32_m68hc11_special_sections): The .vectors
+ section is read-only.
+
+2003-09-04 Nick Clifton <nickc@redhat.com>
+
+ * archures.c (bfd_mach_v850e1): Define.
+ * bfd-in2.h: Regenerate.
+ * cpu-v850.h (scan): Accept bfd_mach_v850e1.
+ (arch_info_struct): Include an entry for bfd_mach_v850e1.
+ * elf32-v850.c (v850_elf_object_p): Accept E_V850E1_ARCH flag.
+ (v850_elf_final_write_processing): Accept bfd_mach_v850e1.
+ (v850_elf_print_private_bfd_data): Interpret E_V850E1_ARCH flag.
+ (v850_elf_merge_private_bfd_data): Allow v850e1 binaries to be
+ linked with v850e binaries. Mark the output as v850e.
+
+2003-09-03 Nick Clifton <nickc@redhat.com>
+
+ * cofflink.c (_bfd_coff_link_input_bfd): Do not skip section
+ symbols that are used in relocs.
+
+2003-08-30 Robert Millan <robertmh@gnu.org>
+
+ * configure.in: Match GNU/KFreeBSD with new kfreebsd*-gnu triplet.
+ * config.bfd: Likewise.
+ * configure: Regenerate.
+
+2003-08-31 Christian Groessler <chris@groessler.org>
+
+ * elf32-i860.c (i860_howto_pc26_reloc): Finish relocation here
+ instead of returning bfd_reloc_continue.
+
+2003-08-31 Andreas Jaeger <aj@suse.de>
+
+ * merge.c: Update to ISO C90.
+
+2003-08-27 Ian Lance Taylor <ian@airs.com>
+
+ * configure.in: Check for strtoull.
+ * bfd.c (bfd_scan_vma): Use strtoull when available.
+ * configure, config.in: Regenerate.
+
+ * configure.in: Define and substitute BFD_HOST_LONG_LONG.
+ * bfd-in.h: Define BFD_HOST_LONG_LONG. Test it rather than
+ __GNUC__ when deciding whether to use long long for
+ BFD_HOST_64_BIT.
+ * configure, Makefile.in, doc/Makefile.in, bfd-in2.h: Regenerate.
+
+2003-08-27 Christian Groessler <chris@groessler.org>
+
+ * elf32-i860.c (i860_howto_pc26_reloc, i860_howto_pc16_reloc,
+ i860_howto_splitn_reloc, i860_howto_highadj_reloc): New
+ functions.
+ (elf32_i860_howto_table): Insert the new functions as
+ 'special_function's in the proper reloc type entries.
+
+2003-08-27 Richard Sandiford <rsandifo@redhat.com>
+
+ * elf32-frv.c (elf32_frv_relocate_section): Use
+ _bfd_elf_rela_local_sym.
+
+2003-08-26 Michael Snyder <msnyder@redhat.com>
+
+ * cpu-frv.c: Remove unused enum.
+
+2003-08-25 Maciej W. Rozycki <macro@ds2.pg.gda.pl>
+
+ * reloc.c: Fix documentation for MIPS ELF relocations.
+ libbfd.h: Regenerate.
+ bfd-in2.h: Regenerate.
+
+2003-08-24 Jason Eckhardt <jle@rice.edu>
+
+ * coff-i860.c (CALC_ADDEND): Define to be a no-op.
+
+2003-08-24 Jason Eckhardt <jle@rice.edu>
+
+ * elf32-i860.c (elf32_i860_relocate_pc16): Subtract 4 and
+ shift by 2 before storing the relocated value.
+
+2003-08-23 Jason Eckhardt <jle@rice.edu>
+
+ * coff-i860.c (coff_i860_reloc_nyi): New function.
+ (howto_table): Add entries for relocations PAIR, HIGHADJ, HIGH,
+ LOWn, SPLITn, and BRADDR.
+ (RTYPE2HOWTO): Check that the r_type is within the howto_table
+ before trying to access the entry.
+ (coff_i860_rtype_to_howto): Likewise.
+ (coff_i860_reloc_type_lookup): New function.
+ (i860_reloc_processing): New function.
+ (coff_bfd_reloc_type_lookup): Define macro.
+ (RELOC_PROCESSING): Define macro.
+ Minor formatting adjustments.
+
+2003-08-23 Alan Modra <amodra@bigpond.net.au>
+
+ * elflink.h (elf_link_add_object_symbols): Don't crash on NULL owner.
+
+2003-08-22 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elfxx-ia64.c (elfNN_ia64_create_dynamic_sections): Align the
+ .got section at 8 bytes.
+
+2003-08-21 Nick Clifton <nickc@redhat.com>
+
+ * cofflink.c: Update to ISO C90 and tidy up formatting.
+
+2003-08-21 Randolph Chung <tausq@debian.org>
+
+ * elf32-hppa.c (elf32_hppa_object_p): For elf32-hppa-linux, objects
+ can have OSABI=Linux or OSABI=SysV. Check for both.
+ * elf64-hppa.c (elf64_hppa_object_p): Likewise.
+
+2003-08-21 Nick Clifton <nickc@redhat.com>
+
+ * po/sv.po: Updated Swedish translation.
+
+2003-08-20 Richard Sandiford <rsandifo@redhat.com>
+
+ * elf64-mips.c (elf_backend_copy_indirect_symbol): Define.
+
+2003-08-20 Nick Clifton <nickc@redhat.com>
+
+ * elf-bfd.h (RELOC_FOR_GLOBAL_SYMBOL): New macro used to
+ replace some duplicated code in most elfxx-xxxx.c files. This
+ version uses the new fields in bfd_link_info.
+
+ * elf-m10300.c (mn10300_elf_relocate_section): Use new macro.
+ * elf32-arm.h (elf32_arm_relocate_section): Likewise.
+ * elf32-cris.c (cris_elf_relocate_section): Likewise.
+ * elf32-hppa.c (elf32_hppa_relocate_section): Likewise.
+ * elf32-i386.c (elf_i386_relocate_section): Likewise.
+ * elf32-ip2k.c (ip2k_elf_relocate_section): Likewise.
+ * elf32-iq2000.c (iq2000_elf_relocate_section): Likewise.
+ * elf32-m68k.c (elf_m68k_relocate_section): Likewise.
+ * elf32-ppc.c (ppc_elf_relocate_section): Likewise.
+ * elf32-s390.c (elf_s390_relocate_section): Likewise.
+ * elf32-sparc.c (elf32_sparc_relocate_section): Likewise.
+ * elf32-vax.c (elf_vax_relocate_section): Likewise.
+ * elf32-xtensa.c (elf_xtensa_relocate_section): Likewise.
+ * elf64-alpha.c (elf64_alpha_relocate_section): Likewise.
+ * elf64-ppc.c (ppc64_elf_relocate_section): Likewise.
+ * elf64-s390.c (elf_s390_relocate_section): Likewise.
+ * elf64-sparc.c (sparc64_elf_relocate_section): Likewise.
+ * elf64-x86-64.c (elf64_x86_64_relocate_section): Likewise.
+ * elfxx-ia64.c (elfNN_ia64_relocate_section): Likewise.
+
+ * elf-hppa.h (elf_hppa_unmark_useless_dynamic_symbols,
+ elf_hppa_remark_useless_dynamic_symbols,
+ elf_hppa_relocate_section): Use the new fields in
+ bfd_link_info structure.
+ * elf32-sh.c (sh_elf_relocate_section): Likewise.
+ * elf64-alpha.c (elf64_alpha_check_relocs): Likewise.
+ * elf64-hppa.c (elf64_hppa_check_relocs): Likewise.
+ * elf64-sh64.c (sh_elf64_relocate_section): Likewise.
+ * elfxx-ia64.c (elfNN_ia64_check_relocs): Likewise.
+ * elfxx-mips.c (mips_elf_calculate_relocation): Likewise.
+
+ * elflink.h (elf_link_output_extsym): Fix test for reporting
+ undefined symbols in shared libraries. Remove redundant test
+ of shlib_undefined when reporting references to forced local
+ symbols.
+
+2003-08-18 Andreas Schwab <schwab@suse.de>
+
+ * libpei.h (bfd_pe_executable_p): Also recognize efi-app
+ executables.
+
+2003-08-17 Hans-Peter Nilsson <hp@bitrange.com>
+
+ * simple.c (bfd_simple_get_relocated_section_contents): Move
+ reloc_done hack to before first bfd_section_size call. Change all
+ returns to use new wrapper macro RETURN, restoring sec->reloc_done.
+
+2003-08-16 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c: Don't include elf/ppc.h.
+
+2003-08-14 Richard Sandiford <rsandifo@redhat.com>
+
+ * elfxx-mips.c (_bfd_mips_elf_modify_segment_map): Fix PT_DYNAMIC
+ code to work with 64-bit bfds.
+
+2003-08-14 Alan Modra <amodra@bigpond.net.au>
+
+ * dep-in.sed: Remove libintl.h.
+ * Makefile.am (SRC-POTFILES.in, BLD-POTFILES.in): Unset LC_COLLATE.
+ (POTFILES.in): Remove target.
+ * Makefile.in: Regenerate.
+
+2003-08-12 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (ppc64_elf_next_input_section): Update comment.
+ (ppc64_elf_relocate_section): For zero sym R_PPC64_TOC relocs,
+ use the function sym from the previous reloc.
+
+2003-08-11 Jakub Jelinek <jakub@redhat.com>
+
+ * elf32-i386.c (elf_i386_relocate_section): Make undefined symbols
+ fatal if -pie.
+ * elf32-s390.c (elf_s390_relocate_section): Likewise.
+ * elf32-sparc.c (elf32_sparc_relocate_section): Likewise.
+ * elf64-alpha.c (elf64_alpha_relocate_section): Likewise.
+ * elf64-ppc.c (ppc64_elf_relocate_section): Likewise.
+ * elf64-s390.c (elf_s390_relocate_section): Likewise.
+ * elf64-sparc.c (sparc64_elf_relocate_section): Likewise.
+ * elf64-x86-64.c (elf64_x86_64_relocate_section): Likewise.
+ * elfxx-ia64.c (elfNN_ia64_relocate_section): Likewise.
+ * elf32-ppc.c (ppc_elf_relocate_section): Likewise.
+ (ppc_elf_relocate_section) <case R_PPC_RELAX32>: Issue fatal error
+ on undefined symbols if -pie.
+ * elf32-sh.c (sh_elf_relocate_section): Likewise.
+
+2003-08-11 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (ppc64_elf_relocate_section): Add special case for crt1.o
+ branch to __libc_start_main.
+
+2003-08-08 Dmitry Diky <diwil@mail.ru>
+
+ * archures.c: Add xW42 and xE42 parts. Sort MPU list according to
+ gcc order.
+ * cpu-msp430.c: Likewise.
+ * elf32-msp430.c: Likewise.
+ * bfd-in2.h: Regenerate.
+
+2003-08-07 Alan Modra <amodra@bigpond.net.au>
+
+ * elfxx-target.h: Remove PTR cast.
+ * targets.c (bfd_target): Make backend_data const void *.
+ * elf-bfd.h: Constify all occurrences of struct elf_backend_data.
+ * elf-m10300.c: Likewise.
+ * elf.c: Likewise.
+ * elf32-hppa.c: Likewise.
+ * elf32-i386.c: Likewise.
+ * elf32-m68hc1x.c: Likewise.
+ * elf32-ppc.c: Likewise.
+ * elf32-s390.c: Likewise.
+ * elf32-sh.c: Likewise.
+ * elf32-sh64.c: Likewise.
+ * elf32-sparc.c: Likewise.
+ * elf32-xtensa.c: Likewise.
+ * elf64-mips.c: Likewise.
+ * elf64-ppc.c: Likewise.
+ * elf64-s390.c: Likewise.
+ * elf64-sh64.c: Likewise.
+ * elf64-sparc.c: Likewise.
+ * elf64-x86-64.c: Likewise.
+ * elfcode.h: Likewise.
+ * elfcore.h: Likewise.
+ * elflink.c: Likewise.
+ * elflink.h: Likewise.
+ * elfxx-ia64.c: Likewise.
+ * elfxx-mips.c: Likewise.
+ * elfxx-mips.h: Likewise.
+ * elf.c (prep_headers): Remove useless check for null backend_data.
+ * bfd-in2.h: Regenerate.
+
+ * elf-bfd.h: Remove PARAMS macro. Replace PTR with void *.
+ (NAME): Use ## rather than CONCAT4 macro.
+ * elfcode.h: Remove one remaining PARAMS macro.
+ * elf-eh-frame.c: Convert to C90, remove unneeded casts and prototypes.
+ * elf-strtab.c: Likewise.
+ * elf-hppa.h: Likewise.
+ * elf32-hppa.h: Likewise.
+ * elf32-hppa.c: Likewise.
+ (elf32_hppa_add_symbol_hook): Delete.
+ (elf_backend_add_symbol_hook): Don't define.
+ * libhppa.h: Convert to C90. Replace INLINE with inline.
+
+2003-08-06 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (ppc_stub_name): Tweak names for better readability.
+ (ppc64_elf_adjust_dynamic_symbol): Allow copy relocs against
+ function descriptors, but warn.
+ (ppc_build_one_stub): Remove a couple of vars. Move code creating
+ stub syms so that we can avoid a stub sym if we already have a
+ plt sym. Do not redefine an existing symbol.
+ (ppc64_elf_build_stubs): When --emit-stub-syms, print a symbol for
+ glink.
+
+2003-08-06 Nick Clifton <nickc@redhat.com>
+
+ * po/fr.po: Updated French translation.
+
+2003-08-06 Alan Modra <amodra@bigpond.net.au>
+
+ * elflink.c (_bfd_elf_create_dynamic_sections): Mark .dynbss with
+ SEC_LINKER_CREATED.
+
+2003-08-05 Daniel Jacobowitz <drow@mvista.com>
+
+ * elf32-arm.h (WILL_CALL_FINISH_DYNAMIC_SYMBOL): Define.
+ (elf32_arm_final_link_relocate, elf32_arm_relocate_section): Use it.
+
+2003-08-03 Jeff Muizelaar <muizelaar@rogers.com>
+
+ * coffcode.h (coff_slurp_line_table): Return with a warning
+ message if the line number table could not be read.
+
+2003-08-04 Nick Clifton <nickc@redhat.com>
+
+ * elflink.h (elf_link_add_object_symbols): Prepend "warning: "
+ to messages produced for .gnu.warning.SYMBOL sections.
+
+2003-08-04 Alan Modra <amodra@bigpond.net.au>
+
+ * elfcode.h: Convert to C90, remove unneeded casts and prototypes.
+ * elfcore.h: Likewise.
+ * elflink.c: Likewise.
+ * elflink.h: Likewise.
+ * elf.c (sym_is_global): Remove INLINE.
+ (align_file_position): Replace INLINE with inline.
+ * elfcode.h (elf_swap_dyn_in, elf_swap_dyn_out): Remove INLINE.
+ (elf_file_p): Replace INLINE with inline.
+
+2003-08-02 Kaz Kojima <kkojima@rr.iij4u.or.jp>
+
+ * elf32-sh.c (sh_elf_check_relocs): Don't set DF_TEXTREL here.
+
+2003-08-01 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elfxx-ia64.c (get_got): Align the .got section at 8 bytes.
+
+2003-08-01 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elfxx-ia64.c (elfNN_ia64_finish_dynamic_symbol): Use
+ ElfNN_External_Rela instead of Elf64_External_Rela.
+
+2003-08-01 Nick Clifton <nickc@redhat.com>
+
+ * config.bfd: Add code to catch obsolete configurations and warn
+ about them unless --enable-obsolete is used. Use this to mark
+ vax-vms port as obsolete.
+
+2003-07-30 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-ppc.c (ppc_elf_install_value): Tidy.
+ (ppc_elf_relax_section): Remove dead code. Remove unnecessary casts.
+ Formatting.
+ * elfxx-target.h: Remove PARAMS macro. Formatting.
+
+2003-07-30 Alan Modra <amodra@bigpond.net.au>
+
+ * elf.c (bfd_section_from_r_symndx): Test for SHN_UNDEF.
+ * elf64-ppc.c (get_fdh): New function, split out from
+ ppc64_elf_edit_opd.
+ (ppc64_elf_check_relocs): Use get_fdh.
+ (func_desc_adjust): Likewise. Tidy.
+ (ppc64_elf_edit_opd): Tighten reloc checks. Free local_syms on error
+ exit. Use get_fdh. Account for superfluous dynamic relocs.
+ (ppc64_elf_relocate_section): Warning fix.
+
+2003-07-30 Jason Eckhardt <jle@rice.edu>
+
+ * coff-i860.c: Convert to ISO C90. Remove superflous prototypes.
+
+2003-07-30 Jason Eckhardt <jle@rice.edu>
+
+ * elf32-i860.c: Convert to ISO C90. Remove superflous prototypes.
+
+2003-07-30 Randolph Chung <tausq@debian.org>
+
+ * elf-hppa.h (elf_hppa_relocate_section): Look up dyn_h for undefweak.
+ * elf64-hppa.c (elf64_hppa_finalize_dlt): Check h->root.type.
+
+2003-07-30 Alan Modra <amodra@bigpond.net.au>
+
+ * elf.c: Convert to C90, remove unnecessary prototypes and casts.
+ Replace PTR with void *. Formatting.
+ (_bfd_elf_assign_file_position_for_section): Remove INLINE.
+ (make_mapping): Likewise.
+
+2003-07-29 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (func_desc_adjust): Give linker created function
+ descriptor symbols a size and type.
+ (ppc64_elf_relocate_section): Correct lq insn test.
+
+2003-07-28 Eric Christopher <echristo@redhat.com>
+
+ * elf32-ppc.c (R_PPC_RELAX32): New relocation.
+ (ppc_elf_install_value): New function.
+ (ppc_elf_sort_rela): Remove.
+ (ppc_elf_relax_section): Rewrite. Remove old relaxation
+ and replace with out of range branch stubs.
+ (ppc_elf_relocate_section): Handle R_PPC_RELAX32.
+
+2003-07-29 Alexandre Oliva <aoliva@redhat.com>
+
+ * elf-m10300.c (mn10300_elf_relax_section): Take symbol hash table
+ from input_bfd.
+
+2003-07-28 Alan Modra <amodra@bigpond.net.au>
+
+ * elf.c (special_sections): Set attributes for .got and .plt.
+
+2003-07-27 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (ppc64_elf_adjust_dynamic_symbol): Ensure no copy relocs
+ on function descriptors.
+ (ELIMINATE_COPY_RELOCS): Expand comment.
+ (ppc64_elf_special_sections): Move. Don't include non-ppc64 sections.
+ Do include ".toc1".
+
+2003-07-25 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf.c (_bfd_elf_new_section_hook): Set the default section
+ type to SHT_NULL.
+ (elf_fake_sections): Set the section type based on asect->flags
+ if it is SHT_NULL. Don't abort on processor specific section
+ types.
+
+2003-07-25 H.J. Lu <hongjiu.lu@intel.com>
+
+ * bfd-in2.h: Regenerated.
+
+2003-07-25 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf-bfd.h (bfd_elf_special_section): New.
+ (elf_backend_data): Add special_sections, a pointer to
+ bfd_elf_special_section.
+ (elf_section_type). New.
+ (elf_section_flags): New.
+ (_bfd_elf_get_sec_type_attr): New.
+
+ * elf.c (_bfd_elf_make_section_from_shdr): Always use the
+ real section type/flags.
+ (special_sections): New.
+ (get_special_section): New.
+ (_bfd_elf_get_sec_type_attr): New.
+ (_bfd_elf_new_section_hook): Check special_section to set
+ elf_section_type and elf_section_flags.
+ (elf_fake_sections): Don't use section name to set ELF section
+ data.
+
+ * elf32-m32r.c (m32r_elf_special_sections): New.
+ (elf_backend_special_sections): Defined.
+
+ * elf32-m68hc11.c (elf32_m68hc11_special_sections): New.
+ (elf_backend_special_sections): Defined.
+
+ * elf32-mcore.c (mcore_elf_special_sections): New.
+ (elf_backend_special_sections): Defined.
+
+ * elf32-ppc.c (ppc_elf_special_sections): New.
+ (elf_backend_special_sections): Defined.
+
+ * elf32-sh64.c (sh64_elf_special_sections): New.
+ (elf_backend_special_sections): Defined.
+
+ * elf32-v850.c (v850_elf_special_sections): New.
+ (elf_backend_special_sections): Defined.
+
+ * elf32-xtensa.c (elf_xtensa_special_sections): New.
+ (elf_backend_special_sections): Defined.
+
+ * elf64-alpha.c (elf64_alpha_special_sections): New.
+ (elf_backend_special_sections): Defined.
+
+ * elf64-hppa.c (elf64_hppa_special_sections): New.
+ (elf_backend_special_sections): Defined.
+
+ * elf64-ppc.c (ppc64_elf_special_sections): New.
+ (elf_backend_special_sections): Defined.
+
+ * elf64-sh64.c (sh64_elf64_special_sections): New.
+ (elf_backend_special_sections): Defined.
+
+ * elfxx-ia64.c (elfNN_ia64_special_sections): New.
+ (elf_backend_special_sections): Defined.
+
+ * elfxx-mips.c (_bfd_mips_elf_special_sections): New.
+
+ * elfxx-mips.h (_bfd_mips_elf_special_sections): New.
+ (elf_backend_special_sections): Defined.
+
+ * elfxx-target.h (elf_backend_special_sections): New. Default
+ to NULL.
+ (elfNN_bed): Initialize special_sections.
+
+ * section.c (bfd_abs_section): Remove const.
+ (bfd_und_section): Likewise.
+ (bfd_com_section): Likewise.
+ (bfd_ind_section): Likewise.
+
+2003-07-24 Nick Clifton <nickc@redhat.com>
+
+ * coff-arm.c (EXTRA_S_FLAGS): Include SEC_CODE so that code
+ sections are assigned the LOAD attribute.
+
+2003-07-25 Kaz Kojima <kkojima@rr.iij4u.or.jp>
+
+ * elf32-sh.c: Convert to C90. Replace PTR with void *.
+ * elf32-sh64-com.c: Likewise.
+ * elf32-sh64.c: Likewise.
+ * elf32-sh64.h: Likewise.
+ * elf64-sh64.c: Likewise.
+
+2003-07-24 Kaz Kojima <kkojima@rr.iij4u.or.jp>
+
+ * elf32-sh.c (sh_elf_adjust_dynamic_symbol): Use SYMBOL_CALLS_LOCAL.
+ (allocate_dynrelocs): Likewise.
+ (sh_elf_relocate_section): Likewise. Use SYMBOL_REFERENCES_LOCAL.
+ (sh_elf_finish_dynamic_symbol): Use SYMBOL_REFERENCES_LOCAL.
+
+2003-07-24 Nick Clifton <nickc@redhat.com>
+
+ * po/fr.po: Updated French translation.
+
+2003-07-23 Bob Wilson <bob.wilson@acm.org>
+
+ * elf32-xtensa.c (xtensa_elf_dynamic_symbol_p): Make inline and move
+ near the beginning of the file. Swap order of arguments. Call
+ _bfd_elf_dynamic_symbol_p with "ignore_protected" set to 0.
+ (elf_xtensa_fix_refcounts): Adjust xtensa_elf_dynamic_symbol_p call.
+ (elf_xtensa_relocate_section): Likewise.
+ (shrink_dynamic_reloc_sections): Likewise.
+
+2003-07-23 Bob Wilson <bob.wilson@acm.org>
+
+ * elf32-xtensa.c (plt_reloc_count): Fix typo in comment.
+ (elf_xtensa_size_dynamic_sections): Use elf_discarded_section.
+ (elf_xtensa_combine_prop_entries): Avoid returning non-zero without
+ first printing an error message.
+ (elf_xtensa_finish_dynamic_sections): Likewise.
+ (elf_xtensa_discard_info_for_section): Adjust size of .got.loc when
+ discarding literal table entries.
+ (elf_xtensa_merge_private_bfd_data): Remove newline from error message.
+ (elf_xtensa_do_asm_simplify): Likewise.
+
+2003-07-23 Stephane Carrez <stcarrez@nerim.fr>
+
+ * elf32-m68hc1x.c (elf32_m68hc11_size_stubs): Avoid crash when
+ we have a local symbol in common section.
+
+2003-07-22 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elflink.c (_bfd_elf_dynamic_symbol_p): Don't return TRUE for
+ weak symbols.
+
+2003-07-22 Nick Clifton <nickc@redhat.com>
+
+ * coffcode.h (coff_slurp_symbol_table): Add C_TCSYM and C_ECOML to
+ expected RS6000 storage classes.
+
+2003-07-21 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elfxx-ia64.c (elfNN_ia64_size_dynamic_sections): Mark
+ output_bfd unused to silence gcc.
+
+2003-07-21 Nick Clifton <nickc@redhat.com>
+
+ * po/sv.po: Updated Swedish translation.
+
+2003-07-21 Alan Modra <amodra@bigpond.net.au>
+
+ * elf-bfd.h (SYMBOL_REFERENCES_LOCAL, SYMBOL_CALLS_LOCAL): Use..
+ (_bfd_elf_symbol_refs_local_p): ..this. Declare.
+ * elflink.c (_bfd_elf_symbol_refs_local_p): New function.
+ * elf32-i386.c (elf_i386_relocate_section): Remove h NULL test
+ now done in _bfd_elf_symbol_refs_local_p.
+ * elf32-ppc.c (ppc_elf_relocate_section): Likewise.
+ * elf64-ppc.c (ppc64_elf_relocate_section): Likewise.
+ * elf64-x86-64.c (elf64_x86_64_relocate_section): Likewise.
+
+2003-07-18 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elflink.c (_bfd_elf_dynamic_symbol_p): Undo the last change.
+
+2003-07-18 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf-bfd.h (SYMBOL_REFERENCES_LOCAL): Fix a typo.
+ (SYMBOL_CALLS_LOCAL): Likewise.
+
+ * elflink.c (_bfd_elf_dynamic_symbol_p): Return TRUE
+ immediately if symbol isn't defined locally.
+
+2003-07-18 Richard Henderson <rth@redhat.com>
+
+ * elflink.c (_bfd_elf_dynamic_symbol_p): New.
+ * elf-bfd.h (_bfd_elf_dynamic_symbol_p): Declare it.
+ (SYMBOL_REFERENCES_LOCAL, SYMBOL_CALLS_LOCAL): Use it.
+ * elf32-xtensa.c (xtensa_elf_dynamic_symbol_p): Likewise.
+ * elf64-alpha.c (alpha_elf_dynamic_symbol_p): Likewise.
+ * elf64-hppa.c (elf64_hppa_dynamic_symbol_p): Likewise.
+ * elfxx-ia64.c (elfNN_ia64_dynamic_symbol_p): Likewise.
+ Update all callers to provide the relocation being resolved.
+
+2003-07-17 Shaun Jackman <sjackman@pathwayconnect.com>
+
+ * config.bfd (arm-wince-pe): Add -DARM_COFF_BUGFIX to
+ targ_cflags.
+
+2003-07-17 Nick Clifton <nickc@redhat.com>
+
+ * po/es.po: New Spanish translation.
+ * po/sv.po: New Swedish translation.
+ * po/opcodes.pot: Regenerate.
+
+2003-07-16 Richard Henderson <rth@redhat.com>
+
+ * config.bfd, configure.host, configure.in: Remove ia64-aix support.
+ * elfxx-ia64.c, targets.c: Likewise.
+
+2003-07-16 Richard Henderson <rth@redhat.com>
+
+ * elfxx-ia64.c (elfNN_ia64_dynamic_symbol_p): Properly return false
+ for symbols defined locally plus -Bsymbolic. Tidy logic.
+
+2003-07-15 Richard Sandiford <rsandifo@redhat.com>
+
+ * archures.c (bfd_mach_mips7000): New.
+ * bfd-in2.h: Regenerated.
+ * cpu-mips.c (arch_info_struct): Add an entry for mips:7000.
+ * elfxx-mips.c (mips_set_isa_flags): Handle bfd_mach_mips7000.
+ (mips_mach_extensions): Add an entry for it.
+
+2003-07-14 Nick Clifton <nickc@redhat.com>
+
+ * po/tr.po: Update with latest version.
+ * po/SRC-POTFILES.in: Regenerate.
+ * po/bfd.pot: Regenerate.
+ * Makfile.in: Regenerate.
+ * configure: Regenerate.
+
+2003-07-12 Jeff Baker <jbaker@qnx.com>
+
+ * config.bfd (__QNXTARGET__): Define for Neutrino architectures.
+ * elf32-arm.h (ELF_MAXPAGESIZE): Set to 4k for Neutrino.
+ * elf32-sh.c (ELF_MAXPAGESIZE): Set to 4k for Neutrino.
+ * elf32-ppc.c (ELF_MAXPAGESIZE): Set to 4k for Neutrino.
+
+2003-07-12 Jeff Muizelaar <muizelaar@rogers.com>
+
+ * coffcode.h (coff_set_section_contents): Set the
+ IMAGE_FILE_32BIT_MACHINE flag for PE targets.
+
+2003-07-11 Richard Sandiford <rsandifo@redhat.com>
+
+ * bfd-in.h (bfd_h8300_pad_address): Declare.
+ * bfd-in2.h: Regenerate.
+ * cpu-h8300.c (bfd_h8300_pad_address): New function.
+ * coff-h8300.c (h8300_reloc16_estimate): Use it to canonicalize
+ addresses before checking whether they can be relaxed.
+ (h8300_reloc16_extra_cases): Likewise for the R_MOVL2 sanity check.
+ Don't complain about overflows in general 8-bit relocations.
+ * elf32-h8300.c (elf32_h8_relax_section): Use bfd_h8300_pad_address.
+ Fix handling of R_H8_DIR24A8.
+
+2003-07-11 Richard Sandiford <rsandifo@redhat.com>
+
+ * elf32-h8300.c: Convert function prototypes and definitions
+ to C90 syntax.
+ * coff-h8300.c: Likewise.
+ * cpu-h8300.c: Likewise.
+
+2003-07-11 Alan Modra <amodra@bigpond.net.au>
+
+ * po/SRC-POTFILES.in: Regenerate.
+ * po/bfd.pot: Likewise.
+
+2003-07-10 Bob Wilson <bob.wilson@acm.org>
+
+ * elf32-xtensa.c (elf_xtensa_create_dynamic_sections): Create new
+ .got.loc section. Do not set SEC_ALLOC or SEC_LOAD flags for the
+ .xt.lit.plt section.
+ (elf_xtensa_size_dynamic_sections): Set size of the .got.loc section
+ and allocate memory for it.
+ (elf_xtensa_combine_prop_entries): Copy contents of .xt.lit output
+ section to the .got.loc section.
+ (elf_xtensa_finish_dynamic_sections): Fix up call to
+ elf_xtensa_combine_prop_entries and set DT_XTENSA_GOT_LOC_OFF to
+ the address of .got.loc.
+ (relax_property_section): Shrink .got.loc to match changes in any
+ literal table section.
+ (xtensa_is_property_section): Change to match
+ xtensa_get_property_section_name.
+ (xtensa_is_littable_section): New.
+
+2003-07-10 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elfxx-ia64.c (IA64_HOWTO): Set dst_mask to -1 instead of
+ -1LL.
+
+2003-07-10 Alan Modra <amodra@bigpond.net.au>
+
+ * Makefile.am (BFD32_BACKENDS): Add elf32-am33lin.lo.
+ (BFD32_BACKENDS_CFILES): elf32-am33lin.c not elf32-am33lin.lo.
+ Run "make dep-am".
+ * Makefile.in: Regenerate.
+
+2003-07-10 Alexandre Oliva <aoliva@redhat.com>
+
+ 2001-09-12 Alexandre Oliva <aoliva@redhat.com>
+ * elf32-am33lin.c (ELF_MACHINE_CODE): Redefine to EM_MN10300.
+ (ELF_MACHINE_ALT1): Define to EM_CYGNUS_MN10300.
+ 2001-06-02 Nick Clifton <nickc@cambridge.redhat.com>
+ * elf32-am33lin.c: Rename global functions.
+ 2001-05-09 Alexandre Oliva <aoliva@redhat.com>
+ * config.bfd (am33_2.0, am33_2.0-*-linux*): Added.
+ * configure.in (bfd_elf32_am33lin_vec): Added.
+ * Makefile.am (BFD32_BACKENDS): Added elf32-am33lin.lo.
+ (elf32-am33lin.lo): List dependencies.
+ * aclocal.m4, configure, Makefile.in: Rebuilt.
+ * elf-m10300.c (TARGET_LITTLE_SYM, TARGET_LITTLE_NAME,
+ ELF_ARCH, ELF_MACHINE_CODE, ELF_MAXPAGESIZE): Define only if
+ ELF_ARCH was not defined before.
+ (elf_symbol_leading_char): Define if not defined.
+ * elf32-am33lin.c: Override the definitions above.
+ * targets.c (bfd_elf32_am33lin_vec): New.
+
+2003-07-09 Alexandre Oliva <aoliva@redhat.com>
+
+ 2002-12-12 Alexandre Oliva <aoliva@redhat.com>
+ * elf-m10300.c (elf32_mn10300_link_hash_newfunc): Initialize
+ pcrel_relocs_copied.
+ 2001-12-13 Alexandre Oliva <aoliva@redhat.com>
+ * elf-m10300.c (ELF_DYNAMIC_INTERPRETER): Renamed from
+ ld-linux.so.2 to ld.so.1.
+ 2001-10-10 Alexandre Oliva <aoliva@redhat.com>
+ * elf-m10300.c (elf_mn10300_sizeof_plt0): New macro.
+ (_bfd_mn10300_elf_adjust_dynamic_symbol): Use it.
+ (_bfd_mn10300_elf_finish_dynamic_symbol): Likewise.
+ * elf-m10300.c (_bfd_mn10300_elf_size_dynamic_sections): Allocate
+ .rela.* section contents with bfd_zalloc.
+ 2001-09-25 Alexandre Oliva <aoliva@redhat.com>
+ * elf-m10300.c: Added declarations for functions missing them.
+ Merge some shared-library changes from the i386 back-end. Use
+ R_MN10300_RELATIVE instead of R_MN10300_PCREL32 and
+ R_MN10300_GLOB_DAT instead of R_MN10300_32 where appropriate.
+ (struct elf32_mn10300_link_hash_entry): Remove duplicates of
+ members of elf_link_hash_entry. Adjusted references.
+ (mn10300_elf_final_link_relocate): dynobj was already loaded
+ into a local variable, use it.
+ 2001-09-21 Nick Clifton <nickc@cambridge.redhat.com>
+ * elf-m10300.c: Add missing function prototypes.
+ 2001-08-24 Alexandre Oliva <aoliva@redhat.com>
+ * elf-m10300.c (mn10300_elf_relocate_section): Don't compute
+ relocation for dynamic relocations.
+ 2001-05-16 Alexandre Oliva <aoliva@redhat.com>
+ * reloc.c (BFD_RELOC_MN10300_GOTOFF24): New.
+ * elf-m10300.c: Introduce GOTPC16, GOTOFF24, GOTOFF16 and
+ PLT16, and rename GOTPC to GOTPC32 and GOTOFF to GOTOFF32.
+ (_bfd_mn10300_elf_create_dynamic_sections): Move creation ot PLT...
+ (_bfd_mn10300_elf_create_got_section): ... here, so that its
+ adress is already known at the time we compute relaxations.
+ (mn10300_elf_relax_section): Relax GOTPC32, GOTOFF32, GOT32
+ and PLT32 to narrower relocations.
+ * libbfd.h, bfd-in2.h: Rebuilt.
+ 2001-04-12 Alexandre Oliva <aoliva@redhat.com>
+ * reloc.c (BFD_RELOC_MN10300_GOT32, BFD_RELOC_MN10300_GOT24,
+ BFD_RELOC_MN10300_GOT16, BFD_RELOC_MN10300_COPY,
+ BFD_RELOC_MN10300_GLOB_DAT, BFD_RELOC_MN10300_JMP_SLOT,
+ BFD_RELOC_MN10300_RELATIVE): New relocs.
+ * libbfd.h, bfd-in2.h: Rebuilt.
+ * elf-m10300.c (struct elf_mn10300_pcrel_relocs_copied): New.
+ (struct elf32_mn10300_link_hash_entry): Added DSO-related
+ fields.
+ (elf_mn10300_howto): Defined new relocation types.
+ (mn10300_reloc_map): Map them.
+ (_bfd_mn10300_elf_create_got_section): New fn.
+ (mn10300_elf_check_relocs): Handle PIC relocs.
+ (mn10300_elf_final_link_relocate): Likewise.
+ (mn10300_elf_relocate_section): Handle DSOs.
+ (PLT0_ENTRY_SIZE, PLT_ENTRY_SIZE, PIC_PLT_ENTRY_SIZE): New macros.
+ (elf_mn10300_plt0_entry, elf_mn10300_plt_entry,
+ elf_mn10300_pic_plt_entry): New.
+ (elf_mn10300_sizeof_plt, elf_mn10300_plt_plt0_offset,
+ elf_mn10300_plt0_linker_offset, elf_mn10300_plt0_gotid_offset,
+ elf_mn10300_plt_temp_offset, elf_mn10300_plt_symbol_offset,
+ elf_mn10300_plt_reloc_offset: New macros.
+ (ELF_DYNAMIC_INTERPRETER): Likewise.
+ (_bfd_mn10300_elf_create_dynamic_sections): New function.
+ (_bfd_mn10300_elf_adjust_dynamic_symbol): Likewise.
+ (_bfd_mn10300_elf_discard_copies): Likewise.
+ (_bfd_mn10300_elf_size_dynamic_sections): Likewise.
+ (_bfd_mn10300_elf_finish_dynamic_symbol): Likewise.
+ (_bfd_mn10300_elf_finish_dynamic_sections): Likewise.
+ (elf_backend_can_gc_sections,
+ elf_backend_create_dynamic_sections,
+ elf_backend_adjust_dynamic_sections,
+ elf_backend_size_dynamic_sections,
+ elf_backend_finish_dynamic_symbol,
+ elf_backend_finish_dynamic_sections, elf_backend_want_got_plt,
+ elf_backend_plt_readonly, elf_backend_want_plt_sym,
+ elf_backend_got_header_size, elf_backend_plt_header_size): New
+ macros.
+
+2003-07-09 Alexandre Oliva <aoliva@redhat.com>
+
+ 2001-05-06 Alexandre Oliva <aoliva@redhat.com>
+ * elf-m10300.c (compute_function_info): Account for AM33
+ registers in `movm' when computing stack space for `call' when
+ linking for AM33/2.0 link.
+ 2000-04-01 Alexandre Oliva <aoliva@cygnus.com>
+ * archures.c (bfd_mach_am33_2): Renamed from bfd_mach_am332.
+ * bfd-in2.h: Rebuilt.
+ * cpu-m10300.c (bfd_am33_2_arch): Renamed from bfd_am332_arch.
+ * elf-m10300.c: Updated.
+ 2000-03-31 Alexandre Oliva <aoliva@cygnus.com>
+ * archures.c (bfd_mach_am332): Defined.
+ * bfd-in2.h: Rebuilt.
+ * cpu-m10300.c (bfd_am332_arch): Defined.
+ (bfd_am33_arch): Chained with am33-2.
+ * elf-m10300.c (elf_mn10300_mach): Handle am332.
+ (_bfd_mn10300_elf_final_write_processing): Likewise.
+
+2003-07-09 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elfxx-ia64.c (IA64_HOWTO): Set dst_mask to -1LL.
+
+2003-07-10 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (bfd_elf64_mkobject): Define.
+ (struct ppc64_elf_obj_tdata): New.
+ (ppc64_elf_tdata, ppc64_tlsld_got): Define.
+ (ppc64_elf_mkobject): New function.
+ (struct got_entry): Add "owner". Move "tls_type".
+ (struct ppc_link_hash_table): Delete "relgot", "tlsld_got".
+ (ppc64_elf_init_stub_bfd): New function.
+ (create_got_section): Create header .got in dynobj. Create .got
+ and .rela.got in each bfd. Stash pointers in ppc64_elf_obj_tdata.
+ (ppc64_elf_create_dynamic_sections): Don't call create_got_section.
+ Look for dynobj .got, and test it.
+ (ppc64_elf_copy_indirect_symbol): Adjust for changed got.
+ (update_local_sym_info): Likewise.
+ (ppc64_elf_check_relocs): Likewise.
+ (ppc64_elf_gc_sweep_hook): Likewise.
+ (ppc64_elf_tls_optimize): Likewise.
+ (allocate_dynrelocs): Likewise.
+ (ppc64_elf_size_dynamic_sections): Likewise.
+ (ppc64_elf_relocate_section): Likewise.
+ (ppc64_elf_next_toc_section): Update comment.
+ (toc_adjusting_stub_needed): Remove unneeded cast.
+ (ppc64_elf_build_stubs): Check for stub sections in stub bfd by
+ testing section flags.
+ (ppc64_elf_build_stubs): Likewise.
+ (ppc64_elf_size_stubs): Likewise. Remove stub_bfd param.
+ (ppc64_elf_finish_dynamic_sections): Write out got sections.
+ (func_desc_adjust): Copy over dynamic info for undef weaks.
+ * elf64-ppc.h (ppc64_elf_init_stub_bfd): Declare.
+ (ppc64_elf_size_stubs): Update prototype.
+ * elflink.h (elf_link_sort_relocs): Use link_orders to find reldyn
+ input sections rather than scanning dynobj.
+
+2003-07-09 Richard Sandiford <rsandifo@redhat.com>
+
+ * elfxx-mips.c (mips_elf_link_hash_entry): Remove min_dyn_reloc_index.
+ (bfd_mips_elf_swap_msym_in, bfd_mips_elf_swap_msym_out): Delete.
+ (mips_elf_create_msym_section): Delete.
+ (mips_elf_create_dynamic_relocation): Don't set min_dyn_reloc_index.
+ (_bfd_mips_elf_copy_indirect_symbol): Likewise.
+ (_bfd_mips_elf_create_dynamic_sections): Don't create .msym.
+ (_bfd_mips_elf_size_dynamic_sections): Don't calculate its size.
+ (_bfd_mips_elf_size_dynamic_sections): Don't add DT_MIPS_MSYM.
+ (_bfd_mips_elf_finish_dynamic_symbol): Don't add symbols to .msym.
+ (_bfd_mips_elf_finish_dynamic_sections): Likewise.
+
+2003-07-09 Richard Sandiford <rsandifo@redhat.com>
+
+ * elfxx-mips.c (mips_elf_irix6_finish_dynamic_symbol): Make the
+ symbols protected.
+
+2003-07-09 Richard Sandiford <rsandifo@redhat.com>
+
+ * elfxx-mips.c (mips_elf_create_dynamic_relocation): Fix handling
+ of relocations whose offset is -2.
+
+2003-07-09 Richard Sandiford <rsandifo@redhat.com>
+
+ * elfxx-mips.c (mips_elf_create_dynamic_relocation): Treat
+ forced-local symbols like other locals. Don't create relocations
+ against STN_UNDEF in irix objects.
+
+2003-07-09 Richard Sandiford <rsandifo@redhat.com>
+
+ * elfxx-mips.c (mips_elf_create_dynamic_relocation): In SGI-
+ compatible objects, add the values of defined external symbols
+ to the addend.
+
+2003-07-09 Richard Sandiford <rsandifo@redhat.com>
+
+ * elfxx-mips.c (_bfd_mips_elf_finish_dynamic_symbol): Always
+ initialize a GOT entry to the symbol's st_value.
+
+2003-07-08 Alan Modra <amodra@bigpond.net.au>
+
+ * elf-bfd.h (struct elf_obj_tdata): Move linker_section_pointers..
+ * elf32-ppc.c (struct ppc_elf_obj_tdata): ..to here. New.
+ (ppc_elf_tdata): Define.
+ (elf_local_ptr_offsets): Adjust.
+ (ppc_elf_mkobject): New function.
+ (bfd_elf32_mkobject): Define.
+
+ * elfcode.h (elf_object_p): Allocate tdata via _bfd_set_format.
+ * elfcore.h (elf_core_file_p): Likewise.
+ * section.c (bfd_section_init): Remove prototype.
+
+2003-07-08 Alan Modra <amodra@bigpond.net.au>
+
+ * elf-bfd.h (struct elf_link_hash_entry): Remove linker_section_pointer
+ field.
+ (enum elf_linker_section_enum): Delete.
+ (struct elf_linker_section): Delete.
+ (struct elf_linker_section_pointers): Delete.
+ (struct elf_obj_tdata): Remove #if 0 chunk. Remove linker_section.
+ Make linker_section_pointers a void**.
+ (elf_local_ptr_offsets, elf_linker_section): Don't define.
+ * elf32-ppc.c (enum elf_linker_section_enum): New, cut-down version
+ of old item in elf-bfd.h.
+ (struct elf_linker_section): Likewise.
+ (struct elf_linker_section_pointers): Likewise.
+ (elf_local_ptr_offsets): Define.
+ (struct ppc_elf_link_hash_entry): Add linker_section_pointer.
+ (ppc_elf_link_hash_newfunc): Init it.
+ (struct ppc_elf_link_hash_table): Add sbss.
+ (ppc_elf_link_hash_table_create): zmalloc rather than clearing
+ individual fields.
+ (elf_create_linker_section): Fold into..
+ (ppc_elf_create_linker_section): ..here. Remove hole_size code.
+ Make rela section here if shared.
+ (elf_find_pointer_linker_section): Pass lsect rather than enum.
+ (elf_create_pointer_linker_section): Adjust. zalloc rather than
+ clearing in a loop.
+ (elf_finish_pointer_linker_section): Adjust. Don't make rela
+ section here.
+ (ppc_elf_check_relocs): Adjust.
+ (ppc_elf_add_symbol_hook): Tighten hash creator test. Remove code
+ creating .sbss by hand.
+ * elf.c (_bfd_elf_link_hash_newfunc): Adjust.
+
+2003-07-04 Jakub Jelinek <jakub@redhat.com>
+
+ * elf32-s390.c (elf_howto_table): Change R_390_GOT12 to
+ complain_overflow_bitfield.
+ * elf64-s390.c (elf_howto_table): Change R_390_GOT12 to
+ complain_overflow_bitfield.
+
+2003-07-04 Jakub Jelinek <jakub@redhat.com>
+
+ * elf-bfd.h (SYMBOL_REFERENCES_LOCAL, SYMBOL_CALLS_LOCAL): Return
+ true even if -pie.
+
+2003-07-04 Jakub Jelinek <jakub@redhat.com>
+
+ * elfxx-ia64.c (struct elfNN_ia64_link_hash_table): Add rel_fptr_sec.
+ (elfNN_ia64_dynamic_symbol_p): Change info->shared into
+ !info->executable.
+ (get_fptr): For -pie create .opd as writable section and create
+ .rela.opd as well.
+ (elfNN_ia64_check_relocs): Change info->shared into
+ !info->executable.
+ (allocate_fptr): Likewise.
+ (allocate_dynrel_entries): Account for a relative reloc for -pie
+ @fptr(). Don't account for a relative reloc if -pie want_ltoff_fptr
+ for undefweak symbol. Account for an IPLT reloc in .rela.opd
+ section if -pie.
+ (set_got_entry): Don't create a relative reloc if -pie
+ want_ltoff_fptr for undefweak symbol.
+ (set_fptr_entry): Emit an IPLT reloc in .rela.opd for -pie.
+ (elfNN_ia64_relocate_section): Emit a relative reloc for -pie
+ @fptr().
+
+ * elfxx-ia64.c (elfNN_ia64_relocate_section): Issue undefined_symbol
+ even if -pie.
+ * elf32-i386.c (elf_i386_relocate_section): Likewise.
+ * elf64-x86-64.c (elf64_x86_64_relocate_section): Likewise.
+ * elf64-sparc.c (sparc64_elf_relocate_section): Likewise.
+ * elf64-s390.c (elf_s390_relocate_section): Likewise.
+ * elf64-ppc.c (ppc64_elf_relocate_section): Likewise.
+ * elf64-alpha.c (elf64_alpha_relocate_section): Likewise.
+ * elf32-sparc.c (elf32_sparc_relocate_section): Likewise.
+ * elf32-s390.c (elf_s390_relocate_section): Likewise.
+ * elf32-ppc.c (ppc_elf_relocate_section): Likewise.
+
+2003-07-04 Paul Clarke <paulc@senet.com.au>
+
+ * elf32-h8300.c (R_H8_DIR32A16): Fix name field.
+ (elf32_h8_relax_section) <R_H8_DIR16A8>: Adjust position of relocation.
+ <R_H8_DIR32A16>: Fix type of relocation.
+
+2003-07-04 Kaz Kojima <kkojima@rr.iij4u.or.jp>
+
+ * elf32-sh.c (sh_elf_create_dynamic_sections): Return if dynamic
+ sections were created already. Remove unnecessary tests of
+ the previous change.
+
+2003-07-04 Kaz Kojima <kkojima@rr.iij4u.or.jp>
+
+ * elf32-sh.c (sh_elf_create_dynamic_sections): Don't call
+ bfd_make_section for existing sections.
+
+2003-07-04 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-sparc.c (elf32_sparc_check_relocs): Don't call
+ create_got_section if we already have done so.
+ * elf32-sh.c (sh_elf_create_dynamic_sections): Likewise.
+ (sh_elf_check_relocs): Likewise.
+ (sh_elf_adjust_dynamic_symbol): Delete "dynobj" var. Use
+ htab->root.dynobj instead.
+ (sh_elf_check_relocs): Likewise.
+ (sh_elf_finish_dynamic_sections): Likewise.
+
+ * section.c (bfd_make_section): Return NULL for existing section.
+
+2003-07-04 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-ppc.c (ppc_elf_create_dynamic_sections): Don't call
+ ppc_elf_create_got if we've already done so.
+
+ * elf-bfd.h (_bfd_elf_create_linker_section) Don't declare.
+ (_bfd_elf_find_pointer_linker_section): Likewise.
+ (bfd_elf32_create_pointer_linker_section): Likewise.
+ (bfd_elf32_finish_pointer_linker_section): Likewise.
+ (bfd_elf64_create_pointer_linker_section): Likewise.
+ (bfd_elf64_finish_pointer_linker_section): Likewise.
+ (_bfd_elf_make_linker_section_rela): Likewise.
+ * elfcode.h (elf_create_pointer_linker_section): Don't define.
+ (elf_finish_pointer_linker_section): Likewise.
+ * elflink.c (_bfd_elf_make_linker_section_rela): Delete.
+ (_bfd_elf_create_linker_section): Move this function..
+ (_bfd_elf_find_pointer_linker_section): ..and this..
+ * elflink.h (elf_create_pointer_linker_section): ..and this..
+ (elf_finish_pointer_linker_section): ..and this..
+ * elf32-ppc.c: ..to here, renaming to the following, and adjusting
+ calls.
+ (elf_create_linker_section): Convert to C90, tidy.
+ (elf_find_pointer_linker_section): Likewise.
+ (elf_create_pointer_linker_section): Likewise.
+ (elf_finish_pointer_linker_section): Likewise.
+ * elf32-i370.c: Delete #if 0 code.
+
+2003-07-02 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (ppc64_elf_func_desc_adjust): Don't allow _savef* and
+ _restf* to be satisfied by shared libs, and always force them local.
+ (toc_adjusting_stub_needed): Avoid scanning linker created sections.
+ Correct test for "bl".
+ (ppc64_elf_relocate_section <R_PPC64_TLS>): Correct test for
+ primary opcode 31.
+
+2003-07-01 Martin Schwidefsky <schwidefsky@de.ibm.com>
+
+ * elf32-s390.c (s390_elf_ldisp_reloc): New prototype.
+ (s390_tls_reloc): New function.
+ (elf_howto_table): Add long displacement relocations R_390_20,
+ R_390_GOT20, R_390_GOTPLT20 and R_390_TLS_GOTIE20.
+ (elf_s390_reloc_type_lookup): Likewise.
+ (elf_s390_check_relocs): Likewise.
+ (elf_s390_gc_sweep_hook): Likewise.
+ (elf_s390_relocate_section): Likewise.
+ * elf64-s390.c: Same changes as for elf32-s390.c.
+ * reloc.c: Add long displacement relocations BFD_RELOC_390_20,
+ BFD_RELOC_390_GOT20, BFD_RELOC_390_GOTPLT20 and
+ BFD_RELOC_390_TLS_GOTIE20.
+ * bfd-in2.h: Regenerate.
+ * libbfd.h: Likewise.
+
+2003-06-30 Alan Modra <amodra@bigpond.net.au>
+
+ * cpu-ia64-opc.c (ext_imms_scaled): Don't sign extend using shifts.
+ (ins_imms, ins_immsm1u4): Likewise. Warning fix.
+
+2003-06-29 Alan Modra <amodra@bigpond.net.au>
+
+ * archive.c: Convert to C90, remove unnecessary prototypes and casts.
+ Replace PTR with void *. Formatting.
+ * archive64.c: Likewise.
+ * archures.c: Likewise.
+ * bfd-in.h: Likewise.
+ * bfd.c: Likewise.
+ * bfdio.c: Likewise.
+ * bfdwin.c: Likewise.
+ * cache.c: Likewise.
+ * corefile.c: Likewise.
+ * format.c: Likewise.
+ * init.c: Likewise.
+ * libbfd-in.h: Likewise.
+ * libbfd.c: Likewise.
+ * linker.c: Likewise.
+ * opncls.c: Likewise.
+ * reloc.c: Likewise.
+ * section.c: Likewise.
+ * simple.c: Likewise.
+ * syms.c: Likewise.
+ * targets.c: Likewise.
+ * bfd-in2.h: Regenerate.
+ * libbfd.h: Regenerate.
+
+ * ecoff.c (bfd_debug_section): Add missing kept_section initialization.
+ * libbfd-in.h (_bfd_sh_align_load_span): Don't declare if defined.
+ * libbfd.c (COERCE32, EIGHT_GAZILLION): Simplify.
+ (bfd_getb64): Rewrite without parens.
+ (bfd_getl64, bfd_getb_signed_64, bfd_getl_signed_64): Likewise.
+ * cache.c (insert, snip): Remove INLINE.
+ * linker.c (bfd_link_add_undef): Likewise.
+
+2003-06-29 Andreas Jaeger <aj@suse.de>
+
+ * elf64-x86-64.c: Convert to ISO C90 prototypes, remove
+ unnecessary prototypes. Replace PTR with void *.
+ (elf64_x86_64_adjust_dynamic_symbol): Use SYMBOL_CALLS_LOCAL to
+ trim plt entries. Move undefweak non-default visibility test ...
+ (allocate_dynrelocs): ... from here.
+ (WILL_CALL_FINISH_DYNAMIC_SYMBOL): Pass SHARED instead of INFO.
+ Change all callers.
+ (allocate_dynrelocs): Use SYMBOL_CALLS_LOCAL. Use
+ SYMBOL_REFERENCES_LOCAL for dynreloc check.
+ (elf64_x86_64_relocate_section): Use SYMBOL_CALLS_LOCAL for
+ dynreloc and .got relocs.
+ (elf64_x86_64_finish_dynamic_symbol): Use SYMBOL_REFERENCES_LOCAL
+ for .got relocs.
+
+2003-06-29 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * elfxx-mips.c: Allow lazy binding for R_MIPS_JALR.
+
+2003-06-27 Nick Clifton <nickc@redhat.com>
+
+ * opncls.c (bfd_add_gnu_debuglink_section): Rename to
+ bfd_add_gnu_debuglink_section and only create the section, do not
+ fill in its contents.
+ (bfd_fill_in_gnu_debuglink_section): New function. Fill in the
+ contents of a .gnu-debuglink section.
+ * bfd-in2.h: Regenerate.
+
+2003-06-27 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * elfxx-mips.c: Revert .got alignment to 2**4.
+
+2003-06-27 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * elf32-mips.c: Fix addend for _gp_disp special symbol.
+
+2003-06-27 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * elfxx-mips.c (_bfd_mips_elf_fake_sections): Remove non-default
+ relocation header setup.
+
+2003-06-25 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-ppc.c (ppc_elf_howto_table): Remove unnecessary cast.
+ (ppc_elf_reloc_type_lookup): Modify comment.
+ (ppc_elf_info_to_howto): Ditto.
+ (ppc_elf_relocate_section): Ditto.
+ (ppc_elf_check_relocs): Call ppc_elf_howto_init.
+
+2003-06-25 Alan Modra <amodra@bigpond.net.au>
+
+ * aout-ns32k.c: Correct spelling of "relocatable".
+ * aoutx.h: Likewise.
+ * bfd-in.h: Likewise.
+ * bfd.c: Likewise.
+ * bout.c: Likewise.
+ * coff-a29k.c: Likewise.
+ * coff-alpha.c: Likewise.
+ * coff-arm.c: Likewise.
+ * coff-i386.c: Likewise.
+ * coff-i860.c: Likewise.
+ * coff-i960.c: Likewise.
+ * coff-m68k.c: Likewise.
+ * coff-m88k.c: Likewise.
+ * coff-mcore.c: Likewise.
+ * coff-mips.c: Likewise.
+ * coff-or32.c: Likewise.
+ * coff-ppc.c: Likewise.
+ * coff-rs6000.c: Likewise.
+ * coff-sh.c: Likewise.
+ * coff-tic80.c: Likewise.
+ * coff64-rs6000.c: Likewise.
+ * cofflink.c: Likewise.
+ * cpu-ns32k.c: Likewise.
+ * ecoff.c: Likewise.
+ * ecofflink.c: Likewise.
+ * elf-bfd.h: Likewise.
+ * elf-eh-frame.c: Likewise.
+ * elf-hppa.h: Likewise.
+ * elf-m10200.c: Likewise.
+ * elf-m10300.c: Likewise.
+ * elf.c: Likewise.
+ * elf32-arm.h: Likewise.
+ * elf32-avr.c: Likewise.
+ * elf32-cris.c: Likewise.
+ * elf32-d10v.c: Likewise.
+ * elf32-dlx.c: Likewise.
+ * elf32-fr30.c: Likewise.
+ * elf32-frv.c: Likewise.
+ * elf32-h8300.c: Likewise.
+ * elf32-hppa.c: Likewise.
+ * elf32-i370.c: Likewise.
+ * elf32-i386.c: Likewise.
+ * elf32-i860.c: Likewise.
+ * elf32-i960.c: Likewise.
+ * elf32-ip2k.c: Likewise.
+ * elf32-iq2000.c: Likewise.
+ * elf32-m32r.c: Likewise.
+ * elf32-m68hc11.c: Likewise.
+ * elf32-m68hc1x.c: Likewise.
+ * elf32-m68k.c: Likewise.
+ * elf32-mcore.c: Likewise.
+ * elf32-mips.c: Likewise.
+ * elf32-msp430.c: Likewise.
+ * elf32-openrisc.c: Likewise.
+ * elf32-ppc.c: Likewise.
+ * elf32-s390.c: Likewise.
+ * elf32-sh.c: Likewise.
+ * elf32-sh64.c: Likewise.
+ * elf32-sparc.c: Likewise.
+ * elf32-v850.c: Likewise.
+ * elf32-vax.c: Likewise.
+ * elf32-xstormy16.c: Likewise.
+ * elf32-xtensa.c: Likewise.
+ * elf64-alpha.c: Likewise.
+ * elf64-hppa.c: Likewise.
+ * elf64-mips.c: Likewise.
+ * elf64-mmix.c: Likewise.
+ * elf64-ppc.c: Likewise.
+ * elf64-s390.c: Likewise.
+ * elf64-sh64.c: Likewise.
+ * elf64-sparc.c: Likewise.
+ * elf64-x86-64.c: Likewise.
+ * elfcode.h: Likewise.
+ * elflink.h: Likewise.
+ * elfn32-mips.c: Likewise.
+ * elfxx-ia64.c: Likewise.
+ * elfxx-mips.c: Likewise.
+ * i386linux.c: Likewise.
+ * ieee.c: Likewise.
+ * libcoff-in.h: Likewise.
+ * linker.c: Likewise.
+ * m68klinux.c: Likewise.
+ * pdp11.c: Likewise.
+ * pe-mips.c: Likewise.
+ * peXXigen.c: Likewise.
+ * reloc.c: Likewise.
+ * reloc16.c: Likewise.
+ * sparclinux.c: Likewise.
+ * sunos.c: Likewise.
+ * syms.c: Likewise.
+ * versados.c: Likewise.
+ * vms.c: Likewise.
+ * xcofflink.c: Likewise.
+ * bfd-in2.h: Regenerate.
+ * libcoff.h: Regenerate.
+ * libbfd.h: Regenerate.
+
+2003-06-24 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-ppc.c (ppc_elf_check_relocs): Report plt reloc against
+ local sym errors.
+
+ * elf32-i386.c: Convert to C90 function definitions, remove unnecessary
+ prototypes and casts. Replace PTR with void *. Formatting.
+ * elf32-ppc.c: Likewise. Break long strings too.
+ (ppc_elf_relax_section): Use enum elf_ppc_reloc_type for r_type.
+ (ppc_elf_unhandled_reloc): Internationalize error message.
+ * elf32-ppc.h: Remove PARAMS.
+
+2003-06-23 Mark Mitchell <mark@codesourcery.com>
+
+ * elf32-ppc.c (ppc_elf_begin_write_processing): Use bytes to count
+ APUinfo slots.
+ (ppc_elf_final_write_processing): Likewise.
+
+2003-06-23 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elflink.h (elf_link_input_bfd): Check raw size when using
+ kept_section to preserve debug information discarded by
+ linkonce.
+
+2003-06-20 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (struct ppc_link_hash_table): Add top_id.
+ (ppc64_elf_setup_section_lists): Set it.
+ (ppc64_elf_relocate_section): Check sym section id against top_id.
+ (ppc_build_one_stub): Comment on top_id.
+
+2003-06-20 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * config.bfd: Add tic4x-*-rtems*.
+
+2003-06-20 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c: Convert to C90 function definitions, remove unnecessary
+ prototypes and casts. Replace PTR with void *. Format copyright.
+ Mention ABI links.
+ (struct ppc_link_hash_table): Rename sgot, srelgot, splt, srelplt,
+ sdynbss, srelbss, sglink, sbrlt and srelbrlt to got, relgot .. relbrlt.
+ (ppc_type_of_stub): Make r_type an enum.
+ (ppc64_elf_size_stubs): Likewise.
+ * elf64-ppc.h: Remove PARAMS macro.
+
+2003-06-19 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (ppc64_elf_link_hash_table_create): Reinstate init of
+ elf hash tab fields.
+
+ * elf64-ppc.c (ppc64_elf_reloc_type_lookup): Tidy prototype.
+ (ppc64_elf_info_to_howto): Likewise.
+ (ppc64_elf_build_stubs): Add "stats" param, and print statistics.
+ * elf64-ppc.h (ppc64_elf_build_stubs): Adjust prototype.
+
+2003-06-19 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-sparc.c (sparc64_elf_relocate_section): Ignore R_SPARC_DISP32
+ reloc overflow on discarded eh_frame entries.
+
+2003-06-19 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (toc_adjusting_stub_needed): New function.
+ (ppc64_elf_next_input_section): Use it here to set has_gp_reloc.
+ Return error condition.
+ (ppc64_elf_size_stubs): Restrict toc adjusting stubs to sections
+ that have has_gp_reloc set.
+ (struct ppc_link_hash_table): Add stub_count.
+ (ppc_build_one_stub): Increment it.
+ (ppc64_elf_link_hash_table_create): zmalloc rather than clearing
+ individual fields.
+ * elf64-ppc.h (ppc64_elf_next_input_section): Update prototype.
+
+2003-06-18 Alan Modra <amodra@bigpond.net.au>
+
+ * elflink.h (elf_gc_record_vtentry): Revert last change. Correct
+ size calculation from addend. Round size up.
+
+2003-06-18 Hans-Peter Nilsson <hp@axis.com>
+
+ * elf32-cris.c (cris_elf_relocate_section) <case
+ R_CRIS_32_GOTREL>: When linking a program, don't complain about a
+ symbol from a normal object or an undefined weak symbol.
+
+2003-06-18 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (ppc64_elf_relocate_section): Accept a symbol on
+ R_PPC64_TOC relocs.
+
+2003-06-17 H.J. Lu <hongjiu.lu@intel.com>
+
+ * section.c (struct sec): Put back kept_section.
+ (STD_SECTION): Put back kept_section initialization.
+ * bfd-in2.h: Regenerate.
+
+ * elflink.h (elf_link_input_bfd): Also check discarded linkonce
+ sections for relocateable output. Use kept_section to preserve
+ debug information discarded by linkonce.
+
+2003-06-17 Roland McGrath <roland@redhat.com>
+
+ * elfxx-ia64.c (elfNN_ia64_relocate_section): Support
+ segment-relative relocation between different segments.
+
+2003-06-17 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (ppc64_elf_relocate_section): Do unaligned reloc
+ optimizations earlier.
+
+ * elf64-ppc.c (struct ppc_link_hash_table): Reinstate top_index.
+ Restore previous input_list type.
+ (ppc64_elf_link_hash_table_create): Undo last change.
+ (ppc64_elf_setup_section_lists): Reinstate code setting up input lists
+ per output section, but don't bother with bfd_abs_section marker.
+ (ppc64_elf_next_input_section): Adjust for multiple input section
+ lists.
+ (group_sections): Likewise.
+
+2003-06-17 Jakub Jelinek <jakub@redhat.com>
+
+ * elf64-ppc.c (ppc64_elf_relocation_section): Ensure
+ *r_offset == r_addend for RELATIVE relocs against .got.
+
+2003-06-17 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (ppc64_elf_relocate_section): Optimize unaligned relocs.
+
+2003-06-17 Nick Clifton <nickc@redhat.com>
+
+ * elflink.h (elf_gc_record_vtentry): Allocate an extra element
+ in the vtable_entries_used array to allow for the accessing
+ the largest element.
+
+2003-06-17 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (struct ppc_link_hash_table): Remove top_index. Modify
+ input_list.
+ (ppc64_elf_link_hash_table_create): Init input_list here.
+ (ppc64_elf_setup_section_lists): Remove code setting up input lists
+ per output section. Set toc_off for abs and other standard sections.
+ (ppc64_elf_reinit_toc): Don't set elf_gp on input bfds lacking a toc.
+ (ppc64_elf_next_input_section): Adjust for single input section list.
+ Don't set toc_curr from input bfds that haven't set elf_gp.
+ (group_sections): Adjust for single input section list.
+
+ * elf64-ppc.c (ppc64_elf_relocate_section): Correct pcrel section zero.
+
+2003-06-16 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (ppc64_elf_relocate_section): When optimizing toctprel
+ tls, check that a TOC16_DS or TOC16_LO_DS reloc isn't pointing to a
+ dtprel entry. Ensure TLS_LD DTPMOD reloc has a zero addend. Write
+ got section for RELATIVE relocs. Fix wrong comment. Change condition
+ under which dynamic relocs update the section contents.
+
+2003-06-13 Robert Millan <zeratul2@wanadoo.es>
+
+ * config.bfd: Add i386-netbsd-gnu target.
+
+2003-06-12 Nick Clifton <nickc@redhat.com>
+
+ * opncls.c (calc_crc32): Rename to
+ bfd_calc_gnu_debuglink_crc32 and export.
+ (GNU_DEBUGLINK): Define and use to replace occurrences of
+ hard-coded ".gnu_debuglink" in the code.
+ (get_debug_link_info): Prevent aborts by replacing call to
+ xmalloc with a call to malloc.
+ (find_separate_debug_file): Prevent aborts by replacing calls
+ to xmalloc and xstrdup with calls to malloc and strdup.
+ (bfd_add_gnu_debuglink): New function. Add a .gnu_debuglink
+ section to a bfd.
+ * bfd-in2.h: Regenerate.
+
+2003-06-12 Federico G. Schwindt <fgsch@lodoss.net>
+
+ * config.bfd (i[3-7]86-*-openbsd[0-2].* | i[3-7]86-*-openbsd3.[0-3]):
+ New target (was i[3-7]86-*-openbsd* before).
+ (i[3-7]86-*-openbsd*): Change to use bfd_elf32_i386_vec.
+ (vax-*-openbsd*): New target.
+
+2003-06-11 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * elfxx-mips.c (MIPS_ELF_OPTIONS_SECTION_NAME): Use .MIPS.options
+ for n32, too.
+ (MIPS_ELF_STUB_SECTION_NAME): Use .MIPS.stubs for n32, too.
+ (mips_elf_rel_dyn_section): Use appropriate section alignment.
+ (mips_elf_create_got_section): Likewise.
+ (_bfd_mips_elf_create_dynamic_sections): Likewise.
+
+2003-06-11 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * elf32-mips.c (mips_elf_generic_reloc): New Function.
+ (elf_mips_howto_table_rel): Use it.
+ (gprel32_with_gp): Move prototype.
+ (mips_elf_hi16_reloc): Check for ! BSF_LOCAL instead of zero addend.
+ Use mips_elf_generic_reloc.
+ (mips_elf_got16_reloc): Check for ! BSF_LOCAL instead of zero addend.
+ Code cleanup.
+ (_bfd_mips_elf32_gprel16_reloc): Check for ! BSF_LOCAL instead of
+ zero addend.
+ (mips_elf_gprel32_reloc): Likewise. Use the same GP assignment logic
+ as in the other *_gprel*_reloc functions.
+ (gprel32_with_gp): Handle partial_inplace properly.
+ (mips32_64bit_reloc): Use mips_elf_generic_reloc.
+ (mips16_gprel_reloc): Check for ! BSF_LOCAL instead of zero addend.
+ Do addend handling directly instead of calling
+ _bfd_mips_elf_gprel16_with_gp. Handle partial_inplace properly.
+ * elf64-mips.c (mips_elf64_hi16_reloc): Check for ! BSF_LOCAL instead
+ of zero addend. Handle partial_inplace properly.
+ (mips_elf64_got16_reloc): Check for ! BSF_LOCAL instead of zero
+ addend.
+ (mips_elf64_gprel16_reloc): Likewise.
+ (mips_elf64_literal_reloc): Likewise.
+ (mips_elf64_gprel32_reloc): Likewise. Use the same GP assignment
+ logic as in the other *_gprel*_reloc functions. Handle
+ partial_inplace properly.
+ (mips_elf64_shift6_reloc): Check for ! BSF_LOCAL instead of zero
+ addend. Handle partial_inplace properly.
+ (mips16_gprel_reloc): Likewise. Do addend handling directly instead
+ of calling _bfd_mips_elf_gprel16_with_gp.
+ * elfn32-mips.c (mips_elf_got16_reloc): Check for BSF_LOCAL.
+ (mips_elf_gprel32_reloc): Check for ! BSF_LOCAL instead
+ of zero addend.
+ (mips_elf_shift6_reloc): Handle partial_inplace properly.
+ (mips16_gprel_reloc): Likewise. Do addend handling directly instead
+ of calling _bfd_mips_elf_gprel16_with_gp.
+ * elfxx-mips.c (_bfd_mips_elf_gprel16_with_gp): Handle
+ partial_inplace properly. Fix wrong addend handling. Fix overflow
+ check.
+ (_bfd_mips_elf_sign_extend): Renamed from mips_elf_sign_extend and
+ exported.
+ (mips_elf_calculate_relocation): Use _bfd_mips_elf_sign_extend.
+ (_bfd_mips_elf_relocate_section): Likewise.
+ (mips_elf_create_dynamic_relocation): Update sec_info_type access.
+ * elfxx-mips.h (_bfd_mips_relax_section): Fix prototype declaration.
+ (_bfd_mips_elf_sign_extend): New prototype.
+
+2003-06-11 Federico G. Schwindt <fgsch@lodoss.net>
+
+ * config.bfd (sparc-*-openbsd[0-2].* | sparc-*-openbsd3.[0-1]):
+ New target (was sparc-*-openbsd* before).
+ (sparc-*-openbsd*): Change to use bfd_elf32_sparc_vec.
+
+ * configure.in (vax-*-openbsd*): Set COREFILE to netbsd-core.lo.
+ * configure: Regenerate.
+
+2003-06-11 H.J. Lu <hongjiu.lu@intel.com>
+
+ * po/Make-in (DESTDIR): New.
+ (install-data-yes): Support $(DESTDIR).
+ (uninstall): Likewise.
+
+2003-06-11 Alan Modra <amodra@bigpond.net.au>
+
+ * Makefile.am (config.status): Depend on version.h.
+ Run "make dep-am".
+ * Makefile.in: Regenerate.
+ * po/SRC-POTFILES.in: Regenerate.
+
+2003-06-10 Alan Modra <amodra@bigpond.net.au>
+ Gary Hade <garyhade@us.ibm.com>
+
+ * elf64-ppc.c (ppc64_elf_relocate_section <*_DS>): Special case lq.
+
+2003-06-10 Richard Sandiford <rsandifo@redhat.com>
+
+ * archures.c (bfd_mach_h8300sxn): New architecture.
+ * bfd-in2.h: Regenerate.
+ * cpu-h8300.c (h8300_scan): Check for 'sxn'.
+ (h8300sxn_info_struct): New.
+ (h8300sx_info_struct): Link to it.
+ * elf32-h8300.c (elf32_h8_mach): Add h8300sxn case.
+ (elf32_h8_final_write_processing): Likewise.
+
+2003-06-08 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c: Move TARGET_LITTLE_SYM and other macros used by
+ elfxx-target.h so that we can use elf_backend_got_header_size.
+ (ELF_MACHINE_ALT1, ELF_MACHINE_ALT2): Delete.
+ (GLINK_CALL_STUB_SIZE): Modify. Define new glink call stub and
+ associated macros.
+ (ppc64_elf_howto_raw <GOT_TPREL16_DS, GOT_TPREL16_LO_DS>): Correct
+ dst_mask.
+ (enum ppc_stub_type): Add ppc_stub_long_branch_r2off and
+ ppc_stub_plt_branch_r2off.
+ (struct ppc_stub_hash_entry): Reorganize.
+ (struct ppc_link_hash_table): Add no_multi_toc, multi_toc_needed,
+ toc_curr, toc_off and emit_stub_syms.
+ (ppc64_elf_link_hash_table_create): Init them.
+ (ppc_stub_name): Correct string size.
+ (ppc64_elf_check_relocs): Set has_gp_reloc on GOT and TOC relocs.
+ (ppc64_elf_size_dynamic_sections): Set no_multi_toc if GOT entries
+ used.
+ (ppc_type_of_stub): Tweak root.type test.
+ (build_plt_stub): Remove glink code. Adjust for insn macro changes.
+ (ppc_size_one_stub): Handle ppc_stub_long_branch_r2off and
+ ppc_stub_plt_branch_r2off.
+ (ppc_build_one_stub): Likewise. Fix var shadowing. Correct addis,addi
+ range test. Use toc_off to calculte r2 values. Handle emit_stub_syms.
+ (ppc64_elf_setup_section_lists): Remove htab creator flavour test.
+ Initialize elf_gp and toc_curr.
+ (ppc64_elf_next_toc_section, ppc64_elf_reinit_toc): New functions.
+ (ppc64_elf_next_input_section): Set toc_off.
+ (group_sections): Ensure groups have the same TOC.
+ (ppc64_elf_size_stubs): Check whether we need a TOC adjusting stub.
+ (ppc64_elf_build_stubs): Add emit_stub_syms param, and stash in htab.
+ Build new glink stub.
+ (ppc64_elf_relocate_section): Handle multiple TOCs. Fix comments.
+ (ppc64_elf_finish_dynamic_sections): Adjust DT_PPC64_GLINK.
+ * elf64-ppc.h (ppc64_elf_build_stubs): Update prototype.
+ (ppc64_elf_next_toc_section, ppc64_elf_reinit_toc): Declare.
+ * section.c (struct sec): Rename flag12 to has_gp_reloc.
+ (STD_SECTION): Update.
+ * ecoff.c (bfd_debug_section): Update comment.
+ * bfd-in2.h: Regenerate.
+
+2003-06-05 Daniel Jacobowitz <drow@mvista.com>
+
+ * elfcode.h (elf_slurp_reloc_table_from_section): Don't dereference
+ NULL function pointers.
+
+2003-06-05 Daniel Jacobowitz <drow@mvista.com>
+
+ * simple.c (bfd_simple_get_relocated_section_contents): Call
+ _bfd_generic_link_add_symbols instead of bfd_link_add_symbols.
+
+2003-06-04 Svein E. Seldal <Svein.Seldal@solidas.com>
+
+ * coff-tic54x.c: Removed the ticoff0_bad_format_hook() and
+ ticoff1_bad_format_hook() functions. Removed the coff0 and coff1
+ swaptables.
+ * coff-tic4x.c: Ditto
+ * coffcode.h: Added extra arguments to CREATE_BIG_COFF_TARGET_VEC
+ and CREATE_LITTLE_COFF_TARGET_VEC. Created the macro
+ CREATE_BIGHDR_COFF_TARGET_VEC. Created the ticoff0_bad_format_hook(),
+ ticoff1_bad_format_hook() functions. Created the coff0 and coff1
+ swap tables.
+ * coff-tic4x.c: Adopted new CREATE_xxx_COFF_TARGET_VEC macros.
+ * coff-a29k.c: Append COFF_SWAP_TABLE argument
+ * coff-apollo.c: Ditto
+ * coff-arm.c: Ditto
+ * coff-h8300.c: Ditto
+ * coff-h8500.c: Ditto
+ * coff-i960.c: Ditto
+ * coff-m68k.c: Ditto
+ * coff-m88k.c: Ditto
+ * coff-mcore.c: Ditto
+ * coff-sh.c: Ditto
+ * coff-sparc.c: Ditto
+ * coff-tic80.c: Ditto
+ * coff-we32k.c: Ditto
+ * coff-z8k.c: Ditto
+ * coff-w65.c: Ditto
+
+2003-06-04 Svein E. Seldal <Svein.Seldal@solidas.com>
+
+ * coff-tic4x.c (ticoff0_swap_table, ticoff1_swap_table): Fixed
+ initialization bug
+
+2003-06-03 Jakub Jelinek <jakub@redhat.com>
+
+ * elf.c (_bfd_elf_print_private_bfd_data): Handle PT_GNU_STACK.
+ (bfd_section_from_phdr): Likewise.
+ (map_sections_to_segments): Create PT_GNU_STACK segment header.
+ (get_program_header_size): Count with PT_GNU_STACK.
+ * elf-bfd.h (struct elf_obj_tdata): Add stack_flags.
+ * elflink.h (bfd_elfNN_size_dynamic_sections): Set stack_flags.
+
+2003-06-03 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elflink.h (elf_link_input_bfd): Call linker error_handler
+ for discarded definitions.
+
+2003-06-03 Elias Athanasopoulos <elathan@phys.uoa.gr>
+
+ * syms.c (decode_section_type): Return 'n' if section flags are
+ SEC_HAS_CONTENTS && SEC_READONLY.
+
+2003-06-03 Nick Clifton <nickc@redhat.com>
+
+ * elf32-v850.c (v850_elf_howto_t): Rename R_V850_32to
+ R_V850_ABS32. Add entry for R_V850_REL32.
+ (v850_elf_reloc_map): Likewise.
+ (v850_elf_check_relocs): Likewise.
+ (v850_elf_perform_relocation): Likewise.
+ (v850_elf_final_link_relocate): Likewise. Include computation
+ to make R_V850_REl32 pc-relative.
+
+2003-06-03 Kaz Kojima <kkojima@rr.iij4u.or.jp>
+
+ * elf32-sh.c (sh_elf_size_dynamic_sections): Create .interp section
+ and DT_DEBUG dynamic tag even for position independent executables.
+ * elf64-sh64.c (sh64_elf64_size_dynamic_sections): Likewize.
+
+2003-06-02 Daniel Jacobowitz <drow@mvista.com>
+
+ * config.bfd: Move obsolete entries out of the range of the
+ targmatch sed script.
+
+2003-06-02 Daniel Jacobowitz <drow@mvista.com>
+
+ * config.bfd (mips*-dec-bsd*, mips*-*-pe*): Mark as obsolete.
+
+2003-05-31 Jakub Jelinek <jakub@redhat.com>
+
+ * elf32-ppc.c (allocate_dynrelocs): Use single slot for first 8192
+ plt entries, not just 8191.
+
+2003-05-30 Daniel Jacobowitz <drow@mvista.com>
+
+ * elfxx-mips.c (_bfd_mips_elf_discard_info): Correct loop index.
+ Reported by Ken Faiczak <kfaiczak@SANDVINE.com>.
+
+2003-05-30 Ulrich Drepper <drepper@redhat.com>
+ Jakub Jelinek <jakub@redhat.com>
+
+ * elflink.h (elf_link_add_object_symbols): Use !info->executable
+ instead of info->shared where appropriate.
+ (bfd_elfNN_size_dynamic_sections, elf_link_output_extsym): Likewise.
+ * elflink.c (_bfd_elf_create_got_section): Likewise.
+ (_bfd_elf_link_create_dynamic_sections): Likewise.
+ (_bfd_elf_link_assign_sym_version): Likewise.
+ * elf32-i386.c (elf_i386_size_dynamic_sections): Create .interp section
+ and DT_DEBUG dynamic tag even for position independent executables.
+ * elf32-ppc.c (ppc_elf_size_dynamic_sections): Likewise.
+ * elf32-s390.c (elf_s390_size_dynamic_sections: Likewise.
+ * elf64-ppc.c (ppc64_elf_size_dynamic_sections: Likewise.
+ * elf64-s390.c (elf_s390_size_dynamic_sections: Likewise.
+ * elf64-x86-64.c (elf64_x86_64_size_dynamic_sections: Likewise.
+ * elfxx-ia64.c (elfNN_ia64_size_dynamic_sections: Likewise.
+ * elf32-sparc.c (elf32_sparc_size_dynamic_sections: Likewise.
+ * elf64-alpha.c (elf64_alpha_size_dynamic_sections: Likewise.
+ * elf64-sparc.c (sparc64_elf_size_dynamic_sections: Likewise.
+
+2003-05-30 Kris Warkentin <kewarken@qnx.com>
+
+ * elf.c (elfcore_grok_nto_status): Only set lwpid for the active or
+ signalled thread.
+ (elfcore_grok_nto_gregs): Only make .reg section for the active thread.
+
+2003-05-29 Nick Clifton <nickc@redhat.com>
+
+ * pef.c: Include "safe-ctype.h" instead of <ctype.h>.
+ Tidy up formatting.
+ * Makefile.am: Add dependency on safe-ctype.h.
+ * Makefile.in: Regenerate.
+
+2003-05-29 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * elfxx-mips.c: Don't force symbols local unconditionally.
+
+2003-05-28 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-hppa.c (elf32_hppa_relocate_section): Delete bogus
+ undefined_symbol call.
+
+2003-05-27 Richard Sandiford <rsandifo@redhat.com>
+
+ * elfxx-mips.c (mips_elf_hash_sort_data): Fix formattting.
+ (mips_elf_link_hash_table): Likewise.
+
+2003-05-22 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * elf64-mips.c (elf_mips_gnu_rel16_s2): Add internally used
+ R_MIPS_GNU_REL16_S2 support.
+ (bfd_elf64_bfd_reloc_type_lookup): Use it.
+ (mips_elf64_rtype_to_howto): Use it.
+ * elfn32-mips.c (elf_mips_gnu_rel16_s2): Add internally used
+ R_MIPS_GNU_REL16_S2 support.
+ (bfd_elf32_bfd_reloc_type_lookup): Use it.
+ (mips_elf_n32_rtype_to_howto): Use it.
+
+2003-05-21 Stuart F. Downing <sdowning@fame.com>
+
+ * som.h: Define PA_2_0 before including a.out.h
+
+2003-05-07 Eric Christopher <echristo@redhat.com>
+ Alexandre Oliva <aoliva@redhat.com>
+
+ * elfxx-mips.c (_bfd_mips_elf_merge_private_bfd_data): Adjust
+ pic tests, change to warning.
+ (_bfd_mips_elf_final_link): Remove EF_MIPS_CPIC flag setting.
+
+2003-05-21 Marcus Comstedt <marcus@mc.pp.se>
+
+ * config.bfd: Check for a target triplet of shl-...-netbsdelf as
+ well as shle-...-netbsdelf. Remove duplicate entry.
+
+2003-05-21 Nick Clifton <nickc@redhat.com>
+
+ * elf32-xstormy16.c (xstormy16_elf_howto_table): Fix dst_mask
+ for X_STORMY16_REL_12 reloc.
+
+ * elf.c (bfd_elf_get_needed_list): Use is_elf_hash_table to check
+ the type of the hash table in the bfd_link_info structure.
+ (bfd_elf_get_runpath_list): Likewise.
+
+2003-05-19 Roland McGrath <roland@redhat.com>
+
+ * elf.c (bfd_elf_bfd_from_remote_memory): New function.
+ * bfd-in.h: Declare it.
+ * bfd-in2.h: Regenerated.
+ * elfcode.h (NAME(_bfd_elf,bfd_from_remote_memory)): New function.
+ * elf-bfd.h (struct elf_backend_data): New function pointer member
+ elf_backend_bfd_from_remote_memory.
+ (_bfd_elf32_bfd_from_remote_memory, _bfd_elf64_bfd_from_remote_memory):
+ Declare them.
+ * elfxx-target.h (elf_backend_bfd_from_remote_memory): New macro.
+ (elfNN_bed): Add that to the initializer.
+
+2003-05-15 Roland McGrath <roland@redhat.com>
+
+ * elf.c (elfcore_grok_note): Grok NT_AUXV note, make ".auxv" section.
+
+2003-05-20 Jakub Jelinek <jakub@redhat.com>
+
+ * elflink.h (elf_link_output_extsym): Only issue error about !=
+ STV_DEFAULT symbols if they are bfd_link_hash_undefined.
+
+2003-05-20 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elflink.c (_bfd_elf_merge_symbol): Check ELF_LINK_DYNAMIC_DEF
+ when removing the old definition for symbols with non-default
+ visibility.
+
+2003-05-18 Jason Eckhardt <jle@rice.edu>
+
+ * elf32-i860.c (elf32_i860_relocate_highadj): Simplify calculation.
+
+2003-05-17 Andreas Schwab <schwab@suse.de>
+
+ * elf32-m68k.c (elf_m68k_check_relocs): Cache reloc section in
+ elf_section_data during processing of pc-relative and absolute
+ relocations.
+ (elf_m68k_relocate_section): Use the cached reloc section instead
+ of computing it again. Fix handling of visibility. Don't modify
+ addend when copying over a relocation into the output.
+
+2003-05-17 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-i386.c (elf_i386_adjust_dynamic_symbol): Use SYMBOL_CALLS_LOCAL
+ to trim plt entries. Move undefweak non-default visibility test..
+ (allocate_dynrelocs): ..from here.
+ * elf32-ppc.c (ppc_elf_adjust_dynamic_symbol): Don't test
+ dynamic_sections_created here. Update comment. Move undefweak
+ non-default visibility test..
+ (allocate_dynrelocs): ..from here. Fix comment.
+ * elf64-ppc.c (ppc64_elf_adjust_dynamic_symbol): Use SYMBOL_CALLS_LOCAL
+ to trim plt entries. Move undefweak non-default visibility test..
+ (allocate_dynrelocs): ..from here. Fix comment.
+ * elflink.h (elf_link_output_extsym): Compare ELF_ST_VISIBILITY with
+ STV_DEFAULT rather than comparing with zero.
+ * elflink.c (_bfd_elf_merge_symbol): Likewise.
+ (_bfd_elf_fix_symbol_flags): Likewise. Format comment.
+
+2003-05-17 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * bfd.c (_bfd_get_gp_value): Prevent illegal access for abfd null
+ pointers.
+ (_bfd_set_gp_value): Likewise.
+
+2003-05-16 Michael Snyder <msnyder@redhat.com>
+ From Bernd Schmidt <bernds@redhat.com>
+ * archures.c (bfd_mach_h8300sx): New.
+ * bfd-in2.h: Regenerate.
+ * cpu-h8300.c (h8300_scan)): Add support for h8300sx.
+ (h8300sx_info_struct): New.
+ (h8300s_info_struct): Link to it.
+ * elf32-h8300.c (elf32_h8_mach): Add support for h8300sx.
+ (elf32_h8_final_write_processing): Likewise.
+ (elf32_h8_relax_section): Likewise.
+
+2003-05-16 Kelley Cook <kelleycook@wideopenwest.com>
+
+ * config.bfd: Accept i[3-7]86 variants.
+ * configure.host: Likewise.
+ * configure.in: Likewise.
+ * configure: Regenerate.
+
+2003-05-15 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elflink.c (_bfd_elf_fix_symbol_flags): Also hide protected
+ symbol.
+
+2003-05-15 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elflink.h (elf_link_check_versioned_symbol): Also allow
+ the base version.
+
+2003-05-15 Alan Modra <amodra@bigpond.net.au>
+ H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf32-i386.c (allocate_dynrelocs): Use SYMBOL_CALLS_LOCAL.
+ (elf_i386_relocate_section): Likewise.
+ * elf32-ppc.c (allocate_dynrelocs): Likewise.
+ (ppc_elf_relocate_section): Likewise.
+ * elf64-ppc.c (allocate_dynrelocs): Likewise.
+ (ppc64_elf_relocate_section): Likewise.
+
+2003-05-15 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * elf32-mips.c (gprel32_with_gp): Remove useless N64 ABI case.
+
+2003-05-13 Stephane Carrez <stcarrez@nerim.fr>
+
+ * elf32-m68hc1x.c (_bfd_m68hc11_elf_merge_private_bfd_data): Check for
+ processor capability, allow merge of HC12 and HCS12 in some cases.
+ (m68hc11_elf_hash_table_create): Use bfd_malloc instead of bfd_zalloc.
+ * cpu-m68hc12.c (bfd_m68hc12s_arch): New struct.
+ (bfd_m68hc12_arch): Link it.
+ (scan_mach): New function.
+
+2003-05-13 Andrew Haley <aph@redhat.com>
+
+ * elf.c (bfd_elf_hash): Mask lower 32 bits of hash.
+
+2003-05-13 Alan Modra <amodra@bigpond.net.au>
+ H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf-bfd.h (SYMBOL_REFERENCES_LOCAL, SYMBOL_CALLS_LOCAL): Move from
+ elf32-ppc.c. Add ELF_LINK_FORCED_LOCAL check.
+ * elf32-ppc.c: (SYMBOL_REFERENCES_LOCAL, SYMBOL_CALLS_LOCAL): Delete.
+ (allocate_dynrelocs): Use SYMBOL_REFERENCES_LOCAL for dynreloc check.
+ (ppc_elf_relocate_section): Likewise.
+ * elf64-ppc.c (allocate_dynrelocs): Likewise.
+ (ppc64_elf_relocate_section): Likewise. Use for .got relocs too.
+ (ppc64_elf_adjust_dynamic_symbol): Don't assume symbols with .plt
+ relocs need no other types.
+ * elf32-i386.c (allocate_dynrelocs): Use SYMBOL_REFERENCES_LOCAL for
+ dynreloc check.
+ (elf_i386_relocate_section): Likewise. Use for .got relocs too.
+ (elf_i386_finish_dynamic_symbol): Use SYMBOL_REFERENCES_LOCAL for
+ .got relocs.
+
+2003-05-13 Kaz Kojima <kkojima@rr.iij4u.or.jp>
+
+ * elf32-sh.c (sh_elf_adjust_dynamic_symbol): For weak symbols,
+ copy ELF_LINK_NON_GOT_REF from weakdef.
+ (allocate_dynrelocs): For undef weak syms with non-default
+ visibility, a) don't allocate plt entries, b) don't allocate
+ .got relocs, c) discard dyn rel space
+ (sh_elf_relocate_section): d) don't generate .got relocs, e)
+ don't generate dynamic relocs.
+ (sh_elf_copy_indirect_symbol): Don't copy ELF_LINK_NON_GOT_REF
+ for weakdefs when symbol already adjusted.
+
+2003-05-12 Nick Clifton <nickc@redhat.com>
+
+ * elf32-xstormy16.c (xstormy16_elf_howto_table): use 'bitfield'
+ overflow detection for R_XSTORMY16_16 reloc.
+
+2003-05-12 Paul Clarke <paulc@senet.com.au>
+
+ * elf32-h8300.c: Fix typo in name of R_H8_DIR8 reloc.
+
+2003-05-11 Jason Eckhardt <jle@rice.edu>
+
+ * elf32-i860.c (elf32_i860_relocate_highadj): Properly
+ adjust upper bits.
+ (elf32_i860_relocate_splitn): Obtain upper 5 bits from the
+ proper place.
+ (elf32_i860_relocate_pc16): Obtain upper 5 bits from the
+ proper place.
+
+2003-05-11 Andreas Schwab <schwab@suse.de>
+
+ * elf32-m68k.c (elf_m68k_relocate_section): Replace ugly
+ complicated tests for unresolvable relocs with a simple direct
+ scheme using "unresolved_reloc" var. Report some detail on
+ bfd_reloc_outofrange and similar errors.
+
+2003-05-09 Martin Schwidefsky <schwidefsky@de.ibm.com>
+
+ * elf32-s390.c (allocate_dynrelocs, elf_s390_relocate_section):
+ Fix WILL_CALL_FINISH_DYNAMIC_SYMBOL call.
+ (WILL_CALL_FINISH_DYNAMIC_SYMBOL): Pass SHARED instead of INFO.
+ * elf64-s390.c: Likewise.
+
+2003-05-09 Martin Schwidefsky <schwidefsky@de.ibm.com>
+
+ * elf32-s390.c (ELIMINATE_COPY_RELOCS): Define as one.
+ (elf_s390_adjust_dynamic_symbol): For weak symbols, copy
+ ELF_LINK_NON_GOT_REF from weakdef.
+ (elf_s390_copy_indirect_symbol): Test whether the weakdef sym has
+ already been adjusted before treating it specially.
+ * el64-s390.c: Likwise.
+
+2003-05-09 Martin Schwidefsky <schwidefsky@de.ibm.com>
+
+ * elf32-s390.c (allocate_dynrelocs): For undef weak syms with
+ non-default visibility, a) don't make them dynamic, b) discard
+ space for dynamic relocs.
+ (elf_s390_relocate_section): Initialize the GOT entries and skip
+ R_390_{8,16,32}/R_390_PC{16,16DBL,32DBL,32} for weak undefined
+ symbols with non-default visibility.
+ * elf64-s390.c: Likewise.
+
+2003-05-09 Alan Modra <amodra@bigpond.net.au>
+
+ * cpu-arm.c (arm_check_note): Warning fix.
+ * elf32-iq2000.c (iq2000_elf_check_relocs): Warning fixes. Arrange
+ to keep relocs if edited.
+ (iq2000_elf_print_private_bfd_data): Return TRUE.
+ * elfxx-ia64.c (elfNN_ia64_relax_section): Use ELFNN_R_SYM, not
+ ELF64_R_SYM.
+ (elfNN_ia64_relax_ldxmov): Warning fix.
+ * xtensa-isa.c (xtensa_add_isa): Warning fix.
+ * xtensa-modules.c (get_num_opcodes): Warning fix.
+
+2003-05-09 Andrey Petrov <petrov@netbsd.org>
+
+ * elf.c (elf_fake_sections): Use correct cast for sh_name.
+
+2003-05-09 Alan Modra <amodra@bigpond.net.au>
+
+ * elflink.c (_bfd_elf_link_create_dynamic_sections): Move from
+ elflink.h. Replace LOG_FILE_ALIGN with bed->s->log_file_align.
+ (_bfd_elf_create_dynamic_sections): Use bed->s->log_file_align.
+ (bfd_elf_record_link_assignment): Move from elflink.h.
+ (_bfd_elf_merge_symbol): Likewise.
+ (_bfd_elf_add_default_symbol): Likewise.
+ (_bfd_elf_export_symbol): Likewise.
+ (_bfd_elf_link_find_version_dependencies): Likewise.
+ (_bfd_elf_link_assign_sym_version): Likewise.
+ (_bfd_elf_link_read_relocs): Likewise.
+ (_bfd_elf_link_size_reloc_section): Likewise.
+ (_bfd_elf_fix_symbol_flags): Likewise.
+ (_bfd_elf_adjust_dynamic_symbol): Likewise.
+ (_bfd_elf_link_sec_merge_syms): Likewise.
+ (elf_link_read_relocs_from_section): Likewise. Use bed->s->sizeof_rel
+ and bed->s->sizeof_rela.
+ (_bfd_elf_link_output_relocs): Likewise.
+ * elf-bfd.h (struct elf_size_info): Rename file_align to
+ log_file_align.
+ (struct elf_info_failed): Move from elflink.h.
+ (struct elf_assign_sym_version_info): Likewise.
+ (struct elf_find_verdep_info): Likewise.
+ (_bfd_elf_create_dynamic_sections): Delete duplicate declaration.
+ (_bfd_elf_merge_symbol, _bfd_elf_add_default_symbol,
+ _bfd_elf_export_symbol, _bfd_elf_link_find_version_dependencies,
+ _bfd_elf_link_assign_sym_version,
+ _bfd_elf_link_create_dynamic_sections, _bfd_elf_link_read_relocs,
+ _bfd_elf_link_size_reloc_section, _bfd_elf_link_output_relocs,
+ _bfd_elf_fix_symbol_flags, _bfd_elf_adjust_dynamic_symbol,
+ _bfd_elf_link_sec_merge_syms): Declare.
+ (bfd_elf32_link_create_dynamic_sections): Don't declare.
+ (_bfd_elf32_link_read_relocs): Likewise.
+ (bfd_elf64_link_create_dynamic_sections): Likewise.
+ (_bfd_elf64_link_read_relocs): Likewise.
+ * elflink.h: Move lots o' stuff elsewhere.
+ * bfd-in.h (bfd_elf32_record_link_assignment): Don't declare.
+ (bfd_elf64_record_link_assignment): Likewise.
+ (bfd_elf_record_link_assignment): Declare.
+ * bfd-in2.h: Regenerate.
+ * elfcode.h (elf_link_create_dynamic_sections): Don't declare.
+ (NAME(_bfd_elf,size_info)): Adjust for log_file_align.
+ * elf.c (_bfd_elf_init_reloc_shdr): Adjust for bed->s->log_file_align.
+ (assign_file_positions_for_segments): Likewise.
+ (assign_file_positions_except_relocs): Likewise.
+ (swap_out_syms, elfcore_write_note): Likewise.
+ * elf-m10200.c: Adjust for changed function names.
+ * elf-m10300.c: Likewise.
+ * elf32-arm.h: Likewise.
+ * elf32-h8300.c: Likewise.
+ * elf32-hppa.c: Likewise.
+ * elf32-ip2k.c: Likewise.
+ * elf32-m32r.c: Likewise.
+ * elf32-m68hc11.c: Likewise.
+ * elf32-m68hc1x.c: Likewise.
+ * elf32-m68k.c: Likewise.
+ * elf32-mips.c: Likewise.
+ * elf32-ppc.c: Likewise.
+ * elf32-sh.c: Likewise.
+ * elf32-v850.c: Likewise.
+ * elf32-xtensa.c: Likewise.
+ * elf64-alpha.c: Likewise.
+ * elf64-hppa.c: Likewise.
+ * elf64-mmix.c: Likewise.
+ * elf64-ppc.c: Likewise.
+ * elf64-sh64.c: Likewise.
+ * elfxx-ia64.c: Likewise.
+ * elfxx-mips.c: Likewise.
+ (MIPS_ELF_LOG_FILE_ALIGN): Use log_file_align.
+ * elf64-alpha.c (alpha_elf_size_info): Adjust for log_file_align.
+ * elf64-hppa.c (hppa64_elf_size_info): Likewise.
+ * elf64-mips.c (mips_elf64_size_info): Likewise.
+ * elf64-s390.c (s390_elf64_size_info): Likewise.
+ * elf64-sparc.c (sparc64_elf_size_info): Likewise.
+
+2003-05-08 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elflink.h (elf_add_default_symbol): After skipping the
+ unversioned symbol, go to non-default one.
+
+2003-05-07 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elfxx-ia64.c (_bfd_elf_link_hash_hide_symbol): Also clear the
+ want_plt field.
+ (elfNN_ia64_relocate_section): Don't do dynamic symbol lookup
+ for symbols with non-default visibility.
+
+2003-05-07 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elflink.h (elf_link_check_versioned_symbol): Also handle the
+ case that a DSO references a hidden symbol which may be
+ satisfied by a versioned symbol in another DSO.
+ (elf_link_output_extsym): Check versioned definition for hidden
+ symbol referenced by a DSO.
+
+2003-05-07 Nick Clifton <nickc@redhat.com>
+
+ * elf32-xstormy16.c (xstormy16_elf_howto_table): Reset
+ R_XSTORMY16_16 reloc to ignore overflows.
+
+2003-05-06 Alexandre Oliva <aoliva@redhat.com>
+
+ * elfxx-mips.c (_bfd_mips_elf_merge_private_bfd_data): Improve
+ error message for mixing different-endian files. Check for ABI
+ compatibility of input files with the selected emulation.
+
+2003-05-05 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-i386.c (allocate_dynrelocs): For undef weak syms with
+ non-default visibility, a) don't make them dynamic, b) discard
+ space for dynamic relocs.
+ * elf64-x86-64.c (allocate_dynrelocs): Likewise.
+
+ * elf32-ppc.c (allocate_dynrelocs): For undef weak syms with
+ non-default visibility, a) don't allocate plt entries, b) don't
+ allocate .got relocs, c) discard dyn rel space,
+ (ppc_elf_relocate_section): d) don't generate .got relocs, e)
+ don't generate dynamic relocs.
+ * elf64-ppc.c (allocate_dynrelocs): As above.
+ (ppc64_elf_relocate_section): As above.
+
+2003-05-05 Andreas Jaeger <aj@suse.de>
+
+ * elf64-x86-64.c (allocate_dynrelocs): Don't allocate dynamic
+ relocation entries for weak undefined symbols with non-default
+ visibility.
+ (elf64_x86_64_relocate_section): Initialize the GOT entries and
+ skip R_386_32/R_386_PC32 for weak undefined symbols with
+ non-default visibility.
+
+2003-05-04 H.J. Lu <hjl@gnu.org>
+
+ * elf32-i386.c (allocate_dynrelocs): Don't allocate dynamic
+ relocation entries for weak undefined symbols with non-default
+ visibility.
+ (elf_i386_relocate_section): Initialize the GOT entries and
+ skip R_386_32/R_386_PC32 for weak undefined symbols with
+ non-default visibility.
+
+ * elfxx-ia64.c (allocate_fptr): Don't allocate function
+ descriptors for weak undefined symbols with non-default
+ visibility.
+ (allocate_dynrel_entries): Don't allocate relocation entries
+ for symbols resolved to 0.
+ (set_got_entry): Don't install dynamic relocation for weak
+ undefined symbols with non-default visibility.
+ (set_pltoff_entry): Likewise.
+
+ * elflink.h (elf_fix_symbol_flags): Hide weak undefined symbols
+ with non-default visibility.
+ (elf_link_output_extsym): Don't make weak undefined symbols
+ with non-default visibility dynamic.
+
+2003-05-04 H.J. Lu <hjl@gnu.org>
+
+ * elflink.h (elf_merge_symbol): Correctly handle weak definition.
+
+2003-05-04 H.J. Lu <hjl@gnu.org>
+
+ * elflink.h (elf_merge_symbol): Don't record a hidden/internal
+ symbol dynamic. Check indirection when removing the old
+ definition for symbols with non-default visibility.
+ (elf_add_default_symbol): Skip when told by elf_merge_symbol.
+
+2003-05-02 Nick Clifton <nickc@redhat.com>
+
+ * elf32-xstormy16.c (xstormy16_elf_howto_table): Make the
+ R_XSTORMY16_8 and R_XSTORMY16_16 relocs detect and complain about
+ unsigned overflow.
+
+2003-05-02 Andreas Jaeger <aj@suse.de>
+
+ * elf64-x86-64.c (elf_x86_64_copy_indirect_symbol): Don't copy
+ ELF_LINK_NON_GOT_REF for weakdefs when symbol already adjusted.
+ (ELIMINATE_COPY_RELOCS): Define as one. Use throughout.
+ (elf_x86_64_adjust_dynamic_symbol): For weak symbols, copy
+ ELF_LINK_NON_GOT_REF from weakdef.
+
+2003-05-02 Charles Lepple <clepple@ghz.cc>
+ Nick Clifton <nickc@redhat.com>
+
+ * acinclude.m4: Fix name of --enable-install-libbfd switch.
+ * aclocal.m4: Regenerate.
+ * configure: Regenerate.
+ * Makefile.in: Regenerate.
+
+2003-05-01 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-ppc.c (ppc_elf_copy_indirect_symbol): Test whether the
+ weakdef sym has already been adjusted before treating it specially.
+ * elf32-i386.c (elf_i386_copy_indirect_symbol): Don't copy
+ ELF_LINK_NON_GOT_REF for weakdefs when symbol already adjusted.
+ * elf64-ppc.c (ppc64_elf_copy_indirect_symbol): Likewise.
+ (ppc64_elf_check_relocs): Set ELF_LINK_NON_GOT_REF.
+
+2003-04-28 H.J. Lu <hjl@gnu.org>
+
+ * elfxx-ia64.c (elfNN_ia64_relax_section): Relax ldxmov during
+ the relax finalize pass.
+
+ * section.c (struct sec): Add need_finalize_relax and remove
+ flag11.
+ (STD_SECTION): Update struct sec initializer.
+ * bfd-in2.h: Regenerated.
+
+2003-04-28 H.J. Lu <hjl@gnu.org>
+
+ * elflink.h (elf_merge_symbol): Call elf_backend_copy_indirect_symbol
+ to copy any information related to dynamic linking when we flip
+ the indirection.
+
+2003-04-27 H.J. Lu <hjl@gnu.org>
+
+ * elf-bfd.h (ELF_LINK_DYNAMIC_DEF): New.
+ (ELF_LINK_DYNAMIC_WEAK): New.
+
+ * elflink.h (elf_merge_symbol): Add one argument to indicate if
+ a symbol should be skipped. Ignore definitions in dynamic
+ objects for symbols with non-default visibility.
+ (elf_add_default_symbol): Adjusted.
+ (elf_link_add_object_symbols): Check if a symbol should be
+ skipped. Don't merge the visibility field with the one from
+ a dynamic object.
+ (elf_link_check_versioned_symbol): Use undef_bfd.
+ (elf_link_output_extsym): Warn if a forced local symbol is
+ referenced from dynamic objects. Make non-weak undefined symbol
+ with non-default visibility a fatal error.
+
+2003-04-27 Daniel Jacobowitz <drow@mvista.com>
+
+ * configure.in: Bump version on HEAD to 2.14.90.
+ * configure: Regenerated.
+
+2003-04-26 Stephane Carrez <stcarrez@nerim.fr>
+
+ PR savannah/3331:
+ * elf32-m68hc11.c (m68hc11_elf_relax_section): Clear prev_insn_group
+ when we couldn't relax something.
+
+2003-04-25 Alan Modra <amodra@bigpond.net.au>
+
+ * elflink.h (elf_merge_symbol): When we find a regular definition
+ for an indirect symbol, flip the indirection so that the old
+ direct symbol now points to the new definition.
+
+2003-04-24 Roland McGrath <roland@redhat.com>
+
+ * elf.c (bfd_section_from_phdr): Map PT_GNU_EH_FRAME to "eh_frame_hdr".
+
+2003-04-24 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-ppc.c: Formatting and comment fixes.
+ (ELIMINATE_COPY_RELOCS): Move before ppc_elf_copy_indirect_symbol.
+ (ppc_elf_copy_indirect_symbol): Copy flags here for weakdefs.
+
+2003-04-24 Dhananjay Deshpande <dhananjayd@kpitcummins.com>
+
+ * archures.c (bfd_mach_h8300hn, bfd_mach_h8300sn): Added.
+ * bfd-in2.h: Rebuilt.
+ * coff-h8300.c (BADMAG): Add check for H8300HNBADMAG & H8300SNBADMAG.
+ * coffcode.h (coff_set_arch_mach_hook): Add case for H8300HNMAGIC
+ & H8300SNMAGIC.
+ (coff_set_flags): Add case for bfd_mach_h8300hn & bfd_mach_h8300sn.
+ * cpu-h8300.c (h8300_scan): Handle h8300hn, h8300sn.
+ (h8300sn_info_struct, h8300hn_info_struct): New.
+ * elf32-h8300.c (elf32_h8_mach): Handle case for h8300hn & h8300sn
+ (elf32_h8_final_write_processing): Likewise.
+
+2003-04-23 Kaz Kojima <kkojima@rr.iij4u.or.jp>
+
+ * elf32-sh.c (tpoff): New.
+ (struct elf_sh_dyn_relocs): Remove tls_tpoff32.
+ (WILL_CALL_FINISH_DYNAMIC_SYMBOL): Pass SHARED instead of INFO.
+ (allocate_dynrelocs): Don't make unnecessary dynamic TLS
+ relocations. Adjust WILL_CALL_FINISH_DYNAMIC_SYMBOL uses.
+ (sh_elf_relocate_section): Likewise. Remove unnecessary tests.
+ (dtpoff_base): Fix wrong indentation.
+ (sh_elf_check_relocs): Don't set DF_STATIC_TLS flag with non-TLS
+ relocations. Don't set tls_tpoff32 flag. Don't make unnecessary
+ R_SH_TLS_TPOFF32 relocations.
+
+2003-04-23 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * archures.c (enum bfd_architecture): Amend comment to refer to SuperH.
+ * cpu-sh.c: Likewise.
+ * elf32-sh.c: Likewise.
+ * reloc.c (bfd_reloc_code_real): Likewise.
+ * elf32-sh64-com.c: Change comment to refer to SuperH.
+ * elf32-sh64.c: Likewise.
+ * elf64-sh64.c: Likewise.
+ * bfd-in2.h (enum bfd_architecture): Regenerate.
+
+2003-04-23 Alan Modra <amodra@bigpond.net.au>
+
+ From Julien LEMOINE <speedblue@debian.org>
+ * elf32-i386.c (elf_i386_info_to_howto): Delete.
+ (elf_info_to_howto): Define as elf_i386_info_to_howto_rel.
+
+2003-04-22 Kazuhiro Inaoka <inaoka.kazuhiro@renesas.com>
+
+ * archures.c: Replace references to Mitsubishi M32R with references
+ to Renesas M32R.
+ * relocs.c: Likewise.
+ * bfd-in2.h: Regenerate.
+
+2003-04-21 Richard Henderson <rth@redhat.com>
+
+ * elf64-alpha.c (alpha_elf_dynamic_symbol_p): Return false for an
+ executable when a symbol is defined both regular and dynamic.
+
+2003-04-21 Stephane Carrez <stcarrez@nerim.fr>
+
+ * Makefile.am (BFD32_BACKENDS): Add elf32-m68hc1x.lo.
+ (elf32-m68hc1x.lo): Update dependencies
+ * configure.in: Add elf32-m68hc1x.lo.
+ * configure: Rebuild.
+ * Makefile.in: Rebuild.
+
+2003-04-21 Stephane Carrez <stcarrez@nerim.fr>
+
+ * elf32-m68hc1x.c: New file (from elf32-m68hc11.c and elf32-m68hc12.c)
+ (m68hc11_elf_hash_table_create): New function.
+ (elf32_m68hc11_link_hash_table_free): New function.
+ (stub_hash_newfunc): New function.
+ (m68hc11_add_stub): New function.
+ (elf32_m68hc11_add_symbol_hook): New function.
+ (elf32_m68hc11_setup_section_lists): New function.
+ (elf32_m68hc11_next_input_section): New function.
+ (elf32_m68hc11_size_stubs): New function.
+ (elf32_m68hc11_build_stubs): New function.
+ (m68hc11_get_relocation_value): New function.
+ (elf32_m68hc11_relocate_section): Call the above to redirect
+ some relocations to the trampoline code.
+ (m68hc11_elf_export_one_stub): New function.
+ (m68hc11_elf_set_symbol): New function.
+ (elf32_m68hc11_build_stubs): Call it via bfd_hash_traverse.
+ (m68hc11_elf_get_bank_parameters): Get parameters only when the info
+ is not yet initialized.
+
+ * elf32-m68hc1x.h: New file (from elf32-m68hc11.c and elf32-m68hc12.c)
+ (elf32_m68hc11_stub_hash_entry): New struct.
+ (m68hc11_page_info): Add trampoline handler address.
+ (m68hc11_elf_link_hash_table): Add stubs generation members.
+ (elf32_m68hc11_add_symbol_hook): Declare.
+ (elf32_m68hc11_setup_section_lists): Declare.
+ (elf32_m68hc11_size_stubs): Declare.
+ (elf32_m68hc11_build_stubs): Declare.
+
+ * elf32-m68hc11.c (m68hc11_elf_ignore_reloc): Move to elf32-m68hc1x.c.
+ (elf32_m68hc11_gc_mark_hook, elf32_m68hc11_gc_sweep_hook): Likewise.
+ (elf32_m68hc11_check_relocs, elf32_m68hc11_relocate_section): Ditto.
+ (_bfd_m68hc11_elf_set_private_flags): Ditto.
+ (_bfd_m68hc11_elf_merge_private_bfd_data): Ditto.
+ (_bfd_m68hc11_elf_print_private_bfd_data): Ditto.
+ (bfd_elf32_bfd_link_hash_table_create): Define.
+ (elf_backend_add_symbol_hook): Define.
+ (m68hc11_elf_bfd_link_hash_table_create): New function.
+ (m68hc11_elf_build_one_stub): New function.
+ (m68hc11_elf_size_one_stub): New function.
+ (m68hc11_elf_bfd_link_hash_table_create): Install the above.
+ (bfd_elf32_bfd_link_hash_table_create): Define.
+
+ * elf32-m68hc12.c (m68hc11_elf_ignore_reloc): Remove.
+ (m68hc12_addr_is_banked): Remove, use m68hc11_addr_is_banked.
+ (m68hc12_phys_addr): Ditto.
+ (m68hc12_phys_page): Ditto.
+ (m68hc12_elf_special_reloc): Move to elf32-m68hc1x.c.
+ (elf32_m68hc11_gc_mark_hook): Likewise.
+ (elf32_m68hc11_gc_sweep_hook): Likewise.
+ (elf32_m68hc11_check_relocs): Likewise.
+ (elf32_m68hc11_relocate_section): Likewise.
+ (_bfd_m68hc12_elf_set_private_flags): Likewise.
+ (_bfd_m68hc12_elf_merge_private_bfd_data): Likewise.
+ (_bfd_m68hc12_elf_print_private_bfd_data): Likewise.
+ (m68hc12_elf_build_one_stub): New function.
+ (m68hc12_elf_size_one_stub): New function.
+ (m68hc12_elf_bfd_link_hash_table_create): New function, use the above.
+ (elf_backend_add_symbol_hook): Define.
+ (elf_m68hc11_howto_table): Use TRUE for pcrel relocs; fix masks.
+
+2003-04-18 Nick Clifton <nickc@redhat.com>
+
+ * format.c (bfd_check_format_matches): Only check associated
+ vector if the matching_vector has been created.
+
+2003-04-15 Alexandre Oliva <aoliva@redhat.com>
+
+ * dwarf2.c (_bfd_dwarf2_find_nearest_line): Fix typo in
+ 2003-04-09's change.
+
+2003-04-15 Brian Ford <ford@vss.fsi.com>
+
+ * peicode.h (coff_swap_scnhdr_in): If a section holds
+ uninitialized data and is from an object file or from an
+ executable image that has not initialized the s_size field, or if
+ the physical size is padded, use the virtual size (stored in
+ s_paddr) instead.
+
+2003-04-15 H.J. Lu <hjl@gnu.org>
+
+ * elflink.h (elf_link_add_object_symbols): Properly report
+ filename for alignment reduction.
+
+2003-04-15 Rohit Kumar Srivastava <rohits@kpitcummins.com>
+
+ * archures.c: Replace occurrances of 'Hitachi' with 'Renesas'.
+ * reloc.c: Likewise.
+ * coff-h8300.c: Likewise.
+ * coff-h8500.c: Likewise.
+ * coff-sh.c: Likewise.
+ * cpu-h8300.c: Likewise.
+ * cpu-sh.c: Likewise.
+ * elf32-h8300.c: Likewise.
+ * elf32-sh.c: Likewise.
+ * elf32-sh64-com.c: Likewise.
+ * elf32-sh64.c: Likewise.
+ * elf64-sh64.c: Likewise.
+ * bfd-in2.h: Regenerate.
+
+2003-04-14 H.J. Lu <hjl@gnu.org>
+
+ * elflink.h (elf_link_add_object_symbols): Maintain maximum
+ alignment for common symbols. Warn reducing alignment for
+ common symbols. Report old filename when symbol size changes.
+
+2003-04-12 Alexandre Oliva <aoliva@redhat.com>
+
+ * elfxx-mips.c (mips_elf_calculate_relocation): Adjust two other
+ occurrences of the same test changed in the previous patch.
+ Optimize.
+
+2003-04-11 Alexandre Oliva <aoliva@redhat.com>
+
+ * elfxx-mips.c (mips_elf_get_global_gotsym_index): New.
+ (mips_elf_calculate_relocation): Decay GOT_PAGE/GOT_OFST to
+ GOT_DISP/addend only if the symbol got a global GOT entry.
+
+2003-04-10 Alexandre Oliva <aoliva@redhat.com>
+
+ * elfxx-mips.c (mips_elf_calculate_relocation): Decay
+ GOT_PAGE/GOT_OFST referencing overridable symbol to
+ GOT_DISP/addend.
+ (_bfd_mips_elf_check_relocs): Handle GOT_PAGE referencing
+ global symbol as GOT_DISP.
+
+2003-04-10 Bob Wilson <bob.wilson@acm.org>
+
+ * elf32-xtensa.c (elf_xtensa_relocate_section): Don't continue to the
+ next relocation on an undefined symbol.
+
+2003-04-09 Richard Henderson <rth@redhat.com>
+
+ * elf64-alpha.c (elf64_alpha_relocate_section) <R_ALPHA_GPREL32>:
+ Ignore relocations against r_symndx == 0.
+
+2003-04-09 H.J. Lu <hjl@gnu.org>
+
+ * elf64-alpha.c (elf64_alpha_relocate_section): Don't return
+ FALSE for undefined symbols.
+ * elfxx-ia64.c (elfNN_ia64_relocate_section): Likewise.
+
+2003-04-09 Alexandre Oliva <aoliva@redhat.com>
+
+ * dwarf2.c (_bfd_dwarf2_find_nearest_line): Try DWARF3-standard
+ and IRIX-specific shift-to-64-bit 4-byte lengths before following
+ addr_size.
+
+2003-04-08 Alexandre Oliva <aoliva@redhat.com>
+
+ * elf32-mips.c (bfd_elf32_bfd_reloc_type_lookup): Detect (ctor)
+ pointer size from ABI, not arch_bits_per_address.
+
+2003-04-07 Kevin Buettner <kevinb@redhat.com>
+
+ * elfn32-mips.c (elf32_mips_grok_prstatus): Adjust core file related
+ constants for n32 ABI.
+
+2003-04-06 Andrew Cagney <cagney@redhat.com>
+
+ * simple.c (bfd_simple_get_relocated_section_contents): Disable
+ free that leads to GDB vs BFD memory corruption.
+
+2003-04-04 Stephane Carrez <stcarrez@nerim.fr>
+
+ * elf32-m68hc11.c (m68hc11_elf_relax_delete_bytes): Also adjust
+ symbols that mark the end of the section.
+ (m68hc11_elf_relax_section): Use R_M68HC11_PCREL_8 relocs when
+ converting to a relative branch so that the offset is computed after
+ the relaxation; also relocate a jsr into a bsr if possible but don't
+ relax them if they are to a far symbol as we need to call the
+ trampoline code.
+ (elf_m68hc11_howto_table): Set pcrel_offset to true.
+
+2003-04-04 Svein E. Seldal <Svein.Seldal@solidas.com>
+
+ * archures.c: Namespace cleanup. Rename bfd_mach_c3x to
+ bfd_mach_tic3x and bfd_mach_c4x to bfd_mach_tic4x
+ * bfd-in2.h: Regenerate
+ * coff-tic4x.c: Namespace cleanup. Replace s/c4x/tic4x/
+ * cpu-tic4x.c: Ditto
+
+2003-04-03 Nick Clifton <nickc@redhat.com>
+
+ * peXXigen.c (_bfd_XXi_swap_scnhdr_out): Compute ps and ss
+ differently for object files and executables.
+ * peicode.h (coff_swap_scnhdr_in): Only set the s_size field
+ for object files or for executables who have not already
+ initialised the field.
+ * libpei.h (bfd_pe_executable_p): New macro. Return true if
+ the PE format bfd is an executable.
+
+2003-04-03 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-ppc.c (ppc_elf_check_relocs): Don't use SYMBOL_REFERENCES_LOCAL
+ here as it's too early to reliably determine locality.
+ (ppc_elf_gc_sweep_hook): Likewise.
+ (SYMBOL_REFERENCES_LOCAL): Expand comment.
+
+2003-04-02 Bob Wilson <bob.wilson@acm.org>
+
+ * xtensa-modules.c: Remove comment indicating that this is a
+ generated file.
+
+2003-04-02 Alan Modra <amodra@bigpond.net.au>
+
+ * elfxx-mips.c (_bfd_mips_elf_hide_symbol): Test for NULL dynobj.
+
+2003-04-01 Bob Wilson <bob.wilson@acm.org>
+
+ * Makefile.am (ALL_MACHINES): Add cpu-xtensa.lo.
+ (ALL_MACHINES_CFILES): Add cpu-xtensa.c.
+ (BFD32_BACKENDS): Add elf32-xtensa.lo, xtensa-isa.lo, and
+ xtensa-modules.lo.
+ (BFD32_BACKENDS_CFILES): Add elf32-xtensa.c, xtensa-isa.c, and
+ xtensa-modules.c.
+ (cpu-xtensa.lo): New target.
+ (elf32-xtensa.lo): Likewise.
+ (xtensa-isa.lo): Likewise.
+ (xtensa-modules.lo): Likewise.
+ * Makefile.in: Regenerate.
+ * archures.c (bfd_architecture): Add bfd_{arch,mach}_xtensa.
+ (bfd_archures_list): Add bfd_xtensa_arch.
+ * config.bfd: Handle xtensa-*-*.
+ * configure.in: Handle bfd_elf32_xtensa_{le,be}_vec.
+ * configure: Regenerate.
+ * reloc.c: Add BFD_RELOC_XTENSA_{RTLD,GLOB_DAT,JMP_SLOT,RELATIVE,
+ PLT,OP0,OP1,OP2,ASM_EXPAND,ASM_SIMPLIFY}.
+ * targets.c (bfd_elf32_xtensa_be_vec): Declare.
+ (bfd_elf32_xtensa_le_vec): Likewise.
+ (bfd_target_vector): Add bfd_elf32_xtensa_{be,le}_vec.
+ * cpu-xtensa.c: New file.
+ * elf32-xtensa.c: Likewise.
+ * xtensa-isa.c: Likewise.
+ * xtensa-modules.c: Likewise.
+ * libbfd.h: Regenerate.
+ * bfd-in2.h: Likewise.
+
+2003-04-01 Nick Clifton <nickc@redhat.com>
+
+ * archures.c (bfd_mach_arm_unknown): Define.
+ * bfd-in.h (bfd_arm_merge_machines, bfd_arm+update_notes,
+ bfd_arm_get_mach_from_notes): Prototype.
+ * bfd-in2.h: Regenerate.
+ * coff-arm.c (coff_arm_merge_private_bfd_data): Call
+ bfd_arm_merge_machines.
+ (coff_arm_final_link_postscript): Call bfd_arm_update_notes.
+ * coffcode.h (coff_set_arch_mach_hook): Call
+ bfd_arm_get_mach_from_notes.
+ * coffgen.c (coff_real_object_p): Revert previous delta.
+ * cpu_arm.c (arm_check_note): New function. Examine a note in a
+ .note section.
+ (bfd_arm_merge_machines): New function: Handle the merging of ARM
+ binaries compiled for different architectures..
+ (bfd_arm_update_notes): New function: Update an ARM note section.
+ (bfd_arm_get_mach_from_notes): New function: Extract a bfd machine
+ number from an ARM note section.
+ * elf32-arm.h (elf32_arm_object_p): Use
+ bfd_arm_get_mach_from_notes.
+ (elf32_arm_merge_private_bfd_data): Use bfd_arm_merge_machines.
+ (elf32_arm_final_write_processing): Use bfd_arm_update_notes.
+
+2003-04-01 Ben Elliston <bje@wasabisystems.com>
+
+ * dwarf2.c (read_attribute_value): Correct typo in comment.
+
+2003-04-01 Nick Clifton <nickc@redhat.com>
+
+ * dwarf2.c (concat_filename): Use bfd_malloc() and strdup()
+ instead of concat().
+ (decode_line_info): Only free filename if it is not NULL.
+ (add_line_info): Make a copy of the filename when storing it into
+ the info structure.
+
+2003-03-31 Andreas Schwab <schwab@suse.de>
+ Daniel Jacobowitz <drow@mvista.com>
+
+ * simple.c (bfd_simple_get_relocated_section_contents): Add
+ parameter symbol_table. Optionally use it instead of the symbol
+ table from the bfd. Save and restore output offsets and output
+ sections around bfd_get_relocated_section_contents. Fix a memory
+ leak.
+ (simple_save_output_info, simple_restore_output_info): New
+ functions.
+ * bfd-in2.h: Regenerate.
+ * dwarf2.c (read_abbrevs): Use
+ bfd_simple_get_relocated_section_contents instead of
+ bfd_get_section_contents.
+ (decode_line_info): Likewise.
+ (_bfd_dwarf2_find_nearest_line): Likewise. Don't call
+ find_rela_addend.
+ (find_rela_addend): Remove.
+ * elfxx-ia64.c (elfNN_ia64_reloc): Weaken sanity check for
+ debugging sections.
+ (elfNN_ia64_hash_table_create): Create the hash table with malloc,
+ not bfd_zalloc.
+
+2003-03-31 David Heine <dlheine@suif.stanford.edu>
+
+ * aoutx.h (aout_link_hash_table_create): Use bfd_malloc instead of
+ bfd_alloc.
+ * dwarf2.c (concat_filename): Always allocate space for the
+ returned filename.
+ (decode_line_info): Free the allocated filename returned by
+ concat_filename.
+ * elf-eh-frame.c (bfd_elf_write_section_eh_frame): Fix memory leaks.
+ * elf.c (copy_private_bfd_data): Likewise.
+ (_bfd_elf_slurp_version_tables): Fix bug freeing contents pointer.
+ * elflink.h (elf_link_sort_relocs): Fix memory leak.
+ * format.c (bfd_check_format_matches): Likewise.
+ * linker.c (bfd_generic_final_link): Likewise.
+ * opncls.c (find_separate_debug_info): Likewise.
+ * simple.c (bfd_simple_get_relocated_section_contents): Likewise.
+
+2003-03-28 H.J. Lu <hjl@gnu.org>
+
+ * elflink.h (elf_link_add_object_symbols): Correctly combine
+ visibilities.
+
+2003-03-27 Jakub Jelinek <jakub@redhat.com>
+
+ * elfxx-ia64.c (elfNN_ia64_relax_section): Reset self_dtpmod_offset
+ to -1 before recomputing got offsets.
+
+2003-03-26 Andreas Schwab <schwab@suse.de>
+
+ * elf32-m68k.c (WILL_CALL_FINISH_DYNAMIC_SYMBOL): Define.
+ (elf_m68k_relocate_section): Use it to correctly handle symbols
+ forced to be local.
+ (elf_m68k_finish_dynamic_symbol): Emit RELATIVE reloc for got
+ entries for symbols that are forced to be local.
+
+2003-03-25 Alexandre Oliva <aoliva@redhat.com>
+
+ * elfxx-mips.c (_bfd_mips_relax_section): New function.
+ * elfxx-mips.h (_bfd_mips_relax_section): Declare.
+ * elfn32-mips.c, elf64-mips.c: Use it.
+
+2003-03-25 Stan Cox <scox@redhat.com>
+ Nick Clifton <nickc@redhat.com>
+
+ Contribute support for Intel's iWMMXt chip - an ARM variant:
+
+ * archures.c: Add bfd_mach_arm_iWMMXt.
+ * reloc.c: Add BFD_RELOC_ARM_CP_OFF_IMM_S2.
+ * bfd-in2.h: Regenerate.
+ * libbfd.h: Regenerate.
+ * coff-arm.c (coff_arm_merge_private_bfd_data): Allow iWMMXt
+ object files to be linked with XScale ones.
+ (coff_arm_final_link_postscript): Update note section.
+ * coffcode.h (coff_set_arch_mach_hook): Handle note section.
+ * coffgen.c (coff_real_object_p): Call bfd_coff_set_arch_mach_hook
+ after identifying a coff binary.
+ * cpu-arm.c (processors): Add iWMMXt.
+ (arch_inf): Likewise.
+ * elf32-arm.h (arm_object_p): Handle note section.
+ (elf32_arm_merge_private_bfd_data): Allow iWMMXt object files to
+ be linked with XScale ones.
+ (elf32_arm_section_flags): New function: Set flags on note section.
+ (elf32_arm_final_write_processing): Handle note section.
+
+2003-03-21 DJ Delorie <dj@redhat.com>
+
+ * elf32-xstormy16.c (elf32_xstormy16_relocate_section): Call
+ _bfd_elf_rela_local_sym.
+
+2003-03-20 H.J. Lu <hjl@gnu.org>
+
+ * elfxx-ia64.c (elfNN_ia64_relax_section): Don't try relax for
+ non-ELF outputs.
+
+2003-03-20 Nick Clifton <nickc@redhat.com>
+
+ * peXXigen.c (_bfd_XXi_swap_aouthdr_out): Initialise $idata2 and
+ $idata5 in case bfd_coff_final_link is not called.
+
+2003-03-19 Jakub Jelinek <jakub@redhat.com>
+
+ * elf64-sparc.c (struct sparc64_elf_section_data): Add reloc_count
+ field.
+ (canon_reloc_count): Define.
+ (sparc64_elf_slurp_one_reloc_table, sparc64_elf_slurp_reloc_table,
+ sparc64_elf_canonicalize_dynamic_reloc): Use it instead of
+ reloc_count.
+ (sparc64_elf_canonicalize_reloc): New routine.
+ (bfd_elf64_canonicalize_reloc): Define.
+
+2003-03-18 Jakub Jelinek <jakub@redhat.com>
+
+ * elfxx-ia64.c (elfNN_ia64_relax_section): Handle relaxation
+ againt mergeable sections. Take r_addend into account when caching
+ trampolines.
+
+2003-03-18 Richard Henderson <rth@redhat.com>
+
+ * elfxx-ia64.c (get_dyn_sym_info): Return NULL gracefully for
+ local symbols that have no dyninfo.
+
+2003-03-14 Gene Smith <gene.smith@siemens.com>
+
+ * ieee.c (ieee_write_expression): Handle the case where symbol is
+ NULL.
+ General formatting improvements.
+
+2003-03-13 Nick Clifton <nickc@redhat.com>
+
+ * configure.in (LINGUAS): Add zh_CN.
+ * configure: Regenerate.
+ * po/zh_CN.po: New file.
+
+2003-03-13 Elias Athanasopoulos <elathan@phys.uoa.gr>
+
+ * aout-cris.c (BYTES_IN_WORD): Don't define.
+ aout-encap.c: Likewise.
+ aout-ns32k.c: Likewise.
+ aout-tic30.c: Likewise.
+ hp300bsd.c: Likewise.
+ i386aout.c: Likewise.
+ i386dynix.c: Likewise.
+ i386linux.c: Likewise.
+ i386lynx.c: Likewise.
+ i386mach3.c: Likewise.
+ m68k4knetbsd.c: Likewise.
+ m68klinux.c: Likewise.
+ m68klynx.c: Likewise.
+ m68knetbsd.c: Likewise.
+ m88kmach3.c: Likewise.
+ mipsbsd.c: Likewise.
+ newsos3.c: Likewise.
+ sparclinux.c: Likewise.
+ sparclynx.c: Likewise.
+ sparcnetbsd.c: Likewise.
+ vaxbsd.c: Likewise. Fix comment formatting.
+
+2003-03-12 Alexandre Oliva <aoliva@redhat.com>
+
+ * Reverted 2003-03-02's patch.
+
+ * elfxx-target.h (bfd_elfNN_canonicalize_reloc): Make it
+ overridable.
+ * elf64-mips.c (mips_elf64_canonicalize_reloc,
+ mips_elf64_get_dynamic_reloc_upper_bound,
+ mips_elf64_canonicalize_dynamic_reloc): New, adapted from elf.c.
+ (bfd_elf64_get_canonicalize_reloc,
+ bfd_elf64_get_dynamic_reloc_upper_bound,
+ bfd_elf64_canonicalize_dynamic_reloc): Define.
+ (mips_elf64_slurp_reloc_table): Support dynamic.
+ (mips_elf64_slurp_one_reloc_table): Adjust.
+
+2003-03-12 Nick Clifton <nickc@redhat.com>
+
+ * xsym.c (bfd_sym_fetch_type_information_table_entry): Change
+ 'index' to 'offset' in test for zero value.
+
+2003-03-11 Alexandre Oliva <aoliva@redhat.com>
+
+ * elfxx-mips.c (mips_elf_create_dynamic_relocation): Do not create
+ dynamic relocations pointing to local or section symbols, use the
+ NULL symbol instead. Document the choice to not emit an
+ additional R_MIPS_64 relocation.
+
+2003-03-11 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-ppc.c (ppc_elf_relocate_section): Subtract tls seg vma from
+ zero index dynamic tls relocs generated for the GOT. Tidy code.
+ Set "relocation" to 1 on DTPMOD32 relocs. Optimize HA adjustment.
+ * elf64-ppc.c (ppc64_elf_relocate_section): Likewise.
+
+2003-03-07 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-ppc.c (ppc_elf_relocate_section): Don't look for a nop after
+ a tls_get_addr call.
+
+ * elf32-ppc.c (ELIMINATE_COPY_RELOCS): Define as one.
+ (ppc_elf_adjust_dynamic_symbol): For weak symbols, copy
+ ELF_LINK_NON_GOT_REF from weakdef.
+ * elf64-ppc.c (ELIMINATE_COPY_RELOCS): Define as one.
+ (ppc64_elf_adjust_dynamic_symbol): For weak symbols, copy
+ ELF_LINK_NON_GOT_REF from weakdef.
+ * elf32-i386.c (ELIMINATE_COPY_RELOCS): Define as one. Use throughout.
+ (elf_i386_adjust_dynamic_symbol): For weak symbols, copy
+ ELF_LINK_NON_GOT_REF from weakdef.
+
+2003-03-06 Jakub Jelinek <jakub@redhat.com>
+ Andrew Haley <aph@redhat.com>
+
+ * elflink.h (elf_bfd_discard_info): Don't process eh frames if
+ output is relocateable.
+
+2003-03-06 Steven Konopa <skonopa@kgo.csc.com>
+
+ * som.c (som_fixup_formats): Correct formats for R_AUX_UNWIND and
+ R_COMMENT.
+
+2003-03-06 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-ppc.c (ppc_elf_create_linker_section): Don't capitalize
+ error messages.
+ (ELIMINATE_COPY_RELOCS): Define to zero.
+ (ppc_elf_relocate_section): Don't deref htab->tls_sec when calculating
+ TLSLD relocs. Report reloc types on a number of errors. Optimize
+ LOCAL24PC check for non-local syms. Don't capitalize error messages.
+ * elf64-ppc.c (ELIMINATE_COPY_RELOCS): Define to zero.
+ (ppc64_elf_relocate_section): Don't deref htab->tls_sec when
+ calculating TLSLD relocs. Report reloc types on a number of errors.
+ Don't capitalize error messages.
+
+2003-03-03 H.J. Lu <hjl@gnu.org>
+
+ * elfxx-ia64.c (USE_BRL): Removed.
+ (oor_ip): Removed.
+
+2003-03-03 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * elf32-sh.c (sh_elf_howto_tab): Make R_SH_IND12W into an ordinary
+ relocation (no special function), and make it non-partial_inplace.
+ (sh_elf_relax_section): When creating a bsr, use a consistent value
+ no matter if the symbol is extern or not; set addend to -4.
+ Don't swap load / non-load instructions for SH4.
+ (sh_elf_relax_delete_bytes): In R_SH_IND12W case, check the offset
+ rather than if the symbol is external to determine if adjusting the
+ offset makes sense. Adjust the addend too if appropriate.
+ (sh_elf_relocate_section): In R_SH_IND12W, don't fiddle with the
+ relocation.
+
+2003-03-03 Nick Clifton <nickc@redhat.com>
+
+ * po/da.po: Installed latest translation.
+
+2003-03-02 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * elf32-mips.c (elf_mips_howto_table_rel): Change definition of
+ R_MIPS_PC16 to rightshift 2.
+ (elf_reloc_map mips_reloc_map): Map to rightshifted BFD reloc.
+ (bfd_elf32_bfd_reloc_type_lookup): Support
+ BFD_RELOC_MIPSEMB_16_PCREL_S2.
+ * elf64-mips.c (mips_elf64_howto_table_rel): Change definition of
+ R_MIPS_PC16 to rightshift 2.
+ (mips_elf64_howto_table_rela): Likewise.
+ (mips_reloc_map): Map to rightshifted BFD reloc.
+ * elfn32-mips.c: The same as in elf64-mips.c.
+ * elfxx-mips.c (mips_elf_got_for_ibfd): Typo in comment.
+ (mips_elf_calculate_relocation): Handle rightshifted addends for
+ R_MIPS_PC16.
+ * reloc.c (BFD_RELOC_MIPSEMB_16_PCREL_S2): New BFD relocation for
+ MIPS Embedded PIC. Remove superfluous empty COMMENT.
+ * libbfd.h: Regenerate.
+ * bfd-in2.h: Regenerate.
+
+2003-02-28 Richard Henderson <rth@redhat.com>
+
+ * elfxx-ia64.c (elfNN_ia64_relax_section): Correct bounds
+ for ltoff22x relaxation.
+
+2003-03-01 Alan Modra <amodra@bigpond.net.au>
+
+ * bfd-in.h (_bfd): Don't define.
+ * bfd.c: Rename occurrences of "struct _bfd" to "struct bfd".
+ * syms.c: Likewise.
+ * bfd-in2.h: Regenerate.
+
+2003-02-27 Richard Henderson <rth@redhat.com>
+
+ * elfxx-ia64.c (struct elfNN_ia64_dyn_sym_info): Add want_gotx;
+ (elfNN_ia64_check_relocs): Set it.
+ (allocate_global_data_got): Check it.
+ (allocate_local_got): Likewise.
+ (allocate_dynrel_entries): Likewise.
+ (elfNN_ia64_relax_ldxmov): New.
+ (elfNN_ia64_relax_section): Handle LTOFF22X, LDXMOV.
+ (elfNN_ia64_choose_gp): Split out from ...
+ (elfNN_ia64_final_link): ... here.
+
+2003-02-27 Andrew Cagney <cagney@redhat.com>
+
+ * bfd.c (struct bfd): Rename "struct _bfd".
+ * bfd-in.h: Update copyright.
+ (struct bfd): Rename "struct _bfd".
+ (_bfd): Define for backward compatibility.
+ * bfd-in2.h: Regenerate.
+
+2003-02-25 Alan Modra <amodra@bigpond.net.au>
+
+ * elflink.h (elf_bfd_final_link): Apportion reloc counts to rel_hdr
+ and rel_hdr2 when initially counting input relocs rather than after
+ creating output reloc sections.
+ (elf_link_read_relocs_from_section): Don't abort with wrong reloc
+ sizes.
+
+ * Makefile.am: Run "make dep-am".
+ * Makefile.in: Regenerate.
+
+2003-02-24 Kris Warkentin <kewarken@qnx.com>
+
+ * elf.c (elfcore_read_notes): Add check for QNX style core file.
+ (elfcore_grog_nto_note): New function.
+ (elfcore_grog_nto_gregs): New function.
+ (elfcore_grog_nto_status): New function.
+
+2003-02-24 Alan Modra <amodra@bigpond.net.au>
+
+ * elflink.c (_bfd_elf_create_got_section): Check existing .got
+ section flags before concluding that we've already been called.
+ Don't use register keyword.
+ (_bfd_elf_create_dynamic_sections): Don't use register keyword.
+ (_bfd_elf_create_linker_section): Formatting.
+
+2003-02-20 jmc <jmc@prioris.mini.pw.edu.pl>
+
+ * coff-h8300.c: Fix typo: intial -> initial.
+ * coff-ppc.c: Likewise.
+
+2003-02-20 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-ppc.c: Formatting.
+ (allocate_dynrelocs): LD and GD relocs against the same sym need
+ separate GOT entries.
+ (ppc_elf_relocate_section): Correct GOT handling for multiple GOT
+ entries per symbol.
+
+2003-02-19 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-hppa.c (elf32_hppa_gc_sweep_hook): Simplify dynamic reloc
+ removal. Localize vars. Remove unnecessary dynobj test.
+ * elf32-i386 (WILL_CALL_FINISH_DYNAMIC_SYMBOL): Pass SHARED instead
+ of INFO.
+ (allocate_dynrelocs): Adjust WILL_CALL_FINISH_DYNAMIC_SYMBOL uses,
+ and optimize.
+ (elf_i386_relocate_section): Likewise.
+ (elf_i386_gc_sweep_hook): Simplify dyn reloc removal. Localize vars.
+ * elf32-s390.c (elf_s390_gc_sweep_hook): Likewise.
+ * elf32-sh.c (sh_elf_gc_sweep_hook): Likewise.
+ * elf64-s390.c (elf_s390_gc_sweep_hook): Likewise.
+ * elf64-x86-64.c (elf64_x86_64_gc_sweep_hook): Likewise.
+ * elf32-sparc.c (elf32_sparc_gc_sweep_hook): Likewise. Remove
+ local_dynrel for section too. Don't touch HIPLT22, LOPLT10, PCPLT32
+ or PCPLT10 relocs. Don't subtract twice on PLT32 relocs.
+ Formatting.
+
+ * elf64-ppc.c (ELIMINATE_COPY_RELOCS): Define.
+ (ppc64_elf_check_relocs): Use it. Correct comment. Move SEC_ALLOC
+ test.
+ (ppc64_elf_adjust_dynamic_symbol): Use ELIMINATE_COPY_RELOCS.
+ (WILL_CALL_FINISH_DYNAMIC_SYMBOL): Pass SHARED instead of INFO.
+ (allocate_dynrelocs): Adjust WILL_CALL_FINISH_DYNAMIC_SYMBOL uses,
+ and optimize. Use ELIMINATE_COPY_RELOCS.
+ (ppc64_elf_relocate_section): Likewise.
+
+ * elf32-ppc.c (struct ppc_elf_dyn_relocs): Add pc_count field.
+ (ppc_elf_copy_indirect_symbol): Copy pc_count field.
+ (ELIMINATE_COPY_RELOCS): Define.
+ (ppc_elf_adjust_dynamic_symbol): Convert copy relocs to dynamic.
+ (WILL_CALL_FINISH_DYNAMIC_SYMBOL): Pass SHARED instead of INFO.
+ (MUST_BE_DYN_RELOC): Define.
+ (allocate_dynrelocs): Adjust WILL_CALL_FINISH_DYNAMIC_SYMBOL uses,
+ and optimize. Trim dyn_relocs.
+ (ppc_elf_check_relocs): Don't generate dyn_relocs when we know they'll
+ not be used. Do generate dyn_relocs for copy reloc avoidance. Keep
+ track of pc_rel dyn relocs.
+ (ppc_elf_relocate_section): Remove "will_become_local". Adjust
+ WILL_CALL_FINISH_DYNAMIC_SYMBOL use. Trim dyn relocs as per
+ allocate_dynrelocs. Don't recalculate "sec".
+
+2003-02-18 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-ppc.c (ppc_elf_relocate_section): Remove unnecessary test.
+ * elf64-ppc.c (ppc64_elf_tls_optimize): Decrement tlsld_got.refcount
+ on invalid LD relocs.
+ (allocate_dynrelocs): Invalid LD relocs don't use tlsld_got entry.
+ (ppc64_elf_relocate_section): Unify new handling of LD relocs and
+ tlsld_got entry. Use IS_PPC64_TLS_RELOC.
+
+ * elf32-ppc.h: New file.
+ * elf32-ppc.c: Include elf32-ppc.h.
+ (NOP, CROR_151515, CROR_313131, TP_OFFSET, DTP_OFFSET): Define.
+ (struct ppc_elf_link_hash_entry): Rename "root" to "elf". Adjust uses.
+ Add "tls_mask" field.
+ (TLS_GD, TLS_LD, TLS_TPREL, TLS_DTPREL, TLS_TLS, TLS_TPRELGD): Define.
+ (struct ppc_elf_link_hash_table): Rename "root" to "elf". Adjust uses.
+ Add got, relgot, plt, relplt, dynbss, relbss, dynsbss, relsbss,
+ sdata, sdata2, tls_sec, tls_get_addr, tlsld_got fields.
+ Make use of htab shortcuts throughout file.
+ (ppc_elf_link_hash_newfunc): Init tls_mask field.
+ (ppc_elf_link_hash_table_create): Init new fields.
+ (ppc_elf_copy_indirect_symbol): Copy tls_mask.
+ (ppc_elf_howto_raw): Add tls relocs.
+ (ppc_elf_reloc_type_lookup): Handle them.
+ (ppc_elf_unhandled_reloc): New function.
+ (ppc_elf_create_got): Stash got section pointer in hash table,
+ return status. Make .rela.got too.
+ (ppc_elf_create_dynamic_sections): Stash section pointers in htab.
+ (ppc_elf_adjust_dynamic_symbol): Only set up copy relocs when
+ NON_GOT_REF set. Don't allocate space in .plt here..
+ (allocate_dynrelocs): ..do so here instead, properly ref-counting and
+ not allocating plt entries unnecessarily. Allocate got entries here.
+ (WILL_CALL_FINISH_DYNAMIC_SYMBOL): Define.
+ (ppc_elf_size_dynamic_sections): Allocate local got entries. Pass
+ "info" during allocate_dynrelocs hash traversal. Use htab section
+ shortcuts rather than searching for named sections. Get rid of
+ "plt" and "strip" booleans.
+ (update_local_sym_info, bad_shared_reloc): New functions.
+ (ppc_elf_check_relocs): Handle TLS relocs. Move .rela.got creation to
+ ppc_elf_create_got. Don't mark got or plt reloc syms dynamic, do so
+ in allocate_dynreloc. Use update_local_sym_info and bad_shared_reloc.
+ Disallow R_PPC_EMB_RELSDA, R_PPC_EMB_NADDR32, R_PPC_EMB_NADDR16,
+ R_PPC_EMB_NADDR16_LO, R_PPC_EMB_NADDR16_HI and R_PPC_EMB_NADDR16_HA
+ in shared libs. R_PPC_PLTREL32 is a plt reloc too. Refcount all
+ relocs that might use a plt entry. Set NON_GOT_REF too.
+ Enumerate all do-nothing relocs.
+ (ppc_elf_gc_sweep_hook): Simplify removal of dynrelocs. Handle
+ tls relocs and all plt relocs.
+ (ppc_elf_tls_setup, ppc_elf_tls_optimize): New functions.
+ (ppc_elf_finish_dynamic_symbol): Don't build got entries here.
+ (ppc_elf_finish_dynamic_sections): Rewrite tag code using htab
+ shortcuts.
+ (ppc_elf_relocate_section): Tidy. Handle TLS relocs. Use
+ bfd_elf_local_sym_name. Simplify unresolved reloc code. Build got
+ entries and got relocs here. Warn on non-zero got reloc addend.
+ Split out branch taken/not taken reloc code into a separate switch
+ and correct offset calculation. Allow BRTAKEN/BRNTAKEN dynamic relocs.
+ Split out HA reloc adjustments to separate switch statement. Don't
+ warn on reloc overflow if we've already warned about undefined.
+ Don't rebuild sym name when reporting errors. Report all possible
+ errors from _bfd_final_link_relocate.
+ (bfd_elf32_bfd_final_link): Don't define.
+
+2003-02-18 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (ppc64_elf_relocate_section): Don't init "r". Don't
+ rebuild sym name when reporting errors.
+
+2003-02-17 Nick Clifton <nickc@redhat.com>
+
+ * elflink.h (elf_link_output_extsym): Only check
+ allow_shlib_undefined for shared libraries.
+ * elf32-i386.c (elf_i386_relocate_section): Remove bogus check
+ of allow_shlib_undefined.
+ * elf32-cris.c (cris_elf_relocate_section): Likewise.
+ * elf32-hppa.c (elf32_hppa_relocate_section): Likewise.
+ * elf32-m68k.c (elf_m68k_relocate_section): Likewise.
+ * elf32-ppc.c (ppc_elf_relocate_section): Likewise.
+ * elf32-s390.c (elf_s390_relocate_section): Likewise.
+ * elf32-sh.c (sh_elf_relocate_section): Likewise.
+ * elf32-sparc.c (elf32_sparc_relocate_section): Likewise.
+ * elf32-vax.c (elf_vax_relocate_section): Likewise.
+ * elf64-alpha.c (elf64_alpha_relocate_section): Likewise.
+ * elf64-hppa.c (elf64_hppa_relocate_section): Likewise.
+ * elf64-ppc.c (ppc64_elf_relocate_section): Likewise.
+ * elf64-s390.c (elf_s390_relocate_section): Likewise.
+ * elf64-sparc.c (sparc64_elf_relocate_section): Likewise.
+ * elf64-x86-64.c (elf64_x86_64_relocate_section): Likewise.
+ * elfxx-ia64.c (elfNN_ia64_relocate_section): Likewise.
+ * elfxx-mips.c (_bfd_mips_elf_relocate_section): Likewise.
+
+2003-02-17 Nick Clifton <nickc@redhat.com>
+
+ * elf.c (SEGMENT_AFTER_SEGMENT): Add third parameter - the
+ address field to use in the comparison.
+ (SEGMENT_OVERLAPS): Check that LMAs overlap as well.
+
+2003-02-14 Bob Wilson <bob.wilson@acm.org>
+
+ * elfcore.h (elf_core_file_p): Compare alternate machine codes for ELF
+ backends when checking if the generic ELF target should be used.
+
+ * syms.c (_bfd_stab_section_find_nearest_line): For line number stabs
+ outside of functions, treat values as absolute addresses.
+
+ * bfd.c: Change embedded documentation to use consistent indentation
+ and to split up long lines. Change informal style of description
+ for functions lacking real documentation.
+ * coffcode.h: Break up long lines in embedded documentation.
+ * format.c: Likewise.
+ * targets.c: Likewise.
+ * libcoff.h: Regenerate.
+ * bfd-in2.h: Regenerate.
+
+2003-02-14 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (ppc64_elf_link_hash_table_create): Init tls_get_addr.
+ (ppc64_elf_copy_indirect_symbol): Merge tls_mask too.
+ (ppc64_elf_gc_sweep_hook): Simplify removal of dyn_relocs.
+ (allocate_dynrelocs): Don't treat undefined and undefweak specially.
+ (ppc_size_one_stub): Fix warning, and tighten plt entry check.
+ (group_sections): Don't share a stub section if stubs are for a large
+ section. Adjust comment.
+ (ppc64_elf_size_stubs): Roughly double the size left for stubs if
+ !stubs_always_before_branch.
+ (ppc64_elf_relocate_section): Initialize tlsld GOT entry once. Don't
+ treat undefined and undefweak specially when processing dyn relocs.
+
+2003-02-13 Jakub Jelinek <jakub@redhat.com>
+
+ * elflink.h (elf_link_add_object_symbols): Handle .symver x, x@FOO.
+
+2003-02-13 Nick Clifton <nickc@redhat.com>
+
+ * elf32-arm.h (elf32_thumb_to_arm_stub): Include section VMAs
+ in computation of offset to insert into BL instruction.
+
+2003-02-11 Uwe Stieber <uwe@wwws.de>
+
+ * config.bfd: Add support for kaOS as cross build target system.
+
+2003-02-11 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (ppc64_elf_check_relocs): Match versioned
+ .__tls_get_addr too.
+ (ppc64_elf_tls_setup): Ensure cached tls_get_addr is not indirect.
+
+2003-02-10 Kaz kojima <kkojima@rr.iij4u.or.jp>
+
+ * elf32-sh.c (elf_sh_dyn_relocs): Add tls_tpoff32 field.
+ (elf_sh_link_hash_entry): Remove tls_tpoff32 field.
+ (sh_elf_link_hash_newfunc): Remove the initialization of
+ tls_tpoff32 field.
+ (allocate_dynrelocs): Keep dyn_relocs if it includes the entry
+ for which tls_tpoff32 flag is set.
+ (sh_elf_relocate_section): Covert to LE only if the dyn_relocs
+ of the symbol includes the entry matched with the input_section
+ and having tls_tpoff32 flag on. When linking statically, set
+ symbol index of R_SH_TLS_TPOFF32 relocation to zero if the symbol
+ is defined in this executable.
+ (sh_elf_check_relocs): Set tls_tpoff32 flag appropriately.
+
+2003-02-10 Jakub Jelinek <jakub@redhat.com>
+
+ * elf32-s390.c (elf_s390_size_dynamic_sections): Set relocs to TRUE
+ even if there is just non-empty .rela.plt.
+
+2003-02-10 Nick Clifton <nickc@redhat.com>
+
+ * archures.c (bfd_mach_arm_ep9312): Define.
+ * bfd-in2.h: Regenerate.
+ * cpu-arm.c (processors[]): Add ep9312.
+ (bfd_arm_arch): Add ep9312.
+ * elf32-arm.h (elf32_arm_merge_private_data): Update error
+ messages and add test for Maverick floating point support.
+ (elf32_arm_print_private_bfd_data): Handle
+ EF_ARM_MAVERICK_FLOAT flag.
+ (elf32_arm_object_p): New function.
+ (elf_backend_object_p): Define.
+
+2003-02-10 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c: Rename assorted occurrences of tls_type and similar
+ variables, structure fields or function params to tls_mask or
+ similar to better reflect usage.
+ (struct got_entry): Comment.
+ (struct ppc_link_hash_entry): Expand comment, and renumber TLS_*.
+ (get_tls_mask): Rename from get_tls_type.
+
+2003-02-09 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (TLS_GD_LD): Don't define..
+ (TLS_GD): ..define this instead and update all uses.
+ (TLS_TPRELGD): Define.
+ (ppc64_elf_link_hash_table_create): Tweak initialization of
+ init_refcount and init_offset.
+ (ppc64_elf_check_relocs): Add one extra element to t_symndx array.
+ Mark second slot of GD or LD toc entries.
+ (get_tls_type): Return an int. Distinguish toc GD and LD entries
+ from other tls types.
+ (ppc64_elf_tls_setup): New function, split out from..
+ (ppc64_elf_tls_optimize): ..here. Don't optimize when symbols are
+ defined in a dynamic object. Fix LD optimization. Don't set TLS_TPREL
+ on GD->IE optimization, use TLS_TPRELGD instead. Use get_tls_type
+ return value to properly decide whether toc GD and LD entries can
+ optimize away __tls_get_addr call. Check next reloc after DTPMOD64
+ to determine GD or LD rather than looking at TLS_LD flag. Don't
+ attempt to adjust got entry tls_type here..
+ (allocate_dynrelocs): ..instead, adjust got entry tls_type here, and
+ look for possible merges.
+ (ppc64_elf_size_dynamic_sections): Adjust local got entries for
+ optimization.
+ (ppc64_elf_size_stubs): Tweak __tls_get_addr fudge.
+ (ppc64_elf_relocate_section): Rename some vars to better reflect usage.
+ Make use of return value from get_tls_type to properly detect GD and
+ LD optimizations. Split tlsld/gd hi/ha from lo/ds case. Don't
+ handle tls_get_addr removal when looking at REL24 relocs, do it when
+ looking at the previous reloc. Check reloc after DTPMOD64 to determine
+ GD or LD.
+ * elf64-ppc.h (ppc64_elf_tls_setup): Declare.
+
+2003-02-08 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-hppa.c (group_sections): Don't share a stub section if
+ stubs are for a large section.
+
+ * elf32-hppa.c (elf32_hppa_size_stubs): Double the size left for
+ stubs if !stubs_always_before_branch.
+
+2003-02-07 Nick Clifton <nickc@redhat.com>
+
+ * elf.c (swap_out_syms): Generate an error message if an
+ equivalent output section cannot be found for a symbol.
+
+2003-02-07 Jakub Jelinek <jakub@redhat.com>
+
+ * elf64-alpha.c (elf64_alpha_relax_section): Don't crash if
+ local_got_entries is NULL.
+
+2003-02-06 Andreas Schwab <schwab@suse.de>
+
+ * elf-eh-frame.c (get_DW_EH_PE_signed): Define.
+ (read_value): Add parameter is_signed, use signed extraction if
+ the value is signed.
+ (_bfd_elf_write_section_eh_frame): Pass signed flag of the
+ encoding to read_value.
+
+2003-02-06 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (ppc64_elf_copy_indirect_symbol): Don't copy got and
+ plt info when called to transfer weak sym info.
+
+2003-02-05 Alan Modra <amodra@bigpond.net.au>
+
+ * reloc.c: Add PPC and PPC64 TLS relocs.
+ * libbfd.h: Regenerate.
+ * bfd-in2.h: Regenerate.
+ * elf64-ppc.c (TP_OFFSET, DTP_OFFSET): Declare.
+ (ppc64_elf_howto_raw): Add TLS howto's. Adjust R_PPC64_NONE to be
+ against a 32 bit field.
+ (ppc64_elf_reloc_type_lookup): Handle TLS relocs.
+ (_ppc64_elf_section_data): Add t_symndx and comments.
+ (ppc64_elf_section_data): Use elf_section_data macro.
+ (ppc64_elf_new_section_hook): American spelling.
+ (struct got_entry, struct plt_entry): New.
+ (MUST_BE_DYN_RELOC): Rename from IS_ABSOLUTE_RELOC.
+ (struct ppc_stub_hash_entry): Add "addend" field.
+ (struct ppc_link_hash_entry): Add "tls_type".
+ (TLS_TLS, TLS_GD_LD, TLS_LD, TLS_TPREL, TLS_DTPREL,
+ TLS_EXPLICIT): Define.
+ (struct ppc_link_hash_table): Add tls_sec, tls_get_addr, tlsld_got.
+ (link_hash_newfunc): Init new fields.
+ (ppc64_elf_link_hash_table_create): Likewise. Set init_refcount and
+ init_offset to NULL.
+ (ppc64_elf_copy_indirect_symbol): Copy got and plt info. Don't call
+ _bfd_elf_link_hash_copy_indirect, rather insert relevant code from
+ there.
+ (update_local_sym_info, update_plt_info): New functions.
+ (ppc64_elf_check_relocs): Use them. Handle TLS relocs. Adjust GOT
+ handling to use got.glist rather than got.refcount. Likewise for PLT.
+ (ppc64_elf_gc_sweep_hook): Handle TLS relocs, new GOT and PLT lists.
+ (func_desc_adjust): Adjust for new PLT list.
+ (ppc64_elf_adjust_dynamic_symbol): Likewise.
+ (get_sym_h, get_tls_type): New functions.
+ (ppc64_elf_edit_opd): Remove unused variable. Use get_sym_h.
+ (ppc64_elf_tls_optimize): New function.
+ (allocate_dynrelocs): Adjust for new PLT and GOT lists. Allocate
+ TLS relocs.
+ (ppc64_elf_size_dynamic_sections): Likewise.
+ (ppc_type_of_stub): Adjust for new PLT list.
+ (ppc_build_one_stub): Likewise.
+ (ppc64_elf_size_stubs): Likewise. Use get_sym_h. Treat __tls_get_addr
+ calls specially.
+ (ppc64_elf_relocate_section): Adjust for new GOT and PLT lists. Handle
+ TLS relocs. Report local syms using bfd_elf_local_sym_name. Don't
+ init GOT entries that have a reloc. Generate GOT relocs here..
+ (ppc64_elf_finish_dynamic_symbol): ..not here. Adjust for PLT list.
+ * elf64-ppc.h (ppc64_elf_tls_optimize): Declare.
+
+2003-02-04 Andreas Schwab <schwab@suse.de>
+
+ * elf32-m68k.c (elf_m68k_hash_entry): Define.
+ (elf_m68k_link_hash_traverse): Remove.
+ (elf_m68k_link_hash_newfunc): Use struct bfd_hash_entry and
+ elf_m68k_hash_entry instead of struct elf_m68k_link_hash_entry to
+ reduce casting.
+ (elf_m68k_check_relocs): Use elf_m68k_hash_entry instead of
+ casting.
+ (elf_m68k_size_dynamic_sections): Use elf_link_hash_traverse
+ instead of elf_m68k_link_hash_traverse.
+ (elf_m68k_discard_copies): Change first parameter to pointer to
+ struct elf_link_hash_entry and use elf_m68k_hash_entry when struct
+ elf_m68k_link_hash_entry is needed.
+
+2003-02-04 Alan Modra <amodra@bigpond.net.au>
+
+ * elf-bfd.h (struct got_entry, struct plt_entry): Forward declare.
+ (struct elf_link_hash_entry): Add "glist" and "plist" fields to
+ "got" union, and declare as gotplt_union. Use gotplt_uinion for
+ "plt" field.
+ (struct elf_link_hash_table): Make "init_refcount" a gotplt_union.
+ Add "init_offset" field.
+ (struct elf_obj_tdata <local_got>): Add "struct got_entry **" to union.
+ (elf_local_got_ents): Declare.
+ * elf.c (_bfd_elf_link_hash_newfunc): Adjust initialization of "got"
+ and "plt".
+ (_bfd_elf_link_hash_hide_symbol): Use "init_offset".
+ (_bfd_elf_link_hash_table_init): Set "init_offset".
+ * elflink.h (NAME(bfd_elf,size_dynamic_sections)): Set init_refcount
+ from init_offset.
+ (elf_adjust_dynamic_symbol): Set plt and got offsets using init_offset.
+
+ * elf.c (bfd_elf_local_sym_name): Split out from..
+ (group_signature): ..here.
+ * elf-bfd.h (bfd_elf_local_sym_name): Declare.
+
+2003-02-04 Alan Modra <amodra@bigpond.net.au>
+
+ * elf-bfd.h (enum elf_link_info_type): Remove.
+ (struct bfd_elf_section_data): Move sec_info_type, use_rela_p fields
+ to struct sec. Remove linkonce_p field.
+ (elf_linkonce_p): Delete.
+ (elf_discarded_section): Update for sec_info_type change.
+ * section.c (struct sec): Add sec_info_type, use_rela_p, has_tls_reloc,
+ flag11, flag12, flag13, flag14, flag15, flag16, flag20, flag24.
+ (ELF_INFO_TYPE_NONE): Define.
+ (ELF_INFO_TYPE_STABS): Define.
+ (ELF_INFO_TYPE_MERGE): Define.
+ (ELF_INFO_TYPE_EH_FRAME): Define.
+ (ELF_INFO_TYPE_JUST_SYMS): Define.
+ (STD_SECTION): Update struct sec initializer.
+ * ecoff.c (bfd_debug_section): Likewise.
+ * elf.c: Likewise. Update occurrences of sec_info_type and use_rela_p.
+ * elflink.h: Likewise.
+ * elf-eh-frame.c: Likewise.
+ * elf64-alpha.c: Likewise.
+ * elfxx-ia64.c: Likewise.
+ * elfxx-mips.c: Likewise.
+ * bfd-in2.h: Regenerate.
+
+ * elf32-sparc.c (sec_do_relax): Use elf_section_data macro rather than
+ referring to used_by_bfd.
+ * elf64-sparc.c (sec_do_relax): Likewise.
+ * elf64-mmix.c (mmix_elf_section_data): Likewise.
+ * elfxx-mips.c (mips_elf_section_data): Likewise.
+ * ieee.c (ieee_slurp_section_data): Use ieee_per_section macro.
+ (ieee_get_section_contents): Likewise.
+ (ieee_new_section_hook): Formatting.
+ (ieee_canonicalize_reloc): Remove commented out code.
+ * mmo.c (mmo_section_data): Define. Use throughout file.
+ * oasys.c (oasys_get_section_contents): Use oasys_per_section macro.
+
+2003-01-31 Graydon Hoare <graydon@redhat.com>
+
+ * Makefile.am (opncls.lo): Add dependency upon libiberty.h.
+ * Makefile.in: Regenerate.
+ * opncls.c (calc_crc32, get_debug_link_info,
+ seperate_debug_file_exists, find_seperate_debug_file): New
+ internal functions.
+ (bfd_follow_gnu_debuglink): New function. Follow the pointer
+ contained inside a .gnu_debuglink section.
+ * bfd-in2.h: Regenerate.
+
+2003-01-29 Alexandre Oliva <aoliva@redhat.com>
+
+ * elfxx-mips.c (mips_elf_got_entry_hash): Don't dereference
+ entry->abfd when it's NULL.
+
+2003-01-27 Alexandre Oliva <aoliva@redhat.com>
+
+ * elfxx-mips.c (mips_elf_create_dynamic_relocation): Handle
+ _bfd_elf_section_offset returning -2 the same way as -1.
+
+ * elfxx-mips.c (mips_elf_multi_got): New function.
+ (struct mips_got_entry): Make symndx and gotidx signed. Moved
+ addend into union along with address and link hash entry.
+ (struct mips_got_info): Added bfd2got and next.
+ (struct mips_elf_hash_sort_data): Added max_unref_got_dynindx.
+ (mips_elf_got_section, mips_elf_create_got_section): Use
+ SEC_EXCLUDE bit to tell whether we really need the got
+ section. Take boolean arguments to disregard an excluded
+ section, or to create it as excluded. Adjust all callers.
+ Use mips_elf_got_section all over.
+ (mips_elf_local_got_index, mips_elf_got_page,
+ mips_elf_got16_entry): Take input bfd as argument, and pass it
+ on to mips_elf_create_local_got_entry.
+ (mips_elf_global_got_index, mips_elf_create_local_got_entry):
+ Take input bfd as argument, and manage entries in the
+ appropriate GOT.
+ (mips_elf_got_offset_from_index): Take input bfd as argument,
+ and use it to adjust the GP offset of the bfd.
+ (mips_elf_sort_hash_table, mips_elf_sort_hash_table_f): Move
+ unreferenced GOT entries of global symbols to the end.
+ (mips_elf_record_global_got_symbol): Take input bfd as
+ argument. Add entries to the master GOT hash table.
+ (struct mips_elf_bfd2got_hash): New.
+ (struct mips_elf_got_per_bfd_arg): New.
+ (struct mips_elf_set_global_got_offset_arg): New.
+ (mips_elf_hash_bfd_vma, mips_elf_multi_got_entry_hash,
+ mips_elf_multi_got_entry_eq, mips_elf_bfd2got_entry_hash,
+ mips_elf_bfd2got_entry_eq, mips_elf_make_got_per_bfd,
+ mips_elf_merge_gots, mips_elf_set_global_got_offset,
+ mips_elf_resolve_final_got_entry,
+ mips_elf_resolve_final_got_entries, mips_elf_adjust_gp,
+ mips_elf_got_for_ibfd): New functions.
+ (ELF_MIPS_GP_OFFSET): Don't depend on SGI_COMPAT.
+ (MIPS_ELF_GOT_MAX_SIZE): New macro.
+ (STUB_LW): Generate 64-bit stub regardless of SGI_COMPAT.
+ (mips_elf_got_entry_hash): Take new fields into account. Use
+ mips_elf_hash_bfd_vma.
+ (mips_elf_got_entry_eq): Take new fields into account.
+ (mips_elf_create_got_section): Initialize new fields.
+ (mips_elf_calculate_relocation): Pass input_bfd to functions
+ that now take it. Adjust gp for the input_bfd.
+ (mips_elf_allocate_dynamic_relocation,
+ mips_elf_create_dynamic_relocation,
+ _bfd_mips_elf_create_dynamic_sections): Use...
+ (mips_elf_rel_dyn_section): New function. Borrow code from...
+ (_bfd_mips_elf_check_relocs): Pass input_bfd to functions that
+ now take it. Create the got section if needed, even if
+ excluded, before recording a global got symbol. Move some
+ code to...
+ (mips_elf_record_local_got_symbol): New fn.
+ (_bfd_mips_elf_size_dynamic_sections): Disable combreloc.
+ Compute multi-got global entries offsets. Move GOT code to...
+ (_bfd_mips_elf_always_size_sections): Call mips_elf_multi_got
+ if the GOT is too big.
+ (_bfd_mips_elf_finish_dynamic_symbol): Set got entry of
+ undefweak symbol to zero. Generate dynamic relocations for
+ non-primary GOT entries for global symbols.
+ (_bfd_mips_elf_finish_dynamic_sections): Handle multi-got
+ case. Generate dynamic relocations for local got entries.
+ Sort dynamic relocations on N64 too, using...
+ (sort_dynamic_relocs_64): New fns.
+ (_bfd_mips_elf_hide_symbol): Adjust multi-got counters.
+ (_bfd_mips_elf_merge_private_bfd_data): Ignore EF_MIPS_XGOT.
+
+2003-01-27 Alexandre Oliva <aoliva@redhat.com>
+
+ * bfd.c (struct _bfd): Added id field.
+ * opncls.c (_bfd_id_counter): New static variable.
+ (_bfd_new_bfd): Use it.
+ * bfd-in2.h: Rebuilt.
+
+2003-01-25 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-sparc.c (bfd_elf32_new_section_hook): Define.
+
+2003-01-25 Jakub Jelinek <jakub@redhat.com>
+
+ * elf32-sparc.c (_bfd_sparc_elf_howto_table): Add TLS relocs.
+ (elf32_sparc_rev32_howto): New variable.
+ (sparc_reloc_map): Add TLS relocs.
+ (elf32_sparc_reloc_type_lookup, elf32_sparc_info_to_howto):
+ Handle REV32.
+ (sparc_elf_hix22_reloc, sparc_elf_lox10_reloc, elf32_sparc_mkobject):
+ New functions.
+ (struct elf32_sparc_dyn_relocs, struct elf32_sparc_link_hash_entry,
+ struct elf32_sparc_link_hash_table):
+ New structures.
+ (elf32_sparc_tdata, elf32_sparc_local_got_tls_type,
+ elf32_sparc_hash_table): Define.
+ (link_hash_newfunc, elf32_sparc_link_hash_table_create,
+ create_got_section, elf32_sparc_create_dynamic_sections,
+ elf32_sparc_copy_indirect_symbol, elf32_sparc_tls_transition): New
+ functions.
+ (elf32_sparc_check_relocs): Handle TLS relocs. Add dynamic reloc
+ reference counting.
+ (elf32_sparc_gc_sweep_hook): Likewise.
+ (elf32_sparc_adjust_dynamic_symbol): Likewise.
+ (elf32_sparc_size_dynamic_sections): Likewise.
+ (elf32_sparc_relocate_section): Likewise.
+ (allocate_dynrelocs, readonly_dynrelocs, dtpoff_base, tpoff):
+ New functions.
+ (elf32_sparc_object_p): Allocate backend private object data.
+ (bfd_elf32_bfd_link_hash_table_create,
+ elf_backend_copy_indirect_symbol, bfd_elf32_mkobject,
+ elf_backend_can_refcount): Define.
+ (elf_backend_create_dynamic_sections): Define to
+ elf32_sparc_create_dynamic_sections.
+ * reloc.c: Add SPARC TLS relocs.
+ * bfd-in2.h, libbfd.h: Rebuilt.
+ * elf64-sparc.c (sparc64_elf_howto_table): Add TLS relocs.
+ (sparc_reloc_map): Likewise.
+
+2003-01-24 Martin Schwidefsky <schwidefsky@de.ibm.com>
+
+ * bfd-in2.h: Regenerate.
+ * elf32-s390.c (elf_s390_mkobject, elf_s390_tls_transition,
+ s390_tls_reloc, dtpoff_base, tpoff, invalid_tls_insn): New functions.
+ (elf_howto_table): Add TLS relocs.
+ (elf_s390_reloc_type_lookup): Likewise.
+ (elf_s390_link_hash_entry): Add tls_type.
+ (elf_s390_hash_entry, elf_s390_obj_tdata, elf_s390_local_got_tls_type):
+ New macros.
+ (elf_s390_link_hash_table): Add tls_ldm_got.
+ (link_hash_newfunc): Initialize tls_type.
+ (elf_s390_link_hash_table_create): Initialize refcount of tls_ldm_got.
+ (elf_s390_copy_indirect_symbol): Copy tls_type information.
+ (elf_s390_check_relocs): Support TLS relocs.
+ (elf_s390_gc_sweep_hook): Likewise.
+ (allocate_dynrelocs): Likewise.
+ (elf_s390_size_dynamic_sections): Likewise.
+ (elf_s390_relocate_section): Likewise.
+ (elf_s390_finish_dynamic_symbol): Likewise.
+ (bfd_elf32_mkobject): Define for TLS.
+ * elf64-s390.c: Same changes as for elf32-s390.c.
+ * libbfd.h: Regenerate.
+ * reloc.c: Add s390 TLS relocations.
+
+2003-01-24 Charles Lepple <clepple@ghz.cc>
+
+ * aclocal.m4: Fix name of --enable-install-libbfd switch.
+
+2003-01-23 Nick Clifton <nickc@redhat.com>
+
+ * Add sh2e support:
+ 2002-04-02 Elena Zannoni <ezannoni@redhat.com>
+ * archures.c (bfd_mach_sh2e): Added.
+ * bfd-in2.h: Rebuilt.
+ * cpu-sh.c (arch_info_struct): Added SH2e.
+ * elf32-sh.c (sh_elf_set_mach_from_flags): Handle EF_SH2E.
+
+2003-01-23 Alan Modra <amodra@bigpond.net.au>
+
+ * elf-bfd.h (struct bfd_elf_section_data): Remove tdata. Change
+ dynindx to an int. Rearrange for better packing.
+ * elf.c (_bfd_elf_new_section_hook): Don't alloc if already done.
+ * elf32-mips.c (bfd_elf32_new_section_hook): Define.
+ * elf32-sh64.h: New. Split out from include/elf/sh.h.
+ (struct _sh64_elf_section_data): New struct.
+ (sh64_elf_section_data): Don't dereference sh64_info (was tdata).
+ * elf32-sh64-com.c: Include elf32-sh64.h.
+ * elf32-sh64.c: Likewise.
+ (sh64_elf_new_section_hook): New function.
+ (bfd_elf32_new_section_hook): Define.
+ (sh64_elf_fake_sections): Adjust for sh64_elf_section_data change.
+ (sh64_bfd_elf_copy_private_section_data): Likewise.
+ (sh64_elf_final_write_processing): Likewise.
+ * elf32-sparc.c (struct elf32_sparc_section_data): New.
+ (elf32_sparc_new_section_hook): New function.
+ (SET_SEC_DO_RELAX, SEC_DO_RELAX): Delete.
+ (sec_do_relax): Define.
+ (elf32_sparc_relax_section): Adjust to use sec_do_relax.
+ (elf32_sparc_relocate_section): Likewise.
+ * elf64-mips.c (bfd_elf64_new_section_hook): Define.
+ * elf64-mmix.c (struct _mmix_elf_section_data): New.
+ (mmix_elf_section_data): Define. Use throughout file.
+ (mmix_elf_new_section_hook): New function.
+ (bfd_elf64_new_section_hook): Define.
+ * elf64-ppc.c (struct _ppc64_elf_section_data): New.
+ (ppc64_elf_section_data): Define. Use throughout.
+ (ppc64_elf_new_section_hook): New function.
+ (bfd_elf64_new_section_hook): Define.
+ * elf64-sparc.c (struct sparc64_elf_section_data): New.
+ (sparc64_elf_new_section_hook): New function.
+ (SET_SEC_DO_RELAX, SEC_DO_RELAX): Delete.
+ (sec_do_relax): Define.
+ (sparc64_elf_relax_section): Adjust to use sec_do_relax.
+ (sparc64_elf_relocate_section): Likewise.
+ (bfd_elf64_new_section_hook): Define.
+ * elfn32-mips.c (bfd_elf32_new_section_hook): Define.
+ * elfxx-mips.c (struct _mips_elf_section_data): New.
+ (mips_elf_section_data): Define. Use throughout.
+ (_bfd_mips_elf_new_section_hook): New function.
+ (mips_elf_create_got_section): Don't alloc used_by_bfd.
+ * elfxx-mips.h (_bfd_mips_elf_new_section_hook): Declare.
+ * elfxx-target.h (bfd_elfNN_new_section_hook): Add #ifndef.
+ * Makefile.am: Run "make dep-am".
+ * Makefile.in: Regenerate.
+
+2003-01-21 Richard Henderson <rth@redhat.com>
+
+ * elf64-alpha.c (ALPHA_ELF_LINK_HASH_PLT_LOC): New.
+ (struct alpha_elf_link_hash_entry): Add plt_old_section, plt_old_value.
+ (elf64_alpha_adjust_dynamic_symbol): Set them.
+ (elf64_alpha_size_plt_section_1): Reset them when plt entry removed.
+ (elf64_alpha_relax_tls_get_addr): Handle LDM relocs. Frob the
+ symbol index when relaxing LDM to TPREL.
+ (elf64_alpha_relax_section): Likewise. Allow relaxation of GD
+ relocs, even if the target isn't locally defined.
+ (elf64_alpha_check_relocs): Frob LDM reloc symndx to zero.
+ (elf64_alpha_relocate_section): Likewise. Force TP-relative
+ relocs vs symndx 0 to the tp base.
+
+2003-01-21 Fabio Alemagna <falemagn@aros.org>
+
+ * config.bfd: Handle i[3456]86-*-aros*.
+
+2003-01-21 Andreas Schwab <schwab@suse.de>
+
+ * elf32-ppc.c (struct ppc_elf_dyn_relocs): Define.
+ (struct ppc_elf_link_hash_entry): Define.
+ (ppc_elf_hash_entry): New function.
+ (struct ppc_elf_link_hash_table): Define.
+ (ppc_elf_hash_table): New function.
+ (ppc_elf_link_hash_newfunc): New function.
+ (ppc_elf_link_hash_table_create): New function.
+ (ppc_elf_copy_indirect_symbol): New function.
+ (allocate_dynrelocs): New function.
+ (readonly_dynrelocs): New function.
+ (ppc_elf_size_dynamic_sections): Allocate space for dynamic
+ relocs and determine DT_TEXTREL.
+ (ppc_elf_check_relocs): Don't do that here, just count the
+ dynamic relocs.
+ (ppc_elf_gc_sweep_hook): Discard any dynamic relocs against the
+ removed section.
+ (bfd_elf32_bfd_link_hash_table_create): Define.
+ (elf_backend_copy_indirect_symbol): Define.
+
+2003-01-21 Richard Henderson <rth@redhat.com>
+
+ * elf64-alpha.c (alpha_dynamic_entries_for_reloc): GOTTPREL and
+ TPREL also get a reloc if shared. Remove SREL support.
+ (elf64_alpha_emit_dynrel): New.
+ (elf64_alpha_relocate_section): Use it. Resolve dynamic TPREL
+ and GOTTPREL relocs to local symbols against the tp base.
+ (elf64_alpha_finish_dynamic_symbol): Use elf64_alpha_emit_dynrel.
+
+ * elf64-alpha.c (elf64_alpha_relax_got_load): Decrement got
+ use count before clobbering r_type.
+ (elf64_alpha_relax_tls_get_addr): Don't use pos[1] if insn
+ ordering would mean dataflow inspection is necessary.
+
+2003-01-20 Svein E. Seldal <Svein.Seldal@solidas.com>
+
+ * coffcode.h (coff_set_flags): Added get/set arch hooks.
+
+2003-01-20 Fabio Alemagna <falemagn@aros.org>
+
+ * elf32-sh.c: Treat elfNN_bed like other macros defined in
+ elfxx-target.h and #undef it before #define'ing it.
+ * elf32-i386.c: Likewise.
+ * elf32-sh64.c: Likewise.
+ * elf64-alpha.c: Likewise.
+ * elf64-sh64.c: Likewise.
+
+2003-01-20 Martin Schwidefsky <schwidefsky@de.ibm.com>
+
+ * bfd-in2.h: Regenerate.
+ * elf32-s390.c (elf_s390_adjust_gotplt): New prototype.
+ (elf_howto_table): Rename R_390_GOTOFF to R_390_GOTOFF32. Add
+ R_390_GOTOFF16, R_390_GOTOFF64, R_390_GOTPLT12, R_390_GOTPLT16,
+ R_390_GOTPLT32, R_390_GOTPLT64, R_390_GOTPLTENT, R_390_PLTOFF16,
+ R_390_PLTOFF32 and R_390_PLTOFF64.
+ (elf_s390_reloc_type_lookup): Likewise.
+ (struct elf_s390_link_hash_entry): Add gotplt_refcount to keep track
+ of GOTPLT references to a function.
+ (link_hash_newfunc): Initialize gotplt_refcount.
+ (elf_s390_check_relocs): Move allocation of local_got_refcounts array
+ and creation of the got section out of the main switch. Add support
+ for the gotoff, gotplt and pltoff relocations.
+ (elf_s390_gc_sweep_hook): Add reference counting for gotoff, gotplt
+ and pltoff.
+ (elf_s390_adjust_gotplt): New function.
+ (elf_s390_adjust_dynamic_symbol): Adjust gotplt refcount for removed
+ plt entries.
+ (allocate_dynrelocs): Add comment.
+ (elf_s390_relocate_section): Change r_type to unsigned. Add support
+ for gotoff, gotplt and pltoff relocations.
+ * elf64-s390.c: Same changes as for elf32-s390.c.
+ * libbfd.h: Regenerate.
+ * reloc.c: Add BFD_RELOC_390_GOTOFF64, BFD_RELOC_390_GOTPLT12,
+ BFD_RELOC_390_GOTPLT16, BFD_RELOC_390_GOTPLT32, BFD_RELOC_390_GOTPLT64,
+ BFD_RELOC_390_GOTPLTENT, BFD_RELOC_390_PLTOFF16, BFD_RELOC_390_PLTOFF32
+ and BFD_RELOC_390_PLTOFF64.
+
+2003-01-18 Jakub Jelinek <jakub@redhat.com>
+
+ * elfxx-ia64.c (elfNN_ia64_relocate_section): Handle
+ R_IA64_TPREL64[LM]SB against non-global symbol properly.
+
+2003-01-16 Jakub Jelinek <jakub@redhat.com>
+
+ * elfxx-ia64.c (struct elfNN_ia64_link_hash_table): Add
+ self_dtpmod_done and self_dtpmod_offset.
+ (allocate_global_data_got): Only use one got entry for all
+ dtpmod relocs against local symbols.
+ (allocate_dynrel_entries): Only need .rela.got entry for
+ dtpmod against global symbol.
+ (elfNN_ia64_size_dynamic_sections): Initialize self_dtpmod_offset.
+ Reserve space in .rela.got for the local dtpmod entry.
+ (set_got_entry): Initialize the common local dtpmod .got entry.
+ (elfNN_ia64_relocate_section): Handle R_IA_64_DTPREL64LSB
+ and R_IA_64_DTPREL64MSB.
+
+2003-01-16 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c: Include elf/ppc64.h rather than elf/ppc.h.
+ (R_PPC_*): Rename all occurrences to R_PPC64_*.
+ (R_PPC64_ADDR30): Rename all occurrences to R_PPC64_REL30.
+ (enum elf_ppc_reloc_type): Ditto to enum elf_ppc64_reloc_type.
+ (ppc64_elf_gc_sweep_hook): Handle R_PPC64_REL30 along with other
+ relative relocs, not with absolute ones.
+ * Makefile.am: Run "make dep-am".
+ * Makefile.in: Regenerate.
+ * po/SRC-POTFILES.in: Regenerate.
+
+2003-01-15 Andreas Schwab <schwab@suse.de>
+
+ * elf32-ppc.c (ppc_elf_check_relocs): Don't set DF_TEXTREL for a
+ relocation against a non-allocated readonly section.
+
+2003-01-10 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-ppc.c (ppc_elf_relocate_section): Adjust addend for GOT16_HA.
+ * elf64-ppc.c (ppc64_elf_relocate_section): Likewise. PLTGOT16_HA too.
+
+2002-01-08 Klee Dienes <kdienes@apple.com>
+
+ * Makefile.am (ALL_MACHINES): Use cpu-msp430.lo, not cpu-msp430.c.
+ (BFD32_BACKENDS): Use elf32-msp430.lo, not elf32-msp430.c.
+ * Makefile.in: Regenerate.
+
+2003-01-08 Alexandre Oliva <aoliva@redhat.com>
+
+ * elfn32-mips.c (prev_reloc_section): New.
+ (GET_RELOC_ADDEND): Use it. Parenthesize macro arguments.
+ (SET_RELOC_ADDEND): Parenthesize macro argument.
+
+2003-01-07 John David Anglin <dave.anglin@nrc.gc.ca>
+
+ * elf32-hppa.c (final_link_relocate): For all DP relative relocations,
+ adjust addil instructions if the symbol has no section.
+
+2003-01-07 DJ Delorie <dj@redhat.com>
+
+ * elf32-xstormy16.c (xstormy16_elf_howto_table): Make REL_12 not
+ partial_inplace.
+
+2003-01-07 Andreas Schwab <schwab@suse.de>
+
+ * elf32-m68k.c (elf_m68k_check_relocs): Don't set DF_TEXTREL for
+ PC relative relocations.
+ (elf_m68k_discard_copies): Set it here instead.
+
+2002-01-02 Ben Elliston <bje@redhat.com>
+ Jeff Johnston <jjohnstn@redhat.com>
+
+ * Makefile.am (ALL_MACHINES): Add cpu-iq2000.lo.
+ (ALL_MACHINES_CFILES): Add cpu-iq2000.c.
+ (BFD32_BACKENDS): Add elf32-iq2000.lo.
+ (BFD32_BACKENDS_CFILES): Add elf32-iq2000.c.
+ (cpu-iq2000.lo): New target.
+ * Makefile.in: Regenerate.
+ * config.bfd: Handle iq2000-*-elf.
+ * archures.c (bfd_architecture): Add bfd_{arch,mach}_iq2000.
+ (bfd_archures_list): Add bfd_iq2000_arch.
+ * configure.in: Handle bfd_elf32_iq2000_vec.
+ * configure: Regenerate.
+ * reloc.c: Add BFD_RELOC_IQ2000_OFFSET_16, BFD_RELOC_IQ2000_OFFSET_21,
+ and BFD_RELOC_IQ2000_UHI16.
+ * targets.c (bfd_elf32_iq2000_vec): Declare.
+ (bfd_target_vector): Add bfd_elf32_iq2000_vec.
+ * elf.c (prep_headers): Set e_machine to EM_IQ2000.
+ * cpu-iq2000.c: New file.
+ * elf32-iq2000.c: Likewise.
+ * libbfd.h: Regenerate.
+ * bfd-in2.h: Likewise.
+
+2003-01-02 Richard Sandiford <rsandifo@redhat.com>
+
+ * elfxx-mips.c: Include libiberty.h.
+ (elf_mips_isa, _bfd_mips_elf_mach_extends_p): Remove.
+ (mips_set_isa_flags): New function, split out from...
+ (_bfd_mips_elf_final_write_processing): ...here. Only call
+ mips_set_isa_flags if the EF_MIPS_MACH bits are clear.
+ (mips_mach_extensions): New array.
+ (mips_32bit_flags_p): New function.
+ (_bfd_mips_elf_merge_private_bfd_data): Rework architecture checks.
+ Use mips_32bit_flags_p to check if one binary is 32-bit and the
+ other is 64-bit. When adopting IBFD's architecture, adopt the
+ bfd_mach as well as the flags.
+
+2003-01-02 Nick Kelsey <nickk@ubicom.com>
+
+ * elf32-ip2k.c: Re-work of linker relaxation code for the ip2k to
+ fix internal errors, fix bad code generation, fix incorrect stabs
+ information, and improve ability to eliminate redundant page
+ instructions. Added code to ip2k_final_link_relocate to self-verify
+ the linker relaxation. Fix formatting problems.
+
+2002-12-30 Chris Demetriou <cgd@broadcom.com>
+
+ * aoutx.h (NAME(aout,machine_type)): Add bfd_mach_mipsisa32r2 case.
+ * archures.c (bfd_mach_mipsisa32r2): New define.
+ * bfd-in2.h: Regenerate.
+ * cpu-mips.c (I_mipsisa32r2): New enum value.
+ (arch_info_struct): Add entry for I_mipsisa32r2.
+ * elfxx-mips.c (elf_mips_isa, _bfd_elf_mips_mach)
+ (_bfd_mips_elf_print_private_bfd_data): Handle E_MIPS_ARCH_32R2.
+ (_bfd_mips_elf_final_write_processing): Add
+ bfd_mach_mipsisa32r2 case.
+ (_bfd_mips_elf_merge_private_bfd_data): Handle merging of
+ binaries marked as using MIPS32 Release 2.
+
+2002-12-30 Dmitry Diky <diwil@mail.ru>
+
+ * Makefile.am: Add msp430 target.
+ * configure.in: Likewise.
+ * Makefile.in: Regenerate.
+ * configure: Regenerate.
+ * archures.c: Add msp430 architecture vector.
+ * config.bfd: Likewise.
+ * reloc.c: Add msp430 relocs.
+ * targets.c: Add msp320 target.
+ * cpu-msp430.c: New file: msp430 cpu detection.
+ * elf32-msp430.c: New file: msp430 reloc processing.
+ * bfd-in2.h: Regenerate.
+ * libbfd.h: Regenerate.
+
+2002-12-28 Jakub Jelinek <jakub@redhat.com>
+
+ * elf.c (elf_sort_sections): Don't reorder .tbss.
+ (assign_file_positions_for_segments): Only adjust off/voff
+ for increased alignment in PT_LOAD or PT_NOTE segment,
+ but adjust p_filesz for .tbss too. in PT_LOAD consider
+ .tbss to have zero memory size.
+ (copy_private_bfd_data) [SECTION_SIZE]: Define.
+ [IS_CONTAINED_BY_VMA, IS_CONTAINED_BY_LMA]: Use it.
+ [INCLUDE_SECTION_IN_SEGMENT]: Only put SHF_TLS sections
+ into PT_TLS segment. Never put SHF_TLS sections in
+ segments other than PT_TLS or PT_LOAD.
+
+ * elf64-alpha.c (elf64_alpha_finish_dynamic_sections): Clear .plt
+ sh_entsize.
+
+2002-12-23 DJ Delorie <dj@redhat.com>
+
+ * coff64-rs6000.c (xcoff64_ppc_relocate_section): Fix logic reversal.
+
+2002-12-23 Alan Modra <amodra@bigpond.net.au>
+
+ * elflink.h (elf_link_output_extsym): Heed strip_discarded.
+
+2002-12-23 Nick Clifton <nickc@redhat.com>
+
+ * archures.c (bfd_arch_get_compatible): Add third parameter
+ 'accept_unknowns'. Only accept unknown format BFDs if
+ accept_unknowns is true, or if the format is "binary".
+ * bfd-in2.h: Regenerate.
+
+2002-12-21 Nick Clifton <nickc@redhat.com>
+
+ * coff-arm.c (coff_arm_relocate_section): Disable WINCE workaround
+ that subtracted 8 from pc relative relocations.
+
+2002-12-20 Kazu Hirata <kazu@cs.umass.edu>
+
+ * coff-h8300.c: Fix comment typos.
+ * coffcode.h: Likewise.
+ * cpu-cris.c: Likewise.
+ * elf32-vax.c: Likewise.
+ * genlink.h: Likewise.
+ * linker.c: Likewise.
+ * som.c: Likewise.
+ * tekhex.c: Likewise.
+ * vms-misc.c: Likewise.
+
+2002-12-20 DJ Delorie <dj@redhat.com>
+
+ * reloc.c: Add BFD_RELOC_XSTORMY16_12.
+ * libbfd.h: Regenerate.
+ * bfd-in2.h: Regenerate.
+ * elf32-xstormy16.c (xstormy16_elf_howto): Add R_XSTORMY16_12.
+ (xstormy16_reloc_map): Add R_XSTORMY16_12.
+
+2002-12-19 Kazu Hirata <kazu@cs.umass.edu>
+
+ * doc/bfdint.texi: Fix typos.
+
+2002-12-20 Paul Eggert <eggert@twinsun.com>
+
+ Port to POSIX 1003.1-2001.
+ * acinclude.m4 (AM_INSTALL_LIBBFD): Do not rely on "test -o".
+ * configure.in (build-warnings): Likewise.
+ (Horrible hacks to build DLLs on Windows): Do not rely on "tail -1".
+ * aclocal.m4: Regenerate.
+ * config.in: Regenerate.
+ * configure: Regenerate.
+
+2002-12-19 Alan Modra <amodra@bigpond.net.au>
+
+ * coff-h8300.c: Include libiberty.h.
+ (h8300_reloc16_extra_cases): Check the hash table creator before
+ referencing h8300 specific fields. Stash the hash table pointer
+ in a local var. Comment typo fixes.
+ (h8300_bfd_link_add_symbols): Likewise.
+
+ * reloc.c (struct reloc_howto_struct): Revise src_mask and
+ dst_mask comments.
+ * bfd-in2.h: Regenerate.
+
+2002-12-18 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-ppc.c (ppc_elf_relocate_section): Reorganize dynamic reloc
+ code a little. Comment on dynamic relocs against section symbols.
+
+2002-12-17 Roger Sayle <roger@eyesopen.com>
+
+ * configure.host (ia64-*-hpux*): Support 64 bit targets using
+ the HP compiler's "long long".
+
+2002-12-16 Andrew MacLeod <amacleod@redhat.com>
+
+ * elf32-xstormy16.c (xstormy16_elf_howto): Add R_XSTORMY16_LO16
+ and R_XSTORMY16_HI16) howto entries.
+ (xstormy16_reloc_map): Map R_XSTORMY16_{LO,HI}16 to BFD_RELOC_{LO,HI}16.
+ (xstormy16_info_to_howto_rela): Use R_XSTORMY16_GNU_VTINHERIT to
+ determine the start of the second reloc table.
+
+2002-12-16 Nathan Tallent <eraxxon@alumni.rice.edu>
+
+ * ecofflink.c: Fix the reading of the debugging information
+ of Tru64/Alpha binaries that are produced by recent Compaq
+ compilers.
+ (mk_fdrtab): Fix error in creating the FDR (file descriptor)
+ table.
+ (lookup_line): Because of the strange information sometimes
+ generated by Compaq's recent compilers, change how the FDR
+ table is searched so that PDRs (procedure descriptors) are
+ correctly found. Note that this change is really more of a hack;
+ however, I have included extensive documentation as to why
+ this is the best solution short of an extensive rewrite or
+ another hack.
+ (fdrtab_lookup): Add comments to explain the algorithm.
+
+2002-12-12 Alexandre Oliva <aoliva@redhat.com>
+
+ * elf-m10300.c (elf32_mn10300_link_hash_newfunc): Reorder
+ initializers to match struct declaration.
+
+2002-12-12 Alan Modra <amodra@bigpond.net.au>
+
+ * dwarf2.c (comp_unit_contains_address): Comment typo fix.
+ * elf.c (get_program_header_size): Likewise.
+ * elf32-m32r.c (m32r_elf_lo16_reloc): Likewise.
+ (m32r_elf_generic_reloc): Likewise.
+ * elf32-ppc.c (ppc_elf_howto_init): Likewise.
+ * elflink.h (elf_bfd_discard_info): Likewise.
+
+2002-12-12 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-i386.c (elf_i386_finish_dynamic_sections): Add output_offset
+ to DT_JMPREL. Use srelplt input section size for DT_PLTRELSZ and
+ DT_RELSZ adjustment, not output section. Avoid writing tags when
+ unchanged. Don't assume linker script is sane, adjust DT_REL too.
+ * elf32-hppa.c (elf32_hppa_finish_dynamic_sections): Just use raw
+ size of srelplt for DT_PLTRELSZ. Use srelplt input section size for
+ DT_RELASZ adjustment, not output section. Avoid writing tags when
+ unchanged. Adjust DT_RELA.
+ * elf64-ppc.c (ppc64_elf_finish_dynamic_sections): Tweaks for better
+ formatting. Avoid writing tags when unchanged. Adjust DT_RELA.
+
+2002-12-12 Alexandre Oliva <aoliva@redhat.com>
+
+ * elfxx-mips.c (mips_elf_calculate_relocation): Don't divide
+ addend by 4.
+
+2002-12-12 Alexandre Oliva <aoliva@redhat.com>
+
+ * elfxx-mips.c (struct mips_got_entry): New.
+ (struct mips_got_info): Added got_entries field.
+ (mips_elf_got_entry_hash, mips_elf_got_entry_eq): New functions.
+ (mips_elf_local_got_index, mips_elf_got_page,
+ mips_elf_got16_entry): Re-implement in terms of new...
+ (mips_elf_create_local_got_entry): Rewrite to use got_entries.
+ Change return type.
+ (mips_elf_highest): Warning clean-up.
+ (mips_elf_create_got_section): Initialize got_entries.
+ (_bfd_mips_elf_check_relocs): Use got_entries to estimate
+ local got size.
+ (_bfd_mips_elf_size_dynamic_sections): Do not account for
+ GOT_PAGE entries, since we now reuse GOT16 entries.
+
+2002-12-10 Jason Thorpe <thorpej@wasabisystems.com>
+
+ * aoutx.h (set_section_contents): Allow an otherwise unrepresentable
+ read-only section that lies after .text and before .data to be
+ written into the output file and included in a_text.
+ (translate_to_native_sym_flags): If an otherwise unrepresentable
+ section was merged with .text, convert its symbols to N_TEXT
+ symbols.
+ * libaout.h (aout_section_merge_with_text_p): New macro.
+
+2002-12-08 Alan Modra <amodra@bigpond.net.au>
+
+ * bfd-in.h: Comment typo fix. Formatting.
+ * bfd-in2.h: Regenerate.
+ * coff64-rs6000.c (xcoff64_openr_next_archived_file): Warning fix.
+ * elf32-m68hc12.c (m68hc12_elf_set_mach_from_flags): Prototype.
+ * elf64-mmix.c (mmix_dump_bpo_gregs): Warning fix.
+
+2002-12-05 Richard Henderson <rth@redhat.com>
+
+ * elfxx-ia64.c (elfNN_ia64_relax_section): Handle PCREL21BI.
+ Only send PCREL21B though the plt. Fix installed reloc type.
+ (elfNN_ia64_relocate_section): Give error for dynamic reloc
+ against PCREL22 or PCREL64I; clean up error messages for
+ branch relocs.
+
+2002-12-04 Kevin Buettner <kevinb@redhat.com>
+
+ * elf64-mips.c (elf64_mips_grok_prstatus, elf64_mips_grok_psinfo):
+ New functions.
+ (elf_backend_grok_prstatus, elf_backend_grok_psinfo): Define.
+
+2002-12-04 David Mosberger <davidm@hpl.hp.com>
+
+ * cpu-ia64-opc.c: Add operand constant "ar.csd".
+
+2002-12-04 H.J. Lu <hjl@gnu.org>
+
+ * elfxx-ia64.c (get_local_sym_hash): Use section ID instead of
+ BFD address when constructing local name.
+
+2002-12-04 Andreas Schwab <schwab@suse.de>
+
+ * elf32-m68k.c (struct elf_m68k_link_hash_table): Add sym_sec
+ member.
+ (elf_m68k_link_hash_table_create): Initialize it.
+ (elf_m68k_check_relocs): Handle symbols that are forced to be
+ local due to visibility changes.
+ (elf_m68k_adjust_dynamic_symbol): Likewise.
+ (elf_m68k_size_dynamic_sections): Likewise.
+ (elf_m68k_discard_copies): Likewise.
+ (elf_m68k_relocate_section): Likewise.
+
+2002-12-04 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (ppc64_elf_edit_opd): Correct typo.
+
+2002-12-04 Alan Modra <amodra@bigpond.net.au>
+
+ * srec.c (srec_write_symbols): Restore '$' prefix to address
+ accidentally removed in 2002-04-04 change.
+ (srec_get_symtab): Use 0 instead of `(long) FALSE'.
+
+2002-12-03 Nick Clifton <nickc@redhat.com>
+
+ * elf32-ppc.c (apuinfo_list_init): New function.
+ (apuinfo_list_add): New function: Add a value to the list.
+ (apuinfo_list_length): New function: Return the number of
+ values on the list.
+ (apuinfo_list_element): New function: Return a value on the
+ list.
+ (apuinfo_list_finish): New function: Free the resources used
+ by the list.
+ (ppc_elf_begin_write_processing): New function. Scan the
+ input bfds for apuinfo sections.
+ (ppc_elf_write_section): New function: Delay the creation of
+ the contents of an apuinfo section in an output bfd.
+ (ppc_elf_final_write_processing): New function. Create the
+ contents of an apuinfo section in an output bfd.
+ (elf_backend_begin_write_processing): Define.
+ (elf_backend_final_write_processing): Define.
+ (elf_backend_write_section): Define.
+
+2002-12-03 Richard Henderson <rth@redhat.com>
+
+ * cpu-ia64-opc.c (elf64_ia64_operands): Add ldxmov entry.
+
+2002-12-01 Stephane Carrez <stcarrez@nerim.fr>
+
+ Fix PR savannah/1417:
+ * elf32-m68hc11.c (m68hc11_elf_relax_delete_bytes): Don't adjust
+ branch if it goes to the start of the deleted region.
+
+2002-12-01 Stephane Carrez <stcarrez@nerim.fr>
+
+ * bfd-in2.h (bfd_mach_m6812): Rebuild.
+ * archures.c (bfd_mach_m6812_default, bfd_mach_m6812,
+ bfd_mach_m6812s): Declare.
+
+ * elf32-m68hc12.c (m68hc12_elf_set_mach_from_flags): New function.
+ (_bfd_m68hc12_elf_set_private_flags): Call it.
+ (_bfd_m68hc12_elf_print_private_bfd_data): Report processor version.
+ (_bfd_m68hc12_elf_merge_private_bfd_data): Merge the flags and
+ report microcontroller incompatibilities (HC12 vs HCS12).
+ (elf_backend_object_p): Update.
+
+2002-11-30 Alan Modra <amodra@bigpond.net.au>
+
+ * bfd-in.h (TRUE_FALSE_ALREADY_DEFINED, BFD_TRUE_FALSE): Delete.
+ (enum bfd_boolean, boolean): Delete.
+ (bfd_boolean): Typedef to an int.
+ (FALSE, TRUE): Define.
+ * aix386-core.c, aix5ppc-core.c, aout-adobe.c, aout-arm.c, aout-cris.c,
+ aout-encap.c, aout-ns32k.c, aout-target.h, aout-tic30.c, aoutf1.h,
+ aoutx.h, archive.c, archive64.c, archures.c, bfd-in.h, bfd.c, bfdwin.c,
+ binary.c, bout.c, cache.c, cisco-core.c, coff-a29k.c, coff-alpha.c,
+ coff-apollo.c, coff-arm.c, coff-aux.c, coff-h8300.c, coff-h8500.c,
+ coff-i386.c, coff-i860.c, coff-i960.c, coff-ia64.c, coff-m68k.c,
+ coff-m88k.c, coff-mcore.c, coff-mips.c, coff-or32.c, coff-ppc.c,
+ coff-rs6000.c, coff-sh.c, coff-sparc.c, coff-stgo32.c, coff-tic30.c,
+ coff-tic4x.c, coff-tic54x.c, coff-tic80.c, coff-w65.c, coff-we32k.c,
+ coff-z8k.c, coff64-rs6000.c, coffcode.h, coffgen.c, cofflink.c,
+ corefile.c, cpu-a29k.c, cpu-alpha.c, cpu-arc.c, cpu-arm.c, cpu-avr.c,
+ cpu-cris.c, cpu-d10v.c, cpu-d30v.c, cpu-dlx.c, cpu-fr30.c, cpu-frv.c,
+ cpu-h8300.c, cpu-h8500.c, cpu-hppa.c, cpu-i370.c, cpu-i386.c,
+ cpu-i860.c, cpu-i960.c, cpu-ia64.c, cpu-ip2k.c, cpu-m10200.c,
+ cpu-m10300.c, cpu-m32r.c, cpu-m68hc11.c, cpu-m68hc12.c, cpu-m68k.c,
+ cpu-m88k.c, cpu-mcore.c, cpu-mips.c, cpu-mmix.c, cpu-ns32k.c,
+ cpu-openrisc.c, cpu-or32.c, cpu-pdp11.c, cpu-pj.c, cpu-powerpc.c,
+ cpu-rs6000.c, cpu-s390.c, cpu-sh.c, cpu-sparc.c, cpu-tic30.c,
+ cpu-tic4x.c, cpu-tic54x.c, cpu-tic80.c, cpu-v850.c, cpu-vax.c,
+ cpu-w65.c, cpu-we32k.c, cpu-xstormy16.c, cpu-z8k.c, dwarf1.c,
+ dwarf2.c, ecoff.c, ecofflink.c, efi-app-ia32.c, efi-app-ia64.c,
+ elf-bfd.h, elf-eh-frame.c, elf-hppa.h, elf-m10200.c, elf-m10300.c,
+ elf-strtab.c, elf.c, elf32-arc.c, elf32-arm.h, elf32-avr.c,
+ elf32-cris.c, elf32-d10v.c, elf32-d30v.c, elf32-dlx.c, elf32-fr30.c,
+ elf32-frv.c, elf32-gen.c, elf32-h8300.c, elf32-hppa.c, elf32-hppa.h,
+ elf32-i370.c, elf32-i386.c, elf32-i860.c, elf32-i960.c, elf32-ip2k.c,
+ elf32-m32r.c, elf32-m68hc11.c, elf32-m68hc12.c, elf32-m68k.c,
+ elf32-mcore.c, elf32-mips.c, elf32-openrisc.c, elf32-or32.c,
+ elf32-pj.c, elf32-ppc.c, elf32-s390.c, elf32-sh.c, elf32-sh64-com.c,
+ elf32-sh64.c, elf32-sparc.c, elf32-v850.c, elf32-vax.c,
+ elf32-xstormy16.c, elf64-alpha.c, elf64-gen.c, elf64-hppa.c,
+ elf64-mips.c, elf64-mmix.c, elf64-ppc.c, elf64-ppc.h, elf64-s390.c,
+ elf64-sh64.c, elf64-sparc.c, elf64-x86-64.c, elfarm-nabi.c,
+ elfarm-oabi.c, elfcode.h, elfcore.h, elflink.c, elflink.h,
+ elfn32-mips.c, elfxx-ia64.c, elfxx-mips.c, elfxx-mips.h,
+ elfxx-target.h, format.c, freebsd.h, genlink.h, hash.c, hp300hpux.c,
+ hppabsd-core.c, hpux-core.c, i386aout.c, i386linux.c, i386lynx.c,
+ i386mach3.c, i386msdos.c, i386os9k.c, ieee.c, ihex.c, irix-core.c,
+ libaout.h, libbfd-in.h, libbfd.c, libcoff-in.h, libecoff.h, libieee.h,
+ libnlm.h, liboasys.h, libpei.h, libxcoff.h, linker.c, lynx-core.c,
+ m68klinux.c, m68klynx.c, mach-o.c, mach-o.h, merge.c, mipsbsd.c,
+ mmo.c, netbsd-core.c, netbsd.h, nlm.c, nlm32-alpha.c, nlm32-i386.c,
+ nlm32-ppc.c, nlm32-sparc.c, nlmcode.h, oasys.c, opncls.c, osf-core.c,
+ pc532-mach.c, pdp11.c, pe-arm.c, pe-i386.c, pe-mcore.c, pe-mips.c,
+ pe-sh.c, peXXigen.c, pef.c, pei-arm.c, pei-i386.c, pei-mcore.c,
+ pei-mips.c, pei-sh.c, peicode.h, ppcboot.c, ptrace-core.c, reloc.c,
+ reloc16.c, riscix.c, rs6000-core.c, sco5-core.c, section.c, simple.c,
+ som.c, som.h, sparclinux.c, sparclynx.c, srec.c, stabs.c, sunos.c,
+ syms.c, targets.c, tekhex.c, ticoff.h, trad-core.c, versados.c,
+ vms-gsd.c, vms-hdr.c, vms-misc.c, vms-tir.c, vms.c, vms.h,
+ xcoff-target.h, xcofflink.c, xsym.c, xsym.h: Replace boolean with
+ bfd_boolean, true with TRUE, false with FALSE. Simplify comparisons
+ of bfd_boolean vars with TRUE/FALSE. Formatting.
+ * bfd-in2.h, libbfd.h, libcoff.h: Regenerate
+
+2002-11-28 Alan Modra <amodra@bigpond.net.au>
+
+ * elf-bfd.h: Replace occurrences of Elf32_Internal_* and
+ Elf64_Internal_* with Elf_Internal_*. Replace Elf_Internal_Rel
+ with Elf_Internal_Rela.
+ * elf-hppa.h, elf-m10200.c, elf-m10300.c, elf32-arc.c, elf32-arm.h,
+ elf32-avr.c, elf32-cris.c, elf32-d10v.c, elf32-d30v.c, elf32-dlx.c,
+ elf32-fr30.c, elf32-frv.c, elf32-gen.c, elf32-h8300.c, elf32-hppa.c,
+ elf32-i370.c, elf32-i386.c, elf32-i860.c, elf32-i960.c, elf32-ip2k.c,
+ elf32-m32r.c, elf32-m68hc11.c, elf32-m68hc12.c, elf32-m68k.c,
+ elf32-mcore.c, elf32-mips.c, elf32-openrisc.c, elf32-or32.c,
+ elf32-ppc.c, elf32-s390.c, elf32-sh.c, elf32-v850.c, elf32-vax.c,
+ elf32-xstormy16.c, elf64-alpha.c, elf64-gen.c, elf64-hppa.c,
+ elf64-mips.c, elf64-mmix.c, elf64-ppc.c, elf64-s390.c, elf64-sh64.c,
+ elf64-sparc.c, elf64-x86-64.c, elfarm-nabi.c, elfarm-oabi.c,
+ elfcode.h, elflink.h, elfn32-mips.c, elfxx-ia64.c, elfxx-mips.c: Ditto.
+ * elf-hppa.h (elf_hppa_internal_shdr): Delete. Use Elf_Internal_Shdr
+ throughout instead.
+ * elf.c (_bfd_elf_no_info_to_howto_rel): Delete.
+ * elfcode.h (elf_swap_reloca_in): Pass source operand as a bfd_byte *.
+ Remove INLINE keyword.
+ (elf_swap_reloc_in): Likewise. Also clear r_addend.
+ (elf_swap_reloc_out, elf_swap_reloca_out): Pass destination operand
+ as a bfd_byte *.
+ (elf_write_relocs): Consolidate REL and RELA code.
+ (elf_slurp_reloc_table_from_section): Simplify REL code.
+ (NAME(_bfd_elf,size_info)): Populate reloc swap entries.
+ * elf-bfd.h (MAX_INT_RELS_PER_EXT_REL): Define.
+ * elflink.h (elf_link_read_relocs_from_section): Consolidate REL and
+ RELA code.
+ (elf_link_adjust_relocs): Likewise. Don't malloc space for temp
+ reloc array, use a fixed size of MAX_INT_RELS_PER_EXT_REL.
+ (elf_link_output_relocs): Likewise.
+ (elf_reloc_link_order): Likewise.
+ (elf_finish_pointer_linker_section): Likewise.
+ (struct elf_link_sort_rela): Remove union.
+ (elf_link_sort_cmp1): Update to suit.
+ (elf_link_sort_cmp2): Here too.
+ (elf_link_sort_relocs): Consolidate REL and RELA code. Fix memory
+ over-allocation for int_rels_per_ext_rel != 1 case.
+ * elf32-arm.h: Update all bfd_elf32_swap_reloc_out calls.
+ * elf32-i386.c: Likewise.
+ * elf32-cris.c: Likewise for bfd_elf32_swap_reloca_out.
+ * elf32-hppa.c, elf32-i370.c, elf32-m68k.c, elf32-ppc.c, elf32-s390.c,
+ elf32-sh.c, elf32-vax.c, elfxx-mips.c: Likewise.
+ * elf64-alpha.c: Likewise for bfd_elf64_swap_reloca_out.
+ * elf64-hppa.c, elf64-mips.c, elf64-ppc.c, elf64-s390.c, elf64-sh64.c,
+ elf64-sparc.c, elf64-x86-64.c: Likewise.
+ * elfxx-ia64.c: Likewise for bfd_elfNN_swap_reloca_out.
+ * elfxx-mips.c (sort_dynamic_relocs): Likewise for
+ bfd_elf32_swap_reloc_in.
+
+ * elf32-arm.h: Update elf32_arm_info_to_howto calls.
+ * elf32-mips.c: Likewise for mips_info_to_howto_rel.
+ (mips_elf64_swap_reloc_in): Zero r_addend.
+ (mips_elf64_be_swap_reloc_in): Likewise.
+ (mips_elf64_slurp_one_reloc_table): Simplify.
+
+ * elf64-alpha.c (alpha_elf_size_info): Populate reloc swap entries.
+ * elf64-hppa.c (hppa64_elf_size_info): Likewise.
+ * elf64-sparc.c (sparc64_elf_size_info): Likewise.
+
+2002-11-28 Kaz Kojima <kkojima@rr.iij4u.or.jp>
+
+ * elf32-sh.c (sh_elf_relocate_section): Don't complain about
+ unresolved debugging relocs in dynamic applications.
+ * elf64-sh64.c (sh_elf64_relocate_section): Likewise.
+
+2002-11-26 Alan Modra <amodra@bigpond.net.au>
+
+ * elf-eh-frame.c (ENSURE_NO_RELOCS): Disregard R_*_NONE relocs.
+ (_bfd_elf_discard_section_eh_frame): Don't discard duplicate CIEs
+ on a relocatable link. Comment typos.
+ * elf.c (_bfd_elf_link_hash_newfunc): Assign elements of structure
+ in the order they are declared. Clear elf_hash_value too.
+ (_bfd_elf_link_hash_table_init): Likewise assign in order. Clear
+ eh_info and tls_segment.
+ * elflink.h (elf_link_input_bfd <emit_relocs>): Keep reloc offsets
+ sorted when discarding relocs by turning them into R_*_NONE.
+
+ * libbfd.c (warn_deprecated): Comment spelling.
+ * po/SRC-POTFILES.in: Regenerate.
+
+2002-11-21 Richard Henderson <rth@redhat.com>
+
+ * elflink.h (elf_link_add_object_symbols): Don't overwrite the
+ arch's st_other bits when merging visibilities.
+ (elf_link_output_extsym): Tidy clearing of visibility field.
+
+2002-11-21 Alan Modra <amodra@bigpond.net.au>
+
+ * coff-mcore.c (SWAP_IN_RELOC_OFFSET): Define.
+ (SWAP_OUT_RELOC_OFFSET): Define.
+
+2002-11-20 Alexandre Oliva <aoliva@redhat.com>
+
+ * elf.c (_bfd_elf_link_hash_table_init): Make sure
+ can_refcount is properly extended to the type of
+ init_refcount.
+
+2002-11-19 Alexandre Oliva <aoliva@redhat.com>
+
+ * elfxx-mips.c (MIPS_RELOC_RELA_P): New macro.
+ (_bfd_mips_elf_relocate_section): Use it.
+
+ * elfxx-mips.c (MNAME): New macro.
+ (_bfd_mips_elf_check_relocs): Use it.
+ (_bfd_mips_elf_discard_info): Likewise.
+ (_bfd_mips_elf_final_link): Likewise.
+
+2002-11-19 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (ppc64_elf_edit_opd): When deleting relocs, adjust
+ rel_hdr.sh_size too.
+
+2002-11-18 Klee Dienes <kdienes@apple.com>
+
+ * Makefile.am (BFD32_LIBS): Add bfdwin.lo, bfdio.lo.
+ (BFD32_LIBS_CFILES): Add bfdwin.c, bfdio.c.
+ (BFD_H_FILES): Add bfdwin.c, bfdio.c.
+ (LIBBFD_H_FILES): Add bfdwin.c, bfdio.c.
+ Add dependencies for bfdwin.c, bfdio.c.
+ * bfd.c: Remove bfd_get_mtime, bfd_get_size.
+ * libbfd.c: Remove real_read, bfd_bread, _bfd_window_internal,
+ bfd_init_window, bfd_free_window, bfd_get_file_window, bfd_bwrite,
+ bfd_tell, bfd_flush, bfd_stat, bfd_seek.
+ * bfdio.c: New file. Contains real_read, bfd_bread, bfd_write,
+ bfd_tell, bfd_flush, bfd_stat, bfd_seek, bfd_ge_mtime,
+ bfd_get_size (moved from libbfd.c and bfd.c).
+ * bfdwin.c New file. Contains _bfd_window_internal,
+ bfd_init_window, bfd_free_window, bfd_get_file_window (moved from
+ libbfd.c and bfd.c).
+ * po/SRC-POTFILES.in: Regenerate.
+ * po/bfd.pot: Regenerate.
+ * libbfd.h: Regenerate.
+ * bfd-in2.h: Regenerate.
+ * aclocal.m4: Regenerate.
+ * Makefile.in: Regenerate.
+ * configure: Regenerate.
+
+2002-11-18 Klee Dienes <kdienes@apple.com>
+
+ * bfd.c (bfd_preserve_save): Don't zero BFD_IN_MEMORY.
+
+2002-11-15 Kazu Hirata <kazu@cs.umass.edu>
+
+ * coff-h8300.c (h8300_reloc16_estimate): Do not optimize away
+ jsr after a short jump.
+ * elf32-h8300.c (elf32_h8_relax_section): Likewise.
+
+2002-11-15 Klee Dienes <kdienes@apple.com>
+
+ * pef.c (bfd_pef_convert_architecture): Move declaration of
+ ARCH_POWERPC and ARCH_M68K to the start of the function.
+
+2002-11-14 Svein E. Seldal <Svein.Seldal@solidas.com>
+
+ * coff-tic4x.c (tic4x_howto_table): Formatting fixup
+
+2002-11-14 Hans-Peter Nilsson <hp@bitrange.com>
+
+ * elf64-mmix.c (_bfd_mmix_finalize_linker_allocated_gregs):
+ For bpo_gregs_section->contents, allocate _raw_size, not
+ _cooked_size.
+
+2002-11-13 Klee Dienes <kdienes@apple.com>
+
+ * config.bfd: Add entries for powerpc-*-darwin and cousins.
+
+2002-11-13 H.J. Lu <hjl@gnu.org>
+
+ * elfcode.h (elf_object_p): Don't restore abfd->arch_info.
+
+2002-11-13 Klee Dienes <kdienes@apple.com>
+ Alan Modra <amodra@bigpond.net.au>
+
+ * bfd.c (struct bfd_preserve): New.
+ (bfd_preserve_save): New function.
+ (bfd_preserve_restore): Ditto.
+ (bfd_preserve_finish): Ditto.
+ * bfd-in2.h: Regenerate.
+ * mach-o.c: Formatting.
+ (bfd_mach_o_scan_read_symtab_symbol): Make "value" unsigned.
+ (bfd_mach_o_object_p): Use bfd_preserve_save/restore/finish.
+ (bfd_mach_o_core_p): Ditto.
+ (bfd_mach_o_scan): Pass in mdata.
+ * mach-o.h (bfd_mach_o_scan): Update prototype.
+ * pef.c: Formatting.
+ (bfd_pef_object_p): Use bfd_preserve_save/restore/finish.
+ (bfd_pef_xlib_object_p): Ditto.
+ (bfd_pef_scan): Pass in mdata. Move version check to bfd_pef_object_p.
+ * pef.h (bfd_pef_scan): Update prototype.
+ * xsym.c: Formatting, K&R fixes.
+ (bfd_sym_object_p): Use bfd_preserve_save/restore/finish.
+ (bfd_sym_scan): New function split out from bfd_sym_object_p.
+ * xsym.h (bfd_sym_scan): Declare.
+ * elfcode.h (elf_object_p): Use bfd_preserve_save/restore/finish.
+ * elfcore.h (elf_core_file_p): Likewise.
+ * targets.c (_bfd_target_vector): Revert 2002-11-08 change.
+
+2002-11-12 Nick Clifton <nickc@redhat.com>
+
+ * po/da.po: Updated Danish translation.
+
+2002-11-12 Alan Modra <amodra@bigpond.net.au>
+
+ * elflink.h (elf_link_add_object_symbols): Optimize stabs for
+ relocatable link too.
+ (elf_link_input_bfd): When emitting relocs, adjust offsets for
+ eh_frame and stab sections. Zap deleted relocs.
+ (elf_reloc_symbol_deleted_p): Return true for zero r_symndx.
+ (elf_bfd_discard_info): Run for relocatable link too.
+ * elf64-ppc.c (ppc64_elf_edit_opd): Rename from edit_opd. Make global.
+ Handle ld -r case.
+ (ppc64_elf_size_dynamic_sections): Don't call edit_opd from here.
+ * elf64-ppc.h (ppc64_elf_edit_opd): Declare.
+
+ * elf-bfd.h (struct cie_header): Move from elf_eh-frame.c.
+ (struct cie, struct eh_cie_fde, struct eh_frame_sec_info): Likewise.
+ (struct eh_frame_array_ent, struct eh_frame_hdr_info): Likewise.
+ (enum elf_link_info_type): Remove ELF_INFO_TYPE_EH_FRAME_HDR.
+ (struct eh_frame_hdr_info): Add "hdr_sec", remove "split".
+ (struct elf_link_hash_table): Add eh_info.
+ (struct elf_obj_tdata): Change eh_frame_hdr to an asection *.
+ (_bfd_elf_discard_section_eh_frame): Update prototype.
+ (_bfd_elf_discard_section_eh_frame_hdr): Likewise.
+ (_bfd_elf_write_section_eh_frame): Likewise.
+ (_bfd_elf_write_section_eh_frame_hdr): Likewise.
+ * elf-eh-frame.c (_bfd_elf_discard_section_eh_frame): Remove "ehdrsec"
+ param. Get "hdr_info" from link hash table.
+ (_bfd_elf_discard_section_eh_frame_hdr): Remove "sec" param. Get
+ header section from link hash table. Save header section to elf_tdata.
+ (_bfd_elf_maybe_strip_eh_frame_hdr): Remove local "sec". Use
+ header section from link hash table. Don't alloc hdr_info. Clear
+ hdr_sec instead of setting "strip".
+ (_bfd_elf_eh_frame_section_offset): Formatting.
+ (_bfd_elf_write_section_eh_frame): Remove "ehdrsec", add "info" param.
+ Get header section from link hash table.
+ (_bfd_elf_write_section_eh_frame_hdr): Remove "sec", add "info" param.
+ Get header section from link hash table.
+ * elf.c (map_sections_to_segments): Use cached eh_frame_hdr.
+ (get_program_header_size): Likewise.
+ (_bfd_elf_section_offset): Formatting.
+ * elflink.h (elf_link_create_dynamic_sections): Stash eh frame header
+ section pointer in link hash table.
+ (elf_bfd_final_link): Adjust _bfd_elf_write_section_eh_frame_hdr
+ and _bfd_elf_write_section_eh_frame calls. Update comment about
+ eh_frame entries.
+ (elf_bfd_discard_info): Adjust _bfd_elf_discard_section_eh_frame and
+ _bfd_elf_discard_section_eh_frame_hdr calls. Remove "ehdr".
+
+ * po/SRC-POTFILES.in: Regenerate.
+
+ * elf-eh-frame.c (_bfd_elf_discard_section_eh_frame): Don't zero
+ relocs for discarded FDEs. Remove dead code.
+ (_bfd_elf_write_section_eh_frame_hdr): Remove dead code.
+ * elflink.h (elf_bfd_discard_info): Don't save edited relocs.
+ Tidy conditions under which stabs are edited. Formatting.
+ * elf64-sparc.c (sparc64_elf_relocate_section): Ignore overflows
+ from discarded relocs.
+ * elfxx-ia64.c (elfNN_ia64_install_dyn_reloc): Add reloc output
+ section adjustments after testing magic values.
+
+2002-11-12 Thomas Moestl <tmm@FreeBSD.org>
+
+ * elf64-sparc.c (sparc64_elf_adjust_dynamic_symbol): Correct
+ references to large plt symbols.
+
+2002-11-12 Klee Dienes <kdienes@apple.com>
+
+ * mach-o.c (bfd_mach_o_scan_read_thread): Don't re-use 'i' when
+ looking for an unused section name.
+
+2002-11-11 Kazu Hirata <kazu@cs.umass.edu>
+
+ * coff-h8300.c: Fix formatting.
+ * elf32-h8300.c: Likewise.
+ * reloc16.c: Likewise.
+
+2002-11-09 Jeroen Dobbelaere <jeroen.dobbelaere@acunia.com>
+
+ * elf32-arm.h (elf32_arm_size_dynamic_sections): Don't strip output
+ section when dynamic section unused; _bfd_strip_section_from_output
+ instead.
+
+2002-11-08 Alan Modra <amodra@bigpond.net.au>
+
+ * targets.c (_bfd_target_vector): Disable pef_vec, pef_xlib_vec
+ and sym_vec.
+
+ * dwarf2.c: Revert last change.
+
+2002-11-07 Michal Ludvig <mludvig@suse.cz>
+
+ * dwarf2.c (read_indirect_string, read_abbrevs, decode_line_info,
+ _bfd_dwarf2_find_nearest_line): Use
+ bfd_simple_get_relocated_section_contents() instead of
+ bfd_get_section_contents().
+ * reloc.c (bfd_perform_relocation): Add sanity check.
+ * simple.c (simple_get_relocated_section_contents): If the section
+ does not have any relocs associated with it, just return the
+ unadjusted contents.
+
+2002-11-07 Hans-Peter Nilsson <hp@axis.com>
+
+ * elf32-cris.c (cris_elf_relocate_section) <case R_CRIS_16_GOT,
+ case R_CRIS_32_GOT>: Correct test for filling in constant .got
+ contents, enabling for a non-DSO, for symbols defined in the
+ program with --export-dynamic.
+
+2002-11-07 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c: Comment typo fixes.
+ (ppc64_elf_merge_private_bfd_data): Allow BFD_ENDIAN_UNKNOWN input.
+
+2002-11-07 Nick Clifton <nickc@redhat.com>
+
+ * po/da.po: Updated Danish translation.
+
+2002-11-06 Alexandre Oliva <aoliva@redhat.com>
+
+ * elf64-mips.c (mips_elf64_slurp_one_reloc_table): Generate
+ exactly three internal relocs per external reloc. Set reloc_count
+ to the external reloc count.
+
+2002-11-06 Klee Dienes <kdienes@apple.com>
+
+ * coff-stgo32.c (stub_bytes): Mark as const.
+ Fix comment formatting.
+
+2002-11-06 Klee Dienes <kdienes@apple.com>
+
+ * Makefile.am (BFD32_BACKENDS): Add mach-o.lo, pef.lo, and
+ xsym.lo.
+ (BFD32_BACKENDS_CFILES): Add mach-o.c, pef.c, and xsym.c.
+ (SOURCE_HFILES): Add mach-o.h, pef.h, pef-traceback.h, xsym.h
+ * archures.c (enum bfd_architecture): Add bfd_arch_m98k.
+ * bfd.c (struct bfd): Add private data for mach-o, pef, and sym.
+ * targets.c (enum bfd_flavour): Add flavours for mach-o, pef, and
+ sym.
+ (_bfd_target_vector): Add target vectors for mach-o, pef, and sym.
+ * Makefile.in: Regenerate.
+ * doc/Makefile.in: Regenerate.
+ * bfd-in2.h: Regenerate.
+ * xsym.c: New file. Contains support for the Apple/Metrowerks
+ xSYM debugging format.
+ * xsym.h: New file.
+ * pef.c: New file. Contains support for the Apple Code Fragment
+ Manager Preferred Executable Format
+ * pef.h: New file.
+ * pef-traceback.h: New file. Contains support for parsing PowerPC
+ traceback tables as used by PEF executables (and perhaps other
+ systems as well).
+ * mach-o.c: New file. Contains support for the Mach-O object file
+ format.
+ * mach-o.h: New file.
+ * mach-o-target.c: New file. Declares the mach-o targets
+ themselves. Included three times by mach-o.c; each time with a
+ different set of macros set.
+
+2002-11-06 Graeme Peterson <gp@qnx.com>
+
+ * Makefile.am: Remove entries for elf32-qnx.[ch].
+ * Makefile.in: Regenerate.
+ * config.bfd: Change arm-nto to use bfd_elf32_{big|little}arm_vec,
+ ppc-nto to use bfd_elf32_powerpc{le}_vec, sh-nto to use
+ bfd_elf32_sh{l}_vec, and i386-nto to use bfd_elf32_i386_vec.
+ * configure.in: Remove support for bfd_elf32_sh{l}qnx_vec,
+ bfd_elf32_powerpc{le}qnx_vec, bfd_elf32_{big|little}armqnx_vec,
+ and bfd_elf32_i386qnx_vec, and removed elf32-qnx.lo from other targets.
+ bfd_elf32_sh{l}_vec, and i386-nto to use bfd_elf32_i386_vec.
+ * configure: Regenerate.
+ * elf32-qnx.c: Remove.
+ * elf32-qnx.h: Remove.
+ * elf.c: Remove calls to QNX specific set_nonloadable_filepos,
+ is_contained_by_filepos, and copy_private_bfd_data_p.
+ * elf-bfd.h (struct elf_backend_data): Remove set_nonloadable_filepos,
+ is_contained_by_filepos, and copy_private_bfd_data_p.
+ * elf32-i386.c: Remove QNX extended bfd support.
+ * elf32-ppc.c: Remove QNX extended bfd support.
+ * elf32-sh.c: Remove QNX extended bfd support.
+ * elfarm-nabi.c: Remove QNX extended bfd support.
+ * targets.c: Remove qnx vectors.
+ * elfxx-target.h (elf_backend_set_nonloadable_filepos): Remove
+ (elf_backend_is_contained_by_filepos): Remove.
+ (elf_backend_copy_private_bfd_data_p): Remove.
+ * po/SRC-POTFILES.in: Regenerate.
+
+2002-11-06 David O'Brien <obrien@FreeBSD.org>
+ Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-sparc.c (sparc64_elf_relocate_section): Adjust addend of
+ dynamic relocs against section symbols for the output section vma.
+
+2002-11-05 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-arm.h (t2a1_push_insn, t2a2_ldr_insn, t2a3_mov_insn,
+ t2a4_bx_insn, t2a5_pop_insn, t2a6_bx_insn): Remove.
+
+2002-11-05 Kaz Kojima <kkojima@rr.iij4u.or.jp>
+ Alan Modra <amodra@bigpond.net.au>
+
+ * config.bfd (sh-*-linux*): Use bfd_elf*_sh64*lin_vec as sh64
+ vectors in target_selvecs.
+ (shle-*-netbsdelf*): Use bfd_elf*_sh64*nbsd_vec as sh64 vectors
+ in target_selvecs.
+ (sh-*-netbsdelf*): Likewise.
+ * configure.in (assocvecs): New variable. Handle assocvecs like
+ selvecs.
+ * configure: Regenerate.
+ * format.c (bfd_check_format_matches): Store bfd_target pointers
+ in matching_vector instead of target names. Select first target
+ from bfd_associated_vector that matches a list of ambiguous targets.
+ * targets.c (_bfd_associated_vector): New array.
+ (bfd_associated_vector): New variable.
+ (_bfd_target_vector): Add bfd_elf*_sh64*lin_vec.
+ * libbfd-in.h (bfd_associated_vector): Declare.
+ * libbfd.h: Regenerate.
+
+2002-11-05 Elias Athanasopoulos <eathan@otenet.gr>
+
+ * vms-gsd.c (_bfd_vms_write_gsd): Check that symbol->udata.p is
+ non-NULL before dereferencing.
+
+2002-11-04 Kaz Kojima <kkojima@rr.iij4u.or.jp>
+
+ * vms.c (vms_object_p): Restore the start address when returning
+ NULL.
+
+2002-11-04 Alan Modra <amodra@bigpond.net.au>
+ Hans-Peter Nilsson <hp@axis.com>
+
+ * elflink.h (struct elf_final_link_info): Add shndxbuf_size.
+ (elf_bfd_final_link): Don't bother zeroing symtab_hdr fields.
+ Set up a larger symshndxbuf, and write it out. Free it on
+ exit rather than freeing symbuf twice. Correct section index
+ on output section symbol loop.
+ (elf_link_output_sym): Accumulate symbol extension section
+ indices, reallocating symshndxbuf rather than writing it out.
+ (elf_link_flush_output_syms): Don't flush symshndxbuf.
+ * elf.c (assign_section_numbers): Init i_shdrp to all zero.
+ Use bfd_zalloc to clear i_shdrp[0] too.
+
+2002-11-03 Stephen Clarke <stephen.clarke@earthling.net>
+
+ * elf32-sh64-com.c (sh64_address_in_cranges): Use
+ _raw_size of cranges section if _cooked_size not yet set.
+
+2002-11-03 Hans-Peter Nilsson <hp@axis.com>
+
+ * elf32-v850.c (v850_elf_relax_delete_bytes): Correct parameters
+ for bfd_elf32_swap_symbol_out.
+
+2002-10-31 David O'Brien <obrien@FreeBSD.org>
+
+ * elf-eh-frame.c (_bfd_elf_discard_section_eh_frame): Don't mix
+ signed and unsigned in comparison.
+
+2002-10-30 Daniel Jacobowitz <drow@mvista.com>
+
+ * coffcode.h: Remove extraneous '\'.
+
+2002-10-28 H.J. Lu <hjl@gnu.org>
+
+ * Makefile.am (targets.lo): Depend on Makefile instead of
+ config.status.
+ (archures.lo): Likewise.
+ * Makefile.in: Regenerated.
+
+2002-10-25 Jason Thorpe <thorpej@wasabisystems.com>
+
+ * config.bfd (mips*el-*-netbsd*, mips*-*-netbsd*): Add
+ bfd_elf64_bigmips_vec and bfd_elf64_littlemips_vec to
+ targ_selvecs.
+
+2002-10-25 Jim Wilson <wilson@redhat.com>
+
+ * elf64-sh64.c (sh_elf64_relocate_section): Call
+ _bfd_elf_rela_local_sym. Handle relocs against STT_SECTION symbol
+ of SHF_MERGE section.
+
+2002-10-25 Hans-Peter Nilsson <hp@axis.com>
+
+ * simple.c: Correct placement of ATTRIBUTE_UNUSED.
+
+2002-10-24 John David Anglin <dave@hiauly1.hia.nrc.ca>
+
+ * aoutx.h (NAME(aout,swap_ext_reloc_in)): Cast bytes->r_index to
+ unsigned int. Cast RELOC_BASE10, RELOC_BASE13 and RELOC_BASE22 to
+ unsigned int.
+ (NAME(aout,final_link)): Cast enum used in assignment.
+ (aout_link_write_symbols): Cast enums in comparisons, int values to
+ boolean, enums in assignments to int.
+ (aout_link_input_section_std): Cast rel->r_index to unsigned int.
+ (aout_link_input_section_ext): Likewise. Cast enums used in
+ comparisons with unsigned ints.
+ (aout_link_reloc_link_order): Cast enum to int in assignment.
+ * archive.c (_bfd_generic_read_ar_hdr_mag): Cast result of memchr
+ calls to char *.
+ * bfd-in.h (bfd_set_section_vma): Cast enum true to unsigned int in
+ assignment.
+ * bfd-in2.h (bfd_set_section_vma): Likewise.
+ * bfd.c (bfd_record_phdr): Cast enums in assignments.
+ * binary.c (bfd_alloc): Cast enum to long.
+ * coffgen.c (_bfd_coff_is_local_label_name): Cast return to boolean.
+ * dwarf2.c (read_abbrevs): Add casts to enum types.
+ (read_attribute_value): Likewise.
+ (arange_add): Cast result of bfd_zalloc call.
+ (comp_unit_contains_address): Return true and false.
+ (comp_unit_find_nearest_line): Cast return to boolean.
+ * format.c (bfd_check_format_matches, bfd_set_format): Likewise.
+ * gen-aout.c: define macro '_' if not defined.
+ * libbfd.c (bfd_realloc): Cast malloc and realloc to PTR.
+ (bfd_bwrite): Cast bfd_realloc to bfd_byte *.
+ (bfd_write_bigendian_4byte_int): Cast return to boolean.
+ (bfd_seek): Cast bfd_realloc to bfd_byte *.
+ (bfd_generic_is_local_label_name): Cast return to boolean.
+ * libcoff.h (_bfd_coff_adjust_symndx): Remove extraneous '\'.
+ * linker.c (_bfd_link_hash_newfunc): Cast bfd_hash_allocate result to
+ struct bfd_hash_entry *.
+ (_bfd_generic_link_hash_newfunc): likewise.
+ (_bfd_generic_final_link): Cast enum to unsigned int.
+ * merge.c (sec_merge_emit): Cast return to boolean.
+ (merge_strings): Add casts to const unsigned char *.
+ * reloc.c (bfd_get_reloc_code_name): Cast enums in comparison to int.
+ (bfd_generic_get_relocated_section_content): Cast enum to unsigned int.
+ * section.c (bfd_section_hash_newfunc): Cast bfd_hash_allocate result
+ to struct bfd_hash_entry *.
+ (bfd_set_section_content): Add cast to PTR in comparison.
+ * simple.c (simple_dummy_warning, simple_dummy_undefined_symbol,
+ simple_dummy_reloc_overflow, simple_dummy_reloc_dangerous,
+ simple_dummy_unattached_reloc,
+ bfd_simple_get_relocated_section_contents): Add K&R declarations and
+ function definitions.
+ * srec.c (S3Forced): Initialize to false.
+ (srec_get_symtab): Cast return value from bfd_alloc to asymbol *.
+ * stabs.c (_bfd_link_section_stabs): Cast enum to int in comparisons.
+ (_bfd_discard_section_stabs): Likewise. Also cast return to boolean.
+ * syms.c (bfd_is_undefined_symclass): Cast return to boolean.
+ (_bfd_stab_section_find_nearest_line): Cast enum to bfd_byte in
+ comparisons.
+
+2002-10-23 Jakub Jelinek <jakub@redhat.com>
+
+ * elf64-alpha.c (elf64_alpha_check_relocs): Only put maybe_dynamic
+ relocs into shared lib non-allocated reloc sections.
+
+2002-10-23 Nathan Tallent <eraxxon@alumni.rice.edu>
+
+ * dwarf2.c (add_line_info): Ensure that the line_info_table is
+ sorted even when given an out-of-order line sequence.
+ (lookup_address_in_line_info_table): When an exact VMA match is
+ not found, return line information with the closest VMA.
+
+2002-10-23 Ross Alexander <ross.alexander@uk.neceur.com>
+
+ * elf64-hppa.c: Force DT_FLAGS to always be set. Required by
+ HPUX 11.00 patch PHSS_26559.
+
+2002-10-22 Alexandre Oliva <aoliva@redhat.com>
+
+ * elfxx-mips.c (_bfd_mips_elf_modify_segment_map): Don't move
+ the options section into a separate section unless IRIX 6
+ compatibility is enabled.
+
+2002-10-22 Alexandre Oliva <aoliva@redhat.com>
+
+ * elflink.h (struct elf_link_sort_rela): Turn rel and rela
+ into arrays.
+ (elf_link_sort_cmp1, elf_link_sort_cmp2): Adjust.
+ (elf_link_sort_relocs): Likewise. Take int_rels_per_ext_rel
+ into account.
+ * elfxx-mips.c (mips_elf_create_dynamic_relocation): Compose
+ R_MIPS_REL32 with R_MIPS64 if ABI_64_P.
+
+2002-10-21 Graeme Peterson <gp@qnx.com>
+
+ * targets.c (_bfd_target_vector): Add missing qnx vectors.
+
+2002-10-21 Alan Modra <amodra@bigpond.net.au>
+
+ * targets.c (bfd_target_list): Don't return the default target twice.
+
+2002-10-21 Elias Athanasopoulos <eathan@otenet.gr>
+
+ * archive.c (_bfd_archive_bsd_update_armap_timestamp): Replace
+ perror with bfd_perror.
+
+2002-10-19 H.J. Lu <hjl@gnu.org>
+
+ * elflink.h (elf_link_add_object_symbols): Correctly handle
+ DT_RPATH and DT_RUNPATH.
+
+2002-10-19 Mark Kettenis <kettenis@gnu.org>
+
+ * elf.c (elfcore_grok_note): Fix recognition on NT_PRXFPREG notes.
+
+2002-10-17 Denis Chertykov <denisc@overta.ru>
+
+ * elf32-ip2k.c (ELF_MACHINE_ALT1): Define alternate machine code
+ for ip2k port.
+
+2002-10-17 Alan Modra <amodra@bigpond.net.au>
+
+ * elfxx-target.h (USE_REL): Don't define as 1.
+ * elf32-arm.h (USE_REL): Provide a default define of 0.
+ Use #if rather than #ifdef when testing USE_REL.
+ * elf32-m32r.c: Likewise.
+
+ * elf32-arc.c (USE_REL): Define as 1.
+ * elf32-d10v.c (USE_REL): Likewise.
+ * elf32-m32r.c (USE_REL): Likewise.
+ * elf32-m68hc11.c (USE_REL): Likewise.
+ * elf32-m68hc12.c (USE_REL): Likewise.
+ * elf32-or32.c (USE_REL): Likewise.
+ * elfarm-nabi.c (USE_REL): Likewise.
+
+2002-10-16 Jakub Jelinek <jakub@redhat.com>
+
+ * config.bfd (s390-*-linux*): Add targ64_selvecs.
+ (s390x-*-linux*): Add targ_selvecs.
+
+2002-10-16 Alan Modra <amodra@bigpond.net.au>
+
+ * Makefile.am (BFD32_BACKENDS): Remove elfarmqnx-nabi.lo,
+ elf32-i386-fbsd.lo, elf32-i386qnx.lo, elf32-ppcqnx.lo,
+ elf32-sh-lin.lo, elf32-sh64-lin.lo, elf32-sh-nbsd.lo,
+ elf32-sh64-nbsd.lo, elf32-shqnx.lo. Add elf32-qnx.lo.
+ (BFD32_BACKENDS_CFILES): Likewise for corresponding C files.
+ (BFD64_BACKENDS): Remove elf64-sh64-lin.lo, elf64-sh64-nbsd.lo.
+ (BFD64_BACKENDS_CFILES): Likewise for corresponding C files.
+ (SOURCE_HFILES): Add elf32-qnx.h.
+ (BUILD_HFILES): Add bfdver.h.
+ Run "make dep-am".
+ * Makefile.in: Regenerate.
+ * configure.in Update bfd vector dependencies.
+ * configure: Regenerate.
+ * elf32-i386-fbsd.c: Delete. Move code to elf32-i386.c.
+ * elf32-i386qnx.c: Likewise.
+ * elf32-ppcqnx.c: Delete. Move code to elf32-ppc.c.
+ * elf32-sh-nbsd.c: Delete. Move code to elf32-sh.c.
+ * elf32-sh-lin.c: Likewise.
+ * elf32-shqnx.c: Likewise.
+ * elf32-sh64-lin.c: Delete. Move code to elf32-sh64.c.
+ * elf32-sh64-nbsd.c: Likewise.
+ * elf64-sh64-lin.c: Delete. Move code to elf64-sh64.c.
+ * elf64-sh64-nbsd.c: Likewise.
+ * elfarmqnx-nabi.c: Delete. Move code to elfarm-nabi.c.
+ * elf32-arm.h (ELF_MAXPAGESIZE): Always define.
+ * elf32-i386.c: Remove ELF_ARCH and ELF32_I386_C_INCLUDED tests.
+ * elf32-ppc.c: Remove ELF32_PPC_C_INCLUDED tests.
+ * elf32-qnx.h (elf_backend_set_nonloadable_filepos): Always define.
+ (elf_backend_is_contained_by_filepos): Likewise.
+ (elf_backend_copy_private_bfd_data_p): Likewise.
+ Globalize and move functions to..
+ * elf32-qnx.c: ..here. New file.
+ * elf32-sh.c: Remove ELF_ARCH and ELF32_SH_C_INCLUDED tests. Don't
+ emit target vectors when INCLUDE_SHMEDIA.
+ * elf32-sh64.c: Remove ELF_ARCH test. Move TARGET_* etc. defines to
+ end of file.
+ * elf64-sh64.c: Remove ELF_ARCH test.
+ * elfarm-nabi.c: Remove ELFARM_NABI_C_INCLUDED test.
+ * po/BLD-POTFILES.in: Regenerate.
+ * po/SRC-POTFILES.in: Regenerate.
+
+2002-10-16 Alan Modra <amodra@bigpond.net.au>
+
+ * elflink.h (elf_link_add_object_symbols): Error out on dynamic objects
+ loaded with --just-symbols.
+
+ * elf32-i386qnx.c (TARGET_LITTLE_NAME): Define.
+ * elf32-ppcqnx.c (TARGET_LITTLE_NAME, TARGET_BIG_NAME): Define.
+ * elf32-shqnx.c (TARGET_LITTLE_NAME, TARGET_BIG_NAME): Define.
+ * elfarmqnx-nabi.c (TARGET_LITTLE_NAME, TARGET_BIG_NAME): Define.
+
+2002-10-15 Richard Henderson <rth@redhat.com>
+
+ * Makefile.am (BFD64_BACKENDS): Remove elf64-alpha-fbsd.
+ (BFD64_BACKENDS_CFILES): Likewise.
+ * configure.in (bfd_elf64_alpha_freebsd_vec): Use elf64-alpha.
+ * elf64-alpha-fbsd.c: Remove file, move code ...
+ * elf64-alpha.c: ... here.
+ * Makefile.in, configure: Rebuild.
+
+2002-10-14 Richard Henderson <rth@redhat.com>
+
+ * elf64-alpha.c (elf64_alpha_relocate_section) [BRSGP]: Increment
+ VALUE, not ADDEND.
+
+2002-10-14 Stephen Clarke <stephen.clarke@superh.com>
+
+ * elf32-sh.c (elf_sh_link_hash_entry): Replace
+ datalabel_got_offset with union of datalabel_got
+ offset and refcount.
+ (sh_elf_link_hash_newfunc): Initialize datalabel_got.refcount.
+ (allocate_dynrelocs): Delete unnecessary code for
+ STT_DATALABEL type. Create entry in got for
+ datalabel version of symbol if datalabel_got.refcount > 0.
+ (sh_elf_relocate_section): Use datalabel_got union.
+ (sh_elf_gc_sweep_hook): Pull common code to initialize
+ h and eh out of switch statement. Declare seen_stt_datalabel.
+ Initialize it. Decrement datalabel_got.refcount for
+ got relocs when seen_stt_datalabel is true.
+ Decrement local_got_refcounts entry for datalabel got relocs
+ of local symbols.
+ (sh_elf_copy_indirect_symbol): Copy datalabel_got field over.
+ (sh_elf_check_relocs): Declare seen_stt_datalabel.
+ Initialize it. When seen_stt_datalabel is true, increment
+ datalabel_got refcount rather than got.refcount.
+ (sh_elf_finish_dynamic_symbol): Create relocs to
+ initialize got entry for datalabel version of symbol.
+
+2002-10-14 Alan Modra <amodra@bigpond.net.au>
+
+ * Makefile.am: Run "make dep-am".
+ (BFD_H_FILES): Remove version.h.
+ * bfd-in.h (BFD_VERSION, BFD_VERSION_DATE, BFD_VERSION_STRING): Move..
+ * version.h: ..to here.
+ * configure.in (bfd_version_date): Remove.
+ (AC_OUTPUT): Make bfdver.h from version.h.
+ * bfd.c: #include "bfdver.h".
+ * vms-hdr.c: Likewise.
+ * Makefile.in: Regenerate.
+ * bfd-in2.h: Regenerate.
+ * configure: Regenerate.
+ * po/SRC-POTFILES.in: Regenerate.
+
+2002-10-14 Alan Modra <amodra@bigpond.net.au>
+
+ * archures.c (bfd_mach_i386_i386, bfd_mach_i386_i8086,
+ bfd_mach_i386_i386_intel_syntax, bfd_mach_x86_64,
+ bfd_mach_x86_64_intel_syntax bfd_mach_ppc, bfd_mach_ppc64,
+ bfd_mach_rs6k, bfd_mach_d10v, bfd_mach_sh, bfd_mach_v850,
+ bfd_mach_arc_5, bfd_mach_arc_6, bfd_mach_arc_7, bfd_mach_arc_8,
+ bfd_mach_m32r, bfd_mach_frv, bfd_mach_frvsimple,
+ bfd_mach_ia64_elf64, bfd_mach_ia64_elf32,
+ bfd_mach_ip2022, bfd_mach_ip2022ext,
+ bfd_mach_s390_31, bfd_mach_s390_64, bfd_mach_xstormy16): Renumber.
+ * bfd-in2.h: Regenerate.
+
+2002-10-14 Kaz Kojima <kkojima@rr.iij4u.or.jp>
+
+ * config.bfd (sh*eb-*-linux*, sh*-*-linux*): Add the alternative
+ endian vector to targ_selvecs.
+
+2002-10-13 Alexandre Oliva <aoliva@redhat.com>
+
+ * elfxx-mips.c (mips_elf_calculate_relocation): Take
+ save_addend argument. Don't apply the 32-bit mask to a
+ GPREL32 value if it's to be used in another relocation. Don't
+ use forced-check computation of local_p to decide whether to
+ add gp0 to GPREL16 value. Don't use only the lowest 16 bits
+ of the addend of a non-in-place GPREL16 relocation.
+ (_bfd_mips_elf_relocate_section): Pass use_saved_addend_p to
+ mips_elf_calculate_relocation().
+
+2002-10-12 Stephane Carrez <stcarrez@nerim.fr>
+
+ * elf32-m68hc11.c (m68hc11_elf_relax_section): Don't treat relocs
+ with symbols in other sections if we relaxed something; the sections
+ output offsets must be re-computed before.
+
+2002-10-12 Stephane Carrez <stcarrez@nerim.fr>
+
+ * elf32-m68hc11.c (m68hc11_elf_relax_section): Update symbols
+ handling to use Elf_Internal_Sym.
+ (m68hc11_elf_relax_delete_bytes): Likewise.
+
+2002-10-11 Kaz Kojima <kkojima@rr.iij4u.or.jp>
+
+ * elf32-sh.c (sh_elf_optimized_tls_reloc, sh_elf_mkobject,
+ sh_elf_object_p, dtpoff_base): New functions.
+ (sh_elf_howto_table): Add TLS relocs.
+ (sh_reloc_map): Likewise.
+ (sh_elf_info_to_howto): Support TLS relocs.
+ (elf_sh_link_hash_entry): Add tls_type and tls_tpoff32.
+ (sh_elf_hash_entry, sh_elf_tdata, sh_elf_local_got_tls_type):
+ New macros.
+ (sh_elf_obj_tdata): New.
+ (elf_sh_link_hash_table): Add tls_ldm_got.
+ (sh_elf_link_hash_table_create): Clear refcount of tls_ldm_got.
+ (allocate_dynrelocs): Support TLS relocs.
+ (sh_elf_size_dynamic_sections): Likewise.
+ (sh_elf_relocate_section): Support TLS relocs. Don't try to find
+ .rela.got section when found already. Return false after printing
+ error about unresolvable relocation.
+ (sh_elf_gc_sweep_hook): Support TLS relocs.
+ (sh_elf_check_relocs): Likewise.
+ (sh_elf_finish_dynamic_symbol): Likewise.
+ (bfd_elf32_mkobject, elf_backend_object_p): Define for TLS case.
+ * reloc.c: Add SH TLS relocs.
+ * bfd-in2.h, libbfd.h: Regenerate.
+
+2002-10-11 Daniel Jacobowitz <drow@mvista.com>
+
+ * Makefile.in: Regenerated.
+
+2002-10-11 Daniel Jacobowitz <drow@mvista.com>
+
+ * Makefile.am: Run dep-am.
+ (BFD_H_DEP): Add simple.c and linker.c.
+ (BFD32_LIBS): Add simple.lo.
+ (BFD32_LIBS_CFILES): Add simple.c.
+ * Makefile.in: Regenerated.
+ * bfd-in2.h: Regenerated.
+ * simple.c: New file.
+
+2002-10-11 Alan Modra <amodra@bigpond.net.au>
+
+ * coff-arm.c (record_arm_to_thumb_glue): Avoid type-punned pointers.
+ (record_thumb_to_arm_glue): Likewise.
+ * ecoff.c (ecoff_link_add_externals): Likewise.
+ * elf32-arm.h (record_arm_to_thumb_glue): Likewise.
+ (record_thumb_to_arm_glue): Likewise.
+ * elf32-m32r.c (m32r_elf_add_symbol_hook): Likewise.
+ * elf32-sh.c (sh_elf_create_dynamic_sections): Likewise.
+ * elf32-sh64.c (sh64_elf_add_symbol_hook): Likewise.
+ * elf64-alpha.c (elf64_alpha_create_dynamic_sections): Likewise.
+ * elf64-ppc.c (func_desc_adjust): Likewise.
+ * elf64-sh64.c (sh64_elf64_add_symbol_hook): Likewise.
+ (sh64_elf64_create_dynamic_sections): Likewise.
+ * elflink.c (_bfd_elf_create_got_section): Likewise.
+ (_bfd_elf_create_dynamic_sections): Likewise.
+ (_bfd_elf_create_linker_section): Likewise.
+ * elflink.h (elf_add_default_symbol): Likewise.
+ (elf_link_create_dynamic_sections): Likewise.
+ (NAME(bfd_elf,size_dynamic_sections)): Likewise.
+ * elfxx-ia64.c (elfNN_ia64_aix_add_symbol_hook): Likewise.
+ * elfxx-mips.c (mips_elf_create_got_section): Likewise.
+ (_bfd_mips_elf_add_symbol_hook): Likewise.
+ (_bfd_mips_elf_create_dynamic_sections): Likewise.
+ * linker.c (generic_link_add_symbol_list): Likewise.
+ * xcofflink.c (xcoff_link_add_symbols): Likewise.
+
+ * elfxx-ia64.c (oor_brl, oor_ip): Conditionally define.
+
+ * elf64-ppc.c (edit_opd): Only zero opd syms when function is
+ completely removed. Correct local sym adjustment.
+
+2002-10-10 Stephen Clarke <stephen.clarke@superh.com>
+
+ * elf32-sh.c (elf_sh_pic_plt_entry_be, elf_sh_pic_plt_entry_le):
+ Correct mistake in calculation of address of .got.
+ * elf64-sh64.c (elf_sh64_pic_plt_entry_be,
+ elf_sh64_pic_plt_entry_le): Likewise.
+
+2002-10-09 Richard Shann <richard.shann@superh.com>
+ Stephen Clarke <stephen.clarke@superh.com>
+
+ * Makefile.am: Add entries for elf32-sh64-lin.c and
+ elf64-sh64-lin.c. Regenerate.
+ * Makefile.in: Regenerate.
+ * config.bfd: Change sh64eb-*-linux* and sh64-*-linux*
+ to use sh64 vectors rather than sh vectors.
+ * configure.in: Add bfd_elf32_sh64lin_vec, bfd_elf32_sh64blin_vec,
+ bfd_elf64_sh64lin_vec, bfd_elf64_sh64blin_vec.
+ * configure: Regenerate.
+ * elf32-sh64-lin.c: New file.
+ * elf64-sh64-lin.c: New file.
+ * targets.c: Add bfd_elf32_sh64lin_vec, bfd_elf32_sh64blin_vec,
+ bfd_elf64_sh64lin_vec, bfd_elf64_sh64blin_vec.
+
+2002-10-08 H.J. Lu <hjl@gnu.org>
+
+ * elf32-i386.c (elf_i386_relocate_section): Re-arrange the
+ IE->LE transition for R_386_TLS_IE.
+
+2002-10-08 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (edit_opd): Correct test for discarded sections.
+
+2002-10-07 Mark Elbrecht <snowball3@softhome.net>
+
+ * cofflink.c (mark_relocs): Don't mark relocations in excluded
+ sections.
+
+2002-10-07 Alan Modra <amodra@bigpond.net.au>
+
+ * elflink.h (elf_link_input_bfd): Remove BFD_VERSION_DATE dependent
+ code.
+
+ * elf64-ppc.c (ppc64_elf_build_stubs): Increment .glink indx.
+
+2002-10-06 Alan Modra <amodra@bigpond.net.au>
+
+ * opncls.c: Formatting.
+ (_bfd_new_bfd): Use a smaller section hash table.
+
+2002-10-05 Alexandre Oliva <aoliva@redhat.com>
+
+ * elfxx-mips.c (mips_elf_create_dynamic_relocation): Set the type
+ of the other two relocations packed with a REL32 to NONE.
+
+2002-10-02 Stephen Clarke <stephen.clarke@superh.com>
+
+ * elf32-sh.c (elf_sh_link_hash_entry): Add gotplt_refcount.
+ (sh_elf_link_hash_newfunc): Initialize it.
+ (allocate_dynrelocs): Transfer gotplt refs from plt.refcount
+ to got.refcount for symbols that are forced local or when
+ we have direct got refs.
+ (sh_elf_gc_sweep_hook): Adjust gotplt_refcount. Use it
+ to correctly adjust got.refcount and plt.refcount.
+ (sh_elf_copy_indirect_symbol): Copy gotplt_refcount across.
+ (sh_elf_check_relocs): Increment gotplt_refcount.
+
+2002-10-01 Jakub Jelinek <jakub@redhat.com>
+
+ * elf32-i386.c (elf_i386_relocate_section): Fix
+ movl foo@indntpoff, %eax IE->LE transition.
+
+2002-10-01 Jakub Jelinek <jakub@redhat.com>
+
+ * elf64-x86-64.c (elf64_x86_64_relocate_section): Change TLSGD
+ sequence and its transitions.
+
+2002-10-01 Jakub Jelinek <jakub@redhat.com>
+
+ * elf32-i386.c (elf_i386_relocate_section): Resolve R_386_TLS_LDO_32
+ to st_value + addend in non-code sections.
+ * elf64-x86-64.c (elf64_x86_64_relocate_section): Resolve
+ R_X86_64_DTPOFF32 to st_value + addend in non-code sections.
+
+2002-09-30 Gavin Romig-Koch <gavin@redhat.com>
+ Ken Raeburn <raeburn@cygnus.com>
+ Aldy Hernandez <aldyh@redhat.com>
+ Eric Christopher <echristo@redhat.com>
+ Richard Sandiford <rsandifo@redhat.com>
+
+ * archures.c (bfd_mach_mips4120, bfd_mach_mips5400): New.
+ (bfd_mach_mips5500): New.
+ * cpu-mips.c (I_mips4120, I_mips5400, I_mips5500): New.
+ (arch_info_struct): Add corresponding entries here.
+ * elfxx-mips.c (_bfd_elf_mips_mach): Handle E_MIPS_MACH_4120,
+ E_MIPS_MACH_5400 and E_MIPS_MACH_5500.
+ (_bfd_mips_elf_final_write_processing): Handle bfd_mach_mips4120,
+ bfd_mach_mips5400 and bfd_mach_mips5500.
+ (_bfd_mips_elf_mach_extends_p): New function.
+ (_bfd_mips_elf_merge_private_bfd_data): Use it to help merge
+ the EF_MIPS_MACH flags.
+ * bfd-in2.h: Regenerate.
+
+2002-09-28 Jason Thorpe <thorpej@wasabisystems.com>
+
+ * elf32-vax.c (elf_vax_size_dynamic_section): Don't strip
+ .got sections.
+
+2002-09-28 Alan Modra <amodra@bigpond.net.au>
+
+ * elf.c (map_sections_to_segments): Correct test for start of
+ writable section in the same page as end of read-only section.
+
+2002-09-27 Matt Thomas <matt@3am-software.com>
+
+ * elf32-vax.c (elf_vax_check_relocs): Remove unused
+ local_got_refcounts usage. Remove allocation of got slot.
+ (elf_vax_gc_sweep_hook): Remove unused local_got_refcounts usage.
+ Remove de-allocation of got slot.
+ (elf_vax_size_dynamic_section): Fix some indentation. Add hash
+ traversal for elf_vax_instantiate_got_entries. Allow empty .got
+ sections to be GC'ed.
+ (elf_vax_instantiate_got_entries): New function.
+ (elf_vax_relocate_section): Simplify R_VAX_GOT32 handling. Remove
+ tests that are now handled by elf_vax_instantiate_got_entries.
+ Assert GOT entry falls within .got section size. Remove redundant
+ comparisions. Fix comments.
+
+2002-09-27 Jakub Jelinek <jakub@redhat.com>
+
+ * reloc.c: Add x86-64 TLS relocs.
+ * bfd-in2.h, libbfd.h: Rebuilt.
+ * elf64-x86-64.c (x86_64_elf_howto): Fix size fields for 32-bit
+ relocs. Add TLS relocs.
+ (x86_64_reloc_map): Add TLS relocs.
+ (elf64_x86_64_info_to_howto): Adjust for added TLS relocs.
+ (struct elf64_x86_64_link_hash_entry): Add tls_type field.
+ (GOT_UNKNOWN, GOT_NORMAL, GOT_TLS_GD, GOT_TLS_IE): Define.
+ (elf64_x86_64_hash_entry): Define.
+ (struct elf64_x86_64_obj_tdata): New.
+ (elf64_x86_64_tdata, elf64_x86_64_local_got_tls_type): Define.
+ (struct elf64_x86_64_link_hash_table): Add tls_ld_got.
+ (link_hash_newfunc): Initialize tls_type.
+ (elf64_x86_64_link_hash_table_create): Initialize tls_ld_got.
+ (elf64_x86_64_copy_indirect_symbol): Swap tls_type if necessary.
+ (elf64_x86_64_mkobject): New.
+ (elf64_x86_64_elf_object_p): Allocate struct elf64_x86_64_obj_tdata.
+ (elf64_x86_64_tls_transition): New.
+ (elf64_x86_64_check_relocs): Add r_type variable and use it.
+ Handle TLS relocs.
+ (elf64_x86_64_gc_sweep_hook): Handle TLS relocs.
+ (allocate_dynrelocs): Allocate GOT space for TLS relocs.
+ (elf64_x86_64_size_dynamic_sections): Likewise.
+ (dtpoff_base, tpoff): New.
+ (elf64_x86_64_relocate_section): Handle TLS relocs.
+ (elf64_x86_64_finish_dynamic_symbol): Only handle non-TLS GOT
+ entries.
+ (bfd_elf64_mkobject): Define.
+
+ * elf32-i386.c (elf_i386_check_relocs) [R_386_TLS_LE]: Set
+ DF_STATIC_TLS if shared.
+
+2002-09-26 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * elfxx-mips.c (_bfd_mips_elf_fake_sections): Don't emit unneeded
+ empty relocation sections.
+
+2002-09-26 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (ppc_build_one_stub): Don't build glink stubs here.
+ (ppc64_elf_build_stubs): Build them here instead.
+
+2002-09-24 Jakub Jelinek <jakub@redhat.com>
+
+ * elf32-sparc.c (elf32_sparc_relocate_section): Put R_SPARC_RELATIVE
+ addend into r_addend, not *r_offset.
+ (elf32_sparc_finish_dynamic_symbol): Likewise.
+ * elf64-sparc.c (sparc64_elf_finish_dynamic_symbol): Clear xword at
+ R_SPARC_RELATIVE's r_offset.
+
+2002-09-23 Nathan Tallent <eraxxon@alumni.rice.edu>
+
+ * dwarf2.c (decode_line_info): Update to correctly decode
+ the (non-standard DWARF2) out-of-order address sequences
+ generated by the Intel C++ 6.0 compiler for ia64-Linux.
+
+2002-09-23 Mark Elbrecht <snowball3@softhome.net>
+
+ * config.bfd: For DJGPP targets, match with any cpu and any machine.
+
+2002-09-23 Alan Modra <amodra@bigpond.net.au>
+
+ * elf-eh-frame.c (_bfd_elf_discard_section_eh_frame): Zero relocs
+ for discarded FDEs. Remove redundant assignment.
+ * elflink.h (elf_bfd_discard_info): Save edited relocs.
+
+2002-09-22 H.J. Lu <hjl@gnu.org>
+
+ * elf64-alpha.c (elf64_alpha_merge_ind_symbols): Don't merge
+ the relocation count between different .reloc sections.
+
+2002-09-21 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-ppc.c (ppc_elf_relocate_section): Allow ".sbss.*" and
+ ".sdata.*" for R_PPC_SDAREL16, ".sbss2*" and ".sdata2*" for
+ R_PPC_EMB_SDA2REL. Similarly for R_PPC_EMB_SDA21 and
+ R_PPC_EMB_RELSDA.
+
+ * elfcode.h (elf_slurp_reloc_table_from_section): Make "symcount"
+ unsigned. Move "symcount" assignment out of loop.
+ * Makefile.am: Run "make dep-am".
+ * Makefile.in: Regenerate.
+ * configure: Regenerate.
+ * po/SRC-POTFILES.in: Regnerate.
+
+2002-09-19 Nathan Tallent <eraxxon@alumni.rice.edu>
+
+ * dwarf2.c (_bfd_dwarf2_find_nearest_line): If address length is
+ zero, set it to 8 for (non-standard) 64-bit DWARF2 formats
+ (e.g. IRIX64).
+
+2002-09-19 Jakub Jelinek <jakub@redhat.com>
+
+ * elf32-ppc.c (ppc_elf_finish_dynamic_symbol): Clear .got word
+ even if generating R_PPC_RELATIVE reloc.
+ (ppc_elf_relocate_section): Make sure relocation is performed
+ if skip == -2. Clear memory at r_offset when creating dynamic
+ relocation.
+
+2002-09-19 Jakub Jelinek <jakub@redhat.com>
+
+ * reloc.c (BFD_RELOC_386_TLS_TPOFF, BFD_RELOC_386_TLS_IE,
+ BFD_RELOC_386_TLS_GOTIE): Add.
+ * bfd-in2.h, libbfd.h: Rebuilt.
+ * elf32-i386.c (elf_howto_table): Add R_386_TLS_TPOFF, R_386_TLS_IE
+ and R_386_TLS_GOTIE.
+ (elf_i386_reloc_type_lookup): Handle it.
+ (struct elf_i386_link_hash_entry): Change tls_type type to unsigned
+ char instead of enum, change GOT_* into defines.
+ (GOT_TLS_IE_POS, GOT_TLS_IE_NEG, GOT_TLS_IE_BOTH): Define.
+ (elf_i386_tls_transition): Handle R_386_TLS_IE and R_386_TLS_GOTIE.
+ (elf_i386_check_relocs): Likewise. Avoid crash if local symbol is
+ accessed both as normal and TLS symbol. Move R_386_TLS_LDM and
+ R_386_PLT32 cases so that R_386_TLS_IE can fall through.
+ Handle R_386_TLS_LE_32 and R_386_TLS_LE in shared libs.
+ (elf_i386_gc_sweep_hook): Handle R_386_TLS_IE and R_386_TLS_GOTIE.
+ Handle R_386_TLS_LE_32 and R_386_TLS_LE in shared libs.
+ (allocate_dynrelocs): Allocate 2 .got and 2 .rel.got entries if
+ tls_type is GOT_TLS_IE_BOTH.
+ (elf_i386_size_dynamic_sections): Likewise.
+ (elf_i386_relocate_section): Handle R_386_TLS_IE and R_386_TLS_GOTIE.
+ Handle R_386_TLS_LE_32 and R_386_TLS_LE in shared libs.
+ (elf_i386_finish_dynamic_symbol): Use tls_type & GOT_TLS_IE to catch
+ all 4 GOT_TLS_* TLS types.
+
+2002-09-19 Nick Clifton <nickc@redhat.com>
+
+ * elflink.h (elf_fix_symbol_flags): When examining weak symbols,
+ follow indirect links.
+
+2002-09-19 Nathan Tallent <eraxxon@alumni.rice.edu>
+
+ * ecoffswap.h (ecoff_swap_pdr_in) <isym, iline>: Update to
+ correctly sign-extend 32-bit ECOFF null values (0xffffffff, -1)
+ on 64 bit machines.
+ (ecoff_swap_sym_in) <iss>: Likewise.
+ * ecoff.c (_bfd_ecoff_slurp_symbolic_info): Fix error reading
+ ECOFF information: 'ioptMax' refers to the actual *size*
+ of the optimization symtab, not the number of entries.
+
+2002-09-19 Daniel Jacobowitz <drow@mvista.com>
+
+ * elf32-arm.h (elf32_arm_adjust_dynamic_symbol): Update
+ ELF_LINK_HASH_NEEDS_PLT logic.
+
+2002-09-18 Daniel Jacobowitz <drow@mvista.com>
+
+ * elfcode.h (elf_slurp_reloc_table_from_section): Check
+ correct relocation count.
+
+2002-09-17 Daniel Jacobowitz <drow@mvista.com>
+
+ * bfd-in.h (bfd_get_dynamic_symcount): Define.
+ * bfd.c (struct _bfd): Add dynsymcount.
+ * bfd-in2.h: Regenerated.
+ * elf.c (_bfd_elf_canonicalize_dynamic_symtab): Set
+ abfd->dynsymcount.
+ * elfcode.h (elf_slurp_reloc_table_from_section): Check
+ for overflow.
+
+2002-09-17 Stan Cox <scox@redhat.com>
+
+ * elf64-mips.c (mips_elf64_be_swap_reloca_out): Handle type2 and type3.
+ (mips_elf64_final_gp): Don't make up gp value.
+ * elfn32-mips.c (mips_elf_final_gp): Likewise.
+ * elfxx-mips.c (_bfd_mips_elf_final_link): Always create
+ .MIPS.options/.options section.
+
+2002-09-17 David O'Brien <obrien@FreeBSD.org>
+
+ * elf32-i386-fbsd.c: Always label using the EI_OSABI method.
+ It is benign for FreeBSD < 4.1. Minor reformatting.
+ * elf64-alpha-fbsd.c: Likewise.
+
+2002-09-17 Jakub Jelinek <jakub@redhat.com>
+
+ * elf32-i386.c (elf_i386_relocate_section) [R_386_TLS_TPOFF32]: Negate
+ addend.
+
+2002-09-17 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-alpha.c (alpha_elf_size_info): Make static.
+
+2002-09-17 Svein E. Seldal <Svein.Seldal@solidas.com>
+
+ * coff-tic4x.c: Add function declarations and ATTRIBUTE_UNUSED.
+ * cpu-tic4x.c: Ditto.
+
+2002-09-17 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * elf64-mips.c (define elf_backend_ignore_discarded_relocs): Remove
+ duplicate define.
+
+2002-09-16 Bruno Haible <bruno@clisp.org>
+
+ * elf32-i386.c: Don't defined ELF_ARCH etc. if this file is included
+ by a target variant implementation.
+ * elf64-alpha.c: Likewise.
+ * elf32-i386-fbsd.c: New file.
+ * elf64-alpha-fbsd.c: New file.
+ * targets.c: Support bfd_elf32_i386_freebsd_vec and
+ bfd_elf64_alpha_freebsd_vec.
+ * configure.in: Accept the vectors bfd_elf32_i386_freebsd_vec,
+ bfd_elf64_alpha_freebsd_vec.
+ * Makefile.am (BFD32_BACKENDS): Add elf32-i386-fbsd.lo.
+ (BFD32_BACKENDS_CFILES): Add elf32-i386-fbsd.c.
+ (BFD64_BACKENDS): Add elf64-alpha-fbsd.lo.
+ (BFD64_BACKENDS_CFILES): Add elf64-alpha-fbsd.c.
+ (elf32-i386-fbsd.lo, elf64-alpha-fbsd.lo): Add dependencies.
+ * config.bfd: For FreeBSD targets, set targ_defvec to a FreeBSD
+ specific targets. Define OLD_FREEBSD_ABI_LABEL if appropriate.
+
+2002-09-12 Jakub Jelinek <jakub@redhat.com>
+
+ * elf32-i386.c (dtpoff_base, tpoff): Don't crash if tls_segment is
+ NULL.
+ (elf_i386_relocate_section): Return false after printing error about
+ unresolvable relocation.
+
+2002-09-12 Nick Clifton <nickc@redhat.com>
+
+ * elf32-arm.h (elf32_arm_final_link_relocate): Fix handling of
+ R_ARM_THM_PC11.
+
+2002-09-11 Jeffrey Law <law@redhat.com>
+
+ * elf32-h8300.c (elf32_h8_relax_section): Fix typo.
+
+2002-09-11 Andrew Haley <aph@cambridge.redhat.com>
+
+ * elf.c (_bfd_elf_find_nearest_line): Check functionname_ptr and
+ line_ptr before deciding we've found a symbol.
+
+2002-09-11 Nick Clifton <nickc@redhat.com>
+
+ * po/da.po: New Danish translation file.
+ * configure.in (LINGUAS): Add 'da'.
+ * configure: Regenerate.
+
+2002-09-10 Michael Snyder <msnyder@redhat.com>
+
+ * irix-core.c (do_sections, do_sections64): New functions.
+ (irix_core_core_file_p): Call new functions do_sections,
+ do_sections64, depending on corefile (32-bit or 64-bit).
+
+2002-09-09 Richard Henderson <rth@redhat.com>
+
+ * elfxx-ia64.c (elfNN_ia64_relax_section): Handle PCREL21M
+ and PCREL21F like PCREL21B.
+
+2002-09-04 Kevin Buettner <kevinb@redhat.com>
+
+ * config.bfd (mips*-*-irix6*): Add new ABI vectors. Make n32 default
+ vector.
+
+2002-09-02 Nick Clifton <nickc@redhat.com>
+
+ * elf32-v850.c (v850_elf_final_link_relocate): Use helpful
+ names instead of cryptically overloaded bfd_reloc error
+ codes.
+ (v850_elf_relocate_section): Likewise.
+ (v850_elf_relax_section): Replace caching of external symbols
+ with caching of internal symbols obtained from calling
+ bfd_elf_get_elf_syms().
+ Fixup problems with freeing cached allocated memory blocks.
+
+2002-09-02 Alan Modra <amodra@bigpond.net.au>
+
+ * cpu-pj.c (scan_mach, compatible, arch_info_struct): Remove.
+ (bfd_pj_arch): Use bfd_default_scan.
+ * cpu-v850.c (scan): Remove.
+ (N): Use bfd_default_scan.
+ * cpu-z8k.c (scan_mach): Remove.
+ (arch_info_struct, bfd_z8k_arch): Reorganize so that the default is
+ first. Use bfd_default_scan.
+
+ * ecoff.c (_bfd_ecoff_set_arch_mach_hook): Don't use hard-coded
+ bfd_mach constants.
+ (ecoff_get_magic): Likewise.
+ * elf32-v850.c (v850_elf_object_p): Likewise.
+ (v850_elf_final_write_processing): Likewise.
+ * mipsbsd.c (MY(set_arch_mach)): Likewise.
+ (MY(write_object_contents)): Likewise.
+ * coff64-rs6000.c (xcoff64_write_object_contents): Likewise.
+ * coffcode.h (coff_write_object_contents): Likewise.
+ (coff_set_arch_mach_hook): Add comment describing machine == 0.
+ Remove unnecessary "machine" assignments.
+ (coff_write_relocs): Test for the absolute section sym by testing
+ section and flags.
+
+ * aoutx.h (NAME(aout,machine_type)): Recognize bfd_mach_i386_i386
+ and bfd_mach_i386_i386_intel_syntax.
+ * pdp11.c (NAME(aout,machine_type)): Likewise.
+
+2002-08-30 John David Anglin <dave@hiauly1.hia.nrc.ca>
+
+ * bfd-in.h (align_power): Cast constants to bfd_vma type.
+ * bfd-in2.h (align_power): Likewise.
+
+2002-08-30 Alan Modra <amodra@bigpond.net.au>
+
+ * Makefile.am: Run "make dep-am".
+ * Makefile.in: Regenerate.
+
+ * cpu-avr.c (compatible): Don't use hard-coded mach constants.
+ * cpu-powerpc.c (powerpc_compatible): Likewise.
+ * cpu-rs6000.c (rs6000_compatible): Likewise.
+
+2002-08-28 Catherine Moore <clm@redhat.com>
+
+ * elf32-v850.c (v850_elf_reloc_map): Add new relocs.
+ (v850-elf-reloc): Don't resolve pc relative relocs.
+ (v850_elf_ignore_reloc): New routine.
+ (v850_elf_final_link_relocate): Handle new relocs.
+ (v850_elf_relax_delete_bytes ): New routine.
+ (v850_elf_relax_section): New routine.
+ (bfd_elf32_bfd_relax_section): Define.
+ (HOWTO): New entries for new relocs.
+ * reloc.c (BFD_RELOC_V850_LONGCALL): New reloc.
+ (BFD_RELOC_V850_LONGJUMP): New reloc.
+ (BFD_RELOC_V850_ALIGN): New reloc.
+ * archures.c: Remove redundant v850ea architecture.
+ * cpu-v850.c: Remove redundant v850ea support.
+ * libbfd.h: Regenerate.
+ * bfd-in2.h: Regenerated.
+
+2002-08-28 Svein E. Seldal <Svein.Seldal@solidas.com>
+
+ * config.bfd: Add tic4x-*-*coff* and c4x-*-*coff* target.
+ * configure.in: Add tic4x_coff vector files.
+ * configure: Regenerate.
+ * Makefile.am: Add tic4x target.
+ * Makefile.in: Regenerate.
+
+2002-08-27 Michael Hayes <m.hayes@elec.canterbury.ac.nz>
+
+ * archures.c: Add the BFD arch type tic4x.
+ * bfd-in.h: Add BFD_IN_MEMORY flag.
+ * coff-tic4x.c: New file.
+ * coffswap.h (coff_swap_sym_out): Add preadjuster.
+ * cpu-tic4x.c: New file.
+ * targets.c: Added tic4x- in list of xvecs.
+ * ticoff.h: New file.
+ * bfd-in2.h: Regenerate.
+
+2002-08-27 Adam Nemet <anemet@lnxw.com>
+
+ * elf32-arm.h (elf32_arm_finish_dynamic_sections): Set the last
+ bit of DT_INIT and DT_FINI for Thumb functions.
+
+2002-08-26 Alan Modra <amodra@bigpond.net.au>
+
+ * coffcode.h (coff_set_arch_mach_hook): Handle W65MAGIC.
+
+2002-08-26 Alan Modra <amodra@bigpond.net.au>
+
+ * aoutx.h (NAME(aout,reloc_type_lookup)): Handle BFD_RELOC_8.
+
+2002-08-24 Kaz Kojima <kkojima@rr.iij4u.or.jp>
+
+ * elf32-sh.c (sh_elf_copy_indirect_symbol): New.
+ (create_got_section, allocate_dynrelocs, readonly_dynrelocs):
+ Likewise.
+ (struct elf_sh_pcrel_relocs_copied): Removed.
+ (struct elf_sh_dyn_relocs): New.
+ (struct elf_sh_link_hash_entry): Replace pcrel_relocs_copied
+ field with dyn_relocs.
+ (struct elf_sh_link_hash_table): Add short-cuts to get dynamic
+ sections and sym_sec.
+ (sh_elf_link_hash_newfunc): Clear dyn_relocs.
+ (sh_elf_link_hash_table_create): Clear shorts-cuts and sym_sec.
+ (sh_elf_create_dynamic_sections): Use create_got_section instead
+ of _bfd_elf_create_got_section.
+ (sh_elf_check_relocs): Likewise.
+ (sh_elf_create_dynamic_sections): Use short-cuts to the dynamic
+ sections.
+ (sh_elf_adjust_dynamic_symbol, sh_elf_size_dynamic_sections,
+ sh_elf_relocate_section, sh_elf_check_relocs,
+ sh_elf_finish_dynamic_symbol, sh_elf_finish_dynamic_sections):
+ Likewise.
+ (sh_elf_adjust_dynamic_symbol): Handle nocopyreloc. Keep the
+ dynamic relocations and avoiding the copy relocation when we
+ didn't find any dynamic relocations in the section which has
+ contents or is read-only.
+ (WILL_CALL_FINISH_DYNAMIC_SYMBOL): New.
+ (sh_elf_size_dynamic_sections): Don't reset the size of
+ .rela.got section even if dynamic_sections_created flag is off.
+ Don't use sh_elf_discard_copies. Scan all input bfd and use
+ allocate_dynrelocs. Call readonly_dynrelocs to determine
+ whether we need DT_TEXTREL.
+ (sh_elf_adjust_dynamic_symbol): Use plt.refcount to determine
+ whether the symbol was never referred to.
+ (sh_elf_relocate_section): Use WILL_CALL_FINISH_DYNAMIC_SYMBOL.
+ (sh_elf_gc_sweep_hook): Fill with the real sweep function.
+ (sh_elf_check_relocs): Call create_got_section if the short-cut
+ to .got is null. Increment reference counters only instead of
+ allocating space on dynamic sections here. Don't conditionalize
+ uninitialized got.offset value when marking the symbol as a
+ global offset table entry. Keep relocations for symbols satisfied
+ by a dynamic library to avoid copy relocations for the symbol.
+ Set dynobj field of an elf hash table if needed.
+ (sh_elf_finish_dynamic_sections): Handle null section pointer
+ correctly.
+ (elf_backend_copy_indirect_symbol): Defined.
+ (elf_backend_can_refcount): Defined.
+
+2002-08-23 Nick Clifton <nickc@redhat.com>
+
+ * elf-eh-frame.c (_bfd_elf_discard_section_eh_frame): Undo
+ previous change. Add comment explaining why.
+
+2002-08-23 Stephen Clarke <stephen.clarke@superh.com>
+
+ * elf32-sh.c (elf_sh_plt0_entry_be, elf_sh_plt0_entry_le): Copy
+ contents of .got.plt[2] to tr0, not address of .got.plt.
+ (sh_elf_finish_dynamic_symbol): Do not apply GOT_BIAS when
+ patching absolute plt entry. For shmedia plt entry, set bottom bit
+ of branch to plt0 as this is a branch to an shmedia instruction.
+ * elf64-sh64.c (elf_sh64_plt0_entry_be, elf_sh64_plt0_entry_le):
+ Copy contents of .got.plt[2] to tr0, not address of .got.plt.
+ (elf_sh64_plt_entry_be, elf_sh64_plt_entry_le): Use ptrel to
+ branch to plt0.
+ (sh64_elf64_finish_dynamic_symbol): Do not apply GOT_BIAS when
+ patching absolute plt entry. For shmedia plt entry, branch to
+ plt0 is now ptrel, so use relative offset. Set bottom bit of
+ branch target as it is a branch to an shmedia instruction.
+
+2002-08-23 Stephen Clarke <stephen.clarke@superh.com>,
+ Richard Shann <richard.shann@superh.com>
+
+ * elf32-sh.c (sh_elf_finish_dynamic_sections): Set LSB of DT_INIT
+ value if .init is an SHmedia function. Similarly for DT_FINI.
+ * elf64-sh64.c (sh64_elf64_finish_dynamic_sections): Likewise.
+
+2002-08-23 Stephen Clarke <stephen.clarke@superh.com>
+
+ * elf32-sh.c (sh_elf_size_dynamic_sections): Zero initialize
+ dynamic section.
+ * elf64-sh64.c (sh64_elf64_size_dynamic_sections): Likewise.
+
+2002-08-22 Kaz Kojima <kkojima@rr.iij4u.or.jp>
+
+ * elf-eh-frame.c (_bfd_elf_discard_section_eh_frame): Use a simple
+ byte read when reading the return address register column.
+
+2002-08-22 Nick Clifton <nickc@redhat.com>
+
+ * config.bfd: Add powepc64-*-*bsd* target.
+
+2002-08-22 Graeme Peterson <gp@qnx.com>
+
+ * Makefile.am: Add entries for elf32-shqnx.c
+ * Makefile.in: Regenerate.
+ * config.bfd: Add support sh-*-nto* target.
+ * configure.in: Add support for bfd_elf32_sh{l}qnx_vec.
+ * configure: Regenerate.
+ * elf32-qnx.h: Changed typo "elf_i386qnx_*" to "elf_qnx_*" .
+ * elf32-sh.c: Do not include elf32-target.h if
+ ELF32_SH_C_INCLUDED is defined.
+ * elf32-shqnx.c: New file: Support for QNX.
+ * targets.c: Add bfd_elf32_sh{l}qnx_vec.
+
+2002-08-22 Nick Clifton <nickc@redhat.com>
+
+ * po/tr.po: Updated Turkish translation.
+
+ * syms.c (_bfd_generic_read_minisymbols): Set bfd_error if the
+ symbols are not read.
+
+2002-08-22 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-m68hc11.c: Formatting fixes.
+ (elf32_m68hc11_gc_mark_hook): Correct params. Remove unnecessary test.
+ * elf32-m68hc12.c: Formatting fixes.
+ (elf32_m68hc11_gc_mark_hook): Correct params. Remove unnecessary test.
+
+2002-08-22 Alan Modra <amodra@bigpond.net.au>
+
+ * coff-rs6000.c (rs6000coff_vec <object_flags>): Add SEC_CODE and
+ SEC_DATA.
+ (pmac_xcoff_vec): Likewise.
+ * coff64-rs6000.c (rs6000coff64_vec): Likewise.
+ (aix5coff64_vec): Likewise.
+
+2002-08-22 Alan Modra <amodra@bigpond.net.au>
+
+ * elf-bfd.h (struct elf_backend_data): Add struct elf_backend_data
+ param to elf_backend_copy_indirect_symbol.
+ (_bfd_elf_link_hash_copy_indirect): Likewise.
+ * elflink.h (elf_add_default_symbol, elf_fix_symbol_flags): Adjust
+ calls to copy_indirect_symbol.
+ * elf32-hppa.c (elf32_hppa_copy_indirect_symbol): Likewise.
+ * elf32-i386.c (elf_i386_copy_indirect_symbol): Likewise.
+ * elf32-s390.c (elf_s390_copy_indirect_symbol): Likewise.
+ * elf64-ppc.c (ppc64_elf_copy_indirect_symbol): Likewise.
+ * elf64-s390.c (elf_s390_copy_indirect_symbol): Likewise.
+ * elf64-x86-64.c (elf64_x86_64_copy_indirect_symbol): Likewise.
+ * elfxx-ia64.c (elfNN_ia64_hash_copy_indirect): Likewise.
+ * elfxx-mips.c (_bfd_mips_elf_copy_indirect_symbol): Likewise.
+ * elfxx-mips.h (_bfd_mips_elf_copy_indirect_symbol): Likewise.
+ * elf.c (_bfd_elf_link_hash_copy_indirect): Likewise. Properly
+ test refcounts for "used" values.
+
+2002-08-21 John David Anglin <dave@hiauly1.hia.nrc.ca>
+
+ * elf-eh-frame.c (_bfd_elf_discard_section_eh_frame): Add PARAMS to
+ argument declaration.
+
+2002-08-19 Elena Zannoni <ezannoni@redhat.com>
+
+ * archures.c (bfd_mach_ppc_e500): Added.
+ * bfd-in2.h: Rebuilt.
+ * cpu-powerpc.c (bfd_powerpc_archs): Added e500.
+
+2002-08-19 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-m68hc12.c (elf_backend_can_gc_sections): False.
+
+2002-08-17 Andrew Cagney <ac131313@redhat.com>
+
+ * elf.c (bfd_elf_get_elf_syms): Change type of `esym' to
+ `bfd_byte'.
+
+2002-08-17 Stan Cox <scox@redhat.com>
+
+ * elfxx-mips.c (_bfd_mips_elf_modify_segment_map): Use the
+ IRIX 6 segment layout for NEWABI.
+
+2002-08-16 Stephen Clarke <stephen.clarke@superh.com>
+
+ * elf32-sh.c (sh_elf_gc_mark_hook): For sh64, skip indirect
+ symbols when looking for section referred to by a relocation.
+ * elf64-sh.c (sh_elf64_gc_mark_hook): Likewise.
+
+2002-08-15 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-i370.c: Move reloc enum to include/elf/i370.h.
+
+2002-08-15 Hans-Peter Nilsson <hp@axis.com>
+
+ * elf32-cris.c (elf_cris_discard_excess_program_dynamics): Add
+ missing check for whether the symbol is referenced by DSO before
+ unexporting it as an unneeded dynamic symbol.
+
+2002-08-14 H.J. Lu <hjl@gnu.org>
+
+ * libbfd.h: Regenerate.
+
+2002-08-14 H.J. Lu <hjl@gnu.org>
+
+ * config.bfd: Always add 64bit vectors to 32bit Linux/mips.
+
+2002-08-14 Stephane Carrez <stcarrez@nerim.fr>
+
+ * elf32-m68hc11.c (m68hc11_relax_group): New to relax group of
+ instructions.
+ (m68hc11_direct_relax): New to define table of relaxable instructions.
+ (find_relaxable_insn): New, find a relaxable insn.
+ (compare_reloc): New to compare two relocs.
+ (m68hc11_elf_relax_section): New, relax text sections.
+ (m68hc11_elf_relax_delete_bytes): New, delete bytes and adjust branchs.
+ (elf32_m68hc11_check_relocs): New function for GC support.
+ (elf32_m68hc11_relocate_section): New function for GC support.
+ (bfd_elf32_bfd_relax_section): Define to support linker relaxation.
+ (elf_backend_check_relocs): Likewise.
+ (elf_backend_relocate_section): Likewise.
+
+2002-08-13 H.J. Lu <hjl@gnu.org>
+
+ * elflink.h (NAME(bfd_elf,size_dynamic_sections): Don't count
+ definitions in shared objects when checking symbol with
+ undefined version.
+
+2002-08-13 Stephane Carrez <stcarrez@nerim.fr>
+
+ * elf32-m68hc11.c (elf32_m68hc11_gc_mark_hook): New for section GC.
+ (elf32_m68hc11_gc_sweep_hook): Likewise.
+ (elf_backend_gc_mark_hook): Define for GC section support.
+ (elf_backend_gc_sweep_hook): Likewise.
+ (elf_backend_can_gc_sections): Likewise.
+
+ * elf32-m68hc12.c: Likewise.
+
+2002-08-13 Stephane Carrez <stcarrez@nerim.fr>
+
+ * elf32-m68hc11.c (_bfd_m68hc11_elf_print_private_bfd_data): New.
+ (_bfd_m68hc11_elf_merge_private_bfd_data): New function.
+ (_bfd_m68hc11_elf_set_private_flags): New function.
+ Use them to set/check/print ELF flags specific to 68HC11.
+
+ * elf32-m68hc12.c (_bfd_m68hc12_elf_print_private_bfd_data): New.
+ (_bfd_m68hc12_elf_merge_private_bfd_data): New function.
+ (_bfd_m68hc12_elf_set_private_flags): New function.
+ Use them to set/check/print ELF flags specific to 68HC12.
+
+2002-08-13 Stephane Carrez <stcarrez@nerim.fr>
+
+ * elf32-m68hc11.c (elf_m68hc11_howto_table): Add the new relocs;
+ fix masks for PC-rel relocs.
+ (m68hc11_elf_ignore_reloc): New function.
+
+ * elf32-m68hc12.c (m68hc12_elf_special_reloc): New to handle specific
+ 68HC12 banked addressing relocs.
+ (m68hc12_phys_addr): New to compute physical address of banked memory.
+ (m68hc12_phys_page): Likewise for page.
+ (m68hc12_addr_is_banked): New to see if address is in banked area.
+ (elf_m68hc12_howto_table): Add new relocs and rename to xx12.
+
+2002-08-13 Stephane Carrez <stcarrez@nerim.fr>
+
+ * reloc.c (BFD_RELOC_M68HC11_RL_JUMP, BFD_RELOC_M68HC11_RL_GROUP,
+ BFD_RELOC_M68HC11_LO16, BFD_RELOC_M68HC11_PAGE,
+ BFD_RELOC_M68HC11_24): New relocs for 68HC11/68HC12.
+ * bfd-in2.h: Regenerate.
+
+2002-08-12 H.J. Lu <hjl@gnu.org>
+
+ * elflink.h (elf_add_default_symbol): Preserve section across
+ elf_merge_symbol.
+
+2002-08-09 Graeme Peterson <gp@qnx.com>
+
+ * Makefile.am: Add entries for elf32-ppcqnx.c, and add
+ elf32-qnx.h dependency to elfarmqnx-nabi.c and elf32-i386qnx.c.
+ * Makefile.in: Regenerate.
+ * config.bfd: Add support for powerpc{le}-*-nto targets.
+ * configure.in: Add support for bfd_elf32_powerpc{le}qnx_vec.
+ * configure: Regenerate.
+ * elf32-i386qnx.c: Moved backend functions into a QNX specific
+ common file "elf32-qnx.h", and now include that file.
+ * elf32-qnx.h: New file: QNX specific common elf backend.
+ * elf32-ppc.c: Do not include elf32-target.h if
+ ELF32_PPC_C_INCLUDED is defined.
+ * elf32-ppcqnx.c: New file: Support for QNX.
+ * elfarmqnx-nabi.c: Include elf32-qnx.h for qnx elf backend.
+ * targets.c: Add bfd_elf32_powerpc{le}qnx_vec.
+
+2002-08-09 Nick Clifton <nickc@redhat.com>
+
+ * po/sv.po: Updated Swedish translation.
+
+2002-08-09 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * elfxx-mips.c (mips_elf_global_got_index): Avoid segfault if
+ g->global_gotsym is NULL.
+
+2002-08-08 H.J. Lu <hjl@gnu.org>
+
+ * elflink.h (elf_add_default_symbol): Don't warn if a definition
+ overrides an indirect versioned symbol.
+
+2002-08-08 Jakub Jelinek <jakub@redhat.com>
+
+ * elf32-i386.c (elf_i386_relocate_section): Fill in proper addend
+ for R_386_TLS_TPOFF32 relocs against symndx 0.
+
+2002-08-07 H.J. Lu <hjl@gnu.org>
+
+ * elflink.h (NAME(bfd_elf,size_dynamic_sections)): Check symbol
+ with undefined version if needed.
+ (elf_link_assign_sym_version): Match a default symbol with a
+ version without definition. No need to hide the default
+ definition separately.
+
+2002-08-08 Alan Modra <amodra@bigpond.net.au>
+
+ * elflink.h (elf_link_output_extsym): Don't output symbols from
+ SEC_EXCLUDE sections.
+
+ * aoutx.h (aout_link_write_symbols): Correct handling of warning syms.
+
+2002-08-07 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (edit_opd): Arrange to drop symbols for discarded .opd
+ entries.
+
+2002-08-07 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * elfxx-mips.c (mips_elf_create_dynamic_relocation): Cast signedness
+ mismatch.
+
+2002-08-07 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * elfxx-mips.c (ABI_64_P): Remove superfluous check.
+
+2002-08-07 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * elf32-mips.c (mips_reloc_map): Fix typo.
+
+2002-08-06 Alan Modra <amodra@bigpond.net.au>
+
+ * xcofflink.c (xcoff_write_global_symbol): Set n_scnum for abs_section.
+
+2002-08-06 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (ppc64_elf_howto_raw): Zero all src_mask entries.
+
+2002-08-06 Alan Modra <amodra@bigpond.net.au>
+
+ * libxcoff.h: Use PARAMS on function declarations.
+ * coff-rs6000.c (xcoff_generate_rtinit): Simplify size calc.
+ * coff64-rs6000.c (xcoff64_generate_rtinit): Likewise.
+
+ * coff-rs6000.c: (xcoff_rtype2howto): Don't place reloc address in
+ addend.
+ * coff64-rs6000.c: (xcoff64_rtype2howto): Likewise.
+
+2002-08-06 Alan Modra <amodra@bigpond.net.au>
+
+ * coff-rs6000.c: Formatting fixes.
+ (xcoff_calculate_relocation): Use PARAMS in declaration.
+ (xcoff_complain_overflow): Likewise.
+ (xcoff_ppc_relocate_section): Use old-style function pointer call.
+ (bfd_xcoff_backend_data): Remove useless comments.
+ (rs6000coff_vec): Likewise.
+ (bfd_pmac_xcoff_backend_data): Likewise.
+ (pmac_xcoff_vec): Likewise.
+
+ * coff64-rs6000.c: Formatting fixes.
+ (xcoff64_calculate_relocation): Use PARAMS in declaration.
+ (xcoff64_ppc_relocate_section): Use old-style function pointer call.
+ (bfd_xcoff_backend_data): Remove useless comments.
+ (rs6000coff64_vec): Likewise.
+ (bfd_xcoff_aix5_backend_data): Likewise.
+ (aix5coff64_vec): Likewise.
+
+2002-08-06 Alan Modra <amodra@bigpond.net.au>
+
+ * coff-rs6000.c (xcoff_howto_table): Revert some of last change to
+ mask entries. Use complain_overflow_dont for R_REF.
+ (xcoff_reloc_type_ba): Revert last change.
+ (xcoff_reloc_type_br): Likewise.
+ (xcoff_reloc_type_crel): Likewise.
+ (xcoff_ppc_relocate_section): Likewise.
+ * coff64-rs6000.c (xcoff64_reloc_type_br): Likewise.
+ (xcoff64_ppc_relocate_section): Likewise.
+ (xcoff64_howto_table): Revert some of last change to mask entries.
+ Use complain_overflow_dont for R_REF.
+
+ * coff-rs6000.c (xcoff_howto_table): Fix src_mask entries. Make all
+ relocs with bitsize == 16 have size = 1.
+ (xcoff_reloc_type_ba): Correct src_mask and dst_mask adjustment.
+ (xcoff_reloc_type_br): Likewise.
+ (xcoff_reloc_type_crel): Likewise.
+ (xcoff_ppc_relocate_section): Set up src_mask and dst_mask correctly.
+ * coff64-rs6000.c (xcoff64_reloc_type_br): Correct src_mask and
+ dst_mask adjustment.
+ (xcoff64_ppc_relocate_section): Set up src_mask and dst_mask correctly.
+ (xcoff64_howto_table): Fix src_mask entries. Make all relocs with
+ bitsize == 16 have size = 1.
+
+2002-08-01 Denis Chertykov <denisc@overta.ru>
+
+ * elf32-ip2k.c: Processor manufacturer changed to Ubicom.
+ (struct misc): New field isymbuf. All free_* fields removed.
+ (symbol_value): Pass in internal syms. No need to swap syms in.
+ (ip2k_elf_relax_section): Use bfd_elf_get_elf_syms. Properly free
+ possibly cached info.
+ (tidyup_after_error): Removed.
+ (ip2k_elf_relax_section_pass1): Don't use removed fields of struct
+ misc. Use new field.
+ (adjust_all_relocations): Use internal syms. No need to swap syms
+ in and out.
+ (add_page_insn): Don't use removed fields of struct misc.
+
+2002-08-01 Nick Clifton <nickc@redhat.com>
+
+ * elf32-arm.h: Revert previous delta.
+
+2002-08-01 Nick Clifton <nickc@redhat.com>
+
+ * configure.in (AM_INIT_AUTOMAKE): Bump version number.
+ * configure: Regenerate.
+
+2002-07-31 H.J. Lu <hjl@gnu.org>
+
+ * config.bfd: Add x86-64 vector to Linux/i386 if 64bit BFD is
+ selected.
+
+2002-07-31 H.J. Lu <hjl@gnu.org>
+
+ * config.bfd: Add n32 vectors to 32bit Linux/mips if 64bit BFD
+ is selected.
+
+2002-07-31 Jakub Jelinek <jakub@redhat.com>
+
+ * elf32-i386.c (elf_i386_copy_indirect_symbol): Swap tls_type
+ if _bfd_elf_link_hash_copy_indirect will swap got.refcount.
+
+2002-07-31 Ian Dall <ian@sibyl.beware.dropbear.id.au>
+
+ * cpu-ns32k.c (_bfd_ns32k_put_immdeiate, _bfd_ns32k_get_immediate):
+ There is no 8 byte relocation type for this architecture.
+ (do_ns32k_reloc): Use bfd_vma instead of native types.
+ (bfd_ns32k_put_immediate, _bfd_ns32k_relocate_contents) put_data
+ returns void.
+ (_bfd_ns32k_put_displacement): Don't check for overflow. We can
+ rely on generic code to do that.
+ * aout-ns32k.c (howto_table): Add appropriate overflow detection
+ to all table entries.
+ (_bfd_ns32k_relocate_contents): put_data returns void.
+ * ns32k.h: (_bfd_ns32k_put_displacement, _bfd_ns32k_put_immediate)
+ (_bfd_do_ns32k_reloc_contents): Fix prototypes. put data functions
+ return void.
+
+2002-07-31 Ian Dall <ian@sibyl.beware.dropbear.id.au>
+
+ * aoutx.h (aout_link_check_ar_symbols): Whether to include an
+ archive object is target dependant.
+
+2002-07-31 Adam Nemet <anemet@lnxw.com>
+
+ * elf32-arm.h (ARM_PLT_ENTRY_SIZE): Rename PLT_ENTRY_SIZE.
+ (THUMB_PLT_ENTRY_SIZE): New macro.
+ (PLT_ENTRY_SIZE): Return the appropriate *_PLT_ENTRY_SIZE.
+ (elf32_arm_plt0_entry): Rename PLT_ENTRY_SIZE to
+ ARM_PLT_ENTRY_SIZE.
+ (elf32_arm_plt_entry): Likewise.
+ (elf_backend_plt_header_size): Likewise.
+ (elf32_thumb_plt0_entry): New global.
+ (elf32_arm_finish_dynamic_sections): Use it. Put Thumb entries
+ into .plt.thumb.
+ (elf32_thumb_plt_entry): New global.
+ (elf32_arm_finish_dynamic_symbol): Use it. Use .thumb.plt for
+ Thumb entries. Set the bottom bit of the corresponding GOT entry
+ for a Thumb PLT entry.
+ (struct elf32_arm_plt_entry_info): New structure.
+ (struct elf32_arm_link_hash_entry, plt_info): New member of this
+ type.
+ (elf32_arm_link_hash_newfunc): Initialize new member.
+ (elf32_arm_final_link_relocate, R_ARM_THM_PC22 case): Handle
+ relocations against the PLT.
+ (elf32_arm_check_relocs, case R_ARM_PLT32 case): Set
+ first_rel_type if this is the first time we encounter the symbol.
+ (elf32_arm_check_relocs, case R_ARM_THM_PC22 case): New case.
+ Determine if relocation needs a PLT entry. Set first_rel_type if
+ this is the first time we encounter the symbol
+ (elf32_arm_adjust_dynamic_symbol): Create PLT entries for Thumb
+ functions as well.
+ (elf32_arm_size_dynamic_sections): Handle .plt.thumb like .plt.
+ (elf32_arm_create_dynamic_sections): New function. Create the
+ .plt.thumb section.
+ (elf_backend_create_dynamic_sections): Call it.
+
+2002-07-31 Nick Clifton <nickc@redhat.com>
+
+ * bfd.c (bfd_alt_mach_code): Rename parameter 'index' to
+ 'alternative' in order to avoid shadowing global symbol of the
+ same name.
+ * bfd-in2.h: Regenerate.
+ * libbfd.h: Regenerate.
+ * libcoff.h: Regenerate.
+
+2002-07-31 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * Makefile.am: Add n32 ABI support.
+ * Makefile.in: Regenerate.
+ * config.bfd: Add n32 vectors to mips64*-*-linux* targets. Treat 64
+ bit vectors for mips*-*-linux targets as optional.
+ * configure.in: Add n32 ABI vectors.
+ * configure: Regenerate.
+ * elf32-mips.c (mips_elf32_object_p): Reject n32 ABI files.
+ * elfn32-mips.c: New file, n32 ABI support.
+ * targets.c: Add n32 ABI vectors.
+
+2002-07-30 Graeme Peterson <gp@qnx.com>
+
+ * elfarmqnx-nabi.c: New file: Support for QNX.
+ * config.bfd: Add support for arm-*-nto target.
+ * configure.in: Add support for bfd_elf32_{big|little}armqnx_vec.
+ * configure: Regenerate.
+ * Makefile.am: Add entries for elfarmqnx-nabi.c.
+ * Makefile.in: Regenerate.
+ * elf32-arm.h (ELF_MAXPAGESIZE): Do not define if already defined.
+ Do not define global function if ELFARM_NABI_C_INCLUDED is defined.
+ * elfarm-nabi.c: Do not include elf32-arm.h if
+ ELFARM_NABI_C_INCLUDED is defined.
+ * targets.c: Add bfd_elf32_{big|little}armqnx_vec.
+
+2002-07-30 Nick Clifton <nickc@redhat.com>
+
+ * po/sv.po: Updated Swedish translation.
+
+2002-07-30 Jakub Jelinek <jakub@redhat.com>
+
+ * elf.c (elf_fake_sections): Fix up .tbss sh_size and sh_type.
+
+2002-07-30 Alan Modra <amodra@bigpond.net.au>
+
+ * aoutx.h (some_aout_object_p): Clean up tdata properly on error.
+ * archive.c (bfd_generic_archive_p): Likewise.
+ * coff-rs6000.c (_bfd_xcoff_archive_p): Likewise.
+ (_bfd_xcoff_archive_p): Use bfd_scan_vma in place of strtol.
+ * coff64-rs6000.c (xcoff64_slurp_armap): Likewise.
+ (xcoff64_archive_p): Likewise.
+ (xcoff64_openr_next_archived_file): Likewise.
+ (xcoff64_archive_p): Clean up tdata properly on error.
+ * coffgen.c (coff_real_object_p): Likewise.
+ (coff_object_p): Release filehdr and opthdr.
+ * ecoff.c (_bfd_ecoff_archive_p): Clean up tdata properly on error.
+ * ieee.c (ieee_archive_p): Likewise.
+ * ihex.c (ihex_object_p): Likewise.
+ (ihex_mkobject): Always allocate tdata.
+ * peicode.h (pe_ILF_object_p): Release bfd_alloc'd buffer on error.
+ * srec.c (srec_mkobject): Always allocate tdata.
+ (srec_object_p): Clean up tdata properly on error.
+ (symbolsrec_object_p): Likewise.
+ * versados.c (versados_object_p): Likewise.
+ * vms-misc.c (_bfd_vms_get_record): Use bfd_malloc instead of malloc,
+ and bfd_realloc instead of realloc.
+ (add_new_contents): Use bfd_alloc instead of bfd_malloc for sections.
+ * vms.c (vms_initialize): Always allocate tdata. Use bfd_alloc in
+ place of bfd_malloc, simplifying error freeing. Free hash table too.
+ (vms_object_p): Clean up tdata on error.
+ (vms_mkobject): Don't complain on stderr if vms_initialize fails.
+ (vms_close_and_cleanup): Adjust for bfd_alloc use.
+
+2002-07-30 Alan Modra <amodra@bigpond.net.au>
+
+ * elfxx-ia64.c (elfNN_ia64_final_write_processing): Set e_flags.
+
+2002-07-26 Chris Demetriou <cgd@broadcom.com>
+
+ * elfxx-mips.c (_bfd_mips_elf_merge_private_bfd_data): Merge ASE
+ flags into resulting BFD.
+
+2002-07-26 Alan Modra <amodra@bigpond.net.au>
+
+ From John Reiser <jreiser@BitWagon.com>
+ * elf32-i386.c (elf_i386_link_hash_table_create): Clear
+ tls_ldm_got.refcount.
+
+2002-07-25 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * elf64-mips.c: Update TODO comment.
+ (mips_elf64_higher_reloc,mips_elf64_highest_reloc,
+ mips_elf64_gprel16_reloca): Remove prototypes.
+ (mips16_jump_reloc,mips16_gprel_reloc): Add functions.
+ (UNUSED_RELOC): Replace by EMPTY_RELOC.
+ (mips_elf64_howto_table_rel): Use special R_MIPS_HI16 handling. Remove
+ wrong comments. Remove disfunctional support of R_MIPS_HIGHER and
+ R_MIPS_HIGHEST.
+ (mips_elf64_howto_table_rela): Fix handling of R_MIPS_GPREL16 and
+ R_MIPS_GOT16. Remove wrong comments.
+ (elf_mips16_jump_howto,elf_mips16_gprel_howto,
+ elf_mips_gnu_vtinherit_howto,elf_mips_gnu_vtentry_howto): New, code
+ from elf32-mips.c.
+ (mips_elf64_hi16_reloc): Fix formatting.
+ (mips_elf64_higher_reloc,mips_elf64_highest_reloc): Remove.
+ (mips_elf64_got16_reloc): Fix formatting. Remove superfluous code.
+ Better comment. Fall back to R_MIPS_GOT_DISP instead of abort().
+ (mips_elf64_gprel16_reloc): Make static. Add check for
+ partial_inplace.
+ (mips_elf64_gprel16_reloca): Remove.
+ (mips_elf64_literal_reloc): New function.
+ (mips_elf64_gprel32_reloc): Fix formatting.
+ (mips_elf64_shift6_reloc): Fix comment. Make static.
+ (mips16_jump_reloc,mips16_gprel_reloc): New functions, code from
+ elf32-mips.c.
+ (elf_reloc_map,mips_reloc_map): New mapping table, similiar as in
+ elf32-mips.c
+ (bfd_elf64_bfd_reloc_type_lookup): Use the mapping table. Enable GNU
+ specific relocations.
+ (mips_elf64_rtype_to_howto): Enable GNU specific relocations.
+ (mips_elf64_object_p): Invert logic to check for SGI-ish ABI.
+ (ELF_MAXPAGESIZE): Add comment.
+
+2002-07-25 Nick Clifton <nickc@redhat.com>
+
+ * po/sv.po: Updated Swedish translation.
+ * po/es.po: Updated Spanish translation.
+ * po/fr.po: Updated French translation.
+
+2002-07-25 Alan Modra <amodra@bigpond.net.au>
+
+ * elf-bfd.h (_bfd_elf32_link_record_local_dynamic_symbol): Define
+ as elf_link_record_local_dynamic_symbol.
+ (_bfd_elf64_link_record_local_dynamic_symbol): Likewise.
+ (elf_link_record_local_dynamic_symbol): Declare. Now returns int.
+ * elflink.h (elf_link_record_local_dynamic_symbol): Move to..
+ * elflink.c: .. here. Use bfd_elf_get_elf_syms. Check whether an
+ attempt is made to record a symbol in a discarded section, and
+ return `2' in that case.
+
+2002-07-24 Nick Clifton <nickc@redhat.com>
+
+ * po/sv.po: Updated Swedish translation.
+ * po/es.po: Updated Spanish translation.
+
+2002-07-23 Alan Modra <amodra@bigpond.net.au>
+
+ * po/SRC-POTFILES.in: Regenerate.
+
+ * elf-hppa.h (elf_hppa_relocate_section): If relocatable, return
+ immediately. Remove code handling relocatable linking.
+ * elf32-avr.c (elf32_avr_relocate_section): Likewise.
+ * elf32-cris.c (cris_elf_relocate_section): Likewise.
+ * elf32-fr30.c (elf32_frv_relocate_section): Likewise.
+ * elf32-frv.c (elf32_frv_relocate_section): Likewise.
+ * elf32-h8300.c (elf32_h8_relocate_section): Likewise.
+ * elf32-hppa.c (elf32_hppa_relocate_section): Likewise.
+ * elf32-ip2k.c (ip2k_elf_relocate_section): Likewise.
+ * elf32-sparc.c (elf32_sparc_relocate_section): Likewise.
+ * elf32-v850.c (v850_elf_relocate_section): Likewise.
+ * elf32-vax.c (elf_vax_relocate_section): Likewise.
+ * elf64-sparc.c (sparc64_elf_relocate_section): Likewise.
+ * elf32-avr.c (elf_backend_rela_normal): Define.
+ * elf32-cris.c: Likewise.
+ * elf32-fr30.c: Likewise.
+ * elf32-frv.c: Likewise.
+ * elf32-h8300.c: Likewise.
+ * elf32-hppa.c: Likewise.
+ * elf32-ip2k.c: Likewise.
+ * elf32-sparc.c: Likewise.
+ * elf32-v850.c: Likewise.
+ * elf32-vax.c: Likewise.
+ * elf64-hppa.c: Likewise.
+ * elf64-sparc.c: Likewise.
+ * elf32-fr30.c (elf32_frv_relocate_section): Edit comment.
+ * elf32-frv.c (elf32_frv_relocate_section): Likewise.
+ * elf32-i860.c (elf32_i860_relocate_section): Likewise.
+ * elf32-ip2k.c (ip2k_elf_relocate_section): Likewise.
+ * elf32-m32r.c (m32r_elf_relocate_section): Likewise.
+ * elf32-openrisc.c (openrisc_elf_relocate_section): Likewise.
+ * elf32-xstormy16.c (xstormy16_elf_relocate_section): Likewise.
+ * elf-m10200.c (USE_RELA): Don't define.
+ * elf-m10300.c: Likewise.
+ * elfarm-oabi.c: Likewise.
+ * elf32-i370.c: Likewise.
+ * elf32-ip2k.c: Likewise.
+ * elf32-m68k.c: Likewise.
+ * elf32-mcore.c: Likewise.
+ * elf32-ppc.c: Likewise.
+ * elf32-s390.c: Likewise.
+ * elf32-vax.c: Likewise.
+ * elf64-ppc.c: Likewise.
+ * elf64-s390.c: Likewise.
+ * elf64-x86-64.c: Likewise.
+ * elfxx-ia64.c: Likewise.
+ * elf32-avr.c (USE_REL): Don't undef.
+ * elf32-ip2k.c: Likewise.
+
+2002-07-23 Nick Clifton <nickc@redhat.com>
+
+ * elf-bfd.h (struct elf_backend_data): Add new bitfield
+ 'want_p_paddr_set_to_zero'.
+ * elfxx-target.h: Set default value for want_p_paddr_set_to_zero
+ to false;
+ * elfxx-ia64.c: Set want_p_paddr_set_zero for HPUX target.
+ * elf.c (copy_private_bfd_data): Test want_p_paddr_set_zero.
+
+2002-07-23 Gabor Keresztfalvi <keresztg@mail.com>
+
+ * nlmcode.h (nlm_swap_auxiliary_headers_out): Swapped the order of
+ the MeSsAgEs and CoPyRiGhT tags to make >=NW4.x NLM loaders to
+ show the Copyright string.
+ Minor formatting tidy ups.
+
+2002-07-23 Nick Clifton <nickc@redhat.com>
+
+ * po/fr.po: Updated French translation.
+ * po/sv.po: Updated Swedish translation.
+
+2002-07-23 Alan Modra <amodra@bigpond.net.au>
+
+ * elflink.h (elf_link_input_bfd): Don't change internal symbols
+ when outputting relocs.
+
+2002-07-20 Jason Thorpe <thorpej@wasabisystems.com>
+
+ * elf64-alpha.c (elf64_alpha_size_dynamic_sections): Only insert
+ DT_PLTGOT into the dynamic section if there is a PLT.
+
+2002-07-19 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * elfxx-mips.c (_bfd_mips_elf_discard_info): New function, code from
+ elf32-mips.c.
+ (_bfd_mips_elf_write_section): Likewise.
+ * elfxx-mips.h (_bfd_mips_elf_discard_info): New prototype.
+ (_bfd_mips_elf_write_section): Likewise.
+ * elf32-mips.c (elf32_mips_discard_info): Move to elfxx-mips.c.
+ (elf32_mips_write_section): Likewise.
+ * elf64-mips.c (_bfd_mips_elf_ignore_discarded_relocs): Use it.
+ (_bfd_mips_elf_write_section): Likewise.
+
+2002-07-19 Alan Modra <amodra@bigpond.net.au>
+
+ * elfxx-ia64.c: (elfNN_ia64_modify_segment_map): Properly scan
+ PT_IA_64_UNWIND segments for a given section.
+
+2002-07-17 H.J. Lu <hjl@gnu.org>
+
+ * Makefile.am: Fix a typo.
+ * Makefile.in: Regenerate.
+
+2002-07-15 Denis Chertykov <denisc@overta.ru>
+ Frank Ch. Eigler <fche@redhat.com>
+ Ben Elliston <bje@redhat.com>
+ Alan Lehotsky <alehotsky@cygnus.com>
+ John Healy <jhealy@redhat.com>
+ Graham Stott <grahams@redhat.com>
+ Jeff Johnston <jjohnstn@redhat.com>
+
+ * Makefile.am: Add support for ip2k.
+ * Makefile.in: Regenerate.
+ * doc/Makefile.in: Regenerate.
+ * archures.c: Add support for ip2k.
+ * config.bfd: Add support for ip2k.
+ * configure.in: Add support for ip2k.
+ * configure: Regenerate.
+ * reloc.c: Add support for ip2k.
+ * targets.c: Add support for ip2k.
+ * bfd-in2.h: Regenerate.
+ * libbfd.h: Regenerate.
+ * cpu-ip2k.c: New file.
+ * elf32-ip2k.c: New file.
+
+2002-07-17 Ian Rickards <irickard@arm.com>
+
+ * dwarf2.c (concat_filename): If we can't establish the directory
+ just return the filename.
+
+2002-07-16 Moritz Jodeit <moritz@jodeit.org>
+
+ * peXXigen.c (_bfd_XXi_swap_aouthdr_out): Correct order of memset args.
+
+2002-07-16 Alan Modra <amodra@bigpond.net.au>
+
+ * elflink.h: Formatting fixes, tidy prototypes.
+ (elf_link_assign_sym_version): Move common code out of loop.
+
+2002-07-16 Alan Modra <amodra@bigpond.net.au>
+
+ * elflink.h (elf_link_input_bfd): Don't call reloc_emitter when
+ reloc section size is zero. Correct reloc output location.
+
+2002-07-16 John David Anglin <dave@hiauly1.hia.nrc.ca>
+
+ * elf-hppa.h (elf_hppa_reloc_final_type): Use R_PARISC_PCREL16F as
+ the final type for the e_fsel selector when generating PA2.0W code.
+ (elf_hppa_relocate_insn): Provide support for PA2.0W 16-bit format 1
+ relocations.
+
+2002-07-14 H.J. Lu <hjl@gnu.org>
+
+ * elflink.h (elf_link_assign_sym_version): Hide the default
+ definition if there is a hidden versioned definition.
+
+2002-07-12 Hans-Peter Nilsson <hp@axis.com>
+
+ * elf32-cris.c (cris_elf_relocate_section): Drop nonsensical
+ dynamic reference test in assertion when initializing GOT with
+ static contents. Just assert that there are either no dynamic
+ sections, the symbol is defined in the regular objects or that the
+ symbol is undef weak. Tweak comment.
+ (elf_cris_finish_dynamic_symbol): Emit .got reloc for a program
+ only if the symbol isn't defined in the program and isn't undef
+ weak.
+ (elf_cris_adjust_dynamic_symbol): Simplify condition for getting
+ rid of PLT entry: only do it if the symbol isn't defined in a DSO.
+ When doing so, clear ELF_LINK_HASH_NEEDS_PLT. Tweak comments.
+ (elf_cris_discard_excess_program_dynamics): Don't consider
+ ELF_LINK_HASH_REF_DYNAMIC when omitting .got runtime relocs.
+
+2002-07-11 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-i386.c (elf_i386_relocate_section): Don't complain about
+ unresolved debugging relocs in dynamic applications.
+ * elf32-s390.c (elf_s390_relocate_section): Likewise.
+ * elf32-sparc.c (elf32_sparc_relocate_section): Likewise.
+ * elf64-ppc.c (ppc64_elf_relocate_section): Likewise.
+ * elf64-s390.c (elf_s390_relocate_section): Likewise.
+ * elf64-sparc.c (sparc64_elf_relocate_section): Likewise.
+ * elf64-x86-64.c (elf64_x86_64_relocate_section): Likewise.
+
+2002-07-10 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (ONES): Define.
+ (ppc64_elf_howto_table): Use ONES here to avoid warnings. Fill in
+ missing src_mask fields. Tweak R_PPC64_NONE, R_PPC64_COPY. Fill
+ in missing dst_mask fields on R_PPC64_PLT32, R_PPC64_PLTREL32.
+
+ * elf64-ppc.c (ppc64_elf_get_symbol_info): Delete.
+ (ppc64_elf_set_private_flags): Delete.
+ (ppc64_elf_section_from_shdr): Delete.
+ (ppc64_elf_merge_private_bfd_data): Remove flag checking/merging code.
+ (ppc64_elf_fake_sections): Delete.
+ (bfd_elf64_bfd_set_private_flags): Don't define.
+ (bfd_elf64_get_symbol_info): Likewise.
+ (elf_backend_section_from_shdr): Likewise.
+ (elf_backend_fake_sections): Likewise.
+
+2002-07-10 Marco Walther <Marco.Walther@sun.com>
+
+ * elf.c: (assign_section_numbers) Set sh_entsize for .stab only
+ when not already set.
+ * elf64-sparc.c: (sparc64_elf_fake_sections): New function.
+ (elf_backend_fake_sections): Define.
+
+2002-07-10 Alan Modra <amodra@bigpond.net.au>
+
+ * merge.c (_bfd_merge_section): Remove redundant output_section check.
+ Formatting.
+ (_bfd_merge_sections): Don't set SEC_EXCLUDE on unused sections.
+
+2002-07-09 Hans-Peter Nilsson <hp@axis.com>
+
+ * elf32-cris.c (cris_elf_relocate_section): Move sanity-check for
+ NULL sym_hashes to just before use.
+ <case R_CRIS_32_GOTREL>: In test for local symbol, accept also
+ symbol with non-default visibility.
+ <case R_CRIS_32_GOTREL, case R_CRIS_32_PLT_GOTREL>: Ditto.
+ <case R_CRIS_8_PCREL, case R_CRIS_16_PCREL, case R_CRIS_32_PCREL>:
+ Ditto.
+ (cris_elf_gc_sweep_hook): Only decrease h->plt.refcount for
+ symbol with non-default visibility.
+ (cris_elf_check_relocs): At tests for local symbol before
+ increasing h->plt.refcount, also check for non-default
+ visibility. Ditto when checking for local symbol to eliminate
+ pc-relative runtime relocs.
+
+2002-07-08 Alan Modra <amodra@bigpond.net.au>
+
+ * elf.c: Formatting.
+ (IS_SOLARIS_PT_INTERP): Add p_paddr and p_memsz checks.
+ (INCLUDE_SECTION_IN_SEGMENT): Remove IS_SOLARIS_PT_INTERP.
+ (copy_private_bfd_data): Set p_vaddr on broken Solaris PT_INTERP
+ segments.
+
+2002-07-07 Mark Mitchell <mark@codesourcery.com>
+ Alan Modra <amodra@bigpond.net.au>
+
+ * cofflink.c (_bfd_coff_final_link): On PE COFF systems, take into
+ account the impact of relocation count overflow when computing
+ section offsets.
+ * coffcode.h (coff_write_relocs): Use obj_pe when deciding whether
+ or not to apply the PE COFF reloc overflow handling. Fix a
+ fencepost error in deciding whether or not to use that technique.
+
+2002-07-07 Alan Modra <amodra@bigpond.net.au>
+
+ * elf-bfd.h (struct elf_reloc_cookie): Remove locsym_shndx,
+ change type of locsyms.
+ (bfd_elf_get_elf_syms): Declare.
+ * elf.c (bfd_elf_get_elf_syms): New function.
+ (group_signature): Use bfd_elf_get_elf_syms.
+ (bfd_section_from_r_symndx): Likewise.
+ * elfcode.h (elf_slurp_symbol_table): Likewise.
+ * elflink.h (elf_link_is_defined_archive_symbol): Likewise.
+ (elf_link_add_object_symbols): Likewise. Reorganise to increase
+ locality of various data structures. Properly free internal relocs.
+ (elf_bfd_final_link): Properly free internal relocs.
+ (elf_link_check_versioned_symbol): Use bfd_elf_get_elf_syms.
+ (elf_link_input_bfd): Likewise.
+ (elf_gc_mark): Likewise. Properly free internal relocs.
+ (elf_gc_sweep): Properly free internal relocs.
+ (elf_reloc_symbol_deleted_p): No need to swap syms in.
+ (elf_bfd_discard_info): Use bfd_elf_get_elf_syms. Properly free
+ internal relocs.
+ * elf-m10200.c (mn10200_elf_relax_section): Use bfd_elf_get_elf_syms.
+ Properly free possibly cached info.
+ (mn10200_elf_relax_delete_bytes): Remove symbol swapping code.
+ (mn10200_elf_symbol_address_p): Pass in internal syms. Remove
+ symbol swapping code.
+ (mn10200_elf_get_relocated_section_contents): Use bfd_elf_get_elf_syms.
+ Properly free possibly cached info.
+ * elf-m10300.c (mn10300_elf_relax_section): As above for elf-m10200.c.
+ (mn10300_elf_relax_delete_bytes): Likewise.
+ (mn10300_elf_symbol_address_p): Likewise.
+ (mn10300_elf_get_relocated_section_contents): Likewise.
+ * elf32-h8300.c (elf32_h8_relax_section): As above for elf-m10200.c.
+ (elf32_h8_relax_delete_bytes): Likewise.
+ (elf32_h8_symbol_address_p): Likewise.
+ (elf32_h8_get_relocated_section_contents): Likewise.
+ * elf32-m32r.c (m32r_elf_relax_section): As above for elf-m10200.c.
+ (m32r_elf_relax_delete_bytes): Likewise.
+ (m32r_elf_get_relocated_section_contents): Likewise.
+ * elf32-sh.c (sh_elf_reloc_loop): Free section contents using
+ elf_section_data to determine whether cached.
+ (sh_elf_relax_section): As above for elf-m10200.c.
+ (sh_elf_relax_delete_bytes): Likewise.
+ (sh_elf_get_relocated_section_contents): Likewise.
+ * elf32-xstormy16.c (xstormy16_elf_relax_section): As above.
+ * elf64-alpha.c (elf64_alpha_relax_section): As above. Also delay
+ reading of local syms.
+ * elf64-mmix.c (mmix_elf_relax_section): Likewise.
+ * elf64-sh64.c (sh_elf64_get_relocated_section_contents): As above.
+ * elfxx-ia64.c (elfNN_ia64_relax_section): As above.
+ * elfxx-mips.c (_bfd_mips_elf_check_relocs): Properly free internal
+ relocs.
+ * elf32-arm.h (bfd_elf32_arm_process_before_allocation): Properly
+ free internal relocs and section contents. Don't read symbols.
+ * elf32-hppa.c (get_local_syms): Use bfd_elf_get_elf_syms.
+ (elf32_hppa_size_stubs): Don't free local syms.
+ * elf32-m68k.c (bfd_m68k_elf32_create_embedded_relocs): Delay
+ reading of local syms. Use bfd_elf_get_elf_syms. Properly free
+ possibly cached info.
+ * elf32-mips.c (bfd_mips_elf32_create_embedded_relocs): Likewise.
+ * elf64-hppa.c (elf64_hppa_check_relocs): Use bfd_elf_get_elf_syms.
+ * elf64-ppc.c (struct ppc_link_hash_table): Delete bfd_count and
+ all_local_syms.
+ (get_local_syms): Delete function.
+ (edit_opd): Use bfd_elf_get_elf_syms. Free on error exit. Cache
+ on exit.
+ (ppc64_elf_size_stubs): Use bfd_elf_get_elf_syms. Free/cache on exit.
+
+2002-07-05 Jim Wilson <wilson@redhat.com>
+
+ * syms.c (decode_section_type): New.
+ (bfd_decode_symclass): Call decode_section_type.
+
+2002-07-04 Jakub Jelinek <jakub@redhat.com>
+
+ * merge.c (_bfd_merged_section_offset): Avoid accessing byte before
+ section content start.
+ Reported by Michael Schumacher <mike@hightec-rt.com>.
+
+2002-07-04 Alan Modra <amodra@bigpond.net.au>
+
+ * section.c (_bfd_strip_section_from_output): Remove unnecessary
+ link order code. Don't actually remove the output section here;
+ Just set a flag for the linker to do so.
+ * elflink.c (_bfd_elf_link_renumber_dynsyms): Test for removed
+ sections when setting up output section dynsyms.
+
+2002-07-04 Alan Modra <amodra@bigpond.net.au>
+
+ * elflink.h (elf_link_add_object_symbols): Revert 1999-09-02 hpux
+ fudge.
+ * elf.c (bfd_section_from_shdr): Work around broken hpux shared
+ libs here instead.
+
+2002-07-02 Martin Schwidefsky <schwidefsky@de.ibm.com>
+
+ * elf64-s390.c (create_got_section): Set .got section alignment to
+ 8 bytes.
+ (elf_s390_check_relocs): Set .rela.dyn section alignment to 8 bytes.
+
+2002-07-02 Alan Modra <amodra@bigpond.net.au>
+
+ * elf.c (_bfd_elf_reloc_type_class): Fix comment grammar.
+
+2002-07-01 Matt Thomas <matt@3am-software.com>
+
+ * elf32-vax.c (elf32_vax_print_private_bfd_data): Change EF_*
+ to EF_VAX_*.
+
+2002-07-01 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * elfxx-mips.c (ABI_64_P): Fix comment.
+ (MIPS_ELF_OPTIONS_SECTION_NAME,MIPS_ELF_STUB_SECTION_NAME): Use the
+ new section names for N64 ABI.
+ (mips_elf_output_extsym): No special _gp_disp handling for NewABI.
+ (mips_elf_calculate_relocation): Code formatting.
+ (mips_elf_create_dynamic_relocation): Likewise.
+ (_bfd_mips_elf_fake_sections): IRIX6 needs this hack, too.
+ (_bfd_mips_elf_size_dynamic_sections): Handle GOT_PAGE for any NewABI.
+ (_bfd_mips_elf_relocate_section): No special handling for R_MIPS_64
+ in any NewABI.
+ (_bfd_mips_elf_finish_dynamic_symbol): No special _gp_disp handling
+ for NewABI.
+ (_bfd_mips_elf_modify_segment_map): Handle any N64 ABI.
+ (_bfd_mips_elf_gc_sweep_hook): NewABI GOT relocs should be handled
+ here, too.
+
+2002-07-01 Andreas Schwab <schwab@suse.de>
+
+ * elf64-x86-64.c (elf64_x86_64_relocate_section): Only convert
+ R_X86_64_64 to R_X86_64_RELATIVE.
+
+2002-07-01 John David Anglin <dave@hiauly1.hia.nrc.ca>
+
+ * vaxbsd.c: New BFD backend for VAX BSD and Ultrix.
+ * Makefile.am (BFD32_BACKENDS, BFD32_BACKENDS_CFILES): Add new backend.
+ Run "make dep-am".
+ * config.bfd (vax-*-bsd* | vax-*-ultrix*): Use vaxbsd_vec instead of
+ host_aout_vec.
+ * configure.in (vaxbsd_vec): Add.
+ * targets.c (vaxbsd_vec): Add.
+ * Makefile.in: Rebuild.
+ * configure: Rebuild.
+ * po/SRC-POTFILES.in: Rebuild.
+
+2002-07-01 Alan Modra <amodra@bigpond.net.au>
+
+ * elflink.h (elf_gc_mark): Pass in the section whose relocs we are
+ examining to gc_mark_hook, rather than the bfd.
+ (elf_gc_sections): Adjust.
+ * elf-bfd.h (struct elf_backend_data <gc_mark_hook>): Likewise.
+ * elf-m10300.c (mn10300_elf_gc_mark_hook): Likewise.
+ * elf32-arm.h (elf32_arm_gc_mark_hook): Likewise.
+ * elf32-avr.c (elf32_avr_gc_mark_hook): Likewise.
+ * elf32-cris.c (cris_elf_gc_mark_hook): Likewise.
+ * elf32-d10v.c (elf32_d10v_gc_mark_hook): Likewise.
+ * elf32-fr30.c (fr30_elf_gc_mark_hook): Likewise.
+ * elf32-hppa.c (elf32_hppa_gc_mark_hook): Likewise.
+ * elf32-i386.c (elf_i386_gc_mark_hook): Likewise.
+ * elf32-m32r.c (m32r_elf_gc_mark_hook): Likewise.
+ * elf32-m68k.c (elf_m68k_gc_mark_hook): Likewise.
+ * elf32-mcore.c (mcore_elf_gc_mark_hook): Likewise.
+ * elf32-openrisc.c (openrisc_elf_gc_mark_hook): Likewise.
+ * elf32-ppc.c (ppc_elf_gc_mark_hook): Likewise.
+ * elf32-s390.c (elf_s390_gc_mark_hook): Likewise.
+ * elf32-sh.c (sh_elf_gc_mark_hook): Likewise.
+ * elf32-sparc.c (elf32_sparc_gc_mark_hook): Likewise.
+ * elf32-v850.c (v850_elf_gc_mark_hook): Likewise.
+ * elf32-vax.c (elf_vax_gc_mark_hook): Likewise.
+ * elf32-xstormy16.c (xstormy16_elf_gc_mark_hook): Likewise.
+ * elf64-mmix.c (mmix_elf_gc_mark_hook): Likewise.
+ * elf64-ppc.c (ppc64_elf_gc_mark_hook): Likewise.
+ * elf64-s390.c (elf_s390_gc_mark_hook): Likewise.
+ * elf64-sh64.c (sh_elf64_gc_mark_hook): Likewise.
+ * elfxx-mips.c (_bfd_mips_elf_gc_mark_hook): Likewise.
+ * elfxx-mips.h (_bfd_mips_elf_gc_mark_hook): Likewise.
+ * elf64-x86-64.c (elf64_x86_64_gc_mark_hook): Likewise.
+ * elf32-frv.c (elf32_frv_gc_mark_hook): Likewise. Also remove
+ redundant local sym tests.
+ * elf64-ppc.c (struct ppc_link_hash_entry): Add is_entry.
+ (link_hash_newfunc): Init is_entry.
+ (ppc64_elf_copy_indirect_symbol): Copy is_entry.
+ (ppc64_elf_link_hash_table_create): Init all_local_syms.
+ (create_linkage_sections): Use bfd_make_section_anyway rather than
+ bfd_make_section.
+ (ppc64_elf_mark_entry_syms): New function.
+ (ppc64_elf_check_relocs): Don't bother testing elf_bad_symtab. Set
+ up opd entry to function section map.
+ (ppc64_elf_gc_mark_hook): Special case opd section relocs, and
+ relocs that reference the opd section.
+ (edit_opd): New function.
+ (ppc64_elf_size_dynamic_sections): Call get_local_syms and edit_opd.
+ (ppc64_elf_setup_section_lists): Don't calculate htab->bfd_count here.
+ (get_local_syms): Do so here. Exit if we already have local syms.
+ Remove bogus comment imported from elf32-hppa.c. Don't attempt to
+ read local syms on non-ELF input.
+ (ppc64_elf_size_stubs): Call _bfd_elf64_link_read_relocs rather
+ than duplicating it's function here. Adjust free of internal
+ relocs to suit.
+ (ppc64_elf_relocate_section): Adjust local syms in opd section.
+ * elf64-ppc.h (ppc64_elf_mark_entry_syms): Declare.
+ * elf32-hppa.c (elf32_hppa_size_stubs): Call
+ _bfd_elf32_link_read_relocs rather than duplicating it's function
+ here. Adjust free of internal relocs to suit.
+
+2002-07-01 Andreas Jaeger <aj@suse.de>
+
+ * elf64-x86-64.c (elf64_x86_64_check_relocs): Certain relocations
+ are not allowed in shared libs code, enforce -fPIC.
+
+2002-06-29 Hans-Peter Nilsson <hp@bitrange.com>
+
+ * mmo.c (mmo_write_loc_chunk): Don't eliminate leading and
+ trailing zero-sequences when there's previous left-over data.
+
+2002-06-27 John David Anglin <dave@hiauly1.hia.nrc.ca>
+
+ * elf64-hppa.c (elf64_hppa_reloc_type_class): New function.
+ (elf64_hppa_finish_dynamic_sections): Check other_rel_sec, dlt_rel_sec
+ and opd_rel_sec in order for starting rela section. Check _raw_size.
+ (elf_backend_reloc_type_class): Define.
+
+2002-06-27 Kevin Buettner <kevinb@redhat.com>
+
+ * dwarf2.c (decode_line_info): Handle older, non-standard, 64-bit
+ DWARF2 formats.
+
+2002-06-27 Alan Modra <amodra@bigpond.net.au>
+
+ * cpu-powerpc.c: Comment on ordering of arch_info.
+ * elf32-ppc.c (ppc_elf_object_p): New function.
+ (elf_backend_object_p): Define.
+ * elf64-ppc.c (ppc64_elf_object_p): New function.
+ (elf_backend_object_p): Define.
+
+2002-06-26 Jason Thorpe <thorpej@wasabisystems.com>
+
+ * configure.in (vax-*-netbsd*): Set COREFILE to netbsd-core.lo.
+ * configure: Regenerate.
+
+2002-06-25 Jason Eckhardt <jle@rice.edu>
+
+ * dwarf2.c (decode_line_info): Check unit->addr_size
+ to read in the proper number of prologue bytes.
+
+2002-06-25 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * config.bfd (powerpc-*-aix5*): Only create a selvecs for
+ aix5coff64_vec if 64-bit bfd support has been enabled.
+ (powerpc64-*-aix5*): Only define if 64-bit bfd support has
+ been enabled.
+
+ * targets.c (_bfd_target_vector[]): Only include
+ aix5coff64_vec if 64-bit bfd support has been enabled.
+
+2002-06-25 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (ppc_add_stub): Replace strcpy/strncpy with memcpy.
+ * elf32-hppa.c (hppa_add_stub): Likewise.
+ * elflink.c (_bfd_elf_link_record_dynamic_symbol): Likewise.
+ * elflink.h (elf_add_default_symbol): Fix comment typo.
+ (elf_add_default_symbol): Replace strcpy and strncpy with memcpy.
+ (elf_link_add_object_symbols): Likewise.
+ (elf_link_assign_sym_version): Likewise.
+ * hash.c (bfd_hash_lookup): Likewise.
+ * linker.c (_bfd_generic_link_add_one_symbol): Likewise.
+ * section.c (bfd_get_unique_section_name): Likewise.
+ * syms.c (_bfd_stab_section_find_nearest_line): Likewise.
+ * elf.c (_bfd_elf_make_section_from_phdr): Likewise.
+ (assign_section_numbers): Likewise.
+ (_bfd_elfcore_make_pseudosection): Likewise.
+ (elfcore_grok_lwpstatus): Likewise.
+ (elfcore_grok_win32pstatus): Likewise.
+ (elfcore_write_note): Constify input params. Use PTR instead of
+ void *. Include terminating NUL in namesz. Correct padding.
+ Support NULL "name" param. Use memcpy instead of strcpy.
+ (elfcore_write_prpsinfo): Constify input params.
+ (elfcore_write_prstatus): Likewise. Use PTR instead of void *.
+ (elfcore_write_lwpstatus): Likewise.
+ (elfcore_write_pstatus): Likewise.
+ (elfcore_write_prfpreg): Likewise.
+ (elfcore_write_prxfpreg): Likewise.
+ * elf-bfd.h (elfcore_write_note): Update declaration.
+ (elfcore_write_prpsinfo): Likewise.
+ (elfcore_write_prstatus): Likewise.
+ (elfcore_write_pstatus): Likewise.
+ (elfcore_write_prfpreg): Likewise.
+ (elfcore_write_prxfpreg): Likewise.
+ (elfcore_write_lwpstatus): Likewise.
+
+2002-06-25 Jason Eckhardt <jle@rice.edu>
+
+ * ecoff.c (ecoff_set_symbol_info): Set BSF_FUNCTION for
+ symbols of type stProc and stStaticProc.
+
+2002-06-25 Nick Clifton <nickc@redhat.com>
+
+ * ecoff.c: VArious formatting fixes.
+
+2002-06-25 Alan Modra <amodra@bigpond.net.au>
+
+ * coff-rs6000.c (xcoff_generate_rtinit): Fix typo.
+
+2002-06-25 Alan Modra <amodra@bigpond.net.au>
+
+ * aout-adobe.c: Don't compare against "true" or "false.
+ * aout-target.h: Likewise.
+ * aoutx.h: Likewise.
+ * archive.c: Likewise.
+ * bout.c: Likewise.
+ * cache.c: Likewise.
+ * coff-a29k.c: Likewise.
+ * coff-alpha.c: Likewise.
+ * coff-i386.c: Likewise.
+ * coff-mips.c: Likewise.
+ * coff-or32.c: Likewise.
+ * coff64-rs6000.c: Likewise.
+ * coffcode.h: Likewise.
+ * coffgen.c: Likewise.
+ * cpu-ns32k.c: Likewise.
+ * ecoff.c: Likewise.
+ * ecofflink.c: Likewise.
+ * elf.c: Likewise.
+ * elf32-arm.h: Likewise.
+ * elf32-cris.c: Likewise.
+ * elf32-d30v.c: Likewise.
+ * elf32-i386.c: Likewise.
+ * elf32-mcore.c: Likewise.
+ * elf32-ppc.c: Likewise.
+ * elf32-sh.c: Likewise.
+ * elf32-sh64.c: Likewise.
+ * elf32-v850.c: Likewise.
+ * elf64-alpha.c: Likewise.
+ * elf64-sh64.c: Likewise.
+ * elfcode.h: Likewise.
+ * elfcore.h: Likewise.
+ * elflink.h: Likewise.
+ * elfxx-mips.c: Likewise.
+ * i386os9k.c: Likewise.
+ * ieee.c: Likewise.
+ * libbfd.c: Likewise.
+ * linker.c: Likewise.
+ * mmo.c: Likewise.
+ * nlm32-alpha.c: Likewise.
+ * nlm32-i386.c: Likewise.
+ * nlm32-ppc.c: Likewise.
+ * nlm32-sparc.c: Likewise.
+ * nlmcode.h: Likewise.
+ * oasys.c: Likewise.
+ * pdp11.c: Likewise.
+ * peicode.h: Likewise.
+ * reloc.c: Likewise.
+ * som.c: Likewise.
+ * srec.c: Likewise.
+ * tekhex.c: Likewise.
+ * vms.c: Likewise.
+ * xcofflink.c: Likewise.
+ * elf64-sparc.c: Edit comment to not use "== false".
+
+ * aoutf1.h: Don't use "? true : false".
+ * ecoff.c: Likewise.
+ * format.c: Likewise.
+ * ieee.c: Likewise.
+ * linker.c: Likewise.
+ * mmo.c: Likewise.
+ * oasys.c: Likewise.
+
+2002-06-23 H.J. Lu <hjl@gnu.org>
+
+ * elflink.h (elf_link_add_archive_symbols): For the default
+ version, check references with only one `@' first.
+
+2002-06-23 John David Anglin <dave@hiauly1.hia.nrc.ca>
+
+ * elf64-hppa.c (elf64_hppa_mark_milli_and_exported_functions): New
+ function.
+ (allocate_global_data_dlt): Don't add millicode symbols to dynamic
+ symbol table.
+ (allocate_global_data_opd, allocate_dynrel_entries): Likewise.
+ (elf64_hppa_size_dynamic_sections): Revise to use
+ elf64_hppa_mark_milli_and_exported_functions.
+ (elf64_hppa_finish_dynamic_symbol): Remove code to keep millicode
+ symbols out of dynamic symbol table.
+
+2002-06-23 Alan Modra <amodra@bigpond.net.au>
+
+ * Makefile.in: Regenerate.
+ * libbfd.h: Regenerate.
+ * bfd-in2.h: Regenerate.
+ * configure: Regenerate.
+ * po/SRC-POTFILES.in: Regenerate.
+
+ * elflink.h: Comment typo fixes.
+
+2002-06-23 H.J. Lu <hjl@gnu.org>
+
+ * elf-bfd.h (elf_link_loaded_list): New structure.
+ (elf_link_hash_table): Add "loaded".
+ * elf.c (_bfd_elf_link_hash_table_init): Initialize "loaded".
+ * elflink.h (elf_link_check_versioned_symbol): New function.
+ (elf_link_output_extsym): Call elf_link_check_versioned_symbol.
+
+2002-06-19 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * elflink.h (size_dynamic_sections): If the target does not
+ support an ELF style hash table, return true, indicating that
+ nothing needed to be done, rather than false, indicating that the
+ section's size could not be computed.
+
+2002-06-18 Dave Brolley <brolley@redhat.com>
+
+ From Catherine Moore, Michael Meissner, Dave Brolley:
+ * po/SRC-POTFILES.in: Add cpu-frv.c and elf32-frv.c
+ * targets.c: Support bfd_elf32_frv_vec.
+ * reloc.c: Add FRV relocs.
+ * configure.in: Add support for bfd-elf32-frv-vec.
+ * config.bfd (targ_cpu): Add support for frv-*-elf.
+ * archures.c: Add frv arch and machines.
+ * Makefile.am (ALL_MACHINES): Add cpu-frv.lo.
+ (ALL_MACHINES_CFILES): Add cpu-frv.c.
+ (BFD32_BACKENDS): Add elf32-frv.lo.
+ (BFD32_BACKENDS_CFILES): Add elf32-frv.c
+ (cpu-frv.lo): New target.
+ (elf32-frv.lo): New target.
+ * cpu-frv.c: New file.
+ * elf32-frv.c: New file.
+
+2002-06-18 Jakub Jelinek <jakub@redhat.com>
+
+ * elfcode.h (elf_object_p): Sanity check eh_shoff == 0 implies
+ e_shnum == 0.
+ Only read the first section header if e_shoff is non-zero.
+ Don't consider e_shstrndx if there are no sections.
+
+2002-06-17 Tom Rix <trix@redhat.com>
+
+ * elf32-d10v.c (elf_d10v_howto_table): Change R_D10V_10_PCREL_R,
+ R_D10V_10_PCREL_L and R_D10V_18_PCREL to use
+ complain_overflow_bitfield.
+
+2002-06-17 Alan Modra <amodra@bigpond.net.au>
+
+ * opncls.c (bfd_openr): Remove redundant bfd_set_error.
+ (bfd_fdopenr): Likewise.
+ (bfd_openstreamr): Likewise.
+ (bfd_openw): Likewise.
+
+ * targets.c: Sort target vecs.
+ (_bfd_target_vector): Add aix5coff64_vec, bfd_elf32_sh64_vec,
+ bfd_elf32_sh64l_vec, bfd_elf32_sh64lnbsd_vec,
+ bfd_elf32_sh64nbsd_vec, bfd_elf64_sh64_vec, bfd_elf64_sh64l_vec,
+ bfd_elf64_sh64lnbsd_vec, bfd_elf64_sh64nbsd_vec.
+ * configure.in: Sort target vecs. Add m88kmach3_vec.
+ * configure: Regenerate.
+
+2002-06-16 Hans-Peter Nilsson <hp@bitrange.com>
+
+ * elf64-mmix.c (bpo_reloc_request_sort_fn): Use member
+ bpo_reloc_no to break sort order ties, not address of items.
+
+2002-06-16 John David Anglin <dave@hiauly1.hia.nrc.ca>
+
+ * elf-hppa.h (elf_hppa_final_link): Fix formatting in comment.
+ Skip excluded sections in determing __gp value.
+ (elf_hppa_final_link_relocate): Use the symbol's address in
+ R_PARISC_FPTR64 relocations that don't need an opd entry.
+ * elf64-hppa.c (allocate_dynrel_entries): Simplify code.
+ (elf64_hppa_finalize_dynreloc): Likewise.
+ (elf64_hppa_size_dynamic_sections): Move comments and fix typo.
+ (elf64_hppa_finish_dynamic_symbol): Break up assert.
+
+2002-06-14 Sergey Grigoriev <serge@leopold.Physik.Uni-Augsburg.DE>
+
+ * pei-i386.c (COFF_SECTION_ALIGNMENT_ENTRIES): Enable 16 byte
+ alignment for .bss, .data and .text sections so that sse and sse2
+ code will work.
+ * pe-i386.c (COFF_SECTION_ALIGNMENT_ENTRIES): Likewise.
+
+2002-06013 J"orn Rennecke <joern.rennecke@superh.com>
+
+ config.bfd: Add support for sh[1234]l*-*-elf* | sh3el*-*-elf*,
+ sh[1234]*-elf*.
+
+2002-06-12 John David Anglin <dave@hiauly1.hia.nrc.ca>
+
+ * elflink.h (elf_bfd_final_link): Improve error handling for missing
+ dynamic sections.
+
+ * elf64-hppa.c (allocate_global_data_opd): We don't need an opd entry
+ for a symbol that has no output section.
+ (allocate_dynrel_entries): Correct comment.
+ (elf64_hppa_finalize_dynreloc): Likewise. Don't create an opd entry
+ unless we want one.
+ (elf64_hppa_finalize_opd): Prevent segfault if dyn_h is NULL.
+ (elf64_hppa_finalize_dlt): Likewise. Prevent segfault for symbols
+ with no section. Remove unnecessary parentheses.
+
+2002-06-11 Tom Rix <trix@redhat.com>
+
+ * coffcode.h (coff_compute_section_file_positions): Add data
+ section to AIX loader alignment check.
+
+ * coff-rs6000.c (_bfd_xcoff_mkobject): Set default text section
+ alignment to 4 bytes.
+ (_bfd_xcoff_copy_private_bfd_data): Use text and data alignment
+ power accessor macro.
+ (do_shared_object_padding): Remove invalid assertion.
+
+2002-06-10 Richard Sandiford <rsandifo@redhat.com>
+
+ * section.c (_bfd_strip_section_from_output): Set SEC_EXCLUDE
+ for removed output sections.
+
+2002-06-10 Geoffrey Keating <geoffk@redhat.com>
+
+ * merge.c (merge_strings): Use htab_create_alloc with calloc, not
+ htab_alloc.
+ * elf-strtab.c (_bfd_elf_strtab_finalize): Likewise.
+
+2002-06-08 H.J. Lu <hjl@gnu.org>
+
+ * elf.c (copy_private_bfd_data): Don't cast to bfd_size_type to
+ work around a long long bug in gcc 2.96 on mips.
+
+2002-06-08 Jason Thorpe <thorpej@wasabisystems.com>
+
+ * Makefile.am (BFD32_BACKENDS): Add vax1knetbsd.lo.
+ (BFD32_BACKENDS_CFILES): Add vax1knetbsd.c.
+ Regenerate dependency lists.
+ * Makefile.in: Regenerate.
+ * config.bfd (vax-*-netbsdelf*, vax-*-netbsdaout*): Add
+ vax1knetbsd_vec to targ_selvecs.
+ * configure.in: Add vax1knetbsd_vec.
+ * configure: Regenerate.
+ * targets.c (_bfd_target_vector): Add vax1knetbsd_vec.
+ * vax1knetbsd.c: New file.
+ * vaxnetbsd.c: Update copyright years.
+ (TARGET_PAGE_SIZE): Set to 0x1000.
+ (DEFAULT_MID): Set to M_VAX4K_NETBSD.
+
+2002-06-08 Matt Thomas <matt@3am-software.com>
+
+ * libaout.h (enum machine_type): Add M_VAX4K_NETBSD.
+
+2002-06-08 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-sh64.c (sh64_elf64_link_output_symbol_hook): Make static.
+
+2002-06-08 Alan Modra <amodra@bigpond.net.au>
+
+ * Makefile.am: Run "make dep-am".
+ * Makefile.in: Regenerate.
+
+ * armnetbsd.c: Replace CONST with const.
+ * corefile.c: Likewise.
+ * elf32-dlx.c: Likewise.
+ * elf64-mips.c: Likewise.
+ * mmo.c: Likewise.
+ * ns32knetbsd.c: Likewise.
+
+ * elf64-sparc.c (sparc64_elf_add_symbol_hook): Check the hash
+ table is elf64-sparc.
+
+2002-06-08 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * elfxx-mips.c (_bfd_mips_elf_relocate_section): Simplify code.
+ Fix RELA addends to get not shifted in the result. Don't do special
+ handling of R_MIPS_64 for NewABI.
+
+2002-06-07 Alan Modra <amodra@bigpond.net.au>
+
+ * aoutx.h (NAME(aout,slurp_symbol_table)): Use bfd_zmalloc.
+ (NAME(aout,slurp_reloc_table)): Likewise.
+ * coff-mips.c (mips_relax_section): Use bfd_zalloc.
+ * coff-rs6000.c (xcoff_write_armap_big): Use bfd_zmalloc.
+ (xcoff_write_archive_contents_big): Likewise.
+ (xcoff_generate_rtinit): Likewise.
+ (xcoff_generate_rtinit): Likewise, and check error return.
+ * coff64-rs6000.c (xcoff64_generate_rtinit): Likewise.
+ * coffgen.c (coff_section_symbol): Use bfd_zalloc.
+ (coff_get_normalized_symtab): Likewise.
+ (coff_make_empty_symbol): Likewise.
+ (bfd_coff_set_symbol_class): Likewise.
+ * cofflink.c (coff_link_add_symbols): Likewise.
+ * ecoff.c (_bfd_ecoff_make_empty_symbol): Likewise.
+ * ecofflink.c (ecoff_write_shuffle): Use bfd_zmalloc.
+ (bfd_ecoff_write_accumulated_debug): Likewise.
+ * elf64-alpha.c (get_got_entry): Use bfd_zalloc.
+ * i386linux.c (bfd_i386linux_size_dynamic_sections): Likewise.
+ * i386lynx.c (NAME(lynx,slurp_reloc_table)): Use bfd_zmalloc.
+ * ieee.c (do_with_relocs): Use bfd_zalloc.
+ * m68klinux.c (bfd_m68klinux_size_dynamic_sections): Likewise.
+ * pdp11.c (NAME(aout,slurp_symbol_table)): Use bfd_zmalloc.
+ (NAME(aout,slurp_reloc_table)): Likewise.
+ (NAME(aout,squirt_out_relocs)): Don't memset when zalloc'd.
+ * reloc16.c (bfd_coff_reloc16_relax_section): Use bfd_zmalloc.
+ * som.c (som_build_and_write_symbol_table): Likewise.
+ (som_slurp_string_table): Likewise.
+ (som_slurp_symbol_table): Likewise.
+ (som_bfd_ar_write_symbol_stuff): Likewise.
+ * sparclinux.c (bfd_sparclinux_size_dynamic_sections): Use bfd_zalloc.
+ * sunos.c (bfd_sunos_size_dynamic_sections): Likewise.
+ * tekhex.c (find_chunk): Likewise. Get rid of unused "sname".
+ * vms-gsd.c (_bfd_vms_slurp_gsd): Use bfd_zmalloc.
+ * xcofflink.c (xcoff_link_add_symbols): Use bfd_zalloc/bfd_zmalloc.
+
+2002-06-07 Alan Modra <amodra@bigpond.net.au>
+
+ * elf-bfd.h (struct bfd_elf_section_data <group_name>): Replace with
+ "group" union.
+ (elf_group_name): Update.
+ (elf_group_id): Define.
+ (bfd_elf_set_group_contents): Declare.
+ * elf.c (elf_fake_sections): Qualify use of elf_group_name.
+ (set_group_contents): Rename to bfd_elf_set_group_contents. Remove
+ ATTRIBUTE_UNUSED from failedptrarg. If elf_group_id is set, use
+ that sym for the signature.
+ (_bfd_elf_compute_section_file_positions): Don't call
+ set_group_contents for "ld -r" case.
+ (swap_out_syms): Use bfd_zalloc.
+ * elflink.h (elf_link_add_archive_symbols): Likewise.
+ (NAME(bfd_elf,size_dynamic_sections)): Likewise.
+ (elf_bfd_final_link): Call bfd_elf_set_group_contents.
+
+2002-06-07 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (ppc64_elf_relocate_section): Allow unresolved
+ relocs in opd for non-shared too.
+
+2002-06-06 Jeffrey Law <law@redhat.com>
+
+ * elf32-h8300.c (elf32_h8_relax_section): Ignore uninteresting
+ relocations.
+
+2002-06-06 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * merge.c: Include libiberty.h.
+ * elf-strtab.c: Include libiberty.h.
+
+2002-06-06 Elias Athanasopoulos <eathan@otenet.gr>
+
+ * peXXigen.c (pe_print_idata): Remove unused variable.
+
+2002-06-06 David Heine <dlheine@tensilica.com>
+
+ * elf.c (assign_file_positions_for_segments): Remove unallocated
+ sections from the section to segment mapping for PT_LOAD segments.
+ Update comment about empty loadable segments.
+
+2002-06-06 Richard Sandiford <rsandifo@redhat.com>
+
+ * stabs.c (_bfd_link_section_stabs): Check that the symbol offset
+ is within the .stabstr section.
+
+2002-06-06 Alan Modra <amodra@bigpond.net.au>
+
+ * elf-bfd.h (struct elf_size_info <swap_symbol_in>): Function args
+ are "const PTR", not "const PTR *".
+ (bfd_elf32_swap_symbol_in): Likewise.
+ (bfd_elf64_swap_symbol_in): Likewise.
+ * elfcode.h (elf_swap_symbol_in): Change input args to const PTR.
+ (elf_slurp_symbol_table): Adjust call to elf_swap_symbol_in.
+ * elflink.h (elf_link_is_defined_archive_symbol): Likewise.
+ (elf_link_add_object_symbols): Likewise.
+ (elf_link_record_local_dynamic_symbol): Likewise.
+ (elf_link_input_bfd): Likewise.
+ (elf_gc_mark): Likewise.
+ (elf_reloc_symbol_deleted_p): Likewise.
+ * elf-m10200.c (mn10200_elf_relax_section): Likewise.
+ (mn10200_elf_relax_delete_bytes): Likewise.
+ (mn10200_elf_symbol_address_p): Likewise.
+ (mn10200_elf_get_relocated_section_contents): Likewise.
+ * elf-m10300.c (mn10300_elf_relax_section): Likewise.
+ (mn10300_elf_relax_section): Likewise.
+ (mn10300_elf_relax_delete_bytes): Likewise.
+ (mn10300_elf_symbol_address_p): Likewise.
+ (mn10300_elf_get_relocated_section_contents): Likewise.
+ * elf32-h8300.c (elf32_h8_relax_section): Likewise.
+ (elf32_h8_relax_delete_bytes): Likewise.
+ (elf32_h8_symbol_address_p): Likewise.
+ (elf32_h8_get_relocated_section_contents): Likewise.
+ * elf32-hppa.c (get_local_syms): Likewise.
+ * elf32-m68k.c (bfd_m68k_elf32_create_embedded_relocs): Likewise.
+ * elf32-mips.c (bfd_mips_elf32_create_embedded_relocs): Likewise.
+ * elf32-sh.c (sh_elf_relax_section): Likewise.
+ (sh_elf_relax_delete_bytes): Likewise.
+ (sh_elf_get_relocated_section_contents): Likewise.
+ * elf32-xstormy16.c (xstormy16_elf_relax_section): Likewise.
+ * elf64-alpha.c (elf64_alpha_relax_section): Likewise.
+ * elf64-hppa.c (elf64_hppa_check_relocs): Likewise.
+ * elf64-mmix.c (mmix_elf_relax_section): Likewise.
+ * elf64-ppc.c (get_local_syms): Likewise.
+ * elf64-sh64.c (sh_elf64_get_relocated_section_contents): Likewise.
+ * elfxx-ia64.c (elfNN_ia64_relax_section): Likewise.
+
+2002-06-05 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * config.bfd (sh64l*-*-elf*, shl*-*-elf*): New configurations.
+
+2002-06-05 Alan Modra <amodra@bigpond.net.au>
+
+ * elf.c (group_signature): Swap in the whole symbol, and handle
+ extracting section symbol names.
+ (setup_group): Add comment.
+ (set_group_contents): When called from objcopy or ld, arrange for
+ section contents to be written. Write group member output section
+ indices to allow objcopy to reorganize sections.
+ (_bfd_elf_copy_private_section_data): Copy group info.
+
+ * elf-bfd.h (struct elf_size_info): Add swap_symbol_in field.
+ (bfd_elf32_swap_symbol_in): Update prototype.
+ (bfd_elf64_swap_symbol_in): Likewise.
+ * elfcode.h (elf_swap_symbol_in): Change input args to const PTR *.
+ (elf_slurp_symbol_table): Adjust call to elf_swap_symbol_in.
+ * elflink.h (elf_link_is_defined_archive_symbol): Likewise.
+ (elf_link_add_object_symbols): Likewise.
+ (elf_link_record_local_dynamic_symbol): Likewise.
+ (elf_link_input_bfd): Likewise.
+ (elf_gc_mark): Likewise.
+ (elf_reloc_symbol_deleted_p): Likewise.
+ * elf-m10200.c (mn10200_elf_relax_section): Likewise.
+ (mn10200_elf_relax_delete_bytes): Likewise.
+ (mn10200_elf_symbol_address_p): Likewise.
+ (mn10200_elf_get_relocated_section_contents): Likewise.
+ * elf-m10300.c (mn10300_elf_relax_section): Likewise.
+ (mn10300_elf_relax_section): Likewise.
+ (mn10300_elf_relax_delete_bytes): Likewise.
+ (mn10300_elf_symbol_address_p): Likewise.
+ (mn10300_elf_get_relocated_section_contents): Likewise.
+ * elf32-h8300.c (elf32_h8_relax_section): Likewise.
+ (elf32_h8_relax_delete_bytes): Likewise.
+ (elf32_h8_symbol_address_p): Likewise.
+ (elf32_h8_get_relocated_section_contents): Likewise.
+ * elf32-hppa.c (get_local_syms): Likewise.
+ * elf32-m68k.c (bfd_m68k_elf32_create_embedded_relocs): Likewise.
+ * elf32-mips.c (bfd_mips_elf32_create_embedded_relocs): Likewise.
+ * elf32-sh.c (sh_elf_relax_section): Likewise.
+ (sh_elf_relax_delete_bytes): Likewise.
+ (sh_elf_get_relocated_section_contents): Likewise.
+ * elf32-xstormy16.c (xstormy16_elf_relax_section): Likewise.
+ * elf64-alpha.c (elf64_alpha_relax_section): Likewise.
+ * elf64-hppa.c (elf64_hppa_check_relocs): Likewise.
+ * elf64-mmix.c (mmix_elf_relax_section): Likewise.
+ * elf64-ppc.c (get_local_syms): Likewise.
+ * elf64-sh64.c (sh_elf64_get_relocated_section_contents): Likewise.
+ * elfxx-ia64.c (elfNN_ia64_relax_section): Likewise.
+ * elfcode.h (NAME(_bfd_elf,size_info)): Update initialiser.
+ * elf64-alpha.c (alpha_elf_size_info): Likewise.
+ * elf64-hppa.c (hppa64_elf_size_info): Likewise.
+ * elf64-mips.c (mips_elf64_size_info): Likewise.
+ * elf64-s390.c (s390_elf64_size_info): Likewise.
+ * elf64-sparc.c (sparc64_elf_size_info): Likewise.
+
+2002-06-05 Maciej W. Rozycki <macro@ds2.pg.gda.pl>
+
+ * elf32-mips.c (elf32_mips_ignore_discarded_relocs): Move to...
+ elfxx-mips.c (_bfd_mips_elf_ignore_discarded_relocs): ... here.
+ elf64-mips.c (elf_backend_ignore_discarded_relocs): Use
+ _bfd_mips_elf_ignore_discarded_relocs.
+ elfxx-mips.h (_bfd_mips_elf_ignore_discarded_relocs): Declare.
+
+2002-06-05 H.J. Lu <hjl@gnu.org>
+
+ * elfxx-mips.c (mips_elf_calculate_relocation): Call
+ _bfd_elf_rel_local_sym for STT_SECTION relocations against
+ the SEC_MERGE section.
+
+2002-06-05 Alan Modra <amodra@bigpond.net.au>
+
+ * coff-alpha.c: Update copyright date.
+ * coff-mips.c: Likewise.
+ * xcoff-target.h: Likewise.
+
+ * bfd-in.h: Remove "taken from the source" comment.
+ * libbfd-in.h: Likewise.
+ * libcoff-in.h: Likewise.
+ * bfd-in2.h: Regenerate.
+ * libbfd.h: Regenerate.
+ * libcoff.h: Regenerate.
+
+ * elf.c (bfd_elf_discard_group): Return true.
+ * elf-bfd.h (bfd_elf_discard_group): Declare.
+ * bfd-in.h (bfd_elf_discard_group): Don't declare here.
+ * section.c (bfd_discard_group): Rename to bfd_generic_discard_group.
+ * bfd.c (bfd_discard_group): Define.
+ * targets.c (struct bfd_target): Add _bfd_discard_group.
+ (BFD_JUMP_TABLE_LINK): Here too.
+ * libbfd-in.h (_bfd_nolink_bfd_discard_group): Define.
+ * aout-adobe.c (aout_32_bfd_discard_group): Define.
+ * aout-target.h (MY_bfd_discard_group): Define.
+ * aout-tic30.c (MY_bfd_discard_group): Define.
+ * binary.c (binary_bfd_discard_group): Define.
+ * bout.c (b_out_bfd_discard_group): Define.
+ * coff-alpha.c (_bfd_ecoff_bfd_discard_group): Define.
+ * coffcode.h (coff_bfd_discard_group): Define.
+ * coff-mips.c (_bfd_ecoff_bfd_discard_group): Define.
+ * elfxx-target.h (bfd_elfNN_bfd_discard_group): Define.
+ * i386msdos.c (msdos_bfd_discard_group): Define.
+ * i386os9k.c (os9k_bfd_discard_group): Define.
+ * ieee.c (ieee_bfd_discard_group): Define.
+ * ihex.c (ihex_bfd_discard_group): Define.
+ * mmo.c (mmo_bfd_discard_group): Define.
+ * nlm-target.h (nlm_bfd_discard_group): Define.
+ * oasys.c (oasys_bfd_discard_group): Define.
+ * ppcboot.c (ppcboot_bfd_discard_group): Define.
+ * som.c (som_bfd_discard_group): Define.
+ * srec.c (srec_bfd_discard_group): Define.
+ * tekhex.c (tekhex_bfd_discard_group): Define.
+ * versados.c (versados_bfd_discard_group): Define.
+ * vms.c (vms_bfd_discard_group): Define.
+ * xcoff-target.h (_bfd_xcoff_bfd_discard_group): Define.
+ * coff64-rs6000.c (rs6000coff64_vec): Update initialiser.
+ (aix5coff64_vec): Likewise.
+ * coff-rs6000.c (rs6000coff_vec, pmac_xcoff_vec): Likewise.
+
+2002-06-04 Jason Thorpe <thorpej@wasabisystems.com>
+
+ * Makefile.am (BFD32_BACKENDS): Add elf32-sh64-com.lo.
+ (BFD32_BACKENDS_CFILES): Add elf32-sh64-com.c.
+ (elf32-sh64-com.lo): New dependency list.
+ * Makefile.in: Regenerate.
+ * configure.in (bfd_elf32_sh64_vec, bfd_elf32_sh64l_vec)
+ (bfd_elf32_sh64nbsd_vec, bfd_elf32_sh64lnbsd_vec): Add
+ elf32-sh64-com.lo.
+ * configure: Regenerate.
+ * elf32-sh64.c (sh64_address_in_cranges)
+ (sh64_get_contents_type, sh64_address_is_shmedia): Move to...
+ (crange_qsort_cmpb, crange_qsort_cmpl, crange_bsearch_cmpb):
+ (crange_bsearch_cmpl): Prepend _bfd_sh64_ to name and move to...
+ * elf32-sh64-com.c: ...here. New file.
+
+2002-06-04 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-openrisc.c (openrisc_elf_gc_mark_hook): Remove
+ ATTRIBUTE_UNUSED on used params.
+ * elf32-vax.c (elf_vax_gc_mark_hook): Remove unnecessary checks
+ before calling bfd_section_from_elf_index on local syms.
+ * elf64-sh64.c (sh_elf64_gc_mark_hook): Likewise.
+
+2002-06-04 Jason Thorpe <thorpej@wasabisystems.com>
+
+ * Makefile.am (BFD32_BACKENDS): Add elf32-sh64-nbsd.lo.
+ (BFD32_BACKENDS_CFILES): Add elf32-sh64-nbsd.c.
+ (BFD64_BACKENDS): Add elf64-sh64-nbsd.lo.
+ (BFD64_BACKENDS_CFILES): Add elf64-sh64-nbsd.c.
+ (elf32-sh64-nbsd.lo, elf64-sh64-nbsd.lo): New rules.
+ * Makefile.in: Regenerate.
+ * config.bfd (sh5le-*-netbsd*, sh5-*-netbsd*, sh64le-*-netbsd*)
+ (sh64-*-netbsd*): New targets.
+ * configure.in: Add bfd_elf32_sh64nbsd_vec, bfd_elf32_sh64lnbsd_vec,
+ bfd_elf64_sh64nbsd_vec, and bfd_elf64_sh64lnbsd_vec.
+ * configure: Regenerate.
+ * elf32-sh64-nbsd.c: New file.
+ * elf64-sh64-nbsd.c: New file.
+ * targets.c: Add extern decls for bfd_elf32_sh64nbsd_vec,
+ bfd_elf32_sh64lnbsd_vec, bfd_elf64_sh64nbsd_vec, and
+ bfd_elf64_sh64lnbsd_vec.
+
+2002-06-04 Alan Modra <amodra@bigpond.net.au>
+
+ * elf.c (setup_group): Set SEC_LINK_ONCE on GRP_COMDAT groups.
+ (bfd_section_from_shdr): Likewise. Set section name of group
+ sections from signature.
+ (group_signature): Split out from setup_group. Ensure symbol table
+ is available.
+ (bfd_elf_discard_group): New function.
+ (_bfd_elf_make_section_from_shdr): Don't set SEC_LINK_ONCE on
+ .gnu.linkonce* sections if they are members of a group.
+ (set_group_contents): Set GRP_COMDAT flag.
+ * section.c (bfd_discard_group): New function.
+ * bfd-in.h (bfd_elf_discard_group): Declare.
+ * bfd-in2.h: Regenerate.
+ * elf-bfd.h (struct bfd_elf_section_data): Add linkonce_p field.
+ (elf_linkonce_p): Define.
+
+2002-06-04 Alan Modra <amodra@bigpond.net.au>
+
+ * elf.c (bfd_section_from_shdr): Make "name" const.
+ * elf-bfd.h (elf_backend_section_from_shdr): Likewise.
+ * elf32-i370.c (i370_elf_section_from_shdr): Likewise.
+ * elf32-ppc.c (ppc_elf_section_from_shdr): Likewise.
+ * elf32-sh64.c (sh64_backend_section_from_shdr): Likewise.
+ * elf32-v850.c (v850_elf_section_from_shdr): Likewise.
+ * elf64-alpha.c (elf64_alpha_section_from_shdr): Likewise.
+ * elf64-hppa.c (elf64_hppa_section_from_shdr): Likewise.
+ * elf64-ppc.c (ppc64_elf_section_from_shdr): Likewise.
+ * elfxx-ia64.c (elfNN_ia64_section_from_shdr): Likewise.
+ * elfxx-mips.c (_bfd_mips_elf_section_from_shdr): Likewise.
+ * elfxx-mips.h (_bfd_mips_elf_section_from_shdr): Likewise.
+
+2002-06-03 Maciej W. Rozycki <macro@ds2.pg.gda.pl>
+
+ * elfxx-mips.c (ABI_64_P): Use backend's data to determine the
+ ABI.
+
+2002-06-02 Kazu Hirata <kazu@cs.umass.edu>
+
+ * elf32-arc.c: Fix formatting.
+ * elf32-arm.h: Likewise.
+ * elf32-cris.c: Likewise.
+ * elf32-dlx.c: Likewise.
+ * elf32-hppa.c: Likewise.
+ * elf32-i386.c: Likewise.
+ * elf32-i386qnx.c: Likewise.
+ * elf32-or32.c: Likewise.
+ * elf32-s390.c: Likewise.
+ * elf32-sh64.c: Likewise.
+ * elf32-vax.c: Likewise.
+ * elf32-xstormy16.c: Likewise.
+ * elf64-alpha.c: Likewise.
+ * elf64-mmix.c: Likewise.
+ * elf64-ppc.c: Likewise.
+ * elf64-s390.c: Likewise.
+ * elf64-sh64.c: Likewise.
+ * elf64-x86-64.c: Likewise.
+
+2002-06-02 Richard Henderson <rth@redhat.com>
+
+ * elf64-alpha.c (elf64_alpha_relocate_section): Don't dereference
+ null when there are no got entries for a symbol.
+ (elf64_alpha_relax_find_tls_segment): Rearrange to avoid
+ uninitialized variable warning.
+
+2002-06-01 Richard Henderson <rth@redhat.com>
+
+ * elf64-alpha.c (elf64_alpha_relax_with_lituse): Don't test for
+ undefined symbols here.
+ (elf64_alpha_relax_section): Do it here. Also test for not
+ defined in the current module.
+ (elf64_alpha_relocate_section_r): Split out of ...
+ (elf64_alpha_relocate_section): ... here. Don't dereference
+ NULL when looking up local got entries.
+
+2002-06-01 Richard Henderson <rth@redhat.com>
+
+ * elf64-alpha.c (elf64_alpha_relax_with_lituse): Reject undefined
+ symbols from JSR relaxation.
+ (elf64_alpha_size_plt_section_1): New.
+ (elf64_alpha_calc_dynrel_sizes): Split out .rela.got bits ...
+ (elf64_alpha_size_rela_got_1): ... here.
+ (elf64_alpha_size_dynamic_sections): Split out .rela.got bits ...
+ (elf64_alpha_size_rela_got_section): ... here.
+ (elf64_alpha_size_plt_section): New.
+ (elf64_alpha_relax_section): Call them.
+ (elf64_alpha_size_got_sections): Remove output_bfd arg.
+ (elf64_alpha_finish_dynamic_symbol): Check gotent use_count.
+
+2002-06-01 Richard Henderson <rth@redhat.com>
+
+ * elf64-alpha.c (alpha_get_dtprel_base, alpha_get_tprel_base): New.
+ (elf64_alpha_relocate_section): Use them. Reject LE TLS relocs
+ in shared libraries. Fix DTPRELHI and TPRELHI value.
+ (INSN_ADDQ, INSN_RDUNIQ): New.
+ (struct alpha_relax_info): Add symtab_hdr, tls_segment, first_gotent.
+ (elf64_alpha_relax_with_lituse): Return boolean. Remove irelend
+ argument. Reject dynamic symbols. Use LITUSE symbolic constants.
+ (elf64_alpha_relax_got_load): Rename from relax_without_lituse.
+ Handle GOTDTPREL and GOTTPREL relocations.
+ (elf64_alpha_relax_gprelhilo): New.
+ (elf64_alpha_relax_tls_get_addr): New.
+ (elf64_alpha_relax_find_tls_segment): New.
+ (elf64_alpha_relax_section): Handle TLS relocations.
+ (ALPHA_ELF_LINK_HASH_TLS_IE): New.
+ (elf64_alpha_check_relocs): Set it.
+
+2002-06-01 Richard Henderson <rth@redhat.com>
+
+ * elf64-alpha.c (elf64_alpha_relax_section): Don't store computed gp.
+
+ * elf64-alpha.c (elf64_alpha_check_relocs): Fix typo on maybe_dynamic
+ check; don't suppress dynamic relocs for non-allocated sections.
+
+ * elf64-alpha.c: Remove dead code.
+
+2002-05-31 Alan Modra <amodra@bigpond.net.au>
+
+ * bfd-in2.h: Regenerate.
+ * libbfd.h: Regenerate.
+ * po/SRC-POTFILES.in: Regenerate.
+
+ * elf64-ppc.c (ppc64_elf_size_dynamic_sections): Don't allocate
+ space for bss .plt.
+
+2002-05-31 Graeme Peterson <gp@qnx.com>
+
+ * Makefile.am (BFD32_BACKENDS): Add elf32-i386qnx.lo.
+ (BFD32_BACKENDS_CFILES): Add elf32-i386qnx.c.
+ Run "make dep-am".
+ * Makefile.in: Regenerate.
+ * config.bfd: Add i[3456]86-*-nto-qnx* support.
+ * configure.in: Add bfd_elf32_i386qnx_vec support.
+ * configure: Regenerate.
+ * elf-bfd.h (struct elf_backend_data): Add set_nonloadable_filepos,
+ is_contained_by_filepos, and copy_private_bfd_data_p.
+ * elf.c (assign_file_positions_for_segments): Call backend
+ set_nonloadable_filepos. Fix non-K&R call to _bfd_error_handler.
+ (IS_CONTAINED_BY_FILEPOS): Define.
+ (INCLUDE_SECTION_IN_SEGMENT): Also test IS_CONTAINED_BY_FILEPOS.
+ (copy_private_bfd_data): Use IS_CONTAINED_BY_FILEPOS. Typo fix.
+ Fix non-K&R call to _bfd_error_handler.
+ (_bfd_elf_copy_private_section_data): Use backend
+ copy_private_bfd_data_p.
+ * elf32-i386.c: Don't include elfxx-target.h when
+ ELF32_I386_C_INCLUDED is defined.
+ * elf32-i386qnx.c: New QNX elf backend file.
+ * elfxx-target.h: Add elf_backend_set_nonloadable_filepos,
+ elf_backend_is_contained_by_filepos, and
+ elf_backend_do_copy_private_bfd_data.
+ * targets.c: Add bfd_target bfd_elf32_i386qnx_vec.
+
+2002-05-31 Alan Modra <amodra@bigpond.net.au>
+
+ * elfarm-oabi.c (bfd_elf32_arm_add_glue_sections_to_bfd): Define.
+ Move other similar defines to start of file.
+
+2002-05-30 Tom Rix <trix@redhat.com>
+
+ * coff-rs6000.c (xcoff_rtype2howto): Handle 16 bit R_RBA.
+ * coff64-rs6000.c (xcoff64_rtype2howto): Same.
+
+2002-05-30 Richard Henderson <rth@redhat.com>
+
+ * elf64-alpha.c (ALPHA_ELF_LINK_HASH_LU_TLSGD,
+ ALPHA_ELF_LINK_HASH_LU_TLSLDM, ALPHA_ELF_LINK_HASH_LU_FUNC): New.
+ (ALPHA_ELF_GOT_ENTRY_RELOCS_DONE): Remove.
+ (ALPHA_ELF_GOT_ENTRY_RELOCS_XLATED): Remove.
+ (struct alpha_elf_got_entry): Add reloc_type, reloc_done, reloc_xlated.
+ (struct alpha_elf_obj_tdata): Rename total_got_entries and
+ n_local_got_entries to total_got_size and local_got_size.
+ (elf64_alpha_howto, elf64_alpha_reloc_map): Update for TLS relocs.
+ (alpha_got_entry_size): New.
+ (elf64_alpha_relax_with_lituse): Use it.
+ (elf64_alpha_relax_without_lituse): Likewise.
+ (MAX_GOT_SIZE): Rename from MAX_GOT_ENTRIES.
+ (get_got_entry): New.
+ (elf64_alpha_check_relocs): Handle TLS relocs. Reorganize.
+ (elf64_alpha_adjust_dynamic_symbol): Test LU_FUNC as a mask.
+ (elf64_alpha_merge_ind_symbols): Check gotent->reloc_type.
+ (elf64_alpha_can_merge_gots, elf64_alpha_merge_gots): Likewise.
+ (elf64_alpha_calc_got_offsets_for_symbol): Use alpha_got_entry_size.
+ (elf64_alpha_calc_got_offsets): Likewise.
+ (alpha_dynamic_entries_for_reloc): New.
+ (elf64_alpha_calc_dynrel_sizes): Use it.
+ (elf64_alpha_size_dynamic_sections): Likewise.
+ (elf64_alpha_relocate_section): Handle TLS relocations.
+ * reloc.c: Add Alpha TLS relocations.
+ * bfd-in2.h, libbfd.h: Rebuild.
+
+2002-05-29 Ralf Habacker <ralf.habacker@freenet.de>
+
+ * peXXigen.c (pe_print_idata): Remove double printed
+ import table lines; add Bound-To comment.
+
+2002-05-29 Matt Thomas <matt@3am-software.com>
+
+ * Makefile.am (BFD32_BACKENDS): Add elf32-vax.lo.
+ (BFD32_BACKENDS_CFILES): Add elf32-vax.c.
+ (elf32-vax.lo): New rule.
+ * Makefile.in: Regenerate.
+ * configure.in (bfd_elf32_vax_vec)
+ (vaxnetbsd_vec): New vectors.
+ * configure: Regenerate.
+ * config.bfd (vax-*-netbsdelf*)
+ (vax-*-netbsdaout*)
+ (vax-*-netbsd*): New targets.
+ * elf32-vax.c: New file.
+ * reloc.c: Add VAX relocations.
+ * bfd-in2.h: Regenerate.
+ * targets.c (_bfd_target_vector): Add bfd_elf32_vax_vec.
+
+2002-05-29 Jason Thorpe <thorpej@wasabisystems.com>
+
+ * config.bfd (arm-*-netbsd*): Add bfd_elf32_littlearm_vec
+ and bfd_elf32_bigarm_vec to targ_selvecs.
+
+2002-05-29 Ralf Habacker <ralf.habacker@freenet.de>
+
+ * peXXigen.c (pe_print_idata): Fix seg faults on printing import tables
+ with auto-imported symbols.
+
+2002-05-29 Adam Nemet <anemet@lnxw.com>
+
+ * elf32-arm.h (bfd_elf32_arm_get_bfd_for_interworking): Don't add glue
+ sections only record bfd.
+ (bfd_elf32_arm_add_glue_sections_to_bfd): New function.
+ * bfd-in.h (bfd_elf32_arm_add_glue_sections_to_bfd): Declare it.
+ * bfd-in2.h: Regenerate.
+
+2002-05-28 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * syms.c (_bfd_stab_section_find_nearest_line): Move
+ declaration and initialisation of saw_line and saw_func out of
+ for loop.
+
+2002-05-29 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (ppc64_elf_get_symbol_info): New function.
+ (bfd_elf64_get_symbol_info): Define.
+ * elfxx-target.h (bfd_elfNN_get_symbol_info): Only define if undef.
+
+2002-05-29 Andrey Volkov <avolkov@transas.com>
+
+ * cpu-h8300.c: Make default h8300 machine first in machine list.
+
+2002-05-28 Kuang Hwa Lin <kuang@sbcglobal.net>
+
+ * config.bfd: Added DLX configuraton.
+ * Makefile.am: Added DLX configuraton.
+ * configure.in: Added DLX configuraton.
+ * archures.c: Add DLX architecture.
+ * reloc.c: Add DLX relocs.
+ * targets.c: Added DLX target vector.
+ * configure: Regenerate.
+ * Makefile.in: Regenreate.
+ * bfd-in2.h: Regenreate.
+ * elf32-dlx.c: New file: Support DLX target.
+ * cpu-dlx.c: New file: Support DLX target.
+
+2002-05-25 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-m68k.c (elf32_m68k_print_private_bfd_data): Formatting.
+
+ * elf64-ppc.c (ppc64_elf_copy_indirect_symbol): Revert last change.
+ (ppc64_elf_check_relocs): Don't set up function descriptor symbol
+ strings to point inside function code sym string.
+ (func_desc_adjust): Likewise.
+ (ppc64_elf_hide_symbol): Rewrite code to look up function code sym.
+
+2002-05-24 Michal Ludvig <mludvig@suse.cz>
+
+ * elf64-x86-64.c (elf64_x86_64_grok_prstatus): Added.
+ (elf64_x86_64_grok_psinfo): Added.
+
+2002-05-24 TAMURA Kent <kent@netbsd.org>
+
+ * config.bfd: Add a target for i386-netbsdpe.
+
+2002-05-24 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (ppc64_elf_copy_indirect_symbol): Don't copy is_func
+ and is_func_descriptor.
+ (func_desc_adjust): Hide function code sym in shared libs unless
+ there is a matching exported function descriptor sym.
+
+2002-05-23 Jakub Jelinek <jakub@redhat.com>
+
+ * elf.c (_bfd_elf_make_section_from_shdr): Set SEC_THREAD_LOCAL
+ for symbols from SHF_TLS section.
+ (_bfd_elf_print_private_bfd_data): Add PT_TLS.
+ (elf_fake_sections): Set SHF_TLS for SEC_THREAD_LOCAL sections.
+ (map_sections_to_segments): Build PT_TLS segment if necessary.
+ (assign_file_positions_for_segments): Likewise.
+ (get_program_header_size): Account for PT_TLS segment.
+ (swap_out_syms): Set type of BSF_THREAD_LOCAL symbols and symbols from
+ SEC_THREAD_LOCAL sections to STT_TLS.
+ * reloc.c: Add 386 and IA-64 TLS relocs.
+ * section.c (SEC_THREAD_LOCAL): Define.
+ (SEC_CONSTRUCTOR_TEXT, SEC_CONSTRUCTOR_DATA, SEC_CONSTRUCTOR_BSS):
+ Remove.
+ * elflink.h (elf_link_add_object_symbols): Support .tcommon.
+ (size_dynamic_sections): If DF_STATIC_TLS, set DF_FLAGS
+ unconditionally.
+ (struct elf_final_link_info): Add first_tls_sec.
+ (elf_bfd_final_link): Set first_tls_sec.
+ Compute elf_hash_table (info)->tls_segment.
+ (elf_link_output_extsym): Handle STT_TLS symbols.
+ (elf_link_input_bfd): Likewise.
+ * syms.c (BSF_THREAD_LOCAL): Define.
+ * bfd-in2.h: Rebuilt.
+ * libbfd.h: Rebuilt.
+ * elf32-i386.c (elf_i386_tls_transition, dtpoff_base, tpoff,
+ elf_i386_mkobject, elf_i386_object_p): New functions.
+ (elf_howto_table): Add TLS relocs.
+ (elf_i386_reloc_type_lookup): Support TLS relocs.
+ (elf_i386_info_to_howto_rel): Likewise.
+ (struct elf_i386_link_hash_entry): Add tls_type.
+ (struct elf_i386_obj_tdata): New.
+ (elf_i386_hash_entry, elf_i386_tdata, elf_i386_local_got_tls_type):
+ New macros.
+ (struct elf_i386_link_hash_table): Add tls_ldm_got.
+ (link_hash_newfunc): Clear tls_type.
+ (elf_i386_check_relocs): Support TLS relocs.
+ (elf_i386_gc_sweep_hook): Likewise.
+ (allocate_dynrelocs): Likewise.
+ (elf_i386_size_dynamic_sections): Likewise.
+ (elf_i386_relocate_section): Likewise.
+ (elf_i386_finish_dynamic_symbol): Likewise.
+ (bfd_elf32_mkobject, elf_backend_object_p): Define.
+ * elfxx-ia64.c (struct elfNN_ia64_dyn_sym_info): Add tprel_offset,
+ dtpmod_offset, dtprel_offset, tprel_done, dtpmod_done, dtprel_done,
+ want_tprel, want_dtpmod, want_dtprel.
+ (elfNN_ia64_tprel_base, elfNN_ia64_dtprel_base): New functions.
+ (ia64_howto_table): Add TLS relocs, rename R_IA64_LTOFF_TP22 to
+ R_IA64_LTOFF_TPREL22.
+ (elf_code_to_howto_index): Add TLS relocs.
+ (elfNN_ia64_check_relocs): Support TLS relocs.
+ (allocate_global_data_got): Account for TLS .got data.
+ (allocate_dynrel_entries): Account for TLS dynamic relocations.
+ (elfNN_ia64_install_value): Supprt TLS relocs.
+ (set_got_entry): Support TLS relocs.
+ (elfNN_ia64_relocate_section): Likewise.
+
+2002-05-23 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * elf32-arm.h (elf32_arm_final_link_relocate): For the Thumb
+ BLX reloc round the relocation up rather than down.
+ * coff-arm.c (coff_arm_relocate_section): Likewise.
+
+2002-05-21 H.J. Lu (hjl@gnu.org)
+
+ * linker.c (_bfd_generic_link_add_one_symbol): Allow multiple
+ definition.
+
+2002-05-22 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (ppc64_elf_size_stubs): Don't strip .branch_lt.
+ (ppc64_elf_relocate_section): Handle unresolved relocs in opd.
+
+2002-05-22 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (ppc64_elf_relocate_section): Return false for
+ unresolved relocs.
+ (ppc64_elf_size_dynamic_sections): Check for splt NULL.
+
+2002-05-21 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * bfd.c (bfd_get_arch_size): Remove bfd_set_error call for
+ non-ELF targets.
+
+2002-05-21 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * elf-bfd.h (elf_backend_emit_relocs): Change prototype to return
+ an error value.
+ * elflink.h (elf_link_output_relocs): Likewise. Improve error message.
+ return with false on error.
+ (elf_link_input_bfd): Check reloc_emitter return value.
+
+2002-05-21 Jason Thorpe <thorpej@wasabisystems.com>
+
+ * config.bfd (armeb-*-netbsdelf*): New target.
+
+2002-05-20 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (ppc_build_one_stub): Point undefined function syms
+ at the plt call stub.
+
+2002-05-19 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * cpu-mips.c (mips_compatible): Don't try to check machine
+ compatibility.
+
+2002-05-18 Tom Rix <trix@redhat.com>
+
+ * coff64-rs6000.c (_bfd_xcoff64_swap_aux_out): Fix C_FILE auxent.
+
+2002-05-17 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (ppc64_elf_info_to_howto): Formatting.
+ (ppc64_elf_relocate_section): Don't warn about reloc overflow when
+ we've already warned about an undefined symbol. Report more
+ detail on reloc errors.
+
+2002-05-17 Alan Modra <amodra@bigpond.net.au>
+
+ * acinclude.m4 (AM_INSTALL_LIBBFD): New.
+ * configure.in: Invoke AM_INSTALL_LIBBFD.
+ * Makefile.am (install-data-local): Revert 2002-05-13. Move to..
+ (install_libbfd): .. New target.
+ (uninstall_libbfd): Likewise.
+ (install-bfdlibLTLIBRARIES): Likewise.
+ (uninstall-bfdlibLTLIBRARIES): Likewise.
+ (bfdlibdir): New.
+ (bfdincludedir): New.
+ (lib_LTLIBRARIES): Rename to bfdlib_LTLIBRARIES.
+ * aclocal.m4: Regenerate.
+ * configure: Regenerate.
+ * Makefile.in: Regenerate.
+
+2002-05-17 Stuart Balfour <sbalfour@cisco.com>
+
+ * hash.c (bfd_hash_lookup): Remove computation of len from inside
+ hash loop.
+
+2002-05-16 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * config.bfd: Add targets for sh64-linux (little endian and
+ big endian).
+
+2002-05-15 Laurent Pinchart <laurent.pinchart@skynet.be>
+
+ * peXXigen.c (pe_print_idata): Do not assume that the first thunk
+ is located in the same section as the import table. Instead
+ check, and if necessary load the section containing the thunk.
+
+2002-05-15 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * aix5ppc-core.c (xcoff64_core_p): Replace bfd_read with
+ bfd_bread.
+ (xcoff64_core_file_matches_executable_p): Replace bfd_read
+ with bfd_bread.
+
+2002-05-15 Alan Modra <amodra@bigpond.net.au>
+
+ * aix5ppc-core.c: Warning fixes.
+ * aout-adobe.c (aout_32_bfd_link_just_syms): Define.
+ * aout-target.h (MY_bfd_link_just_syms): Define.
+ * aout-tic30.c (MY_bfd_link_just_syms): Define.
+ * bfd.c (bfd_link_just_syms): Define.
+ * binary.c (binary_bfd_link_just_syms): Define.
+ * bout.c (b_out_bfd_link_just_syms): Define.
+ * coff-rs6000.c (rs6000coff_vec, pmac_xcoff_vec): Update initializer.
+ * coff64-rs6000.c (rs6000coff64_vec, aix5coff64_vec): Likewise.
+ * coffcode.h (coff_bfd_link_just_syms): Define.
+ * elf-bfd.h (enum elf_link_info_type): Add ELF_INFO_TYPE_JUST_SYMS.
+ (elf_discarded_section): Check for ELF_INFO_TYPE_JUST_SYMS.
+ (_bfd_elf_link_just_syms): Declare.
+ * elf.c (_bfd_elf_link_just_syms): New function.
+ * elf-eh-frame.c (_bfd_elf_maybe_strip_eh_frame_hdr): Check that
+ sections haven't already been discarded by the linker.
+ * elflink.h (elf_link_add_object_symbols): Likewise for stab
+ sections and SEC_MERGE sections.
+ (elf_bfd_discard_info): Similarly here.
+ * elfxx-target.h (bfd_elfNN_bfd_link_just_syms): Define.
+ * i386msdos.c (msdos_bfd_link_just_syms): Define.
+ * i386os9k.c (os9k_bfd_link_just_syms): Define.
+ * ieee.c (ieee_bfd_link_just_syms): Define.
+ * ihex.c (ihex_bfd_link_just_syms): Define.
+ * libbfd-in.h (_bfd_nolink_bfd_link_just_syms): Define.
+ (_bfd_generic_link_just_syms): Declare.
+ * libecoff.h (_bfd_ecoff_bfd_link_just_syms): Define.
+ * linker.c (_bfd_generic_link_just_syms): New function.
+ * mmo.c (mmo_bfd_link_just_syms): Define.
+ * nlm-target.h (nlm_bfd_link_just_syms): Define.
+ * oasys.c (oasys_bfd_link_just_syms): Define.
+ * ppcboot.c (ppcboot_bfd_link_just_syms): Define.
+ * som.c (som_bfd_link_just_syms): Define.
+ * srec.c (srec_bfd_link_just_syms): Define.
+ * targets.c (struct bfd_target): Add _bfd_link_just_syms.
+ (BFD_JUMP_TABLE_LINK): And here.
+ * tekhex.c (tekhex_bfd_link_just_syms): Define.
+ * versados.c (versados_bfd_link_just_syms): Define.
+ * vms.c (vms_bfd_link_just_syms): Define.
+ * libbfd.h: Regenerate.
+ * bfd-in2.h: Regenerate.
+
+2002-05-15 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * elf32-mips.c: Remove superfluous definitions copied from
+ elfxx-mips.c.
+ (bfd_elf32_bigmips_vec,bfd_elf32_littlemips_vec): Use the
+ SGIish vectors to check the special case.
+ (mips_elf_hi16_reloc): Fix comment.
+ (mips_elf_got16_reloc): Likewise.
+ (_bfd_mips_elf32_gprel16_reloc): Likewise.
+ (elf_reloc_map): Code cleanup.
+ (mips_reloc_map): Add comment.
+ (bfd_elf23_bfd_reloc_type_lookup): Code cleanup.
+ (mips_elf32_rtype_to_howto): Likewise.
+ (mips_elf32_discard_info): Likewise.
+ (elf32_mips_irix_compat): Invert logic: Only SGIish vectors
+ lead to IRIX compatibility now.
+
+2002-05-15 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * elfxx-mips.c: Call it IRIX, not Irix in comments.
+
+2002-05-13 Jason Thorpe <thorpej@wasabisystems.com>
+
+ * config.bfd (shle-*-netbsdelf*): Add target which includes
+ sh64 support.
+
+2002-05-13 David Edelsohn <edelsohn@gnu.org>
+
+ * configure.in: Revert 2002-04-07. Instead, auto-configure
+ HAVE_ST_C_IMPL.
+ * configure: Regenerate.
+ * config.in: Regenerate.
+ * rs6000-core.c (CNEW_IMPL): Guard use of c_impl with HAVE_ST_C_IMPL
+ or AIX_5_CORE.
+
+2002-05-11 Federico G. Schwindt <fgsch@olimpo.com.br>
+
+ * configure.in (sparc*-*-openbsd*): Support sparc64-openbsd
+ corefiles as well.2
+ * configure: Regenerate.
+
+2002-05-13 Alan Modra <amodra@bigpond.net.au>
+
+ * Makefile.am (install-data-local): Install headers to
+ $(exec_prefix)/include.
+ * Makefile.in: Regenerate.
+
+2002-05-11 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+ Daniel Jacobowitz <drow@mvista.com>
+
+ * coff-sh.c (sh_reloc_map): Map to R_SH_IMM32 for non-PE. Don't
+ map BFD_RELOC_RVA.
+
+2002-05-11 Federico G. Schwindt <fgsch@olimpo.com.br>
+
+ * config.bfd (alpha*-*-openbsd*, sparc64*-*-openbsd*,
+ hppa*-*-openbsd*): New targets.
+ * configure.in (alpha*-*-openbsd*): Set COREFILE.
+ * configure: Regenerate.
+
+2002-05-10 Tom Rix <trix@redhat.com>
+
+ * coff64-rs6000.c (xcoff64_reloc_type_br): New function for
+ xcoff64_ppc_relocate_section.
+ * coff-rs6000.c : Extern common xcoff_reloc_type functions.
+ * libxcoff.h: Common xcoff_reloc_type function declaration.
+
+2002-05-10 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-i386.c (elf_i386_relocate_section): Remove overflow checks
+ added in 2002-05-09 commit.
+
+ * elf32-hppa.c (elf32_hppa_size_stubs): Revert part of 2002-05-04,
+ don't look for stubs on all undefined syms.
+
+2002-05-09 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (RA_REGISTER_MASK, RA_REGISTER_SHIFT): Delete.
+ (ppc64_elf_howto_raw <R_PPC64_RELATIVE>): Not pc_relative or
+ pcrel_offset.
+
+ * elf32-i386.c (elf_howto_table): Comments.
+ (elf_i386_relocate_section): Handle more relocs for relocatable
+ linking and against SEC_MERGE sections.
+
+2002-05-08 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-ppc.c (ppc_elf_create_got): New function.
+ (ppc_elf_create_dynamic_sections): Call ppc_elf_create_got before
+ _bfd_elf_create_dynamic_sections. Correct .plt flags.
+ (ppc_elf_check_relocs): Use ppc_elf_create_got in place of
+ _bfd_elf_create_got_section.
+
+2002-05-07 Alan Modra <amodra@bigpond.net.au>
+
+ * elf-bfd.h (struct elf_backend_data): Add rela_normal.
+ * elfxx-target.h (elf_backend_rela_normal): Define.
+ (elfNN_bed): Init rela_normal.
+ * elflink.h (elf_link_input_bfd <emit_relocs>): Handle adjustment
+ for section symbols here if rela_normal. Simplify abs section test.
+ * elf-m10200.c (mn10200_elf_relocate_section): If relocatable,
+ return immediately. Remove code handling relocatable linking.
+ * elf-m10300.c (mn10300_elf_relocate_section): Likewise.
+ * elf32-fr30.c (fr30_elf_relocate_section): Likewise.
+ * elf32-i370.c (i370_elf_relocate_section): Likewise.
+ * elf32-i860.c (elf32_i860_relocate_section): Likewise.
+ * elf32-m68k.c (elf_m68k_relocate_section): Likewise.
+ * elf32-mcore.c (mcore_elf_relocate_section): Likewise.
+ * elf32-openrisc.c (openrisc_elf_relocate_section): Likewise.
+ * elf32-ppc.c (ppc_elf_relocate_section): Likewise.
+ * elf32-s390.c (elf_s390_relocate_section): Likewise.
+ * elf32-xstormy16.c (xstormy16_elf_relocate_section): Likewise.
+ * elf64-ppc.c (ppc64_elf_relocate_section): Likewise.
+ * elf64-s390.c (elf_s390_relocate_section): Likewise.
+ * elf64-x86-64.c (elf64_x86_64_relocate_section): Likewise.
+ * elfxx-ia64.c (elfNN_ia64_relocate_section): Likewise.
+ * elf32-arm.h (elf32_arm_relocate_section): Likewise #ifndef USE_REL.
+ * elf32-m32r.c (m32r_elf_relocate_section): Likewise.
+ * elf-m10200.c (elf_backend_rela_normal): Define.
+ * elf-m10300.c (elf_backend_rela_normal): Define.
+ * elf32-fr30.c (elf_backend_rela_normal): Define.
+ * elf32-i370.c (elf_backend_rela_normal): Define.
+ * elf32-i860.c (elf_backend_rela_normal): Define.
+ * elf32-m68k.c (elf_backend_rela_normal): Define.
+ * elf32-mcore.c (elf_backend_rela_normal): Define.
+ * elf32-openrisc.c (elf_backend_rela_normal): Define.
+ * elf32-ppc.c (elf_backend_rela_normal): Define.
+ * elf32-s390.c (elf_backend_rela_normal): Define.
+ * elf32-xstormy16.c (elf_backend_rela_normal): Define.
+ * elf64-ppc.c (elf_backend_rela_normal): Define.
+ * elf64-s390.c (elf_backend_rela_normal): Define.
+ * elf64-x86-64.c (elf_backend_rela_normal): Define.
+ * elfxx-ia64.c (elf_backend_rela_normal): Define.
+ * elf32-arm.h (elf_backend_rela_normal): Define #ifndef USE_REL.
+ * elf32-m32r.c (elf_backend_rela_normal): Likewise.
+
+2002-05-06 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * elf32-arm.h (elf32_arm_final_link_relocate): Convert
+ 'reloc_signed_max' and 'reloc_signed_min' into half-word offsets.
+
+2002-05-06 Alan Modra <amodra@bigpond.net.au>
+
+ * elflink.h (elf_link_input_bfd <emit_relocs>): Adjust r_offset
+ when not relocatable. Fix reloc_emitter call for K&R.
+
+2002-05-04 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (ppc64_elf_relocate_section): Reinstate code
+ reloading local sym addend mistakenly removed in 2002-05-01 change.
+
+ * dwarf2.c (struct line_head): Make prologue_length a bfd_vma.
+ (read_abbrevs): Change "offset" param to bfd_vma.
+ (parse_comp_unit): Change "version" and addr_size to unsigned ints.
+ Change "abbrev_offset" to bfd_vma.
+ (read_indirect_string): Use correct conversion chars in error
+ message format string, cast bfd_vma's to unsigned long.
+ (read_abbrevs): Likewise.
+ (read_attribute_value): Likewise.
+ (decode_line_info): Likewise.
+ (scan_unit_for_functions): Likewise.
+ (parse_comp_unit): Likewise.
+
+2002-05-04 Tom Rix <trix@redhat.com>
+
+ * coffswap.h (coff_swap_reloc_in): Remove XCOFF support.
+ (coff_swap_reloc_out): Same.
+ * coff-rs6000.c: (xcoff_swap_reloc_in): Moved from coffswap.h.
+ (xcoff_swap_reloc_out): Same.
+ (xcoff_rtype2howto): Renamed from _bfd_xcoff_rtype2howto. Special
+ case some 16 bit relocs. Add reloc value to output.
+ (xcoff_howto_table): Remove 64 bit R_POS, add 16 bit
+ R_RBR. Improve names.
+ (_bfd_xcoff_reloc_type_lookup): Adjust for removal of 64 bit R_POS.
+ (bfd_xcoff_backend_data): Update with new reloc swap names.
+ (bfd_pmac_xcoff_backend_data) : Same.
+ * coff64-rs6000.c: (xcoff64_swap_reloc_in): Moved from coffswap.h.
+ (xcoff64_swap_reloc_out): Same.
+ (xcoff64_rtype2howto): Special case some 16 bit relocs and 32 bit
+ R_POS. Add reloc value to output.
+ (xcoff64_howto_table): Move 64 bit R_POS to first entry. Add 16
+ bit R_RBR. Improve names, masks.
+ (xcoff64_reloc_type_lookup): Adjust for move of 64 bit R_POS.
+ (bfd_xcoff_backend_data): Update with new reloc swap names.
+ (bfd_xcoff_aix5_backend_data) : Same.
+
+2002-05-04 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-hppa.c (struct elf32_hppa_link_hash_table): Add
+ bfd_count top_index, input_list, all_local_syms.
+ (elf32_hppa_setup_section_lists): New function, split from
+ elf32_hppa_size_stubs.
+ (elf32_hppa_next_input_section): Likewise.
+ (group_sections): Likewise.
+ (get_local_syms): Likewise.
+ (elf32_hppa_size_stubs): Adjust for split out functions. Look for
+ stubs on undefined syms too.
+ (elf32_hppa_set_gp): Use bfd_link_hash* instead of elf_link_hash*.
+ Only access htab elf fields when we have an elf hash table.
+ * elf32-hppa.h (elf32_hppa_setup_section_lists): Declare.
+ (elf32_hppa_next_input_section): Declare.
+
+2002-05-04 Bob Byrnes <byrnes@curl.com>
+
+ * opncls.c (_bfd_new_bfd_contained_in): Check return value of
+ _bfd_new_bfd.
+
+2002-05-03 H.J. Lu (hjl@gnu.org)
+
+ * elfxx-mips.c (mips_elf_link_hash_entry): Add forced_local.
+ (mips_elf_link_hash_newfunc): Initialize forced_local to false.
+ (mips_elf_record_global_got_symbol): Call _bfd_mips_elf_hide_symbol
+ to hide a global symbol.
+ (_bfd_mips_elf_hide_symbol): Return if forced_local is true. Set
+ forced_local to true.
+
+2002-05-02 Richard Henderson <rth@redhat.com>
+
+ * elf64-alpha.c (elf64_alpha_relocate_section): Force relative relocs
+ vs SHN_UNDEF to zero.
+
+2002-05-02 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (ppc64_elf_howto_raw <R_PPC64_SECTOFF>): Change to a
+ 16 bit reloc.
+ <R_PPC64_SECTOFF_DS>: Likewise.
+ (ppc64_elf_reloc_type_lookup): Map from BFD_RELOC_16_BASEREL to
+ SECTOFF reloc.
+ * elf32-ppc.c (ppc_elf_howto_raw <R_PPC_SECTOFF>): Correct.
+ (ppc_elf_reloc_type_lookup): Map from BFD_RELOC_16_BASEREL to
+ SECTOFF reloc.
+
+ * elf64-ppc.c (ppc64_elf_addr16_ha_reloc): Delete.
+ (ppc64_elf_ha_reloc): New function.
+ (ppc64_elf_brtaken_reloc): New function.
+ (ppc64_elf_sectoff_reloc): New function.
+ (ppc64_elf_sectoff_ha_reloc): New function.
+ (ppc64_elf_toc_reloc): New function.
+ (ppc64_elf_toc_ha_reloc): New function.
+ (ppc64_elf_toc64_reloc): New function.
+ (ppc64_elf_unhandled_reloc): New function.
+ (ppc64_elf_howto_raw): Use the above.
+ <R_PPC64_RELATIVE>: Mark pc_relative, pcrel_offset.
+ <R_PPC64_SECTOFF>: Not pc_relative or pcrel_offset. Fix dst_mask.
+ <R_PPC64_SECTOFF_DS>: Likewise.
+ (IS_ABSOLUTE_RELOC): Update.
+ (struct ppc_link_hash_table): Add have_undefweak.
+ (ppc64_elf_link_hash_table_create): Init.
+ (func_desc_adjust): Set have_undefweak.
+ (ppc64_elf_func_desc_adjust): Call func_desc_adjust earlier. Only
+ add the .sfpr blr when have_undefweak.
+ (ppc64_elf_setup_section_lists): Check hash table flavour.
+ (ppc64_elf_next_input_section): Move output_section->owner test to
+ ppc64elf.em.
+ (ppc64_elf_set_toc): Rename to ppc64_elf_toc, remove info param
+ and relocatable test. Return TOCstart and don't set elf_gp.
+ (ppc64_elf_relocate_section): Correct BRTAKEN/BRNTAKEN branch
+ offset calculation. Add assert on weak sym branch tweaks.
+ * elf64-ppc.h (ppc64_elf_set_toc): Delete.
+ (ppc64_elf_toc): Declare.
+ (ppc64_elf_next_input_section): Update.
+
+2002-05-01 Alan Modra <amodra@bigpond.net.au>
+
+ * syms.c (_bfd_stab_section_find_nearest_line): Don't bomb on NULL
+ file_name.
+
+2002-05-01 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (CROR_151515, CROR_313131): Define.
+ (ppc64_elf_relocate_section): Use them. Don't look for plt calls
+ on R_PPC64_ADDR24 relocs. Require a nop or no link reg on plt
+ call branches. Correct undefined weak destination.
+ (ppc64_elf_func_desc_adjust): Always create at least one blr in
+ .sfpr, and correct case where either only savef* or restf* is
+ needed.
+
+ Long branch stubs, multiple stub sections.
+ * elf64-ppc.h (ppc64_elf_setup_section_lists): Declare.
+ (ppc64_elf_next_input_section): Declare.
+ * elf64-ppc.c: Move linker-only prototypes.
+ (STUB_SUFFIX): Define.
+ (enum ppc_stub_type): New.
+ (struct ppc_stub_hash_entry): New.
+ (struct ppc_branch_hash_entry): New.
+ (struct ppc_link_hash_entry): Add stub_cache, oh.
+ (struct ppc_link_hash_table): Add stub_hash_table etc. Remove
+ sstub. Add sbrlt, srelbrlt, has_14bit_branch, stub_iteration.
+ Rename plt_overflow to stub_error.
+ (ppc_stub_hash_lookup): Define.
+ (ppc_branch_hash_lookup): Define.
+ (stub_hash_newfunc): New function.
+ (branch_hash_newfunc): New function.
+ (link_hash_newfunc): Init new fields.
+ (ppc64_elf_link_hash_table_create): Likewise.
+ (ppc64_elf_link_hash_table_free): New function.
+ (ppc_stub_name): New function.
+ (ppc_get_stub_entry): New function.
+ (ppc_add_stub): New function.
+ (create_linkage_sections): Use bfd_make_section_anyway. Create
+ .branch_lt and .rela.branch_lt sections. Don't create .stub.
+ (ppc64_elf_check_relocs): Set has_14bit_branch on R_PPC64_REL14*,
+ and set up for plt call stubs. Link func and func desc syms.
+ (ppc64_elf_gc_sweep_hook): Handle REL14* as per REL24.
+ (func_desc_adjust): Avoid hash lookup when func desc sym available
+ via shortcut, and set links when processing.
+ (ppc64_elf_hide_symbol): Likewise.
+ (allocate_dynrelocs): Don't allocate stub section here.
+ (ppc64_elf_size_dynamic_sections): Handle sbrlt and srelbrlt.
+ Remove sstub code.
+ (ppc_type_of_stub): New function.
+ (build_one_stub): Delete.
+ (ppc_build_one_stub): New function.
+ (ppc_size_one_stub): New function.
+ (ppc64_elf_setup_section_lists): New function.
+ (ppc64_elf_next_input_section): New function.
+ (group_sections): New function.
+ (get_local_syms): New function.
+ (ppc64_elf_size_stubs): Rewrite.
+ (ppc64_elf_build_stubs): Rewrite.
+ (ppc64_elf_relocate_section): Look up stub entry for REL24
+ relocs. Don't propagate REL14* to dynamic objects. Look for long
+ branch stubs if REL14* or REL24 relocs won't reach.
+ (bfd_elf64_bfd_link_hash_table_free): Define.
+
+2002-04-30 Mark Mitchell <mark@codesourcery.com>
+
+ * config.bfd: Add support for powerpc-*-windiss.
+
+2002-04-30 Tom Rix <trix@redhat.com>
+
+ * xcofflink.c (xcoff_link_add_symbols): Always copy undef C_EXT
+ symbol names into the hash table.
+
+2002-04-28 Tom Rix <trix@redhat.com>
+
+ * coff-rs6000.c (xcoff_calculate_relocation) : Function table for
+ calulating relocations.
+ (xcoff_complain_overflow) : Function table for relocation errors.
+ (xcoff_ppc_relocate_section): Use relocation and complain function
+ tables.
+ (xcoff_complain_overflow_unsigned_func): New complain function.
+ (xcoff_complain_overflow_signed_func): Same.
+ (xcoff_complain_overflow_bitfield_func): Same.
+ (xcoff_complain_overflow_dont_func): Same.
+ (xcoff_reloc_type_crel): New recot function.
+ (xcoff_reloc_type_br): Same.
+ (xcoff_reloc_type_ba): Same.
+ (xcoff_reloc_type_toc): Same.
+ (xcoff_reloc_type_rel): Same.
+ (xcoff_reloc_type_neg): Same.
+ (xcoff_reloc_type_pos): Same.
+ (xcoff_reloc_type_fail): Same.
+ (xcoff_reloc_type_noop): Same.
+ * libxcoff.h : Declare common parts for xcoff64.
+ * coff64-rs6000.c (xcoff64_ppc_relocate_section): Use relocation
+ and complain function tables.
+
+2002-04-28 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-x86-64.c (struct elf64_x86_64_dyn_relocs): Comment typo.
+ * elf32-hppa.c (elf32_hppa_final_link): Formatting.
+
+2002-04-26 Alan Modra <amodra@bigpond.net.au>
+
+ * opncls.c (bfd_make_readable): Call bfd_section_list_clear.
+ * xcofflink.c (xcoff_link_add_dynamic_symbols): Likewise.
+
+ * elflink.h (elf_bfd_final_link): Ensure input bfd class is the
+ same as the output before calling elf_link_input_bfd.
+
+ * coffcode.h (coff_compute_section_file_positions): Set
+ section_tail after shuffling section list.
+
+2002-04-24 Christian Groessler <chris@groessler.org>
+
+ * coff-z8k.c (extra_case): Fix R_IMM32 relocations: The
+ addresses are 23bit with a special layout, not plain 32bit
+ values. Prevent relocation of immediate values.
+
+2002-04-24 Chris G. Demetriou <cgd@broadcom.com>
+
+ * elfxx-mips.c (_bfd_mips_elf_print_private_bfd_data): If MDMX or
+ MIPS-16 ASE flags are set, print something to indicate that.
+
+2002-04-23 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-hppa.c (hppa_type_of_stub): Correct and simplify condition
+ under which a plt call stub is used.
+ (final_link_relocate): Similarly.
+ (allocate_plt_static): Clear h-plabel except when plt entry is
+ exclusively used for a plabel.
+ (allocate_dynrelocs): Use the above to simplify plt sizing.
+ (struct elf32_hppa_link_hash_table): Add has_22bit_branch.
+ (elf32_hppa_link_hash_table_create): Init.
+ (BL22_RP): Define.
+ (hppa_build_one_stub): Use BL22_RP if has_22bit_branch.
+ (elf32_hppa_check_relocs): Set has_22bit_branch.
+
+ * elf32-hppa.c (elf32_hppa_check_relocs): Remove debug message.
+ (final_link_relocate): Likewise.
+
+2002-04-22 Jakub Jelinek <jakub@redhat.com>
+
+ * elf-eh-frame.c (_bfd_elf_discard_section_eh_frame): Don't build
+ search table if some FDE is DW_EH_PE_aligned encoded either.
+ (_bfd_elf_write_section_eh_frame): Handle terminating FDE specially.
+
+2002-04-22 Richard Smith <richard@ex-parrot.com>
+ Jakub Jelinek <jakub@redhat.com>
+
+ * elf-eh-frame.c (struct eh_cie_fde): Add per_encoding_relative.
+ (_bfd_elf_discard_section_eh_frame): Set it for CIEs with pcrel
+ encoded personality.
+ (_bfd_elf_write_section_eh_frame): Adjust pcrel encoded personality
+ for CIE/FDE removal.
+
+2002-04-20 Tom Rix <trix@redhat.com>
+
+ * coff64-rs6000.c (_bfd_xcoff64_swap_aux_in): Fix C_FILE auxent.
+
+2002-04-20 Alan Modra <amodra@bigpond.net.au>
+
+ * archures.c (bfd_lookup_arch): Move the list order comment..
+ (struct bfd_arch_info): ..to where it belongs.
+ * bfd-in2.h: Regenerate.
+
+ * archures.c (bfd_lookup_arch): Add comment on list order.
+ (bfd_default_set_arch_mach): Use bfd_lookup_arch.
+ * cpu-powerpc.c (bfd_powerpc_archs): Re-order so that the default
+ is always at head of list.
+
+2002-04-18 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * coff-arm.c (coff_thumb_pcrel_12, coff_thumb_pcrel_9,
+ insert_thumb_branch, record_thumb_to_arm_glue): Suppress
+ definition of these functions for ARM_WINCE builds as they are
+ not used.
+ (SWAP_IN_RELOC_OFFSET, SWAP_OUT_RELOC_OFFSET): Do not define
+ for ARM_WINCE builds.
+
+2002-04-18 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * coff-arm.c (bfd_arm_process_before_allocation):
+
+2002-04-17 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * cpu-sh.c (scan_mach): Delete.
+ (arch_info_struct): Replace scan_mach with bfd_default_scan.
+ (bfd_sh_arch): Likewise.
+
+2002-04-16 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * ihex.c (ihex_write_object_contents): Fix check for records
+ crossing 64K boundaries.
+
+2002-04-16 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-m32r.c (m32r_elf_add_symbol_hook): Check the hash table
+ type rather than just assuming entries are ELF.
+ * elf32-sh64.c (sh64_elf_add_symbol_hook): Likewise.
+ * elf64-sh64.c (sh64_elf64_add_symbol_hook): Likewise.
+ * elf64-sparc.c (sparc64_elf_add_symbol_hook): Likewise.
+ * elf64-mmix.c (mmix_elf_add_symbol_hook): Use bfd_link_hash_entry
+ rather than elf_link_hash_entry.
+
+2002-04-15 Richard Henderson <rth@redhat.com>
+
+ * elf32-mips.c (mips_elf32_object_p): Revert 0404 fragment: allow
+ n32 binaries.
+
+2002-04-15 Michael Snyder <msnyder@redhat.com>
+
+ * opncls.c (bfd_close): Write contents if writeable.
+ Minor formatting tidy-ups.
+
+2002-04-15 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-ppc.c (ppc_elf_add_symbol_hook): Check the hash table type.
+
+2002-04-12 Michael Snyder <msnyder@redhat.com>
+
+ * bfd-in.h (bfd_get_section_lma): New access macro.
+ Minor white-space fix-up.
+
+2002-04-12 Alan Modra <amodra@bigpond.net.au>
+
+ * elf.c (prep_headers): Don't zero EI_OSABI, EI_ABIVERSION or
+ header pad.
+
+2002-04-09 DJ Delorie <dj@redhat.com>
+
+ * elfarm-nabi.c (elf32_arm_howto_table): Fix ABS16 masks.
+
+2002-04-09 Casper S. Hornstrup <chorns@users.sourceforge.net>
+
+ * coffcode.h (coff_read_word): New.
+ (coff_compute_checksum): New.
+ (coff_apply_checksum): New.
+ (coff_write_object_contents): Call coff_apply_checksum () to
+ apply checksum to PE image.
+
+2002-04-08 Randolph Chung <tausq@debian.org>
+
+ * elf32-hppa.c (hppa_unwind_entry_compare): Move to elf-hppa.h.
+ (elf32_hppa_final_link): Split out sorting logic to..
+ * elf-hppa.h (elf_hppa_sort_unwind): ..here.
+ (elf_hppa_final_link): Call elf_hppa_sort_unwind.
+
+2002-04-07 Andrew Cagney <ac131313@redhat.com>
+
+ * configure.in: Add missing ``|'' to powerpc-*-aix4.[4-9]*
+ pattern.
+ * configure: Re-generate.
+
+2002-04-07 Andrew Cagney <ac131313@redhat.com>
+
+ * configure.in: Only define AIX_CORE_DUMPX_CORE when AIX version
+ is greater or equal to 4.3.3.
+ * configure: Regenerate.
+ Fix PR gdb/344.
+
+2002-04-05 Hans-Peter Nilsson <hp@axis.com>
+
+ * elf32-cris.c (cris_elf_howto_table) <R_CRIS_16_PCREL,
+ R_CRIS_32_PCREL>: Fix typo in name.
+ (cris_elf_check_relocs): Always create .rela.got here when
+ R_CRIS_16_GOTPLT or R_CRIS_32_GOTPLT is seen.
+ (elf_cris_adjust_gotplt_to_got): Don't create .rela.got here;
+ assume it's created.
+
+2002-04-04 Daniel Jacobowitz <drow@mvista.com>
+
+ * aout-adobe.c (aout_32_bfd_link_hash_table_free): Define.
+ * aout-target.h (MY_bfd_link_hash_table_free): Conditionally
+ define.
+ * aout-tic30.c (MY_bfd_link_hash_table_free): Likewise.
+ * bfd.c (bfd_link_hash_table_free): Define.
+ * binary.c (binary_bfd_link_hash_table_free): Define.
+ * bout.c (b_out_bfd_link_hash_table_free): Define.
+ * coff-rs6000.c (rs6000coff_vec): Include
+ _bfd_generic_link_hash_table_free.
+ (pmac_xcoff_vec): Likewise.
+ * coff64-rs6000.c (rs6000coff64_vec): Likewise.
+ (aix5coff64_vec): Likewise.
+ * coffcode.h (coff_bfd_link_hash_table_free): Conditionally define.
+ * elf-m10300.c (elf32_mn10300_link_hash_table_free): New function.
+ (bfd_elf32_bfd_link_hash_table_free): Define.
+ * elf32-hppa.c (elf32_hppa_link_hash_table_free): New function.
+ (bfd_elf32_bfd_link_hash_table_free): Define.
+ * elfxx-target.h (bfd_elfNN_bfd_link_hash_table_free): Conditionally
+ define.
+ * i386msdos.c (msdos_bfd_link_hash_table_free): Define.
+ * i386os9k.c (os9k_bfd_link_hash_table_free): Define.
+ * ieee.c (ieee_bfd_link_hash_table_free): Define.
+ * ihex.c (ihex_bfd_link_hash_table_free): Define.
+ * libbfd-in.h (_bfd_nolink_bfd_link_hash_table_free): Define.
+ (_bfd_generic_link_hash_table_free): Add prototype.
+ * libcoff-in.h (_bfd_xcoff_bfd_link_hash_table_free): Add prototype.
+ * libecoff.h (_bfd_ecoff_bfd_link_hash_table_free): Define.
+ * linker.c (_bfd_generic_link_hash_table_free): New function.
+ * mmo.c (mmo_bfd_link_hash_table_free): Define.
+ * nlm-target.h (nlm_bfd_link_hash_table_free): Define.
+ * oasys.c (oasys_bfd_link_hash_table_free): Define.
+ * ppcboot.c (ppcboot_bfd_link_hash_table_free): Define.
+ * som.c (som_bfd_link_hash_table_free): Define.
+ * srec.c (srec_bfd_link_hash_table_free): Define.
+ * tekhex.c (tekhex_bfd_link_hash_table_free): Define.
+ * versados.c (versados_bfd_link_hash_table_free): Define.
+ * vms.c (vms_bfd_link_hash_table_free): New function.
+ * xcofflink.c (_bfd_xcoff_bfd_link_hash_table_free): New function.
+
+ * coff-arm.c (coff_arm_link_hash_table_create): Use bfd_malloc
+ instead of bfd_alloc.
+ * coff-h8300.c (h8300_coff_link_hash_table_create): Likewise.
+ * coff-mcore.c (coff_mcore_link_hash_table_create): Likewise.
+ * coff-ppc.c (ppc_coff_link_hash_table_create): Likewise.
+ * cofflink.c (_bfd_coff_link_hash_table_create): Likewise.
+ * ecoff.c (_bfd_ecoff_bfd_link_hash_table_create): Likewise.
+ * elf-m10300.c (elf32_mn10300_link_hash_table_create): Likewise.
+ * elf.c (_bfd_elf_link_hash_table_create): Likewise.
+ * elf32-arm.h (elf32_arm_link_hash_table_create): Likewise.
+ * elf32-cris.c (elf_cris_link_hash_table_create): Likewise.
+ * elf32-hppa.c (elf32_hppa_link_hash_table_create): Likewise.
+ * elf32-i386.c (elf_i386_link_hash_table_create): Likewise.
+ * elf32-m68k.c (elf_m68k_link_hash_table_create): Likewise.
+ * elf32-s390.c (elf_s390_link_hash_table_create): Likewise.
+ * elf32-sh.c (sh_elf_link_hash_table_create): Likewise.
+ * elf64-alpha.c (elf64_alpha_bfd_link_hash_table_create): Likewise.
+ * elf64-ppc.c (ppc64_elf_link_hash_table_create): Likewise.
+ * elf64-s390.c (elf_s390_link_hash_table_create): Likewise.
+ * elf64-sh64.c (sh64_elf64_link_hash_table_create): Likewise.
+ * elf64-sparc.c (sparc64_elf_bfd_link_hash_table_create): Likewise.
+ * elf64-x86-64.c (elf64_x86_64_link_hash_table_create): Likewise.
+ * elfxx-mips.c (_bfd_mips_elf_link_hash_table_create): Likewise.
+ * linker.c (_bfd_generic_link_hash_table_create): Likewise.
+ * m68klinux.c (linux_link_hash_table_create): Likewise.
+ * sparclinux.c (linux_link_hash_table_create): Likewise.
+ * sunos.c (sunos_link_hash_table_create): Likewise.
+ * xcofflink.c (_bfd_xcoff_bfd_link_hash_table_create): Likewise.
+
+ * targets.c: Add _bfd_link_hash_table_free to xvec.
+
+ * bfd-in2.h: Regenerate.
+ * libbfd.h: Regenerate.
+ * libcoff.h: Regenerate.
+
+2002-04-04 Alan Modra <amodra@bigpond.net.au>
+
+ * dep-in.sed: Cope with absolute paths.
+ * Makefile.am (dep.sed): Subst TOPDIR, and not INCDIR.
+ Run "make dep-am".
+ * Makefile.in: Regenerate.
+ * coff-arm.c: Fix copyright date.
+ * cpu-h8300.c: Likewise.
+ * cpu-i370.c: Likewise.
+ * cpu-s390.c: Likewise.
+ * cpu-mips.c: Likewise.
+ * po/SRC-POTFILES.in: Regenerate.
+
+2002-04-04 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * Makefile.am: Add elfxx-mips.c to the known backends.
+ (elf32-mips.lo): remove dependency to coff/external.h.
+ * Makefile.in: Regenerate.
+ * configure.in: Add elfxx-mips.lo to all vectors using elf32-mips.lo
+ Remove elf32-mips.lo from 64 bit vectors. Update dependencies
+ accordingly.
+ * configure: Regenerate.
+ * elf-bfd.h: Move all MIPS ELF specific prototypes to elfxx-mips.h.
+ (irix_compat_t): IRIX compatibility level, moved from elf32-mips.c.
+ (elf_backend_mips_irix_compat, elf_backend_mips_rtype_to_howto): New
+ MIPS specific backend functions.
+ * elf32-mips.c: Moved most code to elfxx-mips.c.
+ (mips_elf_hi16_reloc): Rename from _bfd_mips_elf_hi16_reloc and make
+ static.
+ (mips_elf_lo16_reloc): Likewise, was _bfd_mips_elf_lo16_reloc.
+ (mips_elf_got16_reloc): Likewise, was _bfd_mips_elf_got16_reloc.
+ (mips_elf_gprel32_reloc): Likewise, was _bfd_mips_elf_gprel32_reloc.
+ (mips_elf32_rtype_to_howto): Rename from mips_rtype_to_howto. Changed
+ interface to allow selection of the right REL or RELA howto table.
+ (mips_elf32_object_p): Rename from _bfd_mips_elf_object_p and made
+ static. Let it refuse n32 objects.
+ (elf32_mips_grok_prstatus): Rename from _bfd_elf32_mips_grok_prstatus.
+ (elf32_mips_grok_psinfo): Rename from _bfd_elf32_mips_grok_psinfo.
+ (elf32_mips_discard_info): Rename from _bfd_elf32_mips_discard_info.
+ (elf32_mips_ignore_discarded_relocs): Rename from
+ _bfd_elf32_mips_ignore_discarded_relocs.
+ (elf32_mips_write_section): Rename from _bfd_elf32_mips_write_section.
+ (elf32_mips_irix_compat): New function, replaces IRIX_COMPAT.
+ (elf_mips_howto_table_rela): Remove.
+ * elf64-mips.c: Moved most code to elfxx-mips.c.
+ (bfd_elf64_bfd_reloc_type_lookup): Make static.
+ (mips_elf64_rtype_to_howto): New function.
+ (mips_elf64_object_p): Likewise.
+ (elf64_mips_irix_compat): Likewise.
+ * elfxx-mips.c: New file containing common code merged together from
+ elf32-mips.c and elf64-mips.c.
+ * elfxx-mips.h: New file containing MIPS specific prototypes from
+ elf-bfd.h.
+ * elfxx-target.h: Add handling for elf_backend_mips_irix_compat and
+ elf_backend_mips_rtype_to_howto.
+
+2002-04-04 Alan Modra <amodra@bigpond.net.au>
+
+ * srec.c (MAXCHUNK, Chunk): Revise comments.
+ (srec_write_record): Correct buffer size.
+ (srec_write_header): Do without intermediate buffer.
+ (srec_write_section): Validate Chunk.
+ (srec_write_terminator): Pass NULL instead of dummy buffer.
+ (srec_write_symbols): Pass file and symbol names directly to
+ bfd_bwrite so sprintf won't overflow buffer.
+
+2002-04-03 Jakub Jelinek <jakub@redhat.com>
+
+ * elf32-sparc.c (elf32_sparc_relocate_section): Don't emit dynamic
+ PC relative relocs against hidden symbols.
+ * elf64-sparc.c (sparc64_elf_relocate_section): Likewise.
+
+2002-04-03 Alan Modra <amodra@bigpond.net.au>
+
+ * elf.c (_bfd_elf_make_section_from_shdr): When setting section
+ LMAs, loop over segments until p_vaddr and p_memsz specify an
+ extent enclosing the section.
+
+2002-04-02 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * ihex.c (ihex_write_object_contents): Do not allow records to
+ cross a 64K boundary - wrap if necessary.
+
+2002-04-01 Nathan Williams <nathanw@wasabisystems.com>
+
+ * elf.c (elfcore_netbsd_get_lwpid): Fix off-by-one error
+ which caused the returned LWP ID to always be 0.
+
+2002-04-01 Richard Henderson <rth@redhat.com>
+
+ * elf32-sparc.c (WILL_CALL_FINISH_DYNAMIC_SYMBOL): New.
+ (elf32_sparc_relocate_section): Use it to figure out when to
+ initialize .got entries.
+ * elf64-sparc.c: Similarly.
+
+2002-03-28 Alan Modra <amodra@bigpond.net.au>
+
+ * linker.c (link_action): Ignore duplicate warning syms.
+ (_bfd_generic_link_write_global_symbol): Follow warning symbol link.
+ * elflink.h (elf_adjust_dynstr_offsets): Likewise.
+ (elf_adjust_dynamic_symbol): Likewise.
+ (elf_export_symbol): Likewise.
+ (elf_link_find_version_dependencies): Likewise.
+ (elf_link_assign_sym_version): Likewise.
+ (elf_link_sec_merge_syms): Likewise.
+ (elf_link_output_extsym): Likewise.
+ (elf_gc_sweep_symbol): Likewise.
+ (elf_gc_propagate_vtable_entries_used): Likewise.
+ (elf_gc_smash_unused_vtentry_relocs): Likewise.
+ (elf_gc_allocate_got_offsets): Likewise.
+ (elf_collect_hash_codes): Likewise.
+ * elflink.c (elf_link_renumber_hash_table_dynsyms): Likewise.
+ * elf-hppa.h (elf_hppa_unmark_useless_dynamic_symbols): Likewise.
+ (elf_hppa_remark_useless_dynamic_symbols): Likewise.
+ * elf-m10300.c (elf32_mn10300_finish_hash_table_entry): Likewise.
+ * elf32-arm.h (elf32_arm_discard_copies): Likewise.
+ * elf32-cris.c (elf_cris_adjust_gotplt_to_got): Likewise.
+ (elf_cris_discard_excess_dso_dynamics): Likewise.
+ * elf32-hppa.c (clobber_millicode_symbols): Likewise.
+ (mark_PIC_calls): Likewise.
+ (allocate_plt_static): Likewise.
+ (allocate_dynrelocs): Likewise.
+ (readonly_dynrelocs): Likewise.
+ * elf32-i386.c (allocate_dynrelocs): Likewise.
+ (readonly_dynrelocs): Likewise.
+ * elf32-i370.c (i370_elf_adjust_dynindx): Likewise.
+ * elf32-m68k.c (elf_m68k_discard_copies): Likewise.
+ * elf32-mips.c (mips_elf_output_extsym): Likewise.
+ (mips_elf_sort_hash_table_f): Likewise.
+ (mips_elf_check_mips16_stubs): Likewise.
+ * elf32-s390.c (allocate_dynrelocs): Likewise.
+ (readonly_dynrelocs): Likewise.
+ * elf32-sh.c (sh_elf_discard_copies): Likewise.
+ * elf32-xstormy16.c (xstormy16_relax_plt_check): Likewise.
+ (xstormy16_relax_plt_realloc): Likewise.
+ * elf64-alpha.c (elf64_alpha_calc_got_offsets_for_symbol): Likewise.
+ (elf64_alpha_output_extsym): Likewise.
+ * elf64-hppa.c (elf64_hppa_mark_exported_functions): Likewise.
+ * elf64-mips.c (mips_elf64_sort_hash_table_f): Likewise.
+ (mips_elf64_check_mips16_stubs): Likewise.
+ (mips_elf64_output_extsym): Likewise.
+ * elf64-ppc.c (func_desc_adjust): Likewise.
+ (allocate_dynrelocs): Likewise.
+ (readonly_dynrelocs): Likewise.
+ * elf64-s390.c (allocate_dynrelocs): Likewise.
+ (readonly_dynrelocs): Likewise.
+ * elf64-sh64.c (sh64_elf64_discard_copies): Likewise.
+ * elf64-x86-64.c (allocate_dynrelocs): Likewise.
+ (readonly_dynrelocs): Likewise.
+ * elfxx-ia64.c (elfNN_ia64_global_dyn_sym_thunk): Likewise.
+ * aoutx.h (aout_link_write_other_symbol): Likewise.
+ * cofflink.c (_bfd_coff_write_task_globals): Likewise.
+ (_bfd_coff_write_global_sym): Likewise.
+ * i386linux.c (linux_tally_symbols): Likewise.
+ * m68klinux.c (linux_tally_symbols): Likewise.
+ * sparclinux.c (linux_tally_symbols): Likewise.
+ * pdp11.c (aout_link_write_other_symbol): Likewise.
+ * sunos.c (sunos_scan_dynamic_symbol): Likewise.
+ * xcofflink.c (xcoff_build_ldsyms): Likewise.
+ (xcoff_write_global_symbol): Likewise.
+
+ * cofflink.c (_bfd_coff_final_link): Formatting.
+ * cpu-mips.c (mips_compatible): Make static, prototype.
+ * elf32-i386.c (elf_i386_check_relocs): Formatting.
+ * elf32-sh.c (sh_elf_size_dynamic_sections): Likewise.
+ * elf64-alpha.c (elf64_alpha_output_extsym): Likewise.
+ * elf64-mips.c (mips_elf64_sort_hash_table): Likewise.
+ (mips_elf64_final_link): Likewise.
+ * elflink.h (elf_link_find_version_dependencies): Remove duplicate
+ prototype.
+
+2002-03-27 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * coff-arm.c (SWAP_IN_RELOC_OFFSET): Define.
+ (SWAP_OUT_RELOC_OFFSET): Define.
+
+2002-03-27 Gregory Steuck <greg@nest.cx>
+
+ * elf.c (_bfd_elf_get_symtab_upper_bound): Leave space for
+ terminating NULL if empty symbol table.
+ (_bfd_elf_get_dynamic_symtab_upper_bound): Likewise.
+
+2002-03-26 H.J. Lu (hjl@gnu.org)
+
+ * elflink.h (elf_link_input_bfd): Revert the last change since
+ the gcc exception handling isn't fixed yet.
+
+2002-03-26 H.J. Lu (hjl@gnu.org)
+
+ * elflink.h (elf_link_input_bfd): Complain about relocations
+ against local symbols in discarded sections.
+
+2002-03-26 Alan Modra <amodra@bigpond.net.au>
+
+ * elflink.h (elf_gc_mark): Don't recurse into non-ELF sections.
+
+2002-03-23 Alan Modra <amodra@bigpond.net.au>
+
+ * elf.c (_bfd_elf_make_section_from_shdr): Don't set lma based on
+ section file offset for !SEC_LOAD sections.
+
+2002-03-21 Richard Earnshaw <rearnsha@arm.com>
+
+ * elf32-arm.h (elf32_arm_final_link_relocate <case R_ARM_GOTOFF>,
+ <case R_ARM_GOT>): Handle relocations to Thumb functions.
+
+2002-03-21 Alan Modra <amodra@bigpond.net.au>
+
+ * coff64-rs6000.c (_bfd_xcoff64_put_symbol_name): Prototype.
+ Whitespace changes.
+ * archive.c: Update copyright date.
+ * bfd-in2.h: Regenerate.
+ * libbfd.h: Regenerate.
+ * Makefile.am: Run "make dep-am"
+ * Makefile.in: Regenerate.
+ * po/SRC-POTFILES.in: Regenerate.
+
+2002-03-20 Daniel Jacobowitz <drow@mvista.com>
+
+ * dwarf2.c (struct funcinfo): Move up.
+ (lookup_address_in_function_table): New argument function_ptr.
+ Set it.
+ (lookup_address_in_line_table): New argument function. If function
+ is non-NULL, use it to handle ``addr'' before the first line note of
+ the function.
+ (comp_unit_find_nearest_line): Update and swap calls to
+ lookup_address_in_function_table and lookup_address_in_line_table.
+ * syms.c (_bfd_stab_section_find_nearest_line): Use the first
+ N_SLINE encountered if we see an N_FUN before any N_SLINE.
+
+2002-03-20 Tom Rix <trix@redhat.com>
+
+ * coff-rs6000.c (_bfd_xcoff_stat_arch_elt): Renamed from
+ _bfd_xcoff_generic_stat_arch_elt. Fix format check.
+ * coff64-rs6000.c : Use _bfd_xcoff_stat_arch_elt.
+
+2002-03-19 Tom Rix <trix@redhat.com>
+
+ * xcofflink.c (_bfd_xcoff_bfd_link_add_symbols): Look through all
+ dynamic objects in archives.
+
+2002-03-19 Hans-Peter Nilsson <hp@bitrange.com>
+
+ * elflink.h (NAME(bfd_elf,record_link_assignment)): Don't set
+ STT_NOTYPE symbols to STT_OBJECT.
+
+2002-03-18 Jan Hubicka <jh@suse.cz>
+
+ * cpu-i386.c (bfd_x86_64_arch): Rename to "i386:x86-64"
+
+2002-03-18 Tom Rix <trix@redhat.com>
+
+ * aix5ppc.core.c : New file for AIX 5 64 bit core support.
+ * bfd-in.h : Add bfd_xcoff_ar_archive_set_magic declaration.
+ * coff-rs6000 (do_pad) : New function for archive padding.
+ (do_copy) : New function for object file copying in archives.
+ (do_shared_object_padding) : New function for padding shared
+ objects to their text section alignment in archives.
+ (bfd_xcoff_ar_achive_set_magic) : Stub.
+ (xcoff_write_armap_big) : Use do_copy and do_pad.
+ (xcoff_write_archive_contents_big) : Use do_shared_object_padding,
+ do_copy and do_pad.
+ * coff64-rs6000.c (xcoff64_write_ojbect_contents) : Use
+ bfd_xcoff_magic_number.
+ (xcoff64_bad_format_hook) : New function for _bfd_bad_format_hook
+ fop.
+ (xcoff_backend_data_r) : Use xcoff64_bad_format_hook.
+ (bfd_xcoff_aix5_backend_data) : New Aix 5 backend data.
+ (aix5coff64_vec) : New Aix 5 target aix5coff64-rs6000.
+ * rs6000-core.c : Update copyright date.
+ * xcofflink.c (bfd_xcoff_size_dynamic_sections): Check for NULL
+ csectpp.
+ * coffcode.h (coff_new_section_hook) : Use new accessor macros.
+ (coff_set_arch_mach_hook) : Add Aix 5 U64_TOCMAGIC magic #.
+ (coff_set_flags) : Use bfd_xcoff_magic_number.
+ * libxcoff.h (bfd_xcoff_is_xcoff64): Add U64_TOCMAGIC.
+ * configure.in : Add powerpc-*-aix5 and rs6000-*-aix5 support.
+ * Makefile.am : Same.
+ * config.bfd : Same.
+ * targets.c : Same.
+ * configure : Regnerate.
+ * Makefile.in : Same.
+ * bfd-in2.h : Same.
+
+2002-03-18 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * po/fr.po: Updated version.
+
+2002-03-18 Alan Modra <amodra@bigpond.net.au>
+
+ * libbfd.c (bfd_write_bigendian_4byte_int): Return true iff success.
+ * libbfd.h: Regenerate.
+ * archive.c (coff_write_armap): Pass on failures from
+ bfd_write_bigendian_4byte_int.
+
+2002-03-14 H.J. Lu <hjl@gnu.org>
+
+ * elflink.h (NAME(bfd_elf,size_dynamic_sections)): Set the BFD
+ error to bfd_error_nonrepresentable_section for reinit_array
+ section in DSO.
+
+2002-03-14 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * coffcode.h (coff_slurp_symbol_table): When adding BSF_WEAK flag,
+ OR it in rather than replacing previously selected flags.
+
+ * elfxx-target.h (TARGET_BIG_SYM): Set ar_max_namelen to 15.
+ (TARGET_LITTLE_SYM): Set ar_max_namelen to 15.
+
+2002-03-14 Alan Modra <amodra@bigpond.net.au>
+
+ * cpu-mips.c (mips_compatible): New. Don't check bits_per_word.
+ (N): Use the above.
+ * elflink.h (elf_bfd_final_link): Revert last change. Instead,
+ ensure reloc size matches before calling elf_link_input_bfd.
+ Add an assert to check reloc size when counting output relocs.
+
+2002-03-14 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * mmo.c (mmo_get_loc): Return NULL rather than false.
+
+2002-03-13 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * po/fr.po: Updated version.
+
+2002-03-13 Alan Modra <amodra@bigpond.net.au>
+
+ * archures.c (bfd_default_compatible): Test bits_per_word.
+ * cpu-i386.c (i386_compatible): Remove. Replace occurrences with
+ bfd_default_compatible.
+ * cpu-i370.c (i370_compatible): Likewise.
+ * cpu-sparc.c (sparc_compatible): Likewise.
+ * cpu-h8300.c (compatible): Test in->arch == out->arch.
+
+ * elflink.h: Formatting fixes.
+ (elf_link_output_extsym): Merge undefined and undef weak cases.
+
+ * elflink.h (elf_bfd_final_link): Only call elf_link_input_bfd
+ when word size of input matches output word size.
+
+2002-03-12 Andreas Jaeger <aj@suse.de>
+
+ * cpu-i386.c (i386_compatible): New. Use it instead of
+ bfd_default_compatible.
+
+2002-03-07 H.J. Lu (hjl@gnu.org)
+
+ * coff-sh.c (shcoff_reloc_map): Use bfd_reloc_code_real_type
+ as the type for bfd_reloc_val.
+
+2002-03-05 John David Anglin <dave@hiauly1.hia.nrc.ca>
+
+ * elf-hppa.h (elf_hppa_is_dynamic_loader_symbol): New function.
+ (elf_hppa_relocate_section): Ignore undefined dynamic loader symbols.
+ (elf_hppa_final_link_relocate): Correct relocations for indirect
+ references to local data through the DLT. Fix .opd creation for
+ local symbols using R_PARISC_LTOFF_FPTR32 and R_PARISC_FPTR64
+ relocations. Use e_lsel selector for R_PARISC_DLTIND21L,
+ R_PARISC_LTOFF_FPTR21L and R_PARISC_LTOFF_TP21L as per
+ "Processor-Specific ELF for PA_RISC, Version 1.43" document.
+ Similarly, use e_rsel for DLT and LTOFF 'R' relocations.
+ * elf32-hppa.c (final_link_relocate): Revise relocation selectors
+ as per "Processor-Specific ELF for PA_RISC, Version 1.43" document.
+
+2002-03-05 Jakub Jelinek <jakub@redhat.com>
+
+ * merge.c (_bfd_merge_sections): Don't segfault if there
+ is nothing to merge due to GC.
+
+2002-03-05 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-hppa.c (clobber_millicode_symbols): Remove hack to keep
+ symbols that have been forced local.
+
+ * elflink.h (elf_bfd_final_link): Call elf_link_output_extsym
+ to output forced local syms for non-shared link.
+ (elf_link_output_extsym): Tweak condition for calling backend
+ adjust_dynamic_symbol so that previous behaviour is kept.
+ Whitespace changes throughout file.
+
+2002-03-04 H.J. Lu <hjl@gnu.org>
+
+ * elf.c (bfd_section_from_shdr): Handle special sections,
+ .init_array, .fini_array and .preinit_array.
+ (elf_fake_sections): Likewise.
+
+ * elflink.h (NAME(bfd_elf,size_dynamic_sections)): Create the
+ DT entry only if the section is in output for .init_array,
+ .fini_array and .preinit_array. Complain about .preinit_array
+ section in DSO.
+ (elf_bfd_final_link): Warn zero size for .init_array,
+ .fini_array and .preinit_array sections.
+
+ * elfxx-ia64.c (elfNN_ia64_section_from_shdr): Remove
+ SHT_INIT_ARRAY, SHT_FINI_ARRAY and SHT_PREINIT_ARRAY.
+ (elfNN_ia64_fake_sections): Remove .init_array, .fini_array and
+ .preinit_array.
+
+2002-03-04 Alan Modra <amodra@bigpond.net.au>
+
+ * configure.in (WIN32LIBADD): Don't eval PICFLAG assignment.
+ * configure: Regenerate.
+
+2002-03-02 Tom Rix <trix@redhat.com>
+
+ * coff64-rs6000.c (xcoff64_howto_table): Replace howto types with
+ symbolic equiv.
+ * coff-rs6000.c (xcoff_howto_table): Same.
+
+2002-03-01 David Mosberger <davidm@hpl.hp.com>
+
+ * elflink.h (size_dynamic_sections): If section named
+ ".preinit_array" exists, create DT_PREINIT_ARRAY and
+ DT_PREINIT_ARRAYSZ entries in dynamic table. Analogously for
+ ".init_array" and ".fini_array".
+ (elf_bfd_final_link): Handle DT_PREINIT_ARRAYSZ, DT_INIT_ARRAYSZ,
+ DT_FINI_ARRAYSZ, DT_PREINIT_ARRAY, DT_INIT_ARRAY, and
+ DT_FINI_ARRAY.
+
+2002-02-26 Andrew Macleod <amacleod@cygnus.com>
+
+ * elflink.h (elf_bfd_final_link): Don't crash on SHN_UNDEF local
+ dynsyms.
+
+2002-02-25 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-hppa.h: Update copyright date.
+
+ * elf64-ppc.c (ppc64_elf_check_relocs): Warning fix.
+ (ppc64_elf_relocate_section): Don't generate power4 style branch
+ hints for *_BRTAKEN and *_BRNTAKEN relocs.
+
+2002-02-22 Jakub Jelinek <jakub@redhat.com>
+
+ * elf64-sh64.c (sh_elf64_relocate_section): Fix a typo from my
+ last patch.
+ * elf64-x86-64.c (elf64_x86_64_relocate_section): Likewise.
+
+2002-02-21 Andreas Jaeger <aj@suse.de>
+
+ * elf64-x86-64.c: Major rework that introduces all recent changes
+ to the x86-64 backend. Get a closer match to elf32-i386.
+ (struct elf64_x86_64_dyn_relocs): Rename from
+ elf64_x86_64_pcrel_relocs_copied, add additional fields. Change
+ all users.
+ (struct elf64_x86_64_link_hash_table): Add short cuts to some
+ sections.
+ (link_hash_newfunc): Rename from elf64_x86_64_link_hash_newfunc,
+ remove casts, initialize new hash members.
+ (create_got_section): New.
+ (elf64_x86_64_create_dynamic_sections): New.
+ (elf64_x86_64_copy_indirect_symbol): New.
+ (elf64_x86_64_check_relocs): Don't allocate space for dynamic
+ relocs, .got or .relgot here but do it in allocate_dynrelocs.
+ Reference count possible .plt and .got entries. Don't test input
+ section SEC_READONLY here to try to avoid copy relocs, and keep
+ dyn_relocs regardless of ELF_LINK_NON_GOT_REF. Don't set
+ DF_TEXTREL here. Delay setting of variables until needed. Cache
+ pointer to "sreloc" section in elf_section_data. Tweak condition
+ under which .got created. Report files with bad relocation
+ section names.
+ (elf64_x86_64_gc_sweep_hook): Sweep dyn_relocs and local_dynrel.
+ Reference count possible .plt entries. Don't deallocate .got and
+ .relgot space here.
+ (elf64_x86_64_adjust_dynamic_symbol): Handle nocopyreloc. Don't
+ do copy reloc processing for weakdefs. Remove redundant casts and
+ aborts. Delay setting of vars until needed. Move creation of
+ dynamic symbols and allocation of .plt and .rela.plt to
+ allocate_dynrelocs. Replace BFD_ASSERT with abort.
+ (WILL_CALL_FINISH_DYNAMIC_SYMBOL): New.
+ (allocate_dynrelocs): New.
+ (readonly_dynrelocs): New.
+ (elf64_x86_64_size_dynamic_sections): Call readonly_dynrelocs.
+ Allocate space for dyn relocs. Replace BFD_ASSERT with abort.
+ Zero out the dynamic allocated content space.
+ (elf64_x86_64_discard_copies): Removed.
+ (elf64_x86_64_relocate_section): Make use of dynamic section
+ short-cuts. Localise vars, and delay setting. Better error
+ reporting, replace BFD_ASSERT with abort. Check
+ ELF_LINK_HASH_DEF_DYNAMIC to see if a symbol is not defined in the
+ regular object file and tread the weak definition as the normal
+ one. Don't discard relocs for undefweak or undefined symbols and
+ check !DEF_REGULAR as well as DEF_DYNAMIC in test for avoided copy
+ relocs.
+ (elf64_x86_64_finish_dynamic_symbol): Don't copy relocs for
+ symbols that have been forced local. Use same test to decide if
+ we can use a relative reloc for got as relocate_section. Expand
+ SHN_UNDEF comment. Move expressions out of function calls.
+ Replace BFD_ASSERT with abort.
+ (bfd_elf64_bfd_final_link): Removed.
+ (elf_backend_copy_indirect_symbol): Define.
+
+2002-02-20 Tom Rix <trix@redhat.com>
+
+ * coff-rs6000.c (xcoff_howto_table): Add 16 bit R_BA.
+ (_bfd_xcoff_reloc_type_lookup): Use it.
+ * coff64-rs6000.c (xcoff64_howto_table): Same.
+ (xcoff64_reloc_type_lookup): Same.
+
+2002-02-20 Peter Schauer <pes@regent.e-technik.tu-muenchen.de>
+
+ * osf-core.c (osf_core_vec): OSF/1 (Digital Unix) core files are
+ little endian.
+
+2002-02-19 Martin Schwidefsky <schwidefsky@de.ibm.com>
+
+ * archures.c (bfd_mach_s390_esa): Rename to bfd_mach_s390_31.
+ (bfd_mach_s390_esame): Rename to bfd_mach_s390_64.
+ * bfd-in2.h: Regenerate.
+ * cpu-s390.c (arch_info_struct): Use renamed architecture defines.
+ Replace architecture name "s390" with "s390:31-bit" and "s390:esame"
+ with "s390:64-bit".
+ * elf32-s390.c (elf_howto_table): Add 32 bit pc relative relocations.
+ (elf_s390_reloc_type_lookup): Likewise.
+ (elf_s390_check_relocs): Likewise.
+ (elf_s390_gc_sweep_hook): Likewise.
+ (elf_s390_relocate_section): Likewise.
+ (elf_s390_object_p): Use renamed architecture define.
+ * elf64-s390.c (elf_s390_object_p): Use renamed architecture define.
+
+2002-02-19 Frank Ch. Eigler <fche@redhat.com>
+
+ * syms.c (stt[]): Sorted. Added .init/.fini -> "t" mapping.
+
+2002-02-19 Jakub Jelinek <jakub@redhat.com>
+
+ * elf-eh-frame.c (_bfd_elf_discard_section_eh_frame): Enable
+ absptr -> pcrel optimization for shared libs.
+ Only create minimal .eh_frame_hdr if absptr FDE encoding in shared
+ library cannot be converted to pcrel.
+ (_bfd_elf_eh_frame_section_offset): Return -2 if making absptr
+ relative.
+ * elf32-i386.c (elf_i386_relocate_section): If
+ _bfd_elf_section_offset returned -2, skip, but make sure the
+ relocation is installed.
+ * elf32-arm.h (elf32_arm_final_link_relocate): Likewise.
+ * elf32-cris.c (cris_elf_relocate_section): Likewise.
+ * elf32-hppa.c (elf32_hppa_relocate_section): Likewise.
+ * elf32-i370.c (i370_elf_relocate_section): Likewise.
+ * elf32-m68k.c (elf_m68k_relocate_section): Likewise.
+ * elf32-ppc.c (ppc_elf_relocate_section): Likewise.
+ * elf32-s390.c (elf_s390_relocate_section): Likewise.
+ * elf32-sh.c (sh_elf_relocate_section): Likewise.
+ * elf32-sparc.c (elf32_sparc_relocate_section): Likewise.
+ * elf64-ppc.c (ppc64_elf_relocate_section): Likewise.
+ * elf64-s390.c (elf_s390_relocate_section): Likewise.
+ * elf64-sh64.c (sh_elf64_relocate_section): Likewise.
+ * elf64-sparc.c (sparc64_elf_relocate_section): Likewise.
+ * elf64-x86-64.c (elf64_x86_64_relocate_section): Likewise.
+ * elf64-alpha.c (elf64_alpha_relocate_section): Handle
+ _bfd_elf_section_offset returning -2 the same way as -1.
+ * elfxx-ia64.c (elfNN_ia64_install_dyn_reloc): Likewise.
+ * elf32-mips.c (mips_elf_create_dynamic_relocation): Add FIXME
+ and BFD_ASSERT.
+ * elf64-mips.c (mips_elf64_create_dynamic_relocation): Likewise.
+
+2002-02-18 Tom Rix <trix@redhat.com>
+
+ * xcofflink.c (bfd_xcoff_link_gernate_rtinit): Add -brtl support.
+ (bfd_xcoff_size_dynamic_sections): Same.
+ * bfd-in.h (bfd_xcoff_link_generate_rtinit): Same.
+ (bfd_xcoff_size_dynamic_sections): Same.
+ * coff-rs6000.c (xcoff_generate_rtinit): Same.
+ * coff-rs646000.c (xcoff64_generate_rtinit): Same.
+ * libxcoff.h (struct xcoff_backend_data_rec): Same.
+ * xcofflink.c (xcoff_build_ldsyms, xcoff_link_add_symbols): Clean.
+ * bfd-in2.h: Regenerate.
+
+2002-02-18 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (STFD_FR0_0R1, LFD_FR0_0R1, BLR): Define.
+ (struct ppc_link_hash_table): Add sfpr.
+ (ppc64_elf_link_hash_table_create): Init it.
+ (ppc64_elf_create_dynamic_sections): Split creation of .stub and
+ .glink out to..
+ (create_linkage_sections): ..here. Make .sfpr too.
+ (ppc64_elf_check_relocs): Call create_linkage_sections, and set
+ dynobj early.
+ (MIN_SAVE_FPR, MAX_SAVE_FPR): Define.
+ (ppc64_elf_func_desc_adjust): Look for missing ._savef* and
+ ._restf* functions, and create as needed.
+ (func_desc_adjust): Only force_local for shared libs.
+
+2002-02-18 David O'Brien <obrien@FreeBSD.org>
+
+ * configure.in: Bump version number post 2.12 branching.
+ * configure: Regenerate.
+
+2002-02-17 Hans-Peter Nilsson <hp@bitrange.com>
+
+ * mmo.c: Correct and improve comments.
+ (mmo_write_chunk): Store trailing byte in bfd buffer; don't
+ zero-pad. Use input to fill up non-empty bfd buffer.
+ (mmo_flush_chunk): New function.
+ (mmo_write_loc_chunk): Add parameter last_vmap, all callers
+ changed. Don't emit location specifier if VMA is same as
+ *LAST_VMAP after omitting leading zero contents. Call
+ mmo_flush_chunk before emitting location specifier.
+ (mmo_write_loc_chunk_list): Call mmo_flush_chunk when finished
+ with mmo_write_loc_chunk calls.
+ (mmo_internal_write_section): Call mmo_flush_chunk after
+ mmo_write_chunk.
+ (mmo_write_symbols_and_terminator): Move :Main to first position
+ in symbol array. Add faked one if it does not exist if there are
+ other symbols. Don't add it if there are no symbols at all. Move
+ out test for value of :Main from symbol loop. Rename table
+ fakemain to maintable and variable mainsym to fakemain.
+
+2002-02-15 Richard Henderson <rth@redhat.com>
+
+ * elf64-alpha.c (elf64_alpha_relocate_section) [BRSGP]: A target
+ section with no got matches any got. Simplify error generaion.
+
+2002-02-15 Alan Modra <amodra@bigpond.net.au>
+
+ Support arbitrary length fill patterns.
+ * linker.c (bfd_new_link_order): Zero all fields with bfd_zalloc.
+ (_bfd_default_link_order): Remove bfd_fill_link_order code.
+ Call default_data_link_order.
+ (default_fill_link_order): Delete.
+ (default_data_link_order): New function.
+ * elf32-mips.c (_bfd_mips_elf_final_link): Replace occurrences
+ of bfd_fill_link_order with bfd_data_link_order.
+ * elf64-alpha.c (elf64_alpha_final_link): Likewise.
+ * elf64-mips.c (mips_elf64_final_link): Likewise.
+
+ * bfd.c (bfd_scan_vma): Clamp overflows to max bfd_vma value.
+ Correct value returned in "end" for "0x<non-hex>".
+
+2002-02-14 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * cpu-arm.c (processors): Replace 'arch' field with 'mach'.
+ (scan): Test against 'mach' field in info structure.
+
+2002-02-14 Alan Modra <amodra@bigpond.net.au>
+
+ * elf.c (elf_fake_sections): Use SHT_NOBITS when SEC_NEVER_LOAD.
+
+2002-02-14 Matt Fredette <fredette@netbsd.org>
+
+ * elf32-m68k.c (elf32_m68k_print_private_bfd_data): Recognize
+ EF_M68000.
+
+2002-02-13 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * elf.c (_bfd_elf_make_section_from_shdr): Do not insist on
+ non-zero physical addresses when adjusting the LMAs of new
+ sections.
+
+2002-02-12 John David Anglin <dave@hiauly1.hia.nrc.ca>
+
+ * elf-hppa.h (elf_hppa_reloc_final_type): New function stripped
+ from _bfd_elf_hppa_gen_reloc_type.
+ (_bfd_elf_hppa_gen_reloc_type): Remove duplicate prototype.
+ * elf32-hppa.h (elf32_hppa_reloc_final_type): Add protptype.
+ * elf32-hppa.c: Include elf32-hppa.h before elf-hppa.h.
+ * elf64-hppa.h (elf64_hppa_reloc_final_type): Add protptype.
+
+2002-02-12 Alexandre Oliva <aoliva@redhat.com>
+
+ * elf-m10300.c (mn10300_elf_relax_section): Skip section before
+ loading its contents if there's nothing to do in it.
+
+2002-02-12 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (ppc64_elf_size_stubs): Correct test for crossing
+ 64k boundary.
+
+ * elf64-ppc.c (ppc64_elf_size_dynamic_sections): Add dynamic
+ DT_PPC64_OPD and DT_PPC64_OPDSZ tags.
+ (ppc64_elf_finish_dynamic_sections): Set values for them.
+
+2002-02-11 Michael Snyder <msnyder@redhat.com>
+
+ * elf-bfd.h (elfcore_write_lwpstatus): Add prototype.
+ * elf.c (elfcore_grok_pstatus): Add prototype.
+ (elfcore_grok_lwpstatus): Add prototype.
+ (elfcore_write_lwpstatus): New function.
+ (elfcore_write_pstatus): Fix typo, eliminate unnecessary memcpy.
+
+2002-02-11 Alexandre Oliva <aoliva@redhat.com>
+
+ * elf32-sh.c: Added missing prototypes.
+ * elf32-sh64.c: Likewise.
+ (sh_elf_align_loads): Mark unused args as such.
+ * elf64-sh64.c: Added missing prototypes.
+ (struct elf_sh64_link_hash_entry): Fix typo.
+ (sh_elf64_relocate_section): Fix info argument passed to
+ _bfd_elf_section_offset.
+
+2002-02-11 Alan Modra <amodra@bigpond.net.au>
+
+ * Makefile.am: "make dep-am".
+ * Makefile.in: Regenerate.
+ * aclocal.m4: Regenerate.
+ * config.in: Regenerate.
+ * configure: Regenerate.
+
+2002-02-10 Daniel Jacobowitz <drow@mvista.com>
+
+ * coff-rs6000.c (xcoff_generate_rtinit): Silence uninitialized
+ variable warnings.
+ * elf32-sh.c (sh_elf_relax_section): Silence signed/unsigned
+ comparison warning.
+ * trad-core.c (trad_unix_core_file_p): Silence pointer/integer
+ cast warnings for the common case.
+
+2002-02-10 Hans-Peter Nilsson <hp@bitrange.com>
+
+ * config.bfd (sh-*-linux*, sh-*-elf* | sh-*-rtemself*): Add sh64
+ vectors.
+ (sh-*-netbsdelf*): New, to trump sh*-*-netbsdelf* and add sh64
+ vectors.
+
+2002-02-09 Richard Henderson <rth@redhat.com>
+
+ * elf64-alpha.c (elf64_alpha_howto): Add R_ALPHA_BRSGP.
+ (elf64_alpha_reloc_map, elf64_alpha_check_relocs): Likewise.
+ (elf64_alpha_relocate_section): Likewise.
+ * reloc.c (BFD_RELOC_ALPHA_BRSGP): New.
+ * bfd-in2.h, libbfd.h: Rebuild.
+
+2002-02-09 Hans-Peter Nilsson <hp@bitrange.com>
+
+ * elf64-mmix.c (_bfd_mmix_finalize_linker_allocated_gregs): Check
+ that base-plus-offset reloc accounting is consistent.
+ (mmix_elf_relax_section): Keep base-plus-offset reloc accounting
+ up to date for undefined symbols.
+
+2002-02-08 Eric Christopher <echristo@redhat.com>
+
+ From Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * elf32-mips.c (_bfd_mips_elf_fake_sections): Don't create .rela
+ sections for the O32 ABI.
+
+2002-02-08 Chris Demetriou <cgd@broadcom.com>
+
+ * elf32-arm.h: Fix formatting of _("...").
+ * elf32-d10v.c: Likewise.
+ * elf32-m68k.c: Likewise.
+ * elf32-mips.c: Likewise.
+
+2002-02-08 Ivan Guzvinec <ivang@opencores.org>
+
+ * coff-or32.c: Fix compile time warning messages.
+
+2002-02-08 Alexandre Oliva <aoliva@redhat.com>
+
+ Contribute sh64-elf.
+ 2002-01-23 Alexandre Oliva <aoliva@redhat.com>
+ * reloc.c (R_SH_GOTPLT32, R_SH_GOT_LOW16, R_SH_GOT_MEDLOW16,
+ R_SH_GOT_MEDHI16, R_SH_GOT_HI16, R_SH_GOTPLT_LOW16,
+ R_SH_GOTPLT_MEDLOW16, R_SH_GOTPLT_MEDHI16, R_SH_GOTPLT_HI16,
+ R_SH_PLT_LOW16, R_SH_PLT_MEDLOW16, R_SH_PLT_MEDHI16,
+ R_SH_PLT_HI16, R_SH_GOTOFF_LOW16, R_SH_GOTOFF_MEDLOW16,
+ R_SH_GOTOFF_MEDHI16, R_SH_GOTOFF_HI16, R_SH_GOTPC_LOW16,
+ R_SH_GOTPC_MEDLOW16, R_SH_GOTPC_MEDHI16, R_SH_GOTPC_HI16,
+ R_SH_GOT10BY4, R_SH_GOTPLT10BY4, R_SH_GOT10BY8, R_SH_GOTPLT10BY8,
+ R_SH_COPY64, R_SH_GLOB_DAT64, R_SH_JMP_SLOT64, R_SH_RELATIVE64):
+ New relocs.
+ * libbfd.h, bfd-in2.h: Rebuilt.
+ * elf32-sh.c (sh_elf_howto_table): Define new relocs.
+ (sh_reloc_map): Map them.
+ (PLT_ENTRY_SIZE, elf_sh_plt0_entry_be, elf_sh_plt0_entry_le,
+ elf_sh_plt_entry_be, elf_sh_plt_entry_le, elf_sh_pic_plt_entry_be,
+ elf_sh_pic_plt_entry_le, elf_sh_plt0_entry, elf_sh_plt_entry,
+ elf_sh_pic_plt_entry, elf_sh_sizeof_plt, elf_sh_plt_plt0_offset,
+ elf_sh_plt0_gotplt_offset, elf_sh_plt_temp_offset,
+ elf_sh_plt_symbol_offset, elf_sh_plt_reloc_offset,
+ movi_shori_putval) [INCLUDE_SHMEDIA]: New.
+ (elf_sh_link_hash_entry) [INCLUDE_SHMEDIA]: Add
+ datalabel_got_offset.
+ (sh_elf_link_hash_newfunc): Initialize it.
+ (sh_elf_relocate_section): Augment the scope of
+ seen_stt_datalabel. Introduce GOTPLT support. Extend GOTPC, PLT,
+ GOT and GOTOFF handling to new SHmedia relocation types. Support
+ GOT_BIAS.
+ (sh_elf_check_relocs): Likewise.
+ (sh_elf_finish_dynamic_symbol) [TARGET_SHMEDIA]: Set up values in
+ PLT entries using movi_shori_putval. Support GOT_BIAS.
+ (sh_elf_finish_dynamic_sections): Likewise.
+ * elf32-sh64.c (shmedia_prepare_reloc): Do not add addend to
+ relocation, it's now done by the caller.
+ (GOT_BIAS): New.
+ * elf64-sh64.c (GOT_BIAS, PLT_ENTRY_SIZE, elf_sh64_sizeof_plt,
+ elf_sh64_plt_plt0_offset, elf_sh64_plt0_gotplt_offset,
+ elf_sh64_plt_temp_offset, elf_sh64_plt_symbol_offset,
+ elf_sh64_plt_reloc_offset, ELF_DYNAMIC_INTERPRETER,
+ elf_sh64_pcrel_relocs_copied, elf_sh64_link_hash_entry,
+ elf_sh64_link_hash_table, sh64_elf64_link_hash_traverse,
+ sh64_elf64_hash_table): New.
+ (sh_elf64_howto_table): Introduce new relocs.
+ (sh_elf64_info_to_howto): Accept new PIC relocs.
+ (sh_elf64_relocate_section): Augment the scope of
+ seen_stt_datalabel. Support new PIC relocs.
+ (sh_elf64_check_relocs): Support new PIC relocs.
+ (elf_sh64_plt0_entry_be, elf_sh64_plt0_entry_le,
+ elf_sh64_plt_entry_be, elf_sh64_plt_entry_le,
+ elf_sh64_pic_plt_entry_be, elf_sh64_pic_plt_entry_le,
+ elf_sh64_plt0_entry, elf_sh64_plt_entry, elf_sh64_pic_plt_entry,
+ sh64_elf64_link_hash_newfunc, sh64_elf64_link_hash_table_create,
+ movi_shori_putval, movi_3shori_putval,
+ sh64_elf64_create_dynamic_sections,
+ sh64_elf64_adjust_dynamic_symbol, sh64_elf64_discard_copies,
+ sh64_elf64_size_dynamic_sections,
+ sh64_elf64_finish_dynamic_symbol,
+ sh64_elf64_finish_dynamic_sections): New.
+ (elf_backend_create_dynamic-sections,
+ bfd_elf64_bfd_link_hash_table_create,
+ elf_backend_adjust_dynamic_symbol,
+ elf_backend_size_dynamic_sections,
+ elf_backend_finish_dynamic_symbol,
+ elf_backend_finish_dynamic_sections, elf_backend_want_got_plt,
+ elf_backend_plt_readonly, elf_backend_want_plt_sym,
+ elf_backend_got_header_size, elf_backend_plt_header_size):
+ Define.
+ 2001-05-16 Alexandre Oliva <aoliva@redhat.com>
+ * elf32-sh.c: Renumbered and renamed some SH5 relocations to
+ match official numbers and names; moved unmaching ones to the
+ range 0xf2-0xff.
+ * elf32-sh64.c, elf64-sh64.c: Likewise.
+ 2001-03-12 DJ Delorie <dj@redhat.com>
+ * elf32-sh.c (sh_elf_relax_section): Don't relax SHmedia
+ sections.
+ 2001-03-12 DJ Delorie <dj@redhat.com>
+ * elf32-sh64.c (shmedia_prepare_reloc): Validate relocs that must
+ be aligned.
+ * elf64-sh64.c (sh_elf64_relocate_section): Ditto.
+ 2001-01-14 Hans-Peter Nilsson <hpn@cygnus.com>
+ * elf32-sh64.c (bfd_elf32_bfd_copy_private_section_data): Define.
+ (sh64_elf_fake_sections): Set type to SHT_SH5_CR_SORTED for a
+ .cranges section with SEC_SORT_ENTRIES set.
+ (sh64_backend_section_from_shdr): Set SEC_SORT_ENTRIES on an
+ incoming sorted .cranges section.
+ (sh64_bfd_elf_copy_private_section_data): New.
+ (sh64_elf_final_write_processing): Only sort .cranges and modify
+ start address if called by linker.
+ 2001-01-08 Ben Elliston <bje@redhat.com>
+ * elf32-sh64.c (sh64_elf_final_write_processing): Activate
+ Hans-Peter Nilsson's set bit 0 patch from 2001-01-06.
+ * elf64-sh64.c (sh64_elf64_final_write_processing): Ditto.
+ 2001-01-06 Hans-Peter Nilsson <hpn@cygnus.com>
+ * elf64-sh64.c (sh_elf64_howto_table): No open brace at start of
+ line. Add comments before all entries.
+ <R_SH_PT_16, R_SH_SHMEDIA_CODE>: Correct and clarify describing
+ comment.
+ (sh_elf64_reloc): Correct head comment.
+ (sh_elf64_relocate_section): Correct spacing.
+ <relocating for a local symbol>: Do not honour STO_SH5_ISA32;
+ instead call reloc_dangerous callback.
+ <case R_SH_SHMEDIA_CODE>: New case.
+ (sh_elf64_gc_mark_hook): Correct spacing.
+ (sh_elf64_check_relocs): Ditto.
+ * elf32-sh64.c (shmedia_prepare_reloc) <case R_SH_SHMEDIA_CODE>:
+ New case.
+ * elf32-sh.c: Correct #endif comments for #ifndef-wrapped
+ functions.
+ (sh_elf_howto_table) <R_SH_PT_16, R_SH_SHMEDIA_CODE>: Correct,
+ clarify describing comment. Add comments before all entries.
+ (sh_elf_relocate_section) <relocating for a local symbol>: Do not
+ honour STO_SH5_ISA32; instead call reloc_dangerous callback.
+ 2001-01-06 Hans-Peter Nilsson <hpn@cygnus.com>
+ Sort .cranges section in final link. Prepare to set bit 0 on
+ entry address.
+ * elf32-sh64.c (struct sh64_find_section_vma_data): New.
+ (sh64_elf_link_output_symbol_hook): Fix typo in prototype.
+ (sh64_elf_set_mach_from_flags): Set SEC_DEBUGGING on incoming
+ .cranges section.
+ (sh64_backend_section_from_shdr): New, to recognize
+ SHT_SH5_CR_SORTED on incoming .cranges section.
+ (elf_backend_section_from_shdr): Define.
+ (sh64_elf_final_write_processing): Sort outgoing .cranges
+ section. (New, temporarily disabled:) Set bit 0 on entry address
+ according to ISA type.
+ (sh64_find_section_for_address): New.
+ (crange_qsort_cmpb, crange_qsort_cmpl, crange_bsearch_cmpb,
+ crange_bsearch_cmpl): Move here from opcodes/sh64-dis.c.
+ (sh64_address_in_cranges): Move here from opcodes/sh64-dis.c. Use
+ bfd_malloc, not xmalloc.
+ (sh64_get_contents_type): Move here from opcodes/sh64-dis.c. Make
+ global.
+ * elf32-sh64.c (sh64_elf64_final_write_processing): New, (but
+ temporarily disabled) setting bit 0 on entry address.
+ (elf_backend_final_write_processing): Define.
+ 2001-01-05 Hans-Peter Nilsson <hpn@cygnus.com>
+ * elf32-sh.c (sh_elf_howto_table) <R_SH_PT_16>: Adjust fields to
+ be a proper relocation for PTA and PTB rather than a marker.
+ <R_SH_IMMU5, R_SH_IMMS6, R_SH_IMMU6, R_SH_IMMS10, R_SH_IMMS10BY2,
+ R_SH_IMMS10BY4, R_SH_IMMS10BY8, R_SH_IMMS16, R_SH_IMMU16,
+ R_SH_IMM_LOW16, R_SH_IMM_LOW16_PCREL, R_SH_IMM_MEDLOW16,
+ R_SH_IMM_MEDLOW16_PCREL, R_SH_IMM_MEDHI16, R_SH_IMM_MEDHI16_PCREL,
+ R_SH_IMM_HI16, R_SH_IMM_HI16_PCREL, R_SH_64, R_SH_64_PCREL>:
+ Zero src_mask.
+ * elf64-sh64.c: Ditto.
+ (sh_elf64_relocate_section) <case R_SH_PT_16>: New case.
+ * elf32-sh64.c: Include opcodes/sh64-opc.h
+ (shmedia_prepare_reloc): Take a bfd_link_info pointer as first
+ argument. Drop const qualifiers from "bfd *" and "bfd_byte *"
+ parameters. No unused parameters. Caller changed.
+ <case R_SH_PT_16>: New case.
+ * Makefile.am (elf32-sh64.lo): Add dependency on sh64-opc.h.
+ * Makefile.in: Regenerate.
+ 2000-12-30 Hans-Peter Nilsson <hpn@cygnus.com>
+ * elf64-sh64.c (sh64_elf64_fake_sections): Set SHF_SH5_ISA32 for
+ all code sections.
+ (sh_elf64_set_mach_from_flags): Change from EF_SH64 to EF_SH5.
+ (sh64_elf_merge_private_data): Ditto.
+ * elf32-sh64.c (sh64_elf_fake_sections): Use sh64_elf_section_data
+ to access stored section flags.
+ (sh64_elf_final_write_processing): Return immediately unless
+ called by linker. Use sh64_elf_section_data (cranges) to get size
+ of linker-generated cranges entries.
+ (sh64_elf_copy_private_data): Add missing "return true".
+ (sh64_elf_set_mach_from_flags): Change from EF_SH64 to EF_SH5.
+ (sh_elf64_merge_private_data): Ditto.
+ 2000-12-19 Hans-Peter Nilsson <hpn@cygnus.com>
+ * elf64-sh64.c (sh64_elf64_fake_sections): New, copy of
+ elf64-sh64.c:sh64_elf_fake_sections.
+ (elf_backend_fake_sections): Define as sh64_elf64_fake_sections.
+ 2000-12-18 Hans-Peter Nilsson <hpn@cygnus.com>
+ * elf32-sh64.c (sh64_elf_copy_private_data_internal): Delete.
+ (sh64_elf_final_write_processing): New.
+ (elf_backend_final_write_processing): Define.
+ (sh64_elf_fake_sections): Get header flags from tdata field.
+ (sh64_elf_copy_private_data): Do not call
+ sh64_elf_copy_private_data_internal, just copy e_flags field.
+ (sh64_elf_merge_private_data): Do not call
+ sh64_elf_copy_private_data_internal.
+ 2000-12-12 Hans-Peter Nilsson <hpn@cygnus.com>
+ Remove EF_SH64_ABI64, let ELF size make difference.
+ Remove SH64-specific BFD section flag.
+ * elf32-sh64.c (sh64_elf_fake_sections): Recognize section as
+ containing SHmedia through elf_section_data (asect)->tdata
+ non-zero, not using a BFD section flag.
+ (sh64_elf_set_mach_from_flags): Don't recognize EF_SH64_ABI64.
+ (sh64_elf_merge_private_data): Similar.
+ (elf_backend_section_flags): Don't define.
+ (sh64_elf_backend_section_flags): Delete.
+ * elf64-sh64.c (sh_elf64_set_mach_from_flags): Recognize EF_SH64,
+ not EF_SH64_ABI64.
+ (sh_elf64_merge_private_data): Similar.
+ * section.c (Section flags definitions): Don't define
+ SEC_SH_ISA_SHMEDIA.
+ (bfd-in2.h): Regenerate.
+ 2000-12-09 Hans-Peter Nilsson <hpn@cygnus.com>
+ Make DataLabel references work with partial linking.
+ * elf32-sh64.c: Fix formatting.
+ (sh64_elf_link_output_symbol_hook): New.
+ (elf_backend_link_output_symbol_hook): Define to
+ sh64_elf_link_output_symbol_hook.
+ (sh64_elf_add_symbol_hook): Make DataLabel symbol just global
+ undefined if partial linking. Adjust sanity check.
+ * elf64-sh64.c (sh64_elf64_link_output_symbol_hook): New.
+ (elf_backend_link_output_symbol_hook): Define to
+ sh64_elf64_link_output_symbol_hook.
+ (sh64_elf64_add_symbol_hook): Make DataLabel symbol just global
+ undefined if partial linking. Adjust sanity check.
+ 2000-12-07 Hans-Peter Nilsson <hpn@cygnus.com>
+ Implement semantics for inter-file DataLabel references.
+ * elf64-sh64.c (DATALABEL_SUFFIX): Define.
+ (sh64_elf64_add_symbol_hook): New.
+ (sh_elf64_relocate_section): If passing an indirect symbol with
+ st_type STT_DATALABEL on the way to a symbol with st_other
+ STO_SH5_ISA32, do not bitor 1 to the relocation.
+ (elf_backend_add_symbol_hook): Define to
+ sh64_elf64_add_symbol_hook.
+ * elf64-sh32.c: Tweak comments.
+ (DATALABEL_SUFFIX): Define.
+ (sh64_elf_add_symbol_hook): New.
+ (elf_backend_add_symbol_hook): Define to sh64_elf_add_symbol_hook.
+ * elf32-sh.c (sh_elf_relocate_section): If passing an indirect
+ symbol with st_type STT_DATALABEL on the way to a symbol with
+ st_other STO_SH5_ISA32, do not bitor 1 to the relocation.
+ 2000-12-05 Hans-Peter Nilsson <hpn@cygnus.com>
+ Pass through STT_DATALABEL.
+ * elf32-sh64.c (sh64_elf_get_symbol_type): New.
+ (elf_backend_get_symbol_type): Define.
+ * elf64-sh64.c (sh64_elf64_get_symbol_type): New.
+ (elf_backend_get_symbol_type): Define.
+ 2000-11-30 Hans-Peter Nilsson <hpn@cygnus.com>
+ * elf32-sh64.c: Tweak comments.
+ (sh64_elf_copy_private_data_internal): Add prototype.
+ (bfd_elf32_bfd_set_private_flags): Define.
+ (sh64_elf_copy_private_data_internal): Compare machine name, not
+ textual BFD target name, to check whether to copy section flag
+ SHF_SH5_ISA32.
+ (sh64_elf_merge_private_data): Validize bfd_get_arch_size.
+ Tweak section-contents-type-mismatch message.
+ (shmedia_prepare_reloc): Add ATTRIBUTE_UNUSED markers.
+ Validize reloc-types.
+ * elf64-sh64.c: New file.
+ * targets.c (bfd_elf64_sh64_vec, bfd_elf64_sh64l_vec): Declare.
+ * Makefile.am (BFD64_BACKENDS): Add elf64-sh64.lo.
+ (BFD64_BACKENDS_CFILES): Add elf64-sh64.c.
+ Regenerate dependencies.
+ * Makefile.in: Regenerate.
+ * config.bfd (sh64-*-elf*): Add bfd_elf64_sh64_vec and
+ bfd_elf64_sh64l_vec.
+ * configure.in: Handle bfd_elf64_sh64_vec and
+ bfd_elf64_sh64l_vec.
+ * configure: Regenerate.
+ * po/POTFILES.in: Regenerate.
+ * po/bfd.pot: Regenerate.
+ 2000-11-29 Hans-Peter Nilsson <hpn@cygnus.com>
+ * elf32-sh64.c (sh64_elf_set_mach_from_flags): Do not recognize
+ anything else but EF_SH64 and EF_SH64_ABI64.
+ (sh64_elf_merge_private_data): Emit error for anything else but
+ EF_SH64 and EF_SH64_ABI64.
+ * config.bfd: Remove bfd_elf32_shblin_vec and bfd_elf32_shlin_vec
+ from targ_selvecs.
+ * configure.in: Add cofflink.lo to bfd_elf32_sh64_vec and
+ bfd_elf32_sh64l_vec as a temporary measure.
+ * configure: Regenerate.
+ 2000-11-27 Hans-Peter Nilsson <hpn@cygnus.com>
+ * cpu-sh.c (arch_info_struct): Include sh5 item
+ unconditionalized.
+ * config.bfd (sh64-*-elf*): Do not set targ_cflags.
+ Add targ_selvecs bfd_elf32_sh_vec, bfd_elf32_shl_vec,
+ bfd_elf32_shblin_vec and bfd_elf32_shlin_vec.
+ * elf32-sh64.c: Tweak comments.
+ (sh64_elf_set_mach_from_flags): Recognize all machine flags that
+ are proper subsets of SH64 as bfd_mach_sh5. Add EF_SH64_ABI64.
+ (sh64_elf_copy_private_data_internal): Wrap long line.
+ (sh64_elf_merge_private_data): Rewrite to allow objects from
+ SH64 subsets to be linked together.
+ (INCLUDE_SHMEDIA): Define.
+ * elf32-sh.c (sh_elf_relocate_section) <local symbol>:
+ Parenthesize plus-expression inside or-expression.
+ <global symbol>: Ditto.
+ (sh_elf_set_mach_from_flags): Remove code refusing
+ deleted EF_SH64_32BIT_ABI flag.
+ 2000-11-26 Hans-Peter Nilsson <hpn@cygnus.com>
+ * elf32-sh.c (sh_elf_howto_table) <R_SH_IMM_LOW16_PCREL,
+ R_SH_IMM_MEDLOW16_PCREL, R_SH_IMM_MEDHI16_PCREL,
+ R_SH_IMM_HI16_PCREL, R_SH_64_PCREL>: Set pcrel_offset to true.
+ (sh_elf_relocate_section) <local symbol>: Or 1 in
+ calculation of relocation if sym->st_other & STO_SH5_ISA32.
+ <global symbol>: Ditto if h->other & STO_SH5_ISA32.
+ * elf32-sh64.c (shmedia_prepare_reloc): Add rel->r_addend to
+ relocation.
+ 2000-11-24 Hans-Peter Nilsson <hpn@cygnus.com>
+ * Makefile.am (BFD32_BACKENDS): Add elf32-sh64.lo.
+ (BFD32_BACKENDS_CFILES): Add elf32-sh64.c.
+ Regenerate dependencies.
+ * Makefile.in: Regenerate.
+ * archures.c: Add bfd_mach_sh5.
+ * config.bfd: Map targ_cpu sh* to bfd_sh_arch.
+ Handle sh64-*-elf*. Set targ_cflags to -DINCLUDE_SHMEDIA.
+ * configure.in: Handle bfd_elf32_sh64_vec and bfd_elf32_sh64l_vec.
+ * configure: Regenerate.
+ * reloc.c (BFD_RELOC_SH_SHMEDIA_CODE, BFD_RELOC_SH_IMMU5,
+ BFD_RELOC_SH_IMMS6, BFD_RELOC_SH_IMMS6BY32, BFD_RELOC_SH_IMMU6,
+ BFD_RELOC_SH_IMMS10, BFD_RELOC_SH_IMMS10BY2,
+ BFD_RELOC_SH_IMMS10BY4, BFD_RELOC_SH_IMMS10BY8,
+ BFD_RELOC_SH_IMMS16, BFD_RELOC_SH_IMMU16, BFD_RELOC_SH_IMM_LOW16,
+ BFD_RELOC_SH_IMM_LOW16_PCREL, BFD_RELOC_SH_IMM_MEDLOW16,
+ BFD_RELOC_SH_IMM_MEDLOW16_PCREL, BFD_RELOC_SH_IMM_MEDHI16,
+ BFD_RELOC_SH_IMM_MEDHI16_PCREL, BFD_RELOC_SH_IMM_HI16,
+ BFD_RELOC_SH_IMM_HI16_PCREL, BFD_RELOC_SH_PT_16): New relocations.
+ * cpu-sh.c [INCLUDE_SHMEDIA] (arch_info_struct): Define and link
+ in item for SH5.
+ * elf32-sh.c [INCLUDE_SHMEDIA] (sh_elf_howto_table): Add howto items
+ for SHmedia relocs.
+ [INCLUDE_SHMEDIA] (sh_rel): Add mappings for SHmedia relocs.
+ [INCLUDE_SHMEDIA] (sh_elf_relocate_section) [default]: Call
+ shmedia_prepare_reloc, goto final_link_relocate if it returns
+ non-zero, else fail as before.
+ (sh_elf_set_mach_from_flags): Provide function only if not defined
+ as macro. Do not recognize objects with EF_SH64_32BIT_ABI set.
+ (sh_elf_set_private_flags): Provide function only if not defined
+ as a macro.
+ (sh_elf_copy_private_data): Similar.
+ (sh_elf_merge_private_data): Similar.
+ * section.c (SEC_SH_ISA_SHMEDIA): New.
+ * targets.c (bfd_elf32_sh64_vec, bfd_elf32_sh64l_vec): Declare.
+ * elf32-sh64.c: New file.
+ * libbfd.h: Regenerate.
+ * bfd-in2.h: Regenerate.
+ * po/POTFILES.in: Regenerate.
+ * po/bfd.pot: Regenerate.
+ * bfd-in2.h: Regenerate.
+ * libbfd.h: Regenerate.
+
+2002-02-07 Daniel Jacobowitz <drow@mvista.com>
+
+ * bfd-in.h: Update <stdbool.h> check to only see if <stdbool.h> has
+ been included, not drag it in.
+ * bfd-in2.h: Regenerate.
+
+2002-02-06 H.J. Lu (hjl@gnu.org)
+
+ * elf32-mips.c (_bfd_mips_elf_merge_private_bfd_data): Update
+ the mach and ISA fields if necessary.
+
+2002-02-06 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * coffcode.h (coff_set_arch_mach_hook): Select the highest known
+ ARM architecture when an F_ARM_5 flag is detected, since we cannot
+ be sure exactly which architecture this represents.
+
+2002-02-05 Nick Clifton <nickc@redhat.com>
+
+ * po/tr.po: Updated translation.
+
+2002-02-05 Alan Modra <amodra@bigpond.net.au>
+
+ From Jimi X <jimix@watson.ibm.com>
+ * archures (bfd_mach_ppc64): Define.
+ (bfd_powerpc_arch): Rename to bfd_powerpc_archs.
+ (bfd_powerpc_arch): Define.
+ * bfd-in2.h: Regenerate.
+ * cpu-powerpc.c (arch_info_struct): Rename to bfd_powerpc_archs.
+ (bfd_powerpc_arch): Move to tail of bfd_powerpc_archs.
+ (bfd_powerpc_archs): Add default powerpc64 arch.
+
+2002-02-05 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (ppc64_elf_size_dynamic_sections): Check for relocs
+ against section syms in readonly sections. Don't do the global
+ sym check if we find one.
+ * elf64-s390.c (elf_s390_size_dynamic_sections): Likewise.
+ * elf32-hppa.c (elf32_hppa_size_dynamic_sections): Likewise.
+ * elf32-i386.c (elf_i386_size_dynamic_sections): Likewise.
+ * elf32-s390.c (elf_s390_size_dynamic_sections): Likewise.
+ (elf_s390_grok_prstatus): Add missing prototype.
+
+2002-02-04 Hans-Peter Nilsson <hp@bitrange.com>
+
+ * elf64-mmix.c (mmix_dump_bpo_gregs): New function.
+ (mmix_elf_check_common_relocs) <case R_MMIX_BASE_PLUS_OFFSET>:
+ Call bfd_get_section_by_name only once. Initialize
+ bpodata->n_bpo_relocs_this_section.
+ (_bfd_mmix_prepare_linker_allocated_gregs): Remove comment
+ referring to DSOs.
+ (bpo_reloc_request_sort_fn): Don't use difference of values as
+ return-value.
+
+2002-02-02 David O'Brien <obrien@FreeBSD>
+
+ * configure.in: Tweak the FreeBSD 4.x recognition more. Only treat
+ version 4.5 and later the same as 5-CURRENT.
+ * configure: Re-generate.
+
+2002-02-02 Jason Thorpe <thorpej@wasabisystems.com>
+
+ * config.bfd (hppa*-*-netbsd*): New target.
+
+2002-01-31 Philipp Thomas <pthomas@suse.de>
+
+ * coff-arm.c (coff_arm_merge_private_bfd_data): Move ERROR
+ to front of message. Unify messages with elf32-arm.h. Use
+ commas where neccessary.
+ * elf32-arm.h (elf32_arm_merge_private_bfd_data): Use all upcase
+ ERROR in messages. Unify messages with coff-arm.c. Correct
+ VFP/FPA error message.
+ (elf32_arm_print_private_bfd_data): Don't mark APCS-26 and
+ APCS-32 for translation.
+
+2002-02-01 Hans-Peter Nilsson <hp@bitrange.com>
+
+ Perform on-demand global register allocation from
+ R_MMIX_BASE_PLUS_OFFSET relocs.
+ * elf64-mmix.c (struct bpo_reloc_section_info, struct
+ bpo_reloc_request, struct bpo_greg_section_info): New.
+ (mmix_elf_check_common_relocs, mmix_elf_gc_sweep_hook,
+ bpo_reloc_request_sort_fn, mmix_elf_relax_section,
+ _bfd_mmix_check_all_relocs,
+ _bfd_mmix_prepare_linker_allocated_gregs,
+ _bfd_mmix_finalize_linker_allocated_gregs): New functions.
+ (elf_mmix_howto_table): Correct src_mask for most relocs.
+ (mmix_elf_perform_relocation) <case R_MMIX_BASE_PLUS_OFFSET>: New
+ case.
+ (mmix_final_link_relocate) <case R_MMIX_BASE_PLUS_OFFSET>: New
+ case. Fix typo in comment. New label do_mmix_reloc.
+ (mmix_elf_check_relocs): Abuse bfd_link_info member base_file to
+ store first object file with a base-plus-offset reloc. Call
+ mmix_elf_check_common_relocs for the part common with mmo.
+ (mmix_elf_final_link): Write out linker-allocated register
+ contents section.
+ (elf_backend_gc_sweep_hook): Define.
+ (bfd_elf64_bfd_relax_section): Define.
+
+ * mmo.c: Don't include <ctype.h>
+ (mmo_init): Correct init-once logic.
+
+2002-02-01 Tom Rix <trix@redhat.com>
+
+ * config.bfd: Conditionally support <aiaff> for pre AIX 4.3.
+
+2002-02-01 Alan Modra <amodra@bigpond.net.au>
+
+ * Makefile.am: Run "make dep-am"
+ * Makefile.in: Regenerate.
+
+2002-01-31 David O'Brien <obrien@FreeBSD>
+
+ * configure.in: Recognize the differences in core files from FreeBSD
+ 4.{0,1} and later versions of 4.x. This treats 4.2+ the same as
+ 5-CURRENT.
+ * configure: Regenerate.
+
+2002-01-31 Ivan Guzvinec <ivang@opencores.org>
+
+ * coff-or32.c: New file.
+ * cpu-or32.c: New file.
+ * elf32-or32.c: New file.
+ * archures.c: Add support for or32.
+ * targets.c: Add support for or32.
+ * bfd-in2.h: Regenerate.
+ * coffcode.h (coff_set_arch_mach_hook, coff_set_flags,
+ coff_write_object_contents): Add support for or32.
+ * config.bfd: Add target.
+ * configure.in: Add support for or32.
+ * configure: Regenerate.
+ * Makefile.am: Add support for or32.
+ * Makefile.in: Regenerate.
+ * po/SRC-POTFILES.in: Add or32 files.
+ * po/bfd.pot: Regenerate.
+
+2002-01-31 Nick Clifton <nickc@cambridge.redhat.com>
+ Don Lindsay <lindsayd@cisco.com>
+
+ * elf32-mips.c (mips_elf_calculate_relocation): Replace 'return
+ false' with a return of a bfd_reloc_ error code.
+
+2002-01-31 Hans-Peter Nilsson <hp@axis.com>
+
+ * elf32-cris.c (elf_cris_discard_excess_program_dynamics): Don't
+ unexport unreferenced symbols when --export-dynamic. Call
+ _bfd_elf_strtab_delref when unexporting.
+
+2002-01-30 Daniel Jacobowitz <drow@mvista.com>
+
+ * bfd-in.h: Include <stdbool.h> if it is available.
+ * bfd-in2.h: Regenerated.
+
+2002-01-31 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (func_desc_adjust): STV_PROTECTED functions should
+ not go via the plt.
+
+2002-01-30 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * archures.c: Tidy up formatting of embedded comments.
+ * bfd.c: Tidy up formatting of embedded comments.
+ * bfd-in.h: Fix formatting of comments.
+ * reloc.c: Tidy up formatting of ordinary & embedded comments.
+ * section.c: Tidy up formatting of embedded comments.
+ * syms.c: Tidy up formatting of embedded comments.
+ * targets.c: Tidy up formatting of embedded comments.
+
+ * bfd-in2.h: Regenerate.
+
+2002-01-30 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * vms-tir.c (cmd_name): New function.
+ (tir_cmd_name): New function.
+ (etir_sta, etir_sto, etir_opr, etir_stc): Use cmd_name().
+ (tir_opr, tir_ctl, tir_cmd): use tir_cmd_name().
+ Fix formatting.
+
+ * peXXigen.c (pe_print_idata): Rearrange message to aid in
+ translation.
+ (pe_print_pdata): Rearrange message to aid in translation.
+
+ * libbfd.c (warn_deprecated): Rearrange error message to aid in
+ translation.
+
+ * ihex.c (ihex_write_object_contents): Fix spelling typo.
+
+ * ieee.c (ieee_slurp_external_symbols): Remove spurious space.
+
+ * elf64-sparc.c (sparc64_elf_add_symbol_hook): Rearrange error
+ message to aid in translation.
+
+ * elf64-mmix.c (mmix_final_link_relocate): Rearrange error message
+ to aid in translation.
+
+ * elf32-arm.h (elf32_arm_merge_private_bfd_data): Fix typo.
+
+2002-01-30 Philipp Thomas <pthomas@suse.de>
+
+ * coff-arm.c, elf32-elf.h: Unify messages.
+
+2002-01-30 Nick Clifton <nickc@redhat.com>
+
+ * po/sv.po: Updated translation.
+
+2002-01-30 Philipp Thomas <pthomas@suse.de>
+
+ * dwarf2.c (read_abbrev): Use full section name in error message.
+ (decode_line_info): Likewise.
+
+ * elf.c (_bfd_elf_symbol_from_bfd_symbol): Don't translate debugging
+ message.
+
+2002-01-30 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (func_desc_adjust): Only provide missing function
+ descriptor symbols for undefined function code syms. Clear
+ ELF_LINK_NON_ELF so that they can stay weak.
+
+2002-01-29 Chris Demetriou <cgd@broadcom.com>
+ Mitch Lichtenberg <mpl@broadcom.com>
+
+ * bfd-in.h (bfd_mips_elf32_create_embedded_relocs): New prototype.
+ * elf32-mips.c (bfd_mips_elf32_create_embedded_relocs): New function
+ to handle 32-bit ELF embedded reloc (ld --embedded-relocs)
+ generation.
+ * bfd-in2.h: Regenerate.
+
+2002-01-29 Chris Demetriou <cgd@broadcom.com>
+
+ * elf32-mips.c: Add additional comments about HI16 relocation
+ processing.
+ (_bfd_mips_elf_hi16_reloc): Don't subtract address here for
+ pc-relative relocations. (Reverts change made on 2001-10-31.)
+ (_bfd_mips_elf_lo16_reloc): Subtract address of LO16 part here
+ for pc-relative relocations.
+ (mips_elf_calculate_relocation): Add a comment about a kludge
+ in the R_MIPS_GNU_REL_HI16 handling.
+ (_bfd_mips_elf_relocate_section): Implement that kludge;
+ adjust pc-relative HI16 relocation for difference in HI16 and
+ LO16 addresses, since it can't easily be done in
+ mips_elf_calculate_relocation.
+
+2002-01-29 Martin Schwidefsky <schwidefsky@de.ibm.com>
+
+ * elf32-i386 (elf_i386_adjust_dynamic_symbol): Do not replace PLT32
+ relocations with PC32 relocations for undefined or weak symbols.
+ * elf32-s390 (elf_i386_adjust_dynamic_symbol): Likewise.
+ * elf64-s390x (elf_i386_adjust_dynamic_symbol): Likewise.
+
+2002-01-28 Jason Thorpe <thorpej@wasabisystems.com>
+
+ * elfcore.h (elf_core_file_p): Improve comment for last change.
+
+2002-01-27 Daniel Jacobowitz <drow@mvista.com>
+
+ * configure: Regenerated.
+
+2002-01-27 Jason Thorpe <thorpej@wasabisystems.com>
+
+ * elfcore.h (elf_core_file_p): Set the machine architecture
+ before processing the program headers.
+
+2002-01-26 Hans-Peter Nilsson <hp@bitrange.com>
+
+ * configure.in <64-bit configuration>: If using gcc, check and
+ emit error for egcs-1.1.2.
+ * configure: Regenerate.
+
+2002-01-26 Egor Duda <deo@logos-m.ru>
+
+ * elf.c (elfcore_grok_win32pstatus): Copy only as much information
+ as possible to avoid stack corruption.
+
+2002-01-26 Richard Henderson <rth@redhat.com>
+
+ * elf64-alpha.c (elf64_alpha_check_relocs): Don't set reltext
+ for non-allocated sections.
+
+2002-01-25 Mark Kettenis <kettenis@gnu.org>
+
+ * elf.c (elfcore_write_prstatus): Make sure we pass the address of
+ prstat.pr_reg even if it is a struct.
+
+2002-01-25 Steve Ellcey <sje@cup.hp.com>
+
+ * elfxx-ia64.c: Reset AIX vector function overrides for HP-UX.
+
+2002-01-25 Philipp Thomas <pthomas@suse.de>
+
+ * coffgen.c (coff_print_symbol): Don't mark info message
+ for translation.
+
+2002-01-25 Nick Clifton <nickc@redhat.com>
+
+ * po/fr.po: Updated translation.
+ * po/es.po: Updated translation.
+
+2002-01-25 Philipp Thomas <pthomas@suse.de>
+
+ * coff-alpha.c (alpha_relocate_section): Unify warning message
+ for GP relative relocations without GP defined.
+ * coff-mips.c (mips_relocate_section): Likewise.
+
+2002-01-25 Alan Modra <amodra@bigpond.net.au>
+
+ * elf-eh-frame.c (_bfd_elf_eh_frame_section_offset): Avoid
+ unsigned overflow when new_offset < old_offset.
+
+2002-01-24 Philipp Thomas <pthomas@suse.de>
+
+ * bfd.c (_bfd_abort): Fix typo.
+
+2002-01-23 Richard Henderson <rth@redhat.com>
+
+ * elf64-alpha.c (elf64_alpha_adjust_dynamic_symbol): Don't suppress
+ plt entries for undefweak symbols.
+
+2002-01-23 Steve Ellcey <sje@cup.hp.com>
+
+ * targets.c (bfd_elf32_ia64_hpux_big_vec): Add to DEFAULT_VECTOR.
+ (bfd_elf64_ia64_hpux_big_vec): Ditto.
+ (bfd_elf32_h8300_vec): Ditto.
+
+2002-01-23 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c: Remove stale part of ABI comment.
+ (NO_OPD_RELOCS): Define.
+ (ppc64_elf_check_relocs): Use it.
+ (ppc64_elf_relocate_section): Here too.
+ (build_one_stub): Don't point function syms at the stub. Instead,
+ hijack plt.offset.
+ (ppc64_elf_relocate_section): Check whether REL24 relocs should
+ really go to the stub. Make all dynamic relocs in opd against
+ locals.
+ (ppc64_elf_finish_dynamic_symbol): Allow for non-standard use of
+ plt.offset.
+
+2002-01-22 Richard Henderson <rth@redhat.com>
+
+ * elf64-alpha.c (INSN_UNOP): Encode with RB as $sp.
+
+2002-01-22 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (ppc64_elf_finish_dynamic_sections): Correct sign of
+ TOC_BASE_OFF adjustment.
+
+ * Makefile.am: Run "make dep-am".
+ * Makefile.in: Regenerate.
+ * po/SRC-POTFILES.in: Regenerate.
+
+2002-01-22 John David Anglin <dave@hiauly1.hia.nrc.ca>
+
+ * configure.host (hppa*64*-*-hpux*, hppa*64*-*-linux*): Add new
+ host defines.
+
+2002-01-21 Hans-Peter Nilsson <hp@axis.com>
+
+ * elf32-cris.c (cris_elf_relocate_section) <case R_CRIS_32_GOTREL>:
+ Check for and emit error if sgot is NULL at this point.
+
+2002-01-21 Jason Thorpe <thorpej@wasabisystems.com>
+
+ * config.bfd (ia64*-*-netbsd*): New target.
+
+2002-01-21 Thomas Klausner <wiz@danbala.ifoer.tuwien.ac.at>
+
+ * som.c (som_write_space_strings): Comment typo fix.
+
+2002-01-21 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (struct ppc_link_hash_entry): Add is_func and
+ is_func_descriptor fields.
+ (link_hash_newfunc): Init them.
+ (ppc64_elf_check_relocs): Only R_PPC24_REL24 syms starting with a
+ dot are candidates for plt entries. When processing .opd relocs,
+ set function descriptor strings to point inside function code
+ string, and set new ppc_link_hash_entry fields.
+ (ppc64_elf_gc_sweep_hook): Don't sweep R_PPC64_REL24 relocs.
+ (ppc64_elf_adjust_dynamic_symbol): Remove most code dealing with
+ function descriptors. It's now done in..
+ (func_desc_adjust): New.
+ (ppc64_elf_func_desc_adjust): New.
+ (define elf_backend_always_size_sections): Define.
+ (ppc64_elf_hide_symbol): New.
+ (define elf_backend_hide_symbol): Define.
+ (allocate_dynrelocs): Remove code looking up function descriptors
+ as that has been done earlier.
+ (ppc64_elf_size_dynamic_sections): Use htab shortcut to elf hash
+ table.
+ (ppc64_elf_finish_dynamic_symbol): Likewise. Remove code looking
+ up function descriptor.
+ (build_one_stub): Look up the function code sym. Check for
+ invalid plt offsets.
+ (ppc64_elf_relocate_section): Tweak calls to undefined weak syms.
+ Convert R_PPC64_TOC relocs to R_PPC64_RELATIVE in shared libs.
+
+ * elf-bfd.h (elf_backend_data <elf_backend_hide_symbol>): Add
+ boolean param.
+ (_bfd_elf_link_hash_hide_symbol): Likewise.
+ * elflink.h (elf_link_add_object_symbols): Adjust call to
+ elf_backend_hide_symbol.
+ (elf_fix_symbol_flags): Likewise.
+ (elf_link_assign_sym_version): Likewise. Use bfd_malloc rather
+ than bfd_alloc.
+ * elf.c (_bfd_elf_link_hash_hide_symbol): Add "force_local" param.
+ Set ELF_LINK_FORCED_LOCAL and call _bfd_elf_strtab_delref.
+ * elf32-hppa.c (elf32_hppa_hide_symbol): Likewise.
+ (clobber_millicode_symbols): Adjust to suit new hide_symbol.
+ * elf32-cris.c (elf_cris_hide_symbol): Add "force_local" param
+ and adjust to suit.
+ * elf32-mips.c (_bfd_mips_elf_hide_symbol): Likewise, and call
+ _bfd_elf_link_hash_hide_symbol rather than duplicating code.
+ * elfxx-ia64.c (elfNN_ia64_hash_hide_symbol): Likewise.
+
+2002-01-18 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (ppc64_elf_adjust_dynamic_symbol): Test for a
+ dynamic function descriptor symbol, not the associated function
+ symbol.
+
+2002-01-17 Eric Christopher <echristo@redhat.com>
+
+ * elf32-mips.c (mips_elf_calculate_relocation): Fix typo.
+
+2002-01-17 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * po/bfd.pot: Regenerate.
+ * po/fr.po: Regenerate.
+
+2002-01-17 Alan Modra <amodra@bigpond.net.au>
+
+ * elf-bfd.h (elf_backend_data <elf_backend_section_from_bfd_section>):
+ Remove "Elf_Internal_Shdr *" param.
+ (_bfd_mips_elf_section_from_bfd_section): Ditto.
+ * elf32-mips.c (_bfd_mips_elf_section_from_bfd_section): Ditto.
+ * elf32-m32r.c (_bfd_m32r_elf_section_from_bfd_section): Ditto.
+ * elf32-v850.c (v850_elf_section_from_bfd_section): Ditto.
+ * elf64-mmix.c (mmix_elf_section_from_bfd_section): Ditto.
+ * elfxx-ia64.c (elfNN_hpux_backend_section_from_bfd_section): Ditto.
+ * elf.c (_bfd_elf_section_from_bfd_section): Allow backend
+ function to override special sections. Remove hdr arg from
+ backend call, and don't loop.
+
+2002-01-16 Eric Christopher <echristo@redhat.com>
+
+ * elf32-mips.c (mips_elf_calculate_relocation): Set require_jalxp
+ on R_MIPS_26 and target is 16bit. Add R_MIPS16_GPREL to list of
+ relocations requiring gp0 and gp.
+
+2002-01-16 Richard Earnshaw <rearnsha@arm.com>
+
+ * elf32-arm.h (elf32_arm_merge_private_bfd_data): Handle
+ EF_ARM_VFP_FLOAT.
+ (elf32_arm_print_private_bfd_data): Likewise.
+
+2002-01-16 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * po/tr.po: Import new version.
+
+2002-01-16 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (ppc64_elf_howto_raw): Remove stale FIXMEs.
+ (ppc64_elf_reloc_type_lookup): Use proper CTOR reloc.
+ (ORI_R0_R0_0): Correct.
+
+2002-01-16 Alan Modra <amodra@bigpond.net.au>
+
+ * elflink.c (_bfd_elf_create_dynamic_sections): Don't set SEC_CODE
+ when plt_not_loaded.
+ * elf64-ppc.c (ppc64_elf_create_dynamic_sections): No need to
+ clear .plt SEC_CODE here. Create .stub and correct .glink flags.
+ (PLT_INITIAL_ENTRY_SIZE): Set to 24.
+ (ppc64_elf_glink_code): Delete.
+ (PPC64_ELF_GLINK_SIZE): Delete.
+ (ADDIS_R12_R2, STD_R2_40R1, LD_R11_0R12, LD_R2_0R12, MTCTR_R11,
+ BCTR, ADDIS_R12_R12_1, LD_R2_40R1, NOP, LI_R0_0, B_DOT, LIS_R0_0,
+ ORI_R0_R0_0): Define.
+ (PLT_CALL_STUB_SIZE, GLINK_CALL_STUB_SIZE): Define.
+ (struct ppc_link_hash_table): Add sstub and plt_overflow.
+ (ppc64_elf_link_hash_table_create): Init them.
+ (ppc64_elf_check_relocs <R_PPC64_REL24>): Refcount .plt entry.
+ Don't copy to shared lib.
+ (ppc64_elf_check_relocs): Call bfd_set_error on errors.
+ (ppc64_elf_gc_sweep_hook <R_PPC64_REL24>): Sweep plt refcount.
+ (allocate_dynrelocs <plt>): Don't change function sym here. Make
+ room for .stub and .glink code.
+ (ppc64_elf_size_dynamic_sections): Handle .stub. Make entry for
+ DT_PPC64_GLINK.
+ (ppc64_elf_final_link): Rename to ppc64_elf_set_toc. Don't call
+ bfd_elf64_bfd_final_link.
+ (bfd_elf64_bfd_final_link): Don't define.
+ (ppc64_elf_size_stubs): New.
+ (build_plt_stub): New.
+ (build_one_stub): New.
+ (ppc64_elf_build_stubs): New.
+ (ppc64_elf_relocate_section <toc relocs>): Remove assert.
+ (ppc64_elf_relocate_section): Don't copy R_PPC64_REL24 relocs.
+ (ppc64_elf_finish_dynamic_symbol): Don't build stubs here. Set
+ DT_PPC64_GLINK entry. Tweak DT_PLTGOT, DT_JMPREL, DT_PLTRELSZ in
+ case output sections not separate. Adjust DT_RELASZ to not
+ include plt relocs. Set reserved got entry. Set got and plt
+ entry size.
+ (elf_backend_got_header_size): Set to 8.
+ * elf64-ppc.h: New file.
+
+2002-01-16 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-arm.h (elf32_arm_size_dynamic_sections): When removing
+ sections, use bfd_section_list_remove.
+ * elf32-i370.c (i370_elf_size_dynamic_sections): Likewise.
+ * elflink.h (elf_link_add_object_symbols): When removing all
+ sections, use bfd_section_list_clear.
+
+2002-01-15 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * po/sv.po: New file: Swedish translation.
+ * configure.in (ALL_LINGUAS): Add sv.
+ * configure: Regenerate.
+
+2002-01-15 Jakub Jelinek <jakub@redhat.com>
+
+ * elflink.h (elf_link_input_bfd): Back out 2002-01-07 change.
+ * elf.c (merge_sections_remove_hook): New function.
+ (_bfd_elf_merge_sections): Pass it as 3rd argument to
+ _bfd_merge_sections.
+ * libbfd-in.h (_bfd_merge_sections): Add 3rd argument.
+ * libbfd.h: Rebuilt.
+ * merge.c (_bfd_merge_sections): Add remove_hook argument.
+ Call remove_hook if a SEC_EXCLUDE section is encountered.
+
+2002-01-15 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * elf32-xstormy16.c (xstormy16_reloc_map): Add new field 'table'.
+ (xstormy16_reloc_map): Initialise new field with correct howto
+ table.
+ (xstormy16_reloc_type_lookup): Use 'table' field to locate correct
+ howto entry.
+
+2002-01-10 Michael Snyder <msnyder@redhat.com>
+
+ * elf.c (elfcore_write_prstatus): Use long instead of pid_t;
+ (elfcore_write_pstatus): Use long instead of pid_t;
+ * elf-bfd.h: Change prototypes to use long instead of pid_t;
+
+2002-01-09 Jason Thorpe <thorpej@wasabisystems.com>
+
+ * elf.c: Update copyright years.
+ (elfcore_grok_netbsd_note): Use NT_NETBSDCORE_PROCINFO
+ and NT_NETBSDCORE_FIRSTMACH. Improve a comment.
+
+2002-01-08 Michael Snyder <msnyder@redhat.com>
+
+ Add capability to write corefile note sections, for gdb.
+ * elf.c (elfcore_write_note): New function.
+ (elfcore_write_prpsinfo): New function.
+ (elfcore_write_prstatus): New function.
+ (elfcore_write_pstatus): New function.
+ (elfcore_write_prfpreg): New function.
+ (elfcore_write_prxfpreg): New function.
+ * elf-bfd.h: Add prototypes for above functions.
+
+2002-01-08 Alexandre Oliva <aoliva@redhat.com>
+
+ * elf.c (elf_fake_sections): Propagate errors from
+ elf_backend_fake_section.
+
+2002-01-07 Jason Thorpe <thorpej@wasabisystems.com>
+
+ * Makefile.am (BFD32_BACKENDS): Add elf32-sh-nbsd.lo.
+ (BFD32_BACKENDS_CFILES): Add elf32-sh-nbsd.c.
+ (elf32-sh-nbsd.lo): New rule.
+ * Makefile.in: Regenerate.
+ * config.bfd (sh*le-*-netbsdelf*): New target.
+ (sh*-*-netbsdelf*): New target.
+ * configure.in: Include netbsd-core.lo for native sh*-*-netbsd*.
+ (bfd_elf32_shnbsd_vec): New vector.
+ (bfd_elf32_shlnbsd_vec): New vector.
+ * configure: Regenerate.
+ * elf32-sh-nbsd.c: New file.
+ * targets.c: Update copyright years.
+ (_bfd_target_vector): Add bfd_elf32_shlnbsd_vec and
+ bfd_elf32_shnbsd_vec.
+
+2002-01-07 Aldy Hernandez <aldyh@redhat.com>
+
+ * coff-rs6000.c (READ20): Use bfd_scan_vma.
+
+2002-01-07 Geoffrey Keating <geoffk@redhat.com>
+
+ * elflink.h (elf_link_input_bfd): Don't ask for the merged offset
+ of a symbol in a section that will be deleted.
+
+2002-01-07 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * po/es.po: New file: Spanish translation.
+ * configure.in (ALL_LINGUAS): Add es.
+ * configure: Regenerate.
+
+2002-01-06 Steve Ellcey <sje@cup.hp.com>
+
+ * elfxx-ia64.c (is_unwind_section_name): Add target vector as
+ argument so we can handle HP-UX specially.
+ (elfNN_ia64_hpux_vec): New for use in is_unwind_section_name.
+ (elfNN_hpux_backend_section_from_bfd_section): New for support
+ of SHN_IA_64_ANSI_COMMON.
+ (elfNN_ia64_relax_section): Add support for SHN_IA_64_ANSI_COMMON.
+ (is_unwind_section_name): Add special HP-UX support.
+ (elfNN_ia64_section_from_shdr): Add support for more sections.
+ (elfNN_ia64_fake_sections): Modify is_unwind_section_name call and
+ add support for more sections.
+ (elfNN_ia64_additional_program_headers): Modify
+ is_unwind_section_name call.
+ (elfNN_ia64_modify_segment_map): Remove assumption that there is
+ only one unwind section in segment.
+
+2002-01-06 Alan Modra <amodra@bigpond.net.au>
+
+ * syms.c (_bfd_generic_make_empty_symbol): New function.
+ * libbfd-in.h (_bfd_nosymbols_make_empty_symbol): Define as
+ _bfd_generic_make_empty_symbol.
+ * libbfd.h: Regenerate.
+ * bfd-in2.h: Regenerate.
+ * hppabsd-core.c (hppabsd_core_make_empty_symbol): Delete function.
+ (hppabsd_core_get_symtab_upper_bound): Don't define.
+ (hppabsd_core_get_symtab): Likewise.
+ (hppabsd_core_print_symbol): Likewise.
+ (hppabsd_core_get_symbol_info): Likewise.
+ (hppabsd_core_bfd_is_local_label_name): Likewise.
+ (hppabsd_core_get_lineno): Likewise.
+ (hppabsd_core_find_nearest_line): Likewise.
+ (hppabsd_core_bfd_make_debug_symbol): Likewise.
+ (hppabsd_core_read_minisymbols): Likewise.
+ (hppabsd_core_minisymbol_to_symbol): Likewise.
+ (hppabsd_core_vec): Use BFD_JUMP_TABLE_SYMBOLS (_bfd_nosymbols).
+ Formatting fixes.
+ * hpux-core.c: Similarly.
+ * irix-core.c: Similarly.
+ * osf-core.c: Similarly.
+ * sco5-core.c: Similarly.
+ * binary.c (binary_make_empty_symbol): Remove function, define as
+ _bfd_generic_make_empty_symbol.
+ * ihex.c (ihex_make_empty_symbol): Likewise.
+ * mmo.c (mmo_make_empty_symbol): Likewise.
+ * ppcboot.c (ppcboot_make_empty_symbol): Likewise.
+ * srec.c (srec_make_empty_symbol): Likewise.
+ * versados.c (versados_make_empty_symbol): Likewise.
+ * vms.c (_bfd_vms_make_empty_symbol): Remove.
+ (vms_make_empty_symbol): Define as _bfd_generic_make_empty_symbol.
+ * vms-gsd.c (_bfd_vms_slurp_gsd): Call bfd_make_empty_symbol
+ rather than _bfd_vms_make_empty_symbol.
+ * vms-misc.c (new_symbol): Likewise.
+
+2002-01-05 Alan Modra <amodra@bigpond.net.au>
+
+ * section.c (bfd_section_init): Remove unnecessary initialisations.
+ (bfd_section_list_clear): New function.
+ (bfd_section_list_remove, bfd_section_list_insert): New macros.
+ (_bfd_strip_section_from_output): Use them.
+ * coffcode.h (coff_set_alignment_hook): Likewise.
+ * elf32-mips.c (_bfd_mips_elf_final_link): Likewise.
+ * elf64-mips.c (mips_elf64_final_link): Likewise.
+ * elf64-mmix.c (mmix_elf_final_link): Likewise.
+ * sunos.c (sunos_add_dynamic_symbols): Likewise.
+ * xcofflink.c (_bfd_xcoff_bfd_final_link): Likewise.
+ * bfd-in2.h: Regenerate.
+
+ * netbsd-core.c (netbsd_core_file_p): Use bfd_make_section_anyway
+ rather than doing our own section handling. Clean up after errors
+ with bfd_release and bfd_section_list_clear. Handle unexpected
+ flags.
+ * aoutf1.h (sunos4_core_file_p): Likewise.
+ * aix386-core.c (aix386_core_file_p): Likewise.
+ * cisco-core.c (cisco_core_file_validate): Likewise.
+ * ptrace-core.c (ptrace_unix_core_file_p): Likewise.
+ * trad-core.c (trad_unix_core_file_p): Likewise.
+
+ * hppabsd-core.c (hppabsd_core_core_file_p): Clean up after errors
+ with bfd_release and bfd_section_list_clear.
+ * hpux-core.c (hpux_core_core_file_p): Likewise.
+ * irix-core.c (irix_core_core_file_p): Likewise.
+ * lynx-core.c (lynx_core_file_p): Likewise.
+ * osf-core.c (osf_core_core_file_p): Likewise.
+ * rs6000-core.c (rs6000coff_core_p): Likewise.
+ * sco5-core.c (sco5_core_file_p): Likewise.
+
+ * elf32-mips.c (_bfd_mips_elf_lo16_reloc): Simplify, and perform
+ sign extension adjustments without conditionals.
+
+2002-01-04 Jakub Jelinek <jakub@redhat.com>
+
+ * elf-eh-frame.c (_bfd_elf_write_section_eh_frame): Don't crash if
+ CIE at .eh_frame start is removed due to no FDEs referencing it.
+
+2002-01-04 Jason Thorpe <thorpej@wasabisystems.com>
+
+ * config.bfd (x86_64-*-netbsd*): New target.
+ * configure.in (x86_64-*-netbsd*): Set COREFILE
+ to netbsd-core.lo.
+ * configure: Regenerated.
+
+2002-01-03 Tom Rix <trix@redhat.com>
+
+ * xcofflink.c (_bfd_xcoff_bfd_final_link): Update .pad section ordering
+ for recent bfd_make_section_anyway change.
+
+2002-01-03 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * elf32-arm.h (elf32_arm_final_link_relocate): Handle
+ R_ARM_THM_PC11 reloc.
+
+2002-01-02 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * configure.in (LINGUAS): Add ja.
+ * configure: Regenerate.
+ * po/ja.po: Import from translation project's web site.
+
+2002-01-02 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * elf32-arm.h (elf32_arm_merge_private_bfd_data): Reformat error
+ messages to ease translation into other languages.
+
+For older changes see ChangeLog-0001
+
+Copyright (C) 2002-2003 Free Software Foundation, Inc.
+
+Copying and distribution of this file, with or without modification,
+are permitted in any medium without royalty provided the copyright
+notice and this notice are preserved.
+
+Local Variables:
+mode: change-log
+left-margin: 8
+fill-column: 74
+version-control: never
+End:
diff --git a/bfd/ChangeLog-2004 b/bfd/ChangeLog-2004
new file mode 100644
index 0000000..09d816f
--- /dev/null
+++ b/bfd/ChangeLog-2004
@@ -0,0 +1,5069 @@
+2004-12-31 Paul Brook <paul@copdesourcery.com>
+
+ * elf32-arm.c (elf32_arm_symbian_plt_entry): Fix comment typo.
+
+2004-12-31 Alan Modra <amodra@bigpond.net.au>
+
+ * reloc.c (BFD_RELOC_AVR_LDI, BFD_RELOC_AVR_6, BFD_RELOC_AVR_6_ADIW):
+ Commit missing changes from 2004-12-22.
+ * bfd-in2.h: Regenerate.
+
+2004-12-23 Tomer Levi <Tomer.Levi@nsc.com>
+
+ * elf32-crx.c (elf32_crx_relax_section): Support 'bcop' relaxation.
+
+2004-12-21 Kris Warkentin <kewarken@qnx.com>
+
+ * elf.c (elfcore_grok_nto_gregs): Change name to elfcore_grok_nto_regs.
+ Add 'base' argument for constructing register sections. Reformat.
+ (elfcore_grok_nto_note): Call elfcore_grok_nto_regs for both
+ gp and fp regs. Reformat.
+
+2004-12-22 Klaus Rudolph <lts-rudolph@gmx.de>
+
+ * reloc.c: Add new relocs R_AVR_LDI, R_AVR_6, R_AVR_6_ADIW.
+ * bfd-in2.h: Regenerate.
+ * elf32-avr.c (elf_avr_nowto_table): Add the new relocs.
+ (avr_reloc_map): Likewise.
+ (avr_final_link_relocate): Likewise.
+
+2004-12-22 Alan Modra <amodra@bigpond.net.au>
+
+ * elflink.c (_bfd_elf_merge_symbol): Treat old definitions from
+ as-needed dynamic libs as undefined.
+ (elf_link_add_object_symbols): Remove DYN_AS_NEEDED from as-needed
+ libs when finding they are needed.
+
+2004-12-20 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (struct ppc64_elf_obj_tdata): Add opd_relocs.
+ (opd_entry_value): Use opd_relocs if available.
+ (ppc64_elf_relocate_section): Don't set reloc_done. Instead
+ copy .opd relocations to opd_relocs.
+ (ppc64_elf_edit_toc): Set rel_hdr.sh_size after editing relocs.
+
+2004-12-16 Richard Sandiford <rsandifo@redhat.com>
+
+ * reloc.c (BFD_RELOC_V850_LO16_SPLIT_OFFSET): New bfd_reloc_code_type.
+ * elf32-v850.c (v850_elf_howto_table): Add entry for
+ R_V850_LO16_SPLIT_OFFSET.
+ (v850_elf_reloc_map): Map it to BFD_RELOC_V850_LO16_SPLIT_OFFSET.
+ (v850_elf_perform_lo16_relocation): New function, extracted from...
+ (v850_elf_perform_relocation): ...here. Use it to handle
+ R_V850_LO16_SPLIT_OFFSET.
+ (v850_elf_check_relocs, v850_elf_final_link_relocate): Handle
+ R_V850_LO16_SPLIT_OFFSET.
+ * libbfd.h, bfd-in2.h: Regenerate.
+
+2004-12-14 P.J. Darcy <darcypj@us.ibm.com>
+
+ * config.bfd: Add s390x-ibm-tpf support.
+
+2004-12-14 Tomer Levi <Tomer.Levi@nsc.com>
+
+ * elf32-crx.c (elf32_crx_relax_delete_bytes): Add 'struct bfd_link_info *'
+ to prototype, to make hash info available.
+ Prevent wrapped symbols from being adjusted twice.
+
+2004-12-14 Richard Sandiford <rsandifo@redhat.com>
+
+ * elfxx-mips.c (mips_elf_calculate_relocation): Don't report an
+ overflow for calls to undefined weak symbols.
+
+2004-12-11 Alan Modra <amodra@bigpond.net.au>
+
+ * elfcode.h (elf_slurp_symbol_table): Use bfd_elf_sym_name so that
+ canonical sections syms have a name.
+
+2004-12-11 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (opd_entry_value): Don't use cached relocs if they
+ have been adjusted for output.
+ (ppc64_elf_relocate_section): Mark sections with reloc_done.
+
+2004-12-10 Alan Modra <amodra@bigpond.net.au>
+
+ * elf.c (bfd_elf_sym_name): Rename from bfd_elf_local_sym_name and
+ add symtab_hdr param.
+ (group_signature): Update calls.
+ * elf-bfd.h (bfd_elf_sym_name): Update.
+ * elf32-ppc.c (ppc_elf_relocate_section): Update.
+ * elf64-ppc.c (ppc64_elf_edit_opd, ppc64_elf_edit_toc): Update.
+ (ppc64_elf_relocate_section): Update.
+ * elflink.c (elf_link_input_bfd): Update.
+
+2004-12-10 Jakub Jelinek <jakub@redhat.com>
+
+ * elf.c (bfd_elf_local_sym_name): Avoid crashes with invalid
+ st_shndx on STT_SECTION sections.
+
+2004-12-09 Daniel Jacobowitz <dan@codesourcery.com>
+
+ * elfcode.h (elf_slurp_reloc_table_from_section): Don't canonicalize
+ ELF section symbols.
+
+2004-12-09 Ian Lance Taylor <ian@wasabisystems.com>
+
+ * elfxx-mips.c (mips_elf_calculate_relocation): For R_MIPS_JALR,
+ return a real value, unless it is a PLT symbol.
+ (mips_elf_perform_relocation): On the RM9000, turn a jal into a
+ bal if possible.
+
+ * elfn32-mips.c (elf_mips_howto_table_rela): Change dst_mask of
+ R_MIPS_JALR entry to 0.
+
+ * archures.c: Define bfd_mach_mips9000.
+ * elfxx-mips.c (_bfd_elf_mips_mach): Handle E_MIPS_MACH_9000.
+ (mips_set_isa_flags): Handle bfd_mach_mips9000.
+ * cpu-mips.c (I_mips9000): Define.
+ (arch_info_struct): Add case for bfd_mach_mips9000.
+ * aoutx.h (NAME(aout,machine_type)): Handle bfd_mach_mips9000.
+ * bfd-in2.h: Regenerate.
+
+2004-12-08 Ian Lance Taylor <ian@wasabisystems.com>
+
+ * elfxx-mips.c (mips_elf_calculate_relocation): Test for R_MIPS_26
+ overflow.
+
+2004-12-07 Ben Elliston <bje@gnu.org>
+
+ * netbsd-core.c (netbsd_core_file_p): Make `i' unsigned.
+
+2004-12-06 Daniel Jacobowitz <dan@debian.org>
+
+ Suggested by Fergal Daly <fergal@esatclear.ie>:
+ * simple.c (simple_dummy_multiple_definition): New function.
+ (bfd_simple_get_relocated_section_contents): Use it.
+
+2004-12-03 Jan Beulich <jbeulich@novell.com>
+
+ * elf.c (elf_find_function): Don't use the last file symbol ever,
+ seen, but the last one seen prior to the symbol being reported.
+ Don't report a filename at all for global symbols when that might
+ be ambiguous/wrong.
+
+2004-12-01 Paul Brook <paul@codesourcery.com>
+
+ * elf32-arm.c (elf32_arm_copy_private_bfd_data): Set EI_OSABI.
+ (elf32_arm_post_process_headers): Set EI_OSABI depending on ABI
+ version.
+
+2004-12-01 Paul Brook <paul@codesourcery.com>
+
+ * elflink.c (elf_link_add_object_symbols): Make symbols from discarded
+ sections undefined.
+
+2004-11-30 Paul Brook <paul@codesourcery.com>
+
+ * elf32-arm.c (struct elf32_arm_link_hash_table): Remove
+ no_pipeline_knowledge
+ (elf32_arm_link_hash_table_create): Ditto.
+ (bfd_elf32_arm_process_before_allocation): Ditto.
+ (elf32_arm_final_link_relocate): Ditto. Remove oabi relocation
+ handling.
+ * bfd-in.h (bfd_elf32_arm_process_before_allocation): Update
+ prototype.
+ * bfd-in2.h: Regenerate.
+
+2004-11-30 Randolph Chung <tausq@debian.org>
+
+ * elf32-hppa.c (elf32_hppa_grok_prstatus): New function.
+ (elf32_hppa_grok_psinfo): New function.
+ (elf_backend_grok_prstatus): Define.
+ (elf_backend_grok_psinfo): Define.
+
+2004-11-24 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR 574:
+ * elfcode.h (elf_slurp_symbol_table): Handle STT_TLS.
+
+2004-11-24 Paul Brook <paul@codesourcery.com>
+
+ * elf.c (assign_section_numbers): Number SHT_GROUP sections first.
+
+2004-11-24 Paul Brook <paul@codesourcery.com>
+
+ * elf32-arm.c (elf32_arm_swap_symbol_in): New function.
+ (elf32_arm_swap_symbol_out): New function.
+ (elf32_arm_size_info): Add.
+ (elf_backend_size_info): Define.
+
+2004-11-20 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ * hpux-core.c (hpux_core_core_file_p): Use offsetof macro in calls to
+ make_bfd_asection.
+
+2004-11-19 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-arm.c (elf32_arm_finish_dynamic_sections): Warning fix.
+ * elf32-iq2000.c (iq2000_reloc_type_lookup): C90 function decl.
+ * nlmcode.h (nlm_write_object_contents): Warning fix.
+
+2004-11-18 Bob Wilson <bob.wilson@acm.org>
+
+ * elf32-xtensa.c (ebb_propose_action): Fix argument order.
+
+2004-11-17 Daniel Jacobowitz <dan@codesourcery.com>
+
+ * elf32-arm.c (PLT_THUMB_STUB_SIZE): Define.
+ (elf32_arm_plt_thumb_stub): New.
+ (struct elf32_arm_link_hash_entry): Add plt_thumb_refcount
+ and plt_got_offset.
+ (elf32_arm_link_hash_traverse): Fix typo.
+ (elf32_arm_link_hash_table): Add obfd.
+ (elf32_arm_link_hash_newfunc): Initialize new fields.
+ (elf32_arm_copy_indirect_symbol): Copy plt_thumb_refcount.
+ (elf32_arm_link_hash_table_create): Initialize obfd.
+ (record_arm_to_thumb_glue): Mark the glue as a local ARM function.
+ (record_thumb_to_arm_glue): Mark the glue as a local Thumb function.
+ (bfd_elf32_arm_get_bfd_for_interworking): Verify that the
+ interworking BFD is not dynamic.
+ (bfd_elf32_arm_process_before_allocation): Handle R_ARM_PLT32. Do
+ not emit glue for PLT references.
+ (elf32_arm_final_link_relocate): Handle Thumb functions. Do not
+ emit glue for PLT references. Support the Thumb PLT prefix.
+ (elf32_arm_gc_sweep_hook): Handle R_ARM_THM_PC22 and
+ plt_thumb_refcount.
+ (elf32_arm_check_relocs): Likewise.
+ (elf32_arm_adjust_dynamic_symbol): Handle Thumb functions and
+ plt_thumb_refcount.
+ (allocate_dynrelocs): Handle Thumb PLT references.
+ (elf32_arm_finish_dynamic_symbol): Likewise.
+ (elf32_arm_symbol_processing): New function.
+ (elf_backend_symbol_processing): Define.
+
+2004-11-16 Richard Sandiford <rsandifo@redhat.com>
+
+ * elf-bfd.h (eh_cie_fde): Add new fields: add_augmentation_size and
+ add_fde_encoding. Remove need_relative.
+ * elf-eh-frame.c (extra_augmentation_string_bytes)
+ (extra_augmentation_data_bytes, size_of_output_cie_fde): New functions.
+ (_bfd_elf_discard_section_eh_frame): Consider changing the FDE encoding
+ in cases where the CIE has no existing 'R' augmentation. Use
+ size_of_output_cie_fde when assigning offsets. Use the final offset
+ as the new section size.
+ (_bfd_elf_eh_frame_section_offset): Remove need_relative handling.
+ Account for any extra augmentation bytes in the returned offset.
+ (_bfd_elf_write_section_eh_frame): Rework so that the entries are
+ moved before being modified. Pad growing entries with DW_CFA_nops.
+ Add 'z' and 'R' augmentations as directed by add_augmentation_size
+ and add_fde_encoding.
+
+2004-11-15 Mark Mitchell <mark@codesourcery.com>
+
+ * elf32-arm.c (elf32_arm_relocate_section): Use
+ arm_real_reloc_type.
+
+2004-11-16 Richard Sandiford <rsandifo@redhat.com>
+
+ * elfxx-mips.c (mips_elf_create_dynamic_relocation): Return early
+ for discard relocations; don't add an R_MIPS_NONE to the main body
+ of .rel.dyn.
+
+2004-11-04 Paul Brook <paul@codesourcery.com>
+
+ * elf-bfd.h (_bfd_elf_slurp_version_tables): Update prototype.
+ * elf.c (_bfd_elf_print_private_bfd_data): Pass extra argument.
+ (_bfd_elf_slurp_version_tables): Add extra argument. Create extra
+ default version definition for unversioned symbols.
+ * elfcode.h (elf_slurp_symbol_table): Pass extra argument.
+ * elflink.c (elf_link_add_object_symbols): Pass extra argument to
+ _bfd_elf_slurp_version_tables. Set default version for unversioned
+ imported symbols.
+
+2004-11-15 Paul Brook <paul@codesourcery.com>
+
+ * elflink.c (elf_link_add_object_symbols): Don't assume version
+ indices are consecutive.
+
+2004-11-14 Richard Sandiford <rsandifo@redhat.com>
+
+ * elf-eh-frame.c (_bfd_elf_discard_section_eh_frame): Deal with
+ composite relocations against the personality data.
+
+2004-11-13 Paul Brook <paul@codesourcery.com>
+
+ * elf32-arm.c (elf32_arm_final_link_relocate): Resolve
+ R_ARM_PREL31 relocations to PLT entries.
+ (elf32_arm_relocate_section, elf32_arm_gc_sweep_hook): Ditto.
+ (elf32_arm_check_relocs): Ditto.
+
+2004-11-12 Bob Wilson <bob.wilson@acm.org>
+
+ * xtensa-isa.c (xtensa_interface_class_id): New.
+
+2004-11-11 Bob Wilson <bob.wilson@acm.org>
+
+ * elf32-xtensa.c (property_table_compare): Remove assertion about
+ entries with the same address and non-zero size.
+ (xtensa_read_table_entries): Report such entries as errors.
+
+2004-11-11 Mark Mitchell <mark@codesourcery.com>
+
+ * elf32-arm.c (elf32_arm_final_link_relocate): Correct logic for
+ R_ARM_RELATIVE on Symbian OS.
+
+2004-11-09 Mark Mitchell <mark@codesourcery.com>
+
+ * som.c (som_bfd_print_private_bfd_data): New function.
+ (som_object_setup): Save the auxiliary header. Don't assume that
+ zero is an invalid entry point for a shared library.
+ (som_object_p): Allocate the auxiliary header on the heap.
+
+ * elf32-arm.c (elf32_arm_begin_write_processing): Do not use a K&R
+ declaration.
+ (elf32_arm_symbian_modify_segment_map): Likewise.
+
+2004-11-09 Daniel Jacobowitz <dan@debian.org>
+
+ From David Poole <daveml@mbuf.com>:
+ * elf32-arm.c (elf32_arm_readonly_dynrelocs): New function.
+ (elf32_arm_size_dynamic_sections): Call it.
+
+2004-11-09 Alan Modra <amodra@bigpond.net.au>
+
+ * Makefile.am (SOURCE_HFILES): Remove elf32-arm.h.
+ (ALL_MACHINES_CFILES): Fix typo.
+ * Makefile.in: Regenerate.
+ * po/SRC-POTFILES.in: Regenerate.
+
+2004-11-08 Mark Mitchell <mark@codesourcery.com>
+
+ * elf32-arm.c (elf32_arm_final_link_relocate): When generating an
+ R_ARM_RELATIVE relocation for Symbian OS, mention the section
+ symbol in the relocation.
+
+2004-11-08 Inderpreet Singh <inderpreetb@nioda.hcltech.com>
+ Vineet Sharma <vineets@noida.hcltech.com>
+
+ * coff-maxq.c: New File.
+ * cpu-maxq.c: New File.
+ * coffcode.h: Likewise.
+ * config.bfd: Likewise.
+ * configure.in (maxqcoff_vec): New target vector.
+ * Makefile.am: Add support for maxq target.
+ * configure.in: Likewise.
+ * archures.c:. Likewise.
+ * targets.c: Likewise.
+ * bfd_in2.h : Regenerated.
+ * Makefile.in: Regenerated.
+ * configure: Regenerated.
+ * doc/Makefile.in: Regenerated.
+
+2004-11-08 Aaron W. LaFramboise <aaron98wiridge9@aaronwl.com>
+
+ * coff-i386.c (coff_i386_reloc): Fix weak symbols.
+ * cofflink.c (_bfd_coff_link_input_bfd): Don't process
+ C_NT_WEAK aux entries.
+ (_bfd_coff_generic_relocate_section): Handle undefined
+ aliases.
+
+2004-11-07 Andreas Schwab <schwab@suse.de>
+
+ * elf32-m68k.c (elf_m68k_adjust_dynamic_symbol): Use
+ SYMBOL_CALLS_LOCAL and check for undefweak symbols with
+ non-default visibility.
+
+2004-11-01 Mark Mitchell <mark@codesourcery.com>
+
+ * elf32-arm.c (elf32_arm_symbian_begin_write_processing): Clear
+ D_PAGED.
+ (elf32_arm_symbian_modify_segment_map): Don't
+ reset includes_filehdr and includes_phdrs here.
+
+2004-11-04 Daniel Jacobowitz <dan@debian.org>
+
+ * Makefile.am (BFD32_BACKENDS, BFD32_BACKENDS_CFILES): Replace
+ elfarm-nabi with elf32-arm. Remove elfarm-oabi.
+ (elf32-arm.lo): Replace elfarm-nabi.lo rule. Remove elf32-arm.h
+ dependency.
+ * config.bfd: Move arm-*-oabi* and thumb-*-oabi* from obsolete list
+ to a new removed list. Remove normal configuration stanzas.
+ * configure.in: (bfd_elf32_bigarm_vec, bfd_elf32_bigarm_symbian_vec)
+ (bfd_elf32_littlearm_symbian_vec, bfd_elf32_littlearm_vec): Replace
+ elfarm-nabi.lo with elf32-arm.lo.
+ (bfd_elf32_bigarm_oabi_vec, bfd_elf32_littlearm_oabi_vec): Remove.
+ * elf32-arm.c: Renamed from elfarm-nabi.c. Inline elf32-arm.h.
+ * elf32-arm.h: Remove.
+ * elfarm-oabi.c: Remove.
+ * targets.c (_bfd_target_vector): Remove bfd_elf32_bigarm_oabi_vec
+ and bfd_elf32_littlearm_oabi_vec.
+ * aclocal.m4, Makefile.in, configure, doc/Makefile.in: Regenerated.
+
+2004-11-04 Hans-Peter Nilsson <hp@axis.com>
+
+ * config.bfd: Support crisv32-*-* like cris-*-*.
+ * archures.c (bfd_mach_cris_v0_v10, bfd_mach_cris_v32)
+ (bfd_mach_cris_v10_v32): New macros.
+ * cpu-cris.c: Tweak formatting.
+ (get_compatible): New function.
+ (N): New macro.
+ (bfd_cris_arch_compat_v10_v32, bfd_cris_arch_v32): New
+ bfd_arch_info_type:s.
+ (bfd_cris_arch): Use bfd_mach_cris_v0_v10 for member mach,
+ get_compatible for member compatible and link bfd_cris_arch_v32 as
+ next.
+ * elf32-cris.c (cris_elf_pcrel_reloc)
+ (cris_elf_set_mach_from_flags): New functions.
+ (cris_elf_howto_table) <R_CRIS_8_PCREL, R_CRIS_16_PCREL>
+ <R_CRIS_32_PCREL>: Use cris_elf_pcrel_reloc.
+ (cris_elf_grok_prstatus, cris_elf_grok_psinfo): Give correct
+ numbers for bfd_mach_cris_v32.
+ (PLT_ENTRY_SIZE_V32): New macro.
+ (elf_cris_plt0_entry): Drop last comma in initializer.
+ (elf_cris_plt0_entry_v32, elf_cris_plt_entry_v32)
+ (elf_cris_pic_plt0_entry_v32, elf_cris_pic_plt_entry_v32): New
+ PLT initializers.
+ (cris_elf_relocate_section): Change all "%B(%A)" messages to
+ "%B, section %A".
+ (elf_cris_finish_dynamic_symbol): Do V32-specific PLT entries.
+ (elf_cris_finish_dynamic_sections): Similar.
+ (elf_cris_adjust_dynamic_symbol): Similar.
+ (cris_elf_check_relocs): Change all "%B(%A)" messages to "%B,
+ section %A".
+ <switch with PIC relocs>: Emit error and return FALSE for
+ bfd_mach_cris_v10_v32.
+ <case R_CRIS_8_PCREL, case R_CRIS_16_PCREL, case R_CRIS_32_PCREL>:
+ Emit warning when generating textrel reloc.
+ (cris_elf_object_p): Call cris_elf_set_mach_from_flags.
+ (cris_elf_final_write_processing): Set flags according to mach.
+ (cris_elf_print_private_bfd_data): Display
+ EF_CRIS_VARIANT_COMMON_V10_V32 and EF_CRIS_VARIANT_V32.
+ (cris_elf_merge_private_bfd_data): Drop variables old_flags,
+ new_flags. Don't call cris_elf_final_write_processing. Don't
+ look at the actual elf header flags at all; use
+ bfd_get_symbol_leading_char to check ibfd, obfd. Trap difference
+ in bfd_get_mach for ibfd and obfd and handle merging of compatible
+ objects.
+ (bfd_elf32_bfd_copy_private_bfd_data): Define.
+ * reloc.c (BFD_RELOC_CRIS_SIGNED_8, BFD_RELOC_CRIS_UNSIGNED_8)
+ (BFD_RELOC_CRIS_SIGNED_16, BFD_RELOC_CRIS_UNSIGNED_16)
+ (BFD_RELOC_CRIS_LAPCQ_OFFSET): New relocs.
+ * bfd-in2.h, libbfd.h: Regenerate.
+
+2004-11-04 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.h (ppc64_elf_edit_toc): Declare.
+ * elf64-ppc.c (struct ppc_link_hash_entry <adjust_done>): Update
+ comment.
+ (struct adjust_toc_info): New.
+ (adjust_toc_syms, ppc64_elf_edit_toc): New functions.
+
+2004-11-03 Bob Wilson <bob.wilson@acm.org>
+
+ * elf.c (assign_file_positions_for_segments): Set next_file_pos even
+ if there are no segments.
+
+2004-11-02 Daniel Jacobowitz <dan@debian.org>
+
+ * config.bfd: Mark arm-*-oabi and thumb-*-oabi as obsolete.
+
+2004-11-02 Nick Clifton <nickc@redhat.com>
+
+ * elf32-iq2000.c: Convert to ISO C90 formatting.
+
+2004-11-02 Hans-Peter Nilsson <hp@axis.com>
+
+ * elflink.c (_bfd_elf_create_got_section): Hide _GLOBAL_OFFSET_TABLE_.
+
+2004-10-28 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elfxx-ia64.c (elfNN_ia64_relocate_section): Handle weak
+ undefined symbols for R_IA64_SECREL32MSB, R_IA64_SECREL32LSB,
+ R_IA64_SECREL64MSB and R_IA64_SECREL64LSB.
+
+2004-10-28 Kaz Kojima <kkojima@rr.iij4u.or.jp>
+
+ * elf32-sh.c (tpoff): Take alignment into account.
+
+2004-10-28 Nick Clifton <nickc@redhat.com>
+
+ * elf32-iq2000.c (iq2000_elf_relocate_section): Do nothing when
+ performing a relocatable link.
+ (iq2000_elf_object_p): Do not set elf_bad_symtab. This is only
+ for MIPS ports under Irix.
+
+2004-10-27 Richard Earnshaw <rearnsha@arm.com>
+
+ * elf32-arm.h (bfd_elf32_arm_process_before_allocation): Handle
+ R_ARM_CALL and R_ARM_JUMP24 as aliases of R_ARM_PC24.
+ (elf32_arm_final_link_relocate): Ditto.
+ (arm_add_to_rel, elf32_arm_relocate_section): Ditto.
+ (elf32_arm_gc_sweep_hook, elf32_arm_check_relocs): Ditto
+ (elf32_arm_adjust_dynamic_symbol): Ditto.
+ * elfarm-nabi.c (elf32_arm_howto_table): Add R_ARM_CALL and
+ R_ARM_JUMP32. Move R_ARM_R{REL32,ABS32,PC24,BASE}...
+ (elf32_arm_r_howto): ... To here.
+ (elf32_arm_howto_from_type): Use elf32_arm_r_howto.
+
+2004-10-26 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR 475
+ * elfxx-ia64.c (elfNN_ia64_relocate_section): Correct
+ R_IA64_SECREL32MSB, R_IA64_SECREL32LSB, R_IA64_SECREL64MSB
+ and R_IA64_SECREL64LSB.
+
+2004-10-26 Paul Brook <paul@codesourcery.com>
+
+ * elflink.c (elf_finalize_dynstr): Skip shared aux structure.
+ (bfd_elf_size_dynamic_sections): Create default version definition.
+ (elf_link_output_extsym): Adjust for default symbol version.
+
+2004-10-24 Hans-Peter Nilsson <hp@bitrange.com>
+
+ * mmo.c: Adjust to ISO C.
+
+ * mmo.c (mmo_write_section_description): New function broken out
+ of mmo_internal_write_section.
+ (mmo_internal_write_section): For each of .text and .data, call
+ mmo_write_section_description before outputting contents if it has
+ nontrivially deducible vma or contents.
+ (mmo_has_leading_or_trailing_zero_tetra_p): New function.
+ (mmo_canonicalize_symtab): Adjust absolute symbols to .data
+ symbols if found within the .data address range.
+
+2004-10-24 Daniel Jacobowitz <dan@debian.org>
+
+ * opncls.c (bfd_close): Return TRUE for BFD_IN_MEMORY.
+
+2004-10-24 Hans-Peter Nilsson <hp@bitrange.com>
+
+ * mmo.c (File Layout): Correct place of misplaced blurb about
+ special data.
+
+2004-10-22 Mark Kettenis <kettenis@gnu.org>
+
+ * config.bfd: Add mips64*-*-openbsd.
+
+2004-10-21 Bob Wilson <bob.wilson@acm.org>
+
+ * elf32-xtensa.c (ebb_propose_action): Put declarations before
+ statements.
+
+2004-10-21 H.J. Lu <hongjiu.lu@intel.com>
+
+ * configure.in: (AM_INIT_AUTOMAKE): Set version to 2.15.94.
+ * configure: Regenerate.
+
+2004-10-21 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR 463
+ * aoutx.h (aout_link_input_section_std): Pass proper hash entry
+ to linker reloc_overflow callback.
+ (aout_link_input_section_ext): Likewise.
+ (aout_link_reloc_link_order): Likewise.
+ * coff-a29k.c (coff_a29k_relocate_section): Likewise.
+ * coff-alpha.c (alpha_ecoff_get_relocated_section_contents):
+ Likewise.
+ (alpha_relocate_section): Likewise.
+ * coff-arm.c (coff_arm_relocate_section): Likewise.
+ * coff-h8300.c (h8300_reloc16_extra_cases): Likewise.
+ * coff-h8500.c (extra_case): Likewise.
+ * coff-i960.c (coff_i960_relocate_section): Likewise.
+ * coff-mcore.c (coff_mcore_relocate_section): Likewise.
+ * coff-mips.c (mips_relocate_section): Likewise.
+ * coff-or32.c (coff_or32_relocate_section): Likewise.
+ * coff-ppc.c (coff_ppc_relocate_section): Likewise.
+ * coff-rs6000.c (xcoff_ppc_relocate_section): Likewise.
+ * coff-sh.c (sh_relocate_section): Likewise.
+ * coff-tic80.c (coff_tic80_relocate_section): Likewise.
+ * coff-w65.c (w65_reloc16_extra_cases): Likewise.
+ * coff-z8k.c (extra_case): Likewise.
+ * coff64-rs6000.c (xcoff64_ppc_relocate_section): Likewise.
+ * cofflink.c (_bfd_coff_reloc_link_order): Likewise.
+ (_bfd_coff_generic_relocate_section): Likewise.
+ * ecoff.c (ecoff_reloc_link_order): Likewise.
+ * elf-hppa.h (elf_hppa_relocate_section): Likewise.
+ * elf-m10200.c (mn10200_elf_relocate_section): Likewise.
+ * elf-m10300.c (mn10300_elf_relocate_section): Likewise.
+ * elf32-arm.h (elf32_arm_relocate_section): Likewise.
+ * elf32-avr.c (elf32_avr_relocate_section): Likewise.
+ * elf32-cr16c.c (elf32_cr16c_relocate_section): Likewise.
+ * elf32-cris.c (cris_elf_relocate_section): Likewise.
+ * elf32-crx.c (elf32_crx_relocate_section): Likewise.
+ * elf32-d10v.c (elf32_d10v_relocate_section): Likewise.
+ * elf32-fr30.c (fr30_elf_relocate_section): Likewise.
+ * elf32-frv.c (elf32_frv_relocate_section): Likewise.
+ * elf32-h8300.c (elf32_h8_relocate_section): Likewise.
+ * elf32-hppa.c (elf32_hppa_relocate_section): Likewise.
+ * elf32-i370.c (i370_elf_relocate_section): Likewise.
+ * elf32-i386.c (elf_i386_relocate_section): Likewise.
+ * elf32-i860.c (elf32_i860_relocate_section): Likewise.
+ * elf32-ip2k.c (ip2k_elf_relocate_section): Likewise.
+ * elf32-iq2000.c (iq2000_elf_relocate_section): Likewise.
+ * elf32-m32r.c (m32r_elf_relocate_section): Likewise.
+ * elf32-m68hc1x.c (elf32_m68hc11_relocate_section): Likewise.
+ * elf32-m68k.c (elf_m68k_relocate_section): Likewise.
+ * elf32-mcore.c (mcore_elf_relocate_section): Likewise.
+ * elf32-msp430.c (elf32_msp430_relocate_section): Likewise.
+ * elf32-openrisc.c (openrisc_elf_relocate_section): Likewise.
+ * elf32-ppc.c (ppc_elf_relocate_section): Likewise.
+ * elf32-s390.c (elf_s390_relocate_section): Likewise.
+ * elf32-sh.c (sh_elf_relocate_section): Likewise.
+ * elf32-sparc.c (elf32_sparc_relocate_section): Likewise.
+ * elf32-v850.c (v850_elf_relocate_section): Likewise.
+ * elf32-vax.c (elf_vax_relocate_section): Likewise.
+ * elf32-xstormy16.c (xstormy16_elf_relocate_section): Likewise.
+ * elf64-alpha.c (elf64_alpha_relocate_section): Likewise.
+ * elf64-mmix.c (mmix_elf_relocate_section): Likewise.
+ * elf64-ppc.c (ppc64_elf_relocate_section): Likewise.
+ * elf64-s390.c (elf_s390_relocate_section): Likewise.
+ * elf64-sh64.c (sh_elf64_relocate_section): Likewise.
+ * elf64-sparc.c (sparc64_elf_relocate_section): Likewise.
+ * elf64-x86-64.c (elf64_x86_64_relocate_section): Likewise.
+ * elflink.c (elf_reloc_link_order): Likewise.
+ * elfxx-ia64.c (elfNN_ia64_relocate_section): Likewise.
+ * elfxx-mips.c (_bfd_mips_elf_relocate_section): Likewise.
+ (_bfd_elf_mips_get_relocated_section_contents): Likewise.
+ * linker.c (_bfd_generic_reloc_link_order): Likewise.
+ * pdp11.c (pdp11_aout_link_input_section): Likewise.
+ (aout_link_reloc_link_order): Likewise.
+ * reloc.c (bfd_generic_get_relocated_section_contents):
+ Likewise.
+ * xcofflink.c (xcoff_reloc_link_order): Likewise.
+ * simple.c (simple_dummy_reloc_overflow): Updated.
+
+2004-10-20 Andreas Schwab <schwab@suse.de>
+
+ * elf32-m68k.c (elf_m68k_plt_sym_val): New function.
+ (elf_backend_plt_sym_val): Define.
+
+2004-10-19 Danny Smith <dannysmith@users.sourceforege.net>
+
+ * config.bfd: Set targ_underscore=yes for PE COFF targets
+
+2004-10-19 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (opd_entry_value): Handle --just-symbols objects.
+ (ppc64_elf_edit_opd): Likewise.
+
+2004-10-18 Mark Mitchell <mark@codesourcery.com>
+
+ * elfarm-nabi.c (ELF_DYNAMIC_SEC_FLAGS): Add comment.
+ * elflink.c (_bfd_elf_create_dynamic_sections): For a loaded PLT,
+ set SEC_ALLOC and SEC_LOAD.
+
+2004-10-18 Nick Clifton <nickc@redhat.com>
+
+ * elf32-xstormy16.c (xstormy16_elf_relocate_section): Compute
+ 'name' for relocs against both local and global symbols.
+
+2004-10-16 Daniel Jacobowitz <dan@debian.org>
+
+ * bfd-in2.h: Regenerate.
+ * bfd.c (struct bfd): Add no_export.
+ * elflink.c (elf_link_add_object_symbols): Handle no_export.
+
+2004-10-15 Alan Modra <amodra@bigpond.net.au>
+
+ * config.bfd: Whitespace cleanup.
+ * Makefile.am: Run "make dep-am"
+ * Makefile.in: Regenerate.
+
+2004-10-15 Jakub Jelinek <jakub@redhat.com>
+
+ * elflink.c (struct already_linked_section): Removed.
+ (try_match_symbols_in_sections, already_linked): Removed.
+ (_bfd_elf_section_already_linked): Skip ^\.gnu\.linkonce\.[^.]*\.
+ prefix of section names when finding already_linked_table
+ chain. Compare section names. Instead of calling already_linked,
+ do it inline and only for sections in the same already_linked_list.
+
+2004-10-15 Alan Modra <amodra@bigpond.net.au>
+
+ * elf-eh-frame.c (_bfd_elf_eh_frame_section_offset): Add "info"
+ parameter. If called after _bfd_elf_write_section_eh_frame,
+ don't allow a -2 return unless need_* bit is already set, and
+ handle offsets adjusted for output_offset.
+ * elf-bfd.h (_bfd_elf_eh_frame_section_offset): Update prototype.
+ * elf.c (_bfd_elf_section_offset): Update call.
+
+2004-10-13 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR 440
+ * coffcode.h (coff_compute_section_file_positions): Cast to
+ bfd_vma when computing page alignment.
+
+2004-10-13 Mark Mitchell <mark@codesourcery.com>
+
+ * elf32-arm.h (elf32_arm_finish_dynamic_sections): Use file
+ offsets, not VMAs, for DT_VERSYM, DT_VERDEF, DT_VERNEED.
+
+2004-10-12 Mark Mitchell <mark@codesourcery.com>
+
+ * elf32-arm.h (elf32_arm_finish_dynamic_symbol): Make .rel.plt
+ relocations use a virtual address, not a section offset.
+
+2004-10-12 Bob Wilson <bob.wilson@acm.org>
+
+ * elf32-xtensa.c (elf_xtensa_get_private_bfd_flags): Delete.
+ (narrow_instruction, widen_instruction): Remove unnecessary calls to
+ xtensa_format_encode.
+ (ebb_propose_action): Inline call to ebb_add_proposed_action.
+ (ebb_add_proposed_action): Delete.
+
+2004-10-12 Bob Wilson <bob.wilson@acm.org>
+
+ * elf32-xtensa.c: Use ISO C90 formatting.
+
+2004-10-12 Paul Brook <paul@codesourcery.com>
+
+ * elf32-arm.h (elf32_arm_merge_private_bfd_data): Rephrase error
+ message.
+
+2004-10-12 Paul Brook <paul@codesourcery.com>
+
+ * elf32-arm.h: Support EABI version 4 objects.
+
+2004-10-12 Alan Modra <amodra@bigpond.net.au>
+
+ PR 325
+ * cpu-i386.c (bfd_x86_64_arch_intel_syntax): Place last in chain.
+ Don't mark as default.
+ (bfd_x86_64_arch): Don't mark as default.
+
+2004-10-12 Alan Modra <amodra@bigpond.net.au>
+
+ * elflink.c (enum action_discarded): New.
+ (elf_section_complain_discarded): Delete.
+ (elf_action_discarded): New function subsuming the above and also
+ controlling reloc behaviour.
+ (elf_link_input_bfd): Use it.
+
+2004-10-11 Jakub Jelinek <jakub@redhat.com>
+
+ * elf.c (bfd_section_from_shdr): Handle SHT_GNU_LIBLIST.
+ (special_sections): Add .gnu.liblist and .gnu.conflict.
+ (assign_section_numbers): Handle SHT_GNU_LIBLIST.
+
+2004-10-11 Alan Modra <amodra@bigpond.net.au>
+
+ PR 233
+ * elflink.c (elf_link_input_bfd): Try harder to support
+ relocations against symbols in removed linkonce sections.
+
+2004-10-11 Alan Modra <amodra@bigpond.net.au>
+
+ * elflink.c (elf_link_input_bfd): Revert PR 354 change.
+
+ PR 354
+ * elflink.c (elf_link_input_bfd): Check that relocs in SEC_ALLOC
+ sections do not reference symbols in non-SEC_ALLOC sections.
+
+2004-10-11 Alan Modra <amodra@bigpond.net.au>
+
+ PR 437
+ * elflink.c (elf_link_sort_relocs): Don't bomb on unusual sections.
+ (_bfd_elf_link_omit_section_dynsym): Formatting.
+
+2004-10-10 Alan Modra <amodra@bigpond.net.au>
+
+ * libbfd-in.h (BFD_ASSERT, BFD_FAIL): Wrap macro body in do while.
+ * libbfd.h: Regnerate.
+ * elf32-cris.c: Add missing semicolon to BFD_ASSERTs.
+ * elf32-frv.c: Likewise.
+ * elf32-m32r.c: Likewise.
+ * elf32-ppc.c: Likewise.
+ * elf64-hppa.c: Likewise.
+ * elfxx-ia64.c: Likewise.
+ * opncls.c: Likewise.
+
+2004-10-10 Alan Modra <amodra@bigpond.net.au>
+
+ * elf-bfd.h (struct eh_frame_hdr_info): Add offsets_adjusted.
+ * elf-eh-frame.c (_bfd_elf_write_section_eh_frame): Adjust
+ offsets stored in struct eh_cie_fde entries before doing other
+ work.
+
+ * elf-bfd.h (struct eh_cie_fde): Add cie_inf, remove sec.
+ (struct eh_frame_hdr_info): Add last_cie_inf, remove last_cie_offset.
+ * elf-eh-frame.c (_bfd_elf_discard_section_eh_frame): Delete code
+ setting offsets for removed CIEs. Don't set "sec", instead set
+ cie_inf for FDEs. Keep a pointer to last struct eh_cie_fde for a
+ CIE in hdr_info. Only set make_relative and make_lsda_relative
+ for CIEs. Use pointers rather than array indices.
+ (_bfd_elf_eh_frame_section_offset): Test/set make_relative,
+ make_lsda_relative, need_* on cie_inf for FDEs.
+ (_bfd_elf_write_section_eh_frame): Adjust offset and new_offset for
+ section output_offset. Delete cie_offset, instead use cie_inf
+ pointer to CIE entry. Use need_relative and need_lsda_relative on
+ CIE entry for FDEs. Use pointers rather than array indices.
+
+2004-10-09 Alan Modra <amodra@bigpond.net.au>
+
+ * coff-rs6000.c (rs6000coff_vec): Add initializer for
+ bfd_is_target_special_symbol.
+ * coff64-rs6000.c (rs6000coff64_vec): Likewise.
+ * som.c (som_bfd_is_target_special_symbol): Define.
+
+2004-10-08 Nick Clifton <nickc@redhat.com>
+
+ * configure.in: (AM_INIT_AUTOMAKE): Set version to 2.15.93.
+ * configure: Regenerate.
+ * bfd-in2.h: Regenerate.
+ * syms.c (bfd_is_target_special_symbol): New interface function.
+ Returns true when a symbol should be considered to be special.
+ * targets.c (bfd_target): Include bfd_is_target_special_symbol in
+ the symbol jump table.
+ * elf32-arm.h (elf32_arm_is_target_special_symbol): New function.
+ Return true iff the symbol is a mapping symbol.
+ (bfd_elf32_bfd_is_target_special_symbol): Define.
+ * elfxx-target.h: Provide a default definition for
+ bfd_is_target_special_symbol.
+ * aout-target.h: Likewise.
+ * aout-tic30.c: Likewise.
+ * binary.c: Likewise.
+ * coffcode.h: Likewise.
+ * i386msdos.c: Likewise.
+ * ieee.c: Likewise.
+ * ihex.c: Likewise.
+ * libaout.h: Likewise.
+ * libbfd-in.h: Likewise
+ * libecoff.h: Likewise.
+ * mach-o.c: Likewise.
+ * mmo.c: Likewise.
+ * nlm-target.h: Likewise.
+ * oasys.c: Likewise.
+ * pef.c: Likewise.
+ * ppcboot.c: Likewise.
+ * srec.c: Likewise.
+ * tekhex.c: Likewise.
+ * versados.c: Likewise.
+ * vms.c: Likewise.
+ * xcoff-target.h: Likewise.
+ * xsym.c: Likewise.
+ * libbfd.h: Regenerate.
+
+2004-10-08 Daniel Jacobowitz <dan@debian.org>
+
+ * config.bfd: Include 64-bit support for i[3-7]86-*-solaris2*.
+ * elf64-x86-64.c (elf64_x86_64_section_from_shdr): New function.
+ (elf_backend_section_from_shdr): Define.
+
+2004-10-08 Alan Modra <amodra@bigpond.net.au>
+
+ * syms.c (bfd_is_local_label): Return false for file symbols.
+
+2004-10-07 Bob Wilson <bob.wilson@acm.org>
+ David Heine <dlheine@tensilica.com>
+
+ * elf32-xtensa.c (elf32xtensa_size_opt): New global variable.
+ (xtensa_default_isa): Global variable moved here from xtensa-isa.c.
+ (elf32xtensa_no_literal_movement): New global variable.
+ (elf_howto_table): Add entries for new relocations.
+ (elf_xtensa_reloc_type_lookup): Handle new relocations.
+ (property_table_compare): When addresses are equal, compare sizes and
+ various property flags.
+ (property_table_matches): New.
+ (xtensa_read_table_entries): Extend to read new property tables. Add
+ output_addr parameter to indicate that output addresses should be used.
+ Use bfd_get_section_limit.
+ (elf_xtensa_find_property_entry): New.
+ (elf_xtensa_in_literal_pool): Use elf_xtensa_find_property_entry.
+ (elf_xtensa_check_relocs): Handle new relocations.
+ (elf_xtensa_do_reloc): Use bfd_get_section_limit. Handle new
+ relocations. Use new xtensa-isa.h functions.
+ (build_encoding_error_message): Remove encode_result parameter. Add
+ new target_address parameter used to detect alignment errors.
+ (elf_xtensa_relocate_section): Use bfd_get_section_limit. Clean up
+ error handling. Use new is_operand_relocation function.
+ (elf_xtensa_combine_prop_entries, elf_xtensa_merge_private_bfd_data):
+ Use underbar macro for error messages. Formatting.
+ (get_const16_opcode): New.
+ (get_l32r_opcode): Add a separate flag for initialization.
+ (get_relocation_opnd): Operand number is no longer explicit in the
+ relocation. Change to decode the opcode and analyze its operands.
+ (get_relocation_slot): New.
+ (get_relocation_opcode): Add bfd parameter. Use bfd_get_section_limit.
+ Use new xtensa-isa.h functions to handle multislot instructions.
+ (is_l32r_relocation): Add bfd parameter. Use is_operand_relocation.
+ (get_asm_simplify_size, is_alt_relocation, is_operand_relocation,
+ insn_decode_len, insn_decode_opcode, check_branch_target_aligned,
+ check_loop_aligned, check_branch_target_aligned_address, narrowable,
+ widenable, narrow_instruction, widen_instruction, op_single_fmt_table,
+ get_single_format, init_op_single_format_table): New.
+ (elf_xtensa_do_asm_simplify): Add error_message parameter and use it
+ instead of calling _bfd_error_handler. Use new xtensa-isa.h functions.
+ (contract_asm_expansion): Add error_message parameter and pass it to
+ elf_xtensa_do_asm_simplify. Replace use of R_XTENSA_OP0 relocation
+ with R_XTENSA_SLOT0_OP.
+ (get_expanded_call_opcode): Extend to handle either L32R or CONST16
+ instructions. Use new xtensa-isa.h functions.
+ (r_reloc struct): Add new virtual_offset field.
+ (r_reloc_init): Add contents and content_length parameters. Set
+ virtual_offset field to zero. Add contents to target_offset field for
+ partial_inplace relocations.
+ (r_reloc_is_defined): Check for null.
+ (print_r_reloc): New debug function.
+ (source_reloc struct): Replace xtensa_operand field with pair of the
+ opcode and the operand position. Add is_abs_literal field.
+ (init_source_reloc): Specify operand by opcode/position pair. Set
+ is_abs_literal field.
+ (source_reloc_compare): When target_offsets are equal, compare other
+ fields to make sorting predictable.
+ (literal_value struct): Add is_abs_literal field.
+ (value_map_hash_table struct): Add has_last_loc and last_loc fields.
+ (init_literal_value): New.
+ (is_same_value): Replace with ...
+ (literal_value_equal): ... this function. Add comparisons of
+ virtual_offset and is_abs_literal fields.
+ (value_map_hash_table_init): Use bfd_zmalloc. Check for allocation
+ failure. Initialize has_last_loc field.
+ (value_map_hash_table_delete): New.
+ (hash_literal_value): Rename to ...
+ (literal_value_hash): ... this. Include is_abs_literal flag and
+ virtual_offset field in the hash value.
+ (get_cached_value): Rename to ...
+ (value_map_get_cached_value): ... this. Update calls to
+ literal_value_hash and literal_value_equal.
+ (add_value_map): Check for allocation failure. Update calls to
+ value_map_get_cached_value and literal_value_hash.
+ (text_action, text_action_list, text_action_t): New types.
+ (find_fill_action, compute_removed_action_diff, adjust_fill_action,
+ text_action_add, text_action_add_literal, offset_with_removed_text,
+ offset_with_removed_text_before_fill, find_insn_action,
+ print_action_list, print_removed_literals): New.
+ (offset_with_removed_literals): Delete.
+ (xtensa_relax_info struct): Add is_relaxable_asm_section, action_list,
+ fix_array, fix_array_count, allocated_relocs, relocs_count, and
+ allocated_relocs_count fields.
+ (init_xtensa_relax_info): Initialize new fields.
+ (reloc_bfd_fix struct): Add new translated field.
+ (reloc_bfd_fix_init): Add translated parameter and use it to set the
+ translated field.
+ (fix_compare, cache_fix_array): New.
+ (get_bfd_fix): Remove fix_list parameter and get all relax_info for the
+ section via get_xtensa_relax_info. Use cache_fix_array to set up
+ sorted fix_array and use bsearch instead of linear search.
+ (section_cache_t): New struct.
+ (init_section_cache, section_cache_section, clear_section_cache): New.
+ (ebb_t, ebb_target_enum, proposed_action, ebb_constraint): New types.
+ (init_ebb_constraint, free_ebb_constraint, init_ebb, extend_ebb_bounds,
+ extend_ebb_bounds_forward, extend_ebb_bounds_backward,
+ insn_block_decodable_len, ebb_propose_action, ebb_add_proposed_action):
+ New.
+ (retrieve_contents): Use bfd_get_section_limit.
+ (elf_xtensa_relax_section): Add relocations_analyzed flag. Update call
+ to compute_removed_literals. Free value_map_hash_table when no longer
+ needed.
+ (analyze_relocations): Check is_relaxable_asm_section flag. Call
+ compute_text_actions for all sections.
+ (find_relaxable_sections): Mark sections as relaxable if they contain
+ ASM_EXPAND relocations that can be optimized. Adjust r_reloc_init
+ call. Increment relax_info src_count field only for appropriate
+ relocation types. Remove is_literal_section check.
+ (collect_source_relocs): Use bfd_get_section_limit. Adjust calls to
+ r_reloc_init and find_associated_l32r_irel. Check
+ is_relaxable_asm_section flag. Handle L32R instructions with absolute
+ literals. Pass is_abs_literal flag to init_source_reloc.
+ (is_resolvable_asm_expansion): Use bfd_get_section_limit. Check for
+ CONST16 instructions. Adjust calls to r_reloc_init and
+ pcrel_reloc_fits. Handle weak symbols conservatively.
+ (find_associated_l32r_irel): Add bfd parameter and pass it to
+ is_l32r_relocation.
+ (compute_text_actions, compute_ebb_proposed_actions,
+ compute_ebb_actions, check_section_ebb_pcrels_fit,
+ check_section_ebb_reduces, text_action_add_proposed,
+ compute_fill_extra_space): New.
+ (remove_literals): Replace with ...
+ (compute_removed_literals): ... this function. Call
+ init_section_cache. Use bfd_get_section_limit. Sort internal_relocs.
+ Call xtensa_read_table_entries to get the property table. Skip
+ relocations other than R_XTENSA_32 and R_XTENSA_PLT. Use new
+ is_removable_literal, remove_dead_literal, and
+ identify_literal_placement functions.
+ (get_irel_at_offset): Rewrite to use bsearch on sorted relocations
+ instead of linear search.
+ (is_removable_literal, remove_dead_literal,
+ identify_literal_placement): New.
+ (relocations_reach): Update check for literal not referenced by any
+ PC-relative relocations. Adjust call to pcrel_reloc_fits.
+ (coalesce_shared_literal, move_shared_literal): New.
+ (relax_section): Use bfd_get_section_limit. Call
+ translate_section_fixes. Update calls to r_reloc_init and
+ offset_with_removed_text. Check new is_relaxable_asm_section flag.
+ Add call to pin_internal_relocs. Add special handling for
+ R_XTENSA_ASM_SIMPLIFY and R_XTENSA_DIFF* relocs. Use virtual_offset
+ info to calculate new addend_displacement variable. Replace code for
+ deleting literals with more general code to perform the actions
+ determined by the action_list for the section.
+ (translate_section_fixes, translate_reloc_bfd_fix): New.
+ (translate_reloc): Check new is_relaxable_asm_section flag. Call
+ find_removed_literal only if is_operand_relocation. Update call to
+ offset_with_removed_text. Use new target_offset and removed_bytes
+ variables.
+ (move_literal): New.
+ (relax_property_section): Use bfd_get_section_limit. Set new
+ is_full_prop_section flag and handle new property tables. Update calls
+ to r_reloc_init and offset_with_removed_text. Check
+ is_relaxable_asm_section flag. Handle expansion of zero-sized
+ unreachable entries, with use of offset_with_removed_text_before_fill.
+ For relocatable links, combine entries only for literal tables.
+ (relax_section_symbols): Check is_relaxable_asm_section flag. Update
+ calls to offset_with_removed_text. Translate st_size field for
+ function symbols.
+ (do_fix_for_relocatable_link): Change to return bfd_boolean to indicate
+ failure. Add contents parameter. Update call to get_bfd_fix. Update
+ call to r_reloc_init. Call _bfd_error_handler and return FALSE for
+ R_XTENSA_ASM_EXPAND relocs.
+ (do_fix_for_final_link): Add input_bfd and contents parameters. Update
+ call to get_bfd_fix. Include offset from contents for partial_inplace
+ relocations.
+ (is_reloc_sym_weak): New.
+ (pcrel_reloc_fits): Use new xtensa-isa.h functions.
+ (prop_sec_len): New.
+ (xtensa_is_property_section): Handle new property sections.
+ (is_literal_section): Delete.
+ (internal_reloc_compare): When r_offset matches, compare r_info and
+ r_addend to make sorting predictable.
+ (internal_reloc_matches): New.
+ (xtensa_get_property_section_name): Handle new property sections.
+ (xtensa_get_property_predef_flags): New.
+ (xtensa_callback_required_dependence): Use bfd_get_section_limit.
+ Update calls to xtensa_isa_init, is_l32r_relocation, and r_reloc_init.
+ * xtensa-isa.c (xtensa_default_isa): Moved to elf32-xtensa.c.
+ (xtisa_errno, xtisa_error_msg): New variables.
+ (xtensa_isa_errno, xtensa_isa_error_msg): New.
+ (xtensa_insnbuf_alloc): Add error handling.
+ (xtensa_insnbuf_to_chars): Add num_chars parameter. Update to
+ use xtensa_format_decode. Add error handling.
+ (xtensa_insnbuf_from_chars): Add num_chars parameter. Decode the
+ instruction length to find the number of bytes to copy.
+ (xtensa_isa_init): Add error handling. Replace calls to
+ xtensa_load_isa and xtensa_extend_isa with code to initialize lookup
+ tables in the xtensa_modules structure.
+ (xtensa_check_isa_config, xtensa_add_isa, xtensa_load_isa,
+ xtensa_extend_isa): Delete.
+ (xtensa_isa_free): Change to only free lookup tables.
+ (opname_lookup_compare): Replace with ...
+ (xtensa_isa_name_compare): ... this function. Use strcasecmp.
+ (xtensa_insn_maxlength): Rename to ...
+ (xtensa_isa_maxlength): ... this.
+ (xtensa_insn_length): Delete.
+ (xtensa_insn_length_from_first_byte): Replace with ...
+ (xtensa_isa_length_from_chars): ... this function.
+ (xtensa_num_opcodes): Rename to ...
+ (xtensa_isa_num_opcodes): ... this.
+ (xtensa_isa_num_pipe_stages, xtensa_isa_num_formats,
+ xtensa_isa_num_regfiles, xtensa_isa_num_stages,
+ xtensa_isa_num_sysregs, xtensa_isa_num_interfaces,
+ xtensa_isa_num_funcUnits, xtensa_format_name, xtensa_format_lookup,
+ xtensa_format_decode, xtensa_format_encode, xtensa_format_length,
+ xtensa_format_num_slots, xtensa_format_slot_nop_opcode,
+ xtensa_format_get_slot, xtensa_format_set_slot): New functions.
+ (xtensa_opcode_lookup): Add error handling.
+ (xtensa_decode_insn): Replace with ...
+ (xtensa_opcode_decode): ... this function, with new format and
+ slot parameters. Add error handling.
+ (xtensa_encode_insn): Replace with ...
+ (xtensa_opcode_encode): ... this function, which does the encoding via
+ one of the entries in the "encode_fns" array. Add error handling.
+ (xtensa_opcode_name): Add error handling.
+ (xtensa_opcode_is_branch, xtensa_opcode_is_jump, xtensa_opcode_is_loop,
+ xtensa_opcode_is_call): New.
+ (xtensa_num_operands): Replace with ...
+ (xtensa_opcode_num_operands): ... this function. Add error handling.
+ (xtensa_opcode_num_stateOperands,
+ xtensa_opcode_num_interfaceOperands, xtensa_opcode_num_funcUnit_uses,
+ xtensa_opcode_funcUnit_use, xtensa_operand_name,
+ xtensa_operand_is_visible): New.
+ (xtensa_get_operand, xtensa_operand_kind): Delete.
+ (xtensa_operand_inout): Add error handling and special-case for
+ "sout" operands.
+ (xtensa_operand_get_field, xtensa_operand_set_field): Rewritten to
+ operate on one slot of an instruction. Added error handling.
+ (xtensa_operand_encode): Handle default operands with no encoding
+ functions. Check for success by comparing against decoded value.
+ Add error handling.
+ (xtensa_operand_decode): Handle default operands. Return decoded value
+ through argument pointer. Add error handling.
+ (xtensa_operand_is_register, xtensa_operand_regfile,
+ xtensa_operand_num_regs, xtensa_operand_is_known_reg): New.
+ (xtensa_operand_isPCRelative): Rename to ...
+ (xtensa_operand_is_PCrelative): ... this. Add error handling.
+ (xtensa_operand_do_reloc, xtensa_operand_undo_reloc): Return value
+ through argument pointer. Add error handling.
+ (xtensa_stateOperand_state, xtensa_stateOperand_inout,
+ xtensa_interfaceOperand_interface, xtensa_regfile_lookup,
+ xtensa_regfile_lookup_shortname, xtensa_regfile_name,
+ xtensa_regfile_shortname, xtensa_regfile_view_parent,
+ xtensa_regfile_num_bits, xtensa_regfile_num_entries,
+ xtensa_state_lookup, xtensa_state_name, xtensa_state_num_bits,
+ xtensa_state_is_exported, xtensa_sysreg_lookup,
+ xtensa_sysreg_lookup_name, xtensa_sysreg_name, xtensa_sysreg_number,
+ xtensa_sysreg_is_user, xtensa_interface_lookup, xtensa_interface_name,
+ xtensa_interface_num_bits, xtensa_interface_inout,
+ xtensa_interface_has_side_effect, xtensa_funcUnit_lookup,
+ xtensa_funcUnit_name, xtensa_funcUnit_num_copies): New.
+ * xtensa-modules.c: Rewrite to use new data structures.
+ * reloc.c (BFD_RELOC_XTENSA_DIFF8, BFD_RELOC_XTENSA_DIFF16,
+ BFD_RELOC_XTENSA_DIFF32, BFD_RELOC_XTENSA_SLOT0_OP,
+ BFD_RELOC_XTENSA_SLOT1_OP, BFD_RELOC_XTENSA_SLOT2_OP,
+ BFD_RELOC_XTENSA_SLOT3_OP, BFD_RELOC_XTENSA_SLOT4_OP,
+ BFD_RELOC_XTENSA_SLOT5_OP, BFD_RELOC_XTENSA_SLOT6_OP,
+ BFD_RELOC_XTENSA_SLOT7_OP, BFD_RELOC_XTENSA_SLOT8_OP,
+ BFD_RELOC_XTENSA_SLOT9_OP, BFD_RELOC_XTENSA_SLOT10_OP,
+ BFD_RELOC_XTENSA_SLOT11_OP, BFD_RELOC_XTENSA_SLOT12_OP,
+ BFD_RELOC_XTENSA_SLOT13_OP, BFD_RELOC_XTENSA_SLOT14_OP,
+ BFD_RELOC_XTENSA_SLOT0_ALT, BFD_RELOC_XTENSA_SLOT1_ALT,
+ BFD_RELOC_XTENSA_SLOT2_ALT, BFD_RELOC_XTENSA_SLOT3_ALT,
+ BFD_RELOC_XTENSA_SLOT4_ALT, BFD_RELOC_XTENSA_SLOT5_ALT,
+ BFD_RELOC_XTENSA_SLOT6_ALT, BFD_RELOC_XTENSA_SLOT7_ALT,
+ BFD_RELOC_XTENSA_SLOT8_ALT, BFD_RELOC_XTENSA_SLOT9_ALT,
+ BFD_RELOC_XTENSA_SLOT10_ALT, BFD_RELOC_XTENSA_SLOT11_ALT,
+ BFD_RELOC_XTENSA_SLOT12_ALT, BFD_RELOC_XTENSA_SLOT13_ALT,
+ BFD_RELOC_XTENSA_SLOT14_ALT): Add new relocations.
+ * Makefile.am (xtensa-isa.lo, xtensa-modules.lo): Update dependencies.
+ * Makefile.in: Regenerate.
+ * bfd-in2.h: Likewise.
+ * libbfd.h: Likewise.
+
+2004-10-07 Richard Sandiford <rsandifo@redhat.com>
+
+ * elf64-mips.c (mips_elf64_write_rel): Use STN_UNDEF for relocs
+ against the absolute section.
+ (mips_elf64_write_rela): Likewise.
+
+2004-10-07 Jan Beulich <jbeulich@novell.com>
+
+ * elf.c (elf_find_function): Don't generally check for matching
+ section, just for non-file symbols. Remove redunant comparison
+ for the latter.
+ * elf32-arm.h (arm_elf_find_function): Likewise.
+
+2004-10-07 Jeff Baker <jbaker@qnx.com>
+
+ * elflink.c (_bfd_elf_add_dynamic_entry): Add code to warn if
+ adding a DT_TEXTREL to a shared object and --warn-shared-textrel
+ was specified.
+
+2004-10-04 Roland McGrath <roland@redhat.com>
+
+ * hash.c (bfd_hash_set_default_size): Use const for table.
+ Use size_t instead of int for variable compared to sizeof results.
+
+2004-10-05 Alan Modra <amodra@bigpond.net.au>
+
+ PR 425
+ * syms.c (_bfd_stab_section_find_nearest_line): Ignore R_*_NONE relocs.
+
+2004-10-01 Paul Brook <paul@codesourcery.com>
+
+ * elf32-arm.h (elf32_arm_fake_sections,
+ is_arm_elf_unwind_section_name, elf32_arm_section_from_shdr): New
+ functions.
+ (elf_backend_fake_sections, elf_backend_section_from_shdr): Define.
+
+2004-10-01 Alan Modra <amodra@bigpond.net.au>
+
+ * elf-bfd.h (struct eh_cie_fde): Add need_relative and
+ need_lsda_relative.
+ * elf-eh-frame.c (_bfd_elf_eh_frame_section_offset): Set
+ need_relative or need_lsda_relative if we are processing an
+ offset for a reloc on a FDE initial loc or LSDA field
+ respectively.
+ (_bfd_elf_write_section_eh_frame): Test need_relative and
+ need_lsda_relative in place of corresponding make_* field
+ when deciding to use pc-relative encodings.
+
+2004-09-30 Paul Brook <paul@codesourcery.com>
+
+ * elf32-arm.h (bfd_elf32_arm_set_target_relocs): Handle "abs"
+ target2 relocation type.
+
+2004-09-30 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR 414
+ * elflink.c (_bfd_elf_merge_symbol): Check TLS symbol.
+
+2004-09-30 Paul Brook <paul@codesourcery.com>
+
+ * reloc.c: Add BFD_RELOC_ARM_SMI.
+ * bfd-in2.h: Regenerate.
+ * libbfd.h: Ditto.
+
+2004-09-24 Alan Modra <amodra@bigpond.net.au>
+
+ * dwarf2.c (_bfd_dwarf2_find_nearest_line): Add output section
+ vma and output offset to address.
+ * simple.c (simple_save_output_info): Only set output section
+ and offset for debug sections, or those not already set up by
+ the linker.
+ (bfd_simple_get_relocated_section_contents): Update comment.
+
+2004-09-24 Alan Modra <amodra@bigpond.net.au>
+
+ * elf.c (IS_LOADED): Delete.
+ (assign_file_positions_for_segments): Just test SEC_LOAD instead.
+ Restore SEC_HAS_CONTENTS test to the one place it was used prior
+ to 2004-09-22.
+
+2004-09-23 Alan Modra <amodra@bigpond.net.au>
+
+ PR gas/396
+ * elf32-sparc.c (elf32_sparc_final_write_processing): Handle
+ bfd_mach_sparc_sparclet and bfd_mach_sparc_sparclite. Remove
+ redundant assignment of EM_SPARC.
+
+2004-09-22 Brian Ford <ford@vss.fsi.com>
+
+ * pei-i386.c (COFF_SECTION_ALIGNMENT_ENTRIES): Enable 16 byte
+ alignment for .rdata sections so sse[2] code works with gcc >= 3.3.3
+ constants.
+ * pe-i386.c (COFF_SECTION_ALIGNMENT_ENTRIES): Likewise.
+
+2004-09-22 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-ppc.c (ppc_elf_modify_segment_map): Delete.
+ (elf_backend_modify_segment_map): Don't define.
+
+2004-09-22 Alan Modra <amodra@bigpond.net.au>
+
+ * elf.c (IS_LOADED): Define.
+ (assign_file_positions_for_segments): Don't round up file offset of
+ PT_LOAD segments containing no SEC_LOAD sections, instead round down.
+ Delete code handling link script adjustment of lma. Do the adjust
+ in later code handling similar ajustments. Remove dead code error
+ check. Warn if section lma would require a negative offset
+ adjustment. Tweak lma adjustment to use p_filesz rather than p_memsz.
+ Use p_vaddr + p_memsz inside section loop in place of voff. Don't
+ update voff in section loop. Change voff in segment loop to be an
+ adjustment on top of "off". Set sec->filepos and update "off" later.
+ Test for loadable sections consistently using IS_LOADED. Similarly,
+ test for alloc-only sections other than .tbss consistently.
+ Don't bother checking SEC_ALLOC in PT_LOAD segments. Remove FIXME.
+ Tidy PT_NOTE handling. Use %B and %A in error messages.
+ (assign_file_positions_except_relocs): Use %B in error message.
+
+2004-09-17 H.J. Lu <hongjiu.lu@intel.com>
+
+ * Makefile.am (AUTOMAKE_OPTIONS): Require 1.9.
+ (CONFIG_STATUS_DEPENDENCIES): New.
+ (Makefile): Removed.
+ (config.status): Likewise.
+ * Makefile.in: Regenerated.
+
+2004-09-17 Paul Brook <paul@codesourcery.com>
+
+ * bfd-in.h (bfd_elf32_arm_set_target_relocs): Add prototype.
+ (bfd_elf32_arm_process_before_allocation): Update prototype.
+ * bfd-in2.h: Regenerate.
+ * elf32-arm.h (elf32_arm_link_hash_table): Add target2_reloc.
+ (elf32_arm_link_hash_table_create): Set it.
+ (bfd_elf32_arm_process_before_allocation): Remove target1_is_rel.
+ (bfd_elf32_arm_set_target_relocs): New function.
+ (arm_real_reloc_type): New function.
+ (elf32_arm_final_link_relocate): Use it. Handle R_ARM_PREL31 and
+ R_ARM_GOT_PREL. Remove R_ARM_TARGET1.
+ (elf32_arm_gc_sweep_hook): Ditto.
+ (elf32_arm_check_relocs): Ditto.
+ (elf32_arm_relocate_section): Handle R_ARM_GOT_PREL.
+ * elfarm-nabi.c (elf32_arm_howto_table): Add R_ARM_PREL31 and
+ R_ARM_GOT_TARGET2.
+ (elf32_arm_got_prel): New variable.
+ (elf32_arm_howto_from_type): New function.
+ (elf32_arm_info_to_howto): Use it.
+ (elf32_arm_reloc_map): Add BFD_RELOC_ARM_PREL31 and
+ BFD_RELOC_ARM_TARGET2.
+ * libbfd.h: Regenerate.
+ * reloc.c: Add BFD_RELOC_ARM_TARGET2 and BFD_RELOC_ARM_PREL31.
+
+2004-09-17 Alan Modra <amodra@bigpond.net.au>
+
+ * ecoff.c: Update u.undef.next refs.
+ * elf64-ppc.c: Likewise.
+ * elflink.c: Likewise.
+ * linker.c: Likewise.
+ * xcofflink.c: Likewise.
+
+ * elf-bfd.h (struct elf_link_hash_entry): Rearrange. Add FIXME to
+ dynamic_def. Combine weakdef and elf_hash_value. Move vtable
+ fields to indirect struct.
+ * elf-m10300.c: Update u.weakdef refs.
+ * elf32-arm.h: Likewise.
+ * elf32-cris.c: Likewise.
+ * elf32-frv.c: Likewise.
+ * elf32-hppa.c: Likewise.
+ * elf32-i370.c: Likewise.
+ * elf32-i386.c: Likewise.
+ * elf32-m32r.c: Likewise.
+ * elf32-m68k.c: Likewise.
+ * elf32-ppc.c: Likewise.
+ * elf32-s390.c: Likewise.
+ * elf32-sh.c: Likewise.
+ * elf32-sparc.c: Likewise.
+ * elf32-vax.c: Likewise.
+ * elf32-xtensa.c: Likewise.
+ * elf64-alpha.c: Likewise.
+ * elf64-hppa.c: Likewise.
+ * elf64-ppc.c: Likewise.
+ * elf64-s390.c: Likewise.
+ * elf64-sh64.c: Likewise.
+ * elf64-sparc.c: Likewise.
+ * elf64-x86-64.c: Likewise.
+ * elfxx-ia64.c: Likewise.
+ * elfxx-mips.c: Likewise.
+ * elflink.c: Likewise. Also u.elf_hash_value.
+ (elf_gc_propagate_vtable_entries_used): Update for h->vtable
+ indirection.
+ (elf_gc_smash_unused_vtentry_relocs): Likewise.
+ (bfd_elf_gc_record_vtinherit): Alloc vtable.
+ (bfd_elf_gc_record_vtentry): Likewise.
+ * elf.c (_bfd_elf_link_hash_newfunc): Use memset.
+
+2004-09-17 Alan Modra <amodra@bigpond.net.au>
+
+ * Makefile.am: Run "make dep-am".
+ * Makefile.in: Regenerate.
+ * bfd-in2.h: Regenerate.
+ * po/SRC-POTFILES.in: Regenerate.
+ * po/bfd.pot: Regenerate.
+
+2004-09-16 Alan Modra <amodra@bigpond.net.au>
+
+ * elf-bfd.h (struct elf_link_hash_entry): Replace elf_link_hash_flags
+ with bitfields. Make "type" and "other" bitfields too.
+ (ELF_LINK_HASH_REF_REGULAR, ELF_LINK_HASH_DEF_REGULAR,
+ ELF_LINK_HASH_REF_DYNAMIC, ELF_LINK_HASH_DEF_DYNAMIC,
+ ELF_LINK_HASH_REF_REGULAR_NONWEAK, ELF_LINK_HASH_DYNAMIC_ADJUSTED,
+ ELF_LINK_HASH_NEEDS_COPY, ELF_LINK_HASH_NEEDS_PLT, ELF_LINK_NON_ELF,
+ ELF_LINK_HIDDEN, ELF_LINK_FORCED_LOCAL, ELF_LINK_HASH_MARK,
+ ELF_LINK_NON_GOT_REF, ELF_LINK_DYNAMIC_DEF, ELF_LINK_DYNAMIC_WEAK,
+ ELF_LINK_POINTER_EQUALITY_NEEDED): Delete.
+ (ELF_COMMON_DEF_P, WILL_CALL_FINISH_DYNAMIC_SYMBOL): Update.
+ * elf-hppa.h: Update all uses of elf_link_hash_flags.
+ * elf-m10300.c: Likewise.
+ * elf.c: Likewise.
+ * elf32-arm.h: Likewise.
+ * elf32-cris.c: Likewise.
+ * elf32-frv.c: Likewise.
+ * elf32-hppa.c: Likewise.
+ * elf32-i370.c: Likewise.
+ * elf32-i386.c: Likewise.
+ * elf32-m32r.c: Likewise.
+ * elf32-m68k.c: Likewise.
+ * elf32-ppc.c: Likewise.
+ * elf32-s390.c: Likewise.
+ * elf32-sh-symbian.c: Likewise.
+ * elf32-sh.c: Likewise.
+ * elf32-sh64.c: Likewise.
+ * elf32-sparc.c: Likewise.
+ * elf32-vax.c: Likewise.
+ * elf32-xtensa.c: Likewise.
+ * elf64-alpha.c: Likewise.
+ * elf64-hppa.c: Likewise.
+ * elf64-ppc.c: Likewise.
+ * elf64-s390.c: Likewise.
+ * elf64-sh64.c: Likewise.
+ * elf64-sparc.c: Likewise.
+ * elf64-x86-64.c: Likewise.
+ * elflink.c: Likewise.
+ * elfxx-ia64.c: Likewise.
+ * elfxx-mips.c: Likewise.
+ * configure.in (AM_INIT_AUTOMAKE): Set version to 2.15.92.
+ * configure: Regenerate.
+ * aclocal.m4: Regenerate.
+
+2004-09-16 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-arm.h (elf32_arm_gc_sweep_hook): Add #ifndef OLD_ARM_ABI
+ around uses of R_ARM_TARGET1.
+ (elf32_arm_check_relocs): Likewise.
+
+2004-09-13 Paul Brook <paul@codesourcery.com>
+
+ * bfd-in.h (bfd_elf32_arm_process_before_allocation): Update
+ prototype.
+ * bfd-in2.h: Regenerate.
+ * libbfd.h: Regenerate.
+ * elf32-arm.h (elf32_arm_link_hash_table): Add target1_is_rel.
+ (elf32_arm_link_hash_table_create): Set target1_is_rel.
+ (bfd_elf32_arm_process_before_allocation): Ditto.
+ (elf32_arm_final_link_relocate): Handle R_ARM_TARGET1.
+ (elf32_arm_gc_sweep_hook, elf32_arm_check_relocs): Ditto.
+ * elfarm-nabi.c (elf32_arm_howto_table): Rename RELABS to TARGET1.
+ * reloc.c: Ditto.
+
+2004-09-10 Joel Brobecker <brobecker@gnat.com>
+
+ * hpux-core.c (thread_section_p): New function.
+ (hpux_core_core_file_p): Fix computation of offset in call
+ to bfd_seek. Create a ".reg" section from an arbitrary
+ ".reg/<id>" section if none was created after having read
+ all sections.
+
+2004-09-11 Andreas Schwab <schwab@suse.de>
+
+ * acinclude.m4: Fix spelling of ACX_NONCANONICAL_*.
+ * aclocal.m4: Rebuild.
+ * configure: Rebuild.
+
+2004-09-10 Joel Brobecker <brobecker@gnat.com>
+
+ * section.c (bfd_sections_find_if): Fix parameter name in
+ comment to match code.
+
+2004-09-10 Alan Modra <amodra@bigpond.net.au>
+
+ * elf.c (assign_file_positions_except_relocs): Assign relocs
+ stored in a bfd section.
+
+2004-09-08 Hans-Peter Nilsson <hp@axis.com>
+
+ * elf32-cris.c (elf_cris_adjust_gotplt_to_got): Reset
+ h->gotplt_refcount to 0, not -1.
+
+2004-09-07 Hans-Peter Nilsson <hp@axis.com>
+
+ * elf32-cris.c (cris_elf_relocate_section) <case R_CRIS_16_GOTPLT,
+ case R_CRIS_32_GOTPLT>: For internal error message, handle NULL
+ symname.
+ (cris_elf_check_relocs) <case R_CRIS_32_PLT_PCREL>: Don't try to
+ handle symbol visibility here.
+
+2004-09-07 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (struct ppc_link_hash_table): Add stub_globals.
+ (is_ppc64_elf_target): Rename from is_ppc64_target. Update all
+ callers.
+ (ppc_stub_name): Remove trailing "+0" on stub name.
+ (create_linkage_sections): Create relocations for
+ branch lookup table when --emit-relocs as well as when --shared.
+ (ppc_build_one_stub): Emit relocs for long branch stubs. Adjust
+ relbrlt test. For --emit-stub-syms, always output a sym even when
+ one already exists on a plt call stub. Put stub type in the stub
+ symbol name.
+ (ppc_size_one_stub): Size long branch stub relocs. Adjust relbrlt
+ test.
+ (ppc64_elf_size_stubs): Count global sym stubs added. Zero
+ reloc_count in stub sections. Adjust relbrlt test.
+ (ppc64_elf_build_stubs): Adjust relbrlt test. Tweak stats output.
+ * elflink.c (bfd_elf_size_dynamic_sections): Fix comment typo.
+ (elf_link_input_bfd): Ignore symbol index zero relocs when checking
+ for relocs against discarded symbols. Fix comments.
+
+2004-09-06 Mark Mitchell <mark@codesourcery.com>
+
+ * elf-bfd.h (_bfd_elf_make_dynamic_segment): Declare it.
+ * elf.c (_bfd_elf_make_dynamic_segment): New function, split out
+ from ...
+ (map_sections_to_segments): ... here. Use it. Assign a file
+ position to the .dynamic section if it is not loadable, but part
+ of the PT_DYNAMIC segment.
+ * elf32-arm.h (elf32_arm_finish_dynamic_sections): Use file
+ offsets, not VMAs, for the BPABI. Do not fill in the header in
+ the .got.plt section for the BPABI.
+ * elfarm-nabi.c (elf32_arm_symbian_modify_segment_map): Add a
+ PT_DYNAMIC segment.
+ (elf_backend_want_got_plt): Define to zero for Symbian OS.
+
+2004-09-06 Nick Clifton <nickc@redhat.com>
+
+ * elflink.c (elf_link_add_object_symbols): Set the error code to
+ bfd_error_wrong_format when the input format does not match the
+ output format.
+
+2004-09-06 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (is_ppc64_target): New function, extracted from..
+ (ppc64_elf_check_directives): ..here.
+ (ppc64_elf_size_dynamic_sections): Use it here to check bfd type
+ before accessing ppc64_elf_tdata.
+ (ppc64_elf_finish_dynamic_sections): And here too.
+
+2004-09-04 Alan Modra <amodra@bigpond.net.au>
+
+ * bfd.c (_bfd_default_error_handler): Correct loop exit.
+
+2004-09-03 Mark Mitchell <mark@codesourcery.com>
+
+ * config.bfd (arm*-*-symbianelf*): Use OS-specific target vectors.
+ * configure.in (bfd_elf32_bigarm_symbian_vec): Add it.
+ (bfd_elf32_littlearm_symbian_vec): Likewise.
+ * configure: Regenerated.
+ * elf-bfd.h (elf_backend_data): Add dynamic_sec_flags.
+ * elf32-arm.h (PLT_HEADER_SIZE): Do not define.
+ (PLT_ENTRY_SIZE): Likewise.
+ (bfd_vma_elf32_arm_symbian_plt_entry): New
+ variable.
+ (elf32_arm_link_hash_table): Add plt_header_size, plt_entry_size,
+ and symbian_p.
+ (create_got_section): Don't create sections when generating BPABI
+ objects.
+ (elf32_arm_create_dynamic_sections): Tidy.
+ (elf32_arm_link_hash_table_create): Set plt_header_size,
+ plt_entry_size, and symbian_p.
+ (elf32_arm_check_relocs): Do not mark .rel.dyn as loadable when
+ generating BPABI objects.
+ (allocate_dynrelocs): Use htab->plt_header_size, not
+ PLT_HEADER_SIZE. Do not add to .got.plt when
+ generating BPABI objects.
+ (elf32_arm_finish_dynamic_symbol): Generate Symbian OS PLTs.
+ * elfarm-nabi.c: Add SymbianOS target vectors.
+ * elflink.c (_bfd_elf_create_got_section): Use dynamic_sec_flags.
+ (_bfd_elf_link_create_dynamic_sections): Likewise.
+ * elfxx-target.h (ELF_DYNAMIC_SEC_FLAGS): New macro.
+ (elfNN_bed): Use it.
+ * targets.c (bfd_elf32_bigarm_symbian_vec): New variable.
+ (bfd_elf32_littlearm_symbian_vec): Likewise.
+ (_bfd_target_vector): Add them.
+
+2004-09-03 Nick Clifton <nickc@redhat.com>
+
+ PR 360
+ * coffcode.h (handle_COMDAT): Replace abort with an warning
+ message and allow the scan to continue.
+
+2004-09-02 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (ppc64_elf_get_synthetic_symtab): Use static_syms passed
+ in when reading relocs, not our sorted syms. Remove unnecessary
+ var.
+
+2004-08-31 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ * elf.c (special_sections): Add .gnu.linkonce.b modelled on .bss.
+
+2004-08-30 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * acinclude.m4: Require AC_CANONICAL_TARGET, not AC_CANONICAL_SYSTEM.
+ Include ../config/acx.m4 and use ACX_NONCANONICAL_* where appropriate;
+ replace uses of *_alias with *_noncanonical.
+ * aclocal.m4: Rebuild with aclocal 1.4p6.
+ * Makefile.in: Rebuild with automake 1.4p6.
+ * doc/Makefile.in: Rebuild with automake 1.4p6.
+ * configure.in: Autoupdate with autoupdate 2.59.
+ * config.in: Regenerate with autoheader 2.59.
+ * configure: Regnerate with autoconf 2.59.
+
+2004-08-28 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (ppc64_elf_get_synthetic_symtab): Copy input
+ symbol pointer arrays before modifying.
+
+2004-08-28 Alan Modra <amodra@bigpond.net.au>
+
+ * bfd.c (bfd_get_synthetic_symtab): Pass counts and both symbol tables.
+ * elf-bfd.h (_bfd_elf_get_synthetic_symtab): Adjust.
+ * elf.c (_bfd_elf_get_synthetic_symtab): Adjust.
+ * libbfd-in.h (_bfd_nodynamic_get_synthetic_symtab): Adjust.
+ * targets.c (struct bfd_target <_bfd_get_synthetic_symtab>): Adjust.
+ * elf64-ppc.c (ppc64_elf_get_synthetic_symtab): Don't read symbols.
+ Use both symbol tables on non-relocatable objects. Use a common
+ error exit. Fix "mid" warning.
+ * libbfd.h: Regenerate.
+ * bfd-in2.h: Regenerate.
+
+2004-08-28 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (ppc64_elf_branch_reloc): Check .opd is in a regular
+ object file.
+ (struct sfpr_def_parms): Save some space.
+ (sfpr_define): Here too.
+
+ * elf64-ppc.c (compare_symbols): Put section syms first.
+ (sym_exists_at): New function.
+ (ppc64_elf_get_synthetic_symtab): Use relocs to find code entry
+ points only for relocatable files. Use .opd section contents
+ otherwise. Generally clean up the code.
+
+2004-08-27 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (STD_R0_0R1, STD_R0_0R12, LD_R0_0R1, LD_R0_0R12,
+ LI_R12_0, STVX_VR0_R12_R0, LVX_VR0_R12_R0, MTLR_R0, SFPR_MAX): Define.
+ (struct sfpr_def_parms): New.
+ (sfpr_define): New function.
+ (savegpr0, savegpr0_tail, restgpr0, restgpr0_tail): New functions.
+ (savegpr1, savegpr1_tail, restgpr1, restgpr1_tail): New functions.
+ (savefpr, savefpr0_tail, restfpr, restfpr0_tail): New functions.
+ (savefpr1_tail, restfpr1_tail): New functions.
+ (savevr, savevr_tail, restvr, restvr_tail): New functions.
+ (MIN_SAVE_FPR, MAX_SAVE_FPR): Don't define.
+ (ppc64_elf_func_desc_adjust): Use sfpr_define in place of existing
+ code. Define all ABI mandated _save and _rest functions.
+
+2004-08-26 Paul Brook <paul@codesourcery.com>
+
+ * elf32-arm.h (INTERWORK_FLAG): Return true for EABIv3 objects.
+
+2004-08-26 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-m32r.c (m32r_elf_relocate_section): Don't compare with
+ TRUE or FALSE.
+
+2004-08-26 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-i386.c (elf_i386_relocate_section): Tweak last change so
+ that pcrel correction is applied for R_386_PC32.
+
+2004-08-25 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-i386.c (elf_i386_relocate_section): Zero section contents
+ for R_386_32 and R_386_PC32 relocs against symbols defined in
+ discarded sections.
+
+2004-08-25 Dmitry Diky <diwil@spec.ru>
+
+ * reloc.c (BFD_RELOC_MSP430_2X_PCREL,BFD_RELOC_MSP430_RL_PCREL):
+ Add new relocations.
+ * bfd-in2.h: Regenerate.
+ * libbfd.h: Regenerate.
+ * elf32-msp430.c: Clean-up code.
+ (elf_msp430_howto_table): Add new relocation entries.
+ (bfd_elf32_bfd_reloc_type_lookup): New relocation handlers.
+ (msp430_elf_relax_section): New function.
+ (msp430_elf_relax_delete_bytes): New function.
+ (msp430_elf_symbol_address_p): New function.
+
+2004-08-24 Kazuhiro Inaoka <inaoka.kazuhiro@renesas.com>
+
+ * elf32-m32r.c (m32r_elf_relocate_section): Handle
+ R_M32R_SDA16_RELA in the same way as R_M32R_SDA16.
+
+2004-08-20 Daniel Jacobowitz <dan@debian.org>
+
+ * elflink.c (_bfd_elf_section_already_linked): Handle
+ SEC_LINK_DUPLICATES_SAME_CONTENTS.
+
+2004-08-19 Mark Mitchell <mark@codesourcery.com>
+
+ * config.bfd (arm*-*-symbianelf*): New target.
+ (arm*-*-eabi*): Likewise.
+
+2004-08-19 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (ppc_get_stub_entry): Change third param to a
+ "struct ppc_link_hash_entry *".
+ (ppc64_elf_relocate_section): Ditto for type of h. Introduce h_elf
+ to satisfy RELOC_FOR_GLOBAL_SYMBOL.
+
+2004-08-19 Jakub Jelinek <jakub@redhat.com>
+
+ * elf64-ppc.c (ppc64_elf_edit_opd): Support 16 byte long .opd
+ entries (where fd_aux overlaps next entry's fd_func).
+ Add non_overlapping argument, use it.
+ (ppc64_elf_check_relocs, ppc64_elf_gc_mark_hook, adjust_opd_syms,
+ ppc64_elf_size_stubs, ppc64_elf_relocate_section,
+ ppc64_elf_output_symbol_hook): Use address / 8 instead of address / 24
+ as indexes into opd_sym_map/opd_adjust array.
+ * elf64-ppc.h (ppc64_elf_edit_opd): Adjust prototype.
+
+2004-08-18 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (func_desc_adjust): Give undefined dot-symbols a value
+ if we can look up their function descriptor in a regular file.
+
+2004-08-18 Nick Clifton <nickc@redhat.com>
+
+ PR 324
+ * cofflink.c (coff_link_add_symbols): Check that the comdat
+ pointer in the coff_section_data structure has been initialised
+ before using it.
+
+2004-08-18 Alan Modra <amodra@bigpond.net.au>
+
+ PR 338
+ * elflink.c (bfd_elf_record_link_assignment): Add comment about
+ changing bfd_link_hash_undefined to bfd_link_hash_new.
+
+2004-08-17 Jakub Jelinek <jakub@redhat.com>
+
+ * elfxx-target.h (bfd_elfNN_get_synthetic_symtab): Only define
+ if not yet defined.
+ * elf64-ppc.c (bfd_elf64_get_synthetic_symtab): Define.
+ (synthetic_opd, synthetic_relocatable): New variables.
+ (compare_symbols, compare_relocs): New helper routines.
+ (ppc64_elf_get_synthetic_symtab): New function.
+ * bfd.c (bfd_get_synthetic_symtab): Rename dynsyms argument
+ to relsyms.
+ * bfd-in2.h: Regenerated.
+ * elf.c (_bfd_elf_get_synthetic_symtab): Rename dynsyms argument
+ to relsyms. Return 0 if abfd is relocatable.
+
+2004-08-17 Alan Modra <amodra@bigpond.net.au>
+
+ * elflink.h (elf_gc_sweep): Keep non-alloc, non-load sections.
+
+2004-08-17 Nick Clifton <nickc@redhat.com>
+
+ * (is_arm_mapping_symbol_name): New function - return true
+ when a symbol name matches the requirements for an ARM mapping
+ symbol name.
+ (arm_elf_find_function): New function based on
+ elf_find_function in elf.c but skipping ARM mapping symbols
+ and including thumb function symbols.
+ (elf32_arm_find_nearest_line): Use arm_elf_find_function.
+ (elf32_arm_output_symbol_hook): Use is_arm_mapping_symbol_name.
+
+2004-08-17 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (ppc64_elf_branch_reloc): New function.
+ (ppc64_elf_howto_raw): Use ppc64_elf_branch_reloc.
+ (ppc64_elf_brtaken_reloc): Here too.
+
+2004-08-17 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (add_symbol_adjust): Correct mismatched function
+ symbol visibility.
+ (ppc64_elf_check_directives): Check that we have the right hash
+ table before proceeding.
+
+2004-08-17 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (struct ppc64_elf_obj_tdata): Add "deleted_section".
+ (adjust_opd_syms): Attach opd syms for deleted entries to one of
+ the sections that will be discarded.
+
+2004-08-16 Alan Modra <amodra@bigpond.net.au>
+
+ * elflink.c (elf_section_complain_discarded): Ignore .fixup.
+
+2004-08-16 Alan Modra <amodra@bigpond.net.au>
+
+ * bfd.c (_bfd_default_error_handler): Account for doubled '%' in
+ free space available.
+
+2004-08-16 Alan Modra <amodra@bigpond.net.au>
+
+ * pdp11.c (struct pdp11_aout_reloc_external): Delete. Replace
+ occurrences with bfd_byte * thoughout file.
+
+ * coff-rs6000.c (do_shared_object_padding): Warning fix.
+ (xcoff_write_armap_big): Likewise.
+ (xcoff_write_archive_contents_old): Likewise.
+ (xcoff_write_archive_contents_big): Likewise.
+
+ * elf64-mmix.c (mmix_elf_get_section_contents): Delete declaration.
+
+2004-08-13 Nick Clifton <nickc@redhat.com>
+
+ * elf32-arm.h: Convert to ISO C90.
+
+2004-08-13 Alan Modra <amodra@bigpond.net.au>
+
+ PR 293
+ * elf32-hppa.c (elf32_hppa_hide_symbol): Use init_refcount to
+ zero the plt field.
+
+2004-08-13 Alan Modra <amodra@bigpond.net.au>
+
+ * bfd.c (_bfd_default_error_handler): Handle %A and %B.
+ (bfd_archive_filename, bfd_get_section_ident): Delete.
+ * ecofflink.c (bfd_ecoff_debug_accumulate_other): Don't call
+ bfd_archive_filename.
+ * elflink.c (elf_link_input_bfd): Don't use callbacks->error_handler
+ to warn about symbols in discarded sections. Use _bfd_error_handler.
+ * aout-adobe.c (aout_adobe_callback): See below.
+ * aout-cris.c (swap_ext_reloc_in): ..
+ * coff-arm.c (find_thumb_glue, find_arm_glue,
+ coff_arm_relocate_section, bfd_arm_process_before_allocation,
+ coff_arm_merge_private_bfd_data, _bfd_coff_arm_set_private_flags,
+ coff_arm_copy_private_bfd_data): ..
+ * coff-i860.c (i860_reloc_processing): ..
+ * coff-mcore.c (mcore_coff_unsupported_reloc,
+ coff_mcore_relocate_section): ..
+ * coff-ppc.c (coff_ppc_relocate_section): ..
+ * coff-rs6000.c (xcoff_create_csect_from_smclas
+ * coff-sh.c (sh_relax_section, sh_relax_delete_bytes,
+ sh_swap_insns, sh_relocate_section): ..
+ * coff-tic54x.c (tic54x_reloc_processing): ..
+ * coff-tic80.c (coff_tic80_relocate_section): ..
+ * coff64-rs6000.c (xcoff64_create_csect_from_smclas): ..
+ * coffcode.h (styp_to_sec_flags, coff_slurp_line_table,
+ coff_slurp_symbol_table, coff_classify_symbol,
+ coff_slurp_reloc_table): ..
+ * coffgen.c (_bfd_coff_read_string_table): ..
+ * cofflink.c (coff_link_add_symbols, _bfd_coff_link_input_bfd,
+ _bfd_coff_generic_relocate_section): ..
+ * cpu-arm.c (bfd_arm_merge_machines): ..
+ * cpu-sh.c (sh_merge_bfd_arch): ..
+ * elf-hppa.h (elf_hppa_relocate_section): ..
+ * elf.c (bfd_elf_string_from_elf_section, setup_group,
+ _bfd_elf_setup_group_pointers, bfd_section_from_shdr,
+ assign_section_numbers, _bfd_elf_symbol_from_bfd_symbol,
+ copy_private_bfd_data, _bfd_elf_validate_reloc): ..
+ * elf32-arm.h (find_thumb_glue, find_arm_glue,
+ bfd_elf32_arm_process_before_allocation, elf32_thumb_to_arm_stub,
+ elf32_arm_to_thumb_stub, elf32_arm_final_link_relocate,
+ elf32_arm_relocate_section, elf32_arm_set_private_flags,
+ elf32_arm_copy_private_bfd_data, elf32_arm_merge_private_bfd_data): ..
+ * elf32-cris.c (cris_elf_relocate_section, cris_elf_check_relocs,
+ cris_elf_merge_private_bfd_data
+ * elf32-frv.c (elf32_frv_relocate_section, elf32_frv_check_relocs): ..
+ * elf32-gen.c (elf32_generic_link_add_symbols): ..
+ * elf32-hppa.c (hppa_add_stub, hppa_build_one_stub,
+ elf32_hppa_check_relocs, get_local_syms, final_link_relocate,
+ elf32_hppa_relocate_section): ..
+ * elf32-i370.c (i370_elf_merge_private_bfd_data,
+ i370_elf_check_relocs, i370_elf_relocate_section): ..
+ * elf32-i386.c (elf_i386_info_to_howto_rel, elf_i386_check_relocs,
+ elf_i386_relocate_section): ..
+ * elf32-m32r.c (m32r_elf_relocate_section,
+ m32r_elf_merge_private_bfd_data): ..
+ * elf32-m68hc1x.c (m68hc12_add_stub,
+ _bfd_m68hc11_elf_merge_private_bfd_data): ..
+ * elf32-m68k.c (elf_m68k_relocate_section): ..
+ * elf32-mcore.c (mcore_elf_unsupported_reloc,
+ mcore_elf_relocate_section): ..
+ * elf32-ppc.c (ppc_elf_merge_private_bfd_data, bad_shared_reloc,
+ ppc_elf_check_relocs, ppc_elf_relocate_section,
+ ppc_elf_begin_write_processing): ..
+ * elf32-s390.c (elf_s390_check_relocs, invalid_tls_insn,
+ elf_s390_relocate_section): ..
+ * elf32-sh-symbian.c (sh_symbian_import_as,
+ sh_symbian_process_embedded_commands,
+ sh_symbian_relocate_section): ..
+ * elf32-sh.c (sh_elf_relax_section, sh_elf_relax_delete_bytes,
+ sh_elf_swap_insns, sh_elf_relocate_section, sh_elf_check_relocs,
+ sh_elf_merge_private_data): ..
+ * elf32-sparc.c (elf32_sparc_check_relocs,
+ elf32_sparc_relocate_section,
+ elf32_sparc_merge_private_bfd_data): ..
+ * elf32-v850.c (v850_elf_check_relocs,
+ v850_elf_merge_private_bfd_data): ..
+ * elf32-xtensa.c (elf_xtensa_check_relocs,
+ elf_xtensa_relocate_section, elf_xtensa_merge_private_bfd_data): ..
+ * elf64-alpha.c (elf64_alpha_relax_with_lituse,
+ elf64_alpha_relax_got_load, elf64_alpha_size_got_sections,
+ elf64_alpha_relocate_section_r, elf64_alpha_relocate_section): ..
+ * elf64-gen.c (elf64_generic_link_add_symbols): ..
+ * elf64-ppc.c (ppc64_elf_merge_private_bfd_data, ppc_add_stub,
+ ppc64_elf_check_relocs, ppc64_elf_edit_opd,
+ ppc64_elf_relocate_section): ..
+ * elf64-s390.c (elf_s390_check_relocs, invalid_tls_insn,
+ elf_s390_relocate_section): ..
+ * elf64-sh64.c (sh_elf64_relocate_section): ..
+ * elf64-sparc.c (sparc64_elf_check_relocs,
+ sparc64_elf_add_symbol_hook, sparc64_elf_relocate_section,
+ sparc64_elf_merge_private_bfd_data): ..
+ * elf64-x86-64.c (elf64_x86_64_check_relocs,
+ elf64_x86_64_relocate_section): ..
+ * elflink.c (_bfd_elf_add_default_symbol,
+ _bfd_elf_link_assign_sym_version, elf_link_read_relocs_from_section,
+ _bfd_elf_link_output_relocs, elf_link_add_object_symbols,
+ bfd_elf_size_dynamic_sections, elf_link_output_extsym,
+ elf_get_linked_section_vma, elf_fixup_link_order,
+ bfd_elf_final_link, bfd_elf_gc_record_vtinherit,
+ bfd_elf_gc_record_vtinherit, _bfd_elf_section_already_linked): ..
+ * elfxx-ia64.c (elfNN_ia64_relax_section,
+ elfNN_ia64_relocate_section, elfNN_ia64_merge_private_bfd_data): ..
+ * elfxx-mips.c (mips_elf_perform_relocation,
+ _bfd_mips_elf_check_relocs,
+ _bfd_mips_elf_merge_private_bfd_data): ..
+ * ieee.c (ieee_slurp_external_symbols): ..
+ * ihex.c (ihex_bad_byte, ihex_scan, ihex_read_section): ..
+ * libbfd.c (_bfd_generic_verify_endian_match): ..
+ * linker.c (_bfd_generic_link_add_one_symbol,
+ _bfd_generic_section_already_linked): ..
+ * pdp11.c (translate_to_native_sym_flags): ..
+ * pe-mips.c (coff_pe_mips_relocate_section): ..
+ * peicode.h (pe_ILF_build_a_bfd): ..
+ * srec.c (srec_bad_byte): ..
+ * stabs.c (_bfd_link_section_stabs): ..
+ * xcofflink.c (xcoff_link_add_symbols, xcoff_link_input_bfd): ..
+ Replace all uses of bfd_archive_filename and bfd_get_section_ident
+ with corresponding %B and %A in _bfd_error_handler format string.
+ Replace occurrences of "fprintf (stderr," with _bfd_error_handler
+ calls to use %A and %B. Fix "against symbol .. from section" and
+ similar error messages. Combine multiple _bfd_error_handler calls
+ where they were separated due to bfd_archive_filename deficiencies.
+ * bfd-in2.h: Regenerate.
+
+2004-08-12 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf32-i386.c (elf_i386_relocate_section): Report unrecognized
+ relocation.
+
+2004-08-10 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (struct ppc_link_hash_entry): Add was_undefined.
+ (struct ppc_link_hash_table): Remove no_multi_toc, multi_toc_needed.
+ Make emit_stub_syms, stub_error and has_14bit_branch bit-fields.
+ Add twiddled_syms.
+ (link_hash_newfunc): Init was_undefined.
+ (add_symbol_adjust): Don't set undefined dot symbols to defweak;
+ Use undefweak instead.
+ (ppc64_elf_check_directives): Fix undefs chain.
+ (ppc64_elf_next_toc_section): Remove no_multi_toc and multi_toc_needed
+ references.
+ (ppc64_elf_size_stubs): Adjust for add_symbol_adjust change.
+ (undo_symbol_twiddle, ppc64_elf_restore_symbols): New functions.
+ * elf64-ppc.h (ppc64_elf_restore_symbols): Declare.
+
+2004-08-09 Jakub Jelinek <jakub@redhat.com>
+
+ * elf64-x86-64.c (elf64_x86_64_relocate_section): For -fno-pic
+ error, test input_section flags rather than sec.
+
+2004-08-09 Alan Modra <amodra@bigpond.net.au>
+
+ * elf-bfd.h (struct elf_backend_data): Add
+ elf_backend_archive_symbol_lookup.
+ (_bfd_elf_archive_symbol_lookup): Declare.
+ * elflink.c (_bfd_elf_archive_symbol_lookup): New function..
+ (elf_link_add_archive_symbols): ..extracted from here. Call the
+ backend version.
+ * elfxx-target.h (elf_backend_archive_symbol_lookup): Provide default.
+ (elfNN_bed): Init new field.
+ * elf64-ppc.c (elf_backend_check_directives): Define.
+ (elf_backend_archive_symbol_lookup): Define.
+ (struct ppc_link_hash_table): Add tls_get_add_fd. Make tls_get_add
+ a ppc_link_hash_entry pointer.
+ (get_fdh): Move.
+ (ppc64_elf_archive_symbol_lookup, opd_entry_value): New functions.
+ (add_symbol_adjust, ppc64_elf_check_directives): New functions.
+ (ppc64_elf_check_relocs, ppc64_elf_gc_mark_hook, func_desc_adjust,
+ ppc64_elf_adjust_dynamic_symbol, ppc64_elf_tls_setup,
+ ppc64_elf_tls_optimize, allocate_dynrelocs, ppc_type_of_stub,
+ ppc_build_one_stub, ppc64_elf_size_stubs, ppc64_elf_relocate_section,
+ ppc64_elf_finish_dynamic_symbol): Handle branch relocs to function
+ descriptor symbols.
+
+2004-08-09 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (struct ppc_link_hash_entry): Expand adjust_done comment.
+ (ppc64_elf_add_symbol_hook): Test for NULL section.
+ (get_sym_h): Formatting.
+ (ppc64_elf_size_stubs): Include reloc addend in value stored as
+ stub target_value.
+
+ * elf64-ppc.c (ppc64_elf_relocate_section): Combine handling of
+ long branch stubs with code handling plt and r2off branch stubs.
+
+2004-08-09 Alan Modra <amodra@bigpond.net.au>
+
+ * elf-bfd.h (_bfd_elf_gc_mark): Declare.
+ * elflink.c (elf_link_input_bfd): Formatting.
+ (_bfd_elf_gc_mark): Rename from elf_gc_mark and make global. Adjust
+ all callers.
+ * elf64-ppc.c (struct ppc_link_hash_entry): Remove is_entry.
+ (link_hash_newfunc): Don't set it.
+ (ppc64_elf_copy_indirect_symbol): Nor copy it.
+ (ppc64_elf_mark_entry_syms): Delete.
+ (ppc64_elf_gc_mark_hook): Mark entry syms here. Also mark opd
+ sections. Use get_opd_info.
+ * elf64-ppc.h (ppc64_elf_mark_entry_syms): Delete.
+
+2004-08-09 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (adjust_opd_syms): Fix merge error.
+
+ * elf64-ppc.c (struct ppc_link_hash_table): Remove have_undefweak.
+ (func_desc_adjust): Don't set have_undefweak.
+ (ppc64_elf_func_desc_adjust): Don't add an extr nop to sfpr.
+ (ppc64_elf_relocate_section): NOP out calls to undefweak functions.
+
+ * elf64-ppc.c (struct ppc_link_hash_entry): Make "oh" a
+ "struct ppc_link_hash_entry *". Adjust all references.
+ (ppc64_elf_hide_symbol): Correct a comment.
+
+ * elf64-ppc.c (get_opd_info): New function.
+ (adjust_opd_syms): Use get_opd_info. Define removed symbols as zero.
+ (ppc64_elf_edit_opd): Use get_opd_info. Check that sym has a dot
+ before calling get_fdh. Test fdh rather than h before dereferencing
+ fdh. Mark removed symbols in opd_adjust.
+ (ppc64_elf_tls_optimize): Don't bother with opd adjustment here.
+ (ppc64_elf_relocate_section): Use get_opd_info, and handle removed
+ opd symbols.
+ (ppc64_elf_output_symbol_hook): Likewise.
+
+2004-08-06 Paul Brook <paul@codesourcery.com>
+
+ * elfarm-nabi.c (elf32_arm_howto_table): Add new EABI relocations.
+ (elf32_arm_reloc_map): Add BFD_RELOC_ARM_RELABS32,
+ BFD_RELOC_ARM_ROSEGREL32 and BFD_RELOC_ARM_SBREL32.
+ * reloc.c: Add BFD_RELOC_ARM_RELABS32, BFD_RELOC_ARM_ROSEGREL32
+ and BFD_RELOC_ARM_SBREL32.
+ * bfd-in2.h, bbfd.h: Regenerate.
+
+2004-08-01 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * elfxx-mips.c (mips_elf_calculate_relocation): Test only for
+ the dynamic link symbol actually in use.
+
+2004-08-01 Stephane Carrez <stcarrez@nerim.fr>
+
+ * elf32-m68hc1x.c (elf32_m68hc11_size_stubs): Handle bfd_link_hash_new
+
+2004-07-31 Joel Brobecker <brobecker@gnat.com>
+ Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * elfxx-mips.c (_bfd_mips_elf_symbol_processing): Handle
+ SHN_MIPS_TEXT and SHN_MIPS_DATA.
+
+2004-07-30 H.J. Lu <hongjiu.lu@intel.com>
+ Nick Clifton <nickc@redhat.com>
+
+ PR 290
+ * bfd.c (_bfd_default_error_handler): Make it global.
+
+ * elf-bfd.h (elf_backend_data): Add link_order_error_handler.
+
+ * elf.c (assign_section_numbers): Cope gracefully with sections
+ which have SHF_LINK_ORDER set but no sh_link set up.
+ * elflink.c (elf_get_linked_section_vma): Likewise.
+
+ * elfxx-ia64.c (elf_backend_link_order_error_handler): New. Set
+ it to NULL.
+
+ * elfxx-target.h (elf_backend_link_order_error_handler): New.
+ Set it to _bfd_default_error_handler.
+ (elfNN_bed): Add elf_backend_link_order_error_handler.
+
+ * libbfd-in.h (_bfd_default_error_handler): New.
+
+ * libbfd.h: Regenerated.
+
+2004-07-30 Jakub Jelinek <jakub@redhat.com>
+
+ * archures.c (bfd_mach_sparc_64bit_p): Define.
+ * elf32-sparc.c (elf32_sparc_merge_private_bfd_data): Use it.
+ * bfd-in2.h: Rebuilt.
+
+2004-07-29 Alexandre Oliva <aoliva@redhat.com>
+
+ Introduce SH2a support.
+ 2004-02-18 Corinna Vinschen <vinschen@redhat.com>
+ * archures.c (bfd_mach_sh2a_nofpu): New.
+ * bfd-in2.h: Rebuilt.
+ * cpu-sh.c (SH2A_NOFPU_NEXT): New.
+ (arch_info_struct): Add sh2a_nofpu.
+ * elf32-sh.c (sh_elf_set_mach_from_flags): Handle sh2a_nofpu.
+ 2003-12-29 DJ Delorie <dj@redhat.com>
+ * reloc.c: Add relocs for sh2a.
+ * bfd-in2.h: Regenerate.
+ * libbfd.hh: Regenerate.
+ 2003-12-01 Michael Snyder <msnyder@redhat.com>
+ * archures.c (bfd_mach_sh2a): New.
+ * bfd-in2.h: Rebuilt.
+ * cpu-sh.c (SH_NEXT, SH2_NEXT, etc.): Change defines to enums.
+ (SH2A_NEXT): New.
+ (arch_info_struct): Add sh2a.
+ * elf32-sh.c (sh_elf_set_mach_from_flags): Handle sh2a.
+
+2004-07-28 Nick Clifton <nickc@redhat.com>
+ John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ PR 273
+ * som.c (setup_sections): Improve estimation of space sizes in
+ relocatable objects.
+
+2004-07-27 Jason Thorpe <thorpej@wasabisystems.com>
+ * config.bfd (hppa*-*-netbsd*): Set targ_defvec to
+ bfd_elf32_hppa_nbsd_vec. Add bfd_elf32_hppa_linux_vec
+ to targ_selvecs.
+ * configure.in (bfd_elf32_hppa_nbsd_vec): Add case.
+ * configure: Regenerate.
+ * elf32-hppa.c (elf32_hppa_object_p): Add "elf32-hppa-netbsd"
+ case that accepts OSABI=NetBSD and OSABI=SysV.
+ (elf32_hppa_set_gp): For "elf32-hppa-netbsd", set the GP to
+ the base of .got or .data (if .got does not exist).
+ (elf32_hppa_post_process_headers): For elf32-hppa-netbsd,
+ set OSABI=NetBSD.
+ (TARGET_BIG_SYM): Add bfd_elf32_hppa_nbsd_vec case.
+ (TARGET_BIG_NAME): Add "elf32-hppa-netbsd" case.
+ * targets.c (bfd_elf32_hppa_nbsd_vec): Add extern declaration.
+ (_bfd_target_vector): Add bfd_elf32_hppa_nbsd_vec.
+
+2004-07-27 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR 161/251
+ * elf-bfd.h (bfd_elf_section_data): Add sec_group.
+ (elf_sec_group): Defined.
+ (bfd_elf_match_symbols_in_sections): New prototype.
+ (_bfd_elf_setup_group_pointers): Likewise.
+
+ * elf.c (bfd_elf_discard_group): Abort.
+ (bfd_elf_set_group_contents): Also include relocation sections.
+ Remove zero-fill for ld -r.
+ (_bfd_elf_setup_group_pointers): New function.
+ (elf_sort_elf_symbol): Likewise.
+ (elf_sym_name_compare): Likewise.
+ (bfd_elf_match_symbols_in_sections): Likewise.
+
+ * elfcode.h (elf_object_p): Call _bfd_elf_setup_group_pointers.
+
+ * elflink.c (match_group_member): New.
+ (elf_link_input_bfd): Check group member for discarded section.
+ (try_match_symbols_in_sections): New function.
+ (already_linked): Likewise.
+ (_bfd_elf_section_already_linked): Support mixing comdat group
+ and linkonce section.
+
+ * libbfd-in.h (bfd_section_already_linked_table_traverse): New.
+ * linker.c (bfd_section_already_linked_table_traverse): New.
+
+ * libbfd.h: Regenerated.
+
+2004-07-27 Tomer Levi <Tomer.Levi@nsc.com>
+
+ * reloc.c: Add BFD_RELOC_CRX_SWITCH8, BFD_RELOC_CRX_SWITCH16,
+ BFD_RELOC_CRX_SWITCH32.
+ * bfd-in2.h: Regenerate.
+ * libbfd.h: Regenerate.
+ * elf32-crx.c: Support relocation/relaxation of
+ BFD_RELOC_CRX_SWITCH* types.
+
+2004-07-27 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c: Correct "Linker stubs" comment.
+
+2004-07-26 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf-bfd.h (bfd_elf_section_data): Add a pointer for the
+ linked-to section.
+ (elf_linked_to_section): New.
+
+ * elf.c (assign_section_numbers): Set up sh_link for
+ SHF_LINK_ORDER.
+
+ * elfxx-ia64.c (elfNN_ia64_final_write_processing): Set sh_info
+ to sh_link for SHT_IA_64_UNWIND sections.
+
+2004-07-22 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elflink.c (elf_fixup_link_order): Add _() to error message.
+
+2004-07-22 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elflink.c (elf_fixup_link_order): Issue a warning and flag
+ an error if failed.
+
+2004-07-21 H.J. Lu <hongjiu.lu@intel.com>
+
+ * aout-adobe.c (aout_32_section_already_linked): Defined.
+ * aout-target.h (MY_section_already_linked): Likewise.
+ * aout-tic30.c (MY_section_already_linked): Likewise.
+ * binary.c (binary_section_already_linked): Likewise.
+ * bout.c (b_out_section_already_linked): Likewise.
+ * coff-alpha.c (_bfd_ecoff_section_already_linked): Likewise.
+ * coff-mips.c (_bfd_ecoff_section_already_linked): Likewise.
+ * coffcode.h (coff_section_already_linked): Likewise.
+ * i386msdos.c (msdos_section_already_linked): Likewise.
+ * i386os9k.c (os9k_section_already_linked): Likewise.
+ * ieee.c (ieee_section_already_linked): Likewise.
+ * ihex.c (ihex_section_already_linked): Likewise.
+ * mach-o.c (bfd_mach_o_section_already_linked): Likewise.
+ * mmo.c (mmo_section_already_linked): Likewise.
+ * nlm-target.h (nlm_section_already_linked): Likewise.
+ * oasys.c (oasys_section_already_linked): Likewise.
+ * pef.c (bfd_pef_section_already_linked): Likewise.
+ * ppcboot.c (ppcboot_section_already_linked): Likewise.
+ * som.c (som_bfd_discard_group): Likewise.
+ * srec.c (srec_section_already_linked): Likewise.
+ * tekhex.c (tekhex_section_already_linked): Likewise.
+ * versados.c (versados_section_already_linked): Likewise.
+ * vms.c (vms_section_already_linked): Likewise.
+ * coff-target.h (_bfd_xcoff_section_already_linked): Likewise.
+ * xsym.c (bfd_sym_section_already_linked): Likewise.
+
+ * bfd-in.h (bfd_section_already_linked_table_init): New.
+ (bfd_section_already_linked_table_free): Likewise.
+
+ * coff-rs6000.c (rs6000coff_vec): Add
+ _bfd_generic_section_already_linked.
+ (pmac_xcoff_vec): Likewise.
+ * coff64-rs6000.c (rs6000coff64_vec): Likewise.
+ (aix5coff64_vec): Likewise.
+
+ * elf-bfd.h (_bfd_elf_section_already_linked): New prototype.
+ * elflink.c (_bfd_elf_section_already_linked): New function.
+
+ * elfxx-target.h (bfd_elfNN_section_already_linked): Defined.
+
+ * libbfd-in.h (_bfd_nolink_section_already_linked): Defined.
+ (_bfd_generic_section_already_linked): New.
+ (bfd_section_already_linked_hash_entry): Likewise.
+ (bfd_section_already_linked): Likewise.
+ (bfd_section_already_linked_table_lookup): Likewise.
+ (bfd_section_already_linked_table_insert): Likewise.
+
+ * linker.c (bfd_section_already_linked): New.
+ (_bfd_section_already_linked_table): Likewise.
+ (bfd_section_already_linked_table_lookup): Likewise.
+ (bfd_section_already_linked_table_insert): Likewise.
+ (already_linked_newfunc): Likewise.
+ (bfd_section_already_linked_table_init): Likewise.
+ (bfd_section_already_linked_table_free): Likewise.
+ (_bfd_generic_section_already_linked): Likewise.
+
+ * section.c (bfd_section): Remove comdat.
+ (bfd_comdat_info): Moved to ...
+ * bfd-in.h (coff_comdat_info): Here.
+ (bfd_coff_get_comdat_section): New.
+ * coffgen.c (bfd_coff_get_comdat_section): Likewise.
+ * libcoff-in.h (coff_section_tdata): Add comdat.
+ * coffcode.h (handle_COMDAT): Updated.
+ * cofflink.c (coff_link_add_symbols): Likewise.
+ * ecoff.c (bfd_debug_section): Likewise.
+
+ * targets.c (bfd_target): Add _section_already_linked.
+ (BFD_JUMP_TABLE_LINK): Updated.
+
+ * bfd-in2.h: Regenerated.
+ * libbfd.h: Likewise.
+ * libcoff.h: Likewise.
+
+2003-07-21 Paul Brook <paul@codesourcery.com>
+
+ * elflink.c (elf_get_linked_section_vma, compare_link_order,
+ elf_fixup_link_order): New functions.
+ (bfd_elf_final_link): Call elf_fixup_link_order.
+
+2004-07-21 Alexandre Oliva <aoliva@redhat.com>
+
+ * elf-bfd.h (ELF_COMMON_DEF_P): New.
+ * elflink.c (_bfd_elf_symbol_refs_local_p): Use it to handle
+ common definitions.
+ * elf-m10300.c: Use SYMBOL_REFERENCES_LOCAL instead of
+ _bfd_elf_symbol_refs_local_p.
+ * elf32-frv.c (FRVFDPIC_SYM_LOCAL): Remove hack for common
+ symbols.
+
+2004-07-19 H.J. Lu <hongjiu.lu@intel.com>
+
+ * bfd-in.h (dynamic_lib_link_class): Add DYN_NO_ADD_NEEDED and
+ DYN_NO_NEEDED.
+ (bfd_elf_get_dyn_lib_class): New prototype.
+ * elf.c (bfd_elf_get_dyn_lib_class): New function.
+
+ * elflink.c (elf_link_add_object_symbols): Check DYN_AS_NEEDED,
+ DYN_DT_NEEDED and DYN_NO_NEEDED bits to see if a DT_NEEDED
+ entry is needed. Issue an error if a DT_NEEDED entry is needed
+ for a file marked DYN_NO_NEEDED.
+ (elf_link_check_versioned_symbol): Check the DYN_DT_NEEDED bit
+ for DT_NEEDED tags.
+
+ * bfd-in2.h: Regenerated.
+
+2004-07-14 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ * elflink.c (elf_section_complain_discarded): Don't complain in
+ .PARISC.unwind.
+
+2004-07-10 James E Wilson <wilson@specifixinc.com>
+
+ * elfxx-ia64.c (elfNN_ia64_relax_ldxmov): Remove abfd parameter.
+ (elfNN_ia64_install_value, elfNN_ia64_relax_brl): Likewise.
+ (elfNN_ia64_relax_section, elfNN_ia64_relocate_section,
+ elfNN_ia64_finish_dynamic_symbol, elfNN_ia64_finish_dynamic_sections):
+ Fix callers.
+ (elfNN_ia64_relax_brl): Change bfd_get_64 to bfd_getl64. Change
+ bfd_put_64 to bfd_putl64.
+ (elfNN_ia64_relax_ldxmov, elfNN_ia64_install_value): Likewise.
+
+2004-07-09 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR 240
+ * elfxx-ia64.c (elfNN_ia64_relax_section): Only warn br in
+ .init/.fini sections when trying to relax it.
+
+2004-07-09 Jie Zhang <zhangjie@magima.com.cn>
+
+ * elf.c (assign_file_positions_for_segments): Make sure the
+ .dynamic section is the first section in the PT_DYNAMIC segment.
+
+2004-07-09 Nick Clifton <nickc@redhat.com>
+
+ * config.bfd: Change sh-sybmian-elf to sh-*-symbianelf.
+ * elf32-sh-symbian.c: Rename the sh_find_elf_flags and
+ sh_elf_get_flags_from_mach functions so that they do not conflict
+ when this target is built with other sh-elf targets.
+ * elf32-sh.c (sh_elf_get_flags_from_mach): Remove bogus
+ suppression of this function.
+ (sh_elf_find_flags): Likewise.
+
+2004-07-07 Tomer Levi <Tomer.Levi@nsc.com>
+
+ * Makefile.am (ALL_MACHINES): Add cpu-crx.lo.
+ (ALL_MACHINES_CFILES): Add cpu-crx.c.
+ (BFD32_BACKENDS): Add elf32-crx.lo.
+ (BFD32_BACKENDS_CFILES): Add elf32-crx.c.
+ (cpu-crx.lo): New target.
+ (elf32-crx.lo): New target.
+ * Makefile.in: Regenerate.
+ * archures.c (bfd_architecture): Add bfd_{arch,mach}_crx.
+ (bfd_archures_list): Add bfd_crx_arch.
+ * bfd-in2.h: Regenerate.
+ * config.bfd: Handle crx-*-elf*, crx*.
+ * configure.in: Handle bfd_elf32_crx_vec.
+ * configure: Regenerate.
+ * cpu-crx.c: New file.
+ * elf32-crx.c: Likewise.
+ * libbfd.h: Regenerate.
+ * reloc.c: Add BFD_RELOC_CRX_REL4, BFD_RELOC_CRX_REL8,
+ BFD_RELOC_CRX_REL8_CMP, BFD_RELOC_CRX_REL16, BFD_RELOC_CRX_REL24,
+ BFD_RELOC_CRX_REL32, BFD_RELOC_CRX_REGREL12, BFD_RELOC_CRX_REGREL22,
+ BFD_RELOC_CRX_REGREL28, BFD_RELOC_CRX_REGREL32, BFD_RELOC_CRX_ABS16,
+ BFD_RELOC_CRX_ABS32, BFD_RELOC_CRX_NUM8, BFD_RELOC_CRX_NUM16,
+ BFD_RELOC_CRX_NUM32, BFD_RELOC_CRX_IMM16 and BFD_RELOC_CRX_IMM32
+ * targets.c (bfd_elf32_crx_vec): Declare.
+ (bfd_target_vector): Add bfd_elf32_crx_vec.
+
+2004-07-06 Nick Clifton <nickc@redhat.com>
+
+ * config.bfd: Add sh-symbian-elf target.
+ * configure.in: Add bfd_elf32_shl_symbian_vec.
+ * configure: Regenerate.
+ * elf-bfd.h (struct elf_backend_data): Add new field
+ 'check_directives'.
+ * elflink.c (elf_link_add_object_symbols): Invoke the
+ check_directives function, if defined.
+ * elfxx-target.h: Provide a default, NULL definition for
+ check_directives.
+ * targets.c: Add bfd_elf32_shl_symbian_vec.
+ * elf32-sh.c (sh_elf_swap_insns): Protect against unnecessary
+ definition.
+ (elf32_shlin_grok_prstatus, elf32_shlib_grok_psinfo,
+ * sh_elf_get_flags_from_mach, sh_elf_find_flags): Likewise.
+ (TARGET_BIG_SYM, TARGET_LITTLE_SYM): Only define if they have
+ not already been defined.
+ * elf32-sh64.c: Use SH_TARGET_ALREADY_DEFINED.
+ * sh-symbian.c: New file. Provide functions to support the
+ * sh-symbian-elf target.
+ * Makefile.am: Add elf32-sh-symbian.c
+ * Makefile.in: Regenerate.
+
+2004-07-05 Andrew Stubbs <andrew.stubbs@superh.com>
+
+ * elf32-sh.c: Include ../opcodes/sh-opc.h.
+ * Makefile.am: Ran make dep-am.
+ * Makefile.in: Ran make dep-in.
+
+2004-07-03 Aaron W. LaFramboise <aaron98wiridge9@aaronwl.com>
+
+ * cofflink.c (_bfd_coff_generic_relocate_section): Resolve PE weak
+ externals properly.
+
+2004-07-02 Martin Schwidefsky <schwidefsky@de.ibm.com>
+
+ * config.bfd: Add want64 to configuration target s390-*-linux*.
+
+2004-07-01 H.J. Lu <hongjiu.lu@intel.com>
+
+ * bfd.c (bfd_get_section_ident): New.
+
+ * elflink.c (elf_link_read_relocs_from_section): Call
+ bfd_get_section_ident to identify the section when reporting
+ error.
+ (_bfd_elf_link_output_relocs): Likewise.
+ (elf_link_output_extsym): Likewise.
+ (elf_link_input_bfd): Likewise.
+ (bfd_elf_gc_record_vtinherit): Likewise.
+
+ * bfd-in2.h: Regenerated.
+
+2004-07-01 Jie Zhang <zhangjie@magima.com.cn>
+ Nick Clifton <nickc@redhat.com>
+
+ PR 204
+ * elfxx-mips.c (_bfd_mips_elf_final_link): Pass the correct number
+ of section symbols to mips_elf_sort_hash_table ().
+
+2004-07-01 Alan Modra <amodra@bigpond.net.au>
+
+ * elflink.c (elf_section_ignore_discarded_relocs): Revert last
+ change. Comment.
+ (elf_section_complain_discarded): New function. Handle
+ .gcc_except_table too.
+ (elf_link_input_bfd): Rewrite handling of relocs against symbols
+ in discarded sections.
+ * elf-bfd.h (elf_discarded_section): Protect macro arg.
+
+2004-06-30 James E Wilson <wilson@specifixinc.com>
+
+ * elfxx-ia64.c (elfNN_ia64_check_relocs): New local pltoff. Initialize
+ to NULL. Call get_pltoff if NULL and NEED_PLTOFF is true.
+
+2004-06-30 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR 233
+ * elflink.c (elf_link_input_bfd): Issue an error for non-debug
+ local references to discarded sections and report their
+ locations.
+
+2004-06-30 Alan Modra <amodra@bigpond.net.au>
+
+ * elflink.c (elf_section_ignore_discarded_relocs): Don't test
+ sec_info_type, test section name instead.
+
+2004-06-29 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR 240
+ * elfxx-ia64.c (elfNN_ia64_relax_section): Don't relax branch
+ in .init/.fini sections.
+
+2004-06-29 Bob Wilson <bob.wilson@acm.org>
+
+ * elf32-xtensa.c (elf_xtensa_relocate_section): Use
+ bfd_get_section_limit.
+
+2004-06-29 Bob Wilson <bob.wilson@acm.org>
+
+ * elf32-xtensa.c (elf_xtensa_combine_prop_entries): Don't change the
+ output section size.
+
+2004-06-29 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-mmix.c (mmix_set_relaxable_size): Save original size in
+ rawsize.
+ (mmix_elf_perform_relocation): Adjust for above change.
+ (mmix_elf_relocate_section): Likewise.
+ (mmix_elf_relax_section): Likewise. Use output_section->rawsize.
+ (mmix_elf_get_section_contents): Delete.
+ (bfd_elf64_get_section_contents): Delete.
+ (mmix_elf_relocate_section): Zero stub area.
+ * linker.c (default_indirect_link_order): Alloc max of section size
+ and rawsize.
+ * simple.c (bfd_simple_get_relocated_section_contents): Likewise.
+ * section.c (bfd_malloc_and_get_section): Likewise.
+ (struct bfd_section): Update rawsize comment.
+ * bfd-in2.h: Regenerate.
+
+ * reloc16.c (bfd_coff_reloc16_relax_section): Set rawsize.
+
+2004-06-29 Alan Modra <amodra@bigpond.net.au>
+
+ * bfd-in.h (bfd_get_section_limit): Define.
+ * reloc.c (bfd_perform_relocation, bfd_install_relocation)
+ (_bfd_final_link_relocate): Use bfd_get_section_limit.
+ * aout-tic30.c (tic30_aout_final_link_relocate): Likewise.
+ * coff-arm.c (coff_arm_relocate_section): Likewise.
+ * coff-mips.c (mips_refhi_reloc, mips_gprel_reloc): Likewise.
+ * cpu-ns32k.c (do_ns32k_reloc): Likewise.
+ (bfd_ns32k_final_link_relocate): Likewise.
+ * elf32-d30v.c (bfd_elf_d30v_reloc, bfd_elf_d30v_reloc_21): Likwise.
+ * elf32-dlx.c (_bfd_dlx_elf_hi16_reloc): Likewise.
+ * elf32-i860.c (i860_howto_pc26_reloc, i860_howto_pc16_reloc)
+ (i860_howto_highadj_reloc, i860_howto_splitn_reloc): Likewise.
+ * elf32-m32r.c (m32r_elf_do_10_pcrel_reloc, m32r_elf_hi16_reloc)
+ (m32r_elf_generic_reloc, m32r_elf_relocate_section): Likewise.
+ * elf32-m68hc1x.c (m68hc11_elf_special_reloc): Likewise.
+ * elf32-mips.c (gprel32_with_gp, mips16_gprel_reloc): Likewise.
+ * elf32-or32.c (or32_elf_consth_reloc): Likewise.
+ * elf32-ppc.c (ppc_elf_addr16_ha_reloc): Likewise.
+ * elf32-s390.c (s390_elf_ldisp_reloc): Likewise.
+ * elf32-sh.c (sh_elf_reloc_loop): Likewise.
+ * elf32-sparc.c (sparc_elf_wdisp16_reloc): Likewise.
+ (sparc_elf_hix22_reloc, sparc_elf_lox10_reloc): Likwise.
+ * elf32-v850.c (v850_elf_reloc): Likewise.
+ * elf32-xstormy16.c (xstormy16_elf_24_reloc): Likewise.
+ * elf32-xtensa.c (bfd_elf_xtensa_reloc): Likewise.
+ * elf64-alpha.c (elf64_alpha_reloc_gpdisp): Likewise.
+ * elf64-mips.c (mips_elf64_gprel32_reloc)
+ (mips16_gprel_reloc): Likewise.
+ * elf64-mmix.c (mmix_elf_reloc): Likewise.
+ * elf64-s390.c (s390_elf_ldisp_reloc): Likewise.
+ * elf64-sparc.c (init_insn_reloc): Likewise.
+ * elfn32-mips.c (gprel32_with_gp, mips16_gprel_reloc): Likewise.
+ * elfxx-mips.c (_bfd_mips_elf_gprel16_with_gp)
+ (_bfd_mips_elf_hi16_reloc, _bfd_mips_elf_lo16_reloc)
+ (_bfd_mips_elf_generic_reloc): Likewise.
+ * bfd-in2.h: Regenerate.
+
+2004-06-28 Alan Modra <amodra@bigpond.net.au>
+
+ * bfd-in.h (struct stab_info): Move from stabs.c.
+ * stabs.c (struct stab_link_includes_table): Delete.
+ (stab_link_includes_lookup): Delete.
+ (_bfd_write_section_stabs, _bfd_write_stab_strings): Remove one
+ level of indirection from sinfo parm.
+ (_bfd_link_section_stabs): Likewise. Set SEC_LINKER_CREATED on
+ stabstr section. Adjust hash table accesses.
+ * coff-ppc.c (ppc_bfd_coff_final_link): Do include rawsize in contents
+ alloc. Adjust stab_info test.
+ * cofflink.c (_bfd_coff_link_hash_table_init): Clear stab_info.
+ (_bfd_coff_final_link): Adjust stab_info test.
+ (_bfd_coff_link_input_bfd): Ignore SEC_LINKER_CREATED sections.
+ * elf-bfd.h (struct elf_link_hash_table): Include struct stab_info
+ in place.
+ * libcoff-in.h (struct coff_link_hash_table): Likewise.
+ * elf.c (_bfd_elf_link_hash_table_init): Clear stab_info.
+ * elflink.c (bfd_elf_final_link): Don't attempt to link linker created
+ stabstr section. Adjust stab_info test.
+ * libbfd-in.h (_bfd_link_section_stabs, _bfd_write_section_stabs)
+ (_bfd_write_stab_strings): Adjust prototypes.
+ * libbfd.h: Regenerate.
+ * libcoff.h: Regenerate.
+ * bfd-in2.h: Regenerate.
+
+2004-06-27 Mark Kettenis <kettenis@gnu.org>
+
+ From Miod Vallat <miod@online.fr>:
+ * aoutx.h (NAME(aout,machine_type)): Handle bfd_arch_m88k.
+
+2004-06-26 Alexandre Oliva <aoliva@redhat.com>
+
+ * elf-m10300.c (struct elf_mn10300_pcrel_relocs_copied): Delete.
+ (struct elf32_mn10300_link_hash_entry): Remove
+ pcrel_relocs_copied.
+ (mn10300_elf_check_relocs): Only reserve dynamic relocations for
+ R_MN10300_32. Don't adjust pcrel_relocs_copied.
+ (mn10300_elf_final_link_relocate): Fail for direct, pc-relative
+ and gotoff relocations if the symbol doesn't bind locally. Use
+ _bfd_elf_symbol_refs_local_p to test. Don't create dynamic
+ relocation for PCREL32.
+ (mn10300_elf_relocate_section): Use _bfd_elf_symbol_refs_local_p
+ to test whether a symbol binds locally.
+ (elf32_mn10300_link_hash_newfunc): Don't initialize
+ pcrel_relocs_copied.
+ (_bfd_mn10300_elf_discard_copies): Delete.
+ (_bfd_mn10300_elf_size_dynamic_sections): Don't call it.
+
+2004-06-26 Mark Kettenis <kettenis@gnu.org>
+
+ * config.bfd: Replace m88k-*-openbsd* with m88*-*-openbsd*.
+
+2004-06-25 Joel Brobecker <brobecker@gnat.com>
+
+ * som.c (som_set_reloc_info): Correct small typo.
+
+2004-06-25 Kazuhiro Inaoka <inaoka.kazuhiro@renesas.com>
+
+ * elf32-m32r.c (m32r_elf_howto_table): Support R_M32R_GOTOFF.
+ (m32r_elf_relocate_section): Changed for R_M32R_GOTOFF.
+ (m32r_elf_gcsweep_hook): Likewise.
+ (m32r_elf_check_relocs): Likewise.
+ (m32r_elf_howto_table): Added R_M32R_GOTOFF_HI_ULO,
+ R_M32R_GOTOFF_HI_SLO and R_M32R_GOTOFF_LO.
+ * reloc.c: Added BFD_RELOC_M32R_GOTOFF_HI_ULO,
+ BFD_RELOC_M32R_GOTOFF_HI_SLO and BFD_RELOC_M32R_GOTOFF_LO.
+ * bfd-in2.h: Regenerated.
+ * libbfd.h: Regenerated.
+
+2004-06-24 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf64-x86-64.c (elf64_x86_64_check_relocs): Warn overflow
+ relocation symbol.
+ (elf64_x86_64_relocate_section): Issue an error for
+ R_X86_64_PC8, R_X86_64_PC16 and R_X86_64_PC32 relocations
+ against global symbols when building shared library.
+
+2004-06-24 Alan Modra <amodra@bigpond.net.au>
+
+ * section.c (struct sec): Rename "_cooked_size" to "size".
+ Rename "_raw_size" to "rawsize".
+ (STD_SECTION): Adjust comments.
+ (bfd_set_section_size, bfd_get_section_contents): Use size.
+ (bfd_malloc_and_get_section): New function.
+ * bfd-in.h (bfd_section_size, bfd_get_section_size): Use size.
+ * coff-sh.c (sh_relax_section): Alloc coff_section_data struct early.
+ Correctly free reloc and contents memory.
+ * elf-eh-frame.c (_bfd_elf_discard_section_eh_frame): Delete FIXME
+ and fake CIE now that we can shink section size to zero.
+ (_bfd_elf_write_section_eh_frame): Likewise..
+ * elf32-ppc.c (ppc_elf_relax_section): Delay reading section contents.
+ * elf-m10300.c (mn10300_elf_final_link_relocate): Don't use
+ _bfd_stab_section_offset. Use _bfd_elf_section_offset.
+ * stabs.c (_bfd_stab_section_offset_): Remove unused args and
+ unneeded indirection.
+ * elf.c (_bfd_elf_section_offset): .. and update call.
+ * libbfd-in.h (_bfd_stab_section_offset): Update prototype.
+ * libbfd.h: Regenerate.
+ * bfd-in2.h: Regenerate.
+
+ Replace occurrences of "_raw_size" and "_cooked_size" in most places
+ with "size". Set new "rawsize" for stabs, eh_frame, and SEC_MERGE
+ sections. Use "rawsize", if non-zero, for bfd_get_section_contents
+ calls if the section might be a stabs, eh_frame, or SEC_MERGE section.
+ Similarly use "rawsize", if non-zero, in reloc functions to validate
+ reloc addresses. Use new bfd_malloc_and_get_section in most places
+ where bfd_get_section_contents was called. Expand all occurrences of
+ bfd_section_size and bfd_get_section_size. Rename "raw_size" var in
+ grok_prstatus and similar functions to "size".
+ * aix386-core.c (aix386_core_file_p): ..
+ * aix5ppc-core.c (xcoff64_core_p): ..
+ * aout-adobe.c (aout_adobe_callback, aout_adobe_write_object_contents,
+ aout_adobe_set_section_contents): ..
+ * aout-target.h (callback): ..
+ * aout-tic30.c (tic30_aout_callback, tic30_aout_final_link_relocate,
+ MY_bfd_final_link): ..
+ * aoutf1.h (sunos4_core_file_p): ..
+ * aoutx.h (some_aout_object_p, adjust_o_magic, adjust_z_magic,
+ adjust_n_magic, adjust_sizes_and_vmas, translate_from_native_sym_flags,
+ final_link, aout_link_input_section): ..
+ * binary.c (binary_object_p, binary_canonicalize_symtab,
+ binary_set_section_contents): ..
+ * bout.c (b_out_callback, b_out_write_object_contents,
+ b_out_set_section_contents, b_out_bfd_relax_section,
+ b_out_bfd_get_relocated_section_contents): ..
+ * cisco-core.c (cisco_core_file_validate): ..
+ * coff-alpha.c (alpha_ecoff_object_p,
+ alpha_ecoff_get_relocated_section_conten, alpha_relocate_section): ..
+ * coff-arm.c (coff_arm_relocate_section,
+ bfd_arm_allocate_interworking_sections): ..
+ * coff-h8300.c (h8300_reloc16_extra_cases,
+ h8300_bfd_link_add_symbols): ..
+ * coff-mips.c (mips_refhi_reloc, mips_gprel_reloc): ..
+ * coff-ppc.c (coff_ppc_relocate_section, ppc_allocate_toc_section,
+ ppc_bfd_coff_final_link): ..
+ * coff-rs6000.c (xcoff_reloc_type_br, xcoff_ppc_relocate_section): ..
+ * coff-sh.c (sh_relax_section, sh_relax_delete_bytes,
+ sh_align_loads, sh_coff_get_relocated_section_contents): ..
+ * coff64-rs6000.c (xcoff64_write_object_contents,
+ xcoff64_reloc_type_br, xcoff64_ppc_relocate_section): ..
+ * coffcode.h (coff_compute_section_file_positions,
+ coff_write_object_contents): ..
+ * coffgen.c (make_a_section_from_file, coff_write_symbols,
+ coff_section_symbol, build_debug_section): ..
+ * cofflink.c (coff_link_add_symbols, _bfd_coff_final_link,
+ process_embedded_commands, _bfd_coff_link_input_bfd,
+ _bfd_coff_write_global_sym): ..
+ * cpu-arm.c (bfd_arm_update_notes, bfd_arm_get_mach_from_notes): ..
+ * cpu-ns32k.c (do_ns32k_reloc, _bfd_ns32k_final_link_relocate): ..
+ * dwarf1.c (parse_line_table, _bfd_dwarf1_find_nearest_line): ..
+ * dwarf2.c (read_indirect_string, read_abbrevs, decode_line_info,
+ _bfd_dwarf2_find_nearest_line): ..
+ * ecoff.c (bfd_debug_section, ecoff_set_symbol_info,
+ ecoff_compute_section_file_positions,
+ _bfd_ecoff_write_object_contents, ecoff_indirect_link_order): ..
+ * elf-eh-frame.c (_bfd_elf_discard_section_eh_frame,
+ _bfd_elf_discard_section_eh_frame_hdr,
+ _bfd_elf_maybe_strip_eh_frame_hdr, _bfd_elf_eh_frame_section_offset,
+ _bfd_elf_write_section_eh_frame,
+ _bfd_elf_write_section_eh_frame_hdr): ..
+ * elf-hppa.h (elf_hppa_sort_unwind): ..
+ * elf-m10200.c (mn10200_elf_relax_section,
+ mn10200_elf_relax_delete_bytes,
+ mn10200_elf_get_relocated_section_contents): ..
+ * elf-m10300.c (_bfd_mn10300_elf_create_got_section,
+ mn10300_elf_check_relocs, mn10300_elf_relax_section,
+ mn10300_elf_relax_delete_bytes,
+ mn10300_elf_get_relocated_section_contents,
+ _bfd_mn10300_elf_adjust_dynamic_symbol,
+ _bfd_mn10300_elf_discard_copies,
+ _bfd_mn10300_elf_size_dynamic_sections,
+ _bfd_mn10300_elf_finish_dynamic_sections): ..
+ * elf.c (_bfd_elf_print_private_bfd_data, bfd_elf_get_bfd_needed_list,
+ _bfd_elf_make_section_from_phdr, elf_fake_sections,
+ bfd_elf_set_group_contents, map_sections_to_segments,
+ elf_sort_sections, assign_file_positions_for_segments,
+ SECTION_SIZE, copy_private_bfd_data,
+ _bfd_elf_get_dynamic_reloc_upper_bound,
+ _bfd_elf_canonicalize_dynamic_reloc, elfcore_maybe_make_sect,
+ _bfd_elfcore_make_pseudosection, elfcore_grok_prstatus,
+ elfcore_grok_lwpstatus, elfcore_grok_win32pstatus,
+ elfcore_grok_note, elfcore_grok_nto_status, elfcore_grok_nto_gregs,
+ _bfd_elf_rel_local_sym, _bfd_elf_get_synthetic_symtab): ..
+ * elf32-arm.h (bfd_elf32_arm_allocate_interworking_sect,
+ bfd_elf32_arm_process_before_allocation,
+ elf32_arm_adjust_dynamic_symbol, allocate_dynrelocs,
+ elf32_arm_size_dynamic_sections, elf32_arm_finish_dynamic_sections,
+ elf32_arm_write_section): ..
+ * elf32-cris.c (cris_elf_grok_prstatus,
+ elf_cris_finish_dynamic_sections, cris_elf_gc_sweep_hook,
+ elf_cris_adjust_gotplt_to_got, elf_cris_adjust_dynamic_symbol,
+ cris_elf_check_relocs, elf_cris_size_dynamic_sections,
+ elf_cris_discard_excess_dso_dynamics,
+ elf_cris_discard_excess_program_dynamics): ..
+ * elf32-d30v.c (bfd_elf_d30v_reloc, bfd_elf_d30v_reloc_21): ..
+ * elf32-dlx.c (_bfd_dlx_elf_hi16_reloc): ..
+ * elf32-frv.c (_frvfdpic_add_dyn_reloc, _frvfdpic_add_rofixup,
+ _frv_create_got_section, _frvfdpic_assign_plt_entries,
+ elf32_frvfdpic_size_dynamic_sections,
+ elf32_frvfdpic_modify_segment_map,
+ elf32_frvfdpic_finish_dynamic_sections): ..
+ * elf32-h8300.c (elf32_h8_relax_section, elf32_h8_relax_delete_bytes,
+ elf32_h8_get_relocated_section_contents): ..
+ * elf32-hppa.c (hppa_build_one_stub, hppa_size_one_stub,
+ elf32_hppa_adjust_dynamic_symbol, allocate_plt_static,
+ allocate_dynrelocs, elf32_hppa_size_dynamic_sections, group_sections,
+ elf32_hppa_size_stubs, elf32_hppa_set_gp, elf32_hppa_build_stubs,
+ elf32_hppa_finish_dynamic_sections): ..
+ * elf32-i370.c (i370_elf_adjust_dynamic_symbol,
+ i370_elf_size_dynamic_sections, i370_elf_check_relocs,
+ i370_elf_finish_dynamic_sections): ..
+ * elf32-i386.c (elf_i386_grok_prstatus, elf_i386_adjust_dynamic_symbol,
+ allocate_dynrelocs, elf_i386_size_dynamic_sections,
+ elf_i386_relocate_section, elf_i386_finish_dynamic_sections): ..
+ * elf32-i860.c (i860_howto_pc26_reloc, i860_howto_pc16_reloc,
+ i860_howto_highadj_reloc, i860_howto_splitn_reloc): ..
+ * elf32-ip2k.c (ip2k_is_switch_table_128,
+ ip2k_relax_switch_table_128, ip2k_is_switch_table_256,
+ ip2k_relax_switch_table_256, ip2k_elf_relax_section,
+ adjust_all_relocations, ip2k_elf_relax_delete_bytes): ..
+ * elf32-m32r.c (m32r_elf_do_10_pcrel_reloc, m32r_elf_hi16_reloc,
+ m32r_elf_generic_reloc, m32r_elf_adjust_dynamic_symbol,
+ allocate_dynrelocs, m32r_elf_size_dynamic_sections,
+ m32r_elf_relocate_section, m32r_elf_finish_dynamic_sections,
+ m32r_elf_relax_section, m32r_elf_relax_delete_bytes,
+ m32r_elf_get_relocated_section_contents): ..
+ * elf32-m68hc11.c (m68hc11_elf_build_one_stub,
+ m68hc11_elf_size_one_stub, m68hc11_elf_relax_section,
+ m68hc11_elf_relax_delete_bytes): ..
+ * elf32-m68hc12.c (m68hc12_elf_build_one_stub,
+ m68hc12_elf_size_one_stub): ..
+ * elf32-m68hc1x.c (elf32_m68hc11_size_stubs,
+ elf32_m68hc11_build_stubs, m68hc11_elf_special_reloc): ..
+ * elf32-m68k.c (elf_m68k_check_relocs, elf_m68k_gc_sweep_hook,
+ elf_m68k_adjust_dynamic_symbol, elf_m68k_size_dynamic_sections,
+ elf_m68k_discard_copies, elf_m68k_finish_dynamic_sections): ..
+ * elf32-mips.c (gprel32_with_gp, mips16_gprel_reloc,
+ elf32_mips_grok_prstatus): ..
+ * elf32-or32.c (or32_elf_consth_reloc): ..
+ * elf32-ppc.c (ppc_elf_relax_section, ppc_elf_addr16_ha_reloc,
+ elf_create_pointer_linker_section, ppc_elf_create_linker_section,
+ ppc_elf_additional_program_headers, ppc_elf_adjust_dynamic_symbol,
+ allocate_dynrelocs, ppc_elf_size_dynamic_sections,
+ ppc_elf_finish_dynamic_sections, ppc_elf_grok_prstatus,
+ ppc_elf_final_write_processing): ..
+ * elf32-s390.c (s390_elf_ldisp_reloc, elf_s390_adjust_dynamic_symbol,
+ allocate_dynrelocs, elf_s390_size_dynamic_sections,
+ elf_s390_finish_dynamic_sections, elf_s390_grok_prstatus): ..
+ * elf32-sh.c (sh_elf_reloc_loop, sh_elf_relax_section,
+ sh_elf_relax_delete_bytes, sh_elf_align_loads,
+ sh_elf_adjust_dynamic_symbol, allocate_dynrelocs,
+ sh_elf_size_dynamic_sections, sh_elf_get_relocated_section_contents,
+ sh_elf_finish_dynamic_sections, elf32_shlin_grok_prstatus): ..
+ * elf32-sh64-com.c (sh64_address_in_cranges,
+ sh64_get_contents_type): ..
+ * elf32-sh64.c (sh64_find_section_for_address,
+ sh64_elf_final_write_processing): ..
+ * elf32-sparc.c (sparc_elf_wdisp16_reloc, sparc_elf_hix22_reloc,
+ sparc_elf_lox10_reloc, elf32_sparc_adjust_dynamic_symbol,
+ allocate_dynrelocs, elf32_sparc_size_dynamic_sections,
+ elf32_sparc_relocate_section, elf32_sparc_finish_dynamic_sections): ..
+ * elf32-v850.c (v850_elf_reloc, v850_elf_relax_section): ..
+ * elf32-vax.c (elf_vax_check_relocs, elf_vax_adjust_dynamic_symbol,
+ elf_vax_size_dynamic_sections, elf_vax_discard_copies,
+ elf_vax_instantiate_got_entries, elf_vax_relocate_section,
+ elf_vax_finish_dynamic_sections): ..
+ * elf32-xstormy16.c (xstormy16_elf_24_reloc,
+ xstormy16_elf_check_relocs, xstormy16_relax_plt_check,
+ xstormy16_elf_relax_section, xstormy16_elf_always_size_sections,
+ xstormy16_elf_finish_dynamic_sections): ..
+ * elf32-xtensa.c (xtensa_read_table_entries,
+ elf_xtensa_allocate_got_size, elf_xtensa_allocate_local_got_size,
+ elf_xtensa_size_dynamic_sections, elf_xtensa_do_reloc,
+ bfd_elf_xtensa_reloc, elf_xtensa_relocate_section,
+ elf_xtensa_combine_prop_entries, elf_xtensa_finish_dynamic_sections,
+ elf_xtensa_discard_info_for_section, elf_xtensa_grok_prstatus,
+ get_relocation_opcode, retrieve_contents, find_relaxable_sections,
+ collect_source_relocs, is_resolvable_asm_expansion, remove_literals,
+ relax_section, shrink_dynamic_reloc_sections, relax_property_section,
+ xtensa_callback_required_dependence): ..
+ * elf64-alpha.c (elf64_alpha_reloc_gpdisp, elf64_alpha_relax_section,
+ elf64_alpha_check_relocs, elf64_alpha_adjust_dynamic_symbol,
+ elf64_alpha_calc_got_offsets_for_symbol, elf64_alpha_calc_got_offsets,
+ elf64_alpha_size_plt_section, elf64_alpha_size_plt_section_1,
+ elf64_alpha_always_size_sections, elf64_alpha_calc_dynrel_sizes,
+ elf64_alpha_size_rela_got_section, elf64_alpha_size_rela_got_1,
+ elf64_alpha_size_dynamic_sections, elf64_alpha_emit_dynrel,
+ elf64_alpha_finish_dynamic_sections, elf64_alpha_final_link): ..
+ * elf64-hppa.c (allocate_dynrel_entries,
+ elf64_hppa_size_dynamic_sections,
+ elf64_hppa_finish_dynamic_sections): ..
+ * elf64-mips.c (mips_elf64_gprel32_reloc, mips16_gprel_reloc,
+ mips_elf64_canonicalize_dynamic_reloc, mips_elf64_slurp_reloc_table,
+ elf64_mips_grok_prstatus): ..
+ * elf64-mmix.c (mmix_elf_perform_relocation, mmix_elf_reloc,
+ mmix_elf_relocate_section, mmix_elf_final_link,
+ mmix_set_relaxable_size, _bfd_mmix_after_linker_allocation,
+ mmix_elf_relax_section, mmix_elf_get_section_contents): ..
+ * elf64-ppc.c (ppc64_elf_object_p, ppc64_elf_grok_prstatus,
+ ppc64_elf_check_relocs, ppc64_elf_func_desc_adjust,
+ ppc64_elf_adjust_dynamic_symbol, ppc64_elf_edit_opd,
+ allocate_dynrelocs, ppc64_elf_size_dynamic_sections,
+ ppc_build_one_stub, ppc_size_one_stub, ppc64_elf_next_toc_section,
+ toc_adjusting_stub_needed, group_sections, ppc64_elf_size_stubs,
+ ppc64_elf_build_stubs, ppc64_elf_relocate_section,
+ ppc64_elf_finish_dynamic_sections): ..
+ * elf64-s390.c (s390_elf_ldisp_reloc, elf_s390_adjust_dynamic_symbol,
+ allocate_dynrelocs, elf_s390_size_dynamic_sections,
+ elf_s390_finish_dynamic_sections): ..
+ * elf64-sh64.c (sh_elf64_get_relocated_section_contents,
+ sh_elf64_check_relocs, sh64_elf64_adjust_dynamic_symbol,
+ sh64_elf64_discard_copies, sh64_elf64_size_dynamic_sections,
+ sh64_elf64_finish_dynamic_sections): ..
+ * elf64-sparc.c (sparc64_elf_slurp_reloc_table, init_insn_reloc,
+ sparc64_elf_check_relocs, sparc64_elf_adjust_dynamic_symbol,
+ sparc64_elf_size_dynamic_sections, sparc64_elf_relocate_section,
+ sparc64_elf_finish_dynamic_symbol,
+ sparc64_elf_finish_dynamic_sections): ..
+ * elf64-x86-64.c (elf64_x86_64_grok_prstatus,
+ elf64_x86_64_adjust_dynamic_symbol, allocate_dynrelocs,
+ elf64_x86_64_size_dynamic_sections, elf64_x86_64_relocate_section,
+ elf64_x86_64_finish_dynamic_sections): ..
+ * elfarm-nabi.c (elf32_arm_nabi_grok_prstatus): ..
+ * elfcode.h (elf_slurp_reloc_table): ..
+ * elflink.c (_bfd_elf_create_got_section, elf_add_dt_needed_tag,
+ elf_finalize_dynstr, elf_link_add_object_symbols,
+ bfd_elf_size_dynamic_sections, elf_link_sort_relocs,
+ elf_link_input_bfd, bfd_elf_final_link, bfd_elf_discard_info): ..
+ * elfn32-mips.c (gprel32_with_gp, mips16_gprel_reloc,
+ elf32_mips_grok_prstatus): ..
+ * elfxx-ia64.c (elfNN_ia64_relax_section, allocate_dynrel_entries,
+ elfNN_ia64_size_dynamic_sections, elfNN_ia64_install_dyn_reloc,
+ elfNN_ia64_choose_gp, elfNN_ia64_final_link,
+ elfNN_ia64_finish_dynamic_sections): ..
+ * elfxx-mips.c (mips_elf_create_procedure_table,
+ mips_elf_check_mips16_stubs, _bfd_mips_elf_gprel16_with_gp,
+ _bfd_mips_elf_hi16_reloc, _bfd_mips_elf_generic_reloc,
+ mips_elf_global_got_index, mips_elf_multi_got,
+ mips_elf_create_compact_rel_section, mips_elf_calculate_relocation,
+ mips_elf_allocate_dynamic_relocations,
+ mips_elf_create_dynamic_relocation, _bfd_mips_elf_fake_sections,
+ _bfd_mips_relax_section, _bfd_mips_elf_adjust_dynamic_symbol,
+ _bfd_mips_elf_always_size_sections,
+ _bfd_mips_elf_size_dynamic_sections,
+ _bfd_mips_elf_finish_dynamic_symbol,
+ _bfd_mips_elf_finish_dynamic_sections,
+ _bfd_mips_elf_modify_segment_map, _bfd_mips_elf_discard_info,
+ _bfd_mips_elf_write_section, _bfd_mips_elf_set_section_contents,
+ _bfd_elf_mips_get_relocated_section_contents,
+ _bfd_mips_elf_final_link, _bfd_mips_elf_merge_private_bfd_data): ..
+ * hp300hpux.c (callback): ..
+ * hppabsd-core.c (make_bfd_asection): ..
+ * hpux-core.c (make_bfd_asection): ..
+ * i386linux.c (linux_link_create_dynamic_sections,
+ bfd_i386linux_size_dynamic_sections, linux_finish_dynamic_link): ..
+ * i386msdos.c (msdos_write_object_contents): ..
+ * i386os9k.c (os9k_callback, os9k_write_object_contents,
+ os9k_set_section_contents): ..
+ * ieee.c (parse_expression, ieee_slurp_external_symbols,
+ ieee_slurp_sections, ieee_slurp_debug, ieee_slurp_section_data,
+ ieee_write_section_part, do_with_relocs, do_as_repeat,
+ do_without_relocs, ieee_write_debug_part, init_for_output,
+ ieee_set_section_contents): ..
+ * ihex.c (ihex_scan, ihex_read_section, ihex_get_section_contents): ..
+ * irix-core.c (do_sections, make_bfd_asection): ..
+ * libaout.h (aout_section_merge_with_text_p): ..
+ * libbfd.c (_bfd_generic_get_section_contents,
+ _bfd_generic_get_section_contents_in_window): ..
+ * linker.c (default_indirect_link_order): ..
+ * lynx-core.c (make_bfd_asection): ..
+ * m68klinux.c (linux_link_create_dynamic_sections,
+ bfd_m68klinux_size_dynamic_sections, linux_finish_dynamic_link): ..
+ * mach-o.c (bfd_mach_o_make_bfd_section,
+ bfd_mach_o_scan_read_dylinker, bfd_mach_o_scan_read_dylib,
+ bfd_mach_o_scan_read_thread, bfd_mach_o_scan_read_symtab,
+ bfd_mach_o_scan_read_segment): ..
+ * merge.c (_bfd_add_merge_section, record_section, merge_strings,
+ _bfd_merge_sections): ..
+ * mmo.c (mmo_find_sec_w_addr, mmo_get_spec_section, mmo_get_loc,
+ mmo_map_set_sizes, mmo_canonicalize_symtab,
+ mmo_internal_write_section, mmo_write_object_contents): ..
+ * netbsd-core.c (netbsd_core_file_p): ..
+ * nlm32-alpha.c (nlm_alpha_read_reloc, nlm_alpha_write_import,
+ nlm_alpha_set_public_section): ..
+ * nlm32-ppc.c (nlm_powerpc_read_reloc, nlm_powerpc_write_reloc): ..
+ * nlm32-sparc.c (nlm_sparc_write_import): ..
+ * nlmcode.h (add_bfd_section, nlm_swap_auxiliary_headers_in,
+ nlm_compute_section_file_positions): ..
+ * oasys.c (oasys_object_p, oasys_slurp_section_data,
+ oasys_write_sections, oasys_write_data, oasys_set_section_contents): ..
+ * opncls.c (get_debug_link_info): ..
+ * osf-core.c (make_bfd_asection): ..
+ * pdp11.c (some_aout_object_p, adjust_o_magic, adjust_z_magic,
+ adjust_n_magic, adjust_sizes_and_vmas, squirt_out_relocs,
+ final_link, aout_link_input_section): ..
+ * peXXigen.c (_bfd_XXi_swap_sym_in, _bfd_XXi_swap_aouthdr_out,
+ pe_print_idata, pe_print_edata, pe_print_pdata, pe_print_reloc): ..
+ * pef.c (bfd_pef_make_bfd_section, bfd_pef_print_loader_section,
+ bfd_pef_scan_start_address, bfd_pef_parse_symbols): ..
+ * ppcboot.c (ppcboot_object_p, ppcboot_canonicalize_symtab): ..
+ * ptrace-core.c (ptrace_unix_core_file_p): ..
+ * reloc.c (bfd_perform_relocation, bfd_install_relocation,
+ _bfd_final_link_relocate, bfd_generic_relax_section,
+ bfd_generic_get_relocated_section_contents): ..
+ * reloc16.c (bfd_coff_reloc16_relax_section,
+ bfd_coff_reloc16_get_relocated_section_c): ..
+ * riscix.c (riscix_some_aout_object_p): ..
+ * rs6000-core.c (read_hdr, make_bfd_asection): ..
+ * sco5-core.c (make_bfd_asection): ..
+ * simple.c (bfd_simple_get_relocated_section_contents): ..
+ * som.c (som_object_setup, setup_sections, som_prep_headers,
+ som_write_fixups, som_begin_writing, bfd_section_from_som_symbol,
+ som_set_reloc_info, som_get_section_contents,
+ som_bfd_link_split_section): ..
+ * sparclinux.c (linux_link_create_dynamic_sections,
+ bfd_sparclinux_size_dynamic_sections, linux_finish_dynamic_link): ..
+ * srec.c (srec_scan, srec_read_section, srec_get_section_contents): ..
+ * stabs.c (_bfd_link_section_stabs, _bfd_discard_section_stabs,
+ _bfd_write_stab_strings, _bfd_stab_section_offset): ..
+ * sunos.c (sunos_read_dynamic_info, sunos_create_dynamic_sections,
+ bfd_sunos_size_dynamic_sections, sunos_scan_std_relocs,
+ sunos_scan_ext_relocs, sunos_scan_dynamic_symbol,
+ sunos_write_dynamic_symbol, sunos_check_dynamic_reloc,
+ sunos_finish_dynamic_link): ..
+ * syms.c (_bfd_stab_section_find_nearest_line): ..
+ * tekhex.c (first_phase, tekhex_set_section_contents,
+ tekhex_write_object_contents): ..
+ * trad-core.c (trad_unix_core_file_p): ..
+ * versados.c (process_esd, process_otr, process_otr): ..
+ * vms-gsd.c (_bfd_vms_slurp_gsd, _bfd_vms_write_gsd): ..
+ * vms-misc.c (add_new_contents): ..
+ * vms-tir.c (check_section, new_section, _bfd_vms_write_tir): ..
+ * vms.c (vms_set_section_contents): ..
+ * xcofflink.c (xcoff_get_section_contents, xcoff_link_add_symbols,
+ xcoff_sweep, bfd_xcoff_size_dynamic_sections, xcoff_build_ldsyms,
+ _bfd_xcoff_bfd_final_link, xcoff_link_input_bfd): ..
+ * xsym.c (bfd_sym_scan): .. See above.
+
+2004-06-21 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elfxx-ia64.c (elfNN_ia64_relax_section): Add addend when
+ calling _bfd_merged_section_offset only for section symbols.
+
+2004-06-22 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-ppc.c (ppc_elf_relax_section): Implement reference code
+ for handling SEC_MERGE symbols in relax_section.
+
+2004-06-21 Alexandre Oliva <aoliva@redhat.com>
+
+ 2003-05-15 Richard Sandiford <rsandifo@redhat.com>
+ * cpu-h8300.c (compatible): Allow h8300s and h8300sx code to be
+ linked together. Mark the result as h8300sx code.
+
+2004-06-21 Alexandre Oliva <aoliva@redhat.com>
+
+ * elf-bfd.h (struct elf_backend_data): Added
+ elf_backend_omit_section_dynsym.
+ (_bfd_elf_link_omit_section_dynsym): Declare.
+ * elf32-frv.c (_frvfdpic_link_omit_section_dynsym): New.
+ (elf_backend_omit_section_dynsym): Use it for frvfdpic.
+ * elflink.c (_bfd_elf_link_omit_section_dynsym): Split out of...
+ (_bfd_elf_link_renumber_dynsyms): ... this function.
+ * elfxx-target.h (elf_backend_omit_section_dynsym): Default to
+ _bfd_elf_link_omit_section_dynsym).
+ (elfNN_bed): Added elf_backend_omit_section_dynsym.
+
+2004-06-21 Nick Clifton <nickc@redhat.com>
+
+ * coffcode.h (styp_to_sec_flags): Ignore IMAGE_SCN_MEM_NOT_PAGED
+ flags.
+
+2004-06-17 Jerome Guitton <guitton@gnat.com>
+
+ * bfd-in.h (bfd_cache_close_all): New function declaration.
+ * bfd-in2.h: Regenerate.
+ * cache.c (bfd_cache_close_all): New function definition.
+
+2004-06-16 Mark Kettenis <kettenis@gnu.org>
+
+ * configure.in: Don't set COREFILE to trad-core.lo for FreeBSD
+ 4.10 and beyond.
+ * configure: Regenerate.
+
+2004-06-16 Daniel Jacobowitz <dan@debian.org>
+
+ * elf32-ppc.c (ppc_elf_create_linker_section): Create symbols in
+ the pre-existing section.
+
+2004-06-15 Alan Modra <amodra@bigpond.net.au>
+
+ * section.c (struct sec): Remove usused flags. Reorganize a little.
+ (bfd_get_section_size_before_reloc): Delete.
+ (bfd_get_section_size_after_reloc): Delete.
+ (STD_SECTION): Update.
+ (bfd_get_section_size_now): Delete.
+ (bfd_set_section_contents): Don't referece reloc_done.
+ (bfd_get_section_contents): Remove reloc_done comment.
+ * bout.c (b_out_bfd_get_relocated_section_contents): Don't set
+ reloc_done.
+ * coff-alpha.c (alpha_ecoff_get_relocated_section_contents): Likewise.
+ * ecoff.c (bfd_debug_section): Update initializer.
+ * elfxx-mips.c (_bfd_elf_mips_get_relocated_section_contents): Ditto.
+ * reloc.c (bfd_generic_get_relocated_section_contents): Likewise.
+ * bfd-in.h (bfd_section_size): Expand.
+ (bfd_get_section_size): New macro.
+ * bfd-in2.h: Regenerate.
+ * coff64-rs6000.c (xcoff64_write_object_contents): Replace
+ bfd_get_section_size_before_reloc with bfd_get_section_size.
+ * coffcode.h (coff_write_object_contents): Likewise.
+ * coffgen.c (build_debug_section): Likewise.
+ * dwarf1.c (parse_line_table): Likewise.
+ (_bfd_dwarf1_find_nearest_line): Likewise.
+ * ecoff.c (_bfd_ecoff_write_object_contents): Likewise.
+ * i386msdos.c (msdos_write_object_contents): Likewise.
+ * pdp11.c (squirt_out_relocs): Likewise.
+ * elf32-sh64.c (sh64_find_section_for_address): Remove comment.
+ * elf64-mmix.c (mmix_elf_final_link): Update comment.
+
+2004-06-14 Chris Demetriou <cgd@broadcom.com>
+
+ * elf32-mips.c (elf_mips_gnu_pcrel32): Add (undoing 2004-04-24
+ removal) with updated comment.
+ (bfd_elf32_bfd_reloc_type_lookup): Add back case for
+ BFD_RELOC_32_PCREL.
+ (mips_elf32_rtype_to_howto): Add back case for R_MIPS_PC32.
+ * elfxx-mips.c (mips_elf_calculate_relocation): Likewise.
+
+2004-06-12 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-x86-64.c (elf64_x86_64_relocate_section): Ignore reloc
+ overflow on branches to undefweaks.
+
+2004-06-11 Maciej W. Rozycki <macro@ds2.pg.gda.pl>
+
+ * coff-alpha.c (alpha_relocate_section): Set used_by_bfd directly
+ as ecoff_section_data() does not return a valid lvalue.
+
+2004-06-09 Alexandre Oliva <aoliva@redhat.com>
+
+ * elflink.c (elf_sort_symbol): Compare section id, not pointers.
+ (elf_link_add_object_symbols): Likewise.
+
+ * elf-m10300.c (_bfd_mn10300_elf_reloc_type_class): New.
+ (elf_backend_reloc_type_class): New.
+
+2004-06-08 Mark Kettenis <kettenis@gnu.org>
+
+ * configure.in (hppa*-*-netbsd*, hppa*-*-openbsd): Set COREFILE to
+ netbsd-core.lo.
+ * configure: Regenerate.
+
+2004-06-07 Daniel Jacobowitz <dan@debian.org>
+
+ From: Albert Chin-A-Young <china@thewrittenword.com>
+ * elf-bfd.h (struct eh_cie_fde): Convert unsigned char bitfields
+ to unsigned int.
+
+2004-05-29 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elfxx-ia64.c (elfNN_ia64_relax_section): Undo the last
+ change.
+
+2004-05-28 DJ Delorie <dj@redhat.com>
+
+ * elf-m10300.c (mn10300_elf_relax_section): Preserve reloc addend
+ for linking, but otherwise adjust reloc for merged sections.
+
+2004-05-28 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elfxx-ia64.c (elfNN_ia64_relax_section): Properly call
+ _bfd_merged_section_offset for local symbols.
+
+2004-05-28 Andrew Stubbs <andrew.stubbs@superh.com>
+
+ * Makefile.am: Regenerate dependencies.
+ * Makefile.in: Regenerate.
+ * archures.c: Add bfd_mach_sh3_nommu .
+ * bfd-in2.h: Regenerate.
+ * cpu-sh.c: Add sh3-nommu architecture.
+ (bfd_to_arch_table): Create new table.
+ (sh_get_arch_from_bfd_mach): Create new function.
+ (sh_get_arch_up_from_bfd_mach): Create new function.
+ (sh_merge_bfd_arch): Create new function.
+ * elf32-sh.c (sh_ef_bfd_table): Add table.
+ (sh_elf_check_relocs): Replace switch statement with
+ use of sh_ef_bfd_table .
+ (sh_elf_get_flags_from_mach): Add new function.
+ (sh_find_elf_flags): Likewise.
+ (sh_elf_copy_private_data): Replace most of non-elf contents
+ with a call to sh_merge_bfd_arch() .
+
+2004-05-27 Michael Chastain <mec.gnu@mindspring.com>
+
+ * Makefile.am (bfdver.h): Use explicit filename, not $< .
+ * Makefile.in: Regenerate.
+
+2004-05-27 Alexandre Oliva <aoliva@redhat.com>
+
+ * elf-m10300.c (elf32_mn10300_finish_hash_table_entry): Avoid
+ custom calling conventions for dynamic symbols.
+ (mn10300_elf_relax_section): Avoid relaxing a function as a local
+ symbol if it's an alias to a global one.
+
+2004-05-26 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf.c (_bfd_elf_make_section_from_shdr): Undo the last
+ change.
+
+2004-05-27 Alexandre Oliva <aoliva@redhat.com>
+
+ * elf-m10300.c (mn10300_elf_relax_section): Don't test isym within
+ loop over hashes.
+
+2004-05-26 Alan Modra <amodra@bigpond.net.au>
+
+ * elf.c (_bfd_elf_make_section_from_shdr): Don't set SEC_EXCLUDE
+ for SHT_GROUP sections.
+
+2004-05-25 Alan Modra <amodra@bigpond.net.au>
+
+ * elflink.c (elf_link_add_object_symbols): Don't set up merge
+ section data here..
+ * elf.c (_bfd_elf_merge_sections): .. Do it here instead.
+ * merge.c: Formatting. Remove unnecessary casts. Expand
+ bfd_get_section_alignment macro.
+ (struct sec_merge_sec_info): Rename "first" to "first_str". Update
+ use throughout file.
+ (_bfd_add_merge_section): Rename from _bfd_merge_section. Update
+ comment. Abort on dynamic or non-SEC_MERGE input. Don't test
+ section name to determine sinfo group, instead test output section
+ and alignment.
+ (_bfd_merge_sections): Add struct bfd_link_info param. Call
+ _bfd_strip_section_from_output rather than just twiddling flags.
+ * libbfd-in.h (_bfd_add_merge_section): Rename, update comment.
+ (_bfd_merge_sections): Update prototype.
+ * libbfd.h: Regenerate.
+
+2004-05-24 Mark Kettenis <kettenis@gnu.org>
+
+ * netbsd-core.c: Correctly indent section that sets architecture
+ from machine ID.
+
+ From Miod Vallat <miod@online.fr>:
+ * m88kopenbsd.c: New file.
+ * targets.c (m88k_openbsd_vec): New.
+ * config.bfd: Add m88k-*-openbsd*.
+ * configure.in (m88k-*-openbsd*): Set COREFILE to netbsd-core.lo.
+ (m88kopenbsd_vec): New.
+ * configure: Regenerate.
+ * Makefile.am (BFD32_BACKENDS): Add m88kopenbsd.lo.
+ (BFD32_BACKENDS_CFILES): Add m88kopenbsd.c.
+ Run "make dep-am".
+ * Makefile.in: Regenerate.
+ * po/SRC-POTFILES.in: Regenerate.
+
+2004-05-24 Nick Clifton <nickc@redhat.com>
+
+ * hash.c: Remove bogus node "Changing the default Hash Table Size"
+ introduced by hash table size patch.
+
+2004-05-22 Ben Elliston <bje@au.ibm.com>
+
+ * configure.in (is_release): Remove.
+ (bfd_version_date, bfd_version, bfd_version_string): Likewise.
+ (AC_OUTPUT): Don't output bfdver.h from version.h.
+ * configure: Regenerate.
+ * Makefile.am (RELEASE): New variable.
+ (bfdver.h): New target.
+ * Makefile.in: Regenerate.
+ * doc/Makefile.in: Likewise.
+
+2004-05-22 Ben Elliston <bje@au.ibm.com>
+
+ * Makefile.am (config.status): Don't depend on version.h.
+ * Makefile.in: Regenerate.
+
+2004-05-22 Alan Modra <amodra@bigpond.net.au>
+
+ * merge.c (_bfd_merged_section_offset): Remove "addend" param.
+ * libbfd-in.h (_bfd_merged_section_offset): Adjust prototype.
+ * libbfd.h: Regenerate.
+ * elf.c (_bfd_elf_rela_local_sym): Adjust call.
+ (_bfd_elf_rel_local_sym): Likewise.
+ * elflink.c (_bfd_elf_link_sec_merge_syms): Likewise.
+ (elf_link_input_bfd): Likewise.
+ * elf32-ppc.c (ppc_elf_relax_section): Likewise.
+ * elf64-alpha.c (elf64_alpha_relocate_section): Likewise.
+ * elfxx-ia64.c (elfNN_ia64_relax_section): Likewise.
+ (elfNN_ia64_relocate_section): Likewise.
+
+2004-05-21 Andy Chittenden <achittenden@bluearc.com>
+
+ * hash.c (bfd_default_hash_table_size): New variable.
+ (bfd_hash_table_init): Use new variable instead of DEFAULT_SIZE.
+ (bfd_hash_set_default_size): New function. Set the default size
+ to a selected prime number close to the argument. Document new
+ function.
+ * bfd-in.h: Add prototype for bfd_hash_set_default_size.
+ * bfd-in2.h: Regenerate.
+ * Makefile.am (hash.lo): Add dependency upon libiberty.h.
+ * Makefile.in: Regenerate.
+
+2004-05-21 Mark Kettenis <kettenis@gnu.org>
+
+ * libaout.h (machine_type): Add M_88K_OPENBSD and M_HPPA_OPENBSD.
+ * netbsd-core.c (netbsd_core_file_p): Set architecture for alpha,
+ arm, m68k, m88k and hppa core files.
+
+2004-05-21 Nick Clifton <nickc@redhat.com>
+
+ * bfdio.c (bfd_bread): Do not use iovec if it is NULL.
+ (bfd_bwrite): Likewise.
+ (bfd_tell): Likewise.
+ (bfd_flush): Likewise.
+ (bfd_stat): Likewise.
+ (bfd_seek): Likewise.
+ (bfd_get_mtime): Likewise.
+ (bfd_get_size): Likewise.
+
+2004-05-19 Ben Elliston <bje@au.ibm.com>
+
+ * dwarf2.c (_bfd_dwarf2_find_nearest_line): Comment correction.
+
+2004-05-19 Mikulas Patocka <mikulas@artax.karlin.mff.cuni.cz>
+
+ * archive.c (_bfd_get_elt_at_filepos): Cope with a nested archives.
+ (bfd_generic_openr_next_archived_file): Likewise.
+
+2004-05-17 Bob Wilson <bob.wilson@acm.org>
+
+ * elf32-xtensa.c (xtensa_get_property_section_name): Determine linkonce
+ section names by inserting a new substring after .gnu.linkonce, except
+ for .gnu.linkonce.t.* where the "t." is replaced.
+
+2004-05-17 Adam Nemet <anemet@lnxw.com>
+
+ * config.bfd (sparc-*-lynxos* case): Add to obsolete list.
+ (m68-*-lynxos* case): Likewise.
+ (powerpc-*-lyxnos* case): New case.
+ (i[3-7]86-*-lynxos* case): Update to LynxOS 4.0 ELF.
+
+2004-05-17 David Heine <dlheine@tensilica.com>
+
+ * aout-target.h (MY_bfd_copy_private_header_data): Define.
+ * aout-tic30.c (MY_bfd_copy_private_header_data): Define.
+ * bfd.c (bfd_copy_private_header_data): Define.
+ * coff-rs6000.c (rs6000coff_vec, pmac_xcoff_vec): Add entries for new
+ interface.
+ * coff64-rs6000.c (rs6000coff64_vec, aix5coff64_vec): Likewise.
+ * coffcode.h (coff_bfd_copy_private_header_data): Define.
+ * elf-bfd.h (_bfd_elf_copy_private_header_data): Declare.
+ * elf.c (_bfd_elf_copy_private_section_data): Remove code to set up
+ segments by calling copy_private_bfd_data.
+ (_bfd_elf_copy_private_header_data): Define.
+ * elfxx-target.h (bfd_elfNN_bfd_copy_private_header_data): Define.
+ * libbfd-in.h (_bfd_generic_bfd_copy_private_header_data): Define.
+ * libecoff.h (_bfd_ecoff_bfd_copy_private_header_data): Define.
+ * mach-o.c (bfd_mach_o_bfd_copy_private_header_data): Define.
+ * mmo.c (mmo_bfd_copy_private_header_data): Define.
+ * ppcboot.c (ppcboot_bfd_copy_private_header_data): Define.
+ * som.c (som_bfd_copy_private_header_data): Define.
+ * targets.c (BFD_JUMP_TABLE_COPY): Add _bfd_copy_private_header_data.
+ * vms.c (vms_bfd_copy_private_header_data): Define.
+ * bfd-in2.h: Regenerate.
+ * libbfd.h: Regenerate.
+
+2004-05-15 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * elfxx-mips.c (MINUS_TWO): Define.
+ (mips_elf_higher, mips_elf_highest,
+ mips_elf_create_dynamic_relocation): Use MINUS_ONE and MINUS_TWO for
+ some bfd_vma values.
+ (_bfd_mips_elf_finish_dynamic_symbol): Likewise. Code cleanup.
+
+2004-05-14 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ * som.c (log2): Rename to exact_log2. Adjust all callers.
+
+2004-05-13 Paul Brook <paul@codesourcery.com>
+
+ * elf-eh-frame.c (_bfd_elf_discard_section_eh_frame): Handle
+ dwarf3 format CIE entries. Remove comment about the size of the
+ ra_column field. It is now correctly deduced.
+
+2004-05-13 Joel Sherrill <joel@oarcorp.com>
+
+ * config.bfd (or32-*-rtems*): Switch to elf.
+
+2004-05-13 Nick Clifton <nickc@redhat.com>
+
+ * po/fr.po: Updated French translation.
+
+2004-05-11 Jakub Jelinek <jakub@redhat.com>
+
+ * elflink.c (bfd_elf_final_link): Don't output STT_SECTION symbol
+ into .dynsym if elf_section_data (sec)->dynindx <= 0.
+ Adjust counting of last_local.
+ (_bfd_elf_link_renumber_dynsyms): Don't assign dynindx to sections
+ other than SHT_PROGBITS/SHT_NOBITS and neither for .got/.got.plt/.plt
+ created by the linker nor !SHF_ALLOC.
+
+ * elf32-i386.c (elf_i386_finish_dynamic_sections): Point
+ DT_PLTGOT to the start of the .got.plt section instead of the
+ .got output section. Set sh_entsize for .got section in addition
+ to .got.plt.
+ (elf_i386_relocate_section): Don't assume _GLOBAL_OFFSET_TABLE_
+ is at sgot->output_section->vma.
+ * elf64-x86-64.c (elf64_x86_64_finish_dynamic_sections): Point
+ DT_PLTGOT to the start of the .got.plt section instead of the
+ .got output section.
+ (elf64_x86_64_relocate_section): Don't assume _GLOBAL_OFFSET_TABLE_
+ is at sgot->output_section->vma. Set sh_entsize for .got section
+ in addition to .got.plt.
+ * elf.c (_bfd_elf_print_private_bfd_data): Handle PT_GNU_RELRO.
+ (bfd_section_from_phdr): Likewise.
+ (map_sections_to_segments): Likewise.
+ (assign_file_positions_for_segments): Likewise.
+ (get_program_header_size): Likewise.
+ * elflink.c (bfd_elf_size_dynamic_sections): Set
+ elf_tdata (output_bfd)->relro from info->relro.
+ * elf-bfd.h (struct elf_obj_tdata): Add relro field.
+
+2004-05-08 Alexandre Oliva <aoliva@redhat.com>
+
+ * elf32-frv.c (_frvfdpic_add_dyn_reloc): Don't warn when we get
+ a zero symndx for which we hadn't accounted a dynamic relocation.
+ (_frvfdpic_add_rofixup): Likewise.
+
+2004-05-07 Brian Ford <ford@vss.fsi.com>
+ DJ Delorie <dj@redhat.com>
+
+ * coffcode.h (coff_write_object_contents) [COFF_IMAGE_WITH_PE]:
+ Propagate IMAGE_FILE_LARGE_ADDRESS_AWARE.
+ * peXXigen.c (_bfd_XX_print_private_bfd_data_common): Recognize
+ IMAGE_FILE_LARGE_ADDRESS_AWARE. Use PE defines.
+
+2004-05-07 Alexandre Oliva <aoliva@redhat.com>
+
+ * elf32-frv.c (elf32_frvfdpic_modify_segment_map): Return
+ immediately if there's no link info.
+ (elf32_frvfdpic_copy_private_bfd_data): New.
+ (bfd_elf32_bfd_copy_private_bfd_data): Use it for frvfdpic.
+
+2004-05-06 Zack Weinberg <zack@codesourcery.com>
+
+ * dwarf2.c (add_line_info): Also set info->filename to NULL if
+ filename argument is null; do not call strlen on a null pointer.
+
+2004-05-06 Daniel Jacobowitz <drow@mvista.com>
+
+ * elf32-arm.h (elf32_arm_relocate_section): Remove R_ARM_PLT32
+ special case.
+
+2004-05-05 Alexandre Oliva <aoliva@redhat.com>
+
+ * configure.in (bfd_elf32_frvfdpic_vec): New.
+ * configure: Rebuilt.
+ * targets.c (bfd_elf32_frvfdpic_vec): New.
+ * config.bfd: Enable it on frv-*-elf and frv-*-*linux*, as default
+ on the latter.
+ * elf32-frv.c: Prefix all identifiers added for FDPIC support with
+ frvfdpic instead of frv. Rearrange elf-target macros such that
+ the FDPIC-specific ones are only defined for this new target
+ vector.
+ (bfd_elf32_frvfdpic_vec): Declare.
+ (IS_FDPIC): New.
+ (elf32_frv_relocate_section): Use it to enable segment checking
+ and to control rofixup emission. Add output section vma to
+ applied relocation in non-LOAD non-ALLOC sections. Use
+ _bfd_error_handler for errors.
+ (_frv_create_got_section): Create .rel.got and .rofixup only in
+ FDPIC. Create non-dynamic _gp at .got+2048 in non-FDPIC, like the
+ linker script.
+ (elf32_frvfdpic_size_dynamic_sections): Assume FDPIC.
+ (elf32_frvfdpic_modify_segment_map): Likewise.
+ (elf32_frv_finish_dynamic_sections): New, do-nothing.
+ (elf32_frvfdpic_finish_dynamic_sections): Assume FDPIC. Improve
+ error message if we miscompute the rofixup size.
+ (frvfdpic_elf_use_relative_eh_frame): Assume FDPIC.
+ (frvfdpic_elf_encode_eh_address): Likewise.
+ (elf32_frv_check_relocs): Reject FDPIC-only relocs in non-FDPIC.
+ Record relocs only in FDPIC. Make sure _gp is defined for GPREL
+ relocs. Reject unknown relocation types.
+ (elf32_frv_object_p): Make sure target vector matches FDPIC bits.
+ (frv_elf_merge_private_bfd_data): Likewise.
+ (ELF_MAXPAGESIZE): Revert to 0x1000 for elf32-frv; keep it as
+ 0x4000 for newly-added elf32-frvfdpic.
+
+2004-05-05 Nick Clifton <nickc@redhat.com>
+
+ PR/136
+ * cache.c (bfd_cache_lookup_worker): Call abort() rather than
+ returning NULL as most users of this function do not check its
+ return value.
+ * hppabsd-core.c (hppabsd_core_core_file_p): Do not check result
+ of bfd_cache_lookup().
+ * sco5-core.c (sco5_core_file_p): Likewise.
+ * trad-core.c (trad_unix_core_file_p): Likewise.
+
+2004-05-05 Nick Clifton <nickc@redhat.com>
+
+ * cache.c (bfd_cache_lookup): Improve formatting.
+ * archive.c: Fix formatting.
+
+2004-05-05 Peter Barada <peter@the-baradas.com>
+
+ * bfd_archures.c(bfd_architecture): Add 521x,5249,547x,548x.
+ * cpu-m68k.c(bfd_m68k_arch): Likewise.
+ * bfd-in2.h(bfd_architecture): Regenerate.
+
+2004-05-03 Alan Modra <amodra@bigpond.net.au>
+
+ * elf.c (_bfd_elf_rela_local_sym): Set kept_section for excluded
+ SEC_MERGE sections.
+ * elflink.c (elf_link_input_bfd): Adjust output reloc index for
+ those against discarded link-once and SEC_MERGE section symbols.
+
+2004-05-02 H.J. Lu <hongjiu.lu@intel.com>
+
+ * section.c (bfd_get_section_by_name_if): New.
+ * bfd-in2.h: Regenerated.
+
+2004-05-02 Alan Modra <amodra@bigpond.net.au>
+
+ * som.c (som_bfd_is_group_section): Define.
+
+2004-05-01 Alan Modra <amodra@bigpond.net.au>
+
+ * section.c (bfd_make_section_anyway): Copy the whole
+ bfd_hash_entry, not just "next" from existing entry.
+
+2004-04-30 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf.c (bfd_section_from_shdr): Maintain the section order in
+ a section group.
+ (special_sections): Add ".note.GNU-stack".
+ (elf_fake_sections): Handle section group for relocatable
+ link..
+
+2004-04-30 H.J. Lu <hongjiu.lu@intel.com>
+
+ * section.c (bfd_sections_find_if): New.
+ * bfd-in2.h: Regenerated.
+
+2004-04-30 Alan Modra <amodra@bigpond.net.au>
+
+ * section.c (bfd_make_section_anyway): Add all sections to hash tab.
+
+ * elf-bfd.h (bfd_elf_is_group_section): Declare.
+ * elf.c (bfd_elf_is_group_section): New function.
+ * elfxx-target.h (bfd_elfNN_bfd_is_group_section
+ * section.c (bfd_generic_is_group_section): New function.
+ * targets.c (struct bfd_target): Add _bfd_is_group_section field.
+ (BFD_JUMP_TABLE_LINK): Adjust.
+ * aout-adobe.c (aout_32_bfd_is_group_section): Define.
+ * aout-target.h (MY_bfd_is_group_section): Define.
+ * aout-tic30.c (MY_bfd_is_group_section): Define.
+ * bfd.c (bfd_is_group_section): Define.
+ * binary.c (binary_bfd_is_group_section): Define.
+ * bout.c (b_out_bfd_is_group_section): Define.
+ * coff-alpha.c (_bfd_ecoff_bfd_is_group_section): Define.
+ * coff-mips.c (_bfd_ecoff_bfd_is_group_section): Define.
+ * coff-rs6000.c (rs6000coff_vec, pmac_xcoff_vec): Adjust.
+ * coff64-rs6000.c (rs6000coff64_vec, aix5coff64_vec): Adjust.
+ * coffcode.h (coff_bfd_is_group_section): Define.
+ * i386msdos.c (msdos_bfd_is_group_section): Define.
+ * i386os9k.c (os9k_bfd_is_group_section): Define.
+ * ieee.c (ieee_bfd_is_group_section): Define.
+ * ihex.c (ihex_bfd_is_group_section): Define.
+ * libbfd-in.h (_bfd_nolink_bfd_is_group_section): Define.
+ * mach-o.c (bfd_mach_o_bfd_is_group_section): Define.
+ * mmo.c (mmo_bfd_is_group_section): Define.
+ * nlm-target.h (nlm_bfd_is_group_section): Define.
+ * oasys.c (oasys_bfd_is_group_section): Define.
+ * pef.c (bfd_pef_bfd_is_group_section): Define.
+ * ppcboot.c (ppcboot_bfd_is_group_section): Define.
+ * srec.c (srec_bfd_is_group_section): Define.
+ * tekhex.c (tekhex_bfd_is_group_section): Define.
+ * versados.c (versados_bfd_is_group_section): Define.
+ * vms.c (vms_bfd_is_group_section): Define.
+ * xsym.c (bfd_sym_bfd_is_group_section): Define.
+ * bfd-in2.h: Regenerate.
+ * libbfd.h: Regenerate.
+
+2004-04-30 Alan Modra <amodra@bigpond.net.au>
+
+ * elflink.c (elf_gc_mark): Follow indirect and warning syms.
+
+2004-04-30 Hans-Peter Nilsson <hp@axis.com>
+
+ * configure.in: Update version to 2.15.91.
+ * configure: Regenerate.
+
+2004-04-29 Brian Ford <ford@vss.fsi.com>
+
+ * bfd.c (bfd_get_sign_extend_vma): Add pe[i]-i386 case to DJGPP hack.
+ * coffcode.h (DOT_DEBUG, GNU_LINKONCE_WI): Define.
+ [!COFF_WITH_PE] (sec_to_styp_flags, styp_to_sec_flags): Use them.
+ (coff_compute_section_file_positions) [RS6000COFF_C]: Likewise.
+ [COFF_WITH_PE] (sec_to_styp_flags): Handle DWARF 2/3 .debug* and
+ .gnu.linkonce.wi. sections.
+ * pe-i386.c (COFF_SUPPORT_GNU_LINKONCE): Define.
+ (COFF_SECTION_ALIGNMENT_ENTRIES): Add entries for .debug and
+ .gnu.linkonce.wi..
+ * pei-i386.c (COFF_SUPPORT_GNU_LINKONCE): Likewise.
+ (COFF_SECTION_ALIGNMENT_ENTRIES): Likewise.
+
+2004-04-28 Chris Demetriou <cgd@broadcom.com>
+
+ * reloc.c: Remove BFD_RELOC_PCREL_HI16_S and BFD_RELOC_PCREL_LO16.
+ * bfd-in2.h: Regenerate.
+ * libbfd.h: Likewise.
+
+2004-04-28 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ * som.c (struct som_misc_symbol_info): Add is_comdat, is_common and
+ dup_common fields.
+ (setup_sections): Use som_subspace_dictionary_record struct instead
+ subspace_dictionary_record. Set SEC_LINK_ONCE if subspace is
+ is_comdat, is_common or dup_common.
+ (som_prep_headers): Use som_subspace_dictionary_record struct. Set
+ is_comdat, is_common and dup_common in section subspace_dict from
+ copy_data.
+ (som_begin_writing): Use som_subspace_dictionary_record struct.
+ (som_finish_writing): Likewise.
+ (som_bfd_derive_misc_symbol_info): Add support to set is_comdat,
+ is_common and dup_common flags in info for symbol. Add comment
+ regarding linker support for these fields. Slightly reorganize
+ function.
+ (som_build_and_write_symbol_table): Set is_comdat, is_common and
+ dup_common fields in symbol table from symbol info.
+ (bfd_som_set_subsection_attributes): Add comdat, common and dup_common
+ arguments. Set corresponding fields in copy_data. Change all callers.
+ (som_bfd_ar_write_symbol_stuff): Set dup_common flag in library
+ symbol table.
+ (som_vec): Add SEC_LINK_ONCE to applicable section flags.
+ * som.h (som_subspace_dictionary_record): Define.
+ (som_copyable_section_data_struct): Add is_comdat, is_common and
+ dup_common fields.
+ (som_section_data_struct): Use som_subspace_dictionary_record struct
+ instead of subspace_dictionary_record.
+ (bfd_boolean bfd_som_set_subsection_attributes): Adjust prototype.
+
+2004-04-27 Bob Wilson <bob.wilson@acm.org>
+
+ * elf32-xtensa.c (xtensa_read_table_entries): Use section _cooked_size
+ if set. Check reloc_done flag before applying relocations. Use
+ output addresses, both when applying relocations and when comparing
+ against the specified section.
+ (elf_xtensa_relocate_section): Use output address to check if dynamic
+ reloc is in a literal pool. Set section's reloc_done flag.
+
+2004-04-27 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf32-sh64.c (elf_backend_section_flags): New. Defined.
+ (sh64_elf_set_mach_from_flags): Remove the kludge for .cranges
+ section.
+ (sh64_elf_section_flags): New. Set SEC_DEBUGGING for .cranges
+ section.
+
+2004-04-27 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-alpha.c (elf64_alpha_read_ecoff_info): Don't assign
+ structure field removed in 2004-04-24 patch.
+ * elf64-sparc.c (sparc64_elf_plt_sym_val): Warning fix.
+
+ * elf-bfd.h (struct elf_backend_data <elf_backend_section_flags>):
+ Constify hdr arg.
+ * elf32-arm.h (elf32_arm_section_flags): Likewise.
+ * elf64-alpha.c (elf64_alpha_section_flags): Likewise.
+ * elfxx-ia64.c (elfNN_ia64_section_flags): Likewise.
+ * elf.c (_bfd_elf_make_section_from_shdr): Set the bfd_section
+ field before calling elf_backend_section_flags.
+
+2004-04-24 Chris Demetriou <cgd@broadcom.com>
+
+ * elf32-mips.c (elf_mips_gnu_rel_hi16, elf_mips_gnu_rel_lo16)
+ (elf_mips_gnu_pcrel64, elf_mips_gnu_pcrel32): Remove.
+ (bfd_elf32_bfd_reloc_type_lookup): Remove cases for
+ BFD_RELOC_PCREL_HI16_S, BFD_RELOC_PCREL_LO16, BFD_RELOC_64_PCREL,
+ and BFD_RELOC_32_PCREL.
+ (mips_elf32_rtype_to_howto): Remove cases for R_MIPS_GNU_REL_HI16,
+ R_MIPS_GNU_REL_LO16, R_MIPS_PC64, R_MIPS_PC32.
+ * elfxx-mips.c (mips_elf_calculate_relocation): Likewise.
+ (_bfd_mips_elf_lo16_reloc): Remove handling for R_MIPS_GNU_REL_HI16.
+ (mips_elf_next_relocation): Move comment about matching HI/LO
+ relocations to...
+ (_bfd_mips_elf_relocate_section): Here. Remove handling for
+ R_MIPS_GNU_REL_HI16.
+
+2004-04-23 Chris Demetriou <cgd@broadcom.com>
+
+ * coff-mips.c (mips_relhi_reloc, mips_rello_reloc)
+ (mips_switch_reloc, mips_read_relocs, mips_relax_section)
+ (mips_relax_pcrel16, PCREL16_EXPANSION_ADJUSTMENT): Remove.
+ (mips_relocate_hi): Remove now-unused 'adjust' and 'pcrel' arguments,
+ and update comments to reflect current usage.
+ (mips_howto_table): Remove entries for MIPS_R_RELHI, MIPS_R_RELLO,
+ and MIPS_R_SWITCH, as well as several empty entries. Update comment
+ for MIPS_R_PCREL16.
+ (mips_ecoff_swap_reloc_in, mips_ecoff_swap_reloc_out)
+ (mips_adjust_reloc_out, mips_bfd_reloc_type_lookup): Remove support
+ for MIPS_R_SWITCH, MIPS_R_RELLO, and MIPS_R_RELHI relocations.
+ (mips_adjust_reloc_in): Likewise, adjust maximum accepted relocation
+ type number to be MIPS_R_PCREL16.
+ (mips_relocate_section): Remove support for link-time relaxation
+ of branches used by embedded-PIC. Remove support for MIPS_R_SWITCH,
+ MIPS_R_RELLO, and MIPS_R_RELHI relocations.
+ (_bfd_ecoff_bfd_relax_section): Redefine to bfd_generic_relax_section.
+ * ecoff.c (ecoff_indirect_link_order): Remove support for link-time
+ relaxation of branches used by embedded-PIC.
+ * ecofflink.c (bfd_ecoff_debug_accumulate): Likewise.
+ * libecoff.h (struct ecoff_section_tdata): Remove embedded-PIC
+ related members, update comment.
+ * pe-mips.c: Remove disabled (commented-out and #if 0'd)
+ code related to embedded-PIC.
+ * elfxx-mips.c (_bfd_mips_elf_read_ecoff_info): Remove
+ initialization of now-removed 'adjust' member of
+ 'struct ecoff_debug_info'.
+
+2004-04-23 Chris Demetriou <cgd@broadcom.com>
+
+ * elfxx-mips.c (mips_elf_get_global_gotsym_index): Remove.
+
+2004-04-21 Philip Blundell <pb@nexus.co.uk>
+
+ * elf32-arm.h (elf32_arm_check_relocs): Don't output REL32
+ relocs for locally defined symbols during -shared final link.
+ (elf32_arm_final_link_relocate): Likewise.
+
+2004-04-22 Jakub Jelinek <jakub@redhat.com>
+
+ * elf64-x86-64.c (elf64_x86_64_copy_indirect_symbol): Copy also
+ ELF_LINK_POINTER_EQUALITY_NEEDED.
+ (elf64_x86_64_check_relocs): Set ELF_LINK_POINTER_EQUALITY_NEEDED
+ if r_type is not R_X86_64_PC32.
+ (elf64_x86_64_finish_dynamic_symbol): If
+ ELF_LINK_POINTER_EQUALITY_NEEDED is not set, clear st_value of
+ SHN_UNDEF symbols.
+
+2004-04-22 Kaz Kojima <kkojima@rr.iij4u.or.jp>
+
+ * elf32-sh.c (sh_elf_plt_sym_val): New function.
+ (elf_backend_plt_sym_val): Define.
+
+2004-04-22 Andrew Cagney <cagney@redhat.com>
+
+ * opncls.c (bfd_alloc): Fix type of "wanted" in doco.
+
+2004-04-22 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ * hpux-core.c (hpux_core_core_file_p): Add cast in call to
+ make_bfd_asection.
+ * som.c (som_set_section_contents): Constantify second argument.
+ (hppa_som_gen_reloc_type): Abort for unsupported selectors.
+ (som_object_setup): Rework to avoid warning.
+ (setup_sections, som_write_fixups, bfd_section_from_som_symbol):
+ Likewise.
+
+2004-04-22 Andrew Cagney <cagney@redhat.com>
+
+ * cache.c (bfd_cache_close): Check for a previously closed file.
+
+2004-04-22 Jakub Jelinek <jakub@redhat.com>
+
+ * bfd.c (bfd_get_synthetic_symtab): Define.
+ * targets.c (BFD_JUMP_TABLE_DYNAMIC): Add
+ NAME##_get_synthetic_symtab.
+ (struct bfd_target): Add _bfd_get_synthetic_symtab.
+ * libbfd-in.h (_bfd_nodynamic_get_synthetic_symtab): Define.
+ * elf-bfd.h (struct elf_backend_data): Add plt_sym_val and
+ relplt_name fields.
+ (_bfd_elf_get_synthetic_symtab): New prototype.
+ * elfcode.h (elf_get_synthetic_symtab): Define.
+ * elf.c (_bfd_elf_get_synthetic_symtab): New function.
+ * elfxx-target.h (bfd_elfNN_get_synthetic_symtab): Define.
+ (elf_backend_plt_sym_val, elf_backend_relplt_name): Define.
+ (elfNN_bed): Add elf_backend_plt_sym_val and elf_backend_relplt_name.
+ * bfd-in2.h: Rebuilt.
+ * libbfd.h: Rebuilt.
+ * elf32-i386.c (elf_i386_plt_sym_val): New function.
+ (elf_backend_plt_sym_val): Define.
+ * elf64-x86-64.c (elf64_x86_64_plt_sym_val): New function.
+ (elf_backend_plt_sym_val): Define.
+ * elf32-s390.c (elf_s390_plt_sym_val): New function.
+ (elf_backend_plt_sym_val): Define.
+ * elf64-s390.c (elf_s390_plt_sym_val): New function.
+ (elf_backend_plt_sym_val): Define.
+ * elf32-sparc (elf32_sparc_plt_sym_val): New function.
+ (elf_backend_plt_sym_val): Define.
+ * elf64-sparc.c (sparc64_elf_plt_sym_val): New function.
+ (elf_backend_plt_sym_val): Define.
+ * elf32-ppc.c (ppc_elf_plt_sym_val): New function.
+ (elf_backend_plt_sym_val): Define.
+ * aout-target.h (MY_get_synthetic_symtab): Define.
+ * aout-tic30.c (MY_get_synthetic_symtab): Define.
+ * coff-rs6000.c (rs6000coff_vec): Add
+ _bfd_nodynamic_get_synthetic_symtab.
+ (pmac_xcoff_vec): Likewise.
+ * coff64-rs6000.c (rs6000coff64_vec): Add
+ _bfd_nodynamic_get_synthetic_symtab.
+ (aix5coff64_vec): Likewise.
+ * sunos.c (MY_get_synthetic_symtab): Define.
+ * vms.c (vms_get_synthetic_symtab): Define.
+
+2004-04-22 Nick Clifton <nickc@redhat.com>
+
+ * bfd.c (bfd_archive_filename): Return NULL on NULL input.
+
+2004-04-22 Peter Barada <peter@the-baradas.com>
+
+ * archures.c: Add bfd_mach_mcfv4e to bfd_architecture.
+ * bfd2-in.h: Regenerate.
+ * cpu-m68k.c: Add 'm68k:mcfv4e' to arch_info_struct[].
+
+2004-04-21 Chris Demetriou <cgd@broadcom.com>
+
+ * coff-mips.c (bfd_mips_ecoff_create_embedded_relocs): Remove.
+ * elf32-mips.c (bfd_mips_elf32_create_embedded_relocs): Remove.
+ * bfd-in.h (bfd_mips_ecoff_create_embedded_relocs)
+ (bfd_mips_elf32_create_embedded_relocs): Remove prototypes
+ * bfd-in2.h: Regenerate.
+
+2004-04-21 Bob Wilson <bob.wilson@acm.org>
+
+ * elf32-xtensa.c (is_same_value): Add final_static_link argument and
+ require relocations against a weak symbol to reference the same
+ symbol hash entry if not a final, static link.
+ (get_cached_value, add_value_map): Add final_static_link argument.
+ (remove_literals): Pass final_static_link argument as needed.
+
+2004-04-21 Andrew Cagney <cagney@redhat.com>
+
+ * opncls.c (_bfd_new_bfd_contained_in): Copy "iovec".
+ (struct opncls, opncls_btell, opncls_bseek, opncls_bread)
+ (opncls_bwrite, opncls_bclose, opncls_bflush)
+ (opncls_bstat, opncls_iovec, bfd_openr_iovec): Implement a
+ bfd iovec that uses function callbacks.
+ (bfd_close): Use the iovec's bclose.
+ * cache.c (cache_btell, cache_bseek, cache_bread, cache_bwrite)
+ (cache_bclose, cache_bflush, cache_bstat)
+ (cache_iovec): New functions and global variable, implement a
+ cache "iovec", where applicable set bfd_error.
+ (bfd_cache_init, bfd_cache_close): Set/test the bfd's iovec.
+ * bfdio.c (struct bfd_iovec): Define.
+ (real_read): Delete function.
+ (bfd_bread, bfd_bread, bfd_bwrite, bfd_tell, bfd_flush, bfd_stat)
+ (bfd_seek, bfd_get_mtime, bfd_get_size): Use the bfd's "iovec",
+ assume that bread and bwrite set bfd_error.
+ * bfd.c (struct bfd): Add "iovec", update comments.
+ * bfd-in2.h, libbfd.h: Re-generate.
+
+2004-04-21 Andrew Cagney <cagney@redhat.com>
+
+ * libaout.h (enum machine_type): Add M_POWERPC_NETBSD.
+
+2004-04-21 Eric Botcazou <ebotcazou@act-europe.fr>
+
+ * elflink.c (elf_gc_mark_dynamic_ref_symbol): New function.
+ (bfd_elf_gc_sections): Fail if a shared object is being created.
+ Do not fail if dynamic sections have been created. Instead call
+ elf_gc_mark_dynamic_ref_symbol to mark sections that contain
+ dynamically referenced symbols. Do not mark the whole graph
+ rooted at .eh_frame, only the section proper.
+
+2004-04-20 DJ Delorie <dj@redhat.com>
+
+ * reloc.c: Add BFD_RELOC_32_SECREL.
+ * bfd-in2.h: Regenerate.
+ * libbfd.h: Likewise.
+ * coff-i386.c (howto_table) [COFF_WITH_PE]: Add R_SECREL32.
+ (coff_i386_rtype_to_howto) [COFF_WITH_PE]: Handle it.
+ (coff_i386_reloc_type_lookup) [COFF_WITH_PE]: Likewise.
+
+2004-04-19 Jakub Jelinek <jakub@redhat.com>
+
+ * elf32-sparc.c (elf32_sparc_relocate_section): Handle
+ relocs against hidden/protected undefweak symbols properly.
+ * elf64-sparc.c (sparc64_elf_relocate_section): Likewise.
+
+2004-04-18 Mark Kettenis <kettenis@gnu.org>
+
+ * libaout.h (enum machine_type): Add M_POWERPC_NETBSD.
+ * netbsd-core.c (netbsd_core_file_p): Set architecture for PowerPC
+ core files.
+
+2004-04-17 Brian Ford <ford@vss.fsi.com>
+
+ * peXXigen.c (_bfd_XXi_swap_aouthdr_out): Use the first non-zero
+ filepos for the SizeOfHeaders field.
+ (_bfd_XXi_swap_scnhdr_out): Correct section flags lossage on reloc
+ overflow.
+ (_bfd_XXi_swap_sym_in): Remove redundant section flags assignment.
+
+2004-04-16 Alan Modra <amodra@bigpond.net.au>
+
+ * simple.c (bfd_simple_get_relocated_section_contents): Don't
+ change reloc_done. Set and restore _cooked_size.
+ (RETURN): Delete.
+
+2004-04-15 Mark Kettenis <kettenis@gnu.org>
+
+ * netbsd-core.c (netbsd_core_file_p): Set architecture for VAX
+ core files.
+
+2004-04-15 Nick Clifton <nickc@redhat.com>
+
+ * bfd.c (bfd_archive_filename): Catch NULL bfd pointers.
+
+2004-04-15 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-sparc.c (sparc64_elf_check_relocs): Fix thinko last change.
+
+2004-04-15 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elflink.c (_bfd_elf_merge_symbol): Treat weak as strong only
+ when it is a definition.
+
+2004-04-14 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-sparc.c (elf32_sparc_relocate_section): Don't abort
+ when statically linking PIC code.
+ * elf64-sparc.c (sparc64_elf_relocate_section): Likewise.
+
+2004-04-11 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * config.bfd: Remove mips*-*-mach3* and mips*-dec-mach3* targets.
+ * configure.in: Remove mips-dec-bsd*, mips-dec-mach3*, mips-*-mach3*
+ targets amd aout_mips_big_vec, aout_mips_little_vec target vectors.
+ * configure: Regenerate.
+
+2004-04-08 Richard Sandiford <rsandifo@redhat.com>
+
+ * elflink.c: Include libiberty.h.
+ * Makefile.am (elflink.lo): Depend on libiberty.h.
+ * Makefile.in: Regenerate.
+
+2004-04-06 Daniel Jacobowitz <drow@mvista.com>
+
+ * elfxx-mips.c (MIPS_ELF_STUB_SECTION_NAME): Always use
+ ".MIPS.stubs".
+
+2004-04-05 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elfxx-ia64.c (elfNN_ia64_size_dynamic_sections): Always
+ reserve the memory for dynamic linker
+
+2004-04-05 Mark Kettenis <kettenis@gnu.org>
+
+ * netbsd-core.c (CORE_WCOOKIE_OFFSET): New define.
+ (netbsd_core_file_p): Create a .wcookie section for OpenBSD/sparc.
+
+2004-04-02 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf32-cr16c.c (elf32_cr16c_relocate_section): Use
+ RELOC_FOR_GLOBAL_SYMBOL.
+ (elf32_cr16c_add_symbol_hook): Remove const from Elf_Internal_Sym.
+
+2004-04-02 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf32-arm.h (elf32_arm_final_link_relocate): Handle
+ R_ARM_ALU* only if OLD_ARM_ABI is not defined.
+
+2004-04-01 Paul Brook <paul@codesourcery.com>
+
+ * bfd-in.h (bfd_elf32_arm_process_before_allocation): Update.
+ * elf32-arm.h (struct elf32_elf_section_map): New.
+ (struct _arm_elf_section_data): New.
+ (elf32_arm_section_data): Define.
+ (struct elf32_arm_link_hash_table): Add byteswap_code.
+ (elf32_arm_link_hash_table_create): Initialize byteswap_code.
+ (bfd_elf32_arm_process_before_allocation): Add byteswap_code.
+ (elf32_arm_post_process_headers): Set EF_ARM_BE8.
+ (elf32_arm_output_symbol_hook, elf32_arm_new_section_hook,
+ elf32_arm_compare_mapping, elf32_arm_write_section): New functions.
+ (bfd_elf32_new_section_hook, elf_backend_write_section,
+ elf_backend_link_output_symbol_hook): Define.
+
+2004-04-01 Andy Chittenden <achittenden@bluearc.com>
+
+ * stabs.c (struct stab_link_includes_totals): Add field 'symb'
+ that keeps the characters in a B_INCL..B_EINCL range.
+ (_bfd_link_section_stabs): When computing the sum of the
+ characters in a B_INCL..B_EINCL range also keep a copy of those
+ characters. Use this information to distinguish between
+ include sections that have the same sum and the same length
+ but which are nevertheless unique.
+
+2004-03-31 Paul Brook <paul@codesourcery.com>
+
+ * elf32-arm.h (elf32_arm_final_link_relocate): Add R_ARM_ALU*.
+ * elfarm-nabi.c (elf32_arm_howto_table): Ditto.
+
+2004-03-31 Andy Chittenden <achittenden@bluearc.com>
+
+ * stabs.c (struct stab_link_includes_totals): Rename field 'total'
+ to 'sum_chars' and add field 'num_chars'.
+ (_bfd_link_section_stabs): When computing the sum of the
+ characters in a B_INCL..B_EINCL range also keep a count of the
+ number of characters. Use this information to help distinguish
+ between include sections when have the same sum but which
+ nevertheless are still unique.
+
+2004-03-31 Mattias Engdegård <mattias@virtutech.se>
+
+ * stabs.c (_bfd_link_section_stabs): Do not skip N_EXCL stabs.
+
+2004-03-30 Galit Heller <Galit.Heller@nsc.com>
+ Tomer Levi <Tomer.Levi@nsc.com>
+
+ * Makefile.am (ALL_MACHINES): Add cpu-cr16c.lo.
+ (ALL_MACHINES_CFILES): Add cpu-cr16c.c.
+ (BFD32_BACKENDS): Add elf32-cr16c.lo.
+ (BFD32_BACKENDS_CFILES): Add elf32-cr16c.c.
+ (cpu-cr16c.lo): New target.
+ (elf32-cr16c.lo): Likewise.
+ * Makefile.in: Regenerate.
+ * archures.c (bfd_architecture): Add bfd_{arch,mach}_cr16c.
+ (bfd_archures_list): Add bfd_cr16c_arch.
+ * config.bfd: Handle cr16c-*-elf*.
+ * configure.in: Handle bfd_elf32_cr16c_vec.
+ * configure: Regenerate.
+ * reloc.c: Add BFD_RELOC_16C_NUM08, BFD_RELOC_16C_NUM08_C,
+ BFD_RELOC_16C_NUM16, BFD_RELOC_16C_NUM16_C,
+ BFD_RELOC_16C_NUM32, BFD_RELOC_16C_NUM32_C,
+ BFD_RELOC_16C_DISP04, BFD_RELOC_16C_DISP04_C,
+ BFD_RELOC_16C_DISP08, BFD_RELOC_16C_DISP08_C,
+ BFD_RELOC_16C_DISP16, BFD_RELOC_16C_DISP16_C,
+ BFD_RELOC_16C_DISP24, BFD_RELOC_16C_DISP24_C,
+ BFD_RELOC_16C_DISP24a, BFD_RELOC_16C_DISP24a_C,
+ BFD_RELOC_16C_REG04, BFD_RELOC_16C_REG04_C,
+ BFD_RELOC_16C_REG04a, BFD_RELOC_16C_REG04a_C,
+ BFD_RELOC_16C_REG14, BFD_RELOC_16C_REG14_C,
+ BFD_RELOC_16C_REG16, BFD_RELOC_16C_REG16_C,
+ BFD_RELOC_16C_REG20, BFD_RELOC_16C_REG20_C,
+ BFD_RELOC_16C_ABS20, BFD_RELOC_16C_ABS20_C,
+ BFD_RELOC_16C_ABS24, BFD_RELOC_16C_ABS24_C,
+ BFD_RELOC_16C_IMM04, BFD_RELOC_16C_IMM04_C,
+ BFD_RELOC_16C_IMM16, BFD_RELOC_16C_IMM16_C,
+ BFD_RELOC_16C_IMM20, BFD_RELOC_16C_IMM20_C,
+ BFD_RELOC_16C_IMM24, BFD_RELOC_16C_IMM24_C,
+ BFD_RELOC_16C_IMM32, BFD_RELOC_16C_IMM32_C.
+ * targets.c (bfd_elf32_cr16c_vec): Declare.
+ (bfd_target_vector): Add bfd_elf32_cr16c_vec.
+ * cpu-cr16c.c: New file.
+ * elf32-cr16c.c: Likewise.
+ * libbfd.h: Regenerate.
+ * bfd-in2.h: Likewise.
+
+2004-03-30 Jakub Jelinek <jakub@redhat.com>
+
+ * elf.c (map_sections_to_segments): Fix handling of .tbss.
+
+2004-03-27 Alan Modra <amodra@bigpond.net.au>
+
+ * Makefile.am: Remove all mention of elflink.h.
+ * Makefile.in: Regenerate.
+ * bfd-in.h (bfd_elf_discard_info): Declare.
+ (bfd_elf32_discard_info, bfd_elf64_discard_info): Delete.
+ * bfd-in2.h: Regenerate.
+ * elf-bfd.h (bfd_elf32_print_symbol, bfd_elf64_print_symbol,
+ bfd_elf32_link_record_dynamic_symbol,
+ bfd_elf64_link_record_dynamic_symbol,
+ _bfd_elf_link_record_dynamic_symbol, bfd_elf32_bfd_final_link,
+ bfd_elf64_bfd_final_link, elf_link_record_local_dynamic_symbol,
+ _bfd_elf32_link_record_local_dynamic_symbol,
+ _bfd_elf64_link_record_local_dynamic_symbol,
+ _bfd_elf32_gc_sections, _bfd_elf32_gc_common_finalize_got_offsets,
+ _bfd_elf32_gc_common_final_link, _bfd_elf64_gc_common_final_link,
+ _bfd_elf32_gc_record_vtinherit, _bfd_elf32_gc_record_vtentry,
+ _bfd_elf64_gc_sections, _bfd_elf64_gc_common_finalize_got_offsets,
+ _bfd_elf64_gc_record_vtinherit, _bfd_elf64_gc_record_vtentry,
+ _bfd_elf32_reloc_symbol_deleted_p,
+ _bfd_elf64_reloc_symbol_deleted_p): Delete.
+ (bfd_elf_link_record_dynamic_symbol,
+ bfd_elf_link_record_local_dynamic_symbol,
+ bfd_elf_final_link, bfd_elf_gc_sections,
+ bfd_elf_gc_record_vtinherit, bfd_elf_gc_record_vtentry,
+ bfd_elf_gc_common_finalize_got_offsets, bfd_elf_gc_common_final_link,
+ bfd_elf_reloc_symbol_deleted_p): Declare.
+ (WILL_CALL_FINISH_DYNAMIC_SYMBOL): Define.
+ * elf32-arm.h: Update for changed function names. Remove local
+ WILL_CALL_FINISH_DYNAMIC_SECTION define.
+ * elf-hppa.h, elf-m10300.c, elf32-cris.c, elf32-d10v.c, elf32-dlx.c,
+ * elf32-fr30.c, elf32-frv.c, elf32-h8300.c, elf32-hppa.c, elf32-i386.c,
+ * elf32-iq2000.c, elf32-m32r.c, elf32-m68hc1x.c, elf32-m68k.c,
+ * elf32-mcore.c, elf32-openrisc.c, elf32-ppc.c, elf32-s390.c,
+ * elf32-sh.c, elf32-sparc.c, elf32-v850.c, elf32-vax.c,
+ * elf32-xstormy16.c, elf32-xtensa.c, elf64-alpha.c, elf64-hppa.c,
+ * elf64-mmix.c, elf64-ppc.c, elf64-s390.c, elf64-sh64.c, elf64-sparc.c,
+ * elf64-x86-64.c, elfxx-ia64.c, elfxx-mips.c, elfxx-target.h: Likewise.
+ * elfxx-target.h (bfd_elfNN_bfd_final_link): Define.
+ (bfd_elfNN_print_symbol): Define.
+ * elfcode.h: Don't include elflink.h.
+ (elf_bfd_discard_info, elf_reloc_symbol_deleted_p,
+ elf_link_record_dynamic_symbol, elf_bfd_final_link, elf_gc_sections,
+ elf_gc_common_finalize_got_offsets, elf_gc_common_final_link,
+ elf_gc_record_vtinherit, elf_gc_record_vtentry,
+ elf_link_record_local_dynamic_symbol): Don't define.
+ * elflink.c: Update for changed function names. Move elflink.h
+ code here.
+ * elflink.h: Delete file.
+ * po/SRC-POTFILES.in: Regenerate.
+ * po/bfd.pot: Regenerate.
+
+2004-03-27 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-mmix.c (mmix_elf_relocate_section): Restore code setting
+ "name" for global syms accidentally removed in 2004-03-20 change.
+
+2004-03-27 Alan Modra <amodra@bigpond.net.au>
+
+ * elf-bfd.h (struct elf_reloc_cookie): Add r_sym_shift field.
+ * elflink.h: Replace all occurrences of sizeof (Elf_External_*)
+ where Elf_External_* is different for 64 and 32 bit, with
+ corresponding elf_size_info field.
+ (struct elf_final_link_info): Use "bfd_byte *" instead
+ of "Elf_External_Sym *" for external_syms and symbuf.
+ (elf_link_adjust_relocs): Set up r_type_mask and r_sym_shift local
+ vars and use instead of ELF_R_INFO and ELF_R_TYPE macros.
+ (struct elf_link_sort_rela): Add "sym_mask" alias for "offset".
+ (elf_link_sort_cmp1): Use sym_mask field instead of ELF_R_SYM.
+ (elf_link_sort_cmp2): Adjust.
+ (elf_link_sort_relocs): Set up r_sym_mask local var instead of
+ using ELF_R_SYM macro. Set u.sym_mask.
+ (elf_bfd_final_link): Call _bfd_elf_stringtab_init instead of macro
+ version, elf_stringtab_init. Ditto for bfd_section_from_elf_index
+ vs. section_from_elf_index. Adjust Elf_External_Sym pointer
+ arithmetic. Pass bed to elf_link_flush_output_syms. Adjust
+ Elf_External_Dyn pointer arithmentic. Use bed swap_dyn_in and
+ swap_syn_out functions. Rearrange dyn swap in/out switch.
+ (elf_link_output_sym): Adjust Elf_External_Sym pointer arithmentic.
+ Pass bed to elf_link_flush_output_syms. Use bed swap_symbol_out.
+ (elf_link_flush_output_syms): Add elf_backend_data arg.
+ (elf_link_check_versioned_symbol): Likewise.
+ (elf_link_output_extsym): Pass bed to elf_link_check_versioned_symbol.
+ Adjust Elf_External_Sym pointer arithmetic. Use bed swap_symbol_out.
+ (elf_link_input_bfd): Use bfd_section_from_elf_index. Set up
+ r_type_mask and r_sym_shift local vars and use instead of ELF_R_SYM,
+ ELF_R_TYPE and ELF_R_INFO macros.
+ (elf_reloc_link_order): Select ELF32_R_INFO or ELF64_R_INFO invocation
+ based on size rather than using ELF_R_INFO.
+ (elf_gc_mark): Set up r_sym_shift local var and use instead of
+ ELF_R_SYM macro.
+ (struct alloc_got_off_arg): New.
+ (elf_gc_common_finalize_got_offsets): Use elf_size_info instead of
+ ARCH_SIZE. Pass get entry size down to elf_gc_allocate_got_offsets.
+ (elf_gc_allocate_got_offsets): Adjust.
+ (elf_reloc_symbol_deleted_p): Usee cookie.r_sym_shift instead of
+ ELF_R_SYM. Use bfd_section_from_elf_index.
+ (elf_bfd_discard_info): Set cookie.r_sym_shift.
+ * elfcode.h (elf_stringtab_init, section_from_elf_index): Delete.
+ (elf_slurp_symbol_table): Use bfd_section_from_elf_index.
+
+2004-03-26 Stan Shebs <shebs@apple.com>
+
+ Remove MPW support, no longer used.
+ * config.bfd (powerpc-*-mpw*): Remove configuration.
+ * mpw-config.in, mpw-make.sed: Remove files.
+ * ecoffswap.h [MPW_C]: Remove MPW-C-friendly version of code.
+
+2004-03-26 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (elf_backend_add_symbol_hook): Define.
+ (ppc64_elf_add_symbol_hook): New function.
+ * elf-bfd.h (struct elf_backend_data <elf_add_symbol_hook>): Remove
+ const from Elf_Internal_Sym param.
+ * elflink.c (elf_link_add_object_symbols): Adjust.
+ * elf-hppa.h (elf_hppa_add_symbol_hook): Adjust.
+ * elf32-frv.c (elf32_frv_add_symbol_hook): Adjust.
+ * elf32-i370.c (elf_backend_add_symbol_hook): Adjust.
+ * elf32-m32r.c (m32r_elf_add_symbol_hook): Adjust.
+ * elf32-m68hc1x.c (elf32_m68hc11_add_symbol_hook): Adjust.
+ * elf32-m68hc1x.h (elf32_m68hc11_add_symbol_hook): Adjust.
+ * elf32-ppc.c (ppc_elf_add_symbol_hook): Adjust.
+ * elf32-sh64.c (sh64_elf_add_symbol_hook): Adjust.
+ * elf32-v850.c (v850_elf_add_symbol_hook): Adjust.
+ * elf64-alpha.c (elf64_alpha_add_symbol_hook): Adjust.
+ * elf64-mmix.c (mmix_elf_add_symbol_hook): Adjust.
+ * elf64-sh64.c (sh64_elf64_add_symbol_hook): Adjust.
+ * elf64-sparc.c (sparc64_elf_add_symbol_hook): Adjust.
+ * elfxx-ia64.c (elfNN_ia64_add_symbol_hook): Adjust.
+ * elfxx-mips.c (_bfd_mips_elf_add_symbol_hook): Adjust.
+ * elfxx-mips.h (_bfd_mips_elf_add_symbol_hook): Adjust.
+
+2004-03-26 Alan Modra <amodra@bigpond.net.au>
+
+ * elfxx-target.h (bfd_elfNN_bfd_link_add_symbols): Define.
+ * elf-bfd.h (_bfd_elf_link_add_archive_symbols): Delete.
+ (_bfd_elf_sort_symbol, _bfd_elf_add_dt_needed_tag): Delete.
+ (_bfd_elf_finalize_dynstr, bfd_elf32_bfd_link_add_symbols): Delete.
+ (bfd_elf64_bfd_link_add_symbols): Delete.
+ (bfd_elf_link_add_symbols): Declare.
+ * elfcode.h (elf_bfd_link_add_symbols): Delete.
+ * elflink.c: Include safe-ctype.h.
+ (elf_add_dt_needed_tag): Rename from _bfd_elf_add_dt_needed_tag,
+ make static.
+ (elf_sort_symbol): Rename from _bfd_elf_sort_symbol, make static.
+ (elf_finalize_dynstr): Rename from _bfd_elf_finalize_dynstr, make
+ static.
+ (elf_link_add_archive_symbols): Rename from
+ _bfd_elf_link_add_archive_symbols, make static.
+ (elf_link_add_object_symbols): New function. Corresponding
+ elflink.h function converted to use elf_size_info.
+ (bfd_elf_link_add_symbols): Likewise.
+ (bfd_elf_size_dynamic_sections): Adjust.
+ * elflink.h (elf_bfd_link_add_symbols): Delete.
+ (elf_link_add_object_symbols): Delete.
+ * elf32-gen.c (elf32_generic_link_add_symbols): Call
+ bfd_elf_link_add_symbols.
+ * elf64-gen.c (elf64_generic_link_add_symbols): Likewise.
+
+2004-03-25 Alan Modra <amodra@bigpond.net.au>
+
+ * elflink.h (elf_link_add_object_symbols): Add DT_NEEDED for as-needed
+ and chained shared libs only if dynsym. Clear dynsym on forced-local.
+
+ * elf-bfd.h (_bfd_elf_add_dynamic_entry): Declare.
+ (bfd_elf32_add_dynamic_entry, bfd_elf64_add_dynamic_entry): Delete.
+ (_bfd_elf_add_dt_needed_tag): Declare.
+ (_bfd_elf_sort_symbol): Declare.
+ (_bfd_elf_finalize_dynstr): Declare.
+ (RELOC_FOR_GLOBAL_SYM): Formatting.
+ * elfcode.h (elf_add_dynamic_entry): Delete.
+ * elflink.c (_bfd_elf_add_dynamic_entry): New function. Corresponding
+ elflink.h function converted to use elf_size_info.
+ (_bfd_elf_add_dt_needed_tag): Likewise.
+ (_bfd_elf_sort_symbol): Likewise.
+ (_bfd_elf_finalize_dynstr): Likewise.
+ (compute_bucket_count): Likewise.
+ (bfd_elf_size_dynamic_sections): Likewise. Check result of
+ _bfd_elf_strtab_add before calling _bfd_elf_strtab_addref.
+ (elf_adjust_dynstr_offsets, elf_collect_hash_codes): Moved from..
+ * elflink.h: ..here.
+ (sort_symbol, add_dt_needed_tag): Delete.
+ (elf_add_dynamic_entry, elf_finalize_dynstr): Delete.
+ (compute_bucket_count, NAME(bfd_elf,size_dynamic_sections)): Delete.
+ Update all users.
+ * elf32-arm.h (add_dynamic_entry): Update. Remove casts.
+ * elf32-cris.c (add_dynamic_entry): Likewise.
+ * elf32-hppa.c (add_dynamic_entry): Likewise.
+ * elf32-i370.c (add_dynamic_entry): Likewise.
+ * elf32-i386.c (add_dynamic_entry): Likewise.
+ * elf32-m32r.c (add_dynamic_entry): Likewise.
+ * elf32-m68k.c (add_dynamic_entry): Likewise.
+ * elf32-ppc.c (add_dynamic_entry): Likewise.
+ * elf32-s390.c (add_dynamic_entry): Likewise.
+ * elf32-sh.c (add_dynamic_entry): Likewise.
+ * elf32-sparc.c (add_dynamic_entry): Likewise.
+ * elf32-vax.c (add_dynamic_entry): Likewise.
+ * elf32-xtensa.c (add_dynamic_entry): Likewise.
+ * elf64-alpha.c (add_dynamic_entry): Likewise.
+ * elf64-hppa.c (add_dynamic_entry): Likewise.
+ * elf64-ppc.c (add_dynamic_entry): Likewise.
+ * elf64-s390.c (add_dynamic_entry): Likewise.
+ * elf64-sparc.c (add_dynamic_entry): Likewise.
+ * elf64-x86-64.c (add_dynamic_entry): Likewise.
+ * elfxx-ia64.c (add_dynamic_entry): Likewise.
+ * elfxx-mips.c (MIPS_ELF_ADD_DYNAMIC_ENTRY): Likewise.
+ * elf-m10300.c (_bfd_mn10300_elf_size_dynamic_sections): Likewise.
+ * elf32-frv.c (elf32_frv_size_dynamic_sections): Likewise.
+ * elf64-sh64.c (sh64_elf64_size_dynamic_sections): Likewise.
+
+2004-03-23 Paul Brook <paul@codesourcery.com>
+
+ * elf32-arm.h (arm_print_private_bfd_data): Add EABI v3.
+
+2004-03-22 Bob Wilson <bob.wilson@acm.org>
+
+ * elf32-xtensa.c (elf_xtensa_check_relocs): Remove code to read
+ literal tables and check for relocs outside of literal pools.
+ (elf_xtensa_make_sym_local): Don't clear ELF_LINK_NON_GOT_REF flag.
+ (elf_xtensa_fix_refcounts): Don't check ELF_LINK_NON_GOT_REF or
+ set DF_TEXTREL.
+ (elf_xtensa_size_dynamic_sections): Don't add DT_TEXTREL entry.
+ (elf_xtensa_relocate_section): Read literal tables and check for
+ dynamic relocations in read-only sections and not in literal pools.
+
+2004-03-23 Alan Modra <amodra@bigpond.net.au>
+
+ PR 51.
+ * linker.c (bfd_wrapped_link_hash_lookup): Handle info->wrap_char.
+
+2004-03-22 Hans-Peter Nilsson <hp@axis.com>
+
+ * elf32-cris.c (cris_elf_relocate_section) <case R_CRIS_16_GOTPLT,
+ R_CRIS_16_GOTPLT>: Also error if there's no PLT for a symbol
+ not defined by the executable, or defined in a DSO.
+ <eliding run-time relocation of .got>: Initialize GOT entry for a
+ function symbol or ELF_LINK_HASH_NEEDS_PLT statically in an
+ executable.
+ (cris_elf_gc_sweep_hook): Improve fallthrough marking.
+ (elf_cris_try_fold_plt_to_got): Improve head comment. Do not fold
+ a PLT reloc to GOT for an executable.
+ (elf_cris_adjust_dynamic_symbol): Only fold a .got.plt entry with
+ .got for a DSO and explain why.
+ (elf_cris_discard_excess_program_dynamics): Also lose GOT-relocs
+ and unreferenced symbols for which a PLT is defined. Adjust
+ dynamic-symbol pruning correspondingly, to make sure we don't lose
+ a dynamic symbol also defined by a DSO.
+
+2004-03-22 Alan Modra <amodra@bigpond.net.au>
+
+ * elf-bfd.h (RELOC_FOR_GLOBAL_SYMBOL): Add input_bfd, input_section
+ and rel args. Group input and output args. Wrap to 80 columns.
+ * elf-m10200.c, elf-m10300.c, elf32-arm.h, elf32-avr.c,
+ elf32-cris.c, elf32-d10v.c, elf32-fr30.c, elf32-h8300.c,
+ elf32-hppa.c, elf32-i386.c, elf32-i860.c, elf32-ip2k.c,
+ elf32-iq2000.c, elf32-m68hc1x.c, elf32-m68k.c, elf32-mcore.c,
+ elf32-msp430.c, elf32-openrisc.c, elf32-ppc.c, elf32-s390.c,
+ elf32-sparc.c, elf32-v850.c, elf32-vax.c, elf32-xstormy16.c,
+ elf32-xtensa.c, elf64-alpha.c, elf64-mmix.c, elf64-ppc.c,
+ elf64-s390.c, elf64-sparc.c, elf64-x86-64.c, elfxx-ia64.c: Update
+ RELOC_FOR_GLOBAL_SYMBOL invocation.
+
+2004-03-20 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf-bfd.h (RELOC_FOR_GLOBAL_SYMBOL): Report error if
+ unresolved symbols in objects aren't allowed.
+
+ * elf-hppa.h (elf_hppa_relocate_section): Properly handle
+ unresolved symbols.
+ (elf_hppa_remark_useless_dynamic_symbols): Likewise.
+ (elf_hppa_unmark_useless_dynamic_symbols):
+ * elf32-frv.c (elf32_frv_relocate_section): Likewise.
+ * elf32-hppa.c (elf32_hppa_size_stubs): Likewise.
+ (elf32_hppa_relocate_section): Likewise.
+ * elf32-i370.c (i370_elf_relocate_section): Likewise.
+ * elf32-m32r.c (m32r_elf_relocate_section): Likewise.
+ * elf32-sh.c (sh_elf_relocate_section): Likewise.
+ * elf64-sh64.c (sh_elf64_relocate_section): Likewise.
+ * elfxx-mips.c (mips_elf_calculate_relocation): Likewise.
+
+ * elf-m10200.c (mn10200_elf_relocate_section): Use
+ RELOC_FOR_GLOBAL_SYMBOL.
+ * elf32-avr.c (elf32_avr_relocate_section): Likewise.
+ * elf32-d10v.c (elf32_d10v_relocate_section): Likewise.
+ * elf32-fr30.c (fr30_elf_relocate_section): Likewise.
+ * elf32-h8300.c (elf32_h8_relocate_section): Likewise.
+ * elf32-i860.c (elf32_i860_relocate_section): Likewise.
+ * elf32-m68hc1x.c (m68hc11_get_relocation_value): Likewise.
+ * elf32-mcore.c (mcore_elf_relocate_section): Likewise.
+ * elf32-msp430.c (elf32_msp430_relocate_section): Likewise.
+ * elf32-openrisc.c (openrisc_elf_relocate_section): Likewise.
+ * elf32-v850.c (v850_elf_relocate_section): Likewise.
+ * elf32-xstormy16.c (xstormy16_elf_relocate_section): Likewise.
+ * elf64-mmix.c (mmix_elf_relocate_section): Likewise.
+
+2004-03-19 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ * elf32-hppa.c (elf32_hppa_check_relocs): Handle R_PARISC_PCREL32.
+ (final_link_relocate): Likewise.
+ * elf-hppa.h (elf_hppa_reloc_final_type): Handle selectors for
+ R_PARISC_PCREL32 and R_PARISC_PCREL64 relocations.
+
+2004-03-19 Alan Modra <amodra@bigpond.net.au>
+
+ * Makefile.am: Run "make dep-am".
+ * Makefile.in: Regenerate.
+ * aclocal.m4: Regenerate.
+ * config.in: Regenerate.
+ * po/bfd.pot: Regenerate.
+
+2004-03-19 Alan Modra <amodra@bigpond.net.au>
+ H.J. Lu <hongjiu.lu@intel.com>
+
+ * elflink.c (_bfd_elf_merge_symbol): Revert last change. Move
+ type and size change code to where it was previously. Remove
+ dt_needed param. Treat old weak syms as strong if new sym is
+ from a shared lib, even when old sym is from another shared
+ lib. Remove unnecessary tests of oldweak and newweak. Correct
+ comments.
+ (_bfd_elf_add_default_symbol): Remove dt_needed param. Update
+ _bfd_elf_merge_symbol calls.
+ * elflink.h (elf_link_add_object_symbols): Update calls. Remove
+ dt_needed local var. Update comments.
+ * elf-bfd.h (_bfd_elf_merge_symbol): Update prototype.
+ (_bfd_elf_add_default_symbol): Likewise.
+
+ * elflink.c (_bfd_elf_merge_symbol): Reinstate code to handle
+ strong syms in one shared object overriding weak syms in another.
+
+2004-03-18 Alan Modra <amodra@bigpond.net.au>
+
+ * elf-bfd.h (struct elf_obj_tdata): Delete dt_soname field. Add
+ dyn_lib_class field. Rearrange for better packing.
+ (elf_dt_soname): Delete.
+ (elf_dyn_lib_class): Define.
+ * elf.c (bfd_elf_set_dt_needed_name): Update comment.
+ (bfd_elf_set_dt_needed_soname): Delete.
+ (bfd_elf_set_dyn_lib_class): New function.
+ * elflink.h (add_dt_needed_tag): New function. Split out from..
+ (elf_link_add_object_symbols): ..here. Rename "name" to "soname".
+ Use elf_dyn_lib_class to set dt_needed and add_needed. Move fallback
+ initialization of soname.
+ (elf_link_check_versioned_symbol): Test elf_dyn_lib_class instead of
+ elf_dt_soname.
+ * bfd-in.h (enum dynamic_lib_link_class): New.
+ (bfd_elf_set_dt_needed_soname): Delete.
+ (bfd_elf_set_dyn_lib_class): Declare.
+ * bfd-in2.h: Regenerate.
+
+ * elflink.c (_bfd_elf_merge_symbol): Rewrite weak symbol handling.
+ (_bfd_elf_add_default_symbol): Remove indirect BFD_ASSERTs.
+ * elflink.h (elf_link_add_object_symbols): Don't clear dt_needed in
+ symbol loop. Instead use add_needed to flag tag as written.
+
+2004-03-17 Nathan Sidwell <nathan@codesourcery.com>
+
+ * elfxx-mips.c (_bfd_mips_elf_merge_private_bfd_data): Correct
+ logic for null_input_bfd detection.
+
+2004-03-17 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * config.bfd: Switch sh-*-rtems* to ELF. Add sh-*-rtemscoff*.
+
+2004-03-16 Mark Kettenis <kettenis@gnu.org>
+
+ * netbsd-core.c (netbsd_core_file_p) [CORE_FPU_OFFSET]: Remove
+ code.
+
+2004-03-16 Alan Modra <amodra@bigpond.net.au>
+
+ * elflink.c (elf_link_read_relocs_from_section): Don't use
+ NUM_SHDR_ENTRIES in end of reloc calc. Move NULL shdr check..
+ (_bfd_elf_link_read_relocs): ..to here.
+ * elf32-ppc.c (ppc_elf_relax_section): Formatting.
+
+2004-03-16 Alan Modra <amodra@bigpond.net.au>
+
+ * configure.in (HOST_64BIT_TYPE, HOST_U_64BIT_TYPE): Don't override
+ values selected in configure.host. Require both to be defined
+ before setting BFD_HOST_64_BIT_DEFINED. Protect assignment to
+ corresponding BFD_HOST vars with quotes.
+ <${host64}-${target64}-${want64} in *true*>: Don't exempt gcc;
+ Always require BFD_HOST_64_BIT_DEFINED.
+ <file_ptr type>: Find off_t size before emitting message. Combine
+ off_t and ftello64 conditional.
+ * configure: Regenerate.
+
+2004-03-16 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-m32r.c (m32r_elf_create_dynamic_sections): Fix pointer
+ aliasing warning. Remove trailing whitespace throughout file.
+
+2004-03-15 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ * elf-hppa.h (elf_hppa_relocate_section): Pass input_bfd instead of
+ input_section in calls to get_dyn_name.
+ * elf64-hppa.c (get_dyn_name): Change type of first argument to "bfd *". Use section id of first section in input BFD to build dynamic name for
+ local symbols.
+ (elf64_hppa_check_relocs): Pass abfd in call to get_dyn_name.
+
+2004-03-15 Alan Modra <amodra@bigpond.net.au>
+
+ * bfd-in.h (bfd_int64_t, bfd_uint64_t): New types.
+ (BFD_HOST_64_BIT, BFD_HOST_U_64_BIT): Don't define here.
+ (bfd_getb64, bfd_getl64, bfd_get_bits): Return bfd_uint64_t.
+ (bfd_getb_signed_64, bfd_getl_signed_64): Return bfd_int64_t.
+ (bfd_putb64, bfd_putl64, bfd_put_bits): Accept bfd_uint64_t.
+ * configure.in (HOST_U_64BIT_TYPE): Set when sizeof long is 8.
+ (BFD_HOST_64_BIT_DEFINED, BFD_HOST_64_BIT, BFD_HOST_U_64_BIT): Set
+ when using long.
+ * libbfd.c (EIGHT_GAZILLION, COERCE64): Use bfd_int64_t.
+ (bfd_getb64): Return bfd_uint64_t. Enable when BFD_HOST_64_BIT.
+ (bfd_getl64, bfd_getb_signed_64, bfd_getl_signed_64): Likewise.
+ (bfd_putb64): Accept bfd_uint64_t. Enable when BFD_HOST_64_BIT.
+ (bfd_putl64, bfd_put_bits, bfd_get_bits): Likewise.
+ * dwarf2.c (struct attribute): Use bfd_int64_t and bfd_uint64_t.
+ (read_8_bytes, read_indirect_string, read_address): Likewise.
+ (read_abbrevs, parse_comp_unit): Likewise.
+ * targets.c (struct bfd_target): Likewise.
+ * aix386-core.c (NO_GET64, NO_PUT64, NO_GETS64): Define and use.
+ * hppabsd-core.c: Likewise. Formatting.
+ * hpux-core.c: Likewise.
+ * irix-core.c: Likewise.
+ * netbsd-core.c: Likewise.
+ * osf-core.c: Likewise.
+ * ptrace-core.c: Likewise.
+ * sco5-core.c: Likewise.
+ * trad-core.c: Likewise.
+ * configure: Regenerate.
+ * bfd-in2.h: Regenerate.
+
+2004-03-15 Alan Modra <amodra@bigpond.net.au>
+
+ * bfd-in.h (bfd_getb64, bfd_getl64): Replace bfd_byte* with void*.
+ (bfd_getb32, bfd_getl32, bfd_getb16, bfd_getl16): Likewise.
+ (bfd_getb_signed_64, bfd_getl_signed_64): Likewise.
+ (bfd_getb_signed_32, bfd_getl_signed_32): Likewise.
+ (bfd_getb_signed_16, bfd_getl_signed_16): Likewise.
+ (bfd_putb64, bfd_putl64, bfd_putb32, bfd_putl32): Likewise.
+ (bfd_putb16, bfd_putl16, bfd_get_bits, bfd_put_bits): Likewise.
+ * libbfd.c: Likewise in function definitions.
+ (bfd_put_8): Mask with 0xff rather than casting to char.
+ (bfd_putb16, bfd_putl16, bfd_putb32, bfd_putl32): Likewise.
+ (bfd_putb64, bfd_putl64, bfd_put_bits): Likewise.
+ (H_PUT_64, H_PUT_32, H_PUT_16, H_PUT_8): Remove casts, simplify.
+ (H_PUT_S64, H_PUT_S32, H_PUT_S16, H_PUT_S8): Likewise.
+ (H_GET_64, H_GET_32, H_GET_16, H_GET_8): Likewise.
+ (H_GET_S64, H_GET_S32, H_GET_S16, H_GET_S8): Likewise.
+ * libaout.h (H_PUT_64 H_PUT_32, H_PUT_16): Remove casts, simplify.
+ (H_PUT_S64, H_PUT_S32, H_PUT_S16): Likewise.
+ (H_GET_64, H_GET_32, H_GET_16): Likewise.
+ (H_GET_S64, H_GET_S32, H_GET_S16): Likewise.
+ * archive.c (do_slurp_coff_armap): Update swap prototype.
+ * coff-tic54x.c (tic54x_getl32): Replace bfd_byte* with void*.
+ (tic54x_getl_signed_32): Likewise.
+ (tic54x_putl32): Likewise. Mask with 0xff rather than casting to char.
+ * mach-o.c (bfd_mach_o_read_header): Update get32 prototype.
+ * pdp11.c (bfd_getp32): Make static, replace bfd_byte* with void*.
+ (bfd_getp_signed_32, bfd_putp32): Likewise.
+ * targets.c (struct bfd_target): Use void* in place of bfd_byte* for
+ bfd_getx64, bfd_getx_signed_64, bfd_putx64, bfd_getx32,
+ bfd_getx_signed_32, bfd_putx32, bfd_getx16, bfd_getx_signed_16,
+ bfd_putx16, bfd_h_getx64, bfd_h_getx_signed_64, bfd_h_putx64,
+ bfd_h_getx32, bfd_h_getx_signed_32, bfd_h_putx32, bfd_h_getx16,
+ bfd_h_getx_signed_16, bfd_h_putx16.
+ * aix386-core.c (NO_GET, NO_GETS, NO_PUT): Update prototypes.
+ * hppabsd-core.c: Similarly. Rename NO_SIGNED_GET to NO_GETS.
+ * hpux-core.c: Likewise.
+ * irix-core.c: Likewise.
+ * netbsd-core.c: Likewise.
+ * osf-core.c: Likewise.
+ * ptrace-core.c: Likewise.
+ * sco5-core.c: Likewise.
+ * trad-core.c: Likewise.
+ * bfd-in2.h: Regenerate.
+
+2004-03-15 Matt Thomas <matt@3am-software.com>
+
+ * config.bfd: Add x86-64 vector to NetBSD/i386 if 64bit BFD is
+ selected.
+
+2004-03-13 Mark Kettenis <kettenis@gnu.org>
+
+ * config.bfd: Add x86_64-*-openbsd*.
+ * configure.in (x86_64-*-openbsd*): Set COREFILE to
+ netbsd-core.lo.
+ * configure: Regenerate.
+
+2004-03-12 Nick Clifton <nickc@redhat.com>
+ Dave Murphy <wintermute2k4@ntlworld.com>
+
+ * elf32-arm.h (elf32_arm_merge_private_bfd_data): Skip most checks
+ if the input bfd does not contain any code.
+
+2004-03-09 Steve Ellcey <sje@cup.hp.com>
+
+ * elfxx-ia64.c (plt_full_entry): Change ld8 to ld8.acq.
+
+2004-03-05 Fred Fish <fnf@redhat.com>
+
+ * elfxx-mips.c (_bfd_mips_elf_finish_dynamic_symbol): Just force
+ mips16 symbols to be even rather than testing first for even/odd.
+ (_bfd_mips_elf_link_output_symbol_hook): Ditto.
+
+2004-03-05 Nathan Sidwell <nathan@codesourcery.com>
+
+ * elf.c (map_sections_to_segments): Ignore .tbss sections for
+ layout purposes.
+
+2004-03-03 Alexandre Oliva <aoliva@redhat.com>
+
+ * elflink.c (bfd_elf_record_link_assignment): Mark undefweak and
+ undefined symbols as hash_new.
+
+2003-03-03 Andrew Stubbs <andrew.stubbs@superh.com>
+
+ * archures.c: Add bfd_mach_sh4_nommu_nofpu.
+ * cpu-sh.c: Ditto.
+ * elf32-sh.c: Ditto.
+ * bfd-in2.h: Regenerate.
+
+2004-03-02 Alexandre Oliva <aoliva@redhat.com>
+
+ * elf32-frv.c (struct frv_pic_relocs_info): Added fixups and
+ dynrelocs.
+ (_frv_count_got_plt_entries): Initialize them.
+ (frv_pic_relocs_info_find): Add insert argument. Adjust all
+ callers.
+ (frv_pic_relocs_info_for_global): Likewise.
+ (frv_pic_relocs_info_for_local): Likewise.
+ (frv_pic_merge_early_relocs_info): New.
+ (_frv_resolve_final_relocs_info): Use it in case one entry maps to
+ another.
+ (_frv_add_dyn_reloc): Add entry argument. Adjust all callers.
+ Check that we don't exceed the allocated count for entry.
+ (_frv_add_rofixup): Likewise.
+ (_frv_emit_got_relocs_plt_entries): Adjust for coding standards.
+ (elf32_frv_finish_dynamic_sections): Improve error message in case
+ we emit too few rofixup entries.
+
+2004-03-01 Richard Sandiford <rsandifo@redhat.com>
+
+ * archures.c (bfd_mach_fr450): New.
+ * bfd-in2.h: Regenerate.
+ * cpu-frv.c (arch_info_450): New bfd_arch_info_type.
+ (arch_info_500): Link to it.
+ * elf32-frv.c (elf32_frv_machine, frv_elf_merge_private_bfd_data)
+ (frv_elf_print_private_bfd_data): Handle fr405 and fr450 header flags.
+ (frv_elf_arch_extension_p): New function.
+ (frv_elf_merge_private_bfd_data): Use it.
+
+2004-02-28 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf-bfd.h (_bfd_elf_link_add_archive_symbols): New prototype.
+
+ * elflink.h (is_global_data_symbol_definition): Moved to
+ elflink.c.
+ (elf_link_is_defined_archive_symbol): Likewise.
+ (elf_link_add_archive_symbols): Likewise. Renamed to
+ _bfd_elf_link_add_archive_symbols.
+
+ * elflink.c (elf_link_is_defined_archive_symbol): Get the size
+ of ELF symbol table entry from backend.
+ (_bfd_elf_link_add_archive_symbols): Call bfd_link_add_symbols
+ instead of elf_link_add_object_symbols.
+
+2004-02-27 Alexandre Oliva <aoliva@redhat.com>
+
+ * elf-bfd.h (struct elf_backend_data): Added
+ elf_backend_can_make_relative_eh_frame,
+ elf_backend_can_make_lsda_relative_eh_frame and
+ elf_backend_encode_eh_address.
+ (_bfd_elf_encode_eh_address): Declare.
+ (_bfd_elf_can_make_relative): Declare.
+ * elf-eh-frame.c (_bfd_elf_discard_section_eh_frame): Use new
+ hooks to decide whether to attempt to make_relative and
+ make_lsda_relative.
+ (_bfd_elf_write_section_eh_frame_hdr): Call encode_eh_address.
+ (_bfd_elf_can_make_relative): New.
+ (_bfd_elf_encode_eh_address): New.
+ * elf32-frv.c (frv_elf_use_relative_eh_frame): New.
+ (frv_elf_encode_eh_address): New.
+ (elf_backend_can_make_relative_eh_frame): Define.
+ (elf_backend_can_make_lsda_relative_eh_frame): Define.
+ (elf_backend_encode_eh_address): Define.
+ * elfxx-target.h
+ (elf_backend_can_make_relative_eh_frame): Define.
+ (elf_backend_can_make_lsda_relative_eh_frame): Define.
+ (elf_backend_encode_eh_address): Define.
+ (elfNN_bed): Add them.
+
+2004-02-27 Alexandre Oliva <aoliva@redhat.com>
+
+ * elf32-frv.c (elf32_frv_howto_table) <R_FRV_LABEL16>: Set
+ complain_on_overflow to signed.
+
+2004-02-27 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elflink.h (sort_symbol): New.
+ (elf_link_add_object_symbols): Use a sorted symbol array for
+ weakdef.
+
+2004-02-27 Jakub Jelinek <jakub@redhat.com>
+
+ * elf32-s390.c (allocate_dynrelocs): Use SYMBOL_REFERENCES_LOCAL
+ for pc relative relocs.
+ (elf_s390_relocate_section): Likewise.
+ * elf64-s390.c (allocate_dynrelocs): Use SYMBOL_REFERENCES_LOCAL
+ for pc relative relocs.
+ (elf_s390_relocate_section): Likewise.
+
+2004-02-26 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elfxx-ia64.c (elfNN_ia64_check_relocs): Fix call to
+ count_dyn_reloc.
+
+2004-02-25 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elfxx-ia64.c (elfNN_ia64_dyn_reloc_entry): Add the reltext.
+ field to track if a relocation is against readonly section.
+ (count_dyn_reloc): Take a new argument for rent->reltext.
+ (elfNN_ia64_check_relocs): Adjust call to count_dyn_reloc.
+ (get_reloc_section): Don't set ia64_info->reltext here.
+ (allocate_dynrel_entries): Set ia64_info->reltext here.
+
+2004-02-24 Alexandre Oliva <aoliva@redhat.com>
+
+ * elf32-frv.c (FRV_SYM_LOCAL): Weak undefined doesn't imply local.
+ (_frv_emit_got_relocs_plt_entries): Decay relocation to protected
+ function's descriptor to symbol+offset, and map local undefweak
+ symbol to NULL function descriptor.
+ (elf32_frv_relocate_section): Likewise.
+
+2004-02-23 Mark Kettenis <kettenis@gnu.org>
+
+ * libaout.h (enum machine_type): Add M_SPARC64_NETBSD and
+ M_X86_64_NETBSD.
+ * netbsd-core.c (M_SPARC64_OPENBSD): Define.
+ (netbsd_core_file_p): Set architecture from machine ID for
+ selected machines.
+
+2004-02-23 Jakub Jelinek <jakub@redhat.com>
+
+ * elflink.h (size_dynamic_sections): If not adding DT_FLAGS and
+ DF_BIND_NOW is set in info->flags, create DT_BIND_NOW dynamic entry.
+
+2004-02-21 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elflink.c (_bfd_elf_merge_symbol): Properly handle undefined
+ symbols with non-default visibility.
+
+2004-02-21 Danny Smith <daanysmith@users.sourceforge.net>
+
+ * peXXigen.c (_bfd_XXi_swap_scnhdr_out): Clear
+ IMAGE_SCN_MEM_WRITE on known sections only.
+
+2004-02-20 Jakub Jelinek <jakub@redhat.com>
+
+ * elf32-ppc.c (allocate_dynrelocs): Create dynsym for undef weak
+ symbols used in PIE relocs.
+
+2004-02-19 Jakub Jelinek <jakub@redhat.com>
+
+ * elf32-sparc.c (elf32_sparc_finish_dynamic_sections): Clear
+ .plt sh_entsize.
+
+2004-02-18 Daniel Jacobowitz <drow@mvista.com>
+
+ * configure.in: Update version to 2.15.90.
+ * configure: Regenerate.
+
+2004-02-17 Daniel Jacobowitz <drow@mvista.com>
+ Richard Sandiford <rsandifo@redhat.com>
+
+ * elfxx-mips.c (mips_elf_calculate_relocation): Use
+ _bfd_elf_symbol_refs_local_p to decide whether to decay
+ a GOT_PAGE/GOT_OFST pair to GOT_DISP/addend.
+ (_bfd_mips_elf_check_relocs): Add a global GOT entry for GOT_PAGE
+ relocs if the symbol wasn't defined by a regular object file.
+ Don't check the symbol's dynindx.
+
+2004-02-16 Andrew Cagney <cagney@redhat.com>
+
+ * bfd-in.h (file_ptr, ufile_ptr): Configure type using
+ @bfd_file_ptr@.
+ * bfd-in2.h: Re-generate.
+
+2004-02-14 Andrew Cagney <cagney@redhat.com>
+
+ * configure.host (HDEFINES): When hppa*-*-hpux*, define
+ _LARGEFILE64_SOURCE.
+
+2004-02-13 Andrew Cagney <cagney@redhat.com>
+
+ * elf.c (vma_page_aligned_bias): New function.
+ (assign_file_positions_except_relocs)
+ (assign_file_positions_for_segments): Replace broken modulo
+ arithmetic with call to vma_page_aligned_bias.
+
+2004-02-11 Andrew Cagney <cagney@redhat.com>
+
+ * bfd-in.h: Update copyright.
+ (bfd_tell): Change return type to file_ptr.
+ * bfd-in2.h: Re-generate.
+ * cache.c: Update copyright.
+ (bfd_cache_lookup_worker): Use real_fseek, do not cast offset
+ parameter.
+ (close_one): Use real_ftell.
+ * bfdio.c: Update copyright.
+ (real_ftell, real_fseek): New functions.
+ (bfd_tell): Use real_fseek and real_ftell, change return type to
+ file_ptr.
+ (bfd_seek): Use real_ftell and real_fseek, change type of
+ file_position to a file_ptr.
+ * libbfd-in.h: Update copyright.
+ (real_ftell, real_fseek): Declare.
+ * libbfd.h: Re-generate.
+
+ * configure.in (AC_CHECK_FUNCS): Check for ftello, ftello64,
+ fseeko and fseeko64. Determine bfd_file_ptr.
+ * configure: Re-generate.
+ * config.in: Re-generate.
+
+2004-02-09 Anil Paranjpe <anilp1@KPITCummins.com>
+
+ * coff-h8300.c: Added comments about relaxation for ldc.w and stc.w.
+ * elf32-h8300.c: Likewise.
+
+2004-02-09 Christian Vogel <vogelchr@vogel.cx>
+ Nick Clifton <nickc@redhat.com>
+
+ * elf64-alpha.c (elf64_alpha_calc_got_offsets_for_symbol): Catch
+ GOT entries with no associated GOT subsection.
+
+2004-02-09 Richard Sandiford <rsandifo@redhat.com>
+
+ * bfd-elf.h (elf_backend_name_local_section_symbols): New hook.
+ * elf.c (swap_out_syms): Use it to decide whether local section
+ symbols should be named.
+ * elfxx-target.h (elf_backend_name_local_section_symbols): New macro.
+ * elfxx-mips.h (_bfd_mips_elf_name_local_section_symbols): Declare.
+ (elf_backend_name_local_section_symbols): Define.
+ * elfxx-mips.c (_bfd_mips_elf_name_local_section_symbols): New.
+
+2004-01-30 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elfxx-ia64.c (elfNN_ia64_relax_brl): New function.
+ (elfNN_ia64_relax_section): Optimize brl to br during the relax
+ finalize pass.
+
+2004-01-30 Alexandre Oliva <aoliva@redhat.com>
+
+ * elf32-frv.c (elf32_frv_always_size_sections): Initialize pointer
+ to bfd_link_hash_entry passed by reference to
+ _bfd_generic_link_add_one_symbol.
+
+2004-01-25 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elfxx-ia64.c (elfNN_ia64_relocate_section): Disallow imm
+ relocations against dynamic symbols.
+
+2004-01-23 Daniel Jacobowitz <drow@mvista.com>
+
+ * elf32-arm.h (elf32_arm_check_relocs): Revert part of 2004-01-13
+ change.
+
+2004-01-21 Tom Rix <tcrix@worldnet.att.net>
+
+ * reloc.c: New 5 bit reloc, BFD_RELOC_M68HC12_5B, for m68hc12 movb/movw.
+ * bfd-in2.h, libbfd.h: Rebuilt.
+
+2004-01-20 Danny Smith <dannysmith@users.sourceforge.net>
+
+ * peXXigen.c (_bfd_XXi_swap_scnhdr_out): Don't remove
+ IMAGE_SCN_MEM_WRITE flag from .text section if WP_TEXT
+ flag has been cleared.
+
+2004-01-19 Kazu Hirata <kazu@cs.umass.edu>
+
+ * coff-h8300.c: Add and adjust comments about relaxation.
+ * elf32-h8300.c: Likewise.
+
+2004-01-16 Kazu Hirata <kazu@cs.umass.edu>
+
+ * coff-h8300.c: Fix comment typos.
+ * elf32-h8300.c: Likewise.
+
+2004-01-16 Kazu Hirata <kazu@cs.umass.edu>
+
+ * coff-h8300.c: Add comments about relaxation.
+ * elf32-h8300.c: Likewise.
+
+2004-01-14 Maciej W. Rozycki <macro@ds2.pg.gda.pl>
+
+ * acinclude.m4: Quote names of macros to be defined by AC_DEFUN
+ throughout.
+ * aclocal.m4: Regenerate.
+ * configure: Regenerate.
+
+2004-01-13 Ian Lance Taylor <ian@wasabisystems.com>
+
+ * elf64-mips.c (mips_elf64_slurp_one_reloc_table): Call
+ mips_elf64_rtype_to_howto instead of using howto_table.
+
+2004-01-13 Daniel Jacobowitz <drow@mvista.com>
+
+ * elf32-arm.h (elf32_arm_final_link_relocate): Check that we created
+ the .plt section.
+ (elf32_arm_check_relocs): Don't increment the PLT refcount for
+ relocs which would not use the PLT.
+
+2004-01-13 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (ppc64_elf_check_relocs): Ignore !SEC_ALLOC relocs.
+ (ppc64_elf_gc_sweep_hook): Likewise.
+ (ppc64_elf_size_dynamic_sections): Test for .plt directly.
+
+2004-01-12 Anil Paranjpe <anilp1@KPITCummins.com>
+
+ Adds linker relaxation support for bit manipulation insns like
+ band, bclr, biand, bild, bior, bist, bixor, bld, bnot, bor, bset,
+ bst, btst, bxor.
+ * elf32-h8300.c: Opcode for bit manipulation insn is checked in
+ elf32_h8_relax_section function while relxation for aa:16 and aa:32.
+ * coff-h8300.c: Opcode for bit manipulation insn is checked in
+ h8300_reloc16_extra_cases function while relxation for aa:16 and aa:32.
+
+2004-01-12 Alan Modra <amodra@bigpond.net.au>
+
+ * dwarf2.c: Convert to C90, remove unneeded casts and prototypes.
+
+2004-01-11 Kazu Hirata <kazu@cs.umass.edu>
+
+ * elf32-h8300.c: Fix formatting.
+
+2004-01-11 Kazu Hirata <kazu@cs.umass.edu>
+
+ * elf32-cris.c (cris_elf_gc_sweep_hook): Return early if no
+ dynamic object is present. Declare r_symndx and h in an inner
+ scope.
+ * elf32-vax.c (elf_vax_gc_sweep_hook): Likewise.
+
+2004-01-09 Daniel Jacobowitz <drow@mvista.com>
+
+ * elf32-arm.h (struct elf32_arm_relocs_copied): Remove pc_count.
+ (elf32_arm_copy_indirect_symbol): Don't copy pc_count.
+ (elf32_arm_final_link_relocate): Handle PLT32 and PC24 relocs
+ identically. Do not emit PC24 relocations for shared libraries.
+ (elf32_arm_gc_sweep_hook): Handle PLT32 and PC24 relocs
+ identically. Don't adjust pc_count.
+ (elf32_arm_check_relocs): Handle PLT32 and PC24 relocs identically.
+ Set ELF_LINK_HASH_NEEDS_PLT for both. Don't adjust pc_count; don't
+ adjust count for branch relocations.
+ (allocate_dynrelocs): Correct typo in call to
+ WILL_CALL_FINISH_DYNAMIC_SYMBOL. Never allocate space for
+ PC24 or PLT32 relocs when linking.
+
+2004-01-09 Dmitry Semyonov <Dmitry.Semyonov@oktet.ru>
+
+ * coff-arm.c (aoutarm_std_reloc_howto): [ARM_WINCE] Synchronize ARM_26D
+ relocation howto with ARM_26 one for consistency.
+ (coff_arm_relocate_section): Set partial_inplace for ARM_26 relocations
+ that will be converted to ARM_26D ones, since we always want 'done'
+ relocations to be reflected in section's data.
+ (coff_arm_relocate_section): [ARM_WINCE] Quick fix for BL instruction
+ offset.
+ (_bfd_final_link_relocate): Do not modify "inplace" data, if not
+ requested.
+
+2004-01-08 Dmitry Semyonov <Dmitry.Semyonov@oktet.ru>
+
+ * coff-arm.c (coff_arm_relocate_section): Do not alter relocs that
+ are not partial_inplace during a relocatable link.
+
+2004-01-08 Kazu Hirata <kazu@cs.umass.edu>
+
+ * elf32-m68k.c (elf_m68k_gc_sweep_hook): Return early
+ if no dynamic object is present. Declare r_symndx and h in an
+ inner scope.
+
+2004-01-07 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elfxx-ia64.c (elfNN_ia64_relax_section): Don't install
+ trampoline if it is known out of range.
+
+2004-01-06 Alexandre Oliva <aoliva@redhat.com>
+
+ 2003-12-17 Alexandre Oliva <aoliva@redhat.com>
+ * elf32-frv.c (_frv_osec_readonly_p): New.
+ (_frv_emit_got_relocs_plt_entries): Don't emit rofixup for
+ undefweak symbol.
+ (_frv_count_got_plt_entries): Adjust expected count accordingly.
+ (elf32_frv_relocate_section): Likewise. Error out if attempting
+ to emit rofixups or dynamic relocs in read-only segments. Use
+ _bfd_elf_section_offset to adjust r_offsets in rofixups and
+ dynamic relocations.
+ 2003-12-12 Alexandre Oliva <aoliva@redhat.com>
+ * elf32-frv.c (elf32_frv_relocate_section): Compute dynamic
+ relocations or fixups involving merged sections correctly. Avoid
+ crash when undefined symbol is referenced by R_FRV_32 or
+ R_FRV_FUNCDESC_VALUE.
+ 2003-12-02 Alexandre Oliva <aoliva@redhat.com>
+ * elf32-frv.c (elf32_frv_relocate_section): Add output_offset of
+ input section holding local symbol to addend of R_FRV_32 or
+ R_FRV_FUNCDESC_VALUE dynamic relocation.
+ 2003-11-27 Alexandre Oliva <aoliva@redhat.com>
+ * elf32-frv.c (elf32_frv_modify_segment_map): Add link info arg.
+ (elf32_frv_always_size_sections): Don't store pointer to
+ __stacksize symbol in sec_info.
+ (elf32_frv_modify_segment_map): Look it up here.
+ 2003-11-26 Alexandre Oliva <aoliva@redhat.com>
+ * elf32-frv.c (_frv_emit_got_relocs_plt_entries): Emit the address
+ of the lazy PLT entry, not only its offset, as the low word of a
+ function descriptor.
+ 2003-11-10 Alexandre Oliva <aoliva@redhat.com>
+ * elf32-frv.c (elf32_frv_always_size_sections): Define __stacksize
+ if a hash table entry already exists but is not a definition.
+ 2003-11-05 Alexandre Oliva <aoliva@redhat.com>
+ * elf32-frv.c (frv_elf_link_hash_table_create): Use bfd_zalloc.
+ (_frv_add_rofixup): Don't inline.
+ (_frv_emit_got_relocs_plt_entries): Use NULL as funcdesc address
+ for undefweak symbols.
+ (elf32_frv_relocate_section): Avoid crash while computing
+ relocation when linking with shared library. Only emit rofixups
+ and dynamic relocations for alloc&load sections. Mark binaries
+ with inter-segment relocations for relocation as a unit.
+ (_frv_create_got_section): Rename .rofixup.got to .rofixup.
+ (DEFAULT_STACK_SIZE): New.
+ (_frv_count_got_plt_entries): Fix thinko in deciding whether to
+ emit rofixups or dynamic relocs when linking dynamic non-PIE
+ executables.
+ (elf32_frv_size_dynamic_sections): Generate rofixup on PIEs and
+ shared libs too. Reserve the last entry for the GOT pointer.
+ (elf32_frv_finish_dynamic_sections): Emit it.
+ (elf32_frv_always_size_sections): New.
+ (elf32_frv_modify_segment_map): New.
+ (elf32_frv_check_relocs): Reserve relocs32 space only in ALLOC
+ sections.
+ (frv_elf_merge_private_bfd_data): Clear PIC bit if FDPIC is set.
+ (frv_elf_print_private_bfd_data): Handle FDPIC and LIBPIC.
+ (elf_backend_always_size_sections): New.
+ (elf_backend_modify_segment_map): New.
+ 2003-10-31 Alexandre Oliva <aoliva@redhat.com>
+ * config.bfd: Added frv-*-*linux*.
+ * elf32-frv.c (_frv_emit_got_relocs_plt_entries): Use idx 0 for
+ ABS section, instead of crashing.
+ (elf32_frv_relocate_section): Don't crash before warning about
+ different segments in non-PIC relocation.
+ 2003-10-17 Alexandre Oliva <aoliva@redhat.com>
+ * elf32-frv.c (elf32_frv_relocate_section): Don't warn on LABEL24
+ relocs to undefweak symbols.
+ (elf32_frv_relocate_section): Ditto for undefined symbols.
+ 2003-10-06 Alexandre Oliva <aoliva@redhat.com>
+ * elf32-frv.c (elf32_frv_create_dynamic_sections): Make sure
+ gotfixup section was created.
+ 2003-09-30 Alexandre Oliva <aoliva@redhat.com>
+ * elf32-frv.c (elf32_frv_howto_table): Change GOT12,
+ FUNCDESC_GOT12, GOTOFF12 and FUNCDESC_GOTOFF12 to
+ complain_overflow_signed.
+ * elf32-frv.c (_frv_add_rofixup): Do not error out if contents
+ have not been allocated.
+ (_frv_emit_got_relocs_plt_entries): Return non-void. Assert
+ privfd only if dynamic sections were created.
+ (elf32_frv_relocate_section): Compute gprel_segment, and use it
+ for GPREL relocs. When linking relocatable FDPIC executables,
+ emit warnings for relocations that would be illegal on PIE or
+ shared libraries. Emit rofixup for R_FRV_32 only if input object
+ is not FDPIC.
+ (_frv_create_got_section): Define _gp symbol in the rofixup
+ section.
+ (elf32_frv_finish_dynamic_sections): If rofixups needed but
+ dynamic sections missing, error out requesting -melf32frvfd.
+ 2003-09-19 Alexandre Oliva <aoliva@redhat.com>
+ * elf32-frv.c (_frv_emit_got_relocs_plt_entries): Rearrange
+ computation of addends from section and global or local symbol
+ value. Change return type to bfd_boolean, and return a failure if
+ a dynamic FUNCDESC or FUNCDESC_VALUE relocation that requires a
+ nonzero addend is required.
+ (elf32_frv_relocate_section): Likewise. Print error for
+ unsupported nonzero addends.
+ 2003-09-18 Alexandre Oliva <aoliva@redhat.com>
+ * elf32-frv.c (FRV_SYM_LOCAL): In the absence of dynamic sections,
+ force everything local.
+ (_frv_emit_got_relocs_plt_entries): Cope with NULL sec.
+ * elf32-frv.c (struct frv_elf_link_hash_table): Added sgotfixup.
+ (frv_gotfixup_section): New.
+ (FRV_SYM_LOCAL): Accept undefweak and local common symbols.
+ (struct frv_pic_relocs_info): Split relocs into relocs32, relocsfd
+ and relocsfdv.
+ (_frv_add_rofixup): New.
+ (_frv_emit_got_relocs_plt_entries): Generate fixups for non-PIE
+ fdpic executables. Use FRV_SYM_LOCAL more widely to simplify and
+ improve some ugly conditions.
+ (elf32_frv_relocate_section): Likewise. Reject inter-segment
+ relocations in fdpic.
+ (_frv_create_got_section): Create .rofixup.got section.
+ (struct _frv_dynamic_got_info): Added fixups.
+ (_frv_count_got_plt_entries): Account in-GOT relocations into
+ relocs32, relocsfd and relocsfdv. Account them into relocs or
+ fixups, as appropriate.
+ (elf32_frv_size_dynamic_sections): Size rofixup section. Simplify
+ sizing of gotrel.
+ (elf32_frv_finish_dynamic_sections): Verify that the right number
+ of relocations and fixups was generated.
+ (elf32_frv_check_relocs): Compute relocs32, relocsfd and
+ relocsfdv.
+ * elf32-frv.c (FRV_SYM_LOCAL): New macro, used instead of
+ SYMBOL_CALLS_LOCAL and SYMBOL_REFERENCES_LOCAL.
+ (FRV_FUNCDESC_LOCAL): New macro, used to decide whether a function
+ descriptor of a (formerly-)global symbol is local.
+ (struct frv_pic_relocs_info): Adjust comments.
+ (_frv_emit_got_relocs_plt_entries): Adjust.
+ (elf32_frv_relocate_section): Likewise.
+ (_frv_count_got_plt_entries): Likewise.
+ * elf32-frv.c (_frv_emit_got_relocs_plt_entries): Don't add global
+ symbol's value to addend in the common preamble. Decay dynamic
+ symbols to section+offset if they bind or call locally, for GOT
+ and FUNCDESC_VALUE, respectively.
+ (elf32_frv_relocate_section): Likewise.
+ (elf32_frv_check_relocs): Don't register as dynamic symbols of
+ internal or hidden visibility.
+ 2003-09-17 Alexandre Oliva <aoliva@redhat.com>
+ * elf32-frv.c (_frv_emit_got_relocs_plt_entries): Get addend as
+ argument, so as to not call _bfd_elf_rel_local_sym to compute it.
+ (elf32_frv_relocate_section): Pass relocation addend in. Use
+ original relocation addend to look up the got relocs/plt entries
+ table. Do not call _bfd_elf_rel_local_sym. Don't error out when
+ processing relocations that reference .scommon symbols.
+ 2003-09-15 Alexandre Oliva <aoliva@redhat.com>
+ Introduce support for dynamic linking.
+ * elf32-frv.c (R_FRV_FUNCDESC_VALUE): Mark it as 64 bits.
+ (elf32_frv_rel_32_howto, elf32_frv_rel_funcdesc_howto,
+ elf32_frv_rel_funcdesc_value_howto): New REL descriptors.
+ (frv_reloc_type_lookup): Return REL howtos for executables and
+ dynamic libraries.
+ (frv_info_to_howto_rel): New.
+ (struct frv_elf_link_hash_table): New.
+ (frv_hash_table, frv_got_section, frv_gotrel_section,
+ frv_plt_section, frv_pltrel_section, frv_relocs_info,
+ frv_got_initial_offset, frv_plt_initial_offset): New macros.
+ (frv_elf_link_hash_table_create): New.
+ (struct frv_pic_relocs_info): New.
+ (frv_pic_relocs_info_hash, frv_pic_relocs_info_eq): New.
+ (frv_pic_relocs_info_find): New.
+ (frv_pic_relocs_info_for_global, frv_pic_relocs_info_for_local):
+ New.
+ (FRV_LZPLT_BLOCK_SIZE, FRV_LZPLT_RESOLVE_LOC): New.
+ (_frv_add_dyn_reloc, _frv_osec_to_segment): New.
+ (_frv_emit_got_relocs_plt_entries): New.
+ (elf32_frv_relocate_section): Add support for dynamic linking.
+ Handle new relocations.
+ (_frv_create_got_section): New.
+ (elf32_frv_create_dynamic_sections): New.
+ (ELF_DYNAMIC_INTERPRETER): New.
+ (struct _frv_dynamic_got_info): New.
+ (_frv_count_got_plt_entries): New.
+ (struct _frv_dynamic_got_plt_info): New.
+ (_frv_compute_got_alloc_data): New.
+ (_frv_get_got_entry, _frv_get_fd_entry): New.
+ (_frv_assign_got_entries, _frv_assign_plt_entries): New.
+ (_frv_resolve_final_relocs_info): New.
+ (elf32_frv_size_dynamic_sections): New.
+ (elf32_frv_finish_dynamic_sections): New.
+ (elf32_frv_adjust_dynamic_symbol): New.
+ (elf32_frv_finish_dynamic_symbol): New.
+ (elf32_frv_check_relocs): Handle new relocs. Explain how the
+ whole thing works.
+ (elf_info_to_howto_rel): Define.
+ (bfd_elf32_bfd_link_hash_table_create): Define.
+ (elf_backend_create_dynamic_sections): Define.
+ (elf_backend_adjust_dynamic_symbol): Define.
+ (elf_backend_size_dynamic_sections): Define.
+ (elf_backend_finish_dynamic_symbol): Define.
+ (elf_backend_finish_dynamic_sections): Define.
+ (elf_backend_want_got_sym): Define.
+ (elf_backend_got_header_size): Define.
+ (elf_backend_want_got_plt): Define.
+ (elf_backend_plt_readonly): Define.
+ (elf_backend_want_plt_sym): Define.
+ (elf_backend_plt_header_size): Define.
+ (elf_backend_may_use_rel_p): Define.
+ (elf_backend_may_use_rela_p): Define.
+ (elf_backend_default_use_rela_p): Define.
+ 2003-08-08 Alexandre Oliva <aoliva@redhat.com>
+ * elf32-frv.c (R_FRV_FUNCDESC_VALUE, R_FRV_FUNCDESC_GOTOFF12,
+ R_FRV_FUNCDESC_GOTOFFHI, R_FRV_FUNCDESC_GOTOFFLO, R_FRV_GOTOFF12,
+ R_FRV_GOTOFFHI, R_FRV_GOTOFFLO): New.
+ (frv_reloc_map): Map the corresponding BFD relocs to them.
+ (frv_reloc_type_lookup): ... and back to BFD relocs.
+ * reloc.c: New relocs.
+ * bfd-in2.h, libbfd.h: Rebuilt.
+ 2003-08-04 Alexandre Oliva <aoliva@redhat.com>
+ * elf32-frv.c (R_FRV_GOT12, R_FRV_GOTHI, R_FRV_GOTLO,
+ R_FRV_FUNCDESC, R_FRV_FUNCDESC_GOT12, R_FRV_FUNCDESC_GOTHI,
+ R_FRV_FUNCDESC_GOTLO): New.
+ (frv_reloc_map): Map the corresponding BFD relocs to them.
+ (frv_reloc_type_lookup): ... and back to BFD relocs.
+ * reloc.c: New relocs.
+ * bfd-in2.h, libbfd.h: Rebuilt.
+
+2004-01-05 Maciej W. Rozycki <macro@ds2.pg.gda.pl>
+
+ * elf32-mips.c (ELF_MAXPAGESIZE): Redefine for traditional
+ targets to support pages of up to 64kB.
+ (elf32_bed): Redefine to get a separate backend data structure for
+ traditional targets.
+ * elf64-mips.c (ELF_MAXPAGESIZE): Redefine for traditional
+ targets to support pages of up to 64kB.
+ (elf64_bed): Redefine to get a separate backend data structure for
+ traditional targets.
+ * elfn32-mips.c (ELF_MAXPAGESIZE): Redefine for traditional
+ targets to support pages of up to 64kB.
+ (elf32_bed): Redefine to get a separate backend data structure for
+ traditional targets.
+
+2004-01-04 Mark Kettenis <kettenis@gnu.org>
+
+ * elf32-sparc.c (elf32_sparc_grok_psinfo): New function.
+
+2004-01-02 Mark Kettenis <kettenis@gnu.org>
+
+ * elf32-i386.c (elf_i386_grok_prstatus): Add support for FreeBSD.
+ (elf_i386_grok_psinfo): Likewise.
+
+2004-01-02 Bernardo Innocenti <bernie@develer.com>
+
+ * config.bfd: Add m68k-uClinux target.
+
+2004-01-01 Grant Edwards <grante@visi.com>
+
+ * elflink.h (elf_gc_sections): Warn when gc-sections option is ignored.
+ * elf32-h8300.c (elf32_h8_gc_mark_hook): New function.
+ (elf32_h8_gc_sweep_hook): New function.
+ (elf_backend_gc_mark_hook): Define.
+ (elf_backend_gc_sweep_hook): Define.
+ (elf_backend_can_gc_sections): Define.
+
+For older changes see ChangeLog-0203
+
+Copyright (C) 2004 Free Software Foundation, Inc.
+
+Copying and distribution of this file, with or without modification,
+are permitted in any medium without royalty provided the copyright
+notice and this notice are preserved.
+
+Local Variables:
+mode: change-log
+left-margin: 8
+fill-column: 74
+version-control: never
+End:
diff --git a/bfd/ChangeLog-2005 b/bfd/ChangeLog-2005
new file mode 100644
index 0000000..7c9b0d3
--- /dev/null
+++ b/bfd/ChangeLog-2005
@@ -0,0 +1,5275 @@
+2005-12-31 Valeriy E. Ushakov <uwe@NetBSD.org>
+ Kaz Kojima <kkojima@rr.iij4u.or.jp>
+
+ * elf32-sh.c (sh_elf_relocate_section): Don't reset relocation
+ for R_SH_REL32 in shared objects if the symbol is locally called.
+
+2005-12-31 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (ppc64_elf_relocate_section): Adjust relocs against
+ opd section sym when opd has been edited. Use correct addend
+ when determining branch 'y' bit and branch overflow. Adjust and
+ save opd relocs for ld -r too.
+
+2005-12-30 Eric Christopher <echristo@apple.com>
+
+ * elfxx-mips.c (mips_elf_record_global_got_symbol): Add assert
+ to verify we have a got.
+ (_bfd_mips_elf_check_relocs): Add R_MIPS_TLS_GOTTPREL to relocs
+ needing a GOT.
+
+2005-12-30 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ * configure.host (hppa*64*-*-hpux*): Set host64 to true.
+
+2005-12-29 Nick Clifton <nickc@redhat.com>
+
+ * hash.c (bfd_hash_set_default_size): Add more entries to the
+ hash_size_primes table.
+
+ * stabs.c (_bfd_link_section_stabs): Use bfd_hash_table_init
+ rather than bfd_hash_table_init_n(...,251) so that the size of the
+ hash table can be controlled by the user.
+
+2005-12-27 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ * elf32-hppa.c (elf32_hppa_size_dynamic_sections): Use info->executable
+ instead of !info->shared.
+
+2005-12-27 Jan-Benedict Glaw <jbglaw@lug-owl.de>
+
+ * vaxlinux.h: New file. (TRAD_CORE_EXTRA_SIZE_ALLOWED): Define.
+ (HOST_MACHINE_ARCH): Define. This allows cross-building vax-linux
+ hosted binutils.
+
+2005-12-27 Nathan Sidwell <nathan@codesourcery.com>
+
+ * elf32-mt.c (mt_elf_merge_private_bfd_data): Do not allow mixing
+ object files from different mt variants.
+
+2005-12-27 Leif Ekblad <leif@rdos.net>
+
+ * config.bfd: Add support for RDOS targets.
+
+2005-12-27 Marty Leisner <leisner@rochester.rr.com>
+
+ * dwarf2.c (lookup_symbol_in_function_table): Check for a function
+ name before passing it to strcmp.
+
+2005-12-27 Alan Modra <amodra@bigpond.net.au>
+
+ * elf.c (elf_find_function): Don't ignore section syms.
+ Simplify filename logic.
+
+2005-12-27 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-ppc.c (add_stub_sym): Pass info rather than htab.
+ Use different names for pic vs non-pic, '.' instead of '_'.
+ (allocate_dynrelocs): Adjust add_stub_sym call.
+
+2005-12-27 Alan Modra <amodra@bigpond.net.au>
+
+ * elf.c (bfd_section_from_shdr): Treat invalid reloc sections as
+ normal sections rather than returning false.
+
+2005-12-27 Alan Modra <amodra@bigpond.net.au>
+
+ * coff-h8300.c (h8300_reloc16_extra_cases): Use input section
+ "output_offset" instead of link order "offset".
+ * coff-h8500.c (extra_case): Likewise.
+ * coff-w65.c (w65_reloc16_extra_cases): Likewise.
+ * coff-z80.c (extra_case): Likewise.
+ * coff-z8k.c (extra_case): Likewise.
+ * linker.c (default_indirect_link_order): Likewise, "size" too.
+ * ecoff.c (ecoff_indirect_link_order): Likewise.
+
+2005-12-27 Alan Modra <amodra@bigpond.net.au>
+
+ * Makefile.am: Run "make dep-am".
+ * Makefile.in: Regenerate.
+ * po/SRC-POTFILES.in: Regenerate.
+
+2005-12-24 Alan Modra <amodra@bigpond.net.au>
+
+ * aix5ppc-core.c: Remove duplicate prototypes.
+ (xcoff64_core_file_matches_executable_p): Provide implementation
+ for !AIX_5_CORE.
+ * corefile.c (generic_core_file_matches_executable_p): Correct
+ syntax error in prototype.
+ * libbfd-in.h (generic_core_file_matches_executable_p): Delete.
+ * libbfd.h: Regenerate.
+ * bfd-in2.h: Regenerate.
+
+2005-12-23 Michael Weiser <michael@weiser.dinsnail.net>
+
+ PR 1150
+ * elf-bfd.h (struct elf_backend_data): New field
+ 'elf_backend_ignore_undef_symbol'.
+ * elfxx-target.h (elf_backend_ignore_undef_symbol): Define to NULL
+ if not already defined.
+ (elfNN_bed): Initialise the elf_backend_ignore_undef_symbol field.
+ * elfxx-mips.c (_bfd_mips_elf_ignore_undef_symbol): New function.
+ * elfxx-mips.h (elf_backend_ignore_undef_symbol): Define and
+ prototype.
+ * elflink.c (elf_link_output_extsym): Check
+ elf_backend_ignore_undef_symbol before reporting an undefined
+ symbol in a shared library.
+
+2005-12-23 Joel Brobecker <brobecker@adacore.com>
+
+ * corefile.c (generic_core_file_matches_executable_p): New function.
+ * libbfd-in.h (generic_core_file_matches_executable_p): Add
+ declaration.
+ * libbfd.h: Regenerate.
+ * hpux-core.c: ANSIfy function declarations and prototypes.
+ (thread_section_p): Manually expand bfd_section_name macro
+ to make it clear that parameter ABFD is not used.
+ (hpux_core_core_file_matches_executable_p): Delete, replaced
+ by macro pointing to generic_core_file_matches_executable_p.
+
+ * aix386-core.c: Replace core_file_matches_executable_p null
+ implementation by generic_core_file_matches_executable_p by
+ using a macro.
+ * aix5ppc-core.c: Likewise.
+ * cisco-core.c: Likewise.
+ * hppabsd-core.c: Likewise.
+ * irix-core.c: Likewise.
+ * lynx-core.c: Likewise.
+ * mach-o.c: Likewise.
+ * netbsd-core.c: Likewise.
+ * osf-core.c: Likewise.
+ * ptrace-core.c: Likewise.
+ * sco5-core.c: Likewise.
+ * trad-core.c: Likewise.
+
+2005-12-19 David Heine <dlheine@tensilica.com>
+
+ * elf32-xtensa.c (action_list_count, xlate_map_entry, xlate_map,
+ xlate_offset_with_removed_text, build_xlate_map, free_xlate_map): New.
+ (check_section_ebb_pcrels_fit): Build new xlate_map, use it and free it
+ when finished.
+
+2005-12-16 Nathan Sidwell <nathan@codesourcery.com>
+
+ Second part of ms1 to mt renaming.
+ * archures.c (bfd_arch_mt): Renamed.
+ (bfd_mt_arch): Renamed.
+ (bfd_archures_list): Adjusted.
+ * bfd-in2.h: Rebuilt.
+ * config.bfd (mt): Remove special case targ_archs.
+ (mt-*-elf): Rename bfd_elf32_mt_vec.
+ * configure: Rebuilt.
+ * configure.in (bfd_elf32_mt_vec): Renamed.
+ (selarchs) Remove mt special case.
+ * cpu-mt.c (arch_info_struct): Adjust.
+ (bfd_mt_arch): Renamed, adjust.
+ * elf32-mt.c (mt_reloc_type_lookup, mt_info_to_howto_rela,
+ mt_elf_relocate_hi16, mt_final_link_relocate, mt_relocate_section,
+ mt_elf_howto_table): Renamed, adjusted.
+ (mt_elf_gc_mark_hook, mt_elf_gc_sweep_hook, mt_elf_check_relocs,
+ elf32_mt_machine, mt_elf_object_p, mt_elf_set_private_flags,
+ mt_elf_copy_private_bfd_data, mt_elf_merge_private_bfd_data,
+ mt_elf_print_private_bfd_data): Renamed, adjusted.
+ (TARGET_BIG_SYM, TARGET_BIG_NAME, ELF_ARCH, ELF_MACHINE_CODE,
+ ELF_MAXPAGESIZE, elf_info_to_howto, elf_backend_relocate_section,
+ bfd_elf32_bfd_reloc_type_lookup, elf_backend_gc_mark_hook,
+ elf_backend_gc_sweep_hook, elf_backend_check_relocs,
+ eld_backend_object_p, bfd_elf32_bfd_set_private_flags,
+ bfd_elf32_bfd_copy_private_bfd_data,
+ bfd_elf32_bfd_merge_private_bfd_data,
+ bfd_elf32_bfd_print_private_bfd_data): Adjusted.
+ * libbfd.h: Regenerated.
+ * reloc.c (BFD_RELOC_MT_PC16, BFD_RELOC_MT_HI16,
+ BFD_RELOC_MT_LO16, BFD_RELOC_MT_GNU_VTINHERIT,
+ BFD_RELOC_MT_GNU_VTENTRY, BFD_RELOC_MT_PCINSN8): Renamed.
+ * targets.c (bfd_elf32_mt_vec): Renamed.
+ (_bfd_target_vector): Adjusted.
+
+2005-12-13 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/2008
+ * elf.c (_bfd_elf_setup_sections): Return FALSE if
+ elf_linked_to_section will be set to NULL.
+
+ * format.c (bfd_check_format_matches): Don't check the default
+ target twice.
+
+2005-12-13 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (ppc64_elf_relocate_section): Force tail calls in
+ shared libs to resolve locally.
+
+2005-12-12 Paul Brook <paul@codesourcery.com>
+
+ * bfd-in2.h: Regenerate.
+ * elf32-arm.c (elf32_arm_reloc_map): Add BFD_RELOC_ARM_PCREL_CALL and
+ BFD_RELOC_ARM_PCREL_JUMP.
+ (check_use_blx): New function.
+ (bfd_elf32_arm_process_before_allocation): Don't allocate glue if
+ using BLX.
+ (elf32_arm_final_link_relocate): Perform bl<->blx conversion for
+ R_ARM_CALL and R_ARM_THM.
+ (elf32_arm_get_eabi_attr_int): New function.
+ (elf32_arm_size_dynamic_sections): Call check_use_blx.
+ * libbfd.h: Regenerate.
+ * reloc.c: Add BFD_RELOC_ARM_PCREL_CALL and BFD_RELOC_ARM_PCREL_JUMP.
+
+2005-12-12 Nathan Sidwell <nathan@codesourcery.com>
+
+ * Makefile.am (ALL_MACHINES, ALL_MACHINES_CFILES,
+ BFD32_BACKENDS, BFD32_BACKENDS_CFILES): Replace ms1 with mt.
+ (cpu_mt.lo, elf32-mt.lo): Update target and dependency names.
+ * Makefile.in: Rebuilt.
+ * config.bfd: Replace ms1 arch with mt.
+ * configure.in: Replace ms1 files with mt files.
+ * configure: Rebuilt.
+ * elf32-mt.c: Renamed from elf32-ms1.c. Update include files.
+ * cpu-mt.c: Renamed from cpu-ms1.c.
+
+2005-12-12 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (ppc64_elf_size_stubs): Don't consider non-ppc64 input.
+
+2005-12-10 Alan Modra <amodra@bigpond.net.au>
+
+ * elflink.c (elf_gc_mark_dynamic_ref_symbol): Use !info-executable
+ to test for linking shared libs, not info->shared.
+
+2005-12-08 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-ppc.c (struct ppc_elf_link_hash_table): Add emit_stub_syms.
+ (ppc_elf_select_plt_layout): Add emit_stub_syms param, save to htab.
+ (add_stub_sym): New function.
+ (allocate_dynrelocs): Call add_stub_sym.
+ (ppc_elf_size_dynamic_sections): Emit __glink and __glink_PLTresolve
+ when emit_stub_syms.
+ * elf32-ppc.h (ppc_elf_select_plt_layout): Update prototype.
+
+2005-12-08 Alan Modra <amodra@bigpond.net.au>
+
+ * reloc.c (enum complain_overflow): Correct comments.
+ (bfd_check_overflow): Combine complain_overflow_bitfield and
+ complain_overflow_signed code.
+ (_bfd_relocate_contents): Likewise.
+ (bfd_howto_32): Use complain_overflow_dont.
+ * elf32-d10v.c (elf_d10v_howto_table): Revert 2002-06-17 change.
+ * bfd-in2.h: Regenerate.
+
+2005-12-07 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf.c (assign_section_numbers): Remove extra code in the last
+ change.
+
+2005-12-07 H.J. Lu <hongjiu.lu@intel.com>
+ Andreas Schwab <schwab@suse.de>
+
+ PR binutils/1991
+ * elf.c (assign_section_numbers): Always use the output section
+ when setting up sh_link for SHF_LINK_ORDER.
+
+2005-12-07 Thiemo Seufer <ths@networkno.de>
+ H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/1932
+ * bfd-in.h (bfd_elf_record_link_assignment): Add output_bfd
+ and hidden arguments.
+
+ * bfd.c (bfd_hide_symbol): Removed.
+
+ * bfd-in2.h: Regenerated.
+
+ * elflink.c (bfd_elf_record_link_assignment): Handle hidden
+ symbols which were provided by a linker script.
+
+2005-12-06 Paul Gilliam <pgilliam@us.ibm.com>
+
+ * cpu-powerpc.c (bfd_powerpc_archs): Add ppc 750.
+
+2005-11-18 Mark Kettenis <kettenis@gnu.org>
+
+ * elf64-hppa.c (elf64_hppa_section_from_phdr): Create .kernel
+ pseudo-section. Make sure .reg section comes after the proc
+ section it's generated from.
+
+2005-12-01 Kazuhiro Inaoka <inaoka.kazuhiro@renesas.com>
+
+ * elf32-m32r.c (m32r_elf_sweep_hook): Fix an illegal duplicate check.
+ (m32r_elf_relocate_section): Fix R_M32R_10_PCREL_RELA linkage bug.
+ (m32r_elf_gc_sweep_hook): Likewise.
+ (m32r_elf_check_relocs): Likewise.
+
+2005-11-24 Alan Modra <amodra@bigpond.net.au>
+
+ * elf-bfd.h (_bfd_generic_match_sections_by_type): Don't define.
+ * libbfd-in.h (_bfd_generic_match_sections_by_type): Delete.
+ * libbfd.c (_bfd_generic_match_sections_by_type): Delete.
+ * targets.c (bfd_match_sections_by_type): Don't define.
+ (BFD_JUMP_TABLE_LINK): Remove _bfd_generic_match_sections_by_type.
+ * coff-rs6000.c (rs6000coff_vec, pmac_xcoff_vec): Likewise.
+ * coff64-rs6000.c (rs6000coff64_vec, aix5coff64_vec): Likewise.
+ * bfd-in2.h: Regenerate.
+ * libbfd.h: Regenerate.
+
+2005-11-23 Daniel Jacobowitz <dan@codesourcery.com>
+ Thiemo Seufer <ths@networkno.de>
+
+ * elf32-mips.c (elf_mips_howto_table_rel): Use rightshift 2 for
+ R_MIPS_PC16.
+ (mips_reloc_map): Map BFD_RELOC_16_PCREL_S2 to R_MIPS_PC16.
+ (bfd_elf32_bfd_reloc_type_lookup): Don't handle
+ BFD_RELOC_16_PCREL_S2.
+ * elf64-mips.c (mips_elf64_howto_table_rel): Use rightshift 2 for
+ R_MIPS_PC16.
+ (mips_elf64_howto_table_rela): Likewise.
+ (mips_reloc_map): Map BFD_RELOC_16_PCREL_S2 to R_MIPS_PC16.
+ (bfd_elf64_bfd_reloc_type_lookup): Don't handle
+ BFD_RELOC_16_PCREL_S2.
+ * elfn32-mips.c (elf_mips_howto_table_rel): Use rightshift 2 for
+ R_MIPS_PC16.
+ (elf_mips_howto_table_rela): Likewise.
+ (mips_reloc_map): Map BFD_RELOC_16_PCREL_S2 to R_MIPS_PC16.
+ (bfd_elf32_bfd_reloc_type_lookup): Don't handle
+ BFD_RELOC_16_PCREL_S2.
+ * elfxx-mips.c: Formatting fixes.
+ (mips_elf_calculate_relocation): Handle R_MIPS_GNU_REL16_S2
+ and R_MIPS_PC16 identically.
+
+2005-11-23 Frederic Riss <frederic.riss@st.com>
+
+ * elfcode.h (elf_object_p): Delay the setting of start_address
+ until we're sure the backend matches the binary.
+
+2005-11-20 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ * som.c (som_decode_symclass): Decode BSF_WEAK symbols in the same
+ manner as bfd_decode_symclass.
+
+2005-11-18 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (ppc64_elf_check_relocs): Don't set has_14bit_branch
+ on branches to same section.
+
+2005-11-17 Randolph Chung <tausq@debian.org>
+
+ * elf64-hppa.c (elf64_hppa_object_p): Recognize corefiles under
+ hppa64-hp-hpux11.11.
+ (elf64_hppa_section_from_phdr): New function.
+ (elf_backend_section_from_phdr): Define.
+
+2005-11-11 Nick Clifton <nickc@redhat.com>
+
+ PR 1150
+ * elfxx-mips.c (mips_elf_calculate_relocation): Ignore an
+ undefined symbol if it is optional.
+ (_bfd_mips_elf_merge_symbol_attribute): Make sure that the
+ optional flag is merged as well as the visibility.
+ * elfxx-mips.h (_bfd_mips_elf_merge_symbol_attribute): Prototype.
+ (elf_backend_merge_symbol_attribute): Define.
+
+2005-11-08 Nathan Sidwell <nathan@codesourcery.com>
+
+ Add ms2 support
+ * archures.c (bfd_mach_ms2): Define.
+ * cpu-ms1.c (arch_info_struct): Add ms2 stanza.
+ * elf32-ms1.c (elf32_ms1_machine): Add ms2 case.
+ (ms1_elf_merge_private_bfd_data): Remove unused variables. Add
+ correct merging logic, with workaround.
+ (ms1_elf_print_private_bfd_data): Add ms2 case.
+ * reloc.c (BFD_RELOC_MS1_PCINSN8): Add ms2 specific reloc.
+ * libbfd.h: Regenerated.
+ * bfd-in2.h: Regenerated.
+
+2005-11-07 Steve Ellcey <sje@cup.hp.com>
+
+ * warning.m4 (AM_BINUTILS_WARNINGS): Default to empty string
+ if compiler is not GCC.
+ * configure: Regenerate
+
+2005-11-07 Steve Ellcey <sje@cup.hp.com>
+
+ * configure: Regenerate after modifying bfd/warning.m4.
+
+2005-11-07 Steve Ellcey <sje@cup.hp.com>
+
+ * configure.host (ia64-*-hpux*): Set _LARGEFILE64_SOURCE.
+
+2005-11-03 Daniel Jacobowitz <dan@codesourcery.com>
+
+ * configure.in: Check for fopen64.
+ * libbfd-in.h (real_fopen): New prototype.
+ * configure, config.in, libbfd.h: Regenerated.
+ * bfdio.c (real_fopen): New function.
+ * opncls.c (bfd_fopen, bfd_fill_in_gnu_debuglink_section): Use it.
+ * cache.c (bfd_open_file): Likewise.
+
+2005-11-03 Thiemo Seufer <ths@networkno.de>
+
+ * elfxx-mips.c (mips_elf_calculate_relocation): Handle only
+ forced local symbols here.
+ (mips_elf_create_dynamic_relocation): Likewise.
+ (_bfd_mips_elf_finish_dynamic_symbol): Fix typo in comment.
+
+2005-11-03 Alan Modra <amodra@bigpond.net.au>
+
+ * elf.c (elf_fake_sections): When calculating tbss size, just use
+ the last link_order.
+ (assign_file_positions_for_segments): Likewise.
+ * elflink.c (bfd_elf_final_link): Likewise.
+ (elf_reloc_link_order): Correct comment.
+
+2005-11-02 Alan Modra <amodra@bigpond.net.au>
+
+ PR ld/1775
+ * elf32-m68k.c (elf_m68k_finish_dynamic_symbol): Add required
+ parentheses.
+
+2005-10-29 H.J. Lu <hongjiu.lu@intel.com>
+
+ * Makefile.am: Run "make dep-am".
+ * Makefile.in: Regenerated.
+
+ * dep-in.sed: Replace " ./" with " ".
+
+2005-10-29 H.J. Lu <hongjiu.lu@intel.com>
+
+ * hpux-core.c: Include <machine/reg.h> only if HPUX_CORE is
+ define.
+ * osf-core.c: Include <sys/core.h> only if OSF_CORE is defined.
+ * sco5-core.c: Include <sys/paccess.h> and <sys/region.h> only
+ if SCO5_CORE is defined.
+
+2005-10-29 Mark Kettenis <kettenis@gnu.org>
+
+ * Makefile.am: Run "make dep-am".
+ * Makefile.in: Regenerate.
+
+2005-10-28 Joel Brobecker <brobecker@adacore.com>
+
+ From Eric Botcazou <botcazou@adacore.com>
+ * coffcode.h (coff_compute_section_file_positions): Fix small
+ error in preprocessor directives.
+
+2005-10-28 Joel Brobecker <brobecker@adacore.com>
+
+ Mostly from Eric Botcazou <botcazou@adacore.com>
+ * rs6000-core.c: ANSIfy all function definitions.
+ Add missing function prototypes.
+ (ptr_to_uint): New type.
+ (rs6000coff_core_p): Use it as intermediate step in casts.
+ (rs6000coff_core_file_matches_executable_p): Likewise.
+ * xcoff-target.h (rs6000coff_core_p): Fix prototype.
+ (rs6000coff_core_file_matches_executable_p): Likewise.
+
+2005-10-28 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR binutils/1472
+ * aoutx.h (NAME (aout, machine_type)): Handle
+ bfd_mach_sparc_v8plus, bfd_mach_sparc_v8plusa,
+ bfd_mach_sparc_v8plusb, bfd_mach_sparc_v9, bfd_mach_sparc_v9a
+ and bfd_mach_sparc_v9b.
+
+2005-10-28 Hans-Peter Nilsson <hp@axis.com>
+
+ PR ld/1567
+ * elf32-cris.c (cris_elf_howto_table) <R_CRIS_32>: Set
+ complain_on_overflow field to complain_overflow_dont.
+
+2005-10-27 Alan Modra <amodra@bigpond.net.au>
+
+ PR 973
+ * cache.c (enum cache_flag): New.
+ (close_one): Save file mtime.
+ (bfd_cache_lookup): Add flag arg, adjust all users.
+ (bfd_cache_lookup_worker): Likewise.
+ (cache_btell): Use CACHE_NO_OPEN and return abfd->where if file
+ not open.
+ (cache_bflush): Similarly, and return success of file not open.
+ (cache_bseek): Use CACHE_NO_SEEK if SEEK_SET or SEEK_END.
+ (cache_bstat): Use CACHE_NO_SEEK_ERROR.
+
+ * bfdwin.c (bfd_get_file_window): Seek into file in place of
+ using bfd_cache_lookup.
+
+ * cache.c (BFD_CACHE_MAX_OPEN): Make private to this file.
+ (bfd_last_cache, bfd_cache_lookup, bfd_cache_lookup_worker): Likewise.
+ * libbfd-in.h (bfd_cache_lookup_worker, bfd_last_cache): Delete.
+ * libbfd.h: Regenerate.
+
+ * hppabsd-core.c (hppabsd_core_core_file_p): Use bfd_stat, not fstat.
+ * sco5-core.c (sco5_core_file_p): Likewise.
+ * trad-core.c (trad_unix_core_file_p): Likewise.
+
+ * cache.c: Reorganize file to avoid forward reference.
+
+2005-10-26 Alan Modra <amodra@bigpond.net.au>
+
+ * cache.c (bfd_cache_lookup_worker): Don't abort on failing to
+ reopen file.
+ (cache_btell, cache_bseek, cache_bflush, cache_bstat): Return -1 on
+ bfd_cache_lookup failure.
+ (cache_bread, cache_bwrite): Return 0 on the same.
+ * bfdwin.c (bfd_get_file_window): Likewise.
+ * hppabsd-core.c (hppabsd_core_core_file_p): Likewise.
+ * sco5-core.c (sco5_core_file_p): Likewise.
+ * trad-core.c (trad_unix_core_file_p): Likewise.
+
+2005-10-26 Alan Modra <amodra@bigpond.net.au>
+
+ * cache.c (bfd_cache_lookup_worker): Use bfd_error_handler
+ rather than bfd_perror. Print file name. Internationalise.
+
+2005-10-26 Alan Modra <amodra@bigpond.net.au>
+
+ * cache.c (bfd_open_file): Set bfd_error_system_call on failure
+ to open file.
+ (bfd_cache_lookup_worker): Remove check that file pos is in
+ unsigned long range. Print system error before aborting.
+
+2005-10-25 Arnold Metselaar <arnold.metselaar@planet.nl>
+
+ * Makefile.am: Add rules for coff-z80 and cpu-z80.
+ * Makefile.in: Regenerated.
+ * archures.c: Add bfd_arch_z80 and support for it.
+ * coffcode.h(coff_set_arch_mach_hook): Add case Z80MAGIC.
+ (coff_set_flags): Add case bfd_arch_z80.
+ * config.bfd: Add z80coff_vec.
+ * configure.in: Add z80coff_vec.
+ * reloc.c: Add BFD_RELOC_Z80_DISP8
+ * targets.c: Add z80coff_vec.
+ * coff-z80.c: New file
+ * cpu-z80.c: New file
+ * configure: Regenerated.
+ * libbfd.h: Regenerated.
+ * bfd-in2.h: Regenerated.
+
+2005-10-26 Alan Modra <amodra@bigpond.net.au>
+
+ PR ld/1540
+ * elf-bfd.h (elf_backend_copy_indirect_symbol): Replace pointer to
+ elf_backend_data with pointer to bfd_link_info.
+ (_bfd_elf_link_hash_copy_indirect): Likewise.
+ * elf.c (_bfd_elf_link_hash_copy_indirect): Likewise. Handle
+ direct and indirect symbols both having dynamic link info.
+ * elf32-arm.c (elf32_arm_copy_indirect_symbol): Likewise.
+ * elf32-hppa.c (elf32_hppa_copy_indirect_symbol): Likewise.
+ * elf32-i386.c (elf_i386_copy_indirect_symbol): Likewise.
+ * elf32-m32r.c (m32r_elf_copy_indirect_symbol): Likewise.
+ * elf32-ppc.c (ppc_elf_copy_indirect_symbol): Likewise.
+ * elf32-s390.c (elf_s390_copy_indirect_symbol): Likewise.
+ * elf32-sh.c (sh_elf_copy_indirect_symbol): Likewise.
+ * elf64-ppc.c (ppc64_elf_copy_indirect_symbol): Likewise.
+ * elf64-s390.c (elf_s390_copy_indirect_symbol): Likewise.
+ * elf64-x86-64.c (elf64_x86_64_copy_indirect_symbol): Likewise.
+ * elfxx-ia64.c (elfNN_ia64_hash_copy_indirect): Likewise.
+ * elfxx-mips.c (_bfd_mips_elf_copy_indirect_symbol): Likewise.
+ * elfxx-sparc.c (_bfd_sparc_elf_copy_indirect_symbol): Likewise.
+ * elflink.c: Adjust all calls to bed->elf_backend_copy_indirect_symbol.
+ * elfxx-mips.h (_bfd_mips_elf_copy_indirect_symbol): Update prototype.
+ * elfxx-sparc.h (_bfd_sparc_elf_copy_indirect_symbol): Likewise.
+
+2005-10-25 Alan Modra <amodra@bigpond.net.au>
+
+ * po/SRC-POTFILES.in: Regenerate.
+ * po/bfd.pot: Regenerate.
+
+2005-10-24 Jie Zhang <jie.zhang@analog.com>
+
+ * elf32-bfin.c (bfd_bfin_elf32_create_embedded_relocs): Fix signedness
+ warning.
+
+2005-10-24 Bernd Schmidt <bernd.schmidt@analog.com>
+
+ * elf32-bfin.c (bfin_howto_table): Set src_mask to 0 for all relocs.
+ (bfin_imm16_reloc): Always add in the addend. Don't fetch existing
+ contents from section.
+ (bfin_relocate_section): Rework so as to not call special_functions.
+ Handle the relocation stack here. Treat pcrel24 relocs specially.
+
+2005-10-24 Alan Modra <amodra@bigpond.net.au>
+
+ * elflink.c (elf_link_input_bfd): Don't use linker_mark and
+ SEC_EXCLUDE to test for sections dropped from output. Instead,
+ use bfd_section_removed_from_list on normal sections. Don't
+ attempt to handle symbols with unknown reserved section indices.
+ * linker.c (_bfd_generic_link_output_symbols): Don't use
+ linker_mark to test for symbols belonging to dropped sections.
+ Do allow absolute symbols.
+
+2005-10-24 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-i370.c (i370_elf_fake_sections): Don't set SHF_EXCLUDE on
+ group sections.
+
+2005-10-24 Jan Beulich <jbeulich@novell.com>
+
+ * cpu-ia64-opc.c (elf64_ia64_operands): Move memory operand out of
+ set of indirect operands.
+
+2005-10-24 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-ppc.c (ppc_elf_fake_sections): Don't set SHF_EXCLUDE on
+ group sections.
+
+2005-10-23 H.J. Lu <hongjiu.lu@intel.com>
+
+ * coff-rs6000.c (rs6000coff_vec): Initialize
+ _bfd_init_private_section_data with
+ _bfd_generic_init_private_section_data.
+ (pmac_xcoff_vec): Likewise.
+ * coff64-rs6000.c (rs6000coff64_vec): Likewise.
+ (aix5coff64_vec): Likewise.
+
+2005-10-23 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/1487
+ * elf-bfd.h (_bfd_generic_init_private_section_data): New.
+ (_bfd_elf_init_private_section_data): New.
+
+ * elf.c (elf_fake_sections): Don't set SHF_GROUP for
+ relocatable link.
+ (bfd_elf_set_group_contents): Don't handle relocatable link
+ specially.
+ (assign_section_numbers): If it isn't called by assembler,
+ use the output section of elf_linked_to_section for
+ SHF_LINK_ORDER.
+ (_bfd_elf_init_private_section_data): New.
+ (_bfd_elf_copy_private_section_data): Call it.
+
+ * libbfd-in.h (_bfd_generic_init_private_section_data): New.
+
+ * libbfd.c (_bfd_generic_init_private_section_data): New.
+
+ * targets.c (BFD_JUMP_TABLE_COPY): Add
+ _bfd_generic_init_private_section_data.
+ (bfd_init_private_section_data): Likewise.
+
+ * bfd-in2.h: Regenerated.
+ * libbfd.h: Likewise.
+
+2005-10-23 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (dec_dynrel_count): Don't report errors for local
+ syms in gc'd sections.
+ (ppc64_elf_edit_opd): Don't adjust reloc counts when NO_OPD_RELOCS.
+ (elf_backend_action_discarded): Define.
+ (ppc64_elf_action_discarded): New function.
+
+2005-10-19 Paul Brook <paul@codesourcery.com>
+
+ * elf32-arm.c (find_arm_elf_section_entry): New function.
+ (get_arm_elf_section_data): Use it.
+ (unrecord_section_with_arm_elf_section_data): Use it.
+
+2005-10-15 H.J. Lu <hongjiu.lu@intel.com>
+
+ * coff-rs6000.c (rs6000coff_vec): Initialize
+ _bfd_match_sections_by_type with
+ _bfd_generic_match_sections_by_type.
+ (pmac_xcoff_vec): Likewise.
+ * coff64-rs6000.c (rs6000coff64_vec): Likewise.
+ (aix5coff64_vec): Likewise.
+
+2005-10-15 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/1467
+ * elf-bfd.h (_bfd_elf_match_sections_by_type): New.
+ (_bfd_generic_match_sections_by_type): New. Defined.
+
+ * elf.c (_bfd_elf_match_sections_by_type): New.
+
+ * libbfd-in.h (_bfd_generic_match_sections_by_type): New.
+
+ * bfd-in2.h: Regenerated.
+ * libbfd.h: Likewise.
+
+ * libbfd.c (_bfd_generic_match_sections_by_type): New.
+
+ * targets.c (BFD_JUMP_TABLE_LINK): Initialize
+ _bfd_match_sections_by_type with
+ _bfd_generic_match_sections_by_type.
+ (bfd_target): Add _bfd_match_sections_by_type.
+
+2005-10-08 Paul Brook <paul@codesourcery.com>
+
+ * elf32-arm.c: Move #include "elf/arm.h" after libbfd.h.
+ (NUM_KNOWN_ATTRIBUTES): Define.
+ (aeabi_attribute, aeabi_attribute_list): Define.
+ (elf32_arm_obj_tdata): Add known_eabi_attributes and
+ other_eabi_attributes.
+ (uleb128_size, is_default_attr, eabi_attr_size,
+ elf32_arm_eabi_attr_size, write_uleb128, write_eabi_attribute,
+ elf32_arm_set_eabi_attr_contents, elf32_arm_bfd_final_link,
+ elf32_arm_new_eabi_attr, attr_strdup, elf32_arm_add_eabi_attr_int,
+ elf32_arm_add_eabi_attr_compat, copy_eabi_attributes,
+ elf32_arm_merge_eabi_attributes): New functions.
+ (elf32_arm_copy_private_bfd_data): Copy EABI object attributes.
+ (elf32_arm_fake_sections): Handle .ARM.attributes.
+ (elf32_arm_parse_attributes): New function.
+ (elf32_arm_section_from_shdr): Use it.
+ (bfd_elf32_bfd_final_link): Define.
+
+2005-10-06 Daniel Jacobowitz <dan@codesourcery.com>
+
+ * elf32-arm.c (elf32_arm_check_relocs): Avoid aliasing warnings from
+ GCC.
+ (elf32_arm_size_dynamic_sections): Likewise.
+ * ecofflink.c (bfd_ecoff_debug_one_external): Likewise.
+ * elf32-hppa.c (elf32_hppa_check_relocs): Likewise.
+ * elf32-m32r.c (m32r_elf_check_relocs): Likewise.
+ * elf32-m68k.c (elf_m68k_check_relocs): Likewise.
+ * elf32-ppc.c (ppc_elf_check_relocs): Likewise.
+ * elf32-s390.c (elf_s390_check_relocs): Likewise.
+ (elf_s390_size_dynamic_sections): Likewise.
+ * elf32-sh.c (sh_elf_check_relocs): Likewise.
+ * elf64-ppc.c (ppc64_elf_check_relocs, dec_dynrel_count)
+ (ppc64_elf_size_dynamic_sections): Likewise.
+ * elf64-s390.c (elf_s390_check_relocs): Likewise.
+ (elf_s390_size_dynamic_sections): Likewise.
+ * elfxx-mips.c (_bfd_mips_elf_finish_dynamic_sections): Likewise.
+ * elfxx-sparc.c (_bfd_sparc_elf_check_relocs): Likewise.
+ (_bfd_sparc_elf_size_dynamic_sections): Likewise.
+ * ieee.c (ieee_slurp_section_data): Likewise.
+ * oasys.c (oasys_slurp_section_data): Likewise.
+
+2005-10-04 Bob Wilson <bob.wilson@acm.org>
+
+ * archive.c: Add missing SUBSECTION for documentation.
+ * bfd.c: Likewise.
+ * cache.c: Likewise.
+ * corefile.c: Likewise.
+ * format.c: Likewise.
+ * init.c: Likewise.
+ * libbfd.c: Likewise.
+ * opncls.c: Likewise.
+ * elf.c: Remove blank line after SECTION heading.
+ * reloc.c: Change "howto manager" SECTION to a SUBSECTION.
+
+2005-10-04 Nick Clifton <nickc@redhat.com>
+
+ * elf32-arm.c (get_arm_elf_section_data): Cache the last pointer
+ matched so that the typical case of scanning for the previous
+ section to last one can be handled quickly.
+
+2005-10-03 David Heine <dlheine@tensilica.com>
+
+ * elf32-xtensa.c (relocations_reach): Skip range check for
+ absolute literals.
+
+2005-10-03 Alan Modra <amodra@bigpond.net.au>
+
+ * elf.c (_bfd_elf_get_synthetic_symtab): Set BSF_GLOBAL on
+ synthetic syms.
+
+2005-09-30 H.J. Lu <hongjiu.lu@intel.com>
+
+ * Makefile.am: Run "make dep-am".
+ * Makefile.in: Regenerated.
+ * aclocal.m4: Likewise.
+
+2005-09-30 Catherine Moore <clm@cm00re.com>
+
+ * Makefile.am: Bfin support.
+ * Makefile.in: Regenerated.
+ * aclocal.m4: Regenerated.
+ * archures.c (bfd_mach_bfin): New.
+ (bfd_arch_bfin): New.
+ bfd-in.h (bfd_bfin_elf32_create_embedded_relocs): New.
+ * bfd-in2.h: Regenerated.
+ * config.bfd: Bfin support.
+ * configure: Regenerated.
+ * configure.in: Bfin support.
+ * libbfd.h: Regenerated.
+ * reloc.c: Add BFD relocations for Bfin.
+ * targets.c (bfd_elf32_bfin_vec): New.
+ * cpu-bfin.c: New file.
+ * elf32-bfin.c: New file.
+
+2005-09-30 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (ppc_type_of_stub): Check both func desc and func
+ entry sym before deciding no stub is needed.
+ (ppc64_elf_size_stubs): When calculating branch destination,
+ don't use func desc sym for old ABI objects unless func entry
+ is undefined.
+
+2005-09-28 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR binutils/1321
+ * elf-bfd.h (_bfd_elf_setup_group_pointers): Renamed to ...
+ (_bfd_elf_setup_sections): This.
+ * elf.c: Likewise.
+ * elfcode.h (elf_object_p): Likewise.
+
+ * elf.c (_bfd_elf_setup_sections): Process SHF_LINK_ORDER.
+ (_bfd_elf_copy_private_section_data): Likewise.
+
+2005-09-28 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elflink.c (elf_fixup_link_order): Report locations for mixed
+ ordered and unordered input sections.
+
+2005-09-22 James E. Wilson <wilson@specifix.com>
+
+ * dwarf2.c (struct funcinfo): Delete nesting_level field.
+ (lookup_address_in_function_table): Delete code to set funcinfo
+ caller_func field. Delete local curr_func.
+ (scan_unit_for_symbols): New locals nested_funcs, nested_funcs_size.
+ Delete code setting funcinfo nesting_level field. Add code to set
+ funcinfo caller_func field.
+
+2005-09-20 James E. Wilson <wilson@specifix.com>
+
+ * dwarf2.c (find_abstract_instance_name): Don't early exit when name
+ set. For DW_AT_name case, only set name if not already set. Handle
+ DW_AT_MIPS_linkage_name.
+
+2005-09-20 Alan Modra <amodra@bigpond.net.au>
+
+ * elflink.c (_bfd_elf_merge_symbol): Simplify.
+
+2005-09-19 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (ppc_build_one_stub): Replace assertion that long
+ branch offset is in range with an error. Print full stub name on
+ errors.
+ (ppc_size_one_stub): Print full stub name on errors.
+ (group_sections): Warn if section size exceeds group size.
+ (ppc64_elf_size_stubs): Continue relaxing when stub types change.
+
+2005-09-09 Kevin Buettner <kevinb@redhat.com>
+
+ * elf32-am33lin.c (bfd.h, sysdep.h, elf-bfd.h, elf/mn10300.h):
+ Include.
+ (elf32_am33lin_grok_prstatus, elf32_am33lin_grok_psinfo): New
+ functions.
+ (elf_backend_grok_prstatus, elf_backend_grok_psinfo): Define.
+
+2005-09-09 Richard Earnshaw <richard.earnshaw@arm.com>
+
+ * elf32-arm.c (elf32_arm_section_from_shdr): Accept SHT_ARM_PREEMPTMAP
+ and SHT_ARM_ATTRIBUTES.
+
+2005-09-08 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elflink.c (elf_get_linked_section_vma): Fix a typo in comment.
+ * elfxx-ia64.c (elf_backend_link_order_error_handler): Likewise.
+
+2005-09-08 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/1263
+ * elflink.c (elf_link_add_object_symbols): Abort for
+ --just-symbols on DSO.
+
+2005-09-08 Paul Brook <paul@codesourcery.com>
+
+ * reloc.c: Rename BFD_RELOC_ARM_SMI to BFD_RELOC_ARM_SMC.
+ * bfd-in2.h: Regenerate.
+ * libbfd.h: Regenerate.
+
+2005-09-06 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/1301
+ * elflink.c (_bfd_elf_merge_symbol): Don't check undefined
+ symbol introduced by "ld -u" for TLS.
+
+2005-09-02 Paul Brook <paul@codesourcery.com>
+
+ * libbdf.h: Regenerate.
+ * bfd-in2.h: Regenerate.
+ * reloc.c: Add BFD_RELOC_ARM_T32_CP_OFF_IMM and
+ BFD_RELOC_ARM_T32_CP_OFF_IMM_S2.
+
+2005-09-01 Dmitry Diky <diwil@spec.ru>
+
+ * elf32-msp430.c (msp430_elf_relax_delete_bytes): Do not adjust
+ local symbols and move it to
+ (msp430_elf_relax_adjust_locals): New function - walk over the
+ sections in the bfd and adjust relocations as necessary.
+
+2005-08-31 DJ Delorie <dj@redhat.com>
+
+ * elf32-i386.c (elf_i386_check_relocs): Don't cast a unary &
+ address operator, as that breaks GCC's strict aliasing rules.
+ (elf_i386_size_dynamic_sections): Avoid the need for type
+ punning.
+ * elf64-x86-64.c (elf_x86_64_check_relocs): Don't cast a unary
+ & address operator, as that breaks GCC's strict aliasing
+ rules.
+ (elf_x86_64_size_dynamic_sections): Avoid the need for type
+ punning.
+
+2005-08-30 Phil Edwards <phil@codesourcery.com>
+
+ * config.bfd (i[3-7]86-*-vxworks): Match vxworks* instead.
+
+2005-08-29 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/1247
+ * elfxx-ia64.c (allocate_fptr): Check undefined symbol.
+
+2005-08-29 Steven J. Hill <sjhill@realitydiluted.com>
+
+ * elfxx-mips.c (_bfd_mips_elf_relocate_section): Initialise
+ 'value' to avoid compile time warning message.
+
+2005-08-26 Christian Groessler <chris@groessler.org>
+
+ * coff-z8k.c: (r_jr, r_disp7, r_callr): Fix src_mask and dst_mask
+ of HOWTO.
+ (coff_z8k_select_reloc): Remove.
+ (SELECT_RELOC): Remove.
+ (coff_z8k_reloc_type_lookup): New function.
+ (coff_bfd_reloc_type_lookup): Define.
+ * configure.in: Add cofflink.lo to z8kcoff_vec.
+ * configure: Regenerate.
+ * reloc.c: (bfd_reloc_code_type): Add z8k relocations.
+ (bfd_install_relocation): Don't clear reloc_entry->addend for
+ coff-z8k target.
+ * bfd-in2.h: Regenerate.
+ * libbfd.h: Regenerate.
+
+2005-08-25 Kaz Kojima <kkojima@rr.iij4u.or.jp>
+
+ * elf32-sh.c (sh_elf_get_flags_from_mach): Fix off-by-one error.
+
+2005-08-24 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/1208
+ * elf-hppa.h (elf_hppa_relocate_section): Print out the name
+ of unresolvable relocation.
+ * elf-m10300.c (mn10300_elf_relocate_section): Likewise.
+ * elf32-arm.c (elf32_arm_relocate_section): Likewise.
+ * elf32-i386.c (elf_i386_relocate_section): Likewise.
+ * elf32-m32r.c (m32r_elf_relocate_section): Likewise.
+ * elf32-m68k.c (elf_m68k_relocate_section): Likewise.
+ * elf32-s390.c (elf_s390_relocate_section): Likewise.
+ * elf32-sh.c (sh_elf_relocate_section): Likewise.
+ * elf32-xtensa.c (elf_xtensa_relocate_section): Likewise.
+ * elf64-s390.c (elf_s390_relocate_section): Likewise.
+ * elf64-sh64.c (sh_elf64_relocate_section): Likewise.
+ * elf64-x86-64.c (elf64_x86_64_relocate_section): Likewise.
+ * elfxx-sparc.c (_bfd_sparc_elf_relocate_section): Likewise.
+
+2005-08-18 Kaz Kojima <kkojima@rr.iij4u.or.jp>
+
+ * config.bfd: Add bfd_elf32_shnbsd_vec and bfd_elf32_shlnbsd_vec
+ to targ_selvecs for sh5*-*-netbsd* and sh64*-*-netbsd*.
+
+2005-08-18 Alan Modra <amodra@bigpond.net.au>
+
+ * coff-a29k.c: Delete.
+ * cpu-a29k.c: Delete.
+ * Makefile.am: Remove mention of a29k files.
+ * aoutf1.h: Remove a29k support.
+ * aoutx.h: Likewise.
+ * archures.c: Likewise.
+ * coffcode.h: Likewise.
+ * config.bfd: Likewise.
+ * configure.in: Likewise.
+ * ieee.c: Likewise.
+ * mipsbsd.c: Likewise.
+ * pdp11.c: Likewise.
+ * sparclynx.c: Likewise.
+ * targets.c: Likewise.
+ * Makefile.in: Regenerate.
+ * configure: Regenerate.
+ * bfd-in2.h: Regenerate.
+ * po/SRC-POTFILES.in: Regenerate.
+
+2005-08-18 Alan Modra <amodra@bigpond.net.au>
+
+ * elf-m10300.c (_bfd_mn10300_elf_adjust_dynamic_symbol): Warn on
+ zero size dynamic variables.
+ * elf32-arm.c (elf32_arm_adjust_dynamic_symbol): Likewise.
+ * elf32-cris.c (elf_cris_adjust_dynamic_symbol): Likewise.
+ * elf32-hppa.c (elf32_hppa_adjust_dynamic_symbol): Likewise.
+ * elf32-i370.c (i370_elf_adjust_dynamic_symbol): Likewise.
+ * elf32-i386.c (elf_i386_adjust_dynamic_symbol): Likewise.
+ * elf32-m32r.c (m32r_elf_adjust_dynamic_symbol): Likewise.
+ * elf32-m68k.c (elf_m68k_adjust_dynamic_symbol): Likewise.
+ * elf32-ppc.c (ppc_elf_adjust_dynamic_symbol): Likewise.
+ * elf32-s390.c (elf_s390_adjust_dynamic_symbol): Likewise.
+ * elf32-sh.c (sh_elf_adjust_dynamic_symbol): Likewise.
+ * elf32-vax.c (elf_vax_adjust_dynamic_symbol): Likewise.
+ * elf64-ppc.c (ppc64_elf_adjust_dynamic_symbol): Likewise.
+ * elf64-s390.c (elf_s390_adjust_dynamic_symbol): Likewise.
+ * elf64-sh64.c (sh64_elf64_adjust_dynamic_symbol): Likewise.
+ * elf64-x86-64.c (elf64_x86_64_adjust_dynamic_symbol): Likewise.
+ * elfxx-sparc.c (_bfd_sparc_elf_adjust_dynamic_symbol): Likewise.
+
+2005-08-17 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR binutils/1179
+ * dwarf2.c (_bfd_dwarf2_find_nearest_line): Use section lma
+ instead of vma.
+ (_bfd_dwarf2_find_line): Likewise.
+
+2005-08-17 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-mmix.c (mmix_elf_add_symbol_hook): Mark reg section
+ SEC_LINKER_CREATED.
+ (mmix_elf_final_link): Check that section hasn't already been
+ removed before removing.
+ * mmo.c (mmo_scan): Mark reg contents section SEC_LINKER_CREATED.
+ (mmo_canonicalize_symtab): Likewise for reg section.
+
+2005-08-17 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-cris.c (elf_cris_adjust_gotplt_to_got): Move assert later.
+ * elfxx-mips.c (_bfd_mips_elf_hide_symbol): Cope with being called
+ without any got section.
+
+2005-08-17 Danny Smith <dannysmith@users.sourceforge.net>
+
+ * cofflink.c (_bfd_coff_generic_relocate_section): Correct
+ comment.
+
+2005-08-17 Alan Modra <amodra@bigpond.net.au>
+
+ * elflink.c (_bfd_elf_define_linkage_sym): Don't call
+ bfd_elf_link_record_dynamic_symbol. Call elf_backend_hide_symbol.
+ (_bfd_elf_link_renumber_dynsyms): Formatting.
+ (struct elf_gc_sweep_symbol_info): New.
+ (elf_gc_sweep_symbol): Rewrite.
+ (elf_gc_sweep): Adjust params and elf_gc_sweep_symbol call.
+ Call _bfd_elf_link_renumber_dynsyms.
+ (bfd_elf_gc_sections): Adjust elf_gc_sweep call.
+
+2005-08-16 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (ppc64_elf_edit_opd): Don't call dec_dynrel_count
+ when relocatable.
+
+2005-08-15 Bob Wilson <bob.wilson@acm.org>
+
+ * elf32-xtensa.c (ELF_MACHINE_CODE, ELF_MACHINE_ALT1): Swap values
+ of EM_XTENSA and EM_XTENSA_OLD.
+
+2005-08-16 Alan Modra <amodra@bigpond.net.au>
+
+ * elf-bfd.h (_bfd_elf_define_linkage_sym): Declare.
+ * elflink.c (_bfd_elf_define_linkage_sym): New function, extracted
+ from..
+ (_bfd_elf_create_got_section): ..here.
+ (_bfd_elf_link_create_dynamic_sections): Call it for _DYNAMIC.
+ (_bfd_elf_create_dynamic_sections): ..and _PROCEDURE_LINKAGE_TABLE_.
+ * elf-m10300.c (_bfd_mn10300_elf_create_got_section): Use
+ _bfd_elf_define_linkage_sym.
+ * elf32-frv.c (_frv_create_got_section): Likewise.
+ * elf64-alpha.c (elf64_alpha_create_dynamic_sections): Likewise.
+
+2005-08-15 Paul Brook <paul@codesourcery.com>
+
+ * elf32-arm.c (elf32_arm_howto_table_1): Make R_ARM_PLT32 the same as
+ R_ARM_PC24.
+
+2005-08-13 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ PR ld/1135
+ * elf64-hppa.c (elf64_hppa_special_sections): Add flag definitions for
+ .plt, .dlt, .sdata, .sbss and .tbss.
+
+2005-08-12 Dmitry Diky <diwil@spec.ru>
+
+ * elf32-msp430.c (msp430_elf_relax_delete_bytes): Adjust relocations
+ referenced by .section + DISPLACEMENT.
+
+2005-08-10 James E. Wilson <wilson@specifix.com>
+
+ * dwarf2.c (scan_unit_for_symbols, case DT_AT_location): Verify that
+ DW_OP_addr is only opcode in location before using it.
+
+2005-08-09 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elfxx-ia64.c (elfNN_ia64_final_link): Reset gp.
+
+2005-08-09 Rodney Brown <rbrown@bravurasolutions.com.au>
+ Nick Clifton <nickc@redhat.com>
+
+ * aix5ppc-core.c (xcoff64_core_p): Constify return_value
+ variable. Also, do not use core_hdr macro as it evaluates to a
+ cast of an lvalue which is no longer supported by GCC 4.0.
+
+2005-08-08 Eric Dönges <Eric.Doenges@betty-tv.com>
+
+ * archures.c (bfd_mach_msp21): New MSP430 machine number.
+ * bfd-in2.h: Regenerate.
+ * cpu-msp430.c (arch_info_struct): Add support for msp430x21xx
+ variants.
+
+2005-08-07 Nick Clifton <nickc@redhat.com>
+ Paul Brook <paul@codesourcery.com>
+
+ PR 1147
+ * elf32-arm.c (bfd_elf32_close_and_cleanup): Define.
+ (elf32_arm_close_and_cleanup): New function - walk over the
+ sections in the bfd that is being closed removing them from the
+ list of recorded sections.
+ (unrecord_section_via_map_over_sections): New helper function.
+ (record_section_with_arm_elf_section_data): Call bfd_malloc
+ instead of bfd_alloc. Remove unneeded abfd parameter.
+ (elf32_arm_new_section_hook): Do not pass bfd to
+ record_section_with_arm_elf_section_data.
+
+ * elfxx-target.h (bfd_elfNN_close_and_cleanup): Only define if not
+ already defined by the target.
+
+2005-08-05 Fred Fish <fnf@specifix.com>
+
+ * dwarf2.c (read_rangelist): Use addr_size instead of offset_size
+ to determine how many bytes to read from each rangelist entry.
+
+2005-08-05 H.J. Lu <hongjiu.lu@intel.com>
+
+ * bfd.c (bfd_hide_symbol): New.
+ * bfd-in2.h: Regenerated.
+
+2005-08-04 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf64-x86-64.c (elf64_x86_64_merge_symbol): When mixing a
+ large common symbol and a normal common symbol, always turn
+ the large common symbol into a normal one.
+
+2005-08-04 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-ppc.c (struct elf_linker_section): Replace sym_val field
+ with sym.
+ (ppc_elf_relocate_section): Adjust for above.
+ (create_sdata_sym): New function.
+ (ppc_elf_create_linker_section): Call it.
+ (ppc_elf_check_relocs): Correct has_sda_refs and non_got_refs.
+ Create sdata syms for all SDA relocs.
+ (ppc_elf_adjust_dynamic_symbol): Don't special case _SDA_BASE_
+ and _SDA2_BASE_.
+ (ppc_elf_set_sdata_syms): Delete.
+ * elflink.c (bfd_elf_size_dynamic_sections): Don't create DT_INIT
+ and DT_FINI tags unless associated section has input.
+ (bfd_elf_set_symbol, _bfd_elf_provide_symbol): Delete.
+ (_bfd_elf_provide_section_bound_symbols): Delete.
+ * bfd-in.h (_bfd_elf_provide_symbol): Delete.
+ (_bfd_elf_provide_section_bound_symbols): Delete.
+ * bfd-in2.h: Regenerate.
+
+2005-08-04 Alan Modra <amodra@bigpond.net.au>
+
+ * elflink.c (fix_syms, _bfd_elf_fix_excluded_sec_syms): Move to..
+ * linker.c (fix_syms, _bfd_fix_excluded_sec_syms): ..here.
+ * bfd-in.h (_bfd_fix_excluded_sec_syms): Rename.
+ * bfd-in2.h: Regenerate.
+
+2005-08-03 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elfxx-ia64.c (elfNN_ia64_relax_section): Resize .rela.got
+ only if it isn't NULL.
+
+2005-08-03 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf32-i386.c (elf_howto_table): Undo the overflow change for
+ R_386_PC16 made on 2005-07-18.
+
+ * elf64-x86-64.c (x86_64_elf_howto_table): Undo the overflow
+ change for R_X86_64_PC16 made on 2005-07-18.
+
+2005-08-03 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-ppc.c (struct ppc_elf_link_hash_table): Remove hgot. Use
+ elf.hgot throughout file.
+
+2005-08-03 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-ppc.c (ppc_elf_size_dynamic_sections): Correct value of
+ _GLOBAL_OFFSET_TABLE_ for > 32k GOT.
+
+2005-08-02 Andreas Schwab <schwab@suse.de>
+
+ * elfxx-ia64.c (struct elfNN_ia64_allocate_data): Add only_got.
+ (elfNN_ia64_relax_section): Reallocate .rela.got when .got has
+ changed.
+ (allocate_dynrel_entries): Look only at GOT relocations when
+ only_got is true.
+ (elfNN_ia64_size_dynamic_sections): Set only_got to false before
+ calling allocate_dynrel_entries.
+
+2005-08-02 Nick Clifton <nickc@redhat.com>
+
+ PR 1147
+ * elf32-arm.c (struct _arm_elf_section_data): Turn into a typedef
+ and make the mapcount field unsigned.
+ (struct section_list): New: Used to keep track of which sections
+ have an _arm_elf_section_data structure.
+ (record_section_with_arm_elf_section_data): New function.
+ (get_arm_elf_section_data): New function.
+ (unrecord_section_with_arm_elf_section_data): New function.
+ (elf32_arm_output_symbol_hook): Use get_arm_elf_section_data.
+ (elf32_arm_new_section_hook): Call
+ record_section_with_arm_elf_section_data.
+ (elf32_arm_write_section): Use get_arm_elf_section_data and
+ unrecord_section_with_arm_elf_section_data.
+
+2005-08-01 Richard Sandiford <richard@codesourcery.com>
+
+ * elfxx-mips.c (mips_mach_extends_p): Treat MIPS64 as an extension
+ of MIPS32 and MIPS64r2 as an extension of MIPS32r2.
+
+2005-07-30 David Daney <ddaney@avtrex.com>
+
+ * elflink.c (elf_gc_sweep): Set dynsymcount to correct value.
+
+2005-07-29 David Daney <ddaney@avtrex.com>
+
+ * elfxx-mips.c (_bfd_mips_elf_add_symbol_hook): Ignore _gp_disp
+ if it is in the *ABS* section.
+
+2005-07-29 Paul Brook <paul@codesourcery.com>
+
+ * reloc.c: Add BFD_RELOC_ARM_T32_ADD_PC12.
+ * bfd-in2.h: Regenerate.
+ * libbfd.h: Regenerate.
+
+2005-07-29 Paul Brook <paul@codesourcery.com>
+
+ * reloc.c (BFD_RELOC_ARM_T32_IMM12): Add.
+ * bfd-in2.h: Regeenrate.
+ * libbfd.h: Regenerate.
+
+2005-07-29 Pavel Kankovsky <peak@argo.troja.mff.cuni.cz>
+
+ * peXXigen.c (pe_print_edata): Compute the size of the export
+ table from the size field in the DataDictionary and not the size
+ of the section. Some linkers embed the export table inside a
+ larger section.
+
+2005-07-29 Alan Modra <amodra@bigpond.net.au>
+
+ * elf-bfd.h (struct elf_backend_data): Add action_discarded.
+ (enum action_discarded): Move from..
+ * elflink.c (enum action_discarded): ..here.
+ (_bfd_elf_default_action_discarded): Rename from elf_action_discarded.
+ Remove target specific section checks.
+ (elf_link_input_bfd): Adjust.
+ * elfxx-target.h (elf_backend_action_discarded): Define.
+ (elfNN_bed): Init new field.
+ * bfd-in.h (_bfd_elf_default_action_discarded): Declare.
+ * bfd-in2.h: Regenerate.
+ * elf-hppa.h (elf_hppa_action_discarded): New function.
+ * elf32-hppa.c (elf_backend_action_discarded): Define.
+ * elf64-hppa.c (elf_backend_action_discarded): Define.
+ * elf32-ppc.c (ppc_elf_action_discarded): New function.
+ (elf_backend_action_discarded): Define.
+
+2005-07-27 Alan Modra <amodra@bigpond.net.au>
+
+ * elflink.c (fix_syms): Handle symbols defined in input sections.
+
+2005-07-27 Jan Beulich <jbeulich@novell.com>
+
+ * elf64-x86-64.c (R_X86_64_standard, R_X86_64_vt_offset): New.
+ (elf64_x86_64_info_to_howto): Use them.
+
+2005-07-27 Alan Modra <amodra@bigpond.net.au>
+
+ * elflink.c (_bfd_elf_merge_symbol): Skip weak redefinition
+ regardless of strength of previous definition.
+
+2005-07-26 Alan Modra <amodra@bigpond.net.au>
+
+ * elflink.c (elf_gc_mark_dynamic_ref_symbol): Handle -shared.
+ (bfd_elf_gc_sections): Allow -gc-sections when -shared.
+ * elf32-ppc.c (ppc_elf_gc_sweep_hook): Correct for -shared.
+
+2005-07-26 Alan Modra <amodra@bigpond.net.au>
+
+ * elflink.c (elf_gc_sweep): Move gcc_except_table code..
+ (bfd_elf_gc_sections): ..to here.
+
+2005-07-25 DJ Delorie <dj@redhat.com>
+
+ * reloc.c: Remove unused M32C relocs, add BFD_RELOC_M32C_HI8.
+ * libbfd.h: Regenerate.
+ * bfd-in2.h: Regenerate.
+
+ * elf32-m32c.c (m32c_elf_howto_table): Add R_M32C_8, R_M32C_LO16,
+ R_M32C_HI8, R_M32C_HI16.
+ (m32c_reloc_map): Likewise.
+ (m32c_elf_relocate_section): Add R_M32C_HI8 and R_M32C_HI16.
+
+2005-07-25 Jan Hubicka <jh@suse.cz>
+ H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf-bfd.h (_bfd_elf_large_com_section): New.
+ * elf.c (_bfd_elf_large_com_section): New. Defined.
+
+ * elf64-x86-64.c (elf64_x86_64_add_symbol_hook): New.
+ (elf64_x86_64_elf_section_from_bfd_section): New.
+ (elf64_x86_64_symbol_processing): New.
+ (elf64_x86_64_common_definition): New.
+ (elf64_x86_64_common_section_index): New.
+ (elf64_x86_64_common_section): New.
+ (elf64_x86_64_merge_symbol): New.
+ (elf64_x86_64_additional_program_headers): New.
+ (elf64_x86_64_special_sections): New.
+ (elf_backend_section_from_bfd_section): New. Defined.
+ (elf_backend_add_symbol_hook): Likewise.
+ (elf_backend_common_section_index): Likewise.
+ (elf_backend_common_section): Likewise.
+ (elf_backend_common_definition): Likewise.
+ (elf_backend_merge_symbol): Likewise.
+ (elf_backend_special_sections): Likewise.
+ (elf_backend_additional_program_headers): Likewise.
+
+2005-07-25 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf-bfd.h (elf_backend_data): Add common_definition,
+ common_section_index, common_section, and merge_symbol.
+ (_bfd_elf_common_definition): New.
+ (_bfd_elf_common_section_index): New.
+ (_bfd_elf_common_section): New.
+
+ * elf.c (elf_fake_sections): Don't clear sh_flags.
+
+ * elflink.c (_bfd_elf_merge_symbol): Call backend merge_symbol
+ if it is available.
+ (is_global_data_symbol_definition): Call backend
+ common_definition instead of checking SHN_COMMON.
+ (elf_link_add_object_symbols): Likewise.
+ (elf_link_output_extsym): Call backend common_section_index
+ for common section index.
+ (_bfd_elf_common_definition): New.
+ (_bfd_elf_common_section_index): New.
+ (_bfd_elf_common_section): New.
+
+ * elfxx-target.h (elf_backend_common_definition): New.
+ (elf_backend_common_section_index): New.
+ (elf_backend_common_section): New.
+ (elf_backend_merge_symbol): New.
+ (elfNN_bed): Initialize common_definition, common_section_index,
+ common_section, and merge_symbol.
+
+ * section.c (BFD_FAKE_SECTION): New.
+ (STD_SECTION): Use it.
+ * bfd-in2.h: Regenerated.
+
+2005-07-23 Olaf Hering <olh@suse.de>
+
+ * elflink.c (elf_link_input_bfd): Add '\n' for linker einfo
+ callback.
+
+2005-07-21 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * config.bfd: Remove i[3-7]86-*-rtemself*.
+ Remove sparc-*-rtemself*.
+
+2005-07-22 Kazuhiro Inaoka <inaoka.kazuhiro@renesas.com>
+
+ * elf32-m32r.c (m32r_elf_check_relocs): Fix pc count for
+ R_M32R_REL32.
+
+2005-07-21 Ben Elliston <bje@gnu.org>
+
+ * Makefile.am (BFD32_BACKENDS): Remove cf-m68klynx.lo.
+ (BFD32_BACKENDS): Likewise, remove m68klynx.lo.
+ (BFD32_BACKENDS_CFILES): Remove cf-m68klynx.c, m68klynx.c.
+ (cf-m68klynx.lo, m68klynx.lo): Remove targets.
+ * Makefile.in: Regenerate.
+ * cf-m68klynx.c: Remove.
+ * m68klynx.c: Likewise.
+ * configure.in (m68klynx_aout_vec): Remove vector.
+ (m68klynx_coff_vec): Likewise.
+ * configure: Regenerate.
+ * targets.c (m68klynx_aout_vec): Remove extern.
+ (m68klynx_coff_vec): Likewise.
+ (_bfd_target_vector): Remove m68klynx_{aout,coff}_vec.
+ * po/SRC-POTFILES.in: Remove cf-m68klynx.c, m68klynx.c.
+
+2005-07-20 Kazuhiro Inaoka <inaoka.kazuhiro@renesas.com>
+
+ * elf32-m32r.c (m32r_elf_howto_table): Support R_M32R_REL32.
+ (m32r_reloc_map): Likewise.
+ (m32r_elf_relocate_section): Likewise.
+ (m32r_elf_gc_sweep_hook): Likewise.
+ (m32r_elf_check_relocs): Likewise.
+
+2005-07-18 Nick Clifton <nickc@redhat.com>
+
+ * reloc.c: Add M32C and MS1 relocs.
+ * bfd-in2.h: Regenerate.
+ * libbfd.h: Regenerate.
+
+2005-07-18 Nick Clifton <nickc@redhat.com>
+
+ * config.bfd: Move m32c entry to correct location.
+ * archures.c: Likewise.
+ * configure.in: Likewise.
+ * configure: Regenerate.
+ * targets.c: Move ms1 vector to correct location.
+
+2005-07-18 Jan Beulich <jbeulich@novell.com>
+
+ * elf32-i386.c (elf_howto_table): Adjust overflow complaint handler
+ for R_386_PC16.
+ * elf64-x86-64.c (x86_64_elf_howto_table): Adjust overflow complaint
+ handler for R_X86_64_PC16, R_X86_64_8, and R_X86_64_DTPOFF.
+
+2005-07-16 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR ld/1021
+ PR ld/1031
+ * elflink.c (elf_link_add_object_symbols): Also append the version
+ name to non-hidden absolute symbols that are functions.
+
+2005-07-16 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-ppc.c (ppc_elf_set_sdata_syms): Return void. Remove hack
+ for zero size sections. Don't set .sbss syms here.
+ * elf32-ppc.h (ppc_elf_set_sdata_syms): Adjust prototype.
+
+2005-07-16 Alan Modra <amodra@bigpond.net.au>
+
+ * Makefile.am: Run "make dep-am".
+ * Makefile.in: Regenerate.
+
+2005-07-15 Bob Wilson <bob.wilson@acm.org>
+
+ * elf32-xtensa.c (vsprint_msg): Add prototype.
+ (build_encoding_error_message): Delete. Code moved into....
+ (elf_xtensa_do_reloc): ....here, and changed to give better
+ error messages for out of range literals.
+
+2005-07-15 Alan Modra <amodra@bigpond.net.au>
+
+ * elflink.c (bfd_elf_record_link_assignment): Remove output_bfd param.
+ (_bfd_elf_provide_symbol): Allow redefinition of weak syms and those
+ defined in output sections. Call bfd_elf_record_link_assignment.
+ * bfd-in.h (bfd_elf_record_link_assignment): Update prototype.
+ * bfd-in2.h: Regenerate.
+
+2005-07-14 Jim Blandy <jimb@redhat.com>
+
+ Add support for m32c-*-elf (Renesas m32c and m16c).
+ * Makefile.am (ALL_MACHINES): Add cpu-m32c.lo.
+ (ALL_MACHINES_CFILES): Add cpu-m32c.c.
+ (BFD32_BACKENDS): Add elf32-m32c.lo.
+ (BFD32_BACKENDS_CFILES): Add elf32-m32c.c.
+ (cpu-m32c.lo, elf32-m32c.lo): New rules, generated by 'make dep-am'.
+ * Makefile.in: Regenerated.
+ * archures.c (bfd_arch_m32c, bfd_mach_m16c, bfd_mach_m32c): New
+ arch and mach codes.
+ (bfd_m32c_arch): New arch info object.
+ (bfd_archures_list): List bfd_m32c_arch.
+ * bfd-in2.h: Regenerated.
+ * config.bfd: Add case for the m32c.
+ * configure.in: Add case for the m32c.
+ * configure: Regenerated.
+ * cpu-m32c.c, elf32-m32c.c: New files.
+ * libbfd.h: Regenerated.
+ * targets.c (bfd_elf32_m32c_vec): Declare.
+ (_bfd_target_vector): List bfd_elf32_m32c_vec.
+
+2005-07-14 Alan Modra <amodra@bigpond.net.au>
+
+ * bfd-in.h (_bfd_elf_fix_excluded_sec_syms): Declare.
+ (_bfd_elf_provide_section_bound_symbols): Remove param name.
+ Formatting.
+ * bfd-in2.h: Regenerate.
+ * elflink.c (bfd_elf_gc_sections): Don't call generic function.
+ (_bfd_elf_provide_symbol): Formatting.
+ (_bfd_elf_provide_section_bound_symbols): Remove all hacks, just
+ create section relative syms.
+ (fix_syms, _bfd_elf_fix_excluded_sec_syms): New functions.
+ * elf32-ppc.c (ppc_elf_set_sdata_syms): Use
+ _bfd_elf_provide_section_bound_symbols.
+ * reloc.c (bfd_mark_used_section): Delete.
+ (bfd_generic_gc_sections): Don't call the above.
+
+2005-07-14 Paul Woegerer <paul.woegerer@nsc.com>
+
+ PR 1063
+ * cache.c (bfd_last_cache): Initialise to NULL.
+
+2005-07-14 Daniel Marques <marques@cs.cornell.edu>
+ Nick Clifton <nickc@redhat.com>
+
+ * coff-alpha.c (alpha_ecoff_bad_format_hook): Detect compressed
+ Alpha binaries and issue a helpful error message.
+ (alpha_ecoff_swap_reloc_out): Increase maximum allowed internal
+ symbol index to 15 to allow for binaries produced by DEC
+ compilers.
+
+2005-07-13 Steve Ellcey <sje@cup.hp.com>
+
+ * bfd.m4 (BFD_NEED_DECLARATION): Remove.
+
+2005-07-12 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (ppc64_elf_relocate_section): Don't use a plt stub
+ when !can_plt_call.
+
+2005-07-12 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-xtensa.c (bfd_elf_xtensa_reloc): Warning fix.
+
+2005-07-12 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-ppc.c (ppc_elf_set_sdata_syms): Correct __sbss_start value.
+
+2005-07-11 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elflink.c (_bfd_elf_symbol_refs_local_p): Revert the last
+ change.
+
+2005-07-08 Paul Koning <pkoning@equallogic.com>
+
+ * dwarf2.c (read_address): Check sign_extend_vma to handle targets
+ where addresses are sign extended.
+
+2005-07-08 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * config.bfd: Mark i960-*-rtems*, or32-*-rtems* as obsolete.
+ Mark a29k-*rtems*, hppa*-*-rtems*, *-go32-rtems*,
+ i[3-7]86*-*-rtemscoff*, mips*el-*-rtems*, powerpcle-*-rtems*,
+ sparc*-*-rtemsaout* as removed
+
+2005-07-08 Alan Modra <amodra@bigpond.net.au>
+
+ * elf-hppa.h (elf_hppa_final_link): Use gp val of zero when none
+ of the usual sections are found.
+ * elf-m10300.c (_bfd_mn10300_elf_size_dynamic_sections): Tidy.
+ Strip .dynbss if it is zero size.
+ * elf32-arm.c (elf32_arm_size_dynamic_sections): Likewise.
+ * elf32-cris.c (elf_cris_size_dynamic_sections): Likewise.
+ * elf32-hppa.c (elf32_hppa_size_dynamic_sections): Likewise.
+ * elf32-i370.c (i370_elf_size_dynamic_sections): Likewise, and
+ .dynsbss.
+ (i370_elf_finish_dynamic_sections): Don't attempt to write .got
+ when it is zero size.
+ * elf32-i386.c (elf_i386_size_dynamic_sections): Correct handling
+ of .dynbss and zero size sections.
+ * elf32-m32r.c (m32r_elf_size_dynamic_sections): Strip .dynbss if
+ it is zero size.
+ * elf32-m68k.c (elf_m68k_size_dynamic_sections): Tidy. Strip
+ .dynbss if zero size.
+ * elf32-ppc.c (ppc_elf_size_dynamic_sections): Likewise, .dynsbss
+ too.
+ * elf32-s390.c (elf_s390_size_dynamic_sections): Likewise.
+ * elf32-sh.c (sh_elf_size_dynamic_sections): Likewise.
+ * elf32-vax.c (elf_vax_size_dynamic_sections): Likewise.
+ * elf32-xtensa.c (elf_xtensa_size_dynamic_sections): Tidy. Strip
+ .plt.* and .got.plt.* if zero size.
+ * elf64-alpha.c (elf64_alpha_size_dynamic_sections): Tidy. Strip
+ .got* and .dynbss if zero size.
+ * elf64-hppa.c (elf64_hppa_size_dynamic_sections): Tidy. Strip
+ * elf64-ppc.c (create_linkage_sections): Create branch lookup table
+ in .data.rel.ro.brlt or .rodata.brlt, and similarly for associated
+ reloc section.
+ (create_got_section): Always create new .got and .rela.got sections.
+ (ppc64_elf_size_dynamic_sections): Tidy. Strip .dynbss if zero size.
+ * elf64-s390.c (elf_s390_size_dynamic_sections): Likewise.
+ * elf64-sh64.c (sh64_elf64_size_dynamic_sections): Likewise.
+ * elf64-x86-64.c (elf64_x86_64_size_dynamic_sections): Handle
+ dynamic bss sections correctly.
+ * elfxx-mips.c (_bfd_mips_elf_size_dynamic_sections): Tidy.
+ * elfxx-sparc.c (_bfd_sparc_elf_size_dynamic_sections): Tidy. Strip
+ .dynbss if zero size.
+
+2005-07-08 Ben Elliston <bje@au.ibm.com>
+
+ * elf32-xtensa.c: Include <stdarg.h> unconditionally, not only
+ when ANSI_PROTOTYPES is defined. Remove #ifdef logic.
+
+2005-07-07 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf-bfd.h (elf_backend_data): Add special_sections.
+
+ * elf.c (_bfd_elf_get_sec_type_attr): Check special_sections
+ first.
+
+ * elf32-arm.c (elf_backend_get_sec_type_attr): Removed.
+ (elf_backend_special_sections): New. Defined.
+ * elf32-m32r.c: Likewise.
+ * elf32-m68hc11.c: Likewise.
+ * elf32-m68hc12.c: Likewise.
+ * elf32-mcore.c: Likewise.
+ * elf32-sh64.c: Likewise.
+ * elf32-v850.c: Likewise.
+ * elf32-xtensa.c: Likewise.
+ * elf64-alpha.c: Likewise.
+ * elf64-hppa.c: Likewise.
+ * elf64-ppc.c: Likewise.
+ * elf64-sh64.c: Likewise.
+ * elfxx-ia64.c: Likewise.
+ * elfxx-mips.c: Likewise.
+ * elfxx-mips.h: Likewise.
+
+ * elfxx-target.h (elf_backend_special_sections): New.
+ (elfNN_bed): Initialize special_sections.
+
+2005-07-07 Bob Wilson <bob.wilson@acm.org>
+
+ * xtensa-modules.c: Update tables with Xtensa MMU features.
+
+2005-07-07 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * elf32-xtensa.c (vsprint_msg): Add format attribute. Fix
+ format bugs.
+ * vms.h (_bfd_vms_debug): Add format attribute.
+ (_bfd_vms_debug, _bfd_hexdump): Fix typos.
+
+2005-07-07 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR 975
+ * elflink.c (_bfd_elf_symbol_refs_local_p): Only undefined
+ symbol with default visibility is local.
+
+2005-07-07 Ben Elliston <bje@gnu.org>
+
+ * config.bfd: Mark m68*-*-rtemscoff as obsolete.
+
+2005-07-06 H.J. Lu <hongjiu.lu@intel.com>
+
+ * dwarf2.c (varinfo): Add addr.
+ (lookup_symbol_in_variable_table): Also check addr.
+ (scan_unit_for_symbols): Set addr for variable.
+ (comp_unit_find_line): Updated.
+
+2005-07-06 Nick Clifton <nickc@redhat.com>
+
+ * coff-alpha.c (alpha_adjust_reloc_in): Issue an informative error
+ message if an unknown reloc is encountered.
+ (alpha_relocate_section): Likewise.
+
+ * ecoff.c (_bfd_ecoff_write_object_contents): Cope with a reloc
+ with a missing howto field.
+
+2005-07-06 Alan Modra <amodra@bigpond.net.au>
+
+ * po/SRC-POTFILES.in: Add cpu-ms1.c, elf32-ms1.c, elf-vxworks.c,
+ elfxx-sparc.c.
+
+2005-07-05 Paul Brook <paul@codesourcery.com>
+
+ * elf32-ppc.c (ppc_elf_vxworks_special_sections): Remove.
+ (ppc_elf_vxworks_get_sec_type_attr): New function.
+ (elf_backend_special_sections): Remove vxwords definition.
+ (elf_backend_get_sec_type_attr): Define for vxworks.
+
+2005-07-05 Nick Clifton <nickc@redhat.com>
+
+ * elf64-ppc.c (ppc64_elf_info_to_howto): Fix typo.
+
+2005-07-05 Paul Brook <paul@codesourcery.com>
+
+ * config.bfd: Add separate case for ppc-vxworks.
+ * configure: Regenerate.
+ * configure.in: Include elf-vxworks.lo on ppc targets.
+ * elf-vxworks.c (elf_vxworks_final_write_processing): Handle
+ .rela.plt.unloaded.
+ * elf32-ppc.c: Add VxWorks target vec. Include elf-vxworks.h.
+ (PLT_ENTRY_SIZE, PLT_INITIAL_ENTRY_SIZE, PLT_SLOT_SIZE): Remove.
+ (VXWORKS_PLT_ENTRY_SIZE, ppc_elf_vxworks_plt_entry,
+ ppc_elf_vxworks_pic_plt_entry, VXWORKS_PLT_INITIAL_ENTRY_SIZE,
+ ppc_elf_vxworks_plt0_entry, ppc_elf_vxworks_pic_plt0_entry,
+ VXWORKS_PLT_NON_JMP_SLOT_RELOCS, VXWORKS_PLTRESOLVE_RELOCS,
+ VXWORKS_PLTRESOLVE_RELOCS_SHLIB): New.
+ (ppc_elf_link_hash_table): Add srelplt2, sgotplt, hgot, hplt,
+ is_vxworks, plt_entry_size, plt_slot_size, plt_initial_entry_size.
+ (ppc_elf_link_hash_table_create): Initialize hadtab plt fields.
+ (ppc_elf_create_got): Create .got.plt for VxWorks.
+ (ppc_elf_create_dynamic_sections): Create unloaded plt relocation
+ section for VxWorks.
+ (ppc_elf_select_plt_layout): Handle VxWorks plt format.
+ (allocate_got): VxWorks does not need a got header.
+ (allocate_dynrelocs): Handle VxWorks plt format.
+ (ppc_elf_size_dynamic_sections): Save _G_O_T_ and _P_L_T_ symbols for
+ VxWorks. Handle VxWorks plt/got.
+ (ppc_elf_finish_dynamic_sections): Fill in VxWorks plt.
+ (ppc_elf_vxworks_special_sections): New.
+ (ppc_elf_vxworks_link_hash_table_create,
+ ppc_elf_vxworks_add_symbol_hook,
+ elf_i386_vxworks_link_output_symbol_hook,
+ ppc_elf_vxworks_final_write_processing): New functions.
+ * targets.c (bfd_elf32_powerpc_vxworks_vec): Declare.
+ (_bfd_target_vector): Use it.
+
+2005-07-05 Jakub Jelinek <jakub@redhat.com>
+
+ * libbfd-in.h (struct artdata): Add extended_names_size field.
+ * libbfd.h: Rebuilt.
+ * coff-rs600.c (_bfd_xcoff_archive_p): Don't clear fields in freshly
+ allocated object by bfd_zalloc.
+ * coff64-rs6000.c (xcoff64_archive_p): Likewise.
+ * ecoff.c (_bfd_ecoff_archive_p): Likewise.
+ * archive.c (_bfd_generic_mkarchive, bfd_generic_archive_p): Likewise.
+ (get_extended_arelt_filename): Fail if index is bigger or equal to
+ extended_names_size.
+ (_bfd_generic_read_ar_hdr_mag): Don't set bfd_error_malformed_archive,
+ get_extended_arelt_filename already did that.
+ (_bfd_slurp_extended_name_table): Initialize extended_names_size field.
+ Allocate one extra byte and clear it, in case extended names table
+ is not terminated.
+
+ * libbfd-in.h (bfd_malloc2, bfd_realloc2, bfd_zmalloc2, bfd_alloc2,
+ bfd_zalloc2): New prototypes.
+ * bfd-in.h (HALF_BFD_SIZE_TYPE): Define.
+ * libbfd.c (bfd_malloc2, bfd_realloc2, bfd_zmalloc2): New functions.
+ * opncls.c (bfd_alloc2, bfd_zalloc2): New functions.
+ * elf.c (bfd_elf_get_elf_syms, setup_group, assign_section_numbers,
+ elf_map_symbols, map_sections_to_segments,
+ assign_file_positions_for_segments, copy_private_bfd_data,
+ swap_out_syms, _bfd_elf_slurp_version_tables): Use bfd_*alloc2
+ where appropriate.
+ * bfd-in2.h: Rebuilt.
+ * libbfd.h: Rebuilt.
+
+ * elf.c (_bfd_elf_print_private_bfd_data): Don't crash on bogus
+ verdef or verneed section.
+ (_bfd_elf_slurp_version_tables): Handle corrupt verdef and/or
+ verneed sections gracefully.
+ * elfxx-sparc.c (_bfd_sparc_elf_info_to_howto_ptr): Don't crash on
+ bogus relocation values.
+ * elf64-ppc.c (ppc64_elf_info_to_howto): Likewise.
+ * elf64-s390.c (elf_s390_info_to_howto): Likewise.
+ * elf32-s390.c (elf_s390_info_to_howto): Likewise.
+ * elf64-x86-64.c (elf64_x86_64_info_to_howto): Likewise.
+ * elfxx-ia64.c (lookup_howto): Likewise.
+
+ * elf.c (bfd_elf_get_str_section): Allocate an extra byte after
+ the end of strtab and clear it.
+ (elf_read): Remove.
+
+2005-07-05 Nick Clifton <nickc@redhat.com>
+
+ * po/vi.po: New Vietnamese translation.
+ * configure.in (ALL_LINGUAS): Add vi.
+ * configure: Regenerate.
+
+2005-07-05 Peter S. Mazinger <ps.m@gmx.net>
+
+ * elf32-arm.c (elf32_arm_size_dynamic_sections): Fix a typo and
+ touchup logic like i386/ppc.
+
+2005-07-05 Alan Modra <amodra@bigpond.net.au>
+
+ * elf.c (special_sections): Move const qualifier.
+ (special_sections_b..special_sections_t): Likewise.
+ * elf32-arm.c (elf32_arm_symbian_get_sec_type_attr): Remove duplicate
+ const.
+ (elf32_arm_symbian_special_sections): Move const qualifier.
+ * elf32-m32r.c: Similarly.
+ * elf32-m68hc11.c: Similarly.
+ * elf32-m68hc12.c: Similarly.
+ * elf32-mcore.c: Similarly.
+ * elf32-ppc.c: Similarly.
+ * elf32-sh64.c: Similarly.
+ * elf32-v850.c: Similarly.
+ * elf32-xtensa.c: Similarly.
+ * elf64-alpha.c: Similarly.
+ * elf64-hppa.c: Similarly.
+ * elf64-ppc.c: Similarly.
+ * elf64-sh64.c: Similarly.
+ * elfxx-ia64.c: Similarly.
+ * elfxx-mips.c: Similarly.
+
+2005-07-04 Kazuhiro Inaoka <inaoka.kazuhiro@renesas.com>
+
+ * elf32-m32r.c (m32r_elf_size_dynamic_sections): Use
+ info->executable instead of !info->shared where appropriate.
+
+2005-07-04 Alan Modra <amodra@bigpond.net.au>
+
+ PR 1042
+ * elf.c (assign_file_positions_for_segments): Remove excluded
+ sections from the segment map.
+
+2005-07-04 Alan Modra <amodra@bigpond.net.au>
+
+ PR 1004
+ * elf-bfd.h (struct elf_backend_data): Add get_sec_type_attr. Delete
+ special_sections.
+ (_bfd_elf_get_special_section): Declare.
+ (bfd_elf_special_section): Update prototype.
+ * elf.c (special_sections): Remove unused outer entries.
+ (get_special_section): Delete.
+ (_bfd_elf_get_special_section): New function.
+ (_bfd_elf_get_sec_type_attr): Replace "name" arg with "sec". Update
+ special_sections indexing.
+ (_bfd_elf_new_section_hook): Call backend get_sec_type_attr.
+ * elf32-arm.c (symbian_special_sections_d): Delete.
+ (symbian_special_sections_g, symbian_special_sections_h): Delete.
+ (symbian_special_sections_i, symbian_special_sections_f): Delete.
+ (symbian_special_sections_p): Delete.
+ (elf32_arm_symbian_special_sections): Merge above to here.
+ (elf32_arm_symbian_get_sec_type_attr): New function.
+ (elf_backend_special_sections): Don't define.
+ (elf_backend_get_sec_type_attr): Define.
+ * elf32-m32r.c: Similarly to elf32-arm.c.
+ * elf32-m68hc11.c: Likewise.
+ * elf32-m68hc12.c: Likewise.
+ * elf32-mcore.c: Likewise.
+ * elf32-sh64.c: Likewise.
+ * elf32-v850.c: Likewise.
+ * elf32-xtensa.c: Likewise.
+ * elf64-alpha.c: Likewise.
+ * elf64-hppa.c: Likewise.
+ * elf64-ppc.c: Likewise.
+ * elf64-sh64.c: Likewise.
+ * elfxx-ia64.c: Likewise.
+ * elfxx-mips.c: Likewise.
+ * elf32-ppc.c: Likewise.
+ (bfd_elf_special_section ppc_alt_plt): New. Use it if .plt loadable.
+ * elfxx-mips.h (_bfd_mips_elf_get_sec_type_attr): Declare.
+ (_bfd_mips_elf_special_sections, elf_backend_special_sections): Delete.
+ (elf_backend_get_sec_type_attr): Define.
+ * elfxx-target.h (elf_backend_get_sec_type_attr): Define.
+ (elf_backend_special_sections): Don't define.
+ (elfNN_bed): Update.
+
+2005-07-01 Nick Clifton <nickc@redhat.com>
+
+ * cpu-d10v.c: Update to ISO C90 style function declarations and
+ fix formatting.
+ * cpu-d30v.c: Likewsie.
+ * cpu-i370.c: Likewsie.
+ * cpu-xstormy16.c: Likewsie.
+ * elf32-arc.c: Likewsie.
+ * elf32-d10v.c: Likewsie.
+ * elf32-d30v.c: Likewsie.
+ * elf32-dlx.c: Likewsie.
+ * elf32-i370.c: Likewsie.
+ * elf32-i960.c: Likewsie.
+ * elf32-ip2k.c: Likewsie.
+ * elf32-m32r.c: Likewsie.
+ * elf32-mcore.c: Likewsie.
+ * elf32-openrisc.c: Likewsie.
+ * elf32-or32.c: Likewsie.
+ * elf32-pj.c: Likewsie.
+ * elf32-v850.c: Likewsie.
+ * elf32-xstormy16.c: Likewsie.
+
+2005-07-01 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-alpha.c (elf64_alpha_create_got_section): Always create
+ a new .got section.
+ (elf64_alpha_create_dynamic_sections): Always make new sections
+ by using bfd_make_section_anyway_with_flags. Check that .got not
+ already created.
+ (elf64_alpha_check_relocs): Delete "got_created". Use tdata->gotobj
+ instead.
+
+2005-06-30 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-ppc.c (ppc_elf_adjust_dynamic_symbol): Ignore dynamic
+ _SDA_BASE_ and _SDA2_BASE_ symbols.
+ * elflink.c (_bfd_elf_provide_symbol): Correct comment. Define
+ sym if not def_regular.
+ (_bfd_elf_provide_section_bound_symbols): Similarly.
+
+2005-06-30 Ben Elliston <bje@gnu.org>
+
+ * config.bfd: Mark as obsolete:
+ m68*-apollo-*
+ m68*-apple-aux*
+ m68*-bull-sysv*
+
+2005-06-29 Alan Modra <amodra@bigpond.net.au>
+
+ * elflink.c (_bfd_elf_gc_mark): Mark sections referenced by
+ .eh_frame specially..
+ (bfd_elf_gc_sections): ..rather than totally ignoring .eh_frame.
+ Don't recheck sections we have already marked.
+ (elf_gc_sweep): Keep non-code sections referenced from .eh_frame.
+ * section.c (struct bfd_section): Add gc_mark_from_eh.
+ (STD_SECTION): Adjust.
+ * ecoff.c (bfd_debug_section): Adjust.
+ * bfd-in2.h: Regenerate.
+
+2005-06-29 Alan Modra <amodra@bigpond.net.au>
+
+ * elflink.c (elf_gc_sweep): Do not refcount on sections that have
+ not been processed by check_relocs.
+
+2005-06-29 Paul Brook <paul@codesourcery.com>
+
+ * bfd-in.h (_bfd_elf_provide_symbol): Update prototype.
+ * bfd-in2.h: Regenerate.
+ * elf32-ppc.c (ppc_elf_set_sdata_syms): Make sdata symbols section
+ relative.
+ * elflink.c (bfd_elf_set_symbol): Add section argument.
+ (_bfd_elf_provide_symbol): Ditto.
+ (_bfd_elf_provide_section_bound_symbols): Pass NULL section argument.
+
+2005-06-27 Carlos O'Donell <carlos@systemhalted.org>
+
+ * elf32-hppa.c (struct elf32_hppa_stub_hash_entry):
+ Use bh_root, and hh.
+ (struct elf32_hppa_link_hash_entry): Use eh, and hsh_cache.
+ (struct elf32_hppa_dyn_reloc_entry): Use hdh_next.
+ (struct elf32_hppa_link_hash_table): Use etab and bstab.
+ (stub_hash_newfunc): Use hh.
+ (hppa_link_hash_newfunc): Use hsh_cache.
+ (elf32_hppa_link_hash_table_create): Use etab, and bstab.
+ (elf32_hppa_link_hash_table_free): Use bstab.
+ (hppa_stub_name): Use eh.
+ (hppa_get_stub_entry): Use hh, hsh_entry, and hsh_cache.
+ (hppa_add_stub): Use bstab.
+ (hppa_type_of_stub): Use eh.
+ (hppa_build_one_stub): Use hh and bh_root.
+ (elf32_hppa_copy_indirect_symbol): Use hdh_next.
+ (elf32_hppa_check_relocs): Use eh, etab, and hdh_next.
+ (elf32_hppa_gc_sweep_hook): Use hdh_next.
+ (elf32_hppa_adjust_dynamic_symbol): Use hdh_next, and etab.
+ (allocate_plt_static): Use etab.
+ (allocate_dynrelocs): Use etab, and hdh_next.
+ (readonly_dynrelocs): Use hdh_next.
+ (elf32_hppa_size_dynamic_sections): Use etab, and hdh_next.
+ (get_local_syms): Use eh, bstab, and hh.
+ (elf32_hppa_size_stubs): Use eh, bstab, and hh.
+ (elf32_hppa_set_gp): Use etab.
+ (elf32_hppa_build_stubs): Use bstab.
+ (final_link_relocate): Use eh, bh_root.
+ (elf32_hppa_relocate_section): Use elf, etab.
+ (elf32_hppa_finish_dynamic_sections): Use etab.
+
+2005-06-27 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elfxx-ia64.c (elfNN_hpux_backend_symbol_processing): Remove
+ the extra `;'.
+
+2005-06-21 Carlos O'Donell <carlos@systemhalted.org>
+
+ * elf32-hppa.c (hppa_elf_hash_entry): Define.
+ (hppa_stub_hash_entry): Define.
+ (stub_hash_newfunc): Rename variables.
+ (hppa_link_hash_newfunc): Likewise.
+ (elf32_hppa_link_hash_table_free): Likewise.
+ (hppa_stub_name): Likewise.
+ (hppa_get_stub_entry): Likewise.
+ (hppa_add_stub): Likewise.
+ (hppa_type_of_stub): Likewise.
+ (hppa_build_one_stub): Likewise.
+ (hppa_size_one_stub): Likewise.
+ (elf32_hppa_create_dynamic_sections): Likewise.
+ (elf32_hppa_copy_indirect_symbol): Likewise.
+ (elf32_hppa_check_relocs): Likewise.
+ (elf32_hppa_gc_mark_hook): Likewise.
+ (elf32_hppa_gc_sweep_hook): Likewise.
+ (elf32_hppa_grok_psinfo): Likewise.
+ (elf32_hppa_hide_symbol): Likewise.
+ (elf32_hppa_adjust_dynamic_symbol): Likewise.
+ (allocate_dynrelocs): Likewise.
+ (clobber_millicode_symbols): Likewise.
+ (readonly_dynrelocs): Likewise.
+ (elf32_hppa_size_dynamic_sections): Likewise.
+ (get_local_syms): Likewise.
+ (elf32_hppa_size_stubs): Likewise.
+ (hppa_record_segment_addr): Likewise.
+ (final_link_relocate): Likewise.
+ (elf32_hppa_relocate_section): Likewise.
+ (elf32_hppa_finish_dynamic_symbol): Likewise.
+
+2005-06-20 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR 1025
+ * elf-m10300.c (mn10300_elf_check_relocs): Handle indirect
+ symbol.
+ * elf32-arm.c (elf32_arm_check_relocs): Likewise.
+ * elf32-avr.c (elf32_avr_check_relocs): Likewise.
+ * elf32-cris.c (cris_elf_check_relocs): Likewise.
+ * elf32-d10v.c (elf32_d10v_check_relocs): Likewise.
+ * elf32-dlx.c (elf32_dlx_check_relocs): Likewise.
+ * elf32-fr30.c (fr30_elf_check_relocs): Likewise.
+ * elf32-frv.c (elf32_frv_check_relocs): Likewise.
+ * elf32-i370.c (i370_elf_check_relocs): Likewise.
+ * elf32-iq2000.c (iq2000_elf_check_relocs): Likewise.
+ * elf32-m32r.c (m32r_elf_check_relocs): Likewise.
+ * elf32-m68hc1x.c (elf32_m68hc11_check_relocs): Likewise.
+ * elf32-m68k.c (elf_m68k_check_relocs): Likewise.
+ * elf32-mcore.c (mcore_elf_check_relocs): Likewise.
+ * elf32-ms1.c (ms1_elf_check_relocs): Likewise.
+ * elf32-msp430.c (elf32_msp430_check_relocs): Likewise.
+ * elf32-openrisc.c (openrisc_elf_check_relocs): Likewise.
+ * elf32-ppc.c (ppc_elf_check_relocs): Likewise.
+ * elf32-s390.c (elf_s390_check_relocs): Likewise.
+ * elf32-sh.c (sh_elf_check_relocs): Likewise.
+ * elf32-v850.c (v850_elf_check_relocs): Likewise.
+ * elf32-vax.c (elf_vax_check_relocs): Likewise.
+ * elf64-mmix.c (mmix_elf_check_relocs): Likewise.
+ * elf64-ppc.c (ppc64_elf_check_relocs): Likewise.
+ * elf64-s390.c (elf_s390_check_relocs): Likewise.
+ * elf64-sh64.c (sh_elf64_check_relocs): Likewise.
+ * elfxx-mips.c (_bfd_mips_elf_check_relocs): Likewise.
+ * elfxx-sparc.c (_bfd_sparc_elf_check_relocs): Likewise.
+
+2005-06-20 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR 1022
+ * elf32-hppa.c (elf32_hppa_check_relocs): Handle indirect
+ symbol.
+
+2005-06-20 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR 1025
+ * elf32-i386.c (elf_i386_check_relocs): Handle indirect symbol.
+ * elf64-x86-64.c (elf64_x86_64_check_relocs): Likewise.
+
+2005-06-18 H.J. Lu <hongjiu.lu@intel.com>
+
+ * reloc.c: Add BFD_RELOC_X86_64_GOTOFF64 and
+ BFD_RELOC_X86_64_GOTPC32.
+ * bfd-in2.h: Regenerated.
+
+2005-06-17 Jakub Jelinek <jakub@redhat.com>
+
+ * elf.c (bfd_section_from_shdr): Kill bogus warning.
+
+ * elf.c (bfd_section_from_shdr): Fail if sh_entsize is bogus for
+ symbol, relocation, group or versym sections.
+
+ * coffcode.h (coff_slurp_reloc_table): Don't crash if native_relocs
+ is NULL.
+ * peXXigen.c (pe_print_idata): Don't crash if dll_name or start_address
+ doesn't point into the section.
+
+2005-06-17 Jan Beulich <jbeulich@novell.com>
+
+ * bfd-in2.h (elf_x86_64_reloc_type): Add BFD_RELOC_X86_64_GOTOFF64
+ and BFD_RELOC_X86_64_GOTPC32.
+ * libbfd.h (bfd_reloc_code_real_names): Likewise.
+ * elf64-x86-64.c (x86_64_elf_howto_table): Add entries for
+ R_X86_64_PC64, R_X86_64_GOTOFF64, and R_X86_64_GOTPC32.
+ (x86_64_reloc_map): Add entries for R_X86_64_PC64, R_X86_64_GOTOFF64,
+ and R_X86_64_GOTPC32.
+ (elf64_x86_64_info_to_howto): Adjust bounding relocation type.
+ (elf64_x86_64_check_relocs): Also handle R_X86_64_PC64,
+ R_X86_64_GOTOFF64, and R_X86_64_GOTPC32.
+ (elf64_x86_64_relocate_section): Likewise.
+ (elf64_x86_64_gc_sweep_hook): Also handle R_X86_64_PC64.
+
+2005-06-15 Mark Kettenis <kettenis@gnu.org>
+
+ * archive.c: Include "libiberty.h".
+
+2005-06-15 Nick Clifton <nickc@redhat.com>
+
+ * elf32-v850.c (ELF_MACHINE_ALT2): Define so that binaries
+ produced by the GreenHills toolchain can be assimilated.
+
+2005-06-14 Steve Ellcey <sje@cup.hp.com>
+
+ * som.c (som_find_inliner_info): New.
+
+2005-06-14 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elflink.c (_bfd_elf_merge_symbol): Fix a typo in comment.
+
+2005-06-14 Jakub Jelinek <jakub@redhat.com>
+
+ * elf.c (bfd_section_from_shdr): Fail if name is NULL.
+ Prevent endless recursion on broken objects.
+
+ * archive.c (do_slurp_coff_armap): Check for overflows.
+
+2005-06-10 Daniel Jacobowitz <dan@codesourcery.com>
+
+ * elfcode.h (elf_write_relocs): Do nothing if there are no
+ relocations.
+
+2005-06-10 Alan Modra <amodra@bigpond.net.au>
+
+ * dwarf2.c (decode_line_info): Revert last change. Instead set
+ initial low_pc to -1 to avoid need to test whether loc_pc has
+ been set.
+
+2005-06-09 Christopher Faylor <cgf@timesys.com>
+
+ * coffcode.h (sec_to_styp_flags): Set appropriate section flags when
+ either SEC_ALLOC OR SEC_LOAD.
+
+2005-06-09 Christopher Faylor <cgf@timesys.com>
+
+ * coffcode.h (sec_to_styp_flags): Remove read/write flags from noload
+ section header. Do not add STYP_NOLOAD since it does not appear to be
+ a valid PE flag.
+
+2005-06-09 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR 1000
+ * dwarf2.c (lookup_address_in_line_info_table): Restore code
+ handling NULL function info, removed with 2005-04-03 change.
+
+2005-06-08 Mark Mitchell <mark@codesourcery.com>
+
+ * opncls.c (bfd_fopen): Mark returned BFD as cacheable if FD == -1.
+
+2005-06-09 Alan Modra <amodra@bigpond.net.au>
+
+ * elflink.c (elf_mark_used_section): Delete.
+ (bfd_elf_gc_sections): Call bfd_generic_gc_sections.
+ * reloc.c (bfd_mark_used_section): New function.
+ (bfd_generic_gc_sections): Call bfd_mark_used_section.
+
+2005-06-08 Alan Modra <amodra@bigpond.net.au>
+
+ * opncls.c (bfd_fopen): Don't set bfd_error unconditionally.
+ (bfd_fdopenr): Same.
+
+2005-06-07 Mark Mitchell <mark@codesourcery.com>
+
+ * opncls.c (bfd_fdopenr): Add missing break statements.
+
+2005-06-07 Mark Mitchell <mark@codesourcery.com>
+
+ * opncls.c (bfd_fopen): New API.
+ (bfd_openr): Use it.
+ (bfd_fdopenr): Likewise.
+ * bfd-in2.h: Regenerated.
+
+2005-06-07 Aldy Hernandez <aldyh@redhat.com>
+ Michael Snyder <msnyder@redhat.com>
+ Stan Cox <scox@redhat.com>
+
+ * Makefile.am (ALL_MACHINES): Add ms1 support.
+ (ALL_MACHINES_CFILES): Same.
+ (BFD32_BACKENDS): Same.
+ (BFD32_BACKENDS_CFILES): Same.
+
+ * Makefile.in: Regenerate.
+
+ * archures.c (bfd_architecture): Add ms1 entries.
+ Externalize bfd_ms1_arch.
+ (bfd_archures_list): Add bfd_ms1_arch.
+
+ * bfd-in2.h: Regenerate.
+
+ * cpu-ms1.c: New file.
+
+ * elf32-ms1.c: New file.
+
+ * targets.c: Define extern of bfd_elf32_ms1_vec.
+ Add bfd_elf32_ms1_vec to _bfd_target_vector.
+
+ * configure.in: Add bfd_elf32_ms1_vec case.
+
+ * configure: Regenerate.
+
+ * config.bfd: Add ms1-*-elf to table.
+
+2005-06-07 Zack Weinberg <zack@codesourcery.com>
+
+ * coff-i386.c: Change md_apply_fix3 to md_apply_fix in comment.
+
+2005-06-07 Alan Modra <amodra@bigpond.net.au>
+
+ * coff-rs6000.c (rs6000coff_vec, pmac_xcoff_vec): Init _bfd_find_line.
+ * coff64-rs6000.c (rs6000coff64_vec, aix5coff64_vec): Likewise.
+
+2005-06-06 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR 990
+ * bfd.c (bfd_find_line): New.
+
+ * dwarf2.c (comp_unit): Add variable_table.
+ (funcinfo): Add file, line, and sec.
+ (varinfo): New.
+ (lookup_symbol_in_function_table): New.
+ (lookup_symbol_in_variable_table): New.
+ (scan_unit_for_functions): Renamed to ...
+ (scan_unit_for_symbols): This. Handle DW_TAG_entry_point and
+ DW_TAG_variable.
+ (comp_unit_find_nearest_line): Updated.
+ (comp_unit_find_line): New.
+ (_bfd_dwarf2_find_line): New.
+
+ * elf-bfd.h (_bfd_elf_find_line): New.
+ (_bfd_generic_find_line): New. Defined.
+
+ * elf.c (_bfd_elf_find_line): New.
+
+ * libbfd-in.h (_bfd_dwarf2_find_line): New.
+ (_bfd_generic_find_line): New.
+
+ * bfd-in2.h: Regenerated.
+ * libbfd.h: Likewise.
+
+ * libbfd.c (_bfd_generic_find_line): New.
+
+ * targets.c (BFD_JUMP_TABLE_SYMBOLS): Initialize _bfd_find_line
+ with _bfd_generic_find_line.
+ (bfd_target): Add _bfd_find_line.
+
+2005-06-06 H.J. Lu <hongjiu.lu@intel.com>
+
+ * dwarf2.c (decode_line_info): Properly set low_pc.
+
+2005-06-06 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-pcc.c (ppc64_elf_gc_mark_hook): For the local sym in .opd
+ case, include addend when indexing .opd section map.
+ (ppc64_elf_edit_opd): Add no_opd_opt param. Do nothing besides
+ clear opd_adjust array if no_opd_opt set. Tidy code.
+ Ignore zero size .opd. Check bfd_alloc return value.
+ (ppc_stub_name): Return immediately on bfd_malloc fail.
+ * elf64-ppc.h (ppc64_elf_edit_opd): Update prototype.
+
+2005-06-04 H.J. Lu <hongjiu.lu@intel.com>
+
+ * dwarf2.c (comp_unit): Fix a typo in comment.
+
+2005-06-03 Jan-Benedict Glaw <jbglaw@lug-owl.de>
+
+ * elf32-vax.c (rtype_to_howto): Remove PARAMS.
+ (reloc_type_lookup): Dito.
+ (elf_vax_discard_copies): Dito.
+ (elf_vax_instantiate_got_entries): Dito.
+ (elf_vax_link_hash_traverse): Dito.
+ (elf_vax_link_hash_newfunc): Dito.
+ (elf_vax_link_hash_table_create): Dito.
+ (elf32_vax_set_private_flags): Dito.
+ (elf32_vax_merge_private_bfd_data): Dito.
+ (elf32_vax_print_private_bfd_data): Dito.
+ (elf_vax_check_relocs): Dito.
+ (elf_vax_gc_mark_hook): Dito.
+ (elf_vax_gc_sweep_hook): Dito.
+ (elf_vax_size_dynamic_sections): Dito.
+ (elf_vax_discard_copies): Dito.
+ (elf_vax_instantiate_got_entries): Dito.
+ (elf_vax_relocate_section): Dito.
+ (elf_vax_finish_dynamic_symbol): Dito.
+ (elf_vax_finish_dynamic_sections): Dito.
+ (elf_vax_hash_table): Break-up of line isn't needed.
+ (elf_vax_check_relocs): Remove leading whitespace
+ (elf_vax_relocate_section): Remove redundant whitespace
+ (elf_vax_link_hash_newfunc): Don't cast NULL.
+ (elf_vax_link_hash_table_create): Dito.
+ * cpu-vax.c (bfd_vax_arch) Remove a trailing space.
+
+2005-06-03 Alan Modra <amodra@bigpond.net.au>
+
+ PR 568
+ * configure.in: Bump version
+ * configure: Regenerate.
+ * elflink.c (elf_link_input_bfd): Use einfo linker callback to print
+ discarded section sym refs and kill linker output.
+ * simple.c (simple_dummy_einfo): New function.
+ (bfd_simple_get_relocated_section_contents): Init callbacks.einfo.
+
+ * elf32-i386.c (elf_i386_relocate_section): Handle zero symndx
+ for all reloc types.
+
+2005-06-02 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (add_symbol_adjust): Set sym visibility to most
+ restrictive of func code and func descr for undefined syms as well
+ as defined.
+
+2005-05-31 Jim Blandy <jimb@redhat.com>
+
+ * Makefile.am: Regenerate dependencies with 'make dep-am'.
+ * Makefile.in: Regenerate.
+
+2005-05-31 Richard Henderson <rth@redhat.com>
+
+ * elf64-alpha.c (ALPHA_ELF_LINK_HASH_LU_JSRDIRECT): New.
+ (ALPHA_ELF_LINK_HASH_TLS_IE): Renumber to 0x80.
+ (ALPHA_ELF_LINK_HASH_LU_PLT): Rename from ALPHA_ELF_LINK_HASH_LU_FUNC.
+ (elf64_alpha_want_plt): Update to match.
+ (elf64_alpha_check_relocs): Collect JSRDIRECT in gotent_flags.
+ (elf64_alpha_relax_with_lituse): Likewise. Handle JSRDIRECT.
+
+2005-05-31 Zack Weinberg <zack@codesourcery.com>
+
+ * elf32-arm.c (elf32_arm_reloc_type_lookup)
+ (elf32_arm_nabi_grok_prstatus, elf32_arm_nabi_grok_psinfo):
+ Use ISO C90 function declaration style.
+
+2005-05-31 James E Wilson <wilson@specifixinc.com>
+
+ * elfcode.h (NAME(bfd_elf,bfd_from_remote_memory)): Check for program
+ header PF_R flag on PT_LOAD segments.
+
+2005-05-30 Richard Henderson <rth@redhat.com>
+
+ * elf64-alpha.c (elf64_alpha_relocate_section): Use dtp_base for
+ the zero index relocs produced by elf64_alpha_relax_tls_get_addr.
+
+2005-05-29 Richard Henderson <rth@redhat.com>
+
+ * configure.in (--enable-secureplt): New.
+ * elf64-alpha.c (INSN_LDA, INSN_LDAH, INSN_LDQ, INSN_BR): New.
+ (INSN_SUBQ, INSN_S4SUBQ, INSN_JMP): New.
+ (INSN_A, INSN_AB, INSN_ABC, INSN_ABO, INSN_AD): New.
+ (elf64_alpha_use_secureplt): New.
+ (OLD_PLT_HEADER_SIZE, OLD_PLT_ENTRY_SIZE): New.
+ (NEW_PLT_HEADER_SIZE, NEW_PLT_ENTRY_SIZE): New.
+ (PLT_HEADER_SIZE, PLT_ENTRY_SIZE): Conditionalize on secureplt.
+ (ALPHA_ELF_LINK_HASH_PLT_LOC): Remove.
+ (struct alpha_elf_link_hash_entry): Add plt_offset.
+ (PLT_HEADER_WORD1, PLT_HEADER_WORD2, PLT_HEADER_WORD3): Remove.
+ (PLT_HEADER_WORD4, PLT_ENTRY_WORD1, PLT_ENTRY_WORD2): Remove.
+ (PLT_ENTRY_WORD3): Remove.
+ (elf64_alpha_create_dynamic_sections): If secureplt, set SEC_READONLY
+ on .plt and create .got.plt.
+ (elf64_alpha_output_extsym): Remove .plt frobbing for symbol values.
+ (get_got_entry): Initialize plt_offset.
+ (elf64_alpha_want_plt): New.
+ (elf64_alpha_check_relocs): Use it.
+ (elf64_alpha_adjust_dynamic_symbol): Likewise. Don't allocate
+ plt entries here.
+ (elf64_alpha_calc_got_offsets_for_symbol): Don't report internal
+ error as user error.
+ (elf64_alpha_size_plt_section_1): Allocate one plt entry per
+ got subsection.
+ (elf64_alpha_size_plt_section): Size .got.plt section.
+ (elf64_alpha_size_rela_got_1): Don't allocate relocations if
+ plt entries used.
+ (elf64_alpha_size_dynamic_sections): Call elf64_alpha_size_plt_section.
+ Add PLTRO DYNAMIC entry.
+ (elf64_alpha_finish_dynamic_symbol): Generate secureplt format.
+ (elf64_alpha_finish_dynamic_sections): Likewise.
+
+2005-05-28 David Daney <ddaney@avtrex.com>
+
+ * elfxx-mips.c (_bfd_mips_elf_finish_dynamic_sections): Move
+ calculation of DT_RELSZ to occur after all dynamic relocations
+ are created.
+
+2005-05-28 Eli Zaretskii <eliz@gnu.org>
+
+ * configure.in: Add snprintf and vsnprintf to AC_CHECK_DECLS.
+ * config.in, configure: Regenerate.
+
+2005-05-26 Mark Kettenis <kettenis@gnu.org>
+ Maciej W. Rozycki <macro@linux-mips.org>
+
+ * elfxx-mips.c (_bfd_mips_elf_section_processing): Warn and
+ stop processing of options if one of invalid size is
+ encountered.
+ (_bfd_mips_elf_section_from_shdr): Likewise.
+ (_bfd_mips_elf_fake_sections): Reset the type of empty special
+ sections.
+
+2005-05-26 Richard Henderson <rth@redhat.com>
+
+ * elf64-alpha.c (struct alpha_elf_link_hash_entry): Remove
+ plt_old_section, plt_old_value.
+ (elf64_alpha_adjust_dynamic_symbol): Don't set it.
+ (elf64_alpha_size_plt_section_1): Don't use it.
+
+2005-05-26 Jakub Jelinek <jakub@redhat.com>
+
+ * elfcode.h (elf_object_p): Fail if e_shoff != 0, e_shnum == 0 and
+ first shdr has sh_size == 0. Fail if e_shnum is large to cause
+ arithmetic overflow when allocating the i_shdr array.
+ Sanity check sh_link and sh_info fields. Fix e_shstrndx sanity check.
+
+2005-05-25 Richard Henderson <rth@redhat.com>
+
+ * elf64-alpha.c: Update all function definitions to ISO C. Remove
+ all function prototypes; rearrange functions into def-use order.
+
+2005-05-25 Richard Henderson <rth@redhat.com>
+
+ * elf64-alpha.c (elf64_alpha_merge_gots): Fix gotent iteration
+ in the presence of deleting elements.
+ (elf64_alpha_size_got_sections): Zero dead got section size.
+
+2005-05-23 Fred Fish <fnf@specifixinc.com>
+
+ * dwarf2.c (struct dwarf2_debug): Add inliner_chain member.
+ (struct funcinfo): Add caller_func, caller_file, caller_line.
+ tag, and nesting_level members.
+ (lookup_address_in_function_table): Change first passed parameter
+ from "struct funcinfo *" to "struct comp_unit *".
+ (lookup_address_in_function_table): Dereference unit to find function
+ table.
+ (lookup_address_in_function_table): Traverse the function list to
+ create a chain of inlined functions back to the first non inlined
+ function.
+ (scan_unit_for_functions): Remember tag and nesting level. Handle
+ DW_AT_call_file and DW_AT_call_line.
+ (comp_unit_find_nearest_line): Adjust lookup_address_in_function_table
+ call to pass unit pointer instead of function table pointer. For
+ inlined functions, save pointer to the inliner chain.
+ (_bfd_dwarf2_find_nearest_line): Initialize inliner_chain to NULL.
+ (_bfd_dwarf2_find_inliner_info): New function that returns information
+ from the inliner chain after a call to bfd_find_nearest_line.
+
+ * bfd.c (bfd_find_inliner_info): Define using BFD_SEND.
+ * targets.c (BFD_JUMP_TABLE_SYMBOLS): Add entry for
+ NAME##_find_inliner_info.
+ (bfd_target): Add _bfd_find_inliner_info.
+ * bfd-in2.h: Regenerate.
+
+ * libbfd-in.h (_bfd_nosymbols_find_inliner_info): Define as
+ macro that always returns bfd_false.
+ (_bfd_dwarf2_find_inliner_info): Declare.
+ * libbfd.h: Regenerate.
+
+ * elf32-arm.c (elf32_arm_find_inliner_info): New function
+ that calls _bfd_dwarf2_find_inliner_info.
+ (bfd_elf32_find_inliner_info): Define to elf32_arm_find_inliner_info.
+
+ * elfxx-mips.c (_bfd_mips_elf_find_inliner_info): New function
+ that calls _bfd_dwarf2_find_inliner_info.
+ * elfxx-mips.h (_bfd_mips_elf_find_inliner_info): Declare.
+ * elfn32-mips.c (bfd_elf32_find_inliner_info): Define to
+ _bfd_mips_elf_find_inliner_info.
+ * elf64-mips.c (bfd_elf64_find_inliner_info): Ditto.
+ * elf32-mips.c (bfd_elf32_find_inliner_info): Ditto.
+
+ * elf.c (_bfd_elf_find_inliner_info): New function that calls
+ _bfd_dwarf2_find_inliner_info.
+ * elf-bfd.h (_bfd_elf_find_inliner_info): Declare.
+ * elfxx-target.h (bfd_elfNN_find_inliner_info): Define to
+ _bfd_elf_find_inliner_info.
+
+ * coffgen.c (coff_find_inliner_info): New function that
+ calls _bfd_dwarf2_find_inliner_info.
+ * libcoff-in.h (coff_find_inliner_info): Declare.
+ * libcoff.h: Regenerate.
+ * coff-rs6000.c (rs6000coff_vec): Add coff_find_inliner_info.
+ (pmac_xcoff_vec) Ditto.
+ * coff64-rs6000.c (rs6000coff64_vec): Ditto.
+ (aix5coff64_vec): Ditto.
+
+ * aout-target.h (MY_find_inliner_info): Define as
+ _bfd_nosymbols_find_inliner_info.
+ * aout-tic30.c (MY_find_inliner_info): Ditto.
+ * binary.c (binary_find_inliner_info): Ditto.
+ * i386msdos.c (msdos_find_inliner_info): Ditto.
+ * ihex.c (ihex_find_inliner_info): Ditto.
+ * libaout.h (aout_32_find_inliner_info): Ditto.
+ * libecoff.h (_bfd_ecoff_find_inliner_info): Ditto.
+ * mach-o.c (bfd_mach_o_find_inliner_info): Ditto.
+ * mmo.c (mmo_find_inliner_info): Ditto.
+ * nlm-target.h (nlm_find_inliner_info): Ditto.
+ * pef.c (bfd_pef_find_inliner_info): Ditto.
+ * ppcboot.c (ppcboot_find_inliner_info): Ditto.
+ * srec.c (srec_find_inliner_info): Ditto.
+ * tekhex.c (tekhex_find_inliner_info): Ditto.
+ * versados.c (versados_find_inliner_info): Ditto.
+ * xsym.c (bfd_sym_find_inliner_info): Ditto.
+
+ * ieee.c (ieee_find_inliner_info): New function that always
+ returns FALSE.
+ * oasys.c (oasys_find_inliner_info): Ditto.
+ * vms.c (vms_find_inliner_info): Ditto.
+
+2005-05-24 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-ppc.c (ppc_elf_check_relocs): For old gcc -fPIC code
+ force old plt layout.
+
+2005-05-22 Richard Henderson <rth@redhat.com>
+
+ * elf64-alpha.c (elf64_alpha_relax_section): Ignore non-allocated
+ sections.
+ (elf64_alpha_check_relocs): Likewise.
+ (elf64_alpha_relocate_section): Don't emit dynamic relocations to
+ non-allocated sections.
+
+2005-05-22 Richard Henderson <rth@redhat.com>
+
+ * elf64-alpha.c (elf64_alpha_relax_with_lituse): Relax jsr to
+ undefweak to use zero register. Call elf64_alpha_relax_got_load
+ if not all uses removed.
+ (elf64_alpha_relax_got_load): Relax undefweak to lda zero.
+ (elf64_alpha_relax_section): Handle undefweak symbols.
+ (elf64_alpha_calc_dynrel_sizes): Don't add relocs for undefweak.
+ (elf64_alpha_size_rela_got_1): Likewise.
+ (elf64_alpha_relocate_section): Likewise.
+
+2005-05-22 Richard Henderson <rth@redhat.com>
+
+ * elf64-alpha.c (elf64_alpha_relax_section): Only operate
+ on SEC_CODE sections.
+
+2005-05-22 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ * som.c (try_prev_fixup): Changed type of subspace_reloc_sizep to
+ unsigned int *.
+ (som_write_space_strings): Change type of tmp_space and p to char *.
+ (som_write_symbol_strings): Likewise. Also change type of comp to
+ char *comp[4].
+ (som_begin_writing): Change type of strings_size to unsigned int.
+ (som_finish_writing): Likewise.
+ (som_slurp_reloc_table): Change type of external_relocs to unsigned
+ char *.
+ * som.h (struct som_section_data_struct): Change type of reloc_stream
+ field to unsigned char *.
+
+2005-05-20 Daniel Jacobowitz <dan@codesourcery.com>
+
+ * elf32-i386.c (elf_i386_adjust_dynamic_symbol): Don't eliminate
+ copy relocations for VxWorks.
+
+2005-05-20 Daniel Jacobowitz <dan@codesourcery.com>
+
+ * elf32-ppc.c (struct ppc_elf_link_hash_entry): Add new field
+ has_sda_refs.
+ (ppc_elf_copy_indirect_symbol): Copy has_sda_refs.
+ (ppc_elf_check_relocs): Set has_sda_refs.
+ (ppc_elf_adjust_dynamic_symbol): Check has_sda_refs before eliminating
+ copy relocations. Use has_sda_refs to place variables in .sbss.
+ (ppc_elf_finish_dynamic_symbol): Use has_sda_refs to place variables in
+ .sbss.
+
+2005-05-20 Bob Wilson <bob.wilson@acm.org>
+
+ * elf32-xtensa.c (bfd_elf_xtensa_reloc): Make sure that
+ xtensa_default_isa is initialized.
+
+2005-05-20 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-ppc.c (allocate_dynrelocs): Correct plt offset assigned
+ for second and subsequent list entries. Only allocate multiple
+ glink stubs when shared or pie.
+ (ppc_elf_finish_dynamic_symbol): Break out early when only one
+ glink stub is needed.
+
+2005-05-19 Zack Weinberg <zack@codesourcery.com>
+
+ * Makefile.am: Have 'all' depend on 'info'.
+ * Makefile.in: Regenerate.
+
+2005-05-19 Alan Modra <amodra@bigpond.net.au>
+
+ * elf-bfd.h (struct elf_link_hash_table): Delete init_refcount and
+ init_offset. Add init_got_refcount, init_plt_refcount,
+ init_got_offset and init_plt_offset.
+ * elf.c (_bfd_elf_link_hash_newfunc): Adjust for above change.
+ (_bfd_elf_link_hash_hide_symbol): Likewise.
+ (_bfd_elf_link_hash_table_init): Likewise.
+ * elf32-hppa.c (elf32_hppa_hide_symbol): Likewise.
+ * elf64-ppc.c (ppc64_elf_link_hash_table_create): Likewise.
+ * elflink.c (_bfd_elf_adjust_dynamic_symbol): Likewise.
+ (bfd_elf_size_dynamic_sections): Likewise.
+ * elf32-ppc.c (GLINK_PLTRESOLVE): Now 16 insns.
+ (LWZU_0_X_12, LWZ_0_4_30, LWZ_0_X_12, LWZ_11_X_11, LWZ_11_X_30,
+ LWZ_12_4_12, LWZ_12_8_30, LWZ_12_X_12, SUB_11_11_30): Delete.
+ (ADDIS_12_12, BCL_20_31, LWZU_0_12, LWZ_0_12, LWZ_11_11, LWZ_11_30,
+ LWZ_12_12, MFLR_0, MFLR_12, MTLR_0, SUB_11_11_12): Define.
+ (struct plt_entry): New.
+ (ppc_elf_link_hash_table_create): Set new init_plt fields.
+ (ppc_elf_copy_indirect_symbol): Handle merge of plt plist. Don't
+ use _bfd_elf_link_hash_copy_indirect.
+ (update_plt_info, find_plt_ent): New functions.
+ (ppc_elf_check_relocs): Handle R_PPC_PLTREL24 with non-zero addend
+ and adjust for use of plt list rather than refcount.
+ (ppc_elf_gc_sweep_hook): Likewise.
+ (ppc_elf_tls_optimize): Likewise.
+ (ppc_elf_adjust_dynamic_symbol): Likewise.
+ (allocate_dynrelocs): Likewise.
+ (ppc_elf_relax_section): Likewise.
+ (ppc_elf_relocate_section): Likewise. Adjust R_PPC_PLTREL24 addends
+ when performing a relocatable link.
+ (ppc_elf_finish_dynamic_symbol): Likewise. Write .glink stubs here..
+ (ppc_elf_finish_dynamic_sections): ..rather than here. Use new
+ pic resolver stub.
+
+2005-05-19 Alan Modra <amodra@bigpond.net.au>
+
+ * elf.c (assign_file_positions_for_segments): Use maximum of
+ maxpagesize and section alignment when adjusting initial
+ segment offset and section offsets.
+
+2005-05-18 Zack Weinberg <zack@codesourcery.com>
+
+ * elf32-arm.c: Make all #ifndef OLD_ARM_ABI blocks
+ unconditional.
+
+2005-05-18 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf.c (group_signature): Undo the last change. Check if the
+ symbol table section is correct.
+
+2005-05-17 Zack Weinberg <zack@codesourcery.com>
+
+ * elf32-arm.c: Wherever possible, use official reloc names
+ from AAELF.
+ (elf32_arm_howto_table, elf32_arm_tls_gd32_howto)
+ (elf32_arm_tls_ldo32_howto, elf32_arm_tls_ldm32_howto)
+ (elf32_arm_tls_le32_howto, elf32_arm_tls_ie32_howto)
+ (elf32_arm_vtinherit_howto, elf32_arm_vtentry_howto)
+ (elf32_arm_pc11_howto, elf32_arm_thm_pc9_howto, elf32_arm_got_prel)
+ (elf32_arm_r_howto): Replace with elf32_arm_howto_table_1,
+ elf32_arm_howto_table_2, and elf32_arm_howto_table_3.
+ Add many new relocations from AAELF.
+ (elf32_arm_howto_from_type): Update to match.
+ (elf32_arm_reloc_map): Add entries for R_ARM_THM_JUMP24,
+ R_ARM_THM_JUMP11, R_ARM_THM_JUMP19, R_ARM_THM_JUMP8,
+ R_ARM_THM_JUMP6, R_ARM_GNU_VTINHERIT, and R_ARM_GNU_VTENTRY.
+ (elf32_arm_reloc_type_lookup): Use elf32_arm_howto_from_type.
+ (elf32_arm_final_link_relocate): Add support for
+ R_ARM_THM_JUMP24, R_ARM_THM_JUMP19, R_ARM_THM_JUMP6. Remove
+ case entries redundant with default.
+
+ * reloc.c: Reorganize ARM relocations. Add Thumb
+ assembler-internal relocations BFD_RELOC_ARM_T32_OFFSET_U8,
+ BFD_RELOC_ARM_T32_OFFSET_IMM, BFD_RELOC_ARM_T32_IMMEDIATE.
+ Add visible relocations BFD_RELOC_THUMB_PCREL_BRANCH7,
+ BFD_RELOC_THUMB_BRANCH20, BFD_RELOC_THUMB_BRANCH25.
+ Delete unused relocations BFD_RELOC_ARM_GOT12, BFD_RELOC_ARM_COPY.
+ * bfd-in2.h, libbfd.h: Regenerate.
+
+2005-05-17 Daniel Jacobowitz <dan@codesourcery.com>
+
+ * elf.c (_bfd_elf_write_object_contents): Check for non-NULL
+ elf_shstrtab.
+ * format.c (bfd_check_format_matches): Set output_has_begun
+ for both_direction.
+ * section.c (bfd_set_section_contents): Use bfd_write_p. Remove
+ special case for both_direction.
+
+2005-05-17 Nick Clifton <nickc@redhat.com>
+
+ * elf.c (group_signature): Check for a group section which is
+ actually a (corrupt) symbol table section in disguise and prevent
+ an infinite loop from occurring.
+
+2005-05-17 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elfxx-ia64.c (elfNN_ia64_relax_brl): Undo the change made on
+ 2005-02-16.
+
+2005-05-17 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elfxx-ia64.c (elfNN_ia64_relax_br): Keep the original
+ predicate on slot 0 only if slot 0 isn't br.
+
+2005-05-17 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR 797
+ * elf32-i386.c (elf_i386_size_dynamic_sections): Also remove
+ empty sdynbss section.
+ * elf64-x86-64.c (elf64_x86_64_size_dynamic_sections): Likewise.
+
+2005-05-17 Tavis Ormandy <taviso@gentoo.org>
+
+ * elf.c (bfd_section_from_shdr): Add sanity check when parsing
+ dynamic sections.
+
+2005-05-17 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-ppc.c (LIS_11. LIS_12): Define.
+ (LWZU_0_X_12, LWZ_0_X_12, LWZ_12_4_12, LWZ_12_X_12): Define.
+ (ppc_elf_finish_dynamic_sections): Provide non-pic plt call stub
+ for --data-plt when building non-pie executables.
+
+2005-05-17 Nick Clifton <nickc@redhat.com>
+
+ * elf32-arm.c (elf32_arm_final_link_relocate): Gracefully handle
+ the situation where a symbols's section is not known but a section
+ relative R_ARM_RELATIVE reloc has to be generated for the Symbian
+ OS.
+
+ * elf32-v850.c (v850_elf_relocate_section): Move code to test for
+ the presence of a symbol table to just before the symbol table is
+ actually used.
+
+2005-05-16 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR 834
+ * elfxx-ia64.c (elfNN_ia64_relax_br): New.
+ (elfNN_ia64_relax_section): Use it.
+
+2005-05-14 Mark Kettenis <kettenis@gnu.org>
+
+ * elflink.c (bfd_elf_size_dynamic_sections): Use lbasename instead
+ of basename.
+
+2005-05-14 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-ppc.c (ppc_elf_size_dynamic_sections): Set DT_PPC_GOT,
+ not DT_PPC_GLINK.
+ (ppc_elf_finish_dynamic_sections): Likewise.
+
+2005-05-13 Fred Fish <fnf@specifixinc.com>
+
+ * libbfd-in.h: Fix a comment typo, 'neaderst' -> 'nearest'
+ * libbfd.h: Rebuilt.
+
+2005-05-13 Bob Wilson <bob.wilson@acm.org>
+
+ * elf32-xtensa.c (xtensa_get_property_section_name): Add missing
+ periods in linkonce_kind values.
+
+2005-05-12 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf32-i386.c (elf_i386_relocate_section): Allow R_386_GOTOFF
+ against protected function when building executable.
+
+2005-05-12 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-ppc.c (LWZU_0_X_11): Delete.
+ (B, LWZ_11_X_11, LWZ_11_X_30, MTCTR_11): Define.
+ (ppc_elf_select_plt_layout): Set .got flags too. Formatting.
+ (ppc_elf_size_dynamic_sections): Allocate space for .glink branch
+ table.
+ (ppc_elf_finish_dynamic_symbol): Point .plt entries into the branch
+ table.
+ (ppc_elf_finish_dynamic_sections): Adjust DT_PPC_GLINK value.
+ Generate .glink branch table and updated stubs.
+
+2005-05-11 Alan Modra <amodra@bigpond.net.au>
+
+ * reloc.c (BFD_RELOC_HI16_PCREL): Define.
+ (BFD_RELOC_HI16_S_PCREL, BFD_RELOC_LO16_PCREL): Define.
+ * elf32-ppc.c (GLINK_PLTRESOLVE, GLINK_ENTRY_SIZE): Define.
+ (CROR_151515, CROR_313131): Delete.
+ (ADDIS_11_11, ADDI_11_11, SUB_11_11_30, ADD_0_11_11, ADD_11_0_11,
+ LWZ_0_4_30, MTCTR_0, LWZ_12_8_30, BCTR, ADDIS_11_30,
+ LWZU_0_X_11): Define.
+ (ppc_elf_howto_raw): Add R_PPC_REL16, R_PPC_REL16_LO, R_PPC_REL16_HI
+ and R_PPC_REL16_HA entries.
+ (ppc_elf_reloc_type_lookup): Convert new bfd reloc types.
+ (ppc_elf_addr16_ha_reloc): Also handle R_PPC_REL16_HA.
+ (struct ppc_elf_link_hash_table): Add glink, glink_pltresolve,
+ new_plt, and old_plt.
+ (ppc_elf_create_dynamic_sections): Create .glink section.
+ (ppc_elf_check_relocs): Set new_plt and old_plt.
+ (ppc_elf_select_plt_layout): New function.
+ (ppc_elf_tls_setup): Set plt output section elf type and flags.
+ (allocate_got): Handle differences between old and new got layout.
+ (allocate_dynrelocs): Likewise for plt.
+ (ppc_elf_size_dynamic_sections): Likewise. Allocate memory for
+ .glink. Don't allocate memory for old bss .plt. Emit DT_PPC_GLINK.
+ (ppc_elf_relax_section): Rename ppc_info to htab. Handle .glink
+ destination of R_PPC_PLTREL24 relocs.
+ (ppc_elf_relocate_section): Handle new relocs and changed destination
+ of R_PPC_PLTREL24.
+ (ppc_elf_finish_dynamic_symbol): Init new style plt and handle
+ differences in layout.
+ (ppc_elf_finish_dynamic_sections): Set DT_PPC_GLINK value. Don't
+ put a blrl in new got. Write glink contents.
+ * elf32-ppc.h (ppc_elf_select_plt_layout): Declare.
+ * libbfd.h: Regenerate.
+ * bfd-in2.h: Regenerate.
+
+2005-05-11 Andreas Schwab <schwab@suse.de>
+
+ * elf32-i386.c (elf_i386_finish_dynamic_sections): Fix signedness
+ warning.
+
+2005-05-10 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf.c (_bfd_elf_make_section_from_shdr): Only check debug
+ section if SEC_ALLOC isn't set.
+
+2005-05-09 Kelley Cook <kcook@gcc.gnu.org>
+
+ * configure.in: Replace AC_COMPILE_CHECK_SIZEOF with AC_CHECK_SIZEOF.
+ * acinclude.m4: Don't sinclude accross.m4.
+ * config.in, configure, Makefile.in, doc/Makefile.in: Regenerate.
+
+2005-05-09 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (struct ppc64_elf_obj_tdata): Add has_dotsym.
+ (ppc64_elf_add_symbol_hook): Set has_dotsym.
+ (ppc64_elf_check_directives): Only process syms when has_dotsym.
+ (func_desc_adjust): Hide fake function descriptors when function
+ code entry is defined.
+ (adjust_opd_syms): Adjust for deleted_section becoming union field.
+
+2005-05-09 Alan Modra <amodra@bigpond.net.au>
+
+ * elfcode.h (elf_object_p): Add more sanity checks on elf header.
+
+2005-05-08 Dave Korn <dave.korn@artimi.com>
+
+ * coff-tic80.c: Undefine _CONST after system headers to prevent
+ clash with tic80-specific definition in include/coff/tic80.h
+
+2005-05-08 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR 939
+ * elflink.c (elf_link_output_extsym): Use output_bfd if
+ h->root.u.def.section is bfd_abs_section_ptr when reporting
+ error.
+
+2005-05-07 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf-bfd.h (elf_backend_data): Update special_sections to
+ array of pointer to bfd_elf_special_section.
+ * elf.c (special_sections): Likewise.
+ * elf32-arm.c (elf32_arm_symbian_special_sections): Likewise.
+ * elf32-m32r.c (m32r_elf_special_sections): Likewise.
+ * elf32-m68hc11.c (elf32_m68hc11_special_sections): Likewise.
+ * elf32-m68hc12.c (elf32_m68hc12_special_sections): Likewise.
+ * elf32-mcore.c (mcore_elf_special_sections): Likewise.
+ * elf32-ppc.c (ppc_elf_special_sections): Likewise.
+ * elf32-sh64.c (sh64_elf_special_sections): Likewise.
+ * elf32-v850.c (v850_elf_special_sections): Likewise.
+ * elf32-xtensa.c (elf_xtensa_special_sections): Likewise.
+ * elf64-alpha.c (elf64_alpha_special_sections): Likewise.
+ * elf64-hppa.c (elf64_hppa_special_sections): Likewise.
+ * elf64-ppc.c (ppc64_elf_special_sections): Likewise.
+ * elf64-sh64.c (sh64_elf64_special_sections): Likewise.
+ * elfxx-ia64.c (elfNN_ia64_special_sections): Likewise.
+ * elfxx-mips.c (_bfd_mips_elf_special_sections): Likewise.
+ * elfxx-mips.h (_bfd_mips_elf_special_sections): Likewise.
+
+ * elf.c (get_special_section): Updated.
+
+2005-05-07 Alan Modra <amodra@bigpond.net.au>
+
+ * elf-bfd.h (struct elf_backend_data): Remove got_symbol_offset.
+ * elfxx-target.h (elf_backend_got_symbol_offset): Delete.
+ * elflink.c (_bfd_elf_create_got_section): Use zero in place of
+ got_symbol_offset.
+ * elf-m10300.c (_bfd_mn10300_elf_create_got_section): Likewise.
+ * elf32-frv.c (_frv_create_got_section): Likewise.
+ * elf32-i370.c (i370_elf_finish_dynamic_sections): Delete ppc code.
+ (elf_backend_got_symbol_offset): Don't define.
+ * elf64-ppc.c (elf_backend_got_symbol_offset): Don't define.
+ * elf32-ppc.c (struct ppc_elf_link_hash_table): Add got_header_size
+ and got_gap.
+ (ppc_elf_create_got): Tidy.
+ (ppc_elf_create_dynamic_sections): Don't set SEC_IN_MEMORY for .plt.
+ (ppc_elf_check_relocs): Reduce string comparisons by using elf.hgot.
+ (ppc_elf_gc_sweep_hook): Likewise.
+ (ppc_elf_relocate_section): Likewise.
+ (ppc_elf_finish_dynamic_symbol): Likewise.
+ (allocate_got): New function.
+ (allocate_dynrelocs): Use allocate_got.
+ (ppc_elf_size_dynamic_sections): Likewise. Delay tlsld_got allocation
+ so that local got can refcount it. Set got_header_size.
+ (ppc_elf_relocate_section): Use value of elf.hgot rather than hard-
+ coded 4.
+ (ppc_elf_finish_dynamic_sections): Likewise.
+ (elf_backend_got_symbol_offset): Don't define.
+ (elf_backend_got_header_size): Ditto.
+
+2005-05-05 Steve Ellcey <sje@cup.hp.com>
+
+ * configure.in (ACX_HEADER_STRING): New.
+ * configure: Regenerate.
+ * config.in: Regenerate.
+ * sysdep.h (STRING_WITH_STRINGS): Use.
+
+2005-05-05 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf.c (_bfd_elf_close_and_cleanup): Only call
+ _bfd_dwarf2_cleanup_debug_info on bfd_object.
+
+2005-05-05 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elflink.c (_bfd_elf_provide_section_bound_symbols): Use
+ "__bss_start" instead of "_edata" as fallback.
+
+2005-05-05 H.J. Lu <hongjiu.lu@intel.com>
+
+ * bfd-in2.h: Regenerated.
+
+2005-05-05 Paul Brook <paul@codesourcery.com>
+
+ * config.bfd: Use bfd_elf32_i386_vxworks_vec for i?86-*-vxworks.
+ * configure.in: Add bfd_elf32_i386_vxworks_vec. i386 targets need
+ elf-vxworks.lo.
+ * configure: Regenerate.
+ * Makefile.am (BFD32_BACKENDS): Add elf-vxworks.lo.
+ (BFD32_BACKENDS_CFILES): Add elf-vxworks.c.
+ (elf32-i386.lo): Depend on elf-vxworks.h.
+ (elf-vxworks.lo): New rule.
+ * Makefile.in: Regenerate.
+ * elf-bfd.h (elf_backend_data): Update type of
+ elf_backend_emit_relocs.
+ (_bfd_elf_link_output_relocs): Update prototype.
+ * elflink.c (_bfd_elf_link_output_relocs): Always use
+ bed->elf_backend_emit_relocs when outputting relocations.
+ * elfxx-target.h (elf_backend_emit_relocs): Default to
+ _bfd_elf_link_output_relocs.
+ * targets.c (bfd_elf32_i386_vxworks_vec): Declare.
+ (_bfd_target_vector): Add bfd_elf32_i386_vxworks_vec.
+ * elf32-i386.c: Add elf32-i386-vxworks target BFD.
+ (elf_i386_plt0_entry): Remove padding.
+ (elf_i386_pic_plt0_entry): Ditto.
+ (PLTRESOLVE_RELOCS_SHLIB, PLTRESOLVE_RELOCS): Define.
+ (PLT_NON_JUMP_SLOT_RELOCS): Define.
+ (elf_i386_link_hash_table): Add srelplt2, hgot, hplt, is_vxworks and
+ plt0_pad_byte fields.
+ (elf_i386_link_hash_table_create): Zero them.
+ (elf_i386_create_dynamic_sections): Create static relocation section.
+ (allocate_dynrelocs): Allocate space for static PLT relocations.
+ (elf_i386_size_dynamic_sections): Save shortcuts to PLT and GOT
+ symbols. Give PLT symbols function type. Don't strip PLT sections
+ if we have exported symbols from them.
+ (elf_i386_finish_dynamic_symbol): Fill in VxWorks PLT static
+ relocation section. Don't mark _GLOBAL_OFFSET_TABLE_ as absolute on
+ VxWorks.
+ (elf_i386_finish_dynamic_sections): Allow different pad bytes.
+ Add relocation for GOT location. Fill in PLT static relocations.
+ (elf_i386_vxworks_link_hash_table_create): New function.
+ (elf_i386_vxworks_link_output_symbol_hook): New function.
+ * elf-vxworks.h: New file.
+
+2005-05-05 H.J. Lu <hongjiu.lu@intel.com>
+
+ * section.c (bfd_make_section_anyway_with_flags): New.
+ (bfd_make_section_anyway): Call bfd_make_section_anyway_with_flags,
+ (bfd_make_section_with_flags): New.
+ (bfd_make_section): Call bfd_make_section_with_flags.
+
+ * elf-m10300.c (_bfd_mn10300_elf_create_got_section): Call
+ bfd_make_section_with_flags/bfd_make_section_anyway_with_flags
+ instead of bfd_make_section/bfd_make_section and don't call
+ bfd_set_section_flags.
+ (mn10300_elf_check_relocs): Likewise.
+ (_bfd_mn10300_elf_create_dynamic_sections): Likewise.
+ * elf32-arm.c (create_got_section): Likewise.
+ (bfd_elf32_arm_add_glue_sections_to_bfd): Likewise.
+ (elf32_arm_check_relocs): Likewise.
+ * elf32-cris.c (cris_elf_check_relocs): Likewise.
+ * elf32-frv.c (elf32_frv_add_symbol_hook): Likewise.
+ (_frv_create_got_section): Likewise.
+ (elf32_frvfdpic_create_dynamic_sections): Likewise.
+ * elf32-hppa.c (elf32_hppa_create_dynamic_sections): Likewise.
+ (elf32_hppa_check_relocs): Likewise.
+ * elf32-i370.c (i370_elf_create_dynamic_sections): Likewise.
+ (i370_elf_check_relocs): Likewise.
+ * elf32-i386.c (create_got_section): Likewise.
+ (elf_i386_check_relocs): Likewise.
+ * elf32-m32r.c (m32r_elf_add_symbol_hook): Likewise.
+ (create_got_section): Likewise.
+ (m32r_elf_create_dynamic_sections): Likewise.
+ (m32r_elf_check_relocs): Likewise.
+ * elf32-m68k.c (elf_m68k_check_relocs): Likewise.
+ * elf32-ppc.c (ppc_elf_create_got): Likewise.
+ (ppc_elf_create_dynamic_sections): Likewise.
+ (ppc_elf_add_symbol_hook): Likewise.
+ (ppc_elf_check_relocs): Likewise.
+ * elf32-s390.c (create_got_section): Likewise.
+ (elf_s390_check_relocs): Likewise.
+ * elf32-sh.c (create_got_section): Likewise.
+ (sh_elf_create_dynamic_sections): Likewise.
+ (sh_elf_check_relocs): Likewise.
+ * elf32-vax.c (elf_vax_check_relocs): Likewise.
+ * elf32-xstormy16.c (xstormy16_elf_check_relocs): Likewise.
+ * elf32-xtensa.c (elf_xtensa_create_dynamic_sections): Likewise.
+ (add_extra_plt_sections): Likewise.
+ * elf64-alpha.c (elf64_alpha_add_symbol_hook): Likewise.
+ (elf64_alpha_create_got_section): Likewise.
+ (elf64_alpha_create_dynamic_sections): Likewise.
+ (elf64_alpha_check_relocs): Likewise.
+ * elf64-hppa.c (get_reloc_section): Likewise.
+ (get_opd): Likewise.
+ (get_plt): Likewise.
+ (get_dlt): Likewise.
+ (get_stub): Likewise.
+ (elf64_hppa_create_dynamic_sectionso): Likewise.
+ * elf64-mmix.c (mmix_elf_check_common_relocs): Likewise.
+ * elf64-ppc.c (create_linkage_sections): Likewise.
+ (ppc64_elf_check_relocs): Likewise.
+ * elf64-s390.c (create_got_section): Likewise.
+ (elf_s390_check_relocs): Likewise.
+ * elf64-sh64.c (sh_elf64_check_relocs): Likewise.
+ (sh64_elf64_create_dynamic_sections): Likewise.
+ * elf64-x86-64.c (create_got_section): Likewise.
+ (elf64_x86_64_check_relocs): Likewise.
+ * elflink.c (_bfd_elf_create_got_section): Likewise.
+ (_bfd_elf_link_create_dynamic_sections): Likewise.
+ (elf_link_add_object_symbols): Likewise.
+ * elfxx-ia64.c (elfNN_ia64_add_symbol_hook): Likewise.
+ (elfNN_ia64_create_dynamic_sections): Likewise.
+ (get_fptr): Likewise.
+ (get_pltoff): Likewise.
+ (get_reloc_section): Likewise.
+ (elfNN_ia64_object_p): Likewise.
+ * elfxx-mips.c (mips_elf_rel_dyn_section): Likewise.
+ (mips_elf_create_compact_rel_section): Likewise.
+ (mips_elf_create_got_section): Likewise.
+ (_bfd_mips_elf_create_dynamic_sections): Likewise.
+ * elfxx-sparc.c (create_got_section): Likewise.
+ (_bfd_sparc_elf_check_relocs): Likewise.
+
+ * elf.c (_bfd_elf_new_section_hook): Call _bfd_elf_get_sec_type_attr
+ on linker created sections.
+
+2005-05-05 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR 882
+ * elflink.c (_bfd_elf_link_assign_sym_version): Allow version
+ script on executable.
+
+2005-05-05 John Levon <levon@movementarian.org>
+
+ * dwarf2.c (read_abbrevs): If bfd_realloc fails, free currently
+ allocated memory before returning.
+ (decode_line_info): Likewise.
+ (_bfd_dwarf2_cleanup_debug_info): New function: Frees memory
+ allocated by functions in this file.
+ * elf-bfd.h (_bfd_dwarf2_cleanup_debug_info): Prototype.
+ * elf.c (_bfd_elf_close_and_cleanup): Call
+ _bfd_dwarf2_cleanup_debug_info.
+
+2005-05-05 Hans-Peter Nilsson <hp@axis.com>
+
+ * Makefile.am (INCLUDES): Don't -D_GNU_SOURCE here.
+ * configure.in: Call AC_GNU_SOURCE here, after AC_PROG_CC.
+ * configure, config.in, Makefile.in: Regenerate.
+ * sysdep.h (stpcpy): Revert last change.
+
+2005-05-05 Hans-Peter Nilsson <hp@axis.com>
+
+ * sysdep.h (stpcpy): Wrap declaration in parentheses.
+
+2005-05-04 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elfxx-ia64.c (ARCH_SIZE): New.
+ (LOG_SECTION_ALIGN): Likewise.
+ (elfNN_ia64_create_dynamic_sections): Use LOG_SECTION_ALIGN to
+ align relocation sections.
+ (get_fptr): Likewise.
+ (get_reloc_section): Likewise.
+ (elfNN_ia64_tprel_base): Likewise.
+ (elfNN_ia64_check_relocs): Support 32bit relocations.
+ (allocate_global_fptr_got): Likewise.
+ (allocate_dynrel_entries): Likewise.
+ (set_got_entry): Likewise.
+ (set_pltoff_entry): Likewise.
+ (elfNN_ia64_relocate_section): Likewise.
+
+2005-05-04 H.J. Lu <hongjiu.lu@intel.com>
+
+ * configure.in: Add AC_CHECK_DECLS(stpcpy).
+ * configure: Regenerate.
+ * config.in: Likewise.
+
+ * sysdep.h (stpcpy): New.
+
+2005-05-04 Nick Clifton <nickc@redhat.com>
+
+ * Update the address and phone number of the FSF organization in
+ the GPL notices in the following files:
+ aix386-core.c, aix5ppc-core.c, aout-adobe.c, aout-arm.c,
+ aout-cris.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, archive64.c, archures.c, armnetbsd.c, bfd-in.h,
+ bfd-in2.h, bfd.c, bfdio.c, bfdwin.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-ia64.c, coff-m68k.c, coff-m88k.c, coff-maxq.c,
+ coff-mcore.c, coff-mips.c, coff-or32.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-tic4x.c, coff-tic54x.c,
+ coff-tic80.c, coff-u68k.c, coff-w65.c, coff-we32k.c, coff-z8k.c,
+ coff64-rs6000.c, coffcode.h, coffgen.c, cofflink.c, coffswap.h,
+ corefile.c, cpu-a29k.c, cpu-alpha.c, cpu-arc.c, cpu-arm.c,
+ cpu-avr.c, cpu-cr16c.c, cpu-cris.c, cpu-crx.c, cpu-d10v.c,
+ cpu-d30v.c, cpu-dlx.c, cpu-fr30.c, cpu-frv.c, cpu-h8300.c,
+ cpu-h8500.c, cpu-hppa.c, cpu-i370.c, cpu-i386.c, cpu-i860.c,
+ cpu-i960.c, cpu-ia64-opc.c, cpu-ia64.c, cpu-ip2k.c, cpu-iq2000.c,
+ cpu-m10200.c, cpu-m10300.c, cpu-m32r.c, cpu-m68hc11.c,
+ cpu-m68hc12.c, cpu-m68k.c, cpu-m88k.c, cpu-maxq.c, cpu-mcore.c,
+ cpu-mips.c, cpu-mmix.c, cpu-msp430.c, cpu-ns32k.c, cpu-openrisc.c,
+ cpu-or32.c, cpu-pdp11.c, cpu-pj.c, cpu-powerpc.c, cpu-rs6000.c,
+ cpu-s390.c, cpu-sh.c, cpu-sparc.c, cpu-tic30.c, cpu-tic4x.c,
+ cpu-tic54x.c, cpu-tic80.c, cpu-v850.c, cpu-vax.c, cpu-w65.c,
+ cpu-we32k.c, cpu-xstormy16.c, cpu-xtensa.c, cpu-z8k.c, demo64.c,
+ dwarf1.c, dwarf2.c, ecoff.c, ecofflink.c, ecoffswap.h,
+ efi-app-ia32.c, efi-app-ia64.c, elf-bfd.h, elf-eh-frame.c,
+ elf-hppa.h, elf-m10200.c, elf-m10300.c, elf-strtab.c, elf.c,
+ elf32-am33lin.c, elf32-arc.c, elf32-arm.c, elf32-avr.c,
+ elf32-cr16c.c, elf32-cris.c, elf32-crx.c, elf32-d10v.c,
+ elf32-d30v.c, elf32-dlx.c, elf32-fr30.c, elf32-frv.c, elf32-gen.c,
+ elf32-h8300.c, elf32-hppa.c, elf32-hppa.h, elf32-i370.c,
+ elf32-i386.c, elf32-i860.c, elf32-i960.c, elf32-ip2k.c,
+ elf32-iq2000.c, elf32-m32r.c, elf32-m68hc11.c, elf32-m68hc12.c,
+ elf32-m68hc1x.c, elf32-m68hc1x.h, elf32-m68k.c, elf32-m88k.c,
+ elf32-mcore.c, elf32-mips.c, elf32-msp430.c, elf32-openrisc.c,
+ elf32-or32.c, elf32-pj.c, elf32-ppc.c, elf32-ppc.h, elf32-s390.c,
+ elf32-sh-symbian.c, elf32-sh.c, elf32-sh64-com.c, elf32-sh64.c,
+ elf32-sh64.h, elf32-sparc.c, elf32-v850.c, elf32-vax.c,
+ elf32-xstormy16.c, elf32-xtensa.c, elf32.c, elf64-alpha.c,
+ elf64-gen.c, elf64-hppa.c, elf64-hppa.h, elf64-mips.c,
+ elf64-mmix.c, elf64-ppc.c, elf64-ppc.h, elf64-s390.c,
+ elf64-sh64.c, elf64-sparc.c, elf64-x86-64.c, elf64.c, elfcode.h,
+ elfcore.h, elflink.c, elfn32-mips.c, elfxx-ia64.c, elfxx-mips.c,
+ elfxx-mips.h, elfxx-sparc.c, elfxx-sparc.h, elfxx-target.h,
+ epoc-pe-arm.c, epoc-pei-arm.c, format.c, freebsd.h, gen-aout.c,
+ genlink.h, hash.c, host-aout.c, hp300bsd.c, hp300hpux.c,
+ 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, libbfd.h, libcoff-in.h,
+ libcoff.h, libecoff.h, libhppa.h, libieee.h, libnlm.h, liboasys.h,
+ libpei.h, libxcoff.h, linker.c, lynx-core.c, m68k4knetbsd.c,
+ m68klinux.c, m68klynx.c, m68knetbsd.c, m88kmach3.c, m88kopenbsd.c,
+ mach-o-target.c, mach-o.c, mach-o.h, merge.c, mipsbsd.c, mmo.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, pdp11.c, pe-arm.c, pe-i386.c,
+ pe-mcore.c, pe-mips.c, pe-ppc.c, pe-sh.c, peXXigen.c,
+ pef-traceback.h, pef.c, pef.h, pei-arm.c, pei-i386.c, pei-mcore.c,
+ pei-mips.c, pei-ppc.c, pei-sh.c, peicode.h, ppcboot.c,
+ ptrace-core.c, reloc.c, reloc16.c, riscix.c, rs6000-core.c,
+ sco5-core.c, section.c, simple.c, som.c, som.h, sparclinux.c,
+ sparclynx.c, sparcnetbsd.c, srec.c, stab-syms.c, stabs.c, sunos.c,
+ syms.c, sysdep.h, targets.c, tekhex.c, ticoff.h, trad-core.c,
+ vax1knetbsd.c, vaxbsd.c, vaxnetbsd.c, versados.c, vms-gsd.c,
+ vms-hdr.c, vms-misc.c, vms-tir.c, vms.c, vms.h, xcoff-target.h,
+ xcofflink.c, xsym.c, xsym.h, xtensa-isa.c, xtensa-modules.c,
+ hosts/alphavms.h
+
+2005-05-04 H.J. Lu <hongjiu.lu@intel.com>
+
+ * bfd-in.h (_bfd_elf_provide_section_bound_symbols): New.
+ * bfd-in2.h: Regenerated.
+
+ * elflink.c (bfd_elf_set_symbol): New.
+ (_bfd_elf_provide_symbol): Call it.
+ (_bfd_elf_provide_section_bound_symbols): New.
+
+2005-05-04 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elflink.c (_bfd_elf_merge_symbol): Only skip weak definitions
+ at the end, if a strong definition has already been seen.
+
+2005-05-04 Alan Modra <amodra@bigpond.net.au>
+
+ * section.c (struct bfd_section): Replace link_order_head and
+ link_order_tail with map_head and map_tail union.
+ (STD_SECTION): Update.
+ (_bfd_strip_section_from_output): Delete.
+ * aoutx.h: Update throughout for above changes.
+ * coff-ppc.c: Likewise.
+ * cofflink.c: Likewise.
+ * ecoff.c: Likewise.
+ * elf-eh-frame.c: Likewise.
+ * elf-m10300.c: Likewise.
+ * elf.c: Likewise.
+ * elf32-arm.c: Likewise.
+ * elf32-cris.c: Likewise.
+ * elf32-hppa.c: Likewise.
+ * elf32-i386.c: Likewise.
+ * elf32-m32r.c: Likewise.
+ * elf32-m68hc1x.c: Likewise.
+ * elf32-m68k.c: Likewise.
+ * elf32-ppc.c: Likewise.
+ * elf32-s390.c: Likewise.
+ * elf32-sh.c: Likewise.
+ * elf32-vax.c: Likewise.
+ * elf32-xtensa.c: Likewise.
+ * elf64-alpha.c: Likewise.
+ * elf64-hppa.c: Likewise.
+ * elf64-ppc.c: Likewise.
+ * elf64-s390.c: Likewise.
+ * elf64-sh64.c: Likewise.
+ * elf64-x86-64.c: Likewise.
+ * elflink.c: Likewise.
+ * elfxx-ia64.c: Likewise.
+ * elfxx-mips.c: Likewise.
+ * elfxx-sparc.c: Likewise.
+ * linker.c: Likewise.
+ * merge.c: Likewise.
+ * pdp11.c: Likewise.
+ * xcofflink.c: Likewise.
+ * elflink.c (bfd_boolean bfd_elf_size_dynsym_hash_dynstr): Split
+ out from bfd_elf_size_dynamic_sections.
+ * bfd-in.h (bfd_boolean bfd_elf_size_dynsym_hash_dynstr): Declare.
+ * bfd-in2.h: Regenerate.
+
+2005-05-04 Alan Modra <amodra@bigpond.net.au>
+
+ * section.c (bfd_section_list_remove): Don't clear s->next.
+ (bfd_section_list_append): Always init s->prev.
+ (bfd_section_list_prepend): Define.
+ (bfd_section_list_insert_after): Minor optimization.
+ (bfd_section_removed_from_list): Rewrite.
+ * elf.c (assign_section_numbers): Simplify list traversal now that
+ bfd_section_list_remove doesn't destroy removed section next ptr.
+ * sunos.c (sunos_add_dynamic_symbols): Likewise.
+ * elfxx-ia64.c (elfNN_ia64_object_p): Use bfd_section_list_prepend.
+ * xcofflink.c (_bfd_xcoff_bfd_final_link): Simplify list traversal.
+ * bfd-in2.h: Regenerate.
+
+2005-05-02 H.J. Lu <hongjiu.lu@intel.com>
+
+ * bfd.c (bfd): Remove section_tail and add section_last.
+ (bfd_preserve): Likewise.
+ (bfd_preserve_save): Likewise.
+ (bfd_preserve_restore): Likewise.
+ * opncls.c (_bfd_new_bfd): Likewise.
+
+ * coffcode.h (coff_compute_section_file_positions): Updated.
+ (coff_compute_section_file_positions): Likewise.
+ * elf.c (assign_section_numbers): Likewise.
+ * elf32-i370.c (i370_elf_size_dynamic_sections): Likewise.
+ * elf64-mmix.c (mmix_elf_final_link): Likewise.
+ * elfxx-ia64.c (elfNN_ia64_object_p): Likewise.
+ * elfxx-mips.c (_bfd_mips_elf_link_hash_table_create): Likewise.
+ * sunos.c (sunos_add_dynamic_symbols): Likewise.
+ * xcofflink.c (_bfd_xcoff_bfd_final_link): Likewise.
+
+ * ecoff.c (bfd_debug_section): Initialize prev.
+
+ * section.c (bfd_section): Add prev.
+ (bfd_section_list_remove): Updated.
+ (bfd_section_list_append): New.
+ (bfd_section_list_insert_after): New.
+ (bfd_section_list_insert_before): New.
+ (bfd_section_list_insert): Removed.
+ (bfd_section_removed_from_list): Updated.
+ (STD_SECTION): Initialize prev.
+ (bfd_section_init): Updated.
+ (bfd_section_list_clear): Updated.
+
+ * bfd-in2.h: Regenerated.
+
+2005-05-02 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf.c (_bfd_elf_new_section_hook): Don't call
+ _bfd_elf_get_sec_type_attr on sections from input files.
+
+2005-05-02 H.J. Lu <hongjiu.lu@intel.com>
+
+ * merge.c (sec_merge_init): Call bfd_hash_table_init_n with
+ hash table size 16699 instead of bfd_hash_table_init.
+
+2005-05-01 Paul Brook <paul@codesourcery.com>
+
+ * elflink.c (_bfd_elf_merge_symbol): Skip weak definitions if a strong
+ definition has already been seen.
+
+2005-05-01 Paul Brook <paul@codesourcery.com>
+
+ * elf32-arm.c (bfd_elf32_arm_process_before_allocation): Treat
+ R_ARM_PLT32 the same as R_ARM_PC24.
+ (arm_add_to_rel): Ditto.
+
+2005-04-29 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * config.bfd: Add h8300*-*-rtemscoff.
+ Switch h8300*-*-rtems* to elf.
+
+2005-04-29 Daniel Jacobowitz <dan@codesourcery.com>
+
+ * aclocal.m4, Makefile.in: Regnerated.
+
+2005-04-28 Paul Brook <paul@codesourcery.com>
+
+ Merge changes only applied to Makefile.in.
+ * Makefile.am (BFD32_BACKENDS): Add elfxx-sparc.lo
+ (BFD32_BACKENDS_CFILES): Add elfxx-sparc.c
+ (elfxx-sparc.lo): New rule.
+ (elf32-sparc.lo): Add elfxx-sparc.h dependency.
+ (elf64-sparc.lo): Likewise.
+
+2005-04-28 Julian Brown <julian@codesourcery.com>
+
+ * elflink.c (_bfd_elf_provide_symbol): Provide symbol for weak
+ import.
+
+2005-04-27 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf-bfd.h (bfd_elf_sym_name): Also take "asection *".
+
+ * elf.c (bfd_elf_sym_name): Updated.
+ (group_signature): Likewise.
+ * elf32-ppc.c (ppc_elf_relocate_section): Likewise.
+ * elf64-ppc.c (ppc64_elf_edit_opd): Likewise.
+ (ppc64_elf_edit_toc): Likewise.
+ (ppc64_elf_relocate_section): Likewise.
+ * elfcode.h (elf_slurp_symbol_table): Likewise.
+ * elflink.c (elf_link_input_bfd): Likewise.
+
+ * elfxx-ia64.c (elfNN_ia64_relocate_section): Call
+ bfd_elf_sym_name to get local symbol name when reporting errors.
+
+2005-04-27 Nick Clifton <nickc@redhat.com>
+
+ * elflink.c (elf_link_input_bfd): Handle the case where a badly
+ formatted input file results in a reloc which has no associated
+ global symbol.
+
+2005-04-26 Jerome Guitton <guitton@gnat.com>
+
+ * bfd.m4 (BFD_NEED_DECLARATION): Restore.
+
+2005-04-25 David S. Miller <davem@davemloft.net>
+
+ * elfxx-sparc.c (sparc_elf_append_rela_64): Add BFD64 protection.
+ (sparc_elf_r_info_64, _bfd_sparc_elf_finish_dynamic_symbol,
+ sparc64_finish_dyn, _bfd_sparc_elf_finish_dynamic_sections):
+ Likewise.
+
+2005-04-25 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR 858
+ * elflink.c (elf_link_input_bfd): Make non-debugging reference
+ to discarded section an error.
+
+2005-04-21 Jerome Guitton <guitton@gnat.com>
+
+ * configure.in: Replace BFD_NEED_DECLARATION checks by the
+ corresponding AC_CHECK_DECLS.
+ * sysdep.h: Replace NEED_DECLARATION_* checks by the corresponding
+ HAVE_DECL_*.
+ * bfd.m4 (BFD_NEED_DECLARATION): Remove, obsolete.
+ * configure: Regenerate.
+ * config.in: Ditto.
+
+2005-04-21 Andreas Schwab <schwab@suse.de>
+
+ * elfxx-sparc.h (struct _bfd_sparc_elf_link_hash_table): Remove
+ unsigned from type of dynamic_interpreter.
+ * elfxx-sparc.c (_bfd_sparc_elf_link_hash_table_create): Remove
+ casts again.
+
+ * elf.c (assign_section_numbers): Fix comment.
+
+2005-04-21 Jerome Guitton <guitton@gnat.com>
+
+ * som.c (som_bfd_print_private_bfd_data): Add explicit cast to long
+ for struct som_exec_auxhdr fields.
+
+2005-04-21 Nick Clifton <nickc@redhat.com>
+
+ * aout-adobe.c: Convert to ISO C and fix formatting.
+ * aout-arm.c: Convert to ISO C and fix formatting.
+ * aout-cris.c: Convert to ISO C and fix formatting.
+ * aout-ns32k.c: Convert to ISO C and fix formatting.
+ * aout-tic30.c: Convert to ISO C and fix formatting.
+ * coffcode.h: Convert to ISO C and fix formatting.
+ * coffswap.h: Convert to ISO C and fix formatting.
+ * i386aout.c: Convert to ISO C and fix formatting.
+ * libaout.h: Convert to ISO C and fix formatting.
+ * libcoff-in.h: Convert to ISO C and fix formatting.
+ * libcoff.h: Convert to ISO C and fix formatting.
+ * libecoff.h: Convert to ISO C and fix formatting.
+ * libnlm.h: Convert to ISO C and fix formatting.
+ * libpei.h: Convert to ISO C and fix formatting.
+ * libxcoff.h: Convert to ISO C and fix formatting.
+ * nlm-target.h: Convert to ISO C and fix formatting.
+ * nlm.c: Convert to ISO C and fix formatting.
+ * nlm32-alpha.c: Convert to ISO C and fix formatting.
+ * nlm32-i386.c: Convert to ISO C and fix formatting.
+ * nlm32-ppc.c: Convert to ISO C and fix formatting.
+ * nlm32-sparc.c: Convert to ISO C and fix formatting.
+ * nlmcode.h: Convert to ISO C and fix formatting.
+ * nlmswap.h: Convert to ISO C and fix formatting.
+ * pe-mips.c: Convert to ISO C and fix formatting.
+ * peXXigen.c: Convert to ISO C and fix formatting.
+ * peicode.h: Convert to ISO C and fix formatting.
+ * vms-gsd.c: Convert to ISO C and fix formatting.
+ * vms-hdr.c: Convert to ISO C and fix formatting.
+ * vms-misc.c: Convert to ISO C and fix formatting.
+ * vms-tir.c: Convert to ISO C and fix formatting.
+ * vms.c: Convert to ISO C and fix formatting.
+ * vms.h: Convert to ISO C and fix formatting.
+
+ * coffgen.c (coff_print_symbol): Restore correct formatting of
+ output.
+
+2005-04-20 David S. Miller <davem@davemloft.net>
+
+ * elfxx-sparc.c (sparc_elf_r_symndx_64): Fix compiler warning.
+ (_bfd_sparc_elf_link_hash_table_create): Likewise.
+ (allocate_dynrelocs): Likewise.
+
+2005-04-20 Jerome Guitton <guitton@gnat.com>
+
+ * configure.in: Fix the check for basename declaration. Add check
+ for declarations of ftello, ftello64, fseeko, fseeko64.
+ * configure: Regenerate.
+ * config.in: Ditto.
+ * sysdep.h: If needed, declare ftello, ftello64, fseeko, fseeko64.
+
+2005-04-19 David S. Miller <davem@davemloft.net>
+
+ * elfxx-sparc.c: New file.
+ * elfxx-sparc.h: New file.
+ * Makefile.in (BFD32_BACKENDS): Add elfxx-sparc.lo
+ (BFD32_BACKENDS_CFILES): Add elfxx-sparc.c
+ (elfxx-sparc.lo): New rule.
+ (elf32-sparc.lo): Add elfxx-sparc.h dependency.
+ (elf64-sparc.lo): Likewise.
+ * configure.in (bfd_elf32_sparc_vec): Add elfxx-sparc.lo
+ (bfd_elf64_sparc_vec): Likewise.
+ * configure: Regenerate.
+ * elf32-sparc.c: Remove common code now in elfxx-sparc.c
+ * elf64-sparc.c: Likewise, also use elf64_sparc_*() naming
+ which is more consistent with elf32-sparc.c
+
+2005-04-19 Daniel Jacobowitz <dan@codesourcery.com>
+
+ * elfxx-mips.c (struct mips_elf_link_hash_entry): Update comment.
+ (mips_elf_create_local_got_entry): Check h->root.forced_local.
+
+2005-04-19 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-ppc.c (ppc_elf_check_relocs): Don't bother with
+ dynamic relocs in non-SEC_ALLOC sections.
+ (ppc_elf_gc_sweep_hook): Likewise.
+ (ppc_elf_relax_section): Likewise.
+ (ppc_elf_relocate_section): Likewise.
+
+2005-04-18 Nick Clifton <nickc@redhat.com>
+
+ * aix5ppc-core.c (xcoff64_core_p): Fix compile time warning
+ assigning a value to return_value.
+
+2005-04-17 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR 855
+ * elf.c (_bfd_elf_copy_private_section_data): Don't copy linker
+ created group data.
+
+2005-04-17 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR 855
+ * elf.c (setup_group): Properly handle zero group count.
+
+2005-04-17 Mark Kettenis <kettenis@gnu.org>
+
+ * som.c (hppa_som_reloc, som_mkobject, som_is_space)
+ (som_is_subspace, compare_subspaces, som_compute_checksum)
+ (som_build_and_write_symbol_table, som_slurp_symbol_table): New
+ protoypes.
+ (hppa_som_reloc, compare_syms, compare_subspaces)
+ (som_print_symbol, som_get_section_contents)
+ (som_set_section_contents): Remove space after 'void *'.
+ (som_bfd_print_private_bfd_data): Use %lx to print longs.
+ (som_bfd_merge_private_bfd_data)
+ (som_bfd_copy_private_header_data, som_bfd_set_private_flags): New
+ defines.
+
+2005-04-15 Julian Brown <julian@codesourcery.com>
+
+ * bfd-in.h (bfd_elf32_arm_set_target_relocs): Update prototype.
+ * bfd-in2.h: Regenerate.
+ * elf32-arm.c (elf32_arm_link_hash_table): New field, 'use_blx'.
+ (elf32_arm_link_hash_table_create): Initialise fix_v4bx, use_blx.
+ (bfd_elf32_arm_set_target_relocs): Handle use_blx.
+ (elf32_arm_final_link_relocate): Use Thumb BLX for R_ARM_THM_PC22
+ relocations if requested to.
+ (allocate_dynrelocs): Don't count size of omitted Thumb stubs based on
+ use_blx rather than symbian_p.
+ (elf32_arm_finish_dynamic_symbol): Don't output Thumb PLT stubs if
+ use_blx is in effect.
+ (elf32_arm_symbian_link_hash_table_create): Enable use_blx by default
+ for SymbianOS.
+
+2005-04-15 Nick Clifton <nickc@redhat.com>
+
+ * coffgen.c (coff_print_symbol): Use fprintf_vma to print vma
+ values.
+
+2005-04-15 Alan Modra <amodra@bigpond.net.au>
+
+ PR ld/815
+ * elflink.c (elf_smash_syms): Clear undef.next if it's not being
+ used as a list pointer.
+
+2005-04-14 Alan Modra <amodra@bigpond.net.au>
+
+ * Makefile.am (NO_WERROR): Define.
+ * warning.m4: New file
+ * acinclude.m4: Include warning.m4.
+ * configure.in: Invoke AM_BINUTILS_WARNINGS.
+ * Makefile.in: Regenerate.
+ * configure: Regenerate.
+
+2005-04-14 Alan Modra <amodra@bigpond.net.au>
+
+ * merge.c (sec_merge_emit): Tidy. Check for bfd_zmalloc errors.
+ Write trailing padding.
+
+ * merge.c (merge_strings): Round up section size for alignment.
+
+2005-04-14 David S. Miller <davem@davemloft.net>
+
+ Add TLS support for 64-bit Sparc ELF.
+ * elf64-sparc.c (sparc64_elf_dyn_relocs,
+ sparc64_elf_link_hash_entry, sparc64_elf_obj_tdata): New structs.
+ (GOT_UNKNOWN, GOT_NORMAL, GOT_TLD_GD, GOT_TLD_IE,
+ sparc64_elf_hash_entry, sparc64_elf_tdata,
+ sparc64_elf_local_got_tls_type): New defines.
+ (sparc64_elf_mkobject): New function.
+ (sparc64_elf_link_hash_table): Add members for dynamic linker
+ sections PLT, RELPLT, DYNBSS, and RELBSS. Add tls_ldm_got
+ uion to track TLS GOT references. Add sym_sec to cache
+ mappings from local sym to section.
+ (link_hash_newfunc): New function.
+ (sparc64_elf_bfd_link_hash_table_create): Rename to
+ sparc64_elf_link_hash_table_create for consistency.
+ Pass link_hash_newfunc to _bfd_elf_link_hash_table_init.
+ (sparc64_elf_create_dynamic_sections): Initialize new section
+ members of sparc64_elf_link_hash_table. Only init srelbss
+ if not-shared.
+ (sparc64_elf_copy_indirect_symbol, sparc64_elf_tls_transition):
+ New functions.
+ (SPARC_NOP): Define.
+ (sparc64_elf_build_plt, sparc64_elf_plt_entry_offset,
+ sparc64_elf_plt_ptr_offset): Delete.
+ (sparc64_plt_entry_build): New function to build PLT entries
+ gradually instread of all at once at the end of linking.
+ (sparc64_elf_check_relocs): Delete dynobj, sgot, and srelgot
+ local vars. Get them from sparc64_elf_hash_table instead.
+ Check early on if r_symndx is in bounds. Handle TLS transitions.
+ Account for TLS GOT references and DF_STATIC_TLS, as needed.
+ For TLS relocs, record the tls_type in either
+ sparc64_elf_local_got_tls_type or sparc64_elf_hash_entry as
+ appropriate. For R_SPARC_TLS_{GD,LDM}_CALL, emit a reference
+ to the __tls_get_addr symbol. For PLT relocs, track references
+ via h->plt.refcount. When R_SPARC_{PC10,PC22,PC_HH22,PC_HM10,
+ PC_LM22} and h not-NULL, set h->non_got_ref. For global data
+ symbol references, count the number of relocations needed for
+ that symbol. For default switch case, don't error, this lets
+ the TLS relocs not explicitly handled by this function get
+ accepted.
+ (sparc64_elf_gc_mark_hook, sparc64_gc_sweep_hook): New functions.
+ (sparc64_elf_adjust_dynamic_symbol): Remove dynobj local var, get
+ it from sparc64_elf_hash_table. Store the real PLT offset
+ in h->plt.offset, and build PLT entries one at a time. Also
+ get .dynbss section pointer from htab.
+ (allocate_dynrelocs, readonly_dynrelocs,
+ sparc64_omit_section_dynsym): New functions.
+ (sparc64_elf_omit_section_dynsym): Use these new functions as
+ helpers.
+ (dtpoff_base, tpoff): New functions.
+ (sparc64_elf_relocate_section): Kill dynobj, sgot, and splt
+ locals, get them from sparc64_elf_hash_table. Handle TLS
+ relocations and refcounting in main relocation loop.
+ (sparc64_elf_finish_dynamic_symbol): Use
+ sparc64_elf_link_hash_table. Build PLT entries as we see
+ them. Handle TLS GOT relocations.
+ (sparc64_elf_finish_dynamic_sections): Get sgot and dynobj
+ from sparc64_elf_hash_table. Initialize only PLT header
+ not all entries since we not build PLT entries one by one.
+ (elf_backend_copy_indirect_symbol, bfd_elf64_mkobject,
+ elf_backend_gc_mark_hook, elf_backend_gc_sweep_hook,
+ elf_backend_can_gc_sections, elf_backend_can_refcount): Define.
+
+2005-04-13 Daniel Jacobowitz <dan@codesourcery.com>
+
+ * elflink.c (elf_link_input_bfd): Update check for removed
+ sections.
+
+2005-04-12 Alan Modra <amodra@bigpond.net.au>
+
+ * Makefile.am: Run "make dep-am".
+ * Makefile.in: Regenerate.
+ * aclocal.m4: Regenerate.
+ * libcoff.h: Regenerate.
+
+2005-04-11 H.J. Lu <hongjiu.lu@intel.com>
+
+ * linker.c (_bfd_generic_link_output_symbols): Also check if
+ the output section of an input section has been removed from
+ the output file.
+
+ * section.c (bfd_section_list_remove): Clear the next field
+ of the removed section.
+ (bfd_section_removed_from_list): New.
+ * bfd-in2.h: Regenerated.
+
+2005-04-11 David S. Miller <davem@davemloft.net>
+
+ * elf32-sparc.c (elf32_sparc_relocate_section,
+ R_SPARC_TLS_LDO_{HIX22,LOX10}): When not shared, transition to
+ R_SPARC_TLS_LE_{HIX22,LOX10}.
+ (elf32_sparc_relocate_section, R_SPARC_TLS_{LDO,LE}_HIX22): Only
+ xor relocation with 0xffffffff if R_SPARC_TLS_LE_HIX22.
+ (elf32_sparc_relocate_section, R_SPARC_TLS_{LDO,LE}_LOX10): Only
+ or 0x1c00 into relocation if R_SPARC_TLS_LE_HIX22.
+
+2005-04-11 H.J. Lu <hongjiu.lu@intel.com>
+
+ * coffcode.h (STRING_SIZE_SIZE): Updated to match libcoff-in.h.
+
+2005-04-11 Nick Clifton <nickc@redhat.com>
+
+ * aout-target.h: Convert to ISO C.
+ * aoutf1.h: Convert to ISO C.
+ * aoutx.h: Convert to ISO C.
+ * bout.c: Convert to ISO C.
+ * dwarf1.c: Convert to ISO C.
+ * ecoffswap.h: Convert to ISO C.
+ * freebsd.h: Convert to ISO C.
+ * genlink.h: Convert to ISO C.
+ * ieee.c: Convert to ISO C.
+ * ihex.c: Convert to ISO C.
+ * libcoff-in.h: Convert to ISO C.
+ * mach-o.c: Convert to ISO C.
+ * mach-o.h: Convert to ISO C.
+ * netbsd.h: Convert to ISO C.
+ * ns32k.h: Convert to ISO C.
+ * ns32knetbsd.c: Convert to ISO C.
+ * oasys.c: Convert to ISO C.
+ * pdp11.c: Convert to ISO C.
+ * pef-traceback.h: Convert to ISO C.
+ * pef.c: Convert to ISO C.
+ * pef.h: Convert to ISO C.
+ * riscix.c: Convert to ISO C.
+ * som.c: Convert to ISO C.
+ * som.h: Convert to ISO C.
+ * srec.c: Convert to ISO C.
+ * stabs.c: Convert to ISO C.
+ * sunos.c: Convert to ISO C.
+ * tekhex.c: Convert to ISO C.
+ * versados.c: Convert to ISO C.
+ * version.h: Convert to ISO C.
+ * xcoff-target.h: Convert to ISO C.
+ * xcofflink.c: Convert to ISO C.
+ * xsym.c: Convert to ISO C.
+ * xsym.h: Convert to ISO C.
+
+2005-04-08 Paul Brook <paul@codesourcery.com>
+
+ * elf32-arm.c (ARM2THUMB_GLUE_SIZE): Rename...
+ (ARM2THUMB_STATIC_GLUE_SIZE): ... to this.
+ (ARM2THUMB_PIC_GLUE_SIZE): Define.
+ (a2t1p_ldr_insn, a2t2p_add_pc_insn, a2t3p_bx_r12_insn): Add.
+ (elf32_arm_to_thumb_stub): Create PIC stubs.
+ (record_arm_to_thumb_glue): Use different stub size for relocatable
+ images.
+
+2005-04-05 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (dec_dynrel_count): New function split out from
+ ppc64_elf_edit_toc, with additional code from ppc64_elf_edit_opd.
+ (ppc64_elf_edit_toc, ppc64_elf_edit_opd): Use it.
+ (ppc64_elf_tls_optimize): Likewise.
+
+2005-04-05 Mark Kettenis <kettenis@gnu.org>
+
+ * netbsd-core.c (SPARC_WCOOKIE_OFFSET): Renamed from
+ CORE_WCOOKIE_OFFSET.
+ (SPARC64_WCOOKIE_OFFSET): New.
+ (netbsd_core_file_p): Provide .wcookie section for OpenBSD/sparc64.
+
+2005-04-05 Nick Clifton <nickc@redhat.com>
+
+ * po/rw.po: New translation: Kinyarwanda
+ * configure.in (ALL_LINGUAS): Add rw
+ * configure: Regenerate.
+
+2005-04-05 Richard Sandiford <rsandifo@redhat.com>
+
+ * elfxx-mips.c (MIPS_ELF_OPTIONS_SECTION_NAME_P): New macro.
+ (_bfd_mips_elf_section_from_shdr): Use it to check for recognized
+ SHT_MIPS_OPTIONS names. Allow all sections with unrecognised
+ section flags.
+ (_bfd_mips_elf_fake_sections): Use MIPS_ELF_OPTIONS_SECTION_NAME_P
+ to check for SHT_MIPS_OPTIONS sections.
+ (_bfd_mips_elf_set_section_contents): Likewise.
+
+2005-04-04 Eric Christopher <echristo@redhat.com>
+
+ * elfxx-mips.c (_bfd_elf_mips_get_relocated_section_contents):
+ Clean up gp handling code.
+
+2005-04-04 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf.c (bfd_elf_set_group_contents): Ignore linker created
+ group section.
+ (assign_section_numbers): Accept link_info. Check SHT_GROUP
+ sections for relocatable files only. Remove the linker created
+ group sections.
+ (_bfd_elf_compute_section_file_positions): Pass link_info to
+ assign_section_numbers.
+
+ * elfxx-ia64.c (elfNN_ia64_object_p): New.
+ (elf_backend_object_p): Defined.
+
+2005-04-04 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf-bfd.h (elf_section_data): Use (sec) instead of sec.
+
+2005-04-03 Fred Fish <fnf@specifixinc.com>
+
+ * dwarf2.c (struct dwarf2_debug): Add dwarf_ranges_buffer and
+ dwarf_ranges_size members.
+ (struct comp_unit): Add base_address member.
+ (struct funcinfo): Replace low/high members with an arange.
+ (arange_add): Replace incoming "unit" parameter with "abfd" and
+ "first_arange" pointers. Reorganize/rewrite function body.
+ (decode_line_info): Change arange_add call to pass bfd and arange
+ pointers.
+ (lookup_address_in_line_info_table): Use arange list instead of
+ individual low/high members. Walk function's arange list to find
+ lowest PC in list, to test for overlapping functions.
+ (read_debug_ranges): New function, reads the debug_ranges section.
+ (lookup_address_in_function_table): Use arange list instead of
+ individual low/high members. Rewrite to find smallest range that
+ matches.
+ (read_rangelist): Read a given rangelist from debug_ranges.
+ (scan_unit_for_functions): Use arange list instead of individual
+ low/high members. Handle a DW_AT_ranges attribute.
+ (parse_comp_unit): Use arange list instead of individual low/high
+ members. Save comp unit base address. Handle a DW_AT_ranges
+ attribute.
+
+2005-04-01 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf.c (assign_section_numbers): Really use the kept section.
+
+2005-03-31 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf-bfd.h (_bfd_elf_check_kept_section): New.
+
+ * elf.c (assign_section_numbers): When sh_link points to a
+ discarded section, call _bfd_elf_check_kept_section to see if
+ the kept section can be used. Otherwise reject sh_link
+ pointing to discarded section.
+
+ * elflink.c (_bfd_elf_check_kept_section): New.
+ (elf_link_input_bfd): Use it.
+
+2005-04-01 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (ppc64_elf_edit_toc): Account for dynamic relocs
+ that we no longer need.
+
+2005-04-01 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (ppc64_elf_get_synthetic_symtab): Return -1 on errors
+ rather than 0.
+ (ppc64_elf_check_relocs): Remove unnecessary SEC_ALLOC check.
+
+2005-03-31 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf.c (assign_section_numbers): Fix a typo.
+
+2005-03-31 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elflink.c (elf_link_input_bfd): Remove the extra `\n' in
+ error message.
+ (_bfd_elf_section_already_linked): Likewise.
+
+2005-03-31 Jerome Guitton <guitton@gnat.com>
+
+ * config.in: Regenerate.
+
+2005-03-31 Jerome Guitton <guitton@gnat.com>
+
+ * config.in (HAVE_DECL_BASENAME): New configure macro.
+ * configure.in: Check for basename.
+ * configure: Regenerate.
+
+2005-03-30 Julian Brown <julian@codesourcery.com>
+
+ * bfd-in.h (bfd_is_arm_mapping_symbol_name): Rename from
+ bfd_elf32_is_arm_mapping_symbol_name.
+ * bfd-in2.h: Regenerate.
+ * cpu-arm.c (bfd_is_arm_mapping_symbol_name): Rename from
+ bfd_elf32_is_arm_mapping_symbol_name.
+ * elf32-arm.c (elf32_arm_is_target_special_symbol): Rename
+ bfd_elf32_is_arm_mapping_symbol_name to bfd_is_arm_mapping_symbol_name.
+ (arm_elf_find_function): Likewise.
+ (elf32_arm_output_symbol_hook): Likewise.
+
+2005-03-30 Julian Brown <julian@codesourcery.com>
+
+ * bfd-in.h (bfd_elf32_is_arm_mapping_symbol_name): Add prototype.
+ * bfd-in2.h: Regenerate.
+ * elf32-arm.c (elf32_arm_is_target_special_symbol): Rename call to
+ bfd_elf32_is_arm_mapping_symbol_name.
+ (elf32_arm_output_symbol_hook): Likewise.
+ (arm_elf_find_function): Likewise, and include STT_NOTYPE in test for
+ mapping symbols.
+ (is_arm_mapping_symbol_name): Function moved from here...
+ * cpu-arm.c (bfd_elf32_is_arm_mapping_symbol_name): ...to here, renamed
+ and made global.
+
+2005-03-29 Aaron W. LaFramboise <aaron98wiridge9@aaronwl.com>
+
+ * configure.in: Check for ffs decl and alphabetize.
+ * config.in: Regenerate.
+ * configure: Regenerate.
+ * sysdep.h [NEED_DECLARATION_FFS] (ffs): Prototype and alphabetize.
+
+2005-03-29 Fred Fish <fnf@specifixinc.com>
+
+ * dwarf2.c (struct comp_unit): Fix typo.
+ (scan_unit_for_functions): Remove unused local variable "name"
+ and dead code that set it.
+
+2005-03-29 Daniel Jacobowitz <dan@codesourcery.com>
+ Phil Blundell <philb@gnu.org>
+
+ * bfd-in2.h, libbfd.h: Regenerated.
+ * reloc.c: Add ARM TLS relocations.
+ * elf32-arm.c (elf32_arm_howto_table): Add dynamic TLS
+ relocations.
+ (elf32_arm_tls_gd32_howto, elf32_arm_tls_ldo32_howto)
+ (elf32_arm_tls_ldm32_howto, elf32_arm_tls_le32_howto)
+ (elf32_arm_tls_ie32_howto): New.
+ (elf32_arm_howto_from_type): Support TLS relocations.
+ (elf32_arm_reloc_map): Likewise.
+ (elf32_arm_reloc_type_lookup): Likewise.
+ (TCB_SIZE): Define.
+ (struct elf32_arm_obj_tdata): New.
+ (elf32_arm_tdata, elf32_arm_local_got_tls_type): Define.
+ (elf32_arm_mkobject): New function.
+ (struct elf32_arm_relocs_copied): Add pc_count.
+ (elf32_arm_hash_entry, GOT_UNKNOWN, GOT_NORMAL, GOT_TLS_GD)
+ (GOT_TLS_IE): Define.
+ (struct elf32_arm_link_hash_table): Add tls_ldm_got.
+ (elf32_arm_link_hash_newfunc): Initialize tls_type.
+ (elf32_arm_copy_indirect_symbol): Copy pc_count and tls_type.
+ (elf32_arm_link_hash_table_create): Initialize tls_ldm_got.
+ (dtpoff_base, tpoff): New functions.
+ (elf32_arm_final_link_relocate): Handle TLS relocations.
+ (IS_ARM_TLS_RELOC): Define.
+ (elf32_arm_relocate_section): Warn about TLS mismatches.
+ (elf32_arm_gc_sweep_hook): Handle TLS relocations and pc_count.
+ (elf32_arm_check_relocs): Detect invalid symbol indexes. Handle
+ TLS relocations and pc_count.
+ (elf32_arm_adjust_dynamic_symbol): Check non_got_ref.
+ (allocate_dynrelocs): Handle TLS. Bind REL32 relocs to local
+ calls.
+ (elf32_arm_size_dynamic_sections): Handle TLS.
+ (elf32_arm_finish_dynamic_symbol): Likewise.
+ (bfd_elf32_mkobject): Define.
+
+2005-03-29 Daniel Jacobowitz <dan@codesourcery.com>
+
+ * elf32-arm.c (elf32_arm_check_relocs): Increment count for all
+ relocation types. Don't count relocations which will use a PLT.
+
+2005-03-29 Joel Brobecker <brobecker@gnat.com>
+
+ * elf.c (elfcore_grok_nto_status): Print tid as long.
+ (elfcore_grok_nto_regs): Likewise.
+
+2005-03-29 Joel Brobecker <brobecker@gnat.com>
+
+ * irix-core.c: Remove some unnecessary prototypes.
+
+2005-03-28 Joel Brobecker <brobecker@adacore.com>
+
+ * irix-core.c: Convert to ISO C.
+
+2005-03-28 Joel Brobecker <brobecker@adacore.com>
+
+ * irix-core.c (do_sections): Replace + by | in expression.
+ (irix_core_core_file_matches_executable_p): Add ATTRIBUTE_UNUSED
+ to unused parameters to avoid a compiler warning.
+
+2005-03-28 Mark Kettenis <kettenis@gnu.org>
+
+ * netbsd-core.c: Convert to ISO C. Fix formatting.
+
+2005-03-24 Eric Christopher <echristo@redhat.com>
+
+ * elfxx-mips.c: Revert previous patch.
+
+2005-03-24 Nick Clifton <nickc@redhat.com>
+
+ * targets.c (_bfd_target_vector): Only include the
+ bfd_elf32_ia64_hpux_big_vec vector when building a 64-bit BFD with
+ all targets enabled.
+
+2005-03-24 James E Wilson <wilson@specifixinc.com>
+
+ * Makefile.am (BFD32_BACKENDS): Delete elf32-ia64.lo.
+ (BFD64_BACKENDS): Add elf32-ia64.lo.
+ * Makefile.in: Regenerate.
+
+2005-03-23 Eric Christopher <echristo@redhat.com>
+
+ * elfxx-mips.c (MIPS_ELF_READONLY_SECTION): New.
+ (mips_elf_calculate_relocation): Use. Define DF_TEXTREL
+ after emitting relocation.
+ (_bfd_mips_elf_adjust_dynamic_symbol): Ditto.
+ (_bfd_mips_elf_check_relocs): Remove code to set DF_TEXTREL
+ and readonly_reloc.
+
+2005-03-23 Mike Frysinger <vapier@gentoo.org>
+ Nick Clifton <nickc@redhat.com>
+
+ * config.bfd: Accept any C library to accompany a GNU Linux
+ implementation, not just the GNU C library.
+ * configure.in: Likewise.
+ * configure: Regenerate.
+
+2005-03-22 H.J. Lu <hongjiu.lu@intel.com>
+
+ * bfd-in.h (_bfd_elf_provide_symbol): New.
+ * bfd-in2.h: Regenerated.
+
+ * elf32-ppc.c (set_linker_sym): Moved to elflink.c.
+ (ppc_elf_set_sdata_syms): Call _bfd_elf_provide_symbol instead
+ of set_linker_sym.
+
+ * elflink.c (_bfd_elf_provide_symbol): New. Moved and renamed
+ from elf32-ppc.c.
+
+2005-03-22 Hans-Peter Nilsson <hp@axis.com>
+
+ * hash.c (strtab_hash_newfunc): Fix typo in allocated size.
+
+2005-03-22 Bob Wilson <bob.wilson@acm.org>
+
+ * xtensa-isa.c (xtensa_opcode_lookup, xtensa_state_lookup,
+ xtensa_sysreg_lookup_name, xtensa_interface_lookup,
+ xtensa_funcUnit_lookup): Skip bsearch call if count is zero.
+ (xtensa_opcode_decode): Rearrange code.
+
+2005-03-22 Nick Clifton <nickc@redhat.com>
+
+ * binary.c: Convert to ISO C90 formatting.
+ * coff-arm.c: Convert to ISO C90 formatting.
+ * coffgen.c: Convert to ISO C90 formatting.
+ * elf32-gen.c: Convert to ISO C90 formatting.
+ * elf64-gen.c: Convert to ISO C90 formatting.
+ * hash.c: Convert to ISO C90 formatting.
+ * ieee.c: Convert to ISO C90 formatting.
+
+2005-03-22 Daniel Jacobowitz <dan@codesourcery.com>
+
+ * elf32-arm.c (elf32_arm_final_link_relocate): Don't fail for
+ unresolved symbols in R_ARM_NONE relocations.
+
+2005-03-22 Daniel Jacobowitz <dan@codesourcery.com>
+
+ * elf32-arm.c (elf32_arm_final_link_relocate): Add
+ UNRESOLVED_RELOC_P argument. Set it appropriately.
+ (elf32_arm_relocate_section): Update call to
+ elf32_arm_final_link_relocate. Don't clobber RELOCATION; use
+ unresolved_reloc instead.
+
+2005-03-23 Alan Modra <amodra@bigpond.net.au>
+
+ * elflink.c (elf_link_add_object_symbols): Set SEC_EXCLUDE on
+ .gnu.warning.* sections.
+
+2005-03-22 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-ppc.c (elf_linker_section_pointers_t): Remove
+ written_address_p.
+ (ppc_elf_create_linker_section): Don't try to reuse existing section.
+ (elf_create_pointer_linker_section): Delete info parm. Don't make
+ h dynamic. Don't set written_address_p.
+ (ppc_elf_check_relocs): Adjust ppc_elf_create_linker_section calls.
+ (bfd_put_ptr): Delete.
+ (elf_finish_pointer_linker_section): Remove output_bfd and info parms.
+ Always write section contents. Assert global sym is def_regular.
+ Use offset bottom bit as a written flag.
+ (ppc_elf_relocate_section): Adjust elf_finish_pointer_linker_section
+ calls.
+
+2005-03-22 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-ppc.c (ppc_elf_set_sdata_syms): New function, extracted from..
+ (ppc_elf_set_sdata_syms): ..here. Expand comment. Set .sbss start
+ and end syms.
+
+2005-03-21 Nick Clifton <nickc@redhat.com>
+
+ * coff-arm.c (coff_link_hash_entry): Only define for non WINCE
+ targets.
+ (t2a1_bx_pc_insn): Likewise.
+ (t2a2_noop_insn): Likewise.
+ (t2a3_b_insn): Likewise.
+ (t2a1_push_insn): Likewise.
+ (t2a2_ldr_insn): Likewise.
+ (t2a3_mov_insn): Likewise.
+ (t2a4_bx_insn): Likewise.
+ (t2a5_pop_insn): Likewise.
+ (t2a6_bx_insn): Likewise.
+ (coff_arm_relocate_section): Only declare the high_address
+ variable for non WINCE targets.
+
+2005-03-22 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-ppc.c (ppc_elf_add_symbol_hook): Make htab->sbss
+ SEC_LINKER_CREATED. Attach to dynobj.
+ (ppc_elf_size_dynamic_sections): Strip htab->sbss if zero size.
+
+2005-03-21 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-ppc.c (struct elf_linker_section): Remove sym_hash and
+ sym_offset. Add name, bss_name, sym_name, sym_val.
+ (struct ppc_elf_link_hash_table): Remove sdata and sdata2 pointers.
+ Add sdata array of elf_linker_section_t.
+ (ppc_elf_link_hash_table_create): Set name, sym_name, and bss_name.
+ (enum elf_linker_section_enum): Delete.
+ (ppc_elf_create_linker_section): Rewrite. Don't create syms here.
+ (ppc_elf_check_relocs): Delay ppc_elf_create_linker_section until
+ the special sections are needed. Adjust htab->sdata refs.
+ Ensure dynobj is set in sreloc code.
+ (ppc_elf_size_dynamic_sections): Strip sdata sections.
+ (ppc_elf_set_sdata_syms): New function.
+ (elf_finish_pointer_linker_section): Use 0x8000 for sym_offset.
+ (ppc_elf_relocate_section): Adjust references to htab->sdata. Use
+ sym_val instead of sym_hash.
+ * elf32-ppc.h (ppc_elf_set_sdata_syms): Declare.
+
+2005-03-21 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-ppc.c (is_ppc_elf_target): Move to linker part of file.
+ (ppc_elf_merge_private_bfd_data): Likewise.
+
+2005-03-21 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-ppc.c (struct elf_linker_section): Remove rel_section.
+ (ppc_elf_create_linker_section): Don't create rel_section.
+ (elf_create_pointer_linker_section): Don't size relocs.
+ (elf_finish_pointer_linker_section): Remove relative_reloc parm.
+ Don't generate relocs.
+ (ppc_elf_relocate_section): Adjust calls to
+ elf_finish_pointer_linker_section.
+
+2005-03-21 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-ppc.c (is_ppc_elf_target): New function.
+ (ppc_elf_merge_private_bfd_data): Use it rather than just testing
+ for bfd_target_elf_flavour. Do this test before endian check.
+ (ppc_elf_add_symbol_hook): Use is_pcc_elf_target.
+ (ppc_elf_size_dynamic_sections): Likewise.
+
+2005-03-20 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf-bfd.h (elf_backend_data): Add int to
+ elf_backend_section_from_shdr.
+ (bfd_elf_section_data): Update comment for this_idx.
+ (_bfd_elf_make_section_from_shdr): Add int.
+ * elfxx-mips.h (_bfd_mips_elf_section_from_shdr): Likewise.
+
+ * elf.c (_bfd_elf_make_section_from_shdr): Take section index
+ and use it to set this_idx in bfd_elf_section_data.
+ (bfd_section_from_shdr): Pass shindex to
+ _bfd_elf_make_section_from_shdr.
+ (_bfd_elf_section_from_bfd_section): Use this_idx in
+ bfd_elf_section_data to find section index.
+
+ * elf32-arm.c (elf32_arm_section_from_shdr): Take section
+ index and pass it to _bfd_elf_make_section_from_shdr.
+ * elf32-i370.c(i370_elf_section_from_shdr): Likewise.
+ * elf32-ppc.c (ppc_elf_section_from_shdr): Likewise.
+ * elf32-sh64.c (sh64_backend_section_from_shdr): Likewise.
+ * elf32-v850.c (v850_elf_section_from_shdr): Likewise.
+ * elf64-alpha.c (elf64_alpha_section_from_shdr): Likewise.
+ * elf64-hppa.c (elf64_hppa_section_from_shdr): Likewise.
+ * elf64-x86-64.c (elf64_x86_64_section_from_shdr): Likewise.
+ * elfxx-ia64.c (elfNN_ia64_section_from_shdr): Likewise.
+ * elfxx-mips.c (_bfd_mips_elf_section_from_shdr): Likewise.
+
+2005-03-19 Danny Smith <dannysmith@users.sourceforge.net>
+ Ross Ridge <rridge@csclub.uwaterloo.ca>
+
+ * peicode.h (pe_ILF_build_a_bfd): Strip only one prefix
+ character in IMPORT_NAME_UNDECORATE and IMPORT_NAME_NOPREFIX
+ cases. Add comment.
+
+2005-03-18 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elflink.c (elf_mark_used_section): Remove check for special
+ sections.
+
+2005-03-18 Andreas Schwab <schwab@suse.de>
+
+ * elfxx-ia64.c (elfNN_ia64_install_value): Change type of insn
+ from bfd_vma to ia64_insn, remove broken cast.
+
+2005-03-18 C Jaiprakash <cjaiprakash@noida.hcltech.com>
+
+ * elf32-m68k.c (elf_cfv4e_plt0_entry): plt entry for coldfire v4e.
+ (elf_m68k_adjust_dynamic_symbol,elf_m68k_finish_dynamic_symbol,
+ elf_m68k_finish_dynamic_sections): Use it.
+
+2005-03-17 Paul Brook <paul@codesourcery.com>
+ Dan Jacobowitz <dan@codesourcery.com>
+ Mark Mitchell <mark@codesourcery.com>
+
+ * elf32-arm.c (elf32_arm_modify_segment_map): New function.
+ (elf32_arm_additional_program_headers): Likewise.
+ (elf_backend_modify_segment_map): Define.
+ (elf_backend_additional_program_headers): Likewise.
+ (elf32_arm_symbian_modify_segment_map): Use
+ elf32_arm_modify_segment_map.
+
+2005-03-18 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elflink.c (elf_mark_used_section): Check bfd_is_const_section
+ for special sections.
+
+2005-03-18 Alan Modra <amodra@bigpond.net.au>
+
+ * elf-bfd.h (_bfd_elf_link_renumber_dynsyms): Delete.
+ * elflink.c (_bfd_elf_link_renumber_dynsyms): Make static, add
+ section_sym_count param, and return number of section symbols.
+ (bfd_elf_size_dynamic_sections): Clear section symbol area of
+ .dynsym contents. Don't bother calling swap_symbol_out on the
+ first all-zero dynsym.
+ (elf_mark_used_section): Formatting. Avoid twiddling flags in
+ special sections like bfd_abs_section.
+ (bfd_elf_gc_sections): Spelling fix.
+
+2005-03-16 Fred Fish <fnf@specifixinc.com>
+
+ PR binutils/790
+ * dwarf2.c (read_indirect_string): Fix apparent typo, check
+ dwarf_str_buffer allocation, not dwarf_abbrev_buffer.
+
+2005-03-16 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elflink.c (elf_mark_used_section): New.
+ (bfd_elf_gc_sections): Call elf_gc_mark_section for
+ non-relocatable link if we don't do GC.
+
+2005-03-16 Nick Clifton <nickc@redhat.com>
+ Ben Elliston <bje@au.ibm.com>
+
+ * configure.in (werror): New switch: Add -Werror to the
+ compiler command line. Enabled by default. Disable via
+ --disable-werror.
+ * configure: Regenerate.
+
+2005-03-16 Nick Clifton <nickc@redhat.com>
+
+ * ecoff.c: Convert to ISO C90 formatting.
+
+2005-03-16 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-ppc.c: Divide file into general and linker specific
+ functions. Sort linker functions into roughly the order in which
+ they are called by the ELF linker code.
+
+2005-03-16 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-ppc.c (ppc_elf_create_linker_section): Set SEC_LINKER_CREATED
+ on section. Correct comment, and add FIXME.
+ (ppc_elf_additional_program_headers): Don't bump header count for
+ interp. Test SEC_ALLOC, not SEC_LOAD, and don't test size.
+ (ppc_elf_size_dynamic_sections): Don't strip sdata and sdata2, but
+ do allocate memory if they need it.
+
+2005-03-15 Mikkel Krautz <krautz@gmail.com>
+
+ * config.bfd (x86_64-elf): Add target.
+
+2005-03-15 Alan Modra <amodra@bigpond.net.au>
+
+ * po/es.po: Commit new Spanish translation.
+
+2005-03-14 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elfxx-ia64.c (elfNN_ia64_relocate_section): Set symbo name
+ for global symbol when reporting overflow.
+
+2005-03-11 Jakub Jelinek <jakub@redhat.com>
+
+ * libbfd-in.h (_bfd_ar_spacepad): New prototype.
+ * libbfd.h: Rebuilt.
+ * archive.c (_bfd_ar_spacepad): New function.
+ (_bfd_construct_extended_name_table, _bfd_write_archive_contents,
+ bsd_write_armap, _bfd_archive_bsd_update_armap_timestamp,
+ coff_write_armap): Use it.
+ (bfd_ar_hdr_from_filesystem): Likewise. Fix HP-UX large
+ uid/gid support.
+ * archive64.c (bfd_elf64_archive_write_armap): Use _bfd_ar_spacepad.
+
+2005-03-10 Mark Kettenis <kettenis@gnu.org>
+
+ * archive.c (_bfd_look_for_bfd_in_cache): Move declaration of
+ has_table to the start of the function.
+
+2005-03-10 Ben Elliston <bje@au.ibm.com>
+
+ * archive.c: Include hashtab.h.
+ (struct ar_cache): Rename `arelt' to `arbfd' and remove `next'.
+ (_bfd_look_for_bfd_in_cache): Reimplement using htab_find.
+ (hash_file_ptr): New function.
+ (eq_file_ptr): Likewise.
+ (_bfd_add_bfd_to_archive_cache): Reimplement using a hash table.
+ * libbfd-in.h: Include hashtab.h.
+ (struct artdata): Change `cache' member type to htab_t.
+ * libbfd.h: Rebuild.
+
+2005-03-08 Daniel Jacobowitz <dan@codesourcery.com>
+
+ * configure.in: Bump version to 2.16.90.
+ * configure: Regenerated.
+
+2005-03-07 Jakub Jelinek <jakub@redhat.com>
+
+ * opncls.c (opncls_bread, opncls_bclose): Fix if pread resp.
+ close is a function like macro in system headers.
+
+2005-03-07 Alan Modra <amodra@bigpond.net.au>
+
+ PR ld/778
+ * elf32-hppa.c (elf32_hppa_create_dynamic_sections): Reinstate
+ _GLOBAL_OFFSET_TABLE_ as a normal dynamic symbol.
+
+2005-03-06 Alan Modra <amodra@bigpond.net.au>
+
+ * elf.c (elfcore_grok_win32pstatus): Warning fixes.
+
+2005-03-05 Alan Modra <amodra@bigpond.net.au>
+
+ * po/bfd.pot: Regenerate.
+
+2005-03-05 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (update_plt_info): Don't mark new ABI call syms
+ with is_func.
+ (func_desc_adjust): Force dot-syms local in executables as well
+ as shared libs.
+
+2005-03-04 David Daney <ddaney@avtrex.com>
+
+ * elfxx-mips.c (mips_elf_calculate_relocation): Handle special
+ '__gnu_local_gp' symbol used by gas -mno-shared.
+
+2005-03-03 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf-bfd.h (elf_backend_data): Add "const char *" to
+ elf_backend_section_from_phdr.
+
+ * elf.c (bfd_section_from_phdr): Pass "proc" to the
+ elf_backend_section_from_phdr hook.
+
+2005-03-02 Daniel Jacobowitz <dan@codesourcery.com>
+ Joseph Myers <joseph@codesourcery.com>
+
+ * elfxx-mips.c (struct mips_got_entry): Add tls_type.
+ (struct mips_got_info): Add tls_gotno, tls_assigned_gotno,
+ and tls_ldm_offset.
+ (struct mips_elf_got_per_bfd_arg): Add global_count.
+ (struct mips_elf_count_tls_arg): New.
+ (struct mips_elf_hash_sort_data): Update comment for min_got_dynindx.
+ (struct mips_elf_link_hash_entry): Add tls_type and tls_got_offset.
+ (GOT_NORMAL, GOT_TLS_GD, GOT_TLS_LDM, GOT_TLS_IE)
+ (GOT_TLS_OFFSET_DONE, GOT_TLS_DONE): Define.
+ (TLS_RELOC_P): Define.
+ (TP_OFFSET, DTP_OFFSET): Define.
+ (dtprel_base, tprel_base): New functions.
+ (mips_elf_link_hash_newfunc): Initialize tls_type.
+ (mips_elf_got_entry_hash, mips_elf_got_entry_eq)
+ (mips_elf_multi_got_entry_hash, mips_elf_multi_got_entry_eq): Handle
+ TLS entries.
+ (mips_tls_got_relocs, mips_elf_count_local_tls_relocs)
+ (mips_elf_count_global_tls_entries, mips_elf_count_global_tls_relocs)
+ (mips_elf_output_dynamic_relocation, mips_elf_initialize_tls_slots)
+ (mips_tls_got_index): New functions.
+ (mips_elf_local_got_index): Add new R_SYMNDX, H, and R_TYPE
+ arguments. Pass them to mips_elf_create_local_got_entry. Use
+ mips_tls_got_index.
+ (mips_elf_global_got_index): Add new R_TYPE and INFO arguments.
+ Handle TLS entries.
+ (mips_elf_got_page, mips_elf_got16_entry): Update calls to
+ mips_elf_create_local_got_entry.
+ (mips_elf_create_local_got_entry): Add new R_SYMNDX, H, and R_TYPE
+ arguments. Handle TLS entries.
+ (mips_elf_sort_hash_table_f): Add non-TLS assertions.
+ (mips_elf_record_local_got_symbol): Add new TLS_FLAG argument. Handle
+ TLS entries.
+ (mips_elf_record_global_got_symbol): Likewise.
+ (mips_elf_make_got_per_bfd): Initialize new mips_got_info members.
+ Count TLS entries.
+ (mips_elf_merge_gots): Handle TLS entries when merging.
+ (mips_elf_initialize_tls_index): New function.
+ (mips_elf_set_global_got_offset): Handle TLS entries.
+ (mips_elf_adjust_gp): Handle TLS.
+ (mips_elf_multi_got): Remove redundant call to
+ mips_elf_resolve_final_got_entries. Initialize global_count.
+ Correct a comment. Initialize new TLS members of mips_got_info.
+ Assign TLS GOT indexes for new GOTs.
+ (mips_elf_create_got_section): Initialize new TLS members of
+ mips_got_info.
+ (mips_elf_calculate_relocation): Handle TLS relocs.
+ (_bfd_mips_elf_check_relocs): Likewise. Update calls to changed
+ functions.
+ (_bfd_mips_elf_always_size_sections): Handle TLS.
+ (_bfd_mips_elf_size_dynamic_sections): Likewise.
+ (_bfd_mips_elf_finish_dynamic_symbol): Likewise. Update calls to
+ changed functions.
+ (_bfd_mips_elf_copy_indirect_symbol): Copy tls_type.
+ (_bfd_mips_elf_hide_symbol): Handle TLS.
+ * elfn32-mips.c (elf_mips_howto_table_rel, elf_mips_howto_table_rela)
+ (mips_reloc_map): Add TLS relocs.
+ * elf32-mips.c (elf_mips_howto_table_rel, mips_reloc_map): Likewise.
+ * elf64-mips.c (mips_elf64_howto_table_rel)
+ (mips_elf64_howto_table_rela, mips_reloc_map): Likewise.
+ * reloc.c: Define new MIPS TLS relocations.
+ * libbfd.h, bfd-in2.h: Regenerated.
+
+2005-03-02 Jan Beulich <jbeulich@novell.com>
+
+ * Makefile.am: Add dependency of cache.o on libiberty.h.
+ * cache.c: Include libiberty.h.
+ (bfd_open_file): Use unlink_if_ordinary instead of unlink.
+
+2005-03-01 Zack Weinberg <zack@codesourcery.com>
+
+ * elf.c (bfd_section_from_shdr <default case>): Call
+ elf_backend_section_from_shdr hook unconditionally, and return
+ what it returns.
+ (bfd_section_from_phdr): Similarly, for elf_backend_section_from_phdr.
+ * elfxx-target.h (elf_backend_section_from_shdr)
+ (elf_backend_section_from_phdr): Default to
+ _bfd_elf_make_section_from_shdr and _bfd_elf_make_section_from_phdr
+ respectively.
+
+2005-03-01 Alan Modra <amodra@bigpond.net.au>
+
+ * targets.h: Typo fix.
+ * bfd-in2.h: Regenerate.
+
+ * bout.c (b_out_write_object_contents): Don't use sizeof on host
+ structs to size on-disk structures.
+ (b_out_set_section_contents): Size the external struct, not the
+ internal one for on-disk size.
+ (b_out_sizeof_headers): Likewise.
+
+2005-03-01 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (ppc64_elf_size_stubs): Override defined dot-sym
+ entry points with the func descriptor as well as undefweak.
+
+2005-02-28 Ross Ridge <rridge@csclub.uwaterloo.ca>
+
+ * peicode.h (pe_ILF_build_a_bfd): Do not assume that an @ will be
+ present when IMPORT_NAME_UNDOECRATE is used.
+
+2005-02-28 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR 757
+ * elf-bfd.h (_bfd_elf_merge_symbol): Add a pointer to unsigned
+ int.
+
+ * elf32-sh-symbian.c (sh_symbian_relocate_section): Pass NULL
+ to _bfd_elf_merge_symbol.
+
+ * elflink.c (_bfd_elf_merge_symbol): Use the pointer to
+ unsigned int to return the alignment of the old common symbol
+ in the dynamic object.
+ (_bfd_elf_add_default_symbol): Pass NULL to
+ _bfd_elf_merge_symbol.
+ (elf_link_add_object_symbols): Pass &old_alignment to
+ _bfd_elf_merge_symbol. Get the alignment of the new common
+ symbol in the dynamic object.
+
+2005-02-24 Ben Elliston <bje@au.ibm.com>
+
+ * coffcode.h (coff_sym_filepos): Remove GNU960 conditional code.
+ * format.c (bfd_check_format_matches): Likewise.
+ * archive.c (BFD_GNU960_ARMAG): Likewise.
+ (bfd_generic_archive_p): Likewise.
+ (_bfd_write_archive_contents): Likewise.
+
+2005-02-24 H.J. Lu <hongjiu.lu@intel.com>
+
+ * configure.in: (AM_INIT_AUTOMAKE): Set version to 2.15.95.
+ * configure: Regenerate.
+
+2005-02-24 Julian Brown <julian@sirius.codesourcery.com>
+
+ * elflink.c (elf_link_add_object_symbols): Force symbols in discarded
+ COMDAT group sections to have default visibility.
+
+2005-02-24 Alan Modra <amodra@bigpond.net.au>
+
+ * coffcode.h (coff_print_aux): Warning fix.
+ * elf-m10300.c (mn10300_elf_relax_section): Use section->id
+ instead of section pointer to identify.
+ * coff-h8300.c (h8300_reloc16_extra_cases): Likewise. Allocate
+ the correct size buffer for local sym mangling too.
+ (h8300_bfd_link_add_symbols): Likewise.
+ * elf32-sh-symbian.c (sh_symbian_process_embedded_commands): Fix
+ warning.
+ * elf32-sh64.c (shmedia_prepare_reloc): Use %B and %p in error message
+ * elf32-xtensa.c (literal_value_hash): Warning fix.
+ * versados.c (process_otr): Warning fix.
+ (versados_canonicalize_reloc): Likewise.
+ * vms-gsd.c (_bfd_vms_slurp_gsd): Warning fix.
+ * vms.c (fill_section_ptr): Warning fix.
+
+2005-02-23 H.J. Lu <hongjiu.lu@intel.com>
+
+ * coff-tic54x.c (SWAP_OUT_RELOC_EXTRA): Defined.
+ * coff-tic80.c (SWAP_OUT_RELOC_EXTRA): Likewise.
+
+2005-02-23 Nick Clifton <nickc@redhat.com>
+
+ * elfxx-mips.c (mips_elf_create_dynamic_relocation): Initialise
+ the relvaddr field of the Elf32_crinfo structure.
+
+ * elf32-m68hc1x.c (elf32_m68hc11_relocate_section): Initialise
+ variables that are passed by reference to
+ m68hc11_get_relocation_value in case that function does not
+ initialise them.
+
+ * elf32-cr16c.c (cr16c_elf_final_link_relocate): Remove duplicated
+ return statements and replace with a single return at the end of
+ the function. This helps pacify the flow analysis code in gcc 4.0.
+
+ * elf.c (_bfd_elf_compute_section_file_positions): Initialise
+ strtab to avoid compile time warning.
+
+2005-02-23 Ben Elliston <bje@au.ibm.com>
+
+ * opncls.c (bfd_zalloc): Document this function.
+
+2005-02-21 H.J. Lu <hongjiu.lu@intel.com>
+
+ * coffcode.h (sec_to_styp_flags): Replaced SEC_CLINK with
+ SEC_TIC54X_CLINK. Replace SEC_BLOCK with SEC_TIC54X_BLOCK.
+ Replace SEC_SHARED with SEC_COFF_SHARED.
+ (styp_to_sec_flags): Likewise.
+
+ * elfxx-target.h (TARGET_BIG_SYM): Remove SEC_ARCH_BIT_0.
+ (TARGET_LITTLE_SYM): Likewise.
+
+ * section.c (SEC_ARCH_BIT_0): Removed.
+ (SEC_LINK_DUPLICATES_SAME_CONTENTS): Defined with
+ SEC_LINK_DUPLICATES_ONE_ONLY and SEC_LINK_DUPLICATES_SAME_SIZE.
+ (SEC_SHARED): Renamed to ...
+ (SEC_COFF_SHARED): This.
+ (SEC_BLOCK): Renamed to ...
+ (SEC_TIC54X_BLOCK): This.
+ (SEC_CLINK): Renamed to ...
+ (SEC_TIC54X_CLINK): This.
+ (SEC_XXX): Rearranged. Move SEC_COFF_SHARED_LIBRARY,
+ SEC_COFF_SHARED, SEC_TIC54X_BLOCK and SEC_TIC54X_CLINK to the
+ end.
+ * bfd-in2.h: Regenerated.
+
+2005-02-21 Fred Fish <fnf@specifixinc.com>
+
+ * dwarf2.c (find_abstract_instance_name): Call recursively
+ to handle a DW_AT_specification.
+
+2005-02-21 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * elfxx-mips.c (ecoff_swap_rpdr_out, mips_elf_output_extsym,
+ mips_elf_create_dynamic_relocation,
+ _bfd_mips_elf_size_dynamic_sections, _bfd_mips_elf_final_link):
+ Remove #if 0'd code.
+
+2005-02-21 Alan Modra <amodra@bigpond.net.au>
+
+ * Makefile.am: Run "make dep-am"
+ * Makefile.in: Regenerate.
+
+2005-02-21 Alan Modra <amodra@bigpond.net.au>
+
+ * coffgen.c (bfd_coff_get_comdat_section): Check that
+ coff_section_data isn't NULL.
+
+2005-02-21 Alan Modra <amodra@bigpond.net.au>
+
+ * bfd-in.h (bfd_elf_bfd_from_remote_memory): Warning fix.
+ * coff-m68k.c (bfd_m68k_coff_create_embedded_relocs): Likewise.
+ * coff-rs6000.c (xcoff_write_armap_big): Warning fixes. Remove
+ useless assignments.
+ (xcoff_write_archive_contents_big): Likewise.
+ (_bfd_xcoff_put_ldsymbol_name): Likewise.
+ * coff64-rs6000.c (_bfd_xcoff64_put_ldsymbol_name): Likewise.
+ * coffgen.c (coff_write_symbols): Make "written" a bfd_vma.
+ * cofflink.c (process_embedded_commands): Warning fixes.
+ * cpu-arm.c: Delete unnecessary prototypes. Convert to C90.
+ Warning fixes.
+ * dwarf2.c: Warning fixes.
+ * elf-bfd.h: Likewise.
+ * elf-eh-frame.c: Likewise.
+ * elf-strtab.c: Likewise.
+ * elf.c: Likewise.
+ * elf32-m68k.c: Likewise.
+ * elf32-ppc.c: Likewise.
+ * elf32-sh-symbian.c: Likewise.
+ * elf32-sh.c: Delete unnecessary prototypes. Warning fixes.
+ * elf64-sh64.c: Likewise.
+ * peicode.h: Likewise.
+ * elf64-mmix.c: Warning fixes.
+ * elfcode.h: Likewise.
+ * elfxx-mips.c: Likewise.
+ * libbfd-in.h: Likewise.
+ * libbfd.c: Likewise.
+ * mach-o.c: Likewise.
+ * merge.c: Likewise.
+ * mmo.c: Likewise.
+ * opncls.c: Likewise.
+ * pef.c: Likewise.
+ * srec.c: Likewise.
+ * vms-hdr.c: Likewise.
+ * vms-tir.c: Likewise.
+ * xtensa-isa.c: Likewise.
+ * xtensa-modules.c: Likewise.
+ * xsym.c: Likewise.
+ (pstrcmp): Use correct choice of string lengths. Fix return value.
+ (bfd_sym_module_name): Correct string length.
+ * bfd-in2.h: Regenerate.
+ * libbfd.h: Regenerate.
+
+2005-02-17 Alexandre Oliva <aoliva@redhat.com>
+
+ * elf32-frv.c (elf32_frv_relocate_section): Remove warning from
+ uninitialized check_segment[1] in TLSMOFF case.
+ Reported by Alan Modra.
+ (elf32_frv_relocate_section): Improve errors and warnings.
+
+2005-02-17 Alan Modra <amodra@bigpond.net.au>
+
+ * elf-eh-frame.c (_bfd_elf_discard_section_eh_frame): Fix warning.
+
+2005-02-16 Alan Modra <amodra@bigpond.net.au>
+
+ * coff-arm.c (coff_arm_is_local_label_name): Warning fix.
+ * elf32-frv.c (frvfdpic_relocs_info_hash): Likewise.
+ * pef.c (bfd_pef_scan): Don't ignore return value of
+ bfd_pef_scan_start_address.
+ * mach-o.c (bfd_mach_o_scan): Don't ignore return value of
+ bfd_mach_o_scan_start_address.
+ * elfxx-ia64.c (elfNN_ia64_relax_brl): Rewrite for 32-bit bfd_vma.
+ * elfxx-mips.c: Remove unnecessary prototypes.
+ (sort_dynamic_relocs_64): Abort if not BFD64.
+
+2005-02-16 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (ppc64_elf_edit_toc): Skip toc if size is zero.
+ Skip toc reloc adjust if reloc_count is zero.
+
+2005-02-15 Nigel Stephens <nigel@mips.com>
+ Maciej W. Rozycki <macro@mips.com>
+
+ * elf32-mips.c (elf_mips16_howto_table_rel): New array for MIPS16
+ reloc howtos. Add R_MIPS16_HI16 and R_MIPS16_LO16 relocs and
+ R_MIPS16_GOT16 and R_MIPS16_CALL16 placeholders.
+ (elf_mips16_jump_howto): Move into elf_mips16_howto_table_rel.
+ (elf_mips16_gprel_howto): Likewise. Redefine src_mask and
+ dst_mask.
+ (mips16_gprel_reloc): Remove bit shuffling; call
+ _bfd_mips16_elf_reloc_unshuffle(), _bfd_mips_elf_gprel16_with_gp()
+ and _bfd_mips16_elf_reloc_shuffle() instead.
+ (mips16_reloc_map): New reloc map for MIPS16 relocs.
+ (bfd_elf32_bfd_reloc_type_lookup): Use mips16_reloc_map for MIPS16
+ relocs.
+ (mips_elf32_rtype_to_howto): Fetch MIPS16 howtos from
+ elf_mips16_howto_table_rel.
+ * elf64-mips.c (mips16_elf64_howto_table_rel): New array for
+ MIPS16 REL reloc howtos. Add R_MIPS16_HI16 and R_MIPS16_LO16
+ relocs and R_MIPS16_GOT16 and R_MIPS16_CALL16 placeholders.
+ (elf_mips16_jump_howto): Move into mips16_elf64_howto_table_rel.
+ (elf_mips16_gprel_howto): Likewise. Redefine src_mask and
+ dst_mask.
+ (mips16_elf64_howto_table_rela): New array for MIPS16 RELA
+ reloc howtos. Add R_MIPS16_26, R_MIPS16_GPREL, R_MIPS16_HI16 and
+ R_MIPS16_LO16 relocs and R_MIPS16_GOT16 and R_MIPS16_CALL16
+ placeholders.
+ (mips16_gprel_reloc): Remove bit shuffling; call
+ _bfd_mips16_elf_reloc_unshuffle(), _bfd_mips_elf_gprel16_with_gp()
+ and _bfd_mips16_elf_reloc_shuffle() instead.
+ (mips16_reloc_map): New reloc map for MIPS16 relocs.
+ (bfd_elf64_bfd_reloc_type_lookup): Use mips16_reloc_map for MIPS16
+ relocs.
+ (mips_elf64_rtype_to_howto): Fetch MIPS16 howtos from
+ mips16_elf64_howto_table_rela or mips16_elf64_howto_table_rel.
+ * elfn32-mips.c (elf_mips16_howto_table_rel): New array for MIPS16
+ REL reloc howtos. Add R_MIPS16_HI16 and R_MIPS16_LO16 relocs and
+ R_MIPS16_GOT16 and R_MIPS16_CALL16 placeholders.
+ (elf_mips16_jump_howto): Move into elf_mips16_howto_table_rel.
+ (elf_mips16_gprel_howto): Likewise. Redefine src_mask and
+ dst_mask.
+ (mips16_gprel_reloc): Remove bit shuffling; call
+ _bfd_mips16_elf_reloc_unshuffle(), _bfd_mips_elf_gprel16_with_gp()
+ and _bfd_mips16_elf_reloc_shuffle() instead.
+ (mips16_reloc_map): New reloc map for MIPS16 relocs.
+ (bfd_elf32_bfd_reloc_type_lookup): Use mips16_reloc_map for MIPS16
+ relocs.
+ (mips_elf_n32_rtype_to_howto): Fetch MIPS16 howtos from
+ elf_mips16_howto_table_rela or elf_mips16_howto_table_rel.
+ * elfxx-mips.c (_bfd_mips16_elf_reloc_unshuffle): New function to
+ handle bit shuffling for MIPS16 relocs.
+ (_bfd_mips16_elf_reloc_shuffle): Likewise.
+ (_bfd_mips_elf_lo16_reloc): Use _bfd_mips16_elf_reloc_unshuffle()
+ and _bfd_mips16_elf_reloc_shuffle().
+ (_bfd_mips_elf_generic_reloc): Likewise.
+ (mips_elf_calculate_relocation): Likewise. Handle R_MIPS16_HI16
+ and R_MIPS16_LO16.
+ (mips_elf_obtain_contents): Remove bit shuffling.
+ (mips_elf_perform_relocation): Likewise; call
+ _bfd_mips16_elf_reloc_unshuffle() and _bfd_mips16_elf_reloc_shuffle()
+ instead.
+ (_bfd_mips_elf_relocate_section): Likewise. Handle R_MIPS16_HI16
+ and R_MIPS16_LO16.
+ * elfxx-mips.h (_bfd_mips16_elf_reloc_unshuffle): Declare.
+ (_bfd_mips16_elf_reloc_shuffle): Likewise.
+ * reloc.c (BFD_RELOC_MIPS16_HI16): New reloc.
+ (BFD_RELOC_MIPS16_HI16_S): Likewise.
+ (BFD_RELOC_MIPS16_LO16): Likewise.
+ * bfd-in2.h: Regenerate.
+ * libbfd.h: Regenerate.
+
+2005-02-15 Jan Beulich <jbeulich@novell.com>
+
+ * elfxx-ia64.c (ia64_howto_table): Correct strings for
+ R_IA64_DTPMOD64[LM]SB.
+
+2005-02-14 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elfxx-ia64.c (elfNN_ia64_relax_section): Allow relax
+ backward branch in the same section.
+ (elfNN_ia64_relocate_section): Inform users that the input
+ section is too big to relax br instruction when overflow
+ happens to R_IA64_PCREL21B, R_IA64_PCREL21BI, R_IA64_PCREL21M
+ and R_IA64_PCREL21F.
+
+2005-02-14 Orjan Friberg <orjanf@axis.com>
+
+ * elfcore.h (elf_core_file_p): Move the call to
+ elf_backend_object_p to allow the correct machine to be set before
+ processing the program headers.
+
+2005-02-14 Nick Clifton <nickc@redhat.com>
+
+ PR binutils/716
+ * peicode.h (pe_bfd_copy_private_bfd_data): Copy the large address
+ aware flag from the input bfd to the output bfd.
+
+2005-02-11 Maciej W. Rozycki <macro@mips.com>
+
+ * elf32-mips.c (_bfd_mips_elf32_gprel16_reloc): Reject
+ R_MIPS_LITERAL relocations for external symbols.
+ * elf64-mips.c (mips_elf64_literal_reloc): Likewise.
+ * elfn32-mips.c (mips_elf_literal_reloc): Likewise.
+
+2005-02-11 H.J. Lu <hongjiu.lu@intel.com>
+
+ * bfd-in2.h: Rebuilt.
+
+2005-02-11 Paul Brook <paul@codesourcery.com>
+
+ * elf-bfd.h (struct elf_link_hash_table): Add
+ is_relocatable_executable.
+ * elf.c (_bfd_elf_link_hash_table_init): Initialize it.
+ * elflink.c (bfd_elf_link_record_dynamic_symbol): Create local dynamic
+ symbols in relocatable executables.
+ (bfd_elf_record_link_assignment): Create dynamic section symbols in
+ relocatable executables.
+ (_bfd_elf_link_renumber_dynsyms): Ditto.
+ (bfd_elf_final_link): Ditto.
+ * elf32-arm.c (elf32_arm_final_link_relocate): Copy absolute
+ relocations into relocatable executables.
+ (elf32_arm_check_relocs): Crate dynamic sections for relocatable
+ executables. Also copy absolute relocations.
+ (elf32_arm_adjust_dynamic_symbol): Don't create copy relocations
+ in relocatable executables.
+ (allocate_dynrelocs): Copy relocations for relocatable executables.
+ Output dynamic symbols for symbols defined in linker scripts.
+
+2005-02-11 Nick Clifton <nickc@redhat.com>
+
+ * libbfd.c (read_signed_leb128): Use an unsigned type for 'shift'
+ to avoid a compile time warning.
+
+ * coff-alpha.c (alpha_adjust_reloc_in): Remove redundant test from
+ BFD_ASSERT.
+
+ * coff-tic4x.c (coff_rtype_to_howto): Move definition before
+ inclusion of coffcode.h so that it is actually picked up.
+
+ * coffcode.h (coff_std_swap_table): Add an unused attribute in
+ case it is not used.
+
+ * elf32-ip2k.c (ip2k_call_opcode, IS_CALL_OPCODE): Remove unused
+ structure and macro.
+
+ * elf32-iq2000.c (iq2000_reloc_map): Remove unused structure and
+ array.
+
+ * elf32-m32r.c (m32r_reloc_map_old): Use #ifdef USE_M32R_OLD_RELOC
+ to protect the declaration of this array.
+
+ * xsym.c (bfd_sym_parse_contained_variables_table_entry_v32):
+ Avoid call to memcpy with a size of 0.
+
+2005-02-12 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (toc_adjusting_stub_needed): Return true for
+ old-style branches to undefined dot-symbols which will be
+ satisfied by a plt call.
+
+2005-02-11 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (move_plt_plist): New function, extracted from..
+ (ppc64_elf_copy_indirect_symbol): ..here.
+ (func_desc_adjust): Use move_plt_plist.
+
+2005-02-10 Paul Brook <paul@codesourcery.com>
+
+ * elf32-arm.c (elf32_arm_final_link_relocate): Handle R_ARM_THM_PC9.
+
+2005-02-10 Paul Brook <paul@codesourcery.com>
+
+ * elflink.c (bfd_elf_record_link_assignment): Make hidden and internal
+ symbols local.
+ (elf_link_renumber_hash_table_dynsyms): Ignore local symbols.
+ (elf_link_renumber_local_hash_table_dynsyms): New function.
+ (_bfd_elf_link_renumber_dynsyms): Number local dynamic symbols.
+
+2005-02-10 Jakub Jelinek <jakub@redhat.com>
+
+ * bfd-in.h (BFD_LINKER_CREATED): Define.
+ * bfd-in2.h: Rebuilt.
+ * elflink.c (bfd_elf_size_dynamic_sections): Disregard
+ BFD_LINKER_CREATED bfds when determining input bfds without
+ .note.GNU-stack section.
+
+2005-02-10 Maciej W. Rozycki <macro@mips.com>
+
+ * elf64-mips.c (mips16_gprel_reloc): Update a comment.
+ * elfn32-mips.c (mips16_gprel_reloc): Keep R_MIPS16_GPREL
+ relocations against external symbols unchanged.
+
+2005-02-08 Paul Brook <paul@codesourcery.com>
+
+ * elflink.c (elf_link_input_bfd): Ignore symbols from null input
+ sections.
+
+2005-02-08 Hans-Peter Nilsson <hp@axis.com>
+
+ * elflink.c (elf_link_add_object_symbols): Don't add "warning: "
+ prefix here.
+
+2005-02-07 Maciej W. Rozycki <macro@mips.com>
+
+ * elf64-mips.c: Fix formatting throughout.
+
+2005-02-07 Maciej W. Rozycki <macro@mips.com>
+
+ * elfn32-mips.c (elf_mips_howto_table_rela): Fix a comment typo.
+
+2005-02-07 Alexandre Oliva <aoliva@redhat.com>
+
+ * elf32-frv.c (FRVFDPIC_SYM_LOCAL): Remove special handling for
+ *ABS*/*UND* sections.
+ (elf32_frv_relocate_section): Move zero-addend-required error...
+ (_frv_emit_got_relocs_plt_entries): ... here. Report error for
+ missing needed TLS section.
+
+2005-02-07 Hans-Peter Nilsson <hp@axis.com>
+
+ * aoutx.h (NAME(aout,find_nearest_line)): Correct case for N_SO
+ being the last symbol.
+ (aout_link_add_symbols): Just return TRUE if a warning
+ symbol was last.
+
+2005-02-07 Maciej W. Rozycki <macro@mips.com>
+
+ * elf32-mips.c (mips_elf_gprel32_reloc): Reject
+ R_MIPS_GPREL32 relocations against external symbols.
+ * elf64-mips.c (mips_elf64_gprel32_reloc): Replace an incorrect
+ comment.
+
+2005-02-07 Alan Modra <amodra@bigpond.net.au>
+
+ * elf-bfd.h (elf_string_from_elf_strtab): Delete macro.
+ * elf.c (bfd_elf_string_from_elf_section): Expand occurrence of
+ elf_string_from_elf_strtab.
+ (_bfd_elf_setup_group_pointers, bfd_section_from_shdr): Likewise.
+ (bfd_section_from_shdr): For SHT_SYMTAB, load SHT_SYMTAB_SHNDX too
+ if it exists. Don't do the reverse for SHT_SYMTAB_SHNDX. For
+ SHT_STRTAB, check whether the strtab is for symtab or dynsymtab by
+ looking at cached symtab info first, before iterating over headers.
+ For SHT_REL and SHT_RELA, load dynsymtab if needed.
+ * elfcode.h (elf_object_p): Don't load section header stringtab
+ specially.
+
+2005-02-06 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf32-i386.c (elf_i386_relocate_section): Disallow R_386_GOTOFF
+ against protected function when building shared library.
+
+ PR 584
+ * elf64-x86-64.c (is_32bit_relative_branch): New.
+ (elf64_x86_64_relocate_section): Alllow R_X86_64_PC32 on a
+ protected function symbol when building shared library for
+ 32bit relative branch instruction.
+
+2005-02-06 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (add_symbol_adjust): Don't create fake descriptor
+ syms when doing a relocatable link.
+ (ppc64_elf_gc_mark_hook): Check that syms are defined before looking
+ at u.def.section.
+ (ppc64_elf_tls_setup): Likewise.
+ (ppc64_elf_edit_opd): Don't use an undefined func desc sym.
+
+2005-02-04 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (struct ppc_link_hash_entry): Add "fake".
+ (link_hash_newfunc): Clear all locals using memset.
+ (make_fdh): Remove flags param. Always create fake func desc
+ weak. Link the descriptor with the code entry sym.
+ (ppc64_elf_archive_symbol_lookup): Don't return fake syms.
+ (add_symbol_adjust): Adjust make_fdh call.
+ (func_desc_adjust): Likewise. Twiddle any pre-existing fake
+ descriptor to strong undefined if code entry is strong.
+
+2005-02-04 Alan Modra <amodra@bigpond.net.au>
+
+ * elflink.c (bfd_elf_record_link_assignment): Do "provide" symbol
+ lookup here. Set to new before calling bfd_link_repair_undef_list.
+ (elf_smash_syms): Check that u.undef.weak isn't the not_needed bfd.
+
+2005-02-03 Alan Modra <amodra@bigpond.net.au>
+
+ * linker.c (_bfd_link_hash_newfunc): Set all local fields.
+
+2005-02-03 Alan Modra <amodra@bigpond.net.au>
+
+ * linker.c (_bfd_generic_link_add_one_symbol): Set u.undef.weak.
+ * elflink.c (elf_smash_syms): Restore symbols that were undefweak
+ before the as-needed lib was loaded. Abort on unexpected refs.
+
+2005-02-02 Alan Modra <amodra@bigpond.net.au>
+
+ * elflink.c (elf_smash_syms): Expand comments.
+ (elf_link_add_object_symbols): Only call elf_smash_syms for
+ as-needed dynamic objects.
+
+ * elfxx-ia64.c (elfNN_ia64_new_elf_hash_entry): Don't clear
+ everything, just the field specific to ia64.
+ * elf64-hppa.c (elf64_hppa_new_dyn_hash_entry): Likewise.
+
+2005-02-01 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (func_desc_adjust): Move code creating func desc sym to..
+ (make_fdh): ..here. New function. Don't set BSF_OBJECT for
+ undefined syms.
+ (struct add_symbol_adjust_data): New.
+ (add_symbol_adjust): Make an undefweak func desc for old ABI
+ objects to link with --as-needed shared libs. Return fail status.
+ Don't adjust old ABI func entry sym to weak if func desc syms
+ isn't defined.
+ (ppc64_elf_check_directives): Adjust call to add_symbol_adjust,
+ and return status.
+
+2005-02-01 Hans-Peter Nilsson <hp@axis.com>
+
+ * cpu-cris.c (get_compatible): Rearrange disabled code and comment
+ for clarity.
+
+2005-02-01 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (ppc64_elf_check_directives): Move undefs list fixup..
+ * linker.c (bfd_link_repair_undef_list): ..to new function, but don't
+ remove anything but new and undefweak.
+ * elflink.c (_bfd_elf_link_create_dynamic_sections): Override any
+ existing _DYNAMIC.
+ (_bfd_elf_create_dynamic_sections): Formatting.
+ (bfd_elf_record_link_assignment): Call bfd_link_repair_undef_list.
+ (_bfd_elf_merge_symbol): Don't handle as-needed syms here.
+ (struct elf_smash_data): New.
+ (elf_smash_syms): New function.
+ (elf_link_add_object_symbols): Call elf_smash_syms. Don't add
+ unneeded dynamic objects to loaded list.
+ (elf_link_output_extsym): Don't handle as-needed here. Strip
+ bfd_link_hash_new symbols.
+ * elf32-cris.c (elf_cris_discard_excess_program_dynamics): Don't
+ delref when dynindx is already -1.
+ * elf64-alpha.c (elf64_alpha_output_extsym): Strip bfd_link_hash_new
+ symbols.
+ * elfxx-mips.c (mips_elf_output_extsym): Likewise.
+
+2005-02-01 Ben Elliston <bje@au.ibm.com>
+
+ * elfxx-target.h (bfd_elfNN_bfd_discard_group): Redefine.
+
+2005-02-01 Ben Elliston <bje@au.ibm.com>
+
+ * aout-arm.c, aout-target.h, aoutx.h, archive.c, armnetbsd.c,
+ bfd-in.h, bfdio.c, coff-alpha.c, coff-arm.c, coff-h8300.c,
+ coff-i860.c, coff-mcore.c, coff-or32.c, coff-ppc.c, coff-sh.c,
+ coff-sparc.c, coffcode.h, coffgen.c, cofflink.c, cpu-cris.c,
+ cpu-h8500.c, cpu-ns32k.c, ecoff.c, ecofflink.c, elf.c,
+ elf32-dlx.c, elf32-fr30.c, elf32-frv.c, elf32-hppa.c,
+ elf32-i860.c, elf32-ip2k.c, elf32-m32r.c, elf32-sh.c,
+ elf32-v850.c, elf64-mips.c, elf64-sparc.c, elflink.c,
+ i386aout.c, i386msdos.c, i386os9k.c, ieee.c, mach-o.c,
+ nlm32-sparc.c, oasys.c, opncls.c, pdp11.c, pe-mips.c, peXXigen.c,
+ pef.c, peicode.h, reloc.c, riscix.c, section.c, simple.c, som.c,
+ sparclynx.c, targets.c, vms-misc.c, vms-tir.c, xsym.c,
+ hosts/delta68.h, hosts/vaxbsd.h: Remove #if 0'd code
+ throughout. Similarly, collapse #if 1'd code.
+
+2005-02-01 Ben Elliston <bje@au.ibm.com>
+
+ * elf-bfd.h (bfd_elf_discard_group): Remove.
+ * elf.c (bfd_elf_discard_group): Likewise.
+ * elfxx-target.h (bfd_elfNN_bfd_discard_group): Remove macro.
+
+2005-01-31 Richard Sandiford <rsandifo@redhat.com>
+
+ * elf-bfd.h (elf_backend_data): Add elf_backend_eh_frame_address_size.
+ (_bfd_elf_eh_frame_address_size): Declare.
+ * elfxx-target.h (elf_backend_eh_frame_address_size): Define a default.
+ (elfNN_bed): Initialize elf_backend_eh_frame_address_size.
+ * elfxx-mips.h (_bfd_mips_elf_eh_frame_address_size): Declare.
+ (elf_backend_eh_frame_address_size): Define.
+ * elfxx-mips.c (_bfd_mips_elf_eh_frame_address_size): New function.
+ * elf-eh-frame.c (_bfd_elf_discard_section_eh_frame): Get the address
+ size from the new backend hook.
+ (_bfd_elf_write_section_eh_frame): Likewise.
+ (_bfd_elf_eh_frame_address_size): New function.
+
+2005-01-31 Andrew Cagney <cagney@gnu.org>
+
+ * configure: Regenerate to track ../gettext.m4.
+
+2005-01-31 Mark Mitchell <mark@codesourcery.com>
+
+ * elf32-arm.c (elf32_arm_symbian_special_sections): Do not set
+ SHF_WRITE for .init_array, .fini_array, and .preinit_array.
+
+2005-01-31 Nick Clifton <nickc@redhat.com>
+
+ * confg.bfd: Make targets scheduled for obsoletion (m68k-lynxos,
+ sparc-lynxos, vax-vms) be obsolete.
+
+2005-01-28 Daniel Jacobowitz <dan@codesourcery.com>
+
+ * elf-bfd.h (struct elf_backend_data): Add minpagesize.
+ * elf32-arm.c (ELF_MINPAGESIZE): Define.
+ * elf32-ppc.c (ELF_MINPAGESIZE): Define.
+ * elfcode.h (elf_object_p): Use minpagesize instead of
+ maxpagesize.
+ * elfxx-target.h (ELF_MINPAGESIZE): Default to ELF_MAXPAGESIZE.
+ (elfNN_bed): Include ELF_MINPAGESIZE.
+
+2005-01-28 Julian Brown <julian@codesourcery.com>
+
+ * bin-in.h (bfd_elf32_arm_set_target_relocs): Update prototype.
+ * bin-in2.h (bfd_elf32_arm_set_target_relocs): Update prototype.
+ * elf32-arm.c (elf32_arm_link_hash_table): Add fix_v4bx flag.
+ (bfd_elf32_arm_set_target_relocs): Add formal parameter fix_v4bx for
+ passing flag value from ld. Set flag value in global hash table entry.
+ (elf32_arm_final_link_relocate): Add code to implement R_ARM_V4BX
+ relocation.
+
+2005-01-27 Andrew Cagney <cagney@gnu.org>
+
+ * configure: Regenerate to track ../gettext.m4 change.
+
+2005-01-25 Mark Mitchell <mark@codesourcery.com>
+
+ * elf32-arm.c (elf_backend_default_use_rela_p): Define to zero for
+ SymbianOS.
+
+2005-01-25 Alexandre Oliva <aoliva@redhat.com>
+
+ 2004-12-10 Alexandre Oliva <aoliva@redhat.com>
+ * elf32-frv.c (elf32_frv_relocate_section): Force local binding
+ for TLSMOFF.
+ * reloc.c: Add R_FRV_TLSMOFF.
+ * elf32-frv.c (elf32_frv_howto_table): Likewise.
+ (frv_reloc_map, frv_reloc_type_lookup): Map it.
+ (elf32_frv_relocate_section): Handle it.
+ (elf32_frv_check_relocs): Likewise.
+ * libbfd.h, bfd-in2.h: Rebuilt.
+ 2004-11-26 Alexandre Oliva <aoliva@redhat.com>
+ * elf32-frv.c (_frvfdpic_emit_got_relocs_plt_entries): Don't crash
+ when given an undefweak TLS symbol. Fix constant TLS PLT entries
+ such that they return the constant in gr9.
+ (_frvfdpic_relax_tls_entries): Don't crash for undefweak TLS
+ symbols.
+ (_frvfdpic_size_got_plt): Set _cooked_size of dynamic sections.
+ too, such that they shrink on relaxation.
+ (elf32_frvfdpic_finish_dynamic_sections): Check __ROFIXUP_END__ as
+ marking the position right past the _GLOBAL_OFFSET_TABLE_ value.
+ (_frvfdpic_assign_plt_entries): Shrink constant TLS PLT entries
+ if we can guarantee the use of 16-bit constants.
+ 2004-11-10 Alexandre Oliva <aoliva@redhat.com>
+ Introduce TLS support for FR-V FDPIC.
+ * reloc.c: Add TLS relocations.
+ * elf32-frv.c (elf32_frv_howto_table): Add TLS relocations.
+ (elf32_frv_rel_tlsdesc_value_howto): New.
+ (elf32_frv_rel_tlsoff_howto): New.
+ (frv_reloc_map): Add new mappings.
+ (struct frvfdpic_elf_link_hash_table): Add pointer to summary
+ reloc information.
+ (frvfdpic_dynamic_got_plt_info): New.
+ (frvfdpic_plt_tls_ret_offset): New.
+ (ELF_DYNAMIC_INTERPRETER, DEFAULT_STACK_SIZE): Move earlier.
+ (struct _frvfdpic_dynamic_got_info): Likewise. Add TLS members.
+ (struct _frvfdpic_dynamic_got_plt_info): Likewise.
+ (FRVFDPIC_SYM_LOCAL): Regard symbols defined in the absolute
+ section as local.
+ (struct frvfdpic_relocs_info): Add TLS fields.
+ (frvfdpic_relocs_info_hash): Warning clean up.
+ (frvfdpic_relocs_info_find): Initialize tlsplt_entry.
+ (frvfdpic_pic_merge_early_relocs_info): Merge TLS fields.
+ (FRVFDPIC_TLS_BIAS): Define.
+ (tls_biased_base): New.
+ (_frvfdpic_emit_got_relocs_plt_entries): Deal with TLS
+ relocations.
+ (frv_reloc_type_lookup): Likewise.
+ (frvfdpic_info_to_howto_rel): Likewise.
+ (elf32_frv_relocate_section): Likewise.
+ (_frv_create_got_section): Create the PLT section here.
+ (elf32_frvfdpic_create_dynamic_sections): Not here.
+ (_frvfdpic_count_nontls_entries): Move out of...
+ (_frvfdpic_count_got_plt_entries): ... here.
+ (_frvfdpic_count_tls_entries): Likewise. Add TLS support.
+ (_frvfdpic_count_relocs_fixups): Likewise. Add relaxation
+ support.
+ (_frvfdpic_relax_tls_entries): New.
+ (_frvfdpic_compute_got_alloc_data): Add TLS support.
+ (_frvfdpic_get_tlsdesc_entry): New.
+ (_frvfdpic_assign_got_entries): Add TLS support.
+ (_frvfdpic_assign_plt_entries): Likewise.
+ (_frvfdpic_reset_got_plt_entries): New.
+ (_frvfdpic_size_got_plt): Move out of...
+ (elf32_frvfdpic_size_dynamic_sections): ... here.
+ (_frvfdpic_relax_got_plt_entries): New.
+ (elf32_frvfdpic_relax_section): New.
+ (elf32_frvfdpic_finish_dynamic_sections): Add TLS sanity check.
+ (elf32_frv_check_relocs): Add TLS support.
+ (bfd_elf32_bfd_relax_section): Define for FDPIC.
+ * libbfd.h, bfd-in2.h: Rebuilt.
+
+2005-01-25 Alan Modra <amodra@bigpond.net.au>
+
+ * elf.c (_bfd_elf_get_dynamic_reloc_upper_bound): Only include
+ loadable reloc sections.
+ (_bfd_elf_canonicalize_dynamic_reloc): Likewise.
+ (_bfd_elf_get_synthetic_symtab): Return 0 if no dynamic syms.
+
+2005-01-25 Alan Modra <amodra@bigpond.net.au>
+
+ * elflink.c (elf_link_add_object_symbols): Don't create link dynamic
+ sections immediately when linking shared libs. Instead, wait until
+ we know a lib is needed.
+ (_bfd_elf_link_create_dynstrtab): Extract from..
+ (_bfd_elf_link_create_dynamic_sections_): ..here.
+ (elf_add_dt_needed_tag): Call _bfd_elf_link_create_dynstrtab and
+ _bfd_elf_link_create_dynamic_sections. Add abfd param. Allow
+ for non-existent .dynamic.
+ (elf_link_output_extsym): Don't complain about undefined symbols
+ in as-needed dynamic libs that aren't actually linked.
+
+2005-01-24 Andrew Cagney <cagney@gnu.org>
+
+ * configure: Regenerate, ../gettext.m4 was updated.
+
+2005-01-21 Ben Elliston <bje@au.ibm.com>
+
+ * aout-encap.c: Remove unused file.
+
+2005-01-19 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR 679
+ * elflink.c (_bfd_elf_dynamic_symbol_p): Only protected
+ non-function symbols are local.
+ (_bfd_elf_symbol_refs_local_p): Likewise.
+
+2005-01-18 Alan Modra <amodra@bigpond.net.au>
+
+ * bfd.c (bfd_link_just_syms): Add abfd param.
+ * bfd-in2.h: Regenerate.
+
+2005-01-17 Richard Sandiford <rsandifo@redhat.com>
+
+ * elf-eh-frame.c (skip_cfa_op, skip_non_nops): New functions.
+ (_bfd_elf_discard_section_eh_frame): Use them to interpret the CFA
+ instructions. If the amount of padding is known, reduce the size
+ of the CIE or FDE by that amount.
+
+2005-01-17 Richard Sandiford <rsandifo@redhat.com>
+
+ * elf-bfd.h (struct cie): Use bfd_vmas for code_align, ra_column and
+ augmentation_size. Use bfd_signed_vmas for data_align.
+ * elf-eh-frame.c (read_uleb128, read_sleb128): Delete in favor of...
+ (read_byte, skip_leb128, read_uleb128, read_sleb128): ...these new
+ functions. Don't read past the end of the enclosing CIE or FDE.
+ (skip_bytes): New utility function.
+ (_bfd_elf_discard_section_eh_frame): Use new functions, adding more
+ sanity checking.
+ (_bfd_elf_write_section_eh_frame): Use new functions.
+
+2005-01-17 Richard Sandiford <rsandifo@redhat.com>
+
+ * elf-eh-frame.c (_bfd_elf_discard_section_eh_frame): Use an
+ assert-style REQUIRE() macro to handle sanity checks.
+
+2005-01-17 H.J. Lu <hongjiu.lu@intel.com>
+
+ * dwarf2.c (dwarf2_debug): Move info_ptr_unit to ...
+ (comp_unit): Here.
+ (read_unsigned_leb128): Removed.
+ (read_signed_leb128): Removed.
+ (find_abstract_instance_name): Updated.
+ (parse_comp_unit): Accept info_ptr_unit.
+ (_bfd_dwarf2_find_nearest_line): Set info_ptr_unit for each
+ comp unit and pass it to parse_comp_unit.
+
+ * elf-eh-frame.c (read_unsigned_leb128): Moved to ...
+ (read_signed_leb128): Moved to ...
+ * libbfd.c: Here.
+
+ * libbfd-in.h (read_unsigned_leb128): New prototype.
+ (read_signed_leb128): Likewise.
+ * libbfd.h: Regenerated.
+
+2005-01-17 Andrew Stubbs <andrew.stubbs@st.com>
+ Nick Clifton <nickc@redhat.com>
+
+ * cpu-sh.c (bfd_to_arch_table): Change arch_sh1_up to arch_sh_up,
+ arch__sh4_nofp_up to arch_sh4_nofpu_up and arch_sh4a_nofp_up to
+ arch_sh4a_nofpu_up in order to match the external names and make the
+ testsuite's job easier.
+ * archuires.c: Rename bfd_mach_sh2a_fake? to more meaningful
+ names.
+ * bfd-in2.h: Regenerate.
+
+2005-01-15 Andrew Cagney <cagney@gnu.org>
+
+ * bfd.m4: New file.
+ * acinclude.m4: Move BFD_NEED_DECLARATION,
+ BFD_HAVE_SYS_PROCFS_TYPE and BFD_HAVE_SYS_PROCFS_TYPE_MEMBER to
+ the new file bfd.m4. Include ../bfd/bfd.m4.
+ * configure: Re-generate.
+
+2005-01-12 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-ppc.c (ppc_elf_howto_raw): Delete RELAX32* entries.
+ (ppc_elf_relax_section): Use PLT variants of RELAX32 relocs for
+ reaching PLT.
+ (ppc_elf_relocate_section): Handle R_PPC_RELAX32_PLT and
+ R_PPC_RELAX32PC_PLT.
+
+2005-01-11 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (ppc64_elf_gc_sweep_hook): Follow indirect and warning
+ symbols.
+ * elf32-arm.c (elf32_arm_gc_sweep_hook): Likewise.
+ * elf32-cris.c (cris_elf_gc_sweep_hook): Likewise.
+ * elf32-hppa.c (elf32_hppa_gc_sweep_hook): Likewise.
+ * elf32-i386.c (elf_i386_gc_sweep_hook): Likewise.
+ * elf32-m32r.c (m32r_elf_gc_sweep_hook): Likewise.
+ * elf32-m68k.c (elf_m68k_gc_sweep_hook): Likewise.
+ * elf32-ppc.c (ppc_elf_gc_sweep_hook): Likewise.
+ * elf32-s390.c (elf_s390_gc_sweep_hook): Likewise.
+ * elf32-sh.c (sh_elf_gc_sweep_hook): Likewise.
+ * elf32-sparc.c (elf32_sparc_gc_sweep_hook): Likewise.
+ * elf32-vax.c (elf_vax_gc_sweep_hook): Likewise.
+ * elf32-xtensa.c (elf_xtensa_gc_sweep_hook): Likewise.
+ * elf64-s390.c (elf_s390_gc_sweep_hook): Likewise.
+ * elf64-x86-64.c (elf64_x86_64_gc_sweep_hook): Likewise.
+
+2005-01-11 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-ppc.c (ppc_elf_create_dynamic_sections): Correct
+ .dynsbss flags.
+
+2005-01-10 Inderpreet Singh <inderpreetb@noida.hcltech.com>
+
+ * archures.c: Define bfd_mach_maxq10 and bfd_mach_maxq20.
+ * bfd-in2.h: Regenerate.
+ * coffcode.h (coff_set_arch_mach_hook, coff_set_flags): Add code
+ to support these new machine values.
+ * cpu-maxq.c (bfd_maxq10_arch): New architecture definition for
+ the maxq10.
+ (bfd_maxq_arch): Update values for the maxq20.
+
+2005-01-10 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ * elf64-sparc.c (sparc64_elf_adjust_dynamic_symbol): When linking a
+ non-shared object, do not reserve space in .plt and .rela.plt for
+ regular symbols neither defined nor referenced in shared objects.
+
+2005-01-09 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ * elf32-sparc.c (elf32_sparc_link_hash_table_create): Use bfd_zmalloc
+ to zero the structure.
+ (create_got_section): Use BFD_ASSERT instead of abort.
+ * elf64-sparc.c (struct sparc64_elf_link_hash_table): New 'sgot' and
+ 'srelgot' fields.
+ (create_got_section): New function.
+ (sparc64_elf_create_dynamic_sections): Likewise.
+ (sparc64_elf_check_relocs): Invoke create_got_section instead of
+ _bfd_elf_create_got_section. Use the sgot and srelgot shortcuts.
+ (sparc64_elf_size_dynamic_sections): Use the srelgot shortcut.
+ (sparc64_elf_relocate_section): Use the sgot and srelgot shortcuts.
+ (sparc64_elf_finish_dynamic_symbol): Likewise.
+ (sparc64_elf_finish_dynamic_sections): Use the sgot shortcut.
+ (elf_backend_create_dynamic_sections): Define to
+ sparc64_elf_create_dynamic_sections.
+
+2005-01-09 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ * elf32-sparc.c (elf32_sparc_omit_section_dynsym): New function.
+ (elf_backend_omit_section_dynsym): Define to it.
+ * elf64-sparc.c (sparc64_elf_omit_section_dynsym): New function.
+ (elf_backend_omit_section_dynsym): Define to it.
+
+2005-01-07 Jakub Jelinek <jakub@redhat.com>
+
+ * elf.c (INCLUDE_SECTION_IN_SEGMENT): Don't put empty sections into
+ PT_DYNAMIC segment, unless .dynamic.
+
+2005-01-06 Paul Brook <paul@codesourcery.com>
+
+ * config.bfd: Add entry for arm-*-vxworks and arm-*-windiss.
+ * configure.in: Add bfd_elf32_{big,little}arm_vxworks_vec.
+ * configure: Regenerate.
+ * elf32-arm.c: Add VxWorks target bfd.
+ (USE_REL): Remove.
+ (elf32_arm_link_hash_table): Add use_rel.
+ (elf32_arm_link_hash_table_create, elf32_arm_final_link_relocate,
+ elf32_arm_relocate_section): Replace USE_REL with runtime check.
+ Correct offset calculation for RELA case.
+ (elf_backend_may_use_rel_p, elf_backend_may_use_rela_p,
+ elf_backend_default_use_rela_p, elf_backend_rela_normal): Define.
+ (elf32_arm_vxworks_link_hash_table_create): New function.
+ * targets.c (bfd_elf32_bigarm_vxworks_vec): Add declaration.
+ (bfd_elf32_littlearm_vxworks_vec): Ditto.
+ (_bfd_target_vector): Add bfd_elf32_{big,little}arm_vxworks_vec.
+
+2005-01-06 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (struct ppc_link_hash_table): Add no_multi_toc and
+ multi_toc_needed.
+ (has_toc_reloc, makes_toc_func_call, call_check_in_progress): Define.
+ (ppc64_elf_check_relocs): Update references to has_gp_reloc.
+ (ppc64_elf_setup_section_lists): Add no_multi_toc parm, set htab bit.
+ (ppc64_elf_next_toc_section): Heed no_multi_toc.
+ (ppc64_elf_reinit_toc): Set multi_toc_needed.
+ (toc_adjusting_stub_needed): Rewrite.
+ (ppc64_elf_next_input_section): Use multi_toc_needed to shortcut
+ toc tests. Adjust for toc_adjusting_stub_needed changes.
+ (ppc64_elf_size_stubs): Update references to has_gp_reloc.
+ * elf64-ppc.h (ppc64_elf_setup_section_lists): Update prototype.
+ * section.c: Expand comment on backend bits.
+ * bfd-in2.h: Regenerate.
+ * libbfd.h: Regenerate.
+
+2005-01-06 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (ppc64_elf_size_stubs): When determining need for
+ toc adjusting stub, do not test source section flags.
+
+2005-01-05 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ * elf64-sparc.c (sparc64_elf_relocate_section): Ignore overflows
+ from STABS debugging sections again.
+
+2005-01-05 Fred Fish <fnf@specifixinc.com>
+
+ * dwarf2.c (struct dwarf2_debug): Add info_ptr_unit member.
+ (find_abstract_instance_name): New function.
+ (scan_unit_for_functions): Handle DW_TAG_inlined_subroutine.
+ (scan_unit_for_functions): Handle DW_AT_abstract_origin.
+ (_bfd_dwarf2_find_nearest_line): Initialize info_ptr_unit.
+
+For older changes see ChangeLog-2004
+
+Copyright (C) 2005 Free Software Foundation, Inc.
+
+Copying and distribution of this file, with or without modification,
+are permitted in any medium without royalty provided the copyright
+notice and this notice are preserved.
+
+Local Variables:
+mode: change-log
+left-margin: 8
+fill-column: 74
+version-control: never
+End:
diff --git a/bfd/ChangeLog-2006 b/bfd/ChangeLog-2006
new file mode 100644
index 0000000..dc15581
--- /dev/null
+++ b/bfd/ChangeLog-2006
@@ -0,0 +1,3607 @@
+2006-12-31 H.J. Lu <hongjiu.lu@intel.com>
+
+ * bfd.c (bfd_record_phdr): Call bfd_zalloc instead of bfd_alloc
+ to allocate elf_segment_map.
+
+2006-12-29 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elflink.c (elf_link_add_object_symbols): Remember the symbol
+ size only if it is defined.
+
+2006-12-25 Kazu Hirata <kazu@codesourcery.com>
+
+ * archures.c (bfd_mach_cpu32_fido): New.
+ (bfd_mach_mcf_isa_a_nodiv, bfd_mach_mcf_isa_a,
+ bfd_mach_mcf_isa_a_mac, bfd_mach_mcf_isa_a_emac,
+ bfd_mach_mcf_isa_aplus, bfd_mach_mcf_isa_aplus_mac,
+ bfd_mach_mcf_isa_aplus_emac, bfd_mach_mcf_isa_b_nousp,
+ bfd_mach_mcf_isa_b_nousp_mac, bfd_mach_mcf_isa_b_nousp_emac,
+ bfd_mach_mcf_isa_b, bfd_mach_mcf_isa_b_mac,
+ bfd_mach_mcf_isa_b_emac, bfd_mach_mcf_isa_b_float,
+ bfd_mach_mcf_isa_b_float_mac, bfd_mach_mcf_isa_b_float_emac):
+ Increment the defined values.
+ * bfd-in2.h: Regenerate.
+ * cpu-m68k.c (arch_info_struct): Add en entry for
+ bfd_mach_cpu32_fido.
+ * elf32-m68k.c (elf32_m68k_object_p): Handle
+ EF_M68K_CPU32_FIDO_A.
+ (elf32_m68k_merge_private_bfd_data): Use EF_M68K_CPU32_MASK.
+ (elf32_m68k_print_private_bfd_data): Handle
+ EF_M68K_CPU32_FIDO_A.
+
+2006-12-25 Mei Ligang <ligang@sunnorth.com.cn>
+
+ * elf32-score.c (score_elf_got_lo16_reloc): Change some variables
+ type from unsigned to signed.
+ (score_elf_final_link_relocate): Fix bugs of handling relocation
+ type R_SCORE_GOT15, R_SCORE_GOT_LO16, and R_SCORE_REL32.
+ (_bfd_score_elf_relocate_section): Handle R_SCORE_GOT_LO16
+ specially.
+
+2006-12-23 Jakub Jelinek <jakub@redhat.com>
+
+ * elf-bfd.h (struct elf_backend_data): Add as_needed_cleanup hook.
+ * elfxx-target.h (elf_backend_as_needed_cleanup): Define.
+ (elfNN_bed): Add as_needed_cleanup hook.
+ * elflink.c (elf_link_add_object_symbols): Call it when reverting
+ hash table changes for unneeded --as-needed input.
+ * elf64-ppc64.c (elf_backend_as_needed_cleanup): Define.
+ (ppc64_elf_as_needed_cleanup): New function.
+
+2006-12-19 Kazu Hirata <kazu@codesourcery.com>
+
+ * elf32-m68k.c (elf32_m68k_object_p,
+ elf32_m68k_print_private_bfd_data): Use EF_M68K_ARCH_MASK to
+ extract architecture mask.
+
+2006-12-19 Nathan Sidwell <nathan@codesourcery.com>
+
+ * elf.c (assign_file_positions_for_load_sections): Adjust p_vaddr
+ by p_vaddr_offset. Copy alignment & use if it is valid.
+ (rewrite_elf_program_headers): Cope with leading padding in a
+ segment that does not contain file or program headers.
+ (copy_elf_program_header): Likewise.
+
+2006-12-15 Mark Kettenis <kettenis@gnu.org>
+
+ * config.bfd: (sh*-*-openbsd*): Add target.
+ * configure.in (sh*-*-openbsd*): Set COREFILE to netbsd-core.lo.
+ * configure: Regenerate.
+
+2006-12-15 Alan Modra <amodra@bigpond.net.au>
+
+ * opncls.c (bfd_openr_iovec): Add "stat" parameter.
+ (struct opncls): Add "stat" field.
+ (opncls_bstat): Call vec->stat.
+ * bfd-in2.h: Regenerate.
+ * elf32-spu.c (spu_elf_open_builtin_lib): Adjust.
+
+2006-12-14 Alan Modra <amodra@bigpond.net.au>
+
+ * elf-bfd.h (struct bfd_elf_section_data): Clarify sec_group
+ and next_in_group usage.
+
+2006-12-14 Alan Modra <amodra@bigpond.net.au>
+
+ PR 3704
+ * bfdio.c (bfd_bread): Don't read past end of archive elements.
+
+2006-12-12 Daniel Jacobowitz <dan@codesourcery.com>
+
+ * doc/Makefile.am (bfd_TEXINFOS): Set.
+ (bfd.info bfd.dvi bfd.html): Delete rule.
+ * doc/Makefile.in: Regenerated.
+
+2006-12-11 Daniel Jacobowitz <dan@codesourcery.com>
+
+ * configure.in: Define GENINSRC_NEVER.
+ * doc/Makefile.am (bfd.info): Remove srcdir prefix.
+ (MAINTAINERCLEANFILES): Add info file.
+ (DISTCLEANFILES): Pretend to add info file.
+ * po/Make-in (.po.gmo): Put gmo files in objdir.
+ * configure, Makefile.in, doc/Makefile.in: Regenerated.
+
+2006-12-11 Eric Botcazou <ebotcazou@adacore.com>
+
+ * elflink.c (bfd_elf_gc_sections): Also search for corresponding
+ sections with .gnu.linkonce.t. prefix.
+
+2006-12-07 Kazu Hirata <kazu@codesourcery.com>
+
+ * elf32-m68k.c: Update uses of EF_M68K_*.
+
+2006-12-07 H.J. Lu <hjl@gnu.org>
+
+ PR ld/3666
+ * elflink.c (elf_link_add_object_symbols): Keep symbol
+ visibility for symbols from discarded section.
+
+2006-12-06 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-alpha.c (elf64_alpha_merge_symbol_attribute): New function.
+ (elf_backend_merge_symbol_attribute): Define.
+
+2006-12-04 Jan Beulich <jbeulich@novell.com>
+
+ * elflink.c (_bfd_elf_link_create_dynamic_sections): Don't create
+ .eh_frame_hdr section from here anymore.
+ (bfd_elf_size_dynamic_sections): Call _bfd_elf_maybe_strip_eh_frame_hdr
+ a little earlier.
+
+2006-12-01 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR binutils/3609
+ * elf.c (rewrite_elf_program_header): Preserve segment physical
+ address in the output segment if the first section in the
+ corresponding input segment is null.
+
+2006-12-01 Nick Clifton <nickc@redhat.com>
+
+ PR 3609
+ * elf.c (rewrite_elf_program_header): Do not use the first_section
+ pointer if it is null.
+
+2006-11-29 Paul Brook <paul@codesourcery.com>
+
+ * elf32-arm.c (elf32_arm_to_thumb_export_stub): Assert that output
+ section is present.
+ (allocate_dynrelocs): Only add export stub for symbols defined in
+ this object.
+
+2006-11-29 Paul Brook <paul@codesourcery.com>
+
+ * elf32-arm.c (elf32_arm_to_thumb_export_stub): Assert that output
+ section is present.
+ (allocate_dynrelocs): Only add export stub for symbols defined in
+ this object.
+
+2006-11-29 Paul Brook <paul@codesourcery.com>
+ Julian Brown <julian@codesourcery.com>
+
+ * elf32-arm.c (copy_eabi_attributes): Correct starting offset.
+ (elf32_arm_merge_eabi_attributes): Mark output as initialized.
+ Only set Tag_CPU_name and Tag_ABI_PCS_R9_use if input attribute
+ is present.
+
+2006-11-27 Bob Wilson <bob.wilson@acm.org>
+
+ * elf32-xtensa.c (elf_xtensa_special_sections): Add .xtensa.info.
+
+2006-11-24 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf.c (IS_SECTION_IN_INPUT_SEGMENT): New.
+ (INCLUDE_SECTION_IN_SEGMENT): Use IS_SECTION_IN_INPUT_SEGMENT.
+ (rewrite_elf_program_header): Don't preserve segment physical
+ address in the output segment if the first section in the
+ corresponding input segment is removed.
+
+2006-11-22 Alan Modra <amodra@bigpond.net.au>
+
+ * pef.c (bfd_pef_make_empty_symbol): Delete function. Define instead.
+ * xsym.c (bfd_sym_make_empty_symbol): Likewise.
+ * xsym.h (bfd_sym_make_empty_symbol): Delete.
+
+2006-11-21 Greg McGary <greg@mcgary.org>
+
+ * elf32-ppc.c (ppc_elf_relocate_section): Fixup D field
+ at proper offset in little-endian mode.
+ * elf64-ppc.c (ppc_elf_relocate_section): Likewise.
+
+2006-11-21 Jakub Jelinek <jakub@redhat.com>
+
+ * elf-eh-frame.c (struct cie): New type.
+ (cie_compare): Removed.
+ (cie_eq, cie_hash, cie_compute_hash): New functions.
+ (_bfd_elf_discard_section_eh_frame): Rewrite not to rely on FDEs
+ pointing only to last CIE and allow merging of any duplicate CIEs,
+ not just duplicate consecutive CIEs.
+ (_bfd_elf_discard_section_eh_frame_hdr): Delete cies hash table.
+ * elf-bfd.h (struct cie_header, struct cie): Removed.
+ (struct eh_frame_sec_info): Remove alloced field.
+ (struct eh_frame_hdr_info): Remove last_cie, last_cie_sec
+ and last_cie_inf fields. Add cies field.
+
+2006-11-20 Alan Modra <amodra@bigpond.net.au>
+
+ * bfd-in.h (struct stat): Don't typedef.
+ * bfdio.c (bfd_get_size): Return a file_ptr.
+ * cisco-core.c (cisco_core_file_validate): Use bfd_size_type for nread.
+ * mmo.c (mmo_scan): Use file_ptr for curpos.
+ * trad-core.c (trad_unix_core): Don't cast statbuf.st_size to
+ unsigned long.
+ * bfd-in2.h: Regenerate.
+
+2006-11-20 Alan Modra <amodra@bigpond.net.au>
+
+ PR 3532
+ * bfd-in.h (struct bfd_hash_table): Reorganize. Add "frozen".
+ * hash.c (bfd_hash_table_init_n): Init frozen.
+ (bfd_hash_lookup): Don't grow if frozen.
+ (bfd_hash_traverse): Freeze hash table during traversal.
+ * bfd-in2.h: Regenerate.
+
+2006-11-18 Alan Modra <amodra@bigpond.net.au>
+
+ * elflink.c (_bfd_elf_check_kept_section): Test for kept group
+ section. Save result of checks in kept_section.
+ (_bfd_elf_section_already_linked): Tidy. Correct comments.
+ Ignore all group member sections. Handle special matching of
+ single-member groups against linkonce sections via their group
+ section. When such a match is found, set kept_section to the
+ group member section rather than to the group.
+
+2006-11-14 Phil Lello <phil.lello@homecall.co.uk>
+
+ * peXXigen.c: Updates for PE/COFF V8.0, and clarification
+ (dir_names): Added CLR Runtime Header to dir_names[].
+ (_bfd_XX_print_private_bfd_data_common): Added EFI_ROM and XBOX
+ subsystem names
+ (_bfd_XXi_swap_aouthdr_in, _bfd_XXi_swap_aouthdr_out)
+ (pe_print_idata, pe_print_edata)
+ (_bfd_XX_bfd_copy_private_bfd_data_common)
+ (_bfd_XXi_final_link_postscript): Use #DEFINEs for index into
+ DataDirectory.
+
+2006-11-13 Daniel Jacobowitz <dan@codesourcery.com>
+
+ * bfd-in.h (bfd_elf32_arm_process_before_allocation): Update
+ prototype.
+ (bfd_elf32_arm_set_byteswap_code): New prototype.
+ * bfd-in2.h: Regenerate.
+ * elf32-arm.c (bfd_elf32_arm_process_before_allocation): Don't take
+ byteswap_code as an argument. Revert 2006-11-01 change.
+ (bfd_elf32_arm_set_byteswap_code): New.
+ (elf32_arm_size_dynamic_sections): Call
+ bfd_elf32_arm_process_before_allocation.
+
+2006-11-10 Thiemo Seufer <ths@mips.com>
+
+ * config.bfd (mips*el-sde-elf*, mips*-sde-elf*): Drop ECOFF support
+ for SDE configs.
+
+2006-11-10 Nick Clifton <nickc@redhat.com>
+
+ * config.bfd: Move previously obsoleted targets to the REMOVED
+ list.
+ Add maxq-*-coff to the obsolete list.
+
+2006-11-10 Pedro Alves <pedro_alves@portugalmail.pt>
+
+ * pe-arm-wince.c (LOCAL_LABEL_PREFIX): Define as ".".
+ * pei-arm-wince.c (LOCAL_LABEL_PREFIX): Likewise.
+ * coff-arm.c (LOCAL_LABEL_PREFIX): Only define if not defined before.
+
+2006-11-07 Daniel Jacobowitz <dan@codesourcery.com>
+
+ * elf32-arm.c (find_thumb_glue): Add ERROR_MESSAGE argument; set it
+ on error.
+ (find_arm_glue): Likewise.
+ (elf32_thumb_to_arm_stub, elf32_arm_create_thumb_stub)
+ (elf32_arm_to_thumb_stub, elf32_arm_final_link_relocate): Add
+ ERROR_MESSAGE argument and pass it through.
+ (elf32_arm_to_thumb_export_stub): Update.
+ (elf32_arm_relocate_section): Use ERROR_MESSAGE and reloc_dangerous.
+
+2006-11-07 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (enum _ppc64_sec_type): New.
+ (struct _ppc64_elf_section_data): Move "t_symndx" into opd union,
+ and rename fields. Add sec_type and has_14bit_branch.
+ (struct ppc_link_hash_table): Remove has_14bit_branch.
+ (get_opd_info, get_tls_mask, ppc64_elf_edit_opd): Adjust.
+ (ppc64_elf_relocate_section): Likewise.
+ (ppc64_elf_check_relocs): Likewise. Set per-section has_14bit_branch.
+ (ppc64_elf_size_stubs): Don't set default group size here.
+ (group_sections): Instead do so here, and group sections using
+ their individual requirements.
+
+2006-11-07 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (struct ppc64_elf_obj_tdata): Remove "has_dotsym"
+ and union.
+ (struct ppc_link_hash_entry): Add "next_dot_sym".
+ (struct ppc_link_hash_table): Add "dot_syms".
+ (link_hash_newfunc): Make list of syms starting with a dot.
+ (ppc_get_stub_entry, adjust_opd_syms): Adjust.
+ (ppc64_elf_add_symbol_hook): Don't set has_dotsym.
+ (struct add_symbol_adjust_data): Delete.
+ (add_symbol_adjust): Simplify params and return.
+ (ppc64_elf_check_directives): Just process the "dot_syms" lists,
+ not all syms.
+
+2006-11-02 Daniel Jacobowitz <dan@codesourcery.com>
+
+ * libbfd-in.h (_bfd_clear_contents): New prototype.
+ * reloc.c (_bfd_clear_contents): New.
+ * libbfd.h: Regenerated.
+
+ * elf32-arm.c (elf32_arm_final_link_relocate): Use
+ _bfd_clear_contents.
+ * elf32-d10v.c (elf32_d10v_relocate_section): Likewise.
+ * elf32-hppa.c (elf32_hppa_relocate_section): Likewise.
+ * elf32-i386.c (elf_i386_relocate_section): Likewise.
+ * elf32-ppc.c (ppc_elf_relocate_section): Likewise.
+ * elf32-s390.c (elf_s390_relocate_section): Likewise.
+ * elf32-sh.c (sh_elf_relocate_section): Likewise.
+ * elf32-xtensa.c (elf_xtensa_relocate_section): Likewise.
+ * elf64-ppc.c (ppc64_elf_relocate_section): Likewise.
+ * elf64-s390.c (elf_s390_relocate_section): Likewise.
+ * elf64-x86-64.c (elf64_x86_64_relocate_section): Likewise.
+ * elfxx-sparc.c (_bfd_sparc_elf_relocate_section): Likewise.
+
+ * elfxx-ia64.c (elfNN_ia64_relocate_section): Set value to
+ zero for discarded symbols.
+ * elfxx-mips.c (mips_elf_calculate_relocation): Likewise.
+
+2006-11-01 Thiemo Seufer <ths@mips.com>
+ David Ung <davidu@mips.com>
+
+ * elf-bfd.h (local_call_stubs): New member.
+ * elfxx-mips.c (FN_STUB_P, CALL_STUB_P, CALL_FP_STUB_P): New macros.
+ (mips_elf_calculate_relocation): Handle local mips16 call stubs.
+ (mips16_stub_section_p): Rename from mips_elf_stub_section_p, use
+ the new stub macros.
+ (_bfd_mips_elf_check_relocs): Handle call stubs for code which
+ mixes mips16 and mips32 functions. Use mips16_stub_section_p. Mark
+ used stubs with SEC_KEEP. Use the new stub macros.
+
+2006-11-01 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-arm.c (bfd_elf32_arm_process_before_allocation): Correct
+ check for PLT usage.
+
+2006-11-01 Daniel Jacobowitz <dan@codesourcery.com>
+
+ * elfxx-mips.c (mips_elf_merge_gots): Always use maxcnt.
+
+2006-10-31 Alan Modra <amodra@bigpond.net.au>
+
+ * elf.c (elfcore_write_note): Pad note descriptor to 4-byte
+ boundary. Tidy. Comment.
+
+2006-10-30 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/3111
+ * elf-bfd.h (elf_obj_tdata): Add symbuf.
+ (_bfd_elf_section_already_linked): Add struct bfd_link_info *.
+ (_bfd_elf_check_kept_section): Likewise.
+ (bfd_elf_match_symbols_in_sections): Likewise.
+
+ * elf.c (assign_section_numbers): Updated to add
+ struct bfd_link_info *.
+ (bfd_elf_match_symbols_in_sections): Updated. Cache symbol
+ buffer if info->reduce_memory_overheads is false.
+
+ * elflink.c (match_group_member): Updated to add
+ struct bfd_link_info *.
+ (_bfd_elf_check_kept_section): Likewise.
+ (elf_link_input_bfd): Likewise.
+ (_bfd_elf_section_already_linked): Likewise.
+ (bfd_elf_final_link): Free symbol buffer if
+ info->reduce_memory_overheads is false.
+
+ * libbfd-in.h (_bfd_nolink_section_already_linked): Add
+ struct bfd_link_info *.
+ (_bfd_generic_section_already_linked): Likewise.
+ * libbfd.h: Regenerated.
+
+ * linker.c (bfd_section_already_linked): Add
+ struct bfd_link_info *.
+ (_bfd_generic_section_already_linked): Likewise.
+ * targets.c (bfd_target): Add struct bfd_link_info * to
+ _section_already_linked.
+ * bfd-in2.h: Regenerated.
+
+2006-10-30 Alan Modra <amodra@bigpond.net.au>
+
+ * bfd.c (bfd_error_type): Add bfd_error_on_input.
+ (input_bfd, input_error): New static vars.
+ (bfd_set_error): Handle bfd_error_on_input.
+ (bfd_errmsg): Likewise.
+ (bfd_perror): Simplify.
+ * archive.c (_bfd_write_archive_contents): Report errors on input.
+ * bfd-in2.h: Regenerate.
+
+2006-10-30 Alan Modra <amodra@bigpond.net.au>
+
+ * elf.c (elfcore_write_note): Pad to 4-byte boundary.
+
+2006-10-28 Richard Sandiford <richard@codesourcery.com>
+
+ * elf32-mips.c (elf_mips_howto_table_rel): Add R_MIPS_GLOB_DAT.
+ * elfn32-mips.c (elf_mips_howto_table_rel): Likewise.
+ (elf_mips_howto_table_rela): Likewise.
+ * elf64-mips.c (mips_elf64_howto_table_rel): Likewise.
+ (mips_elf64_howto_table_rela): Likewise.
+
+2006-10-26 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf.c (_bfd_elf_init_private_section_data): Assert output
+ section ELF type instead of check if it is SHT_NULL. Copy
+ OS/PROC specific flags from input section to output section.
+
+2006-10-27 Alan Modra <amodra@bigpond.net.au>
+
+ * section.c (SEC_KEEP): Update comment.
+ * bfd-in2.h: Regenerate.
+ * elflink.c (bfd_elf_gc_sections): Ignore SEC_EXCLUDE sections.
+ * merge.c (_bfd_merge_sections): Set SEC_KEEP on excluded sections.
+ * stabs.c (_bfd_discard_section_stabs): Likewise.
+ (_bfd_link_section_stabs): Likewise. Simplify abs_section check.
+
+2006-10-26 Ben Elliston <bje@au.ibm.com>
+
+ * reloc.c (_bfd_relocate_contents): Remove explicit case 0.
+
+ * elf.c (bfd_section_from_shdr): Remove extraneous breaks.
+ * targets.c (find_target): Remove extraneous break.
+
+2006-10-26 Ben Elliston <bje@au.ibm.com>
+
+ * coff-maxq.c (coff_maxq20_reloc): Remove unused variable `howto'.
+ (struct maxq_reloc_map): Unused; remove.
+ (maxq_reloc_map): Likewise.
+ (maxq_reloc_type_lookup): Remove loop over maxq_reloc_map.
+
+2006-10-26 Ben Elliston <bje@au.ibm.com>
+
+ * elf.c (bfd_elf_set_dyn_lib_class): Change second argument type
+ from int to enum dynamic_lib_link_class lib_class.
+ * bfd-in.h (bfd_elf_set_dyn_lib_class): Likewise.
+ * bfd-in2.h: Regenerate.
+
+2006-10-25 Alan Modra <amodra@bigpond.net.au>
+ Trevor Smigiel <Trevor_Smigiel@playstation.sony.com>
+ Yukishige Shibata <shibata@rd.scei.sony.co.jp>
+ Nobuhisa Fujinami <fnami@rd.scei.sony.co.jp>
+ Takeaki Fukuoka <fukuoka@rd.scei.sony.co.jp>
+
+ * cpu-spu.c: New file.
+ * elf32-spu.c: New file.
+ * elf32-spu.h: New file.
+ * archures.c: Add SPU support.
+ * config.bfd: Likewise.
+ * configure.in: Likewise.
+ * reloc.c: Likewise.
+ * targets.c: Likewise.
+ * Makefile.am: Likewise. Run "make dep-am".
+ * libbfd.h: Regenerate.
+ * bfd-in2.h: Regenerate.
+ * Makefile.in: Regenerate.
+ * configure: Regenerate.
+ * po/SRC-POTFILES.in: Regenerate.
+
+2006-10-23 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (ppc64_elf_edit_opd): Clarify comment.
+
+2006-10-23 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-score.c: Formatting.
+ (elf_backend_omit_section_dynsym): Define.
+ (score_elf_create_dynamic_relocation): Remove code copied from mips.
+ Don't use section syms in dynamic relocs. Remove unused param.
+ (score_elf_final_link_relocate): Remove unused param.
+
+2006-10-23 Alan Modra <amodra@bigpond.net.au>
+
+ * linker.c (fix_syms): Choose best of previous and next
+ section based on section flags and vma.
+
+2006-10-21 Kaz Kojima <kkojima@rr.iij4u.or.jp>
+
+ * elf32-sh64.c (sh64_elf_merge_symbol_attribute): Do merging
+ only when the non visibility part of st_other is non-zero.
+ * elf64-sh64.c (sh64_elf64_merge_symbol_attribute): Likewise.
+
+2006-10-20 Richard Sandiford <richard@codesourcery.com>
+
+ * elfxx-mips.c (_bfd_mips_elf_modify_segment_map): Don't extend
+ PT_DYNAMIC on GNU/Linux targets.
+
+2006-10-20 Richard Sandiford <richard@codesourcery.com>
+
+ * elfxx-mips.c (_bfd_mips_elf_finish_dynamic_sections): Make the
+ size of .rel.dyn reflect the value of DT_RELSZ.
+
+2006-10-20 Richard Sandiford <richard@codesourcery.com>
+
+ * elfxx-mips.c (_bfd_mips_elf_additional_program_headers): Allocate
+ a PT_NULL header for dynamic objects.
+ (_bfd_mips_elf_modify_segment_map): Add it.
+
+2006-10-19 Mei Ligang <ligang@sunnorth.com.cn>
+
+ * elf32-score.c (score_elf_rel_dyn_section): Replace
+ bfd_make_section with bfd_make_section_with_flags.
+ (_bfd_score_elf_create_dynamic_sections): Ditto.
+ (score_elf_create_got_section): Ditto.
+ (score_elf_final_link_relocate): Delete referrence to
+ EF_SCORE_HASENTRY.
+
+2006-10-19 Richard Sandiford <richard@codesourcery.com>
+
+ * elfxx-mips.c (sort_dynamic_relocs): Sort relocations against the
+ same symbol by increasing r_offset.
+ (sort_dynamic_relocs_64): Likewise. Fix comparisons between very
+ large and very small symbol indexes.
+
+2006-10-19 Richard Sandiford <richard@codesourcery.com>
+
+ * elfxx-mips.c (_bfd_mips_elf_size_dynamic_sections): Add DT_DEBUG
+ and DT_MIPS_RLD_MAP tags for position-independent executables.
+ Do not add DT_DEBUG to shared libraries for any MIPS target.
+
+2006-10-18 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/3290
+ * elflink.c (elf_link_add_object_symbols): Hide definitions in
+ debug sections.
+
+2006-10-19 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-arm.c (bfd_elf32_arm_allocate_interworking_sect): Check,
+ don't set, glue section size.
+ (record_arm_to_thumb_glue): Set glue section size here.
+ (record_thumb_to_arm_glue): Likewise.
+ (bfd_elf32_arm_add_glue_sections_to_bfd): Formatting.
+ (bfd_elf32_arm_process_before_allocation): Ignore exluded sections.
+
+2006-10-18 Roy Marples <uberlord@gentoo.org>
+
+ * elf64-sparc.c: Add FreeBSD support.
+ (elf64_sparc_fbsd_post_process_headers): New function.
+ * targets.c (_bfd_target_vector): Add bfd_elf64_sparc_freebsd_vec.
+ * config.bfd (sparc64-*-freebsd*): Set targ_defvec to bfd_elf64_sparc_freebsd_vec.
+ * configure.in: Add entry for bfd_elf64_sparc_freebsd_vec.
+ * configure: Regenerate.
+
+2006-10-17 Mark Shinwell <shinwell@codesourcery.com>
+
+ * elf32-arm.c (elf32_arm_final_link_relocate): Add support for
+ R_ARM_MOVW_BREL_NC, R_ARM_MOVW_BREL, R_ARM_MOVT_BREL,
+ R_ARM_THM_MOVW_BREL_NC, R_ARM_THM_MOVW_BREL and
+ R_ARM_THM_MOVT_BREL relocations.
+
+2006-10-17 Mark Shinwell <shinwell@codesourcery.com>
+
+ * elf32-arm.c (elf32_arm_howto_table_1): Change offset for
+ R_THM_CALL to 25 and remove FIXME comment.
+ (using_thumb2): New function.
+ (elf32_arm_final_link_relocate): Cope with Thumb-2 BL encoding.
+
+2006-10-17 Mark Shinwell <shinwell@codesourcery.com>
+
+ * elf32-arm.c (elf32_arm_final_link_relocate): Add cases
+ for R_ARM_ABS32_NOI and R_ARM_REL32_NOI.
+ (elf32_arm_gc_sweep_hook): Likewise.
+ (elf32_arm_check_relocs): Likewise.
+ (allocate_dynrelocs): Likewise.
+
+2006-10-17 Alan Modra <amodra@bigpond.net.au>
+
+ * elf-bfd.h (struct elf_link_hash_table): Reorder. Add
+ text_index_section and data_index_section.
+ (struct elf_backend_data): Add elf_backend_init_index_section.
+ (_bfd_elf_init_1_index_section): Declare.
+ (_bfd_elf_init_2_index_sections): Declare.
+ * elfxx-target.h (elf_backend_init_index_section): Define.
+ (elfNN_bed): Init new field.
+ * elflink.c (_bfd_elf_link_omit_section_dynsym): Keep first tls
+ section and text_index_section plus data_index_section.
+ (_bfd_elf_link_renumber_dynsyms): Clear dynindx on omitted sections.
+ (_bfd_elf_init_1_index_section): New function.
+ (_bfd_elf_init_2_index_sections): New function.
+ (bfd_elf_size_dynsym_hash_dynstr): Call elf_backend_init_index_section.
+ (elf_link_input_bfd): When emitting relocs, use text_index_section
+ and data_index_section for removed sections.
+ * elf-m10300.c (elf_backend_omit_section_dynsym): Define.
+ * elf32-i386.c: Likewise.
+ * elf32-m32r.c: Likewise.
+ * elf32-sh.c: Likewise.
+ * elf32-xstormy16.c: Likewise.
+ * elf32-xtensa.c: Likewise.
+ * elf64-alpha.c: Likewise.
+ * elf64-hppa.c: Likewise.
+ * elf64-mmix.c: Likewise.
+ * elf64-sh64.c: Likewise.
+ * elfxx-ia64.c: Likewise.
+ * elf32-arm.c (elf32_arm_final_link_relocate): Use text_index_section
+ and data_index_section sym for relocs against sections with no dynamic
+ section sym.
+ (elf_backend_init_index_section): Define.
+ * elf32-cris.c: Similarly.
+ * elf32-hppa.c: Similarly.
+ * elf32-i370.c: Similarly.
+ * elf32-m68k.c: Similarly.
+ * elf32-mips.c: Similarly.
+ * elf32-ppc.c: Similarly.
+ * elf32-s390.c: Similarly.
+ * elf32-sparc.c: Similarly.
+ * elf32-vax.c: Similarly.
+ * elf64-mips.c: Similarly.
+ * elf64-ppc.c: Similarly.
+ * elf64-s390.c: Similarly.
+ * elf64-sparc.c: Similarly.
+ * elf64-x86-64.c: Similarly.
+ * elfn32-mips.c: Similarly.
+ * elfxx-mips.c: Similarly.
+ * elfxx-sparc.c: Similarly.
+ * linker.c (fix_syms): Base symbols in removed sections on
+ previous section in preference to using absolute section.
+
+2006-10-16 Andreas Schwab <schwab@suse.de>
+
+ * elfxx-ia64.c (addend_compare): Properly compute return value.
+
+2006-10-15 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/3314
+ * elf.c (assign_file_positions_for_non_load_sections): Don't
+ page align empty SHF_ALLOC sections.
+
+2006-10-13 Jakub Jelinek <jakub@redhat.com>
+
+ * elfxx-sparc.c (_bfd_sparc_elf_finish_dynamic_sections): Set
+ .plt sh_entsize to 0 if plt header size isn't multiple of
+ plt entry size or for 32-bit which adds a nop insn at the
+ end of the .plt section.
+
+2006-10-12 Bob Wilson <bob.wilson@acm.org>
+
+ * elf32-xtensa.c (elf_xtensa_action_discarded): New.
+ (elf_backend_action_discarded): Define.
+
+2006-10-11 Bob Wilson <bob.wilson@acm.org>
+
+ * elf32-xtensa.c (elf_xtensa_relocate_section): Return after
+ unresolvable relocation error.
+ (elf_xtensa_finish_dynamic_symbol): Set value of undefined, weak
+ symbols to zero.
+
+2006-10-10 Bob Wilson <bob.wilson@acm.org>
+
+ * elf32-xtensa.c (elf_xtensa_size_dynamic_sections): Add DT_DEBUG
+ for PIE executables.
+
+2006-10-03 Jakub Jelinek <jakub@redhat.com>
+
+ * elf-bfd.h (struct eh_cie_fde): Add set_loc pointer.
+ * elf-eh-frame.c (skip_cfa_op): Fix handling of DW_CFA_advance_loc.
+ Handle DW_CFA_{remember,restore}_state, DW_CFA_GNU_window_save,
+ DW_CFA_val_{offset{,_sf},expression}.
+ (skip_non_nops): Record number of DW_CFA_set_loc ops.
+ (_bfd_elf_discard_section_eh_frame): Require skip_non_nops recognizes
+ all ops. If there are any DW_CFA_set_loc ops and they are pcrel
+ or going to be pcrel, compute set_loc array.
+ (_bfd_elf_eh_frame_section_offset): If make_relative, kill relocations
+ against DW_CFA_set_loc operands.
+ (_bfd_elf_write_section_eh_frame): Handle DW_CFA_set_loc adjusting.
+
+2006-10-02 Daniel Jacobowitz <dan@codesourcery.com>
+
+ * elflink.c (_bfd_elf_merge_symbol): Discard references to TLS
+ symbols from the --just-syms file.
+
+2006-10-01 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (ppc64_elf_build_stubs): Test glink size for
+ existence of PLT.
+
+2006-09-29 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/3283
+ * elf64-x86-64.c (elf64_x86_64_relocate_section): Don't ignore
+ relocation overflow on branches to undefweaks.
+
+2006-09-29 Alan Modra <amodra@bigpond.net.au>
+
+ * po/BLD-POTFILES.in: Regenerate.
+ * po/SRC-POTFILES.in: Regenerate.
+
+2006-09-29 Danny Smith <dannysmith@users.sourceforge.net>
+
+ PR 3276
+ * pei-i386.c (COFF_SECTION_ALIGNMENT_ENTRIES): Enable 16 byte
+ alignment for .data$, .rdata$ and .text$ sections so that sse
+ and sse2 code will work for linkonce sections too.
+ * pe-i386.c (COFF_SECTION_ALIGNMENT_ENTRIES): Likewise.
+
+2006-09-28 Alan Modra <amodra@bigpond.net.au>
+
+ * elflink.c (_bfd_elf_gc_mark_hook): New function.
+ * elf-bfd.h (_bfd_elf_gc_mark_hook): Declare.
+ * elfxx-target.h (elf_backend_gc_mark_hook): Default to above.
+ * elf-m10300.c (mn10300_elf_gc_mark_hook): Use _bfd_elf_gc_mark_hook.
+ * elf32-arm.c (elf32_arm_gc_mark_hook): Likewise.
+ * elf32-cris.c (cris_elf_gc_mark_hook): Likewise.
+ * elf32-hppa.c (elf32_hppa_gc_mark_hook): Likewise.
+ * elf32-i386.c (elf_i386_gc_mark_hook): Likewise.
+ * elf32-m32r.c (m32r_elf_gc_mark_hook): Likewise.
+ * elf32-m68k.c (elf_m68k_gc_mark_hook): Likewise.
+ * elf32-mcore.c (mcore_elf_gc_mark_hook): Likewise.
+ * elf32-ppc.c (ppc_elf_gc_mark_hook): Likewise.
+ * elf32-s390.c (elf_s390_gc_mark_hook): Likewise.
+ * elf32-score.c (_bfd_score_elf_gc_mark_hook): Likewise.
+ * elf32-sh.c (sh_elf_gc_mark_hook): Likewise.
+ * elf32-vax.c (elf_vax_gc_mark_hook): Likewise.
+ * elf32-xtensa.c (elf_xtensa_gc_mark_hook): Likewise.
+ * elf64-mmix.c (mmix_elf_gc_mark_hook): Likewise.
+ * elf64-s390.c (elf_s390_gc_mark_hook): Likewise.
+ * elf64-x86-64.c (elf64_x86_64_gc_mark_hook): Likewise.
+ * elfxx-mips.c (_bfd_mips_elf_gc_mark_hook): Likewise.
+ * elfxx-sparc.c (_bfd_sparc_elf_gc_mark_hook): Likewise.
+ * elf32-bfin.c (bfin_gc_mark_hook): Likewise.
+ (bfinfdpic_gc_sweep_hook): Delete.
+ (elf_backend_gc_sweep_hook): Don't define for elf32-bfinfdpic.
+ * elf32-d10v.c (elf32_d10v_gc_mark_hook): Use _bfd_elf_gc_mark_hook.
+ (elf32_d10v_gc_sweep_hook): Delete.
+ (elf_backend_gc_sweep_hook): Don't define.
+ * elf32-fr30.c (fr30_elf_gc_mark_hook): Use _bfd_elf_gc_mark_hook.
+ (fr30_elf_gc_sweep_hook): Delete.
+ (elf_backend_gc_sweep_hook): Don't define.
+ * elf32-frv.c (elf32_frv_gc_mark_hook): Use _bfd_elf_gc_mark_hook.
+ (elf32_frv_gc_sweep_hook): Delete.
+ (elf_backend_gc_sweep_hook): Don't define.
+ * elf32-iq2000.c (iq2000_elf_gc_mark_hook): Use _bfd_elf_gc_mark_hook.
+ (iq2000_elf_gc_sweep_hook): Delete.
+ (elf_backend_gc_sweep_hook): Don't define.
+ * elf32-openrisc.c (openrisc_elf_gc_mark_hook): Use
+ _bfd_elf_gc_mark_hook.
+ (openrisc_elf_gc_sweep_hook): Delete.
+ (elf_backend_gc_sweep_hook): Don't define.
+ * elf32-v850.c (v850_elf_gc_mark_hook): Use _bfd_elf_gc_mark_hook.
+ (v850_elf_gc_sweep_hook): Delete.
+ (elf_backend_gc_sweep_hook): Don't define.
+ * elf32-xstormy16.c (xstormy16_elf_gc_mark_hook): Use
+ _bfd_elf_gc_mark_hook.
+ (xstormy16_elf_gc_sweep_hook): Delete.
+ (elf_backend_gc_sweep_hook): Don't define.
+ * elf64-sh64.c (sh_elf64_gc_mark_hook): Use _bfd_elf_gc_mark_hook.
+ (sh_elf64_gc_sweep_hook): Delete.
+ (elf_backend_gc_sweep_hook): Don't define.
+ * elf32-avr.c (elf32_avr_gc_mark_hook): Delete.
+ (elf32_avr_gc_sweep_hook): Delete.
+ (elf_backend_gc_mark_hook, elf_backend_gc_mark_hook): Don't define.
+ * elf32-cr16c.c (elf32_cr16c_gc_mark_hook): Delete.
+ (elf32_cr16c_gc_sweep_hook): Delete.
+ (elf_backend_gc_mark_hook, elf_backend_gc_mark_hook): Don't define.
+ * elf32-crx.c (elf32_crx_gc_mark_hook): Delete.
+ (elf32_crx_gc_sweep_hook): Delete.
+ (elf_backend_gc_mark_hook, elf_backend_gc_mark_hook): Don't define.
+ * elf32-h8300.c (elf32_h8_gc_mark_hook): Delete.
+ (elf32_h8_gc_sweep_hook): Delete.
+ (elf_backend_gc_mark_hook, elf_backend_gc_mark_hook): Don't define.
+ * elf32-ip2k.c (ip2k_elf_gc_mark_hook): Delete.
+ (ip2k_elf_gc_sweep_hook): Delete.
+ (elf_backend_gc_mark_hook, elf_backend_gc_mark_hook): Don't define.
+ * elf32-m32c.c (m32c_elf_gc_mark_hook, m32c_elf_gc_sweep_hook): Delete.
+ (elf_backend_gc_mark_hook, elf_backend_gc_mark_hook): Don't define.
+ * elf32-m68hc11.c (elf_backend_gc_mark_hook): Don't define.
+ (elf_backend_gc_sweep_hook): Don't define.
+ * elf32-m68hc12.c (elf_backend_gc_mark_hook): Don't define.
+ (elf_backend_gc_sweep_hook): Don't define.
+ * elf32-m68hc1x.c (elf32_m68hc11_gc_mark_hook): Delete.
+ (elf32_m68hc11_gc_sweep_hook): Delete.
+ * elf32-m68hc1x.h (elf32_m68hc11_gc_mark_hook): Delete.
+ (elf32_m68hc11_gc_sweep_hook): Delete.
+ * elf32-msp430.c (elf32_msp430_gc_mark_hook): Delete.
+ (elf32_msp430_gc_sweep_hook): Delete.
+ (elf_backend_gc_mark_hook, elf_backend_gc_mark_hook): Don't define.
+ * elf32-mt.c (mt_elf_gc_mark_hook, mt_elf_gc_sweep_hook): Delete.
+ (elf_backend_gc_mark_hook, elf_backend_gc_mark_hook): Don't define.
+
+2006-09-25 Pedro Alves <pedro_alves@portugalmail.pt>
+
+ * bfd-in.h (CONST_STRNCPY) : Delete.
+ (LITSTRCPY) : New.
+ (LITMEMCPY) : New.
+ * bfd-in2.h : Regenerate.
+ * elflink.c (bfd_elf_gc_sections) : Use LITMEMCPY. Don't manually
+ calculate string lengths.
+ * nlmcode.h (nlm_swap_auxiliary_headers_in) : Use LITMEMCPY.
+
+2006-09-26 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/3223
+ PR ld/3267
+ * elf.c (assign_file_positions_for_non_load_sections): Don't
+ warn zero size allocated sections.
+
+2006-09-27 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-score.c (_bfd_score_elf_relocate_section): Move assignment
+ to "name" so that compiler realizes it is never uninitialized.
+ Use bfd_elf_sym_name.
+
+2006-09-26 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR binutils/3262
+ * elf.c (rewrite_elf_program_header): Use bfd_zalloc instead of
+ bfd_alloc to allocate segment map.
+ (copy_elf_program_header): Likewise.
+
+2006-09-26 Mark Shinwell <shinwell@codesourcery.com>
+ Joseph Myers <joseph@codesourcery.com>
+ Ian Lance Taylor <ian@wasabisystems.com>
+ Ben Elliston <bje@wasabisystems.com>
+
+ * archures.c: Add definition for bfd_mach_arm_iWMMXt2.
+ * cpu-arm.c (processors): Add bfd_mach_arm_iWMMXt2.
+ (arch_info_struct, bfd_arm_update_notes): Likewise.
+ (architectures): Likewise.
+ (bfd_arm_merge_machines): Check for iWMMXt2.
+ * bfd-in2.h: Rebuild.
+
+2006-09-24 H.J. Lu <hongjiu.lu@intel.com>
+
+ * configure: Regenerated.
+
+2006-09-22 Alan Modra <amodra@bigpond.net.au>
+
+ * elfcode.h (elf_swap_symbol_in): Return bfd_boolean. Don't abort
+ on error.
+ * elf-bfd.h (elf_size_info <swap_symbol_in>): Adjust decl.
+ (bfd_elf32_swap_symbol_in, bfd_elf64_swap_symbol_in): Likewise.
+ * elf.c (bfd_elf_get_elf_syms): Test return of swap_symbol_in,
+ and report error.
+ * elf32-arm.c (elf32_arm_swap_symbol_in): Return bfd_boolean.
+
+2006-09-20 Martin Schwidefsky <schwidefsky@de.ibm.com>
+
+ * elf32-s390.c (elf_s390_relocate_section): Remove check for code
+ section in LD to LE linker relaxation for R_390_TLS_LDO32.
+ * elf64-s390.c (elf_s390_relocate_section): Likewise for
+ R_390_TLS_LDO64.
+
+2006-09-20 Kai Tietz <Kai.Tietz@onevision.com>
+
+ * configure.in: Added new target-vectors x86_64coff_vec,
+ x86_64pe_vec, and x86_64pei_vec.
+ * configure: Regenerate.
+ * config.bfd: Adjusted x86_64 target architecture detection.
+ * bfd.c: Add for new target "coff-x86-64"
+ (bfd_get_sign_extend): Add target vector idents for pe-x86-64. and pei-x86-64.
+ * coff-x86_64.c: Add new file for x86_64 (AMD64) coff support.
+ * libpei.h: Adjustments for COFF_WITH_pex64.
+ * coffcode.h: Add for new target machine, architecture, signature, and internal
+ signature handler.
+ * Makefile.am: Add new files to target-all and define make-rule for pex64igen.c
+ * Makefile.in: Regenerate.
+ * pe-x86_64.c: Add for new target "pe-x86-64".
+ * pei-x86_64.c: Add for new target "pei-x86-64".
+ * peicode.h: Adjusts for new targets.
+ (coff_swap_filehdr_out): Set for this target to
+ _bfd_pex64_only_swap_filehdr_out.
+ (SIZEOF_IDATA4): Define it as 8 byte size for this target.
+ (SIZEOF_IDATA5): Define it as 8 byte size for this target.
+ (jump_table jtab): Add for AMD64MAGIC.
+ (pe_ILF_build_a_bfd): Adjusts for new size of SIZEOF_IDATA4 and SIZE_IDATA5.
+ (pe_ILF_object_p): Add coff image-file signature to internal
+ signature translation.
+ * peXXigen.c: Adjust proper include of target coff-header and
+ introduced target specific code
+ (COFF_WITH_pex64): New macro for this target.
+ (pe_print_idata): New dumping method for import section of PE+ files.
+ * targets.c: Add new target vectors declarations for x86_64 coff targets.
+ * coffcode.h: Support code to support the x86_64 PE magic number.
+ * coff-x86_64.c: New file.
+
+2006-09-17 Hans-Peter Nilsson <hp@axis.com>
+
+ * elf.c (special_sections_s): Revert last STRING_COMMA_LEN change
+ for .stabstr entry, explain why.
+
+2006-09-17 Anton Blanchard <anton@samba.org>
+ Alan Modra <amodra@bigpond.net.au>
+
+ * dwarf2.c (concat_filename): Apply DW_AT_comp_dir if dir table
+ entry isn't absolute.
+
+2006-09-17 Mei Ligang <ligang@sunnorth.com.cn>
+
+ * cpu-score.c: New file.
+ * elf32-score.c: New file.
+ * config.bfd: Add Score target.
+ * Makefile.am: Add Score files.
+ * Makefile.in: Regenerate.
+ * archures.c: Add Score architecture.
+ * reloc.c: Add Score relocs.
+ * targets.c: Add Score target vectors.
+ * bfd-in2.h: Regenerate.
+ * libbfd.h: Regenerate.
+ * configure.in: Add Score target.
+ * configure: Regenerate.
+
+2006-09-16 Nick Clifton <nickc@redhat.com>
+ Pedro Alves <pedro_alves@portugalmail.pt>
+
+ * bfd-in.h (STRING_COMMA_LEN): New macro. Takes one constant
+ string as its argument and emits the string followed by a comma
+ and then the length of the string.
+ (CONST_STRNEQ): New macro. Checks to see if a variable string
+ has a constant string as its initial characters.
+ (CONST_STRNCPY): New macro. Copies a constant string to the start
+ of a variable string.
+ * bfd-in2.h: Regenerate.
+ * archive.c: Make use of the new macros.
+ * archive64.c: Likewise.
+ * bfd.c: Likewise.
+ * coff-ppc.c: Likewise.
+ * coff-stgo32.c: Likewise.
+ * coffcode.h: Likewise.
+ * cofflink.c: Likewise.
+ * cpu-i960.c: Likewise.
+ * dwarf2.c: Likewise.
+ * ecoff.c: Likewise.
+ * elf-m10300.c: Likewise.
+ * elf.c: Likewise.
+ * elf32-arm.c: Likewise.
+ * elf32-bfin.c: Likewise.
+ * elf32-cris.c: Likewise.
+ * elf32-hppa.c: Likewise.
+ * elf32-i370.c: Likewise.
+ * elf32-i386.c: Likewise.
+ * elf32-iq2000.c: Likewise.
+ * elf32-m32r.c: Likewise.
+ * elf32-m68hc11.c: Likewise.
+ * elf32-m68hc12.c: Likewise.
+ * elf32-m68k.c: Likewise.
+ * elf32-mcore.c: Likewise.
+ * elf32-ppc.c: Likewise.
+ * elf32-s390.c: Likewise.
+ * elf32-sh-symbian.c: Likewise.
+ * elf32-sh.c: Likewise.
+ * elf32-sh64.c: Likewise.
+ * elf32-v850.c: Likewise.
+ * elf32-vax.c: Likewise.
+ * elf32-xtensa.c: Likewise.
+ * elf64-alpha.c: Likewise.
+ * elf64-hppa.c: Likewise.
+ * elf64-mmix.c: Likewise.
+ * elf64-ppc.c: Likewise.
+ * elf64-s390.c: Likewise.
+ * elf64-sh64.c: Likewise.
+ * elf64-x86-64.c: Likewise.
+ * elflink.c: Likewise.
+ * elfxx-ia64.c: Likewise.
+ * elfxx-mips.c: Likewise.
+ * elfxx-sparc.c: Likewise.
+ * hpux-core.c: Likewise.
+ * i386linux.c: Likewise.
+ * ieee.c: Likewise.
+ * libpei.h: Likewise.
+ * linker.c: Likewise.
+ * m68klinux.c: Likewise.
+ * mmo.c: Likewise.
+ * nlmcode.h: Likewise.
+ * osf-core.c: Likewise.
+ * pef.c: Likewise.
+ * som.c: Likewise.
+ * sparclinux.c: Likewise.
+ * vms-hdr.c: Likewise.
+
+2006-09-14 Alan Modra <amodra@bigpond.net.au>
+
+ PR 3181
+ * elf.c (_bfd_elf_copy_private_header_data): Fix group members
+ that have had their SHT_GROUP section removed.
+
+2006-09-12 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/3197
+ * elflink.c (elf_link_output_extsym): Compute bucket only if
+ needed.
+
+2006-09-10 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR binutils/3186
+ * elf.c (_bfd_elf_make_section_from_shdr): Correct length of
+ "gnu.linkonce.wi.".
+
+2006-09-08 Vladimir Prus <vladimir@codesourcery.com>
+
+ * elf32-arm.c (elf32_arm_swap_symbol_out): Remove
+ unconditional setting of low bit for Thumb symbol
+ mistakenly left behind after check for external
+ symbols was added. Fix comment typo.
+
+2006-09-07 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf-bfd.h (elf_link_hash_entry): Add a dynamic field.
+ (bfd_elf_link_mark_dynamic_symbol): New.
+ (SYMBOLIC_BIND): New.
+
+ * elf32-i386.c (elf_i386_check_relocs): Replace info->symbolic
+ with SYMBOLIC_BIND (info, h).
+ (elf_i386_relocate_section): Likewise.
+ * elf64-x86-64.c (elf64_x86_64_check_relocs): Likewise.
+ (elf64_x86_64_relocate_section): Likewise.
+ * elfxx-ia64.c (elfNN_ia64_check_relocs): Likewise.
+
+ * elflink.c (bfd_elf_link_mark_dynamic_symbol): New.
+ (bfd_elf_record_link_assignment): Call
+ bfd_elf_link_mark_dynamic_symbol on new entry.
+ (_bfd_elf_merge_symbol): Likewise.
+ (_bfd_elf_export_symbol): Return if the symbol isn't exported.
+ (_bfd_elf_fix_symbol_flags): Replace info->symbolic with
+ SYMBOLIC_BIND (info, h).
+ (_bfd_elf_dynamic_symbol_p): Likewise.
+ (_bfd_elf_symbol_refs_local_p): Likewise.
+ (bfd_elf_size_dynamic_sections): Updated.
+
+2006-09-05 Bibo Mao <bibo.mao@intel.com>
+
+ PR binutils/3171
+ * coffcode.h (coff_write_object_contents): Set the optional
+ header magic number to PE32PMAGIC instead of ZMAGIC for ia64.
+
+2006-09-04 Mark Shinwell <shinwell@codesourcery.com>
+
+ * elf32-arm.c (elf32_arm_howto_table_1): Adjust entries for
+ R_ARM_THM_ALU_PREL_11_0 and R_ARM_THM_PC12 relocations.
+ (elf32_arm_final_link_relocate): Handle R_ARM_THM_ALU_PREL_11_0
+ and R_ARM_THM_PC12 relocations.
+
+2006-08-24 Bob Wilson <bob.wilson@acm.org>
+
+ * elf32-xtensa.c (xtensa_get_property_section_name): Delete.
+ (xtensa_get_property_section): New.
+ (xtensa_read_table_entries): Use xtensa_get_property_section.
+ (relax_property_section, xtensa_get_property_predef_flags): Handle
+ group name suffixes in property section names.
+ (match_section_group): New.
+
+2006-08-23 Frediano Ziglio <Frediano.Ziglio@vodafone.com>
+
+ * archive.c (hpux_uid_gid_encode): Fix thinko decrementing "cnt"
+ variable.
+
+2006-08-22 Daniel Jacobowitz <dan@codesourcery.com>
+
+ * elf32-arm.c (elf32_arm_copy_indirect_symbol): Only copy
+ plt_thumb_refcount from indirect symbols.
+
+2006-08-22 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-ppc.c (ppc_elf_relocate_section): Correct GOT and PLT HA
+ reloc handling.
+ * elf64-ppc.c (ppc64_elf_relocate_section): Likewise.
+
+2006-08-21 Mark Shinwell <shinwell@codesourcery.com>
+
+ * elf32-arm.c (elf32_arm_link_hash_table): Correct typo in
+ comment for target1_is_rel.
+
+2006-08-21 Pedro Alves <pedro_alves@portugalmail.pt>
+
+ * Makefile.am: Add rules to build pe-arm-wince.lo
+ and pei-arm-wince.lo objects.
+ * Makefile.in: Regenerate.
+ * pe-arm-wince.c: New file.
+ * pei-arm-wince.c: New file.
+ * pei-arm.c: Remove ARM_WINCE block.
+ * pe-arm.c: Remove ARM_WINCE block. Rename
+ bfd_arm_pe_allocate_interworking_sections,
+ bfd_arm_pe_get_bfd_for_interworking, and
+ bfd_arm_pe_process_before_allocation to
+ bfd_armpe_allocate_interworking_sections,
+ bfd_armpe_get_bfd_for_interworking, and
+ bfd_armpe_process_before_allocation. Move them before
+ including bfd.h.
+ * bfd.c: ARM wince bfd format names were renamed. Adjust.
+ * coff-arm.c [ARM_WINCE]: Adjust so Windows CE doesn't end up
+ with unexpected/conflicting relocs.
+ * targets.c: The arm-wince-pe target got its own new vector.
+ Adjust.
+ * config.bfd: Likewise.
+ * configure.in: Likewise.
+ * configure: Regenerate.
+
+2006-08-18 Paul Brook <paul@codesourcery.com>
+
+ * elf32-arm.c (elf32_arm_link_hash_entry): Add export_glue.
+ (elf32_arm_link_hash_newfunc): Initialize export_glue.
+ (record_arm_to_thumb_glue): Return stub symbol.
+ (elf32_arm_create_thumb_stub): New function.
+ (elf32_arm_to_thumb_stub): Use it.
+ (elf32_arm_to_thumb_export_stub): New function.
+ (elf32_arm_begin_write_processing): New function.
+ (allocate_dynrelocs): Allocate Arm stubs.
+ (elf_backend_begin_write_processing): Define.
+ (elf32_arm_symbian_begin_write_processing): Remove ATTRIBUTE_UNUSED.
+ Call elf32_arm_begin_write_processing.
+
+2006-08-17 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (create_linkage_sections): Align .glink to 8 bytes.
+ (ppc64_elf_build_stubs): Use new lazy linking stub.
+
+2006-08-17 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (ppc64_elf_size_stubs): Ignore non-code sections.
+
+2006-08-16 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/3015
+ * elf.c (get_program_header_size): Add a PT_GNU_RELRO segment
+ only if there is a PT_DYNAMIC segment.
+ (_bfd_elf_map_sections_to_segments): Likewise.
+ (assign_file_positions_for_load_sections): Set PT_GNU_RELRO
+ segment alignment to 1.
+
+2006-08-15 Thiemo Seufer <ths@mips.com>
+ Nigel Stephens <nigel@mips.com>
+
+ * elf32-mips.c, elf64-mips.c, elfn32-mips.c
+ (elf_backend_merge_symbol_attribute): Define.
+ * elflink.c (elf_link_add_object_symbols): Merge only the ELF
+ visibility flags.
+ * elfxx-mips.c (_bfd_mips_elf_merge_symbol_attribute): New function.
+
+2006-08-15 Thiemo Seufer <ths@mips.com>
+ Nigel Stephens <nigel@mips.com>
+ David Ung <davidu@mips.com>
+
+ * config.bfd: Add configurations for mips*el-sde-elf* and
+ mips*-sde-elf*.
+
+2006-08-14 DJ Delorie <dj@redhat.com>
+
+ * elf-m10300.c (elf32_mn10300_link_hash_entry): Add value.
+ (elf32_mn10300_count_hash_table_entries): New.
+ (elf32_mn10300_list_hash_table_entries): New.
+ (sort_by_value): New.
+ (mn10300_elf_relax_section): Don't skip data sections; restrict
+ code-specific tests to code-specific areas so that potential
+ indirect calls can be detected. Check for multiple local symbols
+ at the same address and merge their flags.
+ (elf32_mn10300_link_hash_newfunc): Initialize value.
+
+2006-08-14 Thiemo Seufer <ths@mips.com>
+
+ * elfxx-mips.c (_bfd_mips_elf_symbol_processing,
+ _bfd_mips_elf_add_symbol_hook): Don't try to place small common TLS
+ symbols in .scommon.
+
+2006-08-11 Thiemo Seufer <ths@mips.com>
+
+ * elfxx-mips.c (_bfd_mips_elf_finish_dynamic_sections): Set
+ sh_entsize only when sgot was already initialized.
+
+2006-08-08 DJ Delorie <dj@redhat.com>
+
+ * elf32-sh.c (sh_elf_relax_section): Allow for branches across
+ non-moving .align directives. Preserve any DIR32 offset when
+ converting bsr's to jsr's.
+
+2006-08-08 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (ppc64_elf_build_stubs): Clear relbrlt reloc_count
+ after stubs have been built.
+
+2006-08-07 Nick Clifton <nickc@redhat.com>
+
+ * elf32-sh.c (vxworks_object_p): Only check for vxworks target
+ vectors if they are going to be created.
+
+2006-08-07 Nick Clifton <nickc@redhat.com>
+
+ * configure.in (bfd_elf32_shnbsd_vec): Fix typo.
+ * configure: Regenerate.
+
+2006-08-07 Nick Clifton <nickc@redhat.com>
+
+ * coff-arm.c (coff_arm_rtype_to_howto): Only check for ARM_SECREL
+ relocation types if the target is ARM_WINCE.
+
+2006-08-05 Pedro Alves <pedro_alves@portugalmail.pt>
+
+ * bfd.c (bfd_get_sign_extend_vma): Add cases for pe-arm-little
+ and pei-arm-little.
+ * coff-arm.c (coff_arm_rtype_to_howto) [COFF_WITH_PE]: Handle
+ ARM_SECREL.
+ (coff_arm_reloc_type_lookup): Map BFD_RELOC_32_SECREL to
+ ARM_SECREL.
+ * pe-arm.c [COFF_SECTION_ALIGNMENT_ENTRIES]: Define.
+ * pei-arm.c [TARGET_UNDERSCORE]: Define for ARM_WINCE like in
+ pe-arm.c.
+ [COFF_SECTION_ALIGNMENT_ENTRIES]: Define.
+
+2006-08-04 Marcelo Tosatti <marcelo@kvack.org>
+
+ * elflink.c (elf_gc_sweep): If info.print_gc_sections is true,
+ list removed sections to stderr.
+
+2006-08-04 Richard Sandiford <richard@codesourcery.com>
+ Kazu Hirata <kazu@codesourcery.com>
+ Phil Edwards <phil@codesourcery.com>
+ Nathan Sidwell <nathan@codesourcery.com>
+
+ * config.bfd (sh-*-vxworks): Use bfd_elf32_shvxworks_vec and
+ bfd_elf32_shlvxworks_vec.
+ * configure.in (bfd_elf32_sh64_vec): Add elf-vxworks.lo.
+ (bfd_elf32_sh64l_vec, bfd_elf32_sh64lin_vec): Likewise.
+ (bfd_elf32_sh64blin_vec, bfd_elf32_sh64lnbsd_vec): Likewise.
+ (bfd_elf32_sh64nbsd_vec, bfd_elf32_sh_vec): Likewise.
+ (bfd_elf32_shblin_vec, bfd_elf32_shl_vec): Likewise.
+ (bfd_elf32_shl_symbian_vec, bfd_elf32_shlin_vec): Likewise.
+ (bfd_elf32_shlnbsd_vec, bfd_elf32_shnbsd_vec): Likewise.
+ (bfd_elf32_shlvxworks_vec, bfd_elf32_shvxworks_vec): New stanzas.
+ * configure: Regenerate.
+ * Makefile.am: Regenerate dependencies.
+ * Makefile.in: Regenerate.
+ * elf-vxworks.c (elf_vxworks_gott_symbol_p): New function.
+ (elf_vxworks_add_symbol_hook): Use it.
+ (elf_vxworks_link_output_symbol_hook): Likewise. Use the hash
+ table entry to check for weak undefined symbols and to obtain
+ the original bfd.
+ (elf_vxworks_emit_relocs): Use target_index instead of this_idx.
+ * elf32-sh-relocs.h: New file, split from elf32-sh.c.
+ (R_SH_DIR32): Use SH_PARTIAL32 for the partial_inplace field,
+ SH_SRC_MASK32 for the src_mask field, and SH_ELF_RELOC for the
+ special_function field.
+ (R_SH_REL32): Use SH_PARTIAL32 and SH_SRC_MASK32 here too.
+ (R_SH_REL32, R_SH_TLS_GD_32, R_SH_TLS_LD_32): Likewise.
+ (R_SH_TLS_LDO_32, R_SH_TLS_IE_32, R_SH_TLS_LE_32): Likewise.
+ (R_SH_TLS_DTPMOD32, R_SH_TLS_DTPOFF32, R_SH_TLS_TPOFF32): Likewise.
+ (R_SH_GOT32, R_SH_PLT32, R_SH_COPY, R_SH_GLOB_DAT): Likewise.
+ (R_SH_JMP_SLOT, R_SH_RELATIVE, R_SH_GOTOFF, R_SH_GOTPC): Likewise.
+ (SH_PARTIAL32, SH_SRC_MASK32, SH_ELF_RELOC): Undefine at end of file.
+ * elf32-sh.c: Include elf32-vxworks.h.
+ (MINUS_ONE): Define.
+ (sh_elf_howto_table): Include elf32-sh-relocs.h with SH_PARTIAL32
+ set to TRUE, SH_SRC_MASK32 set to 0xffffffff, and SH_ELF_RELOC set
+ to sh_elf_reloc.
+ (sh_vxworks_howto_table): New variable. Include elf32-sh-relocs.h
+ with SH_PARTIAL32 set to FALSE, SH_SRC_MASK32 set to 0, and
+ SH_ELF_RELOC set to bfd_elf_generic_reloc.
+ (vxworks_object_p, get_howto_table): New functions.
+ (sh_elf_reloc_type_lookup): Fix typo. Use get_howto_table.
+ (sh_elf_info_to_howto): Use get_howto_table.
+ (sh_elf_relax_section): Honor the partial_inplace field of the
+ R_SH_DIR32 howto.
+ (sh_elf_relax_delete_bytes): Likewise.
+ (elf_sh_plt_info): New structure.
+ (PLT_ENTRY_SIZE): Replace both definitions with...
+ (ELF_PLT_ENTRY_SIZE): ...this new macro, with separate definitions for
+ INCLUDE_SHMEDIA and !INCLUDE_SHMEDIA.
+ (elf_sh_plt0_entry_be): Update sizes of both definitions accordingly.
+ (elf_sh_plt0_entry_le): Likewise.
+ (elf_sh_plt_entry_be, elf_sh_plt_entry_le): Likewise.
+ (elf_sh_pic_plt_entry_be, elf_sh_pic_plt_entry_le): Likewise.
+ (elf_sh_plts): New structure, with separate definitions for
+ INCLUDE_SHMEDIA and !INCLUDE_SHMEDIA.
+ (elf_sh_plt0_entry): Delete both definitions.
+ (elf_sh_plt_entry, elf_sh_pic_plt_entry): Likewise.
+ (elf_sh_sizeof_plt, elf_sh_plt_plt0_offset): Likewise.
+ (elf_sh_plt_temp_offset, elf_sh_plt_symbol_offset): Likewise.
+ (elf_sh_plt_reloc_offset): Likewise.
+ (movi_shori_putval): Delete in favor of...
+ (install_plt_field): ...this new function, with separate definitions
+ for INCLUDE_SHMEDIA and !INCLUDE_SHMEDIA.
+ (get_plt_info): New function, with separate definitions
+ for INCLUDE_SHMEDIA and !INCLUDE_SHMEDIA.
+ (elf_sh_plt0_linker_offset, elf_sh_plt0_gotid_offset): Delete.
+ (VXWORKS_PLT_HEADER_SIZE, VXWORKS_PLT_ENTRY_SIZE): New macros.
+ (vxworks_sh_plt0_entry_be, vxworks_sh_plt0_entry_le): New constants.
+ (vxworks_sh_plt_entry_be, vxworks_sh_plt_entry_le): Likewise.
+ (vxworks_sh_pic_plt_entry_be, vxworks_sh_pic_plt_entry_le): Likewise.
+ (get_plt_index, get_plt_offset): New functions.
+ (elf_sh_link_hash_table): Add srelplt2, plt_info and vxworks_p fields.
+ (sh_elf_link_hash_table_create): Initialize them.
+ (sh_elf_create_dynamic_sections): Call
+ elf_vxworks_create_dynamic_sections for VxWorks.
+ (allocate_dynrelocs): Use htab->plt_info to get the size of PLT
+ entries. Allocate relocation entries in .rela.plt.unloaded if
+ generating a VxWorks executable.
+ (sh_elf_always_size_sections): New function.
+ (sh_elf_size_dynamic_sections): Extend .rela.plt handling to
+ .rela.plt.unloaded.
+ (sh_elf_relocate_section): Use get_howto_table. Honor
+ partial_inplace when calculating the addend for dynamic
+ relocations. Use get_plt_index.
+ (sh_elf_finish_dynamic_symbol): Use get_plt_index, install_plt_field
+ and htab->plt_info. Fill in the bra .plt offset for VxWorks
+ executables. Populate .rela.plt.unloaded. Do not make
+ _GLOBAL_OFFSET_TABLE_ absolute on VxWorks.
+ (sh_elf_finish_dynamic_sections): Use install_plt_field and
+ htab->plt_info. Handle cases where there is no special PLT header.
+ Populate the first relocation in .rela.plt.unloaded and fix up
+ the remaining entries.
+ (sh_elf_plt_sym_val): Use get_plt_info.
+ (elf_backend_always_size_sections): Define.
+ (TARGET_BIG_SYM, TARGET_BIG_NAME): Override for VxWorks.
+ (TARGET_LITTLE_SYM, TARGET_BIG_SYM): Likewise.
+ (elf32_bed, elf_backend_want_plt_sym): Likewise.
+ (elf_symbol_leading_char, elf_backend_want_got_underscore): Likewise.
+ (elf_backend_grok_prstatus, elf_backend_grok_psinfo): Likewise.
+ (elf_backend_add_symbol_hook): Likewise.
+ (elf_backend_link_output_symbol_hook): Likewise.
+ (elf_backend_emit_relocs): Likewise.
+ (elf_backend_final_write_processing): Likewise.
+ (ELF_MAXPAGESIZE, ELF_COMMONPAGESIZE): Likewise.
+ * targets.c (bfd_elf32_shlvxworks_vec): Declare.
+ (bfd_elf32_shvxworks_vec): Likewise.
+ (_bfd_target_vector): Include bfd_elf32_shlvxworks_vec and
+ bfd_elf32_shvxworks_vec.
+
+2006-08-02 Mark Kettenis <kettenis@gnu.org>
+
+ * configure.in (arm-*-openbsd*): Set COREFILE to netbsd-core.lo.
+ * configure: Regenerate.
+
+2006-08-02 Petr Salinger <Petr.Salinger@seznam.cz>
+
+ PR binutils/2983
+ * elf64-x86-64.c: Add FreeBSD support.
+ (elf64_x86_64_fbsd_post_process_headers): New function.
+ * targets.c (_bfd_target_vector): Add bfd_elf64_x86_64_freebsd_vec.
+ * config.bfd (x64_64-*-freebsd*): Add bfd_elf64_x86_64_freebsd_vec
+ to the targ_selvecs.
+ * configure.in: Add entry for bfd_elf64_x86_64_freebsd_vec.
+ * configure: Regenerate.
+
+2006-07-26 Andreas Schwab <schwab@suse.de>
+
+ * elfxx-ia64.c (elfNN_ia64_choose_gp): Use rawsize if set.
+
+2006-07-26 Alan Modra <amodra@bigpond.net.au>
+
+ * elf.c (elf_modify_segment_map): Delete empty PT_LOAD segments.
+ * elf32-xtensa.c (elf_xtensa_modify_segment_map): Delete.
+ (define elf_backend_modify_segment_map): Don't define.
+
+2006-07-25 Thiemo Seufer <ths@networkno.de>
+
+ * elfxx-mips.c (_bfd_mips_elf_merge_private_bfd_data): Allow
+ linking of objects for compatible machine types.
+
+2006-07-25 Thiemo Seufer <ths@networkno.de>
+
+ * elfxx-mips.c (mips_elf_next_relocation): Tighten check to test
+ also for same symbol.
+
+2006-07-25 Thiemo Seufer <ths@mips.com>
+
+ * elfxx-mips.c (mips_elf_calculate_relocation): Remove magic constant.
+
+2006-07-24 Michael Wetherell <mike.wetherell@ntlworld.com>
+
+ * elf.c (bfd_section_from_shdr): Reject unrecognised OS-specific
+ sections only if the SHF_OS_NONCONFORMING flag is present.
+
+2006-07-24 Nick Clifton <nickc@redhat.com>
+
+ PR ld/2729
+ * peXXigen.c (_bfd_XXi_final_link_postscript): Check for the
+ existance of output sections before putting their entries into the
+ DataDictionary.
+
+2006-07-20 Thiemo Seufer <ths@mips.com>
+
+ * elf32-mips.c (mips16_jump_reloc): Remove function.
+ (elf_mips16_howto_table_rel): Use _bfd_mips_elf_generic_reloc
+ instead of mips16_jump_reloc.
+ * elf64_mips.c, wlfn32-mips.c (mips16_jump_reloc): Remove function.
+ (elf_mips16_howto_table_rel, elf_mips16_howto_table_rela): Use
+ _bfd_mips_elf_generic_reloc instead of mips16_jump_reloc.
+
+2006-07-19 Alan Modra <amodra@bigpond.net.au>
+
+ * bfd-in.h (enum notice_asneeded_action): Define.
+ * bfd-in2.h: Regenerate.
+ * elflink.c (elf_link_add_object_symbols): Call linker "notice"
+ function with NULL name for as-needed handling.
+
+2006-07-18 Paul Brook <paul@codesourcery.com>
+
+ * bfd-in2.h: Regenerate.
+ * libbfd.h: Regenerate.
+ * reloc.c: Add BFD_RELOC_ARM_T32_ADD_IMM.
+
+2006-07-18 Nick Clifton <nickc@redhat.com>
+
+ * elfxx-mips.c (_bfd_mips_elf_common_definition): New function.
+ Consider SHN_MIPS_ACOMMON and SHN_MIPS_SCOMMON as being common
+ sections.
+ * elfxx-mips.h (_bfd_mips_elf_common_definition): Prototype.
+
+2006-07-14 Jakub Jelinek <jakub@redhat.com>
+
+ * elflink.c (bfd_elf_size_dynsym_hash_dynstr): Fix cinfo.shift2 value.
+
+2006-07-14 Mark Kettenis <kettenis@gnu.org>
+
+ * elflink.c (bfd_elf_size_dynsym_hash_dynstr): Move declarations
+ to the start of a block.
+
+2006-07-13 Nick Clifton <nickc@redhat.com>
+
+ * coff-sh.c (_bfd_sh_align_load_span): Catch sh_insn_info()
+ returning a NULL value.
+
+2006-07-12 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/2884
+ * elflink.c (_bfd_elf_merge_symbol): Copy the symbol info from
+ the old versioned dynamic definition to the new one with
+ non-default visibility. Hide the symbol if it is hidden or
+ internal.
+
+2006-07-12 Matthew R. Dempsky <mrd@alkemio.org>
+
+ * cpu-m68k.c (bfd_m68k_compatible): Handle CPU32.
+
+2006-07-10 Jakub Jelinek <jakub@redhat.com>
+
+ * elf.c (_bfd_elf_print_private_bfd_data): Handle DT_GNU_HASH.
+ (bfd_section_from_shdr, elf_fake_sections, assign_section_numbers):
+ Handle SHT_GNU_HASH.
+ (special_sections_g): Include .gnu.hash section.
+ (bfd_elf_gnu_hash): New function.
+ * elf-bfd.h (bfd_elf_gnu_hash, _bfd_elf_hash_symbol): New prototypes.
+ (struct elf_backend_data): Add elf_hash_symbol method.
+ * elflink.c (_bfd_elf_link_create_dynamic_sections): Create .hash
+ only if info->emit_hash, create .gnu.hash section if
+ info->emit_gnu_hash.
+ (struct collect_gnu_hash_codes): New type.
+ (elf_collect_gnu_hash_codes, elf_renumber_gnu_hash_syms,
+ _bfd_elf_hash_symbol): New functions.
+ (compute_bucket_count): Don't compute HASHCODES array, instead add
+ that and NSYMS as arguments. Use bed->s->sizeof_hash_entry
+ instead of bed->s->arch_size / 8. Fix .hash size estimation.
+ When not optimizing, use the number of hashed symbols rather than
+ dynsymcount.
+ (bfd_elf_size_dynamic_sections): Only add DT_HASH if info->emit_hash,
+ and ADD DT_GNU_HASH if info->emit_gnu_hash.
+ (bfd_elf_size_dynsym_hash_dynstr): Size .hash only if info->emit_hash,
+ adjust compute_bucket_count caller. Create and populate .gnu.hash
+ section if info->emit_gnu_hash.
+ (elf_link_output_extsym): Only populate .hash section if
+ finfo->hash_sec != NULL.
+ (bfd_elf_final_link): Adjust assertion. Handle DT_GNU_HASH.
+ * elfxx-target.h (elf_backend_hash_symbol): Define if not yet defined.
+ (elfNN_bed): Add elf_backend_hash_symbol.
+ * elf64-x86-64.c (elf64_x86_64_hash_symbol): New function.
+ (elf_backend_hash_symbol): Define.
+ * elf32-i386.c (elf_i386_hash_symbol): New function.
+ (elf_backend_hash_symbol): Define.
+
+2006-07-05 Nick Clifton <nickc@redhat.com>
+
+ PR ld/2659
+ * cofflink.c (_bfd_coff_link_input_bfd): Fix selection of aux
+ entry when multiple definitions of a symbol are encountered.
+
+2006-06-30 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf32-i386.c (elf_i386_relocate_section): Use xchg %ax,%ax
+ instead of 2 nops.
+ * elf64-x86-64.c (elf64_x86_64_relocate_section): Likewise.
+ (elf64_x86_64_plt0_entry): Use nopl 0(%rax) instead of 4 nops.
+
+2006-06-29 Jakub Jelinek <jakub@redhat.com>
+
+ PR ld/2513
+ * elf32-i386.c (GOT_TLS_MASK, GOT_TLS_IE_IE, GOT_TLS_IE_GD,
+ GOT_TLS_IE_MASK, elf_i386_check_relocs, allocate_dynrelocs): Revert
+ 2006-04-08 changes.
+ (elf_i386_relocate_section): Likewise. For GD->IE transition
+ change subl into addl whenever tls_type is GOT_TLS_IE_POS.
+
+2006-06-23 Alan Modra <amodra@bigpond.net.au>
+
+ PR ld/2754
+ * elf.c (bfd_elf_mkobject): Don't alloc if already done. Set
+ program_header_size to -1.
+ (_bfd_elf_map_sections_to_segments): Adjust program_header_size check.
+ (assign_file_positions_for_load_sections ): Likewise.
+ (_bfd_elf_sizeof_headers): Use saved program_header_size if
+ available.
+ * elf32-arm.c (elf32_arm_mkobject): Call bfd_elf_mkobject, don't
+ alloc if already done.
+ * elf32-i386.c (elf_i386_mkobject): Likewise.
+ * elf32-ppc.c (ppc_elf_mkobject): Likewise.
+ * elf32-s390.c (elf_s390_mkobject): Likewise.
+ * elf32-sh.c (sh_elf_mkobject): Likewise.
+ * elf64-alpha.c (elf64_alpha_mkobject): Likewise.
+ * elf64-ppc.c (ppc64_elf_mkobject): Likewise.
+ * elf64-s390.c (elf_s390_mkobject): Likewise.
+ * elf64-x86-64.c (elf64_x86_64_mkobject): Likewise.
+ * elfxx-sparc.c (_bfd_sparc_elf_mkobject): Likewise.
+
+2006-06-20 Jakub Jelinek <jakub@redhat.com>
+
+ * elflink.c (elf_link_add_object_symbols): Don't create .tcommon
+ section for relocatable link.
+
+2006-06-21 Alan Modra <amodra@bigpond.net.au>
+
+ * elf-bfd.h (struct elf_backend_data): Add
+ elf_backend_modify_program_headers.
+ * elfxx-target.h (elf_backend_modify_program_headers): Define.
+ (elfNN_bed): Init new field.
+ * elf.c (elf_modify_segment_map): Remove comment.
+ (assign_file_positions_for_load_sections): Only call
+ elf_modify_segment_map for objcopy/strip.
+ (assign_file_positions_except_relocs): Call
+ elf_backend_modify_program_headers.
+ * elf32-frv.c (elf32_frvfdpic_always_size_sections): Don't make
+ .stack section.
+ (elf32_frvfdpic_modify_segment_map): Delete.
+ (elf32_frvfdpic_modify_program_headers): New.
+ (elf_backend_modify_segment_map): Don't define.
+ (elf_backend_modify_program_headers): Define.
+ * elf32-bfin.c (elf32_bfinfdpic_always_size_sections): Don't make
+ .stack section.
+ (elf32_bfinfdpic_modify_segment_map): Delete.
+ (elf32_bfinfdpic_modify_program_headers): New.
+ (elf_backend_modify_segment_map): Don't define.
+ (elf_backend_modify_program_headers): Define.
+ * elfxx-ia64.c (elfNN_ia64_modify_program_headers): New function.
+ Split out from..
+ (elfNN_ia64_modify_segment_map): ..here.
+ (elf_backend_modify_program_headers): Define.
+
+2006-06-20 Jakub Jelinek <jakub@redhat.com>
+
+ * bfd.c (bfd_record_phdr): Clear p_align and p_align_valid fields.
+ * elf.c (_bfd_elf_link_hash_table_init): Clear hplt field.
+
+2006-06-20 Alan Modra <amodra@bigpond.net.au>
+
+ * elf-bfd.h: Formatting.
+ (_bfd_elf_map_sections_to_segments): Declare.
+ * elf-eh-frame.c (_bfd_elf_discard_section_eh_frame_hdr): Don't
+ clear program_header_size.
+ * elf.c (get_program_header_size): Move. Don't use or set saved
+ program_header_size here.
+ (elf_modify_segment_map): New function. Split out from..
+ (assign_file_positions_for_load_sections): ..here. Assert
+ header size is correct. Remove dead code.
+ (_bfd_elf_map_sections_to_segments): Rename from
+ map_sections_to_segments. Make global. Use get_program_header_size
+ when we need estimate of header size. Call elf_modify_segment_map.
+ Set program_header_size.
+ (print_segment_map): Delete.
+ (_bfd_elf_sizeof_headers): If segment_map available, get the
+ actual size.
+ * elf32-arm.c (elf32_arm_symbian_modify_segment_map): Make safe
+ for calling more than once.
+ * elf32-bfin.c (elf32_bfinfdpic_modify_segment_map): Likewise.
+ * elf32-frv.c (elf32_frvfdpic_modify_segment_map): Likewise.
+ * elfxx-mips.c (_bfd_mips_elf_modify_segment_map): Likewise.
+ * elf32-i370.c (elf_backend_add_symbol_hook): Delete.
+ (elf_backend_additional_program_headers): Delete.
+ (elf_backend_modify_segment_map): Delete.
+ * elf64-hppa.c (elf64_hppa_modify_segment_map): Convert to ISO C.
+ * elfxx-ia64.c (elfNN_ia64_modify_segment_map): Likewise.
+ * doc/bfdint.texi: Delete SIZEOF_HEADERS difficulties.
+
+2006-06-19 Vladimir Prus <vladimir@codesourcery.com>
+
+ * elf32-arm.c (elf32_arm_swap_symbol_out): Don't set low
+ bit for undefined symbols.
+
+2006-06-19 Alan Modra <amodra@bigpond.net.au>
+
+ * elf-bfd.h (struct elf_backend_data): Add bfd_link_info pointer
+ parameter.
+ (_bfd_elf_sizeof_headers): Replace bfd_boolean param with
+ bfd_link_info pointer.
+ * targets.c (struct bfd_target <_bfd_sizeof_headers>): Likewise.
+ * bfd.c (bfd_sizeof_headers): Tweak param name.
+ * aout-adobe.c (aout_adobe_sizeof_headers): Adjust.
+ * aoutx.h (NAME (aout, sizeof_headers)): Adjust.
+ * binary.c (binary_sizeof_headers): Adjust.
+ * bout.c (b_out_sizeof_headers): Adjust.
+ * coff-rs6000.c (_bfd_xcoff_sizeof_headers): Adjust.
+ * coff64-rs6000.c (xcoff64_sizeof_headers): Adjust.
+ * coffgen.c (coff_sizeof_headers): Adjust.
+ * ecoff.c (_bfd_ecoff_sizeof_headers): Adjust.
+ (ecoff_compute_section_file_positions): Adjust.
+ (_bfd_ecoff_write_object_contents): Adjust.
+ * elf.c (get_program_header_size, _bfd_elf_sizeof_headers): Adjust.
+ * elf32-arm.c (elf32_arm_additional_program_headers): Adjust.
+ * elf32-i370.c (elf_backend_additional_program_headers): Adjust.
+ * elf32-ppc.c (ppc_elf_additional_program_headers): Adjust.
+ * elf64-hppa.c (elf64_hppa_additional_program_headers): Adjust.
+ * elf64-x86-64.c (elf64_x86_64_additional_program_headers): Adjust.
+ * elfxx-ia64.c (elfNN_ia64_additional_program_headers): Adjust.
+ * elfxx-mips.c (_bfd_mips_elf_additional_program_headers): Adjust.
+ * elfxx-mips.h (_bfd_mips_elf_additional_program_headers): Adjust.
+ * i386msdos.c: Convert to ISO C.
+ (msdos_sizeof_headers): Adjust.
+ * i386os9k.c: Convert to ISO C.
+ (os9k_sizeof_headers): Adjust.
+ * ieee.c (ieee_sizeof_headers): Adjust.
+ * ihex.c (ihex_sizeof_headers): Adjust.
+ * libaout.h (NAME (aout, sizeof_headers)): Adjust.
+ * libbfd-in.h (_bfd_nolink_sizeof_headers): Adjust.
+ * libcoff-in.h (coff_sizeof_headers): Adjust.
+ * libecoff.h (_bfd_ecoff_sizeof_headers): Adjust.
+ * mach-o.c (bfd_mach_o_sizeof_headers): Adjust.
+ * mmo.c (mmo_sizeof_headers): Adjust.
+ * oasys.c (oasys_sizeof_headers): Adjust.
+ * pdp11.c (NAME (aout, sizeof_headers)): Adjust.
+ * pef.c (bfd_pef_sizeof_headers): Adjust.
+ * ppcboot.c (ppcboot_sizeof_headers): Adjust.
+ * som.c (som_sizeof_headers): Adjust.
+ * srec.c (srec_sizeof_headers): Adjust.
+ * tekhex.c (tekhex_sizeof_headers): Adjust.
+ * versados.c (versados_sizeof_headers): Adjust.
+ * vms.c (vms_sizeof_headers): Adjust.
+ * xcoff-target.h (_bfd_xcoff_sizeof_headers): Adjust.
+ * xsym.c (bfd_sym_sizeof_headers): Adjust.
+ * xsym.h (bfd_sym_sizeof_headers): Adjust.
+ * bfd-in2.h: Regenerate.
+ * libbfd.h: Regenerate.
+ * libcoff.h: Regenerate.
+
+2006-06-15 Mark Shinwell <shinwell@codesourcery.com>
+
+ * bfd-in2.h: Regenerate.
+ * elf32-arm.c (R_ARM_ALU_PC_G0_NC, R_ARM_ALU_PC_G0,
+ R_ARM_ALU_PC_G1_NC, R_ARM_ALU_PC_G1, R_ARM_ALU_PC_G2,
+ R_ARM_LDR_PC_G1, R_ARM_LDR_PC_G2, R_ARM_LDRS_PC_G0,
+ R_ARM_LDRS_PC_G1, R_ARM_LDRS_PC_G2, R_ARM_LDC_PC_G0,
+ R_ARM_LDC_PC_G1, R_ARM_LDC_PC_G2, R_ARM_ALU_SB_G0_NC,
+ R_ARM_ALU_SB_G0, R_ARM_ALU_SB_G1_NC, R_ARM_ALU_SB_G1,
+ R_ARM_ALU_SB_G2, R_ARM_LDR_SB_G0, R_ARM_LDR_SB_G1,
+ R_ARM_LDR_SB_G2, R_ARM_LDRS_SB_G0, R_ARM_LDRS_SB_G1,
+ R_ARM_LDRS_SB_G2, R_ARM_LDC_SB_G0, R_ARM_LDC_SB_G1,
+ R_ARM_LDC_SB_G2): New relocation types.
+ (R_ARM_PC13): Rename to AAELF name R_ARM_LDR_PC_G0 and
+ adjust HOWTO entry to be consistent with R_ARM_LDR_PC_G1
+ and friends.
+ (elf32_arm_howto_table_3): Delete; contents merged into
+ elf32_arm_howto_table_2.
+ (elf32_arm_howto_from_type): Adjust correspondingly.
+ (elf32_arm_reloc_map): Extend with the above relocations.
+ (calculate_group_reloc_mask): New function.
+ (identify_add_or_sub): New function.
+ (elf32_arm_final_link_relocate): Support for the above
+ relocations.
+ * reloc.c: Add enumeration entries for BFD_RELOC_ARM_...
+ codes to correspond to the above relocations.
+
+2006-06-14 Richard Sandiford <richard@codesourcery.com>
+
+ * elf32-m68k.c (elf_m68k_plt_info): New structure.
+ (elf_m68k_plt0_entry): Add R_68K_PC32-style in-place addends.
+ (elf_m68k_plt_entry): Likewise.
+ (elf_m68k_plt_info): New table.
+ (CFV4E_PLT_ENTRY_SIZE): Rename to...
+ (ISAB_PLT_ENTRY_SIZE): ...this.
+ (CFV4E_FLAG): Delete.
+ (elf_cfv4e_plt0_entry): Rename to...
+ (elf_isab_plt0_entry): ...this. Adjust comments. Use (-6,%pc,%d0)
+ for the second instruction too.
+ (elf_cfv4e_plt_entry): Rename to...
+ (elf_isab_plt_entry): ...this. Adjust comments and use (-6,%pc,%d0).
+ (elf_isab_plt_info): New table.
+ (CPU32_FLAG): Delete.
+ (PLT_CPU32_ENTRY_SIZE): Rename to...
+ (CPU32_PLT_ENTRY_SIZE): ...this.
+ (elf_cpu32_plt0_entry): Update bounds accordingly. Add R_68K_PC32-
+ style in-place addends.
+ (elf_cpu32_plt_entry): Likewise.
+ (elf_cpu32_plt_info): New table.
+ (elf_m68k_link_hash_table): Add a plt_info field.
+ (elf_m68k_link_hash_table_create): Initialize it.
+ (elf_m68k_get_plt_info): New function.
+ (elf_m68k_always_size_sections): Likewise.
+ (elf_m68k_adjust_dynamic_symbol): Use the plt_info hash table field.
+ (elf_m68k_install_pc32): New function.
+ (elf_m68k_finish_dynamic_symbol): Factor code using plt_info and
+ elf_m68k_install_pc32.
+ (elf_m68k_finish_dynamic_sections): Likewise.
+ (elf_m68k_plt_sym_val): Use elf_m68k_get_plt_info.
+ (elf_backend_always_size_sections): Define.
+
+2006-06-14 Alan Modra <amodra@bigpond.net.au>
+
+ * elflink.c (elf_link_add_object_symbols): Save and restore
+ struct bfd_hash_table table, size and count fields for
+ as-needed libs.
+
+2006-06-12 Thiemo Seufer <ths@mips.com>
+
+ * elf32-mips.c: Expand comment about ABI-mandated pagesize values.
+ (ELF_MAXPAGESIZE, ELF_COMMONPAGESIZE): define in a more obvious way.
+ * elf64-mips.c, elfn32-mips.c (ELF_MAXPAGESIZE): Fix value for IRIX6.
+ Delete old comments.
+ (ELF_COMMONPAGESIZE): Define in a more obvious way.
+
+2006-06-12 Nick Clifton <nickc@redhat.com>
+
+ PR binutils/2735
+ * elflink.c (elf_link_add_object_symbols): Fix the warning message
+ about mismatched alignments to allow for the case where the common
+ alignment has been deduced from the section alignment.
+ * bfd.c (_bfd_default_error_handler): Update comment to explain
+ why bfd and asection varargs are out of order. Explicitly catch
+ and abort on NULL bfd and asection arguments.
+
+2006-06-11 Richard Sandiford <richard@codesourcery.com>
+ Thiemo Seufer <ths@mips.com>
+
+ * elfxx-mips.c (mips_elf_link_hash_table): Add function_stub_size.
+ (STUB_ORI): New macro.
+ (STUB_LI16U): Fix formatting.
+ (MIPS_FUNCTION_STUB_SIZE): Delete.
+ (MIPS_FUNCTION_STUB_MAX_SIZE): Likewise.
+ (MIPS_FUNCTION_STUB_NORMAL_SIZE): New macro.
+ (MIPS_FUNCTION_STUB_BIG_SIZE): Likewise.
+ (_bfd_mips_elf_adjust_dynamic_symbol): Use htab->function_stub_size
+ instead of MIPS_FUNCTION_STUB_SIZE.
+ (count_section_dynsyms): New function, split out from
+ _bfd_mips_elf_final_link.
+ (_bfd_mips_elf_always_size_sections): Get a worst-case estimate
+ of the number of dynamic symbols needed and use it to set up
+ function_stub_size. Use function_stub_size rather than
+ MIPS_FUNCTION_STUB_SIZE to determine the size of the stub section.
+ Use 16-byte stubs for 0x10000 dynamic symbols.
+ (_bfd_mips_elf_size_dynamic_sections): Use htab->function_stub_size
+ instead of MIPS_FUNCTION_STUB_SIZE. Fix formatting.
+ (_bfd_mips_elf_finish_dynamic_symbol): Likewise. Change the
+ size of the stub buffer from MIPS_FUNCTION_STUB_MAX_SIZE to
+ MIPS_FUNCTION_STUB_BIG_SIZE. Tweak the check for unhandled dynindxes.
+ Use MIPS_FUNCTION_STUB_BIG_SIZE rather than a hard-coded 20.
+ Use STUB_ORI rather than STUB_LI16U for big stubs.
+ (_bfd_mips_elf_link_hash_table_create): Initialize function_stub_size.
+ (_bfd_mips_elf_final_link): Use count_section_dynsyms.
+
+2006-06-09 David Ung <davidu@mips.com>
+
+ * bfd/elfxx-mips.c (mips_elf_calculate_relocation): Fix mode for stub
+ calling relocations.
+
+2006-06-08 David Daney <ddaney@avtrex.com>
+
+ * elfxx-mips.c (STUB_LI16): Removed.
+ (STUB_LUI): New macro.
+ (STUB_LI16U): Ditto.
+ (STUB_LI16S): Ditto.
+ (MIPS_FUNCTION_STUB_SIZE): Rewrote to take info parameter.
+ (_bfd_mips_elf_adjust_dynamic_symbol): Pass info parameter to
+ MIPS_FUNCTION_STUB_SIZE.
+ (_bfd_mips_elf_always_size_sections): Ditto.
+ (_bfd_mips_elf_size_dynamic_sections): Ditto.
+ (_bfd_mips_elf_finish_dynamic_sections): Ditto.
+ (_bfd_mips_elf_finish_dynamic_symbol): Rewrote stub generation
+ to allow larger symbol table indexes.
+
+2006-06-07 Joseph S. Myers <joseph@codesourcery.com>
+
+ * po/Make-in (pdf, ps): New dummy targets.
+
+2006-06-06 Alan Modra <amodra@bigpond.net.au>
+
+ * hash.c (bfd_hash_lookup): Correct stray line.
+
+ * elf.c (_bfd_elf_init_private_section_data): Comment typo.
+ (elfcore_grok_nto_status): Use long instead of pid_t.
+ (elfcore_grok_nto_regs, elfcore_grok_nto_note): Likewise.
+
+2006-06-05 Daniel Jacobowitz <dan@codesourcery.com>
+
+ * po/Make-in (top_builddir): Define.
+
+2006-06-05 Alan Modra <amodra@bigpond.net.au>
+
+ * Makefile.am: Run "make dep-am".
+ * Makefile.in: Regenerate.
+ * config.in: Regenerate.
+
+2006-06-02 Alan Modra <amodra@bigpond.net.au>
+ H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/2723
+ * elflink.c (bfd_elf_final_link): Don't output section symbols
+ for special ELF sections.
+
+2006-06-01 Alan Modra <amodra@bigpond.net.au>
+
+ * stabs.c (_bfd_link_section_stabs): Use bfd_make_section*_with_flags
+ instead of bfd_make_section*.
+ * aix386-core.c: Likewise.
+ * aix5ppc-core.c: Likewise.
+ * aout-adobe.c: Likewise.
+ * aoutf1.h: Likewise.
+ * binary.c: Likewise.
+ * cisco-core.c: Likewise.
+ * coff-arm.c: Likewise.
+ * coff-h8300.c: Likewise.
+ * elf.c: Likewise.
+ * elf32-bfin.c: Likewise.
+ * elf32-m32c.c: Likewise.
+ * hppabsd-core.c: Likewise.
+ * hpux-core.c: Likewise.
+ * i386linux.c: Likewise.
+ * ieee.c: Likewise.
+ * ihex.c: Likewise.
+ * irix-core.c: Likewise.
+ * lynx-core.c: Likewise.
+ * m68klinux.c: Likewise.
+ * mach-o.c: Likewise.
+ * netbsd-core.c: Likewise.
+ * nlmcode.h: Likewise.
+ * opncls.c: Likewise.
+ * osf-core.c: Likewise.
+ * peXXigen.c: Likewise.
+ * ppcboot.c: Likewise.
+ * ptrace-core.c: Likewise.
+ * rs6000-core.c: Likewise.
+ * sco5-core.c: Likewise.
+ * sparclinux.c: Likewise.
+ * srec.c: Likewise.
+ * sunos.c: Likewise.
+ * trad-core.c: Likewise.
+ * xcofflink.c: Likewise.
+ * xsym.c: Likewise.
+
+2006-05-31 Daniel Jacobowitz <dan@codesourcery.com>
+
+ * Makefile.am (INCLUDES): Use @INCINTL@.
+ * acinclude.m4: Include new gettext macros.
+ * configure.in: Use ZW_GNU_GETTEXT_SISTER_DIR and AM_PO_SUBDIRS.
+ Manually substitute POFILES and GMOFILES.
+ * Makefile.in, aclocal.m4, configure, doc/Makefile.in: Regenerated.
+
+2006-05-30 H.J. Lu <hongjiu.lu@intel.com>
+
+ * bfd.c (bfd_emul_get_maxpagesize): New.
+ (bfd_elf_set_pagesize): Likewise.
+ (bfd_emul_set_maxpagesize): Likewise.
+ (bfd_emul_get_commonpagesize): Likewise.
+ (bfd_emul_set_commonpagesize): Likewise.
+ * bfd-in2.h: Regenerated.
+
+ * elf-bfd.h (elf_backend_data): Add commonpagesize.
+ (xvec_get_elf_backend_data): New.
+ (get_elf_backend_data): Use xvec_get_elf_backend_data.
+
+ * elf32-arm.c (elf32_arm_vxworks_bed): Remove const.
+ * elfxx-target.h (elfNN_bed): Likewise.
+
+ * elf32-arm.c (ELF_COMMONPAGESIZE): Defined.
+ * elf32-mips.c (ELF_COMMONPAGESIZE): Likewise.
+ * elf32-ppc.c (ELF_COMMONPAGESIZE): Likewise.
+ * elf32-sh.c (ELF_COMMONPAGESIZE): Likewise.
+ * elf32-sh64.c (ELF_COMMONPAGESIZE): Likewise.
+ * elf32-sparc.c (ELF_COMMONPAGESIZE): Likewise.
+ * elf64-alpha.c (ELF_COMMONPAGESIZE): Likewise.
+ * elf64-ppc.c (ELF_COMMONPAGESIZE): Likewise.
+ * elf64-sparc.c (ELF_COMMONPAGESIZE): Likewise.
+ * elf64-x86-64.c (ELF_COMMONPAGESIZE): Likewise.
+ * elfn32-mips.c (ELF_COMMONPAGESIZE): Likewise.
+ * elfxx-ia64.c (ELF_COMMONPAGESIZE): Likewise.
+
+ * elfxx-target.h (ELF_COMMONPAGESIZE): Define if not defined.
+ (elfNN_bed): Initialize commonpagesize with ELF_COMMONPAGESIZE.
+
+ * targets.c (bfd_find_target): Support NULL abfd.
+
+2006-05-30 Nick Clifton <nickc@redhat.com>
+
+ * po/es.po: Updated Spanish translation.
+
+2006-05-27 Alan Modra <amodra@bigpond.net.au>
+ H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf.c (assign_file_positions_for_load_sections): Retrieve
+ maxpagesize from m->p_align if it is valid. Set p_vaddr,
+ p_paddr and p_align earlier. Revert 2006-05-19 change to p_align.
+ (copy_elf_program_header): Copy p_align. Set p_align_valid.
+
+2006-05-26 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf64-x86-64.c (ELF_MINPAGESIZE): Changed to 0x1000.
+
+2006-05-25 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf64-x86-64.c (ELF_MINPAGESIZE): Set to 0x100000.
+
+2006-05-25 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf64-x86-64.c (ELF_MAXPAGESIZE): Updated to 0x200000.
+
+2006-05-26 Alan Modra <amodra@bigpond.net.au>
+
+ * elf.c (sym_is_global): Return a bfd_boolean.
+ (ignore_section_sym): New function.
+ (elf_map_symbols): Use ignore_section_sym to discard some syms.
+ (_bfd_elf_symbol_from_bfd_symbol): Ensure section belongs to
+ bfd before using elf_section_syms.
+
+2006-05-25 H.J. Lu <hongjiu.lu@intel.com>
+
+ * config.bfd: (sh-*-linux*): Treat as 64bit target.
+ (sh*l*-*-netbsdelf*): Likewise.
+ (sh-*-netbsdelf*): Likewise.
+ (shl*-*-elf*): Likewise.
+ (sh[1234]l*-*-elf*): Likewise.
+ (sh3el*-*-elf*): Likewise.
+ (shl*-*-kaos*): Likewise.
+ (sh-*-elf*): Likewise.
+ (sh[1234]*-elf*): Likewise.
+ (sh-*-rtems*): Likewise.
+ (sh-*-kaos*): Likewise.
+
+2006-05-24 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/1485
+ * config.bfd: Set want64 to true if 64bit bfd is used.
+ (sh-*-linux*): Use targ64_selvecs for 64bit targets.
+ (sh*l*-*-netbsdelf*): Likewise.
+ (sh-*-netbsdelf*): Likewise.
+ (shl*-*-elf*): Likewise.
+ (sh[1234]l*-*-elf*): Likewise.
+ (sh3el*-*-elf*): Likewise.
+ (shl*-*-kaos*): Likewise.
+ (sh-*-elf*): Likewise.
+ (sh[1234]*-elf*): Likewise.
+ (sh-*-rtems*): Likewise.
+ (sh-*-kaos*): Likewise.
+
+2006-05-24 Paul Brook <paul@codesourcery.com>
+
+ * elf-bfd.h (elf_backend_data): Add elf_backend_output_arch_local_syms
+ * elf32-arm.c (output_arch_syminfo): Define.
+ (elf32_arm_ouput_plt_map_sym, elf32_arm_output_plt_map,
+ elf32_arm_output_arch_local_syms): New functions.
+ (elf_backend_output_arch_local_syms): Define.
+ * elflink.c (bfd_elf_final_link): Call
+ elf_backend_output_arch_local_syms.
+ * elfxx-target.h (elf_backend_output_arch_local_syms): Provide default
+ definition.
+ (elfNN_bed): Add elf_backend_output_arch_local_syms.
+
+2006-05-24 Paul Brook <paul@codesourcery.com>
+
+ * elf32-arm.c (put_arm_insn, put_thumb_insn): New functions.
+ (elf32_thumb_to_arm_stub, elf32_arm_to_thumb_stub,
+ elf32_arm_finish_dynamic_symbol): Use them.
+
+2006-05-24 Carlos O'Donell <carlos@systemhalted.org>
+ Randolph Chung <tausq@debian.org>
+
+ * elf-hppa.h (reloc_hppa_howto_table): Check bitfield for
+ TPREL21L/TPREL14R relocations. Handle LTOFF_TP14R relocations.
+ Add handling for TLS relocations.
+ (elf_hpp_reloc_final_type): Handle TLS relocs.
+ * elf32-hppa.c: Add authors for cleanup and TLS support.
+ (hppa_elf_local_got_tls_type, hh_name, eh_name): Define.
+ (elf32_hppa_link_hash_entry): Add tls_type.
+ (elf32_hppa_link_hash_table): Add tld_ldm_got.
+ (hppa_link_has_newfunc): Set tls_type.
+ (elf32_hppa_link_hash_table_create): Set tls_ldm_got refcount.
+ (hppa_stub_name): Use hh_name macro.
+ (elf32_hppa_copy_indirect_symbol): Copy TLS information.
+ (elf32_hppa_check_relocs): Call elf32_hppa_optimized_tls_reloc.
+ Handle TLS relocs.
+ (elf32_hppa_gc_sweep_hook): Likewise.
+ (allocate_dynrelocs): Handle TLS relocs.
+ (elf32_hppa_size_dynamic_sections): Count space required by TLS
+ relocs. Use hh_name macro.
+ (dtpoff_base): New function.
+ (tpoff): Likewise.
+ (elf32_hppa_optimized_tls_reloc): Likewise.
+ (final_link_relocate): Handle TLS relocs.
+ (elf32_hppa_relocate_section): Handle TLS relocs. Use eh_name
+ and hh_name macros.
+ (elf32_hppa_finish_dynamic_symbol): Setup TLS got entries. Use
+ hh_name and eh_name macros.
+ (elf32_hppa_reloc_type_clas): Handle TLS relocs.
+
+2006-05-24 Bjoern Haase <bjoern.m.haase@web.de>
+
+ * archures.c: Add bfd_mach_avr6.
+ * cpu-avr.c: Likewise.
+ * reloc.c (BFD_RELOC_AVR_LO8_LDI_GS, BFD_RELOC_AVR_HI8_LDI_GS):
+ New relocations.
+ * libbfd.h: Regenerate.
+ * bfd-in2.h:Regenerate.
+ * elf32-avr.h: New file. Protoypes for functions accessed from ld.
+ * elf32-avr.c: Add elf32-avr.h to include list.
+ (elf32_avr_stub_hash_entry): New function.
+ (elf32_avr_link_hash_table): New struct.
+ (avr_link_hash_table): Likewise.
+ (avr_stub_hash_entry): Likewise.
+ (avr_stub_hash_lookup): New function.
+ (stub_hash_newfunc): New function.
+ (elf32_avr_link_hash_table_create): New function.
+ (elf32_avr_link_hash_table_free): New function.
+ (avr_get_stub_addr): New function.
+ (debug_relax, debug_stubs): Add new global variables controlling
+ debugging printout to stdout.
+ (avr_pc_wrap_around): Change the type to bfd_vma.
+ (avr_replace_call_ret_sequences): Add a new variable controling
+ linkrelax optimizations.
+ (avr_stub_is_required_for_16_bit_reloc): New function.
+ (avr_final_link_relocate):
+ Add linker hash table to parameter list. Use stub addr. if necessary.
+ (elf32_avr_relocate_section):
+ Add linker hashtable to parameter list of avr_final_link_relocate.
+ (bfd_elf_avr_final_write_processing): Add support for bfd_mach_avr6.
+ (elf32_avr_object_p): Add support for E_AVR_MACH_AVR6.
+ (elf32_avr_relax_delete_bytes):
+ Iterate over all sections of a bfd when adjusting relocs addends.
+ (elf32_avr_relax_section):
+ Evaluate avr_replace_call_ret_sequences and recalculate the size of
+ stub section.
+ (avr_stub_name): New function.
+ (avr_get_stub_entry): New function.
+ (avr_add_stub): New function.
+ (avr_build_one_stub): New function.
+ (avr_size_one_stub): New function.
+ (elf32_avr_setup_params): New function.
+ (elf32_avr_setup_section_lists): New function.
+ (get_local_syms): New function.
+ (elf32_avr_size_stubs): New function.
+ (bfd_elf32_bfd_link_hash_table_create): New function.
+ (bfd_elf32_bfd_link_hash_table_free): New function.
+
+2006-05-23 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/2655
+ PR ld/2657
+ * elf-eh-frame.c (_bfd_elf_write_section_eh_frame): Properly
+ update CIE/FDE length. Don't pad to the section alignment.
+
+2006-05-23 Jie Zhang <jie.zhang@analog.com>
+
+ * elf32-bfin.c (bfinfdpic_relocate_section): Clear reloc for
+ deteted entries in .eh_frame section.
+
+2006-05-23 Jie Zhang <jie.zhang@analog.com>
+
+ * elf32-bfin.c (bfin_check_relocs): Use __GLOBAL_OFFSET_TABLE_
+ instead of _GLOBAL_OFFSET_TABLE_.
+ (bfin_relocate_section): Ditto.
+ (_bfin_create_got_section): Ditto.
+ (elf32_bfinfdpic_create_dynamic_sections): Use
+ __PROCEDURE_LINKAGE_TABLE_ instead of _PROCEDURE_LINKAGE_TABLE_.
+ (bfin_finish_dynamic_symbol): Use __DYNAMIC instead of _DYNAMIC.
+
+2006-05-23 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (compare_symbols): Prefer strong dynamic global
+ function syms over other syms.
+
+2006-05-22 Daniel Jacobowitz <dan@codesourcery.com>
+
+ * elflink.c (_bfd_elf_add_dynamic_entry): Remove DT_TEXTREL
+ check.
+ (bfd_elf_final_link): Add a late DT_TEXTREL check.
+ * elfxx-mips.c (MIPS_ELF_READONLY_SECTION): Define.
+ (mips_elf_create_dynamic_relocation): Set DF_TEXTREL.
+ (_bfd_mips_elf_check_relocs): Delete MIPS_READONLY_SECTION.
+ Use MIPS_ELF_READONLY_SECTION.
+ (_bfd_mips_elf_size_dynamic_sections): Clear DF_TEXTREL after
+ creating DT_TEXTREL.
+ (_bfd_mips_elf_finish_dynamic_sections): Clear textrel markers
+ if no text relocations were generated.
+
+2006-05-19 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elfxx-ia64.c (ELF_MAXPAGESIZE): Fix a typo in comment.
+
+2006-05-19 Alan Modra <amodra@bigpond.net.au>
+
+ * elf.c (elf_fake_sections): Formatting.
+ (assign_file_positions_for_load_sections): Only add SEC_ALLOC
+ sections to p_memsz. Remove hack for PT_NOTE sections. Allow
+ section alignment to increase p_align for PT_LOAD.
+ (assign_file_positions_for_non_load_sections): Remove ARM BPABI
+ hack for PT_DYNAMIC. Instead, set p_filesz for all segments
+ other than PT_LOAD, and PT_NOTE in core.
+
+2006-05-17 Alan Modra <amodra@bigpond.net.au>
+
+ * elf.c (assign_file_positions_for_segments): Split into..
+ (assign_file_positions_for_load_sections): ..this, and..
+ (assign_file_positions_for_non_load_sections): ..this new function,..
+ (assign_file_positions_except_relocs): ..writing program headers here.
+
+2006-05-17 Alan Modra <amodra@bigpond.net.au>
+
+ * elflink.c (elf_gc_sweep): Don't specially keep non-alloc,
+ non-load sections if they have relocs.
+
+2006-05-15 Paul Brook <paul@codesourcery.com>
+
+ * cpu-arm.c (bfd_is_arm_mapping_symbol_name): Rename ...
+ (bfd_is_arm_special_symbol_name): ... to this. Add type argument.
+ Check symbol name is of specified type.
+ * elf32-arm.c (elf32_arm_is_target_special_symbol,
+ arm_elf_find_function, elf32_arm_output_symbol_hook): Use
+ bfd_is_arm_special_symbol_name.
+ * bfd-in.h (BFD_ARM_SPECIAL_SYM_TYPE_MAP,
+ BFD_ARM_SPECIAL_SYM_TYPE_TAG, BFD_ARM_SPECIAL_SYM_TYPE_OTHER,
+ BFD_ARM_SPECIAL_SYM_TYPE_ANY): Define.
+ (bfd_is_arm_mapping_symbol_name): Remove prototype.
+ (bfd_is_arm_special_symbol_name): Add prototype.
+ * bfd-in2.h: Regenerate.
+
+2006-05-15 David Heine <dlheine@tensilica.com>
+ Bob Wilson <bob.wilson@acm.org>
+
+ * elf32-xtensa.c (check_loop_aligned): Fix reversed check for
+ undefined opcode. Clean up assertions.
+ (narrow_instruction, widen_instruction): Remove "do_it" parameters.
+ Factor most of the code into separate functions....
+ (can_narrow_instruction, can_widen_instruction): New.
+ (prev_instr_is_a_loop): New.
+ (compute_ebb_proposed_actions): Combine error handling code for
+ decode errors. Replace call to insn_decode_len with inline code.
+ Use can_narrow_instruction and can_widen_instruction. Handle errors
+ from call to xtensa_opcode_is_loop.
+ (relax_section): Adjust calls to narrow_instruction and
+ widen_instruction.
+
+2006-05-15 Alan Modra <amodra@bigpond.net.au>
+
+ PR 2658
+ * elf32-ppc.c (ppc_elf_relax_section): Don't segfault on non-pic
+ -shared link.
+
+2006-05-11 Michael Matz <matz@suse.de>
+
+ * elflink.c (match_group_member): Correctly iterate group
+ members.
+
+2006-05-11 Paul Brook <paul@codesourcery.com>
+
+ * elf32-arm.c (elf32_arm_reloc_map): Add MOVW and MOVT relocs.
+ (elf32_arm_final_link_relocate): Handle MOVW and MOVT relocs.
+ (elf32_arm_gc_sweep_hook, elf32_arm_check_relocs): Ditto.
+ * reloc.c: Ditto.
+ * bfd-in2.h: Regenerate.
+ * libbfd.h: Regenerate.
+ * libcoff.h: Regenerate.
+
+2006-05-11 Mike Bland <mbland@google.com>
+
+ * elf.c (_bfd_elf_init_private_section_data): Don't change
+ section type if already set.
+
+2006-05-10 Nick Clifton <nickc@redhat.com>
+
+ PR ld/2607
+ * elfcode.h (valid_section_index_p): New function: Checks for a
+ valid section index. Allows indicies in the range SHN_LOPROC to
+ SHN_HIOS.
+ (elf_object_p): Use valid_section_index_p.
+
+2006-05-11 Pedro Alves <pedro_alves@portugalmail.pt>
+
+ * coff-arm.c (ARM_26D, ARM_32, ARM_RVA_32, ARM_SECTION,
+ ARM_SECREL): Mark WinCE versions of these relocs as partial
+ inplace.
+ (coff_arm_relocate_section): Adjust addend for WinCE.
+
+2006-05-10 Alan Modra <amodra@bigpond.net.au>
+
+ PR 2342
+ * elflink.c (_bfd_elf_default_action_discarded): Revert 2006-02-16.
+
+2006-05-09 Nick Clifton <nickc@redhat.com>
+
+ * coffcode.h (coff_write_relocs): Produce an error message if a an
+ out-of-range symbol index is detected in a reloc.
+
+2006-05-09 Ben Elliston <bje@au.ibm.com>
+
+ * elf64-ppc.c (ppc64_elf_finish_dynamic_symbol): Remove unused
+ local variable `dynobj'.
+
+2006-05-05 Bjoern Haase <bjoern.m.haase@web.de>
+
+ * elf32-avr.c (elf32_avr_relax_delete_bytes): Iterate over all
+ of the bfd's sections for the reloc-addend adjustments.
+
+2006-05-05 Martin Schwidefsky <schwidefsky@de.ibm.com>
+
+ * elf32-s390.c (invalid_tls_insn): Call bfd_set_error.
+ (elf_s390_relocate_section): Add code to do the GD->LE and
+ LD->LE TLS linker optimizations if a brasl instruction is used
+ for the __tls_get_offset function call.
+ * elf64-s390.c (invalid_tls_insn): Call bfd_set_error.
+
+2006-05-05 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (ppc64_elf_tls_optimize): Only optimize
+ R_PPC64_TPREL64 and R_PPC64_DTPMOD64 relocs when they are in
+ the .toc and referenced by a TLS code sequence.
+ (ppc64_elf_edit_toc): Cater for the unlikely situation that
+ .toc is the first section in a file.
+
+2006-05-04 Andreas Schwab <schwab@suse.de>
+
+ * aoutf1.h (struct external_sparc_core): Declare c_regs as struct
+ regs instead of an array of int.
+ (struct external_solaris_bcp_core): Likewise.
+ (swapcore_sun3): Use offsetof instead of computing the offset
+ manually.
+ (swapcore_sparc): Likewise. Simplify reference to c_regs.
+ (swapcore_solaris_bcp): Likewise.
+
+2006-05-04 Daniel Jacobowitz <dan@codesourcery.com>
+
+ * elfxx-mips.c (_bfd_mips_elf_hide_symbol): Adjust handling
+ for missing GOTs.
+
+2006-05-04 Daniel Jacobowitz <dan@codesourcery.com>
+
+ * cpu-arm.c (bfd_is_arm_mapping_symbol_name): Accept more
+ mapping symbols.
+
+2006-05-04 Ben Elliston <bje@au.ibm.com>
+
+ * coff-or32.c (bfd_section_from_shdr): Remove unused local
+ variable `ptr'.
+ * cofflink.c (process_embedded_commands): Remove unused local
+ variables `had_read' and `had_shared'.
+ * ecofflink.c (bfd_ecoff_debug_accumulate): Remove unused local
+ variable `fdr_adr'.
+ * ihex.c (ihex_read_section): Remove unused local variable `addr'.
+
+2006-05-03 Alan Modra <amodra@bigpond.net.au>
+
+ * libbfd-in.h (_bfd_generic_new_section_hook): Declare.
+ * section.c (bfd_abs_symbol, bfd_com_symbol): Delete.
+ (bfd_und_symbol, bfd_ind_symbol): Delete.
+ (BFD_FAKE_SECTION): Remove SYM_PTR param, set symbol_ptr_ptr to
+ &SEC.symbol.
+ (STD_SECTION): Adjust.
+ (_bfd_generic_new_section_hook): New function, extracted from..
+ (bfd_section_init): ..here.
+ (bfd_make_section_old_way): Call new_section_hook for abs, com,
+ und and ind sections.
+ * elf.c (_bfd_elf_large_com_section): Adjust.
+ * aoutx.h (new_section_hook): Call _bfd_generic_new_section_hook.
+ * pdp11.c (new_section_hook): Likewise.
+ * coffcode.h (coff_new_section_hook): Likewise.
+ * ecoff.c (_bfd_ecoff_new_section_hook): Likewise.
+ * elf.c (_bfd_elf_new_section_hook): Likewise.
+ * vms.c (vms_new_section_hook): Likwise.
+ * elf32-arm.c (elf32_arm_new_section_hook): Check used_by_bfd isn't
+ already set.
+ * elf32-sh64.c (sh64_elf_new_section_hook): Likewise.
+ * elf32-xtensa.c (elf_xtensa_new_section_hook): Likewise.
+ * elf64-mmix.c (mmix_elf_new_section_hook): Likewise.
+ * elf64-ppc.c (ppc64_elf_new_section_hook): Likewise.
+ * elfxx-mips.c (_bfd_mips_elf_new_section_hook): Likewise.
+ * elfxx-sparc.c (_bfd_sparc_elf_new_section_hook): Likewise.
+ * ieee.c (ieee_new_section_hook): Likewise. Call
+ _bfd_generic_new_section_hook too.
+ * mmo.c (mmo_new_section_hook): Likewise.
+ * oasys.c (oasys_new_section_hook): Likewise.
+ * som.c (som_new_section_hook): Likewise.
+ * coff-w65.c (reloc_processing): Don't use bfd_abs_symbol.
+ * bfd-in2.h: Regenerate.
+ * libbfd.h: Regenerate.
+
+2006-05-03 Alan Modra <amodra@bigpond.net.au>
+
+ * hash.c (DEFAULT_SIZE): Revert last change.
+ (higher_prime_number): Correct test for no larger prime. Don't
+ abort on error, instead return 0. Depopulate primes[].
+ (bfd_hash_lookup): If we overflow size, refuse to grow table.
+
+2006-05-02 Paul Brook <paul@codesourcery.com>
+
+ * elf32-arm.c (elf32_arm_final_link_relocate): Set thumb funciton bit
+ for R_ARM_REL32.
+
+2006-05-02 Ben Elliston <bje@au.ibm.com>
+
+ * archive.c (bfd_generic_archive_p): Remove unused local variable
+ `fail'.
+ * dwarf2.c (decode_line_info): Remove unused local variable
+ `basic_block'.
+ * elfcode.h (elf_slurp_reloc_table_from_section): Remove unused
+ local variable `s'.
+ * tekhex.c (tekhex_write_object_contents): Remove unused local
+ variable `bytes_written'.
+ * aout-ns32k.c (MY_swap_std_reloc_out): Remove unused local
+ variable `r_addend'.
+ * elf32-dlx.c (dlx_rtype_to_howto): Remove breaks after returns.
+ * elfxx-mips.c (_bfd_elf_mips_mach): Remove breaks after returns.
+ (_bfd_ns32k_relocate_contents): Remove break after return.
+ * elf.c (bfd_section_from_shdr): Remove breaks after returns.
+
+2006-05-02 Nick Clifton <nickc@redhat.com>
+
+ * elf32-sh-symbian.c: Rename local define DEBUG to SYMBIAN_DEBUG
+ in order to avoid conflicts with the global DEBUG define.
+
+2006-05-02 Alan Modra <amodra@bigpond.net.au>
+
+ * dwarf2.c: Formatting.
+ * elf-eh-frame.c (_bfd_elf_discard_section_eh_frame): Simplify
+ output section check.
+ * elf32-i370.c: Warning fixes inside #ifdef DEBUG.
+ * elf32-m32c.c: Similarly.
+ * elf32-ppc.c: Similarly.
+ * elf32-v850.c: Similarly.
+ * nlm32-sparc.c: Similarly.
+ * elfcode.h: Similarly.
+ (elf_symbol_flags): Delete.
+ * elflink.c (elf_link_input_bfd): Comment typo.
+
+2006-05-01 DJ Delorie <dj@redhat.com>
+
+ * bfd-in.h (bfd_hash_table): Add count field.
+ * bfd-in2.h: Regenerate.
+ * hash.c (higher_prime_number): New.
+ (bfd_hash_table_inint_n): Init count field.
+ (bfd_hash_lookup): Grow table as needed.
+
+2006-04-27 Kaz Kojima <kkojima@rr.iij4u.or.jp>
+
+ PR binutils/2584
+ * tekhex.c (getvalue): Change return type to bfd_boolean and
+ add the new parameter. Return false if the unexpected character
+ is found.
+ (getsym): Likewise.
+ (first_phase): Change return type to bfd_boolean and return
+ false if the unexpected character is found. Replace abort
+ with returning false.
+ (pass_over): Change return type to bfd_boolean and the type of
+ the second argument to bfd_boolean (*) (bfd *, int, char *).
+ Return false if FUNC returns false.
+ (tekhex_object_p): Return NULL if pass_over fails.
+
+2006-04-27 Alan Modra <amodra@bigpond.net.au>
+
+ * coff-rs6000.c (xcoff_write_archive_contents_old): Warning fix.
+
+2006-04-26 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR binutils/2593
+ * elf.c (_bfd_elf_new_section_hook): Don't set section ELF type
+ and flags if its BFD flags have been set.
+ (_bfd_elf_init_private_section_data): Don't copy the output ELF
+ section type from input if it has been set to something
+ different.
+
+2006-04-25 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR binutils/2467
+ * elf.c (_bfd_elf_close_and_cleanup): Check elf_tdata (abfd)
+ is NULL first.
+
+ * elf32-arm.c (elf32_arm_close_and_cleanup): Check if
+ abfd->sections is NULL.
+ (elf32_arm_bfd_free_cached_info): New.
+ (bfd_elf32_bfd_free_cached_info): Defined.
+
+ * elfxx-target.h (bfd_elfNN_bfd_free_cached_info): Default it
+ to _bfd_free_cached_info.
+
+ * libbfd-in.h (_bfd_free_cached_info): New.
+ * libbfd: Regenerated.
+
+ * opncls.c (_bfd_delete_bfd): Check if abfd->memory is NULL.
+ (_bfd_free_cached_info): New.
+
+2006-04-21 Alan Modra <amodra@bigpond.net.au>
+
+ * elf.c (assign_file_positions_except_relocs): Move code setting
+ file position of non-loaded sections..
+ (assign_file_positions_for_segments): ..to here.
+
+2006-04-20 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/2537
+ * elf.c (bfd_section_from_shdr): Allow sections reserved for
+ applications. Issue an error on sections we don't know how
+ to handle.
+
+2006-04-19 Alan Modra <amodra@bigpond.net.au>
+
+ * Makefile.am: Run "make dep-am".
+ * Makefile.in: Regenerate.
+
+2006-04-19 Alan Modra <amodra@bigpond.net.au>
+
+ * warning.m4 (--enable-werror): Format help message.
+ (--enable-build-warnings): Likewise.
+ * configure: Regenerate.
+
+2006-04-18 Nick Clifton <nickc@redhat.com>
+
+ PR 2257
+ * elfcode.h (elf_object_p): Allow files with corrupt e_shstrndx
+ fields to still be handled as ELF files.
+
+2006-04-16 Daniel Jacobowitz <dan@codesourcery.com>
+
+ * po/SRC-POTFILES.in: Regenerated.
+
+2006-04-16 Daniel Jacobowitz <dan@codesourcery.com>
+
+ * configure.in: Update version to 2.17.50.
+ * configure: Regenerated.
+
+2006-04-14 David Heine <dlheine@tensilica.com>
+
+ * elf32-xtensa.c (build_reloc_opcodes): New.
+ (compute_text_actions): Use it to decode opcodes outside inner loop.
+ (check_section_ebb_pcrels_fit): Add "reloc_opcodes" argument, and if
+ it is set, use it to get the opcodes for relocations.
+ (move_shared_literal): Adjust call to check_section_ebb_pcrels_fit.
+
+2006-04-08 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/2513
+ * elf32-i386.c (GOT_TLS_MASK): New macro for tls_type.
+ (GOT_TLS_IE_IE): Likewise.
+ (GOT_TLS_IE_GD): Likewise.
+ (GOT_TLS_IE_MASK): Likewise.
+ (elf_i386_check_relocs): For global symbols, set GOT_TLS_IE_GD
+ and GOT_TLS_IE_IE for R_386_TLS_GD and R_386_TLS_IE
+ respectively.
+ (allocate_dynrelocs): If both GOT_TLS_IE_IE and GOT_TLS_IE_GD
+ are set, treat tls_type as GOT_TLS_IE_BOTH.
+ (elf_i386_relocate_section): Likewise.
+
+2006-04-07 Randolph Chung <tausq@debian.org>
+
+ * elf64-hppa.c (elf64_hppa_grok_prstatus): New function.
+ (elf64_hppa_grok_psinfo): Likewise.
+ (elf_backend_grok_pstatus, elf_backend_grok_psinfo): Define.
+
+2006-04-06 DJ Delorie <dj@redhat.com>
+
+ * elf32-m32c.c (m32c_elf_relocate_section): Generate a symbol for
+ each plt entry we create.
+
+2006-04-06 Carlos O'Donell <carlos@codesourcery.com>
+
+ * po/Make-in: Add install-html target.
+ * Makefile.am: Rename docdir to bfddocdir. Add datarootdir, docdir
+ htmldir. Add install-html and install-html-recursive targets.
+ * Makefile.in: Regenerate.
+ * configure.in: AC_SUBST for datarootdir, docdir and htmldir.
+ * configure: Regenerate.
+
+2006-04-06 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elfxx-ia64.c (elfNN_ia64_relax_section): Skip unneeded passes
+ with the skip_relax_pass_0 and skip_relax_pass_1 bits in the
+ section structure.
+
+2006-04-05 Bernd Schmidt <bernd.schmidt@analog.com>
+
+ * elf32-bfin.c (bfinfdpic_relocs_info_hash): Sprinkle casts to
+ eliminate warnings.
+
+2006-04-05 H.J. Lu <hongjiu.lu@intel.com>
+ James E Wilson <wilson@specifixinc.com>
+
+ PR ld/2442
+ * elfxx-ia64.c (elfNN_ia64_dyn_sym_info): Remove next.
+ (elfNN_ia64_local_hash_entry): Add count, sorted_count and
+ size.
+ (elfNN_ia64_link_hash_entry): Likewise.
+ (elfNN_ia64_new_elf_hash_entry): Initialize count, sorted_count
+ and size.
+ (elfNN_ia64_hash_copy_indirect): Updated elfNN_ia64_dyn_sym_info
+ processing.
+ (elfNN_ia64_hash_hide_symbol): Likewise.
+ (elfNN_ia64_global_dyn_sym_thunk): Likewise.
+ (elfNN_ia64_local_dyn_sym_thunk): Likewise.
+ (elfNN_ia64_global_dyn_info_free): New function.
+ (elfNN_ia64_local_dyn_info_free): Likewise.
+ (elfNN_ia64_hash_table_free): Free local and global
+ elfNN_ia64_dyn_sym_info.
+ (addend_compare): New function.
+ (sort_dyn_sym_info): Likewise.
+ (get_dyn_sym_info): Updated to use binary search for addend.
+ (elfNN_ia64_check_relocs): Scan relocations to create dynamic
+ relocation arrays first.
+
+2006-04-05 Bernd Schmidt <bernd.schmidt@analog.com>
+
+ * elf32-bfin.c (_bfin_create_got_section): Don't generate a _gp
+ symbol.
+
+2006-04-05 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/2411
+ * elflink.c (check_dynsym): New.
+ (elf_link_output_extsym): Use it.
+ (bfd_elf_final_link): Likewise.
+
+2006-04-05 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/2404
+ * elflink.c (_bfd_elf_merge_symbol): Skip the default indirect
+ symbol from the dynamic definition with the default version if
+ its type and the type of existing regular definition mismatch.
+
+2006-04-05 Richard Sandiford <richard@codesourcery.com>
+ Daniel Jacobowitz <dan@codesourcery.com>
+
+ * config.bfd (sparc-*-vxworks*): New stanza.
+ * configure.in (bfd_elf32_sparc_vxworks_vec): New stanza.
+ (bfd_elf32_sparc_vec, bfd_elf64_sparc_vec): Add elf-vxworks.lo.
+ * configure: Regenerate.
+ * elf32-sparc.c: Include elf-vxworks.h.
+ (elf32_sparc_vxworks_link_hash_table_create: New.
+ (elf32_sparc_vxworks_final_write_processing): New.
+ (TARGET_BIG_SYM): Override for VxWorks.
+ (TARGET_BIG_NAME, ELF_MINPAGESIZE): Likewise.
+ (bfd_elf32_bfd_link_hash_table_create): Likewise.
+ (elf_backend_want_got_plt, elf_backend_plt_readonly): Likewise.
+ (elf_backend_got_header_size, elf_backend_add_symbol_hook): Likewise.
+ (elf_backend_link_output_symbol_hook): Likewise.
+ (elf_backend_emit_relocs): Likewise.
+ (elf_backend_final_write_processing, elf32_bed): Likewise.
+ * elfxx-sparc.c: Include libiberty.h and elf-vxworks.h.
+ (sparc_vxworks_exec_plt0_entry, sparc_vxworks_exec_plt_entry): New.
+ (sparc_vxworks_shared_plt0_entry, sparc_vxworks_shared_plt_entry): New.
+ (_bfd_sparc_elf_link_hash_table_create): Don't initialize
+ build_plt_entry here.
+ (create_got_section): Initialize sgotplt for VxWorks.
+ (_bfd_sparc_elf_create_dynamic_sections): Initialize build_plt_entry,
+ plt_header_size and plt_entry_size, with new VxWorks-specific settings.
+ Call elf_vxworks_create_dynamic_sections for VxWorks.
+ (allocate_dynrelocs): Use plt_header_size and plt_entry_size.
+ Allocate room for .got.plt and .rela.plt.unloaded entries on VxWorks.
+ (_bfd_sparc_elf_size_dynamic_sections): Don't allocate a nop in .plt
+ for VxWorks. Check for the .got.plt section.
+ (sparc_vxworks_build_plt_entry): New function.
+ (_bfd_sparc_elf_finish_dynamic_symbol): Add handling of VxWorks PLTs.
+ Don't make _GLOBAL_OFFSET_TABLE_ and _PROCEDURE_LINKAGE_TABLE_
+ absolute on VxWorks.
+ (sparc32_finish_dyn): Add special handling for DT_RELASZ
+ and DT_PLTGOT on VxWorks.
+ (sparc_vxworks_finish_exec_plt): New.
+ (sparc_vxworks_finish_shared_plt): New.
+ (_bfd_sparc_elf_finish_dynamic_sections): Call them.
+ Use plt_header_size and plt_entry_size.
+ * elfxx-sparc.h (_bfd_sparc_elf_link_hash_table): Add is_vxworks,
+ srelplt2, sgotplt, plt_header_size and plt_entry_size fields.
+ * Makefile.am (elfxx-sparc.lo): Depend on elf-vxworks.h.
+ (elf32-sparc.lo): Likewise.
+ * Makefile.in: Regenerate.
+ * targets.c (bfd_elf32_sparc_vxworks_vec): Declare.
+ (_bfd_target_vector): Add a pointer to it.
+
+2006-03-30 Ben Elliston <bje@au.ibm.com>
+
+ PR ld/2267
+ * elflink.c (elf_fixup_link_order): Ensure `elfsec' is not a
+ special section number that exceeds the number of ELF sections
+ (eg. SHN_MIPS_SCOMMON).
+
+2006-03-27 Richard Sandiford <richard@codesourcery.com>
+
+ * elfxx-mips.c (mips_got_entry): Add more commentary.
+ (mips_elf_local_got_index): Use the hash table entry to record
+ the GOT index of forced-local symbols.
+ (mips_elf_initialize_tls_index): Rearrange code. Store the index
+ in either the hash table entry or the mips_got_entry, not both.
+ Add more commentary.
+ (mips_elf_multi_got): Make sure the g->next is nonnull when calling
+ mips_elf_initialize_tls_index.
+
+2006-03-25 Bernd Schmidt <bernd.schmidt@analog.com>
+
+ * elf32-bfin.c (bfd_const_reloc, bfd_oper_reloc, bfin_push_reloc,
+ RELOC_STACK_SIZE, reloc_stack, reloc_stack_tos, is_reloc_stack_empty,
+ reloc_stack_push, reloc_stack_pop, reloc_stack_operate,
+ bfin_areloc_howto_table): Delete. All
+ uses deleted as well.
+ (bfin_reloc_map): Delete all stack relocs.
+ (bfin_info_to_howto, bfin_bfd_reloc_type_lookup,
+ bfin_reloc_type_lookup): Don't support them.
+ (bfin_relocate_section): Don't try to handle them.
+
+ * config.bfd (bfin-*-*): Add bfd_elf32_bfinfdpic_vec.
+ * configure.in: Likewise.
+ * configure: Regenerate.
+ * elf32-bfin.c: Include "elf/dwarf2.h" and "hashtab.h".
+ (BFIN_RELOC_MAX): Now 0x21.
+ (bfin_howto_table, bfin_reloc_map): Add FD-PIC relocs.
+ (bfd_elf32_bfinfdpic_vec): Declare.
+ (IS_FDPIC): New macro.
+ (struct bfinfdpic_elf_link_hash_table): New struct.
+ (bfinfdpic_hash_table, bfinfdpic_got_section,
+ bfinfdpic_gotrel_section, bfinfdpic_gotfixup_section,
+ bfinfdpic_plt_setion, bfinfdpic_pltrel_section,
+ bfinfdpic_relocs_info, bfinfdpic_got_initial_offset,
+ bfinfdpic_plt_initial_offset): Accessor macros for it.
+ (BFINFDPIC_SYM_LOCAL, BFINFDPIC_FUNCDESC_LOCAL): New macros.
+ (struct bfinfdpic_relocs_info): New struct.
+ (LZPLT_RESOLVER_EXTRA, LZPLT_NORMAL_SIZE, LZPLT_ENTRIES,
+ BFINFDPIC_LZPLT_BLOCK_SIZE, BFINFDPIC_LZPLT_RESOLV_LOC,
+ DEFAULT_STACK_SIZE): New macros.
+ (bfinfdpic_elf_link_hash_table_create, bfinfdpic_relocs_info_hash,
+ bfinfdpic_relocs_info_eq, bfinfdpics_relocs_info_find,
+ bfinfdpic_relocs_info_for_global, bfinfdpic_relocs_info_for_local,
+ bfinfdpic_pic_merge_early_relocs_info, _bfinfdpic_add_dyn_reloc,
+ _bfinfdpic_add_rofixup, _bfinfdpic_osec_to_segment,
+ _bfinfdpic_osec_readonly_p, bfinfdpic_relocate_section,
+ bfinfdpic_check_relocs, bfinfdpic_gc_sweep_hook,
+ _bfinfdpic_link_omit_section_dynsym, _bfin_create_got_section,
+ elf32_bfinfdpic_create_dynamic_sections, _bfinfdpic_get_fd_entry,
+ _bfinfdpic_compute_got_alloc_data, _bfinfdpic_get_got_entry,
+ _bfinfdpic_assign_got_entries, _bfinfdpic_assign_plt_entries,
+ _bfinfdpic_resolve_final_relocs_info,
+ elf32_bfinfdpic_size_dynamic_sections,
+ elf32_bfinfdpic_always_size_sections,
+ elf32_bfinfdpic_modify_segment_map,
+ _bfinfdpic_count_got_plt_entries,
+ elf32_bfinfdpic_finish_dynamic_sections,
+ elf32_bfinfdpic_adjust_dynamic_symbol,
+ elf32_bfinfdpic_finish_dynamic_symbol,
+ elf32_bfinfdpic_elf_use_relative_eh_frame,
+ elf32_bfinfdpic_elf_encode_eh_address,
+ elf32_bfin_object_p, bfin_elf_copy_private_bfd_data,
+ elf32_bfinfdpic_copy_private_bfd_data,
+ (struct _bfinfdpic_dynamic_got_info,
+ struct _bfinfdpic_dynamic_got_plt_info): New structs.
+ (elf32_bfin_print_private_bfd_data): Print PIC flags.
+ (elf32_bfin_merge_private_bfd_data): Extend to support FD-PIC.
+ (TARGET_LITTLE_SYM, TARGET_LITTLE_NAME, elf32_bed,
+ elf_backend_got_header_size, bfd_elf32_bfd_link_hash_table_create,
+ elf_backend_always_size_sectinos, elf_backend_modify_segment_map,
+ bfd_elf32_bfd_copy_private_bfd_data,
+ 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, elf_backend_relocate_section,
+ elf_backend_can_make_relative_eh_frame, elf_backend_check_relocs,
+ elf_backend_can_make_ldsa_relative_eh_frame, elf_backend_may_use_rel_p,
+ elf_backend_may_use_rela_p, elf_backend_default_use_rela_p,
+ elf_backend_omit_section_dynsym): Redefine these macros and include
+ "elf32-target.h" again to create the elf32-bfinfdpic target.
+ * reloc.c (BFD_RELOC_BFIN_GOT17M4, BFD_RELOC_BFIN_GOTHI,
+ BFD_RELOC_BFIN_GOTLO, BFD_RELOC_BFIN_FUNCDESC,
+ BFD_RELOC_BFIN_FUNCDESC_GOT17M4, BFD_RELOC_BFIN_FUNCDESC_GOTHI,
+ BFD_RELOC_BFIN_FUNCDESC_GOTLO, BFD_RELOC_BFIN_FUNCDESC_VALUE,
+ BFD_RELOC_BFIN_FUNCDESC_GOTOFF17M4, BFD_RELOC_BFIN_FUNCDESC_GOTOFFHI,
+ BFD_RELOC_BFIN_FUNCDESC_GOTOFFLO, BFD_RELOC_BFIN_GOTOFFHI,
+ BFD_RELOC_BFIN_GOTOFFLO): New.
+ * targets.c (bfd_elf32_bfinfdpic_vec): New bfd_target.
+ (_bfd_target_vector): Add it.
+ * bfd-in2.h: Regenerate.
+ * libbfd.h: Regenerate.
+
+2006-03-25 Richard Sandiford <richard@codesourcery.com>
+
+ * cpu-m68k.c (bfd_m68k_compatible): Treat ISA A+ and ISA B code as
+ incompatible. Likewise MAC and EMAC code.
+ * elf32-m68k.c (elf32_m68k_merge_private_bfd_data): Use
+ bfd_get_compatible to set the new bfd architecture. Rely on it
+ to detect incompatibilities.
+
+2006-03-23 Michael Matz <matz@suse.de>
+
+ * reloc.c: Add BFD_RELOC_X86_64_GOT64, BFD_RELOC_X86_64_GOTPCREL64,
+ BFD_RELOC_X86_64_GOTPC64, BFD_RELOC_X86_64_GOTPLT64,
+ BFD_RELOC_X86_64_PLTOFF64.
+ * bfd-in2.h: Regenerated.
+ * libbfd.h: Regenerated.
+ * elf64-x86-64.c (x86_64_elf_howto_table): Correct comment.
+ Add howtos for above relocs.
+ (x86_64_reloc_map): Add mappings for new relocs.
+ (elf64_x86_64_check_relocs): R_X86_64_GOT64, R_X86_64_GOTPCREL64,
+ R_X86_64_GOTPLT64 need a got entry. R_X86_64_GOTPLT64 also a PLT
+ entry. R_X86_64_GOTPC64 needs a .got section. R_X86_64_PLTOFF64
+ needs a PLT entry.
+ (elf64_x86_64_gc_sweep_hook): Reflect changes from
+ elf64_x86_64_check_relocs for the new relocs.
+ (elf64_x86_64_relocate_section): Handle new relocs.
+
+2006-03-22 Bob Wilson <bob.wilson@acm.org>
+
+ * elf32-xtensa.c (xtensa_read_table_entries): Remove assertion that
+ rel->r_addend is zero.
+
+2006-03-22 Richard Sandiford <richard@codesourcery.com>
+
+ * elfxx-mips.c (_bfd_mips_vxworks_finish_dynamic_symbol): Fix type
+ of "loc".
+
+2006-03-22 Richard Sandiford <richard@codesourcery.com>
+ Daniel Jacobowitz <dan@codesourcery.com>
+ Phil Edwards <phil@codesourcery.com>
+ Zack Weinberg <zack@codesourcery.com>
+ Mark Mitchell <mark@codesourcery.com>
+ Nathan Sidwell <nathan@codesourcery.com>
+
+ * bfd-in2.h: Regenerate.
+ * config.bfd (mips*-*-vxworks*, mips*el-*-vxworks*): New stanzas.
+ * configure.in (bfd_elf32_bigmips_vxworks_vec): New stanza.
+ (bfd_elf32_littlemips_vxworks_vec): Likewise.
+ (bfd_elf32_bigmips_vec): Add elf-vxworks.lo.
+ (bfd_elf32_littlemips_vec): Likewise.
+ (bfd_elf32_nbigmips_vec): Likewise.
+ (bfd_elf32_nlittlemips_vec): Likewise.
+ (bfd_elf32_ntradbigmips_vec): Likewise.
+ (bfd_elf32_ntradlittlemips_vec): Likewise.
+ (bfd_elf32_tradbigmips_vec): Likewise.
+ (bfd_elf32_tradlittlemips_vec): Likewise.
+ (bfd_elf64_bigmips_vec): Likewise.
+ (bfd_elf64_littlemips_vec): Likewise.
+ (bfd_elf64_tradbigmips_vec): Likewise.
+ (bfd_elf64_tradlittlemips_vec): Likewise.
+ * elf32-mips.c: Include elf-vxworks.h.
+ (mips_info_to_howto_rel): Use elf_backend_mips_rtype_to_howto
+ instead of calling mips_elf32_rtype_to_howto directly.
+ (mips_vxworks_copy_howto_rela): New reloc howto.
+ (mips_vxworks_jump_slot_howto_rela): Likewise.
+ (mips_vxworks_bfd_reloc_type_lookup): New function.
+ (mips_vxworks_rtype_to_howto): Likewise.
+ (mips_vxworks_final_write_processing): Likewise.
+ (TARGET_LITTLE_SYM, TARGET_LITTLE_NAME): Override for VxWorks.
+ (TARGET_BIG_SYM, TARGET_BIG_NAME, elf_bed, ELF_MAXPAGESIZE): Likewise.
+ (elf_backend_want_got_plt): Likewise.
+ (elf_backend_want_plt_sym): Likewise.
+ (elf_backend_got_symbol_offset): Likewise.
+ (elf_backend_want_dynbss): Likewise.
+ (elf_backend_may_use_rel_p): Likewise.
+ (elf_backend_may_use_rela_p): Likewise.
+ (elf_backend_default_use_rela_p): Likewise.
+ (elf_backend_got_header_size: Likewise.
+ (elf_backend_plt_readonly): Likewise.
+ (bfd_elf32_bfd_reloc_type_lookup): Likewise.
+ (elf_backend_mips_rtype_to_howto): Likewise.
+ (elf_backend_adjust_dynamic_symbol): Likewise.
+ (elf_backend_finish_dynamic_symbol): Likewise.
+ (bfd_elf32_bfd_link_hash_table_create): Likewise.
+ (elf_backend_add_symbol_hook): Likewise.
+ (elf_backend_link_output_symbol_hook): Likewise.
+ (elf_backend_emit_relocs): Likewise.
+ (elf_backend_final_write_processing: Likewise.
+ (elf_backend_additional_program_headers): Likewise.
+ (elf_backend_modify_segment_map): Likewise.
+ (elf_backend_symbol_processing): Likewise.
+ * elfxx-mips.c: Include elf-vxworks.h.
+ (mips_elf_link_hash_entry): Add is_relocation_target and
+ is_branch_target fields.
+ (mips_elf_link_hash_table): Add is_vxworks, srelbss, sdynbss, srelplt,
+ srelplt2, sgotplt, splt, plt_header_size and plt_entry_size fields.
+ (MIPS_ELF_RELA_SIZE, MIPS_ELF_REL_DYN_NAME): New macros.
+ (MIPS_RESERVED_GOTNO): Take a mips_elf_link_hash_table argument.
+ Return 3 for VxWorks.
+ (ELF_MIPS_GP_OFFSET): Change the argument from a bfd to a
+ mips_elf_link_hash_table. Return 0 for VxWorks.
+ (MIPS_ELF_GOT_MAX_SIZE): Change the argument from a bfd to a
+ mips_elf_link_hash_table. Update the call to ELF_MIPS_GP_OFFSET.
+ (mips_vxworks_exec_plt0_entry): New variable.
+ (mips_vxworks_exec_plt_entry): Likewise.
+ (mips_vxworks_shared_plt0_entry): Likewise.
+ (mips_vxworks_shared_plt_entry): Likewise.
+ (mips_elf_link_hash_newfunc): Initialize the new hash_entry fields.
+ (mips_elf_rel_dyn_section): Change the bfd argument to a
+ mips_elf_link_hash_table. Use MIPS_ELF_REL_DYN_NAME to get
+ the name of the section.
+ (mips_elf_initialize_tls_slots): Update the call to
+ mips_elf_rel_dyn_section.
+ (mips_elf_gotplt_index): New function.
+ (mips_elf_local_got_index): Add an input_section argument.
+ Update the call to mips_elf_create_local_got_entry.
+ (mips_elf_got_page): Likewise.
+ (mips_elf_got16_entry): Likewise.
+ (mips_elf_create_local_got_entry): Add bfd_link_info and input_section
+ arguments. Create dynamic relocations for each entry on VxWorks.
+ (mips_elf_merge_gots): Update the use of MIPS_ELF_GOT_MAX_SIZE.
+ (mips_elf_multi_got): Update the uses of MIPS_ELF_GOT_MAX_SIZE
+ and MIPS_RESERVED_GOTNO.
+ (mips_elf_create_got_section): Update the uses of
+ MIPS_ELF_GOT_MAX_SIZE. Create .got.plt on VxWorks.
+ (is_gott_symbol): New function.
+ (mips_elf_calculate_relocation): Use a dynobj local variable.
+ Update the calls to mips_elf_local_got_index, mips_elf_got16_entry and
+ mips_elf_got_page_entry. Set G to the .got.plt entry when calculating
+ VxWorks R_MIPS_CALL* relocations. Calculate and use G for all GOT
+ relocations on VxWorks. Add dynamic relocations for references
+ to the VxWorks __GOTT_BASE__ and __GOTT_INDEX__ symbols. Don't
+ create dynamic relocations for R_MIPS_32, R_MIPS_REL32 or R_MIPS_64
+ in VxWorks executables.
+ (mips_elf_allocate_dynamic_relocations): Add a bfd_link_info argument.
+ Use MIPS_ELF_RELA_SIZE to calculate the size of a VxWorks entry.
+ Don't allocate a null entry on VxWorks.
+ (mips_elf_create_dynamic_relocation): Update the call to
+ mips_elf_rel_dyn_section. Use absolute rather than relative
+ relocations for VxWorks, and make them RELA rather than REL.
+ (_bfd_mips_elf_create_dynamic_sections): Don't make .dynamic
+ read-only on VxWorks. Update the call to mips_elf_rel_dyn_section.
+ Create the .plt, .rela.plt, .dynbss and .rela.bss sections on
+ VxWorks. Likewise create the _PROCEDURE_LINKAGE_TABLE symbol.
+ Call elf_vxworks_create_dynamic_sections for VxWorks and
+ initialize the plt_header_size and plt_entry_size fields.
+ (_bfd_mips_elf_check_relocs): Don't allow GOT relocations to be
+ used in VxWorks executables. Don't allocate dynamic relocations
+ for R_MIPS_32, R_MIPS_REL32 or R_MIPS_64 in VxWorks executables.
+ Set is_relocation_target for each symbol referenced by a relocation.
+ Allocate .rela.dyn entries for relocations against the special
+ VxWorks __GOTT_BASE__ and __GOTT_INDEX__ symbols. Create GOT
+ entries for all VxWorks R_MIPS_GOT16 relocations. Don't allocate
+ a global GOT entry for symbols mentioned in VxWorks R_MIPS_CALL*,
+ R_MIPS_32, R_MIPS_REL32 or R_MIPS_64 relocations. Update the calls
+ to mips_elf_rel_dyn_section and mips_elf_allocate_dynamic_relocations.
+ Set is_branch_target for symbols mentioned in R_MIPS_PC16 or R_MIPS_26
+ relocations. Don't set no_fn_stub on VxWorks.
+ (_bfd_mips_elf_adjust_dynamic_symbol): Update the call to
+ mips_elf_allocate_dynamic_relocations.
+ (_bfd_mips_vxworks_adjust_dynamic_symbol): New function.
+ (_bfd_mips_elf_always_size_sections): Do not allocate GOT page
+ entries for VxWorks, and do not create multiple GOTs.
+ (_bfd_mips_elf_size_dynamic_sections): Use MIPS_ELF_REL_DYN_NAME.
+ Handle .got specially for VxWorks. Update the uses of
+ MIPS_RESERVED_GOTNO and mips_elf_allocate_dynamic_relocations.
+ Check for sgotplt and splt. Allocate the .rel(a).dyn contents last,
+ once its final size is known. Set DF_TEXTREL for VxWorks. Add
+ DT_RELA, DT_RELASZ, DT_RELAENT, DT_PLTREL, DT_PLTRELSZ and DT_JMPREL
+ tags on VxWorks. Do not add the MIPS-specific tags for VxWorks.
+ (_bfd_mips_vxworks_finish_dynamic_symbol): New function.
+ (mips_vxworks_finish_exec_plt): Likewise.
+ (mips_vxworks_finish_shared_plt): Likewise.
+ (_bfd_mips_elf_finish_dynamic_sections): Remove an unncessary call
+ to mips_elf_rel_dyn_section. Use a VxWorks-specific value of
+ DT_PLTGOT. Handle DT_RELA, DT_RELASZ, DT_RELAENT, DT_PLTREL,
+ DT_PLTRELSZ and DT_JMPREL. Update the uses of MIPS_RESERVED_GOTNO
+ and mips_elf_rel_dyn_section. Use a different GOT header for
+ VxWorks. Don't sort .rela.dyn on VxWorks. Finish the PLT on VxWorks.
+ (_bfd_mips_elf_link_hash_table_create): Initialize the new
+ mips_elf_link_hash_table fields.
+ (_bfd_mips_vxworks_link_hash_table_create): New function.
+ (_bfd_mips_elf_final_link): Set the GP value to _GLOBAL_OFFSET_TABLE_
+ on VxWorks. Update the call to ELF_MIPS_GP_OFFSET.
+ * elfxx-mips.h (_bfd_mips_vxworks_adjust_dynamic_symbol): Declare.
+ (_bfd_mips_vxworks_finish_dynamic_symbol): Likewise.
+ (_bfd_mips_vxworks_link_hash_table_create): Likewise.
+ * libbfd.h: Regenerate.
+ * Makefile.am (elfxx-mips.lo): Depend on elf-vxworks.h.
+ (elf32-mips.lo): Likewise.
+ * Makefile.in: Regenerate.
+ * reloc.c (BFD_RELOC_MIPS_COPY, BFD_RELOC_MIPS_JUMP_SLOT): Declare.
+ * targets.c (bfd_elf32_bigmips_vxworks_vec): Declare.
+ (bfd_elf32_littlemips_vxworks_vec): Likewise.
+ (_bfd_target_vector): Add entries for them.
+
+2006-03-19 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ * elf64-hppa.c (elf64_hppa_special_sections): Change flags for .tbss
+ section from SHF_PARISC_WEAKORDER to SHF_HP_TLS.
+ (elf_backend_special_sections): Remove #undef.
+
+2006-03-18 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ * elf64-hppa.c (allocate_global_data_opd): Don't create an OPD entry
+ for undefined weak symbols.
+
+2006-03-17 Daniel Jacobowitz <dan@codesourcery.com>
+
+ PR ld/2462
+ * elflink.c (bfd_elf_final_link): Remove
+ bed->elf_backend_emit_relocs from emit_relocs.
+
+2006-03-17 Alexandre Oliva <aoliva@redhat.com>
+
+ * elf32-ppc.c (ppc_elf_relocate_section): Copy addend from
+ first relocation to the second when relaxing TLS GD to LE;
+ zero it out when relaxing to IE.
+
+2006-03-17 Alan Modra <amodra@bigpond.net.au>
+
+ PR 2434
+ * elflink.c (elf_link_add_object_symbols): Save and restore
+ warning sym's linked sym.
+
+2006-03-16 Alan Modra <amodra@bigpond.net.au>
+
+ PR 2434
+ * elflink.c (struct elf_smash_syms_data, elf_smash_syms): Delete.
+ (elf_link_add_object_symbols): Delete unnecessary locals. Rename
+ hash_table -> htab. Formatting. Save entire symbol table
+ before loading as-needed syms, and restore afterwards if lib not
+ needed. Use bfd_hash_allocate rather than bfd_alloc for sym
+ name. Free some buffers earlier.
+ * bfd-in.h (struct bfd_hash_table): Add entsize.
+ (bfd_hash_table_init, bfd_hash_table_init_n): Adjust prototype.
+ * elf-bfd.h (_bfd_elf_link_hash_table_init): Likewise
+ * hash.c (bfd_hash_table_init_n): Add entsize param, save to
+ hash table.
+ (bfd_hash_table_init): Add param, adjust calls.
+ * aoutx.h: Adjust all hash_table_init functions and calls.
+ * bfd.c: Likewise.
+ * coff-arm.c: Likewise.
+ * coff-h8300.c: Likewise.
+ * coff-ppc.c: Likewise.
+ * cofflink.c: Likewise.
+ * ecoff.c: Likewise.
+ * ecofflink.c: Likewise.
+ * elf-m10300.c: Likewise.
+ * elf-strtab.c: Likewise.
+ * elf.c: Likewise.
+ * elf32-arm.c: Likewise.
+ * elf32-bfin.c: Likewise.
+ * elf32-cris.c: Likewise.
+ * elf32-frv.c: Likewise.
+ * elf32-hppa.c: Likewise.
+ * elf32-i386.c: Likewise.
+ * elf32-m32r.c: Likewise.
+ * elf32-m68hc1x.c: Likewise.
+ * elf32-m68k.c: Likewise.
+ * elf32-ppc.c: Likewise.
+ * elf32-s390.c: Likewise.
+ * elf32-sh.c: Likewise.
+ * elf32-vax.c: Likewise.
+ * elf64-alpha.c: Likewise.
+ * elf64-hppa.c: Likewise.
+ * elf64-ppc.c: Likewise.
+ * elf64-s390.c: Likewise.
+ * elf64-sh64.c: Likewise.
+ * elf64-x86-64.c: Likewise.
+ * elfxx-ia64.c: Likewise.
+ * elfxx-mips.c: Likewise.
+ * elfxx-sparc.c: Likewise.
+ * i386linux.c: Likewise.
+ * libaout.h: Likewise.
+ * libbfd-in.h: Likewise.
+ * libcoff-in.h: Likewise.
+ * linker.c: Likewise.
+ * m68klinux.c: Likewise.
+ * merge.c: Likewise.
+ * opncls.c: Likewise.
+ * pdp11.c: Likewise.
+ * sparclinux.c: Likewise.
+ * stabs.c: Likewise.
+ * sunos.c: Likewise.
+ * vms.c: Likewise.
+ * xcofflink.c: Likewise.
+ * section.c (struct section_hash_entry): Move to..
+ * libbfd-in.h: ..here.
+ * Makefile.am: Run "make dep-am"
+ * Makefile.in: Regenerate.
+ * bfd-in2.h: Regenerate.
+ * libbfd.h: Regenerate.
+ * libcoff.h: Regenerate.
+
+2006-03-16 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-ppc.c (ppc_elf_check_relocs): REL24 and REL14 relocs
+ against __GLOBAL_OFFSET_TABLE__ need never be dynamic. Tweak
+ last change to REL32 relocs so that they are counted as
+ possibly dynamic as per REL24 and REL14.
+
+2006-03-16 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-ppc.c (ppc_elf_check_relocs): Don't fall into REL24
+ checks from REL32.
+
+2006-03-15 Ben Elliston <bje@au.ibm.com>
+
+ * elf32-arm.c (elf32_arm_merge_eabi_attributes): Iterate over all
+ in_list elements, not just the first.
+
+2006-03-14 Richard Sandiford <richard@codesourcery.com>
+
+ * elf32-mips.c (mips_elf_adjust_addend): New function, mostly split
+ out from...
+ (_bfd_mips_elf_relocate_section): ...here. Use it to adjust r_addend
+ for final links too.
+
+2006-03-13 Richard Sandiford <richard@codesourcery.com>
+
+ * elfxx-mips.c (mips_elf_create_got_section): Initialize hgot.
+
+2006-03-11 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/2443
+ * dwarf2.c (concat_filename): Don't issue an error if file is 0.
+
+2006-03-10 Paul Brook <paul@codesourcery.com>
+
+ * elf32-arm.c (INTERWORK_FLAG): Handle EABIv5.
+ (elf32_arm_print_private_bfd_data): Ditto.
+
+2006-03-09 Paul Brook <paul@codesourcery.com>
+
+ * cpu-arm.c (bfd_is_arm_mapping_symbol_name): Recognise additional
+ mapping symbols.
+
+2006-03-09 Khem Raj <khem@mvista.com>
+
+ * elf32-arm.c(elf32_arm_finish_dynamic_sections): Use unsigned
+ char type.
+
+2006-03-08 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elfxx-ia64.c (elfNN_ia64_choose_gp): Properly choose gp.
+
+2006-03-07 Richard Sandiford <richard@codesourcery.com>
+ Daniel Jacobowitz <dan@codesourcery.com>
+ Zack Weinberg <zack@codesourcery.com>
+ Nathan Sidwell <nathan@codesourcery.com>
+ Paul Brook <paul@codesourcery.com>
+ Ricardo Anguiano <anguiano@codesourcery.com>
+ Phil Edwards <phil@codesourcery.com>
+
+ * configure.in (bfd_elf32_bigarm_vec): Include elf-vxworks.lo.
+ (bfd_elf32_bigarm_symbian_vec): Likewise.
+ (bfd_elf32_bigarm_vxworks_vec): Likewise.
+ (bfd_elf32_littlearm_vec): Likewise.
+ (bfd_elf32_littlearm_symbian_vec): Likewise.
+ (bfd_elf32_littlearm_vxworks_vec): Likewise.
+ * configure: Regenerate.
+ * elf32-arm.c: Include libiberty.h and elf-vxworks.h.
+ (RELOC_SECTION, RELOC_SIZE, SWAP_RELOC_IN, SWAP_RELOC_OUT): New macros.
+ (elf32_arm_vxworks_bed): Add forward declaration.
+ (elf32_arm_howto_table_1): Fix the masks for R_ASM_ABS12.
+ (elf32_arm_vxworks_exec_plt0_entry): New table.
+ (elf32_arm_vxworks_exec_plt_entry): Likewise.
+ (elf32_arm_vxworks_shared_plt_entry): Likewise.
+ (elf32_arm_link_hash_table): Add vxworks_p and srelplt2 fields.
+ (reloc_section_p): New function.
+ (create_got_section): Use RELOC_SECTION.
+ (elf32_arm_create_dynamic_sections): Likewise. Call
+ elf_vxworks_create_dynamic_sections for VxWorks targets.
+ Choose between the two possible values of plt_header_size
+ and plt_entry_size.
+ (elf32_arm_link_hash_table_create): Initialize vxworks_p and srelplt2.
+ (elf32_arm_abs12_reloc): New function.
+ (elf32_arm_final_link_relocate): Call it. Allow the creation of
+ dynamic R_ARM_ABS12 relocs on VxWorks. Use reloc_section_p,
+ RELOC_SIZE, SWAP_RELOC_OUT and RELOC_SECTION. Initialize the
+ r_addend fields of relocs. On rela targets, skip any code that
+ adjusts in-place addends. When using _bfd_link_final_relocate
+ to perform a final relocation, pass rel->r_addend as the addend
+ argument.
+ (elf32_arm_merge_private_bfd_data): If one of the bfds is a VxWorks
+ object, ignore flags that are not standard on VxWorks.
+ (elf32_arm_check_relocs): Allow the creation of dynamic R_ARM_ABS12
+ relocs on VxWorks. Use reloc_section_p.
+ (elf32_arm_adjust_dynamic_symbol): Use RELOC_SECTION and RELOC_SIZE.
+ (allocate_dynrelocs): Use RELOC_SIZE. Account for the size of
+ .rela.plt.unloaded relocs on VxWorks targets.
+ (elf32_arm_size_dynamic_sections): Use RELOC_SIZE. Check for
+ .rela.plt.unloaded as well as .rel(a).plt. Add DT_RELA* tags
+ instead of DT_REL* tags on RELA targets.
+ (elf32_arm_finish_dynamic_symbol): Use RELOC_SECTION, RELOC_SIZE
+ and SWAP_RELOC_OUT. Initialize r_addend fields. Handle VxWorks
+ PLT entries. Do not make _GLOBAL_OFFSET_TABLE_ absolute on VxWorks.
+ (elf32_arm_finish_dynamic_sections): Use RELOC_SECTION, RELOC_SIZE
+ and SWAP_RELOC_OUT. Initialize r_addend fields. Handle DT_RELASZ
+ like DT_RELSZ. Handle the VxWorks form of initial PLT entry.
+ Correct the .rela.plt.unreloaded symbol indexes.
+ (elf32_arm_output_symbol_hook): Call the VxWorks version of this
+ hook on VxWorks targets.
+ (elf32_arm_vxworks_link_hash_table_create): Set vxworks_p to true.
+ Minor formatting tweak.
+ (elf32_arm_vxworks_final_write_processing): New function.
+ (elf_backend_add_symbol_hook): Override for VxWorks and reset
+ for Symbian.
+ (elf_backend_final_write_processing): Likewise.
+ (elf_backend_emit_relocs): Likewise.
+ (elf_backend_want_plt_sym): Likewise.
+ (ELF_MAXPAGESIZE): Likewise.
+ (elf_backend_may_use_rel_p): Minor formatting tweak.
+ (elf_backend_may_use_rela_p): Likewise.
+ (elf_backend_default_use_rela_p): Likewise.
+ (elf_backend_rela_normal): Likewise.
+ * Makefile.in (elf32-arm.lo): Depend on elf-vxworks.h.
+
+2006-03-06 Nathan Sidwell <nathan@codesourcery.com>
+
+ * archures.c (bfd_mach_mcf_isa_a_nodiv, bfd_mach_mcf_isa_b_nousp):
+ New. Adjust other variants.
+ (bfd_default_scan): Update.
+ * bfd-in2.h: Rebuilt.
+ * cpu-m68k.c: Adjust.
+ (bfd_m68k_compatible): New. Use it for architectures.
+ * elf32-m68k.c (elf32_m68k_object_p): Adjust.
+ (elf32_m68k_merge_private_bfd_data): Adjust. Correct isa-a/b
+ mismatch.
+ (elf32_m68k_print_private_bfd_data): Adjust.
+ * ieee.c (ieee_write_processor): Adjust.
+
+2006-03-06 Alan Modra <amodra@bigpond.net.au>
+
+ * dwarf2.c: Formatting.
+ (add_line_info): Remove outer loop.
+
+2006-03-05 H.J. Lu <hongjiu.lu@intel.com>
+ Alan Modra <amodra@bigpond.net.au>
+
+ PR binutils/2338
+ * dwarf2.c (loadable_section): New struct.
+ (dwarf2_debug): Add loadable_section_count and
+ loadable_sections.
+ (new_line_sorts_after): New.
+ (add_line_info): Use new_line_sorts_after to compare line
+ addresses.
+ (check_function_name): Removed.
+ (unset_sections): New.
+ (place_sections): New.
+ (_bfd_dwarf2_find_nearest_line): Updated. Call place_sections
+ and unset_sections on relocatable files.
+ (_bfd_dwarf2_find_line): Likewise.
+
+2006-03-03 Nick Clifton <nickc@redhat.com>
+
+ * cpu-avr.c: Update to ISO-C90 formatting.
+ * elf32-avr.c: Likewise.
+
+2006-03-03 Bjoern Haase <bjoern.m.haase@web.de>
+
+ * elf32-avr.c (avr_reloc_map): Insert BFD_RELOC_AVR_MS8_LDI
+ and R_AVR_MS8_LDI
+ (bfd_elf_avr_final_write_processing): Set
+ EF_AVR_LINKRELAX_PREPARED in e_flags field.
+ (elf32_avr_relax_section): New function.
+ (elf32_avr_relax_delete_bytes): New function.
+ (elf32_avr_get_relocated_section_contents): New function.
+ (avr_pc_wrap_around): New function.
+ (avr_relative_distance_considering_wrap_around): New function.
+ (avr_final_link_relocate): Handle negative int8t_t immediate for R_AVR_LDI.
+ * reloc.c: Add BFD_RELOC_AVR_MS8_LDI and BFD_RELOC_AVR_LDI_NEG
+ * libbfd.h: Regenerate.
+ * bfd-in2.h: Regenerate.
+
+2006-03-02 DJ Delorie <dj@redhat.com>
+
+ * elf32-m32c.c (m32c_offset_for_reloc): Fix local symbol
+ calculations.
+
+2006-03-02 Richard Sandiford <richard@codesourcery.com>
+
+ * elf32-ppc.c (is_ppc_elf_target): Return true if the target is
+ bfd_elf32_powerpc_vxworks_vec.
+
+2006-03-02 Nick Clifton <nickc@redhat.com>
+
+ * elf32-m32c.c (m32c_elf_relax_section): Initialise 'gap'.
+
+2006-03-02 Richard Sandiford <richard@codesourcery.com>
+
+ * elf32-i386.c (elf_i386_create_dynamic_sections): Use
+ elf_vxworks_create_dynamic_sections.
+ (elf_i386_size_dynamic_sections): Remove VxWorks GOT and PLT
+ symbol handling.
+ * elf32-ppc.c (ppc_elf_create_dynamic_sections): Use
+ elf_vxworks_create_dynamic_sections.
+ (ppc_elf_size_dynamic_sections): Remove VxWorks GOT and PLT
+ symbol handling.
+ * elf-vxworks.c (elf_vxworks_create_dynamic_sections): New function.
+ * elf-vxworks.h (elf_vxworks_create_dynamic_sections): Declare.
+
+2006-03-02 Richard Sandiford <richard@codesourcery.com>
+
+ * elf32-i386.c (elf_i386_vxworks_link_output_symbol_hook): Delete.
+ (elf_backend_link_output_symbol_hook): Use
+ elf_vxworks_link_output_symbol_hook instead.
+ * elf32-ppc.c (elf_i386_vxworks_link_output_symbol_hook): Delete.
+ (elf_backend_link_output_symbol_hook): Use
+ elf_vxworks_link_output_symbol_hook instead.
+ * elf-vxworks.c (elf_vxworks_link_output_symbol_hook): Provide the
+ same interface as elf_backend_link_output_symbol_hook.
+ * elf-vxworks.h (elf_vxworks_link_output_symbol_hook): Update
+ prototype accordingly.
+
+2006-03-02 Richard Sandiford <richard@codesourcery.com>
+
+ * elf32-ppc.c (ppc_elf_plt_type): New enumeration.
+ (ppc_elf_link_hash_table): Replace old_got and new_got with
+ plt_type and can_use_new_plt.
+ (ppc_elf_create_dynamic_sections): Add SEC_HAS_CONTENTS,
+ SEC_LOAD and SEC_READONLY to the VxWorks .plt flags.
+ (ppc_elf_check_relocs): Set can_use_new_plt instead of new_plt.
+ Move from plt_type == PLT_UNSET to PLT_OLD instead of setting old_plt.
+ (ppc_elf_select_plt_layout): Move from plt_type == PLT_UNSET to
+ either plt_type == PLT_OLD or plt_type == PLT_NEW. Assert that
+ this function should not be called for VxWorks targets.
+ (ppc_elf_tls_setup): Use plt_type instead of old_got.
+ (allocate_got): Likewise. Rearrange so that max_before_header
+ is only used for PLT_OLD and PLT_NEW.
+ (allocate_dynrelocs): Use plt_type instead of old_got and is_vxworks.
+ (ppc_elf_size_dynamic_sections): Likewise.
+ (ppc_elf_relax_section): Likewise.
+ (ppc_elf_relocate_section): Likewise.
+ (ppc_elf_finish_dynamic_symbol): Likewise.
+ (ppc_elf_vxworks_link_hash_table_create): Initialize plt_type.
+
+2006-02-28 Richard Sandiford <richard@codesourcery.com>
+
+ * elf32-i386.c (elf_i386_link_hash_table): Add next_tls_desc_index.
+ (elf_i386_link_hash_table_create): Initialize it.
+ (elf_i386_compute_jump_table_size): Use it instead of
+ srelplt->reloc_count.
+ (allocate_dynrelocs): Likewise.
+ (elf_i386_size_dynamic_sections): Likewise.
+ (elf_i386_relocate_section): Likewise.
+
+2006-02-27 Jakub Jelinek <jakub@redhat.com>
+
+ * elf-eh-frame.c (_bfd_elf_discard_section_eh_frame): Handle S flag.
+ (_bfd_elf_write_section_eh_frame): Likewise.
+
+2006-02-27 Carlos O'Donell <carlos@codesourcery.com>
+
+ * po/Make-in: Add html target.
+
+2006-02-27 Richard Sandiford <richard@codesourcery.com>
+
+ * elf-m10300.c (_bfd_mn10300_elf_finish_dynamic_symbol): Use the
+ cached hgot entry to check for _GLOBAL_OFFSET_TABLE_.
+ * elf32-arm.c (elf32_arm_finish_dynamic_symbol): Likewise.
+ * elf32-bfin.c (bfin_finish_dynamic_symbol): Likewise.
+ * elf32-cris.c (elf_cris_finish_dynamic_symbol): Likewise.
+ * elf32-hppa.c (elf32_hppa_finish_dynamic_symbol): Likewise.
+ * elf32-i386.c (elf_i386_finish_dynamic_symbol): Likewise.
+ * elf32-m32r.c (m32r_elf_finish_dynamic_symbol): Likewise.
+ * elf32-m68k.c (elf_m68k_finish_dynamic_symbol): Likewise.
+ * elf32-sh.c (sh_elf_finish_dynamic_symbol): Likewise.
+ * elf32-vax.c (elf_vax_finish_dynamic_symbol): Likewise.
+ * elf32-xtensa.c (elf_xtensa_finish_dynamic_symbol): Likewise.
+ * elf64-sh64.c (sh64_elf64_finish_dynamic_symbol): Likewise.
+ * elf64-x86-64.c (elf64_x86_64_finish_dynamic_symbol): Likewise.
+ * elfxx-mips.c (_bfd_mips_elf_finish_dynamic_symbol): Likewise.
+ * elf32-s390.c (elf_s390_finish_dynamic_symbol): Likewise. Also use
+ the cached hplt entry to check for _PROCEDURE_LINKAGE_TABLE_.
+ * elf64-alpha.c (elf64_alpha_finish_dynamic_symbol): Likewise.
+ * elf64-s390.c (elf_s390_finish_dynamic_symbol): Likewise.
+ * elfxx-ia64.c (elfNN_ia64_finish_dynamic_symbol): Likewise.
+ * elfxx-sparc.c (_bfd_sparc_elf_finish_dynamic_symbol): Likewise.
+
+2006-02-25 Richard Sandiford <richard@codesourcery.com>
+
+ * elf-bfd.h (elf_link_hash_table): Add hplt field.
+ * elflink.c (_bfd_elf_create_dynamic_sections): Initialize it.
+ * elf-m10300.c (_bfd_mn10300_elf_create_got_section): Likewise.
+ * elf32-frv.c (_frv_create_got_section): Likewise.
+ * elf32-m32r.c (m32r_elf_create_dynamic_sections): Likewise.
+ * elf32-sh.c (sh_elf_create_dynamic_sections): Likewise.
+ * elf64-alpha.c (elf64_alpha_create_dynamic_sections): Likewise.
+ * elf64-sh64.c (sh64_elf64_create_dynamic_sections): Likewise.
+ * elf32-i386.c (elf_i386_link_hash_table): Remove hgot and hplt.
+ (elf_i386_link_hash_table_create): Don't initialize them.
+ (elf_i386_size_dynamic_sections): Use the generic ELF hplt and
+ hgot fields.
+ (elf_i386_finish_dynamic_symbol): Likewise.
+ * elf32-ppc.c (ppc_elf_link_hash_table): Remove hplt.
+ (ppc_elf_size_dynamic_sections): Use the generic ELF hplt fields.
+ (ppc_elf_finish_dynamic_symbol): Likewise.
+
+2006-02-24 DJ Delorie <dj@redhat.com>
+
+ * elf32-m32c.c (m32c_elf_howto_table): Add relaxation relocs.
+ (m32c_elf_relocate_section): Don't relocate them.
+ (compare_reloc): New.
+ (relax_reloc): Remove.
+ (m32c_offset_for_reloc): New.
+ (m16c_addr_encodings): New.
+ (m16c_jmpaddr_encodings): New.
+ (m32c_addr_encodings): New.
+ (m32c_elf_relax_section): Relax jumps and address displacements.
+ (m32c_elf_relax_delete_bytes): Adjust for internal syms. Fix up
+ short jumps.
+
+ * reloc.c: Add m32c relax relocs.
+ * libbfd.h: Regenerate.
+ * bfd-in2.h: Regenerate.
+
+2006-02-24 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/2218
+ * elf-bfd.h (elf_backend_data): Add elf_backend_fixup_symbol.
+ (_bfd_elf_link_hash_fixup_symbol): New.
+
+ * elflink.c (_bfd_elf_link_hash_fixup_symbol): New.
+ (_bfd_elf_fix_symbol_flags): Call elf_backend_fixup_symbol if
+ it isn't NULL.
+
+ * elfxx-ia64.c (elf_backend_fixup_symbol): Defined.
+
+ * elfxx-target.h (elf_backend_fixup_symbol): New.
+ (elfNN_bed): Initialize elf_backend_fixup_symbol.
+
+2006-02-23 H.J. Lu <hongjiu.lu@intel.com>
+
+ * cpu-ia64-opc.c (ins_immu5b): New.
+ (ext_immu5b): Likewise.
+ (elf64_ia64_operands): Add IMMU5b.
+
+2006-02-21 Alan Modra <amodra@bigpond.net.au>
+
+ PR ld/2218
+ * elf32-arm.c (allocate_dynrelocs): Ensure undef weak sym in pie
+ is dynamic.
+ * elf32-hppa.c (allocate_dynrelocs): Likewise.
+ * elf32-i386.c (allocate_dynrelocs): Likewise.
+ * elf32-s390.c (allocate_dynrelocs): Likewise.
+ * elf32-sh.c (allocate_dynrelocs): Likewise.
+ * elf64-s390.c (allocate_dynrelocs): Likewise.
+ * elf64-x86-64.c (allocate_dynrelocs): Likewise.
+ * elf32-m32r.c (allocate_dynrelocs): Likewise. Discard relocs
+ on undef weak with non-default visibility too.
+ * elfxx-sparc.c (allocate_dynrelocs): Ditto.
+
+2006-02-21 Alan Modra <amodra@bigpond.net.au>
+
+ * bfd.c: (_bfd_default_error_handler): Don't call abort on
+ error, instead call _exit.
+ (_bfd_abort): Call _exit not xexit.
+
+2006-02-17 Kevin Buettner <kevinb@redhat.com>
+
+ * elf32-frv.c (elf32_frv_grok_prstatus, elf32_frv_grok_psinfo):
+ New functions.
+ * elf_backend_grok_prstatus, elf_backend_grok_psinfo): Define.
+
+2006-02-17 Shrirang Khisti <shrirangk@kpitcummins.com>
+ Anil Paranjape <anilp1@kpitcummins.com>
+ Shilin Shakti <shilins@kpitcummins.com>
+
+ * Makefile.am: Add xc16x related entry
+ * Makefile.in: Regenerate
+ * archures.c: Add bfd_xc16x_arch
+ * bfd-in2.h: Regenerate
+ * config.bfd: Add xc16x-*-elf
+ * configure.in: Add bfd_elf32_xc16x_vec
+ * configure: Regenerate.
+ * targets.c: Added xc16x related information
+ * cpu-xc16x.c: New file
+ * reloc.c: Add new relocations specific to xc16x:
+ BFD_RELOC_XC16X_PAG, BFD_RELOC_XC16X_POF, BFD_RELOC_XC16X_SEG,
+ BFD_RELOC_XC16X_SOF
+ * elf32-xc16x.c: New file.
+
+2006-02-17 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-ppc.c (allocate_dynrelocs): Tweak undef weak handling.
+ * elf64-ppc.c (allocate_dynrelocs): Likewise.
+
+2006-02-17 Alan Modra <amodra@bigpond.net.au>
+
+ PR ld/2218
+ * elf64-ppc.c (allocate_dynrelocs): Ensure undef weak sym is
+ dynamic.
+ (ppc64_elf_relocate_section): Check output reloc section size.
+ * elf32-ppc.c (allocate_dynrelocs): Simplify undef weak test.
+
+2006-02-16 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/2322
+ * elf.c (get_segment_type): New function.
+ (_bfd_elf_print_private_bfd_data): Use it.
+ (print_segment_map): New function.
+ (assign_file_positions_for_segments): Call print_segment_map
+ when there are not enough room for program headers.
+
+2006-02-16 Nick Hudson <nick.hudson@dsl.pipex.com>
+
+ * config.bfd (mips*el-*-netbsd*, mips*-*-netbsd*): Use
+ traditional MIPS ELF targets.
+
+2006-02-15 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR binutils/2338
+ * dwarf2.c (check_function_name): New function.
+ (_bfd_dwarf2_find_nearest_line): Use check_function_name to
+ check if function is correct.
+
+2006-02-16 Alan Modra <amodra@bigpond.net.au>
+
+ * elflink.c (_bfd_elf_default_action_discarded): Return 0 for
+ debug sections.
+ (elf_link_input_bfd): Adjust comments.
+
+2006-02-10 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf.c (copy_private_bfd_data): Minor update.
+
+2006-02-10 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR binutils/2258
+ * elf.c (copy_private_bfd_data): Renamed to ...
+ (rewrite_elf_program_header): This.
+ (copy_elf_program_header): New function.
+ (copy_private_bfd_data): Likewise.
+
+2006-02-07 Nathan Sidwell <nathan@codesourcery.com>
+
+ * archures.c (bfd_mach_mcf5200, bfd_mach_mcf5206e,
+ bfd_mach_mcf5307, bfd_mach_mcf5407, bfd_mach_mcf528x,
+ bfd_mach_mcfv4e, bfd_mach_mcf521x, bfd_mach_mcf5249,
+ bfd_mach_mcf547x, bfd_mach_mcf548x): Remove.
+ (bfd_mach_mcf_isa_a, bfd_mach_mcf_isa_a_div,
+ bfd_mach_mcf_isa_a_div_mac, bfd_mach_mcf_isa_a_div_emac,
+ bfd_mach_mcf_isa_aplus, bfd_mach_mcf_isa_aplus_mac,
+ bfd_mach_mcf_isa_aplus_emac, bfd_mach_mcf_isa_aplus_usp,
+ bfd_mach_mcf_isa_aplus_usp_mac, bfd_mach_mcf_isa_aplus_usp_emac,
+ bfd_mach_mcf_isa_b, bfd_mach_mcf_isa_b_mac, bfd_mach_mcf_isa_b_emac,
+ bfd_mach_mcf_isa_b_usp_float, bfd_mach_mcf_isa_b_usp_float_mac,
+ bfd_mach_mcf_isa_b_usp_float_emac): New.
+ (bfd_default_scan): Update coldfire mapping.
+ * bfd-in.h (bfd_m68k_mach_to_features,
+ bfd_m68k_features_to_mach): Declare.
+ * bfd-in2.h: Rebuilt.
+ * cpu-m68k.c (arch_info_struct): Add new coldfire machines,
+ adjust legacy names.
+ (m68k_arch_features): New.
+ (bfd_m68k_mach_to_features,
+ bfd_m68k_features_to_mach): Define.
+ * elf32-m68k.c (elf32_m68k_object_p): New.
+ (elf32_m68k_merge_private_bfd_data): Merge the CF EF flags.
+ (elf32_m68k_print_private_bfd_data): Print the CF EF flags.
+ (elf_backend_object_p): Define.
+ * ieee.c (ieee_write_processor): Update coldfire machines.
+ * libbfd.h: Rebuilt.
+
+2006-02-06 Steve Ellcey <sje@cup.hp.com>
+
+ * elfxx-ia64.c (elfNN_ia64_fake_sections): Set SHF_IA_64_HP_TLS
+ if SHF_TLS is set.
+
+2006-02-05 Arnold Metselaar <arnold.metselaar@planet.nl>
+
+ * coff-z80.c (r_imm24): New howto.
+ (rtype2howto): New case R_IMM24.
+ (coff_z80_reloc_type_lookup): New case BFD_RELOC_24.
+ (extra_case): Use bfd_get_8 for R_IMM8, new case R_IMM24.
+
+2006-02-04 Richard Sandiford <richard@codesourcery.com>
+
+ * elfxx-mips.c (mips_elf_initialize_tls_index): If a TLS symbol
+ has already been assigned a GOT index, copy that index to the
+ current hash table entry.
+
+2006-02-01 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ * elfxx-sparc.c (_bfd_sparc_elf_relocate_section): Reinstate bypass
+ for call-to-undefweak reloc overflow.
+
+2006-01-31 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ * elfxx-sparc.c (_bfd_sparc_elf_relocate_section): Reinstate bypass
+ for 32-bit relocs overflow.
+
+2006-01-27 Paul Brook <paul@codesourcery.com>
+
+ * elf32-arm.c (elf32_arm_get_symbol_type): Allow STT_TLS thumb
+ objects.
+
+2006-01-18 Alexandre Oliva <aoliva@redhat.com>
+
+ Introduce TLS descriptors for i386 and x86_64.
+ * reloc.c (BFD_RELOC_386_TLS_GOTDESC, BFD_RELOC_386_TLS_DESC,
+ BFD_RELOC_386_TLS_DESC_CALL, BFD_RELOC_X86_64_GOTPC32_TLSDESC,
+ BFD_RELOC_X86_64_TLSDESC, BFD_RELOC_X86_64_TLSDESC_CALL): New.
+ * libbfd.h, bfd-in2.h: Rebuilt.
+ * elf32-i386.c (elf_howto_table): New relocations.
+ (R_386_tls): Adjust.
+ (elf_i386_reloc_type_lookup): Map new relocations.
+ (GOT_TLS_GDESC, GOT_TLS_GD_BOTH_P): New macros.
+ (GOT_TLS_GD_P, GOT_TLS_GDESC_P, GOT_TLS_GD_ANY_P): New macros.
+ (struct elf_i386_link_hash_entry): Add tlsdesc_got field.
+ (struct elf_i386_obj_tdata): Add local_tlsdesc_gotent field.
+ (elf_i386_local_tlsdesc_gotent): New macro.
+ (struct elf_i386_link_hash_table): Add sgotplt_jump_table_size.
+ (elf_i386_compute_jump_table_size): New macro.
+ (link_hash_newfunc): Initialize tlsdesc_got.
+ (elf_i386_link_hash_table_create): Set sgotplt_jump_table_size.
+ (elf_i386_tls_transition): Handle R_386_TLS_GOTDESC and
+ R_386_TLS_DESC_CALL.
+ (elf_i386_check_relocs): Likewise. Allocate space for
+ local_tlsdesc_gotent.
+ (elf_i386_gc_sweep_hook): Handle R_386_TLS_GOTDESC and
+ R_386_TLS_DESC_CALL.
+ (allocate_dynrelocs): Count function PLT relocations. Reserve
+ space for TLS descriptors and relocations.
+ (elf_i386_size_dynamic_sections): Reserve space for TLS
+ descriptors and relocations. Set up sgotplt_jump_table_size.
+ Don't zero reloc_count in srelplt.
+ (elf_i386_always_size_sections): New. Set up _TLS_MODULE_BASE_.
+ (elf_i386_relocate_section): Handle R_386_TLS_GOTDESC and
+ R_386_TLS_DESC_CALL.
+ (elf_i386_finish_dynamic_symbol): Use GOT_TLS_GD_ANY_P.
+ (elf_backend_always_size_sections): Define.
+ * elf64-x86-64.c (x86_64_elf_howto): Add R_X86_64_GOTPC32_TLSDESC,
+ R_X86_64_TLSDESC, R_X86_64_TLSDESC_CALL.
+ (R_X86_64_standard): Adjust.
+ (x86_64_reloc_map): Map new relocs.
+ (elf64_x86_64_rtype_to_howto): New, split out of...
+ (elf64_x86_64_info_to_howto): ... this function, and...
+ (elf64_x86_64_reloc_type_lookup): ... use it to map elf_reloc_val.
+ (GOT_TLS_GDESC, GOT_TLS_GD_BOTH_P): New macros.
+ (GOT_TLS_GD_P, GOT_TLS_GDESC_P, GOT_TLS_GD_ANY_P): New macros.
+ (struct elf64_x86_64_link_hash_entry): Add tlsdesc_got field.
+ (struct elf64_x86_64_obj_tdata): Add local_tlsdesc_gotent field.
+ (elf64_x86_64_local_tlsdesc_gotent): New macro.
+ (struct elf64_x86_64_link_hash_table): Add tlsdesc_plt,
+ tlsdesc_got and sgotplt_jump_table_size fields.
+ (elf64_x86_64_compute_jump_table_size): New macro.
+ (link_hash_newfunc): Initialize tlsdesc_got.
+ (elf64_x86_64_link_hash_table_create): Initialize new fields.
+ (elf64_x86_64_tls_transition): Handle R_X86_64_GOTPC32_TLSDESC and
+ R_X86_64_TLSDESC_CALL.
+ (elf64_x86_64_check_relocs): Likewise. Allocate space for
+ local_tlsdesc_gotent.
+ (elf64_x86_64_gc_sweep_hook): Handle R_X86_64_GOTPC32_TLSDESC and
+ R_X86_64_TLSDESC_CALL.
+ (allocate_dynrelocs): Count function PLT relocations. Reserve
+ space for TLS descriptors and relocations.
+ (elf64_x86_64_size_dynamic_sections): Reserve space for TLS
+ descriptors and relocations. Set up sgotplt_jump_table_size,
+ tlsdesc_plt and tlsdesc_got. Make room for them. Don't zero
+ reloc_count in srelplt. Add dynamic entries for DT_TLSDESC_PLT
+ and DT_TLSDESC_GOT.
+ (elf64_x86_64_always_size_sections): New. Set up
+ _TLS_MODULE_BASE_.
+ (elf64_x86_64_relocate_section): Handle R_386_TLS_GOTDESC and
+ R_386_TLS_DESC_CALL.
+ (elf64_x86_64_finish_dynamic_symbol): Use GOT_TLS_GD_ANY_P.
+ (elf64_x86_64_finish_dynamic_sections): Set DT_TLSDESC_PLT and
+ DT_TLSDESC_GOT. Set up TLS descriptor lazy resolver PLT entry.
+ (elf_backend_always_size_sections): Define.
+
+2006-01-17 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR binutils/2096
+ * dwarf2.c (comp_unit_contains_address): Update comment.
+ (_bfd_dwarf2_find_nearest_line): Use section's vma, instead of
+ lma. Return TRUE only if both comp_unit_contains_address and
+ comp_unit_find_nearest_line return TRUE.
+ (_bfd_dwarf2_find_line): Use section's vma, instead of lma.
+
+2006-01-18 Alan Modra <amodra@bigpond.net.au>
+
+ * elf-bfd.h (struct elf_backend_data): Add gc_mark_dynamic_ref.
+ (bfd_elf_gc_mark_dynamic_ref_symbol): Declare.
+ * elflink.c (bfd_elf_gc_mark_dynamic_ref_symbol): Rename from
+ elf_gc_mark_dynamic_ref_symbol. Make global.
+ (bfd_elf_gc_sections): Call bed->gc_mark_dynamic_ref.
+ * elfxx-target.h (elf_backend_gc_mark_dynamic_ref): Define.
+ (elfNN_bed): Init new field.
+ * elf64-ppc.c (elf_backend_gc_mark_dynamic_ref): Define.
+ (ppc64_elf_gc_mark_dynamic_ref): New function.
+
+2006-01-17 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (ppc64_elf_gc_mark_hook): Don't hang forever in loop.
+
+2006-01-17 Nick Clifton <nickc@redhat.com>
+
+ PR binutils/2159
+ * elf.c (elfcore_write_pstatus): Add ATTRIBUTE_UNUSED to unused
+ parameters.
+
+2006-01-11 Nick Clifton <nickc@redhat.com>
+
+ * elf32-arm.c (elf32_arm_output_symbol_hook): Install new entry
+ into the newly (re)allocated map array.
+
+2006-01-09 Alexis Wilke <alexis_wilke@yahoo.com>
+
+ * peXXigen.c (tbl): Add comma after "HIGH3ADJ".
+
+2006-01-01 Jakub Jelinek <jakub@redhat.com>
+
+ * elf64-ppc.c (ppc64_elf_action_discarded): Return 0
+ for .toc1 section.
+
+For older changes see ChangeLog-2005
+
+Copyright (C) 2006 Free Software Foundation, Inc.
+
+Copying and distribution of this file, with or without modification,
+are permitted in any medium without royalty provided the copyright
+notice and this notice are preserved.
+
+Local Variables:
+mode: change-log
+left-margin: 8
+fill-column: 74
+version-control: never
+End:
diff --git a/bfd/ChangeLog-2007 b/bfd/ChangeLog-2007
new file mode 100644
index 0000000..85076b9
--- /dev/null
+++ b/bfd/ChangeLog-2007
@@ -0,0 +1,3567 @@
+2007-12-31 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/5530
+ * elfxx-ia64.c (elfNN_ia64_relocate_section): Call
+ _bfd_elf_find_segment_containing_section with output_bfd,
+ instead of input_bfd.
+
+2007-12-31 Nick Clifton <nickc@redhat.com>
+
+ * elf-m10300.c (mn10300_elf_relax_section): Use
+ _bfd_merged_section_offset to compute the offset of a symbol in a
+ merged section.
+
+2007-12-31 Nick Clifton <nickc@redhat.com>
+
+ * elf.c (_bfd_elf_find_segment_containing_section): New function:
+ Scan the segment map looking for the segment containing a
+ specified function.
+ * elf-bfd.h: Prototype the new function.
+ * elf-hppa.h (elf_hppa_osec_to_segment): Delete.
+ (elf_hppa_record_segment_addrs): Use new function.
+ * elf32-bfin.c (_bfdfdpic_osec_to_segment): Use new function.
+ * elf32-frv.c (_frvfdpic_osec_to_segment): Use new function.
+ * elf32-hppa.c (hppa_record_segment_addr): Use new function.
+ * elfxx-ia64.c (elfNN_ia64_relocate_section): Use new function.
+
+2007-12-28 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ PR binutils/5146
+ * elf64-hppa.c: Declare alloca when __GNUC__ is defined.
+ * som.c: Likewise.
+
+ * elf-hppa.h (elf_hppa_osec_to_segment): New function.
+ (elf_hppa_record_segment_addrs): Use elf_hppa_osec_to_segment.
+ Remove ATTRIBUTE_UNUSED from abfd argument.
+ * elf32-hppa.c (hppa_record_segment_addr): Likewise.
+
+2007-12-28 Nick Hudson <nick.hudson@dsl.pipex.com>
+
+ * elf32-hppa.c (hppa_record_segment_addr): Locate the segment
+ containing the section using the segment map, rather than guessing
+ based upon the section's vma and file position.
+
+2007-12-24 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR binutils/5488
+ * elf.c (IS_NOTE): New.
+ (IS_COREFILE_NOTE): Use IS_NOTE.
+ (IS_SECTION_IN_INPUT_SEGMENT): Use IS_NOTE instead of
+ IS_COREFILE_NOTE.
+
+2007-12-24 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR binutils/5449
+ * elf.c (rewrite_elf_program_header): Don't adjust p_paddr if
+ p_paddr is set to 0.
+ (copy_private_bfd_data): Call rewrite_elf_program_header if
+ p_paddr is set to 0.
+
+ * elfcode.h (elf_swap_phdr_out): Set p_paddr to 0 if needed.
+
+ * elfxx-ia64.c (ELF_MAXPAGESIZE): Don't redefine it for HPUX.
+
+2007-12-21 Bob Wilson <bob.wilson@acm.org>
+
+ * elf32-xtensa.c (relax_section): Update DIFF relocations in the
+ same way as other relocations.
+
+2007-12-18 Daniel Jacobowitz <dan@codesourcery.com>
+
+ * section.c (BFD_FAKE_SECTION): Update.
+ * bfd-in2.h: Regenerate.
+
+2007-12-18 Daniel Jacobowitz <dan@codesourcery.com>
+
+ * bfd-in2.h: Regenerate.
+
+2007-12-17 Pedro Alves <pedro_alves@portugalmail.pt>
+
+ * config.bfd: Add arm-*-mingw32ce* target.
+
+2007-12-15 Richard Sandiford <rsandifo@nildram.co.uk>
+
+ * elf-bfd.h (eh_cie_fde): Replace u.cie.merged with a union of
+ a merged field and a sec field.
+ (eh_frame_hdr_info): Remove offsets_adjusted.
+ * elf-eh-frame.c (_bfd_elf_parse_eh_frame): Update accesses to
+ the CIE merged field.
+ (_bfd_elf_gc_mark_fdes): Likewise.
+ (_bfd_elf_discard_section_eh_frame): Likewise. Set u.cie.u.sec
+ when clearing the removed flag.
+ (_bfd_elf_eh_frame_section_offset): Remove offsets_adjusted handling.
+ (_bfd_elf_write_section_eh_frame): Likewise. Apply output_offsets
+ where appropriate.
+
+2007-12-15 Richard Sandiford <rsandifo@nildram.co.uk>
+
+ * elf-bfd.h (eh_cie_fde): Move add_fde_encoding and
+ per_encoding_relative to u.cie. Add commentary.
+ * elf-eh-frame.c (cie): Remove make_relative.
+ (extra_augmentation_string_bytes): Update use of add_fde_encoding.
+ (extra_augmentation_data_bytes): Likewise. Use an FDE's own
+ add_augmentation_size field, rather than referring to the CIE.
+ (_bfd_elf_parse_eh_frame): Don't set the struct cie
+ make_relative field; set the eh_cie_fde field directly.
+ Update setting of add_fde_encoding and per_encoding_relative.
+ Copy make_relative and add_augmentation_size from the CIE
+ to the FDE.
+ (_bfd_elf_discard_section_eh_frame): Use the FDE's own
+ make_relative field.
+ (_bfd_elf_eh_frame_section_offset): Likewise.
+ (_bfd_elf_write_section_eh_frame): Update accesses to
+ add_fde_encoding and per_encoding_relative. Use the FDE's
+ own make_relative and add_augmentation_size fields.
+
+2007-12-15 Richard Sandiford <rsandifo@nildram.co.uk>
+
+ * elf-bfd.h (eh_cie_fde): Remove need_lsda_relative.
+ Move make_lsda_relative to u.cie.
+ * elf-eh-frame.c (cie): Rename make_lsda_relative to
+ can_make_lsda_relative.
+ (_bfd_elf_parse_eh_frame): Don't set the old eh_cie_fde
+ make_lsda_relative field. Update after cie renaming.
+ Set u.cie.make_lsda_relative if can_make_lsda_relative
+ and if we find a relocation against the LSDA.
+ (_bfd_elf_discard_section_eh_frame): Copy make_lsda_relative when
+ changing a CIE's group representative.
+ (_bfd_elf_eh_frame_section_offset): Don't set need_ldsa_relative here.
+ (_bfd_elf_write_section_eh_frame): Check u.cie.make_lsda_relative
+ rather than need_lsda_relative.
+
+2007-12-15 Richard Sandiford <rsandifo@nildram.co.uk>
+
+ * elf-bfd.h (eh_cie_fde): Add u.fde.next_for_section and
+ u.cie.gc_mark.
+ (bfd_elf_section_data): Add fde_list.
+ (elf_fde_list): New macro.
+ (elf_obj_tdata): Add eh_frame_section.
+ (elf_eh_frame_section): New macro.
+ (_bfd_elf_gc_mark_reloc): Remove last parameter.
+ (_bfd_elf_gc_mark_fdes): Declare.
+ * elf-eh-frame.c (_bfd_elf_get_eh_frame_sec_info): Chain the FDEs
+ for each input section.
+ (mark_entry, _bfd_elf_gc_mark_fdes): New functions.
+ * elflink.c (_bfd_elf_gc_mark_reloc): Remove is_eh parameter.
+ (_bfd_elf_gc_mark): Update call accordingly. Mark the relocations
+ againts the section's FDEs. Don't mark the bfd's elf_eh_frame_section.
+ (bfd_elf_gc_sections): Parse each input bfd's .eh_frame before
+ marking any input sections. Remove the current EH handling.
+ * section.c (bfd_section): Remove gc_mark_from_eh.
+ * ecoff.c (bfd_debug_section): Update initializer accordingly.
+
+2007-12-15 Richard Sandiford <rsandifo@nildram.co.uk>
+
+ * elf-bfd.h (eh_cie_fde): Add u.cie. Document how u.fde.cie_inf
+ changes when removed == 0.
+ (eh_frame_hdr_info): Add parsed_eh_frames.
+ (_bfd_elf_begin_eh_frame_parsing): Declare.
+ (_bfd_elf_parse_eh_frame): Declare.
+ (_bfd_elf_end_eh_frame_parsing): Declare.
+ * elf-eh-frame.c (_bfd_elf_begin_eh_frame_parsing): New function.
+ (_bfd_elf_parse_eh_frame): New function, split out from
+ _bfd_elf_discard_section_eh_frame. Make a first pass through the
+ buffer to calculate the number of entries and CIEs. Allocate memory
+ for them before the main loop. Replace current extended cie
+ representation with a pair of pointers, one to the local eh_cie_fde
+ and one to the full struct cie. Allocate a separate array of struct
+ cies if not merging. Merge CIEs during the main loop and set up each
+ u.cie.merged field. Point an FDE's cie_inf field directly at the
+ local CIE. Initially assume that all entries should be removed.
+ (_bfd_elf_end_eh_frame_parsing): New function.
+ (_bfd_elf_discard_section_eh_frame): Assume that the section has
+ already been parsed. Use a separate pass to mark entries that
+ need to be kept. Use the u.cie.merged field to track a CIE's
+ group representative.
+ * elflink.c (bfd_elf_discard_info): Call _bfd_elf_parse_eh_frame
+ before _bfd_elf_discard_section_eh_frame. Wrap loop with calls to
+ _bfd_elf_begin_eh_frame_parsing and _bfd_elf_end_eh_frame_parsing.
+
+2007-12-15 Richard Sandiford <rsandifo@nildram.co.uk>
+
+ * elf-bfd.h (eh_cie_fde): Put cie_inf in a union. Add a reloc_index
+ field. Use bitfields for fde_encoding, lsda_encoding and lsda_offset.
+ * elf-eh-frame.c (extra_augmentation_data_bytes): Adjust cie_inf
+ accesses after the above change.
+ (_bfd_elf_eh_frame_section_offset): Likewise.
+ (_bfd_elf_write_section_eh_frame): Likewise.
+ (_bfd_elf_discard_section_eh_frame): Likewise. Set up reloc_index.
+
+2007-12-15 Richard Sandiford <rsandifo@nildram.co.uk>
+
+ * elf-bfd.h (_bfd_elf_gc_mark_rsec, _bfd_elf_gc_mark_reloc): Declare.
+ (_bfd_elf_gc_mark): Use elf_gc_mark_hook_fn.
+ * elflink.c (init_reloc_cookie, fini_reloc_cookie)
+ (init_reloc_cookie_rels, fini_reloc_cookie_rels): New functions,
+ split out from...
+ (bfd_elf_discard_info): ...here.
+ (init_reloc_cookie_for_section): New function.
+ (fini_reloc_cookie_for_section): Likewise.
+ (_bfd_elf_gc_mark_rsec, _bfd_elf_gc_mark_reloc): New functions,
+ split out from...
+ (_bfd_elf_gc_mark): ...here. Use init_reloc_cookie_for_section
+ and fini_reloc_cookie_for_section.
+
+2007-12-12 Bob Wilson <bob.wilson@acm.org>
+
+ * elf32-xtensa.c (elf_xtensa_do_reloc): Update self_address along with
+ address.
+ (print_action_list): Fix name for ta_convert_longcall.
+
+2007-12-11 Catherine Moore <clm@codesourcery.com>
+
+ * elf.c (_bfd_elf_copy_private_symbol_data): Don't copy shndx if
+ the symbol's section is the undefined section.
+
+2007-12-11 Alan Modra <amodra@bigpond.net.au>
+
+ * elf.c (elf_fake_sections): Add "warning:" to "..changed to PROGBITS"
+ message.
+
+2007-12-07 Bob Wilson <bob.wilson@acm.org>
+
+ * elf32-xtensa.c (elf_howto_table): Add R_XTENSA_32_PCREL.
+ (elf_xtensa_reloc_type_lookup): Handle BFD_RELOC_32_PCREL.
+ (elf_xtensa_check_relocs): Use default case for all relocations that
+ need nothing done here.
+ (elf_xtensa_do_reloc): Compute self_address for all relocation types.
+ Handle R_XTENSA_32_PCREL.
+ (elf_xtensa_relocate_section): Check for R_XTENSA_32_PCREL for dynamic
+ symbols.
+ (check_section_ebb_pcrels_fit): Ignore R_XTENSA_32_PCREL relocations.
+
+2007-12-05 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-spu.c (spu_elf_size_stubs): Do consider branches to
+ non-function symbols for overlay stubs.
+
+2007-12-04 Bob Wilson <bob.wilson@acm.org>
+
+ * elf32-xtensa.c (elf_xtensa_size_dynamic_sections): Create DT_PLTGOT
+ entry for all dynamic objects.
+
+2007-12-04 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-spu.c (spu_elf_size_stubs): Correct section alignment.
+
+2007-11-30 Richard Sandiford <rsandifo@nildram.co.uk>
+
+ * elf-eh-frame.c (_bfd_elf_discard_section_eh_frame): Use the
+ ELF header to choose between 32-bit and 64-bit relocation structures.
+
+2007-11-29 Mark Shinwell <shinwell@codesourcery.com>
+
+ * archures.c (bfd_mach_mips_loongson_2e): New.
+ (bfd_mach_mips_loongson_2f): New.
+ * bfd-in2.h (bfd_mach_mips_loongson_2e): New.
+ (bfd_mach_mips_loongson_2f): New.
+ * cpu-mips.c: Add I_loongson_2e and I_loongson_2f to
+ anonymous enum.
+ (arch_info_struct): Add Loongson-2E and Loongson-2F entries.
+ * elfxx-mips.c (_bfd_elf_mips_mach): Handle Loongson-2E
+ and Loongson-2F flags.
+ (mips_set_isa_flags): Likewise.
+ (mips_mach_extensions): Add Loongson-2E and Loongson-2F
+ entries.
+
+2007-11-29 Nick Clifton <nickc@redhat.com>
+
+ PR ld/5398
+ * elf32-arm.c (bfd_elf32_arm_process_before_allocation): Do not
+ complain if there is no glue bfd, just return.
+
+2007-11-28 Nick Clifton <nickc@redhat.com>
+
+ * elf-m10300.c (mn10300_elf_relax_section): Extend previous fix to
+ cover forward jumps.
+
+2007-11-21 Nick Clifton <nickc@redhat.com>
+
+ * elf-m10300.c (mn10300_elf_relax_section): Allow for alignment
+ relocs when computing whether instructions can be relaxed.
+
+2007-11-16 Tristan Gingold <gingold@adacore.com>
+
+ * elflink.c (elf_link_output_extsym): Weaken assertion: if
+ --gc-section is set, there may be no TLS segment.
+
+2007-11-19 Alan Modra <amodra@bigpond.net.au>
+
+ * elf-bfd.h (bfd_elf_perform_complex_relocation): Update prototype.
+ * elflink.c (bfd_elf_perform_complex_relocation): Return status.
+ Don't print reloc overflow message.
+ * elf32-mep.c (mep_elf_relocate_section): Handle status from
+ bfd_elf_perform_complex_relocation.
+
+2007-11-17 Thiemo Seufer <ths@mips.com>
+
+ * elfxx-mips.c (mips_elf_merge_obj_attributes): Handle -mips32r2
+ -mfp64 attribute.
+
+2007-11-16 Nick Clifton <nickc@redhat.com>
+
+ * elf-m10300.c (mn10300_elf_check_relocs): Fix memory leak and
+ check that bfd_elf_get_elf_syms is only called once.
+
+2007-11-16 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * elf64-ppc.c (ppc64_elf_get_synthetic_symtab): Set udata.p of
+ synthetic symbol to point to the ELF symbol it was derived from.
+
+2007-11-15 Alan Modra <amodra@bigpond.net.au>
+
+ PR 5328
+ * opncls.c (separate_debug_file_exists): Use fopen/fread
+ rather than open/read and open in binary mode.
+
+2007-11-14 Richard Sandiford <richard@codesourcery.com>
+
+ * elfxx-mips.c (mips_got_page_range): New structure.
+ (mips_got_page_entry): Likewise.
+ (mips_got_info): Add page_gotno and got_page_entries fields.
+ (mips_elf_got_per_bfd_arg): Add max_pages field. Delete
+ primary_count and current_count fields.
+ (mips_got_page_entry_hash, mips_got_page_entry_eq): New functions.
+ (mips_elf_pages_for_range, mips_elf_record_got_page_entry): Likewise.
+ (mips_elf_get_got_for_bfd): New function, split out from
+ mips_elf_make_got_per_bfd. Initialize the page_gotno and
+ got_page_entries fields when creating a new GOT structure.
+ (mips_elf_make_got_pages_per_bfd): New function.
+ (mips_elf_merge_got_with): New function, split out from
+ mips_elf_make_got_per_bfd. Merge page entries as well as
+ non-page entries. Use the minimum of max_pages and the sum
+ of the page_gotnos to estimate the number of page entries.
+ (mips_elf_merge_gots): Use the minimum of max_pages and the
+ bfd's page_gotno to estimate the number of page entries.
+ Use the above functions.
+ (mips_elf_multi_got): Add page entries as well as non-page entries
+ to the individual per-bfd GOTs. Initialize got_per_bfd_arg.max_pages.
+ Initialize the page_gotno and got_page_entries fields when creating
+ a new primary GOT. Use the minimum of pages and page_gotno when
+ adding the number of pages entries to local_gotno.
+ (mips_elf_create_got_section): Initialize the page_gotno and
+ got_page_entries fields of the GOT structure.
+ (mips_elf_rel_relocation_p, mips_elf_read_rel_addend)
+ (mips_elf_add_lo16_rel_addend, mips_elf_get_section_contents): New
+ functions, split out from...
+ (_bfd_mips_elf_relocate_section): ...here.
+ (_bfd_mips_elf_check_relocs): Record GOT page entries too.
+ (_bfd_mips_relax_section): Use mips_elf_get_section_contents.
+ (_bfd_mips_elf_always_size_sections): Use the smaller of the
+ loadable_size- and page_gotno-derived estimates.
+
+2007-11-14 Thiemo Seufer <ths@mips.com>
+
+ * elfxx-mips.c (mips_elf_merge_obj_attributes): Prevent
+ unwanted fallthroughs in case statement.
+
+2007-11-13 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR binutils/5307
+ * peXXigen.c (_bfd_XX_bfd_copy_private_bfd_data_common): Don't
+ copy input subsystem if output is different from input.
+
+2007-11-13 Nick Clifton <nickc@redhat.com>
+
+ * elf-m10300.c (mn10300_elf_final_link_relocate): Prevent the
+ accidental termination of DWARF location list entries.
+ (mn10300_elf_relax_delete_bytes): Stop deletion if an align reloc
+ is encountered that is larger than or not a mutliple of the number
+ of bytes being deleted.
+ When adjusting symbols, any symbols inside the region being
+ deleted must be moved to the end of the region.
+ Move align relocs forward if there is room for them after the
+ deletion of the region.
+
+2007-11-13 Alan Modra <amodra@bigpond.net.au>
+
+ PR 5233
+ * elf.c (rewrite_elf_program_header): Formatting. Add
+ first_matching_lma and first_suggested_lma booleans and use
+ instead of testing matching_lma and suggested_lma for zero.
+
+2007-11-12 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR binutils/5299
+ * peicode.h (pe_bfd_object_p): Save and restore previous bfd
+ state when calling coff_object_p.
+
+2007-11-12 Alan Modra <amodra@bigpond.net.au>
+
+ * elf.c (_bfd_elf_get_synthetic_symtab): Only bump the symbol
+ pointer when we have a valid symbol. Init udata.p to NULL.
+
+2007-11-09 Nathan Sidwell <nathan@codesourcery.com>
+
+ * elf-vxworks.c (elf_vxworks_emit_relocs): Don't clobber
+ rel_hash. Move loop inside if test.
+
+2007-11-08 Nathan Sidwell <nathan@codesourcery.com>
+
+ * elf-vxworks.h (elf_vxworks_add_dynamic_entries): Declare.
+ (elf_vxworks_finish_dynamic_entry): Declare.
+ * elf-vxworks.c: Include elf/vxworks.h.
+ (elf_vxworks_add_dynamic_entries): New.
+ (elf_vxworks_finish_dynamic_entry): New.
+ * Makefile.am (elf-vxworks.lo): Add dependency.
+ * Makefile.in (elf-vxworks.lo): Add dependency.
+ * elf32-i386.c (elf_i386_size_dynamic_sections,
+ elf_i386_finish_dynamic_sections): Call
+ elf_vxworks_add_dynamic_entries and
+ elf_vxworks_finish_dynamic_entry.
+ * elf32-ppc.c (ppc_elf_size_dynamic_sections,
+ ppc_elf_finish_dynamic_sections): Likewise.
+ * elfxx-sparc.c (_bfd_sparc_elf_size_dynamic_sections,
+ sparc_finish_dyn): Likewise.
+ * elf32-sh.c (sh_elf_size_dynamic_sections,
+ sh_elf_finish_dynamic_sections): Likewise.
+ * elfxx-mips.c (_bfd_mips_elf_size_dynamic_sections,
+ _bfd_mips_elf_finish_dynamic_sections): Likewise.
+ * elf32-arm.c (elf32_arm_size_dynamic_sections,
+ elf32_arm_finish_dynamic_sections): Likewise.
+
+2007-11-07 Olivier Hainque <hainque@adacore.com>
+
+ * bfd/elfxx-mips.c (_bfd_mips_elf_fake_sections): Force
+ SHF_MIPS_NOSTRIP on .debug_frame for Irix.
+
+2007-11-06 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (ppc64_elf_check_relocs): Don't refcount tlsld_got here..
+ (ppc64_elf_gc_sweep_hook): ..or here..
+ (ppc64_elf_tls_optimize): ..or here. Make two passes through the
+ relocs, ensuring that tls_get_addr calls follow gd and ld relocs.
+ (allocate_dynrelocs): Refcount tlsld_got here.
+ (ppc64_elf_size_dynamic_sections): Allocate local got and call
+ allocate_dynrelocs before allocating tlsld_got.
+ (ppc64_elf_relocate_section): Remove check that a tls_get_addr
+ call follows gd and ld relocs.
+
+ * elf32-ppc.c (ppc_elf_check_relocs): Don't refcount tlsld_got here..
+ (ppc_elf_gc_sweep_hook): ..or here..
+ (ppc_elf_tls_optimize): ..or here. Make two passes through the
+ relocs, ensuring that tls_get_addr calls follow gd and ld relocs.
+ (allocate_dynrelocs): Refcount tlsld_got here.
+ (ppc_elf_size_dynamic_sections): Call allocate_dynrelocs before
+ allocating tlsld_got.
+ (ppc_elf_relocate_section): Remove check that a tls_get_addr
+ call follows gd and ld relocs.
+
+2007-11-05 Alan Modra <amodra@bigpond.net.au>
+
+ * merge.c (sec_merge_hash_lookup): Revert last change.
+ (record_section): Likewise.
+ (_bfd_merge_sections): Likewise.
+ (_bfd_merged_section_offset): Properly handle NULL secinfo.
+ (_bfd_add_merge_section): Allocate extra space for a zero
+ terminator on SEC_STRINGS sections.
+
+2007-11-05 Danny Smith <dannysmith@users.sourceforge.net>
+
+ * pe-i386.c (COFF_SECTION_ALIGNMENT_ENTRIES): Let .data, .text
+ and .bss section use the default.
+ * pei-i386.c (COFF_SECTION_ALIGNMENT_ENTRIES): Likewise.
+
+2007-11-01 Joseph Myers <joseph@codesourcery.com>
+
+ * merge.c (sec_merge_hash_lookup): Add parameter sec_end. Check
+ for unterminated strings. All callers changed.
+ (record_section): Add parameter abfd. Give error message for
+ unterminated strings.
+ (_bfd_merge_sections): Update call to record_section.
+ (_bfd_write_merged_section, _bfd_merged_section_offset): Handle
+ NULL secinfo from merge failures.
+
+2007-10-31 Nick Clifton <nickc@redhat.com>
+
+ * elf-m10300.c (mn10300_elf_relax_delete_bytes): Do not look for
+ align relocs when there are no relocs attached to the section.
+
+2007-10-31 Alan Modra <amodra@bigpond.net.au>
+
+ * elf-bfd.h (bfd_elf_match_symbols_in_sections): Don't declare.
+ * elflink.c (bfd_elf_match_symbols_in_sections): Make static.
+ Remove section name comparisons.
+
+2007-10-30 Nick Clifton <nickc@redhat.com>
+
+ * reloc.c (BFD_RELOC_MN10300_ALIGN): Add.
+ * bfd-in2.h: Regenerate.
+ * libbfd.h: Regnerate.
+ * elf-m10300.h: Handle R_MN10300_ALIGN relocs.
+ (mn10300_elf_relax_delete_bytes): Honour R_MN10300_ALIGN relocs.
+ Re-fix off by one error in comparisons.
+
+2007-10-25 Pedro Alves <pedro_alves@portugalmail.pt>
+
+ * bfd-in.h (STRING_COMMA_LEN): Don't handle NULL STR case.
+ * bfd-in2.h: Regenerate.
+
+2007-10-25 Daniel Jacobowitz <dan@codesourcery.com>
+
+ * elf32-ppc.c (ppc_elf_merge_obj_attributes): Add support for
+ Tag_GNU_Power_ABI_Vector.
+
+2007-10-25 Joseph Myers <joseph@codesourcery.com>
+
+ * elfxx-mips.c (_bfd_mips_elf_modify_segment_map): Do not add
+ PT_NULL header when not linking.
+
+2007-10-25 Carlos Eduardo Seo <cseo@linux.vnet.ibm.com>
+
+ * elf.c (elfcore_grok_ppc_vmx): New function.
+ (elfcore_grok_note): Handle NT_PPC_VMX.
+ (elfcore_write_ppc_vmx): New function.
+ * elf-bfd.h (elfcore_write_ppc_vmx): Declare.
+
+2007-10-24 Alan Modra <amodra@bigpond.net.au>
+
+ * Makefile.am: Run "make dep-am".
+ * Makefile.in: Regenerate.
+ * po/SRC-POTFILES.in: Regenerate.
+
+2007-10-23 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (ppc_build_one_stub): Don't duplicate relocs
+ emitted for ".brlt" entries.
+ (toc_adjusting_stub_needed): Don't treat ".fixup" specially here..
+ (ppc64_elf_next_input_section): ..instead do so here.
+
+2007-10-19 Nick Clifton <nickc@redhat.com>
+
+ * config.bfd: Recognise am34-linux-gnu target.
+ * reloc.c: Add BFD_RELOC_MN10300_SYM_DIFF relocation.
+ * bfd-in2.h: Regenerate.
+ * libbfd.h: Regenerate.
+ * elf-m10300.c (elf_mn10300_howto): Add R_MN10300_SYM_DIFF.
+ (mn10300_reloc_map): Likewise.
+ (mn10300_elf_check_relocs): Do not create dynamic relocs for
+ symbol differences or relocations against absolute symbols.
+ (mn10300_elf_final_link_relocate): Likewise.
+ Handle R_MN10300_SYM_DIFF relocs.
+ (mn10300_elf_relocate_section): Fix for creating local copys of
+ dynamic relocs.
+ (mn10300_elf_relax_delete_bytes): Adjust symbols at the end of the
+ region. Adjust the size of function symbols.
+ (mn10300_elf_relax_section): Ignore symbols that are in discarded
+ sections.
+
+2007-10-19 Nick Clifton <nickc@redhat.com>
+
+ * elf-m10300.c: Convert to ISO C.
+
+2007-10-18 H.J. Lu <hongjiu.lu@intel.com>
+ Alan Modra <amodra@bigpond.net.au>
+
+ PR ld/4424
+ * config.bfd (targ_selvecs): Add bfd_elf64_alpha_vec for
+ alpha/FreeBSD. Add bfd_elf64_sparc_vec for sparc64/FreeBSD.
+ Add bfd_elf32_i386_vec and bfd_efi_app_ia32_vec for i386/FreeBSD.
+ (targ64_selvecs): Set for i386/FreeBSD.
+ * elf-bfd.h (elf_backend_data): Add relocs_compatible.
+ (_bfd_elf_default_relocs_compatible): Declare.
+ (_bfd_elf_relocs_compatible): Declare.
+ * elfxx-target.h (elf_backend_relocs_compatible): Define.
+ (elfNN_bed): Init new relocs_compatible field.
+ * elflink.c (_bfd_elf_default_relocs_compatible): New function.
+ (_bfd_elf_relocs_compatible): New function.
+ (elf_link_add_object_symbols): Call bed->relocs_compatible.
+ * elf32-i386.c (elf_backend_relocs_compatible): Define.
+ * elf64-alpha.c: Likewise.
+ * elf64-sparc.c: Likewise.
+ * elf64-x86-64.c: Likewise.
+
+2007-10-16 Bob Wilson <bob.wilson@acm.org>
+
+ * elf32-xtensa.c (relax_section): Check for a reference to a discarded
+ DWARF section and anticipate its replacement with the kept section.
+
+2007-10-16 Bob Wilson <bob.wilson@acm.org>
+
+ * elf32-xtensa.c (elf_xtensa_discard_info_for_section): Remove
+ unnecessary size variables. Set sec->rawsize.
+ (relax_section, relax_property_section): Likewise.
+
+2007-10-16 Bob Wilson <bob.wilson@acm.org>
+
+ * section.c (struct bfd_section): Clarify comment for rawsize field.
+ * bfd-in2.h: Regenerate.
+
+2007-10-16 Bob Wilson <bob.wilson@acm.org>
+
+ * elflink.c (_bfd_elf_check_kept_section): Use the section rawsize
+ values if they are set.
+
+2007-10-16 Nick Clifton <nickc@redhat.com>
+
+ PR 5146
+ * configure.in (AC_CHECK_HEADERS): Add alloca.h
+ * configure: Regenerate.
+ * config.in: Regenerate.
+ * som.c: Replace alloca-conf.h inclusion with code recommended in
+ autoconf documentation.
+ * elf64-hppa.c: Likewise.
+
+2007-10-16 Nick Clifton <nickc@redhat.com>
+
+ * configure.in (--enable-elf-stt-common): New configure
+ option. If enabled then the tools can generate symbols with
+ the ELF STT_COMMON type.
+ * config.in: Regenerate.
+ * configure: Regenerate.
+ * elf.c (swap_out_syms): If USE_STT_COMMON is defined then set
+ the type of emitted common symbols to STT_COMMON.
+ * elfcode.h (elf_slurp_symbol_table): Accept STT_COMMON symbol
+ types.
+
+2007-10-15 Alan Modra <amodra@bigpond.net.au>
+
+ * coff-arm.c (arm_emit_base_file_entry): Check fwrite return value.
+ Return status. Adjust callers.
+ * coff-mcore.c (mcore_emit_base_file_entry): Likewise.
+ * coff-ppc.c (write_base_file_entry): New function.
+ (coff_ppc_relocate_section): Use it.
+ * elf32-arm.c (find_thumb_glue): Check asprintf return status.
+ (find_arm_glue): Likewise.
+ * vms-misc.c (_bfd_vms_output_flush): Check fwrite return value.
+
+2007-10-12 Nick Clifton <nickc@redhat.com>
+
+ PR 5160
+ * elflink.c (eval_symbol): Remove bufsz variable and use
+ sizeof(symbuf) where necessary.
+
+2007-10-12 M R Swami Reddy <MR.Swami.Reddy@nsc.com>
+
+ * elf32-cr16.c (elf32_cr16_relax_section): Fix condition check typo.
+
+2007-10-12 Daniel Jacobowitz <dan@codesourcery.com>
+
+ * elfxx-mips.c (mips_elf_sort_hash_table_f): Handle forced
+ local symbols specially.
+ (mips_elf_set_global_got_offset): Skip forced local symbols.
+
+2007-10-12 Alan Modra <amodra@bigpond.net.au>
+
+ * elf.c (elfcore_grok_prxfpreg): Fix comment typo.
+
+2007-10-10 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf.c (get_program_header_size): Always add a PT_GNU_RELRO
+ segment for -z relro.
+ (_bfd_elf_map_sections_to_segments): Make a PT_GNU_RELRO
+ segment only when needed.
+
+2007-10-05 Bob Wilson <bob.wilson@acm.org>
+
+ * elf32-xtensa.c (relax_section): Call pin_internal_relocs when
+ changing a relocation's offset. Adjust call to translate_reloc. Do
+ not add a fix record for a DIFF reloc. For other relocs, only add a
+ fix record if the translated target is in a different object file;
+ otherwise, just update the relocation. Call pin_internal_relocs when
+ updating a reloc but not when adding a fix record.
+ (translate_reloc): Get the target section from a new argument, not
+ from the relocation. Change check for relaxable sections to an
+ assertion. Compute separate offset adjustments for the base symbol
+ and the addend, and set the new relocation's addend correctly. Return
+ the new target section.
+
+2007-10-05 Bob Wilson <bob.wilson@acm.org>
+
+ * elf32-xtensa.c (elf_xtensa_relocate_section): Remove updates of
+ r_type and howto after calling do_fix_for_relocateable_link and
+ do_fix_for_final_link.
+
+2007-10-05 Bob Wilson <bob.wilson@acm.org>
+
+ * elf32-xtensa.c (removed_by_actions): New.
+ (offset_with_removed_text): Reimplement using removed_by_actions.
+ (offset_with_removed_text_before_fill): Delete.
+ (relax_property_section): Use removed_by_actions. Rearrange logic.
+ (relax_section_symbols): Likewise.
+
+2007-10-04 Bob Wilson <bob.wilson@acm.org>
+
+ * elf32-xtensa.c (reloc_bfd_fix_struct): Delete target_abfd field.
+ (reloc_bfd_fix_init): Remove target_abfd argument.
+ (relax_section, move_literal): Adjust calls to reloc_bfd_fix_init.
+
+2007-10-04 Nick Clifton <nickc@redhat.com>
+
+ PR linker/5099
+ * elf64-x86-64.c (elf64_x86_64_check_relocs): Add missing
+ apostrophe to error message.
+
+2007-10-01 M R Swami Reddy <MR.Swami.Reddy@nsc.com>
+
+ * elf32-cr16.c: Fixed DISP8, DISP20 and IMM20 relocations at
+ final relocation phase.
+ Added the below relaxations: IMM32 -> IMM20/IM16 -> IMM4.
+ * reloc.c: Added 3 new relocations: R_CR16_SWITCH8,
+ R_CR16_SWITCH16, R_CR16_SWITCH32.
+ * libbfd.h: Regenerate.
+ * bfd-in2.h: Regenerate.
+
+2007-09-30 Alan Modra <amodra@bigpond.net.au>
+
+ * elflink.c: Formatting.
+
+2007-09-29 Alan Modra <amodra@bigpond.net.au>
+
+ * elflink.c (resolve_symbol): Handle symbols in SEC_MERGE
+ sections. Don't test symbol st_shndx. Don't bother with
+ bfd_link_hash_common symbols. Print longs rather than ints
+ in debug messages.
+ (eval_symbol): Replace "sym" and "advanced" params with "symp".
+ Replace "addr" and "section_offset" params with "dot". Don't
+ cast bfd_vma values to signed, cast them to bfd_signed_vma.
+ (bfd_elf_perform_complex_relocation): Delete "output_bfd", "info",
+ "local_syms" and "local_sections" params. Add "relocation".
+ Delete code calculating relocation value.
+ (evaluate_complex_relocation_symbols): Delete function. Fold into..
+ (elf_link_input_bfd): ..existing code examining relocs.
+ * elf-bfd.h (bfd_elf_perform_complex_relocation): Update prototype.
+ * elf32-mep.c (mep_elf_check_relocs): Delete function.
+ (mep_elf_gc_sweep_hook, mep_elf_gc_mark_hook): Likewise.
+ (mep_elf_object_p): Don't set elf_bad_symtab.
+ (elf_backend_check_relocs): Don't define.
+ (elf_backend_gc_mark_hook, elf_backend_gc_sweep_hook): Likewise.
+ (elf_backend_can_gc_sections, USE_RELA): Likwise.
+ (mep_elf_relocate_section): Move bfd_elf_perform_complex_relocation
+ call after we have calculated reloc value. Delete local sym
+ debug code. Use RELOC_FOR_GLOBAL_SYMBOL. Delete addend
+ adjusting code..
+ (elf_backend_rela_normal): ..instead define this.
+
+2007-09-28 Alan Modra <amodra@bigpond.net.au>
+
+ * elf-m10300.c (mn10300_elf_check_relocs): Delete dead code.
+ * elf32-arm.c (elf32_arm_check_relocs): Likewise.
+ * elf32-avr.c (elf32_avr_check_relocs): Likewise.
+ * elf32-bfin.c (bfinfdpic_check_relocs): Likewise.
+ * elf32-cris.c (cris_elf_check_relocs): Likewise.
+ * elf32-d10v.c (elf32_d10v_check_relocs): Likewise.
+ * elf32-dlx.c (elf32_dlx_check_relocs): Likewise.
+ * elf32-fr30.c (fr30_elf_check_relocs): Likewise.
+ * elf32-frv.c (_frvfdpic_check_discarded_relocs): Likewise.
+ (elf32_frv_check_relocs): Likewise.
+ * elf32-iq2000.c (iq2000_elf_check_relocs): Likewise.
+ * elf32-m32c.c (m32c_elf_check_relocs): Likewise.
+ * elf32-m32r.c (m32r_elf_check_relocs): Likewise.
+ * elf32-m68hc1x.c (elf32_m68hc11_check_relocs): Likewise.
+ * elf32-mcore.c (mcore_elf_check_relocs): Likewise.
+ * elf32-msp430.c (elf32_msp430_check_relocs): Likewise.
+ * elf32-mt.c (mt_elf_check_relocs): Likewise.
+ * elf32-openrisc.c (openrisc_elf_check_relocs): Likewise.
+ * elf32-sh.c (sh_elf_check_relocs): Likewise.
+ * elf64-mmix.c (mmix_elf_check_relocs): Likewise.
+ * elf64-sh64.c (sh_elf64_check_relocs): Likewise.
+ * elf32-score.c (_bfd_score_elf_check_relocs): Likewise.
+ (score_elf_local_relocation_p): Likewise.
+ (_bfd_score_elf_relocate_section): Likewise.
+ (score_elf_final_link_relocate): Likewise.
+
+2007-09-26 Jan Beulich <jbeulich@novell.com>
+
+ * elf32-i386.c (elf_i386_check_relocs): Revert NULL pointer
+ check for R_386_GNU_VTINHERIT.
+ * elf-m10300.c (mn10300_elf_check_relocs): Check for NULL
+ pointer for R_xxx_GNU_VTENTRY.
+ * elf32-arm.c (elf32_arm_check_relocs): Likewise.
+ * elf32-bfin.c (bfin_check_relocs): Likewise.
+ (bfinfdpic_check_relocs): Likewise.
+ * elf32-cris.c (cris_elf_check_relocs): Likewise.
+ * elf32-d10v.c (elf32_d10v_check_relocs): Likewise.
+ * elf32-dlx.c (elf32_dlx_check_relocs): Likewise.
+ * elf32-fr30.c (fr30_elf_check_relocs): Likewise.
+ * elf32-frv.c (elf32_frv_check_relocs): Likewise.
+ * elf32-hppa.c (elf32_hppa_check_relocs): Likewise.
+ * elf32-iq2000.c (iq2000_elf_check_relocs): Likewise.
+ * elf32-m32r.c (m32r_elf_check_relocs): Likewise.
+ * elf32-m68hc1x.c (elf32_m68hc11_check_relocs): Likewise.
+ * elf32-m68k.c (elf_m68k_check_relocs): Likewise.
+ * elf32-mcore.c (mcore_elf_check_relocs): Likewise.
+ * elf32-openrisc.c (openrisc_elf_check_relocs): Likewise.
+ * elf32-ppc.c (ppc_elf_check_relocs): Likewise.
+ * elf32-s390.c (elf_s390_check_relocs): Likewise.
+ * elf32-score.c (_bfd_score_elf_check_relocs): Likewise.
+ * elf32-sh.c (sh_elf_check_relocs): Likewise.
+ * elf32-v850.c (v850_elf_check_relocs): Likewise.
+ * elf32-vax.c (elf_vax_check_relocs): Likewise.
+ * elf32-xstormy16.c (xstormy16_elf_check_relocs): Likewise.
+ * elf32-xtensa.c (elf_xtensa_check_relocs): Likewise.
+ * elf64-mmix.c (mmix_elf_check_relocs): Likewise.
+ * elf64-ppc.c (ppc64_elf_check_relocs): Likewise.
+ * elf64-s390.c (elf_s390_check_relocs): Likewise.
+ * elf64-sh64.c (sh_elf64_check_relocs): Likewise.
+ * elf64-x86-64.c (elf64_x86_64_check_relocs): Likewise.
+ * elfxx-mips.c (_bfd_mips_elf_check_relocs): Likewise.
+ * elfxx-sparc.c (_bfd_sparc_elf_check_relocs): Likewise.
+
+2007-09-26 Alan Modra <amodra@bigpond.net.au>
+
+ * elflink.c (set_symbol_value): Add isymbuf and locsymcount
+ params. Change symidx to a size_t. Don't access past end
+ of symbol buffer.
+ (resolve_symbol): Add isymbuf param and use instead of
+ finfo->internal_syms.
+ (eval_symbol, evaluate_complex_relocation_symbols): Likewise.
+ (elf_link_input_bfd): Don't read symbols specially for
+ evaluate_complex_relocation_symbols.
+
+2007-09-26 Tristan Gingold <gingold@adacore.com>
+
+ * som.c (som_get_reloc_upper_bound): If there are no relocs return
+ enough space to hold a NULL pointer.
+
+2007-09-26 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (ppc_build_one_stub): Correct rel_hdr.sh_size.
+
+2007-09-25 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-spu.c (struct spu_link_hash_table): Add ovly_load_r_symndx.
+ (spu_elf_size_stubs): Count stub relocs.
+ (write_one_stub): Emit relocs on overlay call stubs.
+
+ * elf32-spu.c (struct spu_link_hash_table): Add "stubs".
+ (spu_elf_link_hash_table_create): Init new field.
+ (spu_elf_size_stubs): Store sorted stub syms in new htab field
+ rather than local var.
+ (spu_elf_build_stubs): Iterate over htab stubs rather than
+ hash traversal.
+ (struct stubarr): Delete.
+ (allocate_spuear_stubs, populate_stubs, write_one_stub): Adjust.
+
+2007-09-24 Daniel Jacobowitz <dan@codesourcery.com>
+
+ * elf.c (assign_file_positions_for_load_sections): Trust
+ p_align_valid.
+ (copy_elf_program_header): Copy PT_NULL segments.
+
+2007-09-24 Trevor Smigiel <Trevor_Smigiel@playstation.sony.com>
+
+ * elf32-spu.c (is_indirect_branch): New function.
+ (find_function_stack_adjust): End scan on hitting indirect branch.
+ (sum_stack): Cast %v arg to correct type.
+
+2007-09-21 H.J. Lu <hongjiu.lu@intel.com>
+
+ * Makefile.am: Run "make dep-am".
+ * Makefile.in: Regenerated.
+
+2007-09-21 Doug Kwan <dougkwan@google.com>
+
+ * Makefile.am (BFD32_LIBS): Add arange-set.lo.
+ (BFD32_LIBS_CFILES): Add arange-set.c.
+ (SOURCE_HFILES): Add arange-set.h
+ (dwarf2.lo): Add dependency upon arange-set.h.
+ (arange-set.lo): New target.
+ * Makefile.in: Regenerate.
+ * arange-set.c: New file.
+ * arange-set.h: New file.
+ * dwarf2.c: Include arange-set.h.
+ (struct dwarf2_debug) Add new fields comp_unit_count and
+ comp_unit_arange_set.
+ (struct comp_unit) Replace field arange with a new field arange_set.
+ (dwarf2_arange_set_allocate, dwarf2_arange_set_deallocate,
+ dwarf2_combine_arange_value, dwarf2_arange_set_new,
+ dwarf2_arange_set_with_value_new, dwarf2_comp_unit_arange_add): New
+ functions to utilize arange set in dwarf2.c.
+ (arange_add): Formatting change for a line longer than 80 characters.
+ (decode_line_info): Replace call target arange_add with
+ dwarf2_comp_unit_arange_add.
+ (read_rangelist_insert_arange_list,
+ read_rangelist_comp_unit_arange_add): New functions used as callbacks
+ for read_rangelist.
+ (read_rangelist): Change interface to accept a callback and data to
+ allow caller to select the action peformed on a new range list read.
+ (scan_unit_for_symbols): Use new interface of read_rangelist.
+ (parse_comp_unit): Create an arange set for each new comp unit.
+ Use new interface of read_rangelist. Replace call to arange_add
+ with that to dwarf2_comp_unit_arange_add.
+ (comp_unit_contains_address): Replace sequential search with a call to
+ arange_set_lookup_address, which can handles large set efficiently.
+ (stash_copy_local_aranges, stash_maybe_enable_arange_set,
+ stash_find_nearest_line_fast): New functions maintaining and using a
+ valued global arange set for all compilation units to speed up
+ bfd_dwarf2_find_nearest_line.
+ (find_line): Use global arange set. Replace sequential search over all
+ compilation units with a call to stash_find_nearest_line_fast. Add
+ book keeping to count number of compilation units. Replace empty
+ arange list test with a call to arange_set_empty_p.
+
+2007-09-21 Olivier Hainque <hainque@adacore.com>
+ Tristan Gingold <gingold@adacore.com>
+
+ * syms.c (_bfd_stab_section_find_nearest_line): Look at the
+ specific SOM sections for stabs if the regular ones are not found.
+ * som.h (struct somdata): Add a line_info field, to be used by
+ som_find_nearest_line.
+ * som.c (som_find_nearest_line): Implement using the bfd stabs
+ function above.
+
+2007-09-19 Daniel Jacobowitz <dan@codesourcery.com>
+
+ * elfxx-mips.c (_bfd_mips_elf_finish_dynamic_sections): Make sure .got
+ will be output.
+
+2007-09-19 Alan Modra <amodra@bigpond.net.au>
+ Doug Kwan <dougkwan@google.com>
+
+ * bfd-in.h (bfd_hash_insert): Declare.
+ * bfd-in2.h: Regenerate.
+ * hash.c (bfd_hash_insert): New function. Split out from..
+ (bfd_hash_lookup): ..here.
+ * merge.c (sec_merge_hash_lookup): Use bfd_hash_insert.
+
+2007-09-18 Alan Modra <amodra@bigpond.net.au>
+
+ * elf.c (bfd_section_from_shdr): Check bfd_alloc return.
+ (elfcore_write_note): Check realloc return.
+ * elflink.c (_bfd_elf_link_find_version_dependencies): Check
+ bfd_zalloc return.
+ (_bfd_elf_link_assign_sym_version): Check bfd_malloc return.
+ (elf_link_add_object_symbols): Likewise.
+ (struct hash_codes_info): New.
+ (elf_collect_hash_codes): Return bfd_malloc error.
+ (struct collect_gnu_hash_codes): Add "error".
+ (elf_collect_gnu_hash_codes): Return bfd_malloc error.
+ (bfd_elf_size_dynamic_sections): Check return status of
+ _bfd_elf_link_find_version_dependencies.
+ (bfd_elf_size_dynsym_hash_dynstr): Adjust for elf_collect_hash_codes
+ and elf_collect_gnu_hash_codes changes.
+ (elf_sym_name_compare): Formatting.
+ (elf_fixup_link_order): Use bfd_malloc, not xmalloc.
+
+2007-09-17 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR binutils/3281
+ PR binutils/5037
+ * elf-bfd.h (elf_obj_tdata): Remove relro.
+
+ * elf.c (get_program_header_size): Check info->relro instead
+ of elf_tdata (abfd)->relro.
+ (_bfd_elf_map_sections_to_segments): Likewise.
+ (assign_file_positions_for_load_sections): Don't set
+ PT_GNU_RELRO segment alignment here.
+ (assign_file_positions_for_non_load_sections): Properly set up
+ PT_GNU_RELRO segment for copying executable/shared library.
+ (rewrite_elf_program_header): Remove PT_GNU_RELRO segment.
+ (copy_elf_program_header): Set p_size and p_size_valid fields for
+ PT_GNU_RELRO segment.
+
+2007-09-17 Nick Clifton <nickc@redhat.com>
+
+ * po/fi.po: New Finnish translation.
+ * po/es.po: Updated Spanish translation.
+ * configure.in (ALL_LINGUAS): Add fi.
+ * configure: Regenerate.
+ * po/bfd.pot: Regenerate.
+
+2007-09-15 Nick Clifton <nickc@redhat.com>
+
+ * bfd.c (_bfd_default_error_handler): fflush stdout.
+
+2007-09-14 Alan Modra <amodra@bigpond.net.au>
+
+ * opncls.c (find_separate_debug_file): Ensure bfd_set_error has
+ been called on all error return paths.
+ (bfd_fill_in_gnu_debuglink_section): Use bfd_malloc, not malloc.
+ Clear padding after filename
+
+2007-09-14 Alan Modra <amodra@bigpond.net.au>
+
+ * format.c (bfd_check_format_matches): Record matching targets even
+ when "matching" is NULL to allow bfd_associated_vector matches.
+ Consolidate error return code. Consolidate ok return code. Always
+ restore original target and format on error.
+
+2007-09-14 Alan Modra <amodra@bigpond.net.au>
+
+ * configure.in: Delete BFD_HOST_LONG_LONG and bfd checks for
+ long long. Partly revert 2007-07-12 change, so that
+ BFD_HOST_64BIT_LONG and BFD_HOST_64BIT_LONG_LONG are set
+ independent of "void *" size.
+ * configure: Regenerate.
+ * config.in: Regenerate.
+ * Makefile.in: Regenerate.
+
+2007-09-12 Alan Modra <amodra@bigpond.net.au>
+
+ * elf-bfd.h (struct elf_backend_data): Delete elf_backend_sprintf_vma
+ and elf_backend_fprintf_vma.
+ (_bfd_elf_sprintf_vma, _bfd_elf_fprintf_vma): Delete.
+ * elf.c (_bfd_elf_sprintf_vma, _bfd_elf_fprintf_vma): Delete.
+ * elfxx-target.h (elf_backend_sprintf_vma): Don't define.
+ (elf_backend_fprintf_vma): Likewise.
+ (elfNN_bed): Don't init removed fields.
+ * bfd.c (is32bit): New function.
+ (bfd_sprintf_vma, bfd_fprintf_vma): Use the above.
+
+2007-09-11 Nathan Sidwell <nathan@codesourcery.com>
+
+ * archures.c: Add bfd_mach_mcf_isa_c_nodiv,
+ bfd_mach_mcf_isa_c_nodiv_mac & bfd_mach_mcf_isa_c_nodiv_emac.
+ * ieee.c (ieee_write_processor): Update coldfire architecture
+ list.
+ * bfd-in2.h: Rebuilt.
+ * cpu-m68k.c (arch_info_struct): Add isa_c nodiv architectures.
+ (m68k_arch_features): Likewise.
+ * elf32-m68k.c (elf32_m68k_object_p): Add EF_M68K_CF_ISA_C_NODIV.
+ (elf32_m68k_print_private_bfd_data): Likewise.
+
+2007-09-11 Jan Beulich <jbeulich@novell.com>
+
+ * elf64-i386.c (elf64_i386_tls_transition): Remove redundant 'const'.
+ * elf64-x86_64.c (elf64_x86_64_tls_transition): Likewise.
+
+2007-09-08 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (func_desc_adjust): When resolving undefined
+ references to dot-symbols, transfer def_regular and
+ def_dynamic from the descriptor symbol.
+
+2007-09-08 Alan Modra <amodra@bigpond.net.au>
+
+ * config.bfd: Set want64 for spu-*-elf.
+
+2007-09-08 Alan Modra <amodra@bigpond.net.au>
+
+ PR ld/2864, ld/5006
+ * elf.c (special_sections): Comment typo.
+ (elf_fake_sections): Force SHT_PROGBITS for sections that are
+ SHT_NOBITS if BFD section flags say they have contents.
+
+2007-09-04 Michael Snyder <msnyder@access-company.com>
+
+ * elf32-bfin.c (howto_table): Cut and paste error?
+ Name field of reloc is wrong.
+
+2007-09-04 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-spu.c (elf_howto_table): Formatting.
+
+2007-09-02 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/4986
+ * dwarf2.c (new_line_sorts_after): Undo the last change.
+ (add_line_info): Only keep the last entry with the same address
+ and end sequence.
+
+2007-08-31 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/4986
+ * dwarf2.c (new_line_sorts_after): Also compare line number.
+
+2007-08-31 Jesse Michael <jmichael@suse.de>
+
+ * mach-o.c (bfd_mach_o_make_bfd_section): Fix test for non
+ zerofill sections.
+
+2007-08-28 David Heine <dlheine@tensilica.com>
+
+ * elf32-xtensa.c (compute_ebb_actions): Update removed_bytes when
+ narrowing instructions.
+
+2007-08-28 Mark Shinwell <shinwell@codesourcery.com>
+ Joseph Myers <joseph@codesourcery.com>
+
+ * elf32-arm.c (elf32_arm_compare_mapping): Compare first on vma,
+ then on type.
+
+2007-08-28 Robert Sebastian Gerus <arachnist@gmail.com>
+
+ * config.bfd: Add support for i[3-7]86-*-dragonfly*.
+ * configure.in: Likewise.
+ * configure: Regenerate.
+
+2007-08-25 Ulrich Weigand <uweigand@de.ibm.com>
+ Alan Modra <amodra@bigpond.net.au>
+
+ * elf.c (elfcore_grok_spu_note): New function.
+ (elf_parse_notes): Call it.
+
+2007-08-24 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf64-x86-64.c (elf64_x86_64_relocate_section): Adjust
+ indentation.
+
+2007-08-24 Pedro Alves <pedro_alves@portugalmail.pt>
+
+ * elf.c (elfcore_grok_win32pstatus): Remove HAVE_WIN32_PSTATUS_T
+ guard. Make it host independent.
+ (elfcore_grok_note): Remove HAVE_WIN32_PSTATUS_T guard around
+ NT_WIN32PSTATUS.
+
+2007-08-24 Jan Kratochvil <jan.kratochvil@redhat.com>
+
+ * elf-bfd.h (struct elf_obj_tdata): New BUILD_ID_SIZE, BUILD_ID.
+ * elf.c (elfcore_read_notes): Split to ...
+ (elf_read_notes) ... here ...
+ (elf_parse_notes): ... and here. Check `bfd_get_format (abfd)' with
+ the former subfunctions called only for BFD_CORE.
+ Call ELFOBJ_GROK_GNU_NOTE for BFD_OBJECT files with the owner "GNU".
+ (_bfd_elf_make_section_from_shdr): Call ELF_PARSE_NOTES for SHT_NOTEs.
+ (bfd_section_from_phdr): Update the call for renamed ELFCORE_READ_NOTES.
+ (elfobj_grok_gnu_build_id, elfobj_grok_gnu_note): New functions.
+ Code advisory: Roland McGrath
+
+2007-08-24 Daniel Jacobowitz <dan@codesourcery.com>
+
+ * elf64-mips.c (elf_backend_sign_extend_vma): Define.
+
+2007-08-24 Alan Modra <amodra@bigpond.net.au>
+
+ * elfxx-ia64.c (elfNN_ia64_add_symbol_hook): Warning fix.
+
+2007-08-23 H.J. Lu <hongjiu.lu@intel.com>
+
+ * Makefile.am: Run "make dep-am".
+ * Makefile.in: Regenerated.
+
+2007-08-23 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf32-i386.c: Include "bfd_stdint.h".
+ (elf_i386_rtype_to_howto): New function.
+ (elf_i386_info_to_howto_rel): Use it.
+ (x86_64_opcode16): New union type.
+ (elf_i386_check_tls_transition): New function.
+ (elf_i386_tls_transition): Updated to check transition and
+ issue an error if a transition isn't supported.
+ (elf_i386_check_relocs): Return FALSE if
+ elf_i386_tls_transition returns FALSE.
+ (elf_i386_gc_sweep_hook): Likewise.
+ (elf_i386_relocate_section): Likewise. Remove BFD_ASSERT
+ on TLS transitions.
+
+ * elf64-x86-64.c: Include "bfd_stdint.h".
+ (x86_64_opcode16): New union type.
+ (x86_64_opcode32): Likewise.
+ (elf64_x86_64_check_tls_transition): New function.
+ (elf64_x86_64_tls_transition): Updated to check transition and
+ issue an error if a transition isn't supported.
+ (elf64_x86_64_check_relocs): Return FALSE if
+ elf64_x86_64_tls_transition returns FALSE.
+ (elf64_x86_64_gc_sweep_hook): Likewise.
+ (elf64_x86_64_relocate_section): Likewise. Remove BFD_ASSERT
+ on TLS transitions.
+
+2007-08-22 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elfxx-ia64.c: Convert to ISO C90 prototypes.
+ (elfNN_hpux_backend_section_from_bfd_section): Make it static.
+
+2007-08-22 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf64-x86-64.c: Remove trailing whitespace.
+ * elfxx-ia64.c: Likewise.
+
+2007-08-21 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf32-i386.c (elf_i386_tls_transition): Accept a pointer
+ to ELF hash entry instead of an integer for local test.
+ (elf_i386_check_relocs): Updated.
+ (elf_i386_gc_sweep_hook): Likewise.
+ (elf_i386_relocate_section): Likewise.
+
+ * elf64-x86-64.c (elf64_x86_64_tls_transition): Accept a
+ pointer to ELF hash entry instead of an integer for local
+ test.
+ (elf64_x86_64_check_relocs): Updated.
+ (elf64_x86_64_gc_sweep_hook): Likewise.
+ (elf64_x86_64_relocate_section): Likewise.
+
+2007-08-20 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf32-i386.c (elf_i386_tls_transition): Break long line.
+ * elf64-x86-64.c (elf64_x86_64_tls_transition): Likewise.
+
+2007-08-20 Jan Kratochvil <jan.kratochvil@redhat.com>
+
+ * elfxx-target.h [ELF_COMMONPAGESIZE && ELF_MAXPAGESIZE]
+ (ELF_MINPAGESIZE): Fixed its size guess. Sanity checked its size.
+ (ELF_COMMONPAGESIZE, ELF_MAXPAGESIZE): Sanity checked their size.
+
+2007-08-20 Nick Clifton <nickc@redhat.com>
+
+ * elflink.c (elf_fixup_link_order): Rewrite conversion of
+ s->alignment_power into an offset mask in order to avoid a gcc
+ error message.
+
+2007-08-17 Jakub Jelinek <jakub@redhat.com>
+
+ * config.bfd: Handle sparcv*-*-linux-* the same as sparc-*-linux-*.
+ Change sparc64-*-linux-* to sparc64*-*-linux-*.
+
+2007-08-17 Alan Modra <amodra@bigpond.net.au>
+
+ * po/Make-in: Add --msgid-bugs-address to xgettext invocation.
+
+2007-08-16 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf.c: Revert last change.
+
+2007-08-16 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf.c (get_segment_type): Change PT_GNU_STACK to PT_GNU_ATTR.
+ (bfd_section_from_phdr): Likewise.
+ (get_program_header_size): Likewise. Add a PT_GNU_ATTR segment
+ if there is an attribute section.
+ (_bfd_elf_map_sections_to_segments): Likewise.
+ (IS_SECTION_IN_INPUT_SEGMENT): Likewise.
+
+2007-08-14 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/4918
+ * elf32-i386.c (elf_i386_relocate_section): Allow R_386_PC32
+ on ___tls_get_addr for GD->LE/LD->LE transitions when not
+ building shared library.
+
+ * elf64-x86-64.c (elf64_x86_64_relocate_section): Allow
+ R_X86_64_PC32 on __tls_get_addr for GD->LE/LD->LE transitions
+ when not building shared library.
+
+2007-08-14 Jan Kratochvil <jan.kratochvil@redhat.com>
+
+ * elfcode.h (NAME(_bfd_elf,bfd_from_remote_memory)): LOADBASE is now
+ initialized only on the first PT_LOAD. New variable LOADBASE_SET.
+ Removed PF_R checking for IA-64 vDSOs as redundant now.
+ Code advisory: Roland McGrath
+
+2007-08-13 Richard Sandiford <richard@codesourcery.com>
+
+ * elfxx-mips.c (mips_elf_link_hash_table): Add computed_got_sizes.
+ (mips_elf_record_global_got_symbol): Increment local_gotno for
+ each forced-local symbol.
+ (_bfd_mips_elf_check_relocs): Pass forced-local call symbols to
+ mips_elf_record_global_got_symbol for VxWorks too.
+ (_bfd_mips_elf_always_size_sections): Set computed_got_sizes
+ to true after computing the GOT size.
+ (_bfd_mips_elf_hide_symbol): Increase local_gotno whenever
+ got.offset == 1. Only adjust global_gotno if computed_got_sizes.
+ For VxWorks, add a local entry when hiding a symbol that needs a
+ plt but has not been marked as needing a global got entry.
+ (_bfd_mips_elf_link_hash_table_create): Set computed_got_sizes to
+ false.
+
+2007-08-12 Daniel Jacobowitz <dan@codesourcery.com>
+
+ * coffgen.c (coff_get_normalized_symtab): Correct cast.
+
+2007-08-13 Alan Modra <amodra@bigpond.net.au>
+
+ * elf.c (elf_modify_segment_map): Add remove_empty_load param.
+ Don't remove empty PT_LOAD header if false.
+ (_bfd_elf_map_sections_to_segments): If user phdrs, pass false
+ to elf_modify_segment_map.
+ (assign_file_positions_for_load_sections): Pass false to
+ elf_modify_segment_map.
+
+2007-08-13 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (ADDI_R12_R12, LD_R11_0R2, LD_R2_0R2): Define.
+ Update stub comments.
+ (build_plt_stub): Build two variants, one without "addis".
+ (ppc_build_one_stub): Build stubs without "addis" if possible.
+ (ppc_size_one_stub): Size new stubs.
+
+2007-08-11 Richard Sandiford <richard@codesourcery.com>
+
+ * config.bfd (sh-*-vxworks): Define targ_underscore to "yes".
+
+2007-08-09 Michael Snyder <msnyder@access-company.com>
+
+ * aoutx.h (aout_get_external_symbols): Return if count is zero.
+
+2007-08-09 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/4909
+ * elf.c (print_segment_map): New function.
+ (assign_file_positions_for_load_sections): Call print_segment_map
+ when a section can't be allocated in segment.
+
+2007-08-09 Jan Kratochvil <jan.kratochvil@redhat.com>
+
+ * opncls.c (bfd_openr_iovec): Fix the OPEN parameter macro expansion.
+
+2007-08-07 Nick Clifton <nickc@redhat.com>
+
+ * po/bfd.pot: Updated template.
+ * po/BLD-POTFILES.in: Regenerate.
+
+2007-08-07 Alan Modra <amodra@bigpond.net.au>
+
+ * elf.c: (_bfd_elf_make_section_from_phdr): Properly handle
+ bss segments.
+
+2007-08-06 Daniel Jacobowitz <dan@codesourcery.com>
+
+ * Makefile.am (BUILD_HFILES): Clean bfd_stdint.h.
+ * Makefile.in: Regenerated.
+
+2007-08-06 Daniel Jacobowitz <dan@codesourcery.com>
+
+ * configure.in: Update version to 2.18.50.
+ * configure: Regenerated.
+
+2007-08-06 Paul Brook <paul@codesourcery.com>
+
+ * elf32-arm.c (elf32_arm_link_hash_entry): Add
+ plt_maybe_thumb_refcount.
+ (elf32_arm_link_hash_newfunc): Set plt_maybe_thumb_refcount.
+ (elf32_arm_copy_indirect_symbol): Ditto.
+ (elf32_arm_adjust_dynamic_symbol): Ditto.
+ (bfd_elf32_arm_process_before_allocation): Handle R_ARM_THM_JUMP24.
+ (arm_add_to_rel): Ditto.
+ (elf32_arm_final_link_relocate): Merge R_ARM_THM_JUMP24 with
+ R_ARM_THM_CALL. Handle R_ARM_THM_JUMP19 against a PLT stub.
+ (elf32_arm_gc_sweep_hook): Call check_use_blx. Update plt counts
+ for R_ARM_THM_JUMP24 and R_ARM_THM_JUMP19.
+ (elf32_arm_check_relocs): Update plt counts for R_ARM_THM_JUMP24
+ and R_ARM_THM_JUMP19.
+ (allocate_dynrelocs): Use plt_maybe_thumb_refcount.
+ (elf32_arm_finish_dynamic_symbol): Ditto.
+ (elf32_arm_output_plt_map): Ditto.
+
+2007-08-06 Daniel Jacobowitz <dan@codesourcery.com>
+
+ * elf.c (rewrite_elf_program_header): Handle sections not sorted
+ by address.
+ (copy_elf_program_header): Likewise.
+
+2007-08-04 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf-bfd.h (xvec_get_elf_backend_data): Add const.
+
+ * elfcode.h (elf_object_p): Use xvec_get_elf_backend_data.
+ * elfcore.h (elf_core_file_p): Likewise.
+
+2007-08-02 H.J. Lu <hongjiu.lu@intel.com>
+
+ * coffcode.h (ALIGN_SET): Removed.
+ (ELIFALIGN_SET): Likewise.
+ (coff_set_alignment_hook): Handle IMAGE_SCN_ALIGN_128BYTES,
+ IMAGE_SCN_ALIGN_256BYTES, IMAGE_SCN_ALIGN_512BYTES,
+ IMAGE_SCN_ALIGN_1024BYTES, IMAGE_SCN_ALIGN_2048BYTES,
+ IMAGE_SCN_ALIGN_4096BYTES and IMAGE_SCN_ALIGN_8192BYTES.
+
+2007-08-01 Michael Snyder <msnyder@access-company.com>
+
+ * vms-tir.c (new_section): Fix cut and paste error.
+
+ * aoutx.h (aout_link_add_symbols): Return if count is zero.
+
+ * elf.c (bfd_elf_print_symbol): Macro dereferences pointer, so
+ pointer must be non-null.
+
+2007-08-01 Tristan Gingold <gingold@adacore.com>
+
+ * coffcode.h (coff_sort_func_alent): New function.
+ (coff_slurp_line_table): Sort line table if not already sorted.
+
+2007-08-01 Jakub Jelinek <jakub@redhat.com>
+
+ * elf.c (_bfd_elf_map_sections_to_segments): Work around buggy
+ GCC 3.4.x warning.
+
+2007-08-01 Alan Modra <amodra@bigpond.net.au>
+
+ * aoutx.h (swap_ext_reloc_in): Set howto to NULL for unknown
+ r_type.
+ (swap_std_reloc_in): Likewise.
+ (aout_link_input_section_std): Likewise. Return with an error
+ on unexpected relocation type.
+ (aout_link_input_section_ext): Likewise.
+
+2007-08-01 Alan Modra <amodra@bigpond.net.au>
+
+ PR4694
+ * aoutx.h (final_link): Write a zero in first word of
+ stringtab if no symbols rather than corrupting last byte
+ of text/data.
+
+2007-07-31 Jakub Jelinek <jakub@redhat.com>
+
+ * elf.c (get_program_header_size): Adjacent loadable .note*
+ sections need just one PT_NOTE segment.
+ (_bfd_elf_map_sections_to_segments): Likewise.
+
+2007-07-30 Michael Snyder <msnyder@access-company.com>
+
+ * coffgen.c (_bfd_coff_read_internal_relocs): Revert change of
+ 2007-07-26. Buffer still in use, can't be freed.
+
+2007-07-27 Michael Snyder <msnyder@access-company.com>
+
+ * cofflink.c (coff_link_add_symbols): Return if count is zero.
+
+ * coff-i386.c (coff_i386_rtype_to_howto): Off by one error.
+
+ * aoutx.h (slurp_symbol_table): Return if count == 0.
+
+ * coffgen.c (_bfd_coff_read_internal_relocs): Return if count is zero.
+
+ * elf32-i386.c (elf_i386_check_relocs): Check for null pointer.
+
+2007-07-27 H.J. Lu <hongjiu.lu@intel.com>
+
+ * config.bfd (x86_64-*-mingw*): Don't include x86_64coff_vec.
+
+2007-07-26 Michael Snyder <msnyder@access-company.com>
+
+ * coff-i386.c (coff_i386_rtype_to_howto): Guard against null.
+
+ * linker.c (bfd_section_already_linked_table_insert): Change
+ return type from void to boolean. Return FALSE on failure.
+ (_bfd_generic_section_already_linked): Test return value of
+ bfd_section_already_linked_table_insert, call fatal on error.
+
+ * elflink.c (_bfd_elf_section_already_linked): Test return value
+ of bfd_section_already_linked_table_insert, call fatal on error.
+
+ * libbfd-in.h (bfd_section_already_linked_table_insert): Update
+ return type to bfd_boolean.
+
+ * libbfd.h: Regenerate.
+
+2007-07-26 Adam Nemet <anemet@caviumnetworks.com>
+
+ * archive.c (do_slurp_bsd_armap, do_slurp_coff_armap,
+ bfd_slurp_armap): Improve function comment.
+
+2007-07-26 Michael Snyder <msnyder@access-company.com>
+
+ * linker.c (already_linked_newfunc): Check for NULL return from
+ bfd_hash_allocate.
+
+ * coffgen.c (fixup_symbol_value): Guard against null;
+ bfd_is_com_section will dereference the section pointer.
+
+ * syms.c (bfd_decode_symclass): Guard against NULL, since
+ bfd_is_com_section dereferences the pointer.
+
+ * srec.c (srec_scan): Check for EOF (critical because return value
+ will be used as array index).
+
+ * coffgen.c (_bfd_coff_read_internal_relocs): If internal_relocs
+ are not to be cached, free the temporary buffer.
+
+ * aoutx.h (slurp_reloc_table): Return TRUE if reloc_size == zero
+ or count == zero.
+
+ * tekhex.c (first_phase): Check return value for null.
+
+ * elf.c (_bfd_elf_get_synthetic_symtab): Remove meaningless
+ pointer increment.
+
+2007-07-26 Alan Modra <amodra@bigpond.net.au>
+
+ * elflink.c (_bfd_elf_fix_symbol_flags): Remove unnecessary
+ check on dynobj. Remove bed shadow.
+
+ * srec.c (srec_get_section_contents): Return immediately on
+ count zero. Check that offset and count are within section.
+ * libbfd.c (_bfd_generic_get_section_contents): Check that
+ offset + count does not overflow.
+
+ * srec.c (srec_canonicalize_symtab): Don't alloc when symcount
+ is zero. Correct return value on error.
+ * mmo.c (mmo_canonicalize_symtab): Likewise.
+ * binary.c (binary_canonicalize_symtab) Correct return on error.
+
+2007-07-26 Thiemo Seufer <ths@mips.com>
+
+ * bfd.c (_bfd_set_gp_value): Use abort instead of BFD_FAIL.
+
+2007-07-26 Alan Modra <amodra@bigpond.net.au>
+
+ * reloc.c (bfd_generic_get_relocated_section_contents): Avoid
+ bfd_canonicalize_reloc call when bfd_get_reloc_upper_bound
+ says there are no relocs.
+
+2007-07-26 Doug Kwan <dougkwan@google.com>
+
+ Speed up bfd_dwarf2_find_line.
+ * dwarf2.c (struct dwarf2_debug): Add new fields to support function
+ and variable info hash tables. Add last_comp_unit, info_hash_count,
+ funcinfo_hash_table, varinfo_hash_table, hash_units_head.
+ (struct comp_unit): Add prev_unit, cached.
+ (struct info_list_node, struct info_hash_entry,
+ struct info_hash_table): New.
+ (info_hash_table_newfunc, create_info_hash_table,
+ insert_info_hash_table, lookup_info_hash_table): New functions
+ implementing function and variable info hash tables.
+ (scan_unit_for_symbols): Add checks to make sure hash tables are
+ consistent with compilation units.
+ (comp_unit_maybe_decode_line_info): New function.
+ (comp_unit_find_line): Use comp_unit_maybe_decode_line_info.
+ (reverse_funcinfo_list, reverse_varinfo_list, comp_unit_hash_info,
+ info_hash_lookup_funcinfo, info_hash_lookup_varinfo,
+ stash_maybe_update_info_hash_table, stash_verify_info_hash_table,
+ stash_maybe_enable_info_hash_tables, stash_find_line_fast): New
+ functions. Make use of info hash tables to speed up
+ bfd_dwarf2_find_line.
+ (find_line): Use hash table for faster lookup if it is turned on.
+ Also add code to maintain bi-directional link in comp units.
+
+2007-07-25 Michael Snyder <msnyder@access-company.com>
+
+ * coffgen.c (_bfd_coff_get_external_symbols): Nothing to be done
+ if size == 0; return and avoid possible null pointer issues.
+
+2007-07-25 Alan Modra <amodra@bigpond.net.au>
+
+ * linker.c (generic_link_add_symbol_list): Warning fix.
+
+2007-07-24 Michael Snyder <msnyder@access-company.com>
+
+ * opncls.c (bfd_make_writable): Check return from bfd_malloc.
+
+ * elflink.c (bfd_elf_final_link): Avoid redundant frees -- return
+ on bfd_malloc error rather than goto error_return.
+
+2007-07-24 Alan Modra <amodra@bigpond.net.au>
+
+ * elflink.c (_bfd_elf_link_just_syms, merge_sections_remove_hook,
+ _bfd_elf_merge_sections, _bfd_elf_link_hash_newfunc,
+ _bfd_elf_link_hash_copy_indirect, _bfd_elf_link_hash_hide_symbol,
+ _bfd_elf_link_hash_table_init, _bfd_elf_link_hash_table_create,
+ bfd_elf_set_dt_needed_name, bfd_elf_get_dyn_lib_class,
+ bfd_elf_set_dyn_lib_class, bfd_elf_get_needed_list,
+ bfd_elf_get_runpath_list, bfd_elf_get_dt_soname,
+ bfd_elf_get_bfd_needed_list, struct elf_symbuf_symbol,
+ struct elf_symbuf_head, struct elf_symbol, elf_sort_elf_symbol,
+ elf_sym_name_compare, elf_create_symbuf,
+ bfd_elf_match_symbols_in_sections,
+ _bfd_elf_match_sections_by_type): Move to here..
+ * elf.c: ..from here.
+
+2007-07-23 Richard Sandiford <richard@codesourcery.com>
+
+ * elflink.c (_bfd_elf_fix_symbol_flags): Only assert the type
+ of weakdef->root.type if weakdef has no regular definition.
+
+2007-07-22 Adam Nemet <anemet@caviumnetworks.com>
+
+ * elfxx-mips.c (struct mips_elf_link_hash_table): Add new field
+ small_data_overflow_reported.
+ (_bfd_mips_elf_link_hash_table_create): Initialize it.
+ (_bfd_mips_elf_relocate_section) <bfd_reloc_overflow>: Report
+ small-data section overflow.
+
+2007-07-19 Doug Kwan <dougkwan@google.com>
+
+ PR binutils/4797
+ * dwarf2.c: (find_line) Do not dereference functionname_ptr if
+ do_line is true.
+
+2007-07-18 Bob Wilson <bob.wilson@acm.org>
+
+ * elf32-xtensa.c (xtensa_callback_required_dependence): Ignore
+ non-ELF sections.
+
+2007-07-18 Bob Wilson <bob.wilson@acm.org>
+
+ * elf32-xtensa.c (elf_xtensa_finish_dynamic_sections): Get section
+ vma and size for dynamic tags from the output sections.
+
+2007-07-18 Alan Modra <amodra@bigpond.net.au>
+
+ * elf-bfd.h (struct sym_sec_cache): Delete "sec". Add "shndx".
+ * elf.c (bfd_section_from_r_symndx): Don't cache bfd section of
+ symbol. Instead cache ELF section index. Remove redundant
+ checks of st_shndx.
+
+2007-07-15 Mike Frysinger <vapier@gentoo.org>
+
+ * trad-core.c (NBPG): If not defined, set to getpagesize().
+
+2007-07-13 Roland McGrath <roland@redhat.com>
+
+ * elf-bfd.h (struct elf_obj_tdata): Revert last change.
+ Add after_write_object_contents, after_write_object_contents_info.
+ * elf.c (_bfd_elf_write_object_contents): Revert last change.
+ Instead, call after_write_object_contents if set.
+
+2007-07-12 Kai Tietz <kai.tietz@onevision.com>
+
+ * bfd-in.h: (BFD_HOST_64BIT_LONG_LONG): New.
+ (BFD_HOSTPTR_T): Host pointer type for casting a
+ pointer to an integer type.
+ (bfd_hostptr_t): The typedef of BFD_HOSTPTR_T.
+ (sprintf_vma, fprintf_vma): Add support for long long prints.
+ * bfd-in2.h: Regenerate.
+ * configure.in: (BFD_HOST_64BIT_LONG_LONG): New.
+ (BFD_HOSTPTR_T): Host pointer type for casting a
+ pointer to an integer type. Default is "unsigned long".
+ (AC_CHECK_SIZEOF(void *)): New.
+ (host64): Set it if the pointer size is 8.
+ * configure: Regenerate.
+ * config.in: Add macro SIZEOF_VOID_P.
+ * coffcode.h: Replace host ptr type assuming "long" with
+ bfd_hostptr_t type.
+ * coffgen.c: Likewise.
+ * elf-eh-frame.c: Likewise.
+ * peicode.h: Likewise.
+
+2007-07-10 H.J. Lu <hongjiu.lu@intel.com>
+
+ * Makefile.in: Regenerated.
+
+2007-07-10 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR binutils/4756
+ * simple.c (bfd_simple_get_relocated_section_content): Don't
+ apply relocation on executable and shared library.
+
+2007-07-10 Nathan Sidwell <nathan@codesourcery.com>
+
+ * elf32-ppc.c (ppc_elf_adjust_dynamic_symbol): Don't eliminate
+ copy relocs on vxworks.
+
+2007-07-10 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-arm.c (elf32_arm_size_info): Init checksum_contents field.
+ * elf64-alpha.c (alpha_elf_size_info): Likewise.
+ * elf64-hppa.c (hppa64_elf_size_info): Likewise.
+ * elf64-mips.c (mips_elf64_size_info): Likewise.
+ * elf64-s390.c (s390_elf64_size_info): Likewise.
+ * elf64-sparc.c (elf64_sparc_size_info): Likewise.
+
+2007-07-09 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elflink.c (bfd_elf_record_link_assignment): Handle indirect
+ symbol.
+ (_bfd_elf_merge_symbol): Properly update normal symbol when
+ overriding the versioned symbol from a dynamic library.
+
+2007-07-09 Roland McGrath <roland@redhat.com>
+
+ * elf-bfd.h (struct elf_obj_tdata): Add members
+ emit_note_gnu_build_id and note_gnu_build_id_sec.
+ * elf.c (_bfd_id_note_section_size): New global function.
+ (read_hex, _bfd_elf_write_build_id_section): New static functions.
+ (_bfd_elf_write_object_contents): Call _bfd_elf_write_build_id_section
+ if emit_note_gnu_build_id is set.
+ * Makefile.am (elf.lo): Update dependencies.
+
+ * elf-bfd.h (struct elf_size_info): Add checksum_contents hook.
+ (bfd_elf32_checksum_contents, bfd_elf64_checksum_contents): Declare.
+ * elfcode.h (elf_checksum_contents): New macro and function.
+ (NAME(_bfd_elf,size_info)): Initialize checksum_contents hook.
+
+2007-07-06 Michael Snyder <msnyder@access-company.com>
+
+ * elflink.c (elf_link_add_object_symbols): Return via
+ error_free_vers on "notice" failure.
+
+2007-07-04 H.J. Lu <hongjiu.lu@intel.com>
+
+ * peicode.h (pe_bfd_object_p): Don't check PE vs. EFI target
+ if arch is unknown.
+
+2007-07-04 Nick Clifton <nickc@redhat.com>
+
+ Import this patch from an internal tree:
+
+ 2001-07-17 Richard Henderson <rth@redhat.com>
+
+ * elf32-mep.c (mep_final_link_relocate) [R_MEP_HI16S]: Correctly
+ compensate for high bit set in R_MEP_LOW16.
+
+2007-07-03 Joseph Myers <joseph@codesourcery.com>
+
+ * elf32-arm.c (elf32_arm_merge_eabi_attributes): Copy type from
+ input attributes if value has been copied.
+
+2007-07-03 Nick Clifton <nickc@redhat.com>
+
+ * COPYING: Replace with GPLv3 text.
+ * aix386-core.c: Update copyright notice to refer to GPLv3.
+ * aix5ppc-core.c, aout0.c, aout32.c, aout64.c, aout-adobe.c,
+ aout-arm.c, aout-cris.c, aoutf1.h, aout-ns32k.c, aout-sparcle.c,
+ aout-target.h, aout-tic30.c, aoutx.h, archive64.c, archive.c,
+ archures.c, armnetbsd.c, bfd.c, bfd-in.h, bfdio.c, bfdwin.c,
+ binary.c, bout.c, cache.c, cf-i386lynx.c, cf-sparclynx.c,
+ cisco-core.c, coff64-rs6000.c, coff-alpha.c, coff-apollo.c,
+ coff-arm.c, coff-aux.c, coffcode.h, coffgen.c, coff-go32.c,
+ coff-h8300.c, coff-h8500.c, coff-i386.c, coff-i860.c, coff-i960.c,
+ coff-ia64.c, cofflink.c, coff-m68k.c, coff-m88k.c, coff-maxq.c,
+ coff-mcore.c, coff-mips.c, coff-or32.c, coff-pmac.c, coff-ppc.c,
+ coff-rs6000.c, coff-sh.c, coff-sparc.c, coff-stgo32.c,
+ coff-svm68k.c, coffswap.h, coff-tic30.c, coff-tic4x.c,
+ coff-tic54x.c, coff-tic80.c, coff-u68k.c, coff-w65.c,
+ coff-we32k.c, coff-x86_64.c, coff-z80.c, coff-z8k.c, corefile.c,
+ cpu-alpha.c, cpu-arc.c, cpu-arm.c, cpu-avr.c, cpu-bfin.c,
+ cpu-cr16.c, cpu-cr16c.c, cpu-cris.c, cpu-crx.c, cpu-d10v.c,
+ cpu-d30v.c, cpu-dlx.c, cpu-fr30.c, cpu-frv.c, cpu-h8300.c,
+ cpu-h8500.c, cpu-hppa.c, cpu-i370.c, cpu-i386.c, cpu-i860.c,
+ cpu-i960.c, cpu-ia64.c, cpu-ia64-opc.c, cpu-ip2k.c, cpu-iq2000.c,
+ cpu-m10200.c, cpu-m10300.c, cpu-m32c.c, cpu-m32r.c, cpu-m68hc11.c,
+ cpu-m68hc12.c, cpu-m68k.c, cpu-m88k.c, cpu-maxq.c, cpu-mcore.c,
+ cpu-mep.c, cpu-mips.c, cpu-mmix.c, cpu-msp430.c, cpu-mt.c,
+ cpu-ns32k.c, cpu-openrisc.c, cpu-or32.c, cpu-pdp11.c, cpu-pj.c,
+ cpu-powerpc.c, cpu-rs6000.c, cpu-s390.c, cpu-score.c, cpu-sh.c,
+ cpu-sparc.c, cpu-spu.c, cpu-tic30.c, cpu-tic4x.c, cpu-tic54x.c,
+ cpu-tic80.c, cpu-v850.c, cpu-vax.c, cpu-w65.c, cpu-we32k.c,
+ cpu-xc16x.c, cpu-xstormy16.c, cpu-xtensa.c, cpu-z80.c, cpu-z8k.c,
+ demo64.c, doc/chew.c, dwarf1.c, dwarf2.c, ecoff.c, ecofflink.c,
+ ecoffswap.h, efi-app-ia32.c, efi-app-ia64.c, efi-app-x86_64.c,
+ elf32-am33lin.c, elf32-arc.c, elf32-arm.c, elf32-avr.c,
+ elf32-avr.h, elf32-bfin.c, elf32.c, elf32-cr16.c, elf32-cr16c.c,
+ elf32-cris.c, elf32-crx.c, elf32-d10v.c, elf32-d30v.c,
+ elf32-dlx.c, elf32-fr30.c, elf32-frv.c, elf32-gen.c,
+ elf32-h8300.c, elf32-hppa.c, elf32-hppa.h, elf32-i370.c,
+ elf32-i386.c, elf32-i860.c, elf32-i960.c, elf32-ip2k.c,
+ elf32-iq2000.c, elf32-m32c.c, elf32-m32r.c, elf32-m68hc11.c,
+ elf32-m68hc12.c, elf32-m68hc1x.c, elf32-m68hc1x.h, elf32-m68k.c,
+ elf32-m88k.c, elf32-mcore.c, elf32-mep.c, elf32-mips.c,
+ elf32-msp430.c, elf32-mt.c, elf32-openrisc.c, elf32-or32.c,
+ elf32-pj.c, elf32-ppc.c, elf32-ppc.h, elf32-s390.c, elf32-score.c,
+ elf32-sh64.c, elf32-sh64-com.c, elf32-sh64.h, elf32-sh.c,
+ elf32-sh-symbian.c, elf32-sparc.c, elf32-spu.c, elf32-spu.h,
+ elf32-v850.c, elf32-vax.c, elf32-xc16x.c, elf32-xstormy16.c,
+ elf32-xtensa.c, elf64-alpha.c, elf64.c, elf64-gen.c, elf64-hppa.c,
+ elf64-hppa.h, elf64-mips.c, elf64-mmix.c, elf64-ppc.c,
+ elf64-ppc.h, elf64-s390.c, elf64-sh64.c, elf64-sparc.c,
+ elf64-x86-64.c, elf-attrs.c, elf-bfd.h, elf.c, elfcode.h,
+ elfcore.h, elf-eh-frame.c, elf-hppa.h, elflink.c, elf-m10200.c,
+ elf-m10300.c, elfn32-mips.c, elf-strtab.c, elf-vxworks.c,
+ elf-vxworks.h, elfxx-ia64.c, elfxx-mips.c, elfxx-mips.h,
+ elfxx-sparc.c, elfxx-sparc.h, elfxx-target.h, epoc-pe-arm.c,
+ epoc-pei-arm.c, format.c, freebsd.h, gen-aout.c, genlink.h,
+ hash.c, host-aout.c, hosts/alphavms.h, hp300bsd.c, hp300hpux.c,
+ 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.c, libbfd-in.h, libcoff-in.h, libecoff.h,
+ libhppa.h, libieee.h, libnlm.h, liboasys.h, libpei.h, libxcoff.h,
+ linker.c, lynx-core.c, m68k4knetbsd.c, m68klinux.c, m68knetbsd.c,
+ m88kmach3.c, m88kopenbsd.c, mach-o.c, mach-o.h, mach-o-target.c,
+ mep-relocs.pl, merge.c, mipsbsd.c, mmo.c, netbsd-core.c, netbsd.h,
+ newsos3.c, nlm32-alpha.c, nlm32.c, nlm32-i386.c, nlm32-ppc.c,
+ nlm32-sparc.c, nlm64.c, nlm.c, nlmcode.h, nlmswap.h, nlm-target.h,
+ ns32k.h, ns32knetbsd.c, oasys.c, opncls.c, osf-core.c,
+ pc532-mach.c, pdp11.c, pe-arm.c, pe-arm-wince.c, pef.c, pef.h,
+ pef-traceback.h, pe-i386.c, pei-arm.c, pei-arm-wince.c, peicode.h,
+ pei-i386.c, pei-mcore.c, pei-mips.c, pei-ppc.c, pei-sh.c,
+ pei-x86_64.c, pe-mcore.c, pe-mips.c, pe-ppc.c, pe-sh.c,
+ pe-x86_64.c, peXXigen.c, ppcboot.c, ptrace-core.c, reloc16.c,
+ reloc.c, riscix.c, rs6000-core.c, sco5-core.c, section.c,
+ simple.c, som.c, som.h, sparclinux.c, sparclynx.c, sparcnetbsd.c,
+ srec.c, stabs.c, stab-syms.c, stamp-h.in, sunos.c, syms.c,
+ sysdep.h, targets.c, targmatch.sed, tekhex.c, ticoff.h,
+ trad-core.c, vax1knetbsd.c, vaxbsd.c, vaxnetbsd.c, versados.c,
+ vms.c, vms-gsd.c, vms.h, vms-hdr.c, vms-misc.c, vms-tir.c,
+ xcofflink.c, xcoff-target.h, xsym.c, xsym.h, xtensa-isa.c,
+ xtensa-modules.c: Likewise.
+ * elf32-sh-relocs.h: Add copyright notice.
+ * hosts/alphalinux.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.h, hosts/news-mips.h, hosts/pc532mach.h,
+ hosts/riscos.h, hosts/symmetry.h, hosts/tahoe.h, hosts/vaxbsd.h,
+ hosts/vaxlinux.h, hosts/vaxult2.h, hosts/vaxult.h: Likewise.
+ * bfd-in2.h, libbfd.h, libcoff.h: Regenerate.
+
+2007-07-02 Joseph Myers <joseph@codesourcery.com>
+
+ * elfxx-mips.c (mips_elf_calculate_relocation): Handle
+ R_MIPS_TLS_DTPREL32 and R_MIPS_TLS_DTPREL64.
+ * elf64-mips.c (mips_elf64_howto_table_rela): Support
+ R_MIPS_TLS_DTPREL64.
+
+2007-07-02 Alan Modra <amodra@bigpond.net.au>
+
+ * Makefile.am: Run "make dep-am".
+ * Makefile.in: Regenerate.
+ * aclocal.m4: Regenerate.
+ * config.in: Regenerate.
+ * po/SRC-POTFILES.in: Regenerate.
+ * po/bfd.pot: Regenerate.
+
+2007-07-02 Alan Modra <amodra@bigpond.net.au>
+
+ * elf-eh-frame.c (_bfd_elf_discard_section_eh_frame): Tidy
+ symsec != NULL tests.
+
+2007-07-02 Alan Modra <amodra@bigpond.net.au>
+
+ PR 4712
+ * elf.c (assign_file_positions_for_load_sections): Adjust lma
+ by p_vaddr_offset.
+
+2007-06-30 H.J. Lu <hongjiu.lu@intel.com>
+
+ * aclocal.m4: Regenerated.
+ * Makefile.in: Likewise.
+
+2007-06-29 Joseph Myers <joseph@codesourcery.com>
+
+ * elf32-ppc.c (ppc_elf_merge_obj_attributes): New.
+ (ppc_elf_merge_private_bfd_data): Call it.
+
+2007-06-29 Joseph Myers <joseph@codesourcery.com>
+
+ * elfxx-mips.c (mips_elf_merge_obj_attributes): New.
+ (_bfd_mips_elf_merge_private_bfd_data): Call it.
+
+2007-06-29 Joseph Myers <joseph@codesourcery.com>
+
+ * elf-attrs.c: New.
+ * Makefile.am (BFD32_BACKENDS): Add elf-attrs.lo.
+ (BFD32_BACKENDS_CFILES): Add elf-attrs.c.
+ (elf-attrs.lo): Generate dependencies.
+ * Makefile.in: Regenerate.
+ * configure.in (elf): Add elf-attrs.lo.
+ * configure: Regenerate.
+ * elf-bfd.h (struct elf_backend_data): Add entries for object
+ attributes.
+ (NUM_KNOWN_OBJ_ATTRIBUTES, obj_attribute, obj_attribute_list,
+ OBJ_ATTR_PROC, OBJ_ATTR_GNU, OBJ_ATTR_FIRST, OBJ_ATTR_LAST,
+ Tag_NULL, Tag_File, Tag_Section, Tag_Symbol, Tag_compatibility):
+ New.
+ (struct elf_obj_tdata): Add entries for object attributes.
+ (elf_known_obj_attributes, elf_other_obj_attributes,
+ elf_known_obj_attributes_proc, elf_other_obj_attributes_proc):
+ New.
+ (bfd_elf_obj_attr_size, bfd_elf_set_obj_attr_contents,
+ bfd_elf_get_obj_attr_int, bfd_elf_add_obj_attr_int,
+ bfd_elf_add_proc_attr_int, bfd_elf_add_obj_attr_string,
+ bfd_elf_add_proc_attr_string, bfd_elf_add_obj_attr_compat,
+ bfd_elf_add_proc_attr_compat, _bfd_elf_attr_strdup,
+ _bfd_elf_copy_obj_attributes, _bfd_elf_obj_attrs_arg_type,
+ _bfd_elf_parse_attributes, _bfd_elf_merge_object_attributes): New.
+ * elf.c (_bfd_elf_copy_private_bfd_data): Copy object attributes.
+ (bfd_section_from_shdr): Handle attributes sections.
+ * elflink.c (bfd_elf_final_link): Handle attributes sections.
+ * elfxx-target.h (elf_backend_obj_attrs_vendor,
+ elf_backend_obj_attrs_section, elf_backend_obj_attrs_arg_type,
+ elf_backend_obj_attrs_section_type): New.
+ (elfNN_bed): Update.
+ * elf32-arm.c (NUM_KNOWN_ATTRIBUTES, aeabi_attribute,
+ aeabi_attribute_list): Remove.
+ (struct elf32_arm_obj_tdata): Remove object attributes fields.
+ (check_use_blx, bfd_elf32_arm_set_vfp11_fix, using_thumb2,
+ elf32_arm_copy_private_bfd_data, elf32_arm_merge_eabi_attributes):
+ Update for new object attributes interfaces.
+ (uleb128_size, is_default_attr, eabi_attr_size,
+ elf32_arm_eabi_attr_size, write_uleb128, write_eabi_attribute,
+ elf32_arm_set_eabi_attr_contents, elf32_arm_bfd_final_link,
+ elf32_arm_new_eabi_attr, elf32_arm_get_eabi_attr_int,
+ elf32_arm_add_eabi_attr_int, attr_strdup,
+ elf32_arm_add_eabi_attr_string, elf32_arm_add_eabi_attr_compat,
+ copy_eabi_attributes, elf32_arm_parse_attributes): Remove. Moved
+ to generic code in elf-attrs.c.
+ (elf32_arm_obj_attrs_arg_type): New.
+ (elf32_arm_fake_sections): Do not handle .ARM.attributes.
+ (elf32_arm_section_from_shdr): Do not handle SHT_ARM_ATTRIBUTES.
+ (bfd_elf32_bfd_final_link): Remove.
+ (elf_backend_obj_attrs_vendor, elf_backend_obj_attrs_section,
+ elf_backend_obj_attrs_arg_type,
+ elf_backend_obj_attrs_section_type): New.
+ * elf32-bfin.c (bfin_elf_copy_private_bfd_data): Copy object
+ attributes.
+ * elf32-frv.c (frv_elf_copy_private_bfd_data): Likewise.
+ * elf32-iq2000.c (iq2000_elf_copy_private_bfd_data): Likewise.
+ * elf32-mep.c (mep_elf_copy_private_bfd_data): Likewise.
+ * elf32-mt.c (mt_elf_copy_private_bfd_data): Likewise.
+ * elf32-sh.c (sh_elf_copy_private_data): Likewise.
+ * elf64-sh64.c (sh_elf64_copy_private_data_internal): Likewise.
+
+2007-06-29 Paul Brook <paul@codesourcery.com>
+
+ * elf32-arm.c (bfd_elf32_arm_process_before_allocation): Suppress
+ call veneers for call relocations against undefined symbols.
+ (elf32_arm_final_link_relocate): Turn call to undefined symbol
+ into a jump to the next instruction.
+
+2007-06-29 Michael Snyder <msnyder@access-company.com>
+
+ * bfd.c (bfd_demangle): Plug memory leak (Coverity).
+
+2007-06-29 M R Swami Reddy <MR.Swami.Reddy@nsc.com>
+
+ * Makefile.am: Add cr16 related entry
+ * Makefile.in: Regenerate
+ * archures.c: Add bfd_cr16_arch
+ * bfd-in2.h: Regenerate
+ * config.bfd: Add cr16-elf
+ * configure.in: Add bfd_elf32_cr16_vec
+ * configure: Regenerate.
+ * targets.c: Added cr16 related information
+ * cpu-cr16.c: New file.
+ * elf32-cr16.c: New file.
+ * reloc.c: Added cr16 relocs.
+
+2007-06-29 Alan Modra <amodra@bigpond.net.au>
+
+ * elflink.c (_bfd_elf_link_assign_sym_version): Improve error
+ message for undefined version nodes.
+ (elf_gc_sweep): Don't warn when zero size sections are
+ removed.
+
+2007-06-29 Nathan Froyd <froydnj@codesourcery.com>
+
+ * elf32-ppc.c (ppc_elf_info_to_howto): Check for invalid relocation
+ types.
+
+2007-06-29 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-spu.c (spu_elf_fake_sections): New function.
+ (elf_backend_fake_sections): Define.
+
+2007-06-29 Alan Modra <amodra@bigpond.net.au>
+
+ * elf.c (assign_file_positions_for_load_sections): Use elf
+ section header sh_size rather than bfd section size, simplifying
+ .tbss handling.
+
+2007-06-29 Alan Modra <amodra@bigpond.net.au>
+
+ PR ld/4701
+ * elf.c (assign_file_positions_for_load_sections): Ensure bss
+ segments meet gABI alignment requirements. Don't allocate
+ file space for bss sections in a segment also containing file
+ or program headers.
+
+2007-06-27 Alan Modra <amodra@bigpond.net.au>
+
+ * bfd.c (struct bfd): Rename "next" to "archive_next".
+ * archive.c: Rename uses throughout file.
+ * archive64.c: Likewise.
+ * coff-rs6000.c: Likewise.
+ * ecoff.c: Likewise.
+ * som.c: Likewise.
+ * bfd-in2.h: Regenerate.
+
+ * elf32-ppc.c (ppc_elf_select_plt_layout): Properly iterate over
+ input bfds.
+ * elf32-spu.c (spu_elf_create_sections): Likewise.
+
+2007-06-26 H.J. Lu <hongjiu.lu@intel.com>
+
+ * dwarf2.c (find_line): New. Contains the duplicated code from:
+ (_bfd_dwarf2_find_nearest_line): Use it.
+ (_bfd_dwarf2_find_line): Use it.
+
+2007-06-26 Joseph Myers <joseph@codesourcery.com>
+
+ * elf32-arm.c (copy_eabi_attributes): Copy type of attributes.
+
+2007-06-25 Richard Sandiford <richard@codesourcery.com>
+
+ * elfxx-mips.c (mips_elf_calculate_relocation): Allow local stubs
+ to be used for calls from MIPS16 code.
+
+2007-06-23 Andreas Schwab <schwab@suse.de>
+
+ * configure.in (--with-separate-debug-dir): New option.
+ * configure: Regenerate.
+ * Makefile.am (dwarf2.lo): Add rule to pass DEBUGDIR.
+ * Makefile.in: Regenerate.
+ * dwarf2.c (_bfd_dwarf2_find_nearest_line): Pass DEBUGDIR to
+ bfd_follow_gnu_debuglink.
+ (_bfd_dwarf2_find_line): Likewise.
+
+2007-06-22 Nick Clifton <nickc@redhat.com>
+
+ * dwarf2.c: Add support for reading in debug information via a
+ .gnu_debuglink section:
+ (struct dwarf2_debug): Add bfd field to record the bfd containing
+ the debug info.
+ (parse_comp_unit): Remove ABFD parameter. Instead use the bfd
+ field in the dwarf2_debug structure.
+ (_bfd_dwarf2_find_nearest_line): If a debug info section could not
+ be found in the current bfd call bfd_follow_gnu_debuglink to see
+ if another file contains the debug information. If it does, open
+ it and continue.
+ (_bfd_dwarf2_find_line): Likewise.
+
+2007-06-19 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/4590
+ * elfxx-ia64.c (sort_dyn_sym_info): Keep the valid got_offset
+ when removing duplicated entries.
+ (get_dyn_sym_info): Initialize the got_offset field to -1.
+ Update call to sort_dyn_sym_info.
+ (elfNN_ia64_relocate_section): Call sort_dyn_sym_info to sort
+ array of addend and remove duplicates.
+
+2007-06-18 H.J. Lu <hongjiu.lu@intel.com>
+
+ * libpei.h (_bfd_XXi_final_link_postscript): Remove
+ duplication.
+ (bfd_target_pei_p): New.
+ (bfd_target_pei_arch): New
+ (bfd_target_efi_p): Likewise.
+ (bfd_target_efi_arch): New
+ (bfd_pe_executable_p): Use bfd_target_pei_p and
+ bfd_target_efi_p.
+
+ * peicode.h (arch_type): New enum.
+ (pe_arch): New function.
+ (pe_bfd_object_p): Don't match PE/EFI target with EFI/PE file
+ if there is an EFI/PE target.
+
+2007-06-14 H.J. Lu <hongjiu.lu@intel.com>
+
+ * Makefile.am (ACLOCAL_AMFLAGS): Add -I . -I ../config.
+
+ * acinclude.m4: Don't include m4 files. Remove libtool
+ kludge.
+
+ * Makefile.in: Regenerated.
+ * aclocal.m4: Likewise.
+ * configure: Likewise.
+
+2007-06-11 Sterling Augustine <sterling@tensilica.com>
+ Bob Wilson <bob.wilson@acm.org>
+
+ * elf32-xtensa.c (extend_ebb_bounds_forward): Use renamed
+ XTENSA_PROP_NO_TRANSFORM flag instead of XTENSA_PROP_INSN_NO_TRANSFORM.
+ (extend_ebb_bounds_backward, compute_text_actions): Likewise.
+ (compute_ebb_proposed_actions, coalesce_shared_literal): Likewise.
+ (xtensa_get_property_predef_flags): Likewise.
+ (compute_removed_literals): Pass new arguments to is_removable_literal.
+ (is_removable_literal): Add sec, prop_table and ptblsize arguments.
+ Do not remove literal if the NO_TRANSFORM property flag is set.
+
+2007-05-31 Richard Sandiford <rsandifo@nildram.co.uk>
+
+ * elfxx-mips.c (mips_elf_initialize_tls_index): When processing a
+ type (3) single-GOT entry, read tls_type from the hash table entry
+ rather than the GOT entry.
+
+2007-06-01 Alan Modra <amodra@bigpond.net.au>
+
+ * simple.c (bfd_simple_get_relocated_section_contents): Init
+ input_bfds_tail.
+
+2007-05-30 Alan Modra <amodra@bigpond.net.au>
+
+ * elf.c (elf_fake_sections): Adjust test for SHT_NOBITS sections
+ created by objcopy --only-keep-debug.
+ (_bfd_elf_init_private_section_data): Only change elf_section_type
+ if it is SHT_NULL.
+
+ * elf.c (assign_file_positions_for_load_sections): Correct sh_type
+ to SHT_NOBITS earlier. Base actions in rest of function on sh_type
+ and sh_flags instead of bfd section flags. Delete voff and code
+ keeping nobits segments aligned.
+
+2007-05-25 Eric Christopher <echristo@apple.com>
+
+ * elf-eh-frame.c (_bfd_elf_discard_section_eh_frame):
+ Check that sym_sec isn't NULL before accessing.
+
+2007-05-24 Steve Ellcey <sje@cup.hp.com>
+
+ * Makefile.in: Regnerate.
+ * configure: Regenerate.
+ * aclocal.m4: Regenerate.
+ * doc/Makefile.in: Regenerate.
+
+2007-05-22 Paul Brook <paul@codesourcery.com>
+
+ * elf32-arm.c (output_arch_syminfo): Replace plt_shndx and plt_offset
+ with sec and sec_shndx.
+ (elf32_arm_ouput_plt_map_sym): Use them.
+ (elf32_arm_output_arch_local_syms): Output mapping symbols for
+ interworking glue.
+
+2007-05-18 Paul Brook <paul@codesourcery.com>
+
+ * elf32-arm.c (ARM2THUMB_V5_STATIC_GLUE_SIZE): Define.
+ (a2t1v5_ldr_insn, a2t1v5_ldr_insn): New.
+ (record_arm_to_thumb_glue): Add v5t non-pic glue.
+ (elf32_arm_create_thumb_stub): Ditto.
+
+2007-05-16 H.J. Lu <hongjiu.lu@intel.com>
+ Alan Modra <amodra@bigpond.net.au>
+
+ * elflink.c (_bfd_elf_adjust_dynamic_copy): Align dynamic bss
+ section to the minimum alignment.
+
+2007-05-15 H.J. Lu <hongjiu.lu@intel.com>
+ Alan Modra <amodra@bigpond.net.au>
+
+ PR ld/4504
+ * elf-bfd.h (_bfd_elf_adjust_dynamic_copy): New.
+ * elflink.c (_bfd_elf_adjust_dynamic_copy): New.
+
+ * elf-m10300.c (_bfd_mn10300_elf_adjust_dynamic_symbol): Call
+ _bfd_elf_adjust_dynamic_copy to adjust for the copy in dynamic
+ bss section.
+ * elf32-arm.c (elf32_arm_adjust_dynamic_symbol): Likewise.
+ * elf32-cris.c (elf_cris_adjust_dynamic_symbol): Likewise.
+ * elf32-hppa.c (elf32_hppa_adjust_dynamic_symbol): Likewise.
+ * elf32-i370.c (i370_elf_adjust_dynamic_symbol): Likewise.
+ * elf32-i386.c (elf_i386_adjust_dynamic_symbol): Likewise.
+ * elf32-m32r.c (m32r_elf_adjust_dynamic_symbol): Likewise.
+ * elf32-m68k.c (elf_m68k_adjust_dynamic_symbol): Likewise.
+ * elf32-ppc.c (ppc_elf_adjust_dynamic_symbol): Likewise.
+ * elf32-s390.c (elf_s390_adjust_dynamic_symbol): Likewise.
+ * elf32-sh.c (sh_elf_adjust_dynamic_symbol): Likewise.
+ * elf32-vax.c (elf_vax_adjust_dynamic_symbol): Likewise.
+ * elf64-ppc.c (ppc64_elf_adjust_dynamic_symbol): Likewise.
+ * elf64-s390.c (elf_s390_adjust_dynamic_symbol): Likewise.
+ * elf64-sh64.c (sh64_elf64_adjust_dynamic_symbol): Likewise.
+ * elf64-x86-64.c (elf64_x86_64_adjust_dynamic_symbol): Likewise.
+ * elfxx-mips.c (_bfd_mips_vxworks_adjust_dynamic_symbol): Likewise.
+ * elfxx-sparc.c (_bfd_sparc_elf_adjust_dynamic_symbol): Likewise.
+
+2007-05-15 Richard Sandiford <richard@codesourcery.com>
+
+ * elfxx-mips.c (mips_elf_create_local_got_entry): Remove
+ input_section argument. Create .rela.dyn relocations against
+ symbol 0 rather than the section symbol.
+ (mips_elf_local_got_index): Remove input_section argument.
+ Update call to mips_elf_create_local_got_entry.
+ (mips_elf_got_page, mips_elf_got16_entry): Likewise.
+ (mips_elf_calculate_relocation): Update calls to
+ mips_elf_local_got_index, mips_elf_got16_entry and mips_elf_got_page.
+
+2007-05-15 Mark Shinwell <shinwell@codesourcery.com>
+
+ * elf32-arm.c (elf32_arm_final_link_relocate): Correctly
+ handle the Thumb-2 JUMP19 relocation.
+
+2007-05-15 Alan Modra <amodra@bigpond.net.au>
+
+ PR 4479
+ * elf.c (elf_fake_sections): Don't allow backend to change
+ SHT_NOBITS if called for strip/objcopy --only-keep-debug.
+ * elfxx-mips.c (_bfd_mips_elf_fake_sections): Remove similar
+ fix from here.
+
+2007-05-14 Alan Modra <amodra@bigpond.net.au>
+
+ * elf.c (bfd_elf_string_from_elf_section): Return NULL on
+ invalid shstrndx.
+ (bfd_elf_get_str_section): Likewise.
+
+2007-05-12 Alan Modra <amodra@bigpond.net.au>
+
+ PR 4497
+ * elf-eh-frame.c (struct cie): Add "local_personality". Make
+ "personality" a union.
+ (cie_eq): Compare local_personality too. Adjust personality
+ comparison.
+ (_bfd_elf_discard_section_eh_frame): Check binding on personality
+ reloc sym to allow for bad symtab. Use stashed local syms rather
+ than reading personality local sym. Handle discarded sections.
+
+2007-05-12 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-spu.c (elf_howto_table): Add howto for R_SPU_ADDR16X.
+
+2007-05-11 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-ppc.h (ppc_elf_select_plt_layout): Update prototype.
+ (enum ppc_elf_plt_type): Move from..
+ * elf32-ppc.c: ..here.
+ (struct ppc_elf_obj_tdata): Add makes_plt_call and has_rel16.
+ (struct ppc_elf_link_hash_table): Reorder. Add old_bfd. Delete
+ can_use_new_plt. Make is_vxworks a bitfield.
+ (ppc_elf_link_hash_table_create): Don't clear is_vxworks (again).
+ (ppc_elf_check_relocs): Update setting of reloc flags. Set old_bfd.
+ (ppc_elf_select_plt_layout): Modify parameters. Use bfd reloc
+ flags to better detect object files needing old bss-style plt.
+ Allow secure plt to be used without rel16 relocs being detected.
+ Warn if secure plt request cannot be allowed.
+
+2007-05-11 Alan Modra <amodra@bigpond.net.au>
+
+ * reloc.c (BFD_RELOC_SPU_PPU32, BFD_RELOC_SPU_PPU64): Define.
+ * elf-bfd.h (struct elf_backend_data): Change return type of
+ elf_backend_relocate_section to int.
+ * elf32-spu.c (elf_howto_table): Add howtos for R_SPU_PPU32 and
+ R_SPU_PPU64.
+ (spu_elf_bfd_to_reloc_type): Convert new relocs.
+ (spu_elf_count_relocs): New function.
+ (elf_backend_count_relocs): Define.
+ (spu_elf_relocate_section): Arrange to emit R_SPU_PPU32 and
+ R_SPU_PPU64 relocs.
+ * elflink.c (elf_link_input_bfd): Emit relocs if relocate_section
+ returns 2.
+ * bfd-in2.h: Regenerate.
+ * libbfd.h: Regenerate.
+
+2007-05-10 Richard Sandiford <richard@codesourcery.com>
+
+ * elf32-arm.c (elf32_arm_check_relocs): Don't create PLT entries
+ for R_ARM_ABS12 relocs.
+ (elf32_arm_finish_dynamic_symbol): Fix the loop that creates
+ non-shared VxWorks PLT entries.
+
+2007-05-11 Alan Modra <amodra@bigpond.net.au>
+
+ PR 4454
+ * elf-eh-frame.c (struct cie): Make "personality" a bfd_vma.
+ (_bfd_elf_discard_section_eh_frame): Handle local syms on
+ personality relocation.
+
+2007-05-10 Richard Sandiford <richard@codesourcery.com>
+
+ * elf.c (assign_file_positions_for_load_sections): Use p_memsz
+ rather than p_filesz to calculate the LMA of the end of a segment.
+
+2007-05-10 Jakub Jelinek <jakub@redhat.com>
+
+ * elf64-ppc.c (ppc64_elf_adjust_dynamic_symbol): Don't do copyreloc
+ processing if symbol is defined in the executable.
+
+2007-05-10 Alexandre Oliva <aoliva@redhat.com>
+
+ * elf32-frv.c (_frvfdpic_check_discarded_relocs): New.
+ (frvfdpic_elf_discard_info): New.
+ (elf_backend_discard_info): Define for FDPIC.
+
+2007-05-09 Mark Shinwell <shinwell@codesourcery.com>
+
+ * elf32-arm.c (bfd_elf32_arm_vfp11_erratum_scan): Don't
+ attempt to scan if the bfd doesn't correspond to an ELF image.
+ (bfd_elf32_arm_vfp11_fix_veneer_locations): Likewise.
+
+2007-05-08 Alexandre Oliva <aoliva@redhat.com>
+
+ * elf32-frv.c (elf32_frv_relocate_section): Discard dynamic relocs
+ for which _bfd_elf_section_offset returns -1.
+
+2007-05-08 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-spu.c (spu_elf_size_stubs): Use "void *" for psyms.
+ (mark_functions_via_relocs): Likewise.
+
+2007-05-07 Alan Modra <amodra@bigpond.net.au>
+
+ * elflink.c (bfd_elf_final_link): Correct reloc handling for
+ elf_backend_count_relocs.
+ (bfd_elf_discard_info): Print an error if we can't read syms.
+
+2007-05-07 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-spu.c (spu_elf_reloc_type_lookup): Return NULL on
+ invalid reloc code.
+ (spu_elf_gc_mark_hook, spu_elf_section_processing): Delete functions.
+ (elf_backend_gc_mark_hook, elf_backend_section_processing): Don't
+ define.
+
+2007-05-07 Alan Modra <amodra@bigpond.net.au>
+
+ * elf.c (assign_file_positions_for_load_sections): Don't check
+ core segment.
+
+2007-05-04 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elflink.c (elf_link_sort_relocs): Return if both .rela.dyn
+ and .rel.dyn aren't present.
+
+2007-05-04 Nick Clifton <nickc@redhat.com>
+
+ * elflink.c (elf_link_sort_relocs): If both .rela.dyn and .rel.dyn
+ sections are present examine the indirect sections in an attempt
+ to compute the correct relocation size. If there is any
+ ambiguity, produce an error and refuse to sort.
+
+2007-05-03 Sandra Loosemore <sandra@codesourcery.com>
+
+ * elf32-arm.c (allocate_dynrelocs): Fix typo in comment.
+
+2007-05-03 Vincent Riviere <vincent.riviere@freesbee.fr>
+ Nick Clifton <nickc@redhat.com>
+
+ PR gas/3041
+ * aoutx.h (swap_std_reloc_out): Treat relocs against weak symbols
+ in the same way as relocs against external symbols.
+
+2007-05-02 Alan Modra <amodra@bigpond.net.au>
+
+ * elf.c (assign_file_positions_for_load_sections): Set sh_offset
+ here. Set sh_type to SHT_NOBITS if we won't be allocating
+ file space. Don't bump p_memsz for non-alloc sections. Adjust
+ section-in-segment check.
+ (assign_file_positions_for_non_load_sections): Don't set sh_offset
+ here for sections that have already been handled above.
+
+2007-04-30 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-spu.c (struct spu_link_hash_table): Add stack_analysis
+ and emit_stack_syms bitfields.
+ (get_sym_h): Read all symbols if stack analysis will be done.
+ (spu_elf_create_sections): Add stack_analysis and emit_stack_syms
+ params, and stash in hash table.
+ (is_hint): Split off from..
+ (is_branch): ..here. Adjust callers.
+ (spu_elf_size_stubs): Add stack_analysis param. Arrange to read
+ and keep all syms.
+ (write_one_stub): Fix mem leak.
+ (find_function_stack_adjust): New function.
+ (sort_syms_syms, sort_syms_psecs): New vars.
+ (sort_syms): New function.
+ (struct call_info, struct function_info): New.
+ (struct spu_elf_stack_info): New.
+ (alloc_stack_info, maybe_insert_function, func_name): New functions.
+ (is_nop, insns_at_end, check_function_ranges): Likewise.
+ (find_function, insert_callee, mark_functions_via_relocs): Likewise.
+ (pasted_function, interesting_section, discover_functions): Likewise.
+ (mark_non_root, call_graph_traverse, build_call_tree): Likewise.
+ (sum_stack, spu_elf_stack_analysis, spu_elf_final_link): Likewise.
+ (bfd_elf32_bfd_final_link): Define.
+ * elf32-spu.h (struct _spu_elf_section_data): Add stack_info field.
+ (spu_elf_create_sections, spu_elf_size_stubs): Update prototypes.
+
+2007-04-28 Sergey Rogozhkin <rogozhkin@niisi.msk.ru>
+
+ * elfxx-mips.c (mips_elf_create_dynamic_relocation): Don't access
+ memory which we might not own.
+
+2007-04-27 Bob Wilson <bob.wilson@acm.org>
+
+ * elf32-xtensa.c (elf_xtensa_make_sym_local): Restore deleted function.
+ (elf_xtensa_hide_symbol, elf_backend_hide_symbol): Likewise.
+ (elf_xtensa_allocate_dynrelocs): Use elf_xtensa_make_sym_local.
+
+2007-04-27 Bob Wilson <bob.wilson@acm.org>
+
+ * elf32-xtensa.c (xtensa_read_table_entries): Step through table
+ contents and relocs in parallel.
+
+2007-04-27 Bob Wilson <bob.wilson@acm.org>
+
+ * elf32-xtensa.c (relax_property_section): Remove extra irel increment.
+
+2007-04-27 Alan Modra <amodra@bigpond.net.au>
+
+ * cpu-rs6000.c: Write Mimi's name in ASCII.
+ * coff-rs6000.c: Likewise.
+ * rs6000-core.c: Likewise.
+
+2007-04-27 Alan Modra <amodra@bigpond.net.au>
+
+ * sysdep.h: Include config.h first.
+ Many files: Include sysdep.h before bfd.h.
+ * Makefile.am: Run "make dep-am".
+ * Makefile.in: Regenerate.
+
+2007-04-25 Alan Modra <amodra@bigpond.net.au>
+
+ * sysdep.h: Revert last change.
+
+2007-04-24 Nick Clifton <nickc@redhat.com>
+
+ * coffcode.h (coff_slurp_reloc_table): Initialise dst.r_offset.
+ * coff-m68k.c (m68kcoff_rtype_to_howto): Initialize relent.howto.
+
+2007-04-24 Alan Modra <amodra@bigpond.net.au>
+
+ * elf-eh-frame.c (_bfd_elf_discard_section_eh_frame): Warn if
+ eh_frame_hdr table won't be created.
+
+2007-04-24 Alan Modra <amodra@bigpond.net.au>
+
+ * acinclude.m4: Include config/stdint.m4.
+ * configure.in: Invoke GCC_HEADER_STDINT.
+ * sysdep.h: Don't include ansidecl.h here.
+ * configure: Regenerate.
+ * config.in: Regenerate.
+ * Makefile.in: Regenerate.
+
+2007-04-23 Nathan Sidwell <nathan@codesourcery.com>
+
+ * archures.c (bfd_mach_mcf_isa_c, bfd_mach_mcf_isa_c_mac,
+ bfd_mach_mcf_isa_c_emac): New.
+ * elf32-m68k.c (ISAC_PLT_ENTRY_SIZE, elf_isac_plt0_entry,
+ elf_isac_plt_entry, elf_isac_plt_info): New.
+ (elf32_m68k_object_p): Add ISA_C.
+ (elf32_m68k_print_private_bfd_data): Print ISA_C.
+ (elf32_m68k_get_plt_info): Detect ISA_C.
+ * cpu-m68k.c (arch_info): Add ISAC.
+ (m68k_arch_features): Likewise,
+ (bfd_m68k_compatible): ISAs B & C are not compatible.
+
+2007-04-21 Nick Clifton <nickc@redhat.com>
+
+ * ecoff.c (_bfd_ecoff_write_armap): Initialise rehash.
+ (ecoff_link_add_archive_symbols): Likewise.
+ * coff-m68k.c (m68kcoff_common_addend_rtype_to_howto): Initialise
+ relent.howto.
+ * ieee.c (parse_int): Initialise x.
+ (must_parse_int): Initialise result.
+ (ieee_slurp_external_symbols): Initialise value.
+
+2007-04-21 Alan Modra <amodra@bigpond.net.au>
+
+ * config.bfd (spu-*-elf): Delete targ_selvecs.
+
+2007-04-19 Nick Clifton <nickc@redhat.com>
+
+ * coffcode.h (coff_rtype_to_howto): Initialise genrel.howto.
+
+2007-04-19 Alan Modra <amodra@bigpond.net.au>
+
+ * bfd.c (bfd_demangle): New function.
+ * Makefile.am: Run "make dep-am".
+ * Makefile.in: Regenerate.
+ * bfd-in2.h: Regenerate.
+
+2007-04-18 Matthias Klose <doko@ubuntu.com>
+
+ * Makefile.am (libbfd_la_LDFLAGS): Use bfd soversion.
+ (bfdver.h): Use the date in non-release builds for the soversion.
+ * Makefile.in: Regenerate.
+
+2007-04-17 Paul Brook <paul@codesourcery.com>
+
+ * elf.c (_bfd_elf_is_function_type): New function.
+ * elflink.c (_bfd_elf_merge_symbol): Use bed->is_function_type.
+ (_bfd_elf_dynamic_symbol_p, _bfd_elf_symbol_refs_local_p,
+ is_global_data_symbol_definition, elf_link_add_object_symbols): Ditto.
+ * elf-bfd.h (elf_backend_data): Add is_function_type.
+ (_bfd_elf_is_function_type): Add prototype.
+ * elfxx-target.h (elf_backend_is_function_type): Add default
+ definition.
+ (elfNN_bed): Add elf_backend_is_function_type.
+ * elf32-arm.c (elf32_arm_is_function_type): New function.
+ (elf_backend_is_function_type): Define.
+
+2007-04-17 Daniel Jacobowitz <dan@codesourcery.com>
+
+ * elfxx-mips.c (_bfd_mips_elf_size_dynamic_sections): Put
+ DT_MIPS_RLD_MAP before DT_DEBUG again.
+
+2007-04-14 Steve Ellcey <sje@cup.hp.com>
+
+ * Makefile.am: Add ACLOCAL_AMFLAGS.
+ * configure.in: Change macro call order.
+ * Makefile.in: Regnerate.
+ * doc/Makefile.in: Regenerate.
+ * configure: Regenerate.
+
+2007-04-14 Jakub Jelinek <jakub@redhat.com>
+
+ * elflink.c (bfd_elf_final_link): Don't free symbuf for
+ non-elf input bfds.
+ (bfd_elf_size_dynamic_sections): Don't access elf_section_data
+ for non-elf input bfds.
+
+2007-04-12 Richard Sandiford <richard@codesourcery.com>
+
+ * elfxx-mips.c (_bfd_mips_elf_size_dynamic_sections): Don't add
+ DT_MIPS_RTLD_MAP for PIEs.
+
+2007-04-12 Richard Sandiford <richard@codesourcery.com>
+
+ * elfxx-mips.c (mips_elf_calculate_relocation): Set DT_TEXTREL
+ when creating a __GOTT_BASE__ or __GOTT_INDEX__ relocation
+ in a read-only section.
+ (_bfd_mips_elf_check_relocs): Likewise.
+
+2007-04-12 Bob Wilson <bob.wilson@acm.org>
+
+ * elf32-xtensa.c (xtensa_is_insntable_section): New.
+ (xtensa_is_proptable_section): New.
+ (elf_xtensa_discard_info_for_section): Handle "full" .xt.prop property
+ tables with 12-byte entries, as well as tables with 8-byte entries.
+ Sort the relocations before examining them.
+ (relax_property_section): Use xtensa_is_proptable_section and
+ xtensa_is_littable_section. Rewrite code for combining table entries
+ to be more robust in case of unexpected relocations. Do not set offset
+ of unused relocations to less than zero.
+ (xtensa_is_property_section): Use other functions instead of
+ duplicating section name comparisons.
+ (xtensa_is_littable_section): Use CONST_STRNEQ for ".gnu.linkonce.p.".
+ (xtensa_get_property_predef_flags): Use xtensa_is_insntable_section.
+
+2007-04-12 Bob Wilson <bob.wilson@acm.org>
+
+ * elf32-xtensa.c (elf_xtensa_gc_mark_hook): Don't follow references
+ from Xtensa property sections.
+
+2007-04-12 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-spu.c (needs_ovl_stub): Test that spu_elf_section_data
+ is non-NULL before dereferencing.
+
+2007-04-11 Nathan Sidwell <nathan@codesourcery.com>
+
+ * elf-vxworks.c (elf_vxworks_emit_relocs): Remap weakdef PLT slot
+ relocs too.
+
+2007-04-10 Richard Henderson <rth@redhat.com>
+
+ * elf64-alpha.c (struct alpha_elf_link_hash_table): Add relax_trip.
+ (elf64_alpha_size_got_sections): Remove unused something_changed local.
+ (elf64_alpha_size_plt_section): Return void.
+ (elf64_alpha_size_rela_got_section): Likewise.
+ (elf64_alpha_relax_section): Only regenerate got+plt if the
+ relax_trip counter has changed.
+
+2007-04-09 Daniel Jacobowitz <dan@codesourcery.com>
+
+ * Makefile.am (bfdver.h): Do not generate doc/bfdver.texi.
+ * doc/Makefile.am (DOCFILES): Add bfdver.texi.
+ (bfdver.texi): New rule.
+ * Makefile.in, doc/Makefile.in: Regenerated.
+
+2007-04-03 Matt Thomas <matt@netbsd.org>
+
+ * elf32-vax.c (elf_vax_relocate_section): Do not emit a PCREL reloc
+ in a shared object if it is not in a CODE section or if it is against
+ a section symbol. This allows DWARF2 to use pcrel format.
+
+2007-04-05 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/4304
+ * elflink.c (bfd_elf_final_link): Call einfo callback in
+ bfd_link_info instead of _bfd_error_handler for DT_TEXTREL
+ warning.
+
+2007-04-05 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-spu.c (spu_elf_output_symbol_hook): New function.
+ (elf_backend_link_output_symbol_hook): Define.
+
+2007-04-02 Nick Clifton <nickc@redhat.com>
+
+ PR binutils/4292
+ * bfd.c (bfd_fprintf_vma): Do not print addresses of 32-bit
+ targets as 64-bit values, even if running on a 64-bit host.
+ * coffgen.c (coff_print_symbol): Likewise.
+
+2007-03-29 Nick Clifton <nickc@redhat.com>
+
+ PR binutils/4110
+ * elf.c (IS_VALID_GROUP_SECTION_HEADER): New macro.
+ (setup_group): Use it. Report corrupt group section headers.
+ (bfd_section_from_shdr): Use new macro. Replace constant 4 with
+ GRP_ENTRY_SIZE. Cope with NULLs in the group section table.
+ (elf_fake_section): Replace constant 4 with GRP_ENTRY_SIZE.
+
+2007-03-29 Alan Modra <amodra@bigpond.net.au>
+
+ PR ld/4267
+ * elflink.c (evaluate_complex_relocation_symbols): Use bfd_vma
+ for rel->r_info values.
+ (bfd_elf_perform_complex_relocation): Likewise.
+ * elf32-ppc.c (allocate_dynrelocs): Set plt.offset to -1 for
+ unused entries. Don't clear plt.plist in loop.
+
+2007-03-28 Richard Sandiford <richard@codesourcery.com>
+
+ * elfxx-sparc.h (_bfd_sparc_elf_link_hash_table): Remove append_rela.
+ * elfxx-sparc.c (sparc_elf_append_rela_64, sparc_elf_append_rela_32):
+ Merge into...
+ (sparc_elf_append_rela): ...this new function.
+ (SPARC_ELF_APPEND_RELA): Delete.
+ (_bfd_sparc_elf_link_hash_table_create): Don't initialize
+ the deleted append_rela field.
+ (_bfd_sparc_elf_relocate_section): Use sparc_elf_append_rela
+ instead of SPARC_ELF_APPEND_RELA.
+ (_bfd_sparc_elf_finish_dynamic_symbol): Likewise. Use the
+ elf_size_info structure to find the size of a RELA entry and
+ the associated swap-out function.
+ (sparc64_finish_dyn, sparc64_finish_dyn): Merge into...
+ (sparc_finish_dyn): ...this new function.
+ (_bfd_sparc_elf_finish_dynamic_sections): Update calls accordingly.
+
+2007-03-28 Richard Sandiford <richard@codesourcery.com>
+ Phil Edwards <phil@codesourcery.com>
+
+ * doc/bfd.texinfo: Put the contents after the title page rather
+ than at the end of the document.
+
+2007-03-27 Andreas Schwab <schwab@suse.de>
+
+ * elfxx-ia64.c (elf_backend_default_execstack): Define to 0.
+
+2007-03-26 H.J. Lu <hongjiu.lu@intel.com>
+
+ * configure: Regenerated.
+
+2007-03-26 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-spu.c (struct stubarr): Add stub_hash_table and err fields.
+ (allocate_spuear_stubs): New function.
+ (spu_elf_size_stubs): Call allocate_spuear_stubs.
+
+2007-03-26 Alan Modra <amodra@bigpond.net.au>
+
+ * aout-adobe.c (aout_32_bfd_reloc_name_lookup): Define.
+ * aout-arm.c (MY_bfd_reloc_name_lookup): Define.
+ (MY (bfd_reloc_name_lookup)): New function.
+ * aout-ns32k.c (MY (bfd_reloc_name_lookup)): New function.
+ * aout-target.h (NAME (aout, reloc_name_lookup)): Declare.
+ (MY_bfd_reloc_name_lookup): Define.
+ * aout-tic30.c (tic30_aout_reloc_name_lookup): New function.
+ (MY_bfd_reloc_name_lookup): Define.
+ * aoutx.h (NAME (aout, reloc_type_lookup)): Don't declare.
+ (NAME (aout, reloc_name_lookup)): New function.
+ * bout.c (b_out_bfd_reloc_name_lookup): New function.
+ * coff-alpha.c (alpha_bfd_reloc_name_lookup): New function.
+ (_bfd_ecoff_bfd_reloc_name_lookup): Define.
+ * coff-arm.c (coff_arm_reloc_name_lookup): New function.
+ (coff_bfd_reloc_name_lookup): Define.
+ * coff-i386.c (coff_bfd_reloc_name_lookup): Define.
+ (coff_i386_reloc_name_lookup): New function.
+ * coff-i860.c (coff_i860_reloc_name_lookup): New function.
+ (coff_bfd_reloc_name_lookup): Define.
+ * coff-i960.c (coff_i960_reloc_name_lookup): New function.
+ (coff_bfd_reloc_name_lookup): Define.
+ * coff-m68k.c (m68k_reloc_name_lookup): New function.
+ (coff_bfd_reloc_name_lookup): Define.
+ * coff-maxq.c (maxq_reloc_name_lookup): New function.
+ (coff_bfd_reloc_name_lookup): Define.
+ * coff-mcore.c (mcore_coff_reloc_name_lookup): New function.
+ (coff_bfd_reloc_name_lookup): Define.
+ * coff-mips.c (mips_bfd_reloc_name_lookup): New function.
+ (_bfd_ecoff_bfd_reloc_name_lookup): Define.
+ * coff-ppc.c (ppc_coff_reloc_name_lookup): New function.
+ (coff_bfd_reloc_name_lookup): Define.
+ * coff-rs6000.c (coff_bfd_reloc_name_lookup): Define.
+ (_bfd_xcoff_reloc_name_lookup): New function.
+ (rs6000coff_vec, pmac_xcoff_vec): Init new field.
+ * coff-sh.c (coff_bfd_reloc_name_lookup): Define.
+ (sh_coff_reloc_name_lookup): New function.
+ * coff-sparc.c (coff_sparc_reloc_name_lookup): New function.
+ (coff_bfd_reloc_name_lookup): Define.
+ * coff-tic30.c (coff_bfd_reloc_name_lookup): Define.
+ (tic30_coff_reloc_name_lookup): New function.
+ * coff-tic4x.c (coff_bfd_reloc_name_lookup): Define.
+ (tic4x_coff_reloc_name_lookup): New function.
+ * coff-tic54x.c (coff_bfd_reloc_name_lookup): Define.
+ (tic54x_coff_reloc_name_lookup): New function.
+ * coff-x86_64.c (coff_bfd_reloc_name_lookup): Define.
+ (coff_amd64_reloc_name_lookup): New function.
+ * coff-z80.c (coff_z80_reloc_name_lookup): New function.
+ (coff_bfd_reloc_name_lookup): Define.
+ * coff-z8k.c (coff_z8k_reloc_name_lookup): New function.
+ (coff_bfd_reloc_name_lookup): Define.
+ * coff64-rs6000.c (coff_bfd_reloc_name_lookup): Define.
+ (xcoff64_reloc_name_lookup): New function.
+ (rs6000coff64_vec, aix5coff64_vec): Init new field.
+ * coffcode.h (coff_bfd_reloc_name_lookup): Define.
+ * elf-hppa.h (elf_hppa_reloc_name_lookup): New function.
+ * elf-m10200.c (bfd_elf32_bfd_reloc_name_lookup): New function.
+ * elf-m10300.c (bfd_elf32_bfd_reloc_name_lookup): New function.
+ * elf32-arc.c (bfd_elf32_bfd_reloc_name_lookup): New function.
+ * elf32-arm.c (elf32_arm_reloc_name_lookup): New function.
+ (bfd_elf32_bfd_reloc_name_lookup): Define.
+ * elf32-avr.c (bfd_elf32_bfd_reloc_name_lookup): New function.
+ * elf32-bfin.c (bfin_bfd_reloc_name_lookup): New function.
+ (bfd_elf32_bfd_reloc_name_lookup): Define.
+ * elf32-cr16c.c (elf_cr16c_reloc_name_lookup): New function.
+ (bfd_elf32_bfd_reloc_name_lookup): Define.
+ * elf32-cris.c (cris_reloc_name_lookup): New function.
+ (bfd_elf32_bfd_reloc_name_lookup): Define.
+ * elf32-crx.c (elf_crx_reloc_name_lookup): New function.
+ (bfd_elf32_bfd_reloc_name_lookup): Define.
+ * elf32-d10v.c (bfd_elf32_bfd_reloc_name_lookup): New function.
+ * elf32-d30v.c (bfd_elf32_bfd_reloc_name_lookup): New function.
+ * elf32-dlx.c (elf32_dlx_reloc_name_lookup): New function.
+ (bfd_elf32_bfd_reloc_name_lookup): Define.
+ * elf32-fr30.c (fr30_reloc_name_lookup): New function.
+ (bfd_elf32_bfd_reloc_name_lookup): Define.
+ * elf32-frv.c (frv_reloc_name_lookup): New function.
+ (bfd_elf32_bfd_reloc_name_lookup): Define.
+ * elf32-gen.c (bfd_elf32_bfd_reloc_name_lookup): Define.
+ * elf32-h8300.c (elf32_h8_reloc_name_lookup): New function.
+ (bfd_elf32_bfd_reloc_name_lookup): Define.
+ * elf32-hppa.c (bfd_elf32_bfd_reloc_name_lookup): Define.
+ * elf32-i370.c (i370_elf_reloc_name_lookup): New function.
+ (bfd_elf32_bfd_reloc_name_lookup): Define.
+ * elf32-i386.c (elf_i386_reloc_name_lookup): New function.
+ (bfd_elf32_bfd_reloc_name_lookup): Define.
+ * elf32-i860.c (elf32_i860_reloc_name_lookup): New function.
+ (bfd_elf32_bfd_reloc_name_lookup): Define.
+ * elf32-i960.c (elf32_i960_reloc_name_lookup): New function.
+ (bfd_elf32_bfd_reloc_name_lookup): Define.
+ * elf32-ip2k.c (ip2k_reloc_name_lookup): New function.
+ (bfd_elf32_bfd_reloc_name_lookup): Define.
+ * elf32-iq2000.c (iq2000_reloc_name_lookup): New function.
+ (bfd_elf32_bfd_reloc_name_lookup): Define.
+ * elf32-m32c.c (m32c_reloc_name_lookup): New function.
+ (bfd_elf32_bfd_reloc_name_lookup): Define.
+ * elf32-m32r.c (bfd_elf32_bfd_reloc_name_lookup): New function.
+ * elf32-m68hc11.c (bfd_elf32_bfd_reloc_name_lookup): New function.
+ * elf32-m68hc12.c (bfd_elf32_bfd_reloc_name_lookup): New function.
+ * elf32-m68k.c (reloc_name_lookup): New function.
+ (bfd_elf32_bfd_reloc_name_lookup): Define.
+ * elf32-m88k.c (bfd_elf32_bfd_reloc_name_lookup): Define.
+ * elf32-mcore.c (mcore_elf_reloc_name_lookup): New function.
+ (bfd_elf32_bfd_reloc_name_lookup): Define.
+ * elf32-mep.c (mep_reloc_name_lookup): New function.
+ (bfd_elf32_bfd_reloc_name_lookup): Define.
+ * elf32-mips.c (bfd_elf32_bfd_reloc_name_lookup): New function.
+ (mips_vxworks_bfd_reloc_name_lookup): Likewise.
+ (bfd_elf32_bfd_reloc_name_lookup): Define.
+ * elf32-msp430.c (bfd_elf32_bfd_reloc_name_lookup): New function.
+ * elf32-mt.c (mt_reloc_name_lookup): New function.
+ (bfd_elf32_bfd_reloc_name_lookup): Define.
+ * elf32-openrisc.c (openrisc_reloc_name_lookup): New function.
+ (bfd_elf32_bfd_reloc_name_lookup): Define.
+ * elf32-or32.c (bfd_elf32_bfd_reloc_name_lookup): New function.
+ * elf32-pj.c (pj_elf_reloc_name_lookup): New function.
+ (bfd_elf32_bfd_reloc_name_lookup): Define.
+ * elf32-ppc.c (ppc_elf_reloc_name_lookup): New function.
+ (bfd_elf32_bfd_reloc_name_lookup): Define.
+ * elf32-s390.c (elf_s390_reloc_name_lookup): New function.
+ (bfd_elf32_bfd_reloc_name_lookup): Define.
+ * elf32-score.c (elf32_score_reloc_name_lookup): New function.
+ (bfd_elf32_bfd_reloc_name_lookup): Define.
+ * elf32-sh.c (sh_elf_reloc_name_lookup): New function.
+ (bfd_elf32_bfd_reloc_name_lookup): Define.
+ * elf32-sparc.c (bfd_elf32_bfd_reloc_name_lookup): Define.
+ * elf32-spu.c (spu_elf_reloc_name_lookup): New function.
+ (bfd_elf32_bfd_reloc_name_lookup): Define.
+ * elf32-v850.c (v850_elf_reloc_name_lookup): New function.
+ (bfd_elf32_bfd_reloc_name_lookup): Define.
+ * elf32-vax.c (reloc_name_lookup): New function.
+ (bfd_elf32_bfd_reloc_name_lookup): Define.
+ * elf32-xc16x.c (xc16x_reloc_name_lookup): New function.
+ (bfd_elf32_bfd_reloc_name_lookup): Define.
+ * elf32-xstormy16.c (xstormy16_reloc_name_lookup): New function.
+ (bfd_elf32_bfd_reloc_name_lookup): Define.
+ * elf32-xtensa.c (elf_xtensa_reloc_name_lookup): New function.
+ (bfd_elf32_bfd_reloc_name_lookup): Define.
+ * elf64-alpha.c (elf64_alpha_bfd_reloc_name_lookup): New function.
+ (bfd_elf64_bfd_reloc_name_lookup): Define.
+ * elf64-gen.c (bfd_elf64_bfd_reloc_name_lookup): Define.
+ * elf64-hppa.c (bfd_elf64_bfd_reloc_name_lookup): Define.
+ * elf64-mips.c (bfd_elf64_bfd_reloc_name_lookup): New function.
+ * elf64-mmix.c (bfd_elf64_bfd_reloc_name_lookup): New function.
+ * elf64-ppc.c (ppc64_elf_reloc_name_lookup): New function.
+ (bfd_elf64_bfd_reloc_name_lookup): Define.
+ * elf64-s390.c (elf_s390_reloc_name_lookup): New function.
+ (bfd_elf64_bfd_reloc_name_lookup): Define.
+ * elf64-sh64.c (sh_elf64_reloc_name_lookup): New function.
+ (bfd_elf64_bfd_reloc_name_lookup): Define.
+ * elf64-sparc.c (bfd_elf64_bfd_reloc_name_lookup): Define.
+ * elf64-x86-64.c (elf64_x86_64_reloc_name_lookup): New function.
+ (bfd_elf64_bfd_reloc_name_lookup): Define.
+ * elfn32-mips.c (bfd_elf32_bfd_reloc_name_lookup): New function.
+ * elfxx-ia64.c (elfNN_ia64_reloc_name_lookup): New function.
+ (bfd_elfNN_bfd_reloc_name_lookup): Define.
+ * elfxx-sparc.c (_bfd_sparc_elf_reloc_name_lookup): New function.
+ * elfxx-sparc.h (_bfd_sparc_elf_reloc_name_lookup): Declare.
+ * i386msdos.c (msdos_bfd_reloc_name_lookup): Define.
+ * i386os9k.c (aout_32_bfd_reloc_name_lookup): Define.
+ * ieee.c (ieee_bfd_reloc_name_lookup): Define.
+ * libaout.h (NAME (aout, reloc_name_lookup)): Declare.
+ * libbfd-in.h (_bfd_norelocs_bfd_reloc_name_lookup): Declare.
+ * mipsbsd.c (MY_bfd_reloc_name_lookup): Define.
+ (MY(reloc_type_lookup)): Rename from MY(reloc_howto_type_lookup).
+ (MY(reloc_name_lookup)): New function.
+ * nlm-target.h (nlm_bfd_reloc_name_lookup): Define.
+ * oasys.c (oasys_bfd_reloc_name_lookup): Define.
+ * pdp11.c (NAME (aout, reloc_name_lookup)): New function.
+ * pe-mips.c (coff_mips_reloc_name_lookup): New function.
+ (coff_bfd_reloc_name_lookup): Define.
+ * reloc.c (bfd_reloc_name_lookup): New function.
+ * riscix.c (riscix_reloc_name_lookup): New function.
+ (MY_bfd_reloc_name_lookup): Define.
+ * som.c (som_bfd_reloc_name_lookup): New function.
+ * targets.c (struct bfd_target): Add reloc_name_lookup.
+ (BFD_JUMP_TABLE_RELOCS): Add NAME##_bfd_reloc_name_lookup.
+ * versados.c (versados_bfd_reloc_name_lookup): Define.
+ * vms.c (vms_bfd_reloc_name_lookup): New function.
+ * bfd-in2.h: Regenerate.
+ * libbfd.h: Regenerate.
+
+2007-03-26 Thiemo Seufer <ths@mips.com>
+
+ PR ld/4208
+ * elfxx-mips.c (mips_elf_next_relocation): Don't signal an error if no
+ matching relocation is found.
+ (_bfd_mips_elf_relocate_section): Only warn about missing relocations.
+
+2007-03-23 H.J. Lu <hongjiu.lu@intel.com>
+
+ * configure: Regenerated.
+
+2007-03-23 Joseph Myers <joseph@codesourcery.com>
+
+ * configure.in: Use ACX_PKGVERSION and ACX_BUGURL.
+ * configure: Regenerate.
+
+2007-03-23 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-spu.c (spu_stub_name): Don't put input section in stub name.
+ Remove input_sec param. Adjust all calls.
+ (write_one_stub): Adjust stub symbol.
+ (needs_ovl_stub): New function, extracted from..
+ (spu_elf_size_stubs): ..here.
+ (spu_elf_relocate_section): Use needs_ovl_stub.
+
+2007-03-22 Joseph Myers <joseph@codesourcery.com>
+
+ * Makefile.am (bfdver.h): Only set VERSION_PACKAGE in bfdver.texi
+ if nonempty.
+ * configure.in (REPORT_BUGS_TO): Do not use "URL:" prefix.
+ * Makefile.in, configure, doc/Makefile.in: Regenerate.
+
+2007-03-22 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/4210
+ * peXXigen.c (_bfd_XXi_swap_aouthdr_out): Use the virtual
+ address and virtual size of the last section for the image
+ size.
+
+2007-03-22 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/4007
+ * elf.c (assign_file_positions_for_load_sections): Check if
+ all sections are in the segment.
+
+2007-03-20 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/4208
+ * elfxx-mips.c (_bfd_mips_elf_relocate_section): Report missing
+ matching LO16 relocation for HI16 relocation.
+
+2007-03-20 Paul Brook <paul@codesourcery.com>
+
+ * bfd-in.h (bfd_elf32_arm_set_target_relocs): Update prototype.
+ * bfd-in2.h: Regenerate.
+ * elf32-arm.c (elf32_arm_link_hash_table): Add pic_veneer.
+ (record_arm_to_thumb_glue): Use globals->pic_veneer.
+ (elf32_arm_create_thumb_stub): Ditto.
+ (bfd_elf32_arm_set_target_relocs): Set globals->pic_veneer.
+
+2007-03-18 Mark Shinwell <shinwell@codesourcery.com>
+
+ * bfd-in.h (bfd_elf32_arm_set_target_relocs): Add "bfd *"
+ argument and extra last argument.
+ * bfd-in2.h: Regenerate.
+ * elf32-arm.c (elf32_arm_obj_tdata): Add no_enum_size_warning
+ member.
+ (bfd_elf32_arm_set_target_relocs): Add "bfd *" argument and
+ extra last argument. Set no_enum_size_warning appropriately.
+ (elf32_arm_merge_eabi_attributes): Improve enum sizes
+ diagnostic, suppressing it when no_enum_size_warning dictates.
+
+2007-03-20 Nick Clifton <nickc@redhat.com>
+
+ PR binutils/3535
+ * elf.c (copy_private_bfd_data): Widen the scope of Solaris
+ specific conditions that need the program headers to be
+ rewritten.
+
+2007-03-19 H.J. Lu <hongjiu.lu@intel.com>
+
+ * peXXigen.c (_bfd_XXi_swap_aouthdr_in): Store Magic,
+ MajorLinkerVersion, MinorLinkerVersion, SizeOfCode,
+ SizeOfInitializedData, SizeOfUninitializedData,
+ AddressOfEntryPoint, BaseOfCode and BaseOfData in internal
+ extra PE a.out header.
+ (IMAGE_NT_OPTIONAL_HDR_MAGIC): Defined as 0x10b if not defined.
+ (IMAGE_NT_OPTIONAL_HDR64_MAGIC): Defined as 0x20b if not
+ defined.
+ (IMAGE_NT_OPTIONAL_HDRROM_MAGIC): Defined as 0x107 if not
+ defined.
+ (_bfd_XX_print_private_bfd_data_common): Also print Magic,
+ MajorLinkerVersion, MinorLinkerVersion, SizeOfCode,
+ SizeOfInitializedData, SizeOfUninitializedData,
+ AddressOfEntryPoint, BaseOfCode and BaseOfData from internal
+ extra PE a.out header.
+
+2007-03-18 H.J. Lu <hongjiu.lu@intel.com>
+
+ * targets.c (_bfd_target_vector): Add bfd_efi_app_x86_64_vec
+ only if BFD64 is defined.
+
+2007-03-17 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-spu.c (spu_elf_size_stubs): Always use an overlay stub
+ on setjmp calls.
+
+2007-03-15 H.J. Lu <hongjiu.lu@intel.com>
+
+ * doc/Makefile.in: Regenerated.
+
+2007-03-15 H.J. Lu <hongjiu.lu@intel.com>
+
+ * Makefile.am (bfdver.h): Substitute report_bugs_to. Also
+ create doc/bfdver.texi.
+ * Makefile.in: Regenerated.
+
+ * configure.in (--with-bugurl): New option.
+ * configure: Regenerated.
+
+ * version.h (REPORT_BUGS_TO): New.
+
+2007-03-13 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR binutils/3826
+ * elf-bfd.h (elf_backend_data): Add elf_osabi.
+ (_bfd_elf_set_osabi): New.
+
+ * elf.c (_bfd_elf_set_osabi): New.
+
+ * elf32-hppa.c (elf32_hppa_post_process_headers): Removed.
+ (elf_backend_post_process_headers): Defined with
+ _bfd_elf_set_osabi.
+ (ELF_OSABI): Properly defined for each target.
+
+ * elf32-i370.c (i370_elf_post_process_headers): Removed.
+ (ELF_OSABI): Defined.
+ (elf_backend_post_process_headers): Defined with
+ _bfd_elf_set_osabi.
+
+ * elf32-i386.c (ELF_OSABI): Defined to ELFOSABI_FREEBSD for
+ freebsd.
+ (elf_i386_post_process_headers): Set EI_OSABI with elf_osabi.
+
+ * elf32-msp430.c (elf32_msp430_post_process_headers): Removed.
+ (ELF_OSABI): Defined.
+ (elf_backend_post_process_headers): Defined with
+ _bfd_elf_set_osabi.
+
+ * elf64-alpha.c (ELF_OSABI): Defined to ELFOSABI_FREEBSD for
+ freebsd.
+ (elf64_alpha_fbsd_post_process_headers): Set EI_OSABI with
+ elf_osabi.
+
+ * elf64-hppa.c (elf64_hppa_post_process_headers): Set EI_OSABI
+ with elf_osabi.
+ (ELF_OSABI): Properly defined for each target.
+ (elf_backend_post_process_headers): Defined with
+ _bfd_elf_set_osabi for Linux.
+
+ * elf64-sparc.c (elf64_sparc_fbsd_post_process_headers): Removed.
+ (ELF_OSABI): Defined to ELFOSABI_FREEBSD for freebsd.
+ (elf_backend_post_process_headers): Defined with
+ _bfd_elf_set_osabi.
+
+ * elf64-x86-64.c (elf64_x86_64_fbsd_post_process_headers): Removed.
+ (ELF_OSABI): Defined to ELFOSABI_FREEBSD for freebsd.
+ (elf_backend_post_process_headers): Defined with
+ _bfd_elf_set_osabi.
+
+ * elfcode.h (elf_object_p): Match the ELFOSABI_NONE ELF target
+ with any ELF target of the compatible machine for which we do not
+ have a specific backend.
+
+ * elfxx-ia64.c (elfNN_hpux_post_process_headers): Set EI_OSABI
+ with elf_osabi.
+
+ * elfxx-target.h (ELF_OSABI): Default to ELFOSABI_NONE.
+ (elfNN_bed): Initialize elf_osabi with ELF_OSABI.
+
+2007-03-08 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-v850.c (v850_elf_link_output_symbol_hook): Clean out
+ V850_OTHER_* bits.
+
+2007-03-08 Alan Modra <amodra@bigpond.net.au>
+
+ * Makefile.am (BFD64_BACKENDS): Add efi-app-x86_64.lo.
+ (BFD64_BACKENDS_CFILES): Add efi-app-x86_64.c.
+ Run "make dep-am".
+ * Makefile.in: Regenerate.
+ * po/SRC-POTFILES.in: Regenerate.
+
+2007-03-07 H.J. Lu <hongjiu.lu@intel.com>
+
+ * config.bfd (x86_64-*-freebsd*): Add bfd_efi_app_x86_64_vec.
+ (x86_64-*-kfreebsd*-gnu): Likewise.
+ (x86_64-*-netbsd*): Likewise.
+ (x86_64-*-openbsd*): Likewise.
+ (x86_64-*-linux-*): Likewise.
+
+ * configure.in: Support bfd_efi_app_x86_64_vec.
+ * configure: Regenerated.
+
+ * efi-app-x86_64.c: New file.
+
+ * targets.c (bfd_efi_app_x86_64_vec): New.
+ (_bfd_target_vector): Add bfd_efi_app_x86_64_vec.
+
+2007-03-07 Kai Tietz <kai.tietz@onevision.com>
+
+ * reloc.c (bfd_generic_get_relocated_section_contents): Remove
+ const for type reloc_howto_type.
+
+2007-03-07 Alan Modra <amodra@bigpond.net.au>
+
+ PR 3958
+ * elf-bfd.h (RELOC_FOR_GLOBAL_SYMBOL): No error on relocatable link.
+ (elf_discarded_section): Move..
+ * bfd-in.h: ..to here.
+ * bfd-in2.h: Regenerate.
+ * elflink.c (elf_link_input_bfd): Don't zap relocs against symbols
+ from discarded sections before relocate_section has done its job.
+ * reloc.c (bfd_generic_get_relocated_section_contents): Handle
+ relocs against symbols from discarded sections.
+ * elf-hppa.h (elf_hppa_howto_table): Set size. Set dst_mask on
+ SECREL32.
+ (elf_hppa_relocate_section): Handle relocatable link after setting
+ sec, sym, h etc. for final link. Squash error messages for
+ relocatable link. Clear section contents for relocs against
+ symbols in discarded sections, and zero reloc. Remove existing
+ zero r_symndx code.
+ * elf-m10200.c (mn10200_elf_relocate_section): Likewise.
+ * elf-m10300.c (mn10300_elf_relocate_section): Likewise.
+ * elf32-arm.c (elf32_arm_relocate_section): Likewise.
+ * elf32-avr.c (elf32_avr_relocate_section): Likewise.
+ * elf32-bfin.c (bfinfdpic_relocate_section): Likewise.
+ (bfin_relocate_section): Likewise.
+ * elf32-cr16c.c (elf32_cr16c_relocate_section): Likewise.
+ * elf32-cris.c (cris_elf_relocate_section): Likewise.
+ * elf32-crx.c (elf32_crx_relocate_section): Likewise.
+ * elf32-d10v.c (elf32_d10v_relocate_section): Likewise.
+ * elf32-fr30.c (fr30_elf_relocate_section): Likewise.
+ * elf32-frv.c (elf32_frv_relocate_section): Likewise.
+ * elf32-h8300.c (elf32_h8_relocate_section): Likewise.
+ * elf32-hppa.c (elf32_hppa_relocate_section): Likewise.
+ * elf32-i370.c (i370_elf_relocate_section): Likewise.
+ * elf32-i386.c (elf_i386_relocate_section): Likewise.
+ * elf32-i860.c (elf32_i860_relocate_section): Likewise.
+ * elf32-ip2k.c (ip2k_elf_relocate_section): Likewise.
+ * elf32-iq2000.c (iq2000_elf_relocate_section): Likewise.
+ * elf32-m32c.c (m32c_elf_relocate_section): Likewise.
+ * elf32-m32r.c (m32r_elf_relocate_section): Likewise.
+ * elf32-m68hc1x.c (elf32_m68hc11_check_relocs): Likewise.
+ * elf32-m68k.c (elf_m68k_relocate_section): Likewise.
+ * elf32-mcore.c (mcore_elf_relocate_section): Likewise.
+ * elf32-mep.c (mep_elf_relocate_section): Likewise.
+ * elf32-msp430.c (elf32_msp430_relocate_section): Likewise.
+ * elf32-mt.c (mt_elf_relocate_section): Likewise.
+ * elf32-openrisc.c (openrisc_elf_relocate_section): Likewise.
+ * elf32-ppc.c (ppc_elf_relocate_section): Likewise.
+ * elf32-s390.c (elf_s390_relocate_section): Likewise.
+ * elf32-score.c (_bfd_score_elf_relocate_section): Likewise.
+ * elf32-sh.c (sh_elf_relocate_section): Likewise.
+ * elf32-spu.c (spu_elf_relocate_section): Likewise.
+ * elf32-v850.c (v850_elf_relocate_section): Likewise.
+ * elf32-vax.c (elf_vax_relocate_section): Likewise.
+ * elf32-xc16x.c (elf32_xc16x_relocate_section): Likewise.
+ * elf32-xstormy16.c (xstormy16_elf_relocate_section): Likewise.
+ * elf32-xtensa.c (elf_xtensa_relocate_section): Likewise.
+ * elf64-alpha.c (elf64_alpha_relocate_section_r): Likewise.
+ (elf64_alpha_relocate_section): Likewise.
+ * elf64-mmix.c (mmix_elf_relocate_section): Likewise.
+ * elf64-ppc.c (ppc64_elf_relocate_section): Likewise.
+ * elf64-s390.c (elf_s390_relocate_section): Likewise.
+ * elf64-sh64.c (sh_elf64_relocate_section): Likewise.
+ * elf64-x86-64.c (elf64_x86_64_relocate_section): Likewise.
+ * elfxx-ia64.c (elfNN_ia64_relocate_section): Likewise.
+ * elfxx-mips.c (_bfd_mips_elf_relocate_section): Likewise.
+ * elfxx-sparc.c (_bfd_sparc_elf_relocate_section): Likewise.
+
+ * elf32-arm.c (elf32_arm_relocate_section): Always adjust section
+ symbols for relocatable link. Don't use always-zero st_value.
+ (elf_backend_rela_normal): Don't define.
+ * elf32-bfin.c (bfinfdpic_relocate_section): Use
+ RELOC_FOR_GLOBAL_SYMBOL.
+ * elf32-frv.c (elf32_frv_relocate_section): Likewise.
+ * elf32-d10v.c (elf32_d10v_relocate_section): Combine SEC_MERGE
+ section symbol adjustments with same for relocatable link.
+ * elf32-i386.c (elf_i386_relocate_section): Likewise.
+ * elf32-m68hc1x.c (m68hc11_get_relocation_value): Move..
+ (elf32_m68hc11_check_relocs): ..to here.
+ * elf32-score.c (score_elf_final_link_relocate): Remove zero
+ r_symndx code.
+ * elfxx-mips.c (mips_elf_calculate_relocation): Likewise.
+
+2007-03-07 Alan Modra <amodra@bigpond.net.au>
+
+ PR 4144
+ * elf.c (assign_file_positions_for_load_sections): Don't
+ adjust p_memsz for !SEC_LOAD section vma modulo page size.
+ Instead, use the same lma based adjustment for SEC_LOAD
+ sections.
+
+2007-03-01 Bob Wilson <bob.wilson@acm.org>
+
+ * elf32-xtensa.c (analyze_relocations): Zero src_count if not relaxing.
+ (find_relaxable_sections): Do not increment src_count for unknown
+ opcodes. Decode only once instead of calling is_l32r_relocation.
+ (compute_text_actions): Remove unused no_insn_move flag. Assert that
+ src_next matches src_count in relax_info.
+
+2007-03-01 Joseph Myers <joseph@codesourcery.com>
+
+ * Makefile.am (bfdver.h): Use "." not " " between version number
+ and date.
+ * Makefile.in: Regenerate.
+ * configure.in (PKGVERSION): Default to "(GNU Binutils) ".
+ * configure: Regenerate.
+
+2007-02-28 Nathan Sidwell <nathan@codesourcery.com>
+
+ * config.bfd (sh-*-uclinux, sh[12]-*-uclinux): New stanza.
+
+2007-02-27 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-spu.h (struct _ovl_stream): Make "start" and "end" const.
+ * elf32-spu.c (ovl_mgr_pread): Add const to casts.
+
+2007-02-23 Carlos O'Donell <carlos@codesourcery.com>
+
+ * dwarf2.c (_bfd_dwarf2_find_nearest_line): Assume 32-bit
+ DWARF even with 64-bit addresses.
+ (_bfd_dwarf2_find_nearest_line): Likewise.
+
+2007-02-23 Nick Clifton <nickc@redhat.com>
+
+ PR binutils/3535
+ * elf.c (copy_private_bfd_data): Always rewrite the program
+ headers when a Solaris interpreter segment is involved.
+
+2007-02-22 Paul Brook <paul@codesourcery.com>
+
+ * elflink.c (gc_mark_hook_fn): Remove.
+ (_bfd_elf_gc_mark): Rename gc_mark_hook_fn to elf_gc_mark_hook_fn.
+ (bfd_elf_gc_sections): Ditto. Call gc_mark_extra_sections.
+ * elf-bfd.h (elf_gc_mark_hook_fn): Define.
+ (elf_backend_data): Add gc_mark_extra_sections.
+ * elfxx-target.h (elf_backend_gc_mark_extra_sections): Provide default
+ definition.
+ (elfNN_bed): Add elf_backend_gc_mark_extra_sections.
+ * elf32-arm.c (elf32_arm_gc_mark_extra_sections): New function.
+ (elf_backend_gc_mark_extra_sections): Define.
+
+2007-02-21 Nick Clifton <nickc@redhat.com>
+
+ * elf.c (_bfd_elf_map_sections_to_segments): If the
+ override_segment_assignment callback is defined then call it.
+
+2007-02-21 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-spu.c (spu_elf_size_stubs): Correct order of warning args.
+
+2007-02-19 Thiemo Seufer <ths@mips.com>
+
+ * elfxx-mips.c (_bfd_mips_elf_print_private_bfd_data): Remove
+ translation marker from untranslatable strings.
+
+2007-02-19 Alan Modra <amodra@bigpond.net.au>
+
+ * elf-bfd.h (struct elf_backend_data): Add default_execstack.
+ * elflink.c (bfd_elf_size_dynamic_sections): Heed default_execstack.
+ * elfxx-target.h (elf_backend_default_execstack): Define to 1.
+ (elfNN_bed): Init new field.
+ * elf64-ppc.c (elf_backend_default_execstack): Define to 0.
+
+2007-02-17 Mark Mitchell <mark@codesourcery.com>
+ Nathan Sidwell <nathan@codesourcery.com>
+ Vladimir Prus <vladimir@codesourcery.com
+ Joseph Myers <joseph@codesourcery.com>
+
+ * configure.in (--with-pkgversion): New option.
+ * configure: Regenerate.
+ * Makefile.am (bfdver.h): Substitute for @bfd_version_package@.
+ * Makefile.in: Regenerate.
+ * version.h (BFD_VERSION_STRING): Define using
+ @bfd_version_package@.
+
+2007-02-16 Carlos O'Donell <carlos@codesourcery.com>
+
+ * elfxx-mips.c (_bfd_mips_elf_print_private_bfd_data):
+ Print EF_MIPS_NOREORDER, EF_MIPS_PIC, EF_MIPS_CPIC, EF_MIPS_XGOT
+ and EF_MIPS_UCODE.
+
+2007-02-15 Alan Modra <amodra@bigpond.net.au>
+
+ * libbfd-in.h (_bfd_norelocs_get_reloc_upper_bound): Don't define,
+ declare.
+ (_bfd_norelocs_canonicalize_reloc): Likewise.
+ * libbfd.h: Regenerate.
+ * libbfd.c (_bfd_norelocs_get_reloc_upper_bound): New function.
+ (_bfd_norelocs_canonicalize_reloc): Likewise.
+ * binary.c (binary_bfd_reloc_type_lookup): Don't define.
+ (binary_get_reloc_upper_bound, binary_canonicalize_reloc): Likewise.
+ (binary_vec): Use _bfd_norelocs in BFD_JUMP_TABLE_RELOCS.
+ * ihex.c: Similarly.
+ * mach-o-target.c: Similarly.
+ * mach-o.c: Similarly.
+ * mmo.c: Similarly.
+ * pef.c: Similarly.
+ * ppcboot.c: Similarly.
+ * srec.c: Similarly.
+ * xsym.c: Similarly.
+
+2007-02-14 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/3953
+ * elflink.c (_bfd_elf_add_default_symbol): Check warning symbol
+ when adding default symbol.
+
+2007-02-13 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (create_linkage_sections): Use section ".branch_lt"
+ for branch lookup table.
+
+2007-02-12 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (create_linkage_sections): Don't create
+ .rela.rodata.brlt for --emit-relocs.
+ (ppc_build_one_stub): Create relocs for brlt --emit-relocs here.
+ (ppc_size_one_stub): Count them. Simplify test of stub type
+ when counting stub relocs. Set SEC_RELOC too.
+ (ppc64_elf_size_stubs): Clear reloc_count and SEC_RELOC.
+ (ppc64_elf_finish_dynamic_sections): Output brlt relocs.
+
+2007-02-12 Alan Modra <amodra@bigpond.net.au>
+
+ * elflink.c (evaluate_complex_relocation_symbols): Ignore relocs
+ with a zero symbol index.
+
+2007-02-12 Alan Modra <amodra@bigpond.net.au>
+
+ * elflink.c (bfd_elf_discard_info): Tidy setting of "eh".
+
+2007-02-05 Dave Brolley <brolley@redhat.com>
+ Stan Cox <scox@redhat.com>
+
+ PR ld/3972
+ * elflink.c (elf_link_input_bfd): Always setup finfo->internal_syms.
+
+2007-02-05 Dave Brolley <brolley@redhat.com>
+ Richard Sandiford <rsandifo@redhat.com>
+ Stan Cox <scox@redhat.com>
+ Nick Clifton <nickc@redhat.com>
+ DJ Delorie <dj@redhat.com>
+ Frank Ch. Eigler <fche@redhat.com>
+ Ben Elliston <bje@redhat.com>
+ Richard Henderson <rth@redhat.com>
+
+ * Makefile.am (ALL_MACHINES): Add cpu-mep.lo.
+ (ALL_MACHINES_CFILES): Add CPU_MEP.c.
+ (BFD32_BACKENDS): Add elf32-mep.lo.
+ (BFD32_BACKENDS_CFILES): Add elf32-mep.c.
+ (cpu-mep.lo,elf32-mep.lo): New targets.
+ * archures.c (bfd_arch_mep): New enumerator.
+ (bfd_mach_mep, bfd_mach_mep_h1): New macros.
+ (bfd_mep_arch): New external variable.
+ (bfd_archures_list): Add bfd_mep_arch.
+ * config.bfd: Support mep-*-elf.
+ * configure.in: Support bfd_elf32_mep_vec and bfd_elf32_mep_little_vec.
+ * reloc.c (BFD_RELOC_MEP_*): New relocation numbers.
+ * targets.c (bfd_elf32_mep_vec,bfd_elf32_mep_little_vec): New extern
+ declarations.
+ (_bfd_target_vector): Add bfd_elf32_mep_vec and
+ bfd_elf32_mep_little_vec.
+ * mep-relocs.pl: New file.
+ * cpu-mep.c: New file.
+ * elf32-mep.c: New file.
+ * bfd-in2.h: Regenerate.
+ * po/POTFILES.in: Regenerate.
+ * libbfd.h: Regenerate.
+ * Makefile.in: Regenerate.
+ * configure: Regenerate.
+
+2007-02-05 Dave Brolley <brolley@redhat.com>
+
+ * elflink.c (evaluate_complex_relocation_symbols): Check for
+ STT_SRELC for global symbols.
+ (perform_complex_relocations): Renamed to
+ perform_complex_relocation and now examines only one relocation.
+ (elf_link_input_bfd): Don't call perform_complex_relocations.
+ * elf-bfd.h (bfd_elf_perform_complex_relocation_: New prototype.
+ * elf32-mep.c (mep_elf_howto_table): Add R_RELC.
+ (OD,OS,OU): #undefs corrected to N, S and U repectively.
+ (mep_reloc_type_lookup): Handle BFD_RELOC_RELC.
+ (complex_reloc_installation_howto): Removed.
+ (mep_info_to_howto_rela): Remove special case for r_type==0xff.
+ (mep_elf_relocate_section): Call bfd_elf_perform_complex_relocation.
+
+2007-02-05 Dave Brolley <brolley@redhat.com>
+ Richard Sandiford <rsandifo@redhat.com>
+ DJ Delorie <dj@redhat.com>
+ Graydon Hoare <graydon@redhat.com>
+ Nick Clifton <nickc@cambridge.redhat.com>
+ Jeff Holcomb <jeffh@redhat.com>
+ Frank Ch. Eigler <fche@redhat.com>
+
+ * elf-bfd.h (bfd_elf_perform_complex_relocations): New prototype.
+ * elf.c (swap_out_syms): Handle BSF_RELC and BSF_SRELC.
+ * elfcode.h (elf_slurp_symbol_table): Handle STT_RELC and STT_SRELC.
+ * elflink.c (set_symbolValue): New static function.
+ (resolve_symbol): Likewise.
+ (resolve_section): Likewise.
+ (undefined_reference): Likewise.
+ (eval_symbol): Likewise.
+ (evaluate_complex_relocation_symbols): Likewise.
+ (put_value): Likewise.
+ (get_value): Likewise.
+ (decode_complex_addend):
+ (bfd_elf_perform_complex_relocation): New function.
+ (elf_link_input_bfd): Call evaluate_complex_relocation_symbols.
+ * reloc.c (BFD_RELOC_RELC): New relocation number.
+ * syms.c (BSF_RELC,BSF_SRELC): New macros.
+
+2007-02-05 Bob Wilson <bob.wilson@acm.org>
+
+ * elf32-xtensa.c (elf_xtensa_make_sym_local): Delete.
+ (elf_xtensa_hide_symbol, elf_backend_hide_symbol): Delete.
+ (elf_xtensa_fix_refcounts, elf_xtensa_allocate_plt_size)
+ (elf_xtensa_allocate_got_size): Replace these with...
+ (elf_xtensa_allocate_dynrelocs): ...this new function.
+ (elf_xtensa_size_dynamic_sections): Use it.
+
+2007-02-05 Bob Wilson <bob.wilson@acm.org>
+
+ * elf32-xtensa.c (elf_howto_table) <R_XTENSA_GLOB_DAT>
+ <R_XTENSA_JMP_SLOT, R_XTENSA_RELATIVE, R_XTENSA_PLT, R_XTENSA_DIFF32>:
+ Set src_mask to zero.
+ <R_XTENSA_DIFF8, R_XTENSA_DIFF16>: Likewise. Also fix dst_mask.
+ <R_XTENSA_ASM_EXPAND>: Set pcrel_offset to TRUE.
+
+2007-02-02 Bob Wilson <bob.wilson@acm.org>
+
+ * elf32-xtensa.c (xtensa_elf_dynamic_symbol_p): Renamed to...
+ (elf_xtensa_dynamic_symbol_p): ...this.
+
+2007-02-02 Bob Wilson <bob.wilson@acm.org>
+
+ * elf32-xtensa.c (plt_reloc_count): Move into link hash table.
+ (struct elf_xtensa_link_hash_table): New.
+ (elf_xtensa_hash_table): New.
+ (elf_xtensa_link_hash_table_create): New.
+ (elf_xtensa_check_relocs): Update plt_reloc_count references.
+ Update arguments to add_extra_plt_sections.
+ (elf_xtensa_create_dynamic_sections): Record new sections in the hash
+ table. Update for plt_reloc_count and add_extra_plt_sections.
+ (add_extra_plt_sections, elf_xtensa_create_plt_entry): Replace dynobj
+ argument with link info. Update calls to elf_xtensa_get_plt_section
+ and elf_xtensa_get_gotplt_section.
+ (elf_xtensa_allocate_local_got_size, elf_xtensa_size_dynamic_sections)
+ (elf_xtensa_relocate_section, elf_xtensa_finish_dynamic_sections)
+ (elf_xtensa_discard_info_for_section, shrink_dynamic_reloc_sections)
+ (relax_property_section): Get sections from the hash table and update
+ function calls.
+ (elf_xtensa_get_plt_section, elf_xtensa_get_gotplt_section): Replace
+ dynobj argument with link info. Get sections for first plt chunk from
+ the hash table.
+ (bfd_elf32_bfd_link_hash_table_create): Define.
+
+2007-02-02 Jakub Jelinek <jakub@redhat.com>
+
+ * elf-bfd.h (struct elf_obj_tdata): Change symbuf type to void *.
+ * elf.c (struct elf_symbuf_symbol, struct elf_symbuf_head): New types.
+ (struct elf_symbol): Change first member into union.
+ (elf_sort_elf_symbol): Compare pointers to internal syms rather than
+ internal syms. Only compare st_shndx fields.
+ (elf_create_symbuf): New function.
+ (bfd_elf_match_symbols_in_sections): Use it. If symbufs are available
+ for bfds, use a binary search, otherwise don't qsort symbols
+ unnecessarily only to select which symbols are for the particular
+ shndx.
+
+2007-02-01 Nick Clifton <nickc@redhat.com>
+
+ PR ld/3852
+ * elf.c (_bfd_elf_link_hash_table_init): Initialize all the fields
+ in the elf_link_hash_table structure.
+
+2007-02-01 Alan Modra <amodra@bigpond.net.au>
+
+ * elf-bfd.h (struct elf_backend_data): Add elf_backend_write_core_note.
+ * elfxx-target.h (elf_backend_write_core_note): Define and use.
+ * elf.c (elfcore_write_prpsinfo): Call the above. Add support for
+ 32-bit core note on 64-bit target.
+ (elfcore_write_prstatus): Likewise.
+ (elfcore_write_lwpstatus): Make note_name const.
+ (elfcore_write_prfpreg): Likewise.
+ (elfcore_write_pstatus): Add support for 32-bit core note on 64-bit
+ target.
+ * elf32-ppc.c (ppc_elf_write_core_note): New function.
+ (elf_backend_write_core_note): Define.
+ * elf64-ppc.c (ppc64_elf_write_core_note): New function.
+ (elf_backend_write_core_note): Define.
+
+2007-01-31 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf32-cris.c (INCLUDED_TARGET_FILE): Removed.
+ (elf32_bed): Defined for elf32-us-cris.
+
+ * elf64-sh64.c (elf64_bed): Defined for Linux.
+ (INCLUDED_TARGET_FILE): Removed.
+
+ * elfxx-target.h (elfNN_bed): Always define. Don't check
+ INCLUDED_TARGET_FILE.
+
+2007-01-31 DJ Delorie <dj@redhat.com>
+
+ * elf-m10300.c (mn10300_elf_relocate_section): Clarify the warning
+ message for dangerous relocs, special case the common user error.
+
+2007-01-30 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf.c (copy_elf_program_header): Start from the first section
+ in a segment and stop when all sections in a segment are
+ accounted for.
+
+2007-01-29 Julian Brown <julian@codesourcery.com>
+
+ * bfd-in2.h: Regenerate.
+ * bfd-in.h (bfd_arm_vfp11_fix): New enum. Specify how VFP11
+ instruction scanning should be done.
+ (bfd_elf32_arm_init_maps, bfd_elf32_arm_vfp11_erratum_scan)
+ (bfd_elf32_arm_vfp11_fix_veneer_locations): Add prototypes.
+ (bfd_elf32_arm_set_target_relocs): Add vfp11 fix type argument to
+ prototype.
+ * elf-bfd.h (elf_backend_write_section): Add struct bfd_link_info
+ argument.
+ * elf32-arm.c (VFP11_ERRATUM_VENEER_SECTION_NAME)
+ (VFP11_ERRATUM_VENEER_ENTRY_NAME): Define macros.
+ (elf32_vfp11_erratum_type): New enum.
+ (elf32_vfp11_erratum_list): New struct. List of veneers or jumps to
+ veneers.
+ (_arm_elf_section_data): Add mapsize, erratumcount, erratumlist.
+ (elf32_arm_link_hash_table): Add vfp11_erratum_glue_size,
+ vfp11_fix and num_vfp11_fixes fields.
+ (elf32_arm_link_hash_table_create): Initialise vfp11_fix,
+ vfp11_erratum_glue_size, num_vfp11_fixes fields.
+ (VFP11_ERRATUM_VENEER_SIZE): Define. Size of an (ARM) veneer.
+ (bfd_elf32_arm_allocate_interworking_sections): Initialise erratum
+ glue section.
+ (elf32_arm_section_map_add): Add an code/data mapping symbol entry
+ to a section's map.
+ (record_vfp11_erratum_veneer): Create a single veneer, and its
+ associated symbols.
+ (bfd_elf32_arm_add_glue_sections_to_bfd): Add vfp11 erratum glue.
+ (bfd_elf32_arm_init_maps): Initialise mapping symbol table for input
+ BFDs.
+ (bfd_elf32_arm_set_vfp11_fix): Set the type of erratum workaround
+ required.
+ (bfd_arm_vfp11_pipe): Define VFP11 instruction pipes.
+ (bfd_arm_vfp11_regno): Recode a register number from a VFP11 insn.
+ (bfd_arm_vfp11_write_mask): Update write mask according to coded
+ register number.
+ (bfd_arm_vfp11_antidependency): New function.
+ (bfd_arm_vfp11_insn_decode): Decode a VFP11 insn.
+ (elf32_arm_compare_mapping): Declare.
+ (bfd_elf32_arm_vfp11_erratum_scan): Scan the sections of an input
+ BFD for potential erratum-triggering insns. Record results.
+ (bfd_elf32_arm_vfp11_fix_veneer_locations): Find out where veneers
+ and branches to veneers have been placed in virtual memory after
+ layout.
+ (bfd_elf32_arm_set_target_relocs): Set vfp11_fix field in global
+ hash table.
+ (elf32_arm_output_symbol_hook): Remove.
+ (elf32_arm_write_section): Output veneers, and branches to veneers.
+ Use maps from input sections, not output sections, for code
+ byte-swapping.
+ * elf32-ppc.c (ppc_elf_write_section): Add dummy link_info argument.
+ * elf32-score.c (_bfd_score_elf_write_section): Likewise.
+ * elfxx-mips.c (_bfd_mips_elf_write_section): Likewise.
+ * elfxx-mips.h (_bfd_mips_elf_write_section): Likewise.
+
+2007-01-27 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf64-hppa.c (elf64_bed): Defined for HPUX and Linux.
+ (INCLUDED_TARGET_FILE): Removed.
+
+2007-01-27 Mike Frysinger <vapier@gentoo.org>
+
+ * elf32-hppa.c (elf32_bed): Define for hpux, linux and netbsd.
+ (INCLUDED_TARGET_FILE): Remove.
+
+2007-01-25 DJ Delorie <dj@redhat.com>
+
+ * elf32-m32c.c (m32c_elf_howto_table): Don't complain about
+ R_M32C_16 or R_M32C_24 relocs.
+
+2007-01-25 Nick Clifton <nickc@redhat.com>
+
+ PR binutils/3874
+ * elf32-avr.c (avr_link_hash_table): Check to make sure that the
+ hash table was created by elf32_avr_link_hash_table_create before
+ using it.
+ (elf32_avr_link_hash_newfunc): New function. Just pass the call
+ through to _bfd_elf_link_hash_newfunc.
+ (elf32_avr_link_hash_table_create): Use
+ elf32_avr_link_hash_newfunc instead of
+ _bfd_elf_link_hash_newfunc.
+ (elf32_avr_relocate_section): Check for the hash table pointer
+ being NULL.
+ (elf32_avr_relax_section, avr_build_one_stub,
+ elf32_avr_setup_params, get_local_syms, elf32_avr_size_stubs,
+ elf32_avr_build_stubs): Likewise.
+
+2007-01-16 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/3831
+ * elf-bfd.h (bfd_elf_link_mark_dynamic_symbol): Add an
+ argument, Elf_Internal_Sym *.
+
+ * elflink.c (bfd_elf_link_mark_dynamic_symbol): Mark a data
+ symbol dynamic if info->dynamic_data is TRUE.
+ (bfd_elf_record_link_assignment): Updated call to
+ bfd_elf_record_link_assignment.
+ (_bfd_elf_merge_symbol): Likewise. Always call
+ bfd_elf_link_mark_dynamic_symbol.
+
+2007-01-12 H.J. Lu <hongjiu.lu@intel.com>
+
+ * Makefile.am (BFD_LIBS): Removed.
+ * Makefile.in: Regenerated.
+
+2007-01-11 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR binutils/3631
+ * Makefile.am (OFILES): Add @bfd64_libs@.
+ (libbfd_la_SOURCES): Remove $(BFD64_LIBS_CFILES).
+ * Makefile.in: Regenerated.
+
+ * configure.in (bfd_libs): Replaced by ...
+ (bfd64_libs): This.
+ * configure: Regenerated.
+
+2007-01-11 Nathan Sidwell <nathan@codesourcery.com>
+
+ * elf.c (assign_file_positions_for_load_sections): We can
+ require fewer phdrs than expected.
+
+2007-01-08 Kazu Hirata <kazu@codesourcery.com>
+
+ * archures.c (bfd_mach_cpu32_fido): Rename to bfd_mach_fido.
+ * bfd-in2.h: Regenerate.
+ * cpu-m68k.c (arch_info_struct): Use bfd_mach_fido instead of
+ bfd_mach_cpu32_fido.
+ (m68k_arch_features): Use fido_a instead of cpu32.
+ (bfd_m68k_compatible): Reject the combination of Fido and
+ ColdFire. Accept the combination of CPU32 and Fido with a
+ warning.
+ * elf32-m68k.c (elf32_m68k_object_p,
+ elf32_m68k_merge_private_bfd_data,
+ elf32_m68k_print_private_bfd_data): Treat Fido as an
+ architecture by itself.
+
+2007-01-08 Kai Tietz <kai.tietz@onevision.com>
+
+ * config.bfd: Renamed target x86_64-*-mingw64 to x86_64-*-mingw*.
+
+2007-01-05 Jakub Jelinek <jakub@redhat.com>
+
+ * texhex.c (first_phase): Don't fall through into the default
+ case.
+ (pass_over): Replace abort () calls with return FALSE. Fix
+ buffer overflow.
+
+2007-01-04 Jie Zhang <jie.zhang@analog.com>
+
+ * elf-eh-frame.c (_bfd_elf_discard_section_eh_frame): Don't set
+ SEC_EXCLUDE on zero size .eh_frame.
+
+For older changes see ChangeLog-2006
+
+Copyright (C) 2007 Free Software Foundation, Inc.
+
+Copying and distribution of this file, with or without modification,
+are permitted in any medium without royalty provided the copyright
+notice and this notice are preserved.
+
+Local Variables:
+mode: change-log
+left-margin: 8
+fill-column: 74
+version-control: never
+End:
diff --git a/bfd/ChangeLog-2008 b/bfd/ChangeLog-2008
new file mode 100644
index 0000000..b61a790
--- /dev/null
+++ b/bfd/ChangeLog-2008
@@ -0,0 +1,3392 @@
+2008-12-29 Arnold Metselaar <arnold.metselaar@planet.nl>
+
+ * coff-z80.c (r_imm32): Fix copy-paste bug that caused z80-objdump to
+ issue warnings about stabs debugging symbols rather than to show them.
+
+2008-12-23 Jon Beniston <jon@beniston.com>
+
+ * Makefile.am: Add LM32 object files and dependencies.
+ * Makefile.in: Regenerate.
+ * archures.c: Add LM32 architechiture info.
+ * targets.c: Likewise.
+ * reloc.c: Likewise.
+ * bfd-in2.h: Regenerate.
+ * config.bfd: Add LM32 targets.
+ * configure.in: Likewise.
+ * configure: Regenerate.
+ * cpu-lm32.c: New file.
+ * elf32-lm32.c: New file.
+
+2008-12-23 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/7036
+ * elfxx-ia64.c (elfNN_ia64_relax_section): Assume linker will
+ always insert 32byte between the .plt and .text sections after
+ the first relaxation pass.
+
+2008-12-23 Nick Clifton <nickc@redhat.com>
+
+ PR 7093
+ * elf32-arm.c (bfd_elf32_arm_init_maps): Only process ARM ELF
+ object files.
+
+2008-12-23 Tristan Gingold <gingold@adacore.com>
+
+ * mach-o.c (bfd_mach_o_make_bfd_section): Use the standard ELF name
+ .eh_frame for __TEXT.__eh_frame so that it is recognized by gdb.
+ Use shorter sections name for well known sections.
+ (bfd_mach_o_scan_read_dylinker): Only put dylinker name in the
+ section content.
+ (bfd_mach_o_scan_read_segment): Use shorter sections name for
+ well known segments.
+ (bfd_mach_o_scan_read_command): Ignore some new commands.
+ (bfd_mach_o_openr_next_archived_file): Use more descriptive names
+ for members filename.
+ (bfd_mach_o_fat_extract): New function to easily extract members
+ of a fat binary.
+ * mach-o.h (bfd_mach_o_load_command_type): Add new constants.
+ (bfd_mach_o_dylinker_command): Fix comment and reindent.
+ (bfd_mach_o_fat_extract): New prototype.
+
+2008-12-23 Johan Olmutz Nielsen <jnielsen@ddci.com>
+
+ * coffcode.h (coff_write_object_contents): Always initialise
+ section.s_page.
+
+2008-12-23 Andreas Schwab <schwab@suse.de>
+
+ * elf32-m68k.c (elf_m68k_discard_copies): Use SYMBOL_CALLS_LOCAL.
+ (elf_m68k_relocate_section): Use SYMBOL_CALLS_LOCAL and
+ SYMBOL_REFERENCES_LOCAL.
+ (elf_m68k_relocate_section): Likewise.
+
+2008-12-23 Nick Clifton <nickc@redhat.com>
+
+ * elf-bfd.h (struct bfd_elf_section_data): Remove indirect_relocs
+ field.
+ (_bfd_elf_make_ifunc_reloc_section): Remove prototype.
+ * elf.c (swap_out_syms): Remove STT_IFUNC support.
+ (elf_find_function): Likewise.
+ * elf32-arm.c (arm_elf_find_function): Likewise.
+ (elf32_arm_adjust_dynamic_symbol): Likewise.
+ (elf32_arm_swap_symbol_in): Likewise.
+ (elf32_arm_is_function_type): Likewise.
+ * elf32-i386.c (is_indirect_symbol): Delete.
+ (elf_i386_check_relocs): Remove STT_IFUNC support.
+ (allocate_dynrelocs): Likewise.
+ (elf_i386_relocate_section): Likewise.
+ * elf64-x86-64.c (is_indirect_symbol): Delete.
+ (elf64_x86_64_check_relocs): Remove STT_IFUNC support.
+ (allocate_dynrelocs): Likewise.
+ (elf64_x86_64_relocate_section): Likewise.
+ * elfcode.h (elf_slurp_symbol_table): Likewise.
+ * elflink.c (_bfd_elf_adjust_symbol): Likewise.
+ (get_ifunc_reloc_section_name): Delete.
+ (_bfd_elf_make_ifunc_reloc_section): Delete.
+ * syms.c (BSF_INDIRECT_FUNCTION): Delete.
+ (bfd_print_symbol_vandf): Remove STT_IFUNC support.
+ (bfd_decode_symclass): Likewise.
+ * bfd-in2.h: Regenerate.
+
+2008-12-20 Hans-Peter Nilsson <hp@axis.com>
+
+ * elf32-cris.c (cris_elf_howto_table): Add entry for R_CRIS_32_IE.
+ (cris_reloc_map): Similarly.
+ (cris_elf_relocate_section, cris_elf_gc_sweep_hook)
+ (cris_elf_check_relocs): Handle R_CRIS_32_IE.
+ * reloc.c (bfd_reloc_code_type): Add entry for R_CRIS_32_IE.
+ * bfd-in2.h, libbfd.h: Regenerate.
+
+2008-12-18 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
+
+ * configure: Regenerate.
+
+2008-12-17 Hans-Peter Nilsson <hp@axis.com>
+
+ * elf32-cris.c (elf_cris_copy_indirect_symbol): Return without
+ action for symbols other than bfd_link_hash_indirect.
+ (cris_elf_relocate_section) <R_CRIS_8, R_CRIS_16, R_CRIS_32>: Add missing
+ gate h != NULL for h->def_regular test.
+
+2008-12-15 Hans-Peter Nilsson <hp@axis.com>
+
+ * elf32-cris.c (elf_cris_copy_indirect_symbol): New function.
+ (elf_backend_copy_indirect_symbol): Define to above.
+
+ * elf32-cris.c (struct elf_cris_pcrel_relocs_copied): New member
+ r_type. Fix formatting.
+ (cris_elf_relocate_section) <R_CRIS_8_PCREL, R_CRIS_16_PCREL>
+ <R_CRIS_32_PCREL>: Also break early if the symbol doesn't get
+ emitted as a dynamic one.
+ (cris_elf_check_relocs) <R_CRIS_7, R_CRIS_16, R_CRIS_32>: Fork
+ from PCREL relocs code and simplify; don't fall through.
+ <R_CRIS_8_PCREL, R_CRIS_16_PCREL, R_CRIS_32_PCREL>: Simplify for
+ pcrel only. For non-local or overridable symbols in a DSO, always
+ keep count of relocs, not just when -Bsymbolic. Don't emit
+ message nor mark as TEXTREL here.
+ (elf_cris_discard_excess_dso_dynamics): Emit warning and mark as
+ TEXTREL here, if there are nondiscarded pcrel relocs.
+
+ * elf32-cris.c (elf_cris_got_elt_size) <symtab_hdr>: Initialize
+ using ibfd, not abfd.
+
+2008-12-11 Alan Modra <amodra@bigpond.net.au>
+
+ PR 7041
+ * elf64-ppc.c (func_desc_adjust): Correct logic making fake function
+ descriptors. Similarly correct making function descriptors dynamic.
+
+2008-12-10 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-spu.h (struct spu_elf_params): Add num_regions.
+ * elf32-spu.c (spu_elf_auto_overlay): Handle multiple overlay regions.
+
+2008-12-10 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-spu.g (struct spu_elf_params, enum _ovly_flavour): New.
+ (spu_elf_setup): Declare.
+ (spu_elf_create_sections, spu_elf_size_stubs): Update prototype.
+ (spu_elf_build_stubs, spu_elf_check_vma): Likewise.
+ * elf32-spu.c (struct spu_link_hash_table): Add "params". Remove
+ various other fields now in "params". Adjust code throughout.
+ (struct call_info, struct function_info): Move earlier in file.
+ (struct spu_elf_stack_info): Likewise.
+ (spu_elf_setup): New function.
+ (spu_elf_create_sections): Remove args other than "info".
+ (spu_elf_size_stubs, spu_elf_build_stubs, spu_elf_check_vma): Likewise.
+ (maybe_needs_stubs): Remove "output_bfd" arg. Adjust all calls.
+ (interesting_section): Similarly with "obfd" arg.
+ (needs_ovl_stub): Adjust output_section test.
+ (allocate_spuear_stubs): Likewise.
+ (OVL_STUB_SIZE): Don't define.
+ (ovl_stub_size): New function, use in place of OVL_STUB_SIZE.
+ (build_stub): Test params->ovly_flavour rather than OVL_STUB_SIZE.
+ (spu_elf_auto_overlay): Remove args other than "info". Make use
+ of size returned from spu_elf_load_ovl_mgr.
+ (spu_elf_stack_analysis): Remove args other than "info".
+ (spu_elf_relocate_section): Tidy setting of "ea".
+
+2008-12-10 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-spu.c (find_function_stack_adjust): Don't limit number
+ of insns scanned. Correct sp tests. Handle "fsmbi" and "andbi".
+ (mark_detached_root): New function.
+ (build_call_tree): Call it.
+ (sort_calls): Don't do void* arithmetic.
+ (define_ovtab_symbol): Don't abort on symbols defined in linker scripts.
+ (discover_functions): Consider STT_SECTION symbols too.
+ (collect_lib_sections): Don't cut short call tree traversal
+ when function size is too large.
+
+2008-12-09 Tom Tromey <tromey@redhat.com>
+
+ * pef.c (bfd_pef_parse_traceback_table): Add parens to placate gcc
+ 4.4.
+
+2008-12-09 Tristan Gingold <gingold@adacore.com>
+
+ * cpu-avr.c (compatible): Makes avr-6 compatible only with itself.
+
+2008-12-04 Andreas Krebbel <Andreas.Krebbel@de.ibm.com>
+
+ * elf64-s390.c (elf_s390_check_relocs): Initialize
+ htab->elf.dynobj if necessary.
+
+2008-12-03 Nick Clifton <nickc@redhat.com>
+
+ * syms.c (struct bfd_symbol): Add new flag BSF_INDIRECT_FUNCTION.
+ Remove redundant flag BFD_FORT_COMM_DEFAULT_VALUE. Renumber flags
+ to remove gaps.
+ (bfd_print_symbol_vandf): Return 'i' for BSF_INDIRECT_FUNCTION.
+ (bfd_decode_symclass): Likewise.
+ * elf.c (swap_out_syms): Translate BSF_INDIRECT_FUNCTION into
+ STT_IFUNC.
+ (elf_find_function): Treat STT_IFUNC in the same way as STT_FUNC.
+ (_bfd_elf_is_function_type): Likewise.
+ * elf32-arm.c (arm_elf_find_function): Likewise.
+ (elf32_arm_adjust_dynamic_symbol): Likewise.
+ (elf32_arm_swap_symbol_in): Likewise.
+ (elf32_arm_additional_program_headers): Likewise.
+ * elf32-i386.c (is_indirect_symbol): New function.
+ (elf_i386_check_relocs): Also generate dynamic relocs for
+ relocations against STT_IFUNC symbols.
+ (allocate_dynrelocs): Likewise.
+ (elf_i386_relocate_section): Likewise.
+ * elf64-x86-64.c (is_indirect_symbol): New function.
+ (elf64_x86_64_check_relocs): Also generate dynamic relocs for
+ relocations against STT_IFUNC symbols.
+ (allocate_dynrelocs): Likewise.
+ (elf64_x86_64_relocate_section): Likewise.
+ * elfcode.h (elf_slurp_symbol_table): Translate STT_IFUNC into
+ BSF_INDIRECT_FUNCTION.
+ * elflink.c (_bfd_elf_adjust_dynamic_reloc_section): Add support
+ for STT_IFUNC symbols.
+ (get_ifunc_reloc_section_name): New function.
+ (_bfd_elf_make_ifunc_reloc_section): New function.
+ * elf-bfd.h (struct bfd_elf_section_data): Add indirect_relocs field.
+ * bfd-in2.h: Regenerate.
+
+2008-12-02 Tristan Gingold <gingold@adacore.com>
+
+ * config.bfd: Add x86_64-*-darwin*
+
+2008-11-28 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ * hpux-core.c: Don't include sys/file.h.
+
+2008-11-28 Joshua Kinard <kumba@gentoo.org>
+
+ * aoutx.h (NAME): Add case statements for bfd_mach_mips14000,
+ bfd_mach_mips16000.
+ * archures.c (bfd_architecture): Add .#defines for bfd_mach_mips14000,
+ bfd_mach_mips16000.
+ * bfd-in2.h: Regenerate.
+ * cpu-mips.c: Add enums I_mips14000, I_mips16000.
+ (arch_info_struct): Add refs to R14000, R16000.
+ * elfxx-mips.c (mips_set_isa_flags): Handle bfd_mach_mips14000,
+ bfd_mach_mips16000.
+ (mips_mach_extensions): Map R14000, R16000 to R10000.
+
+2008-11-27 M R Swami Reddy <MR.Swami.Reddy@nsc.com>
+
+ * Add PIC support for CR16 target.
+ * elf32-cr16.c (R_CR16_GOT_REGREL20, R_CR16_GOTC_REGREL20 and
+ R_CR16_GLOB_DAT): New macros
+ (cr16_elf_howto_table): Add entries for for R_CR16_GOT_REGREL20,
+ R_CR16_GOTC_REGREL20 and R_CR16_GLOB_DAT.
+ (cr16_reloc_map): Ditto
+ (_bfd_cr16_elf_create_got_section): New function to create GOT section.
+ (_bfd_cr16_elf_create_dynamic_sections): New function to create dynamic
+ section.
+ (_bfd_cr16_elf_adjust_dynamic_symbol): New function to adjust symbol
+ defined by dynamic object.
+ (_bfd_cr16_elf_size_dynamic_sections): New function to find the size of
+ dynamic sections.
+ (_bfd_cr16_elf_finish_dynamic_symbol): New function to handle dynamic
+ symbols.
+ (_bfd_cr16_elf_finish_dynamic_symbol): New function to handle dynamic
+ sections.
+ (bfd_cr16_elf32_create_embedded_relocs): New function to create
+ embedded relocs in .emreloc section in memory for .data.rel section.
+ (_bfd_cr16_elf_reloc_type_class): New function for classify reloc types.
+ (cr16_elf_check_relocs): New function for checking reloc types in first
+ phase.
+ (cr16_elf_final_link_relocate): Update for handling the new reloc types
+ R_CR16_GOT_REGREL20 and R_CR16_GOTC_REGREL20.
+ (elf32_cr16_relax_section): Update relax implementation.
+ * reloc.c (bfd_reloc_code_type): Add entries for R_CR16_GOT_REGREL20,
+ R_CR16_GOTC_REGREL20 and R_CR16_GLOB_DAT.
+ * bfd-in.h (bfd_boolean bfd_cr16_elf32_create_embedded_relocs): Declared
+ * libbfd.h, bfd-in2.h: Regenerate.
+
+2008-11-26 Alan Modra <amodra@bigpond.net.au>
+
+ PR 7047
+ * configure.in: Bump version.
+ * configure: Regenerate.
+ * elflink.c (_bfd_elf_link_assign_sym_version): Continue matching
+ against version nodes when a global match is a wildcard. Similarly
+ continue matching on local wildcard matches, rather than only
+ continuing for "*". Have any global wildcard match override a
+ local wildcard match. Correct logic hiding unversioned symbol.
+ (bfd_elf_size_dynamic_sections): Update for changes to struct
+ bfd_elf_version_expr.
+
+2008-11-25 Joel Brobecker <brobecker@adacore.com>
+
+ * configure.in: Deactivate large-file support on native x86-solaris
+ as well unless the user explicitly requested it.
+ * configure: Regenerate.
+
+2008-11-25 Joseph Myers <joseph@codesourcery.com>
+
+ * elf32-arm.c (elf32_arm_final_link_relocate): Do not turn
+ branches to undefine weak symbols into branches to the next
+ instruction if creating PLT entries for those symbols.
+
+2008-11-25 Nick Clifton <nickc@redhat.com>
+
+ * elflink.c (is_reloc_section): New function. Returns true if the
+ given name matches the name of the reloc-containing section
+ associated with the given section.
+ (get_dynamic_reloc_section_name): New function. Computes the name
+ of the section that contains the dynamic relocs associated with
+ the given section.
+ (_bfd_elf_get_dynamic_reloc_section): New function. Returns a
+ pointer to the section containing the dynamic relocs associated
+ with the given section.
+ (_bfd_elf_make_dynamic_reloc_section): New function. Creates a
+ section to contain the dynamic relocs associated with a given
+ section.
+ * elf-bfd.h: Prototype the new functions.
+ * elf-m10300.c (mn10300_elf_check_relocs): Use new functions.
+ (mn10300_elf_final_link_relocs): Likewise.
+ * elf32-arm.c (reloc_section_p): Delete - replaced by new
+ functions.
+ (elf32_arm_final_link_relocate): Use new functions.
+ (elf32_arm_check_relocs): Likewise.
+ * elf32-cris.c (cris_elf_relocate_section): Likewise.
+ (elf_cris_check_relocs): Likewise.
+ * elf32-hppa.c (elf32_hppa_check_relocs): Likewise.
+ * elf32-i370.c (i370_elf_check_relocs): Likewise.
+ (i370_elf_relocate_section): Likewise.
+ * elf32-i386.c (elf_i386_check_relocs): Likewise.
+ * elf32-m32r.c (m32r_elf_relocate_section): Likewise.
+ (m32r_elf_check_relocs): Likewise.
+ * elf32-m68k.c (elf_m68k_check_relocs): Likewise.
+ * elf32_ppc.c (ppc_elf_check_relocs): Likewise.
+ (ppc_elf_relocate_section): Likewise.
+ * elf32-s390.c (elf_s390_check_relocs): Likewise.
+ * elf32-sh.c (sh_elf_relocate_section): Likewise.
+ (sh_elf_check_relocs): Likewise.
+ * elf32-vax.c (elf_vax_check_relocs): Likewise.
+ (elf_vax_relocate_section): Likewise.
+ * elf64-alpha.c (elf64_alpha_check_relocs): Likewise.
+ * elf64-ppc.c (ppc64_elf_check_relocs): Likewise.
+ * elf64-s390.c (elf_s390_check_relocs): Likewise.
+ * elf64-sh64.c (sh_elf64_relocate_section): Likewise.
+ * elf64-x86-64.c (elf64_x86_64_check_relocs): Likewise.
+ * elfxx-sparc.c (_bfd_sparc_elf_check_relocs): Likewise.
+ * elf32-bfin.c (bfin_check_relocs): Remove redundant local
+ variable 'sreloc'.
+ (bfin_relocate_section): Likewise.
+ * elf32-v850.c (v850_elf_check_relocs): Likewise.
+
+2008-11-23 Hans-Peter Nilsson <hp@axis.com>
+
+ Implement TLS for CRIS.
+ * elf32-cris.c: Include limits.h.
+ (TLSHOWTO16): Redefine in terms of and move contents to...
+ (TLSHOWTO16X): New macro.
+ (TLSHOWTO16S, LGOT_REG_NDX, LGOT_DTP_NDX, LGOT_ALLOC_NELTS_FOR)
+ (elf_cris_hash_entry): New macros.
+ (cris_elf_howto_table): Make R_CRIS_16_DTPREL,
+ R_CRIS_16_GOT_TPREL, R_CRIS_16_TPREL check overflow for signed,
+ not unsigned values.
+ (cris_info_to_howto_rela): Make r_type a enum elf_cris_reloc_type,
+ not unsigned int.
+ (struct elf_cris_link_hash_entry): New members reg_got_refcount,
+ tprel_refcount, and dtp_refcount.
+ (struct elf_cris_link_hash_table): New member dtpmod_refcount.
+ (elf_cris_link_hash_newfunc): Initialize new members.
+ (elf_cris_link_hash_table_create): Similar.
+ (cris_final_link_relocate, elf_cris_reloc_type_class): Use a
+ temporary variable when testing the relocation type.
+ (cris_elf_gc_mark_hook): Ditto. Add default case where needed.
+ (cris_elf_gc_sweep_hook): Ditto. Handle reference-counting for
+ the new assembly-generated relocs. Rewrite refcount handling to
+ set temporary variables to pointers to reloc-specific variables
+ and entry size and common code for the update.
+ (additional_relocation_error_msg_count): New variable.
+ (cris_elf_relocate_section): Use a function-local variable srelgot
+ for the .rela.got section instead of looking it up for every need.
+ Make r_type a enum elf_cris_reloc_type, not int. Actually set
+ symname for non-local symbols. Handle new assembly-generated
+ relocs. For overflow, emit additional messages for the new 16-bit
+ relocs as well as R_CRIS_16_GOTPLT and R_CRIS_16_GOT.
+ (elf_cris_finish_dynamic_symbol): Use elf_cris_finish_dynamic_symbol
+ instead of plain casts. Check new hash entry member
+ reg_got_refcount when checking whether to emit a GOT entry.
+ (elf_cris_finish_dynamic_sections): Update head comment to warn
+ about emitting relocs here. Use a temporary variable when testing
+ the relocation type.
+ (elf_cris_discard_excess_program_dynamics)
+ (elf_cris_adjust_gotplt_to_got): Handle reference counting change
+ regarding h->reg_got_refcount.
+ (cris_elf_check_relocs): Rewrite refcount handling to set
+ temporary variables and entry size and common code for the update
+ for local symbols. Use new macro elf_cris_hash_entry. Adjust
+ allocation for change in reference counting of GOT entries for
+ local symbols.
+ (elf_cris_size_dynamic_sections): Adjust calculated size of
+ .got.plt and .rela.got if we need a GOT entry for a
+ R_CRIS_DTPMOD relocation.
+ (elf_cris_got_elt_size): New function.
+ (elf_backend_got_elt_size): Define.
+
+2008-11-21 Sterling Augustine <sterling@tensilica.com>
+
+ * xtensa-isa.c (xtensa_state_is_shared_or): New function.
+
+2008-11-21 Hans-Peter Nilsson <hp@axis.com>
+
+ * elf-bfd.h (struct elf_backend_data): New member got_elt_size.
+ (_bfd_elf_default_got_elt_size): Declare.
+ * elflink.c (struct alloc_got_off_arg): Replace member got_elt_size
+ by new member info.
+ (elf_gc_allocate_got_offsets): Adjust for calling bed->got_elt_size
+ to get the element size instead of using a gofarg entry.
+ (bfd_elf_gc_common_finalize_got_offsets): Similar.
+ (_bfd_elf_default_got_elt_size): New function.
+ * elfxx-target.h: New macro elf_backend_got_elt_size.
+ (elfNN_bed): Use it.
+
+2008-11-20 Tristan Gingold <gingold@adacore.com>
+
+ * bfdwin.c: Fix comment.
+
+2008-11-20 Tristan Gingold <gingold@adacore.com>
+
+ * bfd.c (is32bit): Use architecture information for non-ELF
+ targets.
+
+2008-11-20 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-ppc.c (allocate_dynrelocs): Always use tlsld_got for
+ TLS_LD even when symbol is used with other TLS reloc types.
+ (ppc_elf_relocate_section): Bypass symbol checks when using tlsld_got.
+ Leave addend zero on LD DTPMOD dynamic reloc.
+
+2008-11-19 Bob Wilson <bob.wilson@acm.org>
+
+ * xtensa-modules.c (sysregs): Add MMID, VECBASE, EPC5, EPC6, EPC7,
+ EXCSAVE5, EXCSAVE6, EXCSAVE7, EPS5, EPS6, EPS7, CPENABLE,
+ SCOMPARE1, and THREADPTR registers.
+ (NUM_SYSREGS, MAX_USER_REG): Update.
+ (states): Change width of INTERRUPT, WindowBase, WindowStart, and
+ INTENABLE. Add VECBASE, EPC5, EPC6, EPC7, EXCSAVE5, EXCSAVE6,
+ EXCSAVE7, EPS6, EPS6, EPS7, THREADPTR, CPENABLE, and SCOMPARE1 states.
+ (NUM_STATES): Update.
+ (enum xtensa_state_id): Add entries for new states.
+ (enum xtensa_field_id): Add entries for xt_wbr15_imm and xt_wbr18_imm
+ fields, along with functions to extract and set them.
+ (regfiles): Change number of AR registers to 32.
+ (Operand_ar0_encode, Operand_ar4_encode, Operand_ar8_encode,
+ Operand_ar12_encode, Operand_ars_entry_encode): Update register mask.
+ (operands): Add entries for tp7, xt_wbr15_label, xt_wbr18_label,
+ xt_wbr15_imm, and xt_wbr18_imm operands, along with functions to
+ encode and decode them.
+ (enum xtensa_operand_id): Add entries for new operands.
+ (Iclass_xt_iclass_rfi_stateArgs): Add EPC5, EPC6, EPC7, EPS5, EPS6, and
+ EPC7 states.
+ (Iclass_xt_iclass_rfdo_stateArgs): Replace EPC4 and EPS4 by EPC6 and
+ EPS6, respectively.
+ (iclasses): Add entries for rur_threadptr, wur_threadptr,
+ xt_iclass_wsr_176, xt_iclass_rsr_epc5, xt_iclass_wsr_epc5,
+ xt_iclass_xsr_epc5, xt_iclass_rsr_excsave5, xt_iclass_wsr_excsave5,
+ xt_iclass_xsr_excsave5, xt_iclass_rsr_epc6, xt_iclass_wsr_epc6,
+ xt_iclass_xsr_epc6, xt_iclass_rsr_excsave6, xt_iclass_wsr_excsave6,
+ xt_iclass_xsr_excsave6, xt_iclass_rsr_epc7, xt_iclass_wsr_epc7,
+ xt_iclass_xsr_epc7, xt_iclass_rsr_excsave7, xt_iclass_wsr_excsave7,
+ xt_iclass_xsr_excsave7, xt_iclass_rsr_eps5, xt_iclass_wsr_eps5,
+ xt_iclass_xsr_eps5, xt_iclass_rsr_eps6, xt_iclass_wsr_eps6,
+ xt_iclass_xsr_eps6, xt_iclass_rsr_eps7, xt_iclass_wsr_eps7,
+ xt_iclass_xsr_eps7, xt_iclass_rsr_vecbase, xt_iclass_wsr_vecbase,
+ xt_iclass_xsr_vecbase, xt_iclass_mul16, xt_iclass_wsr_mmid,
+ xt_iclass_icache_lock, xt_iclass_dcache_lock, xt_iclass_rsr_cpenable,
+ xt_iclass_wsr_cpenable, xt_iclass_xsr_cpenable, xt_iclass_clamp,
+ xt_iclass_minmax, xt_iclass_sx, xt_iclass_l32ai, xt_iclass_s32ri,
+ xt_iclass_s32c1i, xt_iclass_rsr_scompare1, xt_iclass_wsr_scompare1,
+ xt_iclass_xsr_scompare1, xt_iclass_div, and xt_iclass_mul32, along
+ with corresponding argument and state argument arrays. Change
+ number of state arguments for xt_iclass_rfi. Add arguments for
+ xt_iclass_rfdo.
+ (enum xtensa_iclass_id): Add entries for new iclasses.
+ (opcodes): Add entries for RUR_THREADPTR, WUR_THREADPTR, WSR_176,
+ RSR_EPC5, WSR_EPC5, XSR_EPC5, RSR_EXCSAVE5, WSR_EXCSAVE5, XSR_EXCSAVE5,
+ RSR_EPC6, WSR_EPC6, XSR_EPC6, RSR_EXCSAVE6, WSR_EXCSAVE6, XSR_EXCSAVE6,
+ RSR_EPC7, WSR_EPC7, XSR_EPC7, RSR_EXCSAVE7, WSR_EXCSAVE7, XSR_EXCSAVE7,
+ RSR_EPS5, WSR_EPS5, XSR_EPS5, RSR_EPS6, WSR_EPS6, XSR_EPS6, RSR_EPS7,
+ WSR_EPS7, XSR_EPS7, RSR_VECBASE, WSR_VECBASE, XSR_VECBASE, MUL16U,
+ MUL16S, WSR_MMID, IPFL, IHU, IIU, DPFL, DHU, DIU, RSR_CPENABLE,
+ WSR_CPENABLE, XSR_CPENABLE, CLAMPS, MIN, MAX, MINU, MAXU, SEXT, L32AI,
+ S32RI, S32C1I, RSR_SCOMPARE1, WSR_SCOMPARE1, XSR_SCOMPARE1, QUOU, QUOS,
+ REMU, REMS, and MULL opcodes, along with the corresponding functions
+ to encode them.
+ (enum xtensa_opcode_id): Add entries for new opcodes.
+ (Slot_inst_decode): Handle new opcodes.
+ (Slot_inst_get_field_fns, Slot_inst_set_field_fns): Add entries for
+ xt_wbr15_imm and xt_wbr18_imm fields.
+ (Slot_inst16a_get_field_fns, Slot_inst16a_set_field_fns): Likewise.
+ (Slot_inst16b_get_field_fns, Slot_inst16b_set_field_fns): Likewise.
+ (xtensa_modules): Update number of fields, operands, iclasses and
+ opcodes.
+
+2008-11-19 Nix <nix@esperi.org.uk>
+
+ * elf.c (swap_out_syms) [USE_STT_COMMON]: Fix syntax error.
+
+2008-11-19 Nick Clifton <nickc@redhat.com>
+
+ PR 7027
+ * elfxx-sparc.c (_bfd_sparc_elf_check_relocs): Treat WPLT30 relocs
+ against local symbols in 64-bit binaries as if they were WDISP30
+ relocs.
+ (_bfd_sparc_elf_relocate_section): Likewise.
+
+2008-11-18 Catherine Moore <clm@codesourcery.com>
+
+ * elf32-arm.c (elf32_arm_merge_eabi_attributes): Merge
+ half-precision attributes.
+ (elf32_arm_copy_one_eabi_other_attribute): New.
+ (elf32_arm_copy_other_attribute_list): New.
+
+2008-11-18 Nick Clifton <nickc@redhat.com>
+
+ * dwarf2.c (read_section): Fix formatting.
+ (read_n_bytes): Remove unhelpful comment.
+ (read_indirect_string): Pass symbol table to read_section in case
+ the .debug_str section needs relocating.
+
+ PR 7037
+ * elf32-cr16.c (cr16_elf_howto_table): Zero the src_mask field of
+ the reloc descriptions.
+
+2008-11-14 Eric B. Weddington <eric.weddington@atmel.com>
+
+ PR 7022
+ * elf32-avr.c (bfd_elf_avr_final_write_processing):
+ Add missing break statements.
+
+2008-11-14 Bob Wilson <bob.wilson@acm.org>
+
+ * xtensa-modules.c (xtensa_state_id): New enum, replacing STATE macros.
+ (xtensa_field_id, xtensa_regfile_id, xtensa_operand_id)
+ (xtensa_iclass_id, xtensa_opcode_id): New enums.
+ Replace hardcoded constants throughout this file with enum values.
+
+2008-11-14 Nathan Sidwell <nathan@codesourcery.com>
+
+ * elf.c (assign_file_positions_for_load_sections): Use header_size
+ to avoid moving the load address of file headers.
+ (assign_file_positions_for_load_sections): Set header_size for
+ segments containing the file header.
+
+2008-11-14 Tristan Gingold <gingold@adacore.com>
+
+ * configure.com: Handle bfd_default_target_size, BFD_HOST_LONG_LONG,
+ BFD_HOST_64BIT_LONG_LONG, BFD_HOSTPTR_T, bfd_file_ptr.
+ Generate bfdver.h.
+ * vms-hdr.c (_bfd_vms_write_hdr): Use strdup/free instead of alloca.
+ * hosts/alphavms.h: Defines macros to bypass i18n.
+ * makefile.vms (OBJS): Update file list.
+ (DEFS): Remove VMS_DEBUG, const, add DEBUGDIR.
+ (CFLAGS): Update flags.
+ * bfdio.c (real_fopen): Add code specific to VMS: extract attributes
+ from modes.
+
+2008-11-13 Joel Brobecker <brobecker@adacore.com>
+
+ * configure.in: Deactivate large-file support on native 32bit
+ sparc-solaris unless the user explicitly requested it.
+ * configure: Regenerate.
+
+2008-11-13 Hans-Peter Nilsson <hp@axis.com>
+
+ PR ld/7028
+ * elf.c (assign_file_positions_for_load_sections): Allocate phrds
+ with bfd_zalloc2 instead of bfd_alloc2. For the amount, use
+ the possibly-preset header-size, not the computed one.
+
+2008-11-13 Alan Modra <amodra@bigpond.net.au>
+
+ PR 7023
+ * elf.c (bfd_section_from_shdr <SHT_SYMTAB>): Fail on invalid sh_info.
+
+2008-11-11 Alan Modra <amodra@bigpond.net.au>
+
+ * elf.c (assign_file_positions_for_non_load_sections): Consolidate
+ PT_GNU_RELRO handling.
+
+2008-11-11 Alan Modra <amodra@bigpond.net.au>
+
+ PR 7012
+ * dwarf2.c (find_line): Don't keep stale pointers into realloc'd
+ memory. Return on errors. Fix memory leak.
+ (_bfd_dwarf2_cleanup_debug_info): Free dwarf_str_buffer.
+
+2008-11-10 Andreas Schwab <schwab@suse.de>
+
+ PR 7011
+ * elf.c (assign_file_positions_for_non_load_sections): Handle
+ PT_GNU_RELRO specially.
+
+2008-11-06 Joel Sherrill <joel.sherrill@oarcorp.com>
+
+ * config.bfd: Add m32c-*-rtems* and m32r-*-rtems*.
+
+2008-11-06 Tom Tromey <tromey@redhat.com>
+
+ * configure, config.in: Rebuild.
+ * configure.in: Check for fileno.
+ * bfdio.c (close_on_exec): New function.
+ (real_fopen): Use it.
+ (FD_CLOEXEC): New define.
+
+2008-11-06 Tristan Gingold <gingold@adacore.com>
+
+ * mach-o.h (BFD_MACH_O_NO_SECT): Add; reorders the macros.
+ (BFD_MACH_O_SYM_NTYPE, BFD_MACH_O_SYM_NSECT,
+ BFD_MACH_O_SYM_NDESC): New macros.
+ (bfd_mach_o_i386_thread_flavour): Define according to the latest
+ definition from system header.
+ (bfd_mach_o_load_command_type): Add BFD_MACH_O_LC_RPATH,
+ BFD_MACH_O_LC_CODE_SIGNATURE.
+ (BFD_MACH_O_SECTION_TYPE_MASK, BFD_MACH_O_SECTION_ATTRIBUTES_MASK,
+ BFD_MACH_O_SECTION_ATTRIBUTES_SYS, BFD_MACH_O_SECTION_ATTRIBUTES_USR,
+ BFD_MACH_O_S_ATTR_LOC_RELOC, BFD_MACH_O_S_ATTR_EXT_RELOC,
+ BFD_MACH_O_S_ATTR_SOME_INSTRUCTIONS, BFD_MACH_O_S_ATTR_DEBUG,
+ BFD_MACH_O_S_ATTR_PURE_INSTRUCTIONS): Add.
+ (bfd_mach_o_segment_command): Add room for a nul terminator in
+ segname field.
+ (BFD_MACH_O_PROT_READ, BFD_MACH_O_PROT_WRITE,
+ BFD_MACH_O_PROT_EXECUTE): Add.
+ (INDIRECT_SYMBOL_LOCAL): Renames to BFD_MACH_O_INDIRECT_SYMBOL_LOCAL.
+ (INDIRECT_SYMBOL_ABS): Renames to BFD_MACH_O_INDIRECT_SYMBOL_ABS.
+ (bfd_mach_o_uuid_command): Add the structure.
+ (bfd_mach_o_load_command): Add uuid field.
+ (bfd_get_mach_o_data): New macro.
+ * mach-o.c (bfd_mach_o_bfd_print_private_bfd_data): New function which
+ replaces the macro.
+ (SECTION_TYPE, SECTION_ATTRIBUTES, SECTION_ATTRIBUTES_USR,
+ S_ATTR_PURE_INSTRUCTIONS, SECTION_ATTRIBUTES_SYS,
+ S_ATTR_SOME_INSTRUCTIONS, S_ATTR_EXT_RELOC, S_ATTR_LOC_RELOC): Renamed
+ and moved to mach-o.h.
+ (N_STAB, N_TYPE, N_EXT, N_UNDF, N_ABS, N_TEXT, N_DATA, N_BSS,
+ N_SECT, N_INDR): Removed as they duplicated macros in mach-o.h.
+ (bfd_mach_o_print_symbol): Print much more details.
+ (bfd_mach_o_make_bfd_section): Add prot argument, use canonical
+ dwarf name for dwarf sections. Precisely set section flags.
+ (bfd_mach_o_scan_read_section_32): Add prot argument.
+ (bfd_mach_o_scan_read_section_64): Ditto.
+ (bfd_mach_o_scan_read_section): Ditto.
+ (bfd_mach_o_scan_read_symtab_symbol): Set section for debugging
+ stabs, set BSF_GLOBAL and LOCAL flags correctly. Fix section
+ for N_SECT symbols.
+ (bfd_mach_o_i386_flavour_string): Reindent and adjust for new
+ names.
+ (bfd_mach_o_scan_read_symtab): Set HAS_SYMS flags on bfd if there
+ are symbols.
+ (bfd_mach_o_scan_read_uuid): New function.
+ (bfd_mach_o_scan_read_segment): Add a trailing nul. Segments
+ flags are now simply HAS_CONTENTS. Pass protection to
+ bfd_mach_o_scan_read_section.
+ (bfd_mach_o_scan_read_command): Decode UUID command.
+ (bfd_mach_o_flatten_sections): Add comments. Fix flavour names.
+ (bfd_mach_o_scan): Set flags according to file type.
+ (mach_o_fat_archentry): Remove abfd field.
+ (bfd_mach_o_archive_p): Remove initialization of abfd field.
+ (bfd_mach_o_openr_next_archived_file): Find previous archive
+ by position and not by bfd (as former bfds may have been freed).
+ Give architecture name to archived file.
+ * mach-o-target.c (TARGET_NAME): Use generic archive for non fat
+ targets.
+
+2008-10-30 Jay Krell <jay.krell@cornell.edu>
+
+ * cache.c (cache_bread): Cast void * pointer before performing
+ arithmetic on it.
+
+2008-10-20 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (ppc64_elf_process_dot_syms): Renamed from
+ ppc64_elf_check_directives.
+ * elf32-sh-symbian.c (sh_symbian_process_directives): Combine..
+ (sh_symbian_check_directives): ..this
+ (bfd_elf32_sh_symbian_process_directives) ..and this function.
+
+2008-10-20 Alan Modra <amodra@bigpond.net.au>
+
+ * elflink.c (bfd_elf_final_link): Move code reading relocs to..
+ * elf32-spu.c (spu_elf_count_relocs): ..here. Adjust params.
+ * elf-bfd.h (struct elf_backend_data): Update elf_backend_count_relocs
+ params.
+
+2008-10-20 Alan Modra <amodra@bigpond.net.au>
+
+ * elflink.c (bfd_elf_final_link): Use d_ptr rather than d_val
+ where Elf_Internal_Dyn holds an address.
+
+2008-10-10 Nathan Froyd <froydnj@codesourcery.com>
+
+ * elf32-ppc.c (ppc_elf_merge_obj_attributes): Merge
+ Tag_GNU_Power_ABI_Struct_Return.
+
+2008-10-09 Kai Tietz <kai.tietz@onevision.com>
+
+ * cofflink.c (_bfd_coff_generic_relocate_section): Dump bfd_vma
+ sized addresses instead of long sized.
+
+2008-10-09 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (ppc64_elf_get_synthetic_symtab): Don't attempt to
+ read plt relocs if no dynamic syms.
+
+2008-10-08 Nick Clifton <nickc@redhat.com>
+
+ * configure.in (ALL_LINGUAS): Add "id".
+ * configure: Regenerate.
+ * po/id.po: New Indonesian translation.
+
+2008-10-08 Alan Modra <amodra@bigpond.net.au>
+
+ * elf.c (assign_file_positions_for_load_sections): When checking
+ a segment for contents, don't assume that a non-TLS nobits section
+ must only be followed by nobits sections.
+
+2008-10-04 Hans-Peter Nilsson <hp@axis.com>
+
+ * elf32-cris.c (TLSHOWTO32, TLSHOWTO16): New macros.
+ (cris_elf_howto_table): Add entries for R_CRIS_32_GOT_GD,
+ R_CRIS_16_GOT_GD, R_CRIS_32_GD, R_CRIS_DTP, R_CRIS_32_DTPREL,
+ R_CRIS_16_DTPREL, R_CRIS_DTPMOD, R_CRIS_32_GOT_TPREL,
+ R_CRIS_16_GOT_TPREL, R_CRIS_32_TPREL, R_CRIS_16_TPREL.
+ (cris_reloc_map): Similarly.
+ * reloc.c (bfd_reloc_code_type): Add entries for
+ BFD_RELOC_CRIS_32_GOT_GD, BFD_RELOC_CRIS_16_GOT_GD,
+ BFD_RELOC_CRIS_32_GD, BFD_RELOC_CRIS_DTP,
+ BFD_RELOC_CRIS_32_DTPREL, BFD_RELOC_CRIS_16_DTPREL,
+ BFD_RELOC_CRIS_DTPMOD, BFD_RELOC_CRIS_32_GOT_TPREL,
+ BFD_RELOC_CRIS_16_GOT_TPREL, BFD_RELOC_CRIS_32_TPREL,
+ BFD_RELOC_CRIS_16_TPREL.
+ * libbfd.h, bfd-in2.h: Regenerate.
+
+2008-10-03 Alan Modra <amodra@bigpond.net.au>
+
+ PR 6931
+ * elf.c (bfd_elf_set_group_contents): Assign sh_info for ld -r when
+ the signature symbol is global.
+ * elflink.c (elf_link_input_bfd): Ensure group signature symbol
+ is output when ld -r. Set group sh_info when local.
+ * linker.c (default_indirect_link_order): Handle group sections
+ specially.
+
+2008-09-30 Wesley W. Terpstra <wesley@terpstra.ca>
+ Nick Clifton <nickc@redhat.com>
+
+ * coffgen.c (coff_write_symbols): Check to see if a symbol's flags
+ do not match it class and if necessary update the class.
+ (null_error_handler): New function. Suppresses the generation of
+ bfd error messages.
+ * coff64-rs6000.c (bfd_xcoff_backend_data): Update comment.
+
+2008-09-30 Alan Modra <amodra@bigpond.net.au>
+
+ * Makefile.am: Run "make dep-am".
+ * Makefile.in: Regenerate.
+
+2008-09-30 Alan Modra <amodra@bigpond.net.au>
+
+ * elflink.c (elf_link_add_object_symbols): Don't ignore returned
+ value of check_directives.
+
+2008-09-29 Peter O'Gorman <pogma@thewrittenword.com>
+ Steve Ellcey <sje@cup.hp.com>
+
+ * configure: Regenerate for new libtool.
+ * aclocal.m4: Ditto.
+ * Makefile.in: Ditto.
+ * doc/Makefile.in: Ditto.
+
+2008-09-29 Alan Modra <amodra@bigpond.net.au>
+
+ PR 6789
+ * elf.c (assign_file_positions_for_load_sections): Call
+ _bfd_elf_map_sections_to_segments, not elf_modify_segment_map.
+ (get_program_header_size): Protect against NULL info.
+ (_bfd_elf_map_sections_to_segments): Likewise.
+ * elf32-spu.c (spu_elf_additional_program_headers): Likewise.
+
+2008-09-29 Nick Clifton <nickc@redhat.com>
+
+ * po/vi.po: Updated Vietnamese translation.
+
+2008-09-28 Alan Modra <amodra@bigpond.net.au>
+
+ * elf.c (_bfd_elf_init_private_section_data): Tweak union copy.
+ (bfd_section_from_shdr): Don't change SHT_GROUP section name.
+ * elflink.c (section_signature): New function.
+ (_bfd_elf_section_already_linked): Use it.
+
+2008-09-19 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-ppc.c (ppc_elf_finish_dynamic_sections): Handle vxworks
+ _GLOBAL_OFFSET_TABLE_ in .got.plt section. Add BFD_ASSERTs.
+
+2008-09-17 Bob Wilson <bob.wilson@acm.org>
+
+ * elf32-xtensa.c (elf_xtensa_check_relocs): Check for negative
+ refcount.
+
+2008-09-17 Jan Kratochvil <jan.kratochvil@redhat.com>
+
+ PR 6893 - Do not consider FDEs for discarded sections as invalid.
+ * elf-eh-frame.c (_bfd_elf_parse_eh_frame): New REQUIRE_CLEARED_RELOCS.
+ Consider FDEs with cleared relocations as valid and ignorable.
+
+2008-09-16 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/6877
+ * elflink.c (_bfd_elf_merge_symbol): Allow a common symbol to
+ override the function in a shared library.
+
+2008-09-16 Alan Modra <amodra@bigpond.net.au>
+
+ PR 6844
+ * elf32-ppc.c (SYM_VAL): Define. Use throughout to find symbol vma.
+ (ppc_elf_relocate_section): Correct GOT offset calculation.
+ (ppc_elf_finish_dynamic_symbol): Use PPC_HA and PPC_LO.
+ (ppc_elf_finish_dynamic_sections): Likewise. Error if
+ htab->elf.hgot symbol is not defined in htab->got section.
+
+2008-09-16 Alan Modra <amodra@bigpond.net.au>
+
+ PR 6888
+ * elf32-ppc.c (ppc_elf_relocate_section): Handle NULL symbol section
+ on R_PPC_TOC16, R_PPC_SDAREL16, R_PPC_EMB_SDA2REL, R_PPC_EMB_SDA21,
+ R_PPC_EMB_RELSDA, R_PPC_SECTOFF* relocs.
+
+2008-09-11 Jan Kratochvil <jan.kratochvil@redhat.com>
+
+ Fix loading large elf64 binaries on 32bit hosts.
+ * configure.in: Call AC_SYS_LARGEFILE.
+ * config.in: Regenerate.
+ * configure: Regenerate.
+
+2008-09-08 Tom Tromey <tromey@redhat.com>
+
+ * elfxx-mips.c (mips16_stub_symndx) <sec>: Mark argument as
+ unused.
+
+2008-09-08 H.J. Lu <hongjiu.lu@intel.com>
+ Daniel Jacobowitz <dan@codesourcery.com>
+
+ PR ld/3191
+ * dwarf2.c (struct adjusted_section): Renamed from struct
+ loadable_section.
+ (struct dwarf2_debug): Adjust for renaming. Add version field.
+ (read_attribute_value): Correctly handle DW_FORM_ref_addr for
+ DWARF3.
+ (find_abstract_instance_name): Pass a pointer to
+ attribute instead of offset. For DW_FORM_ref_addr, get the
+ entry at the offset from the .debug_info section.
+ (scan_unit_for_symbols): Update.
+ (parse_comp_unit): Allow DWARF3. Save the version.
+ (unset_sections): Update for renaming.
+ (place_sections): Likewise. Set new VMAs for DWARF sections
+ also.
+
+2008-09-08 Tristan Gingold <gingold@adacore.com>
+
+ * configure.in: Update version to 2.19.50
+ * configure: Regenerated.
+
+2008-09-05 Daniel Jacobowitz <dan@codesourcery.com>
+
+ * dwarf2.c: Change leading whitespace to tabs.
+
+2008-09-05 Tristan Gingold <gingold@adacore.com>
+
+ Add MacOSX 64 bits support.
+ * mach-o.h (bfd_mach_o_ppc_thread_flavour): Add
+ BFD_MACH_O_PPC_THREAD_STATE_64.
+ (bfd_mach_o_i386_thread_flavour): Add BFD_MACH_O_x86_THREAD_STATE64,
+ BFD_MACH_O_x86_FLOAT_STATE64, BFD_MACH_O_x86_EXCEPTION_STATE64,
+ BFD_MACH_O_x86_THREAD_STATE, BFD_MACH_O_x86_FLOAT_STATE,
+ BFD_MACH_O_x86_EXCEPTION_STATE.
+ (bfd_mach_o_load_command_type): Add
+ BFD_MACH_O_LC_SEGMENT_64, BFD_MACH_O_LC_ROUTINES_64,
+ BFD_MACH_O_LC_UUID.
+ (BFD_MACH_O_CPU_IS64BIT): Added.
+ (bfd_mach_o_cpu_type): Add BFD_MACH_O_CPU_TYPE_POWERPC_64,
+ BFD_MACH_O_CPU_TYPE_X86_64.
+ (bfd_mach_o_header): Add version field.
+ (bfd_mach_o_section) Add reserved3 field.
+ (bfd_mach_o_segment_command): Add initprot and maxprot fields.
+
+ * mach-o.c (N_TEXT, N_DATA, N_BSS): Added.
+ (bfd_mach_o_version): New function.
+ (bfd_mach_o_valid): Handle 64bits cpus.
+ (bfd_mach_o_write_header): handler 64bits headers.
+ (bfd_mach_o_scan_write_section_32, bfd_mach_o_scan_write_section_64):
+ New functions (from bfd_mach_o_scan_write_section) to handle both
+ flavors.
+ (bfd_mach_o_scan_write_segment): Parameter wide added to support
+ both flavors.
+ (bfd_mach_o_write_contents): Support both flavors.
+ (bfd_mach_o_read_header): Ditto.
+ (bfd_mach_o_scan_read_section_32, bfd_mach_o_scan_read_section_64):
+ New functions (from bfd_mach_o_scan_read_section) to support both
+ flavors.
+ (bfd_mach_o_scan_read_symtab_symbol): Support both flavors.
+ (bfd_mach_o_scan_read_symtab): Ditto.
+ (bfd_mach_o_scan_read_segment): Parameter wide added to support
+ both flavors.
+ (bfd_mach_o_scan_read_segment_32, bfd_mach_o_scan_read_segment_64):
+ New functions to call bfd_mach_o_scan_read_segment.
+ (bfd_mach_o_flatten_sections): Support both flavors.
+ (bfd_mach_o_scan_start_address): Ditto.
+ (bfd_mach_o_scan): Ditto.
+ (bfd_mach_o_lookup_section): Ditto.
+
+2008-08-27 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ * elf-hppa.h (elf_hppa_reloc_final_type): Handle R_PARISC_GPREL64,
+ R_PARISC_SEGREL32 and R_PARISC_SEGREL64.
+ * som.c (som_fixup_formats): Add R_DATA_GPREL fixup.
+ (som_hppa_howto_table): Likewise.
+ (hppa_som_gen_reloc_type): In case R_HPPA_GOTOFF, detect R_DATA_GPREL
+ final type.
+ (som_write_fixups): Handle R_DATA_GPREL.
+
+2008-08-26 Nick Clifton <nickc@redhat.com>
+
+ * elf32-arm.c: Fix up comment describing Thumb to ARM interworking
+ stub.
+
+2008-08-25 Christophe Lyon <christophe.lyon@st.com>
+
+ * elf32-arm.c (arm_thumb_arm_v4t_short_branch_stub): Define.
+ (elf32_arm_stub_type): Add arm_thumb_arm_v4t_stub_short_branch.
+ (arm_type_of_stub): Handle armv4t short branches. Update
+ prototype.
+ (arm_stub_is_thumb): Handle arm_thumb_arm_v4t_stub_short_branch.
+ (arm_build_one_stub): Likewise.
+ (arm_size_one_stub): Likewise.
+ (elf32_arm_size_stubs): Use new arm_type_of_stub prototype.
+ (arm_map_one_stub): Handle arm_thumb_arm_v4t_stub_short_branch.
+
+2008-08-24 Andreas Schwab <schwab@suse.de>
+
+ * elf-eh-frame.c (_bfd_elf_write_section_eh_frame): Do proper
+ extension when calculating difference of offsets.
+
+2008-08-24 Alan Modra <amodra@bigpond.net.au>
+
+ * configure.in: Update a number of obsolete autoconf macros.
+ * aclocal.m4: Regenerate.
+
+2008-08-23 Andreas Schwab <schwab@suse.de>
+
+ * opncls.c (find_separate_debug_file): Use the canonical
+ absolute name of the bfd object for finding the debug file in
+ the global debugfile directory.
+
+2008-08-22 Jakub Jelinek <jakub@redhat.com>
+
+ Fix PR ld/3290 regression for cross-files DW_FORM_ref_addr relocations.
+ * elflink.c (elf_link_add_object_symbols): Make debug symbols local
+ now only for non-RELOCATABLE targets.
+
+2008-08-20 Bob Wilson <bob.wilson@acm.org>
+
+ * elf-bfd.h (elf_object_id): Add XTENSA_ELF_TDATA.
+ * elf32-xtensa.c (elf_howto_table): Add TLS relocations.
+ (elf_xtensa_reloc_type_lookup): Likewise.
+ (TCB_SIZE): Define.
+ (elf_xtensa_link_hash_entry): New.
+ (GOT_UNKNOWN, GOT_NORMAL, GOT_TLS_GD, GOT_TLS_IE, GOT_TLS_ANY): Define.
+ (elf_xtensa_hash_entry): Define.
+ (elf_xtensa_obj_tdata): New.
+ (elf_xtensa_tdata): Define.
+ (elf_xtensa_local_got_tls_type): Define.
+ (elf_xtensa_local_tlsfunc_refcounts): Define.
+ (is_xtensa_elf): Define.
+ (elf_xtensa_mkobject): New.
+ (elf_xtensa_link_hash_table): Add tlsbase field.
+ (elf_xtensa_link_hash_newfunc): New.
+ (elf_xtensa_link_hash_table_create): Use elf_xtensa_link_hash_newfunc.
+ Create an entry for "_TLS_MODULE_BASE_" and save it in tlsbase field.
+ (elf_xtensa_copy_indirect_symbol): New.
+ (elf_xtensa_check_relocs): Rewrite to handle TLS relocations.
+ (elf_xtensa_gc_sweep_hook): Likewise.
+ (elf_xtensa_allocate_dynrelocs): Optimize away GOT entries for
+ TLSDESC_FN relocations when an IE reference is seen.
+ (elf_xtensa_allocate_local_got_size): Likewise.
+ (elf_xtensa_always_size_sections): New.
+ (dtpoff_base, tpoff): New.
+ (elf_xtensa_do_reloc): Handle TLS relocations.
+ (replace_tls_insn): New.
+ (IS_XTENSA_TLS_RELOC): Define.
+ (elf_xtensa_relocate_section): Handle TLS relocations.
+ (get_indirect_call_dest_reg): New.
+ (bfd_elf32_mkobject): Define.
+ (elf_backend_always_size_sections): New.
+ (elf_backend_copy_indirect_symbol): New.
+ * reloc.c (BFD_RELOC_XTENSA_TLSDESC_FN, BFD_RELOC_XTENSA_TLSDESC_ARG)
+ (BFD_RELOC_XTENSA_TLS_DTPOFF, BFD_RELOC_XTENSA_TLS_TPOFF)
+ (BFD_RELOC_XTENSA_TLS_FUNC, BFD_RELOC_XTENSA_TLS_ARG)
+ (BFD_RELOC_XTENSA_TLS_CALL): New.
+ * bfd-in2.h: Regenerate.
+ * libbfd.h: Regenerate.
+
+2008-08-18 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * elfxx-mips.c (_bfd_mips_elf_copy_indirect_symbol): Copy MIPS16
+ stub information.
+
+2008-08-17 Nick Clifton <nickc@redhat.com>
+
+ * elf32-arm.c: Tidy up the code.
+ (bfd_elf32_arm_allocate_interworking_sections): Move common code
+ into...
+ (arm_allocate_glue_section_space): ... New function.
+ (bfd_elf32_arm_add_glue_sections_to_bfd): Move common code
+ into...
+ (arm_make_glue_section): ... New function.
+
+ * elfxx-mips.c (_bfd_mips_elf_check_relocs): Handle the situation
+ where the sym_hashes are not available.
+
+2008-08-17 Alan Modra <amodra@bigpond.net.au>
+
+ * bfd.c (struct _bfd): Correct outsymbols comment.
+ * bfd-in2.h: Regenerate.
+ * linker.c (bfd_generic_link_read_symbols): Renamed from..
+ (generic_link_read_symbols): ..this, and made global.
+
+2008-08-15 Alan Modra <amodra@bigpond.net.au>
+
+ PR 6526
+ * configure.in: Invoke AC_USE_SYSTEM_EXTENSIONS.
+ * Makefile.in: Regenerate.
+ * aclocal.m4: Regenerate.
+ * config.in: Regenerate.
+ * configure: Regenerate.
+
+2008-08-14 Jaka MoÄnik <jaka@xlab.si>
+
+ * coffgen.c (coff_find_nearest_line): Correct cached line index.
+
+2008-08-12 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-ppc.c (allocate_dynrelocs): Ignore dyn_relocs when
+ !dynamic_sections_created. Don't make symbols with got
+ references dynamic if !dynamic_sections_created.
+ * elf64-ppc.c (allocate_dynrelocs): Likewise. Alloc dynamic
+ relocs on undefined symbols.
+ (ppc64_elf_relocate_section): Allow dynamic relocs on
+ undefined symbols.
+
+2008-08-11 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (toc_adjusting_stub_needed): Any call via the plt
+ needs r2 valid, not just those to external syms.
+
+2008-08-09 Pedro Alves <pedro@codesourcery.com>
+
+ * archive.c (_bfd_archive_bsd_update_armap_timestamp): Cast stat
+ st_mtime to long before comparison.
+
+2008-08-08 Anatoly Sokolov <aesok@post.ru>
+
+ * archures.c (bfd_mach_avr25, bfd_mach_avr31, bfd_mach_avr35,
+ bfd_mach_avr51): New.
+ * bfd-in2.h: Regenerate.
+ * cpu-avr.c (arch_info_struct): Add avr25, avr31, avr35, and avr51
+ architectures. Change comments to match architecture comments in GCC.
+ (compatible): Add test for new AVR architectures.
+ * elf32-avr.c (bfd_elf_avr_final_write_processing): Recognize
+ bfd_mach_avr25, bfd_mach_avr31, bfd_mach_avr35 and bfd_mach_avr51.
+ (elf32_avr_object_p): Recognize E_AVR_MACH_AVR25, E_AVR_MACH_AVR31,
+ E_AVR_MACH_AVR35 and E_AVR_MACH_AVR51.
+
+
+2008-08-08 Richard Sandiford <rdsandiford@googlemail.com>
+ Daniel Jacobowitz <dan@codesourcery.com>
+ Catherine Moore <clm@codesourcery.com>
+ Mark Shinwell <shinwell@codesourcery.com>
+ Maxim Kuvyrkov <maxim@codesourcery.com>
+
+ * elf32-mips.c (mips_vxworks_copy_howto_rela): Replace with...
+ (elf_mips_copy_howto): ...this howto. Clear the size fields.
+ (mips_vxworks_jump_slot_howto_rela): Replace with...
+ (elf_mips_jump_slot_howto): ...this howto.
+ (bfd_elf32_bfd_reloc_type_lookup): Handle BFD_RELOC_MIPS_COPY
+ and BFD_RELOC_MIPS_JUMP_SLOT.
+ (bfd_elf32_bfd_reloc_name_lookup): Handle "R_MIPS_COPY" and
+ "R_MIPS_JUMP_SLOT".
+ (mips_elf32_rtype_to_howto): Handle R_MIPS_COPY and R_MIPS_JUMP_SLOT.
+ (elf_backend_plt_readonly): Define.
+ (elf_backend_plt_sym_val): Define for non-VxWorks targets.
+ (mips_vxworks_bfd_reloc_type_lookup): Delete.
+ (mips_vxworks_bfd_reloc_name_lookup): Likewise.
+ (mips_vxworks_rtype_to_howto): Likewise.
+ (elf_backend_want_dynbss): Don't define for VxWorks.
+ (elf_backend_plt_readonly): Likewise.
+ (bfd_elf32_bfd_reloc_type_lookup): Likewise.
+ (bfd_elf32_bfd_reloc_name_lookup): Likewise.
+ (elf_backend_mips_rtype_to_howto): Likewise.
+ (elf_backend_adjust_dynamic_symbol): Likewise.
+ (elf_backend_got_symbol_offset): Don't define.
+ * elfn32-mips.c (elf_mips_copy_howto, elf_mips_jump_slot_howto): New.
+ (bfd_elf32_bfd_reloc_type_lookup): Handle BFD_RELOC_MIPS_COPY
+ and BFD_RELOC_MIPS_JUMP_SLOT.
+ (bfd_elf32_bfd_reloc_name_lookup): Handle "R_MIPS_COPY" and
+ "R_MIPS_JUMP_SLOT".
+ (mips_elf32_n32_rtype_to_howto): Handle R_MIPS_COPY and
+ R_MIPS_JUMP_SLOT.
+ (elf_backend_rela_plts_and_copies_p, elf_backend_plt_readonly)
+ (elf_backend_plt_sym_val): Define.
+ * elf64-mips.c (elf_mips_copy_howto, elf_mips_jump_slot_howto): New.
+ (bfd_elf64_bfd_reloc_type_lookup): Handle BFD_RELOC_MIPS_COPY
+ and BFD_RELOC_MIPS_JUMP_SLOT.
+ (bfd_elf64_bfd_reloc_name_lookup): Handle "R_MIPS_COPY" and
+ "R_MIPS_JUMP_SLOT".
+ (mips_elf64_rtype_to_howto): Handle R_MIPS_COPY and R_MIPS_JUMP_SLOT.
+ (elf_backend_rela_plts_and_copies_p, elf_backend_plt_readonly)
+ (elf_backend_plt_sym_val): Define.
+ * elfxx-mips.h (_bfd_mips_vxworks_adjust_dynamic_symbol): Delete.
+ (_bfd_mips_elf_use_plts_and_copy_relocs, _bfd_mips_elf_init_stubs)
+ (_bfd_mips_elf_plt_sym_val, _bfd_mips_post_process_headers): Declare.
+ * elfxx-mips.c (mips_elf_la25_stub): New structure.
+ (LA25_LUI, LA25_J, LA25_ADDIU): New macros.
+ (mips_elf_link_hash_entry): Add "la25_stubs", "has_static_relocs"
+ and "has_nonpic_branches" fields. Remove "is_relocation_target" and
+ "is_branch_target".
+ (mips_elf_link_hash_table): Add blank lines. Add
+ "use_plts_and_copy_relocs", "reserved_gotno", "strampoline",
+ "la25_stubs" and "add_stub_section" fields.
+ (mips_htab_traverse_info): New structure.
+ (PIC_OBJECT_P, MIPS_ELF_LOAD_WORD): New macros.
+ (MIPS_RESERVED_GOTNO): Delete.
+ (mips_o32_exec_plt0_entry, mips_n32_exec_plt0_entry)
+ (mips_n64_exec_plt0_entry, mips_exec_plt_entry): New tables.
+ (mips_elf_link_hash_newfunc): Update after the changes to
+ mips_elf_link_hash_entry.
+ (mips_elf_check_mips16_stubs): Replace the DATA parameter with
+ an INFO parameter. Don't look through warnings symbols here;
+ do it in mips_elf_check_symbols instead.
+ (mips_elf_create_stub_symbol): New function.
+ (mips_elf_la25_stub_hash, mips_elf_la25_stub_eq): New functions.
+ (_bfd_mips_elf_init_stubs, mips_elf_local_pic_function_p): Likewise.
+ (mips_elf_add_la25_intro, mips_elf_add_la25_trampoline): Likewise.
+ (mips_elf_add_la25_stub, mips_elf_check_symbols): New functions.
+ (mips_elf_gotplt_index): Check for VxWorks.
+ (mips_elf_output_dynamic_relocation): Take the relocation index
+ as an extra parameter. Do not increment reloc_count here.
+ (mips_elf_initialize_tls_slots): Update the calls to
+ mips_elf_output_dynamic_relocation accordingly.
+ (mips_elf_multi_got): Use htab->reserved_gotno instead of
+ MIPS_RESERVED_GOTNO.
+ (mips_elf_create_got_section): Don't allocate reserved GOT
+ entries here. Unconditionally create .got.plt, but don't
+ set its alignment here.
+ (mips_elf_relocation_needs_la25_stub): New function.
+ (mips_elf_calculate_relocation): Redirect branches and jumps to
+ a non-PIC stub if one exists. Check !h->has_static_relocs instead
+ of !htab->is_vxworks when deciding whether to create dynamic
+ relocations for R_MIPS_32, R_MIPS_REL32 and R_MIPS_64.
+ (_bfd_mips_elf_create_dynamic_sections): Unconditionally call
+ _bfd_elf_create_dynamic_sections. Unconditionally set up
+ htab->splt and htab->sdynbss. Set htab->srelplt to ".rel.plt"
+ if !htab->is_vxworks. Add non-VxWorks values of
+ htab->plt_header_size and htab->plt_entry_size.
+ (_bfd_mips_elf_check_relocs): Set pointer_equality_needed for
+ non-branch static relocations. Set has_nonpic_branches when an la25
+ stub might be required. Set can_make_dynamic_p to TRUE if R_MIPS_32,
+ R_MIPS_REL32 and R_MIPS_64 relocations can be made dynamic,
+ rather than duplicating the condition. Do not make them dynamic
+ for read-only sections in non-PIC executable objects.
+ Do not protect this code with dynobj == NULL || htab->sgot == NULL;
+ handle each group of cases separately. Add a default case that
+ sets has_static_relocs for non-GOT relocations that cannot be
+ made dynamic. Don't set is_relocation_target and is_branch_target.
+ Reject non-PIC static relocations in shared objects.
+ (_bfd_mips_vxworks_adjust_dynamic_symbol): Fold into...
+ (_bfd_mips_elf_adjust_dynamic_symbol): ...here, using
+ htab->use_plts_and_copy_relocs instead of htab->is_vxworks
+ to select PLT and copy-reloc handling. Set the alignment of
+ .plt and .got.plt when allocating the first entry. Generalize
+ code to handle REL as well as RELA sections and 64-bit as well as
+ 32-bit GOT entries. Complain if we find a static-only reloc
+ against an externally-defined symbol and if we cannot create
+ dynamic relocations for it. Allocate copy relocs using
+ mips_elf_allocate_dynamic_relocations on non-VxWorks targets.
+ Set possibly_dynamic_relocs to 0 when using PLTs or copy relocs.
+ Skip reserved .got.plt entries.
+ (_bfd_mips_elf_always_size_sections): Use mips_elf_check_symbols
+ instead of mips_elf_check_mips16_stubs to process each symbol.
+ Do the traversal for relocatable objects too.
+ (mips_elf_lay_out_got): Use htab->reserved_gotno instead of
+ MIPS_RESERVED_GOTNO.
+ (_bfd_mips_elf_size_dynamic_sections): Exclude sdynbss if it
+ is empty. Extend the DT_PLTREL, DT_JMPREL and DT_PLTRELSZ handling
+ to non-VxWorks targets. Only add DT_REL{,A}, DT_REL{,A}SZ and
+ DT_REL{,A}ENT if .rel.dyn is nonempty. Create a symbol for the
+ PLT. Allocate a nop at the end of the PLT. Allocate DT_MIPS_PLTGOT.
+ (mips_elf_create_la25_stub_info): New function.
+ (_bfd_mips_elf_finish_dynamic_symbol): Write out PLT entries
+ and copy relocs where necessary. Check pointer_equality_needed.
+ (mips_finish_exec_plt): New function.
+ (_bfd_mips_elf_finish_dynamic_sections): Always set DT_PLTGOT
+ to the beginning of htab->sgot. Use htab->reserved_gotno instead
+ of MIPS_RESERVED_GOTNO. Assert htab->use_plts_and_copy_relocs
+ instead of htab->is_vxworks for DT_PLTREL, DT_PLTRELSZ and DT_JMPREL.
+ Set DT_PLTREL to DT_REL instead of DT_RELA on non-VxWorks targets.
+ Use mips_finish_exec_plt to create non-VxWorks PLT headers. Set
+ DT_MIPS_PLTGOT.
+ (_bfd_mips_elf_copy_indirect_symbol): Copy has_static_relocs
+ from the indirect symbol to the direct symbol. Also copy
+ has_nonpic_branches for indirect symbols.
+ (_bfd_mips_elf_get_target_dtag): Handle DT_MIPS_PLTGOT and
+ DT_MIPS_RWPLT.
+ (_bfd_mips_elf_link_hash_table_create): Initialize the new
+ mips_elf_link_hash_table fields.
+ (_bfd_mips_vxworks_link_hash_table_create): Set
+ use_plts_and_copy_relocs to TRUE. Use TRUE rather than 1
+ when setting is_vxworks.
+ (_bfd_mips_elf_use_plts_and_copy_relocs): New function.
+ (_bfd_mips_elf_final_link): Call mips_elf_create_la25_stub for
+ each la25_stub.
+ (_bfd_mips_elf_merge_private_bfd_data): Treat dynamic objects
+ as PIC. Generalize message about linking PIC and non-PIC.
+ (_bfd_mips_elf_plt_sym_val, _bfd_mips_post_process_headers): New
+ functions.
+ * reloc.c: Update comment near BFD_RELOC_MIPS_JUMP_SLOT.
+ * bfd-in2.h: Regenerated.
+
+2008-08-08 Alan Modra <amodra@bigpond.net.au>
+
+ * elf.c (bfd_elf_get_elf_syms): Don't leak memory on error.
+ * elflink.c (_bfd_elf_link_read_relocs): bfd_release on error.
+ (elf_link_add_object_symbols): Don't leak memory on error.
+ (bfd_elf_size_dynsym_hash_dynstr): Likewise.
+ (elf_fixup_link_order): Free sections.
+
+2008-08-07 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * elf-bfd.h (elf_backend_data): Add a "rela_plts_and_copies_p" field.
+ * elfxx-target.h (elf_backend_rela_plts_and_copies_p): New macro.
+ (elfNN_bed): Use it.
+ * elf.c (_bfd_elf_get_synthetic_symtab): Use rela_plts_and_copies_p
+ instead of default_use_rela_p to choose between ".rel.plt" and
+ ".rela.plt".
+ * elflink.c (_bfd_elf_create_dynamic_sections): Use
+ rela_plts_and_copies_p instead of default_use_rela_p to choose
+ between ".rel.plt" and ".rela.plt", and between ".rel.bss" and
+ ".rela.bss".
+
+2008-08-07 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * elf-bfd.h (MIPS_ELF_TDATA): New elf_object_id.
+ * elf32-mips.c (bfd_elf32_mkobject): Define.
+ * elf64-mips.c (bfd_elf64_mkobject): Likewise.
+ * elfn32-mips.c (bfd_elf32_mkobject): Likewise.
+ * elfxx-mips.h (_bfd_mips_elf_mkobject): Declare.
+ * elfxx-mips.c (is_mips_elf): New macro.
+ (_bfd_mips_elf_mkobject): New function.
+ (_bfd_mips_elf_final_link): Use is_mips_elf.
+ (_bfd_mips_elf_merge_private_bfd_data): Likewise.
+
+2008-08-07 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * elfxx-mips.c (mips_elf_record_relocs): Defer allocation of a
+ global GOT entry when deferring allocation of dynamic relocations.
+ (allocate_dynrelocs): When allocating deferred dynamic relocations,
+ also do the deferred allocation of a GOT entry.
+
+2008-08-07 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * elfxx-mips.c (mips_got_info): Add a "reloc_only_gotno" field.
+ (mips_elf_got_section): Delete.
+ (mips_elf_sort_hash_table): Use g->reloc_only_gotno to decide
+ how many reloc-only entries there are.
+ (mips_elf_count_got_symbols): Adjust g->reloc_only_gotno as
+ well as g->global_gotno.
+ (mips_elf_make_got_per_bfd): Initialize reloc_only_gotno.
+ (mips_elf_multi_got): Likewise. Use gg->reloc_only_gotno
+ rather than gg->assigned_gotno to store the number of
+ reloc-only GOT entries.
+ (mips_elf_create_got_section): Remove the MAYBE_EXCLUDE parameter.
+ Initialize reloc_only_gotno.
+ (mips_elf_calculate_relocation): Check htab->got_info instead of
+ dynobj when deciding whether to call mips_elf_adjust_gp,
+ (_bfd_mips_elf_create_dynamic_sections): Adjust the call
+ to mips_elf_create_got_section.
+ (mips_elf_record_relocs): Likewise. Remove redundant
+ "dynobj == NULL" code. Do not use mips_elf_create_got_section
+ or mips_elf_record_global_got_symbol for R_MIPS_32, R_MIPS_REL32
+ and R_MIPS_64; limit global_got_area to GGA_RELOC_ONLY instead.
+ (_bfd_mips_elf_finish_dynamic_symbol): Use htab->sgot instead
+ of mips_elf_got_section.
+ (_bfd_mips_vxworks_finish_dynamic_symbol): Likewise.
+ (_bfd_mips_elf_finish_dynamic_sections): Likewise.
+ Move the initial assignment of G to the block that uses it;
+ it is used for an unrelated purpose later.
+
+2008-08-07 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * elfxx-mips.c (count_section_dynsyms): Move before the new first use.
+ (mips_elf_sort_hash_table): Take the output bfd as a parameter.
+ Remove the MAX_LOCAL parameter. Exit early if there are no
+ dynamic symbols, if there is no dynobj, or if there is no
+ GOT section. Use count_section_dynsyms instead of MAX_LOCAL.
+ Assert == rather than <= when checking hsd.max_unref_got_dynindx.
+ Also assert that g->global_gotno is right.
+ (mips_elf_count_forced_local_got_symbols): Rename to...
+ (mips_elf_count_got_symbols): ...and count global GOT entries too.
+ Set the global_got_area of a forced-local GGA_RELOC_ONLY symbol
+ to GGA_NONE.
+ (mips_elf_multi_got): Don't sort the symbol table.
+ (mips_elf_lay_out_got): Likewise. Use mips_elf_count_got_symbols
+ to count the number of global GOT entries.
+ (_bfd_mips_elf_final_link): Unconditionally call
+ mips_elf_sort_hash_table.
+
+2008-08-07 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * elfxx-mips.c (GGA_NORMAL, GGA_RELOC_ONLY, GGA_NONE): New macros.
+ (mips_elf_link_hash_entry): Add a "global_got_area" field.
+ (mips_elf_link_hash_newfunc): Initialize it.
+ (mips_elf_sort_hash_table_f): Use h->global_got_area instead of
+ h->root.got.offset. Do not handle forced_local symbols specially.
+ (mips_elf_record_global_got_symbol): Set h->global_got_area
+ instead of h->root.got.offset.
+ (mips_elf_recreate_got): Assert that h->global_got_area == GGA_NONE
+ for indirect and warning symbols.
+ (mips_elf_count_forced_local_got_symbols): Change the argument
+ from a "elf_link_hash_entry" to "mips_elf_link_hash_entry".
+ Use and set h->global_got_area instead of h->root.got.offset.
+ Set it to GGA_NONE for all forced-local symbols.
+ (mips_elf_set_global_got_offset): Set h->global_got_area
+ instead of h->root.got.offset. Use g->global_got_area instead
+ of a combination of dynindx, forced_local and tls_type.
+ (mips_elf_multi_got): Remove disabled code. Pass GGA_* values to
+ mips_elf_set_global_got_offset.
+ (mips_elf_lay_out_got): Use mips_elf_link_hash_traverse instead
+ of elf_link_hash_traverse.
+ (_bfd_mips_elf_copy_indirect_symbol): Copy the indirect symbol's
+ global_got_area to the direct symbol if the latter's value is higher.
+ Set the indirect symbol's area to GGA_NONE.
+
+2008-08-07 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * elf32-mips.c (elf_backend_hide_symbol): Delete.
+ * elfn32-mips.c (elf_backend_hide_symbol): Likewise.
+ * elf64-mips.c (elf_backend_hide_symbol): Likewise.
+ * elfxx-mips.h (elf_backend_hide_symbol): Likewise.
+ * elfxx-mips.c (mips_elf_link_hash_entry): Remove "forced_local"
+ and add "needs_lazy_stub".
+ (mips_elf_link_hash_newfunc): Update accordingly.
+ (mips_elf_link_hash_table): Remove "computed_got_sizes" and
+ add "lazy_stub_count".
+ (_bfd_mips_elf_link_hash_table_create): Update accordingly.
+ (mips_elf_output_extsym): Use hd->needs_lazy_stub to detect
+ cases where a lazy stub is being used.
+ (mips_elf_sort_hash_table_f): Use h->root.forced_local instead
+ of h->forced_local.
+ (mips_elf_record_global_got_symbol): Use _bfd_elf_link_hash_hide_symbol
+ instead of _bfd_mips_elf_hide_symbol. Do not increment local_gotno
+ here.
+ (mips_elf_allocate_dynamic_relocations): Move before new first use.
+ (mips_elf_check_recreate_got, mips_elf_recreate_got): New functions.
+ (mips_elf_resolve_final_got_entries): Move earlier in file. Make at
+ most two passes over the hash table. Use mips_elf_check_recreate_got
+ to see if there are any indirect or warning entries and
+ mips_elf_recreate_got to create a new GOT without them.
+ Return a boolean success value.
+ (mips_elf_count_forced_local_got_entries): New function.
+ (mips_elf_make_got_per_bfd): Check h->root.forced_local instead of
+ h->forced_local.
+ (mips_elf_set_global_got_offset): Likewise.
+ (mips_elf_set_no_stub): Replace with...
+ (mips_elf_forbid_lazy_stubs): ...this new function.
+ (mips_elf_resolve_final_got_entry): Delete.
+ (mips_elf_multi_got): Fix formatting. Use mips_elf_forbid_lazy_stubs
+ instead of mips_elf_set_no_stub. Move the code that sets
+ global offsets and allocates dynamic relocations from the main
+ _bfd_mips_elf_size_dynamic_sections loop to here.
+ (_bfd_mips_elf_adjust_dynamic_symbol): Do not allocate room in
+ .MIPS.stubs here; just set hmips->needs_lazy_stub and increment
+ htab->lazy_stub_count.
+ (_bfd_mips_elf_always_size_sections): Move the stub-estimation
+ code to mips_elf_estimate_stub_size and the GOT-sizing code to
+ mips_elf_lay_out_got. Do not call these functions here.
+ (mips_elf_estimate_stub_size): New function, split
+ out from _bfd_mips_elf_always_size_sections. Call
+ mips_elf_resolve_final_got_entries earlier. Count the number
+ of forced-local entries. Do not add stub sizes to loadable_size;
+ after this patch, the stub sizes are already included in the main
+ estimate. Allocate dynamic relocations here rather than in the
+ main _bfd_mips_elf_size_dynamic_sections loop.
+ (mips_elf_estimate_stub_size): New function, split out from
+ _bfd_mips_elf_always_size_sections.
+ (mips_elf_allocate_lazy_stub): New function.
+ (mips_elf_lay_out_lazy_stubs): Likewise.
+ (_bfd_mips_elf_size_dynamic_sections): Call mips_elf_estimate_stub_size,
+ mips_elf_lay_out_got and mips_elf_lay_out_lazy_stubs. Do not handle
+ the allocation of sreldyn specially.
+ (_bfd_mips_elf_hide_symbol): Delete.
+
+2008-08-07 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * elfxx-mips.c (allocate_dynrelocs): Ignore indirect and warning
+ symbols.
+
+2008-08-06 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * elfxx-mips.c (mips_elf_link_hash_entry): Move bfd_boolean
+ fields to the end of the structure and make them single-bit
+ bitfields.
+ (mips_elf_link_hash_newfunc): Make the initialization statements
+ follow the new field order.
+
+2008-08-06 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * elfxx-mips.c (_mips_elf_section_data): Remove the "u.got_info" field.
+ (mips_elf_link_hash_table): Add "sgot" and "got_info" fields.
+ (_bfd_mips_elf_link_hash_table_create): Initialize them.
+ (mips_elf_got_section): Always apply the !maybe_excluded behavior.
+ (mips_elf_got_info): Delete.
+ (mips_elf_initialize_tls_slots): Remove the DYNOBJ local variable.
+ Adjust the call to mips_elf_got_section.
+ (mips_elf_local_got_index): Don't call mips_elf_got_info.
+ Update the call to mips_elf_create_local_got_entry.
+ Use htab->got_info.
+ (mips_elf_global_got_index): Don't call mips_elf_got_info;
+ use htab->got_info and htab->sgot instead.
+ (mips_elf_got_page): Don't call mips_elf_got_info. Update the
+ call to mips_elf_create_local_got_entry.
+ (mips_elf_got16_entry): Likewise.
+ (mips_elf_got_offset_from_index): Replace with DYNOBJ parameter
+ with an INFO parameter. Don't call mips_elf_got_info; use htab->sgot
+ and htab->got_info instead.
+ (mips_elf_create_local_got_entry): Remove the GG and SGOT parameters.
+ Use htab->sgot and htab->got_info.
+ (mips_elf_sort_hash_table): Remove the DYNOBJ local variable.
+ Don't call mips_elf_got_info; use htab->got_info instead.
+ (mips_elf_record_global_got_symbol): Turn G from a paramter to
+ a local variable and read it from htab->got_info.
+ (mips_elf_record_local_got_symbol): Replace the G parameter with
+ an INFO parameter. Make G a local variable and read it from
+ htab->got_info instead.
+ (mips_elf_record_got_page_entry): Likewise.
+ (mips_elf_multi_got): Remove the G parameter and make it a local
+ variable instead. Read it from htab->got_info.
+ (mips_elf_create_got_section): Cache the GOT section in htab->sgot.
+ Store the GOT information in htab->got_info.
+ (mips_elf_calculate_relocation): Don't call mips_elf_got_section
+ and mips_elf_got_info; use htab->sgot and htab->got_info instead.
+ Adjust the calls to mips_elf_got_offset_from_index and
+ mips_elf_adjust_gp.
+ (_bfd_mips_elf_check_relocs): Remove the G and SGOT local variables.
+ Adjust the calls to mips_elf_record_local_got_symbol,
+ mips_elf_record_global_got_symbol and mips_elf_record_got_page_entry.
+ Use htab->sgot.
+ (_bfd_mips_elf_always_size_sections): Remove the DYNOBJ local variable.
+ Don't call mips_elf_got_info; use htab->sgot and htab->got_info instead.
+ Update the call to mips_elf_multi_got.
+ (_bfd_mips_elf_size_dynamic_sections): Don't call mips_elf_got_info;
+ use htab->got_info instead.
+ (_bfd_mips_elf_finish_dynamic_symbol): Update the call to
+ mips_elf_got_section. Get the got_info from the hash table
+ rather than the GOT section.
+ (_bfd_mips_vxworks_finish_dynamic_symbol): Likewise.
+ (_bfd_mips_elf_finish_dynamic_sections): Likewise.
+ (_bfd_mips_elf_hide_symbol): Don't call mips_elf_got_section;
+ get the got_info from the hash table instead. Remove the GOT
+ local variable.
+ (_bfd_mips_elf_final_link): Likewise. Also remove the DYNOBJ
+ local variable.
+
+2008-08-06 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * elfxx-mips.c (mips_elf_link_hash_table): Add an "sstubs" field.
+ (_bfd_mips_elf_create_dynamic_sections): Use it to cache the stubs
+ section. Don't check whether the section already exists.
+ (_bfd_mips_elf_adjust_dynamic_symbol): Use htab->sstubs.
+ (_bfd_mips_elf_finish_dynamic_symbol): Likewise.
+ (_bfd_mips_elf_finish_dynamic_sections): Likewise.
+ (_bfd_mips_elf_size_dynamic_sections): Likewise. Don't add the
+ dummy stub to an empty section.
+ (_bfd_mips_elf_link_hash_table_create): Initialize the "sstubs" field.
+
+2008-08-06 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * reloc.c (BFD_RELOC_MIPS16_GOT16, BFD_RELOC_MIPS16_CALL16): Declare.
+ * libbfd.h, bfd-in2.h: Regenerate.
+ * elf32-mips.c (elf_mips16_howto_table_rel): Fill in reserved
+ R_MIPS16_GOT16 and R_MIPS16_CALL16 entries.
+ (mips16_reloc_map): Add mappings.
+ * elf64-mips.c (mips16_elf64_howto_table_rel): Fill in reserved
+ R_MIPS16_GOT16 and R_MIPS16_CALL16 entries.
+ (mips16_elf64_howto_table_rela): Likewise.
+ (mips16_reloc_map): Add mappings.
+ * elfn32-mips.c (elf_mips16_howto_table_rel): Fill in reserved
+ R_MIPS16_GOT16 and R_MIPS16_CALL16 entries.
+ (elf_mips16_howto_table_rela): Likewise.
+ (mips16_reloc_map): Add mappings.
+ * elfxx-mips.c (mips_elf_create_shadow_symbol): New function.
+ (section_allows_mips16_refs_p): Likewise.
+ (mips16_stub_symndx): Likewise.
+ (mips_elf_check_mips16_stubs): Treat the data argument as a
+ bfd_link_info. Mark every dynamic symbol as needing MIPS16 stubs
+ and create a "shadow" symbol for the original MIPS16 definition.
+ (mips16_reloc_p, got16_reloc_p, call16_reloc_p, hi16_reloc_p)
+ (lo16_reloc_p, mips16_call_reloc_p): New functions.
+ (_bfd_mips16_elf_reloc_unshuffle): Use mips16_reloc_p to generalize
+ relocation checks.
+ (_bfd_mips16_elf_reloc_shuffle): Likewise.
+ (_bfd_mips_elf_lo16_reloc): Handle R_MIPS16_GOT16.
+ (mips_elf_got16_entry): Add comment.
+ (mips_elf_calculate_relocation): Use hi16_reloc_p,
+ lo16_reloc_p, mips16_call_reloc_p, call16_reloc_p and got16_reloc_p
+ to generalize relocation checks. Use section_allows_mips16_refs_p
+ instead of mips16_stub_section_p. Handle R_MIPS16_CALL16 and
+ R_MIPS16_GOT16, allowing the former to refer directly to a
+ MIPS16 function if its stub is not needed.
+ (mips16_stub_section_p): Delete.
+ (_bfd_mips_elf_symbol_processing): Convert odd-valued function
+ symbols into even MIPS16 symbols.
+ (mips_elf_add_lo16_rel_addend): Use mips16_reloc_p to generalize
+ a relocation check.
+ (_bfd_mips_elf_check_relocs): Calculate "bed" and "rel_end"
+ earlier in the function. Use mips16_stub_symndx to identify
+ the target function. Avoid out-of-bounds accesses when the
+ stub has no relocations; report an error instead. Use
+ section_allows_mips16_refs_p instead of mips16_stub_section_p.
+ Use mips16_call_reloc_p and got16_reloc_p to generalize relocation
+ checks. Handle R_MIPS16_CALL16 and R_MIPS16_GOT16. Don't create
+ dynamic relocations for absolute references to __gnu_local_gp.
+ (_bfd_mips_elf_always_size_sections): Pass a bfd_link_info as
+ the argument to mips_elf_check_mips16_stubs. Generalize comment.
+ (_bfd_mips_elf_relocate_section): Use hi16_reloc_p and got16_reloc_p
+ to generalize relocation checks.
+ (_bfd_mips_elf_finish_dynamic_symbol): If a dynamic MIPS16 function
+ symbol has a non-MIPS16 stub, redirect the symbol to the stub.
+ Fix an overly long line. Don't give dynamic symbols type STO_MIPS16.
+ (_bfd_mips_elf_gc_sweep_hook): Handle R_MIPS16_CALL16 and
+ R_MIPS16_GOT16.
+
+2008-08-06 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-ppc.c (ppc_elf_relax_section): Clear R_PPC_PLTREL24 addend.
+ (ppc_elf_relocate_section <R_PPC_RELAX32_PLT>): Don't bother here.
+
+2008-08-05 Alan Modra <amodra@bigpond.net.au>
+ Jaka MoÄnik <jaka@xlab.si>
+
+ * coffcode.h (coff_slurp_line_table): bfd_alloc lineno_cache first
+ so that we don't inadvertently free it. Use bfd_alloc for sort
+ arrays, and memcpy sorted line table.
+
+2008-08-04 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-spu.c (spu_elf_auto_overlay): Use the maximum possible
+ if --fixed-space request is too large.
+
+2008-08-04 Alan Modra <amodra@bigpond.net.au>
+
+ * Makefile.am (SRC-POTFILES.in, BLD-POTFILES.in): Set LC_ALL=C.
+ * Makefile.in: Regenerate.
+ * po/SRC-POTFILES.in: Regenerate.
+
+2008-08-02 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-spu.c (mark_overlay_section): Move code calculating
+ max_overlay_size to correct block.
+ (spu_elf_auto_overlay): Don't use %x in einfo error message.
+
+2008-08-01 Alan Modra <amodra@bigpond.net.au>
+ Jan Kratochvil <jan.kratochvil@redhat.com>
+
+ * elfcore.h (elf_core_file_p): Ensure we have a backend match
+ with the correct arch size before rejecting the generic fallback.
+ * elfcode.h (elf_object_p): Likewise. Ensure arch size matches
+ before accepting a target.
+
+2008-08-01 Alan Modra <amodra@bigpond.net.au>
+
+ PR 6774
+ * elf.c (rewrite_elf_program_header): Don't wrap p_paddr to
+ include file or program headers.
+
+2008-07-30 Alan Modra <amodra@bigpond.net.au>
+
+ * coff-ppc.c, coffgen.c, ecoff.c, ecofflink.c, elf.c, elf32-frv.c,
+ elf32-iq2000.c, elf32-m32c.c, elf32-mep.c, elf32-mt.c,
+ elf32-sh-symbian.c, elf64-hppa.c, mach-o.c, peXXigen.c, pef.c,
+ ppcboot.c, vms-misc.c, xsym.c: Silence gcc warnings.
+
+2008-07-28 Daniel Jacobowitz <dan@codesourcery.com>
+
+ * elfxx-mips.c (mips_elf_calculate_relocation): Avoid generating
+ relocations for undefined weak symbols with non-default visibility.
+ (_bfd_mips_elf_check_relocs): Use possibly_dynamic_relocs for
+ global symbols in shared libraries.
+ (allocate_dynrelocs): New function.
+ (_bfd_mips_elf_adjust_dynamic_symbol): Do not handle
+ possibly_dynamic_relocs here.
+ (_bfd_mips_elf_size_dynamic_sections): Call allocate_dynrelocs.
+
+2008-07-28 Alexandre Oliva <aoliva@redhat.com>
+
+ * elf32-i386.c (struct elf_i386_link_hash_table): Added field
+ tls_module_base.
+ (elf_i386_link_hash_table_create): Initialize it.
+ (elf_i386_always_size_sections): Set it.
+ (set_tls_module_base): New.
+ (elf_i386_relocate_sections): Call it.
+ * elf64-x86-64.c (struct elf64_x86_64_link_hash_table): Added
+ field tls_module_base.
+ (elf64_x86_64_link_hash_table_create): Initialize it.
+ (elf64_x86_64_always_size_sections): Set it.
+ (set_tls_module_base): New.
+ (elf64_x86_64_relocate_sections): Call it.
+ Reported by Cary Coutant <ccoutant@google.com>
+
+2008-07-28 Ineiev <ineiev@yahoo.co.uk>
+
+ * elf32-arm.c (arm_map_one_stub): Declare variables at beginning
+ of block.
+ * elf32-avr.c (get_local_syms): Likewise.
+
+2008-07-28 Alan Modra <amodra@bigpond.net.au>
+
+ PR 6769
+ * bfd-in.h (BFD_VMA_FMT): Define.
+ (printf_vma, sprintf_vma): Use the above.
+ (_bfd_int64_low, _bfd_int64_high): Delete.
+ * bfd-in2.h: Regenerate.
+
+2008-07-27 Alan Modra <amodra@bigpond.net.au>
+
+ * elf.c (_bfd_elf_make_section_from_shdr): Ignore return from
+ elf_parse_notes. Use bfd_malloc_and_get_section.
+ (elf_parse_notes): Validate note namesz and descsz.
+
+2008-07-26 Michael Eager <eager@eagercon.com>
+
+ * elf32-ppc.c (ppc_elf_merge_obj_attributes): Check compatibility
+ between single-float, double-float, and soft-float.
+
+2008-07-24 Daniel Jacobowitz <dan@codesourcery.com>
+
+ * elf32-mips.c (elf_backend_write_section): Define.
+
+2008-07-24 Nick Clifton <nickc@redhat.com>
+
+ * elf.c (_bfd_elf_map_sections_to_segments): Catch off by one
+ error assigning sections to segments.
+
+2008-07-22 Nick Clifton <nickc@redhat.com>
+
+ * elf.c (_bfd_elf_map_sections_to_segments): Allow sections in
+ adjoining pages to be included in the same segment.
+
+2008-07-22 Simon Baldwin <simonb@google.com>
+
+ * elflink.c (elf_link_output_extsym): Set st_size to zero for
+ symbols from dynamic libraries.
+
+2008-07-21 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/4424
+ * elflink.c (_bfd_elf_merge_symbol): Call bed->relocs_compatible
+ to check if 2 inputs are compatible.
+
+2008-07-21 Sterling Augustine <sterling@tensilica.com>
+
+ * elf.c (assign_file_positions_for_load_sections): Print vma in
+ error message about overlapping section vmas.
+
+2008-07-21 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/6747
+ * elf32-frv.c (elf32_frv_relocate_section): Revert the change
+ for PR ld/6446 checked in by accident on May 21, 2008.
+
+2008-07-21 Nick Clifton <nickc@redhat.com>
+
+ * coff-sh.c (bfd_pe_print_pdata): Define to NULL for non
+ COFF_WITH_PE based SH ports.
+ * libpei.h (_bfd_XX_print_ce_compressed_pdata): Prototype.
+ * arm-wince-pe.c (bfd_pe_print_pdata): Use
+ _bfd_pe_print_ce_compressed_pdata.
+ (slurp_symcache, cleanup_syms, pe_print_ce_compressed_pdata): Move
+ to...
+ * peXXigen.c: ... here and rename pe_print_ce_compressed_pdata to
+ _bfd_XX_print_ce_compressed_pdata.
+
+2008-07-21 Alan Modra <amodra@bigpond.net.au>
+
+ * elf-eh-frame.c (_bfd_elf_discard_section_eh_frame): Drop
+ unwanted zero terminators.
+
+2008-07-21 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-spu.c (spu_elf_relocate_section): Expand
+ RELOC_FOR_GLOBAL_SYMBOL. Don't warn about undefined symbols for
+ R_SPU_PPU32 and R_SPU_PPU64 relocations.
+
+2008-07-21 Luis Machado <luisgpm@br.ibm.com>
+
+ * elf-bfd.h: Declare elfcore_write_ppc_vsx.
+ * elf.c (elfcore_grok_ppc_vsx): New function.
+ (elfcore_write_ppc_vsx): New function
+ (elfcore_grok_note): Handle VSX notes.
+ (elfcore_write_register_note): Handle VSX notes.
+
+2008-07-18 Joseph Myers <joseph@codesourcery.com>
+
+ * bfd-in.h (bfd_elf32_arm_set_target_relocs): Add new parameter.
+ * bfd-in2.h: Regenerate.
+ * elf32-arm.c (struct elf_arm_obj_tdata): Add field
+ no_wchar_size_warning.
+ (bfd_elf32_arm_set_target_relocs): Add new parameter
+ no_wchar_warn.
+ (elf32_arm_merge_eabi_attributes): Give a warning, not an error,
+ for conflicting wchar_t attributes. Do not warn if
+ --no-wchar-size-warning. Make diagnostic text more specific.
+
+2008-07-18 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/6748
+ * elf32-arm.c (elf32_arm_link_hash_table_create): Initialize
+ new fields added for ARM long call support.
+
+2008-07-18 Danny Backx <dannybackx@users.sourceforge.net>
+
+ * pe-arm-wince.c (pe_print_compressed_pdata): Define new function to
+ print compressed pdata structure as described on MSDN. This only
+ applies to a limited set of architectures (ARM, SH4).
+ (slurp_symtab, my_symbol_for_address): Define static helper
+ functions for pe_print_compressed_pdata.
+ * coffcode.h (bfd_coff_backend_data): Add _bfd_coff_print_pdata field.
+ (bfd_coff_have_print_pdata, bfd_coff_print_pdata): Define.
+ * bfd/peXXigen.c (_bfd_XX_print_private_bfd_data_common): Add check on
+ bfd_coff_backend_data, call the function if non-null.
+ * pei-mcore.c: Add target dependent initialisation for
+ bfd_coff_backend_data.
+ * coff-sh.c: Likewise.
+ * coff64-rs6000.c: Likewise.
+ * coff-rs6000.c: Likewise.
+ * libcoff-in.h: Likewise.
+ * cf-i386lynx.c: Likewise.
+ * coff-alpha.c: Likewise.
+ * coff-apollo.c: Likewise.
+ * coff-arm.c: Likewise.
+ * coff-aux.c: Likewise.
+ * coff-h8300.c: Likewise.
+ * coff-h8500.c: Likewise.
+ * coff-i386.c: Likewise.
+ * coff-i860.c: Likewise.
+ * coff-i960.c: Likewise.
+ * coff-ia64.c: Likewise.
+ * coff-m68k.c: Likewise.
+ * coff-m88k.c: Likewise.
+ * coff-maxq.c: Likewise.
+ * coff-mips.c: Likewise.
+ * coff-or32.c: Likewise.
+ * coff-sparc.c: Likewise.
+ * coff-tic30.c: Likewise.
+ * coff-tic4x.c: Likewise.
+ * coff-tic54x.c: Likewise.
+ * coff-tic80.c: Likewise.
+ * coff-w65.c: Likewise.
+ * coff-we32k.c: Likewise.
+ * coff-x86_64.c: Likewise.
+ * coff-z80.c: Likewise.
+ * coff-z8k.c: Likewise.
+ * pe-mcore.c: Likewise.
+ * pe-mips.c: Likewise.
+ * pe-ppc.c: Likewise.
+ * peXXigen.c: Likewise.
+ * pei-ppc.c: Likewise.
+ * libcoff.h: Regenerate.
+
+2008-07-16 Bernd Schmidt <bernd.schmidt@analog.com>
+
+ * elf32-bfin.c (bfin_check_relocs, bfin_relocate_section,
+ bfin_final_link_relocate, bfin_gc_mark_hook, bfin_gc_sweep_hook,
+ ELF_DYNAMIC_INTERPRETER, DEFAULT_STACK_SIZE,
+ struct _bfinfdpic_dynamic_got_info): Moved around to keep FD-PIC code
+ separate from non-FD-PIC.
+
+2008-07-14 DJ Delorie <dj@redhat.com>
+
+ * elf-m10300.c (mn10300_elf_final_link_relocate): Correct overflow
+ checks for PCREL8, PCREL16, GOTPC16, GOTOFF16, PLT16, and GOT16
+ relocs.
+ (mn10300_elf_relax_section): Correct jump offset check when target
+ is in a different section.
+
+2008-07-15 Jie Zhang <jie.zhang@analog.com>
+
+ * elf32-bfin.c (elf32_bfin_special_sections[]): New.
+ (elf_backend_special_sections): Define.
+
+2008-07-13 Craig Silverstein <csilvers@google.com>
+
+ PR binutils/6743
+ * dwarf2.c (struct dwarf2_debug): New variable info_ptr_memory.
+ (find_line): Use info_ptr_memory instead of sec_info_ptr.
+ (_bfd_dwarf2_cleanup_debug_info): Likewise.
+
+2008-07-12 Jie Zhang <jie.zhang@analog.com>
+
+ Revert
+ 2008-07-12 Jie Zhang <jie.zhang@analog.com>
+ * elf.c (_bfd_elf_map_sections_to_segments): Don't put
+ executable sections into the same segment with other
+ read only sections if --sep-code.
+ * elf32-bfin.c (elf32_bfin_code_in_l1): New variable.
+ (elf32_bfin_data_in_l1): New variable.
+ (elf32_bfin_final_write_processing): New.
+ (elf32_bfin_special_sections[]): New.
+ (elf_backend_final_write_processing): Define.
+ (elf_backend_special_sections): Define.
+
+2008-07-12 Jie Zhang <jie.zhang@analog.com>
+
+ * elf.c (_bfd_elf_map_sections_to_segments): Don't put
+ executable sections into the same segment with other
+ read only sections if --sep-code.
+ * elf32-bfin.c (elf32_bfin_code_in_l1): New variable.
+ (elf32_bfin_data_in_l1): New variable.
+ (elf32_bfin_final_write_processing): New.
+ (elf32_bfin_special_sections[]): New.
+ (elf_backend_final_write_processing): Define.
+ (elf_backend_special_sections): Define.
+
+2008-07-11 Andreas Schwab <schwab@suse.de>
+
+ * dwarf2.c (read_section): Take pointer to bfd_size_type instead
+ of unsigned long as last parameter.
+ (struct dwarf2_debug): Define dwarf_abbrev_size, dwarf_line_size,
+ dwarf_str_size and dwarf_ranges_size as bfd_size_type instead of
+ unsigned long.
+
+2008-07-10 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * elfxx-mips.c (mips_elf_calculate_relocation): Calculate GP and GP0
+ for all relocation types. Allow any type of relocation to refer to
+ __gnu_local_gp.
+
+2008-07-10 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * elfxx-mips.c (mips_elf_check_mips16_stubs): Use ELF_ST_IS_MIPS16.
+ (mips_elf_calculate_relocation): Likewise.
+ (_bfd_mips_elf_add_symbol_hook): Likewise.
+ (_bfd_mips_elf_finish_dynamic_symbol): Likewise.
+ (_bfd_mips_vxworks_finish_dynamic_symbol): Likewise.
+
+2008-07-10 Andreas Schwab <schwab@suse.de>
+
+ * elfxx-mips.c (_bfd_mips_elf_section_from_shdr): Add missing
+ paren.
+
+2008-07-09 Craig Silverstein <csilvers@google.com>
+
+ * Makefile.am (BFD32_LIBS): Add compress.lo.
+ (BFD32_LIBS_CFILES): Add compress.c.
+ (BFD_H_FILES): Likewise.
+ * Makefile.in: Regenerate.
+ * bfd-in2.h: Regenerate.
+ * config.in: Add HAVE_ZLIB_H
+ * configure.in: Add test for libz and zlib.h
+ * configure: Regenerate.
+ * dwarf2.c (read_section): New function.
+ (read_indirect_string): Call new function read_section.
+ (read_abbrevs): Likewise.
+ (decode_line_info): Likewise.
+ (read_debug_ranges): Likewise.
+ (find_line): Call new function read_section when just one
+ .zdebug_info section is found, otherwise read and compress
+ multiple sections.
+ (_bfd_dwarf2_cleanup_debug_info): Free sec_info_ptr.
+ * elf.c (_bfd_elf_make_section_from_shdr): Add zdebug prefix.
+ (special_sections_z): New struct.
+ (special_sections): Refer to special_sections_z.
+ * elfxx-mips.c (_bfd_mips_elf_section_from_shdr): Recognize
+ sections named .zdebug_*.
+ (_bfd_mips_elf_fake_sections): Likewise.
+ * compress.c: New file.
+ (bfd_uncompress_section_contents): New function.
+
+2008-07-07 Christophe Lyon <christophe.lyon@st.com>
+
+ * elf32-arm.c (arm_type_of_stub): Don't crash on local symbols in
+ the presence of a PLT.
+
+2008-07-07 Alan Modra <amodra@bigpond.net.au>
+
+ * bfd.c (bfd_demangle): Always trim off bfd_get_symbol_leading_char.
+
+2008-07-02 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-ppc.c (is_pic_glink_stub): New function.
+ (ppc_elf_get_synthetic_symtab): Don't generate symbols when
+ multiple shared/pie stubs per plt entry.
+
+2008-06-30 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * elf.c (_bfd_elf_get_synthetic_symtab): Increment p by
+ bed->s->int_rels_per_ext_rel.
+
+2008-06-30 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * syms.c (BSF_SYNTHETIC): New flag.
+ * elf.c (_bfd_elf_get_synthetic_symtab): Set it.
+ * elf32-ppc.c (ppc_elf_get_synthetic_symtab): Likewise.
+ * elf64-ppc.c (ppc64_elf_get_synthetic_symtab): Likewise.
+ * bfd-in.h (bfd_asymbol_flavour): Return bfd_target_unknown_flavour
+ for synthetic symbols.
+ * bfd-in2.h: Regenerate.
+
+2008-06-30 Daniel Jacobowitz <dan@codesourcery.com>
+
+ * elf32-arm.c (record_arm_to_thumb_glue, record_thumb_to_arm_glue):
+ Expand comments.
+ (arm_map_one_stub): Use | 1 when setting the low bit.
+
+2008-06-29 Andreas Schwab <schwab@suse.de>
+
+ * elf32-m68k.c (elf_m68k_relocate_section): Don't ignore existing
+ addend on _GLOBAL_OFFSET_TABLE_.
+
+2008-06-24 Daniel Jacobowitz <dan@codesourcery.com>
+
+ * elf32-arm.c (STUB_ENTRY_NAME): Define.
+ (arm_thumb_thumb_long_branch_stub): Use bx instead of b.n.
+ (arm_pic_long_branch_stub): Mention R_ARM_REL32 instead of
+ R_ARM_ABS32.
+ (struct elf32_arm_stub_hash_entry): Add output_name.
+ (arm_build_one_stub): Move offsets into the offset argument
+ of _bfd_final_link_relocate. Correct offset for
+ arm_thumb_arm_v4t_stub_long_branch.
+ (elf32_arm_size_stubs): Set stub_entry->output_name.
+ (elf32_arm_ouput_plt_map_sym): Rename to elf32_arm_output_map_sym.
+ Update all callers.
+ (elf32_arm_output_stub_sym): New.
+ (arm_map_one_stub): Correct formatting. Use elf32_arm_output_stub_sym.
+
+2008-06-20 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-spu.c (needs_ovl_stub): Correctly return nonovl_stub for
+ non-branch insns.
+
+2008-06-20 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-spu.c (build_stub): Allow wraparound on stub branches.
+ (allocate_spuear_stubs, build_spuear_stubs): Return value from
+ count_stub/build_stub.
+ (spu_elf_build_stubs): Correct location of stub reloc error message.
+
+2008-06-18 M R Swami Reddy <MR.Swami.Reddy@nsc.com>
+
+ * elf32-cr16.c (ELF_MACHINE_ALT1): Define to EM_CR16_OLD.
+
+2008-06-17 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
+
+ * configure: Regenerate.
+
+2008-06-17 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-spu.c (struct spu_link_hash_table): Add extra_stack_space.
+ (spu_elf_check_vma): Add extra_stack_space param, copy to htab.
+ (spu_elf_auto_overlay): Use it.
+ (RECURSE_UNMARK): Define as 0.
+ (unmark_overlay_section): Heed RECURSE_UNMARK.
+ * elf32-spu.h (spu_elf_check_vma): Update prototype.
+
+2008-06-12 DJ Delorie <dj@redhat.com>
+
+ * elf32-m32c.c (ELF_MACHINE_ALT1): Define as EM_M32C_OLD.
+
+2008-06-09 Paul Brook <paul@codesourcery.com>
+
+ bfd/
+ * elf32-arm.c (elf32_arm_merge_private_bfd_data): Allow BE8 shared
+ libraries.
+
+2008-06-09 Christophe Lyon <christophe.lyon@st.com>
+
+ * elf32-arm.c (arm_stub_is_thumb): Define.
+ (elf32_arm_final_link_relocate): Handle near mode switching stubs.
+
+2008-06-07 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-spu.c (spu_elf_auto_overlay): Add valid area below sp
+ to stack calculation.
+
+2008-06-06 Paul Brook <paul@codesourcery.com>
+
+ bfd/
+ * elf32-arm.c (elf32_arm_merge_private_bfd_data): Reject BE8 input.
+
+2008-06-06 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-spu.c (spu_elf_auto_overlay): Relax requirement that
+ file names be unique. Specify archive:path in overlay script.
+
+2008-06-05 Alan Modra <amodra@bigpond.net.au>
+
+ PR ld/6590
+ * elf64-ppc.c (ppc_build_one_stub): Correct reloc offsets.
+
+2008-06-04 Alan Modra <amodra@bigpond.net.au>
+
+ * elf.c (ignore_section_sym): Don't test section sym value here.
+ (elf_map_symbols): Instead check zero value here as was done prior
+ to 2006-05-26 change.
+
+2008-06-04 Nick Clifton <nickc@redhat.com>
+
+ PR ld/6019
+ * elf32-avr.c (elf32_avr_relax_section): Handle the case where
+ there are no local symbols.
+
+2008-06-04 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-spu.c (get_sym_h): Don't attempt to read global syms.
+ (process_stubs): Likewise.
+ (discover_functions): Don't used cached symbols.
+ (maybe_insert_function): Correct condition under which function
+ array is realloc'd.
+ (mark_functions_via_relocs): Delete unused variable.
+
+2008-05-30 Frediano Ziglio <frediano.ziglio@vodafone.com>
+ Nick Clifton <nickc@redhat.com>
+
+ PR ld/6511
+ * elf64-hppa.c (allocate_global_data_opd): Default to using the
+ dynamic symbol table for local function names in shared libraries.
+
+2008-05-29 Jan Kratochvil <jan.kratochvil@redhat.com>
+
+ * elf.c (assign_file_positions_for_load_sections): Adjust pre-section
+ gaps based on VMA and P_VADDR instead of LMA and P_PADDR addresses.
+
+2008-05-28 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-spu.c (spu_elf_object_p): New function.
+ (elf_backend_object_p): Define.
+ (build_stub): Correct second word of 8 byte overlay stubs.
+ (spu_elf_relocate_section): Formatting.
+
+2008-05-24 Carlos Eduardo Seo <cseo@linux.vnet.ibm.com>
+
+ * elf.c (elfcore_write_register_note): New function.
+ * elf-bfd.h (elfcore_write_register_note): New prototype.
+
+2008-05-22 Christophe Lyon <christophe.lyon@st.com>
+
+ * elf32-arm.c (arm_type_of_stub): Ignore STT_SECTION symbols.
+ (elf32_arm_stub_add_mapping_symbol): Remove.
+ (elf32_arm_add_stub): Don't generate mapping symbols. Change
+ prototype.
+ (elf32_arm_size_stubs): Use new elf32_arm_add_stub
+ prototype. Don't generate thumb to arm glue for calls.
+ (arm_map_one_stub): Define.
+ (elf32_arm_output_arch_local_syms): Generate mapping symbols for
+ long calls stubs.
+
+2008-05-21 Nick Clifton <nickc@redhat.com>
+
+ * elf32-arm.c (group_sections): Reformat comments.
+
+ PR ld/6446
+ * elf32-frv.c (elf32_frv_relocate_section): Set EF_FRV_PIC by
+ default (for FDPIC). Clear it if any inter-segment relocations
+ are found.
+
+ * elf64-hppa.c (elf64_hppa_finalize_opd): Check NULL return
+ from elf_link_hash_lookup.
+
+2008-05-21 Maxim Kuvyrkov <maxim@codesourcery.com>
+
+ Add multi-GOT support for m68k.
+ * elf32-m68k.c (struct elf_m68k_link_hash_entry: got_entry_key,
+ glist): New fields.
+ (struct elf_m68k_got_entry_key, struct elf_m68k_got_entry,
+ struct elf_m68k_got, struct elf_m68k_bfd2got_entry,
+ struct elf_m68k_multi_got): New data structures.
+ (struct elf_m68k_link_hash_table: local_gp_p, use_neg_got_offsets_p,
+ allow_multigot_p, multi_got_): New fields.
+ (elf_m68k_multi_got): New macro.
+ (elf_m68k_link_hash_newfunc): Initialize new fields of
+ struct elf_m68k_link_hash_entry.
+ (elf_m68k_link_hash_table_create): Initialize new fields of
+ struct elf_m68k_link_hash_table.
+ (elf_m68k_link_hash_table_free): New static function implementing hook.
+ (elf_m68k_init_got, elf_m68k_clear_got, elf_m68k_create_empty_got): New
+ static functions for struct elf_m68k_got.
+ (elf_m68k_init_got_entry_key, elf_m68k_got_entry_hash,
+ elf_m68k_got_entry_eq): New static functions for
+ struct elf_m68k_got_entry.
+ (ELF_M68K_REL_8O_MAX_N_ENTRIES_IN_GOT,
+ ELF_M68K_REL_8O_16O_MAX_N_ENTRIES_IN_GOT): New macros.
+ (enum elf_m68k_get_entry_howto): New enum.
+ (elf_m68k_get_got_entry, elf_m68k_update_got_entry_type,
+ elf_m68k_remove_got_entry_type): New static functions for
+ struct elf_m68k_got_entry.
+ (elf_m68k_add_entry_to_got): New static function.
+ (elf_m68k_bfd2got_entry_hash, elf_m68k_bfd2got_entry_eq,
+ elf_m68k_bfd2got_entry_del, elf_m68k_get_bfd2got_entry): New static
+ functions for struct elf_m68k_bfd2got_entry.
+ (struct elf_m68k_can_merge_gots_arg, elf_m68k_can_merge_gots_1,
+ elf_m68k_can_merge_gots): New traversal.
+ (struct elf_m68k_merge_gots_arg, elf_m68k_merge_gots_1,
+ elf_m68k_merge_gots): Ditto.
+ (struct elf_m68k_finalize_got_offsets_arg,
+ elf_m68k_finalize_got_offsets_1, elf_m68k_finalize_got_offsets): Ditto.
+ (struct elf_m68k_partition_multi_got_arg,
+ elf_m68k_partition_multi_got_1, elf_m68k_init_symndx2h_1,
+ elf_m68k_partition_multi_got): Ditto.
+ (elf_m68k_find_got_entry_ptr, elf_m68k_remove_got_entry): New static
+ functions.
+ (elf_m68k_copy_indirect_symbol): New static function implementing
+ a hook.
+ (elf_m68k_check_relocs): Update to add entries to multi-GOT.
+ (elf_m68k_gc_sweep_hook): Update to remove entries from multi-GOT.
+ (elf_m68k_always_size_sections): Assign BFDs to GOTs.
+ (elf_m68k_relocate_section): Update to properly handle GOT relocations.
+ (elf_m68k_finish_dynamic_symbol): Update to traverse all GOT entries
+ of a global symbol.
+ (bfd_elf_m68k_set_target_options): New function.
+ (bfd_elf32_bfd_link_hash_table_free): Define hook.
+ (bfd_elf32_bfd_final_link): Change expansion to bfd_elf_final_link
+ to skip generic calculation of GOT offsets.
+ (elf_backend_copy_indirect_symbol): Define hook.
+ * bfd-in.h (bfd_elf_m68k_set_target_options): Declare function.
+ * bfd-in2.h: Regenerate.
+
+2008-05-21 André Johansen <andrejoh@gmail.com>
+
+ PR 868
+ * dwarf2.c (_bfd_dwarf2_cleanup_debug_info): Free memory allocated
+ for filenames in function tables and variable tables.
+
+2008-05-19 Alan Modra <amodra@bigpond.net.au>
+
+ PR 2995, PR 6473
+ * elf.c (_bfd_elf_make_section_from_shdr): Leave lma equal to
+ vma when all p_paddr fields are zero and there is more than
+ one PT_LOAD header.
+
+2008-05-15 Christophe Lyon <christophe.lyon@st.com>
+
+ Add long call support for ARM.
+ * elf32-arm.c (THM2_MAX_FWD_BRANCH_OFFSET): Define.
+ (THM2_MAX_BWD_BRANCH_OFFSET): Define.
+ (ARM_MAX_FWD_BRANCH_OFFSET): Define.
+ (ARM_MAX_BWD_BRANCH_OFFSET): Define.
+ (THM_MAX_FWD_BRANCH_OFFSET): Define.
+ (THM_MAX_BWD_BRANCH_OFFSET): Define.
+ (arm_long_branch_stub): Define.
+ (arm_pic_long_branch_stub): Define.
+ (arm_thumb_v4t_long_branch_stub): Define.
+ (arm_thumb_thumb_long_branch_stub): Define.
+ (arm_thumb_arm_v4t_long_branch_stub): Define.
+ (STUB_SUFFIX): Define.
+ (elf32_arm_stub_type): Define.
+ (elf32_arm_stub_hash_entry): Define.
+ (elf32_arm_link_hash_entry): Add stub_cache field.
+ (arm_stub_hash_lookup): Define.
+ (elf32_arm_link_hash_table): Add stub_hash_table, stub_bfd,
+ add_stub_section, layout_sections_again, stub_group, bfd_count,
+ top_index, input_list fields.
+ (elf32_arm_link_hash_newfunc): Init new field.
+ (stub_hash_newfunc): New function.
+ (elf32_arm_link_hash_table_create): Init stub_hash_table.
+ (elf32_arm_hash_table_free): New function.
+ (arm_type_of_stub): New function.
+ (elf32_arm_stub_name): New function.
+ (elf32_arm_get_stub_entry): New function.
+ (elf32_arm_stub_add_mapping_symbol): New function.
+ (elf32_arm_add_stub): New function.
+ (arm_build_one_stub): New function.
+ (arm_size_one_stub): New function.
+ (elf32_arm_setup_section_lists): New function.
+ (elf32_arm_next_input_section): New function.
+ (group_sections): New function.
+ (elf32_arm_size_stubs): New function.
+ (elf32_arm_build_stubs): New function.
+ (bfd_elf32_arm_add_glue_sections_to_bfd): Skip stub sections.
+ (bfd_elf32_arm_process_before_allocation): No longer handle
+ R_ARM_CALL and R_ARM_THM_CALL.
+ (using_thumb_only): New function.
+ (elf32_arm_final_link_relocate): Redirect calls to stub if range
+ exceeds encoding capabilities.
+ (bfd_elf32_bfd_link_hash_table_free): Define.
+ * bfd-in.h (R_ARM_max): Fix value to 130.
+ (elf32_arm_setup_section_lists): Protype.
+ (elf32_arm_next_input_section): Protype.
+ (elf32_arm_size_stubs): Protype.
+ (elf32_arm_build_stubs): Protype.
+ * bfd-in2.h: Regenerate.
+
+2008-05-14 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * elf32-ppc.c (ppc_elf_get_synthetic_symtab): Fix memset calls.
+ * elf64-ppc.c (ppc64_elf_get_synthetic_symtab): Likewise.
+
+2008-05-14 Alan Modra <amodra@bigpond.net.au>
+
+ * Makefile.am: Run "make dep-am".
+ * Makefile.in: Regenerate.
+
+2008-05-14 Ulrich Weigand <uweigand@de.ibm.com>
+ Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-ppc.c (section_covers_vma): New function.
+ (ppc_elf_get_synthetic_symtab): New function.
+ (bfd_elf32_get_synthetic_symtab): Define.
+ * elf64-ppc.c (section_covers_vma): New function.
+ (ppc64_elf_get_synthetic_symtab): Generate sym@plt on glink branch
+ table entries, and __glink_PLTresolve on resolver stub.
+ (ppc64_elf_build_stubs): Rename __glink sym to __glink_PLTresolve.
+
+2008-05-12 Alan Modra <amodra@bigpond.net.au>
+
+ PR 6443
+ * elf32-ppc.c (MUST_BE_DYN_RELOC): Delete.
+ (must_be_dyn_reloc): New function.
+ (ppc_elf_check_relocs): Don't set DF_STATIC_TLS for tprel relocs
+ in pies.
+ (ppc_elf_tls_optimize): Optimise pies.
+ (ppc_elf_relocate_section): Use a section symbol rather than no
+ symbol if possible for LD->IE TLS sequence, but don't error if
+ we must use no symbol.
+ * elf64-ppc.c (MUST_BE_DYN_RELOC): As for elf32-ppc.c.
+ (must_be_dyn_reloc): Likewise.
+ (ppc64_elf_check_relocs): Likewise.
+ (ppc64_elf_tls_optimize): Likewise.
+ (ppc64_elf_relocate_section): Likewise.
+
+2008-05-12 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-spu.c (spu_elf_relocate_section): Rename is_ea to is_ea_sym.
+
+2008-05-10 Paul Pluzhnikov <ppluzhnikov@google.com>
+
+ * elfcore.h (elf_core_file_p): Warn about core truncation.
+
+2008-05-07 Bob Wilson <bob.wilson@acm.org>
+
+ * elf32-xtensa.c (xtensa_property_section_name): New.
+ (xtensa_make_property_section): New.
+ (xtensa_get_property_section): Make static. Do not create a new
+ section if it does not exist.
+
+2008-05-08 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-spu.c (spu_elf_special_sections): Add "._ea".
+ (spu_elf_relocate_section): Handle relocations against symbols
+ defined in ._ea specially.
+
+2008-05-03 Daniel Jacobowitz <dan@codesourcery.com>
+
+ * elf32-arm.c (elf32_arm_symbian_link_hash_table_create): Use
+ ARRAY_SIZE.
+ (elf32_arm_symbian_plt_sym_val): New.
+ (elf_backend_plt_sym_val): Define.
+
+2008-05-03 Alan Modra <amodra@bigpond.net.au>
+
+ PR 2995, PR 6473
+ * elf.c (rewrite_elf_program_header): Rather than clearing
+ p_paddr_valid at end, don't set it in the first place. Delete
+ comment no longer relevant. When not p_paddr_valid, don't set
+ paddr from vaddr, and don't set p_vaddr_offset.
+
+2008-05-01 Cary Coutant <ccoutant@google.com>
+
+ * elf.c (bfd_elf_get_str_section): Fix memory leak caused by
+ corrupt string table.
+
+2008-05-01 Joel Brobecker <brobecker@adacore.com>
+
+ * cache.c (cache_bread_1): Renames cache_bread.
+ (cache_bread): New function.
+
+2008-05-01 Alan Modra <amodra@bigpond.net.au>
+
+ PR 2995, PR 6473
+ * elf.c (_bfd_elf_make_section_from_shdr): Always set lma from p_paddr.
+ (assign_file_positions_for_load_sections): Combine nested "if".
+ (copy_elf_program_header): Don't set p_paddr_valid or p_vaddr_offset
+ when all header p_paddr fields are zero.
+
+2008-04-30 Edmar Wienskoski <edmar@freescale.com>
+
+ * cpu-powerpc.c (bfd_powerpc_archs): Add e500mc entry.
+
+2008-04-29 Daniel Jacobowitz <dan@codesourcery.com>
+
+ * elf.c (_bfd_elf_get_dynamic_reloc_upper_bound)
+ (_bfd_elf_canonicalize_dynamic_reloc): Find dynamic relocations
+ even if they are not loaded.
+ * elflink.c (_bfd_elf_init_2_index_sections): Set data_index_section
+ first.
+
+2008-04-25 Jay Foad <jay.foad@gmail.com>
+
+ * reloc16.c (bfd_coff_reloc16_get_value): Add support for
+ undefined weak symbols.
+
+2008-04-25 Nick Clifton <nickc@redhat.com>
+
+ * po/vi.po: Updated Vietnamese translation.
+
+2008-04-23 Paolo Bonzini <bonzini@gnu.org>
+
+ * aclocal.m4: Regenerate.
+ * configure: Regenerate.
+
+2008-04-21 Cary Coutant <ccoutant@google.com>
+
+ * archive.c (_bfd_write_archive_contents): Fix incorrect use of
+ ARFMAG.
+
+2008-04-21 Nathan Sidwell <nathan@codesourcery.com>
+
+ * elfxx-mips.c (_bfd_mips_vxworks_adjust_dynamic_symbol): Don't
+ set the value of undefined symbols in shared objects.
+ (_bfd_mips_vxworks_finish_dynamic_symbol): Clear value for
+ undefined symbols unless pointer equality is needed.
+
+2008-04-18 Dennis Roberts <dennis.roberts@sunquestinfo.com>
+
+ * aix5ppc-core.c: Define macros for the default architecture and
+ machine for matching core files.
+ (xcoff64_core_p): Set the architecture and machine to the default
+ values defined in the macros mentioned above.
+ * rs6000-core.c: Define macros to determine whether or not the
+ core file header uses the core_dumpxx header format.
+ (rs6000coff_core_p): Don't match core files that use the
+ core_dumpxx header format.
+
+2008-04-16 Pedro Alves <pedro@codesourcery.com>
+
+ * config.bfd (i[3-7]86-*-dicos*, x86_64-*-dicos*): Add.
+
+2008-04-16 David S. Miller <davem@davemloft.net>
+
+ * reloc.c (BFD_RELOC_SPARC_GOTDATA_HIX22,
+ BFD_RELOC_SPARC_GOTDATA_LOX10, BFD_RELOC_SPARC_GOTDATA_OP_HIX22,
+ BFD_RELOC_SPARC_GOTDATA_OP_LOX10, BFD_RELOC_SPARC_GOTDATA_OP): New.
+ * libbfd.h: Regnerate.
+ * bfd-in2.h: Regenerate.
+ * elfxx-sparc.c (_bfd_sparc_elf_howto_table): Add entries for
+ GOTDATA relocations.
+ (sparc_reloc_map): Likewise.
+ (_bfd_sparc_elf_check_relocs): Handle R_SPARC_GOTDATA_* like
+ R_SPARC_GOT*.
+ (_bfd_sparc_elf_gc_sweep_hook): Likewise.
+ (_bfd_sparc_elf_relocate_section): Transform R_SPARC_GOTDATA_HIX22,
+ R_SPARC_GOTDATA_LOX10, R_SPARC_GOTDATA_OP_HIX22, and
+ R_SPARC_GOTDATA_OP_LOX10 into the equivalent R_SPARC_GOT* reloc.
+ Simply ignore R_SPARC_GOTDATA_OP relocations.
+
+2008-04-14 Aurelien Jarno <aurelien@aurel32.net>
+
+ * configure.in: Link with the PIC version of libiberty on
+ Linux/MIPS hosts.
+ * configure: Regenerate.
+
+2008-04-14 Edmar Wienskoski <edmar@freescale.com>
+
+ * archures.c: Add bfd_mach_ppc_e500mc.
+ * bfd-in2.h: Regenerate.
+
+2008-04-08 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-spu.c (spu_elf_build_stubs): Correct error message.
+ (mark_functions_via_relocs): Remove premature init of symtab_hdr.
+ (collect_overlays): Commment typo fix.
+
+2008-04-08 Kees Cook <kees@canonical.com>
+
+ * elflink.c (bfd_elf_size_dynamic_sections): Ignore GNU-stack note
+ in EXEC_P bfds.
+
+2008-04-08 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-spu.c: Include libiberty.h.
+ (struct spu_link_hash_table): Add local_stire, overlay_fixed, reserved,
+ non_ovly_stub, spu_elf_load_ovl_mgr, spu_elf_open_overlay_script,
+ spu_elf_relink, auto_overlay fields.
+ (AUTO_OVERLAY, AUTO_RELINK, OVERLAY_RODATA): Define.
+ (needs_ovl_stub): Flip test so that call to non-function warning
+ is emitted during relocate_section rather than earlier.
+ (spu_elf_check_vma): Stash --auto-overlay parameters, and clear
+ auto_overlay if no section exceeds local store.
+ (struct call_info): Add count, max_depth, is_pasted fields.
+ (struct function_info): Add rodata, last_caller, call_count,
+ depth, new visit flags.
+ (insert_callee): Increment call count.
+ (copy_callee): New function.
+ (mark_functions_via_relocs): Investigate all reloc types to count
+ possible function pointer stubs for --auto-overlay. Track
+ last_caller and increment function call_count.
+ (pasted_function): Insert a "call" into call info for pasted section.
+ (remove_cycles): Track max depth of calls. Don't emit call graph
+ pruning warning for --auto-overlay.
+ (build_call_tree): Don't transfer_calls for --auto-overlay.
+ Adjust remove_cycles call.
+ (sort_calls, sort_lib, sort_bfds): New functions.
+ (struct _mos_param, struct _uos_param, struct _cl_param): New.
+ (mark_overlay_section, unmark_overlay_section): New functions.
+ (collect_lib_sectios, auto_ovl_lib_functions): New functions.
+ (collect_overlays, find_pasted_call): New functions.
+ (sum_stack): Deal with is_pasted "calls". Exit before printing
+ when --auto-overlay.
+ (spu_elf_auto_overlay): New function.
+ (spu_elf_final_link): Call spu_elf_auto_overlay.
+ * elf32-spu.h (spu_elf_check_vma): Update prototype.
+
+2008-04-07 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-spu.c (allocate_spuear_stubs): Ensure _SPUEAR_ symbol
+ is defined in overlay section before creating a stub.
+ (build_spuear_stubs): Likewise.
+ (spu_elf_size_stubs, spu_elf_build_stubs): Adjust calls.
+
+2008-04-02 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-spu.c (insert_callee): Reorder call list so most recent
+ call is always first.
+ (interesting_section): Move.
+ (mark_functions_via_relocs): Fold interesting_section and
+ reloc_count tests in callers to here. Simplify output section
+ owner test.
+ (discover_functions): Set "gaps" when no symbols and some
+ "interesting_section". Run pasted_function loop for no symbol
+ bfds.
+ (for_each_node, transfer_calls): New functions.
+ (mark_non_root): Adjust to suit for_each_node.
+ (call_graph_traverse): Likewise. Fix memory leak. Rename to..
+ (remove_cycles): ..this.
+ (build_call_tree): Use for_each_node and transfer_calls.
+ (struct _sum_stack_param): New.
+ (sum_stack): Adjust to suit for_each_node. Return error on
+ malloc failure. Move code to print root node cumulative stack from..
+ (spu_elf_stack_analysis): ..here. Use for_each_node.
+
+2008-03-31 Cary Coutant <ccoutant@google.com>
+
+ PR 6006
+ * archive.c (_bfd_slurp_extended_name_table): Change
+ ARFMAG[0] to ARFMAG[1].
+ (_bfd_construct_extended_name_table): Likewise.
+
+2008-03-31 Daniel Jacobowitz <dan@codesourcery.com>
+
+ * elfxx-mips.c (mips_elf_record_got_page_entry): Update comment.
+ (_bfd_mips_elf_check_relocs): Update comments. Always call
+ mips_elf_record_got_page_entry for R_MIPS_GOT_PAGE.
+
+2008-03-27 Cary Coutant <ccoutant@google.com>
+
+ Add support for thin archives.
+ * archive.c (_bfd_find_nested_archive): New function.
+ (get_extended_arelt_filename): Add origin parameter.
+ (_bfd_generic_read_ar_hdr_mag): Deal with extended name
+ combined with a file offset.
+ (append_relative_path): New function.
+ (_bfd_get_elt_at_filepos): Deal with external members and
+ nested archives.
+ (bfd_generic_openr_next_archived_file): Thin archives.
+ (bfd_generic_archive_p): Recognize new magic string.
+ (adjust_relative_path): New function.
+ (_bfd_construct_extended_name_table): Construct extended
+ names for thin archive members.
+ (_bfd_write_archive_contents): Emit new magic string, skip
+ copying files for thin archives.
+ * bfd-in.h (bfd_is_thin_archive): New macro.
+ * bfd.c (struct bfd): New fields for thin archives.
+ * libbfd-in.h (struct areltdata): New field for thin archives.
+ * opncls.c (bfd_close): Delete BFDs for nested archives.
+
+2008-03-25 Bernd Schmidt <bernd.schmidt@analog.com>
+
+ * elf32-bfin.c (bfin_final_link_relocate): New function, wrapper around
+ _bfd_final_link_relocate that also handles R_pcrel24 relocs.
+ (bfinfdpic_relocate_section, bfin_relocate_section): Use it.
+
+2008-03-25 Nathan Sidwell <nathan@codesourcery.com>
+
+ * elf32-arm.c (elf32_arm_final_link_relocate): Skip dynamic relocs
+ in vxworks tls_vars sections.
+ (allocate_dynrelocs, elf32_arm_size_dynamic_sections): Likewise.
+ * elf32-i386.c (allocate_dynrelocs,
+ elf_i386_size_dynamic_sections, elf_i386_relocate_section): Likewise.
+ * elf32-ppc.c (allocate_dynrelocs, ppc_elf_size_dynamic_sections,
+ ppc_elf_relocate_section): Likewise.
+ * elf32-sh.c (allocate_dynrelocs, sh_elf_size_dynamic_sections,
+ sh_elf_relocate_section): Likewise.
+ * elfxx-sparc.c (allocate_dynrelocs,
+ _bfd_sparc_elf_size_dynamic_sections,
+ _bfd_sparc_elf_relocate_section): Likewise.
+
+2008-03-21 Adam Nemet <anemet@caviumnetworks.com>
+
+ * elf.c (_bfd_elf_print_private_bfd_data): Use bfd_fprintf_vma to
+ print the values from the dynamic section.
+
+2008-03-20 Richard Sandiford <rsandifo@nildram.co.uk>
+
+ * elfxx-mips.c (MIPS_ELF_GNU_GOT1_MASK): New macro.
+ (_bfd_mips_elf_finish_dynamic_sections): Use it instead of 0x80000000.
+
+2008-03-20 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-spu.c (spu_elf_create_sections): Remove output_bfd parameter.
+ (spu_elf_find_overlays, spu_elf_size_stubs): Likewise
+ (process_stubs, discover_functions, build_call_tree): Likewise.
+ (spu_elf_stack_analysis): Likewise.
+ (spu_elf_check_vma): Likewise. Move.
+ (struct call_info): Make "is_tail" a bitfield.
+ (insert_callee): Clear fun->start and set fun->is_func if we find
+ a non-tail call.
+ * elf32-spu.h (spu_elf_create_sections): Update prototype.
+ (spu_elf_find_overlays, spu_elf_size_stubs, spu_elf_check_vma): Ditto.
+
+2008-03-17 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
+
+ * aclocal.m4: Regenerate.
+ * configure: Likewise.
+ * Makefile.in: Likewise.
+
+2008-03-16 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/5789
+ PR ld/5943
+ * elf32-i386.c (elf_i386_relocate_section): Issue an error
+ for R_386_GOTOFF relocaton against undefined hidden/internal
+ symbols when building a shared object.
+
+ * elf64-x86-64.c (elf64_x86_64_relocate_section): Issue an
+ error for R_X86_64_PC8/R_X86_64_PC16/R_X86_64_PC32
+ relocaton against undefined hidden/internal symbols when
+ building a shared object.
+ (elf64_x86_64_finish_dynamic_symbol): Return FALSE when symbol
+ is referenced locally, but isn't defined in a regular file.
+
+2008-03-15 H.J. Lu <hongjiu.lu@intel.com>
+
+ * bfd-in.h (BFD_NO_FLAGS, HAS_RELOC, EXEC_P, HAS_LINENO,
+ HAS_DEBUG, HAS_SYMS, HAS_LOCALS, DYNAMIC, WP_TEXT, D_PAGED,
+ BFD_IS_RELAXABLE, BFD_TRADITIONAL_FORMAT, BFD_IN_MEMORY,
+ HAS_LOAD_PAGE, BFD_LINKER_CREATED): Moved to ...
+ * bfd.c: Here.
+
+ * bfd.c (bfd): Change cacheable, target_defaulted, opened_once,
+ mtime_set, no_export, output_has_begun and has_armap to bit
+ field.
+
+ * bfd-in2.h: Regenerated.
+
+2008-03-14 Daniel Jacobowitz <dan@codesourcery.com>
+
+ * cache.c (close_one): Remove mtime hack.
+
+2008-03-14 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/5913
+ * elfxx-ia64.c (elfNN_ia64_tprel_base): Remove BFD_ASSERT.
+ (elfNN_ia64_dtprel_base): Likewise.
+ (elfNN_ia64_relocate_section): Go to missing_tls_sec if
+ tls_sec is NULL before calling elfNN_ia64_tprel_base or
+ elfNN_ia64_dtprel_base. Report unsupported TLS relocations.
+
+2008-03-14 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-spu.c (process_stubs, spu_elf_relocate_section): Move
+ common code to..
+ (maybe_needs_stub): ..here, a new function that also omits stubs
+ for .eh_frame, and..
+ (needs_ovl_stub): ..here. Create stubs for labels in code section
+ referenced by switch jump table.
+ (spu_elf_find_overlays): Set htab->ovly_load and htab->ovly_return.
+ (enum _insn_type): Delete.
+ (enum _stub_type): New.
+ (count_stub, build_stub): Adjust.
+ (allocate_spuear_stubs, build_spuear_stubs): Adjust.
+
+2008-03-13 Alan Modra <amodra@bigpond.net.au>
+
+ * elf.c (_bfd_elf_make_section_from_shdr): Remove unnecessary cast.
+ (_bfd_elf_assign_file_position_for_section): Simplify align.
+ (_bfd_elf_init_reloc_shdr): Ensure shift expression wide enough
+ for sh_addralign.
+ (elf_fake_sections, swap_out_syms): Likewise.
+ * elflink.c (bfd_elf_final_link): Likewise.
+
+2008-03-13 Alan Modra <amodra@bigpond.net.au>
+
+ * Makefile.am: Run "make dep-am".
+ * Makefile.in: Regenerate.
+ * po/SRC-POTFILES.in: Regenerate.
+
+2008-03-12 Bernd Schmidt <bernd.schmidt@analog.com>
+
+ From Jie Zhang <jie.zhang@analog.com>
+ * elf32-bfin.c (struct bfinfdpic_relocs_info): Make got17m4,
+ gothilo, fd, fdgot17m4, fdgothilo, fdgoff17m4, fdgoffhilo,
+ gotoff, call and sym not bitfields.
+ (bfinfdpic_gc_sweep_hook): New function; update the relocation
+ information for the relocations of the section being removed.
+ (bfinfdpic_check_relocs): Accumulate the number of relocations
+ which set got17m4, gothilo, fd, fdgot17m4, fdgothilo, fdgoff17m4,
+ fdgoffhilo, gotoff, call and sym fields.
+ (elf_backend_gc_sweep_hook): Redefine for FD-PIC.
+
+2008-03-12 Alan Modra <amodra@bigpond.net.au>
+
+ PR 5900
+ * elf-bfd.h: Include elf/internal.h after elf/external.h.
+ * elfcode.h (elf_swap_symbol_in): Map reserved shndx range.
+ (elf_swap_symbol_out): Adjust SHN_XINDEX test.
+ (elf_swap_ehdr_out): Mask SHN_LORESERVE and SHN_XINDEX to values
+ seen in external structs.
+ (valid_section_index_p): Delete.
+ (elf_object_p): Don't increment section numbers over reserved range.
+ Simplify test for valid sh_link, sh_info and e_shstrndx fields.
+ (elf_write_shdrs_and_ehdr): Mask SHN_LORESERVE and SHN_XINDEX to values
+ seen in external structs. Don't increment section numbers over
+ reserved range.
+ * elf.c (bfd_elf_sym_name): Remove redundant tests on st_shndx.
+ (bfd_section_from_shdr): Likewise.
+ (group_signature): Range check before accessing elf_elfsections.
+ (_bfd_elf_setup_sections): Likewise.
+ (bfd_section_from_shdr): Likewise.
+ (bfd_section_from_shdr): Don't increment section number over
+ reserved sections.
+ (assign_file_positions_for_non_load_sections): Likewise.
+ (assign_file_positions_except_relocs): Likewise.
+ (_bfd_elf_write_object_contents): Likewise.
+ (assign_section_numbers): Likewise. Adjust for changed SHN_*.
+ (prep_headers): Delete unused variable.
+ * elflink.c (bfd_elf_link_record_local_dynamic_symbol): Adjust
+ for changed SHN_* values.
+ (check_dynsym, elf_link_input_bfd): Likewise.
+ (bfd_elf_final_link): Likewise. Don't skip over reserved section
+ range.
+ (elf_fixup_link_order): Check that sh_link field is valid.
+ * elf-hppa.h (elf_hppa_add_symbol_hook): Make "index" unsigned.
+ * elf32-arm.c (elf32_arm_gc_mark_extra_sections): Range check before
+ accesssing elf_elfsections.
+ * elf32-avr.c (elf32_avr_size_stubs): Likewise.
+ * elf32-hppa.c (elf32_hppa_size_stubs): Likewise.
+ * elf32-m68hc1x.c (elf32_m68hc11_size_stubs): Likewise.
+ * elf64-hppa.c (elf64_hppa_check_relocs): Adjust for changed
+ SHN_* defines. Test for SHN_BAD return from
+ _bfd_elf_section_from_bfd_section
+
+2008-03-12 Alan Modra <amodra@bigpond.net.au>
+
+ * elf-bfd.h (_bfd_elf_section_from_bfd_section): Update prototype.
+ * elf.c (_bfd_elf_section_from_bfd_section): Return unsigned int,
+ SHN_BAD on error.
+ (_bfd_elf_print_private_bfd_data): Test for SHN_BAD result from
+ _bfd_elf_section_from_bfd_section, not -1.
+ (swap_out_syms): Likewise.
+ * elflink.c (elf_link_add_object_symbols): Likewise.
+ (bfd_elf_get_bfd_needed_list): Likewise.
+ (bfd_elf_match_symbols_in_sections): Likewise.
+ (elf_link_add_object_symbols): Don't bother testing for symbols
+ using normal sections before calling bfd_section_from_elf_index.
+ (elf_link_input_bfd, bfd_elf_final_link): Likewise.
+ (bfd_elf_reloc_symbol_deleted_p): Likewise.
+ * elfcode.h (elf_slurp_symbol_table): Likewise.
+ * elf32-spu.c (get_sym_h): Likewise.
+ * elf32-xtensa.c (get_elf_r_symndx_section): Likewise.
+ * elf64-ppc.c (opd_entry_value, get_sym_h, ppc64_elf_edit_toc): Ditto.
+ * elf64-sh64.c (sh_elf64_get_relocated_section_contents): Likewise.
+
+2008-03-11 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-spu.c (spu_elf_relocate_section): Test identical conditions
+ to those in process_stubs for overlay symbols.
+
+2008-03-09 Paul Brook <paul@codesourcery.com>
+
+ * elf32-arm.c (elf32_arm_merge_eabi_attributes): Handle new
+ Tag_VFP_arch values.
+
+2008-03-08 Paul Brook <paul@codesourcery.com>
+
+ * elf32-arm.c (insert_thumb_branch): Rewrite.
+ (elf32_thumb_to_arm_stub): Use new insert_thumb_branch.
+
+2008-03-07 Paul Brook <paul@codesourcery.com>
+
+ * elf32-arm.c (elf32_arm_howto_table_1): Fix bitmasks for MOVW and
+ MOVT relocations.
+ (elf32_arm_final_link_relocate): Fix off by one MOVW/MOVT sign
+ extension.
+ (elf32_arm_relocate_section): Handle MOVW and MOVT
+ relocations. Improve safety check for other weird relocations.
+ (elf32_arm_check_relocs): Only set h->needs_plt for branch/call
+ relocations.
+
+2008-03-03 Bob Wilson <bob.wilson@acm.org>
+
+ * xtensa-isa.c (xtensa_isa_num_pipe_stages): Make max_stage static and
+ only compute its value once.
+
+2008-03-03 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-spu.c (struct got_entry): Add "addend" field.
+ (count_stub, build_stub): Use a new stub if relocation addend
+ differs from existing stubs for this symbol.
+ (process_stubs): Deal with addends.
+ (spu_elf_relocate_section, spu_elf_output_symbol_hook): Likewise.
+
+2008-03-02 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/5789
+ * elflink.c (_bfd_elf_symbol_refs_local_p): Always return true
+ for hidden and local symbols.
+
+2008-03-03 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-ppc.c (allocate_dynrelocs): Discard relocs on
+ undefined symbols with internal or hidden visibility.
+ (ppc_elf_relocate_section): Likewise. Use SYMBOL_CALLS_LOCAL
+ rather than SYMBOL_REFERENCES_LOCAL on branches. Don't
+ return immediately on dynamic reloc error.
+
+2008-03-01 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (build_plt_stub): Add relocs on plt call stubs
+ if emitrelocations.
+ (get_relocs): New function, split out from..
+ (ppc_build_one_stub): ..here. Add relocs on plt_branch stubs if
+ emitrelocations. Remove indx temp.
+ (ppc_size_one_stub): Count new stub relocs.
+ (ppc64_elf_size_stubs): Count new glink reloc.
+ (ppc64_elf_build_stubs): Emit glink reloc if emitrelocations.
+ (ppc64_elf_finish_dynamic_sections): Output glink relocs.
+ * elf32-ppc.c (ppc_elf_finish_dynamic_sections): Describe non-pic
+ glink code.
+
+2008-02-28 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-spu.c (mark_functions_via_relocs): Don't assume that
+ the "->start" pointer reaches to function origin, so that we
+ can handle functions split over more than two sections.
+ (build_call_tree): Likewise.
+ (pasted_function): Don't attempt to set fun->start back to the
+ function origin, just go back one section.
+
+2008-02-27 Catherine Moore <clm@codesourcery.com>
+
+ * elf.c ( _bfd_elf_print_private_bfd_data): Call
+ elf_backend_get_target_dtag if defined.
+ * elf32-mips.c (elf_backend_get_target_dtag): Define.
+ * elf64-mips.c: Likewise.
+ * elfn32-mips.c: Likewise.
+ * elfxx-mips.c (_bfd_mips_elf_get_target_dtag): New.
+ * elfxx-mips.h (_bfd_mips_elf_get_target_dtag): Declare.
+ * elf-bfd.h (elf_backend_get_target_dtag): Add prototype.
+ * elfxx-target.h (elf_backend_get_target_dtag): Add default.
+ (elf_backend_data): Add elf_backend_get_target_dtag.
+
+2008-02-26 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-ppc.c (ppc_elf_check_relocs): Set pointer_equality_needed
+ for R_PPC_REL32 syms. Don't set non_got_ref on branch reloc syms,
+ and assume branch relocs are not dynamic when non-shared.
+ (readonly_dynrelocs): New function, split out from..
+ (maybe_set_textrel): ..here, renamed from old readonly_dynrelocs.
+ (ppc_elf_adjust_dynamic_symbol): For symbols generating plt entries,
+ clear non_got_ref..
+ (allocate_dynrelocs): ..and don't set u.def for undefined weak.
+ Do allow dynamic relocs on undefined symbols.
+ (ppc_elf_adjust_dynamic_symbol): Use readonly_dynrelocs.
+ (ppc_elf_relocate_section): Mirror dynamic reloc changes in
+ check_relocs.
+ (ppc_elf_finish_dynamic_symbol): Don't give a warning on weak
+ plt symbols needing pointer_equality_needed.
+
+2008-02-23 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-ppc.c (ppc_elf_check_relocs): Revert non_got_ref change.
+
+2008-02-23 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-ppc.c (ppc_elf_copy_indirect_symbol): Copy
+ pointer_equality_needed.
+ (ppc_elf_check_relocs): Split out non-branch relocs from others
+ that might emit dynamic relocs. Set pointer_equality_needed
+ for their symbols. Don't set non_got_ref on branch reloc symbols.
+ (ppc_elf_hash_symbol): New function.
+ (elf_backend_hash_symbol): Define.
+ (ppc_elf_finish_dynamic_symbol): Handle pointer_equality_needed.
+ Error if pointer_equality_needed on weak plt symbol.
+
+2008-02-22 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/5788
+ * elflink.c (elf_create_symbuf): Correct buffer size and
+ position.
+
+2008-02-22 Nick Clifton <nickc@redhat.com>
+
+ PR 868
+ * dwarf2.c: Revert previous patch. All of the allocate memory is
+ on an obstack which will be freed at some other time.
+
+2008-02-20 Nick Clifton <nickc@redhat.com>
+
+ PR 868
+ * libbfd.c (bfd_realloc_or_free): New function. Performs like
+ bfd_realloc, but if the (re)allocation fails, the pointer is
+ freed.
+ * libbfd-in.h: Prototype.
+ * libbfd.h: Regenerate.
+ * bfdio.c (bfd_bwrite): Use the new function.
+ (bfd_seek): Likewise.
+ * bfdwin.c:(bfd_get_file_window): Likewise.
+ * elf-strtab.c (_bfd_elf_strtab_add): Likewise.
+ * elf32-ppc.c (ppc_elf_relax_section): Likewise.
+ * elf32-xtensa.c (vsprintf_msg): Likewise.
+ * mach-o.c (bfd_mach_o_core_fetch_environment): Likewise.
+ * stabs.c (_bfd_link_seciton_stabs): Likewise.
+ * vms-misc.c (_bfd_vms_get_record): Likewise.
+ * vms-tir.c (check_section): Likewise.
+ * vms.c (vms_new_section_hook): Likewise.
+ * elf32-arm.c (elf32_arm_section_map_add): Check that the
+ allocation of sec_data->map succeeded before using it.
+ * elflink.c (elf_link_output_sym): Do not overwrite finfo->
+ symshndxbuf until it is known that the reallocation succeeded.
+
+2008-02-20 Diogo de Carvalho Kraemer <diogo@kraemer.eng.br>
+ Nick Clifton <nickc@redhat.com>
+
+ PR 868
+ * dwarf2.c (read_abbrevs): Free the abbreviation table if we run
+ out of memory.
+ (decode_line_info): Free the line_info_table before returning a
+ failure result.
+ (_bfd_dwarf2_cleanup_debug_info): Free the abbreviation table.
+ Free the line table. Free the function table. Free the variable
+ table.
+
+2008-02-17 Mark Kettenis <kettenis@gnu.org>
+
+ * elf.c (swap_out_syms): Avoid preprocessing directive within
+ macro arg.
+
+2008-02-17 Jan Kratochvil <jan.kratochvil@redhat.com>
+
+ * elf.c (assign_file_positions_for_load_sections): Set the type of
+ PT_NOTE sections to SHT_NOTE.
+
+2008-02-17 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * simple.c (bfd_simple_get_relocated_section_contents): Set
+ link_info.output_bfd.
+
+2008-02-16 Nathan Sidwell <nathan@codesourcery.com>
+
+ * dwarf2.c (find_line): Don't trust debug information after an
+ unparseable compilation unit.
+
+2008-02-15 Alan Modra <amodra@bigpond.net.au>
+
+ PR 5765
+ * section.c (SEC_LINK_DUPLICATES): Correct. Renumber following flags.
+ * bfd-in2.h: Regenerate.
+
+2008-02-15 Alan Modra <amodra@bigpond.net.au>
+
+ * elf-bfd.h (enum elf_object_id): Add HPPA_ELF_TDATA.
+ * elf.c (bfd_elf_allocate_object): Don't check for already allocated
+ tdata.
+ * elf32-hppa.c (elf32_hppa_mkobject): New function.
+ (bfd_elf32_mkobject): Define.
+ * elf32-ppc.c (is_ppc_elf_target): Delete. Replace all uses with..
+ (is_ppc_elf): ..this new macro.
+ * elf64-ppc.c (is_ppc64_elf_target): Delete. Replace all uses with..
+ (is_ppc64_elf): ..this new macro.
+
+2008-02-15 Alan Modra <amodra@bigpond.net.au>
+
+ * elflink.c: Replace all accesses to hash->creator field with
+ output_bfd->xvec.
+ * cofflink.c: Likewise.
+ * coff-h8300.c: Likewise.
+ * ecoff.c: Likewise.
+ * elf32-m68hc1x.c: Likewise.
+ * elf32-ppc.c: Likewise.
+ * elf64-alpha.c: Likewise.
+ * elf64-ppc.c: Likewise.
+ * elf64-sparc.c: Likewise.
+ * elfxx-mips.c: Likewise.
+ * i386linux.c: Likewise.
+ * m68klinux.c: Likewise.
+ * sparclinux.c: Likewise.
+ * sunos.c: Likewise.
+ * xcofflink.c: Likewise.
+ * linker.c: Likewise.
+ (_bfd_link_hash_table_init): Don't store creator.
+
+2008-02-14 Peter Jones <pjones@redhat.com>
+
+ * efi-rtdrv-ia32.c: New file.
+ * efi-bsdrv-ia32.c: New file.
+ * efi-rtdrv-ia64.c: New file.
+ * efi-bsdrv-ia64.c: New file.
+ * efi-rtdrv-x86_64.c: New file.
+ * efi-bsdrv-x86_64.c: New file.
+ * peicode.h (pe_bfd_object_p): Add support for boot service and
+ runtime service drivers.
+ * libpei.h: Add macros for EFI formats, and rename the efi application
+ format macros to disambiguate.
+ * targets.c: Add bfd_target _vec externs.
+ (_bfd_tar): Add EFI _vec entries.
+ * config.bfd: Add EFI vectors into the selection routines.
+ * configure.in: add EFI _vec entries.
+ * configure: Regenerate.
+ * Makefile.am: Add EFI files.
+ * Makefile.in: Regenerate.
+
+2008-02-14 Nathan Sidwell <nathan@codesourcery.com>
+
+ * dwarf1.c (struct dwarf1_debug): Add syms member.
+ (alloc_dwarf1_unit, alloc_dwarf1_func): Check for out of memory.
+ (parse_line_table, _bfd_dwarf1_find_nearest_line): Relocate
+ section contents, check for out of memory.
+
+ * dwarf1.c (struct dwarf1_debug): Change data pointers to bfd_byte.
+ (parse_die): Change data pointers to bfd_byte.
+ (parse_line_table, parse_functions_in_unit): Likewise.
+
+2008-02-14 Alan Modra <amodra@bigpond.net.au>
+
+ * elflink.c (compute_bucket_count): Warning fixes.
+
+2008-02-12 DJ Delorie <dj@redhat.com>
+
+ * elf32-iq2000.c (iq2000_elf_relocate_section): Adjust addend of
+ relocation pointing to local symbol in merged section.
+
+ * elf32-iq2000.c (iq2000_elf_relocate_offset16): New.
+ (iq2000_elf_relocate_section): Call it.
+
+2008-02-12 Nick Clifton <nickc@redhat.com>
+
+ PR ld/5692
+ * elf-bfd.h (enum elf_object_id): New enum, used to identify
+ target specific extensions to the elf_obj_tdata structure.
+ (struct elf_obj_tdata): New field 'object_id'.
+ (elf_object_id, elf_program_header_size, elf_symtab_hdr): New
+ macros for accessing fields in the elf_obj_tdata structure.
+ (bfd_elf_mkobject): Rename to bfd_elf_make_generic_object.
+ (bfd_elf_allocate_object): New function.
+ * elf.c (bfd_elf_mkobject): Rename to bfd_elf_make_generic_object
+ and implement by calling bfd_elf_allocate_object.
+ (bfd_elf_allocate_object): New function: Allocates an
+ elf_obj_tdata structure, possibly with a target specific
+ extension.
+ * elfxx-target.h (bfd_elfNN_mkobject): Use
+ bfd_elf_make_generic_object as the default value.
+ * elf32-arm.c (elf32_arm_obj_tdata): Rename to elf_arm_obj_tdata
+ for consistency with other, similar structures.
+ (is_arm_elf): New macro. Checks a BFD to make sure that is an ARM
+ ELF bfd.
+ (elf32_arm_mkobject): Call bfd_elf_allocate_object.
+ (bfd_elf32_arm_vfp11_erratum_scan): Use is_arm_elf macro to check
+ the bfd being processed.
+ (bfd_elf32_arm_vfp11_fix_veneer_locations): Likewise.
+ (bfd_elf32_arm_set_target_relocs): Likewise.
+ (bfd_elf32_arm_final_link_relocate): Likewise.
+ (bfd_elf32_arm_copy_private_bfd_data): Likewise.
+ (bfd_elf32_arm_merge_eabi_attributes): Likewise.
+ (bfd_elf32_arm_merge_private_bfd_data): Likewise.
+ (bfd_elf32_arm_check_relocs): Likewise.
+ (bfd_elf32_arm_gc_mark_extra_sections): Likewise.
+ (bfd_elf32_arm_size_dynamic_sections): Likewise.
+ (bfd_elf32_arm_process_before_allocation): Use elf_symtab_hdr.
+ (bfd_elf32_arm_init_maps): Likewise.
+ (bfd_elf32_arm_final_link_relocate): Likewise.
+ (bfd_elf32_arm_relocate_section): Likewise.
+ (bfd_elf32_arm_gc_sweep_hook): Likewise.
+ (bfd_elf32_arm_check_relocs): Likewise.
+ (bfd_elf32_arm_size_dynamic_sections): Likewise.
+ * elf32-i386.c (elf_i386_mkobject): Call bfd_elf_allocate_object.
+ (is_i386_elf): New macro. Checks a BFD to make sure that is an x86
+ ELF bfd.
+ (elf_i386_check_relocs): Use is_i386_elf macro to check the bfd
+ being processed.
+ (elf_i386_size_dynamic_sections): Likewise.
+ (elf_i386_relocate_section): Likewise.
+ (elf_i386_check_relocs): Use elf_symtab_hdr.
+ (elf_i386_gc_sweep_hook): Likewise.
+ (elf_i386_size_dynamic_sections): Likewise.
+ (elf_i386_relocate_section): Likewise.
+ * elf32-ppc.c (ppc_elf_mkobject): Call bfd_elf_allocate_object.
+ (elf_create_pointer_linker_section): Use is_ppc_elf_target to
+ verify that the bfd before accessing target specific fields.
+ (ppc_elf_check_relocs): Likewise.
+ (elf_finish_pointer_linker_section): Likewise.
+ (elf_create_pointer_linker_section): Use elf_symtab_hdr.
+ (ppc_elf_check_relocs): Likewise.
+ (ppc_elf_gc_sweep_hook): Likewise.
+ (ppc_elf_tls_optimize): Likewise.
+ (ppc_elf_size_dynamic_sections): Likewise.
+ (ppc_elf_relax_section): Likewise.
+ (ppc_elf_relocate_section): Likewise.
+ * elf32-s390.c (struct elf_s390_obj_tdata): Add a comment
+ reminding programmers to keep this structure in sync with the one
+ defined in elf64-s390.c.
+ (elf_s390_mkobject): Call bfd_elf_allocate_object.
+ (is_s390_elf): New macro. Checks a BFD to make sure that is an s390
+ ELF bfd.
+ (elf_s390_check_relocs): Use is_s390_elf macro to check the bfd
+ being processed.
+ (elf_s390_size_dynamic_sections): Likewise.
+ (elf_s390_relocate_section): Likewise.
+ (elf_s390_check_relocs): Use elf_symtab_hdr.
+ (elf_s390_gc_sweep_hook): Likewise.
+ (elf_s390_size_dynamic_sections): Likewise.
+ (elf_s390_relocate_section): Likewise.
+ * elf32-sh.c (sh_elf_mkobject): Call bfd_elf_allocate_object.
+ (is_sh_elf): New macro. Checks a BFD to make sure that is an SH
+ ELF bfd.
+ (sh_elf_size_dynamic_sections): Use is_sh_elf macro to check the
+ bfd being processed.
+ (sh_elf_relocate_section): Likewise.
+ (sh_elf_check_relocs): Likewise.
+ (sh_elf_copy_private_data): Likewise.
+ (sh_elf_relax_section): Use elf_symtab_hdr.
+ (sh_elf_size_dynamic_sections): Likewise.
+ (sh_elf_relocate_section): Likewise.
+ (sh_elf_get_relocated_section_contents): Likewise.
+ (sh_elf_gc_sweep_hook): Likewise.
+ (sh_elf_check_relocs): Likewise.
+ * elf64-alpha.c (elf64_alpha_mkobject): Call bfd_elf_allocate_object.
+ (is_alpha_elf): New macro. Checks a BFD to make sure that is an
+ Alpha ELF bfd.
+ (elf64_alpha_create_got_section): Use is_alpha_elf macro to check
+ the bfd being processed.
+ (elf64_alpha_create_dynamic_section): Likewise.
+ (elf64_alpha_check_relocs): Likewise.
+ (elf64_alpha_size_got_sections): Likewise.
+ (elf64_alpha_relax_section): Likewise.
+ (elf64_alpha_relocate_section): Likewise.
+ (elf64_alpha_final_link): Likewise.
+ (elf64_alpha_check_relocs): Use elf_symtab_hdr.
+ (elf64_alpha_relax_section): Likewise.
+ (elf64_alpha_relocate_section_r): Likewise.
+ (elf64_alpha_relocate_section): Likewise.
+ * elf64-ppc.c (ppc64_elf_mkobject): Call bfd_elf_allocate_object.
+ (ppc64_elf_check_relocs): Use is_ppc64_elf_target to check the bfd
+ being processed.
+ (opd_entry_value): Likewise.
+ (allocate_dynrelocs): Likewise.
+ (ppc64_elf_relocate_section): Likewise.
+ (ppc64_elf_check_relocs): Use elf_symtab_hdr.
+ (opd_entry_value): Likewise.
+ (ppc64_elf_gc_sweep_hook): Likewise.
+ (get_sym_h): Likewise.
+ (ppc64_elf_edit_opd): Likewise.
+ (ppc64_elf_tls_optimize): Likewise.
+ (ppc64_elf_edit_toc): Likewise.
+ (ppc64_elf_size_dynamic_sections): Likewise.
+ (toc_adjusting_stub_needed): Likewise.
+ (ppc64_elf_size_stubs): Likewise.
+ (ppc64_elf_relocate_section): Likewise.
+ * elf64-s390.c (struct elf_s390_obj_tdata): Add a comment
+ reminding programmers to keep this structure in sync with the one
+ defined in elf32-s390.c.
+ (elf_s390_mkobject): Call bfd_elf_allocate_object.
+ (is_s390_elf): New macro. Checks a BFD to make sure that is an s390
+ ELF bfd.
+ (elf_s390_check_relocs): Use is_s390_elf macro to check the bfd
+ being processed.
+ (elf_s390_size_dynamic_sections): Likewise.
+ (elf_s390_relocate_section): Likewise.
+ (elf_s390_check_relocs): Use elf_symtab_hdr.
+ (elf_s390_gc_sweep_hook): Likewise.
+ (elf_s390_size_dynamic_sections): Likewise.
+ (elf_s390_relocate_section): Likewise.
+ * elf64-x86_64.c (elf64_x86_64_mkobject): Call bfd_elf_allocate_object.
+ (is_x86_64_elf): New macro. Checks a BFD to make sure that is an
+ x86_64 ELF bfd.
+ (elf64_x86_64_check_relocs): Use is_x86_64_elf macro to check the bfd
+ being processed.
+ (elf64_x86_64_size_dynamic_sections): Likewise.
+ (elf64_x86_64_relocate_section): Likewise.
+ (elf64_x86_64_check_relocs): Use elf_symtab_hdr.
+ (elf64_x86_64_gc_sweep_hook): Likewise.
+ (elf64_x86_64_size_dynamic_sections): Likewise.
+ (elf64_x86_64_relocate_section): Likewise.
+ * elfxx-sparc.c (_bfd_sparc_elf_mkobject): Call bfd_elf_allocate_object.
+ (is_sparc_elf): New macro. Checks a BFD to make sure that is a Sparc
+ ELF bfd.
+ (_bfd_sparc_elf_check_relocs): Use is_sparc_elf macro to check the
+ bfd being processed.
+ (_bfd_sparc_elf_gc_sweep_hook): Likewise.
+ (_bfd_sparc_elf_size_dynamic_sections): Likewise.
+ (_bfd_sparc_elf_check_relocs): Use elf_symtab_hdr.
+ (_bfd_sparc_elf_gc_sweep_hook): Likewise.
+ (_bfd_sparc_elf_size_dynamic_sections): Likewise.
+ (_bfd_sparc_elf_relocate_section): Likewise.
+
+2008-02-12 Alan Modra <amodra@bigpond.net.au>
+
+ PR 5303, 5755
+ * arange-set.c: Delete.
+ * arange-set.h: Delete.
+ * dwarf2.c: Revert 2007-09-21 changes.
+ * Makefile.am: Likewise.
+ * Makefile.in: Regenerate.
+ * po/SRC-POTFILES.in: Regenerate.
+
+2008-02-11 Bernd Schmidt <bernd.schmidt@analog.com>
+
+ * elf32-bfin.c (bfin_relocate_section): Set up dynobj before using it
+ if necessary.
+ (elf32_bfin_merge_private_bfd_data): Simplify, and ensure object type
+ mismatches are detected.
+
+ * elf32-bfin.c (bfinfdpic_relocate_section): Take more care not to
+ emit invalid relocs or rofixup entries for deleted .eh_frame entries.
+
+2008-02-11 Daniel Jacobowitz <dan@codesourcery.com>
+
+ * cache.c (cache_bread): Set bfd_error_file_truncated if EOF
+ was reached.
+ * srec.c (srec_scan): Calculate the checksum. Complain on mismatch.
+
+2008-02-07 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-spu.c (spu_elf_size_stubs): Revert 2008-01-28 doubling
+ of _ovly_buf_table size.
+ (spu_elf_build_stubs): Use low bit of .size as "present" bit.
+ Adjust initialisations relating to _ovly_buf_table.
+
+2008-02-04 Bob Wilson <bob.wilson@acm.org>
+
+ * elf32-xtensa (elf_xtensa_relocate_section): After finding an invalid
+ relocation, do not continue processing it. Ignore R_XTENSA_ASM_EXPAND
+ relocations against dynamic symbols.
+ (elf_xtensa_finish_dynamic_sections): Do not fail if there is no
+ .xt.lit section.
+
+2008-02-04 Kai Tietz <kai.tietz@onevision.com>
+ H.J. Lu <hongjiu.lu@intel.com>
+
+ PR 5715
+ * warning.m4: Enable -Wno-format by default when using gcc on
+ mingw.
+ * configure: Regenerated.
+
+2008-02-04 Adam Nemet <anemet@caviumnetworks.com>
+
+ * archures.c: Update copyright.
+ (bfd_mach_mips_octeon): New macro.
+ * bfd-in2.h: Regenerate.
+ * elfxx-mips.c (_bfd_elf_mips_mach): Handle Octeon.
+ (mips_set_isa_flags): Likewise.
+ (mips_mach_extensions): Add Octeon.
+ * cpu-mips.c: Update copyright.
+ (I_mipsocteon): New enum constant.
+ (arch_info_struct): Add Octeon.
+
+2008-02-04 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-spu.c (spu_elf_relocate_section): Correct return type.
+ Return error status on unexpected relocation errors.
+
+2008-02-04 Alan Modra <amodra@bigpond.net.au>
+
+ PR ld/5692
+ * elf.c (bfd_elf_get_elf_syms): Revert 2008-01-31. Instead abort
+ on non-ELF input.
+ * elf32-arm.c (elf32_arm_size_dynamic_sections): Skip glue
+ processing on non-ELF input.
+
+2008-01-31 Marc Gauthier <marc@tensilica.com>
+
+ * config.bfd (xtensa*-*-*): Recognize processor variants.
+
+2008-01-31 Nick Clifton <nickc@redhat.com>
+
+ PR ld/5692
+ * elf.c (bfd_elf_get_elf_syms): Check the return value of
+ get_elf_backend_data.
+
+2008-01-28 Fabian Groffen <grobian@gentoo.org>
+
+ * config.bfd (x86_64-*-solaris2): Add support for this target.
+
+2008-01-28 Alan Modra <amodra@bigpond.net.au>
+
+ Rewrite SPU overlay handling code. Put overlay calls stubs in the
+ overlays where possible. Use a faster call stub, or optionally at
+ compile time, a more compact stub. Double size of _ovly_buf_table
+ so that low bit of _ovly_table.buf can be used as a "present" bit.
+ Reserve an extra _ovly_table entry for index zero.
+ * elf32-spu.c: (struct spu_link_hash_table): Delete a number of fields,
+ add new ones.
+ (struct got_entry): New.
+ (struct spu_stub_hash_entry): Delete.
+ (stub_hash_newfunc, spu_elf_link_hash_table_free): Delete.
+ (spu_elf_link_hash_table_create): Adjust for struct changes.
+ (spu_stub_name): Delete.
+ (spu_elf_find_overlays): Don't track sections from overlay regions.
+ Instead set ovl_buf number in spu elf section data. Error if
+ overlays in one region don't start at the same address. Adjust
+ for struct _spu_elf_section_data changes.
+ (SIZEOF_STUB1, SIZEOF_STUB2, ILA_79, ILA_78): Delete.
+ (OVL_STUB_SIZE, BRSL, LNOP, ILA): Define.
+ (needs_ovl_stub): Adjust for struct _spu_elf_section_data changes.
+ (enum _insn_type): New.
+ (count_stub, build_stub): New functions.
+ (allocate_spuear_stubs): Use count_stub.
+ (build_spuear_stubs): Use build_stub.
+ (populate_stubs, sort_stubs): Delete.
+ (process_stubs): New function.
+ (write_one_stub): Delete.
+ (spu_elf_size_stubs, spu_elf_build_stubs): Rewrite.
+ (alloc_stack_info): Adjust for struct _spu_elf_section_data changes.
+ (maybe_insert_function, check_function_ranges): Likewise.
+ (find_function, pasted_function, build_call_tree): Likewise.
+ (spu_elf_stack_analysis, spu_elf_modify_segment_map): Likewise.
+ (spu_elf_modify_program_headers): Likewise.
+ (interesting_section): Detect stub sections differently. Delete
+ htab param, adjust all callers.
+ (spu_elf_relocate_section): Rewrite stub handling.
+ (spu_elf_output_symbol_hook): Likewise.
+ (bfd_elf32_bfd_link_hash_table_free): Delete.
+ * elf32-spu.h (struct _spu_elf_section_data): Move input-only and
+ output-only fields into a union. Add ovl_buf.
+ (spu_elf_size_stubs, spu_elf_build_stubs): Update prototypes.
+
+2008-01-25 DJ Delorie <dj@redhat.com>
+
+ * elf32-m32c.c (_bfd_m32c_elf_eh_frame_address_size): New.
+
+2008-01-25 Kai Tietz <kai.tietz@onevision.com>
+
+ * bfd-in.h: Add mingw I64 support.
+ * bfd-in2.h: Regenerated.
+ * bfd.c: (bfd_get_sign_extend_vma): Add pe-x86-64 and pei-x86-64.
+
+2008-01-21 Alan Modra <amodra@bigpond.net.au>
+
+ PR 4453
+ * format.c (bfd_check_format_matches): Don't accept archives as
+ fully matching unless they have a map.
+
+2008-01-21 Alan Modra <amodra@bigpond.net.au>
+
+ * elflink.c (_bfd_elf_link_output_relocs): Correct error return.
+
+2008-01-21 Alan Modra <amodra@bigpond.net.au>
+
+ * ecoff.c (_bfd_ecoff_archive_p): Delete.
+ * libecoff.h (_bfd_ecoff_archive_p): Delete.
+ * coff-alpha.c (ecoffalpha_little_vec): Use bfd_generic_archive_p.
+ * coff-mips.c (ecoff_little_vec, ecoff_big_vec): Likewise.
+ (ecoff_biglittle_vec): Likewise.
+
+2008-01-19 Alan Modra <amodra@bigpond.net.au>
+
+ PR 5646
+ * elf64-ppc.c (ppc64_elf_tls_optimize): Ensure htab->tls_get_addr
+ non-NULL before dereferencing.
+
+2008-01-15 Alan Modra <amodra@bigpond.net.au>
+
+ PR 5604
+ * elf-bfd.h (struct elf_backend_data): Add gc_keep. Remove param
+ names from others.
+ (_bfd_elf_gc_keep): Declare.
+ * elfxx-target.h (elf_backend_gc_keep): Define.
+ (elfNN_bed): Init new field.
+ * elflink.c (_bfd_elf_gc_keep): New function.
+ (bfd_elf_gc_sections): Call gc_keep.
+ * elf64-ppc.c (elf_backend_gc_keep): Define.
+ (struct _ppc64_elf_section_data): Move .opd related fields to
+ a struct so they don't occupy the same storage. Adjust accesses
+ throughout file.
+ (ppc64_elf_gc_keep): New function, split out from..
+ (ppc64_elf_gc_mark_hook): ..here. Don't call _bfd_elf_gc_mark
+ to mark .opd section, just set gc_mark.
+ (ppc64_elf_edit_opd): Remove no_opd_opt parm. Don't set opd->adjust
+ unless we are changing .opd. Test non-NULL opd->adjust at all
+ accesses throughout file.
+ * elf64-ppc.h (ppc64_elf_edit_opd): Update prototype.
+
+2008-01-15 Alan Modra <amodra@bigpond.net.au>
+
+ * bfd-in.h (BFD_HOST_LONG_LONG): Delete.
+ * bfd-in2.h: Regenerate.
+
+2008-01-11 Tristan Gingold <gingold@adacore.com>
+ Eric Botcazou <ebotcazou@adacore.com>
+
+ * elf32-ppc.c (ppc_elf_gc_sweep_hook): Exit early if generating a
+ relocatable.
+ * elf32-arm.c (elf32_arm_gc_sweep_hook): Likewise.
+ * elf32-cris.c (cris_elf_gc_sweep_hook): Likewise.
+ * elf32-hppa.c (elf32_hppa_gc_sweep_hook): Likewise.
+ * elf32-i386.c (elf_i386_gc_sweep_hook): Likewise.
+ * elf32-m32r.c (m32r_elf_gc_sweep_hook): Likewise.
+ * elf32-m68k.c (elf_m68k_gc_sweep_hook): Likewise.
+ * elf32-s390.c (elf_s390_gc_sweep_hook): Likewise.
+ * elf32-sh.c (sh_elf_gc_sweep_hook): Likewise.
+ * elf32-vax.c (elf_vax_gc_sweep_hook): Likewise.
+ * elf32-xtensa.c (elf_xtensa_gc_sweep_hook): Likewise.
+ * elf64-x86-64.c (elf64_x86_64_gc_sweep_hook): Likewise.
+ * elf64-s390.c (elf_s390_gc_sweep_hook): Likewise.
+ * elf64-ppc.c (ppc64_elf_gc_sweep_hook): Likewise.
+ * elfxx-mips.c (_bfd_mips_elf_gc_sweep_hook): Likewise.
+ * elfxx-sparc.c (_bfd_sparc_elf_gc_sweep_hook): Likewise.
+ * elflink.c (bfd_elf_gc_sections): Do not punt on relocatable output
+ or executable output with relocations.
+
+2008-01-09 Nick Clifton <nickc@redhat.com>
+
+ PR gas/5552
+ * elf32-fr30.c (fr30_elf_howto_table): Set partial_inplace field
+ to FALSE for all relocs.
+
+2008-01-09 Richard Sandiford <rsandifo@nildram.co.uk>
+
+ PR ld/5526
+ * elf-bfd.h (eh_cie_fde): Add u.cie.u.full_cie and u.cie.merged
+ fields. Rename u.cie.u.merged to u.cie.u.merged_with.
+ (eh_frame_sec_info): Add a cies field.
+ (eh_frame_hdr_info): Add a merge_cies field.
+ * elf-eh-frame.c (cie): Add a reloc_index member to the personality
+ union.
+ (_bfd_elf_begin_eh_frame_parsing): Set hdr_info->merge_cies instead
+ of hdr_info->cies.
+ (_bfd_elf_parse_eh_frame): Remove tmp_cie. Ccreate an array of
+ cie structures in all cases and use it instead of extended_cies.
+ If merging, store the cie array in sec_info->cies and point each
+ CIE's eh_fde_cie at the associated element. Do not try to
+ calculate the value of the personality routine here; record the
+ offset of the relocation instead. Do not merge CIEs here.
+ (_bfd_elf_end_eh_frame_parsing): Do not free hdr_info->cies here...
+ (_bfd_elf_discard_section_eh_frame_hdr): ...do it here instead.
+ (_bfd_elf_gc_mark_fdes): Mark the original (unmerged) CIE.
+ (find_merged_cie): New function.
+ (_bfd_elf_gc_mark_fdes): Use it. Free sec_info->cies.
+
+2008-01-07 Nick Clifton <nickc@redhat.com>
+
+ PR binutils/5535
+ * vms.c (vms_close_and_cleanup): Check for the presence of a
+ vms_private_data_struct before examining any of its fields.
+
+2008-01-07 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/5522
+ * elflink.c (elf_link_input_bfd): Don't write out a section if
+ its output section is marked with SEC_NEVER_LOAD.
+
+For older changes see ChangeLog-2007
+
+Copyright (C) 2008 Free Software Foundation, Inc.
+
+Copying and distribution of this file, with or without modification,
+are permitted in any medium without royalty provided the copyright
+notice and this notice are preserved.
+
+Local Variables:
+mode: change-log
+left-margin: 8
+fill-column: 74
+version-control: never
+End:
diff --git a/bfd/ChangeLog-2009 b/bfd/ChangeLog-2009
new file mode 100644
index 0000000..a3f7b24
--- /dev/null
+++ b/bfd/ChangeLog-2009
@@ -0,0 +1,5161 @@
+2009-12-31 Cary Coutant <ccoutant@google.com>
+
+ * dwarf2.c (struct line_sequence): New struct.
+ (struct line_info_table): Add num_sequences, remove last_line,
+ add sequences.
+ (add_line_info): Add new sequences as necessary.
+ (compare_sequences): New function.
+ (sort_line_sequences): New function.
+ (decode_line_info): Initialize new fields in line table.
+ Call sort_line_sequences.
+ (lookup_address_in_line_info_table): Binary search for proper
+ sequence.
+
+2009-12-28 Daniel Gutson <dgutson@codesourcery.com>
+
+ * elf32-arm.c (elf32_arm_final_link_relocate): limits
+ fixed.
+
+2009-12-28 Daniel Gutson <dgutson@codesourcery.com>
+
+ * elf-attrs.c (_bfd_elf_merge_object_attributes): Error
+ message rephrased.
+
+2009-12-21 Alan Modra <amodra@gmail.com>
+
+ * elf64-ppc.c: Delete my email address.
+
+2009-12-18 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * elf.c (elfcore_grok_s390_high_gprs): New function.
+ (elfcore_grok_note): Handle NT_S390_HIGH_GPRS notes.
+ (elfcore_write_s390_high_gprs): New function.
+ (elfcore_write_register_note): Call it.
+
+2009-12-17 Alan Modra <amodra@bigpond.net.au>
+
+ PR ld/11088
+ * elf32-ppc.c (update_plt_info): Clear sec here when addend is
+ less than 32768..
+ (ppc_elf_check_relocs): ..rather than doing so here. Ignore new
+ relax relocs.
+ (ppc_elf_gc_sweep_hook): Don't segfault when symbol hiding has
+ removed plt_entry records.
+ (ppc_elf_tls_setup): Handle PIE calls to __tls_get_addr correctly.
+ (ppc_elf_tls_optimize): Likewise. Also dec __tls_get_addr refcount
+ when optimizing code using new tlsgd and tlsld marker relocs.
+ (ppc_elf_relax_section): Differentiate relaxed PLTREL24 relocs
+ from ADDR24 relocs using plt or glink. Don't clear the addend
+ for R_PPC_RELAX_PLTREL24.
+ (ppc_elf_relocate_section): Correctly handle addends on relaxed
+ PLTREL24 relocs.
+
+2009-12-17 Alan Modra <amodra@bigpond.net.au>
+
+ PR ld/11088
+ * elf64-ppc.c (ppc64_elf_gc_sweep_hook): Don't abort if symbol
+ hiding has nulled out plt.plist.
+
+2009-12-15 H.J. Lu <hongjiu.lu@intel.com>
+
+ * opncls.c (bfd_opnr_iovec): Replace _XXX with XXX_P in
+ parameters.
+
+ * tekhex.c (pass_over): Replace eof with is_eof.
+
+2009-12-15 Tristan Gingold <gingold@adacore.com>
+
+ * mach-o.h (bfd_mach_o_uuid_command): Remove section field.
+ * mach-o.c (bfd_mach_o_scan_read_uuid): Do not create a section
+ from this command.
+
+2009-12-15 Tristan Gingold <gingold@adacore.com>
+
+ * mach-o.c (struct mach_o_section_name_xlat): Add flags field.
+ (dwarf_section_names_xlat): Add section flags.
+ (text_section_names_xlat): Ditto.
+ (data_section_names_xlat): Ditto.
+ (bfd_mach_o_convert_section_name_to_bfd): Now return name and section
+ flags by reference.
+ (bfd_mach_o_make_bfd_section): Use section flags when know, otherwise
+ try to guess.
+
+2009-12-14 Doug Kwan <dougkwan@google.com>
+
+ * opncls.c (bfd_opnr_iovec): Rename parameters to avoid shawdowed
+ variable warnings.
+ * bfd-in2.h: Regnenerate.
+
+2009-12-12 Nick Clifton <nickc@redhat.com>
+
+ * coff-arm.c (coff_arm_rtype_to_howto): Fix shadowed variable
+ warning.
+
+2009-12-11 Tristan Gingold <gingold@adacore.com>
+
+ * som.c (bfd_som_set_subsection_attributes)
+ (bfd_section_from_som_symbol, som_reloc_queue_fix): Fix shadowed
+ variable warnings.
+ * cache.c (close_one): Likewise.
+
+2009-12-11 Nick Clifton <nickc@redhat.com>
+
+ * warning.m4 (GCC_WARN_CFLAGS): Add -Wshadow.
+ * configure: Regenerate.
+ * Makefile.in: Regenerate.
+ * doc/Makefile.in: Regenerate.
+ * aout-arm.c: Fix shadowed variable warnings.
+ * aout-tic30.c: Likewise.
+ * aoutx.h: Likewise.
+ * archive.c: Likewise.
+ * coff-alpha.c: Likewise.
+ * coff-i386.c: Likewise.
+ * coff-x86_64.c: Likewise.
+ * coffgen.c: Likewise.
+ * dwarf2.c: Likewise.
+ * ecoff.c: Likewise.
+ * elf-eh-frame.c: Likewise.
+ * elf-m10300.c: Likewise.
+ * elf.c: Likewise.
+ * elf32-arm.c: Likewise.
+ * elf32-avr.c: Likewise.
+ * elf32-bfin.c: Likewise.
+ * elf32-cr16.c: Likewise.
+ * elf32-i386.c: Likewise.
+ * elf32-ip2k.c: Likewise.
+ * elf32-lm32.c: Likewise.
+ * elf32-m68hc1x.c: Likewise.
+ * elf32-microblaze.c: Likewise.
+ * elf32-ppc.c: Likewise.
+ * elf32-rx.c: Likewise.
+ * elf32-score.c: Likewise.
+ * elf32-score7.c: Likewise.
+ * elf32-sh.c: Likewise.
+ * elf32-spu.c: Likewise.
+ * elf32-v850.c: Likewise.
+ * elf32-xtensa.c: Likewise.
+ * elf64-hppa.c: Likewise.
+ * elf64-ppc.c: Likewise.
+ * elf64-x86-64.c: Likewise.
+ * elflink.c: Likewise.
+ * elfxx-ia64.c: Likewise.
+ * elfxx-mips.c: Likewise.
+ * elfxx-sparc.c: Likewise.
+ * hash.c: Likewise.
+ * ieee.c: Likewise.
+ * libbfd.c: Likewise.
+ * mach-o.c: Likewise.
+ * merge.c: Likewise.
+ * nlm32-sparc.c: Likewise.
+ * oasys.c: Likewise.
+ * opncls.c: Likewise.
+ * pdp11.c: Likewise.
+ * peXXigen.c: Likewise.
+ * pef.c: Likewise.
+ * versados.c: Likewise.
+ * vms-gsd.c: Likewise.
+ * vms-hdr.c: Likewise.
+ * vms-tir.c: Likewise.
+ * vms.c: Likewise.
+ * xcofflink.c: Likewise.
+ * xsym.c: Likewise.
+ * xtensa-isa.c: Likewise.
+
+2009-12-10 Maciej W. Rozycki <macro@codesourcery.com>
+
+ * elfxx-mips.c (mips_elf_calculate_relocation): Correct handling
+ of undefined symbols.
+
+2009-12-09 Daniel Jacobowitz <dan@codesourcery.com>
+
+ * elf32-arm.c (elf32_arm_next_input_section): Skip sections without
+ SEC_CODE.
+
+2009-12-08 Alan Modra <amodra@bigpond.net.au>
+
+ * elf.c (write_zeros): New function.
+ (assign_file_positions_for_load_sections): Allocate file space for
+ NOBITS sections that are followed by PROGBITS sections in a segment.
+
+2009-12-03 Tristan Gingold <gingold@adacore.com>
+
+ * mach-o.c (bfd_mach_o_make_bfd_section): Force debug flags for
+ all sections of the __DWARF segment.
+
+2009-12-03 Alan Modra <amodra@bigpond.net.au>
+
+ PR ld/11047
+ * elf32-ppc.c (ppc_elf_relocate_section): Delete __tls_get_addr
+ symbol reference from relocs belonging to calls that are
+ optimized away.
+ * elf64-ppc.c (ppc64_elf_relocate_section): Likewise.
+
+2009-12-02 Jerker Bäck <jerker.back@gmail.com>
+
+ PR binutils/11017
+ * coff-i386.h (COFF_PAGE_SIZE): Definition moved to coff/i386.h
+
+2009-11-30 Joseph Myers <joseph@codesourcery.com>
+
+ * configure: Regenerate.
+
+2009-11-26 Per Øyvind Karlsen <peroyvind@mandriva.org>
+
+ * plugin.c (bfd_plugin_bfd_copy_link_hash_symbol_type): Define.
+
+2009-11-24 Joel Brobecker <brobecker@adacore.com>
+
+ * acinclude.m4: Add include of ../config/zlib.m4.
+ * configure.in: AM_ZLIB to check for zlib support.
+ * configure: Regenerate.
+
+2009-11-23 Paul Brook <paul@codesourcery.com>
+
+ * libbfd-in.h (_bfd_generic_copy_link_hash_symbol_type): Add
+ prototype.
+ * elf-bfd.h (_bfd_elf_copy_link_hash_symbol_type): Add prototype.
+ * linker.c (_bfd_generic_copy_link_hash_symbol_type): New function.
+ * elflink.c (_bfd_elf_copy_link_hash_symbol_type): New function.
+ * targets.c (BFD_JUMP_TABLE_LINK, struct bfd_target): Add
+ _copy_link_hash_symbol_type.
+ * coff64-rs6000.c (rs6000coff64_vec, aix5coff64_vec): Add
+ _bfd_generic_copy_link_hash_symbol_type.
+ * coff-rs6000.c (rs6000coff_vec, pmac_xcoff_vec): Add
+ _bfd_generic_copy_link_hash_symbol_type.
+ * aout-adobe.c (aout_32_bfd_copy_link_hash_symbol_type): Define.
+ * aout-target.h (MY_bfd_copy_link_hash_symbol_type): Define.
+ * aout-tic30.c (MY_bfd_copy_link_hash_symbol_type): Define.
+ * binary.c (binary_bfd_copy_link_hash_symbol_type): Define.
+ * bout.c (b_out_bfd_copy_link_hash_symbol_type): Define.
+ * coffcode.h (coff_bfd_copy_link_hash_symbol_type): Define.
+ * elfxx-target.h (bfd_elfNN_bfd_copy_link_hash_symbol_type): Define.
+ * i386msdos.c (msdos_bfd_copy_link_hash_symbol_type): Define.
+ * i386os9k.c (os9k_bfd_copy_link_hash_symbol_type): Define.
+ * ieee.c (ieee_bfd_copy_link_hash_symbol_type): Define.
+ * ihex.c (ihex_bfd_copy_link_hash_symbol_type): Define.
+ * libecoff.h (_bfd_ecoff_bfd_copy_link_hash_symbol_type): Define.
+ * mach-o.c (bfd_mach_o_bfd_copy_link_hash_symbol_type): Define.
+ * mmo.c (mmo_bfd_copy_link_hash_symbol_type): Define.
+ * nlm-target.h (nlm_bfd_copy_link_hash_symbol_type): Define.
+ * oasys.c (oasys_bfd_copy_link_hash_symbol_type): Define.
+ * pef.c (bfd_pef_bfd_copy_link_hash_symbol_type): Define.
+ * ppcboot.c (ppcboot_bfd_copy_link_hash_symbol_type): Define.
+ * som.c (som_bfd_copy_link_hash_symbol_type): Define.
+ * srec.c (srec_bfd_copy_link_hash_symbol_type): Define.
+ * tekhex.c (tekhex_bfd_copy_link_hash_symbol_type): Define.
+ * versados.c (versados_bfd_copy_link_hash_symbol_type): Define.
+ * vms.c (vms_bfd_copy_link_hash_symbol_type): Define.
+ * xsym.c (bfd_sym_bfd_copy_link_hash_symbol_type): Define.
+ * bfd-in2.h: Regenerate.
+ * libbfd.h: Regenerate.
+
+2009-11-19 Tristan Gingold <gingold@adacore.com>
+
+ * coff-rs6000.c (rs6000coff_vec): Use generic routines instead of
+ hard-coded casts.
+ (pmac_xcoff_vec): Ditto.
+ * coff64-rs6000.c (rs6000coff64_vec): Ditto.
+ (aix5coff64_vec): Ditto.
+
+2009-11-18 Alan Modra <amodra@bigpond.net.au>
+
+ * bfd-in.h (_bfd_elf_ppc_at_tls_transform): Declare.
+ * bfd-in2.h: Regenerate.
+ * elf64-ppc.c (ppc64_elf_relocate_section): Move code for R_PPC64_TLS
+ insn optimisation to..
+ * elf32-ppc.c (_bfd_elf_ppc_at_tls_transform): ..here. New function.
+ (ppc_elf_relocate_section): Use it.
+
+2009-11-18 Alan Modra <amodra@bigpond.net.au>
+
+ * targets.c: Don't include alloca-conf.h.
+ (bfd_get_target_info): Don't use alloca.
+
+2009-11-17 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/10955
+ * elfxx-ia64.c (elfNN_ia64_update_short_info): Also skip ABS
+ sections.
+
+2009-11-17 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/10955
+ * elfxx-ia64.c (elfNN_ia64_link_hash_table): Update comments.
+ (elfNN_ia64_update_short_info): Remove "->output_section" from
+ ia64_info->max_short_sec and ia64_info->min_short_sec.
+ (elfNN_ia64_choose_gp): Likewise.
+ (elfNN_ia64_relax_section): Pass tsec->output_section to
+ elfNN_ia64_update_short_info.
+
+2009-11-17 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/10955
+ * elfxx-ia64.c (elfNN_ia64_link_hash_table): Add max_short_sec,
+ max_short_offset, min_short_sec and min_short_offset.
+ (elfNN_ia64_update_short_info): New.
+ (elfNN_ia64_relax_section): Update max_short_sec,
+ max_short_offset, min_short_sec and min_short_offset.
+ (elfNN_ia64_choose_gp): Use min_short_sec/max_short_sec if
+ they are set.
+
+2009-11-17 Paul Brook <paul@codesourcery.com>
+ Daniel Jacobowitz <dan@codesourcery.com>
+
+ * elf32-arm.c (using_thumb_only, arch_has_arm_nop,
+ arch_has_thumb2_nop): Handle TAG_CPU_ARCH_V7E_M.
+ (tag_cpu_arch_combine): Ditto. Correct MAX_TAG_CPU_ARCH test.
+
+2009-11-17 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * elf32-spu.c (struct spu_link_hash_table): Remove overlay_fixed,
+ reserved, and extra_stack_space members.
+ (spu_elf_auto_overlay): Use auto_overlay_fixed, auto_overlay_reserved,
+ and extra_stack_space members of htab->params instead.
+
+2009-11-17 Tristan Gingold <gingold@adacore.com>
+
+ * targets.c: Include alloca-conf.h
+
+2009-11-16 Kai Tietz <kai.tietz@onevision.com>
+
+ * targets.c (bfd_get_target_info): New function.
+ (_bfd_find_arch_match): New function.
+ * bfd-in2.h: Regenerated.
+
+2009-11-12 Nick Clifton <nickc@redhat.com>
+
+ * po/ru.po: Updates Russian translation.
+
+2009-11-11 Nick Clifton <nickc@redhat.com>
+
+ * po/id.po: Updated Indonesian translation.
+
+2009-11-11 Jan Kratochvil <jan.kratochvil@redhat.com>
+
+ * configure.in: Call ACX_LARGEFILE. Stop calling AC_PLUGINS,
+ AC_SYS_LARGEFILE and checking the Solaris largefile exception.
+ * aclocal.m4: Regenerate.
+ * configure: Regenerate.
+
+2009-11-09 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/10911
+ * elflink.c (elf_link_output_extsym): Don't return on
+ STT_GNU_IFUNC symbol when stripping.
+
+2009-11-08 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ * elf32-hppa.c (elf32_hppa_final_link): Don't sort unwind information
+ in a relocatable link.
+ * elf64-hppa.c (elf_hppa_final_link): Likewise.
+
+2009-11-05 Nick Clifton <nickc@redhat.com>
+
+ * elflink.c (elf_link_add_object_symbols): Improve error
+ message generated when a symbol is left unresolved because a
+ --no-add-needed command line option has prevented the
+ inclusion of the DSO defining it.
+
+2009-11-03 Alan Modra <amodra@bigpond.net.au>
+ Ulrich Weigand <uweigand@de.ibm.com>
+
+ * elf32-spu.c (mark_functions_via_relocs): Handle non-branch relocs
+ (jump tables or other references to code labels) as well.
+
+2009-11-02 Paul Brook <paul@codesourcery.com>
+
+ * elf32-arm.c (elf32_arm_merge_eabi_attributes): Handle VFPv4
+ attributes.
+
+2009-11-02 Alan Modra <amodra@bigpond.net.au>
+
+ * elflink.c (elf_link_add_object_symbols): Don't force debug
+ symbols local.
+
+2009-10-29 Johan Kristell <johankri@axis.com>
+
+ * elf32-cris.c (cris_elf_plt_sym_val): New function.
+ (elf_backend_plt_sym_val): Define.
+
+2009-10-27 Kai Tietz <kai.tietz@onevision.com>
+
+ * peXXigen.c (bfdver.h): Add include.
+ (LINKER_VERSION): Do calculation based on BFD_VERSION.
+
+2009-10-25 Maciej W. Rozycki <macro@linux-mips.org>
+
+ * elf32-vax.c (elf_vax_relocate_section): Correct assertion.
+
+2009-10-25 Maciej W. Rozycki <macro@linux-mips.org>
+
+ * elf32-vax.c (elf_vax_plt_entry): Fix formatting.
+
+2009-10-25 Maciej W. Rozycki <macro@linux-mips.org>
+
+ * elf32-vax.c (elf_vax_relocate_section): Fix a typo.
+
+2009-10-23 Kai Tietz <kai.tietz@onevision.com>
+
+ * coff-x86_64.c (coff_amd64_rtype_to_howto): Subtract offset
+ of R_AMD64_PCRLONG_<X> relocations from addend.
+
+2009-10-23 Alan Modra <amodra@bigpond.net.au>
+
+ * plugin.c: Produce empty object if not BFD_SUPPORTS_PLUGINS.
+
+2009-10-20 Alan Modra <amodra@bigpond.net.au>
+
+ PR binutils/10802
+ * opncls.c (_maybe_make_executable): Make DYNAMIC files executable.
+
+2009-10-19 Edgar E. Iglesias <edgar@axis.com>
+ Hans-Peter Nilsson <hp@axis.com>
+
+ * elf32-cris.c (cris_elf_relocate_section) <case R_CRIS_32_DTPREL>:
+ Don't subtract the size of the TLS block for non-shared objects
+ from the relocation.
+
+2009-10-17 Arnold Metselaar <arnold.metselaar@planet.nl>
+
+ * coff-z80.c (z80coff_vec): Allow sections to be of type
+ SEC_CODE or SEC_DATA
+
+2009-10-16 Alan Modra <amodra@bigpond.net.au>
+
+ PR binutils/10785
+ * coff-alpha.c (alpha_ecoff_get_elt_at_filepos): Don't bfd_alloc
+ bim and bim->buffer. bfd_malloc instead.
+ * peicode.h (pe_ILF_build_a_bfd): Similarly.
+ (ILF_DATA_SIZE): Don't include bim.
+ * opncls.c (bfd_close): Test bim->buffer non-NULL before freeing.
+
+2009-10-14 Alan Modra <amodra@bigpond.net.au>
+
+ * aoutx.h (aout_link_check_ar_symbols): Typo fix.
+
+2009-10-13 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR binutils/10763
+ * elf32-i386.c (elf_i386_finish_dynamic_symbol): Declare plt
+ earlier.
+
+2009-10-13 Alan Modra <amodra@bigpond.net.au>
+
+ * elflink.c (_bfd_elf_merge_symbol): Revert previous patch.
+
+2009-10-12 Roland McGrath <roland@frob.com>
+
+ * elflink.c (elf_link_add_object_symbols, _bfd_elf_merge_symbol):
+ Fix %s that should be %B in several message formats.
+
+2009-10-10 Alan Modra <amodra@bigpond.net.au>
+
+ * cofflink.c (_bfd_coff_link_input_bfd): Skip section symbols for
+ excluded output sections.
+
+2009-10-09 Tristan Gingold <gingold@adacore.com>
+
+ * mach-o.c (bfd_mach_o_read_command): Handle BFD_MACH_O_LC_RPATH.
+ (bfd_mach_o_bfd_print_private_bfd_data): Ditto.
+
+2009-10-09 Tristan Gingold <gingold@adacore.com>
+
+ * mach-o.c (bfd_mach_o_scan_read_symtab_symbols): Rename to
+ bfd_mach_o_read_symtab_symbols.
+ (bfd_mach_o_scan_write_thread): Rename to bfd_mach_o_write_thread.
+ (bfd_mach_o_scan_write_relocs): Rename to bfd_mach_o_write_relocs.
+ (bfd_mach_o_scan_write_section_32): Rename to
+ bfd_mach_o_write_section_32.
+ (bfd_mach_o_scan_write_section_64): Rename to
+ bfd_mach_o_write_section_64.
+ (bfd_mach_o_scan_write_segment_32): Rename to
+ bfd_mach_o_write_segment_32.
+ (bfd_mach_o_scan_write_segment_64): Rename to
+ bfd_mach_o_write_segment_64.
+ (bfd_mach_o_scan_write_symtab): Rename to bfd_mach_o_write_symtab.
+ (bfd_mach_o_scan_read_section_32): Rename to
+ bfd_mach_o_read_section_32.
+ (bfd_mach_o_scan_read_section_64): Rename to
+ bfd_mach_o_read_section_64.
+ (bfd_mach_o_scan_read_section): Rename to bfd_mach_o_read_section.
+ (bfd_mach_o_scan_read_symtab_strtab): Rename to
+ bfd_mach_o_read_symtab_strtab.
+ (bfd_mach_o_scan_read_symtab_symbol): Rename to
+ bfd_mach_o_read_symtab_symbol.
+ (bfd_mach_o_scan_read_dysymtab_symbol): Rename to
+ bfd_mach_o_read_dysymtab_symbol.
+ (bfd_mach_o_scan_read_dylinker): Rename to bfd_mach_o_read_dylinker.
+ (bfd_mach_o_scan_read_dylib): Rename to bfd_mach_o_read_dylib.
+ (bfd_mach_o_scan_read_prebound_dylib): Rename to
+ bfd_mach_o_read_prebound_dylib.
+ (bfd_mach_o_scan_read_thread): Rename to bfd_mach_o_read_thread.
+ (bfd_mach_o_scan_read_dysymtab): Rename to bfd_mach_o_read_dysymtab.
+ (bfd_mach_o_scan_read_symtab): Rename to bfd_mach_o_read_symtab.
+ (bfd_mach_o_scan_read_uuid): Rename to bfd_mach_o_read_uuid.
+ (bfd_mach_o_scan_read_linkedit): Rename to bfd_mach_o_read_linkedit.
+ (bfd_mach_o_scan_read_str): Rename to bfd_mach_o_read_str.
+ (bfd_mach_o_scan_read_dyld_info): Rename to bfd_mach_o_read_dyld_info.
+ (bfd_mach_o_scan_read_segment): Rename to bfd_mach_o_read_segment.
+ (bfd_mach_o_scan_read_segment_32): Rename to
+ bfd_mach_o_read_segment_32.
+ (bfd_mach_o_scan_read_segment_64): Rename to
+ bfd_mach_o_read_segment_64.
+ (bfd_mach_o_scan_read_command): Rename to bfd_mach_o_read_command.
+ * mach-o.h (bfd_mach_o_scan_read_dysymtab_symbol): Rename to
+ bfd_mach_o_read_dysymtab_symbol.
+
+2009-10-09 Tristan Gingold <gingold@adacore.com>
+
+ * mach-o.c (bfd_mach_o_section_get_entry_size): Moved.
+ (bfd_mach_o_section_get_nbr_indirect): Ditto.
+ (bfd_mach_o_get_synthetic_symtab): New function.
+ (bfd_mach_o_print_private_header): Print the number of commands
+ in decimal.
+ * mach-o.h (bfd_mach_o_get_synthetic_symtab): Add prototype.
+ * mach-o-target.c: Do not defined bfd_mach_o_get_synthetic_symtab.
+
+2009-10-08 Tristan Gingold <gingold@adacore.com>
+
+ * config.bfd: Add bfd_mach_o_i386_vec in x86_64-darwin targ_selvecs.
+
+2009-10-06 H.J. Lu <hongjiu.lu@intel.com>
+
+ * bfd-in2.h: Regenerated.
+
+2009-10-02 Alan Modra <amodra@bigpond.net.au>
+
+ * aout-cris.c (N_SHARED_LIB): Don't define.
+ * hp300bsd.c (N_SHARED_LIB): Don't define.
+ * i386bsd.c (N_SHARED_LIB): Don't define.
+ * i386linux.c (N_SHARED_LIB): Don't define.
+ * i386lynx.c (N_SHARED_LIB): Don't define.
+ * m68klinux.c (N_SHARED_LIB): Don't define.
+ * m88kmach3.c (N_SHARED_LIB): Don't define.
+ * mipsbsd.c (N_SHARED_LIB): Don't define.
+ * newsos3.c (N_SHARED_LIB): Don't define.
+ * pc532-mach.c (N_SHARED_LIB): Don't define.
+ * pdp11.c (N_SHARED_LIB): Don't define.
+ * sparclinux.c (N_SHARED_LIB): Don't define.
+ * vaxbsd.c (N_SHARED_LIB): Don't define.
+
+2009-10-01 Dave Korn <dave.korn.cygwin@gmail.com>
+
+ * cofflink.c (_bfd_coff_generic_relocate_section): Look for the aux
+ symbol for a weak undef in the auxbfd, not the input bfd.
+
+2009-10-01 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * elf32-spu.c (spu_elf_auto_overlay): Insert icache linker script
+ after .toe instead of before .text section. Set the LMA of all
+ overlay sections to their icache IA address.
+ (spu_elf_find_overlays): Determine icache set id without reference
+ to the LMA.
+
+2009-09-30 Tristan Gingold <gingold@adacore.com>
+
+ * configure.com: Use hosts/alphavms.h on both alpha and ia64 VMS.
+
+2009-09-29 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf64-x86-64.c (elf64_x86_64_append_rela): New.
+ (elf64_x86_64_relocate_section): Use it.
+ (elf64_x86_64_finish_dynamic_symbol): Likewise.
+
+2009-09-29 DJ Delorie <dj@redhat.com>
+
+ * Makefile.am (ALL_MACHINES): Add cpu-rx.lo.
+ (ALL_MACHINES_CFILES): Add cpu-rx.c.
+ (BFD32_BACKENDS): Add elf32-rx.lo.
+ (BFD32_BACKENDS_CFILES): Add elf32-rx.c.
+ * archures.c (bfd_architecture): Add bfd_arch_rx and bfd_mach_rx.
+ Export bfd_rx_arch.
+ (bfd_archures_list): Add bfd_rx_arch.
+ * config.bfd: Add entry for rx-*-elf.
+ * configure.in: Add entries for bfd_elf32_rx_le_vec and
+ bfd_elf32_rx_be_vec.
+ * reloc.c: Add RX relocations.
+ * targets.c: Add RX target vectors.
+ * Makefile.in: Regenerate.
+ * bfd-in2.h: Regenerate.
+ * configure: Regenerate.
+ * libbfd.h: Regenerate.
+ * cpu-rx.c: New file.
+ * elf32-rx.c: New file.
+
+2009-09-29 M R Swami Reddy <MR.Swami.Reddy@nsc.com>
+
+ * elf32-cr16.c (elf32_cr16_relocate_section): Removed
+ info->relocatable to fix the ld/testsuites/ld-elf/linkonce1 test case.
+
+2009-09-28 Nick Clifton <nickc@redhat.com>
+
+ PR 10478: Accepting Solaris binaries.
+ * elf.c (bfd_section_from_shdr): Allow SHN_BEFORE and SHN_AFTER
+ section link values in x86 binaries.
+ * elfcode.h (elf_object_p): Likewise.
+
+2009-09-28 Philippe De Muyter <phdm@macqel.be>
+
+ * elf32-m68k.c (elf_m68k_final_write_processing): New function.
+ (elf_backend_final_write_processing): Macro defined as above function.
+
+2009-09-25 Martin Thuresson <martint@google.com>
+
+ Update sources to make alpha and arm targets compile cleanly with
+ -Wc++-compat:
+ * ecoff.c: Add casts.
+ * ecofflink.c: Add casts.
+ * elf64-alpha.c: Add casts.
+ (struct alpha_elf_got_entry, struct alpha_elf_reloc_entry): Move
+ to top level.
+ (SKIP_HOWTO): Use enum name.
+ * elf32-arm.c: Add casts.
+ (elf32_arm_vxworks_bed): Update code to avoid multiple
+ declarations.
+ (struct map_stub): Move to top level.
+
+2009-09-24 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/10630
+ * elflink.c (elf_link_output_extsym): Turn off visibility on
+ local symbol.
+ (bfd_elf_final_link): Turn off visibility on dynamic local
+ symbol.
+
+2009-09-24 Alan Modra <amodra@bigpond.net.au>
+
+ PR binutils/10654
+ * dwarf2.c (lookup_address_in_line_info_table): Remove workaround
+ for invalid location lists generated by gcc-2.95 and Intel 6.0 C++.
+ Remove "function" parm, adjust caller.
+
+2009-09-23 Matt Rice <ratmice@gmail.com>
+
+ * bfd-in.h (bfd_elf_size_dynamic_sections): Add audit and depaudit
+ arguments.
+ * elflink.c (bfd_elf_size_dynamic_sections): Generate DT_AUDIT,
+ DT_DEPAUDIT from audit/depaudit arguments.
+ (elf_finalize_dynstr): Finalize DT_AUDIT and DT_DEPAUDIT strtab entries.
+ (elf_link_add_object_symbols): Set dt_audit target data when finding a
+ DT_AUDIT.
+ * bfd-in2.h: Regenerate.
+ * bfd-elf.h: Add dt_audit to elf_obj_tdata, and elf_dt_audit macro.
+
+2009-09-23 Jie Zhang <jie.zhang@analog.com>
+
+ * elf32-bfin.c (_bfinfdpic_size_got_plt): Make sure empty
+ .rel.plt and .plt sections are removed.
+ (elf32_bfinfdpic_size_dynamic_sections): Remove empty .dynbss
+ section. Remove the duplicated removing of empty .rel.plt
+ section.
+
+2009-09-21 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * elf-eh-frame.c (_bfd_elf_write_section_eh_frame): Extend previous
+ patch to handle the new personality relaxation.
+
+2009-09-21 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * elf-eh-frame.c (make_pc_relative): New function.
+ (_bfd_elf_write_section_eh_frame): Use it.
+
+2009-09-21 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-ppc.c (TLS_GET_ADDR_GLINK_SIZE): Define.
+ (ADD_3_12_2, BEQLR, CMPWI_11_0, LWZ_11_3, LWZ_12_3): Define.
+ (MR_0_3, MR_3_0): Define.
+ (struct ppc_elf_link_hash_table): Add no_tls_get_addr_opt.
+ (ppc_elf_select_plt_layout): Save emit_stub_syms param earlier.
+ (ppc_elf_tls_setup): Add no_tls_get_addr_opt param and save to hash
+ table. Check for presense of __tls_get_addr_opt
+ (allocate_dynrelocs): Increase glink entry size for __tls_get_addr.
+ (ppc_elf_size_dynamic_sections): Add DT_PPC_TLS_OPT tag.
+ (write_glink_stub): Add param p.
+ (ppc_elf_relocate_section): Adjust write_glink_stub call.
+ (ppc_elf_finish_dynamic_symbol): Emit special glink call stub for
+ __tls_get_addr.
+ * elf32-ppc.h (ppc_elf_tls_setup): Update prototype.
+ * elf64-ppc.c (struct ppc_link_hash_table): Add no_tls_get_addr_opt.
+ (ppc64_elf_tls_setup): Add no_tls_get_addr_opt param and save to hash
+ table. Check for presense of __tls_get_addr_opt.
+ (ppc64_elf_size_dynamic_sections): Add DT_PPC64_TLS_OPT tag.
+ (LD_R11_0R3, LD_R12_0R3, MR_R0_R3, CMPDI_R11_0, ADD_R3_R12_R13,
+ BEQLR, MR_R3_R0, MFLR_R11, STD_R11_0R1, BCTRL, LD_R11_0R1,
+ LD_R2_0R1, MTLR_R11): Define.
+ (build_tls_get_addr_stub): New function.
+ (ppc_build_one_stub): Call it.
+ (ppc_size_one_stub): Add extra size for __tls_get_addr stub.
+ (ppc64_elf_relocate_section): Don't change nop to ld 2,40(1) for
+ __tls_get_addr plt call.
+ * elf64-ppc.h (ppc64_elf_tls_setup): Update prototype.
+
+2009-09-19 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * elf-bfd.h (eh_cie_fde): Add personality_offset and
+ make_per_encoding_relative to the CIE structure. Add a padding field.
+ * elf-eh-frame.c (_bfd_elf_eh_frame_section_offset): Use 0x70
+ rather than 0xf0 when masking out the base address encoding
+ Record the offset of personality data from the start of the CIE.
+ Remove a repeated elf_backend_can_make_relative_eh_frame check.
+ (find_merged_cie): Take an info argument. If the personality
+ binds locally, try converting an absolute personality into
+ a local one.
+ (_bfd_elf_discard_section_eh_frame): Use 0x70 rather than 0xf0
+ when masking out the base address encoding. Update the call to
+ find_merged_cie.
+ (_bfd_elf_eh_frame_section_offset): Discard relocations against
+ the personality data if we are converting into PC-relative form.
+ (_bfd_elf_write_section_eh_frame): Use 0x70 rather than 0xf0
+ when masking out the base address encoding. Handle
+ make_per_encoding_relative.
+
+2009-09-18 Alan Modra <amodra@bigpond.net.au>
+
+ PR ld/10406
+ * elf32-ppc.c (ppc_elf_howto_raw): Make R_PPC_EMB_SDAI16 and
+ R_PPC_EMB_SDA2I16 complain_overflow_signed.
+ (create_sdata_sym): Pass info rather than htab.
+ Update all callers. Ensure symbols are hidden.
+ (ppc_elf_check_relocs): Allow SDAREL16 when shared.
+ (ppc_elf_size_dynamic_sections): When shared, equate _SDA_BASE_ to
+ _GLOBAL_OFFSET_TABLE_.
+ (elf_finish_pointer_linker_section): Don't assume that sdata base
+ symbol is always at 0x8000 offset. Don't subtract the addend here.
+ (is_static_defined): New function.
+ (ppc_elf_relocate_section): Verify symbol base used in SDA relocs
+ is statically defined. Clear addend for EMB_SDAI16 and EMB_SDA2I16
+ relocs. Downgrade error on unexpected section for EMB_SDA2REL
+ reloc symbols to a warning.
+
+2009-09-18 Nick Clifton <nickc@redhat.com>
+
+ * po/es.po: Updated Spanish translation.
+ * po/vi.po: Updated Vietnamese translation.
+
+2009-09-18 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (follow_link, elf_follow_link, ppc_follow_link): New
+ functions. Use throughout.
+ (ppc64_elf_copy_indirect_symbol): Set direct symbol "oh" field
+ from indirect symbol.
+ (lookup_fdh): Rename from get_fdh. Follow indirect sym links.
+ (add_symbol_adjust): Simplify.
+ (defined_code_entry, defined_func_desc): New functions.
+ (ppc64_elf_gc_keep): Follow indirect sym links. Use defined_code_entry.
+ (ppc64_elf_gc_mark_dynamic_ref): Use defined_func_desc and
+ defined_code_entry to follow indirect sym links.
+ (ppc64_elf_gc_mark_hook, func_desc_adjust): Likewise.
+ (ppc_type_of_stub): Follow indirect sym links.
+ (toc_adjusting_stub_needed): Likewise.
+ (ppc_build_one_stub): Likewise. Make undefined dot-symbols weak
+ rather than defining them at stub.
+ (ppc64_elf_relocate_section): Rewrite call test to avoid multiple
+ assignments in test.
+
+2009-09-16 Tristan Gingold <gingold@adacore.com>
+
+ * mach-o.h (bfd_mach_o_filetype): Add new constants from darwin10.
+ Reindent.
+ * mach-o.c (bfd_mach_o_cpu_name): Reindent.
+ (bfd_mach_o_filetype_name): Complete with new constants. Reindent.
+ (bfd_mach_o_print_private_header): Use fputs instead of fprintf
+ when possible to avoid warnings.
+ (bfd_mach_o_print_section_map): Ditto.
+ (bfd_mach_o_section_get_entry_size): New function.
+ (bfd_mach_o_section_get_nbr_indirect): Simplify using the newly
+ added function.
+ (bfd_mach_o_print_dysymtab): Print address of indirect symbols.
+
+2009-09-14 Nick Clifton <nickc@redhat.com>
+
+ * po/fi.po: Updated Finnish translation.
+
+2009-09-11 Nick Clifton <nickc@redhat.com>
+
+ * po/bfd.pot: Updated by the Translation project.
+
+2009-09-11 Philippe De Muyter <phdm@macqel.be>
+
+ * binary.c (binary_object_p): Remove bfd_external_binary_architecture
+ hack. objcopy `-B' (`--binary-architecture') option is now handled
+ in a generic way.
+
+2009-09-11 Nick Clifton <nickc@redhat.com>
+
+ * rs6000-core.c (read_hdr): Fix typo in recent C++ compatibility
+ changes.
+
+2009-09-11 Jie Zhang <jie.zhang@analog.com>
+
+ * elf32-bfin.c (bfinfdpic_relocs_info_find): Just return
+ NULL if `ht' is NULL.
+
+2009-09-09 Martin Thuresson <martin@mtme.org>
+
+ Update sources to compile cleanly with -Wc++-compat:
+ * aoutx.h: Add casts.
+ * archive.c: Add casts.
+ * archive64.c: Add casts.
+ * archures.c: Add casts.
+ * bfd-in2.h: Regenerated.
+ * bfd.c: Add casts. (enum bfd_direction): Move out to top level.
+ * bfdio.c: Add casts.
+ * binary.c: Add casts.
+ * cache.c (cache_bseek,cache_bread_1,cache_bwrite): Updated
+ parameter to use enum value instead of int.
+ * coffcode.h: Add casts.
+ * coffgen.c: Add casts.
+ * cofflink.c: Add casts.
+ * compress.c: Add casts.
+ * dwarf1.c: Add casts.
+ * dwarf2.c: Add casts. (struct dwarf2_debug): Rename member bfd to
+ bfd_ptr. Update code to use new name.
+ * elf-attrs.c: Add casts.
+ * elf-bfd.h (elf_link_virtual_table_entry): Gives name to
+ anonymous struct. (union gotplt_union, struct
+ elf_link_virtual_table_entry): Move to top level.
+ * elf-eh-frame.c: Add casts.
+ * elf-strtab.c: Add casts.
+ * elf.c: Add casts. (_bfd_elm_make_Section_from_phdr): Change
+ argument name from typename to type_name.
+ * elf32-i386.c: Add casts.
+ * elf64-x86-64.c: Add casts.
+ * elfcode.h: Add casts.
+ * elfcore.h: Add casts.
+ * elflink.c: Add casts.
+ * format.c: Add casts.
+ * hash.c: Add casts.
+ * ihex.c: Add casts.
+ * libaout.h (enum aout_subformat, enum aout_magic): Move to top
+ level.
+ * libbfd.c: Add casts.
+ * linker.c: Add casts.
+ * merge.c: Add casts.
+ * opncls.c: Add casts.
+ * peXXigen.c: Add casts.
+ * peicode.h: Add casts.
+ * reloc.c: Add casts.
+ * section.c: Add casts.
+ * simple.c: Add casts.
+ * srec.c: Add casts.
+ * stabs.c: Add casts.
+ * syms.c: Add casts.
+ * targets.c: Add casts.
+ * tekhex.c: Add casts.
+ * verilog.c: Add casts.
+
+2009-09-09 Paolo Bonzini <bonzini@gnu.org>
+
+ * configure: Regenerate.
+
+2009-09-09 Daniel Jacobowitz <dan@codesourcery.com>
+
+ * elf32-arm.c (elf32_arm_final_link_relocate): Set sym_flags
+ for the mode of target PLT entries.
+ (allocate_dynrelocs): Only adjust symbol type if setting its
+ value.
+
+2009-09-09 Paolo Bonzini <bonzini@gnu.org>
+
+ * configure: Regenerate.
+
+2009-09-09 Nick Clifton <nickc@redhat.com>
+
+ PR 10478:
+ * elf.c (bfd_section_from_shdr): Do not reject sparc binaries with
+ section headers containing sh_link values of SHN_BEFORE or
+ SHN_AFTER.
+ * elfcode.h (elf_object_p): Likewise.
+
+2009-09-09 Tristan Gingold <gingold@adacore.com>
+
+ Handle DYLD_INFO introduced by Darwin10.
+ * mach-o.h (bfd_mach_o_load_command_type): Add
+ BFD_MACH_O_LC_DYLD_INFO.
+ (bfd_mach_o_dyld_info_command): New type.
+ (bfd_mach_o_load_command): Add dyld_info field.
+ * mach-o.c (bfd_mach_o_scan_read_str): Reduce size of buf.
+ (bfd_mach_o_scan_read_dyld_info): New function.
+ (bfd_mach_o_scan_read_command): Handle BFD_MACH_O_LC_DYLD_INFO.
+ (bfd_mach_o_bfd_print_private_bfd_data): Ditto.
+ (bfd_mach_o_load_command_name): AddB FD_MACH_O_LC_DYLD_INFO.
+ (bfd_mach_o_print_dyld_info): New function.
+
+2009-09-09 M R Swami Reddy <MR.Swami.Reddy@nsc.com>
+
+ * elf32-cr16.c (elf32_cr16_relocate_section): Add code to discard the
+ linkonce or linker script discarded section.
+
+2009-09-09 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-xtensa.c (elf_xtensa_relax_section): Delete -r check.
+
+2009-09-07 Andreas Schwab <schwab@linux-m68k.org>
+
+ * elf32-m68k.c (rtype_to_howto): If the reloc index is out of
+ range call the bfd error hander and use R_68K_NONE instead.
+
+2009-09-07 Tristan Gingold <gingold@adacore.com>
+
+ * po/SRC-POTFILES.in: Regenerate.
+ * po/bfd.pot: Regenerate.
+
+ * bfd.m4 (BFD_HAVE_TIME_TYPE_MEMBER,
+ BFD_HAVE_SYS_STAT_TYPE_MEMBER): Moved to gas/acinclude.m4
+ * configure.in: Move tests for tm_gmtoff, st_mtim.tv_sec and
+ st_mtim.tv_nsec to gas/configure.in
+ (bfd_elf64_ia64_vms_vec): Remove vmsutil.lo
+ * configure: Regenerate.
+ * config.in: Regenerate.
+ * vmsutil.c: Moved to gas/config/te-vms.c
+ * vmsutil.h: Removed.
+ * Makefile.am (BFD32_BACKENDS_CFILES): Remove vmsutil.c
+ (BFD32_BACKENDS): Remove vmsutil.lo
+ * Makefile.in: Regenerate.
+
+2009-09-05 Eli Zaretskii <eliz@gnu.org>
+
+ * coffcode.h: Include libiberty.h.
+
+2009-09-05 Martin Thuresson <martin@mtme.org>
+
+ * coff-arm.c (coff_arm_relocate_section)
+ (record_thumb_to_arm_glue, bfd_arm_process_before_allocation):
+ Change member name class to symbol_class.
+ * coff-i960.c (coff_i960_relocate_section) Rename variable
+ class to class_val. Change member name class to symbol_class.
+ * coff-rs6000.c (_bfd_xcoff_swap_aux_in)
+ (_bfd_xcoff_swap_aux_out): Rename arguments class to in_class.
+ * coff-stgo32.c (adjust_aux_in_post)
+ (adjust_aux_out_pre, adjust_aux_out_post): Rename arguments class
+ to in_class.
+ * coff64-rs6000.c (_bfd_xcoff64_swap_aux_in)
+ (_bfd_xcoff64_swap_aux_out): Rename arguments class to in_class.
+ * coffcode.h (coff_pointerize_aux_hook): Rename variable class
+ to n_sclass.
+ * coffgen.c (coff_write_symbol, coff_pointerize_aux): Rename
+ variables named class to n_sclass. (coff_write_symbols): Rename
+ variable class to sym_class. (bfd_coff_set_symbol_class): Rename
+ argument class to symbol_class.
+ * cofflink.c (_bfd_coff_link_hash_newfunc)
+ (coff_link_add_symbols, _bfd_coff_link_input_bfd)
+ (_bfd_coff_write_global_sym, _bfd_coff_generic_relocate_section):
+ Update code to use renamed members.
+ * coffswap.h (coff_swap_aux_in, coff_swap_aux_out): Rename
+ argument class to in_class.
+ * libcoff-in.h (struct coff_link_hash_entry, struct
+ coff_debug_merge_type) Renamed members class to symbol_class and
+ type_class.
+ * libcoff.h Regenerated.
+ * peXXigen.c: (_bfd_XXi_swap_aux_in, _bfd_XXi_swap_aux_out):
+ Rename argument class to in_class.
+ * pef.c (bfd_pef_parse_imported_symbol): Update code to use
+ renamed members.
+ * pef.h (struct bfd_pef_imported_symbol): Changed name of
+ member class to symbol_class.
+
+2009-09-04 H.J. Lu <hongjiu.lu@intel.com>
+
+ * configure: Regenerated.
+
+2009-09-04 Tristan Gingold <gingold@adacore.com>
+
+ * configure.in: Bump version to 2.20.51
+
+2009-09-04 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-spu.c (spu_elf_relocate_section): Correct 2009-07-24 logic.
+
+2009-09-04 Jie Zhang <jie.zhang@analog.com>
+
+ * elf32-bfin.c (elf32_bfinfdpic_create_dynamic_sections): Always
+ create .rela.bss.
+ (elf32_bfinfdpic_size_dynamic_sections): Set SEC_EXCLUDE flag
+ for empty .rela.bss and .rel.plt sections.
+
+2009-09-03 Adam Nemet <anemet@caviumnetworks.com>
+
+ * elfxx-mips.c (mips_elf_calculate_relocation): Don't relocate
+ R_MIPS_JALR unless symbol resolves locally.
+
+2009-09-03 Adam Nemet <anemet@caviumnetworks.com>
+
+ * elfxx-mips.c (_bfd_mips_elf_check_relocs): Don't set
+ has_static_relocs for R_MIPS_JALR.
+
+2009-09-03 Maciej W. Rozycki <macro@codesourcery.com>
+
+ * elf64-mips.c (mips_elf64_howto_table_rela): Add support for
+ R_MIPS_TLS_DTPMOD64 and R_MIPS_TLS_TPREL64, replacing the
+ respective stubs.
+
+2009-09-01 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf64-x86-64.c (elf64_x86_64_finish_dynamic_symbol): Declare
+ plt earlier.
+
+2009-09-01 Tristan Gingold <gingold@adacore.com>
+
+ * makefile.vms: Ported to Itanium VMS. Remove useless variable and
+ dependencies. Reindent.
+ * configure.com: Ported to Itanium VMS. Now generates a build.com
+ to build without make. Add messages but make edit silent.
+ * hosts/alphavms.h: Add a prototype for stpcpy.
+ * vms.c: Add a missing include for Alpha VMS.
+ * elfxx-ia64.c (ELF_OSABI): Define for OpenVMS.
+
+2009-08-31 Jan Beulich <jbeulich@novell.com>
+
+ * elf-bfd.h (bfd_elf_get_default_section_type): Declare.
+ * elf.c (bfd_elf_get_default_section_type): New.
+ (elf_fake_sections): Use bfd_elf_get_default_section_type.
+
+2009-08-30 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf32-i386.c (elf_i386_finish_dynamic_symbol): Revert the
+ accidental checkin.
+ * elf64-x86-64.c (elf64_x86_64_finish_dynamic_symbol): Likwise.
+
+2009-08-30 Alan Modra <amodra@bigpond.net.au>
+
+ PR ld/10569
+ * bfd.c (bfd_emul_get_maxpagesize): Don't abort.
+ (bfd_emul_get_commonpagesize): Likewise.
+
+2009-08-29 Martin Thuresson <martin@mtme.org>
+
+ * elf32-arm.c (struct stub_def): Rename member template to
+ template_sequence. (arm_build_one_stub,
+ find_stub_size_and_template, arm_size_one_stub, arm_map_one_stub):
+ Rename variable template to template_sequence.
+ * elfxx-ia64.c (elfNN_ia64_relax_br, elfNN_ia64_relax_brl):
+ Rename variable template to template_val.
+ * aoutx.h (NAME (aout, make_empty_symbol)): Rename variable
+ new to new_symbol.
+ * coffgen.c (coff_make_empty_symbol)
+ (coff_bfd_make_debug_symbol): Rename variable new to new_symbol.
+ * cpu-ia64-opc.c (ext_reg, ins_imms_scaled): Rename variable
+ new to new_insn.
+ * ecoff.c (_bfd_ecoff_make_empty_symbol): Rename variable new
+ to new_symbol.
+ * elf32-m68k.c (elf_m68k_get_got_entry_type): Rename argument
+ new to new_reloc.
+ * hash.c (bfd_hash_lookup): Rename variable new to new_string.
+ * ieee.c (ieee_make_empty_symbol): Rename variable new to
+ new_symbol.
+ * linker.c (bfd_new_link_order): Rename variable new to
+ new_lo.
+ * mach-o.c (bfd_mach_o_sizeof_headers): Rename variable new to
+ symbol.
+ * oasys.c (oasys_make_empty_symbol): Rename variable new to
+ new_symbol_type.
+ * pdp11.c (NAME (aout, make_empty_symbol)): Rename variable
+ new to new_symbol_type.
+ * plugin.c (bfd_plugin_make_empty_symbol): Rename variable new
+ to new_symbol.
+ * rs6000-core.c (CoreHdr, VmInfo): Rename union member new to
+ new_dump.
+ (read_hdr, rs6000coff_core_p)
+ (rs6000coff_core_file_matches_executable_p)
+ (rs6000coff_core_file_failing_command)
+ (rs6000coff_core_file_failing_signal): Updated function to use new
+ union member name.
+ * som.c (som_make_empty_symbol): Rename variable new to
+ new_symbol_type.
+ * syms.c (_bfd_generic_make_empty_symbol): Rename variable new
+ to new_symbol.
+ * tekhex.c (first_phase, tekhex_make_empty_symbol): Rename
+ variable new to new_symbol.
+
+2009-08-27 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
+
+ * acinclude.m4 (AM_INSTALL_LIBBFD): Call AM_SUBST_NOTMAKE for
+ bfdlibdir and bfdincludedir.
+ * Makefile.am (bfdlibdir, bfdincludedir): Move definition ...
+ [INSTALL_LIBBFD]: ... here, ...
+ [INSTALL_LIBBFD]: ... and empty overrides here.
+ [!INSTALL_LIBBFD]: (rpath_bfdlibdir): New variable.
+ [!INSTALL_LIBBFD] (libbfd_la_LDFLAGS): Use it.
+ * Makefile.in: Regenerate.
+ * configure: Regenerate.
+
+2009-08-26 Maxim Kuvyrkov <maxim@codesourcery.com>
+
+ * elf32-m68k.c: Rewrite initialization of GOT entries for TLS
+ relocations. Rewrite output of dynamic TLS relocations.
+ (DTP_OFFSET, TP_OFFSET): New constants.
+ (dtpoff_base): Update.
+ (tpoff): Rename to tpoff_base, update.
+ (elf_m68k_init_got_entry_static, elf_m68k_init_got_entry_local_shared):
+ New functions. Move code from elf_m68k_relocate_section here.
+ (elf_m68k_relocate_section): Update.
+ (elf_m68k_finish_dynamic_symbol): Fix handling of local TLS symbols.
+
+2009-08-26 Maxim Kuvyrkov <maxim@codesourcery.com>
+
+ * elf32-m68k.c (elf_m68k_copy_indirect_symbol): Propagate
+ non_got_ref value.
+ (elf_m68k_check_relocs): Handle dynamic TLS relocations.
+ Handle non_got_ref field.
+ (elf_m68k_adjust_dynamic_symbol): Handle non_got_ref field.
+
+2009-08-26 Alan Modra <amodra@bigpond.net.au>
+
+ PR ld/10518
+ * linker.c (bfd_find_version_for_sym): Revert warning.
+
+2009-08-26 Alan Modra <amodra@bigpond.net.au>
+
+ PR ld/10518
+ * linker.c (bfd_find_version_for_sym): Override a "*" match by any
+ other wildcard match. Warn on multiple wildcard matches.
+
+2009-08-22 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
+
+ * Makefile.am (libbfd_la_LDFLAGS): Initialize early, to allow
+ appending.
+ [INSTALL_LIBBFD] (bfdlib_LTLIBRARIES, bfdinclude_HEADERS): Set
+ only in this condition.
+ [!INSTALL_LIBBFD] (noinst_LTLIBRARIES, libbfd_la_LDFLAGS): New,
+ to build but not install libbfd.la in this condition.
+ (install-bfdlibLTLIBRARIES, uninstall-bfdlibLTLIBRARIES)
+ (install_libbfd, install_libbfd): Remove.
+ * Makefile.in: Regenerate.
+ * doc/Makefile.am (AM_CPPFLAGS): Renamed from ...
+ (INCLUDES): ... this.
+ ($(MKDOC)): Adjust.
+ * doc/Makefile.in: Regenerate.
+
+ * Makefile.am (AUTOMAKE_OPTIONS): Remove cygnus, instead use
+ no-dist and foreign.
+ (EXTRA_libbfd_la_SOURCES): New, list $(CFILES) to allow
+ dependency tracking to work for them.
+ (targets.lo, archures.lo, dwarf.lo): Rewrite to
+ use automake dependency tracking mechanism.
+ (MKDEP, DEP, DEP1, dep.sed, dep, dep-in, dep-am): Remove.
+ (mkdep section): Remove.
+ (BUILT_SOURCES): New, list $(BUILD_HFILES).
+ * Makefile.in: Regenerate.
+ * po/SRC-POTFILES.in, po/bfd.pot: Regenerate.
+
+ * Makefile.am (datarootdir, docdir, htmldor, pdfdir)
+ (install-pdf, install-pdf-recursive, install-html)
+ (install-html-recursive): Remove.
+ * Makefile.in: Regenerate.
+
+ * Makefile.in: Regenerate.
+ * aclocal.m4: Likewise.
+ * config.in: Likewise.
+ * configure: Likewise.
+
+2009-08-21 Daniel Gutson <dgutson@codesourcery.com>
+
+ * elf32-arm.c (arch_has_thumb2_nop): New function.
+ (arch_has_arm_nop): New function.
+ (elf32_arm_final_link_relocate): NOP opcodes changed.
+
+2009-08-16 Doug Evans <dje@google.com>
+
+ * opncls.c (bfd_close): Until BFD_IN_MEMORY has an iovec,
+ at least don't leak memory.
+
+2009-08-13 DJ Delorie <dj@redhat.com>
+
+ * elf32-m32c.c (m32c_elf_relax_delete_bytes): Adjust symbol sizes
+ if needed.
+
+2009-08-12 Nick Clifton <nickc@redhat.com>
+
+ * po/fi.po: Updated Finnish translation.
+
+2009-08-11 Bernd Schmidt <bernd.schmidt@analog.com>
+
+ Merge some FRV FDPIC changes into the Blackfin code.
+ * elf32-bfin.c (struct bfinfdpic_elf_link_hash_table): Add pointer to
+ summary reloc information.
+ (bfinfdpic_dynamic_got_plt_info): New.
+ (_bfin_create_got_section): Create the PLT section here.
+ (elf32_bfinfdpic_create_dynamic_sections): Not here.
+ (_bfinfdpic_count_nontls_entries): Move out of...
+ (_bfinfdpic_count_got_plt_entries): ... here.
+ (_bfinfdpic_count_relocs_fixups): Likewise.
+ (_bfinfdpic_reset_got_plt_entries): New.
+ (_bfinfdpic_size_got_plt): Move out of...
+ (elf32_bfinfdpic_size_dynamic_sections): ... here.
+ (bfinfdpic_relocate_section): Be careful not to call
+ _bfinfdpic_add_rofixup or _bfinfdpic_add_dyn_reloc for deleted relocs.
+ (bfinfdpic_check_discarded_relocs, bfinfdpic_elf_discard_info):
+ New functions.
+ (elf_backend_discard_info): Define for FD-PIC.
+
+2009-08-11 Alan Modra <amodra@bigpond.net.au>
+
+ * elflink.c: Add FIXMEs for some places that require octets_per_byte
+ adjustments.
+ * elf-eh-frame.c: Likewise.
+ * merge.c: Likewise.
+
+2009-08-11 Alan Modra <amodra@bigpond.net.au>
+
+ * configure.in: Remove elf-ifunc.lo from common ELF files. Add
+ to x86 and x86_64 configurations.
+ * configure: Regenerate.
+
+2009-08-10 Jan Kratochvil <jan.kratochvil@redhat.com>
+
+ Stop using bfd_usrdata in libbfd.
+ * coff-stgo32.c (bfd_coff_go32stub): Remove.
+ (stub_bytes, comment): Replace STUBSIZE by GO32_STUBSIZE.
+ (adjust_filehdr_in_post): Declare the abfd parameter as unused.
+ Replace STUBSIZE by GO32_STUBSIZE. Save now the stub in
+ filehdr_dst->u.go32.stub. New comment with the reason.
+ (adjust_filehdr_out_pre): Replace STUBSIZE by GO32_STUBSIZE.
+ Substitute the removed macro bfd_coff_go32stub.
+ (adjust_filehdr_out_post, adjust_scnhdr_in_post, adjust_scnhdr_out_pre)
+ (adjust_scnhdr_out_post, adjust_aux_in_post, adjust_aux_out_pre)
+ (adjust_aux_out_post): Replace STUBSIZE by GO32_STUBSIZE.
+ (create_go32_stub, go32_stubbed_coff_bfd_copy_private_bfd_data):
+ Replace STUBSIZE by GO32_STUBSIZE. Substitute the removed macro
+ bfd_coff_go32stub.
+ * coffcode.h (coff_mkobject_hook): Initialize coff->go32stub.
+ * libcoff-in.h (coff_data_type): New field go32stub.
+ * libcoff.h: Regenerated.
+
+2009-08-10 Jan Kratochvil <jan.kratochvil@redhat.com>
+
+ Fix go32 stub preservation by objcopy.
+ * coff-stgo32.c (adjust_filehdr_in_post): Use bfd_malloc.
+ (go32_stubbed_coff_bfd_copy_private_bfd_data): Optionally allocate OBFD
+ go32stub.
+
+2009-08-10 Nathan Sidwell <nathan@codesourcery.com>
+
+ * elf32-arm.c (elf32_arm_size_stubs): Don't die on undefined local
+ symbols.
+ (elf32_arm_final_link_relocate): Treat local undefined symbols the
+ same as global undefined symbols.
+ (elf32_arm_relocate_section): Give an error for local undefined
+ non-weak symbols, unless the reloc will not use the symbol.
+
+2009-08-10 Nathan Sidwell <nathan@codesourcery.com>
+
+ * elf32-ppc.c (shared_stub_entry, stub_entry): Use r12, not r11.
+ (ppc_elf_relax_section): Use symbol index to distinguish
+ relocatable stubs.
+
+2009-08-10 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-ppc.c (ppc_elf_relax_section): Ignore non-code sections.
+
+2009-08-10 Alan Modra <amodra@bigpond.net.au>
+
+ * elflink.c (_bfd_elf_adjust_dynamic_symbol): Don't clear plt
+ info for STT_GNU_IFUNC.
+ * elf32-ppc.c (ppc_elf_check_relocs): Count a needed plt entry
+ on got refs in case the symbol turns out to be ifunc.
+ (ppc_elf_gc_sweep_hook): Similarly.
+ (ppc_elf_adjust_dynamic_symbol): Adjust assertion.
+ (allocate_dynrelocs): Don't specially allocate got relocs for ifunc.
+ (ppc_elf_size_dynamic_sections): Likewise.
+ (ppc_elf_relocate_section): Likewise.
+
+2009-08-09 Bernd Schmidt <bernd.schmidt@analog.com>
+
+ From Mike Frysinger <michael.frysinger@analog.com>
+ * elf32-bfin.c (bfin_howto_table, bfin_reloc_map, bfin_check_relocs,
+ bfin_final_link_relocate, bfin_relocate_section, bfin_gc_sweep_hook,
+ _bfinfdpic_emit_got_relocs_plt_entries, bfinfdpic_relocate_section,
+ bfinfdpic_gc_sweep_hook, bfinfdpic_check_relocs,
+ bfin_finish_dynamic_symbol, bfd_bfin_elf32_create_embedded_relocs):
+ Adjust to match the renamed reloc definitions.
+
+2009-08-08 Alan Modra <amodra@bigpond.net.au>
+
+ PR 10494
+ * elf.c (_bfd_elf_make_section_from_shdr): When setting up section
+ LMAs, use ELF_IS_SECTION_IN_SEGMENT to match sections with headers.
+
+2009-08-07 Tom Tromey <tromey@redhat.com>
+
+ * elf32-microblaze.c (microblaze_elf_check_relocs): Avoid strict
+ aliasing error.
+
+2009-08-06 Michael Eager <eager@eagercon.com>
+
+ * Makefile.am: Add cpu-microblaze.{lo,c}, elf32-microblaze.{lo,c}.
+ * Makefile.in: Regenerate.
+ * archures.c: Add bfd_arch_microblaze.
+ * bfd-in2.h: Regenerate.
+ * config.bfd: Add microblaze target.
+ * configure.in: Add bfd_elf32_microblaze_vec target.
+ * configure: Regenerate.
+ * cpu-microblaze.c: New.
+ * elf32-microblaze.c: New.
+ * libbfd-in.h: Add prototype _bfd_dwarf2_fixup_section_debug_loc().
+ * libbfd.h: Regenerate.
+ * reloc.c: Add MICROBLAZE relocations.
+ * section.c: Add struct relax_table and relax_count to section.
+ * targets.c: Add bfd_elf32_microblaze_vec.
+
+2009-08-06 Jakub Jelinek <jakub@redhat.com>
+ Alan Modra <amodra@bigpond.net.au>
+
+ PR binutils/10492
+ * elf.c (sym_is_global): Return true even for BSF_GNU_UNIQUE
+ symbols.
+ * elf32-mips.c (mips_elf_sym_is_global): Likewise.
+ * elfn32-mips.c (mips_elf_sym_is_global): Likewise.
+
+2009-08-06 Nathan Sidwell <nathan@codesourcery.com>
+
+ * elf32-arm.c (elf32_arm_size_stubs): Call layout_sections_again
+ at least once when fixing cortex-a8.
+
+2009-08-05 Chao-ying Fu <fu@mips.com>
+
+ * elf32-mips.c (mips_reloc_map): Add BFD_RELOC_MIPS_JALR.
+ * elfxx-mips.c (JAL_TO_BAL_P): New define to transform JAL to BAL
+ for CPUs. It is true for RM9000.
+ (JALR_TO_BAL_P): New define to transform JALR to BAL. It is true
+ for all CPUs.
+ (mips_elf_perform_relocation): Use JAL_TO_BAL_P and JALR_TO_BAL_P
+ to guard the transformation.
+
+2009-08-05 Trevor Smigiel <Trevor_Smigiel@playstation.sony.com>
+
+ * elf32-spu.h (spu_elf_params): Add member emit_fixups.
+ (spu_elf_size_sections): Declare prototype.
+ * elf32-spu.c (spu_link_hash_table): Add member sfixup.
+ (FIXUP_RECORD_SIZE, FIXUP_GET, FIXUP_PUT): New macros.
+ (spu_elf_emit_fixup): New function.
+ (spu_elf_relocate_section): Emit fixup for each SPU_ADDR32.
+ (spu_elf_size_sections): New function.
+
+2009-08-05 Nathan Sidwell <nathan@codesourcery.com>
+
+ * elf32-arm.c (elf32_arm_stub_type): Add arm_stub_a8_veneer_lwm.
+ (arm_build_one_stub): Build a8 veneers as a separate pass.
+ (cortex_a8_erratum_scan): Add prev_num_a8_fixes and stub_changed_p
+ parameters. Use them to check if we create a different a8 fixup
+ than the previous pass.
+ (elf32_arm_size_stubs): Move scope of stub_changed and
+ prev_num_a8_fixes into main loop.
+ (elf32_arm_build_stubs): Build a8 veneers in a second pass.
+
+2009-08-04 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-ppc.c (ppc_elf_relax_section): Correct conditions under
+ which find_plt_ent is called. Delete redundant code.
+
+2009-08-03 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR binutils/10363
+ * elf.c (bfd_elf_string_from_elf_section): Return NULL on
+ invalid string offset.
+
+2009-08-03 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/10433
+ * elf-ifunc.c (_bfd_elf_allocate_ifunc_dyn_relocs): Set got
+ to htab->init_got_offset and plt to htab->init_plt_offset
+ when discarding space for dynamic relocations.
+
+2009-08-03 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-ppc.c (struct plt_entry): Revise comments.
+ (ppc_elf_check_relocs): Don't create needless plt_entry info
+ for non-pie executables. Don't test info->pie when info->shared
+ already covers that case.
+ (ppc_elf_gc_sweep_hook): Adjust for above change.
+ (add_stub_sym): Don't test info->pie when info->shared tested.
+ (allocate_dynrelocs, ppc_elf_size_dynamic_sections): Likewise.
+ (write_glink_stub, ppc_elf_finish_dynamic_symbol): Likewise.
+ (ppc_elf_relax_section): Adjust find_plt_ent arguments.
+ (ppc_elf_relocate_section): Likewise.
+
+2009-08-03 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-ppc.c (ppc_elf_check_relocs): Always add a plt ref count
+ for local ifunc symbols in non-pie executables, regardless of
+ reloc type. Don't specially create ifunc dyn relocs. Tidy ifunc
+ code so that it's obvious that we only do anything special for
+ local ifunc syms.
+ (ppc_elf_gc_sweep_hook): Adjust to suit check_relocs changes.
+ (allocate_dynrelocs): Correct comment for syms defined in plt.
+ Don't specially allocate ifunc dyn relocs.
+ (ppc_elf_relax_section): Relax branches to ifunc plt entries too.
+ (ppc_elf_relocate_section): Set "relocation" value for ifunc
+ syms in non-pie executables. No specially allocated dyn relocs
+ for ifunc to write. Allow for local sym on R_PPC_RELAX32_PLT.
+ (ppc_elf_finish_dynamic_symbol): Set value of ifunc symbols in
+ a non-pie executable.
+
+2009-08-02 H.J. Lu <hongjiu.lu@intel.com>
+ Jakub Jelinek <jakub@redhat.com>
+
+ PR ld/6443
+ * elf32-i386.c (elf_i386_tls_transition): Check executable
+ instead of shared for TLS when building PIE.
+ (elf_i386_check_relocs): Likewise.
+ (elf_i386_allocate_dynrelocs): Likewise.
+ (elf_i386_relocate_section): Likewise.
+
+ * elf64-x86-64.c (elf64_x86_64_tls_transition): Check executable
+ instead of shared for TLS when building PIE.
+ (elf64_x86_64_check_relocs): Likewise.
+ (elf64_x86_64_allocate_dynrelocs): Likewise.
+ (elf64_x86_64_relocate_section): Likewise.
+
+2009-07-31 Anthony Green <green@moxielogic.com>
+
+ * config.bfd (targ_cpu): Add moxie-uclinux support.
+
+2009-07-31 Hans-Peter Nilsson <hp@bitrange.com>
+
+ * linker.c (fix_syms): Consider SEC_LOAD when choosing section.
+
+2009-07-30 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-ppc.c (ppc_elf_check_relocs): Always set up sections
+ used by indirect function support. Count dynamic relocs for
+ ifunc syms.
+ (ppc_elf_adjust_dynamic_symbol): Tweak for ifunc.
+ (allocate_dynrelocs): Allocate all non-dynamic ifunc plt entries
+ in iplt and their relocs in reliplt. Don't make ifunc syms
+ dynamic. Allocate got entry relocs for non-dynamic ifunc in
+ reliplt. Handle other dynamic relocs for ifunc.
+ (ppc_elf_size_dynamic_sections): Alloc dyn relocs for static
+ ifunc in reliplt, likewise relocs for got against local ifunc.
+ Typo fix on reliplt size adjust.
+ (ppc_elf_relocate_section): Don't use plt scheme of allocating
+ relocs 1-1 with entries for iplt, instead just add using
+ reloc_count. Write got relocs and dyn relocs for ifunc to reliplt.
+ Error on invalid ifunc dyn relocs.
+ (ppc_elf_finish_dynamic_symbol): Adjust for non-dynamic ifunc plt
+ in iplt/reliplt.
+ * elf64-ppc.c (ppc64_elf_howto_raw): Add R_PPC64_JMP_IREL,
+ R_PPC64_REL16, R_PPC64_REL16_LO, R_PPC64_REL16_HI, R_PPC64_REL16_HA.
+ (ppc64_elf_reloc_type_lookup): Handle new relocs.
+ (ppc64_elf_check_relocs): Likewise. Count dyn relocs for ifunc.
+ (allocate_dynrelocs): As for elf32-ppc.c above.
+ (ppc64_elf_size_dynamic_sections): Likewise.
+ (ppc_build_one_stub): Put non-dynamic ifunc plt call stubs in iplt,
+ and their relocs in reliplt. Use R_PPC64_JMP_IREL.
+ (ppc_size_one_stub): Similarly.
+ (ppc64_elf_relocate_section): As for elf32-ppc.c above. Handle new
+ relocs too.
+ (ppc64_elf_finish_dynamic_symbol): As for elf32-ppc.c above.
+
+2009-07-29 Hans-Peter Nilsson <hp@bitrange.com>
+
+ * elf64-mmix.c (mmix_elf_relax_section): Revert 2009-05-27
+ change. Add note to head comment.
+
+2009-07-28 Jan Beulich <jbeulich@novell.com>
+
+ * archive.c (get_extended_arelt_filename): Remove redundant
+ range check on index.
+
+2009-07-27 Doug Kwan <dougkwan@google.com>
+
+ * elf32-arm.c (stub_hash_newfunc): Initialize field output_name.
+
+2009-07-27 H.J. Lu <hongjiu.lu@intel.com>
+
+ * archures.c bfd_*_arch): Sorted.
+ (bfd_archures_list): Likewise.
+
+2009-07-27 M R Swami Reddy <MR.Swami.Reddy@nsc.com>
+
+ * elf32-cr16.c (elf_cr16_final_link_relocate): Add code to handle
+ to R_cr16_NUM32 relocation.
+
+2009-07-26 Michael Eager <eager@eagercon.com>
+
+ * archures.c: Add bfd_mach_ppc_405
+ * bfd-in2.h: Same.
+
+2009-07-25 H.J. Lu <hongjiu.lu@intel.com>
+
+ * cpu-i386.c (bfd_x86_64_arch): Fix comment typos.
+ * cpu-l1om.c (bfd_l1om_arch): Likewise.
+
+2009-07-25 H.J. Lu <hongjiu.lu@intel.com>
+
+ * archures.c (bfd_architecture): Add bfd_arch_l1om.
+ (bfd_l1om_arch): New.
+ (bfd_archures_list): Add &bfd_l1om_arch.
+ * bfd-in2.h: Regenerated.
+
+ * config.bfd (targ64_selvecs): Add bfd_elf64_l1om_vec if
+ bfd_elf64_x86_64_vec is supported. Add bfd_elf64_l1om_freebsd_vec
+ if bfd_elf64_x86_64_freebsd_vec is supported.
+ (targ_selvecs): Likewise.
+
+ * configure.in: Support bfd_elf64_l1om_vec and
+ bfd_elf64_l1om_freebsd_vec.
+ * configure: Regenerated.
+
+ * cpu-l1om.c: New.
+
+ * elf64-x86-64.c (elf64_l1om_elf_object_p): New.
+ (bfd_elf64_l1om_vec): Likewise.
+ (bfd_elf64_l1om_freebsd_vec): Likewise.
+
+ * Makefile.am (ALL_MACHINES): Add cpu-l1om.lo.
+ (ALL_MACHINES_CFILES): Add cpu-l1om.c.
+ * Makefile.in: Regenerated.
+
+ * targets.c (bfd_elf64_l1om_vec): New.
+ (bfd_elf64_l1om_freebsd_vec): Likewise.
+ (_bfd_target_vector): Add bfd_elf64_l1om_vec and
+ bfd_elf64_l1om_freebsd_vec.
+
+2009-07-24 Trevor Smigiel <Trevor_Smigiel@playstation.sony.com>
+ Alan Modra <amodra@bigpond.net.au>
+
+ * reloc.c (BFD_RELOC_SPU_ADD_PIC): Define.
+ * bfd-in2.h: Regenerate.
+ * libbfd.h: Regenerate.
+ * elf32-spu.c (elf_howto_table): Add entries SPU_ADD_PIC.
+ (spu_elf_bfd_to_reloc_type): Handle SPU_ADD_PIC.
+ (spu_elf_relocate_section): Patch instructions marked by SPU_ADD_PIC.
+
+2009-07-23 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/10434
+ * elf64-x86-64.c (elf64_x86_64_check_relocs): Check executable
+ instead of shared for R_X86_64_TPOFF32.
+ (elf64_x86_64_relocate_section): Likewise.
+
+2009-07-23 Ulrich Drepper <drepper@redhat.com>
+
+ * elf-bfd.h (struct elf_link_hash_entry): Add unique_global field.
+ * elf.c (swap_out_syms): Set binding to STB_GNU_UNIQUE for symbols
+ with the BSF_GNU_UNIQUE flag bit set.
+ * elfcode.h (elf_slurp_symbol_table): Set the BSF_GNU_UNIQUE flag
+ for symbols with STB_GNU_UNIQUE binding.
+ * elflink.c (_bfd_elf_merge_symbol): Set unique_global for symbols
+ with the STB_GNU_UNIQUE binding.
+ (elf_link_add_object_symbols): Set the BSF_GNU_UNIQUE flag for
+ symbols with STB_GNU_UNIQUE binding. Set STB_GNU_UNIQUE for
+ symbols with the unique_global field set.
+ (elf_link_output_extsym): Set unique_global field for symbols with
+ the STB_GNU_UNIQUE binding.
+ * syms.c (struct bfd_symbol): Define BSF_GNU_UNIQUE flag bit.
+ (bfd_print_symbol_vandf): Print a 'u' character for BSF_GNU_UNIQUE
+ symbols.
+ (bfd_decode_symclass): Return a 'u' character for BSF_GNU_UNIQUE
+ symbols.
+ * bfd-in2.h: Regenerate.
+
+2009-07-22 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elflink.c (elf_link_output_extsym): Revert the last change.
+
+2009-07-22 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/10433
+ * elflink.c (elf_link_output_extsym): Special case ifunc syms
+ when ref_regular, not def_regular.
+
+2009-07-21 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/10426
+ * elflink.c (elf_link_add_object_symbols): Turn an IFUNC symbol
+ from a DSO into a normal FUNC symbol.
+ (elf_link_output_extsym): Turn an undefined IFUNC symbol into
+ a normal FUNC symbol.
+
+2009-07-17 Chao-ying Fu <fu@mips.com>
+
+ * elfxx-mips.c (LOAD_INTERLOCKS_P): New define.
+ (_bfd_mips_elf_size_dynamic_sections): For CPUs without load
+ interlocking, the last PLT entry needs a nop in the branch delay slot.
+ (_bfd_mips_elf_finish_dynamic_symbol): For CPUs with load itnerlocking,
+ output the last two PLT entries in reverse order.
+
+2009-07-16 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf32-i386.c (elf_i386_relocate_section): Don't get local
+ STT_GNU_IFUNC symbol for relocatable link.
+ * elf64-x86-64.c (elf64_x86_64_relocate_section): Likewise.
+
+2009-07-10 H.J. Lu <hongjiu.lu@intel.com>
+
+ * bfdio.c (bfd_iovec): Add comments for bmmap.
+ * bfd-in2.h: Regenerated.
+
+2009-07-10 H.J. Lu <hongjiu.lu@intel.com>
+
+ * Makefile.am: Run "make dep-am".
+ * Makefile.in: Regenerated.
+
+2009-07-10 Doug Kwan <dougkwan@google.com>
+
+ * elf32-arm.c (stub_hash_newfunc): Initialize fields
+ target_addend and orig_insn.
+
+2009-07-10 Tom Tromey <tromey@redhat.com>
+
+ * Makefile.am (dwarf2.lo): Use dwarf2.h, not elf/dwarf2.h.
+ (elf-eh-frame.lo): Likewise.
+ (elf32-bfin.lo): Likewise.
+ (elf32-frv.lo): Likewise.
+ (elf32-xc16x.lo): Likewise.
+ * Makefile.in: Rebuild.
+ * dwarf2.c: Included dwarf.h, not elf/dwarf2.h.
+ * elf-eh-frame.c: Likewise.
+ * elf32-bfin.c: Likewise.
+ * elf32-frv.c: Likewise.
+ * elf32-xc16x.c: Likewise.
+
+2009-07-10 Julian Brown <julian@codesourcery.com>
+
+ * elf32-arm.c (arm_build_one_stub): Use the hash entry of the
+ symbol a stub entry is derived from, not the entry for the stub
+ itself, in call to elf32_arm_final_link_relocate.
+
+2009-07-10 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf.c (_bfd_elf_get_synthetic_symtab): Remove leading zeros
+ when reporting addends.
+
+2009-07-10 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-spu.c (spu_elf_size_stubs): Do set up soft-icache manager
+ data even when no stubs.
+ (spu_elf_place_overlay_data, spu_elf_build_stubs): Adjust.
+
+2009-07-10 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-ppc.c (ppc_elf_howto_raw): Add R_PPC_IRELATIVE.
+ (ppc_elf_get_synthetic_symtab): Report addend.
+ (PLT_IFUNC): Define.
+ (struct ppc_elf_link_hash_table): Add iplt and reliplt.
+ (ppc_elf_create_glink): New function.
+ (ppc_elf_create_dynamic_sections): Use it.
+ (ppc_elf_add_symbol_hook): Set has_ifunc_symbols.
+ (update_local_sym_info): Allocate space for local_plt array.
+ Don't bump local_got_refcounts for PLT_IFUNC. Return local_plt
+ entry pointer.
+ (is_branch_reloc): New function.
+ (ppc_elf_check_relocs): Handle STT_GNU_IFUNC symbols.
+ (ppc_elf_gc_sweep_hook): Likewise.
+ (ppc_elf_adjust_dynamic_symbol): Likewise.
+ (allocate_dynrelocs): Likewise.
+ (ppc_elf_size_dynamic_sections): Likewise.
+ (ppc_elf_relocate_section): Likewise.
+ (branch_reloc_hash_match): Use is_branch_reloc.
+ (ppc_elf_tls_optimize): Adjust for local_plt.
+ (write_glink_stub): New function, extracted from..
+ (ppc_elf_finish_dynamic_symbol): ..here. Handle STT_GNU_IFUNC.
+ (ppc_elf_finish_dynamic_sections): Only write plt resolver and
+ branch table when dynamic.
+ (elf_backend_post_process_headers): Define.
+ * elf64-ppc.c (elf_backend_post_process_headers): Define.
+ (ppc64_elf_howto_raw): Add R_PPC64_IRELATIVE.
+ (ppc64_elf_get_synthetic_symtab): Report addend.
+ (struct ppc_stub_hash_entry): Add plt_ent.
+ (PLT_IFUNC): Define.
+ (struct ppc_link_hash_table): Add iplt and reliplt.
+ (create_linkage_sections): Make .iplt and .rela.iplt sections.
+ (ppc64_elf_add_symbol_hook): Set has_ifunc_symbols.
+ (update_local_sym_info): Allocate space for local_plt array.
+ Don't bump local_got_ents for PLT_IFUNC. Return local_plt
+ entry pointer.
+ (update_plt_info): Pass pointer to plt_entry rather than sym hash,
+ and don't change hash flags here.
+ (is_branch_reloc): New function.
+ (ppc64_elf_check_relocs): Handle STT_GNU_IFUNC.
+ (ppc64_elf_gc_sweep_hook): Likewise.
+ (ppc64_elf_adjust_dynamic_symbol): Likewise.
+ (allocate_dynrelocs): Likewise.
+ (ppc64_elf_size_dynamic_sections): Likewise.
+ (ppc_build_one_stub, ppc_size_one_stub): Likewise.
+ (ppc64_elf_size_stubs): Likewise.
+ (ppc64_elf_relocate_section): Likewise.
+ (get_sym_h): Adjust for local_plt.
+ (branch_reloc_hash_match): Use is_branch_reloc.
+ (ppc_type_of_stub): Pass plt_entry pointer and handle ifunc.
+ (ppc64_elf_toc): Ignore SEC_EXCLUDE sections.
+
+2009-07-10 Alan Modra <amodra@bigpond.net.au>
+
+ * elf.c (_bfd_elf_get_synthetic_symtab): Report addends.
+
+2009-07-10 Alan Modra <amodra@bigpond.net.au>
+
+ * elf-bfd.h (struct elf_link_hash_entry): Clarify ref_regular
+ and ref_regular_nonweak comment.
+ * elflink.c (elf_link_output_extsym): Special case ifunc syms
+ when def_regular, not ref_regular.
+ (elf_link_add_object_symbols): Don't set needs_plt on ifunc syms,..
+ * elf32-i386.c (elf_i386_check_relocs): ..set it here instead..
+ * elf64-x86-64.c (elf64_x86_64_check_relocs): ..and here.
+
+2009-07-09 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-spu.c (mark_functions_via_relocs): Init broken_cycle field
+ of malloc'd struct call_info.
+ (pasted_function): Likewise, priority too.
+
+2009-07-07 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-spu.c (spu_elf_auto_overlay): Take into account section
+ alignment when packing sections into overlays.
+
+2009-07-03 Cary Coutant <ccoutant@google.com>
+
+ * dwarf2.c (decode_line_info): Ignore DW_LNE_set_discriminator.
+
+2009-07-03 Dave Korn <dave.korn.cygwin@gmail.com>
+
+ * coffcode.h (sec_to_styp_flags): Partially revert (functional
+ changes only) earlier patch:-
+
+2009-06-25 Kai Tietz <kai.tietz@onevision.com>
+
+ * coffcode.h (sec_to_styp_flags): Set discardable for .reloc and
+ give .debug and .reloc data characteristics.
+ (DOT_RELOC): New define for .reloc section string.
+ (coff_write_object_contents): Use DOT_RELOC instead of string.
+
+2009-07-02 Tom Tromey <tromey@redhat.com>
+
+ * aoutx.h (aout_get_external_symbols): Declare 'amt' locally.
+ * bfdwin.c (bfd_free_window): Cast to unsigned long.
+
+2009-07-01 Nick Clifton <nickc@redhat.com>
+
+ * elf-m10300.c: Remove trailing white space.
+ * reloc.c: Likewise.
+
+2009-07-01 Douglas B Rupp <rupp@gnat.com>
+
+ * bfd.m4 (BFD_HAVE_TIME_TYPE_MEMBER,
+ BFD_HAVE_SYS_STAT_TYPE_MEMBER): New config functions.
+ * configure.in: Use them.
+ * configure: Regenerate.
+ * config.in: Regenerate.
+ * vmsutil.c: Include sysdep.h, remove ansidecl.h.
+ #define _BSD_SOURCE. Add comments.
+ (vms_file_stats_name): Calculate creation date based on available
+ runtime data. Return 1 for version instead of 0.
+
+2009-07-01 Nick Clifton <nickc@redhat.com>
+
+ PR 10072
+ * elf32-arm.c (elf32_arm_final_link_relocate): Add code to handle
+ to R_ARM_THM_PC8 relocation.
+
+2009-06-29 Nick Clifton <nickc@redhat.com>
+
+ * elf-m10300.c (mn10300_elf_relax_section): Allow for the
+ different uses of the relocations addend when a symbol is in a
+ merged section.
+
+2009-06-27 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/10337
+ * elf.c (bfd_section_from_shdr): Don't change sh_link for
+ SHT_REL/SHT_RELA sections on executable nor shared library.
+ Treat SHT_REL/SHT_RELA sections with sh_link set to SHN_UNDEF
+ as a normal section.
+
+2009-06-25 Nick Clifton <nickc@redhat.com>
+
+ * elf-m10300.c (mn10300_elf_relax_section): Handle non-section
+ symbols with SEC_MERGE flag.
+
+2009-06-25 Kai Tietz <kai.tietz@onevision.com>
+
+ * coffcode.h (sec_to_styp_flags): Set discardable for .reloc and
+ give .debug and .reloc data characteristics.
+ (DOT_RELOC): New define for .reloc section string.
+ (coff_write_object_contents): Use DOT_RELOC instead of string.
+
+2009-06-25 Tristan Gingold <gingold@adacore.com>
+
+ * mach-o-target.c (bfd_mach_o_get_dynamic_symtab_upper_bound)
+ (bfd_mach_o_canonicalize_dynamic_symtab)
+ (bfd_mach_o_get_synthetic_symtab): Defines.
+ (TARGET_NAME_BACKEND): Add bfd_mach_o_print_thread entry.
+ (TARGET_NAME): Use Mach-O specific functions for dynamic.
+
+ * mach-o-i386.c (bfd_mach_o_i386_swap_reloc_in): Fix howto indexes
+ for scattered relocations.
+ (bfd_mach_o_i386_print_thread): New function.
+ (bfd_mach_o_print_thread): Define.
+
+ * mach-o.c (text_section_names_xlat): Add an entry for __const.
+ (bfd_mach_o_canonicalize_one_reloc, bfd_mach_o_canonicalize_relocs):
+ New functions extracted from ...
+ (bfd_mach_o_canonicalize_reloc): ... This. Simplified.
+ (bfd_mach_o_get_dynamic_reloc_upper_bound): New function.
+ (bfd_mach_o_canonicalize_dynamic_reloc): New function.
+ (bfd_mach_o_i386_flavour_string): Adjusted after enum renaming.
+ (bfd_mach_o_ppc_flavour_string): Reindentation. Add 64 bits cases.
+ (bfd_mach_o_scan_read_dylinker): Do not create a section anymore.
+ Set name_str field.
+ (bfd_mach_o_scan_read_dylib): Ditto.
+ (bfd_mach_o_scan_read_thread): Set mdata at declaration. Add comments,
+ reindent.
+ (bfd_mach_o_scan_read_dysymtab): Set mdata at declaration. Correctly
+ decode isym and flags on little endian targets. Set dysymtab field.
+ (bfd_mach_o_scan_start_address): Adjust for enum names.
+ (bfd_mach_o_lookup_section): Do not look for segments anymore.
+ (bfd_mach_o_print_section): Display bfd section name.
+ (bfd_mach_o_print_segment): Display none if no name.
+ (bfd_mach_o_print_dysymtab): Display next index for local, external
+ and undefined symbols.
+ (bfd_mach_o_bfd_print_private_bfd_data): Adjust code by using name_str.
+ Display dylinker name. Display thread and unixthread commands content.
+ (bfd_mach_o_print_thread): New macro.
+
+ * mach-o.h (bfd_mach_o_mach_header_magic): Align numbers.
+ (bfd_mach_o_ppc_thread_flavour): Ditto.
+ (bfd_mach_o_i386_thread_flavour): Ditto.
+ (BFD_MACH_O_PPC_THREAD_STATE_NONE): New enum.
+ (BFD_MACH_O_x86_THREAD_STATE_NONE): Replaces
+ BFD_MACH_O_THREAD_STATE_NONE.
+ (bfd_mach_o_segment_command): Remove segment field.
+ (bfd_mach_o_thread_flavour): Field offset is now unsigned long.
+ (bfd_mach_o_dylinker_command): Remove section field, add name_str.
+ (bfd_mach_o_prebound_dylib_command): Ditto.
+ (bfd_mach_o_dylib_command): Ditto.
+ (bfd_mach_o_prebound_dylib_command): Remove section field.
+ (mach_o_data_struct): Add dysymtab field.
+ (bfd_mach_o_backend_data): Add _bfd_mach_o_print_thread field.
+ (bfd_mach_o_get_reloc_upper_bound, bfd_mach_o_canonicalize_reloc)
+ (bfd_mach_o_build_commands): Remove parameter names and attributes.
+ (bfd_mach_o_get_dynamic_reloc_upper_bound)
+ (bfd_mach_o_canonicalize_dynamic_reloc): New prototypes.
+
+2009-06-25 Rafael Avila de Espindola <espindola@google.com>
+
+ * plugin.c (load_plugin): Use stat and S_ISREG instead of the d_type
+ field of struct dirent.
+
+2009-06-23 Tristan Gingold <gingold@adacore.com>
+
+ * vms.c (vms_get_synthetic_symtab): Remove duplicate definition
+ of this macro. Fix indentation.
+
+2009-06-22 Christophe Lyon <christophe.lyon@st.com>
+
+ * elf32-arm.c (elf32_arm_size_stubs): Use PLT address as
+ destination for defined dynamic symbols when deciding whether to
+ insert a stub or not.
+ (allocate_dynrelocs): Make sure functions are not marked as Thumb
+ when actually accessed through a PLT, even when generating a
+ shared lib.
+
+2009-06-22 Tristan Gingold <gingold@adacore.com>
+
+ * mach-o.c (bfd_mach_o_canonicalize_reloc): Append a sentinel to
+ the relocs array.
+
+2009-06-22 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-ppc.c (ppc_elf_check_relocs): Handle R_PPC_RELAX* in switch.
+ * elf32-v850.c (v850_elf_relocate_section): Warning fix.
+
+2009-06-22 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (ppc64_elf_edit_opd): Avoid gcc warning.
+
+2009-06-19 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elflink.c (elf_link_add_object_symbols): Avoid warning
+ from -Wjump-misses-init in gcc 4.5.0.
+
+2009-06-19 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf32-i386.c (elf_i386_check_relocs): Properly check local
+ symbol on error.
+ * elf64-x86-64.c (elf64_x86_64_check_relocs): Likewise.
+
+2009-06-19 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf32-i386.c (elf_i386_tls_transition): Add a parameter,
+ r_symndx. Report local symbol name on error.
+ (elf_i386_check_relocs): Updated. Report local symbol name on
+ error.
+ (elf_i386_gc_sweep_hook): Updated.
+ (elf_i386_relocate_section): Likewise.
+
+ * elf64-x86-64.c (elf64_x86_64_tls_transition): Add a parameter,
+ r_symndx. Report local symbol name on error.
+ (elf64_x86_64_check_relocs): Updated. Report local symbol name
+ on error.
+ (elf64_x86_64_gc_sweep_hook): Updated.
+ (elf64_x86_64_relocate_section): Likewise.
+
+2009-06-19 Tristan Gingold <gingold@adacore.com>
+
+ * mach-o.c (bfd_mach_o_print_private_header): Fix format character.
+
+2009-06-19 Tristan Gingold <gingold@adacore.com>
+
+ * mach-o.c (bfd_mach_o_scan_read_symtab_symbols): Add prototype.
+ (bfd_mach_o_version): Use bfd_mach_o_get_data instead of direct access.
+ (bfd_mach_o_valid): Ditto.
+ (bfd_mach_o_wide_p): Ditto.
+ (bfd_mach_o_canonicalize_reloc): Ditto.
+ (bfd_mach_o_build_commands): Ditto.
+ (bfd_mach_o_scan_read_thread): Ditto.
+ (bfd_mach_o_flatten_sections): Ditto.
+ (bfd_mach_o_scan_start_address): Ditto.
+ (bfd_mach_o_lookup_section): Ditto.
+ (bfd_mach_o_core_fetch_environment): Ditto.
+ (bfd_mach_o_write_contents): Ditto. Handle reexport_dylib.
+ (bfd_mach_o_scan_write_relocs): Adjust for bfd_mach_o_get_data.
+ (bfd_mach_o_scan_write_symtab): Ditto.
+ Use macros instead of hard-coded values.
+ (bfd_mach_o_scan_read_symtab_symbol): Make the function static.
+ Use bfd_mach_o_get_data instead of direct access. Use macros
+ instead of hard-coded values.
+ (bfd_mach_o_scan_read_symtab_strtab): Make the function static.
+ Remove sym argument and get section from mdata.
+ Move code into the else branch.
+ (bfd_mach_o_scan_read_symtab_symbols): Make the function static.
+ Remove sym argument and get section from mdata. Adjust code.
+ (bfd_mach_o_scan_read_dylib): Move assertion into the created
+ switch (which replaces consecutive if statements).
+ (bfd_mach_o_scan_read_dysymtab): Rename seg to cmd. Load
+ module table, table of content, indirect symbols and external
+ referenced symbols.
+ (bfd_mach_o_scan_read_symtab): Renames seg to symtab. Set symtab
+ field.
+ (bfd_mach_o_scan_read_linkedit): New function.
+ (bfd_mach_o_scan_read_str): Ditto.
+ (bfd_mach_o_count_symbols): Simplify the code by using the symtab
+ field of mdata.
+ (bfd_mach_o_get_symtab_upper_bound): Remove check as
+ bfd_mach_o_count_symbols never returns an error.
+ (bfd_mach_o_canonicalize_symtab): Simplify the code by using the
+ symtab field (there might be only one symtab).
+ (bfd_mach_o_scan_read_command): Handle reexported dylib.
+ Handle sub frameworks, sub umbrella, sub library and sub client.
+ Read code signature and segment split info commands.
+ (bfd_mach_o_scan): Reindent.
+ (bfd_mach_o_xlat_name): New type.
+ (bfd_mach_o_print_flags): New function.
+ (bfd_mach_o_get_name): Ditto.
+ (bfd_mach_o_cpu_name): New variable.
+ (bfd_mach_o_filetype_name, bfd_mach_o_header_flags_name)
+ (bfd_mach_o_section_type_name)
+ (bfd_mach_o_section_attribute_name)
+ (bfd_mach_o_load_command_name): New variables.
+ (bfd_mach_o_print_private_header): New function.
+ (bfd_mach_o_print_section_map): New function extracted from
+ bfd_mach_o_print_private_bfd_data.
+ (bfd_mach_o_print_section): Ditto. Print more infos.
+ (bfd_mach_o_print_segment): Ditto.
+ (bfd_mach_o_print_dysymtab): Ditto.
+ (bfd_mach_o_bfd_print_private_bfd_data): Reworked. Handle
+ load weak dylib, reexport dylib and id dylib.
+ Handle code signature and segment_split info.
+ Handle sub frameworks, sub umbrella, sub library and sub client.
+ (bfd_mach_o_section_get_nbr_indirect): New function.
+
+ * mach-o.h (BFD_MACH_O_REFERENCE_MASK): New macro. Add comment.
+ (bfd_mach_o_header_flags): New enum to define header flags.
+ (bfd_mach_o_section_attribute): New enum to replace ...
+ (BFD_MACH_O_S_ATTR_LOC_RELOC, BFD_MACH_O_S_ATTR_EXT_RELOC,
+ BFD_MACH_O_S_ATTR_SOME_INSTRUCTIONS, BFD_MACH_O_S_ATTR_DEBUG,
+ BFD_MACH_O_S_SELF_MODIFYING_CODE, BFD_MACH_O_S_ATTR_LIVE_SUPPORT,
+ BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, BFD_MACH_O_S_ATTR_STRIP_STATIC_SYMS,
+ BFD_MACH_O_S_ATTR_NO_TOC, BFD_MACH_O_S_ATTR_PURE_INSTRUCTIONS): ...
+ these removed macros.
+ (BFD_MACH_O_NLIST_SIZE, BFD_MACH_O_NLIST_64_SIZE): New macros.
+ (bfd_mach_o_dylib_module): New type.
+ (BFD_MACH_O_DYLIB_MODULE_SIZE, BFD_MACH_O_DYLIB_MODULE_64_SIZE): New
+ macros.
+ (bfd_mach_o_dylib_table_of_content): New type.
+ (BFD_MACH_O_TABLE_OF_CONTENT_SIZE): New macro.
+ (bfd_mach_o_dylib_reference): New type.
+ (BFD_MACH_O_REFERENCE_SIZE): New macro.
+ (bfd_mach_o_dysymtab_command): Add fields for loaded and decoded
+ modules, toc, references and indirect syms.
+ (BFD_MACH_O_INDIRECT_SYMBOL_SIZE): New macro.
+ (bfd_mach_o_dylinker_command): Remove cmd and cmdsize fields (were
+ unused). Add comment.
+ (bfd_mach_o_dylib_command): Ditto.
+ (bfd_mach_o_prebound_dylib_command): Ditto.
+ (bfd_mach_o_linkedit_command): New type.
+ (bfd_mach_o_str_command): New type.
+ (bfd_mach_o_load_command): Add linkedit and str fields.
+ (mach_o_data_struct): Add symtab field.
+ (bfd_get_mach_o_data): Renamed to ...
+ (bfd_mach_o_get_data): ... this new macro.
+ (bfd_mach_o_scan_read_symtab_symbol,
+ bfd_mach_o_scan_read_symtab_strtab,
+ bfd_mach_o_scan_read_symtab_symbols): Prototypes removed.
+
+ * mach-o-i386.c (bfd_mach_o_i386_mkobject): Use bfd_mach_o_get_data
+ instead of direct access.
+
+2009-06-19 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-ppc.c (ppc_elf_check_relocs): Allow local symbols for
+ R_PPC_PLTREL24 relocs.
+ (ppc_elf_relocate_section): Likewise.
+
+2009-06-19 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-ppc.c (find_plt_ent): Pass pointer to plist rather than
+ pointer to sym hash. Update all uses.
+ (update_plt_info): Likewise. Don't check addend here.
+
+2009-06-18 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf32-i386.c (elf_i386_check_relocs): Remove isymbuf and use
+ bfd_sym_from_r_symndx.
+ * elf64-x86-64.c (elf64_x86_64_check_relocs): Likewise.
+
+2009-06-18 Alan Modra <amodra@bigpond.net.au>
+
+ * elf-bfd.h (struct sym_sec_cache): Delete.
+ (struct sym_cache): New.
+ (bfd_section_from_r_symndx): Delete prototype.
+ (bfd_sym_from_r_symndx): Define prototype.
+ * elf.c (bfd_section_from_r_symndx): Delete, replace with..
+ (bfd_sym_from_r_symndx): ..new function.
+ * elf32-arm.c: Update all uses of struct sym_sec_cache and
+ bfd_section_from_r_symndx to new struct and function.
+ * elf32-bfin.c: Likewise.
+ * elf32-hppa.c: Likewise.
+ * elf32-i386.c: Likewise.
+ * elf32-m32r.c: Likewise.
+ * elf32-m68hc1x.c: Likewise.
+ * elf32-m68hc1x.h: Likewise.
+ * elf32-m68k.c: Likewise.
+ * elf32-ppc.c: Likewise.
+ * elf32-s390.c: Likewise.
+ * elf32-sh.c: Likewise.
+ * elf64-ppc.c: Likewise.
+ * elf64-s390.c: Likewise.
+ * elf64-x86-64.c: Likewise.
+ * elfxx-sparc.c: Likewise.
+ * elfxx-sparc.h: Likewise.
+
+2009-06-18 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf32-i386.c (elf_i386_check_relocs): Cache or free isymbuf.
+ * elf64-x86-64.c (elf64_x86_64_check_relocs): Likewise.
+
+2009-06-18 Nick Clifton <nickc@redhat.com>
+
+ * elflink.c (elf_link_sort_relocs): Return early if there are no
+ relocs to sort.
+
+2009-06-18 Dave Korn <dave.korn.cygwin@gmail.com>
+
+ Merge cegcc and mingw32ce target name changes from
+ CeGCC project:
+
+ 2007-12-25 Pedro Alves <pedro_alves@portugalmail.pt>
+
+ * config.bfd: Add arm*-*-cegcc* target.
+
+ 2007-12-17 Pedro Alves <pedro_alves@portugalmail.pt>
+
+ * config.bfd: Add arm-*-mingw32ce* target.
+
+2009-06-17 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf-bfd.h (_bfd_elf_allocate_ifunc_dyn_relocs): New.
+ * elf-ifunc.c (_bfd_elf_allocate_ifunc_dyn_relocs): Likewise.
+ * elf32-i386.c (elf_i386_allocate_dynrelocs): Use it.
+ * elf64-x86-64.c (elf64_x86_64_allocate_dynrelocs): Likewise.
+
+2009-06-17 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf-bfd.h (_bfd_elf_create_ifunc_dyn_reloc): New.
+ * elf-ifunc.c (_bfd_elf_create_ifunc_dyn_reloc): Likewise.
+ * elf32-i386.c (elf_i386_check_relocs): Use it.
+ * elf64-x86-64.c (elf64_x86_64_check_relocs): Likewise.
+
+2009-06-17 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf-bfd.h (elf_dyn_relocs): New.
+
+ * elf32-i386.c (elf_i386_dyn_relocs): Removed.
+ (elf_i386_link_hash_entry): Replace elf_i386_dyn_relocs with
+ elf_dyn_relocs.
+ (elf_i386_copy_indirect_symbol): Likewise.
+ (elf_i386_check_relocs): Likewise.
+ (elf_i386_gc_sweep_hook): Likewise.
+ (elf_i386_allocate_dynrelocs): Likewise.
+ (elf_i386_readonly_dynrelocs): Likewise.
+ (elf_i386_size_dynamic_sections): Likewise.
+
+ * elf64-x86-64.c (elf64_x86_64_dyn_relocs): Removed.
+ (elf64_x86_64_link_hash_entry): Replace elf64_x86_64_dyn_relocs
+ with elf_dyn_relocs.
+ (elf64_x86_64_copy_indirect_symbol): Updated.
+ (elf64_x86_64_check_relocs): Likewise.
+ (elf64_x86_64_gc_sweep_hook): Likewise.
+ (elf64_x86_64_adjust_dynamic_symbol): Likewise.
+ (elf64_x86_64_allocate_dynrelocs): Likewise.
+ (elf64_x86_64_readonly_dynrelocs): Likewise.
+ (elf64_x86_64_size_dynamic_sections): Likewise.
+
+2009-06-17 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf32-arm.c (create_got_section): Get existing .rela.got
+ section.
+ * elf32-hppa.c (elf32_hppa_create_dynamic_sections): Likewise.
+ * elf32-lm32.c (create_got_section): Likewise.
+ * elf32-m32r.c (create_got_section): Likewise.
+ * elf32-ppc.c (ppc_elf_create_got): Likewise.
+ * elf32-s390.c (create_got_section): Likewise.
+ * elf32-sh.c (create_got_section): Likewise.
+ * elf32-xtensa.c (elf_xtensa_create_dynamic_sections): Likewise.
+ * elf64-s390.c (create_got_section): Likewise.
+ * elfxx-sparc.c (create_got_section): Likewise.
+
+ * elflink.c (_bfd_elf_create_got_section): Properly initialize
+ the GOT size.
+
+2009-06-16 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf-bfd.h (ELF_LOCAL_SYMBOL_HASH): New.
+
+ * elf32-i386.c (elf_i386_local_hash): Removed.
+ (elf_i386_local_htab_hash): Use ELF_LOCAL_SYMBOL_HASH.
+ (elf_i386_get_local_sym_hash): Likewise.
+
+ * elf64-x86-64.c (elf64_x86_64_local_hash): Removed.
+ (elf64_x86_64_local_htab_hash): Use ELF_LOCAL_SYMBOL_HASH.
+ (elf64_x86_64_get_local_sym_hash): Likewise.
+ * elfxx-ia64.c (elfNN_ia64_local_htab_hash): Likewise.
+ (get_local_sym_hash): Likewise.
+
+2009-06-16 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elfxx-ia64.c (elfNN_ia64_link_hash_table): Remove got_sec,
+ rel_got_sec and plt_sec.
+ (elfNN_ia64_relax_section): Updated.
+ (elfNN_ia64_create_dynamic_sections): Likewise.
+ (get_got): Likewise.
+ (allocate_dynrel_entries): Likewise.
+ (elfNN_ia64_size_dynamic_sections): Likewise.
+ (set_got_entry): Likewise.
+ (elfNN_ia64_choose_gp): Likewise.
+ (elfNN_ia64_relocate_section): Likewise.
+ (elfNN_ia64_finish_dynamic_symbol): Likewise.
+ (elfNN_ia64_finish_dynamic_sections): Likewise.
+
+2009-06-16 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * elf32-spu.c (needs_ovl_stub): Respect .brinfo lrlive bits
+ also for calls.
+
+2009-06-16 H.J. Lu <hongjiu.lu@intel.com>
+
+ * configure.in (elf): Add elf-ifunc.lo.
+
+ * configure: Regenerated.
+ * Makefile.in: Likewise.
+
+ * elf-bfd.h (elf_link_hash_table): Add sgot, sgotplt,
+ srelgot, splt, srelplt, igotplt, iplt, irelplt and irelifunc.
+
+ * elf32-i386.c (elf_i386_link_hash_table): Remove sgot,
+ sgotplt, srelgot, splt, srelplt, igotplt, iplt, irelplt and
+ irelifunc.
+ (elf_i386_link_hash_table_create): Likewise.
+ (elf_i386_create_dynamic_sections): Likewise.
+ (elf_i386_check_relocs): Likewise.
+ (elf_i386_allocate_dynrelocs): Likewise.
+ (elf_i386_size_dynamic_sections): Likewise.
+ (elf_i386_relocate_section): Likewise.
+ (elf_i386_finish_dynamic_symbol): Likewise.
+ (elf_i386_finish_dynamic_sections): Likewise.
+ (elf_i386_create_got_section): Removed.
+
+ * elf64-x86-64.c (elf64_x86_64_link_hash_table): Remove sgot,
+ sgotplt, srelgot, splt, srelplt, igotplt, iplt, irelplt and
+ irelifunc.
+ (elf64_x86_64_compute_jump_table_size): Updated.
+ (elf64_x86_64_link_hash_table_create): Likewise.
+ (elf64_x86_64_create_dynamic_sections): Likewise.
+ (elf64_x86_64_check_relocs): Likewise.
+ (elf64_x86_64_allocate_dynrelocs): Likewise.
+ (elf64_x86_64_size_dynamic_sections): Likewise.
+ (elf64_x86_64_relocate_section): Likewise.
+ (elf64_x86_64_finish_dynamic_symbol): Likewise.
+ (elf64_x86_64_finish_dynamic_sections): Likewise.
+ (elf64_x86_64_create_got_section): Removed.
+
+ * elflink.c (_bfd_elf_create_got_section): Use log_file_align
+ for pointer alignment. Set up section pointers.
+ (_bfd_elf_create_dynamic_sections): Likewise.
+ (_bfd_elf_create_ifunc_sections): Moved to ...
+ * elf-ifunc.c: Here. New.
+
+ * Makefile.am (BFD32_BACKENDS): Add elf-ifunc.lo.
+ (BFD32_BACKENDS_CFILES): Add elf-ifunc.c.
+ Run "make dep-am".
+
+2009-06-16 Doug Kwan <dougkwan@google.com>
+
+ * elf32-arm.c (cortex_a8_erratum_scan): Change type of offset
+ to bfd_signed_vma. Cast constant operands which are used in
+ offset related expressions to bfd_signed_vma type as appropriate.
+
+2009-06-16 Maciej W. Rozycki <macro@linux-mips.org>
+
+ * elf32-vax.c (elf_vax_plt_sym_val): New function.
+ (elf_backend_plt_sym_val): Define.
+
+2009-06-16 Maciej W. Rozycki <macro@linux-mips.org>
+
+ * elf32-vax.c (elf_vax_reloc_type_class): New function.
+ (elf_backend_reloc_type_class): Define.
+
+2009-06-16 Maciej W. Rozycki <macro@linux-mips.org>
+
+ * elf32-vax.c (elf_vax_relocate_section): For symbol references
+ from an executable to a shared library treat R_VAX_PC32
+ relocations as R_VAX_PLT32 ones.
+
+2009-06-16 Maciej W. Rozycki <macro@linux-mips.org>
+
+ * elf32-vax.c (elf_vax_instantiate_got_entries): Skip local
+ symbols in GOT space calculation.
+ (elf_vax_relocate_section): Adjust accordingly.
+
+2009-06-16 Maciej W. Rozycki <macro@linux-mips.org>
+
+ * elf32-vax.c (elf_vax_plt_entry): Set the entry mask to
+ include <R11:R2>.
+
+2009-06-16 Maciej W. Rozycki <macro@linux-mips.org>
+
+ * elf32-vax.c (elf_vax_check_relocs): Handle the visibility
+ attribute.
+ (elf_vax_relocate_section): Likewise.
+
+2009-06-15 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf32-i386.c (elf_i386_allocate_dynrelocs): Update comments.
+ * elf64-x86-64.c (elf64_x86_64_allocate_dynrelocs): Likewise.
+
+2009-06-15 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf32-i386.c (elf_i386_check_relocs): Reformat.
+ * elf64-x86-64.c (elf64_x86_64_check_relocs): Likewise.
+
+2009-06-15 H.J. Lu <hongjiu.lu@intel.com>
+
+ * Makefile.am: Run "make dep-am".
+ * Makefile.in: Regenerated.
+
+2009-06-15 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf32-i386.c (elf_i386_allocate_dynrelocs): Fix a typo.
+ * elf64-x86-64.c (elf64_x86_64_allocate_dynrelocs): Likewise.
+
+2009-06-15 Nick Clifton <nickc@redhat.com>
+
+ * po/ru.po: New Russian translation.
+ * configure.in (ALL_LINGUAS): Add ru.
+ * configure: Regenerate.
+
+2009-06-14 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf32-i386.c: Remove duplicated comments.
+
+2009-06-14 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/10270
+ * elf32-i386.c (elf_i386_allocate_dynrelocs): Disallow
+ dynamic IFUNC pointer in non-shared object. Use .got.plt
+ for IFUNC definition in PIE.
+ (elf_i386_allocate_dynrelocs): Resolve IFUNC definition in
+ PIE locally.
+
+ * elf64-x86-64.c (elf64_x86_64_allocate_dynrelocs): Disallow
+ dynamic IFUNC pointer in non-shared object. Use .got.plt
+ for IFUNC definition in PIE.
+ (elf64_x86_64_relocate_section): Resolve IFUNC definition in
+ PIE locally.
+
+2009-06-13 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf32-i386.c (elf_i386_check_relocs): Properly report
+ local symbol for unhandled relocation against STT_GNU_IFUNC
+ symbol.
+ (elf_i386_relocate_section): Likewise.
+ * elf64-x86-64.c (elf64_x86_64_check_relocs): Likewise.
+ (elf64_x86_64_relocate_section): Likewise.
+
+2009-06-13 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/10269
+ * elf32-i386.c: Include "objalloc.h" and "hashtab.h".
+ (elf_i386_link_hash_table): Add loc_hash_table and
+ loc_hash_memory.
+ (elf_i386_local_hash): New.
+ (elf_i386_local_htab_hash): Likewise.
+ (elf_i386_local_htab_eq): Likewise.
+ (elf_i386_get_local_sym_hash): Likewise.
+ (elf_i386_link_hash_table_free): Likewise.
+ (elf_i386_allocate_local_dynrelocs): Likewise.
+ (elf_i386_finish_local_dynamic_symbol): Likewise.
+ (bfd_elf64_bfd_link_hash_table_free): Likewise.
+ (elf_i386_link_hash_table_create): Create loc_hash_table and
+ loc_hash_memory.
+ (elf_i386_check_relocs): Handle local STT_GNU_IFUNC symbols.
+ (elf_i386_size_dynamic_sections): Likewise.
+ (elf_i386_relocate_section): Likewise.
+ (elf_i386_finish_dynamic_sections): Likewise.
+ (elf_i386_finish_dynamic_symbol): Check _DYNAMIC only if sym
+ isn't NULL.
+
+ * elf64-x86-64.c: Include "objalloc.h" and "hashtab.h".
+ (elf64_x86_64_link_hash_table): Add loc_hash_table and
+ loc_hash_memory.
+ (elf64_x86_64_local_hash): New.
+ (elf64_x86_64_local_htab_hash): Likewise.
+ (elf64_x86_64_local_htab_eq): Likewise.
+ (elf64_x86_64_get_local_sym_hash): Likewise.
+ (elf64_x86_64_link_hash_table_free): Likewise.
+ (elf64_x86_64_allocate_local_dynrelocs): Likewise.
+ (elf64_x86_64_finish_local_dynamic_symbol): Likewise.
+ (bfd_elf64_bfd_link_hash_table_free): Likewise.
+ (elf64_x86_64_link_hash_table_create): Create loc_hash_table
+ and loc_hash_memory.
+ (elf64_x86_64_check_relocs): Handle local STT_GNU_IFUNC
+ symbols.
+ (elf64_x86_64_size_dynamic_sections): Likewise.
+ (elf64_x86_64_relocate_section): Likewise.
+ (elf64_x86_64_finish_dynamic_sections): Likewise.
+ (elf64_x86_64_finish_dynamic_symbol): Check _DYNAMIC only if
+ sym isn't NULL.
+
+2009-06-10 Philip Blundell <philb@gnu.org>
+
+ * elf32-arm.c (elf32_arm_fix_exidx_coverage): Avoid crash if
+ elf_sec->this_hdr == NULL.
+
+2009-06-12 Tristan Gingold <gingold@adacore.com>
+
+ * reloc.c: Add BFD_RELOC_MACH_O_SECTDIFF and BFD_RELOC_MACH_O_PAIR.
+ * bfd-in2.h: Regenerated.
+ * libbfd.h: Regenerated.
+
+ * mach-o.c (FILE_ALIGN): New macro.
+ (bfd_mach_o_canonicalize_symtab): Adjust for bfd_mach_o_asymbol.
+ (bfd_mach_o_print_symbol): Ditto.
+ (bfd_mach_o_scan_write_thread): Adjust type of variable offset.
+ (bfd_mach_o_get_reloc_upper_bound): New function.
+ (bfd_mach_o_canonicalize_reloc): Ditto.
+ (bfd_mach_o_scan_write_relocs): Ditto.
+ (bfd_mach_o_scan_write_section_32): Remove offset argument.
+ (bfd_mach_o_scan_write_section_64): Ditto.
+ (bfd_mach_o_scan_write_segment_32): Write relocs. Fix size of data
+ written for load command. Do not compute section file offset.
+ (bfd_mach_o_scan_write_segment_64): Ditto.
+ (bfd_mach_o_scan_write_symtab): Compute file offset first.
+ Adjust for bfd_mach_o_asymbol. Move code to convert from BFD to
+ Mach-O to ...
+ (bfd_mach_o_mangle_symbols): ... this new function.
+ (bfd_mach_o_write_contents): Be sure to have load commands built.
+ Call bfd_mach_o_mangle_symbols.
+ (bfd_mach_o_build_commands): Adjust for filelen field.
+ Use FILE_ALIGN macro. Clear section file offset if section is empty.
+ Do not set symtab file offset anymore here.
+ (bfd_mach_o_make_empty_symbol): Allocate a bfd_mach_o_asymbol.
+ (bfd_mach_o_make_bfd_section): Set SEC_RELOC if has reloc.
+ Set reloc_count and rel_filepos section fields.
+ (bfd_mach_o_scan_read_section_32): Type of argument offset is now
+ unsigned int.
+ (bfd_mach_o_scan_read_section_64): Ditto.
+ (bfd_mach_o_scan_read_section): Ditto.
+ (bfd_mach_o_scan_read_symtab_symbol): Typr of argument s is now
+ bfd_mach_o_asymbol. Use unsigned int for file offset type.
+ (bfd_mach_o_scan_read_symtab_symbol): Adjust for bfd_mach_o_asymbol.
+ Handle weak-ref symbols.
+ (bfd_mach_o_scan_read_symtab_symbols): Adjust for bfd_mach_o_asymbol.
+ (bfd_mach_o_scan_read_dysymtab_symbol): Ditto.
+ (bfd_mach_o_scan): Remove assignment to removed field.
+ (bfd_mach_o_mkobject_init): Ditto.
+ (bfd_mach_o_bfd_print_private_bfd_data): Adjust printf formatter.
+ (bfd_mach_o_bfd_reloc_type_lookup): New macro.
+ (bfd_mach_o_bfd_reloc_name_lookup): Ditto.
+ (bfd_mach_o_swap_reloc_in): Ditto.
+ (bfd_mach_o_swap_reloc_out): Ditto.
+
+ * mach-o.h (BFD_MACH_O_REFERENCE_FLAG_UNDEFINED_NON_LAZY)
+ (BFD_MACH_O_REFERENCE_FLAG_UNDEFINED_LAZY)
+ (BFD_MACH_O_REFERENCE_FLAG_DEFINED)
+ (BFD_MACH_O_REFERENCE_FLAG_PRIVATE_DEFINED)
+ (BFD_MACH_O_REFERENCE_FLAG_PRIVATE_UNDEFINED_NON_LAZY)
+ (BFD_MACH_O_REFERENCE_FLAG_PRIVATE_UNDEFINED_LAZY)
+ (BFD_MACH_O_REFERENCED_DYNAMICALLY, BFD_MACH_O_N_DESC_DISCARDED)
+ (BFD_MACH_O_N_NO_DEAD_STRIP, BFD_MACH_O_N_WEAK_REF)
+ (BFD_MACH_O_N_WEAK_DEF): New macros.
+ Add comments.
+ (bfd_mach_o_section_type): Add new enumeration values.
+ (BFD_MACH_O_S_SELF_MODIFYING_CODE)
+ (BFD_MACH_O_S_ATTR_LIVE_SUPPORT)
+ (BFD_MACH_O_S_ATTR_NO_DEAD_STRIP)
+ (BFD_MACH_O_S_ATTR_STRIP_STATIC_SYMS, BFD_MACH_O_S_ATTR_NO_TOC): New
+ macros.
+ (BFD_MACH_O_GENERIC_RELOC_VANILLA)
+ (BFD_MACH_O_GENERIC_RELOC_PAIR)
+ (BFD_MACH_O_GENERIC_RELOC_SECTDIFF)
+ (BFD_MACH_O_GENERIC_RELOC_PB_LA_PTR)
+ (BFD_MACH_O_GENERIC_RELOC_LOCAL_SECTDIFF): Ditto.
+ (BFD_MACH_O_RELENT_SIZE): Ditto.
+ (BFD_MACH_O_R_PCREL, BFD_MACH_O_GET_R_LENGTH)
+ (BFD_MACH_O_R_EXTERN, BFD_MACH_O_GET_R_TYPE)
+ (BFD_MACH_O_GET_R_SYMBOLNUM, BFD_MACH_O_SET_R_LENGTH)
+ (BFD_MACH_O_SET_R_TYPE, BFD_MACH_O_SET_R_SYMBOLNUM): Ditto.
+ (BFD_MACH_O_SR_SCATTERED, BFD_MACH_O_SR_PCREL)
+ (BFD_MACH_O_GET_SR_LENGTH, BFD_MACH_O_GET_SR_TYPE)
+ (BFD_MACH_O_GET_SR_ADDRESS, BFD_MACH_O_SET_SR_LENGTH)
+ (BFD_MACH_O_SET_SR_TYPE, BFD_MACH_O_SET_SR_ADDRESS): Ditto.
+ (bfd_mach_o_reloc_info): New struct.
+ (bfd_mach_o_asymbol): New struct.
+ (bfd_mach_o_symtab_command): The symbols field is now of type
+ bfd_mach_o_asymbol.
+ (bfd_mach_o_load_command): The offset and len fields are now of type
+ unsigned int.
+ (mach_o_data_struct): Remove symbols, nsymbols and ibfd fields.
+ Add a filelen field. Add comments.
+ (bfd_mach_o_backend_data): New struct.
+ (bfd_mach_o_get_backend_data): New macro.
+ (bfd_mach_o_scan_read_symtab_symbol): Parameter symbol now of type
+ bfd_mach_o_asymbol.
+ (bfd_mach_o_scan_read_dysymtab_symbol): Ditto.
+ (bfd_mach_o_get_reloc_upper_bound): New prototype.
+ (bfd_mach_o_canonicalize_reloc): Ditto.
+
+ * mach-o-target.c (bfd_mach_o_bfd_is_local_label_name): Remove
+ duplicated macro. Now defined to _bfd_generic_is_local_label.
+ (TARGET_NAME_BACKEND): New macro...
+ (TARGET_NAME_BACKEND): ... used to name a new variable.
+ (TARGET_NAME): Define relocs table using bfd_mach_o, reference
+ Mach-O backend data.
+
+ * mach-o-i386.c (i386_howto_table): New variable.
+ (bfd_mach_o_i386_swap_reloc_in): New function.
+ (bfd_mach_o_i386_swap_reloc_out): Ditto.
+ (bfd_mach_o_i386_bfd_reloc_type_lookup): Ditto.
+ (bfd_mach_o_i386_bfd_reloc_name_lookup): Ditto.
+ (bfd_mach_o_swap_reloc_in, bfd_mach_o_swap_reloc_out): New macros.
+ (bfd_mach_o_bfd_reloc_type_lookup)
+ (bfd_mach_o_bfd_reloc_name_lookup): Ditto.
+
+2009-06-11 Eric Paris <eparis@redhat.com>
+ Nick Clifton <nickc@redhat.com>
+
+ * opncls.c (_maybe_make_executable): New function. Gives execute
+ permission to an executable bfd that was opened for writing
+ provided that it is a regular file. Replaces common code found in...
+ (bfd_close): here and ...
+ (bfd_close_all_done): here.
+
+2009-06-11 Anthony Green <green@moxielogic.com>
+
+ * reloc.c: Add BFD_RELOC_MOXIE_10_PCREL.
+ * bfd-in2.h: Rebuilt.
+ * libbfd.h: Rebuilt.
+ * elf32-moxie.c (moxie_elf_howto_table): Add R_MOXIE_PCREL10
+ relocation support.
+ (moxie_reloc_map): Ditto.
+ Clean up copyright notice.
+
+2009-06-10 Paul Pluzhnikov <ppluzhnikov@google.com>
+
+ * bfd-in2.h: bfd_mmap prototype.
+ * bfdio.c (bfd_mmap): New function.
+ * libbfd.h (bfd_iovec): Add bmmap.
+ * cache.c (cache_bmmap): New function.
+ (cache_iovec): Initialize bmmap member.
+ * opencls.c (opncls_bmmap): New function.
+ (opncls_iovec): Initialize bmmap member.
+
+2009-06-09 Tristan Gingold <gingold@adacore.com>
+
+ * mach-o.h (bfd_mach_o_symtab_command): Remove stabs_segment
+ and stabstr_segment fields.
+ (mach_o_be_vec, mach_o_le_vec): Removed
+ (bfd_mach_o_version): New prototype.
+
+ * mach-o.c (bfd_mach_o_version): Make this function public.
+ (mach_o_wide_p): New function.
+ (bfd_mach_o_wide_p): Ditto.
+ (bfd_mach_o_convert_section_name_to_bfd): Add prefix only for
+ weird names.
+ (bfd_mach_o_convert_section_name_to_mach_o): Fix typo in comment.
+ Search in the list only if the name starts with a dot.
+ (bfd_mach_o_write_header): Use mach_o_wide_p instead of hard-coded
+ test. Check bfd_seek status.
+ (bfd_mach_o_scan_write_thread): Check bfd_seek status.
+ (bfd_mach_o_scan_write_section_32): Ditto.
+ (bfd_mach_o_scan_write_section_64): Ditto.
+ (bfd_mach_o_scan_write_section): Removed.
+ (bfd_mach_o_scan_write_segment): Split into ...
+ (bfd_mach_o_scan_write_segment_32): ... this and ...
+ (bfd_mach_o_scan_write_segment_64): ... this. Check bfd_seek status.
+ (bfd_mach_o_scan_write_symtab_symbols): Moved into ...
+ (bfd_mach_o_scan_write_symtab): ... this. Write symtab from BFD
+ symbol table. Now returns a boolean.
+ (bfd_mach_o_write_contents): Set filetype. Check bfd_seek status.
+ Adjust for status type.
+ (bfd_mach_o_build_commands): Use mach_o_wide_p instead of hard-coded
+ test. Write symbol table. Numbers the sections.
+ (bfd_mach_o_read_header): Check bfd_seek status.
+ Use mach_o_wide_p instead of hard-coded test.
+ (bfd_mach_o_scan_read_section_32): Check bfd_seek status.
+ (bfd_mach_o_scan_read_section_64): Ditto.
+ (bfd_mach_o_scan_read_symtab_symbol): Ditto. Check bfd_seek status.
+ Use BFD_MACH_O_N_TYPE instead of hard-coded value. Correctly
+ handled common symbols.
+ (bfd_mach_o_scan_read_symtab_strtab): Check bfd_seek status.
+ (bfd_mach_o_scan_read_dysymtab_symbol): Ditto.
+ (bfd_mach_o_scan_read_dylinker): Ditto.
+ (bfd_mach_o_scan_read_dylib): Ditto.
+ (bfd_mach_o_scan_read_thread): Ditto.
+ (bfd_mach_o_scan_read_symtab): Ditto.
+ Do not create a section for the stabs.
+ (bfd_mach_o_scan_read_uuid): Check bfd_seek status.
+ (bfd_mach_o_scan_read_segment): Ditto.
+ (bfd_mach_o_scan_read_command): Ditto.
+ (bfd_mach_o_scan_start_address): Ditto.
+ (bfd_mach_o_scan): Use mach_o_wide_p instead of hard-coded test.
+ (bfd_mach_o_archive_p): Check bfd_seek status.
+ (bfd_mach_o_core_fetch_environment): Ditto.
+
+ * mach-o-i386.c (bfd_mach_o_i386_mkobject): Don't set filetype.
+
+2009-06-06 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf32-i386.c (elf_i386_link_hash_table): Add irelifunc.
+ (elf_i386_link_hash_table_create): Initialize irelifunc.
+ (elf_i386_check_relocs): Updated. Set up irelifunc for
+ shared objects.
+ (elf_i386_allocate_dynrelocs): Use irelifunc for dynamic
+ relocation for non-GOT reference of STT_GNU_IFUNC symbol in
+ shared objects.
+ (elf_i386_relocate_section): Likewise.
+
+ * elf64-x86-64.c (elf64_x86_64_link_hash_table): Add irelifunc.
+ (elf64_x86_64_link_hash_table_create): Initialize irelifunc.
+ (elf64_x86_64_check_relocs): Updated. Set up irelifunc for
+ shared objects.
+ (elf64_x86_64_allocate_dynrelocs): Use irelifunc for dynamic
+ relocation for non-GOT reference of STT_GNU_IFUNC symbol in
+ shared objects.
+ (elf64_x86_64_relocate_section): Likewise.
+
+ * elf-bfd.h (_bfd_elf_create_static_ifunc_sections): Renamed to
+ ...
+ (_bfd_elf_create_ifunc_sections): This.
+
+ * elflink.c (_bfd_elf_create_static_ifunc_sections): Renamed to
+ ...
+ (_bfd_elf_create_ifunc_sections): This. Create .rel[a].ifunc
+ for shared objects.
+
+2009-06-06 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf32-i386.c (elf_i386_check_relocs): Make room for dynamic
+ relocation for R_386_32 against STT_GNU_IFUNC symbol when
+ building shared object. Check info->executable instead of
+ !info->shared when setting non_got_ref.
+ (elf_i386_allocate_dynrelocs): Allocate dynamic relocation
+ for non-GOT reference of STT_GNU_IFUNC symbol in shared
+ object. Allocate GOT relocation agsinst STT_GNU_IFUNC
+ symbol if needed.
+ (elf_i386_relocate_section): Output dynamic relocation for
+ R_386_32 against STT_GNU_IFUNC symbol to get the real
+ function address when building shared object.
+ (elf_i386_finish_dynamic_symbol): Output R_386_GLOB_DAT
+ relocation for STT_GNU_IFUNC symbol in shared object.
+
+ * elf64-x86-64.c (elf64_x86_64_check_relocs): Make room for
+ dynamic relocation for R_X86_64_64 against STT_GNU_IFUNC
+ symbol when building shared object. Check info->executable
+ instead of !info->shared when setting non_got_ref.
+ (elf64_x86_64_allocate_dynrelocs): Allocate dynamic relocation
+ for non-GOT reference of STT_GNU_IFUNC symbol in shared
+ library. Allocate GOT relocation agsinst STT_GNU_IFUNC symbol
+ if needed.
+ (elf64_x86_64_relocate_section): Output dynamic relocation
+ for R_X86_64_64 against STT_GNU_IFUNC symbol to get the real
+ function address when building shared object.
+ (elf64_x86_64_finish_dynamic_symbol): Output R_X86_64_GLOB_DAT
+ relocation for STT_GNU_IFUNC symbol in shared object.
+
+2009-06-06 Jan Kratochvil <jan.kratochvil@redhat.com>
+
+ * Makefile.am: Run "make dep-am".
+ (BFD32_BACKENDS): Add mach-o-i386.lo.
+ (BFD32_BACKENDS_CFILES): Add mach-o-i386.c.
+ * Makefile.in: Regenerate.
+
+2009-06-06 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-spu.c (spu_elf_relocate_section): Match overlay number
+ when looking for soft-icache stubs.
+
+2009-06-05 Tristan Gingold <gingold@adacore.com>
+
+ * mach-o.h: Update copyright year.
+ (bfd_mach_o_mach_header_magic): New enum.
+ (bfd_mach_o_cpu_subtype): Now an enum.
+ (BFD_MACH_O_HEADER_SIZE, BFD_MACH_O_HEADER_64_SIZE): New macros.
+ (BFD_MACH_O_SECTION_SIZE, BFD_MACH_O_SECTION_64_SIZE): Ditto.
+ (BFD_MACH_O_LC_SEGMENT_SIZE, BFD_MACH_O_LC_SEGMENT_64_SIZE): Ditto.
+ (bfd_mach_o_load_command): Field type_required is now a boolean.
+ Reindent prototypes.
+ (bfd_mach_o_object_p, bfd_mach_o_core_p): Remove.
+ (bfd_mach_o_bfd_copy_private_symbol_data): Add a prototype.
+ (bfd_mach_o_bfd_copy_private_section_data): Ditto.
+ (bfd_mach_o_bfd_copy_private_bfd_data): Ditto.
+ (bfd_mach_o_get_symtab_upper_bound): Ditto.
+ (bfd_mach_o_canonicalize_symtab): Ditto.
+ (bfd_mach_o_get_symbol_info): Ditto.
+ (bfd_mach_o_print_symbol): Ditto.
+ (bfd_mach_o_bfd_print_private_bfd_data): Ditto.
+ (bfd_mach_o_make_empty_symbol): Ditto.
+ (bfd_mach_o_write_contents): Ditto.
+
+ * mach-o.c (bfd_mach_o_object_p, bfd_mach_o_core_p,
+ bfd_mach_o_mkobject): Defines.
+ (bfd_mach_o_valid): Returns FALSE/TRUE instead of 0/1.
+ Do not check with target vector but with flavour.
+ (struct mach_o_section_name_xlat): New declaration.
+ (dwarf_section_names_xlat): Ditto.
+ (text_section_names_xlat): Ditto.
+ (data_section_names_xlat): Ditto.
+ (struct mach_o_segment_name_xlat): Ditto.
+ (segsec_names_xlat): Ditto.
+ (bfd_mach_o_convert_section_name_to_bfd): New function.
+ (bfd_mach_o_convert_section_name_to_mach_o): Ditto.
+ (bfd_mach_o_bfd_copy_private_symbol_data): Make it public.
+ (bfd_mach_o_bfd_copy_private_section_data): Ditto.
+ (bfd_mach_o_bfd_copy_private_bfd_data): Ditto.
+ Accept any input and output flavour. Do not share private data
+ anymore.
+ (bfd_mach_o_count_symbols): Add a comment.
+ (bfd_mach_o_get_symtab_upper_bound): Make it public.
+ (bfd_mach_o_canonicalize_symtab): Ditto.
+ (bfd_mach_o_get_symbol_info): Ditto.
+ (bfd_mach_o_print_symbol): Ditto.
+ (bfd_mach_o_write_header): Now returns a boolean instead of an int.
+ Use constants instead of hard-coded values.
+ (bfd_mach_o_scan_write_section_32): Use constants instead of hard-coded
+ values.
+ (bfd_mach_o_scan_write_section_64): Ditto.
+ (bfd_mach_o_scan_write_segment): Ditto.
+ Do not copy sections anymore.
+ (bfd_mach_o_write_contents): Make it public.
+ Remove dead code. Rewrite typeflag assignment.
+ (bfd_mach_o_build_commands): New function.
+ (bfd_mach_o_set_section_contents): Ditto.
+ (bfd_mach_o_make_empty_symbol): Make it public.
+ (bfd_mach_o_read_header): Make it static.
+ Convert to bfd_boolean.
+ Use constants instead of hard-coded values.
+ (bfd_mach_o_make_bfd_section): Call
+ bfd_mach_o_convert_section_name_to_bfd to create name.
+ (bfd_mach_o_scan_read_section_32): Use constants instead of hard-coded
+ values.
+ (bfd_mach_o_scan_read_section_64): Ditto.
+ (bfd_mach_o_scan_read_segment): Do not create a bfd section for
+ a segment anymore. Use constants instead of hard-coded values.
+ (bfd_mach_o_scan_read_command): Fix style.
+ (bfd_mach_o_scan): Use constants instead of hard-coded values.
+ Get rid of BFD_IO_FUNCS.
+ (bfd_mach_o_mkobject_init): Renamed from bfd_mach_o_mkobject.
+ (bfd_mach_o_header_p): Created from bfd_mach_o_object_p.
+ (bfd_mach_o_gen_object_p): New function, replaces bfd_mach_o_object_p.
+ (bfd_mach_o_object_p): Removed.
+ (bfd_mach_o_gen_core_p): New function, replaces ...
+ (bfd_mach_o_core_p): ... deleted.
+ (bfd_mach_o_bfd_print_private_bfd_data): Make it public.
+
+ * mach-o-i386.c: New file.
+ * config.bfd: Use mach_o_i386_vec as targ_defvec for ix86-darwin.
+ * configure.in (TDEFINES): Add mach_o_i386_vec.
+ * configure: Regenerated.
+ * targets.c: Add mach_o_i386_vec.
+
+ * mach-o.c: Update copyright years.
+ (BFD_IO_FUNCS): Remove (was not used).
+ (bfd_mach_o_mkarchive, bfd_mach_o_read_ar_hdr, bfd_mach_o_slurp_armap
+ bfd_mach_o_slurp_extended_name_table,
+ bfd_mach_o_construct_extended_name_table,
+ bfd_mach_o_truncate_arname, bfd_mach_o_write_armap,
+ bfd_mach_o_get_elt_at_index, bfd_mach_o_generic_stat_arch_elt,
+ bfd_mach_o_update_armap_timestamp, bfd_mach_o_close_and_cleanup,
+ bfd_mach_o_bfd_free_cached_info, bfd_mach_o_new_section_hook,
+ bfd_mach_o_get_section_contents_in_window,
+ bfd_mach_o_bfd_is_local_label_name,
+ bfd_mach_o_bfd_is_target_special_symbol,
+ bfd_mach_o_bfd_is_local_label_name, bfd_mach_o_get_lineno,
+ bfd_mach_o_find_nearest_line, bfd_mach_o_find_inliner_info,
+ bfd_mach_o_bfd_make_debug_symbol, bfd_mach_o_read_minisymbols,
+ bfd_mach_o_minisymbol_to_symbol,
+ bfd_mach_o_bfd_get_relocated_section_contents,
+ bfd_mach_o_bfd_relax_section, bfd_mach_o_bfd_link_hash_table_create,
+ bfd_mach_o_bfd_link_hash_table_free, bfd_mach_o_bfd_link_add_symbols,
+ bfd_mach_o_bfd_link_just_syms, bfd_mach_o_bfd_final_link,
+ bfd_mach_o_bfd_link_split_section, bfd_mach_o_set_arch_mach,
+ bfd_mach_o_bfd_merge_private_bfd_data,
+ bfd_mach_o_bfd_set_private_flags, bfd_mach_o_get_section_contents,
+ bfd_mach_o_bfd_gc_sections, bfd_mach_o_bfd_merge_sections,
+ bfd_mach_o_bfd_is_group_section, bfd_mach_o_bfd_discard_group,
+ bfd_mach_o_section_already_linked, bfd_mach_o_bfd_define_common_symbol,
+ bfd_mach_o_bfd_copy_private_header_data,
+ bfd_mach_o_core_file_matches_executable_p): Move these defines ...
+ * mach-o-target.c: ... here.
+ Update copyright years.
+
+2009-06-04 Alan Modra <amodra@bigpond.net.au>
+
+ * dep-in.sed: Don't use \n in replacement part of s command.
+ * Makefile.am (DEP1): LC_ALL for uniq.
+ Run "make dep-am".
+ * Makefile.in: Regenerate.
+
+2009-06-03 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf32-i386.c (elf_i386_allocate_dynrelocs): Remove check of
+ h->plt.refcount > 0 on STT_GNU_IFUNC symbol.
+ * elf64-x86-64.c (elf64_x86_64_allocate_dynrelocs): Likewise.
+
+2009-06-03 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf32-i386.c (elf_i386_allocate_dynrelocs): Allocate
+ GOT entry for STT_GNU_IFUNC symbol with pointer equality.
+ (elf_i386_relocate_section): Adjust R_386_GOT32 relocation
+ against STT_GNU_IFUNC symbols for static executables.
+ (elf_i386_finish_dynamic_symbol): Load GOT entry with
+ PLT entry for STT_GNU_IFUNC symbol with pointer equality.
+
+ * elf64-x86-64.c (elf64_x86_64_allocate_dynrelocs): Allocate
+ GOT entry for STT_GNU_IFUNC symbol with pointer equality.
+ (elf64_x86_64_finish_dynamic_symbol): Load GOT entry with
+ PLT entry for STT_GNU_IFUNC symbol with pointer equality.
+
+2009-06-02 Richard Sandiford <r.sandiford@uk.ibm.com>
+
+ * coff-rs6000.c (xcoff_ppc_relocate_section): Allow undefined
+ symbols to be left unimported when linking statically.
+ * xcofflink.c (xcoff_link_add_symbols): Ignore global linkage
+ code when linking statically.
+
+2009-06-02 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf32-i386.c (elf_i386_check_relocs): Increment
+ got.refcount for R_386_GOT32/R_386_GOTOFF relocations
+ against STT_GNU_IFUNC symbol.
+ (elf_i386_allocate_dynrelocs): Set got.refcount to 0 if
+ local STT_GNU_IFUNC definition is used.
+ (elf_i386_relocate_section): Handle got.offset != -1 for
+ R_386_GOT32/R_386_GOTOFF relocations against STT_GNU_IFUNC
+ symbol.
+
+ * elf64-x86-64.c (elf64_x86_64_check_relocs): Increment
+ got.refcount for R_X86_64_GOTPCREL/R_X86_64_GOTPCREL64
+ relocations against STT_GNU_IFUNC symbol.
+ (elf64_x86_64_allocate_dynrelocs): Set got.refcount to 0 if
+ local STT_GNU_IFUNC definition is used.
+ (elf64_x86_64_relocate_section): Handle got.offset != -1
+ for R_X86_64_GOTPCREL/R_X86_64_GOTPCREL64 relocations against
+ STT_GNU_IFUNC symbol.
+
+2009-06-01 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/10205
+ * elf32-i386.c (elf_howto_table): Add R_386_IRELATIVE.
+ (elf_i386_reloc_type_lookup): Likewise.
+ (R_386_tls): Removed.
+ (R_386_irelative): New.
+ (R_386_vt_offset): Updated.
+ (elf_i386_rtype_to_howto): Likewise.
+ (elf_i386_link_hash_table): Add igotplt, iplt and irelplt.
+ (elf_i386_link_hash_table_create): Initialize igotplt,
+ iplt and irelplt.
+ (elf_i386_check_relocs): Handle STT_GNU_IFUNC symbol first.
+ (elf_i386_adjust_dynamic_symbol): Likewise.
+ (elf_i386_allocate_dynrelocs): Likewise.
+ (elf_i386_relocate_section): Likewise.
+ (elf_i386_size_dynamic_sections): Set up .iplt and .igot.plt
+ sections.
+ (elf_i386_finish_dynamic_symbol): When building a static
+ executable, use .iplt, .igot.plt and .rel.iplt sections for
+ STT_GNU_IFUNC symbols. Generate R_386_IRELATIVE relocation for
+ locally defined STT_GNU_IFUNC symbol.
+
+ * elf64-x86-64.c (x86_64_elf_howto): Add R_X86_64_IRELATIVE.
+ (x86_64_reloc_map): Likewise.
+ (R_X86_64_standard): Updated.
+ (elf64_x86_64_link_hash_table): Add igotplt, iplt and irelplt.
+ (elf64_x86_64_link_hash_table_create): Initialize igotplt,
+ iplt and irelplt.
+ (elf64_x86_64_check_relocs): Handle STT_GNU_IFUNC symbol first.
+ (elf64_x86_64_adjust_dynamic_symbol): Likewise.
+ (elf64_x86_64_allocate_dynrelocs): Likewise.
+ (elf64_x86_64_relocate_section): Likewise.
+ (elf64_x86_64_size_dynamic_sections): Set up .iplt and .igot.plt
+ sections.
+ (elf64_x86_64_finish_dynamic_symbol): When building a static
+ executable, use .iplt, .igot.plt and .rela.iplt sections for
+ STT_GNU_IFUNC symbols. Generate R_X86_64_IRELATIVE relocation
+ for locally defined STT_GNU_IFUNC symbol.
+
+ * reloc.c (BFD_RELOC_386_IRELATIVE): New.
+ (BFD_RELOC_X86_64_IRELATIVE): Likewise.
+
+ * bfd-in2.h: Regenerated.
+ * libbfd.h: Likewise.
+
+2009-06-01 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf-bfd.h (struct bfd_elf_section_data): Remove indirect_relocs.
+ (_bfd_elf_make_ifunc_reloc_section): Removed.
+ (_bfd_elf_is_ifunc_symbol): Likewise.
+ (_bfd_elf_create_static_ifunc_sections): New.
+
+ * elflink.c (_bfd_elf_adjust_dynamic_symbol): Move STT_GNU_IFUNC
+ symbol check to ...
+ (elf_link_add_object_symbols): Here.
+ (_bfd_elf_link_hash_hide_symbol): Don't clean plt on
+ STT_GNU_IFUNC symbol.
+ (elf_link_output_extsym): Call elf_backend_finish_dynamic_symbol
+ if a STT_GNU_IFUNC symbol is referenced in a non-shared object.
+ (IFUNC_INFIX): Removed.
+ (get_ifunc_reloc_section_name): Likewise.
+ (_bfd_elf_make_ifunc_reloc_section): Likewise.
+ (_bfd_elf_is_ifunc_symbol): Likewise.
+ (_bfd_elf_create_static_ifunc_sections): New.
+
+2009-05-29 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf32-i386.c (link_hash_newfunc): Add elf_i386_ prefix.
+ (create_got_section): Likewise.
+ (allocate_dynrelocs): Likewise.
+ (readonly_dynrelocs): Likewise.
+ (set_tls_module_base): Likewise.
+ (dtpoff_base): Likewise.
+ (tpoff): Likewise.
+ (elf_i386_link_hash_table_create): Updated.
+ (elf_i386_create_dynamic_sections): Likewise.
+ (elf_i386_check_relocs): Likewise.
+ (elf_i386_size_dynamic_sections): Likewise.
+ (elf_i386_relocate_section): Likewise.
+
+ * elf64-x86-64.c (link_hash_newfunc): Add elf64_x86_64_ prefix.
+ (create_got_section): Likewise.
+ (allocate_dynrelocs): Likewise.
+ (readonly_dynrelocs): Likewise.
+ (set_tls_module_base): Likewise.
+ (dtpoff_base): Likewise.
+ (tpoff): Likewise.
+ (elf64_x86_64_link_hash_table_create): Updated.
+ (elf64_x86_64_create_dynamic_sections): Likewise.
+ (elf64_x86_64_check_relocs): Likewise.
+ (elf64_x86_64_size_dynamic_sections): Likewise.
+ (elf64_x86_64_relocate_section): Likewise.
+
+2009-05-28 Nick Clifton <nickc@redhat.com>
+
+ * targets.c (_bfd_target_vector): Only include plugin target in
+ all-targets build if BFD_SUPPORTS_PLUGINS is non-zero.
+
+2009-05-28 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * elf32-spu.c (struct call_info): New member broken_cycle.
+ (remove_cycle): Instead of physically removing call_info structures
+ to break call graph cycles, mark them using the broken_cycle flag.
+ (mark_overlay_section): Respect broken_cycle flag.
+ (unmark_overlay_section): Likewise.
+ (collect_lib_sections): Likewise.
+ (collect_overlays): Likewise.
+ (sum_stack): Likewise.
+
+2009-05-28 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * elf32-spu.c (insert_callee): Accumulate incoming callee->count.
+ (mark_functions_via_relocs): Initialize callee->count to 1.
+ (pasted_function): Likewise.
+ (spu_elf_auto_overlay): Honor call counts when determining number
+ of stubs required in software i-cache mode.
+
+2009-05-27 Rafael Avila de Espindola <espindola@google.com>
+
+ * plugin.c (program_name): Remove.
+ (plugin_program_name): New.
+ (bfd_plugin_set_program_name): New.
+ (try_load_plugin): Use plugin_program_name.
+ * plugin.h (bfd_plugin_set_program_name): New.
+
+2009-05-27 Rafael Avila de Espindola <espindola@google.com>
+
+ * aclocal.m4: Include ../config/plugins.m4.
+ * configure.in: Use AC_PLUGINS.
+ * configure: Regenerate.
+ * Makefile.in: Regenerate.
+ * doc/Makefile.in: Regenerate.
+
+2009-05-27 Nathan Sidwell <nathan@codesourcery.com>
+
+ * elf32-ppc.c (ppc_elf_relax_section): Work with a partial
+ link.
+ * bout.c (b_out_bfd_relax_section): Reject relocatable links.
+ * elf32-m10300.c (mn10300_elf_relax_section): Likewise.
+ * elf32-avr.c (elf32_avr_relax_section): Likewise.
+ * elf32-frv.c (elf32_avr_relax_section): Likewise.
+ * elf32-xtensa.c (elf_xtensa_relax_section): Likewise.
+ * elf64-mmix.c (mmix_elf_relax_section): Likewise.
+ * elfxx-ia64.c (elfNN_ia64_relax_section): Likewise.
+ * elfxx-sparc.c (_bfd_sparc_elf_relax_section): Likewise.
+ * reloc.c (bfd_generic_relax_section): Likewise.
+ * reloc16.c (bfd_coff_reloc16_relax_section): Likewise.
+ * vms.c (vms_bfd_relax_section): Likewise.
+
+2009-05-26 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf-bfd.h (_bfd_elf_is_ifunc_symbol): New.
+
+ * elf32-i386.c (is_indirect_symbol): Renamed to ...
+ * elflink.c (_bfd_elf_is_ifunc_symbol): This.
+
+ * elf32-i386.c (allocate_dynrelocs): Updated.
+ (elf_i386_relocate_section): Likewise.
+ * elf64-x86-64.c (allocate_dynrelocs): Likewise.
+ (elf64_x86_64_relocate_section): Likewise.
+
+ * elf64-x86-64.c (is_indirect_symbol): Removed.
+
+2009-05-26 Nick Clifton <nickc@redhat.com>
+
+ * po/id.po: Updated Indonesian translation.
+
+2009-05-26 Rafael Avila de Espindola <espindola@google.com>
+
+ * Makefile.am: Run "make dep-am".
+ (AM_CPPFLAGS): New.
+ (LIBDL): New.
+ (ALL_MACHINES): Add cpu-plugin.lo.
+ (ALL_MACHINES_CFILES): Add cpu-plugin.c.
+ (BFD32_BACKENDS): Add plugin.lo.
+ (BFD32_BACKENDS_CFILES): Add plugin.c.
+ (libbfd_la_LIBADD): Add LIBDL
+ * archures.c (bfd_architecture): Add bfd_arch_plugin.
+ (bfd_plugin_arch): Declare.
+ * bfd-in.h (BFD_SUPPORTS_PLUGINS): New.
+ * bfd.c (bfd): Add plugin_data.
+ * config.bfd: Handle the plugin target.
+ * configure.in: Check for --enable-plugins.
+ (LT_INIT): Use the dlopen option.
+ * cpu-plugin.c: New.
+ * plugin.c: New.
+ * plugin.h: New.
+ * targets.c (plugin_vec): Declare.
+ (_bfd_target_vector): Add plugin_vec.
+ * Makefile.in: Regenerate.
+ * bfd-in2.h: Regenerate.
+ * configure: Regenerate.
+
+2009-05-26 Alan Modra <amodra@bigpond.net.au>
+
+ * dep-in.sed: Don't modify .o to .lo here. Output one filename
+ per line with all lines having continuation backslash. Prefix
+ first line with "A", following lines with "B".
+ * Makefile.am (DEP): Don't use dep.sed here.
+ (DEP1): Run $MKDEP on single files, modify .o to .lo here. Use
+ dep.sed here on dependencies, sort and uniq.
+ * Makefile.in: Regenerate.
+
+2009-05-25 Tristan Gingold <gingold@adacore.com>
+
+ * makefile.vms: Add verilog.obj to object list OBJS.
+
+2009-05-24 Alan Modra <amodra@bigpond.net.au>
+
+ * bfdio.c (bfd_seek): Formatting. Ensure newly allocated memory
+ for BFD_IN_MEMORY is cleared.
+ (bfd_bwrite): Zero excess memory allocated.
+
+2009-05-22 Julian Brown <julian@codesourcery.com>
+
+ * elf32-arm.c (THUMB16_BCOND_INSN, THUMB32_INSN, THUMB32_B_INSN): New
+ macros.
+ (elf32_arm_stub_a8_veneer_b_cond, elf32_arm_stub_a8_veneer_b)
+ (elf32_arm_stub_a8_veneer_blx): New stub sequences.
+ (elf32_arm_stub_type): Add arm_stub_a8_veneer_b_cond,
+ arm_stub_a8_veneer_b and arm_stub_a8_veneer_blx.
+ (elf32_arm_stub_hash_entry): Add target_addend, orig_insn fields.
+ (a8_erratum_fix, a8_erratum_reloc): New structs.
+ (elf32_arm_link_hash_table): Add a8_erratum_fixes,
+ num_a8_erratum_fixes, fix_cortex_a8 fields.
+ (elf32_arm_link_hash_table_create): Zero fix_cortex_a8.
+ (elf32_arm_add_stub): Split into two parts, creating...
+ (elf32_arm_create_or_find_stub_sec): New function.
+ (elf32_arm_final_link_relocate): Add forward declaration.
+ (arm_build_one_stub): Add support for THUMB32_TYPE, Thumb-2
+ relocations, multiple relocations per stub.
+ (find_stub_size_and_template): New (using parts of arm_size_one_stub).
+ (arm_size_one_stub): Use find_stub_size_and_template.
+ (a8_reloc_compare): New.
+ (find_thumb_glue): Add forward declaration.
+ (cortex_a8_erratum_scan): New.
+ (elf32_arm_size_stubs): Add Cortex-A8 erratum workaround support.
+ (bfd_elf32_arm_set_cortex_a8_fix): New.
+ (bfd_elf32_arm_set_target_relocs): Add fix_cortex_a8 argument.
+ (arm_map_one_stub): Add THUMB32_TYPE support.
+ (a8_branch_to_stub_data): New.
+ (make_branch_to_a8_stub): New.
+ (elf32_arm_write_section): Add Cortex-A8 erratum workaround support.
+ * bfd-in.h (bfd_elf32_arm_set_cortex_a8_fix): New.
+ (bfd_elf32_arm_set_target_relocs): Add argument for controlling
+ Cortex-A8 erratum workaround.
+ * bfd-in2.h: Regenerate.
+
+2009-05-22 Alan Modra <amodra@bigpond.net.au>
+
+ * Makefile.am: Run "make dep-am".
+ * Makefile.in: Regenerate.
+ * po/SRC-POTFILES.in: Regenerate.
+
+2009-05-21 Alan Modra <amodra@bigpond.net.au>
+
+ * elflink.c (elf_link_input_bfd): Correct *pindex change in last
+ commit.
+
+2009-05-21 Alan Modra <amodra@bigpond.net.au>
+
+ * elf-bfd.h (struct elf_backend_data
+ <elf_backend_link_output_symbol_hook>): Return an int.
+ * elf64-ppc.c (ppc64_elf_output_symbol_hook): Return 2 to drop
+ symbols on deleted .opd entries.
+ * elflink.c (elf_link_output_sym): Return without outputting sym
+ if output_symbol_hook returns 2.
+ (elf_link_output_extsym): Don't assign h->indx when symbol discarded.
+ Abort if we must not discard sym.
+ (elf_link_input_bfd): Similarly, don't set finfo->indices for
+ local syms.
+ (bfd_elf_final_link): Adjust elf_link_output_sym calls.
+ * elf-vxworks.c (elf_vxworks_link_output_symbol_hook): Adjust for
+ elf_backend_link_output_symbol_hook return type change.
+ * elf32-arm.c (output_arch_syminfo): Likewise.
+ (elf32_arm_output_map_sym, elf32_arm_output_stub_sym): Likewise.
+ (elf32_arm_output_arch_local_syms): Likewise.
+ * elf32-cr16c.c (elf32_cr16c_link_output_symbol_hook): Likewise.
+ * elf32-score.c (s3_bfd_score_elf_link_output_symbol_hook): Likewise.
+ (bfd_score_elf_link_output_symbol_hook): Likewise.
+ * elf32-score.h (s7_bfd_score_elf_link_output_symbol_hook): Likewise.
+ * elf32-score7.c (s7_bfd_score_elf_link_output_symbol_hook): Likewise.
+ * elf32-sh64.c (sh64_elf_link_output_symbol_hook): Likewise.
+ * elf32-spu.c (spu_elf_output_symbol_hook): Likewise.
+ * elf32-v850.c (v850_elf_link_output_symbol_hook): Likewise.
+ * elf64-hppa.c (elf64_hppa_link_output_symbol_hook): Likewise.
+ * elf64-mmix.c (mmix_elf_link_output_symbol_hook): Likewise.
+ * elf64-sh64.c (sh64_elf64_link_output_symbol_hook): Likewise.
+ * elf64-sparc.c (elf64_sparc_output_arch_syms): Likewise.
+ * elfxx-mips.c (_bfd_mips_elf_link_output_symbol_hook): Likewise.
+ * elfxx-mips.h (_bfd_mips_elf_link_output_symbol_hook): Likewise.
+
+2009-05-21 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (ppc64_elf_get_synthetic_symtab): Don't segfault on
+ out of range .opd symbols.
+
+2009-05-21 Dave Korn <dave.korn.cygwin@gmail.com>
+
+ * coffgen.c (coff_print_symbol): Use bfd_fprintf_vma, not
+ fprintf_vma directly.
+ * peXXigen.c (pe_print_edata): Likewise.
+ (pe_print_pdata): Likewise.
+ (_bfd_XX_print_ce_compressed_pdata): Likewise.
+ (_bfd_XX_print_private_bfd_data_common): Likewise.
+
+2009-05-19 Dave Korn <dave.korn.cygwin@gmail.com>
+
+ * cofflink.c (process_embedded_commands): Ignore "-aligncomm".
+
+2009-05-15 Andrew Stubbs <ams@codesourcery.com>
+ Paul Brook <paul@codesourcery.com>
+
+ * elf32-arm.c (elf32_arm_fix_exidx_coverage): Don't attempt to
+ fix discarded sections.
+
+2009-05-14 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * elf32-spu.c (mark_overlay_section): Move .init and .fini
+ sections into the software icache.
+
+2009-05-14 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * elf32-spu.c (build_stub): Always build "compact" sofware
+ i-cache stubs.
+
+2009-05-14 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * elf32-spu.c (struct spu_link_hash_table): Add fromelem_size_log2.
+ (spu_elf_setup): Initialize it.
+ (spu_elf_size_stubs): Move .ovtab into .bss for software i-cache.
+ Update to new-sytle cache manager data structures.
+ (spu_elf_build_stubs): Generate new-style cache manager data
+ structures and symbols.
+ (spu_elf_auto_overlay): Update size computation.
+
+2009-05-14 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * elf32-spu.c (spu_elf_modify_segment_map): Move all PF_OVERLAY
+ segments first amongst the program headers.
+
+2009-05-14 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * elf32-spu.c (spu_elf_relocate_section): Only encode overlay index
+ into addresses for relocation types that look at high bits. Remove
+ special handling of relocation overflow warnings.
+
+2009-05-14 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * elf32-spu.c (mark_functions_via_relocs): Handle cycles in the
+ control flow graph between fragments of a function.
+
+2009-05-14 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * elf32-spu.c (spu_elf_size_stubs): Even in software i-cache mode,
+ generate only a 16-byte .toe section.
+ (spu_elf_build_stubs, spu_elf_auto_overlay): Likewise.
+
+2009-05-14 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-spu.c (spu_elf_size_stubs): Split out section placement to..
+ (spu_elf_place_overlay_data): ..here. New function.
+ * elf32-spu.h (spu_elf_place_overlay_data): Declare.
+
+2009-05-13 Andrew Jenner <andrew@codesourcery.com>
+
+ * elf32-arm.c: Move sysdep.h to start of file.
+
+2009-05-11 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * elf32-spu.c (spu_elf_find_overlays): Don't use .ovl.init lma as
+ start of overlays.
+ (spu_elf_build_stubs): Don't define __icache_tagbase. Define
+ __icache_tag_array and __icache_tag_array_size.
+
+2009-05-11 Masaki Muranaka <monaka@monami-software.com>
+
+ * elf32-bfin.c (bfin_bfd_reloc_type_lookup): Remove unnecessary
+ ATTRIBUTE_UNUSED.
+ (bfinfdpic_link_omit_section_dynsym): Likewise.
+ (elf32_bfinfdpic_finish_dynamic_sections): Likewise.
+
+2009-05-05 Paul Brook <paul@codesourcery.com>
+
+ * bfd-in.h (elf32_arm_fix_exidx_coverage): Add prototype.
+ * bfd-in2.h: Regenerate.
+ * elf32-arm.c (arm_unwind_edit_type, arm_unwind_table_edit): Define.
+ (_arm_elf_section_data): Add text and exidx fields.
+ (add_unwind_table_edit, get_arm_elf_section_data, adjust_exidx_size,
+ insert_cantunwind_after, elf32_arm_fix_exidx_coverage, offset_prel31,
+ copy_exidx_entry): New functions.
+ (elf32_arm_write_section): Fixup .ARM.exidx contents.
+
+2009-05-05 Christophe lyon <christophe.lyon@st.com>
+
+ * elf32-arm.c (DEF_STUBS): New helper define.
+ (DEF_STUB): Likewise.
+ (stub_def): New type.
+ (stub_definitions): New array, containing stub template pointers
+ and sizes.
+ (arm_size_one_stub): Make use of stub_definitions.
+
+2009-05-04 Dave Korn <dave.korn.cygwin@gmail.com>
+
+ * elflink.c (find_version_for_sym): Remove from here, ...
+ * linker.c (bfd_find_version_for_sym): ... rename, replace
+ here, make public and update all callers.
+ * bfd-in2.h: Regenerate.
+
+2009-04-30 Nick Clifton <nickc@redhat.com>
+
+ * elf-bfd.h (struct bfd_elf_section_data): Add indirect_relocs
+ section pointer.
+ (struct elf_obj_data): Add has_ifunc_symbols boolean.
+ * elf.c (swap_out_syms): Convert BSF_GNU_INDIRECT_FUNCTION flags
+ into a STT_GNU_IFUNC symbol type.
+ (_bfd_elf_is_function_type): Accept STT_GNU_IFUNC as a function
+ type.
+ (_bfd_elf_set_osabi): Set the osasbi field to ELFOSABI_LINUX if
+ the binary contains ifunc symbols.
+ * elfcode.h (elf_slurp_symbol_table): Translate the STT_GNU_IFUNC
+ symbol type into a BSF_GNU_INDIRECT_FUNCTION flag.
+ * elf32-i386.c (is_indirect_function): New function.
+ (elf_i386_check_relocs): Create an ifunc output section.
+ (allocate_dynrelocs): Create dynamic relocs in the ifunc output
+ section if necessary.
+ (elf_i386_relocate_section): Emit a reloc against an ifunc symbol
+ if necessary.
+ (elf_i386_add_symbol_hook): New function. Set the
+ has_ifunc_symbols field of the elf_obj_data structure if an ifunc
+ symbol is encountered.
+ (elf_backend_post_process_headers): Define.
+ (elf_backend_add_symbol_hook): Define.
+ (elf_i386_post_process_headers): Rename to
+ elf_i388_fbsd_post_process_headers.
+ * elf64-x86_64.c (IS_X86_64_PCREL_TYPE): New macro.
+ (is_indirect_function): New function.
+ (elf64_x86_64_check_relocs): Create an ifunc output section.
+ (allocate_dynrelocs): Create dynamic relocs in the ifunc output
+ section if necessary.
+ (elf64_x86_64_relocate_section): Emit a reloc against an ifunc
+ symbol if necessary.
+ (elf_i386_add_symbol_hook): Set the has_ifunc_symbols field of the
+ elf_obj_data structure if an ifunc symbol is encountered.
+ (elf_backend_post_process_headers): Define.
+ * elflink.c (_bfd_elf_adjust_dynamic_symbol): Always create a PLT
+ if we have ifunc symbols to handle.
+ (get_ifunc_reloc_section_name): New function. Computes the name
+ for an ifunc section.
+ (_bfd_elf_make_ifunc_reloc_section): New function. Creates a
+ section to hold ifunc relocs.
+ * syms.c (BSF_GNU_INDIRECT_FUNCTION): Define.
+ (bfd_print_symbol_vandf): Handle ifunc symbols.
+ (bfd_decode_symclass): Likewise.
+ * bfd-in2.h: Regenerate.
+
+2009-04-30 Joseph Myers <joseph@codesourcery.com>
+
+ * elf32-arm.c (elf32_arm_check_relocs): Give errors for absolute
+ MOVW and MOVT relocations in a shared library link.
+
+2009-04-27 Anthony Green <green@moxielogic.com>
+
+ * verilog.c: New file.
+ * Makefile.am (BFD32_LIBS): Add verilog.c.
+ (BFD32_LIBS_CFILES): Add verilog.c.
+ (verilog.lo): New build rule.
+ * Makefile.in: Rebuilt.
+ * targets.c: Add verilog support.
+ * bfd.c (tdata union): Add Verilog private data field.
+ * bfd-in2.h: Regenerate.
+
+2009-04-27 H.J. Lu <hongjiu.lu@intel.com>
+
+ * peXXigen.c (_bfd_XX_bfd_copy_private_bfd_data_common): Don't
+ copy pe_opthdr.
+
+2009-04-23 Matthias Klose <doko@ubuntu.com>
+
+ * peXXigen.c (_bfd_XXi_swap_sym_in): Initialize `name'.
+
+2009-04-22 Christophe Lyon <christophe.lyon@st.com>
+
+ PR9743
+ * elf32-arm.c (arm_type_of_stub): Handle R_ARM_THM_JUMP24,
+ R_ARM_JUMP24 and R_ARM_PLT32 relocations.
+ (elf32_arm_size_stubs): Likewise.
+ (record_thumb_to_arm_glue): Deleted unused function.
+ (bfd_elf32_arm_process_before_allocation): No longer handle
+ R_ARM_THM_JUMP24, R_ARM_JUMP24 and R_ARM_PLT32 relocations here.
+ (elf32_arm_final_link_relocate): Handle R_ARM_THM_JUMP24,
+ R_ARM_JUMP24 and R_ARM_PLT32 relocations.
+
+2009-04-21 Daniel Jacobowitz <dan@codesourcery.com>
+
+ * elf32-arm.c (INTERWORK_FLAG): Check BFD_LINKER_CREATED.
+ (elf32_arm_write_section): Declare early.
+ (elf32_arm_size_stubs): Skip non-stub sections in the stub BFD.
+ (arm_allocate_glue_section_space): Exclude empty sections.
+ (ARM_GLUE_SECTION_FLAGS): Add SEC_LINKER_CREATED.
+ (bfd_elf32_arm_add_glue_sections_to_bfd): Do not skip the stub
+ BFD.
+ (elf32_arm_output_glue_section, elf32_arm_final_link): New.
+ (elf32_arm_merge_eabi_attributes): Skip the stub BFD.
+ (elf32_arm_size_dynamic_sections): Allocate interworking
+ sections here.
+ (bfd_elf32_bfd_final_link): Define.
+
+2009-04-21 H.J. Lu <hongjiu.lu@intel.com>
+
+ * coff-ia64.c (COFF_PAGE_SIZE): Changed to 8K.
+
+ * coffcode.h (coff_compute_section_file_positions): Clear
+ D_PAGED if PE section alignment is smaller than COFF_PAGE_SIZE.
+
+ * libcoff-in.h (pe_tdata): Remove force_minimum_alignment and
+ force_minimum_alignment.
+
+ * libcoff.h: Regenerated.
+
+ * pei-ia64.c (PEI_TARGET_SUBSYSTEM): Removed.
+ (PEI_FORCE_MINIMUM_ALIGNMENT): Likewise.
+
+ * peicode.h (pe_mkobject): Don't set force_minimum_alignment
+ nor target_subsystem.
+
+ * peXXigen.c (_bfd_XXi_swap_aouthdr_out): Don't check
+ force_minimum_alignment nor target_subsystem.
+
+2009-04-21 Kai Tietz <kai.tietz@onevision.com>
+
+ * coff-x86_64.c (PEI_HEADERS): Protect includes.
+ (bfd_pe_print_pdata): Remove #ifdef PE variation.
+ * pei-x86_64.c (PEI_HEADERS): Define to prevent double
+ include in coff-x86_64.c of headers.
+ (PDATA_ROW_SIZE): New define.
+ (pex_regs[]): New static array.
+ (pex64_get_runtime_function): New static function.
+ (pex64_get_unwind_info): Likewise.
+ (pex64_get_scope_entry): Likewise.
+ (pex64_xdata_print_uwd_codes): Likewise.
+ (pex64_get_section_by_rva): Likewise.
+ (pex64_dump_xdata): Likewise.
+ (pex64_bfd_print_pdata): Likewise.
+ (bfd_pe_print_pdata): Define as pex64_bfd_print_pdata.
+ * peXXigen.c (_bfd_pex64_print_pdata): Removed implementation.
+ * libpei.h (_bfd_pex64_print_pdata): Removed declaration.
+
+2009-04-19 Peter O'Gorman <binutils@mlists.thewrittenword.com>
+ Alan Modra <amodra@bigpond.net.au>
+ Dave Korn <dave.korn.cygwin@gmail.com>
+
+ * peXXigen.c (_bfd_XXi_swap_sym_in): Fix name handling w.r.t
+ long names and non-NUL-terminated strings.
+
+2009-04-17 H.J. Lu <hongjiu.lu@intel.com>
+
+ * bfd-in2.h: Regenerated.
+
+2009-04-17 H.J. Lu <hongjiu.lu@intel.com>
+
+ * peXXigen.c (_bfd_XX_print_private_bfd_data_common): Replace
+ IMAGE_SUBSYSTEM_EFI_ROM with IMAGE_SUBSYSTEM_SAL_RUNTIME_DRIVER.
+
+2009-04-17 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR binutils/10074
+ * coffcode.h (bfd_pei_p): New.
+
+ * config.bfd: Remove bfd_efi_bsdrv_ia32_vec,
+ bfd_efi_rtdrv_ia32_vec, bfd_efi_bsdrv_x86_64_vec,
+ bfd_efi_rtdrv_x86_64_vec, bfd_efi_bsdrv_ia64_vec and
+ bfd_efi_rtdrv_ia64_vec. Replace bfd_efi_app_ia32_vec,
+ bfd_efi_app_x86_64_vec and bfd_efi_app_ia64_vec with
+ i386pei_vec, x86_64pei_vec and bfd_pei_ia64_vec, respectively.
+
+ * configure.in: Remove bfd_efi_bsdrv_ia32_vec,
+ bfd_efi_rtdrv_ia32_vec, bfd_efi_bsdrv_x86_64_vec,
+ bfd_efi_rtdrv_x86_64_vec,
+ bfd_efi_bsdrv_ia64_vec and bfd_efi_rtdrv_ia64_vec. Replace
+ bfd_efi_ia64_vec with bfd_pei_ia64_vec.
+ * targets.c: Likewise.
+
+ * configure: Regenerated.
+ * libcoff.h: Likewise.
+ * Makefile.in: Likewise.
+
+ * efi-app-ia32.c: Removed.
+ * efi-app-x86_64.c: Likewise.
+ * efi-bsdrv-ia32.c: Likewise.
+ * efi-bsdrv-ia64.c: Likewise.
+ * efi-bsdrv-x86_64.c: Likewise.
+ * efi-rtdrv-ia32.c: Likewise.
+ * efi-rtdrv-ia64.c: Likewise.
+ * efi-rtdrv-x86_64.c: Likewise.
+ * efi-rtdrv-ia32.c: Likewise.
+
+ * efi-app-ia64.c: Moved to ...
+ * pei-ia64.c: This.
+ (TARGET_SYM): Set to bfd_pei_ia64_vec.
+ (TARGET_NAME): Set to pei-ia64.
+
+ * libpei.h (bfd_target_pei_p): Removed.
+ (bfd_target_pei_arch): Likewise.
+ (bfd_target_efi_app_p): Likewise.
+ (bfd_target_efi_app_arch): Likewise.
+ (bfd_target_efi_bsdrv_p): Likewise.
+ (bfd_target_efi_bsdrv_arch): Likewise.
+ (bfd_target_efi_rtdrv_p): Likewise.
+ (bfd_target_efi_rtdrv_arch): Likewise.
+ (bfd_pe_executable_p): Likewise.
+
+ * Makefile.am (BFD32_BACKENDS): Remove efi-app-ia32.lo,
+ efi-bsdrv-ia32.lo and efi-rtdrv-ia32.lo.
+ (BFD32_BACKENDS_CFILES): Remove efi-app-ia32.c, efi-bsdrv-ia32.c
+ and efi-rtdrv-ia32.c.
+ (BFD64_BACKENDS): Remove efi-app-ia64.lo, efi-bsdrv-ia64.lo,
+ efi-rtdrv-ia64.lo, efi-app-x86_64.lo, efi-bsdrv-x86_64.lo and
+ efi-rtdrv-x86_64.lo. Add pei-ia64.lo.
+ (BFD64_BACKENDS_CFILES): Remove efi-app-ia64.c, efi-bsdrv-ia64.c,
+ efi-rtdrv-ia64.c, efi-app-x86_64.c, efi-bsdrv-x86_64.c and
+ efi-rtdrv-x86_64.c. Add pei-ia64.c.
+ (efi-app-ia64.lo): Removed.
+ (efi-bsdrv-ia32.lo): Likewise.
+ (efi-rtdrv-ia32.lo): Likewise.
+ (efi-app-ia64.lo): Likewise.
+ (efi-bsdrv-ia64.lo): Likewise.
+ (efi-rtdrv-ia64.lo): Likewise.
+ (efi-app-x86_64.lo): Likewise.
+ (efi-bsdrv-x86_64.lo): Likewise.
+ (efi-rtdrv-x86_64.lo): Likewise.
+ (pei-ia64.lo): New.
+
+ * peicode.h (coff_swap_scnhdr_in): Replace bfd_pe_executable_p
+ with bfd_pei_p.
+ (arch_type): Removed.
+ (pe_arch): Likewise.
+ (pe_bfd_object_p): Just return coff_object_p.
+
+ * peXXigen.c (_bfd_XXi_swap_scnhdr_out): Replace
+ bfd_pe_executable_p with bfd_pei_p.
+
+2009-04-17 Christophe Lyon <christophe.lyon@st.com>
+
+ * elf32-arm.c (elf32_arm_size_stubs): Handle long branches through
+ PLT entries to an undefined symbol when generating a shared
+ library.
+
+2009-04-17 Nick Clifton <nickc@redhat.com>
+
+ PR 9909
+ * coffcode.h (handle_COMDAT): Allow for external COMDAT symbols.
+
+2009-04-16 Richard Sandiford <r.sandiford@uk.ibm.com>
+
+ * aout-adobe.c (aout_32_bfd_define_common_symbol): Define.
+ * aout-target.h (MY_bfd_define_common_symbol): Likewise.
+ * aout-tic30.c (MY_bfd_define_common_symbol): Likewise.
+ * binary.c (binary_bfd_define_common_symbol): Likewise.
+ * bout.c (b_out_bfd_define_common_symbol): Likewise.
+ * coff-alpha.c (_bfd_ecoff_bfd_define_common_symbol): Likewise.
+ * coff-mips.c (_bfd_ecoff_bfd_define_common_symbol): Likewise.
+ * coffcode.h (coff_bfd_define_common_symbol): Likewise.
+ * elfxx-target.h (bfd_elfNN_bfd_define_common_symbol): Likewise.
+ * i386msdos.c (msdos_bfd_define_common_symbol): Likewise.
+ * i386os9k.c (os9k_bfd_define_common_symbol): Likewise.
+ * ieee.c (ieee_bfd_define_common_symbol): Likewise.
+ * ihex.c (ihex_bfd_define_common_symbol): Likewise.
+ * libbfd-in.h (_bfd_nolink_bfd_define_common_symbol): Likewise.
+ * mach-o.c (bfd_mach_o_bfd_define_common_symbol): Likewise.
+ * mmo.c (mmo_bfd_define_common_symbol): Likewise.
+ * nlm-target.h (nlm_bfd_define_common_symbol): Likewise.
+ * oasys.c (oasys_bfd_define_common_symbol): Likewise.
+ * pef.c (bfd_pef_bfd_define_common_symbol): Likewise.
+ * ppcboot.c (ppcboot_bfd_define_common_symbol): Likewise.
+ * som.c (som_bfd_define_common_symbol): Likewise.
+ * srec.c (srec_bfd_define_common_symbol): Likewise.
+ * tekhex.c (tekhex_bfd_define_common_symbol): Likewise.
+ * versados.c (versados_bfd_define_common_symbol): Likewise.
+ * vms.c (vms_bfd_define_common_symbol): Likewise.
+ * xcoff-target.h (_bfd_xcoff_bfd_define_common_symbol): Likewise.
+ * xsym.c (bfd_sym_bfd_define_common_symbol): Likewise.
+ * coff-rs6000.c (rs6000coff_vec): Add _bfd_xcoff_define_common_symbol.
+ (pmac_xcoff_vec): Likewise.
+ * coff64-rs6000.c (rs6000coff64_vec): Likewise.
+ (aix5coff64_vec): Likewise.
+ * linker.c (bfd_generic_define_common_symbol): New function.
+ * targets.c (BFD_JUMP_TABLE_LINK): Add NAME##_bfd_define_common_symbol.
+ (_bfd_define_common_symbol): New field.
+ * libcoff-in.h (_bfd_xcoff_define_common_symbol): Declare.
+ * xcofflink.c (_bfd_xcoff_define_common_symbol): New function.
+ (xcoff_build_ldsyms): Don't set XCOFF_DEF_REGULAR for common
+ symbols here.
+ * bfd-in2.h: Regenerate.
+ * libbfd.h: Likewise.
+ * libcoff.h: Likewise.
+
+2009-04-15 Anthony Green <green@moxielogic.com>
+
+ * targets.c: Add moxie support.
+ * Makefile.am: Ditto.
+ * Makefile.in: Rebuilt.
+ * cpu-moxie.c, elf32-moxie.c: New files.
+ * archures.c: Add moxie support.
+ * configure.in: Add moxie support.
+ * configure: Rebuilt.
+ * config.bfd, archures.c: Add moxie support.
+ * bfd-in2.h: Rebuilt.
+
+2009-04-15 Christophe Lyon <christophe.lyon@st.com>
+
+ * elf32-arm.c (elf32_arm_final_link_relocate): Don't convert ARM
+ branch to an undef weak symbol into a jump to next instruction if
+ a PLT entry will be created.
+
+2009-04-14 Dave Korn <dave.korn.cygwin@gmail.com>
+
+ * coffgen.c (make_a_section_from_file): Set the backend long
+ section names enable if long section names found on input.
+ * coffcode.h: Extend long section names documentation to match.
+
+2009-04-08 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elflink.c (elf_link_add_object_symbols): Warn alternate ELF
+ machine code.
+
+2009-04-07 DJ Delorie <dj@redhat.com>
+
+ * archures.c: Add bfd_mach_mep_c5.
+ * bfd-in2.h: Likewise.
+ * cpu-mep.c: Add bfd_c5_arch.
+ * elf32-mep.c: Support it.
+
+2009-04-07 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elflink.c (_bfd_elf_section_already_linked): Add `\n' for
+ info->callbacks->einfo.
+ * linker.c (_bfd_generic_section_already_linked): Likewise.
+
+2009-04-06 DJ Delorie <dj@redhat.com>
+
+ * elf32-h8300.c (elf32_h8_relax_section): Relax MOVA opcodes.
+
+2009-04-06 H.J. Lu <hongjiu.lu@intel.com>
+
+ * coff-x86_64.c (bfd_pe_print_pdata): Defined to
+ _bfd_pex64_print_pdata only if PE is defined.
+
+ * libpei.h (_bfd_pep_print_x64_pdata): Renamed to ...
+ (_bfd_pex64_print_pdata): This.
+
+ * peXXigen.c (_bfd_pep_print_x64_pdata): Renamed to ...
+ (_bfd_pex64_print_pdata): This. Defined only if COFF_WITH_pex64
+ is defined.
+
+2009-04-05 Kai Tietz <kai.tietz@onevision.com>
+
+ * coff-x86_64.c (bfd_pe_print_pdata): Define as
+ _bfd_pep_print_x64_pdata.
+ * libpei.h (_bfd_pep_print_x64_pdata): Add prototype.
+ * peXXigen.c (_bfd_pep_print_x64_pdata): New.
+
+2009-04-02 Sterling Augustine <sterling@jaw.hq.tensilica.com>
+
+ * elf32-xtensa.c (relax_property_section): Always set r_offset
+ to zero.
+
+2009-04-02 Christophe Lyon <christophe.lyon@st.com>
+
+ * elf32-arm.c (elf32_arm_stub_long_branch_v4t_thumb_thumb,
+ elf32_arm_stub_long_branch_v4t_thumb_thumb_pic): Two new long
+ branch stubs.
+ (elf32_arm_stub_type): New enum values for the two new stubs.
+ (arm_type_of_stub): Make use of the two new stubs.
+ (arm_size_one_stub): Handle the two new stubs.
+
+2009-04-01 Matt Thomas <matt@netbsd.org>
+
+ * elf32-vax.c (elf_vax_check_relocs): Do not put relocations against
+ hidden symbols into the GOT or PLT.GOT.
+ (elf_vax_relocate_section): Do not emit a PCREL reloc
+ into a shared object if it is against a hidden symbol.
+
+2009-04-01 Richard Sandiford <r.sandiford@uk.ibm.com>
+
+ * xcofflink.c (xcoff_archive_info): Add contains_shared_object_p
+ and know_contains_shared_object_p.
+ (xcoff_archive_contains_shared_object_p): Add an "info" parameter.
+ Cache the result in the archive_info table.
+ (xcoff_auto_export_p): Add an "info" parameter and update the
+ call to xcoff_archive_contains_shared_object_p.
+ (xcoff_mark_auto_exports): Update accordingly.
+ (xcoff_post_gc_symbol): Likewise.
+
+2009-04-01 Richard Sandiford <r.sandiford@uk.ibm.com>
+
+ * xcofflink.c (bfd_link_input_bfd): Treat __rtinit as C_HIDEXT
+ rather than C_EXT.
+
+2009-04-01 Richard Sandiford <r.sandiford@uk.ibm.com>
+
+ * coff-rs6000.c (member_layout): New structure.
+ (archive_iterator): Likewise.
+ (member_layout_init): New function.
+ (archive_iterator_begin): Likewise.
+ (archive_iterator_next): Likewise.
+ (xcoff_write_armap_old): Use the new iterator functions.
+ (do_shared_object_padding): Delete.
+ (xcoff_write_armap_big): Use the new iterator functions. Simplify
+ handling of arch_info.
+ (xcoff_write_archive_contents_old): Allocate arelt_data in the
+ first loop rather than the second. Allocate a member header if
+ there isn't one, then work out the stat information and length
+ in the first loop too. Use the new iterators for the second loop.
+ (xcoff_write_archive_contents_big): Likewise.
+
+2009-04-01 Richard Sandiford <r.sandiford@uk.ibm.com>
+
+ * bfd-in.h (bfd_xcoff_split_import_path): Declare.
+ (bfd_xcoff_set_archive_import_path): Likewise.
+ * bfd-in2.h: Regenerate.
+ * xcofflink.c: Include libiberty.h.
+ (xcoff_archive_info): New structure.
+ (xcoff_archive_info_hash): New function.
+ (xcoff_archive_info_eq): Likewise.
+ (xcoff_get_archive_info): Likewise.
+ (_bfd_xcoff_bfd_link_hash_table_create): Initialize archive_info.
+ (bfd_xcoff_split_import_path): New function.
+ (bfd_xcoff_set_archive_import_path): Likewise.
+ (xcoff_set_import_path): Move earlier in file.
+ (xcoff_link_add_dynamic_symbols): Set the import path of a non-archive
+ object to the directory part of the bfd's filename. Get the
+ import path and filename of an archive object from the archive's
+ xcoff_tdata, initializing it if necessary. Update use of
+ import_file_id.
+ (bfd_link_input_bfd): Update use of import_file_id.
+ (xcoff_write_global_symbol): Likewise.
+
+2009-04-01 Richard Sandiford <r.sandiford@uk.ibm.com>
+
+ * xcofflink.c (xcoff_link_hash_table): Moved from include/coff/xcoff.h.
+
+2009-04-01 Richard Sandiford <r.sandiford@uk.ibm.com>
+
+ * xcofflink.c (xcoff_link_create_extra_sections): Don't create
+ a .loader section for relocatable links.
+ (xcoff_need_ldrel_p): New function.
+ (xcoff_mark): Use it.
+ (bfd_xcoff_link_count_reloc): Only count loader relocs if there's
+ a loader section.
+ (xcoff_build_ldsym): New function, split out from...
+ (xcoff_build_ldsyms): ...here. Rename to...
+ (xcoff_post_gc_symbol): ...this. Only export symbols, and only
+ call xcoff_build_ldsym, if there's a loader section.
+ (xcoff_build_loader_section): New function, extracted verbatim from...
+ (bfd_xcoff_size_dynamic_sections): ...here. Only call it if
+ there's a loader section. Only add an __rtinit loader symbol
+ if there's a loader section. Update after above name change.
+ (xcoff_symbol_section, xcoff_create_ldrel): New functions.
+ (bfd_link_input_bfd): Use xcoff_need_ldrel_p, xcoff_symbol_section
+ and xcoff_create_ldrel.
+ (xcoff_write_global_symbol): Use xcoff_create_ldrel.
+ (xcoff_reloc_link_order): Likewise, but only call it if there's
+ a loader section. Use xcoff_symbol_section.
+ (_bfd_xcoff_bfd_final_link): Only use fdinfo.ldrel and fdinfo.ldsym
+ if there's a loader section.
+
+2009-04-01 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * xcofflink.c (bfd_link_input_bfd): Fix buffer overrun.
+
+2009-04-01 Christophe Lyon <christophe.lyon@st.com>
+
+ * elf32-arm.c (group_sections): Rewrite loops for better
+ readability.
+
+2009-03-30 DJ Delorie <dj@redhat.com>
+
+ * elflink.c (elf_link_input_bfd): Don't try to resolve complex
+ relocs when doing a relocatable link.
+
+2009-03-28 Mark Mitchell <mark@codesourcery.com>
+
+ * coff-arm.c (coff_arm_merge_private_bfd_data): Use "error:", not
+ "ERROR:", in error messages.
+ * cpu-arm.c (bfd_arm_merge_machines): Likewise.
+ * elf-attrs.c (_bfd_elf_merge_object_attributes): Likewise.
+ * elf32-arm.c (tag_cpu_arch_combine): Likewise.
+ (elf32_arm_merge_eabi_attributes): Likewise.
+ (elf32_arm_merge_private_bfd_data): Likewise.
+
+2009-03-27 Nick Clifton <nickc@redhat.com>
+
+ * section.c (bfd_get_section_contents): Detect and handle the case
+ where a section has the SEC_IN_MEMORY flag set but no actual
+ contents allocated.
+
+2009-03-26 Alan Modra <amodra@bigpond.net.au>
+
+ PR 6494
+ * elf.c (copy_elf_program_header): Do not check that PT_GNU_RELRO
+ p_filesz and p_memsz are equal. Use p_memsz as the segment size.
+ (assign_file_positions_for_non_load_sections): Zap PT_GNU_RELRO
+ if we don't find matching PT_LOAD when copying.
+
+2009-03-25 M R Swami Reddy <MR.Swami.Reddy@nsc.com>
+
+ * elf32-crx.c (crx_elf_howto_table): Zero the src_mask field of
+ the reloc descriptions.
+
+2009-03-25 Hans-Peter Nilsson <hp@axis.com>
+
+ * elf32-cris.c (cris_elf_relocate_section) <case R_CRIS_32_GD>
+ <R_CRIS_16_GOT_GD, case R_CRIS_32_GOT_GD>: Handle COMMON symbols.
+ <case R_CRIS_16_TPREL, R_CRIS_32_TPREL>: Ditto.
+
+2009-03-24 H.J. Lu <hongjiu.lu@intel.com>
+
+ * cpu-i386.c (bfd_x86_64_arch_intel_syntax): Make it static.
+ (bfd_i386_arch_intel_syntax): Likewise.
+ (i8086_arch): Likewise.
+ (bfd_x86_64_arch): Likewise.
+
+2009-03-24 Hans-Peter Nilsson <hp@axis.com>
+
+ * elf32-cris.c (cris_elf_relocate_section): <case
+ R_CRIS_16_DTPREL, R_CRIS_32_DTPREL>: Allow use of non-local
+ symbols for non-allocated sections. Don't check whether to
+ generate R_CRIS_DTPMOD for non-allocated sections.
+ (cris_elf_gc_sweep_hook) <case R_CRIS_32_DTPREL>: Don't
+ handle relocation GC:ing if applied to non-allocated section.
+ (cris_elf_check_relocs): Similar.
+
+ * elf32-cris.c (cris_elf_relocate_section) <case R_CRIS_32_GD>
+ <R_CRIS_16_GOT_GD, R_CRIS_32_GOT_GD>: Don't include the TLS size
+ when emitting a known TP offset in the GOT.
+
+2009-03-23 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (synthetic_opd): Delete.
+ (compare_symbols): Look for .opd name rather than section match.
+ (ppc64_elf_get_synthetic_symtab): Likewise.
+
+2009-03-21 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-ppc.c (is_pic_glink_stub): Delete.
+ (is_nonpic_glink_stub): New function.
+ (ppc_elf_get_synthetic_symtab): Check for last non-pic stub rather
+ than first pic one.
+ (struct ppc_elf_link_hash_table <glink_pltresolve>): Comment fix.
+
+2009-03-20 Martin Schwidefsky <schwidefsky@de.ibm.com>
+ Andreas Krebbel <Andreas.Krebbel@de.ibm.com>
+
+ * elf32-s390.c (elf_s390_check_relocs): Use the SYMBOL_*
+ macros for visibilty and locality checks.
+ (elf_s390_adjust_dynamic_symbol): Likewise.
+ (allocate_dynrelocs): Likewise.
+ (elf_s390_relocate_section): Likewise.
+ (elf_s390_finish_dynamic_symbol): Likewise.
+ * elf64-s390.c (elf_s390_check_relocs): Likewise.
+ (elf_s390_adjust_dynamic_symbol): Likewise.
+ (allocate_dynrelocs): Likewise.
+ (elf_s390_relocate_section): Likewise.
+ (elf_s390_finish_dynamic_symbol): Likewise.
+
+2009-03-19 Kai Tietz <kai.tietz@onevision.com>
+
+ * bfd-in2.h: Regenerated.
+ * coffcode.h (sec_to_styp_flags): For pe-coff add SEC_READONLY
+ for debugging sections and map memory read/write dependent on
+ SEC_COFF_NOREAD.
+ (styp_to_sec_flags): Set SEC_COFF_NOREAD for sections
+ without memory read flags set.
+ * section.c: Add SEC_COFF_NOREAD to section flags.
+
+2009-03-19 Andreas Schwab <schwab@linux-m68k.org>
+
+ * elf32-hppa.c (final_link_relocate): Cast bfd_vma values to long
+ for format string.
+
+2009-03-19 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-spu.c (spu_elf_find_overlays): Separate error return from
+ "no overlays" return. If there are overlays, create overlay
+ manager entry symbols here, so that..
+ (spu_elf_build_stubs): ..we don't need to set them up here.
+ Simplify entry symbol tests.
+ * elf32-spu.h (spu_elf_find_overlays): Update prototype.
+
+2009-03-18 Mark Kettenis <kettenis@gnu.org>
+
+ * elf.c (elfcore_grok_openbsd_procinfo)
+ (elfcore_grok_openbsd_note): New functions.
+ (elf_parse_notes): Handle notes from OpenBSD ELF core files.
+
+2009-03-18 Alan Modra <amodra@bigpond.net.au>
+
+ * vms-hdr.c: Don't include alloca.h.
+ * elf32-m68hc1x.c: Include alloca-conf.h.
+ * xsym.c: Likewise.
+ * elf64-hppa.c: Likewise. Remove existing #if's handling alloca.
+ * som.c: Likewise.
+ * Makefile.am: Run "make dep-am".
+ * Makefile.in: Regenerate.
+
+2009-03-17 Daniel Jacobowitz <dan@codesourcery.com>
+
+ * elf32-arm.c (elf32_arm_check_relocs): Correct symbian_p test.
+
+2009-03-17 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-spu.h (struct spu_elf_params): ovly_flavour now only 1 bit.
+ Add compact_stub.
+ (emum _ovly_flavour): Delete ovly_compact, ovly_none.
+ * elf32-spu.c (struct spu_link_hash_table): Replace ovly_load and
+ ovly_return fields with ovly_entry[2]. Adjust all users.
+ (spu_elf_find_overlays): Set ovly_entry[1] from __icache_call_handler
+ when soft-icache.
+ (spu_elf_build_stubs): Likewise.
+ (ovl_stub_size): Change arg to spu_elf_params pointer. Adjust for
+ ovly_flavour changes. Update all callers.
+ (ovl_stub_size_log2): New function.
+ (build_stub): Handle compact icache stubs. Use different manager
+ entry point for stubs in non-icache area.
+ (spu_elf_size_stubs): Don't allocate space for indirect branch
+ descriptors.
+ (spu_elf_build_stubs): And don't built them.
+
+2009-03-16 Andrew Stubbs <ams@codesourcery.com>
+
+ * dwarf2.c (read_section): Always use rawsize, if available.
+
+2009-03-16 Alan Modra <amodra@bigpond.net.au>
+
+ * simple.c (bfd_simple_get_relocated_section_contents): Use larger
+ of rawsize and size for buffer.
+
+2009-03-15 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * elf32-spu.c (spu_elf_check_vma): Do not reset auto_overlay
+ parameter just because fixed sections fit into local store.
+ (spu_elf_auto_overlay): Do not declare as "noreturn". Skip
+ generating overlays if fixed sections plus reserved stack
+ and heap space fit into local store.
+
+2009-03-15 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-spu.c (build_stub): Correct icache set_id.
+ (spu_elf_relocate_section): Likewise.
+
+2009-03-14 Richard Sandiford <r.sandiford@uk.ibm.com>
+
+ * xcofflink.c (xcoff_link_check_archive_element): Only free the
+ symbol table if it was created by the current call.
+
+2009-03-14 Richard Sandiford <r.sandiford@uk.ibm.com>
+
+ * xcofflink.c (xcoff_build_ldsyms): Give imported descriptors
+ class XMC_DS rather than XMC_UA.
+
+2009-03-14 Richard Sandiford <r.sandiford@uk.ibm.com>
+
+ * bfd-in.h (bfd_xcoff_size_dynamic_sections): Replace the
+ bfd_boolean export_defineds parameter with an unsigned int
+ auto_export_flags parameter.
+ * bfd-in2.h: Regenerate.
+ * xcofflink.c (xcoff_archive_contains_shared_object_p): New function,
+ split out from xcoff_build_ldsyms.
+ (xcoff_covered_by_expall_p): New function.
+ (xcoff_auto_export_p): New function, split out from xcoff_build_ldsyms
+ but with extra code to handle -bexpfull and -bexpall.
+ (xcoff_mark_auto_exports): New function.
+ (xcoff_build_ldsyms): Use xcoff_auto_export_p to decide whether
+ a function should be automatically exported.
+ (bfd_xcoff_size_dynamic_sections): Replace the export_defineds
+ parameter with an auto_export_flags parameter. Update ldinfo
+ accordingly. Use xcoff_mark_auto_exports to mark all automatically-
+ exported symbols.
+
+2009-03-14 Richard Sandiford <r.sandiford@uk.ibm.com>
+
+ * xcofflink.c (xcoff_mark_symbol_by_name): New function.
+ (bfd_xcoff_size_dynamic_sections): Use it to mark the entry,
+ init and fini functions. Do garbage collection for objects
+ without an entry point too.
+
+2009-03-14 Richard Sandiford <r.sandiford@uk.ibm.com>
+
+ * coffcode.h (coff_pointerize_aux_hook): Update CSECT_SYM_P to
+ check whether a symbol has csect information.
+ (coff_print_aux): Likewise.
+ * coff-rs6000.c (_bfd_xcoff_swap_aux_in): Handle auxillary csect
+ information for C_AIX_WEAKEXT too.
+ (_bfd_xcoff_swap_aux_out): Likewise.
+ (xcoff_reloc_type_br): Handle defweak symbols too.
+ * coff64-rs6000.c (_bfd_xcoff64_swap_aux_in): Handle auxillary csect
+ information for C_AIX_WEAKEXT too.
+ (_bfd_xcoff64_swap_aux_out): Likewise.
+ (xcoff64_reloc_type_br): Handle defweak symbols too.
+ * coffgen.c (coff_print_symbol): Handle auxillary function
+ information for C_AIX_WEAKEXT too.
+ * xcofflink.c (_bfd_xcoff_canonicalize_dynamic_symtab): Set BSF_WEAK
+ instead of BSF_GLOBAL if the L_WEAK flag is set.
+ (xcoff_dynamic_definition_p): New function.
+ (xcoff_link_add_dynamic_symbols): Use it to decide whether ldsym
+ defines h. Don't change h if ldsym isn't the definition. Otherwise,
+ always take the symbol class from the ldsym. Use weak bfd symbol
+ types for weak ldsyms.
+ (xcoff_link_add_symbols): Use CSECT_SYM_P and EXTERN_SYM_P.
+ Fix the check for whether a definition is from a shared object.
+ Allow redefinitions of weak symbols.
+ (xcoff_link_check_ar_symbols): Use EXTERN_SYM_P.
+ (xcoff_keep_symbol_p): Likewise.
+ (bfd_xcoff_size_dynamic_sections): Use CSECT_SYM_P.
+ (xcoff_link_input_bfd): Use CSECT_SYM_P and EXTERN_SYM_P.
+ Add .loader entries for C_AIX_WEAKEXT as well as C_EXT symbols,
+ but mark them as L_WEAK.
+ (xcoff_write_global_symbol): Treat weak symbols as C_AIX_WEAKEXT
+ instead of C_EXT if C_AIX_WEAKEXT == C_WEAKEXT.
+
+2009-03-14 Richard Sandiford <r.sandiford@uk.ibm.com>
+
+ * xcofflink.c (xcoff_mark): When walking the relocations,
+ only mark the target symbol or the target section, not both.
+ (xcoff_final_definition_p): New function.
+ (xcoff_keep_symbol_p): Use it to check whether an external XCOFF
+ symbol is a valid definition of the associated output symbol.
+ Use XCOFF_ALLOCATED to stop the same hash table entry having
+ two output symbols.
+ (bfd_xcoff_size_dynamic_sections): Set XCOFF_ALLOCATED when
+ keeping a symbol.
+ (xcoff_link_input_bfd): Use xcoff_final_definition_p.
+
+2009-03-14 Richard Sandiford <r.sandiford@uk.ibm.com>
+
+ * xcofflink.c (bfd_xcoff_import_symbol): Treat imported absolute
+ symbols as XMC_XO.
+
+2009-03-14 Richard Sandiford <r.sandiford@uk.ibm.com>
+
+ * libcoff-in.h (xcoff_tdata): Add a lineno_counts field.
+ * libcoff.h: Regenerate.
+ * xcofflink.c (xcoff_link_add_symbols): Record per-symbol
+ line-number counts in the bfd's lineno_counts field.
+ Don't keep per-csect line-number counts.
+ (xcoff_sweep): Don't update per-csect line-number counts.
+ (bfd_xcoff_size_dynamic_sections): Count the number of line-number
+ entries in each output section.
+ (xcoff_link_input_bfd): Get the number of line numbers from
+ the bfd's lineno_counts field, rather than recalculating it
+ from scratch. Fix the range check when updating C_BINCL and
+ C_EINCL symbols.
+ (_bfd_xcoff_bfd_final_link): Don't count the output line numbers
+ here. Don't expect csects to have line-number counts.
+
+2009-03-14 Richard Sandiford <r.sandiford@uk.ibm.com>
+
+ * libcoff-in.h (xcoff_tdata): Change debug_indices to a signed long.
+ * libcoff.h: Regenerate.
+ * xcofflink.c (xcoff_keep_symbol_p): New function, using the
+ "skip" logic from xcoff_link_input_bfd.
+ (bfd_xcoff_size_dynamic_sections): Explicitly skip dynamic
+ objects in a dynamic link, rather than checking whether csectpp
+ is null. Always allocate debug_index for other objects,
+ and always go through the loop. Update the type of debug_index
+ after the change above. Read the auxillary csect information
+ and use xcoff_keep_symbol_p to decide whether a symbol should
+ be kept. Set its debug_index to -2 if not.
+ (xcoff_link_input_bfd): Update the type of debug_index after
+ the change above and always expect it to be nonnull. Use it to
+ test whether a symbol should be stripped, rather than making the
+ decision here. Postpone all symbol creation to the second pass.
+
+2009-03-14 Richard Sandiford <r.sandiford@uk.ibm.com>
+
+ * xcofflink.c: (xcoff_mark_symbol): Mark the TOC section when
+ creating a descriptor.
+ (xcoff_sweep): Don't mark toc_section unless it's needed.
+ (bfd_xcoff_size_dynamic_sections): Skip the toc_section
+ when marking every bfd.
+ (xcoff_link_input_bfd): Skip all TOC anchors.
+ (xcoff_toc_section_p, xcoff_find_tc0): New functions.
+ (_bfd_xcoff_bfd_final_link): Don't set the output bfd's TOC anchor
+ to -1; call xcoff_find_tc0 instead.
+
+2009-03-14 Richard Sandiford <r.sandiford@uk.ibm.com>
+
+ * libcoff-in.h (xcoff_section_tdata): Update commentary.
+ * libcoff.h: Regenerate.
+ * xcofflink.c (xcoff_link_add_symbols): Set the csect of XTY_ER
+ symbols to bfd_und_section_ptr or bfd_abs_section_ptr, rather than
+ the previous symbol's csect. Treat last_symndx as an inclusive value
+ and simplify its handling.
+ (xcoff_mark): Treat last_symndx as an inclusive value. Only mark
+ symbols with the right csect. Don't mark rsec when processing
+ relocations against undefined or absolute sections.
+ (bfd_xcoff_size_dynamic_sections): Don't check the SEC_MARK flag
+ of bfd_und_section_ptr.
+ (xcoff_link_input_bfd): Likewise.
+
+2009-03-14 Richard Sandiford <r.sandiford@uk.ibm.com>
+
+ * coff-rs6000.c (xcoff_ppc_relocate_section): Report relocations
+ against undefined symbols if the symbol's XCOFF_WAS_UNDEFINED
+ flag is set. Assert that all undefined symbols are either
+ imported or defined by a dynamic object.
+ * coff64-rs6000.c (xcoff64_ppc_relocate_section): Likewise.
+ * xcofflink.c (xcoff_link_add_symbols): Extend function-symbol
+ handling to all relocations. Only set XCOFF_CALLED for function
+ symbols.
+ (xcoff_find_function): New function, split out from...
+ (bfd_xcoff_export_symbol) ...here.
+ (xcoff_set_import_path): New function, split out from...
+ (bfd_xcoff_import_symbol): ...here. Remove assertion for old
+ meaning of XCOFF_CALLED.
+ (xcoff_mark_symbol): If we mark an undefined and unimported
+ symbol, find some way of defining it. If the symbol is a function
+ descriptor, fill in its definition automatically. If the symbol
+ is a function, mark its descriptor and allocate room for global
+ linkage code. Otherwise mark the symbol as implicitly imported.
+ Move the code for creating function descriptors from...
+ (xcoff_build_ldsyms): ...here. Use XCOFF_WAS_UNDEFINED to
+ check for symbols that were implicitly defined.
+ (xcoff_mark): Don't count any dynamic relocations against
+ function symbols.
+ (bfd_xcoff_size_dynamic_sections): Save the rtld parameter
+ in the xcoff link info.
+ (xcoff_link_input_bfd): Remove handling of undefined and
+ unexported symbols.
+
+2009-03-14 Richard Sandiford <r.sandiford@uk.ibm.com>
+
+ * coff-rs6000.c (xcoff_reloc_type_br): Make the branch absolute
+ if the target is absolute. Fix comment typo.
+ (xcoff_ppc_relocate_section): Remove FIXME.
+ * coff64-rs6000.c (xcoff64_reloc_type_br): Make the branch absolute
+ if the target is absolute.
+
+2009-03-14 Richard Sandiford <r.sandiford@uk.ibm.com>
+
+ * xcofflink.c (xcoff_mark, xcoff_link_input_bfd): Don't copy
+ R_POS and R_NEG relocations against absolute symbols to the
+ .loader section.
+
+2009-03-14 Richard Sandiford <r.sandiford@uk.ibm.com>
+
+ * coff64-rs6000.c (xcoff64_write_object_contents): Set the cputype
+ to 2 for bfd_mach_ppc_620.
+
+2009-03-14 Richard Sandiford <r.sandiford@uk.ibm.com>
+
+ * config.bfd: Treat AIX 6+ in the same way as AIX 5.
+ * configure.in: Likewise.
+ * configure: Regenerate.
+
+2009-03-13 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR binutils/9945
+ * elf.c (assign_section_numbers): Generate symbol table if there
+ is any relocation in output.
+ (_bfd_elf_compute_section_file_positions): Likewise.
+
+2009-03-13 Nick Clifton <nickc@redhat.com>
+
+ PR 9934
+ * elf-bfd.h (NUM_SHDR_ENTRIES): Cope with an empty section.
+ * elflink.c (elf_link_read_relocs_from_section): Use
+ NUM_SHDR_ENTRIES. Gracefully handle the case where there are
+ relocs but no symbol table.
+ * elf32-arm.c (elf32_arm_check_relocs): Likewise.
+
+2009-03-12 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/9938
+ * elf32-i386.c (elf_i386_check_tls_transition): Use strncmp
+ to check ___tls_get_addr.
+
+ * elf64-x86-64.c (elf64_x86_64_check_tls_transition): Use
+ strncmp to check __tls_get_addr.
+
+2009-03-12 Andrew Stubbs <ams@codesourcery.com>
+
+ * dwarf2.c (read_section): Always check the offset, even when the
+ section has been read before.
+
+2009-03-11 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf32-i386.c (elf_i386_check_tls_transition): Fix a typo in
+ comments.
+
+2009-03-11 Chris Demetriou <cgd@google.com>
+
+ * bfd.c (BFD_DETERMINISTIC_OUTPUT): New flag.
+ * bfd-in2.h: Regenerate.
+ * archive.c (bfd_ar_hdr_from_filesystem): If BFD_DETERMINISTIC_OUTPUT
+ flag is set, use 0 for uid, gid, and timestamp, and use 0644 for file
+ mode.
+ (bsd_write_armap): Likewise.
+ (_bfd_archive_bsd_update_armap_timestamp): If BFD_DETERMINISTIC_OUTPUT
+ flag is set, do nothing.
+ (coff_write_armap): If BFD_DETERMINISTIC_OUTPUT flag is set, use 0
+ for timestamp.
+
+2009-03-11 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * elf32-spu.c (find_function_stack_adjust): Handle sf instruction
+ used to update stack pointer.
+
+2009-03-07 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ PR binutils/9921
+ * som.c (som_bfd_derive_misc_symbol_info): Set symbol type ST_ABSOLUTE
+ for unknown symbols in absolute section.
+
+2009-03-06 Nick Clifton <nickc@redhat.com>
+
+ * po/es.po: Updated Spanish translation.
+
+2009-03-05 Christophe Lyon <christophe.lyon@st.com>
+
+ * elf32-arm.c (group_sections): Take next section size into
+ account before accepting to group it.
+
+2009-03-05 Christophe Lyon <christophe.lyon@st.com>
+
+ * elf32-arm.c (arm_type_of_stub): Handle long branches targetting
+ PLT entries.
+ (elf32_arm_final_link_relocate): Likewise.
+
+2009-03-05 Moritz Kroll <Moritz.Kroll@gmx.de>
+
+ PR 9923
+ * peXXigen.c (_bfd_XXi_final_link_postscript): Check h->root.type.
+
+2009-03-04 Alan Modra <amodra@bigpond.net.au>
+
+ * reloc.c (BFD_RELOC_PPC_TLSGD, BFD_RELOC_PPC_TLSLD): New.
+ * section.c (struct bfd_section): Add has_tls_get_addr_call.
+ (BFD_FAKE_SECTION): Init new flag.
+ * ecoff.c (bfd_debug_section): Likewise.
+ * bfd-in2.h: Regenerate.
+ * libbfd.h: Regenerate.
+ * elf32-ppc.c (ppc_elf_howto_raw): Add R_PPC_TLSGD and R_PPC_TLSLD.
+ (ppc_elf_reloc_type_lookup): Handle new relocs.
+ (ppc_elf_check_relocs): Set has_tls_get_addr_call on finding such
+ without marker relocs.
+ (ppc_elf_tls_optimize): Allow out-of-order __tls_get_addr relocs
+ if section has no old-style calls.
+ (ppc_elf_relocate_section): Set tls_mask for non-tls relocs too.
+ Don't try to optimize new-style __tls_get_addr call when handling
+ arg setup relocs. Instead do so for R_PPC_TLSGD and R_PPC_TLSLD
+ relocs.
+ * elf64-ppc.c (ppc64_elf_howto_raw): Add R_PPC64_TLSGD, R_PPC64_TLSLD.
+ (ppc64_elf_reloc_type_lookup): Handle new relocs.
+ (ppc64_elf_check_relocs): Set has_tls_get_addr_call on finding such
+ without marker relocs.
+ (ppc64_elf_tls_optimize): Allow out-of-order __tls_get_addr relocs
+ if section has no old-style calls. Set toc_ref for new relocs as
+ appropriate.
+ (ppc64_elf_relocate_section): Set tls_mask for non-tls relocs too.
+ Don't try to optimize new-style __tls_get_addr call when handling
+ arg setup relocs. Instead do so for R_PPC_TLSGD and R_PPC_TLSLD
+ relocs.
+
+2009-03-04 Alan Modra <amodra@bigpond.net.au>
+
+ PR 6768
+ * configure.in: Test for ld --as-needed support. Link shared
+ libbfd against libm.
+ * configure: Regenerate.
+
+2009-03-03 Alan Modra <amodra@bigpond.net.au>
+
+ * Makefile.am: Run "make dep-am".
+ * Makefile.in: Regenerate.
+
+2009-03-02 Qinwei <qinwei@sunnorth.com.cn>
+
+ * elf32-score7.c: New file.
+ * elf32-score.h: New file.
+ * elf32-score.c: Add code to support score 7. Set score7 as the
+ default.
+ * cpu-score.c: Add score7 architecure.
+ (compatibile): New function.
+ * Makefile.am: Add rules for building elf32-score7 object.
+ * Makefile.in: Regenerate.
+ * configure.in: Add elf32-score7 object to score vectors.
+ * configure: Regenerate.
+ * reloc.c: Add score7 relocs.
+ * archures.c: Add score3 and score7 machine numbers.
+ * bfd-in2.h: Regenerate.
+ * libbfd.h: Regenerate.
+
+2009-03-01 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
+
+ * configure: Regenerate.
+
+2009-03-01 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ * elf32-hppa.c (hppa32_elf_local_refcounts): New function.
+ (elf32_hppa_check_relocs): Use it.
+
+ * elf_hppa_add_symbol_hook (elf_hppa_add_symbol_hook): Move to
+ elf64-hppa.c.
+ (elf_hppa_unmark_useless_dynamic_symbols): Likewise.
+ (elf_hppa_remark_useless_dynamic_symbols): Likewise.
+ (elf_hppa_is_dynamic_loader_symbol): Likewise.
+ (elf_hppa_record_segment_addrs): Likewise.
+ (elf_hppa_final_link): Likewise.
+ (elf_hppa_relocate_insn): Likewise.
+ (elf_hppa_final_link_relocate): Likewise.
+ (elf64_hppa_relocate_section): Likewise.
+ * elf64-hppa.c: Insert above.
+
+2009-02-28 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ * elf-hppa.h (elf_hppa_final_link): Use elf_hppa_final_link.
+ (elf_hppa_final_link_relocate ): Rewrite eliminating dynamic hash table.
+ (elf_hppa_relocate_section): Likewise.
+ * elf64-hppa.c (struct elf64_hppa_link_hash_entry): Change to derive
+ from struct elf_link_hash_entry. Add count field.
+ (struct elf64_hppa_dyn_hash_table): Delete.
+ (struct elf64_hppa_link_hash_table): Delete dyn_hash_table field.
+ (elf64_hppa_hash_table): Rename to hppa_link_hash_table.
+ (hppa_elf_hash_entry, eh_name): Define.
+ (elf64_hppa_new_dyn_hash_entry): Delete.
+ (elf64_hppa_dyn_hash_lookup): Delete.
+ (elf64_hppa_dyn_hash_traverse): Delete.
+ (get_dyn_name): Delete.
+ (elf64_hppa_finalize_opd): Use struct elf_link_hash_entry * instead
+ of struct elf64_hppa_dyn_hash_entry *.
+ (elf64_hppa_finalize_dlt, llocate_global_data_dlt,
+ allocate_global_data_plt, allocate_global_data_stub,
+ allocate_global_data_opd, count_dyn_reloc, allocate_dynrel_entries):
+ Likewise.
+ (hppa64_link_hash_newfunc): New.
+ (elf64_hppa_hash_table_create): Rework.
+ (count_dyn_reloc): Likewise.
+ (hppa64_elf_local_refcounts): New.
+ (elf64_hppa_check_relocs): Rework using standard technique for recording
+ local DLT, PLT and OPD reference counts.
+ (elf64_hppa_dynamic_symbol_p): Revise using "eh" for struct
+ elf_link_hash_entry *.
+ (elf64_hppa_mark_exported_functions, allocate_global_data_dlt,
+ allocate_global_data_plt, allocate_global_data_stub,
+ allocate_global_data_opd, allocate_dynrel_entries,
+ elf64_hppa_adjust_dynamic_symbol,
+ elf64_hppa_mark_milli_and_exported_functions): Likewise.
+ (elf64_hppa_create_dynamic_sections, elf64_hppa_size_dynamic_sections):
+ Use hppa_link_hash_table. Rework.
+ (elf64_hppa_link_output_symbol_hook): Rework.
+ (elf64_hppa_finish_dynamic_symbol, elf64_hppa_finalize_opd,
+ elf64_hppa_finalize_dlt, elf64_hppa_finalize_dynreloc,
+ elf64_hppa_finish_dynamic_sections): Likewise.
+
+2009-02-26 Christophe Lyon <christophe.lyon@st.com>
+
+ * elf32-arm.c (stub_reloc_type): Removed.
+ (insn_sequence): Renamed reloc_type field to r_type.
+ (elf32_arm_stub_long_branch_v4t_arm_thumb_pic): New stub.
+ (elf32_arm_stub_long_branch_v4t_thumb_arm_pic): Likewise.
+ (elf32_arm_stub_long_branch_thumb_only_pic): Likewise.
+ (elf32_arm_stub_type): Add new enum entries for the new stubs.
+ (arm_stub_is_thumb): Catch new stubs.
+ (arm_type_of_stub): Handle new stubs.
+ (arm_size_one_stub): Use ARRAY_SIZE. Handle new stubs.
+ (bfd_elf32_arm_process_before_allocation): Remove useless
+ condition.
+
+2009-02-25 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf.c (elf_find_function): Use is_function_type to check
+ function symbol.
+
+2009-02-24 Sterling Augustine <sterling@jaw.hq.tensilica.com>
+
+ * xtensa-modules.c: Revert to previous version 1.11 due
+ to inadvertant commit.
+
+2009-02-24 Sterling Augustine <sterling@tensilica.com>
+
+ * elf32-xtensa.c (text_action_add): Separate test for action
+ type. Break if saved action is ta_widen_insn at same offset.
+
+2009-02-24 Daniel Jacobowitz <dan@codesourcery.com>
+
+ * elf32-arm.c (elf32_arm_stub_long_branch_any_any_pic): Rename
+ to elf32_arm_stub_long_branch_any_arm_pic.
+ (elf32_arm_stub_long_branch_any_thumb_pic): New.
+ (enum elf32_arm_stub_type, arm_type_of_stub)
+ (arm_size_one_stub): Handle any to ARM PIC and any to Thumb PIC
+ separately.
+
+2009-02-24 Joseph Myers <joseph@codesourcery.com>
+
+ * elf32-arm.c (PREV_SEC): Update comment.
+ (group_sections): Rename argument to stubs_always_after_branch.
+ Reverse the list and place stubs at the end of input sections.
+ Undefine NEXT_SEC.
+ (elf32_arm_size_stubs): Update to use stubs_always_after_branch.
+
+2009-02-23 Daniel Jacobowitz <dan@codesourcery.com>
+
+ * elf32-arm.c (arm_build_one_stub): Initialize stub_reloc_offset.
+ Fix formatting.
+ (arm_size_one_stub): Remove unnecessary break.
+ (arm_map_one_stub): Fix formatting. Return after BFD_FAIL.
+
+2009-02-23 Christophe Lyon <christophe.lyon@st.com>
+
+ * elf32-arm.c (stub_insn_type): New type.
+ (stub_reloc_type): Likewise.
+ (insn_sequence): Likewise.
+ (elf32_arm_stub_long_branch_any_any): Encode using insn_sequence.
+ (elf32_arm_stub_long_branch_v4t_arm_thumb): Likewise.
+ (elf32_arm_stub_long_branch_thumb_only): Likewise.
+ (elf32_arm_stub_long_branch_v4t_thumb_arm): Likewise.
+ (elf32_arm_stub_short_branch_v4t_thumb_arm): Likewise.
+ (elf32_arm_stub_long_branch_any_any_pic): Likewise.
+ (elf32_arm_stub_hash_entry): Add new helper fields.
+ (stub_hash_newfunc): Initialize these new fields.
+ (arm_build_one_stub): Encode Arm and Thumb instructions separately
+ to take endianness into account.
+ (arm_size_one_stub): Compute size of stubs using insn_sequence.
+ (arm_map_one_stub): Code is now more generic, thanks to
+ insn_sequence.
+
+2009-02-23 Christophe Lyon <christophe.lyon@st.com>
+
+ * elf32-arm.c (elf32_arm_stub_long_branch_thumb_only): Fix stub
+ code.
+ (elf32_arm_stub_long_branch_v4t_thumb_arm): Likewise.
+ (arm_type_of_stub): Use Thumb-only long branch stub (non-PIC) when
+ BLX is not available. Fix typo in warning message. Add comments
+ and improve formatting.
+ (arm_build_one_stub): Adjust to new
+ elf32_arm_stub_long_branch_v4t_thumb_arm stub.
+ (arm_map_one_stub): Likewise.
+
+2009-02-23 Tristan Gingold <gingold@adacore.com>
+ Eric Botcazou <ebotcazou@adacore.com>
+ Douglas B Rupp <rupp@gnat.com>
+
+ * vms.h: Update copyright year, fix comments, reorder declarations.
+ (_bfd_save_vms_section): Remove the prototype.
+ (EGPS_S_V_NO_SHIFT): New constant.
+ (bfd_vms_set_section_flags): New prototype.
+ (EGPS_S_B_ALIGN, EGPS_S_W_FLAGS, EGPS_S_L_ALLOC, EGPS_S_B_NAMLNG): New
+ constants.
+ (EGSY_S_W_FLAGS): Ditto.
+ (EGSY_S_V_QUAD_VAL): Ditto.
+ (ESDF_S_L_VALUE, ESDF_S_L_PSINDX, ESDF_S_B_NAMLNG): Ditto.
+ (EGST_S_W_FLAGS, EGST_S_Q_LP_1, EGST_S_Q_LP_2, EGST_S_L_PSINDX,
+ EGST_S_B_NAMLNG): Ditto.
+ (ESRF_S_B_NAMLNG): Ditto.
+ (ETIR_S_C_HEADER_SIZE): Ditto.
+ (EGPS_S_V_ALLOC_64BIT): Ditto.
+ (DST_S_C_EPILOG): Ditto.
+ (DST_S_C_SRC_SETLNUM_L, DST_S_C_SRC_SETLNUM_W) : Ditto.
+ (DST_S_C_SRC_INCRLNUM_B): Ditto.
+ (DST_S_B_PCLINE_UNSBYTE, DST_S_W_PCLINE_UNSWORD): Ditto.
+ (DST_S_L_PCLINE_UNSLONG): Ditto.
+ (DST_S_B_MODBEG_NAME, DST_S_L_RTNBEG_ADDRESS) : Ditto
+ (DST_S_B_RTNBEG_NAME, DST_S_L_RTNEND_SIZE): Ditto
+ (DST_S_C_SOURCE_HEADER_SIZE): Ditto.
+ (DST_S_B_SRC_DF_LENGTH, DST_S_W_SRC_DF_FILEID): Ditto.
+ (DST_S_B_SRC_DF_FILENAME, DST_S_B_SRC_UNSBYTE): Ditto.
+ (DST_S_B_SRC_UNSBYTE): Ditto.
+ (DST_S_W_SRC_UNSWORD, DST_S_L_SRC_UNSLONG): Ditto.
+ Add prototypes.
+ (vms_section, vms_reloc): Remove types.
+ (hdr_struc): Replaced by ...
+ (hdr_struct): ... new type.
+ (EMH_S_W_HDRTYP, EMH_S_B_STRLVL, EMH_S_L_ARCH1): New constants.
+ (EMH_S_L_ARCH2, EMH_S_L_RECSIZ, EMH_S_B_NAMLNG): Ditto.
+ (EMH_DATE_LENGTH): Ditto.
+ (eom_struc): Replaced by ...
+ (eom_struct): ... new type.
+ (EEOM_S_L_TOTAL_LPS, EEOM_S_W_COMCOD, EEOM_S_B_TFRFLG): New constants.
+ (EEOM_S_L_PSINDX, EEOM_S_L_TFRADR): Ditto.
+ (EIHD_S_K_MAJORID, EIHD_S_K_MINORID, EIHD_S_K_EXE): Ditto.
+ (EIHD_S_L_SIZE, EIHD_S_L_ISDOFF, EIHD_S_L_SYMDBGOFF): Ditto.
+ (EIHD_S_Q_SYMVVA, EIHD_S_L_IMGTYPE): Ditto.
+ (EISD_S_L_EISDSIZE, EISD_S_L_SECSIZE, EISD_S_Q_VIR_ADDR): Ditto.
+ (EISD_S_L_FLAGS, EISD_S_L_VBN, EISD_S_R_CONTROL): Ditto.
+ (EISD_S_L_IDENT, EISD_S_T_GBLNAM): Ditto.
+ (EISD_S_M_GBL, EISD_S_M_CRF, EISD_S_M_DZRO, EISD_S_M_WRT): Ditto.
+ (EISD_S_M_INITALCODE, EISD_S_M_BASED, EISD_S_M_FIXUPVEC): Ditto.
+ (EISD_S_M_RESIDENT, EISD_S_M_VECTOR, EISD_S_M_PROTECT): Ditto.
+ (EISD_S_M_LASTCLU, EISD_S_M_EXE, EISD_S_M_NONSHRADR): Ditto.
+ (EISD_S_M_QUAD_LENGTH, EISD_S_M_ALLOC_64BIT): Ditto.
+ (EIHS_S_L_DSTVBN, EIHS_S_L_DSTSIZE, EIHS_S_L_GSTVBN): Ditto.
+ (EIHS_S_L_GSTSIZE, EIHS_S_L_DMTVBN, EIHS_S_L_DMTBYTES): Ditto.
+ (DBG_S_L_DMT_MODBEG, DBG_S_L_DST_SIZE): Ditto.
+ (DBG_S_W_DMT_PSECT_COUNT, DBG_S_C_DMT_HEADER_SIZE): Ditto.
+ (DBG_S_L_DMT_PSECT_START, DBG_S_L_DMT_PSECT_LENGTH)
+ (DBG_S_C_DMT_PSECT_SIZE): Ditto.
+ (enum file_type_enum): New type.
+ (struct location_struct): Removed.
+ (struct fileinfo, struct srecinfo, struct lineinfo): New types.
+ (struct funcinfo, struct module): Ditto.
+ (struct vms_private_data_struct): Update fields.
+ (struct vms_section_data_struct): New type.
+
+ * vms.c: Update copyright year, fix comments,
+ Fix includes for DECC, add prototypes.
+ (vms_initialize): Use bfd_alloc instead of bfd_zalloc and remove
+ some initializers.
+ Use flavour to set is_vax, location_stack is removed.
+ (struct pair): Declare.
+ (fill_section_ptr): Initialize variables at declaration.
+ Add guard to set SECTION_SYM flag, handlde und section.
+ (vms_fixup_sections): Use struct pair for fill_section_ptr argument.
+ (_bfd_vms_slurp_object_records): New function, replaces previous
+ vms_object_p.
+ (vms_slurp_module): New function.
+ (vms_slurp_image): Ditto.
+ (vms_object_p): Complete rewrite.
+ (vms_mkobject): Use is_vax field to slect architecture.
+ (free_reloc_stream): New function.
+ (vms_convert_to_var): Ditto.
+ (vms_convert_to_var_1): Ditto.
+ (vms_convert_to_var_unix_filename): Ditto.
+ (vms_close_and_cleanup): Call free_reloc_stream, convert file to
+ VAR format on VMS.
+ (vms_new_section_hook): Set alignment to 0, allocate private data.
+ (vms_get_section_contents): Load content.
+ (vms_get_symbol_info): Handle undefined section.
+ (vms_find_nearest_line): Handle.
+ (alloc_reloc_stream): New function.
+ (vms_slurp_reloc_table): Ditto.
+ (vms_get_reloc_upper_bound): Make it real.
+ (vms_canonicalize_reloc): Do the real work.
+ (alpha_howto_table): Add ALPHA_R_NOP, ALPHA_R_BSR, ALPHA_R_LDA,
+ ALPHA_R_BOH.
+ (vms_bfd_reloc_type_lookup): Handle NOP, BSR, LDA and BOH.
+ (vms_set_arch_mach): Check arch.
+ (vms_set_section_contents): Copy the content after allocation.
+ (vms_alpha_vec): Update object flags.
+
+ * vms-tir.c: Update copyright year, fix comments,
+ add prototypes for new functions.
+ (dst_define_location): New function.
+ (dst_restore_location): New function.
+ (dst_retrieve_location): New function.
+ (dst_check_allocation): New function.
+ (image_dump): Call dst_check_allocation.
+ (image_write_b): Ditto.
+ (image_write_w): Ditto.
+ (image_write_l): Ditto.
+ (image_write_q): Ditto.
+ (cmd_name): Handle STA_LW, STA_QW, STO_OFF, STO_IMM, STO_IMMR, STO_LW,
+ STO_QW, OPR_ADD, CTL_SETRB, STC_LP_PSB, CTL_DFLOC, CTL_STLOC,
+ CTL_STKDL.
+ Call error handler instead of abort if name is not known.
+ (etir_sta): Add quarter_relocs argument and set it.
+ Fix cast.
+ (etir_sto): Ditto.
+ (etir_opr): Ditto, return FALSE in case of error.
+ (etir_ctl): Add quarter_relocs argument and set it, fix cast.
+ Fix CTL_DFLOC, CTL_STLOC, CTL_STKDL.
+ (etir_stc): Add quarter_relocs argument and set it, fix cast.
+ Fix STC_LP, STC_LP_PSB, STC_GBL and STC_CGA.
+ Handle STC_LP_PSB, STC_BSR_GBL, STC_LDA_GBL, STC_BOH_GBL.
+ Move STC_NOP_PS, STC_BSR_PS, STC_LDA_PS, STC_BOH_PS, STC_NBH_PS.
+ Return FALSE in case of error.
+ (tir_sta): Change sign of psect.
+ (tir_ctl): Ditto.
+ (tir_cmd): Fix cast. Makes tir_table static const.
+ (etir_cmd): Add quarter_relocs argument, makes etir_table const,
+ add argument to explain.
+ (analyze_etir): Initialize maxptr, add quarter_relocs
+ declaration, move some declarations into inner scopes.
+ Handle quarter_relocs and STO_IMM.
+ (_bfd_vms_slurp_tir): Use constant instead of hard-coded values.
+ (_bfd_vms_slurp_relocs): New function.
+ (_bfd_vms_decode_relocs): New function.
+ (sto_imm): Rewritten.
+ (start_first_etbt_record): New function.
+ (start_another_etbt_record): Ditto.
+ (etir_output_check): Ditto.
+ (defer_reloc_p): Ditto.
+ (_bfd_vms_write_tir): Remove nextoffset, convert a while-loop to
+ a for-loop. Correctly deals with contents, deals with .vmsdebug,
+ rewritte relocations handling.
+ (_bfd_vms_write_tbt): Removed.
+ (_bfd_vms_write_dbg): Ditto.
+
+ * vms-misc.c: Update copyright year, Fix comments.
+ (_bfd_vms_get_header_values): Use 'size' instead of 'length'.
+ (maybe_adjust_record_pointer_for_object): New function.
+ (_bfd_vms_get_first_record): New function, replaces ...
+ (_bfd_vms_get_record): .. removed.
+ (_bfd_vms_get_object_record): New function.
+ (_bfd_vms_get_object_record): New function.
+ (vms_get_remaining_object_record): New function, replaces ...
+ (_bfd_vms_get_next_record): ... removed.
+ (add_new_contents): Removed.
+ (_bfd_save_vms_section): Removed.
+ (_bfd_get_vms_section): Removed.
+ (_bfd_vms_output_flush): Write in VAR format.
+ (new_symbol): Don't make UND section.
+
+ * vms-hdr.c: Update copyright year, update list of record handled.
+ (_bfd_vms_slurp_hdr): rec_length renamed to rec_size.
+ (_bfd_vms_write_hdr): Strip vms and unix patches,
+ add comments, truncate module name at 31 characters,
+ use constants instead of hard-coded value,
+ write BFD version instead of a fixed string.
+ (_bfd_vms_slurp_ihd): New function.
+ (_bfd_vms_slurp_isd): Ditto.
+ (_bfd_vms_slurp_ihs): Ditto.
+ (new_module): Ditto.
+ (parse_module): Ditto
+ (build_module_list): Ditto.
+ (module_find_nearest_line): Ditto.
+ (_bfd_vms_find_nearest_dst_line): Ditto.
+ (vms_slurp_debug): Ditto.
+ (_bfd_vms_slurp_dbg): Ditto.
+ (_bfd_vms_slurp_tbt): Ditto.
+ (_bfd_vms_write_dbg): Ditto.
+ (_bfd_vms_write_tbt): Ditto.
+
+ * vms-gsd.c: Update copyright year, update list of records handled.
+ (EVAX_LITERALS_NAME): New macro.
+ (evax_section_flags): Add an entry for EVAX_LITERALS_NAME.
+ (gpsflagdesc, gsyflagdesc): Moved out of _bfd_vms_slurp_gsd.
+ (register_universal_symbol): New function and prototype.
+ (_bfd_vms_slurp_gsd): Fix indentations and casts,
+ improve debug messages,
+ use constants instead of hard-coded value,
+ fix missing endianness conversion,
+ handle global symbol (SYMG).
+ (bfd_vms_set_section_flags): New function.
+ (_bfd_vms_write_gsd): Don't write .vmsdebug section,
+ handle section literals,
+ fix indentation,
+ handle section bfd and vms flags,
+ don't output LIB$INITIALIZE symbol,
+ fix handling of weak symbols,
+ fix evax vs vax procedure descriptor,
+ handle absolute symbols.
+
+ * reloc.c (BFD_RELOC_ALPHA_NOP, BFD_RELOC_ALPHA_BSR,
+ BFD_RELOC_ALPHA_LDA, BFD_RELOC_ALPHA_BOH): New relocations.
+
+ * makefile.vms (DEFS): Fix flags for VMS.
+
+ * bfdio.c (real_fopen): Handle multiple VMS fopen attributes.
+
+ * bfd-in2.h: Regenerated.
+ * libbfd.h: Regenerated.
+
+2009-02-20 Cary Coutant <ccoutant@google.com>
+
+ * vmsutil.c (vms_file_stats_name): Fix incorrect use of st_mtime
+ in struct stat.
+
+2009-18-02 Dave Korn <dave.korn.cygwin@gmail.com>
+
+ PR gas/7059
+ * coffcode.h (coff_write_object_contents): Don't let the string
+ table offset overflow the s_name field when using long section names.
+
+2009-18-02 Dave Korn <dave.korn.cygwin@gmail.com>
+
+ * coff-alpha.c (alpha_ecoff_backend_data): Initialise fields which
+ control long section name handling with ECOFF_NO_LONG_SECTION_NAMES.
+ * coff-mips.c (mips_ecoff_backend_data): Likewise.
+ * coff-rs6000.c (bfd_xcoff_backend_data): Initialise fields which
+ control long section name handling with XCOFF_NO_LONG_SECTION_NAMES.
+ (bfd_pmac_xcoff_backend_data): Likewise.
+ * coff64-rs6000.c (bfd_xcoff_backend_data): Likewise.
+ (bfd_xcoff_aix5_backend_data): Likewise.
+ (xcoff64_write_object_contents): Delete unused long_section_names
+ local variable.
+ * coff-sh.c (bfd_coff_small_swap_table): Initialise long section
+ name members using COFF_DEFAULT_LONG_SECTION_NAMES and make entire
+ struct non-const.
+ * coffcode.h (documentation): Update to describe long section names.
+ (COFFLONGSECTIONCATHELPER): New helper macro.
+ (BLANKOR1TOODD): Likewise.
+ (COFF_ENABLE_LONG_SECTION_NAMES): Likewise.
+ (COFF_LONG_SECTION_NAMES_SETTER): Likewise.
+ (COFF_DEFAULT_LONG_SECTION_NAMES): Likewise.
+ (bfd_coff_set_long_section_names_allowed): New function.
+ (bfd_coff_set_long_section_names_disallowed): Likewise.
+ (struct bfd_coff_backend_data): Add new backend hook function
+ pointer _bfd_coff_set_long_section_names.
+ (bfd_coff_set_long_section_names): New backend hook.
+ (coff_write_object_contents): Only generate long section names if
+ bfd_coff_long_section_names() indicates they are currently enabled.
+ (bfd_coff_std_swap_table): Make non-const, and initialise long
+ section name fields using COFF_DEFAULT_LONG_SECTION_NAMES.
+ (ticoff0_swap_table): Likewise to both.
+ (ticoff1_swap_table): Again, likewise to both.
+ * coffgen.c (make_a_section_from_file): Allow long section names
+ as inputs even if not currently allowed for outputs.
+ * ecoff.c (_bfd_ecoff_no_long_sections): New function.
+ * efi-app-ia32.c (COFF_LONG_SECTION_NAMES): Define to 0, not blank.
+ * efi-app-ia64.c (COFF_LONG_SECTION_NAMES): Likewise.
+ * efi-app-x86_64.c (COFF_LONG_SECTION_NAMES): Likewise.
+ * efi-bsdrv-ia32.c (COFF_LONG_SECTION_NAMES): Likewise.
+ * efi-bsdrv-ia64.c (COFF_LONG_SECTION_NAMES): Likewise.
+ * efi-bsdrv-x86_64.c (COFF_LONG_SECTION_NAMES): Likewise.
+ * efi-rtdrv-ia32.c (COFF_LONG_SECTION_NAMES): Likewise.
+ * efi-rtdrv-ia64.c (COFF_LONG_SECTION_NAMES): Likewise.
+ * efi-rtdrv-x86_64.c (COFF_LONG_SECTION_NAMES): Likewise.
+ * pei-arm.c (COFF_LONG_SECTION_NAMES): Likewise.
+ * pei-i386.c (COFF_LONG_SECTION_NAMES): Likewise.
+ * pei-mcore.c (COFF_LONG_SECTION_NAMES): Likewise.
+ * pei-mips.c (COFF_LONG_SECTION_NAMES): Likewise.
+ * pei-ppc.c (COFF_LONG_SECTION_NAMES): Likewise.
+ * pei-sh.c (COFF_LONG_SECTION_NAMES): Likewise.
+ * pei-x86_64.c (COFF_LONG_SECTION_NAMES): Likewise.
+ * libcoff-in.h: Update copyright year to cause updated copyright
+ year in generated libcoff.h, and fix typo.
+ * libcoff.h: Regenerated.
+ * libecoff.h (ECOFF_NO_LONG_SECTION_NAMES): New macro.
+ (_bfd_ecoff_no_long_sections): Add prototype.
+ * libxcoff.h (XCOFF_NO_LONG_SECTION_NAMES): New macro.
+ * pe-mips.c (COFF_LONG_SECTION_NAMES): Define empty if not already
+ defined by an including .c file.
+ * ticoff.h (ticoff0_swap_table): Make non-const, and initialise
+ long section name fields using COFF_DEFAULT_LONG_SECTION_NAMES.
+ (ticoff1_swap_table): Likewise to both.
+
+2009-02-18 Christophe Lyon <christophe.lyon@st.com>
+
+ * elf32-arm.c (arm_build_one_stub): Fix relocation target for pic
+ stub. Catch default case error.
+ (arm_map_one_stub): Add missing Thumb mapping symbol.
+
+2009-02-18 Bjoern Haase <bjoern.m.haase@web.de>
+
+ PR 9841
+ * elf32-avr.c: Handle case where no local symbos exist correctly.
+
+2009-02-16 Christophe Lyon <christophe.lyon@st.com>
+
+ bfd/
+ * elf32-arm.c (arm_long_branch_stub,
+ arm_thumb_v4t_long_branch_stub,
+ arm_thumb_thumb_long_branch_stub,
+ arm_thumb_arm_v4t_long_branch_stub,
+ arm_thumb_arm_v4t_short_branch_stub,
+ arm_pic_long_branch_stub):
+ Renamed to elf32_arm_stub_long_branch_any_any,
+ elf32_arm_stub_long_branch_v4t_arm_thumb,
+ elf32_arm_stub_long_branch_thumb_only,
+ elf32_arm_stub_long_branch_v4t_thumb_arm,
+ elf32_arm_stub_short_branch_v4t_thumb_arm,
+ elf32_arm_stub_long_branch_any_any_pic.
+ (arm_stub_long_branch, arm_thumb_v4t_stub_long_branch,
+ arm_thumb_thumb_stub_long_branch,
+ arm_thumb_arm_v4t_stub_long_branch,
+ arm_thumb_arm_v4t_stub_short_branch, arm_stub_pic_long_branch):
+ Renamed to arm_stub_long_branch_any_any,
+ arm_stub_long_branch_v4t_arm_thumb,
+ arm_stub_long_branch_thumb_only,
+ arm_stub_long_branch_v4t_thumb_arm,
+ arm_stub_short_branch_v4t_thumb_arm,
+ arm_stub_long_branch_any_any_pic.
+
+2009-02-15 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ * elf-hppa.h (elf_hppa_final_link_relocate): Correct addend value used
+ in branch offset check.
+
+2009-02-15 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-ppc.c (struct _ppc64_elf_section_data): Delete t_symndx,
+ add toc.symndx and toc.add.
+ (ppc64_elf_check_relocs): Don't set htab->tls_get_addr here.
+ Set up toc.add.
+ (get_tls_mask): Add toc_addend param, set from toc.add. Adjust all
+ callers.
+ (ppc64_elf_tls_setup): Set htab->tls_get_addr and tls_get_addr_fd.
+ (branch_reloc_hash_match): New function, extracted from..
+ (ppc64_elf_tls_optimize): ..here.
+ (ppc64_elf_relocate_section): Properly set addends when optimizing
+ tls sequences. Avoid unnecessary reading and writing of insns.
+ Only redo reloc when symbol changed. Bypass symbol checks when
+ using tlsld_got.
+ * elf32-ppc.c (ppc_elf_tls_setup): Correct comment.
+ (branch_reloc_hash_match): New function, extracted from..
+ (ppc_elf_tls_optimize): ..here.
+ (ppc_elf_relocate_section): Avoid unnecessary reading of insns.
+ Don't clear addend on zapped __tls_get_addr reloc.
+
+2009-02-12 Nick Clifton <nickc@redhat.com>
+
+ PR 9827
+ * elflink.c (bfd_elf_final_link): When counting the relocations,
+ if the header size has not been set yet then assume that it will
+ match the output section's reloc type.
+
+2009-02-12 Nathan Sidwell <nathan@codesourcery.com>
+
+ * elf32-mips.c (mips_elf_final_gp): Don't add 0x4000 offset for
+ relocatable link.
+
+2009-02-09 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-spu.c (spu_elf_find_overlays): Call bfd_set_error on errors.
+ (find_function): Likewise.
+ (pasted_function): Don't error if no prior function found.
+ (discover_functions): Revert 2008-12-10 change. Extend first
+ function range to start of section.
+
+2009-02-08 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ * elf64-hppa.c: Remove PARAMS macro. Replace PTR with void *. Convert
+ functions to C90.
+ * elf64-hppa.h: Likewise.
+
+2009-02-06 Joseph Myers <joseph@codesourcery.com>
+
+ * elfxx-mips.c (_bfd_mips_elf_section_processing): Remove special
+ .sbss handling.
+
+2009-02-04 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-spu.c (spu_elf_build_stubs): Define __icache_neg_log2_linesize.
+ Define __icache_ptr_handler*, not __icache_ptr___icache_bi_handler*.
+
+2009-02-03 Sandip Matte <sandip@rmicorp.com>
+
+ * aoutx.h (NAME (aout, machine_type)): Handle bfd_mach_mips_xlr.
+ * archures.c (bfd_mach_mips_xlr): Define.
+ * bfd-in2.h: Regenerate.
+ * cpu-mips.c (I_xlr): Define.
+ (arch_info_struct): Add XLR entry.
+ * elfxx-mips.c (_bfd_elf_mips_mach): Handle E_MIPS_MACH_XLR.
+ (mips_set_isa_flags): Handle bfd_mach_mips_xlr
+ (mips_mach_extensions): Add XLR entry.
+
+2009-02-03 Eric B. Weddington <eric.weddington@atmel.com>
+
+ * elf32-avr.c (avr_final_link_relocate): Allow avr25 to wraparound.
+
+2009-02-03 Carlos O'Donell <carlos@codesourcery.com>
+
+ * configure.in: AC_SUBST pdfdir.
+ * Makefile.am: Add install-pdf, install-pdf-am
+ and install-pdf-recursive targets. Define pdfdir.
+ * doc/Makefile.am: Define pdf__strip_dir. Add
+ install-pdf and install-pdf-am targets.
+ * po/Make-in: Add install-pdf target.
+ * configure: Regenerate.
+ * Makefile.in: Regenerate
+ * doc/Makefile.in: Regenerate.
+
+2009-02-03 Maxim Kuvyrkov <maxim@codesourcery.com>
+
+ * bfd-in2.h: Regenerate.
+ * elf32-m68k.c: Handle 2-slot GOT entries. Rename variables and
+ fields from n_entries to n_slots where appropriate, update comments.
+ (HOWTO): Add TLS relocations.
+ (reloc_map): Map BFD_RELOC_68K_TLS_* to R_68K_TLS_*.
+ (enum elf_m68k_got_offset_size): New enum.
+ (struct elf_m68k_got_entry.type): Move field to ...
+ (struct elf_m68k_got_entry_key): ... here. Update all uses.
+ (elf_m68k_reloc_got_type, elf_m68k_reloc_got_offset_size): New static
+ functions.
+ (elf_m68k_reloc_got_n_entries, elf_m68k_reloc_tls_p): New static
+ functions.
+ (struct elf_m68k_got): merge rel_8o_n_entries and rel_8o_16o_n_entries
+ fields into n_entries array. Update comments.
+ (elf_m68k_init_got): Simplify, update all uses.
+ (elf_m68k_init_got_entry_key): Handle R_68K_TLS_LDM32 reloc, update.
+ (ELF_M68K_REL_8O_MAX_N_ENTRIES_IN_GOT): Adjust to handle 2-slot
+ GOT entries; update name, update all uses.
+ (ELF_M68K_REL_8O_16O_MAX_N_ENTRIES_IN_GOT): Ditto.
+ (elf_m68k_get_got_entry): Update.
+ (elf_m68k_update_got_entry_type): Rewrite to handle TLS GOT entries,
+ simplify.
+ (elf_m68k_remove_got_entry_type): Simplify.
+ (elf_m68k_add_entry_to_got, elf_m68k_can_merge_gots_1): Update.
+ (elf_m68k_can_merge_gots): Update.
+ (elf_m68k_merge_gots_1, elf_m68k_merge_gots): Update.
+ (struct elf_m68k_finalize_got_offsets_arg): Rewrite to handle 2-slot
+ GOT entries, simplify.
+ (elf_m68k_finalize_got_offsets_1, elf_m68k_finalize_got_offsets): Same.
+ (struct elf_m68k_partition_multi_got_arg): Add slots_relas_diff
+ field, remove obsoleted local_n_entries field.
+ (elf_m68k_partition_multi_got_2): New static function.
+ (elf_m68k_partition_multi_got_1, elf_m68k_partition_multi_got): Use it;
+ update.
+ (elf_m68k_remove_got_entry_type): Update.
+ (elf_m68k_install_rela, dtpoff_base, tpoff): New static functions.
+ (elf_m68k_check_relocs): Handle TLS relocations. Remove unnecessary
+ update of sgot->size and srelgot->size.
+ (elf_m68k_gc_sweep_hook): Update.
+ (elf_m68k_install_rela, dtpoff_base, tpoff): New static functions.
+ (elf_m68k_relocate_section, elf_m68k_finish_dynamic_symbol): Handle
+ TLS relocations.
+ * reloc.c (BFD_RELOC_68K_TLS_*): Declare TLS relocations.
+ * libbfd.h (bfd_reloc_code_real_names): Add BFD_RELOC_68K_TLS_*.
+
+2009-02-02 DJ Delorie <dj@redhat.com>
+
+ * elf32-mep.c (config_names): Regenerate configuration.
+
+2009-02-02 Alan Modra <amodra@bigpond.net.au>
+
+ * elf-bfd.h (bfd_elf_get_str_section): Don't declare.
+ (bfd_elf_find_section, _sh_elf_set_mach_from_flags): Likewise.
+ * elf.c (bfd_elf_get_str_section): Make static.
+ (bfd_elf_find_section): Delete.
+ * libbfd.h: Regenerate.
+
+2009-02-01 Jan Kratochvil <jan.kratochvil@redhat.com>
+
+ * elf-eh-frame.c (REQUIRE_CLEARED_RELOCS) Remove.
+ (_bfd_elf_parse_eh_frame): Do not check relocations for removed FDEs.
+
+2009-01-31 Alan Modra <amodra@bigpond.net.au>
+
+ * elflink.c (on_needed_list): New function.
+ (elf_link_add_object_symbols): Link in --as-needed libs if they
+ satisfy undefined symbols in other libs.
+
+2009-01-30 Julian Brown <julian@codesourcery.com>
+
+ * elf32-arm.c (bfd_elf32_arm_vfp11_erratum_scan): Skip BFDs with
+ EXEC_P or DYNAMIC flags, and skip sections which are being linked
+ with --just-symbols (-R).
+
+2009-01-29 Adam Nemet <anemet@caviumnetworks.com>
+
+ * dwarf2.c (read_rangelist): Use read_address to read low_pc and
+ high_pc in order to properly sign-extend VMAs.
+
+2009-01-29 Daniel Jacobowitz <dan@codesourcery.com>
+ Mark Shinwell <shinwell@codesourcery.com>
+ Catherine Moore <clm@codesourcery.com>
+
+ * elf-attrs.c, elflink.c, elfxx-mips.c: Correct typos in comments.
+
+2009-01-28 Catherine Moore <clm@codesourcery.com>
+
+ * elf32-arm.c (elf32_arm_check_relocs): Set SEC_ALLOC and
+ SEC_LOAD for dynamic relocation sections.
+
+2009-01-27 Hans-Peter Nilsson <hp@axis.com>
+
+ * elf32-cris.c (cris_elf_relocate_section): Use elf_hash_table
+ (info)->tls_size, not elf_hash_table (info)->tls_sec->size for
+ the size of local TLS data.
+
+2009-01-27 Andreas Schwab <schwab@suse.de>
+
+ * mach-o.c (bfd_mach_o_archive_p): Restrict the number of
+ architectures in the archive.
+
+2009-01-27 Hans-Peter Nilsson <hp@axis.com>
+
+ * elf32-cris.c (cris_elf_relocate_section) <case R_CRIS_16_DTPREL>
+ <R_CRIS_32_DTPREL>: Correct relocation value.
+
+ * elf32-cris.c (cris_elf_relocate_section) <case R_CRIS_8>
+ <R_CRIS_16, R_CRIS_32>: Don't call BFD_ASSERT for weak undefined
+ symbols with non-default visibility.
+
+2009-01-26 Nathan Sidwell <nathan@codesourcery.com>
+
+ * elf32-ppc.c (ppc_elf_relax_section): Add space for relocs
+ describing the trampolines.
+ (ppc_elf_relocate_section): Update relocs to describe the
+ trampolines.
+
+2009-01-25 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ * elf-hppa.h (elf_hppa_final_link_relocate): Add check to ensure that
+ branch targets can be reached for R_PARISC_PCREL22F, R_PARISC_PCREL17F
+ and R_PARISC_PCREL12F relocations.
+
+2009-01-24 Alan Modra <amodra@bigpond.net.au>
+
+ PR 6022
+ * elflink.c (find_version_for_sym): New function split out from,
+ but without export_dynamic test, ..
+ (_bfd_elf_link_assign_sym_version): ..here.
+ (_bfd_elf_export_symbol): Use it.
+
+2009-01-23 Alan Modra <amodra@bigpond.net.au>
+
+ * elf-bfd.h (struct elf_assign_sym_version_info): Delete.
+ (struct elf_info_failed, struct elf_find_verdep_info): Move to..
+ * elflink.c: ..here, somewhat modified.
+ * elf-bfd.h (_bfd_elf_add_default_symbol, _bfd_elf_export_symbol,
+ _bfd_elf_link_find_version_dependencies,
+ _bfd_elf_link_assign_sym_version, _bfd_elf_link_size_reloc_section,
+ _bfd_elf_fix_symbol_flags, _bfd_elf_adjust_dynamic_symbol,
+ _bfd_elf_link_sec_merge_syms, bfd_elf_link_mark_dynamic_symbol): Don't
+ declare..
+ * elflink.c: ..and make static here.
+ (_bfd_elf_link_find_version_dependencies): Adjust for removal
+ of output_bfd from struct elf_find_verdep_info.
+ (_bfd_elf_link_assign_sym_version): Similarly adjust to use
+ struct elf_info_failed.
+ (bfd_elf_size_dynamic_sections): Adjust.
+
+2009-01-22 Alan Modra <amodra@bigpond.net.au>
+
+ PR 6832
+ * dwarf2.c (find_line): Don't update stash->sec_info_ptr until
+ after comp_unit_find_line call.
+
+2009-01-21 Nick Clifton <nickc@redhat.com>
+
+ PR 9769
+ * vmsutil.c (vms_file_stats_name): Remove use of unsupported
+ tm_gmtoff field in struct tm.
+
+2009-01-21 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-spu.h (struct spu_elf_params): Add non_ia_text.
+ * elf32-spu.c (mark_overlay_section): Only include .text.ia.*
+ sections in soft-icache lines unless non_ia_text. Don't add
+ rodata if doing so would exceed line size.
+
+2009-01-19 Hans-Peter Nilsson <hp@axis.com>
+
+ * elf32-cris.c (elf_cris_copy_indirect_symbol): For other symbol
+ types than bfd_link_hash_indirect, before early return, call
+ _bfd_elf_link_hash_copy_indirect.
+
+2009-01-19 Andrew Stubbs <ams@codesourcery.com>
+
+ * elf-attrs.c (vendor_set_obj_attr_contents): Support tag ordering.
+ * elf-bfd.h (elf_backend_data): Add obj_attrs_order.
+ * elf32-arm.c (elf32_arm_obj_attrs_order): New function.
+ (elf_backend_obj_attrs_order): New define.
+ * elfxx-target.h (elf_backend_obj_attrs_order): New define.
+ (elfNN_bed): Add elf_backend_obj_attrs_order.
+
+2009-01-19 Andrew Stubbs <ams@codesourcery.com>
+
+ * elf-attrs.c (is_default_attr): Substitute magic numbers with macros.
+ (obj_attr_size): Likewise.
+ (write_obj_attribute): Likewise.
+ (_bfd_elf_copy_obj_attributes): Likewise.
+ (_bfd_elf_parse_attributes): Likewise.
+ * elf-bfd.h (ATTR_TYPE_FLAG_INT_VAL): New define.
+ (ATTR_TYPE_FLAG_STR_VAL, ATTR_TYPE_FLAG_NO_DEFAULT): New defines.
+ (ATTR_TYPE_HAS_INT_VAL, ATTR_TYPE_HAS_STR_VAL): New defines.
+ (ATTR_TYPE_HAS_NO_DEFAULT): New define.
+ * elf32-arm.c (elf32_arm_obj_attrs_arg_type): Replace magic numbers
+ with macros.
+
+2009-01-19 Andrew Stubbs <ams@codesourcery.com>
+
+ * elf-attrs.c (is_default_attr): Support defaultless attributes.
+ (bfd_elf_add_obj_attr_int): Get type from _bfd_elf_obj_attrs_arg_type.
+ (bfd_elf_add_obj_attr_string): Likewise.
+ (bfd_elf_add_obj_attr_int_string): Likewise.
+ (_bfd_elf_parse_attributes): Allow for unknown flag bits in type.
+ * elf-bfd.h (struct obj_attribute): Document new flag bit.
+ * elf32-arm.c (elf32_arm_obj_attrs_arg_type): Specify that
+ Tag_nodefaults has no default value.
+ (elf32_arm_merge_eabi_attributes): Modify the Tag_nodefaults
+ comment to reflect the new state.
+
+2009-01-19 Alan Modra <amodra@bigpond.net.au>
+
+ PR 9695
+ * pdp11.c (N_BADMAG): True for anything but OMAGIC, NMAGIC, ZMAGIC.
+ (some_aout_object_p): Delete dead code handling QMAGIC and BMAGIC.
+ (adjust_z_magix): Delete dead code handling QMAGIC.
+
+2009-01-16 Kai Tietz <kai.tietz@onevision.com>
+
+ * coffcode.h (styp_to_sec_flags): Correct interpretation of
+ IMAGE_SCN_MEM_DISCARDABLE.
+
+2009-01-16 Alan Modra <amodra@bigpond.net.au>
+
+ * Makefile.am (libbfd_la_LIBADD, libbfd_la_LDFLAGS): Substitute
+ SHARED_LIBADD and SHARED_LDFLAGS rather than WIN32LIBADD, WIN32LDFLAGS.
+ * configure.in (commonbfdlib): Delete.
+ (SHARED_LDFLAGS): Rename from WIN32LDFLAGS/
+ (SHARED_LIBADD): Rename from WIN32LIBADD. Add pic libiberty if such
+ is available, not just for linux.
+ * po/SRC-POTFILES.in: Regenerate.
+ * Makefile.in: Regenerate.
+ * configure: Regenerate.
+
+2009-01-15 Andrew Stubbs <ams@codesourcery.com>
+ Julian Brown <julian@codesourcery.com>
+
+ * elf-bfd.h (NUM_KNOWN_OBJ_ATTRIBUTES): Set to 71 to include all known
+ ARM attributes in ABI 2.07.
+ * elf32-arm.c (get_secondary_compatible_arch): New function.
+ (set_secondary_compatible_arch): New function.
+ (tag_cpu_arch_combine): New function.
+ (elf32_arm_copy_one_eabi_other_attribute): Delete function.
+ (elf32_arm_copy_eabi_other_attribute_list): Delete function.
+ (elf32_arm_merge_eabi_attributes): Rename order_312 to order_021 to
+ make it fit with order_01243.
+ Add support for Tag_also_compatible_with,
+ Tag_CPU_unaligned_access, Tag_T2EE_use, Tag_Virtualization_use,
+ Tag_MPextension_use, Tag_nodefaults and Tag_conformance.
+ Improve/tidy up support for Tag_CPU_raw_name, Tag_CPU_name,
+ Tag_CPU_arch, Tag_ABI_HardFP_use, Tag_VFP_HP_extension,
+ Tag_ABI_FP_denormal, Tag_ABI_PCS_GOT_use, Tag_ABI_align8_needed,
+ Tag_VFP_arch and Tag_ABI_FP_16bit_format.
+ Rework the way unknown attributes are handled.
+ Defer errors until all attributes have been processed.
+
+2009-01-15 Andrew Stubbs <ams@codesourcery.com>
+
+ * elf-attrs.c (bfd_elf_add_obj_attr_compat): Rename to
+ bfd_elf_add_obj_attr_int_string.
+ Read Tag_compatibility from its new location in the attribute array,
+ rather than the attribute list.
+ (_bfd_elf_copy_obj_attributes): bfd_elf_add_obj_attr_compat ->
+ bfd_elf_add_obj_attr_int_string.
+ (_bfd_elf_parse_attributes): Likewise.
+ (_bfd_elf_merge_object_attributes): There's now only one
+ Tag_compatibility, and it's in the array, not the list.
+ * elf-bfd.h (NUM_KNOWN_OBJ_ATTRIBUTES): Set to 33 to include
+ Tag_compatibility.
+ (bfd_elf_add_obj_attr_compat): Rename to
+ bfd_elf_add_obj_attr_int_string.
+ (bfd_elf_add_proc_attr_compat): Rename to
+ bfd_elf_add_proc_attr_int_string.
+ * elf32-arm.c (elf32_arm_merge_eabi_attributes): Explicitly don't handle
+ Tag_compatibility.
+
+2009-01-15 Douglas B Rupp <rupp@gnat.com>
+
+ * Makefile.am (BFD32_BACKENDS): Add new object vmsutil.lo
+ (BFD32_BACKENDS_CFILES): Add new file vmsutil.c
+ (vmsutil.lo): Add dependency rule.
+ * Makefile.in: Regenerate.
+ * config.bfd (ia64*-*-*vms*): Add case.
+ * configure.in (bfd_elf64_ia64_vms_vec): Add case.
+ * configure: Regenerate.
+ * vmsutil.c: New file.
+ * vmsutil.h: New file.
+ * elf-bfd.h (struct bfd_elf_special_section): Change type of
+ attr to bfd_vma.
+ * elfxx-ia64.c (elfNN_vms_post_process_headers,
+ elfNN_vms_section_processing, elfNN_vms_final_write_processing,
+ elfNN_vms_close_and_cleanup, elfNN_vms_section_from_shdr,
+ elfNN_vms_object_p): New functions
+ * targets.c (bfd_elf64_ia64_vms_vec): New target.
+
+2009-01-14 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/9727
+ * elflink.c (elf_gc_sweep): Exclude the group section if the
+ first member of the section group is excluded.
+
+2009-01-14 Alan Modra <amodra@bigpond.net.au>
+
+ PR 9735
+ * syms.c (_bfd_stab_section_find_nearest_line): Don't free
+ saved filename, use bfd_alloc rather than bfd_malloc for it.
+
+2009-01-13 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-spu.c (spu_elf_build_stubs): Make __icache_base absolute.
+
+2009-01-13 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-spu.c (remove_cycles): Always set call->max_depth.
+
+2009-01-12 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-spu.c (spu_elf_auto_overlay): Correct vma mask.
+
+2009-01-12 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-spu.c (struct spu_link_hash_table): Add init, line_size_log2,
+ num_lines_log2.
+ (struct got_entry): Add br_addr.
+ (struct call_info): Add priority.
+ (struct function_info): Add lr_store and sp_adjust.
+ (spu_elf_setup): Init line_size_log2 and num_lines_log2.
+ (spu_elf_find_overlays): For soft-icache, mark any section within cache
+ area as an overlay, and check that no other overlays exist. Look up
+ icache overlay manager entry sym.
+ (BRA_STUBS, BRA, BRASL): Define.
+ (enum _stub_type): Replace ovl_stub with call_ovl_stub and br*_ovl_stub.
+ (needs_ovl_stub): Adjust for soft-icache. Return priority encoded
+ in branch insn.
+ (count_stub, build_stub): Support soft-icache.
+ (build_spuear_stubs, process_stubs): Adjust build_stub call.
+ (spu_elf_size_stubs): Size soft-icache stubs.
+ (overlay_index): New function.
+ (spu_elf_build_stubs): Make static. Support soft-icache.
+ (spu_elf_check_vma): Don't turn off auto_overlay if soft-icache.
+ (find_function_stack_adjust): Save lr store and stack adjust insn
+ offsets.
+ (maybe_insert_function): Adjust find_function_stack_adjust call.
+ (mark_functions_via_relocs): Retrieve priority.
+ (remove_cycles): Only warn about pruned arcs when stack_analysis.
+ (sort_calls): Sort by priority first.
+ (mark_overlay_section): Ignore .ovl.init.
+ (sum_stack): Only print when stack_analysis.
+ (print_one_overlay_section): New function, extracted from..
+ (spu_elf_auto_overlay): ..here. Support soft-icache overlays.
+ (spu_elf_stack_analysis): Only print when htab->stack_analysis.
+ (spu_elf_final_link): Call spu_elf_stack_analysis for lrlive
+ analysis. Call spu_elf_build_stubs.
+ (spu_elf_relocate_section): For soft-icache encode overlay index
+ into addresses.
+ (spu_elf_output_symbol_hook): Support soft-icache.
+ (spu_elf_modify_program_headers: Likewise.
+
+ * elf32-spu.h (struct spu_elf_params): Add lrlive_analysis. Rename
+ num_regions to num_lines. Add line_size and max_branch.
+ (enum _ovly_flavour): Add ovly_soft_icache.
+ (spu_elf_build_stubs): Delete.
+
+2009-01-11 Jan Kratochvil <jan.kratochvil@redhat.com>
+
+ * elflink.c (_bfd_elf_section_already_linked): Handle g++-3.4
+ relocations in `.gnu.linkonce.r.*' referencing its `.gnu.linkonce.t.*'.
+
+2009-01-07 Hans-Peter Nilsson <hp@axis.com>
+
+ * elf32-cris.c (cris_elf_relocate_section) <case R_CRIS_32_GD>
+ <case R_CRIS_16_GOT_GD, R_CRIS_32_GOT_GD>: For a symbol defined in
+ the program, the known offset starts at the negative size of the
+ TLS section.
+ <case R_CRIS_32_IE, R_CRIS_32_GOT_TPREL, R_CRIS_16_GOT_TPREL>:
+ Similar.
+
+2009-01-05 Joel Sherrill <joel.sherrill@oarcorp.com>
+
+ * config.bfd: Add lm32-*-rtems*.
+
+2009-01-03 H.J. Lu <hongjiu.lu@intel.com>
+
+ * coff-ppc.c: Add 2009 to Copyright.
+ * elf32-cris.c: Likewise.
+ * elflink.c: Likewise.
+
+2009-01-03 Hans-Peter Nilsson <hp@axis.com>
+
+ * elf32-cris.c (elf_cris_finish_dynamic_symbol): Rename
+ gotplt_index to rela_plt_index. Adjust for R_CRIS_DTPMOD entry.
+
+2009-01-02 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/9679
+ * elflink.c (elf_merge_st_other): New.
+ (_bfd_elf_merge_symbol): Use it on skipped weak definitions and
+ hide them if needed.
+ (elf_link_add_object_symbols): Updated.
+
+2009-01-02 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/9676
+ * elflink.c (elf_link_add_object_symbols): Update def_dynamic,
+ ref_dynamic and dynamic_def fields when setting def_regular
+ to 1.
+
+2009-01-02 Curtis Mackie <curtmackevo@gmail.com>
+
+ PR 9682
+ * coff-ppc.c (dump_toc): Fix up calls to fprintf without a string
+ literal.
+
+For older changes see ChangeLog-2008
+
+Copyright (C) 2009 Free Software Foundation, Inc.
+
+Copying and distribution of this file, with or without modification,
+are permitted in any medium without royalty provided the copyright
+notice and this notice are preserved.
+
+Local Variables:
+mode: change-log
+left-margin: 8
+fill-column: 74
+version-control: never
+End:
diff --git a/bfd/ChangeLog-2010 b/bfd/ChangeLog-2010
new file mode 100644
index 0000000..4dd4cb1
--- /dev/null
+++ b/bfd/ChangeLog-2010
@@ -0,0 +1,3568 @@
+2010-12-31 Robert Millan <rmh@gnu.org>
+
+ * config.bfd: Recognize mips-freebsd and mips-kfreebsd-gnu.
+ * configure.host: Likewise.
+ * configure.in: Support for `bfd_elf32_ntradbigmips_freebsd_vec',
+ `bfd_elf32_ntradlittlemips_freebsd_vec',
+ `bfd_elf32_tradbigmips_freebsd_vec',
+ `bfd_elf32_tradlittlemips_freebsd_vec',
+ `bfd_elf64_tradbigmips_freebsd_vec' and
+ `bfd_elf64_tradlittlemips_freebsd_vec'.
+ * configure: Regenerate.
+ * elf32-mips.c: New target for FreeBSD support
+ (same as traditional MIPS but overrides ELF_OSABI
+ with ELFOSABI_FREEBSD).
+ * elf64-mips.c: Likewise.
+ * elfn32-mips.c: Likewise.
+ * targets.c (_bfd_target_vector): Add
+ `bfd_elf32_ntradbigmips_freebsd_vec',
+ `bfd_elf32_ntradlittlemips_freebsd_vec',
+ `bfd_elf32_tradbigmips_freebsd_vec',
+ `bfd_elf32_tradlittlemips_freebsd_vec',
+ `bfd_elf64_tradbigmips_freebsd_vec' and
+ `bfd_elf64_tradlittlemips_freebsd_vec'.
+
+2010-12-30 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elfcode.h (NAME(elf,r_info)): New.
+ (NAME(elf,r_sym)): Likewise.
+
+ * elflink.c (elf64_r_info): Removed.
+ (elf32_r_info): Likewise.
+ (elf64_r_sym): Likewise.
+ (elf32_r_sym): Likewise.
+
+2010-12-30 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf64-x86-64.c (elf_x86_64_relocs_compatible): New.
+ (elf_backend_relocs_compatible): Defined to
+ elf_x86_64_relocs_compatible.
+
+2010-12-30 H.J. Lu <hongjiu.lu@intel.com>
+
+ * archures.c (bfd_mach_x64_32): New.
+ (bfd_mach_x64_32_intel_syntax): Likewise.
+ * bfd-in2.h: Regenerated.
+
+ * config.bfd (targ64_selvecs): Add bfd_elf32_x86_64_vec for
+ i[3-7]86-*-linux-*.
+ (targ_selvecs): Add bfd_elf32_x86_64_vec for x86_64-*-linux-*.
+
+ * configure.in: Support bfd_elf32_x86_64_vec.
+ * configure: Regenerated.
+
+ * cpu-i386.c (bfd_x64_32_arch_intel_syntax): New.
+ (bfd_x64_32_arch): Likewise.
+
+ * elf-bfd.h (elf_append_rela): New prototype.
+ (elf_append_rel): Likewise.
+ (elf64_r_info): Likewise.
+ (elf32_r_info): Likewise.
+ (elf64_r_sym): Likewise.
+ (elf32_r_sym): Likewise.
+
+ * elf64-x86-64.c (ABI_64_P): New.
+ (elf_x86_64_info_to_howto): Replace ELF64_R_TYPE with
+ ELF32_R_TYPE. Replace ELF64_ST_TYPE with ELF_ST_TYPE.
+ (elf_x86_64_check_tls_transition):Likewise.
+ (elf_x86_64_check_relocs): Likewise.
+ (elf_x86_64_gc_mark_hook):Likewise.
+ (elf_x86_64_gc_sweep_hook): Likewise.
+ (elf_x86_64_relocate_section): Likewise.
+ (elf_x86_64_reloc_type_class): Likewise.
+ (ELF_DYNAMIC_INTERPRETER): Renamed to ...
+ (ELF64_DYNAMIC_INTERPRETER): This.
+ (ELF32_DYNAMIC_INTERPRETER): New.
+ (elf_x86_64_link_hash_table): Add r_info, r_sym, swap_reloca_out,
+ dynamic_interpreter and dynamic_interpreter_size.
+ (elf_x86_64_get_local_sym_hash): Replace ELF64_R_SYM with
+ htab->r_sym. Replace ELF64_R_INFO with htab->r_info.
+ (elf_x86_64_get_local_sym_hash): Likewise.
+ (elf_x86_64_check_tls_transition):Likewise.
+ (elf_x86_64_check_relocs): Likewise.
+ (elf_x86_64_gc_mark_hook):Likewise.
+ (elf_x86_64_gc_sweep_hook): Likewise.
+ (elf_x86_64_relocate_section): Likewise.
+ (elf_x86_64_finish_dynamic_symbol): Likewise.
+ (elf_x86_64_finish_local_dynamic_symbol): Likewise.
+ (elf_x86_64_link_hash_table_create): Initialize r_info, r_sym,
+ swap_reloca_out, dynamic_interpreter and dynamic_interpreter_size.
+ (elf_x86_64_check_relocs): Check ABI_64_P when requesting for
+ PIC.
+ (elf_x86_64_relocate_section): Likewise.
+ (elf64_x86_64_adjust_dynamic_symbol): Replace sizeof
+ (Elf64_External_Rela) with bed->s->sizeof_rela.
+ (elf64_x86_64_allocate_dynrelocs): Likewise.
+ (elf64_x86_64_size_dynamic_sections): Likewise.
+ (elf64_x86_64_finish_dynamic_symbol): Likewise.
+ (elf64_x86_64_append_rela): Removed.
+ (elf32_x86_64_elf_object_p): New.
+ Add bfd_elf32_x86_64_vec.
+
+ * elf64-x86-64.c (elf64_x86_64_xxx): Renamed to ...
+ (elf_x86_64_xxx): This.
+
+ * elflink.c (bfd_elf_final_link): Check ELF file class on error.
+ (elf_append_rela): New.
+ (elf_append_rel): Likewise.
+ (elf64_r_info): Likewise.
+ (elf32_r_info): Likewise.
+ (elf64_r_sym): Likewise.
+ (elf32_r_sym): Likewise.
+
+ * targets.c (bfd_elf32_x86_64_vec): New.
+ (_bfd_target_vector): Add bfd_elf32_x86_64_vec.
+
+2010-12-24 Alan Modra <amodra@gmail.com>
+
+ * compress.c (decompress_contents): Style.
+ (bfd_get_full_section_contents): Do not decompress directly into
+ caller buffer or directly return cached section contents.
+ Check malloc return for compressed_buffer.
+
+2010-12-21 Kai Tietz <kai.tietz@onevision.com>
+
+ * peXXigen.c (_bfd_XXi_final_link_postscript): Use
+ bfd_get_symbol_leading_char to determine "_tls_used" name.
+
+2010-12-21 Pierre Muller <muller@ics.u-strasbg.fr>
+
+ * peXXigen.c (_bfd_XXi_final_link_postscript): Use correct size
+ for windows 64-bit TLS table size.
+
+2010-12-16 DJ Delorie <dj@redhat.com>
+
+ * reloc.c (BFD_RELOC_RX_ABS16_REV): Add.
+ (BFD_RELOC_RX_ABS32_REV): Add.
+ * bfd-in2.h: Regenerate.
+ * libbfd.h: Regenerate.
+ * elf32-rx.c (rx_reloc_map): Add them.
+
+2010-12-15 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf.c (_bfd_elf_new_section_hook): Special handling for
+ .init_array/.fini_array output sections.
+
+2010-12-13 Alan Modra <amodra@gmail.com>
+
+ * aoutx.h (aout_link_check_ar_symbols): Formatting.
+ * cofflink.c (coff_link_check_ar_symbols): Likewise.
+ * elflink.c (elf_link_add_archive_symbols): Likewise.
+ * pdp11.c (aout_link_check_ar_symbols): Likewise.
+ * xcofflink.c (xcoff_link_check_dynamic_ar_symbols,
+ xcoff_link_check_dynamic_ar_symbols): Likewise.
+
+ * aoutx.h (aout_link_check_archive_element): Simplify code dealing
+ with add_archive_element substitute BFD.
+ * cofflink.c (coff_link_check_archive_element): Likewise.
+ * ecoff.c (ecoff_link_check_archive_element): Likewise.
+ (ecoff_link_add_archive_symbols): Likewise.
+ * linker.c (generic_link_check_archive_element): Likewise.
+ * pdp11.c (aout_link_check_archive_element): Likewise.
+ * vms-alpha.c (alpha_vms_link_add_archive_symbols): Likewise.
+ * xcofflink.c (xcoff_link_check_archive_element): Likewise.
+
+ * aoutx.h (aout_link_check_archive_element): Free symbols from old
+ bfd if !keep_memory.
+ * cofflink.c (coff_link_check_archive_element): Likewise.
+ * pdp11.c (aout_link_check_archive_element): Likewise.
+ * xcofflink.c (xcoff_link_check_archive_element): Likewise.
+
+2010-12-13 Alan Modra <amodra@gmail.com>
+
+ * plugin.c (bfd_plugin_mkobject): Delete.
+ (plugin_vec): Use bfd_false instead.
+
+2010-12-12 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elflink.c (elf_link_add_archive_symbols): Remove subsbfd.
+
+2010-12-12 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf.c (special_sections_g): Add ".gnu.lto_".
+
+2010-12-10 Alan Modra <amodra@gmail.com>
+
+ * config.bfd: Configure rs6000-*-aix* as for powerpc-*-aix*.
+ Add aix5coff64_vec to powerpc ELF entries.
+
+2010-12-09 Mike Frysinger <vapier@gentoo.org>
+
+ * .gitignore: New file.
+
+2010-12-06 Dmitry Gorbachev <d.g.gorbachev@gmail.com>
+
+ PR ld/12288
+ * plugin.c (message): Add putchar for the trailing `\n'.
+
+2010-12-04 Mike Frysinger <vapier@gentoo.org>
+
+ * Makefile.am (!INSTALL_LIBBFD/bfdinclude_HEADERS): Set to nothing.
+ (PLUGINS/bfdinclude_HEADERS): Append plugin-api.h.
+ * Makefile.in: Regenerated.
+
+2010-12-04 Alan Modra <amodra@gmail.com>
+
+ PR ld/12277
+ * elflink.c (elf_link_output_extsym): Set bfd_error on symbol
+ and section errors. Allow better translation of error messages.
+
+2010-12-02 Richard Sandiford <richard.sandiford@linaro.org>
+
+ * elf32-arm.c (elf32_arm_link_hash_table): Remove sgot, sgotplt,
+ srelgot, splt, srelplt.
+ (create_got_section, elf32_arm_link_hash_table_create): Don't set them.
+ (elf32_arm_create_dynamic_sections): Likewise. Use htab->root
+ fields instead.
+ (arm_type_of_stub): Use the root fields instead of the removed ones.
+ (cortex_a8_erratum_scan, elf32_arm_size_stubs): Likewise.
+ (bfd_elf32_arm_process_before_allocation): Likewise.
+ (elf32_arm_check_relocs, allocate_dynrelocs): Likewise.
+ (elf32_arm_size_dynamic_sections): Likewise.
+ (elf32_arm_output_arch_local_syms): Likewise.
+ (elf32_arm_final_link_relocate): Set sgot, splt and srelgot from the
+ htab fields instead of looking them up by name. Consistently use
+ these local variables instead of htab fields.
+ (elf32_arm_finish_dynamic_symbol): Likewise sgot, splt and srel.
+ Use srelbss instead of looking it up by name.
+ (elf32_arm_finish_dynamic_sections): Use sgotplt, splt and srelplt
+ instead of looking up the symbols by name. Use the root fields
+ instead of the removed ones.
+
+2010-12-02 Richard Sandiford <richard.sandiford@linaro.org>
+
+ * elf32-arm.c (elf32_arm_relocs_copied): Delete.
+ (elf32_arm_link_hash_entry): Replace relocs_copied with dyn_relocs.
+ (elf32_arm_link_hash_newfunc): Update accordingly.
+ (elf32_arm_copy_indirect_symbol, elf32_arm_gc_sweep_hook): Likewise.
+ (elf32_arm_check_relocs, allocate_dynrelocs): Likewise.
+ (elf32_arm_readonly_dynrelocs): Likewise.
+ (elf32_arm_size_dynamic_sections): Likewise.
+
+2010-12-02 Paul Koning <ni1d@arrl.net>
+
+ * pdp11.c (aout_link_add_symbols): Ignore debug symbols.
+
+2010-11-30 Joel Sherrill <joel.sherrill@oarcorp.com>
+
+ * config.bfd: Add sparc64-rtems.
+
+2010-11-25 Alan Modra <amodra@gmail.com>
+
+ * po/es.po: Update.
+ * po/fi.po: Update.
+ * po/fr.po: Update.
+ * po/ja.po: Update.
+ * po/zh_CN.po: Update.
+
+2010-11-24 Joel Brobecker <brobecker@adacore.com>
+
+ * Makefile.am (OPTIONAL_BACKENDS): Add rs6000-core.lo.
+ (OPTIONAL_BACKENDS_CFILES): Add rs6000-core.c.
+ * Makefile.in: Regenerate.
+
+2010-11-24 Alan Modra <amodra@gmail.com>
+
+ PR ld/12253
+ * elf-eh-frame.c (_bfd_elf_write_section_eh_frame): Correct
+ DW_EH_PE_datarel handling. Truncate .eh_frame_hdr address to
+ ptr_size.
+
+2010-11-23 Mingming Sun <mingm.sun@gmail.com>
+
+ * elfxx-mips.c (mips_set_isa_flags): Move bfd_mach_loongson_3a
+ after bfd_mach_mips_sb1.
+
+2010-11-17 Tristan Gingold <gingold@adacore.com>
+
+ * vms-lib.c (vms_write_index): Add comments.
+ Partially revert previous patch. Free blocks later.
+
+2010-11-17 Nick Clifton <nickc@redhat.com>
+
+ PR ld/12161
+ * elf32-avr.c (elf32_avr_check_relocs): Delete.
+ (elf_backend_check_relocs): Delete.
+
+2010-11-16 Jie Zhang <jie.zhang@analog.com>
+
+ * elf32-bfin.c (elf32_bfin_code_in_l1): New variable.
+ (elf32_bfin_data_in_l1): New variable.
+ (elf32_bfin_final_write_processing): New.
+ (elf_backend_final_write_processing): Define.
+
+2010-11-15 Mike Frysinger <vapier@gentoo.org>
+
+ PR binutils/12177
+ * elf32-bfin.c (_bfin_create_got_section): Drop unused flags code.
+
+2010-11-12 H.J. Lu <hongjiu.lu@intel.com>
+
+ * archive.c (_bfd_get_elt_at_filepos): Copy BFD_COMPRESS and
+ BFD_DECOMPRESS.
+ (bfd_openr_next_archived_file): Revert the last change.
+
+2010-11-11 Mingming Sun <mingm.sun@gmail.com>
+
+ * archures.c (bfd_mach_mips_loongson_3a): Defined.
+ * bfd-in2.h (bfd_mach_mips_loongson_3a): Defined.
+ * cpu-mips.c (I_loongson_3a): New add.
+ (arch_info_struct): Add loongson_3a.
+ * elfxx-mips.c (_bfd_elf_mips_mach): Add loongson_3a.
+ (mips_set_isa_flags): Add loongson_3a.
+ (mips_mach_extensions): Add loongson_3a in MIPS64 extensions.
+
+2010-11-10 Richard Sandiford <richard.sandiford@linaro.org>
+
+ * elf32-arm.c (elf32_arm_merge_eabi_attributes): Remove unused
+ variables.
+
+2010-11-10 Nick Clifton <nickc@redhat.com>
+
+ * po/ja.po: Updated Japanese translation.
+ * po/ru.po: Updated Russian translation.
+
+2010-11-08 Nick Clifton <nickc@redhat.com>
+
+ * po/ja.po: Updated Japanese translation.
+
+2010-11-08 Alan Modra <amodra@gmail.com>
+
+ * hash.c (bfd_hash_hash): Extract from..
+ (bfd_hash_lookup): ..here.
+ (bfd_hash_rename): New function.
+ * section.c (bfd_rename_section): New function.
+ * bfd-in.h (bfd_hash_rename): Declare.
+ * bfd-in2.h: Regenerate.
+ * elf.c (_bfd_elf_make_section_from_shdr): Rename input sections
+ when compressing or decompressing. Don't assert name match.
+ * elf64-hppa.c (get_reloc_section): Don't assert name match.
+ * elfxx-ia64.c (get_reloc_section): Likewise.
+
+2010-11-05 Joseph Myers <joseph@codesourcery.com>
+
+ * elf32-tic6x.c (elf32_tic6x_obj_attrs_handle_unknown): New.
+ (elf32_tic6x_merge_attributes): Use
+ _bfd_elf_merge_unknown_attribute_low and
+ _bfd_elf_merge_unknown_attribute_list.
+ (elf_backend_obj_attrs_handle_unknown): Define.
+
+2010-11-05 Joseph Myers <joseph@codesourcery.com>
+
+ * elf-attrs.c (_bfd_elf_merge_unknown_attribute_low,
+ _bfd_elf_merge_unknown_attribute_list): Correct test for matching
+ string attributes.
+
+2010-11-05 Tristan Gingold <gingold@adacore.com>
+
+ * po/bfd.pot: Regenerate
+
+2010-11-05 Tristan Gingold <gingold@adacore.com>
+
+ * configure.in: Bump version to 2.21.51
+ * configure: Regenerate.
+
+2010-11-04 Maciej W. Rozycki <macro@codesourcery.com>
+
+ PR ld/10144
+ * elfxx-mips.c (_bfd_mips_elf_check_relocs)
+ [R_MIPS_32, R_MIPS_REL32, R_MIPS_64]: Ignore relocs from
+ SEC_DEBUGGING sections.
+
+2010-11-04 Tristan Gingold <gingold@adacore.com>
+
+ * vms-lib.c (vms_write_index): Fix thinko: reverse the loop.
+ Use bfd_zmalloc instead of bfd_malloc. Fix comment.
+
+2010-11-04 Kai Tietz <kai.tietz@onevision.com>
+
+ * coffcode.h (GNU_LINKONCE_WT): New.
+ (sec_to_styp_flags): Add handling of new debug
+ section.
+ (styp_to_sec_flags): Likewise.
+
+2010-11-04 Tristan Gingold <gingold@adacore.com>
+
+ * makefile.vms (CFLAGS): Make badalias warnings informational.
+ * vms-lib.c (vms_lib_bread): Avoid arithmetic on void pointer.
+
+2010-11-04 Joseph Myers <joseph@codesourcery.com>
+
+ * elf-attrs.c (_bfd_elf_merge_unknown_attribute_low,
+ _bfd_elf_merge_unknown_attribute_list): New.
+ * elf-bfd.h (struct elf_backend_data): Add
+ obj_attrs_handle_unknown.
+ (_bfd_elf_merge_unknown_attribute_low,
+ _bfd_elf_merge_unknown_attribute_list): Declare.
+ * elf32-arm.c (elf32_arm_obj_attrs_handle_unknown): New. Split
+ out from elf32_arm_merge_eabi_attributes.
+ (elf32_arm_merge_eabi_attributes): Use
+ _bfd_elf_merge_unknown_attribute_low and
+ _bfd_elf_merge_unknown_attribute_list.
+ (elf_backend_obj_attrs_handle_unknown): Define.
+ * elfxx-target.h (elf_backend_obj_attrs_handle_unknown): Define.
+ (elfNN_bed): Update initializer.
+
+2010-11-02 H.J. Lu <hongjiu.lu@intel.com>
+
+ * bfd.c (BFD_FLAGS_FOR_BFD_USE_MASK): New.
+ * bfd-in2.h: Regenerated.
+
+2010-11-02 Joseph Myers <joseph@codesourcery.com>
+
+ * elf32-tic6x.c (elf32_tic6x_obj_attrs_arg_type): Except for
+ Tag_ABI_compatibility, treat odd tags as strings and even ones as
+ integers.
+ (elf32_tic6x_obj_attrs_order, elf32_tic6x_tag_to_array_alignment,
+ elf32_tic6x_array_alignment_to_tag): New.
+ (elf32_tic6x_merge_attributes): Handle more attributes. Set type
+ for merged attributes.
+ (elf_backend_obj_attrs_order): Define.
+
+2010-10-29 Maciej W. Rozycki <macro@codesourcery.com>
+
+ * elfxx-mips.c (mips_elf_calculate_relocation): Fix a typo.
+
+2010-10-29 Pawel Sikora <pluto@pld-linux.org>
+
+ PR binutils/12075
+ * compress.c (bfd_compress_section_contents): Use uLong on
+ compressed_size.
+
+2010-10-29 Joseph Myers <joseph@codesourcery.com>
+
+ * elf32-tic6x.c (elf32_tic6x_obj_attrs_arg_type): Check
+ Tag_ABI_compatibility not Tag_compatibility.
+ (elf32_tic6x_merge_attributes): Update compatibility attribute
+ name in comment. Return FALSE if merging common attributes fails.
+
+2010-10-29 Nick Clifton <nickc@redhat.com>
+
+ PR bintils/6962
+ * coffcode.h (handle_COMDAT): Only check the base type when
+ looking for a section symbol.
+
+2010-10-29 H.J. Lu <hongjiu.lu@intel.com>
+ Cary Coutant <ccoutant@google.com>
+
+ * archive.c (bfd_openr_next_archived_file): Copy BFD_COMPRESS
+ and BFD_DECOMPRESS.
+
+ * bfd.c (BFD_COMPRESS): New.
+ (BFD_DECOMPRESS): Likewise.
+ (BFD_FLAGS_SAVED): Likewise.
+ (bfd_preserve_save): Replace BFD_IN_MEMORY with BFD_FLAGS_SAVED.
+
+ * compress.c (bfd_uncompress_section_contents): Removed.
+ (get_uncompressed_size): New.
+ (decompress_contents): Likewise.
+ (bfd_compress_section_contents): Likewise.
+ (bfd_get_full_section_contents): Likewise.
+ (bfd_is_section_compressed): Likewise.
+ (bfd_init_section_decompress_status): Likewise.
+ (bfd_init_section_compress_status): Likewise.
+
+ * dwarf2.c (dwarf_debug_sections): New.
+ (dwarf_debug_section_enum): Likewise.
+ (read_section): Remove section_name and compressed_section_name.
+ Add dwarf_debug_section_enum. Try compressed debug section.
+ (read_indirect_string): Updated.
+ (read_abbrevs): Likewise.
+ (decode_line_info): Likewise.
+ (read_debug_ranges): Likewise.
+ (find_line): Updated.
+
+ * ecoff.c (bfd_debug_section): Add compress_status and
+ compressed_size.
+
+ * elf.c (_bfd_elf_make_section_from_shdr): Call
+ bfd_is_section_compressed to check if a DWARF debug section is
+ compressed. Call bfd_init_section_compress_status or
+ bfd_init_section_decompress_status if needed.
+
+ * elflink.c (elf_link_input_bfd): Replace bfd_get_section_contents
+ with bfd_get_full_section_contents.
+ * merge.c (_bfd_add_merge_section): Likewise.
+ * reloc.c (bfd_generic_get_relocated_section_contents): Likewise.
+ * simple.c (bfd_simple_get_relocated_section_contents): Likewise.
+
+ * elfxx-target.h (TARGET_BIG_SYM): Allow BFD_COMPRESS and
+ BFD_DECOMPRESS.
+ (TARGET_LITTLE_SYM): Likewise.
+
+ * libbfd-in.h (dwarf_debug_section): New.
+ (dwarf_debug_sections): Likewise.
+
+ * libbfd.c (_bfd_generic_get_section_contents): Issue an error
+ when getting contents on compressed/decompressed section.
+
+ * section.c (COMPRESS_SECTION_NONE): New.
+ (COMPRESS_SECTION_DONE): Likewise.
+ (DECOMPRESS_SECTION_SIZED): Likewise.
+ (BFD_FAKE_SECTION): Add compress_status and compressed_size.
+ (bfd_malloc_and_get_section): Replace bfd_get_section_contents
+ with bfd_get_full_section_contents.
+
+ * bfd-in2.h: Regenerated.
+ * libbfd.h: Likewise.
+
+2010-10-29 Bernd Schmidt <bernds@codesourcery.com>
+ Joseph Myers <joseph@codesourcery.com>
+
+ * elf32-tic6x.c (elf32_tic6x_merge_attributes): Check for mismatch
+ of DSBT attributes.
+
+2010-10-25 Daniel Jacobowitz <dan@codesourcery.com>
+
+ * elf-bfd.h (RELOC_AGAINST_DISCARDED_SECTION): Always call
+ _bfd_clear_contents. Pass it the input section.
+ * libbfd-in.h (_bfd_clear_contents): Add input_section argument.
+ * libbfd.h: Regenerate.
+ * reloc.c (_bfd_clear_contents): Take input_section argument.
+ Use non-zero for .debug_ranges.
+ (bfd_generic_get_relocated_section_conten): Update _bfd_clear_contents
+ call.
+
+ * elf32-arm.c (elf32_arm_relocate_section): Use
+ RELOC_AGAINST_DISCARDED_SECTION.
+ * elf-m10200.c (mn10200_elf_relocate_section): Likewise.
+ * elf-m10300.c (mn10300_elf_relocate_section): Likewise.
+ * elf32-arm.c (elf32_arm_relocate_section): Likewise.
+ * elf32-avr.c (elf32_avr_relocate_section): Likewise.
+ * elf32-bfin.c (bfin_relocate_section): Likewise.
+ (bfinfdpic_relocate_section): Likewise.
+ * elf32-cr16.c (elf32_cr16_relocate_section): Likewise.
+ * elf32-cr16c.c (elf32_cr16c_relocate_section): Likewise.
+ * elf32-cris.c (cris_elf_relocate_section): Likewise.
+ * elf32-crx.c (elf32_crx_relocate_section): Likewise.
+ * elf32-d10v.c (elf32_d10v_relocate_section): Likewise.
+ * elf32-fr30.c (fr30_elf_relocate_section): Likewise.
+ * elf32-frv.c (elf32_frv_relocate_section): Likewise.
+ * elf32-h8300.c (elf32_h8_relocate_section): Likewise.
+ * elf32-hppa.c (elf32_hppa_relocate_section): Likewise.
+ * elf32-i370.c (i370_elf_relocate_section): Likewise.
+ * elf32-i860.c (elf32_i860_relocate_section): Likewise.
+ * elf32-ip2k.c (ip2k_elf_relocate_section): Likewise.
+ * elf32-iq2000.c (iq2000_elf_relocate_section): Likewise.
+ * elf32-lm32.c (lm32_elf_relocate_section): Likewise.
+ * elf32-m32c.c (m32c_elf_relocate_section): Likewise.
+ * elf32-m32r.c (m32r_elf_relocate_section): Likewise.
+ * elf32-m68hc1x.c (elf32_m68hc11_relocate_section): Likewise.
+ * elf32-m68k.c (elf_m68k_relocate_section): Likewise.
+ * elf32-mcore.c (mcore_elf_relocate_section): Likewise.
+ * elf32-mep.c (mep_elf_relocate_section): Likewise.
+ * elf32-moxie.c (moxie_elf_relocate_section): Likewise.
+ * elf32-msp430.c (elf32_msp430_relocate_section): Likewise.
+ * elf32-mt.c (mt_elf_relocate_section): Likewise.
+ * elf32-openrisc.c (openrisc_elf_relocate_section): Likewise.
+ * elf32-ppc.c (ppc_elf_relocate_section): Likewise.
+ * elf32-rx.c (rx_elf_relocate_section): Likewise.
+ * elf32-s390.c (elf_s390_relocate_section): Likewise.
+ * elf32-score.c (s3_bfd_score_elf_relocate_section): Likewise.
+ * elf32-score7.c (s7_bfd_score_elf_relocate_section): Likewise.
+ * elf32-sh.c (sh_elf_relocate_section): Likewise.
+ * elf32-spu.c (spu_elf_relocate_section): Likewise.
+ * elf32-tic6x.c (elf32_tic6x_relocate_section): Likewise.
+ * elf32-v850.c (v850_elf_relocate_section): Likewise.
+ * elf32-vax.c (elf_vax_relocate_section): Likewise.
+ * elf32-xc16x.c (elf32_xc16x_relocate_section): Likewise.
+ * elf32-xstormy16.c (xstormy16_elf_relocate_section): Likewise.
+ * elf32-xtensa.c (elf_xtensa_relocate_section): Likewise.
+ * elf64-alpha.c (elf64_alpha_relocate_section_r): Likewise.
+ (elf64_alpha_relocate_section): Likewise.
+ * elf64-hppa.c (elf64_hppa_relocate_section): Likewise.
+ * elf64-mmix.c (mmix_elf_relocate_section): Likewise.
+ * elf64-ppc.c (ppc64_elf_relocate_section): Likewise.
+ * elf64-s390.c (elf_s390_relocate_section): Likewise.
+ * elf64-sh64.c (sh_elf64_relocate_section): Likewise.
+ * elfxx-ia64.c (elfNN_ia64_relocate_section): Likewise.
+ * elfxx-mips.c (_bfd_mips_elf_relocate_section): Likewise.
+ * elfxx-sparc.c (_bfd_sparc_elf_relocate_section): Likewise.
+
+2010-10-25 Nathan Sidwell <nathan@codesourcery.com>
+
+ * elf32-tic6x.c: Add attribution.
+
+2010-10-25 Alan Modra <amodra@gmail.com>
+
+ * elf32-arm.c (find_stub_size_and_template): Avoid uninitialized
+ var warning at -O3.
+
+2010-10-25 Alan Modra <amodra@gmail.com>
+
+ * opncls.c (bfd_alloc, bfd_zalloc): Don't mark internal.
+ * libbfd-in.h (bfd_alloc, bfd_zalloc): Don't declare here.
+ * libbfd.h: Regenerate
+ * bfd-in2.h: Regenerate.
+
+2010-10-25 Alan Modra <amodra@gmail.com>
+
+ * opncls.c (_bfd_id_counter): Rename to bfd_id_counter.
+ (bfd_reserved_id_counter, bfd_use_reserved_id): New vars.
+ (_bfd_new_bfd): Use negative id when bfd_use_reserved_id.
+ (bfd_create): Doc fix.
+ * bfd-in2.h: Regenerate.
+
+2010-10-22 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
+
+ * elfxx-sparc.c (tpoff): Define bed, static_tls_size.
+ Consider static_tls_alignment.
+
+ * elf32-sparc.c (TARGET_BIG_SYM): Redefine to
+ bfd_elf32_sparc_sol2_vec.
+ (TARGET_BIG_NAME): Redefine to elf32-sparc-sol2.
+ (elf32_bed): Redefine to elf32_sparc_sol2_bed.
+ (elf_backend_static_tls_alignment): Redefine to 8.
+ Include elf32-target.h.
+ (elf_backend_static_tls_alignment): Undef again for VxWorks.
+
+ * elf64-sparc.c (TARGET_BIG_SYM): Redefine to
+ bfd_elf64_sparc_sol2_vec.
+ (TARGET_BIG_NAME): Redefine to elf64-sparc-sol2.
+ (ELF_OSABI): Undef.
+ (elf64_bed): Redefine to elf64_sparc_sol2_bed.
+ (elf_backend_static_tls_alignment): Redefine to 16.
+ Include elf64-target.h.
+
+ * config.bfd (sparc-*-solaris2.[0-6]): Split from sparc-*-elf*.
+ Set targ_defvec to bfd_elf32_sparc_sol2_vec.
+ [BFD64] (sparc-*-solaris2*): Set targ_defvec to
+ bfd_elf32_sparc_sol2_vec.
+ Replace bfd_elf64_sparc_vec by bfd_elf64_sparc_sol2_vec in
+ targ_selvecs.
+
+ * configure.in: Handle bfd_elf32_sparc_sol2_vec,
+ bfd_elf64_sparc_sol2_vec.
+ * configure: Regenerate.
+
+ * targets.c (bfd_elf32_sparc_sol2_vec): Declare.
+ (bfd_elf64_sparc_sol2_vec): Declare.
+ (_bfd_target_vector): Add bfd_elf32_sparc_sol2_vec,
+ bfd_elf64_sparc_sol2_vec.
+
+2010-10-21 Joseph Myers <joseph@codesourcery.com>
+
+ * elf32-tic6x.c (elf32_tic6x_merge_arch_attributes): Update for
+ attribute renaming.
+ (elf_backend_obj_attrs_section): Change to ".c6xabi.attributes".
+
+2010-10-21 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
+
+ * elf-bfd.h (struct elf_backend_data): New member
+ static_tls_alignment.
+ * elfxx-target.h (elf_backend_static_tls_alignment): Provide
+ default.
+ (elfNN_bed): Initialize static_tls_alignment.
+ * elflink.c (bfd_elf_final_link): Don't round end of TLS section
+ if static TLS has special alignment requirements.
+ * elf32-i386.c (elf_i386_tpoff): Define bed, static_tls_size.
+ Consider static_tls_alignment.
+ (elf_backend_static_tls_alignment): Redefine for Solaris 2.
+ Undef again for VxWorks.
+ * elf64-x86-64.c (elf64_x86_64_tpoff): Define bed,
+ static_tls_size.
+ Consider static_tls_alignment.
+ (elf_backend_static_tls_alignment): Redefine for Solaris 2.
+ Undef again for Intel L1OM.
+
+2010-10-14 Dave Korn <dave.korn.cygwin@gmail.com>
+
+ Apply LD plugin patch series (part 6/6).
+ * aoutx.h (aout_link_check_ar_symbols): Take new "subsbfd" reference
+ parameter and pass it when invoking add_archive_element callback.
+ (aout_link_check_archive_element): Handle substitute bfd if it
+ was set during add_archive_element callback in the above.
+ * cofflink.c (coff_link_check_ar_symbols): Take new "subsbfd" reference
+ parameter and pass it when invoking add_archive_element callback.
+ (coff_link_check_archive_element): Handle substitute bfd if it
+ was set during add_archive_element callback in the above.
+ * ecoff.c (read_ext_syms_and_strs): New function holds symbol-reading
+ code factored-out from ecoff_link_check_archive_element.
+ (reread_ext_syms_and_strs): Clear old symbols and call it.
+ (ecoff_link_check_archive_element): Use the above. Handle substitute
+ BFD if one is set by add_archive_element callback.
+ (ecoff_link_add_archive_symbols): Likewise allow bfd substitution.
+ * elflink.c (elf_link_add_archive_symbols): Likewise.
+ * linker.c (generic_link_check_archive_element): Likewise.
+ * pdp11.c (aout_link_check_ar_symbols): Take new "subsbfd" reference
+ parameter and pass it when invoking add_archive_element callback.
+ (aout_link_check_archive_element): Handle substitute bfd if it was
+ set during add_archive_element callback in the above.
+ * vms-alpha.c (alpha_vms_link_add_archive_symbols): Handle substitute
+ BFD if one is set by add_archive_element callback.
+ * xcofflink.c (xcoff_link_check_dynamic_ar_symbols): Take new "subsbfd"
+ reference parameter and pass it when invoking add_archive_element
+ callback.
+ (xcoff_link_check_ar_symbols): Likewise.
+ (xcoff_link_check_archive_element): Handle bfd substitution if it was
+ set by callback in the above.
+
+2010-10-11 Alan Modra <amodra@gmail.com>
+
+ * elf32-frv.c (elf32_frv_relocate_section): Set "name" for global syms.
+ (elf32_frvfdpic_finish_dynamic_sections): Don't crash on
+ __ROFIXUP_END__ defined in shared lib.
+
+2010-10-11 Thomas Schwinge <thomas@codesourcery.com>
+
+ * elf32-arm.c (elf32_arm_final_link_relocate)
+ (elf32_arm_relocate_section): Handle relocations against STN_UNDEF.
+
+2010-10-11 Dave Korn <dave.korn.cygwin@gmail.com>
+
+ * elflink.c (_bfd_elf_link_output_relocs): Delete unused variable
+ "output_rel_hdr".
+
+2010-10-09 John Tytgat <john@bass-software.com>
+
+ * reloc.c (BFD_RELOC_ARM_HVC): Add.
+ * libbfd.h: Regenerate.
+
+2010-10-08 Kai Tietz <kai.tietz@onevision.com>
+
+ * pei-x86_64.c (find_next_xdata_or_end): Removed.
+ (pex64_dump_xdata): Remove arguments stop, onaline,
+ and pdata. New argument endx. Print term "none"
+ instead of misleading "CFA".
+ (sort_xdata_arr): New function.
+ (pex64_bfd_print_pdata): Use binary search/sort for unwind-RVAs
+ instead of searching quadratic.
+
+2010-10-08 Pierre Muller <muller@ics.u-strasbg.fr>
+ Alan Modra <amodra@gmail.com>
+
+ Fix build with -DDEBUG=7
+ * elf.c (_bfd_elf_symbol_from_bfd_symbol): Remove call
+ to deleted function elf_symbol_flags. Add typecast to avoid warning.
+ * elf32-rx.c (dump_symbol) : Rename to..
+ (rx_dump_symbol): ..this to avoid link errors.
+ * elflink.c (elf_link_input_bfd): Add typecast to avoid warnings.
+ (bfd_elf_perform_complex_relocation): Likewise.
+ * elf32-xtensa.c (print_action_list): Likewise.
+
+2010-10-06 Nathan Sidwell <nathan@codesourcery.com>
+
+ * elf32-arm.c (elf32_arm_stub_long_branch_any_arm_pic,
+ elf32_arm_stub_long_branch_any_arm_pic): Use a consistent name for
+ ip/r12.
+ (arm_type_of_stub): Remove superfluous braces.
+
+2010-10-04 Bernd Schmidt <bernds@codesourcery.com>
+
+ * elf-bfd.h (struct bfd_elf_section_reloc_data): New structure.
+ (struct bfd_elf_section_data): New members REL and RELA; delete
+ members REL_HDR, REL_HDR2, REL_COUNT, REL_COUNT2, REL_IDX,
+ REL_IDX2, REL_HASHES.
+ (_bfd_elf_init_reloc_shdr): Adjust declaration.
+ (_bfd_elf_single_rel_hdr): Declare.
+ (RELOC_AGAINST_DISCARDED_SECTION): Use it.
+ * elf.c (bfd_section_from_shdr): Adjusted to match changes in
+ data structures.
+ (_bfd_elf_init_reloc_shdr): New arg RELDATA. Remove arg REL_HDR.
+ All callers changed. Allocate memory for the Elf_Internal_Shdr
+ structure.
+ (_bfd_elf_single_rel_hdr): New function.
+ (struct fake_section_arg): New structure.
+ (elf_fake_section): Expect to see a pointer to it in the third
+ argument. If doing a relocatable link, allocate both REL and RELA
+ sections as needed.
+ (assign_section_numbers): Adjusted to match changes in
+ data structures.
+ (_bfd_elf_compute_section_file_positions): Call elf_fake_sections
+ with a struct fake_section_args argument.
+ * elfcode.h (elf_write_relocs): Adjusted to match changes in
+ data structures.
+ (elf_slurp_reloc_table): Likewise.
+ * elflink.c (_bfd_elf_link_read_relocs): Likewise.
+ (_bfd_elf_link_size_reloc_section): Remove arg REL_HDR, replace with
+ RELDATA. Remove argument O. All callers changed. Remove code to
+ discover the right rel_hdr and count.
+ (_bfd_elf_link_output_relocs): Adjusted to match changes in
+ data structures.
+ (elf_link_adjust_relocs): Remove args REL_HDR, COUNT and REL_HASH;
+ replace with RELDATA. All callers changed.
+ (elf_link_input_bfd): Correctly generate rel_hash data when both
+ REL and RELA sections are present.
+ (elf_reloc_link_order): Adjusted to match changes in
+ data structures.
+ (bfd_elf_final_link): Simplify code to count relocs. Free the
+ hashes array for both REL and RELA.
+ (get_dynamic_reloc_section_name): Use _bfd_elf_single_reloc_hdr
+ * elf32-m32r.c (m32r_elf_fake_sections, elf_backend_fake_sections):
+ Delete.
+ * elf32-tic6x.c (elf32_tic6x_fake_sections, elf_backend_fake_sections):
+ Delete.
+ (elf32_tic6x_rel_relocation_p): Adjusted to match changes in
+ data structures.
+ * elf32-microblaze.c (microblaze_elf_check_relocs): Use
+ _bfd_elf_single_rel_hdr.
+ * elf32-ppc.c (ppc_elf_relax_section): Likewise.
+ * elf32-spu.c (spu_elf_relocate_section): Likewise.
+ * elf64-alpha.c (elf64_alpha_relocate_section): Likewise.
+ * elf64-hppa.c (get_reloc_section): Likewise.
+ * elf64-mips.c (mips_elf64_slurp_reloc_table): Adjusted to match
+ changes in data structures.
+ (mips_elf64_write_relocs): Use _bfd_elf_single_rel_hdr.
+ * elf64-ppc.c (ppc64_elf_edit_opd): Likewise.
+ (ppc64_elf_edit_toc): Likewise.
+ (get_relocs): Adjusted to match changes in data structures.
+ Allocate an Elf_Internal_Shdr structure if necessary.
+ (ppc64_elf_finish_dynamic_sections): Use _bfd_elf_single_rel_hdr.
+ * elf64-sparc.c (elf64_sparc_slurp_reloc_table): Adjusted to match
+ changes in data structures.
+ * elfxx-ia64.c (get_reloc_section): Use _bfd_elf_single_rel_hdr.
+ * elfxx-mips.c (MIPS_RELOC_RELA_P): Remove macro.
+ (mips_elf_rel_relocation_p): Adjusted to match changes in data
+ structures.
+ (_bfd_mips_elf_relocate_section): Use mips_elf_rel_relocation_p rather
+ than MIPS_RELOC_RELOCA_P.
+ * elfxx-sparc.c (_bfd_sparc_elf_check_relocs): Use
+ _bfd_elf_single_rel_hdr.
+ (_bfd_sparc_elf_relocate_section): Likewise.
+
+2010-10-01 Thomas Schwinge <thomas@codesourcery.com>
+
+ * elf32-arm.c (elf32_arm_size_stubs): Don't choke on local symbols in
+ SHN_UNDEF, SHN_ABS, SHN_COMMON.
+
+2010-09-30 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/11812
+ * elf32-i386.c (elf_i386_size_dynamic_sections): Don't
+ allocate .got.plt section if there are no GOT nor PLT
+ entries and there is no refeence to _GLOBAL_OFFSET_TABLE_.
+ * elf64-x86-64.c (elf64_x86_64_size_dynamic_sections): Li.kewise.
+
+ * elflink.c (_bfd_elf_define_linkage_sym): Clear non_elf.
+
+2010-09-27 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
+
+ * configure: Regenerate.
+
+2010-09-24 Thomas Schwinge <thomas@codesourcery.com>
+
+ * elf32-arm.c, elf32-cris.c, elf32-hppa.c, elf32-i370.c, elf32-m32r.c,
+ elf32-m68k.c, elf32-microblaze.c, elf32-ppc.c, elf32-score.c,
+ elf32-score7.c, elf32-sh.c, elf32-vax.c, elf32-xtensa.c, elf64-alpha.c,
+ elf64-hppa.c, elf64-mips.c, elf64-ppc.c, elf64-sparc.c, elfcode.h,
+ elflink.c, elfxx-ia64.c, elfxx-mips.c: Use STN_UNDEF when referring to
+ the zero symbol index.
+
+ * elflink.c (bfd_elf_reloc_symbol_deleted_p): Compare the symbol index
+ to STN_UNDEF, not SHN_UNDEF.
+
+2010-09-23 Bernd Schmidt <bernds@codesourcery.com>
+
+ * elf32-tic6x.c (elf32_tic6x_fake_sections): New function.
+ (elf_backend_fake_sections): Define.
+
+2010-09-23 Matthew Gretton-Dann <matthew.gretton-dann@arm.com>
+
+ * bfd-in2.h (BFD_RELOC_ARM_HVC): New enum value.
+
+2010-09-23 Alan Modra <amodra@gmail.com>
+
+ * cpu-d10v.c: Make bits_per_address 18 for all arch_info entries.
+
+2010-09-23 Alan Modra <amodra@gmail.com>
+
+ * elf.c (_bfd_elf_init_private_section_data): Allow for SEC_RELOC
+ difference between input and output section.
+
+2010-09-22 Kai Tietz <kai.tietz@onevision.com>
+
+ * coffcode.h (sec_to_styp_flags): Adjust debug
+ sections to be conform to pe-coff specification
+ and avoid marking them as excluded.
+ (styp_to_sec_flags): Doing reverse mapping.
+
+ * peXXigen.c (_bfd_XXi_final_link_postscript): Add handling for
+ setting IAT directory entry.
+
+2010-09-20 Richard Henderson <rth@redhat.com>
+
+ * elf64-alpha.c (elf64_alpha_howto_table): Use bfd_elf_generic_reloc.
+
+2010-09-19 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * elfxx-mips.c (mips_elf_link_hash_entry): Add got_only_for_calls.
+ (mips_elf_link_hash_newfunc): Initialize it.
+ (mips_elf_record_global_got_symbol): Add a for_call parameter.
+ (mips_elf_count_got_symbols): Check SYMBOL_CALLS_LOCAL rather
+ than SYMBOL_REFERENCES_LOCAL if the GOT entry is only used for calls.
+ Try to remove .got entries in favour of .got.plt entries on VxWorks.
+ (_bfd_mips_elf_check_relocs): Do not try to avoid allocating
+ a global GOT entry for VxWorks calls. Update uses of
+ mips_elf_record_global_got_symbol.
+ (allocate_dynrelocs): Set got_only_for_calls to false if the GOT
+ entry is used for dynamic relocations.
+
+2010-09-19 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * elfxx-mips.c (mips_got_entry): Adjust commentary.
+ (mips_elf_create_local_got_entry): If given a symbol, check that it
+ has been assigned to the local part of the GOT.
+ (mips_elf_count_got_symbols): Take the bfd_link_info as argument
+ instead of the master GOT. Put all locally-binding symbols in
+ the local area.
+ (mips_elf_make_got_per_bfd): Use global_got_area to decide whether
+ a symbol lives in the local or global area.
+ (mips_elf_local_relocation_p): Remove check_forced argument and
+ retain only the !check_forced behavior.
+ (mips_elf_calculate_relocation): Adjust call accordingly.
+ Use global_got_area to decide whether an output relocation
+ should be local or global. Explicitly decay R_MIPS_GOT_PAGE
+ into R_MIPS_GOT_DISP where appropriate. Fix selection of
+ local vs. global semantics for R_MIPS*_26. Remove redundant
+ reevaluation of what is stored in was_local_p.
+ (mips_elf_create_dynamic_relocation): Use global_got_area to decide
+ whether the relocation should be against a global or local symbol.
+ (mips_elf_lay_out_got): Update the GOT traversal after the above
+ change to mips_elf_count_got_symbols.
+ (mips_elf_adjust_addend): Adjust call to mips_elf_local_relocation_p.
+ (_bfd_mips_elf_relocate_section): Likewise.
+ (_bfd_mips_elf_finish_dynamic_symbol): Use global_got_area to decide
+ whether the symbol has a global got entry.
+ (_bfd_mips_vxworks_finish_dynamic_symbol): Likewise.
+
+2010-09-19 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * elfxx-mips.c (allocate_dynrelocs): Don't add relocation symbols
+ to the global GOT on VxWorks.
+
+2010-09-19 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * elfxx-mips.c (_bfd_mips_elf_check_relocs): On VxWorks,
+ exclude __GOTT_BASE__ and __GOTT_INDEX__ from the warning
+ about HI/LO relocations in shared objects.
+
+2010-09-16 Alan Modra <amodra@gmail.com>
+
+ * elf32-spu.c (spu_elf_size_sections): Omit fixups for non-alloc
+ sections.
+ (spu_elf_create_sections): Mark .fixup with SEC_LINKER_CREATED and
+ set dynobj.
+ (spu_elf_finish_dynamic_sections): New function.
+ (elf_backend_finish_dynamic_sections): Define.
+
+2010-09-16 Alan Modra <amodra@gmail.com>
+
+ * elf.c (bfd_elf_get_default_section_type): Don't test SEC_NEVER_LOAD.
+ * elflink.c (elf_link_input_bfd): Likewise.
+
+2010-09-15 Kai Tietz <kai.tietz@onevision.com>
+
+ * pei-x86_64.c (pex64_get_unwind_info): Reorgnized.
+ (pex64_get_scope_entry): Removed.
+ (find_next_xdata_or_end): New helper.
+ (pex64_dump_xdata): Reworked.
+ (pex64_bfd_print_pdata): Add checking for
+ valid pdata sorting and values. Reworked
+ output.
+
+2010-09-15 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR binutils/12004
+ * plugin.c (bfd_plugin_object_p): Handle NULL iostream.
+
+2010-09-14 Kai Tietz <kai.tietz@onevision.com>
+
+ * pe-x86_64.c (COFF_SECTION_ALIGNMENT_ENTRIES): Make
+ .rdata, .data, and .text partial matched section names.
+ * pei-x86_64.c: Likewise.
+
+ * peXXigen.c (sort_x64_pdata): New helper.
+ (_bfd_XXi_final_link_postscript): Do pdata sorting.
+
+2010-09-09 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/11998
+ * elf.c (assign_file_positions_for_load_sections): Don't warn
+ zero LMA adjustment.
+
+2010-09-09 Bernd Schmidt <bernds@codesourcery.com>
+
+ * elflink.c (bfd_elf_final_link): Correct calculation of
+ max_external_reloc_size.
+
+2010-09-07 Alan Modra <amodra@gmail.com>
+ Marcus Brinkmann <marcus.brinkmann@ruhr-uni-bochum.de>
+
+ * peXXigen.c: Whitespace.
+ (pe_print_idata): Correct section limit calculations. Tidy array
+ indexing.
+ (_bfd_XX_print_ce_compressed_pdata): Don't leak memory.
+
+2010-09-02 Richard Henderson <rth@redhat.com>
+
+ * config.bfd (x86_64-*-mingw*): Select 32-bit pei vectors too.
+
+2010-09-01 Pedro Alves <pedro@codesourcery.com>
+
+ * netbsd-core.c (netbsd_core_core_file_pid): Renamed to ...
+ (netbsd_core_file_pid): ... this.
+
+2010-09-01 Tristan Gingold <gingold@adacore.com>
+
+ * coffcode.h (coff_slurp_line_table): Add a cast.
+ (coff_slurp_reloc_table): Ditto.
+
+2010-08-30 Gunther Nikl <gnikl@users.sourceforge.net>
+
+ * cisco-core.c (cisco_core_file_pid): Define.
+
+2010-08-30 Alan Modra <amodra@gmail.com>
+
+ PR binutils/11953
+ * elf.c (copy_elf_program_header): Calculate map->header_size
+ from lowest_section, not first_section. Validate program
+ header p_paddr against section lma. Find lowest_section in
+ second loop over headers.
+
+2010-08-28 Alan Modra <amodra@gmail.com>
+
+ * elflink.c (_bfd_elf_dynamic_symbol_p): Rename param. Make
+ common syms local.
+ (_bfd_elf_symbol_refs_local_p): Expand comment.
+ (elf_link_output_extsym): Fix style nit.
+
+2010-08-26 Nathan Sidwell <nathan@codesourcery.com>
+
+ * elf32-arm.c (elf32_arm_final_link): Process stub sections
+ exactly once.
+
+2010-08-25 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/11939
+ * elflink.c (elf_link_add_object_symbols): Don't set
+ unique_global for non-ELF hash link table.
+
+2010-08-25 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/11944
+ * elf-bfd.h (elf_backend_data): Add target_id.
+ (bfd_elf_make_generic_object): Renamed to ...
+ (bfd_elf_make_object): This.
+
+ * elf.c (bfd_elf_make_generic_object): Removed.
+ (bfd_elf_make_object): New.
+ (bfd_elf_mkcorefile): Really treat it as an object file.
+
+ * elf-m10300.c (ELF_TARGET_ID): New.
+ * elf32-arm.c (ELF_TARGET_ID): Likewise.
+ * elf32-bfin.c (ELF_TARGET_ID): Likewise.
+ * elf32-cris.c (ELF_TARGET_ID): Likewise.
+ * elf32-frv.c (ELF_TARGET_ID): Likewise.
+ * elf32-i386.c (ELF_TARGET_ID): Likewise.
+ * elf32-lm32.c (ELF_TARGET_ID): Likewise.
+ * elf32-m32r.c (ELF_TARGET_ID): Likewise.
+ * elf32-m68hc11.c (ELF_TARGET_ID): Likewise.
+ * elf32-m68hc12.c (ELF_TARGET_ID): Likewise.
+ * elf32-m68k.c (ELF_TARGET_ID): Likewise.
+ * elf32-microblaze.c (ELF_TARGET_ID): Likewise.
+ * elf32-ppc.c (ELF_TARGET_ID): Likewise.
+ * elf32-s390.c (ELF_TARGET_ID): Likewise.
+ * elf32-sh.c (ELF_TARGET_ID): Likewise.
+ * elf32-sparc.c (ELF_TARGET_ID): Likewise.
+ * elf32-spu.c (ELF_TARGET_ID): Likewise.
+ * elf32-tic6x.c (ELF_TARGET_ID): Likewise.
+ * elf32-xtensa.c (ELF_TARGET_ID): Likewise.
+ * elf64-alpha.c (ELF_TARGET_ID): Likewise.
+ * elf64-hppa.c (ELF_TARGET_ID): Likewise.
+ * elf64-ppc.c (ELF_TARGET_ID): Likewise.
+ * elf64-s390.c (ELF_TARGET_ID): Likewise.
+ * elf64-x86-64.c (ELF_TARGET_ID): Likewise.
+ * elfxx-ia64.c (ELF_TARGET_ID): Likewise.
+
+ * elf32-hppa.c (elf32_hppa_mkobject): Removed.
+ (bfd_elf32_mkobject): Likewise.
+ (ELF_TARGET_ID): New.
+
+ * elf32-mips.c (ELF_TARGET_ID): New.
+ (bfd_elf32_mkobject): Removed.
+
+ * elf64-mips.c (ELF_TARGET_ID): New.
+ (bfd_elf64_mkobject): Removed.
+
+ * elfn32-mips.c (ELF_TARGET_ID): New.
+ (bfd_elf32_mkobject): Removed.
+
+ * elfxx-mips.c (_bfd_mips_elf_mkobject): Removed.
+ * elfxx-mips.h (_bfd_mips_elf_mkobject): Likewise.
+
+ * elfxx-target.h (bfd_elfNN_mkobject): Default to
+ bfd_elf_make_object.
+ (ELF_TARGET_ID): New. Default to GENERIC_ELF_DATA.
+ (elfNN_bed): Initialize target_id.
+
+2010-08-25 Julian Brown <julian@codesourcery.com>
+
+ * elf32-arm.c (arm_stub_required_alignment): New.
+ (arm_build_one_stub): Use above to partition stubs.
+ (make_branch_to_a8_stub): Use arm_stub_a8_veneer_lwm not
+ arm_stub_a8_veneer_b_cond.
+
+2010-08-25 Alan Modra <amodra@gmail.com>
+
+ * aout-arm.c (MY(bfd_reloc_type_lookup)): Use bfd_arch_bits_per_address.
+ * aout-ns32k.c (MY(bfd_reloc_type_lookup)): Likewise.
+ * aoutx.h (NAME(aout,reloc_type_lookup)): Likewise.
+ * coff-arm.c (coff_arm_reloc_type_lookup): Likewise.
+ * elf-hppa.h (elf_hppa_reloc_final_type): Likewise.
+ * reloc.c (bfd_default_reloc_type_lookup): Likewise.
+ * riscix.c (riscix_reloc_type_lookup): Likewise.
+
+2010-08-25 Alan Modra <amodra@gmail.com>
+
+ * elf.c (_bfd_elf_map_sections_to_segments): Don't load program
+ headers if any loaded section wraps the address space. Simplify
+ ~(m-1) to -m. Use lma rather than vma when determining whether
+ note sections are adjacent.
+
+2010-08-22 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/11933
+ * elflink.c (elf_link_add_object_symbols): Don't check relocation
+ if input ELF object ID doesn't match output.
+
+2010-08-21 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
+
+ * configure: Regenerate.
+
+2010-08-20 H.J. Lu <hongjiu.lu@intel.com>
+
+ * merge.c (sec_merge_emit): Revert the last checkin.
+
+2010-08-20 Maciej W. Rozycki <macro@codesourcery.com>
+
+ * elf32-sh.c (sh_elf_relocate_section): Handle non-ELF output
+ BFD.
+
+2010-08-20 Maciej W. Rozycki <macro@codesourcery.com>
+
+ * elf32-m68k.c (bfd_elf_m68k_set_target_options): Don't set GOT
+ options unless an m68k hash table has been found.
+
+2010-08-20 Nick Clifton <nickc@redhat.com>
+
+ * merge.c (sec_merge_emit): Do not zero pad sections that do not
+ have an alignment.
+
+2010-08-18 Pedro Alves <pedro@codesourcery.com>
+
+ PR corefile/8210
+
+ * bfd-in2.h: Regenerate.
+ * corefile.c (bfd_core_file_pid): New.
+
+ * targets.c (BFD_JUMP_TABLE_CORE): Add NAME##_core_file_pid.
+ (struct bfd_target) <_core_file_pid>: New.
+
+ * libbfd-in.h (_bfd_nocore_core_file_pid): Declare.
+ * libbfd.c (_bfd_nocore_core_file_pid): New.
+
+ * elf-bfd.h (bfd_elf32_core_file_pid, bfd_elf64_core_file_pid):
+ Declare.
+ * elfcode.h (elf_core_file_pid): New define.
+ * elfcore.h (elf_core_file_pid): New function.
+
+ * elf.c (elfcore_make_pid): Rewrite.
+ (elfcore_grok_prstatus): Only set core_pid if not set yet.
+ (elfcore_grok_prstatus) [!HAVE_PRSTATUS_T_PR_WHO]: Fallback to
+ getting the lwpid from prstat.pr_pid.
+
+ * elf64-x86-64.c (elf64_x86_64_grok_prstatus): Write the LWPID to
+ elf_tdata's core_lwpid instead of to core_pid.
+ (elf64_x86_64_grok_psinfo): Extract the main process's PID,
+ and store it in elf_tdata's core_pid field.
+ * elf32-i386.c (elf_i386_grok_prstatus): Write the LWPID to
+ elf_tdata's core_lwpid instead of to core_pid.
+ (elf_i386_grok_psinfo): Extract the main process's PID, and
+ store it in elf_tdata's core_pid field.
+
+ * elf32-am33lin.c (elf32_am33lin_grok_prstatus): Write the LWPID
+ to elf_tdata's core_lwpid instead of to core_pid.
+ * elf32-arm.c (elf32_arm_nabi_grok_prstatus): Write the LWPID to
+ elf_tdata's core_lwpid instead of to core_pid.
+ * elf32-cris.c (cris_elf_grok_prstatus): Write the LWPID to
+ elf_tdata's core_lwpid instead of to core_pid.
+ * elf32-frv.c (elf32_frv_grok_prstatus): Write the LWPID to
+ elf_tdata's core_lwpid instead of to core_pid.
+ * elf32-hppa.c (elf32_hppa_grok_prstatus): Write the LWPID to
+ elf_tdata's core_lwpid instead of to core_pid.
+ * elf32-mips.c (elf32_mips_grok_prstatus): Write the LWPID to
+ elf_tdata's core_lwpid instead of to core_pid.
+ * elf32-ppc.c (ppc_elf_grok_prstatus): Write the LWPID to
+ elf_tdata's core_lwpid instead of to core_pid.
+ * elf32-s390.c (elf_s390_grok_prstatus): Write the LWPID to
+ elf_tdata's core_lwpid instead of to core_pid.
+ * elf32-score.c (s3_bfd_score_elf_grok_prstatus): Write the LWPID
+ to elf_tdata's core_lwpid instead of to core_pid.
+ * elf32-score7.c (s7_bfd_score_elf_grok_prstatus): Write the LWPID
+ to elf_tdata's core_lwpid instead of to core_pid.
+ * elf32-sh.c (elf32_shlin_grok_prstatus): Write the LWPID to
+ elf_tdata's core_lwpid instead of to core_pid.
+ * elf32-xtensa.c (elf_xtensa_grok_prstatus): Write the LWPID to
+ elf_tdata's core_lwpid instead of to core_pid.
+ * elf64-hppa.c (elf64_hppa_grok_prstatus): Write the LWPID to
+ elf_tdata's core_lwpid instead of to core_pid.
+ * elf64-mips.c (elf64_mips_grok_prstatus): Write the LWPID to
+ elf_tdata's core_lwpid instead of to core_pid.
+ * elf64-ppc.c (ppc64_elf_grok_prstatus): Write the LWPID to
+ elf_tdata's core_lwpid instead of to core_pid.
+ * elfn32-mips.c (elf32_mips_grok_prstatus): Write the LWPID to
+ elf_tdata's core_lwpid instead of to core_pid.
+
+ * plugin.c (bfd_plugin_core_file_pid): New function.
+ * aout-target.h (MY_core_file_pid): Define.
+ * aout-tic30.c (MY_core_file_pid, MY_core_file_p): New defines.
+ * coff-rs6000.c (coff_core_file_pid): New define.
+ (rs6000coff_vec, pmac_xcoff_vec): Use BFD_JUMP_TABLE_CORE.
+ * coff64-rs6000.c (coff_core_file_pid): New define.
+ (rs6000coff64_vec): Use BFD_JUMP_TABLE_CORE.
+ (xcoff64_core_file_pid): New define.
+ (aix5coff64_vec): Use BFD_JUMP_TABLE_CORE.
+ * mach-o-target.c (bfd_mach_o_core_file_pid): New define.
+ * aix386-core.c (aix386_core_file_pid): New define.
+ * hppabsd-core.c (hppabsd_core_core_file_pid): New define.
+ * hpux-core.c (hpux_core_core_file_pid): New define.
+ * irix-core.c (irix_core_core_file_pid): New define.
+ * lynx-core.c (lynx_core_file_pid): New define.
+ * osf-core.c (osf_core_core_file_pid): New define.
+ * ptrace-core.c (ptrace_unix_core_file_pid): New define.
+ * sco5-core.c (sco5_core_file_pid): New define.
+ * xcoff-target.h (coff_core_file_pid): New define.
+ * netbsd-core.c (netbsd_core_core_file_pid): New define.
+
+2010-08-13 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/11913
+ * elf32-i386.c (elf_i386_finish_dynamic_sections): Check if
+ .got.plt section is discarded.
+ * elf64-x86-64.c (elf64_x86_64_finish_dynamic_sections): Likewise.
+
+2010-08-13 Nathan Sidwell <nathan@codesourcery.com>
+
+ * elf32-m69k.c (elf32_m68k_print_private_bfd_data): Detect EMAC_B
+ variant.
+
+2010-08-12 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR binutils/11909
+ * Makefile.am (coff-tic4x.lo): New. Disable -Werror.
+ (coff-tic54x.lo): Likewise.
+ * Makefile.in: Regenerated.
+
+2010-08-12 Todd Veldhuizen <todd.veldhuizen@logicblox.com>
+
+ PR ld/11843
+ * elflink.c (compute_bucket_count): Avoid futile long searches for
+ the best bucket size.
+
+2010-08-09 Richard Henderson <rth@redhat.com>
+
+ PR ld/11891
+ * elf64-alpha.c (elf64_alpha_relax_tls_get_addr): Disallow relaxing
+ to tlshi/lo until pos0 and pos1 are adjacent. Use the destination
+ register from the tldgd insn.
+
+2010-08-09 Catherine Moore <clm@codesourcery.com>
+
+ * elfxx-mips.c (mips_elf_perform_relocation): Improve
+ interlinking error message.
+
+2010-08-06 Alan Modra <amodra@gmail.com>
+
+ * elf64-ppc.c (ha_reloc_match): Allow matches to other than r2.
+ (ppc64_elf_relocate_section): Nop out high part insn of large toc
+ code sequence when the high part of offset is zero.
+
+2010-08-04 Tristan Gingold <gingold@adacore.com>
+
+ * vms-alpha.c (alpha_vms_build_fixups): Write the EICP.
+ (alpha_vms_bfd_final_link): Explicitly forbid relocatable links.
+ Clear the SEC_RELOC flag.
+
+2010-08-04 Tristan Gingold <gingold@adacore.com>
+
+ * vms-alpha.c (alpha_vms_create_eisd_for_section): Make writable
+ sections with relocs.
+ (alpha_vms_add_fixup_lp): Set SEC_RELOC flag.
+ (alpha_vms_add_fixup_ca): Ditto.
+ (alpha_vms_add_fixup_qr): Ditto.
+ Add comments.
+
+2010-08-04 Tristan Gingold <gingold@adacore.com>
+
+ * vms-alpha.c (alpha_vms_create_eisd_for_section): Do not make
+ CODE sections writable.
+
+2010-08-04 Tristan Gingold <gingold@adacore.com>
+
+ * vms-alpha.c (alpha_vms_add_lw_fixup): Renamed to ...
+ (alpha_vms_add_fixup_lr): ... this for consistency.
+ (alpha_vms_add_qw_fixup): Removed.
+ Fix some comments.
+ (vms_get_symbol_info): Adjust type for unknown sections.
+
+2010-08-04 Tristan Gingold <gingold@adacore.com>
+
+ * vms-alpha.c (_bfd_vms_slurp_egsd): Use the canonical absolute
+ section for any absolute section. Remove some debugging code.
+
+2010-08-03 DJ Delorie <dj@redhat.com>
+
+ * elf32-m32c.c (ELF_MAXPAGESIZE): Change page size to 256 bytes.
+
+2010-08-03 Tristan Gingold <gingold@adacore.com>
+
+ * vms-misc.c (vms_convert_to_var): Make it static.
+ (_bfd_vms_convert_to_var_unix_filename): Make it public.
+
+2010-08-03 Tristan Gingold <gingold@adacore.com>
+
+ * makefile.vms (OBJS): Update list.
+
+2010-08-03 Tristan Gingold <gingold@adacore.com>
+
+ * vms-alpha.c (_bfd_vms_slurp_egsd): Do not set SEC_HAS_CONTENTS
+ nor SEC_RELOC for empty sections.
+
+2010-08-03 Tristan Gingold <gingold@adacore.com>
+
+ * vms-alpha.c (evax_section_flags): Fix flags for absolute
+ section. Remove useless parenthesis.
+
+2010-08-03 Tristan Gingold <gingold@adacore.com>
+
+ * vms-lib.c (vms_lib_bread_raw): Change type of BUF argument.
+ (vms_lib_bread, vms_lib_bopen): Adjust.
+
+2010-08-02 Alan Modra <amodra@gmail.com>
+
+ PR 11866
+ * elf.c (assign_file_positions_for_load_sections): Use p_vaddr to
+ calculate off_adjust rather than first section vma.
+
+2010-07-30 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elflink.c (compute_bucket_count): Add ATTRIBUTE_UNUSED to info.
+
+2010-07-30 Anthony Green <green@moxielogic.com>
+
+ * config.bfd (targ_cpu): Add moxie-*-rtems support.
+
+2010-07-29 Alan Modra <amodra@gmail.com>
+
+ * elf64-ppc.c (ppc64_elf_edit_toc): Always adjust local syms in
+ .toc section, even when none are used in relocs.
+
+2010-07-27 Maciej W. Rozycki <macro@codesourcery.com>
+
+ * elfxx-mips.h: Include "elf/mips.h".
+ (gprel16_reloc_p): New static inline function.
+ * elfxx-mips.c (_bfd_mips_elf_check_relocs)
+ [R_MIPS16_GOT16, R_MIPS_GOT16, R_MIPS_GOT_HI16, R_MIPS_GOT_LO16]:
+ Use got16_reloc_p.
+ (_bfd_mips_elf_relocate_section)[bfd_reloc_overflow]: Use
+ gprel16_reloc_p.
+ * elf32-mips.c (mips_info_to_howto_rel): Likewise.
+ * elfn32-mips.c (mips_info_to_howto_rel): Likewise.
+
+2010-07-27 Maciej W. Rozycki <macro@codesourcery.com>
+
+ * elf64-mips.c (mips_elf64_howto_table_rela)
+ [R_MIPS_TLS_DTPMOD64]: Clear partial_inplace.
+ [R_MIPS_TLS_DTPREL64, R_MIPS_TLS_GD, R_MIPS_TLS_LDM]: Likewise.
+ [R_MIPS_TLS_DTPREL_HI16, R_MIPS_TLS_DTPREL_LO16]: Likewise.
+ [R_MIPS_TLS_GOTTPREL, R_MIPS_TLS_TPREL64]: Likewise.
+ [R_MIPS_TLS_TPREL_HI16, R_MIPS_TLS_TPREL_LO16]: Likewise.
+ * elfn32-mips.c (elf_mips_howto_table_rela)
+ [R_MIPS_TLS_DTPMOD32]: Likewise.
+ [R_MIPS_TLS_DTPREL32, R_MIPS_TLS_GD, R_MIPS_TLS_LDM]: Likewise.
+ [R_MIPS_TLS_DTPREL_HI16, R_MIPS_TLS_DTPREL_LO16]: Likewise.
+ [R_MIPS_TLS_GOTTPREL, R_MIPS_TLS_TPREL32]: Likewise.
+ [R_MIPS_TLS_TPREL_HI16, R_MIPS_TLS_TPREL_LO16]: Likewise.
+
+2010-07-23 Naveen.H.S <naveen.S@kpitcummins.com>
+ Ina Pandit <ina.pandit@kpitcummins.com>
+
+ * archures.c (DESCRIPTION): Define bfd_mach_v850e2 and
+ bfd_mach_v850e2v3.
+ * reloc.c (bfd_architecture): Define bfd_mach_v850e2 and
+ bfd_mach_v850e2v3.
+ (BFD_RELOC_V850_16_PCREL, BFD_RELOC_V850_17_PCREL,
+ BFD_RELOC_V850_22_PCREL, BFD_RELOC_V850_23,
+ BFD_RELOC_V850_32_PCREL, BFD_RELOC_V850_32_ABS,
+ BFD_RELOC_V850_16_SPLIT_OFFSET, BFD_RELOC_V850_16_S1,
+ BFD_RELOC_V850_LO16_SPLIT_OFFSET, BFD_RELOC_V850_SDA_15_16_OFFSET,
+ BFD_RELOC_V850_ZDA_16_16_OFFSET, BFD_RELOC_V850_CALLT_15_16_OFFSET,
+ BFD_RELOC_V850_32_GOTPCREL, BFD_RELOC_V850_16_GOT,
+ BFD_RELOC_V850_32_GOT, BFD_RELOC_V850_22_PLT_PCREL,
+ BFD_RELOC_V850_32_PLT_PCREL, BFD_RELOC_V850_COPY,
+ BFD_RELOC_V850_GLOB_DAT, BFD_RELOC_V850_JMP_SLOT,
+ BFD_RELOC_V850_RELATIVE, BFD_RELOC_V850_16_GOTOFF,
+ BFD_RELOC_V850_32_GOTOFF, BFD_RELOC_V850_CODE,
+ BFD_RELOC_V850_DATA): New relocations for V850 target.
+ * config.bfd: Match all v850 targets.
+ * cpu-v850.c (arch_info_struct): Define V850e2 and V850e2v3.
+ * elf32-v850.c (v850_elf_check_relocs): Check the newly added
+ relocations.
+ (v850_elf_perform_relocation ): Update the newly added
+ relocations.
+ (v850_elf_howto_t): Update the specifications of added
+ relocations.
+ (v850_elf_reloc_map): Update the relocation mappings.
+ (v850_elf_final_link_relocate): Maps added relocation into the
+ appropriate howto structure.
+ (v850_elf_object_p): Add support for V850E2 and V850E2V3.
+ (v850_elf_final_write_processing): Likewise.
+ (v850_elf_merge_private_bfd_data): Likewise.
+ (v850_elf_print_private_bfd_data): Likewise.
+ * libbfd.h: Regenerate.
+ * bfd-in2.h: Regenerate.
+
+2010-07-23 Alan Modra <amodra@gmail.com>
+
+ * archive.c (_bfd_archive_bsd44_construct_extended_name_table):
+ Correct format specifier.
+
+2010-07-22 Alan Modra <amodra@gmail.com>
+
+ * ecoff.c: Don't include aout/ranlib.h.
+ (_bfd_ecoff_slurp_armap): Use correct struct for ardata->symdefs.
+ (_bfd_ecoff_write_armap): Output ar_date and ar_size using
+ _bfd_ar_spacepad.
+
+2010-07-22 Alan Modra <amodra@gmail.com>
+
+ * aoutx.h (some_aout_object_p): Don't set EXEC_P for files with
+ relocs.
+
+2010-07-20 Alan Modra <amodra@gmail.com>
+
+ * elf.c (assign_file_positions_for_load_sections): Check that
+ zero size sections are allocated in segments too.
+ (assign_file_positions_for_non_load_sections): Warn if zero
+ size alloc sections are found here.
+ (copy_elf_program_header): Don't drop zero size sections from
+ segment map.
+ (copy_private_bfd_data): Check for changes in zero size sections.
+
+2010-07-17 Alan Modra <amodra@gmail.com>
+
+ * elf.c (_bfd_elf_map_sections_to_segments): Force new segment
+ for sections with overlapping LMAs.
+ (assign_file_positions_for_load_sections): Catch overlap for
+ sections that wrap around the address space. Replace a
+ warning that duplicates ld's --check-sections error with a
+ warning that lma has been adjusted for overlapping sections.
+
+2010-07-14 Cary Coutant <ccoutant@google.com>
+
+ PR ld/11817
+ * dwarf2.c (read_section): Revert patch for compressed debug sections.
+ (find_line): Likewise.
+ (read_and_uncompress_section): Remove.
+
+2010-07-13 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/11812
+ * elf32-i386.c (elf_i386_size_dynamic_sections): Don't
+ allocate .got.plt section if there are no GOT nor PLT
+ entries.
+ * elf64-x86-64.c (elf64_x86_64_size_dynamic_sections): Likewise.
+
+2010-07-13 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/11791
+ * elf-ifunc.c (_bfd_elf_allocate_ifunc_dyn_relocs): Support
+ garbage collection against STT_GNU_IFUNC symbols.
+
+ * elf32-i386.c (elf_i386_get_local_sym_hash): Don't set
+ elf.plt.offset/elf.got.offset to -1.
+ (elf_i386_tls_transition): Skip TLS transition for functions.
+ (elf_i386_gc_sweep_hook): Support STT_GNU_IFUNC symbols.
+
+ * elf64-x86-64.c (elf64_x86_64_get_local_sym_hash): Don't set
+ elf.plt.offset/elf.got.offset to -1.
+ (elf64_x86_64_tls_transition): Skip TLS transition for functions.
+ (elf64_x86_64_gc_sweep_hook): Support STT_GNU_IFUNC symbols.
+
+2010-07-12 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf32-i386.c (elf_i386_check_relocs): Re-indent.
+ (elf_i386_relocate_section): Likewise.
+
+2010-07-06 H.J. Lu <hongjiu.lu@intel.com>
+
+ * dwarf2.c (add_line_info): Initialize prev_line.
+
+2010-07-06 Alan Modra <amodra@gmail.com>
+
+ * elf32-ppc.c (ppc_elf_relax_section): Insert branch around
+ trampolines only for .init and .fini sections.
+
+2010-07-05 Alan Modra <amodra@gmail.com>
+
+ * elf32-ppc.c: Formatting.
+ (ppc_elf_finish_dynamic_sections): Don't make plt_entry var static.
+
+2010-07-03 Cary Coutant <ccoutant@google.com>
+
+ * compress.c (bfd_uncompress_section_contents): Add ATTRIBUTE_UNUSED.
+ * dwarf2.c (read_and_uncompress_section): New function.
+ (read_section): Call it.
+ (find_line): Likewise.
+
+2010-07-01 Alan Modra <amodra@gmail.com>
+
+ * elf64-ppc.c (ppc64_elf_edit_toc): Use SYMBOL_CALLS_LOCAL rather
+ than SYMBOL_REFERENCES_LOCAL.
+ (ppc64_elf_relocate_section): Likewise.
+
+2010-07-01 Alan Modra <amodra@gmail.com>
+
+ * elf64-ppc.c (ppc64_elf_edit_toc): Keep toc entries for ifuncs.
+
+2010-06-29 Alan Modra <amodra@gmail.com>
+
+ * cpu-maxq.c: Delete file.
+ * coff-maxq.c: Delete file.
+ * Makefile.am: Remove references to maxq.
+ * archures.c: Likewise.
+ * coffcode.h: Likewise.
+ * configure.in: Likewise.
+ * targets.c: Likewise.
+ * config.bfd: Move maxq from obsolete to removed.
+ * Makefile.in: Regenerate.
+ * bfd-in2.h: Regenerate.
+ * configure: Regenerate.
+ * libbfd.h: Regenerate.
+ * po/SRC-POTFILES.in: Regenerate.
+
+2010-06-28 Alan Modra <amodra@gmail.com>
+
+ * compress.c (bfd_uncompress_section_contents): Use ATTRIBUTE_UNUSED
+ to silence gcc warning.
+
+2010-06-27 Alan Modra <amodra@gmail.com>
+
+ * elf64-ppc.c (get_tls_mask): Don't segfault on NULL elf_section_data.
+ (group_sections): Likewise.
+
+2010-06-27 Alan Modra <amodra@gmail.com>
+
+ * bout.c (aligncode): Delete set but unused variables.
+ * coff-mcore.c (coff_mcore_relocate_section): Likewise.
+ * coff-ppc.c (ppc_record_toc_entry): Likewise.
+ (coff_ppc_relocate_section): Likewise.
+ * coff-rs6000.c (xcoff_complain_overflow_bitfield_func): Likewise.
+ * elf-m10200.c (mn10200_elf_relax_delete_bytes): Likewise.
+ * elf-m10300.c (mn10300_elf_final_link_relocate): Likewise.
+ (mn10300_elf_relax_section): Likewise.
+ * elf32-arm.c (arm_build_one_stub, arm_size_one_stub): Likewise.
+ (record_vfp11_erratum_veneer): Likewise.
+ (bfd_elf32_arm_vfp11_erratum_scan): Likewise.
+ (elf32_arm_final_link_relocate): Likewise.
+ (elf32_arm_check_relocs, arm_map_one_stub): Likewise.
+ * elf32-avr.c (elf32_avr_relax_delete_bytes): Likewise.
+ (elf32_avr_relax_section): Likewise.
+ (avr_mark_stub_not_to_be_necessary): Likewise.
+ * elf32-bfin.c (_bfin_create_got_section): Likewise.
+ * elf32-cr16.c (cr16_elf_final_link_relocate): Likewise.
+ (elf32_cr16_relax_delete_bytes): Likewise.
+ * elf32-cr16c.c (cr16c_elf_final_link_relocate): Likewise.
+ * elf32-cris.c (elf_cris_finish_dynamic_symbol): Likewise.
+ * elf32-crx.c (elf32_crx_relax_delete_bytes): Likewise.
+ * elf32-h8300.c (elf32_h8_relax_section): Likewise.
+ (elf32_h8_relax_delete_bytes): Likewise.
+ * elf32-hppa.c (elf32_hppa_check_relocs): Likewise.
+ * elf32-i370.c (i370_elf_check_relocs): Likewise.
+ (elf_relocate_section): Likewise.
+ * elf32-ip2k.c (adjust_all_relocations): Likewise.
+ (ip2k_elf_relax_section): Likewise.
+ * elf32-lm32.c (lm32_elf_relocate_section): Likewise.
+ (lm32_elf_check_relocs): Likewise.
+ (lm32_elf_finish_dynamic_sections): Likewise.
+ (lm32_elf_finish_dynamic_symbol): Likewise.
+ * elf32-m32c.c (m32c_offset_for_reloc): Likewise.
+ (m32c_elf_relax_delete_bytes): Likewise.
+ * elf32-m32r.c (m32r_elf_finish_dynamic_symbol): Likewise.
+ (m32r_elf_finish_dynamic_sections): Likewise.
+ (m32r_elf_check_relocs, m32r_elf_fake_sections): Likewise.
+ * elf32-m68hc11.c (m68hc11_elf_relax_section): Likewise.
+ * elf32-m68hc1x.c (elf32_m68hc11_relocate_section): Likewise.
+ * elf32-m68k.c (elf_m68k_gc_sweep_hook): Likewise.
+ * elf32-microblaze.c (microblaze_elf_relocate_section): Likewise.
+ (microblaze_elf_check_relocs): Likewise.
+ (microblaze_elf_finish_dynamic_symbol): Likewise.
+ * elf32-msp430.c (msp430_elf_relax_delete_bytes): Likewise.
+ * elf32-ppc.c (ppc_elf_tls_optimize): Likewise.
+ * elf32-rx.c (rx_elf_relocate_section): Likewise.
+ (elf32_rx_relax_delete_bytes, rx_offset_for_reloc): Likewise.
+ (elf32_rx_relax_section): Likewise.
+ * elf32-score.c (score_elf_got_offset_from_index): Likewise.
+ (score_elf_final_link_relocate): Likewise.
+ (s3_bfd_score_elf_relocate_section): Likewise.
+ * elf32-score7.c (score_elf_got_offset_from_index): Likewise.
+ (s7_bfd_score_elf_relocate_section): Likewise.
+ * elf32-sh.c (sh_elf_check_relocs): Likewise.
+ * elf32-spu.c (spu_elf_relocate_section): Likewise.
+ * elf32-v850.c (v850_elf_check_relocs): Likewise.
+ (find_remembered_hi16s_reloc): Likewise.
+ * elf32-vax.c (elf32_vax_merge_private_bfd_data): Likewise.
+ (elf_vax_relocate_section): Likewise.
+ * elf32-xc16x.c (elf32_xc16x_relocate_section): Likewise.
+ * elf32-xtensa.c (xlate_offset_with_removed_text): Likewise.
+ (move_literal): Likewise.
+ * elf64-hppa.c (elf64_hppa_section_from_shdr): Likewise.
+ (elf64_hppa_check_relocs): Likewise.
+ (elf64_hppa_finish_dynamic_symbol): Likewise.
+ (elf64_hppa_relocate_section): Likewise.
+ * elf64-mmix.c (mmix_elf_reloc, mmix_elf_relax_section): Likewise.
+ * elf64-ppc.c (ppc64_elf_check_relocs): Likewise.
+ (ppc64_elf_edit_opd, ppc64_elf_edit_toc): Likewise.
+ * elfxx-ia64.c (elfNN_ia64_section_from_shdr): Likewise.
+ (elfNN_vms_section_from_shdr): Likewise.
+ * elfxx-sparc.c (_bfd_sparc_elf_check_relocs): Likewise.
+ (_bfd_sparc_elf_relocate_section): Likewise.
+ * hp300hpux.c (slurp_symbol_table): Likewise.
+ * i386lynx.c (swap_std_reloc_out, swap_std_reloc_in): Likewise.
+ * mach-o.c (bfd_mach_o_write_thread): Likewise.
+ * mmo.c (mmo_scan, mmo_write_symbols_and_terminator): Likewise.
+ * nlm32-sparc.c (nlm_sparc_read_reloc): Likewise.
+ * pdp11.c (pdp11_aout_link_input_section): Likewise.
+ (aout_link_input_section, aout_link_input_bfd): Likewise.
+ * pe-mips.c (mips_swap_reloc_out): Likewise.
+ (coff_pe_mips_relocate_section): Likewise.
+ * som.c (som_bfd_ar_write_symbol_stuff): Likewise.
+ * vms-alpha.c (_bfd_vms_slurp_egsd): Likewise.
+ * xsym.c (bfd_sym_fetch_type_information_table_ent): Likewise.
+
+ * coff-i860.c (i860_reloc_processing): Avoid set but unused warning.
+ * coffcode.h (coff_compute_section_file_positions): Likewise.
+ (coff_slurp_reloc_table): Likewise.
+ * cpu-arm.c (arm_check_note): Likewise.
+ * elf-bfd.h (RELOC_FOR_GLOBAL_SYMBOL): Likewise.
+ * elf32-avr.c (elf32_avr_relocate_section): Likewise.
+ * elf32-bfin.c (elf32_bfin_merge_private_bfd_data): Likewise.
+ * elf32-ip2k.c (ip2k_elf_relocate_section): Likewise.
+ * elf32-moxie.c (moxie_elf_relocate_section): Likewise.
+ * elf32-msp430.c (elf32_msp430_relocate_section): Likewise.
+ * elf32-sh64.c (_bfd_sh_align_load_span): Likewise.
+ * ieee.c (parse_expression): Likewise.
+ (ieee_slurp_external_symbols, drop_int): Likewise.
+ * peXXigen.c (pe_print_pdata): Likewise.
+ * versados.c (process_esd): Likewise.
+
+2010-06-25 Tristan Gingold <gingold@adacore.com>
+
+ * vms-alpha.c (_bfd_vms_write_egsd): Check absolute section with
+ its flags. Create an absolute section if needed.
+
+2010-06-25 Tristan Gingold <gingold@adacore.com>
+
+ * vms-alpha.c (_bfd_vms_write_egsd): Set target_index field of
+ sections. Mark .vmsdebug section as SEC_DEBUGGING. Do not create
+ dummy psect anymore. Adjust.
+ (_bfd_vms_write_eeom): Adjust (use target_index instead of index)
+ (_bfd_vms_write_etir): Ditto.
+ (start_etir_or_etbt_record): Test for SEC_DEBUGGING instead of
+ section name. Adjust.
+
+2010-06-25 Tristan Gingold <gingold@adacore.com>
+
+ * vms-alpha.c (alpha_vms_write_exec): Set linktime field.
+
+2010-06-25 Alan Modra <amodra@gmail.com>
+
+ * elf64-ppc.c (toc_skip_enum): Define.
+ (ppc64_elf_edit_toc): Use two low bits of skip array as markers.
+ Optimize largetoc sequences.
+ (adjust_toc_syms): Update for skip array change.
+ (ppc64_elf_relocate_section): Handle R_PPC64_LO_DS_OPT.
+
+2010-06-25 Alan Modra <amodra@gmail.com>
+
+ * elf64-ppc.c (is_static_defined): New function.
+ (get_tls_mask, ppc_type_of_stub): Use it here.
+ (ppc64_elf_edit_opd): Ensure we only attempt to edit ppc64 input.
+ (ppc64_elf_tls_setup): Typo fix.
+ (adjust_toc_syms): Correctly handle symbols defined past the end
+ of the toc. Move syms on removed entries to next entry rather
+ than to start of toc.
+ (ppc64_elf_edit_toc): Likewise. Ensure we only attempt to
+ edit ppc64 input. Allocate one extra word in skip array.
+ Honour info->keep_memory when reading relocs if we can.
+ Adjust toc relocs after adjusting symbols.
+
+2010-06-23 Nathan Sidwell <nathan@codesourcery.com>
+
+ * archive64.c (bfd_elf64_archive_write_armap): Fix buffer overrun
+ when scaning map.
+
+2010-06-17 Tristan Gingold <gingold@adacore.com>
+
+ * Makefile.am (BFD32_BACKENDS_CFILES): Move vms-alpha.c to ...
+ (BFD64_BACKENDS_CFILES): ... here.
+ (BFD32_BACKENDS): Move vms-alpha.lo to ...
+ (BFD64_BACKENDS): ... here.
+ * Makefile.in: Regenerate.
+
+2010-06-15 Joseph Myers <joseph@codesourcery.com>
+
+ * elf-bfd.h (LEAST_KNOWN_OBJ_ATTRIBUTE): Decrease to 2.
+ * elf32-tic6x.c (elf32_tic6x_obj_attrs_arg_type,
+ elf32_tic6x_merge_arch_attributes, elf32_tic6x_merge_attributes,
+ elf32_tic6x_merge_private_bfd_data): New.
+ (bfd_elf32_bfd_merge_private_bfd_data,
+ elf_backend_obj_attrs_arg_type, elf_backend_obj_attrs_section,
+ elf_backend_obj_attrs_section_type, elf_backend_obj_attrs_vendor):
+ Define.
+ * elf32-tic6x.h (elf32_tic6x_merge_arch_attributes): Declare.
+
+2010-06-15 Joseph Myers <joseph@codesourcery.com>
+
+ * elf-bfd.h (LEAST_KNOWN_OBJ_ATTRIBUTE): Define.
+ (struct elf_backend_data): Update comment on obj_attrs_order.
+ * elf-attrs.c (vendor_obj_attr_size, vendor_set_obj_attr_contents,
+ _bfd_elf_copy_obj_attributes): Use LEAST_KNOWN_OBJ_ATTRIBUTE
+ instead of hardcoded 4.
+ * elf32-arm.c (elf32_arm_obj_attrs_order): Use
+ LEAST_KNOWN_OBJ_ATTRIBUTE and LEAST_KNOWN_OBJ_ATTRIBUTE + 1
+ instead of hardcoded 4 and 5.
+ (elf32_arm_merge_eabi_attributes): Use LEAST_KNOWN_OBJ_ATTRIBUTE
+ instead of hardcoded 4.
+
+2010-06-14 Kevin Buettner <kevinb@redhat.com>
+
+ * elf32-h8300.c (elf_symbol_leading_char): Define.
+
+2010-06-11 Jan Kratochvil <jan.kratochvil@redhat.com>
+
+ * vms-alpha.c (_bfd_vms_write_egsd): Make sname const.
+
+2010-06-11 Tristan Gingold <gingold@adacore.com>
+
+ * vms-alpha.c (_bfd_vms_slurp_egsd): Always set vma of absolute
+ sections to 0.
+
+2010-06-11 Tristan Gingold <gingold@adacore.com>
+
+ * vms-alpha.c (evax_bfd_print_etir): Handle ETIR__C_STO_GBL_LW.
+
+2010-06-11 Tristan Gingold <gingold@adacore.com>
+
+ * vms-misc.c (_bfd_vms_output_counted): Make VALUE argument const.
+ Adjust cast.
+ (_bfd_vms_output_dump): Make DATA argument const, adjust cast.
+ * vms.h (_bfd_vms_output_counted, _bfd_vms_output_dump): Adjust.
+ * vms-alpha.c (evax_section_flags): Make it const.
+ (vms_secflag_by_name): Remove unused ABFD argument.
+ Make SECTION_FLAGS and NAME arguments const. Clarify comment.
+ (vms_esecflag_by_name): Make SECTION_FLAGS and NAME arguments const.
+ (_bfd_vms_slurp_egsd): Adjust call to vms_secflag_by_name.
+ (_bfd_vms_write_egsd): Remove useless cast.
+
+2010-06-10 Tristan Gingold <gingold@adacore.com>
+
+ * config.bfd: Remove #if/#endif so that som can be compiled on any
+ host.
+ * targets.c (_bfd_target_vector): Remove #if/#endif so that som
+ can be used on any host.
+
+2010-06-10 Tristan Gingold <gingold@adacore.com>
+
+ * som.c: Can now be compiled on any host.
+ Include bfd headers instead of system one.
+ (som_compute_checksum): Parameter is now a pointer to a
+ som_external_header structure. Adjust.
+ (struct section_to_type): Field section is now const.
+ (R_DLT_REL, R_AUX_UNWIND, R_SEC_STMT): Removed conditional
+ definition.
+ (R_LONG_PCREL_MODE, R_N0SEL, R_N1SEL, R_LINETAB): Ditto.
+ (R_LINETAB_ESC, R_LTP_OVERRIDE, R_COMMENT): Ditto.
+ (som_swap_clock_in, som_swap_clock_out): New functions.
+ (som_swap_header_in, som_swap_header_out): Likewise.
+ (som_swap_space_dictionary_in): Likewise.
+ (som_swap_space_dictionary_out): Likewise.
+ (som_swap_subspace_dictionary_in): Likewise.
+ (som_swap_subspace_dictionary_record_out): Likewise.
+ (som_swap_aux_id_in, som_swap_aux_id_out): Likewise.
+ (som_swap_string_auxhdr_out): Likewise.
+ (som_swap_compilation_unit_out): Likewise.
+ (som_swap_exec_auxhdr_in): Likewise.
+ (som_swap_exec_auxhdr_out): Likewise.
+ (som_swap_lst_header_in): Likewise.
+ (som_object_setup): Adjust parameter type using bfd types.
+ (setup_sections): Likewise. Ditto for object file types.
+ Use intermediate variables for external representation and use the
+ swap functions to convert.
+ (som_object_p): Ditto. Remove #ifdef/#endif on always defined
+ macros.
+ (som_prep_headers): Likewise.
+ (som_write_symbol_strings): Likewise.
+ (som_begin_writing): Likewise.
+ (som_finish_writing): Likewise.
+ (som_build_and_write_symbol_table): Likewise.
+ (bfd_section_from_som_symbol): Likewise.
+ (som_slurp_symbol_table): Likewise.
+ (som_bfd_print_private_bfd_data): Likewise.
+ (bfd_som_attach_aux_hdr): Likewise. Clear the padding.
+ (bfd_som_attach_compilation_unit): Likewise.
+ (som_bfd_count_ar_symbols): Likewise.
+ (som_bfd_fill_in_ar_symbols): Likewise.
+ (som_slurp_armap): Likewise.
+ (som_bfd_ar_write_symbol_stuff): Likewise.
+ (som_write_armap): Likewise. Use _bfd_ar_spacepad instead of
+ sprintf to write header fields.
+ * som.h: Include bfd headers instead of system one.
+ (FILE_HDR_SIZE, AUX_HDR_SIZE): Removed.
+ (struct somdata): Use bfd structures instead of system ones.
+ (struct som_section_data_struct): Likewise.
+ (struct som_subspace_dictionary_record): Removed (now in
+ include/som/internal.h)
+
+2010-06-10 Tristan Gingold <gingold@adacore.com>
+
+ * targets.c (bfd_target_list): Remove hp/ux compiler work-around
+ as bfd requires an ANSI-C compiler.
+
+2010-06-09 Tristan Gingold <gingold@adacore.com>
+
+ * bfdio.c (bfd_bread): Fix the code to prevent reading past the
+ end of archive members.
+
+2010-06-08 Tristan Gingold <gingold@adacore.com>
+
+ * som.c (som_bfd_free_cached_info): Do not free relocations as
+ they were allocated with bfd_zalloc.
+
+2010-06-08 Tristan Gingold <gingold@adacore.com>
+
+ * vms-lib.c (_bfd_vms_lib_write_archive_contents): Increment
+ for the first block.
+
+2010-06-08 Tristan Gingold <gingold@adacore.com>
+
+ * vms-lib.c (_bfd_vms_lib_ia64_mkarchive): New function.
+ * libbfd-in.h (_bfd_vms_lib_ia64_mkarchive): Declare.
+ * libbfd.h: Regenerate.
+ * elfxx-ia64.c (bfd_elfNN_write_archive_contents): Redefine for VMS.
+ (bfd_elfNN_mkarchive): Ditto.
+
+2010-06-02 Tristan Gingold <gingold@adacore.com>
+
+ * vms-alpha.c (alpha_vms_bfd_final_link): Fix 64bit constant.
+
+2010-06-01 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
+
+ * configure: Regenerate.
+
+2010-06-01 Tristan Gingold <gingold@adacore.com>
+
+ * vms-alpha.c (struct vms_private_data_struct): Add
+ transfer_address field. Remove unused dst_info field.
+ (alpha_vms_write_exec): Use transfer_address.
+ (_bfd_vms_write_egsd): Add a comment about LIB$INITIALIZE.
+ (alpha_vms_bfd_final_link): Set transfer_address.
+
+2010-05-31 Tristan Gingold <gingold@adacore.com>
+
+ * vms-lib.c (credat_lo, credat_hi): New fields.
+ (vms_read_block): Adjust comments.
+ (vms_write_block): New function.
+ (_bfd_vms_lib_archive_p): Decode majorid once. Replace some
+ hard-coded values with constants. Set credat_lo and credat_hi.
+ (_bfd_vms_lib_mkarchive): Add argument kind.
+ Set ver, mhd_size and type according to kind.
+ (_bfd_vms_lib_alpha_mkarchive): New function.
+ (struct lib_index): Renamed from struct vms_index
+ (lib_index_cmp): Renamed from vms_index_cmp. Adjusted.
+ (get_idxlen): Type of idx argument adjusted. Add is_elfidx
+ argument and handle it.
+ (vms_write_index): Adjust argument idx. Handle elf indexes.
+ (_bfd_vms_lib_build_map): Adjust type of arguments modules and res.
+ (_bfd_vms_lib_write_archive_contents): Add is_elfidx variable and
+ use it. Handle elf indexes. Set credat.
+ * libbfd-in.h (_bfd_vms_lib_mkarchive): Renamed to ...
+ (_bfd_vms_lib_alpha_mkarchive): ... this.
+ * libbfd.h: Regenerated.
+ * vms-alpha.c (vms_alpha_vec): Adjust after previous renaming.
+
+2010-05-28 Sterling Augustine <sterling@tensilica.com>
+
+ * elf32-xtensa.c (elf_xtensa_relocate_section): Add a large amount
+ of code to change the bits in the instructions to match the changes
+ in the relocations. Declare dest_addr and sym_sec to help.
+
+2010-05-28 Jan Kratochvil <jan.kratochvil@redhat.com>
+
+ Workaround GCC PR middle-end/4210.
+ * vms-misc.c (vms_time_t_to_vms_time): Use ternary operator for val[2]
+ and val[3].
+
+2010-05-27 Tristan Gingold <gingold@adacore.com>
+
+ * vms-misc.c: Define __NEW_STARLET. Remove trailing spaces.
+ (VMS_TIME_FACTOR, VMS_TIME_OFFSET): New macros.
+ (vms_time_to_time_t): Use them instead of local const.
+ (vms_time_t_to_vms_time): New function.
+ (vms_get_time): Likewise.
+ (vms_raw_get_time): Likewise.
+ * vms.h (vms_time_t_to_vms_time): New declaration.
+ (vms_get_time): Likewise.
+ (vms_raw_get_time): Likewise.
+
+2010-05-26 Tristan Gingold <gingold@adacore.com>
+
+ * vms-alpha.c: Update comments.
+ (alpha_vms_write_exec): Set lnkflags. Write the GST.
+ (alpha_vms_link_output_symbol): New function.
+ (alpha_vms_bfd_final_link): Generate the VMS symbol table.
+ Set dst_section private field.
+ (alpha_vms_bfd_final_link): Remove code that set dst_section.
+
+2010-05-26 Tristan Gingold <gingold@adacore.com>
+
+ * bfdio.c: Declare and define _bfd_memory_iovec.
+ (bfd_bread): Move code for BFD_IN_MEMORY...
+ (bfd_bwrite): ... Ditto ...
+ (bfd_tell): ... Ditto ...
+ (bfd_flush): ... Ditto ...
+ (bfd_stat): ... Ditto ...
+ (bfd_seek): ... Ditto ...
+ (bfd_get_size): ... Ditto ...
+ (bfd_mmap): ... Ditto ...
+ (memory_bread): ... to these new functions.
+ (memory_bwrite): Ditto.
+ (memory_btell): Ditto.
+ (memory_bseek): Ditto.
+ (memory_bflush): Ditto.
+ (memory_bstat): Ditto.
+ (memory_bmmap): Ditto.
+ (memory_bclose): New function.
+ * peicode.h (pe_ILF_build_a_bfd): Use BFD_IN_MEMORY.
+ * xcofflink.c (bfd_xcoff_link_generate_rtinit): Ditto.
+ * opncls.c (bfd_close): Do not handle BFD_IN_MEMORY case.
+ (bfd_make_writable): Use _bfd_memory_iovec.
+ * elfcode.h (bfd_from_remote_memory): Use _bfd_memory_iovec.
+ * coff-alpha.c (alpha_ecoff_get_elt_at_filepos): Use
+ _bfd_memory_iovec.
+ (alpha_ecoff_openr_next_archived_file): Use proxy_origin
+ instead of origin.
+ * libbfd.h: Regenerate.
+
+2010-05-25 Daniel Jacobowitz <dan@codesourcery.com>
+ Joseph Myers <joseph@codesourcery.com>
+ Andrew Stubbs <ams@codesourcery.com>
+
+ * config.bfd (sh-*-uclinux* | sh[12]-*-uclinux*): Add
+ bfd_elf32_shl_vec, and FDPIC vectors to targ_selvecs.
+ * configure.in: Handle FDPIC vectors.
+ * elf32-sh-relocs.h: Add FDPIC and movi20 relocations.
+ * elf32-sh.c (DEFAULT_STACK_SIZE): Define.
+ (SYMBOL_FUNCDESC_LOCAL): Define. Use it instead of
+ SYMBOL_REFERENCES_LOCAL for function descriptors.
+ (fdpic_object_p): New.
+ (sh_reloc_map): Add FDPIC and movi20 relocations.
+ (sh_elf_info_to_howto, sh_elf_relocate_section): Handle new invalid
+ range.
+ (struct elf_sh_plt_info): Add got20 and short_plt. Update all
+ definitions.
+ (FDPIC_PLT_ENTRY_SIZE, FDPIC_PLT_LAZY_OFFSET): Define.
+ (fdpic_sh_plt_entry_be, fdpic_sh_plt_entry_le, fdpic_sh_plts): New.
+ (FDPIC_SH2A_PLT_ENTRY_SIZE, FDPIC_SH2A_PLT_LAZY_OFFSET): Define.
+ (fdpic_sh2a_plt_entry_be, fdpic_sh2a_plt_entry_le)
+ (fdpic_sh2a_short_plt_be, fdpic_sh2a_short_plt_le, fdpic_sh2a_plts):
+ New.
+ (get_plt_info): Handle FDPIC.
+ (MAX_SHORT_PLT): Define.
+ (get_plt_index, get_plt_offset): Handle short_plt.
+ (union gotref): New.
+ (struct elf_sh_link_hash_entry): Add funcdesc, rename tls_type to
+ got_type and adjust all uses. Add GOT_FUNCDESC.
+ (struct sh_elf_obj_tdata): Add local_funcdesc. Rename
+ local_got_tls_type to local_got_type.
+ (sh_elf_local_got_type): Renamed from sh_elf_local_got_tls_type. All
+ users changed.
+ (sh_elf_local_funcdesc): Define.
+ (struct elf_sh_link_hash_table): Add sfuncdesc, srelfuncdesc, fdpic_p,
+ and srofixup.
+ (sh_elf_link_hash_newfunc): Initialize new fields.
+ (sh_elf_link_hash_table_create): Set fdpic_p.
+ (sh_elf_omit_section_dynsym): New.
+ (create_got_section): Create .got.funcdesc, .rela.got.funcdesc
+ and .rofixup.
+ (allocate_dynrelocs): Allocate local function descriptors and space
+ for R_SH_FUNCDESC-related relocations, and for rofixups.
+ Handle GOT_FUNCDESC. Create fixups. Handle GOT entries which
+ require function descriptors.
+ (sh_elf_always_size_sections): Handle PT_GNU_STACK and __stacksize.
+ (sh_elf_modify_program_headers): New.
+ (sh_elf_size_dynamic_sections): Allocate function descriptors for
+ local symbols. Allocate .got.funcdesc contents. Allocate rofixups.
+ Handle local GOT entries of type GOT_FUNCDESC. Create fixups for
+ local GOT entries. Ensure that FDPIC libraries always have a PLTGOT
+ entry in the .dynamic section.
+ (sh_elf_add_dyn_reloc, sh_elf_got_offset, sh_elf_initialize_funcdesc)
+ (sh_elf_add_rofixup, sh_elf_osec_to_segment)
+ (sh_elf_osec_readonly_p, install_movi20_field): New functions.
+ (sh_elf_relocate_section): Handle new relocations, R_SH_FUNCDESC,
+ R_SH_GOTFUNCDESC and R_SH_GOTOFFFUNCDESC. Use sh_elf_got_offset
+ and .got.plt throughout to find _GLOBAL_OFFSET_TABLE_. Add rofixup
+ read-only section warnings. Handle undefined weak symbols. Generate
+ fixups for R_SH_DIR32 and GOT entries. Check for cross-segment
+ relocations and clear EF_SH_PIC. Handle 20-bit relocations.
+ Always generate R_SH_DIR32 for FDPIC instead of R_SH_RELATIVE.
+ (sh_elf_gc_sweep_hook): Handle R_SH_FUNCDESC, R_SH_GOTOFF20,
+ R_SH_GOTFUNCDESC, R_SH_GOTFUNCDESC20, and R_SH_GOTOFFFUNCDESC.
+ Handle 20-bit relocations.
+ (sh_elf_copy_indirect_symbol): Copy function descriptor reference
+ counts.
+ (sh_elf_check_relocs): Handle new relocations. Make symbols
+ dynamic for FDPIC relocs. Account for rofixups. Error for FDPIC
+ symbol mismatches. Allocate a GOT for R_SH_DIR32. Allocate fixups
+ for R_SH_DIR32.
+ (sh_elf_copy_private_data): Copy PT_GNU_STACK size.
+ (sh_elf_merge_private_data): Copy initial flags. Do not clobber
+ non-mach flags. Set EF_SH_PIC for FDPIC. Reject FDPIC mismatches.
+ (sh_elf_finish_dynamic_symbol): Do not handle got_funcdesc entries
+ here. Rename sgot to sgotplt and srel to srelplt. Handle short_plt,
+ FDPIC descriptors, and got20. Create R_SH_FUNCDESC_VALUE for FDPIC.
+ Use install_movi20_field. Rename srel to srelgot. Always generate
+ R_SH_DIR32 for FDPIC instead of R_SH_RELATIVE.
+ (sh_elf_finish_dynamic_sections): Fill in the GOT pointer in rofixup.
+ Do not fill in reserved GOT entries for FDPIC. Correct DT_PLTGOT.
+ Rename sgot to sgotplt. Assert that the right number of rofixups
+ and dynamic relocations were allocated.
+ (sh_elf_use_relative_eh_frame, sh_elf_encode_eh_address): New.
+ (elf_backend_omit_section_dynsym): Use sh_elf_omit_section_dynsym.
+ (elf_backend_can_make_relative_eh_frame)
+ (elf_backend_can_make_lsda_relative_eh_frame)
+ (elf_backend_encode_eh_address): Define.
+ (TARGET_BIG_SYM, TARGET_BIG_NAME, TARGET_LITTLE_SYM)
+ (TARGET_LITTLE_NAME, elf_backend_modify_program_headers, elf32_bed):
+ Redefine for FDPIC vector.
+ * reloc.c: Add SH FDPIC and movi20 relocations.
+ * targets.c (_bfd_target_vector): Add FDPIC vectors.
+ * configure, bfd-in2.h, libbfd.h: Regenerated.
+
+2010-05-25 Jay Krell <jay.krell@cornell.edu>
+
+ PR ld/11624
+ * archive.c (_bfd_calloc_wrapper): New function.
+ (_bfd_add_bfd_to_archive_cache): Use it.
+
+ * configure.in: Add alpha*-*-*vms* to list of natives.
+ * configure: Regenerate.
+
+ * vms-misc.c: Define globalref if necessary.
+ (vms_convert_to_var_unix_filename): Rename to
+ _bfd_vms_convert_to_var_unix_filename and export.
+ * vms.h: Add prototype for _bfd_vms_convert_to_var_unix_filename.
+ * vms-alpha.c (vms_close_and_cleanup): Update invocation of
+ vms_convert_to_var_unix_filename.
+
+2010-05-24 Tristan Gingold <gingold@adacore.com>
+
+ * vms-alpha.c (add_symbol_entry): New function extrated from ...
+ (add_symbol): ... adjusted.
+
+2010-05-24 Tristan Gingold <gingold@adacore.com>
+
+ * vms-alpha.c (_bfd_vms_slurp_egsd): Fix indentation.
+ (alpha_vms_write_exec): Add a comment.
+ (_bfd_vms_write_egsd): Ditto.
+ (alpha_vms_convert_symbol): Remove a blank line.
+
+2010-05-21 Tristan Gingold <gingold@adacore.com>
+
+ * vms-alpha.c (_bfd_vms_slurp_eihs): Do not create a bfd section
+ for the GST.
+
+2010-05-21 Tristan Gingold <gingold@adacore.com>
+
+ * vms-alpha.c (_bfd_vms_slurp_eisd): Set SEC_HAS_CONTENTS and
+ SEC_LOAD if isect has data.
+ (vms_get_symbol_info): Refine the condition for 'T' type.
+
+2010-05-18 Tristan Gingold <gingold@adacore.com>
+
+ * vms-alpha.c (_bfd_vms_write_emh): New function.
+ (_bfd_vms_write_lmn): New function.
+ (_bfd_vms_write_eeom): Moved.
+ (hash_string): Likewise.
+ (_bfd_vms_length_hash_symbol): Likewise.
+ (_bfd_vms_write_ehdr): Code moved to _bfd_vms_write_emh
+ and _bfd_vms_write_lmn, and call these functions.
+
+2010-05-18 Tristan Gingold <gingold@adacore.com>
+
+ * vms-alpha.c (evax_bfd_print_dst): Handle INCR_LINUM_L.
+ Add details in the messages.
+ (evax_bfd_print_image): Change message.
+
+2010-05-18 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR gas/11600
+ * elf.c (_bfd_elf_make_section_from_shdr): Handle SHF_EXCLUDE
+ (elf_fake_sections): Likewise.
+
+ * elf32-i370.c (i370_elf_section_from_shdr): Don't handle
+ SHF_EXCLUDE here.
+ * elf32-ppc.c (ppc_elf_fake_sections): Likewise.
+
+2010-05-17 Tristan Gingold <gingold@adacore.com>
+
+ * vms-alpha.c: Include esgps.h and eidc.h.
+ (_bfd_vms_slurp_egsd): Ignore SPSC and IDC sub-records.
+ (evax_bfd_print_egsd_flags): New function, extracted from ...
+ (evax_bfd_print_egsd): ..., calls evax_bfd_print_egsd_flags. Handles
+ EGSD__C_SPSC and EGSD__C_IDC.
+
+2010-05-14 Tristan Gingold <gingold@adacore.com>
+
+ * vms-alpha.c (alpha_vms_object_p): Accept header size of 0.
+ (_bfd_vms_get_object_record): Handle align byte only in the
+ foreign case.
+
+2010-05-14 Tristan Gingold <gingold@adacore.com>
+
+ * vms-lib.c (_bfd_vms_lib_ia64_archive_p): New function.
+ * libbfd-in.h (_bfd_vms_lib_ia64_archive_p): Add prototype.
+ * libbfd.h: Regenerate.
+ * configure.in (havevecs): Define HAVE_all_vecs when
+ --enable-targets=all is set. Use AC_SUBST on it.
+ (tdefaults): Do not add havevecs.
+ (bfd_elf64_ia64_vms_vec): Add vms-lib.lo and vms-misc.lo
+ * configure: Regenerate.
+ * Makefile.am (HAVEVECS): New variable.
+ (INCLUDES): Add HAVEVECS.
+ * Makefile.in: Regenerate.
+ * elfxx-ia64.c (INCLUDE_IA64_VMS): New macro, defined if vms
+ target is selected. Add #ifdef/#endif around vms specific code.
+ (bfd_elfNN_archive_p, bfd_elfNN_archive_slurp_armap,
+ bfd_elfNN_archive_slurp_extended_name_table,
+ bfd_elfNN_archive_construct_extended_name_table,
+ bfd_elfNN_archive_truncate_arname,
+ bfd_elfNN_archive_write_armap,
+ bfd_elfNN_archive_read_ar_hdr,
+ bfd_elfNN_archive_write_ar_hdr,
+ bfd_elfNN_archive_openr_next_archived_file,
+ bfd_elfNN_archive_get_elt_at_index,
+ bfd_elfNN_archive_generic_stat_arch_elt,
+ bfd_elfNN_archive_update_armap_timestamp): Define to use vms archives.
+
+2010-05-11 Jie Zhang <jie@codesourcery.com>
+
+ * elf32-arm.c (elf32_arm_merge_eabi_attributes): Merge
+ Tag_ABI_HardFP_use correctly.
+
+2010-05-11 Alan Modra <amodra@gmail.com>
+
+ * coffcode.h (coff_write_object_contents): Enclose all occurrences
+ of hasdebug and is_reloc_section in #ifdef COFF_IMAGE_WITH_PE.
+
+2010-05-07 Daniel Jacobowitz <dan@codesourcery.com>
+
+ * elf32-arm.c (struct a8_erratum_reloc): Add hash member. Move
+ sym_name to improve packing.
+ (cortex_a8_erratum_scan): Check for PLT entries.
+ (elf32_arm_size_stubs): Save the target symbol for a8 relocs.
+
+2010-05-07 Tristan Gingold <gingold@adacore.com>
+
+ * Makefile.in: Regenerate with automake 1.11.1.
+ * aclocal.m4: Ditto.
+
+2010-05-05 Nick Clifton <nickc@redhat.com>
+
+ * po/es.po: Updated Spanish translation.
+
+2010-05-03 Tristan Gingold <gingold@adacore.com>
+
+ * vms-lib.c (vms_lib_bopen): Fix the size threshold to read
+ selective_search flag.
+ Add comments.
+ * vms-alpha.c (alpha_vms_bfd_final_link): Create the DMT section
+ before output_has_begun is set.
+
+2010-05-03 Tristan Gingold <gingold@adacore.com>
+
+ * vms-alpha.c: Add comments.
+ (struct vms_private_data_struct): Remove image_autoextend field.
+ (dst_check_allocation): Removed.
+ (image_write): Remove call to dst_check_allocation.
+ (vms_slurp_debug): Do not set image_autoextend. Adjust section
+ size.
+ (_bfd_vms_slurp_object_records): Remove useless new_type variable.
+ (alpha_vms_write_exec): Use dst_section to get the dst section.
+ Write the dmt section.
+ (evax_bfd_print_image): Also print the dst size in hexa. Fix typo.
+ (alpha_vms_read_sections_content): Do not set image_autoextend.
+ (alpha_vms_bfd_final_link): Generate the dst.
+
+2010-05-03 Tristan Gingold <gingold@adacore.com>
+
+ * vms-lib.c (_bfd_vms_lib_archive_p): Adjust for a possible empty
+ next array.
+ (vms_lib_dcx): Adjust for the above change.
+
+2010-04-30 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/11542
+ * elf-bfd.h (RELOC_AGAINST_DISCARDED_SECTION): New.
+
+ * elf32-i386.c (elf_i386_relocate_section): Use it.
+ * elf64-x86-64.c (elf64_x86_64_relocate_section): Likewise.
+
+2010-04-30 Tristan Gingold <gingold@adacore.com>
+
+ * vms-lib.c (vms_read_block): New function.
+ (vms_traverse_index): Use vms_read_block. Handle long key names.
+
+2010-04-30 Tristan Gingold <gingold@adacore.com>
+
+ * vms-lib.c (struct lib_tdata): Field artdata added, fields nbr_syms
+ and syms removed.
+ (struct carsym_mem): New structure.
+ (vms_add_index): New function.
+ (vms_add_indexes_from_list): New function.
+ (vms_traverse_index): Parameter carsym changed to carsym_mem.
+ Code adjusted to handle elfidx.
+ (vms_lib_read_index): Adjusted for vms_traverse_index changes.
+ Parameter NBREL is now a pointer.
+ (_bfd_vms_lib_archive_p): Adjust for above change. Handle ia64
+ archives.
+ (_bfd_vms_lib_mkarchive): Adjusted for changes in struct lib_tdata.
+ (_bfd_vms_lib_find_symbol): Ditto.
+ (vms_lib_bopen): Fix two typos: return FALSE in case of error,
+ check MHD id.
+ (_bfd_vms_lib_get_module): New function.
+ (_bfd_vms_lib_get_elt_at_index): Rewritten using the above
+ function.
+ (_bfd_vms_lib_openr_next_archived_file): Use _bfd_vms_lib_get_module.
+ (_bfd_vms_lib_generic_stat_arch_elt): Handle ia64 archives.
+ (vms_write_index): Adjust for structure renamed.
+ * vms-alpha.c (alpha_vms_link_add_archive_symbols): Adjust for
+ changes of _bfd_vms_lib_find_symbol.
+
+2010-04-28 Kai Tietz <kai.tietz@onevision.com>
+
+ * config.bfd: Correct accidential reverted patch
+ about vax*-*-*vms*.
+
+2010-04-27 Kai Tietz <kai.tietz@onevision.com>
+
+ * pe-x86_64.c (TARGET_UNDERSCORE): Set value dependent
+ to USE_MINGW64_LEADING_UNDERSCORES.
+ * pei-x86_64.c (TARGET_UNDERSCORE): Likewise.
+ * config.bfd: Change underscoring default for x64 mingw
+ to false.
+ * coffcode.h (coff_write_relocs): Add check that dereferenced
+ sym_ptr_ptr isn't NULL.
+ * config.in (USE_MINGW64_LEADING_UNDERSCORES): New.
+ * configure: Regenerated.
+ * configure.in: Add option '--enable-leading-mingw64-underscores'
+ and define config.in variable USE_MINGW64_LEADING_UNDERSCORES.
+
+2010-04-27 Nick Clifton <nickc@redhat.com>
+
+ PR binutils/11512
+ * coffgen.c (coff_find_nearest_line): Incldue the section address
+ of function name symbols in address comparisons.
+
+2010-04-27 Nick Clifton <nickc@redhat.com>
+
+ * po/fr.po: Updated French translation.
+
+2010-04-23 Alan Modra <amodra@gmail.com>
+
+ * elf.c: Replace use of ELF_IS_SECTION_IN_SEGMENT and
+ ELF_IS_SECTION_IN_SEGMENT_FILE with ELF_SECTION_IN_SEGMENT
+ throughout file.
+ (assign_file_positions_for_load_sections): Modify section in
+ segment warning to ignore overlay vmas.
+ * elf32-spu.c (spu_elf_object_p): Replace use of
+ ELF_IS_SECTION_IN_SEGMENT_MEMORY with ELF_SECTION_IN_SEGMENT.
+
+2010-04-22 Nick Clifton <nickc@redhat.com>
+
+ * po/bfd.pot: Updated by the Translation project.
+ * po/vi.po: Updated Vietnamese translation.
+
+2010-04-22 Alan Modra <amodra@gmail.com>
+
+ * elf.c (assign_file_positions_for_load_sections): Revert 2008-05-29
+ change. Tidy. Don't error on sections not allocated in segment.
+
+2010-04-15 Andrew Haley <aph@redhat.com>
+
+ * bfd-in.h (elf32_arm_fix_exidx_coverage): Add new flag:
+ merge_exidx_entries.
+ * bfd-in2.h: Likewise.
+ * elf32-arm.c (elf32_arm_fix_exidx_coverage): Likewise. Use it to
+ control merging of exidx entries.
+
+2010-04-20 Joseph Myers <joseph@codesourcery.com>
+
+ * elf32-tic6x.h: New.
+ * elf-bfd.h (enum elf_target_id): Define TIC6X_ELF_DATA.
+ * elf32-tic6x.c (struct elf32_tic6x_obj_tdata, elf32_tic6x_tdata,
+ elf32_tic6x_howto_table_rel, elf32_tic6x_info_to_howto_rel,
+ elf32_tic6x_set_use_rela_p, elf32_tic6x_mkobject,
+ elf32_tic6x_new_section_hook, elf32_tic6x_rel_relocation_p,
+ bfd_elf32_mkobject, bfd_elf32_new_section_hook): New.
+ (elf32_tic6x_reloc_type_lookup, elf32_tic6x_reloc_name_lookup,
+ elf32_tic6x_relocate_section): Handle REL relocations.
+ (elf_info_to_howto_rel): Define to elf32_tic6x_info_to_howto_rel.
+
+2010-04-20 Jakub Jelinek <jakub@redhat.com>
+
+ * dwarf2.c (find_abstract_instance_name, scan_unit_for_symbols): Treat
+ DW_AT_linkage_name the same as DW_AT_MIPS_linkage_name.
+
+2010-04-19 Nick Clifton <nickc@redhat.com>
+
+ * archive64.c (bfd_elf64_archive_slurp_armap): Remove unused
+ arhdrpos variable.
+ * elf64-x86-64.c (elf64_x86_64_relocate_section): Add unused
+ attribute to warned variable. Remove unused val, type and type2
+ variables.
+
+2010-04-16 Andreas Schwab <schwab@redhat.com>
+
+ * vms-alpha.c (alpha_vms_link_add_object_symbols): Avoid breaking
+ strict-aliasing rules.
+
+2010-04-16 Tristan Gingold <gingold@adacore.com>
+
+ * vms-alpha.c (_bfd_vms_slurp_eihd): Fix typo.
+ (_bfd_vms_get_object_record): Always assume there is a pad byte
+ for alignment.
+
+ * vms-lib.c: Add a few comments.
+
+2010-04-15 Matthew Gretton-Dann <matthew.gretton-dann@arm.com>
+
+ * elf32-arm.c (elf32_arm_merge_eabi_attributes): Support additions to
+ attributes in v2.08 of the ABI.
+
+2010-04-15 Alan Modra <amodra@gmail.com>
+
+ * config.bfd (vax*-*-*vms*): Delete.
+
+2010-04-14 Tristan Gingold <gingold@adacore.com>
+
+ * Makefile.am (BFD32_BACKENDS): Remove vms-gsd.lo, vms-hdr.lo,
+ vms-tir.lo, vms.lo and add vms-alpha.lo
+ (BFD32_BACKENDS_CFILES): Remove vms-gsd.c, vms-hdr.c,
+ vms-tir.c, vms.c and add vms-alpha.c
+ * Makefile.in: Regenerate.
+ * configure.in (TDEFINES): Adjust file list for vms_alpha_vec.
+ Remove vms_vax_vec.
+ * configure: Regenerate.
+ * targets.c (vms_vax_vec): Remove the declaration.
+ (_bfd_target_vector): Remove vms_vax_vec.
+ * vms-alpha.c: New file.
+ * vms-gsd.c: Removed, rewritten in vms-alpha.c
+ * vms-hdr.c: Ditto.
+ * vms-tir.c: Ditto.
+ * vms.c: Ditto.
+ * vms-misc.c: Fix indentation and comments. Replace most of
+ #if VMS_DEBUG/vms_debug with vms_debug2.
+ (_bfd_vms_hash_newfunc): Moved to vms-alpha.c
+ (hash_string): Ditto.
+ (_bfd_vms_length_hash_symbol): Ditto.
+ (maybe_adjust_record_pointer_for_object): Ditto.
+ (_bfd_vms_get_object_record): Ditto.
+ (vms_get_remaining_object_record): Ditto.
+ (_bfd_vms_push): Ditto.
+ (_bfd_vms_pop): Ditto.
+ (_bfd_vms_get_header_values): Removed.
+ (_bfd_vms_get_first_record): Removed.
+ (vms_get_remaining_image_record): Removed.
+ (new_symbol): Removed.
+ (_bfd_vms_enter_symbol): Removed.
+ (_bfd_vms_save_sized_string): Use memcpy instead of strncpy.
+ (_bfd_vms_output_begin): Remove rechead parameter. Replace bfd
+ parameter with struct vms_rec_wr.
+ (_bfd_vms_output_push): Removed and replaced by ...
+ (_bfd_vms_output_begin_subrec): ... new function.
+ (_bfd_vms_output_alignment): Replace bfd parameter with
+ struct vms_rec_wr, and adjust.
+ (_bfd_vms_output_check): Ditto
+ (_bfd_vms_output_byte): Ditto.
+ (_bfd_vms_output_short): Ditto.
+ (_bfd_vms_output_long): Ditto.
+ (_bfd_vms_output_quad): Ditto.
+ (_bfd_vms_output_counted): Ditto.
+ (_bfd_vms_output_dump): Ditto.
+ (_bfd_vms_output_fill): Ditto.
+ (_bfd_vms_output_pop): Removed and replaced by ...
+ (_bfd_vms_output_end_subrec): ... new function.
+ (_bfd_vms_output_flush): Removed.
+ (_bfd_vms_output_align): New function.
+ (_bfd_vms_output_end): Add recwr parameter. Adjust for this new
+ parameter.
+ (vms_convert_to_var): New function imported from vms.c
+ (vms_convert_to_var_1): Ditto.
+ (vms_convert_to_var_unix_filename): Ditto.
+ (vms_get_module_name): Ditto.
+ (get_vms_time_string): Ditto.
+ (vms_time_to_time_t): Ditto.
+ (vms_rawtime_to_time_t): Ditto.
+ * vms.h: All macros for the VMS file format are now in include/vms.
+ Prototypes for vms.c, vms-gsd.c, vms-misc.c, vms-hdr.c, vms-tir.c
+ have been removed.
+ (struct vms_symbol_struct, struct stack_struct): Moved to vms-alpha.c
+ (struct fileinfo, struct srecinfo, struct lineinfo): Ditto.
+ (struct funcinfo, struct vms_private_data_struct): Ditto.
+ (struct vms_section_data_struct): Ditto.
+ (struct vms_rec_rd, stryct vms_rec_wr): New declarations.
+ (vms_get_module_name, get_vms_time_string): New declarations.
+ (vms_time_to_time_t, vms_rawtime_to_time_t): Ditto.
+ (_bfd_vms_output_begin_subrec, _bfd_vms_output_end_subrec): Ditto.
+ (_bfd_vms_save_sized_string, _bfd_vms_save_counted_string): Adjusted.
+ (_bfd_vms_output_begin, _bfd_vms_output_alignment): Ditto.
+ (_bfd_vms_output_end,_bfd_vms_output_check): Ditto.
+ (_bfd_vms_output_byte, _bfd_vms_output_short): Ditto.
+ (_bfd_vms_output_long, _bfd_vms_output_quad): Ditto.
+ (_bfd_vms_output_counted, _bfd_vms_output_dump): Ditto.
+ (_bfd_vms_output_fill): Ditto.
+ (bfd_vms_set_section_flags): Ditto.
+
+2010-04-14 Matthew Gretton-Dann <matthew.gretton-dann@arm.com>
+
+ * elflink.c (_bfd_elf_merge_symbol): Tighten up the test for early
+ exit due to merging the same weak symbol to test that the symbols are
+ actually weak.
+
+2010-04-13 Alan Modra <amodra@gmail.com>
+
+ * elf64-ppc.c (ppc64_elf_relocate_section): Correct NOP location
+ when optimizing high got_tlsgd/ld insns.
+
+2010-04-10 H.J. Lu <hongjiu.lu@intel.com>
+
+ * hosts/x86-64linux.h (HAVE_PRPSINFO32_T): Undefine before
+ define.
+ (HAVE_PRSTATUS32_T): Likewise.
+
+2010-04-10 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR corefiles/11467
+ * configure.in (CORE_HEADER): New. Set to hosts/x86-64linux.h
+ for x86_64-*-linux*.
+ * config.in: Regenerated.
+ * configure: Likewise.
+
+ * elf.c: Include CORE_HEADER if it is defined.
+
+2010-04-10 H.J. Lu <hongjiu.lu@intel.com>
+ Jan Kratochvil <jan.kratochvil@redhat.com>
+
+ * hosts/x86-64linux.h: New.
+
+2010-04-09 Nick Clifton <nickc@redhat.com>
+
+ * aoutx.h (aout_link_input_bfd): Remove unused variable sym_count.
+ * elf-eh-frame.c (_bfd_elf_eh_frame_section_offset): Remove unused
+ variables htab and hdr_info and mark info parameter as unused.
+ * elf.c (prep_headers): Remove unused variable i_phdrp.
+ (_bfd_elf_write_object_contents): Remove unused variable i_ehdrp.
+ * elf32-i386.c (elf_i386_relocate_section): Mark variabled warned
+ as unused.
+ * peXXigen.c (pe_print_reloc): Remove unused variable datasize.
+ * verilog.c (verilog_write_section): Remove unused variable
+ address.
+
+2010-04-07 Alan Modra <amodra@gmail.com>
+
+ * warning.m4 (GCC_WARN_CFLAGS): Only add -Wshadow for gcc-4 and above.
+ * configure: Regenerate.
+
+2010-04-06 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/11434
+ * elf-bfd.h (SYMBOLIC_BIND): Don't bind unique symbol locally.
+
+2010-04-06 Tristan Gingold <gingold@adacore.com>
+
+ * vms-lib.c (_bfd_vms_lib_write_archive_contents): Fix idd flags.
+
+2010-04-05 Jakub Jelinek <jakub@redhat.com>
+
+ * elf-eh-frame.c (_bfd_elf_parse_eh_frame): Handle CIE version 4
+ provided that it has the expected address size and zero segment
+ length.
+
+ * dwarf2.c (struct line_head): Add maximum_ops_per_insn field.
+ (struct line_info): Add op_index field, change end_sequence type to
+ unsigned char.
+ (new_line_sorts_after): For the same address compare op_index.
+ (add_line_info): Add op_index argument, store it into the structure.
+ (decode_line_info): Complain about unknown versions of .debug_line.
+ Initialize maximum_ops_per_insn. Add op_index state register and
+ track it.
+
+2010-04-01 Nathan Sidwell <nathan@codesourcery.com>
+
+ * elf32-ppc.c (apuinfo_set): New static var.
+ (ppc_elf_begin_write_processing): Set it here, always create an
+ APUinfo section if there were any in the inputs.
+ (ppc_elf_write_section): Check apuinfo_set.
+ (ppc_elf_final_write_processing): Likewise.
+
+2010-04-01 Tristan Gingold <gingold@adacore.com>
+
+ * vms.h: Include time.h. Add prototypes for vms_get_module_name,
+ vms_time_to_time_t and vms_rawtime_to_time_t.
+ * vms.c (vms_alpha_vec): Add archives support.
+ * vms-misc.c: Include safe-ctype.h
+ (vms_get_module_name): New function.
+ (vms_time_to_time_t, vms_rawtime_to_time_t): Ditto.
+ * vms-hdr.c (_bfd_vms_write_hdr): Put module name creation to the
+ vms_get_module_name function. Use this function.
+ * targets.c: Declare vms_lib_txt_vec. Add it to _bfd_target_vector.
+ * libbfd-in.h: Add prototype for _bfd_append_relative_path.
+ Add prototypes for vms-lib.c
+ * libbfd.h: Regenerate.
+ * configure.in (TDEFINES): Add an entry for vms_lib_txt_vec. Add
+ vms-lib.lo to vms_alpha_vec.
+ * config.bfd (targ_cpu): Add targ_selvecs for alpha*-*-*vms*.
+ * configure: Regenerate.
+ * bfd.c: Add selective_search field.
+ * bfd-in2.h: Regenerate.
+ * archive.c (append_relative_path): Rename to
+ _bfd_append_relative_path and make it public.
+ (_bfd_get_elt_at_filepos): Adjust for above renaming.
+ * Makefile.am (BFD32_BACKENDS): Add vms-lib.lo
+ (BFD32_BACKENDS_CFILES): Add vms-lib.c
+ * Makefile.in: Regenerate.
+
+2010-04-01 Jakub Jelinek <jakub@redhat.com>
+
+ * dwarf2.c (read_attribute_value): Handle CU version 4
+ for DW_FORM_ref_addr, handle DW_FORM_sec_offset, DW_FORM_exprloc
+ and DW_FORM_flag_present. For unknown form value return NULL.
+ (scan_unit_for_symbols): For DW_AT_location handle DW_FORM_exprloc
+ like DW_FORM_block.
+ (parse_comp_unit): Allow CU version 4.
+
+2010-04-01 Hans-Peter Nilsson <hp@axis.com>
+
+ * elf32-cris.c (cris_elf_relocate_section): Correct first argument
+ to _bfd_elf_get_dynamic_reloc_section.
+ (elf_cris_discard_excess_dso_dynamics): Ditto.
+
+2010-03-31 Kai Tietz <kai.tietz@onevision.com>
+
+ * coff-i386.c (in_reloc_p): Check also for R_SECREL32.
+ * coff-x86_64.c (in_reloc_p): Check also for R_AMD64_SECREL.
+
+2010-03-31 Alan Modra <amodra@gmail.com>
+
+ * elf64-ppc.c (ppc64_elf_relocate_section): Nop out optimized
+ TPREL16_HI and TPREL16_HA insns.
+
+2010-03-31 Hans-Peter Nilsson <hp@axis.com>
+
+ PR ld/11458
+ * elf32-cris.c (elf_cris_copy_indirect_symbol): Remove invalid
+ assert of empty pcrel_relocs_copied on the direct symbol. Instead
+ of moving the list from the indirect symbol to the direct symbol,
+ merge into any existing list.
+ (cris_elf_check_relocs): Store the original section in the
+ pcrel_relocs_copied list, not the relocation section.
+ (elf_cris_discard_excess_dso_dynamics): Adjust accordingly to find
+ the relocation section, for reducing its size. Change the
+ BFD_ASSERT into a check for the section being read-only, and only
+ emit warnings and TEXTREL marker when there's an entry for a
+ read-only section.
+
+2010-03-29 Daniel Jacobowitz <dan@codesourcery.com>
+
+ * elf32-arm.c (using_thumb_only): Handle v6-M.
+
+2010-03-26 Alan Modra <amodra@gmail.com>
+
+ * elf32-ppc.c (ppc_elf_howto_raw <R_PPC_EMB_RELSDA>): Not pc-relative.
+ * bfd-in.h (elf_discarded_section): Clarify comment.
+ * reloc.c (struct reloc_howto_struct <pc_relative>): Likewise.
+ * bfd-in2.h: Regenerate.
+
+2010-03-26 Matt Rice <ratmice@gmail.com>
+
+ * archive.c (_bfd_compute_and_write_armap): Allow symbols flagged
+ as unique in the armap.
+
+2010-03-26 Alan Modra <amodra@gmail.com>
+
+ PR ld/11375
+ * elf64-ppc.c (ppc64_elf_relocate_section): Always look up a
+ possible stub on branches.
+
+2010-03-25 Joseph Myers <joseph@codesourcery.com>
+
+ * Makefile.am (ALL_MACHINES): Add cpu-tic6x.lo.
+ (ALL_MACHINES_CFILES): Add cpu-tic6x.c.
+ (BFD32_BACKENDS): Add elf32-tic6x.lo.
+ (BFD32_BACKENDS_CFILES): Add elf32-tic6x.c.
+ * Makefile.in: Regenerate.
+ * archures.c (bfd_arch_tic6x, bfd_tic6x_arch): New.
+ (bfd_archures_list): Update.
+ * config.bfd (tic6x-*-elf): New.
+ * configure.in (bfd_elf32_tic6x_be_vec, bfd_elf32_tic6x_le_vec):
+ New.
+ * configure: Regenerate.
+ * cpu-tic6x.c, elf32-tic6x.c: New.
+ * reloc.c (BFD_RELOC_C6000_PCR_S21, BFD_RELOC_C6000_PCR_S12,
+ BFD_RELOC_C6000_PCR_S10, BFD_RELOC_C6000_PCR_S7,
+ BFD_RELOC_C6000_ABS_S16, BFD_RELOC_C6000_ABS_L16,
+ BFD_RELOC_C6000_ABS_H16, BFD_RELOC_C6000_SBR_U15_B,
+ BFD_RELOC_C6000_SBR_U15_H, BFD_RELOC_C6000_SBR_U15_W,
+ BFD_RELOC_C6000_SBR_S16, BFD_RELOC_C6000_SBR_L16_B,
+ BFD_RELOC_C6000_SBR_L16_H, BFD_RELOC_C6000_SBR_L16_W,
+ BFD_RELOC_C6000_SBR_H16_B, BFD_RELOC_C6000_SBR_H16_H,
+ BFD_RELOC_C6000_SBR_H16_W, BFD_RELOC_C6000_SBR_GOT_U15_W,
+ BFD_RELOC_C6000_SBR_GOT_L16_W, BFD_RELOC_C6000_SBR_GOT_H16_W,
+ BFD_RELOC_C6000_DSBT_INDEX, BFD_RELOC_C6000_PREL31,
+ BFD_RELOC_C6000_COPY, BFD_RELOC_C6000_ALIGN,
+ BFD_RELOC_C6000_FPHEAD, BFD_RELOC_C6000_NOCMP): New.
+ * targets.c (bfd_elf32_tic6x_be_vec, bfd_elf32_tic6x_le_vec): New.
+ (_bfd_target_vector): Update.
+ * bfd-in2.h, libbfd.h: Regenerate.
+
+2010-03-24 H.J. Lu <hongjiu.lu@intel.com>
+
+ * aout-target.h: Update copyright year.
+ * aout-tic30.c: Likewise.
+ * coff-alpha.c: Likewise.
+ * coff-rs6000.c: Likewise.
+ * coff64-rs6000.c: Likewise.
+ * elf64-mips.c: Likewise.
+ * ieee.c: Likewise.
+ * libecoff.h: Likewise.
+ * mach-o-target.c: Likewise.
+ * mach-o.c: Likewise.
+ * oasys.c: Likewise.
+ * targets.c: Likewise.
+
+2010-03-24 H.J. Lu <hongjiu.lu@intel.com>
+
+ * libbfd-in.h: Update copyright year.
+
+2010-03-21 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/11413
+ * elflink.c (_bfd_elf_add_default_symbol): Check !executable
+ instead of shared.
+
+2010-03-19 Jie Zhang <jie@codesourcery.com>
+
+ * elf32-arm.c (struct section_list): Remove.
+ (section_list): Remove typedef.
+ (record_section_with_arm_elf_section_data): Remove.
+ (find_arm_elf_section_entry): Remove.
+ (get_arm_elf_section_data): Use is_arm_elf.
+ (unrecord_section_with_arm_elf_section_data): Remove.
+ (elf32_arm_new_section_hook): Don't call
+ record_section_with_arm_elf_section_data.
+ (elf32_arm_write_section): Set mapcount to -1 when
+ the map has been used. Don't call
+ unrecord_section_with_arm_elf_section_data.
+ (unrecord_section_via_map_over_sections): Remove.
+ (elf32_arm_close_and_cleanup): Remove.
+ (elf32_arm_bfd_free_cached_info): Remove.
+ (bfd_elf32_close_and_cleanup): Don't define.
+ (bfd_elf32_bfd_free_cached_info): Don't define.
+
+2010-03-18 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR binutils/11396
+ * libcoff-in.h (pe_tdata): Add dont_strip_reloc.
+ * libcoff.h: Regenerated.
+
+ * peXXigen.c (_bfd_XXi_only_swap_filehdr_out): Clear F_RELFLG
+ if dont_strip_reloc is set.
+ (_bfd_XX_bfd_copy_private_bfd_data_common): Set
+ dont_strip_reloc on output if there is no .reloc and
+ IMAGE_FILE_RELOCS_STRIPPED isn't set in input.
+
+2010-03-18 Wei Guozhi <carrot@google.com>
+
+ PR gas/11323
+ * elf32-arm.c (elf32_arm_reloc_map): Map BFD_RELOC_ARM_GOT_PREL to
+ R_ARM_GOT_PREL.
+ * reloc.c (BFD_RELOC_ARM_GOT_PREL): New ARM relocation.
+ * bfd-in2.h: Regenerate.
+ * libbfd.h: Regenerate.
+
+2010-03-17 H.J. Lu <hongjiu.lu@intel.com>
+
+ * reloc.c (BFD_RELOC_SPU_PIC18): Removed.
+ (BFD_RELOC_SPU_STUB): Likewise.
+
+2010-03-17 Jie Zhang <jie@codesourcery.com>
+
+ * elf.c (assign_file_positions_for_load_sections): Avoid
+ overflow.
+
+2010-03-17 Alan Modra <amodra@gmail.com>
+
+ PR binutils/11382
+ * plugin.c (bfd_plugin_object_p): Pass iostream to fileno using
+ proper type.
+
+2010-03-17 Alan Modra <amodra@gmail.com>
+
+ * elf32-arm.c (cortex_a8_erratum_scan): Warning fix.
+
+2010-03-16 Alan Modra <amodra@gmail.com>
+
+ * elf64-ppc.c (struct ppc_link_hash_table): Add do_toc_opt.
+ (ppc64_elf_edit_toc): Set it here.
+ (ha_reloc_match): New function.
+ (ppc64_elf_relocate_section): Optimize bigtoc insn sequences.
+
+2010-03-15 Alan Modra <amodra@gmail.com>
+
+ * elf64-ppc.c (ppc64_elf_has_small_toc_reloc): New function.
+ * elf64-ppc.h (ppc64_elf_has_small_toc_reloc): Declare.
+
+2010-03-14 Alan Modra <amodra@gmail.com>
+
+ PR ld/11378
+ * elf64-ppc.h (ppc64_elf_check_init_fini): Declare.
+ * elf64-ppc.c (call_check_done): Define.
+ (ppc64_elf_add_symbol_hook): Substitute bfd_get_section_name macro.
+ (ppc64_elf_check_relocs, ppc64_elf_size_dynamic_sections): Likewise.
+ (ppc64_elf_finish_multitoc_partition): Remove unnecessary check.
+ (toc_adjusting_stub_needed): Use call_check_done rather than toc_off.
+ Simplify return logic. Iterate over all .init and .fini fragments
+ by recursion. Set makes_toc_func_call here..
+ (ppc64_elf_next_input_section): ..rather than here.
+ (check_pasted_section, ppc64_elf_check_init_fini): New functions.
+
+2010-03-13 Alan Modra <amodra@gmail.com>
+
+ PR ld/11375
+ * elf64-ppc.c (ppc_type_of_stub): Always set *hash to the
+ function descriptor symbol if there is one, not just for plt stubs.
+ (ppc64_elf_relocate_section): Use fdh on all ppc_get_stub_entry calls.
+
+2010-03-05 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
+
+ * elflink.c (bfd_elf_size_dynamic_sections): Don't emit base
+ version twice.
+ Skip it when constructing def.vd_next.
+
+ * elf32-i386.c (TARGET_LITTLE_SYM): Redefine to
+ bfd_elf32_i386_sol2_vec.
+ (TARGET_LITTLE_NAME): Redefine to elf32-i386-sol2.
+ (elf32_bed): Redefine to elf32_i386_sol2_bed.
+ (elf_backend_want_plt_sym): Redefine to 1.
+
+ * elf64-x86-64.c (TARGET_LITTLE_SYM): Redefine to
+ bfd_elf64_x86_64_sol2_vec.
+ (TARGET_LITTLE_NAME): Redefine to elf64-x86-64-sol2.
+ (elf64_bed): Redefine to elf64_x86_64_sol2_bed.
+ (elf_backend_want_plt_sym): Redefine to 1.
+
+ * config.bfd (i[3-7]86-*-solaris2*): Set targ_defvec to
+ bfd_elf32_i386_sol2_vec.
+ Replace bfd_elf64_x86_64_vec by bfd_elf64_x86_64_sol2_vec in
+ targ64_selvecs.
+ (x86_64-*-solaris2*): Set targ_defvec to bfd_elf32_i386_sol2_vec.
+ Replace bfd_elf64_x86_64_vec by bfd_elf64_x86_64_sol2_vec in
+ targ_selvecs.
+
+ * configure.in: Handle bfd_elf32_i386_sol2_vec,
+ bfd_elf64_x86_64_sol2_vec.
+ * configure: Regenerate.
+
+ * targets.c (bfd_elf32_i386_sol2_vec): Declare.
+ (bfd_elf64_x86_64_sol2_vec): Declare.
+ (_bfd_target_vector): Add bfd_elf32_i386_sol2_vec,
+ bfd_elf64_x86_64_sol2_vec.
+
+2010-03-04 Daniel Jacobowitz <dan@codesourcery.com>
+
+ * elf32-arm.c (elf32_arm_output_arch_local_syms): Skip non-program
+ sections.
+
+2010-03-04 Alan Modra <amodra@gmail.com>
+
+ PR 11302
+ * dwarf2.c (read_abbrevs): Return NULL on alloc failures.
+ (read_attribute_value, decode_line_info): Likewise.
+ (add_line_info, read_rangelist): Return FALSE on alloc failures.
+ (arange_add, sort_line_sequences): Likewise.
+ (find_abstract_instance_name): Handle failures from called funcs.
+ (scan_unit_for_symbols, parse_comp_unit, decode_line_info): Likewise.
+ (find_line): Realloc to a temp, and handle alloc fail.
+
+2010-03-03 Daniel Jacobowitz <dan@codesourcery.com>
+
+ * elf32-arm.c (elf32_arm_output_arch_local_syms): Do not add
+ a mapping symbol to an empty section.
+
+2010-03-02 Matthew Gretton-Dann <matthew.gretton-dann@arm.com>
+
+ * elf32-arm.c (elf32_arm_merge_eabi_attributes): Add a check of the
+ return value from the call to _bfd_elf_merge_object_attributes.
+
+2010-03-02 Christophe Lyon <christophe.lyon@st.com>
+ Alan Modra <amodra@gmail.com>
+
+ * elf32-arm.c (a8_erratum_fix): Add st_type field to record the
+ destination mode of the a8 stub.
+ (elf32_arm_link_hash_table): Add top_id field.
+ (elf32_arm_link_hash_table_create): Initialize top_id.
+ (arm_type_of_stub): Update prototype, st_type can now be updated
+ by this function. Actual destination address in case of PLT is
+ computed here, to help factorizing code.
+ (elf32_arm_stub_name): Update prototype, use stub_type additional
+ parameter to build stub name.
+ (elf32_arm_get_stub_entry): Update prototype, use stub_type
+ additional parameter to build stub entry.
+ (arm_build_one_stub): Use bfd_put_16/bfd_put_32 instead of
+ put_thumb_insn/put_arm_insn as BE8 encoding is now handled later.
+ Call elf32_arm_final_link_relocate to process all in-stub
+ relocations.
+ (elf32_arm_setup_section_lists): Update top_id.
+ (cortex_a8_erratum_scan): Record stub destination mode.
+ (elf32_arm_size_stubs): Update call to arm_type_of_stub according
+ to new prototype.
+ (elf32_arm_final_link_relocate): Enable processing of in-stub
+ REL32 relocations. Rely on arm_type_of_stub to detect if a stub is
+ needed, enabling code factorization.
+ (elf32_arm_final_link): Process stub sections.
+ (elf32_arm_output_map_sym): Add entry to code/data map.
+
+2010-03-01 David S. Miller <davem@davemloft.net>
+
+ * elfxx-sparc.c (_bfd_sparc_elf_check_relocs): When STT_GNU_IFUNC and
+ h->def_regular, set h->ref_regular.
+ (allocate_dynrelocs): Only force output of STT_GNU_IFUNC plt entries
+ and dynamic relocations if h->ref_regular.
+
+ * elfxx-sparc.c (struct elf_reloc_map): Delete.
+ (sparc_reloc_map): Delete.
+ (_bfd_sparc_elf_reloc_type_lookup): Explicitly handle each
+ relocation type in switch statements.
+
+2010-02-25 Alan Modra <amodra@gmail.com>
+
+ PR ld/11304
+ * elf.c (_bfd_elf_init_private_section_data): Rename need_group
+ to final_link and invert. For final link allow some flags to
+ differ. Don't specially allow flags to be all zero.
+
+2010-02-24 Alan Modra <amodra@gmail.com>
+
+ PR binutils/10858
+ * elfxx-mips.c (mips_elf_create_dynamic_relocation): Ise
+ SYMBOL_REFERENCES_LOCAL to exclude entries from the dynamic symbol
+ table.
+
+2010-02-23 Andrew Zabolotny <anpaza@mail.ru>
+
+ PR binutils/11297
+ * elf32-avr.c (elf_avr_howto_table): Add R_AVR_8.
+ (avr_reloc_map): Map BFD_RELOC_8 to R_AVR_8.
+
+2010-02-22 Alan Modra <amodra@gmail.com>
+
+ * reloc.c (bfd_check_overflow): When forming addrmask, shift
+ fieldmask left by rightshift.
+ (_bfd_relocate_contents): Likewise. Use rightshift addrmask in all
+ overflow checks.
+
+2010-02-20 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf64-x86-64.c (elf64_x86_64_add_symbol_hook): Don't check
+ STT_GNU_IFUNC on large common symbol.
+
+2010-02-18 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf32-i386.c (elf_i386_add_symbol_hook): Don't set
+ has_ifunc_symbols if the symbol comes from a shared library.
+ * elf32-ppc.c (ppc_elf_add_symbol_hook): Likewise.
+ * elf32-sparc.c (elf32_sparc_add_symbol_hook): Likewise.
+ * elf64-ppc.c (ppc64_elf_add_symbol_hook): Likewise.
+ * elf64-sparc.c (elf64_sparc_add_symbol_hook): Likewise.
+ * elf64-x86-64.c (elf64_x86_64_add_symbol_hook): Likewise.
+
+2010-02-19 Alan Modra <amodra@gmail.com>
+
+ * elf.c (_bfd_elf_fixup_group_sections): New function, split out from..
+ (_bfd_elf_copy_private_header_data): ..here.
+ * elflink.c (_bfd_elf_size_group_sections): New function.
+ (bfd_elf_size_dynamic_sections): Call it.
+ * elf-bfd.h (_bfd_elf_size_group_sections): Declare.
+ (_bfd_elf_fixup_group_sections): Declare.
+
+2010-02-18 Matthew Gretton-Dann <matthew.gretton-dann@arm.com>
+
+ * elf32-arm.c (elf32_arm_merge_eabi_attributes): Add support for
+ merging Tag_DIV_use, Tag_MPextension_use, and
+ Tag_MPextension_use_legacy tags.
+
+2010-02-18 Alan Modra <amodra@gmail.com>
+
+ * elf.c (bfd_elf_set_group_contents): Revert accidental 2009-01-15
+ commit. Don't write zeros for removed group members.
+ (_bfd_elf_copy_private_header_data): Adjust size of group section
+ when group members are removed by objcopy.
+
+2010-02-15 Dave Korn <dave.korn.cygwin@gmail.com>
+
+ PR binutils/11280
+ * configure.host (*-*-solaris2.11): Add host define to select
+ valid default code page for windres/windmc on solaris.
+
+2010-02-15 Nick Clifton <nickc@redhat.com>
+
+ * po/vi.po: Updated Vietnamese translation.
+
+2010-02-12 Daniel Gutson <dgutson@codesourcery.com>
+
+ * elf32-arm.c (elf32_arm_output_arch_local_syms): add
+ missing mapping symbol to data only sections.
+
+2010-02-11 David S. Miller <davem@davemloft.net>
+
+ * elfxx-sparc.c (_bfd_sparc_elf_check_relocs): For R_SPARC_GOTDATA_OP_HIX22
+ and R_SPARC_GOTDATA_OP_LOX10, only bump the GOT refcount for global
+ symbols.
+ (_bfd_sparc_elf_gc_sweep_hook): Likewise only decrement the GOT count for
+ these relocs on global symbols.
+ (gdopoff): New.
+ (_bfd_sparc_elf_relocate_section): Perform GOTDATA optimizations on
+ local symbol references which are not STT_GNU_IFUNC. Handle
+ relocation of them like R_SPARC_HIX22 and R_SPARC_LOX10 respectively,
+ and deal with negative vs. non-negative values properly.
+
+2010-02-09 Tristan Gingold <gingold@adacore.com>
+
+ * mach-o.c (bfd_mach_o_canonicalize_one_reloc): Adjust addend for
+ non-external relocation.
+
+2010-02-09 Alan Modra <amodra@gmail.com>
+
+ * elf64-ppc.c (merge_got_entries): Move earlier in file.
+ (allocate_dynrelocs): Merge got entries here if not doing multi-toc.
+ (ppc64_elf_size_dynamic_sections): Similarly merge tlsld_got.
+ (ppc64_elf_layout_multitoc): Don't resize if we have already
+ merged got entries.
+
+2010-02-09 Michael Holzheu <holzheu@de.ibm.com>
+
+ * elf-bfd.h (elfcore_write_s390_timer, elfcore_write_s390_todcmp,
+ elfcore_write_s390_todpreg, elfcore_write_s390_ctrs,
+ elfcore_write_s390_prefix): New.
+ * elf.c (elfcore_write_s390_timer, elfcore_write_s390_todcmp,
+ elfcore_write_s390_todpreg, elfcore_write_s390_ctrs,
+ elfcore_write_s390_prefix): New.
+ (elfcore_grok_note): Handle NT_S390_TIMER, NT_S390_TODCMP,
+ NT_S390_TODPREG, NT_S390_CTRS and NT_S390_PREFIX.
+ (elfcore_write_register_note): Handle .reg-s390-timer,
+ .reg-s390-todcmp, .reg-s390-todpreg, .reg-s390-ctrs,
+ .reg-s390-prefix section.
+
+2010-02-09 Alan Modra <amodra@gmail.com>
+
+ * elf64-ppc.c (struct got_entry): Make tls_type and is_indirect
+ unsigned char. Update variables and code using them throughout file.
+ (struct ppc_link_hash_entry): Likewise for tls_mask.
+
+ * elf64-ppc.c (ppc64_elf_layout_multitoc): Don't merge local got ents.
+
+ * elf64-ppc.c (has_small_toc_reloc): Don't define.
+ (makes_toc_func_call, call_check_in_progress): Shuffle flags.
+ (struct ppc64_elf_obj_tdata): Add has_small_toc_reloc. Update
+ code setting the flag.
+ (ppc64_elf_next_toc_section): Group big-toc sections in
+ 0x80008000 chunks.
+
+2010-02-08 David S. Miller <davem@davemloft.net>
+
+ * elfxx-sparc.h (struct _bfd_sparc_elf_link_hash_table): Remove sgot,
+ srelgot, splt, srelplt, and sgotplt members in favor of generic copies.
+
+ * elfxx-sparc.c (create_got_section): Delete.
+ (_bfd_sparc_elf_create_dynamic_sections): Don't call, the dynamic
+ section creator does that work for us. Use ->elf.foo instead of
+ ->foo where applicable.
+ (_bfd_sparc_elf_check_relocs): Use ->elf.foo instead of ->foo
+ where applicable.
+ (allocate_dynrelocs): Likewise.
+ (_bfd_sparc_elf_size_dynamic_sections): Likewise.
+ (_bfd_sparc_elf_relocate_section): Likewise.
+ (sparc_vxworks_build_plt_entry): Likewise.
+ (_bfd_sparc_elf_finish_dynamic_symbol): Likewise.
+ (sparc_finish_dyn): Likewise.
+ (sparc_vxworks_finish_exec_plt): Likewise.
+ (sparc_vxworks_finish_shared_plt): Likewise.
+ (_bfd_sparc_elf_finish_dynamic_sections): Likewise.
+
+ * elfxx-sparc.c (_bfd_sparc_elf_check_relocs): Use the SYMBOL_*
+ macros for visibilty and locality checks.
+ (_bfd_sparc_elf_adjust_dynamic_symbol): Likewise.
+ (allocate_dynrelocs): Likewise.
+ (_bfd_sparc_elf_relocate_section): Likewise.
+ (_bfd_sparc_elf_finish_dynamic_symbol):Likewise.
+
+ * elfxx-sparc.c (_bfd_sparc_elf_finish_dynamic_symbol): Remove set
+ but never used local var 'dynobj'.
+
+ * elfxx-sparc.c (_bfd_sparc_elf_adjust_dynamic_symbol): Handle
+ nocopyreloc.
+
+ * reloc.c (BFD_RELOC_SPARC_JMP_IREL): New.
+ (BFD_RELOC_SPARC_IRELATIVE): Likewise.
+ * bfd-in2.h: Regenerate.
+ * libbfd.h: Regenerate.
+
+ * elfxx-sparc.h (_bfd_sparc_elf_link_hash_table): Add loc_hash_table
+ and loc_hash_memory.
+ (_bfd_sparc_elf_link_hash_table_free): Declare.
+ * elf32-sparc.c (elf32_sparc_add_symbol_hook): New.
+ (elf_backend_add_symbol_hook, elf_backend_post_process_headers,
+ bfd_elf32_bfd_link_hash_table_free): Define.
+ * elf64-sparc.c (elf64_sparc_add_symbol_hook): Set
+ has_ifunc_symbols if STT_GNU_IFUNC.
+ (bfd_elf64_bfd_link_hash_table_free): Define.
+ (elf_backend_post_process_headers): Define always.
+ * elfxx-sparc.c (sparc_jmp_irel_howto, sparc_irelative_howto): New.
+ (sparc_reloc_map): Add entries for new IFUNC relocs.
+ (_bfd_sparc_elf_reloc_type_lookup): Handle new IFUNC relocs.
+ (_bfd_sparc_elf_info_to_howto_ptr): Likewise.
+ (elf_sparc_local_htab_hash, elf_sparc_local_htab_eq,
+ elf_sparc_get_local_sym_hash): New.
+ (_bfd_sparc_elf_create_dynamic_sections): Move PLT ops initialization
+ from here...
+ (_bfd_sparc_elf_link_hash_table_create): ... to here. Allocate
+ local hash table.
+ (_bfd_sparc_elf_link_hash_table_free): New.
+ (create_ifunc_sections): New.
+ (_bfd_sparc_elf_check_relocs): Unconditionally assign htab->elf.dynobj
+ and call create_ifunc_sections(). For local STT_GNU_IFUNC symbols
+ cons up a fake local hash table entry for it. Unconditionally add
+ a PLT refcount for STT_GNU_IFUNC symbols when h->def_regular. Count
+ dyn relocs for ifunc.
+ (_bfd_sparc_elf_adjust_dynamic_symbol): Handle ifunc.
+ (allocate_dynrelocs): Unconditionally emit a PLT entry when
+ STT_GNU_IFUNC and h->def_regular. Count GOT dyn relocs for ifunc.
+ (allocate_local_dynrelocs): New function.
+ (_bfd_sparc_elf_size_dynamic_sections): Invoke it over the local hash
+ table. Emit dynamic relocs to irelplt when not shared. Treat iplt
+ like splt.
+ (_bfd_sparc_elf_relocate_section): Handle ifunc relocations by hand.
+ (_bfd_sparc_elf_finish_dynamic_symbol): Adjust for non-dynamic ifunc
+ plt in iplt/irelplt.
+
+2010-02-08 Richard Sandiford <r.sandiford@uk.ibm.com>
+
+ * xcofflink.c (_bfd_xcoff_bfd_final_link): When calculating
+ max_contents_size, only consider sections whose contents must
+ be swapped in.
+
+2010-02-09 Alan Modra <amodra@gmail.com>
+
+ * elf64-ppc.c (allocate_dynrelocs): Remove unused got structs here..
+ (ppc64_elf_size_dynamic_sections): ..and here..
+ (merge_got_entries): ..rather than here.
+
+2010-02-09 Alan Modra <amodra@gmail.com>
+
+ * elf64-ppc.c (struct ppc_link_hash_table): Add do_multi_toc.
+ (has_small_toc_reloc): Define.
+ (ppc64_elf_check_relocs): Set the above flags.
+ (ppc64_elf_edit_opd): Delete obfd param.
+ (ppc64_elf_tls_optimize): Likewise.
+ (ppc64_elf_edit_toc): Likewise.
+ (ppc64_elf_tls_setup): Likewise. Add no_multi_toc param.
+ * elf64-ppc.h: Update prototypes.
+
+2010-02-08 Alan Modra <amodra@gmail.com>
+
+ * section.c (struct bfd_section): Delete has_tls_reloc,
+ has_tls_get_addr_call, has_gp_reloc, need_finalize_relax, reloc_done.
+ Add sec_flg0 thru sec_flg5.
+ (BFD_FAKE_SECTION): Update for changed flags.
+ * ecoff.c (bfd_debug_section): Likewise.
+ * elf32-ppc.c (has_tls_reloc, has_tls_get_addr_call): Define.
+ * elf64-ppc.c (has_tls_reloc, has_tls_get_addr_call): Define.
+ (has_toc_reloc, makes_toc_func_call, call_check_in_progress): Update.
+ * elf32-xtensa.c (reloc_done): Define.
+ * elfxx-ia64.c (skip_relax_pass_0, skip_relax_pass_1): Update.
+ * bfd-in2.h: Regenerate.
+
+2010-02-08 Tristan Gingold <gingold@adacore.com>
+
+ * mach-o.c (bfd_mach_o_canonicalize_one_reloc): Set reloc.r_extern
+ for non-scattered relocations.
+
+2010-02-08 Nathan Sidwell <nathan@codesourcery.com>
+
+ * elf32-ppc.c (ppc_elf_begin_write_processing): Allow empty
+ apuinfo sections, only scan input sections once and reuse the
+ buffer.
+
+2010-02-08 Philipp Tomsich <philipp.tomsich@theobroma-systems.com>
+
+ * archures.c (bfd_mach_ppc_titan): Define.
+ * bfd-in2.h: Regenerate.
+ * cpu-powerpc.c (bfd_powerpc_archs): Add titan entry.
+
+2010-02-08 Alan Modra <amodra@gmail.com>
+
+ * elf32-ppc.c (ppc_elf_check_relocs): Remove dead ifunc code.
+
+2010-02-05 Sterling Augustine <sterling@tensilica.com>
+
+ * elf.c (assign_file_positions_for_load_sections) Update lma of
+ section if necessary. Fixes Bugzilla 11219.
+
+2010-02-05 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf32-i386.c: Remove trailing white spaces.
+ * elf64-x86-64.c: Likewise.
+
+2010-02-03 Nick Clifton <nickc@redhat.com>
+
+ * elf-bfd.h (emum elf_object_id): Rename to elf_target_id. Add
+ entries for other architectures.
+ (struct elf_link_hash_table): Add hash_table_id field.
+ (elf_hash_table_id): New accessor macro.
+ * elflink.c (_bfd_elf_link_hash_table_init): Add target_id
+ parameter.
+ * elf-m10300.c (elf32_mn10300_hash_table): Check table id before
+ returning cast pointer.
+ (elf32_mn10300_link_hash_table_create): Identify new table as
+ containing MN10300 extensions.
+ (mn10300_elf_relax_section): Check pointer returned by
+ elf32_mn10300_hash_table.
+ * elf32-arm.c: Likewise, except using ARM extensions.
+ * elf32-avr.c: Likewise, except using AVR extensions.
+ * elf32-bfin.c: Likewise, except using BFIN extensions.
+ * elf32-cris.c: Likewise, except using CRIS extensions.
+ * elf32-frv.c: Likewise, except using FRV extensions.
+ * elf32-hppa.c: Likewise, except using HPPA32 extensions.
+ * elf32-i386.c: Likewise, except using I386 extensions.
+ * elf32-lm32.c: Likewise, except using LM32 extensions.
+ * elf32-m32r.c: Likewise, except using M32RM extensions.
+ * elf32-m68hc11.c: Likewise, except using M68HC11 extensions.
+ * elf32-m68hc1x.c: Likewise, except using M68HC11 extensions.
+ * elf32-m68hc1x.h: Likewise, except using M68HC11 extensions.
+ * elf32-m68k.c: Likewise, except using M68K extensions.
+ * elf32-microblaze.c: Likewise, except using MICROBLAZE extensions.
+ * elf32-ppc.c: Likewise, except using PPC32 extensions.
+ * elf32-s390.c: Likewise, except using S390 extensions.
+ * elf32-sh.c: Likewise, except using SH extensions.
+ * elf32-spu.c: Likewise, except using SPU extensions.
+ * elf32-xtensa.c: Likewise, except using XTENSA extensions.
+ * elf64-alpha.c: Likewise, except using ALPHA extensions.
+ * elf64-hppa.c: Likewise, except using HPPA64 extensions.
+ * elf64-ppc.c: Likewise, except using PPC64 extensions.
+ * elf64-s390.c: Likewise, except using S390 extensions.
+ * elf64-x86-64.c: Likewise, except using X86_64 extensions.
+ * elfxx-ia64.c: Likewise, except using IA64 extensions.
+ * elfxx-mips.c: Likewise, except using MIPS extensions.
+ * elfxx-sparc.c: Likewise, except using SPARC extensions.
+ * elfxx-sparc.h: Likewise, except using SPARC extensions.
+ * elf32-cr16.c (struct elf32_cr16_link_hash_table): Delete
+ redundant structure.
+ (elf32_cr16_hash_table): Delete unused macro.
+ (elf32_cr16_link_hash_traverse): Delete unused macro.
+ * elf32-score.c: Likewise.
+ * elf32-score7.c: Likewise.
+ * elf32-vax.c: Likewise.
+ * elf64-sh64.c: Likewise.
+
+2010-02-03 Alan Modra <amodra@gmail.com>
+
+ * elf64-ppc.c (struct plt_entry): Move earlier in file.
+ (struct got_entry): Likewise. Add is_indirect and got.ent fields.
+ (struct ppc64_elf_obj_tdata): Change tlsld_got to be a struct got_entry.
+ Update all uses.
+ (struct ppc_link_hash_table): Add got_reli_size and second_toc_pass.
+ Remove no_multi_toc.
+ (update_local_sym_info, ppc64_elf_check_relocs): Clear is_indirect
+ when allocating a new struct got_entry.
+ (allocate_got): New function, extracted from..
+ (allocate_dynrelocs): ..here. Abort on got entry in non-ppc64 bfd.
+ (ppc64_elf_size_dynamic_sections): Track got relocs allocated in
+ .reliplt by got_reli_size. Set owner on ppc64_tlsld_got entries.
+ (ppc64_elf_setup_section_lists): Remove output_bfd param and
+ no_multi_toc, add add_stub_section and layout_sections_again. Stash
+ new params in htab. Extract some code to..
+ (ppc64_elf_start_multitoc_partition): ..here. New function.
+ (ppc64_elf_next_toc_section): Check for linker script errors. Handle
+ second pass toc scan.
+ (merge_got_entries, merge_global_got, reallocate_got): New functions.
+ (ppc64_elf_reinit_toc): Rename to..
+ (ppc64_elf_finish_multitoc_partition): ..this.
+ (ppc64_elf_layout_multitoc): New function.
+ (ppc64_elf_size_stubs): Delete output_bfd, add_stub_section and
+ layout_sections_again params.
+ (ppc64_elf_relocate_section): Handle indirect got entries.
+ * elf64-ppc.h: Update prototypes. Declare new functions.
+
+2010-02-02 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf-bfd.h (elfcore_write_xstatereg): New.
+
+ * elf.c (elfcore_grok_xstatereg): New.
+ (elfcore_write_xstatereg): Likewise.
+ (elfcore_grok_note): Handle NT_X86_XSTATE.
+ (elfcore_write_register_note): Handle .reg-xstate section.
+
+2010-02-01 Tristan Gingold <gingold@adacore.com>
+
+ * som.c (som_write_ar_hdr): Define this macro.
+
+2010-01-30 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ * elf32-hppa.c (final_link_relocate): Convert R_PARISC_TLS_GD21L,
+ R_PARISC_TLS_LDM21L and R_PARISC_TLS_IE21L relocations that use the
+ linkage table pointer to use the global table pointer if not doing
+ a shared link.
+
+2010-01-29 Joel Brobecker <brobecker@adacore.com>
+
+ * elf.c (elfcore_grok_lwpstatus): Do not overwrite the core signal
+ if it has already been set.
+
+2010-01-27 Tristan Gingold <gingold@adacore.com>
+
+ * vms.h: Remove trailing spaces.
+ (struct hdr_struct): Remove unused hdr_c_cpr field.
+ (enum file_format_enum): Add comments.
+ * vms.c (vms_bfd_print_private_bfd_data): New function that
+ replaces the macro.
+ Remove trailing spaces.
+ * vms-misc.c: Improve comments.
+ (_bfd_vms_get_object_record): Also handle files without pads.
+ * vms-hdr.c (_bfd_vms_write_dbg): Fix format string.
+ * vms-gsd.c (struct flagdescstruct): Make name field const.
+ (gsyflagdesc): Fix typo.
+
+2010-01-27 Alan Modra <amodra@gmail.com>
+
+ PR ld/11217
+ * elf64-ppc.c (struct ppc_link_hash_table): Add toc_bfd, toc_first_sec.
+ (ppc64_elf_setup_section_lists): Init them.
+ (ppc64_elf_next_toc_section): Don't partition multi-toc between .got
+ and .toc on the same input file.
+ (ppc64_elf_relocate_section): Correct GOT entry offset.
+
+2010-01-26 Tristan Gingold <gingold@adacore.com>
+
+ * targets.c (BFD_JUMP_TABLE_ARCHIVE): Add initializer for write_ar_hdr.
+ (bfd_target): Add _bfd_write_ar_hdr_fn field.
+ * archive.c (is_bsd44_extended_name): New macro.
+ (_bfd_generic_read_ar_hdr_mag): Use it. Add extra_size.
+ (bfd_slurp_armap): Also check for "__.SYMDEF" as a BSD4.4 extended
+ name.
+ (_bfd_archive_bsd44_construct_extended_name_table): New function.
+ (_bfd_generic_write_ar_hdr): Ditto.
+ (_bfd_bsd44_write_ar_hdr): Ditto.
+ (_bfd_write_archive_contents): Call _bfd_write_ar_hdr.
+ (bsd_write_armap): Adjust firstreal computation.
+ * libbfd-in.h (struct areltdata): Add extra_size field.
+ (_bfd_generic_write_ar_hdr): Add prototype.
+ (_bfd_bsd44_write_ar_hdr): Ditto.
+ (_bfd_write_ar_hdr): Define.
+ (_bfd_noarchive_write_ar_hdr): Ditto.
+ (_bfd_archive_bsd_write_ar_hdr): Ditto.
+ (_bfd_archive_coff_write_ar_hdr): Ditto.
+ (_bfd_archive_bsd44_slurp_armap): Ditto.
+ (_bfd_archive_bsd44_slurp_extended_name_table): Ditto.
+ (_bfd_archive_bsd44_construct_extended_name_table): New prototype.
+ (_bfd_archive_bsd44_truncate_arname): Ditto.
+ (_bfd_archive_bsd44_write_armap): Ditto.
+ (_bfd_archive_bsd44_read_ar_hdr): Ditto.
+ (_bfd_archive_bsd44_write_ar_hdr): Ditto.
+ (_bfd_archive_bsd44_openr_next_archived_file): Ditto.
+ (_bfd_archive_bsd44_get_elt_at_index): Ditto.
+ (_bfd_archive_bsd44_generic_stat_arch_elt): Ditto.
+ (_bfd_archive_bsd44_update_armap_timestamp): Ditto.
+ * libbfd.h: Regenerate.
+ * oasys.c (oasys_write_ar_hdr): Define.
+ * libecoff.h (_bfd_ecoff_write_ar_hdr): Define.
+ * ieee.c (ieee_write_ar_hdr): Define.
+ * elf64-mips.c (bfd_elf64_archive_write_ar_hdr): Define.
+ * coff-rs6000.c (rs6000coff_vec): Adjust for write_ar_hdr field.
+ (bfd_pmac_xcoff_backend_data): Ditto.
+ * coff64-rs6000.c (rs6000coff64_vec): Ditto.
+ (bfd_xcoff_aix5_backend_data): Ditto.
+ * coff-alpha.c (alpha_ecoff_write_ar_hdr): Define.
+ * aout-target.h (MY_write_ar_hdr): Define it if not defined.
+ * aout-tic30.c (MY_write_ar_hdr): Ditto.
+ * mach-o-target.c (TARGET_NAME): Use _bfd_archive_bsd44 archive.
+ (bfd_mach_o_mkarchive, bfd_mach_o_read_ar_hdr)
+ (bfd_mach_o_slurp_armap, bfd_mach_o_slurp_extended_name_table)
+ (bfd_mach_o_construct_extended_name_table)
+ (bfd_mach_o_truncate_arname, bfd_mach_o_write_armap)
+ (bfd_mach_o_get_elt_at_index, bfd_mach_o_generic_stat_arch_elt)
+ (bfd_mach_o_update_armap_timestamp): Moved to mach-o.c
+ * mach-o.c (bfd_mach_o_mkarchive, bfd_mach_o_read_ar_hdr)
+ (bfd_mach_o_slurp_armap, bfd_mach_o_slurp_extended_name_table)
+ (bfd_mach_o_construct_extended_name_table)
+ (bfd_mach_o_truncate_arname, bfd_mach_o_write_armap)
+ (bfd_mach_o_get_elt_at_index, bfd_mach_o_generic_stat_arch_elt)
+ (bfd_mach_o_update_armap_timestamp): Moved from mach-o-target.c
+ * bfd-in2.h: Regenerate.
+
+2010-01-26 Alan Modra <amodra@gmail.com>
+ H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/11218
+ * elflink.c (elf_link_output_extsym): Do not ignore undefined
+ symbols with ref_regular set when gc_sections is active.
+
+2010-01-25 Alan Modra <amodra@gmail.com>
+
+ PR ld/11217
+ * elf64-ppc.c (ppc64_elf_tls_optimize): Optimize tls sequences
+ with relocations against undefined weak symbols.
+ (ppc64_elf_relocate_section): Don't optimize calls to undefined
+ weak functions if the symbol is dynamic.
+ (ppc64_elf_relocate_section): Edit tprel tls sequences.
+ * elf32-ppc.c (ppc_elf_relocate_section): Likewise.
+ (_bfd_elf_ppc_at_tprel_transform): New function.
+ * bfd-in.h (_bfd_elf_ppc_at_tprel_transform): Declare.
+ * bfd-in2.h: Regenerate.
+
+2010-01-23 Richard Sandiford <r.sandiford@uk.ibm.com>
+
+ * coff-rs6000.c (xcoff_howto_table): Change size to 0 and bitsize to 1.
+ (_bfd_xcoff_reloc_type_lookup): Handle BFD_RELOC_NONE.
+ * coff64-rs6000.c (xcoff64_howto_table): Change size to 0 and
+ bitsize to 1.
+ (xcoff64_reloc_type_lookup): Handle BFD_RELOC_NONE.
+
+2010-01-21 Nick Clifton <nickc@redhat.com>
+
+ * elflink.c (elf_link_add_object_symbols): Look up name of
+ undefined symbol both before and after versioning has been
+ applied. Do not bother with symbols that are weakly undefined.
+
+2010-01-21 Andreas Krebbel <Andreas.Krebbel@de.ibm.com>
+
+ * elf32-s390.c (elf32_s390_merge_private_bfd_data): New function.
+ (bfd_elf32_bfd_merge_private_bfd_data): New macro definition.
+
+2010-01-19 Cary Coutant <ccoutant@google.com>
+
+ * dwarf2.c (read_attribute_value): Add DW_FORM_ref_sig8.
+
+2010-01-19 Daisuke Hatayama <d.hatayama@jp.fujitsu.com>
+ Alan Modra <amodra@gmail.com>
+
+ * elfcode.h (elf_swap_ehdr_out): Handle e_phnum > 0xffff.
+ (elf_object_p): Read e_phnum extension.
+ (elf_write_shdrs_and_ehdr): Write e_phnum extension.
+ * elfcore.h (elf_core_file_p): Read e_phnum extension. Sanity check
+ that we can read last program header.
+
+2010-01-19 Matthew Gretton-Dann <matthew.gretton-dann@arm.com>
+
+ * elf32-arm.c (elf32_arm_howto_table_1): Correct bitsize of
+ R_ARM_THM_CALL entry.
+ (elf32_arm_final_link_relocate): Correct calculation of
+ reloc_signed_max when doing a R_ARM_THM_CALL, R_ARM_THM_XPC22,
+ or R_ARM_THM_JUMP24 relocation.
+
+2010-01-18 Alan Modra <amodra@gmail.com>
+
+ PR 11168
+ * coffcode.h (coff_compute_section_file_positions): Move Rs6000COFF_C
+ block past vars in COFF_IMAGE_WITH_PE block. Report error on more
+ than 32k sections.
+
+2010-01-15 Jan Kratochvil <jan.kratochvil@redhat.com>
+
+ Fix compilation warning on gcc-3.4.
+ * vms-tir.c (start_etir_record, sto_imm): Rename the prototype
+ parameter index to sec_index according to the function definition.
+
+2010-01-13 Chao-ying Fu <fu@mips.com>
+
+ * elfxx-mips.c (JR_TO_B_P): New define to transform JR to B.
+ It is true for all CPUs.
+ (jal_reloc_p): New function.
+ (mips_elf_calculate_relocation): Rename require_jalxp to
+ cross_mode_jump_p.
+ Update comment for CROSS_MODE_JUMP_P.
+ Set up cross_mode_jump_p based on the mode change.
+ (mips_elf_perform_relocation): Rename require_jalx to cross_mode_jump_p.
+ Update comment for CROSS_MODE_JUMP_P.
+ Test cross_mode_jump_p and jal_reloc_p to turn jal to jalx.
+ Use !cross_mode_jump_p to guard conversion.
+ Convert "jr t9" to "b", if possible.
+ (_bfd_mips_elf_relocate_section): Rename require_jalx to
+ cross_mode_jump_p.
+ Pass &cross_mode_jump_p to call mips_elf_calculate_relocation.
+ Pass cross_mode_jump_p to call mips_elf_perform_relocation.
+
+2010-01-13 Nick Clifton <nickc@redhat.com>
+
+ * cpu-m32c.c (m32c_scan): New function. Ensures that a scan for
+ "m32c" returns the m32c arch_info_struct and not the m16c
+ arch_info_struct.
+ (arch_info_struct): Use the new scan function.
+ (bfd_m32c_arch): Likewise.
+
+2010-01-13 Tristan Gingold <gingold@adacore.com>
+
+ * config.bfd: Remove duplicated target vector for i386-*-darwin.
+ Appends new arch instead of overriding.
+ Use mach_o_x86_64_vec for x86_64-*-darwin.
+ * configure.in: Add mach_o_x86_64_vec.
+ * configure: Regenerate.
+ * targets.c: Declare mach_o_x86_64_vec, add it to _bfd_target_vector.
+ * Makefile.am (BFD64_BACKENDS): Add mach-o-x86-64.lo
+ (BFD64_BACKENDS_CFILES): Add mach-o-x86-64.c
+ * Makefile.in: Regenerate.
+ * mach-o-x86-64.c: New file.
+
+2010-01-13 Tristan Gingold <gingold@adacore.com>
+
+ * reloc.c: Add MACH_O_X86_64 relocations.
+ * bfd-in2.h: Regenerate.
+ * libbfd.h: Regenerate.
+
+2010-01-13 Tristan Gingold <gingold@adacore.com>
+
+ * archive.c (normalize): Use lbasename.
+ (bfd_bsd_truncate_arname): Ditto.
+ (bfd_gnu_truncate_arname): Ditto.
+
+2010-01-12 Tristan Gingold <gingold@adacore.com>
+
+ * makefile.vms (CFLAGS): Turns warnings into informational messages.
+
+2010-01-11 Tristan Gingold <gingold@adacore.com>
+
+ * mach-o.h: Add x86-64 relocation types.
+
+2010-01-11 Tristan Gingold <gingold@adacore.com>
+
+ * mach-o.h (bfd_mach_o_backend_data): Add arch field.
+ (bfd_mach_o_set_arch_mach): New prototype.
+ * mach-o.c (bfd_mach_o_mkobject): Define with bfd_mach_o_gen_mkobject.
+ (bfd_mach_o_set_arch_mach): New function.
+ (bfd_mach_o_gen_mkobject): New function.
+ Set TARGET_ARCHITECTURE for the generic back-ends.
+ * mach-o-target.c (bfd_mach_o_set_arch_mach): Remove define.
+ Check that TARGET_ARCHITECTURE is defined.
+ Add TARGET_ARCHITECTURE in TARGET_NAME_BACKEND structure.
+ * mach-o-i386.c (TARGET_ARCHITECTURE): Define.
+
+2010-01-11 Tristan Gingold <gingold@adacore.com>
+
+ * archive.c (bfd_slurp_armap): Also check for Mach-O sorted armap.
+
+2010-01-11 Nick Clifton <nickc@redhat.com>
+
+ * elf32-v850.c (v850_elf_perform_relocation): Fix overflow
+ handling of R_V850_HI16_S relocation.
+
+2010-01-11 Alan Modra <amodra@gmail.com>
+
+ PR 11103
+ * dwarf1.c (parse_die): Correct FORM_STRING data pointer increment.
+
+2010-01-11 Alan Modra <amodra@gmail.com>
+
+ PR 6832
+ * dwarf2.c (struct comp_unit): Add sec_info_ptr.
+ (find_abstract_instance_name): Use it.
+ (parse_comp_unit): Set it.
+
+2010-01-09 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
+
+ * Makefile.in: Regenerate.
+ * configure: Regenerate.
+
+2010-01-08 Tristan Gingold <gingold@adacore.com>
+
+ * archive.c: Remove bfd_special_undocumented_glue.
+
+2010-01-08 Alan Modra <amodra@gmail.com>
+
+ PR ld/11133
+ * elf32-cr16.c (elf32_cr16_gc_mark_hook): Call _bfd_elf_gc_mark_hook.
+ * elf32-microblaze.c (microblaze_elf_gc_mark_hook): Likewise.
+ * elf64-ppc.c (ppc64_elf_gc_mark_hook): Likewise.
+
+2010-01-07 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/11138
+ * elflink.c (elf_link_check_versioned_symbol): Don't abort if
+ a symbol referenced by DSO is is defined in a non-shared object
+ and forced local.
+
+2010-01-07 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/11133
+ * elflink.c (_bfd_elf_gc_mark_hook): Check section XXX for
+ undefined __start_XXX/__stop_XXX in all input files and set
+ SEC_KEEP.
+
+2010-01-07 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/11143
+ * elflink.c (elf_gc_sweep): Keep SHT_NOTE section.
+
+2010-01-04 Daniel Gutson <dgutson@codesourcery.com>
+
+ * bfd.m4 (BFD_HAVE_SYS_PROCFS_TYPE): Define _STRUCTURE_PROC
+ before including procfs.h.
+ (BFD_HAVE_SYS_PROCFS_TYPE_MEMBER): Likewise.
+ * configure.in: Added autoconf probe for the pr_fpreg member.
+ * configure: Regenerated.
+ * config.in: Regenerated.
+ * elf.c: Define _STRUCTURE_PROC before including procfs.h.
+
+2010-01-04 Joel Brobecker <brobecker@adacore.com>
+
+ Fix -Wshadow warnings in dwarf2.c (seen on alpha-tru64).
+ * dwarf2.c (concat_filename): Rename dirname with dir_name
+ to void shadowing the dirname function.
+ Rename subdirname with subdir_name to stay consistent with
+ the new dir_name variable name.
+
+2010-01-04 Edmar Wienskoski <edmar@freescale.com>
+
+ * archures.c: Add bfd_mach_ppc_e500mc64.
+ * bfd-in2.h: Regenerate.
+ * cpu-powerpc.c (bfd_powerpc_archs): Add entry for
+ bfd_mach_ppc_e500mc64.
+
+2010-01-01 Joel Brobecker <brobecker@adacore.com>
+
+ Fix -Wshadow warnings (seen on ppc-aix)
+ * xcofflink.c: Replace finfo by flinfo throughout.
+
+For older changes see ChangeLog-2009
+
+Copyright (C) 2010 Free Software Foundation, Inc.
+
+Copying and distribution of this file, with or without modification,
+are permitted in any medium without royalty provided the copyright
+notice and this notice are preserved.
+
+Local Variables:
+mode: change-log
+left-margin: 8
+fill-column: 74
+version-control: never
+End:
diff --git a/bfd/ChangeLog-2011 b/bfd/ChangeLog-2011
new file mode 100644
index 0000000..e4e2cc0
--- /dev/null
+++ b/bfd/ChangeLog-2011
@@ -0,0 +1,3389 @@
+2011-12-24 Jan Kratochvil <jan.kratochvil@redhat.com>
+
+ * elf32-rl78.c (rl78_elf_relocate_section, rl78_dump_symtab)
+ (rl78_elf_relax_section): Remove debug prints.
+
+2011-12-23 Jan Kratochvil <jan.kratochvil@redhat.com>
+
+ * elf32-rl78.c (rl78_elf_relocate_section, rl78_elf_relax_section): Use
+ BFD_VMA_FMT.
+
+2011-12-23 Jan Kratochvil <jan.kratochvil@redhat.com>
+
+ * elf32-rl78.c (prev_alignment, sec_start): Remove unused variables.
+
+2011-12-23 Tristan Gingold <gingold@adacore.com>
+
+ * vms-lib.c (vms_traverse_index): Move pointer update code.
+
+2011-12-22 DJ Delorie <dj@redhat.com>
+
+ * elf32-rl78.c (rl78_elf_howto_table): Add R_RL78_RH_RELAX.
+ (rl78_reloc_map): Add BFD_RELOC_RL78_RELAX.
+ (rl78_elf_relocate_section): Add R_RL78_RH_RELAX, R_RL78_RH_SFR,
+ and R_RL78_RH_SADDR.
+ (rl78_elf_finish_dynamic_sections): Only validate PLT section if
+ we didn't relax anything, as relaxing might remove a PLT reference
+ after we've set up the table.
+ (elf32_rl78_relax_delete_bytes): New.
+ (reloc_bubblesort): New.
+ (rl78_offset_for_reloc): New.
+ (relax_addr16): New.
+ (rl78_elf_relax_section): Add support for relaxing long
+ instructions into short ones.
+
+2011-12-22 Martin Schwidefsky <schwidefsky@de.ibm.com>
+
+ * elf32-s390.c (elf_s390_relocate_section): Add check for debugging
+ section in LD to LE linker relaxation for R_390_TLS_LDO32.
+ * elf64-s390.c (elf_s390_relocate_section): Likewise for
+ R_390_TLS_LDO64.
+
+2011-12-21 Ulrich Weigand <ulrich.weigand@linaro.org>
+
+ * elf32-arm.c (elf32_arm_nabi_grok_psinfo): Fill in core_pid.
+
+2011-12-19 Iain Sandoe <idsandoe@googlemail.com>
+
+ * mach-o-i386.c (bfd_mach_o_section_type_valid_for_tgt): Define NULL.
+ * mach-o-target.c (bfd_mach_o_backend_data): Initialize
+ bfd_mach_o_section_type_valid_for_tgt
+ * mach-o-x86-64.c (bfd_mach_o_section_type_valid_for_x86_64): New.
+ (bfd_mach_o_section_type_valid_for_tgt): Set to
+ bfd_mach_o_section_type_valid_for_x86_64.
+ * mach-o.c (bfd_mach_o_section_type_name): Reorder and eliminate dup.
+ (bfd_mach_o_section_attribute_name): Reorder.
+ (bfd_mach_o_get_section_type_from_name): If the target has defined a
+ validator for section types, then use it.
+ * mach-o.h (bfd_mach_o_get_section_type_from_name): Alter declaration
+ to include the bfd.
+
+2011-12-19 Chung-Lin Tang <cltang@codesourcery.com>
+
+ * reloc.c (BFD_RELOC_MIPS16_TLS_GD,BFD_RELOC_MIPS16_TLS_LDM,
+ BFD_RELOC_MIPS16_TLS_DTPREL_HI16,BFD_RELOC_MIPS16_TLS_DTPREL_LO16,
+ BFD_RELOC_MIPS16_TLS_GOTTPREL,BFD_RELOC_MIPS16_TLS_TPREL_HI16,
+ BFD_RELOC_MIPS16_TLS_TPREL_LO16): New relocations for MIPS16 TLS.
+ * bfd-in2.h (bfd_reloc_code_real): Regenerate.
+ * libbfd.h (bfd_reloc_code_real_names): Regenerate.
+ * elf32-mips.c (elf_mips16_howto_table_rel): Add R_MIPS16_TLS_*
+ entries.
+ (mips16_reloc_map): Add BFD_RELOC_MIPS16_TLS_* to R_MIPS16_TLS_*
+ mappings.
+ * elfn32-mips.c (elf_mips16_howto_table_rel,
+ elf_mips16_howto_table_rela): Add R_MIPS16_TLS_* entries.
+ (mips16_reloc_map): Add BFD_RELOC_MIPS16_TLS_* to R_MIPS16_TLS_*
+ mappings.
+ * elf64-mips.c (mips16_elf64_howto_table_rel,
+ mips16_elf64_howto_table_rela): Add R_MIPS16_TLS_* entries.
+ (mips16_reloc_map): Add BFD_RELOC_MIPS16_TLS_* to R_MIPS16_TLS_*
+ mappings.
+ * elfxx-mips.c (TLS_RELOC_P,mips16_reloc_p,
+ _bfd_mips_elf_check_relocs): Add cases for R_MIPS16_TLS_* relocations.
+ (tls_gd_reloc_p): Add R_MIPS16_TLS_GD case.
+ (tls_ldm_reloc_p): Add R_MIPS16_TLS_LDM case.
+ (tls_gottprel_reloc_p): Add R_MIPS16_TLS_GOTTPREL case.
+ (mips_elf_calculate_relocation): Add cases for R_MIPS16_TLS_*,
+ R_MIPS_TLS_DTPREL32/64, and R_MIPS_TLS_TPREL32/64 relocations.
+
+2011-12-19 Chung-Lin Tang <cltang@codesourcery.com>
+ Catherine Moore <clm@codesourcery.com>
+ Sandra Loosemore <sandra@codesourcery.com>
+ Richard Sandiford <rdsandiford@googlemail.com>
+
+ * elfxx-mips.c (mips_elf_local_pic_function_p): Return true when
+ H is a MIPS16 function with a kept 32-bit stub. Update comments.
+ (mips_elf_get_la25_target): New function.
+ (mips_elf_add_la25_intro): Change to use mips_elf_get_la25_target().
+ (mips_elf_add_la25_stub): Move compute of use_trampoline_p down,
+ change to use mips_elf_get_la25_target().
+ (mips_elf_relocation_needs_la25_stub): Add target_is_16_bit_code_p
+ parameter, add switch case for R_MIPS16_26.
+ (mips_elf_calculate_relocation): Redirect relocation to point to the
+ LA25 stub if it exists, instead of the MIPS16 stub. Update arguments
+ of call to mips_elf_relocation_needs_la25_stub(), don't use la25 stub
+ for mips16->mips16 calls.
+ (_bfd_mips_elf_check_relocs): Update arguments of call to
+ mips_elf_relocation_needs_la25_stub().
+ (mips_elf_create_la25_stub): Change to use mips_elf_get_la25_target().
+
+2011-12-16 Shinichiro Hamaji <shinichiro.hamaji@gmail.com>
+
+ * mach-o-i386.c (TARGET_PRIORITY): Define as 0 (top priority)
+ * mach-o-target.c (TARGET_NAME): Use TARGET_PRIORITY
+ * mach-o-x86-64.c (TARGET_PRIORITY): Define as 0 (top priority)
+ * mach-o.c (bfd_mach_o_header_p): Remove special handling for
+ mach-o-i386.
+ (TARGET_PRIORITY) Set 1 for mach-o-be and mach-o-le, and set 0 for
+ mach-o-fat.
+
+2011-12-15 Kevin Buettner <kevinb@redhat.com>
+
+ * elf32-am33lin.c (elf32_am33lin_grok_prstatus): Add case
+ to correspond to a smaller ELF_NGREG defined by the kernel.
+
+2011-12-15 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf64-x86-64.c (ELF32_DYNAMIC_INTERPRETER): Set to
+ "/lib/ldx32.so.1".
+
+2011-12-15 Iain Sandoe <iains@gcc.gnu.org>
+
+ * mach-o.c (bfd_mach_o_mkobject_init): Initialize dyn_reloc_cache.
+ (bfd_mach_o_close_and_cleanup): Only cleanup Mach-O private data
+ for object files.
+
+2011-12-15 Shinichiro Hamaji <shinichiro.hamaji@gmail.com>
+
+ * mach-o.c (bfd_mach_o_canonicalize_reloc): Update relocation
+ table only when there isn't the cahce.
+ (bfd_mach_o_get_dynamic_reloc_upper_bound): Need one more space
+ for a pointer for the watchdog.
+ (bfd_mach_o_canonicalize_dynamic_reloc): Utilize cache like
+ bfd_mach_o_canonicalize_reloc.
+ (bfd_mach_o_close_and_cleanup): Call bfd_mach_o_free_cached_info.
+ (bfd_mach_o_free_cached_info): Free up cache data.
+ * mach-o.h (reloc_cache): A place to store cache of dynamic relocs.
+ (bfd_mach_o_free_cached_info): Add declaration.
+
+2011-12-15 Iain Sandoe <iains@gcc.gnu.org>
+
+ * mach-o-target.c (bfd_mach_o_bfd_set_private_flags): Use
+ bfd_mach_o_bfd_set_private_flags.
+ * mach-o.c (bfd_mach_o_bfd_set_private_flags): New.
+ * mach-o.h (bfd_mach_o_bfd_set_private_flags): Declare.
+
+2011-12-14 Nick Clifton <nickc@redhat.com>
+
+ PR ld/12451
+ * elfcode.h (elf_checksum_contents): Read in the section's
+ contents if they are not already available, and the section
+ actually has some contents.
+
+ * compress.c (bfd_get_full_section_contents): Use zmalloc to
+ allocate the buffers so that excess bytes are guaranteed to be
+ zero.
+
+2011-12-14 Iain Sandoe <iains@gcc.gnu.org>
+
+ * mach-o-i386.c (text_section_names_xlat): New table.
+ (data_section_names_xlat): Likewise.
+ (import_section_names_xlat): Likewise.
+ (mach_o_i386_segsec_names_xlat): Likewise.
+ (bfd_mach_o_tgt_seg_table): Use new tables.
+ * mach-o-x86-64.c (bfd_mach_o_tgt_seg_table): Set NULL.
+ * mach-o.c (mach_o_section_name_xlat, mach_o_segment_name_xlat):
+ Move to mach-o.h as typedefs.
+ (text_section_names_xlat): Update for current GCC usage.
+ (data_section_names_xlat): Likewise.
+ (dwarf_section_names_xlat): Likewise.
+ (objc_section_names_xlat): New table.
+ (segsec_names_xlat): Add objc table.
+ (bfd_mach_o_normalize_section_name): Replace with...
+ (bfd_mach_o_section_data_for_mach_sect): New.
+ (bfd_mach_o_section_data_for_bfd_name): New.
+ (bfd_mach_o_section_data_for_bfd_name): Update to use additional data.
+ (bfd_mach_o_convert_section_name_to_mach_o): Likewise.
+ (bfd_mach_o_bfd_copy_private_section_data): Implement.
+ (bfd_mach_o_write_symtab): Write a zero-length string as the first entry
+ for compatibility with system tools.
+ (bfd_mach_o_build_commands): Update section alignment info.
+ (bfd_mach_o_new_section_hook): Use translation table data to define
+ default section flags, type, attributes and alignment, when available.
+ (bfd_mach_o_init_section_from_mach_o): Add TODO comment.
+ (bfd_mach_o_section_type_name): Add 'symbol_stubs'.
+ (bfd_mach_o_section_attribute_name): Add 'self_modifying_code'.
+ (bfd_mach_o_get_section_type_from_name): Change "not-found" return
+ value.
+ (bfd_mach_o_tgt_seg_table): Set default NULL.
+ * mach-o.h (bfd_mach_o_segment_command): Use define for name length.
+ (bfd_mach_o_backend_data): Move until after contents are defined.
+ (bfd_mach_o_normalize_section_name): Remove.
+ (bfd_mach_o_convert_section_name_to_bfd): Declare.
+ (mach_o_section_name_xlat): Declare.
+ (mach_o_segment_name_xlat): Declare.
+ (bfd_mach_o_section_data_for_mach_sect): Declare.
+ (bfd_mach_o_section_data_for_bfd_name): Declare.
+
+2011-12-13 Shinichiro Hamaji <shinichiro.hamaji@gmail.com>
+
+ * dwarf2.c (bfd_dwarf2_cleanup_debug_info): Accept stash as an
+ argument like other functions to support formats other than ELF.
+ * elf-bfd.h (bfd_dwarf2_cleanup_debug_info): Move to bfd-in.h.
+ * elf.c (_bfd_elf_close_and_cleanup): Pass dwarf2_find_line_info
+ in tdata as a parameter.
+ * libbfd-in.h (bfd_dwarf2_cleanup_debug_info): Move from
+ elf-bfd.h.
+ * libbfd.h (bfd_dwarf2_cleanup_debug_info): Regenerate.
+ * mach-o-target.c (bfd_mach_o_close_and_cleanup): Remove the
+ fallback macro.
+ (bfd_mach_o_find_nearest_line): Likewise.
+ * mach-o.c (bfd_mach_o_find_nearest_line): Add the definition
+ which calls _bfd_dwarf2_find_nearest_line.
+ (bfd_mach_o_close_and_cleanup): Likewise.
+ * mach-o.h (mach_o_data_struct): Add dwarf2_find_line_info.
+ (bfd_mach_o_find_nearest_line): Add declaration.
+ (bfd_mach_o_close_and_cleanup): Add declaration.
+
+2011-12-13 Tristan Gingold <gingold@adacore.com>
+
+ * mach-o.c (bfd_mach_o_read_symtab_symbols): Make global. Remove
+ prototype.
+ (bfd_mach_o_section_get_entry_size): Make global.
+ (bfd_mach_o_section_get_nbr_indirect): Likewise.
+ (bfd_mach_o_read_symtab_strtab): Likewise.
+ (struct bfd_mach_o_xlat_name): Move to mach-o.h
+ (bfd_mach_o_print_flags): Move to binutils/od-macho.c
+ (bfd_mach_o_get_name_of_null, bfd_mach_o_get_name): Likewise.
+ (bfd_mach_o_cpu_name, bfd_mach_o_filetype_name): Likewise.
+ (bfd_mach_o_header_flags_name): Likewise.
+ (bfd_mach_o_load_command_name): Likewise.
+ (bfd_mach_o_print_private_header): Likewise.
+ (bfd_mach_o_print_section_map, bfd_mach_o_print_section): Likwise.
+ (bfd_mach_o_print_segment, bfd_mach_o_print_dysymtab): Likewise.
+ (bfd_mach_o_print_dyld_info): Likewise.
+ (bfd_mach_o_print_private_bfd_data): Remove.
+ (bfd_mach_o_type_name): Make global.
+ (bfd_mach_o_section_attribute_name): Likewise.
+ * mach-o.h (bfd_mach_o_xlat_name): Added.
+ (bfd_mach_o_section_get_nbr_indirect)
+ (bfd_mach_o_section_get_entry_size)
+ (bfd_mach_o_read_symtab_symbols)
+ (bfd_mach_o_read_symtab_strtab)
+ (bfd_mach_o_section_attribute_name)
+ (bfd_mach_o_section_type_name): Likewise.
+ * mach-o-target.c (bfd_mach_o_bfd_print_private_bfd_data): Define.
+
+2011-12-13 Chung-Lin Tang <cltang@codesourcery.com>
+
+ * elfxx-mips.c (mips_elf_calculate_relocation): Correct
+ R_MIPS16_HI16/R_MIPS16_LO16 handling of two cleared lower bits,
+ update comments.
+
+2011-12-12 Iain Sandoe <iains@gcc.gnu.org>
+
+ * mach-o.c (bfd_mach_o_read_section_32): Null-terminate sectname.
+ (bfd_mach_o_read_section_64): Likewise.
+
+2011-12-11 John Davis Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ PR binutils/13476
+ * elf32-hppa.c (final_link_relocate): Convert R_PARISC_TLS_GD21L,
+ R_PARISC_TLS_LDM21L and R_PARISC_TLS_IE21L relocations to
+ R_PARISC_DPREL21L when not doing a shared link. Likewise convert
+ R_PARISC_TLS_GD14R, R_PARISC_TLS_LDM14R and R_PARISC_TLS_IE14R to
+ R_PARISC_DPREL14R. Handle R_PARISC_TLS_GD21L, R_PARISC_TLS_LDM21L
+ and R_PARISC_TLS_IE21L with R_PARISC_DLTIND21L.
+
+2011-12-10 David Daney <david.daney@cavium.com>
+
+ * elfxx-mips.c (mips_elf_link_hash_table.rld_value): Remove.
+ (mips_elf_link_hash_table.rld_symbol): New field;
+ (MIPS_ELF_RLD_MAP_SIZE): New macro.
+ (_bfd_mips_elf_add_symbol_hook): Remember __rld_obj_head symbol
+ in rld_symbol.
+ (_bfd_mips_elf_create_dynamic_sections): Remember __rld_map symbol
+ in rld_symbol.
+ (_bfd_mips_elf_size_dynamic_sections): Set correct size for .rld_map.
+ (_bfd_mips_elf_finish_dynamic_symbol): Remove .rld_map handling.
+ (_bfd_mips_elf_finish_dynamic_sections): Use rld_symbol to
+ calculate DT_MIPS_RLD_MAP value.
+ (_bfd_mips_elf_link_hash_table_create): Initialize rld_symbol,
+ quit initializing rld_value.
+
+2011-12-08 Andrew Pinski <apinski@cavium.com>
+ Adam Nemet <anemet@caviumnetworks.com>
+
+ * archures.c (bfd_mach_mips_octeon2): New macro
+ * bfd-in2.h: Regenerate.
+ * cpu-mips.c (I_mipsocteon2): New enum value.
+ (arch_info_struct): Add bfd_mach_mips_octeon2.
+ * elfxx-mips.c (_bfd_elf_mips_mach): Support E_MIPS_MACH_OCTEON2.
+ (mips_set_isa_flags): Add bfd_mach_mips_octeon2.
+ (mips_mach_extensions): Add bfd_mach_mips_octeon2.
+
+2011-12-07 Alan Modra <amodra@gmail.com>
+
+ PR ld/12772
+ * elflink.c (elf_gc_sweep_symbol): Discard unmarked symbols
+ defined in shared libraries.
+
+2011-12-07 Tristan Gingold <gingold@adacore.com>
+
+ * mach-o.c (bfd_mach_o_canonicalize_symtab): Fix indentation.
+ Adjust the condition.
+ (bfd_mach_o_read_symtab_symbol): Now returns a bfd_boolean.
+ Adjust return statements.
+ (bfd_mach_o_read_symtab_strtab): Likewise.
+ (bfd_mach_o_read_symtab_symbols): Likewise.
+ (bfd_mach_o_scan_start_address): Likewise. Make it static.
+ (bfd_mach_o_scan): Likewise.
+ (bfd_mach_o_read_dysymtab_symbol): Remove unused function.
+ (bfd_mach_o_header_p): Adjust call.
+ (bfd_mach_o_cpu_name): Make it const.
+ (bfd_mach_o_filetype_name): Likewise.
+ (bfd_mach_o_header_flags_name): Likewise.
+ (bfd_mach_o_section_type_name): Likewise.
+ (bfd_mach_o_section_attribute_name): Likewise.
+ (bfd_mach_o_load_command_name): Likewise.
+ (bfd_mach_o_get_section_type_from_name): Add a const qualifier
+ after above change.
+ (bfd_mach_o_get_section_attribute_from_name): Likewise.
+ * mach-o.h (bfd_mach_o_read_dysymtab_symbol)
+ (bfd_mach_o_scan_start_address, bfd_mach_o_scan): Remove.
+
+2011-12-06 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * elf-bfd.h (elfcore_write_s390_last_break): Add prototype.
+ (elfcore_write_s390_system_call): Likewise.
+ * elf.c (elfcore_write_s390_last_break): New function.
+ (elfcore_write_s390_system_call): Likewise.
+ (elfcore_write_register_note): Call them.
+ (elfcore_grok_s390_last_break): New function.
+ (elfcore_grok_s390_system_call): Likewise.
+ (elfcore_grok_note): Call them.
+
+2011-12-05 Tristan Gingold <gingold@adacore.com>
+
+ * mach-o.c (bfd_mach_o_read_symtab_symbol): Accept indirect symbols.
+
+2011-12-05 Tristan Gingold <gingold@adacore.com>
+
+ * mach-o.c (bfd_mach_o_write_contents): Handle LC_LOAD_UPWARD_DYLIB.
+ (bfd_mach_o_read_dylib): Likewise.
+ (bfd_mach_o_read_command): Likewise.
+ (bfd_mach_o_bfd_print_private_bfd_data): Likewise.
+
+2011-12-05 Tristan Gingold <gingold@adacore.com>
+
+ * mach-o.c (bfd_mach_o_read_command): Add the bfd in the error
+ message.
+ (bfd_mach_o_openr_next_archived_file): Use arch name as member name.
+ (bfd_mach_o_fat_extract): Ditto.
+
+2011-12-03 Alan Modra <amodra@gmail.com>
+
+ PR ld/13468
+ * elflink.c (bfd_elf_final_link): Don't segfault when checking
+ for DT_TEXTREL and .dynamic does not exist.
+
+2011-12-03 Alan Modra <amodra@gmail.com>
+
+ PR ld/13470
+ * elf32-ppc.c (ppc_elf_copy_indirect_symbol): Revert substantive
+ change in 2011-07-01 commit. Comment.
+ * elf64-ppc.c (ppc64_elf_copy_indirect_symbol): Likewise.
+
+2011-12-01 Mikael Pettersson <mikpe@it.uu.se>
+
+ * elf32-m68k.c (elf_m68k_check_relocs) <R_68K_8, R68K_16, R_68K_32>: For
+ non-SEC_ALLOC sections break before GOT and PLT accounting.
+
+2011-12-01 Hans-Peter Nilsson <hp@axis.com>
+
+ * elf32-cris.c (cris_elf_check_relocs) <plt accounting for
+ R_CRIS_8, R_CRIS_16, and R_CRIS_32>: Move early break for
+ non-SEC_ALLOC sections before GOT and PLT accounting.
+
+2011-11-29 Andrew Pinski <apinski@cavium.com>
+
+ * archures.c (bfd_mach_mips_octeonp): New macro.
+ * bfd-in2.h: Regenerate.
+ * bfd/cpu-mips.c (I_mipsocteonp): New enum value.
+ (arch_info_struct): Add bfd_mach_mips_octeonp.
+ * elfxx-mips.c (mips_set_isa_flags): Add bfd_mach_mips_octeonp.
+ (mips_mach_extensions): Add bfd_mach_mips_octeonp.
+
+2011-11-23 Tristan Gingold <gingold@adacore.com>
+
+ * vms-lib.c (get_idxlen): Add comments. Fix type in sizeof.
+ (vms_write_index): Add comments.
+
+2011-11-22 DJ Delorie <dj@redhat.com>
+
+ * elf32-rx.c (rx_elf_object_p): Add more checks for "scanning" to
+ avoid using the special non-swapping target when not explicitly
+ requested.
+
+2011-11-22 Daniel Calcoen <Daniel.Calcoen@cern.ch>
+
+ * elf32-rx.c (rx_elf_object_p): Correct typo: lma->vma.
+
+2011-11-22 Tristan Gingold <gingold@adacore.com>
+
+ * mach-o.c (bfd_mach_o_print_symbol): Display COM for common
+ symbols. Print section name in brackets.
+
+2011-11-21 Andreas Tobler <andreast@fgznet.ch>
+
+ * config.bfd: Add vectors for powerpc and powerpc64-freebsd.
+ * configure.in (TDEFINES): Add rules for powerpc*-freebsd.
+ * configure: Regenerate.
+ * elf32-ppc.c: Add powerpc-freebsd definitions.
+ * elf64-ppc.c: Add powerpc64-freebsd definitions.
+ * targets.c: Add bits for powerpc and powerpc64-freebsd.
+
+2011-11-17 Philipp Thomas <philipp@thogro.org>
+
+ * elf32-arm.c (elf32_thumb_to_arm_stub): Sync message so that it
+ needs to be translated only once.
+
+2011-11-16 Maciej W. Rozycki <macro@codesourcery.com>
+
+ * elf64-mips.c (mips_elf64_howto_table_rela): Set src_mask to
+ zero throughout.
+ (mips16_elf64_howto_table_rela): Likewise.
+ (micromips_elf64_howto_table_rela): Likewise.
+ * elfn32-mips.c (elf_mips_howto_table_rela): Likewise.
+ (elf_mips16_howto_table_rela): Likewise.
+ (elf_micromips_howto_table_rela): Likewise.
+
+2011-11-15 Alan Modra <amodra@gmail.com>
+ Andreas Tobler <andreast@fgznet.ch>
+
+ * elflink.c (_bfd_elf_create_got_section): Replace
+ bfd_make_section_with_flags with bfd_make_section_anyway_with_flags.
+ (_bfd_elf_link_create_dynamic_sections): Likewise.
+ * elf32-ppc.c (ppc_elf_create_glink): Likewise.
+ (ppc_elf_create_dynamic_sections): Likewise.
+
+2011-11-14 Maxim Kuvyrkov <maxim@codesourcery.com>
+
+ * elfxx-mips.c (mips_n64_exec_plt0_entry): Use 64-bit move.
+
+2011-11-08 Nick Clifton <nickc@redhat.com>
+
+ * elf-m10300.c (mn10300_elf_relax_section): Fix check for an
+ immediate move into an address register.
+
+2011-11-09 Alan Modra <amodra@gmail.com>
+
+ * elflink.c (bfd_elf_gc_mark_dynamic_ref_symbol): Mark syms in
+ executables when export_dynamic.
+
+2011-11-08 Alan Modra <amodra@gmail.com>
+
+ * elf64-ppc.c (struct ppc64_elf_obj_tdata): Rename
+ ha_relocs_not_using_r2 to unexpected_toc_insn.
+ (ok_lo_toc_insn): New function.
+ (ppc64_elf_edit_toc): Check insn on lo toc reloc. Emit warning.
+ (ppc64_elf_relocate_section): Don't check insn on lo toc reloc here.
+ Handle addic on lo toc reloc.
+
+2011-11-06 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ PR ld/13387
+ * elf32-hppa.c (elf32_hppa_hide_symbol): Make STT_GNU_IFUNC symbol
+ go through PLT. Reset plt field with init_plt_offset.
+ (elf32_hppa_adjust_dynamic_symbol): Ensure that a PLT slot is
+ allocated for symbols referenced by a plabel.
+
+2011-11-02 DJ Delorie <dj@redhat.com>
+
+ * elf32-rl78.c (rl78_elf_merge_private_bfd_data): Delete unused
+ variable.
+
+2011-11-02 Jan Beulich <jbeulich@suse.com>
+
+ * coffgen.c (coff_write_alien_symbol): Make public. Add 'struct
+ internal_syment *' parameter. Extend 'dummy' to an array with two
+ elements. Set n_numaux early. Handle BSF_FILE.
+ (coff_write_symbols): Pass NULL as new third argument to
+ coff_write_alien_symbol().
+ * cofflink.c (_bfd_coff_final_link): Don't use COFF-specific
+ obj_raw_syment_count() on non-COFF input BFD. Insert local symbols
+ from non-COFF input BFDs.
+ * libcoff-in.h (coff_write_alien_symbol): Declare.
+ * libcoff.h (coff_write_alien_symbol): Re-generate.
+
+2011-11-01 DJ Delorie <dj@redhat.com>
+
+ * Makefile.am (ALL_MACHINES): Add cpu-rl78.lo.
+ (ALL_MACHINES_CFILES): Add cpu-rl78.c.
+ (BFD32_BACKENDS): Add elf32-rl78.lo.
+ (BFD32_BACKENDS_CFILES): Add elf32-rl78.c.
+ (Makefile.in): Regenerate.
+ * archures.c (bfd_architecture): Define bfd_arch_rl78.
+ (bfd_archures_list): Add bfd_rl78_arch.
+ * config.bfd: Add rl78-*-elf.
+ * configure.in: Add bfd_elf32_rl78_vec.
+ * reloc.c (bfd_reloc_code_type): Add BFD_RELOC_RL78_* relocations.
+ * targets.c (bfd_target_vector): Add bfd_elf32_rl78_vec.
+ * Makefile.in: Regenerate.
+ * bfd-in2.h: Regenerate.
+ * configure: Regenerate.
+ * libbfd.h: Regenerate.
+ * cpu-rl78.c: New file.
+ * elf32-rl78.c: New file.
+
+2011-10-26 Nick Clifton <nickc@redhat.com>
+
+ PR ld/13049
+ * elf64-ppc.c (STUB_SUFFIX): Revert previous delta.
+ * elf32-hppa.c (STUB_SUFFIX): Likewise.
+
+2011-10-25 Joern Rennecke <joern.rennecke@embecosm.com>
+
+ * Makefile.am (ALL_MACHINES): Add cpu-epiphany.lo.
+ (ALL_MACHINES_CFILES): Add cpu-epiphany.c.
+ (BFD32_BACKENDS): Add elf32-epiphany.lo.
+ (BFD32_BACKENDS_CFILES): Add elf32-epiphany.c.
+ * archures.c (bfd_arch_epiphany): Add.
+ (bfd_mach_epiphany16, bfd_mach_epiphany32): Define.
+ (bfd_epiphany_arch): Declare.
+ (bfd_archures_list): Add &bfd_epiphany_arch.
+ * config.bfd (epiphany-*-elf): New target case.
+ * configure.in (bfd_elf32_epiphany_vec): New target vector case.
+ * reloc.c (BFD_RELOC_EPIPHANY_SIMM8): New relocation.
+ (BFD_RELOC_EPIPHANY_SIMM24, BFD_RELOC_EPIPHANY_HIGH): Likewise.
+ (BFD_RELOC_EPIPHANY_LOW, BFD_RELOC_EPIPHANY_SIMM11): Likewise.
+ (BFD_RELOC_EPIPHANY_IMM11, BFD_RELOC_EPIPHANY_IMM8): Likewise.
+ * targets.c (bfd_elf32_epiphany_vec): Declare.
+ (_bfd_target_vector): Add bfd_elf32_epiphany_vec.
+ * Makefile.in: Regenerate.
+ * bfd-in2.h: Regenerate.
+ * configure: Regenerate.
+ * libbfd.h: Regenerate.
+ * po/SRC-POTFILES.in: Regenerate.
+ * po/bfd.pot: Regenerate.
+ * cpu-epiphany.c: New file.
+ * elf32-epiphany.c: New file.
+
+2011-10-24 Maciej W. Rozycki <macro@codesourcery.com>
+
+ * elfxx-mips.c (_bfd_mips_elf_symbol_processing): Remove
+ assertions.
+
+2011-10-24 Eugeniy Meshcheryakov <eugen@debian.org>
+
+ PR ld/13273
+ * elf32-arm.c (elf32_arm_merge_eabi_attributes): Do not warn about
+ identical TAG_PCS_config attributes.
+
+2011-10-24 Nick Clifton <nickc@redhat.com>
+
+ * po/ja.po: Updated Japanese translation.
+
+2011-10-24 Pau Garcia i Quiles <pgquiles@elpauer.org>
+
+ PR binutils/13292
+ * bfd-in.h: Include <sys/stat.h> rather than forward defining
+ struct stat.
+ * bfd-in2.h: Regenerate.
+
+2011-10-21 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/13302
+ * elf32-i386.c (elf_i386_relocate_section): Replace
+ R_386_IRELATIVE with R_386_RELATIVE.
+
+ * elf64-x86-64.c (elf_x86_64_relocate_section): Replace
+ R_X86_64_IRELATIVE with R_X86_64_RELATIVE.
+
+2011-10-21 H.J. Lu <hongjiu.lu@intel.com>.
+
+ * elf32-i386.c (elf_i386_relocate_section): Fix a typo in
+ comments.
+ * elf64-x86-64.c (elf_x86_64_relocate_section): Likewise.
+
+2011-10-21 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/13302
+ * elf32-i386.c (elf_i386_link_hash_table): Add next_jump_slot_index
+ and next_irelative_index.
+ (elf_i386_link_hash_table_create): Initialize next_jump_slot_index
+ and next_irelative_index.
+ (elf_i386_allocate_dynrelocs): Increment reloc_count instead of
+ next_tls_desc_index.
+ (elf_i386_size_dynamic_sections): Set next_tls_desc_index and
+ next_irelative_index from reloc_count.
+ (elf_i386_finish_dynamic_symbol): Put R_386_IRELATIVE after
+ R_386_JUMP_SLOT.
+
+ * elf64-x86-64.c (elf_x86_64_link_hash_table): Add
+ next_jump_slot_index and next_irelative_index.
+ (elf_x86_64_link_hash_table_create): Initialize
+ next_jump_slot_index and next_irelative_index.
+ (elf_x86_64_size_dynamic_sections): Set next_irelative_index
+ from reloc_count.
+ (elf_x86_64_finish_dynamic_symbol): Put R_X86_64_IRELATIVE after
+ R_X86_64_JUMP_SLOT.
+
+2011-10-20 Nick Clifton <nickc@redhat.com>
+
+ PR ld/13049
+ * elf32-arm.c (STUB_SUFFIX): Avoid collision with user namespace
+ symbol names.
+ * elf64-ppc.c (STUB_SUFFIX): Likewise.
+ * elf32-hppa.c (STUB_SUFFIX): Likewise.
+
+2011-10-20 Alan Modra <amodra@gmail.com>
+
+ * elf32-i386.c (i386_opcode16): Delete.
+ (elf_i386_check_tls_transition): Use memcmp to compare contents.
+ * elf64-x86-64.c (x86_64_opcode16, x86_64_opcode32): Delete.
+ (elf_x86_64_check_tls_transition): Use memcmp to compare contents.
+
+2011-10-19 Alan Modra <amodra@gmail.com>
+
+ PR ld/13177
+ * elflink.c (_bfd_elf_gc_mark_rsec): Set symbol "mark".
+ (elf_gc_sweep_symbol): Don't test plt/got refcounts, instead test
+ "mark". Hide undefweak too. Clear def_regular and ref_regular.
+ * elf-m10300.c (mn10300_elf_relocate_section): Ignore unresolved
+ reloc errors from garbage-collected code.
+ * elf32-arm.c (elf32_arm_relocate_section): Likewise.
+ * elf32-bfin.c (bfin_relocate_section): Likewise.
+ (bfinfdpic_relocate_section): Likewise.
+ * elf32-cris.c (cris_elf_relocate_section): Likewise.
+ * elf32-frv.c (elf32_frv_relocate_section): Likewise.
+ * elf32-i386.c (elf_i386_relocate_section): Likewise.
+ * elf32-m32r.c (m32r_elf_relocate_section): Likewise.
+ * elf32-m68k.c (elf_m68k_relocate_section): Likewise.
+ * elf32-ppc.c (ppc_elf_relocate_section): Likewise.
+ * elf32-s390.c (elf_s390_relocate_section): Likewise.
+ * elf32-sh.c (sh_elf_relocate_section): Likewise.
+ * elf32-spu.c (spu_elf_relocate_section): Likewise.
+ * elf32-tilepro.c (tilepro_elf_relocate_section): Likewise.
+ * elf32-xtensa.c (elf_xtensa_relocate_section): Likewise.
+ * elf64-alpha.c (elf64_alpha_relocate_section): Likewise.
+ * elf64-ppc.c (ppc64_elf_relocate_section): Likewise.
+ * elf64-s390.c (elf_s390_relocate_section): Likewise.
+ * elf64-sh64.c (sh_elf64_relocate_section): Likewise.
+ * elf64-x86-64.c (elf_x86_64_relocate_section): Likewise.
+ * elfxx-sparc.c (_bfd_sparc_elf_relocate_section): Likewise.
+ * elfxx-tilegx.c (tilegx_elf_relocate_section): Likewise.
+
+2011-10-19 Alan Modra <amodra@gmail.com>
+
+ PR ld/13311
+ * elflink.c (elf_link_output_extsym): Correct test for warning when
+ forced local executable syms are referenced from shared libraries.
+
+2011-10-19 Alan Modra <amodra@gmail.com>
+
+ PR ld/13254
+ * elflink.c (bfd_elf_final_link): Emit error_textrel error.
+
+2011-10-18 David S. Miller <davem@davemloft.net>
+
+ PR binutils/13301
+ * elfxx-sparc.c (sparc_elf_find_reloc_at_ofs): New function.
+ (_bfd_sparc_elf_relocate_section): Always move the __tls_get_addr
+ call delay slot instruction forward 4 bytes when performing
+ relaxation.
+
+2011-10-17 Alan Modra <amodra@gmail.com>
+
+ PR ld/12975
+ PR ld/13195
+ * elf64-ppc.c (ppc64_elf_gc_mark_dynamic_ref): Apply 2011-09-15
+ and 2011-09-29 bfd_elf_gc_mark_dynamic_ref_symbol changes here too.
+
+2011-10-14 Hans-Peter Nilsson <hp@axis.com>
+
+ * elf32-cris.c (cris_elf_gc_sweep_hook) <R_CRIS_16_GOTPLT>
+ <R_CRIS_32_GOTPLT>: Fix missing update of gotplt refcount for
+ global symbols.
+ <R_CRIS_8, R_CRIS_16, R_CRIS_32>: New cases for similar missing
+ updates of the plt refcount.
+ (elf_cris_adjust_gotplt_to_got): Assert integrity of the gotplt
+ refcount in relation to the plt refcount.
+
+2011-10-13 Richard Sandiford <richard.sandiford@linaro.org>
+
+ * elf32-arm.c (elf32_arm_final_link_relocate): Mark PLT calls via
+ stubs as resolved.
+
+2011-10-11 Alan Modra <amodra@gmail.com>
+
+ PR binutils/13278
+ * archive.c (bfd_generic_archive_p): Only check first element
+ when target_defaulted.
+ (_bfd_construct_extended_name_table): Use ar_maxnamelen.
+ (_bfd_archive_bsd44_construct_extended_name_table): Likewise.
+
+2011-10-11 Alan Modra <amodra@gmail.com>
+
+ PR binutils/13257
+ * archive.c (_bfd_find_nested_archive, _bfd_get_elt_at_filepos): Open
+ thin archive element using container target if not defaulted.
+
+2011-10-10 Nick Clifton <nickc@redhat.com>
+
+ * po/es.po: Updated Spanish translation.
+ * po/fi.po: Updated Finnish translation.
+ * po/fr.po: Updated French translation.
+ * po/ru.po: Updated Russian translation.
+
+2011-10-10 Alan Modra <amodra@gmail.com>
+
+ * elf64-ppc.c (ppc64_elf_howto_table): Add R_PPC64_TOCSAVE entry.
+ (struct ppc_link_hash_table): Add tocsave_htab.
+ (struct tocsave_entry): New.
+ (tocsave_htab_hash, tocsave_htab_eq, tocsave_find): New functions.
+ (ppc64_elf_link_hash_table_create): Create tocsave_htab..
+ (ppc64_elf_link_hash_table_free): ..and delete it.
+ (build_plt_stub): Always put STD_R2_40R1 first.
+ (ppc64_elf_size_stubs): Check for R_PPC64_TOCSAVE following reloc
+ on plt call. If present add prologue nop location to tocsave_htab.
+ (ppc64_elf_relocate_section): Convert prologue nop to std. Skip
+ first insn of plt call stub when R_PPC64_TOCSAVE present.
+
+2011-10-08 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/13250
+ * elflink.c (elf_link_add_object_symbols): Preserve the maximum
+ alignment and size for common symbols.
+
+2011-10-08 Alan Modra <amodra@gmail.com>
+
+ PR ld/13229
+ PR ld/13244
+ * elflink.c (elf_link_add_object_symbols): Don't make IR symbols
+ dynamic.
+
+2011-10-08 Alan Modra <amodra@gmail.com>
+
+ PR ld/13229
+ * elflink.c (elf_link_output_extsym): Strip defined plugin symbols
+ even when strip_discarded is false.
+
+2011-10-05 Kai Tietz <ktietz@redhat.com>
+
+ * coffgen.c (coff_write_alien_symbol): Don't write
+ symbol for discarded sections, if strip_discarded isn't
+ explicit set to false.
+ (coff_write_native_symbol): Likewise.
+
+2011-10-05 DJ Delorie <dj@redhat.com>
+ Nick Clifton <nickc@redhat.com>
+
+ * elf32-rx.c: Add support for PID mode.
+ (rx_elf_relocate_section): Add checks for unsafe PID relocations.
+ Include addend in R_RX_SYM relocations.
+
+2011-09-30 Tristan Gingold <gingold@adacore.com>
+
+ * dwarf2.c (struct dwarf2_debug): Add field debug_sections.
+ (read_section): Add sec argument. Adjust the code to get section
+ names from it.
+ (read_indirect_string): Adjust call to read_section.
+ (read_abbrevs): Ditto.
+ (decode_line_info): Ditto.
+ (read_debug_ranges): Ditto.
+ (DWARF2_DEBUG_INFO, DWARF2_COMPRESSED_DEBUG_INFO): Remove.
+ (find_debug_info): Add debug_sections parameter. Use it instead
+ the above macros.
+ (place_sections): Get section names from stash.
+ (find_line): Add debug_sections argument. Initialize
+ debug_sections field of stash from it.
+ Adjust calls to find_debug_info.
+ (_bfd_dwarf2_find_nearest_line): Add debug_sections argument.
+ Adjust call to find_line.
+ (_bfd_dwarf2_find_line): Adjust call to find_line.
+ * libcoff-in.h (struct dwarf_debug_section): New declaration.
+ (coff_find_nearest_line_with_names): Likewise.
+ * libcoff.h: Regenerate.
+ * libbfd-in.h (struct dwarf_debug_section): Move declaration.
+ (dwarf_debug_sections): Likewise.
+ (_bfd_dwarf2_find_nearest_line): Add debug_sections argument.
+ * libbfd.h: Regenerate.
+ * elf.c (_bfd_elf_find_nearest_line): Adjust call to
+ _bfd_dwarf2_find_nearest_line.
+ * elfxx-mips.c (_bfd_mips_elf_find_nearest_line): Ditto.
+ * elf64-alpha.c (elf64_alpha_find_nearest_line): Ditto.
+ * elf32-arm.c (elf32_arm_find_nearest_line): Ditto.
+ * coffgen.c (coff_find_nearest_line_with_names): New function.
+ (coff_find_nearest_line): Calls coff_find_nearest_line_with_names.
+ * coff-rs6000.c (xcoff_debug_sections): New constant.
+ (xcoff_find_nearest_line): New function.
+ (rs6000coff_vec): Use xcoff_find_nearest_line.
+ (pmac_xcoff_vec): Ditto.
+
+2011-09-30 Alan Modra <amodra@gmail.com>
+
+ PR ld/13235
+ * elf64-ppc.c (struct ppc64_elf_obj_tdata): Add ha_relocs_not_using_r2.
+ (ppc64_elf_edit_toc): Check HA relocs.
+ (ha_reloc_match): Delete function.
+ (ppc64_elf_relocate_section): Remove delayed HA nop optimization.
+ Instead do it and low part optimization based on
+ ha_relocs_not_using_r2.
+
+2011-09-29 Alan Modra <amodra@gmail.com>
+
+ PR ld/13233
+ * elflink.c (_bfd_elf_gc_mark_extra_sections): Mark single member
+ debug and special section groups.
+
+2011-09-29 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/13195
+ * elflink.c (_bfd_elf_merge_symbol): Don't set dynamic_def when
+ clearing def_dynamic.
+ (elf_link_add_object_symbols): Likewise. Set dynamic_def when
+ setting def_dynamic.
+ (bfd_elf_gc_mark_dynamic_ref_symbol): Check if a symbol is
+ versioned.
+
+2011-09-27 Kai Tietz <ktietz@redhat.com>
+
+ * coffcode.h (sec_to_styp_flags): Handle
+ SEC_LINK_DUPLICATES_SAME_CONTENTS, and
+ SEC_LINK_DUPLICATES_SAME_SIZE.
+
+2011-09-22 Tristan Gingold <gingold@adacore.com>
+
+ * configure.in: Bump version to 2.22.51
+ * configure: Regenerate.
+
+2011-09-21 David S. Miller <davem@davemloft.net>
+
+ * elfxx-sparc.c (_bfd_sparc_elf_merge_private_bfd_data): New.
+ * elfxx-sparc.h: Declare it.
+ * elf32-sparc.c (elf32_sparc_merge_private_bfd_data): Call it.
+ * elf64-sparc.c (elf64_sparc_merge_private_bfd_data): Likewise.
+
+2011-09-21 Tristan Gingold <gingold@adacore.com>
+
+ * mach-o.c (bfd_mach_o_convert_section_name_to_bfd): Add comment.
+ Deals with size limited strings.
+ (bfd_mach_o_build_commands): Initialize more fields.
+
+2011-09-15 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/13177
+ * elflink.c (elf_gc_sweep_symbol): Also hide symbols without PLT
+ nor GOT references.
+
+2011-09-15 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/12975
+ * bfd-in.h (bfd_elf_size_dynamic_sections): Remove pointer
+ to struct bfd_elf_version_tree.
+
+ * elflink.c (elf_info_failed): Remove verdefs.
+ (_bfd_elf_export_symbol): Updated.
+ _bfd_elf_link_assign_sym_version): Likewise.
+ (bfd_elf_size_dynamic_sections): Remove pointer to struct
+ bfd_elf_version_tree. Updated.
+ (bfd_elf_gc_mark_dynamic_ref_symbol): Check if a symbol is hidden
+ by linker script.
+
+ * linker.c (bfd_hide_sym_by_version): New.
+
+ * bfd-in2.h: Regenerated.
+
+2011-09-12 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/13178
+ * elf-ifunc.c (_bfd_elf_allocate_ifunc_dyn_relocs): Use .got.plt
+ if there are no GOT relocations.
+
+2011-09-09 Kai Tietz <ktietz@redhat.com>
+
+ * peicode.h (pe_ILF_build_a_bfd): Don't remove leading underscore
+ for targets without symbol_leading_char.
+
+2011-09-08 Bernd Jendrissek <bernd.jendrissek@gmail.com>
+
+ * bfdwin.c (bfd_get_file_window): Fix memory leak.
+
+2011-09-07 Alan Modra <amodra@gmail.com>
+
+ PR ld/13131
+ * bfd/elf64-ppc.c (adjust_toc_syms): Ensure ppc64_elf_howto_table
+ is initialized.
+
+2011-09-06 Alan Modra <amodra@gmail.com>
+
+ PR ld/13131
+ * elf64-ppc.c (adjust_toc_syms): Delete redundant code.
+ (ppc64_elf_edit_toc): Fix style nit. Report some details
+ on linker failure due to reference in debug or non-alloc
+ sections to optimized away toc entry, and don't abort.
+
+2011-09-01 Christophe Lyon <christophe.lyon@st.com>
+
+ * elf32-arm.c (elf32_arm_output_arch_local_syms): Skip excluded
+ sections.
+
+2011-08-26 Nick Clifton <nickc@redhat.com>
+
+ * po/es.po: Updated Spanish translation.
+
+2011-08-19 Alan Modra <amodra@gmail.com>
+
+ * elf64-ppc.c (ppc64_elf_edit_toc): Ignore can_optimize bit if
+ we haven't seen expected -mcmodel=medium/large code relocs.
+
+2011-08-18 Tristan Gingold <gingold@adacore.com>
+
+ * mach-o.c (bfd_mach_o_read_segment): Initialize list.
+
+2011-08-17 Tristan Gingold <gingold@adacore.com>
+
+ * mach-o.c (bfd_mach_o_write_section_32): Fix typo.
+
+2011-08-17 Alan Modra <amodra@gmail.com>
+
+ PR ld/12762
+ * bfd-in.h (struct bfd_section_already_linked): Forward declare.
+ (_bfd_handle_already_linked): Declare.
+ * coff-alpha.c (_bfd_ecoff_section_already_linked): Define as
+ _bfd_coff_section_already_linked.
+ * coff-mips.c (_bfd_ecoff_section_already_linked): Likewise.
+ * coffcode.h (coff_section_already_linked): Likewise.
+ * cofflink.c (coff_link_add_symbols): Revert 2011-07-09 changes.
+ * elf-bfd.h: Likewise.
+ * libbfd-in.h: Likewise.
+ * targets.c: Likewise.
+ * linker.c (bfd_section_already_linked): Likewise.
+ (bfd_section_already_linked_table_lookup): Likewise.
+ (bfd_section_already_linked_table_insert): Likewise.
+ (_bfd_generic_section_already_linked): Likewise. Call
+ _bfd_handle_already_linked.
+ (_bfd_handle_already_linked): New function, split out from..
+ * elflink.c (_bfd_elf_section_already_linked): ..here. Revert
+ 2011-07-09 changes. Avoid unnecessary strcmp when matching
+ already_linked_list entries. Match plugin linkonce section.
+ (section_signature): Delete.
+ * coffgen.c (_bfd_coff_section_already_linked): New function.
+ * libcoff-in.h (_bfd_coff_section_already_linked): Declare.
+ * libbfd.h: Regenerate.
+ * libcoff.h: Regenerate.
+ * bfd-in2.h: Regenerate.
+
+2011-08-14 Alan Modra <amodra@gmail.com>
+
+ * elf32-ppc.c (ppc_elf_select_plt_layout): Force bss-plt when
+ shared and call to _mcount will go via plt.
+
+2011-08-14 Alan Modra <amodra@gmail.com>
+
+ * elf64-ppc.c: Prefix all einfo error strings with "%P: ".
+ * elf32-ppc.c: Likewise.
+ (ppc_elf_select_plt_layout): Use einfo rather than info to report
+ forced bss-plt.
+
+2011-08-12 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/13082
+ * elf64-x86-64.c (x86_64_elf_howto_table): Add R_X86_64_RELATIVE64.
+ (elf_x86_64_relocate_section): Treat R_X86_64_64 like R_X86_64_32
+ and zero-extend it to 64bit if addend is zero for x32. Generate
+ R_X86_64_RELATIVE64 for x32.
+
+2011-08-09 Matthew Gretton-Dann <matthew.gretton-dann@arm.com>
+
+ * bfd-in.h (bfd_elf32_arm_set_target_relocs): Update prototype.
+ * bfd-in2.h (bfd_elf32_arm_set_target_relocs): Likewise.
+ * elf32-arm.c (elf32_arm_link_hash_table): New field.
+ (elf232_arm_link_hash_table_create): Initialise new field.
+ (check_use_blx): Change test depending on fix_arm1176.
+ (bfd_elf32_arm_set_target_relocs): Set fix_arm1176 from
+ command line options.
+
+2011-08-08 Tristan Gingold <gingold@adacore.com>
+
+ * mach-o.c (struct mach_o_segment_name_xlat): Add comments.
+ (segsec_names_xlat): Reorder elements.
+ (bfd_mach_o_read_section_32): Fix typo.
+ (bfd_mach_o_read_section_64): Fix typo.
+
+2011-08-08 Tristan Gingold <gingold@adacore.com>
+
+ * mach-o.h (BFD_MACH_O_SEGNAME_SIZE): New macro.
+ (BFD_MACH_O_SECTNAME_SIZE): Ditto.
+ (bfd_mach_o_section): Use them. Add next field.
+ (bfd_mach_o_segment_command): Replace sections array by
+ sect_head and sect_tail.
+ (bfd_mach_o_get_mach_o_section): New macro.
+ (bfd_mach_o_lookup_section): Remove.
+ (bfd_mach_o_new_section_hook): New function.
+ * mach-o.c (bfd_mach_o_normalize_section_name): Use strncmp
+ instead of strcmp.
+ (bfd_mach_o_convert_section_name_to_bfd): Replaces section
+ parameter with segname and sectname parameters. Adjust.
+ (bfd_mach_o_append_section_to_segment): New function. Use a
+ linked list for Mach-O sections.
+ (bfd_mach_o_write_segment_32): Adjust.
+ (bfd_mach_o_write_segment_64): Ditto.
+ (bfd_mach_o_build_commands): Fix comment. Adjust.
+ (bfd_mach_o_flatten_sections): Adjust.
+ (bfd_mach_o_print_section_map): Adjust.
+ (bfd_mach_o_set_section_flags_from_bfd): Ditto.
+ (bfd_mach_o_new_section_hook): New function.
+ (bfd_mach_o_init_section_from_mach_o): Ditto.
+ (bfd_mach_o_read_section_32): Remove section parameter.
+ Return a section instead.
+ (bfd_mach_o_read_section_64): Ditto.
+ (bfd_mach_o_read_section): Ditto.
+ (bfd_mach_o_make_bfd_section): Adjust.
+ (bfd_mach_o_read_segment): Adjust for new profile of
+ bfd_mach_o_read_section.
+ (bfd_mach_o_lookup_section): Remove.
+ * mach-o-target.c (bfd_mach_o_new_section_hook): Remove.
+
+2011-08-08 Tristan Gingold <gingold@adacore.com>
+
+ * mach-o.h (bfd_mach_o_version_min_command): New structure.
+ (bfd_mach_o_load_command): Add version_min.
+ (mach_o_data_struct): Fix comment.
+ * mach-o.c (bfd_mach_o_read_version_min): New function.
+ (bfd_mach_o_read_command): Handle BFD_MACH_O_LC_FUNCTION_STARTS,
+ BFD_MACH_O_LC_VERSION_MIN_MACOSX and
+ BFD_MACH_O_LC_VERSION_MIN_IPHONEOS.
+ (bfd_mach_o_get_name_or_null): New function.
+ (bfd_mach_o_get_name): Use the above new one.
+ (bfd_mach_o_load_command_name): Add the above new commands.
+ (bfd_mach_o_bfd_print_private_bfd_data): Display numerically
+ unknown commands. Handle BFD_MACH_O_LC_FUNCTION_STARTS,
+ BFD_MACH_O_LC_VERSION_MIN_MACOSX and
+ BFD_MACH_O_LC_VERSION_MIN_IPHONEOS.
+
+2011-08-08 Tristan Gingold <gingold@adacore.com>
+
+ * mach-o.h: Move size macros to external.h
+ Move reloc macros to reloc.h and x86-64.h.
+ * mach-o-i386.c: Includes mach-o/reloc.h
+ * mach-o-x86-64.c: Ditto and includes mach-o/x86-64.h
+ * mach-o.c: Add includes.
+ (bfd_mach_o_write_header): Use structure from external.h to convert.
+ (bfd_mach_o_write_thread): Ditto.
+ (bfd_mach_o_write_relocs): Ditto.
+ (bfd_mach_o_write_section_32): Ditto.
+ (bfd_mach_o_write_section_64): Ditto.
+ (bfd_mach_o_write_segment_32): Ditto.
+ (bfd_mach_o_write_segment_64): Ditto.
+ (bfd_mach_o_write_symtab): Ditto.
+ (bfd_mach_o_write_contents): Ditto.
+ (bfd_mach_o_read_header): Ditto.
+ (bfd_mach_o_read_section_32): Ditto.
+ (bfd_mach_o_read_section_64): Ditto.
+ (bfd_mach_o_read_symtab_symbol): Ditto.
+ (bfd_mach_o_read_dylinker): Ditto.
+ (bfd_mach_o_read_dylib): Ditto.
+ (bfd_mach_o_read_dysymtab): Ditto.
+ (bfd_mach_o_read_symtab): Ditto.
+ (bfd_mach_o_read_linkedit): Ditto.
+ (bfd_mach_o_read_str): Ditto.
+ (bfd_mach_o_read_dyld_info): Ditto.
+ (bfd_mach_o_read_segment): Ditto.
+ (bfd_mach_o_read_command): Ditto.
+ (bfd_mach_o_archive_p): Ditto.
+ (bfd_mach_o_canonicalize_one_reloc): Ditto. Change the BUF parameter.
+ (bfd_mach_o_canonicalize_relocs): Adjust to call the above function.
+ (bfd_mach_o_read_dysymtab_symbol): Rename BUF variable.
+ (bfd_mach_o_read_uuid): Remove useless cast. Use a macro instead
+ of an hard-coded value.
+
+2011-08-08 Tristan Gingold <gingold@adacore.com>
+
+ * mach-o-x86-64.c (bfd_mach_o_x86_64_mkobject): Fix cut-and-past typos.
+ (bfd_mach_o_x86_64_swap_reloc_out): Handle BFD_RELOC_32_PCREL,
+ BFD_RELOC_MACH_O_X86_64_SUBTRACTOR64 and
+ BFD_RELOC_MACH_O_X86_64_GOT_LOAD. Share common code.
+
+2011-08-08 Tristan Gingold <gingold@adacore.com>
+
+ * mach-o.c (bfd_mach_o_normalize_section_name): New function.
+ (bfd_mach_o_convert_section_name_to_bfd): Use it.
+ (bfd_mach_o_get_section_type_from_name): New function.
+ (bfd_mach_o_get_section_attribute_from_name): Ditto.
+ * mach-o.h (bfd_mach_o_section): Move bfdsection field at the end.
+ Add comments. Add prototypes for the above new functions.
+
+2011-08-05 Mark Kettenis <kettenis@gnu.org>
+
+ * netbsd-core.c (netbsd_core_vec): Init match_priority field.
+
+2011-08-05 Alan Modra <amodra@gmail.com>
+
+ * elf64-ppc.c (maybe_strip_output): New function.
+ (ppc64_elf_size_stubs): Use it to strip .branch_lt and .eh_frame.
+
+2011-08-05 Alan Modra <amodra@gmail.com>
+
+ PR ld/12762
+ * elflink.c (_bfd_elf_section_already_linked): Return matched
+ status. Remove COFF comdat section handling.
+ * linker.c (_bfd_generic_section_already_linked): Return matched
+ status. Don't set SEC_GROUP in l_flags for plugin entries.
+ (bfd_section_already_linked): Update prototype.
+ * targets.c (_section_already_linked): Likewise.
+ * elf-bfd.h (_bfd_elf_section_already_linked): Likewise.
+ * libbfd-in.h (_bfd_generic_section_already_linked): Likewise.
+ (_bfd_nolink_section_already_linked): Update.
+ * libbfd.h: Regenerate.
+ * bfd-in2.h: Regenerate.
+
+2011-08-05 Alan Modra <amodra@gmail.com>
+
+ * elf32-ppc.c: Include dwarf2.h.
+ (struct ppc_elf_link_hash_table): Add glink_eh_frame.
+ (ppc_elf_create_glink): Create .eh_frame section.
+ (glink_eh_frame_cie): New array.
+ (ppc_elf_size_dynamic_sections): Size glink_eh_frame.
+ (ppc_elf_finish_dynamic_sections): Write glink_eh_frame.
+
+2011-08-04 Tristan Gingold <gingold@adacore.com>
+
+ * vms-alpha.c (_bfd_vms_write_eeom): Round vms_linkage_index.
+ (_bfd_vms_write_etir): Initialize vms_linkage_index to 0.
+
+2011-08-03 Tristan Gingold <gingold@adacore.com>
+
+ * mach-o.c (bfd_mach_o_canonicalize_symtab): Handle no symbols case.
+ (bfd_mach_o_read_symtab_symbols): Return if no symbols.
+
+2011-08-02 Maciej W. Rozycki <macro@codesourcery.com>
+
+ * elfxx-mips.c (check_4byte_branch): Remove function.
+ (check_relocated_bzc): New function.
+ (_bfd_mips_elf_relax_section): Permit the relaxation of LUI
+ instructions that immediately follow a compact branch
+ instruction.
+
+2011-08-02 Alan Modra <amodra@gmail.com>
+
+ * elf64-ppc.c (build_plt_stub): Correct emitted relocs when no
+ plt_static_chain.
+ (ppc_build_one_stub): Adjust get_relocs call to suit..
+ (ppc_size_one_stub): ..and reloc sizing. Correct plt size corner case.
+
+2011-08-01 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/13048
+ * archures.c (bfd_mach_i386_intel_syntax): New.
+ (bfd_mach_i386_i8086): Updated.
+ (bfd_mach_i386_i386): Likewise.
+ (bfd_mach_x86_64): Likewise.
+ (bfd_mach_x64_32): Likewise.
+ (bfd_mach_i386_i386_intel_syntax): Likewise.
+ (bfd_mach_x86_64_intel_syntax): Likewise.
+ (bfd_mach_x64_32_intel_syntax): Likewise.
+ (bfd_mach_l1om): Likewise.
+ (bfd_mach_l1om_intel_syntax): Likewise.
+ (bfd_mach_k1om): Likewise.
+ (bfd_mach_k1om_intel_syntax): Likewise.
+
+ * bfd-in2.h: Regenerated.
+
+ * cpu-i386.c (bfd_i386_compatible): Check mach instead of
+ bits_per_address.
+ (bfd_x64_32_arch_intel_syntax): Set bits_per_address to 64.
+ (bfd_x64_32_arch): Likewise.
+
+ * elf64-x86-64.c: Include "libiberty.h".
+ (x86_64_elf_howto_table): Append x32 R_X86_64_32.
+ (elf_x86_64_rtype_to_howto): Support x32 R_X86_64_32.
+ (elf_x86_64_reloc_type_lookup): Likewise.
+ (elf_x86_64_reloc_name_lookup): Likewise.
+ (elf_x86_64_relocate_section): Likewise.
+ (elf_x86_64_check_relocs): Allow R_X86_64_64 relocations for x32.
+
+2011-07-29 Maciej W. Rozycki <macro@codesourcery.com>
+
+ * elfxx-mips.c (check_br32): Fix return type.
+
+2011-07-29 Maciej W. Rozycki <macro@codesourcery.com>
+
+ * elfxx-mips.c (bz_insn_16): Correct opcode mask.
+
+2011-07-29 Maciej W. Rozycki <macro@codesourcery.com>
+
+ * elfxx-mips.c: Adjust comments throughout.
+ (mips_elf_relax_delete_bytes): Reshape code.
+ (_bfd_mips_elf_relax_section): Remove check for
+ R_MICROMIPS_GPREL16 relocations. Reshape code.
+
+2011-07-28 Roland McGrath <mcgrathr@google.com>
+
+ * elf32-i386.c (NACL_PLT_ENTRY_SIZE, NACLMASK): New macros.
+ (elf_i386_nacl_plt0_entry): New variable.
+ (elf_i386_plt_entry): New variable.
+ (elf_i386_nacl_pic_plt0_entry): New variable.
+ (elf_i386_nacl_pic_plt_entry): New variable.
+ (elf_i386_nacl_plt, elf_i386_nacl_arch_bed): New variables.
+ (elf_backend_arch_data): New macro setting for elf_i386_nacl_vec stanza.
+ (elf_backend_plt_alignment): Likewise.
+
+ * config.bfd: Handle i[3-7]86-*-nacl*.
+ * elf32-i386.c (bfd_elf32_i386_nacl_vec): New backend vector stanza.
+ * targets.c: Support bfd_elf32_i386_nacl_vec.
+ * configure.in: Likewise.
+ * configure: Regenerated.
+
+ * elf32-i386.c (struct elf_i386_plt_layout): New type.
+ (GET_PLT_ENTRY_SIZE): New macro.
+ (elf_i386_plt): New variable.
+ (struct elf_i386_backend_data): New member `plt'.
+ (elf_i386_arch_bed): Add initializer for it.
+ (elf_i386_vxworks_arch_bed): Likewise.
+ (elf_i386_allocate_dynrelocs): Use GET_PLT_ENTRY_SIZE.
+ (elf_i386_plt_sym_val): Likewise.
+ (elf_i386_relocate_section): Likewise.
+ (elf_i386_finish_dynamic_symbol): Likewise.
+ Also use other elf_i386_plt_layout members for PLT details.
+ (elf_i386_finish_dynamic_sections): Likewise.
+
+ * elf32-i386.c (struct elf_i386_backend_data): New type.
+ (get_elf_i386_backend_data): New macro.
+ (elf_i386_arch_bed): New variable.
+ (elf_backend_arch_data): New macro.
+ (struct elf_i386_link_hash_table): Remove plt0_pad_byte and is_vxworks.
+ (elf_i386_link_hash_table_create): Don't initialize them.
+ (elf_i386_create_dynamic_sections): Find is_vxworks flags in
+ elf_i386_backend_data, not elf_i386_link_hash_table.
+ (elf_i386_adjust_dynamic_symbol): Likewise.
+ (elf_i386_allocate_dynrelocs): Likewise.
+ (elf_i386_readonly_dynrelocs): Likewise.
+ (elf_i386_size_dynamic_sections): Likewise.
+ (elf_i386_relocate_section): Likewise.
+ (elf_i386_finish_dynamic_symbol): Likewise.
+ (elf_i386_finish_dynamic_sections): Likewise. Same for plt0_pad_byte.
+ (elf_i386_vxworks_link_hash_table_create): Function removed.
+ (elf_i386_vxworks_arch_bed): New variable.
+ (elf_backend_arch_data): New macro in elf32-i386-vxworks stanza.
+
+ * elf-bfd.h (elf_backend_data): New member arch_backend_data.
+ * elfxx-target.h (elf_backend_arch_data): New macro.
+ (elfNN_bed): Use it as initializer for the new member.
+
+2011-07-28 Mikulas Patocka <mikulas@artax.karlin.mff.cuni.cz>
+
+ * elf64-hppa.c (elf_hppa_final_link_relocate): Fix handling of out
+ of range branches.
+
+2011-07-26 Jakub Jelinek <jakub@redhat.com>
+
+ * dwarf2.c (dwarf_debug_sections): Add .debug_macro
+ and .zdebug_macro entry.
+ (dwarf_debug_section_enum): Add debug_macro.
+
+2011-07-26 Alan Modra <amodra@gmail.com>
+
+ * elf64-ppc.c: Include dwarf2.h.
+ (struct ppc_link_hash_table): Add glink_eh_frame.
+ (create_linkage_sections): Create .eh_frame section.
+ (ppc64_elf_size_dynamic_sections): Arrange to drop unneeded
+ glink_eh_frame.
+ (glink_eh_frame_cie): New array.
+ (ppc64_elf_size_stubs): Size glink_eh_frame.
+ (ppc64_elf_build_stubs): Init glink_eh_frame contents.
+ (ppc64_elf_finish_dynamic_sections): Write glink_eh_frame.
+
+2011-07-25 Hans-Peter Nilsson <hp@bitrange.com>
+
+ PR ld/12815
+ * elf64-mmix.c (struct _mmix_elf_section_data): New members
+ has_warned_bpo and has_warned_pushj.
+ (mmix_final_link_relocate): Remove PARAMS and PTR macros,
+ converting to ISO C. Add new parameter error_message. All
+ callers changed.
+ (mmix_elf_perform_relocation): Ditto.
+ <case R_MMIX_PUSHJ_STUBBABLE, case R_MMIX_BASE_PLUS_OFFSET>:
+ Handle the case where mmix_elf_check_common_relocs has not been
+ called, missing preparations for relocs of the respective type.
+
+2011-07-24 Chao-ying Fu <fu@mips.com>
+ Ilie Garbacea <ilie@mips.com>
+ Maciej W. Rozycki <macro@codesourcery.com>
+ Joseph Myers <joseph@codesourcery.com>
+ Catherine Moore <clm@codesourcery.com>
+ Richard Sandiford <rdsandiford@googlemail.com>
+
+ * archures.c (bfd_mach_mips_micromips): New macro.
+ * cpu-mips.c (I_micromips): New enum value.
+ (arch_info_struct): Add bfd_mach_mips_micromips.
+ * elfxx-mips.h (_bfd_mips_elf_is_target_special_symbol): New
+ prototype.
+ (_bfd_mips_elf_relax_section): Likewise.
+ (_bfd_mips16_elf_reloc_unshuffle): Rename to...
+ (_bfd_mips_elf_reloc_unshuffle): ... this. Handle microMIPS
+ ASE.
+ (_bfd_mips16_elf_reloc_shuffle): Rename to...
+ (_bfd_mips_elf_reloc_shuffle): ... this. Handle microMIPS ASE.
+ (gprel16_reloc_p): Handle microMIPS ASE.
+ (literal_reloc_p): New function.
+ * elf32-mips.c (elf_micromips_howto_table_rel): New variable.
+ (_bfd_mips_elf32_gprel16_reloc): Handle microMIPS ASE.
+ (mips16_gprel_reloc): Update for _bfd_mips_elf_reloc_unshuffle
+ and _bfd_mips_elf_reloc_shuffle changes.
+ (mips_elf_gprel32_reloc): Update comment.
+ (micromips_reloc_map): New variable.
+ (bfd_elf32_bfd_reloc_type_lookup): Handle microMIPS ASE.
+ (mips_elf32_rtype_to_howto): Likewise.
+ (mips_info_to_howto_rel): Likewise.
+ (bfd_elf32_bfd_is_target_special_symbol): Define.
+ (bfd_elf32_bfd_relax_section): Likewise.
+ * elf64-mips.c (micromips_elf64_howto_table_rel): New variable.
+ (micromips_elf64_howto_table_rela): Likewise.
+ (mips16_gprel_reloc): Update for _bfd_mips_elf_reloc_unshuffle
+ and _bfd_mips_elf_reloc_shuffle changes.
+ (micromips_reloc_map): Likewise.
+ (bfd_elf64_bfd_reloc_type_lookup): Handle microMIPS ASE.
+ (bfd_elf64_bfd_reloc_name_lookup): Likewise.
+ (mips_elf64_rtype_to_howto): Likewise.
+ (bfd_elf64_bfd_is_target_special_symbol): Define.
+ * elfn32-mips.c (elf_micromips_howto_table_rel): New variable.
+ (elf_micromips_howto_table_rela): Likewise.
+ (mips16_gprel_reloc): Update for _bfd_mips_elf_reloc_unshuffle
+ and _bfd_mips_elf_reloc_shuffle changes.
+ (micromips_reloc_map): Likewise.
+ (bfd_elf32_bfd_reloc_type_lookup): Handle microMIPS ASE.
+ (bfd_elf32_bfd_reloc_name_lookup): Likewise.
+ (mips_elf_n32_rtype_to_howto): Likewise.
+ (bfd_elf32_bfd_is_target_special_symbol): Define.
+ * elfxx-mips.c (LA25_LUI_MICROMIPS_1): New macro.
+ (LA25_LUI_MICROMIPS_2): Likewise.
+ (LA25_J_MICROMIPS_1, LA25_J_MICROMIPS_2): Likewise.
+ (LA25_ADDIU_MICROMIPS_1, LA25_ADDIU_MICROMIPS_2): Likewise.
+ (TLS_RELOC_P): Handle microMIPS ASE.
+ (mips_elf_create_stub_symbol): Adjust value of stub symbol if
+ target is a microMIPS function.
+ (micromips_reloc_p): New function.
+ (micromips_reloc_shuffle_p): Likewise.
+ (got16_reloc_p, call16_reloc_p): Handle microMIPS ASE.
+ (got_disp_reloc_p, got_page_reloc_p): New functions.
+ (got_ofst_reloc_p): Likewise.
+ (got_hi16_reloc_p, got_lo16_reloc_p): Likewise.
+ (call_hi16_reloc_p, call_lo16_reloc_p): Likewise.
+ (hi16_reloc_p, lo16_reloc_p, jal_reloc_p): Handle microMIPS ASE.
+ (micromips_branch_reloc_p): New function.
+ (tls_gd_reloc_p, tls_ldm_reloc_p): Likewise.
+ (tls_gottprel_reloc_p): Likewise.
+ (_bfd_mips16_elf_reloc_unshuffle): Rename to...
+ (_bfd_mips_elf_reloc_unshuffle): ... this. Handle microMIPS
+ ASE.
+ (_bfd_mips16_elf_reloc_shuffle): Rename to...
+ (_bfd_mips_elf_reloc_shuffle): ... this. Handle microMIPS ASE.
+ (_bfd_mips_elf_lo16_reloc): Handle microMIPS ASE.
+ (mips_tls_got_index, mips_elf_got_page): Likewise.
+ (mips_elf_create_local_got_entry): Likewise.
+ (mips_elf_relocation_needs_la25_stub): Likewise.
+ (mips_elf_calculate_relocation): Likewise.
+ (mips_elf_perform_relocation): Likewise.
+ (_bfd_mips_elf_symbol_processing): Likewise.
+ (_bfd_mips_elf_add_symbol_hook): Likewise.
+ (_bfd_mips_elf_link_output_symbol_hook): Likewise.
+ (mips_elf_add_lo16_rel_addend): Likewise.
+ (_bfd_mips_elf_check_relocs): Likewise.
+ (mips_elf_adjust_addend): Likewise.
+ (_bfd_mips_elf_relocate_section): Likewise.
+ (mips_elf_create_la25_stub): Likewise.
+ (_bfd_mips_vxworks_finish_dynamic_symbol): Likewise.
+ (_bfd_mips_elf_gc_sweep_hook): Likewise.
+ (_bfd_mips_elf_is_target_special_symbol): New function.
+ (mips_elf_relax_delete_bytes): Likewise.
+ (opcode_descriptor): New structure.
+ (RA): New macro.
+ (OP32_SREG, OP32_TREG, OP16_VALID_REG): Likewise.
+ (b_insns_32, bc_insn_32, bz_insn_32, bzal_insn_32): New variables.
+ (beq_insn_32): Likewise.
+ (b_insn_16, bz_insn_16): New variables.
+ (BZC32_REG_FIELD): New macro.
+ (bz_rs_insns_32, bz_rt_insns_32): New variables.
+ (bzc_insns_32, bz_insns_16):Likewise.
+ (BZ16_REG, BZ16_REG_FIELD): New macros.
+ (jal_insn_32_bd16, jal_insn_32_bd32): New variables.
+ (jal_x_insn_32_bd32): Likewise.
+ (j_insn_32, jalr_insn_32): Likewise.
+ (ds_insns_32_bd16, ds_insns_32_bd32): Likewise.
+ (jalr_insn_16_bd16, jalr_insn_16_bd32, jr_insn_16): Likewise.
+ (JR16_REG): New macro.
+ (ds_insns_16_bd16): New variable.
+ (lui_insn): Likewise.
+ (addiu_insn, addiupc_insn): Likewise.
+ (ADDIUPC_REG_FIELD): New macro.
+ (MOVE32_RD, MOVE32_RS): Likewise.
+ (MOVE16_RD_FIELD, MOVE16_RS_FIELD): Likewise.
+ (move_insns_32, move_insns_16): New variables.
+ (nop_insn_32, nop_insn_16): Likewise.
+ (MATCH): New macro.
+ (find_match): New function.
+ (check_br16_dslot, check_br32_dslot): Likewise.
+ (check_br16, check_br32): Likewise.
+ (IS_BITSIZE): New macro.
+ (check_4byte_branch): New function.
+ (_bfd_mips_elf_relax_section): Likewise.
+ (_bfd_mips_elf_merge_private_bfd_data): Disallow linking MIPS16
+ and microMIPS modules together.
+ (_bfd_mips_elf_print_private_bfd_data): Handle microMIPS ASE.
+ * reloc.c (BFD_RELOC_MICROMIPS_7_PCREL_S1): New relocation.
+ (BFD_RELOC_MICROMIPS_10_PCREL_S1): Likewise.
+ (BFD_RELOC_MICROMIPS_16_PCREL_S1): Likewise.
+ (BFD_RELOC_MICROMIPS_GPREL16): Likewise.
+ (BFD_RELOC_MICROMIPS_JMP, BFD_RELOC_MICROMIPS_HI16): Likewise.
+ (BFD_RELOC_MICROMIPS_HI16_S): Likewise.
+ (BFD_RELOC_MICROMIPS_LO16): Likewise.
+ (BFD_RELOC_MICROMIPS_LITERAL): Likewise.
+ (BFD_RELOC_MICROMIPS_GOT16): Likewise.
+ (BFD_RELOC_MICROMIPS_CALL16): Likewise.
+ (BFD_RELOC_MICROMIPS_GOT_HI16): Likewise.
+ (BFD_RELOC_MICROMIPS_GOT_LO16): Likewise.
+ (BFD_RELOC_MICROMIPS_CALL_HI16): Likewise.
+ (BFD_RELOC_MICROMIPS_CALL_LO16): Likewise.
+ (BFD_RELOC_MICROMIPS_SUB): Likewise.
+ (BFD_RELOC_MICROMIPS_GOT_PAGE): Likewise.
+ (BFD_RELOC_MICROMIPS_GOT_OFST): Likewise.
+ (BFD_RELOC_MICROMIPS_GOT_DISP): Likewise.
+ (BFD_RELOC_MICROMIPS_HIGHEST): Likewise.
+ (BFD_RELOC_MICROMIPS_HIGHER): Likewise.
+ (BFD_RELOC_MICROMIPS_SCN_DISP): Likewise.
+ (BFD_RELOC_MICROMIPS_JALR): Likewise.
+ (BFD_RELOC_MICROMIPS_TLS_GD): Likewise.
+ (BFD_RELOC_MICROMIPS_TLS_LDM): Likewise.
+ (BFD_RELOC_MICROMIPS_TLS_DTPREL_HI16): Likewise.
+ (BFD_RELOC_MICROMIPS_TLS_DTPREL_LO16): Likewise.
+ (BFD_RELOC_MICROMIPS_TLS_GOTTPREL): Likewise.
+ (BFD_RELOC_MICROMIPS_TLS_TPREL_HI16): Likewise.
+ (BFD_RELOC_MICROMIPS_TLS_TPREL_LO16): Likewise.
+ * bfd-in2.h: Regenerate.
+ * libbfd.h: Regenerate.
+
+2011-07-22 H.J. Lu <hongjiu.lu@intel.com>
+
+ * Makefile.am (ALL_MACHINES): Add cpu-k1om.lo.
+ (ALL_MACHINES_CFILES): Add cpu-k1om.c.
+ * Makefile.in: Regenerated.
+
+ * archures.c (bfd_architecture): Add bfd_arch_k1om.
+ (bfd_k1om_arch): New.
+ (bfd_archures_list): Add &bfd_k1om_arch.
+ * bfd-in2.h: Regenerated.
+
+ * config.bfd (targ64_selvecs): Add bfd_elf64_k1om_vec if
+ bfd_elf64_x86_64_vec is supported. Add bfd_elf64_k1om_freebsd_vec
+ if bfd_elf64_x86_64_freebsd_vec is supported.
+ (targ_selvecs): Likewise.
+
+ * configure.in: Support bfd_elf64_k1om_vec and
+ bfd_elf64_k1om_freebsd_vec.
+ * configure: Regenerated.
+
+ * cpu-k1om.c: New.
+
+ * elf64-x86-64.c (elf64_k1om_elf_object_p): New.
+ (bfd_elf64_k1om_vec): Likewise.
+ (bfd_elf64_k1om_freebsd_vec): Likewise.
+
+ * targets.c (bfd_elf64_k1om_vec): New.
+ (bfd_elf64_k1om_freebsd_vec): Likewise.
+ (_bfd_target_vector): Add bfd_elf64_k1om_vec and
+ bfd_elf64_k1om_freebsd_vec.
+
+2011-07-20 Jan Kratochvil <jan.kratochvil@redhat.com>
+
+ Fix false coff-go32-exe matches.
+ * coff-i386.c (TARGET_SYM) <_bfd_check_format>: Conditionally use
+ COFF_CHECK_FORMAT.
+ * coff-stgo32.c (go32_check_format): New forward declaration.
+ (COFF_CHECK_FORMAT): New defintion.
+ (go32_check_format): New function.
+
+2011-07-15 Alan Modra <amodra@gmail.com>
+
+ * configure.in: Bump version.
+ * configure: Regenerate.
+
+2011-07-14 Alan Modra <amodra@gmail.com>
+
+ * linker.c (_bfd_generic_section_already_linked): Set l_flags.
+ * elf-bfd.h (struct already_linked): Forward declare.
+
+2011-07-14 Alan Modra <amodra@gmail.com>
+
+ * elflink.c (_bfd_elf_fix_symbol_flags): Loop on indirect syms.
+ (_bfd_elf_adjust_dynamic_symbol): Remove FIXME.
+
+2011-07-14 Alan Modra <amodra@gmail.com>
+
+ * elf64-ppc.c (struct ppc_link_hash_table): Add plt_static_chain.
+ (build_plt_stub): Add plt_static_chain param, don't load r11 if false.
+ (build_tls_get_addr_stub): Likewise.
+ (ppc_build_one_stub): Update calls to above.
+ (ppc_size_one_stub): Adjust stub size.
+ (ppc64_elf_size_stubs): Add plt_static_chain param, save to htab.
+ * elf64-ppc.h (ppc64_elf_size_stubs): Update prototype.
+
+2011-07-12 Nick Clifton <nickc@redhat.com>
+
+ * elf32-arm.c (elf32_arm_section_flags): Delete.
+ (elf_backend_section_flags): Remove.
+
+2011-07-11 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/12982
+ * elflink.c (bfd_elf_size_dynamic_sections): Also skip BFD_PLUGIN
+ when setting stack_flags.
+
+2011-07-11 Catherine Moore <clm@codesourcery.com>
+
+ * aout-adobe.c (aout_32_bfd_lookup_section_flags): New definition.
+ * aout-target.h (MY_bfd_lookup_section_flags): New definition.
+ * aout-tic30.c (MY_bfd_lookup_section_flags): New definition.
+ * bfd-in2.h: Regenerated.
+ * bfd.c (bfd_lookup_section_flags): New definition.
+ * binary.c (binary_bfd_lookup_section_flags): New definition.
+ * bout.c (b_out_bfd_lookup_section_flags): New definition.
+ * coff-alpha.c (_bfd_ecoff_bfd_lookup_section_flags): New definition.
+ * coff-mips.c (_bfd_ecoff_bfd_lookup_section_flags): New definition.
+ * coff-rs6000.c (rs6000coff_vec): Include
+ bfd_generic_lookup_section_flags.
+ (pmac_xcoff_vec): Likewise.
+ * coffcode.h (coff_bfd_lookup_section_flags): New definition.
+ * coff64-rs6000.c (rs6000coff64_vec): Include
+ bfd_generic_lookup_section_flags.
+ (aix5coff64_vec): Likewise.
+ * ecoff.c (bfd_debug_section): Initialize flag_info field.
+ * elf-bfd.h (elf_backend_lookup_section_flags_hook): Declare.
+ (bfd_elf_lookup_section_flags): Declare.
+ * elflink.c (bfd_elf_lookup_section_flags): New function.
+ * elfxx-target.h (bfd_elfNN_bfd_lookup_section_flags): Define.
+ (elf_backend_lookup_section_flags_hook): Define.
+ (elf_backend_data): Add elf_backend_lookup_section_flags_hook.
+ * i386msdos.c (msdos_bfd_lookup_section_flags): New define.
+ * i386os9k.c (os9k_bfd_lookup_section_flags): New define.
+ * ieee.c (ieee_bfd_lookup_section_flags): New define.
+ * ihex.c (ihex_bfd_lookup_section_flags): New define.
+ * libbfd-in.h (_bfd_nolink_bfd_lookup_section_flags): Declare.
+ (bfd_generic_lookup_section_flags): Declare.
+ * libbfd.h: Regenerated.
+ * mach-o-target.c (bfd_mach_o_bfd_lookup_section_flags): New.
+ * mmo.c (mmo_bfd_lookup_section_flags): New definition.
+ * nlm-target.h (nlm_bfd_lookup_section_flags): New definition.
+ * oasys.c (oasys_bfd_lookup_section_flags): New definition.
+ * pef.c (bfd_pef_bfd_lookup_section_flags): New definition.
+ * plugin.c (bfd_plugin_bfd_lookup_section_flags): New definition.
+ * ppcboot.c (ppcboot_bfd_lookup_section_flags): New definition.
+ * reloc.c (bfd_generic_lookup_section_flags): New function.
+ * som.c (som_bfd_lookup_section_flags): New definition.
+ * srec.c (srec_bfd_lookup_section_flags): New definition.
+ * targets.c (flag_info): Declare.
+ (NAME##_bfd_lookup_section_flags): Add to LINK jump table.
+ (_bfd_lookup_section_flags): New.
+ * tekhex.c (tekhex_bfd_lookup_section_flags): New definition.
+ * versados.c (versados_bfd_lookup_section_flags): New definition.
+ * vms-alpha.c (alpha_vms_bfd_lookup_section_flag): New definition.
+ * xsym.c (bfd_sym_bfd_lookup_section_flags): New definition.
+
+2011-07-11 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/12978
+ * elfnn-ia64.c (count_dyn_reloc): Fix a typo.
+
+2011-07-09 Alan Modra <amodra@gmail.com>
+
+ PR ld/12942
+ * elflink.c (elf_link_add_object_symbols): Use elf_discarded_section
+ rather than kept_section to determine whether a symbol is from
+ a discarded section.
+ * cofflink.c (coff_link_add_symbols): Make symbols from discarded
+ sections appear undefined.
+
+2011-07-09 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/12942
+ * elf-bfd.h (_bfd_elf_section_already_linked): Replace
+ "asection *" with "struct already_linked *".
+ * libbfd-in.h (_bfd_nolink_section_already_linked): Likewise.
+ (_bfd_generic_section_already_linked): Likewise.
+ (bfd_section_already_linked_table_insert): Likewise.
+ (struct already_linked): New.
+ (struct bfd_section_already_linked): Use it.
+ * elflink.c (_bfd_elf_section_already_linked): Replace.
+ "asection *" with "struct already_linked *". Replace the plugin
+ dummy with the LTO output.
+ * linker.c (_bfd_generic_section_already_linked): Likewise.
+ * targets.c (struct already_linked): Add forward declaration.
+ (bfd_target): Replace "struct bfd_section *" with
+ "struct already_linked *" in _section_already_linked.
+ * bfd-in2.h: Regenerate.
+ * libbfd.h: Regenerate.
+
+2011-07-06 Tristan Gingold <gingold@adacore.com>
+
+ * mach-o.h: Move loader related definitions to
+ include/mach-o/loader.h. Include it.
+
+2011-07-05 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf64-x86-64.c (elf_backend_post_process_headers): Always
+ define to _bfd_elf_set_osabi.
+
+2011-07-03 Samuel Thibault <samuel.thibault@gnu.org>
+ Thomas Schwinge <thomas@schwinge.name>
+
+ PR binutils/12913
+ * elf.c (_bfd_elf_set_osabi): Use ELFOSABI_GNU name instead of
+ ELFOSABI_LINUX alias.
+ * elf32-hppa.c: Likewise.
+ * elf32-i370.c: Likewise.
+ * elf64-hppa.c: Likewise.
+
+2011-07-01 Ian Lance Taylor <iant@google.com>
+
+ * elf32-i386.c (elf_i386_eh_frame_plt): Correct expression: change
+ DW_OP_lit3 to DW_OP_lit2.
+
+2011-07-01 Alan Modra <amodra@gmail.com>
+
+ * elf32-ppc.c (ppc_elf_copy_indirect_symbol): Don't look at
+ dyn relocs when called to copy flags for a weak sym.
+ * elf64-ppc.c (ppc64_elf_copy_indirect_symbol): Likewise.
+ (ppc64_elf_merge_private_bfd_data): Delete.
+ (bfd_elf64_bfd_merge_private_bfd_data): Define as
+ _bfd_generic_verify_endian_match.
+
+2011-06-30 Bernd Schmidt <bernds@codesourcery.com>
+
+ * bfd/elf32-tic6x.c (elf32_tic6x_set_osabi): Also set it if
+ link_info is NULL.
+
+2011-06-28 Tristan Gingold <gingold@adacore.com>
+
+ * vms-alpha.c (vms_private_data_struct): Make vms_linkage_index
+ unsigned int.
+ (_bfd_vms_write_etir): Write linkage index from reloc.
+
+2011-06-28 Fawzi Mohamed <fawzi.mohamed@nokia.com>
+
+ * mach-o.c (bfd_mach_o_read_command): Also ignore
+ BFD_MACH_O_LC_ROUTINES_64.
+
+2011-06-27 Tristan Gingold <gingold@adacore.com>
+
+ * vms-alpha.c (_bfd_vms_write_etir): Use 'section' to get current
+ section target index.
+
+2011-06-27 Nick Clifton <nickc@redhat.com>
+
+ * cisco-core.c (cisco_core_little_vec): Add initialization of
+ match_priority field.
+
+2011-06-27 Tristan Gingold <gingold@adacore.com>
+
+ * cache.c: Include bfd_stdint.h.
+ (cache_bmmap): Change profile. Return region start and size.
+ * bfdio.c (struct bfd_iovec): Change bmmap profile.
+ (bfd_mmap): Change profile and adjust. Update comment.
+ (memory_bmmap): Change profile.
+ * opncls.c (opncls_bmmap): Change profile.
+ * vms-lib.c (vms_lib_bmmap): Likewise.
+ * libbfd.h: Regenerate.
+ * bfd-in2.h: Regenerate.
+
+2011-06-27 Tristan Gingold <gingold@adacore.com>
+
+ * vms-misc.c (vms_time_to_time_t): Adjust overflow detection.
+ Add comment.
+
+2011-06-25 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf64-x86-64.c (elf_backend_post_process_headers): Don't
+ define for FreeBSD/x86-64 nor FreeBSD/L1OM. Define for L1OM.
+
+2011-06-25 Jan Kratochvil <jan.kratochvil@redhat.com>
+
+ * elf64-x86-64.c (elf_x86_64_link_hash_table_create): Initialize
+ PLT_EH_FRAME.
+ * elf32-i386.c (elf_i386_link_hash_table): Likewise.
+
+2011-06-24 Richard Henderson <rth@redhat.com>
+
+ PR ld/12928
+ * elf64-alpha.c (elf64_alpha_relax_tls_get_addr): Recover the
+ tlsgd insn before swapping adjacent insns.
+
+2011-06-24 Tristan Gingold <gingold@adacore.com>
+
+ * vms-alpha.c (alpha_vms_slurp_relocs): Add a guard for relocs in the
+ absolute section.
+
+2011-06-24 Alan Modra <amodra@gmail.com>
+
+ PR ld/12921
+ * elf.c (assign_file_positions_for_load_sections): Don't align
+ sh_offset for all SHT_NOBITS sections here, just .tbss sections
+ that don't get a PT_LOAD.
+
+2011-06-22 Kaz Kojima <kkojima@rr.iij4u.or.jp>
+
+ * elf32-sh.c (sh_elf_relocate_section): Allow R_SH_TLS_LE_32 for PIE.
+ (sh_elf_check_relocs): Likewise.
+
+2011-06-22 Richard Henderson <rth@redhat.com>
+
+ * elf64-alpha.c (elf64_alpha_check_relocs): No dynamic reloc for
+ TPREL in a PIE image.
+ (alpha_dynamic_entries_for_reloc): Likewise.
+ (elf64_alpha_relocate_section): Allow TPREL in PIE images.
+ (elf64_alpha_relax_got_load): Likewise.
+
+2011-06-22 Ramana Radhakrishnan <ramana.radhakrishnan@linaro.org>
+
+ * elf32-arm.c (elf32_arm_final_link_relocate): Allow R_ARM_TLS_LE32
+ for PIE.
+
+2011-06-22 Alan Modra <amodra@gmail.com>
+
+ * elflink.c (_bfd_elf_merge_symbol): Allow type changes for
+ plugin symbols. Fix segfault on linker scrip defined syms.
+
+2011-06-20 Jakub Jelinek <jakub@redhat.com>
+
+ PR ld/12570
+ * elf-eh-frame.c (_bfd_elf_parse_eh_frame): Allow no relocations
+ at all for linker created .eh_frame sections.
+ (_bfd_elf_discard_section_eh_frame): Handle linker created
+ .eh_frame sections with no relocations.
+ * elf64-x86-64.c: Include dwarf2.h.
+ (elf_x86_64_eh_frame_plt): New variable.
+ (PLT_CIE_LENGTH, PLT_FDE_LENGTH, PLT_FDE_START_OFFSET,
+ PLT_FDE_LEN_OFFSET): Define.
+ (struct elf_x86_64_link_hash_table): Add plt_eh_frame field.
+ (elf_x86_64_create_dynamic_sections): Create and fill in
+ .eh_frame section for .plt section.
+ (elf_x86_64_size_dynamic_sections): Write .plt section size
+ into .eh_frame FDE covering .plt section.
+ (elf_x86_64_finish_dynamic_sections): Write .plt section
+ start into .eh_frame FDE covering .plt section. Call
+ _bfd_elf_write_section_eh_frame on htab->plt_eh_frame section.
+ (elf_backend_plt_alignment): Define to 4.
+ * elf32-i386.c: Include dwarf2.h.
+ (elf_i386_eh_frame_plt): New variable.
+ (PLT_CIE_LENGTH, PLT_FDE_LENGTH, PLT_FDE_START_OFFSET,
+ PLT_FDE_LEN_OFFSET): Define.
+ (struct elf_i386_link_hash_table): Add plt_eh_frame field.
+ (elf_i386_create_dynamic_sections): Create and fill in
+ .eh_frame section for .plt section.
+ (elf_i386_size_dynamic_sections): Write .plt section size
+ into .eh_frame FDE covering .plt section.
+ (elf_i386_finish_dynamic_sections): Write .plt section
+ start into .eh_frame FDE covering .plt section. Call
+ _bfd_elf_write_section_eh_frame on htab->plt_eh_frame section.
+ (elf_backend_plt_alignment): Define to 4.
+
+2011-06-19 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf64-x86-64.c (elf_backend_post_process_headers): Defined
+ for x32.
+
+2011-06-16 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf64-x86-64.c: Include <stdarg.h> and CORE_HEADER if
+ CORE_HEADER is defined.
+ (elf_x86_64_write_core_note): New.
+ (elf_backend_write_core_note): Likewise.
+
+ * hosts/x86-64linux.h (uint64_t): New.
+ (user_regsx32_struct): Likewise.
+ (elf_gregx32_t): Likewise.
+ (ELF_NGREGX32): Likewise.
+ (elf_gregsetx32_t): Likewise.
+ (elf_prstatusx32): Likewise.
+ (prstatusx32_t): Likewise.
+ (user_fpregs32_struct): Removed.
+ (user_fpxregs32_struct): Likewise.
+ (user32): Likewise.
+ (elf_fpregset32_t): Likewise.
+ (elf_fpxregset32_t): Likewise.
+ (prgregset32_t): Likewise.
+ (prfpregset32_t): Likewise.
+
+2011-06-16 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf64-x86-64.c (elf_x86_64_grok_prstatus): Support x32.
+ (elf_x86_64_grok_psinfo): Likewise.
+
+2011-06-16 Nick Clifton <nickc@redhat.com>
+
+ * elf.c (elf_find_function): Fail if not provided with a symbol
+ table.
+
+2011-06-15 Ulrich Weigand <ulrich.weigand@linaro.org>
+
+ * elf-bfd.h (elfcore_write_arm_vfp): Add prototype.
+ * elf.c (elfcore_grok_arm_vfp): New function.
+ (elfcore_grok_note): Call it to handle NT_ARM_VFP notes.
+ (elfcore_write_arm_vfp): New function.
+ (elfcore_write_register_note): Call it to handle .reg-arm-vfp.
+
+2011-06-14 Richard Henderson <rth@redhat.com>
+
+ * elf64-alpha.c (elf64_alpha_copy_indirect_symbol): Rename from
+ elf64_alpha_merge_ind_symbols; adjust for the generic interface.
+ (elf64_alpha_always_size_sections): Don't call
+ elf64_alpha_merge_ind_symbols.
+ (elf_backend_copy_indirect_symbol): New.
+
+2011-06-14 Alan Modra <amodra@gmail.com>
+
+ PR ld/12887
+ * elf-eh-frame.c (_bfd_elf_parse_eh_frame): Check sec_info_type
+ before doing anything.
+ (_bfd_elf_discard_section_eh_frame): Likewise.
+
+2011-06-14 Alan Modra <amodra@gmail.com>
+
+ * Makefile.am: Formatting.
+ * Makefile.in: Regenerate.
+ * configure.in (bfd_elf64_tilegx_vec): Add elfxx-tilegx.lo.
+ * po/SRC-POTFILES.in: Regnerate.
+
+2011-06-14 Alan Modra <amodra@gmail.com>
+
+ * elf32-tilepro.c (tilepro_elf_size_dynamic_sections): Don't use PTR.
+ (allocate_dynrelocs, readonly_dynrelocs): Replace PTR with void *.
+ Don't handle warning symbols here.
+ * elfxx-tilegx.c (tilegx_elf_size_dynamic_sections): As above.
+ (allocate_dynrelocs, readonly_dynrelocs): As above.
+
+2011-06-14 Alan Modra <amodra@gmail.com>
+
+ PR ld/12851
+ * elflink.c (_bfd_elf_gc_mark_extra_sections): New function.
+ (elf_gc_sweep): Don't treat debug and sections like .comment
+ specially here.
+ (bfd_elf_gc_sections): Treat note sections as gc roots only when
+ not part of a group. Always call gc_mark_extra_sections.
+ * elf-bfd.h (_bfd_elf_gc_mark_extra_sections): Declare.
+ * elfxx-target.h (elf_backend_gc_mark_extra_sections): Default to
+ _bfd_elf_gc_mark_extra_sections.
+ * elf32-arm.c (elf32_arm_gc_mark_extra_sections): Call
+ _bfd_elf_gc_mark_extra_sections.
+ * elf32-tic6x.c (elf32_tic6x_gc_mark_extra_sections): Likewise.
+
+2011-06-13 Nick Clifton <nickc@redhat.com>
+
+ * elf32-tilepro.c (tilepro_elf_check_relocs): Delete unused local
+ variable 'local_got_offsets'.
+ * elfxx-tilegx.c (tilegx_elf_check_relocs): Likewise.
+ (tilegx_finish_dyn): Delete unused local variable 'abi_64_p'.
+
+2011-06-13 Walter Lee <walt@tilera.com>
+
+ * Makefile.am (ALL_MACHINES): Add cpu-tilegx.lo and cpu-tilepro.lo.
+ (ALL_MACHINE_CFILES): Add cpu-tilegx.c and cpu-tilepro.c.
+ (BFD32_BACKENDS): Add elf32-tilegx.lo, elf32-tilepro.lo,
+ and elfxx-tilegx.lo.
+ (BFD32_BACKENDS_CFILES): Add elf32-tilegx.c elf32-tilepro.c, and
+ elfxx-tilegx.c.
+ (BFD64_BACKENDS): Add elf64-tilegx.lo.
+ (BFD64_BACKENDS_CFILES): Add elf64-tilegx.c.
+ * Makefile.in: Regenerate.
+ * arctures.c (bfd_architecture): Define bfd_arch_tilepro,
+ bfd_arch_tilegx, bfd_mach_tilepro, bfd_mach_tilegx.
+ (bfd_arch_info): Add bfd_tilegx_arch, bfd_tilepro_arch.
+ (bfd_archures_list): Add bfd_tilegx_arch, bfd_tilepro_arch.
+ bfd-in2.h: Regenerate.
+ * config.bfd: Handle tilegx-*-* and tilepro-*-*.
+ * configure.in: Handle bfd_elf32_tilegx_vec, bfd_elf32_tilepro_vec,
+ and bfd_elf64_tilegx_vec.
+ * configure: Regenerate.
+ * elf-bfd.h (enum elf_target_id): Define TILEGX_ELF_DATA and
+ TILEPRO_ELF_DATA.
+ * libbfd.h: Regenerate.
+ * reloc.c: Add BFD_RELOC_TILEPRO_{COPY, GLOB_DAT, JMP_SLOT,
+ RELATIVE, BROFF_X1, JOFFLONG_X1, JOFFLONG_X1_PLT, IMM8_X0,
+ IMM8_Y0, IMM8_X1, IMM8_Y1, DEST_IMM8_X1, MT_IMM15_X1, MF_IMM15_X1,
+ IMM16_X0, IMM16_X1, IMM16_X0_LO, IMM16_X1_LO, IMM16_X0_HI,
+ IMM16_X1_HI, IMM16_X0_HA, IMM16_X1_HA, IMM16_X0_PCREL,
+ IMM16_X1_PCREL, IMM16_X0_LO_PCREL, IMM16_X1_LO_PCREL,
+ IMM16_X0_HI_PCREL, IMM16_X1_HI_PCREL, IMM16_X0_HA_PCREL,
+ IMM16_X1_HA_PCREL, IMM16_X0_GOT, IMM16_X1_GOT, IMM16_X0_GOT_LO,
+ IMM16_X1_GOT_LO, IMM16_X0_GOT_HI, IMM16_X1_GOT_HI,
+ IMM16_X0_GOT_HA, IMM16_X1_GOT_HA, MMSTART_X0, MMEND_X0,
+ MMSTART_X1, MMEND_X1, SHAMT_X0, SHAMT_X1, SHAMT_Y0, SHAMT_Y1,
+ IMM16_X0_TLS_GD, IMM16_X1_TLS_GD, IMM16_X0_TLS_GD_LO,
+ IMM16_X1_TLS_GD_LO, IMM16_X0_TLS_GD_HI, IMM16_X1_TLS_GD_HI,
+ IMM16_X0_TLS_GD_HA, IMM16_X1_TLS_GD_HA, IMM16_X0_TLS_IE,
+ IMM16_X1_TLS_IE, IMM16_X0_TLS_IE_LO, IMM16_X1_TLS_IE_LO,
+ IMM16_X0_TLS_IE_HI, IMM16_X1_TLS_IE_HI, IMM16_X0_TLS_IE_HA,
+ IMM16_X1_TLS_IE_HA, TLS_DTPMOD32, TLS_DTPOFF32, TLS_TPOFF32}
+ Add BFD_RELOC_TILEGX_{HW0, HW1, HW2, HW3, HW0_LAST, HW1_LAST,
+ HW2_LAST, COPY, GLOB_DAT, JMP_SLOT, RELATIVE, BROFF_X1,
+ JUMPOFF_X1, JUMPOFF_X1_PLT, IMM8_X0, IMM8_Y0, IMM8_X1, IMM8_Y1,
+ DEST_IMM8_X1, MT_IMM14_X1, MF_IMM14_X1, MMSTART_X0, MMEND_X0,
+ SHAMT_X0, SHAMT_X1, SHAMT_Y0, SHAMT_Y1, IMM16_X0_HW0,
+ IMM16_X1_HW0, IMM16_X0_HW1, IMM16_X1_HW1, IMM16_X0_HW2,
+ IMM16_X1_HW2, IMM16_X0_HW3, IMM16_X1_HW3, IMM16_X0_HW0_LAST,
+ IMM16_X1_HW0_LAST, IMM16_X0_HW1_LAST, IMM16_X1_HW1_LAST,
+ IMM16_X0_HW2_LAST, IMM16_X1_HW2_LAST, IMM16_X0_HW0_PCREL,
+ IMM16_X1_HW0_PCREL, IMM16_X0_HW1_PCREL, IMM16_X1_HW1_PCREL,
+ IMM16_X0_HW2_PCREL, IMM16_X1_HW2_PCREL, IMM16_X0_HW3_PCREL,
+ IMM16_X1_HW3_PCREL, IMM16_X0_HW0_LAST_PCREL,
+ IMM16_X1_HW0_LAST_PCREL, IMM16_X0_HW1_LAST_PCREL,
+ IMM16_X1_HW1_LAST_PCREL, IMM16_X0_HW2_LAST_PCREL,
+ IMM16_X1_HW2_LAST_PCREL, IMM16_X0_HW0_GOT, IMM16_X1_HW0_GOT,
+ IMM16_X0_HW1_GOT, IMM16_X1_HW1_GOT, IMM16_X0_HW2_GOT,
+ IMM16_X1_HW2_GOT, IMM16_X0_HW3_GOT, IMM16_X1_HW3_GOT,
+ IMM16_X0_HW0_LAST_GOT, IMM16_X1_HW0_LAST_GOT,
+ IMM16_X0_HW1_LAST_GOT, IMM16_X1_HW1_LAST_GOT,
+ IMM16_X0_HW2_LAST_GOT, IMM16_X1_HW2_LAST_GOT, IMM16_X0_HW0_TLS_GD,
+ IMM16_X1_HW0_TLS_GD, IMM16_X0_HW1_TLS_GD, IMM16_X1_HW1_TLS_GD,
+ IMM16_X0_HW2_TLS_GD, IMM16_X1_HW2_TLS_GD, IMM16_X0_HW3_TLS_GD,
+ IMM16_X1_HW3_TLS_GD, IMM16_X0_HW0_LAST_TLS_GD,
+ IMM16_X1_HW0_LAST_TLS_GD, IMM16_X0_HW1_LAST_TLS_GD,
+ IMM16_X1_HW1_LAST_TLS_GD, IMM16_X0_HW2_LAST_TLS_GD,
+ IMM16_X1_HW2_LAST_TLS_GD, IMM16_X0_HW0_TLS_IE,
+ IMM16_X1_HW0_TLS_IE, IMM16_X0_HW1_TLS_IE, IMM16_X1_HW1_TLS_IE,
+ IMM16_X0_HW2_TLS_IE, IMM16_X1_HW2_TLS_IE, IMM16_X0_HW3_TLS_IE,
+ IMM16_X1_HW3_TLS_IE, IMM16_X0_HW0_LAST_TLS_IE,
+ IMM16_X1_HW0_LAST_TLS_IE, IMM16_X0_HW1_LAST_TLS_IE,
+ IMM16_X1_HW1_LAST_TLS_IE, IMM16_X0_HW2_LAST_TLS_IE,
+ IMM16_X1_HW2_LAST_TLS_IE, TLS_DTPMOD64, TLS_DTPOFF64, TLS_TPOFF64,
+ TLS_DTPMOD32, TLS_DTPOFF32, TLS_TPOFF32}
+ * targets.c (bfd_elf32_tilegx_vec): Declare.
+ (bfd_elf32_tilepro_vec): Declare.
+ (bfd_elf64_tilegx_vec): Declare.
+ (bfd_target_vector): Add bfd_elf32_tilegx_vec, bfd_elf32_tilepro_vec,
+ and bfd_elf64_tilegx_vec.
+ * cpu-tilegx.c: New file.
+ * cpu-tilepro.c: New file.
+ * elf32-tilepro.h: New file.
+ * elf32-tilepro.c: New file.
+ * elf32-tilegx.c: New file.
+ * elf32-tilegx.h: New file.
+ * elf64-tilegx.c: New file.
+ * elf64-tilegx.h: New file.
+ * elfxx-tilegx.c: New file.
+ * elfxx-tilegx.h: New file.
+
+2011-06-13 Alan Modra <amodra@gmail.com>
+
+ * linker.c (bfd_link_hash_traverse): Follow warning symbol link.
+ (_bfd_generic_link_write_global_symbol, fix_syms): Don't handle
+ warning symbols here.
+ * elf-m10300.c (elf32_mn10300_finish_hash_table_entry): Likewise.
+ * elf32-arm.c (allocate_dynrelocs_for_symbol,
+ elf32_arm_readonly_dynrelocs): Likewise.
+ * elf32-bfin.c (bfin_discard_copies): Likewise.
+ * elf32-cris.c (elf_cris_adjust_gotplt_to_got,
+ elf_cris_discard_excess_dso_dynamics,
+ elf_cris_discard_excess_program_dynamics): Likewise.
+ * elf32-hppa.c (allocate_plt_static, allocate_dynrelocs,
+ clobber_millicode_symbols, readonly_dynrelocs): Likewise.
+ * elf32-i370.c (i370_elf_adjust_dynindx): Likewise.
+ * elf32-i386.c (elf_i386_allocate_dynrelocs,
+ elf_i386_readonly_dynrelocs): Likewise.
+ * elf32-lm32.c (allocate_dynrelocs, readonly_dynrelocs): Likewise.
+ * elf32-m32c.c (m32c_relax_plt_check, m32c_relax_plt_realloc): Likewise.
+ * elf32-m32r.c (allocate_dynrelocs, readonly_dynrelocs): Likewise.
+ * elf32-m68k.c (elf_m68k_discard_copies): Likewise.
+ * elf32-microblaze.c (allocate_dynrelocs): Likewise.
+ * elf32-ppc.c (allocate_dynrelocs, maybe_set_textrel): Likewise.
+ * elf32-s390.c (allocate_dynrelocs, readonly_dynrelocs): Likewise.
+ * elf32-score.c (score_elf_sort_hash_table_f): Likewise.
+ * elf32-score7.c (score_elf_sort_hash_table_f): Likewise.
+ * elf32-sh.c (allocate_dynrelocs, readonly_dynrelocs): Likewise.
+ * elf32-tic6x.c (elf32_tic6x_allocate_dynrelocs,
+ elf32_tic6x_readonly_dynrelocs): Likewise.
+ * elf32-vax.c (elf_vax_discard_copies): Likewise.
+ * elf32-xstormy16.c (xstormy16_relax_plt_check,
+ xstormy16_relax_plt_realloc): Likewise.
+ * elf32-xtensa.c (elf_xtensa_allocate_dynrelocs): Likewise.
+ * elf64-alpha.c (elf64_alpha_output_extsym,
+ elf64_alpha_calc_got_offsets_for_symbol,
+ elf64_alpha_calc_dynrel_sizes, elf64_alpha_size_rela_got_1): Likewise.
+ * elf64-hppa.c (elf64_hppa_mark_exported_functions,
+ allocate_global_data_opd, elf64_hppa_mark_milli_and_exported_functions,
+ elf_hppa_unmark_useless_dynamic_symbols,
+ elf_hppa_remark_useless_dynamic_symbols): Likewise.
+ * elf64-ppc.c (ppc64_elf_gc_mark_dynamic_ref, func_desc_adjust,
+ adjust_opd_syms, adjust_toc_syms, allocate_dynrelocs,
+ readonly_dynrelocs, merge_global_got, reallocate_got,
+ undo_symbol_twiddle): Likewise.
+ * elf64-s390.c (allocate_dynrelocs, readonly_dynrelocs): Likewise.
+ * elf64-sh64.c (sh64_elf64_discard_copies): Likewise.
+ * elf64-x86-64.c (elf_x86_64_allocate_dynrelocs,
+ elf_x86_64_readonly_dynrelocs): Likewise.
+ * elflink.c (elf_link_renumber_hash_table_dynsyms,
+ elf_link_renumber_local_hash_table_dynsyms, _bfd_elf_export_symbol,
+ _bfd_elf_link_find_version_dependencies,
+ _bfd_elf_link_assign_sym_version, _bfd_elf_adjust_dynamic_symbol,
+ _bfd_elf_link_sec_merge_syms, elf_adjust_dynstr_offsets,
+ elf_collect_hash_codes, elf_collect_gnu_hash_codes,
+ elf_renumber_gnu_hash_syms, elf_gc_sweep_symbol,
+ elf_gc_propagate_vtable_entries_used,
+ elf_gc_smash_unused_vtentry_relocs, bfd_elf_gc_mark_dynamic_ref_symbol,
+ elf_gc_allocate_got_offsets): Likewise.
+ * elfnn-ia64.c (elfNN_ia64_global_dyn_info_free,
+ elfNN_ia64_global_dyn_sym_thunk): Likewise.
+ * elfxx-mips.c (mips_elf_check_symbols, mips_elf_output_extsym,
+ mips_elf_sort_hash_table_f, allocate_dynrelocs): Likewise.
+ * elfxx-sparc.c (allocate_dynrelocs, readonly_dynrelocs): Likewise.
+ * i386linux.c (linux_tally_symbols): Likewise.
+ * m68klinux.c (linux_tally_symbols): Likewise.
+ * sparclinux.c (linux_tally_symbols): Likewise.
+ * sunos.c (sunos_scan_dynamic_symbol): Likewise.
+ * xcofflink.c (xcoff_post_gc_symbol): Likewise.
+
+ * elflink.c (elf_link_output_extsym): Make it a bfd_hash_traverse
+ function. Update all callers.
+ * aoutx.h (aout_link_write_other_symbol): Likewise.
+ * pdp11.c (aout_link_write_other_symbol): Likewise.
+ * cofflink.c (_bfd_coff_write_global_sym): Likewise.
+ * ecoff.c (ecoff_link_write_external): Likewise.
+ * xcofflink.c (xcoff_write_global_symbol): Likewise.
+ * vms-alpha.c (alpha_vms_link_output_symbol): Likewise. Handle
+ warning symbols.
+ * ecoff.c (ecoff_link_hash_traverse): Delete.
+ * coff-ppc.c (ppc_bfd_coff_final_link): Use bfd_hash_traverse for
+ _bfd_coff_write_global_sym.
+ * libcoff-in.h (_bfd_coff_write_global_sym): Update prototype.
+ * libcoff.h: Regenerate.
+
+2011-06-10 Nick Clifton <nickc@redhat.com>
+
+ * elflink.c (_bfd_elf_link_create_dynamic_sections): If the
+ backend does not provide a function for creating dynamic sections
+ then fail.
+ (bfd_elf_final_link): Issue a warning message if a dynamic section
+ has the SHT_NOTE type.
+ (bfd_elf_final_link): Do not look for dynamic strings in a section
+ that does not have the SHT_STRTAB type or the name .dynstr.
+ * elf32-arm.c (elf32_arm_finish_dynamic_sections): Fail if the got
+ section is not in the output binary.
+ * elf32-hppa.c (elf32_hppa_finish_dynamic_sections): Likewise.
+
+2011-06-09 Tristan Gingold <gingold@adacore.com>
+
+ * elfnn-ia64.c (elfNN_ia64_relax_section, elfNN_ia64_choose_gp)
+ (elfNN_ia64_relocate_section, elfNN_vms_object_p): Remove trailing
+ spaces.
+
+2011-06-09 Tristan Gingold <gingold@adacore.com>
+
+ * bfd.c (bfd_get_sign_extend_vma): Handle aixcoff.
+
+2011-06-09 Nick Clifton <nickc@redhat.com>
+
+ PR ld/12845
+ * elf.c (_bfd_elf_init_private_section_data): Add an assertion
+ that the output section has an allocated bfd_elf_section_data
+ structure.
+ * elfxx-mips.c (mips_elf_check_symbols): Do not create a stub for
+ symbols in sections that have been removed by garbage collection.
+
+2011-06-08 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf64-x86-64.c (elf_x86_64_check_relocs): Allow R_X86_64_64
+ relocations in SEC_DEBUGGING sections when building shared
+ libraries.
+
+2011-06-08 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/12851
+ * elflink.c (elf_gc_sweep): Don't check SHT_NOTE sections here.
+ (bfd_elf_gc_sections): Also check SHT_NOTE sections.
+
+2011-06-08 Tristan Gingold <gingold@adacore.com>
+
+ * makefile.vms (OBJS): Add elfxx-ia64.obj
+ Remove vax case.
+
+2011-06-08 Alan Modra <amodra@gmail.com>
+
+ * aix386-core.c, * cisco-core.c, * hpux-core.c, * osf-core.c,
+ * sco5-core.c: Init match_priority field.
+
+2011-06-08 Alan Modra <amodra@gmail.com>
+
+ * elflink.c (_bfd_elf_archive_symbol_lookup): Follow warning and
+ indirect links here.
+
+2011-06-07 Joel Brobecker <brobecker@adacore.com>
+
+ * irix-core.c (irix_core_vec): Add match_priority field.
+
+2011-06-06 Alan Modra <amodra@gmail.com>
+
+ * targets.c (bfd_target): Make ar_max_namelen an unsigned char.
+ Add match_priority.
+ * configure.in: Bump bfd version.
+ * elfcode.h (elf_object_p): Delete hacks preventing match of
+ EM_NONE and ELFOSABI_NONE targets when a better match exists.
+ * elfxx-target.h (elf_match_priority): Define and use.
+ * format.c (bfd_check_format_matches): Use target match_priority
+ to choose best of multiple matching targets. In cases with multiple
+ matches rerun _bfd_check_format if we don't choose the last match.
+ * aout-adobe.c, * aout-arm.c, * aout-target.h, * aout-tic30.c,
+ * binary.c, * bout.c, * coff-alpha.c, * coff-i386.c, * coff-i860.c,
+ * coff-i960.c, * coff-ia64.c, * coff-mips.c, * coff-or32.c,
+ * coff-ppc.c, * coff-rs6000.c, * coff-sh.c, * coff-tic30.c,
+ * coff-tic54x.c, * coff-x86_64.c, * coff64-rs6000.c, * coffcode.h,
+ * i386msdos.c, * i386os9k.c, * ieee.c, * ihex.c, * mach-o-target.c,
+ * mipsbsd.c, * mmo.c, * nlm-target.h, * oasys.c, * pdp11.c,
+ * pe-mips.c, * pef.c, * plugin.c, * ppcboot.c, * som.c, * srec.c,
+ * tekhex.c, * trad-core.c, * verilog.c, * versados.c, * vms-alpha.c,
+ * vms-lib.c, * xsym.c: Init match_priority field.
+ * configure: Regenerate.
+ * bfd-in2.h: Regenerate.
+
+2011-06-04 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/12842
+ * elfcode.h (elf_object_p): Revert the last change.
+
+2011-06-04 Alan Modra <amodra@gmail.com>
+
+ * archures.c (bfd_arch_get_compatible): If one arch is unknown,
+ return the other arch.
+ * elfcode.h (elf_object_p): Allow explicit match to generic ELF
+ target.
+
+2011-06-03 Bertram Felgenhauer <bertram.felgenhauer@gmail.com>
+
+ PR ld/12682
+ * hash.c (higher_primer_number): Add more, small, prime numbers.
+ (bfd_hash_set_default_size): Likewise.
+
+2011-06-02 Nick Clifton <nickc@redhat.com>
+
+ * coff-mcore.c: Fix spelling typo.
+ * coff-stgo32.c: Likewise.
+ * elf32-arm.c: Likewise.
+ * elf32-avr.c: Likewise.
+ * elf-m68hc1x.c: Likewise.
+ * elf32-mcore.c: Likewise.
+ * elf32-mep.c: Likewise.
+ * elf32-mt.c: Likewise.
+ * elf32-ppc.c: Likewise.
+ * elf32-xtensa.c: Likewise.
+ * elf64-ppc.c: Likewise.
+ * elfxx-mips.c: Likewise.
+ * netbsd.h: Likewise.
+ * nlmcode.h: Likewise.
+ * vms-alpha.c: Likewise.
+ * po/bfd.pot: Regenerate.
+ * po/SRC-POTFILES.in: Regenerate.
+
+2011-06-01 DJ Delorie <dj@redhat.com>
+
+ * config.bfd: Add bfd_elf32_rx_be_ns_vec.
+ * target.c: Likewise.
+ * configure.in: Likewise.
+ * configure.in: Regenerate.
+ * elf32-rx.c: Add elf32-rx-be-ns target.
+ (rx_elf_object_p): Never allow the be-ns target by default,
+ only allow it if the user requests it.
+
+2011-06-01 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf32-i386.c (elf_i386_size_dynamic_sections): Properly warn
+ relocation in readonly section in a shared object.
+ * elf64-x86-64.c (elf_x86_64_size_dynamic_sections): Likewise.
+
+2011-05-31 Nick Clifton <nickc@redhat.com>
+
+ * archive.c (adjust_relative_path): Fix comment to prevent it
+ corrupting the auto-generated bfd.h.
+
+2011-05-31 Paul Brook <paul@codesourcery.com>
+
+ * elf32-arm.c (elf32_arm_final_link_relocate): Only do bl conversion
+ for known functions.
+ (elf32_arm_swap_symbol_in): Only set ST_BRANCH_TO_ARM for function
+ symbols.
+
+2011-05-31 Paul Brook <paul@codesourcery.com>
+
+ * elf32-arm.c (arm_stub_is_thumb): Add
+ arm_stub_long_branch_v4t_thumb_tls_pic.
+ (elf32_arm_final_link_relocate): TLS stubs are always ARM.
+ Handle Thumb stubs.
+
+2011-05-27 Nick Clifton <nickc@redhat.com>
+
+ PR binutils/12710
+ * archive.c (_bfd_get_elt_at_filepos): Set correct error value if
+ unable to read a file pointed to by an entry in a thin archive.
+ (adjust_relative_path): Use lrealpath to canonicalize paths.
+ Handle the case where the reference path is above the current
+ path in the directory tree.
+
+2011-05-26 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/12809
+ * elf64-x86-64.c (elf_x86_64_relocate_section): Handle
+ R_X86_64_TPOFF64 in executable.
+
+2011-05-26 Alan Modra <amodra@gmail.com>
+
+ * elf-bfd.h (SYMBOL_REFERENCES_LOCAL): Remove most of comment.
+ * elflink.c (_bfd_elf_symbol_refs_local_p): Expand
+ local_protected comment.
+
+2011-05-25 Tristan Gingold <gingold@adacore.com>
+
+ * configure.in (bfd_elf32_ia64_big_vec, bfd_elf32_ia64_hpux_big_vec)
+ (bfd_elf64_ia64_big_vec, bfd_elf64_ia64_hpux_big_vec)
+ (bfd_elf64_ia64_little_vec, bfd_elf64_ia64_vms_vec): Add elfxx-ia64.lo
+ * Makefile.am (BFD64_BACKENDS): Add elfxx-ia64.lo
+ (BFD64_BACKENDS_CFILES): Add elfxx-ia64.c
+ (elf32-ia64.c): Created from elfnn-ia64.c
+ (elf64-ia64.c): Likewise.
+ * elfxx-ia64.h: New file.
+ * elfxx-ia64.c: Split with elfnn-ia64.c. Keep only the following
+ functions.Includes elfxx-ia64.h.
+ (elfNN_ia64_reloc): Renames to ia64_elf_reloc. Adjust error message.
+ (IA64_HOWTO): Adjust.
+ (lookup_howto): Renames to ia64_elf_lookup_howto. Make it public.
+ (elfNN_ia64_reloc_type_lookup): Renames to
+ ia64_elf_reloc_type_lookup. Make it public. Adjust calls.
+ (elfNN_ia64_reloc_name_lookup): Renames to
+ ia64_elf_reloc_name_lookup. Make it public.
+ (elfNN_ia64_relax_br): Renames to ia64_elf_relax_br. Make it public.
+ (elfNN_ia64_relax_brl): Renames to ia64_elf_relax_brl. Make it
+ public.
+ (elfNN_ia64_relax_ldxmov): Renames to ia64_elf_relax_ldxmov.
+ Move it and make it public. Move prototype to elfxx-ia64.h
+ (elfNN_ia64_install_value): Renames to ia64_elf_install_value.
+ Move prototype to elfxx-ia64.h
+ * elfnn-ia64.c: New file, split from elfxx-ia64.c.
+ (elfNN_ia64_info_to_howto): Adjust calls.
+ (elfNN_ia64_relax_section): Adjust calls.
+ (count_dyn_reloc): Fix typo.
+ (elfNN_ia64_relocate_section): Adjust calls.
+ (elfNN_ia64_finish_dynamic_symbol): Likewise.
+ (bfd_elfNN_bfd_reloc_type_lookup)
+ (bfd_elfNN_bfd_reloc_name_lookup): Adjust macros.
+ * configure: Regenerate.
+ * Makefile.in: Regenerate.
+
+2011-05-23 DJ Delorie <dj@redhat.com>
+
+ * elf32-rx.c (rx_elf_object_p): When reading an RX object in, undo
+ the vma/lma swapping done in elf32_rx_modify_program_headers.
+
+2011-05-23 Nick Clifton <nickc@redhat.com>
+
+ * elf-m10300.c (mn10300_elf_mkobject): New function.
+ (bfd_elf32_mkobject): Define.
+
+2011-05-23 Alan Modra <amodra@gmail.com>
+
+ * elf-bfd.h: Comment typo fix.
+ * elf32-ppc.c (struct ppc_elf_dyn_relocs): Delete. Replace with
+ struct elf_dyn_relocs throughout.
+ * elf64-ppc.c (struct ppc_dyn_relocs): Likewise.
+
+2011-05-23 Alan Modra <amodra@gmail.com>
+
+ * elf32-frv.c: Use info->callbacks->einfo throughout file in linker
+ functions rather than warning callback or _bfd_error_handler.
+ * elf32-ppc.c: Likewise.
+ * elf64-ppc.c: Likewise.
+ * elf32-ppc.c (ppc_elf_tls_optimize): Use %H in __tls_get_addr lost
+ arg error.
+ * elf64-ppc.c (ppc64_elf_tls_optimize): Likewise.
+
+2011-05-23 Alan Modra <amodra@gmail.com>
+
+ PR 12763
+ * elf.c (assign_file_positions_for_load_sections): Set sh_offset for
+ .tbss, and page align same for all SHT_NOBITS sections.
+
+2011-05-21 Alan Modra <amodra@gmail.com>
+
+ PR 12763
+ * elf.c (_bfd_elf_make_section_from_shdr): Set up TLS section LMAs
+ from PT_TLS header.
+ (_bfd_elf_map_sections_to_segments): Don't create a final PT_LOAD
+ segment if just for .tbss.
+ (assign_file_positions_for_load_sections): Don't report "can't
+ allocate in segment" errors for .tbss.
+ (assign_file_positions_for_non_load_sections): Don't set p_filesz
+ from SHT_NOBITS section filepos.
+
+2011-05-20 Bernd Schmidt <bernds@codesourcery.com>
+
+ * elf32-tic6x.c (elf32_tic6x_howto_table): Add entries for
+ R_C6000_PCR_H16 and R_C6000_PCR_L16.
+ (elf32_tic6x_relocate_section): Handle them.
+
+2011-05-18 Nick Clifton <nickc@redhat.com>
+
+ PR ld/12761
+ * elflink.c (elf_link_add_object_symbols): Process .gnu.warning
+ sections when building shared libraries.
+
+2011-05-18 Rafał Krypa <r.krypa@samsung.com>
+
+ PR ld/12778
+ * elf32-arm.c (elf32_arm_gc_sweep_hook): Use the computed dynamic
+ reloc pointer.
+
+2011-05-18 Tristan Gingold <gingold@adacore.com>
+
+ * xcofflink.c (xcoff_link_add_symbols): Handle C_DWARF symbols.
+ (xcoff_sweep): Always keep dwarf sections.
+ (xcoff_link_input_bfd): Handle dwarf symbols and sections.
+
+2011-05-18 Tristan Gingold <gingold@adacore.com>
+
+ * libxcoff.h (struct xcoff_dwsect_name): New type.
+ (XCOFF_DWSECT_NBR_NAMES): New macro.
+ (xcoff_dwsect_names): Declare.
+ * coffcode.h (sec_to_styp_flags): Handle xcoff dwarf sections.
+ (styp_to_sec_flags): Ditto.
+ (coff_new_section_hook): Ditto.
+ (coff_slurp_symbol_table): Handle C_DWARF and C_INFO.
+ * coff-rs6000.c (xcoff_dwsect_name): New variable.
+
+2011-05-17 Tomohiro Kashiwada <kikairoya@gmail.com>
+
+ PR ld/12759
+ * elf32-rx.c (ignore_lma): New variable.
+ (bfd_elf32_rx_set_target_flags): Add ignore_lma parameter.
+ (rx_modify_program_headers): Only copy the LMA into the VMA if
+ ignore_lma is true.
+
+2011-05-17 Alan Modra <amodra@gmail.com>
+
+ PR ld/12760
+ * coff-aux.c (coff_m68k_aux_link_add_one_symbol): Adjust "notice" call.
+ * elflink.c (elf_link_add_object_symbols): Likewise.
+ * linker.c (_bfd_generic_link_add_one_symbol): Likewise.
+
+2011-05-16 Alan Modra <amodra@gmail.com>
+
+ * linker.c (_bfd_generic_link_add_one_symbol): Don't init u.undef.weak.
+
+2011-05-15 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * elfxx-mips.c (_bfd_mips_elf_check_relocs): Record both local and
+ global GOT entries for GOT_PAGE relocations against global symbols.
+
+2011-05-13 Bernd Schmidt <bernds@codesourcery.com>
+
+ * config.bfd (tic6x-*-elf, tic6x-*-uclinux): New.
+ (tic6x-*-*): Replaced by these.
+ * elf32-tic6x.c (elf32_tic6x_set_osabi): New static function.
+ (elf32_tic6x_check_relocs): Create dynamic sections if -shared.
+ (elf_backend_relocs_compatible, elf_backend_post_process_headers):
+ Define.
+ (elf32_bed, TARGET_LITTLE_SYM, TARGET_LITTLE_NAME, TARGET_BIG_SYM,
+ TARGET_BIG_NAME, ELF_OSABI): Redefine twice, and include
+ "elf32-target.h" two more times.
+ * configure.in: Handle bfd_elf32_tic6x_linux_be_vec,
+ bfd_elf32_tic6x_linux_le_vec, bfd_elf32_tic6x_elf_be_vec and
+ bfd_elf32_tic6x_elf_le_vec.
+ * configure: Regenerate.
+
+2011-05-13 Jan Beulich <jbeulich@novell.com>
+
+ * config.bfd: Add targets x86_64-*-pe and x86_64-*-pep.
+
+2011-05-12 Jan Kratochvil <jan.kratochvil@redhat.com>
+
+ * config.in: Regenerated.
+ * configure: Regenerated.
+ * configure.in: New tests for HAVE_PRPSINFO_T_PR_PID,
+ HAVE_PRPSINFO32_T_PR_PID, HAVE_PSINFO_T_PR_PID and
+ HAVE_PSINFO32_T_PR_PID.
+ * elf.c (elfcore_grok_psinfo): Protect reading psinfo.pr_pid by
+ HAVE_PRPSINFO_T_PR_PID, HAVE_PRPSINFO32_T_PR_PID, HAVE_PSINFO_T_PR_PID
+ and HAVE_PSINFO32_T_PR_PID.
+ * hosts/x86-64linux.h (HAVE_PRPSINFO32_T_PR_PID): New redefinition.
+
+2011-05-10 Jan Kratochvil <jan.kratochvil@redhat.com>
+
+ * elf.c (elfcore_grok_psinfo): Initialize CORE_PID for both native and
+ 32bit psinfo.
+ * elf32-ppc.c (ppc_elf_grok_psinfo): Initialize core_pid.
+ * elf64-ppc.c (ppc64_elf_grok_psinfo): Likewise.
+
+2011-05-09 Paul Brook <paul@codesourcery.com>
+
+ * bfd-in.h (elf32_tic6x_fix_exidx_coverage): Add prototype.
+ * bfd-in2.h: Regenerate.
+ * elf32-tic6x.c: Include limits.h.
+ (tic6x_unwind_edit_type, tic6x_unwind_table_edit,
+ _tic6x_elf_section_data): New.
+ (elf32_tic6x_section_data): Define.
+ (elf32_tic6x_new_section_hook): Allocate target specific data.
+ (elf32_tic6x_add_unwind_table_edit): New function.
+ (get_tic6x_elf_section_data, elf32_tic6x_adjust_exidx_size,
+ elf32_tic6x_insert_cantunwind_after, elf32_tic6x_add_low31,
+ elf32_tic6x_copy_exidx_entry): New functions.
+ (elf_backend_write_section): Define.
+
+2011-05-09 Paul Brook <paul@codesourcery.com>
+
+ * elf32-tic6x.c (is_tic6x_elf_unwind_section_name,
+ elf32_tic6x_fake_sections): New functions.
+ (elf_backend_fake_sections): Define.
+
+2011-05-09 Paul Brook <paul@codesourcery.com>
+
+ * elf32-tic6x.c (elf32_tic6x_gc_mark_extra_sections): New function.
+ (elf_backend_gc_mark_extra_sections): Define.
+
+2011-05-07 Dave Korn <dave.korn.cygwin@gmail.com>
+
+ PR ld/12365
+ * cofflink.c (bfd_coff_link_input_bfd): Check for and warn about
+ references to symbols defined in discarded sections.
+
+2011-05-07 Dave Korn <dave.korn.cygwin@gmail.com>
+
+ PR ld/12365
+ * coffgen.c (coff_write_symbol): Assume input section is its own
+ output section if output_section member not set.
+ (coff_write_alien_symbol): Likewise.
+
+2011-05-07 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/12730
+ * elf.c (_bfd_elf_section_offset): Check SEC_ELF_REVERSE_COPY.
+
+ * elflink.c (elf_link_input_bfd): Reverse copy .ctors/.dtors
+ sections if needed.
+
+ * section.c (SEC_ELF_REVERSE_COPY): New.
+ * bfd-in2.h: Regenerated.
+
+2011-05-07 Anders Kaseorg <andersk@ksplice.com>
+
+ PR 12739
+ * libbfd.c (bfd_get_8, bfd_get_signed_8): Use const cast.
+ * bfd-in2.h: Regenerate.
+
+2011-05-06 Tristan Gingold <gingold@adacore.com>
+
+ * vms-alpha.c (evax_section_flags): Remove SEC_IN_MEMORY.
+ (_bfd_vms_slurp_egsd): Rename old_flags to vms_flags. Handle
+ any code section. Add comments.
+ (alpha_vms_object_p): Use void * instead of PTR.
+ (alpha_vms_create_eisd_for_section): Fix test for setting DZRO.
+ (build_module_list): Guard against no DST section. Add comments.
+ (alpha_vms_link_output_symbol): Discard undefined symbols.
+ (alpha_vms_get_section_contents): Simply memcpy if the section was
+ already loaded. Fix typo.
+ (vms_new_section_hook): Use void * instead of PTR.
+ (vms_alpha_vec): Ditto.
+
+2011-05-06 Richard Sandiford <richard.sandiford@linaro.org>
+
+ * elf32-arm.c (cortex_a8_erratum_scan): If the stub is a Thumb
+ branch to a PLT entry, redirect it to the PLT's Thumb entry point.
+
+2011-05-05 Bernd Schmidt <bernds@codesourcery.com>
+
+ * elf32-tic6x.c (elf32_tic6x_final_link): New function.
+ (elf32_tic6x_merge_attributes): Do not warn for PID or PIC
+ mismatch. Choose the lower of the two values.
+ (bfd_elf32_bfd_final_link): New macro.
+
+2011-04-28 Tristan Gingold <gingold@adacore.com>
+
+ * coff-rs6000.c (_bfd_xcoff_swap_aux_in): Adjust for x_file.
+ (bfd_xcoff_swap_aux_out): Ditto.
+ * coff64-rs6000.c (_bfd_xcoff64_swap_aux_in): Ditto.
+ (bfd_xcoff64_swap_aux_out): Ditto.
+
+2011-05-04 Alan Modra <amodra@gmail.com>
+
+ PR ld/12727
+ * elf64-ppc.c (ppc_build_one_stub <ppc_sub_plt_call>): Clear
+ was_undefined on dot-symbols.
+
+2011-05-03 Paul Brook <paul@codesourcery.com>
+
+
+ * elf32-tic6x.c (elf32_tic6x_howto_table,
+ elf32_tic6x_howto_table_rel, (elf32_tic6x_gc_sweep_hook,
+ elf32_tic6x_relocate_section, elf32_tic6x_check_relocs):
+ Add R_C6000_EHTYPE.
+
+2011-05-01 Alan Modra <amodra@gmail.com>
+
+ PR ld/12718
+ * elf32-i386.c (elf_i386_check_relocs): Ensure dynobj set before
+ creating ifunc sections.
+ * elf64-x86-64.c (elf_x86_64_check_relocs): Likewise.
+
+2011-04-30 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf64-x86-64.c (elf_x86_64_merge_symbol): Correct parameter
+ names.
+
+2011-04-28 Tom Tromey <tromey@redhat.com>
+
+ * bfdio.c (memory_bstat): Pass correct size to memset.
+
+2011-04-28 Mike Frysinger <vapier@gentoo.org>
+
+ * dwarf2.c (dwarf_debug_sections): Mark const.
+ * elf.c (special_sections): Likewise.
+ * libbfd-in.h (dwarf_debug_sections): Likewise.
+ * libbfd.h: Regenerate.
+
+2011-04-26 Kai Tietz <ktietz@redhat.com>
+
+ * coffcode.h (sec_to_styp_flags): Allow linkonce for
+ debugging sections.
+
+2011-04-26 Tristan Gingold <gingold@adacore.com>
+
+ * coff64-rs6000.c: Convert to ISO-C. Remove PARAMS and PTR macros.
+
+2011-04-24 Alan Modra <amodra@gmail.com>
+
+ PR ld/12365
+ PR ld/12696
+ * coff-aux.c (coff_m68k_aux_link_add_one_symbol): Update "notice" call.
+ * linker.c (_bfd_link_hash_newfunc): Clear bitfields.
+ (_bfd_generic_link_add_one_symbol): Update "notice" call.
+ * elflink.c (_bfd_elf_merge_symbol): Don't skip weak redefs when
+ it is a redef of an IR symbol in a real BFD.
+
+2011-04-22 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf32-i386.c (elf_i386_readonly_dynrelocs): Warn relocation
+ in readonly section in a shared object.
+ (elf_i386_size_dynamic_sections): Likewise.
+ * elf64-x86-64.c (elf_x86_64_readonly_dynrelocs): Likewise.
+ (elf_x86_64_size_dynamic_sections): Likewise.
+
+2011-04-21 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/12694
+ * elf32-i386.c (elf_i386_readonly_dynrelocs): Skip local IFUNC
+ symbols.
+ * elf64-x86-64.c (elf_x86_64_readonly_dynrelocs): Likewise.
+
+2011-04-21 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf32-i386.c (elf_i386_finish_dynamic_symbol): Return false
+ on dynamic symbol error.
+ * elf64-x86-64.c (elf_x86_64_finish_dynamic_symbol): Likewise.
+
+2011-04-20 Tristan Gingold <gingold@adacore.com>
+
+ * config.bfd (alpha*-*-*vms*, ia64*-*-*vms*): Define targ_selvecs.
+
+2011-04-20 Alan Modra <amodra@gmail.com>
+
+ * hash.c (bfd_default_hash_table_size): Make it an unsigned long.
+ (bfd_hash_table_init_n): Overflow checking.
+ (bfd_hash_set_default_size): Return current size. Take unsigned long
+ arg. Add 65537 to hash_size primes.
+ * bfd-in.h (bfd_hash_set_default_size): Update prototype.
+ * bfd-in2.h: Regenerate.
+
+2011-04-20 Jan Kratochvil <jan.kratochvil@redhat.com>
+
+ * elf-bfd.h (RELOC_AGAINST_DISCARDED_SECTION): Fix +1 overrun of
+ memmove elements.
+
+2011-04-20 Alan Modra <amodra@gmail.com>
+
+ * libbfd.c (bfd_log2): Do return rounded up value.
+ * elflink.c (bfd_elf_size_dynsym_hash_dynstr): Replace bfd_log2
+ call with expanded old round down version of the function.
+
+ * archive.c (_bfd_get_elt_at_filepos): Don't release n_nfd.
+ * elflink.c (elf_link_add_object_symbols): Delete redundant code.
+
+2011-04-20 Alan Modra <amodra@gmail.com>
+
+ PR ld/12365
+ * elfcode.h (elf_slurp_symbol_table): Put common plugin IR symbols
+ in their own common section.
+ * elflink.c (elf_link_add_object_symbols): Likewise.
+ * linker.c (generic_link_check_archive_element): Don't lose flags
+ if common section is pre-existing.
+ (_bfd_generic_link_add_one_symbol): Likewise.
+
+2011-04-20 Alan Modra <amodra@gmail.com>
+
+ PR ld/12365
+ * elflink.c (_bfd_elf_merge_symbol): Update multiple_common calls.
+ * linker.c (_bfd_generic_link_add_one_symbol): Likewise. Call
+ multiple_definition regardless of allow_multiple_definition.
+ * simple.c (simple_dummy_multiple_definition): Update.
+ * xcofflink.c (xcoff_link_add_symbols): Update multiple_definition
+ calls.
+
+2011-04-18 Tristan Gingold <gingold@adacore.com>
+
+ * coff-rs6000.c: Convert to ISO-C. Remove PARAMS macro.
+
+2011-04-18 Alan Modra <amodra@gmail.com>
+
+ PR ld/12365
+ PR ld/12672
+ * bfd.c (BFD_PLUGIN): Define.
+ (BFD_FLAGS_SAVED, BFD_FLAGS_FOR_BFD_USE_MASK): Add BFD_PLUGIN.
+ * bfd-in2.h: Regenerate.
+ * elflink.c (elf_link_output_extsym): Strip undefined plugin syms.
+ * opncls.c (bfd_make_readable): Don't lose original bfd flags.
+
+2011-04-17 Jan Kratochvil <jan.kratochvil@redhat.com>
+
+ * elf64-ppc.c (ppc64_elf_get_synthetic_symtab): Do not check for
+ SEC_LOAD.
+
+2011-04-15 Sergio Durigan Junior <sergiodj@redhat.com>
+
+ * elf-bfd.h (struct sdt_note): New struct.
+ (struct elf_obj_tdata) <sdt_note_head>: New field.
+ * elf.c (elfobj_grok_stapsdt_note_1): New function.
+ (elfobj_grok_stapsdt_note): Likewise.
+ (elf_parse_notes): Added code to treat SystemTap note
+ sections.
+
+2011-04-12 Richard Henderson <rth@redhat.com>
+
+ * elf64-alpha.c (elf64_alpha_size_dynamic_sections): Do not
+ exclude empty .got sections.
+
+2011-04-11 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf32-i386.c (elf_i386_reloc_type_lookup): Fix the out of bound
+ array access for BFD_RELOC_386_IRELATIVE.
+
+2011-04-11 Bernd Schmidt <bernds@codesourcery.com>
+
+ * elf32-tic6x.c (elf32_tic6x_check_relocs): Initialize pc_count field.
+
+2011-04-11 Mark Wielaard <mjw@redhat.com>
+
+ PR 10549
+ * elf-bfd.h (has_ifunc_symbols): Renamed to has_gnu_symbols.
+ (has_gnu_symbols): Renamed from has_ifunc_symbols.
+ * elf.c (_bfd_elf_set_osabi): Use new has_gnu_symbols name.
+ * elf32-arm.c (elf32_arm_add_symbol_hook): Set has_gnu_symbols
+ also if STB_GNU_UNIQUE symbol binding was seen.
+ * elf32-i386.c (elf_i386_add_symbol_hook): Likewise.
+ * elf32-ppc.c (ppc_elf_add_symbol_hook): Likewise.
+ * elf32-sparc.c (elf32_sparc_add_symbol_hook): Likewise.
+ * elf64-ppc.c (ppc64_elf_add_symbol_hook): Likewise.
+ * elf64-sparc.c (elf64_sparc_add_symbol_hook): Likewise.
+ * elf64-x86-64.c (elf_x86_64_add_symbol_hook): Likewise.
+
+2011-04-11 Alan Modra <amodra@gmail.com>
+
+ * bfd-in.h (bfd_get_section_limit): Don't use rawsize with output
+ sections.
+ * libbfd.c (_bfd_generic_get_section_contents): Likewise.
+ (_bfd_generic_get_section_contents_in_window): Likewise.
+ * section.c (bfd_get_section_contents): Likewise.
+ * compress.c (bfd_get_full_section_contents): Likewise.
+ * elf32-rx.c (rx_final_link): Ignore rawsize.
+ * elf32-microblaze.c (microblaze_elf_relocate_section): Use correct
+ bfd with bfd_get_section_limit.
+ * elfxx-ia64.c (elfNN_ia64_choose_gp): Add "final" parameter. Use
+ os->size during final link. Update callers.
+ * bfd-in2.h: Regenerate.
+
+2011-04-10 Richard Sandiford <rdsandiford@googlemail.com>
+
+ PR ld/12637
+ * elfxx-mips.c (mips_elf_merge_got_with): Use arg->global_count
+ as the number of global entries when merging with the primary GOT.
+
+2011-04-09 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf32-i386.c: Update copyright year.
+ * elf64-x86-64.c: Likewise.
+
+2011-04-09 Kai Tietz <ktietz@redhat.com>
+
+ * peXXigen.c (_bfd_XXi_final_link_postscripte): Sort pdata in temporary
+ buffer and use rawsize for sorting.
+ * coffcode.h (coff_compute_section_file_positions): Set rawsize
+ before doing alignment.
+
+2011-04-09 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf32-i386.c (elf_i386_relocate_section): Return relocation
+ error on unsupported relocation.
+ * elf64-x86-64.c (elf_x86_64_relocate_section): Likewise.
+
+2011-04-09 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR binutils/12657
+ * hosts/x86-64linux.h (elf_prstatus32): Replace __pid_t with
+ pid_t.
+
+2011-04-08 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/12654
+ * elf32-i386.c (elf_i386_relocate_section): Check !executable
+ instead of shared for R_386_TLS_LDO_32.
+
+2011-04-08 Tristan Gingold <gingold@adacore.com>
+
+ * Makefile.am (SOURCE_HFILES): Remove xcoff-target.h
+ * coff-pmac: Remove
+ * xcoff-target.h: Remove
+ * Makefile.in: Regenerate.
+
+2011-04-07 Cary Coutant <ccoutant@google.com>
+
+ * dwarf2.c (scan_unit_for_symbols): Check for DW_AT_specification.
+
+2011-04-07 Paul Brook <paul@codesourcery.com>
+
+ * elf32-tic6x.c (elf32_tic6x_howto_table): R_C6000_PREL31 is
+ pc-relative.
+ (elf32_tic6x_howto_table_rel): Ditto.
+ (elf32_tic6x_relocate_section): Implement R_C6000_PREL31.
+ (elf32_tic6x_check_relocs): Ditto.
+
+2011-04-06 Joseph Myers <joseph@codesourcery.com>
+
+ * config.bfd (thumb-*-oabi): Don't handle in list of obsolete
+ targets.
+ (strongarm*, thumb*, xscale*): Remove architectures.
+ (strongarm-*-kaos*, thumb-*-coff, thumb-*-elf, thumb-epoc-pe*,
+ thumb-*-pe*, strongarm-*-elf, strongarm-*-coff, xscale-*-elf,
+ xscale-*-coff): Remove targets.
+
+2011-04-01 Tristan Gingold <gingold@adacore.com>
+
+ * elfxx-ia64.c: include bfd_stdint.h
+
+2011-03-31 Jan Kratochvil <jan.kratochvil@redhat.com>
+
+ * elf32-tic6x.c (elf32_tic6x_relocate_section): Remove unused variable
+ dynobj and its initialization.
+
+2011-03-31 Tristan Gingold <gingold@adacore.com>
+
+ * makefile.vms (DEFS): Add HAVE_bfd_elf64_ia64_vms_vec.
+ * configure.com: Set BFD_HOST_64BIT_LONG_LONG and
+ BFD_HOST_LONG_LONG to 1.
+
+2011-03-31 Tristan Gingold <gingold@adacore.com>
+
+ * vms-alpha.c (vms_get_remaining_object_record): Fix dec-c warning.
+ (_bfd_vms_write_etir): Ditto.
+ (_bfd_vms_slurp_etir): Avoid to use intptr_t
+ * configure.com: Generate bfd_stdint.h
+
+2011-03-31 Bernd Schmidt <bernds@codesourcery.com>
+
+ * elf32-tic6x.h (struct elf32_tic6x_params): New.
+ (elf32_tic6x_setup): Declare.
+ * elf32-tic6x.c: Include <limits.h>.
+ (ELF_DYNAMIC_LINKER, DEFAULT_STACK_SIZE, PLT_ENTRY_SIZE): Define.
+ (struct elf32_tic6x_link_hash_table, struct elf32_link_hash_entry):
+ New structures.
+ (elf32_tic6x_link_hash_table, is_tic6x_elf): New macros.
+ (tic6x_elf_scom_section, tic6x_elf_scom_symbol,
+ tic6x_elf_scom_symbol_ptr): New static variables.
+ (elf32_tic6x_howto_table, elf32_tic6x_howto_table_rel,
+ elf32_tic6x_reloc_map): Add R_C6000_JUMP_SLOT, R_C6000_EHTYPE,
+ R_C6000_PCR_H16 and R_C6000_PCR_L16.
+ (elf32_tic6x_link_hash_newfunc, elf32_tic6x_link_hash_table_create,
+ elf32_tic6x_link_hash_table_free, elf32_tic6x_setup,
+ elf32_tic6x_using_dsbt, elf32_tic6x_install_rela,
+ elf32_tic6x_create_dynamic_sections, elf32_tic6x_make_got_dynreloc,
+ elf32_tic6x_finish_dynamic_symbol, elf32_tic6x_gc_sweep_hook,
+ elf32_tic6x_adjust_dynamic_symbol): New static functions.
+ (elf32_tic6x_relocate_section): For R_C6000_PCR_S21, convert branches
+ to weak symbols as required by the ABI.
+ Handle GOT and DSBT_INDEX relocs, and copy relocs to the output file
+ as needed when generating DSBT output.
+ (elf32_tic6x_check_relocs, elf32_tic6x_add_symbol_hook,
+ elf32_tic6x_symbol_processing, elf32_tic6x_section_from_bfd_section,
+ elf32_tic6x_allocate_dynrelocs, elf32_tic6x_size_dynamic_sections,
+ elf32_tic6x_always_size_sections, elf32_tic6x_modify_program_headers,
+ elf32_tic6x_finish_dynamic_sections, elf32_tic6x_plt_sym_val,
+ elf32_tic6x_copy_private_data, elf32_tic6x_link_omit_section_dynsym):
+ New static functions.
+ (ELF_MAXPAGESIZE): Define to 0x1000.
+ (bfd_elf32_bfd_copy_private_bfd_data,
+ bfd_elf32_bfd_link_hash_table_create,
+ bfd_elf32_bfd_link_hash_table_free, elf_backend_can_refcount,
+ elf_backend_want_got_plt, elf_backend_want_dynbss,
+ elf_backend_plt_readonly, elf_backend_got_header_size,
+ elf_backend_gc_sweep_hook, elf_backend_modify_program_headers,
+ elf_backend_create_dynamic_sections, elf_backend_adjust_dynamic_symbol,
+ elf_backend_check_relocs, elf_backend_add_symbol_hook,
+ elf_backend_symbol_processing, elf_backend_link_output_symbol_hook,
+ elf_backend_section_from_bfd_section,
+ elf_backend_finish_dynamic_symbol, elf_backend_always_size_sections,
+ elf32_tic6x_size_dynamic_sections, elf_backend_finish_dynamic_sections,
+ elf_backend_omit_section_dynsym, elf_backend_plt_sym_val): Define.
+
+ * bfd/reloc.c (BFD_RELOC_C6000_JUMP_SLOT, BFD_RELOC_C6000_EHTYPE,
+ BFD_RELOC_C6000_PCR_H16, BFD_RELOC_C6000_PCR_S16): Add.
+ * bfd/bfd-in2.h: Regenerate.
+ * bfd/libbfd.h: Regenerate.
+ * config.bfd: Accept tic6x-*-* instead of tic6x-*-elf.
+
+2011-03-31 Tristan Gingold <gingold@adacore.com>
+
+ * coffcode.h (coff_slurp_symbol_table): Silently discard C_NULL
+ entry on xcoff when value is C_NULL_VALUE.
+
+2011-03-31 Tristan Gingold <gingold@adacore.com>
+
+ * libcoff-in.h (exec_hdr): Remove.
+ * libcoff.h: Regenerate.
+
+2011-03-30 Nick Clifton <nickc@redhat.com>
+
+ * po/da.po: Updated Danish translation.
+
+2011-03-29 Richard Henderson <rth@redhat.com>
+
+ * elf64-alpha.c (elf64_alpha_gc_mark_hook): New.
+ (elf64_alpha_gc_sweep_hook): New.
+ (elf_backend_gc_mark_hook, elf_backend_gc_sweep_hook): New.
+ (elf_backend_can_gc_sections): New.
+
+2011-03-26 John Marino <binutils@marino.st>
+
+ * config.bfd: Add x86_64-*-dragonfly*, fix i386-*-dragonfly*.
+ * configure.in: Delete unused bfd_elf32_i386_dragonfly_vec.
+ * configure: Regenerate.
+
+2011-03-25 Michael Snyder <msnyder@vmware.com>
+
+ * coffcode.h (coff_set_alignment_hook): Check return of bfd_seek.
+
+2011-03-25 Tristan Gingold <gingold@adacore.com>
+
+ * vms-alpha.c (_bfd_vms_find_nearest_dst_line): Allow the use
+ of find_nearest_line on object files.
+
+2011-03-25 Tristan Gingold <gingold@adacore.com>
+
+ * vms-alpha.c (evax_section_flags): Make $CODE$ section read-only.
+ Minor reordering.
+ (alpha_vms_create_eisd_for_section): Make code sections read-only.
+
+2011-03-24 Alan Modra <amodra@gmail.com>
+
+ * elf32-ppc.c (ppc_elf_tls_optimize): Catch more cases where
+ old-style __tls_get_addr calls without marker relocs don't match
+ their arg setup insn one for one. If such mismatches are found
+ report the reloc and don't do any tls optimization.
+ * elf64-ppc.c (ppc64_elf_tls_optimize): Likewise.
+
+2011-03-22 Eric B. Weddington <eric.weddington@atmel.com>
+
+ * bfd-in2.h: Regenerate.
+
+2011-03-22 Eric B. Weddington <eric.weddington@atmel.com>
+
+ * archures.c: Add AVR XMEGA architecture information.
+ * cpu-avr.c (arch_info_struct): Likewise.
+ * elf32-avr.c (bfd_elf_avr_final_write_processing): Likewise.
+ (elf32_avr_object_p): Likewise.
+
+2011-03-14 Richard Sandiford <richard.sandiford@linaro.org>
+
+ * reloc.c (BFD_RELOC_ARM_IRELATIVE): New relocation.
+ * bfd-in2.h: Regenerate.
+ * elf32-arm.c (elf32_arm_howto_table_2): Rename existing definition
+ to elf32_arm_howto_table_3 and replace with a single R_ARM_IRELATIVE
+ entry.
+ (elf32_arm_howto_from_type): Update accordingly.
+ (elf32_arm_reloc_map): Map BFD_RELOC_ARM_IRELATIVE to R_ARM_IRELATIVE.
+ (elf32_arm_reloc_name_lookup): Handle elf32_arm_howto_table_3.
+ (arm_plt_info): New structure, split out from elf32_arm_link_hash_entry
+ with an extra noncall_refcount field.
+ (arm_local_iplt_info): New structure.
+ (elf_arm_obj_tdata): Add local_iplt.
+ (elf32_arm_local_iplt): New accessor macro.
+ (elf32_arm_link_hash_entry): Replace plt_thumb_refcount,
+ plt_maybe_thumb_refcount and plt_got_offset with an arm_plt_info.
+ Change tls_type to a bitfield and add is_iplt.
+ (elf32_arm_link_hash_newfunc): Update accordingly.
+ (elf32_arm_allocate_local_sym_info): New function.
+ (elf32_arm_create_local_iplt): Likewise.
+ (elf32_arm_get_plt_info): Likewise.
+ (elf32_arm_plt_needs_thumb_stub_p): Likewise.
+ (elf32_arm_get_local_dynreloc_list): Likewise.
+ (create_ifunc_sections): Likewise.
+ (elf32_arm_copy_indirect_symbol): Update after the changes to
+ elf32_arm_link_hash_entry. Assert the is_iplt has not yet been set.
+ (arm_type_of_stub): Add an st_type argument. Use elf32_arm_get_plt_info
+ to get PLT information. Assert that all STT_GNU_IFUNC references
+ are turned into PLT references.
+ (arm_build_one_stub): Pass the symbol type to
+ elf32_arm_final_link_relocate.
+ (elf32_arm_size_stubs): Pass the symbol type to arm_type_of_stub.
+ (elf32_arm_allocate_irelocs): New function.
+ (elf32_arm_add_dynreloc): In static objects, use .rel.iplt for
+ all R_ARM_IRELATIVE.
+ (elf32_arm_allocate_plt_entry): New function.
+ (elf32_arm_populate_plt_entry): Likewise.
+ (elf32_arm_final_link_relocate): Add an st_type parameter.
+ Set srelgot to null for static objects. Use separate variables
+ to record which st_value and st_type should be used when generating
+ a dynamic relocation. Use elf32_arm_get_plt_info to find the
+ symbol's PLT information, setting has_iplt_entry, splt,
+ plt_offset and gotplt_offset accordingly. Check whether
+ STT_GNU_IFUNC symbols should resolve to an .iplt entry, and change
+ the relocation target accordingly. Broaden assert to include
+ .iplts. Don't set sreloc for static relocations. Assert that
+ we only generate dynamic R_ARM_RELATIVE relocations for R_ARM_ABS32
+ and R_ARM_ABS32_NOI. Generate R_ARM_IRELATIVE relocations instead
+ of R_ARM_RELATIVE relocations if the target is an STT_GNU_IFUNC
+ symbol. Pass the symbol type to arm_type_of_stub. Conditionally
+ resolve GOT references to the .igot.plt entry.
+ (elf32_arm_relocate_section): Update the call to
+ elf32_arm_final_link_relocate.
+ (elf32_arm_gc_sweep_hook): Use elf32_arm_get_plt_info to get PLT
+ information. Treat R_ARM_REL32 and R_ARM_REL32_NOI as call
+ relocations in shared libraries and relocatable executables.
+ Count non-call PLT references. Use elf32_arm_get_local_dynreloc_list
+ to get the list of dynamic relocations for a local symbol.
+ (elf32_arm_check_relocs): Always create ifunc sections. Set isym
+ at the same time as setting h. Use elf32_arm_allocate_local_sym_info
+ to allocate local symbol information. Treat R_ARM_REL32 and
+ R_ARM_REL32_NOI as call relocations in shared libraries and
+ relocatable executables. Record PLT information for local
+ STT_GNU_IFUNC functions as well as global functions. Count
+ non-call PLT references. Use elf32_arm_get_local_dynreloc_list
+ to get the list of dynamic relocations for a local symbol.
+ (elf32_arm_adjust_dynamic_symbol): Handle STT_GNU_IFUNC symbols.
+ Don't remove STT_GNU_IFUNC PLTs unless all references have been
+ removed. Update after the changes to elf32_arm_link_hash_entry.
+ (allocate_dynrelocs_for_symbol): Decide whether STT_GNU_IFUNC PLT
+ entries should live in .plt or .iplt. Check whether the .igot.plt
+ and .got entries can be combined. Use elf32_arm_allocate_plt_entry
+ to allocate .plt and .(i)got.plt entries. Detect which .got
+ entries will need R_ARM_IRELATIVE relocations and use
+ elf32_arm_allocate_irelocs to allocate them. Likewise other
+ non-.got dynamic relocations.
+ (elf32_arm_size_dynamic_sections): Allocate .iplt, .igot.plt
+ and dynamic relocations for local STT_GNU_IFUNC symbols.
+ Check whether the .igot.plt and .got entries can be combined.
+ Detect which .got entries will need R_ARM_IRELATIVE relocations
+ and use elf32_arm_allocate_irelocs to allocate them. Use stashed
+ section pointers intead of strcmp checks. Handle iplt and igotplt.
+ (elf32_arm_finish_dynamic_symbol): Use elf32_arm_populate_plt_entry
+ to fill in .plt, .got.plt and .rel(a).plt entries. Point
+ STT_GNU_IFUNC symbols at an .iplt entry if non-call relocations
+ resolve to it.
+ (elf32_arm_output_plt_map_1): New function, split out from
+ elf32_arm_output_plt_map. Handle .iplt entries. Use
+ elf32_arm_plt_needs_thumb_stub_p.
+ (elf32_arm_output_plt_map): Call it.
+ (elf32_arm_output_arch_local_syms): Add mapping symbols for
+ local .iplt entries.
+ (elf32_arm_swap_symbol_in): Handle Thumb STT_GNU_IFUNC symbols.
+ (elf32_arm_swap_symbol_out): Likewise.
+ (elf32_arm_add_symbol_hook): New function.
+ (elf_backend_add_symbol_hook): Define for all targets.
+
+2011-03-14 Richard Sandiford <richard.sandiford@linaro.org>
+
+ * elf-bfd.h (elf_link_hash_entry): Add target_internal.
+ * elf.c (swap_out_syms): Set st_target_internal for each
+ Elf_Internal_Sym.
+ * elfcode.h (elf_swap_symbol_in): Likewise.
+ * elf32-i370.c (i370_elf_finish_dynamic_sections): Likewise.
+ * elf32-sh-symbian.c (sh_symbian_relocate_section): Likewise.
+ * elf64-sparc.c (elf64_sparc_output_arch_syms): Likewise.
+ * elfxx-sparc.c (_bfd_sparc_elf_size_dynamic_sections): Likewise.
+ * elflink.c (elf_link_output_extsym): Likewise.
+ (bfd_elf_final_link): Likewise.
+ (elf_link_add_object_symbols): Copy st_target_internal
+ to the hash table if we see a definition.
+ (_bfd_elf_copy_link_hash_symbol_type): Copy target_internal.
+ * elf32-arm.c (elf32_arm_stub_hash_entry): Replace st_type with
+ a branch_type field.
+ (a8_erratum_fix, a8_erratum_reloc): Likewise.
+ (arm_type_of_stub): Replace actual_st_type with an
+ actual_branch_type parameter.
+ (arm_build_one_stub): Use branch types rather than st_types to
+ determine the type of branch.
+ (cortex_a8_erratum_scan): Likewise.
+ (elf32_arm_size_stubs): Likewise.
+ (bfd_elf32_arm_process_before_allocation): Likewise.
+ (allocate_dynrelocs_for_symbol): Likewise.
+ (elf32_arm_finish_dynamic_sections): Likewise.
+ (elf32_arm_final_link_relocate): Replace sym_flags parameter with
+ a branch_type parameter.
+ (elf32_arm_relocate_section): Update call accordingly.
+ (elf32_arm_adjust_dynamic_symbol): Don't check STT_ARM_TFUNC.
+ (elf32_arm_output_map_sym): Initialize st_target_internal.
+ (elf32_arm_output_stub_sym): Likewise.
+ (elf32_arm_symbol_processing): Delete.
+ (elf32_arm_swap_symbol_in): Convert STT_ARM_TFUNCs into STT_FUNCs.
+ Use st_target_internal to record the branch type.
+ (elf32_arm_swap_symbol_out): Use st_target_internal to test for
+ Thumb functions.
+ (elf32_arm_is_function_type): Delete.
+ (elf_backend_symbol_processing): Likewise.
+ (elf_backend_is_function_type): Likewise.
+
+2011-03-14 Richard Sandiford <richard.sandiford@linaro.org>
+
+ * elf32-arm.c (elf32_arm_check_relocs): Always assign a dynobj.
+ (elf32_arm_finish_dynamic_sections): Move sgot != NULL assertion
+ into the PLT block.
+
+2011-03-14 Richard Sandiford <richard.sandiford@linaro.org>
+
+ * elf32-arm.c (elf32_arm_check_relocs): Use call_reloc_p,
+ may_need_local_target_p and may_become_dynamic_p to classify
+ the relocation type. Don't check info->symbolic or h->def_regular
+ when deciding whether to record a potential dynamic reloc.
+ Don't treat potential dynamic relocs as PLT references.
+ (elf32_arm_gc_sweep_hook): Update to match. Assert that we don't
+ try to make the PLT reference count go negative.
+
+2011-03-14 Richard Sandiford <richard.sandiford@linaro.org>
+
+ * elf32-arm.c (elf32_arm_final_link_relocate): Always fill in the
+ GOT entry here, rather than leaving it to finish_dynamic_symbol.
+ Only create a dynamic relocation for local references if
+ info->shared.
+ (allocate_dynrelocs_for_symbol): Update dynamic relocation
+ allocation accordingly.
+ (elf32_arm_finish_dynamic_symbol): Don't initialise the GOT entry here.
+
+2011-03-14 Richard Sandiford <richard.sandiford@linaro.org>
+
+ * elf32-arm.c (elf32_arm_allocate_dynrelocs): New function.
+ (elf32_arm_add_dynreloc): Likewise.
+ (elf32_arm_adjust_dynamic_symbol): Use elf32_arm_allocate_dynrelocs
+ to allocate dynamic relocations.
+ (elf32_arm_size_dynamic_sections): Likewise.
+ (allocate_dynrelocs): Likewise. Rename to
+ allocate_dynrelocs_for_symbol.
+ (elf32_arm_final_link_relocate): Use elf32_arm_add_dynreloc to
+ create dynamic relocations.
+ (elf32_arm_finish_dynamic_symbol): Likewise.
+
+2011-03-12 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf64-x86-64.c (elf_x86_64_check_tls_transition): Supprt TLS
+ x32 GD->IE and GD->LE transitions.
+ (elf_x86_64_relocate_section): Supprt TLS x32 GD->IE, GD->LE
+ and LD->LE transitions.
+
+2011-03-10 Alan Modra <amodra@gmail.com>
+
+ * elf64-ppc.c (ppc64_elf_relocate_section): Provide section/offset
+ for LO_DS error message and correct multiple.
+
+2011-03-10 Alan Modra <amodra@gmail.com>
+
+ * elf64-ppc.c (bfd_elf64_bfd_link_just_syms): Define.
+ (ppc64_elf_link_just_syms): New function.
+ (opd_entry_value): Don't assume big-endian host.
+ (get_r2off): New function.
+ (ppc_build_one_stub, ppc_size_one_stub): Use it here.
+
+2011-03-06 Michael Snyder <msnyder@vmware.com>
+
+ * compress.c (bfd_compress_section_contents): Check for out of mem.
+
+ * elf64-x86-64.c (elf_x86_64_relocate_section): Document
+ that case statement falls through intentionally.
+
+ * elf32-i386.c (elf_i386_relocate_section): Document fall through.
+
+2011-03-04 Alan Modra <amodra@gmail.com>
+
+ * archive.c (bsd_write_armap): Don't call stat in deterministic
+ mode, and don't use st_mtime if stat returns error.
+
+2011-03-03 Michael Snyder <msnyder@vmware.com>
+
+ * elf64-x86-64.c (elf_x86_64_relocate_section): Remove dead code.
+
+ * coff-x86_64.c (coff_amd64_rtype_to_howto): Fencepost error.
+
+ * aoutx.h (aout_final_link): Use sizeof int not sizeof int*.
+ (aout_link_write_other_symbol): Missing break statement.
+
+ * dwarf2.c (scan_unit_for_symbols): Stop memory leak.
+
+ * archive.c (_bfd_slurp_extended_name_table): Fail if bfd_seek fails.
+
+2011-03-03 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf64-x86-64.c (elf_x86_64_check_tls_transition): Supprt TLS
+ x32 IE->LE transition.
+ (elf_x86_64_relocate_section): Likewise.
+
+2011-03-02 Bernd Schmidt <bernds@codesourcery.com>
+
+ * elflink.c (is_reloc_section): Remove function.
+ (get_dynamic_reloc_section_name): Construct string manually.
+
+2011-02-28 Kai Tietz <kai.tietz@onevision.com>
+
+ * archive.c (_bfd_find_nested_archive): Use filename_(n)cmp.
+ (adjust_relative_path): Likewise.
+ (_bfd_construct_extended_name_table): Likewise.
+ * corefile.c (generic_core_file_matches_executable_p): Likewise.
+ * elf32-bfin.c (bfinfdpic_relocate_section): Likewise.
+ * elf32-frv.c (elf32_frv_relocate_section): Likewise.
+ * elf32-spu.c (sort_bfds): Likewise.
+ (spu_elf_auto_overlay): Likewise.
+ * syms.c (_bfd_stab_section_find_nearest_line): Likewise.
+ * xcofflink.c (xcoff_set_import_path): Likewise.
+ * xtensa-isa.c (xtensa_regfile_lookup): Likewise.
+ (xtensa_regfile_lookup_shortname): Likewise.
+
+2011-02-28 Alan Modra <amodra@gmail.com>
+
+ PR 12513
+ * archive.c (bfd_slurp_bsd_armap_f2): Sanity check parsed_size and
+ stringsize. Properly sanity check symdef_count. Remove redundant
+ bfd_release.
+
+2011-02-25 Rafael Ãvila de Espíndola <respindola@mozilla.com>
+
+ * plugin.c (bfd_plugin_object_p): Correctly set the filesize
+ and handle claim_file seeking. Only try to load the plugin once.
+
+2011-02-22 Andreas Schwab <schwab@redhat.com>
+
+ * elf32-m68k.c (elf_m68k_finish_dynamic_symbol): For a TLS_GD
+ relocation read the value from the second GOT slot.
+
+2011-02-15 Tristan Gingold <gingold@adacore.com>
+
+ * vms-alpha.c (alpha_vms_link_add_archive_symbols): Add a comment.
+
+2011-02-15 Alan Modra <amodra@gmail.com>
+
+ * elf64-ppc.c (ppc64_elf_edit_toc): Reinstate second read of
+ toc relocs. Fuss over free(NULL).
+
+2011-02-14 Mike Frysinger <vapier@gentoo.org>
+
+ * elflink.c (bfd_elf_size_dynamic_sections): Add
+ bfd_get_symbol_leading_char to the start of newname.
+
+2011-02-13 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
+
+ * configure: Regenerate.
+
+2011-02-09 Alan Modra <amodra@gmail.com>
+
+ * elf64-ppc.c (ppc64_elf_edit_toc): Don't free toc relocs until
+ we are done. When optimising large toc, check that a global
+ symbol on a toc reloc is defined in a kept section.
+
+2011-02-08 Nick Clifton <nickc@redhat.com>
+
+ PR binutils/12467
+ * elf.c (assign_file_positions_for_load_sections): Set the program
+ header offset and entry size to zero if there are no program
+ headers.
+
+2011-02-08 Alan Modra <amodra@gmail.com>
+
+ * elf64-ppc.c (ppc64_elf_edit_toc): Don't segfault on NULL
+ local_syms when looking for local symbols in .toc.
+
+2011-02-01 Alan Modra <amodra@gmail.com>
+
+ * elf64-ppc.c (ppc64_elf_next_input_section): Use elf_gp value
+ for toc pointer on any section having makes_toc_func_call set.
+ (check_pasted_section): Ensure pasted .init/.fini fragments use
+ the same toc if any has makes_toc_func_call set.
+
+2011-01-28 Joseph Myers <joseph@codesourcery.com>
+
+ * elf32-ppc.c (ppc_elf_link_hash_newfunc): Initialize has_sda_refs
+ field.
+
+2011-01-22 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * elfxx-mips.c (_bfd_mips_elf_merge_private_bfd_data): Ignore
+ common sections too.
+
+2011-01-18 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf64-x86-64.c (elf_backend_want_plt_sym): Redefine to 0 after
+ Solaris target.
+
+2011-01-18 Pierre Muller <muller@ics.u-strasbg.fr>
+
+ Fix compilation for mingw64.
+ * coffcode.h (coff_slurp_symbol_table): Add intptr_t intermediate
+ typecast to avoid warning.
+ * elf32-rx.c: Add "bfd_stdint.h" include required for int32_t type
+ usage.
+ * elfxx-ia64.c (elfNN_ia64_relax_br): Use intptr_t typeacast instead
+ of long for pointer to avoid warning.
+ (elfNN_ia64_relax_brl): Idem.
+ (elfNN_ia64_install_value): Idem.
+ * vms-alpha.c (_bfd_vms_slurp_etir): Idem.
+
+2011-01-17 Richard Sandiford <richard.sandiford@linaro.org>
+
+ * elf32-arm.c (elf32_arm_check_relocs): Check needs_plt rather than
+ h->needs_plt when deciding whether to record a possible dynamic reloc.
+
+2011-01-17 Richard Sandiford <richard.sandiford@linaro.org>
+
+ * elf32-arm.c (elf32_arm_gc_sweep_hook): Remove all registered
+ dynamic relocs for the removed section.
+
+2011-01-15 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf64-x86-64.c (elf_x86_64_check_relocs): Check invalid x32
+ relocations.
+
+2011-01-14 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf64-x86-64.c (elf_x86_64_link_hash_table): Add pointer_r_type.
+ (elf_x86_64_link_hash_table_create): Set pointer_r_type.
+ (elf_x86_64_check_relocs): Handle R_X86_64_32 like R_X86_64_64
+ for ILP32. Remove ABI_64_P PIC check for R_X86_64_8,
+ R_X86_64_16, R_X86_64_32 and R_X86_64_32S.
+ (elf_x86_64_relocate_section): Handle R_X86_64_32 like R_X86_64_64
+ for ILP32.
+
+2011-01-14 Alan Modra <amodra@gmail.com>
+
+ * bfd.c (bfd_perror): Flush stdout before and stderr after printing
+ error.
+ (_bfd_default_error_handler): Likewise.
+ * elf.c (print_segment_map): Likewise.
+ * libbfd.c (warn_deprecated): Likewise.
+ * som.c (som_sizeof_headers): No need to do so here.
+ * coff-i860.c: Replace use of printf for error messages with
+ _bfd_error_handler.
+ * coff-ppc.c: Likewise.
+ * coff-sh.c: Likewise.
+ * elf32-bfin.c: Likewise.
+ * elf32-dlx.c: Likewise.
+ * elf32-mep.c: Likewise.
+ * elf32-v850.c: Likewise.
+ * mach-o.c: Likewise.
+ * pef.c: Likewise.
+
+2011-01-13 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf64-x86-64.c (elf_x86_64_link_hash_table): Remove
+ swap_reloca_out.
+ (elf_x86_64_link_hash_table_create): Don't set swap_reloca_out.
+ (elf_x86_64_check_relocs): Align relocation section to 4 byte
+ for 32bit.
+ (elf_x86_64_gc_sweep_hook): Replace ELF64_ST_TYPE with
+ ELF_ST_TYPE.
+ (elf_x86_64_finish_dynamic_symbol): Updated.
+ (elf_x86_64_finish_dynamic_sections): Don't use
+ Elf64_External_Dyn, bfd_elf64_swap_dyn_in, nor
+ bfd_elf64_swap_dyn_out.
+
+2011-01-14 J. Park <grassman@gmail.com>
+
+ PR ld/12339
+ * elf32-arm.c (allocate_dynrelocs): Don't set up eh before
+ following bfd_link_hash_warning symbol link.
+
+2011-01-10 Nathan Sidwell <nathan@codesourcery.com>
+ Glauber de Oliveira Costa <glommer@gmail.com>
+
+ * reloc.c (BFD_RELOC_ARM_TLS_GOTDESC, BFD_RELOC_ARM_TLS_CALL,
+ BFD_RELOC_ARM_THM_TLS_CALL, BFD_RELOC_ARM_TLS_DESCSEQ,
+ BFD_RELOC_ARM_THM_TLS_DESCSEQ, BFD_RELOC_ARM_TLS_DESC): New
+ relocations.
+ * libbfd.h: Rebuilt.
+ * bfd-in2.h: Rebuilt.
+ * elf32-arm.c (elf32_arm_howto_table_1): Add new relocations.
+ (elf32_arm_reloc_map): Likewise.
+ (tls_trampoline, dl_tlsdesc_lazy_trampoline): New PLT templates.
+ (elf32_arm_stub_long_branch_any_tls_pic,
+ elf32_arm_stub_long_branch_v4t_thumb_tls_pic): New stub templates.
+ (DEF_STUBS): Add new stubs.
+ (struct_elf_arm_obj_data): Add local_tlsdesc_gotent field.
+ (elf32_arm_local_tlsdesc_gotent): New.
+ (GOT_TLS_GDESC): New mask.
+ (GOT_TLS_GD_ANY): Define.
+ (struct elf32_arm_link_hash_entry): Add tlsdesc_got field.
+ (elf32_arm_compute_jump_table_size): New.
+ (struct elf32_arm_link_hash_table): Add next_tls_desc_index,
+ num_tls_desc, dt_tlsdesc_plt, dt_tlsdesc_got, tls_trampoline,
+ sgotplt_jump_table_size fields.
+ (elf32_arm_link_hash_newfunc): Initialize tlsdesc_got field.
+ (elf32_arm_link_hash_table_create): Initialize new fields.
+ (arm_type_of_stub): Check TLS desc relocs too.
+ (elf32_arm_stub_name): TLS desc relocs can be shared.
+ (elf32_arm_tls_transition): Determine relaxation.
+ (arm_stub_required_alignment): Add tls stubs.
+ (elf32_arm_size_stubs): Likewise.
+ (elf32_arm_tls_relax): Perform TLS relaxing.
+ (elf32_arm_final_link_relocate): Process TLS DESC relocations.
+ (IS_ARM_TLS_GNU_RELOC): New.
+ (IS_ARM_TLS_RELOC): Use it.
+ (elf32_arm_relocate_section): Perform TLS relaxing.
+ (elf32_arm_check_relocs): Anticipate TLS relaxing, process tls
+ desc relocations.
+ (allocate_dynrelocs): Allocate tls desc relcoations.
+ (elf32_arm_output_arch_local_syms): Emit tls trampoline mapping
+ symbols.
+ (elf32_arm_size_dynamic_sections): Allocate tls trampolines and
+ got slots.
+ (elf32_arm_always_size_sections): New. Create _TLS_MODULE_BASE
+ symbol.
+ (elf32_arm_finish_dynamic_symbol): Adjust.
+ (arm_put_trampoline): New.
+ (elf32_arm_finish_dynamic_sections): Emit new dynamic tags and tls
+ trampolines.
+ (elf_backend_always_size_sections): Define.
+
+2011-01-06 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf-ifunc.c (_bfd_elf_allocate_ifunc_dyn_relocs): Optimized.
+
+2011-01-06 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/12366
+ PR ld/12371
+ * elf-ifunc.c (_bfd_elf_allocate_ifunc_dyn_relocs): Properly
+ handle symbols marked with regular reference, but not non-GOT
+ reference when building shared library.
+
+ * elf32-i386.c (elf_i386_gc_sweep_hook): Properly handle
+ local and global STT_GNU_IFUNC symols when building shared
+ library.
+ * elf64-x86-64.c (elf_x86_64_gc_sweep_hook): Likewise.
+
+2011-01-05 DJ Delorie <dj@redhat.com>
+
+ * reloc.c: Add BFD_RELOC_RX_OP_NEG.
+ * libbfd.h: Regenerate.
+ * bfd-in2.h: Regenerate.
+ * elf32-rx.c: Add it to the list, corresponding to R_RX_OPneg.
+
+2011-01-03 H.J. Lu <hongjiu.lu@intel.com>
+
+ * cpu-i386.c (bfd_i386_compatible): New.
+ (bfd_x64_32_arch_intel_syntax): Replace bfd_default_compatible
+ with bfd_i386_compatible.
+ (bfd_x86_64_arch_intel_syntax): Likewise.
+ (bfd_i386_arch_intel_syntax): Likewise.
+ (i8086_arch): Likewise.
+ (bfd_x64_32_arch): Likewise.
+ (bfd_x86_64_arch): Likewise.
+ (bfd_i386_arch): Likewise.
+
+For older changes see ChangeLog-2010
+
+Copyright (C) 2011 Free Software Foundation, Inc.
+
+Copying and distribution of this file, with or without modification,
+are permitted in any medium without royalty provided the copyright
+notice and this notice are preserved.
+
+Local Variables:
+mode: change-log
+left-margin: 8
+fill-column: 74
+version-control: never
+End:
diff --git a/bfd/ChangeLog-2012 b/bfd/ChangeLog-2012
new file mode 100644
index 0000000..7d82ace
--- /dev/null
+++ b/bfd/ChangeLog-2012
@@ -0,0 +1,3300 @@
+2012-12-23 Mike Frysinger <vapier@gentoo.org>
+
+ * config.bfd (i[3-7]86-*-linux-*): Add x86_64pei_vec to
+ targ64_selvecs.
+
+2012-12-21 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf64-x86-64.c (elf_x86_64_relocate_section): Check
+ R_X86_64_standard instead of R_X86_64_max for unrecognized
+ relocation.
+
+2012-12-21 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/14980
+ * elf32-i386.c (elf_i386_adjust_dynamic_symbol): Properly
+ adjust h->plt.refcount.
+ * elf64-x86-64.c (elf_x86_64_adjust_dynamic_symbol): Likewise.
+
+2012-12-19 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf32-i386.c (elf_i386_relocate_section): Replace
+ bfd_elf32_swap_reloc_out with elf_append_rel.
+ (elf_i386_finish_dynamic_symbol): Likewise.
+
+ * elflink.c (elf_append_rel): Call swap_reloc_out instead of
+ swap_reloca_out.
+
+2012-12-18 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf32-i386.c (elf_i386_finish_dynamic_symbol): Reindent.
+
+2012-12-18 Edgar E. Iglesias <edgar.iglesias@gmail.com>
+
+ PR ld/14736
+ * elf32-microblaze.c (calc_fixup): Add end range.
+
+2012-12-18 Alan Modra <amodra@gmail.com>
+
+ * elf.c (swap_out_syms): Set shndx to SHN_ABS when not one of
+ the special MAP_* values.
+
+2012-12-17 Roland McGrath <mcgrathr@google.com>
+ Alan Modra <amodra@gmail.com>
+
+ * elf32-arm.c (elf32_arm_size_stubs): Skip input BFDs that are
+ not ARM ELF.
+
+2012-12-17 Nick Clifton <nickc@redhat.com>
+
+ * MAINTAINERS: Add copyright notice.
+ * Makefile.am: Likewise.
+ * PORTING: Likewise.
+ * README: Likewise.
+ * TODO: Likewise.
+ * acinclude.m4: Likewise.
+ * bfd.m4: Likewise.
+ * config.bfd: Likewise.
+ * configure.com: Likewise.
+ * configure.host: Likewise.
+ * configure.in: Likewise.
+ * makefile.vms: Likewise.
+ * warning.m4: Likewise.
+ * elf64-hppa.c: Fix copyright notice.
+ * Makefile.in: Regenerate.
+
+2012-12-16 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf32-i386.c (elf_i386_check_relocs): Don't check IFUNC
+ relocations here.
+ * elf64-x86-64.c (elf_x86_64_check_relocs): Likewise.
+
+2012-12-16 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/14968
+ * elf32-i386.c (elf_i386_adjust_dynamic_symbol): Also check
+ local IFUNC references.
+ * elf64-x86-64.c (elf_x86_64_adjust_dynamic_symbol): Likewise.
+
+2012-12-14 Tom Tromey <tromey@redhat.com>
+
+ * elf.c (elfcore_grok_note) <NT_FILE>: New case.
+
+2012-12-13 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/14956
+ * elf32-i386.c (elf_i386_adjust_dynamic_symbol): Check local
+ IFUNC calls.
+ * elf64-x86-64.c (elf_x86_64_adjust_dynamic_symbol): Likewise.
+
+2012-12-10 Edgar E. Iglesias <edgar.iglesias@gmail.com>
+
+ * reloc.c (MICROBLAZE): Document new relocations
+ * bfd-in2.h: Regenerated
+ * libbfd.h: Regenerated
+ * elf32-microblaze.c (microblaze_elf_howto_raw): Add TLS relocations
+ (microblaze_elf_reloc_type_lookup): Likewise
+ (elf32_mb_link_hash_entry): define TLS reference types
+ (elf32_mb_link_hash_table): add TLS Local dynamic GOT entry
+ #define has_tls_reloc if section has TLS relocs
+ (dtprel_base), (check_unique_offset): New
+ (microblaze_elf_output_dynamic_relocation): output simple
+ dynamic relocation into SRELOC.
+ (microblaze_elf_relocate_section): Accommodate TLS relocations.
+ (microblaze_elf_check_relocs): Likewise
+ (update_local_sym_info): New
+ (microblaze_elf_copy_indirect_symbol): Add tls_mask.
+ (allocate_dynrelocs): Handle TLS symbol
+ (microblaze_elf_size_dynamic_sections): Set size and offset
+ (microblaze_elf_finish_dynamic_symbol): Use
+ microblaze_elf_output_dynamic_relocation
+
+2012-12-09 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR binutils/14933
+ * archive.c (bsd_write_armap): Properly check indicies bigger
+ than 4Gb.
+
+2012-12-07 Alan Modra <amodra@gmail.com>
+
+ PR ld/14926
+ * elf.c (_bfd_elf_map_sections_to_segments): Include elf header
+ size when determining phdr_in_segment.
+
+2012-12-06 Yufeng Zhang <yufeng.zhang@arm.com>
+
+ * elf64-aarch64.c (elf64_aarch64_grok_prstatus): New function.
+ (elf_backend_grok_prstatus): Define to elf64_aarch64_grok_prstatus.
+
+2012-12-06 Alan Modra <amodra@gmail.com>
+
+ * elfxx-mips.c (allocate_dynrelocs): Correct test for symbol
+ defined in a regular file to include common symbols.
+
+2012-12-05 Leif Ekblad <leif@rdos.net>
+
+ * config.bfd: Add x86_64-*-rdos.
+
+2012-12-05 Alan Modra <amodra@gmail.com>
+
+ * elf64-ppc.c (build_plt_stub): Fix off by one error in branch
+ to glink.
+
+2012-12-03 Maciej W. Rozycki <macro@codesourcery.com>
+
+ PR ld/10629
+ * elfxx-mips.c (mips_elf_link_hash_table): Update comment for
+ use_rld_obj_head.
+ (_bfd_mips_elf_create_dynamic_sections): Always create a
+ .rld_map section if no __rld_obj_head symbol has been seen.
+
+2012-12-03 Maciej W. Rozycki <macro@codesourcery.com>
+
+ * elf32-mips.c (mips_elf32_object_p): Return right away when the
+ ABI is not compatible.
+ * elfn32-mips.c (mips_elf_n32_object_p): Likewise.
+
+2012-12-03 Maciej W. Rozycki <macro@codesourcery.com>
+
+ * elf32-tilepro.c (tilepro_elf_mkobject): New function.
+ (bfd_elf32_mkobject): New macro.
+
+2012-12-03 Maciej W. Rozycki <macro@codesourcery.com>
+
+ * elf32-mips.c (bfd_elf32_mkobject): New macro.
+ * elf64-mips.c (bfd_elf64_mkobject): Likewise.
+ * elfn32-mips.c (bfd_elf32_mkobject): Likewise.
+ * elfxx-mips.h (_bfd_mips_elf_mkobject): New prototype.
+ * elfxx-mips.c (mips_elf_obj_tdata): New struct.
+ (mips_elf_tdata): New macro.
+ (_bfd_mips_elf_mkobject): New function.
+ (mips_elf_merge_obj_attributes): Report the originating input BFD
+ on attribute conflicts.
+
+2012-12-03 Maciej W. Rozycki <macro@codesourcery.com>
+
+ * elfxx-mips.c (mips_elf_merge_obj_attributes): Correct messages
+ for the -mdouble-float and -msingle-float cases throughout; make
+ all the messages report the output file consistently on the
+ left-hand side.
+
+2012-11-29 Roland McGrath <mcgrathr@google.com>
+
+ * elf-nacl.c (segment_eligible_for_headers): Disallow writable segments.
+
+2012-11-26 Roland McGrath <mcgrathr@google.com>
+
+ * elf-nacl.c (nacl_modify_segment_map): Don't crash when INFO is null.
+
+2012-11-21 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR binutils/14493
+ * elf.c (copy_elf_program_header): When rewriting program
+ header, set the output maxpagesize to the maximum alignment
+ of input PT_LOAD segments.
+
+2012-11-21 Roland McGrath <mcgrathr@google.com>
+
+ * elf-nacl.c (segment_nonexecutable_and_has_contents): Renamed to ...
+ (segment_eligible_for_headers): ... this. Take new arguments
+ MAXPAGESIZE and SIZEOF_HEADERS. Return false if the first section's
+ start address doesn't leave space for the headers.
+ (nacl_modify_segment_map): Update caller.
+
+2012-11-20 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/14862
+ * elf-bfd.h (elf_link_hash_entry): Remove ref_dynamic_nonweak
+ added by accident.
+ (elf_link_add_object_symbols): Don't set nor check
+ ref_dynamic_nonweak.
+
+2012-11-20 Alan Modra <amodra@gmail.com>
+
+ * elf32-rx.c (rx_elf_print_private_bfd_data): Warning fix.
+
+2012-11-16 Joey Ye <joey.ye@arm.com>
+
+ * elf32-arm.c (elf32_arm_final_link_relocate
+ <case R_ARM_THM_ALU_PREL_11_0, case R_ARM_THM_PC12>): Align address of
+ the place being relocated.
+ (elf32_arm_final_link_relocate, case R_ARM_THM_PC8): Align address
+ of the place being relocated and truncate addend.
+ (Pa): New macro.
+
+2012-11-14 Roland McGrath <mcgrathr@google.com>
+
+ * elf32-arm.c (elf32_arm_nacl_plt0_entry): Use bic rather than bfc
+ instruction for data sandboxing.
+
+2012-11-14 Tristan Gingold <gingold@adacore.com>
+
+ * mach-o.c (bfd_mach_o_read_main)
+ (bfd_mach_o_read_source_version): New functions.
+ (bfd_mach_o_read_command): Handle BFD_MACH_O_LC_DATA_IN_CODE,
+ BFD_MACH_O_LC_DYLIB_CODE_SIGN_DRS, BFD_MACH_O_LC_MAIN,
+ BFD_MACH_O_LC_SOURCE_VERSION.
+ * mach-o.h (bfd_mach_o_main_command)
+ (bfd_mach_o_source_version_command): New types.
+ (bfd_mach_o_load_command): Add fields for these new types.
+
+2012-11-14 Tristan Gingold <gingold@adacore.com>
+
+ * mach-o.c (bfd_mach_o_canonicalize_one_reloc): Add a special
+ handling for non-scattered pairs. Update comments.
+
+2012-11-13 Joe Seymour <jseymour@codesourcery.com>
+
+ * elf.c (rewrite_elf_program_header): Allocate elf_segment_map
+ with bfd_zalloc, instead of bfd_alloc.
+
+2012-11-09 Nick Clifton <nickc@redhat.com>
+
+ * Makefile.am (ALL_MACHINES): Add cpu-v850-rh850.lo.
+ (ALL_MACHINES_CFILES): Add cpu-v850-rh850.c.
+ * archures.c (bfd_arch_info): Add bfd_v850_rh850_arch.
+ * config.bfd: Likewise.
+ * configure.in: Add bfd_elf32_v850_rh850_vec.
+ * cpu-v850.c: Update printed description.
+ * cpu-v850_rh850.c: New file.
+ * elf32-v850.c (v850_elf_check_relocs): Add support for RH850 ABI
+ relocs.
+ (v850_elf_perform_relocation): Likewise.
+ (v850_elf_final_link_relocate): Likewise.
+ (v850_elf_relocate_section): Likewise.
+ (v850_elf_relax_section): Likewise.
+ (v800_elf_howto_table): New.
+ (v850_elf_object_p): Add support for RH850 ABI values.
+ (v850_elf_final_write_processing): Likewise.
+ (v850_elf_merge_private_bfd_data): Likewise.
+ (v850_elf_print_private_bfd_data): Likewise.
+ (v800_elf_reloc_map): New.
+ (v800_elf_reloc_type_lookup): New.
+ (v800_elf_reloc_name_lookup): New.
+ (v800_elf_info_to_howto): New.
+ (bfd_elf32_v850_rh850_vec): New.
+ (bfd_arch_v850_rh850): New.
+ * targets.c (_bfd_targets): Add bfd_elf32_v850_rh850_vec.
+ * Makefile.in: Regenerate.
+ * bfd-in2.h: Regenerate.
+ * configure: Regenerate.
+
+ * elf32-rx.c (describe_flags): New function. Returns a buffer
+ containing a description of the E_FLAG_RX_... values set.
+ (rx_elf_merge_private_bfd_data): Use it.
+ (rx_elf_print_private_bfd_data): Likewise.
+ (elf32_rx_machine): Skip EF_RX_CPU_RX check.
+ (elf32_rx_special_sections): Define.
+ (elf_backend_special_sections): Define.
+
+2012-11-09 Edgar E. Iglesias <edgar.iglesias@gmail.com>
+
+ * config.bfd: Add microblazeel-*-*
+ * configure.in: Likewise.
+ * configure: Regenerate.
+ * elf32-microblaze.c (microblaze_elf_relocate_section): Add endian awareness.
+ (microblaze_elf_merge_private_bfd_data): New.
+ (microblaze_bfd_write_imm_value_32): New.
+ (microblaze_bfd_write_imm_value_64): New.
+ (microblaze_elf_relax_section): Add endian awareness.
+ (microblaze_elf_add_symbol_hook): Define TARGET_LITTLE_NAME,
+ TARGET_LITTLE_SYM and bfd_elf32_bfd_merge_private_bfd_data.
+ * targets.c: Add bfd target bfd_elf32_microblazeel_vec.
+
+2012-11-09 H.J. Lu <hongjiu.lu@intel.com>
+
+ * aout-tic30.c (MY_final_link_callback): Remove trailing
+ redundant `;'.
+ * coff-h8500.c (extra_case): Likewise.
+ (bfd_coff_reloc16_get_value): Likewise.
+ * dwarf2.c (_bfd_dwarf2_cleanup_debug_info): Likewise.
+ * elf.c (_bfd_elf_slurp_version_tables): Likewise.
+ * elf32-frv.c (elf32_frv_relocate_section): Likewise.
+ * elf32-v850.c (v850_elf_perform_relocation): Likewise.
+ * opncls.c (bfd_calc_gnu_debuglink_crc32): Likewise.
+ * plugin.c (add_symbols): Likewise.
+ * reloc.c (bfd_check_overflow): Likewise.
+ * vms-lib.c (_bfd_vms_lib_archive_p): Likewise.
+
+2012-11-08 Tom Tromey <tromey@redhat.com>
+
+ * elf.c (elfcore_grok_note) <NT_SIGINFO>: New case; make
+ pseudosection.
+
+2012-11-08 Alan Modra <amodra@gmail.com>
+
+ * aclocal.m4: Regenerate.
+ * Makefile.in: Regenerate.
+ * po/SRC-POTFILES.in: Regenerate.
+
+2012-11-07 H.J. Lu <hongjiu.lu@intel.com>
+
+ * section.c (bfd_get_section_contents): Replace memcpy
+ with memmove.
+
+2012-11-07 Hans-Peter Nilsson <hp@axis.com>
+
+ PR binutils/14481
+ * aout-target.h (MY_close_and_cleanup): Make local function
+ instead of alias of MY_bfd_free_cached_info. Also call
+ _bfd_generic_close_and_cleanup.
+
+2012-11-06 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR binutils/14813
+ * bfdio.c (bfd_iovec): Change return type of bclose to
+ bfd_boolean.
+ (memory_bclose): Change return type to bfd_boolean.
+ * cache.c (cache_bclose): Likewise.
+ * opncls.c (opncls_bclose): Likewise. Return TRUE on success.
+ * vms-lib.c (vms_lib_bclose): Likewise. Return TRUE.
+ * libbfd.h: Regenerated.
+
+2012-11-06 Tristan Gingold <gingold@adacore.com>
+
+ * coff-x86_64.c (_bfd_generic_find_nearest_line_discriminator):
+ Define as coff_find_nearest_line_discriminator.
+
+2012-11-06 Alan Modra <amodra@gmail.com>
+
+ PR binutils/14567
+ * opncls.c (opncls_iovec): Forward declare.
+ (_bfd_new_bfd_contained_in): If using opncls_iovec, copy iostream
+ to new bfd.
+
+2012-11-06 Alan Modra <amodra@gmail.com>
+
+ * mach-o.c (bfd_mach_o_close_and_cleanup): Don't call
+ _bfd_generic_close_and_cleanup for mach_o_fat archives.
+
+2012-11-06 Alan Modra <amodra@gmail.com>
+
+ * coff-tic4x.c (tic4x_coff0_vec, tic4x_coff0_beh_vec,
+ tic4x_coff1_vec, tic4x_coff1_beh_vec, tic4x_coff2_vec,
+ tic4x_coff2_beh_vec): Allow SEC_CODE and SEC_READONLY in
+ section flags.
+ * coff-ppc.c (TARGET_LITTLE_SYM): Likewise.
+ (TARGET_BIG_SYM): Likewise.
+
+2012-11-06 Alan Modra <amodra@gmail.com>
+
+ * elf64-ppc.c (struct ppc_link_hash_table): Add dot_toc_dot.
+ (ppc64_elf_size_stubs): Lookup ".TOC.".
+ (ppc64_elf_relocate_section): Resolve special symbol ".TOC.".
+
+2012-11-06 Alan Modra <amodra@gmail.com>
+
+ * elf64-ppc.c (maybe_strip_output): Heed SEC_KEEP.
+
+2012-11-05 Andreas Krebbel <Andreas.Krebbel@de.ibm.com>
+
+ PR target/14788
+ * elf32-s390.c (elf_s390_relocate_section): Set elf.dynobj for
+ local ifunc symbols.
+ * elf64-s390.c (elf_s390_relocate_section): Likewise.
+
+2012-11-05 Alan Modra <amodra@gmail.com>
+
+ * configure.in: Apply 2012-09-10 change to config.in here.
+
+2012-11-05 Alan Modra <amodra@gmail.com>
+
+ * elf64-ppc.c (ppc64_elf_edit_toc): Clear "repeat" inside
+ loop. Really mark toc entry referring to another toc entry
+ only if the first is used.
+
+2012-10-30 H.J. Lu <hongjiu.lu@intel.com>
+
+ * configure.in: Also handle --enable-64-bit-bfd when setting
+ CORE_HEADER for 'i[3-7]86-*-linux-*'.
+
+2012-10-30 Steve McIntyre <steve.mcintyre@linaro.org>
+
+ * elf32-arm.c (elf32_arm_print_private_bfd_data): Recognise and
+ display the new ARM hard-float/soft-float ABI flags for EABI_VER5
+ (elf32_arm_post_process_headers): Add the hard-float/soft-float
+ ABI flag as appropriate for ET_DYN/ET_EXEC in EABI_VER5.
+
+2012-10-30 Yao Qi <yao@codesourcery.com>
+ H.J. Lu <hongjiu.lu@intel.com>
+
+ * configure.in: Set CORE_HEADER to hosts/x86-64linux.h for
+ 'i[3-7]86-*-linux-*' if x86_64-*linux is enabled.
+ * configure: Regenerated.
+
+ * elf64-x86-64.c (elf_x86_64_write_core_note): Replace type
+ 'prpsinfo_t' and 'prstatus_t' with 'prpsinfo64_t' and
+ 'prstatus64_t' respectively.
+
+ * hosts/x86-64linux.h (a8_uint64_t): New.
+ (user_regsx32_struct): Renamed to ...
+ (user_regs64_struct): This. Replace uint64_t with a8_uint64_t.
+ (elf_gregx32_t): Renamed to ...
+ (elf_greg64_t): This. Replace uint64_t with a8_uint64_t.
+ (ELF_NGREGX32): Removed.
+ (ELF_NGREG64): New.
+ (elf_gregx32_t): Removed.
+ (elf_greg64_t): New.
+ (struct prstatus64_timeval): New.
+ (elf_prstatusx32): Replace elf_gregsetx32_t with elf_gregset64_t.
+ (elf_prstatus64): New.
+ (elf_prpsinfo64): New.
+ (prstatus64_t, prpsinfo64_t): New typedef.
+
+2012-10-29 Sean Keys <skeys@ipdatasys.com>
+
+ * elf32-xgate.c(elf_xgate_howto_table): Fix src and dest mask for
+ R_XGATE_16
+
+2012-10-29 Alan Modra <amodra@gmail.com>
+
+ * elf32-ppc.c (ppc_elf_howto_raw): Correct dst_mask in
+ R_PPC_VLE_LO16A, R_PPC_VLE_HI16A, R_PPC_VLE_HA16A,
+ R_PPC_VLE_SDAREL_LO16A, R_PPC_VLE_SDAREL_HI16A,
+ R_PPC_VLE_SDAREL_HA16A reloc howtos.
+
+2012-10-26 Nick Clifton <nickc@redhat.com>
+
+ * po/uk.po: Updated Ukranian translation.
+
+2012-10-26 Alan Modra <amodra@gmail.com>
+
+ PR gas/14758
+ * elf32-ppc.c (ppc_elf_reloc_type_lookup): Decode ppc64 _DS
+ bfd_reloc values. Map to corresponding D-form relocs.
+ (is_insn_ds_form, is_insn_qs_form): New functions.
+ (ppc_elf_relocate_section): Validate insn with DS-form or DQ-form
+ fields using D-form reloc.
+
+2012-10-25 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf32-i386.c (elf_i386_size_dynamic_sections): Replace
+ _GLOBAL_OFFSET_TABLE_ lookup with htab->elf.hgot.
+ * elf64-x86-64.c (elf_x86_64_size_dynamic_sections): Likewise.
+
+2012-10-24 H.J. Lu <hongjiu.lu@intel.com>
+
+ * compress.c (bfd_is_section_compressed): Don't decompress the
+ section.
+
+2012-10-23 Nathan Sidwell <nathan@codesourcery.com>
+
+ * bfd-in.h (bfd_elf_stack_segment_size): Declare.
+ * bfd-in2.h: Rebuilt.
+ * elfxx-target.h (elf_backend_stack_align): New.
+ (elfNN_bed): Add it.
+ * elf-bfd.h (struct elf_backend_data): Add stack_align field.
+ * elf.c (bfd_elf_map_sections_to_segments): Pay attention to
+ stack_align and stacksize for PT_GNU_STACK segment.
+ (assign_file_positions_for_non_load_sections): Set p_memsz for
+ PT_GNU_STACK segment.
+ (copy_elf_program_header): Copy PT_GNU_STACK size.
+ * elflink.c (bfd_elf_stack_segment_size): New function, taken from
+ uclinux backends.
+ (bfd_elf_size_dynamic_sections): Determine
+ PT_GNU_STACK requirements after calling backend. Pay attention to
+ stacksize.
+ * elf32-bfin.c (elf32_bfinfdpic_always_size_sections): Call
+ bfd_elf_stack_segment_size.
+ (elf32_bfinfdpic_modify_program_headers): Delete.
+ (elf32_bfingfdpic_copy_private_bfd_data): Don't copy PT_GNU_STACK
+ here.
+ (elf_backend_stack_align): Override.
+ (elf_backend_modify_program_headers): Don't override.
+ * elf32-frv.c (frvfdpic_always_size_sections): Call
+ bfd_elf_stack_segment_size.
+ (elf32_frvfdpic_modify_program_headers): Delete.
+ (elf32_frvfdpic_copy_private_bfd_data): Don't copy PT_GNU_STACK
+ here.
+ (elf_backend_stack_align): Override.
+ (elf_backend_modify_program_headers): Don't override.
+ * elf32-lm32.c (lm32_elf_always_size_sections): Leave
+ PT_GNU_STACK creation to underlying elf support. Check
+ __stacksize here for backwards compatibility, and set it if
+ needed.
+ (lm32_elf_modify_segment_map): Delete.
+ (lm32_elf_modify_program_headers): Delete.
+ (elf_backend_stack_align): Override.
+ (elf_backend_modify_segment_map): Don't override.
+ (elf_backend_modify_program_headers): Don't override.
+ * elf32-sh.c (sh_elf_always_size_sections): Call
+ bfd_elf_stack_segment_size.
+ (sh_elf_modify_program_headers): Delete.
+ (sh_elf_copy_private_data): Don't copy PT_GNU_STACK
+ here.
+ (elf_backend_stack_align): Override.
+ (elf_backend_modify_program_headers): Don't override.
+ * elf32-tic6x.c (elf32_tic6x_always_size_sections): Call
+ bfd_elf_stack_segment_size.
+ (elf32_tic6x_modify_program_headers): Delete.
+ (elf32_tic6x_copy_private_data): Delete.
+ (elf_backend_stack_align): Override.
+ (bfd_elf32_bfd_copy_private_bfd_data): Don't override.
+ (elf_backend_modify_program_headers): Don't override.
+
+2012-10-22 Alan Modra <amodra@gmail.com>
+
+ * cache.c (cache_bmmap): Don't use void* arithmetic.
+
+2012-10-21 Alan Modra <amodra@gmail.com>
+
+ * compress.c (bfd_cache_section_contents): New function.
+ * bfd-in2.h: Regenerate.
+
+2012-10-21 Hans-Peter Nilsson <hp@bitrange.com>
+
+ * linker.c (_bfd_generic_link_output_symbols): Handle a
+ no-longer-global symbol entered through a plugin.
+
+2012-10-20 Alan Modra <amodra@gmail.com>
+
+ * compress.c: Reinstate 2012-10-19 change.
+ (bfd_get_full_section_contents): Don't free unless we alloc.
+ Use proper decompress size. Delete some vars, rename others.
+
+2012-10-19 Tom Tromey <tromey@redhat.com>
+
+ * compress.c: Revert previous patch.
+
+2012-10-19 Tom Tromey <tromey@redhat.com>
+
+ * compress.c (bfd_get_full_section_contents): Don't cache
+ decompressed contents.
+
+2012-10-18 Kai Tietz <ktietz@redhat.com>
+
+ PR binutils/14067
+ * coff-i386.c (bfd_target): Add section flag SEC_EXCLUDE.
+ Allow BFD_COMPRESS and BFD_DECOMPRESS flags.
+ * coff-x86_64.c: Likewise.
+ * coffcode.h (DOT_ZDEBUG): New define.
+ (sec_to_styp_flags): Check for .zdebug.
+ (styp_to_sec_flags): Likewise.
+ * coffgen.c (make_a_section): Handle .debug_* section
+ compression/decompression flags.
+ * cofflink.c (mark_relocs): Ignore relocations
+ for a section, which isn't marked as used.
+ (_bfd_coff_link_input_bfd): Add support of compressed
+ debug sections.
+ * compress.c (decompress_contents): Loop as long
+ as there is input available and there is room for
+ output.
+ * bfd/pe-arm.c: Add .zdebug_ partial match entry.
+ * pe-i386.c: Likewise.
+ * pe-x86_64.c: Likewise.
+ * peXXigen.c (_bfd_XXi_swap_aouthdr_out): Don't clear all
+ data-directories as this might destroy content.
+
+ * coff-i386.c (_bfd_generic_find_nearest_line_discriminator):
+ define as coff_find_nearest_line_discriminator.
+ * libcoff-in.h (coff_find_nearest_line_discriminator): New
+ * libcoff.h: Regenerated.
+ * coff-x86_64.c: Likewise.
+ * coffgen.c (coff_find_nearest_line_discriminator): New function.
+ prototype.
+
+2012-10-16 Joel Brobecker <brobecker@adacore.com>
+
+ * coff64-rs6000.c (rs6000coff64_vec): Set _close_and_cleanup
+ field to _bfd_archive_close_and_cleanup.
+ (aix5coff64_vec): Likewise.
+
+2012-10-16 Joel Brobecker <brobecker@adacore.com>
+
+ * coff-rs6000.c (rs6000coff_vec): Set _close_and_cleanup
+ field to _bfd_archive_close_and_cleanup.
+ (pmac_xcoff_vec): Likewise.
+
+2012-10-16 Sofiane Naci <sofiane.naci@arm.com>
+
+ * elf64-aarch64.c (elf64_aarch64_tls_howto_table): Fix shift value for
+ R_AARCH64_TLSIE_LD_GOTTPREL_PREL19, R_AARCH64_TLSLE_MOVW_TPREL_G2,
+ R_AARCH64_TLSLE_MOVW_TPREL_G1, R_AARCH64_TLSLE_MOVW_TPREL_G1_NC,
+ R_AARCH64_TLSLE_ADD_TPREL_HI12.
+ (elf64_aarch64_tlsdesc_howto_table): Fix shift value for
+ R_AARCH64_TLSDESC_LD64_PREL19 and R_AARCH64_TLSDESC_OFF_G1.
+ (elf64_aarch64_final_link_relocate): Add signed_addend when resolving
+ AARCH64_TLSLE_*_TPREL_* relocations.
+
+2012-10-16 Alan Modra <amodra@gmail.com>
+
+ * elf32-xtensa.c (free_section_cache): Renamed from
+ clear_section_cache. Don't zero cache.
+ (section_cache_section): Remove ineffectual zero of cache.
+ Call init_section_cache instead.
+
+2012-10-15 Doug Evans <dje@google.com>
+
+ * elf.c (special_sections_d): Add comment.
+
+2012-10-13 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR bfd/14430
+ * Makefile.am (LIBDL): Replace -ldl with @lt_cv_dlopen_libs@.
+ * configure.in (lt_cv_dlopen_libs): AC_SUBST.
+ * Makefile.in: Regenerated.
+ * configure: Likewise.
+
+2012-10-08 Alan Modra <amodra@gmail.com>
+
+ PR binutils/14662
+ * elf.c (_bfd_elf_make_section_from_shdr): Treat .gdb_index as
+ SEC_DEBUGGING.
+
+2012-09-20 Walter Lee <walt@tilera.com>
+
+ * elf32-tilepro.c (tilepro_elf_relocate_section): Adjust got
+ relocations with value of hgot.
+ * elfxx-tilegx.c (tilegx_elf_relocate_section): Ditto.
+
+2012-09-19 Steve Ellcey <sellcey@mips.com>
+
+ * config.bfd: Add mips*-mti-elf* target.
+
+2012-09-18 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/14591
+ * elf-bfd.h (_bfd_elf_merge_symbol): Add an argument to return
+ if the old symbol is weak.
+
+ * elf32-sh-symbian.c (sh_symbian_relocate_section): Update
+ _bfd_elf_merge_symbol call.
+
+ * elflink.c (_bfd_elf_merge_symbol): Add an argument to return
+ if the old symbol is weak.
+ (_bfd_elf_add_default_symbol): Update _bfd_elf_merge_symbol
+ call.
+ (elf_link_add_object_symbols): Don't update symbol type from a
+ weak definition. Update symbol type from a common symbol when
+ overriding a weak symbol.
+
+2012-09-17 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf32-i386.c (elf_i386_convert_mov_to_lea): Ignore discarded
+ section.
+ * elf64-x86-64.c (elf_x86_64_convert_mov_to_lea): Likewise.
+
+2012-09-17 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf32-i386.c (elf_i386_finish_dynamic_symbol): Replace return
+ FALSE with abort.
+ * elf64-x86-64.c (elf_x86_64_finish_dynamic_symbol): Likewise.
+
+2012-09-17 Walter Lee <walt@tilera.com>
+
+ * elf32-tilepro.c (tilepro_elf_relocate_section): Remove unused
+ got_base variable.
+ * elfxx-tilegx.c (tilegx_elf_relocate_section): Ditto.
+
+2012-09-17 Walter Lee <walt@tilera.com>
+
+ * elf32-tilepro.c (tilepro_elf_relocate_section): Fix computation
+ of got relocations for when .got.plt section is merged with .got.
+ * elfxx-tilegx.c (tilegx_elf_relocate_section): Ditto.
+
+2012-09-14 David Edelsohn <dje.gcc@gmail.com>
+
+ * configure: Regenerate.
+
+2012-09-13 Anthony Green <green@moxielogic.com>
+
+ * targets.c (bfd_elf32_bigmoxie_vec, bfd_elf32_littlemoxie_vec):
+ Define.
+ (bfd_elf32_moxie_vec): Remove.
+ * config.bfd, configure.in: Add bi-endian support for moxie.
+ * configure: Rebuilt.
+ * elf32-moxie.c (TARGET_LITTLE_NAME, TARGET_LITTLE_SYM): Define.
+ (TARGET_BIG_NAME, TARGET_BIG_SYM): Update for bi-endian support.
+
+2012-09-12 Doug Kwan <dougkwan@google.com>
+
+ * elf64-ppc.c (ppc64_elf_relocate_section): Use pre-adjusted
+ relocation for stub lookup.
+
+2012-09-12 Chris Schlumberger-Socha <chris.schlumberger-socha@arm.com>
+
+ * bfd-in2.h: Regenerated.
+ * elf64-aarch64.c
+ (elf64_aarch64_howto_table): Add R_AARCH64_GOT_LD_PREL19 reloc to HOWTO.
+ (elf64_aarch64_reloc_map): Add reloc entry.
+ (aarch64_resolve_relocation): Likewise.
+ (bfd_elf_aarch64_put_addend): Likewise.
+ (aarch64_reloc_got_type): Likewise.
+ (elf64_aarch64_final_link_relocate): Likewise.
+ (lf64_aarch64_check_relocs): Likewise.
+ (elf64_aarch64_check_relocs): New case for R_AARCH64_ADR_PREL_LO21
+ reloc.
+ * libbfd.h: Regenerated.
+ * reloc.c (R_AARCH64_GOT_LD_PREL19): New reloc.
+
+2012-09-10 Matthias Klose <doko@ubuntu.com>
+
+ * config.in: Disable sanity check for kfreebsd.
+
+2012-09-10 H.J. Lu <hongjiu.lu@intel.com>
+
+ * configure: Regenerated.
+
+2012-09-04 Sergey A. Guriev <sergey.a.guriev@intel.com>
+
+ * cpu-ia64-opc.c (ins_cnt6a): New function.
+ (ext_cnt6a): Ditto.
+ (ins_strd5b): Ditto.
+ (ext_strd5b): Ditto.
+ (elf64_ia64_operands): Add new operand types.
+
+2012-09-04 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR binutils/14493
+ * elf.c (ignore_section_sym): Also ignore section symbols without
+ a BFD section.
+
+2012-09-03 Andreas Krebbel <Andreas.Krebbel@de.ibm.com>
+
+ * elf32-s390.c (elf_s390_relocate_section): Handle PLTOFF for
+ local and global ifunc symbols.
+ * elf64-s390.c (elf_s390_relocate_section): Likewise.
+
+2012-09-02 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf-bfd.h (elf_link_hash_table): Add hdynamic for the
+ _DYNAMIC symbol.
+
+ * elflink.c (_bfd_elf_link_create_dynamic_sections): Set
+ hdynamic.
+
+ * elf-m10300.c (_bfd_mn10300_elf_finish_dynamic_symbol): Check
+ hdynamic instead of "_DYNAMIC".
+ * elf32-arm.c (elf32_arm_finish_dynamic_symbol): Likewise.
+ * elf32-cr16.c (elf32_arm_finish_dynamic_symbol): Likewise.
+ * elf32-cris.c (elf_cris_finish_dynamic_symbol): Likewise.
+ * elf32-hppa.c (elf32_hppa_finish_dynamic_symbol): Likewise.
+ * elf32-i386.c (elf_i386_convert_mov_to_lea): Likewise.
+ * elf32-lm32.c (lm32_elf_finish_dynamic_symbol): Likewise.
+ * elf32-m32r.c (m32r_elf_finish_dynamic_symbol): Likewise.
+ * elf32-s390.c (elf_s390_finish_dynamic_symbol): Likewise.
+ * elf32-sh.c (sh_elf_finish_dynamic_symbol): Likewise.
+ * elf32-tic6x.c (elf32_tic6x_finish_dynamic_symbol): Likewise.
+ * elf32-tilepro.c (tilepro_elf_finish_dynamic_symbol): Likewise.
+ * elf32-vax.c (elf_vax_finish_dynamic_symbol): Likewise.
+ * elf32-xtensa.c (elf_xtensa_finish_dynamic_symbol): Likewise.
+ * elf64-aarch64.c elf64_aarch64_finish_dynamic_symbol(): Likewise.
+ * elf64-alpha.c (elf64_alpha_finish_dynamic_symbol): Likewise.
+ * elf64-ia64-vms.c (elf64_ia64_finish_dynamic_symbol): Likewise.
+ * elf64-s390.c (elf_s390_finish_dynamic_symbol): Likewise.
+ * elf64-sh64.c (sh64_elf64_finish_dynamic_symbol): Likewise.
+ * elf64-x86-64.c (elf_x86_64_convert_mov_to_lea): Likewise.
+ * elfnn-ia64.c (elfNN_ia64_finish_dynamic_symbol): Likewise.
+ * elfxx-mips.c (_bfd_mips_elf_finish_dynamic_symbol): Likewise.
+ * elfxx-sparc.c (_bfd_sparc_elf_finish_dynamic_symbol): Likewise.
+ * elfxx-tilegx.c (tilegx_elf_finish_dynamic_symbol): Likewise.
+
+ * elf32-microblaze.c (microblaze_elf_finish_dynamic_symbol): Check
+ hdynamic, hgot, hplt instead of _DYNAMIC, _GLOBAL_OFFSET_TABLE_,
+ _PROCEDURE_LINKAGE_TABLE_.
+ * elf32-score.c (s3_bfd_score_elf_finish_dynamic_symbol): Likewise.
+ * elf32-score7.c (s7_bfd_score_elf_finish_dynamic_symbol): Likewise.
+
+2012-08-31 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf32-i386.c (elf_i386_convert_mov_to_lea): Don't optimize
+ _DYNAMIC.
+ * elf64-x86-64.c (elf_x86_64_convert_mov_to_lea): Likewise.
+
+2012-08-31 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf32-i386.c (elf_i386_convert_mov_to_lea): New.
+ (elf_i386_size_dynamic_sections): Use it on input sections.
+ (elf_i386_relocate_section): Don't convert
+ "mov foo@GOT(%reg), %reg" to "lea foo@GOTOFF(%reg), %reg"
+ for local symbols here.
+
+ * elf64-x86-64.c (elf_x86_64_convert_mov_to_lea): New.
+ (elf_x86_64_size_dynamic_sections): Use it on input sections.
+ (elf_x86_64_relocate_section): Don't convert
+ "mov foo@GOTPCREL(%rip), %reg" to "lea foo(%rip), %reg"
+ for local symbols here.
+
+2012-08-30 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf32-i386.c (elf_i386_relocate_section): Convert
+ "mov foo@GOT(%reg), %reg" to "lea foo@GOTOFF(%reg), %reg"
+ for local symbols.
+
+ * elf64-x86-64.c (elf_x86_64_relocate_section): Convert
+ "mov foo@GOTPCREL(%rip), %reg" to "lea foo(%rip), %reg"
+ for local symbols.
+
+2012-08-31 Alan Modra <amodra@gmail.com>
+
+ PR ld/14464
+ * elf64-ppc.c (ppc64_elf_relocate_section): Map symbols defined
+ by a linker script in .opd to corresponding input .opd section.
+
+2012-08-28 Maciej W. Rozycki <macro@codesourcery.com>
+
+ * elf32-ppc.c (ppc_elf_relocate_section): Assert that dynindx is
+ not minus one.
+ * elf64-ppc.c (ppc64_elf_relocate_section): Likewise.
+
+2012-08-28 Maciej W. Rozycki <macro@codesourcery.com>
+
+ * elflink.c (_bfd_elf_merge_symbol): Also override the version
+ a dynamic symbol defaulted to if preempted with a hidden or
+ internal definition.
+
+2012-08-28 Walter Lee <walt@tilera.com>
+
+ * elf32-tilepro.c (allocate_dynrelocs): Use PLT_ENTRY_SIZE as size
+ of header.
+ (tilepro_plt_entry_build): Account for new header size.
+ (tilepro_elf_finish_dynamic_sections): Ditto.
+ (tilepro_elf_plt_sym_val): Ditto.
+ * elfxx-tilegx.c (allocate_dynrelocs): Use PLT_ENTRY_SIZE as size
+ of header + tail.
+ (tilegx_elf_finish_dynamic_sections): Account for new padding.
+
+2012-08-27 Walter Lee <walt@tilera.com>
+
+ * reloc.c (Add BFD_RELOC_TILEGX_IMM16_X0_HW0_PLT_PCREL,
+ BFD_RELOC_TILEGX_IMM16_X1_HW0_PLT_PCREL,
+ BFD_RELOC_TILEGX_IMM16_X0_HW1_PLT_PCREL,
+ BFD_RELOC_TILEGX_IMM16_X1_HW1_PLT_PCREL,
+ BFD_RELOC_TILEGX_IMM16_X0_HW2_PLT_PCREL,
+ BFD_RELOC_TILEGX_IMM16_X1_HW2_PLT_PCREL,
+ BFD_RELOC_TILEGX_IMM16_X0_HW3_PLT_PCREL,
+ BFD_RELOC_TILEGX_IMM16_X1_HW3_PLT_PCREL,
+ BFD_RELOC_TILEGX_IMM16_X0_HW0_LAST_PLT_PCREL,
+ BFD_RELOC_TILEGX_IMM16_X1_HW0_LAST_PLT_PCREL,
+ BFD_RELOC_TILEGX_IMM16_X0_HW1_LAST_PLT_PCREL,
+ BFD_RELOC_TILEGX_IMM16_X1_HW1_LAST_PLT_PCREL,
+ BFD_RELOC_TILEGX_IMM16_X0_HW2_LAST_PLT_PCREL,
+ BFD_RELOC_TILEGX_IMM16_X1_HW2_LAST_PLT_PCREL): new relocations.
+ * elfxx-tilegx.c (tilegx_elf_howto_table): Handle new relocations.
+ (tilegx_reloc_map): Ditto.
+ (reloc_to_create_func): Ditto.
+ (tilegx_elf_check_relocs): Ditto.
+ (tilegx_elf_gc_sweep_hook): Ditto.
+ (tilegx_elf_relocate_section): Ditto.
+ * libbfd.h: Regenerate.
+ * bfd-in2.h: Regenerate.
+
+2012-08-24 Matthew Gretton-Dann <matthew.gretton-dann@arm.com>
+
+ * elf32-arm.c (v8): New array.
+ (tag_cpu_arch_combine): Add support for ARMv8 attributes.
+ (elf32_arm_merge_eabi_attributes): Likewise.
+ (VFP_VERSION_COUNT): New define.
+
+2012-08-20 Tom Tromey <tromey@redhat.com>
+
+ * vms-lib.c (_bfd_vms_lib_get_module): Use bfd_zmalloc for
+ areltdata.
+ * opncls.c (_bfd_delete_bfd): Free arelt_data.
+ * mach-o.c (bfd_mach_o_fat_member_init): Use bfd_zmalloc for
+ areltdata.
+ * ecoff.c (_bfd_ecoff_slurp_armap): Use free for mapdata.
+ * coff-rs6000.c (_bfd_xcoff_read_ar_hdr): Use bfd_zmalloc for
+ areltdata.
+ (xcoff_write_archive_contents_old): Likewise.
+ (xcoff_write_archive_contents_big): Likewise.
+ * archive64.c (bfd_elf64_archive_slurp_armap): Use free for
+ areltdata.
+ * archive.c (_bfd_generic_read_ar_hdr_mag): Use bfd_zmalloc and
+ free for areltdata.
+ (_bfd_get_elt_at_filepos): Likewise. Clear n_nfd->arelt_data on
+ failure.
+ (do_slurp_bsd_armap): Use bfd_zmalloc and free for areltdata.
+ (do_slurp_coff_armap): Likewise.
+ (_bfd_slurp_extended_name_table): Likewise.
+ (bfd_slurp_bsd_armap_f2): Likewise. Don't leak 'mapdata'.
+
+2012-08-17 Nick Clifton <nickc@redhat.com>
+
+ * po/vi.po: Updated Vietnamese translation.
+
+2012-08-17 Yuri Chornoivan <yurchor@ukr.net>
+
+ * elf-bfd.h, * elf32-ppc.c, * elf64-ia64-vms.c, * elfnn-ia64.c,
+ * elfxx-mips.c, * vms-alpha.c: Typo fixes.
+
+2012-08-17 Alan Modra <amodra@gmail.com>
+
+ PR binutils/14475:
+ * archive.c (bfd_ar_hdr_from_filesystem): Revert last change.
+ Instead malloc areltdata.
+
+2012-08-16 Tom Tromey <tromey@redhat.com>
+
+ PR binutils/14475:
+ * archive.c (bfd_ar_hdr_from_filesystem): Allocate areltdata on
+ 'member' BFD. Don't try to free 'ared'.
+
+2012-08-14 Nick Clifton <nickc@redhat.com>
+
+ * po/uk.po: Updated Ukranian translation.
+
+2012-08-13 Maciej W. Rozycki <macro@codesourcery.com>
+
+ * elfxx-mips.c (_bfd_mips_elf_size_dynamic_sections): Look up
+ the options section in the output rather than input BFD to
+ decide if to add a DT_MIPS_OPTIONS tag.
+
+2012-08-13 Maciej W. Rozycki <macro@codesourcery.com>
+
+ * config.bfd: Wrap mips*el-*-linux* and mips*-*-linux* into
+ #ifdef BFD64.
+
+2012-08-13 Ian Bolton <ian.bolton@arm.com>
+ Laurent Desnogues <laurent.desnogues@arm.com>
+ Jim MacArthur <jim.macarthur@arm.com>
+ Marcus Shawcroft <marcus.shawcroft@arm.com>
+ Nigel Stephens <nigel.stephens@arm.com>
+ Ramana Radhakrishnan <ramana.radhakrishnan@arm.com>
+ Richard Earnshaw <rearnsha@arm.com>
+ Sofiane Naci <sofiane.naci@arm.com>
+ Tejas Belagod <tejas.belagod@arm.com>
+ Yufeng Zhang <yufeng.zhang@arm.com>
+
+ * Makefile.am: Add AArch64 files.
+ * Makefile.in: Regenerate.
+ * archures.c (bfd_aarch64_arch): New declaration.
+ (bfd_archures_list): Use bfd_archures_list.
+ * bfd-in.h (bfd_elf64_aarch64_init_maps): New declaration.
+ (bfd_aarch64_process_before_allocation): New declaration.
+ (bfd_elf64_aarch64_process_before_allocation): New declaration.
+ (bfd_elf64_aarch64_set_options): New declaration.
+ (bfd_elf64_aarch64_add_glue_sections_to_bfd): New declaration.
+ (BFD_AARCH64_SPECIAL_SYM_TYPE_MAP): New definition.
+ (BFD_AARCH64_SPECIAL_SYM_TYPE_TAG): New definition.
+ (BFD_AARCH64_SPECIAL_SYM_TYPE_OTHER): New definition.
+ (BFD_AARCH64_SPECIAL_SYM_TYPE_ANY): New definition.
+ (bfd_is_aarch64_special_symbol_name): New declaration.
+ (bfd_aarch64_merge_machines): New declaration.
+ (bfd_aarch64_update_notes): New declaration.
+ (int bfd_aarch64_get_mach_from_notes): New declaration.
+ (elf64_aarch64_setup_section_lists): New declaration.
+ (elf64_aarch64_next_input_section): New declaration.
+ (elf64_aarch64_size_stubs): New declaration.
+ (elf64_aarch64_build_stubs): New declaration.
+ * config.bfd: Add AArch64.
+ * configure.in: Add AArch64.
+ * configure: Regenerate.
+ * cpu-aarch64.c: New file.
+ * elf-bfd.h: Add AArch64.
+ * bfd-in2.h: Regenerate.
+ * libbfd.h: Regenerate.
+ * elf64-aarch64.c: New file.
+ * reloc.c: Add AArch64 relocations.
+ * targets.c: Add AArch64.
+ * po/SRC-POTFILES.in: Regenerate.
+
+2012-08-13 Maciej W. Rozycki <macro@codesourcery.com>
+
+ * elfxx-mips.c (mips_elf_calculate_relocation): Fix the handling
+ of protected symbols.
+
+2012-08-10 Alan Modra <amodra@gmail.com>
+
+ PR binutils/14444
+ * elf.c (IS_VALID_GROUP_SECTION_HEADER) Add minsize param.
+ (setup_group): Adjust uses.
+ (bfd_section_from_shdr): Allow SHT_GROUP sections with just a flag
+ word.
+
+2012-08-09 Nick Clifton <nickc@redhat.com>
+
+ * po/vi.po: Updated Vietnamese translation.
+
+2012-08-09 Maciej W. Rozycki <macro@codesourcery.com>
+
+ * elfxx-mips.c (LA25_LUI_MICROMIPS_1, LA25_LUI_MICROMIPS_2):
+ Remove macros, folding them into...
+ (LA25_LUI_MICROMIPS): ... this new macro.
+ (LA25_J_MICROMIPS_1, LA25_J_MICROMIPS_2): Likewise into...
+ (LA25_J_MICROMIPS): ... this new macro.
+ (LA25_ADDIU_MICROMIPS_1, LA25_ADDIU_MICROMIPS_2): Likewise
+ into...
+ (LA25_ADDIU_MICROMIPS): ... this new macro.
+ (bfd_put_micromips_32, bfd_get_micromips_32): New functions.
+ (mips_elf_create_la25_stub): Use them.
+ (check_br32_dslot, check_br32, check_relocated_bzc): Likewise.
+ (_bfd_mips_elf_relax_section): Likewise.
+
+2012-08-09 Alan Modra <amodra@gmail.com>
+ Tom Tromey <tromey@redhat.com>
+
+ * archive.c (SECTION Archives): Update documentation.
+ (_bfd_delete_archive_data): Remove.
+ (_bfd_add_bfd_to_archive_cache): Set 'parent_cache' and 'key'.
+ (archive_close_worker, _bfd_archive_close_and_cleanup): New
+ functions.
+ * libbfd-in.h (struct areltdata <parent_cache, key>): New fields.
+ (_bfd_delete_archive_data): Don't declare.
+ (_bfd_archive_close_and_cleanup): Declare.
+ (_bfd_generic_close_and_cleanup): Redefine.
+ * libbfd.h: Rebuild.
+ * opncls.c (_bfd_delete_bfd): Don't call _bfd_delete_archive_data.
+ (bfd_close): Don't close nested thin archives here.
+
+2012-08-07 Tom Tromey <tromey@redhat.com>
+
+ * archive.c (_bfd_delete_archive_data): New function.
+ * libbfd-in.h (_bfd_delete_archive_data): Declare.
+ * libbfd.h: Rebuild.
+ * opncls.c (_bfd_delete_bfd): Call _bfd_delete_archive_data.
+
+2012-08-07 Nick Clifton <nickc@redhat.com>
+
+ * po/uk.po: Updated Ukranian translation.
+
+2012-08-06 Maciej W. Rozycki <macro@codesourcery.com>
+
+ * elflink.c (bfd_elf_record_link_assignment): Remove --defsym
+ symbols special case.
+
+2012-08-05 Maciej W. Rozycki <macro@linux-mips.org>
+
+ * elf32-vax.c (elf_vax_adjust_dynamic_symbol): Don't allocate
+ PLT slots for local symbols.
+
+2012-08-03 Maciej W. Rozycki <macro@codesourcery.com>
+
+ * elf64-mips.c (mips16_elf64_howto_table_rela): Correct src_mask
+ field initializers throughout.
+ * elfn32-mips.c (elf_mips16_howto_table_rela): Likewise.
+
+2012-08-03 Maciej W. Rozycki <macro@codesourcery.com>
+
+ * elfxx-mips.c (mips_elf_perform_relocation): Update the
+ cross-mode jump message.
+
+2012-08-03 Maciej W. Rozycki <macro@codesourcery.com>
+
+ * elfxx-mips.c (_bfd_mips_elf_size_dynamic_sections): Update the
+ comment on DT_MIPS_RLD_MAP.
+
+2012-08-03 Tom Tromey <tromey@redhat.com>
+
+ * opncls.c (_bfd_delete_bfd): Now static.
+ * libbfd-in.h (_bfd_delete_bfd): Don't declare.
+ * libbfd.h: Rebuild.
+
+2012-08-02 Sean Keys <skeys@ipdatasys.com>
+
+ * elf32-m68hc1x.c (elf32_m68hc11_relocate_section): Modified
+ conditional statment to allow suppression of mismatched bank
+ warning.
+
+2012-08-01 Alan Modra <amodra@gmail.com>
+
+ * dwarf2.c (struct dwarf2_debug): Add close_on_cleanup.
+ (_bfd_dwarf2_slurp_debug_info): Set close_on_cleanup if we open
+ gnu_debuglink bfd.
+ (_bfd_dwarf2_cleanup_debug_info): Act on close_on_cleanup.
+
+2012-07-30 Nick Clifton <nickc@redhat.com>
+
+ * po/bfd.pot: Updated template.
+ * po/es.po: Updated Spanish translation.
+ * po/fi.po: Updated Finnish translation.
+ * po/fr.po: Updated French translation.
+ * po/ru.po: Updated Russian translation.
+ * po/uk.po: Updated Ukranian translation.
+
+2012-07-27 Mike Frysinger <vapier@gentoo.org>
+
+ * configure.in (AC_INIT): Call with the args bfd and 2.22.52.
+ (AM_INIT_AUTOMAKE): Remove args.
+ * configure: Regenerate.
+
+2012-07-27 Andreas Krebbel <Andreas.Krebbel@de.ibm.com>
+
+ * cpu-s390.c (bfd_s390_64_arch, bfd_s390_arch): Pick the default
+ arch depending on the target size.
+
+2012-07-27 Tristan Gingold <gingold@adacore.com>
+
+ * configure.in: Bump version to 2.23.51
+ * configure: Regenerate.
+
+2012-07-26 Teresa Johnson <tejohnson@google.com>
+
+ * bfd/dwarf2.c (find_line): Initialize discriminator_ptr
+ if it is non-NULL.
+
+2012-07-26 Meador Inge <meadori@codesourcery.com>
+ Nick Clifton <nickc@redhat.com>
+
+ PR ld/14397
+ * elf32-arm.c (elf32_arm_finish_dynamic_sections): Report an error
+ if a required section is missing from the linker script.
+
+2012-07-24 Jan Waclawek <konfera@efton.sk>
+ PR 13899
+ * elf32-avr.c (elf32_avr_relax_delete_bytes): Call
+ _bfd_elf_link_read_relocs with keep_memory as TRUE.
+
+2012-07-24 Teresa Johnson <tejohnson@google.com>
+
+ * bfd.c (bfd_find_nearest_line_discriminator): New macro.
+ * coff-rs6000.c: Init _bfd_find_nearest_line_discriminator.
+ * coff64-rs6000.c: Likewise.
+ * dwarf2.c (struct line_info): Add discriminator field.
+ (add_line_info): Fill in new discriminator field.
+ (decode_line_info): Record discriminator information instead
+ of ignoring it.
+ (lookup_address_in_line_info_table): Return discriminator field if
+ requested.
+ (comp_unit_find_nearest_line): Add discriminator argument.
+ (find_line): Likewise.
+ (_bfd_dwarf2_find_nearest_line): Likewise.
+ (_bfd_dwarf2_find_line): Likewise.
+ * elf-bfd.h (_bfd_elf_find_nearest_line_discriminator): New.
+ (_bfd_elf_find_line_discriminator): Likewise.
+ (_bfd_generic_find_nearest_line_discriminator): Likewise. Defined.
+ * elf.c (_bfd_elf_find_nearest_line): Change to a wrapper
+ that invokes _bfd_elf_find_nearest_line_discriminator with correct
+ arguments.
+ (_bfd_elf_find_nearest_line_discriminator): New.
+ (_bfd_elf_find_line): Change to a wrapper
+ that invokes _bfd_elf_find_line_discriminator with correct
+ arguments.
+ (_bfd_elf_find_line_discriminator): New.
+ * coffgen.c (coff_find_nearest_line_with_names): Handle
+ new discriminator argument.
+ * elf32-arm.c (elf32_arm_find_nearest_line): Likewise.
+ * elf64-alpha.c (elf64_alpha_find_nearest_line): Likewise.
+ * elfxx-mips.c (_bfd_mips_elf_find_nearest_line): Likewise.
+ * mach-o.c (bfd_mach_o_find_nearest_line): Likewise.
+ * libbfd-in.h (_bfd_dwarf2_find_nearest_line): Add discriminator
+ argument.
+ (_bfd_dwarf2_find_line): Likewise.
+ (_bfd_generic_find_nearest_line_discriminator): New.
+ * libbfd.c (_bfd_generic_find_nearest_line_discriminator): New.
+ * bfd-in2.h: Regenerated.
+ * libbfd.h: Likewise.
+ * targets.c (BFD_JUMP_TABLE_SYMBOLS): Initialize
+ _bfd_find_nearest_line_discriminator with
+ _bfd_generic_find_nearest_line_discriminator.
+ (bfd_target): Add _bfd_find_nearest_line_discriminator.
+
+2012-07-24 Sean Keys <skeys@ipdatasys.com>
+
+ * elf32-m68hc1x.c (elf32_m68hc11_relocate_section): Added code
+ that enables the linker to offset addresses, when linking against
+ symbols from the XGATE processor and vice versa.
+
+2012-07-23 Nick Clifton <nickc@redhat.com>
+
+ * cisco-core.c (cisco_core_file_failing_command): Make static.
+ (cisco_core_file_failing_signal): Make static.
+
+2012-07-18 H.J. Lu <hongjiu.lu@intel.com>
+
+ * bfd-in2.h: Regenerated.
+
+2012-07-18 Nicolàs Alejandro Di Risio <sheeva@tiscali.it>
+
+ PR binutils/14335
+ * section.c: Fix a typo in comments.
+
+2012-07-13 Andreas Krebbel <Andreas.Krebbel@de.ibm.com>
+
+ * elf64-s390.c: Include elf-s390-common.c.
+ (R_390_IRELATIVE): New reloc.
+ (elf_s390_reloc_type_lookup): Support R_390_IRELATIVE.
+ (RELA_ENTRY_SIZE): New macro.
+ (elf_s390_link_hash_entry): New fields ifunc_resolver_address and
+ *ifunc_resolver_section.
+ (struct plt_entry): New struct.
+ (struct elf_s390_obj_tdata): New field local_plt.
+ (elf_s390_local_plt): New macro.
+ (struct elf_s390_link_hash_table): New field irelifunc.
+ (ELF64): New macro.
+ (link_hash_newfunc): Initialize new fields.
+ (elf_s390_check_relocs): Handle IFUNC symbols.
+ (elf_s390_adjust_dynamic_symbol): Don't do anything for IFUNC
+ symbols.
+ (allocate_dynrelocs): Call s390_elf_allocate_ifunc_dyn_relocs for
+ IFUNC symbols.
+ (elf_s390_size_dynamic_sections): Handle IFUNC symbols.
+ (elf_s390_relocate_section): Likewise.
+ (elf_s390_finish_dynamic_symbol): Likewise.
+ (elf_s390_finish_dynamic_sections): Handle local IFUNC symbols.
+ (elf_s390_finish_ifunc_symbol): New function.
+ (elf_s390_gc_sweep_hook): Handle local plt entries.
+ (elf_backend_add_symbol_hook): Define.
+ * elf32-s390.c: See elf64-s390.c changes.
+ * elf-s390-common.c: New file.
+ * bfd-in2.h (BFD_RELOC_390_IRELATIVE): New enum field.
+ * libbfd.h (BFD_RELOC_390_IRELATIVE): New entry for
+ BFD_RELOC_390_IRELATIVE.
+ * reloc.c (BFD_RELOC_390_IRELATIVE): Document new relocation.
+
+2012-07-13 Nick Clifton <nickc@redhat.com>
+
+ * aix386-core.c: Remove use of PTR and PARAMS macros.
+ * archive.c: Likewise.
+ * cache.c: Likewise.
+ * cisco-core.c: Likewise.
+ * coff-alpha.c: Likewise.
+ * coff-apollo.c: Likewise.
+ * coff-aux.c: Likewise.
+ * coff-h8300.c: Likewise.
+ * coff-h8500.c: Likewise.
+ * coff-i386.c: Likewise.
+ * coff-i960.c: Likewise.
+ * coff-ia64.c: Likewise.
+ * coff-m68k.c: Likewise.
+ * coff-m88k.c: Likewise.
+ * coff-mcore.c: Likewise.
+ * coff-mips.c: Likewise.
+ * coff-or32.c: Likewise.
+ * coff-ppc.c: Likewise.
+ * coff-rs6000.c: Likewise.
+ * coff-sh.c: Likewise.
+ * coff-sparc.c: Likewise.
+ * coff-stgo32.c: Likewise.
+ * coff-tic30.c: Likewise.
+ * coff-tic4x.c: Likewise.
+ * coff-tic54x.c: Likewise.
+ * coff-tic80.c: Likewise.
+ * coff-w65.c: Likewise.
+ * cofflink.c: Likewise.
+ * cpu-arc.c: Likewise.
+ * cpu-cris.c: Likewise.
+ * cpu-h8500.c: Likewise.
+ * cpu-i960.c: Likewise.
+ * cpu-msp430.c: Likewise.
+ * cpu-ns32k.c: Likewise.
+ * cpu-powerpc.c: Likewise.
+ * cpu-rs6000.c: Likewise.
+ * cpu-tic4x.c: Likewise.
+ * cpu-w65.c: Likewise.
+ * ecoff.c: Likewise.
+ * ecofflink.c: Likewise.
+ * elf-m10200.c: Likewise.
+ * elf32-bfin.c: Likewise.
+ * elf32-cris.c: Likewise.
+ * elf32-crx.c: Likewise.
+ * elf32-fr30.c: Likewise.
+ * elf32-frv.c: Likewise.
+ * elf32-h8300.c: Likewise.
+ * elf32-i960.c: Likewise.
+ * elf32-m32c.c: Likewise.
+ * elf32-m68hc11.c: Likewise.
+ * elf32-m68hc12.c: Likewise.
+ * elf32-m68hc1x.c: Likewise.
+ * elf32-m68k.c: Likewise.
+ * elf32-mcore.c: Likewise.
+ * elf32-rl78.c: Likewise.
+ * elf32-rx.c: Likewise.
+ * elf32-s390.c: Likewise.
+ * elf32-vax.c: Likewise.
+ * elf64-alpha.c: Likewise.
+ * elf64-mmix.c: Likewise.
+ * elf64-s390.c: Likewise.
+ * elf64-sparc.c: Likewise.
+ * elfnn-ia64.c: Likewise.
+ * elfxx-mips.c: Likewise.
+ * elfxx-sparc.c: Likewise.
+ * hash.c: Likewise.
+ * hp300hpux.c: Likewise.
+ * hppabsd-core.c: Likewise.
+ * hpux-core.c: Likewise.
+ * i386dynix.c: Likewise.
+ * i386linux.c: Likewise.
+ * i386lynx.c: Likewise.
+ * i386mach3.c: Likewise.
+ * i386msdos.c: Likewise.
+ * i386os9k.c: Likewise.
+ * irix-core.c: Likewise.
+ * lynx-core.c: Likewise.
+ * m68klinux.c: Likewise.
+ * mach-o.h: Likewise.
+ * mipsbsd.c: Likewise.
+ * netbsd-core.c: Likewise.
+ * nlm32-i386.c: Likewise.
+ * osf-core.c: Likewise.
+ * pc532-mach.c: Likewise.
+ * pef.c: Likewise.
+ * ppcboot.c: Likewise.
+ * ptrace-core.c: Likewise.
+ * reloc16.c: Likewise.
+ * sco5-core.c: Likewise.
+ * som.h: Likewise.
+ * sparclinux.c: Likewise.
+ * sparclynx.c: Likewise.
+ * ticoff.h: Likewise.
+ * trad-core.c: Likewise.
+ * vms-lib.c: Likewise.
+ * xsym.h: Likewise.
+
+2012-07-09 Alan Modra <amodra@gmail.com>
+
+ PR ld/14323
+ * elflink.c (elf_sort_symbol): Sort by size too.
+ (elf_link_add_object_symbols <weakdefs>): Simplify binary search.
+ Do not depend on ordering of symbol aliases. Match largest size.
+
+2012-07-03 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf.c (assign_section_numbers): Check if number of sections
+ >= SHN_LORESERVE.
+ * elfcode.h (elf_object_p): Likewise.
+
+2012-07-03 Nick Clifton <nickc@redhat.com>
+
+ * archive.c (bsd_write_armap): Catch attempts to create an archive
+ with indicies bigger than 4Gb.
+ (coff_write_armap): Likewise.
+
+2012-07-03 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR binutils/14319
+ * elf.c (_bfd_elf_make_section_from_shdr): Don't compress empty
+ debug section.
+
+2012-07-03 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/3351
+ * elflink.c (_bfd_elf_update_dynamic_flags): New.
+ (_bfd_elf_merge_symbol): Update both real and indirect symbol
+ dynamic flags.
+ (_bfd_elf_add_default_symbol): Make the real symbol dynamic if
+ the indirect symbol is defined in a shared library.
+ (elf_link_add_object_symbols): Likewise. If the indirect
+ symbol has been forced local, don't make the real symbol
+ dynamic.
+ (elf_link_check_versioned_symbol): Check indirect symbol.
+ (elf_link_output_extsym): Use real symbol definition when
+ reporting indirect symbol error. Check version info for
+ dynamic versioned symbol.
+
+2012-07-03 Alan Modra <amodra@gmail.com>
+
+ PR ld/14207
+ * elf.c (assign_file_positions_for_load_sections): Remove assertions
+ that only PT_LOAD headers include file header and section headers.
+ (assign_file_positions_for_non_load_sections): Similarly don't
+ assert PT_GNU_RELRO header does not include file and section headers.
+ Compare first section vma rather than PT_LOAD p_vaddr against
+ relro_start when looking for PT_LOAD covering PT_GNU_RELRO. Replace
+ abort with assertion.
+
+2012-07-02 Alan Modra <amodra@gmail.com>
+
+ * elf32-m32c.c (m32c_elf_check_relocs): Use bfd_make_section
+ "anyway" variant when creating .plt.
+ (m32c_elf_relax_plt_section): Remove redundant test and unused param.
+ (m32c_elf_relax_section): Test SEC_LINKER_CREATED before calling
+ m32c_elf_relax_plt_section.
+ * elfxx-mips.c (mips_elf_create_got_section): Use make anyway variant
+ when creating .got and .got.plt.
+ (_bfd_mips_elf_final_link): Likewise for .rtproc, and use
+ bfd_get_linker_section.
+ * sunos.c: Similarly throughout.
+
+2012-07-01 Andreas Schwab <schwab@linux-m68k.org>
+
+ * elf.c (_bfd_elf_make_section_from_shdr): Fix typo in error
+ message.
+
+2012-06-29 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf64-x86-64.c (elf_x86_64_relocate_section): Return FALSE
+ on unresolvable relocation.
+
+2012-06-29 H.J. Lu <hongjiu.lu@intel.com>
+
+ * archive.c (_bfd_compute_and_write_armap): Simplify global
+ symbol handling.
+
+2012-06-29 Nick Clifton <nickc@redhat.com>
+
+ PR ld/14189
+ * elf32-arm.c (elf32_arm_check_relocs): Do not increment refcount
+ for locally bound symbols.
+
+2012-06-29 Alan Modra <amodra@gmail.com>
+
+ * section.c (bfd_get_linker_section): New function.
+ * elf32-arm.c: When retrieving SEC_LINKER_CREATED sections, use
+ the above throughout rather than bfd_get_section_by_name. Use
+ bfd_make_section_anyway rather than bfd_make_section when creating
+ them.
+ * elf32-bfin.c: Likewise.
+ * elf32-cr16.c: Likewise.
+ * elf32-cris.c: Likewise.
+ * elf32-frv.c: Likewise.
+ * elf32-hppa.c: Likewise.
+ * elf32-i370.c: Likewise.
+ * elf32-i386.c: Likewise.
+ * elf32-lm32.c: Likewise.
+ * elf32-m32c.c: Likewise.
+ * elf32-m32r.c: Likewise.
+ * elf32-m68k.c: Likewise.
+ * elf32-microblaze.c: Likewise.
+ * elf32-ppc.c: Likewise.
+ * elf32-rl78.c: Likewise.
+ * elf32-s390.c: Likewise.
+ * elf32-score.c: Likewise.
+ * elf32-score7.c: Likewise.
+ * elf32-sh.c: Likewise.
+ * elf32-tic6x.c: Likewise.
+ * elf32-tilepro.c: Likewise.
+ * elf32-vax.c: Likewise.
+ * elf32-xstormy16.c: Likewise.
+ * elf32-xtensa.c: Likewise.
+ * elf64-alpha.c: Likewise.
+ * elf64-hppa.c: Likewise.
+ * elf64-ia64-vms.c: Likewise.
+ * elf64-ppc.c: Likewise.
+ * elf64-s390.c: Likewise.
+ * elf64-sh64.c: Likewise.
+ * elf64-sparc.c: Likewise.
+ * elf64-x86-64.c: Likewise.
+ * elfnn-ia64.c: Likewise.
+ * elfxx-mips.c: Likewise.
+ * elfxx-sparc.c: Likewise.
+ * elfxx-tilegx.c: Likewise.
+ * elflink.c: Likewise.
+ * elf-vxworks.c: Likewise.
+ * elf-m10300.c: Likewise. Also make use of htab plt, got and
+ gotplt shortcuts.
+ * bfd-in2.h: Regenerate.
+ * elf32-lm32.c (lm32_elf_check_relocs): Use the correct bfd when
+ calling create_rofixup_section.
+ * elflink.c (bfd_elf_final_link): Simplify test for .dynstr.
+
+2012-06-29 Alan Modra <amodra@gmail.com>
+
+ * elf32-sh.c (sh_elf_create_dynamic_sections): Don't create .rela
+ section for bss type sections, except for .rela.bss.
+ * elf-m10300.c (_bfd_mn10300_elf_create_dynamic_sections): Likewise.
+ * elf32-cr16.c (_bfd_cr16_elf_create_dynamic_sections): Likewise.
+ * elf32-lm32.c (lm32_elf_create_dynamic_sections): Likewise.
+ * elf32-m32r.c (m32r_elf_create_dynamic_sections): Likewise.
+ * elf64-sh64.c (sh64_elf64_create_dynamic_sections): Likewise.
+
+2012-06-28 Roland McGrath <mcgrathr@google.com>
+
+ * elf32-arm.c (elf32_arm_populate_plt_entry): Use int32_t for
+ displacement calculation in nacl_p case.
+
+2012-06-28 Nick Clifton <nickc@redhat.com>
+
+ * po/uk.po: New Ukranian translation.
+ * configure.in (ALL_LINGUAS): Add uk.
+ * configure: Regenerate.
+
+2012-06-26 Alan Modra <amodra@gmail.com>
+
+ * elf64-ppc.c (ppc64_elf_next_toc_section): Don't error if input
+ file has multiple .got/.toc sections and all don't fit in
+ current toc group.
+
+2012-06-22 Roland McGrath <mcgrathr@google.com>
+
+ * elf.c (assign_file_positions_for_non_load_sections): Define
+ __ehdr_start symbol if it's referenced and there's a PT_LOAD
+ segment that covers both the file and program headers.
+
+2012-06-22 Andreas Schwab <schwab@linux-m68k.org>
+
+ * elf32-m68k.c (elf_m68k_finish_dynamic_symbol): Don't make
+ _GLOBAL_OFFSET_TABLE_ and _DYNAMIC absolute.
+
+2012-06-22 Alan Modra <amodra@gmail.com>
+
+ * elf64-ppc.c (ppc64_elf_func_desc_adjust): Don't emit out-of-line
+ save/restore functions when relocatable. Make "funcs" static.
+
+2012-06-18 Hans-Peter Nilsson <hp@axis.com>
+
+ * elf32-cris.c (cris_elf_plt_sym_val): Rewrite to work in presence
+ of merged .got and .got.plt entries.
+
+2012-06-18 John Szakmeister <john@szakmeister.net>
+
+ * elf32-arm.c (elf32_arm_final_link_relocate): Correct return value.
+
+2012-06-17 Hans-Peter Nilsson <hp@axis.com>
+
+ * elf32-cris.c (cris_elf_relocate_section): <R_CRIS_32_IE>
+ <R_CRIS_32_GOT_TPREL, R_CRIS_16_GOT_TPREL>: Handle references to
+ thread common symbols.
+
+2012-06-13 Nick Clifton <nickc@redhat.com>
+
+ * elf32-arm.c (bfd_arm_get_mach_from_attributes): New function.
+ (elf32_arm_object_p): If the machine number could not be deduced
+ from the notes, call bfd_arm_get_mach_from_attributes to get the
+ number from the attributes.
+
+2012-06-12 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR bfd/14207
+ * elf.c (assign_file_positions_for_non_load_sections): Abort if
+ PT_GNU_RELRO segment doesn't fit in PT_LOAD segment.
+
+2012-06-12 Alan Modra <amodra@gmail.com>
+
+ PR ld/14207
+ * elf.c (_bfd_elf_map_sections_to_segments): Disregard bss type
+ sections at end of PT_LOAD segment when searching for segment
+ that contains end of relro extent.
+
+2012-06-11 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf.c (assign_file_positions_for_non_load_sections): Reindent.
+
+2012-06-11 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf.c (_bfd_elf_map_sections_to_segments): Reindent.
+
+2012-06-06 Alan Modra <amodra@gmail.com>
+
+ * elflink.c (elf_link_input_bfd): Provide a file symbol for
+ each input file with local syms, if the input lacks such.
+ (bfd_elf_final_link): Add a file symbol to mark end of locals
+ for which we can associate with input files.
+ (struct elf_final_link_info): Add filesym_count field.
+ (struct elf_outext_info): Add need_second_pass and second_pass.
+ (elf_link_output_extsym): Detect symbols defined in the output
+ file, emit them on second pass over locals.
+
+2012-06-04 Jan Kratochvil <jan.kratochvil@redhat.com>
+
+ * bfd-in.h (bfd_elf_bfd_from_remote_memory): Make LEN argument
+ of target_read_memory as bfd_size_type.
+ * bfd-in2.h: Regenerate.
+ * elf-bfd.h (elf_backend_bfd_from_remote_memory): Make LEN
+ argument of target_read_memory as bfd_size_type.
+ (_bfd_elf32_bfd_from_remote_memory): Likewise.
+ (_bfd_elf64_bfd_from_remote_memory): Likewise.
+ * elf.c (bfd_elf_bfd_from_remote_memory): Likewise.
+ * elfcode.h (NAME(_bfd_elf,bfd_from_remote_memory)): Likewise.
+
+2012-06-03 Alan Modra <amodra@gmail.com>
+
+ PR binutils/13897
+ * elf.c (elf_find_function): Cache last function sym info.
+ (_bfd_elf_maybe_function_sym): Return function size, pass in
+ section of interest.
+ * elf-bfd.h (struct elf_backend_data <maybe_function_sym>): Likewise.
+ (_bfd_elf_maybe_function_sym): Likewise.
+ * elf64-ppc.c (ppc64_elf_maybe_function_sym): Likewise.
+ (opd_entry_value): Add in_code_sec param. Revert caching code.
+ Return -1 if in_code_sec and function found in wrong section.
+ Update all calls.
+
+2012-06-01 Siddhesh Poyarekar <siddhesh@redhat.com>
+
+ * bfd-in.h (bfd_elf_bfd_from_remote_memory): Make LEN argument
+ of target_read_memory as size_t.
+ * bfd-in2.h: Regenerate.
+ * elf-bfd.h (elf_backend_bfd_from_remote_memory): Make LEN
+ argument of target_read_memory as size_t.
+ (_bfd_elf32_bfd_from_remote_memory): Likewise.
+ (_bfd_elf64_bfd_from_remote_memory): Likewise.
+ * elf.c (bfd_elf_bfd_from_remote_memory): Likewise.
+ * elfcode.h (NAME(_bfd_elf,bfd_from_remote_memory)): Likewise.
+
+2012-06-01 Alan Modra <amodra@gmail.com>
+
+ PR binutils/13897
+ * elf64-ppc.c (opd_entry_value): Rewrite cache code.
+
+2012-05-29 Tom Tromey <tromey@redhat.com>
+
+ * opncls.c (bfd_fopen): Always close fd on failure.
+ (bfd_fdopenr): Likewise.
+
+2012-05-27 Alan Modra <amodra@gmail.com>
+
+ PR ld/14170
+ * elflink.c (_bfd_elf_merge_symbol): When a symbol defined in
+ a dynamic library finds a new instance with non-default
+ visibility in a regular object, correctly handle symbols
+ already on the undefs list and undo dynamic symbol state when
+ the new symbol is hidden or internal.
+
+2012-05-25 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf32-i386.c (elf_i386_create_dynamic_sections): Don't use
+ dynamic_sec_flags to create PLT .eh_frame section.
+ * elf64-x86-64.c (elf_x86_64_create_dynamic_sections): Likewise.
+
+2012-05-25 Alan Modra <amodra@gmail.com>
+
+ PR ld/13909
+ * elf-eh-frame.c (_bfd_elf_eh_frame_present): New function.
+ (_bfd_elf_maybe_strip_eh_frame_hdr): Use it here.
+ * elf-bfd.h (_bfd_elf_eh_frame_present): Declare.
+ * elflink.c (bfd_elf_size_dynamic_sections): Let the backend
+ size dynamic sections before stripping eh_frame_hdr.
+ (bfd_elf_gc_sections): Handle multiple .eh_frame sections.
+ * elf32-ppc.c (ppc_elf_size_dynamic_sections): Drop glink_eh_frame
+ if no other .eh_frame sections exist.
+ * elf64-ppc.c (ppc64_elf_size_stubs): Likewise.
+ * elf32-i386.c (elf_i386_create_dynamic_sections): Don't size
+ or alloc plt_eh_frame here..
+ (elf_i386_size_dynamic_sections): ..do it here instead. Don't
+ specially keep sgotplt, iplt, tgotplt, sdynbss for symbols.
+ (elf_i386_finish_dynamic_sections): Check plt_eh_frame->contents
+ before writing plt offset.
+ * elf64-x86-64.c (elf_x86_64_create_dynamic_sections): Don't size
+ or alloc plt_eh_frame here..
+ (elf_x86_64_size_dynamic_sections): ..do it here instead.
+ (elf_x86_64_finish_dynamic_sections): Check plt_eh_frame->contents
+ before writing plt offset.
+
+2012-05-24 Alan Modra <amodra@gmail.com>
+
+ PR ld/14158
+ * elf64-ppc.c (ppc64_elf_size_stubs): Round up glink_eh_frame
+ size to output section alignment.
+ (ppc64_elf_build_stubs): Likewise, and extend last FDE to cover.
+
+2012-05-23 Alan Modra <amodra@gmail.com>
+
+ * elf-eh-frame.c (_bfd_elf_maybe_strip_eh_frame_hdr): Handle
+ BFDs with multiple .eh_frame sections.
+
+2012-05-23 Alan Modra <amodra@gmail.com>
+
+ PR ld/13909
+ * elflink.c (bfd_elf_discard_info): Don't ignore dynamic BFDs.
+
+2012-05-22 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/13909
+ * elf32-i386.c (elf_i386_create_dynamic_sections): Revert the
+ last change.
+ * elf64-x86-64.c (elf_x86_64_create_dynamic_sections): Likewise.
+
+2012-05-22 Alan Modra <amodra@gmail.com>
+
+ * elflink.c (bfd_elf_discard_info): Look for next .eh_frame if
+ first one is zero size or discarded.
+ * elf32-ppc.c (ppc_elf_size_dynamic_sections): Set most of
+ glink_eh_frame contents here..
+ (ppc_elf_finish_dynamic_sections): ..rather than here. Just set
+ offset to .glink.
+
+2012-05-22 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/13909
+ * elf32-i386.c (elf_i386_create_dynamic_sections): Create PLT
+ eh_frame section if there is an input .eh_frame section.
+ * elf64-x86-64.c (elf_x86_64_create_dynamic_sections): Likewise.
+
+2012-05-22 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/14105
+ * elf32-i386.c (elf_i386_create_dynamic_sections): Always
+ create PLT eh_frame section with SEC_LINKER_CREATED.
+ * elf64-x86-64.c (elf_x86_64_create_dynamic_sections): Likewise.
+
+2012-05-22 Alan Modra <amodra@gmail.com>
+
+ * elflink.c (bfd_elf_discard_info): Handle multiple .eh_frame
+ sections attached to a BFD.
+ * section.c (bfd_get_section_by_name): Rewrite description.
+ (bfd_get_next_section_by_name): New function.
+ * bfd-in2.h: Regenerate.
+
+2012-05-21 Andreas Schwab <schwab@linux-m68k.org>
+
+ * elf32-m68k.c (elf_m68k_grok_prstatus): New function.
+ (elf_m68k_grok_psinfo): New function.
+ (elf_backend_grok_prstatus): Define.
+ (elf_backend_grok_psinfo): Define.
+
+2012-05-19 Maciej W. Rozycki <macro@linux-mips.org>
+
+ * elf64-mips.c (elf_backend_got_header_size): Correct definition.
+ * elfxx-mips.c (_bfd_mips_elf_adjust_dynamic_symbol): Use the ELF
+ backend's GOT header size instead of hardcoding it.
+
+2012-05-19 Maciej W. Rozycki <macro@linux-mips.org>
+
+ * elf32-vax.c (elf_vax_relocate_section)
+ <R_VAX_8, R_VAX_16, R_VAX_32>: Don't check if info->shared again.
+
+2012-05-19 Maciej W. Rozycki <macro@linux-mips.org>
+
+ * elf32-vax.c (elf_vax_relocate_section)
+ <R_VAX_8, R_VAX_16, R_VAX_32>: Use section flags rather than
+ its name as the check for text sections.
+
+2012-05-19 Maciej W. Rozycki <macro@linux-mips.org>
+
+ * elf64-mips.c (mips_elf64_be_swap_reloc_out): Also make sure
+ the third reloc offset is the same as the first.
+
+2012-05-19 Alan Modra <amodra@gmail.com>
+
+ * elf32-ppc.h (has_vle_insns, is_ppc_vle): Delete.
+ (has_tls_reloc, has_tls_get_addr_call): Move back to..
+ * elf32-ppc.c: ..here.
+ (ppc_elf_section_flags, elf_backend_section_flags): Delete.
+ (ppc_elf_modify_segment_map): Use ELF sh_flags to detect VLE sections.
+
+2012-05-18 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf32-i386.c (elf_i386_finish_dynamic_symbol): Don't make
+ _DYNAMIC nor _GLOBAL_OFFSET_TABLE_ absolute.
+ * elf64-x86-64.c (elf_x86_64_finish_dynamic_symbol): Likewise.
+
+2012-05-18 Roland McGrath <mcgrathr@google.com>
+
+ * archive.c (_bfd_generic_read_ar_hdr_mag): Fix last change so as
+ not to clobber the ar_fmag field stored in ARED->arch_header.
+
+2012-05-18 Pedro Alves <palves@redhat.com>
+
+ * mach-o.h: Don't include sysdep.h.
+
+2012-05-18 Nick Clifton <nickc@redhat.com>
+
+ PR 14072
+ * bfd-in.h: Check for PACKAGE or PACKAGE_VERSION before
+ complaining about config.h not having been included.
+ * bfd-in2.h: Regenerate.
+
+2012-05-18 Andreas Schwab <schwab@linux-m68k.org>
+
+ * aclocal.m4: Regenerate.
+ * Makefile.in: Regenerate.
+
+2012-05-17 Daniel Richard G. <skunk@iskunk.org>
+ Nick Clifton <nickc@redhat.com>
+
+ PR 14072
+ * configure.in: Add check that sysdep.h has been included before
+ any system header files.
+ * configure: Regenerate.
+ * config.in: Regenerate.
+ * aclocal.m4: Regenerate.
+ * bfd-in.h: Generate an error if included before config.h.
+ * sysdep.h: Likewise.
+ * bfd-in2.h: Regenerate.
+ * compress.c: Remove #include "config.h".
+ * plugin.c: Likewise.
+ * elf32-m68hc1x.c: Include sysdep.h before alloca-conf.h.
+ * elf64-hppa.c: Likewise.
+ * som.c: Likewise.
+ * xsymc.c: Likewise.
+
+2012-05-17 Maciej W. Rozycki <macro@linux-mips.org>
+ Alan Modra <amodra@gmail.com>
+
+ * elf.c (ignore_section_sym): Correct comment. Don't return
+ true for absolute section.
+ (elf_map_symbols): Move stray comment. Adjust for above change.
+ Don't discard global section symbols.
+
+2012-05-17 Alan Modra <amodra@gmail.com>
+
+ * elf32-ppc.c (ppc_elf_finish_dynamic_symbol): Don't make _DYNAMIC,
+ _GLOBAL_OFFSET_TABLE_ or _PROCEDURE_LINKAGE_TABLE_ absolute.
+ * elf64-ppc.c (ppc64_elf_finish_dynamic_symbol): Don't make _DYNAMIC
+ absolute.
+
+2012-05-17 Alan Modra <amodra@gmail.com>
+
+ * elf32-ppc.c (has_tls_reloc, has_tls_get_addr_call, has_vle_insns,
+ is_ppc_vle): Move to..
+ * elf32-ppc.h: ..here, making is_ppc_vle a macro.
+
+2012-05-16 Sergio Durigan Junior <sergiodj@redhat.com>
+
+ * bfd-in.h (bfd_get_section_name, bfd_get_section_vma,
+ bfd_get_section_lma, bfd_get_section_alignment,
+ bfd_get_section_flags, bfd_get_section_userdata): Rewrite macros
+ in order to use the `bfd' argument.
+ * bfd-in2.h: Regenerate.
+ * elf-vxworks.c (elf_vxworks_finish_dynamic_entry): Pass proper `bfd'
+ as the first argument for `bfd_get_section_alignment'.
+ * elf32-arm.c (create_ifunc_sections): Likewise, for
+ `bfd_set_section_alignment'.
+ * elf32-m32r.c (m32r_elf_relocate_section): Likewise, for
+ `bfd_get_section_name'.
+ * elf32-microblaze.c (microblaze_elf_relocate_section): Likewise.
+ * elf32-ppc.c (ppc_elf_size_dynamic_sections): Likewise.
+ (ppc_elf_relocate_section): Likewise.
+ * elf64-mmix.c (mmix_final_link_relocate): Likewise, for
+ `bfd_get_section_vma'.
+ * elf64-ppc.c (create_linkage_sections): Likewise, for
+ `bfd_set_section_alignment'.
+
+2012-05-16 Georg-Johann Lay <avr@gjlay.de>
+
+ PR target/13503
+ * reloc.c: Rename BFD_RELOC_AVR_8_HHI to BFD_RELOC_AVR_8_HLO.
+ * bfd-in2.h: Regenerate.
+ * libbfd.h: Regenerate.
+ * elf32-avr.c (elf_avr_howto_table): Rename R_AVR_8_HHI8 to
+ R_AVR_8_HLO8.
+ (avr_reloc_map): Likewise.
+
+2012-05-16 Daniel Richard G. <skunk@iskunk.org>
+
+ PR binutils/13558
+ * bfd/aout-cris.c: Include sysdep.h before bfd.h.
+ * bfd/aout-ns32k.c: Likewise.
+ * bfd/aout-sparcle.c: Likewise.
+ * bfd/aout0.c: Likewise.
+ * bfd/bfd-in2.h: Likewise.
+ * bfd/coff-stgo32.c: Likewise.
+ * bfd/cpu-lm32.c: Likewise.
+ * bfd/cpu-microblaze.c: Likewise.
+ * bfd/cpu-score.c: Likewise.
+ * bfd/cpu-tilegx.c: Likewise.
+ * bfd/cpu-tilepro.c: Likewise.
+ * bfd/elf32-lm32.c: Likewise.
+ * bfd/elf32-microblaze.c: Likewise.
+ * bfd/elf32-score7.c: Likewise.
+ * bfd/elf32-tilepro.c: Likewise.
+ * bfd/elfxx-tilegx.c: Likewise.
+ * bfd/mach-o.h: Likewise.
+ * bfd/nlm32-ppc.c: Likewise.
+ * bfd/ns32knetbsd.c: Likewise.
+ * bfd/pef.h: Likewise.
+ * bfd/plugin.c: Likewise.
+ * bfd/stab-syms.c: Likewise.
+ * bfd/sunos.c: Likewise.
+ * bfd/syms.c: Likewise.
+ * bfd/xsym.h: Likewise.
+
+2012-05-16 Alan Modra <amodra@gmail.com>
+
+ * elflink.c: Rename flaginfo to flinfo throughout, except..
+ (bfd_elf_lookup_section_flags): ..here, rename finfo to flaginfo.
+ Formatting, style. Simplify flag match.
+
+2012-05-16 Alan Modra <amodra@gmail.com>
+
+ * dwarf2.c: Formatting.
+ (arange_add): Pass in unit rather than bfd. Update callers.
+ Ignore empty ranges. Don't ask for cleared memory.
+ (parse_comp_unit): Only set unit->base_address if processing
+ DW_TAG_compile_unit.
+ (find_debug_info): Optimise section lookup.
+ (place_sections): Use bfd_alloc for stash->adjusted_sections.
+ (find_line): Match previously parsed comp unit addresses as we
+ do for newly parsed comp units.
+
+2012-05-16 Alan Modra <amodra@gmail.com>
+
+ * archive.c (_bfd_generic_read_ar_hdr_mag): Ensure sscanf
+ stops at end of ar_size field.
+
+2012-05-16 Alan Modra <amodra@gmail.com>
+
+ PR ld/13962
+ PR ld/7023
+ * elf.c (bfd_section_from_shdr): Fail when .dynsym sh_info is
+ out of range. As a special case, fix sh_info for zero sh_size.
+ Do the same for .symtab.
+
+2012-05-15 James Murray <jsm@jsm-net.demon.co.uk>
+ Stephane Carrez <stcarrez@nerim.fr>
+
+ * archures.c: Add bfd_arch_m9s12x and bfd_arch_m9s12xg.
+ * config.bfd: Likewise.
+ * cpu-m9s12x.c: New.
+ * cpu-m9s12xg.c: New.
+ * elf32-m68hc12.c: Add S12X and XGATE co-processor support.
+ Add option to offset S12 addresses into XGATE memory space.
+ Fix carry bug in IMM16 (IMM8 low/high) relocate.
+ * Makefile.am (ALL_MACHINES): Add cpu-m9s12x and cpu-m9s12xg.
+ (ALL_MACHINES_CFILES): Likewise.
+ * reloc.c: Add S12X relocs.
+ * Makefile.in: Regenerate.
+ * bfd-in2.h: Regenerate.
+ * libbfd.h: Regenerate.
+
+2012-05-14 James Lemke <jwlemke@codesourcery.com>
+ Catherine Moore <clm@codesourcery.com>
+
+ * bfd.c (bfd_lookup_section_flags): Add section parm.
+ * ecoff.c (bfd_debug_section): Remove flag_info initializer.
+ * elf-bfd.h (bfd_elf_section_data): Move in section_flag_info.
+ (bfd_elf_lookup_section_flags): Add section parm.
+ * elf32-ppc.c (is_ppc_vle): New function.
+ (ppc_elf_modify_segment_map): New function.
+ (elf_backend_modify_segment_map): Define.
+ (has_vle_insns): New define.
+ * elf32-ppc.h (ppc_elf_modify_segment_map): Declare.
+ * elflink.c (bfd_elf_lookup_section_flags): Add return value & parm.
+ Move in logic to omit / include a section.
+ * libbfd-in.h (bfd_link_info): Add section parm.
+ (bfd_generic_lookup_section_flags): Likewise.
+ * reloc.c (bfd_generic_lookup_section_flags): Likewise.
+ * section.c (bfd_section): Move out section_flag_info.
+ (BFD_FAKE_SECTION): Remove flag_info initializer.
+ * targets.c (_bfd_lookup_section_flags): Add section parm.
+
+2012-05-14 Catherine Moore <clm@codesourcery.com>
+
+ * archures.c (bfd_mach_ppc_vle): New.
+ * bfd-in2.h: Regenerated.
+ * cpu-powerpc.c (bfd_powerpc_archs): New entry for vle.
+ * elf32-ppc.c (split16_format_type): New enumeration.
+ (ppc_elf_vle_split16): New function.
+ (HOWTO): Add entries for R_PPC_VLE relocations.
+ (ppc_elf_reloc_type_lookup): Handle PPC_VLE relocations.
+ (ppc_elf_section_flags): New function.
+ (ppc_elf_lookup_section_flags): New function.
+ (ppc_elf_section_processing): New function.
+ (ppc_elf_check_relocs): Handle PPC_VLE relocations.
+ (ppc_elf_relocation_section): Likewise.
+ (elf_backend_lookup_section_flags_hook): Define.
+ (elf_backend_section_flags): Define.
+ (elf_backend_section_processing): Define.
+ * elf32-ppc.h (ppc_elf_section_processing): Declare.
+ * libbfd.h: Regenerated.
+ * reloc.c (BFD_RELOC_PPC_VLE_REL8, BFD_RELOC_PPC_VLE_REL15,
+ BFD_RELOC_PPC_VLE_REL24, BFD_RELOC_PPC_VLE_LO16A,
+ BFD_RELOC_PPC_VLE_LO16D, BFD_RELOC_PPC_VLE_HI16A,
+ BFD_RELOC_PPC_VLE_HI16D, BFD_RELOC_PPC_VLE_HA16A,
+ BFD_RELOC_PPC_VLE_HA16D, BFD_RELOC_PPC_VLE_SDA21,
+ BFD_RELOC_PPC_VLE_SDA21_LO, BFD_RELOC_PPC_VLE_SDAREL_LO16A,
+ BFD_RELOC_PPC_VLE_SDAREL_LO16D, BFD_RELOC_PPC_VLE_SDAREL_HI16A,
+ BFD_RELOC_PPC_VLE_SDAREL_HI16D, BFD_RELOC_PPC_VLE_SDAREL_HA16A,
+ BFD_RELOC_PPC_VLE_SDAREL_HA16D): New bfd relocations.
+
+2012-05-11 Georg-Johann Lay <avr@gjlay.de>
+
+ PR target/13503
+ * reloc.c: Add new ENUM for BFD_RELOC_AVR_8_LO,
+ BFD_RELOC_AVR_8_HI, BFD_RELOC_AVR_8_HHI.
+ * bfd-in2.h: Regenerate.
+ * libbfd.h: Regenerate.
+ * elf32-avr.c (elf_avr_howto_table): Add entries for
+ R_AVR_8_LO8, R_AVR_8_HI8, R_AVR_8_HHI8.
+ (avr_reloc_map): Add RELOC mappings for R_AVR_8_LO8, R_AVR_8_HI8,
+ R_AVR_8_HHI8.
+
+2012-05-10 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf64-x86-64.c (elf_x86_64_relocate_section): Use int in x32
+ addend overflow check.
+
+2012-05-10 DJ Delorie <dj@redhat.com>
+
+ * elf32-rx.c (rx_elf_object_p): Ignore empty segments.
+
+2012-05-10 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf64-x86-64.c (elf_x86_64_relocate_section): Display signed
+ hex number in x32 addend overflow check.
+
+2012-05-10 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf64-x86-64.c (elf_x86_64_reloc_type_class): Handle
+ R_X86_64_RELATIVE64.
+
+2012-05-09 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf64-x86-64.c (elf_x86_64_relocate_section): Check addend
+ overflow for R_X86_64_RELATIVE64.
+
+2012-05-08 Ben Cheng <bccheng@google.com>
+
+ * elf.c: Preserve the original p_align and p_flags if they are
+ valid.
+
+2012-05-07 Alan Modra <amodra@gmail.com>
+
+ * elf64-ia64-vms.c (elf64_ia64_relocate_section): Update
+ RELOC_AGAINST_DISCARDED_SECTION invocation.
+
+2012-05-07 Hans-Peter Nilsson <hp@axis.com>
+
+ * elf-bfd.h (RELOC_AGAINST_DISCARDED_SECTION): Declare and use
+ local variable i_ instead of assuming and using a variable i.
+
+2012-05-07 Maciej W. Rozycki <macro@linux-mips.org>
+
+ * elf-bfd.h (RELOC_AGAINST_DISCARDED_SECTION): Handle compound
+ relocations.
+ * elfxx-mips.c (mips_reloc_against_discarded_section): New
+ function.
+ (_bfd_mips_elf_relocate_section): Call it, in place of
+ RELOC_AGAINST_DISCARDED_SECTION.
+ * elf-m10200.c (mn10200_elf_relocate_section): Update arguments
+ to RELOC_AGAINST_DISCARDED_SECTION.
+ * elf-m10300.c (mn10300_elf_relocate_section): Likewise.
+ * elf32-arm.c (elf32_arm_relocate_section): Likewise.
+ * elf32-avr.c (elf32_avr_relocate_section): Likewise.
+ * elf32-bfin.c (bfin_relocate_section): Likewise.
+ (bfinfdpic_relocate_section): Likewise.
+ * elf32-cr16.c (elf32_cr16_relocate_section): Likewise.
+ * elf32-cr16c.c (elf32_cr16c_relocate_section): Likewise.
+ * elf32-cris.c (cris_elf_relocate_section): Likewise.
+ * elf32-crx.c (elf32_crx_relocate_section): Likewise.
+ * elf32-d10v.c (elf32_d10v_relocate_section): Likewise.
+ * elf32-epiphany.c (epiphany_elf_relocate_section): Likewise.
+ * elf32-fr30.c (fr30_elf_relocate_section): Likewise.
+ * elf32-frv.c (elf32_frv_relocate_section): Likewise.
+ * elf32-h8300.c (elf32_h8_relocate_section): Likewise.
+ * elf32-hppa.c (elf32_hppa_relocate_section): Likewise.
+ * elf32-i370.c (i370_elf_relocate_section): Likewise.
+ * elf32-i386.c (elf_i386_relocate_section): Likewise.
+ * elf32-i860.c (elf32_i860_relocate_section): Likewise.
+ * elf32-ip2k.c (ip2k_elf_relocate_section): Likewise.
+ * elf32-iq2000.c (iq2000_elf_relocate_section): Likewise.
+ * elf32-lm32.c (lm32_elf_relocate_section): Likewise.
+ * elf32-m32c.c (m32c_elf_relocate_section): Likewise.
+ * elf32-m32r.c (m32r_elf_relocate_section): Likewise.
+ * elf32-m68hc1x.c (elf32_m68hc11_relocate_section): Likewise.
+ * elf32-m68k.c (elf_m68k_relocate_section): Likewise.
+ * elf32-mcore.c (mcore_elf_relocate_section): Likewise.
+ * elf32-mep.c (mep_elf_relocate_section): Likewise.
+ * elf32-moxie.c (moxie_elf_relocate_section): Likewise.
+ * elf32-msp430.c (elf32_msp430_relocate_section): Likewise.
+ * elf32-mt.c (mt_elf_relocate_section): Likewise.
+ * elf32-openrisc.c (openrisc_elf_relocate_section): Likewise.
+ * elf32-ppc.c (ppc_elf_relocate_section): Likewise.
+ * elf32-rl78.c (rl78_elf_relocate_section): Likewise.
+ * elf32-rx.c (rx_elf_relocate_section): Likewise.
+ * elf32-s390.c (elf_s390_relocate_section): Likewise.
+ * elf32-score.c (s3_bfd_score_elf_relocate_section): Likewise.
+ * elf32-score7.c (s7_bfd_score_elf_relocate_section): Likewise.
+ * elf32-sh.c (sh_elf_relocate_section): Likewise.
+ * elf32-spu.c (spu_elf_relocate_section): Likewise.
+ * elf32-tic6x.c (elf32_tic6x_relocate_section): Likewise.
+ * elf32-tilepro.c (tilepro_elf_relocate_section): Likewise.
+ * elf32-v850.c (v850_elf_relocate_section): Likewise.
+ * elf32-vax.c (elf_vax_relocate_section): Likewise.
+ * elf32-xc16x.c (elf32_xc16x_relocate_section): Likewise.
+ * elf32-xstormy16.c (xstormy16_elf_relocate_section): Likewise.
+ * elf32-xtensa.c (elf_xtensa_relocate_section): Likewise.
+ * elf64-alpha.c (elf64_alpha_relocate_section_r): Likewise.
+ (elf64_alpha_relocate_section): Likewise.
+ * elf64-hppa.c (elf64_hppa_relocate_section): Likewise.
+ * elf64-mmix.c (mmix_elf_relocate_section): Likewise.
+ * elf64-ppc.c (ppc64_elf_relocate_section): Likewise.
+ * elf64-s390.c (elf_s390_relocate_section): Likewise.
+ * elf64-sh64.c (sh_elf64_relocate_section): Likewise.
+ * elf64-x86-64.c (elf_x86_64_relocate_section): Likewise.
+ * elfnn-ia64.c (elfNN_ia64_relocate_section): Likewise.
+ * elfxx-sparc.c (_bfd_sparc_elf_relocate_section): Likewise.
+ * elfxx-tilegx.c (tilegx_elf_relocate_section): Likewise.
+
+2012-05-05 Alan Modra <amodra@gmail.com>
+
+ PR ld/14052
+ PR ld/13621
+ * linker.c (_bfd_nearby_section): Revert 2012-02-13 change.
+
+2012-05-05 Alan Modra <amodra@gmail.com>
+
+ * aout-arm.c: Replace all uses of bfd_abs_section, bfd_com_section,
+ bfd_und_section and bfd_ind_section with their _ptr variants, or
+ use corresponding bfd_is_* macros.
+ * aout-ns32k.c: Likewise.
+ * aout-tic30.c: Likewise.
+ * coff-arm.c: Likewise.
+ * coff-tic54x.c: Likewise.
+ * cpu-ns32k.c: Likewise.
+ * elf-attrs.c: Likewise.
+ * elfcode.h: Likewise.
+ * peicode.h: Likewise.
+ * reloc.c: Likewise.
+ * riscix.c: Likewise.
+ * versados.c: Likewise.
+ * section.c: Likewise.
+ (bfd_abs_section, bfd_ind_section, bfd_com_section,
+ bfd_ind_section): Delete.
+ (std_section): New array replacing above.
+ (bfd_abs_section_ptr, bfd_ind_section_ptr, bfd_com_section_ptr,
+ bfd_ind_section_ptr, STD_SECTION): Update.
+ (BFD_FAKE_SECTION, GLOBAL_SYM_INIT): Remove unnecessary casts.
+ * bfd-in2.h: Regenerate.
+
+2012-05-03 Sean Keys <skeys@ipdatasys.com>
+
+ * cpu-xgate.c: New file. Added XGATE support.
+ * archures.c (bfd_architecture): Add XGATE architecture.
+ (bfd_archures_list): Add reference to XGATE architecture info.
+ * elf-bfd.h (prep_headers): Handle bfd_arch_xgate.
+ * reloc.c: Add various XGATE relocation enums.
+ * targets.c (bfd_elf32_xgate_vec): Declare and add to target vector
+ list.
+ * Makefile.am: Add support for XGATE elf.
+ * configure.in: Ditto.
+ * config.bfd: Ditto.
+ * Makefile.in: Regenerate.
+ * configure: Ditto.
+ * bfd-in2.h: Ditto.
+ * libbfd.h: Ditto.
+ Added files for XGATE relocations.
+ * elf32-xgate.c: Created minimal relocation file.
+ * elf32-xgate.h: Created minimal header file for elf32-xgate.
+
+2012-05-03 Tristan Gingold <gingold@adacore.com>
+
+ * dwarf2.c (decode_line_info): Ignore
+ DW_LNE_HP_source_file_correlation.
+
+2012-05-01 Nick Clifton <nickc@redhat.com>
+
+ PR binutils/13121
+ * aoutx.h: Rename 'finfo' to 'flaginfo' to avoid conflicts with
+ AIX system headers.
+ * coff-ppc.c: Likewise.
+ * cofflink.c: Likewise.
+ * elf32-arm.c: Likewise.
+ * elf64-sparc.c: Likewise.
+ * elflink.c: Likewise.
+ * pdp11.c: Likewise.
+ * rescoff.c: Likewise.
+
+2012-04-26 Mark Wielaard <mjw@redhat.com>
+
+ * dwarf2.c (scan_unit_for_symbols): Account for DW_AT_high_pc
+ possibly being relative to DW_AT_low_pc.
+ (parse_comp_unit): Likewise.
+
+2012-04-26 Andreas Schwab <schwab@linux-m68k.org>
+
+ * elf32-m68k.c (elf_m68k_check_relocs): Mark non-GOT references
+ also when generating PIE.
+ (elf_m68k_discard_copies): Mark undefined weak symbols referenced
+ by relocations as dynamic.
+
+2012-04-26 Hans-Peter Nilsson <hp@axis.com>
+
+ Provide a way for programs to recognize BFD_ASSERT calls.
+ * bfd.c (bfd_assert_handler_type): New API type.
+ (bfd_set_assert_handler, bfd_get_assert_handler): New API functions.
+ (_bfd_assert_handler): New variable.
+ (_bfd_default_assert_handler): New function.
+ (bfd_assert): Call _bfd_assert_handler, not _bfd_error_handler.
+ * libbfd-in.h (_bfd_assert_handler): Declare.
+ * libbfd.h, bfd-in2.h: Regenerate.
+
+2012-04-24 Hans-Peter Nilsson <hp@axis.com>
+
+ PR ld/13990
+ * elf32-arm.c (elf32_arm_gc_sweep_hook): Handle a forced-local
+ symbol, where PLT refcount is set to -1.
+
+2012-04-24 Alan Modra <amodra@gmail.com>
+
+ PR ld/13991
+ * elf-bfd.h (_bfd_elf_link_just_syms): Define as
+ _bfd_generic_link_just_syms.
+ * elflink.c (_bfd_elf_link_just_syms): Delete.
+ * linker.c (_bfd_generic_link_just_syms): Set sec_info_type.
+
+ * bfd-in.h (discarded_section): Renamed from elf_discarded_section.
+ * section.c (SEC_INFO_TYPE_NONE, SEC_INFO_TYPE_STABS,
+ SEC_INFO_TYPE_MERGE, SEC_INFO_TYPE_EH_FRAME,
+ SEC_INFO_TYPE_JUST_SYMS): Renamed from corresponding ELF_INFO_TYPE.
+ * elf-eh-frame.c, * elf-m10200.c, * elf-m10300.c,
+ * elf.c, * elf32-arm.c, * elf32-avr.c, * elf32-bfin.c,
+ * elf32-cr16.c, * elf32-cr16c.c, * elf32-cris.c,
+ * elf32-crx.c, * elf32-d10v.c, * elf32-epiphany.c,
+ * elf32-fr30.c, * elf32-frv.c, * elf32-h8300.c,
+ * elf32-hppa.c, * elf32-i370.c, * elf32-i386.c,
+ * elf32-i860.c, * elf32-ip2k.c, * elf32-iq2000.c,
+ * elf32-lm32.c, * elf32-m32c.c, * elf32-m32r.c,
+ * elf32-m68hc1x.c, * elf32-m68k.c, * elf32-mcore.c,
+ * elf32-mep.c, * elf32-moxie.c, * elf32-msp430.c,
+ * elf32-mt.c, * elf32-openrisc.c, * elf32-ppc.c,
+ * elf32-rl78.c, * elf32-rx.c, * elf32-s390.c,
+ * elf32-score.c, * elf32-score7.c, * elf32-sh.c,
+ * elf32-spu.c, * elf32-tic6x.c, * elf32-tilepro.c,
+ * elf32-v850.c, * elf32-vax.c, * elf32-xc16x.c,
+ * elf32-xstormy16.c, * elf32-xtensa.c, * elf64-alpha.c,
+ * elf64-hppa.c, * elf64-ia64-vms.c, * elf64-mmix.c,
+ * elf64-ppc.c, * elf64-s390.c, * elf64-sh64.c,
+ * elf64-x86-64.c, * elflink.c, * elfnn-ia64.c,
+ * elfxx-mips.c, * elfxx-sparc.c, * elfxx-tilegx.c,
+ * reloc.c: Update all references.
+ * bfd-in2.h: Regenerate.
+
+2012-04-20 Andreas Krebbel <Andreas.Krebbel@de.ibm.com>
+
+ * elf32-s390.c (ELF_DYNAMIC_INTERPRETER): Set to the GCC default.
+ * elf64-s390.c (ELF_DYNAMIC_INTERPRETER): Set to the GCC default.
+
+2012-04-19 Thomas Schwinge <thomas@codesourcery.com>
+
+ * elf32-sh.c (elf_sh_link_hash_entry): Specify an enum identifier for
+ got_type.
+ (allocate_dynrelocs, sh_elf_relocate_section, sh_elf_check_relocs): Use
+ it.
+
+2012-04-17 Kaz Kojima <kkojima@rr.iij4u.or.jp>
+
+ * elf32-sh.c (allocate_dynrelocs): Don't allocate dynamic
+ relocations when LE conversion happens on the IE tls symbol.
+
+2012-04-17 Roland McGrath <mcgrathr@google.com>
+
+ * elf64-x86-64.c (elf_x86_64_nacl_plt0_entry): Fix nop padding
+ so that 32-byte boundary is a proper instruction boundary.
+
+2012-04-17 Tristan Gingold <gingold@adacore.com>
+
+ * vms-lib.c (_bfd_vms_lib_get_module): Append .obj extension to
+ member of an object archive.<
+
+2012-04-17 Tristan Gingold <gingold@adacore.com>
+
+ * vms-lib.c (MAX_EKEYLEN): Define.
+ (MAX_KEYLEN): Fix value.
+ (vms_write_index): Add comments and fix indentation.
+ Adjust comparaison. Add assertions. Free kbn_blk.
+ (_bfd_vms_lib_write_archive_contents): Use MAX_EKEYLEN.
+ Compense MAX_KEYLEN adjustment.
+
+2012-04-16 Maciej W. Rozycki <macro@linux-mips.org>
+
+ * elfxx-mips.c (mips16_stub_symndx): Handle n64 compound relocs.
+ (_bfd_mips_elf_check_relocs): Update accordingly.
+
+2012-04-13 Alan Modra <amodra@gmail.com>
+
+ PR ld/13947
+ * elflink.c (bfd_elf_final_link): Set reloc_count to 0 for
+ reloc sections.
+
+2012-04-12 David S. Miller <davem@davemloft.net>
+
+ * reloc.c (BFD_RELOC_SPARC_H34, BFD_RELOC_SPARC_SIZE32,
+ BFD_RELOC_SPARC_SIZE64, BFD_RELOC_SPARC_WDISP10): New relocs.
+ * libbfd.h: Regenerate.
+ * bfd-in2.h: Likewise.
+ * elfxx-sparc.c (sparc_elf_wdisp10_reloc): New function.
+ (_bfd_sparc_elf_howto_table): Add entries for R_SPARC_H34,
+ R_SPARC_SIZE32, R_SPARC_64, and R_SPARC_WDISP10.
+ (_bfd_sparc_elf_reloc_type_lookup): Handle new relocs.
+ (_bfd_sparc_elf_check_relocs): Likewise.
+ (_bfd_sparc_elf_gc_sweep_hook): Likewise.
+ (_bfd_sparc_elf_relocate_section): Likewise.
+
+2012-04-12 Roland McGrath <mcgrathr@google.com>
+
+ * elf32-arm.c (elf32_arm_nacl_plt0_entry, elf32_arm_nacl_plt_entry):
+ New variables.
+ (struct elf32_arm_link_hash_table): New member `nacl_p'.
+ (elf32_arm_link_hash_table_create): Initialize it.
+ (elf32_arm_nacl_link_hash_table_create): New function.
+ (arm_movw_immediate, arm_movt_immediate): New functions.
+ (elf32_arm_populate_plt_entry): Test HTAB->nacl_p.
+ (elf32_arm_finish_dynamic_sections): Likewise.
+ (elf32_arm_output_plt_map_1): Likewise.
+ (bfd_elf32_littlearm_nacl_vec, bfd_elf32_bigarm_nacl_vec):
+ New backend vector stanza.
+ (elf32_arm_nacl_modify_segment_map): New function.
+ * config.bfd: Handle arm-*-nacl*, armeb-*-nacl*.
+ * targets.c: Support bfd_elf32_{big,little}_nacl_vec.
+ * configure.in: Likewise.
+ (bfd_elf32_bigarm_nacl_vec): Add elf-nacl.lo here.
+ (bfd_elf32_littlearm_nacl_vec): Likewise.
+ (bfd_elf32_bigarm_vec, bfd_elf32_littlearm_vec): Likewise.
+ (bfd_elf32_bigarm_symbian_vec): Likewise.
+ (bfd_elf32_littlearm_symbian_vec): Likewise.
+ (bfd_elf32_bigarm_vxworks_vec): Likewise.
+ (bfd_elf32_littlearm_vxworks_vec): Likewise.
+ * configure: Regenerated.
+
+2012-04-12 Tristan Gingold <gingold@adacore.com>
+
+ * elflink.c (elf_link_output_extsym): Add a guard.
+ (bfd_elf_final_link): Remove assertion.
+ (bfd_elf_final_link): Add a guard.
+ * elfnn-ia64.c (INCLUDE_IA64_VMS): Removed.
+ (elfNN_vms_section_from_shdr, elfNN_vms_object_p)
+ (elfNN_vms_post_process_headers, elfNN_vms_section_processing)
+ (elfNN_vms_final_write_processing, elfNN_vms_close_and_cleanup):
+ Remove.
+ (elfNN-ia64-vms target): Move to ...
+ * elf64-ia64-vms.c: New file.
+ * configure.in (bfd_elf64_ia64_vms_vec): Add elf64-ia64-vms.lo
+ * Makefile.am (BFD64_BACKENDS): Add elf64-ia64-vms.lo.
+ (BFD64_BACKENDS_CFILES): Ad elf64-ia64-vms.c.
+ * configure: Regenerate.
+ * Makefile.in: Regenerate.
+
+2012-04-11 Nick Clifton <nickc@redhat.com>
+
+ PR binutils/13897
+ * elf64-ppc.c (opd_entry_value): When dealing with sections
+ without relocs, keep the last section loaded in order to avoid
+ unnecessary reloads.
+
+2012-04-09 Roland McGrath <mcgrathr@google.com>
+
+ * elf.c (_bfd_elf_map_sections_to_segments): Set INFO->user_phdrs.
+ * elf-nacl.c (nacl_modify_segment_map): Do nothing if INFO->user_phdrs.
+ (nacl_modify_program_headers): Likewise.
+
+2012-04-03 Roland McGrath <mcgrathr@google.com>
+
+ * elf-nacl.c: New file.
+ * elf-nacl.h: New file.
+ * elf32-i386.c (elf_backend_modify_segment_map): Define for
+ bfd_elf32_i386_nacl_vec.
+ (elf_backend_modify_program_headers): Likewise.
+ * elf64-x86-64.c (elf_backend_modify_segment_map): Define for
+ bfd_elf64_x86_64_nacl_vec and bfd_elf32_x86_64_nacl_vec.
+ (elf_backend_modify_program_headers): Likewise.
+ * Makefile.am (BFD32_BACKENDS, BFD64_BACKENDS): Add elf-nacl.lo here.
+ (BFD32_BACKENDS_CFILES, BFD64_BACKENDS_CFILES): Add elf-nacl.c here.
+ * Makefile.in: Regenerated.
+ * configure.in (bfd_elf64_x86_64_nacl_vec): Add elf-nacl.o to tb here.
+ (bfd_elf32_x86_64_nacl_vec): Likewise.
+ (bfd_elf64_x86_64_vec, bfd_elf32_x86_64_vec): Likewise.
+ (bfd_elf64_x86_64_freebsd_vec, bfd_elf64_x86_64_sol2_vec): Likewise.
+ (bfd_elf64_l1om_vec, bfd_elf64_l1om_freebsd_vec): Likewise.
+ (bfd_elf64_k1om_vec, bfd_elf64_k1om_freebsd_vec): Likewise.
+ (bfd_elf32_i386_nacl_vec): Likewise.
+ (bfd_elf32_i386_sol2_vec, bfd_elf32_i386_freebsd_vec): Likewise.
+ (bfd_elf32_i386_vxworks_vec, bfd_elf32_i386_vec): Likewise.
+ * configure: Regenerated.
+
+2012-03-31 Andreas Schwab <schwab@linux-m68k.org>
+
+ * elf32-m68k.c (elf_m68k_relocate_section): Allow
+ R_68K_TLS_LE{8,16,32} for PIE.
+
+2012-03-30 Andreas Krebbel <Andreas.Krebbel@de.ibm.com>
+
+ * elf64-s390.c: Fix several comments regarding PLT entry
+ description.
+ * elf32-s390.c: Likewise.
+
+2012-03-30 Andreas Krebbel <Andreas.Krebbel@de.ibm.com>
+
+ * elf64-s390.c: Use the section pointer shortcuts in
+ elf_link_hash_table and remove them from the target specific
+ variant.
+ * elf32-s390.c: Likewise.
+
+2012-03-30 Andreas Krebbel <Andreas.Krebbel@de.ibm.com>
+
+ * elf64-s390.c (elf_s390x_plt_entry, elf_s390x_first_plt_entry):
+ New definitions.
+ (PLT_PIC_ENTRY_WORD*, PLT_PIC12_ENTRY_WORD*): Remove.
+ (elf_s390_finish_dynamic_symbol): Use memcpy instead of bfd_put_32.
+ (elf_s390_finish_dynamic_sections): Likewise.
+ * elf32-s390.c (elf_s390_plt_entry, elf_s390_plt_pic_entry)
+ (elf_s390_plt_pic12_entry, elf_s390_plt_pic16_entry)
+ (elf_s390_plt_first_entry, elf_s390_plt_pic_first_entry): New definitions.
+ (PLT_PIC16_ENTRY_WORD*, PLT_ENTRY_WORD*)
+ (PLT_PIC_FIRST_ENTRY_WORD*, PLT_FIRST_ENTRY_WORD*): Remove.
+
+2012-03-30 Andreas Krebbel <Andreas.Krebbel@de.ibm.com>
+
+ * elf32-s390.c (struct elf_s390_dyn_relocs): Remove.
+ Rename all occurrences in the file to elf_dyn_relocs.
+ * elf64-s390.c: Likewise.
+
+2012-03-30 Alan Modra <amodra@gmail.com>
+
+ * elflink.c (_bfd_elf_gc_mark_reloc): Don't delve into dynamic
+ libraries.
+
+2012-03-29 Alan Modra <amodra@gmail.com>
+
+ * bfd-in.h (bfd_get_arch_size, bfd_get_sign_extend_vma): Delete.
+ * bfd-in2.h: Regenerate.
+
+2012-03-23 Alan Modra <amodra@gmail.com>
+
+ * elf.c (assign_file_positions_for_non_load_sections): Don't warn
+ on empty alloc sections.
+
+2012-03-23 Alan Modra <amodra@gmail.com>
+
+ * linker.c (_bfd_nearby_section): New function, split out from..
+ (fix_syms): ..here.
+ * bfd-in.h (_bfd_nearby_section): Declare.
+ * bfd-in2.h: Regenerate.
+ * elflink.c (elf_link_input_bfd): Don't use text_index_section or
+ data_index_section with ld -q or ld -r output relocs against
+ stripped output sections. Instead use _bfd_nearby_section.
+
+2012-03-23 Alan Modra <amodra@gmail.com>
+
+ PR binutils/13894
+ * elf64-ppc.c (opd_entry_value): Read full symbol table when
+ sym hashes unavailable.
+
+2012-03-21 Eliot Dresselhaus <eliot@sonic.net>
+
+ * elf32-tic6x.c (elf32_tic6x_merge_private_bfd_data): Return TRUE
+ for non-C6X objects.
+
+2012-03-20 Kai Tietz <ktietz@redhat.com>
+
+ PR ld/12742
+ * configure.in (AC_CHECK_HEADERS): Test for windows.h and dlfcn.h.
+ * plugin.c: Guard include of dlfcn.h if HAVE_DLFCN_H is defined.
+ Add windows.h header include if HAVE_WINDOWS_H is defined.
+ (dlerror): New static function if windows variant is used instead
+ of dlfcn.h.
+ (dlclose): Likewise.
+ (dlopen): Likewise.
+ (dlsym): Likewise.
+ * configure: Regenerated.
+ * config.in: Regenerated.
+
+2012-03-20 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/13880
+ * elf32-i386.c (elf_i386_relocate_section): Don't issue an error
+ for R_386_GOTOFF relocation against protected function if
+ SYMBOLIC_BIND is true.
+
+ * elf64-x86-64.c (elf_x86_64_relocate_section): Don't issue an
+ error for R_X86_64_GOTOFF64 relocation against protected function
+ when building executable or SYMBOLIC_BIND is true.
+
+2012-03-16 Roland McGrath <mcgrathr@google.com>
+
+ * config.bfd: Handle x86_64-*-nacl*.
+ * elf64-x86-64.c (bfd_elf64_x86_64_nacl_vec): New backend vector stanza.
+ (bfd_elf32_x86_64_nacl_vec): Likewise.
+ * targets.c: Support them.
+ * configure.in: Likewise.
+ * configure: Regenerated.
+
+2012-03-16 Matthew Gretton-Dann <matthew.gretton-dann@arm.com>
+
+ * elf32-arm.c (elf32_arm_attributes_accept_div): New function.
+ (elf32_arm_attributes_forbid_div): Likewise.
+ (elf32_arm_merge_eabi_attributes): Correct handling of
+ Tag_DIV_use.
+
+2012-03-15 Roland McGrath <mcgrathr@google.com>
+
+ * elf64-x86-64.c (elf_x86_64_create_dynamic_sections): Use
+ elf_x86_64_backend_data parameters for plt_eh_frame.
+
+ * elf64-x86-64.c (struct elf_x86_64_backend_data): New type.
+ (get_elf_x86_64_backend_data, GET_PLT_ENTRY_SIZE): New macros.
+ (elf_x86_64_arch_bed): New variable.
+ (elf_backend_arch_data): New macro.
+ (elf_x86_64_adjust_dynamic_symbol): Use GET_PLT_ENTRY_SIZE.
+ (elf_x86_64_allocate_dynrelocs): Likewise.
+ (elf_x86_64_relocate_section): Likewise.
+ (elf_x86_64_plt_sym_val): Likewise.
+ (elf_x86_64_finish_dynamic_symbol): Use elf_x86_64_backend_data
+ parameters for PLT details.
+ (elf_x86_64_finish_dynamic_sections): Likewise.
+
+2012-03-14 Roland McGrath <mcgrathr@google.com>
+
+ * elf32-i386.c (elf_i386_nacl_pic_plt0_entry): Initialize up
+ to the full size, padding out with nop instructions.
+
+2012-03-12 Alan Modra <amodra@gmail.com>
+
+ * elf-m10300.c (_bfd_mn10300_elf_adjust_dynamic_symbol): Don't warn
+ on zero size dynbss symbol.
+ * elf32-arm.c (elf32_arm_adjust_dynamic_symbol): Likewise.
+ * elf32-cr16.c (_bfd_cr16_elf_adjust_dynamic_symbol): Likewise.
+ * elf32-cris.c (elf_cris_adjust_dynamic_symbol): Likewise.
+ * elf32-hppa.c (elf32_hppa_adjust_dynamic_symbol): Likewise.
+ * elf32-i370.c (i370_elf_adjust_dynamic_symbol): Likewise.
+ * elf32-i386.c (elf_i386_adjust_dynamic_symbol): Likewise.
+ * elf32-lm32.c (lm32_elf_adjust_dynamic_symbol): Likewise.
+ * elf32-m32r.c (m32r_elf_adjust_dynamic_symbol): Likewise.
+ * elf32-m68k.c (elf_m68k_adjust_dynamic_symbol): Likewise.
+ * elf32-ppc.c (ppc_elf_adjust_dynamic_symbol): Likewise.
+ * elf32-s390.c (elf_s390_adjust_dynamic_symbol): Likewise.
+ * elf32-sh.c (sh_elf_adjust_dynamic_symbol): Likewise.
+ * elf32-tic6x.c (elf32_tic6x_adjust_dynamic_symbol): Likewise.
+ * elf32-tilepro.c (tilepro_elf_adjust_dynamic_symbol): Likewise.
+ * elf32-vax.c (elf_vax_adjust_dynamic_symbol): Likewise.
+ * elf64-ppc.c (ppc64_elf_adjust_dynamic_symbol): Likewise.
+ * elf64-s390.c (elf_s390_adjust_dynamic_symbol): Likewise.
+ * elf64-sh64.c (sh64_elf64_adjust_dynamic_symbol): Likewise.
+ * elf64-x86-64.c (elf_x86_64_adjust_dynamic_symbol): Likewise.
+ * elfxx-sparc.c (_bfd_sparc_elf_adjust_dynamic_symbol): Likewise.
+ * elfxx-tilegx.c (tilegx_elf_adjust_dynamic_symbol): Likewise.
+
+2012-03-10 Edmar Wienskoski <edmar@freescale.com>
+
+ * archures.c: Add bfd_mach_ppc_e5500 and bfd_mach_ppc_e6500.
+ * bfd-in2.h: Regenerate.
+ * cpu-powerpc.c (bfd_powerpc_archs): Add entries for
+ bfd_mach_ppc_e5500 and bfd_mach_ppc_e6500.
+
+2012-03-09 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/13817
+ * elf32-i386.c (elf_i386_relocate_section): Restore
+ R_386_IRELATIVE.
+
+ * elf64-x86-64.c (elf_x86_64_relocate_section): Restore
+ R_X86_64_IRELATIVE.
+
+2012-03-08 Tristan Gingold <gingold@adacore.com>
+
+ * vms-lib.c (_bfd_vms_lib_write_archive_contents): Set maximum
+ keylen according to archive kind. Set nextvbn and nextrfa lhd
+ fields. Add comments.
+
+2012-03-07 Nick Clifton <nickc@redhat.com>
+
+ * elf-m10300.c (elf32_mn10300_link_hash_entry): Add tls_type
+ field.
+ (elf32_mn10300_link_hash_table): Add tls_ldm_got entry;
+ (elf_mn10300_tdata): Define.
+ (elf_mn10300_local_got_tls_type): Define.
+ (elf_mn10300_howto_table): Add entries for R_MN10300_TLS_GD,
+ R_MN10300_TLS_LD, R_MN10300_TLS_LDO, R_MN10300_TLS_GOTIE,
+ R_MN10300_TLS_IE, R_MN10300_TLS_LE, R_MN10300_TLS_DPTMOD,
+ R_MN10300_TLS_DTPOFF, R_MN10300_TLS_TPOFF relocs.
+ (mn10300_reloc_map): Likewise.
+ (elf_mn10300_tls_transition): New function.
+ (dtpoff, tpoff, mn10300_do_tls_transition): New functions.
+ (mn10300_elf_check_relocs): Add TLS support.
+ (mn10300_elf_final_link_relocate): Likewise.
+ (mn10300_elf_relocate_section): Likewise.
+ (mn10300_elf_relax_section): Likewise.
+ (elf32_mn10300_link_hash_newfunc): Initialise new field.
+ (_bfd_mn10300_copy_indirect_symbol): New function.
+ (elf32_mn10300_link_hash_table_create): Initialise new fields.
+ (_bfd_mn10300_elf_size_dynamic_sections): Add TLS support.
+ (_bfd_mn10300_elf_finish_dynamic_symbol): Likewise.
+ (_bfd_mn10300_elf_reloc_type_class): Allocate an
+ elf_mn10300_obj_tdata structure.
+ (elf_backend_copy_indirect_symbol): Define.
+ * reloc.c (BFD_MN10300_TLS_GD, BFD_MN10300_TLS_LD,
+ BFD_MN10300_TLS_LDO, BFD_MN10300_TLS_GOTIE, BFD_MN10300_TLS_IE,
+ BFD_MN10300_TLS_LE, BFD_MN10300_TLS_DPTMOD,
+ BFD_MN10300_TLS_DTPOFF, BFD_MN10300_TLS_TPOFF): New relocations.
+ (BFD_RELOC_MN10300_32_PCREL, BFD_RELOC_MN10300_16_PCREL): Move to
+ alongside other MN10300 relocations.
+ * bfd-in2.h: Regenerate.
+ * libbfd.h: Regenerate.
+
+2012-03-06 Jakub Jelinek <jakub@redhat.com>
+
+ * elf64-x86-64.c (elf_x86_64_relocate_section): For R_X86_64_RELATIVE
+ set relocate to TRUE.
+
+2012-03-05 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
+
+ PR ld/12152
+ * elfxx-sparc.c (_bfd_sparc_elf_relocate_section): Also ignore
+ overflows for R_SPARC_UA32 in .stab sections.
+
+2012-03-01 Alan Modra <amodra@gmail.com>
+
+ * elfxx-tilegx.c (tilegx_elf_relocate_section): Silence bogus warning.
+
+2012-02-27 Alan Modra <amodra@gmail.com>
+
+ * elf32-sh.c (sh_elf_osec_to_segment): Check for elf flavour bfd
+ before calling elf specific function.
+ (sh_elf_osec_readonly_p): Test for error return from above.
+
+2012-02-27 Alan Modra <amodra@gmail.com>
+
+ * elf32-spu.c (build_stub): Fix malloc under-allocation.
+
+2012-02-25 Walter Lee <walt@tilera.com>
+ * reloc.c: Add BFD_RELOC_TILEPRO_TLS_GD_CALL,
+ BFD_RELOC_TILEPRO_IMM8_X0_TLS_GD_ADD,
+ BFD_RELOC_TILEPRO_IMM8_X1_TLS_GD_ADD,
+ BFD_RELOC_TILEPRO_IMM8_Y0_TLS_GD_ADD,
+ BFD_RELOC_TILEPRO_IMM8_Y1_TLS_GD_ADD,
+ BFD_RELOC_TILEPRO_TLS_IE_LOAD, BFD_RELOC_TILEPRO_IMM16_X0_TLS_LE,
+ BFD_RELOC_TILEPRO_IMM16_X1_TLS_LE,
+ BFD_RELOC_TILEPRO_IMM16_X0_TLS_LE_LO,
+ BFD_RELOC_TILEPRO_IMM16_X1_TLS_LE_LO,
+ BFD_RELOC_TILEPRO_IMM16_X0_TLS_LE_HI,
+ BFD_RELOC_TILEPRO_IMM16_X1_TLS_LE_HI,
+ BFD_RELOC_TILEPRO_IMM16_X0_TLS_LE_HA,
+ BFD_RELOC_TILEPRO_IMM16_X1_TLS_LE_HA,
+ BFD_RELOC_TILEGX_IMM16_X0_HW0_TLS_LE,
+ BFD_RELOC_TILEGX_IMM16_X1_HW0_TLS_LE,
+ BFD_RELOC_TILEGX_IMM16_X0_HW0_LAST_TLS_LE,
+ BFD_RELOC_TILEGX_IMM16_X1_HW0_LAST_TLS_LE,
+ BFD_RELOC_TILEGX_IMM16_X0_HW1_LAST_TLS_LE,
+ BFD_RELOC_TILEGX_IMM16_X1_HW1_LAST_TLS_LE,
+ BFD_RELOC_TILEGX_TLS_GD_CALL, BFD_RELOC_TILEGX_IMM8_X0_TLS_GD_ADD,
+ BFD_RELOC_TILEGX_IMM8_X1_TLS_GD_ADD,
+ BFD_RELOC_TILEGX_IMM8_Y0_TLS_GD_ADD,
+ BFD_RELOC_TILEGX_IMM8_Y1_TLS_GD_ADD, BFD_RELOC_TILEGX_TLS_IE_LOAD,
+ BFD_RELOC_TILEGX_IMM8_X0_TLS_ADD,
+ BFD_RELOC_TILEGX_IMM8_X1_TLS_ADD,
+ BFD_RELOC_TILEGX_IMM8_Y0_TLS_ADD, BFD_RELOC_TILEGX_IMM8_Y1_TLS_ADD.
+ Delete BFD_RELOC_TILEGX_IMM16_X0_HW1_GOT,
+ BFD_RELOC_TILEGX_IMM16_X1_HW1_GOT,
+ BFD_RELOC_TILEGX_IMM16_X0_HW2_GOT,
+ BFD_RELOC_TILEGX_IMM16_X1_HW2_GOT,
+ BFD_RELOC_TILEGX_IMM16_X0_HW3_GOT,
+ BFD_RELOC_TILEGX_IMM16_X1_HW3_GOT,
+ BFD_RELOC_TILEGX_IMM16_X0_HW2_LAST_GOT,
+ BFD_RELOC_TILEGX_IMM16_X1_HW2_LAST_GOT,
+ BFD_RELOC_TILEGX_IMM16_X0_HW1_TLS_GD,
+ BFD_RELOC_TILEGX_IMM16_X1_HW1_TLS_GD,
+ BFD_RELOC_TILEGX_IMM16_X0_HW2_TLS_GD,
+ BFD_RELOC_TILEGX_IMM16_X1_HW2_TLS_GD,
+ BFD_RELOC_TILEGX_IMM16_X0_HW3_TLS_GD,
+ BFD_RELOC_TILEGX_IMM16_X1_HW3_TLS_GD,
+ BFD_RELOC_TILEGX_IMM16_X0_HW2_LAST_TLS_GD,
+ BFD_RELOC_TILEGX_IMM16_X1_HW2_LAST_TLS_GD,
+ BFD_RELOC_TILEGX_IMM16_X0_HW1_TLS_IE,
+ BFD_RELOC_TILEGX_IMM16_X1_HW1_TLS_IE,
+ BFD_RELOC_TILEGX_IMM16_X0_HW2_TLS_IE,
+ BFD_RELOC_TILEGX_IMM16_X1_HW2_TLS_IE,
+ BFD_RELOC_TILEGX_IMM16_X0_HW3_TLS_IE,
+ BFD_RELOC_TILEGX_IMM16_X1_HW3_TLS_IE,
+ BFD_RELOC_TILEGX_IMM16_X0_HW2_LAST_TLS_IE,
+ BFD_RELOC_TILEGX_IMM16_X1_HW2_LAST_TLS_IE.
+ * elf32-tilepro.c (tilepro_elf_howto_table): Update tilepro
+ relocations.
+ (tilepro_reloc_map): Ditto.
+ (tilepro_info_to_howto_rela): Ditto.
+ (reloc_to_create_func): Ditto.
+ (tilepro_tls_translate_to_le): New.
+ (tilepro_tls_translate_to_ie): New.
+ (tilepro_elf_tls_transition): New.
+ (tilepro_elf_check_relocs): Handle new tls relocations.
+ (tilepro_elf_gc_sweep_hook): Ditto.
+ (allocate_dynrelocs): Ditto.
+ (tilepro_elf_relocate_section): Ditto.
+ (tilepro_replace_insn): New.
+ (insn_mask_X1): New.
+ (insn_mask_X0_no_dest_no_srca): New
+ (insn_mask_X1_no_dest_no_srca): New
+ (insn_mask_Y0_no_dest_no_srca): New
+ (insn_mask_Y1_no_dest_no_srca): New
+ (srca_mask_X0): New
+ (srca_mask_X1): New
+ (insn_tls_le_move_X1): New
+ (insn_tls_le_move_zero_X0X1): New
+ (insn_tls_ie_lw_X1): New
+ (insn_tls_ie_add_X0X1): New
+ (insn_tls_ie_add_Y0Y1): New
+ (insn_tls_gd_add_X0X1): New
+ (insn_tls_gd_add_Y0Y1): New
+ * elfxx-tilegx.c (tilegx_elf_howto_table): Update tilegx
+ relocations.
+ (tilegx_reloc_map): Ditto.
+ (tilegx_info_to_howto_rela): Ditto.
+ (reloc_to_create_func): Ditto.
+ (tilegx_elf_link_hash_table): New field disable_le_transition.
+ (tilegx_tls_translate_to_le): New.
+ (tilegx_tls_translate_to_ie): New.
+ (tilegx_elf_tls_transition): New.
+ (tilegx_elf_check_relocs): Handle new tls relocations.
+ (tilegx_elf_gc_sweep_hook): Ditto.
+ (allocate_dynrelocs): Ditto.
+ (tilegx_elf_relocate_section): Ditto.
+ (tilegx_copy_bits): New.
+ (tilegx_replace_insn): New.
+ (insn_mask_X1): New.
+ (insn_mask_X0_no_dest_no_srca): New.
+ (insn_mask_X1_no_dest_no_srca): New.
+ (insn_mask_Y0_no_dest_no_srca): New.
+ (insn_mask_Y1_no_dest_no_srca): New.
+ (insn_mask_X0_no_operand): New.
+ (insn_mask_X1_no_operand): New.
+ (insn_mask_Y0_no_operand): New.
+ (insn_mask_Y1_no_operand): New.
+ (insn_tls_ie_ld_X1): New.
+ (insn_tls_ie_ld4s_X1): New.
+ (insn_tls_ie_add_X0X1): New.
+ (insn_tls_ie_add_Y0Y1): New.
+ (insn_tls_ie_addx_X0X1): New.
+ (insn_tls_ie_addx_Y0Y1): New.
+ (insn_tls_gd_add_X0X1): New.
+ (insn_tls_gd_add_Y0Y1): New.
+ (insn_move_X0X1): New.
+ (insn_move_Y0Y1): New.
+ (insn_add_X0X1): New.
+ (insn_add_Y0Y1): New.
+ (insn_addx_X0X1): New.
+ (insn_addx_Y0Y1): New.
+ * libbfd.h: Regenerate.
+ * bfd-in2.h: Regenerate.
+
+2012-02-25 Walter Lee <walt@tilera.com>
+
+ * config.bfd (tilegx-*-*): rename little endian vector; add big
+ endian vector.
+ (tilegxbe-*-*): New case.
+ * configure.in (bfd_elf32_tilegx_vec): Rename...
+ (bfd_elf32_tilegx_le_vec): ... to this.
+ (bfd_elf32_tilegx_be_vec): New vector.
+ (bfd_elf64_tilegx_vec): Rename...
+ (bfd_elf64_tilegx_le_vec): ... to this.
+ (bfd_elf64_tilegx_be_vec): New vector.
+ * configure: Regenerate.
+ * elf32-tilegx.c (TARGET_LITTLE_SYM): Rename.
+ (TARGET_LITTLE_NAME): Ditto.
+ (TARGET_BIG_SYM): Define.
+ (TARGET_BIG_NAME): Define.
+ * elf64-tilegx.c (TARGET_LITTLE_SYM): Rename.
+ (TARGET_LITTLE_NAME): Ditto.
+ (TARGET_BIG_SYM): Define.
+ (TARGET_BIG_NAME): Define.
+ * targets.c (bfd_elf32_tilegx_vec): Rename...
+ (bfd_elf32_tilegx_le_vec): ... to this.
+ (bfd_elf32_tilegx_be_vec): Declare.
+ (bfd_elf64_tilegx_vec): Rename...
+ (bfd_elf64_tilegx_le_vec): ... to this.
+ (bfd_elf64_tilegx_be_vec): Declare.
+ (_bfd_target_vector): Add / rename above vectors.
+ * arctures.c (bfd_architecture): Define bfd_mach_tilegx32.
+ * bfd-in2.h: Regenerate.
+ * cpu-tilegx.c (bfd_tilegx32_arch): define.
+ (bfd_tilegx_arch): link to bfd_tilegx32_arch.
+
+2012-02-24 Nick Clifton <nickc@redhat.com>
+
+ PR ld/13730
+ * reloc.c (bfd_generic_get_relocated_section_contents): Issue an
+ error message instead of aborting, when an outofrange reloc is
+ encountered.
+
+2012-02-23 Iain Sandoe <idsandoe@googlemail.com>
+
+ * mach-o.c (bfd_mach_o_swap_in_non_scattered_reloc): New.
+ (bfd_mach_o_canonicalize_one_reloc): Swap non-scattered reloc
+ bit-fields when target and host differ in endian-ness. When
+ PAIRs are non-scattered find the 'symbol' from the preceding
+ reloc. Add FIXME re. reloc symbols on section boundaries.
+ (bfd_mach_o_swap_out_non_scattered_reloc): New.
+ (bfd_mach_o_write_relocs): Use bfd_mach_o_encode_non_scattered_reloc.
+
+2012-02-17 Iain Sandoe <idsandoe@googlemail.com>
+
+ * mach-o-i386.c (i386_howto_table): Add support for 16 bit
+ sect-diffs.
+ (bfd_mach_o_i386_swap_reloc_in): Handle 16bit sect-diffs.
+ (bfd_mach_o_i386_swap_reloc_out): Likewise.
+
+2012-02-17 Tristan Gingold <gingold@adacore.com>
+
+ * reloc.c (BFD_RELOC_MACH_O_LOCAL_SECTDIFF):
+ * libbfd.h: Regenerated.
+ * bfd-in2.h: Likewise.
+ * mach-o-i386.c (i386_howto_table): Include local sectdiff.
+ (bfd_mach_o_i386_swap_reloc_in): Update for local sectdiff.
+ (bfd_mach_o_i386_swap_reloc_out): Likewise.
+
+2012-02-17 Andreas Krebbel <Andreas.Krebbel@de.ibm.com>
+
+ * elf32-s390.c (elf_s390_relocate_section): Support basr in the
+ GD->LE and LD->LE optimizations.
+
+2012-02-16 Alan Modra <amodra@gmail.com>
+
+ PR binutils/13355
+ * elf32-rx.c (elf32_rx_relax_section): Correct width check.
+
+2012-02-13 Richard Henderson <rth@redhat.com>
+
+ PR ld/13621
+ * linker.c (fix_syms): Force symbols outside any section into
+ bfd_abs_section_ptr.
+
+2012-02-13 Alan Modra <amodra@gmail.com>
+
+ * elf32-m68hc1x.c (elf32_m68hc11_merge_symbol_attribute): New function.
+ * elf32-m68hc1x.h (elf32_m68hc11_merge_symbol_attribute): Declare.
+ * elf32-m68hc11.c (elf_backend_merge_symbol_attribute): Define.
+ * elf32-m68hc12.c (elf_backend_merge_symbol_attribute): Define.
+
+2012-02-11 Jan Kratochvil <jan.kratochvil@redhat.com>
+ Nick Clifton <nickc@redhat.com>
+
+ * oasys.c (oasys_write_header): Fix compilation warning on zero-sized
+ memset.
+
+2012-02-10 Iain Sandoe <idsandoe@googlemail.com>
+
+ * mach-o.c (bfd_mach_o_build_seg_command): Count zerofill section
+ vma additions in their logical, rather than physical order.
+
+2012-02-10 Iain Sandoe <idsandoe@googlemail.com>
+
+ * mach-o.c (mach_o_section_name_xlat): Correct eh-frame section
+ parameters.
+ * mach-o-x86-64.c (text_section_names_xlat): New.
+ (mach_o_x86_64_segsec_names_xlat): New.
+ (bfd_mach_o_tgt_seg_table): Define to mach_o_x86_64_segsec_names_xlat.
+ * mach-o-i386.c (text_section_names_xlat): Correct section parameters.
+
+2012-02-10 Tristan Gingold <gingold@adacore.com>
+
+ * elfnn-ia64.c (elfNN_vms_object_p): Change comparison operator
+ to avoid infinite loop. Add comments.
+
+2012-02-09 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/13675
+ * cpu-i386.c (bfd_arch_i386_fill): Updated to support multi byte
+ nop instructions.
+ (bfd_arch_i386_short_nop_fill): New.
+ (bfd_arch_i386_long_nop_fill): Likewise.
+ Use bfd_arch_i386_short_nop_fill in 32bit bfd_arch_info
+ initializers. Use bfd_arch_i386_long_nop_fill on 64bit
+ bfd_arch_info initializers.
+
+ * cpu-k1om.c (bfd_arch_i386_fill): Renamed to ...
+ (bfd_arch_i386_short_nop_fill): This.
+ Update bfd_arch_info initializers.
+ * cpu-l1om.c: Likewise.
+
+2012-02-08 Alan Modra <amodra@gmail.com>
+
+ * elflink.c (_bfd_elf_gc_mark_rsec): Mark weakdef syms too.
+ (_bfd_elf_fix_symbol_flags): When a weakdef is def_regular, clear
+ the correct h->u.weakdef.
+
+2012-02-07 Alan Modra <amodra@gmail.com>
+
+ * elf.c (elf_find_function): Don't use internal_elf_sym.
+ (_bfd_elf_maybe_function_sym): Likewise. Replace elf_symbol_type
+ parameter with asymbol.
+ * elf64-ppc.c (ppc64_elf_maybe_function_sym): Likewise.
+ * elf-bfd.h (_bfd_elf_maybe_function_sym): Update prototype.
+ (struct elf_backend_data <maybe_function_sym>): Likewise.
+
+2012-02-02 Vidya Praveen (vidya.praveen@atmel.com)
+
+ PR bfd/13410
+ * elf32-avr.c (elf32_avr_relax_section): Correct the
+ condition that qualifies the candidates for relaxation.
+
+2012-02-02 Tristan Gingold <gingold@adacore.com>
+
+ * bfdio.c (real_fopen): Remove unused vms_modes variable.
+
+2012-02-02 Tristan Gingold <gingold@adacore.com>
+
+ * mach-o.c (bfd_mach_o_read_header): Silent uninitialized
+ variable warning.
+
+2012-02-02 Tristan Gingold <gingold@adacore.com>
+
+ * archive.c (bfd_slurp_armap): Fix thinko in cast.
+
+2012-01-31 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/13616
+ * archures.c (bfd_arch_info): Add fill.
+ (bfd_default_arch_struct): Add bfd_arch_default_fill.
+ (bfd_arch_default_fill): New.
+
+ * configure.in: Set bfd version to 2.22.52.
+ * configure: Regenerated.
+
+ * cpu-alpha.c: Add bfd_arch_default_fill to bfd_arch_info
+ initializer.
+ * cpu-arc.c: Likewise.
+ * cpu-arm.c: Likewise.
+ * cpu-avr.c: Likewise.
+ * cpu-bfin.c: Likewise.
+ * cpu-cr16.c: Likewise.
+ * cpu-cr16c.c: Likewise.
+ * cpu-cris.c: Likewise.
+ * cpu-crx.c: Likewise.
+ * cpu-d10v.c: Likewise.
+ * cpu-d30v.c: Likewise.
+ * cpu-dlx.c: Likewise.
+ * cpu-epiphany.c: Likewise.
+ * cpu-fr30.c: Likewise.
+ * cpu-frv.c: Likewise.
+ * cpu-h8300.c: Likewise.
+ * cpu-h8500.c: Likewise.
+ * cpu-hppa.c: Likewise.
+ * cpu-i370.c: Likewise.
+ * cpu-i860.c: Likewise.
+ * cpu-i960.c: Likewise.
+ * cpu-ia64.c: Likewise.
+ * cpu-ip2k.c: Likewise.
+ * cpu-iq2000.c: Likewise.
+ * cpu-lm32.c: Likewise.
+ * cpu-m10200.c: Likewise.
+ * cpu-m10300.c: Likewise.
+ * cpu-m32c.c: Likewise.
+ * cpu-m32r.c: Likewise.
+ * cpu-m68hc11.c: Likewise.
+ * cpu-m68hc12.c: Likewise.
+ * cpu-m68k.c: Likewise.
+ * cpu-m88k.c: Likewise.
+ * cpu-mcore.c: Likewise.
+ * cpu-mep.c: Likewise.
+ * cpu-microblaze.c: Likewise.
+ * cpu-mips.c: Likewise.
+ * cpu-mmix.c: Likewise.
+ * cpu-moxie.c: Likewise.
+ * cpu-msp430.c: Likewise.
+ * cpu-mt.c: Likewise.
+ * cpu-ns32k.c: Likewise.
+ * cpu-openrisc.c: Likewise.
+ * cpu-or32.c: Likewise.
+ * cpu-pdp11.c: Likewise.
+ * cpu-pj.c: Likewise.
+ * cpu-plugin.c: Likewise.
+ * cpu-powerpc.c: Likewise.
+ * cpu-rl78.c: Likewise.
+ * cpu-rs6000.c: Likewise.
+ * cpu-rx.c: Likewise.
+ * cpu-s390.c: Likewise.
+ * cpu-score.c: Likewise.
+ * cpu-sh.c: Likewise.
+ * cpu-sparc.c: Likewise.
+ * cpu-spu.c: Likewise.
+ * cpu-tic30.c: Likewise.
+ * cpu-tic4x.c: Likewise.
+ * cpu-tic54x.c: Likewise.
+ * cpu-tic6x.c: Likewise.
+ * cpu-tic80.c: Likewise.
+ * cpu-tilegx.c: Likewise.
+ * cpu-tilepro.c: Likewise.
+ * cpu-v850.c: Likewise.
+ * cpu-vax.c: Likewise.
+ * cpu-w65.c: Likewise.
+ * cpu-we32k.c: Likewise.
+ * cpu-xc16x.c: Likewise.
+ * cpu-xstormy16.c: Likewise.
+ * cpu-xtensa.c: Likewise.
+ * cpu-z80.c: Likewise.
+ * cpu-z8k.c: Likewise.
+
+ * cpu-i386.c: Include "libiberty.h".
+ (bfd_arch_i386_fill): New.
+ Add bfd_arch_i386_fill to bfd_arch_info initializer.
+
+ * cpu-k1om.c: Add bfd_arch_i386_fill to bfd_arch_info initializer.
+ * cpu-l1om.c: Likewise.
+
+ * linker.c (default_data_link_order): Call abfd->arch_info->fill
+ if fill size is 0.
+
+ * bfd-in2.h: Regenerated.
+
+2012-01-27 Michael Eager <eager@eagercon.com>
+
+ * elf32-microblaze.c (create_got_section):
+ Reuse existing .rela.got section.
+
+2012-01-23 Alan Modra <amodra@gmail.com>
+
+ * elf-bfd.h: Formatting.
+ (struct elf_backend_data): Add "maybe_function_sym".
+ (_bfd_elf_maybe_function_sym): Declare.
+ * elfxx-target.h (elf_backend_maybe_function_sym): Define.
+ (elfNN_bed): Init new field.
+ * elf.c (elf_find_function): Use maybe_function_sym.
+ (_bfd_elf_maybe_function_sym): New function.
+ * elf64-ppc.c (elf_backend_maybe_function_sym): Define.
+ (ppc64_elf_maybe_function_sym): New function.
+
+2012-01-20 Francois Gouget <fgouget@codeweavers.com>
+
+ PR binutils/13534
+ * archive.c (_bfd_ar_sizepad): New function. Correctly install and
+ pad the size field in an archive header.
+ (_bfd_generic_read_ar_hdr_mag): Use the correct type and scan
+ function for the archive size field.
+ (bfd_generic_openr_next_archived_file): Likewise.
+ (do_slurp_coff_armap): Likewise.
+ (_bfd_write_archive_contents): Likewise.
+ (_bfd_bsd44_write_ar_hdr): Use the new function.
+ (bfd_ar_hdr_from_filesystem): Likewise.
+ (_bfd_write_archive_contents): Likewise.
+ (bsd_write_armap): Likewise.
+ (coff_write_armap): Likewise.
+ * archive64.c (bfd_elf64_archive_write_armap): Likewise.
+ * bfdio.c (bfd_bread): Use correct type for archive element
+ sizes.
+ * ar.c (open_inarch): Likewise.
+ (extract_file): Likewise.
+ * libbfd-in.h (struct areltdata): Use correct types for
+ parsed_size and extra_size fields.
+ Prototype _bfd_ar_sizepad function.
+ * libbfd.h: Regenerate.
+
+2012-01-20 Ulrich Weigand <ulrich.weigand@linaro.org>
+
+ * elf.c (elfcore_write_prpsinfo): Provide unconditionally.
+ Return NULL if core file generation is unsupported.
+ (elfcore_write_prstatus): Likewise.
+ * elf32-arm.c (elf32_arm_nabi_write_core_note): New function.
+ (elf_backend_write_core_note): Define.
+
+2012-01-19 Tristan Gingold <gingold@adacore.com>
+
+ * pef.c: Add a comment.
+ * xsym.c: Likewise.
+
+2012-01-17 Alan Modra <amodra@gmail.com>
+
+ * elf32-ppc.c (ppc_elf_write_core_note <NT_PRPSINFO>): Don't leave
+ trailing garbage in the note.
+ * elf64-ppc.c (ppc64_elf_write_core_note <NT_PRPSINFO>): Likewise.
+
+2012-01-16 Daniel Green <venix1@gmail.com>
+
+ PR ld/13491
+ * coff-i386.c (coff_i386_rtype_to_howto <R_SECREL32>): Test
+ h->root.type not h->type.
+ * coff-x86_64.c (coff_amd64_rtype_to_howto <R_AMD64_SECREL>): Likewise.
+
+2012-01-13 Iain Sandoe <idsandoe@googlemail.com>
+
+ * mach-o.c (bfd_mach_o_build_dysymtab_command): Handle absolute
+ indirect symbols.
+
+2012-01-13 Iain Sandoe <idsandoe@googlemail.com>
+
+ * mach-o.c (bfd_mach_o_write_relocs): Move computation of relocs file
+ position from here... to (bfd_mach_o_build_seg_command): Here.
+
+2012-01-12 Iain Sandoe <idsandoe@googlemail.com>
+
+ * mach-o.c (bfd_mach_o_count_indirect_symbols): New.
+ (bfd_mach_o_build_dysymtab_command): Populate indirect symbol table.
+ * mach-o.h (bfd_mach_o_asymbol): Move declaration to start of the
+ file. (bfd_mach_o_section): Add indirect_syms field.
+
+2012-01-11 Iain Sandoe <idsandoe@googlemail.com>
+
+ * mach-o.c (bfd_mach_o_build_seg_command): Separate computation of
+ vmsize from filesize. Don't compute offsets or file sizes for
+ zerofill sections.
+
+2012-01-11 Iain Sandoe <idsandoe@googlemail.com>
+
+ * mach-o.c (bfd_mach_o_build_commands): Make the building of each
+ command type independent.
+
+2012-01-11 Alan Modra <amodra@gmail.com>
+
+ * elf64-ppc.c: Define more insns used in plt call stubs.
+ (ppc64_elf_brtaken_reloc): Assume isa version 2 or above.
+ (ppc64_elf_relocate_section): Likewise.
+ (enum ppc_stub_type): Add ppc_stub_plt_call_r2save.
+ (struct ppc_link_hash_table): Increase size of stub_count array.
+ Add plt_stub_align and plt_thread_safe.
+ (ALWAYS_USE_FAKE_DEP, ALWAYS_EMIT_R2SAVE): Define.
+ (plt_stub_size, plt_stub_pad): New functions.
+ (build_plt_stub): Emit barriers for power7 thread safety. Don't
+ emit needless save of r2.
+ (build_tls_get_addr_stub): Adjust params.
+ (ppc_build_one_stub): Handle ppc_stub_plt_call_r2save and aligning
+ plt stubs. Adjust build_*plt_stub calls.
+ (ppc_size_one_stub): Similarly.
+ (ppc64_elf_size_stubs): Accept plt_thread_safe and plt_stub_align
+ params. Choose default for plt_thread_safe based on existence of
+ calls to thread creation functions. Modify plt_call to
+ plt_call_r2save when no tocsave reloc found. Align tail of stub
+ sections.
+ (ppc64_elf_build_stubs): Align tail of stub sections. Adjust
+ output of stub statistics.
+ (ppc64_elf_relocate_section): Handle ppc_stub_plt_call_r2save.
+ * elf64-ppc.h (ppc64_elf_size_stubs): Update prototype.
+
+2012-01-10 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/13581
+ * elf64-x86-64.c (elf_x86_64_relocate_section): Remove ABI_64_P
+ check on R_X86_64_PCXX.
+
+2012-01-10 Tristan Gingold <gingold@adacore.com>
+
+ * mach-o.c (bfd_mach_o_build_commands): Avoid uninitialized false
+ warning.
+
+2012-01-10 Tristan Gingold <gingold@adacore.com>
+
+ * bfdio.c (bfd_tell): Handle nested archives.
+ (bfd_seek): Ditto.
+ * cache.c (bfd_cache_lookup_worker): Ditto.
+ * archive.c (_bfd_get_elt_at_filepos): Remove code dealing with
+ nested archives.
+ (bfd_generic_openr_next_archived_file): Likewise.
+
+2012-01-09 Iain Sandoe <idsandoe@googlemail.com>
+
+ * mach-o.c (bfd_mach_o_bfd_copy_private_symbol_data): Implement.
+ (bfd_mach_o_write_symtab): Remove handling for indirect syms.
+ (bfd_mach_o_primary_symbol_sort_key): Likewise.
+ (bfd_mach_o_cf_symbols): Likewise.
+ (bfd_mach_o_sort_symbol_table): Remove.
+ (bfd_mach_o_mangle_symbols): Adjust arguments, remove handling
+ for indirect and dysymtab counts. Do the symbol sorting here.
+ (bfd_mach_o_build_dysymtab_command): Count the symbol types here.
+ Make the indirect symbols a TODO.
+ (bfd_mach_o_build_commands): Adjust call to bfd_mach_o_mangle_symbols.
+ (bfd_mach_o_make_empty_symbol): Specifically flag unset symbols with
+ a non-zero value.
+ (bfd_mach_o_read_symtab_symbol): Record the symbol index.
+ (bfd_mach_o_read_symtab_symbol): Adjust recording of global status.
+ * mach-o.h (mach_o_data_struct): Remove indirect and dysymtab entries.
+ (IS_MACHO_INDIRECT): Remove.
+ (SYM_MACHO_FIELDS_UNSET, SYM_MACHO_FIELDS_NOT_VALIDATED): New.
+
+2012-01-06 Nick Clifton <nickc@redhat.com>
+
+ PR binutils/13121
+ * reloc.c (bfd_generic_lookup_section_flags): Rename 'finfo' to
+ 'flaginfo' to avoid conflicts with AIX system headers.
+
+2012-01-06 Tristan Gingold <gingold@adacore.com>
+
+ * bfdio.c (bfd_bread): Use arelt_size macro.
+
+2012-01-06 Tristan Gingold <gingold@adacore.com>
+
+ * config.bfd (i[3-7]86-*-darwin*): Define targ64_selvecs.
+
+2012-01-05 Nick Clifton <nickc@redhat.com>
+
+ PR ld/12161
+ * elf32-avr.c (elf32_avr_relax_delete_bytes): Read in relocs if
+ necessary.
+
+2012-01-05 Jan Kratochvil <jan.kratochvil@redhat.com>
+
+ Fix zero registers core files when built by gcc-4.7.
+ * elf64-x86-64.c (elf_x86_64_write_core_note): Remove variables p and
+ size. Call elfcore_write_note for the local variables. Remove the
+ final elfcore_write_note call. Add NOTREACHED comments.
+
+2012-01-04 Tristan Gingold <gingold@adacore.com>
+
+ * mach-o.c (bfd_mach_o_fat_stat_arch_elt): New function.
+ (bfd_mach_o_generic_stat_arch_elt): Adjust.
+
+2012-01-04 Tristan Gingold <gingold@adacore.com>
+
+ * mach-o.c (bfd_mach_o_fat_member_init): New function.
+ (bfd_mach_o_openr_next_archived_file): Reindent.
+ Adjust to call bfd_mach_o_fat_member_init.
+ (bfd_mach_o_fat_extract): Adjust to call bfd_mach_o_fat_member_init.
+
+2012-01-04 Tristan Gingold <gingold@adacore.com>
+
+ * mach-o-x86-64.c (bfd_mach_o_x86_64_swap_reloc_out): Handle
+ BFD_RELOC_32, BFD_RELOC_MACH_O_X86_64_PCREL32_1,
+ BFD_RELOC_MACH_O_X86_64_PCREL32_2,
+ BFD_RELOC_MACH_O_X86_64_PCREL32_4,
+ BFD_RELOC_MACH_O_X86_64_BRANCH32,
+ BFD_RELOC_MACH_O_X86_64_SUBTRACTOR32,
+ BFD_RELOC_MACH_O_X86_64_GOT.
+
+2012-01-04 Tristan Gingold <gingold@adacore.com>
+
+ * mach-o.h (bfd_mach_o_fvmlib_command): New structure.
+ (bfd_mach_o_load_command): Add fvmlib field.
+
+ * mach-o.c (bfd_mach_o_read_fvmlib): New function.
+ (bfd_mach_o_read_command): Handle fvmlib.
+
+2012-01-04 Tristan Gingold <gingold@adacore.com>
+
+ * mach-o.c (bfd_mach_o_convert_architecture): Reindent.
+ Decode msubtype for ARM.
+
+2012-01-04 Tristan Gingold <gingold@adacore.com>
+
+ * mach-o.c (bfd_mach_o_get_synthetic_symtab): Add comments.
+
+2012-01-04 Tristan Gingold <gingold@adacore.com>
+
+ * mach-o.h: Reindent header.
+ (bfd_mach_o_encryption_info_command): New structure.
+ (bfd_mach_o_load_command): Add encryption_info field.
+
+ * mach-o.c (bfd_mach_o_read_encryption_info): New function.
+ (bfd_mach_o_read_command): Handle BFD_MACH_O_LC_ENCRYPTION_INFO.
+ (bfd_mach_o_read_command): Adjust error message.
+
+2012-01-04 Shinichiro Hamaji <shinichiro.hamaji@gmail.com>
+
+ * dwarf2.c (_bfd_dwarf2_slurp_debug_info): Factor out the part
+ which reads DWARF2 and stores in stash from find_line.
+ (find_line) Call _bfd_dwarf2_slurp_debug_info.
+ * libbfd-in.h (_bfd_dwarf2_slurp_debug_info): Add declaration.
+ * libbfd.h (_bfd_dwarf2_slurp_debug_info): Regenerate.
+ * mach-o.c (dsym_subdir): The name of subdir where debug
+ information may be stored.
+ (bfd_mach_o_lookup_uuid_command): New. Lookup a load command whose
+ type is UUID.
+ (bfd_mach_o_dsym_for_uuid_p): New. Check if the specified BFD is
+ corresponding to the executable.
+ (bfd_mach_o_find_dsym): New. Find a debug information BFD in the
+ specified binary file.
+ (bfd_mach_o_follow_dsym): New. Find a debug information BFD for
+ the original BFD.
+ (bfd_mach_o_find_nearest_line): Check dSYM files for Mach-O
+ executables, dylibs, and bundles.
+ (bfd_mach_o_close_and_cleanup): Clean up BFDs for the dSYM file.
+ * mach-o.h (dsym_bfd): The BFD of the dSYM file.
+
+2012-01-03 Iain Sandoe <idsandoe@googlemail.com>
+
+ * mach-o.c (bfd_mach_o_mangle_symbols): Put in the section index
+ for stabd symbols.
+ (bfd_mach_o_primary_symbol_sort_key): Adjust for stabs.
+ (bfd_mach_o_cf_symbols): Likewise.
+
+2012-01-03 Iain Sandoe <idsandoe@googlemail.com>
+
+ * mach-o.c (bfd_mach_o_mangle_symbols): Correct typo.
+
+2012-01-03 Iain Sandoe <idsandoe@googlemail.com>
+
+ * mach-o.c (bfd_mach_o_write_symtab): Fill in the string table index
+ as the value of an indirect symbol. Keep the string table index in
+ non-indirect syms for reference.
+ (bfd_mach_o_write_dysymtab): New.
+ (bfd_mach_o_primary_symbol_sort_key): New.
+ (bfd_mach_o_cf_symbols): New.
+ (bfd_mach_o_sort_symbol_table): New.
+ (bfd_mach_o_mangle_symbols): Return early if no symbols. Sort symbols.
+ If we are emitting a dysymtab, process indirect symbols and count the
+ number of each other kind.
+ (bfd_mach_o_mangle_sections): New.
+ (bfd_mach_o_write_contents): Split out some pre-requisite code into
+ the command builder. Write dysymtab if the command is present.
+ (bfd_mach_o_count_sections_for_seg): New.
+ (bfd_mach_o_build_seg_command): New.
+ (bfd_mach_o_build_dysymtab_command): New.
+ (bfd_mach_o_build_commands): Reorganize to support the fact that some
+ commands are optional and should not be emitted if there are no
+ sections or symbols.
+ (bfd_mach_o_set_section_contents): Amend comment.
+ * mach-o.h: Amend and add to comments.
+ (mach_o_data_struct): Add fields for dysymtab symbols counts and a
+ pointer to the indirects, when present.
+ (bfd_mach_o_should_emit_dysymtab): New macro.
+ (IS_MACHO_INDIRECT): Likewise.
+
+For older changes see ChangeLog-2011
+
+Copyright (C) 2012 Free Software Foundation, Inc.
+
+Copying and distribution of this file, with or without modification,
+are permitted in any medium without royalty provided the copyright
+notice and this notice are preserved.
+
+Local Variables:
+mode: change-log
+left-margin: 8
+fill-column: 74
+version-control: never
+End:
diff --git a/bfd/ChangeLog-2013 b/bfd/ChangeLog-2013
new file mode 100644
index 0000000..01cdac4
--- /dev/null
+++ b/bfd/ChangeLog-2013
@@ -0,0 +1,3239 @@
+2013-12-30 Ilya Tocar <ilya.tocar@intel.com>
+
+ * peXXigen.c (rsrc_process_section): Use ptrdiff_t as the type for
+ pointer arithmetic.
+
+2013-12-20 Alan Modra <amodra@gmail.com>
+
+ * elf-eh-frame.c (cie_eq): Return false when initial_insn_length
+ is too large.
+ (cie_compute_hash): Don't exceed bounds of initial_instructions.
+ (_bfd_elf_parse_eh_frame): Always set initial_insn_length, and
+ save as much of insns to initial_instructions[] as will fit.
+
+2013-12-19 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR binutils/16317
+ * elf.c (assign_section_numbers): Set the SHF_INFO_LINK bit for
+ SHT_REL/SHT_RELA sections when setting the sh_info field.
+
+2013-12-19 Pierre Muller <muller@sourceware.org>
+
+ * peXXigen.c (rsrc_cmp): Fix unused variable warning.
+
+2013-12-19 Pierre Muller <muller@sourceware.org>
+
+ * peXXigen.c (u16_mbtouc): Avoid unused function warning by excluding
+ if __CYGWIN__ or __MINGW32__ macro is defined.
+ (rsrc_cmp): Fix Windows host version and version without wchar header.
+ [__CYGWIN__, __MINGW32__]: Introduce rsrccmp macro.
+ Fix coding standard issues.
+
+2013-12-19 Andreas Schwab <schwab@suse.de>
+
+ * elf32-m68k.c (elf_m68k_add_symbol_hook): New function.
+ (elf_backend_add_symbol_hook): Define.
+
+2013-12-18 Nick Clifton <nickc@redhat.com>
+
+ * peXXigen.c (rsrc_print_section): Use ptrdiff_t as the type for
+ pointer arithmetic.
+
+2013-12-17 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf32-arm.c (elf32_arm_post_process_headers): Call
+ _bfd_elf_post_process_headers.
+
+2013-12-17 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf32-spu.c (spu_elf_post_process_headers): Call
+ _bfd_elf_post_process_headers.
+ * elfxx-mips.c (_bfd_mips_post_process_headers): Likewise.
+
+2013-12-17 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf-bfd.h (_bfd_elf_set_osabi): Renamed to ...
+ (_bfd_elf_post_process_headers): This.
+ * elf.c (_bfd_elf_compute_section_file_positions): Always
+ call elf_backend_post_process_headers.
+ (_bfd_elf_set_osabi): Renamed to ...
+ (_bfd_elf_post_process_headers): This.
+ * elf32-hppa.c (elf_backend_post_process_headers): Removed.
+ * elf32-i370.c (elf_backend_post_process_headers): Likewise.
+ * elf32-msp430.c (elf_backend_post_process_headers): Likewise.
+ * elf32-ppc.c (elf_backend_post_process_headers): Likewise.
+ * elf32-sparc.c (elf_backend_post_process_headers): Likewise.
+ * elf64-hppa.c (elf_backend_post_process_headers): Likewise.
+ * elf64-ppc.c (elf_backend_post_process_headers): Likewise.
+ * elf64-sparc.c (elf_backend_post_process_headers): Likewise.
+ * elf64-x86-64.c (elf_backend_post_process_headers): Likewise.
+ * (elf_backend_post_process_headers): Likewise.
+ * (elf_backend_post_process_headers): Likewise.
+ * elf32-i386.c (elf_backend_post_process_headers): Don't
+ define as _bfd_elf_set_osabi.
+ (elf_i386_fbsd_post_process_headers): Updated.
+ * elf32-mips.c (elf_fbsd_post_process_headers): Removed.
+ (elf_backend_post_process_headers): Likewise.
+ * elf32-tic6x.c (elf32_tic6x_set_osabi): Removed.
+ (elf_backend_post_process_headers): Likewise.
+ * elf64-mips.c (elf_fbsd_post_process_headers): Removed.
+ (elf_backend_post_process_headers): Likewise.
+ * elfn32-mips.c (elf_fbsd_post_process_headers): Removed.
+ (elf_backend_post_process_headers): Likewise.
+ * elfnn-aarch64.c (elfNN_aarch64_post_process_headers): Updated.
+ * elfxx-target.h (elf_backend_post_process_headers): Default
+ to _bfd_elf_post_process_headers.
+
+2013-12-17 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR binutils/16318
+ * elf32-arm.c (elf32_arm_copy_private_bfd_data): Call
+ _bfd_elf_copy_private_bfd_data.
+ * elf32-bfin.c (bfin_elf_copy_private_bfd_data): Removed.
+ (elf32_bfinfdpic_copy_private_bfd_data): Likewise.
+ (bfd_elf32_bfd_copy_private_bfd_data): Don't define.
+ * elf32-frv.c (frv_elf_copy_private_bfd_data): Removed.
+ (elf32_frvfdpic_copy_private_bfd_data): Likewise.
+ (bfd_elf32_bfd_copy_private_bfd_data): Don't define.
+ * elf32-iq2000.c (iq2000_elf_copy_private_bfd_data): Removed.
+ (bfd_elf32_bfd_copy_private_bfd_data): Don't define.
+ * elf32-lm32.c (lm32_elf_copy_private_bfd_data): Removed.
+ (lm32_elf_fdpic_copy_private_bfd_data): Call
+ _bfd_elf_copy_private_bfd_data.
+ * elf32-mep.c (mep_elf_copy_private_bfd_data): Removed.
+ (bfd_elf32_bfd_copy_private_bfd_data): Don't define.
+ * elf32-msp430.c (elf32_msp430_copy_private_bfd_data): Removed.
+ (bfd_elf32_bfd_copy_private_bfd_data): Don't define.
+ * elf32-mt.c (mt_elf_copy_private_bfd_data): Removed.
+ (bfd_elf32_bfd_copy_private_bfd_data): Don't define.
+ * elf32-sh.c (sh_elf_set_private_flags): Removed.
+ (sh_elf_copy_private_data): Call _bfd_elf_copy_private_bfd_data
+ and sh_elf_set_mach_from_flags.
+ * elfnn-aarch64.c (elfNN_aarch64_copy_private_bfd_data): Removed.
+ (bfd_elfNN_bfd_copy_private_bfd_data): Don't define.
+
+2013-12-17 H.J. Lu <hongjiu.lu@intel.com>
+
+ * peXXigen.c (rsrc_process_section): Rename index to indx.
+
+2013-12-17 Nick Clifton <nickc@redhat.com>
+
+ * peXXigen.c: Include wchar.h if available.
+ Include safe-ctype.h.
+ (HighBitSet, SetHighBit, WithoutHighBit): New macros.
+ (pe_print_resource_entries): Rename to
+ rsrc_print_resource_entries. Handle names that are not RVAs.
+ (pe_print_resource_directory): Rename to
+ rsrc_print_resource_directory.
+ (pe_print_rsrc): Rename to rsrc_print_section. Corrupt
+ computation of RVA bias.
+ (rsrc_count_entries): New function.
+ (rsrc_count_directory): New function.
+ (rsrc_parse_entry): New function.
+ (rsrc_parse_entries): New function.
+ (rsrc_parse_directory): New function.
+ (rsrc_write_string): New function.
+ (rsrc_compute_rva): New function.
+ (rsrc_write_leaf): New function.
+ (rsrc_write_entry): New function.
+ (rsrc_write_directory): New function.
+ (u16_mbtouc): New function.
+ (rsrc_cmp): New function.
+ (rsrc_print_name): New function.
+ (rsrc_resource_name): New function.
+ (rsrc_merge_string_entries): New function.
+ (rsrc_sort_entries): New function.
+ (rsrc_attach_chain): New function.
+ (rsrc_merge): New function.
+ (rsrc_process_section): New function - merges the contents of a
+ .rsrc section.
+ (_bfd_XXi_final_link_postscript): Call rsrc_process_section.
+ (rsrc_print_section): Fix mingw64 size issue.
+
+ * configure.in (AC_CHECK_HEADERS): Add wchar.h
+ * config.in: Regenerate.
+ * configure: Regenerate.
+
+2013-12-16 Andreas Schwab <schwab@suse.de>
+
+ * elf64-ppc.c (ppc64_elf_relocate_section): Add newline to error
+ message.
+
+2013-12-14 Alan Modra <amodra@gmail.com>
+
+ * elflink.c (_bfd_elf_merge_symbol): If merging a new weak
+ symbol that will be skipped, we don't have a new definition.
+
+2013-12-13 Kuan-Lin Chen <kuanlinchentw@gmail.com>
+ Wei-Cheng Wang <cole945@gmail.com>
+
+ * Makefile.am (BFD32_BACKENDS, BFD32_BACKENDS_CFILES): Add nds32
+ files.
+ * Makefile.in: Regenerate.
+ * archures.c (bfd_nds32_arch): Add nds32 target.
+ * bfd-in2.h: Regenerate.
+ * config.bfd (nds32*le-*-linux): Add bfd_elf32_nds32lelin_vec
+ and bfd_elf32_nds32belin_vec.
+ (nds32*be-*-linux*): Likewise.
+ (nds32*le-*-*): Add bfd_elf32_nds32le_vec and bfd_elf32_nds32be_vec.
+ (nds32*be-*-*): Likewise.
+ * configure.in (bfd_elf32_nds32be_vec): Add elf32-nds32.lo.
+ (bfd_elf32_nds32le_vec): Likewise.
+ (bfd_elf32_nds32belin_vec): Likewise.
+ (bfd_elf32_nds32lelin_vec): Likewise.
+ * configure: Regenerate.
+ * cpu-nds32.c: New file for nds32.
+ * elf-bfd.h: Add NDS32_ELF_DATA.
+ * elf32-nds32.c: New file for nds32.
+ * elf32-nds32.h: New file for nds32.
+ * libbfd.h: Regenerate.
+ * reloc.c: Add relocations for nds32.
+ * targets.c (bfd_elf32_nds32be_vec): New declaration for nds32.
+ (bfd_elf32_nds32le_vec): Likewise.
+ (bfd_elf32_nds32belin_vec): Likewise.
+ (bfd_elf32_nds32lelin_vec): Likewise.
+
+2013-12-12 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR binutils/16318
+ * elf.c (_bfd_elf_copy_private_bfd_data): Remove BFD_ASSERT.
+ Set e_flags only if elf_flags_init is FALSE. Copy EI_OSABI
+ field.
+
+2013-12-12 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf32-sh.c (bfd_elf32_bfd_set_private_bfd_flags): Removed.
+
+2013-12-12 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf.c (assign_file_positions_except_relocs): Set e_type in ELF
+ header to ET_EXEC for -pie -Ttext-segment=.
+
+2013-12-08 Alan Modra <amodra@gmail.com>
+
+ * elflink.c (_bfd_elf_add_default_symbol): Set dynamic_def
+ and ref_dynamic_nonweak when chaining together indirect
+ symbols.
+
+2013-12-06 Tristan Gingold <gingold@adacore.com>
+
+ * pei-x86_64.c (pex64_xdata_print_uwd_codes): Add argument rf.
+ Display epilog opcode.
+ (pex64_dump_xdata): Add argument rf; make addr a local variable.
+ Adjust call to pex64_xdata_print_uwd_codes.
+ (pex64_bfd_print_pdata): Display code range, adjust call to
+
+2013-12-05 Tristan Gingold <gingold@adacore.com>
+
+ * mach-o.c (bfd_mach_o_mkobject_init): Use bfd_zalloc.
+
+2013-12-03 Nick Clifton <nickc@redhat.com>
+
+ * peXXigen.c (pe_print_resource_entries): New function: Displays
+ an entry in a .rsrc section.
+ (pe_print_resource_directory): New function: Displays a directory
+ in a .rsrc section.
+ (pe_print_rsrc): New function: Displays the contents of .rsrc
+ section.
+ (_bfd_XX_print_private_bfd_data_common): Call pe_print_rsrc.
+
+2013-12-03 Alan Modra <amodra@gmail.com>
+
+ * elf64-ppc.c (ppc_build_one_stub <ppc_stub_plt_branch_r2off>):
+ Don't omit saving of r2 for ELFv2. Don't addi 2,2,0.
+ (ppc_size_one_stub <ppc_stub_plt_branch_r2off>): Adjust to suit.
+
+2013-12-03 Alan Modra <amodra@gmail.com>
+
+ * elf64-ppc.c (ppc64_elf_link_just_syms): Remove .got check.
+ Handle ELFv2.
+
+2013-11-26 Will Newton <will.newton@linaro.org>
+
+ * elfnn-aarch64.c (elfNN_aarch64_finish_dynamic_symbol):
+ Handle STT_GNU_IFUNC symbols correctly in static links.
+
+2013-11-26 Will Newton <will.newton@linaro.org>
+
+ * elfnn-aarch64.c (elfNN_aarch64_final_link_relocate): Ensure
+ PLT_INDEX is calculated using correct header size.
+
+2013-11-22 Cory Fields <cory@coryfields.com>
+
+ * libcoff-in.h: Add insert_timestamp flag to the pe_data struct.
+ * libcoff.h: Regenerate.
+ * peXXigen.c (_bfd_XXi_only_swap_filehdr_out): Only use a real
+ timestamp if --insert-timestamp was used.
+
+2013-11-19 Roland McGrath <mcgrathr@google.com>
+
+ * elf-nacl.c (nacl_modify_segment_map): Calculate SIZEOF_HEADERS
+ when not doing linking (i.e. INFO is a null pointer).
+
+2013-11-19 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf64-x86-64.c (elf_x86_64_section_from_shdr): Re-indent.
+
+2013-11-17 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf64-x86-64.c (x86_64_elf_howto_table): Add R_X86_64_PC32_BND
+ and R_X86_64_PLT32_BND.
+ (R_X86_64_standard): Replace R_X86_64_RELATIVE64 with
+ R_X86_64_PLT32_BND.
+ (IS_X86_64_PCREL_TYPE): Add R_X86_64_PLT32_BND.
+ (x86_64_reloc_map): Add BFD_RELOC_X86_64_PC32_BND and
+ BFD_RELOC_X86_64_PLT32_BND.
+ (elf_x86_64_check_relocs): Handle R_X86_64_PC32_BND and
+ R_X86_64_PLT32_BND.
+ (elf_x86_64_gc_sweep_hook): Likewise.
+ (elf_x86_64_relocate_section): Likewise.
+ * reloc.c (bfd_reloc_code_real): Add BFD_RELOC_X86_64_PC32_BND
+ and BFD_RELOC_X86_64_PLT32_BND.
+ * bfd-in2.h: Regenerated.
+ * libbfd.h: Likewise.
+
+2013-11-15 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf32-i386.c (elf_i386_allocate_dynrelocs): Make room for
+ PLT0 directly.
+ * elf64-x86-64.c (elf_x86_64_allocate_dynrelocs): Likewise.
+
+2013-11-14 Nick Clifton <nickc@redhat.com>
+
+ PR ld/16017
+ * elf32-arm.c (elf32_arm_populate_plt_entry): Return a boolean
+ value, TRUE for success, FALSE for failure.
+ Fail if attempting to create a PLT entry for a thumb only target.
+ (elf32_arm_final_link_relocate): Check result of calling
+ elf32_arm_populate_plt_entry.
+ (elf32_arm_finish_dynamic_symbol): Likewise.
+
+2013-11-14 Guy Martin <gmsoft@tuxicoman.be>
+
+ PR ld/16082
+ * elf32-hppa.c (elf32_hppa_hide_symbol): Remove old version
+ information when forcing a symbol to be local.
+
+2013-11-13 Yufeng Zhang <yufeng.zhang@arm.com>
+
+ * elfnn-aarch64.c (elfNN_aarch64_howto_table): Use
+ R_AARCH64_TLS_DTPMOD64 instead of R_AARCH64_TLS_DTPMOD;
+ likewise for R_AARCH64_TLS_DTPREL and R_AARCH64_TLS_TPREL.
+
+2013-11-12 Matthew Leach <Matthew.Leach@arm.comm>
+
+ * elfxx-aarch64.c (_bfd_aarch64_elf_grok_prstatus): Fix hard-coded
+ size of struct elf_prstatus.
+
+2013-11-11 Alan Modra <amodra@gmail.com>
+
+ * elf64-ppc.c (allocate_dynrelocs): Revert 2013-11-04 change.
+
+2013-11-11 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * elf64-ppc.c (ppc64_elf_edit_toc): Use SYMBOL_REFERENCES_LOCAL
+ here, not SYMBOL_CALLS_LOCAL.
+ (ppc64_elf_relocate_section): Likewise.
+ (size_global_entry_stubs): Set undefined symbols on their global
+ entry stubs here..
+ (build_global_entry_stubs): ..rather than here.
+ (ppc64_elf_build_stubs): Don't reset glink->size before calling
+ build_global_entry_stubs.
+
+2013-11-07 Roland McGrath <mcgrathr@google.com>
+
+ * archures.c (bfd_mach_i386_nacl): Fix definition so it doesn't
+ collide with bfd_mach_l1om.
+ * bfd-in2.h: Regenerate.
+
+ * elf32-i386.c (elf32_i386_nacl_elf_object_p): New function.
+ (elf_backend_object_p): Use that in elf32-i386-nacl definition.
+ * elf64-x86-64.c (elf64_x86_64_nacl_elf_object_p): New function.
+ (elf_backend_object_p): Use that in elf64-x86-64-nacl definition.
+ (elf32_x86_64_nacl_elf_object_p): New function.
+ (elf_backend_object_p): Use that in elf32-x86-64-nacl definition.
+
+2013-11-05 DJ Delorie <dj@redhat.com>
+
+ * elf32-rl78.c (elf32_rl78_relax_delete_bytes): Make sure relocs
+ are loaded before trying to use them.
+
+2013-11-05 H.J. Lu <hongjiu.lu@intel.com>
+ Bernhard Rosenkränzer <bernhard.rosenkranzer@linaro.org>
+
+ PR ld/4409
+ * elf-bfd.h (RELOC_FOR_GLOBAL_SYMBOL): Add an argument for
+ error ignored.
+ * elf-m10200.c (mn10200_elf_relocate_section): Updated.
+ * elf-m10300.c (mn10300_elf_relocate_section): Likewise.
+ * elf32-arm.c (elf32_arm_relocate_section): Likewise.
+ * elf32-avr.c (elf32_avr_relocate_section): Likewise.
+ * elf32-bfin.c (bfinfdpic_relocate_section): Likewise.
+ (bfin_relocate_section): Likewise.
+ * elf32-cr16.c (elf32_cr16_relocate_section): Likewise.
+ * elf32-cr16c.c (elf32_cr16c_relocate_section): Likewise.
+ * elf32-cris.c (cris_elf_relocate_section): Likewise.
+ * elf32-crx.c (elf32_crx_relocate_section): Likewise.
+ * elf32-d10v.c (elf32_d10v_relocate_section): Likewise.
+ * elf32-epiphany.c (epiphany_elf_relocate_section): Likewise.
+ * elf32-fr30.c (fr30_elf_relocate_section): Likewise.
+ * elf32-frv.c (elf32_frv_relocate_section): Likewise.
+ * elf32-h8300.c (elf32_h8_relocate_section): Likewise.
+ * elf32-hppa.c (elf32_hppa_relocate_section): Likewise.
+ * elf32-i386.c (elf_i386_relocate_section): Likewise.
+ * elf32-i860.c (elf32_i860_relocate_section): Likewise.
+ * elf32-ip2k.c (ip2k_elf_relocate_section): Likewise.
+ * elf32-iq2000.c (iq2000_elf_relocate_section): Likewise.
+ * elf32-lm32.c (lm32_elf_relocate_section): Likewise.
+ * elf32-m68hc1x.c (elf32_m68hc11_relocate_section): Likewise.
+ * elf32-m68k.c (elf_m68k_relocate_section): Likewise.
+ * elf32-metag.c (elf_metag_relocate_section): Likewise.
+ * elf32-microblaze.c (microblaze_elf_relocate_section): Likewise.
+ * elf32-mcore.c (mcore_elf_relocate_section): Likewise.
+ * elf32-mep.c (mep_elf_relocate_section): Likewise.
+ * elf32-moxie.c (moxie_elf_relocate_section): Likewise.
+ * elf32-msp430.c (elf32_msp430_relocate_section): Likewise.
+ * elf32-mt.c (mt_elf_relocate_section): Likewise.
+ * elf32-nios2.c (nios2_elf32_relocate_section): Likewise.
+ * elf32-openrisc.c (openrisc_elf_relocate_section): Likewise.
+ * elf32-ppc.c (ppc_elf_relocate_section): Likewise.
+ * elf32-rl78.c (rl78_elf_relocate_section): Likewise.
+ * elf32-rx.c (rx_elf_relocate_section): Likewise.
+ * elf32-tic6x.c (elf32_tic6x_relocate_section): Likewise.
+ * elf32-tilepro.c (tilepro_elf_relocate_section): Likewise.
+ * elf32-s390.c (elf_s390_relocate_section): Likewise.
+ * elf32-v850.c (v850_elf_relocate_section): Likewise.
+ * elf32-vax.c (elf_vax_relocate_section): Likewise.
+ * elf32-xc16x.c (elf32_xc16x_relocate_section): Likewise.
+ * elf32-xstormy16.c (xstormy16_elf_relocate_section): Likewise.
+ * elf32-xtensa.c (elf_xtensa_relocate_section): Likewise.
+ * elf64-alpha.c (elf64_alpha_relocate_section): Likewise.
+ * elf64-ia64-vms.c (elf64_ia64_relocate_section): Likewise.
+ * elf64-mmix.c (mmix_elf_relocate_section): Likewise.
+ * elf64-ppc.c (ppc64_elf_relocate_section): Likewise.
+ * elf64-s390.c (elf_s390_relocate_section): Likewise.
+ * elf64-x86-64.c (elf64_x86_64_relocate_section): Likewise.
+ * elfxx-sparc.c (_bfd_sparc_elf_relocate_section): Likewise.
+ * elfxx-tilegx.c (tilegx_elf_relocate_section): Likewise.
+ * elfnn-aarch64.c (elfNN_aarch64_relocate_section): Likewise.
+
+ * elfnn-ia64.c (elfNN_ia64_relocate_section): Skip if error
+ from RELOC_FOR_GLOBAL_SYMBOL in executable is ignored.
+
+2013-11-05 Alan Modra <amodra@gmail.com>
+
+ * elf64-ppc.c (ppc64_elf_func_desc_adjust): Make .TOC. defined and
+ hidden.
+ (ppc64_elf_set_toc): Adjust.
+
+2013-11-05 Alan Modra <amodra@gmail.com>
+
+ * elf64-ppc.c (struct ppc_link_hash_table): Remove got, plt, relplt,
+ iplt, reliplt. Update all references to use elf.sgot, elf.splt,
+ elf.srelplt, elf.iplt and elf.irelplt.
+
+2013-11-03 Sandra Loosemore <sandra@codesourcery.com>
+
+ * elf32-niso2.c (nios2_elf32_do_hi16_relocate): Remove incorrect
+ ATTRIBUTE_UNUSED from parameter.
+ (nios2_elf_do_lo16_relocate): Likewise.
+ (nios2_elf32_do_hiadj16_relocate): Likewise.
+ (nios2_elf32_do_pcrel_lo16_relocate): Likewise.
+ (nios2_elf32_do_pcrel_hiadj16_relocate): Likewise.
+ (nios2_elf32_do_pcrel16_relocate): Likewise.
+ (nios2_elf32_do_call26_relocate): Likewise.
+ (nios2_elf32_do_gprel_relocate): Likewise.
+ (nios2_elf32_do_ujmp_relocate): Likewise.
+ (nios2_elf32_do_cjmp_relocate): Likewise.
+ (nios2_elf32_do_callr_relocate): Likewise.
+ (nios2_elf32_gc_mark_hook): Likewise.
+
+2013-11-04 Alan Modra <amodra@gmail.com>
+
+ * elf64-ppc.c (ppc64_elf_relocate_section): Edit global entry
+ prologue to non-PIC in non-PIC executables.
+
+2013-11-04 Alan Modra <amodra@gmail.com>
+
+ * elf64-ppc.c (ppc64_elf_copy_indirect_symbol): Copy
+ pointer_equality_needed flag.
+ (ppc64_elf_check_relocs): For ELFv2 arrange to emit plt
+ entries for references to functions in shared libraries on
+ non-call relocs.
+ (readonly_dynrelocs): Split into function of the same name and..
+ (maybe_set_textrel): ..this new function. Update call.
+ (ppc64_elf_adjust_dynamic_symbol): Don't emit dynrelocs for
+ ELFv2 in most cases if we have a plt entry. Use new
+ readonly_relocs.
+ (allocate_dynrelocs): For ELFv2, don't allocate dynreloc space
+ for ifunc in static executables.
+ (size_global_entry_stubs): New function.
+ (ppc64_elf_size_dynamic_sections): Call size_global_entry_stubs.
+ Save end of glink branch table.
+ (ppc64_elf_hash_symbol): New function.
+ (build_global_entry_stubs): New function.
+ (ppc64_elf_build_stubs): Call build_global_entry_stubs. Adjust
+ glink sizing.
+ (ppc64_elf_relocate_section): Tidy plt16/32/64 reloc code.
+ (ppc64_elf_finish_dynamic_symbol): For ELFv2, adjust symbols
+ defined on plt code.
+
+2013-11-02 Alan Modra <amodra@gmail.com>
+
+ * opncls.c (_bfd_new_bfd): Don't init vars already zeroed.
+
+2013-11-02 Alan Modra <amodra@gmail.com>
+
+ * elf64-ppc.c (ppc64_elf_next_input_section): Always set toc_off
+ to value for object file.
+
+2013-11-01 Roland McGrath <mcgrathr@google.com>
+
+ * elf-nacl.c (segment_eligible_for_headers): Drop requirement that
+ some section have SEC_HAS_CONTENTS set. It's not set for
+ .note.gnu.build-id, and a segment of only read-only SHT_NOBITS
+ sections is implausible and not really supportable anyway.
+
+2013-10-30 Alan Modra <amodra@gmail.com>
+
+ * elf32-ppc.c (ppc_elf_size_dynamic_sections): Use new DT_PPC_OPT
+ tag to specify tls optimisation.
+ * elf64-ppc.c (ppc64_elf_size_dynamic_sections): Likewise.
+ (ppc64_elf_finish_dynamic_sections): Specify whether multiple
+ toc pointers are used via DT_PPC64_OPT.
+
+2013-10-30 Alan Modra <amodra@gmail.com>
+
+ * elf64-ppc.c (STK_LR, STK_TOC, STK_LINKER): Define.
+ (savegpr0_tail, restgpr0_tail, savefpr0_tail, restfpr0_tail)
+ build_plt_stub, build_tls_get_addr_stub, ppc_build_one_stub,
+ ppc64_elf_relocate_section): Use new defines.
+
+2013-10-30 Alan Modra <amodra@gmail.com>
+
+ * elf64-ppc.c (PLT_ENTRY_SIZE, PLT_INITIAL_ENTRY_SIZE): Add htab
+ parameter and adjust for ELFv2. Update all uses.
+ (PLT_CALL_STUB_SIZE): Delete.
+ (ppc64_elf_get_synthetic_symtab): Support new glink layout.
+ (allocate_dynrelocs): Likewise.
+ (plt_stub_size, build_plt_stub): Adjust for ELFv2.
+ (get_r2off): Return 0 for ELFv2 -R.
+ (ppc_build_one_stub, ppc_size_one_stub): Adjust for ELFv2.
+ (ppc64_elf_size_stubs): Likewise.
+ (ppc64_elf_build_stubs): Add new ELFv2 glink.
+
+2013-10-30 Alan Modra <amodra@gmail.com>
+ Ulrich Weigand <uweigand@de.ibm.com>
+
+ * elf64-ppc.c (struct ppc_stub_hash_entry): Add "other".
+ (stub_hash_newfunc): Init new ppc_stub_hash_entry field, and one
+ we forgot, "plt_ent".
+ (ppc64_elf_add_symbol_hook): Check ELFv1 objects don't have
+ st_other bits only valid in ELFv2.
+ (ppc64_elf_merge_symbol_attribute): New function.
+ (ppc_type_of_stub): Add local_off param to test branch range.
+ (ppc_build_one_stub): Adjust destinations for ELFv2 locals.
+ (ppc_size_one_stub, toc_adjusting_stub_needed): Similarly.
+ (ppc64_elf_size_stubs): Pass local_off to ppc_type_of_stub.
+ Set "other" field.
+ (ppc64_elf_relocate_section): Adjust destination for ELFv2 local
+ calls.
+
+2013-10-30 Alan Modra <amodra@gmail.com>
+
+ * elf64-ppc.c (abiversion, set_abiversion): New functions.
+ (ppc64_elf_get_synthetic_symtab): Handle ELFv2 objects without .opd.
+ (struct ppc_link_hash_table): Add opd_abi.
+ (ppc64_elf_check_relocs): Check no .opd with ELFv2.
+ (ppc64_elf_merge_private_bfd_data): New function.
+ (ppc64_elf_print_private_bfd_data): New function.
+ (ppc64_elf_tls_setup): Set htab->opd_abi.
+ (ppc64_elf_size_dynamic_sections): Don't emit OPD related dynamic
+ tags for ELFv2.
+ (ppc_build_one_stub): Use R_PPC64_IRELATIVE for ELFv2 ifunc.
+ (ppc64_elf_finish_dynamic_symbol): Likewise
+
+2013-10-30 Alan Modra <amodra@gmail.com>
+
+ * elf64-ppc.c (build_plt_stub): Switch stubs to use r11 as base
+ reg and r12 as destination.
+ (ppc_build_one_stub): Likewise.
+ (ppc64_elf_build_stubs): Likewise for glink.
+
+2013-10-30 Alan Modra <amodra@gmail.com>
+
+ * reloc.c (BFD_RELOC_PPC64_ADDR16_HIGH, BFD_RELOC_PPC64_ADDR16_HIGHA,
+ BFD_RELOC_PPC64_TPREL16_HIGH, BFD_RELOC_PPC64_TPREL16_HIGHA,
+ BFD_RELOC_PPC64_DTPREL16_HIGH, BFD_RELOC_PPC64_DTPREL16_HIGHA): New.
+ * elf64-ppc.c (ppc64_elf_howto_raw): Add entries for new relocs.
+ Make all _HA and _HI relocs report signed overflow.
+ (ppc64_elf_reloc_type_lookup): Handle new relocs.
+ (must_be_dyn_reloc, ppc64_elf_check_relocs): Likewise.
+ (dec_dynrel_count, ppc64_elf_relocate_section): Likewise.
+ (ppc64_elf_relocate_section): Don't apply 0x8000 adjust to
+ R_PPC64_TPREL16_HIGHER, R_PPC64_TPREL16_HIGHEST,
+ R_PPC64_DTPREL16_HIGHER, and R_PPC64_DTPREL16_HIGHEST.
+ * libbfd.h: Regenerate.
+ * bfd-in2.h: Regenerate.
+
+2013-10-29 Roland McGrath <mcgrathr@google.com>
+
+ * elf64-x86-64.c (elf_x86_64_nacl_plt0_entry): Correct 9-byte nop
+ sequence to match what the assembler generates.
+
+2013-10-29 Jan Beulich <jbeulich@suse.com>
+
+ * elflink.c (struct elf_outext_info): Add field file_sym_done.
+ (bfd_elf_final_link): Initialize new field. Move fake STT_FILE
+ symbol emission from here ...
+ (elf_link_output_extsym): ... to here.
+
+2013-10-24 Nick Clifton <nickc@redhat.com>
+
+ PR binutils/15994
+ * dwarf2.c (lookup_address_in_line_info_table): Change return type
+ to be the range of addresses covered by the table.
+ (comp_unit_find_nearest_line): Likewise.
+ (find_line): Search all CUs. Select the one that matches and
+ covers the smallest address range.
+
+2013-10-18 Hans-Peter Nilsson <hp@axis.com>
+
+ * elf32-cris.c (cris_elf_check_relocs): Don't assume
+ a registered dynobj means that a .got has been created.
+
+2013-10-17 Alan Modra <amodra@gmail.com>
+
+ PR 16056
+ * elf.c (copy_elf_program_header): Only consider SEC_ALLOC sections
+ when finding lowest_section.
+
+2013-10-14 Chao-ying Fu <Chao-ying.Fu@imgtec.com>
+
+ * elfxx-mips.c (mips_elf_obj_tdata): Add abi_msa_bfd.
+ (mips_elf_merge_obj_attributes): Set abi_msa_bfd to the first object
+ file that has a Tag_GNU_MIPS_ABI_MSA attribute.
+ Merge Tag_GNU_MIPS_ABI_MSA attributes.
+
+2013-10-14 Nick Clifton <nickc@redhat.com>
+
+ * gen-aout.c (main): Fix formatting. Close file.
+
+2013-10-13 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * elfxx-mips.c (mips_use_local_got_p): New function.
+ (mips_elf_count_got_symbols, mips_elf_calculate_relocation): Use it.
+ (_bfd_mips_elf_check_relocs): Set pointer_equality_needed for
+ GOT and absolute references.
+
+2013-10-09 Roland McGrath <mcgrathr@google.com>
+
+ * elf64-alpha.c (elf64_alpha_relax_tls_get_addr): Cast switch
+ expression to int to silence over-eager compiler warnings.
+
+ * xcofflink.c (_bfd_xcoff_bfd_final_link): Don't touch EREL in
+ loop that doesn't use (or initialize) it.
+
+ * elfxx-tilegx.c (tilegx32_plt_tail_entry, tilegx32_plt_tail_entry):
+ Move second const qualifier so it applies to the pointer.
+
+2013-10-09 Nick Clifton <nickc@redhat.com>
+
+ PR binutils/16022
+ * elf32-rx.c (rx_dump_symtab): Add missing break statements.
+
+2013-10-09 Tom Tromey <tromey@redhat.com>
+
+ * opncls.c (get_alt_debug_link_info_shim): Update type of 'len'.
+
+2013-10-09 Nick Clifton <nickc@redhat.com>
+
+ PR ld/16021
+ * elf32-rl78.c (rl78_dump_symtab): Delete.
+ (rl78_get_reloc): Delete.
+
+2013-10-09 Tom Tromey <tromey@redhat.com>
+
+ * bfd-in2.h: Rebuild.
+ * opncls.c (bfd_get_alt_debug_link_info): Change type of
+ buildid_len to bfd_size_type.
+
+2013-10-09 Sergio Durigan Junior <sergiodj@redhat.com>
+
+ PR binutils/15993
+ * elf32-m32c.c (dump_symtab): Add missing "break;" statement on each
+ "case". Reindent "switch" statements.
+
+2013-10-08 Tom Tromey <tromey@redhat.com>
+
+ * bfd-in2.h: Rebuild.
+ * opncls.c (bfd_get_alt_debug_link_info): Add buildid_len
+ parameter. Change type of buildid_out. Update.
+ (get_alt_debug_link_info_shim): New function.
+ (bfd_follow_gnu_debuglink): Use it.
+
+2013-10-08 Andreas Schwab <schwab@suse.de>
+
+ * elf32-m68k.c (elf_m68k_size_dynamic_sections): Add DT_DEBUG also
+ for PIE executables.
+
+2013-10-04 Jan-Benedict Glaw <jbglaw@lug-owl.de>
+
+ * configure: Regenerate.
+
+2013-10-03 Will Newton <will.newton@linaro.org>
+
+ * configure: Regenerate.
+ * configure.in: Build elf-ifunc.o for AArch64.
+ * elfnn-aarch64.c: Include objalloc.h.
+ (elfNN_aarch64_local_htab_hash): New function.
+ (elfNN_aarch64_local_htab_eq): New function.
+ (elfNN_aarch64_get_local_sym_hash): New function.
+ (elfNN_aarch64_link_hash_table_create): Initialize local STT_GNU_IFUNC
+ symbol hash.
+ (elfNN_aarch64_hash_table_free): Free local STT_GNU_IFUNC symbol hash.
+ (elfNN_aarch64_final_link_relocate): Add sym argument. Add support
+ for handling STT_GNU_IFUNC symbols.
+ (elfNN_aarch64_gc_sweep_hook): Add support for garbage collecting
+ references to STT_GNU_IFUNC symbols.
+ (elfNN_aarch64_adjust_dynamic_symbol): Add support for handling
+ STT_GNU_IFUNC symbols.
+ (elfNN_aarch64_check_relocs): Add support for handling STT_GNU_IFUNC
+ symbols. Ensure we don't increase plt.refcount from -1 to 0.
+ (elfNN_aarch64_post_process_headers): Call _bfd_elf_set_osabi.
+ (elfNN_aarch64_is_function_type): Remove function.
+ (elfNN_aarch64_allocate_dynrelocs): Handle STT_GNU_IFUNC symbols.
+ (elfNN_aarch64_allocate_ifunc_dynrelocs): New function.
+ (elfNN_aarch64_allocate_local_dynrelocs): New function.
+ (elfNN_aarch64_allocate_local_ifunc_dynrelocs): New function.
+ (elfNN_aarch64_size_dynamic_sections): Call
+ elfNN_aarch64_allocate_local_dynrelocs.
+ (elfNN_aarch64_create_small_pltn_entry): Add info argument.
+ Add support for creating .iplt entries for STT_GNU_IFUNC symbols.
+ (elfNN_aarch64_finish_dynamic_symbol): Add support for handling
+ STT_GNU_IFUNC symbols and .iplt.
+ (elfNN_aarch64_finish_local_dynamic_symbol): New function.
+ (elfNN_aarch64_finish_dynamic_sections): Call
+ elfNN_aarch64_finish_local_dynamic_symbol.
+
+2013-09-30 Nick Clifton <nickc@redhat.com>
+
+ * cpu-msp430.c: Use printable names that match the values
+ displayed by readelf.
+
+2013-08-25 Andrew Pinski <apinski@cavium.com>
+
+ * elfnn-aarch64.c (TCB_SIZE): Base on the ARCH_SIZE rather than a
+ fixed size of 16.
+
+2013-09-24 Gregory Fong <gregory.0xf0@gmail.com>
+
+ * elfxx-mips.c (mips_elf_create_got_section): Hide
+ _GLOBAL_OFFSET_TABLE_.
+
+2013-09-24 Alan Modra <amodra@gmail.com>
+
+ * elf32-mips.c (ELF_OSABI): Undef for vxworks.
+
+2013-09-24 Alan Modra <amodra@gmail.com>
+
+ * syms.c (_bfd_stab_section_find_nearest_line): Ignore partial
+ stabs at end of .stab. Tidy variable usage. Don't drop the need
+ for a NULL function name stab if If N_FUN stab is ignored.
+ Ensure index entry count loop matches write loop.
+
+2013-09-20 Alan Modra <amodra@gmail.com>
+
+ * configure: Regenerate.
+
+2013-09-18 Tristan Gingold <gingold@adacore.com>
+
+ * configure.in: Bump version to 2.24.51
+ * configure: Regenerate.
+
+2013-09-17 Doug Gilmore <Doug.Gilmore@imgtec.com>
+
+ * elfxx-mips.c (_bfd_mips_elf_print_private_bfd_data): Handle
+ EF_MIPS_FP64.
+
+2013-08-31 John David Anglin <dave.anglin@bell.net>
+
+ * elf64-hppa.c (elf_hppa_final_link_relocate): Add missing '%' to
+ format string.
+
+2013-08-29 Jakub Jelinek <jakub@redhat.com>
+
+ * elf64-x86-64.c (elf_x86_64_check_tls_transition): Allow
+ 64-bit -mcmodel=large -fpic TLS GD and LD sequences.
+ (elf_x86_64_relocate_section): Handle -mcmodel=large -fpic
+ TLS GD and LD sequences in GD->LE, GD->IE and LD->LE transitions.
+
+2013-08-27 Alan Modra <amodra@gmail.com>
+
+ * elf-bfd.h (struct elf_backend_data): Remove as_needed_cleanup.
+ Add notice_as_needed.
+ * elf64-ppc.c (elf_backend_as_needed_cleanup): Don't define.
+ (elf_backend_notice_as_needed): Define.
+ (ppc64_elf_as_needed_cleanup): Rename and adjust..
+ (ppc64_elf_notice_as_needed): ..to this.
+ * elflink.c (_bfd_elf_notice_as_needed): New function, extracted..
+ (elf_link_add_object_symbols): ..from here.
+ * elfxx-target.h (elf_backend_as_needed_cleanup): Don't define.
+ (elf_backend_notice_as_needed): Define..
+ (elfNN_bed): ..and use here.
+
+2013-08-26 Roland McGrath <mcgrathr@google.com>
+
+ * archures.c (bfd_mach_i386_nacl, bfd_mach_i386_i386_nacl): New macros.
+ (bfd_mach_x86_64_nacl, bfd_mach_x64_32_nacl): New macros.
+ * cpu-i386.c (bfd_arch_i386_onebyte_nop_fill): New function.
+ (bfd_i386_nacl_arch): New variable.
+ (bfd_x86_64_nacl_arch, bfd_x64_32_nacl_arch): New variables.
+ (bfd_x64_32_arch_intel_syntax): Link them into the list.
+ * bfd-in2.h: Regenerate.
+
+2013-08-26 Roland McGrath <mcgrathr@google.com>
+
+ * elf-nacl.c (nacl_modify_segment_map): Fix logic reordering the
+ elf_segment_map list. If an executable segment is page-aligned
+ but does not end with a full page, then append a fake section into
+ the segment map entry that pads out the page.
+ (nacl_final_write_processing): New function. Write the code fill
+ laid out in nacl_modify_segment_map.
+ * elf-nacl.h: Declare it.
+ * elf32-arm.c (elf32_arm_nacl_final_write_processing): New function.
+ (elf_backend_final_write_processing): Define it for NaCl backend.
+ * elf32-i386.c (elf_backend_final_write_processing): Likewise.
+ * elf64-x86-64.c (elf_backend_final_write_processing): Likewise.
+
+ * elf-nacl.c (segment_eligible_for_headers): Rename MAXPAGESIZE
+ parameter to MINPAGESIZE.
+ (nacl_modify_segment_map): Use minpagesize instead of maxpagesize.
+
+ * elf32-arm.c (ELF_MINPAGESIZE, ELF_COMMONPAGESIZE): #undef for NaCl.
+
+2013-08-24 Maciej W. Rozycki <macro@linux-mips.org>
+
+ * elf32-tilepro.c (tilepro_elf_finish_dynamic_sections): Don't
+ set GOT's entry size if there is no ELF section data.
+ * elf64-s390.c (elf_s390_finish_dynamic_sections): Likewise.
+ * elfxx-sparc.c (_bfd_sparc_elf_finish_dynamic_sections):
+ Likewise.
+
+2013-08-23 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf64-x86-64.c (get_elf_x86_64_arch_data): New.
+ (get_elf_x86_64_backend_data): Use it.
+ (elf_x86_64_size_dynamic_sections): Likewise.
+
+2013-08-23 Yuri Chornoivan <yurchor@ukr.net>
+
+ PR binutils/15834
+ * bfdio.c: Fix typos.
+ * elf32-spu.c: Likewise.
+ * elfnn-aarch64.c: Likewise.
+
+2013-08-21 Tristan Gingold <gingold@adacore.com>
+
+ * coff-rs6000.c (_bfd_xcoff_sizeof_headers): Also count
+ .ovrflo sections.
+ * coffcode.h (coff_compute_section_file_positions): Force
+ match between file offset and vma offset.
+
+2013-08-21 Alan Modra <amodra@gmail.com>
+
+ * elflink.c (_bfd_elf_merge_symbol): Set *poldbfd, *poldweak,
+ and *poldalignment before exiting when !relocs_compatible.
+
+2013-08-21 Alan Modra <amodra@gmail.com>
+
+ * elflink.c (_bfd_elf_define_linkage_sym): Don't set STV_INTERNAL
+ symbols to STV_HIDDEN.
+
+2013-08-14 John Tytgat <john@bass-software.com>
+
+ PR ld/15787
+ * elf32-arm.c (elf32_arm_final_link_relocate): Use origin of output
+ segment containing the relocating symbol instead of assuming 0 for
+ sb group relocations.
+
+2013-08-09 Nick Clifton <nickc@redhat.com>
+
+ * elf32-rl78.c (rl78_elf_merge_private_bfd_data): Complain if G10
+ flag bits do not match.
+ (rl78_elf_print_private_bfd_data): Describe G10 flag.
+
+2013-08-05 John Tytgat <john@bass-software.com>
+
+ * po/BLD-POTFILES.in: Regenerate.
+ * po/SRC-POTFILES.in: Likewise.
+
+2013-07-31 John Tytgat <john@bass-software.com>
+
+ PR ld/15787
+ * elf32-arm.c (elf32_arm_final_link_relocate): Base SB on the
+ output section VMA.
+
+2013-07-28 Maciej W. Rozycki <macro@linux-mips.org>
+
+ * elf64-hppa.c (elf64_hppa_finish_dynamic_sections)
+ <DT_HP_LOAD_MAP>: Return unsuccessfully if there's no `.data'
+ section.
+
+2013-07-27 Andrew Pinski <apinski@cavium.com>
+
+ * elfnn-aarch64.c (elfNN_aarch64_check_relocs):
+ Use the correct alignment for
+ _bfd_elf_make_dynamic_reloc_section for ILP32.
+
+2013-07-27 Andrew Pinski <apinski@cavium.com>
+
+ * elfnn-aarch64.c (elfNN_aarch64_howto_from_bfd_reloc): Handle
+ BFD_RELOC_AARCH64_NONE explicitly.
+
+2013-07-27 Maciej W. Rozycki <macro@linux-mips.org>
+
+ * elf32-vax.c (elf_vax_finish_dynamic_sections): Don't set GOT's
+ entry size if there is no ELF section data.
+
+2013-07-27 Maciej W. Rozycki <macro@linux-mips.org>
+
+ * elf32-vax.c (elf_vax_check_relocs) <R_VAX_GOT32, R_VAX_PLT32>:
+ Don't check symbol visibility here. Remove a check already
+ asserted for.
+ (elf_vax_instantiate_got_entries): Use SYMBOL_REFERENCES_LOCAL
+ instead of individual checks.
+ (elf_vax_relocate_section) <R_VAX_GOT32, R_VAX_PLT32>: Only
+ check the offset to decide if produce a GOT or PLT entry.
+ Remove redundant assertions. Remove code to produce GOT entries
+ for local symbols. Remove a duplicate comment and add a comment
+ on GOT relocations.
+ (elf_vax_finish_dynamic_symbol): Remove code to produce RELATIVE
+ dynamic relocs.
+
+2013-07-27 Maciej W. Rozycki <macro@linux-mips.org>
+
+ * elf32-vax.c (elf_vax_always_size_sections): Correct a comment
+ typo.
+
+2013-07-27 Maciej W. Rozycki <macro@linux-mips.org>
+
+ * elf32-vax.c (elf_vax_discard_got_entries): New function.
+ (elf_vax_always_size_sections): Likewise.
+ (elf_vax_size_dynamic_sections): Remove code moved to
+ elf_vax_always_size_sections. Make comment on
+ elf_vax_instantiate_got_entries match reality.
+ (elf_vax_instantiate_got_entries): Assert that rather than check
+ if dynobj is null. Don't check for dynamic_sections_created.
+ Make function description match reality.
+ (elf_backend_always_size_sections): New macro.
+
+2013-07-25 Alan Modra <amodra@gmail.com>
+
+ * elf64-ppc.c (struct ppc64_elf_obj_tdata): Replace opd_relocs
+ with a union.
+ (opd_entry_value): Cache .opd section contents.
+ (ppc64_elf_relocate_section): Adjust.
+
+2013-07-25 Alan Modra <amodra@gmail.com>
+
+ PR ld/15762
+ PR ld/12761
+ * elflink.c (elf_link_add_object_symbols): Correct test in
+ last patch. Remove unnecessary code.
+
+2013-07-24 Tristan Gingold <gingold@adacore.com>
+
+ * coff-rs6000.c (xcoff_howto_table): Fix masks and pc_relative for
+ R_RBR. Add numbers in comments.
+ (_bfd_xcoff_reloc_type_lookup): Handle BFD_RELOC_PPC_B16.
+ * coff64-rs6000.c: Likewise.
+
+2013-07-20 Alan Modra <amodra@gmail.com>
+
+ PR ld/15762
+ PR ld/12761
+ * elflink.c (elf_link_add_object_symbols): Don't clobber
+ .gnu.warning.symbol sections when shared.
+
+2013-07-19 Nick Clifton <nickc@redhat.com>
+
+ * elf32-rx.c (rx_elf_relocate_section): Fix typo: move
+ saw_subtract from R_RX_OPdiv to R_RX_OPneg.
+
+2013-07-18 Travis Snoozy <quandary@remstate.com>
+
+ PR ld/15721
+ * elf32-msp430.c (R_MSP430_10_PCREL): Use 10-bit source and
+ destination masks.
+ * R_MSP430_2X_PCREL: Likewise.
+ * R_MSP430X_10_PCREL: Likewise.
+ * R_MSP430X_2X_PCREL: Likewise.
+
+2013-07-18 Terry Guo <terry.guo@arm.com>
+
+ * elf32-arm.c (arm_type_of_stub): Don't use ST_BRANCH_TO_ARM for
+ thumb only targets.
+ (elf32_arm_final_link_relocate): Likewise.
+
+2013-07-18 Bill Neubauer <wcn@google.com>
+
+ * mach-o.c (mach_o_section_name_xlat dw): Add entry for
+ .debug_gdb_scripts
+
+2013-07-18 Roland McGrath <mcgrathr@google.com>
+
+ * elf32-arm.c (elf32_arm_stub_long_branch_arm_nacl): New variable.
+ (elf32_arm_stub_long_branch_arm_nacl_pic): New variable.
+ (arm_build_one_stub): Increase MAXRELOCS to 3.
+ (arm_type_of_stub): Use them if GLOBALS->nacl_p.
+ (struct elf32_arm_link_hash_table): Give add_stub_section member's
+ pointee type a third argument.
+ (elf32_arm_create_or_find_stub_sec): Update caller.
+ (elf32_arm_size_stubs): Update argument type.
+ * bfd-in.h (elf32_arm_size_stubs): Update decl.
+ * bfd-in2.h: Regenerate.
+ * libbfd.h: Regenerate.
+
+2013-07-15 Maciej W. Rozycki <macro@codesourcery.com>
+
+ * elfxx-mips.c (mips_elf_merge_obj_attributes): Replace hardcoded
+ magic numbers with enum values.
+
+2013-07-12 Roland McGrath <mcgrathr@google.com>
+
+ * reloc.c: Add BFD_RELOC_390_PC12DBL, BFD_RELOC_390_PLT12DBL,
+ BFD_RELOC_390_PC24DBL, BFD_RELOC_390_PLT24DBL (should have
+ been added here with 2013-07-05 elf32-s390.c change).
+ * bfd-in2.h: Regenerate (no-op).
+ * libbfd.h: Regenerate (no-op).
+
+2013-07-12 Maciej W. Rozycki <macro@codesourcery.com>
+
+ * elfxx-mips.c (_bfd_mips_elf_merge_private_bfd_data): Handle
+ EF_MIPS_NAN2008.
+ (_bfd_mips_elf_print_private_bfd_data): Likewise.
+
+2013-07-09 Tristan Gingold <gingold@adacore.com>
+
+ * vms-alpha.c (struct vms_private_data_struct): Remove
+ flag_hash_long_names and flag_show_after_trunc.
+ (hash_string): Remove.
+ (_bfd_vms_length_hash_symbol): Remove.
+ (alpha_vms_write_exec): Remove call to _bfd_vms_length_hash_symbol.
+ (_bfd_vms_write_egsd): Likewise. Rewrite condition.
+ (_bfd_vms_write_ehdr): Remove code that set removed flags.
+ (_bfd_vms_write_etir): Remove call to _bfd_vms_length_hash_symbol.
+ (vms_bfd_is_local_label_name): Remove trace call.
+
+2013-07-09 Tristan Gingold <gingold@adacore.com>
+
+ * hosts/alphavms.h: Include config.h and ansidecl.h, remove useless
+ macros.
+ * configure.com: Adjust to match changes in configure.
+ * makefile.vms (OBJS): Update list.
+
+2013-07-05 Tristan Gingold <gingold@adacore.com>
+
+ * coffcode.h (coff_write_object_contents): Use ".ovrflo" name for
+ overflow sections.
+
+2013-07-05 Andreas Krebbel <Andreas.Krebbel@de.ibm.com>
+
+ * elf32-s390.c: Add new relocation definitions R_390_PC12DBL,
+ R_390_PLT12DBL, R_390_PC24DBL, and R_390_PLT24DBL.
+ (elf_s390_reloc_type_lookup, elf_s390_check_relocs)
+ (elf_s390_gc_sweep_hook, elf_s390_relocate_section): Support new
+ relocations.
+ * elf64-s390.c: See elf32-s390.c
+ * bfd-in2.h: Add new relocs to enum bfd_reloc_code_real.
+ * libbfd.h: Add new reloc strings.
+
+2013-07-03 Marcus Shawcroft <marcus.shawcroft@arm.com>
+
+ * elfnn-aarch64.c (elfNN_aarch64_final_link_relocate): Reorder case
+ values.
+ (elfNN_aarch64_relocate_section): Likewise.
+ (elfNN_aarch64_gc_sweep_hook): Likewise.
+ (elfNN_aarch64_check_relocs): Likewise.
+
+2013-07-03 Alan Modra <amodra@gmail.com>
+
+ * elf64-ppc.c (ppc64_elf_func_desc_adjust): Don't hide .TOC.
+ when relocatable. Don't change root.type or type here.
+ (ppc64_elf_set_toc): Set type of .TOC. to STT_OBJECT.
+
+2013-07-03 Alan Modra <amodra@gmail.com>
+
+ * elf64-ppc.c (struct ppc_stub_hash_entry): Delete "addend".
+ (ppc64_elf_size_stubs): Don't set "addend".
+ (ppc64_elf_relocate_section): Don't allow calls via
+ toc-adjusting stubs without a following nop even in an
+ executable, except for self-calls and both libc_start_main
+ and .libc_start_main.
+
+2013-07-03 Alan Modra <amodra@gmail.com>
+
+ * elf64-ppc.c (ppc64_elf_func_desc_adjust): Hide ".TOC.".
+
+2013-07-02 Tristan Gingold <gingold@adacore.com>
+
+ * coff-rs6000.c (xcoff_find_nearest_line_discriminator): Add missing
+ line.
+
+2013-07-02 Tristan Gingold <gingold@adacore.com>
+
+ * vms-alpha.c (_bfd_generic_find_nearest_line_discriminator): Define.
+ (_bfd_vms_find_nearest_line_discriminator): New function.
+
+2013-07-02 Tristan Gingold <gingold@adacore.com>
+
+ * coff-rs6000.c (xcoff_create_csect_from_smclas): Handle more smclas.
+
+2013-07-02 Tristan Gingold <gingold@adacore.com>
+
+ * coff-rs6000.c (xcoff_find_nearest_line_discriminator): New function.
+ (rs6000coff_vec): Reference it.
+
+2013-07-02 Marcus Shawcroft <marcus.shawcroft@arm.com>
+
+ * elfnn-aarch64.c (aarch64_elf_create_got_section): New.
+ (elfNN_aarch64_check_relocs): Use aarch64_elf_create_got_section.
+ (elfNN_aarch64_create_dynamic_sections): Do not define
+ _GLOBAL_OFFSET_TABLE_; call aarch64_elf_create_got_section.
+
+2013-07-02 Alan Modra <amodra@gmail.com>
+
+ * elf64-ppc.c (ppc64_elf_relocate_section): Set "relocation" for
+ .TOC. after relocatable check.
+
+2013-07-01 Alan Modra <amodra@gmail.com>
+
+ * elf64-ppc.h (ppc64_elf_toc): Delete.
+ (ppc64_elf_set_toc): Declare.
+ * elf64-ppc.c (ppc64_elf_toc_reloc): Replace call to ppc64_elf_toc
+ with call the ppc64_elf_set_toc.
+ (ppc64_elf_toc_ha_reloc, ppc64_elf_toc64_reloc): Likewise.
+ (ppc64_elf_start_multitoc_partition): Likewise.
+ (struct ppc_link_hash_table): Delete dot_toc_dot. Replace all uses
+ with elf.hgot.
+ (ppc64_elf_process_dot_syms): Don't make a fake function descriptor
+ for ".TOC.".
+ (ppc64_elf_check_relocs): Mark sections with a reference to .TOC.
+ as needing a toc pointer.
+ (ppc64_elf_size_stubs): Don't set dot_toc_dot here.
+ (ppc64_elf_set_toc): Rename from ppc64_elf_toc. Add info param.
+ Set elf.hgot value.
+
+2013-06-28 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/15685
+ * elf64-x86-64.c (elf_x86_64_relocate_section): Handle
+ R_X86_64_DTPOFF64.
+
+2013-06-28 Nick Clifton <nickc@redhat.com>
+
+ PR ld/15302
+ * elf32-arm.c (allocate_dynrelocs_for_symbol): Revert previous patch.
+
+2013-06-27 Marcus Shawcroft <marcus.shawcroft@arm.com>
+
+ * elfnn-aarch64.c (elfNN_aarch64_check_relocs): Reserve one slot
+ in sgot.
+ (elfNN_aarch64_finish_dynamic_sections): Place the &_DYNAMIC reference
+ in sgot[0] rather than sgotplt[0].
+
+2013-06-26 Yufeng Zhang <yufeng.zhang@arm.com>
+
+ * Makefile.am (elf32-aarch64.c): Add a #line cpp directive at the
+ beginning of the generated file.
+ (elf64-aarch64.c): Likewise.
+ * Makefile.in: Re-generated.
+
+2013-06-26 Yufeng Zhang <yufeng.zhang@arm.com>
+
+ * Makefile.am (BFD64_BACKENDS): Add elfxx-aarch64.c.
+ (BFD64_BACKENDS_CFILES): Add elfxx-aarch64.lo.
+ * Makefile.in: Re-generated.
+ * configure.in (bfd_elf64_bigaarch64_vec): Add elfxx-aarch64.lo.
+ (bfd_elf64_littleaarch64_vec): Likewise.
+ (bfd_elf32_bigaarch64_vec): Likewise.
+ (bfd_elf32_littleaarch64_vec): Likewise.
+ * configure: Re-generated.
+ * elfxx-aarch64.c: New file; split from elf64-aarch64.c.
+ * elfxx-aarch64.h: New file.
+ * elfnn-aarch64.c: Include "elfxx-aarch64.h"; move the following
+ stuff to elfxx-aarch64.c.
+ (bfd_elf_aarch64_put_addend): Removed.
+ (PG_OFFSET, PG): Likewise.
+ (elfNN_aarch64_small_plt0_entry): Support ELF32.
+ (elfNN_aarch64_tlsdesc_small_plt_entry): Likewise.
+ (elf64_aarch64_grok_prstatus): Removed.
+ (elf_backend_grok_prstatus): Removed.
+ (insn32): Likewise.
+ (aarch64_unsigned_overflow): Likewise.
+ (aarch64_signed_overflow): Likewise.
+ (aarch64_resolve_relocation): Likewise.
+ (MASK): Likewise.
+ (decode_branch_ofs_26): Likewise.
+ (decode_cond_branch_ofs_19): Likewise.
+ (decode_ld_lit_ofs_19): Likewise.
+ (decode_tst_branch_ofs_14): Likewise.
+ (decode_movw_imm): Likewise.
+ (decode_adr_imm): Likewise.
+ (decode_add_imm): Likewise.
+ (reencode_branch_ofs_26): Likewise.
+ (reencode_cond_branch_ofs_19): Likewise.
+ (reencode_ld_lit_ofs_19): Likewise.
+ (reencode_tst_branch_ofs_14): Likewise.
+ (reencode_movw_imm): Likewise.
+ (reencode_adr_imm): Likewise.
+ (reencode_ldst_pos_imm): Likewise.
+ (reencode_add_imm): Likewise.
+ (reencode_movzn_to_movz): Likewise.
+ (reencode_movzn_to_movn): Likewise.
+ (aarch64_relocate): Update to call the new function names in
+ elfxx-aarch64.c.
+ (aarch64_calculate_got_entry_vma): Likewise.
+ (elfNN_aarch64_final_link_relocate): Likewise.
+ (elf64_aarch64_update_plt_entry): Likewise; change the type of the
+ parameter 'r_type' to bfd_reloc_code_real_type; rename to ...
+ (elf_aarch64_update_plt_entry): ... this.
+ (elfNN_aarch64_create_small_pltn_entry): Update.
+ (elfNN_aarch64_init_small_plt0_entry): Remove plt_got_base; add
+ bfd_vma plt_got_2nd_ent; update to call elf_aarch64_update_plt_entry.
+ (elfNN_aarch64_finish_dynamic_sections): Add plt_entry; update to
+ call elf_aarch64_update_plt_entry.
+
+2013-06-26 Yufeng Zhang <yufeng.zhang@arm.com>
+
+ * bfd-in2.h: Re-generated.
+ * elfnn-aarch64.c (HOWTO64, HOWTO32): New define.
+ (IS_AARCH64_TLS_RELOC): Change to be based on the
+ bfd reloc enumerators.
+ (IS_AARCH64_TLSDESC_RELOC): Likewise.
+ (PG, PG_OFFSET): Cast literal to bfd_vma.
+ (elf64_aarch64_howto_table): Removed.
+ (elf64_aarch64_howto_dynrelocs): Removed.
+ (elf64_aarch64_tls_howto_table): Removed.
+ (elf64_aarch64_tlsdesc_howto_table): Removed.
+ (elfNN_aarch64_howto_table): New table to host all howto entires..
+ (R_AARCH64_*): Replaced by AARCH64_R (*) and AARCH64_R_STR (*).
+ (elfNN_aarch64_bfd_reloc_from_howto): New function.
+ (elfNN_aarch64_bfd_reloc_from_type): Ditto.
+ (struct elf_aarch64_reloc_map): New.
+ (elf_aarch64_reloc_map): New table.
+ (elfNN_aarch64_howto_from_bfd_reloc): New function.
+ (elfNN_aarch64_howto_from_type): Update to look up the new table
+ elfNN_aarch64_howto_table.
+ (struct elf64_aarch64_reloc_map): Remove.
+ (elf64_aarch64_reloc_map): Remove.
+ (elfNN_aarch64_reloc_type_lookup): Change to call
+ elfNN_aarch64_howto_from_bfd_reloc.
+ (elfNN_aarch64_reloc_name_lookup): Change to look up the new table
+ elfNN_aarch64_howto_table.
+ (aarch64_resolve_relocation): Refactor to switch on the bfd
+ reloc enumerators.
+ (bfd_elf_aarch64_put_addend): Likewise.
+ (elfNN_aarch64_final_link_relocate): Likewise.
+ (aarch64_tls_transition_without_check): Likewise.
+ (aarch64_reloc_got_type): Likewise.
+ (aarch64_can_relax_tls): Likewise.
+ (aarch64_tls_transition): Likewise.
+ (elfNN_aarch64_tls_relax): Likewise.
+ (elfNN_aarch64_final_link_relocate): Likewise.
+ (elfNN_aarch64_relocate_section): Likewise.
+ (elfNN_aarch64_gc_sweep_hook): Likewise.
+ (elfNN_aarch64_check_relocs): Likewise.
+ (aarch64_tls_transition): Change to return a bfd reloc enumerator.
+ * libbfd.h: Re-generated.
+ * reloc.c: Re-order the AArch64 bfd reloc enumerators.
+ (BFD_RELOC_AARCH64_RELOC_START)
+ (BFD_RELOC_AARCH64_RELOC_END)
+ (BFD_RELOC_AARCH64_LD_GOT_LO12_NC)
+ (BFD_RELOC_AARCH64_LD32_GOT_LO12_NC)
+ (BFD_RELOC_AARCH64_TLSDESC_LD_LO12_NC)
+ (BFD_RELOC_AARCH64_TLSDESC_LD32_LO12_NC)
+ (BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_LO12_NC)
+ (BFD_RELOC_AARCH64_TLSIE_LD32_GOTTPREL_LO12_NC)
+ (BFD_RELOC_AARCH64_IRELATIVE): New relocs.
+
+2013-06-26 Yufeng Zhang <yufeng.zhang@arm.com>
+
+ * Makefile.am (BFD64_BACKENDS): Add elf32-aarch64.lo.
+ (BUILD_CFILES): Add elf32-aarch64.c.
+ (elf32-aarch64.c): New rule for generating from elfnn-aarch64.c.
+ * Makefile.in: Re-generated.
+ * archures.c (bfd_mach_aarch64_ilp32): New define.
+ * bfd-in.h (bfd_elf32_aarch64_init_maps): New declaration.
+ (bfd_elf32_aarch64_set_options): Ditto.
+ (elf32_aarch64_setup_section_lists): Ditto.
+ (elf32_aarch64_next_input_section): Ditto.
+ (elf32_aarch64_size_stubs): Ditto.
+ (elf32_aarch64_build_stubs): Ditto.
+ * bfd-in2.h: Re-generated.
+ * config.bfd (aarch64-*-elf): Add bfd_elf32_littleaarch64_vec
+ and bfd_elf32_bigaarch64_vec.
+ (aarch64-*-linux*): Likewise.
+ (aarch64_be-*-elf): Likewise.
+ (aarch64_be-*-linux*): Likewise.
+ * configure.in (bfd_elf32_bigaarch64_vec)
+ (bfd_elf32_littleaarch64_vec): New.
+ * configure: Re-generated.
+ * cpu-aarch64.c (compatible): Don't allow mixing ilp32 objects with
+ lp64 ones.
+ (bfd_aarch64_arch_ilp32): New.
+ (bfd_aarch64_arch): Link to bfd_aarch64_arch_ilp32.
+ * elfnn-aarch64.c (ARCH_SIZE): New define.
+ (AARCH64_R, AARCH64_R_STR, LOG_FILE_ALIGN): New defines.
+ (GOT_ENTRY_SIZE): Re-define as (ARCH_SIZE / 8).
+ (elf64_aarch64_*): Rename to elfNN_aarch64_*.
+ (ELF64_R_*): Rename to ELFNN_R_*.
+ Plus other paramaterization.
+ * targets.c (bfd_elf32_bigaarch64_vec, bfd_elf32_littleaarch64_vec):
+ New declarations.
+ (_bfd_target_vector): Add bfd_elf32_bigaarch64_vec and
+ bfd_elf32_littleaarch64_vec.
+
+2013-06-26 Yufeng Zhang <yufeng.zhang@arm.com>
+
+ * Makefile.am (BFD64_BACKENDS_CFILES): Remove elf64-aarch64.c.
+ (BUILD_CFILES): Add elf64-aarch64.c.
+ (elf64-aarch64.c): New rule for generating from elfnn-aarch64.c.
+ * Makefile.in: Re-generated.
+ * elf64-aarch64.c: Rename to ...
+ * elfnn-aarch64.c: ... this.
+
+2013-06-25 Maciej W. Rozycki <macro@codesourcery.com>
+ Paul Brook <paul@codesourcery.com>
+
+ * elfxx-mips.h (_bfd_mips_elf_insn32): New prototype.
+ * elfxx-mips.c (mips_elf_link_hash_table): Add insn32 member.
+ (STUB_MOVE32_MICROMIPS, STUB_JALR32_MICROMIPS): New macros.
+ (MICROMIPS_INSN32_FUNCTION_STUB_NORMAL_SIZE): Likewise.
+ (MICROMIPS_INSN32_FUNCTION_STUB_BIG_SIZE): Likewise.
+ (micromips_insn32_o32_exec_plt0_entry): New variable.
+ (micromips_insn32_o32_exec_plt_entry): Likewise.
+ (_bfd_mips_elf_adjust_dynamic_symbol): Handle insn32 mode.
+ (mips_elf_estimate_stub_size): Likewise.
+ (_bfd_mips_elf_size_dynamic_sections): Likewise.
+ (_bfd_mips_elf_finish_dynamic_symbol): Likewise.
+ (mips_finish_exec_plt): Likewise.
+ (_bfd_mips_elf_relax_section): Likewise.
+ (_bfd_mips_elf_insn32): New function.
+ (_bfd_mips_elf_get_synthetic_symtab): Handle insn32 PLT.
+
+2013-06-24 Maciej W. Rozycki <macro@codesourcery.com>
+
+ * elfxx-mips.h (_bfd_mips_elf_get_synthetic_symtab): New
+ prototype.
+ * elf32-mips.c (elf_backend_plt_sym_val): Remove macro.
+ (bfd_elf32_get_synthetic_symtab): New macro.
+ * elfxx-mips.c (plt_entry): New structure.
+ (mips_elf_link_hash_entry): Add use_plt_entry member.
+ (mips_elf_link_hash_table): Rename plt_entry_size member to
+ plt_mips_entry_size. Add plt_comp_entry_size, plt_mips_offset,
+ plt_comp_offset, plt_got_index entries and plt_header_is_comp
+ members.
+ (STUB_LW_MICROMIPS, STUB_MOVE_MICROMIPS): New macros.
+ (STUB_LUI_MICROMIPS, STUB_JALR_MICROMIPS): Likewise.
+ (STUB_ORI_MICROMIPS, STUB_LI16U_MICROMIPS): Likewise.
+ (STUB_LI16S_MICROMIPS): Likewise.
+ (MICROMIPS_FUNCTION_STUB_NORMAL_SIZE): Likewise.
+ (MICROMIPS_FUNCTION_STUB_BIG_SIZE): Likewise.
+ (micromips_o32_exec_plt0_entry): New variable.
+ (mips16_o32_exec_plt_entry): Likewise.
+ (micromips_o32_exec_plt_entry): Likewise.
+ (mips_elf_link_hash_newfunc): Initialize use_plt_entry.
+ (mips_elf_output_extsym): Update to use gotplt_union's plist
+ member rather than offset.
+ (mips_elf_gotplt_index): Likewise. Remove the VxWorks
+ restriction. Use MIPS_ELF_GOT_SIZE to calculate GOT address.
+ (mips_elf_count_got_symbols): Update to use gotplt_union's plist
+ member rather than offset.
+ (mips_elf_calculate_relocation): Handle MIPS16/microMIPS PLT
+ entries.
+ (_bfd_mips_elf_create_dynamic_sections): Don't set PLT sizes
+ here.
+ (mips_elf_make_plt_record): New function.
+ (_bfd_mips_elf_check_relocs): Update comment. Record occurences
+ of JAL relocations that might need a PLT entry.
+ (_bfd_mips_elf_adjust_dynamic_symbol): Update to use
+ gotplt_union's plist member rather than offset. Set individual
+ PLT entry sizes here. Handle MIPS16/microMIPS PLT entries.
+ Don't set the symbol's value in the symbol table for PLT
+ references here. Don't set the PLT or PLT GOT section sizes
+ here.
+ (mips_elf_estimate_stub_size): Handle microMIPS stubs.
+ (mips_elf_allocate_lazy_stub): Likewise.
+ (mips_elf_lay_out_lazy_stubs): Likewise. Define a _MIPS_STUBS_
+ magic symbol.
+ (mips_elf_set_plt_sym_value): New function.
+ (_bfd_mips_elf_size_dynamic_sections): Set PLT header size and
+ PLT and PLT GOT section sizes here. Set the symbol values in
+ the symbol table for PLT references here. Handle microMIPS
+ annotation of the _PROCEDURE_LINKAGE_TABLE_ magic symbol.
+ (_bfd_mips_elf_finish_dynamic_symbol): Update to use
+ gotplt_union's plist member rather than offset. Handle
+ MIPS16/microMIPS PLT entries. Handle microMIPS stubs.
+ (_bfd_mips_vxworks_finish_dynamic_symbol): Update to use
+ gotplt_union's plist member rather than offset. Use
+ MIPS_ELF_GOT_SIZE to calculate GOT address.
+ (mips_finish_exec_plt): Handle microMIPS PLT. Return status.
+ (_bfd_mips_elf_finish_dynamic_sections): Handle result from
+ mips_finish_exec_plt.
+ (_bfd_mips_elf_link_hash_table_create): Update to use
+ gotplt_union's plist member rather than offset.
+ (_bfd_mips_elf_get_synthetic_symtab): New function.
+
+2013-06-24 Wawa <caojinyu@msn.com>
+
+ PR 15657
+ * hash.c (_bfd_stringtab_add): Copy the string if COPY is true.
+
+2013-06-23 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * Makefile.am (BFD32_BACKENDS, BFD32_BACKENDS_CFILES): Move MIPS ELF
+ files to...
+ (BFD64_BACKENDS, BFD64_BACKENDS_CFILES): ...here.
+ * Makefile.in: Regenerate.
+ * config.bfd: Enclose all MIPS ELF targets in #ifdef BFD64.
+ Set want64 to true for them at the end.
+ * targets.c (_bfd_target_vector): Protect MIPS ELF targets with
+ #ifdef BFD64.
+
+2013-06-22 Sandra Loosemore <sandra@codesourcery.com>
+
+ * elf32-nios2.c (nios2_elf32_finish_dynamic_sections): Don't
+ set sh_entsize for PLT section.
+
+2013-06-20 Yufeng Zhang <yufeng.zhang@arm.com>
+
+ * bfd-in.h (bfd_elf64_aarch64_set_options): Add 'extern'.
+ * bfd-in2.h: Re-generated.
+ * elf64-aarch64.c (RELOC_SECTION): Removed.
+ (SWAP_RELOC_IN, SWAP_RELOC_OUT): Ditto.
+ (AARCH64_ELF_OS_ABI_VERSION): Ditto.
+ (elf64_aarch64_link_hash_traverse): Ditto.
+ (elf64_aarch64_size_stubs): Change 'Aarch64' to 'AArch64' in the
+ comment.
+
+2013-06-19 Will Newton <will.newton@linaro.org>
+
+ * configure: Regenerated.
+ * configure.in: Remove aarch64 dependency on elf-ifunc.c.
+ * elf64-aarch64.c: Remove objalloc.h include.
+ (elf64_aarch64_howto_dynrelocs): Remove R_AARCH64_IRELATIVE howto.
+ (struct elf64_aarch64_link_hash_table): Remove ifunc related
+ members. (elf_aarch64_local_htab_hash): Remove function.
+ (elf_aarch64_local_htab_eq): Remove function.
+ (elf_aarch64_get_local_sym_hash): Remove function.
+ (elf64_aarch64_link_hash_table_create): Remove local hash
+ table initialization.
+ (elf64_aarch64_final_link_relocate): Remove sym argument and
+ handling of ifunc symbols.
+ (elf64_aarch64_relocate_section): Don't pass sym argument to
+ elf64_aarch64_final_link_relocate.
+ (elf64_aarch64_gc_sweep_hook): Remove handling of ifunc symbols.
+ (elf64_aarch64_adjust_dynamic_symbol): Likewise.
+ (elf64_aarch64_check_relocs): Likewise.
+ (elf64_aarch64_post_process_headers): Remove call to
+ _bfd_elf_set_osabi.
+ (elf64_aarch64_is_function_type): New function.
+ (elf64_aarch64_allocate_dynrelocs): Remove handling of ifunc
+ symbols. (elf_aarch64_allocate_local_dynrelocs): Remove function.
+ (elf64_aarch64_size_dynamic_sections): Remove call to
+ elf_aarch64_allocate_local_dynrelocs.
+ (elf64_aarch64_create_small_pltn_entry): Remove info argument.
+ Remove creation of R_AARCH64_IRELATIVE dynamic relocs.
+ (elf64_aarch64_finish_dynamic_symbol): Remove handling of ifunc
+ symbols. (elf_aarch64_finish_local_dynamic_symbol): Remove
+ function. (elf64_aarch64_finish_dynamic_sections): Remove call to
+ elf_aarch64_finish_local_dynamic_symbol.
+ (elf64_aarch64_add_symbol_hook): Remove function.
+
+2013-06-14 Yufeng Zhang <yufeng.zhang@arm.com>
+
+ * elf64-aarch64.c (elf64_aarch64_final_link_relocate): Call
+ aarch64_resolve_relocation and bfd_elf_aarch64_put_addend to
+ handle the relocations of R_AARCH64_JUMP26, R_AARCH64_CALL26,
+ R_AARCH64_LD64_GOT_LO12_NC, R_AARCH64_ADR_GOT_PAGE and
+ R_AARCH64_GOT_LD_PREL19.
+
+2013-06-13 Terry Guo <terry.guo@arm.com>
+
+ PR ld/15302
+ * elf32-arm.c (allocate_dynrelocs_for_symbol): Transform
+ ST_BRANCH_TO_ARM into ST_BRANCH_TO_THUMB if the target only
+ supports thumb instructions.
+
+2013-06-11 DJ Delorie <dj@redhat.com>
+
+ * elf32-rl78.c (rl78_elf_relocate_section): Fix OPsub math.
+
+2013-06-11 Will Newton <will.newton@linaro.org>
+
+ * elf64-aarch64.c (elf_aarch64_get_local_sym_hash): Use
+ ELF64_R_SYM instead of ELF32_R_SYM.
+
+2013-06-11 Nick Clifton <nickc@redhat.com>
+
+ * elf32-rl78.c (rl78_elf_finish_dynamic_sections): Onlly run
+ checks if the dynamic sections have been created and relaxation
+ has not been performed.
+
+2013-06-07 Will Newton <will.newton@linaro.org>
+
+ * configure: Regenerate.
+ * configure.in: Build elf-ifunc.o for AArch64.
+ * elf64-aarch64.c: Include objalloc.h.
+ (elf64_aarch64_howto_dynrelocs): Add R_AARCH64_IRELATIVE howto.
+ (struct elf64_aarch64_link_hash_table): Add members for handling
+ R_AARCH64_IRELATIVE relocations.
+ (elf_aarch64_local_htab_hash): New function.
+ (elf_aarch64_local_htab_eq): New function.
+ (elf_aarch64_get_local_sym_hash): New function.
+ (elf64_aarch64_link_hash_table_create): Initialize local STT_GNU_IFUNC
+ symbol hash.
+ (elf64_aarch64_hash_table_free): Free local STT_GNU_IFUNC symbol hash.
+ (elf64_aarch64_final_link_relocate): Add sym argument. Add support
+ for handling STT_GNU_IFUNC symbols.
+ (elf64_aarch64_gc_sweep_hook): Add support for garbage collecting
+ references to STT_GNU_IFUNC symbols.
+ (elf64_aarch64_adjust_dynamic_symbol): Add support for handling
+ STT_GNU_IFUNC symbols.
+ (elf64_aarch64_check_relocs): Add support for handling STT_GNU_IFUNC
+ symbols. Ensure we don't increase plt.refcount from -1 to 0.
+ (elf64_aarch64_post_process_headers): Call _bfd_elf_set_osabi.
+ (elf64_aarch64_is_function_type): Remove function.
+ (elf64_aarch64_allocate_dynrelocs): Call
+ _bfd_elf_allocate_ifunc_dyn_relocs for STT_GNU_IFUNC symbols.
+ (elf_aarch64_allocate_local_dynrelocs): New function.
+ (elf64_aarch64_size_dynamic_sections): Call
+ elf_aarch64_allocate_local_dynrelocs. Initialize next_irelative_index.
+ (elf64_aarch64_create_small_pltn_entry): Add info argument.
+ Add support for creating .iplt entries for STT_GNU_IFUNC symbols.
+ (elf64_aarch64_finish_dynamic_symbol): Add support for handling
+ STT_GNU_IFUNC symbols and .iplt.
+ (elf_aarch64_finish_local_dynamic_symbol): New function.
+ (elf64_aarch64_finish_dynamic_sections): Call
+ elf_aarch64_finish_local_dynamic_symbol.
+ (elf64_aarch64_add_symbol_hook): New function.
+
+2013-06-03 Alan Modra <amodra@gmail.com>
+
+ * syms.c (_bfd_stab_section_find_nearest_line): Add last_str
+ var. Use it with last_stab.
+
+2013-05-30 Paul Brook <paul@codesourcery.com>
+
+ * bfd-in2.h: Regenerate.
+ * elf32-mips.c (elf_mips_eh_howto): New.
+ (bfd_elf32_bfd_reloc_type_lookup ): Support BFD_RELOC_MIPS_EH.
+ (bfd_elf32_bfd_reloc_name_lookup): Likewise.
+ (mips_elf32_rtype_to_howto): Support R_MIPS_EH.
+ * elf64-mips.c (elf_mips_eh_howto): New.
+ (bfd_elf64_bfd_reloc_type_lookup): Support BFD_RELOC_MIPS_EH.
+ (bfd_elf64_bfd_reloc_name_lookup): Likewise.
+ (mips_elf64_rtype_to_howto): Support R_MIPS_EH.
+ * libbfd.h: Regenerate.
+ * reloc.c (BFD_RELOC_MIPS_EH): New.
+
+2013-05-29 Nick Clifton <nickc@redhat.com>
+
+ * dwarf2.c (struct dwarf2_debug): Add fields for handling
+ alternate debug info source.
+ (dwarf_debug_sections): Add entries for alternate .debug_str and
+ .debug_info sections.
+ (dwarf_debug_section_enum): Likewise.
+ (read_alt_indirect_string): New function. Handles a
+ DW_FORM_GNU_strp_alt attribute.
+ (read_alt_indirect_ref): New function. Handles a
+ DW_FORM_GNU_ref_alt attribute.
+ (read_attribute_value): Process DW_FORM_GNU_ref_alt and
+ DW_FORM_GNU_strp_alt.
+ (find_abstract_instance_name): Handle DW_FORM_GNU_ref_alt
+ attributes.
+ (_bfd_dwarf2_cleanup_debug_info): Free alternate debug info
+ sources.
+ * opncls.c (GNU_DEBUGALTLINK): Define.
+ (bfd_get_alt_debug_link_info): New function.
+ (separate_alt_debug_file_exists): New function.
+ (find_separate_debug_file): Add parameters for fetch and check
+ functions.
+ (bfd_follow_gnu_debugaltlink): New function.
+ * bfd-in2.h: Regenerate.
+
+2013-05-28 Yufeng Zhang <yufeng.zhang@arm.com>
+
+ * reloc.c (BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE): Rename to ...
+ (BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21): ... this.
+ (BFD_RELOC_AARCH64_TLSDESC_LD64_PREL19): Rename to ...
+ (BFD_RELOC_AARCH64_TLSDESC_LD_PREL19): ... this.
+ * bfd-in2.h: Regenerate.
+ * libbfd.h: Regenerate.
+ * elf64-aarch64.c (IS_AARCH64_TLSDESC_RELOC): Update to use
+ the correct names.
+ (elf64_aarch64_tlsdesc_howto_table): Likewise.
+ (elf64_aarch64_reloc_map): Likewise.
+ (aarch64_resolve_relocation): Likewise.
+ (bfd_elf_aarch64_put_addend): Likewise.
+ (aarch64_tls_transition_without_check): Likewise.
+ (aarch64_reloc_got_type): Likewise.
+ (elf64_aarch64_final_link_relocate): Likewise.
+ (elf64_aarch64_tls_relax): Likewise.
+ (elf64_aarch64_relocate_section): Likewise.
+ (elf64_aarch64_gc_sweep_hook): Likewise.
+ (elf64_aarch64_check_relocs): Likewise.
+
+2013-05-26 Mark Wielaard <mjw@redhat.com>
+
+ * cache.c (BFD_CACHE_MAX_OPEN): Remove define.
+ (max_open_files): New static int initialized to zero.
+ (bfd_cache_max_open): New static function to set and return
+ max_open_files.
+ (bfd_cache_init): Use bfd_cache_max_open.
+ (bfd_open_file): Likewise.
+ * configure.in (AC_CHECK_HEADERS): Add sys/resource.h.
+ (AC_CHECK_FUNCS): Add getrlimit.
+ * configure: Regenerated.
+ * config.in: Likewise.
+ * sysdep.h: Check and include sys/resource.h for getrlimit.
+
+2013-05-23 Alan Modra <amodra@gmail.com>
+
+ * format.c (bfd_check_format_matches): Don't match a target in
+ targ_selvecs if some other target is a better match. If
+ targets implement match priority, fall back to the first of
+ the best matches.
+
+2013-05-22 Eric Herman <eric@freesa.org>
+
+ PR binutils/15462
+ * elfxx-mips.c (_bfd_mips_elf_relocate_section): Warning fix.
+
+2013-05-22 Ralf Dreesen <gamma@dreesen.net>
+
+ PR binutils/15474
+ * srec.c (srec_set_section_contents): Properly convert size
+ and offset to address when octets_per_byte is not unity.
+
+2013-05-20 Maciej W. Rozycki <macro@linux-mips.org>
+
+ * elf32-vax.c (elf_vax_instantiate_got_entries): Only set the
+ refcount member of the gotplt_union when resetting the reference
+ count. Adjust comment.
+
+2013-05-20 Will Newton <will.newton@linaro.org>
+
+ * elf64-aarch64.c (elf64_aarch64_link_hash_entry): Remove
+ relocs_copied member.
+ (elf64_aarch64_link_hash_newfunc): Remove initialization of
+ relocs_copied member.
+ (elf64_aarch64_copy_indirect_symbol): Remove code to copy
+ relocs_copied member.
+
+2013-05-19 Maciej W. Rozycki <macro@linux-mips.org>
+
+ * elf32-vax.c (elf_vax_adjust_dynamic_symbol): Convert K&R
+ function definition.
+
+2013-05-16 Cary Coutant <ccoutant@google.com>
+
+ * ecoff.c (ecoff_link_check_archive_element): Add initializers for
+ external_ext_size and esize.
+
+2013-05-16 Tristan Gingold <gingold@adacore.com>
+
+ * coff-rs6000.c (_bfd_xcoff_reloc_type_lookup): Handle BFD_RELOC_16.
+ * coff64-rs6000.c (xcoff64_reloc_type_lookup): Likewise.
+
+2013-05-15 Andreas Schwab <schwab@suse.de>
+
+ * elf64-aarch64.c (elf_backend_default_execstack): Define to 0.
+
+2013-05-10 Joel Brobecker <brobecker@adacore.com>
+
+ * coffcode.h (styp_to_sec_flags) [RS6000COFF_C]: Add handling
+ of STYP_EXCEPT, STYP_LOADER and STYP_TYPCHK sections.
+
+2013-05-09 Joel Brobecker <brobecker@adacore.com>
+
+ * bfd.c (_bfd_default_error_handler): Replace use of putc
+ by fputc. Add comment explaining why.
+
+2013-05-09 Alan Modra <amodra@gmail.com>
+
+ * elflink.c (elf_link_add_object_symbols): Don't omit reading
+ of symbols when hashes already exist.
+
+2013-05-07 Will Newton <will.newton@linaro.org>
+
+ * elf-ifunc.c (_bfd_elf_allocate_ifunc_dyn_relocs): Add a
+ plt_header_size argument for ports where it differs from
+ plt_entry_size.
+ * elf-bfd.h: Likewise.
+ * elf32-i386.c: Pass plt_header_size to
+ _bfd_elf_allocate_ifunc_dyn_relocs.
+ * elf64-x86-64.c: Likewise.
+
+2013-05-07 Will Newton <will.newton@linaro.org>
+
+ * elf-ifunc.c (_bfd_elf_create_ifunc_dyn_reloc): Remove unused
+ function.
+ * elf-bfd.h: Likewise.
+
+2013-05-06 Paul Brook <paul@codesourcery.com>
+
+ * elf64-mips.c (elf_mips_gnu_pcrel32): New.
+ (bfd_elf64_bfd_reloc_type_lookup, bfd_elf64_bfd_reloc_name_lookup,
+ mips_elf64_rtype_to_howto): Handle R_MIPS_PC32.
+ * elfn32-mips.c (elf_mips_gnu_pcrel32): New.
+ (bfd_elfn32_bfd_reloc_type_lookup, bfd_elfn32_bfd_reloc_name_lookup,
+ mips_elfn32_rtype_to_howto): Handle R_MIPS_PC32.
+
+2013-05-06 Alan Modra <amodra@gmail.com>
+
+ * elf64-ppc.c (opd_entry_value): Handle case where symbol
+ hashes are not available.
+
+2013-05-06 Alan Modra <amodra@gmail.com>
+
+ * elflink.c (elf_link_add_object_symbols): Don't save symbol
+ hashes around loading as-needed library. Zero them on allocation,
+ and restore to initial all-zero state if library not needed.
+ Arrange to reuse hashes if we load library again later.
+
+2013-05-04 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * elf32-mips.c (elf_mips_copy_howto, elf_mips_jump_slot_howto):
+ Use _bfd_mips_elf_generic_reloc instead of bfd_elf_generic_reloc.
+ * elfn32-mips.c: Likewise.
+ * elf64-mips.c: Likewise.
+
+2013-05-02 Nick Clifton <nickc@redhat.com>
+
+ * archures.c: Add some more MSP430 machine numbers.
+ * config.bfd (msp430): Define targ_selvecs.
+ * configure.in: Add bfd_elf32_msp430_ti_vec.
+ * cpu-msp430.c: Add some more MSP430 machine numbers.
+ * elf32-msp430.c Add support for MSP430X relocations.
+ Add support for TI compiler generated relocations.
+ Add support for sym_diff relocations.
+ Add support for relaxing out of range short branches into long
+ branches.
+ Add support for MSP430 attribute section.
+ * reloc.c: Add MSP430X relocations.
+ * targets.c: Add bfd_elf32_msp430_ti_vec.
+ * bfd-in2.h: Regenerate.
+ * configure: Regenerate.
+ * libbfd.h: Regenerate.
+
+2013-05-01 Maciej W. Rozycki <macro@codesourcery.com>
+
+ * config.bfd: Replace alpha*-*-linuxecoff* pattern with
+ alpha*-*-linux*ecoff*.
+
+2013-04-30 Olaf Flebbe <o.flebbe@science-computing.de>
+
+ PR binutils/15417
+ * elflink.c (elf_link_add_object_symbols): Initialise 'idx' to
+ zero.
+
+2013-04-30 Alan Modra <amodra@gmail.com>
+
+ * elflink.c (bfd_elf_record_link_assignment): Dont make
+ STV_INTERNAL symbols STV_HIDDEN.
+
+2013-04-29 Nick Clifton <nickc@redhat.com>
+
+ * elflink.c (_bfd_elf_gc_mark_extra_sections): Remove mark from
+ fragmented .debug_line sections associated with unmarked code
+ sections.
+
+2013-04-29 Will Newton <will.newton@linaro.org>
+
+ * elf32-arm.c (elf32_arm_populate_plt_entry): Call
+ elf32_arm_add_dynreloc when emitting R_ARM_IRELATIVE relocs.
+
+2013-04-29 Will Newton <will.newton@linaro.org>
+
+ * elf64-aarch64.c (elf64_aarch64_check_relocs): Move relocation
+ error check up and add error message.
+
+2013-04-26 Will Newton <will.newton@linaro.org>
+
+ * elf64-aarch64.c (elf64_aarch64_check_relocs): Remove dead code.
+
+2013-04-25 Alan Modra <amodra@gmail.com>
+
+ * config.bfd: Add powerpc64le-linux.
+
+2013-04-24 H.J. Lu <hongjiu.lu@intel.com>
+
+ * config.bfd (targ_selvecs): Add bfd_elf32_x86_64_vec for
+ x86_64-*-elf*.
+
+2013-04-24 Roland McGrath <mcgrathr@google.com>
+
+ * elf32-arm.c (elf32_arm_allocate_plt_entry): If HTAB->nacl_p,
+ allocate space for PLT header even if IS_IPLT_ENTRY.
+ (arm_nacl_put_plt0): New function, broken out of ...
+ (elf32_arm_finish_dynamic_sections): ... here. Call it.
+ If HTAB->nacl_p, set up the PLT header in .iplt too.
+ (elf32_arm_output_arch_local_syms): If HTAB->nacl_p, write
+ a mapping symbol for the start of .iplt too.
+
+2013-04-19 Luca Pizzamiglio <luca.pizzamiglio@gmail.com>
+
+ * ecoff.c (_bfd_ecoff_sizeof_headers): Cast the return value of
+ BFD_ALIGN to int.
+ * elf32-tic6x.c (elf32_tic6x_size_dynamic_sections): Remove unused
+ variables.
+ * elf32-v850.c (v850_elf_relax_section): Redefine the type of 'i'
+ to bfd_vma.
+ * vms-alpha.c (evax_bfd_print_etir): Initialize sec_len.
+
+2013-04-22 Alan Modra <amodra@gmail.com>
+
+ PR ld/15382
+ * elf-bfd.h (RELOC_AGAINST_DISCARDED_SECTION): Don't multiply
+ sh_size or reloc_count adjustment by count.
+
+2013-04-22 Alan Modra <amodra@gmail.com>
+
+ * elf64-ppc.c (ppc64_elf_check_relocs): Don't call
+ create_linkage_sections here..
+ (ppc64_elf_init_stub_bfd): ..do so here. Return status.
+ (create_linkage_sections): Move earlier in file.
+ (ppc64_elf_setup_section_lists): Remove now useless htab->brlt test.
+ * elf64-ppc.h (ppc64_elf_init_stub_bfd): Update proto.
+
+2013-04-19 Nick Clifton <nickc@redhat.com>
+
+ PR binutils/15356
+ * compress.c (decompress_contents): Always call inflateEnd, even
+ when another inflation operation fails.
+
+2013-04-17 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf-ifunc.c: Update copyright year.
+
+2013-04-17 Luca Pizzamiglio <luca.pizzamiglio@gmail.com>
+
+ * coffcode.h: Added a cast to void when a bfd_set_section_*()
+ macro's return value is ignored.
+ * elf32-hppa.c: Likewise.
+ * elf32-tic6x.c: Likewise.
+ * mach-o.c: Likewise.
+ * mmo.c: Likewise.
+ * opncls.c: Likewise.
+ * peicode.h: Likewise.
+ * elf32-m32r.c: Check return value of bfd_set_section_*().
+ * elfnn-ia64.c: Likewise.
+ * elfxx-mips.c: Likewise.
+ * vms-alpha.c: Likewise.
+
+2013-04-15 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/15371
+ * elf-ifunc.c (_bfd_elf_allocate_ifunc_dyn_relocs): Check
+ regular reference without non-GOT reference when building
+ shared library.
+
+2013-04-15 Alan Modra <amodra@gmail.com>
+
+ * archive.c (_bfd_archive_close_and_cleanup): Clear parent
+ cache slot for archives.
+
+2013-04-14 Hans-Peter Nilsson <hp@bitrange.com>
+
+ * mmo.c (mmo_write_chunk): Break out abfd->tdata.mmo_data to new
+ local variable mmop.
+
+2013-04-09 Senthil Kumar Selvaraj <senthil_kumar.selvaraj@atmel.com>
+
+ PR ld/12494
+ * elf32-avr.c: Consider all sections to determine if linker
+ relaxation can safely delete a ret after a call/jmp
+
+2013-04-09 Mingjie Xing <mingjie.xing@gmail.com>
+
+ * bfd.c (typedef bfd, Error reporting, Miscellaneous): Add
+ INODEs.
+
+2013-04-08 Tom Tromey <tromey@redhat.com>
+
+ * som.c (bfd_section_from_som_symbol): No longer static.
+ * som.h (bfd_section_from_som_symbol): Declare.
+
+2013-04-06 Alan Modra <amodra@gmail.com>
+
+ * elf32-ppc.c (ppc_elf_check_relocs): Use SYMBOLIC_BIND.
+ * elf64-ppc.c (ppc64_elf_check_relocs, dec_dynrel_count): Likewise.
+
+2013-04-05 Nick Clifton <nickc@redhat.com>
+
+ * elflink.c (elf_link_add_object_symbols): Revert accidental commit.
+
+2013-04-04 Alan Modra <amodra@gmail.com>
+
+ * bfd.c (bfd_error_type, bfd_errmsgs): Add bfd_error_missing_dso.
+ * bfd-in2.h: Regenerate.
+ * elflink.c (elf_link_add_object_symbols): Use new error.
+
+2013-04-03 Nick Clifton <nickc@redhat.com>
+
+ * elf32-v850.c (v850_elf_is_target_special_symbol): New function.
+ (bfd_elf32_bfd_is_target_special_symbol): Define.
+
+2013-04-03 Venkataramanan Kumar <venkataramanan.kumar@linaro.org>
+
+ * elf64-aarch64.c (elf64_aarch64_gc_sweep_hook): Use
+ elf64_aarch64_locals to get local GOT reference counts.
+
+2013-04-02 DJ Delorie <dj@redhat.com>
+
+ * elf32-rl78.c (GET_RELOC): Assert that there are relocs to get.
+ (rl78_elf_relax_section): Only fetch the next reloc if there is
+ one expected.
+
+2013-03-30 Alan Modra <amodra@gmail.com>
+
+ PR ld/15323
+ * elf-m10300.c (mn10300_elf_check_relocs): Set non_ir_ref for
+ global symbols referenced by relocs.
+ * elf32-arm.c (elf32_arm_check_relocs): Likewise.
+ * elf32-bfin.c (bfin_check_relocs): Likewise.
+ * elf32-cr16.c (cr16_elf_check_relocs): Likewise.
+ * elf32-cris.c (cris_elf_check_relocs): Likewise.
+ * elf32-d10v.c (elf32_d10v_check_relocs): Likewise.
+ * elf32-dlx.c (elf32_dlx_check_relocs): Likewise.
+ * elf32-fr30.c (fr30_elf_check_relocs): Likewise.
+ * elf32-frv.c (elf32_frv_check_relocs): Likewise.
+ * elf32-hppa.c (elf32_hppa_check_relocs): Likewise.
+ * elf32-i370.c (i370_elf_check_relocs): Likewise.
+ * elf32-iq2000.c (iq2000_elf_check_relocs): Likewise.
+ * elf32-lm32.c (lm32_elf_check_relocs): Likewise.
+ * elf32-m32c.c (m32c_elf_check_relocs): Likewise.
+ * elf32-m32r.c (m32r_elf_check_relocs): Likewise.
+ * elf32-m68hc1x.c (elf32_m68hc11_check_relocs): Likewise.
+ * elf32-m68k.c (elf_m68k_check_relocs): Likewise.
+ * elf32-mcore.c (mcore_elf_check_relocs): Likewise.
+ * elf32-metag.c (elf_metag_check_relocs): Likewise.
+ * elf32-microblaze.c (microblaze_elf_check_relocs): Likewise.
+ * elf32-moxie.c (moxie_elf_check_relocs): Likewise.
+ * elf32-msp430.c (elf32_msp430_check_relocs): Likewise.
+ * elf32-mt.c (mt_elf_check_relocs): Likewise.
+ * elf32-nios2.c (nios2_elf32_check_relocs): Likewise.
+ * elf32-openrisc.c (openrisc_elf_check_relocs): Likewise.
+ * elf32-ppc.c (ppc_elf_check_relocs): Likewise.
+ * elf32-rl78.c (rl78_elf_check_relocs): Likewise.
+ * elf32-s390.c (elf_s390_check_relocs): Likewise.
+ * elf32-score.c (s3_bfd_score_elf_check_relocs): Likewise.
+ * elf32-score7.c (s7_bfd_score_elf_check_relocs): Likewise.
+ * elf32-sh.c (sh_elf_check_relocs): Likewise.
+ * elf32-tic6x.c (elf32_tic6x_check_relocs): Likewise.
+ * elf32-tilepro.c (tilepro_elf_check_relocs): Likewise.
+ * elf32-v850.c (v850_elf_check_relocs): Likewise.
+ * elf32-vax.c (elf_vax_check_relocs): Likewise.
+ * elf32-xstormy16.c (xstormy16_elf_check_relocs): Likewise.
+ * elf32-xtensa.c (elf_xtensa_check_relocs): Likewise.
+ * elf64-aarch64.c (elf64_aarch64_check_relocs): Likewise.
+ * elf64-alpha.c (elf64_alpha_check_relocs): Likewise.
+ * elf64-hppa.c (elf64_hppa_check_relocs): Likewise.
+ * elf64-ia64-vms.c (elf64_ia64_check_relocs): Likewise.
+ * elf64-mmix.c (mmix_elf_check_relocs): Likewise.
+ * elf64-ppc.c (ppc64_elf_check_relocs): Likewise.
+ * elf64-s390.c (elf_s390_check_relocs): Likewise.
+ * elf64-sh64.c (sh_elf64_check_relocs): Likewise.
+ * elfnn-ia64.c (elfNN_ia64_check_relocs): Likewise.
+ * elfxx-sparc.c (_bfd_sparc_elf_check_relocs): Likewise.
+ * elfxx-tilegx.c (tilegx_elf_check_relocs): Likewise.
+ * elfxx-mips.c (_bfd_mips_elf_check_relocs): Likewise. Don't
+ test indirect/warning links for NULL.
+
+2013-03-29 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/15323
+ * elf32-i386.c (elf_i386_check_relocs): Set non_ir_ref if a
+ symbol is referenced by a non-shared object.
+ * elf64-x86-64.c (elf_x86_64_check_relocs): Likewise.
+
+2013-03-28 Joe Seymour <jseymour@codesourcery.com>
+
+ * elf32-sh.c (sh_elf_relocate_section): Suppress warnings for
+ R_SH_REL32 relocations against undefined weak symbols.
+
+2013-03-28 Alan Modra <amodra@gmail.com>
+
+ * elf64-ppc.c (struct ppc_dyn_relocs): New.
+ (ppc64_elf_check_relocs): Separate dynrel counts for local syms
+ into ifunc and non-ifunc.
+ (dec_dynrel_count): Pass in sym rather than sym_sec. Handle
+ separate ifunc/non-ifunc dynrel counts.
+ (allocate_got): Always use reliplt for ifunc.
+ (allocate_dynrelocs): Likewise.
+ (ppc64_elf_size_dynamic_sections): Likewise.
+ (ppc64_elf_layout_multitoc): Likewise.
+ (ppc64_elf_relocate_section): Likewise.
+
+2013-03-28 Alan Modra <amodra@gmail.com>
+
+ * elf32-ppc.c (struct ppc_dyn_relocs): New.
+ (ppc_elf_check_relocs): Separate dynrel counts for local syms
+ into ifunc and non-ifunc.
+ (allocate_dynrelocs): Always put ifunc relocs into reliplt.
+ (ppc_elf_size_dynamic_sections): Likewise.
+ (ppc_elf_relocate_section): Likewise.
+
+2013-03-28 Alan Modra <amodra@gmail.com>
+
+ * elf-bfd.h (enum elf_reloc_type_class): Add reloc_class_ifunc.
+ (struct elf_backend_data <elf_backed_reloc_type_class>): Add
+ bfd_link_info* and asection* params.
+ (_bfd_elf_reloc_type_class): Likewise.
+ * elf.c (_bfd_elf_reloc_type_class): Likewise.
+ * elflink.c (elf_link_sort_cmp2): Sort first on reloc class.
+ (elf_link_sort_relocs): Update elf_backed_reloc_type_class call.
+ * elf32-ppc.c (ppc_elf_reloc_type_class): Return reloc_class_ifunc
+ for any reliplt reloc. Don't return reloc_class_plt for
+ R_PPC_REL24 and R_PPC_ADDR24.
+ * elf64-ppc.c (allocate_got): Formatting.
+ (ppc64_elf_reloc_type_class): Return reloc_class_ifunc for any
+ reliplt reloc.
+ * elf-m10300.c, * elf32-arm.c, * elf32-bfin.c, * elf32-cr16.c,
+ * elf32-cris.c, * elf32-hppa.c, * elf32-i386.c, * elf32-lm32.c,
+ * elf32-m32r.c, * elf32-m68k.c, * elf32-metag.c, * elf32-nios2.c,
+ * elf32-s390.c, * elf32-sh.c, * elf32-sparc.c, * elf32-tilepro.c,
+ * elf32-vax.c, * elf32-xtensa.c, * elf64-aarch64.c, * elf64-alpha.c,
+ * elf64-hppa.c, * elf64-ia64-vms.c, * elf64-s390.c, * elf64-sparc.c,
+ * elf64-x86-64.c, * elfnn-ia64.c, * elfxx-tilegx.c, * elfxx-tilegx.h:
+ Add extra params to the various reloc_type_class functions.
+
+2013-03-27 Alan Modra <amodra@gmail.com>
+
+ * elf32-ppc.c (ppc_elf_check_relocs): Set PLT_IFUNC in local got
+ masks for all local ifunc syms.
+ (allocate_dynrelocs): Don't use htab->relgot for ifunc.
+ (ppc_elf_size_dynamic_sections): Likewise.
+ (ppc_elf_relocate_section): Likewise.
+
+2013-03-27 Will Newton <will.newton@linaro.org>
+
+ * elf32-arm.c (elf32_arm_final_link_relocate): Avoid emitting a
+ dynamic reloc for symbols with dynindx == -1.
+ (allocate_dynrelocs_for_symbol): Avoid allocating space for a
+ dynamic reloc for symbols with dynindx == -1.
+
+2013-03-27 Will Newton <will.newton@linaro.org>
+
+ * elf32-arm.c (elf32_arm_final_link_relocate): Avoid emitting a
+ dynamic reloc for non-default visibility undefined weaks.
+ (allocate_dynrelocs_for_symbol): Avoid allocating space for a
+ dynamic reloc for non-default visibility undefined weaks.
+
+2013-03-26 Alan Modra <amodra@gmail.com>
+
+ * elflink.c (_bfd_elf_add_default_symbol): Preserve section
+ over _bfd_elf_merge_symbol calls.
+
+2013-03-26 Alan Modra <amodra@gmail.com>
+
+ * elflink.c (elf_link_add_object_symbols): Add assertion for
+ common override alignment check code. Formatting.
+
+2013-03-25 Alan Modra <amodra@gmail.com>
+
+ * elflink.c (_bfd_elf_merge_symbol): Set old_alignment for
+ usual common symbols as well as for dynamic. Add poldbfd param.
+ Save old bfd. Adjust callers.
+ (_bfd_elf_add_default_symbol): Add poldbfd param. Pass "section"
+ and "value" by value, not pointer. Adjust caller.
+ (elf_link_add_object_symbols): Combine undef_bfd and old_bfd vars.
+ Delete code to set same. Use old_bfd and old_alignment from
+ _bfd_elf_merge_symbol instead. Add default symbol before
+ alignment and size checks. Wrap overlong lines.
+
+2013-03-25 Alan Modra <amodra@gmail.com>
+
+ * elflink.c (_bfd_elf_add_default_symbol): Delete "override" param.
+ (elf_link_add_object_symbols): Don't call _bfd_elf_add_default_symbol
+ when override is true.
+
+2013-03-25 Alan Modra <amodra@gmail.com>
+
+ * elflink.c (_bfd_elf_merge_symbol): Use local var holding value
+ of *sym_hash.
+
+2013-03-25 Alan Modra <amodra@gmail.com>
+
+ * elflink.c (_bfd_elf_merge_symbol): Don't discard TLS symbols here.
+ Wrap long lines.
+ (elf_link_add_object_symbols): Discard TLS symbols for --just-syms
+ early in symbol loop.
+
+2013-03-25 Alan Modra <amodra@gmail.com>
+
+ * elf-bfd.h (struct elf_backend_data <merge_symbol>): Update proto.
+ (_bfd_elf_init_reloc_shdr): Delete.
+ * elf.c (_bfd_elf_init_reloc_shdr): Make static.
+ * elf64-x86-64.c (elf_x86_64_merge_symbol): Trim parameters to
+ just what is needed.
+ * elflink.c (_bfd_elf_merge_symbol): Update bed->merge_symbol call.
+
+2013-03-23 Alan Modra <amodra@gmail.com>
+
+ * elf-bfd.h (_bfd_elf_merge_symbol): Delete declaration.
+ * elflink.c (_bfd_elf_merge_symbol): Make static.
+ * elf32-sh-symbian.c (sh_symbian_relocate_section): Don't call
+ _bfd_elf_merge_symbol, call _bfd_generic_link_add_one_symbol.
+
+2013-03-23 Alan Modra <amodra@gmail.com>
+
+ PR ld/15270
+ * elflink.c (elf_link_add_object_symbols): Don't set def_regular
+ or ref_regular for BFD_PLUGIN owned syms, or have them affect
+ def_dynamic/ref_dynamic.
+ (_bfd_elf_fix_symbol_flags): Don't set def_regular for BFD_PLUGIN
+ owned syms.
+
+2013-03-22 David S. Miller <davem@davemloft.net>
+
+ * elfxx-sparc.c (_bfd_sparc_elf_merge_private_bfd_data): Set type of
+ hwcaps attribute.
+
+2013-03-22 Achille Fouilleul <achille.fouilleul+binutils@gadz.org>
+
+ PR ld/14902
+ * elf32-h8300.c (elf32_h8_relax_delete_bytes): Fix off by one
+ errors adjusting relocs and symbols.
+
+2013-03-21 Michael Schewe <michael.schewe@gmx.net>
+
+ * elf32-h8300 (h8_relax_section): Add new relaxation of mov
+ @(disp:32,ERx) to mov @(disp:16,ERx).
+ (R_H8_DISP32A16): New reloc.
+ Comments added and corrected.
+ * reloc.c (BFD_RELOC_H8_DISP32A16): New reloc.
+ * bfd-in2.h: Regenerate.
+ * libbfd.h: Regenerate.
+
+2013-03-21 Kai Tietz <ktietz@redhat.com>
+
+ * coffgen.c (coff_real_object_p): Make global.
+ * peicode.h (coff_real_object_p): Add prototype.
+ (FILHDR): Defined for COFF_IMAGE_WITH_PE as
+ external_PEI_IMAGE_hdr structure.
+ (coff_swap_filehdr_in): Handle variable header-size.
+ * peXXigen.c (_bfd_XXi_swap_aouthdr_in): Just handle amount
+ of directory-entiries as specified in pe-header.
+
+2013-03-21 Nick Clifton <nickc@redhat.com>
+
+ PR sim/15286
+ * elf32-arm.c (bfd_arm_get_mach_from_attributes): Identify XScale,
+ iWMMXt and iWMMXt2 processors from attributes.
+
+2013-03-20 Alan Modra <amodra@gmail.com>
+
+ * elflink.c (_bfd_elf_make_dynamic_reloc_section): Override
+ sh_type according to is_rela.
+
+2013-03-18 Alan Modra <amodra@gmail.com>
+
+ PR ld/12549
+ * elflink.c (elf_link_add_object_symbols): Exclude weak refs when
+ considering whether an --as-needed library is needed.
+
+2013-03-14 Tom Tromey <tromey@redhat.com>
+
+ * opncls.c (bfd_get_debug_link_info): Rename from
+ get_debug_link_info. Export. Update comment.
+ (find_separate_debug_file): Update.
+ * bfd-in2.h: Rebuild.
+
+2013-03-08 Venkataramanan Kumar <venkataramanan.kumar@linaro.org>
+
+ * elf64-aarch64.c (elf_backend_can_gc_sections): Enable gc-section
+ support.
+ (elf64_aarch64_gc_sweep_hook): Handle GOT, TLS and PLT related
+ relocs.
+
+2013-03-08 Andreas Arnez <arnez@linux.vnet.ibm.com>
+
+ * elf-bfd.h (elfcore_write_s390_tdb): Add prototype.
+ * elf.c (elfcore_write_s390_tdb): New function.
+ (elfcore_write_register_note): Call it.
+ (elfcore_grok_s390_tdb): New function.
+ (elfcore_grok_note): Call it.
+
+2013-03-08 Maciej W. Rozycki <macro@codesourcery.com>
+
+ * elfxx-mips.c (mips_elf_allocate_lazy_stub): Correct data type.
+
+2013-03-05 Corinna Vinschen <vinschen@redhat.com>
+
+ * config.bfd: Add x86_64-*-cygwin to list of supported targets.
+
+2013-03-04 Alan Modra <amodra@gmail.com>
+
+ * elf32-ppc.c (ppc_elf_relocate_section <R_PPC_PLTREL24>): Adjust
+ non-zero addends when relocatable, rather than addends >= 32768.
+ Always zero "addend" before applying relocation.
+
+2013-03-04 Nick Clifton <nickc@redhat.com>
+
+ * archive64.c (bfd_elf64_archive_write_armap): Fix calculation of
+ file pointer offsets for thin archives.
+
+2013-02-28 Nathan Sidwell <nathan@codesourcery.com>
+
+ * elf32-arm.c (elf32_arm_size_dynamic_sections): Don't call
+ elf32_arm_allocate_dynrelocs for source reloc for non-dynamic link.
+
+2013-02-27 DJ Delorie <dj@redhat.com>
+
+ * reloc.c (BFD_RELOC_RL78_CODE): Add.
+ * libbfd.h: Regenerate.
+ * bfd-in2.h: Regenerate.
+ * elf32-rl78.c (rl78_elf_relocate_section): Handle weak code
+ references in compuated relocs.
+
+2013-02-26 Anthony Green <green@moxielogic.com>
+
+ * config.bfd: Extend moxie-rtems target triplet name support.
+
+2013-02-21 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/15167
+ * elf64-ia64-vms.c (elf64_vms_link_add_object_symbols): Set
+ unique_global only for definition.
+ * elflink.c (_bfd_elf_merge_symbol): Don't set unique_global
+ here.
+ (elf_link_add_object_symbols): Set unique_global only
+ for definition.
+
+2013-02-21 Alan Modra <amodra@gmail.com>
+
+ * elf-bfd.h (struct elf_build_id): Extracted from..
+ (struct elf_build_id_info): ..here. Delete.
+ (struct output_elf_obj_tdata): New, extracted from..
+ (struct elf_obj_tdata): ..here. Reorganize for better packing.
+ Add "o" field.
+ (elf_program_header_size): Reference tdata->o.
+ (elf_seg_map, elf_next_file_pos, elf_eh_frame_hdr, elf_linker,
+ elf_stack_flags, elf_shstrtab, elf_strtab_sec, elf_shstrtab_sec,
+ elf_section_syms, elf_num_section_syms, elf_flags_init): Likewise.
+ * elf.c (bfd_elf_allocate_object): Allocate output_elf_obj_tdata
+ when opening bfd in any mode that might write.
+ (_bfd_elf_write_object_contents): Use build_id field in
+ output_elf_obj_tdata.
+ (_bfd_elf_close_and_cleanup): Tweak elf_shstrtab test.
+ (elfobj_grok_gnu_build_id): Adjust for elf_tdata changes.
+
+2013-02-21 Alan Modra <amodra@gmail.com>
+
+ * elf-bfd.h (struct core_elf_obj_tdata): New.
+ (struct elf_obj_tdata): Delete core_signal, core_pid, core_lwpid,
+ core_program, and core_command. Add "core".
+ * elf.c (bfd_elf_mkcorefile): Allocate "core" struct.
+ Update all refs to tdata core fields.
+ * elf32-am33lin.c, * elf32-arm.c, * elf32-cris.c, * elf32-frv.c,
+ * elf32-hppa.c, * elf32-i386.c, * elf32-m68k.c, * elf32-mips.c,
+ * elf32-nios2.c, * elf32-ppc.c, * elf32-s390.c, * elf32-score.c,
+ * elf32-score7.c, * elf32-sh.c, * elf32-sparc.c, * elf32-tilegx.c,
+ * elf32-tilepro.c, * elf32-xtensa.c, * elf64-aarch64.c,
+ * elf64-hppa.c, * elf64-mips.c, * elf64-ppc.c, * elf64-tilegx.c,
+ * elf64-x86-64.c, * elfcore.h, * elfn32-mips.c: Update all refs
+ to tdata core fields.
+
+2013-02-21 Alan Modra <amodra@gmail.com>
+
+ * elf-bfd.h (struct elf_obj_tdata): Rename segment_map to seg_map.
+ Delete num_locals and num_globals.
+ (elf_num_locals, elf_num_globals): Don't define.
+ (elf_seg_map, elf_next_file_pos, elf_eh_frame_hdr, elf_linker,
+ elf_stack_flags, elf_strtab_sec, elf_shstrtab_sec): Define.
+ * bfd.c, * elf-eh-frame.c, * elf-nacl.c, * elf-vxworks.c, * elf.c,
+ * elf32-arm.c, * elf32-lm32.c, * elf32-ppc.c, * elf32-rx.c,
+ * elf32-spu.c, * elf64-hppa.c, * elfcode.h, * elflink.c,
+ * elfnn-ia64.c, * elfxx-mips.c: Use newly defined elf_obj_tdata
+ accessor macros.
+ * elf.c (elf_map_symbols): Add pnum_locals param. Return
+ number of locals syms via new param.
+ (swap_out_syms): Adjust to suit elf_map_symbols change.
+
+2013-02-19 Maciej W. Rozycki <macro@codesourcery.com>
+
+ * elfxx-mips.c (_bfd_mips_elf_finish_dynamic_symbol): Also clear
+ STO_MICROMIPS annotation.
+
+2013-02-19 Alan Modra <amodra@gmail.com>
+
+ * configure.in: Bump version to 2.23.52.
+ * elf-bfd.h (struct elf_build_id_info): New.
+ (struct elf_obj_tdata): Delete after_write_object_contents,
+ after_write_object_contents_info and build_id_size. Make build_id
+ a pointer to struct elf_build_id_info.
+ * elf.c (_bfd_elf_write_object_contents): Style. Update
+ after_write_ibject_contents invocation.
+ (elfobj_grok_gnu_build_id): Update for new build_id struct. Don't
+ allow zero size notes.
+ * configure: Regenerate.
+
+2013-02-18 Maciej W. Rozycki <macro@codesourcery.com>
+
+ * elf64-mips.c (micromips_elf64_howto_table_rel): Add
+ R_MICROMIPS_SCN_DISP and R_MICROMIPS_JALR.
+ (micromips_elf64_howto_table_rela): Likewise.
+ (micromips_reloc_map): Add BFD_RELOC_MICROMIPS_JALR.
+ * elfn32-mips.c (elf_micromips_howto_table_rel): Add
+ R_MICROMIPS_SCN_DISP and R_MICROMIPS_JALR.
+ (elf_micromips_howto_table_rela): Likewise.
+ (micromips_reloc_map): Add BFD_RELOC_MICROMIPS_JALR.
+
+2013-02-18 Paul Brook <paul@codesourcery.com>
+
+ * elfxx-mips.c (MICROMIPS_P): New macro.
+ (_bfd_mips_elf_symbol_processing): Use it.
+
+2013-02-18 Maciej W. Rozycki <macro@codesourcery.com>
+
+ * elfxx-mips.c (_bfd_mips_elf_create_dynamic_sections): Clarify
+ comment on _PROCEDURE_LINKAGE_TABLE_ creation.
+
+2013-02-18 Alan Modra <amodra@gmail.com>
+
+ PR ld/12549
+ * elf-bfd.h (_bfd_elf_strtab_clear_refs): Delete.
+ (_bfd_elf_strtab_clear_all_refs): Declare.
+ (_bfd_elf_strtab_resize): Declare.
+ * elf-strtab.c (_bfd_elf_strtab_clear_refs): Delete.
+ (_bfd_elf_strtab_clear_all_refs): New function.
+ (_bfd_elf_strtab_resize): Likewise.
+ * elflink.c (elf_link_add_object_symbols): Use _bfd_elf_strtab_resize.
+
+2013-02-18 Alan Modra <amodra@gmail.com>
+
+ * elf-bfd.h (struct elf_obj_tdata): Move find_line_info, local_stubs,
+ local_call_stubs, elf_data_symbol, elf_text_symbol, elf_data_section,
+ and elf_text_section to..
+ * elfxx-mips.c (struct mips_elf_obj_tdata): ..here. Update all refs.
+ * elf64-alpha.c (struct mips_elf_find_line): Rename to..
+ (struct alpha_elf_find_line): ..this.
+ (struct alpha_elf_obj_tdata): Add find_line_info, update refs.
+
+2013-02-16 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/15146
+ * elflink.c (elf_link_add_object_symbols): Don't add DT_NEEDED
+ for references from the dummy bfd.
+
+2013-02-16 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/15149
+ * elflink.c (elf_link_add_object_symbols): Also track weak
+ references.
+
+2013-02-15 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR binutils/15151
+ * archive.c (_bfd_find_nested_archive): Don't allow a nested
+ archive pointing to itself.
+ (_bfd_get_elt_at_filepos): Revert the last 2 changes.
+
+2013-02-15 Nick Clifton <nickc@redhat.com>
+
+ PR binutils/15140
+ * archive.c (_bfd_get_elt_at_filepos): Prevent an infinite loop
+ accessing a corrupt nested archive.
+
+2013-02-13 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * elfxx-mips.c (mips_got_page_ref): New structure.
+ (mips_got_page_entry): Use a section rather than a (bfd, symndx)
+ pair to represent the anchor point.
+ (mips_got_info): Add a got_page_refs field.
+ (mips_elf_link_hash_table): Add a sym_cache field.
+ (mips_got_page_ref_hash, mips_got_page_ref_eq): New functions.
+ (mips_got_page_entry_hash, mips_got_page_entry_eq): Update for
+ new anchor representation.
+ (mips_elf_create_got_info): Create got_page_refs rather than
+ got_page_entries.
+ (mips_elf_record_got_page_ref): New function.
+ (mips_elf_pages_for_range): Move further down file.
+ (mips_elf_record_got_page_entry): Likewise. Take a got as argument.
+ Use a section rather than a (bfd, symndx) pair to represent the
+ anchor point.
+ (mips_elf_resolve_got_page_ref): New function.
+ (mips_elf_resolve_final_got_entries): Use it to populate
+ got_page_entries.
+ (_bfd_mips_elf_check_relocs): Call mips_elf_record_got_page_ref
+ rather than mips_elf_record_got_page_entry. Only nullify h
+ afterwards.
+ (mips_elf_lay_out_got): Call mips_elf_resolve_final_got_entries
+ earlier.
+
+2013-02-12 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * elfxx-mips.c (mips_elf_lay_out_got): Count VxWorks GOT relocs
+ in g->relocs.
+
+2013-02-12 Alan Modra <amodra@gmail.com>
+
+ * elfxx-target.h (bfd_elfNN_bfd_link_hash_table_free): Provide
+ suitable definition when using generic linker hash table.
+
+2013-02-11 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * elfxx-mips.c (mips_elf_count_got_entries): Delete.
+ (mips_elf_check_recreate_got, mips_elf_recreate_got): Take a
+ mips_elf_traverse_got_arg. Count GOT entries.
+ (mips_elf_resolve_final_got_entries): Take the bfd_link_info
+ as argument. Update after above changes.
+ (mips_elf_merge_got, mips_elf_lay_out_got): Don't call
+ mips_elf_count_got_entries. Update the calls to
+ mips_elf_resolve_final_got_entries.
+
+2013-02-11 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * elfxx-mips.c (mips_got_tls_type): New enum.
+ (mips_got_entry): Add tls_initialized.
+ (mips_elf_got_entry_hash, mips_elf_got_entry_eq, mips_tls_got_relocs)
+ (mips_elf_count_got_entry, mips_elf_initialize_tls_index): Remove
+ GOT_TLS_TYPE masks.
+ (mips_elf_reloc_tls_type, mips_tls_got_entries)
+ (mips_elf_record_global_got_symbol, mips_elf_initialize_tls_index)
+ (_bfd_mips_elf_finish_dynamic_symbol): Use GOT_TLS_NONE rather
+ than GOT_NORMAL.
+ (mips_elf_initialize_tls_slots): Replace got_offset and tls_type_p
+ arguments with a GOT entry. Remove GOT_TLS_TYPE masks. Use
+ tls_initialized rather than GOT_TLS_DONE.
+ (mips_tls_got_index): Delete.
+ (mips_elf_local_got_index, mips_elf_global_got_index): Use
+ mips_elf_initialize_tls_slots rather than mips_tls_got_index.
+ (mips_elf_record_got_entry): Initialize tls_initialized.
+
+2013-02-11 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * elfxx-mips.c (mips_got_entry): Remove tls_ldm_offset.
+ (mips_elf_link_hash_entry): Remove tls_ie_type, tls_gd_type,
+ tls_ie_got_offset and tls_gd_got_offset.
+ (mips_elf_link_hash_newfunc): Remove initialization.
+ (mips_elf_create_got_info): Likewise.
+ (mips_elf_count_local_got_entries, mips_elf_count_global_tls_entries)
+ (mips_tls_single_got_index): Delete.
+ (mips_elf_local_got_index): Always use the GOT entry to track
+ GOT indices.
+ (mips_elf_global_got_index): Likewise.
+ (mips_elf_create_local_got_entry): Assert that TLS entries have
+ already been allocated.
+ (mips_elf_record_global_got_symbol): Don't initialize
+ tls_ie_type or tls_gd_type.
+ (mips_elf_count_got_symbols): Only count reloc-only GOT entries here.
+ (mips_elf_initialize_tls_index): Allocate a GOT index for every TLS
+ entry.
+ (mips_elf_lay_out_got): Use mips_elf_count_got_entries to count
+ the GOT entries.
+ (_bfd_mips_elf_finish_dynamic_symbol): Assert that TLS GOT offsets
+ have been allocated.
+ (_bfd_mips_elf_copy_indirect_symbol): Remove handling of
+ tls_ie_type and tls_gd_type.
+
+2013-02-11 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * elfxx-mips.c (mips_elf_create_local_got_entry): Tidy. Avoid
+ aliasing violation. Check for htab allocation failures.
+
+2013-02-11 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * elfxx-mips.c (mips_elf_primary_global_got_index): New function,
+ split out from...
+ (mips_elf_global_got_index): ...here. Reorder arguments so that
+ the output bfd and info come first.
+ (mips_elf_calculate_relocation): Update the call to
+ mips_elf_global_got_index accordingly.
+ (_bfd_mips_elf_finish_dynamic_symbol): Use
+ mips_elf_primary_global_got_index rather than
+ mips_elf_global_got_index.
+ (_bfd_mips_vxworks_finish_dynamic_symbol): Likewise.
+
+2013-02-11 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * elfxx-mips.c (mips_got_entry): Update comments.
+ (mips_elf_multi_got_entry_eq): Rename to...
+ (mips_elf_got_entry_eq): ...this, deleting the old definition.
+ (mips_elf_create_got_info): Remove master_got_p argument.
+ Always use mips_elf_got_entry_eq.
+ (mips_elf_bfd_got, mips_elf_multi_got, mips_elf_create_got_section):
+ Update calls accordingly.
+
+2013-02-11 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * elfxx-mips.c (mips_got_info): Remove bfd2got.
+ (mips_elf_bfd2got_hash): Delete.
+ (mips_elf_got_per_bfd_arg): Remove bfd2got.
+ (mips_elf_replace_bfd_got, mips_elf_count_got_entries): New functions.
+ (mips_elf_global_got_index, mips_elf_create_local_got_entry): Use
+ g->next to test for the multigot case. Use mips_elf_bfd_got rather
+ than mips_elf_got_for_ibfd.
+ (mips_elf_bfd2got_entry_hash, mips_elf_bfd2got_entry_eq)
+ (mips_elf_got_for_ibfd, mips_elf_get_got_for_bfd): Delete.
+ (mips_elf_make_got_per_bfd): Replace with...
+ (mips_elf_add_got_entry): ...this new function.
+ (mips_elf_make_got_pages_per_bfd): Replace with...
+ (mips_elf_add_got_page_entry): ...this new function.
+ (mips_elf_merge_got_with): Replace bfd2got argument with separate
+ bfd and GOT arguments. Use mips_elf_add_got_entry and
+ mips_elf_add_got_page_entry instead of mips_elf_make_got_per_bfd
+ and mips_elf_make_got_pages_per_bfd. Use mips_elf_replace_bfd_got
+ to set the BFD's GOT and free the old table.
+ (mips_elf_merge_got): Replace bfd2got argument with separate
+ bfd and GOT arguments. Apply mips_elf_resolve_final_got_entries.
+ Use mips_elf_count_got_entries to count the number of entries in
+ each GOT. Update the calls to mips_elf_merge_got_with.
+ (mips_elf_adjust_gp): Use g->next to test for the multigot case.
+ Use mips_elf_bfd_got rather than mips_elf_got_for_ibfd.
+ (mips_elf_multi_got): Don't create the bfd2got hash table.
+ Replace hash table traversal with a walk over the input bfds,
+ updating the call to mips_elf_merge_got. Use mips_elf_replace_bfd_got
+ to set the output bfd's GOT.
+ (mips_elf_lay_out_got): Rename "sub" to "ibfd". Record that all
+ bfds use the master GOT in the single-GOT case.
+ (_bfd_mips_elf_finish_dynamic_sections): Use mips_elf_bfd_got
+ rather than mips_elf_got_for_ibfd.
+
+2013-02-11 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * elfxx-mips.c (mips_elf_obj_tdata): Add a got field.
+ (mips_elf_bfd_got, mips_elf_record_got_entry): New functions.
+ (mips_elf_record_global_got_symbol): Update the hash entry before
+ adding the mips_got_entry. Use mips_elf_record_got_entry to do
+ the latter.
+ (mips_elf_record_local_got_symbol): Use mips_elf_record_got_entry.
+ (mips_elf_record_got_page_entry): Record the entry in both the
+ master and bfd GOTs.
+
+2013-02-11 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * elfxx-mips.c (mips_elf_recreate_got): Don't change the entry;
+ create another one if necessary.
+ (mips_elf_set_gotidx): New function.
+ (mips_elf_set_global_gotidx): Use it.
+ (mips_elf_initialize_tls_index): Likewise. Take a
+ mips_elf_traverse_got_arg as argument.
+ (mips_elf_lay_out_got): Update use of mips_elf_initialize_tls_index.
+ (mips_elf_multi_got): Likewise. Cope with error returns from
+ mips_elf_set_global_gotidx.
+
+2013-02-11 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * elfxx-mips.c (mips_got_info): Add relocs field.
+ (mips_elf_set_global_got_offset_arg, mips_elf_count_tls_arg): Replace
+ with...
+ (mips_elf_traverse_got_arg): ...this new structure.
+ (mips_elf_count_local_tls_relocs): Delete.
+ (mips_elf_count_global_tls_relocs): Likewise.
+ (mips_elf_count_got_entry): New function.
+ (mips_elf_count_local_got_entries): Likewise.
+ (mips_elf_count_global_tls_entries): Take a mips_elf_traverse_got_arg
+ rather than a mips_elf_count_tls_arg. Count both relocs and entries.
+ (mips_elf_record_local_got_symbol): Don't count got entries here.
+ (mips_elf_make_got_per_bfd): Use mips_elf_count_got_entry.
+ (mips_elf_set_global_got_offset): Split into...
+ (mips_elf_set_global_got_area, mips_elf_set_global_gotidx): ...these
+ new functions. Take a mips_elf_traverse_got_arg rather than a
+ mips_elf_set_global_got_offset_arg. Don't count TLS relocs here.
+ Use g->relocs to record the number of relocs needed for global GOT
+ entries.
+ (mips_elf_multi_got): Use mips_elf_traverse_got_arg rather than
+ mips_elf_set_global_got_offset_arg. Use the relocs field to count
+ relocations. Update for above function split.
+ (mips_elf_lay_out_got): Use mips_elf_count_local_got_entries
+ to count both the number of GOT entries and the number of TLS
+ relocs required by local entries. Likewise
+ mips_elf_count_global_tls_entries and global entries.
+ Remove uses of mips_elf_count_local_tls_relocs and
+ mips_elf_count_global_tls_relocs.
+
+2013-02-11 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * elfxx-mips.c (mips_got_entry): Update comment above tls_type entry
+ to say that each structure represents only one type of TLS reference.
+ (GOT_TLS_TYPE): New define.
+ (mips_elf_link_hash_entry): Temporarily split tls_type and
+ tls_got_offset into two variables each.
+ (mips_elf_link_hash_newfunc): Update accordingly.
+ (mips_elf_got_entry_eq, mips_elf_got_entry_hash)
+ (mips_elf_multi_got_entry_eq): Require the tls_type to be the same.
+ (mips_elf_reloc_tls_type, mips_tls_got_entries): New functions.
+ (mips_tls_got_relocs): Use a switch statement.
+ (mips_elf_count_global_tls_entries): Handle the new hash entry fields.
+ (mips_elf_initialize_tls_slots): Use a switch statement. Avoid
+ local "offset" variable.
+ (mips_tls_got_index): Remove r_type argument and assert. Remove
+ code that handled entries with two TLS types; always use the
+ original got_index instead.
+ (mips_tls_single_got_index): New function.
+ (mips_elf_local_got_index): Use entry->tls_type to check for
+ TLS entries. Use mips_tls_single_got_index. Update call to
+ mips_tls_got_index.
+ (mips_elf_global_got_index): Use mips_elf_reloc_tls_type.
+ Use p->tls_type to check for TLS entries. Update call to
+ mips_tls_got_index. Use mips_tls_single_got_index.
+ (mips_elf_create_local_got_entry): Use mips_elf_reloc_tls_type.
+ Use entry.tls_type to check for TLS entries.
+ (mips_elf_record_global_got_symbol): Replace tls_flag argument
+ with r_type argument. Use mips_elf_reloc_tls_type.
+ Set up the new hash entry fields.
+ (mips_elf_record_local_got_symbol): Replace tls_flag argument
+ with r_type argument. Use mips_elf_reloc_tls_type and
+ mips_tls_got_entries. Remove code that handled entries
+ with multiple TLS types.
+ (mips_elf_make_got_per_bfd): Use mips_tls_got_entries.
+ (mips_elf_initialize_tls_index): Handle new hash entry fields.
+ Use equality rather than masks when checking for specific TLS types.
+ Use mips_tls_got_entries. Remove code that handled entries
+ with multiple TLS types.
+ (mips_elf_calculate_relocation): Use TLS_RELOC_P instead of
+ testing the hash table entry.
+ (_bfd_mips_elf_check_relocs): Update calls to
+ mips_elf_record_global_got_symbol and mips_elf_record_local_got_symbol.
+ (_bfd_mips_elf_finish_dynamic_symbol): Don't check h->type.
+ (_bfd_mips_elf_copy_indirect_symbol): Handle new hash entry fields.
+
+2013-02-11 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * elfxx-mips.c (mips_elf_multi_got_entry_hash): Rename to...
+ (mips_elf_got_entry_hash): ...this, deleting the old version.
+ (mips_elf_create_got_info): Use mips_elf_got_entry_hash for
+ both types of GOT.
+
+2013-02-11 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * elfxx-mips.c (mips_elf_create_got_info): New function.
+ (mips_elf_get_got_for_bfd, mips_elf_multi_got): Use it.
+ (mips_elf_create_got_section): Likewise.
+
+2013-02-11 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * elfxx-mips.c (mips_elf_record_local_got_symbol): Always set
+ gotidx to -1.
+
+2013-02-11 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * elfxx-mips.c (mips_elf_multi_got): Simplify size calculation.
+
+2013-02-11 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * elfxx-mips.c (mips_got_info): Move global_gotsym to...
+ (mips_elf_link_hash_table): ...here. Update rest of file accordingly.
+
+2013-02-11 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * elfxx-mips.c (mips_elf_count_global_tls_entries)
+ (mips_elf_count_global_tls_relocs): Don't count indirect or
+ warning symbols.
+ (mips_elf_multi_got, mips_elf_lay_out_got): Assert that the right
+ number of TLS entries were allocated.
+
+2013-02-11 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * elfxx-mips.c (mips_elf_sort_hash_table_f): Remove asserts.
+
+2013-02-11 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * elfxx-mips.c (mips_elf_merge_got_with): Only use arg->global_count
+ if there are TLS relocations.
+
+2013-02-11 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * elfxx-mips.c (mips_elf_recreate_got): Remove free.
+ (mips_elf_resolve_final_got_entries): Remove bogus comment.
+
+2013-02-11 Alan Modra <amodra@gmail.com>
+
+ * elfcode.h (elf_checksum_contents): Free contents.
+ * elf-bfd.h (_bfd_elf_link_hash_table_free): Declare.
+ * elflink.c (_bfd_elf_link_hash_table_free): New function.
+ (elf_final_link_free): New function, extracted from..
+ (bfd_elf_final_link): ..here. Always call
+ _bfd_elf_write_section_eh_frame_hdr.
+ * elfxx-target.h (bfd_elfNN_bfd_link_hash_table_free): Default to
+ _bfd_elf_link_hash_table_free.
+ * libbfd-in.h (_bfd_merge_sections_free): Declare.
+ * libbfd.h: Regenerate.
+ * merge.c (_bfd_merge_sections_free): New function.
+ * elf-eh-frame.c (_bfd_elf_write_section_eh_frame_hdr): Free
+ hdr_info->array.
+ * elf-m10300.c (elf32_mn10300_link_hash_table_free): Call
+ _bfd_elf_link_hash_table_free.
+ * elf32-arm.c (elf32_arm_link_hash_table_free): Likewise.
+ * elf32-avr.c (elf32_avr_link_hash_table_free): Likewise.
+ * elf32-hppa.c (elf32_hppa_link_hash_table_free): Likewise.
+ * elf32-i386.c (elf_i386_link_hash_table_free): Likewise.
+ * elf32-m68hc1x.c (m68hc11_elf_hash_table_free): Likewise.
+ * elf32-m68k.c (elf_m68k_link_hash_table_free): Likewise.
+ * elf32-metag.c (elf_metag_link_hash_table_free): Likewise.
+ * elf32-xgate.c (xgate_elf_bfd_link_hash_table_free): Likewise.
+ * elf64-aarch64.c (elf64_aarch64_link_hash_table_free): Likewise.
+ * elf64-ia64-vms.c (elf64_ia64_hash_table_free): Likewise.
+ * elf64-ppc.c (ppc64_elf_link_hash_table_free): Likewise.
+ * elf64-x86-64.c (elf_x86_64_link_hash_table_free): Likewise.
+ * elfnn-ia64.c (elfNN_ia64_hash_table_free): Likewise.
+ * elf32-cr16.c (elf32_cr16_link_hash_table_free): Delete.
+ (bfd_elf32_bfd_link_hash_table_free): Don't define.
+ * elf32-tic6x.c (elf32_tic6x_link_hash_table_free): Delete.
+ (bfd_elf32_bfd_link_hash_table_free): Dont' define.
+
+2013-02-10 Alan Modra <amodra@gmail.com>
+
+ * coff-arm.c (coff_arm_link_hash_table_create): Use bfd_zmalloc.
+ * coff-h8300.c (h8300_coff_link_hash_table_create): Likewise.
+ * m68klinux.c (linux_link_hash_table_create): Likewise.
+ * sparclinux.c (linux_link_hash_table_create): Likewise.
+ * sunos.c (sunos_link_hash_table_create): Likewise.
+ * xcofflink.c (_bfd_xcoff_bfd_link_hash_table_create): Likewise.
+ * elf-m10300.c (elf32_mn10300_link_hash_table_create): Likewise.
+ * elf32-arm.c (elf32_arm_link_hash_table_create): Likewise.
+ * elf32-avr.c (elf32_avr_link_hash_table_create): Likewise.
+ * elf32-cr16.c (elf32_cr16_link_hash_table_create): Likewise.
+ * elf32-cris.c (elf_cris_link_hash_table_create): Likewise.
+ * elf32-hppa.c (elf32_hppa_link_hash_table_create): Likewise.
+ * elf32-i386.c (elf_i386_link_hash_table_create): Likewise.
+ * elf32-lm32.c (lm32_elf_link_hash_table_create): Likewise.
+ * elf32-m32r.c (m32r_elf_link_hash_table_create): Likewise.
+ * elf32-m68hc1x.c (m68hc11_elf_hash_table_create): Likewise.
+ * elf32-m68k.c (elf_m68k_link_hash_table_create): Likewise.
+ * elf32-metag.c (elf_metag_link_hash_table_create): Likewise.
+ * elf32-nios2.c (nios2_elf32_link_hash_table_create): Likewise.
+ * elf32-s390.c (elf_s390_link_hash_table_create): Likewise.
+ * elf32-score.c (elf32_score_link_hash_table_create): Likewise.
+ * elf32-spu.c (spu_elf_link_hash_table_create): Likewise.
+ * elf32-tic6x.c (elf32_tic6x_link_hash_table_create): Likewise.
+ * elf32-vax.c (elf_vax_link_hash_table_create): Likewise.
+ * elf32-xgate.c (xgate_elf_bfd_link_hash_table_create): Likewise.
+ * elf32-xtensa.c (elf_xtensa_link_hash_table_create): Likewise.
+ * elf64-aarch64.c (elf64_aarch64_link_hash_table_create): Likewise.
+ * elf64-s390.c (elf_s390_link_hash_table_create): Likewise.
+ * elf64-sh64.c (sh64_elf64_link_hash_table_create): Likewise.
+ * elf64-x86-64.c (elf_x86_64_link_hash_table_create): Likewise.
+ * elfxx-mips.c (_bfd_mips_elf_link_hash_table_create): Likewise.
+ * elflink.c (_bfd_elf_link_hash_table_create): Likewise.
+ (_bfd_elf_link_hash_table_init): Assume zero fill table on entry.
+
+2013-02-10 Alan Modra <amodra@gmail.com>
+
+ * i386linux.c (linux_link_hash_table_create): Allocate table
+ with bfd_zmalloc, not bfd_alloc.
+ * pdp11.c (link_hash_table_create): Allocate table with
+ bfd_malloc, not bfd_alloc.
+ * elf32-bfin.c (bfinfdpic_elf_link_hash_table_create): Allocate table
+ with bfd_zmalloc, not bfd_zalloc.
+ (bfin_link_hash_table_create): Likewise.
+ * elf32-frv.c (frvfdpic_elf_link_hash_table_create): Likewise.
+ * elf64-hppa.c (elf64_hppa_hash_table_create): Likewise.
+
+2013-02-10 Alan Modra <amodra@gmail.com>
+
+ PR ld/15113
+ * elf32-sh.c (sh_elf_link_hash_table_create): Use bfd_zmalloc.
+
+2013-02-08 Markos Chandras <markos.chandras@imgtec.com>
+
+ * elf32-metag.c: Use bfd_get_linker_section to get SEC_LINKER_CREATED
+ sections.
+ (elf_metag_adjust_dynamic_symbol): Don't error on zero size dynbss
+ symbol.
+
+2013-02-08 Yufeng Zhang <yufeng.zhang@arm.com>
+
+ * elf64-aarch64.c (elf64_aarch64_grok_prstatus): Change 'size' from
+ 288 to 272.
+
+2013-02-08 Alan Modra <amodra@gmail.com>
+
+ PR binutils/15106
+ * elf-bfd.h (struct elf_obj_tdata): Add elf_find_function_cache.
+ * elf.c (elf_find_function): Revert last change. Use new
+ tdata field rather than static vars for cache.
+
+2013-02-07 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/15107
+ * elflink.c (elf_link_output_extsym): Set STB_GNU_UNIQUE only if
+ symbol is defined in regular object.
+
+2013-02-07 Roberto Agostino Vitillo <ra.vitillo@gmail.com>
+
+ PR binutils/15106
+ * elf.c (elf_find_function): Don't cache if symbols change.
+
+2013-02-07 Alan Modra <amodra@gmail.com>
+
+ PR binutils/14873
+ * elf-attrs.c (_bfd_elf_copy_obj_attributes): Don't attempt to
+ copy attributes from or to non-ELF.
+
+2013-02-06 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf32-i386.c (elf_i386_allocate_dynrelocs): Don't clear pc_count
+ for non-zero TLS symbol.
+ (elf_i386_relocate_section): Don't resolve size relocation against
+ non-zero TLS symbol.
+ * elf64-x86-64.c (elf_x86_64_allocate_dynrelocs): Don't clear
+ pc_count for non-zero TLS symbol.
+ (elf_x86_64_relocate_section): Don't resolve size relocation
+ against non-zero TLS symbol.
+
+2013-02-06 Sandra Loosemore <sandra@codesourcery.com>
+ Andrew Jenner <andrew@codesourcery.com>
+
+ Based on patches from Altera Corporation.
+
+ * Makefile.am (ALL_MACHINES): Add cpu-nios2.lo.
+ (ALL_MACHINES_CFILES): Add cpu-nios2.c.
+ (BFD_BACKENDS): Add elf32-nios2.lo.
+ (BFD32_BACKENDS_CFILES): Add elf32-nios2.c.
+ * Makefile.in: Regenerated.
+ * configure.in: Add entries for bfd_elf32_bignios2_vec and
+ bfd_elf32_littlenios2_vec.
+ * configure: Regenerated.
+ * config.bfd: Add cases for nios2.
+ * archures.c (enum bfd_architecture): Add bfd_arch_nios2.
+ (bfd_mach_nios2): Define.
+ (bfd_nios2_arch): Declare.
+ (bfd_archures_list): Add bfd_nios2_arch.
+ * targets.c (bfd_elf32_bignios2_vec): Declare.
+ (bfd_elf32_littlenios2_vec): Declare.
+ (_bfd_target_vector): Add entries for bfd_elf32_bignios2_vec and
+ bfd_elf32_littlenios2_vec.
+ * elf-bfd.h (enum elf_target_id): Add NIOS2_ELF_DATA.
+ * reloc.c (enum bfd_reloc_code_real): Add Nios II relocations.
+ * bfd-in2.h: Regenerated.
+ * libbfd.h: Regenerated.
+ * cpu-nios2.c: New file.
+ * elf32-nios2.c: New file.
+
+2013-02-06 Alan Modra <amodra@gmail.com>
+
+ * elf32-arm.c (elf32_arm_final_link_relocate): Only test for
+ stubs in stub_bfd.
+
+2013-02-06 Alan Modra <amodra@gmail.com>
+
+ * Makefile.am (SOURCE_HFILES): Add `elf-linux-psinfo.h'.
+ * Makefile.in: Regenerate.
+
+2013-02-04 Sergio Durigan Junior <sergiodj@redhat.com>
+ Pedro Alves <palves@redhat.com>
+
+ * Makefile.in (SOURCE_HFILES): Add `elf-linux-psinfo.h'.
+ * elf-bfd.h (elf_internal_linux_prpsinfo): New structure
+ declaration.
+ (elfcore_write_linux_prpsinfo32, elfcore_write_linux_prpsinfo64)
+ (elfcore_write_ppc32_linux_prpsinfo32): New declarations.
+ * elf-linux-psinfo.h: New file.
+ * elf.c: Include elf-linux-psinfo.h.
+ (elfcore_write_linux_prpsinfo32, elfcore_write_linux_prpsinfo64):
+ New functions.
+ * elf32-ppc.c: Include `elf-linux-psinfo.h'.
+ (elf_external_ppc_linux_prpsinfo32): New structure declaration.
+ (PPC_LINUX_PRPSINFO32_SWAP_FIELDS): New macro.
+ (elfcore_write_ppc_linux_prpsinfo32): New function.
+
+2013-02-04 Tristan Gingold <gingold@adacore.com>
+
+ * mach-o.c (bfd_mach_o_scan_start_address): Do not fail if no
+ start address.
+
+2013-02-04 Alan Modra <amodra@gmail.com>
+
+ * Makefile.am (BFD64_BACKENDS): Remove elf-nacl.lo.
+ (BFD64_BACKENDS_CFILES): Remove elf-nacl.c.
+ * Makefile.in: Regenerate.
+ * po/SRC-POTFILES.in: Regenerate.
+
+2013-02-04 Alan Modra <amodra@gmail.com>
+
+ * coff-tic54x.c (SWAP_OUT_RELOC_EXTRA): Delete.
+ * coff-tic80.c (SWAP_OUT_RELOC_EXTRA): Delete.
+
+2013-02-01 Alan Modra <amodra@gmail.com>
+
+ * elf64-ppc.c (dec_dynrel_count): Don't error when elf_gc_sweep_symbol
+ clears def_regular.
+
+2013-01-31 Tristan Gingold <gingold@adacore.com>
+
+ * mach-o.c (bfd_mach_o_scan): Call bfd_mach_o_flatten_sections
+ earlier. Fix status checking of bfd_mach_o_scan_start_address.
+ (bfd_mach_o_scan_start_address): Handle LC_MAIN.
+
+2013-01-31 Alan Modra <amodra@gmail.com>
+ David S. Miller <davem@davemloft.net>
+
+ PR ld/15056
+ * elfxx-sparc.c (_bfd_sparc_elf_gc_mark_hook): Handle implicit
+ references to __tls_get_addr.
+ * elf32-tilpro.c (tilepro_elf_gc_mark_hook): Likewise. Correct
+ vtinherit and vtentry reloc handling too.
+ * elfxx-tilegx.c (tilegx_elf_gc_mark_hook): As for tilepro.
+
+2013-01-31 Alan Modra <amodra@gmail.com>
+
+ * elf64-ppc.c (ppc_stub_name): Trim off trailing "+0".
+
+2013-01-31 Alan Modra <amodra@gmail.com>
+
+ * elf64-ppc.c (build_plt_stub): Correct plt stub branch to glink.
+
+2013-01-28 Alan Modra <amodra@gmail.com>
+
+ * elf64-ppc.c: Use %T to print symbols names and remove redundant
+ "relocation" in error messages throughout file.
+ (ppc64_elf_relocate_section): Remove sibling call error message,
+ replace with "call lacks nop". Specially report errors for
+ branches to function entry points via OPD lookup and branches
+ to stubs. Remove NULL symbol handling now done by %T.
+
+2013-01-28 Alan Modra <amodra@gmail.com>
+
+ * archive.c (bfd_generic_archive_p): Return target and keep
+ ardata on partial matches.
+ * format.c (bfd_check_format_matches): Adjust for above
+ change. Remove bfd_error_file_ambiguously_recognized dead
+ code.
+
+2013-01-26 Alan Modra <amodra@gmail.com>
+
+ * bfd.c (struct bfd_preserve, bfd_preserve_save, bfd_preserve_restore,
+ bfd_preserve_finish): Move to..
+ * format.c: ..here, splitting out..
+ (bfd_reinit): ..this. New function.
+ (bfd_check_format_matches): Use bfd_preserve_save/restore to
+ keep bfd state for a match.
+ * elfcode.h (elf_object_p): Don't use bfd_preserve_save/restore.
+ * elfcore.h (elf_core_file_p): Likewise.
+ * mach-o.c (bfd_mach_o_header_p): Likewise.
+ * pef.c (bfd_pef_object_p, bfd_pef_xlib_object_p): Likewise.
+ * xsym.c (bfd_sym_object_p): Likewise.
+ * mmo.c (mmo_scan): Clear abfd->symcount.
+ * opncls.c (_bfd_new_bfd): Use a smaller section hash table.
+ * section.c (bfd_section_list_clear): Clear section_htab.count.
+ * bfd-in2.h: Regenerate.
+
+2013-01-25 Michael Schewe <michael.schewe@gmx.net>
+
+ * elf32-h8300.c (elf32_h8_relax_section): When checking for a
+ second reloc, make sure that the reloc potentially exists first.
+
+2013-01-24 Nick Clifton <nickc@redhat.com>
+
+ * archures.c: Add bfd_mach_v850e3v5.
+ * bfd-in2.h: Regenerate.
+ * cpu-v850.c: Add entries for v850e2v5 and v850e3v5.
+ * cpu-v850_rh850.c: Likewise.
+ * elf32-v850.c: Add support for v850e3v5 architecture.
+
+2013-01-23 Markos Chandras <markos.chandras@imgtec.com>
+
+ * elf32-metag.c: Error on HIADDR16/LOADDR16 in shared link.
+
+2013-01-23 Leif Ekblad <leif@rdos.net>
+
+ * config.bfd (x86_64-*-rdos*): Remove targ_selvecs.
+
+2013-01-18 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf32-i386.c (elf_i386_allocate_dynrelocs): Clear pc_count for
+ non-zero TLS symbol.
+ (elf_i386_relocate_section): Resolve size relocation against
+ non-zero TLS symbol.
+ * elf64-x86-64.c (elf_x86_64_allocate_dynrelocs): Clear pc_count
+ for non-zero TLS symbol.
+ (elf_x86_64_relocate_section): Resolve size relocation against
+ non-zero TLS symbol.
+
+2013-01-18 Mike Frysinger <vapier@gentoo.org>
+
+ * elflink.c (bfd_elf_size_dynamic_sections): Only add DT_RPATH
+ when new_dtags is false. Only add DT_RUNPATH when new_dtags is
+ true.
+
+2013-01-17 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf32-i386.c (elf_i386_check_relocs): Count size relocation as
+ PC-relative relocation.
+ * elf64-x86-64.c (elf_x86_64_check_relocs): Count size relocation
+ as PC-relative relocation.
+
+2013-01-16 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf32-i386.c (elf_i386_check_relocs): Update R_386_SIZE32
+ check.
+ (elf_i386_relocate_section): Don't check TLS for R_386_SIZE32.
+
+ * elf64-x86-64.c (elf_x86_64_check_relocs): Update R_X86_64_SIZE32
+ and R_X86_64_SIZE64 check.
+ (elf_x86_64_relocate_section): Don't check TLS for R_X86_64_SIZE32
+ nor R_X86_64_SIZE64.
+
+2013-01-16 H.J. Lu <hongjiu.lu@intel.com>
+
+ * bfd-in2.h: Regenerated.
+ * libbfd.h: Likewise.
+
+ * elf32-i386.c (elf_howto_table): Fill R_386_SIZE32 entry.
+ (elf_i386_reloc_type_lookup): Support BFD_RELOC_SIZE32.
+ (elf_i386_check_relocs): Handle R_386_SIZE32.
+ (elf_i386_gc_sweep_hook): Likewise.
+ (elf_i386_relocate_section): Likewise.
+
+ * elf64-x86-64.c (x86_64_elf_howto_table): Fill R_X86_64_SIZE32
+ and R_X86_64_SIZE64 entries.
+ (x86_64_reloc_map): Add BFD_RELOC_SIZE32 and BFD_RELOC_SIZE64,
+ (elf_x86_64_rtype_to_howto): Handle R_X86_64_SIZE32 for x32.
+ (elf_x86_64_reloc_name_lookup): Likewise.
+ (elf_x86_64_check_relocs): Handle R_X86_64_SIZE32 and
+ R_X86_64_SIZE64.
+ (elf_x86_64_gc_sweep_hook): Likewise.
+ (elf_x86_64_relocate_section): Likewise.
+
+ * reloc.c (bfd_reloc_code_type): Add BFD_RELOC_SIZE32 and
+ BFD_RELOC_SIZE64.
+
+2013-01-15 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf64-x86-64.c (R_X86_64_standard): Replace R_X86_64_IRELATIVE
+ with R_X86_64_RELATIVE64.
+
+2013-01-15 Nick Clifton <nickc@redhat.com>
+
+ * elf32-msp430.c: Fix spelling typo.
+
+2013-01-15 Alan Modra <amodra@gmail.com>
+
+ * elf64-ppc.c (ppc64_elf_size_stubs): Default shared libs to
+ plt-thread-safe.
+
+2013-01-14 Alan Modra <amodra@gmail.com>
+
+ PR binutils/14813
+ * bfdio.c (struct bfd_iovec <bclose>): Revert 2012-11-06.
+ (memory_bclose): Likewise. Return 0 on success.
+ * cache.c (cache_bclose): Likewise.
+ * opncls.c (opncls_bclose, bfd_close): Likewise.
+ * vms-lib.c (vms_lib_bclose): Likewise.
+ * libbfd.h: Regenerate.
+
+2013-01-13 Alan Modra <amodra@gmail.com>
+
+ * elf-bfd.h (struct elf_link_hash_entry): Delete dynamic_weak.
+ Add ref_dynamic_nonweak.
+ * elflink.c (_bfd_elf_mark_dynamic_def_weak): Delete.
+ (_bfd_elf_merge_symbol): Don't call above function. Move
+ setting of ref_dynamic_nonweak and dynamic_def earlier. Don't
+ clear dynamic_def.
+ (elf_link_add_object_symbols): Delete redundant "override" test.
+ Don't set dynamic_def here.
+ (elf_link_output_extsym): Update.
+
+2013-01-12 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf32-i386.c (elf_i386_check_relocs): Set bfd errror for
+ normal and TLS symbol access.
+ * elf64-x86-64.c (elf_x86_64_check_relocs): Likewise.
+
+2013-01-12 Alan Modra <amodra@gmail.com>
+
+ * elf-bfd.h (_bfd_elf_strtab_refcount): Declare.
+ * elf-strtab.c (_bfd_elf_strtab_refcount): New function.
+ * elflink.c (elf_add_dt_needed_tag): Use _bfd_elf_strtab_refcount.
+
+2013-01-12 Alan Modra <amodra@gmail.com>
+
+ PR ld/12549
+ * elf-bfd.h (_bfd_elf_strtab_clear_refs): Declare.
+ (_bfd_elf_strtab_clear_all_refs): Define.
+ * elf-strtab.c (_bfd_elf_strtab_clear_refs): New function.
+ (_bfd_elf_strtab_clear_all_refs): Delete.
+ * elflink.c (elf_link_add_object_symbols): Clear out added
+ strtab refs. Correct handling of warning common symbols.
+
+2013-01-10 H.J. Lu <hongjiu.lu@intel.com>
+
+ * aout0.c: Remove trailing white spaces.
+ * archive.c: Likewise.
+ * archures.c: Likewise.
+ * bfd-in.h: Likewise.
+ * bfd-in2.h: Likewise.
+ * coff-alpha.c: Likewise.
+ * coff-i860.c: Likewise.
+ * coff-mips.c: Likewise.
+ * coff-ppc.c: Likewise.
+ * coff-tic80.c: Likewise.
+ * coff-x86_64.c: Likewise.
+ * coff-z80.c: Likewise.
+ * coffcode.h: Likewise.
+ * coffgen.c: Likewise.
+ * cofflink.c: Likewise.
+ * compress.c: Likewise.
+ * corefile.c: Likewise.
+ * cpu-arm.c: Likewise.
+ * cpu-avr.c: Likewise.
+ * cpu-bfin.c: Likewise.
+ * cpu-cr16.c: Likewise.
+ * cpu-cr16c.c: Likewise.
+ * cpu-crx.c: Likewise.
+ * cpu-h8300.c: Likewise.
+ * cpu-i386.c: Likewise.
+ * cpu-lm32.c: Likewise.
+ * cpu-m68k.c: Likewise.
+ * cpu-moxie.c: Likewise.
+ * cpu-msp430.c: Likewise.
+ * cpu-sh.c: Likewise.
+ * cpu-xc16x.c: Likewise.
+ * dwarf2.c: Likewise.
+ * ecofflink.c: Likewise.
+ * ecoffswap.h: Likewise.
+ * elf-ifunc.c: Likewise.
+ * elf-m10300.c: Likewise.
+ * elf-vxworks.c: Likewise.
+ * elf32-avr.c: Likewise.
+ * elf32-avr.h: Likewise.
+ * elf32-cr16.c: Likewise.
+ * elf32-cr16c.c: Likewise.
+ * elf32-cris.c: Likewise.
+ * elf32-crx.c: Likewise.
+ * elf32-frv.c: Likewise.
+ * elf32-hppa.c: Likewise.
+ * elf32-i860.c: Likewise.
+ * elf32-ip2k.c: Likewise.
+ * elf32-iq2000.c: Likewise.
+ * elf32-m32c.c: Likewise.
+ * elf32-m68hc1x.c: Likewise.
+ * elf32-msp430.c: Likewise.
+ * elf32-mt.c: Likewise.
+ * elf32-ppc.c: Likewise.
+ * elf32-rl78.c: Likewise.
+ * elf32-s390.c: Likewise.
+ * elf32-score.h: Likewise.
+ * elf32-sh-symbian.c: Likewise.
+ * elf32-sh.c: Likewise.
+ * elf32-spu.c: Likewise.
+ * elf32-tic6x.c: Likewise.
+ * elf32-v850.c: Likewise.
+ * elf32-xc16x.c: Likewise.
+ * elf32-xtensa.c: Likewise.
+ * elf64-alpha.c: Likewise.
+ * elf64-hppa.c: Likewise.
+ * elf64-ppc.c: Likewise.
+ * elf64-s390.c: Likewise.
+ * elfcore.h: Likewise.
+ * elflink.c: Likewise.
+ * elfxx-mips.c: Likewise.
+ * elfxx-sparc.c: Likewise.
+ * elfxx-tilegx.c: Likewise.
+ * ieee.c: Likewise.
+ * libcoff.h: Likewise.
+ * libpei.h: Likewise.
+ * libxcoff.h: Likewise.
+ * linker.c: Likewise.
+ * mach-o-i386.c: Likewise.
+ * mach-o-target.c: Likewise.
+ * mach-o.c: Likewise.
+ * mach-o.h: Likewise.
+ * mmo.c: Likewise.
+ * opncls.c: Likewise.
+ * pdp11.c: Likewise.
+ * pe-x86_64.c: Likewise.
+ * peXXigen.c: Likewise.
+ * pef-traceback.h: Likewise.
+ * pei-x86_64.c: Likewise.
+ * peicode.h: Likewise.
+ * plugin.c: Likewise.
+ * reloc.c: Likewise.
+ * riscix.c: Likewise.
+ * section.c: Likewise.
+ * som.c: Likewise.
+ * syms.c: Likewise.
+ * tekhex.c: Likewise.
+ * ticoff.h: Likewise.
+ * vaxbsd.c: Likewise.
+ * xcofflink.c: Likewise.
+ * xtensa-isa.c: Likewise.
+
+2013-01-10 Will Newton <will.newton@imgtec.com>
+
+ * Makefile.am: Add Meta.
+ * Makefile.in: Regenerate.
+ * archures.c (bfd_mach_metag): New.
+ * bfd-in2.h: Regenerate.
+ * config.bfd: Add Meta.
+ * configure: Regenerate.
+ * configure.in: Add Meta.
+ * cpu-metag.c: New file.
+ * elf-bfd.h: Add Meta.
+ * elf32-metag.c: New file.
+ * elf32-metag.h: New file.
+ * libbfd.h: Regenerate.
+ * reloc.c: Add Meta relocations.
+ * targets.c: Add Meta.
+
+2013-01-08 Yufeng Zhang <yufeng.zhang@arm.com>
+
+ * elf-bfd.h (elfcore_write_aarch_tls): Add prototype.
+ (elfcore_write_aarch_hw_break): Likewise.
+ (elfcore_write_aarch_hw_watch): Likewise.
+ * elf.c (elfcore_grok_aarch_tls): New function.
+ (elfcore_grok_aarch_hw_break): Likewise.
+ (elfcore_grok_aarch_hw_watch): Likewise.
+ (elfcore_grok_note): Call the new functions to handle the
+ corresponding notes.
+ (elfcore_write_aarch_tls): New function.
+ (elfcore_write_aarch_hw_break): Likewise.
+ (elfcore_write_aarch_hw_watch): Likewise.
+ (elfcore_write_register_note): Call the new functions to handle the
+ corresponding pseudo sections.
+
+2013-01-07 Tom Tromey <tromey@redhat.com>
+
+ * section.c (_bfd_std_section): Rename from std_section.
+ (bfd_com_section_ptr, bfd_und_section_ptr, bfd_abs_section_ptr)
+ (STD_SECTION): Update.
+ * bfd-in2.h: Rebuild.
+
+2013-01-04 Juergen Urban <JuergenUrban@gmx.de>
+
+ * archures.c (bfd_mach_mips5900): Define.
+ * bfd-in2.h: Regenerate.
+ * config.bfd: Add mips64-ps2-elf and mips-ps2-elf targets.
+ * cpu-mips.c: Add support for MIPS r5900.
+ * elfxx-mips.c: Add support for MIPS r5900 (extension of r4000).
+
+2013-01-03 Nickolai Zeldovich <nickolai@csail.mit.edu>
+ Nick Clifton <nickc@redhat.com>
+
+ * elflink.c (get_value): Prevent the use of an undefined shift
+ operation. Add sanity checks.
+
+2013-01-02 Kaushik Phatak <kaushik.phatak@kpitcummins.com>
+
+ * config.bfd (cr16*-*-uclinux*): New target support.
+
+For older changes see ChangeLog-2012
+
+Copyright (C) 2013 Free Software Foundation, Inc.
+
+Copying and distribution of this file, with or without modification,
+are permitted in any medium without royalty provided the copyright
+notice and this notice are preserved.
+
+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 0000000..31aa237
--- /dev/null
+++ b/bfd/ChangeLog-9193
@@ -0,0 +1,7854 @@
+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
+ sco5-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):
+ * config/delta88.mh (HDEFINES): Define this to be -DPTRACE_CORE.
+ * config/delta88.mh (HDEPFILES): Defined to be ptrace-core.o.
+ * ptrace-core.c: New file for dealing with core files with
+ start with the ptrace_user structure found on BCS compliant systems.
+ * 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.host: 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, config/h8500-coff.mt, config/sh-coff.mt,
+ config/st2000.mt, config/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)
+
+ * nlmcode.h (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.host: 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.
+ * hosts/hppabsd.h: Fix declarations of malloc and free.
+ * 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.c: 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)
+
+ * targets.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.
+
+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:
+ * ctor.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.c (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.c: 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.
+ * section.c (elf_print_symbol): 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)
+ * targets.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.c, 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,
+ newsos3.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.
+ * newsos3.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, doc/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)
+
+ * core.c: New file.
+ * format.c: New file.
+ * reloc.c: New file.
+ * section.c: New file.
+ * syms.c: New filew.
+ 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)
+
+ * 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.
+
+ * newsos3.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 newsos3.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.
+
+Copyright (C) 1991-1993 Free Software Foundation, Inc.
+
+Copying and distribution of this file, with or without modification,
+are permitted in any medium without royalty provided the copyright
+notice and this notice are preserved.
+
+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 0000000..beee531
--- /dev/null
+++ b/bfd/ChangeLog-9495
@@ -0,0 +1,10049 @@
+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.h, 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.c (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)
+
+ * 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.
+ (_bfd_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.
+
+ * 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)
+
+ * 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.c (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 =).
+
+ * 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
+
+Copyright (C) 1994-1995 Free Software Foundation, Inc.
+
+Copying and distribution of this file, with or without modification,
+are permitted in any medium without royalty provided the copyright
+notice and this notice are preserved.
+
+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 0000000..8132840
--- /dev/null
+++ b/bfd/ChangeLog-9697
@@ -0,0 +1,6735 @@
+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, 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)
+
+ * 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: Rebuild.
+ * configure: Rebuild.
+ * Makefile.in: Rebuild.
+ * 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: Corresponding changes.
+ * configure.in: Corresponding changes.
+ * Makefile.in: Rebuild.
+ * 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: Rebuild.
+ * aclocal.m4: Rebuild.
+ * 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.c (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: New target, elf-*-D30V.
+ * archures.c: New target, elf-*-D30V.
+ * config.bfd: New target, elf-*-D30V.
+ * configure.in: New target, elf-*-D30V.
+ * elf.c: New target, elf-*-D30V.
+ * reloc.c: New target, elf-*-D30V.
+ * targets.c: New target, elf-*-D30V.
+ * bfd-in2.h: Rebuilt.
+ * configure: Rebuilt.
+ * libbfd.h: Rebuilt.
+ * cpu-d30v.c: New files.
+ * 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.
+ (_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: Add m32r support.
+ * configure.in: Likewise.
+ * configure: Likewise.
+ * Makefile.in: Likewise.
+ * archures.c: Likewise.
+ * elf.c: Likewise.
+ * 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.
+ * configure.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.
+
+ * coffcode.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
+
+Copyright (C) 1996-1997 Free Software Foundation, Inc.
+
+Copying and distribution of this file, with or without modification,
+are permitted in any medium without royalty provided the copyright
+notice and this notice are preserved.
+
+Local Variables:
+mode: change-log
+left-margin: 8
+fill-column: 74
+version-control: never
+End:
diff --git a/bfd/ChangeLog-9899 b/bfd/ChangeLog-9899
new file mode 100644
index 0000000..b1d516c
--- /dev/null
+++ b/bfd/ChangeLog-9899
@@ -0,0 +1,5605 @@
+1999-12-29 Richard Henderson <rth@cygnus.com>
+
+ * elflink.h (bfd_elf,size_dynamic_sections): Don't export all
+ if no dynamic sections created.
+
+1999-12-27 Nick Clifton <nickc@cygnus.com>
+
+ * peicode.h (pe_bfd_object_p): Only define for PE format
+ targets.
+
+1999-12-17 Nick Clifton <nickc@cygnus.com>
+
+ * coff-i386.c (i3coff_object_p): Delete.
+ (i386coff_vec): Replace reference to i3coff_object_p with a
+ reference to coff_object_p.
+
+ * coff-mcore.c (pe_object_p): Delete.
+
+ * peicode.h (pe_bfd_object_p): New function: Detect the
+ presence of a PE format COFF object file. Also detect and
+ warn about the presence of LINK6 format Image Library Format
+ object files.
+
+1999-12-16 Nick Clifton <nickc@cygnus.com>
+
+ * coff-arm.c (NUM_ELEM): New macro.
+ (NUM_RELOCS): New macro: The number of known ARM relocs.
+ (RTYPE2HOWTO): Return NULL if the reloc type is out of range.
+ (coff_arm_rtype_to_howto): Return NULL if the reloc type is out
+ of range.
+ (bfd_arm_process_before_allocation): Produce a warning message if
+ an out of range symbol index is encountered.
+
+1999-12-14 Nick Clifton <nickc@cygnus.com>
+
+ * elflink.h (is_global_symbol_definition): New Function: Return
+ true iff the symbol is being given a global definition in this
+ bfd.
+ (elf_link_is_defined_archive_symbol): Do not bother processing
+ symbols for an archive element that has already been included
+ in the link.
+ Use is_global_symbol_definition().
+
+1999-12-09 Andrew Cagney <cagney@cygnus.com>
+
+ * config.bfd: Add support for sparc-*-netbsdelf* and
+ sparc-*-netbsdaout*.
+
+1999-12-13 Nick Clifton <nickc@cygnus.com>
+
+ * elflink.h (elf_link_is_defined_archive_symbol): Check to see
+ if the symbol is in the common section.
+
+1999-12-10 Nick Clifton <nickc@cygnus.com>
+
+ * elflink.h (elf_link_is_defined_archive_symbol): New
+ function: Decide if a symbol, in an archive map is there
+ because it is defined in the archive element, or because it is
+ just another common declaration of it.
+ (elf_link_add_archive_symbols): Use
+ elf_link_is_defined_archive_symbol to decide if an archive
+ element contain a reference to a common symbol should be
+ linked in or not.
+
+1999-12-10 Nick Clifton <nickc@cygnus.com>
+
+ * elflink.h: Revert previous patch.
+ * targets.c: Revert previous patch.
+ * libbfd-in2.h: Revert previous patch.
+ * libbfd.h: Revert previous patch.
+ * elfxx-target.h: Revert previous patch.
+ * archive.c: Revert previous patch.
+ * aout-target.h: Revert previous patch.
+ * aout-tic30.h: Revert previous patch.
+ * bfd.c: Revert previous patch.
+ * coff-alpha.c: Revert previous patch.
+ * coff-rs6000.c: Revert previous patch.
+ * elf64-mips.c: Revert previous patch.
+ * ieee.c: Revert previous patch.
+ * libecoff.h: Revert previous patch.
+ * oasys.c: Revert previous patch.
+ * som.c: Revert previous patch.
+ * vms.c: Revert previous patch.
+
+1999-12-09 Nick Clifton <nickc@cygnus.com>
+
+ * elflink.h (elf_link_add_archive_symbols): Add an archive
+ element even if contains a symbol which is currently only
+ considered to be a common.
+
+ * targets.c (struct bfd_target): Add new field
+ _bfd_allow_commons_in_armap.
+ * bfd-in2.h:Regenerate.
+
+ * libbfd-in2.h (_bfd_noarchive_allow_commons_in_armap):
+ Define.
+ (_bfd_archive_bsd_allow_commons_in_armap): Define.
+ * libbfd.h: Regenerate.
+
+ * elfxx-target.h: If using COFF archive map, override
+ definition of allow_commons_in_armap and replace with
+ bfd_false.
+
+ * archive.c (bfd_compute_and_write_armap): Do not place common
+ symbols into the archive map unless _bfd_allow_commons_in_armap
+ returns true.
+
+ * aout-target.h (MY_allow_commons_in_armap): Define.
+ * aout-tic30.h (MY_allow_commons_in_armap): Define.
+ * bfd.c (bfd_allow_commons_in_armap): Define.
+ * coff-alpha.h (alpha_ecoff_allow_commons_in_armap): Define.
+ * coff-rs6000.h (xcoff_allow_commons_in_armap): Define.
+ * elf64-mips.c (bfd_elf64_allow_commons_in_armap): Define.
+ * ieee.c (ieee_ecoff_allow_commons_in_armap): Define.
+ * libecoff.h (_bfd_ecoff_allow_commons_in_armap): Define.
+ * oasys.c (oasys_allow_commons_in_armap): Define.
+ * som.c (som_allow_commons_in_armap): Define.
+ * vms.c (vms_allow_commons_in_armap): Define.
+
+1999-12-07 Jim Blandy <jimb@cygnus.com>
+
+ Add support for SSE registers in ELF core files.
+ * elf.c (elfcore_make_note_pseudosection): New function.
+ (elfcore_grok_prfpreg): Use it.
+ (elfcore_grok_prxfpreg): New function.
+ (elfcore_grok_note): Recognize Linux NT_PRXFPREG notes.
+
+1999-12-03 Ian Lance Taylor <ian@zembu.com>
+
+ * elf32-mips.c (mips_elf_calculate_relocation): Divide R_MIPS_PC16
+ value by 4 before storing it back in the field. From
+ Koundinya. K <kk@ddeorg.soft.net>.
+
+Tue Nov 30 22:41:14 1999 Jeffrey A Law (law@cygnus.com)
+
+ * archures.c (bfd_mach_am33): Define.
+ * bfd-in2.h: Rebuilt.
+ * cpu-m10300.c (bfd_am33_arch): Add to the mn103 architecture list
+ * elf-m10300.c (mn10300_elf_relax_section): Handle am33 instructions.
+ (compute_function_info): Handle additional registers saved by
+ movm on the am33.
+ (elf_mn10300_mach): Handle E_MN10300_MACH_AM33.
+ (_bfd_mn10300_elf_final_write_processing): Handle bfd_mach_am33.
+
+1999-11-29 Jim Blandy <jimb@cygnus.com>
+
+ * elf.c (bfd_get_elf_phdrs, bfd_get_elf_phdr_upper_bound): New
+ functions.
+ * bfd-in2.h (bfd_get_elf_phdrs, bfd_get_elf_phdr_upper_bound): New
+ declarations.
+
+1999-11-27 Michael Meissner <meissner@cygnus.com>
+
+ * reloc.c (BFD_RELOC_ALPHA_USER_LITERAL): New relocation for
+ internal use within gas for alpha explicit relocations.
+ (BFD_RELOC_ALPHA_USER_LITUSE_BASE): Ditto.
+ (BFD_RELOC_ALPHA_USER_LITUSE_BYTOFF): Ditto.
+ (BFD_RELOC_ALPHA_USER_LITUSE_JSR): Ditto.
+ (BFD_RELOC_ALPHA_USER_GPDISP): Ditto.
+ (BFD_RELOC_ALPHA_USER_GPRELHIGH): Ditto.
+ (BFD_RELOC_ALPHA_USER_GPRELLOW): Ditto.
+
+ * elf64-alpha.c (elf64_alpha_reloc_map): Add mappings for
+ BFD_RELOC_ALPHA_USER_*.
+
+ * bfd-in2.h: Regenerate.
+ * libbfd.h: Regenerate.
+
+1999-11-26 Fred Fish <fnf@cygnus.com>
+
+ * elf.c (elfcore_read_notes): Add prototype for static function.
+ (_bfd_elf_make_section_from_phdr): Renamed from bfd_section_from_phdr.
+ (bfd_section_from_phdr): Replacement function that calls
+ _bfd_elf_make_section_from_phdr for generic segment types and
+ backend fucntion pointed to by elf_backend_section_from_phdr for
+ backend specific segment types.
+ (_bfd_elfcore_section_from_phdr): Remove call to elfcore_read_notes,
+ now called by _bfd_elf_make_section_from_phdr. Note that this func
+ is now just a stub between the caller and bfd_section_from_phdr.
+
+ * elf-bfd.h (struct elf_backend_data): Add new function pointer
+ elf_backend_section_from_phdr.
+ (elf_backend_section_from_phdr): Add prototype.
+
+ * elfxx-target.h (elf_backend_section_from_phdr): Define default.
+ (elfNN_bed): Add elf_backend_section_from_phdr.
+
+1999-11-25 Nick Clifton <nickc@cygnus.com>
+
+ * coff-arm.c (bfd_arm_get_bfd_for_interworking): Add
+ SEC_CODE and SEC_READONLY flags to glue sections.
+
+ * elf32-arm.h (bfd_elf32_arm_get_bfd_for_interworking): Add
+ SEC_CODE and SEC_READONLY flags to glue sections.
+
+1999-11-20 Nick Clifton <nickc@cygnus.com>
+
+ * coff-mcore.c (coff_mcore_relocate_section): Fix typo in previous
+ delta.
+
+1999-11-19 Catherine Moore <clm@cygnus.com>
+
+ * elf32-m68k.c (elf_cpu32_plt0_entry): Fix encoding.
+ (elf_cpu32_plt_entry): Likewise.
+
+1999-11-18 Nick Clifton <nickc@cygnus.com>
+
+ * coff-mcore.c (coff_mcore_rtype_to_howto): Special case handling
+ for RVA relocs.
+ (coff_mcore_relocate_section): Initialise addend to 0.
+ Special case processing of RVA reloc.
+
+1999-11-17 Richard Henderson <rth@cygnus.com>
+
+ * elf-bfd.h (struct elf_backend_data): Reorder collect and
+ type_change_ok; add sign_extend_vma.
+ * elf32-mips.c (elf_backend_sign_extend_vma): Define.
+ * elfcode.h (elf_swap_symbol_in): Mind be->sign_extend_vma.
+ (elf_swap_shdr_in, elf_swap_phdr_in): Likewise.
+ * elfxx-target.h (elf_backend_sign_extend_vma): Default.
+ (elfNN_bed): Follow struture changes.
+
+1999-11-09 Ian Lance Taylor <ian@zembu.com>
+
+ * libbfd.c (bfd_read): Check result of read against desired result
+ using !=, not <.
+ (_bfd_generic_get_section_contents): Set bfd_error if the seek is
+ invalid compared to the section size.
+
+ * ieee.c (ieee_slurp_debug): Get the length of the debug
+ information right if there is no data part.
+
+Tue Nov 2 01:44:41 1999 Jeffrey A Law (law@cygnus.com)
+
+ * som.c (som_fixup_formats): Improve handling of R_AUX_UNWIND,
+ R_LINETAB, R_LINETAB_ESC, and R_COMMENT.
+
+1999-10-28 Ian Lance Taylor <ian@zembu.com>
+
+ * elflink.h (elf_bfd_final_link): Make last_local signed.
+
+1999-10-27 Ian Lance Taylor <ian@zembu.com>
+
+ * stabs.c (_bfd_link_section_stabs): Make sure .stabstr section
+ starts with a zero.
+
+Sat Oct 23 17:36:12 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * archures.c: Add definitions bfd_mach_d10v, bfd_mach_d10v_ts2 and
+ bfd_mach_d10v_ts3.
+ * cpu-d10v.c (d10v_ts3_info, d10v_ts2_info): Add.
+ * bfd-in2.h: Regenerate.
+
+1999-10-15 Andrew Haley <aph@cygnus.com>
+
+ * dwarf1.c (parse_die): Fail to parse a die if its length is zero.
+
+Sun Oct 17 17:19:00 1999 Jeffrey A Law (law@cygnus.com)
+
+ * libhppa.h (bfd_hppa_insn2fmt): Change to return an int.
+
+1999-10-08 Ian Lance Taylor <ian@zembu.com>
+
+ * elflink.h (elf_merge_symbol): When overriding a weak symbol with
+ a defined symbol in a shared library, clear the DEF_DYNAMIC flag
+ too.
+
+Fri Oct 8 13:03:45 1999 Geoffrey Keating <geoffk@cygnus.com>
+
+ * elf32-mips.c (mips_elf_calculate_relocation): R_MIPS_LITERAL
+ relocs also need the GP value.
+ (_bfd_mips_elf_relocate_section): Handle unpaired LO16 relocs
+ properly. Handle sign-extension for R_MIPS_64 correctly. Correct
+ the GP value for R_MIPS_LITERAL relocs too. Handle
+ R_MIPS_64 relocs properly on big-endian MIPS.
+ (mips_elf_sign_extend): Behave properly with 'long long'.
+ (mips_elf_highest): Correct typo.
+
+Mon Oct 4 17:49:45 1999 Nick Clifton <nickc@cygnus.com>
+
+ * cpu-m32r.c (arch_info_struct): New static global.
+ (bfd_m32r_arch): Refer to it.
+ * elf32-m32r.c (m32r_elf_object_p): Recognize E_M32RX_ARCH.
+ (m32r_elf_print_private_bfd_data): Ditto.
+ (m32r_elf_final_write_processing): Handle bfd_mach_m32rx.
+ * archures.c (bfd_mach_m32rx): Define it.
+ * bfd-in2.h: Rebuild.
+
+1999-09-28 Fred Fish <fnf@cygnus.com>
+
+ * targets.c (cisco_core_vec): Replaced with two new vecs ...
+ (cisco_core_big_vec): Add new bigendian vec.
+ (cisco_core_little_vec): Add new little endian vec.
+
+ * cisco-core.c (CRASH_INFO): Fixed offset replaced with ...
+ (crash_info_locs): Add array of possible offsets.
+ (MASK_ADDR): Mask to apply to crash info offset.
+ (crashinfo_external): Add textbase, database, bssbase and
+ turn into a typedef.
+ (cisco_core_file_validate): Renamed from cisco_core_file_p.
+ Many small changes to account for additional hardware versions.
+ Pick a reasonable size for ".reg" section. Add a ".crash"
+ section to allow access to crashinfo_external struct.
+ (cisco_core_file_p): New version of this function that
+ iterates over crash_info_locs, calling cisco_core_file_validate.
+ (cisco_core_vec): Old big endian only vec replaced with ...
+ (cisco_core_big_vec): Add big endian version.
+ (cisco_core_little_vec): Add little endian version.
+
+ * configure.in (cisco_core_vec): Split to two new vectors ...
+ (cisco_core_big_vec): New target vector.
+ (cisco_core_little_vec): New target vector.
+ * configure: Regenerate.
+ * config.bfd (targ): For m68*-*-aout* targ, change cisco_core_vec
+ to cisco_core_big_vec in targ_selvecs.
+
+1999-09-28 Geoffrey Keating <geoffk@cygnus.com>
+
+ * elf32-mips.c (mips_elf_relocate_hi16): Unused, delete.
+ (mips_elf_relocate_got_local): Unused, delete.
+ (mips_elf_relocate_global_got): Unused, delete.
+
+1999-09-24 Fred Fish <fnf@cygnus.com>
+
+ * elf.c (bfd_section_from_phdr): Add typename variable. Use p_type
+ to initialize it to something meaningful. Then use it to generate
+ more useful segment names.
+
+Sun Sep 19 12:16:47 1999 Jeffrey A Law (law@cygnus.com)
+
+ * som.c (NO_PCREL_MODES): Define if the system does not define
+ R_SHORT_PCREL_MODE.
+ (hppa_som_gen_reloc_type): Handle both short and long pcrel branches.
+ (som_write_fixups): Eliminate redundant pcrel mode relocs. Handle
+ R_LONG_PCREL_MODE and R_SHORT_PCREL_MODE
+ * libhppa.h (dis_assemble_22): New function.
+ (bfd_hppa_insn2fmt): Handle long branch.
+
+ * libhppa.h (bfd_hppa_insn2fmt): Decode and handle formats found
+ in PA2.0.
+
+1999-09-17 Alan Modra <alan@spri.levels.unisa.edu.au>
+
+ * coff-i386.c (coff_i386_reloc_type_lookup): Support BFD_RELOC_16,
+ BFD_RELOC_16_PCREL, BFD_RELOC_8, BFD_RELOC_8_PCREL relocs.
+ (reloc_howto_type howto_table): Tidy comments and whitespace.
+
+1999-09-17 Nick Clifton <nickc@cygnus.com>
+
+ * elf32-arm.h (bfd_elf32_arm_get_bfd_for_interworking): Undo
+ previous delta. Set sec->gc_mark instead.
+
+Thu Sep 16 11:21:13 1999 Catherine Moore <clm@cygnus.com>
+
+ * elf32-m68k.c (elf_cpu32_plt0_entry): Use a1 instead of a0.
+ (elf_cpu32_plt_entry): Likewise.
+
+Thu Sep 16 10:48:17 1999 Jeffrey A Law (law@cygnus.com)
+
+ * elf-hppa.h (elf_hppa_final_write_processing): Turn on TRAPNIL.
+
+ * elf-hppa.h (elf_hppa_final_link): If unable to find __gp in the
+ symbol table, then just compute a suitable value (but do not
+ create a __gp symbol).
+
+ * elf-hppa.h (elf_hppa_relocate_section): Allow undefined
+ symbols when building shared libraries.
+ (elf_hppa_final_link_relocate): Correct handling of PCREL
+ relocations against undefined symbols.
+
+1999-09-16 Nick Clifton <nickc@cygnus.com>
+
+ * elf32-arm.h (bfd_elf32_arm_get_bfd_for_interworking): Mark
+ interworking sections as linker created so that they will not
+ be removed by garbage collection.
+
+Wed Sep 15 02:31:57 1999 Jeffrey A Law (law@cygnus.com)
+
+ * elf-hppa.h (elf_hppa_final_link): Revamp __gp handling.
+ (elf_hppa_final_link_relocate): Consistently create an absolute
+ address, then subtract out the value of __gp.
+
+1999-09-14 Michael Meissner <meissner@cygnus.com>
+
+ * configure.in (Canonicalization of target names): Remove adding
+ ${CONFIG_SHELL} in front of $ac_config_sub, since autoconfig 2.14
+ generates $ac_config_sub with a ${CONFIG_SHELL} already.
+ * configure: Regenerate.
+
+1999-09-14 Nick Clifton <nickc@cygnus.com>
+
+ * elf32-m32r.c (ELF_MAXPAGESIZE): Change to 0x1 (at request of
+ Mitsubishi).
+
+Mon Sep 13 20:01:47 1999 Jeffrey A Law (law@cygnus.com)
+
+ * elf-hppa.h (elf_hppa_record_segment_addrs): New function.
+ (elf_hppa_final_link): Initialize text_segment_base and
+ data_segment_base.
+ (elf_hppa_final_link_relocate): Handle SEGREL relocations.
+
+ * elf-hppa.h (elf_hppa_final_link): Remove unused variables.
+ (elf_hppa_final_link_relocate): Likewise.
+ (elf_hppa_relocate_insn): Likewise.
+ (elf_hppa_relocate_section): Initialize HOWTO.
+
+1999-09-13 Donn Terry <donn@interix.com>
+
+ * coffcode.h (styp_to_sec_flags): Further refinement of COMDAT
+ handling to support both GNU and MS objects.
+
+ * coffcode.h (coff_write_object_contents): Don't check reloc_count
+ when determining whether to set F_RELFLG.
+
+1999-09-13 Philip Blundell <pb@nexus.co.uk>
+
+ * elf32-arm.h (elf32_arm_final_link_relocate): Don't range-check
+ PC24 relocs if the target is an undefined weak symbol.
+ (arm_add_to_rel): Fix compiler warning.
+ (elf32_arm_plt0_entry): Correct comments.
+
+1999-09-13 Alan Modra <alan@spri.levels.unisa.edu.au>
+
+ * elfcode.h (write_relocs): Check for the_bfd NULL when handling
+ an absolute symbol in REL relocs.
+
+Sun Sep 12 23:47:58 1999 Jeffrey A Law (law@cygnus.com)
+
+ * elf-hppa.h (elf_hppa_final_link_relocate): Handle SECREL32.
+ Stub SEGREL32. Return an error for any relocation not handled.
+
+1999-09-12 Ian Lance Taylor <ian@zembu.com>
+
+ * cofflink.c (coff_link_add_symbols): Look for special MSVC string
+ constant symbols, and avoid multiple definition errors on them.
+
+1999-09-12 Donn Terry <donn@interix.com>
+
+ * libbfd.c (bfd_log2): Rewrite to avoid infinite loop if most
+ significant bit is set.
+
+1999-09-11 Ian Lance Taylor <ian@zembu.com>
+
+ * coff-ppc.c (COFF_SECTION_ALIGNMENT_ENTRIES): Define.
+
+ * elfcode.h (write_relocs): Handle an absolute symbol in REL
+ relocs as we do for RELA relocs.
+
+1999-09-11 Donn Terry <donn@interix.com>
+
+ * libpei.h (_bfd_pei_final_link_postscript): Declare.
+ (coff_final_link_postscript): Define.
+ * peigen.c (_bfd_pei_swap_aouthdr_out): Don't set value for data
+ directory entries here.
+ (_bfd_pei_final_link_postscript): New function.
+
+ * peigen.c (_bfd_pei_swap_scnhdr_out): Remove code which sets
+ section flags based on the section name.
+
+ * peicode.h (coff_swap_scnhdr_in): If COFF_IMAGE_WITH_PE, the
+ get the overflow of the s_nlnno field from the s_nreloc field.
+ * peigen.c (_bfd_pei_swap_scnhdr_out): If doing a final link, swap
+ the s_nlnno overflow of the .text section into the s_nreloc
+ field.
+
+ * peigen.c (add_data_entry): Declare.
+ (pei_swap_aouthdr_out): Get image size right. Set linker version
+ more intuitively.
+ (pei_swap_scnhdr_out): Test for UNINIT section, not .bss.
+ (pe_print_idata): Code cleanup, print more info, get rid of (now)
+ extraneous ImageBase.
+ (pe_print_edata): Likewise.
+ (pe_print_pdata): Likewise. Print exception entries.
+ (pe_print_reloc): Likewise. Print MIPS_JMPADDR.
+ (tbl): Make const, add "UNKNOWN".
+ (_bfd_pe_print_private_bfd_data_common): Print timestamp.
+ (_bfd_pe_bfd_copy_private_bfd_data_common): Don't copy deleted
+ section data directory.
+ (_bfd_pe_bfd_copy_private_section_data): Copy pe_flags.
+
+ * libpei.h (_bfd_pe_bfd_get_symbol_info): Declare.
+ * peigen.c (_bfd_pe_bfd_get_symbol_info): New function.
+ * peicode.h (coff_get_symbol_info): Define.
+
+ * config.bfd (i[3456]86-*-interix*): Set targ_cflags to
+ -DSTRICT_PE_FORMAT.
+ * coffcode.h (styp_to_sec_flags): Check STRICT_PE_FORMAT rather
+ than __INTERIX.
+ (coff_classify_symbol): Re-revert 1999-08-08 patch if
+ STRICT_PE_FORMAT.
+
+ * libpei.h: New file, broken out of peicode.h.
+ * peigen.c: New file, broken out of peicode.h.
+ * peicode.h: A bunch of code moved out to libpei.h and peigen.c.
+ * configure.in: Add peigen.lo to list of files required for each
+ PE target.
+ * Makefile.am: Rebuild dependencies.
+ (BFD32_BACKENDS): Add peigen.lo.
+ (BFD32_BACKENDS_CFILES): Add peigen.c.
+ (SOURCE_HFILES): Add libpei.h.
+ * configure, Makefile.in: Rebuild.
+
+ * peicode.h (coff_swap_scnhdr_in): Don't check for a special
+ section name of _BSS; check IMAGE_SCN_CNT_UNINITIALIZED_DATA
+ instead. Don't clear the s_paddr field for an uninitialized data
+ section.
+
+ * coffcode.h (coff_mkobject_hook): Set timestamp field in
+ coff_data_type to f_timdat.
+ * peicode.h (pe_mkobject_hook): Likewise.
+
+ * peicode.h (coff_swap_filehdr_in): Check the NT executable magic
+ number if COFF_IMAGE_WITH_PE.
+
+ * coffcode.h (coff_mkobject_hook): If COFF_WITH_PE, set HAS_DEBUG
+ to the reverse of IMAGE_FILE_DEBUG_STRIPPED.
+ (coff_write_object_contents): Set IMAGE_FILE_DEBUG_STRIPPED if
+ there is no SEC_DEBUGGING section.
+ * peicode.h (pe_mkobject_hook): Set HAS_DEBUG to the reverse of
+ IMAGE_FILE_DEBUG_STRIPPED.
+
+ * pe-i386.c (COFF_LONG_FILENAMES): Define.
+ (COFF_SECTION_ALIGNMENT_ENTRIES): Define.
+ * pei-i386.c (COFF_LONG_FILENAMES): Define.
+ (COFF_SECTION_ALIGNMENT_ENTRIES): Define.
+
+ * coffswap.h (IMAGE_BASE): Don't define.
+ * pei-arm.c (IMAGE_BASE): Don't define.
+ * pei-i386.c (IMAGE_BASE): Don't define.
+ * pei-mcore.c (IMAGE_BASE): Don't define.
+ * pei-ppc.c (IMAGE_BASE): Don't define.
+
+ * cofflink.c (_bfd_coff_link_input_bfd): When writing out a
+ symbol, switch on the class when determining whether to modify the
+ value. For PE, don't modify the value of a C_FCN symbol not named
+ .bf.
+
+ * libbfd-in.h (_bfd_abort): Declare.
+ (abort): Define.
+ * bfd.c (_bfd_abort): New function.
+ * libbfd.h: Rebuild.
+
+ * coffcode.h (coff_set_alignment_hook): Delete POWERPC_LE_PE
+ special handling.
+
+ * cofflink.c (_bfd_coff_link_input_bfd): If a symbol is stripped,
+ don't write out the associated line numbers.
+
+ * cofflink.c (_bfd_coff_write_global_sym): Handle section symbol
+ aux entries.
+
+ * cofflink.c (coff_link_add_symbols): Don't warn about symbol type
+ changes when the base type is unknown.
+
+ * coffgen.c (coff_print_symbol): Fix printing of aux record for
+ function symbols.
+
+ * syms.c (BSF_DEBUGGING_RELOC): Define.
+ * coffcode.h (coff_slurp_symbol_table): If PE, set BSF_DEBUGGING
+ for C_FCN/C_EFCN symbols, and set BSF_DEBUGGING_RELOC for such
+ symbols named .bf.
+ * coffgen.c (fixup_symbol_value): Relocate a symbol which has
+ BSF_DEBUGGING_RELOC set.
+ * bfd-in2.h: Rebuild.
+
+1999-09-10 Ian Lance Taylor <ian@zembu.com>
+
+ * ecoff.c (bfd_debug_section): Update initialization for new
+ comdat_info field.
+ (_bfd_ecoff_styp_to_sec_flags): Add section parameter.
+ * libecoff.h (_bfd_ecoff_styp_to_sec_flags): Update declaration.
+
+1999-09-10 H.J. Lu <hjl@gnu.org>
+
+ * coff-alpha.c (alpha_ecoff_backend_data): Initialize the new
+ _bfd_filnmlen field.
+ * coff-mips.c (mips_ecoff_backend_data): Likewise.
+
+Fri Sep 10 00:35:14 1999 Jeffrey A Law (law@cygnus.com)
+
+ * elf-hppa.h (elf_hppa_final_link_relocate): Create .opd entries
+ for FPTR relocs involving local symbols.
+
+ * elf-hppa.h (elf_hppa_final_link_relocate): Get the right
+ value for the stub address in a call through a stub.
+ Install the value for a local symbol directly into the DLT
+ instead of generating a reloc. Correctly handle FPTR64 relocs.
+
+ * elf-hppa.h (elf_hppa_unmark_useless_dynamic_symbols): New function.
+ (elf_hppa_remark_useless_dynamic_symbols): Similarly.
+ (elf_hppa_final_link): Call them.
+
+1999-09-10 Ian Lance Taylor <ian@zembu.com>
+
+ * elflink.h (elf_fix_symbol_flags): Move weakdef handling here...
+ (elf_adjust_dynamic_symbol): ...from here.
+
+Wed Sep 8 17:56:11 1999 Jeffrey A Law (law@cygnus.com)
+
+ * elf-hppa.h (elf_hppa_howto_table); There is no DIR64WR, DIR64DR
+ relocation, remove them. SECREL64->LTOFF16WF.
+ (elf_hppa_final_link_relocate): Handle LTOFF* relocations. Handle
+ DIR* relocations.
+ (elf_hppa_relocate_insn): Similarly.
+
+ * elf-hppa.h (elf_hppa_final_link_relocate): Handle PLTOFF* relocs.
+ (elf_hppa_relocate_insn): Similarly.
+
+ * elf-hppa.h (elf_hppa_final_link_relocate): Handle DPREL* and
+ GPREL* relocations.
+ (elf_hppa_relocate_insn): Similarly.
+
+ * elf-hppa.h (elf_hppa_link_final_relocate): Fix typos.
+ Handle LTOFF_TP* relocs.
+ (elf_hppa_relocate_insn): Similarly.
+
+ * elf-hppa.h (elf_hppa_final_link_relocate): Handle PCREL* relocs.
+ Consistently deal with addends. Handle DLTIND14F and DLTREL14F.
+ (elf_hppa_relocate_insn): Handle PCREL* relocs.
+
+ * elf-hppa.h (elf_hppa_final_link_relocate): Handle LT_OFF_FPTR*,
+ DIR32, DIR64 and FPTR64 relocations.
+ (elf_hppa_relocate_insn): Similarly.
+
+ * elf-hppa.h (elf_hppa_final_link): Set the value of __gp to the
+ address of the .PARISC.global section.
+ (elf_hppa_relocate_section): Lookup and pass the PA64 hash
+ table entry elf_hppa_final_link_relocate. Do not give a warning
+ for a reloc against an external symbol if it has a PA64 hash
+ table entry.
+ (elf_hppa_final_link_relocate): Significantly rework. Handle
+ DLTIND relocations. Compute the final value of the relocation
+ before passing the value of elf_hppa_relocate_insn.
+ (elf_hppa_relocate_insn): Revamp to handle just bit tiwiddling
+ relocation support. Handle DLTIND relocation requests just like
+ DLTREL relocation requests. Simplify branch handling.
+
+1999-09-08 Ulrich Drepper <drepper@cygnus.com>
+
+ * elf-hppa.h (elf_hppa_relocate_section): Catch problems with
+ non-allocated section as done in i386 version.
+ (elf_hppa_final_link_relocate): Uncomment R_PARISC_14F in switch
+ statement since this is no know relocation.
+
+Tue Sep 7 17:25:12 1999 Jeffrey A Law (law@cygnus.com)
+
+ * elf-hppa.h (elf_hppa_final_link_relocate): Handle DLTREL14F
+ relocs.
+ (elf_hppa_relocate_insn): Similarly.
+
+ * elf-hppa.h (elf_hppa_final_link_relocate): Handle DLTREL14WR and
+ DLTREL14WD relocs.
+ (elf_hppa_relocate_insn): Similarly.
+
+ * elf-hppa.h (elf_hppa_final_link_relocate): Handle DLTREL14R and
+ DLTREL21L relocs. Pass the output bfd to elf_hppa_relocate_insn.
+ Pass the relocate type rather than the insn format to
+ elf_hppa_relocate_insn.
+ (elf_hppa_relocate_insn): Make switch dependent on relocation type
+ rather than the opcode. Handle DLTREL21L and DLTREL14R relocs.
+
+1999-09-07 Ian Lance Taylor <ian@zembu.com>
+
+ * coffcode.h (bfd_coff_backend_data): Add _bfd_filnmlen field.
+ (bfd_coff_filnmlen): Define.
+ (bfd_coff_std_swap_table): Initialize new field.
+ * coffgen.c (coff_fix_symbol_name): Use bfd_coff_filnmlen rather
+ than FILNMLEN.
+ (coff_write_symbols): Likewise.
+ (coff_get_normalized_symtab): Likewise.
+ * coff-sh.c (bfd_coff_small_swap_table): Initialize new field.
+ * libcoff.h: Rebuild.
+
+1999-09-06 Donn Terry <donn@interix.com>
+
+ * coffcode.h (sort_by_secaddr): New static function if
+ COFF_IMAGE_WITH_PE.
+ (coff_compute_section_file_positions): If COFF_IMAGE_WITH_PE, sort
+ sections by VMA when assigning target_index values. Always set
+ virt_size.
+
+ * libcoff-in.h (struct pei_section_tdata): Add pe_flags field.
+ * coffcode.h (coff_set_alignment_hook) [COFF_WITH_PE version]: Set
+ pe_flags field.
+ * libcoff.h: Rebuild.
+
+ * coffcode.h (coff_set_custom_section_alignment): Add const to
+ declaration to match definition.
+ (coff_write_object_contents): Don't set F_AR32W(R)? if
+ COFF_WITH_PE.
+
+ * coff-i386.c (in_reloc_p): Add declaration.
+ (i386coff_vec): Simplify initialization of
+ application_section_flags.
+
+ * coffcode.h (sec_to_styp_flags): Write separate COFF_WITH_PE
+ version. Move COFF_WITH_PE specific code to new version.
+ (stype_to_sec_flags): Likewise. Add section parameter.
+ * coffgen.c (make_a_section_from_file): Set target_index before
+ calling styp_to_sec_flags. Pass section to styp_to_sec_flags.
+ * libcoff.h: Rebuild.
+
+ * syms.c (stt): Add some PE/PEI section names.
+ (bfd_decode_symclass): Return 'w', not 'U', for a weak undefined
+ symbol.
+ (bfd_symbol_info): Check for 'w'.
+
+ * section.c (struct bfd_comdat_info): Define.
+ (asection): Add comdat field.
+ (STD_SECTION): Initialize comdat field.
+ (bfd_make_section_anyway): Likewise.
+ * bfd-in2.h: Rebuild.
+
+1999-09-06 Andreas Schwab <schwab@suse.de>
+
+ * elflink.h (elf_link_add_object_symbols): Copy NON_GOT_REF flag
+ to version symbols.
+
+1999-09-06 Nick Clifton <nickc@cygnus.com>
+
+ * elflink.h (elf_gc_record_vtentry): Use bfd_zmalloc and
+ bfd_realloc instead of calloc and realloc.
+
+1999-09-04 Steve Chamberlain <sac@pobox.com>
+
+ * cpu-pj.c: New file.
+ * elf32-pj.c: New file.
+ * config.bfd (pj*): New cpu.
+ (pj-*-*, pjl-*-*): New targets.
+ * configure.in (bfd_elf32_pj_vec): New target vector.
+ (bfd_elf32_pjl_vec): New target vector.
+ * archures.c (bfd_arch_pj): Define.
+ * elf.c (prep_headers): Handle bfd_arch_pj.
+ * reloc.c: Define BFD_RELOC_PJ_* relocations.
+ * targets.c (bfd_elf32_pj_vec, bfd_elf32_pjl_vec): Declare and add
+ to target vector list.
+ * Makefile.am: Rebuild dependencies.
+ (ALL_MACHINES): Add cpu-pj.lo.
+ (ALL_MACHINES_CFILES): Add cpu-pj.c.
+ (BFD32_BACKENDS): Add elf32-pj.lo.
+ (BFD32_BACKENDS_CFILES): Add elf32-pj.c.
+ * configure, Makefile.in, bfd-in2.h, libbfd.h: Rebuild.
+
+1999-09-04 Ian Lance Taylor <ian@zembu.com>
+
+ * elf-bfd.h (ELF_LINK_NON_GOT_REF): Define.
+ * elflink.h (elf_adjust_dynamic_symbol): Copy REF_REGULAR_NONWEAK
+ and NON_GOT_REF from weak defined symbol to real symbol.
+ * elf32-i386.c (elf_i386_check_relocs): Set NON_GOT_REF.
+ (elf_i386_adjust_dynamic_symbol): If NON_GOT_REF is not set, don't
+ create a COPY reloc.
+ * elf32-sparc.c (elf32_sparc_check_relocs): Set NON_GOT_REF.
+ (elf32_sparc_adjust_dynamic_symbol): If NON_GOT_REF is not set,
+ don't create a COPY reloc.
+
+1999-09-03 Ian Lance Taylor <ian@zembu.com>
+
+ * elflink.h (elf_bfd_final_link): When counting relocations, don't
+ count those in sections we are not including in the link.
+
+Thu Sep 2 17:41:20 1999 Jeffrey A Law (law@cygnus.com)
+
+ * elflink.h (elf_link_add_object_symbols): Work around bogus SH_LINK
+ field in hpux11 shared libraries.
+
+1999-09-02 Nick Clifton <nickc@cygnus.com>
+
+ * elflink.h (elf_gc_record_vtentry): Fix memory leak.
+
+Wed Sep 1 13:34:29 1999 Jeffrey A Law (law@cygnus.com)
+
+ * elf-hppa.h (elf_hppa_add_symbol_hook): New function.
+ (elf_hppa_final_link, elf_hppa_relocate_section): Likewise.
+ (elf_hppa_final_link_relocate, elf_hppa_relocate_insn): Likewise.
+
+1999-08-31 Alexandre Petit-Bianco <apbianco@cygnus.com>
+
+ * elflink.h (record_link_assignment): When possible, keep the
+ original type of the symbol.
+
+Mon Aug 30 15:26:48 1999 Jeffrey A Law (law@cygnus.com)
+
+ * elf-hppa.h (_bfd_elf_hppa_gen_reloc_type): Allow both
+ R_PARISC_DIR32 and R_PARISC_DIR64 regardless of how the
+ tools were configured.
+ * elf32-hppa.h (_bfd_elf32_hppa_gen_reloc_type): Declare.
+
+1999-08-26 Mark Mitchell <mark@codesourcery.com>
+
+ * elf32-mips.c (_bfd_mips_elf_check_relocs): Don't allocate local
+ GOT entries for GOT16 relocations; they're not required.
+
+1999-08-24 Nick Clifton <nickc@cygnus.com>
+
+ From a patch submitted by Roland McGrath <roland@baalperazim.frob.com>
+
+ * config.bfd (arm-*-netbsd*): New target.
+ * configure.in (armnetbsd_vec): New target vector.
+ * configure: Regenerate
+ * targets.c (bfd_target_vector): Add &armnetbsd_vec.
+
+ * Makefile.am (BFD32_BACKENDS): Add armnetbsd.lo.
+ (ALL_MACHINES_CFILES): Add armnetbsd.c.
+ (armnetbsd.lo): New rule with deps.
+ * Makefile.in: Regenerate.
+
+ * armnetbsd.c: New file: Definitions specific to arm-netbsd
+ target.
+
+Tue Aug 24 00:25:58 1999 Jeffrey A Law (law@cygnus.com)
+
+ * som.c (som_slurp_symbol_table): Fix typo in comment.
+
+Fri Aug 20 17:01:23 1999 Jeffrey A Law (law@cygnus.com)
+
+ * elf-hppa.h (elf_hppa_fake_sections): Compute section indices
+ here instead of using elf_section_data...
+
+1999-08-19 Nick Clifton <nickc@cygnus.com>
+
+ * coff-mcore.c (mcore_emit_base_file_entry): New function: Emit
+ relocations into the base file.
+ (coff_mcore_relocate_section): Call mcore_emit_base_file_entry if
+ we are building a base file.
+
+1999-08-19 Nick Clifton <nickc@cygnus.com>
+
+ * elf32-arm.h (arm_add_to_rel): New function. Add a value to
+ a REL style reloc.
+ (elf32_arm_relocate_section): Use arm_add_to_rel to increment
+ REL relocs when performing a partial relocation.
+
+1999-08-18 Donn Terry <donn@interix.com>
+
+ * cofflink.c: Move definitions of N_TMASK, et. al., out of
+ _bfd_coff_link_input_bfd into top level.
+
+ * coff-i386.c (coff_i386_reloc): Handle R_IMAGEBASE.
+ (RTYPE2HOWTO): Return NULL if reloc type is out of range.
+ (coff_i386_rtype_to_howto): Likewise.
+ * coffcode.h (coff_slurp_symbol_table): Change a -2 to N_DEBUG.
+ Completely ignore symbols which are all zero.
+ (dummy_reloc16_estimate): Add return 0.
+ * cofflink.c (_bfd_coff_link_input_bfd): Rename inner scope
+ variable copy to name_copy to avoid shadowing outer scope
+ variable.
+ * libcoff-in.h (coff_data_type): Change raw_syment_count field
+ from unsigned int to unsigned long. Add timestamp field.
+ * libcoff.h: Rebuild.
+
+1999-08-17 H.J. Lu <hjl@gnu.org>
+
+ * elf32-hppa.c (bfd_elf32_bfd_is_local_label_name): Fix typo in
+ macro definition.
+
+1999-08-17 Ian Lance Taylor <ian@zembu.com>
+
+ * elf32-mips.c (_bfd_mips_elf_add_symbol_hook): Set BSF_DYNAMIC
+ for special section symbols.
+ * elflink.h (elf_merge_symbol): If we have no old BFD, check
+ BSF_DYNAMIC on the section symbol to see whether the old BFD is
+ dynamic.
+
+1999-08-15 Mark Mitchell <mark@codesourcery.com>
+
+ * elf32-mips.c (mips_elf_calculate_relocation): Fix unfortunate
+ coincidence of variable names between old and new code.
+
+1999-08-12 Nick Clifton <nickc@cygnus.com>
+
+ * elf32-arm.h (elf32_arm_to_thumb_stub): Make 'offset' parameter
+ into a bfd_vma and 'addend' parameter a 'bfd_signed_vma'.
+ (elf32_thumb_to_arm_stub): Make 'offset' parameter into a bfd_vma
+ and 'addend' parameter a 'bfd_signed_vma'.
+ (elf32_arm_final_link_relocate): Do not involve stubs in
+ R_ARM_THM_PC22 relocs relative to section symbols, they are long
+ jumps, not function calls.
+
+1999-08-11 Robin Farine <advanc@dial.eunet.ch>
+
+ * elf32-arm.h (elf32_arm_final_link_relocate): Check for overflow
+ in R_ARM_PC24 relocs.
+
+Tue Aug 10 12:48:09 1999 Jeffrey A Law (law@cygnus.com)
+
+ * elf-hppa.h (elf_hppa_fake_sections): New function.
+ * elf32-hppa.c (elf_backend_fake_sections): Define.
+
+ * elf-hppa.h (elf_hppa_final_write_processing): Update for
+ recent changes to the arch_info structure.
+
+ * elf-hppa.h (_bfd_elf_hppa_gen_reloc_type): Handle
+ R_HPPA_SEGBASE and R_HPPA_SEGREL32.
+ * cpu-hppa.c (bfd_hppa20w_arch): New entry in architecture info
+ list.
+
+Tue Aug 10 00:34:29 1999 Mark P. Mitchell <mark@codesourcery.com>
+ Ralf Baechle <ralf@uni-koblenz.de>
+
+ * elf32-mips.c (_bfd_mips_elf_size_dynamic_sections): Always
+ output DT_MIPS_GOTSYM.
+ (_bfd_mips_elf_finish_dynamic_sections): Use the same value as
+ DT_MIPS_SYMTABNO if there are no global GOT symbols.
+
+Tue Aug 10 00:21:08 1999 Mark P. Mitchell <mark@codesourcery.com>
+
+ * elf32-mips.c (mips_elf_create_dynamic_relocation): Change
+ prototype. Handle local symbols. Add commentary.
+ (mips_elf_calculate_relocation): Adjust accordingly.
+ (_bfd_mips_elf_check_relocs): Handle local symbols in R_MIPS_32
+ relocations.
+
+ * elflink.h (elf_bfd_final_link): Tweak last change.
+
+1999-08-09 Mark Mitchell <mark@codesourcery.com>
+
+ * elflink.h (elf_link_size_reloc_section): Use the counts in the
+ elf-section data to allocate just the right amount of relocation
+ space. Don't allocate the hash space twice.
+ (elf_bfd_final_link): Calculate the amount of space to allocate in
+ each relocation section.
+
+Mon Aug 9 17:37:30 1999 Jeffrey A Law (law@cygnus.com)
+
+ * elf-hppa.h (_bfd_elf_hppa_gen_reloc_type, case 32): When in
+ 64bit mode, generate a section relative relocation for a 32bit
+ wide relocation.
+ (elf_hppa_is_local_label_name): New function.
+ * elf32-hppa.c (elf_hppa_is_local_label_name): Deleted. To be
+ shared between 32bit and 64bit port.
+
+1999-08-09 Mark Mitchell <mark@codesourcery.com>
+
+ * elf32-mips.c (elf_mips_howto_table): Fix src_mask for
+ R_MIPS_GOT16 and R_MIPS_CALL16.
+ (mips_elf_got16_entry): Use mips_elf_high to calculate the value
+ to use when looking for a preexisting GOT entry.
+
+1999-08-09 Jakub Jelinek <jj@ultra.linux.cz>
+
+ * elf64-sparc.c (sparc64_elf_relocate_section): Back out part of
+ the Sep. 4th, 1998 change. glibc 2.0.x dynamic linker had bug,
+ not binutils.
+ * elf32-sparc.c (elf32_sparc_relocate_section): Likewise.
+
+1999-08-09 Geoff Keating <geoffk@cygnus.com>
+
+ * elflink.h (elf_link_output_extsym): Don't output a weak
+ reference to an undefined symbol just because it was defined weak
+ in a shared object.
+
+1999-08-09 Eli Zaretskii <eliz@is.elta.co.il>
+
+ * coffgen.c (coff_find_nearest_line): When looking for file, use
+ last best match rather than first. If address is beyond last line
+ number record, don't return the last line as the correct value.
+
+1999-08-08 Ian Lance Taylor <ian@zembu.com>
+
+ * section.c (SEC_SMALL_DATA): Rename from SEC_SHORT.
+ * bfd-in2.h: Rebuild.
+
+1999-08-08 Mark Elbrecht <snowball3@bigfoot.com>
+
+ * libcoff-in.h (struct coff_section_alignment_entry): Define.
+ * coffcode.h (coff_set_custom_section_alignment): New static
+ function.
+ (coff_section_alignment_table): New static array.
+ (coff_new_section_hook): Use coff_set_customer_section_alignment.
+ * coff-go32.c (COFF_SECTION_ALIGNMENT_ENTRIES): Define.
+ * coff-stgo32.c (COFF_SECTION_ALIGNMENT_ENTRIES): Define.
+ * libcoff.h: Rebuild.
+
+1999-08-08 Ian Lance Taylor <ian@zembu.com>
+
+ * Makefile.am: Rename .dep* files to DEP*. Change DEP variable to
+ MKDEP.
+ * Makefile.in: Rebuild.
+
+1999-08-08 Mumit Khan <khan@xraylith.wisc.edu>
+
+ * section.c (SEC_SHARED): Define.
+ * coffcode.h (sec_to_styp_flags): Handle SEC_SHARED.
+ (styp_to_sec_flags): Likewise.
+ * peicode.h (coff_swap_scnhdr_out): Likewise.
+ * bfd-in2.h: Rebuild.
+
+1999-08-08 Ian Lance Taylor <ian@zembu.com>
+
+ * coffcode.h (coff_classify_symbol): Comment out part of
+ 1999-08-05 change which breaks cygwin DLLs.
+
+ * acinclude.m4 (BFD_BINARY_FOPEN): Change -windows to -windows*.
+ * aclocal.m4, configure: Rebuild.
+
+1999-08-06 Ian Lance Taylor <ian@zembu.com>
+
+ * section.c (global_syms): Only initialize union field if
+ __STDC__.
+
+1999-08-04 Mark Mitchell <mark@codesourcery.com>
+
+ * elf32-mips.c (mips_elf_got16_entry): Don't multiply GOT index by
+ the size of a GOT entry here.
+ (mips_elf_calculate_relocation): Don't create a local GOT entry
+ for the symbol in a GOT16 relocation; just for it's high-order bit
+ (_bfd_mips_elf_relocate_section): Fix thinko.
+
+1999-08-05 Ian Lance Taylor <ian@zembu.com>
+
+ Based on patches from Donn Terry <donn@interix.com>:
+ * coffcode.h (enum coff_symbol_classification): Define.
+ (bfd_coff_backend_data): Rename _bfd_coff_sym_is_global to
+ _bfd_coff_classify_symbol. Change return type.
+ (bfd_coff_classify_symbol): Rename from bfd_coff_sym_is_global.
+ (coff_slurp_symbol_table): Use coff_classify_symbol.
+ (coff_classify_symbol): New static function.
+ (coff_sym_is_global): Never define.
+ (bfd_coff_std_swap_table): Initialize with coff_classify_symbol.
+ * cofflink.c (coff_link_check_ar_symbols): Use
+ bfd_coff_classify_symbol rather than bfd_coff_sym_is_global.
+ (coff_link_add_symbols): Likewise.
+ (_bfd_coff_link_input_bfd): Likewise.
+ * coff-sh.c (bfd_coff_small_swap_table): Initialize with
+ coff_classify_symbol.
+ * libcoff.h: Rebuild.
+
+Wed Aug 4 18:08:07 1999 Jeffrey A Law (law@cygnus.com)
+
+ * libhppa.h (R_HPPA_LTPSEL, R_HPPA_RTPSEL): New field selectors
+ (e_ltpsel, e_rtpsel): Similarly.
+
+ * elf-hppa.h (_bfd_elf_hppa_gen_reloc_type): Handle 21bit e_ltpsel
+ and 14bit ertpsel. Handle 64bit psel.
+
+1999-08-04 Mark Mitchell <mark@codesourcery.com>
+
+ * elf32-mips.c (_bfd_mips_elf_relocate_section): Tweak HI16/LO16
+ handling for REL relocations. And only left-shift R_MIPS26
+ relocation addends where necessary.
+
+1999-08-03 Mark Mitchell <mark@codesourcery.com>
+
+ * elf32-mips.c (mips_elf_next_lo16_addend): Rename to ...
+ (mips_elf_next_lo16_relocation): Don't compute the addend here.
+ Just return the relocation found.
+ (mips_elf_relocate_section): Pull the LO16 addend out of the
+ section itself when using REL relocations.
+
+ * elf32-mips.c (mips_elf_calculate_relocation): Restore
+ _DYNAMIC_LINK handling and handling of undefined symbols in shared
+ libraries.
+
+1999-08-03 Ian Lance Taylor <ian@zembu.com>
+
+ * elf32-ppc.c (ppc_elf_relocate_section): Don't use the relocation
+ value of a symbol in a SEC_DEBUGGING section. Warn when doing a
+ relocation against a symbol in an input section with no output
+ section. From Daniel Jacobowitz <drow@false.org>.
+
+ * coff-stgo32.c (go32_stubbed_coff_object_p): Remove; not used.
+
+ * acinclude.m4 (BFD_CC_FOR_BUILD): Change to use conftest, and to
+ look for generated file correctly.
+ * aclocal.m4, configure: Rebuild.
+
+1999-08-02 Mark Mitchell <mark@codesourcery.com>
+
+ * elf32-mips.c (_bfd_mips_elf_relocate_section): Handle R_MIPS_26
+ and R_MIPS16_26 relocations correctly when relocating.
+ (_bfd_mips_elf_check_relocs): Don't assume that R_MIPS_CALL_HI16
+ and R_MIPS_CALL_LO16 are for global symbols.
+
+1999-08-02 Jakub Jelinek <jj@ultra.linux.cz>
+
+ * elflink.h (elf_bfd_final_link): Copy the whole isym, not just
+ some fields.
+ * elf64-sparc.c (sparc64_elf_output_arch_syms): Declare used
+ variables and initialize them.
+
+1999-08-01 Mark Mitchell <mark@codesourcery.com>
+
+ * elf32-mips.c (_bfd_mips_elf_final_link): Handle the case where
+ there are no global symbols requiring GOT entries.
+ (_bfd_mips_elf_size_dynamic_sections): Likewise.
+ (_bfd_mips_elf_finish_dynamic_symbol): Likewise.
+ (_bfd_mips_elf_finish_dynamic_sections): Likewise.
+
+ * elf32-mips.c (mips_elf_calculate_relocation): Undefined weak
+ symbols are considered to have the value zero.
+ (_bfd_mips_elf_relocate_section): Don't try to perform a
+ relocation for an undefined symbol.
+ (_bfd_mips_elf_check_relocs): Allocate locate GOT space for local
+ GOT16 relocations.
+
+1999-07-30 Jakub Jelinek <jj@ultra.linux.cz>
+
+ * elf64-sparc.c (sparc64_elf_build_plt): Cosmetic change - ABI
+ wants ba,a,pt %xcc instead of %icc.
+ Emit correct .PLT0-(.PLTN+4) initial value into the pointer slots
+ of large PLT entries.
+ (sparc64_elf_plt_ptr_offset): Fix calculation.
+ (sparc64_elf_finish_dynamic_symbol): Negative value of R_SPARC_JMP_SLOT
+ addend should be relative to load address, not .plt section start.
+ (sparc64_elf_size_info): Sparc64 uses 32bit .hash entries.
+
+1999-07-30 Jakub Jelinek <jj@ultra.linux.cz>
+
+ * elf-bfd.h (struct elf_backend_data): Add
+ print_symbol_all and output_arch_syms backend methods.
+ * elfxx-target.h: Likewise.
+ * elf64-sparc.c (sparc64_elf_bfd_link_hash_table_create,
+ sparc64_elf_add_symbol_hook, sparc64_elf_output_arch_syms,
+ sparc64_elf_get_symbol_type, sparc64_elf_symbol_processing): New
+ functions.
+ (sparc64_elf_size_dynamic_sections): Leave space for STT_REGISTER
+ symbols in .dynsym, add their names into .dynstr. Put those symbols
+ into dynlocal.
+ (sparc64_elf_finish_dynamic_sections): Fix up DT_SPARC_REGISTER
+ pointers to STT_REGISTER symbols in dynsym section.
+ (sparc64_elf_print_symbol_all): New function.
+ * elf.c (bfd_elf_print_symbol): Allow special backend symbol
+ printing using the print_symbol_all hook.
+
+1999-07-30 Catherine Moore <clm@cygnus.com>
+
+ * elf32-arm.h (elf32_arm_check_relocs): Use r_offset for
+ R_ARM_GNU_VTENTRY.
+
+1999-07-29 Richard Henderson <rth@cygnus.com>
+
+ * elf32-mips.c (_bfd_mips_elf_final_link): Only re-sort dynsyms if
+ dynamic_sections_created.
+
+1999-07-29 Richard Henderson <rth@cygnus.com>
+
+ * elf32-mips.c (mips_info_to_howto_rel): Split out switch to ...
+ (mips_rtype_to_howto): ... new function.
+ (_bfd_mips_elf_relocate_section): Use it.
+
+1999-07-28 Mark Mitchell <mark@codesourcery.com>
+
+ * elf32-mips.c (_bfd_mips_elf_relocate_section): Fix typo.
+
+1999-07-27 Nick Clifton <nickc@cygnus.com>
+
+ Patch generated by Bernd Schmidt. <bernds@cygnus.co.uk>
+
+ * coff-arm.c (coff_arm_is_local_label_name): Change to strip
+ out only symbols that start with LOCAL_LABEL_PREFIX followed by 'L'.
+
+1999-07-23 Donn Terry <donn@interix.com>
+
+ * libcoff-in.h (coff_link_hash_entry): Add coff_link_hash_flags
+ field, and define COFF_LINK_HASH_PE_SECTION_SYMBOL.
+ * cofflink.c (coff_link_add_symbols): If PE, handle section
+ symbols specially.
+ * libcoff.h: Rebuild.
+
+ * config.bfd (i[3456]86-*-interix*): New target.
+
+1999-07-21 Mark Elbrecht <snowball3@bigfoot.com>
+
+ * coffcode.h (styp_to_sec_flags): If COFF_LONG_SECTION_NAMES and
+ COFF_SUPPORT_GNU_LINKONCE, mark sections whose names begin with
+ .gnu.linkonce with SEC_LINKONCE and SEC_LINK_DUPLICATES_DISCARD.
+ * coff-go32.c: (COFF_LONG_SECTION_NAMES): Define.
+ (COFF_SUPPORT_GNU_LINKONCE): Define.
+ * coff-stgo32.c: (COFF_LONG_SECTION_NAMES): Define.
+ (COFF_SUPPORT_GNU_LINKONCE): Define.
+
+1999-07-21 Ian Lance Taylor <ian@zembu.com>
+
+ From Mark Elbrecht:
+ * makefile.dos: Remove; obsolete.
+ * configure.bat: Remove; obsolete.
+
+1999-07-21 H.J. Lu <hjl@gnu.org>
+
+ * config.bfd (i[3456]86-*-vxworks*): Add targ_underscore=yes.
+
+1999-07-21 Philippe De Muyter <phdm@macqel.be>
+
+ * cofflink.c (_bfd_coff_generic_relocate_section): Issue an error
+ message and fail if a symbol index is out of range.
+
+1999-07-21 Ian Lance Taylor <ian@zembu.com>
+
+ * elf32-mips.c (mips_elf_calculate_relocation): Get the GP value
+ when looking at a R_MIPS_GOT16 relocation.
+
+1999-07-20 Nick Clifton <nickc@cygnus.com>
+
+ * coff-m88k.c: Use CREATE_BIG_COFF_TARGET_VEC.
+
+Mon Jul 19 14:03:44 1999 Mark P. Mitchell <mark@codesourcery.com>
+
+ * elf32-mips.c (_bfd_mips_elf_final_link): Restore setting of GP
+ removed in previous change.
+ (_bfd_mips_elf_relocate_section): Adjust GP relative relocations
+ in relocateable output.
+
+1999-07-19 Ian Lance Taylor <ian@zembu.com>
+
+ * coff-m88k.c (m88kbcs_vec): Initialize new field of bfd_target
+ structure.
+
+ * elflink.h (elf_merge_symbol): Do merge symbols from the same BFD
+ if they appear to be specially created by the linker.
+
+1999-07-19 Nick Clifton <nickc@cygnus.com>
+
+ * targets.c (alternative_target): New field in bfd_target
+ structure.
+ (bfd_search_for_target): New function: Find a target that
+ satisifies a search function.
+ * bfd-in2.h: Regenerate.
+
+ * elfxx-target.h: Initialise the alternative_target field of
+ the bfd_target structures to point to the other target (if
+ defined).
+ * nlm-target.h: Initialise the alternative_target field of
+ the bfd_target structures to point to the other target (if
+ defined).
+
+ * coffcode.h (CREATE_BIG_COFF_TARGET_VEC): New macro.
+ (CREATE_LITTLE_COFF_TARGET_VEC): New macro.
+
+ * aix386-core.c: Initialise new field of bfd_target structure.
+ * aout-adobe.c: Initialise new field of bfd_target structure.
+ * aout-arm.c: Initialise new field of bfd_target structure.
+ * aout-target.h: Initialise new field of bfd_target structure.
+ * aout-tic30.c: Initialise new field of bfd_target structure.
+ * binary.c: Initialise new field of bfd_target structure.
+ * bout.c: Initialise new field of bfd_target structure.
+ * cisco-core.c: Initialise new field of bfd_target structure.
+ * coff-a29k.c: Use CREATE_BIG_COFF_TARGET_VEC.
+ * coff-alpha.c: Initialise new field of bfd_target structure.
+ * coff-apollo.c: Use CREATE_BIG_COFF_TARGET_VEC.
+ * coff-arm.c: Use CREATE_{BIG|LITTLE}_COFF_TARGET_VEC.
+ * coff-h8300.c: Use CREATE_BIG_COFF_TARGET_VEC.
+ * coff-h8500.c: Use CREATE_BIG_COFF_TARGET_VEC.
+ * coff-i386.c: Initialise new field of bfd_target structure.
+ * coff-i860.c: Initialise new field of bfd_target structure.
+ * coff-i960.c: Use CREATE_LITTLE_COFF_TARGET_VEC.
+ * coff-m68k.c: Use CREATE_BIG_COFF_TARGET_VEC.
+ * coff-mcore.c: Use CREATE_{BIG|LITTLE}_COFF_TARGET_VEC.
+ * coff-mips.c: Initialise new field of bfd_target structure.
+ * coff-ppc.c: Initialise new field of bfd_target structure.
+ * coff-rs6000.c: Initialise new field of bfd_target structure.
+ * coff-sh.c: Use CREATE_{BIG|LITTLE}_COFF_TARGET_VEC.
+ * coff-sparc.c: Use CREATE_BIG_COFF_TARGET_VEC.
+ * coff-tic30.c: Initialise new field of bfd_target structure.
+ * coff-tic80.c: Use CREATE_LITTLE_COFF_TARGET_VEC.
+ * coff-w65.c: Use CREATE_LITTLE_COFF_TARGET_VEC.
+ * coff-we32k.c: Use CREATE_BIG_COFF_TARGET_VEC.
+ * coff-z8k.c: Use CREATE_BIG_COFF_TARGET_VEC.
+ * hppabsd-core.c: Initialise new field of bfd_target structure.
+ * hpux-core.c: Initialise new field of bfd_target structure.
+ * i386msdos.c: Initialise new field of bfd_target structure.
+ * i386os9k.c: Initialise new field of bfd_target structure.
+ * ieee.c: Initialise new field of bfd_target structure.
+ * ihex.c: Initialise new field of bfd_target structure.
+ * irix-core.c: Initialise new field of bfd_target structure.
+ * mipsbsd.c: Initialise new field of bfd_target structure.
+ * netbsd-core.c: Initialise new field of bfd_target structure.
+ * oasys.c: Initialise new field of bfd_target structure.
+ * osf-core.c: Initialise new field of bfd_target structure.
+ * ppcboot.c: Initialise new field of bfd_target structure.
+ * ptrace-core.c: Initialise new field of bfd_target structure.
+ * sco5-core.c: Initialise new field of bfd_target structure.
+ * som.c: Initialise new field of bfd_target structure.
+ * srec.c: Initialise new field of bfd_target structure.
+ * tekhex.c: Initialise new field of bfd_target structure.
+ * trad-core.c: Initialise new field of bfd_target structure.
+ * versados.c: Initialise new field of bfd_target structure.
+ * vms.c: Initialise new field of bfd_target structure.
+
+1999-07-19 Andreas Schwab <schwab@suse.de>
+
+ * elflink.h (elf_bfd_final_link): Remove unused variables rel_hash
+ and rel_hdr.
+
+Sat Jul 17 02:28:28 1999 Mark P. Mitchell <mark@codesourcery.com>
+
+ * elflink.h (elf_link_adjust_relocs): New function.
+ (elf_bfd_final_link): Use it.
+ (elf_link_input_bfd): Deal with the fact that there can be
+ two relocation sections for a single section.
+ (elf_reloc_link_order): Likewise.
+
+ * elf32-mips.c (_bfd_mips_elf_final_link): Don't set GP for
+ a relocateable object.
+ (_bfd_mips_elf_relocate_section): Handle relocateable links.
+
+1999-07-16 Jakub Jelinek <jj@ultra.linux.cz>
+
+ * elf64-sparc.c (sparc64_elf_info_to_howto): Use ELF64_R_TYPE_ID.
+ (sparc64_elf_get_reloc_upper_bound,
+ sparc64_elf_get_dynamic_reloc_upper_bound,
+ sparc64_elf_slurp_one_reloc_table, sparc64_elf_slurp_reloc_table,
+ sparc64_elf_canonicalize_dynamic_reloc, sparc64_elf_write_relocs):
+ New functions.
+ (sparc64_elf_check_relocs, sparc64_elf_relocate_section): Use
+ ELF64_R_TYPE_ID/DATA where appropriate.
+
+1999-07-16 Jakub Jelinek <jj@ultra.linux.cz>
+
+ * elf64-sparc.c (sparc64_elf_size_dynamic_sections): Remove
+ DT_SPARC_PLTFMT.
+
+1999-07-16 Ian Lance Taylor <ian@zembu.com>
+
+ * elf32-mips.c (mips_elf_local_relocation_p): New static
+ function.
+ (mips_elf_next_lo16_addend): Call bfd_set_error on failure.
+ (mips_elf_calculate_relocation): Use mips_elf_local_relocation_p.
+ Always set *require_jalxp.
+ (mips_elf_stub_section_p): Mark abfd parameter as unused.
+ (_bfd_mips_elf_relocate_section): Only look for LO16 following
+ GOT16 if the GOT16 is against a local symbol. Don't return false
+ for an undefined symbol. If there is an overflow, assert that we
+ have a name.
+
+1999-07-16 Andreas Schwab <schwab@suse.de>
+
+ * elflink.h (elf_link_record_local_dynamic_symbol): Remove unused
+ variables `link' and `elfsec'.
+ (elf_bfd_final_link): Remove unused variable `os'.
+
+Thu Jul 15 17:55:31 1999 Mark P. Mitchell <mark@codesourcery.com>
+
+ * elf32-mips.c (_bfd_mips_elf_modify_segment_map): Don't require
+ a PT_PHDR program headers.
+ (_bfd_mips_elf_final_link): Don't assume there are going to be
+ section symbols when we're not building a shared object.
+ (_bfd_mips_elf_check_relocs): Make sure we have a GOT when
+ we need one.
+
+1999-07-15 J.T. Conklin <jtc@redback.com>
+
+ * config.bfd (i[3456]86-*-vxworks*): New target.
+
+1999-07-15 Mark Mitchell <mark@codesourcery.com>
+
+ * elf32-mips.c (mips_elf_stub_section_p): New function.
+ (mips_elf_calculate_relocation): Handle MIPS16 stub functions.
+ (mips_elf_relocate_section): Adjust calling sequence for
+ mips_elf_calculate_relocation and mips_elf_perform_relocation.
+ (mips_elf_perform_relocation): Turn `jal' into `jalx' where
+ required.
+
+1999-07-15 Ian Lance Taylor <ian@zembu.com>
+
+ * configure.in: Bump version number to 2.9.5.
+ * configure: Rebuild.
+
+Thu Jul 15 02:56:15 1999 Jeffrey A Law (law@cygnus.com)
+
+ * elf-hppa.h (_bfd_elf_hppa_gen_reloc_type, case R_HPPA): Handle
+ 64bit format.
+ (_bfd_elf_hppa_gen_reloc_type, case R_GOTOFF): Use base reloc type
+ to derive final type instead of hardwiring a selection.
+
+1999-07-14 Mark Mitchell <mark@codesourcery.com>
+
+ * elf32-mips.c (mips_elf_obtain_contents): Swap 16-bit halves of
+ things relocated by R_MIPS16_GPREL.
+ (mips_elf_perform_relocation): Likewise.
+
+Wed Jul 14 15:23:19 1999 Jim Wilson <wilson@cygnus.com>
+
+ * elfxx-target.h (elfNN_bed): Add elf_backend_want_dynbss.
+
+1999-07-14 Richard Henderson <rth@cygnus.com>
+
+ * elf32-mips.c (struct mips_got_info): Add global_gotno.
+ (_bfd_mips_elf_size_dynamic_sections): Set it.
+ (_bfd_mips_elf_final_link): Re-sort; verify the got did not grow.
+ (mips_elf_sort_hash_table): Set max_non_got_dynindex based off
+ new argument max_local.
+
+1999-07-14 Mark Mitchell <mark@codesourcery.com>
+
+ * elf32-mips.c (mips_elf_obtain_contents): Swap the 16-bit
+ subwords when handling an R_MIPS16_26 relocation.
+ (mips_elf_perform_relocation): Don't be paranoid abour right-shift
+ semantics.
+
+ * elf32-mips.c (elf_mips16_gprel_howto): Adjust src_mask and
+ dst_mask to match reality.
+ (_bfd_mips_elf_calculate_relocation): Handle R_MIPS16_GPREL.
+ (mips_elf_obtain_contents): Use bfd_get.
+ (mips_elf_perform_relocation): Handle R_MIPS16_GPREL.
+ (mips_elf_relocate_section): Likewise.
+
+1999-07-13 Mark Mitchell <mark@codesourcery.com>
+
+ * elf32-mips.c (mips_elf_calculate_relocation): Handle R_MIPS16_26.
+ (mips_elf_relocate_section): Adjust calling sequence for
+ mips_elf_perform_relocation.
+ (mips_elf_perform_relocation): Take additional argument. Handle
+ R_MIPS16_26. Use bfd_put for convenience.
+
+1999-07-13 Richard Henderson <rth@cygnus.com>
+
+ * elf.c (assign_file_positions_for_segments): Thinko last change.
+ Always overwrite p_flags.
+
+1999-07-13 Richard Henderson <rth@cygnus.com>
+
+ * elf-bfd.h (struct elf_backend_data): Add want_dynbss.
+ * elflink.c (_bfd_elf_create_dynamic_sections): Only create
+ .dynbss and .rel[a].bss if want_dynbss.
+ * elfxx-target.h (elf_backend_want_dynbss): Provide default.
+
+1999-07-13 Richard Henderson <rth@cygnus.com>
+
+ * elf.c (assign_file_positions_for_segments): Don't overwrite p_flags.
+
+1999-07-13 Richard Henderson <rth@cygnus.com>
+
+ * elf-bfd.h (struct elf_link_local_dynamic_entry): New.
+ (struct elf_link_hash_table): Add dynlocal.
+ (_bfd_elf_link_lookup_local_dynindx): Prototype.
+ (_bfd_elf_link_adjust_dynindx): Delete.
+ (_bfd_elf_link_renumber_dynsyms): Prototype.
+ (_bfd_elf,link_record_local_dynamic_symbol): Prototype.
+ * elfcode.h (elf_link_record_local_dynamic_symbol): New alias.
+ * elflink.c (_bfd_elf_link_adjust_dynindx): Delete.
+ (_bfd_elf_link_lookup_local_dynindx): New function.
+ (elf_link_renumber_hash_table_dynsyms): New function.
+ (_bfd_elf_link_renumber_dynsyms): New function.
+ * elflink.h (elf_link_record_local_dynamic_symbol): New function.
+ (struct elf_assign_sym_version_info): Delete removed_dynamic.
+ (bfd_elf,size_dynamic_sections): Use _bfd_strip_section_from_output
+ instead of elf_link_remove_section_and_adjust_dynindices.
+ Remove removed_dynamic code. Use _bfd_elf_link_renumber_dynsyms.
+ (elf_link_assign_sym_version): Remove removed_dynamic code.
+ (elf_link_renumber_dynsyms): Delete.
+ (elf_bfd_final_link): Install section and local symbols into .dynsym.
+
+ * elf32-m68k.c (elf_m68k_adjust_dynindx): Delete.
+ (elf_m68k_size_dynamic_sections): Don't set section dynindicies.
+ (elf_m68k_finish_dynamic_sections): Don't write section dynsyms.
+ * elf32-mips.c: Similarly.
+ * elf32-ppc.c: Similarly.
+ * elf32-sparc.c: Similarly.
+ * elf64-alpha.c: Similarly.
+ * elf64-sparc.c: Similarly.
+
+1999-07-13 Mark Mitchell <mark@codesourcery.com>
+
+ * elf32-mips.c (mips_elf_calculate_relocation): Do not complain
+ when _gp_disp is undefined. Do not check R_MIPS_LO16 for overflow
+ when the relocation is against _gp_disp.
+
+1999-07-12 Mark Mitchell <mark@codesourcery.com>
+
+ * dwarf2.c (read_attribute): Support DW_FORM_ref8.
+ * elf32-mips.c (mips_elf_link_hash_entry): Change mips_32_relocs
+ to possibly_dynamic_relocs. Adjust usage throughout code.
+ (elf_mips_howto_table): Handle R_MIPS_64 correctly.
+ (elf_mips_ctor64_howto): Likewise.
+ (mips_elf_calculate_relocation): Handle R_MIPS_64 like R_MIPS_32.
+ Adjust indentation.
+ (mips_elf_relocate_section): Handle R_MIPS_64 in 32-bit mode.
+ (_bfd_mips_elf_check_relocs): Handle R_MIPS_64 like R_MIPS_32.
+ Use MIPS_ELF_GOT_SIZE to calculate the size of GOT entries.
+ * elf64-mips.c (elf_backend_may_use_rel_p): Define.
+
+1999-07-12 Ian Lance Taylor <ian@zembu.com>
+
+ * Makefile.am: Rebuild dependencies.
+ * Makefile.in: Rebuild.
+
+ * bfd-in.h: Remove tests of COFF_IMAGE_WITH_PE.
+ * bfd-in2.h: Rebuild.
+
+ * Many files: Changes to avoid gcc warnings: Add ATTRIBUTE_UNUSED
+ as appropriate. Use EMPTY_HOWTO as appropriate. Fill in
+ structure initializations. Add casts.
+ * reloc.c (EMPTY_HOWTO): Define.
+ * bfd-in2.h: Rebuild.
+ * coff-h8300.c (h8300_reloc16_extra_cases): Remove useless
+ comparisons against 0.
+ * elf32-sparc.c (elf32_sparc_merge_private_bfd_data): Change
+ previous_ibfd_e_flags to unsigned long.
+ * vms.h (struct vms_private_data_struct): Change section_count to
+ unsigned.
+ * vms-gsd.c (_bfd_vms_slurp_gsd): Change psect_idx to unsigned.
+ (_bfd_vms_write_gsd): Change symnum to unsigned.
+ * vms-hdr.c (_bfd_vms_write_hdr): Change symnum to unsigned.
+ * vms-tir.c (etir_sta): Change psect to unsigned.
+ (alloc_section): Change idx to unsigned.
+ (tir_sta, tir_ctl): Change psect to unsigned.
+ (_bfd_vms_write_tir): Change len and before to bfd_size_type.
+ * vms.c (priv_section_count): Change to unsigned.
+
+1999-07-12 Andreas Schwab <schwab@suse.de>
+
+ * elf32-m68k.c: Add some ATTRIBUTE_UNUSED.
+ * m68klinux.c: Likewise.
+
+1999-07-12 Ian Lance Taylor <ian@zembu.com>
+
+ * Many files: Changes to avoid gcc warnings: Remove unused local
+ variables. Add default case to enum switches.
+ * coff-arm.c (bfd_arm_allocate_interworking_sections): Only
+ compile if not COFF_IMAGE_WITH_PE.
+ (record_arm_to_thumb_glue, record_thumb_to_arm_glue): Likewise.
+ (bfd_arm_get_bfd_for_interworking): Likewise.
+ (bfd_arm_process_before_allocation): Likewise.
+ * epoc-pei-arm.c: Don't rename bfd_arm functions.
+ * pei-arm.c: Likewise.
+ * elf32-mips.c (mips_elf_link_hash_table_create): Don't declare.
+ (MIPS_ELF_ADD_DYNAMIC_ENTRY): Correct last change.
+ (mips_elf_got16_entry): Put parens around & in body of ==.
+ (mips_elf_calculate_relocation): Correct test for empty string.
+ * vms-gsd.c: Use _bfd_error_handler rather than fprintf to
+ stderr.
+ * vms-misc.c (_bfd_vms_length_hash_symbol): Correct sprintf
+ format.
+
+1999-07-11 Ian Lance Taylor <ian@zembu.com>
+
+ * Many files: Changes to avoid gcc warnings: Add ATTRIBUTE_UNUSED
+ as appropriate. Fill in structure initializations. Add variable
+ initializations. Add casts.
+ * dwarf1.c (parse_line_table): Change eachLine to unsigned long.
+ (dwarf1_unit_find_nearest_line): Change i to unsigned long.
+
+ * elf.c (bfd_elf_hash): Change parameter from unsigned char * to
+ char *.
+ * elf-bfd.h (bfd_elf_hash): Update declaration.
+ * elflink.h (NAME(bfd_elf,size_dynamic_sections)): Remove casts
+ when calling bfd_elf_hash.
+
+1999-07-11 Mark Mitchell <mark@codesourcery.com>
+
+ * libbfd.c (bfd_put_8): Make it of type `void'.
+ * bfd-in2.h: Regenerated.
+ * elf32-mips.c (MIPS_ELF_ADD_DYNAMIC_ENTRY): Conditionalize
+ for 32-bit hosts.
+ (_bfd_mips_elf_final_link): Likewise.
+
+ * elflink.h (elf_link_read_relocs_from_section): Be type-correct.
+
+Thu Jul 8 12:32:23 1999 John David Anglin <dave@hiauly1.hia.nrc.ca>
+
+ * config.bfd (hppa*-*-linux-gnu*): New target
+
+1999-07-07 Mark Mitchell <mark@codesourcery.com>
+
+ * elf-bfd.h (_bfd_mips_elf_section_from_shdr): Constify.
+ (_bfd_mips_elf_create_dynamic_sections): New function.
+ (_bfd_mips_elf_add_symbol_hook): Likewise.
+ (_bfd_mips_elf_adjust_dynamic_symbol): Likewise.
+ (_bfd_mips_elf_finish_dynamic_symbol): Likewise.
+ (_bfd_mips_elf_finish_dynamic_sections): Likewise.
+ (_bfd_mips_elf_gc_mark_hook): Likewise.
+ (_bfd_mips_elf_gc_sweep_hook): Likewise.
+ (_bfd_mips_elf_always_size_sections): Likewise.
+ (_bfd_mips_elf_size_dynamic_sections): Likewise.
+ (_bfd_mips_elf_check_relocs): Likewise.
+ (_bfd_mips_elf_link_hash_table_create): Likewise.
+ (_bfd_mips_elf_print_private_data): Likewise.
+ (_bfd_mips_elf_link_output_symbol_hook): Likewise.
+ (_bfd_mips_elf_final_link): Likewise.
+ (_bfd_mips_elf_additional_program_headers): Likewise.
+ (_bfd_mips_elf_modify_segment_map): Likewise.
+ (_bfd_mips_elf_relocate_section): Likewise.
+ * elf32-mips.c (mips_elf32_object_p): Move contents into
+ _bfd_mips_elf_object_p.
+ (mips_elf_additional_program_headers): Rename to
+ _bfd_mips_elf_additional_program_headers.
+ (mips_elf_modify_segment_map): Rename to
+ _bfd_mips_elf_modify_segment_map.
+ (elf_mips_abi_name): Change prototype.
+ (mips_elf32_section_from_shdr): Merge into
+ _bfd_mips_elf_section_from_shdr.
+ (mips_elf32_section_processing): Merge into
+ _bfd_mips_elf_section_processing.
+ (mips_elf_final_link): Rename to _bfd_mips_elf_final_link. Invoke
+ the right back-end ELF linker.
+ (mips_elf_relocate_section): Rename to
+ _bfd_mips_elf_relocate_section. Clean up. Adjust for 64-bit code.
+ (mips_elf_link_output_symbol_hook): Rename to
+ _bfd_mips_elf_link_output_symbol_hook.
+ (mips_elf_create_dynamic_section): Rename to
+ _bfd_mips_elf_create_dynamic_section.
+ (mips_elf_check_relocs): Rename to _bfd_mips_elf_check_relocs.
+ Adjust for 64-bit code. Use mips_elf_got_section.
+ (mips_elf_adjust_dynamic_symbol): Rename to
+ _bfd_mips_elf_adjust_dynamic_symbol. Use
+ mips_elf_allocate_dynamic_relocations.
+ (mips_elf_finish_dynamic_symbol): Rename to
+ _bfd_mips_elf_finish_dynamic_symbol. Use mips_elf_got_section.
+ Adjust for 64-bit code.
+ (mips_elf_finish_dynamic_sections): Rename to
+ _bfd_mips_elf_finish_dynamic_sections. Adjust for 64-bit code.
+ (mips_elf_always_size_sections): Rename to
+ _bfd_mips_elf_always_size_sections.
+ (mips_elf_add_symbol_hook): Rename to
+ _bfd_mips_elf_add_symbol_hook.
+ (mips_elf_next_lo16_addend): Constify.
+ (mips_elf_calculate_relocation): Likewise.
+ (mips_elf_obtain_contents): Likewise.
+ (mips_elf_perform_relocation): Likewise.
+ (mips_elf_create_dynamic_relocation): Likewise.
+ (mips_elf_allocate_dynamic_relocations): New function.
+ (MIPS_ELF_REL_DYN_SECTION_NAME): New macro.
+ (MIPS_ELF_REL_SIZE): Likewise.
+ (MIPS_ELF_DYN_SIZE): Likewise.
+ (MIPS_ELF_GOT_SIZE): Likewise.
+ (MIPS_ELF_SYM_SIZE): Likewise.
+ (MIPS_ELF_LOG_FILE_ALIGN): Likewise.
+ (MIPS_ELF_GET_WORD): Likewise.
+ (MIPS_ELF_PUT_WORD): Likewise.
+ (MIPS_ELF_ADD_DYNAMIC_ENTRY): Likewise.
+ (STUB_LW): Conditionalize for 64-bit value.
+ (elf_mips_howto_table): Add R_MIPS_HIGHER and R_MIPS_HIGHEST
+ entries.
+ (_bfd_mips_elf_merge_private_bfd_data): Merge e_ident[EI_CLASS].
+ Check it for inconsistency.
+ (_bfd_mips_elf_print_private_bfd_data): Print ABI=64 for 64-bit
+ ABI.
+ (_bfd_mips_elf_fake_sections): Remove duplicate handling of
+ .msym.
+ (mips_elf_global_got_index): Use MIPS_ELF_GOT_SIZE.
+ (mips_elf_got_offset_from_index): Use misp_elf_got_section.
+ (mips_elf_create_local_got_entry): Use MIPS_ELF_GOT_SIZE.
+ (mips_elf_local_got_index): Likewise.
+ (mips_elf_got_page): Likewise.
+ (mips_elf_got_info): Likewise.
+ (mips_elf_create_dynamic_relocation): Handle 32-bit/64-bit split.
+ (ELF_DYNAMIC_INTERPRETER): Handle 64-bit code.
+ (mips_elf_create_dynamic_sections): Use MIPS_ELF_LOG_FILE_ALIGN,
+ instead of constant `2'.
+ (mips_elf_create_got_section): Tidy. Use MIPS_ELF_GOT_SIZE.
+ (mips_elf_create_msym_section): Use MIPS_ELF_LOG_FILE_ALIGN.
+ (mips_elf_size_dynamic_sections): Use
+ MIPS_ELF_REL_DYN_SECTION_NAME, MIPS_ELF_GOT_SIZE,
+ MIPS_ELF_ADD_DYNAMIC_ENTRY. Remove #if 0'd code.
+ Adjust all releveant entries in elf backend table.
+ * elf64-mips.c (mips_elf64_section_from_shdr): Remove.
+ (mips_elf64_section_processing): Likewise.
+ Adjust elf backend entries to use _bfd_mips_elf variants now
+ publicly available.
+
+ * elflink.h (elf_link_create_dynamic_sections): Handle non-standard
+ hash-entry sizes.
+ (size_dynamic_sections): Likewise.
+ (elf_link_output_extsym): Likewise.
+ * elf.c: (elf_fake_sections): Likewise.
+ * libbfd.c (bfd_get): New macro.
+ (bfd_put): Likewise.
+ * bfd-in2.h: Regenerated.
+
+1999-07-07 Mark Mitchell <mark@codesourcery.com>
+
+ * elf-bfd.h (elf_size_info): Add hash_entry_size,
+ int_rels_per_ext_rel, swap_dyn_out, swap_reloc_in, swap_reloc_out,
+ wap_reloca_in, and swap_reloca_out.
+ * elflink.h (elf_link_read_relocs_from_section): Adjust to handle
+ multiple internal relocations per external relocation.
+ (link_read_relocs): Likewise.
+ (elf_bfd_final_link): Likewise.
+ (elf_link_input_bfd): Likewise.
+ (elf_gc_mark): Likewise.
+ (elf_gc_smash_unused_vtentry_relocs): Likewise.
+ * elfcode.h (elf_swap_dyn_out): Adjust type to match
+ elf_swap_dyn_in.
+ (size_info): Add entries for new fields.
+ * elf64-mips.c (mips_elf64_swap_reloc_out): Enable.
+ (mips_elf64_be_swap_reloc_in): New function.
+ (mips_elf64_be_swap_reloc_out): Likewise.
+ (mips_elf64_be_swap_reloca_in): Likewise.
+ (mips_elf64_be_swap_reloca_out): Likewise.
+ (mips_elf64_size_info): Add entries for new fields.
+
+1999-07-07 Ian Lance Taylor <ian@zembu.com>
+
+ * elflink.h (elf_bfd_final_link): Assert that section reloc_count
+ field equals the new rel_count field.
+ (elf_link_input_bfd): When doing a relocateable link, use the new
+ rel_count field rather than the reloc_count field.
+ (elf_reloc_link_order): Likewise.
+ (elf_finish_pointer_linker_section): Likewise.
+
+ Based on patch from H.J. Lu <hjl@gnu.org>:
+ * elflink.h (elf_merge_symbol): Permit a non-weak definition in a
+ shared library to override a weak definition in a regular object.
+
+Tue Jul 6 10:23:39 1999 Jeffrey A Law (law@cygnus.com)
+
+ * libhppa.h: Revert July 2, 1999 patch.
+
+ * elf-hppa.h (_bfd_elf_hppa_gen_reloc_type): T mode selectors
+ need to generate DLTIND relocations, not DLTREL relocations.
+
+1999-07-05 Nick Clifton <nickc@cygnus.com>
+
+ * coffcode.h (coff_set_arch_mach_hook): Recognise arm 5
+ architectures.
+ (coff_set_flags): Recognise arm 5 architectures.
+
+ * cpu-arm.c: Add support for strongarm and arm9 cpus.
+ Add support for armv5 architecture.
+
+ * archures.c: Add bfd_mach_arm_5 and bfd_mach_arm_5T.
+
+ * reloc.c: Add new, assembler only, ARM reloc:
+ BFD_RELOC_ARM_ADRL_IMMEDIATE.
+
+ * bfd-in2.h: Regenerate.
+
+1999-07-02 Mark Mitchell <mark@codesourcery.com>
+
+ * dwarf2.c (parse_comp_unit): Add ABBREV_LENGTH parameter.
+ (_bfd_dwarf2_find_nearest_line): Add ADDR_SIZE parameter.
+ * elf.c (_bfd_elf_find_nearest_line): Pass it.
+ * elf32-arm.h (elf32_arm_find_nearest_line): Likewise.
+ * elf32-mips.c (ABI_64_P): New macro.
+ (IRIX_COMPAT): We are IRIX6-compatible if ABI_64_P.
+ (_bfd_mips_elf_find_nearest_line): Adjust call to
+ _bfd_dwarf2_find_nearest_line.
+ * libbfd-in.h (_bfd_dwarf2_find_nearest_line): Update prototype.
+ * libbfd.h: Regenerated.
+
+1999-07-02 Ian Lance Taylor <ian@zembu.com>
+
+ * config.bfd: Add * at the end of i[3456]86-*-unixware.
+
+Fri Jul 2 12:21:10 1999 Jeffrey A Law (law@cygnus.com)
+
+ * libhppa.h (HPPA_R_ARG_RELOC): Delete.
+ (HPPA_R_CONSTANT, HPPA_R_ADDEND): Likewise.
+
+1999-07-01 Mark Mitchell <mark@codesourcery.com>
+
+ * elf-bfd.h (bfd_elf_section_data): Add rel_count and rel_count2
+ fields.
+ (_bfd_elf_init_reloc_shdr): New function.
+ * elf.c (_bfd_elf_new_section_hook): Use bfd_zalloc, rather than
+ bfd_alloc followed by memset.
+ (_bfd_elf_init_reloc_shdr): New function, split out from ...
+ (elf_fake_sections): Here.
+ (assign_section_numbers): Assign section numbers for the second
+ relocation section, if required.
+ * elflink.h (elf_link_output_relocs): New function.
+ (elf_link_size_reloc_section): Likewise.
+ (elf_bfd_final_link): Use elf_link_size_reloc_section.
+ (elf_link_input_bfd): Use elf_link_output_relocs.
+
+ * elf32-mips.c (_bfd_mips_elf_fake_sections): Use
+ _bfd_elf_init_reloc_shdr to initialize rel_hdr2.
+
+Thu Jul 1 13:58:48 1999 Jeffrey A Law (law@cygnus.com)
+
+ * elf-hppa.h (_bfd_elf_hppa_gen_reloc_type): Handle R_PCREL_CALL
+ with 22bit format.
+
+1999-06-28 Mark Mitchell <mark@codesourcery.com>
+
+ * elf32-mips.c (mips_elf_got_info): Move declaration before
+ prototypes. Change global_gotsym to be a pointer to a hash entry,
+ rather than a number index.
+ (mips_elf_link_hash_entry): Move declaration before prototypes.
+ (mips_elf_irix6_finish_dynamic_symbol): New function.
+ (mips_elf_sign_extend): Likewise.
+ (mips_elf_high): Likewise.
+ (mips_elf_higher): Likewise.
+ (mips_elf_highest): Likewise.
+ (mips_elf_global_got_index): Likewise.
+ (mips_elf_local_got_index): Likewise.
+ (mips_elf_got_offset_from_index): Likeiwse.
+ (mips_elf_record_global_got_symbol): Likewise.
+ (mips_elf_got_page): Likewise.
+ (mips_elf_next_lo16_addend): Likewise.
+ (mips_elf_calculate_relocation): Likewise.
+ (mips_elf_obtain_contents): Likewise.
+ (mips_elf_perform_relocation): Likewise.
+ (mips_elf_assign_gp): Likewise.
+ (mips_elf_sort_hash_table_f): Likewise.
+ (mips_elf_sort_hash_table): Likewise.
+ (mips_elf_got_section): Likewise.
+ (mips_elf_got_info): Likewise.
+ (mips_elf_create_local_got_entry): Likewise.
+ (mips_elf_got16_entry): Likewise.
+ (mips_elf_create_dynamic_relocation): Likewise.
+ (elf_mips_howto_table): Add description of R_MIPS_SCN_DISP.
+ (mips_elf_final_gp): Use mips_elf_assign_gp.
+ (_bfd_mips_elf_symbol_processing): Don't move SHN_COMMON symbols
+ into SHN_SCOMMON automatically on IRIX6.
+ (mips_elf_add_symbol_hook): Likewise.
+ (mips_elf_relocate_section): Rewrite, using
+ mips_elf_calculate_relocation and mips_elf_perform_relocation.
+ (mips_elf_create_dynamic_section): Use MIPS_ELF_STUB_SECTION_NAME.
+ Don't deal with .rld_map on IRIX6.
+ (mips_elf_create_got_section): Adjust use of global_gotsym. Set
+ section flags appropriately for .got.
+ (mips_elf_check_relocs): Handle IRIX6 relocations making use of
+ the got. Call mips_elf_record_global_got_symbol and allocate
+ local got space appropriately.
+ (mips_elf_size_dynamic_sections): Use bfd_byte *, not unsigned
+ char *. Rework calculation of GOT size. Sort dynamic symbol
+ table entries so entries that do not require GOT entries appear at
+ the beginning. Don't use DT_MIPS_HIPAGENO on IRIX6. Remove dead
+ code dealing with DT_INIT and DT_FINI. Remove fiddling with
+ global_gotsym.
+ (mips_elf_finish_dynamic_symbol): Adjust creation of global GOT
+ entries.
+ (mips_elf_finish_dynamic_symbol): Use
+ mips_elf_irix6_finish_dynamic_symbol.
+ (mips_elf_finish_dynamic_sections): Correct off-by-one error
+ setting DT_MIPS_UNREFEXTNO. Adjust setting of DT_MIPS_GOTSYM for
+ change to global_gotsym. Set DT_MIPS_OPTIONS on IRIX6.
+
+1999-06-30 Ian Lance Taylor <ian@zembu.com>
+
+ * elf32-mips.c (mips_elf_final_link): Don't set CPIC when doing a
+ relocateable link. From Ralf Baechle <ralf@uni-koblenz.de>.
+
+1999-06-04 Philip Blundell <philb@gnu.org>
+
+ * elf32-arm.h (elf_backend_got_header_size): Define.
+ (elf_backend_plt_header_size): Likewise.
+
+1999-06-28 Jim Pick <jim@jimpick.com>
+
+ * elf32-arm.h (elf32_arm_relocate_section): Mind no_undefined
+
+Tue Jun 29 02:25:03 1999 Jeffrey A Law (law@cygnus.com)
+
+ * elf-hppa.c (elf_hppa_howto_table): Use bfd_elf_generic_reloc as
+ relocation function.
+ * elf32-hppa.c (hppa_elf_reloc): Kill unused/unwanted function.
+
+1999-06-27 Mark Mitchell <mark@codesourcery.com>
+
+ * elf32-mips.c (MIPS_ELF_SRDATA_SECTION_NAME): New macro.
+ (MIPS_ELF_OPTIONS_SECTION_NAME): Likewise.
+ (MIPS_ELF_STUB_SECTION_NAME): Likewise.
+ (_bfd_mips_elf_section_from_shdr): Use them.
+ (_bfd_mips_elf_fake_sections): Likewise. Add .srdata to the list
+ of GP-relative sections.
+ (_bfd_mips_elf_set_section_contents): Use them.
+ (_bfd_mips_elf_section_processing): Share code between .sdata and
+ .lit4/.lit8 sections. Set appropriate flags for .srdata.
+ (mips_elf_additional_program_headers): Add handling for
+ PT_MIPS_OPTIONS segment on IRIX6.
+ (mips_elf_modify_segment_map): Likeiwse.
+ (mips_elf_final_link): Set EF_MIPS_CPIC when required by the ABI.
+ Include the options sections on IRIX6. Don't look for GP-relative
+ sections by name; use SHF_MIPS_GPREL instead.
+ (ELF_DYNAMIC_INTERPRETER): Adjust to use /usr/lib32/libc.so.1 for
+ the N32 ABI.
+ (mips_elf_create_dynamic_sections): Don't muck about with section
+ alignments and such on IRIX6.
+ (mips_elf_adjust_dynamic_symbol): Use MIPS_ELF_STUB_SECTION_NAME.
+ (mips_elf_size_dynamic_sections): Likewise. Adjust to handle the
+ fact that ELF_DYNAMIC_INTERPRETER is no longer a constant. Use
+ bfd_zalloc rather than bfd_alloc and memset.
+ (mips_elf_finish_dynamic_symbol): Use MIPS_ELF_STUB_SECTION_NAME.
+ Don't assert the existence of .rld_map on IRIX6.
+ (mips_elf_finish_dynamic_sections): Use MIPS_ELF_STUB_SECTION_NAME.
+
+ * elf32-mips.c (mips_elf_adjust_dynindx): Remove.
+ (mips_elf_size_dynamic_sections): Use _bfd_elf_link_adjust_dynindx
+ instead.
+
+1999-06-26 Mark Mitchell <mark@codesourcery.com>
+
+ * elf32-mips.c (mips_elf_swap_msym_in): New function.
+ (mips_elf_swap_msym_out): New function.
+ (mips_elf_create_msym_section): Likewise.
+ (MIPS_ELF_MSYM_SECTION_NAME): New macro.
+ (_bfd_mips_elf_final_write_processing): Set sh_link for .msym.
+ (_bfd_mips_elf_section_from_shdr): Reject an SHT_MIPS_MSYM
+ section not named .msym.
+ (_bfd_mips_elf_fake_sections): Use MIPS_ELF_MSYM_SECTION_NAME, not
+ .msym directly. Set appropriate attributes for the .msym
+ section.
+ (mips_elf_link_hash_entry): Add min_dyn_reloc_index field.
+ (mips_elf_link_hash_newfunc): Clear it.
+ (mips_elf_create_dynamic_sections): Create the .msym section
+ on IRIX6.
+ (mips_elf_size_dynamic_sections): Allocate space for the
+ .msym section. Add a DT_MIPS_MSYM entry.
+ (mips_elf_finish_dynamic_symbol): Write out a .msym entry for
+ the symbol.
+ (mips_elf_finish_dynamic_sections): Assign a value for
+ DT_MIPS_MSYM. Add .msym entries for the section symbols as well.
+
+ * elf32-mips.c (irix_compat_t): New enumeration.
+ (ABI_N32_P): New macro.
+ (IRIX_COMPAT): Likewise.
+ (SGI_COMPAT): Implement in terms of IRIX_COMPAT.
+ (mips_elf_relocate_section): Fix typo.
+
+1999-06-26 Mumit Khan <khan@xraylith.wisc.edu>
+
+ * peicode.h (coff_swap_scnhdr_out): Mark non readonly BFD sections
+ as writable PE sections.
+
+1999-06-26 David Mosberger <davidm@hpl.hp.com>
+
+ * dwarf2.c (struct arange): New type.
+ (struct comp_unit): Replace LOW and HIGH by member ARANGE.
+ (arange_add): New function.
+ (decode_line_info): Keep track of address ranges that a compilation
+ unit covers.
+ (comp_unit_contains_address): Return true if address is contained
+ in _any_ of the address ranges associated with a compilation unit.
+ (_bfd_dwarf2_find_nearest_line): Call comp_unit_find_nearest_line
+ on the first comp_unit that contains the address.
+
+1999-06-26 David Mosberger <davidm@hpl.hp.com>
+
+ * dwarf2.c (struct dwarf2_debug): Add member dwarf_line_buffer.
+ (decode_line_info): Add variable STASH and initialize it to point
+ to the per-bfd dwarf2_debug info. Remove static variable
+ dwarf_line_buffer and use stash->dwarf_line_buffer in its place.
+
+1999-06-26 Ian Lance Taylor <ian@zembu.com>
+
+ * elflink.h (elf_link_output_extsym): It's OK for a -Bsymbolic
+ shared library to have an undefined symbol.
+
+ From Franz Sirl <Franz.Sirl-kernel@lauterbach.com>:
+ * elf32-ppc.c (ppc_elf_relocate_section): Fix last patch.
+
+Thu Jun 24 20:59:11 1999 Jeffrey A Law (law@cygnus.com)
+
+ * elf-hppa.c (elf_hppa_final_write_processing): New function.
+ * elf32-hppa.c: Remove everything related to symbol extension
+ sections & records. Use the common elf_hppa_final_write_processing.
+
+1999-06-22 Mark Mitchell <mark@codesourcery.com>
+
+ * elflink.h (size_dynamic_sections): Use user-specified init/fini
+ functions instead of _init/_fini if requested.
+
+1999-06-23 Ian Lance Taylor <ian@zembu.com>
+
+ * elf.c (bfd_section_from_shdr): Avoid crashing on a bogus sh_link
+ field.
+
+1999-06-22 Ian Lance Taylor <ian@zembu.com>
+
+ From Franz Sirl <Franz.Sirl-kernel@lauterbach.com>:
+ * elf32-ppc.c (ppc_elf_size_dynamic_sections): Set unused dynindx
+ field to 0, not -1.
+ (ppc_elf_finish_dynamic_sections): Check for positive section
+ dynindx field, rather than comparing against -1.
+ (ppc_elf_relocate_section): Only return false if undefined_symbol
+ or reloc_overflow fail, not always upon encountering an error.
+
+1999-06-22 Mark Mitchell <mark@codesourcery.com>
+
+ * elflink.h (link_read_relocs): Explicitly cast external_relocs to
+ bfd_byte * before performing pointer arithmetic.
+
+Tue Jun 22 13:06:25 1999 Jeffrey A Law (law@cygnus.com)
+
+ * elf-hppa.h: New file. Common stuff for elf32 and elf64 PA
+ support.
+ * elf32-hppa.c: Include elf-hppa.h.
+ (ARCH_SIZE): Define.
+ (elf_hppa_reloc_type_lookup): Delete. Found in the common code
+ now.
+ (elf32_hppa_info_to_howto): Similarly.
+ (elf_hppa_howto_table): Similarly.
+ (elf_hppa_reloc_type_lookup): Similarly.
+ (hppa_elf_gen_reloc_type): Similarly.
+ * elf32-hppa.h (ELF_HOWTO_TALBE, N_PARISC_RELOCS): Delete.
+
+1999-06-22 Nick Clifton <nickc@cygnus.com>
+
+ * elf32-v850.c (v850_elf_final_link_relocate): Catch overflow
+ handling R_V850_22_PCREL relocation.
+
+1999-06-21 Ian Lance Taylor <ian@zembu.com>
+
+ * coff-arm.c (arm_emit_base_file_entry): Explicitly declare return
+ type.
+
+Sun Jun 20 14:13:57 1999 Richard Henderson <rth@cygnus.com>
+
+ * section.c (_bfd_strip_section_from_output): Ignore sections
+ DISCARDed by the link script.
+
+1999-06-19 Ian Lance Taylor <ian@zembu.com>
+
+ * elflink.h (elf_link_remove_section_and_adjust_dynindices):
+ Remove unused local variable spp.
+
+ * xcofflink.c (bfd_xcoff_size_dynamic_sections): Don't crash if
+ the entry symbol is not set.
+
+Fri Jun 18 04:24:57 1999 Richard Henderson <rth@cygnus.com>
+
+ * elf64-alpha.c (elf64_alpha_relocate_section): Don't adjust
+ GPDISP or LITUSE in a relocatable link.
+
+Thu Jun 17 21:24:43 1999 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * dwarf1.c (alloc_dwarf1_unit): Allocate using bfd_zalloc.
+ * (alloc_dwarf1_func): Likewise.
+
+Wed Jun 16 03:09:57 1999 Jeffrey A Law (law@cygnus.com)
+
+ * libhppa.h: Fix various formatting errors.
+ (assemble_3); Rewrite using CATENATE.
+ (assemble_17): Fix various bugs.
+
+1999-06-16 Nick Clifton <nickc@cygnus.com>
+
+ * elf32-mcore.c (R_MCORE_RAW): Fix definition.
+
+1999-06-15 Richard Henderson <rth@cygnus.com>
+
+ * section.c (SEC_SHORT): Define.
+ * bfd-in2.h: Rebuild.
+
+1999-06-13 Mark Mitchell <mark@codesourcery.com>
+
+ * elflink.h (elf_link_remove_section_and_adjust_dynindices):
+ Remove abfd parameter. Use _bfd_strip_section_from_output.
+ (bfd_elf_size_dynamic_sections): Adjust callers accordingly.
+
+ * elf-bfd.h (_bfd_elf_link_adjust_dynindx): New function.
+ * elflink.c (_bfd_elf_link_adjust_dynindx): Define it.
+ * elflink.h (elf_link_remove_section_and_adjust_dynindices): New
+ function.
+ (bfd_elf_size_dynamic_sections): Use it.
+
+1999-06-13 Alan Modra <alan@spri.levels.unisa.edu.au>
+
+ * elf32-i386.c (elf_howto_table): Change R_386_PC8 from
+ complain_overflow_bitfield to complain_overflow_signed.
+
+1999-06-13 Mark Mitchell <mark@codesourcery.com>
+
+ * elflink.h (elf_link_read_relocs_from_section): New function,
+ split out from ...
+ (elf_link_read_relocs): Here. Use it for both relocation
+ sections.
+
+1999-06-12 Mark Mitchell <mark@codesourcery.com>
+
+ * elfcode.h (elf_slurp_reloc_table_from_section): Don't assume
+ asect->reloc_count is valid.
+
+1999-06-12 Ian Lance Taylor <ian@zembu.com>
+
+ * elf32-mips.c (mips_elf32_section_processing): Permit a
+ SHT_MIPS_REGINFO section to have a size of 0.
+
+1999-06-12 David O'Brien <obrien@freebsd.org>
+
+ * config.bfd (alpha*-*-freebsd*): New target.
+ (i[3456]86-*-freebsd*): Now defaults to ELF.
+
+1999-06-11 Ian Lance Taylor <ian@zembu.com>
+
+ * reloc.c (_bfd_relocate_contents): Permit bitfield relocations to
+ wrap if the relocation covers the high bit of an address.
+
+ * dwarf2.c (decode_line_info): Remove unused variable first_time.
+
+1999-06-10 Jakub Jelinek <jj@ultra.linux.cz>
+
+ * elf64-sparc.c (sparc64_elf_relocate_section): Use R_SPARC_max_std
+ instead of R_SPARC_max.
+ (sparc64_elf_info_to_howto): Likewise.
+ * elf32-sparc.c (elf32_sparc_relocate_section): Likewise.
+ (elf32_sparc_info_to_howto): Likewise; handle vtable relocations.
+
+1999-06-07 Richard Henderson <rth@cygnus.com>
+
+ * section.c (_bfd_strip_section_from_output): Remove output
+ sections with no initial link_order.
+
+1999-06-07 Nick Clifton <nickc@cygnus.com>
+
+ * elf32-m88k.c (ELF_MAXPAGESIZE): Define.
+
+Mon Jun 7 11:49:43 1999 Andreas Schwab <schwab@issan.cs.uni-dortmund.de>
+
+ * Makefile.am (SOURCE_HFILES): Add missing headers.
+ * Makefile.in: Regenerated.
+
+1999-06-06 Mark Mitchell <mark@codesourcery.com>
+
+ * elf32-mips.c (_bfd_mips_elf_print_private_data): Recognize
+ the N32 ABI.
+
+1999-06-04 Franz Sirl <Franz.Sirl-kernel@lauterbach.com>
+
+ * elf32-ppc.c (ppc_elf_relocate_section): Don't barf on out of
+ range undefweak symbols.
+ * hash.c: Add missing comma after @xref{}
+ * linker.c: Likewise.
+
+1999-06-04 Nick Clifton <nickc@cygnus.com>
+
+ * elfxx-target.h (ELF_MAXPAGESIZE): Produce an error message
+ if not defined.
+ * elf32-gen.c (ELF_MAXPAGESIZE): Define.
+ * elf32-i860.c (ELF_MAXPAGESIZE): Define.
+ * elf32-i960.c (ELF_MAXPAGESIZE): Define.
+ * elf64-gen.c (ELF_MAXPAGESIZE): Define.
+
+1999-06-04 Ian Lance Taylor <ian@zembu.com>
+
+ * Makefile.am: Rebuild dependencies.
+ (BFD32_BACKENDS): Add dwarf1.lo.
+ (BFD32_BACKENDS_CFILES): Add dwarf1.c.
+ * Makefile.in: Rebuild.
+
+1999-06-04 Nick Clifton <nickc@cygnus.com>
+
+ * Makefile.am: Add epoc-arm-pe target.
+ * Makefile.in: Regenerate.
+ * pe-arm.c: Only redefine interworking function names if they have
+ not already been redefined.
+ * pei-arm.c: Only redefine interworking function names if they have
+ not already been redefined.
+ * epoc-pe-arm.c: Redefine interworking function names to avoid a
+ name space clash.
+ * epoc-pei-arm.c: Redefine interworking function names to avoid a
+ name space clash.
+
+1999-06-03 Nick Clifton <nickc@cygnus.com>
+
+ * elfxx-target.h (ELF_MAXPAGESIZE): Default to 0x1000 not 1.
+
+Fri Jun 4 10:05:11 1999 Andreas Schwab <schwab@issan.cs.uni-dortmund.de>
+
+ * elf.c (elf_fake_sections): Undo change of 1999-05-10.
+
+Fri Jun 4 03:10:49 1999 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * elf32-sh.c (sh_elf_relax_delete_bytes): Fix setting of
+ start / stop for recalculating of r_addend of R_SH_SWITCH*.
+
+Fri Jun 4 02:53:13 1999 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * elf32-sh.c (sh_elf_relax_delete_bytes): Handle R_SH_SWITCH32
+ in other text sections.
+
+Fri Jun 4 02:29:34 1999 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * libbfd.c (_bfd_generic_verify_endian_match): New function.
+ * libbfd-in.h (_bfd_generic_verify_endian_match): Declare.
+ * libbfd.h: Regenerate.
+ * coff-sh.c (sh_merge_private_data): Delete.
+ (coff_bfd_merge_private_bfd_data): Change to
+ _bfd_generic_verify_endian_match.
+ (elf32-sh.c): bfd_elf32_bfd_merge_private_bfd_data: Define.
+
+1999-06-03 Ulrich Drepper <drepper@cygnus.com>
+
+ * elf32-arm.h: Fix typo: change ELF_MAXPAGE_SIZE to ELF_MAXPAGESIZE.
+
+1999-06-03 Ian Lance Taylor <ian@zembu.com>
+
+ * bfd-in.h (bfd_elf32_arm_allocate_interworking_sections): Correct
+ prototype.
+ (bfd_elf32_arm_process_before_allocation): Likewise.
+ * bfd-in2.h: Rebuild.
+
+1999-06-03 David Mosberger <davidm@hpl.hp.com>
+
+ * dwarf2.c (struct line_info): Add member END_SEQUENCE to keep
+ track of end_sequence markers.
+ (add_line_info): Add END_SEQUENCE arg.
+ (decode_line_info): Don't try to infer lo_pc and hi_pc from the
+ debug-line info---it doesn't work right if a compilation unit
+ consists of multiple discontiguous code-sequences. It would be
+ worthwhile to optimize for the common case where a compilation
+ unit results in a contiguous set of code sequences, but this is
+ quite tricky to get right for arbitrary DWARF2 files.
+ (lookup_address_in_line_info_table): Don't use the last line entry
+ for a compilation unit for anything with an address higher than
+ this line entry. Also, check for end_sequence markers to
+ correctly handle discontinuities.
+ (_bfd_dwarf2_find_nearest_line): When checking previously loaded
+ compilation units, check all compilation units with each->high==0
+ just like when reading compilation units.
+
+ * dwarf2.c (decode_line_info): Initialize table->files and
+ table->last_line to NULL to avoid segfaults due to random
+ values in these members.
+ (concat_filename): Check for out-of-range file number before
+ indexing filename table. Segfaults suck.
+
+ * 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.
+
+1999-06-02 Mark Mitchell <Mark Mitchell <mark@codesourcery.com>>
+
+ * elf32-mips.c (elf_mips_howto_table): Add R_MIPS_JALR.
+ * elf64-mips.c (mips_elf64_howto_table_rel): Likewise.
+ (mips_elf64_howto_table_rela): Likewise.
+
+ * elfcode.h (elf_slurp_reloc_table_from_section): New function,
+ split out from ...
+ (elf_slurp_reloc_table): Here. Use it to handle the case where a
+ single section has two associated relocation sections.
+
+1999-06-02 Mark Salter <msalter@cygnus.com>
+
+ * coffcode.h (coff_set_alignment_hook): Set lma from s_vaddr if
+ COFF_WITH_PE defined.
+
+1999-06-02 Nick Clifton <nickc@cygnus.com>
+
+ * pe-arm.c: Rename global arm interworking functions to avoid name
+ collision when all targets BFD is built.
+ * pei-arm.c: Ditto.
+
+1999-05-31 Mark Mitchell <mark@codesourcery.com>
+
+ * elf-bfd.h (elf_backend_data): Remove use_rela_p. Add
+ may_use_rel_p, may_use_rela_p, default_use_rela_p.
+ (bfd_elf_section_data): Add use_rela_p.
+ * elf.c (bfd_section_from_shdr): Set use_rela_p appropriately.
+ (_bfd_elf_new_section_hook): Likewise.
+ (elf_fake_sections): Use may_use_rela_p, etc., instead of
+ use_rela_p.
+ (_bfd_elf_copy_private_section_data): Copy use_rela_p.
+ * elfcode.h (write_relocs): Determine whether or not use rela
+ relocs based on the relocation section header.
+ * elflink.c (_bfd_elf_create_dynamic_sections): Use default_use_rela_p
+ instead of use_rela_p.
+ * elfxx-target.h (elf_backend_may_use_relp): New macro.
+ (elf_backend_may_use_rela_p): Likewise.
+ (elf_backend_default_use_rela_p): Likewise.
+ (elfNN_bed): Use them.
+
+Wed Jun 2 12:38:49 1999 Miodrag Vallat <miodrag@multimania.com>
+
+ * hosts/alphalinux.h (TRAD_CORE_EXTRA_SIZE_ALLOWED): Expand to 4096.
+
+Tue Jun 1 17:57:58 1999 Mark P. Mitchell <mitchell@n02.acl.lanl.gov>
+
+ * reloc.c (BFD_RELOC_MIPS_SUB): New relocation.
+ (BFD_RELOC_MIPS_GOT_PAGE): Likewise.
+ (BFD_RELOC_MIPS_GOT_OFST): Likewise.
+ (BFD_RELOC_MIPS_GOT_DISP): Likewise.
+ * bfd-in2.h: Regenerated.
+ * libbfd.h: Likewise.
+ * elf32-mips.c (mips_info_to_howto_rela): New function.
+ (USE_REL): Adjust for new conventions.
+ (MINUS_ONE): New macro.
+ (elf_mips_howto_table): Add R_MIPS_SUB.
+ (mips_r): Add entries for MIPS_SUB, MIPS_GOT_PAGE, MIPS_GOT_OFST,
+ and MIPS_GOT_DISP.
+ (mips_elf_final_write_processing): Set sh_link, not sh_info, for a
+ .MIPS.content section.
+ (_bfd_mips_elf_fake_sections): Treat all sections that begin
+ with .MIPS.content as .MIPS.content sections. Set
+ SHF_MNIPS_NOSTRIP for such section.
+ (elf_info_to_howto): Define to mips_info_to_howto_rela.
+ * elf64-mips.c (mips_r): Add entries for MIPS_SUB, MIPS_GOT_PAGE,
+ MIPS_GOT_OFST, and MIPS_GOT_DISP.
+
+Wed Jun 2 11:51:12 1999 Andreas Schwab <schwab@issan.cs.uni-dortmund.de>
+
+ * vms-misc.c (_bfd_vms_hash_newfunc): Fix use of uninitialized
+ variable.
+
+ * elf32-m68k.c (elf_m68k_adjust_dynamic_symbol): Avoid ambigous
+ `else'.
+
+1999-05-30 Philip Blundell <philb@gnu.org>
+
+ * elf32-arm.h (elf32_arm_relocate_section): Reinstate change of
+ 1993-03-25 (!!). Take into account the bitmasks for the reloc so
+ the addend does not overflow into the rest of the word.
+
+1999-05-29 Nick Clifton <nickc@cygnus.com>
+
+ * bfd-in.h: Amend prototype for
+ bfd_elf32_arm_process_before_allocation .
+ * bfd-in.h: Regenerate.
+
+ * elfarm-oabi.c (NUM_ELEM): New macro: Compute the number of
+ elements in a fixed sized array.
+ (ARM_ELF_ABI_VERSION): Define.
+ (ARM_ELF_OS_ABI_VERSION): Define.
+ (R_ARM_THM_ABS5): Fix rightshift and size.
+ (R_ARM_THM_PC22): Fix size.
+ (R_ARM_PLT32): Define Howto.
+ (find_howto): New function: Locate a howto based on a reloc
+ number.
+ (elf32_arm_info_to_howto): Use find_howto if necessary.
+ (elf32_arm_reloc_map): Change type of field bfd_reloc_val to
+ bfd_reloc_code_real_type.
+ (elf32_arm_reloc_map[]): Add entries for BFD_RELOC_VTABLE_INHERIT
+ and BFD_RELOC_VTABLE_ENTRY.
+ (elf32_arm_reloc_type_lookup): Use find_howto if necessary.
+
+ * elfarm-nabi.c (NUM_ELEM): New macro: Compute the number of
+ elements in a fixed sized array.
+ (ARM_ELF_ABI_VERSION): Define.
+ (ARM_ELF_OS_ABI_VERSION): Define.
+ (R_ARM_THM_ABS5): Fix rightshift and size.
+ (R_ARM_THM_PC22): Fix size.
+ (elf32_arm_info_to_howto_rel): Rename to elf32_arm_info_to_howto.
+ (elf32_arm_reloc_map): Change type of field bfd_reloc_val to
+ bfd_reloc_code_real_type.
+
+ * elf32-arm.h (struct elf32_arm_link_hash_table): Add new field:
+ no_pipeline_knowledge.
+ (elf32_arm_link_hash_create): Initialise new field to zero.
+ (bfd_elf32_arm_process_before_allocation): Add new paraemter:
+ no_pipeline_knowledge. Use this parameter to initialise the field
+ in the globals data structure.
+ (elf32_arm_final_link_relocate): Only add in pipeline offset if
+ no_pipeline_knowledge is false and the binary is from an old
+ toolchain.
+ (elf32_arm_merge_private_data): Generate an error if an attempt is
+ made to link together big endian and little endian code.
+ (elf32_arm_post_process_headers): New function: Initialise the
+ EI_OSABI and EI_ABIVERSION fields of the newly created ELF program
+ header.
+ (elf_backend_post_process_headers): Define.
+
+1999-05-28 Nick Clifton <nickc@cygnus.com>
+
+ * elf-bfd.h (struct elf_backend_data): Add new field:
+ elf_backend_post_process_headers.
+
+ * elfxx-target.h (elf_backend_post_process_headers): Define to
+ NULL if not already defined.
+ (elfNN_bed): Initialise elf_backend_post_process_headers field.
+
+ * elf.c (prep_headers): Set the EI_OSABI and EI_ABIVERSION fields
+ to zero.
+ (_bfd_elf_compute_section_file_positions): Call
+ elf_backend_post_process_headers if defined.
+
+1999-05-28 Ian Lance Taylor <ian@zembu.com>
+
+ * configure.in: Check whether getuid and getgid exist.
+ * archive.c: Define getuid and getgid as macros if HAVE_GETUID or
+ HAVE_GETGID are not defined, respectively.
+ (bfd_write_armap): Don't special case on _WIN32 for getuid and
+ getgid.
+ * configure.host: Set ac_cv_func_get{ug}id for *-*-windows*.
+ * configure, config.in: Rebuild.
+
+1999-05-28 Martin Dorey <mdorey@madge.com>
+
+ * elf32-i960.c: New file.
+ * elf.c (prep_headers): Handle bfd_arch_i960.
+ * targets.c (bfd_target_vector): Add &bfd_elf32_i960_vec.
+ * config.bfd (i960-*-elf*): New target.
+ * configure.in (bfd_elf32_i960_vec): New target vector.
+ * Makefile.am (BFD32_BACKENDS): Add elf32-i960.lo.
+ (BFD32_BACKENDS_CFILES): Add elf32-i960.c.
+ * Makefile.in, aclocal.m4, configure: Rebuild.
+
+1999-05-27 Nick Clifton <nickc@cygnus.com>
+
+ * elfarm-oabi.c (elf32_arm_howto_table): Add entry for
+ R_ARM_PLT32.
+ (find_howto): New function: Find entries in the
+ elf32_arm_howto_table.
+ (elf32_arm_info_to_howto): Use find_howto if the entry cannot be
+ computed simply.
+ (elf32_arm_reloc_type_lookup): Add lookup for
+ BFD_RELOC_ARM_PLT32.
+
+1999-05-25 Philip Blundell <pb@nexus.co.uk>
+
+ * elf32-arm.h (elf32_arm_link_hash_newfunc): New function.
+ (elf32_arm_link_hash_table_create): Use above function as the
+ constructor for hash table entries.
+ (elf32_arm_relocate_section): Avoid crash when there is no output
+ section.
+ (elf32_arm_final_link_relocate): New parameter h.
+ (elf32_arm_relocate_section): Pass symbol hash entry to above
+ routine.
+ (elf32_arm_gc_sweep_hook, elf32_arm_check relocs): Correct
+ comments.
+
+1999-05-25 Catherine Moore <clm@cygnus.com>
+
+ * coff-arm.c (coff_arm_relocate_section): Don't emit
+ base file entries for pc-relative values.
+
+1999-05-25 DJ Delorie <dj@cygnus.com>
+
+ * peicode.h (coff_swap_sym_in): When we create the actual section
+ to reflect the not-there section C_SECTION symbols refer to,
+ change the symbol class to C_STAT as the section is now really
+ there.
+
+1999-05-24 Philip Blundell <pb@nexus.co.uk>
+
+ * elf32-arm.h (elf32_arm_relocate_section): Undo change of
+ 1999-03-25.
+
+Mon May 17 13:35:35 1999 Stan Cox <scox@cygnus.com>
+
+ * coff-arm.c (_bfd_coff_arm_set_private_flags): Changed
+ F_PIC_INT to F_PIC.
+ * coffcode.h (coff_set_arch_mach_hook): Added F_ARM_2a, and
+ F_ARM_3M labels. Changed F_PIC_INT to F_PIC.
+
+1999-05-16 Nick Clifton <nickc@cygnus.com>
+
+ * coff-mcore.c (in_reloc_p): Reinstate.
+
+1999-05-15 Nick Clifton <nickc@cygnus.com>
+
+ * reloc.c (BFD_RELOC_MCORE_RVA): Define.
+ * bfd-in2.h: Regenerate.
+ * coff-mcore.c (in_reloc_p): Remove defintion.
+ (mcore_coff_howto): Add IMAGE_REL_MCORE_RVA.
+ (mcore_coff_reloc_type_lookup): Map BFD_RELOC_RVA to
+ IMAGE_REL_MCORE_RVA.
+ (coff_mcore_rtype_to_howto): Add special processing for
+ IMAGE_REL_MCORE_RVA.
+ (coff_mcore_relocate_section): Add support for
+ IMAGE_REL_MCORE_RVA.
+ * elf32-mcore.c (mcore_elf_howto_): Add R_MCORE_RELATIVE.
+ (mcore_elf_reloc_type_lookup): Map BFD_RELOC_RVA to
+ R_MCORE_RELATIVE.
+ (mcore_elf_relocate_section): Delete redundant case labels.
+
+Fri May 14 10:59:55 1999 Andreas Schwab <schwab@issan.cs.uni-dortmund.de>
+
+ * elf32-arm.h (elf32_arm_relocate_section): Fix operator
+ precedence between bit-and and comparison.
+
+Thu May 13 09:45:23 1999 Joel Sherrill (joel@OARcorp.com)
+
+ * config.bfd (i[3456]86*-*-rtems*, m68k*-*-rtems*): Added to
+ list of target formats (targ_selvecs).
+ (i[3456]86*-*-rtemself*, mips*el-*-rtems*): New targets.
+ (powerpcle*-*rtems*, sh-*-rtemself*): New targets.
+
+1999-05-10 DJ Delorie <dj@cygnus.com>
+
+ * ecoff.c (_bfd_ecoff_write_armap): give the symtab element a
+ reasonable mode until "ar x" is smart enough to skip it (fixes
+ gcc/libgcc.a builds on mips-ecoff targets
+
+ * coffcode.h (styp_to_sec_flags): Explain how COMDATs are supposed
+ to work. Hack to support MS import libraries, which use different
+ COMDAT types than GNU.
+ (coff_slurp_symbol_table): C_SECTION symbols are local; they refer
+ to implied zero-length sections (see peicode below)
+ * coffgen.c (coff_get_normalized_symtab): Properly read long MS
+ filename symbols, which use one *or more* auxents.
+ * coffswap.h (coff_swap_aux_in): ditto
+ * peicode.h (coff_swap_sym_in): Build the implied zero-length
+ sections
+
+Tue May 11 15:51:58 1999 Jeffrey A Law (law@cygnus.com)
+
+ * elf32-v850.c (v850_elf_howto_table): Make partial_inplace false
+ for all relocations.
+
+1999-05-10 Catherine Moore <clm@cygnus.com>
+
+ * bfd-in.h (bfd_arm_allocate_interworking_sections): Static
+ if COFF_IMAGE_WITH_PE.
+ (bfd_arm_process_before_allocation): Likewise.
+ (bfd_arm_get_bfd_for_interworking): Likewise.
+ * coff-arm.c: Likewise.
+ * bfd-in2.h: Regenerate.
+ * configure.in (armpe_little_vec): Remove coff-arm.lo.
+ (armpe_big_vec): Likewise.
+ * configure: Rebuild.
+
+1999-05-10 Nick Clifton <nickc@cygnus.com>
+
+ * elf.c (elf_fake_sections): Check for .rel. as start of rel
+ section, not just .rel. Same for .rela.
+
+1999-05-07 Nick Clifton <nickc@cygnus.com>
+
+ * coff-mcore.c (coff_mcore_relocate_section): Replace assert about
+ endianism with an error message.
+
+Thu May 6 17:09:09 1999 Fred Fish <fnf@be.com>
+
+ * dwarf2.c (read_abbrevs): Change cast of dwarf_abbrev_buffer
+ assignment from "unsigned char *" to "char *".
+ (decode_line_info): Likewise for dwarf_line_buffer assignment.
+
+1999-05-05 Catherine Moore <clm@cygnus.com>
+
+ * coff-arm.c (coff_arm_relocate_section): Add one to
+ address of ARM_RVA32 thumb functions.
+
+1999-05-05 Catherine Moore <clm@cygnus.com>
+
+ * elf32-m68k.c (elf32_m68k_set_private_flags): New.
+ (elf32_m68k_copy_private_bfd_data): New.
+ (elf32_m68k_merge_private_bfd_data): New.
+ (elf32_m68k_print_private_bfd_data): New.
+ (CPU32_FLAG): Define.
+ (PLT_CPU32_ENTRY_SIZE): Define.
+ (elf_cpu32_plt0_entry): Declare.
+ (elf_cpu32_plt_entry): Declare.
+ (elf_m68k_adjust_dynamic_symbol): Generate cpu32 plt entries.
+ (elf_m68k_finish_dynamic_symbol): Likewise.
+ (elf_m68k_finish_dynamic_sections): Likewise.
+ (elf_backend_plt_header_size): Remove definition.
+ (bfd_elf32_bfd_copy_private_bfd_data): Define.
+ (bfd_elf32_bfd_merge_private_bfd_data): Define.
+ (bfd_elf32_bfd_set_private_flags): Define.
+ (bfd_elf32_bfd_print_private_bfd_data): Define.
+
+Mon May 3 09:24:49 1999 Jeffrey A Law (law@cygnus.com)
+
+ * som.c (som_fixup_formats): Fix comments for R_SHORT_PCREL_MODE
+ and R_LONG_PCREL_MODE.
+
+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.c: Allow previous header files to override definition of
+ TARGET_LITTLE_SYM and TARGET_BIG_SYM.
+ * pei-arm.c: 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_mach_mips4111): New.
+ * bfd-in2.h: Regenerate.
+ * 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: Likewise.
+ * i386msdos.c: Likewise.
+ * i386os9k.c: Likewise.
+ * 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 entries.
+ 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 non-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
+
+Copyright (C) 1998-1999 Free Software Foundation, Inc.
+
+Copying and distribution of this file, with or without modification,
+are permitted in any medium without royalty provided the copyright
+notice and this notice are preserved.
+
+Local Variables:
+mode: change-log
+left-margin: 8
+fill-column: 74
+version-control: never
+End:
diff --git a/bfd/MAINTAINERS b/bfd/MAINTAINERS
new file mode 100644
index 0000000..9ee4884
--- /dev/null
+++ b/bfd/MAINTAINERS
@@ -0,0 +1,7 @@
+See ../binutils/MAINTAINERS
+
+Copyright (C) 2012-2014 Free Software Foundation, Inc.
+
+Copying and distribution of this file, with or without modification,
+are permitted in any medium without royalty provided the copyright
+notice and this notice are preserved.
diff --git a/bfd/Makefile.am b/bfd/Makefile.am
new file mode 100644
index 0000000..6f64f06
--- /dev/null
+++ b/bfd/Makefile.am
@@ -0,0 +1,1059 @@
+## Process this file with automake to generate Makefile.in
+#
+# Copyright (C) 2012-2014 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 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 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 COPYING3. If not see
+# <http://www.gnu.org/licenses/>.
+#
+
+AUTOMAKE_OPTIONS = 1.11 no-dist foreign
+ACLOCAL_AMFLAGS = -I . -I .. -I ../config
+
+INCDIR = $(srcdir)/../include
+CSEARCH = -I. -I$(srcdir) -I$(INCDIR)
+
+SUBDIRS = doc po
+
+bfddocdir = doc
+
+libbfd_la_LDFLAGS =
+if INSTALL_LIBBFD
+bfdlibdir = @bfdlibdir@
+bfdincludedir = @bfdincludedir@
+bfdlib_LTLIBRARIES = libbfd.la
+bfdinclude_HEADERS = $(BFD_H) $(INCDIR)/ansidecl.h $(INCDIR)/symcat.h $(INCDIR)/bfdlink.h
+else !INSTALL_LIBBFD
+# Empty these so that the respective installation directories will not be created.
+bfdlibdir =
+bfdincludedir =
+bfdinclude_HEADERS =
+rpath_bfdlibdir = @bfdlibdir@
+noinst_LTLIBRARIES = libbfd.la
+libbfd_la_LDFLAGS += -rpath $(rpath_bfdlibdir)
+endif
+
+WARN_CFLAGS = @WARN_CFLAGS@
+NO_WERROR = @NO_WERROR@
+AM_CFLAGS = $(WARN_CFLAGS)
+AM_CPPFLAGS = -DBINDIR='"$(bindir)"'
+if PLUGINS
+bfdinclude_HEADERS += $(INCDIR)/plugin-api.h
+LIBDL = @lt_cv_dlopen_libs@
+endif
+
+# 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).
+BFD32_LIBS = \
+ archive.lo archures.lo bfd.lo bfdio.lo bfdwin.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 \
+ merge.lo dwarf2.lo simple.lo compress.lo verilog.lo
+
+BFD64_LIBS = archive64.lo
+
+BFD32_LIBS_CFILES = \
+ archive.c archures.c bfd.c bfdio.c bfdwin.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 \
+ merge.c dwarf2.c simple.c compress.c verilog.c
+
+BFD64_LIBS_CFILES = archive64.c
+
+# This list is alphabetized to make it easier to keep in sync
+# with the decls and initializer in archures.c.
+ALL_MACHINES = \
+ cpu-aarch64.lo \
+ cpu-alpha.lo \
+ cpu-arc.lo \
+ cpu-arm.lo \
+ cpu-avr.lo \
+ cpu-bfin.lo \
+ cpu-cr16.lo \
+ cpu-cr16c.lo \
+ cpu-cris.lo \
+ cpu-crx.lo \
+ cpu-d10v.lo \
+ cpu-d30v.lo \
+ cpu-dlx.lo \
+ cpu-epiphany.lo \
+ cpu-fr30.lo \
+ cpu-frv.lo \
+ cpu-h8300.lo \
+ cpu-h8500.lo \
+ cpu-hppa.lo \
+ cpu-i370.lo \
+ cpu-i386.lo \
+ cpu-l1om.lo \
+ cpu-k1om.lo \
+ cpu-i860.lo \
+ cpu-i960.lo \
+ cpu-ia64.lo \
+ cpu-ip2k.lo \
+ cpu-iq2000.lo \
+ cpu-lm32.lo \
+ cpu-m10200.lo \
+ cpu-m10300.lo \
+ cpu-m32c.lo \
+ cpu-m32r.lo \
+ cpu-m68hc11.lo \
+ cpu-m68hc12.lo \
+ cpu-m9s12x.lo \
+ cpu-m9s12xg.lo \
+ cpu-m68k.lo \
+ cpu-m88k.lo \
+ cpu-mcore.lo \
+ cpu-mep.lo \
+ cpu-metag.lo \
+ cpu-microblaze.lo \
+ cpu-mips.lo \
+ cpu-mmix.lo \
+ cpu-moxie.lo \
+ cpu-msp430.lo \
+ cpu-mt.lo \
+ cpu-nds32.lo \
+ cpu-nios2.lo \
+ cpu-ns32k.lo \
+ cpu-or1k.lo \
+ cpu-pdp11.lo \
+ cpu-pj.lo \
+ cpu-plugin.lo \
+ cpu-powerpc.lo \
+ cpu-rs6000.lo \
+ cpu-rl78.lo \
+ cpu-rx.lo \
+ cpu-s390.lo \
+ cpu-score.lo \
+ cpu-sh.lo \
+ cpu-sparc.lo \
+ cpu-spu.lo \
+ cpu-tic30.lo \
+ cpu-tic4x.lo \
+ cpu-tic54x.lo \
+ cpu-tic6x.lo \
+ cpu-tic80.lo \
+ cpu-tilegx.lo \
+ cpu-tilepro.lo \
+ cpu-v850.lo \
+ cpu-v850_rh850.lo \
+ cpu-vax.lo \
+ cpu-w65.lo \
+ cpu-we32k.lo \
+ cpu-xc16x.lo \
+ cpu-xgate.lo \
+ cpu-xstormy16.lo \
+ cpu-xtensa.lo \
+ cpu-z80.lo \
+ cpu-z8k.lo
+
+ALL_MACHINES_CFILES = \
+ cpu-aarch64.c \
+ cpu-alpha.c \
+ cpu-arc.c \
+ cpu-arm.c \
+ cpu-avr.c \
+ cpu-bfin.c \
+ cpu-cr16.c \
+ cpu-cr16c.c \
+ cpu-cris.c \
+ cpu-crx.c \
+ cpu-d10v.c \
+ cpu-d30v.c \
+ cpu-dlx.c \
+ cpu-epiphany.c \
+ cpu-fr30.c \
+ cpu-frv.c \
+ cpu-h8300.c \
+ cpu-h8500.c \
+ cpu-hppa.c \
+ cpu-i370.c \
+ cpu-i386.c \
+ cpu-l1om.c \
+ cpu-k1om.c \
+ cpu-i860.c \
+ cpu-i960.c \
+ cpu-ia64.c \
+ cpu-ip2k.c \
+ cpu-iq2000.c \
+ cpu-lm32.c \
+ cpu-m10200.c \
+ cpu-m10300.c \
+ cpu-m32c.c \
+ cpu-m32r.c \
+ cpu-m68hc11.c \
+ cpu-m68hc12.c \
+ cpu-m9s12x.c \
+ cpu-m9s12xg.c \
+ cpu-m68k.c \
+ cpu-m88k.c \
+ cpu-mcore.c \
+ cpu-mep.c \
+ cpu-metag.c \
+ cpu-microblaze.c \
+ cpu-mips.c \
+ cpu-mmix.c \
+ cpu-moxie.c \
+ cpu-msp430.c \
+ cpu-mt.c \
+ cpu-nds32.c \
+ cpu-ns32k.c \
+ cpu-nios2.c \
+ cpu-or1k.c \
+ cpu-pdp11.c \
+ cpu-pj.c \
+ cpu-plugin.c \
+ cpu-powerpc.c \
+ cpu-rs6000.c \
+ cpu-rl78.c \
+ cpu-rx.c \
+ cpu-s390.c \
+ cpu-score.c \
+ cpu-sh.c \
+ cpu-sparc.c \
+ cpu-spu.c \
+ cpu-tic30.c \
+ cpu-tic4x.c \
+ cpu-tic54x.c \
+ cpu-tic6x.c \
+ cpu-tic80.c \
+ cpu-tilegx.c \
+ cpu-tilepro.c \
+ cpu-v850.c \
+ cpu-v850_rh850.c \
+ cpu-vax.c \
+ cpu-w65.c \
+ cpu-we32k.c \
+ cpu-xc16x.c \
+ cpu-xgate.c \
+ cpu-xstormy16.c \
+ cpu-xtensa.c \
+ cpu-z80.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-cris.lo \
+ aout-ns32k.lo \
+ aout-sparcle.lo \
+ aout-tic30.lo \
+ aout0.lo \
+ aout32.lo \
+ armnetbsd.lo \
+ bout.lo \
+ cf-i386lynx.lo \
+ cf-sparclynx.lo \
+ coff-apollo.lo \
+ coff-arm.lo \
+ coff-aux.lo \
+ coff-go32.lo \
+ coff-h8300.lo \
+ coff-h8500.lo \
+ coff-i386.lo \
+ coff-i860.lo \
+ coff-i960.lo \
+ coff-m68k.lo \
+ coff-m88k.lo \
+ coff-mips.lo \
+ coff-rs6000.lo \
+ coff-sh.lo \
+ coff-sparc.lo \
+ coff-stgo32.lo \
+ coff-svm68k.lo \
+ coff-tic30.lo \
+ coff-tic4x.lo \
+ coff-tic54x.lo \
+ coff-tic80.lo \
+ coff-u68k.lo \
+ coff-w65.lo \
+ coff-we32k.lo \
+ coff-z80.lo \
+ coff-z8k.lo \
+ cofflink.lo \
+ dwarf1.lo \
+ ecoff.lo \
+ ecofflink.lo \
+ elf-attrs.lo \
+ elf-eh-frame.lo \
+ elf-ifunc.lo \
+ elf-m10200.lo \
+ elf-m10300.lo \
+ elf-nacl.lo \
+ elf-strtab.lo \
+ elf-vxworks.lo \
+ elf.lo \
+ elf32-am33lin.lo \
+ elf32-arc.lo \
+ elf32-arm.lo \
+ elf32-avr.lo \
+ elf32-bfin.lo \
+ elf32-cr16.lo \
+ elf32-cr16c.lo \
+ elf32-cris.lo \
+ elf32-crx.lo \
+ elf32-d10v.lo \
+ elf32-d30v.lo \
+ elf32-dlx.lo \
+ elf32-epiphany.lo \
+ elf32-fr30.lo \
+ elf32-frv.lo \
+ elf32-gen.lo \
+ elf32-h8300.lo \
+ elf32-hppa.lo \
+ elf32-i370.lo \
+ elf32-i386.lo \
+ elf32-i860.lo \
+ elf32-i960.lo \
+ elf32-ip2k.lo \
+ elf32-iq2000.lo \
+ elf32-lm32.lo \
+ elf32-m32c.lo \
+ elf32-m32r.lo \
+ elf32-m68hc11.lo \
+ elf32-m68hc12.lo \
+ elf32-m68hc1x.lo \
+ elf32-m68k.lo \
+ elf32-m88k.lo \
+ elf32-mcore.lo \
+ elf32-mep.lo \
+ elf32-metag.lo \
+ elf32-microblaze.lo \
+ elf32-moxie.lo \
+ elf32-msp430.lo \
+ elf32-mt.lo \
+ elf32-nds32.lo \
+ elf32-nios2.lo \
+ elf32-or1k.lo \
+ elf32-pj.lo \
+ elf32-ppc.lo \
+ elf32-rl78.lo \
+ elf32-rx.lo \
+ elf32-s390.lo \
+ elf32-sh-symbian.lo \
+ elf32-sh.lo \
+ elf32-sh64-com.lo \
+ elf32-sh64.lo \
+ elf32-sparc.lo \
+ elf32-spu.lo \
+ elf32-tic6x.lo \
+ elf32-tilegx.lo \
+ elf32-tilepro.lo \
+ elf32-v850.lo \
+ elf32-vax.lo \
+ elf32-xc16x.lo \
+ elf32-xgate.lo \
+ elf32-xstormy16.lo \
+ elf32-xtensa.lo \
+ elf32.lo \
+ elflink.lo \
+ elfxx-sparc.lo \
+ elfxx-tilegx.lo \
+ epoc-pe-arm.lo \
+ epoc-pei-arm.lo \
+ hp300bsd.lo \
+ hp300hpux.lo \
+ i386aout.lo \
+ i386bsd.lo \
+ i386dynix.lo \
+ i386freebsd.lo \
+ i386linux.lo \
+ i386lynx.lo \
+ i386mach3.lo \
+ i386msdos.lo \
+ i386netbsd.lo \
+ i386os9k.lo \
+ ieee.lo \
+ m68k4knetbsd.lo \
+ m68klinux.lo \
+ m68knetbsd.lo \
+ m88kmach3.lo \
+ m88kopenbsd.lo \
+ mach-o.lo \
+ mach-o-i386.lo \
+ mipsbsd.lo \
+ newsos3.lo \
+ nlm.lo \
+ nlm32-i386.lo \
+ nlm32-ppc.lo \
+ nlm32-sparc.lo \
+ nlm32.lo \
+ ns32knetbsd.lo \
+ oasys.lo \
+ pc532-mach.lo \
+ pdp11.lo \
+ pe-arm-wince.lo \
+ pe-arm.lo \
+ pe-i386.lo \
+ pe-mcore.lo \
+ pe-mips.lo \
+ pe-ppc.lo \
+ pe-sh.lo \
+ pef.lo \
+ pei-arm-wince.lo \
+ pei-arm.lo \
+ pei-i386.lo \
+ pei-mcore.lo \
+ pei-mips.lo \
+ pei-ppc.lo \
+ pei-sh.lo \
+ peigen.lo \
+ plugin.lo \
+ ppcboot.lo \
+ reloc16.lo \
+ riscix.lo \
+ som.lo \
+ sparclinux.lo \
+ sparclynx.lo \
+ sparcnetbsd.lo \
+ sunos.lo \
+ vax1knetbsd.lo \
+ vaxbsd.lo \
+ vaxnetbsd.lo \
+ versados.lo \
+ vms-lib.lo \
+ vms-misc.lo \
+ xcofflink.lo \
+ xsym.lo \
+ xtensa-isa.lo \
+ xtensa-modules.lo
+
+BFD32_BACKENDS_CFILES = \
+ aout-adobe.c \
+ aout-arm.c \
+ aout-cris.c \
+ aout-ns32k.c \
+ aout-sparcle.c \
+ aout-tic30.c \
+ aout0.c \
+ aout32.c \
+ armnetbsd.c \
+ bout.c \
+ cf-i386lynx.c \
+ cf-sparclynx.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-mips.c \
+ coff-rs6000.c \
+ coff-sh.c \
+ coff-sparc.c \
+ coff-stgo32.c \
+ coff-svm68k.c \
+ coff-tic30.c \
+ coff-tic4x.c \
+ coff-tic54x.c \
+ coff-tic80.c \
+ coff-u68k.c \
+ coff-w65.c \
+ coff-we32k.c \
+ coff-z80.c \
+ coff-z8k.c \
+ cofflink.c \
+ dwarf1.c \
+ ecoff.c \
+ ecofflink.c \
+ elf-attrs.c \
+ elf-eh-frame.c \
+ elf-ifunc.c \
+ elf-m10200.c \
+ elf-m10300.c \
+ elf-nacl.c \
+ elf-strtab.c \
+ elf-vxworks.c \
+ elf.c \
+ elf32-am33lin.c \
+ elf32-arc.c \
+ elf32-arm.c \
+ elf32-avr.c \
+ elf32-bfin.c \
+ elf32-cr16.c \
+ elf32-cr16c.c \
+ elf32-cris.c \
+ elf32-crx.c \
+ elf32-d10v.c \
+ elf32-d30v.c \
+ elf32-dlx.c \
+ elf32-epiphany.c \
+ elf32-fr30.c \
+ elf32-frv.c \
+ elf32-gen.c \
+ elf32-h8300.c \
+ elf32-hppa.c \
+ elf32-i370.c \
+ elf32-i386.c \
+ elf32-i860.c \
+ elf32-i960.c \
+ elf32-ip2k.c \
+ elf32-iq2000.c \
+ elf32-lm32.c \
+ elf32-m32c.c \
+ elf32-m32r.c \
+ elf32-m68hc11.c \
+ elf32-m68hc12.c \
+ elf32-m68hc1x.c \
+ elf32-m68k.c \
+ elf32-m88k.c \
+ elf32-mcore.c \
+ elf32-mep.c \
+ elf32-metag.c \
+ elf32-microblaze.c \
+ elf32-moxie.c \
+ elf32-msp430.c \
+ elf32-mt.c \
+ elf32-nds32.c \
+ elf32-nios2.c \
+ elf32-or1k.c \
+ elf32-pj.c \
+ elf32-ppc.c \
+ elf32-rl78.c \
+ elf32-rx.c \
+ elf32-s390.c \
+ elf32-sh-symbian.c \
+ elf32-sh.c \
+ elf32-sh64-com.c \
+ elf32-sh64.c \
+ elf32-sparc.c \
+ elf32-spu.c \
+ elf32-tic6x.c \
+ elf32-tilegx.c \
+ elf32-tilepro.c \
+ elf32-v850.c \
+ elf32-vax.c \
+ elf32-xc16x.c \
+ elf32-xgate.c \
+ elf32-xstormy16.c \
+ elf32-xtensa.c \
+ elf32.c \
+ elflink.c \
+ elfxx-sparc.c \
+ elfxx-tilegx.c \
+ epoc-pe-arm.c \
+ epoc-pei-arm.c \
+ hp300bsd.c \
+ hp300hpux.c \
+ i386aout.c \
+ i386bsd.c \
+ i386dynix.c \
+ i386freebsd.c \
+ i386linux.c \
+ i386lynx.c \
+ i386mach3.c \
+ i386msdos.c \
+ i386netbsd.c \
+ i386os9k.c \
+ ieee.c \
+ m68k4knetbsd.c \
+ m68klinux.c \
+ m68knetbsd.c \
+ m88kmach3.c \
+ m88kopenbsd.c \
+ mach-o.c \
+ mach-o-i386.c \
+ mipsbsd.c \
+ newsos3.c \
+ nlm.c \
+ nlm32-i386.c \
+ nlm32-ppc.c \
+ nlm32-sparc.c \
+ nlm32.c \
+ ns32knetbsd.c \
+ oasys.c \
+ pc532-mach.c \
+ pdp11.c \
+ pe-arm-wince.c \
+ pe-arm.c \
+ pe-i386.c \
+ pe-mcore.c \
+ pe-mips.c \
+ pe-ppc.c \
+ pe-sh.c \
+ pef.c \
+ pei-arm-wince.c \
+ pei-arm.c \
+ pei-i386.c \
+ pei-mcore.c \
+ pei-mips.c \
+ pei-ppc.c \
+ pei-sh.c \
+ plugin.c \
+ ppcboot.c \
+ reloc16.c \
+ riscix.c \
+ som.c \
+ sparclinux.c \
+ sparclynx.c \
+ sparcnetbsd.c \
+ sunos.c \
+ vax1knetbsd.c \
+ vaxbsd.c \
+ vaxnetbsd.c \
+ versados.c \
+ vms-lib.c \
+ vms-misc.c \
+ xcofflink.c \
+ xsym.c \
+ xtensa-isa.c \
+ xtensa-modules.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.
+# elf32-ia64.c requires a 64-bit bfd_vma, and hence can not be put in
+# BFD32_BACKENDS.
+BFD64_BACKENDS = \
+ elf32-aarch64.lo \
+ elf64-aarch64.lo \
+ elfxx-aarch64.lo \
+ aix5ppc-core.lo \
+ aout64.lo \
+ coff-alpha.lo \
+ coff-x86_64.lo \
+ coff64-rs6000.lo \
+ demo64.lo \
+ elf32-ia64.lo \
+ elf32-mips.lo \
+ elf32-score.lo \
+ elf32-score7.lo \
+ elf64-alpha.lo \
+ elf64-gen.lo \
+ elf64-hppa.lo \
+ elf64-ia64.lo \
+ elf64-ia64-vms.lo \
+ elf64-mips.lo \
+ elf64-mmix.lo \
+ elf64-ppc.lo \
+ elf64-s390.lo \
+ elf64-sh64.lo \
+ elf64-sparc.lo \
+ elf64-tilegx.lo \
+ elf64-x86-64.lo \
+ elf64.lo \
+ elfn32-mips.lo \
+ elfxx-ia64.lo \
+ elfxx-mips.lo \
+ mach-o-x86-64.lo \
+ mmo.lo \
+ nlm32-alpha.lo \
+ nlm64.lo \
+ pe-x86_64.lo \
+ pei-ia64.lo \
+ pei-x86_64.lo \
+ pepigen.lo \
+ pex64igen.lo \
+ vms-alpha.lo
+
+BFD64_BACKENDS_CFILES = \
+ aix5ppc-core.c \
+ aout64.c \
+ coff-alpha.c \
+ coff-x86_64.c \
+ coff64-rs6000.c \
+ demo64.c \
+ elf32-mips.c \
+ elf32-score.c \
+ elf32-score7.c \
+ elf64-alpha.c \
+ elf64-gen.c \
+ elf64-hppa.c \
+ elf64-ia64-vms.c \
+ elf64-mips.c \
+ elf64-mmix.c \
+ elf64-ppc.c \
+ elf64-s390.c \
+ elf64-sh64.c \
+ elf64-sparc.c \
+ elf64-tilegx.c \
+ elf64-x86-64.c \
+ elf64.c \
+ elfn32-mips.c \
+ elfxx-aarch64.c \
+ elfxx-ia64.c \
+ elfxx-mips.c \
+ mach-o-x86-64.c \
+ mmo.c \
+ nlm32-alpha.c \
+ nlm64.c \
+ pe-x86_64.c \
+ pei-ia64.c \
+ pei-x86_64.c \
+ vms-alpha.c
+
+OPTIONAL_BACKENDS = \
+ aix386-core.lo \
+ cisco-core.lo \
+ hpux-core.lo \
+ irix-core.lo \
+ lynx-core.lo \
+ osf-core.lo \
+ rs6000-core.lo \
+ sco5-core.lo \
+ trad-core.lo
+
+OPTIONAL_BACKENDS_CFILES = \
+ aix386-core.c \
+ cisco-core.c \
+ hpux-core.c \
+ irix-core.c \
+ lynx-core.c \
+ osf-core.c \
+ rs6000-core.c \
+ sco5-core.c \
+ trad-core.c
+
+# Reconfigure if config.bfd or configure.host changes.
+# development.sh is used to determine -Werror default.
+CONFIG_STATUS_DEPENDENCIES = \
+ $(srcdir)/config.bfd \
+ $(srcdir)/configure.host \
+ $(srcdir)/development.sh
+
+# These are defined by configure:
+WORDSIZE = @wordsize@
+ALL_BACKENDS = @all_backends@
+BFD_BACKENDS = @bfd_backends@
+BFD_MACHINES = @bfd_machines@
+TDEFAULTS = @tdefaults@
+HAVEVECS = @havevecs@
+
+INCLUDES = @HDEFINES@ @COREFLAG@ @TDEFINES@ $(CSEARCH) $(CSWITCHES) \
+ $(HAVEVECS) @INCINTL@
+
+# C source files that correspond to .o's.
+SOURCE_CFILES = \
+ $(BFD32_LIBS_CFILES) \
+ $(BFD64_LIBS_CFILES) \
+ $(ALL_MACHINES_CFILES) \
+ $(BFD32_BACKENDS_CFILES) \
+ $(BFD64_BACKENDS_CFILES) \
+ $(OPTIONAL_BACKENDS_CFILES)
+
+BUILD_CFILES = \
+ elf32-aarch64.c elf64-aarch64.c \
+ elf32-ia64.c elf64-ia64.c peigen.c pepigen.c pex64igen.c
+
+CFILES = $(SOURCE_CFILES) $(BUILD_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 \
+ elf-bfd.h elf-hppa.h elf-linux-psinfo.h elf32-hppa.h \
+ elf64-hppa.h elfcode.h elfcore.h \
+ freebsd.h genlink.h go32stub.h \
+ libaout.h libbfd.h libcoff.h libecoff.h libhppa.h libieee.h \
+ libnlm.h liboasys.h libpei.h libxcoff.h mach-o.h \
+ netbsd.h nlm-target.h nlmcode.h nlmswap.h ns32k.h \
+ pef.h pef-traceback.h peicode.h som.h version.h \
+ vms.h xsym.h
+
+## ... and all .h files which are in the build tree.
+BUILD_HFILES = \
+ bfdver.h elf32-target.h elf64-target.h targmatch.h bfd_stdint.h
+
+# Ensure they are built early:
+BUILT_SOURCES = $(BUILD_HFILES)
+
+HFILES = $(SOURCE_HFILES) $(BUILD_HFILES)
+
+SRC_POTFILES = $(SOURCE_CFILES) $(SOURCE_HFILES)
+BLD_POTFILES = $(BUILD_CFILES) $(BUILD_HFILES)
+
+po/SRC-POTFILES.in: @MAINT@ Makefile $(SRC_POTFILES)
+ for file in $(SRC_POTFILES); do echo $$file; done \
+ | LC_ALL=C sort > tmp.src \
+ && mv tmp.src $(srcdir)/po/SRC-POTFILES.in
+
+po/BLD-POTFILES.in: @MAINT@ Makefile $(BLD_POTFILES)
+ for file in $(BLD_POTFILES); do echo $$file; done \
+ | LC_ALL=C sort > tmp.bld \
+ && mv tmp.bld $(srcdir)/po/BLD-POTFILES.in
+
+all 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
+# bfd64_libs Routines for 64bit support
+OFILES = $(BFD_BACKENDS) $(BFD_MACHINES) @COREFILE@ @bfd64_libs@
+
+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
+
+# Since BFD64_LIBS is optional and we can't have substitution in
+# libbfd_la_SOURCES, we put BFD64_LIBS in OFILES instead.
+# However, list all sources in EXTRA_libbfd_la_SOURCES so the
+# dependency tracking fragments are picked up in the Makefile.
+libbfd_la_SOURCES = $(BFD32_LIBS_CFILES)
+EXTRA_libbfd_la_SOURCES = $(CFILES)
+libbfd_la_DEPENDENCIES = $(OFILES) ofiles
+libbfd_la_LIBADD = `cat ofiles` @SHARED_LIBADD@ $(LIBDL)
+libbfd_la_LDFLAGS += -release `cat libtool-soversion` @SHARED_LDFLAGS@
+
+# 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
+ libtooldir=`$(LIBTOOL) --config | sed -n -e 's/^objdir=//p'`; \
+ if [ -f $$libtooldir/libbfd.a ]; then \
+ cp $$libtooldir/libbfd.a libbfd.tmp; \
+ $(RANLIB) 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 Makefile
+if am__fastdepCC
+ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $(TDEFAULTS) $(srcdir)/targets.c
+ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+else
+if AMDEP
+ source='targets.c' object='$@' libtool=yes @AMDEPBACKSLASH@
+ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+endif
+ $(LTCOMPILE) -c -o $@ $(TDEFAULTS) $(srcdir)/targets.c
+endif
+
+archures.lo: archures.c Makefile
+if am__fastdepCC
+ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $(TDEFAULTS) $(srcdir)/archures.c
+ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+else
+if AMDEP
+ source='archures.c' object='$@' libtool=yes @AMDEPBACKSLASH@
+ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+endif
+ $(LTCOMPILE) -c -o $@ $(TDEFAULTS) $(srcdir)/archures.c
+endif
+
+dwarf2.lo: dwarf2.c Makefile
+if am__fastdepCC
+ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ -DDEBUGDIR=\"$(DEBUGDIR)\" $(srcdir)/dwarf2.c
+ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+else
+if AMDEP
+ source='dwarf2.c' object='$@' libtool=yes @AMDEPBACKSLASH@
+ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+endif
+ $(LTCOMPILE) -c -o $@ -DDEBUGDIR=\"$(DEBUGDIR)\" $(srcdir)/dwarf2.c
+endif
+
+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
+
+elf32-aarch64.c : elfnn-aarch64.c
+ rm -f elf32-aarch64.c
+ echo "#line 1 \"$(srcdir)/elfnn-aarch64.c\"" > elf32-aarch64.new
+ sed -e s/NN/32/g < $(srcdir)/elfnn-aarch64.c >> elf32-aarch64.new
+ mv -f elf32-aarch64.new elf32-aarch64.c
+
+elf64-aarch64.c : elfnn-aarch64.c
+ rm -f elf64-aarch64.c
+ echo "#line 1 \"$(srcdir)/elfnn-aarch64.c\"" > elf64-aarch64.new
+ sed -e s/NN/64/g < $(srcdir)/elfnn-aarch64.c >> elf64-aarch64.new
+ mv -f elf64-aarch64.new elf64-aarch64.c
+
+elf32-ia64.c : elfnn-ia64.c
+ rm -f elf32-ia64.c
+ sed -e s/NN/32/g < $(srcdir)/elfnn-ia64.c > elf32-ia64.new
+ mv -f elf32-ia64.new elf32-ia64.c
+
+elf64-ia64.c : elfnn-ia64.c
+ rm -f elf64-ia64.c
+ sed -e s/NN/64/g < $(srcdir)/elfnn-ia64.c > elf64-ia64.new
+ mv -f elf64-ia64.new elf64-ia64.c
+
+peigen.c : peXXigen.c
+ rm -f peigen.c
+ sed -e s/XX/pe/g < $(srcdir)/peXXigen.c > peigen.new
+ mv -f peigen.new peigen.c
+
+pepigen.c : peXXigen.c
+ rm -f pepigen.c
+ sed -e s/XX/pep/g < $(srcdir)/peXXigen.c > pepigen.new
+ mv -f pepigen.new pepigen.c
+
+pex64igen.c: peXXigen.c
+ rm -f pex64igen.c
+ sed -e s/XX/pex64/g < $(srcdir)/peXXigen.c > pex64igen.new
+ mv -f pex64igen.new pex64igen.c
+
+BFD_H_DEPS= $(INCDIR)/ansidecl.h $(INCDIR)/symcat.h
+LOCAL_H_DEPS= libbfd.h sysdep.h config.h
+$(BFD32_LIBS) \
+ $(BFD64_LIBS) \
+ $(ALL_MACHINES) \
+ $(BFD32_BACKENDS) \
+ $(BFD64_BACKENDS) \
+ $(OPTIONAL_BACKENDS): $(BFD_H) $(BFD_H_DEPS) $(LOCAL_H_DEPS)
+
+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 bfdio.c bfdwin.c \
+ archive.c corefile.c targets.c format.c compress.c
+BFD64_H_FILES = archive64.c
+LIBBFD_H_FILES = libbfd-in.h init.c libbfd.c bfdio.c bfdwin.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 $(bfddocdir); $(MAKE) protos $(FLAGS_TO_PASS))
+ cp $(bfddocdir)/bfd.h bfd-in2.h-new
+ $(SHELL) $(srcdir)/../move-if-change bfd-in2.h-new $(srcdir)/bfd-in2.h
+ cp $(bfddocdir)/libbfd.h libbfd.h-new
+ $(SHELL) $(srcdir)/../move-if-change libbfd.h-new $(srcdir)/libbfd.h
+ cp $(bfddocdir)/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) $(BFD64_H_FILES)
+ (cd $(bfddocdir); $(MAKE) $(FLAGS_TO_PASS) bfd.h)
+ cp $(bfddocdir)/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 $(bfddocdir); $(MAKE) $(FLAGS_TO_PASS) libbfd.h)
+ cp $(bfddocdir)/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 $(bfddocdir); $(MAKE) $(FLAGS_TO_PASS) libcoff.h)
+ cp $(bfddocdir)/libcoff.h libcoff.h-new
+ $(SHELL) $(srcdir)/../move-if-change libcoff.h-new $(srcdir)/libcoff.h
+ touch stmp-lcoff-h
+
+MOSTLYCLEANFILES = ofiles stamp-ofiles
+
+CLEANFILES = bfd.h dep.sed stmp-bfd-h DEP DEPA DEP1 DEP2 libbfd.a stamp-lib \
+ stmp-bin2-h stmp-lbfd-h stmp-lcoff-h
+
+DISTCLEANFILES = $(BUILD_CFILES) $(BUILD_HFILES) libtool-soversion
+
+bfdver.h: $(srcdir)/version.h $(srcdir)/development.sh $(srcdir)/Makefile.in
+ @echo "creating $@"
+ @bfd_version=`echo "$(VERSION)" | sed -e 's/\([^\.]*\)\.*\([^\.]*\)\.*\([^\.]*\)\.*\([^\.]*\)\.*\([^\.]*\).*/\1.00\2.00\3.00\4.00\5/' -e 's/\([^\.]*\)\..*\(..\)\..*\(..\)\..*\(..\)\..*\(..\)$$/\1\2\3\4\5/'` ;\
+ bfd_version_string="\"$(VERSION)\"" ;\
+ bfd_soversion="$(VERSION)" ;\
+ bfd_version_package="\"$(PKGVERSION)\"" ;\
+ report_bugs_to="\"$(REPORT_BUGS_TO)\"" ;\
+ . $(srcdir)/development.sh ;\
+ if test "$$development" = true ; then \
+ bfd_version_date=`sed -n -e 's/.*DATE //p' < $(srcdir)/version.h` ;\
+ bfd_version_string="\"$(VERSION).$${bfd_version_date}\"" ;\
+ bfd_soversion="$(VERSION).$${bfd_version_date}" ;\
+ fi ;\
+ sed -e "s,@bfd_version@,$$bfd_version," \
+ -e "s,@bfd_version_string@,$$bfd_version_string," \
+ -e "s,@bfd_version_package@,$$bfd_version_package," \
+ -e "s,@report_bugs_to@,$$report_bugs_to," \
+ < $(srcdir)/version.h > $@; \
+ echo "$${bfd_soversion}" > libtool-soversion
+
+# Disable -Werror, if it has been enabled, since coffswap.h won't
+# compile with gcc 4.5 and above.
+coff-tic4x.lo: coff-tic4x.c
+@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< $(NO_WERROR)
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< $(NO_WERROR)
+
+coff-tic54x.lo: coff-tic54x.c
+@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< $(NO_WERROR)
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< $(NO_WERROR)
diff --git a/bfd/Makefile.in b/bfd/Makefile.in
new file mode 100644
index 0000000..2c385d5
--- /dev/null
+++ b/bfd/Makefile.in
@@ -0,0 +1,2123 @@
+# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009 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.
+
+@SET_MAKE@
+
+#
+# Copyright (C) 2012-2014 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 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 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 COPYING3. If not see
+# <http://www.gnu.org/licenses/>.
+#
+
+
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+target_triplet = @target@
+@INSTALL_LIBBFD_FALSE@am__append_1 = -rpath $(rpath_bfdlibdir)
+@PLUGINS_TRUE@am__append_2 = $(INCDIR)/plugin-api.h
+subdir = .
+DIST_COMMON = README ChangeLog $(srcdir)/Makefile.in \
+ $(srcdir)/Makefile.am $(top_srcdir)/configure \
+ $(am__configure_deps) $(srcdir)/config.in \
+ $(srcdir)/../mkinstalldirs $(srcdir)/bfd-in2.h \
+ $(top_srcdir)/po/Make-in $(srcdir)/../depcomp \
+ $(am__bfdinclude_HEADERS_DIST)
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/../config/acx.m4 \
+ $(top_srcdir)/../config/depstand.m4 \
+ $(top_srcdir)/../config/gettext-sister.m4 \
+ $(top_srcdir)/../config/largefile.m4 \
+ $(top_srcdir)/../config/lead-dot.m4 \
+ $(top_srcdir)/../config/nls.m4 \
+ $(top_srcdir)/../config/override.m4 \
+ $(top_srcdir)/../config/plugins.m4 \
+ $(top_srcdir)/../config/po.m4 \
+ $(top_srcdir)/../config/progtest.m4 \
+ $(top_srcdir)/../config/stdint.m4 $(top_srcdir)/../libtool.m4 \
+ $(top_srcdir)/../ltoptions.m4 $(top_srcdir)/../ltsugar.m4 \
+ $(top_srcdir)/../ltversion.m4 $(top_srcdir)/../lt~obsolete.m4 \
+ $(top_srcdir)/bfd.m4 $(top_srcdir)/warning.m4 \
+ $(top_srcdir)/acinclude.m4 $(top_srcdir)/../config/zlib.m4 \
+ $(top_srcdir)/version.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
+ configure.lineno config.status.lineno
+mkinstalldirs = $(SHELL) $(top_srcdir)/../mkinstalldirs
+CONFIG_HEADER = config.h
+CONFIG_CLEAN_FILES = bfd-in3.h po/Makefile.in
+CONFIG_CLEAN_VPATH_FILES =
+LIBRARIES = $(noinst_LIBRARIES)
+ARFLAGS = cru
+libbfd_a_AR = $(AR) $(ARFLAGS)
+libbfd_a_LIBADD =
+am_libbfd_a_OBJECTS =
+libbfd_a_OBJECTS = $(am_libbfd_a_OBJECTS)
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__installdirs = "$(DESTDIR)$(bfdlibdir)" \
+ "$(DESTDIR)$(bfdincludedir)"
+LTLIBRARIES = $(bfdlib_LTLIBRARIES) $(noinst_LTLIBRARIES)
+am__DEPENDENCIES_1 =
+am__objects_1 = archive.lo archures.lo bfd.lo bfdio.lo bfdwin.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 merge.lo dwarf2.lo simple.lo compress.lo \
+ verilog.lo
+am_libbfd_la_OBJECTS = $(am__objects_1)
+libbfd_la_OBJECTS = $(am_libbfd_la_OBJECTS)
+libbfd_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(libbfd_la_LDFLAGS) $(LDFLAGS) -o $@
+@INSTALL_LIBBFD_FALSE@am_libbfd_la_rpath =
+@INSTALL_LIBBFD_TRUE@am_libbfd_la_rpath = -rpath $(bfdlibdir)
+DEFAULT_INCLUDES = -I.@am__isrc@
+depcomp = $(SHELL) $(top_srcdir)/../depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+SOURCES = $(libbfd_a_SOURCES) $(libbfd_la_SOURCES) \
+ $(EXTRA_libbfd_la_SOURCES)
+RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
+ html-recursive info-recursive install-data-recursive \
+ install-dvi-recursive install-exec-recursive \
+ install-html-recursive install-info-recursive \
+ install-pdf-recursive install-ps-recursive install-recursive \
+ installcheck-recursive installdirs-recursive pdf-recursive \
+ ps-recursive uninstall-recursive
+am__bfdinclude_HEADERS_DIST = $(INCDIR)/plugin-api.h bfd.h \
+ $(INCDIR)/ansidecl.h $(INCDIR)/symcat.h $(INCDIR)/bfdlink.h
+HEADERS = $(bfdinclude_HEADERS)
+RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
+ distclean-recursive maintainer-clean-recursive
+AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \
+ $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS
+ETAGS = etags
+CTAGS = ctags
+DIST_SUBDIRS = $(SUBDIRS)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BFD_HOSTPTR_T = @BFD_HOSTPTR_T@
+BFD_HOST_64BIT_LONG = @BFD_HOST_64BIT_LONG@
+BFD_HOST_64BIT_LONG_LONG = @BFD_HOST_64BIT_LONG_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@
+CCDEPMODE = @CCDEPMODE@
+CC_FOR_BUILD = @CC_FOR_BUILD@
+CFLAGS = @CFLAGS@
+COREFILE = @COREFILE@
+COREFLAG = @COREFLAG@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DATADIRNAME = @DATADIRNAME@
+DEBUGDIR = @DEBUGDIR@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+EXEEXT_FOR_BUILD = @EXEEXT_FOR_BUILD@
+FGREP = @FGREP@
+GENCAT = @GENCAT@
+GMSGFMT = @GMSGFMT@
+GREP = @GREP@
+HDEFINES = @HDEFINES@
+INCINTL = @INCINTL@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INSTOBJEXT = @INSTOBJEXT@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBINTL = @LIBINTL@
+LIBINTL_DEP = @LIBINTL_DEP@
+LIBM = @LIBM@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+MKINSTALLDIRS = @MKINSTALLDIRS@
+MSGFMT = @MSGFMT@
+MSGMERGE = @MSGMERGE@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NO_WERROR = @NO_WERROR@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKGVERSION = @PKGVERSION@
+POSUB = @POSUB@
+RANLIB = @RANLIB@
+REPORT_BUGS_TEXI = @REPORT_BUGS_TEXI@
+REPORT_BUGS_TO = @REPORT_BUGS_TO@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHARED_LDFLAGS = @SHARED_LDFLAGS@
+SHARED_LIBADD = @SHARED_LIBADD@
+SHELL = @SHELL@
+STRIP = @STRIP@
+TDEFINES = @TDEFINES@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+WARN_CFLAGS = @WARN_CFLAGS@
+XGETTEXT = @XGETTEXT@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+all_backends = @all_backends@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bfd64_libs = @bfd64_libs@
+bfd_backends = @bfd_backends@
+bfd_default_target_size = @bfd_default_target_size@
+bfd_file_ptr = @bfd_file_ptr@
+bfd_machines = @bfd_machines@
+bfd_ufile_ptr = @bfd_ufile_ptr@
+@INSTALL_LIBBFD_FALSE@bfdincludedir =
+@INSTALL_LIBBFD_TRUE@bfdincludedir = @bfdincludedir@
+# Empty these so that the respective installation directories will not be created.
+@INSTALL_LIBBFD_FALSE@bfdlibdir =
+@INSTALL_LIBBFD_TRUE@bfdlibdir = @bfdlibdir@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+havevecs = @havevecs@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_noncanonical = @host_noncanonical@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+lt_cv_dlopen_libs = @lt_cv_dlopen_libs@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+supports_plugins = @supports_plugins@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_noncanonical = @target_noncanonical@
+target_os = @target_os@
+target_vendor = @target_vendor@
+tdefaults = @tdefaults@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+wordsize = @wordsize@
+AUTOMAKE_OPTIONS = 1.11 no-dist foreign
+ACLOCAL_AMFLAGS = -I . -I .. -I ../config
+INCDIR = $(srcdir)/../include
+CSEARCH = -I. -I$(srcdir) -I$(INCDIR)
+SUBDIRS = doc po
+bfddocdir = doc
+libbfd_la_LDFLAGS = $(am__append_1) -release `cat libtool-soversion` \
+ @SHARED_LDFLAGS@ $(am__empty)
+@INSTALL_LIBBFD_TRUE@bfdlib_LTLIBRARIES = libbfd.la
+@INSTALL_LIBBFD_FALSE@bfdinclude_HEADERS = $(am__append_2)
+@INSTALL_LIBBFD_TRUE@bfdinclude_HEADERS = $(BFD_H) \
+@INSTALL_LIBBFD_TRUE@ $(INCDIR)/ansidecl.h $(INCDIR)/symcat.h \
+@INSTALL_LIBBFD_TRUE@ $(INCDIR)/bfdlink.h $(am__append_2)
+@INSTALL_LIBBFD_FALSE@rpath_bfdlibdir = @bfdlibdir@
+@INSTALL_LIBBFD_FALSE@noinst_LTLIBRARIES = libbfd.la
+AM_CFLAGS = $(WARN_CFLAGS)
+AM_CPPFLAGS = -DBINDIR='"$(bindir)"'
+@PLUGINS_TRUE@LIBDL = @lt_cv_dlopen_libs@
+
+# 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).
+BFD32_LIBS = \
+ archive.lo archures.lo bfd.lo bfdio.lo bfdwin.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 \
+ merge.lo dwarf2.lo simple.lo compress.lo verilog.lo
+
+BFD64_LIBS = archive64.lo
+BFD32_LIBS_CFILES = \
+ archive.c archures.c bfd.c bfdio.c bfdwin.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 \
+ merge.c dwarf2.c simple.c compress.c verilog.c
+
+BFD64_LIBS_CFILES = archive64.c
+
+# This list is alphabetized to make it easier to keep in sync
+# with the decls and initializer in archures.c.
+ALL_MACHINES = \
+ cpu-aarch64.lo \
+ cpu-alpha.lo \
+ cpu-arc.lo \
+ cpu-arm.lo \
+ cpu-avr.lo \
+ cpu-bfin.lo \
+ cpu-cr16.lo \
+ cpu-cr16c.lo \
+ cpu-cris.lo \
+ cpu-crx.lo \
+ cpu-d10v.lo \
+ cpu-d30v.lo \
+ cpu-dlx.lo \
+ cpu-epiphany.lo \
+ cpu-fr30.lo \
+ cpu-frv.lo \
+ cpu-h8300.lo \
+ cpu-h8500.lo \
+ cpu-hppa.lo \
+ cpu-i370.lo \
+ cpu-i386.lo \
+ cpu-l1om.lo \
+ cpu-k1om.lo \
+ cpu-i860.lo \
+ cpu-i960.lo \
+ cpu-ia64.lo \
+ cpu-ip2k.lo \
+ cpu-iq2000.lo \
+ cpu-lm32.lo \
+ cpu-m10200.lo \
+ cpu-m10300.lo \
+ cpu-m32c.lo \
+ cpu-m32r.lo \
+ cpu-m68hc11.lo \
+ cpu-m68hc12.lo \
+ cpu-m9s12x.lo \
+ cpu-m9s12xg.lo \
+ cpu-m68k.lo \
+ cpu-m88k.lo \
+ cpu-mcore.lo \
+ cpu-mep.lo \
+ cpu-metag.lo \
+ cpu-microblaze.lo \
+ cpu-mips.lo \
+ cpu-mmix.lo \
+ cpu-moxie.lo \
+ cpu-msp430.lo \
+ cpu-mt.lo \
+ cpu-nds32.lo \
+ cpu-nios2.lo \
+ cpu-ns32k.lo \
+ cpu-or1k.lo \
+ cpu-pdp11.lo \
+ cpu-pj.lo \
+ cpu-plugin.lo \
+ cpu-powerpc.lo \
+ cpu-rs6000.lo \
+ cpu-rl78.lo \
+ cpu-rx.lo \
+ cpu-s390.lo \
+ cpu-score.lo \
+ cpu-sh.lo \
+ cpu-sparc.lo \
+ cpu-spu.lo \
+ cpu-tic30.lo \
+ cpu-tic4x.lo \
+ cpu-tic54x.lo \
+ cpu-tic6x.lo \
+ cpu-tic80.lo \
+ cpu-tilegx.lo \
+ cpu-tilepro.lo \
+ cpu-v850.lo \
+ cpu-v850_rh850.lo \
+ cpu-vax.lo \
+ cpu-w65.lo \
+ cpu-we32k.lo \
+ cpu-xc16x.lo \
+ cpu-xgate.lo \
+ cpu-xstormy16.lo \
+ cpu-xtensa.lo \
+ cpu-z80.lo \
+ cpu-z8k.lo
+
+ALL_MACHINES_CFILES = \
+ cpu-aarch64.c \
+ cpu-alpha.c \
+ cpu-arc.c \
+ cpu-arm.c \
+ cpu-avr.c \
+ cpu-bfin.c \
+ cpu-cr16.c \
+ cpu-cr16c.c \
+ cpu-cris.c \
+ cpu-crx.c \
+ cpu-d10v.c \
+ cpu-d30v.c \
+ cpu-dlx.c \
+ cpu-epiphany.c \
+ cpu-fr30.c \
+ cpu-frv.c \
+ cpu-h8300.c \
+ cpu-h8500.c \
+ cpu-hppa.c \
+ cpu-i370.c \
+ cpu-i386.c \
+ cpu-l1om.c \
+ cpu-k1om.c \
+ cpu-i860.c \
+ cpu-i960.c \
+ cpu-ia64.c \
+ cpu-ip2k.c \
+ cpu-iq2000.c \
+ cpu-lm32.c \
+ cpu-m10200.c \
+ cpu-m10300.c \
+ cpu-m32c.c \
+ cpu-m32r.c \
+ cpu-m68hc11.c \
+ cpu-m68hc12.c \
+ cpu-m9s12x.c \
+ cpu-m9s12xg.c \
+ cpu-m68k.c \
+ cpu-m88k.c \
+ cpu-mcore.c \
+ cpu-mep.c \
+ cpu-metag.c \
+ cpu-microblaze.c \
+ cpu-mips.c \
+ cpu-mmix.c \
+ cpu-moxie.c \
+ cpu-msp430.c \
+ cpu-mt.c \
+ cpu-nds32.c \
+ cpu-ns32k.c \
+ cpu-nios2.c \
+ cpu-or1k.c \
+ cpu-pdp11.c \
+ cpu-pj.c \
+ cpu-plugin.c \
+ cpu-powerpc.c \
+ cpu-rs6000.c \
+ cpu-rl78.c \
+ cpu-rx.c \
+ cpu-s390.c \
+ cpu-score.c \
+ cpu-sh.c \
+ cpu-sparc.c \
+ cpu-spu.c \
+ cpu-tic30.c \
+ cpu-tic4x.c \
+ cpu-tic54x.c \
+ cpu-tic6x.c \
+ cpu-tic80.c \
+ cpu-tilegx.c \
+ cpu-tilepro.c \
+ cpu-v850.c \
+ cpu-v850_rh850.c \
+ cpu-vax.c \
+ cpu-w65.c \
+ cpu-we32k.c \
+ cpu-xc16x.c \
+ cpu-xgate.c \
+ cpu-xstormy16.c \
+ cpu-xtensa.c \
+ cpu-z80.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-cris.lo \
+ aout-ns32k.lo \
+ aout-sparcle.lo \
+ aout-tic30.lo \
+ aout0.lo \
+ aout32.lo \
+ armnetbsd.lo \
+ bout.lo \
+ cf-i386lynx.lo \
+ cf-sparclynx.lo \
+ coff-apollo.lo \
+ coff-arm.lo \
+ coff-aux.lo \
+ coff-go32.lo \
+ coff-h8300.lo \
+ coff-h8500.lo \
+ coff-i386.lo \
+ coff-i860.lo \
+ coff-i960.lo \
+ coff-m68k.lo \
+ coff-m88k.lo \
+ coff-mips.lo \
+ coff-rs6000.lo \
+ coff-sh.lo \
+ coff-sparc.lo \
+ coff-stgo32.lo \
+ coff-svm68k.lo \
+ coff-tic30.lo \
+ coff-tic4x.lo \
+ coff-tic54x.lo \
+ coff-tic80.lo \
+ coff-u68k.lo \
+ coff-w65.lo \
+ coff-we32k.lo \
+ coff-z80.lo \
+ coff-z8k.lo \
+ cofflink.lo \
+ dwarf1.lo \
+ ecoff.lo \
+ ecofflink.lo \
+ elf-attrs.lo \
+ elf-eh-frame.lo \
+ elf-ifunc.lo \
+ elf-m10200.lo \
+ elf-m10300.lo \
+ elf-nacl.lo \
+ elf-strtab.lo \
+ elf-vxworks.lo \
+ elf.lo \
+ elf32-am33lin.lo \
+ elf32-arc.lo \
+ elf32-arm.lo \
+ elf32-avr.lo \
+ elf32-bfin.lo \
+ elf32-cr16.lo \
+ elf32-cr16c.lo \
+ elf32-cris.lo \
+ elf32-crx.lo \
+ elf32-d10v.lo \
+ elf32-d30v.lo \
+ elf32-dlx.lo \
+ elf32-epiphany.lo \
+ elf32-fr30.lo \
+ elf32-frv.lo \
+ elf32-gen.lo \
+ elf32-h8300.lo \
+ elf32-hppa.lo \
+ elf32-i370.lo \
+ elf32-i386.lo \
+ elf32-i860.lo \
+ elf32-i960.lo \
+ elf32-ip2k.lo \
+ elf32-iq2000.lo \
+ elf32-lm32.lo \
+ elf32-m32c.lo \
+ elf32-m32r.lo \
+ elf32-m68hc11.lo \
+ elf32-m68hc12.lo \
+ elf32-m68hc1x.lo \
+ elf32-m68k.lo \
+ elf32-m88k.lo \
+ elf32-mcore.lo \
+ elf32-mep.lo \
+ elf32-metag.lo \
+ elf32-microblaze.lo \
+ elf32-moxie.lo \
+ elf32-msp430.lo \
+ elf32-mt.lo \
+ elf32-nds32.lo \
+ elf32-nios2.lo \
+ elf32-or1k.lo \
+ elf32-pj.lo \
+ elf32-ppc.lo \
+ elf32-rl78.lo \
+ elf32-rx.lo \
+ elf32-s390.lo \
+ elf32-sh-symbian.lo \
+ elf32-sh.lo \
+ elf32-sh64-com.lo \
+ elf32-sh64.lo \
+ elf32-sparc.lo \
+ elf32-spu.lo \
+ elf32-tic6x.lo \
+ elf32-tilegx.lo \
+ elf32-tilepro.lo \
+ elf32-v850.lo \
+ elf32-vax.lo \
+ elf32-xc16x.lo \
+ elf32-xgate.lo \
+ elf32-xstormy16.lo \
+ elf32-xtensa.lo \
+ elf32.lo \
+ elflink.lo \
+ elfxx-sparc.lo \
+ elfxx-tilegx.lo \
+ epoc-pe-arm.lo \
+ epoc-pei-arm.lo \
+ hp300bsd.lo \
+ hp300hpux.lo \
+ i386aout.lo \
+ i386bsd.lo \
+ i386dynix.lo \
+ i386freebsd.lo \
+ i386linux.lo \
+ i386lynx.lo \
+ i386mach3.lo \
+ i386msdos.lo \
+ i386netbsd.lo \
+ i386os9k.lo \
+ ieee.lo \
+ m68k4knetbsd.lo \
+ m68klinux.lo \
+ m68knetbsd.lo \
+ m88kmach3.lo \
+ m88kopenbsd.lo \
+ mach-o.lo \
+ mach-o-i386.lo \
+ mipsbsd.lo \
+ newsos3.lo \
+ nlm.lo \
+ nlm32-i386.lo \
+ nlm32-ppc.lo \
+ nlm32-sparc.lo \
+ nlm32.lo \
+ ns32knetbsd.lo \
+ oasys.lo \
+ pc532-mach.lo \
+ pdp11.lo \
+ pe-arm-wince.lo \
+ pe-arm.lo \
+ pe-i386.lo \
+ pe-mcore.lo \
+ pe-mips.lo \
+ pe-ppc.lo \
+ pe-sh.lo \
+ pef.lo \
+ pei-arm-wince.lo \
+ pei-arm.lo \
+ pei-i386.lo \
+ pei-mcore.lo \
+ pei-mips.lo \
+ pei-ppc.lo \
+ pei-sh.lo \
+ peigen.lo \
+ plugin.lo \
+ ppcboot.lo \
+ reloc16.lo \
+ riscix.lo \
+ som.lo \
+ sparclinux.lo \
+ sparclynx.lo \
+ sparcnetbsd.lo \
+ sunos.lo \
+ vax1knetbsd.lo \
+ vaxbsd.lo \
+ vaxnetbsd.lo \
+ versados.lo \
+ vms-lib.lo \
+ vms-misc.lo \
+ xcofflink.lo \
+ xsym.lo \
+ xtensa-isa.lo \
+ xtensa-modules.lo
+
+BFD32_BACKENDS_CFILES = \
+ aout-adobe.c \
+ aout-arm.c \
+ aout-cris.c \
+ aout-ns32k.c \
+ aout-sparcle.c \
+ aout-tic30.c \
+ aout0.c \
+ aout32.c \
+ armnetbsd.c \
+ bout.c \
+ cf-i386lynx.c \
+ cf-sparclynx.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-mips.c \
+ coff-rs6000.c \
+ coff-sh.c \
+ coff-sparc.c \
+ coff-stgo32.c \
+ coff-svm68k.c \
+ coff-tic30.c \
+ coff-tic4x.c \
+ coff-tic54x.c \
+ coff-tic80.c \
+ coff-u68k.c \
+ coff-w65.c \
+ coff-we32k.c \
+ coff-z80.c \
+ coff-z8k.c \
+ cofflink.c \
+ dwarf1.c \
+ ecoff.c \
+ ecofflink.c \
+ elf-attrs.c \
+ elf-eh-frame.c \
+ elf-ifunc.c \
+ elf-m10200.c \
+ elf-m10300.c \
+ elf-nacl.c \
+ elf-strtab.c \
+ elf-vxworks.c \
+ elf.c \
+ elf32-am33lin.c \
+ elf32-arc.c \
+ elf32-arm.c \
+ elf32-avr.c \
+ elf32-bfin.c \
+ elf32-cr16.c \
+ elf32-cr16c.c \
+ elf32-cris.c \
+ elf32-crx.c \
+ elf32-d10v.c \
+ elf32-d30v.c \
+ elf32-dlx.c \
+ elf32-epiphany.c \
+ elf32-fr30.c \
+ elf32-frv.c \
+ elf32-gen.c \
+ elf32-h8300.c \
+ elf32-hppa.c \
+ elf32-i370.c \
+ elf32-i386.c \
+ elf32-i860.c \
+ elf32-i960.c \
+ elf32-ip2k.c \
+ elf32-iq2000.c \
+ elf32-lm32.c \
+ elf32-m32c.c \
+ elf32-m32r.c \
+ elf32-m68hc11.c \
+ elf32-m68hc12.c \
+ elf32-m68hc1x.c \
+ elf32-m68k.c \
+ elf32-m88k.c \
+ elf32-mcore.c \
+ elf32-mep.c \
+ elf32-metag.c \
+ elf32-microblaze.c \
+ elf32-moxie.c \
+ elf32-msp430.c \
+ elf32-mt.c \
+ elf32-nds32.c \
+ elf32-nios2.c \
+ elf32-or1k.c \
+ elf32-pj.c \
+ elf32-ppc.c \
+ elf32-rl78.c \
+ elf32-rx.c \
+ elf32-s390.c \
+ elf32-sh-symbian.c \
+ elf32-sh.c \
+ elf32-sh64-com.c \
+ elf32-sh64.c \
+ elf32-sparc.c \
+ elf32-spu.c \
+ elf32-tic6x.c \
+ elf32-tilegx.c \
+ elf32-tilepro.c \
+ elf32-v850.c \
+ elf32-vax.c \
+ elf32-xc16x.c \
+ elf32-xgate.c \
+ elf32-xstormy16.c \
+ elf32-xtensa.c \
+ elf32.c \
+ elflink.c \
+ elfxx-sparc.c \
+ elfxx-tilegx.c \
+ epoc-pe-arm.c \
+ epoc-pei-arm.c \
+ hp300bsd.c \
+ hp300hpux.c \
+ i386aout.c \
+ i386bsd.c \
+ i386dynix.c \
+ i386freebsd.c \
+ i386linux.c \
+ i386lynx.c \
+ i386mach3.c \
+ i386msdos.c \
+ i386netbsd.c \
+ i386os9k.c \
+ ieee.c \
+ m68k4knetbsd.c \
+ m68klinux.c \
+ m68knetbsd.c \
+ m88kmach3.c \
+ m88kopenbsd.c \
+ mach-o.c \
+ mach-o-i386.c \
+ mipsbsd.c \
+ newsos3.c \
+ nlm.c \
+ nlm32-i386.c \
+ nlm32-ppc.c \
+ nlm32-sparc.c \
+ nlm32.c \
+ ns32knetbsd.c \
+ oasys.c \
+ pc532-mach.c \
+ pdp11.c \
+ pe-arm-wince.c \
+ pe-arm.c \
+ pe-i386.c \
+ pe-mcore.c \
+ pe-mips.c \
+ pe-ppc.c \
+ pe-sh.c \
+ pef.c \
+ pei-arm-wince.c \
+ pei-arm.c \
+ pei-i386.c \
+ pei-mcore.c \
+ pei-mips.c \
+ pei-ppc.c \
+ pei-sh.c \
+ plugin.c \
+ ppcboot.c \
+ reloc16.c \
+ riscix.c \
+ som.c \
+ sparclinux.c \
+ sparclynx.c \
+ sparcnetbsd.c \
+ sunos.c \
+ vax1knetbsd.c \
+ vaxbsd.c \
+ vaxnetbsd.c \
+ versados.c \
+ vms-lib.c \
+ vms-misc.c \
+ xcofflink.c \
+ xsym.c \
+ xtensa-isa.c \
+ xtensa-modules.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.
+# elf32-ia64.c requires a 64-bit bfd_vma, and hence can not be put in
+# BFD32_BACKENDS.
+BFD64_BACKENDS = \
+ elf32-aarch64.lo \
+ elf64-aarch64.lo \
+ elfxx-aarch64.lo \
+ aix5ppc-core.lo \
+ aout64.lo \
+ coff-alpha.lo \
+ coff-x86_64.lo \
+ coff64-rs6000.lo \
+ demo64.lo \
+ elf32-ia64.lo \
+ elf32-mips.lo \
+ elf32-score.lo \
+ elf32-score7.lo \
+ elf64-alpha.lo \
+ elf64-gen.lo \
+ elf64-hppa.lo \
+ elf64-ia64.lo \
+ elf64-ia64-vms.lo \
+ elf64-mips.lo \
+ elf64-mmix.lo \
+ elf64-ppc.lo \
+ elf64-s390.lo \
+ elf64-sh64.lo \
+ elf64-sparc.lo \
+ elf64-tilegx.lo \
+ elf64-x86-64.lo \
+ elf64.lo \
+ elfn32-mips.lo \
+ elfxx-ia64.lo \
+ elfxx-mips.lo \
+ mach-o-x86-64.lo \
+ mmo.lo \
+ nlm32-alpha.lo \
+ nlm64.lo \
+ pe-x86_64.lo \
+ pei-ia64.lo \
+ pei-x86_64.lo \
+ pepigen.lo \
+ pex64igen.lo \
+ vms-alpha.lo
+
+BFD64_BACKENDS_CFILES = \
+ aix5ppc-core.c \
+ aout64.c \
+ coff-alpha.c \
+ coff-x86_64.c \
+ coff64-rs6000.c \
+ demo64.c \
+ elf32-mips.c \
+ elf32-score.c \
+ elf32-score7.c \
+ elf64-alpha.c \
+ elf64-gen.c \
+ elf64-hppa.c \
+ elf64-ia64-vms.c \
+ elf64-mips.c \
+ elf64-mmix.c \
+ elf64-ppc.c \
+ elf64-s390.c \
+ elf64-sh64.c \
+ elf64-sparc.c \
+ elf64-tilegx.c \
+ elf64-x86-64.c \
+ elf64.c \
+ elfn32-mips.c \
+ elfxx-aarch64.c \
+ elfxx-ia64.c \
+ elfxx-mips.c \
+ mach-o-x86-64.c \
+ mmo.c \
+ nlm32-alpha.c \
+ nlm64.c \
+ pe-x86_64.c \
+ pei-ia64.c \
+ pei-x86_64.c \
+ vms-alpha.c
+
+OPTIONAL_BACKENDS = \
+ aix386-core.lo \
+ cisco-core.lo \
+ hpux-core.lo \
+ irix-core.lo \
+ lynx-core.lo \
+ osf-core.lo \
+ rs6000-core.lo \
+ sco5-core.lo \
+ trad-core.lo
+
+OPTIONAL_BACKENDS_CFILES = \
+ aix386-core.c \
+ cisco-core.c \
+ hpux-core.c \
+ irix-core.c \
+ lynx-core.c \
+ osf-core.c \
+ rs6000-core.c \
+ sco5-core.c \
+ trad-core.c
+
+
+# Reconfigure if config.bfd or configure.host changes.
+# development.sh is used to determine -Werror default.
+CONFIG_STATUS_DEPENDENCIES = \
+ $(srcdir)/config.bfd \
+ $(srcdir)/configure.host \
+ $(srcdir)/development.sh
+
+
+# These are defined by configure:
+WORDSIZE = @wordsize@
+ALL_BACKENDS = @all_backends@
+BFD_BACKENDS = @bfd_backends@
+BFD_MACHINES = @bfd_machines@
+TDEFAULTS = @tdefaults@
+HAVEVECS = @havevecs@
+INCLUDES = @HDEFINES@ @COREFLAG@ @TDEFINES@ $(CSEARCH) $(CSWITCHES) \
+ $(HAVEVECS) @INCINTL@
+
+
+# C source files that correspond to .o's.
+SOURCE_CFILES = \
+ $(BFD32_LIBS_CFILES) \
+ $(BFD64_LIBS_CFILES) \
+ $(ALL_MACHINES_CFILES) \
+ $(BFD32_BACKENDS_CFILES) \
+ $(BFD64_BACKENDS_CFILES) \
+ $(OPTIONAL_BACKENDS_CFILES)
+
+BUILD_CFILES = \
+ elf32-aarch64.c elf64-aarch64.c \
+ elf32-ia64.c elf64-ia64.c peigen.c pepigen.c pex64igen.c
+
+CFILES = $(SOURCE_CFILES) $(BUILD_CFILES)
+SOURCE_HFILES = \
+ aout-target.h aoutf1.h aoutx.h coffcode.h coffswap.h ecoffswap.h \
+ elf-bfd.h elf-hppa.h elf-linux-psinfo.h elf32-hppa.h \
+ elf64-hppa.h elfcode.h elfcore.h \
+ freebsd.h genlink.h go32stub.h \
+ libaout.h libbfd.h libcoff.h libecoff.h libhppa.h libieee.h \
+ libnlm.h liboasys.h libpei.h libxcoff.h mach-o.h \
+ netbsd.h nlm-target.h nlmcode.h nlmswap.h ns32k.h \
+ pef.h pef-traceback.h peicode.h som.h version.h \
+ vms.h xsym.h
+
+BUILD_HFILES = \
+ bfdver.h elf32-target.h elf64-target.h targmatch.h bfd_stdint.h
+
+
+# Ensure they are built early:
+BUILT_SOURCES = $(BUILD_HFILES)
+HFILES = $(SOURCE_HFILES) $(BUILD_HFILES)
+SRC_POTFILES = $(SOURCE_CFILES) $(SOURCE_HFILES)
+BLD_POTFILES = $(BUILD_CFILES) $(BUILD_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
+# bfd64_libs Routines for 64bit support
+OFILES = $(BFD_BACKENDS) $(BFD_MACHINES) @COREFILE@ @bfd64_libs@
+
+# Since BFD64_LIBS is optional and we can't have substitution in
+# libbfd_la_SOURCES, we put BFD64_LIBS in OFILES instead.
+# However, list all sources in EXTRA_libbfd_la_SOURCES so the
+# dependency tracking fragments are picked up in the Makefile.
+libbfd_la_SOURCES = $(BFD32_LIBS_CFILES)
+EXTRA_libbfd_la_SOURCES = $(CFILES)
+libbfd_la_DEPENDENCIES = $(OFILES) ofiles
+libbfd_la_LIBADD = `cat ofiles` @SHARED_LIBADD@ $(LIBDL)
+
+# 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 $(INCDIR)/symcat.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 bfdio.c bfdwin.c \
+ archive.c corefile.c targets.c format.c compress.c
+
+BFD64_H_FILES = archive64.c
+LIBBFD_H_FILES = libbfd-in.h init.c libbfd.c bfdio.c bfdwin.c \
+ cache.c reloc.c archures.c elf.c
+
+LIBCOFF_H_FILES = libcoff-in.h coffcode.h
+MOSTLYCLEANFILES = ofiles stamp-ofiles
+CLEANFILES = bfd.h dep.sed stmp-bfd-h DEP DEPA DEP1 DEP2 libbfd.a stamp-lib \
+ stmp-bin2-h stmp-lbfd-h stmp-lcoff-h
+
+DISTCLEANFILES = $(BUILD_CFILES) $(BUILD_HFILES) libtool-soversion
+all: $(BUILT_SOURCES) config.h
+ $(MAKE) $(AM_MAKEFLAGS) all-recursive
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+am--refresh:
+ @:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ echo ' cd $(srcdir) && $(AUTOMAKE) --foreign'; \
+ $(am__cd) $(srcdir) && $(AUTOMAKE) --foreign \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ echo ' $(SHELL) ./config.status'; \
+ $(SHELL) ./config.status;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ $(SHELL) ./config.status --recheck
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ $(am__cd) $(srcdir) && $(AUTOCONF)
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)
+$(am__aclocal_m4_deps):
+
+config.h: stamp-h1
+ @if test ! -f $@; then \
+ rm -f stamp-h1; \
+ $(MAKE) $(AM_MAKEFLAGS) stamp-h1; \
+ else :; fi
+
+stamp-h1: $(srcdir)/config.in $(top_builddir)/config.status
+ @rm -f stamp-h1
+ cd $(top_builddir) && $(SHELL) ./config.status config.h
+$(srcdir)/config.in: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ ($(am__cd) $(top_srcdir) && $(AUTOHEADER))
+ rm -f stamp-h1
+ touch $@
+
+distclean-hdr:
+ -rm -f config.h stamp-h1
+bfd-in3.h: $(top_builddir)/config.status $(srcdir)/bfd-in2.h
+ cd $(top_builddir) && $(SHELL) ./config.status $@
+po/Makefile.in: $(top_builddir)/config.status $(top_srcdir)/po/Make-in
+ cd $(top_builddir) && $(SHELL) ./config.status $@
+
+clean-noinstLIBRARIES:
+ -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
+install-bfdlibLTLIBRARIES: $(bfdlib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ test -z "$(bfdlibdir)" || $(MKDIR_P) "$(DESTDIR)$(bfdlibdir)"
+ @list='$(bfdlib_LTLIBRARIES)'; test -n "$(bfdlibdir)" || list=; \
+ list2=; for p in $$list; do \
+ if test -f $$p; then \
+ list2="$$list2 $$p"; \
+ else :; fi; \
+ done; \
+ test -z "$$list2" || { \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(bfdlibdir)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(bfdlibdir)"; \
+ }
+
+uninstall-bfdlibLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(bfdlib_LTLIBRARIES)'; test -n "$(bfdlibdir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(bfdlibdir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(bfdlibdir)/$$f"; \
+ done
+
+clean-bfdlibLTLIBRARIES:
+ -test -z "$(bfdlib_LTLIBRARIES)" || rm -f $(bfdlib_LTLIBRARIES)
+ @list='$(bfdlib_LTLIBRARIES)'; for p in $$list; do \
+ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+ test "$$dir" != "$$p" || dir=.; \
+ echo "rm -f \"$${dir}/so_locations\""; \
+ rm -f "$${dir}/so_locations"; \
+ done
+
+clean-noinstLTLIBRARIES:
+ -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+ @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \
+ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+ test "$$dir" != "$$p" || dir=.; \
+ echo "rm -f \"$${dir}/so_locations\""; \
+ rm -f "$${dir}/so_locations"; \
+ done
+libbfd.la: $(libbfd_la_OBJECTS) $(libbfd_la_DEPENDENCIES)
+ $(libbfd_la_LINK) $(am_libbfd_la_rpath) $(libbfd_la_OBJECTS) $(libbfd_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/aix386-core.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/aix5ppc-core.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/aout-adobe.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/aout-arm.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/aout-cris.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/aout-ns32k.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/aout-sparcle.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/aout-tic30.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/aout0.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/aout32.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/aout64.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/archive.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/archive64.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/archures.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/armnetbsd.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bfd.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bfdio.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bfdwin.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/binary.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bout.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cache.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cf-i386lynx.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cf-sparclynx.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cisco-core.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/coff-alpha.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/coff-apollo.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/coff-arm.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/coff-aux.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/coff-go32.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/coff-h8300.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/coff-h8500.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/coff-i386.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/coff-i860.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/coff-i960.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/coff-m68k.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/coff-m88k.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/coff-mips.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/coff-rs6000.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/coff-sh.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/coff-sparc.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/coff-stgo32.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/coff-svm68k.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/coff-tic30.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/coff-tic4x.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/coff-tic54x.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/coff-tic80.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/coff-u68k.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/coff-w65.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/coff-we32k.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/coff-x86_64.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/coff-z80.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/coff-z8k.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/coff64-rs6000.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/coffgen.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cofflink.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/compress.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/corefile.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-aarch64.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-alpha.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-arc.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-arm.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-avr.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-bfin.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-cr16.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-cr16c.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-cris.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-crx.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-d10v.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-d30v.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-dlx.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-epiphany.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-fr30.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-frv.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-h8300.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-h8500.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-hppa.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-i370.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-i386.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-i860.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-i960.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-ia64.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-ip2k.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-iq2000.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-k1om.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-l1om.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-lm32.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-m10200.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-m10300.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-m32c.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-m32r.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-m68hc11.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-m68hc12.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-m68k.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-m88k.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-m9s12x.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-m9s12xg.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-mcore.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-mep.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-metag.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-microblaze.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-mips.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-mmix.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-moxie.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-msp430.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-mt.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-nds32.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-nios2.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-ns32k.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-or1k.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-pdp11.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-pj.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-plugin.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-powerpc.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-rl78.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-rs6000.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-rx.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-s390.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-score.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-sh.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-sparc.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-spu.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-tic30.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-tic4x.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-tic54x.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-tic6x.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-tic80.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-tilegx.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-tilepro.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-v850.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-v850_rh850.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-vax.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-w65.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-we32k.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-xc16x.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-xgate.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-xstormy16.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-xtensa.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-z80.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-z8k.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/demo64.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf1.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf2.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ecoff.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ecofflink.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf-attrs.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf-eh-frame.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf-ifunc.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf-m10200.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf-m10300.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf-nacl.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf-strtab.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf-vxworks.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32-aarch64.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32-am33lin.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32-arc.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32-arm.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32-avr.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32-bfin.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32-cr16.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32-cr16c.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32-cris.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32-crx.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32-d10v.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32-d30v.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32-dlx.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32-epiphany.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32-fr30.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32-frv.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32-gen.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32-h8300.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32-hppa.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32-i370.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32-i386.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32-i860.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32-i960.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32-ia64.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32-ip2k.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32-iq2000.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32-lm32.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32-m32c.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32-m32r.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32-m68hc11.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32-m68hc12.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32-m68hc1x.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32-m68k.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32-m88k.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32-mcore.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32-mep.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32-metag.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32-microblaze.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32-mips.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32-moxie.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32-msp430.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32-mt.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32-nds32.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32-nios2.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32-or1k.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32-pj.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32-ppc.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32-rl78.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32-rx.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32-s390.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32-score.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32-score7.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32-sh-symbian.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32-sh.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32-sh64-com.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32-sh64.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32-sparc.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32-spu.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32-tic6x.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32-tilegx.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32-tilepro.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32-v850.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32-vax.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32-xc16x.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32-xgate.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32-xstormy16.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32-xtensa.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf64-aarch64.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf64-alpha.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf64-gen.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf64-hppa.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf64-ia64-vms.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf64-ia64.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf64-mips.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf64-mmix.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf64-ppc.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf64-s390.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf64-sh64.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf64-sparc.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf64-tilegx.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf64-x86-64.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf64.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elflink.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elfn32-mips.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elfxx-aarch64.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elfxx-ia64.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elfxx-mips.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elfxx-sparc.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elfxx-tilegx.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/epoc-pe-arm.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/epoc-pei-arm.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/format.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hash.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hp300bsd.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hp300hpux.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hpux-core.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/i386aout.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/i386bsd.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/i386dynix.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/i386freebsd.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/i386linux.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/i386lynx.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/i386mach3.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/i386msdos.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/i386netbsd.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/i386os9k.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ieee.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ihex.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/init.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/irix-core.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libbfd.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/linker.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lynx-core.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/m68k4knetbsd.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/m68klinux.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/m68knetbsd.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/m88kmach3.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/m88kopenbsd.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mach-o-i386.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mach-o-x86-64.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mach-o.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/merge.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mipsbsd.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mmo.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/newsos3.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nlm.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nlm32-alpha.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nlm32-i386.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nlm32-ppc.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nlm32-sparc.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nlm32.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nlm64.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ns32knetbsd.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/oasys.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/opncls.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/osf-core.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pc532-mach.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pdp11.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pe-arm-wince.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pe-arm.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pe-i386.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pe-mcore.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pe-mips.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pe-ppc.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pe-sh.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pe-x86_64.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pef.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pei-arm-wince.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pei-arm.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pei-i386.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pei-ia64.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pei-mcore.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pei-mips.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pei-ppc.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pei-sh.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pei-x86_64.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/peigen.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pepigen.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pex64igen.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/plugin.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ppcboot.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/reloc.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/reloc16.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/riscix.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rs6000-core.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sco5-core.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/section.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simple.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/som.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sparclinux.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sparclynx.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sparcnetbsd.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/srec.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stab-syms.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stabs.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sunos.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/syms.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/targets.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tekhex.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/trad-core.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vax1knetbsd.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vaxbsd.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vaxnetbsd.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/verilog.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/versados.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vms-alpha.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vms-lib.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vms-misc.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xcofflink.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xsym.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xtensa-isa.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xtensa-modules.Plo@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+distclean-libtool:
+ -rm -f libtool config.lt
+install-bfdincludeHEADERS: $(bfdinclude_HEADERS)
+ @$(NORMAL_INSTALL)
+ test -z "$(bfdincludedir)" || $(MKDIR_P) "$(DESTDIR)$(bfdincludedir)"
+ @list='$(bfdinclude_HEADERS)'; test -n "$(bfdincludedir)" || list=; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(bfdincludedir)'"; \
+ $(INSTALL_HEADER) $$files "$(DESTDIR)$(bfdincludedir)" || exit $$?; \
+ done
+
+uninstall-bfdincludeHEADERS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(bfdinclude_HEADERS)'; test -n "$(bfdincludedir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ test -n "$$files" || exit 0; \
+ echo " ( cd '$(DESTDIR)$(bfdincludedir)' && rm -f" $$files ")"; \
+ cd "$(DESTDIR)$(bfdincludedir)" && rm -f $$files
+
+# 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.
+$(RECURSIVE_TARGETS):
+ @fail= failcom='exit 1'; \
+ for f in x $$MAKEFLAGS; do \
+ case $$f in \
+ *=* | --[!k]*);; \
+ *k*) failcom='fail=yes';; \
+ esac; \
+ done; \
+ 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; \
+ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || eval $$failcom; \
+ done; \
+ if test "$$dot_seen" = "no"; then \
+ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+ fi; test -z "$$fail"
+
+$(RECURSIVE_CLEAN_TARGETS):
+ @fail= failcom='exit 1'; \
+ for f in x $$MAKEFLAGS; do \
+ case $$f in \
+ *=* | --[!k]*);; \
+ *k*) failcom='fail=yes';; \
+ esac; \
+ done; \
+ dot_seen=no; \
+ case "$@" in \
+ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+ *) list='$(SUBDIRS)' ;; \
+ esac; \
+ rev=''; for subdir in $$list; do \
+ if test "$$subdir" = "."; then :; else \
+ rev="$$subdir $$rev"; \
+ fi; \
+ done; \
+ 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; \
+ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || eval $$failcom; \
+ done && test -z "$$fail"
+tags-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
+ done
+ctags-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \
+ done
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: tags-recursive $(HEADERS) $(SOURCES) config.in $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ set x; \
+ here=`pwd`; \
+ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
+ include_option=--etags-include; \
+ empty_fix=.; \
+ else \
+ include_option=--include; \
+ empty_fix=; \
+ fi; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test ! -f $$subdir/TAGS || \
+ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
+ fi; \
+ done; \
+ list='$(SOURCES) $(HEADERS) config.in $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: CTAGS
+CTAGS: ctags-recursive $(HEADERS) $(SOURCES) config.in $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ list='$(SOURCES) $(HEADERS) config.in $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+check-am: all-am
+check: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) check-recursive
+all-am: Makefile $(LIBRARIES) $(LTLIBRARIES) $(HEADERS) config.h
+installdirs: installdirs-recursive
+installdirs-am:
+ for dir in "$(DESTDIR)$(bfdlibdir)" "$(DESTDIR)$(bfdincludedir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) install-recursive
+install-exec: install-exec-recursive
+install-data: install-data-recursive
+uninstall: uninstall-recursive
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-recursive
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+ -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES)
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+ -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+ -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
+clean: clean-recursive
+
+clean-am: clean-bfdlibLTLIBRARIES clean-generic clean-libtool \
+ clean-noinstLIBRARIES clean-noinstLTLIBRARIES mostlyclean-am
+
+distclean: distclean-recursive
+ -rm -f $(am__CONFIG_DISTCLEAN_FILES)
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-hdr distclean-libtool distclean-tags
+
+dvi: dvi-recursive
+
+dvi-am:
+
+html: html-recursive
+
+html-am:
+
+info: info-recursive
+
+info-am:
+
+install-data-am: install-bfdincludeHEADERS install-bfdlibLTLIBRARIES
+
+install-dvi: install-dvi-recursive
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-recursive
+
+install-html-am:
+
+install-info: install-info-recursive
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-recursive
+
+install-pdf-am:
+
+install-ps: install-ps-recursive
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-recursive
+ -rm -f $(am__CONFIG_DISTCLEAN_FILES)
+ -rm -rf $(top_srcdir)/autom4te.cache
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-recursive
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-recursive
+
+pdf-am:
+
+ps: ps-recursive
+
+ps-am:
+
+uninstall-am: uninstall-bfdincludeHEADERS uninstall-bfdlibLTLIBRARIES
+
+.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) all check \
+ ctags-recursive install install-am install-strip \
+ tags-recursive
+
+.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \
+ all all-am am--refresh check check-am clean \
+ clean-bfdlibLTLIBRARIES clean-generic clean-libtool \
+ clean-noinstLIBRARIES clean-noinstLTLIBRARIES ctags \
+ ctags-recursive distclean distclean-compile distclean-generic \
+ distclean-hdr distclean-libtool distclean-tags dvi dvi-am html \
+ html-am info info-am install install-am \
+ install-bfdincludeHEADERS install-bfdlibLTLIBRARIES \
+ install-data install-data-am install-dvi install-dvi-am \
+ install-exec install-exec-am install-html install-html-am \
+ install-info install-info-am install-man install-pdf \
+ install-pdf-am install-ps install-ps-am install-strip \
+ installcheck installcheck-am installdirs installdirs-am \
+ maintainer-clean maintainer-clean-generic mostlyclean \
+ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
+ pdf pdf-am ps ps-am tags tags-recursive uninstall uninstall-am \
+ uninstall-bfdincludeHEADERS uninstall-bfdlibLTLIBRARIES
+
+
+po/SRC-POTFILES.in: @MAINT@ Makefile $(SRC_POTFILES)
+ for file in $(SRC_POTFILES); do echo $$file; done \
+ | LC_ALL=C sort > tmp.src \
+ && mv tmp.src $(srcdir)/po/SRC-POTFILES.in
+
+po/BLD-POTFILES.in: @MAINT@ Makefile $(BLD_POTFILES)
+ for file in $(BLD_POTFILES); do echo $$file; done \
+ | LC_ALL=C sort > tmp.bld \
+ && mv tmp.bld $(srcdir)/po/BLD-POTFILES.in
+
+all 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
+ libtooldir=`$(LIBTOOL) --config | sed -n -e 's/^objdir=//p'`; \
+ if [ -f $$libtooldir/libbfd.a ]; then \
+ cp $$libtooldir/libbfd.a libbfd.tmp; \
+ $(RANLIB) 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 Makefile
+@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $(TDEFAULTS) $(srcdir)/targets.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='targets.c' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $(TDEFAULTS) $(srcdir)/targets.c
+
+archures.lo: archures.c Makefile
+@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $(TDEFAULTS) $(srcdir)/archures.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='archures.c' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $(TDEFAULTS) $(srcdir)/archures.c
+
+dwarf2.lo: dwarf2.c Makefile
+@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ -DDEBUGDIR=\"$(DEBUGDIR)\" $(srcdir)/dwarf2.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='dwarf2.c' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ -DDEBUGDIR=\"$(DEBUGDIR)\" $(srcdir)/dwarf2.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
+
+elf32-aarch64.c : elfnn-aarch64.c
+ rm -f elf32-aarch64.c
+ echo "#line 1 \"$(srcdir)/elfnn-aarch64.c\"" > elf32-aarch64.new
+ sed -e s/NN/32/g < $(srcdir)/elfnn-aarch64.c >> elf32-aarch64.new
+ mv -f elf32-aarch64.new elf32-aarch64.c
+
+elf64-aarch64.c : elfnn-aarch64.c
+ rm -f elf64-aarch64.c
+ echo "#line 1 \"$(srcdir)/elfnn-aarch64.c\"" > elf64-aarch64.new
+ sed -e s/NN/64/g < $(srcdir)/elfnn-aarch64.c >> elf64-aarch64.new
+ mv -f elf64-aarch64.new elf64-aarch64.c
+
+elf32-ia64.c : elfnn-ia64.c
+ rm -f elf32-ia64.c
+ sed -e s/NN/32/g < $(srcdir)/elfnn-ia64.c > elf32-ia64.new
+ mv -f elf32-ia64.new elf32-ia64.c
+
+elf64-ia64.c : elfnn-ia64.c
+ rm -f elf64-ia64.c
+ sed -e s/NN/64/g < $(srcdir)/elfnn-ia64.c > elf64-ia64.new
+ mv -f elf64-ia64.new elf64-ia64.c
+
+peigen.c : peXXigen.c
+ rm -f peigen.c
+ sed -e s/XX/pe/g < $(srcdir)/peXXigen.c > peigen.new
+ mv -f peigen.new peigen.c
+
+pepigen.c : peXXigen.c
+ rm -f pepigen.c
+ sed -e s/XX/pep/g < $(srcdir)/peXXigen.c > pepigen.new
+ mv -f pepigen.new pepigen.c
+
+pex64igen.c: peXXigen.c
+ rm -f pex64igen.c
+ sed -e s/XX/pex64/g < $(srcdir)/peXXigen.c > pex64igen.new
+ mv -f pex64igen.new pex64igen.c
+$(BFD32_LIBS) \
+ $(BFD64_LIBS) \
+ $(ALL_MACHINES) \
+ $(BFD32_BACKENDS) \
+ $(BFD64_BACKENDS) \
+ $(OPTIONAL_BACKENDS): $(BFD_H) $(BFD_H_DEPS) $(LOCAL_H_DEPS)
+
+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 $(bfddocdir); $(MAKE) protos $(FLAGS_TO_PASS))
+ cp $(bfddocdir)/bfd.h bfd-in2.h-new
+ $(SHELL) $(srcdir)/../move-if-change bfd-in2.h-new $(srcdir)/bfd-in2.h
+ cp $(bfddocdir)/libbfd.h libbfd.h-new
+ $(SHELL) $(srcdir)/../move-if-change libbfd.h-new $(srcdir)/libbfd.h
+ cp $(bfddocdir)/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) $(BFD64_H_FILES)
+ (cd $(bfddocdir); $(MAKE) $(FLAGS_TO_PASS) bfd.h)
+ cp $(bfddocdir)/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 $(bfddocdir); $(MAKE) $(FLAGS_TO_PASS) libbfd.h)
+ cp $(bfddocdir)/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 $(bfddocdir); $(MAKE) $(FLAGS_TO_PASS) libcoff.h)
+ cp $(bfddocdir)/libcoff.h libcoff.h-new
+ $(SHELL) $(srcdir)/../move-if-change libcoff.h-new $(srcdir)/libcoff.h
+ touch stmp-lcoff-h
+
+bfdver.h: $(srcdir)/version.h $(srcdir)/development.sh $(srcdir)/Makefile.in
+ @echo "creating $@"
+ @bfd_version=`echo "$(VERSION)" | sed -e 's/\([^\.]*\)\.*\([^\.]*\)\.*\([^\.]*\)\.*\([^\.]*\)\.*\([^\.]*\).*/\1.00\2.00\3.00\4.00\5/' -e 's/\([^\.]*\)\..*\(..\)\..*\(..\)\..*\(..\)\..*\(..\)$$/\1\2\3\4\5/'` ;\
+ bfd_version_string="\"$(VERSION)\"" ;\
+ bfd_soversion="$(VERSION)" ;\
+ bfd_version_package="\"$(PKGVERSION)\"" ;\
+ report_bugs_to="\"$(REPORT_BUGS_TO)\"" ;\
+ . $(srcdir)/development.sh ;\
+ if test "$$development" = true ; then \
+ bfd_version_date=`sed -n -e 's/.*DATE //p' < $(srcdir)/version.h` ;\
+ bfd_version_string="\"$(VERSION).$${bfd_version_date}\"" ;\
+ bfd_soversion="$(VERSION).$${bfd_version_date}" ;\
+ fi ;\
+ sed -e "s,@bfd_version@,$$bfd_version," \
+ -e "s,@bfd_version_string@,$$bfd_version_string," \
+ -e "s,@bfd_version_package@,$$bfd_version_package," \
+ -e "s,@report_bugs_to@,$$report_bugs_to," \
+ < $(srcdir)/version.h > $@; \
+ echo "$${bfd_soversion}" > libtool-soversion
+
+# Disable -Werror, if it has been enabled, since coffswap.h won't
+# compile with gcc 4.5 and above.
+coff-tic4x.lo: coff-tic4x.c
+@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< $(NO_WERROR)
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< $(NO_WERROR)
+
+coff-tic54x.lo: coff-tic54x.c
+@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< $(NO_WERROR)
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< $(NO_WERROR)
+
+# 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 0000000..f4786b3
--- /dev/null
+++ b/bfd/PORTING
@@ -0,0 +1,89 @@
+ 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.ac 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.ac, 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>"
+
+Copyright (C) 2012-2014 Free Software Foundation, Inc.
+
+Copying and distribution of this file, with or without modification,
+are permitted in any medium without royalty provided the copyright
+notice and this notice are preserved.
diff --git a/bfd/README b/bfd/README
new file mode 100644
index 0000000..09fc6c7
--- /dev/null
+++ b/bfd/README
@@ -0,0 +1,55 @@
+BFD is 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-binutils@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.
+
+Copyright (C) 2012-2014 Free Software Foundation, Inc.
+
+Copying and distribution of this file, with or without modification,
+are permitted in any medium without royalty provided the copyright
+notice and this notice are preserved.
diff --git a/bfd/TODO b/bfd/TODO
new file mode 100644
index 0000000..076588a
--- /dev/null
+++ b/bfd/TODO
@@ -0,0 +1,27 @@
+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.
+
+Copyright (C) 2012-2014 Free Software Foundation, Inc.
+
+Copying and distribution of this file, with or without modification,
+are permitted in any medium without royalty provided the copyright
+notice and this notice are preserved.
diff --git a/bfd/acinclude.m4 b/bfd/acinclude.m4
new file mode 100644
index 0000000..31a4bf9
--- /dev/null
+++ b/bfd/acinclude.m4
@@ -0,0 +1,91 @@
+dnl
+dnl Copyright (C) 2012-2014 Free Software Foundation, Inc.
+dnl
+dnl This file is free software; you can redistribute it and/or modify
+dnl it under the terms of the GNU General Public License as published by
+dnl the Free Software Foundation; either version 3 of the License, or
+dnl (at your option) any later version.
+dnl
+dnl This program is distributed in the hope that it will be useful,
+dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
+dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+dnl GNU General Public License for more details.
+dnl
+dnl You should have received a copy of the GNU General Public License
+dnl along with this program; see the file COPYING3. If not see
+dnl <http://www.gnu.org/licenses/>.
+dnl
+
+sinclude([../config/zlib.m4])
+
+dnl See whether we need to use fopen-bin.h rather than fopen-same.h.
+AC_DEFUN([BFD_BINARY_FOPEN],
+[AC_REQUIRE([AC_CANONICAL_TARGET])
+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,
+ [rm -f conftest*
+ echo 'int main () { return 0; }' > conftest.c
+ bfd_cv_build_exeext=
+ ${CC_FOR_BUILD} -o conftest conftest.c 1>&5 2>&5
+ for file in conftest.*; do
+ case $file in
+ *.c | *.o | *.obj | *.ilk | *.pdb) ;;
+ *) bfd_cv_build_exeext=`echo $file | sed -e s/conftest//` ;;
+ esac
+ done
+ rm -f conftest*
+ 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
+
+AC_DEFUN([AM_INSTALL_LIBBFD],
+[AC_MSG_CHECKING([whether to install libbfd])
+ AC_ARG_ENABLE(install-libbfd,
+[ --enable-install-libbfd controls installation of libbfd and related headers],
+ install_libbfd_p=$enableval,
+ if test "${host}" = "${target}" || test "$enable_shared" = "yes"; then
+ install_libbfd_p=yes
+ else
+ install_libbfd_p=no
+ fi)
+ AC_MSG_RESULT($install_libbfd_p)
+ AM_CONDITIONAL(INSTALL_LIBBFD, test $install_libbfd_p = yes)
+ # Need _noncanonical variables for this.
+ ACX_NONCANONICAL_HOST
+ ACX_NONCANONICAL_TARGET
+ # libbfd.a is a host library containing target dependent code
+ bfdlibdir='$(libdir)'
+ bfdincludedir='$(includedir)'
+ if test "${host}" != "${target}"; then
+ bfdlibdir='$(exec_prefix)/$(host_noncanonical)/$(target_noncanonical)/lib'
+ bfdincludedir='$(exec_prefix)/$(host_noncanonical)/$(target_noncanonical)/include'
+ fi
+ AC_SUBST(bfdlibdir)
+ AM_SUBST_NOTMAKE(bfdlibdir)
+ AC_SUBST(bfdincludedir)
+ AM_SUBST_NOTMAKE(bfdincludedir)
+]
+)
diff --git a/bfd/aclocal.m4 b/bfd/aclocal.m4
new file mode 100644
index 0000000..d9e743e
--- /dev/null
+++ b/bfd/aclocal.m4
@@ -0,0 +1,989 @@
+# generated automatically by aclocal 1.11.1 -*- Autoconf -*-
+
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
+# 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
+# This file 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.
+
+m4_ifndef([AC_AUTOCONF_VERSION],
+ [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
+m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.64],,
+[m4_warning([this file was generated for autoconf 2.64.
+You have another version of autoconf. It may work, but is not guaranteed to.
+If you have problems, you may need to regenerate the build system entirely.
+To do so, use the procedure documented by the package, typically `autoreconf'.])])
+
+# Copyright (C) 2002, 2003, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+#
+# This file 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.
+
+# AM_AUTOMAKE_VERSION(VERSION)
+# ----------------------------
+# Automake X.Y traces this macro to ensure aclocal.m4 has been
+# generated from the m4 files accompanying Automake X.Y.
+# (This private macro should not be called outside this file.)
+AC_DEFUN([AM_AUTOMAKE_VERSION],
+[am__api_version='1.11'
+dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
+dnl require some minimum version. Point them to the right macro.
+m4_if([$1], [1.11.1], [],
+ [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
+])
+
+# _AM_AUTOCONF_VERSION(VERSION)
+# -----------------------------
+# aclocal traces this macro to find the Autoconf version.
+# This is a private macro too. Using m4_define simplifies
+# the logic in aclocal, which can simply ignore this definition.
+m4_define([_AM_AUTOCONF_VERSION], [])
+
+# AM_SET_CURRENT_AUTOMAKE_VERSION
+# -------------------------------
+# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
+# This function is AC_REQUIREd by AM_INIT_AUTOMAKE.
+AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
+[AM_AUTOMAKE_VERSION([1.11.1])dnl
+m4_ifndef([AC_AUTOCONF_VERSION],
+ [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
+_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
+
+# AM_AUX_DIR_EXPAND -*- Autoconf -*-
+
+# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc.
+#
+# This file 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.
+
+# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets
+# $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to
+# `$srcdir', `$srcdir/..', or `$srcdir/../..'.
+#
+# Of course, Automake must honor this variable whenever it calls a
+# tool from the auxiliary directory. The problem is that $srcdir (and
+# therefore $ac_aux_dir as well) can be either absolute or relative,
+# depending on how configure is run. This is pretty annoying, since
+# it makes $ac_aux_dir quite unusable in subdirectories: in the top
+# source directory, any form will work fine, but in subdirectories a
+# relative path needs to be adjusted first.
+#
+# $ac_aux_dir/missing
+# fails when called from a subdirectory if $ac_aux_dir is relative
+# $top_srcdir/$ac_aux_dir/missing
+# fails if $ac_aux_dir is absolute,
+# fails when called from a subdirectory in a VPATH build with
+# a relative $ac_aux_dir
+#
+# The reason of the latter failure is that $top_srcdir and $ac_aux_dir
+# are both prefixed by $srcdir. In an in-source build this is usually
+# harmless because $srcdir is `.', but things will broke when you
+# start a VPATH build or use an absolute $srcdir.
+#
+# So we could use something similar to $top_srcdir/$ac_aux_dir/missing,
+# iff we strip the leading $srcdir from $ac_aux_dir. That would be:
+# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"`
+# and then we would define $MISSING as
+# MISSING="\${SHELL} $am_aux_dir/missing"
+# This will work as long as MISSING is not called from configure, because
+# unfortunately $(top_srcdir) has no meaning in configure.
+# However there are other variables, like CC, which are often used in
+# configure, and could therefore not use this "fixed" $ac_aux_dir.
+#
+# Another solution, used here, is to always expand $ac_aux_dir to an
+# absolute PATH. The drawback is that using absolute paths prevent a
+# configured tree to be moved without reconfiguration.
+
+AC_DEFUN([AM_AUX_DIR_EXPAND],
+[dnl Rely on autoconf to set up CDPATH properly.
+AC_PREREQ([2.50])dnl
+# expand $ac_aux_dir to an absolute path
+am_aux_dir=`cd $ac_aux_dir && pwd`
+])
+
+# AM_CONDITIONAL -*- Autoconf -*-
+
+# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005, 2006, 2008
+# Free Software Foundation, Inc.
+#
+# This file 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.
+
+# serial 9
+
+# AM_CONDITIONAL(NAME, SHELL-CONDITION)
+# -------------------------------------
+# Define a conditional.
+AC_DEFUN([AM_CONDITIONAL],
+[AC_PREREQ(2.52)dnl
+ ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])],
+ [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl
+AC_SUBST([$1_TRUE])dnl
+AC_SUBST([$1_FALSE])dnl
+_AM_SUBST_NOTMAKE([$1_TRUE])dnl
+_AM_SUBST_NOTMAKE([$1_FALSE])dnl
+m4_define([_AM_COND_VALUE_$1], [$2])dnl
+if $2; then
+ $1_TRUE=
+ $1_FALSE='#'
+else
+ $1_TRUE='#'
+ $1_FALSE=
+fi
+AC_CONFIG_COMMANDS_PRE(
+[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then
+ AC_MSG_ERROR([[conditional "$1" was never defined.
+Usually this means the macro was only invoked conditionally.]])
+fi])])
+
+# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2009
+# Free Software Foundation, Inc.
+#
+# This file 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.
+
+# serial 10
+
+# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be
+# written in clear, in which case automake, when reading aclocal.m4,
+# will think it sees a *use*, and therefore will trigger all it's
+# C support machinery. Also note that it means that autoscan, seeing
+# CC etc. in the Makefile, will ask for an AC_PROG_CC use...
+
+
+# _AM_DEPENDENCIES(NAME)
+# ----------------------
+# See how the compiler implements dependency checking.
+# NAME is "CC", "CXX", "GCJ", or "OBJC".
+# We try a few techniques and use that to set a single cache variable.
+#
+# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was
+# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular
+# dependency, and given that the user is not expected to run this macro,
+# just rely on AC_PROG_CC.
+AC_DEFUN([_AM_DEPENDENCIES],
+[AC_REQUIRE([AM_SET_DEPDIR])dnl
+AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl
+AC_REQUIRE([AM_MAKE_INCLUDE])dnl
+AC_REQUIRE([AM_DEP_TRACK])dnl
+
+ifelse([$1], CC, [depcc="$CC" am_compiler_list=],
+ [$1], CXX, [depcc="$CXX" am_compiler_list=],
+ [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'],
+ [$1], UPC, [depcc="$UPC" am_compiler_list=],
+ [$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'],
+ [depcc="$$1" am_compiler_list=])
+
+AC_CACHE_CHECK([dependency style of $depcc],
+ [am_cv_$1_dependencies_compiler_type],
+[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
+ # We make a subdir and do the tests there. Otherwise we can end up
+ # making bogus files that we don't know about and never remove. For
+ # instance it was reported that on HP-UX the gcc test will end up
+ # making a dummy file named `D' -- because `-MD' means `put the output
+ # in D'.
+ mkdir conftest.dir
+ # Copy depcomp to subdir because otherwise we won't find it if we're
+ # using a relative directory.
+ cp "$am_depcomp" conftest.dir
+ cd conftest.dir
+ # We will build objects and dependencies in a subdirectory because
+ # it helps to detect inapplicable dependency modes. For instance
+ # both Tru64's cc and ICC support -MD to output dependencies as a
+ # side effect of compilation, but ICC will put the dependencies in
+ # the current directory while Tru64 will put them in the object
+ # directory.
+ mkdir sub
+
+ am_cv_$1_dependencies_compiler_type=none
+ if test "$am_compiler_list" = ""; then
+ am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp`
+ fi
+ am__universal=false
+ m4_case([$1], [CC],
+ [case " $depcc " in #(
+ *\ -arch\ *\ -arch\ *) am__universal=true ;;
+ esac],
+ [CXX],
+ [case " $depcc " in #(
+ *\ -arch\ *\ -arch\ *) am__universal=true ;;
+ esac])
+
+ for depmode in $am_compiler_list; do
+ # Setup a source with many dependencies, because some compilers
+ # like to wrap large dependency lists on column 80 (with \), and
+ # we should not choose a depcomp mode which is confused by this.
+ #
+ # We need to recreate these files for each test, as the compiler may
+ # overwrite some of them when testing with obscure command lines.
+ # This happens at least with the AIX C compiler.
+ : > sub/conftest.c
+ for i in 1 2 3 4 5 6; do
+ echo '#include "conftst'$i'.h"' >> sub/conftest.c
+ # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with
+ # Solaris 8's {/usr,}/bin/sh.
+ touch sub/conftst$i.h
+ done
+ echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
+
+ # We check with `-c' and `-o' for the sake of the "dashmstdout"
+ # mode. It turns out that the SunPro C++ compiler does not properly
+ # handle `-M -o', and we need to detect this. Also, some Intel
+ # versions had trouble with output in subdirs
+ am__obj=sub/conftest.${OBJEXT-o}
+ am__minus_obj="-o $am__obj"
+ case $depmode in
+ gcc)
+ # This depmode causes a compiler race in universal mode.
+ test "$am__universal" = false || continue
+ ;;
+ nosideeffect)
+ # after this tag, mechanisms are not by side-effect, so they'll
+ # only be used when explicitly requested
+ if test "x$enable_dependency_tracking" = xyes; then
+ continue
+ else
+ break
+ fi
+ ;;
+ msvisualcpp | msvcmsys)
+ # This compiler won't grok `-c -o', but also, the minuso test has
+ # not run yet. These depmodes are late enough in the game, and
+ # so weak that their functioning should not be impacted.
+ am__obj=conftest.${OBJEXT-o}
+ am__minus_obj=
+ ;;
+ none) break ;;
+ esac
+ if depmode=$depmode \
+ source=sub/conftest.c object=$am__obj \
+ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
+ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \
+ >/dev/null 2>conftest.err &&
+ grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep $am__obj sub/conftest.Po > /dev/null 2>&1 &&
+ ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
+ # icc doesn't choke on unknown options, it will just issue warnings
+ # or remarks (even with -Werror). So we grep stderr for any message
+ # that says an option was ignored or not supported.
+ # When given -MP, icc 7.0 and 7.1 complain thusly:
+ # icc: Command line warning: ignoring option '-M'; no argument required
+ # The diagnosis changed in icc 8.0:
+ # icc: Command line remark: option '-MP' not supported
+ if (grep 'ignoring option' conftest.err ||
+ grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
+ am_cv_$1_dependencies_compiler_type=$depmode
+ break
+ fi
+ fi
+ done
+
+ cd ..
+ rm -rf conftest.dir
+else
+ am_cv_$1_dependencies_compiler_type=none
+fi
+])
+AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type])
+AM_CONDITIONAL([am__fastdep$1], [
+ test "x$enable_dependency_tracking" != xno \
+ && test "$am_cv_$1_dependencies_compiler_type" = gcc3])
+])
+
+
+# AM_SET_DEPDIR
+# -------------
+# Choose a directory name for dependency files.
+# This macro is AC_REQUIREd in _AM_DEPENDENCIES
+AC_DEFUN([AM_SET_DEPDIR],
+[AC_REQUIRE([AM_SET_LEADING_DOT])dnl
+AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl
+])
+
+
+# AM_DEP_TRACK
+# ------------
+AC_DEFUN([AM_DEP_TRACK],
+[AC_ARG_ENABLE(dependency-tracking,
+[ --disable-dependency-tracking speeds up one-time build
+ --enable-dependency-tracking do not reject slow dependency extractors])
+if test "x$enable_dependency_tracking" != xno; then
+ am_depcomp="$ac_aux_dir/depcomp"
+ AMDEPBACKSLASH='\'
+fi
+AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno])
+AC_SUBST([AMDEPBACKSLASH])dnl
+_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl
+])
+
+# Generate code to set up dependency tracking. -*- Autoconf -*-
+
+# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2008
+# Free Software Foundation, Inc.
+#
+# This file 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.
+
+#serial 5
+
+# _AM_OUTPUT_DEPENDENCY_COMMANDS
+# ------------------------------
+AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
+[{
+ # Autoconf 2.62 quotes --file arguments for eval, but not when files
+ # are listed without --file. Let's play safe and only enable the eval
+ # if we detect the quoting.
+ case $CONFIG_FILES in
+ *\'*) eval set x "$CONFIG_FILES" ;;
+ *) set x $CONFIG_FILES ;;
+ esac
+ shift
+ for mf
+ do
+ # Strip MF so we end up with the name of the file.
+ mf=`echo "$mf" | sed -e 's/:.*$//'`
+ # Check whether this is an Automake generated Makefile or not.
+ # We used to match only the files named `Makefile.in', but
+ # some people rename them; so instead we look at the file content.
+ # Grep'ing the first line is not enough: some people post-process
+ # each Makefile.in and add a new line on top of each file to say so.
+ # Grep'ing the whole file is not good either: AIX grep has a line
+ # limit of 2048, but all sed's we know have understand at least 4000.
+ if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then
+ dirpart=`AS_DIRNAME("$mf")`
+ else
+ continue
+ fi
+ # Extract the definition of DEPDIR, am__include, and am__quote
+ # from the Makefile without running `make'.
+ DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
+ test -z "$DEPDIR" && continue
+ am__include=`sed -n 's/^am__include = //p' < "$mf"`
+ test -z "am__include" && continue
+ am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
+ # When using ansi2knr, U may be empty or an underscore; expand it
+ U=`sed -n 's/^U = //p' < "$mf"`
+ # Find all dependency output files, they are included files with
+ # $(DEPDIR) in their names. We invoke sed twice because it is the
+ # simplest approach to changing $(DEPDIR) to its actual value in the
+ # expansion.
+ for file in `sed -n "
+ s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
+ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do
+ # Make sure the directory exists.
+ test -f "$dirpart/$file" && continue
+ fdir=`AS_DIRNAME(["$file"])`
+ AS_MKDIR_P([$dirpart/$fdir])
+ # echo "creating $dirpart/$file"
+ echo '# dummy' > "$dirpart/$file"
+ done
+ done
+}
+])# _AM_OUTPUT_DEPENDENCY_COMMANDS
+
+
+# AM_OUTPUT_DEPENDENCY_COMMANDS
+# -----------------------------
+# This macro should only be invoked once -- use via AC_REQUIRE.
+#
+# This code is only required when automatic dependency tracking
+# is enabled. FIXME. This creates each `.P' file that we will
+# need in order to bootstrap the dependency handling code.
+AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
+[AC_CONFIG_COMMANDS([depfiles],
+ [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS],
+ [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"])
+])
+
+# Do all the work for Automake. -*- Autoconf -*-
+
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
+# 2005, 2006, 2008, 2009 Free Software Foundation, Inc.
+#
+# This file 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.
+
+# serial 16
+
+# 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.
+
+# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE])
+# AM_INIT_AUTOMAKE([OPTIONS])
+# -----------------------------------------------
+# The call with PACKAGE and VERSION arguments is the old style
+# call (pre autoconf-2.50), which is being phased out. PACKAGE
+# and VERSION should now be passed to AC_INIT and removed from
+# the call to AM_INIT_AUTOMAKE.
+# We support both call styles for the transition. After
+# the next Automake release, Autoconf can make the AC_INIT
+# arguments mandatory, and then we can depend on a new Autoconf
+# release and drop the old call support.
+AC_DEFUN([AM_INIT_AUTOMAKE],
+[AC_PREREQ([2.62])dnl
+dnl Autoconf wants to disallow AM_ names. We explicitly allow
+dnl the ones we care about.
+m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl
+AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl
+AC_REQUIRE([AC_PROG_INSTALL])dnl
+if test "`cd $srcdir && pwd`" != "`pwd`"; then
+ # Use -I$(srcdir) only when $(srcdir) != ., so that make's output
+ # is not polluted with repeated "-I."
+ AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl
+ # test to see if srcdir already configured
+ if test -f $srcdir/config.status; then
+ AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
+ fi
+fi
+
+# test whether we have cygpath
+if test -z "$CYGPATH_W"; then
+ if (cygpath --version) >/dev/null 2>/dev/null; then
+ CYGPATH_W='cygpath -w'
+ else
+ CYGPATH_W=echo
+ fi
+fi
+AC_SUBST([CYGPATH_W])
+
+# Define the identity of the package.
+dnl Distinguish between old-style and new-style calls.
+m4_ifval([$2],
+[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl
+ AC_SUBST([PACKAGE], [$1])dnl
+ AC_SUBST([VERSION], [$2])],
+[_AM_SET_OPTIONS([$1])dnl
+dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT.
+m4_if(m4_ifdef([AC_PACKAGE_NAME], 1)m4_ifdef([AC_PACKAGE_VERSION], 1), 11,,
+ [m4_fatal([AC_INIT should be called with package and version arguments])])dnl
+ AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl
+ AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl
+
+_AM_IF_OPTION([no-define],,
+[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package])
+ AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl
+
+# Some tools Automake needs.
+AC_REQUIRE([AM_SANITY_CHECK])dnl
+AC_REQUIRE([AC_ARG_PROGRAM])dnl
+AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version})
+AM_MISSING_PROG(AUTOCONF, autoconf)
+AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version})
+AM_MISSING_PROG(AUTOHEADER, autoheader)
+AM_MISSING_PROG(MAKEINFO, makeinfo)
+AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
+AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl
+AC_REQUIRE([AM_PROG_MKDIR_P])dnl
+# We need awk for the "check" target. The system "awk" is bad on
+# some platforms.
+AC_REQUIRE([AC_PROG_AWK])dnl
+AC_REQUIRE([AC_PROG_MAKE_SET])dnl
+AC_REQUIRE([AM_SET_LEADING_DOT])dnl
+_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])],
+ [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])],
+ [_AM_PROG_TAR([v7])])])
+_AM_IF_OPTION([no-dependencies],,
+[AC_PROVIDE_IFELSE([AC_PROG_CC],
+ [_AM_DEPENDENCIES(CC)],
+ [define([AC_PROG_CC],
+ defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_CXX],
+ [_AM_DEPENDENCIES(CXX)],
+ [define([AC_PROG_CXX],
+ defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_OBJC],
+ [_AM_DEPENDENCIES(OBJC)],
+ [define([AC_PROG_OBJC],
+ defn([AC_PROG_OBJC])[_AM_DEPENDENCIES(OBJC)])])dnl
+])
+_AM_IF_OPTION([silent-rules], [AC_REQUIRE([AM_SILENT_RULES])])dnl
+dnl The `parallel-tests' driver may need to know about EXEEXT, so add the
+dnl `am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This macro
+dnl is hooked onto _AC_COMPILER_EXEEXT early, see below.
+AC_CONFIG_COMMANDS_PRE(dnl
+[m4_provide_if([_AM_COMPILER_EXEEXT],
+ [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl
+])
+
+dnl Hook into `_AC_COMPILER_EXEEXT' early to learn its expansion. Do not
+dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further
+dnl mangled by Autoconf and run in a shell conditional statement.
+m4_define([_AC_COMPILER_EXEEXT],
+m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])])
+
+
+# When config.status generates a header, we must update the stamp-h file.
+# This file resides in the same directory as the config header
+# that is generated. The stamp files are numbered to have different names.
+
+# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the
+# loop where config.status creates the headers, so we can generate
+# our stamp files there.
+AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK],
+[# Compute $1's index in $config_headers.
+_am_arg=$1
+_am_stamp_count=1
+for _am_header in $config_headers :; do
+ case $_am_header in
+ $_am_arg | $_am_arg:* )
+ break ;;
+ * )
+ _am_stamp_count=`expr $_am_stamp_count + 1` ;;
+ esac
+done
+echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count])
+
+# Copyright (C) 2001, 2003, 2005, 2008 Free Software Foundation, Inc.
+#
+# This file 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.
+
+# AM_PROG_INSTALL_SH
+# ------------------
+# Define $install_sh.
+AC_DEFUN([AM_PROG_INSTALL_SH],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+if test x"${install_sh}" != xset; then
+ case $am_aux_dir in
+ *\ * | *\ *)
+ install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;;
+ *)
+ install_sh="\${SHELL} $am_aux_dir/install-sh"
+ esac
+fi
+AC_SUBST(install_sh)])
+
+# Add --enable-maintainer-mode option to configure. -*- Autoconf -*-
+# From Jim Meyering
+
+# Copyright (C) 1996, 1998, 2000, 2001, 2002, 2003, 2004, 2005, 2008
+# Free Software Foundation, Inc.
+#
+# This file 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.
+
+# serial 5
+
+# AM_MAINTAINER_MODE([DEFAULT-MODE])
+# ----------------------------------
+# Control maintainer-specific portions of Makefiles.
+# Default is to disable them, unless `enable' is passed literally.
+# For symmetry, `disable' may be passed as well. Anyway, the user
+# can override the default with the --enable/--disable switch.
+AC_DEFUN([AM_MAINTAINER_MODE],
+[m4_case(m4_default([$1], [disable]),
+ [enable], [m4_define([am_maintainer_other], [disable])],
+ [disable], [m4_define([am_maintainer_other], [enable])],
+ [m4_define([am_maintainer_other], [enable])
+ m4_warn([syntax], [unexpected argument to AM@&t@_MAINTAINER_MODE: $1])])
+AC_MSG_CHECKING([whether to am_maintainer_other maintainer-specific portions of Makefiles])
+ dnl maintainer-mode's default is 'disable' unless 'enable' is passed
+ AC_ARG_ENABLE([maintainer-mode],
+[ --][am_maintainer_other][-maintainer-mode am_maintainer_other make rules and dependencies not useful
+ (and sometimes confusing) to the casual installer],
+ [USE_MAINTAINER_MODE=$enableval],
+ [USE_MAINTAINER_MODE=]m4_if(am_maintainer_other, [enable], [no], [yes]))
+ AC_MSG_RESULT([$USE_MAINTAINER_MODE])
+ AM_CONDITIONAL([MAINTAINER_MODE], [test $USE_MAINTAINER_MODE = yes])
+ MAINT=$MAINTAINER_MODE_TRUE
+ AC_SUBST([MAINT])dnl
+]
+)
+
+AU_DEFUN([jm_MAINTAINER_MODE], [AM_MAINTAINER_MODE])
+
+# Check to see how 'make' treats includes. -*- Autoconf -*-
+
+# Copyright (C) 2001, 2002, 2003, 2005, 2009 Free Software Foundation, Inc.
+#
+# This file 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.
+
+# serial 4
+
+# AM_MAKE_INCLUDE()
+# -----------------
+# Check to see how make treats includes.
+AC_DEFUN([AM_MAKE_INCLUDE],
+[am_make=${MAKE-make}
+cat > confinc << 'END'
+am__doit:
+ @echo this is the am__doit target
+.PHONY: am__doit
+END
+# If we don't find an include directive, just comment out the code.
+AC_MSG_CHECKING([for style of include used by $am_make])
+am__include="#"
+am__quote=
+_am_result=none
+# First try GNU make style include.
+echo "include confinc" > confmf
+# Ignore all kinds of additional output from `make'.
+case `$am_make -s -f confmf 2> /dev/null` in #(
+*the\ am__doit\ target*)
+ am__include=include
+ am__quote=
+ _am_result=GNU
+ ;;
+esac
+# Now try BSD make style include.
+if test "$am__include" = "#"; then
+ echo '.include "confinc"' > confmf
+ case `$am_make -s -f confmf 2> /dev/null` in #(
+ *the\ am__doit\ target*)
+ am__include=.include
+ am__quote="\""
+ _am_result=BSD
+ ;;
+ esac
+fi
+AC_SUBST([am__include])
+AC_SUBST([am__quote])
+AC_MSG_RESULT([$_am_result])
+rm -f confinc confmf
+])
+
+# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*-
+
+# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2004, 2005, 2008
+# Free Software Foundation, Inc.
+#
+# This file 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.
+
+# serial 6
+
+# AM_MISSING_PROG(NAME, PROGRAM)
+# ------------------------------
+AC_DEFUN([AM_MISSING_PROG],
+[AC_REQUIRE([AM_MISSING_HAS_RUN])
+$1=${$1-"${am_missing_run}$2"}
+AC_SUBST($1)])
+
+
+# AM_MISSING_HAS_RUN
+# ------------------
+# Define MISSING if not defined so far and test if it supports --run.
+# If it does, set am_missing_run to use it, otherwise, to nothing.
+AC_DEFUN([AM_MISSING_HAS_RUN],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+AC_REQUIRE_AUX_FILE([missing])dnl
+if test x"${MISSING+set}" != xset; then
+ case $am_aux_dir in
+ *\ * | *\ *)
+ MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;;
+ *)
+ MISSING="\${SHELL} $am_aux_dir/missing" ;;
+ esac
+fi
+# Use eval to expand $SHELL
+if eval "$MISSING --run true"; then
+ am_missing_run="$MISSING --run "
+else
+ am_missing_run=
+ AC_MSG_WARN([`missing' script is too old or missing])
+fi
+])
+
+# Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+#
+# This file 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.
+
+# AM_PROG_MKDIR_P
+# ---------------
+# Check for `mkdir -p'.
+AC_DEFUN([AM_PROG_MKDIR_P],
+[AC_PREREQ([2.60])dnl
+AC_REQUIRE([AC_PROG_MKDIR_P])dnl
+dnl Automake 1.8 to 1.9.6 used to define mkdir_p. We now use MKDIR_P,
+dnl while keeping a definition of mkdir_p for backward compatibility.
+dnl @MKDIR_P@ is magic: AC_OUTPUT adjusts its value for each Makefile.
+dnl However we cannot define mkdir_p as $(MKDIR_P) for the sake of
+dnl Makefile.ins that do not define MKDIR_P, so we do our own
+dnl adjustment using top_builddir (which is defined more often than
+dnl MKDIR_P).
+AC_SUBST([mkdir_p], ["$MKDIR_P"])dnl
+case $mkdir_p in
+ [[\\/$]]* | ?:[[\\/]]*) ;;
+ */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;;
+esac
+])
+
+# Helper functions for option handling. -*- Autoconf -*-
+
+# Copyright (C) 2001, 2002, 2003, 2005, 2008 Free Software Foundation, Inc.
+#
+# This file 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.
+
+# serial 4
+
+# _AM_MANGLE_OPTION(NAME)
+# -----------------------
+AC_DEFUN([_AM_MANGLE_OPTION],
+[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])])
+
+# _AM_SET_OPTION(NAME)
+# ------------------------------
+# Set option NAME. Presently that only means defining a flag for this option.
+AC_DEFUN([_AM_SET_OPTION],
+[m4_define(_AM_MANGLE_OPTION([$1]), 1)])
+
+# _AM_SET_OPTIONS(OPTIONS)
+# ----------------------------------
+# OPTIONS is a space-separated list of Automake options.
+AC_DEFUN([_AM_SET_OPTIONS],
+[m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])])
+
+# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET])
+# -------------------------------------------
+# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
+AC_DEFUN([_AM_IF_OPTION],
+[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
+
+# Check to make sure that the build environment is sane. -*- Autoconf -*-
+
+# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005, 2008
+# Free Software Foundation, Inc.
+#
+# This file 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.
+
+# serial 5
+
+# AM_SANITY_CHECK
+# ---------------
+AC_DEFUN([AM_SANITY_CHECK],
+[AC_MSG_CHECKING([whether build environment is sane])
+# Just in case
+sleep 1
+echo timestamp > conftest.file
+# Reject unsafe characters in $srcdir or the absolute working directory
+# name. Accept space and tab only in the latter.
+am_lf='
+'
+case `pwd` in
+ *[[\\\"\#\$\&\'\`$am_lf]]*)
+ AC_MSG_ERROR([unsafe absolute working directory name]);;
+esac
+case $srcdir in
+ *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*)
+ AC_MSG_ERROR([unsafe srcdir value: `$srcdir']);;
+esac
+
+# 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" conftest.file 2> /dev/null`
+ if test "$[*]" = "X"; then
+ # -L didn't work.
+ set X `ls -t "$srcdir/configure" conftest.file`
+ fi
+ rm -f conftest.file
+ if test "$[*]" != "X $srcdir/configure conftest.file" \
+ && test "$[*]" != "X conftest.file $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]" = conftest.file
+ )
+then
+ # Ok.
+ :
+else
+ AC_MSG_ERROR([newly created file is older than distributed files!
+Check your system clock])
+fi
+AC_MSG_RESULT(yes)])
+
+# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc.
+#
+# This file 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.
+
+# AM_PROG_INSTALL_STRIP
+# ---------------------
+# One issue with vendor `install' (even GNU) is that you can't
+# specify the program used to strip binaries. This is especially
+# annoying in cross-compiling environments, where the build's strip
+# is unlikely to handle the host's binaries.
+# Fortunately install-sh will honor a STRIPPROG variable, so we
+# always use install-sh in `make install-strip', and initialize
+# STRIPPROG with the value of the STRIP variable (set by the user).
+AC_DEFUN([AM_PROG_INSTALL_STRIP],
+[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
+# Installed binaries are usually stripped using `strip' when the user
+# run `make install-strip'. However `strip' might not be the right
+# tool to use in cross-compilation environments, therefore Automake
+# will honor the `STRIP' environment variable to overrule this program.
+dnl Don't test for $cross_compiling = yes, because it might be `maybe'.
+if test "$cross_compiling" != no; then
+ AC_CHECK_TOOL([STRIP], [strip], :)
+fi
+INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
+AC_SUBST([INSTALL_STRIP_PROGRAM])])
+
+# Copyright (C) 2006, 2008 Free Software Foundation, Inc.
+#
+# This file 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.
+
+# serial 2
+
+# _AM_SUBST_NOTMAKE(VARIABLE)
+# ---------------------------
+# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in.
+# This macro is traced by Automake.
+AC_DEFUN([_AM_SUBST_NOTMAKE])
+
+# AM_SUBST_NOTMAKE(VARIABLE)
+# ---------------------------
+# Public sister of _AM_SUBST_NOTMAKE.
+AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)])
+
+# Check how to create a tarball. -*- Autoconf -*-
+
+# Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+#
+# This file 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.
+
+# serial 2
+
+# _AM_PROG_TAR(FORMAT)
+# --------------------
+# Check how to create a tarball in format FORMAT.
+# FORMAT should be one of `v7', `ustar', or `pax'.
+#
+# Substitute a variable $(am__tar) that is a command
+# writing to stdout a FORMAT-tarball containing the directory
+# $tardir.
+# tardir=directory && $(am__tar) > result.tar
+#
+# Substitute a variable $(am__untar) that extract such
+# a tarball read from stdin.
+# $(am__untar) < result.tar
+AC_DEFUN([_AM_PROG_TAR],
+[# Always define AMTAR for backward compatibility.
+AM_MISSING_PROG([AMTAR], [tar])
+m4_if([$1], [v7],
+ [am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'],
+ [m4_case([$1], [ustar],, [pax],,
+ [m4_fatal([Unknown tar format])])
+AC_MSG_CHECKING([how to create a $1 tar archive])
+# Loop over all known methods to create a tar archive until one works.
+_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none'
+_am_tools=${am_cv_prog_tar_$1-$_am_tools}
+# Do not fold the above two line into one, because Tru64 sh and
+# Solaris sh will not grok spaces in the rhs of `-'.
+for _am_tool in $_am_tools
+do
+ case $_am_tool in
+ gnutar)
+ for _am_tar in tar gnutar gtar;
+ do
+ AM_RUN_LOG([$_am_tar --version]) && break
+ done
+ am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"'
+ am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"'
+ am__untar="$_am_tar -xf -"
+ ;;
+ plaintar)
+ # Must skip GNU tar: if it does not support --format= it doesn't create
+ # ustar tarball either.
+ (tar --version) >/dev/null 2>&1 && continue
+ am__tar='tar chf - "$$tardir"'
+ am__tar_='tar chf - "$tardir"'
+ am__untar='tar xf -'
+ ;;
+ pax)
+ am__tar='pax -L -x $1 -w "$$tardir"'
+ am__tar_='pax -L -x $1 -w "$tardir"'
+ am__untar='pax -r'
+ ;;
+ cpio)
+ am__tar='find "$$tardir" -print | cpio -o -H $1 -L'
+ am__tar_='find "$tardir" -print | cpio -o -H $1 -L'
+ am__untar='cpio -i -H $1 -d'
+ ;;
+ none)
+ am__tar=false
+ am__tar_=false
+ am__untar=false
+ ;;
+ esac
+
+ # If the value was cached, stop now. We just wanted to have am__tar
+ # and am__untar set.
+ test -n "${am_cv_prog_tar_$1}" && break
+
+ # tar/untar a dummy directory, and stop if the command works
+ rm -rf conftest.dir
+ mkdir conftest.dir
+ echo GrepMe > conftest.dir/file
+ AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar])
+ rm -rf conftest.dir
+ if test -s conftest.tar; then
+ AM_RUN_LOG([$am__untar <conftest.tar])
+ grep GrepMe conftest.dir/file >/dev/null 2>&1 && break
+ fi
+done
+rm -rf conftest.dir
+
+AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool])
+AC_MSG_RESULT([$am_cv_prog_tar_$1])])
+AC_SUBST([am__tar])
+AC_SUBST([am__untar])
+]) # _AM_PROG_TAR
+
+m4_include([../config/acx.m4])
+m4_include([../config/depstand.m4])
+m4_include([../config/gettext-sister.m4])
+m4_include([../config/largefile.m4])
+m4_include([../config/lead-dot.m4])
+m4_include([../config/nls.m4])
+m4_include([../config/override.m4])
+m4_include([../config/plugins.m4])
+m4_include([../config/po.m4])
+m4_include([../config/progtest.m4])
+m4_include([../config/stdint.m4])
+m4_include([../libtool.m4])
+m4_include([../ltoptions.m4])
+m4_include([../ltsugar.m4])
+m4_include([../ltversion.m4])
+m4_include([../lt~obsolete.m4])
+m4_include([bfd.m4])
+m4_include([warning.m4])
+m4_include([acinclude.m4])
diff --git a/bfd/aix386-core.c b/bfd/aix386-core.c
new file mode 100644
index 0000000..d3e2080
--- /dev/null
+++ b/bfd/aix386-core.c
@@ -0,0 +1,269 @@
+/* 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 (C) 1988-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.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 const bfd_target *
+aix386_core_file_p (bfd *abfd)
+{
+ int i, n;
+ unsigned char longbuf[4]; /* Raw bytes of various header fields */
+ bfd_size_type core_size = sizeof (struct corehdr);
+ bfd_size_type amt;
+ struct corehdr *core;
+ struct mergem
+ {
+ struct trad_core_struct coredata;
+ struct corehdr internal_core;
+ } *mergem;
+ flagword flags;
+
+ amt = sizeof (longbuf);
+ if (bfd_bread (longbuf, amt, abfd) != amt)
+ {
+ 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, (file_ptr) 0, 0) != 0)
+ return 0;
+
+ amt = sizeof (struct mergem);
+ mergem = (struct mergem *) bfd_zalloc (abfd, amt);
+ if (mergem == NULL)
+ return 0;
+
+ core = &mergem->internal_core;
+
+ if ((bfd_bread (core, core_size, abfd)) != core_size)
+ {
+ if (bfd_get_error () != bfd_error_system_call)
+ bfd_set_error (bfd_error_wrong_format);
+ loser:
+ bfd_release (abfd, (char *) mergem);
+ abfd->tdata.any = NULL;
+ bfd_section_list_clear (abfd);
+ return 0;
+ }
+
+ set_tdata (abfd, &mergem->coredata);
+ core_hdr (abfd) = core;
+
+ /* Create the sections. */
+ flags = SEC_HAS_CONTENTS;
+ core_regsec (abfd) = bfd_make_section_anyway_with_flags (abfd, ".reg",
+ flags);
+ if (core_regsec (abfd) == NULL)
+ goto loser;
+
+ core_regsec (abfd)->size = sizeof (core->cd_regs);
+ core_regsec (abfd)->vma = (bfd_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]);
+
+ flags = SEC_HAS_CONTENTS;
+ core_reg2sec (abfd) = bfd_make_section_anyway_with_flags (abfd, ".reg2",
+ flags);
+ if (core_reg2sec (abfd) == NULL)
+ /* bfd_release frees everything allocated after it's arg. */
+ goto loser;
+
+ core_reg2sec (abfd)->size = sizeof (core->cd_fpregs);
+ core_reg2sec (abfd)->vma = (bfd_vma) -1;
+ core_reg2sec (abfd)->filepos =
+ (file_ptr) offsetof (struct corehdr, cd_fpregs);
+
+ for (i = 0, n = 0; (i < MAX_CORE_SEGS) && (core->cd_segs[i].cs_type); i++)
+ {
+ const char *sname;
+ flagword flags;
+
+ if (core->cd_segs[i].cs_offset == 0)
+ continue;
+
+ switch (core->cd_segs[i].cs_type)
+ {
+ case COR_TYPE_DATA:
+ sname = ".data";
+ flags = SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS;
+ break;
+ case COR_TYPE_STACK:
+ sname = ".stack";
+ flags = SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS;
+ break;
+ case COR_TYPE_LIBDATA:
+ sname = ".libdata";
+ flags = SEC_ALLOC + SEC_HAS_CONTENTS;
+ break;
+ case COR_TYPE_WRITE:
+ sname = ".writeable";
+ flags = SEC_ALLOC + SEC_HAS_CONTENTS;
+ break;
+ case COR_TYPE_MSC:
+ sname = ".misc";
+ flags = SEC_ALLOC + SEC_HAS_CONTENTS;
+ break;
+ default:
+ sname = ".unknown";
+ flags = SEC_ALLOC + SEC_HAS_CONTENTS;
+ break;
+ }
+ core_section (abfd, n) = bfd_make_section_anyway_with_flags (abfd,
+ sname,
+ flags);
+ if (core_section (abfd, n) == NULL)
+ goto loser;
+
+ core_section (abfd, n)->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;
+ n++;
+ }
+
+ return abfd->xvec;
+}
+
+static char *
+aix386_core_file_failing_command (bfd *abfd)
+{
+ return core_hdr (abfd)->cd_comm;
+}
+
+static int
+aix386_core_file_failing_signal (bfd *abfd)
+{
+ return core_hdr (abfd)->cd_cursig;
+}
+
+#define aix386_core_file_matches_executable_p generic_core_file_matches_executable_p
+
+#define aix386_core_file_pid _bfd_nocore_core_file_pid
+
+/* If somebody calls any byte-swapping routines, shoot them. */
+
+static void
+swap_abort (void)
+{
+ /* This way doesn't require any declaration for ANSI to fuck up. */
+ abort ();
+}
+
+#define NO_GET ((bfd_vma (*) (const void *)) swap_abort)
+#define NO_PUT ((void (*) (bfd_vma, void *)) swap_abort)
+#define NO_GETS ((bfd_signed_vma (*) (const void *)) swap_abort)
+#define NO_GET64 ((bfd_uint64_t (*) (const void *)) swap_abort)
+#define NO_PUT64 ((void (*) (bfd_uint64_t, void *)) swap_abort)
+#define NO_GETS64 ((bfd_int64_t (*) (const void *)) swap_abort)
+
+const bfd_target core_aix386_vec =
+{
+ "aix386-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),
+
+ (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
+ 0, /* leading underscore */
+ ' ', /* ar_pad_char */
+ 16, /* ar_max_namelen */
+ 0, /* match priority. */
+ NO_GET64, NO_GETS64, NO_PUT64,
+ NO_GET, NO_GETS, NO_PUT,
+ NO_GET, NO_GETS, NO_PUT, /* data */
+ NO_GET64, NO_GETS64, NO_PUT64,
+ 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),
+
+ NULL,
+
+ NULL
+};
diff --git a/bfd/aix5ppc-core.c b/bfd/aix5ppc-core.c
new file mode 100644
index 0000000..82593ff
--- /dev/null
+++ b/bfd/aix5ppc-core.c
@@ -0,0 +1,357 @@
+/* IBM RS/6000 "XCOFF" back-end for BFD.
+ Copyright (C) 2001-2014 Free Software Foundation, Inc.
+ Written by Tom Rix
+ Contributed by Red Hat 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+
+const bfd_target *xcoff64_core_p (bfd *);
+bfd_boolean xcoff64_core_file_matches_executable_p (bfd *, bfd *);
+char *xcoff64_core_file_failing_command (bfd *);
+int xcoff64_core_file_failing_signal (bfd *);
+
+#ifdef AIX_5_CORE
+
+#include "libbfd.h"
+
+/* Aix 5.1 system include file. */
+
+/* Need to define this macro so struct ld_info64 get included. */
+#define __LDINFO_PTRACE64__
+#include <sys/ldr.h>
+#include <core.h>
+
+/* The default architecture and machine for matching core files. */
+#define DEFAULT_ARCHITECTURE bfd_arch_powerpc
+#define DEFAULT_MACHINE bfd_mach_ppc_620
+
+#define core_hdr(abfd) ((struct core_dumpxx *) abfd->tdata.any)
+
+#define CHECK_FILE_OFFSET(s, v) \
+ ((bfd_signed_vma)(v) < 0 || (bfd_signed_vma)(v) > (bfd_signed_vma)(s).st_size)
+
+const bfd_target *
+xcoff64_core_p (bfd *abfd)
+{
+ enum bfd_architecture arch;
+ unsigned long mach;
+ struct core_dumpxx core, *new_core_hdr;
+ struct stat statbuf;
+ asection *sec;
+ struct __ld_info64 ldinfo;
+ bfd_vma ld_offset;
+ bfd_size_type i;
+ struct vm_infox vminfo;
+ const bfd_target *return_value = NULL;
+ flagword flags;
+
+ /* Get the header. */
+ if (bfd_seek (abfd, 0, SEEK_SET) != 0)
+ goto xcoff64_core_p_error;
+
+ if (sizeof (struct core_dumpxx)
+ != bfd_bread (&core, sizeof (struct core_dumpxx), abfd))
+ goto xcoff64_core_p_error;
+
+ if (bfd_stat (abfd, &statbuf) < 0)
+ goto xcoff64_core_p_error;
+
+ /* Sanity checks
+ c_flag has CORE_VERSION_1, Aix 4+
+ c_entries = 0 for Aix 4.3+
+ IS_PROC64 is a macro defined in procinfo.h, test for 64 bit process.
+
+ We will still be confused if a Aix 4.3 64 bit core file is
+ copied over to a Aix 5 machine.
+
+ Check file header offsets
+
+ See rs6000-core.c for comment on size of core
+ If there isn't enough of a real core file, bail. */
+
+ if ((CORE_VERSION_1 != (core.c_flag & CORE_VERSION_1))
+ || (0 != core.c_entries)
+ || (! (IS_PROC64 (&core.c_u.U_proc)))
+ || ((CHECK_FILE_OFFSET (statbuf, core.c_fdsinfox)))
+ || ((CHECK_FILE_OFFSET (statbuf, core.c_loader)))
+ || ((CHECK_FILE_OFFSET (statbuf, core.c_loader + core.c_lsize)))
+ || ((CHECK_FILE_OFFSET (statbuf, core.c_thr)))
+ || ((CHECK_FILE_OFFSET (statbuf, core.c_segregion)))
+ || ((CHECK_FILE_OFFSET (statbuf, core.c_stack)))
+ || ((CHECK_FILE_OFFSET (statbuf, core.c_stack + core.c_size)))
+ || ((CHECK_FILE_OFFSET (statbuf, core.c_data)))
+ || ((CHECK_FILE_OFFSET (statbuf, core.c_data + core.c_datasize)))
+ || (! (core.c_flag & UBLOCK_VALID))
+ || (! (core.c_flag & LE_VALID)))
+ goto xcoff64_core_p_error;
+
+ /* Check for truncated stack or general truncating. */
+ if ((! (core.c_flag & USTACK_VALID))
+ || (core.c_flag & CORE_TRUNC))
+ {
+ bfd_set_error (bfd_error_file_truncated);
+
+ return return_value;
+ }
+
+ new_core_hdr = bfd_zalloc (abfd, sizeof (struct core_dumpxx));
+ if (NULL == new_core_hdr)
+ return return_value;
+
+ memcpy (new_core_hdr, &core, sizeof (struct core_dumpxx));
+ /* The core_hdr() macro is no longer used here because it would
+ expand to code relying on gcc's cast-as-lvalue extension,
+ which was removed in gcc 4.0. */
+ abfd->tdata.any = new_core_hdr;
+
+ /* .stack section. */
+ flags = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS;
+ sec = bfd_make_section_anyway_with_flags (abfd, ".stack", flags);
+ if (NULL == sec)
+ return return_value;
+
+ sec->size = core.c_size;
+ sec->vma = core.c_stackorg;
+ sec->filepos = core.c_stack;
+
+ /* .reg section for all registers. */
+ flags = SEC_HAS_CONTENTS | SEC_IN_MEMORY;
+ sec = bfd_make_section_anyway_with_flags (abfd, ".reg", flags);
+ if (NULL == sec)
+ return return_value;
+
+ sec->size = sizeof (struct __context64);
+ sec->vma = 0;
+ sec->filepos = 0;
+ sec->contents = (bfd_byte *)&new_core_hdr->c_flt.r64;
+
+ /* .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. */
+ flags = SEC_HAS_CONTENTS;
+ sec = bfd_make_section_anyway_with_flags (abfd, ".ldinfo", flags);
+ if (NULL == sec)
+ return return_value;
+
+ sec->size = core.c_lsize;
+ sec->vma = 0;
+ sec->filepos = core.c_loader;
+
+ /* AIX 4 adds data sections from loaded objects to the core file,
+ which can be found by examining ldinfo, and anonymously mmapped
+ regions. */
+
+ /* .data section from executable. */
+ flags = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS;
+ sec = bfd_make_section_anyway_with_flags (abfd, ".data", flags);
+ if (NULL == sec)
+ return return_value;
+
+ sec->size = core.c_datasize;
+ sec->vma = core.c_dataorg;
+ sec->filepos = core.c_data;
+
+ /* .data sections from loaded objects. */
+ ld_offset = core.c_loader;
+
+ while (1)
+ {
+ if (bfd_seek (abfd, ld_offset, SEEK_SET) != 0)
+ return return_value;
+
+ if (sizeof (struct __ld_info64) !=
+ bfd_bread (&ldinfo, sizeof (struct __ld_info64), abfd))
+ return return_value;
+
+ if (ldinfo.ldinfo_core)
+ {
+ flags = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS;
+ sec = bfd_make_section_anyway_with_flags (abfd, ".data", flags);
+ if (NULL == sec)
+ return return_value;
+
+ sec->size = ldinfo.ldinfo_datasize;
+ sec->vma = ldinfo.ldinfo_dataorg;
+ sec->filepos = ldinfo.ldinfo_core;
+ }
+
+ if (0 == ldinfo.ldinfo_next)
+ break;
+ ld_offset += ldinfo.ldinfo_next;
+ }
+
+ /* .vmdata sections from anonymously mmapped regions. */
+ if (core.c_vmregions)
+ {
+ if (bfd_seek (abfd, core.c_vmm, SEEK_SET) != 0)
+ return return_value;
+
+ for (i = 0; i < core.c_vmregions; i++)
+ if (sizeof (struct vm_infox) !=
+ bfd_bread (&vminfo, sizeof (struct vm_infox), abfd))
+ return return_value;
+
+ if (vminfo.vminfo_offset)
+ {
+ flags = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS;
+ sec = bfd_make_section_anyway_with_flags (abfd, ".vmdata", flags);
+ if (NULL == sec)
+ return return_value;
+
+ sec->size = vminfo.vminfo_size;
+ sec->vma = vminfo.vminfo_addr;
+ sec->filepos = vminfo.vminfo_offset;
+ }
+ }
+
+ /* Set the architecture and machine. */
+ arch = DEFAULT_ARCHITECTURE;
+ mach = DEFAULT_MACHINE;
+ bfd_default_set_arch_mach (abfd, arch, mach);
+
+ return_value = (bfd_target *) abfd->xvec; /* This is garbage for now. */
+
+ xcoff64_core_p_error:
+ if (bfd_get_error () != bfd_error_system_call)
+ bfd_set_error (bfd_error_wrong_format);
+
+ return return_value;
+}
+
+/* Return `TRUE' if given core is from the given executable. */
+
+bfd_boolean
+xcoff64_core_file_matches_executable_p (bfd *core_bfd, bfd *exec_bfd)
+{
+ struct core_dumpxx core;
+ char *path, *s;
+ size_t alloc;
+ const char *str1, *str2;
+ bfd_boolean return_value = FALSE;
+
+ /* Get the header. */
+ if (bfd_seek (core_bfd, 0, SEEK_SET) != 0)
+ return return_value;
+
+ if (sizeof (struct core_dumpxx) !=
+ bfd_bread (&core, sizeof (struct core_dumpxx), core_bfd))
+ return return_value;
+
+ if (bfd_seek (core_bfd, core.c_loader, SEEK_SET) != 0)
+ return return_value;
+
+ alloc = 100;
+ path = bfd_malloc (alloc);
+ if (path == NULL)
+ return return_value;
+
+ s = path;
+
+ while (1)
+ {
+ if (bfd_bread (s, 1, core_bfd) != 1)
+ goto xcoff64_core_file_matches_executable_p_end_1;
+
+ if (*s == '\0')
+ break;
+ ++s;
+ if (s == path + alloc)
+ {
+ char *n;
+
+ alloc *= 2;
+ n = bfd_realloc (path, alloc);
+ if (n == NULL)
+ goto xcoff64_core_file_matches_executable_p_end_1;
+
+ 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)
+ return_value = TRUE;
+
+ xcoff64_core_file_matches_executable_p_end_1:
+ free (path);
+ return return_value;
+}
+
+char *
+xcoff64_core_file_failing_command (bfd *abfd)
+{
+ struct core_dumpxx *c = core_hdr (abfd);
+ char *return_value = 0;
+
+ if (NULL != c)
+ return_value = c->c_u.U_proc.pi_comm;
+
+ return return_value;
+}
+
+int
+xcoff64_core_file_failing_signal (bfd *abfd)
+{
+ struct core_dumpxx *c = core_hdr (abfd);
+ int return_value = 0;
+
+ if (NULL != c)
+ return_value = c->c_signo;
+
+ return return_value;
+}
+
+#else /* AIX_5_CORE */
+
+const bfd_target *
+xcoff64_core_p (bfd *abfd ATTRIBUTE_UNUSED)
+{
+ bfd_set_error (bfd_error_wrong_format);
+ return 0;
+}
+
+bfd_boolean
+xcoff64_core_file_matches_executable_p (bfd *core_bfd, bfd *exec_bfd)
+{
+ return generic_core_file_matches_executable_p (core_bfd, exec_bfd);
+}
+
+char *
+xcoff64_core_file_failing_command (bfd *abfd ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+int
+xcoff64_core_file_failing_signal (bfd *abfd ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+#endif /* AIX_5_CORE */
diff --git a/bfd/aout-adobe.c b/bfd/aout-adobe.c
new file mode 100644
index 0000000..cfdcc64
--- /dev/null
+++ b/bfd/aout-adobe.c
@@ -0,0 +1,518 @@
+/* BFD back-end for a.out.adobe binaries.
+ Copyright (C) 1990-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+#include "aout/adobe.h"
+#include "aout/stab_gnu.h"
+#include "libaout.h" /* BFD a.out internal data structures. */
+
+/* Forward decl. */
+extern const bfd_target aout_adobe_vec;
+
+/* Swaps the information in an executable header taken from a raw byte
+ stream memory image, into the internal exec_header structure. */
+
+static void
+aout_adobe_swap_exec_header_in (bfd *abfd,
+ struct external_exec *bytes,
+ struct internal_exec *execp)
+{
+ /* Now fill in fields in the execp, from the bytes in the raw data. */
+ execp->a_info = 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. */
+
+static void
+aout_adobe_swap_exec_header_out (bfd *abfd,
+ struct internal_exec *execp,
+ struct external_exec *bytes)
+{
+ /* Now fill in fields in the raw data, from the fields in the exec
+ struct. */
+ 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);
+}
+
+/* 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 (bfd *abfd)
+{
+ struct internal_exec *execp = exec_hdr (abfd);
+ asection *sect;
+ struct external_segdesc ext[1];
+ char *section_name;
+ char try_again[30]; /* Name and number. */
+ char *newname;
+ int trynum;
+ flagword flags;
+
+ /* Architecture and machine type -- unknown in this format. */
+ bfd_set_arch_mach (abfd, bfd_arch_unknown, 0L);
+
+ /* The positions of the string table and symbol table. */
+ obj_str_filepos (abfd) = N_STROFF (*execp);
+ obj_sym_filepos (abfd) = N_SYMOFF (*execp);
+
+ /* Suck up the section information from the file, one section at a time. */
+ for (;;)
+ {
+ bfd_size_type amt = sizeof (*ext);
+ if (bfd_bread ( ext, amt, abfd) != amt)
+ {
+ if (bfd_get_error () != bfd_error_system_call)
+ bfd_set_error (bfd_error_wrong_format);
+
+ return NULL;
+ }
+ switch (ext->e_type[0])
+ {
+ case N_TEXT:
+ section_name = ".text";
+ flags = SEC_CODE | SEC_LOAD | SEC_ALLOC | SEC_HAS_CONTENTS;
+ break;
+
+ case N_DATA:
+ section_name = ".data";
+ flags = SEC_DATA | SEC_LOAD | SEC_ALLOC | SEC_HAS_CONTENTS;
+ break;
+
+ case N_BSS:
+ section_name = ".bss";
+ flags = SEC_DATA | SEC_HAS_CONTENTS;
+ break;
+
+ case 0:
+ goto no_more_sections;
+
+ default:
+ (*_bfd_error_handler)
+ (_("%B: Unknown section type in a.out.adobe file: %x\n"),
+ abfd, ext->e_type[0]);
+ goto no_more_sections;
+ }
+
+ /* First one is called ".text" or whatever; subsequent ones are
+ ".text1", ".text2", ... */
+ bfd_set_error (bfd_error_no_error);
+ sect = bfd_make_section_with_flags (abfd, section_name, flags);
+ trynum = 0;
+
+ while (!sect)
+ {
+ if (bfd_get_error () != bfd_error_no_error)
+ /* Some other error -- slide into the sunset. */
+ return NULL;
+ sprintf (try_again, "%s%d", section_name, ++trynum);
+ sect = bfd_make_section_with_flags (abfd, try_again, flags);
+ }
+
+ /* Fix the name, if it is a sprintf'd name. */
+ if (sect->name == try_again)
+ {
+ amt = strlen (sect->name);
+ newname = bfd_zalloc (abfd, amt);
+ if (newname == NULL)
+ return NULL;
+ strcpy (newname, sect->name);
+ sect->name = newname;
+ }
+
+ /* Assumed big-endian. */
+ sect->size = ((ext->e_size[0] << 8)
+ | ext->e_size[1] << 8
+ | ext->e_size[2]);
+ sect->vma = H_GET_32 (abfd, ext->e_virtbase);
+ sect->filepos = H_GET_32 (abfd, ext->e_filebase);
+ /* FIXME XXX alignment? */
+
+ /* Set relocation information for first section of each type. */
+ if (trynum == 0)
+ switch (ext->e_type[0])
+ {
+ case N_TEXT:
+ sect->rel_filepos = N_TRELOFF (*execp);
+ sect->reloc_count = execp->a_trsize;
+ break;
+
+ case N_DATA:
+ sect->rel_filepos = N_DRELOFF (*execp);
+ sect->reloc_count = execp->a_drsize;
+ break;
+
+ default:
+ break;
+ }
+ }
+ no_more_sections:
+
+ adata (abfd).reloc_entry_size = sizeof (struct reloc_std_external);
+ adata (abfd).symbol_entry_size = sizeof (struct external_nlist);
+ adata (abfd).page_size = 1; /* Not applicable. */
+ adata (abfd).segment_size = 1; /* Not applicable. */
+ adata (abfd).exec_bytes_size = EXEC_BYTES_SIZE;
+
+ return abfd->xvec;
+}
+
+static const bfd_target *
+aout_adobe_object_p (bfd *abfd)
+{
+ struct internal_exec anexec;
+ struct external_exec exec_bytes;
+ char *targ;
+ bfd_size_type amt = EXEC_BYTES_SIZE;
+
+ if (bfd_bread (& exec_bytes, amt, abfd) != amt)
+ {
+ if (bfd_get_error () != bfd_error_system_call)
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+
+ anexec.a_info = 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, aout_adobe_vec.name))
+ /* Just continue anyway, if specifically set to this format. */
+ ;
+ else
+ {
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+ }
+
+ aout_adobe_swap_exec_header_in (abfd, &exec_bytes, &anexec);
+ return aout_32_some_aout_object_p (abfd, &anexec, aout_adobe_callback);
+}
+
+struct bout_data_struct
+{
+ struct aoutdata a;
+ struct internal_exec e;
+};
+
+static bfd_boolean
+aout_adobe_mkobject (bfd *abfd)
+{
+ struct bout_data_struct *rawptr;
+ bfd_size_type amt = sizeof (struct bout_data_struct);
+
+ rawptr = bfd_zalloc (abfd, amt);
+ 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 void
+aout_adobe_write_section (bfd *abfd ATTRIBUTE_UNUSED,
+ sec_ptr sect ATTRIBUTE_UNUSED)
+{
+ /* FIXME XXX. */
+}
+
+static bfd_boolean
+aout_adobe_write_object_contents (bfd *abfd)
+{
+ struct external_exec swapped_hdr;
+ static struct external_segdesc sentinel[1]; /* Initialized to zero. */
+ asection *sect;
+ bfd_size_type amt;
+
+ exec_hdr (abfd)->a_info = ZMAGIC;
+
+ /* Calculate text size as total of text sections, etc. */
+ exec_hdr (abfd)->a_text = 0;
+ exec_hdr (abfd)->a_data = 0;
+ exec_hdr (abfd)->a_bss = 0;
+ exec_hdr (abfd)->a_trsize = 0;
+ exec_hdr (abfd)->a_drsize = 0;
+
+ for (sect = abfd->sections; sect; sect = sect->next)
+ {
+ if (sect->flags & SEC_CODE)
+ {
+ exec_hdr (abfd)->a_text += sect->size;
+ exec_hdr (abfd)->a_trsize += sect->reloc_count *
+ sizeof (struct reloc_std_external);
+ }
+ else if (sect->flags & SEC_DATA)
+ {
+ exec_hdr (abfd)->a_data += sect->size;
+ exec_hdr (abfd)->a_drsize += sect->reloc_count *
+ sizeof (struct reloc_std_external);
+ }
+ else if (sect->flags & SEC_ALLOC && !(sect->flags & SEC_LOAD))
+ exec_hdr (abfd)->a_bss += sect->size;
+ }
+
+ exec_hdr (abfd)->a_syms = bfd_get_symcount (abfd)
+ * sizeof (struct external_nlist);
+ exec_hdr (abfd)->a_entry = bfd_get_start_address (abfd);
+
+ aout_adobe_swap_exec_header_out (abfd, exec_hdr (abfd), &swapped_hdr);
+
+ amt = EXEC_BYTES_SIZE;
+ if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0
+ || bfd_bwrite (& swapped_hdr, amt, abfd) != amt)
+ return FALSE;
+
+ /* Now write out the section information. Text first, data next, rest
+ afterward. */
+ for (sect = abfd->sections; sect; sect = sect->next)
+ if (sect->flags & SEC_CODE)
+ aout_adobe_write_section (abfd, sect);
+
+ for (sect = abfd->sections; sect; sect = sect->next)
+ if (sect->flags & SEC_DATA)
+ aout_adobe_write_section (abfd, sect);
+
+ for (sect = abfd->sections; sect; sect = sect->next)
+ if (!(sect->flags & (SEC_CODE | SEC_DATA)))
+ aout_adobe_write_section (abfd, sect);
+
+ /* Write final `sentinel` section header (with type of 0). */
+ amt = sizeof (*sentinel);
+ if (bfd_bwrite (sentinel, amt, abfd) != amt)
+ return FALSE;
+
+ /* Now write out reloc info, followed by syms and strings. */
+ if (bfd_get_symcount (abfd) != 0)
+ {
+ if (bfd_seek (abfd, (file_ptr) (N_SYMOFF (*exec_hdr (abfd))), SEEK_SET)
+ != 0)
+ return FALSE;
+
+ if (! aout_32_write_syms (abfd))
+ return FALSE;
+
+ if (bfd_seek (abfd, (file_ptr) (N_TRELOFF (*exec_hdr (abfd))), SEEK_SET)
+ != 0)
+ return FALSE;
+
+ for (sect = abfd->sections; sect; sect = sect->next)
+ if (sect->flags & SEC_CODE)
+ if (!aout_32_squirt_out_relocs (abfd, sect))
+ return FALSE;
+
+ if (bfd_seek (abfd, (file_ptr) (N_DRELOFF (*exec_hdr (abfd))), SEEK_SET)
+ != 0)
+ return FALSE;
+
+ for (sect = abfd->sections; sect; sect = sect->next)
+ if (sect->flags & SEC_DATA)
+ if (!aout_32_squirt_out_relocs (abfd, sect))
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static bfd_boolean
+aout_adobe_set_section_contents (bfd *abfd,
+ asection *section,
+ const void * location,
+ file_ptr offset,
+ bfd_size_type count)
+{
+ file_ptr section_start;
+ sec_ptr sect;
+
+ /* Set by bfd.c handler. */
+ if (! abfd->output_has_begun)
+ {
+ /* 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->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->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->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 TRUE;
+
+ return bfd_bwrite (location, count, abfd) == count;
+}
+
+static bfd_boolean
+aout_adobe_set_arch_mach (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 (bfd *ignore_abfd ATTRIBUTE_UNUSED,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED)
+{
+ return sizeof (struct internal_exec);
+}
+
+/* Build the transfer vector for Adobe A.Out files. */
+
+#define aout_32_find_line _bfd_nosymbols_find_line
+#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_bfd_reloc_name_lookup _bfd_norelocs_bfd_reloc_name_lookup
+#define aout_32_close_and_cleanup aout_32_bfd_free_cached_info
+#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_lookup_section_flags bfd_generic_lookup_section_flags
+#define aout_32_bfd_merge_sections bfd_generic_merge_sections
+#define aout_32_bfd_is_group_section bfd_generic_is_group_section
+#define aout_32_bfd_discard_group bfd_generic_discard_group
+#define aout_32_section_already_linked _bfd_generic_section_already_linked
+#define aout_32_bfd_define_common_symbol bfd_generic_define_common_symbol
+#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_link_just_syms _bfd_generic_link_just_syms
+#define aout_32_bfd_copy_link_hash_symbol_type \
+ _bfd_generic_copy_link_hash_symbol_type
+#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 aout_adobe_vec =
+{
+ "a.out.adobe", /* Name. */
+ bfd_target_aout_flavour,
+ BFD_ENDIAN_BIG, /* Data byte order is unknown (big assumed). */
+ BFD_ENDIAN_BIG, /* Header 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. */
+ 0, /* match priority. */
+
+ 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, /* Headers. */
+
+ {_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),
+
+ NULL,
+
+ NULL
+};
diff --git a/bfd/aout-arm.c b/bfd/aout-arm.c
new file mode 100644
index 0000000..5f336ff
--- /dev/null
+++ b/bfd/aout-arm.c
@@ -0,0 +1,548 @@
+/* BFD back-end for raw ARM a.out binaries.
+ Copyright (C) 1994-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+
+/* Avoid multiple definitions from aoutx if supporting standard a.out
+ as well as our own. */
+/* Do not "beautify" the CONCAT* macro args. Traditional C will not
+ remove whitespace added here, and thus will fail to concatenate
+ the tokens. */
+#define NAME(x,y) CONCAT3 (aoutarm,_32_,y)
+
+#define N_TXTADDR(x) \
+ ((N_MAGIC (x) == NMAGIC) \
+ ? (bfd_vma) 0x8000 \
+ : ((N_MAGIC (x) != ZMAGIC) \
+ ? (bfd_vma) 0 \
+ : ((N_SHARED_LIB (x)) \
+ ? ((x).a_entry & ~(bfd_vma) (TARGET_PAGE_SIZE - 1)) \
+ : (bfd_vma) 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) CONCAT2 (arm_aout_,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)
+
+#define MY_bfd_reloc_type_lookup arm_aout_bfd_reloc_type_lookup
+#define MY_bfd_reloc_name_lookup arm_aout_bfd_reloc_name_lookup
+
+#include "libaout.h"
+#include "aout/aout64.h"
+
+
+static bfd_reloc_status_type
+ MY (fix_pcrel_26) (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
+static bfd_reloc_status_type
+ MY (fix_pcrel_26_done) (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
+
+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),
+ EMPTY_HOWTO (-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)
+
+static reloc_howto_type *
+MY (reloc_howto) (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 howto_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);
+ }
+ howto_index = r_length + 4 * r_pcrel_done + 8 * r_neg;
+ if (howto_index == 3)
+ *r_pcrel = 1;
+
+ return MY (howto_table) + howto_index;
+}
+
+#define MY_reloc_howto(BFD, REL, IN, EX, PC) \
+ MY (reloc_howto) (BFD, REL, &IN, &EX, &PC)
+
+static void
+MY (put_reloc) (bfd *abfd,
+ int r_extern,
+ int r_index,
+ bfd_vma 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);
+ /* Size as a power of two. */
+ r_length = howto->size;
+
+ /* 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)
+
+static void
+MY (relocatable_reloc) (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) (bfd *abfd ATTRIBUTE_UNUSED,
+ arelent *reloc_entry ATTRIBUTE_UNUSED,
+ asymbol *symbol ATTRIBUTE_UNUSED,
+ void * data ATTRIBUTE_UNUSED,
+ asection *input_section ATTRIBUTE_UNUSED,
+ bfd *output_bfd ATTRIBUTE_UNUSED,
+ char **error_message ATTRIBUTE_UNUSED)
+{
+ /* This is dead simple at present. */
+ return bfd_reloc_ok;
+}
+
+static bfd_reloc_status_type
+MY (fix_pcrel_26) (bfd *abfd,
+ arelent *reloc_entry,
+ asymbol *symbol,
+ void * data,
+ asection *input_section,
+ bfd *output_bfd,
+ char **error_message ATTRIBUTE_UNUSED)
+{
+ bfd_vma relocation;
+ bfd_size_type addr = reloc_entry->address;
+ bfd_vma 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 (bfd_is_und_section (symbol->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 != 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 & ~ (bfd_vma) 0x03ffffff)
+ flag = bfd_reloc_overflow;
+
+ target &= ~ (bfd_vma) 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;
+}
+
+static reloc_howto_type *
+MY (bfd_reloc_type_lookup) (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_arch_bits_per_address (abfd))
+ {
+ case 32:
+ code = BFD_RELOC_32;
+ break;
+ default:
+ return 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 NULL;
+ }
+}
+
+static reloc_howto_type *
+MY (bfd_reloc_name_lookup) (bfd *abfd ATTRIBUTE_UNUSED,
+ const char *r_name)
+{
+ unsigned int i;
+
+ for (i = 0;
+ i < sizeof (MY (howto_table)) / sizeof (MY (howto_table)[0]);
+ i++)
+ if (MY (howto_table)[i].name != NULL
+ && strcasecmp (MY (howto_table)[i].name, r_name) == 0)
+ return &MY (howto_table)[i];
+
+ return NULL;
+}
+
+#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
+
+void MY_swap_std_reloc_in (bfd *, struct reloc_std_external *, arelent *, asymbol **, bfd_size_type);
+void MY_swap_std_reloc_out (bfd *, arelent *, struct reloc_std_external *);
+
+#include "aoutx.h"
+
+void
+MY_swap_std_reloc_in (bfd *abfd,
+ struct reloc_std_external *bytes,
+ arelent *cache_ptr,
+ asymbol **symbols,
+ bfd_size_type symcount ATTRIBUTE_UNUSED)
+{
+ int r_index;
+ int r_extern;
+ int r_pcrel;
+ struct aoutdata *su = &(abfd->tdata.aout_data->a);
+
+ cache_ptr->address = 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 (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;
+ }
+
+ /* 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_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"
+
+extern const bfd_target arm_aout_be_vec;
+
+const bfd_target arm_aout_le_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. */
+ 0, /* match priority. */
+ 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, /* Headers. */
+ {_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),
+
+ & arm_aout_be_vec,
+
+ (void *) MY_backend_data,
+};
+
+const bfd_target arm_aout_be_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. */
+ 0, /* match priority. */
+ 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, /* Headers. */
+ {_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),
+
+ & arm_aout_le_vec,
+
+ (void *) MY_backend_data,
+};
diff --git a/bfd/aout-cris.c b/bfd/aout-cris.c
new file mode 100644
index 0000000..01b7bcf
--- /dev/null
+++ b/bfd/aout-cris.c
@@ -0,0 +1,289 @@
+/* BFD backend for CRIS a.out binaries.
+ Copyright (C) 2000-2014 Free Software Foundation, Inc.
+ Contributed by Axis Communications AB.
+ Written by Hans-Peter Nilsson.
+
+ This file is part of BFD, the Binary File Descriptor library.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+/* See info in the file PORTING for documentation of these macros and
+ functions. Beware; some of the information there is outdated. */
+
+#define N_HEADER_IN_TEXT(x) 0
+#define N_TXTOFF(x) 32
+#define ENTRY_CAN_BE_ZERO
+#define TEXT_START_ADDR 0
+
+/* Without reading symbols to get the text start symbol, there is no way
+ to know where the text segment starts in an a.out file. Defaulting to
+ anything as constant as TEXT_START_ADDR is bad. But we can guess from
+ the entry point, which is usually within the first 64k of the text
+ segment. We also assume here that the text segment is 64k-aligned.
+ FIXME: It is also wrong to assume that data and bss follow immediately
+ after text, but with those, we don't have any choice besides reading
+ symbol info, and luckily there's no pressing need for correctness for
+ those vma:s at this time. */
+#define N_TXTADDR(x) ((x).a_entry & ~(bfd_vma) 0xffff)
+
+/* If you change this to 4, you can not link to an address N*4+2. */
+#define SEGMENT_SIZE 2
+
+/* For some reason, if the a.out file has Z_MAGIC, then
+ adata(abfd).exec_bytes_size is not used, but rather
+ adata(abfd).zmagic_disk_block_size, even though the exec_header is
+ *not* included in the text segment. A simple workaround is to
+ #define ZMAGIC_DISK_BLOCK_SIZE, which is used if defined; otherwise
+ TARGET_PAGE_SIZE is used. */
+#define ZMAGIC_DISK_BLOCK_SIZE N_TXTOFF (0)
+
+/* It seems odd at first to set a page-size this low, but gives greater
+ freedom in where things can be linked. The drawback is that you have
+ to set alignment and padding in linker scripts. */
+#define TARGET_PAGE_SIZE SEGMENT_SIZE
+#define TARGETNAME "a.out-cris"
+
+/* The definition here seems not used; just provided as a convention. */
+#define DEFAULT_ARCH bfd_arch_cris
+
+/* Do not "beautify" the CONCAT* macro args. Traditional C will not
+ remove whitespace added here, and thus will fail to concatenate
+ the tokens. */
+#define MY(OP) CONCAT2 (cris_aout_,OP)
+#define NAME(x, y) CONCAT3 (cris_aout,_32_,y)
+
+#include "sysdep.h"
+#include "bfd.h"
+
+/* Version 1 of the header. */
+#define MY_exec_hdr_flags 1
+
+#define MY_write_object_contents MY (write_object_contents)
+static bfd_boolean MY (write_object_contents) (bfd *);
+
+/* Forward this, so we can use a pointer to it in PARAMS. */
+struct reloc_ext_external;
+
+#define MY_swap_ext_reloc_out MY (swap_ext_reloc_out)
+static void MY (swap_ext_reloc_out) (bfd *, arelent *, struct reloc_ext_external *);
+
+#define MY_swap_ext_reloc_in MY (swap_ext_reloc_in)
+static void MY (swap_ext_reloc_in) (bfd *, struct reloc_ext_external *,
+ arelent *, asymbol **, bfd_size_type);
+
+#define MY_set_sizes MY (set_sizes)
+static bfd_boolean MY (set_sizes) (bfd *);
+
+/* To set back reloc_size to ext, we make MY (set_sizes) be called
+ through this construct. Note that MY_set_arch_mach is only called
+ through SET_ARCH_MACH. The default bfd_default_set_arch_mach will
+ not call set_sizes. */
+
+#define MY_set_arch_mach NAME (aout, set_arch_mach)
+#define SET_ARCH_MACH(BFD, EXEC) \
+ MY_set_arch_mach (BFD, DEFAULT_ARCH, N_MACHTYPE (EXEC))
+
+/* These macros describe the binary layout of the reloc information we
+ use in a file. */
+#define RELOC_EXT_BITS_EXTERN_LITTLE 0x80
+#define RELOC_EXT_BITS_TYPE_LITTLE 3
+#define RELOC_EXT_BITS_TYPE_SH_LITTLE 0
+
+#ifndef MY_get_section_contents
+#define MY_get_section_contents aout_32_get_section_contents
+#endif
+
+#define MACHTYPE_OK(mtype) ((mtype) == M_CRIS)
+
+/* Include generic functions (some are overridden above). */
+#include "aout32.c"
+#include "aout-target.h"
+
+/* We need our own version to set header flags. */
+
+static bfd_boolean
+MY (write_object_contents) (bfd *abfd)
+{
+ struct external_exec exec_bytes;
+ struct internal_exec *execp = exec_hdr (abfd);
+
+ /* We set the reloc type to RELOC_EXT_SIZE, although setting it at all
+ seems unnecessary when inspecting as and ld behavior (not an
+ exhaustive inspection). The default write_object_contents
+ definition sets RELOC_EXT_SIZE, so we follow suite and set it too. */
+ obj_reloc_entry_size (abfd) = RELOC_EXT_SIZE;
+
+ /* Setting N_SET_MACHTYPE and using N_SET_FLAGS is not performed by
+ the default definition. */
+ if (bfd_get_arch (abfd) == bfd_arch_cris)
+ N_SET_MACHTYPE (*execp, M_CRIS);
+
+ N_SET_FLAGS (*execp, aout_backend_info (abfd)->exec_hdr_flags);
+
+ WRITE_HEADERS (abfd, execp);
+
+ return TRUE;
+}
+
+/* We need our own for these reasons:
+ - Assert that a normal 8, 16 or 32 reloc is output.
+ - Fix what seems to be a weak-bug (perhaps there for valid reasons). */
+
+static void
+MY (swap_ext_reloc_out) (bfd *abfd,
+ arelent *g,
+ struct reloc_ext_external *natptr)
+{
+ int r_index;
+ int r_extern;
+ unsigned int r_type;
+ bfd_vma 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))
+ /* Remember to check for weak symbols; they count as global. */
+ || (sym->flags & (BSF_GLOBAL | BSF_WEAK)) != 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;
+ }
+
+ /* The relocation type is the same as the canonical ones, but only
+ the first 3 are used: RELOC_8, RELOC_16, RELOC_32.
+ We may change this later, but assert this for the moment. */
+ if (r_type > 2)
+ {
+ (*_bfd_error_handler) (_("%s: Invalid relocation type exported: %d"),
+ bfd_get_filename (abfd), r_type);
+
+ bfd_set_error (bfd_error_wrong_format);
+ }
+
+ /* Now the fun stuff. */
+ 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);
+}
+
+/* We need our own to assert that a normal 8, 16 or 32 reloc is input. */
+
+static void
+MY (swap_ext_reloc_in) (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. */
+ 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_SH_LITTLE)
+ & RELOC_EXT_BITS_TYPE_LITTLE;
+
+ if (r_type > 2)
+ {
+ (*_bfd_error_handler) (_("%B: Invalid relocation type imported: %d"),
+ abfd, r_type);
+
+ bfd_set_error (bfd_error_wrong_format);
+ }
+
+ cache_ptr->howto = howto_table_ext + r_type;
+
+ if (r_extern && r_index > symcount)
+ {
+ (*_bfd_error_handler)
+ (_("%B: Bad relocation record imported: %d"), abfd, r_index);
+
+ bfd_set_error (bfd_error_wrong_format);
+
+ /* We continue, so we can catch further errors. */
+ r_extern = 0;
+ r_index = N_ABS;
+ }
+
+ /* Magically uses r_extern, symbols etc. Ugly, but it's what's in the
+ default. */
+ MOVE_ADDRESS (GET_SWORD (abfd, bytes->r_addend));
+}
+
+/* We use the same as the default, except that we also set
+ "obj_reloc_entry_size (abfd) = RELOC_EXT_SIZE;", to avoid changing
+ NAME (aout, set_arch_mach) in aoutx. */
+
+static bfd_boolean
+MY (set_sizes) (bfd *abfd)
+{
+ /* Just as the default in aout-target.h (with some #ifdefs folded)... */
+
+ adata (abfd).page_size = TARGET_PAGE_SIZE;
+ adata (abfd).segment_size = SEGMENT_SIZE;
+ adata (abfd).zmagic_disk_block_size = ZMAGIC_DISK_BLOCK_SIZE;
+ adata (abfd).exec_bytes_size = EXEC_BYTES_SIZE;
+
+ /* ... except for that we have the extended reloc. The alternative
+ would be to add a check on bfd_arch_cris in NAME (aout,
+ set_arch_mach) in aoutx.h, but I don't want to do that since
+ target-specific things should not be added there. */
+
+ obj_reloc_entry_size (abfd) = RELOC_EXT_SIZE;
+
+ return TRUE;
+}
diff --git a/bfd/aout-ns32k.c b/bfd/aout-ns32k.c
new file mode 100644
index 0000000..b436b21
--- /dev/null
+++ b/bfd/aout-ns32k.c
@@ -0,0 +1,364 @@
+/* BFD back-end for ns32k a.out-ish binaries.
+ Copyright (C) 1990-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "aout/aout64.h"
+#include "ns32k.h"
+
+/* Do not "beautify" the CONCAT* macro args. Traditional C will not
+ remove whitespace added here, and thus will fail to concatenate
+ the tokens. */
+#define MYNS(OP) CONCAT2 (ns32k_aout_,OP)
+
+reloc_howto_type * MYNS (bfd_reloc_type_lookup) (bfd *, bfd_reloc_code_real_type);
+reloc_howto_type * MYNS (bfd_reloc_name_lookup) (bfd *, const char *);
+bfd_boolean MYNS (write_object_contents) (bfd *);
+
+/* Avoid multiple definitions from aoutx if supporting
+ standard a.out format(s) as well as this one. */
+#define NAME(x,y) CONCAT3 (ns32kaout,_32_,y)
+
+void bfd_ns32k_arch (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)
+
+/* The ns32k series is ah, unusual, when it comes to relocation.
+ There are three storage methods for relocatable 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 architecture).
+
+ 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, complain_overflow_signed,
+ _bfd_ns32k_reloc_imm, "NS32K_IMM_8",
+ TRUE, 0x000000ff,0x000000ff, FALSE),
+ HOWTO (BFD_RELOC_NS32K_IMM_16, 0, 1, 16, FALSE, 0, complain_overflow_signed,
+ _bfd_ns32k_reloc_imm, "NS32K_IMM_16",
+ TRUE, 0x0000ffff,0x0000ffff, FALSE),
+ HOWTO (BFD_RELOC_NS32K_IMM_32, 0, 2, 32, FALSE, 0, complain_overflow_signed,
+ _bfd_ns32k_reloc_imm, "NS32K_IMM_32",
+ TRUE, 0xffffffff,0xffffffff, FALSE),
+ HOWTO (BFD_RELOC_NS32K_IMM_8_PCREL, 0, 0, 8, TRUE, 0, complain_overflow_signed,
+ _bfd_ns32k_reloc_imm, "PCREL_NS32K_IMM_8",
+ TRUE, 0x000000ff, 0x000000ff, FALSE),
+ HOWTO (BFD_RELOC_NS32K_IMM_16_PCREL, 0, 1, 16, TRUE, 0, complain_overflow_signed,
+ _bfd_ns32k_reloc_imm, "PCREL_NS32K_IMM_16",
+ TRUE, 0x0000ffff,0x0000ffff, FALSE),
+ HOWTO (BFD_RELOC_NS32K_IMM_32_PCREL, 0, 2, 32, TRUE, 0, complain_overflow_signed,
+ _bfd_ns32k_reloc_imm, "PCREL_NS32K_IMM_32",
+ TRUE, 0xffffffff,0xffffffff, FALSE),
+
+ /* ns32k displacements. */
+ HOWTO (BFD_RELOC_NS32K_DISP_8, 0, 0, 7, FALSE, 0, complain_overflow_signed,
+ _bfd_ns32k_reloc_disp, "NS32K_DISP_8",
+ TRUE, 0x000000ff,0x000000ff, FALSE),
+ HOWTO (BFD_RELOC_NS32K_DISP_16, 0, 1, 14, FALSE, 0, complain_overflow_signed,
+ _bfd_ns32k_reloc_disp, "NS32K_DISP_16",
+ TRUE, 0x0000ffff, 0x0000ffff, FALSE),
+ HOWTO (BFD_RELOC_NS32K_DISP_32, 0, 2, 30, FALSE, 0, complain_overflow_signed,
+ _bfd_ns32k_reloc_disp, "NS32K_DISP_32",
+ TRUE, 0xffffffff, 0xffffffff, FALSE),
+ HOWTO (BFD_RELOC_NS32K_DISP_8_PCREL, 0, 0, 7, TRUE, 0, complain_overflow_signed,
+ _bfd_ns32k_reloc_disp, "PCREL_NS32K_DISP_8",
+ TRUE, 0x000000ff,0x000000ff, FALSE),
+ HOWTO (BFD_RELOC_NS32K_DISP_16_PCREL, 0, 1, 14, TRUE, 0, complain_overflow_signed,
+ _bfd_ns32k_reloc_disp, "PCREL_NS32K_DISP_16",
+ TRUE, 0x0000ffff,0x0000ffff, FALSE),
+ HOWTO (BFD_RELOC_NS32K_DISP_32_PCREL, 0, 2, 30, TRUE, 0, complain_overflow_signed,
+ _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
+
+static reloc_howto_type *
+MY (reloc_howto) (bfd *abfd ATTRIBUTE_UNUSED,
+ struct reloc_std_external *rel,
+ int *r_index,
+ int *r_extern,
+ int *r_pcrel)
+{
+ unsigned int r_length;
+ int r_ns32k_type;
+
+ *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)
+
+static void
+MY (put_reloc) (bfd *abfd,
+ int r_extern,
+ int r_index,
+ bfd_vma 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;
+
+ 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
+
+static void MY_swap_std_reloc_in (bfd *, struct reloc_std_external *, arelent *, asymbol **, bfd_size_type);
+static void MY_swap_std_reloc_out (bfd *, arelent *, struct reloc_std_external *);
+
+#include "aoutx.h"
+
+reloc_howto_type *
+MY (bfd_reloc_type_lookup) (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_arch_bits_per_address (abfd))
+ {
+ case 32:
+ code = BFD_RELOC_32;
+ break;
+ default:
+ 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 NULL;
+ }
+#undef ENTRY
+}
+
+reloc_howto_type *
+MY (bfd_reloc_name_lookup) (bfd *abfd ATTRIBUTE_UNUSED,
+ const char *r_name)
+{
+ unsigned int i;
+
+ for (i = 0;
+ i < sizeof (MY (howto_table)) / sizeof (MY (howto_table)[0]);
+ i++)
+ if (MY (howto_table)[i].name != NULL
+ && strcasecmp (MY (howto_table)[i].name, r_name) == 0)
+ return &MY (howto_table)[i];
+
+ return NULL;
+}
+
+static void
+MY_swap_std_reloc_in (bfd *abfd,
+ struct reloc_std_external *bytes,
+ arelent *cache_ptr,
+ asymbol **symbols,
+ bfd_size_type symcount ATTRIBUTE_UNUSED)
+{
+ int r_index;
+ int r_extern;
+ int r_pcrel;
+ struct aoutdata *su = &(abfd->tdata.aout_data->a);
+
+ cache_ptr->address = 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 (bfd *abfd,
+ arelent *g,
+ struct reloc_std_external *natptr)
+{
+ int r_index;
+ asymbol *sym = *(g->sym_ptr_ptr);
+ int r_extern;
+ asection *output_section = sym->section->output_section;
+
+ /* 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;
+#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 (reloc_howto_type *howto,
+ bfd *input_bfd,
+ bfd_vma relocation,
+ bfd_byte *location)
+{
+ int r_ns32k_type = (howto - MY (howto_table)) / 6;
+ bfd_vma (*get_data) (bfd_byte *, int);
+ void (*put_data) (bfd_vma, bfd_byte *, int);
+
+ 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);
+ 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 0000000..0d75a28
--- /dev/null
+++ b/bfd/aout-sparcle.c
@@ -0,0 +1,37 @@
+/* BFD backend for sparc little-endian aout binaries.
+ Copyright (C) 1996-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#define TARGETNAME "a.out-sparc-little"
+
+/* Do not "beautify" the CONCAT* macro args. Traditional C will not
+ remove whitespace added here, and thus will fail to concatenate
+ the tokens. */
+#define MY(OP) CONCAT2 (sparc_aout_le_,OP)
+
+#include "sysdep.h"
+#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 0000000..3bca8b5
--- /dev/null
+++ b/bfd/aout-target.h
@@ -0,0 +1,680 @@
+/* Define a target vector and some small routines for a variant of a.out.
+ Copyright (C) 1990-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, 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) (bfd *, bfd_reloc_code_real_type);
+extern reloc_howto_type * NAME (aout, reloc_name_lookup) (bfd *, const char *);
+
+/* 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) (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)->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)->size, arch_align)
+ == obj_textsec (abfd)->size)
+ && (BFD_ALIGN (obj_datasec (abfd)->size, arch_align)
+ == obj_datasec (abfd)->size)
+ && (BFD_ALIGN (obj_bsssec (abfd)->size, arch_align)
+ == obj_bsssec (abfd)->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. */
+
+ 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) (bfd *abfd)
+{
+ struct external_exec exec_bytes; /* Raw exec header from file. */
+ struct internal_exec exec; /* Cleaned-up exec header. */
+ const bfd_target *target;
+ bfd_size_type amt = EXEC_BYTES_SIZE;
+
+ if (bfd_bread ((void *) &exec_bytes, amt, abfd) != amt)
+ {
+ 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 = GET_MAGIC (abfd, exec_bytes.e_info);
+#endif
+
+ 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
+
+ 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 bfd_boolean
+MY (mkobject) (bfd *abfd)
+{
+ return NAME (aout, mkobject (abfd));
+}
+
+#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 bfd_boolean
+MY_bfd_copy_private_section_data (bfd *ibfd,
+ asection *isec ATTRIBUTE_UNUSED,
+ bfd *obfd,
+ asection *osec ATTRIBUTE_UNUSED)
+{
+ 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 bfd_boolean
+MY (write_object_contents) (bfd *abfd)
+{
+ struct external_exec exec_bytes;
+ struct internal_exec *execp = exec_hdr (abfd);
+
+ obj_reloc_entry_size (abfd) = RELOC_STD_SIZE;
+
+ WRITE_HEADERS (abfd, execp);
+
+ return TRUE;
+}
+#define MY_write_object_contents MY (write_object_contents)
+#endif
+
+#ifndef MY_set_sizes
+
+static bfd_boolean
+MY (set_sizes) (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 (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 bfd_boolean
+MY_bfd_final_link (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_write_ar_hdr
+#define MY_write_ar_hdr _bfd_generic_write_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_pid
+#define MY_core_file_pid _bfd_nocore_core_file_pid
+#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 (*) (bfd *, struct bfd_section *)) 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_canonicalize_symtab
+#define MY_canonicalize_symtab NAME (aout, canonicalize_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_find_line
+#define MY_find_line _bfd_nosymbols_find_line
+#endif
+#ifndef MY_find_inliner_info
+#define MY_find_inliner_info _bfd_nosymbols_find_inliner_info
+#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_lookup_section_flags
+#define MY_bfd_lookup_section_flags bfd_generic_lookup_section_flags
+#endif
+#ifndef MY_bfd_merge_sections
+#define MY_bfd_merge_sections bfd_generic_merge_sections
+#endif
+#ifndef MY_bfd_is_group_section
+#define MY_bfd_is_group_section bfd_generic_is_group_section
+#endif
+#ifndef MY_bfd_discard_group
+#define MY_bfd_discard_group bfd_generic_discard_group
+#endif
+#ifndef MY_section_already_linked
+#define MY_section_already_linked \
+ _bfd_generic_section_already_linked
+#endif
+#ifndef MY_bfd_define_common_symbol
+#define MY_bfd_define_common_symbol bfd_generic_define_common_symbol
+#endif
+#ifndef MY_bfd_reloc_type_lookup
+#define MY_bfd_reloc_type_lookup NAME (aout, reloc_type_lookup)
+#endif
+#ifndef MY_bfd_reloc_name_lookup
+#define MY_bfd_reloc_name_lookup NAME (aout, reloc_name_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_just_syms
+#define MY_bfd_link_just_syms _bfd_generic_link_just_syms
+#endif
+#ifndef MY_bfd_copy_link_hash_symbol_type
+#define MY_bfd_copy_link_hash_symbol_type \
+ _bfd_generic_copy_link_hash_symbol_type
+#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_copy_private_header_data
+#define MY_bfd_copy_private_header_data _bfd_generic_bfd_copy_private_header_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_is_target_special_symbol
+#define MY_bfd_is_target_special_symbol ((bfd_boolean (*) (bfd *, asymbol *)) bfd_false)
+#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
+
+/* Handle closing of a BFD including the resource-releasing parts. */
+
+static bfd_boolean
+MY_close_and_cleanup (bfd *abfd)
+{
+ if (!MY_bfd_free_cached_info (abfd))
+ return FALSE;
+
+ return _bfd_generic_close_and_cleanup (abfd);
+}
+
+#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_synthetic_symtab
+#define MY_get_synthetic_symtab \
+ _bfd_nodynamic_get_synthetic_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. */
+ 0, /* match priority. */
+#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, /* Headers. */
+#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, /* Headers. */
+#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),
+
+ /* Alternative_target. */
+ NULL,
+
+ MY_backend_data
+};
+#endif /* MY_BFD_TARGET */
diff --git a/bfd/aout-tic30.c b/bfd/aout-tic30.c
new file mode 100644
index 0000000..e74464d
--- /dev/null
+++ b/bfd/aout-tic30.c
@@ -0,0 +1,1112 @@
+/* BFD back-end for TMS320C30 a.out binaries.
+ Copyright (C) 1998-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
+ 02110-1301, USA. */
+
+#define TARGET_IS_BIG_ENDIAN_P
+#define N_HEADER_IN_TEXT(x) 1
+#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
+
+/* Do not "beautify" the CONCAT* macro args. Traditional C will not
+ remove whitespace added here, and thus will fail to concatenate
+ the tokens. */
+#define MY(OP) CONCAT2 (tic30_aout_,OP)
+#define TARGETNAME "a.out-tic30"
+#define NAME(x,y) CONCAT3 (tic30_aout,_32_,y)
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libaout.h"
+#include "aout/aout64.h"
+#include "aout/stab_gnu.h"
+#include "aout/ar.h"
+
+#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 bfd_boolean
+tic30_aout_set_sizes (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;
+}
+
+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
+
+static reloc_howto_type *
+ tic30_aout_reloc_howto (bfd *, struct reloc_std_external *, int *, int *, int *);
+static bfd_reloc_status_type
+ tic30_aout_final_link_relocate
+ (reloc_howto_type *, bfd *, asection *, bfd_byte *, bfd_vma, bfd_vma, bfd_vma);
+
+/* FIXME: This is wrong. aoutx.h should really only be included by
+ aout32.c. */
+
+#include "aoutx.h"
+
+/* 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 (bfd *abfd,
+ arelent *reloc_entry,
+ asymbol *symbol ATTRIBUTE_UNUSED,
+ void * data,
+ asection *input_section ATTRIBUTE_UNUSED,
+ bfd *output_bfd ATTRIBUTE_UNUSED,
+ char **error_message ATTRIBUTE_UNUSED)
+{
+ 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;
+}
+
+/* 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 (bfd *abfd,
+ arelent *reloc_entry,
+ asymbol *symbol,
+ void * data,
+ asection *input_section ATTRIBUTE_UNUSED,
+ bfd *output_bfd,
+ char **error_message ATTRIBUTE_UNUSED)
+{
+ bfd_vma relocation;
+
+ /* Make sure that the symbol's section is defined. */
+ if (bfd_is_und_section (symbol->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 (bfd *abfd,
+ arelent *reloc_entry,
+ asymbol *symbol,
+ void * data,
+ asection *input_section ATTRIBUTE_UNUSED,
+ bfd *output_bfd,
+ char **error_message ATTRIBUTE_UNUSED)
+{
+ bfd_vma relocation;
+
+ /* Make sure that the symbol's section is defined. */
+ if (bfd_is_und_section (symbol->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 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[] =
+{
+ EMPTY_HOWTO (-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),
+ EMPTY_HOWTO (-1),
+ EMPTY_HOWTO (-1),
+ EMPTY_HOWTO (-1),
+ EMPTY_HOWTO (-1),
+ EMPTY_HOWTO (-1)
+};
+
+
+static reloc_howto_type *
+tic30_aout_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ 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 NULL;
+ }
+}
+
+static reloc_howto_type *
+tic30_aout_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ const char *r_name)
+{
+ unsigned int i;
+
+ for (i = 0;
+ i < (sizeof (tic30_aout_howto_table)
+ / sizeof (tic30_aout_howto_table[0]));
+ i++)
+ if (tic30_aout_howto_table[i].name != NULL
+ && strcasecmp (tic30_aout_howto_table[i].name, r_name) == 0)
+ return &tic30_aout_howto_table[i];
+
+ return NULL;
+}
+
+static reloc_howto_type *
+tic30_aout_reloc_howto (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 howto_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);
+ }
+ howto_index = r_length + 4 * r_pcrel_done;
+ return tic30_aout_howto_table + howto_index;
+}
+
+/* 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 (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)->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, 0L);
+#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)->size, arch_align)
+ == obj_textsec (abfd)->size)
+ && (BFD_ALIGN (obj_datasec (abfd)->size, arch_align)
+ == obj_datasec (abfd)->size)
+ && (BFD_ALIGN (obj_bsssec (abfd)->size, arch_align)
+ == obj_bsssec (abfd)->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_relocate_contents (reloc_howto_type *howto,
+ bfd *input_bfd,
+ bfd_vma relocation,
+ bfd_byte *location)
+{
+ bfd_vma x;
+ bfd_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)
+ != ((bfd_vma) -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;
+}
+
+static bfd_reloc_status_type
+tic30_aout_final_link_relocate (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 > bfd_get_section_limit (input_bfd, input_section))
+ 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);
+}
+
+/* Finish up the reading of an a.out file header. */
+
+static const bfd_target *
+tic30_aout_object_p (bfd *abfd)
+{
+ struct external_exec exec_bytes; /* Raw exec header from file. */
+ struct internal_exec exec; /* Cleaned-up exec header. */
+ const bfd_target *target;
+ bfd_size_type amt = EXEC_BYTES_SIZE;
+
+ if (bfd_bread (& exec_bytes, amt, abfd) != amt)
+ {
+ 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 = 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
+
+ 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
+
+ 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. */
+
+static bfd_boolean
+MY_bfd_copy_private_section_data (bfd *ibfd,
+ asection *isec ATTRIBUTE_UNUSED,
+ bfd *obfd,
+ asection *osec ATTRIBUTE_UNUSED)
+{
+ 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 bfd_boolean
+tic30_aout_write_object_contents (bfd *abfd)
+{
+ struct external_exec exec_bytes;
+ struct internal_exec *execp = exec_hdr (abfd);
+
+ obj_reloc_entry_size (abfd) = RELOC_STD_SIZE;
+
+ {
+ 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)
+ {
+ bfd_size_type amt;
+
+ if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
+ return FALSE;
+ amt = adata (abfd).exec_bytes_size;
+ if (bfd_bwrite (& exec_bytes, amt, abfd) != amt)
+ 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;
+}
+
+#ifndef MY_final_link_callback
+
+/* Callback for the final_link routine to set the section offsets. */
+
+static void
+MY_final_link_callback (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 bfd_boolean
+MY_bfd_final_link (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)->size;
+ vma += obj_textsec (abfd)->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)->size = execp->a_text;
+
+ /* Since BSS follows data immediately, see if it needs alignment. */
+ vma += obj_datasec (abfd)->size;
+ pad = align_power (vma, obj_bsssec (abfd)->alignment_power) - vma;
+ obj_datasec (abfd)->size += pad;
+ pos += obj_datasec (abfd)->size;
+ execp->a_data = obj_datasec (abfd)->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
+
+static enum machine_type
+tic30_aout_machine_type (enum bfd_architecture arch,
+ unsigned long machine ATTRIBUTE_UNUSED,
+ bfd_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;
+}
+
+static bfd_boolean
+tic30_aout_set_arch_mach (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)
+ {
+ bfd_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_write_ar_hdr
+#define MY_write_ar_hdr _bfd_generic_write_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_pid
+#define MY_core_file_pid _bfd_nocore_core_file_pid
+#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 (*) (bfd*, struct bfd_section *)) 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_canonicalize_symtab
+#define MY_canonicalize_symtab NAME (aout, canonicalize_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_find_line
+#define MY_find_line _bfd_nosymbols_find_line
+#endif
+#ifndef MY_find_inliner_info
+#define MY_find_inliner_info _bfd_nosymbols_find_inliner_info
+#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_lookup_section_flags
+#define MY_bfd_lookup_section_flags bfd_generic_lookup_section_flags
+#endif
+#ifndef MY_bfd_merge_sections
+#define MY_bfd_merge_sections bfd_generic_merge_sections
+#endif
+#ifndef MY_bfd_is_group_section
+#define MY_bfd_is_group_section bfd_generic_is_group_section
+#endif
+#ifndef MY_bfd_discard_group
+#define MY_bfd_discard_group bfd_generic_discard_group
+#endif
+#ifndef MY_section_already_linked
+#define MY_section_already_linked \
+ _bfd_generic_section_already_linked
+#endif
+#ifndef MY_bfd_define_common_symbol
+#define MY_bfd_define_common_symbol bfd_generic_define_common_symbol
+#endif
+#ifndef MY_bfd_reloc_type_lookup
+#define MY_bfd_reloc_type_lookup tic30_aout_reloc_type_lookup
+#endif
+#ifndef MY_bfd_reloc_name_lookup
+#define MY_bfd_reloc_name_lookup tic30_aout_reloc_name_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_just_syms
+#define MY_bfd_link_just_syms _bfd_generic_link_just_syms
+#endif
+#ifndef MY_bfd_copy_link_hash_symbol_type
+#define MY_bfd_copy_link_hash_symbol_type \
+ _bfd_generic_copy_link_hash_symbol_type
+#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_copy_private_header_data
+#define MY_bfd_copy_private_header_data _bfd_generic_bfd_copy_private_header_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_is_target_special_symbol
+#define MY_bfd_is_target_special_symbol \
+ ((bfd_boolean (*) (bfd *, asymbol *)) bfd_false)
+#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_synthetic_symtab
+#define MY_get_synthetic_symtab \
+ _bfd_nodynamic_get_synthetic_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. */
+ 0, /* match priority. */
+ 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, /* Headers. */
+ {_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),
+
+ NULL,
+
+ MY_backend_data
+};
+#endif /* MY_BFD_TARGET */
diff --git a/bfd/aout0.c b/bfd/aout0.c
new file mode 100644
index 0000000..a0370e3
--- /dev/null
+++ b/bfd/aout0.c
@@ -0,0 +1,38 @@
+/* BFD backend for SunOS style a.out with flags set to 0
+ Copyright (C) 1990-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#define TARGETNAME "a.out-zero-big"
+
+/* Do not "beautify" the CONCAT* macro args. Traditional C will not
+ remove whitespace added here, and thus will fail to concatenate
+ the tokens. */
+#define MY(OP) CONCAT2 (aout0_be_,OP)
+
+#include "sysdep.h"
+#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 0000000..a6f6df3
--- /dev/null
+++ b/bfd/aout32.c
@@ -0,0 +1,24 @@
+/* BFD back-end for 32-bit a.out files.
+ Copyright (C) 1990-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#define ARCH_SIZE 32
+
+#include "aoutx.h"
diff --git a/bfd/aout64.c b/bfd/aout64.c
new file mode 100644
index 0000000..6474a76
--- /dev/null
+++ b/bfd/aout64.c
@@ -0,0 +1,32 @@
+/* BFD back-end for 64-bit a.out files.
+ Copyright (C) 1990-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, 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 0000000..63c16d9
--- /dev/null
+++ b/bfd/aoutf1.h
@@ -0,0 +1,792 @@
+/* A.out "format 1" file handling code for BFD.
+ Copyright (C) 1990-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.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. */
+
+#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
+
+/* 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 bfd_boolean
+sunos_merge_private_bfd_data (bfd *ibfd, bfd *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 (bfd *abfd, enum machine_type machtype)
+{
+ /* Determine the architecture and machine type of the object file. */
+ enum bfd_architecture arch;
+ unsigned 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_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 (bfd *abfd)
+{
+ switch (bfd_get_arch (abfd))
+ {
+ case bfd_arch_sparc:
+ 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 bfd_boolean
+sunos_write_object_contents (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;
+ 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, (long)(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
+ struct regs c_regs; /* 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
+ struct regs c_regs; /* 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. */
+};
+
+/* Byte-swap in the Sun-3 core structure. */
+
+static void
+swapcore_sun3 (bfd *abfd, char *ext, struct internal_sunos_core *intcore)
+{
+ struct external_sun3_core *extcore = (struct external_sun3_core *) ext;
+
+ intcore->c_magic = H_GET_32 (abfd, &extcore->c_magic);
+ intcore->c_len = H_GET_32 (abfd, &extcore->c_len);
+ intcore->c_regs_pos = offsetof (struct external_sun3_core, 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 = H_GET_32 (abfd, &extcore->c_signo);
+ intcore->c_tsize = H_GET_32 (abfd, &extcore->c_tsize);
+ intcore->c_dsize = H_GET_32 (abfd, &extcore->c_dsize);
+ intcore->c_data_addr = N_DATADDR (intcore->c_aouthdr);
+ intcore->c_ssize = H_GET_32 (abfd, &extcore->c_ssize);
+ memcpy (intcore->c_cmdname, extcore->c_cmdname, sizeof (intcore->c_cmdname));
+ intcore->fp_stuff_pos = offsetof (struct external_sun3_core, fp_stuff);
+ /* FP stuff takes up whole rest of struct, except c_ucode. */
+ intcore->fp_stuff_size = intcore->c_len - (sizeof extcore->c_ucode) -
+ offsetof (struct external_sun3_core, fp_stuff);
+ /* Ucode is the last thing in the struct -- just before the end. */
+ intcore->c_ucode = 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 (bfd *abfd, char *ext, struct internal_sunos_core *intcore)
+{
+ struct external_sparc_core *extcore = (struct external_sparc_core *) ext;
+
+ intcore->c_magic = H_GET_32 (abfd, &extcore->c_magic);
+ intcore->c_len = H_GET_32 (abfd, &extcore->c_len);
+ intcore->c_regs_pos = offsetof (struct external_sparc_core, 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 = H_GET_32 (abfd, &extcore->c_signo);
+ intcore->c_tsize = H_GET_32 (abfd, &extcore->c_tsize);
+ intcore->c_dsize = H_GET_32 (abfd, &extcore->c_dsize);
+ intcore->c_data_addr = N_DATADDR (intcore->c_aouthdr);
+ intcore->c_ssize = H_GET_32 (abfd, &extcore->c_ssize);
+ memcpy (intcore->c_cmdname, extcore->c_cmdname, sizeof (intcore->c_cmdname));
+ intcore->fp_stuff_pos = offsetof (struct external_sparc_core, fp_stuff);
+ /* FP stuff takes up whole rest of struct, except c_ucode. */
+ intcore->fp_stuff_size = intcore->c_len - (sizeof extcore->c_ucode) -
+ offsetof (struct external_sparc_core, fp_stuff);
+ /* Ucode is the last thing in the struct -- just before the end. */
+ intcore->c_ucode = 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 = H_GET_32 (abfd, &extcore->c_regs.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 (bfd *abfd, char *ext, struct internal_sunos_core *intcore)
+{
+ struct external_solaris_bcp_core *extcore =
+ (struct external_solaris_bcp_core *) ext;
+
+ intcore->c_magic = H_GET_32 (abfd, &extcore->c_magic);
+ intcore->c_len = H_GET_32 (abfd, &extcore->c_len);
+ intcore->c_regs_pos = offsetof (struct external_solaris_bcp_core, 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 ((void *) &intcore->c_aouthdr, 0, sizeof (struct internal_exec));
+ intcore->c_data_addr = H_GET_32 (abfd, &extcore->c_exdata_datorg);
+ intcore->c_signo = H_GET_32 (abfd, &extcore->c_signo);
+ intcore->c_tsize = H_GET_32 (abfd, &extcore->c_tsize);
+ intcore->c_dsize = H_GET_32 (abfd, &extcore->c_dsize);
+ intcore->c_ssize = H_GET_32 (abfd, &extcore->c_ssize);
+ memcpy (intcore->c_cmdname, extcore->c_cmdname, sizeof (intcore->c_cmdname));
+ intcore->fp_stuff_pos =
+ offsetof (struct external_solaris_bcp_core, fp_stuff);
+ /* FP stuff takes up whole rest of struct, except c_ucode. */
+ intcore->fp_stuff_size = intcore->c_len - (sizeof extcore->c_ucode) -
+ offsetof (struct external_solaris_bcp_core, fp_stuff);
+ /* Ucode is the last thing in the struct -- just before the end */
+ intcore->c_ucode = 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 = H_GET_32 (abfd, &extcore->c_regs.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 (bfd *abfd)
+{
+ unsigned char longbuf[4]; /* Raw bytes of various header fields. */
+ bfd_size_type core_size, amt;
+ 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;
+ flagword flags;
+
+ if (bfd_bread ((void *) longbuf, (bfd_size_type) sizeof (longbuf), abfd)
+ != sizeof (longbuf))
+ return NULL;
+ core_mag = H_GET_32 (abfd, longbuf);
+
+ if (core_mag != CORE_MAGIC)
+ return NULL;
+
+ /* SunOS core headers can vary in length; second word is size; */
+ if (bfd_bread ((void *) longbuf, (bfd_size_type) sizeof (longbuf), abfd)
+ != sizeof (longbuf))
+ return NULL;
+ core_size = H_GET_32 (abfd, longbuf);
+ /* Sanity check. */
+ if (core_size > 20000)
+ return NULL;
+
+ if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
+ return NULL;
+
+ amt = core_size + sizeof (struct mergem);
+ mergem = bfd_zalloc (abfd, amt);
+ if (mergem == NULL)
+ return NULL;
+
+ extcore = mergem->external_core;
+
+ if ((bfd_bread ((void *) extcore, core_size, abfd)) != core_size)
+ {
+ loser:
+ bfd_release (abfd, (char *) mergem);
+ abfd->tdata.any = NULL;
+ bfd_section_list_clear (abfd);
+ return NULL;
+ }
+
+ /* 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. */
+ goto loser;
+ }
+
+ abfd->tdata.sun_core_data = &mergem->suncoredata;
+ abfd->tdata.sun_core_data->hdr = core;
+
+ /* Create the sections. */
+ flags = SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS;
+ core_stacksec (abfd) = bfd_make_section_anyway_with_flags (abfd, ".stack",
+ flags);
+ if (core_stacksec (abfd) == NULL)
+ /* bfd_release frees everything allocated after it's arg. */
+ goto loser;
+
+ flags = SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS;
+ core_datasec (abfd) = bfd_make_section_anyway_with_flags (abfd, ".data",
+ flags);
+ if (core_datasec (abfd) == NULL)
+ goto loser;
+
+ flags = SEC_HAS_CONTENTS;
+ core_regsec (abfd) = bfd_make_section_anyway_with_flags (abfd, ".reg",
+ flags);
+ if (core_regsec (abfd) == NULL)
+ goto loser;
+
+ flags = SEC_HAS_CONTENTS;
+ core_reg2sec (abfd) = bfd_make_section_anyway_with_flags (abfd, ".reg2",
+ flags);
+ if (core_reg2sec (abfd) == NULL)
+ goto loser;
+
+ core_stacksec (abfd)->size = core->c_ssize;
+ core_datasec (abfd)->size = core->c_dsize;
+ core_regsec (abfd)->size = core->c_regs_size;
+ core_reg2sec (abfd)->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;
+
+ return abfd->xvec;
+}
+
+static char *
+sunos4_core_file_failing_command (bfd *abfd)
+{
+ return core_hdr (abfd)->hdr->c_cmdname;
+}
+
+static int
+sunos4_core_file_failing_signal (bfd *abfd)
+{
+ return core_hdr (abfd)->hdr->c_signo;
+}
+
+static bfd_boolean
+sunos4_core_file_matches_executable_p (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;
+}
+
+#define MY_set_sizes sunos4_set_sizes
+
+static bfd_boolean
+sunos4_set_sizes (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 (*) (bfd *, struct bfd_section *)) 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 0000000..9385a98
--- /dev/null
+++ b/bfd/aoutx.h
@@ -0,0 +1,5650 @@
+/* BFD semi-generic back-end for a.out binaries.
+ Copyright (C) 1990-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, 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 sparc_aout_sunos_be_vec
+| #include "aoutf1.h"
+
+ requires all the names from @file{aout32.c}, and produces the jump vector
+
+| sparc_aout_sunos_be_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.ac}
+ 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 "sysdep.h"
+#include "bfd.h"
+#include "safe-ctype.h"
+#include "bfdlink.h"
+
+#include "libaout.h"
+#include "libbfd.h"
+#include "aout/aout64.h"
+#include "aout/stab_gnu.h"
+#include "aout/ar.h"
+
+/*
+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_ext_reloc_in
+#define MY_swap_ext_reloc_in NAME (aout, swap_ext_reloc_in)
+#endif
+
+#ifndef MY_swap_std_reloc_out
+#define MY_swap_std_reloc_out NAME (aout, swap_std_reloc_out)
+#endif
+
+#ifndef MY_swap_ext_reloc_out
+#define MY_swap_ext_reloc_out NAME (aout, swap_ext_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),
+EMPTY_HOWTO (-1),
+EMPTY_HOWTO (-1),
+EMPTY_HOWTO (-1),
+EMPTY_HOWTO (-1),
+EMPTY_HOWTO (-1),
+ HOWTO (16, 0, 2, 0, FALSE, 0, complain_overflow_bitfield,0,"JMP_TABLE", FALSE, 0,0x00000000, FALSE),
+EMPTY_HOWTO (-1),
+EMPTY_HOWTO (-1),
+EMPTY_HOWTO (-1),
+EMPTY_HOWTO (-1),
+EMPTY_HOWTO (-1),
+EMPTY_HOWTO (-1),
+EMPTY_HOWTO (-1),
+EMPTY_HOWTO (-1),
+EMPTY_HOWTO (-1),
+EMPTY_HOWTO (-1),
+EMPTY_HOWTO (-1),
+EMPTY_HOWTO (-1),
+EMPTY_HOWTO (-1),
+EMPTY_HOWTO (-1),
+EMPTY_HOWTO (-1),
+ HOWTO (32, 0, 2, 0, FALSE, 0, complain_overflow_bitfield,0,"RELATIVE", FALSE, 0,0x00000000, FALSE),
+EMPTY_HOWTO (-1),
+EMPTY_HOWTO (-1),
+EMPTY_HOWTO (-1),
+EMPTY_HOWTO (-1),
+EMPTY_HOWTO (-1),
+EMPTY_HOWTO (-1),
+EMPTY_HOWTO (-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) (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_arch_bits_per_address (abfd))
+ {
+ case 32:
+ code = BFD_RELOC_32;
+ break;
+ case 64:
+ code = BFD_RELOC_64;
+ break;
+ }
+
+ if (ext)
+ switch (code)
+ {
+ EXT (BFD_RELOC_8, 0);
+ EXT (BFD_RELOC_16, 1);
+ 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 NULL;
+ }
+ else
+ /* std relocs. */
+ switch (code)
+ {
+ STD (BFD_RELOC_8, 0);
+ 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 NULL;
+ }
+}
+
+reloc_howto_type *
+NAME (aout, reloc_name_lookup) (bfd *abfd, const char *r_name)
+{
+ unsigned int i, size;
+ reloc_howto_type *howto_table;
+
+ if (obj_reloc_entry_size (abfd) == RELOC_EXT_SIZE)
+ {
+ howto_table = howto_table_ext;
+ size = sizeof (howto_table_ext) / sizeof (howto_table_ext[0]);
+ }
+ else
+ {
+ howto_table = howto_table_std;
+ size = sizeof (howto_table_std) / sizeof (howto_table_std[0]);
+ }
+
+ for (i = 0; i < size; i++)
+ if (howto_table[i].name != NULL
+ && strcasecmp (howto_table[i].name, r_name) == 0)
+ return &howto_table[i];
+
+ return 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 *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) (bfd *abfd,
+ struct external_exec *bytes,
+ struct internal_exec *execp)
+{
+ /* 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 ((void *) execp, 0, sizeof (struct internal_exec));
+ /* Now fill in fields in the execp, from the bytes in the raw data. */
+ execp->a_info = 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) (bfd *abfd,
+ struct internal_exec *execp,
+ struct external_exec *bytes)
+{
+ /* Now fill in fields in the raw data, from the fields in the exec struct. */
+ 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. */
+
+bfd_boolean
+NAME (aout, make_sections) (bfd *abfd)
+{
+ if (obj_textsec (abfd) == NULL && bfd_make_section (abfd, ".text") == NULL)
+ return FALSE;
+ if (obj_datasec (abfd) == NULL && bfd_make_section (abfd, ".data") == NULL)
+ return FALSE;
+ if (obj_bsssec (abfd) == NULL && bfd_make_section (abfd, ".bss") == 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,
+ struct internal_exec *execp,
+ const bfd_target *(*callback_to_real_object_p) (bfd *));
+
+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) (bfd *abfd,
+ struct internal_exec *execp,
+ const bfd_target *(*callback_to_real_object_p) (bfd *))
+{
+ struct aout_data_struct *rawptr, *oldrawptr;
+ const bfd_target *result;
+ bfd_size_type amt = sizeof (* rawptr);
+
+ rawptr = (struct aout_data_struct *) bfd_zalloc (abfd, amt);
+ if (rawptr == NULL)
+ return NULL;
+
+ 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;
+ /* Copy in the internal_exec struct. */
+ *(abfd->tdata.aout_data->a.hdr) = *execp;
+ 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) = 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))
+ goto error_ret;
+
+ obj_datasec (abfd)->size = execp->a_data;
+ obj_bsssec (abfd)->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);
+ /* 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)->size)
+ && execp->a_trsize == 0
+ && execp->a_drsize == 0))
+ 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)
+ return result;
+
+ error_ret:
+ bfd_release (abfd, rawptr);
+ abfd->tdata.aout_data = oldrawptr;
+ return NULL;
+}
+
+/*
+FUNCTION
+ aout_@var{size}_mkobject
+
+SYNOPSIS
+ bfd_boolean aout_@var{size}_mkobject, (bfd *abfd);
+
+DESCRIPTION
+ Initialize BFD @var{abfd} for use with a.out files.
+*/
+
+bfd_boolean
+NAME (aout, mkobject) (bfd *abfd)
+{
+ struct aout_data_struct *rawptr;
+ bfd_size_type amt = sizeof (* rawptr);
+
+ bfd_set_error (bfd_error_system_call);
+
+ rawptr = (struct aout_data_struct *) bfd_zalloc (abfd, amt);
+ if (rawptr == NULL)
+ return FALSE;
+
+ abfd->tdata.aout_data = rawptr;
+ exec_hdr (abfd) = &(rawptr->e);
+
+ obj_textsec (abfd) = NULL;
+ obj_datasec (abfd) = NULL;
+ obj_bsssec (abfd) = 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,
+ bfd_boolean *unknown);
+
+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) (enum bfd_architecture arch,
+ unsigned long machine,
+ bfd_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_v8plus
+ || machine == bfd_mach_sparc_v8plusa
+ || machine == bfd_mach_sparc_v8plusb
+ || machine == bfd_mach_sparc_v9
+ || machine == bfd_mach_sparc_v9a
+ || machine == bfd_mach_sparc_v9b)
+ 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
+ || machine == bfd_mach_i386_i386
+ || machine == bfd_mach_i386_i386_intel_syntax)
+ arch_flags = M_386;
+ 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_mips9000:
+ case bfd_mach_mips10000:
+ case bfd_mach_mips12000:
+ case bfd_mach_mips14000:
+ case bfd_mach_mips16000:
+ case bfd_mach_mips16:
+ case bfd_mach_mipsisa32:
+ case bfd_mach_mipsisa32r2:
+ case bfd_mach_mipsisa32r3:
+ case bfd_mach_mipsisa32r5:
+ case bfd_mach_mipsisa32r6:
+ case bfd_mach_mips5:
+ case bfd_mach_mipsisa64:
+ case bfd_mach_mipsisa64r2:
+ case bfd_mach_mipsisa64r3:
+ case bfd_mach_mipsisa64r5:
+ case bfd_mach_mipsisa64r6:
+ case bfd_mach_mips_sb1:
+ case bfd_mach_mips_xlr:
+ /* FIXME: These should be MIPS3, MIPS4, MIPS16, MIPS32, etc. */
+ 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;
+
+ case bfd_arch_cris:
+ if (machine == 0 || machine == 255)
+ arch_flags = M_CRIS;
+ break;
+
+ case bfd_arch_m88k:
+ *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
+ bfd_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.
+*/
+
+bfd_boolean
+NAME (aout, set_arch_mach) (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)
+ {
+ bfd_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_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 (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)->size;
+ vma += obj_textsec (abfd)->size;
+
+ /* Data. */
+ if (!obj_datasec (abfd)->user_set_vma)
+ {
+ obj_textsec (abfd)->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)->size;
+ vma += obj_datasec (abfd)->size;
+
+ /* BSS. */
+ if (!obj_bsssec (abfd)->user_set_vma)
+ {
+ obj_datasec (abfd)->size += pad;
+ pos += pad;
+ vma += pad;
+ obj_bsssec (abfd)->vma = vma;
+ }
+ else
+ {
+ /* The VMA of the .bss section is set by 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)->size += pad;
+ pos += pad;
+ }
+ }
+ obj_bsssec (abfd)->filepos = pos;
+
+ /* Fix up the exec header. */
+ execp->a_text = obj_textsec (abfd)->size;
+ execp->a_data = obj_datasec (abfd)->size;
+ execp->a_bss = obj_bsssec (abfd)->size;
+ N_SET_MAGIC (*execp, OMAGIC);
+}
+
+static void
+adjust_z_magic (bfd *abfd, struct internal_exec *execp)
+{
+ bfd_size_type data_pad, text_pad;
+ file_ptr text_end;
+ const struct aout_backend_data *abdp;
+ /* TRUE if text includes exec header. */
+ bfd_boolean ztih;
+
+ 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)->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)->size;
+ text_pad += BFD_ALIGN (text_end, adata (abfd).page_size) - text_end;
+ text_end += obj_textsec (abfd)->filepos;
+ }
+ obj_textsec (abfd)->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)->size;
+ obj_datasec (abfd)->vma = BFD_ALIGN (vma, adata (abfd).segment_size);
+ }
+ if (abdp && abdp->zmagic_mapped_contiguous)
+ {
+ asection * text = obj_textsec (abfd);
+ asection * data = obj_datasec (abfd);
+
+ text_pad = data->vma - (text->vma + text->size);
+ /* Only pad the text section if the data
+ section is going to be placed after it. */
+ if (text_pad > 0)
+ text->size += text_pad;
+ }
+ obj_datasec (abfd)->filepos = (obj_textsec (abfd)->filepos
+ + obj_textsec (abfd)->size);
+
+ /* Fix up exec header while we're at it. */
+ execp->a_text = obj_textsec (abfd)->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)->size
+ = align_power (obj_datasec (abfd)->size,
+ obj_bsssec (abfd)->alignment_power);
+ execp->a_data = BFD_ALIGN (obj_datasec (abfd)->size,
+ adata (abfd).page_size);
+ data_pad = execp->a_data - obj_datasec (abfd)->size;
+
+ /* BSS. */
+ if (!obj_bsssec (abfd)->user_set_vma)
+ obj_bsssec (abfd)->vma = (obj_datasec (abfd)->vma
+ + obj_datasec (abfd)->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)->size)
+ execp->a_bss = (data_pad > obj_bsssec (abfd)->size
+ ? 0 : obj_bsssec (abfd)->size - data_pad);
+ else
+ execp->a_bss = obj_bsssec (abfd)->size;
+}
+
+static void
+adjust_n_magic (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)->size;
+ vma += obj_textsec (abfd)->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)->size;
+ pad = align_power (vma, obj_bsssec (abfd)->alignment_power) - vma;
+ obj_datasec (abfd)->size += pad;
+ pos += obj_datasec (abfd)->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)->size;
+ execp->a_data = obj_datasec (abfd)->size;
+ execp->a_bss = obj_bsssec (abfd)->size;
+ N_SET_MAGIC (*execp, NMAGIC);
+}
+
+bfd_boolean
+NAME (aout, adjust_sizes_and_vmas) (bfd *abfd,
+ bfd_size_type *text_size,
+ file_ptr *text_end ATTRIBUTE_UNUSED)
+{
+ 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)->size =
+ align_power (obj_textsec (abfd)->size,
+ obj_textsec (abfd)->alignment_power);
+
+ *text_size = obj_textsec (abfd)->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)->size,
+ obj_textsec (abfd)->alignment_power,
+ obj_datasec (abfd)->vma, obj_datasec (abfd)->size,
+ obj_datasec (abfd)->alignment_power,
+ obj_bsssec (abfd)->vma, obj_bsssec (abfd)->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)->size,
+ obj_textsec (abfd)->filepos,
+ obj_datasec (abfd)->vma, obj_datasec (abfd)->size,
+ obj_datasec (abfd)->filepos,
+ obj_bsssec (abfd)->vma, obj_bsssec (abfd)->size);
+#endif
+
+ return TRUE;
+}
+
+/*
+FUNCTION
+ aout_@var{size}_new_section_hook
+
+SYNOPSIS
+ bfd_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.
+*/
+bfd_boolean
+NAME (aout, new_section_hook) (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;
+ }
+ else if (obj_datasec (abfd) == NULL && !strcmp (newsect->name, ".data"))
+ {
+ obj_datasec (abfd) = newsect;
+ newsect->target_index = N_DATA;
+ }
+ else if (obj_bsssec (abfd) == NULL && !strcmp (newsect->name, ".bss"))
+ {
+ obj_bsssec (abfd) = newsect;
+ newsect->target_index = N_BSS;
+ }
+ }
+
+ /* We allow more than three sections internally. */
+ return _bfd_generic_new_section_hook (abfd, newsect);
+}
+
+bfd_boolean
+NAME (aout, set_section_contents) (bfd *abfd,
+ sec_ptr section,
+ const void * 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))
+ {
+ if (aout_section_merge_with_text_p (abfd, section))
+ section->filepos = obj_textsec (abfd)->filepos +
+ (section->vma - obj_textsec (abfd)->vma);
+ 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, section));
+ bfd_set_error (bfd_error_nonrepresentable_section);
+ return FALSE;
+ }
+ }
+
+ if (count != 0)
+ {
+ if (bfd_seek (abfd, section->filepos + offset, SEEK_SET) != 0
+ || bfd_bwrite (location, count, abfd) != count)
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/* Read the external symbols from an a.out file. */
+
+static bfd_boolean
+aout_get_external_symbols (bfd *abfd)
+{
+ if (obj_aout_external_syms (abfd) == NULL)
+ {
+ bfd_size_type count;
+ struct external_nlist *syms;
+ bfd_size_type amt = exec_hdr (abfd)->a_syms;
+
+ count = amt / EXTERNAL_NLIST_SIZE;
+ if (count == 0)
+ return TRUE; /* Nothing to do. */
+
+#ifdef USE_MMAP
+ if (! bfd_get_file_window (abfd, obj_sym_filepos (abfd), amt,
+ &obj_aout_sym_window (abfd), TRUE))
+ 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 (amt);
+ if (syms == NULL)
+ return FALSE;
+
+ if (bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET) != 0
+ || bfd_bread (syms, amt, abfd) != amt)
+ {
+ 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;
+ bfd_size_type amt = BYTES_IN_WORD;
+
+ /* Get the size of the strings. */
+ if (bfd_seek (abfd, obj_str_filepos (abfd), SEEK_SET) != 0
+ || bfd_bread ((void *) string_chars, amt, abfd) != amt)
+ 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))
+ return FALSE;
+ strings = (char *) obj_aout_string_window (abfd).data;
+#else
+ strings = (char *) bfd_malloc (stringsize + 1);
+ if (strings == NULL)
+ return FALSE;
+
+ /* Skip space for the string count in the buffer for convenience
+ when using indexes. */
+ amt = stringsize - BYTES_IN_WORD;
+ if (bfd_bread (strings + BYTES_IN_WORD, amt, abfd) != amt)
+ {
+ 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 bfd_boolean
+translate_from_native_sym_flags (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. */
+ 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 bfd_boolean
+translate_to_native_sym_flags (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
+ {
+ if (aout_section_merge_with_text_p (abfd, sec))
+ sym_pointer->e_type[0] |= N_TEXT;
+ 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;
+ else if ((cache_ptr->flags & BSF_LOCAL) != 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) (bfd *abfd)
+{
+ bfd_size_type amt = sizeof (aout_symbol_type);
+
+ aout_symbol_type *new_symbol = (aout_symbol_type *) bfd_zalloc (abfd, amt);
+ if (!new_symbol)
+ return NULL;
+ new_symbol->symbol.the_bfd = abfd;
+
+ return &new_symbol->symbol;
+}
+
+/* Translate a set of internal symbols into external symbols. */
+
+bfd_boolean
+NAME (aout, translate_symbol_table) (bfd *abfd,
+ aout_symbol_type *in,
+ struct external_nlist *ext,
+ bfd_size_type count,
+ char *str,
+ bfd_size_type strsize,
+ bfd_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 = H_GET_16 (abfd, ext->e_desc);
+ in->other = H_GET_8 (abfd, ext->e_other);
+ in->type = 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. */
+
+bfd_boolean
+NAME (aout, slurp_symbol_table) (bfd *abfd)
+{
+ struct external_nlist *old_external_syms;
+ aout_symbol_type *cached;
+ bfd_size_type cached_size;
+
+ /* If there's no work to be done, don't do any. */
+ if (obj_aout_symbols (abfd) != 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);
+ if (cached_size == 0)
+ return TRUE; /* Nothing to do. */
+
+ cached_size *= sizeof (aout_symbol_type);
+ cached = (aout_symbol_type *) bfd_zmalloc (cached_size);
+ if (cached == NULL)
+ return FALSE;
+
+ /* 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 == NULL
+ && obj_aout_external_syms (abfd) != 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. */
+
+/* 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 (bfd *abfd,
+ struct bfd_strtab_hash *tab,
+ const char *str,
+ bfd_boolean copy)
+{
+ bfd_boolean hash;
+ bfd_size_type str_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;
+
+ str_index = _bfd_stringtab_add (tab, str, hash, copy);
+
+ if (str_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. */
+ str_index += BYTES_IN_WORD;
+
+ return str_index;
+}
+
+/* Write out a strtab. ABFD is already at the right location in the
+ file. */
+
+static bfd_boolean
+emit_stringtab (bfd *abfd, struct bfd_strtab_hash *tab)
+{
+ bfd_byte buffer[BYTES_IN_WORD];
+ bfd_size_type amt = BYTES_IN_WORD;
+
+ /* The string table starts with the size. */
+ PUT_WORD (abfd, _bfd_stringtab_size (tab) + BYTES_IN_WORD, buffer);
+ if (bfd_bwrite ((void *) buffer, amt, abfd) != amt)
+ return FALSE;
+
+ return _bfd_stringtab_emit (abfd, tab);
+}
+
+bfd_boolean
+NAME (aout, write_syms) (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;
+ bfd_size_type amt;
+
+ 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)
+ {
+ H_PUT_16 (abfd, aout_symbol (g)->desc, nsp.e_desc);
+ H_PUT_8 (abfd, aout_symbol (g)->other, nsp.e_other);
+ H_PUT_8 (abfd, aout_symbol (g)->type, nsp.e_type);
+ }
+ else
+ {
+ H_PUT_16 (abfd, 0, nsp.e_desc);
+ H_PUT_8 (abfd, 0, nsp.e_other);
+ H_PUT_8 (abfd, 0, nsp.e_type);
+ }
+
+ if (! translate_to_native_sym_flags (abfd, g, &nsp))
+ goto error_return;
+
+ amt = EXTERNAL_NLIST_SIZE;
+ if (bfd_bwrite ((void *) &nsp, amt, abfd) != amt)
+ 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, canonicalize_symtab) (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)
+ (bfd *, arelent *, struct reloc_std_external *);
+
+void
+NAME (aout, swap_std_reloc_out) (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;
+
+ /* 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)
+ /* PR gas/3041 a.out relocs against weak symbols
+ must be treated as if they were against externs. */
+ || (sym->flags & BSF_WEAK))
+ {
+ 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)
+ (bfd *, arelent *, struct reloc_ext_external *);
+
+void
+NAME (aout, swap_ext_reloc_out) (bfd *abfd,
+ arelent *g,
+ struct reloc_ext_external *natptr)
+{
+ int r_index;
+ int r_extern;
+ unsigned int r_type;
+ bfd_vma 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) (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 = (((unsigned int) bytes->r_index[0] << 16)
+ | ((unsigned int) 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 = (((unsigned int) bytes->r_index[2] << 16)
+ | ((unsigned int) 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);
+ }
+
+ if (r_type < TABLE_SIZE (howto_table_ext))
+ cache_ptr->howto = howto_table_ext + r_type;
+ else
+ cache_ptr->howto = NULL;
+
+ /* 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 == (unsigned int) RELOC_BASE10
+ || r_type == (unsigned int) RELOC_BASE13
+ || r_type == (unsigned int) 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) (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 = H_GET_32 (abfd, bytes->r_address);
+
+ /* Now the fun stuff. */
+ if (bfd_header_big_endian (abfd))
+ {
+ r_index = (((unsigned int) bytes->r_index[0] << 16)
+ | ((unsigned int) 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 = (((unsigned int) bytes->r_index[2] << 16)
+ | ((unsigned int) 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);
+ if (howto_idx < TABLE_SIZE (howto_table_std))
+ {
+ cache_ptr->howto = howto_table_std + howto_idx;
+ if (cache_ptr->howto->type == (unsigned int) -1)
+ cache_ptr->howto = NULL;
+ }
+ else
+ cache_ptr->howto = NULL;
+
+ /* 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. */
+
+bfd_boolean
+NAME (aout, slurp_reloc_table) (bfd *abfd, sec_ptr asect, asymbol **symbols)
+{
+ bfd_size_type count;
+ bfd_size_type reloc_size;
+ void * relocs;
+ arelent *reloc_cache;
+ size_t each_size;
+ unsigned int counter = 0;
+ arelent *cache_ptr;
+ bfd_size_type amt;
+
+ 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 (reloc_size == 0)
+ return TRUE; /* Nothing to be done. */
+
+ if (bfd_seek (abfd, asect->rel_filepos, SEEK_SET) != 0)
+ return FALSE;
+
+ each_size = obj_reloc_entry_size (abfd);
+
+ count = reloc_size / each_size;
+ if (count == 0)
+ return TRUE; /* Nothing to be done. */
+
+ amt = count * sizeof (arelent);
+ reloc_cache = (arelent *) bfd_zmalloc (amt);
+ if (reloc_cache == NULL)
+ return FALSE;
+
+ relocs = bfd_malloc (reloc_size);
+ if (relocs == NULL)
+ {
+ free (reloc_cache);
+ return FALSE;
+ }
+
+ if (bfd_bread (relocs, reloc_size, abfd) != reloc_size)
+ {
+ free (relocs);
+ free (reloc_cache);
+ return FALSE;
+ }
+
+ cache_ptr = reloc_cache;
+ if (each_size == RELOC_EXT_SIZE)
+ {
+ struct reloc_ext_external *rptr = (struct reloc_ext_external *) relocs;
+
+ for (; counter < count; counter++, rptr++, cache_ptr++)
+ MY_swap_ext_reloc_in (abfd, rptr, cache_ptr, symbols,
+ (bfd_size_type) bfd_get_symcount (abfd));
+ }
+ else
+ {
+ 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_size_type) 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. */
+
+bfd_boolean
+NAME (aout, squirt_out_relocs) (bfd *abfd, asection *section)
+{
+ arelent **generic;
+ unsigned char *native, *natptr;
+ size_t each_size;
+
+ unsigned int count = section->reloc_count;
+ bfd_size_type natsize;
+
+ if (count == 0 || section->orelocation == NULL)
+ return TRUE;
+
+ each_size = obj_reloc_entry_size (abfd);
+ natsize = (bfd_size_type) 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)
+ MY_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_bwrite ((void *) native, 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) (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) (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) (bfd *abfd)
+{
+ if (!NAME (aout, slurp_symbol_table) (abfd))
+ return -1;
+
+ return (bfd_get_symcount (abfd)+1) * (sizeof (aout_symbol_type *));
+}
+
+alent *
+NAME (aout, get_lineno) (bfd *ignore_abfd ATTRIBUTE_UNUSED,
+ asymbol *ignore_symbol ATTRIBUTE_UNUSED)
+{
+ return NULL;
+}
+
+void
+NAME (aout, get_symbol_info) (bfd *ignore_abfd ATTRIBUTE_UNUSED,
+ 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;
+ }
+}
+
+void
+NAME (aout, print_symbol) (bfd *abfd,
+ void * 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 (abfd, (void *)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) (bfd *abfd,
+ bfd_boolean dynamic,
+ void * *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 = (void *) 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) (bfd *abfd,
+ bfd_boolean dynamic,
+ const void * 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. */
+
+bfd_boolean
+NAME (aout, find_nearest_line) (bfd *abfd,
+ asymbol **symbols,
+ asection *section,
+ bfd_vma offset,
+ const char **filename_ptr,
+ const char **functionname_ptr,
+ unsigned int *line_ptr,
+ unsigned int *disriminator_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;
+ bfd_size_type filelen, funclen;
+ char *buf;
+
+ *filename_ptr = abfd->filename;
+ *functionname_ptr = 0;
+ *line_ptr = 0;
+ if (disriminator_ptr)
+ *disriminator_ptr = 0;
+
+ if (symbols != 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)
+ goto done;
+ 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
+ || IS_ABSOLUTE_PATH (main_file_name)
+ || 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 (IS_ABSOLUTE_PATH (main_file_name) || 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 *colon;
+
+ /* 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. */
+ colon = strchr (buf, ':');
+ if (colon != NULL)
+ *colon = '\0';
+ *functionname_ptr = buf;
+ }
+
+ return TRUE;
+}
+
+int
+NAME (aout, sizeof_headers) (bfd *abfd,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED)
+{
+ 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. */
+
+bfd_boolean
+NAME (aout, bfd_free_cached_info) (bfd *abfd)
+{
+ asection *o;
+
+ if (bfd_get_format (abfd) != bfd_object
+ || abfd->tdata.aout_data == NULL)
+ 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 != NULL; o = o->next)
+ BFCI_FREE (o->relocation);
+#undef BFCI_FREE
+
+ return TRUE;
+}
+
+/* a.out link code. */
+
+/* Routine to create an entry in an a.out link hash table. */
+
+struct bfd_hash_entry *
+NAME (aout, link_hash_newfunc) (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 == NULL)
+ ret = (struct aout_link_hash_entry *) bfd_hash_allocate (table,
+ sizeof (* ret));
+ if (ret == NULL)
+ return NULL;
+
+ /* 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. */
+
+bfd_boolean
+NAME (aout, link_hash_table_init) (struct aout_link_hash_table *table,
+ bfd *abfd,
+ struct bfd_hash_entry *(*newfunc)
+ (struct bfd_hash_entry *, struct bfd_hash_table *,
+ const char *),
+ unsigned int entsize)
+{
+ return _bfd_link_hash_table_init (&table->root, abfd, newfunc, entsize);
+}
+
+/* Create an a.out link hash table. */
+
+struct bfd_link_hash_table *
+NAME (aout, link_hash_table_create) (bfd *abfd)
+{
+ struct aout_link_hash_table *ret;
+ bfd_size_type amt = sizeof (* ret);
+
+ ret = (struct aout_link_hash_table *) bfd_malloc (amt);
+ if (ret == NULL)
+ return NULL;
+
+ if (!NAME (aout, link_hash_table_init) (ret, abfd,
+ NAME (aout, link_hash_newfunc),
+ sizeof (struct aout_link_hash_entry)))
+ {
+ free (ret);
+ return NULL;
+ }
+ return &ret->root;
+}
+
+/* Add all symbols from an object file to the hash table. */
+
+static bfd_boolean
+aout_link_add_symbols (bfd *abfd, struct bfd_link_info *info)
+{
+ bfd_boolean (*add_one_symbol)
+ (struct bfd_link_info *, bfd *, const char *, flagword, asection *,
+ bfd_vma, const char *, bfd_boolean, bfd_boolean,
+ struct bfd_link_hash_entry **);
+ struct external_nlist *syms;
+ bfd_size_type sym_count;
+ char *strings;
+ bfd_boolean copy;
+ struct aout_link_hash_entry **sym_hash;
+ struct external_nlist *p;
+ struct external_nlist *pend;
+ bfd_size_type amt;
+
+ 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;
+ }
+
+ if (sym_count == 0)
+ return TRUE; /* Nothing to do. */
+
+ /* 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. */
+ amt = sym_count * sizeof (struct aout_link_hash_entry *);
+ sym_hash = (struct aout_link_hash_entry **) bfd_alloc (abfd, amt);
+ if (sym_hash == NULL)
+ 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 = 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. If there is no next symbol, just look away. */
+ if (p + 1 >= pend)
+ return TRUE;
+ ++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;
+}
+
+/* Free up the internal symbols read from an a.out file. */
+
+static bfd_boolean
+aout_link_free_symbols (bfd *abfd)
+{
+ if (obj_aout_external_syms (abfd) != NULL)
+ {
+#ifdef USE_MMAP
+ bfd_free_window (&obj_aout_sym_window (abfd));
+#else
+ free ((void *) obj_aout_external_syms (abfd));
+#endif
+ obj_aout_external_syms (abfd) = NULL;
+ }
+ if (obj_aout_external_strings (abfd) != NULL)
+ {
+#ifdef USE_MMAP
+ bfd_free_window (&obj_aout_string_window (abfd));
+#else
+ free ((void *) obj_aout_external_strings (abfd));
+#endif
+ obj_aout_external_strings (abfd) = NULL;
+ }
+ return TRUE;
+}
+
+/* Add symbols from an a.out object file. */
+
+static bfd_boolean
+aout_link_add_object_symbols (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;
+}
+
+/* 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 bfd_boolean
+aout_link_check_ar_symbols (bfd *abfd,
+ struct bfd_link_info *info,
+ bfd_boolean *pneeded,
+ bfd **subsbfd)
+{
+ 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 = 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 == 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, whether to include this object is target
+ dependant for backward compatibility.
+
+ 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 it has not been implemented
+ yet. However, it might be correct. */
+ if (h->type == bfd_link_hash_common)
+ {
+ int skip = 0;
+
+ switch (info->common_skip_ar_symbols)
+ {
+ case bfd_link_common_skip_text:
+ skip = (type == (N_TEXT | N_EXT));
+ break;
+ case bfd_link_common_skip_data:
+ skip = (type == (N_DATA | N_EXT));
+ break;
+ default:
+ case bfd_link_common_skip_all:
+ skip = 1;
+ break;
+ }
+
+ if (skip)
+ continue;
+ }
+
+ if (!(*info->callbacks
+ ->add_archive_element) (info, abfd, name, subsbfd))
+ 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 == 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, subsbfd))
+ 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, subsbfd))
+ return FALSE;
+ *pneeded = TRUE;
+ return TRUE;
+ }
+ }
+ }
+
+ /* We do not need this object file. */
+ 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 bfd_boolean
+aout_link_check_archive_element (bfd *abfd,
+ struct bfd_link_info *info,
+ struct bfd_link_hash_entry *h ATTRIBUTE_UNUSED,
+ const char *name ATTRIBUTE_UNUSED,
+ bfd_boolean *pneeded)
+{
+ bfd *oldbfd;
+ bfd_boolean needed;
+
+ if (!aout_get_external_symbols (abfd))
+ return FALSE;
+
+ oldbfd = abfd;
+ if (!aout_link_check_ar_symbols (abfd, info, pneeded, &abfd))
+ return FALSE;
+
+ needed = *pneeded;
+ if (needed)
+ {
+ /* Potentially, the add_archive_element hook may have set a
+ substitute BFD for us. */
+ if (abfd != oldbfd)
+ {
+ if (!info->keep_memory
+ && !aout_link_free_symbols (oldbfd))
+ return FALSE;
+ if (!aout_get_external_symbols (abfd))
+ return FALSE;
+ }
+ if (!aout_link_add_symbols (abfd, info))
+ return FALSE;
+ }
+
+ if (!info->keep_memory || !needed)
+ {
+ if (!aout_link_free_symbols (abfd))
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/* Given an a.out BFD, add symbols to the global hash table as
+ appropriate. */
+
+bfd_boolean
+NAME (aout, link_add_symbols) (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;
+ }
+}
+
+/* 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. */
+ void * 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;
+};
+
+/* The function to create a new entry in the header file hash table. */
+
+static struct bfd_hash_entry *
+aout_link_includes_newfunc (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 == NULL)
+ ret = (struct aout_link_includes_entry *)
+ bfd_hash_allocate (table, sizeof (* ret));
+ if (ret == NULL)
+ return NULL;
+
+ /* 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;
+}
+
+/* Write out a symbol that was not associated with an a.out input
+ object. */
+
+static bfd_boolean
+aout_link_write_other_symbol (struct bfd_hash_entry *bh, void *data)
+{
+ struct aout_link_hash_entry *h = (struct aout_link_hash_entry *) bh;
+ struct aout_final_link_info *flaginfo = (struct aout_final_link_info *) data;
+ bfd *output_bfd;
+ int type;
+ bfd_vma val;
+ struct external_nlist outsym;
+ bfd_size_type indx;
+ bfd_size_type amt;
+
+ if (h->root.type == bfd_link_hash_warning)
+ {
+ h = (struct aout_link_hash_entry *) h->root.u.i.link;
+ if (h->root.type == bfd_link_hash_new)
+ return TRUE;
+ }
+
+ output_bfd = flaginfo->output_bfd;
+
+ if (aout_backend_info (output_bfd)->write_dynamic_symbol != NULL)
+ {
+ if (! ((*aout_backend_info (output_bfd)->write_dynamic_symbol)
+ (output_bfd, flaginfo->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
+ && (flaginfo->info->strip == strip_all
+ || (flaginfo->info->strip == strip_some
+ && bfd_hash_lookup (flaginfo->info->keep_hash, h->root.root.string,
+ FALSE, FALSE) == NULL)))
+ return TRUE;
+
+ switch (h->root.type)
+ {
+ default:
+ case bfd_link_hash_warning:
+ 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;
+ break;
+ case bfd_link_hash_indirect:
+ /* We ignore these symbols, since the indirected symbol is
+ already in the hash table. */
+ return TRUE;
+ }
+
+ H_PUT_8 (output_bfd, type, outsym.e_type);
+ H_PUT_8 (output_bfd, 0, outsym.e_other);
+ H_PUT_16 (output_bfd, 0, outsym.e_desc);
+ indx = add_to_stringtab (output_bfd, flaginfo->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);
+
+ amt = EXTERNAL_NLIST_SIZE;
+ if (bfd_seek (output_bfd, flaginfo->symoff, SEEK_SET) != 0
+ || bfd_bwrite ((void *) &outsym, amt, output_bfd) != amt)
+ /* FIXME: No way to handle errors. */
+ abort ();
+
+ flaginfo->symoff += EXTERNAL_NLIST_SIZE;
+ h->indx = obj_aout_external_sym_count (output_bfd);
+ ++obj_aout_external_sym_count (output_bfd);
+
+ return TRUE;
+}
+
+/* Handle a link order which is supposed to generate a reloc. */
+
+static bfd_boolean
+aout_link_reloc_link_order (struct aout_final_link_info *flaginfo,
+ 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 = NULL;
+ struct reloc_std_external srel;
+ struct reloc_ext_external erel;
+ void * rel_ptr;
+ bfd_size_type amt;
+
+ 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 == flaginfo->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 (flaginfo->output_bfd, flaginfo->info,
+ pr->u.name, FALSE, FALSE, TRUE));
+ if (h != 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->root.root, flaginfo))
+ return FALSE;
+ r_index = h->indx;
+ }
+ else
+ {
+ if (! ((*flaginfo->info->callbacks->unattached_reloc)
+ (flaginfo->info, pr->u.name, NULL, NULL, (bfd_vma) 0)))
+ return FALSE;
+ r_index = 0;
+ }
+ }
+
+ howto = bfd_reloc_type_lookup (flaginfo->output_bfd, pr->reloc);
+ if (howto == 0)
+ {
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+
+ if (o == obj_textsec (flaginfo->output_bfd))
+ reloff_ptr = &flaginfo->treloff;
+ else if (o == obj_datasec (flaginfo->output_bfd))
+ reloff_ptr = &flaginfo->dreloff;
+ else
+ abort ();
+
+ if (obj_reloc_entry_size (flaginfo->output_bfd) == RELOC_STD_SIZE)
+ {
+#ifdef MY_put_reloc
+ MY_put_reloc (flaginfo->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 = (int) 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 (flaginfo->output_bfd, p->offset, srel.r_address);
+ if (bfd_header_big_endian (flaginfo->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 = (void *) &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;
+ bfd_boolean ok;
+
+ size = bfd_get_reloc_size (howto);
+ buf = (bfd_byte *) bfd_zmalloc (size);
+ if (buf == NULL)
+ return FALSE;
+ r = MY_relocate_contents (howto, flaginfo->output_bfd,
+ (bfd_vma) pr->addend, buf);
+ switch (r)
+ {
+ case bfd_reloc_ok:
+ break;
+ default:
+ case bfd_reloc_outofrange:
+ abort ();
+ case bfd_reloc_overflow:
+ if (! ((*flaginfo->info->callbacks->reloc_overflow)
+ (flaginfo->info, NULL,
+ (p->type == bfd_section_reloc_link_order
+ ? bfd_section_name (flaginfo->output_bfd,
+ pr->u.section)
+ : pr->u.name),
+ howto->name, pr->addend, NULL, NULL, (bfd_vma) 0)))
+ {
+ free (buf);
+ return FALSE;
+ }
+ break;
+ }
+ ok = bfd_set_section_contents (flaginfo->output_bfd, o, (void *) buf,
+ (file_ptr) p->offset, size);
+ free (buf);
+ if (! ok)
+ return FALSE;
+ }
+ }
+ else
+ {
+#ifdef MY_put_ext_reloc
+ MY_put_ext_reloc (flaginfo->output_bfd, r_extern, r_index, p->offset,
+ howto, &erel, pr->addend);
+#else
+ PUT_WORD (flaginfo->output_bfd, p->offset, erel.r_address);
+
+ if (bfd_header_big_endian (flaginfo->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 (flaginfo->output_bfd, (bfd_vma) pr->addend, erel.r_addend);
+#endif /* MY_put_ext_reloc */
+
+ rel_ptr = (void *) &erel;
+ }
+
+ amt = obj_reloc_entry_size (flaginfo->output_bfd);
+ if (bfd_seek (flaginfo->output_bfd, *reloff_ptr, SEEK_SET) != 0
+ || bfd_bwrite (rel_ptr, amt, flaginfo->output_bfd) != amt)
+ return FALSE;
+
+ *reloff_ptr += obj_reloc_entry_size (flaginfo->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 (flaginfo->output_bfd)
+ && (reloff_ptr != &flaginfo->treloff
+ || (*reloff_ptr
+ <= obj_datasec (flaginfo->output_bfd)->rel_filepos)));
+
+ return TRUE;
+}
+
+/* Get the section corresponding to a reloc index. */
+
+static INLINE asection *
+aout_reloc_index_to_section (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 ();
+ }
+ return NULL;
+}
+
+/* Relocate an a.out section using standard a.out relocs. */
+
+static bfd_boolean
+aout_link_input_section_std (struct aout_final_link_info *flaginfo,
+ bfd *input_bfd,
+ asection *input_section,
+ struct reloc_std_external *relocs,
+ bfd_size_type rel_size,
+ bfd_byte *contents)
+{
+ bfd_boolean (*check_dynamic_reloc)
+ (struct bfd_link_info *, bfd *, asection *,
+ struct aout_link_hash_entry *, void *, bfd_byte *, bfd_boolean *,
+ bfd_vma *);
+ bfd *output_bfd;
+ bfd_boolean relocatable;
+ struct external_nlist *syms;
+ char *strings;
+ struct aout_link_hash_entry **sym_hashes;
+ int *symbol_map;
+ bfd_size_type reloc_count;
+ struct reloc_std_external *rel;
+ struct reloc_std_external *rel_end;
+
+ output_bfd = flaginfo->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);
+
+ relocatable = flaginfo->info->relocatable;
+ syms = obj_aout_external_syms (input_bfd);
+ strings = obj_aout_external_strings (input_bfd);
+ sym_hashes = obj_aout_sym_hashes (input_bfd);
+ symbol_map = flaginfo->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 = (((unsigned int) rel->r_index[0] << 16)
+ | ((unsigned int) 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 = (((unsigned int) rel->r_index[2] << 16)
+ | ((unsigned int) 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);
+ if (howto_idx < TABLE_SIZE (howto_table_std))
+ howto = howto_table_std + howto_idx;
+ else
+ howto = NULL;
+ }
+#endif
+
+ if (howto == NULL)
+ {
+ (*flaginfo->info->callbacks->einfo)
+ (_("%P: %B: unexpected relocation type\n"), input_bfd);
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+
+ if (relocatable)
+ {
+ /* We are generating a relocatable 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 != 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->root.root,
+ flaginfo))
+ return FALSE;
+ }
+ r_index = h->indx;
+ }
+ else
+ {
+ const char *name;
+
+ name = strings + GET_WORD (input_bfd,
+ syms[r_index].e_strx);
+ if (! ((*flaginfo->info->callbacks->unattached_reloc)
+ (flaginfo->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
+ {
+ bfd_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 != 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 != 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)
+ {
+ bfd_boolean skip;
+
+ if (! ((*check_dynamic_reloc)
+ (flaginfo->info, input_bfd, input_section, h,
+ (void *) 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 && ! flaginfo->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 (! ((*flaginfo->info->callbacks->undefined_symbol)
+ (flaginfo->info, name, input_bfd, input_section,
+ r_addr, TRUE)))
+ 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 = NULL;
+ 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 (! ((*flaginfo->info->callbacks->reloc_overflow)
+ (flaginfo->info, (h ? &h->root : NULL), 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 bfd_boolean
+aout_link_input_section_ext (struct aout_final_link_info *flaginfo,
+ bfd *input_bfd,
+ asection *input_section,
+ struct reloc_ext_external *relocs,
+ bfd_size_type rel_size,
+ bfd_byte *contents)
+{
+ bfd_boolean (*check_dynamic_reloc)
+ (struct bfd_link_info *, bfd *, asection *,
+ struct aout_link_hash_entry *, void *, bfd_byte *, bfd_boolean *,
+ bfd_vma *);
+ bfd *output_bfd;
+ bfd_boolean relocatable;
+ struct external_nlist *syms;
+ char *strings;
+ struct aout_link_hash_entry **sym_hashes;
+ int *symbol_map;
+ bfd_size_type reloc_count;
+ struct reloc_ext_external *rel;
+ struct reloc_ext_external *rel_end;
+
+ output_bfd = flaginfo->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);
+
+ relocatable = flaginfo->info->relocatable;
+ syms = obj_aout_external_syms (input_bfd);
+ strings = obj_aout_external_strings (input_bfd);
+ sym_hashes = obj_aout_sym_hashes (input_bfd);
+ symbol_map = flaginfo->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 = (((unsigned int) rel->r_index[0] << 16)
+ | ((unsigned int) 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 = (((unsigned int) rel->r_index[2] << 16)
+ | ((unsigned int) 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);
+
+ if (r_type >= TABLE_SIZE (howto_table_ext))
+ {
+ (*flaginfo->info->callbacks->einfo)
+ (_("%P: %B: unexpected relocation type\n"), input_bfd);
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+
+ if (relocatable)
+ {
+ /* We are generating a relocatable output file, and must
+ modify the reloc accordingly. */
+ if (r_extern
+ || r_type == (unsigned int) RELOC_BASE10
+ || r_type == (unsigned int) RELOC_BASE13
+ || r_type == (unsigned int) 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 == (unsigned int) RELOC_BASE10
+ || r_type == (unsigned int) RELOC_BASE13
+ || r_type == (unsigned int) RELOC_BASE22)
+ h = NULL;
+ else
+ h = sym_hashes[r_index];
+ if (h != 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->root.root,
+ flaginfo))
+ return FALSE;
+ }
+ r_index = h->indx;
+ }
+ else
+ {
+ const char *name;
+
+ name = strings + GET_WORD (input_bfd,
+ syms[r_index].e_strx);
+ if (! ((*flaginfo->info->callbacks->unattached_reloc)
+ (flaginfo->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
+ {
+ bfd_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 != 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 != NULL
+ && h->root.type == bfd_link_hash_undefweak)
+ relocation = 0;
+ else
+ {
+ hundef = TRUE;
+ relocation = 0;
+ }
+ }
+ else if (r_type == (unsigned int) RELOC_BASE10
+ || r_type == (unsigned int) RELOC_BASE13
+ || r_type == (unsigned int) 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 = 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)
+ {
+ bfd_boolean skip;
+
+ if (! ((*check_dynamic_reloc)
+ (flaginfo->info, input_bfd, input_section, h,
+ (void *) 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
+ && ! flaginfo->info->shared
+ && r_type != (unsigned int) RELOC_BASE10
+ && r_type != (unsigned int) RELOC_BASE13
+ && r_type != (unsigned int) 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 (! ((*flaginfo->info->callbacks->undefined_symbol)
+ (flaginfo->info, name, input_bfd, input_section,
+ r_addr, TRUE)))
+ return FALSE;
+ }
+
+ if (r_type != (unsigned int) 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 = NULL;
+ else if (r_extern
+ || r_type == (unsigned int) RELOC_BASE10
+ || r_type == (unsigned int) RELOC_BASE13
+ || r_type == (unsigned int) 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 (! ((*flaginfo->info->callbacks->reloc_overflow)
+ (flaginfo->info, (h ? &h->root : NULL), name,
+ howto_table_ext[r_type].name,
+ r_addend, input_bfd, input_section, r_addr)))
+ return FALSE;
+ }
+ break;
+ }
+ }
+ }
+ }
+
+ return TRUE;
+}
+
+/* Link an a.out section into the output file. */
+
+static bfd_boolean
+aout_link_input_section (struct aout_final_link_info *flaginfo,
+ bfd *input_bfd,
+ asection *input_section,
+ file_ptr *reloff_ptr,
+ bfd_size_type rel_size)
+{
+ bfd_size_type input_size;
+ void * relocs;
+
+ /* Get the section contents. */
+ input_size = input_section->size;
+ if (! bfd_get_section_contents (input_bfd, input_section,
+ (void *) flaginfo->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 = flaginfo->relocs;
+ if (rel_size > 0)
+ {
+ if (bfd_seek (input_bfd, input_section->rel_filepos, SEEK_SET) != 0
+ || bfd_bread (relocs, 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 (flaginfo, input_bfd, input_section,
+ (struct reloc_std_external *) relocs,
+ rel_size, flaginfo->contents))
+ return FALSE;
+ }
+ else
+ {
+ if (! aout_link_input_section_ext (flaginfo, input_bfd, input_section,
+ (struct reloc_ext_external *) relocs,
+ rel_size, flaginfo->contents))
+ return FALSE;
+ }
+
+ /* Write out the section contents. */
+ if (! bfd_set_section_contents (flaginfo->output_bfd,
+ input_section->output_section,
+ (void *) flaginfo->contents,
+ (file_ptr) input_section->output_offset,
+ input_size))
+ return FALSE;
+
+ /* If we are producing relocatable output, the relocs were
+ modified, and we now write them out. */
+ if (flaginfo->info->relocatable && rel_size > 0)
+ {
+ if (bfd_seek (flaginfo->output_bfd, *reloff_ptr, SEEK_SET) != 0)
+ return FALSE;
+ if (bfd_bwrite (relocs, rel_size, flaginfo->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 (flaginfo->output_bfd)
+ && (reloff_ptr != &flaginfo->treloff
+ || (*reloff_ptr
+ <= obj_datasec (flaginfo->output_bfd)->rel_filepos)));
+ }
+
+ return TRUE;
+}
+
+/* Adjust and write out the symbols for an a.out file. Set the new
+ symbol indices into a symbol_map. */
+
+static bfd_boolean
+aout_link_write_symbols (struct aout_final_link_info *flaginfo, 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;
+ struct external_nlist *sym;
+ struct external_nlist *sym_end;
+ struct aout_link_hash_entry **sym_hash;
+ int *symbol_map;
+ bfd_boolean pass;
+ bfd_boolean skip_next;
+
+ output_bfd = flaginfo->output_bfd;
+ sym_count = obj_aout_external_sym_count (input_bfd);
+ strings = obj_aout_external_strings (input_bfd);
+ strip = flaginfo->info->strip;
+ discard = flaginfo->info->discard;
+ outsym = flaginfo->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 (flaginfo->info->keep_hash, input_bfd->filename,
+ FALSE, FALSE) != NULL)
+ && discard != discard_all)
+ {
+ H_PUT_8 (output_bfd, N_TEXT, outsym->e_type);
+ H_PUT_8 (output_bfd, 0, outsym->e_other);
+ H_PUT_16 (output_bfd, 0, outsym->e_desc);
+ strtab_index = add_to_stringtab (output_bfd, flaginfo->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 = flaginfo->symbol_map;
+ memset (symbol_map, 0, (size_t) 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;
+ bfd_boolean skip;
+ asection *symsec;
+ bfd_vma val = 0;
+ bfd_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 = 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
+ && h->root.type != bfd_link_hash_warning)
+ 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 != NULL
+ && 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 (flaginfo->info->keep_hash, name, FALSE, FALSE)
+ == NULL)
+ skip = TRUE;
+ break;
+ case strip_all:
+ skip = TRUE;
+ break;
+ }
+ if (skip)
+ {
+ if (h != 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 == 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 == 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 != 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 != 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:
+ case discard_sec_merge:
+ 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 == (int) 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 = H_GET_8 (input_bfd, incl_sym->e_type);
+ if (incl_type == (int) N_EINCL)
+ {
+ if (nest == 0)
+ break;
+ --nest;
+ }
+ else if (incl_type == (int) 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 (*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 = (bfd_boolean) (! flaginfo->info->keep_memory);
+ incl_entry = aout_link_includes_lookup (&flaginfo->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 (&flaginfo->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 = (int) 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 = H_GET_8 (input_bfd, incl_sym->e_type);
+ if (incl_type == (int) N_EINCL)
+ {
+ if (nest == 0)
+ {
+ *incl_map = -1;
+ break;
+ }
+ --nest;
+ }
+ else if (incl_type == (int) N_BINCL)
+ ++nest;
+ else if (nest == 0)
+ *incl_map = -1;
+ }
+ }
+ }
+ }
+
+ /* Copy this symbol into the list of symbols we are going to
+ write out. */
+ H_PUT_8 (output_bfd, type, outsym->e_type);
+ H_PUT_8 (output_bfd, H_GET_8 (input_bfd, sym->e_other), outsym->e_other);
+ H_PUT_16 (output_bfd, H_GET_16 (input_bfd, sym->e_desc), outsym->e_desc);
+ copy = FALSE;
+ if (! flaginfo->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 != NULL)
+ name = h->root.root.string;
+ else
+ copy = TRUE;
+ }
+ strtab_index = add_to_stringtab (output_bfd, flaginfo->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 > flaginfo->output_syms)
+ {
+ bfd_size_type outsym_size;
+
+ if (bfd_seek (output_bfd, flaginfo->symoff, SEEK_SET) != 0)
+ return FALSE;
+ outsym_size = outsym - flaginfo->output_syms;
+ outsym_size *= EXTERNAL_NLIST_SIZE;
+ if (bfd_bwrite ((void *) flaginfo->output_syms, outsym_size, output_bfd)
+ != outsym_size)
+ return FALSE;
+ flaginfo->symoff += outsym_size;
+ }
+
+ return TRUE;
+}
+
+/* Link an a.out input BFD into the output file. */
+
+static bfd_boolean
+aout_link_input_bfd (struct aout_final_link_info *flaginfo, bfd *input_bfd)
+{
+ 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)
+ (flaginfo->info, input_bfd));
+
+ /* Get the symbols. We probably have them already, unless
+ flaginfo->info->keep_memory is FALSE. */
+ if (! aout_get_external_symbols (input_bfd))
+ return FALSE;
+
+ /* Write out the symbols and get a map of the new indices. The map
+ is placed into flaginfo->symbol_map. */
+ if (! aout_link_write_symbols (flaginfo, 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 (flaginfo, input_bfd,
+ obj_textsec (input_bfd),
+ &flaginfo->treloff,
+ exec_hdr (input_bfd)->a_trsize))
+ return FALSE;
+ }
+ if (obj_datasec (input_bfd)->linker_mark)
+ {
+ if (! aout_link_input_section (flaginfo, input_bfd,
+ obj_datasec (input_bfd),
+ &flaginfo->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 (! flaginfo->info->keep_memory)
+ {
+ if (! aout_link_free_symbols (input_bfd))
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/* 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. */
+
+bfd_boolean
+NAME (aout, final_link) (bfd *abfd,
+ struct bfd_link_info *info,
+ void (*callback) (bfd *, file_ptr *, file_ptr *, file_ptr *))
+{
+ struct aout_final_link_info aout_info;
+ bfd_boolean includes_hash_initialized = FALSE;
+ bfd *sub;
+ bfd_size_type trsize, drsize;
+ bfd_size_type max_contents_size;
+ bfd_size_type max_relocs_size;
+ bfd_size_type max_sym_count;
+ bfd_size_type text_size;
+ file_ptr text_end;
+ struct bfd_link_order *p;
+ asection *o;
+ bfd_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,
+ sizeof (struct aout_link_includes_entry),
+ 251))
+ goto error_return;
+ includes_hash_initialized = TRUE;
+
+ /* Figure out the largest section size. Also, if generating
+ relocatable 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)
+ {
+ bfd_size_type sz;
+
+ if (info->relocatable)
+ {
+ 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: relocatable 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 = obj_textsec (sub)->size;
+ if (sz > max_contents_size)
+ max_contents_size = sz;
+ sz = obj_datasec (sub)->size;
+ 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->relocatable)
+ {
+ if (obj_textsec (abfd) != NULL)
+ trsize += (_bfd_count_link_order_relocs (obj_textsec (abfd)
+ ->map_head.link_order)
+ * obj_reloc_entry_size (abfd));
+ if (obj_datasec (abfd) != NULL)
+ drsize += (_bfd_count_link_order_relocs (obj_datasec (abfd)
+ ->map_head.link_order)
+ * 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 = 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->root.root, &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 != 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->map_head.link_order; 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 != NULL; o = o->next)
+ {
+ for (p = o->map_head.link_order;
+ p != 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. */
+ bfd_hash_traverse (&info->hash->table,
+ aout_link_write_other_symbol,
+ &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 != NULL; o = o->next)
+ {
+ for (p = o->map_head.link_order;
+ p != 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 (bfd_seek (abfd, obj_str_filepos (abfd), SEEK_SET) != 0)
+ goto error_return;
+ if (abfd->symcount > 0)
+ {
+ if (!emit_stringtab (abfd, aout_info.strtab))
+ goto error_return;
+ }
+ else
+ {
+ bfd_byte b[BYTES_IN_WORD];
+
+ memset (b, 0, BYTES_IN_WORD);
+ if (bfd_bwrite (b, (bfd_size_type) BYTES_IN_WORD, abfd) != BYTES_IN_WORD)
+ 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;
+}
diff --git a/bfd/archive.c b/bfd/archive.c
new file mode 100644
index 0000000..df37996
--- /dev/null
+++ b/bfd/archive.c
@@ -0,0 +1,2766 @@
+/* BFD back-end for archive files (libraries).
+ Copyright (C) 1990-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, 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.
+
+ A BFD returned by <<bfd_openr_next_archived_file>> can be
+ closed manually with <<bfd_close>>. If you do not close it,
+ then a second iteration through the members of an archive may
+ return the same BFD. If you close the archive BFD, then all
+ the member BFDs will automatically be closed as well.
+
+ Archive contents of output BFDs are chained through the
+ <<archive_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>>.
+
+SUBSECTION
+ Archive functions
+*/
+
+/* 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.
+*/
+
+/* 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 spaces) 23 characters long,
+ BSD 4.4 style, full name follows header.
+ " 18 " - Long name 18 characters long, extended pseudo-BSD.
+ */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libiberty.h"
+#include "libbfd.h"
+#include "aout/ar.h"
+#include "aout/ranlib.h"
+#include "safe-ctype.h"
+#include "hashtab.h"
+#include "filenames.h"
+#include "bfdlink.h"
+
+#ifndef errno
+extern int errno;
+#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 *arbfd;
+};
+
+#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)
+
+/* True iff NAME designated a BSD 4.4 extended name. */
+
+#define is_bsd44_extended_name(NAME) \
+ (NAME[0] == '#' && NAME[1] == '1' && NAME[2] == '/' && ISDIGIT (NAME[3]))
+
+void
+_bfd_ar_spacepad (char *p, size_t n, const char *fmt, long val)
+{
+ static char buf[20];
+ size_t len;
+
+ snprintf (buf, sizeof (buf), fmt, val);
+ len = strlen (buf);
+ if (len < n)
+ {
+ memcpy (p, buf, len);
+ memset (p + len, ' ', n - len);
+ }
+ else
+ memcpy (p, buf, n);
+}
+
+bfd_boolean
+_bfd_ar_sizepad (char *p, size_t n, bfd_size_type size)
+{
+ static char buf[21];
+ size_t len;
+
+ snprintf (buf, sizeof (buf), "%-10" BFD_VMA_FMT "u", size);
+ len = strlen (buf);
+ if (len > n)
+ {
+ bfd_set_error (bfd_error_file_too_big);
+ return FALSE;
+ }
+ if (len < n)
+ {
+ memcpy (p, buf, len);
+ memset (p + len, ' ', n - len);
+ }
+ else
+ memcpy (p, buf, n);
+ return TRUE;
+}
+
+bfd_boolean
+_bfd_generic_mkarchive (bfd *abfd)
+{
+ bfd_size_type amt = sizeof (struct artdata);
+
+ abfd->tdata.aout_ar_data = (struct artdata *) bfd_zalloc (abfd, amt);
+ if (bfd_ardata (abfd) == NULL)
+ return FALSE;
+
+ /* Already cleared by bfd_zalloc above.
+ 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)->extended_names_size = 0;
+ 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 (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 (bfd *obfd)
+{
+ return _bfd_new_bfd_contained_in (obfd);
+}
+
+/*
+FUNCTION
+ bfd_set_archive_head
+
+SYNOPSIS
+ bfd_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}.
+*/
+
+bfd_boolean
+bfd_set_archive_head (bfd *output_archive, bfd *new_head)
+{
+ output_archive->archive_head = new_head;
+ return TRUE;
+}
+
+bfd *
+_bfd_look_for_bfd_in_cache (bfd *arch_bfd, file_ptr filepos)
+{
+ htab_t hash_table = bfd_ardata (arch_bfd)->cache;
+ struct ar_cache m;
+
+ m.ptr = filepos;
+
+ if (hash_table)
+ {
+ struct ar_cache *entry = (struct ar_cache *) htab_find (hash_table, &m);
+ if (!entry)
+ return NULL;
+ else
+ return entry->arbfd;
+ }
+ else
+ return NULL;
+}
+
+static hashval_t
+hash_file_ptr (const void * p)
+{
+ return (hashval_t) (((struct ar_cache *) p)->ptr);
+}
+
+/* Returns non-zero if P1 and P2 are equal. */
+
+static int
+eq_file_ptr (const void * p1, const void * p2)
+{
+ struct ar_cache *arc1 = (struct ar_cache *) p1;
+ struct ar_cache *arc2 = (struct ar_cache *) p2;
+ return arc1->ptr == arc2->ptr;
+}
+
+/* The calloc function doesn't always take size_t (e.g. on VMS)
+ so wrap it to avoid a compile time warning. */
+
+static void *
+_bfd_calloc_wrapper (size_t a, size_t b)
+{
+ return calloc (a, b);
+}
+
+/* Kind of stupid to call cons for each one, but we don't do too many. */
+
+bfd_boolean
+_bfd_add_bfd_to_archive_cache (bfd *arch_bfd, file_ptr filepos, bfd *new_elt)
+{
+ struct ar_cache *cache;
+ htab_t hash_table = bfd_ardata (arch_bfd)->cache;
+
+ /* If the hash table hasn't been created, create it. */
+ if (hash_table == NULL)
+ {
+ hash_table = htab_create_alloc (16, hash_file_ptr, eq_file_ptr,
+ NULL, _bfd_calloc_wrapper, free);
+ if (hash_table == NULL)
+ return FALSE;
+ bfd_ardata (arch_bfd)->cache = hash_table;
+ }
+
+ /* Insert new_elt into the hash table by filepos. */
+ cache = (struct ar_cache *) bfd_zalloc (arch_bfd, sizeof (struct ar_cache));
+ cache->ptr = filepos;
+ cache->arbfd = new_elt;
+ *htab_find_slot (hash_table, (const void *) cache, INSERT) = cache;
+
+ /* Provide a means of accessing this from child. */
+ arch_eltdata (new_elt)->parent_cache = hash_table;
+ arch_eltdata (new_elt)->key = filepos;
+
+ return TRUE;
+}
+
+static bfd *
+_bfd_find_nested_archive (bfd *arch_bfd, const char *filename)
+{
+ bfd *abfd;
+ const char *target;
+
+ /* PR 15140: Don't allow a nested archive pointing to itself. */
+ if (filename_cmp (filename, arch_bfd->filename) == 0)
+ {
+ bfd_set_error (bfd_error_malformed_archive);
+ return NULL;
+ }
+
+ for (abfd = arch_bfd->nested_archives;
+ abfd != NULL;
+ abfd = abfd->archive_next)
+ {
+ if (filename_cmp (filename, abfd->filename) == 0)
+ return abfd;
+ }
+ target = NULL;
+ if (!arch_bfd->target_defaulted)
+ target = arch_bfd->xvec->name;
+ abfd = bfd_openr (filename, target);
+ if (abfd)
+ {
+ abfd->archive_next = arch_bfd->nested_archives;
+ arch_bfd->nested_archives = abfd;
+ }
+ return abfd;
+}
+
+/* The name begins with space. Hence the rest of the name is an index into
+ the string table. */
+
+static char *
+get_extended_arelt_filename (bfd *arch, const char *name, file_ptr *originp)
+{
+ unsigned long table_index = 0;
+ const char *endp;
+
+ /* 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. */
+ table_index = strtol (name + 1, (char **) &endp, 10);
+ if (errno != 0 || table_index >= bfd_ardata (arch)->extended_names_size)
+ {
+ bfd_set_error (bfd_error_malformed_archive);
+ return NULL;
+ }
+ /* In a thin archive, a member of an archive-within-an-archive
+ will have the offset in the inner archive encoded here. */
+ if (bfd_is_thin_archive (arch) && endp != NULL && *endp == ':')
+ {
+ file_ptr origin = strtol (endp + 1, NULL, 10);
+
+ if (errno != 0)
+ {
+ bfd_set_error (bfd_error_malformed_archive);
+ return NULL;
+ }
+ *originp = origin;
+ }
+ else
+ *originp = 0;
+
+ return bfd_ardata (arch)->extended_names + table_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. */
+
+void *
+_bfd_generic_read_ar_hdr (bfd *abfd)
+{
+ return _bfd_generic_read_ar_hdr_mag (abfd, 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. */
+
+void *
+_bfd_generic_read_ar_hdr_mag (bfd *abfd, const char *mag)
+{
+ struct ar_hdr hdr;
+ char *hdrp = (char *) &hdr;
+ bfd_size_type parsed_size;
+ struct areltdata *ared;
+ char *filename = NULL;
+ bfd_size_type namelen = 0;
+ bfd_size_type allocsize = sizeof (struct areltdata) + sizeof (struct ar_hdr);
+ char *allocptr = 0;
+ file_ptr origin = 0;
+ unsigned int extra_size = 0;
+ char fmag_save;
+ int scan;
+
+ if (bfd_bread (hdrp, 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;
+ fmag_save = hdr.ar_fmag[0];
+ hdr.ar_fmag[0] = 0;
+ scan = sscanf (hdr.ar_size, "%" BFD_VMA_FMT "u", &parsed_size);
+ hdr.ar_fmag[0] = fmag_save;
+ if (scan != 1)
+ {
+ 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, &origin);
+ if (filename == NULL)
+ return NULL;
+ }
+ /* BSD4.4-style long filename. */
+ else if (is_bsd44_extended_name (hdr.ar_name))
+ {
+ /* BSD-4.4 extended name */
+ namelen = atoi (&hdr.ar_name[3]);
+ allocsize += namelen + 1;
+ parsed_size -= namelen;
+ extra_size = namelen;
+
+ allocptr = (char *) bfd_zmalloc (allocsize);
+ if (allocptr == NULL)
+ return NULL;
+ filename = (allocptr
+ + sizeof (struct areltdata)
+ + sizeof (struct ar_hdr));
+ if (bfd_bread (filename, namelen, abfd) != namelen)
+ {
+ free (allocptr);
+ 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 = (char *) memchr (hdr.ar_name, '\0', ar_maxnamelen (abfd));
+ if (e == NULL)
+ {
+ e = (char *) memchr (hdr.ar_name, '/', ar_maxnamelen (abfd));
+ if (e == NULL)
+ e = (char *) 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 = (char *) bfd_zmalloc (allocsize);
+ if (allocptr == NULL)
+ return NULL;
+ }
+
+ ared = (struct areltdata *) allocptr;
+
+ ared->arch_header = allocptr + sizeof (struct areltdata);
+ memcpy (ared->arch_header, &hdr, sizeof (struct ar_hdr));
+ ared->parsed_size = parsed_size;
+ ared->extra_size = extra_size;
+ ared->origin = origin;
+
+ 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 ared;
+}
+
+/* Append the relative pathname for a member of the thin archive
+ to the pathname of the directory containing the archive. */
+
+char *
+_bfd_append_relative_path (bfd *arch, char *elt_name)
+{
+ const char *arch_name = arch->filename;
+ const char *base_name = lbasename (arch_name);
+ size_t prefix_len;
+ char *filename;
+
+ if (base_name == arch_name)
+ return elt_name;
+
+ prefix_len = base_name - arch_name;
+ filename = (char *) bfd_alloc (arch, prefix_len + strlen (elt_name) + 1);
+ if (filename == NULL)
+ return NULL;
+
+ strncpy (filename, arch_name, prefix_len);
+ strcpy (filename + prefix_len, elt_name);
+ return filename;
+}
+
+/* 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 (bfd *archive, file_ptr filepos)
+{
+ struct areltdata *new_areldata;
+ bfd *n_nfd;
+ char *filename;
+
+ 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;
+
+ filename = new_areldata->filename;
+
+ if (bfd_is_thin_archive (archive))
+ {
+ const char *target;
+
+ /* This is a proxy entry for an external file. */
+ if (! IS_ABSOLUTE_PATH (filename))
+ {
+ filename = _bfd_append_relative_path (archive, filename);
+ if (filename == NULL)
+ {
+ free (new_areldata);
+ return NULL;
+ }
+ }
+
+ if (new_areldata->origin > 0)
+ {
+ /* This proxy entry refers to an element of a nested archive.
+ Locate the member of that archive and return a bfd for it. */
+ bfd *ext_arch = _bfd_find_nested_archive (archive, filename);
+
+ if (ext_arch == NULL
+ || ! bfd_check_format (ext_arch, bfd_archive))
+ {
+ free (new_areldata);
+ return NULL;
+ }
+ n_nfd = _bfd_get_elt_at_filepos (ext_arch, new_areldata->origin);
+ if (n_nfd == NULL)
+ {
+ free (new_areldata);
+ return NULL;
+ }
+ n_nfd->proxy_origin = bfd_tell (archive);
+ return n_nfd;
+ }
+ /* It's not an element of a nested archive;
+ open the external file as a bfd. */
+ target = NULL;
+ if (!archive->target_defaulted)
+ target = archive->xvec->name;
+ n_nfd = bfd_openr (filename, target);
+ if (n_nfd == NULL)
+ bfd_set_error (bfd_error_malformed_archive);
+ }
+ else
+ {
+ n_nfd = _bfd_create_empty_archive_element_shell (archive);
+ }
+
+ if (n_nfd == NULL)
+ {
+ free (new_areldata);
+ return NULL;
+ }
+
+ n_nfd->proxy_origin = bfd_tell (archive);
+
+ if (bfd_is_thin_archive (archive))
+ {
+ n_nfd->origin = 0;
+ }
+ else
+ {
+ n_nfd->origin = n_nfd->proxy_origin;
+ n_nfd->filename = xstrdup (filename);
+ }
+
+ n_nfd->arelt_data = new_areldata;
+
+ /* Copy BFD_COMPRESS and BFD_DECOMPRESS flags. */
+ n_nfd->flags |= archive->flags & (BFD_COMPRESS | BFD_DECOMPRESS);
+
+ if (_bfd_add_bfd_to_archive_cache (archive, filepos, n_nfd))
+ return n_nfd;
+
+ free (new_areldata);
+ n_nfd->arelt_data = NULL;
+ return NULL;
+}
+
+/* Return the BFD which is referenced by the symbol in ABFD indexed by
+ SYM_INDEX. SYM_INDEX should have been returned by bfd_get_next_mapent. */
+
+bfd *
+_bfd_generic_get_elt_at_index (bfd *abfd, symindex sym_index)
+{
+ carsym *entry;
+
+ entry = bfd_ardata (abfd)->symdefs + sym_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 (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 (bfd *archive, bfd *last_file)
+{
+ file_ptr filestart;
+
+ if (!last_file)
+ filestart = bfd_ardata (archive)->first_file_filepos;
+ else
+ {
+ bfd_size_type size = arelt_size (last_file);
+
+ filestart = last_file->proxy_origin;
+ if (! bfd_is_thin_archive (archive))
+ filestart += size;
+ /* 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 += filestart % 2;
+ }
+
+ return _bfd_get_elt_at_filepos (archive, filestart);
+}
+
+const bfd_target *
+bfd_generic_archive_p (bfd *abfd)
+{
+ struct artdata *tdata_hold;
+ char armag[SARMAG + 1];
+ bfd_size_type amt;
+
+ if (bfd_bread (armag, SARMAG, abfd) != SARMAG)
+ {
+ if (bfd_get_error () != bfd_error_system_call)
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+
+ bfd_is_thin_archive (abfd) = (strncmp (armag, ARMAGT, SARMAG) == 0);
+
+ if (strncmp (armag, ARMAG, SARMAG) != 0
+ && strncmp (armag, ARMAGB, SARMAG) != 0
+ && ! bfd_is_thin_archive (abfd))
+ return NULL;
+
+ tdata_hold = bfd_ardata (abfd);
+
+ amt = sizeof (struct artdata);
+ bfd_ardata (abfd) = (struct artdata *) bfd_zalloc (abfd, amt);
+ if (bfd_ardata (abfd) == NULL)
+ {
+ bfd_ardata (abfd) = tdata_hold;
+ return NULL;
+ }
+
+ bfd_ardata (abfd)->first_file_filepos = SARMAG;
+ /* Cleared by bfd_zalloc above.
+ 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)->extended_names_size = 0;
+ bfd_ardata (abfd)->tdata = NULL; */
+
+ if (!BFD_SEND (abfd, _bfd_slurp_armap, (abfd))
+ || !BFD_SEND (abfd, _bfd_slurp_extended_name_table, (abfd)))
+ {
+ if (bfd_get_error () != bfd_error_system_call)
+ bfd_set_error (bfd_error_wrong_format);
+ bfd_release (abfd, bfd_ardata (abfd));
+ bfd_ardata (abfd) = tdata_hold;
+ return NULL;
+ }
+
+ if (abfd->target_defaulted && 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, NULL);
+ if (first != NULL)
+ {
+ first->target_defaulted = FALSE;
+ if (bfd_check_format (first, bfd_object)
+ && first->xvec != abfd->xvec)
+ bfd_set_error (bfd_error_wrong_object_format);
+ /* And we ought to close `first' here too. */
+ }
+ }
+
+ 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 H_GET_32 to 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
+
+/* Read a BSD-style archive symbol table. Returns FALSE on error,
+ TRUE otherwise. */
+
+static bfd_boolean
+do_slurp_bsd_armap (bfd *abfd)
+{
+ struct areltdata *mapdata;
+ unsigned int counter;
+ bfd_byte *raw_armap, *rbase;
+ struct artdata *ardata = bfd_ardata (abfd);
+ char *stringbase;
+ bfd_size_type parsed_size, amt;
+ carsym *set;
+
+ mapdata = (struct areltdata *) _bfd_read_ar_hdr (abfd);
+ if (mapdata == NULL)
+ return FALSE;
+ parsed_size = mapdata->parsed_size;
+ free (mapdata);
+
+ raw_armap = (bfd_byte *) bfd_zalloc (abfd, parsed_size);
+ if (raw_armap == NULL)
+ return FALSE;
+
+ if (bfd_bread (raw_armap, parsed_size, abfd) != parsed_size)
+ {
+ if (bfd_get_error () != bfd_error_system_call)
+ bfd_set_error (bfd_error_malformed_archive);
+ byebye:
+ bfd_release (abfd, raw_armap);
+ return FALSE;
+ }
+
+ ardata->symdef_count = 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);
+ amt = ardata->symdef_count * sizeof (carsym);
+ ardata->symdefs = (struct carsym *) bfd_alloc (abfd, amt);
+ if (!ardata->symdefs)
+ return FALSE;
+
+ for (counter = 0, set = ardata->symdefs;
+ counter < ardata->symdef_count;
+ counter++, set++, rbase += BSD_SYMDEF_SIZE)
+ {
+ set->name = H_GET_32 (abfd, rbase) + stringbase;
+ set->file_offset = 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;
+}
+
+/* Read a COFF archive symbol table. Returns FALSE on error, TRUE
+ otherwise. */
+
+static bfd_boolean
+do_slurp_coff_armap (bfd *abfd)
+{
+ struct areltdata *mapdata;
+ int *raw_armap, *rawptr;
+ struct artdata *ardata = bfd_ardata (abfd);
+ char *stringbase;
+ bfd_size_type stringsize;
+ bfd_size_type parsed_size;
+ carsym *carsyms;
+ bfd_size_type nsymz; /* Number of symbols in armap. */
+ bfd_vma (*swap) (const void *);
+ char int_buf[sizeof (long)];
+ bfd_size_type carsym_size, ptrsize;
+ unsigned int i;
+
+ mapdata = (struct areltdata *) _bfd_read_ar_hdr (abfd);
+ if (mapdata == NULL)
+ return FALSE;
+ parsed_size = mapdata->parsed_size;
+ free (mapdata);
+
+ if (bfd_bread (int_buf, 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 (int_buf);
+ stringsize = parsed_size - (4 * nsymz) - 4;
+
+ /* ... 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 (int_buf);
+ stringsize = parsed_size - (4 * nsymz) - 4;
+ swap = bfd_getl32;
+ }
+
+ /* The coff armap must be read sequentially. So we construct a
+ bsd-style one in core all at once, for simplicity. */
+
+ if (nsymz > ~ (bfd_size_type) 0 / sizeof (carsym))
+ return FALSE;
+
+ carsym_size = (nsymz * sizeof (carsym));
+ ptrsize = (4 * nsymz);
+
+ if (carsym_size + stringsize + 1 <= carsym_size)
+ return FALSE;
+
+ ardata->symdefs = (struct 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_bread (raw_armap, ptrsize, abfd) != ptrsize
+ || (bfd_bread (stringbase, 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 ((bfd_byte *) 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, 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) & ~(unsigned) 1;
+ }
+ free (tmp);
+ }
+ }
+
+ return TRUE;
+
+release_raw_armap:
+ bfd_release (abfd, raw_armap);
+release_symdefs:
+ bfd_release (abfd, (ardata)->symdefs);
+ return FALSE;
+}
+
+/* This routine can handle either coff-style or bsd-style armaps
+ (archive symbol table). Returns FALSE on error, TRUE otherwise */
+
+bfd_boolean
+bfd_slurp_armap (bfd *abfd)
+{
+ char nextname[17];
+ int i = bfd_bread (nextname, 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 (CONST_STRNEQ (nextname, "__.SYMDEF ")
+ || CONST_STRNEQ (nextname, "__.SYMDEF/ ")) /* Old Linux archives. */
+ return do_slurp_bsd_armap (abfd);
+ else if (CONST_STRNEQ (nextname, "/ "))
+ return do_slurp_coff_armap (abfd);
+ else if (CONST_STRNEQ (nextname, "/SYM64/ "))
+ {
+ /* 64bit ELF (Irix 6) archive. */
+#ifdef BFD64
+ extern bfd_boolean bfd_elf64_archive_slurp_armap (bfd *);
+ return bfd_elf64_archive_slurp_armap (abfd);
+#else
+ bfd_set_error (bfd_error_wrong_format);
+ return FALSE;
+#endif
+ }
+ else if (CONST_STRNEQ (nextname, "#1/20 "))
+ {
+ /* Mach-O has a special name for armap when the map is sorted by name.
+ However because this name has a space it is slightly more difficult
+ to check it. */
+ struct ar_hdr hdr;
+ char extname[21];
+
+ if (bfd_bread (&hdr, sizeof (hdr), abfd) != sizeof (hdr))
+ return FALSE;
+ /* Read the extended name. We know its length. */
+ if (bfd_bread (extname, 20, abfd) != 20)
+ return FALSE;
+ if (bfd_seek (abfd, -(file_ptr) (sizeof (hdr) + 20), SEEK_CUR) != 0)
+ return FALSE;
+ if (CONST_STRNEQ (extname, "__.SYMDEF SORTED")
+ || CONST_STRNEQ (extname, "__.SYMDEF"))
+ return do_slurp_bsd_armap (abfd);
+ }
+
+ 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
+
+bfd_boolean
+bfd_slurp_bsd_armap_f2 (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;
+ unsigned int left;
+ bfd_size_type amt;
+ carsym *set;
+ int i = bfd_bread (nextname, 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, (file_ptr) -16, SEEK_CUR) != 0)
+ return FALSE;
+
+ if (CONST_STRNEQ (nextname, "__.SYMDEF ")
+ || CONST_STRNEQ (nextname, "__.SYMDEF/ ")) /* Old Linux archives. */
+ return do_slurp_bsd_armap (abfd);
+
+ if (! CONST_STRNEQ (nextname, "/ "))
+ {
+ bfd_has_map (abfd) = FALSE;
+ return TRUE;
+ }
+
+ mapdata = (struct areltdata *) _bfd_read_ar_hdr (abfd);
+ if (mapdata == NULL)
+ return FALSE;
+
+ if (mapdata->parsed_size < HPUX_SYMDEF_COUNT_SIZE + BSD_STRING_COUNT_SIZE)
+ {
+ free (mapdata);
+ wrong_format:
+ bfd_set_error (bfd_error_wrong_format);
+ byebye:
+ return FALSE;
+ }
+ left = mapdata->parsed_size - HPUX_SYMDEF_COUNT_SIZE - BSD_STRING_COUNT_SIZE;
+
+ amt = mapdata->parsed_size;
+ free (mapdata);
+
+ raw_armap = (bfd_byte *) bfd_zalloc (abfd, amt);
+ if (raw_armap == NULL)
+ goto byebye;
+
+ if (bfd_bread (raw_armap, amt, abfd) != amt)
+ {
+ if (bfd_get_error () != bfd_error_system_call)
+ bfd_set_error (bfd_error_malformed_archive);
+ goto byebye;
+ }
+
+ ardata->symdef_count = H_GET_16 (abfd, raw_armap);
+
+ ardata->cache = 0;
+
+ stringsize = H_GET_32 (abfd, raw_armap + HPUX_SYMDEF_COUNT_SIZE);
+ if (stringsize > left)
+ goto wrong_format;
+ left -= stringsize;
+
+ /* Skip sym count and string sz. */
+ stringbase = ((char *) raw_armap
+ + HPUX_SYMDEF_COUNT_SIZE
+ + BSD_STRING_COUNT_SIZE);
+ rbase = (bfd_byte *) stringbase + stringsize;
+ amt = ardata->symdef_count * BSD_SYMDEF_SIZE;
+ if (amt > left)
+ goto wrong_format;
+
+ ardata->symdefs = (struct carsym *) bfd_alloc (abfd, amt);
+ if (!ardata->symdefs)
+ return FALSE;
+
+ for (counter = 0, set = ardata->symdefs;
+ counter < ardata->symdef_count;
+ counter++, set++, rbase += BSD_SYMDEF_SIZE)
+ {
+ set->name = H_GET_32 (abfd, rbase) + stringbase;
+ set->file_offset = 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. */
+
+bfd_boolean
+_bfd_slurp_extended_name_table (bfd *abfd)
+{
+ char nextname[17];
+ struct areltdata *namedata;
+ bfd_size_type amt;
+
+ /* FIXME: Formatting sucks here, and in case of failure of BFD_READ,
+ we probably don't want to return TRUE. */
+ if (bfd_seek (abfd, bfd_ardata (abfd)->first_file_filepos, SEEK_SET) != 0)
+ return FALSE;
+
+ if (bfd_bread (nextname, 16, abfd) == 16)
+ {
+ if (bfd_seek (abfd, (file_ptr) -16, SEEK_CUR) != 0)
+ return FALSE;
+
+ if (! CONST_STRNEQ (nextname, "ARFILENAMES/ ")
+ && ! CONST_STRNEQ (nextname, "// "))
+ {
+ bfd_ardata (abfd)->extended_names = NULL;
+ bfd_ardata (abfd)->extended_names_size = 0;
+ return TRUE;
+ }
+
+ namedata = (struct areltdata *) _bfd_read_ar_hdr (abfd);
+ if (namedata == NULL)
+ return FALSE;
+
+ amt = namedata->parsed_size;
+ if (amt + 1 == 0)
+ goto byebye;
+
+ bfd_ardata (abfd)->extended_names_size = amt;
+ bfd_ardata (abfd)->extended_names = (char *) bfd_zalloc (abfd, amt + 1);
+ if (bfd_ardata (abfd)->extended_names == NULL)
+ {
+ byebye:
+ free (namedata);
+ bfd_ardata (abfd)->extended_names = NULL;
+ bfd_ardata (abfd)->extended_names_size = 0;
+ return FALSE;
+ }
+
+ if (bfd_bread (bfd_ardata (abfd)->extended_names, amt, abfd) != amt)
+ {
+ if (bfd_get_error () != bfd_error_system_call)
+ bfd_set_error (bfd_error_malformed_archive);
+ bfd_release (abfd, (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 *ext_names = bfd_ardata (abfd)->extended_names;
+ char *temp = ext_names;
+ char *limit = temp + namedata->parsed_size;
+
+ for (; temp < limit; ++temp)
+ {
+ if (*temp == ARFMAG[1])
+ temp[temp > ext_names && temp[-1] == '/' ? -1 : 0] = '\0';
+ if (*temp == '\\')
+ *temp = '/';
+ }
+ *limit = '\0';
+ }
+
+ /* 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;
+
+ free (namedata);
+ }
+ return TRUE;
+}
+
+#ifdef VMS
+
+/* Return a copy of the stuff in the filename between any :]> and a
+ semicolon. */
+
+static const char *
+normalize (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 = 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 (bfd *abfd ATTRIBUTE_UNUSED, const char *file)
+{
+ return lbasename (file);
+}
+#endif
+
+/* Adjust a relative path name based on the reference path.
+ For example:
+
+ Relative path Reference path Result
+ ------------- -------------- ------
+ bar.o lib.a bar.o
+ foo/bar.o lib.a foo/bar.o
+ bar.o foo/lib.a ../bar.o
+ foo/bar.o baz/lib.a ../foo/bar.o
+ bar.o ../lib.a <parent of current dir>/bar.o
+ ; ../bar.o ../lib.a bar.o
+ ; ../bar.o lib.a ../bar.o
+ foo/bar.o ../lib.a <parent of current dir>/foo/bar.o
+ bar.o ../../lib.a <grandparent>/<parent>/bar.o
+ bar.o foo/baz/lib.a ../../bar.o
+
+ Note - the semicolons above are there to prevent the BFD chew
+ utility from interpreting those lines as prototypes to put into
+ the autogenerated bfd.h header...
+
+ Note - the string is returned in a static buffer. */
+
+static const char *
+adjust_relative_path (const char * path, const char * ref_path)
+{
+ static char *pathbuf = NULL;
+ static unsigned int pathbuf_len = 0;
+ const char *pathp;
+ const char *refp;
+ char * lpath;
+ char * rpath;
+ unsigned int len;
+ unsigned int dir_up = 0;
+ unsigned int dir_down = 0;
+ char *newp;
+ char * pwd = getpwd ();
+ const char * down;
+
+ /* Remove symlinks, '.' and '..' from the paths, if possible. */
+ lpath = lrealpath (path);
+ pathp = lpath == NULL ? path : lpath;
+
+ rpath = lrealpath (ref_path);
+ refp = rpath == NULL ? ref_path : rpath;
+
+ /* Remove common leading path elements. */
+ for (;;)
+ {
+ const char *e1 = pathp;
+ const char *e2 = refp;
+
+ while (*e1 && ! IS_DIR_SEPARATOR (*e1))
+ ++e1;
+ while (*e2 && ! IS_DIR_SEPARATOR (*e2))
+ ++e2;
+ if (*e1 == '\0' || *e2 == '\0' || e1 - pathp != e2 - refp
+ || filename_ncmp (pathp, refp, e1 - pathp) != 0)
+ break;
+ pathp = e1 + 1;
+ refp = e2 + 1;
+ }
+
+ len = strlen (pathp) + 1;
+ /* For each leading path element in the reference path,
+ insert "../" into the path. */
+ for (; *refp; ++refp)
+ if (IS_DIR_SEPARATOR (*refp))
+ {
+ /* PR 12710: If the path element is "../" then instead of
+ inserting "../" we need to insert the name of the directory
+ at the current level. */
+ if (refp > ref_path + 1
+ && refp[-1] == '.'
+ && refp[-2] == '.')
+ dir_down ++;
+ else
+ dir_up ++;
+ }
+
+ /* If the lrealpath calls above succeeded then we should never
+ see dir_up and dir_down both being non-zero. */
+
+ len += 3 * dir_up;
+
+ if (dir_down)
+ {
+ down = pwd + strlen (pwd) - 1;
+
+ while (dir_down && down > pwd)
+ {
+ if (IS_DIR_SEPARATOR (*down))
+ --dir_down;
+ }
+ BFD_ASSERT (dir_down == 0);
+ len += strlen (down) + 1;
+ }
+ else
+ down = NULL;
+
+ if (len > pathbuf_len)
+ {
+ if (pathbuf != NULL)
+ free (pathbuf);
+ pathbuf_len = 0;
+ pathbuf = (char *) bfd_malloc (len);
+ if (pathbuf == NULL)
+ goto out;
+ pathbuf_len = len;
+ }
+
+ newp = pathbuf;
+ while (dir_up-- > 0)
+ {
+ /* FIXME: Support Windows style path separators as well. */
+ strcpy (newp, "../");
+ newp += 3;
+ }
+
+ if (down)
+ sprintf (newp, "%s/%s", down, pathp);
+ else
+ strcpy (newp, pathp);
+
+ out:
+ free (lpath);
+ free (rpath);
+ return pathbuf;
+}
+
+/* Build a BFD style extended name table. */
+
+bfd_boolean
+_bfd_archive_bsd_construct_extended_name_table (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. */
+
+bfd_boolean
+_bfd_archive_coff_construct_extended_name_table (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! */
+
+bfd_boolean
+_bfd_construct_extended_name_table (bfd *abfd,
+ bfd_boolean trailing_slash,
+ char **tabloc,
+ bfd_size_type *tablen)
+{
+ unsigned int maxname = ar_maxnamelen (abfd);
+ bfd_size_type total_namelen = 0;
+ bfd *current;
+ char *strptr;
+ const char *last_filename;
+ long last_stroff;
+
+ *tablen = 0;
+ last_filename = NULL;
+
+ /* Figure out how long the table should be. */
+ for (current = abfd->archive_head;
+ current != NULL;
+ current = current->archive_next)
+ {
+ const char *normal;
+ unsigned int thislen;
+
+ if (bfd_is_thin_archive (abfd))
+ {
+ const char *filename = current->filename;
+
+ /* If the element being added is a member of another archive
+ (i.e., we are flattening), use the containing archive's name. */
+ if (current->my_archive
+ && ! bfd_is_thin_archive (current->my_archive))
+ filename = current->my_archive->filename;
+
+ /* If the path is the same as the previous path seen,
+ reuse it. This can happen when flattening a thin
+ archive that contains other archives. */
+ if (last_filename && filename_cmp (last_filename, filename) == 0)
+ continue;
+
+ last_filename = filename;
+
+ /* If the path is relative, adjust it relative to
+ the containing archive. */
+ if (! IS_ABSOLUTE_PATH (filename)
+ && ! IS_ABSOLUTE_PATH (abfd->filename))
+ normal = adjust_relative_path (filename, abfd->filename);
+ else
+ normal = filename;
+
+ /* In a thin archive, always store the full pathname
+ in the extended name table. */
+ total_namelen += strlen (normal) + 1;
+ if (trailing_slash)
+ /* Leave room for trailing slash. */
+ ++total_namelen;
+
+ continue;
+ }
+
+ 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 (filename_ncmp (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 = (char *) bfd_zalloc (abfd, total_namelen);
+ if (*tabloc == NULL)
+ return FALSE;
+
+ *tablen = total_namelen;
+ strptr = *tabloc;
+
+ last_filename = NULL;
+ last_stroff = 0;
+
+ for (current = abfd->archive_head;
+ current != NULL;
+ current = current->archive_next)
+ {
+ const char *normal;
+ unsigned int thislen;
+ long stroff;
+ const char *filename = current->filename;
+
+ if (bfd_is_thin_archive (abfd))
+ {
+ /* If the element being added is a member of another archive
+ (i.e., we are flattening), use the containing archive's name. */
+ if (current->my_archive
+ && ! bfd_is_thin_archive (current->my_archive))
+ filename = current->my_archive->filename;
+ /* If the path is the same as the previous path seen,
+ reuse it. This can happen when flattening a thin
+ archive that contains other archives.
+ If the path is relative, adjust it relative to
+ the containing archive. */
+ if (last_filename && filename_cmp (last_filename, filename) == 0)
+ normal = last_filename;
+ else if (! IS_ABSOLUTE_PATH (filename)
+ && ! IS_ABSOLUTE_PATH (abfd->filename))
+ normal = adjust_relative_path (filename, abfd->filename);
+ else
+ normal = filename;
+ }
+ else
+ {
+ normal = normalize (current, filename);
+ if (normal == NULL)
+ return FALSE;
+ }
+
+ thislen = strlen (normal);
+ if (thislen > maxname || bfd_is_thin_archive (abfd))
+ {
+ /* 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);
+ if (normal == last_filename)
+ stroff = last_stroff;
+ else
+ {
+ strcpy (strptr, normal);
+ if (! trailing_slash)
+ strptr[thislen] = ARFMAG[1];
+ else
+ {
+ strptr[thislen] = '/';
+ strptr[thislen + 1] = ARFMAG[1];
+ }
+ stroff = strptr - *tabloc;
+ last_stroff = stroff;
+ }
+ hdr->ar_name[0] = ar_padchar (current);
+ if (bfd_is_thin_archive (abfd) && current->origin > 0)
+ {
+ int len = snprintf (hdr->ar_name + 1, maxname - 1, "%-ld:",
+ stroff);
+ _bfd_ar_spacepad (hdr->ar_name + 1 + len, maxname - 1 - len,
+ "%-ld",
+ current->origin - sizeof (struct ar_hdr));
+ }
+ else
+ _bfd_ar_spacepad (hdr->ar_name + 1, maxname - 1, "%-ld", stroff);
+ if (normal != last_filename)
+ {
+ strptr += thislen + 1;
+ if (trailing_slash)
+ ++strptr;
+ last_filename = filename;
+ }
+ }
+ }
+
+ return TRUE;
+}
+
+/* Do not construct an extended name table but transforms name field into
+ its extended form. */
+
+bfd_boolean
+_bfd_archive_bsd44_construct_extended_name_table (bfd *abfd,
+ char **tabloc,
+ bfd_size_type *tablen,
+ const char **name)
+{
+ unsigned int maxname = ar_maxnamelen (abfd);
+ bfd *current;
+
+ *tablen = 0;
+ *tabloc = NULL;
+ *name = NULL;
+
+ for (current = abfd->archive_head;
+ current != NULL;
+ current = current->archive_next)
+ {
+ const char *normal = normalize (current, current->filename);
+ int has_space = 0;
+ unsigned int len;
+
+ if (normal == NULL)
+ return FALSE;
+
+ for (len = 0; normal[len]; len++)
+ if (normal[len] == ' ')
+ has_space = 1;
+
+ if (len > maxname || has_space)
+ {
+ struct ar_hdr *hdr = arch_hdr (current);
+
+ len = (len + 3) & ~3;
+ arch_eltdata (current)->extra_size = len;
+ _bfd_ar_spacepad (hdr->ar_name, maxname, "#1/%lu", len);
+ }
+ }
+
+ return TRUE;
+}
+
+/* Write an archive header. */
+
+bfd_boolean
+_bfd_generic_write_ar_hdr (bfd *archive, bfd *abfd)
+{
+ struct ar_hdr *hdr = arch_hdr (abfd);
+
+ if (bfd_bwrite (hdr, sizeof (*hdr), archive) != sizeof (*hdr))
+ return FALSE;
+ return TRUE;
+}
+
+/* Write an archive header using BSD4.4 convention. */
+
+bfd_boolean
+_bfd_bsd44_write_ar_hdr (bfd *archive, bfd *abfd)
+{
+ struct ar_hdr *hdr = arch_hdr (abfd);
+
+ if (is_bsd44_extended_name (hdr->ar_name))
+ {
+ /* This is a BSD 4.4 extended name. */
+ const char *fullname = normalize (abfd, abfd->filename);
+ unsigned int len = strlen (fullname);
+ unsigned int padded_len = (len + 3) & ~3;
+
+ BFD_ASSERT (padded_len == arch_eltdata (abfd)->extra_size);
+
+ if (!_bfd_ar_sizepad (hdr->ar_size, sizeof (hdr->ar_size),
+ arch_eltdata (abfd)->parsed_size + padded_len))
+ return FALSE;
+
+ if (bfd_bwrite (hdr, sizeof (*hdr), archive) != sizeof (*hdr))
+ return FALSE;
+
+ if (bfd_bwrite (fullname, len, archive) != len)
+ return FALSE;
+
+ if (len & 3)
+ {
+ static const char pad[3] = { 0, 0, 0 };
+
+ len = 4 - (len & 3);
+ if (bfd_bwrite (pad, len, archive) != len)
+ return FALSE;
+ }
+ }
+ else
+ {
+ if (bfd_bwrite (hdr, sizeof (*hdr), archive) != sizeof (*hdr))
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/* A couple of functions for creating ar_hdrs. */
+
+#ifdef HPUX_LARGE_AR_IDS
+/* Function to encode large UID/GID values according to HP. */
+
+static void
+hpux_uid_gid_encode (char str[6], long int id)
+{
+ int cnt;
+
+ str[5] = '@' + (id & 3);
+ id >>= 2;
+
+ for (cnt = 4; cnt >= 0; --cnt, id >>= 6)
+ str[cnt] = ' ' + (id & 0x3f);
+}
+#endif /* HPUX_LARGE_AR_IDS */
+
+#ifndef HAVE_GETUID
+#define getuid() 0
+#endif
+
+#ifndef HAVE_GETGID
+#define getgid() 0
+#endif
+
+/* 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 (bfd *abfd, const char *filename, bfd *member)
+{
+ struct stat status;
+ struct areltdata *ared;
+ struct ar_hdr *hdr;
+ bfd_size_type amt;
+
+ 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;
+ }
+
+ /* If the caller requested that the BFD generate deterministic output,
+ fake values for modification time, UID, GID, and file mode. */
+ if ((abfd->flags & BFD_DETERMINISTIC_OUTPUT) != 0)
+ {
+ status.st_mtime = 0;
+ status.st_uid = 0;
+ status.st_gid = 0;
+ status.st_mode = 0644;
+ }
+
+ amt = sizeof (struct ar_hdr) + sizeof (struct areltdata);
+ ared = (struct areltdata *) bfd_zmalloc (amt);
+ if (ared == NULL)
+ return NULL;
+ hdr = (struct ar_hdr *) (((char *) ared) + sizeof (struct areltdata));
+
+ /* ar headers are space padded, not null padded! */
+ memset (hdr, ' ', sizeof (struct ar_hdr));
+
+ _bfd_ar_spacepad (hdr->ar_date, sizeof (hdr->ar_date), "%-12ld",
+ status.st_mtime);
+#ifdef HPUX_LARGE_AR_IDS
+ /* HP has a very "special" way to handle UID/GID's with numeric values
+ > 99999. */
+ if (status.st_uid > 99999)
+ hpux_uid_gid_encode (hdr->ar_uid, (long) status.st_uid);
+ else
+#endif
+ _bfd_ar_spacepad (hdr->ar_uid, sizeof (hdr->ar_uid), "%ld",
+ status.st_uid);
+#ifdef HPUX_LARGE_AR_IDS
+ /* HP has a very "special" way to handle UID/GID's with numeric values
+ > 99999. */
+ if (status.st_gid > 99999)
+ hpux_uid_gid_encode (hdr->ar_gid, (long) status.st_gid);
+ else
+#endif
+ _bfd_ar_spacepad (hdr->ar_gid, sizeof (hdr->ar_gid), "%ld",
+ status.st_gid);
+ _bfd_ar_spacepad (hdr->ar_mode, sizeof (hdr->ar_mode), "%-8lo",
+ status.st_mode);
+ if (!_bfd_ar_sizepad (hdr->ar_size, sizeof (hdr->ar_size), status.st_size))
+ {
+ free (ared);
+ return NULL;
+ }
+ memcpy (hdr->ar_fmag, ARFMAG, 2);
+ ared->parsed_size = status.st_size;
+ ared->arch_header = (char *) hdr;
+
+ return ared;
+}
+
+/* Analogous to stat call. */
+
+int
+bfd_generic_stat_arch_elt (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;
+
+ /* Some platforms support special notations for large IDs. */
+#ifdef HPUX_LARGE_AR_IDS
+# define foo2(arelt, stelt, size) \
+ if (hdr->arelt[5] == ' ') \
+ { \
+ foo (arelt, stelt, size); \
+ } \
+ else \
+ { \
+ int cnt; \
+ for (buf->stelt = cnt = 0; cnt < 5; ++cnt) \
+ { \
+ if (hdr->arelt[cnt] < ' ' || hdr->arelt[cnt] > ' ' + 0x3f) \
+ return -1; \
+ buf->stelt <<= 6; \
+ buf->stelt += hdr->arelt[cnt] - ' '; \
+ } \
+ if (hdr->arelt[5] < '@' || hdr->arelt[5] > '@' + 3) \
+ return -1; \
+ buf->stelt <<= 2; \
+ buf->stelt += hdr->arelt[5] - '@'; \
+ }
+#else
+# define foo2(arelt, stelt, size) foo (arelt, stelt, size)
+#endif
+
+ foo (ar_date, st_mtime, 10);
+ foo2 (ar_uid, st_uid, 10);
+ foo2 (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 (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 (bfd *abfd, const char *pathname, char *arhdr)
+{
+ struct ar_hdr *hdr = (struct ar_hdr *) arhdr;
+ size_t length;
+ const char *filename = lbasename (pathname);
+ size_t maxlen = ar_maxnamelen (abfd);
+
+ 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 (bfd *abfd, const char *pathname, char *arhdr)
+{
+ struct ar_hdr *hdr = (struct ar_hdr *) arhdr;
+ size_t length;
+ const char *filename = lbasename (pathname);
+ size_t maxlen = ar_maxnamelen (abfd);
+
+ 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. */
+
+bfd_boolean
+_bfd_write_archive_contents (bfd *arch)
+{
+ bfd *current;
+ char *etable = NULL;
+ bfd_size_type elength = 0;
+ const char *ename = NULL;
+ bfd_boolean makemap = bfd_has_map (arch);
+ /* If no .o's, don't bother to make a map. */
+ bfd_boolean hasobjects = FALSE;
+ bfd_size_type wrote;
+ int tries;
+ char *armag;
+
+ /* 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 != NULL;
+ current = current->archive_next)
+ {
+ /* This check is checking the bfds for the objects we're reading
+ from (which are usually either an object file or archive on
+ disk), not the archive entries we're writing to. We don't
+ actually create bfds for the archive members, we just copy
+ them byte-wise when we write out the archive. */
+ if (bfd_write_p (current))
+ {
+ bfd_set_error (bfd_error_invalid_operation);
+ goto input_err;
+ }
+ if (!current->arelt_data)
+ {
+ current->arelt_data =
+ bfd_ar_hdr_from_filesystem (arch, current->filename, current);
+ if (!current->arelt_data)
+ goto input_err;
+
+ /* 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)))
+ 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;
+ armag = ARMAG;
+ if (bfd_is_thin_archive (arch))
+ armag = ARMAGT;
+ wrote = bfd_bwrite (armag, SARMAG, arch);
+ if (wrote != SARMAG)
+ return FALSE;
+
+ if (makemap && hasobjects)
+ {
+ if (! _bfd_compute_and_write_armap (arch, (unsigned int) elength))
+ return FALSE;
+ }
+
+ if (elength != 0)
+ {
+ struct ar_hdr hdr;
+
+ memset (&hdr, ' ', sizeof (struct ar_hdr));
+ memcpy (hdr.ar_name, ename, strlen (ename));
+ /* Round size up to even number in archive header. */
+ if (!_bfd_ar_sizepad (hdr.ar_size, sizeof (hdr.ar_size),
+ (elength + 1) & ~(bfd_size_type) 1))
+ return FALSE;
+ memcpy (hdr.ar_fmag, ARFMAG, 2);
+ if ((bfd_bwrite (&hdr, sizeof (struct ar_hdr), arch)
+ != sizeof (struct ar_hdr))
+ || bfd_bwrite (etable, elength, arch) != elength)
+ return FALSE;
+ if ((elength % 2) == 1)
+ {
+ if (bfd_bwrite (&ARFMAG[1], 1, arch) != 1)
+ return FALSE;
+ }
+ }
+
+ for (current = arch->archive_head;
+ current != NULL;
+ current = current->archive_next)
+ {
+ char buffer[DEFAULT_BUFFERSIZE];
+ bfd_size_type remaining = arelt_size (current);
+
+ /* Write ar header. */
+ if (!_bfd_write_ar_hdr (arch, current))
+ return FALSE;
+ if (bfd_is_thin_archive (arch))
+ continue;
+ if (bfd_seek (current, (file_ptr) 0, SEEK_SET) != 0)
+ goto input_err;
+
+ while (remaining)
+ {
+ unsigned int amt = DEFAULT_BUFFERSIZE;
+
+ if (amt > remaining)
+ amt = remaining;
+ errno = 0;
+ if (bfd_bread (buffer, amt, current) != amt)
+ {
+ if (bfd_get_error () != bfd_error_system_call)
+ bfd_set_error (bfd_error_file_truncated);
+ goto input_err;
+ }
+ if (bfd_bwrite (buffer, amt, arch) != amt)
+ return FALSE;
+ remaining -= amt;
+ }
+
+ if ((arelt_size (current) % 2) == 1)
+ {
+ if (bfd_bwrite (&ARFMAG[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;
+
+ input_err:
+ bfd_set_error (bfd_error_on_input, current, bfd_get_error ());
+ return FALSE;
+}
+
+/* Note that the namidx for the first symbol is 0. */
+
+bfd_boolean
+_bfd_compute_and_write_armap (bfd *arch, unsigned int elength)
+{
+ char *first_name = NULL;
+ bfd *current;
+ file_ptr elt_no = 0;
+ struct orl *map = NULL;
+ unsigned int orl_max = 1024; /* Fine initial default. */
+ unsigned int orl_count = 0;
+ int stridx = 0;
+ asymbol **syms = NULL;
+ long syms_max = 0;
+ bfd_boolean ret;
+ bfd_size_type amt;
+
+ /* Dunno if this is the best place for this info... */
+ if (elength != 0)
+ elength += sizeof (struct ar_hdr);
+ elength += elength % 2;
+
+ amt = orl_max * sizeof (struct orl);
+ map = (struct orl *) bfd_malloc (amt);
+ if (map == NULL)
+ goto error_return;
+
+ /* We put the symbol names on the arch objalloc, and then discard
+ them when done. */
+ first_name = (char *) 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->archive_next;
+
+ /* Map over each element. */
+ for (current = arch->archive_head;
+ current != NULL;
+ current = current->archive_next, elt_no++)
+ {
+ if (bfd_check_format (current, bfd_object)
+ && (bfd_get_file_flags (current) & HAS_SYMS) != 0)
+ {
+ 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 (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
+ | BSF_WEAK
+ | BSF_INDIRECT
+ | BSF_GNU_UNIQUE)) != 0
+ || bfd_is_com_section (sec))
+ && ! bfd_is_und_section (sec))
+ {
+ bfd_size_type namelen;
+ struct orl *new_map;
+
+ /* This symbol will go into the archive header. */
+ if (orl_count == orl_max)
+ {
+ orl_max *= 2;
+ amt = orl_max * sizeof (struct orl);
+ new_map = (struct orl *) bfd_realloc (map, amt);
+ if (new_map == NULL)
+ goto error_return;
+
+ map = new_map;
+ }
+
+ if (strcmp (syms[src_count]->name, "__gnu_lto_slim") == 0)
+ (*_bfd_error_handler)
+ (_("%s: plugin needed to handle lto object"),
+ bfd_get_filename (current));
+ namelen = strlen (syms[src_count]->name);
+ amt = sizeof (char *);
+ map[orl_count].name = (char **) bfd_alloc (arch, amt);
+ if (map[orl_count].name == NULL)
+ goto error_return;
+ *(map[orl_count].name) = (char *) 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].u.abfd = 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;
+}
+
+bfd_boolean
+bsd_write_armap (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;
+ long uid, gid;
+
+ firstreal = mapsize + elength + sizeof (struct ar_hdr) + SARMAG;
+
+ /* If deterministic, we use 0 as the timestamp in the map.
+ Some linkers may require that the archive filesystem modification
+ time is less than (or near to) the archive map timestamp. Those
+ linkers should not be used with deterministic mode. (GNU ld and
+ Gold do not have this restriction.) */
+ bfd_ardata (arch)->armap_timestamp = 0;
+ uid = 0;
+ gid = 0;
+ if ((arch->flags & BFD_DETERMINISTIC_OUTPUT) == 0)
+ {
+ struct stat statbuf;
+
+ if (stat (arch->filename, &statbuf) == 0)
+ bfd_ardata (arch)->armap_timestamp = (statbuf.st_mtime
+ + ARMAP_TIME_OFFSET);
+ uid = getuid();
+ gid = getgid();
+ }
+
+ memset (&hdr, ' ', sizeof (struct ar_hdr));
+ memcpy (hdr.ar_name, RANLIBMAG, strlen (RANLIBMAG));
+ bfd_ardata (arch)->armap_datepos = (SARMAG
+ + offsetof (struct ar_hdr, ar_date[0]));
+ _bfd_ar_spacepad (hdr.ar_date, sizeof (hdr.ar_date), "%ld",
+ bfd_ardata (arch)->armap_timestamp);
+ _bfd_ar_spacepad (hdr.ar_uid, sizeof (hdr.ar_uid), "%ld", uid);
+ _bfd_ar_spacepad (hdr.ar_gid, sizeof (hdr.ar_gid), "%ld", gid);
+ if (!_bfd_ar_sizepad (hdr.ar_size, sizeof (hdr.ar_size), mapsize))
+ return FALSE;
+ memcpy (hdr.ar_fmag, ARFMAG, 2);
+ if (bfd_bwrite (&hdr, sizeof (struct ar_hdr), arch)
+ != sizeof (struct ar_hdr))
+ return FALSE;
+ H_PUT_32 (arch, ranlibsize, temp);
+ if (bfd_bwrite (temp, sizeof (temp), arch) != sizeof (temp))
+ return FALSE;
+
+ for (count = 0; count < orl_count; count++)
+ {
+ unsigned int offset;
+ bfd_byte buf[BSD_SYMDEF_SIZE];
+
+ if (map[count].u.abfd != last_elt)
+ {
+ do
+ {
+ struct areltdata *ared = arch_eltdata (current);
+
+ firstreal += (ared->parsed_size + ared->extra_size
+ + sizeof (struct ar_hdr));
+ firstreal += firstreal % 2;
+ current = current->archive_next;
+ }
+ while (current != map[count].u.abfd);
+ }
+
+ /* The archive file format only has 4 bytes to store the offset
+ of the member. Check to make sure that firstreal has not grown
+ too big. */
+ offset = (unsigned int) firstreal;
+ if (firstreal != (file_ptr) offset)
+ {
+ bfd_set_error (bfd_error_file_truncated);
+ return FALSE;
+ }
+
+ last_elt = current;
+ H_PUT_32 (arch, map[count].namidx, buf);
+ H_PUT_32 (arch, firstreal, buf + BSD_SYMDEF_OFFSET_SIZE);
+ if (bfd_bwrite (buf, BSD_SYMDEF_SIZE, arch)
+ != BSD_SYMDEF_SIZE)
+ return FALSE;
+ }
+
+ /* Now write the strings themselves. */
+ H_PUT_32 (arch, stringsize, temp);
+ if (bfd_bwrite (temp, sizeof (temp), arch) != sizeof (temp))
+ return FALSE;
+ for (count = 0; count < orl_count; count++)
+ {
+ size_t len = strlen (*map[count].name) + 1;
+
+ if (bfd_bwrite (*map[count].name, 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_bwrite ("", 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. */
+
+bfd_boolean
+_bfd_archive_bsd_update_armap_timestamp (bfd *arch)
+{
+ struct stat archstat;
+ struct ar_hdr hdr;
+
+ /* If creating deterministic archives, just leave the timestamp as-is. */
+ if ((arch->flags & BFD_DETERMINISTIC_OUTPUT) != 0)
+ return TRUE;
+
+ /* 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)
+ {
+ bfd_perror (_("Reading archive file mod timestamp"));
+
+ /* Can't read mod time for some reason. */
+ return TRUE;
+ }
+ if (((long) archstat.st_mtime) <= bfd_ardata (arch)->armap_timestamp)
+ /* OK by the linker's rules. */
+ return TRUE;
+
+ /* 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, ' ', sizeof (hdr.ar_date));
+ _bfd_ar_spacepad (hdr.ar_date, sizeof (hdr.ar_date), "%ld",
+ bfd_ardata (arch)->armap_timestamp);
+
+ /* 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_bwrite (hdr.ar_date, sizeof (hdr.ar_date), arch)
+ != sizeof (hdr.ar_date)))
+ {
+ bfd_perror (_("Writing updated armap timestamp"));
+
+ /* Some error while writing. */
+ return TRUE;
+ }
+
+ /* We updated the timestamp successfully. */
+ return FALSE;
+}
+
+/* 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 */
+
+bfd_boolean
+coff_write_armap (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 an 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;
+ 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 (&hdr, ' ', sizeof (struct ar_hdr));
+ hdr.ar_name[0] = '/';
+ if (!_bfd_ar_sizepad (hdr.ar_size, sizeof (hdr.ar_size), mapsize))
+ return FALSE;
+ _bfd_ar_spacepad (hdr.ar_date, sizeof (hdr.ar_date), "%ld",
+ ((arch->flags & BFD_DETERMINISTIC_OUTPUT) == 0
+ ? time (NULL) : 0));
+ /* This, at least, is what Intel coff sets the values to. */
+ _bfd_ar_spacepad (hdr.ar_uid, sizeof (hdr.ar_uid), "%ld", 0);
+ _bfd_ar_spacepad (hdr.ar_gid, sizeof (hdr.ar_gid), "%ld", 0);
+ _bfd_ar_spacepad (hdr.ar_mode, sizeof (hdr.ar_mode), "%-7lo", 0);
+ memcpy (hdr.ar_fmag, ARFMAG, 2);
+
+ /* Write the ar header for this item and the number of symbols. */
+ if (bfd_bwrite (&hdr, sizeof (struct ar_hdr), arch)
+ != sizeof (struct ar_hdr))
+ return FALSE;
+
+ if (!bfd_write_bigendian_4byte_int (arch, symbol_count))
+ 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 != 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 (count < symbol_count && map[count].u.abfd == current)
+ {
+ unsigned int offset = (unsigned int) archive_member_file_ptr;
+
+ /* Catch an attempt to grow an archive past its 4Gb limit. */
+ if (archive_member_file_ptr != (file_ptr) offset)
+ {
+ bfd_set_error (bfd_error_file_truncated);
+ return FALSE;
+ }
+ if (!bfd_write_bigendian_4byte_int (arch, offset))
+ return FALSE;
+ count++;
+ }
+ archive_member_file_ptr += sizeof (struct ar_hdr);
+ if (! bfd_is_thin_archive (arch))
+ {
+ /* Add size of this archive entry. */
+ archive_member_file_ptr += arelt_size (current);
+ /* Remember about the even alignment. */
+ archive_member_file_ptr += archive_member_file_ptr % 2;
+ }
+ current = current->archive_next;
+ }
+
+ /* Now write the strings themselves. */
+ for (count = 0; count < symbol_count; count++)
+ {
+ size_t len = strlen (*map[count].name) + 1;
+
+ if (bfd_bwrite (*map[count].name, 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_bwrite ("", 1, arch) != 1)
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static int
+archive_close_worker (void **slot, void *inf ATTRIBUTE_UNUSED)
+{
+ struct ar_cache *ent = (struct ar_cache *) *slot;
+
+ bfd_close_all_done (ent->arbfd);
+ return 1;
+}
+
+bfd_boolean
+_bfd_archive_close_and_cleanup (bfd *abfd)
+{
+ if (bfd_read_p (abfd) && abfd->format == bfd_archive)
+ {
+ bfd *nbfd;
+ bfd *next;
+ htab_t htab;
+
+ /* Close nested archives (if this bfd is a thin archive). */
+ for (nbfd = abfd->nested_archives; nbfd; nbfd = next)
+ {
+ next = nbfd->archive_next;
+ bfd_close (nbfd);
+ }
+
+ htab = bfd_ardata (abfd)->cache;
+ if (htab)
+ {
+ htab_traverse_noresize (htab, archive_close_worker, NULL);
+ htab_delete (htab);
+ bfd_ardata (abfd)->cache = NULL;
+ }
+ }
+ if (arch_eltdata (abfd) != NULL)
+ {
+ struct areltdata *ared = arch_eltdata (abfd);
+ htab_t htab = (htab_t) ared->parent_cache;
+
+ if (htab)
+ {
+ struct ar_cache ent;
+ void **slot;
+
+ ent.ptr = ared->key;
+ slot = htab_find_slot (htab, &ent, NO_INSERT);
+ if (slot != NULL)
+ {
+ BFD_ASSERT (((struct ar_cache *) *slot)->arbfd == abfd);
+ htab_clear_slot (htab, slot);
+ }
+ }
+ }
+ if (abfd->is_linker_output)
+ (*abfd->link.hash->hash_table_free) (abfd);
+
+ return TRUE;
+}
diff --git a/bfd/archive64.c b/bfd/archive64.c
new file mode 100644
index 0000000..6b87ec5
--- /dev/null
+++ b/bfd/archive64.c
@@ -0,0 +1,240 @@
+/* Support for 64-bit ELF archives.
+ Copyright (C) 1996-2014 Free Software Foundation, Inc.
+ Ian Lance Taylor, Cygnus Support
+ Linker support added by Mark Mitchell, CodeSourcery, LLC.
+ <mark@codesourcery.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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+/* This file supports the 64-bit (MIPS) ELF archives. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+#include "aout/ar.h"
+
+/* Irix 6 defines a 64bit archive map format, so that they can
+ have archives more than 4 GB in size. */
+
+bfd_boolean bfd_elf64_archive_slurp_armap (bfd *);
+bfd_boolean bfd_elf64_archive_write_armap
+ (bfd *, unsigned int, struct orl *, unsigned int, int);
+
+/* Read an Irix 6 armap. */
+
+bfd_boolean
+bfd_elf64_archive_slurp_armap (bfd *abfd)
+{
+ struct artdata *ardata = bfd_ardata (abfd);
+ char nextname[17];
+ 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;
+ bfd_size_type amt;
+
+ ardata->symdefs = NULL;
+
+ /* Get the name of the first element. */
+ i = bfd_bread (nextname, 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 (CONST_STRNEQ (nextname, "/ "))
+ return bfd_slurp_armap (abfd);
+
+ if (! CONST_STRNEQ (nextname, "/SYM64/ "))
+ {
+ 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;
+ free (mapdata);
+
+ if (bfd_bread (int_buf, 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;
+
+ amt = carsym_size + stringsize + 1;
+ ardata->symdefs = (struct carsym *) bfd_zalloc (abfd, amt);
+ 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 release_symdefs;
+
+ if (bfd_bread (raw_armap, ptrsize, abfd) != ptrsize
+ || bfd_bread (stringbase, stringsize, abfd) != stringsize)
+ {
+ if (bfd_get_error () != bfd_error_system_call)
+ bfd_set_error (bfd_error_malformed_archive);
+ goto release_raw_armap;
+ }
+
+ 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 = 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, raw_armap);
+
+ return TRUE;
+
+release_raw_armap:
+ bfd_release (abfd, raw_armap);
+release_symdefs:
+ 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. */
+
+bfd_boolean
+bfd_elf64_archive_write_armap (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;
+ 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 (&hdr, ' ', sizeof (struct ar_hdr));
+ memcpy (hdr.ar_name, "/SYM64/", strlen ("/SYM64/"));
+ if (!_bfd_ar_sizepad (hdr.ar_size, sizeof (hdr.ar_size), mapsize))
+ return FALSE;
+ _bfd_ar_spacepad (hdr.ar_date, sizeof (hdr.ar_date), "%ld",
+ time (NULL));
+ /* This, at least, is what Intel coff sets the values to.: */
+ _bfd_ar_spacepad (hdr.ar_uid, sizeof (hdr.ar_uid), "%ld", 0);
+ _bfd_ar_spacepad (hdr.ar_gid, sizeof (hdr.ar_gid), "%ld", 0);
+ _bfd_ar_spacepad (hdr.ar_mode, sizeof (hdr.ar_mode), "%-7lo", 0);
+ memcpy (hdr.ar_fmag, ARFMAG, 2);
+
+ /* Write the ar header for this item and the number of symbols */
+
+ if (bfd_bwrite (&hdr, sizeof (struct ar_hdr), arch)
+ != sizeof (struct ar_hdr))
+ return FALSE;
+
+ bfd_putb64 ((bfd_vma) symbol_count, buf);
+ if (bfd_bwrite (buf, 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. */
+ count = 0;
+ for (current = arch->archive_head;
+ current != NULL && count < symbol_count;
+ current = current->archive_next)
+ {
+ /* For each symbol which is used defined in this object, write out
+ the object file's address in the archive. */
+
+ for (;
+ count < symbol_count && map[count].u.abfd == current;
+ count++)
+ {
+ bfd_putb64 ((bfd_vma) archive_member_file_ptr, buf);
+ if (bfd_bwrite (buf, 8, arch) != 8)
+ return FALSE;
+ }
+
+ /* Add size of this archive entry */
+ archive_member_file_ptr += sizeof (struct ar_hdr);
+ if (! bfd_is_thin_archive (arch))
+ archive_member_file_ptr += arelt_size (current);
+ /* remember about the even alignment */
+ archive_member_file_ptr += archive_member_file_ptr % 2;
+ }
+
+ /* now write the strings themselves */
+ for (count = 0; count < symbol_count; count++)
+ {
+ size_t len = strlen (*map[count].name) + 1;
+
+ if (bfd_bwrite (*map[count].name, 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_bwrite ("", 1, arch) != 1)
+ return FALSE;
+ --padding;
+ }
+
+ return TRUE;
+}
diff --git a/bfd/archures.c b/bfd/archures.c
new file mode 100644
index 0000000..c9fd6c8
--- /dev/null
+++ b/bfd/archures.c
@@ -0,0 +1,1401 @@
+/* BFD library support routines for architectures.
+ Copyright (C) 1990-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+#include "safe-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
+.#define bfd_mach_fido 9
+.#define bfd_mach_mcf_isa_a_nodiv 10
+.#define bfd_mach_mcf_isa_a 11
+.#define bfd_mach_mcf_isa_a_mac 12
+.#define bfd_mach_mcf_isa_a_emac 13
+.#define bfd_mach_mcf_isa_aplus 14
+.#define bfd_mach_mcf_isa_aplus_mac 15
+.#define bfd_mach_mcf_isa_aplus_emac 16
+.#define bfd_mach_mcf_isa_b_nousp 17
+.#define bfd_mach_mcf_isa_b_nousp_mac 18
+.#define bfd_mach_mcf_isa_b_nousp_emac 19
+.#define bfd_mach_mcf_isa_b 20
+.#define bfd_mach_mcf_isa_b_mac 21
+.#define bfd_mach_mcf_isa_b_emac 22
+.#define bfd_mach_mcf_isa_b_float 23
+.#define bfd_mach_mcf_isa_b_float_mac 24
+.#define bfd_mach_mcf_isa_b_float_emac 25
+.#define bfd_mach_mcf_isa_c 26
+.#define bfd_mach_mcf_isa_c_mac 27
+.#define bfd_mach_mcf_isa_c_emac 28
+.#define bfd_mach_mcf_isa_c_nodiv 29
+.#define bfd_mach_mcf_isa_c_nodiv_mac 30
+.#define bfd_mach_mcf_isa_c_nodiv_emac 31
+. 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_or1k, {* OpenRISC 1000 *}
+.#define bfd_mach_or1k 1
+.#define bfd_mach_or1knd 2
+.
+. 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. *}
+.#define bfd_mach_sparc_v8plusb 9 {* with cheetah add'ns. *}
+.#define bfd_mach_sparc_v9b 10 {* with cheetah 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_v9b \
+. && (mach) != bfd_mach_sparc_sparclite_le)
+.{* Nonzero if MACH is a 64 bit sparc architecture. *}
+.#define bfd_mach_sparc_64bit_p(mach) \
+. ((mach) >= bfd_mach_sparc_v9 && (mach) != bfd_mach_sparc_v8plusb)
+. bfd_arch_spu, {* PowerPC SPU *}
+.#define bfd_mach_spu 256
+. 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_mips4120 4120
+.#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_mips5400 5400
+.#define bfd_mach_mips5500 5500
+.#define bfd_mach_mips5900 5900
+.#define bfd_mach_mips6000 6000
+.#define bfd_mach_mips7000 7000
+.#define bfd_mach_mips8000 8000
+.#define bfd_mach_mips9000 9000
+.#define bfd_mach_mips10000 10000
+.#define bfd_mach_mips12000 12000
+.#define bfd_mach_mips14000 14000
+.#define bfd_mach_mips16000 16000
+.#define bfd_mach_mips16 16
+.#define bfd_mach_mips5 5
+.#define bfd_mach_mips_loongson_2e 3001
+.#define bfd_mach_mips_loongson_2f 3002
+.#define bfd_mach_mips_loongson_3a 3003
+.#define bfd_mach_mips_sb1 12310201 {* octal 'SB', 01 *}
+.#define bfd_mach_mips_octeon 6501
+.#define bfd_mach_mips_octeonp 6601
+.#define bfd_mach_mips_octeon2 6502
+.#define bfd_mach_mips_xlr 887682 {* decimal 'XLR' *}
+.#define bfd_mach_mipsisa32 32
+.#define bfd_mach_mipsisa32r2 33
+.#define bfd_mach_mipsisa32r3 34
+.#define bfd_mach_mipsisa32r5 36
+.#define bfd_mach_mipsisa32r6 37
+.#define bfd_mach_mipsisa64 64
+.#define bfd_mach_mipsisa64r2 65
+.#define bfd_mach_mipsisa64r3 66
+.#define bfd_mach_mipsisa64r5 68
+.#define bfd_mach_mipsisa64r6 69
+.#define bfd_mach_mips_micromips 96
+. bfd_arch_i386, {* Intel 386 *}
+.#define bfd_mach_i386_intel_syntax (1 << 0)
+.#define bfd_mach_i386_i8086 (1 << 1)
+.#define bfd_mach_i386_i386 (1 << 2)
+.#define bfd_mach_x86_64 (1 << 3)
+.#define bfd_mach_x64_32 (1 << 4)
+.#define bfd_mach_i386_i386_intel_syntax (bfd_mach_i386_i386 | bfd_mach_i386_intel_syntax)
+.#define bfd_mach_x86_64_intel_syntax (bfd_mach_x86_64 | bfd_mach_i386_intel_syntax)
+.#define bfd_mach_x64_32_intel_syntax (bfd_mach_x64_32 | bfd_mach_i386_intel_syntax)
+. bfd_arch_l1om, {* Intel L1OM *}
+.#define bfd_mach_l1om (1 << 5)
+.#define bfd_mach_l1om_intel_syntax (bfd_mach_l1om | bfd_mach_i386_intel_syntax)
+. bfd_arch_k1om, {* Intel K1OM *}
+.#define bfd_mach_k1om (1 << 6)
+.#define bfd_mach_k1om_intel_syntax (bfd_mach_k1om | bfd_mach_i386_intel_syntax)
+.#define bfd_mach_i386_nacl (1 << 7)
+.#define bfd_mach_i386_i386_nacl (bfd_mach_i386_i386 | bfd_mach_i386_nacl)
+.#define bfd_mach_x86_64_nacl (bfd_mach_x86_64 | bfd_mach_i386_nacl)
+.#define bfd_mach_x64_32_nacl (bfd_mach_x64_32 | bfd_mach_i386_nacl)
+. bfd_arch_we32k, {* AT&T WE32xxx *}
+. bfd_arch_tahoe, {* CCI/Harris Tahoe *}
+. bfd_arch_i860, {* Intel 860 *}
+. bfd_arch_i370, {* IBM 360/370 Mainframes *}
+. bfd_arch_romp, {* IBM ROMP PC/RT *}
+. bfd_arch_convex, {* Convex *}
+. bfd_arch_m88k, {* Motorola 88xxx *}
+. bfd_arch_m98k, {* Motorola 98xxx *}
+. bfd_arch_pyramid, {* Pyramid Technology *}
+. bfd_arch_h8300, {* Renesas H8/300 (formerly Hitachi H8/300) *}
+.#define bfd_mach_h8300 1
+.#define bfd_mach_h8300h 2
+.#define bfd_mach_h8300s 3
+.#define bfd_mach_h8300hn 4
+.#define bfd_mach_h8300sn 5
+.#define bfd_mach_h8300sx 6
+.#define bfd_mach_h8300sxn 7
+. bfd_arch_pdp11, {* DEC PDP-11 *}
+. bfd_arch_plugin,
+. bfd_arch_powerpc, {* PowerPC *}
+.#define bfd_mach_ppc 32
+.#define bfd_mach_ppc64 64
+.#define bfd_mach_ppc_403 403
+.#define bfd_mach_ppc_403gc 4030
+.#define bfd_mach_ppc_405 405
+.#define bfd_mach_ppc_505 505
+.#define bfd_mach_ppc_601 601
+.#define bfd_mach_ppc_602 602
+.#define bfd_mach_ppc_603 603
+.#define bfd_mach_ppc_ec603e 6031
+.#define bfd_mach_ppc_604 604
+.#define bfd_mach_ppc_620 620
+.#define bfd_mach_ppc_630 630
+.#define bfd_mach_ppc_750 750
+.#define bfd_mach_ppc_860 860
+.#define bfd_mach_ppc_a35 35
+.#define bfd_mach_ppc_rs64ii 642
+.#define bfd_mach_ppc_rs64iii 643
+.#define bfd_mach_ppc_7400 7400
+.#define bfd_mach_ppc_e500 500
+.#define bfd_mach_ppc_e500mc 5001
+.#define bfd_mach_ppc_e500mc64 5005
+.#define bfd_mach_ppc_e5500 5006
+.#define bfd_mach_ppc_e6500 5007
+.#define bfd_mach_ppc_titan 83
+.#define bfd_mach_ppc_vle 84
+. bfd_arch_rs6000, {* IBM RS/6000 *}
+.#define bfd_mach_rs6k 6000
+.#define bfd_mach_rs6k_rs1 6001
+.#define bfd_mach_rs6k_rsc 6003
+.#define bfd_mach_rs6k_rs2 6002
+. bfd_arch_hppa, {* HP PA RISC *}
+.#define bfd_mach_hppa10 10
+.#define bfd_mach_hppa11 11
+.#define bfd_mach_hppa20 20
+.#define bfd_mach_hppa20w 25
+. bfd_arch_d10v, {* Mitsubishi D10V *}
+.#define bfd_mach_d10v 1
+.#define bfd_mach_d10v_ts2 2
+.#define bfd_mach_d10v_ts3 3
+. bfd_arch_d30v, {* Mitsubishi D30V *}
+. bfd_arch_dlx, {* DLX *}
+. bfd_arch_m68hc11, {* Motorola 68HC11 *}
+. bfd_arch_m68hc12, {* Motorola 68HC12 *}
+.#define bfd_mach_m6812_default 0
+.#define bfd_mach_m6812 1
+.#define bfd_mach_m6812s 2
+. bfd_arch_m9s12x, {* Freescale S12X *}
+. bfd_arch_m9s12xg, {* Freescale XGATE *}
+. bfd_arch_z8k, {* Zilog Z8000 *}
+.#define bfd_mach_z8001 1
+.#define bfd_mach_z8002 2
+. bfd_arch_h8500, {* Renesas H8/500 (formerly Hitachi H8/500) *}
+. bfd_arch_sh, {* Renesas / SuperH SH (formerly Hitachi SH) *}
+.#define bfd_mach_sh 1
+.#define bfd_mach_sh2 0x20
+.#define bfd_mach_sh_dsp 0x2d
+.#define bfd_mach_sh2a 0x2a
+.#define bfd_mach_sh2a_nofpu 0x2b
+.#define bfd_mach_sh2a_nofpu_or_sh4_nommu_nofpu 0x2a1
+.#define bfd_mach_sh2a_nofpu_or_sh3_nommu 0x2a2
+.#define bfd_mach_sh2a_or_sh4 0x2a3
+.#define bfd_mach_sh2a_or_sh3e 0x2a4
+.#define bfd_mach_sh2e 0x2e
+.#define bfd_mach_sh3 0x30
+.#define bfd_mach_sh3_nommu 0x31
+.#define bfd_mach_sh3_dsp 0x3d
+.#define bfd_mach_sh3e 0x3e
+.#define bfd_mach_sh4 0x40
+.#define bfd_mach_sh4_nofpu 0x41
+.#define bfd_mach_sh4_nommu_nofpu 0x42
+.#define bfd_mach_sh4a 0x4a
+.#define bfd_mach_sh4a_nofpu 0x4b
+.#define bfd_mach_sh4al_dsp 0x4d
+.#define bfd_mach_sh5 0x50
+. 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_unknown 0
+.#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
+.#define bfd_mach_arm_5 7
+.#define bfd_mach_arm_5T 8
+.#define bfd_mach_arm_5TE 9
+.#define bfd_mach_arm_XScale 10
+.#define bfd_mach_arm_ep9312 11
+.#define bfd_mach_arm_iWMMXt 12
+.#define bfd_mach_arm_iWMMXt2 13
+. bfd_arch_nds32, {* Andes NDS32 *}
+.#define bfd_mach_n1 1
+.#define bfd_mach_n1h 2
+.#define bfd_mach_n1h_v2 3
+.#define bfd_mach_n1h_v3 4
+.#define bfd_mach_n1h_v3m 5
+. bfd_arch_ns32k, {* National Semiconductors ns32000 *}
+. bfd_arch_w65, {* WDC 65816 *}
+. bfd_arch_tic30, {* Texas Instruments TMS320C30 *}
+. bfd_arch_tic4x, {* Texas Instruments TMS320C3X/4X *}
+.#define bfd_mach_tic3x 30
+.#define bfd_mach_tic4x 40
+. bfd_arch_tic54x, {* Texas Instruments TMS320C54X *}
+. bfd_arch_tic6x, {* Texas Instruments TMS320C6X *}
+. bfd_arch_tic80, {* TI TMS320c80 (MVP) *}
+. bfd_arch_v850, {* NEC V850 *}
+. bfd_arch_v850_rh850,{* NEC V850 (using RH850 ABI) *}
+.#define bfd_mach_v850 1
+.#define bfd_mach_v850e 'E'
+.#define bfd_mach_v850e1 '1'
+.#define bfd_mach_v850e2 0x4532
+.#define bfd_mach_v850e2v3 0x45325633
+.#define bfd_mach_v850e3v5 0x45335635 {* ('E'|'3'|'V'|'5') *}
+. bfd_arch_arc, {* ARC Cores *}
+.#define bfd_mach_arc_5 5
+.#define bfd_mach_arc_6 6
+.#define bfd_mach_arc_7 7
+.#define bfd_mach_arc_8 8
+. bfd_arch_m32c, {* Renesas M16C/M32C. *}
+.#define bfd_mach_m16c 0x75
+.#define bfd_mach_m32c 0x78
+. bfd_arch_m32r, {* Renesas M32R (formerly Mitsubishi M32R/D) *}
+.#define bfd_mach_m32r 1 {* For backwards compatibility. *}
+.#define bfd_mach_m32rx 'x'
+.#define bfd_mach_m32r2 '2'
+. bfd_arch_mn10200, {* Matsushita MN10200 *}
+. bfd_arch_mn10300, {* Matsushita MN10300 *}
+.#define bfd_mach_mn10300 300
+.#define bfd_mach_am33 330
+.#define bfd_mach_am33_2 332
+. bfd_arch_fr30,
+.#define bfd_mach_fr30 0x46523330
+. bfd_arch_frv,
+.#define bfd_mach_frv 1
+.#define bfd_mach_frvsimple 2
+.#define bfd_mach_fr300 300
+.#define bfd_mach_fr400 400
+.#define bfd_mach_fr450 450
+.#define bfd_mach_frvtomcat 499 {* fr500 prototype *}
+.#define bfd_mach_fr500 500
+.#define bfd_mach_fr550 550
+. bfd_arch_moxie, {* The moxie processor *}
+.#define bfd_mach_moxie 1
+. bfd_arch_mcore,
+. bfd_arch_mep,
+.#define bfd_mach_mep 1
+.#define bfd_mach_mep_h1 0x6831
+.#define bfd_mach_mep_c5 0x6335
+. bfd_arch_metag,
+.#define bfd_mach_metag 1
+. bfd_arch_ia64, {* HP/Intel ia64 *}
+.#define bfd_mach_ia64_elf64 64
+.#define bfd_mach_ia64_elf32 32
+. bfd_arch_ip2k, {* Ubicom IP2K microcontrollers. *}
+.#define bfd_mach_ip2022 1
+.#define bfd_mach_ip2022ext 2
+. bfd_arch_iq2000, {* Vitesse IQ2000. *}
+.#define bfd_mach_iq2000 1
+.#define bfd_mach_iq10 2
+. bfd_arch_epiphany, {* Adapteva EPIPHANY *}
+.#define bfd_mach_epiphany16 1
+.#define bfd_mach_epiphany32 2
+. bfd_arch_mt,
+.#define bfd_mach_ms1 1
+.#define bfd_mach_mrisc2 2
+.#define bfd_mach_ms2 3
+. bfd_arch_pj,
+. bfd_arch_avr, {* Atmel AVR microcontrollers. *}
+.#define bfd_mach_avr1 1
+.#define bfd_mach_avr2 2
+.#define bfd_mach_avr25 25
+.#define bfd_mach_avr3 3
+.#define bfd_mach_avr31 31
+.#define bfd_mach_avr35 35
+.#define bfd_mach_avr4 4
+.#define bfd_mach_avr5 5
+.#define bfd_mach_avr51 51
+.#define bfd_mach_avr6 6
+.#define bfd_mach_avrtiny 100
+.#define bfd_mach_avrxmega1 101
+.#define bfd_mach_avrxmega2 102
+.#define bfd_mach_avrxmega3 103
+.#define bfd_mach_avrxmega4 104
+.#define bfd_mach_avrxmega5 105
+.#define bfd_mach_avrxmega6 106
+.#define bfd_mach_avrxmega7 107
+. bfd_arch_bfin, {* ADI Blackfin *}
+.#define bfd_mach_bfin 1
+. bfd_arch_cr16, {* National Semiconductor CompactRISC (ie CR16). *}
+.#define bfd_mach_cr16 1
+. bfd_arch_cr16c, {* National Semiconductor CompactRISC. *}
+.#define bfd_mach_cr16c 1
+. bfd_arch_crx, {* National Semiconductor CRX. *}
+.#define bfd_mach_crx 1
+. bfd_arch_cris, {* Axis CRIS *}
+.#define bfd_mach_cris_v0_v10 255
+.#define bfd_mach_cris_v32 32
+.#define bfd_mach_cris_v10_v32 1032
+. bfd_arch_rl78,
+.#define bfd_mach_rl78 0x75
+. bfd_arch_rx, {* Renesas RX. *}
+.#define bfd_mach_rx 0x75
+. bfd_arch_s390, {* IBM s390 *}
+.#define bfd_mach_s390_31 31
+.#define bfd_mach_s390_64 64
+. bfd_arch_score, {* Sunplus score *}
+.#define bfd_mach_score3 3
+.#define bfd_mach_score7 7
+. bfd_arch_mmix, {* Donald Knuth's educational processor. *}
+. bfd_arch_xstormy16,
+.#define bfd_mach_xstormy16 1
+. bfd_arch_msp430, {* Texas Instruments MSP430 architecture. *}
+.#define bfd_mach_msp11 11
+.#define bfd_mach_msp110 110
+.#define bfd_mach_msp12 12
+.#define bfd_mach_msp13 13
+.#define bfd_mach_msp14 14
+.#define bfd_mach_msp15 15
+.#define bfd_mach_msp16 16
+.#define bfd_mach_msp20 20
+.#define bfd_mach_msp21 21
+.#define bfd_mach_msp22 22
+.#define bfd_mach_msp23 23
+.#define bfd_mach_msp24 24
+.#define bfd_mach_msp26 26
+.#define bfd_mach_msp31 31
+.#define bfd_mach_msp32 32
+.#define bfd_mach_msp33 33
+.#define bfd_mach_msp41 41
+.#define bfd_mach_msp42 42
+.#define bfd_mach_msp43 43
+.#define bfd_mach_msp44 44
+.#define bfd_mach_msp430x 45
+.#define bfd_mach_msp46 46
+.#define bfd_mach_msp47 47
+.#define bfd_mach_msp54 54
+. bfd_arch_xc16x, {* Infineon's XC16X Series. *}
+.#define bfd_mach_xc16x 1
+.#define bfd_mach_xc16xl 2
+.#define bfd_mach_xc16xs 3
+. bfd_arch_xgate, {* Freescale XGATE *}
+.#define bfd_mach_xgate 1
+. bfd_arch_xtensa, {* Tensilica's Xtensa cores. *}
+.#define bfd_mach_xtensa 1
+. bfd_arch_z80,
+.#define bfd_mach_z80strict 1 {* No undocumented opcodes. *}
+.#define bfd_mach_z80 3 {* With ixl, ixh, iyl, and iyh. *}
+.#define bfd_mach_z80full 7 {* All undocumented instructions. *}
+.#define bfd_mach_r800 11 {* R800: successor with multiplication. *}
+. bfd_arch_lm32, {* Lattice Mico32 *}
+.#define bfd_mach_lm32 1
+. bfd_arch_microblaze,{* Xilinx MicroBlaze. *}
+. bfd_arch_tilepro, {* Tilera TILEPro *}
+. bfd_arch_tilegx, {* Tilera TILE-Gx *}
+.#define bfd_mach_tilepro 1
+.#define bfd_mach_tilegx 1
+.#define bfd_mach_tilegx32 2
+. bfd_arch_aarch64, {* AArch64 *}
+.#define bfd_mach_aarch64 0
+.#define bfd_mach_aarch64_ilp32 32
+. bfd_arch_nios2,
+.#define bfd_mach_nios2 0
+. 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.
+. The default arch should be the first entry for an arch so that
+. all the entries for that arch can be accessed via <<next>>. *}
+. bfd_boolean the_default;
+. const struct bfd_arch_info * (*compatible)
+. (const struct bfd_arch_info *a, const struct bfd_arch_info *b);
+.
+. bfd_boolean (*scan) (const struct bfd_arch_info *, const char *);
+.
+. {* Allocate via bfd_malloc and return a fill buffer of size COUNT. If
+. IS_BIGENDIAN is TRUE, the order of bytes is big endian. If CODE is
+. TRUE, the buffer contains code. *}
+. void *(*fill) (bfd_size_type count, bfd_boolean is_bigendian,
+. bfd_boolean code);
+.
+. const struct bfd_arch_info *next;
+.}
+.bfd_arch_info_type;
+.
+*/
+
+extern const bfd_arch_info_type bfd_aarch64_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_avr_arch;
+extern const bfd_arch_info_type bfd_bfin_arch;
+extern const bfd_arch_info_type bfd_cr16_arch;
+extern const bfd_arch_info_type bfd_cr16c_arch;
+extern const bfd_arch_info_type bfd_cris_arch;
+extern const bfd_arch_info_type bfd_crx_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_dlx_arch;
+extern const bfd_arch_info_type bfd_epiphany_arch;
+extern const bfd_arch_info_type bfd_fr30_arch;
+extern const bfd_arch_info_type bfd_frv_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_i370_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_ia64_arch;
+extern const bfd_arch_info_type bfd_ip2k_arch;
+extern const bfd_arch_info_type bfd_iq2000_arch;
+extern const bfd_arch_info_type bfd_k1om_arch;
+extern const bfd_arch_info_type bfd_l1om_arch;
+extern const bfd_arch_info_type bfd_lm32_arch;
+extern const bfd_arch_info_type bfd_m32c_arch;
+extern const bfd_arch_info_type bfd_m32r_arch;
+extern const bfd_arch_info_type bfd_m68hc11_arch;
+extern const bfd_arch_info_type bfd_m68hc12_arch;
+extern const bfd_arch_info_type bfd_m9s12x_arch;
+extern const bfd_arch_info_type bfd_m9s12xg_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_mcore_arch;
+extern const bfd_arch_info_type bfd_mep_arch;
+extern const bfd_arch_info_type bfd_metag_arch;
+extern const bfd_arch_info_type bfd_mips_arch;
+extern const bfd_arch_info_type bfd_microblaze_arch;
+extern const bfd_arch_info_type bfd_mmix_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_moxie_arch;
+extern const bfd_arch_info_type bfd_msp430_arch;
+extern const bfd_arch_info_type bfd_mt_arch;
+extern const bfd_arch_info_type bfd_nds32_arch;
+extern const bfd_arch_info_type bfd_nios2_arch;
+extern const bfd_arch_info_type bfd_ns32k_arch;
+extern const bfd_arch_info_type bfd_or1k_arch;
+extern const bfd_arch_info_type bfd_pdp11_arch;
+extern const bfd_arch_info_type bfd_pj_arch;
+extern const bfd_arch_info_type bfd_plugin_arch;
+extern const bfd_arch_info_type bfd_powerpc_archs[];
+#define bfd_powerpc_arch bfd_powerpc_archs[0]
+extern const bfd_arch_info_type bfd_rs6000_arch;
+extern const bfd_arch_info_type bfd_rl78_arch;
+extern const bfd_arch_info_type bfd_rx_arch;
+extern const bfd_arch_info_type bfd_s390_arch;
+extern const bfd_arch_info_type bfd_score_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_spu_arch;
+extern const bfd_arch_info_type bfd_tic30_arch;
+extern const bfd_arch_info_type bfd_tic4x_arch;
+extern const bfd_arch_info_type bfd_tic54x_arch;
+extern const bfd_arch_info_type bfd_tic6x_arch;
+extern const bfd_arch_info_type bfd_tic80_arch;
+extern const bfd_arch_info_type bfd_tilegx_arch;
+extern const bfd_arch_info_type bfd_tilepro_arch;
+extern const bfd_arch_info_type bfd_v850_arch;
+extern const bfd_arch_info_type bfd_v850_rh850_arch;
+extern const bfd_arch_info_type bfd_vax_arch;
+extern const bfd_arch_info_type bfd_w65_arch;
+extern const bfd_arch_info_type bfd_we32k_arch;
+extern const bfd_arch_info_type bfd_xstormy16_arch;
+extern const bfd_arch_info_type bfd_xtensa_arch;
+extern const bfd_arch_info_type bfd_xc16x_arch;
+extern const bfd_arch_info_type bfd_xgate_arch;
+extern const bfd_arch_info_type bfd_z80_arch;
+extern const bfd_arch_info_type bfd_z8k_arch;
+
+static const bfd_arch_info_type * const bfd_archures_list[] =
+ {
+#ifdef SELECT_ARCHITECTURES
+ SELECT_ARCHITECTURES,
+#else
+ &bfd_aarch64_arch,
+ &bfd_alpha_arch,
+ &bfd_arc_arch,
+ &bfd_arm_arch,
+ &bfd_avr_arch,
+ &bfd_bfin_arch,
+ &bfd_cr16_arch,
+ &bfd_cr16c_arch,
+ &bfd_cris_arch,
+ &bfd_crx_arch,
+ &bfd_d10v_arch,
+ &bfd_d30v_arch,
+ &bfd_dlx_arch,
+ &bfd_epiphany_arch,
+ &bfd_fr30_arch,
+ &bfd_frv_arch,
+ &bfd_h8300_arch,
+ &bfd_h8500_arch,
+ &bfd_hppa_arch,
+ &bfd_i370_arch,
+ &bfd_i386_arch,
+ &bfd_i860_arch,
+ &bfd_i960_arch,
+ &bfd_ia64_arch,
+ &bfd_ip2k_arch,
+ &bfd_iq2000_arch,
+ &bfd_k1om_arch,
+ &bfd_l1om_arch,
+ &bfd_lm32_arch,
+ &bfd_m32c_arch,
+ &bfd_m32r_arch,
+ &bfd_m68hc11_arch,
+ &bfd_m68hc12_arch,
+ &bfd_m9s12x_arch,
+ &bfd_m9s12xg_arch,
+ &bfd_m68k_arch,
+ &bfd_m88k_arch,
+ &bfd_mcore_arch,
+ &bfd_mep_arch,
+ &bfd_metag_arch,
+ &bfd_microblaze_arch,
+ &bfd_mips_arch,
+ &bfd_mmix_arch,
+ &bfd_mn10200_arch,
+ &bfd_mn10300_arch,
+ &bfd_moxie_arch,
+ &bfd_msp430_arch,
+ &bfd_mt_arch,
+ &bfd_nds32_arch,
+ &bfd_nios2_arch,
+ &bfd_ns32k_arch,
+ &bfd_or1k_arch,
+ &bfd_pdp11_arch,
+ &bfd_powerpc_arch,
+ &bfd_rs6000_arch,
+ &bfd_rl78_arch,
+ &bfd_rx_arch,
+ &bfd_s390_arch,
+ &bfd_score_arch,
+ &bfd_sh_arch,
+ &bfd_sparc_arch,
+ &bfd_spu_arch,
+ &bfd_tic30_arch,
+ &bfd_tic4x_arch,
+ &bfd_tic54x_arch,
+ &bfd_tic6x_arch,
+ &bfd_tic80_arch,
+ &bfd_tilegx_arch,
+ &bfd_tilepro_arch,
+ &bfd_v850_arch,
+ &bfd_v850_rh850_arch,
+ &bfd_vax_arch,
+ &bfd_w65_arch,
+ &bfd_we32k_arch,
+ &bfd_xstormy16_arch,
+ &bfd_xtensa_arch,
+ &bfd_xc16x_arch,
+ &bfd_xgate_arch,
+ &bfd_z80_arch,
+ &bfd_z8k_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 (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 (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 (void)
+{
+ int vec_length = 0;
+ const char **name_ptr;
+ const char **name_list;
+ const bfd_arch_info_type * const *app;
+ bfd_size_type amt;
+
+ /* 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++;
+ }
+ }
+
+ amt = (vec_length + 1) * sizeof (char **);
+ name_list = (const char **) bfd_malloc (amt);
+ 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, bfd_boolean accept_unknowns);
+
+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 (const bfd *abfd,
+ const bfd *bbfd,
+ bfd_boolean accept_unknowns)
+{
+ const bfd *ubfd, *kbfd;
+
+ /* Look for an unknown architecture. */
+ if (abfd->arch_info->arch == bfd_arch_unknown)
+ ubfd = abfd, kbfd = bbfd;
+ else if (bbfd->arch_info->arch == bfd_arch_unknown)
+ ubfd = bbfd, kbfd = abfd;
+ else
+ /* Otherwise architecture-specific code has to decide. */
+ return abfd->arch_info->compatible (abfd->arch_info, bbfd->arch_info);
+
+ /* We can allow an unknown architecture if accept_unknowns
+ is true, or if the target is the "binary" format, which
+ has an unknown architecture. Since the binary format can
+ only be set by explicit request from the user, it is safe
+ to assume that they know what they are doing. */
+ if (accept_unknowns
+ || strcmp (bfd_get_target (ubfd), "binary") == 0)
+ return kbfd->arch_info;
+ return NULL;
+}
+
+/*
+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,
+ bfd_arch_default_fill,
+ 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 (bfd *abfd, const bfd_arch_info_type *arg)
+{
+ abfd->arch_info = arg;
+}
+
+/*
+INTERNAL_FUNCTION
+ bfd_default_set_arch_mach
+
+SYNOPSIS
+ bfd_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.
+*/
+
+bfd_boolean
+bfd_default_set_arch_mach (bfd *abfd,
+ enum bfd_architecture arch,
+ unsigned long mach)
+{
+ abfd->arch_info = bfd_lookup_arch (arch, mach);
+ if (abfd->arch_info != NULL)
+ 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 (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 (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 (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 (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 (const bfd_arch_info_type *a,
+ const bfd_arch_info_type *b)
+{
+ if (a->arch != b->arch)
+ return NULL;
+
+ if (a->bits_per_word != b->bits_per_word)
+ return NULL;
+
+ if (a->mach > b->mach)
+ return a;
+
+ if (b->mach > a->mach)
+ return b;
+
+ return a;
+}
+
+/*
+INTERNAL_FUNCTION
+ bfd_default_scan
+
+SYNOPSIS
+ bfd_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.
+*/
+
+bfd_boolean
+bfd_default_scan (const bfd_arch_info_type *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)
+ {
+ size_t 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)
+ {
+ size_t 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 ambiguous. 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 (*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. */
+ /* The following seven case's are here only for compatibility with
+ older binutils (at least IEEE objects from binutils 2.9.1 require
+ them). */
+ case bfd_mach_m68000:
+ case bfd_mach_m68010:
+ case bfd_mach_m68020:
+ case bfd_mach_m68030:
+ case bfd_mach_m68040:
+ case bfd_mach_m68060:
+ case bfd_mach_cpu32:
+ arch = bfd_arch_m68k;
+ break;
+ 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 5200:
+ arch = bfd_arch_m68k;
+ number = bfd_mach_mcf_isa_a_nodiv;
+ break;
+ case 5206:
+ arch = bfd_arch_m68k;
+ number = bfd_mach_mcf_isa_a_mac;
+ break;
+ case 5307:
+ arch = bfd_arch_m68k;
+ number = bfd_mach_mcf_isa_a_mac;
+ break;
+ case 5407:
+ arch = bfd_arch_m68k;
+ number = bfd_mach_mcf_isa_b_nousp_mac;
+ break;
+ case 5282:
+ arch = bfd_arch_m68k;
+ number = bfd_mach_mcf_isa_aplus_emac;
+ 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;
+
+ case 7410:
+ arch = bfd_arch_sh;
+ number = bfd_mach_sh_dsp;
+ break;
+
+ case 7708:
+ arch = bfd_arch_sh;
+ number = bfd_mach_sh3;
+ break;
+
+ case 7729:
+ arch = bfd_arch_sh;
+ number = bfd_mach_sh3_dsp;
+ break;
+
+ case 7750:
+ arch = bfd_arch_sh;
+ number = bfd_mach_sh4;
+ 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 (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 architecture 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 (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 (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!";
+}
+
+/*
+FUNCTION
+ bfd_octets_per_byte
+
+SYNOPSIS
+ unsigned int bfd_octets_per_byte (bfd *abfd);
+
+DESCRIPTION
+ Return the number of octets (8-bit quantities) per target byte
+ (minimum addressable unit). In most cases, this will be one, but some
+ DSP targets have 16, 32, or even 48 bits per byte.
+*/
+
+unsigned int
+bfd_octets_per_byte (bfd *abfd)
+{
+ return bfd_arch_mach_octets_per_byte (bfd_get_arch (abfd),
+ bfd_get_mach (abfd));
+}
+
+/*
+FUNCTION
+ bfd_arch_mach_octets_per_byte
+
+SYNOPSIS
+ unsigned int bfd_arch_mach_octets_per_byte
+ (enum bfd_architecture arch, unsigned long machine);
+
+DESCRIPTION
+ See bfd_octets_per_byte.
+
+ This routine is provided for those cases where a bfd * is not
+ available
+*/
+
+unsigned int
+bfd_arch_mach_octets_per_byte (enum bfd_architecture arch,
+ unsigned long mach)
+{
+ const bfd_arch_info_type *ap = bfd_lookup_arch (arch, mach);
+
+ if (ap)
+ return ap->bits_per_byte / 8;
+ return 1;
+}
+
+/*
+INTERNAL_FUNCTION
+ bfd_arch_default_fill
+
+SYNOPSIS
+ void *bfd_arch_default_fill (bfd_size_type count,
+ bfd_boolean is_bigendian,
+ bfd_boolean code);
+
+DESCRIPTION
+ Allocate via bfd_malloc and return a fill buffer of size COUNT.
+ If IS_BIGENDIAN is TRUE, the order of bytes is big endian. If
+ CODE is TRUE, the buffer contains code.
+*/
+
+void *
+bfd_arch_default_fill (bfd_size_type count,
+ bfd_boolean is_bigendian ATTRIBUTE_UNUSED,
+ bfd_boolean code ATTRIBUTE_UNUSED)
+{
+ void *fill = bfd_malloc (count);
+ if (fill != NULL)
+ memset (fill, 0, count);
+ return fill;
+}
diff --git a/bfd/armnetbsd.c b/bfd/armnetbsd.c
new file mode 100644
index 0000000..05b7635
--- /dev/null
+++ b/bfd/armnetbsd.c
@@ -0,0 +1,39 @@
+/* BFD back-end for NetBSD/ARM a.out-ish binaries.
+ Copyright (C) 1999-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, 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_arm
+#define DEFAULT_MID M_ARM6_NETBSD
+/*#define MACHTYPE_OK(mtype) ((mtype) == M_ARM6_NETBSD)*/
+
+/* Do not "beautify" the CONCAT* macro args. Traditional C will not
+ remove whitespace added here, and thus will fail to concatenate
+ the tokens. */
+#define MY(OP) CONCAT2 (arm_aout_nbsd_, OP)
+
+/* This needs to start with a.out so GDB knows it is an a.out variant. */
+#define TARGETNAME "a.out-arm-netbsd"
+
+#include "netbsd.h"
diff --git a/bfd/bfd-in.h b/bfd/bfd-in.h
new file mode 100644
index 0000000..1f80a76
--- /dev/null
+++ b/bfd/bfd-in.h
@@ -0,0 +1,1013 @@
+/* Main header file for the bfd library -- portable access to object files.
+
+ Copyright (C) 1990-2014 Free Software Foundation, Inc.
+
+ Contributed 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#ifndef __BFD_H_SEEN__
+#define __BFD_H_SEEN__
+
+/* PR 14072: Ensure that config.h is included first. */
+#if !defined PACKAGE && !defined PACKAGE_VERSION
+#error config.h must be included before this header
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "ansidecl.h"
+#include "symcat.h"
+#include <sys/stat.h>
+
+#if defined (__STDC__) || defined (ALMOST_STDC) || defined (HAVE_STRINGIZE)
+#ifndef SABER
+/* This 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 XCONCAT2 macro will
+ cause the inner CONCAT2 macros to be evaluated first, producing
+ still-valid pp-tokens. Then the final concatenation can be done. */
+#undef CONCAT4
+#define CONCAT4(a,b,c,d) XCONCAT2(CONCAT2(a,b),CONCAT2(c,d))
+#endif
+#endif
+
+/* This is a utility macro to handle the situation where the code
+ wants to place a constant string into the code, followed by a
+ comma and then the length of the string. Doing this by hand
+ is error prone, so using this macro is safer. */
+#define STRING_COMMA_LEN(STR) (STR), (sizeof (STR) - 1)
+/* Unfortunately it is not possible to use the STRING_COMMA_LEN macro
+ to create the arguments to another macro, since the preprocessor
+ will mis-count the number of arguments to the outer macro (by not
+ evaluating STRING_COMMA_LEN and so missing the comma). This is a
+ problem for example when trying to use STRING_COMMA_LEN to build
+ the arguments to the strncmp() macro. Hence this alternative
+ definition of strncmp is provided here.
+
+ Note - these macros do NOT work if STR2 is not a constant string. */
+#define CONST_STRNEQ(STR1,STR2) (strncmp ((STR1), (STR2), sizeof (STR2) - 1) == 0)
+ /* strcpy() can have a similar problem, but since we know we are
+ copying a constant string, we can use memcpy which will be faster
+ since there is no need to check for a NUL byte inside STR. We
+ can also save time if we do not need to copy the terminating NUL. */
+#define LITMEMCPY(DEST,STR2) memcpy ((DEST), (STR2), sizeof (STR2) - 1)
+#define LITSTRCPY(DEST,STR2) memcpy ((DEST), (STR2), sizeof (STR2))
+
+
+#define BFD_SUPPORTS_PLUGINS @supports_plugins@
+
+/* The word size used by BFD on the host. This may be 64 with a 32
+ bit target if the host is 64 bit, or if other 64 bit targets have
+ been selected with --enable-targets, or if --enable-64-bit-bfd. */
+#define BFD_ARCH_SIZE @wordsize@
+
+/* The word size of the default bfd target. */
+#define BFD_DEFAULT_TARGET_SIZE @bfd_default_target_size@
+
+#define BFD_HOST_64BIT_LONG @BFD_HOST_64BIT_LONG@
+#define BFD_HOST_64BIT_LONG_LONG @BFD_HOST_64BIT_LONG_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@
+typedef BFD_HOST_64_BIT bfd_int64_t;
+typedef BFD_HOST_U_64_BIT bfd_uint64_t;
+#endif
+
+#if BFD_ARCH_SIZE >= 64
+#define BFD64
+#endif
+
+#ifndef INLINE
+#if __GNUC__ >= 2
+#define INLINE __inline__
+#else
+#define INLINE
+#endif
+#endif
+
+/* Declaring a type wide enough to hold a host long and a host pointer. */
+#define BFD_HOSTPTR_T @BFD_HOSTPTR_T@
+typedef BFD_HOSTPTR_T bfd_hostptr_t;
+
+/* Forward declaration. */
+typedef struct bfd bfd;
+
+/* Boolean type used in bfd. Too many systems define their own
+ versions of "boolean" for us to safely typedef a "boolean" of
+ our own. Using an enum for "bfd_boolean" has its own set of
+ problems, with strange looking casts required to avoid warnings
+ on some older compilers. Thus we just use an int.
+
+ General rule: Functions which are bfd_boolean return TRUE on
+ success and FALSE on failure (unless they're a predicate). */
+
+typedef int bfd_boolean;
+#undef FALSE
+#undef TRUE
+#define FALSE 0
+#define TRUE 1
+
+#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;
+
+#if BFD_HOST_64BIT_LONG
+#define BFD_VMA_FMT "l"
+#elif defined (__MSVCRT__)
+#define BFD_VMA_FMT "I64"
+#else
+#define BFD_VMA_FMT "ll"
+#endif
+
+#ifndef fprintf_vma
+#define sprintf_vma(s,x) sprintf (s, "%016" BFD_VMA_FMT "x", x)
+#define fprintf_vma(f,x) fprintf (f, "%016" BFD_VMA_FMT "x", x)
+#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 BFD_VMA_FMT "l"
+#define fprintf_vma(s,x) fprintf (s, "%08" BFD_VMA_FMT "x", x)
+#define sprintf_vma(s,x) sprintf (s, "%08" BFD_VMA_FMT "x", x)
+
+#endif /* not BFD64 */
+
+#define HALF_BFD_SIZE_TYPE \
+ (((bfd_size_type) 1) << (8 * sizeof (bfd_size_type) / 2))
+
+#ifndef BFD_HOST_64_BIT
+/* Fall back on a 32 bit type. The idea is to make these types always
+ available for function return types, but in the case that
+ BFD_HOST_64_BIT is undefined such a function should abort or
+ otherwise signal an error. */
+typedef bfd_signed_vma bfd_int64_t;
+typedef bfd_vma bfd_uint64_t;
+#endif
+
+/* An offset into a file. BFD always uses the largest possible offset
+ based on the build time availability of fseek, fseeko, or fseeko64. */
+typedef @bfd_file_ptr@ file_ptr;
+typedef unsigned @bfd_file_ptr@ ufile_ptr;
+
+extern void bfd_sprintf_vma (bfd *, char *, bfd_vma);
+extern void bfd_fprintf_vma (bfd *, void *, bfd_vma);
+
+#define printf_vma(x) fprintf_vma(stdout,x)
+#define bfd_printf_vma(abfd,x) bfd_fprintf_vma (abfd,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/assembler/compiler output. */
+ bfd_archive, /* Object archive file. */
+ bfd_core, /* Core dump. */
+ bfd_type_end /* Marks the end; don't use it! */
+}
+bfd_format;
+
+/* 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) \
+ (((x)->flags & BSF_SYNTHETIC) != 0 \
+ ? bfd_target_unknown_flavour \
+ : 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. */
+ union
+ {
+ file_ptr pos;
+ bfd *abfd;
+ } u; /* 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 bfd_symbol *sym; /* Function name. */
+ bfd_vma offset; /* Offset into section. */
+ } u;
+}
+alent;
+
+/* Object and core file sections. */
+
+#define align_power(addr, align) \
+ (((addr) + ((bfd_vma) 1 << (align)) - 1) & ((bfd_vma) -1 << (align)))
+
+typedef struct bfd_section *sec_ptr;
+
+#define bfd_get_section_name(bfd, ptr) ((void) bfd, (ptr)->name)
+#define bfd_get_section_vma(bfd, ptr) ((void) bfd, (ptr)->vma)
+#define bfd_get_section_lma(bfd, ptr) ((void) bfd, (ptr)->lma)
+#define bfd_get_section_alignment(bfd, ptr) ((void) bfd, \
+ (ptr)->alignment_power)
+#define bfd_section_name(bfd, ptr) ((ptr)->name)
+#define bfd_section_size(bfd, ptr) ((ptr)->size)
+#define bfd_get_section_size(ptr) ((ptr)->size)
+#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) ((void) bfd, (ptr)->flags)
+#define bfd_get_section_userdata(bfd, ptr) ((void) bfd, (ptr)->userdata)
+
+#define bfd_is_com_section(ptr) (((ptr)->flags & SEC_IS_COMMON) != 0)
+
+/* Find the address one past the end of SEC. */
+#define bfd_get_section_limit(bfd, sec) \
+ (((bfd)->direction != write_direction && (sec)->rawsize != 0 \
+ ? (sec)->rawsize : (sec)->size) / bfd_octets_per_byte (bfd))
+
+/* Return TRUE if input section SEC has been discarded. */
+#define discarded_section(sec) \
+ (!bfd_is_abs_section (sec) \
+ && bfd_is_abs_section ((sec)->output_section) \
+ && (sec)->sec_info_type != SEC_INFO_TYPE_MERGE \
+ && (sec)->sec_info_type != SEC_INFO_TYPE_JUST_SYMS)
+
+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 (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;
+ /* 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)
+ (struct bfd_hash_entry *, struct bfd_hash_table *, const char *);
+ /* An objalloc for this hash table. This is a struct objalloc *,
+ but we use void * to avoid requiring the inclusion of objalloc.h. */
+ void *memory;
+ /* The number of slots in the hash table. */
+ unsigned int size;
+ /* The number of entries in the hash table. */
+ unsigned int count;
+ /* The size of elements. */
+ unsigned int entsize;
+ /* If non-zero, don't grow the hash table. */
+ unsigned int frozen:1;
+};
+
+/* Initialize a hash table. */
+extern bfd_boolean bfd_hash_table_init
+ (struct bfd_hash_table *,
+ struct bfd_hash_entry *(*) (struct bfd_hash_entry *,
+ struct bfd_hash_table *,
+ const char *),
+ unsigned int);
+
+/* Initialize a hash table specifying a size. */
+extern bfd_boolean bfd_hash_table_init_n
+ (struct bfd_hash_table *,
+ struct bfd_hash_entry *(*) (struct bfd_hash_entry *,
+ struct bfd_hash_table *,
+ const char *),
+ unsigned int, unsigned int);
+
+/* Free up a hash table. */
+extern void bfd_hash_table_free
+ (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
+ (struct bfd_hash_table *, const char *, bfd_boolean create,
+ bfd_boolean copy);
+
+/* Insert an entry in a hash table. */
+extern struct bfd_hash_entry *bfd_hash_insert
+ (struct bfd_hash_table *, const char *, unsigned long);
+
+/* Rename an entry in a hash table. */
+extern void bfd_hash_rename
+ (struct bfd_hash_table *, const char *, struct bfd_hash_entry *);
+
+/* Replace an entry in a hash table. */
+extern void bfd_hash_replace
+ (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
+ (struct bfd_hash_entry *, struct bfd_hash_table *, const char *);
+
+/* Grab some space for a hash table entry. */
+extern void *bfd_hash_allocate
+ (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
+ (struct bfd_hash_table *,
+ bfd_boolean (*) (struct bfd_hash_entry *, void *),
+ void *info);
+
+/* Allows the default size of a hash table to be configured. New hash
+ tables allocated using bfd_hash_table_init will be created with
+ this size. */
+extern unsigned long bfd_hash_set_default_size (unsigned long);
+
+/* 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 bfd_hash_table includes;
+ /* The first .stabstr section. */
+ struct bfd_section *stabstr;
+};
+
+#define COFF_SWAP_TABLE (void *) &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_bread (void *, bfd_size_type, bfd *);
+extern bfd_size_type bfd_bwrite (const void *, bfd_size_type, bfd *);
+extern int bfd_seek (bfd *, file_ptr, int);
+extern file_ptr bfd_tell (bfd *);
+extern int bfd_flush (bfd *);
+extern int bfd_stat (bfd *, struct stat *);
+
+/* Deprecated old routines. */
+#if __GNUC__
+#define bfd_read(BUF, ELTSIZE, NITEMS, ABFD) \
+ (warn_deprecated ("bfd_read", __FILE__, __LINE__, __FUNCTION__), \
+ bfd_bread ((BUF), (ELTSIZE) * (NITEMS), (ABFD)))
+#define bfd_write(BUF, ELTSIZE, NITEMS, ABFD) \
+ (warn_deprecated ("bfd_write", __FILE__, __LINE__, __FUNCTION__), \
+ bfd_bwrite ((BUF), (ELTSIZE) * (NITEMS), (ABFD)))
+#else
+#define bfd_read(BUF, ELTSIZE, NITEMS, ABFD) \
+ (warn_deprecated ("bfd_read", (const char *) 0, 0, (const char *) 0), \
+ bfd_bread ((BUF), (ELTSIZE) * (NITEMS), (ABFD)))
+#define bfd_write(BUF, ELTSIZE, NITEMS, ABFD) \
+ (warn_deprecated ("bfd_write", (const char *) 0, 0, (const char *) 0),\
+ bfd_bwrite ((BUF), (ELTSIZE) * (NITEMS), (ABFD)))
+#endif
+extern void warn_deprecated (const char *, const char *, int, const char *);
+
+/* 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_family_coff(abfd) \
+ (bfd_get_flavour (abfd) == bfd_target_coff_flavour || \
+ bfd_get_flavour (abfd) == bfd_target_xcoff_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_is_thin_archive(abfd) ((abfd)->is_thin_archive)
+
+#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_dynamic_symcount(abfd) ((abfd)->dynsymcount)
+
+#define bfd_get_symbol_leading_char(abfd) ((abfd)->xvec->symbol_leading_char)
+
+extern bfd_boolean bfd_cache_close
+ (bfd *abfd);
+/* NB: This declaration should match the autogenerated one in libbfd.h. */
+
+extern bfd_boolean bfd_cache_close_all (void);
+
+extern bfd_boolean bfd_record_phdr
+ (bfd *, unsigned long, bfd_boolean, flagword, bfd_boolean, bfd_vma,
+ bfd_boolean, bfd_boolean, unsigned int, struct bfd_section **);
+
+/* Byte swapping routines. */
+
+bfd_uint64_t bfd_getb64 (const void *);
+bfd_uint64_t bfd_getl64 (const void *);
+bfd_int64_t bfd_getb_signed_64 (const void *);
+bfd_int64_t bfd_getl_signed_64 (const void *);
+bfd_vma bfd_getb32 (const void *);
+bfd_vma bfd_getl32 (const void *);
+bfd_signed_vma bfd_getb_signed_32 (const void *);
+bfd_signed_vma bfd_getl_signed_32 (const void *);
+bfd_vma bfd_getb16 (const void *);
+bfd_vma bfd_getl16 (const void *);
+bfd_signed_vma bfd_getb_signed_16 (const void *);
+bfd_signed_vma bfd_getl_signed_16 (const void *);
+void bfd_putb64 (bfd_uint64_t, void *);
+void bfd_putl64 (bfd_uint64_t, void *);
+void bfd_putb32 (bfd_vma, void *);
+void bfd_putl32 (bfd_vma, void *);
+void bfd_putb16 (bfd_vma, void *);
+void bfd_putl16 (bfd_vma, void *);
+
+/* Byte swapping routines which take size and endiannes as arguments. */
+
+bfd_uint64_t bfd_get_bits (const void *, int, bfd_boolean);
+void bfd_put_bits (bfd_uint64_t, void *, int, bfd_boolean);
+
+#if defined(__STDC__) || defined(ALMOST_STDC)
+struct ecoff_debug_info;
+struct ecoff_debug_swap;
+struct ecoff_extr;
+struct bfd_symbol;
+struct bfd_link_info;
+struct bfd_link_hash_entry;
+struct bfd_section_already_linked;
+struct bfd_elf_version_tree;
+#endif
+
+extern bfd_boolean bfd_section_already_linked_table_init (void);
+extern void bfd_section_already_linked_table_free (void);
+extern bfd_boolean _bfd_handle_already_linked
+ (struct bfd_section *, struct bfd_section_already_linked *,
+ struct bfd_link_info *);
+
+/* Externally visible ECOFF routines. */
+
+extern bfd_vma bfd_ecoff_get_gp_value
+ (bfd * abfd);
+extern bfd_boolean bfd_ecoff_set_gp_value
+ (bfd *abfd, bfd_vma gp_value);
+extern bfd_boolean bfd_ecoff_set_regmasks
+ (bfd *abfd, unsigned long gprmask, unsigned long fprmask,
+ unsigned long *cprmask);
+extern void *bfd_ecoff_debug_init
+ (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
+ (void *handle, bfd *output_bfd, struct ecoff_debug_info *output_debug,
+ const struct ecoff_debug_swap *output_swap, struct bfd_link_info *);
+extern bfd_boolean bfd_ecoff_debug_accumulate
+ (void *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 bfd_boolean bfd_ecoff_debug_accumulate_other
+ (void *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 bfd_boolean bfd_ecoff_debug_externals
+ (bfd *abfd, struct ecoff_debug_info *debug,
+ const struct ecoff_debug_swap *swap, bfd_boolean relocatable,
+ bfd_boolean (*get_extr) (struct bfd_symbol *, struct ecoff_extr *),
+ void (*set_index) (struct bfd_symbol *, bfd_size_type));
+extern bfd_boolean bfd_ecoff_debug_one_external
+ (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
+ (bfd *abfd, struct ecoff_debug_info *debug,
+ const struct ecoff_debug_swap *swap);
+extern bfd_boolean bfd_ecoff_write_debug
+ (bfd *abfd, struct ecoff_debug_info *debug,
+ const struct ecoff_debug_swap *swap, file_ptr where);
+extern bfd_boolean bfd_ecoff_write_accumulated_debug
+ (void *handle, bfd *abfd, struct ecoff_debug_info *debug,
+ const struct ecoff_debug_swap *swap,
+ struct bfd_link_info *info, file_ptr where);
+
+/* Externally visible ELF routines. */
+
+struct bfd_link_needed_list
+{
+ struct bfd_link_needed_list *next;
+ bfd *by;
+ const char *name;
+};
+
+enum dynamic_lib_link_class {
+ DYN_NORMAL = 0,
+ DYN_AS_NEEDED = 1,
+ DYN_DT_NEEDED = 2,
+ DYN_NO_ADD_NEEDED = 4,
+ DYN_NO_NEEDED = 8
+};
+
+enum notice_asneeded_action {
+ notice_as_needed,
+ notice_not_needed,
+ notice_needed
+};
+
+extern bfd_boolean bfd_elf_record_link_assignment
+ (bfd *, struct bfd_link_info *, const char *, bfd_boolean,
+ bfd_boolean);
+extern struct bfd_link_needed_list *bfd_elf_get_needed_list
+ (bfd *, struct bfd_link_info *);
+extern bfd_boolean bfd_elf_get_bfd_needed_list
+ (bfd *, struct bfd_link_needed_list **);
+extern bfd_boolean bfd_elf_stack_segment_size (bfd *, struct bfd_link_info *,
+ const char *, bfd_vma);
+extern bfd_boolean bfd_elf_size_dynamic_sections
+ (bfd *, const char *, const char *, const char *, const char *, const char *,
+ const char * const *, struct bfd_link_info *, struct bfd_section **);
+extern bfd_boolean bfd_elf_size_dynsym_hash_dynstr
+ (bfd *, struct bfd_link_info *);
+extern void bfd_elf_set_dt_needed_name
+ (bfd *, const char *);
+extern const char *bfd_elf_get_dt_soname
+ (bfd *);
+extern void bfd_elf_set_dyn_lib_class
+ (bfd *, enum dynamic_lib_link_class);
+extern int bfd_elf_get_dyn_lib_class
+ (bfd *);
+extern struct bfd_link_needed_list *bfd_elf_get_runpath_list
+ (bfd *, struct bfd_link_info *);
+extern int bfd_elf_discard_info
+ (bfd *, struct bfd_link_info *);
+extern unsigned int _bfd_elf_default_action_discarded
+ (struct bfd_section *);
+
+/* Return an upper bound on the number of bytes required to store a
+ copy of ABFD's program header table entries. Return -1 if an error
+ occurs; bfd_get_error will return an appropriate code. */
+extern long bfd_get_elf_phdr_upper_bound
+ (bfd *abfd);
+
+/* Copy ABFD's program header table entries to *PHDRS. The entries
+ will be stored as an array of Elf_Internal_Phdr structures, as
+ defined in include/elf/internal.h. To find out how large the
+ buffer needs to be, call bfd_get_elf_phdr_upper_bound.
+
+ Return the number of program header table entries read, or -1 if an
+ error occurs; bfd_get_error will return an appropriate code. */
+extern int bfd_get_elf_phdrs
+ (bfd *abfd, void *phdrs);
+
+/* Create a new BFD as if by bfd_openr. Rather than opening a file,
+ reconstruct an ELF file by reading the segments out of remote
+ memory based on the ELF file header at EHDR_VMA and the ELF program
+ headers it points to. If non-zero, SIZE is the known extent of the
+ object. If not null, *LOADBASEP is filled in with the difference
+ between the VMAs from which the segments were read, and the VMAs
+ the file headers (and hence BFD's idea of each section's VMA) put
+ them at.
+
+ The function TARGET_READ_MEMORY is called to copy LEN bytes from
+ the remote memory at target address VMA into the local buffer at
+ MYADDR; it should return zero on success or an `errno' code on
+ failure. TEMPL must be a BFD for a target with the word size and
+ byte order found in the remote memory. */
+extern bfd *bfd_elf_bfd_from_remote_memory
+ (bfd *templ, bfd_vma ehdr_vma, bfd_size_type size, bfd_vma *loadbasep,
+ int (*target_read_memory) (bfd_vma vma, bfd_byte *myaddr,
+ bfd_size_type len));
+
+extern struct bfd_section *_bfd_elf_tls_setup
+ (bfd *, struct bfd_link_info *);
+
+extern struct bfd_section *
+_bfd_nearby_section (bfd *, struct bfd_section *, bfd_vma);
+
+extern void _bfd_fix_excluded_sec_syms
+ (bfd *, struct bfd_link_info *);
+
+extern unsigned bfd_m68k_mach_to_features (int);
+
+extern int bfd_m68k_features_to_mach (unsigned);
+
+extern bfd_boolean bfd_m68k_elf32_create_embedded_relocs
+ (bfd *, struct bfd_link_info *, struct bfd_section *, struct bfd_section *,
+ char **);
+
+extern void bfd_elf_m68k_set_target_options (struct bfd_link_info *, int);
+
+extern bfd_boolean bfd_bfin_elf32_create_embedded_relocs
+ (bfd *, struct bfd_link_info *, struct bfd_section *, struct bfd_section *,
+ char **);
+
+extern bfd_boolean bfd_cr16_elf32_create_embedded_relocs
+ (bfd *, struct bfd_link_info *, struct bfd_section *, struct bfd_section *,
+ char **);
+
+/* SunOS shared library support routines for the linker. */
+
+extern struct bfd_link_needed_list *bfd_sunos_get_needed_list
+ (bfd *, struct bfd_link_info *);
+extern bfd_boolean bfd_sunos_record_link_assignment
+ (bfd *, struct bfd_link_info *, const char *);
+extern bfd_boolean bfd_sunos_size_dynamic_sections
+ (bfd *, struct bfd_link_info *, struct bfd_section **,
+ struct bfd_section **, struct bfd_section **);
+
+/* Linux shared library support routines for the linker. */
+
+extern bfd_boolean bfd_i386linux_size_dynamic_sections
+ (bfd *, struct bfd_link_info *);
+extern bfd_boolean bfd_m68klinux_size_dynamic_sections
+ (bfd *, struct bfd_link_info *);
+extern bfd_boolean bfd_sparclinux_size_dynamic_sections
+ (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. */
+ void *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
+ (bfd_window *);
+extern void bfd_free_window
+ (bfd_window *);
+extern bfd_boolean bfd_get_file_window
+ (bfd *, file_ptr, bfd_size_type, bfd_window *, bfd_boolean);
+
+/* XCOFF support routines for the linker. */
+
+extern bfd_boolean bfd_xcoff_split_import_path
+ (bfd *, const char *, const char **, const char **);
+extern bfd_boolean bfd_xcoff_set_archive_import_path
+ (struct bfd_link_info *, bfd *, const char *);
+extern bfd_boolean bfd_xcoff_link_record_set
+ (bfd *, struct bfd_link_info *, struct bfd_link_hash_entry *, bfd_size_type);
+extern bfd_boolean bfd_xcoff_import_symbol
+ (bfd *, struct bfd_link_info *, struct bfd_link_hash_entry *, bfd_vma,
+ const char *, const char *, const char *, unsigned int);
+extern bfd_boolean bfd_xcoff_export_symbol
+ (bfd *, struct bfd_link_info *, struct bfd_link_hash_entry *);
+extern bfd_boolean bfd_xcoff_link_count_reloc
+ (bfd *, struct bfd_link_info *, const char *);
+extern bfd_boolean bfd_xcoff_record_link_assignment
+ (bfd *, struct bfd_link_info *, const char *);
+extern bfd_boolean bfd_xcoff_size_dynamic_sections
+ (bfd *, struct bfd_link_info *, const char *, const char *,
+ unsigned long, unsigned long, unsigned long, bfd_boolean,
+ int, bfd_boolean, unsigned int, struct bfd_section **, bfd_boolean);
+extern bfd_boolean bfd_xcoff_link_generate_rtinit
+ (bfd *, const char *, const char *, bfd_boolean);
+
+/* XCOFF support routines for ar. */
+extern bfd_boolean bfd_xcoff_ar_archive_set_magic
+ (bfd *, char *);
+
+/* Externally visible COFF routines. */
+
+#if defined(__STDC__) || defined(ALMOST_STDC)
+struct internal_syment;
+union internal_auxent;
+#endif
+
+extern bfd_boolean bfd_coff_get_syment
+ (bfd *, struct bfd_symbol *, struct internal_syment *);
+
+extern bfd_boolean bfd_coff_get_auxent
+ (bfd *, struct bfd_symbol *, int, union internal_auxent *);
+
+extern bfd_boolean bfd_coff_set_symbol_class
+ (bfd *, struct bfd_symbol *, unsigned int);
+
+extern bfd_boolean bfd_m68k_coff_create_embedded_relocs
+ (bfd *, struct bfd_link_info *, struct bfd_section *, struct bfd_section *, char **);
+
+/* ARM VFP11 erratum workaround support. */
+typedef enum
+{
+ BFD_ARM_VFP11_FIX_DEFAULT,
+ BFD_ARM_VFP11_FIX_NONE,
+ BFD_ARM_VFP11_FIX_SCALAR,
+ BFD_ARM_VFP11_FIX_VECTOR
+} bfd_arm_vfp11_fix;
+
+extern void bfd_elf32_arm_init_maps
+ (bfd *);
+
+extern void bfd_elf32_arm_set_vfp11_fix
+ (bfd *, struct bfd_link_info *);
+
+extern void bfd_elf32_arm_set_cortex_a8_fix
+ (bfd *, struct bfd_link_info *);
+
+extern bfd_boolean bfd_elf32_arm_vfp11_erratum_scan
+ (bfd *, struct bfd_link_info *);
+
+extern void bfd_elf32_arm_vfp11_fix_veneer_locations
+ (bfd *, struct bfd_link_info *);
+
+/* ARM Interworking support. Called from linker. */
+extern bfd_boolean bfd_arm_allocate_interworking_sections
+ (struct bfd_link_info *);
+
+extern bfd_boolean bfd_arm_process_before_allocation
+ (bfd *, struct bfd_link_info *, int);
+
+extern bfd_boolean bfd_arm_get_bfd_for_interworking
+ (bfd *, struct bfd_link_info *);
+
+/* PE ARM Interworking support. Called from linker. */
+extern bfd_boolean bfd_arm_pe_allocate_interworking_sections
+ (struct bfd_link_info *);
+
+extern bfd_boolean bfd_arm_pe_process_before_allocation
+ (bfd *, struct bfd_link_info *, int);
+
+extern bfd_boolean bfd_arm_pe_get_bfd_for_interworking
+ (bfd *, struct bfd_link_info *);
+
+/* ELF ARM Interworking support. Called from linker. */
+extern bfd_boolean bfd_elf32_arm_allocate_interworking_sections
+ (struct bfd_link_info *);
+
+extern bfd_boolean bfd_elf32_arm_process_before_allocation
+ (bfd *, struct bfd_link_info *);
+
+void bfd_elf32_arm_set_target_relocs
+ (bfd *, struct bfd_link_info *, int, char *, int, int, bfd_arm_vfp11_fix,
+ int, int, int, int, int);
+
+extern bfd_boolean bfd_elf32_arm_get_bfd_for_interworking
+ (bfd *, struct bfd_link_info *);
+
+extern bfd_boolean bfd_elf32_arm_add_glue_sections_to_bfd
+ (bfd *, struct bfd_link_info *);
+
+/* ELF ARM mapping symbol support. */
+#define BFD_ARM_SPECIAL_SYM_TYPE_MAP (1 << 0)
+#define BFD_ARM_SPECIAL_SYM_TYPE_TAG (1 << 1)
+#define BFD_ARM_SPECIAL_SYM_TYPE_OTHER (1 << 2)
+#define BFD_ARM_SPECIAL_SYM_TYPE_ANY (~0)
+
+extern bfd_boolean bfd_is_arm_special_symbol_name
+ (const char *, int);
+
+extern void bfd_elf32_arm_set_byteswap_code
+ (struct bfd_link_info *, int);
+
+extern void bfd_elf32_arm_use_long_plt (void);
+
+/* ARM Note section processing. */
+extern bfd_boolean bfd_arm_merge_machines
+ (bfd *, bfd *);
+
+extern bfd_boolean bfd_arm_update_notes
+ (bfd *, const char *);
+
+extern unsigned int bfd_arm_get_mach_from_notes
+ (bfd *, const char *);
+
+/* ARM stub generation support. Called from the linker. */
+extern int elf32_arm_setup_section_lists
+ (bfd *, struct bfd_link_info *);
+extern void elf32_arm_next_input_section
+ (struct bfd_link_info *, struct bfd_section *);
+extern bfd_boolean elf32_arm_size_stubs
+ (bfd *, bfd *, struct bfd_link_info *, bfd_signed_vma,
+ struct bfd_section * (*) (const char *, struct bfd_section *, unsigned int),
+ void (*) (void));
+extern bfd_boolean elf32_arm_build_stubs
+ (struct bfd_link_info *);
+
+/* ARM unwind section editing support. */
+extern bfd_boolean elf32_arm_fix_exidx_coverage
+(struct bfd_section **, unsigned int, struct bfd_link_info *, bfd_boolean);
+
+/* C6x unwind section editing support. */
+extern bfd_boolean elf32_tic6x_fix_exidx_coverage
+(struct bfd_section **, unsigned int, struct bfd_link_info *, bfd_boolean);
+
+/* PowerPC @tls opcode transform/validate. */
+extern unsigned int _bfd_elf_ppc_at_tls_transform
+ (unsigned int, unsigned int);
+/* PowerPC @tprel opcode transform/validate. */
+extern unsigned int _bfd_elf_ppc_at_tprel_transform
+ (unsigned int, unsigned int);
+
+extern void bfd_elf64_aarch64_init_maps
+ (bfd *);
+
+extern void bfd_elf32_aarch64_init_maps
+ (bfd *);
+
+extern void bfd_elf64_aarch64_set_options
+ (bfd *, struct bfd_link_info *, int, int, int, int);
+
+extern void bfd_elf32_aarch64_set_options
+ (bfd *, struct bfd_link_info *, int, int, int, int);
+
+/* ELF AArch64 mapping symbol support. */
+#define BFD_AARCH64_SPECIAL_SYM_TYPE_MAP (1 << 0)
+#define BFD_AARCH64_SPECIAL_SYM_TYPE_TAG (1 << 1)
+#define BFD_AARCH64_SPECIAL_SYM_TYPE_OTHER (1 << 2)
+#define BFD_AARCH64_SPECIAL_SYM_TYPE_ANY (~0)
+extern bfd_boolean bfd_is_aarch64_special_symbol_name
+ (const char * name, int type);
+
+/* AArch64 stub generation support for ELF64. Called from the linker. */
+extern int elf64_aarch64_setup_section_lists
+ (bfd *, struct bfd_link_info *);
+extern void elf64_aarch64_next_input_section
+ (struct bfd_link_info *, struct bfd_section *);
+extern bfd_boolean elf64_aarch64_size_stubs
+ (bfd *, bfd *, struct bfd_link_info *, bfd_signed_vma,
+ struct bfd_section * (*) (const char *, struct bfd_section *),
+ void (*) (void));
+extern bfd_boolean elf64_aarch64_build_stubs
+ (struct bfd_link_info *);
+/* AArch64 stub generation support for ELF32. Called from the linker. */
+extern int elf32_aarch64_setup_section_lists
+ (bfd *, struct bfd_link_info *);
+extern void elf32_aarch64_next_input_section
+ (struct bfd_link_info *, struct bfd_section *);
+extern bfd_boolean elf32_aarch64_size_stubs
+ (bfd *, bfd *, struct bfd_link_info *, bfd_signed_vma,
+ struct bfd_section * (*) (const char *, struct bfd_section *),
+ void (*) (void));
+extern bfd_boolean elf32_aarch64_build_stubs
+ (struct bfd_link_info *);
+
+
+/* TI COFF load page support. */
+extern void bfd_ticoff_set_section_load_page
+ (struct bfd_section *, int);
+
+extern int bfd_ticoff_get_section_load_page
+ (struct bfd_section *);
+
+/* H8/300 functions. */
+extern bfd_vma bfd_h8300_pad_address
+ (bfd *, bfd_vma);
+
+/* IA64 Itanium code generation. Called from linker. */
+extern void bfd_elf32_ia64_after_parse
+ (int);
+
+extern void bfd_elf64_ia64_after_parse
+ (int);
+
+/* This structure is used for a comdat section, as in PE. A comdat
+ section is associated with a particular symbol. When the linker
+ sees a comdat section, it keeps only one of the sections with a
+ given name and associated with a given symbol. */
+
+struct coff_comdat_info
+{
+ /* The name of the symbol associated with a comdat section. */
+ const char *name;
+
+ /* The local symbol table index of the symbol associated with a
+ comdat section. This is only meaningful to the object file format
+ specific code; it is not an index into the list returned by
+ bfd_canonicalize_symtab. */
+ long symbol;
+};
+
+extern struct coff_comdat_info * bfd_coff_get_comdat_section
+ (bfd *, struct bfd_section *);
diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
new file mode 100644
index 0000000..c7a2bb5
--- /dev/null
+++ b/bfd/bfd-in2.h
@@ -0,0 +1,7279 @@
+/* DO NOT EDIT! -*- buffer-read-only: t -*- This file is automatically
+ generated from "bfd-in.h", "init.c", "opncls.c", "libbfd.c",
+ "bfdio.c", "bfdwin.c", "section.c", "archures.c", "reloc.c",
+ "syms.c", "bfd.c", "archive.c", "corefile.c", "targets.c", "format.c",
+ "linker.c", "simple.c" and "compress.c".
+ Run "make headers" in your build bfd/ to regenerate. */
+
+/* Main header file for the bfd library -- portable access to object files.
+
+ Copyright (C) 1990-2014 Free Software Foundation, Inc.
+
+ Contributed 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#ifndef __BFD_H_SEEN__
+#define __BFD_H_SEEN__
+
+/* PR 14072: Ensure that config.h is included first. */
+#if !defined PACKAGE && !defined PACKAGE_VERSION
+#error config.h must be included before this header
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "ansidecl.h"
+#include "symcat.h"
+#include <sys/stat.h>
+
+#if defined (__STDC__) || defined (ALMOST_STDC) || defined (HAVE_STRINGIZE)
+#ifndef SABER
+/* This 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 XCONCAT2 macro will
+ cause the inner CONCAT2 macros to be evaluated first, producing
+ still-valid pp-tokens. Then the final concatenation can be done. */
+#undef CONCAT4
+#define CONCAT4(a,b,c,d) XCONCAT2(CONCAT2(a,b),CONCAT2(c,d))
+#endif
+#endif
+
+/* This is a utility macro to handle the situation where the code
+ wants to place a constant string into the code, followed by a
+ comma and then the length of the string. Doing this by hand
+ is error prone, so using this macro is safer. */
+#define STRING_COMMA_LEN(STR) (STR), (sizeof (STR) - 1)
+/* Unfortunately it is not possible to use the STRING_COMMA_LEN macro
+ to create the arguments to another macro, since the preprocessor
+ will mis-count the number of arguments to the outer macro (by not
+ evaluating STRING_COMMA_LEN and so missing the comma). This is a
+ problem for example when trying to use STRING_COMMA_LEN to build
+ the arguments to the strncmp() macro. Hence this alternative
+ definition of strncmp is provided here.
+
+ Note - these macros do NOT work if STR2 is not a constant string. */
+#define CONST_STRNEQ(STR1,STR2) (strncmp ((STR1), (STR2), sizeof (STR2) - 1) == 0)
+ /* strcpy() can have a similar problem, but since we know we are
+ copying a constant string, we can use memcpy which will be faster
+ since there is no need to check for a NUL byte inside STR. We
+ can also save time if we do not need to copy the terminating NUL. */
+#define LITMEMCPY(DEST,STR2) memcpy ((DEST), (STR2), sizeof (STR2) - 1)
+#define LITSTRCPY(DEST,STR2) memcpy ((DEST), (STR2), sizeof (STR2))
+
+
+#define BFD_SUPPORTS_PLUGINS @supports_plugins@
+
+/* The word size used by BFD on the host. This may be 64 with a 32
+ bit target if the host is 64 bit, or if other 64 bit targets have
+ been selected with --enable-targets, or if --enable-64-bit-bfd. */
+#define BFD_ARCH_SIZE @wordsize@
+
+/* The word size of the default bfd target. */
+#define BFD_DEFAULT_TARGET_SIZE @bfd_default_target_size@
+
+#define BFD_HOST_64BIT_LONG @BFD_HOST_64BIT_LONG@
+#define BFD_HOST_64BIT_LONG_LONG @BFD_HOST_64BIT_LONG_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@
+typedef BFD_HOST_64_BIT bfd_int64_t;
+typedef BFD_HOST_U_64_BIT bfd_uint64_t;
+#endif
+
+#if BFD_ARCH_SIZE >= 64
+#define BFD64
+#endif
+
+#ifndef INLINE
+#if __GNUC__ >= 2
+#define INLINE __inline__
+#else
+#define INLINE
+#endif
+#endif
+
+/* Declaring a type wide enough to hold a host long and a host pointer. */
+#define BFD_HOSTPTR_T @BFD_HOSTPTR_T@
+typedef BFD_HOSTPTR_T bfd_hostptr_t;
+
+/* Forward declaration. */
+typedef struct bfd bfd;
+
+/* Boolean type used in bfd. Too many systems define their own
+ versions of "boolean" for us to safely typedef a "boolean" of
+ our own. Using an enum for "bfd_boolean" has its own set of
+ problems, with strange looking casts required to avoid warnings
+ on some older compilers. Thus we just use an int.
+
+ General rule: Functions which are bfd_boolean return TRUE on
+ success and FALSE on failure (unless they're a predicate). */
+
+typedef int bfd_boolean;
+#undef FALSE
+#undef TRUE
+#define FALSE 0
+#define TRUE 1
+
+#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;
+
+#if BFD_HOST_64BIT_LONG
+#define BFD_VMA_FMT "l"
+#elif defined (__MSVCRT__)
+#define BFD_VMA_FMT "I64"
+#else
+#define BFD_VMA_FMT "ll"
+#endif
+
+#ifndef fprintf_vma
+#define sprintf_vma(s,x) sprintf (s, "%016" BFD_VMA_FMT "x", x)
+#define fprintf_vma(f,x) fprintf (f, "%016" BFD_VMA_FMT "x", x)
+#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 BFD_VMA_FMT "l"
+#define fprintf_vma(s,x) fprintf (s, "%08" BFD_VMA_FMT "x", x)
+#define sprintf_vma(s,x) sprintf (s, "%08" BFD_VMA_FMT "x", x)
+
+#endif /* not BFD64 */
+
+#define HALF_BFD_SIZE_TYPE \
+ (((bfd_size_type) 1) << (8 * sizeof (bfd_size_type) / 2))
+
+#ifndef BFD_HOST_64_BIT
+/* Fall back on a 32 bit type. The idea is to make these types always
+ available for function return types, but in the case that
+ BFD_HOST_64_BIT is undefined such a function should abort or
+ otherwise signal an error. */
+typedef bfd_signed_vma bfd_int64_t;
+typedef bfd_vma bfd_uint64_t;
+#endif
+
+/* An offset into a file. BFD always uses the largest possible offset
+ based on the build time availability of fseek, fseeko, or fseeko64. */
+typedef @bfd_file_ptr@ file_ptr;
+typedef unsigned @bfd_file_ptr@ ufile_ptr;
+
+extern void bfd_sprintf_vma (bfd *, char *, bfd_vma);
+extern void bfd_fprintf_vma (bfd *, void *, bfd_vma);
+
+#define printf_vma(x) fprintf_vma(stdout,x)
+#define bfd_printf_vma(abfd,x) bfd_fprintf_vma (abfd,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/assembler/compiler output. */
+ bfd_archive, /* Object archive file. */
+ bfd_core, /* Core dump. */
+ bfd_type_end /* Marks the end; don't use it! */
+}
+bfd_format;
+
+/* 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) \
+ (((x)->flags & BSF_SYNTHETIC) != 0 \
+ ? bfd_target_unknown_flavour \
+ : 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. */
+ union
+ {
+ file_ptr pos;
+ bfd *abfd;
+ } u; /* 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 bfd_symbol *sym; /* Function name. */
+ bfd_vma offset; /* Offset into section. */
+ } u;
+}
+alent;
+
+/* Object and core file sections. */
+
+#define align_power(addr, align) \
+ (((addr) + ((bfd_vma) 1 << (align)) - 1) & ((bfd_vma) -1 << (align)))
+
+typedef struct bfd_section *sec_ptr;
+
+#define bfd_get_section_name(bfd, ptr) ((void) bfd, (ptr)->name)
+#define bfd_get_section_vma(bfd, ptr) ((void) bfd, (ptr)->vma)
+#define bfd_get_section_lma(bfd, ptr) ((void) bfd, (ptr)->lma)
+#define bfd_get_section_alignment(bfd, ptr) ((void) bfd, \
+ (ptr)->alignment_power)
+#define bfd_section_name(bfd, ptr) ((ptr)->name)
+#define bfd_section_size(bfd, ptr) ((ptr)->size)
+#define bfd_get_section_size(ptr) ((ptr)->size)
+#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) ((void) bfd, (ptr)->flags)
+#define bfd_get_section_userdata(bfd, ptr) ((void) bfd, (ptr)->userdata)
+
+#define bfd_is_com_section(ptr) (((ptr)->flags & SEC_IS_COMMON) != 0)
+
+/* Find the address one past the end of SEC. */
+#define bfd_get_section_limit(bfd, sec) \
+ (((bfd)->direction != write_direction && (sec)->rawsize != 0 \
+ ? (sec)->rawsize : (sec)->size) / bfd_octets_per_byte (bfd))
+
+/* Return TRUE if input section SEC has been discarded. */
+#define discarded_section(sec) \
+ (!bfd_is_abs_section (sec) \
+ && bfd_is_abs_section ((sec)->output_section) \
+ && (sec)->sec_info_type != SEC_INFO_TYPE_MERGE \
+ && (sec)->sec_info_type != SEC_INFO_TYPE_JUST_SYMS)
+
+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 (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;
+ /* 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)
+ (struct bfd_hash_entry *, struct bfd_hash_table *, const char *);
+ /* An objalloc for this hash table. This is a struct objalloc *,
+ but we use void * to avoid requiring the inclusion of objalloc.h. */
+ void *memory;
+ /* The number of slots in the hash table. */
+ unsigned int size;
+ /* The number of entries in the hash table. */
+ unsigned int count;
+ /* The size of elements. */
+ unsigned int entsize;
+ /* If non-zero, don't grow the hash table. */
+ unsigned int frozen:1;
+};
+
+/* Initialize a hash table. */
+extern bfd_boolean bfd_hash_table_init
+ (struct bfd_hash_table *,
+ struct bfd_hash_entry *(*) (struct bfd_hash_entry *,
+ struct bfd_hash_table *,
+ const char *),
+ unsigned int);
+
+/* Initialize a hash table specifying a size. */
+extern bfd_boolean bfd_hash_table_init_n
+ (struct bfd_hash_table *,
+ struct bfd_hash_entry *(*) (struct bfd_hash_entry *,
+ struct bfd_hash_table *,
+ const char *),
+ unsigned int, unsigned int);
+
+/* Free up a hash table. */
+extern void bfd_hash_table_free
+ (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
+ (struct bfd_hash_table *, const char *, bfd_boolean create,
+ bfd_boolean copy);
+
+/* Insert an entry in a hash table. */
+extern struct bfd_hash_entry *bfd_hash_insert
+ (struct bfd_hash_table *, const char *, unsigned long);
+
+/* Rename an entry in a hash table. */
+extern void bfd_hash_rename
+ (struct bfd_hash_table *, const char *, struct bfd_hash_entry *);
+
+/* Replace an entry in a hash table. */
+extern void bfd_hash_replace
+ (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
+ (struct bfd_hash_entry *, struct bfd_hash_table *, const char *);
+
+/* Grab some space for a hash table entry. */
+extern void *bfd_hash_allocate
+ (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
+ (struct bfd_hash_table *,
+ bfd_boolean (*) (struct bfd_hash_entry *, void *),
+ void *info);
+
+/* Allows the default size of a hash table to be configured. New hash
+ tables allocated using bfd_hash_table_init will be created with
+ this size. */
+extern unsigned long bfd_hash_set_default_size (unsigned long);
+
+/* 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 bfd_hash_table includes;
+ /* The first .stabstr section. */
+ struct bfd_section *stabstr;
+};
+
+#define COFF_SWAP_TABLE (void *) &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_bread (void *, bfd_size_type, bfd *);
+extern bfd_size_type bfd_bwrite (const void *, bfd_size_type, bfd *);
+extern int bfd_seek (bfd *, file_ptr, int);
+extern file_ptr bfd_tell (bfd *);
+extern int bfd_flush (bfd *);
+extern int bfd_stat (bfd *, struct stat *);
+
+/* Deprecated old routines. */
+#if __GNUC__
+#define bfd_read(BUF, ELTSIZE, NITEMS, ABFD) \
+ (warn_deprecated ("bfd_read", __FILE__, __LINE__, __FUNCTION__), \
+ bfd_bread ((BUF), (ELTSIZE) * (NITEMS), (ABFD)))
+#define bfd_write(BUF, ELTSIZE, NITEMS, ABFD) \
+ (warn_deprecated ("bfd_write", __FILE__, __LINE__, __FUNCTION__), \
+ bfd_bwrite ((BUF), (ELTSIZE) * (NITEMS), (ABFD)))
+#else
+#define bfd_read(BUF, ELTSIZE, NITEMS, ABFD) \
+ (warn_deprecated ("bfd_read", (const char *) 0, 0, (const char *) 0), \
+ bfd_bread ((BUF), (ELTSIZE) * (NITEMS), (ABFD)))
+#define bfd_write(BUF, ELTSIZE, NITEMS, ABFD) \
+ (warn_deprecated ("bfd_write", (const char *) 0, 0, (const char *) 0),\
+ bfd_bwrite ((BUF), (ELTSIZE) * (NITEMS), (ABFD)))
+#endif
+extern void warn_deprecated (const char *, const char *, int, const char *);
+
+/* 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_family_coff(abfd) \
+ (bfd_get_flavour (abfd) == bfd_target_coff_flavour || \
+ bfd_get_flavour (abfd) == bfd_target_xcoff_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_is_thin_archive(abfd) ((abfd)->is_thin_archive)
+
+#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_dynamic_symcount(abfd) ((abfd)->dynsymcount)
+
+#define bfd_get_symbol_leading_char(abfd) ((abfd)->xvec->symbol_leading_char)
+
+extern bfd_boolean bfd_cache_close
+ (bfd *abfd);
+/* NB: This declaration should match the autogenerated one in libbfd.h. */
+
+extern bfd_boolean bfd_cache_close_all (void);
+
+extern bfd_boolean bfd_record_phdr
+ (bfd *, unsigned long, bfd_boolean, flagword, bfd_boolean, bfd_vma,
+ bfd_boolean, bfd_boolean, unsigned int, struct bfd_section **);
+
+/* Byte swapping routines. */
+
+bfd_uint64_t bfd_getb64 (const void *);
+bfd_uint64_t bfd_getl64 (const void *);
+bfd_int64_t bfd_getb_signed_64 (const void *);
+bfd_int64_t bfd_getl_signed_64 (const void *);
+bfd_vma bfd_getb32 (const void *);
+bfd_vma bfd_getl32 (const void *);
+bfd_signed_vma bfd_getb_signed_32 (const void *);
+bfd_signed_vma bfd_getl_signed_32 (const void *);
+bfd_vma bfd_getb16 (const void *);
+bfd_vma bfd_getl16 (const void *);
+bfd_signed_vma bfd_getb_signed_16 (const void *);
+bfd_signed_vma bfd_getl_signed_16 (const void *);
+void bfd_putb64 (bfd_uint64_t, void *);
+void bfd_putl64 (bfd_uint64_t, void *);
+void bfd_putb32 (bfd_vma, void *);
+void bfd_putl32 (bfd_vma, void *);
+void bfd_putb16 (bfd_vma, void *);
+void bfd_putl16 (bfd_vma, void *);
+
+/* Byte swapping routines which take size and endiannes as arguments. */
+
+bfd_uint64_t bfd_get_bits (const void *, int, bfd_boolean);
+void bfd_put_bits (bfd_uint64_t, void *, int, bfd_boolean);
+
+#if defined(__STDC__) || defined(ALMOST_STDC)
+struct ecoff_debug_info;
+struct ecoff_debug_swap;
+struct ecoff_extr;
+struct bfd_symbol;
+struct bfd_link_info;
+struct bfd_link_hash_entry;
+struct bfd_section_already_linked;
+struct bfd_elf_version_tree;
+#endif
+
+extern bfd_boolean bfd_section_already_linked_table_init (void);
+extern void bfd_section_already_linked_table_free (void);
+extern bfd_boolean _bfd_handle_already_linked
+ (struct bfd_section *, struct bfd_section_already_linked *,
+ struct bfd_link_info *);
+
+/* Externally visible ECOFF routines. */
+
+extern bfd_vma bfd_ecoff_get_gp_value
+ (bfd * abfd);
+extern bfd_boolean bfd_ecoff_set_gp_value
+ (bfd *abfd, bfd_vma gp_value);
+extern bfd_boolean bfd_ecoff_set_regmasks
+ (bfd *abfd, unsigned long gprmask, unsigned long fprmask,
+ unsigned long *cprmask);
+extern void *bfd_ecoff_debug_init
+ (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
+ (void *handle, bfd *output_bfd, struct ecoff_debug_info *output_debug,
+ const struct ecoff_debug_swap *output_swap, struct bfd_link_info *);
+extern bfd_boolean bfd_ecoff_debug_accumulate
+ (void *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 bfd_boolean bfd_ecoff_debug_accumulate_other
+ (void *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 bfd_boolean bfd_ecoff_debug_externals
+ (bfd *abfd, struct ecoff_debug_info *debug,
+ const struct ecoff_debug_swap *swap, bfd_boolean relocatable,
+ bfd_boolean (*get_extr) (struct bfd_symbol *, struct ecoff_extr *),
+ void (*set_index) (struct bfd_symbol *, bfd_size_type));
+extern bfd_boolean bfd_ecoff_debug_one_external
+ (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
+ (bfd *abfd, struct ecoff_debug_info *debug,
+ const struct ecoff_debug_swap *swap);
+extern bfd_boolean bfd_ecoff_write_debug
+ (bfd *abfd, struct ecoff_debug_info *debug,
+ const struct ecoff_debug_swap *swap, file_ptr where);
+extern bfd_boolean bfd_ecoff_write_accumulated_debug
+ (void *handle, bfd *abfd, struct ecoff_debug_info *debug,
+ const struct ecoff_debug_swap *swap,
+ struct bfd_link_info *info, file_ptr where);
+
+/* Externally visible ELF routines. */
+
+struct bfd_link_needed_list
+{
+ struct bfd_link_needed_list *next;
+ bfd *by;
+ const char *name;
+};
+
+enum dynamic_lib_link_class {
+ DYN_NORMAL = 0,
+ DYN_AS_NEEDED = 1,
+ DYN_DT_NEEDED = 2,
+ DYN_NO_ADD_NEEDED = 4,
+ DYN_NO_NEEDED = 8
+};
+
+enum notice_asneeded_action {
+ notice_as_needed,
+ notice_not_needed,
+ notice_needed
+};
+
+extern bfd_boolean bfd_elf_record_link_assignment
+ (bfd *, struct bfd_link_info *, const char *, bfd_boolean,
+ bfd_boolean);
+extern struct bfd_link_needed_list *bfd_elf_get_needed_list
+ (bfd *, struct bfd_link_info *);
+extern bfd_boolean bfd_elf_get_bfd_needed_list
+ (bfd *, struct bfd_link_needed_list **);
+extern bfd_boolean bfd_elf_stack_segment_size (bfd *, struct bfd_link_info *,
+ const char *, bfd_vma);
+extern bfd_boolean bfd_elf_size_dynamic_sections
+ (bfd *, const char *, const char *, const char *, const char *, const char *,
+ const char * const *, struct bfd_link_info *, struct bfd_section **);
+extern bfd_boolean bfd_elf_size_dynsym_hash_dynstr
+ (bfd *, struct bfd_link_info *);
+extern void bfd_elf_set_dt_needed_name
+ (bfd *, const char *);
+extern const char *bfd_elf_get_dt_soname
+ (bfd *);
+extern void bfd_elf_set_dyn_lib_class
+ (bfd *, enum dynamic_lib_link_class);
+extern int bfd_elf_get_dyn_lib_class
+ (bfd *);
+extern struct bfd_link_needed_list *bfd_elf_get_runpath_list
+ (bfd *, struct bfd_link_info *);
+extern int bfd_elf_discard_info
+ (bfd *, struct bfd_link_info *);
+extern unsigned int _bfd_elf_default_action_discarded
+ (struct bfd_section *);
+
+/* Return an upper bound on the number of bytes required to store a
+ copy of ABFD's program header table entries. Return -1 if an error
+ occurs; bfd_get_error will return an appropriate code. */
+extern long bfd_get_elf_phdr_upper_bound
+ (bfd *abfd);
+
+/* Copy ABFD's program header table entries to *PHDRS. The entries
+ will be stored as an array of Elf_Internal_Phdr structures, as
+ defined in include/elf/internal.h. To find out how large the
+ buffer needs to be, call bfd_get_elf_phdr_upper_bound.
+
+ Return the number of program header table entries read, or -1 if an
+ error occurs; bfd_get_error will return an appropriate code. */
+extern int bfd_get_elf_phdrs
+ (bfd *abfd, void *phdrs);
+
+/* Create a new BFD as if by bfd_openr. Rather than opening a file,
+ reconstruct an ELF file by reading the segments out of remote
+ memory based on the ELF file header at EHDR_VMA and the ELF program
+ headers it points to. If non-zero, SIZE is the known extent of the
+ object. If not null, *LOADBASEP is filled in with the difference
+ between the VMAs from which the segments were read, and the VMAs
+ the file headers (and hence BFD's idea of each section's VMA) put
+ them at.
+
+ The function TARGET_READ_MEMORY is called to copy LEN bytes from
+ the remote memory at target address VMA into the local buffer at
+ MYADDR; it should return zero on success or an `errno' code on
+ failure. TEMPL must be a BFD for a target with the word size and
+ byte order found in the remote memory. */
+extern bfd *bfd_elf_bfd_from_remote_memory
+ (bfd *templ, bfd_vma ehdr_vma, bfd_size_type size, bfd_vma *loadbasep,
+ int (*target_read_memory) (bfd_vma vma, bfd_byte *myaddr,
+ bfd_size_type len));
+
+extern struct bfd_section *_bfd_elf_tls_setup
+ (bfd *, struct bfd_link_info *);
+
+extern struct bfd_section *
+_bfd_nearby_section (bfd *, struct bfd_section *, bfd_vma);
+
+extern void _bfd_fix_excluded_sec_syms
+ (bfd *, struct bfd_link_info *);
+
+extern unsigned bfd_m68k_mach_to_features (int);
+
+extern int bfd_m68k_features_to_mach (unsigned);
+
+extern bfd_boolean bfd_m68k_elf32_create_embedded_relocs
+ (bfd *, struct bfd_link_info *, struct bfd_section *, struct bfd_section *,
+ char **);
+
+extern void bfd_elf_m68k_set_target_options (struct bfd_link_info *, int);
+
+extern bfd_boolean bfd_bfin_elf32_create_embedded_relocs
+ (bfd *, struct bfd_link_info *, struct bfd_section *, struct bfd_section *,
+ char **);
+
+extern bfd_boolean bfd_cr16_elf32_create_embedded_relocs
+ (bfd *, struct bfd_link_info *, struct bfd_section *, struct bfd_section *,
+ char **);
+
+/* SunOS shared library support routines for the linker. */
+
+extern struct bfd_link_needed_list *bfd_sunos_get_needed_list
+ (bfd *, struct bfd_link_info *);
+extern bfd_boolean bfd_sunos_record_link_assignment
+ (bfd *, struct bfd_link_info *, const char *);
+extern bfd_boolean bfd_sunos_size_dynamic_sections
+ (bfd *, struct bfd_link_info *, struct bfd_section **,
+ struct bfd_section **, struct bfd_section **);
+
+/* Linux shared library support routines for the linker. */
+
+extern bfd_boolean bfd_i386linux_size_dynamic_sections
+ (bfd *, struct bfd_link_info *);
+extern bfd_boolean bfd_m68klinux_size_dynamic_sections
+ (bfd *, struct bfd_link_info *);
+extern bfd_boolean bfd_sparclinux_size_dynamic_sections
+ (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. */
+ void *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
+ (bfd_window *);
+extern void bfd_free_window
+ (bfd_window *);
+extern bfd_boolean bfd_get_file_window
+ (bfd *, file_ptr, bfd_size_type, bfd_window *, bfd_boolean);
+
+/* XCOFF support routines for the linker. */
+
+extern bfd_boolean bfd_xcoff_split_import_path
+ (bfd *, const char *, const char **, const char **);
+extern bfd_boolean bfd_xcoff_set_archive_import_path
+ (struct bfd_link_info *, bfd *, const char *);
+extern bfd_boolean bfd_xcoff_link_record_set
+ (bfd *, struct bfd_link_info *, struct bfd_link_hash_entry *, bfd_size_type);
+extern bfd_boolean bfd_xcoff_import_symbol
+ (bfd *, struct bfd_link_info *, struct bfd_link_hash_entry *, bfd_vma,
+ const char *, const char *, const char *, unsigned int);
+extern bfd_boolean bfd_xcoff_export_symbol
+ (bfd *, struct bfd_link_info *, struct bfd_link_hash_entry *);
+extern bfd_boolean bfd_xcoff_link_count_reloc
+ (bfd *, struct bfd_link_info *, const char *);
+extern bfd_boolean bfd_xcoff_record_link_assignment
+ (bfd *, struct bfd_link_info *, const char *);
+extern bfd_boolean bfd_xcoff_size_dynamic_sections
+ (bfd *, struct bfd_link_info *, const char *, const char *,
+ unsigned long, unsigned long, unsigned long, bfd_boolean,
+ int, bfd_boolean, unsigned int, struct bfd_section **, bfd_boolean);
+extern bfd_boolean bfd_xcoff_link_generate_rtinit
+ (bfd *, const char *, const char *, bfd_boolean);
+
+/* XCOFF support routines for ar. */
+extern bfd_boolean bfd_xcoff_ar_archive_set_magic
+ (bfd *, char *);
+
+/* Externally visible COFF routines. */
+
+#if defined(__STDC__) || defined(ALMOST_STDC)
+struct internal_syment;
+union internal_auxent;
+#endif
+
+extern bfd_boolean bfd_coff_get_syment
+ (bfd *, struct bfd_symbol *, struct internal_syment *);
+
+extern bfd_boolean bfd_coff_get_auxent
+ (bfd *, struct bfd_symbol *, int, union internal_auxent *);
+
+extern bfd_boolean bfd_coff_set_symbol_class
+ (bfd *, struct bfd_symbol *, unsigned int);
+
+extern bfd_boolean bfd_m68k_coff_create_embedded_relocs
+ (bfd *, struct bfd_link_info *, struct bfd_section *, struct bfd_section *, char **);
+
+/* ARM VFP11 erratum workaround support. */
+typedef enum
+{
+ BFD_ARM_VFP11_FIX_DEFAULT,
+ BFD_ARM_VFP11_FIX_NONE,
+ BFD_ARM_VFP11_FIX_SCALAR,
+ BFD_ARM_VFP11_FIX_VECTOR
+} bfd_arm_vfp11_fix;
+
+extern void bfd_elf32_arm_init_maps
+ (bfd *);
+
+extern void bfd_elf32_arm_set_vfp11_fix
+ (bfd *, struct bfd_link_info *);
+
+extern void bfd_elf32_arm_set_cortex_a8_fix
+ (bfd *, struct bfd_link_info *);
+
+extern bfd_boolean bfd_elf32_arm_vfp11_erratum_scan
+ (bfd *, struct bfd_link_info *);
+
+extern void bfd_elf32_arm_vfp11_fix_veneer_locations
+ (bfd *, struct bfd_link_info *);
+
+/* ARM Interworking support. Called from linker. */
+extern bfd_boolean bfd_arm_allocate_interworking_sections
+ (struct bfd_link_info *);
+
+extern bfd_boolean bfd_arm_process_before_allocation
+ (bfd *, struct bfd_link_info *, int);
+
+extern bfd_boolean bfd_arm_get_bfd_for_interworking
+ (bfd *, struct bfd_link_info *);
+
+/* PE ARM Interworking support. Called from linker. */
+extern bfd_boolean bfd_arm_pe_allocate_interworking_sections
+ (struct bfd_link_info *);
+
+extern bfd_boolean bfd_arm_pe_process_before_allocation
+ (bfd *, struct bfd_link_info *, int);
+
+extern bfd_boolean bfd_arm_pe_get_bfd_for_interworking
+ (bfd *, struct bfd_link_info *);
+
+/* ELF ARM Interworking support. Called from linker. */
+extern bfd_boolean bfd_elf32_arm_allocate_interworking_sections
+ (struct bfd_link_info *);
+
+extern bfd_boolean bfd_elf32_arm_process_before_allocation
+ (bfd *, struct bfd_link_info *);
+
+void bfd_elf32_arm_set_target_relocs
+ (bfd *, struct bfd_link_info *, int, char *, int, int, bfd_arm_vfp11_fix,
+ int, int, int, int, int);
+
+extern bfd_boolean bfd_elf32_arm_get_bfd_for_interworking
+ (bfd *, struct bfd_link_info *);
+
+extern bfd_boolean bfd_elf32_arm_add_glue_sections_to_bfd
+ (bfd *, struct bfd_link_info *);
+
+/* ELF ARM mapping symbol support. */
+#define BFD_ARM_SPECIAL_SYM_TYPE_MAP (1 << 0)
+#define BFD_ARM_SPECIAL_SYM_TYPE_TAG (1 << 1)
+#define BFD_ARM_SPECIAL_SYM_TYPE_OTHER (1 << 2)
+#define BFD_ARM_SPECIAL_SYM_TYPE_ANY (~0)
+
+extern bfd_boolean bfd_is_arm_special_symbol_name
+ (const char *, int);
+
+extern void bfd_elf32_arm_set_byteswap_code
+ (struct bfd_link_info *, int);
+
+extern void bfd_elf32_arm_use_long_plt (void);
+
+/* ARM Note section processing. */
+extern bfd_boolean bfd_arm_merge_machines
+ (bfd *, bfd *);
+
+extern bfd_boolean bfd_arm_update_notes
+ (bfd *, const char *);
+
+extern unsigned int bfd_arm_get_mach_from_notes
+ (bfd *, const char *);
+
+/* ARM stub generation support. Called from the linker. */
+extern int elf32_arm_setup_section_lists
+ (bfd *, struct bfd_link_info *);
+extern void elf32_arm_next_input_section
+ (struct bfd_link_info *, struct bfd_section *);
+extern bfd_boolean elf32_arm_size_stubs
+ (bfd *, bfd *, struct bfd_link_info *, bfd_signed_vma,
+ struct bfd_section * (*) (const char *, struct bfd_section *, unsigned int),
+ void (*) (void));
+extern bfd_boolean elf32_arm_build_stubs
+ (struct bfd_link_info *);
+
+/* ARM unwind section editing support. */
+extern bfd_boolean elf32_arm_fix_exidx_coverage
+(struct bfd_section **, unsigned int, struct bfd_link_info *, bfd_boolean);
+
+/* C6x unwind section editing support. */
+extern bfd_boolean elf32_tic6x_fix_exidx_coverage
+(struct bfd_section **, unsigned int, struct bfd_link_info *, bfd_boolean);
+
+/* PowerPC @tls opcode transform/validate. */
+extern unsigned int _bfd_elf_ppc_at_tls_transform
+ (unsigned int, unsigned int);
+/* PowerPC @tprel opcode transform/validate. */
+extern unsigned int _bfd_elf_ppc_at_tprel_transform
+ (unsigned int, unsigned int);
+
+extern void bfd_elf64_aarch64_init_maps
+ (bfd *);
+
+extern void bfd_elf32_aarch64_init_maps
+ (bfd *);
+
+extern void bfd_elf64_aarch64_set_options
+ (bfd *, struct bfd_link_info *, int, int, int, int);
+
+extern void bfd_elf32_aarch64_set_options
+ (bfd *, struct bfd_link_info *, int, int, int, int);
+
+/* ELF AArch64 mapping symbol support. */
+#define BFD_AARCH64_SPECIAL_SYM_TYPE_MAP (1 << 0)
+#define BFD_AARCH64_SPECIAL_SYM_TYPE_TAG (1 << 1)
+#define BFD_AARCH64_SPECIAL_SYM_TYPE_OTHER (1 << 2)
+#define BFD_AARCH64_SPECIAL_SYM_TYPE_ANY (~0)
+extern bfd_boolean bfd_is_aarch64_special_symbol_name
+ (const char * name, int type);
+
+/* AArch64 stub generation support for ELF64. Called from the linker. */
+extern int elf64_aarch64_setup_section_lists
+ (bfd *, struct bfd_link_info *);
+extern void elf64_aarch64_next_input_section
+ (struct bfd_link_info *, struct bfd_section *);
+extern bfd_boolean elf64_aarch64_size_stubs
+ (bfd *, bfd *, struct bfd_link_info *, bfd_signed_vma,
+ struct bfd_section * (*) (const char *, struct bfd_section *),
+ void (*) (void));
+extern bfd_boolean elf64_aarch64_build_stubs
+ (struct bfd_link_info *);
+/* AArch64 stub generation support for ELF32. Called from the linker. */
+extern int elf32_aarch64_setup_section_lists
+ (bfd *, struct bfd_link_info *);
+extern void elf32_aarch64_next_input_section
+ (struct bfd_link_info *, struct bfd_section *);
+extern bfd_boolean elf32_aarch64_size_stubs
+ (bfd *, bfd *, struct bfd_link_info *, bfd_signed_vma,
+ struct bfd_section * (*) (const char *, struct bfd_section *),
+ void (*) (void));
+extern bfd_boolean elf32_aarch64_build_stubs
+ (struct bfd_link_info *);
+
+
+/* TI COFF load page support. */
+extern void bfd_ticoff_set_section_load_page
+ (struct bfd_section *, int);
+
+extern int bfd_ticoff_get_section_load_page
+ (struct bfd_section *);
+
+/* H8/300 functions. */
+extern bfd_vma bfd_h8300_pad_address
+ (bfd *, bfd_vma);
+
+/* IA64 Itanium code generation. Called from linker. */
+extern void bfd_elf32_ia64_after_parse
+ (int);
+
+extern void bfd_elf64_ia64_after_parse
+ (int);
+
+/* This structure is used for a comdat section, as in PE. A comdat
+ section is associated with a particular symbol. When the linker
+ sees a comdat section, it keeps only one of the sections with a
+ given name and associated with a given symbol. */
+
+struct coff_comdat_info
+{
+ /* The name of the symbol associated with a comdat section. */
+ const char *name;
+
+ /* The local symbol table index of the symbol associated with a
+ comdat section. This is only meaningful to the object file format
+ specific code; it is not an index into the list returned by
+ bfd_canonicalize_symtab. */
+ long symbol;
+};
+
+extern struct coff_comdat_info * bfd_coff_get_comdat_section
+ (bfd *, struct bfd_section *);
+/* Extracted from init.c. */
+void bfd_init (void);
+
+/* Extracted from opncls.c. */
+/* Set to N to open the next N BFDs using an alternate id space. */
+extern unsigned int bfd_use_reserved_id;
+bfd *bfd_fopen (const char *filename, const char *target,
+ const char *mode, int fd);
+
+bfd *bfd_openr (const char *filename, const char *target);
+
+bfd *bfd_fdopenr (const char *filename, const char *target, int fd);
+
+bfd *bfd_openstreamr (const char * filename, const char * target, void * stream);
+
+bfd *bfd_openr_iovec (const char *filename, const char *target,
+ void *(*open_func) (struct bfd *nbfd,
+ void *open_closure),
+ void *open_closure,
+ file_ptr (*pread_func) (struct bfd *nbfd,
+ void *stream,
+ void *buf,
+ file_ptr nbytes,
+ file_ptr offset),
+ int (*close_func) (struct bfd *nbfd,
+ void *stream),
+ int (*stat_func) (struct bfd *abfd,
+ void *stream,
+ struct stat *sb));
+
+bfd *bfd_openw (const char *filename, const char *target);
+
+bfd_boolean bfd_close (bfd *abfd);
+
+bfd_boolean bfd_close_all_done (bfd *);
+
+bfd *bfd_create (const char *filename, bfd *templ);
+
+bfd_boolean bfd_make_writable (bfd *abfd);
+
+bfd_boolean bfd_make_readable (bfd *abfd);
+
+void *bfd_alloc (bfd *abfd, bfd_size_type wanted);
+
+void *bfd_zalloc (bfd *abfd, bfd_size_type wanted);
+
+unsigned long bfd_calc_gnu_debuglink_crc32
+ (unsigned long crc, const unsigned char *buf, bfd_size_type len);
+
+char *bfd_get_debug_link_info (bfd *abfd, unsigned long *crc32_out);
+
+char *bfd_get_alt_debug_link_info (bfd * abfd,
+ bfd_size_type *buildid_len,
+ bfd_byte **buildid_out);
+
+char *bfd_follow_gnu_debuglink (bfd *abfd, const char *dir);
+
+char *bfd_follow_gnu_debugaltlink (bfd *abfd, const char *dir);
+
+struct bfd_section *bfd_create_gnu_debuglink_section
+ (bfd *abfd, const char *filename);
+
+bfd_boolean bfd_fill_in_gnu_debuglink_section
+ (bfd *abfd, struct bfd_section *sect, const char *filename);
+
+/* Extracted from libbfd.c. */
+
+/* Byte swapping macros for user section data. */
+
+#define bfd_put_8(abfd, val, ptr) \
+ ((void) (*((unsigned char *) (ptr)) = (val) & 0xff))
+#define bfd_put_signed_8 \
+ bfd_put_8
+#define bfd_get_8(abfd, ptr) \
+ (*(const unsigned char *) (ptr) & 0xff)
+#define bfd_get_signed_8(abfd, ptr) \
+ (((*(const unsigned char *) (ptr) & 0xff) ^ 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))
+
+#define bfd_get(bits, abfd, ptr) \
+ ((bits) == 8 ? (bfd_vma) bfd_get_8 (abfd, ptr) \
+ : (bits) == 16 ? bfd_get_16 (abfd, ptr) \
+ : (bits) == 32 ? bfd_get_32 (abfd, ptr) \
+ : (bits) == 64 ? bfd_get_64 (abfd, ptr) \
+ : (abort (), (bfd_vma) - 1))
+
+#define bfd_put(bits, abfd, val, ptr) \
+ ((bits) == 8 ? bfd_put_8 (abfd, val, ptr) \
+ : (bits) == 16 ? bfd_put_16 (abfd, val, ptr) \
+ : (bits) == 32 ? bfd_put_32 (abfd, val, ptr) \
+ : (bits) == 64 ? bfd_put_64 (abfd, val, ptr) \
+ : (abort (), (void) 0))
+
+
+/* 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))
+
+/* Aliases for the above, which should eventually go away. */
+
+#define H_PUT_64 bfd_h_put_64
+#define H_PUT_32 bfd_h_put_32
+#define H_PUT_16 bfd_h_put_16
+#define H_PUT_8 bfd_h_put_8
+#define H_PUT_S64 bfd_h_put_signed_64
+#define H_PUT_S32 bfd_h_put_signed_32
+#define H_PUT_S16 bfd_h_put_signed_16
+#define H_PUT_S8 bfd_h_put_signed_8
+#define H_GET_64 bfd_h_get_64
+#define H_GET_32 bfd_h_get_32
+#define H_GET_16 bfd_h_get_16
+#define H_GET_8 bfd_h_get_8
+#define H_GET_S64 bfd_h_get_signed_64
+#define H_GET_S32 bfd_h_get_signed_32
+#define H_GET_S16 bfd_h_get_signed_16
+#define H_GET_S8 bfd_h_get_signed_8
+
+
+/* Extracted from bfdio.c. */
+long bfd_get_mtime (bfd *abfd);
+
+file_ptr bfd_get_size (bfd *abfd);
+
+void *bfd_mmap (bfd *abfd, void *addr, bfd_size_type len,
+ int prot, int flags, file_ptr offset,
+ void **map_addr, bfd_size_type *map_len);
+
+/* Extracted from bfdwin.c. */
+/* Extracted from section.c. */
+
+typedef struct bfd_section
+{
+ /* 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;
+
+ /* A unique sequence number. */
+ int id;
+
+ /* Which section in the bfd; 0..n-1 as sections are created in a bfd. */
+ int index;
+
+ /* The next section in the list belonging to the BFD, or NULL. */
+ struct bfd_section *next;
+
+ /* The previous section in the list belonging to the BFD, or NULL. */
+ struct bfd_section *prev;
+
+ /* 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
+
+ /* A signal to the OS that the section contains read only data. */
+#define SEC_READONLY 0x008
+
+ /* The section contains code only. */
+#define SEC_CODE 0x010
+
+ /* The section contains data only. */
+#define SEC_DATA 0x020
+
+ /* The section will reside in ROM. */
+#define SEC_ROM 0x040
+
+ /* 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 0x080
+
+ /* 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 0x100
+
+ /* An instruction to the linker to not output the section
+ even if it has information which would normally be written. */
+#define SEC_NEVER_LOAD 0x200
+
+ /* The section contains thread local data. */
+#define SEC_THREAD_LOCAL 0x400
+
+ /* The section has GOT references. This flag is only for the
+ linker, and is currently only used by the elf32-hppa back end.
+ It will be set if global offset table references were detected
+ in this section, which indicate to the linker that the section
+ contains PIC code, and must be handled specially when doing a
+ static link. */
+#define SEC_HAS_GOT_REF 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 0x1000
+
+ /* 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 0x2000
+
+ /* 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 0x4000
+
+ /* 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 0x8000
+
+ /* The contents of this section are to be sorted based on the sum of
+ the symbol and addend values specified by the associated relocation
+ entries. Entries without associated relocation entries will be
+ appended to the end of the section in an unspecified order. */
+#define SEC_SORT_ENTRIES 0x10000
+
+ /* 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 0x20000
+
+ /* If SEC_LINK_ONCE is set, this bitfield describes how the linker
+ should handle duplicate sections. */
+#define SEC_LINK_DUPLICATES 0xc0000
+
+ /* 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 0x40000
+
+ /* 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 0x80000
+
+ /* 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 \
+ (SEC_LINK_DUPLICATES_ONE_ONLY | SEC_LINK_DUPLICATES_SAME_SIZE)
+
+ /* 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 0x100000
+
+ /* This section should not be subject to garbage collection.
+ Also set to inform the linker that this section should not be
+ listed in the link map as discarded. */
+#define SEC_KEEP 0x200000
+
+ /* This section contains "short" data, and should be placed
+ "near" the GP. */
+#define SEC_SMALL_DATA 0x400000
+
+ /* Attempt to merge identical entities in the section.
+ Entity size is given in the entsize field. */
+#define SEC_MERGE 0x800000
+
+ /* If given with SEC_MERGE, entities to merge are zero terminated
+ strings where entsize specifies character size instead of fixed
+ size entries. */
+#define SEC_STRINGS 0x1000000
+
+ /* This section contains data about section groups. */
+#define SEC_GROUP 0x2000000
+
+ /* 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 0x4000000
+
+ /* This input section should be copied to output in reverse order
+ as an array of pointers. This is for ELF linker internal use
+ only. */
+#define SEC_ELF_REVERSE_COPY 0x4000000
+
+ /* This section contains data which may be shared with other
+ executables or shared objects. This is for COFF only. */
+#define SEC_COFF_SHARED 0x8000000
+
+ /* When a section with this flag is being linked, then if the size of
+ the input section is less than a page, it should not cross a page
+ boundary. If the size of the input section is one page or more,
+ it should be aligned on a page boundary. This is for TI
+ TMS320C54X only. */
+#define SEC_TIC54X_BLOCK 0x10000000
+
+ /* Conditionally link this section; do not link if there are no
+ references found to any symbol in the section. This is for TI
+ TMS320C54X only. */
+#define SEC_TIC54X_CLINK 0x20000000
+
+ /* Indicate that section has the no read flag set. This happens
+ when memory read flag isn't set. */
+#define SEC_COFF_NOREAD 0x40000000
+
+ /* End of section flags. */
+
+ /* Some internal packed boolean fields. */
+
+ /* See the vma field. */
+ unsigned int user_set_vma : 1;
+
+ /* A mark flag used by some of the linker backends. */
+ unsigned int linker_mark : 1;
+
+ /* Another mark flag used by some of the linker backends. Set for
+ output sections that have an input section. */
+ unsigned int linker_has_input : 1;
+
+ /* Mark flag used by some linker backends for garbage collection. */
+ unsigned int gc_mark : 1;
+
+ /* Section compression status. */
+ unsigned int compress_status : 2;
+#define COMPRESS_SECTION_NONE 0
+#define COMPRESS_SECTION_DONE 1
+#define DECOMPRESS_SECTION_SIZED 2
+
+ /* The following flags are used by the ELF linker. */
+
+ /* Mark sections which have been allocated to segments. */
+ unsigned int segment_mark : 1;
+
+ /* Type of sec_info information. */
+ unsigned int sec_info_type:3;
+#define SEC_INFO_TYPE_NONE 0
+#define SEC_INFO_TYPE_STABS 1
+#define SEC_INFO_TYPE_MERGE 2
+#define SEC_INFO_TYPE_EH_FRAME 3
+#define SEC_INFO_TYPE_JUST_SYMS 4
+#define SEC_INFO_TYPE_TARGET 5
+
+ /* Nonzero if this section uses RELA relocations, rather than REL. */
+ unsigned int use_rela_p:1;
+
+ /* Bits used by various backends. The generic code doesn't touch
+ these fields. */
+
+ unsigned int sec_flg0:1;
+ unsigned int sec_flg1:1;
+ unsigned int sec_flg2:1;
+ unsigned int sec_flg3:1;
+ unsigned int sec_flg4:1;
+ unsigned int sec_flg5: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 octets, as it will be output.
+ Contains a value even if the section has no contents (e.g., the
+ size of <<.bss>>). */
+ bfd_size_type size;
+
+ /* For input sections, the original size on disk of the section, in
+ octets. This field should be set for any section whose size is
+ changed by linker relaxation. It is required for sections where
+ the linker relaxation scheme doesn't cache altered section and
+ reloc contents (stabs, eh_frame, SEC_MERGE, some coff relaxing
+ targets), and thus the original size needs to be kept to read the
+ section multiple times. For output sections, rawsize holds the
+ section size calculated on a previous linker relaxation pass. */
+ bfd_size_type rawsize;
+
+ /* The compressed size of the section in octets. */
+ bfd_size_type compressed_size;
+
+ /* Relaxation table. */
+ struct relax_table *relax;
+
+ /* Count of used relaxation table entries. */
+ int relax_count;
+
+
+ /* If this section is going to be output, then this value is the
+ offset in *bytes* into the output section of the first byte in the
+ input section (byte ==> smallest addressable unit on the
+ target). In most cases, if this was going to start at the
+ 100th octet (8-bit quantity) in the output section, this value
+ would be 100. However, if the target byte size is 16 bits
+ (bfd_octets_per_byte is "2"), this value would be 50. */
+ bfd_vma output_offset;
+
+ /* The output section through which to map on output. */
+ struct bfd_section *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. */
+ void *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;
+
+ /* Entity size for merging purposes. */
+ unsigned int entsize;
+
+ /* Points to the kept section if this section is a link-once section,
+ and is discarded. */
+ struct bfd_section *kept_section;
+
+ /* 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;
+
+ void *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 bfd_symbol *symbol;
+ struct bfd_symbol **symbol_ptr_ptr;
+
+ /* Early in the link process, map_head and map_tail are used to build
+ a list of input sections attached to an output section. Later,
+ output sections use these fields for a list of bfd_link_order
+ structs. */
+ union {
+ struct bfd_link_order *link_order;
+ struct bfd_section *s;
+ } map_head, map_tail;
+} asection;
+
+/* Relax table contains information about instructions which can
+ be removed by relaxation -- replacing a long address with a
+ short address. */
+struct relax_table {
+ /* Address where bytes may be deleted. */
+ bfd_vma addr;
+
+ /* Number of bytes to be deleted. */
+ int size;
+};
+
+/* Note: the following are provided as inline functions rather than macros
+ because not all callers use the return value. A macro implementation
+ would use a comma expression, eg: "((ptr)->foo = val, TRUE)" and some
+ compilers will complain about comma expressions that have no effect. */
+static inline bfd_boolean
+bfd_set_section_userdata (bfd * abfd ATTRIBUTE_UNUSED, asection * ptr, void * val)
+{
+ ptr->userdata = val;
+ return TRUE;
+}
+
+static inline bfd_boolean
+bfd_set_section_vma (bfd * abfd ATTRIBUTE_UNUSED, asection * ptr, bfd_vma val)
+{
+ ptr->vma = ptr->lma = val;
+ ptr->user_set_vma = TRUE;
+ return TRUE;
+}
+
+static inline bfd_boolean
+bfd_set_section_alignment (bfd * abfd ATTRIBUTE_UNUSED, asection * ptr, unsigned int val)
+{
+ ptr->alignment_power = val;
+ return TRUE;
+}
+
+/* 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. */
+extern asection _bfd_std_section[4];
+
+#define BFD_ABS_SECTION_NAME "*ABS*"
+#define BFD_UND_SECTION_NAME "*UND*"
+#define BFD_COM_SECTION_NAME "*COM*"
+#define BFD_IND_SECTION_NAME "*IND*"
+
+/* Pointer to the common section. */
+#define bfd_com_section_ptr (&_bfd_std_section[0])
+/* Pointer to the undefined section. */
+#define bfd_und_section_ptr (&_bfd_std_section[1])
+/* Pointer to the absolute section. */
+#define bfd_abs_section_ptr (&_bfd_std_section[2])
+/* Pointer to the indirect section. */
+#define bfd_ind_section_ptr (&_bfd_std_section[3])
+
+#define bfd_is_und_section(sec) ((sec) == bfd_und_section_ptr)
+#define bfd_is_abs_section(sec) ((sec) == bfd_abs_section_ptr)
+#define bfd_is_ind_section(sec) ((sec) == bfd_ind_section_ptr)
+
+#define bfd_is_const_section(SEC) \
+ ( ((SEC) == bfd_abs_section_ptr) \
+ || ((SEC) == bfd_und_section_ptr) \
+ || ((SEC) == bfd_com_section_ptr) \
+ || ((SEC) == bfd_ind_section_ptr))
+
+/* Macros to handle insertion and deletion of a bfd's sections. These
+ only handle the list pointers, ie. do not adjust section_count,
+ target_index etc. */
+#define bfd_section_list_remove(ABFD, S) \
+ do \
+ { \
+ asection *_s = S; \
+ asection *_next = _s->next; \
+ asection *_prev = _s->prev; \
+ if (_prev) \
+ _prev->next = _next; \
+ else \
+ (ABFD)->sections = _next; \
+ if (_next) \
+ _next->prev = _prev; \
+ else \
+ (ABFD)->section_last = _prev; \
+ } \
+ while (0)
+#define bfd_section_list_append(ABFD, S) \
+ do \
+ { \
+ asection *_s = S; \
+ bfd *_abfd = ABFD; \
+ _s->next = NULL; \
+ if (_abfd->section_last) \
+ { \
+ _s->prev = _abfd->section_last; \
+ _abfd->section_last->next = _s; \
+ } \
+ else \
+ { \
+ _s->prev = NULL; \
+ _abfd->sections = _s; \
+ } \
+ _abfd->section_last = _s; \
+ } \
+ while (0)
+#define bfd_section_list_prepend(ABFD, S) \
+ do \
+ { \
+ asection *_s = S; \
+ bfd *_abfd = ABFD; \
+ _s->prev = NULL; \
+ if (_abfd->sections) \
+ { \
+ _s->next = _abfd->sections; \
+ _abfd->sections->prev = _s; \
+ } \
+ else \
+ { \
+ _s->next = NULL; \
+ _abfd->section_last = _s; \
+ } \
+ _abfd->sections = _s; \
+ } \
+ while (0)
+#define bfd_section_list_insert_after(ABFD, A, S) \
+ do \
+ { \
+ asection *_a = A; \
+ asection *_s = S; \
+ asection *_next = _a->next; \
+ _s->next = _next; \
+ _s->prev = _a; \
+ _a->next = _s; \
+ if (_next) \
+ _next->prev = _s; \
+ else \
+ (ABFD)->section_last = _s; \
+ } \
+ while (0)
+#define bfd_section_list_insert_before(ABFD, B, S) \
+ do \
+ { \
+ asection *_b = B; \
+ asection *_s = S; \
+ asection *_prev = _b->prev; \
+ _s->prev = _prev; \
+ _s->next = _b; \
+ _b->prev = _s; \
+ if (_prev) \
+ _prev->next = _s; \
+ else \
+ (ABFD)->sections = _s; \
+ } \
+ while (0)
+#define bfd_section_removed_from_list(ABFD, S) \
+ ((S)->next == NULL ? (ABFD)->section_last != (S) : (S)->next->prev != (S))
+
+#define BFD_FAKE_SECTION(SEC, FLAGS, SYM, NAME, IDX) \
+ /* name, id, index, next, prev, flags, user_set_vma, */ \
+ { NAME, IDX, 0, NULL, NULL, FLAGS, 0, \
+ \
+ /* linker_mark, linker_has_input, gc_mark, decompress_status, */ \
+ 0, 0, 1, 0, \
+ \
+ /* segment_mark, sec_info_type, use_rela_p, */ \
+ 0, 0, 0, \
+ \
+ /* sec_flg0, sec_flg1, sec_flg2, sec_flg3, sec_flg4, sec_flg5, */ \
+ 0, 0, 0, 0, 0, 0, \
+ \
+ /* vma, lma, size, rawsize, compressed_size, relax, relax_count, */ \
+ 0, 0, 0, 0, 0, 0, 0, \
+ \
+ /* output_offset, output_section, alignment_power, */ \
+ 0, &SEC, 0, \
+ \
+ /* relocation, orelocation, reloc_count, filepos, rel_filepos, */ \
+ NULL, NULL, 0, 0, 0, \
+ \
+ /* line_filepos, userdata, contents, lineno, lineno_count, */ \
+ 0, NULL, NULL, NULL, 0, \
+ \
+ /* entsize, kept_section, moving_line_filepos, */ \
+ 0, NULL, 0, \
+ \
+ /* target_index, used_by_bfd, constructor_chain, owner, */ \
+ 0, NULL, NULL, NULL, \
+ \
+ /* symbol, symbol_ptr_ptr, */ \
+ (struct bfd_symbol *) SYM, &SEC.symbol, \
+ \
+ /* map_head, map_tail */ \
+ { NULL }, { NULL } \
+ }
+
+void bfd_section_list_clear (bfd *);
+
+asection *bfd_get_section_by_name (bfd *abfd, const char *name);
+
+asection *bfd_get_next_section_by_name (asection *sec);
+
+asection *bfd_get_linker_section (bfd *abfd, const char *name);
+
+asection *bfd_get_section_by_name_if
+ (bfd *abfd,
+ const char *name,
+ bfd_boolean (*func) (bfd *abfd, asection *sect, void *obj),
+ void *obj);
+
+char *bfd_get_unique_section_name
+ (bfd *abfd, const char *templat, int *count);
+
+asection *bfd_make_section_old_way (bfd *abfd, const char *name);
+
+asection *bfd_make_section_anyway_with_flags
+ (bfd *abfd, const char *name, flagword flags);
+
+asection *bfd_make_section_anyway (bfd *abfd, const char *name);
+
+asection *bfd_make_section_with_flags
+ (bfd *, const char *name, flagword flags);
+
+asection *bfd_make_section (bfd *, const char *name);
+
+bfd_boolean bfd_set_section_flags
+ (bfd *abfd, asection *sec, flagword flags);
+
+void bfd_rename_section
+ (bfd *abfd, asection *sec, const char *newname);
+
+void bfd_map_over_sections
+ (bfd *abfd,
+ void (*func) (bfd *abfd, asection *sect, void *obj),
+ void *obj);
+
+asection *bfd_sections_find_if
+ (bfd *abfd,
+ bfd_boolean (*operation) (bfd *abfd, asection *sect, void *obj),
+ void *obj);
+
+bfd_boolean bfd_set_section_size
+ (bfd *abfd, asection *sec, bfd_size_type val);
+
+bfd_boolean bfd_set_section_contents
+ (bfd *abfd, asection *section, const void *data,
+ file_ptr offset, bfd_size_type count);
+
+bfd_boolean bfd_get_section_contents
+ (bfd *abfd, asection *section, void *location, file_ptr offset,
+ bfd_size_type count);
+
+bfd_boolean bfd_malloc_and_get_section
+ (bfd *abfd, asection *section, bfd_byte **buf);
+
+bfd_boolean bfd_copy_private_section_data
+ (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))
+bfd_boolean bfd_generic_is_group_section (bfd *, const asection *sec);
+
+bfd_boolean bfd_generic_discard_group (bfd *abfd, asection *group);
+
+/* Extracted from archures.c. */
+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
+#define bfd_mach_fido 9
+#define bfd_mach_mcf_isa_a_nodiv 10
+#define bfd_mach_mcf_isa_a 11
+#define bfd_mach_mcf_isa_a_mac 12
+#define bfd_mach_mcf_isa_a_emac 13
+#define bfd_mach_mcf_isa_aplus 14
+#define bfd_mach_mcf_isa_aplus_mac 15
+#define bfd_mach_mcf_isa_aplus_emac 16
+#define bfd_mach_mcf_isa_b_nousp 17
+#define bfd_mach_mcf_isa_b_nousp_mac 18
+#define bfd_mach_mcf_isa_b_nousp_emac 19
+#define bfd_mach_mcf_isa_b 20
+#define bfd_mach_mcf_isa_b_mac 21
+#define bfd_mach_mcf_isa_b_emac 22
+#define bfd_mach_mcf_isa_b_float 23
+#define bfd_mach_mcf_isa_b_float_mac 24
+#define bfd_mach_mcf_isa_b_float_emac 25
+#define bfd_mach_mcf_isa_c 26
+#define bfd_mach_mcf_isa_c_mac 27
+#define bfd_mach_mcf_isa_c_emac 28
+#define bfd_mach_mcf_isa_c_nodiv 29
+#define bfd_mach_mcf_isa_c_nodiv_mac 30
+#define bfd_mach_mcf_isa_c_nodiv_emac 31
+ 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_or1k, /* OpenRISC 1000 */
+#define bfd_mach_or1k 1
+#define bfd_mach_or1knd 2
+
+ 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. */
+#define bfd_mach_sparc_v8plusb 9 /* with cheetah add'ns. */
+#define bfd_mach_sparc_v9b 10 /* with cheetah 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_v9b \
+ && (mach) != bfd_mach_sparc_sparclite_le)
+/* Nonzero if MACH is a 64 bit sparc architecture. */
+#define bfd_mach_sparc_64bit_p(mach) \
+ ((mach) >= bfd_mach_sparc_v9 && (mach) != bfd_mach_sparc_v8plusb)
+ bfd_arch_spu, /* PowerPC SPU */
+#define bfd_mach_spu 256
+ 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_mips4120 4120
+#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_mips5400 5400
+#define bfd_mach_mips5500 5500
+#define bfd_mach_mips5900 5900
+#define bfd_mach_mips6000 6000
+#define bfd_mach_mips7000 7000
+#define bfd_mach_mips8000 8000
+#define bfd_mach_mips9000 9000
+#define bfd_mach_mips10000 10000
+#define bfd_mach_mips12000 12000
+#define bfd_mach_mips14000 14000
+#define bfd_mach_mips16000 16000
+#define bfd_mach_mips16 16
+#define bfd_mach_mips5 5
+#define bfd_mach_mips_loongson_2e 3001
+#define bfd_mach_mips_loongson_2f 3002
+#define bfd_mach_mips_loongson_3a 3003
+#define bfd_mach_mips_sb1 12310201 /* octal 'SB', 01 */
+#define bfd_mach_mips_octeon 6501
+#define bfd_mach_mips_octeonp 6601
+#define bfd_mach_mips_octeon2 6502
+#define bfd_mach_mips_xlr 887682 /* decimal 'XLR' */
+#define bfd_mach_mipsisa32 32
+#define bfd_mach_mipsisa32r2 33
+#define bfd_mach_mipsisa32r3 34
+#define bfd_mach_mipsisa32r5 36
+#define bfd_mach_mipsisa32r6 37
+#define bfd_mach_mipsisa64 64
+#define bfd_mach_mipsisa64r2 65
+#define bfd_mach_mipsisa64r3 66
+#define bfd_mach_mipsisa64r5 68
+#define bfd_mach_mipsisa64r6 69
+#define bfd_mach_mips_micromips 96
+ bfd_arch_i386, /* Intel 386 */
+#define bfd_mach_i386_intel_syntax (1 << 0)
+#define bfd_mach_i386_i8086 (1 << 1)
+#define bfd_mach_i386_i386 (1 << 2)
+#define bfd_mach_x86_64 (1 << 3)
+#define bfd_mach_x64_32 (1 << 4)
+#define bfd_mach_i386_i386_intel_syntax (bfd_mach_i386_i386 | bfd_mach_i386_intel_syntax)
+#define bfd_mach_x86_64_intel_syntax (bfd_mach_x86_64 | bfd_mach_i386_intel_syntax)
+#define bfd_mach_x64_32_intel_syntax (bfd_mach_x64_32 | bfd_mach_i386_intel_syntax)
+ bfd_arch_l1om, /* Intel L1OM */
+#define bfd_mach_l1om (1 << 5)
+#define bfd_mach_l1om_intel_syntax (bfd_mach_l1om | bfd_mach_i386_intel_syntax)
+ bfd_arch_k1om, /* Intel K1OM */
+#define bfd_mach_k1om (1 << 6)
+#define bfd_mach_k1om_intel_syntax (bfd_mach_k1om | bfd_mach_i386_intel_syntax)
+#define bfd_mach_i386_nacl (1 << 7)
+#define bfd_mach_i386_i386_nacl (bfd_mach_i386_i386 | bfd_mach_i386_nacl)
+#define bfd_mach_x86_64_nacl (bfd_mach_x86_64 | bfd_mach_i386_nacl)
+#define bfd_mach_x64_32_nacl (bfd_mach_x64_32 | bfd_mach_i386_nacl)
+ bfd_arch_we32k, /* AT&T WE32xxx */
+ bfd_arch_tahoe, /* CCI/Harris Tahoe */
+ bfd_arch_i860, /* Intel 860 */
+ bfd_arch_i370, /* IBM 360/370 Mainframes */
+ bfd_arch_romp, /* IBM ROMP PC/RT */
+ bfd_arch_convex, /* Convex */
+ bfd_arch_m88k, /* Motorola 88xxx */
+ bfd_arch_m98k, /* Motorola 98xxx */
+ bfd_arch_pyramid, /* Pyramid Technology */
+ bfd_arch_h8300, /* Renesas H8/300 (formerly Hitachi H8/300) */
+#define bfd_mach_h8300 1
+#define bfd_mach_h8300h 2
+#define bfd_mach_h8300s 3
+#define bfd_mach_h8300hn 4
+#define bfd_mach_h8300sn 5
+#define bfd_mach_h8300sx 6
+#define bfd_mach_h8300sxn 7
+ bfd_arch_pdp11, /* DEC PDP-11 */
+ bfd_arch_plugin,
+ bfd_arch_powerpc, /* PowerPC */
+#define bfd_mach_ppc 32
+#define bfd_mach_ppc64 64
+#define bfd_mach_ppc_403 403
+#define bfd_mach_ppc_403gc 4030
+#define bfd_mach_ppc_405 405
+#define bfd_mach_ppc_505 505
+#define bfd_mach_ppc_601 601
+#define bfd_mach_ppc_602 602
+#define bfd_mach_ppc_603 603
+#define bfd_mach_ppc_ec603e 6031
+#define bfd_mach_ppc_604 604
+#define bfd_mach_ppc_620 620
+#define bfd_mach_ppc_630 630
+#define bfd_mach_ppc_750 750
+#define bfd_mach_ppc_860 860
+#define bfd_mach_ppc_a35 35
+#define bfd_mach_ppc_rs64ii 642
+#define bfd_mach_ppc_rs64iii 643
+#define bfd_mach_ppc_7400 7400
+#define bfd_mach_ppc_e500 500
+#define bfd_mach_ppc_e500mc 5001
+#define bfd_mach_ppc_e500mc64 5005
+#define bfd_mach_ppc_e5500 5006
+#define bfd_mach_ppc_e6500 5007
+#define bfd_mach_ppc_titan 83
+#define bfd_mach_ppc_vle 84
+ bfd_arch_rs6000, /* IBM RS/6000 */
+#define bfd_mach_rs6k 6000
+#define bfd_mach_rs6k_rs1 6001
+#define bfd_mach_rs6k_rsc 6003
+#define bfd_mach_rs6k_rs2 6002
+ bfd_arch_hppa, /* HP PA RISC */
+#define bfd_mach_hppa10 10
+#define bfd_mach_hppa11 11
+#define bfd_mach_hppa20 20
+#define bfd_mach_hppa20w 25
+ bfd_arch_d10v, /* Mitsubishi D10V */
+#define bfd_mach_d10v 1
+#define bfd_mach_d10v_ts2 2
+#define bfd_mach_d10v_ts3 3
+ bfd_arch_d30v, /* Mitsubishi D30V */
+ bfd_arch_dlx, /* DLX */
+ bfd_arch_m68hc11, /* Motorola 68HC11 */
+ bfd_arch_m68hc12, /* Motorola 68HC12 */
+#define bfd_mach_m6812_default 0
+#define bfd_mach_m6812 1
+#define bfd_mach_m6812s 2
+ bfd_arch_m9s12x, /* Freescale S12X */
+ bfd_arch_m9s12xg, /* Freescale XGATE */
+ bfd_arch_z8k, /* Zilog Z8000 */
+#define bfd_mach_z8001 1
+#define bfd_mach_z8002 2
+ bfd_arch_h8500, /* Renesas H8/500 (formerly Hitachi H8/500) */
+ bfd_arch_sh, /* Renesas / SuperH SH (formerly Hitachi SH) */
+#define bfd_mach_sh 1
+#define bfd_mach_sh2 0x20
+#define bfd_mach_sh_dsp 0x2d
+#define bfd_mach_sh2a 0x2a
+#define bfd_mach_sh2a_nofpu 0x2b
+#define bfd_mach_sh2a_nofpu_or_sh4_nommu_nofpu 0x2a1
+#define bfd_mach_sh2a_nofpu_or_sh3_nommu 0x2a2
+#define bfd_mach_sh2a_or_sh4 0x2a3
+#define bfd_mach_sh2a_or_sh3e 0x2a4
+#define bfd_mach_sh2e 0x2e
+#define bfd_mach_sh3 0x30
+#define bfd_mach_sh3_nommu 0x31
+#define bfd_mach_sh3_dsp 0x3d
+#define bfd_mach_sh3e 0x3e
+#define bfd_mach_sh4 0x40
+#define bfd_mach_sh4_nofpu 0x41
+#define bfd_mach_sh4_nommu_nofpu 0x42
+#define bfd_mach_sh4a 0x4a
+#define bfd_mach_sh4a_nofpu 0x4b
+#define bfd_mach_sh4al_dsp 0x4d
+#define bfd_mach_sh5 0x50
+ 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_unknown 0
+#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
+#define bfd_mach_arm_5 7
+#define bfd_mach_arm_5T 8
+#define bfd_mach_arm_5TE 9
+#define bfd_mach_arm_XScale 10
+#define bfd_mach_arm_ep9312 11
+#define bfd_mach_arm_iWMMXt 12
+#define bfd_mach_arm_iWMMXt2 13
+ bfd_arch_nds32, /* Andes NDS32 */
+#define bfd_mach_n1 1
+#define bfd_mach_n1h 2
+#define bfd_mach_n1h_v2 3
+#define bfd_mach_n1h_v3 4
+#define bfd_mach_n1h_v3m 5
+ bfd_arch_ns32k, /* National Semiconductors ns32000 */
+ bfd_arch_w65, /* WDC 65816 */
+ bfd_arch_tic30, /* Texas Instruments TMS320C30 */
+ bfd_arch_tic4x, /* Texas Instruments TMS320C3X/4X */
+#define bfd_mach_tic3x 30
+#define bfd_mach_tic4x 40
+ bfd_arch_tic54x, /* Texas Instruments TMS320C54X */
+ bfd_arch_tic6x, /* Texas Instruments TMS320C6X */
+ bfd_arch_tic80, /* TI TMS320c80 (MVP) */
+ bfd_arch_v850, /* NEC V850 */
+ bfd_arch_v850_rh850,/* NEC V850 (using RH850 ABI) */
+#define bfd_mach_v850 1
+#define bfd_mach_v850e 'E'
+#define bfd_mach_v850e1 '1'
+#define bfd_mach_v850e2 0x4532
+#define bfd_mach_v850e2v3 0x45325633
+#define bfd_mach_v850e3v5 0x45335635 /* ('E'|'3'|'V'|'5') */
+ bfd_arch_arc, /* ARC Cores */
+#define bfd_mach_arc_5 5
+#define bfd_mach_arc_6 6
+#define bfd_mach_arc_7 7
+#define bfd_mach_arc_8 8
+ bfd_arch_m32c, /* Renesas M16C/M32C. */
+#define bfd_mach_m16c 0x75
+#define bfd_mach_m32c 0x78
+ bfd_arch_m32r, /* Renesas M32R (formerly Mitsubishi M32R/D) */
+#define bfd_mach_m32r 1 /* For backwards compatibility. */
+#define bfd_mach_m32rx 'x'
+#define bfd_mach_m32r2 '2'
+ bfd_arch_mn10200, /* Matsushita MN10200 */
+ bfd_arch_mn10300, /* Matsushita MN10300 */
+#define bfd_mach_mn10300 300
+#define bfd_mach_am33 330
+#define bfd_mach_am33_2 332
+ bfd_arch_fr30,
+#define bfd_mach_fr30 0x46523330
+ bfd_arch_frv,
+#define bfd_mach_frv 1
+#define bfd_mach_frvsimple 2
+#define bfd_mach_fr300 300
+#define bfd_mach_fr400 400
+#define bfd_mach_fr450 450
+#define bfd_mach_frvtomcat 499 /* fr500 prototype */
+#define bfd_mach_fr500 500
+#define bfd_mach_fr550 550
+ bfd_arch_moxie, /* The moxie processor */
+#define bfd_mach_moxie 1
+ bfd_arch_mcore,
+ bfd_arch_mep,
+#define bfd_mach_mep 1
+#define bfd_mach_mep_h1 0x6831
+#define bfd_mach_mep_c5 0x6335
+ bfd_arch_metag,
+#define bfd_mach_metag 1
+ bfd_arch_ia64, /* HP/Intel ia64 */
+#define bfd_mach_ia64_elf64 64
+#define bfd_mach_ia64_elf32 32
+ bfd_arch_ip2k, /* Ubicom IP2K microcontrollers. */
+#define bfd_mach_ip2022 1
+#define bfd_mach_ip2022ext 2
+ bfd_arch_iq2000, /* Vitesse IQ2000. */
+#define bfd_mach_iq2000 1
+#define bfd_mach_iq10 2
+ bfd_arch_epiphany, /* Adapteva EPIPHANY */
+#define bfd_mach_epiphany16 1
+#define bfd_mach_epiphany32 2
+ bfd_arch_mt,
+#define bfd_mach_ms1 1
+#define bfd_mach_mrisc2 2
+#define bfd_mach_ms2 3
+ bfd_arch_pj,
+ bfd_arch_avr, /* Atmel AVR microcontrollers. */
+#define bfd_mach_avr1 1
+#define bfd_mach_avr2 2
+#define bfd_mach_avr25 25
+#define bfd_mach_avr3 3
+#define bfd_mach_avr31 31
+#define bfd_mach_avr35 35
+#define bfd_mach_avr4 4
+#define bfd_mach_avr5 5
+#define bfd_mach_avr51 51
+#define bfd_mach_avr6 6
+#define bfd_mach_avrtiny 100
+#define bfd_mach_avrxmega1 101
+#define bfd_mach_avrxmega2 102
+#define bfd_mach_avrxmega3 103
+#define bfd_mach_avrxmega4 104
+#define bfd_mach_avrxmega5 105
+#define bfd_mach_avrxmega6 106
+#define bfd_mach_avrxmega7 107
+ bfd_arch_bfin, /* ADI Blackfin */
+#define bfd_mach_bfin 1
+ bfd_arch_cr16, /* National Semiconductor CompactRISC (ie CR16). */
+#define bfd_mach_cr16 1
+ bfd_arch_cr16c, /* National Semiconductor CompactRISC. */
+#define bfd_mach_cr16c 1
+ bfd_arch_crx, /* National Semiconductor CRX. */
+#define bfd_mach_crx 1
+ bfd_arch_cris, /* Axis CRIS */
+#define bfd_mach_cris_v0_v10 255
+#define bfd_mach_cris_v32 32
+#define bfd_mach_cris_v10_v32 1032
+ bfd_arch_rl78,
+#define bfd_mach_rl78 0x75
+ bfd_arch_rx, /* Renesas RX. */
+#define bfd_mach_rx 0x75
+ bfd_arch_s390, /* IBM s390 */
+#define bfd_mach_s390_31 31
+#define bfd_mach_s390_64 64
+ bfd_arch_score, /* Sunplus score */
+#define bfd_mach_score3 3
+#define bfd_mach_score7 7
+ bfd_arch_mmix, /* Donald Knuth's educational processor. */
+ bfd_arch_xstormy16,
+#define bfd_mach_xstormy16 1
+ bfd_arch_msp430, /* Texas Instruments MSP430 architecture. */
+#define bfd_mach_msp11 11
+#define bfd_mach_msp110 110
+#define bfd_mach_msp12 12
+#define bfd_mach_msp13 13
+#define bfd_mach_msp14 14
+#define bfd_mach_msp15 15
+#define bfd_mach_msp16 16
+#define bfd_mach_msp20 20
+#define bfd_mach_msp21 21
+#define bfd_mach_msp22 22
+#define bfd_mach_msp23 23
+#define bfd_mach_msp24 24
+#define bfd_mach_msp26 26
+#define bfd_mach_msp31 31
+#define bfd_mach_msp32 32
+#define bfd_mach_msp33 33
+#define bfd_mach_msp41 41
+#define bfd_mach_msp42 42
+#define bfd_mach_msp43 43
+#define bfd_mach_msp44 44
+#define bfd_mach_msp430x 45
+#define bfd_mach_msp46 46
+#define bfd_mach_msp47 47
+#define bfd_mach_msp54 54
+ bfd_arch_xc16x, /* Infineon's XC16X Series. */
+#define bfd_mach_xc16x 1
+#define bfd_mach_xc16xl 2
+#define bfd_mach_xc16xs 3
+ bfd_arch_xgate, /* Freescale XGATE */
+#define bfd_mach_xgate 1
+ bfd_arch_xtensa, /* Tensilica's Xtensa cores. */
+#define bfd_mach_xtensa 1
+ bfd_arch_z80,
+#define bfd_mach_z80strict 1 /* No undocumented opcodes. */
+#define bfd_mach_z80 3 /* With ixl, ixh, iyl, and iyh. */
+#define bfd_mach_z80full 7 /* All undocumented instructions. */
+#define bfd_mach_r800 11 /* R800: successor with multiplication. */
+ bfd_arch_lm32, /* Lattice Mico32 */
+#define bfd_mach_lm32 1
+ bfd_arch_microblaze,/* Xilinx MicroBlaze. */
+ bfd_arch_tilepro, /* Tilera TILEPro */
+ bfd_arch_tilegx, /* Tilera TILE-Gx */
+#define bfd_mach_tilepro 1
+#define bfd_mach_tilegx 1
+#define bfd_mach_tilegx32 2
+ bfd_arch_aarch64, /* AArch64 */
+#define bfd_mach_aarch64 0
+#define bfd_mach_aarch64_ilp32 32
+ bfd_arch_nios2,
+#define bfd_mach_nios2 0
+ 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.
+ The default arch should be the first entry for an arch so that
+ all the entries for that arch can be accessed via <<next>>. */
+ bfd_boolean the_default;
+ const struct bfd_arch_info * (*compatible)
+ (const struct bfd_arch_info *a, const struct bfd_arch_info *b);
+
+ bfd_boolean (*scan) (const struct bfd_arch_info *, const char *);
+
+ /* Allocate via bfd_malloc and return a fill buffer of size COUNT. If
+ IS_BIGENDIAN is TRUE, the order of bytes is big endian. If CODE is
+ TRUE, the buffer contains code. */
+ void *(*fill) (bfd_size_type count, bfd_boolean is_bigendian,
+ bfd_boolean code);
+
+ const struct bfd_arch_info *next;
+}
+bfd_arch_info_type;
+
+const char *bfd_printable_name (bfd *abfd);
+
+const bfd_arch_info_type *bfd_scan_arch (const char *string);
+
+const char **bfd_arch_list (void);
+
+const bfd_arch_info_type *bfd_arch_get_compatible
+ (const bfd *abfd, const bfd *bbfd, bfd_boolean accept_unknowns);
+
+void bfd_set_arch_info (bfd *abfd, const bfd_arch_info_type *arg);
+
+enum bfd_architecture bfd_get_arch (bfd *abfd);
+
+unsigned long bfd_get_mach (bfd *abfd);
+
+unsigned int bfd_arch_bits_per_byte (bfd *abfd);
+
+unsigned int bfd_arch_bits_per_address (bfd *abfd);
+
+const bfd_arch_info_type *bfd_get_arch_info (bfd *abfd);
+
+const bfd_arch_info_type *bfd_lookup_arch
+ (enum bfd_architecture arch, unsigned long machine);
+
+const char *bfd_printable_arch_mach
+ (enum bfd_architecture arch, unsigned long machine);
+
+unsigned int bfd_octets_per_byte (bfd *abfd);
+
+unsigned int bfd_arch_mach_octets_per_byte
+ (enum bfd_architecture arch, unsigned long machine);
+
+/* Extracted from reloc.c. */
+
+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 bfd_symbol **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 value overflows when considered as a signed
+ number one bit larger than the field. ie. A bitfield of N bits
+ is allowed to represent -2**n to 2**n-1. */
+ complain_overflow_bitfield,
+
+ /* Complain if the value overflows when considered as a signed
+ number. */
+ complain_overflow_signed,
+
+ /* Complain if the value overflows when considered as an
+ unsigned number. */
+ complain_overflow_unsigned
+};
+struct bfd_symbol; /* 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;
+
+ /* The relocation is relative to the field being relocated. */
+ bfd_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 accommodated (e.g., i960 callj
+ instructions). */
+ bfd_reloc_status_type (*special_function)
+ (bfd *, arelent *, struct bfd_symbol *, void *, asection *,
+ bfd *, char **);
+
+ /* The textual name of the relocation type. */
+ char *name;
+
+ /* Some formats record a relocation addend in the section contents
+ rather than with the relocation. For ELF formats this is the
+ distinction between USE_REL and USE_RELA (though the code checks
+ for USE_REL == 1/0). The value of this field is TRUE if the
+ addend is recorded with the section contents; when performing a
+ partial link (ld -r) the section contents (the data) will be
+ modified. The value of this field is FALSE if addends are
+ recorded with the relocation (in arelent.addend); when performing
+ a partial link the relocation will be modified.
+ All relocations for all ELF USE_RELA targets should set this field
+ to FALSE (values of TRUE should be looked on with suspicion).
+ However, the converse is not true: not all relocations of all ELF
+ USE_REL targets set this field to TRUE. Why this is so is peculiar
+ to each particular target. For relocs that aren't used in partial
+ links (e.g. GOT stuff) it doesn't matter what this is set to. */
+ bfd_boolean partial_inplace;
+
+ /* src_mask selects the part of the instruction (or data) to be used
+ in the relocation sum. If the target relocations don't have an
+ addend in the reloc, eg. ELF USE_REL, src_mask will normally equal
+ dst_mask to extract the addend from the section contents. If
+ relocations do have an addend in the reloc, eg. ELF USE_RELA, this
+ field should be zero. Non-zero values for ELF USE_RELA targets are
+ bogus as in those cases the value in the dst_mask part of the
+ section contents should be treated as garbage. */
+ bfd_vma src_mask;
+
+ /* dst_mask selects which parts of the instruction (or data) are
+ replaced with a relocated value. */
+ 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. */
+ bfd_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 EMPTY_HOWTO(C) \
+ HOWTO ((C), 0, 0, 0, FALSE, 0, complain_overflow_dont, NULL, \
+ NULL, FALSE, 0, 0, FALSE)
+
+#define HOWTO_PREPARE(relocation, symbol) \
+ { \
+ if (symbol != NULL) \
+ { \
+ if (bfd_is_com_section (symbol->section)) \
+ { \
+ relocation = 0; \
+ } \
+ else \
+ { \
+ relocation = symbol->value; \
+ } \
+ } \
+ }
+
+unsigned int bfd_get_reloc_size (reloc_howto_type *);
+
+typedef struct relent_chain
+{
+ arelent relent;
+ struct relent_chain *next;
+}
+arelent_chain;
+
+bfd_reloc_status_type bfd_check_overflow
+ (enum complain_overflow how,
+ unsigned int bitsize,
+ unsigned int rightshift,
+ unsigned int addrsize,
+ bfd_vma relocation);
+
+bfd_reloc_status_type bfd_perform_relocation
+ (bfd *abfd,
+ arelent *reloc_entry,
+ void *data,
+ asection *input_section,
+ bfd *output_bfd,
+ char **error_message);
+
+bfd_reloc_status_type bfd_install_relocation
+ (bfd *abfd,
+ arelent *reloc_entry,
+ void *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,
+
+/* Section relative relocations. Some targets need this for DWARF2. */
+ BFD_RELOC_32_SECREL,
+
+/* 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_64_PLT_PCREL,
+ BFD_RELOC_32_PLT_PCREL,
+ BFD_RELOC_24_PLT_PCREL,
+ BFD_RELOC_16_PLT_PCREL,
+ BFD_RELOC_8_PLT_PCREL,
+ BFD_RELOC_64_PLTOFF,
+ 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,
+
+/* Size relocations. */
+ BFD_RELOC_SIZE32,
+ BFD_RELOC_SIZE64,
+
+/* Relocations used by 68K ELF. */
+ BFD_RELOC_68K_GLOB_DAT,
+ BFD_RELOC_68K_JMP_SLOT,
+ BFD_RELOC_68K_RELATIVE,
+ BFD_RELOC_68K_TLS_GD32,
+ BFD_RELOC_68K_TLS_GD16,
+ BFD_RELOC_68K_TLS_GD8,
+ BFD_RELOC_68K_TLS_LDM32,
+ BFD_RELOC_68K_TLS_LDM16,
+ BFD_RELOC_68K_TLS_LDM8,
+ BFD_RELOC_68K_TLS_LDO32,
+ BFD_RELOC_68K_TLS_LDO16,
+ BFD_RELOC_68K_TLS_LDO8,
+ BFD_RELOC_68K_TLS_IE32,
+ BFD_RELOC_68K_TLS_IE16,
+ BFD_RELOC_68K_TLS_IE8,
+ BFD_RELOC_68K_TLS_LE32,
+ BFD_RELOC_68K_TLS_LE16,
+ BFD_RELOC_68K_TLS_LE8,
+
+/* 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_UA16,
+ BFD_RELOC_SPARC_UA32,
+ BFD_RELOC_SPARC_UA64,
+ BFD_RELOC_SPARC_GOTDATA_HIX22,
+ BFD_RELOC_SPARC_GOTDATA_LOX10,
+ BFD_RELOC_SPARC_GOTDATA_OP_HIX22,
+ BFD_RELOC_SPARC_GOTDATA_OP_LOX10,
+ BFD_RELOC_SPARC_GOTDATA_OP,
+ BFD_RELOC_SPARC_JMP_IREL,
+ BFD_RELOC_SPARC_IRELATIVE,
+
+/* 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_PLT32,
+ 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_H34,
+ BFD_RELOC_SPARC_SIZE32,
+ BFD_RELOC_SPARC_SIZE64,
+ BFD_RELOC_SPARC_WDISP10,
+
+/* SPARC little endian relocation */
+ BFD_RELOC_SPARC_REV32,
+
+/* SPARC TLS relocations */
+ BFD_RELOC_SPARC_TLS_GD_HI22,
+ BFD_RELOC_SPARC_TLS_GD_LO10,
+ BFD_RELOC_SPARC_TLS_GD_ADD,
+ BFD_RELOC_SPARC_TLS_GD_CALL,
+ BFD_RELOC_SPARC_TLS_LDM_HI22,
+ BFD_RELOC_SPARC_TLS_LDM_LO10,
+ BFD_RELOC_SPARC_TLS_LDM_ADD,
+ BFD_RELOC_SPARC_TLS_LDM_CALL,
+ BFD_RELOC_SPARC_TLS_LDO_HIX22,
+ BFD_RELOC_SPARC_TLS_LDO_LOX10,
+ BFD_RELOC_SPARC_TLS_LDO_ADD,
+ BFD_RELOC_SPARC_TLS_IE_HI22,
+ BFD_RELOC_SPARC_TLS_IE_LO10,
+ BFD_RELOC_SPARC_TLS_IE_LD,
+ BFD_RELOC_SPARC_TLS_IE_LDX,
+ BFD_RELOC_SPARC_TLS_IE_ADD,
+ BFD_RELOC_SPARC_TLS_LE_HIX22,
+ BFD_RELOC_SPARC_TLS_LE_LOX10,
+ BFD_RELOC_SPARC_TLS_DTPMOD32,
+ BFD_RELOC_SPARC_TLS_DTPMOD64,
+ BFD_RELOC_SPARC_TLS_DTPOFF32,
+ BFD_RELOC_SPARC_TLS_DTPOFF64,
+ BFD_RELOC_SPARC_TLS_TPOFF32,
+ BFD_RELOC_SPARC_TLS_TPOFF64,
+
+/* SPU Relocations. */
+ BFD_RELOC_SPU_IMM7,
+ BFD_RELOC_SPU_IMM8,
+ BFD_RELOC_SPU_IMM10,
+ BFD_RELOC_SPU_IMM10W,
+ BFD_RELOC_SPU_IMM16,
+ BFD_RELOC_SPU_IMM16W,
+ BFD_RELOC_SPU_IMM18,
+ BFD_RELOC_SPU_PCREL9a,
+ BFD_RELOC_SPU_PCREL9b,
+ BFD_RELOC_SPU_PCREL16,
+ BFD_RELOC_SPU_LO16,
+ BFD_RELOC_SPU_HI16,
+ BFD_RELOC_SPU_PPU32,
+ BFD_RELOC_SPU_PPU64,
+ BFD_RELOC_SPU_ADD_PIC,
+
+/* 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) */
+ 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,
+
+/* The GPREL_HI/LO relocations together form a 32-bit offset from the
+GP register. */
+ BFD_RELOC_ALPHA_GPREL_HI16,
+ BFD_RELOC_ALPHA_GPREL_LO16,
+
+/* Like BFD_RELOC_23_PCREL_S2, except that the source and target must
+share a common GP, and the target address is adjusted for
+STO_ALPHA_STD_GPLOAD. */
+ BFD_RELOC_ALPHA_BRSGP,
+
+/* The NOP relocation outputs a NOP if the longword displacement
+between two procedure entry points is < 2^21. */
+ BFD_RELOC_ALPHA_NOP,
+
+/* The BSR relocation outputs a BSR if the longword displacement
+between two procedure entry points is < 2^21. */
+ BFD_RELOC_ALPHA_BSR,
+
+/* The LDA relocation outputs a LDA if the longword displacement
+between two procedure entry points is < 2^16. */
+ BFD_RELOC_ALPHA_LDA,
+
+/* The BOH relocation outputs a BSR if the longword displacement
+between two procedure entry points is < 2^21, or else a hint. */
+ BFD_RELOC_ALPHA_BOH,
+
+/* Alpha thread-local storage relocations. */
+ BFD_RELOC_ALPHA_TLSGD,
+ BFD_RELOC_ALPHA_TLSLDM,
+ BFD_RELOC_ALPHA_DTPMOD64,
+ BFD_RELOC_ALPHA_GOTDTPREL16,
+ BFD_RELOC_ALPHA_DTPREL64,
+ BFD_RELOC_ALPHA_DTPREL_HI16,
+ BFD_RELOC_ALPHA_DTPREL_LO16,
+ BFD_RELOC_ALPHA_DTPREL16,
+ BFD_RELOC_ALPHA_GOTTPREL16,
+ BFD_RELOC_ALPHA_TPREL64,
+ BFD_RELOC_ALPHA_TPREL_HI16,
+ BFD_RELOC_ALPHA_TPREL_LO16,
+ BFD_RELOC_ALPHA_TPREL16,
+
+/* The MIPS jump instruction. */
+ BFD_RELOC_MIPS_JMP,
+ BFD_RELOC_MICROMIPS_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,
+
+/* High 16 bits of 32-bit pc-relative value */
+ BFD_RELOC_HI16_PCREL,
+
+/* High 16 bits of 32-bit pc-relative value, adjusted */
+ BFD_RELOC_HI16_S_PCREL,
+
+/* Low 16 bits of pc-relative value */
+ BFD_RELOC_LO16_PCREL,
+
+/* Equivalent of BFD_RELOC_MIPS_*, but with the MIPS16 layout of
+16-bit immediate fields */
+ BFD_RELOC_MIPS16_GOT16,
+ BFD_RELOC_MIPS16_CALL16,
+
+/* MIPS16 high 16 bits of 32-bit value. */
+ BFD_RELOC_MIPS16_HI16,
+
+/* MIPS16 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_MIPS16_HI16_S,
+
+/* MIPS16 low 16 bits. */
+ BFD_RELOC_MIPS16_LO16,
+
+/* MIPS16 TLS relocations */
+ BFD_RELOC_MIPS16_TLS_GD,
+ BFD_RELOC_MIPS16_TLS_LDM,
+ BFD_RELOC_MIPS16_TLS_DTPREL_HI16,
+ BFD_RELOC_MIPS16_TLS_DTPREL_LO16,
+ BFD_RELOC_MIPS16_TLS_GOTTPREL,
+ BFD_RELOC_MIPS16_TLS_TPREL_HI16,
+ BFD_RELOC_MIPS16_TLS_TPREL_LO16,
+
+/* Relocation against a MIPS literal section. */
+ BFD_RELOC_MIPS_LITERAL,
+ BFD_RELOC_MICROMIPS_LITERAL,
+
+/* microMIPS PC-relative relocations. */
+ BFD_RELOC_MICROMIPS_7_PCREL_S1,
+ BFD_RELOC_MICROMIPS_10_PCREL_S1,
+ BFD_RELOC_MICROMIPS_16_PCREL_S1,
+
+/* MIPS PC-relative relocations. */
+ BFD_RELOC_MIPS_21_PCREL_S2,
+ BFD_RELOC_MIPS_26_PCREL_S2,
+ BFD_RELOC_MIPS_18_PCREL_S3,
+ BFD_RELOC_MIPS_19_PCREL_S2,
+
+/* microMIPS versions of generic BFD relocs. */
+ BFD_RELOC_MICROMIPS_GPREL16,
+ BFD_RELOC_MICROMIPS_HI16,
+ BFD_RELOC_MICROMIPS_HI16_S,
+ BFD_RELOC_MICROMIPS_LO16,
+
+/* MIPS ELF relocations. */
+ BFD_RELOC_MIPS_GOT16,
+ BFD_RELOC_MICROMIPS_GOT16,
+ BFD_RELOC_MIPS_CALL16,
+ BFD_RELOC_MICROMIPS_CALL16,
+ BFD_RELOC_MIPS_GOT_HI16,
+ BFD_RELOC_MICROMIPS_GOT_HI16,
+ BFD_RELOC_MIPS_GOT_LO16,
+ BFD_RELOC_MICROMIPS_GOT_LO16,
+ BFD_RELOC_MIPS_CALL_HI16,
+ BFD_RELOC_MICROMIPS_CALL_HI16,
+ BFD_RELOC_MIPS_CALL_LO16,
+ BFD_RELOC_MICROMIPS_CALL_LO16,
+ BFD_RELOC_MIPS_SUB,
+ BFD_RELOC_MICROMIPS_SUB,
+ BFD_RELOC_MIPS_GOT_PAGE,
+ BFD_RELOC_MICROMIPS_GOT_PAGE,
+ BFD_RELOC_MIPS_GOT_OFST,
+ BFD_RELOC_MICROMIPS_GOT_OFST,
+ BFD_RELOC_MIPS_GOT_DISP,
+ BFD_RELOC_MICROMIPS_GOT_DISP,
+ BFD_RELOC_MIPS_SHIFT5,
+ BFD_RELOC_MIPS_SHIFT6,
+ BFD_RELOC_MIPS_INSERT_A,
+ BFD_RELOC_MIPS_INSERT_B,
+ BFD_RELOC_MIPS_DELETE,
+ BFD_RELOC_MIPS_HIGHEST,
+ BFD_RELOC_MICROMIPS_HIGHEST,
+ BFD_RELOC_MIPS_HIGHER,
+ BFD_RELOC_MICROMIPS_HIGHER,
+ BFD_RELOC_MIPS_SCN_DISP,
+ BFD_RELOC_MICROMIPS_SCN_DISP,
+ BFD_RELOC_MIPS_REL16,
+ BFD_RELOC_MIPS_RELGOT,
+ BFD_RELOC_MIPS_JALR,
+ BFD_RELOC_MICROMIPS_JALR,
+ BFD_RELOC_MIPS_TLS_DTPMOD32,
+ BFD_RELOC_MIPS_TLS_DTPREL32,
+ BFD_RELOC_MIPS_TLS_DTPMOD64,
+ BFD_RELOC_MIPS_TLS_DTPREL64,
+ BFD_RELOC_MIPS_TLS_GD,
+ BFD_RELOC_MICROMIPS_TLS_GD,
+ BFD_RELOC_MIPS_TLS_LDM,
+ BFD_RELOC_MICROMIPS_TLS_LDM,
+ BFD_RELOC_MIPS_TLS_DTPREL_HI16,
+ BFD_RELOC_MICROMIPS_TLS_DTPREL_HI16,
+ BFD_RELOC_MIPS_TLS_DTPREL_LO16,
+ BFD_RELOC_MICROMIPS_TLS_DTPREL_LO16,
+ BFD_RELOC_MIPS_TLS_GOTTPREL,
+ BFD_RELOC_MICROMIPS_TLS_GOTTPREL,
+ BFD_RELOC_MIPS_TLS_TPREL32,
+ BFD_RELOC_MIPS_TLS_TPREL64,
+ BFD_RELOC_MIPS_TLS_TPREL_HI16,
+ BFD_RELOC_MICROMIPS_TLS_TPREL_HI16,
+ BFD_RELOC_MIPS_TLS_TPREL_LO16,
+ BFD_RELOC_MICROMIPS_TLS_TPREL_LO16,
+ BFD_RELOC_MIPS_EH,
+
+
+/* MIPS ELF relocations (VxWorks and PLT extensions). */
+ BFD_RELOC_MIPS_COPY,
+ BFD_RELOC_MIPS_JUMP_SLOT,
+
+
+/* Moxie ELF relocations. */
+ BFD_RELOC_MOXIE_10_PCREL,
+
+
+/* Fujitsu Frv Relocations. */
+ BFD_RELOC_FRV_LABEL16,
+ BFD_RELOC_FRV_LABEL24,
+ BFD_RELOC_FRV_LO16,
+ BFD_RELOC_FRV_HI16,
+ BFD_RELOC_FRV_GPREL12,
+ BFD_RELOC_FRV_GPRELU12,
+ BFD_RELOC_FRV_GPREL32,
+ BFD_RELOC_FRV_GPRELHI,
+ BFD_RELOC_FRV_GPRELLO,
+ BFD_RELOC_FRV_GOT12,
+ BFD_RELOC_FRV_GOTHI,
+ BFD_RELOC_FRV_GOTLO,
+ BFD_RELOC_FRV_FUNCDESC,
+ BFD_RELOC_FRV_FUNCDESC_GOT12,
+ BFD_RELOC_FRV_FUNCDESC_GOTHI,
+ BFD_RELOC_FRV_FUNCDESC_GOTLO,
+ BFD_RELOC_FRV_FUNCDESC_VALUE,
+ BFD_RELOC_FRV_FUNCDESC_GOTOFF12,
+ BFD_RELOC_FRV_FUNCDESC_GOTOFFHI,
+ BFD_RELOC_FRV_FUNCDESC_GOTOFFLO,
+ BFD_RELOC_FRV_GOTOFF12,
+ BFD_RELOC_FRV_GOTOFFHI,
+ BFD_RELOC_FRV_GOTOFFLO,
+ BFD_RELOC_FRV_GETTLSOFF,
+ BFD_RELOC_FRV_TLSDESC_VALUE,
+ BFD_RELOC_FRV_GOTTLSDESC12,
+ BFD_RELOC_FRV_GOTTLSDESCHI,
+ BFD_RELOC_FRV_GOTTLSDESCLO,
+ BFD_RELOC_FRV_TLSMOFF12,
+ BFD_RELOC_FRV_TLSMOFFHI,
+ BFD_RELOC_FRV_TLSMOFFLO,
+ BFD_RELOC_FRV_GOTTLSOFF12,
+ BFD_RELOC_FRV_GOTTLSOFFHI,
+ BFD_RELOC_FRV_GOTTLSOFFLO,
+ BFD_RELOC_FRV_TLSOFF,
+ BFD_RELOC_FRV_TLSDESC_RELAX,
+ BFD_RELOC_FRV_GETTLSOFF_RELAX,
+ BFD_RELOC_FRV_TLSOFF_RELAX,
+ BFD_RELOC_FRV_TLSMOFF,
+
+
+/* This is a 24bit GOT-relative reloc for the mn10300. */
+ BFD_RELOC_MN10300_GOTOFF24,
+
+/* This is a 32bit GOT-relative reloc for the mn10300, offset by two bytes
+in the instruction. */
+ BFD_RELOC_MN10300_GOT32,
+
+/* This is a 24bit GOT-relative reloc for the mn10300, offset by two bytes
+in the instruction. */
+ BFD_RELOC_MN10300_GOT24,
+
+/* This is a 16bit GOT-relative reloc for the mn10300, offset by two bytes
+in the instruction. */
+ BFD_RELOC_MN10300_GOT16,
+
+/* Copy symbol at runtime. */
+ BFD_RELOC_MN10300_COPY,
+
+/* Create GOT entry. */
+ BFD_RELOC_MN10300_GLOB_DAT,
+
+/* Create PLT entry. */
+ BFD_RELOC_MN10300_JMP_SLOT,
+
+/* Adjust by program base. */
+ BFD_RELOC_MN10300_RELATIVE,
+
+/* Together with another reloc targeted at the same location,
+allows for a value that is the difference of two symbols
+in the same section. */
+ BFD_RELOC_MN10300_SYM_DIFF,
+
+/* The addend of this reloc is an alignment power that must
+be honoured at the offset's location, regardless of linker
+relaxation. */
+ BFD_RELOC_MN10300_ALIGN,
+
+/* Various TLS-related relocations. */
+ BFD_RELOC_MN10300_TLS_GD,
+ BFD_RELOC_MN10300_TLS_LD,
+ BFD_RELOC_MN10300_TLS_LDO,
+ BFD_RELOC_MN10300_TLS_GOTIE,
+ BFD_RELOC_MN10300_TLS_IE,
+ BFD_RELOC_MN10300_TLS_LE,
+ BFD_RELOC_MN10300_TLS_DTPMOD,
+ BFD_RELOC_MN10300_TLS_DTPOFF,
+ BFD_RELOC_MN10300_TLS_TPOFF,
+
+/* 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,
+
+
+/* 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,
+ BFD_RELOC_386_TLS_TPOFF,
+ BFD_RELOC_386_TLS_IE,
+ BFD_RELOC_386_TLS_GOTIE,
+ BFD_RELOC_386_TLS_LE,
+ BFD_RELOC_386_TLS_GD,
+ BFD_RELOC_386_TLS_LDM,
+ BFD_RELOC_386_TLS_LDO_32,
+ BFD_RELOC_386_TLS_IE_32,
+ BFD_RELOC_386_TLS_LE_32,
+ BFD_RELOC_386_TLS_DTPMOD32,
+ BFD_RELOC_386_TLS_DTPOFF32,
+ BFD_RELOC_386_TLS_TPOFF32,
+ BFD_RELOC_386_TLS_GOTDESC,
+ BFD_RELOC_386_TLS_DESC_CALL,
+ BFD_RELOC_386_TLS_DESC,
+ BFD_RELOC_386_IRELATIVE,
+
+/* x86-64/elf relocations */
+ BFD_RELOC_X86_64_GOT32,
+ BFD_RELOC_X86_64_PLT32,
+ BFD_RELOC_X86_64_COPY,
+ BFD_RELOC_X86_64_GLOB_DAT,
+ BFD_RELOC_X86_64_JUMP_SLOT,
+ BFD_RELOC_X86_64_RELATIVE,
+ BFD_RELOC_X86_64_GOTPCREL,
+ BFD_RELOC_X86_64_32S,
+ BFD_RELOC_X86_64_DTPMOD64,
+ BFD_RELOC_X86_64_DTPOFF64,
+ BFD_RELOC_X86_64_TPOFF64,
+ BFD_RELOC_X86_64_TLSGD,
+ BFD_RELOC_X86_64_TLSLD,
+ BFD_RELOC_X86_64_DTPOFF32,
+ BFD_RELOC_X86_64_GOTTPOFF,
+ BFD_RELOC_X86_64_TPOFF32,
+ BFD_RELOC_X86_64_GOTOFF64,
+ BFD_RELOC_X86_64_GOTPC32,
+ BFD_RELOC_X86_64_GOT64,
+ BFD_RELOC_X86_64_GOTPCREL64,
+ BFD_RELOC_X86_64_GOTPC64,
+ BFD_RELOC_X86_64_GOTPLT64,
+ BFD_RELOC_X86_64_PLTOFF64,
+ BFD_RELOC_X86_64_GOTPC32_TLSDESC,
+ BFD_RELOC_X86_64_TLSDESC_CALL,
+ BFD_RELOC_X86_64_TLSDESC,
+ BFD_RELOC_X86_64_IRELATIVE,
+ BFD_RELOC_X86_64_PC32_BND,
+ BFD_RELOC_X86_64_PLT32_BND,
+
+/* 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,
+
+/* PDP11 relocations */
+ BFD_RELOC_PDP11_DISP_8_PCREL,
+ BFD_RELOC_PDP11_DISP_6_PCREL,
+
+/* Picojava relocs. Not all of these appear in object files. */
+ BFD_RELOC_PJ_CODE_HI16,
+ BFD_RELOC_PJ_CODE_LO16,
+ BFD_RELOC_PJ_CODE_DIR16,
+ BFD_RELOC_PJ_CODE_DIR32,
+ BFD_RELOC_PJ_CODE_REL16,
+ BFD_RELOC_PJ_CODE_REL32,
+
+/* 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,
+ BFD_RELOC_PPC_VLE_REL8,
+ BFD_RELOC_PPC_VLE_REL15,
+ BFD_RELOC_PPC_VLE_REL24,
+ BFD_RELOC_PPC_VLE_LO16A,
+ BFD_RELOC_PPC_VLE_LO16D,
+ BFD_RELOC_PPC_VLE_HI16A,
+ BFD_RELOC_PPC_VLE_HI16D,
+ BFD_RELOC_PPC_VLE_HA16A,
+ BFD_RELOC_PPC_VLE_HA16D,
+ BFD_RELOC_PPC_VLE_SDA21,
+ BFD_RELOC_PPC_VLE_SDA21_LO,
+ BFD_RELOC_PPC_VLE_SDAREL_LO16A,
+ BFD_RELOC_PPC_VLE_SDAREL_LO16D,
+ BFD_RELOC_PPC_VLE_SDAREL_HI16A,
+ BFD_RELOC_PPC_VLE_SDAREL_HI16D,
+ BFD_RELOC_PPC_VLE_SDAREL_HA16A,
+ BFD_RELOC_PPC_VLE_SDAREL_HA16D,
+ BFD_RELOC_PPC64_HIGHER,
+ BFD_RELOC_PPC64_HIGHER_S,
+ BFD_RELOC_PPC64_HIGHEST,
+ BFD_RELOC_PPC64_HIGHEST_S,
+ BFD_RELOC_PPC64_TOC16_LO,
+ BFD_RELOC_PPC64_TOC16_HI,
+ BFD_RELOC_PPC64_TOC16_HA,
+ BFD_RELOC_PPC64_TOC,
+ BFD_RELOC_PPC64_PLTGOT16,
+ BFD_RELOC_PPC64_PLTGOT16_LO,
+ BFD_RELOC_PPC64_PLTGOT16_HI,
+ BFD_RELOC_PPC64_PLTGOT16_HA,
+ BFD_RELOC_PPC64_ADDR16_DS,
+ BFD_RELOC_PPC64_ADDR16_LO_DS,
+ BFD_RELOC_PPC64_GOT16_DS,
+ BFD_RELOC_PPC64_GOT16_LO_DS,
+ BFD_RELOC_PPC64_PLT16_LO_DS,
+ BFD_RELOC_PPC64_SECTOFF_DS,
+ BFD_RELOC_PPC64_SECTOFF_LO_DS,
+ BFD_RELOC_PPC64_TOC16_DS,
+ BFD_RELOC_PPC64_TOC16_LO_DS,
+ BFD_RELOC_PPC64_PLTGOT16_DS,
+ BFD_RELOC_PPC64_PLTGOT16_LO_DS,
+ BFD_RELOC_PPC64_ADDR16_HIGH,
+ BFD_RELOC_PPC64_ADDR16_HIGHA,
+ BFD_RELOC_PPC64_ADDR64_LOCAL,
+
+/* PowerPC and PowerPC64 thread-local storage relocations. */
+ BFD_RELOC_PPC_TLS,
+ BFD_RELOC_PPC_TLSGD,
+ BFD_RELOC_PPC_TLSLD,
+ BFD_RELOC_PPC_DTPMOD,
+ BFD_RELOC_PPC_TPREL16,
+ BFD_RELOC_PPC_TPREL16_LO,
+ BFD_RELOC_PPC_TPREL16_HI,
+ BFD_RELOC_PPC_TPREL16_HA,
+ BFD_RELOC_PPC_TPREL,
+ BFD_RELOC_PPC_DTPREL16,
+ BFD_RELOC_PPC_DTPREL16_LO,
+ BFD_RELOC_PPC_DTPREL16_HI,
+ BFD_RELOC_PPC_DTPREL16_HA,
+ BFD_RELOC_PPC_DTPREL,
+ BFD_RELOC_PPC_GOT_TLSGD16,
+ BFD_RELOC_PPC_GOT_TLSGD16_LO,
+ BFD_RELOC_PPC_GOT_TLSGD16_HI,
+ BFD_RELOC_PPC_GOT_TLSGD16_HA,
+ BFD_RELOC_PPC_GOT_TLSLD16,
+ BFD_RELOC_PPC_GOT_TLSLD16_LO,
+ BFD_RELOC_PPC_GOT_TLSLD16_HI,
+ BFD_RELOC_PPC_GOT_TLSLD16_HA,
+ BFD_RELOC_PPC_GOT_TPREL16,
+ BFD_RELOC_PPC_GOT_TPREL16_LO,
+ BFD_RELOC_PPC_GOT_TPREL16_HI,
+ BFD_RELOC_PPC_GOT_TPREL16_HA,
+ BFD_RELOC_PPC_GOT_DTPREL16,
+ BFD_RELOC_PPC_GOT_DTPREL16_LO,
+ BFD_RELOC_PPC_GOT_DTPREL16_HI,
+ BFD_RELOC_PPC_GOT_DTPREL16_HA,
+ BFD_RELOC_PPC64_TPREL16_DS,
+ BFD_RELOC_PPC64_TPREL16_LO_DS,
+ BFD_RELOC_PPC64_TPREL16_HIGHER,
+ BFD_RELOC_PPC64_TPREL16_HIGHERA,
+ BFD_RELOC_PPC64_TPREL16_HIGHEST,
+ BFD_RELOC_PPC64_TPREL16_HIGHESTA,
+ BFD_RELOC_PPC64_DTPREL16_DS,
+ BFD_RELOC_PPC64_DTPREL16_LO_DS,
+ BFD_RELOC_PPC64_DTPREL16_HIGHER,
+ BFD_RELOC_PPC64_DTPREL16_HIGHERA,
+ BFD_RELOC_PPC64_DTPREL16_HIGHEST,
+ BFD_RELOC_PPC64_DTPREL16_HIGHESTA,
+ BFD_RELOC_PPC64_TPREL16_HIGH,
+ BFD_RELOC_PPC64_TPREL16_HIGHA,
+ BFD_RELOC_PPC64_DTPREL16_HIGH,
+ BFD_RELOC_PPC64_DTPREL16_HIGHA,
+
+/* IBM 370/390 relocations */
+ BFD_RELOC_I370_D12,
+
+/* The type of reloc used to build a constructor 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,
+
+/* ARM 26 bit pc-relative branch. The lowest bit must be zero and is
+not stored in the instruction. The 2nd lowest bit comes from a 1 bit
+field in the instruction. */
+ BFD_RELOC_ARM_PCREL_BLX,
+
+/* Thumb 22 bit pc-relative branch. The lowest bit must be zero and is
+not stored in the instruction. The 2nd lowest bit comes from a 1 bit
+field in the instruction. */
+ BFD_RELOC_THUMB_PCREL_BLX,
+
+/* ARM 26-bit pc-relative branch for an unconditional BL or BLX instruction. */
+ BFD_RELOC_ARM_PCREL_CALL,
+
+/* ARM 26-bit pc-relative branch for B or conditional BL instruction. */
+ BFD_RELOC_ARM_PCREL_JUMP,
+
+/* Thumb 7-, 9-, 12-, 20-, 23-, and 25-bit pc-relative branches.
+The lowest bit must be zero and is not stored in the instruction.
+Note that the corresponding ELF R_ARM_THM_JUMPnn constant has an
+"nn" one smaller in all cases. Note further that BRANCH23
+corresponds to R_ARM_THM_CALL. */
+ BFD_RELOC_THUMB_PCREL_BRANCH7,
+ BFD_RELOC_THUMB_PCREL_BRANCH9,
+ BFD_RELOC_THUMB_PCREL_BRANCH12,
+ BFD_RELOC_THUMB_PCREL_BRANCH20,
+ BFD_RELOC_THUMB_PCREL_BRANCH23,
+ BFD_RELOC_THUMB_PCREL_BRANCH25,
+
+/* 12-bit immediate offset, used in ARM-format ldr and str instructions. */
+ BFD_RELOC_ARM_OFFSET_IMM,
+
+/* 5-bit immediate offset, used in Thumb-format ldr and str instructions. */
+ BFD_RELOC_ARM_THUMB_OFFSET,
+
+/* Pc-relative or absolute relocation depending on target. Used for
+entries in .init_array sections. */
+ BFD_RELOC_ARM_TARGET1,
+
+/* Read-only segment base relative address. */
+ BFD_RELOC_ARM_ROSEGREL32,
+
+/* Data segment base relative address. */
+ BFD_RELOC_ARM_SBREL32,
+
+/* This reloc is used for references to RTTI data from exception handling
+tables. The actual definition depends on the target. It may be a
+pc-relative or some form of GOT-indirect relocation. */
+ BFD_RELOC_ARM_TARGET2,
+
+/* 31-bit PC relative address. */
+ BFD_RELOC_ARM_PREL31,
+
+/* Low and High halfword relocations for MOVW and MOVT instructions. */
+ BFD_RELOC_ARM_MOVW,
+ BFD_RELOC_ARM_MOVT,
+ BFD_RELOC_ARM_MOVW_PCREL,
+ BFD_RELOC_ARM_MOVT_PCREL,
+ BFD_RELOC_ARM_THUMB_MOVW,
+ BFD_RELOC_ARM_THUMB_MOVT,
+ BFD_RELOC_ARM_THUMB_MOVW_PCREL,
+ BFD_RELOC_ARM_THUMB_MOVT_PCREL,
+
+/* Relocations for setting up GOTs and PLTs for shared libraries. */
+ BFD_RELOC_ARM_JUMP_SLOT,
+ BFD_RELOC_ARM_GLOB_DAT,
+ BFD_RELOC_ARM_GOT32,
+ BFD_RELOC_ARM_PLT32,
+ BFD_RELOC_ARM_RELATIVE,
+ BFD_RELOC_ARM_GOTOFF,
+ BFD_RELOC_ARM_GOTPC,
+ BFD_RELOC_ARM_GOT_PREL,
+
+/* ARM thread-local storage relocations. */
+ BFD_RELOC_ARM_TLS_GD32,
+ BFD_RELOC_ARM_TLS_LDO32,
+ BFD_RELOC_ARM_TLS_LDM32,
+ BFD_RELOC_ARM_TLS_DTPOFF32,
+ BFD_RELOC_ARM_TLS_DTPMOD32,
+ BFD_RELOC_ARM_TLS_TPOFF32,
+ BFD_RELOC_ARM_TLS_IE32,
+ BFD_RELOC_ARM_TLS_LE32,
+ BFD_RELOC_ARM_TLS_GOTDESC,
+ BFD_RELOC_ARM_TLS_CALL,
+ BFD_RELOC_ARM_THM_TLS_CALL,
+ BFD_RELOC_ARM_TLS_DESCSEQ,
+ BFD_RELOC_ARM_THM_TLS_DESCSEQ,
+ BFD_RELOC_ARM_TLS_DESC,
+
+/* ARM group relocations. */
+ BFD_RELOC_ARM_ALU_PC_G0_NC,
+ BFD_RELOC_ARM_ALU_PC_G0,
+ BFD_RELOC_ARM_ALU_PC_G1_NC,
+ BFD_RELOC_ARM_ALU_PC_G1,
+ BFD_RELOC_ARM_ALU_PC_G2,
+ BFD_RELOC_ARM_LDR_PC_G0,
+ BFD_RELOC_ARM_LDR_PC_G1,
+ BFD_RELOC_ARM_LDR_PC_G2,
+ BFD_RELOC_ARM_LDRS_PC_G0,
+ BFD_RELOC_ARM_LDRS_PC_G1,
+ BFD_RELOC_ARM_LDRS_PC_G2,
+ BFD_RELOC_ARM_LDC_PC_G0,
+ BFD_RELOC_ARM_LDC_PC_G1,
+ BFD_RELOC_ARM_LDC_PC_G2,
+ BFD_RELOC_ARM_ALU_SB_G0_NC,
+ BFD_RELOC_ARM_ALU_SB_G0,
+ BFD_RELOC_ARM_ALU_SB_G1_NC,
+ BFD_RELOC_ARM_ALU_SB_G1,
+ BFD_RELOC_ARM_ALU_SB_G2,
+ BFD_RELOC_ARM_LDR_SB_G0,
+ BFD_RELOC_ARM_LDR_SB_G1,
+ BFD_RELOC_ARM_LDR_SB_G2,
+ BFD_RELOC_ARM_LDRS_SB_G0,
+ BFD_RELOC_ARM_LDRS_SB_G1,
+ BFD_RELOC_ARM_LDRS_SB_G2,
+ BFD_RELOC_ARM_LDC_SB_G0,
+ BFD_RELOC_ARM_LDC_SB_G1,
+ BFD_RELOC_ARM_LDC_SB_G2,
+
+/* Annotation of BX instructions. */
+ BFD_RELOC_ARM_V4BX,
+
+/* ARM support for STT_GNU_IFUNC. */
+ BFD_RELOC_ARM_IRELATIVE,
+
+/* 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_ADRL_IMMEDIATE,
+ BFD_RELOC_ARM_T32_IMMEDIATE,
+ BFD_RELOC_ARM_T32_ADD_IMM,
+ BFD_RELOC_ARM_T32_IMM12,
+ BFD_RELOC_ARM_T32_ADD_PC12,
+ BFD_RELOC_ARM_SHIFT_IMM,
+ BFD_RELOC_ARM_SMC,
+ BFD_RELOC_ARM_HVC,
+ BFD_RELOC_ARM_SWI,
+ BFD_RELOC_ARM_MULTI,
+ BFD_RELOC_ARM_CP_OFF_IMM,
+ BFD_RELOC_ARM_CP_OFF_IMM_S2,
+ BFD_RELOC_ARM_T32_CP_OFF_IMM,
+ BFD_RELOC_ARM_T32_CP_OFF_IMM_S2,
+ 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_T32_OFFSET_U8,
+ BFD_RELOC_ARM_T32_OFFSET_IMM,
+ BFD_RELOC_ARM_HWLITERAL,
+ BFD_RELOC_ARM_THUMB_ADD,
+ BFD_RELOC_ARM_THUMB_IMM,
+ BFD_RELOC_ARM_THUMB_SHIFT,
+
+/* Renesas / SuperH SH relocs. Not all of these appear in object files. */
+ BFD_RELOC_SH_PCDISP8BY2,
+ BFD_RELOC_SH_PCDISP12BY2,
+ BFD_RELOC_SH_IMM3,
+ BFD_RELOC_SH_IMM3U,
+ BFD_RELOC_SH_DISP12,
+ BFD_RELOC_SH_DISP12BY2,
+ BFD_RELOC_SH_DISP12BY4,
+ BFD_RELOC_SH_DISP12BY8,
+ BFD_RELOC_SH_DISP20,
+ BFD_RELOC_SH_DISP20BY8,
+ 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_SH_LOOP_START,
+ BFD_RELOC_SH_LOOP_END,
+ BFD_RELOC_SH_COPY,
+ BFD_RELOC_SH_GLOB_DAT,
+ BFD_RELOC_SH_JMP_SLOT,
+ BFD_RELOC_SH_RELATIVE,
+ BFD_RELOC_SH_GOTPC,
+ BFD_RELOC_SH_GOT_LOW16,
+ BFD_RELOC_SH_GOT_MEDLOW16,
+ BFD_RELOC_SH_GOT_MEDHI16,
+ BFD_RELOC_SH_GOT_HI16,
+ BFD_RELOC_SH_GOTPLT_LOW16,
+ BFD_RELOC_SH_GOTPLT_MEDLOW16,
+ BFD_RELOC_SH_GOTPLT_MEDHI16,
+ BFD_RELOC_SH_GOTPLT_HI16,
+ BFD_RELOC_SH_PLT_LOW16,
+ BFD_RELOC_SH_PLT_MEDLOW16,
+ BFD_RELOC_SH_PLT_MEDHI16,
+ BFD_RELOC_SH_PLT_HI16,
+ BFD_RELOC_SH_GOTOFF_LOW16,
+ BFD_RELOC_SH_GOTOFF_MEDLOW16,
+ BFD_RELOC_SH_GOTOFF_MEDHI16,
+ BFD_RELOC_SH_GOTOFF_HI16,
+ BFD_RELOC_SH_GOTPC_LOW16,
+ BFD_RELOC_SH_GOTPC_MEDLOW16,
+ BFD_RELOC_SH_GOTPC_MEDHI16,
+ BFD_RELOC_SH_GOTPC_HI16,
+ BFD_RELOC_SH_COPY64,
+ BFD_RELOC_SH_GLOB_DAT64,
+ BFD_RELOC_SH_JMP_SLOT64,
+ BFD_RELOC_SH_RELATIVE64,
+ BFD_RELOC_SH_GOT10BY4,
+ BFD_RELOC_SH_GOT10BY8,
+ BFD_RELOC_SH_GOTPLT10BY4,
+ BFD_RELOC_SH_GOTPLT10BY8,
+ BFD_RELOC_SH_GOTPLT32,
+ BFD_RELOC_SH_SHMEDIA_CODE,
+ BFD_RELOC_SH_IMMU5,
+ BFD_RELOC_SH_IMMS6,
+ BFD_RELOC_SH_IMMS6BY32,
+ BFD_RELOC_SH_IMMU6,
+ BFD_RELOC_SH_IMMS10,
+ BFD_RELOC_SH_IMMS10BY2,
+ BFD_RELOC_SH_IMMS10BY4,
+ BFD_RELOC_SH_IMMS10BY8,
+ BFD_RELOC_SH_IMMS16,
+ BFD_RELOC_SH_IMMU16,
+ BFD_RELOC_SH_IMM_LOW16,
+ BFD_RELOC_SH_IMM_LOW16_PCREL,
+ BFD_RELOC_SH_IMM_MEDLOW16,
+ BFD_RELOC_SH_IMM_MEDLOW16_PCREL,
+ BFD_RELOC_SH_IMM_MEDHI16,
+ BFD_RELOC_SH_IMM_MEDHI16_PCREL,
+ BFD_RELOC_SH_IMM_HI16,
+ BFD_RELOC_SH_IMM_HI16_PCREL,
+ BFD_RELOC_SH_PT_16,
+ BFD_RELOC_SH_TLS_GD_32,
+ BFD_RELOC_SH_TLS_LD_32,
+ BFD_RELOC_SH_TLS_LDO_32,
+ BFD_RELOC_SH_TLS_IE_32,
+ BFD_RELOC_SH_TLS_LE_32,
+ BFD_RELOC_SH_TLS_DTPMOD32,
+ BFD_RELOC_SH_TLS_DTPOFF32,
+ BFD_RELOC_SH_TLS_TPOFF32,
+ BFD_RELOC_SH_GOT20,
+ BFD_RELOC_SH_GOTOFF20,
+ BFD_RELOC_SH_GOTFUNCDESC,
+ BFD_RELOC_SH_GOTFUNCDESC20,
+ BFD_RELOC_SH_GOTOFFFUNCDESC,
+ BFD_RELOC_SH_GOTOFFFUNCDESC20,
+ BFD_RELOC_SH_FUNCDESC,
+
+/* ARC Cores 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,
+
+/* ADI Blackfin 16 bit immediate absolute reloc. */
+ BFD_RELOC_BFIN_16_IMM,
+
+/* ADI Blackfin 16 bit immediate absolute reloc higher 16 bits. */
+ BFD_RELOC_BFIN_16_HIGH,
+
+/* ADI Blackfin 'a' part of LSETUP. */
+ BFD_RELOC_BFIN_4_PCREL,
+
+/* ADI Blackfin. */
+ BFD_RELOC_BFIN_5_PCREL,
+
+/* ADI Blackfin 16 bit immediate absolute reloc lower 16 bits. */
+ BFD_RELOC_BFIN_16_LOW,
+
+/* ADI Blackfin. */
+ BFD_RELOC_BFIN_10_PCREL,
+
+/* ADI Blackfin 'b' part of LSETUP. */
+ BFD_RELOC_BFIN_11_PCREL,
+
+/* ADI Blackfin. */
+ BFD_RELOC_BFIN_12_PCREL_JUMP,
+
+/* ADI Blackfin Short jump, pcrel. */
+ BFD_RELOC_BFIN_12_PCREL_JUMP_S,
+
+/* ADI Blackfin Call.x not implemented. */
+ BFD_RELOC_BFIN_24_PCREL_CALL_X,
+
+/* ADI Blackfin Long Jump pcrel. */
+ BFD_RELOC_BFIN_24_PCREL_JUMP_L,
+
+/* ADI Blackfin FD-PIC relocations. */
+ BFD_RELOC_BFIN_GOT17M4,
+ BFD_RELOC_BFIN_GOTHI,
+ BFD_RELOC_BFIN_GOTLO,
+ BFD_RELOC_BFIN_FUNCDESC,
+ BFD_RELOC_BFIN_FUNCDESC_GOT17M4,
+ BFD_RELOC_BFIN_FUNCDESC_GOTHI,
+ BFD_RELOC_BFIN_FUNCDESC_GOTLO,
+ BFD_RELOC_BFIN_FUNCDESC_VALUE,
+ BFD_RELOC_BFIN_FUNCDESC_GOTOFF17M4,
+ BFD_RELOC_BFIN_FUNCDESC_GOTOFFHI,
+ BFD_RELOC_BFIN_FUNCDESC_GOTOFFLO,
+ BFD_RELOC_BFIN_GOTOFF17M4,
+ BFD_RELOC_BFIN_GOTOFFHI,
+ BFD_RELOC_BFIN_GOTOFFLO,
+
+/* ADI Blackfin GOT relocation. */
+ BFD_RELOC_BFIN_GOT,
+
+/* ADI Blackfin PLTPC relocation. */
+ BFD_RELOC_BFIN_PLTPC,
+
+/* ADI Blackfin arithmetic relocation. */
+ BFD_ARELOC_BFIN_PUSH,
+
+/* ADI Blackfin arithmetic relocation. */
+ BFD_ARELOC_BFIN_CONST,
+
+/* ADI Blackfin arithmetic relocation. */
+ BFD_ARELOC_BFIN_ADD,
+
+/* ADI Blackfin arithmetic relocation. */
+ BFD_ARELOC_BFIN_SUB,
+
+/* ADI Blackfin arithmetic relocation. */
+ BFD_ARELOC_BFIN_MULT,
+
+/* ADI Blackfin arithmetic relocation. */
+ BFD_ARELOC_BFIN_DIV,
+
+/* ADI Blackfin arithmetic relocation. */
+ BFD_ARELOC_BFIN_MOD,
+
+/* ADI Blackfin arithmetic relocation. */
+ BFD_ARELOC_BFIN_LSHIFT,
+
+/* ADI Blackfin arithmetic relocation. */
+ BFD_ARELOC_BFIN_RSHIFT,
+
+/* ADI Blackfin arithmetic relocation. */
+ BFD_ARELOC_BFIN_AND,
+
+/* ADI Blackfin arithmetic relocation. */
+ BFD_ARELOC_BFIN_OR,
+
+/* ADI Blackfin arithmetic relocation. */
+ BFD_ARELOC_BFIN_XOR,
+
+/* ADI Blackfin arithmetic relocation. */
+ BFD_ARELOC_BFIN_LAND,
+
+/* ADI Blackfin arithmetic relocation. */
+ BFD_ARELOC_BFIN_LOR,
+
+/* ADI Blackfin arithmetic relocation. */
+ BFD_ARELOC_BFIN_LEN,
+
+/* ADI Blackfin arithmetic relocation. */
+ BFD_ARELOC_BFIN_NEG,
+
+/* ADI Blackfin arithmetic relocation. */
+ BFD_ARELOC_BFIN_COMP,
+
+/* ADI Blackfin arithmetic relocation. */
+ BFD_ARELOC_BFIN_PAGE,
+
+/* ADI Blackfin arithmetic relocation. */
+ BFD_ARELOC_BFIN_HWPAGE,
+
+/* ADI Blackfin arithmetic relocation. */
+ BFD_ARELOC_BFIN_ADDR,
+
+/* 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,
+
+/* DLX relocs */
+ BFD_RELOC_DLX_HI16_S,
+
+/* DLX relocs */
+ BFD_RELOC_DLX_LO16,
+
+/* DLX relocs */
+ BFD_RELOC_DLX_JMP26,
+
+/* Renesas M16C/M32C Relocations. */
+ BFD_RELOC_M32C_HI8,
+ BFD_RELOC_M32C_RL_JUMP,
+ BFD_RELOC_M32C_RL_1ADDR,
+ BFD_RELOC_M32C_RL_2ADDR,
+
+/* Renesas M32R (formerly 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,
+
+/* For PIC. */
+ BFD_RELOC_M32R_GOT24,
+ BFD_RELOC_M32R_26_PLTREL,
+ BFD_RELOC_M32R_COPY,
+ BFD_RELOC_M32R_GLOB_DAT,
+ BFD_RELOC_M32R_JMP_SLOT,
+ BFD_RELOC_M32R_RELATIVE,
+ BFD_RELOC_M32R_GOTOFF,
+ BFD_RELOC_M32R_GOTOFF_HI_ULO,
+ BFD_RELOC_M32R_GOTOFF_HI_SLO,
+ BFD_RELOC_M32R_GOTOFF_LO,
+ BFD_RELOC_M32R_GOTPC24,
+ BFD_RELOC_M32R_GOT16_HI_ULO,
+ BFD_RELOC_M32R_GOT16_HI_SLO,
+ BFD_RELOC_M32R_GOT16_LO,
+ BFD_RELOC_M32R_GOTPC_HI_ULO,
+ BFD_RELOC_M32R_GOTPC_HI_SLO,
+ BFD_RELOC_M32R_GOTPC_LO,
+
+/* NDS32 relocs.
+This is a 20 bit absolute address. */
+ BFD_RELOC_NDS32_20,
+
+/* This is a 9-bit pc-relative reloc with the right 1 bit assumed to be 0. */
+ BFD_RELOC_NDS32_9_PCREL,
+
+/* This is a 9-bit pc-relative reloc with the right 1 bit assumed to be 0. */
+ BFD_RELOC_NDS32_WORD_9_PCREL,
+
+/* This is an 15-bit reloc with the right 1 bit assumed to be 0. */
+ BFD_RELOC_NDS32_15_PCREL,
+
+/* This is an 17-bit reloc with the right 1 bit assumed to be 0. */
+ BFD_RELOC_NDS32_17_PCREL,
+
+/* This is a 25-bit reloc with the right 1 bit assumed to be 0. */
+ BFD_RELOC_NDS32_25_PCREL,
+
+/* This is a 20-bit reloc containing the high 20 bits of an address
+used with the lower 12 bits */
+ BFD_RELOC_NDS32_HI20,
+
+/* This is a 12-bit reloc containing the lower 12 bits of an address
+then shift right by 3. This is used with ldi,sdi... */
+ BFD_RELOC_NDS32_LO12S3,
+
+/* This is a 12-bit reloc containing the lower 12 bits of an address
+then shift left by 2. This is used with lwi,swi... */
+ BFD_RELOC_NDS32_LO12S2,
+
+/* This is a 12-bit reloc containing the lower 12 bits of an address
+then shift left by 1. This is used with lhi,shi... */
+ BFD_RELOC_NDS32_LO12S1,
+
+/* This is a 12-bit reloc containing the lower 12 bits of an address
+then shift left by 0. This is used with lbisbi... */
+ BFD_RELOC_NDS32_LO12S0,
+
+/* This is a 12-bit reloc containing the lower 12 bits of an address
+then shift left by 0. This is only used with branch relaxations */
+ BFD_RELOC_NDS32_LO12S0_ORI,
+
+/* This is a 15-bit reloc containing the small data area 18-bit signed offset
+and shift left by 3 for use in ldi, sdi... */
+ BFD_RELOC_NDS32_SDA15S3,
+
+/* This is a 15-bit reloc containing the small data area 17-bit signed offset
+and shift left by 2 for use in lwi, swi... */
+ BFD_RELOC_NDS32_SDA15S2,
+
+/* This is a 15-bit reloc containing the small data area 16-bit signed offset
+and shift left by 1 for use in lhi, shi... */
+ BFD_RELOC_NDS32_SDA15S1,
+
+/* This is a 15-bit reloc containing the small data area 15-bit signed offset
+and shift left by 0 for use in lbi, sbi... */
+ BFD_RELOC_NDS32_SDA15S0,
+
+/* This is a 16-bit reloc containing the small data area 16-bit signed offset
+and shift left by 3 */
+ BFD_RELOC_NDS32_SDA16S3,
+
+/* This is a 17-bit reloc containing the small data area 17-bit signed offset
+and shift left by 2 for use in lwi.gp, swi.gp... */
+ BFD_RELOC_NDS32_SDA17S2,
+
+/* This is a 18-bit reloc containing the small data area 18-bit signed offset
+and shift left by 1 for use in lhi.gp, shi.gp... */
+ BFD_RELOC_NDS32_SDA18S1,
+
+/* This is a 19-bit reloc containing the small data area 19-bit signed offset
+and shift left by 0 for use in lbi.gp, sbi.gp... */
+ BFD_RELOC_NDS32_SDA19S0,
+
+/* for PIC */
+ BFD_RELOC_NDS32_GOT20,
+ BFD_RELOC_NDS32_9_PLTREL,
+ BFD_RELOC_NDS32_25_PLTREL,
+ BFD_RELOC_NDS32_COPY,
+ BFD_RELOC_NDS32_GLOB_DAT,
+ BFD_RELOC_NDS32_JMP_SLOT,
+ BFD_RELOC_NDS32_RELATIVE,
+ BFD_RELOC_NDS32_GOTOFF,
+ BFD_RELOC_NDS32_GOTOFF_HI20,
+ BFD_RELOC_NDS32_GOTOFF_LO12,
+ BFD_RELOC_NDS32_GOTPC20,
+ BFD_RELOC_NDS32_GOT_HI20,
+ BFD_RELOC_NDS32_GOT_LO12,
+ BFD_RELOC_NDS32_GOTPC_HI20,
+ BFD_RELOC_NDS32_GOTPC_LO12,
+
+/* for relax */
+ BFD_RELOC_NDS32_INSN16,
+ BFD_RELOC_NDS32_LABEL,
+ BFD_RELOC_NDS32_LONGCALL1,
+ BFD_RELOC_NDS32_LONGCALL2,
+ BFD_RELOC_NDS32_LONGCALL3,
+ BFD_RELOC_NDS32_LONGJUMP1,
+ BFD_RELOC_NDS32_LONGJUMP2,
+ BFD_RELOC_NDS32_LONGJUMP3,
+ BFD_RELOC_NDS32_LOADSTORE,
+ BFD_RELOC_NDS32_9_FIXED,
+ BFD_RELOC_NDS32_15_FIXED,
+ BFD_RELOC_NDS32_17_FIXED,
+ BFD_RELOC_NDS32_25_FIXED,
+ BFD_RELOC_NDS32_LONGCALL4,
+ BFD_RELOC_NDS32_LONGCALL5,
+ BFD_RELOC_NDS32_LONGCALL6,
+ BFD_RELOC_NDS32_LONGJUMP4,
+ BFD_RELOC_NDS32_LONGJUMP5,
+ BFD_RELOC_NDS32_LONGJUMP6,
+ BFD_RELOC_NDS32_LONGJUMP7,
+
+/* for PIC */
+ BFD_RELOC_NDS32_PLTREL_HI20,
+ BFD_RELOC_NDS32_PLTREL_LO12,
+ BFD_RELOC_NDS32_PLT_GOTREL_HI20,
+ BFD_RELOC_NDS32_PLT_GOTREL_LO12,
+
+/* for floating point */
+ BFD_RELOC_NDS32_SDA12S2_DP,
+ BFD_RELOC_NDS32_SDA12S2_SP,
+ BFD_RELOC_NDS32_LO12S2_DP,
+ BFD_RELOC_NDS32_LO12S2_SP,
+
+/* for dwarf2 debug_line. */
+ BFD_RELOC_NDS32_DWARF2_OP1,
+ BFD_RELOC_NDS32_DWARF2_OP2,
+ BFD_RELOC_NDS32_DWARF2_LEB,
+
+/* for eliminate 16-bit instructions */
+ BFD_RELOC_NDS32_UPDATE_TA,
+
+/* for PIC object relaxation */
+ BFD_RELOC_NDS32_PLT_GOTREL_LO20,
+ BFD_RELOC_NDS32_PLT_GOTREL_LO15,
+ BFD_RELOC_NDS32_PLT_GOTREL_LO19,
+ BFD_RELOC_NDS32_GOT_LO15,
+ BFD_RELOC_NDS32_GOT_LO19,
+ BFD_RELOC_NDS32_GOTOFF_LO15,
+ BFD_RELOC_NDS32_GOTOFF_LO19,
+ BFD_RELOC_NDS32_GOT15S2,
+ BFD_RELOC_NDS32_GOT17S2,
+
+/* NDS32 relocs.
+This is a 5 bit absolute address. */
+ BFD_RELOC_NDS32_5,
+
+/* This is a 10-bit unsigned pc-relative reloc with the right 1 bit assumed to be 0. */
+ BFD_RELOC_NDS32_10_UPCREL,
+
+/* If fp were omitted, fp can used as another gp. */
+ BFD_RELOC_NDS32_SDA_FP7U2_RELA,
+
+/* relaxation relative relocation types */
+ BFD_RELOC_NDS32_RELAX_ENTRY,
+ BFD_RELOC_NDS32_GOT_SUFF,
+ BFD_RELOC_NDS32_GOTOFF_SUFF,
+ BFD_RELOC_NDS32_PLT_GOT_SUFF,
+ BFD_RELOC_NDS32_MULCALL_SUFF,
+ BFD_RELOC_NDS32_PTR,
+ BFD_RELOC_NDS32_PTR_COUNT,
+ BFD_RELOC_NDS32_PTR_RESOLVED,
+ BFD_RELOC_NDS32_PLTBLOCK,
+ BFD_RELOC_NDS32_RELAX_REGION_BEGIN,
+ BFD_RELOC_NDS32_RELAX_REGION_END,
+ BFD_RELOC_NDS32_MINUEND,
+ BFD_RELOC_NDS32_SUBTRAHEND,
+ BFD_RELOC_NDS32_DIFF8,
+ BFD_RELOC_NDS32_DIFF16,
+ BFD_RELOC_NDS32_DIFF32,
+ BFD_RELOC_NDS32_DIFF_ULEB128,
+ BFD_RELOC_NDS32_EMPTY,
+
+/* This is a 25 bit absolute address. */
+ BFD_RELOC_NDS32_25_ABS,
+
+/* For ex9 and ifc using. */
+ BFD_RELOC_NDS32_DATA,
+ BFD_RELOC_NDS32_TRAN,
+ BFD_RELOC_NDS32_17IFC_PCREL,
+ BFD_RELOC_NDS32_10IFCU_PCREL,
+
+/* For TLS. */
+ BFD_RELOC_NDS32_TPOFF,
+ BFD_RELOC_NDS32_TLS_LE_HI20,
+ BFD_RELOC_NDS32_TLS_LE_LO12,
+ BFD_RELOC_NDS32_TLS_LE_ADD,
+ BFD_RELOC_NDS32_TLS_LE_LS,
+ BFD_RELOC_NDS32_GOTTPOFF,
+ BFD_RELOC_NDS32_TLS_IE_HI20,
+ BFD_RELOC_NDS32_TLS_IE_LO12S2,
+ BFD_RELOC_NDS32_TLS_TPOFF,
+ BFD_RELOC_NDS32_TLS_LE_20,
+ BFD_RELOC_NDS32_TLS_LE_15S0,
+ BFD_RELOC_NDS32_TLS_LE_15S1,
+ BFD_RELOC_NDS32_TLS_LE_15S2,
+
+/* 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-contiguously 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-contiguously 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,
+
+/* Used for relaxing indirect function calls. */
+ BFD_RELOC_V850_LONGCALL,
+
+/* Used for relaxing indirect jumps. */
+ BFD_RELOC_V850_LONGJUMP,
+
+/* Used to maintain alignment whilst relaxing. */
+ BFD_RELOC_V850_ALIGN,
+
+/* This is a variation of BFD_RELOC_LO16 that can be used in v850e ld.bu
+instructions. */
+ BFD_RELOC_V850_LO16_SPLIT_OFFSET,
+
+/* This is a 16-bit reloc. */
+ BFD_RELOC_V850_16_PCREL,
+
+/* This is a 17-bit reloc. */
+ BFD_RELOC_V850_17_PCREL,
+
+/* This is a 23-bit reloc. */
+ BFD_RELOC_V850_23,
+
+/* This is a 32-bit reloc. */
+ BFD_RELOC_V850_32_PCREL,
+
+/* This is a 32-bit reloc. */
+ BFD_RELOC_V850_32_ABS,
+
+/* This is a 16-bit reloc. */
+ BFD_RELOC_V850_16_SPLIT_OFFSET,
+
+/* This is a 16-bit reloc. */
+ BFD_RELOC_V850_16_S1,
+
+/* Low 16 bits. 16 bit shifted by 1. */
+ BFD_RELOC_V850_LO16_S1,
+
+/* This is a 16 bit offset from the call table base pointer. */
+ BFD_RELOC_V850_CALLT_15_16_OFFSET,
+
+/* DSO relocations. */
+ BFD_RELOC_V850_32_GOTPCREL,
+
+/* DSO relocations. */
+ BFD_RELOC_V850_16_GOT,
+
+/* DSO relocations. */
+ BFD_RELOC_V850_32_GOT,
+
+/* DSO relocations. */
+ BFD_RELOC_V850_22_PLT_PCREL,
+
+/* DSO relocations. */
+ BFD_RELOC_V850_32_PLT_PCREL,
+
+/* DSO relocations. */
+ BFD_RELOC_V850_COPY,
+
+/* DSO relocations. */
+ BFD_RELOC_V850_GLOB_DAT,
+
+/* DSO relocations. */
+ BFD_RELOC_V850_JMP_SLOT,
+
+/* DSO relocations. */
+ BFD_RELOC_V850_RELATIVE,
+
+/* DSO relocations. */
+ BFD_RELOC_V850_16_GOTOFF,
+
+/* DSO relocations. */
+ BFD_RELOC_V850_32_GOTOFF,
+
+/* start code. */
+ BFD_RELOC_V850_CODE,
+
+/* start data in text. */
+ BFD_RELOC_V850_DATA,
+
+/* 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 7bit reloc for the tms320c54x, where the least
+significant 7 bits of a 16 bit word are placed into the least
+significant 7 bits of the opcode. */
+ BFD_RELOC_TIC54X_PARTLS7,
+
+/* This is a 9bit DP reloc for the tms320c54x, where the most
+significant 9 bits of a 16 bit word are placed into the least
+significant 9 bits of the opcode. */
+ BFD_RELOC_TIC54X_PARTMS9,
+
+/* This is an extended address 23-bit reloc for the tms320c54x. */
+ BFD_RELOC_TIC54X_23,
+
+/* This is a 16-bit reloc for the tms320c54x, where the least
+significant 16 bits of a 23-bit extended address are placed into
+the opcode. */
+ BFD_RELOC_TIC54X_16_OF_23,
+
+/* This is a reloc for the tms320c54x, where the most
+significant 7 bits of a 23-bit extended address are placed into
+the opcode. */
+ BFD_RELOC_TIC54X_MS7_OF_23,
+
+/* TMS320C6000 relocations. */
+ BFD_RELOC_C6000_PCR_S21,
+ BFD_RELOC_C6000_PCR_S12,
+ BFD_RELOC_C6000_PCR_S10,
+ BFD_RELOC_C6000_PCR_S7,
+ BFD_RELOC_C6000_ABS_S16,
+ BFD_RELOC_C6000_ABS_L16,
+ BFD_RELOC_C6000_ABS_H16,
+ BFD_RELOC_C6000_SBR_U15_B,
+ BFD_RELOC_C6000_SBR_U15_H,
+ BFD_RELOC_C6000_SBR_U15_W,
+ BFD_RELOC_C6000_SBR_S16,
+ BFD_RELOC_C6000_SBR_L16_B,
+ BFD_RELOC_C6000_SBR_L16_H,
+ BFD_RELOC_C6000_SBR_L16_W,
+ BFD_RELOC_C6000_SBR_H16_B,
+ BFD_RELOC_C6000_SBR_H16_H,
+ BFD_RELOC_C6000_SBR_H16_W,
+ BFD_RELOC_C6000_SBR_GOT_U15_W,
+ BFD_RELOC_C6000_SBR_GOT_L16_W,
+ BFD_RELOC_C6000_SBR_GOT_H16_W,
+ BFD_RELOC_C6000_DSBT_INDEX,
+ BFD_RELOC_C6000_PREL31,
+ BFD_RELOC_C6000_COPY,
+ BFD_RELOC_C6000_JUMP_SLOT,
+ BFD_RELOC_C6000_EHTYPE,
+ BFD_RELOC_C6000_PCR_H16,
+ BFD_RELOC_C6000_PCR_L16,
+ BFD_RELOC_C6000_ALIGN,
+ BFD_RELOC_C6000_FPHEAD,
+ BFD_RELOC_C6000_NOCMP,
+
+/* 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,
+ BFD_RELOC_MCORE_RVA,
+
+/* Toshiba Media Processor Relocations. */
+ BFD_RELOC_MEP_8,
+ BFD_RELOC_MEP_16,
+ BFD_RELOC_MEP_32,
+ BFD_RELOC_MEP_PCREL8A2,
+ BFD_RELOC_MEP_PCREL12A2,
+ BFD_RELOC_MEP_PCREL17A2,
+ BFD_RELOC_MEP_PCREL24A2,
+ BFD_RELOC_MEP_PCABS24A2,
+ BFD_RELOC_MEP_LOW16,
+ BFD_RELOC_MEP_HI16U,
+ BFD_RELOC_MEP_HI16S,
+ BFD_RELOC_MEP_GPREL,
+ BFD_RELOC_MEP_TPREL,
+ BFD_RELOC_MEP_TPREL7,
+ BFD_RELOC_MEP_TPREL7A2,
+ BFD_RELOC_MEP_TPREL7A4,
+ BFD_RELOC_MEP_UIMM24,
+ BFD_RELOC_MEP_ADDR24A4,
+ BFD_RELOC_MEP_GNU_VTINHERIT,
+ BFD_RELOC_MEP_GNU_VTENTRY,
+
+
+/* Imagination Technologies Meta relocations. */
+ BFD_RELOC_METAG_HIADDR16,
+ BFD_RELOC_METAG_LOADDR16,
+ BFD_RELOC_METAG_RELBRANCH,
+ BFD_RELOC_METAG_GETSETOFF,
+ BFD_RELOC_METAG_HIOG,
+ BFD_RELOC_METAG_LOOG,
+ BFD_RELOC_METAG_REL8,
+ BFD_RELOC_METAG_REL16,
+ BFD_RELOC_METAG_HI16_GOTOFF,
+ BFD_RELOC_METAG_LO16_GOTOFF,
+ BFD_RELOC_METAG_GETSET_GOTOFF,
+ BFD_RELOC_METAG_GETSET_GOT,
+ BFD_RELOC_METAG_HI16_GOTPC,
+ BFD_RELOC_METAG_LO16_GOTPC,
+ BFD_RELOC_METAG_HI16_PLT,
+ BFD_RELOC_METAG_LO16_PLT,
+ BFD_RELOC_METAG_RELBRANCH_PLT,
+ BFD_RELOC_METAG_GOTOFF,
+ BFD_RELOC_METAG_PLT,
+ BFD_RELOC_METAG_COPY,
+ BFD_RELOC_METAG_JMP_SLOT,
+ BFD_RELOC_METAG_RELATIVE,
+ BFD_RELOC_METAG_GLOB_DAT,
+ BFD_RELOC_METAG_TLS_GD,
+ BFD_RELOC_METAG_TLS_LDM,
+ BFD_RELOC_METAG_TLS_LDO_HI16,
+ BFD_RELOC_METAG_TLS_LDO_LO16,
+ BFD_RELOC_METAG_TLS_LDO,
+ BFD_RELOC_METAG_TLS_IE,
+ BFD_RELOC_METAG_TLS_IENONPIC,
+ BFD_RELOC_METAG_TLS_IENONPIC_HI16,
+ BFD_RELOC_METAG_TLS_IENONPIC_LO16,
+ BFD_RELOC_METAG_TLS_TPOFF,
+ BFD_RELOC_METAG_TLS_DTPMOD,
+ BFD_RELOC_METAG_TLS_DTPOFF,
+ BFD_RELOC_METAG_TLS_LE,
+ BFD_RELOC_METAG_TLS_LE_HI16,
+ BFD_RELOC_METAG_TLS_LE_LO16,
+
+/* These are relocations for the GETA instruction. */
+ BFD_RELOC_MMIX_GETA,
+ BFD_RELOC_MMIX_GETA_1,
+ BFD_RELOC_MMIX_GETA_2,
+ BFD_RELOC_MMIX_GETA_3,
+
+/* These are relocations for a conditional branch instruction. */
+ BFD_RELOC_MMIX_CBRANCH,
+ BFD_RELOC_MMIX_CBRANCH_J,
+ BFD_RELOC_MMIX_CBRANCH_1,
+ BFD_RELOC_MMIX_CBRANCH_2,
+ BFD_RELOC_MMIX_CBRANCH_3,
+
+/* These are relocations for the PUSHJ instruction. */
+ BFD_RELOC_MMIX_PUSHJ,
+ BFD_RELOC_MMIX_PUSHJ_1,
+ BFD_RELOC_MMIX_PUSHJ_2,
+ BFD_RELOC_MMIX_PUSHJ_3,
+ BFD_RELOC_MMIX_PUSHJ_STUBBABLE,
+
+/* These are relocations for the JMP instruction. */
+ BFD_RELOC_MMIX_JMP,
+ BFD_RELOC_MMIX_JMP_1,
+ BFD_RELOC_MMIX_JMP_2,
+ BFD_RELOC_MMIX_JMP_3,
+
+/* This is a relocation for a relative address as in a GETA instruction or
+a branch. */
+ BFD_RELOC_MMIX_ADDR19,
+
+/* This is a relocation for a relative address as in a JMP instruction. */
+ BFD_RELOC_MMIX_ADDR27,
+
+/* This is a relocation for an instruction field that may be a general
+register or a value 0..255. */
+ BFD_RELOC_MMIX_REG_OR_BYTE,
+
+/* This is a relocation for an instruction field that may be a general
+register. */
+ BFD_RELOC_MMIX_REG,
+
+/* This is a relocation for two instruction fields holding a register and
+an offset, the equivalent of the relocation. */
+ BFD_RELOC_MMIX_BASE_PLUS_OFFSET,
+
+/* This relocation is an assertion that the expression is not allocated as
+a global register. It does not modify contents. */
+ BFD_RELOC_MMIX_LOCAL,
+
+/* This is a 16 bit reloc for the AVR that stores 8 bit pc relative
+short offset into 7 bits. */
+ BFD_RELOC_AVR_7_PCREL,
+
+/* This is a 16 bit reloc for the AVR that stores 13 bit pc relative
+short offset into 12 bits. */
+ BFD_RELOC_AVR_13_PCREL,
+
+/* This is a 16 bit reloc for the AVR that stores 17 bit value (usually
+program memory address) into 16 bits. */
+ BFD_RELOC_AVR_16_PM,
+
+/* This is a 16 bit reloc for the AVR that stores 8 bit value (usually
+data memory address) into 8 bit immediate value of LDI insn. */
+ BFD_RELOC_AVR_LO8_LDI,
+
+/* This is a 16 bit reloc for the AVR that stores 8 bit value (high 8 bit
+of data memory address) into 8 bit immediate value of LDI insn. */
+ BFD_RELOC_AVR_HI8_LDI,
+
+/* This is a 16 bit reloc for the AVR that stores 8 bit value (most high 8 bit
+of program memory address) into 8 bit immediate value of LDI insn. */
+ BFD_RELOC_AVR_HH8_LDI,
+
+/* This is a 16 bit reloc for the AVR that stores 8 bit value (most high 8 bit
+of 32 bit value) into 8 bit immediate value of LDI insn. */
+ BFD_RELOC_AVR_MS8_LDI,
+
+/* This is a 16 bit reloc for the AVR that stores negated 8 bit value
+(usually data memory address) into 8 bit immediate value of SUBI insn. */
+ BFD_RELOC_AVR_LO8_LDI_NEG,
+
+/* This is a 16 bit reloc for the AVR that stores negated 8 bit value
+(high 8 bit of data memory address) into 8 bit immediate value of
+SUBI insn. */
+ BFD_RELOC_AVR_HI8_LDI_NEG,
+
+/* This is a 16 bit reloc for the AVR that stores negated 8 bit value
+(most high 8 bit of program memory address) into 8 bit immediate value
+of LDI or SUBI insn. */
+ BFD_RELOC_AVR_HH8_LDI_NEG,
+
+/* This is a 16 bit reloc for the AVR that stores negated 8 bit value (msb
+of 32 bit value) into 8 bit immediate value of LDI insn. */
+ BFD_RELOC_AVR_MS8_LDI_NEG,
+
+/* This is a 16 bit reloc for the AVR that stores 8 bit value (usually
+command address) into 8 bit immediate value of LDI insn. */
+ BFD_RELOC_AVR_LO8_LDI_PM,
+
+/* This is a 16 bit reloc for the AVR that stores 8 bit value
+(command address) into 8 bit immediate value of LDI insn. If the address
+is beyond the 128k boundary, the linker inserts a jump stub for this reloc
+in the lower 128k. */
+ BFD_RELOC_AVR_LO8_LDI_GS,
+
+/* This is a 16 bit reloc for the AVR that stores 8 bit value (high 8 bit
+of command address) into 8 bit immediate value of LDI insn. */
+ BFD_RELOC_AVR_HI8_LDI_PM,
+
+/* This is a 16 bit reloc for the AVR that stores 8 bit value (high 8 bit
+of command address) into 8 bit immediate value of LDI insn. If the address
+is beyond the 128k boundary, the linker inserts a jump stub for this reloc
+below 128k. */
+ BFD_RELOC_AVR_HI8_LDI_GS,
+
+/* This is a 16 bit reloc for the AVR that stores 8 bit value (most high 8 bit
+of command address) into 8 bit immediate value of LDI insn. */
+ BFD_RELOC_AVR_HH8_LDI_PM,
+
+/* This is a 16 bit reloc for the AVR that stores negated 8 bit value
+(usually command address) into 8 bit immediate value of SUBI insn. */
+ BFD_RELOC_AVR_LO8_LDI_PM_NEG,
+
+/* This is a 16 bit reloc for the AVR that stores negated 8 bit value
+(high 8 bit of 16 bit command address) into 8 bit immediate value
+of SUBI insn. */
+ BFD_RELOC_AVR_HI8_LDI_PM_NEG,
+
+/* This is a 16 bit reloc for the AVR that stores negated 8 bit value
+(high 6 bit of 22 bit command address) into 8 bit immediate
+value of SUBI insn. */
+ BFD_RELOC_AVR_HH8_LDI_PM_NEG,
+
+/* This is a 32 bit reloc for the AVR that stores 23 bit value
+into 22 bits. */
+ BFD_RELOC_AVR_CALL,
+
+/* This is a 16 bit reloc for the AVR that stores all needed bits
+for absolute addressing with ldi with overflow check to linktime */
+ BFD_RELOC_AVR_LDI,
+
+/* This is a 6 bit reloc for the AVR that stores offset for ldd/std
+instructions */
+ BFD_RELOC_AVR_6,
+
+/* This is a 6 bit reloc for the AVR that stores offset for adiw/sbiw
+instructions */
+ BFD_RELOC_AVR_6_ADIW,
+
+/* This is a 8 bit reloc for the AVR that stores bits 0..7 of a symbol
+in .byte lo8(symbol) */
+ BFD_RELOC_AVR_8_LO,
+
+/* This is a 8 bit reloc for the AVR that stores bits 8..15 of a symbol
+in .byte hi8(symbol) */
+ BFD_RELOC_AVR_8_HI,
+
+/* This is a 8 bit reloc for the AVR that stores bits 16..23 of a symbol
+in .byte hlo8(symbol) */
+ BFD_RELOC_AVR_8_HLO,
+
+/* AVR relocations to mark the difference of two local symbols.
+These are only needed to support linker relaxation and can be ignored
+when not relaxing. The field is set to the value of the difference
+assuming no relaxation. The relocation encodes the position of the
+second symbol so the linker can determine whether to adjust the field
+value. */
+ BFD_RELOC_AVR_DIFF8,
+ BFD_RELOC_AVR_DIFF16,
+ BFD_RELOC_AVR_DIFF32,
+
+/* This is a 7 bit reloc for the AVR that stores SRAM address for 16bit
+lds and sts instructions supported only tiny core. */
+ BFD_RELOC_AVR_LDS_STS_16,
+
+/* This is a 6 bit reloc for the AVR that stores an I/O register
+number for the IN and OUT instructions */
+ BFD_RELOC_AVR_PORT6,
+
+/* This is a 5 bit reloc for the AVR that stores an I/O register
+number for the SBIC, SBIS, SBI and CBI instructions */
+ BFD_RELOC_AVR_PORT5,
+
+/* Renesas RL78 Relocations. */
+ BFD_RELOC_RL78_NEG8,
+ BFD_RELOC_RL78_NEG16,
+ BFD_RELOC_RL78_NEG24,
+ BFD_RELOC_RL78_NEG32,
+ BFD_RELOC_RL78_16_OP,
+ BFD_RELOC_RL78_24_OP,
+ BFD_RELOC_RL78_32_OP,
+ BFD_RELOC_RL78_8U,
+ BFD_RELOC_RL78_16U,
+ BFD_RELOC_RL78_24U,
+ BFD_RELOC_RL78_DIR3U_PCREL,
+ BFD_RELOC_RL78_DIFF,
+ BFD_RELOC_RL78_GPRELB,
+ BFD_RELOC_RL78_GPRELW,
+ BFD_RELOC_RL78_GPRELL,
+ BFD_RELOC_RL78_SYM,
+ BFD_RELOC_RL78_OP_SUBTRACT,
+ BFD_RELOC_RL78_OP_NEG,
+ BFD_RELOC_RL78_OP_AND,
+ BFD_RELOC_RL78_OP_SHRA,
+ BFD_RELOC_RL78_ABS8,
+ BFD_RELOC_RL78_ABS16,
+ BFD_RELOC_RL78_ABS16_REV,
+ BFD_RELOC_RL78_ABS32,
+ BFD_RELOC_RL78_ABS32_REV,
+ BFD_RELOC_RL78_ABS16U,
+ BFD_RELOC_RL78_ABS16UW,
+ BFD_RELOC_RL78_ABS16UL,
+ BFD_RELOC_RL78_RELAX,
+ BFD_RELOC_RL78_HI16,
+ BFD_RELOC_RL78_HI8,
+ BFD_RELOC_RL78_LO16,
+ BFD_RELOC_RL78_CODE,
+
+/* Renesas RX Relocations. */
+ BFD_RELOC_RX_NEG8,
+ BFD_RELOC_RX_NEG16,
+ BFD_RELOC_RX_NEG24,
+ BFD_RELOC_RX_NEG32,
+ BFD_RELOC_RX_16_OP,
+ BFD_RELOC_RX_24_OP,
+ BFD_RELOC_RX_32_OP,
+ BFD_RELOC_RX_8U,
+ BFD_RELOC_RX_16U,
+ BFD_RELOC_RX_24U,
+ BFD_RELOC_RX_DIR3U_PCREL,
+ BFD_RELOC_RX_DIFF,
+ BFD_RELOC_RX_GPRELB,
+ BFD_RELOC_RX_GPRELW,
+ BFD_RELOC_RX_GPRELL,
+ BFD_RELOC_RX_SYM,
+ BFD_RELOC_RX_OP_SUBTRACT,
+ BFD_RELOC_RX_OP_NEG,
+ BFD_RELOC_RX_ABS8,
+ BFD_RELOC_RX_ABS16,
+ BFD_RELOC_RX_ABS16_REV,
+ BFD_RELOC_RX_ABS32,
+ BFD_RELOC_RX_ABS32_REV,
+ BFD_RELOC_RX_ABS16U,
+ BFD_RELOC_RX_ABS16UW,
+ BFD_RELOC_RX_ABS16UL,
+ BFD_RELOC_RX_RELAX,
+
+/* Direct 12 bit. */
+ BFD_RELOC_390_12,
+
+/* 12 bit GOT offset. */
+ BFD_RELOC_390_GOT12,
+
+/* 32 bit PC relative PLT address. */
+ BFD_RELOC_390_PLT32,
+
+/* Copy symbol at runtime. */
+ BFD_RELOC_390_COPY,
+
+/* Create GOT entry. */
+ BFD_RELOC_390_GLOB_DAT,
+
+/* Create PLT entry. */
+ BFD_RELOC_390_JMP_SLOT,
+
+/* Adjust by program base. */
+ BFD_RELOC_390_RELATIVE,
+
+/* 32 bit PC relative offset to GOT. */
+ BFD_RELOC_390_GOTPC,
+
+/* 16 bit GOT offset. */
+ BFD_RELOC_390_GOT16,
+
+/* PC relative 12 bit shifted by 1. */
+ BFD_RELOC_390_PC12DBL,
+
+/* 12 bit PC rel. PLT shifted by 1. */
+ BFD_RELOC_390_PLT12DBL,
+
+/* PC relative 16 bit shifted by 1. */
+ BFD_RELOC_390_PC16DBL,
+
+/* 16 bit PC rel. PLT shifted by 1. */
+ BFD_RELOC_390_PLT16DBL,
+
+/* PC relative 24 bit shifted by 1. */
+ BFD_RELOC_390_PC24DBL,
+
+/* 24 bit PC rel. PLT shifted by 1. */
+ BFD_RELOC_390_PLT24DBL,
+
+/* PC relative 32 bit shifted by 1. */
+ BFD_RELOC_390_PC32DBL,
+
+/* 32 bit PC rel. PLT shifted by 1. */
+ BFD_RELOC_390_PLT32DBL,
+
+/* 32 bit PC rel. GOT shifted by 1. */
+ BFD_RELOC_390_GOTPCDBL,
+
+/* 64 bit GOT offset. */
+ BFD_RELOC_390_GOT64,
+
+/* 64 bit PC relative PLT address. */
+ BFD_RELOC_390_PLT64,
+
+/* 32 bit rel. offset to GOT entry. */
+ BFD_RELOC_390_GOTENT,
+
+/* 64 bit offset to GOT. */
+ BFD_RELOC_390_GOTOFF64,
+
+/* 12-bit offset to symbol-entry within GOT, with PLT handling. */
+ BFD_RELOC_390_GOTPLT12,
+
+/* 16-bit offset to symbol-entry within GOT, with PLT handling. */
+ BFD_RELOC_390_GOTPLT16,
+
+/* 32-bit offset to symbol-entry within GOT, with PLT handling. */
+ BFD_RELOC_390_GOTPLT32,
+
+/* 64-bit offset to symbol-entry within GOT, with PLT handling. */
+ BFD_RELOC_390_GOTPLT64,
+
+/* 32-bit rel. offset to symbol-entry within GOT, with PLT handling. */
+ BFD_RELOC_390_GOTPLTENT,
+
+/* 16-bit rel. offset from the GOT to a PLT entry. */
+ BFD_RELOC_390_PLTOFF16,
+
+/* 32-bit rel. offset from the GOT to a PLT entry. */
+ BFD_RELOC_390_PLTOFF32,
+
+/* 64-bit rel. offset from the GOT to a PLT entry. */
+ BFD_RELOC_390_PLTOFF64,
+
+/* s390 tls relocations. */
+ BFD_RELOC_390_TLS_LOAD,
+ BFD_RELOC_390_TLS_GDCALL,
+ BFD_RELOC_390_TLS_LDCALL,
+ BFD_RELOC_390_TLS_GD32,
+ BFD_RELOC_390_TLS_GD64,
+ BFD_RELOC_390_TLS_GOTIE12,
+ BFD_RELOC_390_TLS_GOTIE32,
+ BFD_RELOC_390_TLS_GOTIE64,
+ BFD_RELOC_390_TLS_LDM32,
+ BFD_RELOC_390_TLS_LDM64,
+ BFD_RELOC_390_TLS_IE32,
+ BFD_RELOC_390_TLS_IE64,
+ BFD_RELOC_390_TLS_IEENT,
+ BFD_RELOC_390_TLS_LE32,
+ BFD_RELOC_390_TLS_LE64,
+ BFD_RELOC_390_TLS_LDO32,
+ BFD_RELOC_390_TLS_LDO64,
+ BFD_RELOC_390_TLS_DTPMOD,
+ BFD_RELOC_390_TLS_DTPOFF,
+ BFD_RELOC_390_TLS_TPOFF,
+
+/* Long displacement extension. */
+ BFD_RELOC_390_20,
+ BFD_RELOC_390_GOT20,
+ BFD_RELOC_390_GOTPLT20,
+ BFD_RELOC_390_TLS_GOTIE20,
+
+/* STT_GNU_IFUNC relocation. */
+ BFD_RELOC_390_IRELATIVE,
+
+/* Score relocations
+Low 16 bit for load/store */
+ BFD_RELOC_SCORE_GPREL15,
+
+/* This is a 24-bit reloc with the right 1 bit assumed to be 0 */
+ BFD_RELOC_SCORE_DUMMY2,
+ BFD_RELOC_SCORE_JMP,
+
+/* This is a 19-bit reloc with the right 1 bit assumed to be 0 */
+ BFD_RELOC_SCORE_BRANCH,
+
+/* This is a 32-bit reloc for 48-bit instructions. */
+ BFD_RELOC_SCORE_IMM30,
+
+/* This is a 32-bit reloc for 48-bit instructions. */
+ BFD_RELOC_SCORE_IMM32,
+
+/* This is a 11-bit reloc with the right 1 bit assumed to be 0 */
+ BFD_RELOC_SCORE16_JMP,
+
+/* This is a 8-bit reloc with the right 1 bit assumed to be 0 */
+ BFD_RELOC_SCORE16_BRANCH,
+
+/* This is a 9-bit reloc with the right 1 bit assumed to be 0 */
+ BFD_RELOC_SCORE_BCMP,
+
+/* Undocumented Score relocs */
+ BFD_RELOC_SCORE_GOT15,
+ BFD_RELOC_SCORE_GOT_LO16,
+ BFD_RELOC_SCORE_CALL15,
+ BFD_RELOC_SCORE_DUMMY_HI16,
+
+/* Scenix IP2K - 9-bit register number / data address */
+ BFD_RELOC_IP2K_FR9,
+
+/* Scenix IP2K - 4-bit register/data bank number */
+ BFD_RELOC_IP2K_BANK,
+
+/* Scenix IP2K - low 13 bits of instruction word address */
+ BFD_RELOC_IP2K_ADDR16CJP,
+
+/* Scenix IP2K - high 3 bits of instruction word address */
+ BFD_RELOC_IP2K_PAGE3,
+
+/* Scenix IP2K - ext/low/high 8 bits of data address */
+ BFD_RELOC_IP2K_LO8DATA,
+ BFD_RELOC_IP2K_HI8DATA,
+ BFD_RELOC_IP2K_EX8DATA,
+
+/* Scenix IP2K - low/high 8 bits of instruction word address */
+ BFD_RELOC_IP2K_LO8INSN,
+ BFD_RELOC_IP2K_HI8INSN,
+
+/* Scenix IP2K - even/odd PC modifier to modify snb pcl.0 */
+ BFD_RELOC_IP2K_PC_SKIP,
+
+/* Scenix IP2K - 16 bit word address in text section. */
+ BFD_RELOC_IP2K_TEXT,
+
+/* Scenix IP2K - 7-bit sp or dp offset */
+ BFD_RELOC_IP2K_FR_OFFSET,
+
+/* Scenix VPE4K coprocessor - data/insn-space addressing */
+ BFD_RELOC_VPE4KMATH_DATA,
+ BFD_RELOC_VPE4KMATH_INSN,
+
+/* 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 inheritance 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,
+
+/* Intel IA64 Relocations. */
+ BFD_RELOC_IA64_IMM14,
+ BFD_RELOC_IA64_IMM22,
+ BFD_RELOC_IA64_IMM64,
+ BFD_RELOC_IA64_DIR32MSB,
+ BFD_RELOC_IA64_DIR32LSB,
+ BFD_RELOC_IA64_DIR64MSB,
+ BFD_RELOC_IA64_DIR64LSB,
+ BFD_RELOC_IA64_GPREL22,
+ BFD_RELOC_IA64_GPREL64I,
+ BFD_RELOC_IA64_GPREL32MSB,
+ BFD_RELOC_IA64_GPREL32LSB,
+ BFD_RELOC_IA64_GPREL64MSB,
+ BFD_RELOC_IA64_GPREL64LSB,
+ BFD_RELOC_IA64_LTOFF22,
+ BFD_RELOC_IA64_LTOFF64I,
+ BFD_RELOC_IA64_PLTOFF22,
+ BFD_RELOC_IA64_PLTOFF64I,
+ BFD_RELOC_IA64_PLTOFF64MSB,
+ BFD_RELOC_IA64_PLTOFF64LSB,
+ BFD_RELOC_IA64_FPTR64I,
+ BFD_RELOC_IA64_FPTR32MSB,
+ BFD_RELOC_IA64_FPTR32LSB,
+ BFD_RELOC_IA64_FPTR64MSB,
+ BFD_RELOC_IA64_FPTR64LSB,
+ BFD_RELOC_IA64_PCREL21B,
+ BFD_RELOC_IA64_PCREL21BI,
+ BFD_RELOC_IA64_PCREL21M,
+ BFD_RELOC_IA64_PCREL21F,
+ BFD_RELOC_IA64_PCREL22,
+ BFD_RELOC_IA64_PCREL60B,
+ BFD_RELOC_IA64_PCREL64I,
+ BFD_RELOC_IA64_PCREL32MSB,
+ BFD_RELOC_IA64_PCREL32LSB,
+ BFD_RELOC_IA64_PCREL64MSB,
+ BFD_RELOC_IA64_PCREL64LSB,
+ BFD_RELOC_IA64_LTOFF_FPTR22,
+ BFD_RELOC_IA64_LTOFF_FPTR64I,
+ BFD_RELOC_IA64_LTOFF_FPTR32MSB,
+ BFD_RELOC_IA64_LTOFF_FPTR32LSB,
+ BFD_RELOC_IA64_LTOFF_FPTR64MSB,
+ BFD_RELOC_IA64_LTOFF_FPTR64LSB,
+ BFD_RELOC_IA64_SEGREL32MSB,
+ BFD_RELOC_IA64_SEGREL32LSB,
+ BFD_RELOC_IA64_SEGREL64MSB,
+ BFD_RELOC_IA64_SEGREL64LSB,
+ BFD_RELOC_IA64_SECREL32MSB,
+ BFD_RELOC_IA64_SECREL32LSB,
+ BFD_RELOC_IA64_SECREL64MSB,
+ BFD_RELOC_IA64_SECREL64LSB,
+ BFD_RELOC_IA64_REL32MSB,
+ BFD_RELOC_IA64_REL32LSB,
+ BFD_RELOC_IA64_REL64MSB,
+ BFD_RELOC_IA64_REL64LSB,
+ BFD_RELOC_IA64_LTV32MSB,
+ BFD_RELOC_IA64_LTV32LSB,
+ BFD_RELOC_IA64_LTV64MSB,
+ BFD_RELOC_IA64_LTV64LSB,
+ BFD_RELOC_IA64_IPLTMSB,
+ BFD_RELOC_IA64_IPLTLSB,
+ BFD_RELOC_IA64_COPY,
+ BFD_RELOC_IA64_LTOFF22X,
+ BFD_RELOC_IA64_LDXMOV,
+ BFD_RELOC_IA64_TPREL14,
+ BFD_RELOC_IA64_TPREL22,
+ BFD_RELOC_IA64_TPREL64I,
+ BFD_RELOC_IA64_TPREL64MSB,
+ BFD_RELOC_IA64_TPREL64LSB,
+ BFD_RELOC_IA64_LTOFF_TPREL22,
+ BFD_RELOC_IA64_DTPMOD64MSB,
+ BFD_RELOC_IA64_DTPMOD64LSB,
+ BFD_RELOC_IA64_LTOFF_DTPMOD22,
+ BFD_RELOC_IA64_DTPREL14,
+ BFD_RELOC_IA64_DTPREL22,
+ BFD_RELOC_IA64_DTPREL64I,
+ BFD_RELOC_IA64_DTPREL32MSB,
+ BFD_RELOC_IA64_DTPREL32LSB,
+ BFD_RELOC_IA64_DTPREL64MSB,
+ BFD_RELOC_IA64_DTPREL64LSB,
+ BFD_RELOC_IA64_LTOFF_DTPREL22,
+
+/* Motorola 68HC11 reloc.
+This is the 8 bit high part of an absolute address. */
+ BFD_RELOC_M68HC11_HI8,
+
+/* Motorola 68HC11 reloc.
+This is the 8 bit low part of an absolute address. */
+ BFD_RELOC_M68HC11_LO8,
+
+/* Motorola 68HC11 reloc.
+This is the 3 bit of a value. */
+ BFD_RELOC_M68HC11_3B,
+
+/* Motorola 68HC11 reloc.
+This reloc marks the beginning of a jump/call instruction.
+It is used for linker relaxation to correctly identify beginning
+of instruction and change some branches to use PC-relative
+addressing mode. */
+ BFD_RELOC_M68HC11_RL_JUMP,
+
+/* Motorola 68HC11 reloc.
+This reloc marks a group of several instructions that gcc generates
+and for which the linker relaxation pass can modify and/or remove
+some of them. */
+ BFD_RELOC_M68HC11_RL_GROUP,
+
+/* Motorola 68HC11 reloc.
+This is the 16-bit lower part of an address. It is used for 'call'
+instruction to specify the symbol address without any special
+transformation (due to memory bank window). */
+ BFD_RELOC_M68HC11_LO16,
+
+/* Motorola 68HC11 reloc.
+This is a 8-bit reloc that specifies the page number of an address.
+It is used by 'call' instruction to specify the page number of
+the symbol. */
+ BFD_RELOC_M68HC11_PAGE,
+
+/* Motorola 68HC11 reloc.
+This is a 24-bit reloc that represents the address with a 16-bit
+value and a 8-bit page number. The symbol address is transformed
+to follow the 16K memory bank of 68HC12 (seen as mapped in the window). */
+ BFD_RELOC_M68HC11_24,
+
+/* Motorola 68HC12 reloc.
+This is the 5 bits of a value. */
+ BFD_RELOC_M68HC12_5B,
+
+/* Freescale XGATE reloc.
+This reloc marks the beginning of a bra/jal instruction. */
+ BFD_RELOC_XGATE_RL_JUMP,
+
+/* Freescale XGATE reloc.
+This reloc marks a group of several instructions that gcc generates
+and for which the linker relaxation pass can modify and/or remove
+some of them. */
+ BFD_RELOC_XGATE_RL_GROUP,
+
+/* Freescale XGATE reloc.
+This is the 16-bit lower part of an address. It is used for the '16-bit'
+instructions. */
+ BFD_RELOC_XGATE_LO16,
+
+/* Freescale XGATE reloc. */
+ BFD_RELOC_XGATE_GPAGE,
+
+/* Freescale XGATE reloc. */
+ BFD_RELOC_XGATE_24,
+
+/* Freescale XGATE reloc.
+This is a 9-bit pc-relative reloc. */
+ BFD_RELOC_XGATE_PCREL_9,
+
+/* Freescale XGATE reloc.
+This is a 10-bit pc-relative reloc. */
+ BFD_RELOC_XGATE_PCREL_10,
+
+/* Freescale XGATE reloc.
+This is the 16-bit lower part of an address. It is used for the '16-bit'
+instructions. */
+ BFD_RELOC_XGATE_IMM8_LO,
+
+/* Freescale XGATE reloc.
+This is the 16-bit higher part of an address. It is used for the '16-bit'
+instructions. */
+ BFD_RELOC_XGATE_IMM8_HI,
+
+/* Freescale XGATE reloc.
+This is a 3-bit pc-relative reloc. */
+ BFD_RELOC_XGATE_IMM3,
+
+/* Freescale XGATE reloc.
+This is a 4-bit pc-relative reloc. */
+ BFD_RELOC_XGATE_IMM4,
+
+/* Freescale XGATE reloc.
+This is a 5-bit pc-relative reloc. */
+ BFD_RELOC_XGATE_IMM5,
+
+/* Motorola 68HC12 reloc.
+This is the 9 bits of a value. */
+ BFD_RELOC_M68HC12_9B,
+
+/* Motorola 68HC12 reloc.
+This is the 16 bits of a value. */
+ BFD_RELOC_M68HC12_16B,
+
+/* Motorola 68HC12/XGATE reloc.
+This is a PCREL9 branch. */
+ BFD_RELOC_M68HC12_9_PCREL,
+
+/* Motorola 68HC12/XGATE reloc.
+This is a PCREL10 branch. */
+ BFD_RELOC_M68HC12_10_PCREL,
+
+/* Motorola 68HC12/XGATE reloc.
+This is the 8 bit low part of an absolute address and immediately precedes
+a matching HI8XG part. */
+ BFD_RELOC_M68HC12_LO8XG,
+
+/* Motorola 68HC12/XGATE reloc.
+This is the 8 bit high part of an absolute address and immediately follows
+a matching LO8XG part. */
+ BFD_RELOC_M68HC12_HI8XG,
+
+/* NS CR16C Relocations. */
+ BFD_RELOC_16C_NUM08,
+ BFD_RELOC_16C_NUM08_C,
+ BFD_RELOC_16C_NUM16,
+ BFD_RELOC_16C_NUM16_C,
+ BFD_RELOC_16C_NUM32,
+ BFD_RELOC_16C_NUM32_C,
+ BFD_RELOC_16C_DISP04,
+ BFD_RELOC_16C_DISP04_C,
+ BFD_RELOC_16C_DISP08,
+ BFD_RELOC_16C_DISP08_C,
+ BFD_RELOC_16C_DISP16,
+ BFD_RELOC_16C_DISP16_C,
+ BFD_RELOC_16C_DISP24,
+ BFD_RELOC_16C_DISP24_C,
+ BFD_RELOC_16C_DISP24a,
+ BFD_RELOC_16C_DISP24a_C,
+ BFD_RELOC_16C_REG04,
+ BFD_RELOC_16C_REG04_C,
+ BFD_RELOC_16C_REG04a,
+ BFD_RELOC_16C_REG04a_C,
+ BFD_RELOC_16C_REG14,
+ BFD_RELOC_16C_REG14_C,
+ BFD_RELOC_16C_REG16,
+ BFD_RELOC_16C_REG16_C,
+ BFD_RELOC_16C_REG20,
+ BFD_RELOC_16C_REG20_C,
+ BFD_RELOC_16C_ABS20,
+ BFD_RELOC_16C_ABS20_C,
+ BFD_RELOC_16C_ABS24,
+ BFD_RELOC_16C_ABS24_C,
+ BFD_RELOC_16C_IMM04,
+ BFD_RELOC_16C_IMM04_C,
+ BFD_RELOC_16C_IMM16,
+ BFD_RELOC_16C_IMM16_C,
+ BFD_RELOC_16C_IMM20,
+ BFD_RELOC_16C_IMM20_C,
+ BFD_RELOC_16C_IMM24,
+ BFD_RELOC_16C_IMM24_C,
+ BFD_RELOC_16C_IMM32,
+ BFD_RELOC_16C_IMM32_C,
+
+/* NS CR16 Relocations. */
+ BFD_RELOC_CR16_NUM8,
+ BFD_RELOC_CR16_NUM16,
+ BFD_RELOC_CR16_NUM32,
+ BFD_RELOC_CR16_NUM32a,
+ BFD_RELOC_CR16_REGREL0,
+ BFD_RELOC_CR16_REGREL4,
+ BFD_RELOC_CR16_REGREL4a,
+ BFD_RELOC_CR16_REGREL14,
+ BFD_RELOC_CR16_REGREL14a,
+ BFD_RELOC_CR16_REGREL16,
+ BFD_RELOC_CR16_REGREL20,
+ BFD_RELOC_CR16_REGREL20a,
+ BFD_RELOC_CR16_ABS20,
+ BFD_RELOC_CR16_ABS24,
+ BFD_RELOC_CR16_IMM4,
+ BFD_RELOC_CR16_IMM8,
+ BFD_RELOC_CR16_IMM16,
+ BFD_RELOC_CR16_IMM20,
+ BFD_RELOC_CR16_IMM24,
+ BFD_RELOC_CR16_IMM32,
+ BFD_RELOC_CR16_IMM32a,
+ BFD_RELOC_CR16_DISP4,
+ BFD_RELOC_CR16_DISP8,
+ BFD_RELOC_CR16_DISP16,
+ BFD_RELOC_CR16_DISP20,
+ BFD_RELOC_CR16_DISP24,
+ BFD_RELOC_CR16_DISP24a,
+ BFD_RELOC_CR16_SWITCH8,
+ BFD_RELOC_CR16_SWITCH16,
+ BFD_RELOC_CR16_SWITCH32,
+ BFD_RELOC_CR16_GOT_REGREL20,
+ BFD_RELOC_CR16_GOTC_REGREL20,
+ BFD_RELOC_CR16_GLOB_DAT,
+
+/* NS CRX Relocations. */
+ BFD_RELOC_CRX_REL4,
+ BFD_RELOC_CRX_REL8,
+ BFD_RELOC_CRX_REL8_CMP,
+ BFD_RELOC_CRX_REL16,
+ BFD_RELOC_CRX_REL24,
+ BFD_RELOC_CRX_REL32,
+ BFD_RELOC_CRX_REGREL12,
+ BFD_RELOC_CRX_REGREL22,
+ BFD_RELOC_CRX_REGREL28,
+ BFD_RELOC_CRX_REGREL32,
+ BFD_RELOC_CRX_ABS16,
+ BFD_RELOC_CRX_ABS32,
+ BFD_RELOC_CRX_NUM8,
+ BFD_RELOC_CRX_NUM16,
+ BFD_RELOC_CRX_NUM32,
+ BFD_RELOC_CRX_IMM16,
+ BFD_RELOC_CRX_IMM32,
+ BFD_RELOC_CRX_SWITCH8,
+ BFD_RELOC_CRX_SWITCH16,
+ BFD_RELOC_CRX_SWITCH32,
+
+/* These relocs are only used within the CRIS assembler. They are not
+(at present) written to any object files. */
+ BFD_RELOC_CRIS_BDISP8,
+ BFD_RELOC_CRIS_UNSIGNED_5,
+ BFD_RELOC_CRIS_SIGNED_6,
+ BFD_RELOC_CRIS_UNSIGNED_6,
+ BFD_RELOC_CRIS_SIGNED_8,
+ BFD_RELOC_CRIS_UNSIGNED_8,
+ BFD_RELOC_CRIS_SIGNED_16,
+ BFD_RELOC_CRIS_UNSIGNED_16,
+ BFD_RELOC_CRIS_LAPCQ_OFFSET,
+ BFD_RELOC_CRIS_UNSIGNED_4,
+
+/* Relocs used in ELF shared libraries for CRIS. */
+ BFD_RELOC_CRIS_COPY,
+ BFD_RELOC_CRIS_GLOB_DAT,
+ BFD_RELOC_CRIS_JUMP_SLOT,
+ BFD_RELOC_CRIS_RELATIVE,
+
+/* 32-bit offset to symbol-entry within GOT. */
+ BFD_RELOC_CRIS_32_GOT,
+
+/* 16-bit offset to symbol-entry within GOT. */
+ BFD_RELOC_CRIS_16_GOT,
+
+/* 32-bit offset to symbol-entry within GOT, with PLT handling. */
+ BFD_RELOC_CRIS_32_GOTPLT,
+
+/* 16-bit offset to symbol-entry within GOT, with PLT handling. */
+ BFD_RELOC_CRIS_16_GOTPLT,
+
+/* 32-bit offset to symbol, relative to GOT. */
+ BFD_RELOC_CRIS_32_GOTREL,
+
+/* 32-bit offset to symbol with PLT entry, relative to GOT. */
+ BFD_RELOC_CRIS_32_PLT_GOTREL,
+
+/* 32-bit offset to symbol with PLT entry, relative to this relocation. */
+ BFD_RELOC_CRIS_32_PLT_PCREL,
+
+/* Relocs used in TLS code for CRIS. */
+ BFD_RELOC_CRIS_32_GOT_GD,
+ BFD_RELOC_CRIS_16_GOT_GD,
+ BFD_RELOC_CRIS_32_GD,
+ BFD_RELOC_CRIS_DTP,
+ BFD_RELOC_CRIS_32_DTPREL,
+ BFD_RELOC_CRIS_16_DTPREL,
+ BFD_RELOC_CRIS_32_GOT_TPREL,
+ BFD_RELOC_CRIS_16_GOT_TPREL,
+ BFD_RELOC_CRIS_32_TPREL,
+ BFD_RELOC_CRIS_16_TPREL,
+ BFD_RELOC_CRIS_DTPMOD,
+ BFD_RELOC_CRIS_32_IE,
+
+/* Intel i860 Relocations. */
+ BFD_RELOC_860_COPY,
+ BFD_RELOC_860_GLOB_DAT,
+ BFD_RELOC_860_JUMP_SLOT,
+ BFD_RELOC_860_RELATIVE,
+ BFD_RELOC_860_PC26,
+ BFD_RELOC_860_PLT26,
+ BFD_RELOC_860_PC16,
+ BFD_RELOC_860_LOW0,
+ BFD_RELOC_860_SPLIT0,
+ BFD_RELOC_860_LOW1,
+ BFD_RELOC_860_SPLIT1,
+ BFD_RELOC_860_LOW2,
+ BFD_RELOC_860_SPLIT2,
+ BFD_RELOC_860_LOW3,
+ BFD_RELOC_860_LOGOT0,
+ BFD_RELOC_860_SPGOT0,
+ BFD_RELOC_860_LOGOT1,
+ BFD_RELOC_860_SPGOT1,
+ BFD_RELOC_860_LOGOTOFF0,
+ BFD_RELOC_860_SPGOTOFF0,
+ BFD_RELOC_860_LOGOTOFF1,
+ BFD_RELOC_860_SPGOTOFF1,
+ BFD_RELOC_860_LOGOTOFF2,
+ BFD_RELOC_860_LOGOTOFF3,
+ BFD_RELOC_860_LOPC,
+ BFD_RELOC_860_HIGHADJ,
+ BFD_RELOC_860_HAGOT,
+ BFD_RELOC_860_HAGOTOFF,
+ BFD_RELOC_860_HAPC,
+ BFD_RELOC_860_HIGH,
+ BFD_RELOC_860_HIGOT,
+ BFD_RELOC_860_HIGOTOFF,
+
+/* OpenRISC 1000 Relocations. */
+ BFD_RELOC_OR1K_REL_26,
+ BFD_RELOC_OR1K_GOTPC_HI16,
+ BFD_RELOC_OR1K_GOTPC_LO16,
+ BFD_RELOC_OR1K_GOT16,
+ BFD_RELOC_OR1K_PLT26,
+ BFD_RELOC_OR1K_GOTOFF_HI16,
+ BFD_RELOC_OR1K_GOTOFF_LO16,
+ BFD_RELOC_OR1K_COPY,
+ BFD_RELOC_OR1K_GLOB_DAT,
+ BFD_RELOC_OR1K_JMP_SLOT,
+ BFD_RELOC_OR1K_RELATIVE,
+ BFD_RELOC_OR1K_TLS_GD_HI16,
+ BFD_RELOC_OR1K_TLS_GD_LO16,
+ BFD_RELOC_OR1K_TLS_LDM_HI16,
+ BFD_RELOC_OR1K_TLS_LDM_LO16,
+ BFD_RELOC_OR1K_TLS_LDO_HI16,
+ BFD_RELOC_OR1K_TLS_LDO_LO16,
+ BFD_RELOC_OR1K_TLS_IE_HI16,
+ BFD_RELOC_OR1K_TLS_IE_LO16,
+ BFD_RELOC_OR1K_TLS_LE_HI16,
+ BFD_RELOC_OR1K_TLS_LE_LO16,
+ BFD_RELOC_OR1K_TLS_TPOFF,
+ BFD_RELOC_OR1K_TLS_DTPOFF,
+ BFD_RELOC_OR1K_TLS_DTPMOD,
+
+/* H8 elf Relocations. */
+ BFD_RELOC_H8_DIR16A8,
+ BFD_RELOC_H8_DIR16R8,
+ BFD_RELOC_H8_DIR24A8,
+ BFD_RELOC_H8_DIR24R8,
+ BFD_RELOC_H8_DIR32A16,
+ BFD_RELOC_H8_DISP32A16,
+
+/* Sony Xstormy16 Relocations. */
+ BFD_RELOC_XSTORMY16_REL_12,
+ BFD_RELOC_XSTORMY16_12,
+ BFD_RELOC_XSTORMY16_24,
+ BFD_RELOC_XSTORMY16_FPTR16,
+
+/* Self-describing complex relocations. */
+ BFD_RELOC_RELC,
+
+
+/* Infineon Relocations. */
+ BFD_RELOC_XC16X_PAG,
+ BFD_RELOC_XC16X_POF,
+ BFD_RELOC_XC16X_SEG,
+ BFD_RELOC_XC16X_SOF,
+
+/* Relocations used by VAX ELF. */
+ BFD_RELOC_VAX_GLOB_DAT,
+ BFD_RELOC_VAX_JMP_SLOT,
+ BFD_RELOC_VAX_RELATIVE,
+
+/* Morpho MT - 16 bit immediate relocation. */
+ BFD_RELOC_MT_PC16,
+
+/* Morpho MT - Hi 16 bits of an address. */
+ BFD_RELOC_MT_HI16,
+
+/* Morpho MT - Low 16 bits of an address. */
+ BFD_RELOC_MT_LO16,
+
+/* Morpho MT - Used to tell the linker which vtable entries are used. */
+ BFD_RELOC_MT_GNU_VTINHERIT,
+
+/* Morpho MT - Used to tell the linker which vtable entries are used. */
+ BFD_RELOC_MT_GNU_VTENTRY,
+
+/* Morpho MT - 8 bit immediate relocation. */
+ BFD_RELOC_MT_PCINSN8,
+
+/* msp430 specific relocation codes */
+ BFD_RELOC_MSP430_10_PCREL,
+ BFD_RELOC_MSP430_16_PCREL,
+ BFD_RELOC_MSP430_16,
+ BFD_RELOC_MSP430_16_PCREL_BYTE,
+ BFD_RELOC_MSP430_16_BYTE,
+ BFD_RELOC_MSP430_2X_PCREL,
+ BFD_RELOC_MSP430_RL_PCREL,
+ BFD_RELOC_MSP430_ABS8,
+ BFD_RELOC_MSP430X_PCR20_EXT_SRC,
+ BFD_RELOC_MSP430X_PCR20_EXT_DST,
+ BFD_RELOC_MSP430X_PCR20_EXT_ODST,
+ BFD_RELOC_MSP430X_ABS20_EXT_SRC,
+ BFD_RELOC_MSP430X_ABS20_EXT_DST,
+ BFD_RELOC_MSP430X_ABS20_EXT_ODST,
+ BFD_RELOC_MSP430X_ABS20_ADR_SRC,
+ BFD_RELOC_MSP430X_ABS20_ADR_DST,
+ BFD_RELOC_MSP430X_PCR16,
+ BFD_RELOC_MSP430X_PCR20_CALL,
+ BFD_RELOC_MSP430X_ABS16,
+ BFD_RELOC_MSP430_ABS_HI16,
+ BFD_RELOC_MSP430_PREL31,
+ BFD_RELOC_MSP430_SYM_DIFF,
+
+/* Relocations used by the Altera Nios II core. */
+ BFD_RELOC_NIOS2_S16,
+ BFD_RELOC_NIOS2_U16,
+ BFD_RELOC_NIOS2_CALL26,
+ BFD_RELOC_NIOS2_IMM5,
+ BFD_RELOC_NIOS2_CACHE_OPX,
+ BFD_RELOC_NIOS2_IMM6,
+ BFD_RELOC_NIOS2_IMM8,
+ BFD_RELOC_NIOS2_HI16,
+ BFD_RELOC_NIOS2_LO16,
+ BFD_RELOC_NIOS2_HIADJ16,
+ BFD_RELOC_NIOS2_GPREL,
+ BFD_RELOC_NIOS2_UJMP,
+ BFD_RELOC_NIOS2_CJMP,
+ BFD_RELOC_NIOS2_CALLR,
+ BFD_RELOC_NIOS2_ALIGN,
+ BFD_RELOC_NIOS2_GOT16,
+ BFD_RELOC_NIOS2_CALL16,
+ BFD_RELOC_NIOS2_GOTOFF_LO,
+ BFD_RELOC_NIOS2_GOTOFF_HA,
+ BFD_RELOC_NIOS2_PCREL_LO,
+ BFD_RELOC_NIOS2_PCREL_HA,
+ BFD_RELOC_NIOS2_TLS_GD16,
+ BFD_RELOC_NIOS2_TLS_LDM16,
+ BFD_RELOC_NIOS2_TLS_LDO16,
+ BFD_RELOC_NIOS2_TLS_IE16,
+ BFD_RELOC_NIOS2_TLS_LE16,
+ BFD_RELOC_NIOS2_TLS_DTPMOD,
+ BFD_RELOC_NIOS2_TLS_DTPREL,
+ BFD_RELOC_NIOS2_TLS_TPREL,
+ BFD_RELOC_NIOS2_COPY,
+ BFD_RELOC_NIOS2_GLOB_DAT,
+ BFD_RELOC_NIOS2_JUMP_SLOT,
+ BFD_RELOC_NIOS2_RELATIVE,
+ BFD_RELOC_NIOS2_GOTOFF,
+ BFD_RELOC_NIOS2_CALL26_NOAT,
+ BFD_RELOC_NIOS2_GOT_LO,
+ BFD_RELOC_NIOS2_GOT_HA,
+ BFD_RELOC_NIOS2_CALL_LO,
+ BFD_RELOC_NIOS2_CALL_HA,
+
+/* IQ2000 Relocations. */
+ BFD_RELOC_IQ2000_OFFSET_16,
+ BFD_RELOC_IQ2000_OFFSET_21,
+ BFD_RELOC_IQ2000_UHI16,
+
+/* Special Xtensa relocation used only by PLT entries in ELF shared
+objects to indicate that the runtime linker should set the value
+to one of its own internal functions or data structures. */
+ BFD_RELOC_XTENSA_RTLD,
+
+/* Xtensa relocations for ELF shared objects. */
+ BFD_RELOC_XTENSA_GLOB_DAT,
+ BFD_RELOC_XTENSA_JMP_SLOT,
+ BFD_RELOC_XTENSA_RELATIVE,
+
+/* Xtensa relocation used in ELF object files for symbols that may require
+PLT entries. Otherwise, this is just a generic 32-bit relocation. */
+ BFD_RELOC_XTENSA_PLT,
+
+/* Xtensa relocations to mark the difference of two local symbols.
+These are only needed to support linker relaxation and can be ignored
+when not relaxing. The field is set to the value of the difference
+assuming no relaxation. The relocation encodes the position of the
+first symbol so the linker can determine whether to adjust the field
+value. */
+ BFD_RELOC_XTENSA_DIFF8,
+ BFD_RELOC_XTENSA_DIFF16,
+ BFD_RELOC_XTENSA_DIFF32,
+
+/* Generic Xtensa relocations for instruction operands. Only the slot
+number is encoded in the relocation. The relocation applies to the
+last PC-relative immediate operand, or if there are no PC-relative
+immediates, to the last immediate operand. */
+ BFD_RELOC_XTENSA_SLOT0_OP,
+ BFD_RELOC_XTENSA_SLOT1_OP,
+ BFD_RELOC_XTENSA_SLOT2_OP,
+ BFD_RELOC_XTENSA_SLOT3_OP,
+ BFD_RELOC_XTENSA_SLOT4_OP,
+ BFD_RELOC_XTENSA_SLOT5_OP,
+ BFD_RELOC_XTENSA_SLOT6_OP,
+ BFD_RELOC_XTENSA_SLOT7_OP,
+ BFD_RELOC_XTENSA_SLOT8_OP,
+ BFD_RELOC_XTENSA_SLOT9_OP,
+ BFD_RELOC_XTENSA_SLOT10_OP,
+ BFD_RELOC_XTENSA_SLOT11_OP,
+ BFD_RELOC_XTENSA_SLOT12_OP,
+ BFD_RELOC_XTENSA_SLOT13_OP,
+ BFD_RELOC_XTENSA_SLOT14_OP,
+
+/* Alternate Xtensa relocations. Only the slot is encoded in the
+relocation. The meaning of these relocations is opcode-specific. */
+ BFD_RELOC_XTENSA_SLOT0_ALT,
+ BFD_RELOC_XTENSA_SLOT1_ALT,
+ BFD_RELOC_XTENSA_SLOT2_ALT,
+ BFD_RELOC_XTENSA_SLOT3_ALT,
+ BFD_RELOC_XTENSA_SLOT4_ALT,
+ BFD_RELOC_XTENSA_SLOT5_ALT,
+ BFD_RELOC_XTENSA_SLOT6_ALT,
+ BFD_RELOC_XTENSA_SLOT7_ALT,
+ BFD_RELOC_XTENSA_SLOT8_ALT,
+ BFD_RELOC_XTENSA_SLOT9_ALT,
+ BFD_RELOC_XTENSA_SLOT10_ALT,
+ BFD_RELOC_XTENSA_SLOT11_ALT,
+ BFD_RELOC_XTENSA_SLOT12_ALT,
+ BFD_RELOC_XTENSA_SLOT13_ALT,
+ BFD_RELOC_XTENSA_SLOT14_ALT,
+
+/* Xtensa relocations for backward compatibility. These have all been
+replaced by BFD_RELOC_XTENSA_SLOT0_OP. */
+ BFD_RELOC_XTENSA_OP0,
+ BFD_RELOC_XTENSA_OP1,
+ BFD_RELOC_XTENSA_OP2,
+
+/* Xtensa relocation to mark that the assembler expanded the
+instructions from an original target. The expansion size is
+encoded in the reloc size. */
+ BFD_RELOC_XTENSA_ASM_EXPAND,
+
+/* Xtensa relocation to mark that the linker should simplify
+assembler-expanded instructions. This is commonly used
+internally by the linker after analysis of a
+BFD_RELOC_XTENSA_ASM_EXPAND. */
+ BFD_RELOC_XTENSA_ASM_SIMPLIFY,
+
+/* Xtensa TLS relocations. */
+ BFD_RELOC_XTENSA_TLSDESC_FN,
+ BFD_RELOC_XTENSA_TLSDESC_ARG,
+ BFD_RELOC_XTENSA_TLS_DTPOFF,
+ BFD_RELOC_XTENSA_TLS_TPOFF,
+ BFD_RELOC_XTENSA_TLS_FUNC,
+ BFD_RELOC_XTENSA_TLS_ARG,
+ BFD_RELOC_XTENSA_TLS_CALL,
+
+/* 8 bit signed offset in (ix+d) or (iy+d). */
+ BFD_RELOC_Z80_DISP8,
+
+/* DJNZ offset. */
+ BFD_RELOC_Z8K_DISP7,
+
+/* CALR offset. */
+ BFD_RELOC_Z8K_CALLR,
+
+/* 4 bit value. */
+ BFD_RELOC_Z8K_IMM4L,
+
+/* Lattice Mico32 relocations. */
+ BFD_RELOC_LM32_CALL,
+ BFD_RELOC_LM32_BRANCH,
+ BFD_RELOC_LM32_16_GOT,
+ BFD_RELOC_LM32_GOTOFF_HI16,
+ BFD_RELOC_LM32_GOTOFF_LO16,
+ BFD_RELOC_LM32_COPY,
+ BFD_RELOC_LM32_GLOB_DAT,
+ BFD_RELOC_LM32_JMP_SLOT,
+ BFD_RELOC_LM32_RELATIVE,
+
+/* Difference between two section addreses. Must be followed by a
+BFD_RELOC_MACH_O_PAIR. */
+ BFD_RELOC_MACH_O_SECTDIFF,
+
+/* Like BFD_RELOC_MACH_O_SECTDIFF but with a local symbol. */
+ BFD_RELOC_MACH_O_LOCAL_SECTDIFF,
+
+/* Pair of relocation. Contains the first symbol. */
+ BFD_RELOC_MACH_O_PAIR,
+
+/* PCREL relocations. They are marked as branch to create PLT entry if
+required. */
+ BFD_RELOC_MACH_O_X86_64_BRANCH32,
+ BFD_RELOC_MACH_O_X86_64_BRANCH8,
+
+/* Used when referencing a GOT entry. */
+ BFD_RELOC_MACH_O_X86_64_GOT,
+
+/* Used when loading a GOT entry with movq. It is specially marked so that
+the linker could optimize the movq to a leaq if possible. */
+ BFD_RELOC_MACH_O_X86_64_GOT_LOAD,
+
+/* Symbol will be substracted. Must be followed by a BFD_RELOC_64. */
+ BFD_RELOC_MACH_O_X86_64_SUBTRACTOR32,
+
+/* Symbol will be substracted. Must be followed by a BFD_RELOC_64. */
+ BFD_RELOC_MACH_O_X86_64_SUBTRACTOR64,
+
+/* Same as BFD_RELOC_32_PCREL but with an implicit -1 addend. */
+ BFD_RELOC_MACH_O_X86_64_PCREL32_1,
+
+/* Same as BFD_RELOC_32_PCREL but with an implicit -2 addend. */
+ BFD_RELOC_MACH_O_X86_64_PCREL32_2,
+
+/* Same as BFD_RELOC_32_PCREL but with an implicit -4 addend. */
+ BFD_RELOC_MACH_O_X86_64_PCREL32_4,
+
+/* This is a 32 bit reloc for the microblaze that stores the
+low 16 bits of a value */
+ BFD_RELOC_MICROBLAZE_32_LO,
+
+/* This is a 32 bit pc-relative reloc for the microblaze that
+stores the low 16 bits of a value */
+ BFD_RELOC_MICROBLAZE_32_LO_PCREL,
+
+/* This is a 32 bit reloc for the microblaze that stores a
+value relative to the read-only small data area anchor */
+ BFD_RELOC_MICROBLAZE_32_ROSDA,
+
+/* This is a 32 bit reloc for the microblaze that stores a
+value relative to the read-write small data area anchor */
+ BFD_RELOC_MICROBLAZE_32_RWSDA,
+
+/* This is a 32 bit reloc for the microblaze to handle
+expressions of the form "Symbol Op Symbol" */
+ BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM,
+
+/* This is a 64 bit reloc that stores the 32 bit pc relative
+value in two words (with an imm instruction). No relocation is
+done here - only used for relaxing */
+ BFD_RELOC_MICROBLAZE_64_NONE,
+
+/* This is a 64 bit reloc that stores the 32 bit pc relative
+value in two words (with an imm instruction). The relocation is
+PC-relative GOT offset */
+ BFD_RELOC_MICROBLAZE_64_GOTPC,
+
+/* This is a 64 bit reloc that stores the 32 bit pc relative
+value in two words (with an imm instruction). The relocation is
+GOT offset */
+ BFD_RELOC_MICROBLAZE_64_GOT,
+
+/* This is a 64 bit reloc that stores the 32 bit pc relative
+value in two words (with an imm instruction). The relocation is
+PC-relative offset into PLT */
+ BFD_RELOC_MICROBLAZE_64_PLT,
+
+/* This is a 64 bit reloc that stores the 32 bit GOT relative
+value in two words (with an imm instruction). The relocation is
+relative offset from _GLOBAL_OFFSET_TABLE_ */
+ BFD_RELOC_MICROBLAZE_64_GOTOFF,
+
+/* This is a 32 bit reloc that stores the 32 bit GOT relative
+value in a word. The relocation is relative offset from */
+ BFD_RELOC_MICROBLAZE_32_GOTOFF,
+
+/* This is used to tell the dynamic linker to copy the value out of
+the dynamic object into the runtime process image. */
+ BFD_RELOC_MICROBLAZE_COPY,
+
+/* Unused Reloc */
+ BFD_RELOC_MICROBLAZE_64_TLS,
+
+/* This is a 64 bit reloc that stores the 32 bit GOT relative value
+of the GOT TLS GD info entry in two words (with an imm instruction). The
+relocation is GOT offset. */
+ BFD_RELOC_MICROBLAZE_64_TLSGD,
+
+/* This is a 64 bit reloc that stores the 32 bit GOT relative value
+of the GOT TLS LD info entry in two words (with an imm instruction). The
+relocation is GOT offset. */
+ BFD_RELOC_MICROBLAZE_64_TLSLD,
+
+/* This is a 32 bit reloc that stores the Module ID to GOT(n). */
+ BFD_RELOC_MICROBLAZE_32_TLSDTPMOD,
+
+/* This is a 32 bit reloc that stores TLS offset to GOT(n+1). */
+ BFD_RELOC_MICROBLAZE_32_TLSDTPREL,
+
+/* This is a 32 bit reloc for storing TLS offset to two words (uses imm
+instruction) */
+ BFD_RELOC_MICROBLAZE_64_TLSDTPREL,
+
+/* This is a 64 bit reloc that stores 32-bit thread pointer relative offset
+to two words (uses imm instruction). */
+ BFD_RELOC_MICROBLAZE_64_TLSGOTTPREL,
+
+/* This is a 64 bit reloc that stores 32-bit thread pointer relative offset
+to two words (uses imm instruction). */
+ BFD_RELOC_MICROBLAZE_64_TLSTPREL,
+
+/* AArch64 pseudo relocation code to mark the start of the AArch64
+relocation enumerators. N.B. the order of the enumerators is
+important as several tables in the AArch64 bfd backend are indexed
+by these enumerators; make sure they are all synced. */
+ BFD_RELOC_AARCH64_RELOC_START,
+
+/* AArch64 null relocation code. */
+ BFD_RELOC_AARCH64_NONE,
+
+/* Basic absolute relocations of N bits. These are equivalent to
+BFD_RELOC_N and they were added to assist the indexing of the howto
+table. */
+ BFD_RELOC_AARCH64_64,
+ BFD_RELOC_AARCH64_32,
+ BFD_RELOC_AARCH64_16,
+
+/* PC-relative relocations. These are equivalent to BFD_RELOC_N_PCREL
+and they were added to assist the indexing of the howto table. */
+ BFD_RELOC_AARCH64_64_PCREL,
+ BFD_RELOC_AARCH64_32_PCREL,
+ BFD_RELOC_AARCH64_16_PCREL,
+
+/* AArch64 MOV[NZK] instruction with most significant bits 0 to 15
+of an unsigned address/value. */
+ BFD_RELOC_AARCH64_MOVW_G0,
+
+/* AArch64 MOV[NZK] instruction with less significant bits 0 to 15 of
+an address/value. No overflow checking. */
+ BFD_RELOC_AARCH64_MOVW_G0_NC,
+
+/* AArch64 MOV[NZK] instruction with most significant bits 16 to 31
+of an unsigned address/value. */
+ BFD_RELOC_AARCH64_MOVW_G1,
+
+/* AArch64 MOV[NZK] instruction with less significant bits 16 to 31
+of an address/value. No overflow checking. */
+ BFD_RELOC_AARCH64_MOVW_G1_NC,
+
+/* AArch64 MOV[NZK] instruction with most significant bits 32 to 47
+of an unsigned address/value. */
+ BFD_RELOC_AARCH64_MOVW_G2,
+
+/* AArch64 MOV[NZK] instruction with less significant bits 32 to 47
+of an address/value. No overflow checking. */
+ BFD_RELOC_AARCH64_MOVW_G2_NC,
+
+/* AArch64 MOV[NZK] instruction with most signficant bits 48 to 64
+of a signed or unsigned address/value. */
+ BFD_RELOC_AARCH64_MOVW_G3,
+
+/* AArch64 MOV[NZ] instruction with most significant bits 0 to 15
+of a signed value. Changes instruction to MOVZ or MOVN depending on the
+value's sign. */
+ BFD_RELOC_AARCH64_MOVW_G0_S,
+
+/* AArch64 MOV[NZ] instruction with most significant bits 16 to 31
+of a signed value. Changes instruction to MOVZ or MOVN depending on the
+value's sign. */
+ BFD_RELOC_AARCH64_MOVW_G1_S,
+
+/* AArch64 MOV[NZ] instruction with most significant bits 32 to 47
+of a signed value. Changes instruction to MOVZ or MOVN depending on the
+value's sign. */
+ BFD_RELOC_AARCH64_MOVW_G2_S,
+
+/* AArch64 Load Literal instruction, holding a 19 bit pc-relative word
+offset. The lowest two bits must be zero and are not stored in the
+instruction, giving a 21 bit signed byte offset. */
+ BFD_RELOC_AARCH64_LD_LO19_PCREL,
+
+/* AArch64 ADR instruction, holding a simple 21 bit pc-relative byte offset. */
+ BFD_RELOC_AARCH64_ADR_LO21_PCREL,
+
+/* AArch64 ADRP instruction, with bits 12 to 32 of a pc-relative page
+offset, giving a 4KB aligned page base address. */
+ BFD_RELOC_AARCH64_ADR_HI21_PCREL,
+
+/* AArch64 ADRP instruction, with bits 12 to 32 of a pc-relative page
+offset, giving a 4KB aligned page base address, but with no overflow
+checking. */
+ BFD_RELOC_AARCH64_ADR_HI21_NC_PCREL,
+
+/* AArch64 ADD immediate instruction, holding bits 0 to 11 of the address.
+Used in conjunction with BFD_RELOC_AARCH64_ADR_HI21_PCREL. */
+ BFD_RELOC_AARCH64_ADD_LO12,
+
+/* AArch64 8-bit load/store instruction, holding bits 0 to 11 of the
+address. Used in conjunction with BFD_RELOC_AARCH64_ADR_HI21_PCREL. */
+ BFD_RELOC_AARCH64_LDST8_LO12,
+
+/* AArch64 14 bit pc-relative test bit and branch.
+The lowest two bits must be zero and are not stored in the instruction,
+giving a 16 bit signed byte offset. */
+ BFD_RELOC_AARCH64_TSTBR14,
+
+/* AArch64 19 bit pc-relative conditional branch and compare & branch.
+The lowest two bits must be zero and are not stored in the instruction,
+giving a 21 bit signed byte offset. */
+ BFD_RELOC_AARCH64_BRANCH19,
+
+/* AArch64 26 bit pc-relative unconditional branch.
+The lowest two bits must be zero and are not stored in the instruction,
+giving a 28 bit signed byte offset. */
+ BFD_RELOC_AARCH64_JUMP26,
+
+/* AArch64 26 bit pc-relative unconditional branch and link.
+The lowest two bits must be zero and are not stored in the instruction,
+giving a 28 bit signed byte offset. */
+ BFD_RELOC_AARCH64_CALL26,
+
+/* AArch64 16-bit load/store instruction, holding bits 0 to 11 of the
+address. Used in conjunction with BFD_RELOC_AARCH64_ADR_HI21_PCREL. */
+ BFD_RELOC_AARCH64_LDST16_LO12,
+
+/* AArch64 32-bit load/store instruction, holding bits 0 to 11 of the
+address. Used in conjunction with BFD_RELOC_AARCH64_ADR_HI21_PCREL. */
+ BFD_RELOC_AARCH64_LDST32_LO12,
+
+/* AArch64 64-bit load/store instruction, holding bits 0 to 11 of the
+address. Used in conjunction with BFD_RELOC_AARCH64_ADR_HI21_PCREL. */
+ BFD_RELOC_AARCH64_LDST64_LO12,
+
+/* AArch64 128-bit load/store instruction, holding bits 0 to 11 of the
+address. Used in conjunction with BFD_RELOC_AARCH64_ADR_HI21_PCREL. */
+ BFD_RELOC_AARCH64_LDST128_LO12,
+
+/* AArch64 Load Literal instruction, holding a 19 bit PC relative word
+offset of the global offset table entry for a symbol. The lowest two
+bits must be zero and are not stored in the instruction, giving a 21
+bit signed byte offset. This relocation type requires signed overflow
+checking. */
+ BFD_RELOC_AARCH64_GOT_LD_PREL19,
+
+/* Get to the page base of the global offset table entry for a symbol as
+part of an ADRP instruction using a 21 bit PC relative value.Used in
+conjunction with BFD_RELOC_AARCH64_LD64_GOT_LO12_NC. */
+ BFD_RELOC_AARCH64_ADR_GOT_PAGE,
+
+/* Unsigned 12 bit byte offset for 64 bit load/store from the page of
+the GOT entry for this symbol. Used in conjunction with
+BFD_RELOC_AARCH64_ADR_GOTPAGE. Valid in LP64 ABI only. */
+ BFD_RELOC_AARCH64_LD64_GOT_LO12_NC,
+
+/* Unsigned 12 bit byte offset for 32 bit load/store from the page of
+the GOT entry for this symbol. Used in conjunction with
+BFD_RELOC_AARCH64_ADR_GOTPAGE. Valid in ILP32 ABI only. */
+ BFD_RELOC_AARCH64_LD32_GOT_LO12_NC,
+
+/* Get to the page base of the global offset table entry for a symbols
+tls_index structure as part of an adrp instruction using a 21 bit PC
+relative value. Used in conjunction with
+BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC. */
+ BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21,
+
+/* Unsigned 12 bit byte offset to global offset table entry for a symbols
+tls_index structure. Used in conjunction with
+BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21. */
+ BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC,
+
+/* AArch64 TLS INITIAL EXEC relocation. */
+ BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G1,
+
+/* AArch64 TLS INITIAL EXEC relocation. */
+ BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC,
+
+/* AArch64 TLS INITIAL EXEC relocation. */
+ BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21,
+
+/* AArch64 TLS INITIAL EXEC relocation. */
+ BFD_RELOC_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC,
+
+/* AArch64 TLS INITIAL EXEC relocation. */
+ BFD_RELOC_AARCH64_TLSIE_LD32_GOTTPREL_LO12_NC,
+
+/* AArch64 TLS INITIAL EXEC relocation. */
+ BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19,
+
+/* AArch64 TLS LOCAL EXEC relocation. */
+ BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G2,
+
+/* AArch64 TLS LOCAL EXEC relocation. */
+ BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1,
+
+/* AArch64 TLS LOCAL EXEC relocation. */
+ BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1_NC,
+
+/* AArch64 TLS LOCAL EXEC relocation. */
+ BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0,
+
+/* AArch64 TLS LOCAL EXEC relocation. */
+ BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC,
+
+/* AArch64 TLS LOCAL EXEC relocation. */
+ BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_HI12,
+
+/* AArch64 TLS LOCAL EXEC relocation. */
+ BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12,
+
+/* AArch64 TLS LOCAL EXEC relocation. */
+ BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12_NC,
+
+/* AArch64 TLS DESC relocation. */
+ BFD_RELOC_AARCH64_TLSDESC_LD_PREL19,
+
+/* AArch64 TLS DESC relocation. */
+ BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21,
+
+/* AArch64 TLS DESC relocation. */
+ BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21,
+
+/* AArch64 TLS DESC relocation. */
+ BFD_RELOC_AARCH64_TLSDESC_LD64_LO12_NC,
+
+/* AArch64 TLS DESC relocation. */
+ BFD_RELOC_AARCH64_TLSDESC_LD32_LO12_NC,
+
+/* AArch64 TLS DESC relocation. */
+ BFD_RELOC_AARCH64_TLSDESC_ADD_LO12_NC,
+
+/* AArch64 TLS DESC relocation. */
+ BFD_RELOC_AARCH64_TLSDESC_OFF_G1,
+
+/* AArch64 TLS DESC relocation. */
+ BFD_RELOC_AARCH64_TLSDESC_OFF_G0_NC,
+
+/* AArch64 TLS DESC relocation. */
+ BFD_RELOC_AARCH64_TLSDESC_LDR,
+
+/* AArch64 TLS DESC relocation. */
+ BFD_RELOC_AARCH64_TLSDESC_ADD,
+
+/* AArch64 TLS DESC relocation. */
+ BFD_RELOC_AARCH64_TLSDESC_CALL,
+
+/* AArch64 TLS relocation. */
+ BFD_RELOC_AARCH64_COPY,
+
+/* AArch64 TLS relocation. */
+ BFD_RELOC_AARCH64_GLOB_DAT,
+
+/* AArch64 TLS relocation. */
+ BFD_RELOC_AARCH64_JUMP_SLOT,
+
+/* AArch64 TLS relocation. */
+ BFD_RELOC_AARCH64_RELATIVE,
+
+/* AArch64 TLS relocation. */
+ BFD_RELOC_AARCH64_TLS_DTPMOD,
+
+/* AArch64 TLS relocation. */
+ BFD_RELOC_AARCH64_TLS_DTPREL,
+
+/* AArch64 TLS relocation. */
+ BFD_RELOC_AARCH64_TLS_TPREL,
+
+/* AArch64 TLS relocation. */
+ BFD_RELOC_AARCH64_TLSDESC,
+
+/* AArch64 support for STT_GNU_IFUNC. */
+ BFD_RELOC_AARCH64_IRELATIVE,
+
+/* AArch64 pseudo relocation code to mark the end of the AArch64
+relocation enumerators that have direct mapping to ELF reloc codes.
+There are a few more enumerators after this one; those are mainly
+used by the AArch64 assembler for the internal fixup or to select
+one of the above enumerators. */
+ BFD_RELOC_AARCH64_RELOC_END,
+
+/* AArch64 pseudo relocation code to be used internally by the AArch64
+assembler and not (currently) written to any object files. */
+ BFD_RELOC_AARCH64_GAS_INTERNAL_FIXUP,
+
+/* AArch64 unspecified load/store instruction, holding bits 0 to 11 of the
+address. Used in conjunction with BFD_RELOC_AARCH64_ADR_HI21_PCREL. */
+ BFD_RELOC_AARCH64_LDST_LO12,
+
+/* AArch64 pseudo relocation code to be used internally by the AArch64
+assembler and not (currently) written to any object files. */
+ BFD_RELOC_AARCH64_LD_GOT_LO12_NC,
+
+/* AArch64 pseudo relocation code to be used internally by the AArch64
+assembler and not (currently) written to any object files. */
+ BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_LO12_NC,
+
+/* AArch64 pseudo relocation code to be used internally by the AArch64
+assembler and not (currently) written to any object files. */
+ BFD_RELOC_AARCH64_TLSDESC_LD_LO12_NC,
+
+/* Tilera TILEPro Relocations. */
+ BFD_RELOC_TILEPRO_COPY,
+ BFD_RELOC_TILEPRO_GLOB_DAT,
+ BFD_RELOC_TILEPRO_JMP_SLOT,
+ BFD_RELOC_TILEPRO_RELATIVE,
+ BFD_RELOC_TILEPRO_BROFF_X1,
+ BFD_RELOC_TILEPRO_JOFFLONG_X1,
+ BFD_RELOC_TILEPRO_JOFFLONG_X1_PLT,
+ BFD_RELOC_TILEPRO_IMM8_X0,
+ BFD_RELOC_TILEPRO_IMM8_Y0,
+ BFD_RELOC_TILEPRO_IMM8_X1,
+ BFD_RELOC_TILEPRO_IMM8_Y1,
+ BFD_RELOC_TILEPRO_DEST_IMM8_X1,
+ BFD_RELOC_TILEPRO_MT_IMM15_X1,
+ BFD_RELOC_TILEPRO_MF_IMM15_X1,
+ BFD_RELOC_TILEPRO_IMM16_X0,
+ BFD_RELOC_TILEPRO_IMM16_X1,
+ BFD_RELOC_TILEPRO_IMM16_X0_LO,
+ BFD_RELOC_TILEPRO_IMM16_X1_LO,
+ BFD_RELOC_TILEPRO_IMM16_X0_HI,
+ BFD_RELOC_TILEPRO_IMM16_X1_HI,
+ BFD_RELOC_TILEPRO_IMM16_X0_HA,
+ BFD_RELOC_TILEPRO_IMM16_X1_HA,
+ BFD_RELOC_TILEPRO_IMM16_X0_PCREL,
+ BFD_RELOC_TILEPRO_IMM16_X1_PCREL,
+ BFD_RELOC_TILEPRO_IMM16_X0_LO_PCREL,
+ BFD_RELOC_TILEPRO_IMM16_X1_LO_PCREL,
+ BFD_RELOC_TILEPRO_IMM16_X0_HI_PCREL,
+ BFD_RELOC_TILEPRO_IMM16_X1_HI_PCREL,
+ BFD_RELOC_TILEPRO_IMM16_X0_HA_PCREL,
+ BFD_RELOC_TILEPRO_IMM16_X1_HA_PCREL,
+ BFD_RELOC_TILEPRO_IMM16_X0_GOT,
+ BFD_RELOC_TILEPRO_IMM16_X1_GOT,
+ BFD_RELOC_TILEPRO_IMM16_X0_GOT_LO,
+ BFD_RELOC_TILEPRO_IMM16_X1_GOT_LO,
+ BFD_RELOC_TILEPRO_IMM16_X0_GOT_HI,
+ BFD_RELOC_TILEPRO_IMM16_X1_GOT_HI,
+ BFD_RELOC_TILEPRO_IMM16_X0_GOT_HA,
+ BFD_RELOC_TILEPRO_IMM16_X1_GOT_HA,
+ BFD_RELOC_TILEPRO_MMSTART_X0,
+ BFD_RELOC_TILEPRO_MMEND_X0,
+ BFD_RELOC_TILEPRO_MMSTART_X1,
+ BFD_RELOC_TILEPRO_MMEND_X1,
+ BFD_RELOC_TILEPRO_SHAMT_X0,
+ BFD_RELOC_TILEPRO_SHAMT_X1,
+ BFD_RELOC_TILEPRO_SHAMT_Y0,
+ BFD_RELOC_TILEPRO_SHAMT_Y1,
+ BFD_RELOC_TILEPRO_TLS_GD_CALL,
+ BFD_RELOC_TILEPRO_IMM8_X0_TLS_GD_ADD,
+ BFD_RELOC_TILEPRO_IMM8_X1_TLS_GD_ADD,
+ BFD_RELOC_TILEPRO_IMM8_Y0_TLS_GD_ADD,
+ BFD_RELOC_TILEPRO_IMM8_Y1_TLS_GD_ADD,
+ BFD_RELOC_TILEPRO_TLS_IE_LOAD,
+ BFD_RELOC_TILEPRO_IMM16_X0_TLS_GD,
+ BFD_RELOC_TILEPRO_IMM16_X1_TLS_GD,
+ BFD_RELOC_TILEPRO_IMM16_X0_TLS_GD_LO,
+ BFD_RELOC_TILEPRO_IMM16_X1_TLS_GD_LO,
+ BFD_RELOC_TILEPRO_IMM16_X0_TLS_GD_HI,
+ BFD_RELOC_TILEPRO_IMM16_X1_TLS_GD_HI,
+ BFD_RELOC_TILEPRO_IMM16_X0_TLS_GD_HA,
+ BFD_RELOC_TILEPRO_IMM16_X1_TLS_GD_HA,
+ BFD_RELOC_TILEPRO_IMM16_X0_TLS_IE,
+ BFD_RELOC_TILEPRO_IMM16_X1_TLS_IE,
+ BFD_RELOC_TILEPRO_IMM16_X0_TLS_IE_LO,
+ BFD_RELOC_TILEPRO_IMM16_X1_TLS_IE_LO,
+ BFD_RELOC_TILEPRO_IMM16_X0_TLS_IE_HI,
+ BFD_RELOC_TILEPRO_IMM16_X1_TLS_IE_HI,
+ BFD_RELOC_TILEPRO_IMM16_X0_TLS_IE_HA,
+ BFD_RELOC_TILEPRO_IMM16_X1_TLS_IE_HA,
+ BFD_RELOC_TILEPRO_TLS_DTPMOD32,
+ BFD_RELOC_TILEPRO_TLS_DTPOFF32,
+ BFD_RELOC_TILEPRO_TLS_TPOFF32,
+ BFD_RELOC_TILEPRO_IMM16_X0_TLS_LE,
+ BFD_RELOC_TILEPRO_IMM16_X1_TLS_LE,
+ BFD_RELOC_TILEPRO_IMM16_X0_TLS_LE_LO,
+ BFD_RELOC_TILEPRO_IMM16_X1_TLS_LE_LO,
+ BFD_RELOC_TILEPRO_IMM16_X0_TLS_LE_HI,
+ BFD_RELOC_TILEPRO_IMM16_X1_TLS_LE_HI,
+ BFD_RELOC_TILEPRO_IMM16_X0_TLS_LE_HA,
+ BFD_RELOC_TILEPRO_IMM16_X1_TLS_LE_HA,
+
+/* Tilera TILE-Gx Relocations. */
+ BFD_RELOC_TILEGX_HW0,
+ BFD_RELOC_TILEGX_HW1,
+ BFD_RELOC_TILEGX_HW2,
+ BFD_RELOC_TILEGX_HW3,
+ BFD_RELOC_TILEGX_HW0_LAST,
+ BFD_RELOC_TILEGX_HW1_LAST,
+ BFD_RELOC_TILEGX_HW2_LAST,
+ BFD_RELOC_TILEGX_COPY,
+ BFD_RELOC_TILEGX_GLOB_DAT,
+ BFD_RELOC_TILEGX_JMP_SLOT,
+ BFD_RELOC_TILEGX_RELATIVE,
+ BFD_RELOC_TILEGX_BROFF_X1,
+ BFD_RELOC_TILEGX_JUMPOFF_X1,
+ BFD_RELOC_TILEGX_JUMPOFF_X1_PLT,
+ BFD_RELOC_TILEGX_IMM8_X0,
+ BFD_RELOC_TILEGX_IMM8_Y0,
+ BFD_RELOC_TILEGX_IMM8_X1,
+ BFD_RELOC_TILEGX_IMM8_Y1,
+ BFD_RELOC_TILEGX_DEST_IMM8_X1,
+ BFD_RELOC_TILEGX_MT_IMM14_X1,
+ BFD_RELOC_TILEGX_MF_IMM14_X1,
+ BFD_RELOC_TILEGX_MMSTART_X0,
+ BFD_RELOC_TILEGX_MMEND_X0,
+ BFD_RELOC_TILEGX_SHAMT_X0,
+ BFD_RELOC_TILEGX_SHAMT_X1,
+ BFD_RELOC_TILEGX_SHAMT_Y0,
+ BFD_RELOC_TILEGX_SHAMT_Y1,
+ BFD_RELOC_TILEGX_IMM16_X0_HW0,
+ BFD_RELOC_TILEGX_IMM16_X1_HW0,
+ BFD_RELOC_TILEGX_IMM16_X0_HW1,
+ BFD_RELOC_TILEGX_IMM16_X1_HW1,
+ BFD_RELOC_TILEGX_IMM16_X0_HW2,
+ BFD_RELOC_TILEGX_IMM16_X1_HW2,
+ BFD_RELOC_TILEGX_IMM16_X0_HW3,
+ BFD_RELOC_TILEGX_IMM16_X1_HW3,
+ BFD_RELOC_TILEGX_IMM16_X0_HW0_LAST,
+ BFD_RELOC_TILEGX_IMM16_X1_HW0_LAST,
+ BFD_RELOC_TILEGX_IMM16_X0_HW1_LAST,
+ BFD_RELOC_TILEGX_IMM16_X1_HW1_LAST,
+ BFD_RELOC_TILEGX_IMM16_X0_HW2_LAST,
+ BFD_RELOC_TILEGX_IMM16_X1_HW2_LAST,
+ BFD_RELOC_TILEGX_IMM16_X0_HW0_PCREL,
+ BFD_RELOC_TILEGX_IMM16_X1_HW0_PCREL,
+ BFD_RELOC_TILEGX_IMM16_X0_HW1_PCREL,
+ BFD_RELOC_TILEGX_IMM16_X1_HW1_PCREL,
+ BFD_RELOC_TILEGX_IMM16_X0_HW2_PCREL,
+ BFD_RELOC_TILEGX_IMM16_X1_HW2_PCREL,
+ BFD_RELOC_TILEGX_IMM16_X0_HW3_PCREL,
+ BFD_RELOC_TILEGX_IMM16_X1_HW3_PCREL,
+ BFD_RELOC_TILEGX_IMM16_X0_HW0_LAST_PCREL,
+ BFD_RELOC_TILEGX_IMM16_X1_HW0_LAST_PCREL,
+ BFD_RELOC_TILEGX_IMM16_X0_HW1_LAST_PCREL,
+ BFD_RELOC_TILEGX_IMM16_X1_HW1_LAST_PCREL,
+ BFD_RELOC_TILEGX_IMM16_X0_HW2_LAST_PCREL,
+ BFD_RELOC_TILEGX_IMM16_X1_HW2_LAST_PCREL,
+ BFD_RELOC_TILEGX_IMM16_X0_HW0_GOT,
+ BFD_RELOC_TILEGX_IMM16_X1_HW0_GOT,
+ BFD_RELOC_TILEGX_IMM16_X0_HW0_PLT_PCREL,
+ BFD_RELOC_TILEGX_IMM16_X1_HW0_PLT_PCREL,
+ BFD_RELOC_TILEGX_IMM16_X0_HW1_PLT_PCREL,
+ BFD_RELOC_TILEGX_IMM16_X1_HW1_PLT_PCREL,
+ BFD_RELOC_TILEGX_IMM16_X0_HW2_PLT_PCREL,
+ BFD_RELOC_TILEGX_IMM16_X1_HW2_PLT_PCREL,
+ BFD_RELOC_TILEGX_IMM16_X0_HW0_LAST_GOT,
+ BFD_RELOC_TILEGX_IMM16_X1_HW0_LAST_GOT,
+ BFD_RELOC_TILEGX_IMM16_X0_HW1_LAST_GOT,
+ BFD_RELOC_TILEGX_IMM16_X1_HW1_LAST_GOT,
+ BFD_RELOC_TILEGX_IMM16_X0_HW3_PLT_PCREL,
+ BFD_RELOC_TILEGX_IMM16_X1_HW3_PLT_PCREL,
+ BFD_RELOC_TILEGX_IMM16_X0_HW0_TLS_GD,
+ BFD_RELOC_TILEGX_IMM16_X1_HW0_TLS_GD,
+ BFD_RELOC_TILEGX_IMM16_X0_HW0_TLS_LE,
+ BFD_RELOC_TILEGX_IMM16_X1_HW0_TLS_LE,
+ BFD_RELOC_TILEGX_IMM16_X0_HW0_LAST_TLS_LE,
+ BFD_RELOC_TILEGX_IMM16_X1_HW0_LAST_TLS_LE,
+ BFD_RELOC_TILEGX_IMM16_X0_HW1_LAST_TLS_LE,
+ BFD_RELOC_TILEGX_IMM16_X1_HW1_LAST_TLS_LE,
+ BFD_RELOC_TILEGX_IMM16_X0_HW0_LAST_TLS_GD,
+ BFD_RELOC_TILEGX_IMM16_X1_HW0_LAST_TLS_GD,
+ BFD_RELOC_TILEGX_IMM16_X0_HW1_LAST_TLS_GD,
+ BFD_RELOC_TILEGX_IMM16_X1_HW1_LAST_TLS_GD,
+ BFD_RELOC_TILEGX_IMM16_X0_HW0_TLS_IE,
+ BFD_RELOC_TILEGX_IMM16_X1_HW0_TLS_IE,
+ BFD_RELOC_TILEGX_IMM16_X0_HW0_LAST_PLT_PCREL,
+ BFD_RELOC_TILEGX_IMM16_X1_HW0_LAST_PLT_PCREL,
+ BFD_RELOC_TILEGX_IMM16_X0_HW1_LAST_PLT_PCREL,
+ BFD_RELOC_TILEGX_IMM16_X1_HW1_LAST_PLT_PCREL,
+ BFD_RELOC_TILEGX_IMM16_X0_HW2_LAST_PLT_PCREL,
+ BFD_RELOC_TILEGX_IMM16_X1_HW2_LAST_PLT_PCREL,
+ BFD_RELOC_TILEGX_IMM16_X0_HW0_LAST_TLS_IE,
+ BFD_RELOC_TILEGX_IMM16_X1_HW0_LAST_TLS_IE,
+ BFD_RELOC_TILEGX_IMM16_X0_HW1_LAST_TLS_IE,
+ BFD_RELOC_TILEGX_IMM16_X1_HW1_LAST_TLS_IE,
+ BFD_RELOC_TILEGX_TLS_DTPMOD64,
+ BFD_RELOC_TILEGX_TLS_DTPOFF64,
+ BFD_RELOC_TILEGX_TLS_TPOFF64,
+ BFD_RELOC_TILEGX_TLS_DTPMOD32,
+ BFD_RELOC_TILEGX_TLS_DTPOFF32,
+ BFD_RELOC_TILEGX_TLS_TPOFF32,
+ BFD_RELOC_TILEGX_TLS_GD_CALL,
+ BFD_RELOC_TILEGX_IMM8_X0_TLS_GD_ADD,
+ BFD_RELOC_TILEGX_IMM8_X1_TLS_GD_ADD,
+ BFD_RELOC_TILEGX_IMM8_Y0_TLS_GD_ADD,
+ BFD_RELOC_TILEGX_IMM8_Y1_TLS_GD_ADD,
+ BFD_RELOC_TILEGX_TLS_IE_LOAD,
+ BFD_RELOC_TILEGX_IMM8_X0_TLS_ADD,
+ BFD_RELOC_TILEGX_IMM8_X1_TLS_ADD,
+ BFD_RELOC_TILEGX_IMM8_Y0_TLS_ADD,
+ BFD_RELOC_TILEGX_IMM8_Y1_TLS_ADD,
+
+/* Adapteva EPIPHANY - 8 bit signed pc-relative displacement */
+ BFD_RELOC_EPIPHANY_SIMM8,
+
+/* Adapteva EPIPHANY - 24 bit signed pc-relative displacement */
+ BFD_RELOC_EPIPHANY_SIMM24,
+
+/* Adapteva EPIPHANY - 16 most-significant bits of absolute address */
+ BFD_RELOC_EPIPHANY_HIGH,
+
+/* Adapteva EPIPHANY - 16 least-significant bits of absolute address */
+ BFD_RELOC_EPIPHANY_LOW,
+
+/* Adapteva EPIPHANY - 11 bit signed number - add/sub immediate */
+ BFD_RELOC_EPIPHANY_SIMM11,
+
+/* Adapteva EPIPHANY - 11 bit sign-magnitude number (ld/st displacement) */
+ BFD_RELOC_EPIPHANY_IMM11,
+
+/* Adapteva EPIPHANY - 8 bit immediate for 16 bit mov instruction. */
+ BFD_RELOC_EPIPHANY_IMM8,
+ BFD_RELOC_UNUSED };
+
+typedef enum bfd_reloc_code_real bfd_reloc_code_real_type;
+reloc_howto_type *bfd_reloc_type_lookup
+ (bfd *abfd, bfd_reloc_code_real_type code);
+reloc_howto_type *bfd_reloc_name_lookup
+ (bfd *abfd, const char *reloc_name);
+
+const char *bfd_get_reloc_code_name (bfd_reloc_code_real_type code);
+
+/* Extracted from syms.c. */
+
+typedef struct bfd_symbol
+{
+ /* 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 (1 << 0)
+
+ /* The symbol has global scope; initialized data in <<C>>. The
+ value is the offset into the section of the data. */
+#define BSF_GLOBAL (1 << 1)
+
+ /* 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_COMMON>>, <<BSF_UNDEFINED>> or
+ <<BSF_GLOBAL>>. */
+
+ /* The symbol is a debugging record. The value has an arbitrary
+ meaning, unless BSF_DEBUGGING_RELOC is also set. */
+#define BSF_DEBUGGING (1 << 2)
+
+ /* The symbol denotes a function entry point. Used in ELF,
+ perhaps others someday. */
+#define BSF_FUNCTION (1 << 3)
+
+ /* Used by the linker. */
+#define BSF_KEEP (1 << 5)
+#define BSF_KEEP_G (1 << 6)
+
+ /* A weak global symbol, overridable without warnings by
+ a regular global symbol of the same name. */
+#define BSF_WEAK (1 << 7)
+
+ /* This symbol was created to point to a section, e.g. ELF's
+ STT_SECTION symbols. */
+#define BSF_SECTION_SYM (1 << 8)
+
+ /* The symbol used to be a common symbol, but now it is
+ allocated. */
+#define BSF_OLD_COMMON (1 << 9)
+
+ /* 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 (1 << 10)
+
+ /* Signal that the symbol is the label of constructor section. */
+#define BSF_CONSTRUCTOR (1 << 11)
+
+ /* 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 (1 << 12)
+
+ /* 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 (1 << 13)
+
+ /* BSF_FILE marks symbols that contain a file name. This is used
+ for ELF STT_FILE symbols. */
+#define BSF_FILE (1 << 14)
+
+ /* Symbol is from dynamic linking information. */
+#define BSF_DYNAMIC (1 << 15)
+
+ /* The symbol denotes a data object. Used in ELF, and perhaps
+ others someday. */
+#define BSF_OBJECT (1 << 16)
+
+ /* This symbol is a debugging symbol. The value is the offset
+ into the section of the data. BSF_DEBUGGING should be set
+ as well. */
+#define BSF_DEBUGGING_RELOC (1 << 17)
+
+ /* This symbol is thread local. Used in ELF. */
+#define BSF_THREAD_LOCAL (1 << 18)
+
+ /* This symbol represents a complex relocation expression,
+ with the expression tree serialized in the symbol name. */
+#define BSF_RELC (1 << 19)
+
+ /* This symbol represents a signed complex relocation expression,
+ with the expression tree serialized in the symbol name. */
+#define BSF_SRELC (1 << 20)
+
+ /* This symbol was created by bfd_get_synthetic_symtab. */
+#define BSF_SYNTHETIC (1 << 21)
+
+ /* This symbol is an indirect code object. Unrelated to BSF_INDIRECT.
+ The dynamic linker will compute the value of this symbol by
+ calling the function that it points to. BSF_FUNCTION must
+ also be also set. */
+#define BSF_GNU_INDIRECT_FUNCTION (1 << 22)
+ /* This symbol is a globally unique data object. The dynamic linker
+ will make sure that in the entire process there is just one symbol
+ with this name and type in use. BSF_OBJECT must also be set. */
+#define BSF_GNU_UNIQUE (1 << 23)
+
+ 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 bfd_section *section;
+
+ /* Back end special data. */
+ union
+ {
+ void *p;
+ bfd_vma i;
+ }
+ udata;
+}
+asymbol;
+
+#define bfd_get_symtab_upper_bound(abfd) \
+ BFD_SEND (abfd, _bfd_get_symtab_upper_bound, (abfd))
+
+bfd_boolean bfd_is_local_label (bfd *abfd, asymbol *sym);
+
+bfd_boolean bfd_is_local_label_name (bfd *abfd, const char *name);
+
+#define bfd_is_local_label_name(abfd, name) \
+ BFD_SEND (abfd, _bfd_is_local_label_name, (abfd, name))
+
+bfd_boolean bfd_is_target_special_symbol (bfd *abfd, asymbol *sym);
+
+#define bfd_is_target_special_symbol(abfd, sym) \
+ BFD_SEND (abfd, _bfd_is_target_special_symbol, (abfd, sym))
+
+#define bfd_canonicalize_symtab(abfd, location) \
+ BFD_SEND (abfd, _bfd_canonicalize_symtab, (abfd, location))
+
+bfd_boolean bfd_set_symtab
+ (bfd *abfd, asymbol **location, unsigned int count);
+
+void bfd_print_symbol_vandf (bfd *abfd, void *file, asymbol *symbol);
+
+#define bfd_make_empty_symbol(abfd) \
+ BFD_SEND (abfd, _bfd_make_empty_symbol, (abfd))
+
+asymbol *_bfd_generic_make_empty_symbol (bfd *);
+
+#define bfd_make_debug_symbol(abfd,ptr,size) \
+ BFD_SEND (abfd, _bfd_make_debug_symbol, (abfd, ptr, size))
+
+int bfd_decode_symclass (asymbol *symbol);
+
+bfd_boolean bfd_is_undefined_symclass (int symclass);
+
+void bfd_symbol_info (asymbol *symbol, symbol_info *ret);
+
+bfd_boolean bfd_copy_private_symbol_data
+ (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))
+
+/* Extracted from bfd.c. */
+
+enum bfd_direction
+ {
+ no_direction = 0,
+ read_direction = 1,
+ write_direction = 2,
+ both_direction = 3
+ };
+
+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;
+
+ /* The IOSTREAM, and corresponding IO vector that provide access
+ to the file backing the BFD. */
+ void *iostream;
+ const struct bfd_iovec *iovec;
+
+ /* 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... */
+ ufile_ptr where;
+
+ /* File modified time, if mtime_set is TRUE. */
+ long mtime;
+
+ /* A unique identifier of the BFD */
+ unsigned int id;
+
+ /* The format which belongs to the BFD. (object, core, etc.) */
+ ENUM_BITFIELD (bfd_format) format : 3;
+
+ /* The direction with which the BFD was opened. */
+ ENUM_BITFIELD (bfd_direction) direction : 2;
+
+ /* Format_specific flags. */
+ flagword flags : 17;
+
+ /* 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). */
+
+#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
+
+ /* This BFD has been created by the linker and doesn't correspond
+ to any input file. */
+#define BFD_LINKER_CREATED 0x1000
+
+ /* This may be set before writing out a BFD to request that it
+ be written using values for UIDs, GIDs, timestamps, etc. that
+ will be consistent from run to run. */
+#define BFD_DETERMINISTIC_OUTPUT 0x2000
+
+ /* Compress sections in this BFD. */
+#define BFD_COMPRESS 0x4000
+
+ /* Decompress sections in this BFD. */
+#define BFD_DECOMPRESS 0x8000
+
+ /* BFD is a dummy, for plugins. */
+#define BFD_PLUGIN 0x10000
+
+ /* Flags bits to be saved in bfd_preserve_save. */
+#define BFD_FLAGS_SAVED \
+ (BFD_IN_MEMORY | BFD_COMPRESS | BFD_DECOMPRESS | BFD_PLUGIN)
+
+ /* Flags bits which are for BFD use only. */
+#define BFD_FLAGS_FOR_BFD_USE_MASK \
+ (BFD_IN_MEMORY | BFD_COMPRESS | BFD_DECOMPRESS | BFD_LINKER_CREATED \
+ | BFD_PLUGIN | BFD_TRADITIONAL_FORMAT | BFD_DETERMINISTIC_OUTPUT)
+
+ /* Is the file descriptor being cached? That is, can it be closed as
+ needed, and re-opened when accessed later? */
+ unsigned int cacheable : 1;
+
+ /* 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. */
+ unsigned int target_defaulted : 1;
+
+ /* ... and here: (``once'' means at least once). */
+ unsigned int opened_once : 1;
+
+ /* Set if we have a locally maintained mtime value, rather than
+ getting it from the file each time. */
+ unsigned int mtime_set : 1;
+
+ /* Flag set if symbols from this BFD should not be exported. */
+ unsigned int no_export : 1;
+
+ /* Remember when output has begun, to stop strange things
+ from happening. */
+ unsigned int output_has_begun : 1;
+
+ /* Have archive map. */
+ unsigned int has_armap : 1;
+
+ /* Set if this is a thin archive. */
+ unsigned int is_thin_archive : 1;
+
+ /* Set if only required symbols should be added in the link hash table for
+ this object. Used by VMS linkers. */
+ unsigned int selective_search : 1;
+
+ /* Set if this is the linker output BFD. */
+ unsigned int is_linker_output : 1;
+
+ /* 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. */
+ ufile_ptr origin;
+
+ /* The origin in the archive of the proxy entry. This will
+ normally be the same as origin, except for thin archives,
+ when it will contain the current offset of the proxy in the
+ thin archive rather than the offset of the bfd in its actual
+ container. */
+ ufile_ptr proxy_origin;
+
+ /* A hash table for section names. */
+ struct bfd_hash_table section_htab;
+
+ /* Pointer to linked list of sections. */
+ struct bfd_section *sections;
+
+ /* The last section on the section list. */
+ struct bfd_section *section_last;
+
+ /* The number of sections. */
+ unsigned int section_count;
+
+ /* A field used by _bfd_generic_link_add_archive_symbols. This will
+ be used only for archive elements. */
+ int archive_pass;
+
+ /* Stuff only useful for object files:
+ The start address. */
+ bfd_vma start_address;
+
+ /* Symbol table for output BFD (with symcount entries).
+ Also used by the linker to cache input BFD symbols. */
+ struct bfd_symbol **outsymbols;
+
+ /* Used for input and output. */
+ unsigned int symcount;
+
+ /* Used for slurped dynamic symbol tables. */
+ unsigned int dynsymcount;
+
+ /* Pointer to structure which contains architecture information. */
+ const struct bfd_arch_info *arch_info;
+
+ /* Stuff only useful for archives. */
+ void *arelt_data;
+ struct bfd *my_archive; /* The containing archive BFD. */
+ struct bfd *archive_next; /* The next BFD in the archive. */
+ struct bfd *archive_head; /* The first BFD in the archive. */
+ struct bfd *nested_archives; /* List of nested archive in a flattened
+ thin archive. */
+
+ union {
+ /* For input BFDs, a chain of BFDs involved in a link. */
+ struct bfd *next;
+ /* For output BFD, the linker hash table. */
+ struct bfd_link_hash_table *hash;
+ } link;
+
+ /* 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 verilog_data_struct *verilog_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 mmo_data_struct *mmo_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;
+ struct mach_o_data_struct *mach_o_data;
+ struct mach_o_fat_data_struct *mach_o_fat_data;
+ struct plugin_data_struct *plugin_data;
+ struct bfd_pef_data_struct *pef_data;
+ struct bfd_pef_xlib_data_struct *pef_xlib_data;
+ struct bfd_sym_data_struct *sym_data;
+ void *any;
+ }
+ tdata;
+
+ /* Used by the application to hold private data. */
+ void *usrdata;
+
+ /* Where all the allocated stuff under this BFD goes. This is a
+ struct objalloc *, but we use void * to avoid requiring the inclusion
+ of objalloc.h. */
+ void *memory;
+};
+
+/* See note beside bfd_set_section_userdata. */
+static inline bfd_boolean
+bfd_set_cacheable (bfd * abfd, bfd_boolean val)
+{
+ abfd->cacheable = val;
+ return TRUE;
+}
+
+
+typedef enum bfd_error
+{
+ bfd_error_no_error = 0,
+ bfd_error_system_call,
+ bfd_error_invalid_target,
+ bfd_error_wrong_format,
+ bfd_error_wrong_object_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_missing_dso,
+ 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_on_input,
+ bfd_error_invalid_error_code
+}
+bfd_error_type;
+
+bfd_error_type bfd_get_error (void);
+
+void bfd_set_error (bfd_error_type error_tag, ...);
+
+const char *bfd_errmsg (bfd_error_type error_tag);
+
+void bfd_perror (const char *message);
+
+
+typedef void (*bfd_error_handler_type) (const char *, ...);
+
+bfd_error_handler_type bfd_set_error_handler (bfd_error_handler_type);
+
+void bfd_set_error_program_name (const char *);
+
+bfd_error_handler_type bfd_get_error_handler (void);
+
+
+typedef void (*bfd_assert_handler_type) (const char *bfd_formatmsg,
+ const char *bfd_version,
+ const char *bfd_file,
+ int bfd_line);
+
+bfd_assert_handler_type bfd_set_assert_handler (bfd_assert_handler_type);
+
+bfd_assert_handler_type bfd_get_assert_handler (void);
+
+long bfd_get_reloc_upper_bound (bfd *abfd, asection *sect);
+
+long bfd_canonicalize_reloc
+ (bfd *abfd, asection *sec, arelent **loc, asymbol **syms);
+
+void bfd_set_reloc
+ (bfd *abfd, asection *sec, arelent **rel, unsigned int count);
+
+bfd_boolean bfd_set_file_flags (bfd *abfd, flagword flags);
+
+int bfd_get_arch_size (bfd *abfd);
+
+int bfd_get_sign_extend_vma (bfd *abfd);
+
+bfd_boolean bfd_set_start_address (bfd *abfd, bfd_vma vma);
+
+unsigned int bfd_get_gp_size (bfd *abfd);
+
+void bfd_set_gp_size (bfd *abfd, unsigned int i);
+
+bfd_vma bfd_scan_vma (const char *string, const char **end, int base);
+
+bfd_boolean bfd_copy_private_header_data (bfd *ibfd, bfd *obfd);
+
+#define bfd_copy_private_header_data(ibfd, obfd) \
+ BFD_SEND (obfd, _bfd_copy_private_header_data, \
+ (ibfd, obfd))
+bfd_boolean bfd_copy_private_bfd_data (bfd *ibfd, bfd *obfd);
+
+#define bfd_copy_private_bfd_data(ibfd, obfd) \
+ BFD_SEND (obfd, _bfd_copy_private_bfd_data, \
+ (ibfd, obfd))
+bfd_boolean bfd_merge_private_bfd_data (bfd *ibfd, bfd *obfd);
+
+#define bfd_merge_private_bfd_data(ibfd, obfd) \
+ BFD_SEND (obfd, _bfd_merge_private_bfd_data, \
+ (ibfd, obfd))
+bfd_boolean bfd_set_private_flags (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, info) \
+ BFD_SEND (abfd, _bfd_sizeof_headers, (abfd, info))
+
+#define bfd_find_nearest_line(abfd, sec, syms, off, file, func, line) \
+ BFD_SEND (abfd, _bfd_find_nearest_line, \
+ (abfd, syms, sec, off, file, func, line, NULL))
+
+#define bfd_find_nearest_line_discriminator(abfd, sec, syms, off, file, func, \
+ line, disc) \
+ BFD_SEND (abfd, _bfd_find_nearest_line, \
+ (abfd, syms, sec, off, file, func, line, disc))
+
+#define bfd_find_line(abfd, syms, sym, file, line) \
+ BFD_SEND (abfd, _bfd_find_line, \
+ (abfd, syms, sym, file, line))
+
+#define bfd_find_inliner_info(abfd, file, func, line) \
+ BFD_SEND (abfd, _bfd_find_inliner_info, \
+ (abfd, file, func, line))
+
+#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_lookup_section_flags(link_info, flag_info, section) \
+ BFD_SEND (abfd, _bfd_lookup_section_flags, (link_info, flag_info, section))
+
+#define bfd_merge_sections(abfd, link_info) \
+ BFD_SEND (abfd, _bfd_merge_sections, (abfd, link_info))
+
+#define bfd_is_group_section(abfd, sec) \
+ BFD_SEND (abfd, _bfd_is_group_section, (abfd, sec))
+
+#define bfd_discard_group(abfd, sec) \
+ BFD_SEND (abfd, _bfd_discard_group, (abfd, sec))
+
+#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_link_just_syms(abfd, sec, info) \
+ BFD_SEND (abfd, _bfd_link_just_syms, (sec, 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_synthetic_symtab(abfd, count, syms, dyncount, dynsyms, ret) \
+ BFD_SEND (abfd, _bfd_get_synthetic_symtab, (abfd, count, syms, \
+ dyncount, dynsyms, ret))
+
+#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
+ (bfd *, struct bfd_link_info *, struct bfd_link_order *, bfd_byte *,
+ bfd_boolean, asymbol **);
+
+bfd_boolean bfd_alt_mach_code (bfd *abfd, int alternative);
+
+bfd_vma bfd_emul_get_maxpagesize (const char *);
+
+void bfd_emul_set_maxpagesize (const char *, bfd_vma);
+
+bfd_vma bfd_emul_get_commonpagesize (const char *);
+
+void bfd_emul_set_commonpagesize (const char *, bfd_vma);
+
+char *bfd_demangle (bfd *, const char *, int);
+
+/* Extracted from archive.c. */
+symindex bfd_get_next_mapent
+ (bfd *abfd, symindex previous, carsym **sym);
+
+bfd_boolean bfd_set_archive_head (bfd *output, bfd *new_head);
+
+bfd *bfd_openr_next_archived_file (bfd *archive, bfd *previous);
+
+/* Extracted from corefile.c. */
+const char *bfd_core_file_failing_command (bfd *abfd);
+
+int bfd_core_file_failing_signal (bfd *abfd);
+
+int bfd_core_file_pid (bfd *abfd);
+
+bfd_boolean core_file_matches_executable_p
+ (bfd *core_bfd, bfd *exec_bfd);
+
+bfd_boolean generic_core_file_matches_executable_p
+ (bfd *core_bfd, bfd *exec_bfd);
+
+/* Extracted from targets.c. */
+#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_xcoff_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_verilog_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,
+ bfd_target_mmo_flavour,
+ bfd_target_mach_o_flavour,
+ bfd_target_pef_flavour,
+ bfd_target_pef_xlib_flavour,
+ bfd_target_sym_flavour
+};
+
+enum bfd_endian { BFD_ENDIAN_BIG, BFD_ENDIAN_LITTLE, BFD_ENDIAN_UNKNOWN };
+
+/* Forward declaration. */
+typedef struct bfd_link_info _bfd_link_info;
+
+/* Forward declaration. */
+typedef struct flag_info flag_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 char ar_max_namelen;
+
+ /* How well this target matches, used to select between various
+ possible targets when more than one target matches. */
+ unsigned char match_priority;
+
+ /* Entries for byte swapping for data. These are different from the
+ other entry points, since they don't take a BFD as the first argument.
+ Certain other handlers could do the same. */
+ bfd_uint64_t (*bfd_getx64) (const void *);
+ bfd_int64_t (*bfd_getx_signed_64) (const void *);
+ void (*bfd_putx64) (bfd_uint64_t, void *);
+ bfd_vma (*bfd_getx32) (const void *);
+ bfd_signed_vma (*bfd_getx_signed_32) (const void *);
+ void (*bfd_putx32) (bfd_vma, void *);
+ bfd_vma (*bfd_getx16) (const void *);
+ bfd_signed_vma (*bfd_getx_signed_16) (const void *);
+ void (*bfd_putx16) (bfd_vma, void *);
+
+ /* Byte swapping for the headers. */
+ bfd_uint64_t (*bfd_h_getx64) (const void *);
+ bfd_int64_t (*bfd_h_getx_signed_64) (const void *);
+ void (*bfd_h_putx64) (bfd_uint64_t, void *);
+ bfd_vma (*bfd_h_getx32) (const void *);
+ bfd_signed_vma (*bfd_h_getx_signed_32) (const void *);
+ void (*bfd_h_putx32) (bfd_vma, void *);
+ bfd_vma (*bfd_h_getx16) (const void *);
+ bfd_signed_vma (*bfd_h_getx_signed_16) (const void *);
+ void (*bfd_h_putx16) (bfd_vma, void *);
+
+ /* 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]) (bfd *);
+
+ /* Set the format of a file being written. */
+ bfd_boolean (*_bfd_set_format[bfd_type_end]) (bfd *);
+
+ /* Write cached information into a file being written, at <<bfd_close>>. */
+ bfd_boolean (*_bfd_write_contents[bfd_type_end]) (bfd *);
+
+
+ /* Generic entry points. */
+#define BFD_JUMP_TABLE_GENERIC(NAME) \
+ NAME##_close_and_cleanup, \
+ NAME##_bfd_free_cached_info, \
+ NAME##_new_section_hook, \
+ NAME##_get_section_contents, \
+ NAME##_get_section_contents_in_window
+
+ /* Called when the BFD is being closed to do any necessary cleanup. */
+ bfd_boolean (*_close_and_cleanup) (bfd *);
+ /* Ask the BFD to free all cached information. */
+ bfd_boolean (*_bfd_free_cached_info) (bfd *);
+ /* Called when a new section is created. */
+ bfd_boolean (*_new_section_hook) (bfd *, sec_ptr);
+ /* Read the contents of a section. */
+ bfd_boolean (*_bfd_get_section_contents)
+ (bfd *, sec_ptr, void *, file_ptr, bfd_size_type);
+ bfd_boolean (*_bfd_get_section_contents_in_window)
+ (bfd *, sec_ptr, bfd_window *, file_ptr, bfd_size_type);
+
+ /* Entry points to copy private data. */
+#define BFD_JUMP_TABLE_COPY(NAME) \
+ NAME##_bfd_copy_private_bfd_data, \
+ NAME##_bfd_merge_private_bfd_data, \
+ _bfd_generic_init_private_section_data, \
+ NAME##_bfd_copy_private_section_data, \
+ NAME##_bfd_copy_private_symbol_data, \
+ NAME##_bfd_copy_private_header_data, \
+ NAME##_bfd_set_private_flags, \
+ NAME##_bfd_print_private_bfd_data
+
+ /* Called to copy BFD general private data from one object file
+ to another. */
+ bfd_boolean (*_bfd_copy_private_bfd_data) (bfd *, bfd *);
+ /* Called to merge BFD general private data from one object file
+ to a common output file when linking. */
+ bfd_boolean (*_bfd_merge_private_bfd_data) (bfd *, bfd *);
+ /* Called to initialize BFD private section data from one object file
+ to another. */
+#define bfd_init_private_section_data(ibfd, isec, obfd, osec, link_info) \
+ BFD_SEND (obfd, _bfd_init_private_section_data, (ibfd, isec, obfd, osec, link_info))
+ bfd_boolean (*_bfd_init_private_section_data)
+ (bfd *, sec_ptr, bfd *, sec_ptr, struct bfd_link_info *);
+ /* Called to copy BFD private section data from one object file
+ to another. */
+ bfd_boolean (*_bfd_copy_private_section_data)
+ (bfd *, sec_ptr, bfd *, sec_ptr);
+ /* Called to copy BFD private symbol data from one symbol
+ to another. */
+ bfd_boolean (*_bfd_copy_private_symbol_data)
+ (bfd *, asymbol *, bfd *, asymbol *);
+ /* Called to copy BFD private header data from one object file
+ to another. */
+ bfd_boolean (*_bfd_copy_private_header_data)
+ (bfd *, bfd *);
+ /* Called to set private backend flags. */
+ bfd_boolean (*_bfd_set_private_flags) (bfd *, flagword);
+
+ /* Called to print private BFD data. */
+ bfd_boolean (*_bfd_print_private_bfd_data) (bfd *, void *);
+
+ /* Core file entry points. */
+#define BFD_JUMP_TABLE_CORE(NAME) \
+ NAME##_core_file_failing_command, \
+ NAME##_core_file_failing_signal, \
+ NAME##_core_file_matches_executable_p, \
+ NAME##_core_file_pid
+
+ char * (*_core_file_failing_command) (bfd *);
+ int (*_core_file_failing_signal) (bfd *);
+ bfd_boolean (*_core_file_matches_executable_p) (bfd *, bfd *);
+ int (*_core_file_pid) (bfd *);
+
+ /* Archive entry points. */
+#define BFD_JUMP_TABLE_ARCHIVE(NAME) \
+ NAME##_slurp_armap, \
+ NAME##_slurp_extended_name_table, \
+ NAME##_construct_extended_name_table, \
+ NAME##_truncate_arname, \
+ NAME##_write_armap, \
+ NAME##_read_ar_hdr, \
+ NAME##_write_ar_hdr, \
+ NAME##_openr_next_archived_file, \
+ NAME##_get_elt_at_index, \
+ NAME##_generic_stat_arch_elt, \
+ NAME##_update_armap_timestamp
+
+ bfd_boolean (*_bfd_slurp_armap) (bfd *);
+ bfd_boolean (*_bfd_slurp_extended_name_table) (bfd *);
+ bfd_boolean (*_bfd_construct_extended_name_table)
+ (bfd *, char **, bfd_size_type *, const char **);
+ void (*_bfd_truncate_arname) (bfd *, const char *, char *);
+ bfd_boolean (*write_armap)
+ (bfd *, unsigned int, struct orl *, unsigned int, int);
+ void * (*_bfd_read_ar_hdr_fn) (bfd *);
+ bfd_boolean (*_bfd_write_ar_hdr_fn) (bfd *, bfd *);
+ bfd * (*openr_next_archived_file) (bfd *, bfd *);
+#define bfd_get_elt_at_index(b,i) BFD_SEND (b, _bfd_get_elt_at_index, (b,i))
+ bfd * (*_bfd_get_elt_at_index) (bfd *, symindex);
+ int (*_bfd_stat_arch_elt) (bfd *, struct stat *);
+ bfd_boolean (*_bfd_update_armap_timestamp) (bfd *);
+
+ /* Entry points used for symbols. */
+#define BFD_JUMP_TABLE_SYMBOLS(NAME) \
+ NAME##_get_symtab_upper_bound, \
+ NAME##_canonicalize_symtab, \
+ NAME##_make_empty_symbol, \
+ NAME##_print_symbol, \
+ NAME##_get_symbol_info, \
+ NAME##_bfd_is_local_label_name, \
+ NAME##_bfd_is_target_special_symbol, \
+ NAME##_get_lineno, \
+ NAME##_find_nearest_line, \
+ NAME##_find_line, \
+ NAME##_find_inliner_info, \
+ NAME##_bfd_make_debug_symbol, \
+ NAME##_read_minisymbols, \
+ NAME##_minisymbol_to_symbol
+
+ long (*_bfd_get_symtab_upper_bound) (bfd *);
+ long (*_bfd_canonicalize_symtab)
+ (bfd *, struct bfd_symbol **);
+ struct bfd_symbol *
+ (*_bfd_make_empty_symbol) (bfd *);
+ void (*_bfd_print_symbol)
+ (bfd *, void *, struct bfd_symbol *, 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)
+ (bfd *, struct bfd_symbol *, symbol_info *);
+#define bfd_get_symbol_info(b,p,e) BFD_SEND (b, _bfd_get_symbol_info, (b,p,e))
+ bfd_boolean (*_bfd_is_local_label_name) (bfd *, const char *);
+ bfd_boolean (*_bfd_is_target_special_symbol) (bfd *, asymbol *);
+ alent * (*_get_lineno) (bfd *, struct bfd_symbol *);
+ bfd_boolean (*_bfd_find_nearest_line)
+ (bfd *, struct bfd_symbol **, struct bfd_section *, bfd_vma,
+ const char **, const char **, unsigned int *, unsigned int *);
+ bfd_boolean (*_bfd_find_line)
+ (bfd *, struct bfd_symbol **, struct bfd_symbol *,
+ const char **, unsigned int *);
+ bfd_boolean (*_bfd_find_inliner_info)
+ (bfd *, const char **, const char **, unsigned int *);
+ /* 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)
+ (bfd *, void *, unsigned long size);
+#define bfd_read_minisymbols(b, d, m, s) \
+ BFD_SEND (b, _read_minisymbols, (b, d, m, s))
+ long (*_read_minisymbols)
+ (bfd *, bfd_boolean, void **, 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)
+ (bfd *, bfd_boolean, const void *, asymbol *);
+
+ /* Routines for relocs. */
+#define BFD_JUMP_TABLE_RELOCS(NAME) \
+ NAME##_get_reloc_upper_bound, \
+ NAME##_canonicalize_reloc, \
+ NAME##_bfd_reloc_type_lookup, \
+ NAME##_bfd_reloc_name_lookup
+
+ long (*_get_reloc_upper_bound) (bfd *, sec_ptr);
+ long (*_bfd_canonicalize_reloc)
+ (bfd *, sec_ptr, arelent **, struct bfd_symbol **);
+ /* See documentation on reloc types. */
+ reloc_howto_type *
+ (*reloc_type_lookup) (bfd *, bfd_reloc_code_real_type);
+ reloc_howto_type *
+ (*reloc_name_lookup) (bfd *, const char *);
+
+
+ /* Routines used when writing an object file. */
+#define BFD_JUMP_TABLE_WRITE(NAME) \
+ NAME##_set_arch_mach, \
+ NAME##_set_section_contents
+
+ bfd_boolean (*_bfd_set_arch_mach)
+ (bfd *, enum bfd_architecture, unsigned long);
+ bfd_boolean (*_bfd_set_section_contents)
+ (bfd *, sec_ptr, const void *, file_ptr, bfd_size_type);
+
+ /* Routines used by the linker. */
+#define BFD_JUMP_TABLE_LINK(NAME) \
+ NAME##_sizeof_headers, \
+ NAME##_bfd_get_relocated_section_contents, \
+ NAME##_bfd_relax_section, \
+ NAME##_bfd_link_hash_table_create, \
+ NAME##_bfd_link_add_symbols, \
+ NAME##_bfd_link_just_syms, \
+ NAME##_bfd_copy_link_hash_symbol_type, \
+ NAME##_bfd_final_link, \
+ NAME##_bfd_link_split_section, \
+ NAME##_bfd_gc_sections, \
+ NAME##_bfd_lookup_section_flags, \
+ NAME##_bfd_merge_sections, \
+ NAME##_bfd_is_group_section, \
+ NAME##_bfd_discard_group, \
+ NAME##_section_already_linked, \
+ NAME##_bfd_define_common_symbol
+
+ int (*_bfd_sizeof_headers) (bfd *, struct bfd_link_info *);
+ bfd_byte * (*_bfd_get_relocated_section_contents)
+ (bfd *, struct bfd_link_info *, struct bfd_link_order *,
+ bfd_byte *, bfd_boolean, struct bfd_symbol **);
+
+ bfd_boolean (*_bfd_relax_section)
+ (bfd *, struct bfd_section *, struct bfd_link_info *, bfd_boolean *);
+
+ /* 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) (bfd *);
+
+ /* Add symbols from this object file into the hash table. */
+ bfd_boolean (*_bfd_link_add_symbols) (bfd *, struct bfd_link_info *);
+
+ /* Indicate that we are only retrieving symbol values from this section. */
+ void (*_bfd_link_just_syms) (asection *, struct bfd_link_info *);
+
+ /* Copy the symbol type and other attributes for a linker script
+ assignment of one symbol to another. */
+#define bfd_copy_link_hash_symbol_type(b, t, f) \
+ BFD_SEND (b, _bfd_copy_link_hash_symbol_type, (b, t, f))
+ void (*_bfd_copy_link_hash_symbol_type)
+ (bfd *, struct bfd_link_hash_entry *, struct bfd_link_hash_entry *);
+
+ /* Do a link based on the link_order structures attached to each
+ section of the BFD. */
+ bfd_boolean (*_bfd_final_link) (bfd *, struct bfd_link_info *);
+
+ /* Should this section be split up into smaller pieces during linking. */
+ bfd_boolean (*_bfd_link_split_section) (bfd *, struct bfd_section *);
+
+ /* Remove sections that are not referenced from the output. */
+ bfd_boolean (*_bfd_gc_sections) (bfd *, struct bfd_link_info *);
+
+ /* Sets the bitmask of allowed and disallowed section flags. */
+ bfd_boolean (*_bfd_lookup_section_flags) (struct bfd_link_info *,
+ struct flag_info *,
+ asection *);
+
+ /* Attempt to merge SEC_MERGE sections. */
+ bfd_boolean (*_bfd_merge_sections) (bfd *, struct bfd_link_info *);
+
+ /* Is this section a member of a group? */
+ bfd_boolean (*_bfd_is_group_section) (bfd *, const struct bfd_section *);
+
+ /* Discard members of a group. */
+ bfd_boolean (*_bfd_discard_group) (bfd *, struct bfd_section *);
+
+ /* Check if SEC has been already linked during a reloceatable or
+ final link. */
+ bfd_boolean (*_section_already_linked) (bfd *, asection *,
+ struct bfd_link_info *);
+
+ /* Define a common symbol. */
+ bfd_boolean (*_bfd_define_common_symbol) (bfd *, struct bfd_link_info *,
+ struct bfd_link_hash_entry *);
+
+ /* Routines to handle dynamic symbols and relocs. */
+#define BFD_JUMP_TABLE_DYNAMIC(NAME) \
+ NAME##_get_dynamic_symtab_upper_bound, \
+ NAME##_canonicalize_dynamic_symtab, \
+ NAME##_get_synthetic_symtab, \
+ NAME##_get_dynamic_reloc_upper_bound, \
+ NAME##_canonicalize_dynamic_reloc
+
+ /* Get the amount of memory required to hold the dynamic symbols. */
+ long (*_bfd_get_dynamic_symtab_upper_bound) (bfd *);
+ /* Read in the dynamic symbols. */
+ long (*_bfd_canonicalize_dynamic_symtab)
+ (bfd *, struct bfd_symbol **);
+ /* Create synthetized symbols. */
+ long (*_bfd_get_synthetic_symtab)
+ (bfd *, long, struct bfd_symbol **, long, struct bfd_symbol **,
+ struct bfd_symbol **);
+ /* Get the amount of memory required to hold the dynamic relocs. */
+ long (*_bfd_get_dynamic_reloc_upper_bound) (bfd *);
+ /* Read in the dynamic relocs. */
+ long (*_bfd_canonicalize_dynamic_reloc)
+ (bfd *, arelent **, struct bfd_symbol **);
+
+ /* Opposite endian version of this target. */
+ const struct bfd_target * alternative_target;
+
+ /* Data for use by back-end routines, which isn't
+ generic enough to belong in this structure. */
+ const void *backend_data;
+
+} bfd_target;
+
+bfd_boolean bfd_set_default_target (const char *name);
+
+const bfd_target *bfd_find_target (const char *target_name, bfd *abfd);
+
+const bfd_target *bfd_get_target_info (const char *target_name,
+ bfd *abfd,
+ bfd_boolean *is_bigendian,
+ int *underscoring,
+ const char **def_target_arch);
+const char ** bfd_target_list (void);
+
+const bfd_target *bfd_search_for_target
+ (int (*search_func) (const bfd_target *, void *),
+ void *);
+
+/* Extracted from format.c. */
+bfd_boolean bfd_check_format (bfd *abfd, bfd_format format);
+
+bfd_boolean bfd_check_format_matches
+ (bfd *abfd, bfd_format format, char ***matching);
+
+bfd_boolean bfd_set_format (bfd *abfd, bfd_format format);
+
+const char *bfd_format_string (bfd_format format);
+
+/* Extracted from linker.c. */
+bfd_boolean bfd_link_split_section (bfd *abfd, asection *sec);
+
+#define bfd_link_split_section(abfd, sec) \
+ BFD_SEND (abfd, _bfd_link_split_section, (abfd, sec))
+
+bfd_boolean bfd_section_already_linked (bfd *abfd,
+ asection *sec,
+ struct bfd_link_info *info);
+
+#define bfd_section_already_linked(abfd, sec, info) \
+ BFD_SEND (abfd, _section_already_linked, (abfd, sec, info))
+
+bfd_boolean bfd_generic_define_common_symbol
+ (bfd *output_bfd, struct bfd_link_info *info,
+ struct bfd_link_hash_entry *h);
+
+#define bfd_define_common_symbol(output_bfd, info, h) \
+ BFD_SEND (output_bfd, _bfd_define_common_symbol, (output_bfd, info, h))
+
+struct bfd_elf_version_tree * bfd_find_version_for_sym
+ (struct bfd_elf_version_tree *verdefs,
+ const char *sym_name, bfd_boolean *hide);
+
+bfd_boolean bfd_hide_sym_by_version
+ (struct bfd_elf_version_tree *verdefs, const char *sym_name);
+
+/* Extracted from simple.c. */
+bfd_byte *bfd_simple_get_relocated_section_contents
+ (bfd *abfd, asection *sec, bfd_byte *outbuf, asymbol **symbol_table);
+
+/* Extracted from compress.c. */
+bfd_boolean bfd_compress_section_contents
+ (bfd *abfd, asection *section, bfd_byte *uncompressed_buffer,
+ bfd_size_type uncompressed_size);
+
+bfd_boolean bfd_get_full_section_contents
+ (bfd *abfd, asection *section, bfd_byte **ptr);
+
+void bfd_cache_section_contents
+ (asection *sec, void *contents);
+
+bfd_boolean bfd_is_section_compressed
+ (bfd *abfd, asection *section);
+
+bfd_boolean bfd_init_section_decompress_status
+ (bfd *abfd, asection *section);
+
+bfd_boolean bfd_init_section_compress_status
+ (bfd *abfd, asection *section);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/bfd/bfd.c b/bfd/bfd.c
new file mode 100644
index 0000000..2d9397b
--- /dev/null
+++ b/bfd/bfd.c
@@ -0,0 +1,1925 @@
+/* Generic BFD library interface and support routines.
+ Copyright (C) 1990-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+/*
+INODE
+typedef bfd, Error reporting, BFD front end, BFD front end
+
+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
+.
+.enum bfd_direction
+. {
+. no_direction = 0,
+. read_direction = 1,
+. write_direction = 2,
+. both_direction = 3
+. };
+.
+.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;
+.
+. {* The IOSTREAM, and corresponding IO vector that provide access
+. to the file backing the BFD. *}
+. void *iostream;
+. const struct bfd_iovec *iovec;
+.
+. {* 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... *}
+. ufile_ptr where;
+.
+. {* File modified time, if mtime_set is TRUE. *}
+. long mtime;
+.
+. {* A unique identifier of the BFD *}
+. unsigned int id;
+.
+. {* The format which belongs to the BFD. (object, core, etc.) *}
+. ENUM_BITFIELD (bfd_format) format : 3;
+.
+. {* The direction with which the BFD was opened. *}
+. ENUM_BITFIELD (bfd_direction) direction : 2;
+.
+. {* Format_specific flags. *}
+. flagword flags : 17;
+.
+. {* 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). *}
+.
+.#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
+.
+. {* This BFD has been created by the linker and doesn't correspond
+. to any input file. *}
+.#define BFD_LINKER_CREATED 0x1000
+.
+. {* This may be set before writing out a BFD to request that it
+. be written using values for UIDs, GIDs, timestamps, etc. that
+. will be consistent from run to run. *}
+.#define BFD_DETERMINISTIC_OUTPUT 0x2000
+.
+. {* Compress sections in this BFD. *}
+.#define BFD_COMPRESS 0x4000
+.
+. {* Decompress sections in this BFD. *}
+.#define BFD_DECOMPRESS 0x8000
+.
+. {* BFD is a dummy, for plugins. *}
+.#define BFD_PLUGIN 0x10000
+.
+. {* Flags bits to be saved in bfd_preserve_save. *}
+.#define BFD_FLAGS_SAVED \
+. (BFD_IN_MEMORY | BFD_COMPRESS | BFD_DECOMPRESS | BFD_PLUGIN)
+.
+. {* Flags bits which are for BFD use only. *}
+.#define BFD_FLAGS_FOR_BFD_USE_MASK \
+. (BFD_IN_MEMORY | BFD_COMPRESS | BFD_DECOMPRESS | BFD_LINKER_CREATED \
+. | BFD_PLUGIN | BFD_TRADITIONAL_FORMAT | BFD_DETERMINISTIC_OUTPUT)
+.
+. {* Is the file descriptor being cached? That is, can it be closed as
+. needed, and re-opened when accessed later? *}
+. unsigned int cacheable : 1;
+.
+. {* 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. *}
+. unsigned int target_defaulted : 1;
+.
+. {* ... and here: (``once'' means at least once). *}
+. unsigned int opened_once : 1;
+.
+. {* Set if we have a locally maintained mtime value, rather than
+. getting it from the file each time. *}
+. unsigned int mtime_set : 1;
+.
+. {* Flag set if symbols from this BFD should not be exported. *}
+. unsigned int no_export : 1;
+.
+. {* Remember when output has begun, to stop strange things
+. from happening. *}
+. unsigned int output_has_begun : 1;
+.
+. {* Have archive map. *}
+. unsigned int has_armap : 1;
+.
+. {* Set if this is a thin archive. *}
+. unsigned int is_thin_archive : 1;
+.
+. {* Set if only required symbols should be added in the link hash table for
+. this object. Used by VMS linkers. *}
+. unsigned int selective_search : 1;
+.
+. {* Set if this is the linker output BFD. *}
+. unsigned int is_linker_output : 1;
+.
+. {* 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. *}
+. ufile_ptr origin;
+.
+. {* The origin in the archive of the proxy entry. This will
+. normally be the same as origin, except for thin archives,
+. when it will contain the current offset of the proxy in the
+. thin archive rather than the offset of the bfd in its actual
+. container. *}
+. ufile_ptr proxy_origin;
+.
+. {* A hash table for section names. *}
+. struct bfd_hash_table section_htab;
+.
+. {* Pointer to linked list of sections. *}
+. struct bfd_section *sections;
+.
+. {* The last section on the section list. *}
+. struct bfd_section *section_last;
+.
+. {* The number of sections. *}
+. unsigned int section_count;
+.
+. {* A field used by _bfd_generic_link_add_archive_symbols. This will
+. be used only for archive elements. *}
+. int archive_pass;
+.
+. {* Stuff only useful for object files:
+. The start address. *}
+. bfd_vma start_address;
+.
+. {* Symbol table for output BFD (with symcount entries).
+. Also used by the linker to cache input BFD symbols. *}
+. struct bfd_symbol **outsymbols;
+.
+. {* Used for input and output. *}
+. unsigned int symcount;
+.
+. {* Used for slurped dynamic symbol tables. *}
+. unsigned int dynsymcount;
+.
+. {* Pointer to structure which contains architecture information. *}
+. const struct bfd_arch_info *arch_info;
+.
+. {* Stuff only useful for archives. *}
+. void *arelt_data;
+. struct bfd *my_archive; {* The containing archive BFD. *}
+. struct bfd *archive_next; {* The next BFD in the archive. *}
+. struct bfd *archive_head; {* The first BFD in the archive. *}
+. struct bfd *nested_archives; {* List of nested archive in a flattened
+. thin archive. *}
+.
+. union {
+. {* For input BFDs, a chain of BFDs involved in a link. *}
+. struct bfd *next;
+. {* For output BFD, the linker hash table. *}
+. struct bfd_link_hash_table *hash;
+. } link;
+.
+. {* 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 verilog_data_struct *verilog_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 mmo_data_struct *mmo_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;
+. struct mach_o_data_struct *mach_o_data;
+. struct mach_o_fat_data_struct *mach_o_fat_data;
+. struct plugin_data_struct *plugin_data;
+. struct bfd_pef_data_struct *pef_data;
+. struct bfd_pef_xlib_data_struct *pef_xlib_data;
+. struct bfd_sym_data_struct *sym_data;
+. void *any;
+. }
+. tdata;
+.
+. {* Used by the application to hold private data. *}
+. void *usrdata;
+.
+. {* Where all the allocated stuff under this BFD goes. This is a
+. struct objalloc *, but we use void * to avoid requiring the inclusion
+. of objalloc.h. *}
+. void *memory;
+.};
+.
+.{* See note beside bfd_set_section_userdata. *}
+.static inline bfd_boolean
+.bfd_set_cacheable (bfd * abfd, bfd_boolean val)
+.{
+. abfd->cacheable = val;
+. return TRUE;
+.}
+.
+*/
+
+#include "sysdep.h"
+#include <stdarg.h>
+#include "bfd.h"
+#include "bfdver.h"
+#include "libiberty.h"
+#include "demangle.h"
+#include "safe-ctype.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"
+
+#ifndef EXIT_FAILURE
+#define EXIT_FAILURE 1
+#endif
+
+
+/* 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 */
+
+/*
+INODE
+Error reporting, Miscellaneous, typedef bfd, BFD front end
+
+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_wrong_object_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_missing_dso,
+. 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_on_input,
+. bfd_error_invalid_error_code
+.}
+.bfd_error_type;
+.
+*/
+
+static bfd_error_type bfd_error = bfd_error_no_error;
+static bfd *input_bfd = NULL;
+static bfd_error_type input_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_("Archive object 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_("DSO missing from command line"),
+ 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_("Error reading %s: %s"),
+ 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 (void)
+{
+ 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}.
+ If @var{error_tag} is bfd_error_on_input, then this function
+ takes two more parameters, the input bfd where the error
+ occurred, and the bfd_error_type error.
+*/
+
+void
+bfd_set_error (bfd_error_type error_tag, ...)
+{
+ bfd_error = error_tag;
+ if (error_tag == bfd_error_on_input)
+ {
+ /* This is an error that occurred during bfd_close when
+ writing an archive, but on one of the input files. */
+ va_list ap;
+
+ va_start (ap, error_tag);
+ input_bfd = va_arg (ap, bfd *);
+ input_error = (bfd_error_type) va_arg (ap, int);
+ if (input_error >= bfd_error_on_input)
+ abort ();
+ va_end (ap);
+ }
+}
+
+/*
+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 (bfd_error_type error_tag)
+{
+#ifndef errno
+ extern int errno;
+#endif
+ if (error_tag == bfd_error_on_input)
+ {
+ char *buf;
+ const char *msg = bfd_errmsg (input_error);
+
+ if (asprintf (&buf, _(bfd_errmsgs [error_tag]), input_bfd->filename, msg)
+ != -1)
+ return buf;
+
+ /* Ick, what to do on out of memory? */
+ return msg;
+ }
+
+ if (error_tag == bfd_error_system_call)
+ return xstrerror (errno);
+
+ if (error_tag > bfd_error_invalid_error_code)
+ error_tag = bfd_error_invalid_error_code; /* sanity check */
+
+ return _(bfd_errmsgs [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 (const char *message)
+{
+ fflush (stdout);
+ 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 ()));
+ fflush (stderr);
+}
+
+/*
+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 overridden by the program.
+
+ The BFD error handler acts like printf.
+
+CODE_FRAGMENT
+.
+.typedef void (*bfd_error_handler_type) (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.
+ Like fprintf (stderr, ...), but also handles some extra format specifiers.
+
+ %A section name from section. For group components, print group name too.
+ %B file name from bfd. For archive components, prints archive too.
+
+ Note - because these two extra format specifiers require special handling
+ they are scanned for and processed in this function, before calling
+ vfprintf. This means that the *arguments* for these format specifiers
+ must be the first ones in the variable argument list, regardless of where
+ the specifiers appear in the format string. Thus for example calling
+ this function with a format string of:
+
+ "blah %s blah %A blah %d blah %B"
+
+ would involve passing the arguments as:
+
+ "blah %s blah %A blah %d blah %B",
+ asection_for_the_%A,
+ bfd_for_the_%B,
+ string_for_the_%s,
+ integer_for_the_%d);
+ */
+
+void
+_bfd_default_error_handler (const char *fmt, ...)
+{
+ va_list ap;
+ char *bufp;
+ const char *new_fmt, *p;
+ size_t avail = 1000;
+ char buf[1000];
+
+ /* PR 4992: Don't interrupt output being sent to stdout. */
+ fflush (stdout);
+
+ if (_bfd_error_program_name != NULL)
+ fprintf (stderr, "%s: ", _bfd_error_program_name);
+ else
+ fprintf (stderr, "BFD: ");
+
+ va_start (ap, fmt);
+ new_fmt = fmt;
+ bufp = buf;
+
+ /* Reserve enough space for the existing format string. */
+ avail -= strlen (fmt) + 1;
+ if (avail > 1000)
+ _exit (EXIT_FAILURE);
+
+ p = fmt;
+ while (1)
+ {
+ char *q;
+ size_t len, extra, trim;
+
+ p = strchr (p, '%');
+ if (p == NULL || p[1] == '\0')
+ {
+ if (new_fmt == buf)
+ {
+ len = strlen (fmt);
+ memcpy (bufp, fmt, len + 1);
+ }
+ break;
+ }
+
+ if (p[1] == 'A' || p[1] == 'B')
+ {
+ len = p - fmt;
+ memcpy (bufp, fmt, len);
+ bufp += len;
+ fmt = p + 2;
+ new_fmt = buf;
+
+ /* If we run out of space, tough, you lose your ridiculously
+ long file or section name. It's not safe to try to alloc
+ memory here; We might be printing an out of memory message. */
+ if (avail == 0)
+ {
+ *bufp++ = '*';
+ *bufp++ = '*';
+ *bufp = '\0';
+ }
+ else
+ {
+ if (p[1] == 'B')
+ {
+ bfd *abfd = va_arg (ap, bfd *);
+
+ if (abfd == NULL)
+ /* Invoking %B with a null bfd pointer is an internal error. */
+ abort ();
+ else if (abfd->my_archive)
+ snprintf (bufp, avail, "%s(%s)",
+ abfd->my_archive->filename, abfd->filename);
+ else
+ snprintf (bufp, avail, "%s", abfd->filename);
+ }
+ else
+ {
+ asection *sec = va_arg (ap, asection *);
+ bfd *abfd;
+ const char *group = NULL;
+ struct coff_comdat_info *ci;
+
+ if (sec == NULL)
+ /* Invoking %A with a null section pointer is an internal error. */
+ abort ();
+ abfd = sec->owner;
+ if (abfd != NULL
+ && bfd_get_flavour (abfd) == bfd_target_elf_flavour
+ && elf_next_in_group (sec) != NULL
+ && (sec->flags & SEC_GROUP) == 0)
+ group = elf_group_name (sec);
+ else if (abfd != NULL
+ && bfd_get_flavour (abfd) == bfd_target_coff_flavour
+ && (ci = bfd_coff_get_comdat_section (sec->owner,
+ sec)) != NULL)
+ group = ci->name;
+ if (group != NULL)
+ snprintf (bufp, avail, "%s[%s]", sec->name, group);
+ else
+ snprintf (bufp, avail, "%s", sec->name);
+ }
+ len = strlen (bufp);
+ avail = avail - len + 2;
+
+ /* We need to replace any '%' we printed by "%%".
+ First count how many. */
+ q = bufp;
+ bufp += len;
+ extra = 0;
+ while ((q = strchr (q, '%')) != NULL)
+ {
+ ++q;
+ ++extra;
+ }
+
+ /* If there isn't room, trim off the end of the string. */
+ q = bufp;
+ bufp += extra;
+ if (extra > avail)
+ {
+ trim = extra - avail;
+ bufp -= trim;
+ do
+ {
+ if (*--q == '%')
+ --extra;
+ }
+ while (--trim != 0);
+ *q = '\0';
+ avail = extra;
+ }
+ avail -= extra;
+
+ /* Now double all '%' chars, shuffling the string as we go. */
+ while (extra != 0)
+ {
+ while ((q[extra] = *q) != '%')
+ --q;
+ q[--extra] = '%';
+ --q;
+ }
+ }
+ }
+ p = p + 2;
+ }
+
+ vfprintf (stderr, new_fmt, ap);
+ va_end (ap);
+
+ /* On AIX, putc is implemented as a macro that triggers a -Wunused-value
+ warning, so use the fputc function to avoid it. */
+ fputc ('\n', stderr);
+ fflush (stderr);
+}
+
+/* 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 (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 (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 (void)
+{
+ return _bfd_error_handler;
+}
+
+/*
+SUBSECTION
+ BFD assert handler
+
+ If BFD finds an internal inconsistency, the bfd assert
+ handler is called with information on the BFD version, BFD
+ source file and line. If this happens, most programs linked
+ against BFD are expected to want to exit with an error, or mark
+ the current BFD operation as failed, so it is recommended to
+ override the default handler, which just calls
+ _bfd_error_handler and continues.
+
+CODE_FRAGMENT
+.
+.typedef void (*bfd_assert_handler_type) (const char *bfd_formatmsg,
+. const char *bfd_version,
+. const char *bfd_file,
+. int bfd_line);
+.
+*/
+
+/* Note the use of bfd_ prefix on the parameter names above: we want to
+ show which one is the message and which is the version by naming the
+ parameters, but avoid polluting the program-using-bfd namespace as
+ the typedef is visible in the exported headers that the program
+ includes. Below, it's just for consistency. */
+
+static void
+_bfd_default_assert_handler (const char *bfd_formatmsg,
+ const char *bfd_version,
+ const char *bfd_file,
+ int bfd_line)
+
+{
+ (*_bfd_error_handler) (bfd_formatmsg, bfd_version, bfd_file, bfd_line);
+}
+
+/* Similar to _bfd_error_handler, a program can decide to exit on an
+ internal BFD error. We use a non-variadic type to simplify passing
+ on parameters to other functions, e.g. _bfd_error_handler. */
+
+bfd_assert_handler_type _bfd_assert_handler = _bfd_default_assert_handler;
+
+/*
+FUNCTION
+ bfd_set_assert_handler
+
+SYNOPSIS
+ bfd_assert_handler_type bfd_set_assert_handler (bfd_assert_handler_type);
+
+DESCRIPTION
+ Set the BFD assert handler function. Returns the previous
+ function.
+*/
+
+bfd_assert_handler_type
+bfd_set_assert_handler (bfd_assert_handler_type pnew)
+{
+ bfd_assert_handler_type pold;
+
+ pold = _bfd_assert_handler;
+ _bfd_assert_handler = pnew;
+ return pold;
+}
+
+/*
+FUNCTION
+ bfd_get_assert_handler
+
+SYNOPSIS
+ bfd_assert_handler_type bfd_get_assert_handler (void);
+
+DESCRIPTION
+ Return the BFD assert handler function.
+*/
+
+bfd_assert_handler_type
+bfd_get_assert_handler (void)
+{
+ return _bfd_assert_handler;
+}
+
+/*
+INODE
+Miscellaneous, Memory Usage, Error reporting, BFD front end
+
+SECTION
+ Miscellaneous
+
+SUBSECTION
+ Miscellaneous functions
+*/
+
+/*
+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 (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 (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.
+
+*/
+
+void
+bfd_set_reloc (bfd *ignore_abfd ATTRIBUTE_UNUSED,
+ sec_ptr asect,
+ arelent **location,
+ unsigned int count)
+{
+ asect->orelocation = location;
+ asect->reloc_count = count;
+}
+
+/*
+FUNCTION
+ bfd_set_file_flags
+
+SYNOPSIS
+ bfd_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.
+
+*/
+
+bfd_boolean
+bfd_set_file_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 (const char *file, int line)
+{
+ (*_bfd_assert_handler) (_("BFD %s assertion fail %s:%d"),
+ BFD_VERSION_STRING, file, line);
+}
+
+/* A more or less friendly abort message. In libbfd.h abort is
+ defined to call this function. */
+
+void
+_bfd_abort (const char *file, int line, const char *fn)
+{
+ if (fn != NULL)
+ (*_bfd_error_handler)
+ (_("BFD %s internal error, aborting at %s line %d in %s\n"),
+ BFD_VERSION_STRING, file, line, fn);
+ else
+ (*_bfd_error_handler)
+ (_("BFD %s internal error, aborting at %s line %d\n"),
+ BFD_VERSION_STRING, file, line);
+ (*_bfd_error_handler) (_("Please report this bug.\n"));
+ _exit (EXIT_FAILURE);
+}
+
+/*
+FUNCTION
+ bfd_get_arch_size
+
+SYNOPSIS
+ int bfd_get_arch_size (bfd *abfd);
+
+DESCRIPTION
+ Returns the normalized architecture address size, in bits, as
+ determined by the object file's format. By normalized, we mean
+ either 32 or 64. For ELF, this information is included in the
+ header. Use bfd_arch_bits_per_address for number of bits in
+ the architecture address.
+
+RETURNS
+ Returns the arch size in bits if known, <<-1>> otherwise.
+*/
+
+int
+bfd_get_arch_size (bfd *abfd)
+{
+ if (abfd->xvec->flavour == bfd_target_elf_flavour)
+ return get_elf_backend_data (abfd)->s->arch_size;
+
+ return bfd_arch_bits_per_address (abfd) > 32 ? 64 : 32;
+}
+
+/*
+FUNCTION
+ bfd_get_sign_extend_vma
+
+SYNOPSIS
+ int bfd_get_sign_extend_vma (bfd *abfd);
+
+DESCRIPTION
+ Indicates if the target architecture "naturally" sign extends
+ an address. Some architectures implicitly sign extend address
+ values when they are converted to types larger than the size
+ of an address. For instance, bfd_get_start_address() will
+ return an address sign extended to fill a bfd_vma when this is
+ the case.
+
+RETURNS
+ Returns <<1>> if the target architecture is known to sign
+ extend addresses, <<0>> if the target architecture is known to
+ not sign extend addresses, and <<-1>> otherwise.
+*/
+
+int
+bfd_get_sign_extend_vma (bfd *abfd)
+{
+ char *name;
+
+ if (bfd_get_flavour (abfd) == bfd_target_elf_flavour)
+ return get_elf_backend_data (abfd)->sign_extend_vma;
+
+ name = bfd_get_target (abfd);
+
+ /* Return a proper value for DJGPP & PE COFF.
+ This function is required for DWARF2 support, but there is
+ no place to store this information in the COFF back end.
+ Should enough other COFF targets add support for DWARF2,
+ a place will have to be found. Until then, this hack will do. */
+ if (CONST_STRNEQ (name, "coff-go32")
+ || strcmp (name, "pe-i386") == 0
+ || strcmp (name, "pei-i386") == 0
+ || strcmp (name, "pe-x86-64") == 0
+ || strcmp (name, "pei-x86-64") == 0
+ || strcmp (name, "pe-arm-wince-little") == 0
+ || strcmp (name, "pei-arm-wince-little") == 0
+ || strcmp (name, "aixcoff-rs6000") == 0)
+ return 1;
+
+ if (CONST_STRNEQ (name, "mach-o"))
+ return 0;
+
+ bfd_set_error (bfd_error_wrong_format);
+ return -1;
+}
+
+/*
+FUNCTION
+ bfd_set_start_address
+
+SYNOPSIS
+ bfd_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.
+*/
+
+bfd_boolean
+bfd_set_start_address (bfd *abfd, bfd_vma vma)
+{
+ abfd->start_address = vma;
+ return TRUE;
+}
+
+/*
+FUNCTION
+ bfd_get_gp_size
+
+SYNOPSIS
+ unsigned 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.
+*/
+
+unsigned int
+bfd_get_gp_size (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, unsigned 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 (bfd *abfd, unsigned 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 (bfd *abfd)
+{
+ if (! abfd)
+ return 0;
+ if (abfd->format != bfd_object)
+ return 0;
+
+ 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 (bfd *abfd, bfd_vma v)
+{
+ if (! abfd)
+ abort ();
+ 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.
+
+ If the value would overflow, the maximum <<bfd_vma>> value is
+ returned.
+*/
+
+bfd_vma
+bfd_scan_vma (const char *string, const char **end, int base)
+{
+ bfd_vma value;
+ bfd_vma cutoff;
+ unsigned int cutlim;
+ int overflow;
+
+ /* Let the host do it if possible. */
+ if (sizeof (bfd_vma) <= sizeof (unsigned long))
+ return strtoul (string, (char **) end, base);
+
+#ifdef HAVE_STRTOULL
+ if (sizeof (bfd_vma) <= sizeof (unsigned long long))
+ return strtoull (string, (char **) end, base);
+#endif
+
+ if (base == 0)
+ {
+ if (string[0] == '0')
+ {
+ if ((string[1] == 'x') || (string[1] == 'X'))
+ base = 16;
+ else
+ base = 8;
+ }
+ }
+
+ if ((base < 2) || (base > 36))
+ base = 10;
+
+ if (base == 16
+ && string[0] == '0'
+ && (string[1] == 'x' || string[1] == 'X')
+ && ISXDIGIT (string[2]))
+ {
+ string += 2;
+ }
+
+ cutoff = (~ (bfd_vma) 0) / (bfd_vma) base;
+ cutlim = (~ (bfd_vma) 0) % (bfd_vma) base;
+ value = 0;
+ overflow = 0;
+ while (1)
+ {
+ unsigned int digit;
+
+ digit = *string;
+ if (ISDIGIT (digit))
+ digit = digit - '0';
+ else if (ISALPHA (digit))
+ digit = TOUPPER (digit) - 'A' + 10;
+ else
+ break;
+ if (digit >= (unsigned int) base)
+ break;
+ if (value > cutoff || (value == cutoff && digit > cutlim))
+ overflow = 1;
+ value = value * base + digit;
+ ++string;
+ }
+
+ if (overflow)
+ value = ~ (bfd_vma) 0;
+
+ if (end != NULL)
+ *end = string;
+
+ return value;
+}
+
+/*
+FUNCTION
+ bfd_copy_private_header_data
+
+SYNOPSIS
+ bfd_boolean bfd_copy_private_header_data (bfd *ibfd, bfd *obfd);
+
+DESCRIPTION
+ Copy private BFD header information from the BFD @var{ibfd} to the
+ the BFD @var{obfd}. This copies information that may require
+ sections to exist, but does not require symbol tables. 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_header_data(ibfd, obfd) \
+. BFD_SEND (obfd, _bfd_copy_private_header_data, \
+. (ibfd, obfd))
+
+*/
+
+/*
+FUNCTION
+ bfd_copy_private_bfd_data
+
+SYNOPSIS
+ bfd_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
+ bfd_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
+ bfd_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
+ Other functions
+
+DESCRIPTION
+ The following functions exist but have not yet been documented.
+
+.#define bfd_sizeof_headers(abfd, info) \
+. BFD_SEND (abfd, _bfd_sizeof_headers, (abfd, info))
+.
+.#define bfd_find_nearest_line(abfd, sec, syms, off, file, func, line) \
+. BFD_SEND (abfd, _bfd_find_nearest_line, \
+. (abfd, syms, sec, off, file, func, line, NULL))
+.
+.#define bfd_find_nearest_line_discriminator(abfd, sec, syms, off, file, func, \
+. line, disc) \
+. BFD_SEND (abfd, _bfd_find_nearest_line, \
+. (abfd, syms, sec, off, file, func, line, disc))
+.
+.#define bfd_find_line(abfd, syms, sym, file, line) \
+. BFD_SEND (abfd, _bfd_find_line, \
+. (abfd, syms, sym, file, line))
+.
+.#define bfd_find_inliner_info(abfd, file, func, line) \
+. BFD_SEND (abfd, _bfd_find_inliner_info, \
+. (abfd, file, func, line))
+.
+.#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_lookup_section_flags(link_info, flag_info, section) \
+. BFD_SEND (abfd, _bfd_lookup_section_flags, (link_info, flag_info, section))
+.
+.#define bfd_merge_sections(abfd, link_info) \
+. BFD_SEND (abfd, _bfd_merge_sections, (abfd, link_info))
+.
+.#define bfd_is_group_section(abfd, sec) \
+. BFD_SEND (abfd, _bfd_is_group_section, (abfd, sec))
+.
+.#define bfd_discard_group(abfd, sec) \
+. BFD_SEND (abfd, _bfd_discard_group, (abfd, sec))
+.
+.#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_link_just_syms(abfd, sec, info) \
+. BFD_SEND (abfd, _bfd_link_just_syms, (sec, 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_synthetic_symtab(abfd, count, syms, dyncount, dynsyms, ret) \
+. BFD_SEND (abfd, _bfd_get_synthetic_symtab, (abfd, count, syms, \
+. dyncount, dynsyms, ret))
+.
+.#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
+. (bfd *, struct bfd_link_info *, struct bfd_link_order *, bfd_byte *,
+. bfd_boolean, asymbol **);
+.
+
+*/
+
+bfd_byte *
+bfd_get_relocated_section_contents (bfd *abfd,
+ struct bfd_link_info *link_info,
+ struct bfd_link_order *link_order,
+ bfd_byte *data,
+ bfd_boolean relocatable,
+ asymbol **symbols)
+{
+ bfd *abfd2;
+ bfd_byte *(*fn) (bfd *, struct bfd_link_info *, struct bfd_link_order *,
+ bfd_byte *, bfd_boolean, asymbol **);
+
+ if (link_order->type == bfd_indirect_link_order)
+ {
+ abfd2 = link_order->u.indirect.section->owner;
+ if (abfd2 == NULL)
+ abfd2 = abfd;
+ }
+ else
+ abfd2 = abfd;
+
+ fn = abfd2->xvec->_bfd_get_relocated_section_contents;
+
+ return (*fn) (abfd, link_info, link_order, data, relocatable, symbols);
+}
+
+/* Record information about an ELF program header. */
+
+bfd_boolean
+bfd_record_phdr (bfd *abfd,
+ unsigned long type,
+ bfd_boolean flags_valid,
+ flagword flags,
+ bfd_boolean at_valid,
+ bfd_vma at,
+ bfd_boolean includes_filehdr,
+ bfd_boolean includes_phdrs,
+ unsigned int count,
+ asection **secs)
+{
+ struct elf_segment_map *m, **pm;
+ bfd_size_type amt;
+
+ if (bfd_get_flavour (abfd) != bfd_target_elf_flavour)
+ return TRUE;
+
+ amt = sizeof (struct elf_segment_map);
+ amt += ((bfd_size_type) count - 1) * sizeof (asection *);
+ m = (struct elf_segment_map *) bfd_zalloc (abfd, amt);
+ if (m == NULL)
+ return FALSE;
+
+ 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_seg_map (abfd); *pm != NULL; pm = &(*pm)->next)
+ ;
+ *pm = m;
+
+ return TRUE;
+}
+
+#ifdef BFD64
+/* Return true iff this target is 32-bit. */
+
+static bfd_boolean
+is32bit (bfd *abfd)
+{
+ if (bfd_get_flavour (abfd) == bfd_target_elf_flavour)
+ {
+ const struct elf_backend_data *bed = get_elf_backend_data (abfd);
+ return bed->s->elfclass == ELFCLASS32;
+ }
+
+ /* For non-ELF targets, use architecture information. */
+ return bfd_arch_bits_per_address (abfd) <= 32;
+}
+#endif
+
+/* bfd_sprintf_vma and bfd_fprintf_vma display an address in the
+ target's address size. */
+
+void
+bfd_sprintf_vma (bfd *abfd ATTRIBUTE_UNUSED, char *buf, bfd_vma value)
+{
+#ifdef BFD64
+ if (is32bit (abfd))
+ {
+ sprintf (buf, "%08lx", (unsigned long) value & 0xffffffff);
+ return;
+ }
+#endif
+ sprintf_vma (buf, value);
+}
+
+void
+bfd_fprintf_vma (bfd *abfd ATTRIBUTE_UNUSED, void *stream, bfd_vma value)
+{
+#ifdef BFD64
+ if (is32bit (abfd))
+ {
+ fprintf ((FILE *) stream, "%08lx", (unsigned long) value & 0xffffffff);
+ return;
+ }
+#endif
+ fprintf_vma ((FILE *) stream, value);
+}
+
+/*
+FUNCTION
+ bfd_alt_mach_code
+
+SYNOPSIS
+ bfd_boolean bfd_alt_mach_code (bfd *abfd, int alternative);
+
+DESCRIPTION
+
+ When more than one machine code number is available for the
+ same machine type, this function can be used to switch between
+ the preferred one (alternative == 0) and any others. Currently,
+ only ELF supports this feature, with up to two alternate
+ machine codes.
+*/
+
+bfd_boolean
+bfd_alt_mach_code (bfd *abfd, int alternative)
+{
+ if (bfd_get_flavour (abfd) == bfd_target_elf_flavour)
+ {
+ int code;
+
+ switch (alternative)
+ {
+ case 0:
+ code = get_elf_backend_data (abfd)->elf_machine_code;
+ break;
+
+ case 1:
+ code = get_elf_backend_data (abfd)->elf_machine_alt1;
+ if (code == 0)
+ return FALSE;
+ break;
+
+ case 2:
+ code = get_elf_backend_data (abfd)->elf_machine_alt2;
+ if (code == 0)
+ return FALSE;
+ break;
+
+ default:
+ return FALSE;
+ }
+
+ elf_elfheader (abfd)->e_machine = code;
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/*
+FUNCTION
+ bfd_emul_get_maxpagesize
+
+SYNOPSIS
+ bfd_vma bfd_emul_get_maxpagesize (const char *);
+
+DESCRIPTION
+ Returns the maximum page size, in bytes, as determined by
+ emulation.
+
+RETURNS
+ Returns the maximum page size in bytes for ELF, 0 otherwise.
+*/
+
+bfd_vma
+bfd_emul_get_maxpagesize (const char *emul)
+{
+ const bfd_target *target;
+
+ target = bfd_find_target (emul, NULL);
+ if (target != NULL
+ && target->flavour == bfd_target_elf_flavour)
+ return xvec_get_elf_backend_data (target)->maxpagesize;
+
+ return 0;
+}
+
+static void
+bfd_elf_set_pagesize (const bfd_target *target, bfd_vma size,
+ int offset, const bfd_target *orig_target)
+{
+ if (target->flavour == bfd_target_elf_flavour)
+ {
+ const struct elf_backend_data *bed;
+
+ bed = xvec_get_elf_backend_data (target);
+ *((bfd_vma *) ((char *) bed + offset)) = size;
+ }
+
+ if (target->alternative_target
+ && target->alternative_target != orig_target)
+ bfd_elf_set_pagesize (target->alternative_target, size, offset,
+ orig_target);
+}
+
+/*
+FUNCTION
+ bfd_emul_set_maxpagesize
+
+SYNOPSIS
+ void bfd_emul_set_maxpagesize (const char *, bfd_vma);
+
+DESCRIPTION
+ For ELF, set the maximum page size for the emulation. It is
+ a no-op for other formats.
+
+*/
+
+void
+bfd_emul_set_maxpagesize (const char *emul, bfd_vma size)
+{
+ const bfd_target *target;
+
+ target = bfd_find_target (emul, NULL);
+ if (target)
+ bfd_elf_set_pagesize (target, size,
+ offsetof (struct elf_backend_data,
+ maxpagesize), target);
+}
+
+/*
+FUNCTION
+ bfd_emul_get_commonpagesize
+
+SYNOPSIS
+ bfd_vma bfd_emul_get_commonpagesize (const char *);
+
+DESCRIPTION
+ Returns the common page size, in bytes, as determined by
+ emulation.
+
+RETURNS
+ Returns the common page size in bytes for ELF, 0 otherwise.
+*/
+
+bfd_vma
+bfd_emul_get_commonpagesize (const char *emul)
+{
+ const bfd_target *target;
+
+ target = bfd_find_target (emul, NULL);
+ if (target != NULL
+ && target->flavour == bfd_target_elf_flavour)
+ return xvec_get_elf_backend_data (target)->commonpagesize;
+
+ return 0;
+}
+
+/*
+FUNCTION
+ bfd_emul_set_commonpagesize
+
+SYNOPSIS
+ void bfd_emul_set_commonpagesize (const char *, bfd_vma);
+
+DESCRIPTION
+ For ELF, set the common page size for the emulation. It is
+ a no-op for other formats.
+
+*/
+
+void
+bfd_emul_set_commonpagesize (const char *emul, bfd_vma size)
+{
+ const bfd_target *target;
+
+ target = bfd_find_target (emul, NULL);
+ if (target)
+ bfd_elf_set_pagesize (target, size,
+ offsetof (struct elf_backend_data,
+ commonpagesize), target);
+}
+
+/*
+FUNCTION
+ bfd_demangle
+
+SYNOPSIS
+ char *bfd_demangle (bfd *, const char *, int);
+
+DESCRIPTION
+ Wrapper around cplus_demangle. Strips leading underscores and
+ other such chars that would otherwise confuse the demangler.
+ If passed a g++ v3 ABI mangled name, returns a buffer allocated
+ with malloc holding the demangled name. Returns NULL otherwise
+ and on memory alloc failure.
+*/
+
+char *
+bfd_demangle (bfd *abfd, const char *name, int options)
+{
+ char *res, *alloc;
+ const char *pre, *suf;
+ size_t pre_len;
+ bfd_boolean skip_lead;
+
+ skip_lead = (abfd != NULL
+ && *name != '\0'
+ && bfd_get_symbol_leading_char (abfd) == *name);
+ if (skip_lead)
+ ++name;
+
+ /* This is a hack for better error reporting on XCOFF, PowerPC64-ELF
+ or the MS PE format. These formats have a number of leading '.'s
+ on at least some symbols, so we remove all dots to avoid
+ confusing the demangler. */
+ pre = name;
+ while (*name == '.' || *name == '$')
+ ++name;
+ pre_len = name - pre;
+
+ /* Strip off @plt and suchlike too. */
+ alloc = NULL;
+ suf = strchr (name, '@');
+ if (suf != NULL)
+ {
+ alloc = (char *) bfd_malloc (suf - name + 1);
+ if (alloc == NULL)
+ return NULL;
+ memcpy (alloc, name, suf - name);
+ alloc[suf - name] = '\0';
+ name = alloc;
+ }
+
+ res = cplus_demangle (name, options);
+
+ if (alloc != NULL)
+ free (alloc);
+
+ if (res == NULL)
+ {
+ if (skip_lead)
+ {
+ size_t len = strlen (pre) + 1;
+ alloc = (char *) bfd_malloc (len);
+ if (alloc == NULL)
+ return NULL;
+ memcpy (alloc, pre, len);
+ return alloc;
+ }
+ return NULL;
+ }
+
+ /* Put back any prefix or suffix. */
+ if (pre_len != 0 || suf != NULL)
+ {
+ size_t len;
+ size_t suf_len;
+ char *final;
+
+ len = strlen (res);
+ if (suf == NULL)
+ suf = res + len;
+ suf_len = strlen (suf) + 1;
+ final = (char *) bfd_malloc (pre_len + len + suf_len);
+ if (final != NULL)
+ {
+ memcpy (final, pre, pre_len);
+ memcpy (final + pre_len, res, len);
+ memcpy (final + pre_len + len, suf, suf_len);
+ }
+ free (res);
+ res = final;
+ }
+
+ return res;
+}
diff --git a/bfd/bfd.m4 b/bfd/bfd.m4
new file mode 100644
index 0000000..6b711e2
--- /dev/null
+++ b/bfd/bfd.m4
@@ -0,0 +1,61 @@
+dnl This file was derived from acinclude.m4.
+dnl
+dnl Copyright (C) 2012-2014 Free Software Foundation, Inc.
+dnl
+dnl This file is free software; you can redistribute it and/or modify
+dnl it under the terms of the GNU General Public License as published by
+dnl the Free Software Foundation; either version 3 of the License, or
+dnl (at your option) any later version.
+dnl
+dnl This program is distributed in the hope that it will be useful,
+dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
+dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+dnl GNU General Public License for more details.
+dnl
+dnl You should have received a copy of the GNU General Public License
+dnl along with this program; see the file COPYING3. If not see
+dnl <http://www.gnu.org/licenses/>.
+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([
+#define _SYSCALL32
+/* Needed for new procfs interface on sparc-solaris. */
+#define _STRUCTURED_PROC 1
+#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([
+#define _SYSCALL32
+/* Needed for new procfs interface on sparc-solaris. */
+#define _STRUCTURED_PROC 1
+#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/bfdio.c b/bfd/bfdio.c
new file mode 100644
index 0000000..14619f5
--- /dev/null
+++ b/bfd/bfdio.c
@@ -0,0 +1,621 @@
+/* Low-level I/O routines for BFDs.
+
+ Copyright (C) 1990-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include <limits.h>
+#include "bfd.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
+
+#ifndef FD_CLOEXEC
+#define FD_CLOEXEC 1
+#endif
+
+file_ptr
+real_ftell (FILE *file)
+{
+#if defined (HAVE_FTELLO64)
+ return ftello64 (file);
+#elif defined (HAVE_FTELLO)
+ return ftello (file);
+#else
+ return ftell (file);
+#endif
+}
+
+int
+real_fseek (FILE *file, file_ptr offset, int whence)
+{
+#if defined (HAVE_FSEEKO64)
+ return fseeko64 (file, offset, whence);
+#elif defined (HAVE_FSEEKO)
+ return fseeko (file, offset, whence);
+#else
+ return fseek (file, offset, whence);
+#endif
+}
+
+/* Mark FILE as close-on-exec. Return FILE. FILE may be NULL, in
+ which case nothing is done. */
+static FILE *
+close_on_exec (FILE *file)
+{
+#if defined (HAVE_FILENO) && defined (F_GETFD)
+ if (file)
+ {
+ int fd = fileno (file);
+ int old = fcntl (fd, F_GETFD, 0);
+ if (old >= 0)
+ fcntl (fd, F_SETFD, old | FD_CLOEXEC);
+ }
+#endif
+ return file;
+}
+
+FILE *
+real_fopen (const char *filename, const char *modes)
+{
+#ifdef VMS
+ char *vms_attr;
+
+ /* On VMS, fopen allows file attributes as optional arguments.
+ We need to use them but we'd better to use the common prototype.
+ In fopen-vms.h, they are separated from the mode with a comma.
+ Split here. */
+ vms_attr = strchr (modes, ',');
+ if (vms_attr == NULL)
+ {
+ /* No attributes. */
+ return close_on_exec (fopen (filename, modes));
+ }
+ else
+ {
+ /* Attributes found. Split. */
+ size_t modes_len = strlen (modes) + 1;
+ char attrs[modes_len + 1];
+ char *at[3];
+ int i;
+
+ memcpy (attrs, modes, modes_len);
+ at[0] = attrs;
+ for (i = 0; i < 2; i++)
+ {
+ at[i + 1] = strchr (at[i], ',');
+ BFD_ASSERT (at[i + 1] != NULL);
+ *(at[i + 1]++) = 0; /* Replace ',' with a nul, and skip it. */
+ }
+ return close_on_exec (fopen (filename, at[0], at[1], at[2]));
+ }
+#else /* !VMS */
+#if defined (HAVE_FOPEN64)
+ return close_on_exec (fopen64 (filename, modes));
+#else
+ return close_on_exec (fopen (filename, modes));
+#endif
+#endif /* !VMS */
+}
+
+/*
+INTERNAL_DEFINITION
+ struct bfd_iovec
+
+DESCRIPTION
+
+ The <<struct bfd_iovec>> contains the internal file I/O class.
+ Each <<BFD>> has an instance of this class and all file I/O is
+ routed through it (it is assumed that the instance implements
+ all methods listed below).
+
+.struct bfd_iovec
+.{
+. {* To avoid problems with macros, a "b" rather than "f"
+. prefix is prepended to each method name. *}
+. {* Attempt to read/write NBYTES on ABFD's IOSTREAM storing/fetching
+. bytes starting at PTR. Return the number of bytes actually
+. transfered (a read past end-of-file returns less than NBYTES),
+. or -1 (setting <<bfd_error>>) if an error occurs. *}
+. file_ptr (*bread) (struct bfd *abfd, void *ptr, file_ptr nbytes);
+. file_ptr (*bwrite) (struct bfd *abfd, const void *ptr,
+. file_ptr nbytes);
+. {* Return the current IOSTREAM file offset, or -1 (setting <<bfd_error>>
+. if an error occurs. *}
+. file_ptr (*btell) (struct bfd *abfd);
+. {* For the following, on successful completion a value of 0 is returned.
+. Otherwise, a value of -1 is returned (and <<bfd_error>> is set). *}
+. int (*bseek) (struct bfd *abfd, file_ptr offset, int whence);
+. int (*bclose) (struct bfd *abfd);
+. int (*bflush) (struct bfd *abfd);
+. int (*bstat) (struct bfd *abfd, struct stat *sb);
+. {* Mmap a part of the files. ADDR, LEN, PROT, FLAGS and OFFSET are the usual
+. mmap parameter, except that LEN and OFFSET do not need to be page
+. aligned. Returns (void *)-1 on failure, mmapped address on success.
+. Also write in MAP_ADDR the address of the page aligned buffer and in
+. MAP_LEN the size mapped (a page multiple). Use unmap with MAP_ADDR and
+. MAP_LEN to unmap. *}
+. void *(*bmmap) (struct bfd *abfd, void *addr, bfd_size_type len,
+. int prot, int flags, file_ptr offset,
+. void **map_addr, bfd_size_type *map_len);
+.};
+
+.extern const struct bfd_iovec _bfd_memory_iovec;
+
+*/
+
+
+/* Return value is amount read. */
+
+bfd_size_type
+bfd_bread (void *ptr, bfd_size_type size, bfd *abfd)
+{
+ size_t nread;
+
+ /* If this is an archive element, don't read past the end of
+ this element. */
+ if (abfd->arelt_data != NULL)
+ {
+ bfd_size_type maxbytes = arelt_size (abfd);
+
+ if (abfd->where + size > maxbytes)
+ {
+ if (abfd->where >= maxbytes)
+ return 0;
+ size = maxbytes - abfd->where;
+ }
+ }
+
+ if (abfd->iovec)
+ nread = abfd->iovec->bread (abfd, ptr, size);
+ else
+ nread = 0;
+ if (nread != (size_t) -1)
+ abfd->where += nread;
+
+ return nread;
+}
+
+bfd_size_type
+bfd_bwrite (const void *ptr, bfd_size_type size, bfd *abfd)
+{
+ size_t nwrote;
+
+ if (abfd->iovec)
+ nwrote = abfd->iovec->bwrite (abfd, ptr, size);
+ else
+ nwrote = 0;
+
+ if (nwrote != (size_t) -1)
+ abfd->where += nwrote;
+ if (nwrote != size)
+ {
+#ifdef ENOSPC
+ errno = ENOSPC;
+#endif
+ bfd_set_error (bfd_error_system_call);
+ }
+ return nwrote;
+}
+
+file_ptr
+bfd_tell (bfd *abfd)
+{
+ file_ptr ptr;
+
+ if (abfd->iovec)
+ {
+ bfd *parent_bfd = abfd;
+ ptr = abfd->iovec->btell (abfd);
+
+ while (parent_bfd->my_archive != NULL)
+ {
+ ptr -= parent_bfd->origin;
+ parent_bfd = parent_bfd->my_archive;
+ }
+ }
+ else
+ ptr = 0;
+
+ abfd->where = ptr;
+ return ptr;
+}
+
+int
+bfd_flush (bfd *abfd)
+{
+ if (abfd->iovec)
+ return abfd->iovec->bflush (abfd);
+ return 0;
+}
+
+/* Returns 0 for success, negative value for failure (in which case
+ bfd_get_error can retrieve the error code). */
+int
+bfd_stat (bfd *abfd, struct stat *statbuf)
+{
+ int result;
+
+ if (abfd->iovec)
+ result = abfd->iovec->bstat (abfd, statbuf);
+ else
+ result = -1;
+
+ 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 (bfd *abfd, file_ptr position, int direction)
+{
+ int result;
+ 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->format != bfd_archive && abfd->my_archive == 0)
+ {
+ if (direction == SEEK_SET && (bfd_vma) 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. */
+ }
+
+ file_position = position;
+ if (direction == SEEK_SET)
+ {
+ bfd *parent_bfd = abfd;
+
+ while (parent_bfd->my_archive != NULL)
+ {
+ file_position += parent_bfd->origin;
+ parent_bfd = parent_bfd->my_archive;
+ }
+ }
+
+ if (abfd->iovec)
+ result = abfd->iovec->bseek (abfd, file_position, direction);
+ else
+ result = -1;
+
+ 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;
+}
+
+/*
+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 (bfd *abfd)
+{
+ struct stat buf;
+
+ if (abfd->mtime_set)
+ return abfd->mtime;
+
+ if (abfd->iovec == NULL)
+ return 0;
+
+ if (abfd->iovec->bstat (abfd, &buf) != 0)
+ return 0;
+
+ abfd->mtime = buf.st_mtime; /* Save value in case anyone wants it */
+ return buf.st_mtime;
+}
+
+/*
+FUNCTION
+ bfd_get_size
+
+SYNOPSIS
+ file_ptr 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 question, "is the
+ size reasonable?".
+*/
+
+file_ptr
+bfd_get_size (bfd *abfd)
+{
+ struct stat buf;
+
+ if (abfd->iovec == NULL)
+ return 0;
+
+ if (abfd->iovec->bstat (abfd, &buf) != 0)
+ return 0;
+
+ return buf.st_size;
+}
+
+
+/*
+FUNCTION
+ bfd_mmap
+
+SYNOPSIS
+ void *bfd_mmap (bfd *abfd, void *addr, bfd_size_type len,
+ int prot, int flags, file_ptr offset,
+ void **map_addr, bfd_size_type *map_len);
+
+DESCRIPTION
+ Return mmap()ed region of the file, if possible and implemented.
+ LEN and OFFSET do not need to be page aligned. The page aligned
+ address and length are written to MAP_ADDR and MAP_LEN.
+
+*/
+
+void *
+bfd_mmap (bfd *abfd, void *addr, bfd_size_type len,
+ int prot, int flags, file_ptr offset,
+ void **map_addr, bfd_size_type *map_len)
+{
+ void *ret = (void *)-1;
+
+ if (abfd->iovec == NULL)
+ return ret;
+
+ return abfd->iovec->bmmap (abfd, addr, len, prot, flags, offset,
+ map_addr, map_len);
+}
+
+/* Memory file I/O operations. */
+
+static file_ptr
+memory_bread (bfd *abfd, void *ptr, file_ptr size)
+{
+ struct bfd_in_memory *bim;
+ bfd_size_type get;
+
+ bim = (struct bfd_in_memory *) abfd->iostream;
+ get = size;
+ if (abfd->where + get > bim->size)
+ {
+ if (bim->size < (bfd_size_type) abfd->where)
+ get = 0;
+ else
+ get = bim->size - abfd->where;
+ bfd_set_error (bfd_error_file_truncated);
+ }
+ memcpy (ptr, bim->buffer + abfd->where, (size_t) get);
+ return get;
+}
+
+static file_ptr
+memory_bwrite (bfd *abfd, const void *ptr, file_ptr size)
+{
+ struct bfd_in_memory *bim = (struct bfd_in_memory *) abfd->iostream;
+
+ if (abfd->where + size > bim->size)
+ {
+ bfd_size_type newsize, oldsize;
+
+ oldsize = (bim->size + 127) & ~(bfd_size_type) 127;
+ bim->size = abfd->where + size;
+ /* Round up to cut down on memory fragmentation */
+ newsize = (bim->size + 127) & ~(bfd_size_type) 127;
+ if (newsize > oldsize)
+ {
+ bim->buffer = (bfd_byte *) bfd_realloc_or_free (bim->buffer, newsize);
+ if (bim->buffer == NULL)
+ {
+ bim->size = 0;
+ return 0;
+ }
+ if (newsize > bim->size)
+ memset (bim->buffer + bim->size, 0, newsize - bim->size);
+ }
+ }
+ memcpy (bim->buffer + abfd->where, ptr, (size_t) size);
+ return size;
+}
+
+static file_ptr
+memory_btell (bfd *abfd)
+{
+ return abfd->where;
+}
+
+static int
+memory_bseek (bfd *abfd, file_ptr position, int direction)
+{
+ file_ptr nwhere;
+ struct bfd_in_memory *bim;
+
+ bim = (struct bfd_in_memory *) abfd->iostream;
+
+ if (direction == SEEK_SET)
+ nwhere = position;
+ else
+ nwhere = abfd->where + position;
+
+ if (nwhere < 0)
+ {
+ abfd->where = 0;
+ errno = EINVAL;
+ return -1;
+ }
+
+ if ((bfd_size_type)nwhere > bim->size)
+ {
+ if (abfd->direction == write_direction
+ || abfd->direction == both_direction)
+ {
+ bfd_size_type newsize, oldsize;
+
+ oldsize = (bim->size + 127) & ~(bfd_size_type) 127;
+ bim->size = nwhere;
+ /* Round up to cut down on memory fragmentation */
+ newsize = (bim->size + 127) & ~(bfd_size_type) 127;
+ if (newsize > oldsize)
+ {
+ bim->buffer = (bfd_byte *) bfd_realloc_or_free (bim->buffer, newsize);
+ if (bim->buffer == NULL)
+ {
+ errno = EINVAL;
+ bim->size = 0;
+ return -1;
+ }
+ memset (bim->buffer + oldsize, 0, newsize - oldsize);
+ }
+ }
+ else
+ {
+ abfd->where = bim->size;
+ errno = EINVAL;
+ bfd_set_error (bfd_error_file_truncated);
+ return -1;
+ }
+ }
+ return 0;
+}
+
+static int
+memory_bclose (struct bfd *abfd)
+{
+ struct bfd_in_memory *bim = (struct bfd_in_memory *) abfd->iostream;
+
+ if (bim->buffer != NULL)
+ free (bim->buffer);
+ free (bim);
+ abfd->iostream = NULL;
+
+ return 0;
+}
+
+static int
+memory_bflush (bfd *abfd ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+static int
+memory_bstat (bfd *abfd, struct stat *statbuf)
+{
+ struct bfd_in_memory *bim = (struct bfd_in_memory *) abfd->iostream;
+
+ memset (statbuf, 0, sizeof (*statbuf));
+ statbuf->st_size = bim->size;
+
+ return 0;
+}
+
+static void *
+memory_bmmap (bfd *abfd ATTRIBUTE_UNUSED, void *addr ATTRIBUTE_UNUSED,
+ bfd_size_type len ATTRIBUTE_UNUSED, int prot ATTRIBUTE_UNUSED,
+ int flags ATTRIBUTE_UNUSED, file_ptr offset ATTRIBUTE_UNUSED,
+ void **map_addr ATTRIBUTE_UNUSED,
+ bfd_size_type *map_len ATTRIBUTE_UNUSED)
+{
+ return (void *)-1;
+}
+
+const struct bfd_iovec _bfd_memory_iovec =
+{
+ &memory_bread, &memory_bwrite, &memory_btell, &memory_bseek,
+ &memory_bclose, &memory_bflush, &memory_bstat, &memory_bmmap
+};
diff --git a/bfd/bfdwin.c b/bfd/bfdwin.c
new file mode 100644
index 0000000..2af868a
--- /dev/null
+++ b/bfd/bfdwin.c
@@ -0,0 +1,263 @@
+/* Support for memory-mapped windows into a BFD.
+ Copyright (C) 1995-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+
+#include "bfd.h"
+#include "libbfd.h"
+
+/* Currently, if USE_MMAP is undefined, none of the window stuff is
+ used. Enabled by --with-mmap. */
+
+#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;
+
+/* 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. */
+
+/*
+INTERNAL_DEFINITION
+
+.struct _bfd_window_internal {
+. struct _bfd_window_internal *next;
+. void *data;
+. bfd_size_type size;
+. int refcount : 31; {* should be enough... *}
+. unsigned mapped : 1; {* 1 = mmap, 0 = malloc *}
+.};
+*/
+
+void
+bfd_init_window (bfd_window *windowp)
+{
+ windowp->data = 0;
+ windowp->i = 0;
+ windowp->size = 0;
+}
+
+void
+bfd_free_window (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, (unsigned long) 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;
+
+bfd_boolean
+bfd_get_file_window (bfd *abfd,
+ file_ptr offset,
+ bfd_size_type size,
+ bfd_window *windowp,
+ bfd_boolean writable)
+{
+ static size_t pagesize;
+ bfd_window_internal *i = windowp->i;
+ bfd_size_type 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 == NULL)
+ {
+ i = bfd_zmalloc (sizeof (bfd_window_internal));
+ if (i == NULL)
+ return FALSE;
+ i->data = NULL;
+ }
+#ifdef HAVE_MMAP
+ if (ok_to_map
+ && (i->data == NULL || i->mapped == 1)
+ && (abfd->flags & BFD_IN_MEMORY) == 0)
+ {
+ file_ptr file_offset, offset2;
+ size_t real_size;
+ int fd;
+
+ /* Find the real file and the real offset into it. */
+ while (abfd->my_archive != NULL)
+ {
+ offset += abfd->origin;
+ abfd = abfd->my_archive;
+ }
+
+ /* Seek into the file, to ensure it is open if cacheable. */
+ if (abfd->iostream == NULL
+ && (abfd->iovec == NULL
+ || abfd->iovec->bseek (abfd, offset, SEEK_SET) != 0))
+ goto free_and_fail;
+
+ fd = fileno ((FILE *) abfd->iostream);
+ /* 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 != NULL && i->size < size)
+ {
+ munmap (i->data, i->size);
+ i->data = NULL;
+ }
+ 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 == (void *) -1)
+ {
+ /* An error happened. Report it, or try using malloc, or
+ something. */
+ bfd_set_error (bfd_error_system_call);
+ windowp->data = 0;
+ if (debug_windows)
+ fprintf (stderr, "\t\tmmap failed!\n");
+ goto free_and_fail;
+ }
+ 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 = (bfd_byte *) i->data + offset2;
+ windowp->size = size;
+ i->mapped = 1;
+ i->refcount = 1;
+ windowp->i = i;
+ 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 = bfd_realloc_or_free (i->data, size_to_alloc);
+ if (debug_windows)
+ fprintf (stderr, "\t-> %p\n", i->data);
+ if (i->data == NULL)
+ {
+ if (size_to_alloc == 0)
+ {
+ windowp->i = i;
+ return TRUE;
+ }
+ goto free_and_fail;
+ }
+ i->refcount = 1;
+ if (bfd_seek (abfd, offset, SEEK_SET) != 0)
+ goto free_and_fail;
+ i->size = bfd_bread (i->data, size, abfd);
+ if (i->size != size)
+ goto free_and_fail;
+ 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;
+ windowp->i = i;
+ return TRUE;
+
+ free_and_fail:
+ /* We have a bfd_window_internal, but an error occurred. Free it. */
+ free (i);
+ return FALSE;
+}
+
+#endif /* USE_MMAP */
diff --git a/bfd/binary.c b/bfd/binary.c
new file mode 100644
index 0000000..d35e859
--- /dev/null
+++ b/bfd/binary.c
@@ -0,0 +1,368 @@
+/* BFD back-end for binary objects.
+ Copyright (C) 1994-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, 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 "sysdep.h"
+#include "bfd.h"
+#include "safe-ctype.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
+
+/* Create a binary object. Invoked via bfd_set_format. */
+
+static bfd_boolean
+binary_mkobject (bfd *abfd ATTRIBUTE_UNUSED)
+{
+ 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 (bfd *abfd)
+{
+ struct stat statbuf;
+ asection *sec;
+ flagword flags;
+
+ 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. */
+ flags = SEC_ALLOC | SEC_LOAD | SEC_DATA | SEC_HAS_CONTENTS;
+ sec = bfd_make_section_with_flags (abfd, ".data", flags);
+ if (sec == NULL)
+ return NULL;
+ sec->vma = 0;
+ sec->size = statbuf.st_size;
+ sec->filepos = 0;
+
+ abfd->tdata.any = (void *) 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 bfd_boolean
+binary_get_section_contents (bfd *abfd,
+ asection *section ATTRIBUTE_UNUSED,
+ void * location,
+ file_ptr offset,
+ bfd_size_type count)
+{
+ if (bfd_seek (abfd, offset, SEEK_SET) != 0
+ || bfd_bread (location, 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 (bfd *abfd ATTRIBUTE_UNUSED)
+{
+ return (BIN_SYMS + 1) * sizeof (asymbol *);
+}
+
+/* Create a symbol name based on the bfd's filename. */
+
+static char *
+mangle_name (bfd *abfd, char *suffix)
+{
+ bfd_size_type 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 (*p))
+ *p = '_';
+
+ return buf;
+}
+
+/* Return the symbol table. */
+
+static long
+binary_canonicalize_symtab (bfd *abfd, asymbol **alocation)
+{
+ asection *sec = (asection *) abfd->tdata.any;
+ asymbol *syms;
+ unsigned int i;
+ bfd_size_type amt = BIN_SYMS * sizeof (asymbol);
+
+ syms = (asymbol *) bfd_alloc (abfd, amt);
+ if (syms == NULL)
+ return -1;
+
+ /* 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->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->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;
+}
+
+#define binary_make_empty_symbol _bfd_generic_make_empty_symbol
+#define binary_print_symbol _bfd_nosymbols_print_symbol
+
+/* Get information about a symbol. */
+
+static void
+binary_get_symbol_info (bfd *ignore_abfd ATTRIBUTE_UNUSED,
+ 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_find_line _bfd_nosymbols_find_line
+#define binary_find_inliner_info _bfd_nosymbols_find_inliner_info
+#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_bfd_is_target_special_symbol ((bfd_boolean (*) (bfd *, asymbol *)) bfd_false)
+
+/* 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 bfd_boolean
+binary_set_section_contents (bfd *abfd,
+ asection *sec,
+ const void * data,
+ file_ptr offset,
+ bfd_size_type size)
+{
+ if (size == 0)
+ return TRUE;
+
+ if (! abfd->output_has_begun)
+ {
+ bfd_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))
+ && (s->size > 0)
+ && (! 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)
+ || (s->size == 0))
+ 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 (bfd *abfd ATTRIBUTE_UNUSED,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED)
+{
+ 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_lookup_section_flags bfd_generic_lookup_section_flags
+#define binary_bfd_merge_sections bfd_generic_merge_sections
+#define binary_bfd_is_group_section bfd_generic_is_group_section
+#define binary_bfd_discard_group bfd_generic_discard_group
+#define binary_section_already_linked _bfd_generic_section_already_linked
+#define binary_bfd_define_common_symbol bfd_generic_define_common_symbol
+#define binary_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
+#define binary_bfd_link_just_syms _bfd_generic_link_just_syms
+#define binary_bfd_copy_link_hash_symbol_type \
+ _bfd_generic_copy_link_hash_symbol_type
+#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 */
+ 255, /* match priority. */
+ 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_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 (_bfd_norelocs),
+ BFD_JUMP_TABLE_WRITE (binary),
+ BFD_JUMP_TABLE_LINK (binary),
+ BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
+
+ NULL,
+
+ NULL
+};
diff --git a/bfd/bout.c b/bfd/bout.c
new file mode 100644
index 0000000..a27df58
--- /dev/null
+++ b/bfd/bout.c
@@ -0,0 +1,1481 @@
+/* BFD back-end for Intel 960 b.out binaries.
+ Copyright (C) 1990-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+#include "bfdlink.h"
+#include "genlink.h"
+#include "bout.h"
+#include "libiberty.h"
+
+#include "aout/stab_gnu.h"
+#include "libaout.h" /* BFD a.out internal data structures. */
+
+#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),
+};
+
+/* Swaps the information in an executable header taken from a raw byte
+ stream memory image, into the internal exec_header structure. */
+
+static void
+bout_swap_exec_header_in (bfd *abfd,
+ struct external_exec *bytes,
+ struct internal_exec *execp)
+{
+ /* Now fill in fields in the execp, from the bytes in the raw data. */
+ execp->a_info = 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. */
+
+static void
+bout_swap_exec_header_out (bfd *abfd,
+ struct internal_exec *execp,
+ struct external_exec *bytes)
+{
+ /* Now fill in fields in the raw data, from the fields in the exec struct. */
+ 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;
+}
+
+/* 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 (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)->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;
+}
+
+static const bfd_target *
+b_out_object_p (bfd *abfd)
+{
+ struct internal_exec anexec;
+ struct external_exec exec_bytes;
+ bfd_size_type amt = EXEC_BYTES_SIZE;
+
+ if (bfd_bread ((void *) &exec_bytes, amt, abfd) != amt)
+ {
+ if (bfd_get_error () != bfd_error_system_call)
+ bfd_set_error (bfd_error_wrong_format);
+ return 0;
+ }
+
+ anexec.a_info = 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);
+}
+
+struct bout_data_struct
+ {
+ struct aoutdata a;
+ struct internal_exec e;
+ };
+
+static bfd_boolean
+b_out_mkobject (bfd *abfd)
+{
+ struct bout_data_struct *rawptr;
+ bfd_size_type amt = sizeof (struct bout_data_struct);
+
+ rawptr = bfd_zalloc (abfd, amt);
+ if (rawptr == NULL)
+ return FALSE;
+
+ abfd->tdata.bout_data = rawptr;
+ exec_hdr (abfd) = &rawptr->e;
+
+ obj_textsec (abfd) = NULL;
+ obj_datasec (abfd) = NULL;
+ obj_bsssec (abfd) = NULL;
+
+ return TRUE;
+}
+
+static int
+b_out_symbol_cmp (const void * a_ptr, const void * b_ptr)
+{
+ struct aout_symbol ** a = (struct aout_symbol **) a_ptr;
+ struct aout_symbol ** b = (struct aout_symbol **) b_ptr;
+ 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 bfd_boolean
+b_out_squirt_out_relocs (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;
+ bfd_size_type natsize;
+ int extern_mask, pcrel_mask, len_2, callj_mask;
+
+ if (count == 0)
+ return TRUE;
+
+ generic = section->orelocation;
+ natsize = (bfd_size_type) count * sizeof (struct relocation_info);
+ native = 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;
+
+ 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 + ARRAY_SIZE (howto_align_table) - 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_bwrite ((void *) native, natsize, abfd) != natsize)
+ {
+ free (native);
+ return FALSE;
+ }
+
+ free (native);
+
+ return TRUE;
+}
+
+static bfd_boolean
+b_out_write_object_contents (bfd *abfd)
+{
+ struct external_exec swapped_hdr;
+ bfd_size_type amt;
+
+ if (! aout_32_make_sections (abfd))
+ return FALSE;
+
+ exec_hdr (abfd)->a_info = BMAGIC;
+
+ exec_hdr (abfd)->a_text = obj_textsec (abfd)->size;
+ exec_hdr (abfd)->a_data = obj_datasec (abfd)->size;
+ exec_hdr (abfd)->a_bss = obj_bsssec (abfd)->size;
+ exec_hdr (abfd)->a_syms = bfd_get_symcount (abfd) * 12;
+ exec_hdr (abfd)->a_entry = bfd_get_start_address (abfd);
+ exec_hdr (abfd)->a_trsize = (obj_textsec (abfd)->reloc_count) * 8;
+ exec_hdr (abfd)->a_drsize = (obj_datasec (abfd)->reloc_count) * 8;
+
+ 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);
+
+ amt = EXEC_BYTES_SIZE;
+ if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0
+ || bfd_bwrite ((void *) &swapped_hdr, amt, abfd) != amt)
+ 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, (size_t) (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)
+
+static bfd_vma
+get_value (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,
+ TRUE)))
+ abort ();
+ value = 0;
+ }
+ }
+ else
+ value = symbol->value + output_addr (symbol->section);
+
+ /* Add the value contained in the relocation. */
+ value += reloc->addend;
+
+ return value;
+}
+
+/* Magic to turn callx into calljx. */
+
+static bfd_reloc_status_type
+calljx_callback (bfd *abfd,
+ struct bfd_link_info *link_info,
+ arelent *reloc_entry,
+ void * src,
+ void * 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, (bfd_vma) 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, (bfd_vma) word, dst);
+ return bfd_reloc_ok;
+}
+
+/* Magic to turn call into callj. */
+
+static bfd_reloc_status_type
+callj_callback (bfd *abfd,
+ struct bfd_link_info *link_info,
+ arelent *reloc_entry,
+ void * data,
+ unsigned int srcidx,
+ unsigned int dstidx,
+ asection *input_section,
+ bfd_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, (bfd_vma) word, (bfd_byte *) data + dstidx);
+ return bfd_reloc_ok;
+}
+
+static reloc_howto_type *
+b_out_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ 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;
+ }
+}
+
+static reloc_howto_type *
+b_out_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ const char *r_name)
+{
+ if (strcasecmp (howto_reloc_callj.name, r_name) == 0)
+ return &howto_reloc_callj;
+ if (strcasecmp (howto_reloc_abs32.name, r_name) == 0)
+ return &howto_reloc_abs32;
+ if (strcasecmp (howto_reloc_pcrel24.name, r_name) == 0)
+ return &howto_reloc_pcrel24;
+
+ return NULL;
+}
+
+/* Allocate enough room for all the reloc entries, plus pointers to them all. */
+
+static bfd_boolean
+b_out_slurp_reloc_table (bfd *abfd, sec_ptr asect, asymbol **symbols)
+{
+ 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;
+ bfd_size_type reloc_size, amt;
+ 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;
+ 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;
+ count = reloc_size / sizeof (struct relocation_info);
+
+ relocs = bfd_malloc (reloc_size);
+ if (!relocs && reloc_size != 0)
+ return FALSE;
+
+ amt = ((bfd_size_type) count + 1) * sizeof (arelent);
+ reloc_cache = bfd_malloc (amt);
+ if (!reloc_cache)
+ {
+ if (relocs != NULL)
+ free (relocs);
+ return FALSE;
+ }
+
+ if (bfd_bread ((void *) relocs, 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 = 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 an 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 (FALSE);
+ 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;
+}
+
+/* This is stupid. This function should be a boolean predicate. */
+
+static long
+b_out_canonicalize_reloc (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 (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 bfd_boolean
+b_out_set_section_contents (bfd *abfd,
+ asection *section,
+ const void * location,
+ file_ptr offset,
+ bfd_size_type count)
+{
+ if (! abfd->output_has_begun)
+ {
+ /* Set by bfd.c handler. */
+ if (! aout_32_make_sections (abfd))
+ return FALSE;
+
+ obj_textsec (abfd)->filepos = sizeof (struct external_exec);
+ obj_datasec (abfd)->filepos = obj_textsec (abfd)->filepos
+ + obj_textsec (abfd)->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 TRUE;
+
+ return bfd_bwrite ((void *) location, count, abfd) == count;
+}
+
+static bfd_boolean
+b_out_set_arch_mach (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 (bfd *ignore_abfd ATTRIBUTE_UNUSED,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED)
+{
+ return sizeof (struct external_exec);
+}
+
+static void
+perform_slip (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 (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 (bfd *abfd,
+ asection *input_section,
+ arelent *r,
+ unsigned int shrink)
+{
+ bfd_vma dot = output_addr (input_section) + r->address;
+ bfd_vma old_end;
+ bfd_vma new_end;
+ unsigned 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);
+
+ 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 bfd_boolean
+b_out_bfd_relax_section (bfd *abfd,
+ asection *i,
+ struct bfd_link_info *link_info,
+ bfd_boolean *again)
+{
+ /* Get enough memory to hold the stuff. */
+ bfd *input_bfd = i->owner;
+ asection *input_section = i;
+ unsigned int shrink = 0 ;
+ arelent **reloc_vector = NULL;
+ long reloc_size = bfd_get_reloc_upper_bound (input_bfd, input_section);
+
+ if (link_info->relocatable)
+ (*link_info->callbacks->einfo)
+ (_("%P%F: --relax and -r may not be used together\n"));
+
+ 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 = bfd_malloc ((bfd_size_type) 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->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 (bfd *output_bfd,
+ struct bfd_link_info *link_info,
+ struct bfd_link_order *link_order,
+ bfd_byte *data,
+ bfd_boolean relocatable,
+ 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 relocatable output, don't bother to relax. */
+ if (relocatable)
+ return bfd_generic_get_relocated_section_contents (output_bfd, link_info,
+ link_order,
+ data, relocatable,
+ symbols);
+
+ reloc_vector = bfd_malloc ((bfd_size_type) reloc_size);
+ if (reloc_vector == NULL && reloc_size != 0)
+ goto error_return;
+
+ /* Read in the section. */
+ BFD_ASSERT (bfd_get_section_contents (input_bfd,
+ input_section,
+ data,
+ (bfd_vma) 0,
+ input_section->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 ((bfd_vma) reloc->addend
+ <= input_section->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, (bfd_vma) 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, (bfd_vma) 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_find_line _bfd_nosymbols_find_line
+#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_link_just_syms _bfd_generic_link_just_syms
+#define b_out_bfd_copy_link_hash_symbol_type \
+ _bfd_generic_copy_link_hash_symbol_type
+#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 b_out_bfd_lookup_section_flags bfd_generic_lookup_section_flags
+#define b_out_bfd_merge_sections bfd_generic_merge_sections
+#define b_out_bfd_is_group_section bfd_generic_is_group_section
+#define b_out_bfd_discard_group bfd_generic_discard_group
+#define b_out_section_already_linked _bfd_generic_section_already_linked
+#define b_out_bfd_define_common_symbol bfd_generic_define_common_symbol
+#define aout_32_get_section_contents_in_window _bfd_generic_get_section_contents_in_window
+
+extern const bfd_target bout_le_vec;
+
+const bfd_target bout_be_vec =
+{
+ "b.out.big", /* Name. */
+ bfd_target_aout_flavour,
+ BFD_ENDIAN_LITTLE, /* Data byte order. */
+ BFD_ENDIAN_BIG, /* Header byte order. */
+ (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. */
+ 0, /* match priority. */
+ 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, /* Headers. */
+ {_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),
+
+ & bout_le_vec,
+
+ NULL
+};
+
+const bfd_target bout_le_vec =
+{
+ "b.out.little", /* Name. */
+ bfd_target_aout_flavour,
+ BFD_ENDIAN_LITTLE, /* Data byte order. */
+ BFD_ENDIAN_LITTLE, /* Header byte order. */
+ (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. */
+ 0, /* match priority. */
+ 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, /* Headers. */
+
+ {_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),
+
+ & bout_be_vec,
+
+ NULL
+};
diff --git a/bfd/cache.c b/bfd/cache.c
new file mode 100644
index 0000000..ffda004
--- /dev/null
+++ b/bfd/cache.c
@@ -0,0 +1,644 @@
+/* BFD library -- caching of file descriptors.
+
+ Copyright (C) 1990-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, 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.
+
+SUBSECTION
+ Caching functions
+*/
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+#include "libiberty.h"
+#include "bfd_stdint.h"
+
+#ifdef HAVE_MMAP
+#include <sys/mman.h>
+#endif
+
+/* In some cases we can optimize cache operation when reopening files.
+ For instance, a flush is entirely unnecessary if the file is already
+ closed, so a flush would use CACHE_NO_OPEN. Similarly, a seek using
+ SEEK_SET or SEEK_END need not first seek to the current position.
+ For stat we ignore seek errors, just in case the file has changed
+ while we weren't looking. If it has, then it's possible that the
+ file is shorter and we don't want a seek error to prevent us doing
+ the stat. */
+enum cache_flag {
+ CACHE_NORMAL = 0,
+ CACHE_NO_OPEN = 1,
+ CACHE_NO_SEEK = 2,
+ CACHE_NO_SEEK_ERROR = 4
+};
+
+/* The maximum number of files which the cache will keep open at
+ one time. When needed call bfd_cache_max_open to initialize. */
+
+static int max_open_files = 0;
+
+/* Set max_open_files, if not already set, to 12.5% of the allowed open
+ file descriptors, but at least 10, and return the value. */
+static int
+bfd_cache_max_open (void)
+{
+ if (max_open_files == 0)
+ {
+ int max;
+#ifdef HAVE_GETRLIMIT
+ struct rlimit rlim;
+ if (getrlimit (RLIMIT_NOFILE, &rlim) == 0
+ && rlim.rlim_cur != (rlim_t) RLIM_INFINITY)
+ max = rlim.rlim_cur / 8;
+ else
+#endif /* HAVE_GETRLIMIT */
+#ifdef _SC_OPEN_MAX
+ max = sysconf (_SC_OPEN_MAX) / 8;
+#else
+ max = 10;
+#endif /* _SC_OPEN_MAX */
+ max_open_files = max < 10 ? 10 : max;
+ }
+
+ return max_open_files;
+}
+
+/* The number of BFD files we have open. */
+
+static int open_files;
+
+/* 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. */
+
+static bfd *bfd_last_cache = NULL;
+
+/* Insert a BFD into the cache. */
+
+static void
+insert (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 void
+snip (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;
+ }
+}
+
+/* Close a BFD and remove it from the cache. */
+
+static bfd_boolean
+bfd_cache_delete (bfd *abfd)
+{
+ bfd_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;
+}
+
+/* We need to open a new file, and the cache is full. Find the least
+ recently used cacheable BFD and close it. */
+
+static bfd_boolean
+close_one (void)
+{
+ register bfd *to_kill;
+
+ if (bfd_last_cache == NULL)
+ to_kill = NULL;
+ else
+ {
+ for (to_kill = bfd_last_cache->lru_prev;
+ ! to_kill->cacheable;
+ to_kill = to_kill->lru_prev)
+ {
+ if (to_kill == bfd_last_cache)
+ {
+ to_kill = NULL;
+ break;
+ }
+ }
+ }
+
+ if (to_kill == NULL)
+ {
+ /* There are no open cacheable BFD's. */
+ return TRUE;
+ }
+
+ to_kill->where = real_ftell ((FILE *) to_kill->iostream);
+
+ return bfd_cache_delete (to_kill);
+}
+
+/* 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, flag) \
+ ((x) == bfd_last_cache \
+ ? (FILE *) (bfd_last_cache->iostream) \
+ : bfd_cache_lookup_worker (x, flag))
+
+/* 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. It will return NULL
+ if it is unable to (re)open the @var{abfd}. */
+
+static FILE *
+bfd_cache_lookup_worker (bfd *abfd, enum cache_flag flag)
+{
+ bfd *orig_bfd = abfd;
+ if ((abfd->flags & BFD_IN_MEMORY) != 0)
+ abort ();
+
+ while (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);
+ }
+ return (FILE *) abfd->iostream;
+ }
+
+ if (flag & CACHE_NO_OPEN)
+ return NULL;
+
+ if (bfd_open_file (abfd) == NULL)
+ ;
+ else if (!(flag & CACHE_NO_SEEK)
+ && real_fseek ((FILE *) abfd->iostream, abfd->where, SEEK_SET) != 0
+ && !(flag & CACHE_NO_SEEK_ERROR))
+ bfd_set_error (bfd_error_system_call);
+ else
+ return (FILE *) abfd->iostream;
+
+ (*_bfd_error_handler) (_("reopening %B: %s\n"),
+ orig_bfd, bfd_errmsg (bfd_get_error ()));
+ return NULL;
+}
+
+static file_ptr
+cache_btell (struct bfd *abfd)
+{
+ FILE *f = bfd_cache_lookup (abfd, CACHE_NO_OPEN);
+ if (f == NULL)
+ return abfd->where;
+ return real_ftell (f);
+}
+
+static int
+cache_bseek (struct bfd *abfd, file_ptr offset, int whence)
+{
+ FILE *f = bfd_cache_lookup (abfd, whence != SEEK_CUR ? CACHE_NO_SEEK : CACHE_NORMAL);
+ if (f == NULL)
+ return -1;
+ return real_fseek (f, offset, whence);
+}
+
+/* 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 file_ptr
+cache_bread_1 (struct bfd *abfd, void *buf, file_ptr nbytes)
+{
+ FILE *f;
+ file_ptr nread;
+ /* 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 (nbytes == 0)
+ return 0;
+
+ f = bfd_cache_lookup (abfd, CACHE_NORMAL);
+ if (f == NULL)
+ return 0;
+
+#if defined (__VAX) && defined (VMS)
+ /* Apparently fread on Vax VMS does not keep the record length
+ information. */
+ nread = read (fileno (f), buf, nbytes);
+ /* 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. */
+ if (nread == (file_ptr)-1)
+ {
+ bfd_set_error (bfd_error_system_call);
+ return nread;
+ }
+#else
+ nread = fread (buf, 1, nbytes, f);
+ /* 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. */
+ if (nread < nbytes && ferror (f))
+ {
+ bfd_set_error (bfd_error_system_call);
+ return nread;
+ }
+#endif
+ if (nread < nbytes)
+ /* This may or may not be an error, but in case the calling code
+ bails out because of it, set the right error code. */
+ bfd_set_error (bfd_error_file_truncated);
+ return nread;
+}
+
+static file_ptr
+cache_bread (struct bfd *abfd, void *buf, file_ptr nbytes)
+{
+ file_ptr nread = 0;
+
+ /* Some filesystems are unable to handle reads that are too large
+ (for instance, NetApp shares with oplocks turned off). To avoid
+ hitting this limitation, we read the buffer in chunks of 8MB max. */
+ while (nread < nbytes)
+ {
+ const file_ptr max_chunk_size = 0x800000;
+ file_ptr chunk_size = nbytes - nread;
+ file_ptr chunk_nread;
+
+ if (chunk_size > max_chunk_size)
+ chunk_size = max_chunk_size;
+
+ chunk_nread = cache_bread_1 (abfd, (char *) buf + nread, chunk_size);
+
+ /* Update the nread count.
+
+ We just have to be careful of the case when cache_bread_1 returns
+ a negative count: If this is our first read, then set nread to
+ that negative count in order to return that negative value to the
+ caller. Otherwise, don't add it to our total count, or we would
+ end up returning a smaller number of bytes read than we actually
+ did. */
+ if (nread == 0 || chunk_nread > 0)
+ nread += chunk_nread;
+
+ if (chunk_nread < chunk_size)
+ break;
+ }
+
+ return nread;
+}
+
+static file_ptr
+cache_bwrite (struct bfd *abfd, const void *where, file_ptr nbytes)
+{
+ file_ptr nwrite;
+ FILE *f = bfd_cache_lookup (abfd, CACHE_NORMAL);
+
+ if (f == NULL)
+ return 0;
+ nwrite = fwrite (where, 1, nbytes, f);
+ if (nwrite < nbytes && ferror (f))
+ {
+ bfd_set_error (bfd_error_system_call);
+ return -1;
+ }
+ return nwrite;
+}
+
+static int
+cache_bclose (struct bfd *abfd)
+{
+ return bfd_cache_close (abfd) - 1;
+}
+
+static int
+cache_bflush (struct bfd *abfd)
+{
+ int sts;
+ FILE *f = bfd_cache_lookup (abfd, CACHE_NO_OPEN);
+
+ if (f == NULL)
+ return 0;
+ sts = fflush (f);
+ if (sts < 0)
+ bfd_set_error (bfd_error_system_call);
+ return sts;
+}
+
+static int
+cache_bstat (struct bfd *abfd, struct stat *sb)
+{
+ int sts;
+ FILE *f = bfd_cache_lookup (abfd, CACHE_NO_SEEK_ERROR);
+
+ if (f == NULL)
+ return -1;
+ sts = fstat (fileno (f), sb);
+ if (sts < 0)
+ bfd_set_error (bfd_error_system_call);
+ return sts;
+}
+
+static void *
+cache_bmmap (struct bfd *abfd ATTRIBUTE_UNUSED,
+ void *addr ATTRIBUTE_UNUSED,
+ bfd_size_type len ATTRIBUTE_UNUSED,
+ int prot ATTRIBUTE_UNUSED,
+ int flags ATTRIBUTE_UNUSED,
+ file_ptr offset ATTRIBUTE_UNUSED,
+ void **map_addr ATTRIBUTE_UNUSED,
+ bfd_size_type *map_len ATTRIBUTE_UNUSED)
+{
+ void *ret = (void *) -1;
+
+ if ((abfd->flags & BFD_IN_MEMORY) != 0)
+ abort ();
+#ifdef HAVE_MMAP
+ else
+ {
+ static uintptr_t pagesize_m1;
+ FILE *f;
+ file_ptr pg_offset;
+ bfd_size_type pg_len;
+
+ f = bfd_cache_lookup (abfd, CACHE_NO_SEEK_ERROR);
+ if (f == NULL)
+ return ret;
+
+ if (pagesize_m1 == 0)
+ pagesize_m1 = getpagesize () - 1;
+
+ /* Handle archive members. */
+ if (abfd->my_archive != NULL)
+ offset += abfd->origin;
+
+ /* Align. */
+ pg_offset = offset & ~pagesize_m1;
+ pg_len = (len + (offset - pg_offset) + pagesize_m1) & ~pagesize_m1;
+
+ ret = mmap (addr, pg_len, prot, flags, fileno (f), pg_offset);
+ if (ret == (void *) -1)
+ bfd_set_error (bfd_error_system_call);
+ else
+ {
+ *map_addr = ret;
+ *map_len = pg_len;
+ ret = (char *) ret + (offset & pagesize_m1);
+ }
+ }
+#endif
+
+ return ret;
+}
+
+static const struct bfd_iovec cache_iovec =
+{
+ &cache_bread, &cache_bwrite, &cache_btell, &cache_bseek,
+ &cache_bclose, &cache_bflush, &cache_bstat, &cache_bmmap
+};
+
+/*
+INTERNAL_FUNCTION
+ bfd_cache_init
+
+SYNOPSIS
+ bfd_boolean bfd_cache_init (bfd *abfd);
+
+DESCRIPTION
+ Add a newly opened BFD to the cache.
+*/
+
+bfd_boolean
+bfd_cache_init (bfd *abfd)
+{
+ BFD_ASSERT (abfd->iostream != NULL);
+ if (open_files >= bfd_cache_max_open ())
+ {
+ if (! close_one ())
+ return FALSE;
+ }
+ abfd->iovec = &cache_iovec;
+ insert (abfd);
+ ++open_files;
+ return TRUE;
+}
+
+/*
+INTERNAL_FUNCTION
+ bfd_cache_close
+
+SYNOPSIS
+ bfd_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.
+*/
+
+bfd_boolean
+bfd_cache_close (bfd *abfd)
+{
+ if (abfd->iovec != &cache_iovec)
+ return TRUE;
+
+ if (abfd->iostream == NULL)
+ /* Previously closed. */
+ return TRUE;
+
+ return bfd_cache_delete (abfd);
+}
+
+/*
+FUNCTION
+ bfd_cache_close_all
+
+SYNOPSIS
+ bfd_boolean bfd_cache_close_all (void);
+
+DESCRIPTION
+ Remove all BFDs from the cache. If the attached file is open,
+ then close it too.
+
+RETURNS
+ <<FALSE>> is returned if closing one of the file fails, <<TRUE>> is
+ returned if all is well.
+*/
+
+bfd_boolean
+bfd_cache_close_all ()
+{
+ bfd_boolean ret = TRUE;
+
+ while (bfd_last_cache != NULL)
+ ret &= bfd_cache_close (bfd_last_cache);
+
+ return ret;
+}
+
+/*
+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 (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 = real_fopen (abfd->filename, FOPEN_RB);
+ break;
+ case both_direction:
+ case write_direction:
+ if (abfd->opened_once)
+ {
+ abfd->iostream = real_fopen (abfd->filename, FOPEN_RUB);
+ if (abfd->iostream == NULL)
+ abfd->iostream = real_fopen (abfd->filename, FOPEN_WUB);
+ }
+ else
+ {
+ /* Create the file.
+
+ Some operating systems won't let us overwrite a running
+ binary. For them, we want to unlink the file first.
+
+ However, gcc 2.95 will create temporary files using
+ O_EXCL and tight permissions to prevent other users from
+ substituting other .o files during the compilation. gcc
+ will then tell the assembler to use the newly created
+ file as an output file. If we unlink the file here, we
+ open a brief window when another user could still
+ substitute a file.
+
+ So we unlink the output file if and only if it has
+ non-zero size. */
+#ifndef __MSDOS__
+ /* Don't do this for MSDOS: it doesn't care about overwriting
+ a running binary, but if this file is already open by
+ another BFD, we will be in deep trouble if we delete an
+ open file. In fact, objdump does just that if invoked with
+ the --info option. */
+ struct stat s;
+
+ if (stat (abfd->filename, &s) == 0 && s.st_size != 0)
+ unlink_if_ordinary (abfd->filename);
+#endif
+ abfd->iostream = real_fopen (abfd->filename, FOPEN_WUB);
+ abfd->opened_once = TRUE;
+ }
+ break;
+ }
+
+ if (abfd->iostream == NULL)
+ bfd_set_error (bfd_error_system_call);
+ else
+ {
+ if (! bfd_cache_init (abfd))
+ return NULL;
+ }
+
+ return (FILE *) abfd->iostream;
+}
diff --git a/bfd/cf-i386lynx.c b/bfd/cf-i386lynx.c
new file mode 100644
index 0000000..480c275
--- /dev/null
+++ b/bfd/cf-i386lynx.c
@@ -0,0 +1,34 @@
+/* BFD back-end for Intel 386 COFF LynxOS files.
+ Copyright (C) 1993-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+
+#define TARGET_SYM i386_coff_lynx_vec
+#define TARGET_NAME "coff-i386-lynx"
+
+#define LYNXOS
+
+#define COFF_LONG_FILENAMES
+
+#define bfd_pe_print_pdata NULL
+
+#include "coff-i386.c"
diff --git a/bfd/cf-sparclynx.c b/bfd/cf-sparclynx.c
new file mode 100644
index 0000000..2be0048
--- /dev/null
+++ b/bfd/cf-sparclynx.c
@@ -0,0 +1,29 @@
+/* BFD back-end for Sparc COFF LynxOS files.
+ Copyright (C) 1993-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#define TARGET_SYM sparc_coff_lynx_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 0000000..36845a2
--- /dev/null
+++ b/bfd/cisco-core.c
@@ -0,0 +1,418 @@
+/* BFD back-end for CISCO crash dumps.
+ Copyright (C) 1994-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.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
+
+int crash_info_locs[] =
+{
+ 0x0250, /* mips, ppc, x86, i960 */
+ 0x0400, /* m68k, mips, x86, i960 */
+ 0x0FFC, /* m68k, mips, ppc, x86, i960 */
+ 0x3000, /* ppc */
+ 0x4FFC, /* m68k */
+ -1
+};
+
+#define CRASH_MAGIC 0xdead1234
+#define MASK_ADDR(x) ((x) & 0x0fffffff) /* Mask crash info address */
+
+typedef enum
+{
+ CRASH_REASON_NOTCRASHED = 0,
+ CRASH_REASON_EXCEPTION = 1,
+ CRASH_REASON_CORRUPT = 2,
+} crashreason;
+
+typedef struct
+{
+ 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) */
+ char textbase[4]; /* Base of .text section (not in V3 crash info) */
+ char database[4]; /* Base of .data section (not in V3 crash info) */
+ char bssbase[4]; /* Base of .bss section (not in V3 crash info) */
+} crashinfo_external;
+
+struct cisco_core_struct
+{
+ int sig;
+};
+
+#define cisco_core_file_matches_executable_p generic_core_file_matches_executable_p
+#define cisco_core_file_pid _bfd_nocore_core_file_pid
+
+/* Examine the file for a crash info struct at the offset given by
+ CRASH_INFO_LOC. */
+
+static const bfd_target *
+cisco_core_file_validate (bfd *abfd, int crash_info_loc)
+{
+ char buf[4];
+ unsigned int crashinfo_offset;
+ crashinfo_external crashinfo;
+ bfd_size_type nread;
+ unsigned int magic;
+ unsigned int version;
+ unsigned int rambase;
+ sec_ptr asect;
+ struct stat statbuf;
+ bfd_size_type amt;
+ flagword flags;
+
+ if (bfd_seek (abfd, (file_ptr) crash_info_loc, SEEK_SET) != 0)
+ return NULL;
+
+ nread = bfd_bread (buf, (bfd_size_type) 4, abfd);
+ if (nread != 4)
+ {
+ if (bfd_get_error () != bfd_error_system_call)
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+ crashinfo_offset = MASK_ADDR (bfd_get_32 (abfd, buf));
+
+ if (bfd_seek (abfd, (file_ptr) crashinfo_offset, SEEK_SET) != 0)
+ {
+ /* Most likely we failed because of a bogus (huge) offset */
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+
+ nread = bfd_bread (&crashinfo, (bfd_size_type) 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;
+ }
+
+ magic = bfd_get_32 (abfd, crashinfo.magic);
+ if (magic != CRASH_MAGIC)
+ {
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+
+ version = bfd_get_32 (abfd, crashinfo.version);
+ if (version == 0)
+ {
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+ else if (version == 1)
+ {
+ /* V1 core dumps don't specify the dump base, assume 0 */
+ rambase = 0;
+ }
+ else
+ {
+ rambase = bfd_get_32 (abfd, crashinfo.rambase);
+ }
+
+ /* OK, we believe you. You're a core file. */
+
+ amt = sizeof (struct cisco_core_struct);
+ abfd->tdata.cisco_core_data = (struct cisco_core_struct *) bfd_zmalloc (amt);
+ 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;
+ }
+
+ /* Create a ".data" section that maps the entire file, which is
+ essentially a dump of the target system's RAM. */
+
+ flags = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS;
+ asect = bfd_make_section_anyway_with_flags (abfd, ".data", flags);
+ if (asect == NULL)
+ goto error_return;
+ /* The size of memory is the size of the core file itself. */
+ asect->size = statbuf.st_size;
+ asect->vma = rambase;
+ asect->filepos = 0;
+
+ /* Create a ".crash" section to allow access to the saved
+ crash information. */
+
+ flags = SEC_HAS_CONTENTS;
+ asect = bfd_make_section_anyway_with_flags (abfd, ".crash", flags);
+ if (asect == NULL)
+ goto error_return;
+ asect->vma = 0;
+ asect->filepos = crashinfo_offset;
+ asect->size = sizeof (crashinfo);
+
+ /* Create a ".reg" section to allow access to the saved
+ registers. */
+
+ asect = bfd_make_section_anyway_with_flags (abfd, ".reg", flags);
+ if (asect == NULL)
+ goto error_return;
+ asect->vma = 0;
+ asect->filepos = bfd_get_32 (abfd, crashinfo.registers) - rambase;
+ /* Since we don't know the exact size of the saved register info,
+ choose a register section size that is either the remaining part
+ of the file, or 1024, whichever is smaller. */
+ nread = statbuf.st_size - asect->filepos;
+ asect->size = (nread < 1024) ? nread : 1024;
+
+ return abfd->xvec;
+
+ /* Get here if we have already started filling out the BFD
+ and there is an error of some kind. */
+
+ error_return:
+ bfd_release (abfd, abfd->tdata.any);
+ abfd->tdata.any = NULL;
+ bfd_section_list_clear (abfd);
+ return NULL;
+}
+
+static const bfd_target *
+cisco_core_file_p (bfd *abfd)
+{
+ int *crash_info_locp;
+ const bfd_target *target = NULL;
+
+ for (crash_info_locp = crash_info_locs;
+ *crash_info_locp != -1 && target == NULL;
+ crash_info_locp++)
+ {
+ target = cisco_core_file_validate (abfd, *crash_info_locp);
+ }
+ return (target);
+}
+
+static char *
+cisco_core_file_failing_command (bfd *abfd ATTRIBUTE_UNUSED)
+{
+ return NULL;
+}
+
+static int
+cisco_core_file_failing_signal (bfd *abfd ATTRIBUTE_UNUSED)
+{
+ return abfd->tdata.cisco_core_data->sig;
+}
+
+extern const bfd_target core_cisco_le_vec;
+
+const bfd_target core_cisco_be_vec =
+{
+ "cisco-ios-core-big",
+ 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 */
+ 0, /* match priority. */
+ 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),
+
+ & core_cisco_le_vec,
+
+ NULL /* backend_data */
+};
+
+const bfd_target core_cisco_le_vec =
+{
+ "cisco-ios-core-little",
+ 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 */
+ 0, /* match_priority */
+ 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_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),
+
+ &core_cisco_be_vec,
+
+ NULL /* backend_data */
+};
diff --git a/bfd/coff-alpha.c b/bfd/coff-alpha.c
new file mode 100644
index 0000000..0e78088
--- /dev/null
+++ b/bfd/coff-alpha.c
@@ -0,0 +1,2392 @@
+/* BFD back-end for ALPHA Extended-Coff files.
+ Copyright (C) 1993-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.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. */
+
+
+
+/* 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 H_GET_64
+#define PUT_FILEHDR_SYMPTR H_PUT_64
+#define GET_AOUTHDR_TSIZE H_GET_64
+#define PUT_AOUTHDR_TSIZE H_PUT_64
+#define GET_AOUTHDR_DSIZE H_GET_64
+#define PUT_AOUTHDR_DSIZE H_PUT_64
+#define GET_AOUTHDR_BSIZE H_GET_64
+#define PUT_AOUTHDR_BSIZE H_PUT_64
+#define GET_AOUTHDR_ENTRY H_GET_64
+#define PUT_AOUTHDR_ENTRY H_PUT_64
+#define GET_AOUTHDR_TEXT_START H_GET_64
+#define PUT_AOUTHDR_TEXT_START H_PUT_64
+#define GET_AOUTHDR_DATA_START H_GET_64
+#define PUT_AOUTHDR_DATA_START H_PUT_64
+#define GET_SCNHDR_PADDR H_GET_64
+#define PUT_SCNHDR_PADDR H_PUT_64
+#define GET_SCNHDR_VADDR H_GET_64
+#define PUT_SCNHDR_VADDR H_PUT_64
+#define GET_SCNHDR_SIZE H_GET_64
+#define PUT_SCNHDR_SIZE H_PUT_64
+#define GET_SCNHDR_SCNPTR H_GET_64
+#define PUT_SCNHDR_SCNPTR H_PUT_64
+#define GET_SCNHDR_RELPTR H_GET_64
+#define PUT_SCNHDR_RELPTR H_PUT_64
+#define GET_SCNHDR_LNNOPTR H_GET_64
+#define PUT_SCNHDR_LNNOPTR 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 (bfd *abfd ATTRIBUTE_UNUSED,
+ arelent *reloc ATTRIBUTE_UNUSED,
+ asymbol *sym ATTRIBUTE_UNUSED,
+ void * data ATTRIBUTE_UNUSED,
+ asection *sec ATTRIBUTE_UNUSED,
+ bfd *output_bfd ATTRIBUTE_UNUSED,
+ char **error_message ATTRIBUTE_UNUSED)
+{
+ 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 (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 == sec->size
+ || size + 8 == sec->size);
+ if (! bfd_set_section_size (abfd, sec, size))
+ return NULL;
+ }
+ }
+
+ return ret;
+}
+
+/* See whether the magic number matches. */
+
+static bfd_boolean
+alpha_ecoff_bad_format_hook (bfd *abfd ATTRIBUTE_UNUSED,
+ void * filehdr)
+{
+ struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr;
+
+ if (! ALPHA_ECOFF_BADMAG (*internal_f))
+ return TRUE;
+
+ if (ALPHA_ECOFF_COMPRESSEDMAG (*internal_f))
+ (*_bfd_error_handler)
+ (_("%B: Cannot handle compressed Alpha binaries.\n"
+ " Use compiler flags, or objZ, to generate uncompressed binaries."),
+ abfd);
+
+ return FALSE;
+}
+
+/* This is a hook called by coff_real_object_p to create any backend
+ specific information. */
+
+static void *
+alpha_ecoff_mkobject_hook (bfd *abfd, void * filehdr, void * aouthdr)
+{
+ void * 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 (bfd *abfd,
+ void * ext_ptr,
+ struct internal_reloc *intern)
+{
+ const RELOC *ext = (RELOC *) ext_ptr;
+
+ intern->r_vaddr = H_GET_64 (abfd, ext->r_vaddr);
+ intern->r_symndx = H_GET_32 (abfd, 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 (bfd *abfd,
+ const struct internal_reloc *intern,
+ void * 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;
+ }
+
+ /* XXX FIXME: The maximum symndx value used to be 14 but this
+ fails with object files produced by DEC's C++ compiler.
+ Where does the value 14 (or 15) come from anyway ? */
+ BFD_ASSERT (intern->r_extern
+ || (intern->r_symndx >= 0 && intern->r_symndx <= 15));
+
+ H_PUT_64 (abfd, intern->r_vaddr, ext->r_vaddr);
+ H_PUT_32 (abfd, symndx, 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 (bfd *abfd,
+ const struct internal_reloc *intern,
+ arelent *rptr)
+{
+ if (intern->r_type > ALPHA_R_GPVALUE)
+ {
+ (*_bfd_error_handler)
+ (_("%B: unknown/unsupported relocation type %d"),
+ abfd, intern->r_type);
+ bfd_set_error (bfd_error_bad_value);
+ rptr->addend = 0;
+ rptr->howto = NULL;
+ return;
+ }
+
+ 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);
+ 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 (bfd *abfd ATTRIBUTE_UNUSED,
+ 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 (bfd *abfd,
+ struct bfd_link_info *link_info,
+ struct bfd_link_order *link_order,
+ bfd_byte *data,
+ bfd_boolean relocatable,
+ 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 = relocatable ? abfd : (bfd *) NULL;
+ bfd_vma gp;
+ bfd_size_type sz;
+ bfd_boolean gp_undefined;
+ bfd_vma stack[RELOC_STACKSIZE];
+ int tos = 0;
+
+ if (reloc_size < 0)
+ goto error_return;
+ reloc_vector = (arelent **) bfd_malloc ((bfd_size_type) reloc_size);
+ if (reloc_vector == NULL && reloc_size != 0)
+ goto error_return;
+
+ sz = input_section->rawsize ? input_section->rawsize : input_section->size;
+ if (! bfd_get_section_contents (input_bfd, input_section, data, 0, sz))
+ goto error_return;
+
+ 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 (relocatable)
+ {
+ 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 (relocatable
+ && ((*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 (relocatable)
+ {
+ 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 (relocatable)
+ {
+ 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 (relocatable)
+ {
+ 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 (relocatable)
+ {
+ 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 (relocatable)
+ {
+ 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, TRUE)))
+ 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, NULL,
+ 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 (bfd *abfd ATTRIBUTE_UNUSED,
+ 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;
+ default:
+ return (reloc_howto_type *) NULL;
+ }
+
+ return &alpha_howto_table[alpha_type];
+}
+
+static reloc_howto_type *
+alpha_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ const char *r_name)
+{
+ unsigned int i;
+
+ for (i = 0;
+ i < sizeof (alpha_howto_table) / sizeof (alpha_howto_table[0]);
+ i++)
+ if (alpha_howto_table[i].name != NULL
+ && strcasecmp (alpha_howto_table[i].name, r_name) == 0)
+ return &alpha_howto_table[i];
+
+ return NULL;
+}
+
+/* A helper routine for alpha_relocate_section which converts an
+ external reloc when generating relocatable output. Returns the
+ relocation amount. */
+
+static bfd_vma
+alpha_convert_external_reloc (bfd *output_bfd ATTRIBUTE_UNUSED,
+ 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->relocatable);
+
+ 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 = (unsigned long) -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 == (unsigned long) -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 == (unsigned long) -1)
+ {
+ /* Caller must give an error. */
+ r_symndx = 0;
+ }
+ relocation = 0;
+ }
+
+ /* Write out the new r_symndx value. */
+ H_PUT_32 (input_bfd, r_symndx, 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 bfd_boolean
+alpha_relocate_section (bfd *output_bfd,
+ struct bfd_link_info *info,
+ bfd *input_bfd,
+ asection *input_section,
+ bfd_byte *contents,
+ void * external_relocs)
+{
+ asection **symndx_to_section, *lita_sec;
+ struct ecoff_link_hash_entry **sym_hashes;
+ bfd_vma gp;
+ bfd_boolean gp_undefined;
+ bfd_vma stack[RELOC_STACKSIZE];
+ int tos = 0;
+ struct external_reloc *ext_rel;
+ struct external_reloc *ext_rel_end;
+ bfd_size_type amt;
+
+ /* 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)
+ {
+ amt = NUM_RELOC_SECTIONS * sizeof (asection *);
+ symndx_to_section = (asection **) bfd_alloc (input_bfd, amt);
+ 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->relocatable && 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)
+ {
+ amt = sizeof (struct ecoff_section_tdata);
+ lita_sec_data = ((struct ecoff_section_tdata *)
+ bfd_zalloc (input_bfd, amt));
+ lita_sec->used_by_bfd = 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->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;
+ bfd_boolean relocatep;
+ bfd_boolean adjust_addrp;
+ bfd_boolean gp_usedp;
+ bfd_vma addend;
+
+ r_vaddr = H_GET_64 (input_bfd, ext_rel->r_vaddr);
+ r_symndx = H_GET_32 (input_bfd, 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)
+ {
+ case ALPHA_R_GPRELHIGH:
+ (*_bfd_error_handler)
+ (_("%B: unsupported relocation: ALPHA_R_GPRELHIGH"),
+ input_bfd);
+ bfd_set_error (bfd_error_bad_value);
+ continue;
+
+ case ALPHA_R_GPRELLOW:
+ (*_bfd_error_handler)
+ (_("%B: unsupported relocation: ALPHA_R_GPRELLOW"),
+ input_bfd);
+ bfd_set_error (bfd_error_bad_value);
+ continue;
+
+ default:
+ (*_bfd_error_handler)
+ (_("%B: unknown relocation type %d"),
+ input_bfd, (int) r_type);
+ bfd_set_error (bfd_error_bad_value);
+ continue;
+
+ 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->relocatable)
+ H_PUT_64 (input_bfd, input_section->output_offset + r_vaddr,
+ 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->relocatable)
+ {
+ 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, TRUE)))
+ 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->relocatable)
+ {
+ /* Adjust r_vaddr by the addend. */
+ H_PUT_64 (input_bfd, addend, 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 relocatable output, all we do is
+ adjust the address of the reloc. */
+ if (! info->relocatable)
+ {
+ 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->relocatable)
+ {
+ /* We are generating relocatable 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, TRUE)))
+ 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, NULL, name,
+ alpha_howto_table[r_type].name,
+ (bfd_vma) 0, input_bfd, input_section,
+ r_vaddr - input_section->vma)))
+ return FALSE;
+ }
+ break;
+ }
+ }
+ }
+
+ if (info->relocatable && adjust_addrp)
+ {
+ /* Change the address of the relocation. */
+ H_PUT_64 (input_bfd,
+ (input_section->output_section->vma
+ + input_section->output_offset
+ - input_section->vma
+ + r_vaddr),
+ ext_rel->r_vaddr);
+ }
+
+ if (gp_usedp && gp_undefined)
+ {
+ if (! ((*info->callbacks->reloc_dangerous)
+ (info, _("GP relative relocation used 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. */
+
+static bfd_boolean
+alpha_adjust_headers (bfd *abfd,
+ struct internal_filehdr *fhdr,
+ struct internal_aouthdr *ahdr ATTRIBUTE_UNUSED)
+{
+ 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_write_ar_hdr _bfd_generic_write_ar_hdr
+#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 void *
+alpha_ecoff_read_ar_hdr (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, (file_ptr) FILHSZ, SEEK_CUR) != 0
+ || bfd_bread (ab, (bfd_size_type) 8, abfd) != 8
+ || bfd_seek (abfd, (file_ptr) (- (FILHSZ + 8)), SEEK_CUR) != 0)
+ return NULL;
+
+ ret->parsed_size = H_GET_64 (abfd, ab);
+ }
+
+ return 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 (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;
+
+ buf = NULL;
+ 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_bread 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, (file_ptr) FILHSZ, SEEK_SET) != 0)
+ goto error_return;
+
+ /* The next eight bytes are the real file size. */
+ if (bfd_bread (ab, (bfd_size_type) 8, nbfd) != 8)
+ goto error_return;
+ size = H_GET_64 (nbfd, ab);
+
+ if (size != 0)
+ {
+ bfd_size_type left;
+ bfd_byte dict[4096];
+ unsigned int h;
+ bfd_byte b;
+
+ buf = (bfd_byte *) bfd_malloc (size);
+ if (buf == NULL)
+ goto error_return;
+ p = buf;
+
+ left = size;
+
+ /* I don't know what the next eight bytes are for. */
+ if (bfd_bread (ab, (bfd_size_type) 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_bread (&b, (bfd_size_type) 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_bread (&n, (bfd_size_type) 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_malloc ((bfd_size_type) 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 = bim;
+ nbfd->iovec = &_bfd_memory_iovec;
+ nbfd->origin = 0;
+ BFD_ASSERT (! nbfd->cacheable);
+
+ return nbfd;
+
+ error_return:
+ if (buf != NULL)
+ free (buf);
+ if (nbfd != NULL)
+ bfd_close (nbfd);
+ return NULL;
+}
+
+/* Open the next archived file. */
+
+static bfd *
+alpha_ecoff_openr_next_archived_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->proxy_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 (bfd *abfd, symindex sym_index)
+{
+ carsym *entry;
+
+ entry = bfd_ardata (abfd)->symdefs + sym_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 (*) (bfd *,void *,int,int,int,int,void *)) bfd_void, /* aux_in */
+ (void (*) (bfd *,void *,void *)) bfd_void, /* sym_in */
+ (void (*) (bfd *,void *,void *)) bfd_void, /* lineno_in */
+ (unsigned (*) (bfd *,void *,int,int,int,int,void *)) bfd_void,/*aux_out*/
+ (unsigned (*) (bfd *,void *,void *)) bfd_void, /* sym_out */
+ (unsigned (*) (bfd *,void *,void *)) bfd_void, /* lineno_out */
+ (unsigned (*) (bfd *,void *,void *)) 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, FILNMLEN, TRUE,
+ ECOFF_NO_LONG_SECTION_NAMES, 4, FALSE, 2, 32768,
+ 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, 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
+#define _bfd_ecoff_bfd_reloc_name_lookup \
+ alpha_bfd_reloc_name_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
+
+/* Input section flag lookup is generic. */
+#define _bfd_ecoff_bfd_lookup_section_flags bfd_generic_lookup_section_flags
+
+/* Relaxing sections is generic. */
+#define _bfd_ecoff_bfd_relax_section bfd_generic_relax_section
+#define _bfd_ecoff_bfd_gc_sections bfd_generic_gc_sections
+#define _bfd_ecoff_bfd_merge_sections bfd_generic_merge_sections
+#define _bfd_ecoff_bfd_is_group_section bfd_generic_is_group_section
+#define _bfd_ecoff_bfd_discard_group bfd_generic_discard_group
+#define _bfd_ecoff_section_already_linked \
+ _bfd_coff_section_already_linked
+#define _bfd_ecoff_bfd_define_common_symbol bfd_generic_define_common_symbol
+
+const bfd_target alpha_ecoff_le_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 */
+ 0, /* match priority. */
+ 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_generic_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),
+
+ NULL,
+
+ & alpha_ecoff_backend_data
+};
diff --git a/bfd/coff-apollo.c b/bfd/coff-apollo.c
new file mode 100644
index 0000000..2c75598
--- /dev/null
+++ b/bfd/coff-apollo.c
@@ -0,0 +1,120 @@
+/* BFD back-end for Apollo 68000 COFF binaries.
+ Copyright (C) 1990-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.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. */
+
+extern void apollo_rtype2howto (arelent *, int);
+extern int apollo_howto2rtype (reloc_howto_type *);
+#ifndef ONLY_DECLARE_RELOCS
+
+void
+apollo_rtype2howto (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 (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);
+
+#define bfd_pe_print_pdata NULL
+
+#include "coffcode.h"
+
+#ifndef TARGET_SYM
+#define TARGET_SYM m68k_coff_apollo_vec
+#endif
+
+#ifndef TARGET_NAME
+#define TARGET_NAME "apollo-m68k"
+#endif
+
+#ifdef NAMES_HAVE_UNDERSCORE
+CREATE_BIG_COFF_TARGET_VEC (TARGET_SYM, TARGET_NAME, 0, 0, '_', NULL, COFF_SWAP_TABLE)
+#else
+CREATE_BIG_COFF_TARGET_VEC (TARGET_SYM, TARGET_NAME, 0, 0, 0, NULL, COFF_SWAP_TABLE)
+#endif
diff --git a/bfd/coff-arm.c b/bfd/coff-arm.c
new file mode 100644
index 0000000..d47b77e
--- /dev/null
+++ b/bfd/coff-arm.c
@@ -0,0 +1,2560 @@
+/* BFD back-end for ARM COFF files.
+ Copyright (C) 1990-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.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) \
+ do \
+ { \
+ coff_data (abfd)->flags &= ~(F_APCS_26 | F_APCS_FLOAT | F_PIC); \
+ coff_data (abfd)->flags |= (flgs) | F_APCS_SET; \
+ } \
+ while (0)
+
+#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) \
+ do \
+ { \
+ coff_data (abfd)->flags &= ~F_INTERWORK; \
+ coff_data (abfd)->flags |= (flg) | F_INTERWORK_SET; \
+ } \
+ while (0)
+
+#ifndef NUM_ELEM
+#define NUM_ELEM(a) ((sizeof (a)) / sizeof ((a)[0]))
+#endif
+
+typedef enum {bunknown, b9, b12, b23} thumb_pcrel_branchtype;
+/* Some typedefs for holding instructions. */
+typedef unsigned long int insn32;
+typedef unsigned short int insn16;
+
+/* 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 (bfd *abfd,
+ arelent *reloc_entry,
+ asymbol *symbol ATTRIBUTE_UNUSED,
+ void * data,
+ asection *input_section ATTRIBUTE_UNUSED,
+ bfd *output_bfd,
+ char **error_message ATTRIBUTE_UNUSED)
+{
+ symvalue diff;
+
+ if (output_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, (bfd_vma) x, addr);
+ }
+ break;
+
+ case 2:
+ {
+ long x = bfd_get_32 (abfd, addr);
+ DOIT (x);
+ bfd_put_32 (abfd, (bfd_vma) 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. */
+
+#ifdef ARM_WINCE
+
+#define ARM_26D 0
+#define ARM_32 1
+#define ARM_RVA32 2
+#define ARM_26 3
+#define ARM_THUMB12 4
+#define ARM_SECTION 14
+#define ARM_SECREL 15
+
+#else
+
+#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
+
+#endif
+
+static bfd_reloc_status_type aoutarm_fix_pcrel_26_done
+ (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
+static bfd_reloc_status_type aoutarm_fix_pcrel_26
+ (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
+static bfd_reloc_status_type coff_thumb_pcrel_12
+ (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
+#ifndef ARM_WINCE
+static bfd_reloc_status_type coff_thumb_pcrel_9
+ (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
+static bfd_reloc_status_type coff_thumb_pcrel_23
+ (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
+#endif
+
+static reloc_howto_type aoutarm_std_reloc_howto[] =
+ {
+#ifdef ARM_WINCE
+ HOWTO (ARM_26D,
+ 2,
+ 2,
+ 24,
+ TRUE,
+ 0,
+ complain_overflow_dont,
+ aoutarm_fix_pcrel_26_done,
+ "ARM_26D",
+ TRUE, /* partial_inplace. */
+ 0x00ffffff,
+ 0x0,
+ PCRELOFFSET),
+ HOWTO (ARM_32,
+ 0,
+ 2,
+ 32,
+ FALSE,
+ 0,
+ complain_overflow_bitfield,
+ coff_arm_reloc,
+ "ARM_32",
+ TRUE, /* partial_inplace. */
+ 0xffffffff,
+ 0xffffffff,
+ PCRELOFFSET),
+ HOWTO (ARM_RVA32,
+ 0,
+ 2,
+ 32,
+ FALSE,
+ 0,
+ complain_overflow_bitfield,
+ coff_arm_reloc,
+ "ARM_RVA32",
+ TRUE, /* partial_inplace. */
+ 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_THUMB12,
+ 1,
+ 1,
+ 11,
+ TRUE,
+ 0,
+ complain_overflow_signed,
+ coff_thumb_pcrel_12 ,
+ "ARM_THUMB12",
+ FALSE,
+ 0x000007ff,
+ 0x000007ff,
+ PCRELOFFSET),
+ EMPTY_HOWTO (-1),
+ EMPTY_HOWTO (-1),
+ EMPTY_HOWTO (-1),
+ EMPTY_HOWTO (-1),
+ EMPTY_HOWTO (-1),
+ EMPTY_HOWTO (-1),
+ EMPTY_HOWTO (-1),
+ EMPTY_HOWTO (-1),
+ EMPTY_HOWTO (-1),
+ HOWTO (ARM_SECTION,
+ 0,
+ 1,
+ 16,
+ FALSE,
+ 0,
+ complain_overflow_bitfield,
+ coff_arm_reloc,
+ "ARM_SECTION",
+ TRUE, /* partial_inplace. */
+ 0x0000ffff,
+ 0x0000ffff,
+ PCRELOFFSET),
+ HOWTO (ARM_SECREL,
+ 0,
+ 2,
+ 32,
+ FALSE,
+ 0,
+ complain_overflow_bitfield,
+ coff_arm_reloc,
+ "ARM_SECREL",
+ TRUE, /* partial_inplace. */
+ 0xffffffff,
+ 0xffffffff,
+ PCRELOFFSET),
+#else /* not ARM_WINCE */
+ HOWTO (ARM_8,
+ 0,
+ 0,
+ 8,
+ FALSE,
+ 0,
+ complain_overflow_bitfield,
+ coff_arm_reloc,
+ "ARM_8",
+ TRUE,
+ 0x000000ff,
+ 0x000000ff,
+ PCRELOFFSET),
+ 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 */
+ EMPTY_HOWTO (-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)
+#endif /* not ARM_WINCE */
+ };
+
+#define NUM_RELOCS NUM_ELEM (aoutarm_std_reloc_howto)
+
+#ifdef COFF_WITH_PE
+/* Return TRUE if this relocation should
+ appear in the output .reloc section. */
+
+static bfd_boolean
+in_reloc_p (bfd * abfd ATTRIBUTE_UNUSED,
+ reloc_howto_type * howto)
+{
+ return !howto->pc_relative && howto->type != ARM_RVA32;
+}
+#endif
+
+#define RTYPE2HOWTO(cache_ptr, dst) \
+ (cache_ptr)->howto = \
+ (dst)->r_type < NUM_RELOCS \
+ ? aoutarm_std_reloc_howto + (dst)->r_type \
+ : NULL
+
+#define coff_rtype_to_howto coff_arm_rtype_to_howto
+
+static reloc_howto_type *
+coff_arm_rtype_to_howto (bfd *abfd ATTRIBUTE_UNUSED,
+ asection *sec,
+ struct internal_reloc *rel,
+ struct coff_link_hash_entry *h ATTRIBUTE_UNUSED,
+ struct internal_syment *sym ATTRIBUTE_UNUSED,
+ bfd_vma *addendp)
+{
+ reloc_howto_type * howto;
+
+ if (rel->r_type >= NUM_RELOCS)
+ return NULL;
+
+ howto = aoutarm_std_reloc_howto + rel->r_type;
+
+ if (rel->r_type == ARM_RVA32)
+ *addendp -= pe_data (sec->output_section->owner)->pe_opthdr.ImageBase;
+
+#if defined COFF_WITH_PE && defined ARM_WINCE
+ if (rel->r_type == ARM_SECREL)
+ {
+ bfd_vma osect_vma;
+
+ if (h && (h->type == bfd_link_hash_defined
+ || h->type == bfd_link_hash_defweak))
+ osect_vma = h->root.u.def.section->output_section->vma;
+ else
+ {
+ int i;
+
+ /* Sigh, the only way to get the section to offset against
+ is to find it the hard way. */
+
+ for (sec = abfd->sections, i = 1; i < sym->n_scnum; i++)
+ sec = sec->next;
+
+ osect_vma = sec->output_section->vma;
+ }
+
+ *addendp -= osect_vma;
+ }
+#endif
+
+ return howto;
+}
+
+/* Used by the assembler. */
+
+static bfd_reloc_status_type
+aoutarm_fix_pcrel_26_done (bfd *abfd ATTRIBUTE_UNUSED,
+ arelent *reloc_entry ATTRIBUTE_UNUSED,
+ asymbol *symbol ATTRIBUTE_UNUSED,
+ void * data ATTRIBUTE_UNUSED,
+ asection *input_section ATTRIBUTE_UNUSED,
+ bfd *output_bfd ATTRIBUTE_UNUSED,
+ char **error_message ATTRIBUTE_UNUSED)
+{
+ /* This is dead simple at present. */
+ return bfd_reloc_ok;
+}
+
+/* Used by the assembler. */
+
+static bfd_reloc_status_type
+aoutarm_fix_pcrel_26 (bfd *abfd,
+ arelent *reloc_entry,
+ asymbol *symbol,
+ void * data,
+ asection *input_section,
+ bfd *output_bfd,
+ char **error_message ATTRIBUTE_UNUSED)
+{
+ 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 (bfd_is_und_section (symbol->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 & ~(bfd_vma) 0x03ffffff)
+ flag = bfd_reloc_overflow;
+
+ target &= ~0x00ffffff;
+ target |= (relocation >> 2) & 0x00ffffff;
+ bfd_put_32 (abfd, (bfd_vma) 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 (bfd *abfd,
+ arelent *reloc_entry,
+ asymbol *symbol,
+ void * data,
+ asection *input_section,
+ bfd *output_bfd,
+ char **error_message ATTRIBUTE_UNUSED,
+ 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 (bfd_is_und_section (symbol->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, (bfd_vma) 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;
+}
+
+#ifndef ARM_WINCE
+static bfd_reloc_status_type
+coff_thumb_pcrel_23 (bfd *abfd,
+ arelent *reloc_entry,
+ asymbol *symbol,
+ void * 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_9 (bfd *abfd,
+ arelent *reloc_entry,
+ asymbol *symbol,
+ void * 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);
+}
+#endif /* not ARM_WINCE */
+
+static bfd_reloc_status_type
+coff_thumb_pcrel_12 (bfd *abfd,
+ arelent *reloc_entry,
+ asymbol *symbol,
+ void * 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 const struct reloc_howto_struct *
+coff_arm_reloc_type_lookup (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_arch_bits_per_address (abfd))
+ {
+ case 32:
+ code = BFD_RELOC_32;
+ break;
+ default:
+ return NULL;
+ }
+
+ switch (code)
+ {
+#ifdef ARM_WINCE
+ ASTD (BFD_RELOC_32, ARM_32);
+ ASTD (BFD_RELOC_RVA, ARM_RVA32);
+ ASTD (BFD_RELOC_ARM_PCREL_BRANCH, ARM_26);
+ ASTD (BFD_RELOC_THUMB_PCREL_BRANCH12, ARM_THUMB12);
+ ASTD (BFD_RELOC_32_SECREL, ARM_SECREL);
+#else
+ 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_ARM_PCREL_BLX, 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);
+ ASTD (BFD_RELOC_THUMB_PCREL_BLX, ARM_THUMB23);
+#endif
+ default: return NULL;
+ }
+}
+
+static reloc_howto_type *
+coff_arm_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ const char *r_name)
+{
+ unsigned int i;
+
+ for (i = 0;
+ i < (sizeof (aoutarm_std_reloc_howto)
+ / sizeof (aoutarm_std_reloc_howto[0]));
+ i++)
+ if (aoutarm_std_reloc_howto[i].name != NULL
+ && strcasecmp (aoutarm_std_reloc_howto[i].name, r_name) == 0)
+ return &aoutarm_std_reloc_howto[i];
+
+ return NULL;
+}
+
+#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. */
+
+#ifndef ARM_WINCE
+/* Make sure that the 'r_offset' field is copied properly
+ so that identical binaries will compare the same. */
+#define SWAP_IN_RELOC_OFFSET H_GET_32
+#define SWAP_OUT_RELOC_OFFSET H_PUT_32
+#endif
+
+/* 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 containing the Thumb-to-ARM glue. */
+ bfd_size_type thumb_glue_size;
+
+ /* The size in bytes of the section containing the ARM-to-Thumb glue. */
+ bfd_size_type arm_glue_size;
+
+ /* An arbitrary 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 (bfd * abfd)
+{
+ struct coff_arm_link_hash_table * ret;
+ bfd_size_type amt = sizeof (struct coff_arm_link_hash_table);
+
+ ret = bfd_zmalloc (amt);
+ if (ret == NULL)
+ return NULL;
+
+ if (!_bfd_coff_link_hash_table_init (&ret->root,
+ abfd,
+ _bfd_coff_link_hash_newfunc,
+ sizeof (struct coff_link_hash_entry)))
+ {
+ free (ret);
+ return NULL;
+ }
+
+ return & ret->root.root;
+}
+
+static bfd_boolean
+arm_emit_base_file_entry (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;
+ if (fwrite (&addr, sizeof (addr), 1, (FILE *) info->base_file) == 1)
+ return TRUE;
+
+ bfd_set_error (bfd_error_system_call);
+ return FALSE;
+}
+
+#ifndef ARM_WINCE
+/* 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 (identified 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 (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
+ /* FIXME: the BFD library should never abort except for internal errors
+ - it should return an error status. */
+ abort (); /* Error - not a valid branch instruction form. */
+
+ return br_insn;
+}
+
+
+static struct coff_link_hash_entry *
+find_thumb_glue (struct bfd_link_info *info,
+ const char *name,
+ bfd *input_bfd)
+{
+ char *tmp_name;
+ struct coff_link_hash_entry *myh;
+ bfd_size_type amt = strlen (name) + strlen (THUMB2ARM_GLUE_ENTRY_NAME) + 1;
+
+ tmp_name = bfd_malloc (amt);
+
+ 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 (_("%B: unable to find THUMB glue '%s' for `%s'"),
+ input_bfd, tmp_name, name);
+
+ free (tmp_name);
+
+ return myh;
+}
+#endif /* not ARM_WINCE */
+
+static struct coff_link_hash_entry *
+find_arm_glue (struct bfd_link_info *info,
+ const char *name,
+ bfd *input_bfd)
+{
+ char *tmp_name;
+ struct coff_link_hash_entry * myh;
+ bfd_size_type amt = strlen (name) + strlen (ARM2THUMB_GLUE_ENTRY_NAME) + 1;
+
+ tmp_name = bfd_malloc (amt);
+
+ 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 (_("%B: unable to find ARM glue '%s' for `%s'"),
+ 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 (globals->support_old_code ? 20 : 8)
+#ifndef ARM_WINCE
+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;
+#endif
+
+/* 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 bfd_boolean
+coff_arm_relocate_section (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;
+#ifndef ARM_WINCE
+ bfd_vma high_address = bfd_get_section_limit (input_bfd, input_section);
+#endif
+
+ 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 relocatable link. However, we want to convert
+ ARM_26 to ARM_26D relocs if possible. We return a fake howto in
+ this case without pcrel_offset set, and adjust the addend to
+ compensate. 'partial_inplace' is also set, since we want 'done'
+ relocations to be reflected in section's data. */
+ if (rel->r_type == ARM_26
+ && h != NULL
+ && info->relocatable
+ && (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",
+ TRUE,
+ 0x00ffffff,
+ 0x00ffffff,
+ FALSE);
+
+ addend -= rel->r_vaddr - input_section->vma;
+#ifdef ARM_WINCE
+ /* FIXME: I don't know why, but the hack is necessary for correct
+ generation of bl's instruction offset. */
+ addend -= 8;
+#endif
+ howto = & fake_arm26_reloc;
+ }
+
+#ifdef ARM_WINCE
+ /* MS ARM-CE makes the reloc relative to the opcode's pc, not
+ the next opcode's pc, so is off by one. */
+ if (howto->pc_relative && !info->relocatable)
+ addend -= 8;
+#endif
+
+ /* If we are doing a relocatable 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 relocatable link,
+ then we should ignore the symbol value. */
+ if (howto->pc_relative && howto->pcrel_offset)
+ {
+ if (info->relocatable)
+ continue;
+ /* FIXME - it is not clear which targets need this next test
+ and which do not. It is known that it is needed for the
+ VxWorks and EPOC-PE targets, but it is also known that it
+ was suppressed for other ARM targets. This ought to be
+ sorted out one day. */
+#ifdef ARM_COFF_BUGFIX
+ /* We must not ignore the symbol value. If the symbol is
+ within the same section, the relocation should have already
+ been fixed, but if it is not, we'll be handed a reloc into
+ the beginning of the symbol's section, so we must not cancel
+ out the symbol's value, otherwise we'll be adding it in
+ twice. */
+ if (sym != NULL && sym->n_scnum != 0)
+ addend += sym->n_value;
+#endif
+ }
+
+ 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
+ {
+ /* 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->relocatable
+ && ( 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->symbol_class == C_THUMBSTATFUNC
+ || h->symbol_class == C_THUMBEXTFUNC)
+ {
+ /* Arm code calling a Thumb function. */
+ unsigned long int tmp;
+ bfd_vma 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 */
+ (_("%B(%s): warning: interworking not enabled.\n"
+ " first occurrence: %B: arm call to thumb"),
+ h_sec->owner, input_bfd, name);
+
+ --my_offset;
+ myh->root.u.def.value = my_offset;
+
+ bfd_put_32 (output_bfd, (bfd_vma) a2t1_ldr_insn,
+ s->contents + my_offset);
+
+ bfd_put_32 (output_bfd, (bfd_vma) 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, my_offset + 8))
+ return FALSE;
+ }
+
+ 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, (bfd_vma) tmp,
+ contents + rel->r_vaddr - input_section->vma);
+ done = 1;
+ }
+ }
+
+#ifndef ARM_WINCE
+ /* Note: We used to check for ARM_THUMB9 and ARM_THUMB12. */
+ else if (howto->type == ARM_THUMB23)
+ {
+ if ( h->symbol_class == C_EXT
+ || h->symbol_class == C_STAT
+ || h->symbol_class == C_LABEL)
+ {
+ /* Thumb code calling an ARM function. */
+ asection * s = 0;
+ bfd_vma 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 */
+ (_("%B(%s): warning: interworking not enabled.\n"
+ " first occurrence: %B: thumb call to arm\n"
+ " consider relinking with --support-old-code enabled"),
+ h_sec->owner, input_bfd, name);
+
+ -- my_offset;
+ myh->root.u.def.value = my_offset;
+
+ if (globals->support_old_code)
+ {
+ bfd_put_16 (output_bfd, (bfd_vma) t2a1_push_insn,
+ s->contents + my_offset);
+
+ bfd_put_16 (output_bfd, (bfd_vma) t2a2_ldr_insn,
+ s->contents + my_offset + 2);
+
+ bfd_put_16 (output_bfd, (bfd_vma) t2a3_mov_insn,
+ s->contents + my_offset + 4);
+
+ bfd_put_16 (output_bfd, (bfd_vma) t2a4_bx_insn,
+ s->contents + my_offset + 6);
+
+ bfd_put_32 (output_bfd, (bfd_vma) t2a5_pop_insn,
+ s->contents + my_offset + 8);
+
+ bfd_put_32 (output_bfd, (bfd_vma) 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);
+
+ if (info->base_file
+ && !arm_emit_base_file_entry (info,
+ output_bfd, s,
+ my_offset + 16))
+ return FALSE;
+ }
+ else
+ {
+ bfd_put_16 (output_bfd, (bfd_vma) t2a1_bx_pc_insn,
+ s->contents + my_offset);
+
+ bfd_put_16 (output_bfd, (bfd_vma) t2a2_noop_insn,
+ s->contents + my_offset + 2);
+
+ ret_offset =
+ /* Address of destination of the stub. */
+ ((bfd_signed_vma) h_val)
+ - ((bfd_signed_vma)
+ /* Offset from the start of the current section to the start of the stubs. */
+ (s->output_offset
+ /* Offset of the start of this stub from the start of the stubs. */
+ + my_offset
+ /* Address of the start of the current section. */
+ + s->output_section->vma)
+ /* The branch instruction is 4 bytes into the stub. */
+ + 4
+ /* ARM branches work from the pc of the instruction + 8. */
+ + 8);
+
+ bfd_put_32 (output_bfd,
+ (bfd_vma) 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
+ + rel->r_vaddr)
+ -4;
+
+ tmp = bfd_get_32 (input_bfd, contents + rel->r_vaddr
+ - input_section->vma);
+
+ bfd_put_32 (output_bfd,
+ (bfd_vma) insert_thumb_branch (tmp,
+ ret_offset),
+ contents + rel->r_vaddr - input_section->vma);
+
+ done = 1;
+ }
+ }
+#endif
+ }
+
+ /* 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
+ 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->relocatable)
+ {
+ if (! ((*info->callbacks->undefined_symbol)
+ (info, h->root.root.string, input_bfd, input_section,
+ rel->r_vaddr - input_section->vma, TRUE)))
+ return FALSE;
+ }
+ }
+
+ /* Emit a reloc if the backend thinks it needs it. */
+ if (info->base_file
+ && sym
+ && pe_data(output_bfd)->in_reloc_p(output_bfd, howto)
+ && !arm_emit_base_file_entry (info, output_bfd, input_section,
+ rel->r_vaddr))
+ return FALSE;
+
+ if (done)
+ rstat = bfd_reloc_ok;
+#ifndef ARM_WINCE
+ /* Only perform this fix during the final link, not a relocatable link. */
+ else if (! info->relocatable
+ && 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 > high_address)
+ rstat = bfd_reloc_outofrange;
+ else
+ {
+ bfd_vma relocation = val + addend;
+ int size = bfd_get_reloc_size (howto);
+ bfd_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;
+
+ /* howto->bitpos == 0 */
+ /* Add the value from the object file, shifted so that it is a
+ straight number. */
+ 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 the relocation into the correct bits.
+ For a BLX instruction, make sure that the relocation is rounded up
+ to a word boundary. This follows the semantics of the instruction
+ which specifies that bit 1 of the target address will come from bit
+ 1 of the base address. */
+ if (bfd_big_endian (input_bfd))
+ {
+ if ((x & 0x1800) == 0x0800 && (relocation & 0x02))
+ relocation += 2;
+ relocation = (((relocation & 0xffe) >> 1) | ((relocation << 4) & 0x07ff0000));
+ }
+ else
+ {
+ if ((x & 0x18000000) == 0x08000000 && (relocation & 0x02))
+ relocation += 2;
+ relocation = (((relocation & 0xffe) << 15) | ((relocation >> 12) & 0x7ff));
+ }
+
+ /* Add the 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;
+ }
+ }
+#endif
+ else
+ if (info->relocatable && ! howto->partial_inplace)
+ rstat = bfd_reloc_ok;
+ else
+ rstat = _bfd_final_link_relocate (howto, input_bfd, input_section,
+ contents,
+ rel->r_vaddr - input_section->vma,
+ val, addend);
+ /* Only perform this fix during the final link, not a relocatable link. */
+ if (! info->relocatable
+ && (rel->r_type == ARM_32 || rel->r_type == ARM_RVA32))
+ {
+ /* 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->symbol_class == C_THUMBSTATFUNC
+ || h->symbol_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);
+ }
+ }
+
+ switch (rstat)
+ {
+ default:
+ abort ();
+ case bfd_reloc_ok:
+ break;
+ case bfd_reloc_outofrange:
+ (*_bfd_error_handler)
+ (_("%B: bad reloc address 0x%lx in section `%A'"),
+ input_bfd, input_section, (unsigned long) rel->r_vaddr);
+ return FALSE;
+ case bfd_reloc_overflow:
+ {
+ const char *name;
+ char buf[SYMNMLEN + 1];
+
+ if (symndx == -1)
+ name = "*ABS*";
+ else if (h != NULL)
+ name = NULL;
+ else
+ {
+ name = _bfd_coff_internal_syment_name (input_bfd, sym, buf);
+ if (name == NULL)
+ return FALSE;
+ }
+
+ if (! ((*info->callbacks->reloc_overflow)
+ (info, (h ? &h->root : NULL), name, howto->name,
+ (bfd_vma) 0, input_bfd, input_section,
+ rel->r_vaddr - input_section->vma)))
+ return FALSE;
+ }
+ }
+ }
+
+ return TRUE;
+}
+
+#ifndef COFF_IMAGE_WITH_PE
+
+bfd_boolean
+bfd_arm_allocate_interworking_sections (struct bfd_link_info * info)
+{
+ asection * s;
+ bfd_byte * foo;
+ struct coff_arm_link_hash_table * globals;
+
+ 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_alloc (globals->bfd_of_glue_owner, globals->arm_glue_size);
+
+ s->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_alloc (globals->bfd_of_glue_owner, globals->thumb_glue_size);
+
+ s->size = globals->thumb_glue_size;
+ s->contents = foo;
+ }
+
+ return TRUE;
+}
+
+static void
+record_arm_to_thumb_glue (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 bfd_link_hash_entry * bh;
+ struct coff_arm_link_hash_table * globals;
+ bfd_vma val;
+ bfd_size_type amt;
+
+ 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);
+
+ amt = strlen (name) + strlen (ARM2THUMB_GLUE_ENTRY_NAME) + 1;
+ tmp_name = bfd_malloc (amt);
+
+ 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);
+ /* We've already seen this guy. */
+ return;
+ }
+
+ /* 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. */
+ bh = NULL;
+ val = globals->arm_glue_size + 1;
+ bfd_coff_link_add_one_symbol (info, globals->bfd_of_glue_owner, tmp_name,
+ BSF_GLOBAL, s, val, NULL, TRUE, FALSE, &bh);
+
+ free (tmp_name);
+
+ globals->arm_glue_size += ARM2THUMB_GLUE_SIZE;
+
+ return;
+}
+
+#ifndef ARM_WINCE
+static void
+record_thumb_to_arm_glue (struct bfd_link_info * info,
+ struct coff_link_hash_entry * h)
+{
+ const char * name = h->root.root.string;
+ asection * s;
+ char * tmp_name;
+ struct coff_link_hash_entry * myh;
+ struct bfd_link_hash_entry * bh;
+ struct coff_arm_link_hash_table * globals;
+ bfd_vma val;
+ bfd_size_type amt;
+
+ 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);
+
+ amt = strlen (name) + strlen (THUMB2ARM_GLUE_ENTRY_NAME) + 1;
+ tmp_name = bfd_malloc (amt);
+
+ 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);
+ /* We've already seen this guy. */
+ return;
+ }
+
+ bh = NULL;
+ val = globals->thumb_glue_size + 1;
+ bfd_coff_link_add_one_symbol (info, globals->bfd_of_glue_owner, tmp_name,
+ BSF_GLOBAL, s, val, NULL, TRUE, FALSE, &bh);
+
+ /* If we mark it 'thumb', the disassembler will do a better job. */
+ myh = (struct coff_link_hash_entry *) bh;
+ myh->symbol_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"
+
+ amt = strlen (name) + strlen (CHANGE_TO_ARM) + 1;
+ tmp_name = bfd_malloc (amt);
+
+ BFD_ASSERT (tmp_name);
+
+ sprintf (tmp_name, globals->support_old_code ? BACK_FROM_ARM : CHANGE_TO_ARM, name);
+
+ bh = NULL;
+ val = globals->thumb_glue_size + (globals->support_old_code ? 8 : 4);
+ bfd_coff_link_add_one_symbol (info, globals->bfd_of_glue_owner, tmp_name,
+ BSF_LOCAL, s, val, NULL, TRUE, FALSE, &bh);
+
+ free (tmp_name);
+
+ globals->thumb_glue_size += THUMB2ARM_GLUE_SIZE;
+
+ return;
+}
+#endif /* not ARM_WINCE */
+
+/* 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 */
+
+bfd_boolean
+bfd_arm_get_bfd_for_interworking (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->relocatable)
+ 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_CODE | SEC_READONLY);
+ sec = bfd_make_section_with_flags (abfd, ARM2THUMB_GLUE_SECTION_NAME,
+ flags);
+ if (sec == NULL
+ || ! 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_CODE | SEC_READONLY);
+ sec = bfd_make_section_with_flags (abfd, THUMB2ARM_GLUE_SECTION_NAME,
+ flags);
+
+ if (sec == NULL
+ || ! bfd_set_section_alignment (abfd, sec, 2))
+ return FALSE;
+ }
+
+ /* Save the bfd for later use. */
+ globals->bfd_of_glue_owner = abfd;
+
+ return TRUE;
+}
+
+bfd_boolean
+bfd_arm_process_before_allocation (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->relocatable)
+ 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;
+
+ /* If the index is outside of the range of our table, something has gone wrong. */
+ if (symndx >= obj_conv_table_size (abfd))
+ {
+ _bfd_error_handler (_("%B: illegal symbol index in reloc: %d"),
+ abfd, symndx);
+ 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->symbol_class == C_THUMBEXTFUNC)
+ record_arm_to_thumb_glue (info, h);
+ break;
+
+#ifndef ARM_WINCE
+ 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->symbol_class)
+ {
+ case C_EXT:
+ case C_STAT:
+ case C_LABEL:
+ record_thumb_to_arm_glue (info, h);
+ break;
+ default:
+ ;
+ }
+ break;
+#endif
+
+ default:
+ break;
+ }
+ }
+ }
+
+ return TRUE;
+}
+
+#endif /* ! defined (COFF_IMAGE_WITH_PE) */
+
+#define coff_bfd_reloc_type_lookup coff_arm_reloc_type_lookup
+#define coff_bfd_reloc_name_lookup coff_arm_reloc_name_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 relocatable link, we want to convert ARM_26 relocs
+ into ARM_26D relocs. */
+
+static bfd_boolean
+coff_arm_adjust_symndx (bfd *obfd ATTRIBUTE_UNUSED,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ bfd *ibfd,
+ asection *sec,
+ struct internal_reloc *irel,
+ bfd_boolean *adjustedp)
+{
+ if (irel->r_type == ARM_26)
+ {
+ 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 = ARM_26D;
+ }
+ *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 different APCS's. */
+
+static bfd_boolean
+coff_arm_merge_private_bfd_data (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;
+
+ /* Determine what should happen if the input ARM architecture
+ does not match the output ARM architecture. */
+ if (! bfd_arm_merge_machines (ibfd, obfd))
+ return FALSE;
+
+ /* 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 */
+ (_("error: %B is compiled for APCS-%d, whereas %B is compiled for APCS-%d"),
+ ibfd, obfd,
+ APCS_26_FLAG (ibfd) ? 26 : 32,
+ 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 = _("error: %B passes floats in float registers, whereas %B passes them in integer registers");
+ else
+ /* xgettext: c-format */
+ msg = _("error: %B passes floats in integer registers, whereas %B passes them in float registers");
+
+ _bfd_error_handler (msg, ibfd, 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 = _("error: %B is compiled as position independent code, whereas target %B is absolute position");
+ else
+ /* xgettext: c-format */
+ msg = _("error: %B is compiled as absolute position code, whereas target %B is position independent");
+ _bfd_error_handler (msg, ibfd, 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: %B supports interworking, whereas %B does not");
+ else
+ /* xgettext: c-format */
+ msg = _("Warning: %B does not support interworking, whereas %B does");
+
+ _bfd_error_handler (msg, ibfd, obfd);
+ }
+ }
+ else
+ {
+ SET_INTERWORK_FLAG (obfd, INTERWORK_FLAG (ibfd));
+ }
+ }
+
+ return TRUE;
+}
+
+/* Display the flags field. */
+
+static bfd_boolean
+coff_arm_print_private_bfd_data (bfd * abfd, void * 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 Procedure 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 bfd_boolean
+_bfd_coff_arm_set_private_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))
+ ))
+ 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 %B since it has already been specified as non-interworking"),
+ abfd);
+ else
+ /* xgettext: c-format */
+ _bfd_error_handler (_("Warning: Clearing the interworking flag of %B due to outside request"),
+ 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 bfd_boolean
+coff_arm_copy_private_bfd_data (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 flag of %B because non-interworking code in %B has been linked with it"),
+ dest, 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|semi|aout}.h. */
+#ifndef LOCAL_LABEL_PREFIX
+#define LOCAL_LABEL_PREFIX ""
+#endif
+#ifndef USER_LABEL_PREFIX
+#define USER_LABEL_PREFIX "_"
+#endif
+
+/* Like _bfd_coff_is_local_label_name, but
+ a) test against USER_LABEL_PREFIX, to avoid stripping labels known to be
+ non-local.
+ b) Allow other prefixes than ".", e.g. an empty prefix would cause all
+ labels of the form Lxxx to be stripped. */
+
+static bfd_boolean
+coff_arm_is_local_label_name (bfd * abfd ATTRIBUTE_UNUSED,
+ const char * name)
+{
+#ifdef USER_LABEL_PREFIX
+ if (USER_LABEL_PREFIX[0] != 0)
+ {
+ size_t len = strlen (USER_LABEL_PREFIX);
+
+ if (strncmp (name, USER_LABEL_PREFIX, len) == 0)
+ return FALSE;
+ }
+#endif
+
+#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)
+ {
+ size_t len = strlen (LOCAL_LABEL_PREFIX);
+
+ if (strncmp (name, LOCAL_LABEL_PREFIX, len) != 0)
+ return FALSE;
+
+ /* Perform the checks below for the rest of the name. */
+ name += len;
+ }
+#endif
+
+ return name[0] == 'L';
+}
+
+/* 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. */
+
+static bfd_boolean
+coff_arm_link_output_has_begun (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 bfd_boolean
+coff_arm_final_link_postscript (bfd * abfd ATTRIBUTE_UNUSED,
+ 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 bfd_arm_update_notes (abfd, ARM_NOTE_SECTION);
+}
+
+#ifndef bfd_pe_print_pdata
+#define bfd_pe_print_pdata NULL
+#endif
+
+#include "coffcode.h"
+
+#ifndef TARGET_LITTLE_SYM
+#define TARGET_LITTLE_SYM arm_coff_le_vec
+#endif
+#ifndef TARGET_LITTLE_NAME
+#define TARGET_LITTLE_NAME "coff-arm-little"
+#endif
+#ifndef TARGET_BIG_SYM
+#define TARGET_BIG_SYM arm_coff_be_vec
+#endif
+#ifndef TARGET_BIG_NAME
+#define TARGET_BIG_NAME "coff-arm-big"
+#endif
+
+#ifndef TARGET_UNDERSCORE
+#define TARGET_UNDERSCORE 0
+#endif
+
+#ifndef EXTRA_S_FLAGS
+#ifdef COFF_WITH_PE
+#define EXTRA_S_FLAGS (SEC_CODE | SEC_LINK_ONCE | SEC_LINK_DUPLICATES)
+#else
+#define EXTRA_S_FLAGS SEC_CODE
+#endif
+#endif
+
+/* Forward declaration for use initialising alternative_target field. */
+extern const bfd_target TARGET_BIG_SYM ;
+
+/* Target vectors. */
+CREATE_LITTLE_COFF_TARGET_VEC (TARGET_LITTLE_SYM, TARGET_LITTLE_NAME, D_PAGED, EXTRA_S_FLAGS, TARGET_UNDERSCORE, & TARGET_BIG_SYM, COFF_SWAP_TABLE)
+CREATE_BIG_COFF_TARGET_VEC (TARGET_BIG_SYM, TARGET_BIG_NAME, D_PAGED, EXTRA_S_FLAGS, TARGET_UNDERSCORE, & TARGET_LITTLE_SYM, COFF_SWAP_TABLE)
diff --git a/bfd/coff-aux.c b/bfd/coff-aux.c
new file mode 100644
index 0000000..d95b98b
--- /dev/null
+++ b/bfd/coff-aux.c
@@ -0,0 +1,145 @@
+/* BFD back-end for Apple M68K COFF A/UX 3.x files.
+ Copyright (C) 1996-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#define TARGET_SYM m68k_coff_aux_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 "sysdep.h"
+#include "bfd.h"
+
+#define coff_link_add_one_symbol coff_m68k_aux_link_add_one_symbol
+static bfd_boolean
+coff_m68k_aux_link_add_one_symbol
+ (struct bfd_link_info *, bfd *, const char *, flagword, asection *,
+ bfd_vma, const char *, bfd_boolean, bfd_boolean,
+ struct bfd_link_hash_entry **);
+
+#ifndef bfd_pe_print_pdata
+#define bfd_pe_print_pdata NULL
+#endif
+
+#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 bfd_boolean
+coff_m68k_aux_link_add_one_symbol (struct bfd_link_info *info,
+ bfd *abfd,
+ const char *name,
+ flagword flags,
+ asection *section,
+ bfd_vma value,
+ const char *string,
+ bfd_boolean copy,
+ bfd_boolean collect,
+ struct bfd_link_hash_entry **hashp)
+{
+ struct bfd_link_hash_entry *h, *inh, *t;
+
+ 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;
+ else
+ {
+ h = bfd_link_hash_lookup (info->hash, name, TRUE, copy, FALSE);
+ if (h == NULL)
+ {
+ if (hashp != NULL)
+ *hashp = NULL;
+ return FALSE;
+ }
+ }
+
+ if (hashp != (struct bfd_link_hash_entry **) NULL)
+ *hashp = h;
+ /* end duplication from linker.c */
+
+ t = h;
+ inh = NULL;
+ if (h->type == bfd_link_hash_indirect)
+ {
+ inh = h->u.i.link;
+ t = inh;
+ }
+
+ if (t->type == bfd_link_hash_defined)
+ {
+ asection *msec = t->u.def.section;
+ bfd_boolean special = FALSE;
+
+ if (bfd_is_abs_section (msec) && !bfd_is_abs_section (section))
+ {
+ t->u.def.section = section;
+ t->u.def.value = value;
+ special = TRUE;
+ }
+ else if (bfd_is_abs_section (section) && !bfd_is_abs_section (msec))
+ special = TRUE;
+
+ if (special)
+ {
+ if (info->notice_all
+ || (info->notice_hash != NULL
+ && bfd_hash_lookup (info->notice_hash, name,
+ FALSE, FALSE) != NULL))
+ {
+ if (!(*info->callbacks->notice) (info, h, inh,
+ abfd, section, value, flags))
+ return FALSE;
+ }
+
+ 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 0000000..4797265
--- /dev/null
+++ b/bfd/coff-go32.c
@@ -0,0 +1,45 @@
+/* BFD back-end for Intel 386 COFF files (DJGPP variant).
+ Copyright (C) 1990-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#define TARGET_SYM i386_coff_go32_vec
+#define TARGET_NAME "coff-go32"
+#define TARGET_UNDERSCORE '_'
+#define COFF_LONG_SECTION_NAMES
+#define COFF_SUPPORT_GNU_LINKONCE
+#define COFF_LONG_FILENAMES
+
+#define COFF_SECTION_ALIGNMENT_ENTRIES \
+{ COFF_SECTION_NAME_EXACT_MATCH (".data"), \
+ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 4 }, \
+{ COFF_SECTION_NAME_EXACT_MATCH (".text"), \
+ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 4 }, \
+{ COFF_SECTION_NAME_PARTIAL_MATCH (".gnu.linkonce.d"), \
+ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 4 }, \
+{ COFF_SECTION_NAME_PARTIAL_MATCH (".gnu.linkonce.t"), \
+ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 4 }, \
+{ COFF_SECTION_NAME_PARTIAL_MATCH (".gnu.linkonce.r"), \
+ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 4 }, \
+{ COFF_SECTION_NAME_PARTIAL_MATCH (".debug"), \
+ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 0 }, \
+{ COFF_SECTION_NAME_PARTIAL_MATCH (".gnu.linkonce.wi"), \
+ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 0 }
+
+#include "coff-i386.c"
diff --git a/bfd/coff-h8300.c b/bfd/coff-h8300.c
new file mode 100644
index 0000000..5ec48c9
--- /dev/null
+++ b/bfd/coff-h8300.c
@@ -0,0 +1,1417 @@
+/* BFD back-end for Renesas H8/300 COFF binaries.
+ Copyright (C) 1990-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+#include "bfdlink.h"
+#include "genlink.h"
+#include "coff/h8300.h"
+#include "coff/internal.h"
+#include "libcoff.h"
+#include "libiberty.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;
+ };
+
+
+/* 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 (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 (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. */
+ switch (bfd_get_mach (table->abfd))
+ {
+ case bfd_mach_h8300:
+ case bfd_mach_h8300hn:
+ case bfd_mach_h8300sn:
+ table->offset += 2;
+ break;
+ case bfd_mach_h8300h:
+ case bfd_mach_h8300s:
+ table->offset += 4;
+ break;
+ default:
+ return NULL;
+ }
+
+ /* Everything went OK. */
+ return (struct bfd_hash_entry *) ret;
+}
+
+/* Initialize the function vector hash table. */
+
+static bfd_boolean
+funcvec_hash_table_init (struct funcvec_hash_table *table,
+ bfd *abfd,
+ struct bfd_hash_entry *(*newfunc)
+ (struct bfd_hash_entry *,
+ struct bfd_hash_table *,
+ const char *),
+ unsigned int entsize)
+{
+ /* Initialize our local fields, then call the generic initialization
+ routine. */
+ table->offset = 0;
+ table->abfd = abfd;
+ return (bfd_hash_table_init (&table->root, newfunc, entsize));
+}
+
+/* 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 (bfd *abfd)
+{
+ struct h8300_coff_link_hash_table *ret;
+ bfd_size_type amt = sizeof (struct h8300_coff_link_hash_table);
+
+ ret = (struct h8300_coff_link_hash_table *) bfd_zmalloc (amt);
+ if (ret == NULL)
+ return NULL;
+ if (!_bfd_link_hash_table_init (&ret->root.root, abfd,
+ _bfd_generic_link_hash_newfunc,
+ sizeof (struct generic_link_hash_entry)))
+ {
+ free (ret);
+ return NULL;
+ }
+
+ 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 only
+ the addend until the final link. */
+
+static bfd_reloc_status_type
+special (bfd * abfd ATTRIBUTE_UNUSED,
+ arelent * reloc_entry ATTRIBUTE_UNUSED,
+ asymbol * symbol ATTRIBUTE_UNUSED,
+ void * data ATTRIBUTE_UNUSED,
+ asection * input_section ATTRIBUTE_UNUSED,
+ bfd * output_bfd,
+ char ** error_message ATTRIBUTE_UNUSED)
+{
+ if (output_bfd == (bfd *) NULL)
+ return bfd_reloc_continue;
+
+ /* Adjust the reloc address to that in the output section. */
+ reloc_entry->address += input_section->output_offset;
+ 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 16-bit pc-relative
+ branch is turned into an 8-bit 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) \
+ && H8300HNBADMAG(x) && H8300SNBADMAG(x))
+#define H8300 1 /* Customize coffcode.h */
+#define __A_MAGIC_SET__
+
+/* Code to swap in the reloc. */
+#define SWAP_IN_RELOC_OFFSET H_GET_32
+#define SWAP_OUT_RELOC_OFFSET 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 (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 (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 (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;
+}
+
+static bfd_boolean
+h8300_symbol_address_p (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 (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)
+ {
+ bfd_byte code;
+
+ if (!bfd_get_section_contents (abfd, input_section, & code,
+ reloc->address, 1))
+ break;
+ code = bfd_get_8 (abfd, & code);
+
+ /* 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.
+
+ Only perform this optimisation for jumps (code 0x5a) not
+ subroutine calls, as otherwise it could transform:
+
+ mov.w r0,r0
+ beq .L1
+ jsr @_bar
+ .L1: rts
+ _bar: rts
+ into:
+ mov.w r0,r0
+ bne _bar
+ rts
+ _bar: rts
+
+ which changes the call (jsr) into a branch (bne). */
+ if (code == 0x5a
+ && 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);
+ value = bfd_h8300_pad_address (abfd, value);
+
+ /* If the address is in the top 256 bytes of the address space
+ then we can relax this instruction. */
+ if (value >= 0xffffff00u)
+ {
+ /* 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 16-bit 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);
+ value = bfd_h8300_pad_address (abfd, value);
+
+ if (value >= 0xffffff00u)
+ {
+ /* 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 24-/32-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);
+ value = bfd_h8300_pad_address (abfd, value);
+
+ /* If the address is a sign-extended 16-bit value then we can
+ relax this instruction. */
+ if (value <= 0x7fff || value >= 0xffff8000u)
+ {
+ /* 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 (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;
+ unsigned char temp_code;
+
+ switch (reloc->howto->type)
+ {
+ /* Generic 8-bit 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 = (input_section->output_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, NULL,
+ 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 16-bit 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 = (input_section->output_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, NULL,
+ 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, (bfd_vma) gap, data + dst_address);
+ dst_address += 2;
+ src_address += 2;
+
+ /* All done. */
+ break;
+
+ /* Generic 8-bit 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);
+
+ bfd_put_8 (abfd, value & 0xff, data + dst_address);
+ dst_address += 1;
+ src_address += 1;
+
+ /* All done. */
+ break;
+
+ /* Various simple 16-bit 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-/32-bit 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-/32-bit 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;
+
+ /* This is a 24-/32-bit absolute address in one of the following
+ instructions:
+
+ "band", "bclr", "biand", "bild", "bior", "bist", "bixor",
+ "bld", "bnot", "bor", "bset", "bst", "btst", "bxor", "ldc.w",
+ "stc.w" and "mov.[bwl]"
+
+ We may relax this into an 16-bit absolute address if it's in
+ the right range. */
+ case R_MOVL2:
+ value = bfd_coff_reloc16_get_value (reloc, link_info, input_section);
+ value = bfd_h8300_pad_address (abfd, value);
+
+ /* Sanity check. */
+ if (value <= 0x7fff || value >= 0xffff8000u)
+ {
+ /* Insert the 16-bit value into the proper location. */
+ bfd_put_16 (abfd, value, data + dst_address);
+
+ /* Fix the opcode. For all the instructions that belong to
+ this relaxation, 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, NULL,
+ bfd_asymbol_name (*reloc->sym_ptr_ptr),
+ reloc->howto->name, reloc->addend, input_section->owner,
+ input_section, reloc->address)))
+ abort ();
+ }
+ break;
+
+ /* A 16-bit 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 = (input_section->output_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, NULL,
+ 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 8-bit value. */
+ bfd_put_8 (abfd, gap, data + dst_address);
+
+ dst_address += 1;
+ src_address += 3;
+
+ break;
+
+ /* A 16-bit 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 = (input_section->output_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, NULL,
+ 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 second byte of the original insn, which contains
+ the condition code. */
+ tmp = data[dst_address - 1];
+
+ /* Compute the fisrt byte of the relaxed instruction. The
+ original sequence 0x58 0xX0 is relaxed to 0x4X, where X
+ represents the condition code. */
+ tmp &= 0xf0;
+ tmp >>= 4;
+ tmp |= 0x40;
+
+ /* Write it. */
+ bfd_put_8 (abfd, tmp, data + dst_address - 2);
+ break;
+
+ case 0x5c:
+ /* bsr:16 -> bsr:8 */
+ bfd_put_8 (abfd, 0x55, 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 8-bit reloc is applied at
+ dst_address - 1, so the next insn should begin at dst_address. */
+ src_address += 2;
+
+ break;
+
+ /* Similarly for a 24-bit 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 = (input_section->output_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;
+
+ /* This is a 16-bit absolute address in one of the following
+ instructions:
+
+ "band", "bclr", "biand", "bild", "bior", "bist", "bixor",
+ "bld", "bnot", "bor", "bset", "bst", "btst", "bxor", and
+ "mov.b"
+
+ We may relax this into an 8-bit absolute address if it's in
+ the right range. */
+ case R_MOV16B2:
+ value = bfd_coff_reloc16_get_value (reloc, link_info, input_section);
+
+ /* All instructions with R_H8_DIR16B2 start with 0x6a. */
+ if (data[dst_address - 2] != 0x6a)
+ abort ();
+
+ temp_code = data[src_address - 1];
+
+ /* If this is a mov.b instruction, clear the lower nibble, which
+ contains the source/destination register number. */
+ if ((temp_code & 0x10) != 0x10)
+ temp_code &= 0xf0;
+
+ /* Fix up the opcode. */
+ switch (temp_code)
+ {
+ case 0x00:
+ /* This is mov.b @aa:16,Rd. */
+ data[dst_address - 2] = (data[src_address - 1] & 0xf) | 0x20;
+ break;
+ case 0x80:
+ /* This is mov.b Rs,@aa:16. */
+ data[dst_address - 2] = (data[src_address - 1] & 0xf) | 0x30;
+ break;
+ case 0x18:
+ /* This is a bit-maniputation instruction that stores one
+ bit into memory, one of "bclr", "bist", "bnot", "bset",
+ and "bst". */
+ data[dst_address - 2] = 0x7f;
+ break;
+ case 0x10:
+ /* This is a bit-maniputation instruction that loads one bit
+ from memory, one of "band", "biand", "bild", "bior",
+ "bixor", "bld", "bor", "btst", and "bxor". */
+ data[dst_address - 2] = 0x7e;
+ break;
+ default:
+ abort ();
+ }
+
+ bfd_put_8 (abfd, value & 0xff, data + dst_address - 1);
+ src_address += 2;
+ break;
+
+ /* This is a 24-bit absolute address in one of the following
+ instructions:
+
+ "band", "bclr", "biand", "bild", "bior", "bist", "bixor",
+ "bld", "bnot", "bor", "bset", "bst", "btst", "bxor", and
+ "mov.b"
+
+ We may relax this into an 8-bit absolute address if it's in
+ the right range. */
+ case R_MOV24B2:
+ value = bfd_coff_reloc16_get_value (reloc, link_info, input_section);
+
+ /* All instructions with R_MOV24B2 start with 0x6a. */
+ if (data[dst_address - 2] != 0x6a)
+ abort ();
+
+ temp_code = data[src_address - 1];
+
+ /* If this is a mov.b instruction, clear the lower nibble, which
+ contains the source/destination register number. */
+ if ((temp_code & 0x30) != 0x30)
+ temp_code &= 0xf0;
+
+ /* Fix up the opcode. */
+ switch (temp_code)
+ {
+ case 0x20:
+ /* This is mov.b @aa:24/32,Rd. */
+ data[dst_address - 2] = (data[src_address - 1] & 0xf) | 0x20;
+ break;
+ case 0xa0:
+ /* This is mov.b Rs,@aa:24/32. */
+ data[dst_address - 2] = (data[src_address - 1] & 0xf) | 0x30;
+ break;
+ case 0x38:
+ /* This is a bit-maniputation instruction that stores one
+ bit into memory, one of "bclr", "bist", "bnot", "bset",
+ and "bst". */
+ data[dst_address - 2] = 0x7f;
+ break;
+ case 0x30:
+ /* This is a bit-maniputation instruction that loads one bit
+ from memory, one of "band", "biand", "bild", "bior",
+ "bixor", "bld", "bor", "btst", and "bxor". */
+ data[dst_address - 2] = 0x7e;
+ 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 = (input_section->output_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, NULL,
+ 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 8-bit 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;
+ const char *name;
+ struct funcvec_hash_table *ftab;
+ struct funcvec_hash_entry *h;
+ struct h8300_coff_link_hash_table *htab;
+ asection *vectors_sec;
+
+ if (link_info->output_bfd->xvec != abfd->xvec)
+ {
+ (*_bfd_error_handler)
+ (_("cannot handle R_MEM_INDIRECT reloc when using %s output"),
+ link_info->output_bfd->xvec->name);
+
+ /* What else can we do? This function doesn't allow return
+ of an error, and we don't want to call abort as that
+ indicates an internal error. */
+#ifndef EXIT_FAILURE
+#define EXIT_FAILURE 1
+#endif
+ xexit (EXIT_FAILURE);
+ }
+ htab = h8300_coff_hash_table (link_info);
+ vectors_sec = htab->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 <= 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 <= 0xff)
+ {
+ bfd_put_8 (abfd, value, data + dst_address);
+ dst_address += 1;
+ src_address += 1;
+ }
+ else
+ {
+ if (! ((*link_info->callbacks->reloc_overflow)
+ (link_info, NULL,
+ 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 ((bfd_size_type) strlen (name) + 10);
+
+ if (new_name == NULL)
+ abort ();
+
+ sprintf (new_name, "%s_%08x", name, symbol->section->id);
+ name = new_name;
+ }
+
+ ftab = htab->funcvec_hash_table;
+ h = funcvec_hash_lookup (ftab, 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
+ thing 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. */
+ switch (bfd_get_mach (input_section->owner))
+ {
+ case bfd_mach_h8300:
+ case bfd_mach_h8300hn:
+ case bfd_mach_h8300sn:
+ bfd_put_16 (abfd,
+ bfd_coff_reloc16_get_value (reloc,
+ link_info,
+ input_section),
+ vectors_sec->contents + h->offset);
+ break;
+ case bfd_mach_h8300h:
+ case bfd_mach_h8300s:
+ bfd_put_32 (abfd,
+ bfd_coff_reloc16_get_value (reloc,
+ link_info,
+ input_section),
+ vectors_sec->contents + h->offset);
+ break;
+ default:
+ 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,
+ (file_ptr) vectors_sec->output_offset,
+ vectors_sec->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 bfd_boolean
+h8300_bfd_link_add_symbols (bfd *abfd, struct bfd_link_info *info)
+{
+ asection *sec;
+ struct funcvec_hash_table *funcvec_hash_table;
+ bfd_size_type amt;
+ struct h8300_coff_link_hash_table *htab;
+
+ /* Add the symbols using the generic code. */
+ _bfd_generic_link_add_symbols (abfd, info);
+
+ if (info->output_bfd->xvec != abfd->xvec)
+ return TRUE;
+
+ htab = h8300_coff_hash_table (info);
+
+ /* If we haven't created a vectors section, do so now. */
+ if (!htab->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);
+ htab->vectors_sec = bfd_make_section_with_flags (abfd, ".vectors",
+ flags);
+
+ /* If the section wasn't created, or we couldn't set the flags,
+ quit quickly now, rather than dying a painful death later. */
+ if (!htab->vectors_sec)
+ return FALSE;
+
+ /* Also create the vector hash table. */
+ amt = sizeof (struct funcvec_hash_table);
+ funcvec_hash_table = (struct funcvec_hash_table *) bfd_alloc (abfd, amt);
+
+ if (!funcvec_hash_table)
+ return FALSE;
+
+ /* And initialize the funcvec hash table. */
+ if (!funcvec_hash_table_init (funcvec_hash_table, abfd,
+ funcvec_hash_newfunc,
+ sizeof (struct funcvec_hash_entry)))
+ {
+ bfd_release (abfd, funcvec_hash_table);
+ return FALSE;
+ }
+
+ /* Store away a pointer to the funcvec hash table. */
+ htab->funcvec_hash_table = funcvec_hash_table;
+ }
+
+ /* Load up the function vector hash table. */
+ funcvec_hash_table = htab->funcvec_hash_table;
+
+ /* 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 ((bfd_size_type) 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_table *ftab;
+ struct funcvec_hash_entry *h;
+
+ name = symbol->name;
+ if (symbol->flags & BSF_LOCAL)
+ {
+ char *new_name;
+
+ new_name = bfd_malloc ((bfd_size_type) strlen (name) + 10);
+ if (new_name == NULL)
+ abort ();
+
+ sprintf (new_name, "%s_%08x", name, symbol->section->id);
+ name = new_name;
+ }
+
+ /* Look this symbol up in the function vector hash table. */
+ ftab = htab->funcvec_hash_table;
+ h = funcvec_hash_lookup (ftab, 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 (ftab, 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. */
+ switch (bfd_get_mach (abfd))
+ {
+ case bfd_mach_h8300:
+ case bfd_mach_h8300hn:
+ case bfd_mach_h8300sn:
+ htab->vectors_sec->size += 2;
+ break;
+ case bfd_mach_h8300h:
+ case bfd_mach_h8300s:
+ htab->vectors_sec->size += 4;
+ break;
+ default:
+ abort ();
+ }
+ }
+ }
+ }
+
+ /* 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. */
+ sec = htab->vectors_sec;
+ if (sec->size != 0)
+ {
+ /* Free the old contents. */
+ if (sec->contents)
+ free (sec->contents);
+
+ /* Allocate new contents. */
+ sec->contents = bfd_malloc (sec->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
+
+#ifndef bfd_pe_print_pdata
+#define bfd_pe_print_pdata NULL
+#endif
+
+#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
+
+CREATE_BIG_COFF_TARGET_VEC (h8300_coff_vec, "coff-h8300", BFD_IS_RELAXABLE, 0, '_', NULL, COFF_SWAP_TABLE)
diff --git a/bfd/coff-h8500.c b/bfd/coff-h8500.c
new file mode 100644
index 0000000..574f956
--- /dev/null
+++ b/bfd/coff-h8500.c
@@ -0,0 +1,304 @@
+/* BFD back-end for Renesas H8/500 COFF binaries.
+ Copyright (C) 1993-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.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 (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 H_GET_32
+#define SWAP_OUT_RELOC_OFFSET 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 (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 (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 (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, (bfd_vma) 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, (bfd_vma) 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 = (*dst_ptr
+ + input_section->output_offset
+ + 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 > 128 || gap < -128)
+ {
+ if (! ((*link_info->callbacks->reloc_overflow)
+ (link_info, NULL,
+ 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 = (*dst_ptr
+ + input_section->output_offset
+ + 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 > 32767 || gap < -32768)
+ {
+ if (! ((*link_info->callbacks->reloc_overflow)
+ (link_info, NULL,
+ 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, (bfd_vma) gap, data + *dst_ptr);
+ (*dst_ptr) += 2;
+ (*src_ptr) += 2;
+ break;
+ }
+
+ default:
+ abort ();
+ }
+}
+
+#define coff_reloc16_extra_cases extra_case
+
+#ifndef bfd_pe_print_pdata
+#define bfd_pe_print_pdata NULL
+#endif
+
+#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
+
+CREATE_BIG_COFF_TARGET_VEC (h8500_coff_vec, "coff-h8500", 0, 0, '_', NULL, COFF_SWAP_TABLE)
diff --git a/bfd/coff-i386.c b/bfd/coff-i386.c
new file mode 100644
index 0000000..848d69b
--- /dev/null
+++ b/bfd/coff-i386.c
@@ -0,0 +1,679 @@
+/* BFD back-end for Intel 386 COFF files.
+ Copyright (C) 1990-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.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
+
+#ifndef bfd_pe_print_pdata
+#define bfd_pe_print_pdata NULL
+#endif
+
+#include "libcoff.h"
+
+static reloc_howto_type *coff_i386_rtype_to_howto
+ (bfd *, asection *, struct internal_reloc *,
+ struct coff_link_hash_entry *, struct internal_syment *,
+ bfd_vma *);
+static reloc_howto_type *coff_i386_reloc_type_lookup
+ (bfd *, bfd_reloc_code_real_type);
+
+#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 relocatable 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 (bfd *abfd,
+ arelent *reloc_entry,
+ asymbol *symbol,
+ void * data,
+ asection *input_section ATTRIBUTE_UNUSED,
+ bfd *output_bfd,
+ char **error_message ATTRIBUTE_UNUSED)
+{
+ symvalue diff;
+
+#ifndef COFF_WITH_PE
+ if (output_bfd == (bfd *) NULL)
+ return bfd_reloc_continue;
+#endif
+
+ 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
+ relocatable output. This seems to be always wrong for 386
+ COFF, so we handle the addend here instead. */
+#ifdef COFF_WITH_PE
+ if (output_bfd == (bfd *) NULL)
+ {
+ reloc_howto_type *howto = reloc_entry->howto;
+
+ /* Although PC relative relocations are very similar between
+ PE and non-PE formats, but they are off by 1 << howto->size
+ bytes. For the external relocation, PE is very different
+ from others. See md_apply_fix3 () in gas/config/tc-i386.c.
+ When we link PE and non-PE object files together to
+ generate a non-PE executable, we have to compensate it
+ here. */
+ if (howto->pc_relative && howto->pcrel_offset)
+ diff = -(1 << howto->size);
+ else if (symbol->flags & BSF_WEAK)
+ diff = reloc_entry->addend - symbol->value;
+ else
+ diff = -reloc_entry->addend;
+ }
+ else
+#endif
+ diff = reloc_entry->addend;
+ }
+
+#ifdef COFF_WITH_PE
+ /* FIXME: How should this case be handled? */
+ if (reloc_entry->howto->type == R_IMAGEBASE
+ && output_bfd != NULL
+ && bfd_get_flavour(output_bfd) == bfd_target_coff_flavour)
+ diff -= pe_data (output_bfd)->pe_opthdr.ImageBase;
+#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, (bfd_vma) x, addr);
+ }
+ break;
+
+ case 2:
+ {
+ long x = bfd_get_32 (abfd, addr);
+ DOIT (x);
+ bfd_put_32 (abfd, (bfd_vma) 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 bfd_boolean in_reloc_p (bfd * abfd ATTRIBUTE_UNUSED,
+ reloc_howto_type *howto)
+{
+ return ! howto->pc_relative && howto->type != R_IMAGEBASE
+ && howto->type != R_SECREL32;
+}
+#endif /* COFF_WITH_PE */
+
+#ifndef PCRELOFFSET
+#define PCRELOFFSET FALSE
+#endif
+
+static reloc_howto_type howto_table[] =
+{
+ EMPTY_HOWTO (0),
+ EMPTY_HOWTO (1),
+ EMPTY_HOWTO (2),
+ EMPTY_HOWTO (3),
+ EMPTY_HOWTO (4),
+ EMPTY_HOWTO (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 */
+ /* PE IMAGE_REL_I386_DIR32NB relocation (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 */
+ EMPTY_HOWTO (010),
+ EMPTY_HOWTO (011),
+ EMPTY_HOWTO (012),
+#ifdef COFF_WITH_PE
+ /* 32-bit longword section relative relocation (013). */
+ HOWTO (R_SECREL32, /* 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 */
+ "secrel32", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+#else
+ EMPTY_HOWTO (013),
+#endif
+ EMPTY_HOWTO (014),
+ EMPTY_HOWTO (015),
+ EMPTY_HOWTO (016),
+ /* Byte relocation (017). */
+ 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 */
+ /* 16-bit word relocation (020). */
+ 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 */
+ /* 32-bit longword relocation (021). */
+ 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 */
+ /* Byte PC relative relocation (022). */
+ 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 */
+ /* 16-bit word PC relative relocation (023). */
+ 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 */
+ /* 32-bit longword PC relative relocation (024). */
+ 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 */
+};
+
+#define NUM_HOWTOS (sizeof (howto_table) / sizeof (howto_table[0]))
+
+/* 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 = \
+ ((dst)->r_type < NUM_HOWTOS \
+ ? howto_table + (dst)->r_type \
+ : NULL))
+
+/* 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 && reloc.r_type < NUM_HOWTOS \
+ && 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
+ relocatable link. */
+
+static bfd_boolean
+coff_pe_i386_relocate_section (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->relocatable)
+ 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 (bfd *abfd ATTRIBUTE_UNUSED,
+ 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_HOWTOS)
+ {
+ bfd_set_error (bfd_error_bad_value);
+ return NULL;
+ }
+
+ howto = howto_table + rel->r_type;
+
+#ifdef COFF_WITH_PE
+ /* Cancel out code in _bfd_coff_generic_relocate_section. */
+ *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
+ relocatable 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
+ && (bfd_get_flavour(sec->output_section->owner)
+ == bfd_target_coff_flavour))
+ {
+ *addendp -= pe_data(sec->output_section->owner)->pe_opthdr.ImageBase;
+ }
+
+ BFD_ASSERT (sym != NULL);
+ if (rel->r_type == R_SECREL32 && sym != NULL)
+ {
+ bfd_vma osect_vma;
+
+ if (h && (h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak))
+ osect_vma = h->root.u.def.section->output_section->vma;
+ else
+ {
+ asection *s;
+ int i;
+
+ /* Sigh, the only way to get the section to offset against
+ is to find it the hard way. */
+
+ for (s = abfd->sections, i = 1; i < sym->n_scnum; i++)
+ s = s->next;
+
+ osect_vma = s->output_section->vma;
+ }
+
+ *addendp -= osect_vma;
+ }
+#endif
+
+ return howto;
+}
+
+#define coff_bfd_reloc_type_lookup coff_i386_reloc_type_lookup
+#define coff_bfd_reloc_name_lookup coff_i386_reloc_name_lookup
+
+static reloc_howto_type *
+coff_i386_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ 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;
+ case BFD_RELOC_16:
+ return howto_table + R_RELWORD;
+ case BFD_RELOC_16_PCREL:
+ return howto_table + R_PCRWORD;
+ case BFD_RELOC_8:
+ return howto_table + R_RELBYTE;
+ case BFD_RELOC_8_PCREL:
+ return howto_table + R_PCRBYTE;
+#ifdef COFF_WITH_PE
+ case BFD_RELOC_32_SECREL:
+ return howto_table + R_SECREL32;
+#endif
+ default:
+ BFD_FAIL ();
+ return 0;
+ }
+}
+
+static reloc_howto_type *
+coff_i386_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ const char *r_name)
+{
+ unsigned int i;
+
+ for (i = 0; i < NUM_HOWTOS; i++)
+ if (howto_table[i].name != NULL
+ && strcasecmp (howto_table[i].name, r_name) == 0)
+ return &howto_table[i];
+
+ return NULL;
+}
+
+#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 bfd_boolean
+coff_i386_is_local_label_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"
+
+const bfd_target
+#ifdef TARGET_SYM
+ TARGET_SYM =
+#else
+ i386_coff_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 | BFD_COMPRESS | BFD_DECOMPRESS ),
+
+ (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC /* section flags */
+#ifdef COFF_WITH_PE
+ | SEC_LINK_ONCE | SEC_LINK_DUPLICATES | SEC_READONLY | SEC_DEBUGGING
+#endif
+ | SEC_CODE | SEC_DATA | SEC_EXCLUDE ),
+
+#ifdef TARGET_UNDERSCORE
+ TARGET_UNDERSCORE, /* leading underscore */
+#else
+ 0, /* leading underscore */
+#endif
+ '/', /* ar_pad_char */
+ 15, /* ar_max_namelen */
+ 0, /* match priority. */
+
+ 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_check_format */
+#ifdef COFF_CHECK_FORMAT
+ {_bfd_dummy_target, COFF_CHECK_FORMAT,
+ bfd_generic_archive_p, COFF_CHECK_FORMAT},
+#else
+ {_bfd_dummy_target, coff_object_p, bfd_generic_archive_p, coff_object_p},
+#endif
+ {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),
+
+ NULL,
+
+ COFF_SWAP_TABLE
+};
diff --git a/bfd/coff-i860.c b/bfd/coff-i860.c
new file mode 100644
index 0000000..341183f
--- /dev/null
+++ b/bfd/coff-i860.c
@@ -0,0 +1,709 @@
+/* BFD back-end for Intel i860 COFF files.
+ Copyright (C) 1990-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+
+#include "coff/i860.h"
+
+#include "coff/internal.h"
+
+#ifndef bfd_pe_print_pdata
+#define bfd_pe_print_pdata NULL
+#endif
+
+#include "libcoff.h"
+
+
+#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 relocatable 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 (bfd *abfd,
+ arelent *reloc_entry,
+ asymbol *symbol,
+ void *data,
+ asection *input_section ATTRIBUTE_UNUSED,
+ bfd *output_bfd,
+ char **error_message ATTRIBUTE_UNUSED)
+{
+ 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
+ relocatable 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, (bfd_vma) x, addr);
+ }
+ break;
+
+ case 2:
+ {
+ long x = bfd_get_32 (abfd, addr);
+ DOIT (x);
+ bfd_put_32 (abfd, (bfd_vma) x, addr);
+ }
+ break;
+
+ default:
+ abort ();
+ }
+ }
+
+ /* Now let bfd_perform_relocation finish everything up. */
+ return bfd_reloc_continue;
+}
+
+/* This is just a temporary measure until we teach bfd to generate
+ these relocations. */
+
+static bfd_reloc_status_type
+coff_i860_reloc_nyi (bfd *abfd ATTRIBUTE_UNUSED,
+ arelent *reloc_entry,
+ asymbol *symbol ATTRIBUTE_UNUSED,
+ void *data ATTRIBUTE_UNUSED,
+ asection *input_section ATTRIBUTE_UNUSED,
+ bfd *output_bfd ATTRIBUTE_UNUSED,
+ char **error_message ATTRIBUTE_UNUSED)
+{
+ reloc_howto_type *howto = reloc_entry->howto;
+ (*_bfd_error_handler) (_("relocation `%s' not yet implemented"), howto->name);
+ return bfd_reloc_notsupported;
+}
+
+#ifndef PCRELOFFSET
+#define PCRELOFFSET FALSE
+#endif
+
+static reloc_howto_type howto_table[] =
+{
+ EMPTY_HOWTO (0),
+ EMPTY_HOWTO (1),
+ EMPTY_HOWTO (2),
+ EMPTY_HOWTO (3),
+ EMPTY_HOWTO (4),
+ EMPTY_HOWTO (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 */
+ EMPTY_HOWTO (010),
+ EMPTY_HOWTO (011),
+ EMPTY_HOWTO (012),
+ EMPTY_HOWTO (013),
+ EMPTY_HOWTO (014),
+ EMPTY_HOWTO (015),
+ EMPTY_HOWTO (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 */
+ EMPTY_HOWTO (0x15),
+ EMPTY_HOWTO (0x16),
+ EMPTY_HOWTO (0x17),
+ EMPTY_HOWTO (0x18),
+ EMPTY_HOWTO (0x19),
+ EMPTY_HOWTO (0x1a),
+ EMPTY_HOWTO (0x1b),
+ HOWTO (COFF860_R_PAIR, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ coff_i860_reloc_nyi, /* special_function */
+ "PAIR", /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ EMPTY_HOWTO (0x1d),
+ HOWTO (COFF860_R_HIGH, /* type */
+ 16, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ coff_i860_reloc, /* special_function */
+ "HIGH", /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ HOWTO (COFF860_R_LOW0, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ coff_i860_reloc, /* special_function */
+ "LOW0", /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ HOWTO (COFF860_R_LOW1, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ coff_i860_reloc, /* special_function */
+ "LOW1", /* name */
+ FALSE, /* partial_inplace */
+ 0xfffe, /* src_mask */
+ 0xfffe, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ HOWTO (COFF860_R_LOW2, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ coff_i860_reloc, /* special_function */
+ "LOW2", /* name */
+ FALSE, /* partial_inplace */
+ 0xfffc, /* src_mask */
+ 0xfffc, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ HOWTO (COFF860_R_LOW3, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ coff_i860_reloc, /* special_function */
+ "LOW3", /* name */
+ FALSE, /* partial_inplace */
+ 0xfff8, /* src_mask */
+ 0xfff8, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ HOWTO (COFF860_R_LOW4, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ coff_i860_reloc, /* special_function */
+ "LOW4", /* name */
+ FALSE, /* partial_inplace */
+ 0xfff0, /* src_mask */
+ 0xfff0, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ HOWTO (COFF860_R_SPLIT0, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ coff_i860_reloc_nyi, /* special_function */
+ "SPLIT0", /* name */
+ FALSE, /* partial_inplace */
+ 0x1f07ff, /* src_mask */
+ 0x1f07ff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ HOWTO (COFF860_R_SPLIT1, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ coff_i860_reloc_nyi, /* special_function */
+ "SPLIT1", /* name */
+ FALSE, /* partial_inplace */
+ 0x1f07fe, /* src_mask */
+ 0x1f07fe, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ HOWTO (COFF860_R_SPLIT2, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ coff_i860_reloc_nyi, /* special_function */
+ "SPLIT2", /* name */
+ FALSE, /* partial_inplace */
+ 0x1f07fc, /* src_mask */
+ 0x1f07fc, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ HOWTO (COFF860_R_HIGHADJ, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ coff_i860_reloc_nyi, /* special_function */
+ "HIGHADJ", /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ HOWTO (COFF860_R_BRADDR, /* type */
+ 2, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 26, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ coff_i860_reloc_nyi, /* special_function */
+ "BRADDR", /* name */
+ FALSE, /* partial_inplace */
+ 0x3ffffff, /* src_mask */
+ 0x3ffffff, /* dst_mask */
+ TRUE) /* pcrel_offset */
+};
+
+/* Turn a howto into a reloc number. */
+
+#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 = \
+ ((dst)->r_type < sizeof (howto_table) / sizeof (howto_table[0]) \
+ ? howto_table + (dst)->r_type \
+ : NULL))
+
+/* 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)
+
+/* 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 (bfd *abfd ATTRIBUTE_UNUSED,
+ 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 > sizeof (howto_table) / sizeof (howto_table[0]))
+ {
+ bfd_set_error (bfd_error_bad_value);
+ return NULL;
+ }
+
+ 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 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;
+ }
+
+ /* If the output symbol is common (in which case this must be a
+ relocatable 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;
+}
+
+static reloc_howto_type *
+coff_i860_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ bfd_reloc_code_real_type code)
+{
+ switch (code)
+ {
+ case BFD_RELOC_32:
+ return howto_table + R_DIR32;
+ case BFD_RELOC_860_PC26:
+ return howto_table + COFF860_R_BRADDR;
+ case BFD_RELOC_860_PC16:
+ /* ??? How to handle PC16 for COFF? SPLIT0 is close for now. */
+ return howto_table + COFF860_R_SPLIT0;
+ case BFD_RELOC_860_LOW0:
+ return howto_table + COFF860_R_LOW0;
+ case BFD_RELOC_860_SPLIT0:
+ return howto_table + COFF860_R_SPLIT0;
+ case BFD_RELOC_860_LOW1:
+ return howto_table + COFF860_R_LOW1;
+ case BFD_RELOC_860_SPLIT1:
+ return howto_table + COFF860_R_SPLIT1;
+ case BFD_RELOC_860_LOW2:
+ return howto_table + COFF860_R_LOW2;
+ case BFD_RELOC_860_SPLIT2:
+ return howto_table + COFF860_R_SPLIT2;
+ case BFD_RELOC_860_LOW3:
+ return howto_table + COFF860_R_LOW3;
+ case BFD_RELOC_860_HIGHADJ:
+ return howto_table + COFF860_R_HIGHADJ;
+ case BFD_RELOC_860_HIGH:
+ return howto_table + COFF860_R_HIGH;
+ default:
+ BFD_FAIL ();
+ return 0;
+ }
+}
+
+static reloc_howto_type *
+coff_i860_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ const char *r_name)
+{
+ unsigned int i;
+
+ for (i = 0; i < sizeof (howto_table) / sizeof (howto_table[0]); i++)
+ if (howto_table[i].name != NULL
+ && strcasecmp (howto_table[i].name, r_name) == 0)
+ return &howto_table[i];
+
+ return NULL;
+}
+
+/* This is called from coff_slurp_reloc_table for each relocation
+ entry. This special handling is due to the `PAIR' relocation
+ which has a different meaning for the `r_symndx' field. */
+
+static void
+i860_reloc_processing (arelent *cache_ptr, struct internal_reloc *dst,
+ asymbol **symbols, bfd *abfd, asection *asect)
+{
+ if (dst->r_type == COFF860_R_PAIR)
+ {
+ /* Handle the PAIR relocation specially. */
+ cache_ptr->howto = howto_table + dst->r_type;
+ cache_ptr->address = dst->r_vaddr;
+ cache_ptr->addend = dst->r_symndx;
+ cache_ptr->sym_ptr_ptr= bfd_abs_section_ptr->symbol_ptr_ptr;
+ }
+ else
+ {
+ /* For every other relocation, do exactly what coff_slurp_reloc_table
+ would do (which this code is taken directly from). */
+ asymbol *ptr = NULL;
+ 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)
+ (_("%B: warning: illegal symbol index %ld in relocs"),
+ 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);
+ (void) ptr;
+
+ cache_ptr->address -= asect->vma;
+
+ /* Fill in the cache_ptr->howto field from dst->r_type. */
+ RTYPE2HOWTO (cache_ptr, dst);
+ }
+}
+
+#define coff_rtype_to_howto coff_i860_rtype_to_howto
+#define coff_bfd_reloc_type_lookup coff_i860_reloc_type_lookup
+#define coff_bfd_reloc_name_lookup coff_i860_reloc_name_lookup
+
+#define RELOC_PROCESSING(relent, reloc, symbols, abfd, section) \
+ i860_reloc_processing (relent, reloc, symbols, abfd, section)
+
+#include "coffcode.h"
+
+static const bfd_target *
+i3coff_object_p(bfd *a)
+{
+ return coff_object_p (a);
+}
+
+const bfd_target
+#ifdef TARGET_SYM
+ TARGET_SYM =
+#else
+ i860_coff_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 */
+ 0, /* match priority. */
+
+ 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),
+
+ NULL,
+
+ COFF_SWAP_TABLE
+};
diff --git a/bfd/coff-i960.c b/bfd/coff-i960.c
new file mode 100644
index 0000000..1448257
--- /dev/null
+++ b/bfd/coff-i960.c
@@ -0,0 +1,659 @@
+/* BFD back-end for Intel 960 COFF files.
+ Copyright (C) 1990-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#define I960 1
+#define BADMAG(x) I960BADMAG(x)
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+#include "coff/i960.h"
+#include "coff/internal.h"
+
+#ifndef bfd_pe_print_pdata
+#define bfd_pe_print_pdata NULL
+#endif
+
+#include "libcoff.h" /* To allow easier abstraction-breaking. */
+
+
+#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (3)
+#define COFF_ALIGN_IN_SECTION_HEADER 1
+
+#define GET_SCNHDR_ALIGN H_GET_32
+#define PUT_SCNHDR_ALIGN 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 bfd_boolean
+coff_i960_is_local_label_name (bfd *abfd ATTRIBUTE_UNUSED, 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 (bfd *abfd,
+ arelent *reloc_entry,
+ asymbol *symbol_in,
+ void * data,
+ asection *input_section,
+ bfd *ignore_bfd ATTRIBUTE_UNUSED,
+ 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, (bfd_vma) 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 relocatable 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
+ relocatable 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 (bfd *abfd,
+ arelent *reloc_entry,
+ asymbol *symbol,
+ void * data ATTRIBUTE_UNUSED,
+ asection *input_section ATTRIBUTE_UNUSED,
+ bfd *output_bfd,
+ char **error_message ATTRIBUTE_UNUSED)
+{
+ asection *osec;
+
+ if (output_bfd == NULL)
+ {
+ /* Not generating relocatable 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)
+ {
+ bfd_size_type amt = sizeof (struct coff_section_tdata);
+ osec->used_by_bfd = bfd_zalloc (abfd, amt);
+ if (osec->used_by_bfd == NULL)
+ return bfd_reloc_overflow;
+ }
+ coff_section_data (output_bfd, osec)->tdata = 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 (bfd *abfd ATTRIBUTE_UNUSED,
+ 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;
+ }
+}
+
+static reloc_howto_type *
+coff_i960_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ const char *r_name)
+{
+ if (strcasecmp (howto_optcall.name, r_name) == 0)
+ return &howto_optcall;
+ if (strcasecmp (howto_rellong.name, r_name) == 0)
+ return &howto_rellong;
+ if (strcasecmp (howto_iprmed.name, r_name) == 0)
+ return &howto_iprmed;
+
+ return NULL;
+}
+
+/* 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 bfd_boolean
+coff_i960_start_final_link (bfd *abfd, struct bfd_link_info *info)
+{
+ bfd_size_type symesz = bfd_coff_symesz (abfd);
+ asection *o;
+ bfd_byte *esym;
+
+ if (! info->relocatable)
+ 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, &isym, esym);
+
+ if (bfd_bwrite (esym, symesz, 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 bfd_boolean
+coff_i960_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
+ 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;
+ bfd_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->relocatable)
+ {
+ if (! ((*info->callbacks->undefined_symbol)
+ (info, h->root.root.string, input_bfd, input_section,
+ rel->r_vaddr - input_section->vma, TRUE)))
+ return FALSE;
+ }
+ }
+
+ done = FALSE;
+
+ if (howto->type == R_OPTCALL && ! info->relocatable && symndx != -1)
+ {
+ int class_val;
+
+ if (h != NULL)
+ class_val = h->symbol_class;
+ else
+ class_val = sym->n_sclass;
+
+ switch (class_val)
+ {
+ 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, esyms, sym->n_type,
+ sym->n_sclass, 1, sym->n_numaux,
+ &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,
+ (bfd_vma) 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 = NULL;
+ else
+ {
+ name = _bfd_coff_internal_syment_name (input_bfd, sym, buf);
+ if (name == NULL)
+ return FALSE;
+ }
+
+ if (! ((*info->callbacks->reloc_overflow)
+ (info, (h ? &h->root : NULL), 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. */
+
+static bfd_boolean
+coff_i960_adjust_symndx (bfd *obfd ATTRIBUTE_UNUSED,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ bfd *ibfd,
+ asection *sec ATTRIBUTE_UNUSED,
+ struct internal_reloc *irel,
+ bfd_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
+#define coff_bfd_reloc_name_lookup coff_i960_reloc_name_lookup
+
+#include "coffcode.h"
+
+extern const bfd_target icoff_be_vec;
+
+CREATE_LITTLE_COFF_TARGET_VEC (icoff_le_vec, "coff-Intel-little", 0, 0, '_', & icoff_be_vec, COFF_SWAP_TABLE)
+
+const bfd_target icoff_be_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 */
+ 0, /* match priority. */
+
+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),
+
+ & icoff_le_vec,
+
+ COFF_SWAP_TABLE
+};
diff --git a/bfd/coff-ia64.c b/bfd/coff-ia64.c
new file mode 100644
index 0000000..38a0a38
--- /dev/null
+++ b/bfd/coff-ia64.c
@@ -0,0 +1,202 @@
+/* BFD back-end for HP/Intel IA-64 COFF files.
+ Copyright (C) 1999-2014 Free Software Foundation, Inc.
+ Contributed by David Mosberger <davidm@hpl.hp.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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+#include "coff/ia64.h"
+#include "coff/internal.h"
+#include "coff/pe.h"
+#include "libcoff.h"
+
+#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (2)
+
+/* Windows ia64 uses 8K page size. */
+#define COFF_PAGE_SIZE 0x2000
+
+static reloc_howto_type howto_table[] =
+{
+ EMPTY_HOWTO (0),
+};
+
+#define BADMAG(x) IA64BADMAG(x)
+#define IA64 1 /* Customize coffcode.h */
+
+#ifdef COFF_WITH_pep
+# undef AOUTSZ
+# define AOUTSZ PEPAOUTSZ
+# define PEAOUTHDR PEPAOUTHDR
+#endif
+
+#define RTYPE2HOWTO(cache_ptr, dst) \
+ (cache_ptr)->howto = howto_table + (dst)->r_type;
+
+#ifdef COFF_WITH_PE
+/* Return TRUE if this relocation should
+ appear in the output .reloc section. */
+
+static bfd_boolean
+in_reloc_p (bfd * abfd ATTRIBUTE_UNUSED,
+ reloc_howto_type *howto ATTRIBUTE_UNUSED)
+{
+ return FALSE; /* We don't do relocs for now... */
+}
+#endif
+
+#ifndef bfd_pe_print_pdata
+#define bfd_pe_print_pdata NULL
+#endif
+
+#include "coffcode.h"
+
+static const bfd_target *
+ia64coff_object_p (bfd *abfd)
+{
+#ifdef COFF_IMAGE_WITH_PE
+ {
+ struct external_PEI_DOS_hdr dos_hdr;
+ struct external_PEI_IMAGE_hdr image_hdr;
+ file_ptr offset;
+
+ if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0
+ || (bfd_bread (&dos_hdr, (bfd_size_type) sizeof (dos_hdr), abfd)
+ != sizeof (dos_hdr)))
+ {
+ if (bfd_get_error () != bfd_error_system_call)
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+
+ /* There are really two magic numbers involved; the magic number
+ that says this is a NT executable (PEI) and the magic number
+ that determines the architecture. The former is DOSMAGIC,
+ stored in the e_magic field. The latter is stored in the
+ f_magic field. If the NT magic number isn't valid, the
+ architecture magic number could be mimicked by some other
+ field (specifically, the number of relocs in section 3). Since
+ this routine can only be called correctly for a PEI file, check
+ the e_magic number here, and, if it doesn't match, clobber the
+ f_magic number so that we don't get a false match. */
+ if (H_GET_16 (abfd, dos_hdr.e_magic) != DOSMAGIC)
+ {
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+
+ offset = H_GET_32 (abfd, dos_hdr.e_lfanew);
+ if (bfd_seek (abfd, offset, SEEK_SET) != 0
+ || (bfd_bread (&image_hdr, (bfd_size_type) sizeof (image_hdr), abfd)
+ != sizeof (image_hdr)))
+ {
+ if (bfd_get_error () != bfd_error_system_call)
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+
+ if (H_GET_32 (abfd, image_hdr.nt_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 for PE, see "struct external_PEI_filehdr"
+ in include/coff/pe.h. We adjust so that that will work. */
+ if (bfd_seek (abfd, offset - sizeof (dos_hdr), 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
+ ia64coff_vec =
+#endif
+{
+#ifdef TARGET_NAME
+ TARGET_NAME,
+#else
+ "coff-ia64", /* 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 */
+ 0, /* match priority. */
+
+ 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, ia64coff_object_p, /* bfd_check_format */
+ bfd_generic_archive_p, ia64coff_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),
+
+ NULL,
+
+ COFF_SWAP_TABLE
+};
diff --git a/bfd/coff-m68k.c b/bfd/coff-m68k.c
new file mode 100644
index 0000000..f7089a6
--- /dev/null
+++ b/bfd/coff-m68k.c
@@ -0,0 +1,542 @@
+/* BFD back-end for Motorola 68000 COFF binaries.
+ Copyright (C) 1990-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.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 m68k_coff_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
+ (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
+
+#define RELOC_SPECIAL_FN m68kcoff_common_addend_special_fn
+#endif
+
+static bfd_boolean m68k_coff_is_local_label_name (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 bfd_boolean
+m68k_coff_is_local_label_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
+#define m68k_reloc_name_lookup _bfd_m68kcoff_reloc_name_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 (arelent *internal, int relocentry);
+extern int m68k_howto2rtype (reloc_howto_type *);
+extern reloc_howto_type * m68k_reloc_type_lookup
+ (bfd *, bfd_reloc_code_real_type);
+extern reloc_howto_type * m68k_reloc_name_lookup (bfd *, const char *);
+#else
+
+#ifdef STATIC_RELOCS
+#define STAT_REL static
+#else
+#define STAT_REL
+#endif
+
+STAT_REL void m68k_rtype2howto (arelent *, int);
+STAT_REL int m68k_howto2rtype (reloc_howto_type *);
+STAT_REL reloc_howto_type * m68k_reloc_type_lookup (bfd *, bfd_reloc_code_real_type);
+STAT_REL reloc_howto_type * m68k_reloc_name_lookup (bfd *, const char *);
+
+STAT_REL void
+m68k_rtype2howto (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;
+ }
+}
+
+STAT_REL int
+m68k_howto2rtype (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;
+}
+
+STAT_REL reloc_howto_type *
+m68k_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ 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*/
+}
+
+STAT_REL reloc_howto_type *
+m68k_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ const char *r_name)
+{
+ unsigned int i;
+
+ for (i = 0;
+ i < sizeof (m68kcoff_howto_table) / sizeof (m68kcoff_howto_table[0]);
+ i++)
+ if (m68kcoff_howto_table[i].name != NULL
+ && strcasecmp (m68kcoff_howto_table[i].name, r_name) == 0)
+ return &m68kcoff_howto_table[i];
+
+ return NULL;
+}
+
+#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
+#define coff_bfd_reloc_name_lookup m68k_reloc_name_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 (bfd *abfd ATTRIBUTE_UNUSED,
+ asection *sec,
+ struct internal_reloc *rel,
+ struct coff_link_hash_entry *h ATTRIBUTE_UNUSED,
+ struct internal_syment *sym ATTRIBUTE_UNUSED,
+ bfd_vma *addendp)
+{
+ arelent relent;
+ reloc_howto_type *howto;
+
+ relent.howto = NULL;
+ RTYPE2HOWTO (&relent, rel);
+
+ howto = relent.howto;
+
+ if (howto != NULL && 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 relocatable 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 (bfd *abfd,
+ arelent *reloc_entry,
+ asymbol *symbol,
+ void * data,
+ asection *input_section ATTRIBUTE_UNUSED,
+ bfd *output_bfd,
+ char **error_message ATTRIBUTE_UNUSED)
+{
+ 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
+ relocatable 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, (bfd_vma) x, addr);
+ }
+ break;
+
+ case 2:
+ {
+ long x = bfd_get_32 (abfd, addr);
+ DOIT (x);
+ bfd_put_32 (abfd, (bfd_vma) 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. */
+
+static reloc_howto_type *
+m68kcoff_common_addend_rtype_to_howto (bfd *abfd ATTRIBUTE_UNUSED,
+ 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;
+
+ relent.howto = NULL;
+ 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
+ relocatable 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 */
+
+#if !defined ONLY_DECLARE_RELOCS && ! defined STATIC_RELOCS
+/* Given a .data section and a .emreloc in-memory section, store
+ relocation information into the .emreloc 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. */
+
+bfd_boolean
+bfd_m68k_coff_create_embedded_relocs (bfd *abfd,
+ struct bfd_link_info *info,
+ asection *datasec,
+ asection *relsec,
+ char **errmsg)
+{
+ char *extsyms;
+ bfd_size_type symesz;
+ struct internal_reloc *irel, *irelend;
+ bfd_byte *p;
+ bfd_size_type amt;
+
+ BFD_ASSERT (! info->relocatable);
+
+ *errmsg = NULL;
+
+ if (datasec->reloc_count == 0)
+ return TRUE;
+
+ extsyms = obj_coff_external_syms (abfd);
+ symesz = bfd_coff_symesz (abfd);
+
+ irel = _bfd_coff_read_internal_relocs (abfd, datasec, TRUE, NULL, FALSE,
+ NULL);
+ irelend = irel + datasec->reloc_count;
+
+ amt = (bfd_size_type) datasec->reloc_count * 12;
+ relsec->contents = (bfd_byte *) bfd_alloc (abfd, amt);
+ if (relsec->contents == NULL)
+ return FALSE;
+
+ p = relsec->contents;
+
+ for (; irel < irelend; irel++, p += 12)
+ {
+ asection *targetsec;
+
+ /* We are going to write a four byte longword into the runtime
+ reloc section. The longword will be the address in the data
+ section which must be relocated. It is followed by the name
+ of the target section NUL-padded or truncated to 8
+ characters. */
+
+ /* We can only relocate absolute longword relocs at run time. */
+ if (irel->r_type != R_RELLONG)
+ {
+ *errmsg = _("unsupported reloc type");
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+
+ if (irel->r_symndx == -1)
+ targetsec = bfd_abs_section_ptr;
+ else
+ {
+ struct coff_link_hash_entry *h;
+
+ h = obj_coff_sym_hashes (abfd)[irel->r_symndx];
+ if (h == NULL)
+ {
+ struct internal_syment isym;
+
+ bfd_coff_swap_sym_in (abfd, extsyms + symesz * irel->r_symndx,
+ &isym);
+ targetsec = coff_section_from_bfd_index (abfd, isym.n_scnum);
+ }
+ else if (h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak)
+ targetsec = h->root.u.def.section;
+ else
+ targetsec = NULL;
+ }
+
+ bfd_put_32 (abfd,
+ (irel->r_vaddr - datasec->vma + datasec->output_offset), p);
+ memset (p + 4, 0, 8);
+ if (targetsec != NULL)
+ strncpy ((char *) p + 4, targetsec->output_section->name, 8);
+ }
+
+ return TRUE;
+}
+#endif /* neither ONLY_DECLARE_RELOCS not STATIC_RELOCS */
+
+#define coff_bfd_is_local_label_name m68k_coff_is_local_label_name
+
+#define coff_relocate_section _bfd_coff_generic_relocate_section
+
+#ifndef bfd_pe_print_pdata
+#define bfd_pe_print_pdata NULL
+#endif
+
+#include "coffcode.h"
+
+#ifndef TARGET_SYM
+#define TARGET_SYM m68k_coff_vec
+#endif
+
+#ifndef TARGET_NAME
+#define TARGET_NAME "coff-m68k"
+#endif
+
+#ifdef NAMES_HAVE_UNDERSCORE
+CREATE_BIG_COFF_TARGET_VEC (TARGET_SYM, TARGET_NAME, D_PAGED, 0, '_', NULL, COFF_SWAP_TABLE)
+#else
+CREATE_BIG_COFF_TARGET_VEC (TARGET_SYM, TARGET_NAME, D_PAGED, 0, 0, NULL, COFF_SWAP_TABLE)
+#endif
diff --git a/bfd/coff-m88k.c b/bfd/coff-m88k.c
new file mode 100644
index 0000000..7d474f9
--- /dev/null
+++ b/bfd/coff-m88k.c
@@ -0,0 +1,284 @@
+/* BFD back-end for Motorola 88000 COFF "Binary Compatibility Standard" files.
+ Copyright (C) 1990-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#define M88 1 /* Customize various include files */
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+#include "coff/m88k.h"
+#include "coff/internal.h"
+#include "libcoff.h"
+
+static bfd_reloc_status_type m88k_special_reloc
+ (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
+
+#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (3)
+
+#define GET_SCNHDR_NRELOC H_GET_32
+#define GET_SCNHDR_NLNNO H_GET_32
+
+/* On coff-m88k, local labels start with '@'. */
+
+#define coff_bfd_is_local_label_name m88k_is_local_label_name
+
+static bfd_boolean
+m88k_is_local_label_name (bfd *abfd ATTRIBUTE_UNUSED, const char *name)
+{
+ return name[0] == '@';
+}
+
+static bfd_reloc_status_type
+m88k_special_reloc (bfd *abfd,
+ arelent *reloc_entry,
+ asymbol *symbol,
+ void * data,
+ asection *input_section,
+ bfd *output_bfd,
+ char **error_message ATTRIBUTE_UNUSED)
+{
+ 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 targeted 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, (bfd_vma) relocation,
+ (unsigned char *) data + addr);
+ }
+
+ /* If we are not producing relocatable 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 (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 H_GET_16
+#define SWAP_OUT_RELOC_OFFSET H_PUT_16
+
+#define RELOC_PROCESSING(relent,reloc,symbols,abfd,section) \
+ reloc_processing(relent, reloc, symbols, abfd, section)
+
+static void
+reloc_processing (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)
+
+#ifndef bfd_pe_print_pdata
+#define bfd_pe_print_pdata NULL
+#endif
+
+#include "coffcode.h"
+
+#undef coff_write_armap
+
+CREATE_BIG_COFF_TARGET_VEC (m88k_coff_bcs_vec, "coff-m88kbcs", 0, 0, '_', NULL, COFF_SWAP_TABLE)
diff --git a/bfd/coff-mcore.c b/bfd/coff-mcore.c
new file mode 100644
index 0000000..7dad44f
--- /dev/null
+++ b/bfd/coff-mcore.c
@@ -0,0 +1,560 @@
+/* BFD back-end for Motorola MCore COFF/PE
+ Copyright (C) 1999-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, 51 Franklin Street - Fifth Floor,
+ Boston, MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.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 bfd_boolean mcore_bfd_coff_final_link
+ (bfd *, struct bfd_link_info *);
+static bfd_reloc_status_type mcore_coff_unsupported_reloc
+ (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
+
+
+/* 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 2
+
+/* 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 */
+ NULL, /* 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 */
+ NULL, /* 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 */
+
+ HOWTO (IMAGE_REL_MCORE_RVA, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ NULL, /* special_function */
+ "MCORE_RVA", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* 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))
+
+
+/* Add an entry to the base file. */
+
+static bfd_boolean
+mcore_emit_base_file_entry (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;
+
+ if (fwrite (&addr, sizeof (addr), 1, (FILE *) info->base_file) == 1)
+ return TRUE;
+
+ bfd_set_error (bfd_error_system_call);
+ return FALSE;
+}
+
+static bfd_reloc_status_type
+mcore_coff_unsupported_reloc (bfd * abfd,
+ arelent * reloc_entry,
+ asymbol * symbol ATTRIBUTE_UNUSED,
+ void * data ATTRIBUTE_UNUSED,
+ asection * input_section ATTRIBUTE_UNUSED,
+ bfd * output_bfd ATTRIBUTE_UNUSED,
+ char ** error_message ATTRIBUTE_UNUSED)
+{
+ BFD_ASSERT (reloc_entry->howto != (reloc_howto_type *)0);
+
+ _bfd_error_handler (_("%B: Relocation %s (%d) is not currently supported.\n"),
+ 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 (bfd * abfd ATTRIBUTE_UNUSED,
+ 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);
+ HOW2MAP (BFD_RELOC_RVA, IMAGE_REL_MCORE_RVA);
+ default:
+ return NULL;
+ }
+ /*NOTREACHED*/
+}
+#undef HOW2MAP
+
+static reloc_howto_type *
+mcore_coff_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ const char *r_name)
+{
+ unsigned int i;
+
+ for (i = 0;
+ i < (sizeof (mcore_coff_howto_table)
+ / sizeof (mcore_coff_howto_table[0]));
+ i++)
+ if (mcore_coff_howto_table[i].name != NULL
+ && strcasecmp (mcore_coff_howto_table[i].name, r_name) == 0)
+ return &mcore_coff_howto_table[i];
+
+ return NULL;
+}
+
+#define RTYPE2HOWTO(cache_ptr, dst) \
+ (cache_ptr)->howto = mcore_coff_howto_table + (dst)->r_type;
+
+static reloc_howto_type *
+coff_mcore_rtype_to_howto (bfd * abfd ATTRIBUTE_UNUSED,
+ asection * sec,
+ struct internal_reloc * rel,
+ struct coff_link_hash_entry * h ATTRIBUTE_UNUSED,
+ 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 (rel->r_type == IMAGE_REL_MCORE_RVA)
+ * addendp -= pe_data (sec->output_section->owner)->pe_opthdr.ImageBase;
+
+ else 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.
+ This function is referenced in pe_mkobject in peicode.h. */
+
+static bfd_boolean
+in_reloc_p (bfd * abfd ATTRIBUTE_UNUSED, reloc_howto_type * howto)
+{
+ return ! howto->pc_relative && howto->type != IMAGE_REL_MCORE_RVA;
+}
+
+/* The reloc processing routine for the optimized COFF linker. */
+static bfd_boolean
+coff_mcore_relocate_section (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;
+
+ /* If we are performing a relocatable link, we don't need to do a
+ thing. The caller will take care of adjusting the reloc
+ addresses and symbol indices. */
+ if (info->relocatable)
+ return TRUE;
+
+ /* Check if we have the same endianness */
+ if ( input_bfd->xvec->byteorder != output_bfd->xvec->byteorder
+ && output_bfd->xvec->byteorder != BFD_ENDIAN_UNKNOWN)
+ {
+ (*_bfd_error_handler)
+ (_("%B: compiled for a %s system and target is %s.\n"),
+ input_bfd,
+ bfd_big_endian (input_bfd) ? _("big endian") : _("little endian"),
+ bfd_big_endian (output_bfd) ? _("big endian") : _("little endian"));
+
+ bfd_set_error (bfd_error_wrong_format);
+ return FALSE;
+ }
+
+ rel = relocs;
+ relend = rel + input_section->reloc_count;
+
+ for (; rel < relend; rel++)
+ {
+ 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;
+ }
+
+ addend = 0;
+
+ /* 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, TRUE)))
+ 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 (_("%B: unsupported relocation type 0x%02x"),
+ input_bfd, r_type);
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+
+ case IMAGE_REL_MCORE_ABSOLUTE:
+ _bfd_error_handler
+ (_("Warning: unsupported reloc %s <file %B, section %A>\n"
+ "sym %ld (%s), r_vaddr %ld (%lx)"),
+ input_bfd, input_section, howto->name,
+ 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:
+ /* XXX fixme - shouldn't this be like the code for the RVA reloc ? */
+ rstat = _bfd_relocate_contents (howto, input_bfd, val, loc);
+ break;
+
+ case IMAGE_REL_MCORE_RVA:
+ rstat = _bfd_final_link_relocate
+ (howto, input_bfd,
+ input_section, contents, rel->r_vaddr - input_section->vma,
+ val, addend);
+ break;
+ }
+
+ /* Emit a reloc if the backend thinks it needs it. */
+ if (info->base_file
+ && sym
+ && pe_data (output_bfd)->in_reloc_p (output_bfd, howto)
+ && !mcore_emit_base_file_entry (info, output_bfd, input_section,
+ rel->r_vaddr))
+ return FALSE;
+
+ switch (rstat)
+ {
+ default:
+ abort ();
+
+ case bfd_reloc_ok:
+ break;
+
+ case bfd_reloc_overflow:
+ if (! ((*info->callbacks->reloc_overflow)
+ (info, (h ? &h->root : NULL), 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_bfd_reloc_name_lookup mcore_coff_reloc_name_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;}
+
+/* Make sure that the 'r_offset' field is copied properly
+ so that identical binaries will compare the same. */
+#define SWAP_IN_RELOC_OFFSET H_GET_32
+#define SWAP_OUT_RELOC_OFFSET H_PUT_32
+
+#define COFF_PAGE_SIZE 0x1000
+
+#include "coffcode.h"
+
+/* Forward declaration to initialise alternative_target field. */
+extern const bfd_target TARGET_LITTLE_SYM;
+
+/* The transfer vectors that lead the outside world to all of the above. */
+CREATE_BIG_COFF_TARGET_VEC (TARGET_BIG_SYM, TARGET_BIG_NAME, D_PAGED,
+ (SEC_CODE | SEC_DATA | SEC_DEBUGGING | SEC_READONLY | SEC_LINK_ONCE | SEC_LINK_DUPLICATES),
+ 0, & TARGET_LITTLE_SYM, COFF_SWAP_TABLE)
+CREATE_LITTLE_COFF_TARGET_VEC (TARGET_LITTLE_SYM, TARGET_LITTLE_NAME, D_PAGED,
+ (SEC_CODE | SEC_DATA | SEC_DEBUGGING | SEC_READONLY | SEC_LINK_ONCE | SEC_LINK_DUPLICATES),
+ 0, & TARGET_BIG_SYM, COFF_SWAP_TABLE)
diff --git a/bfd/coff-mips.c b/bfd/coff-mips.c
new file mode 100644
index 0000000..298671c
--- /dev/null
+++ b/bfd/coff-mips.c
@@ -0,0 +1,1500 @@
+/* BFD back-end for MIPS Extended-Coff files.
+ Copyright (C) 1990-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.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 bfd_reloc_status_type
+mips_generic_reloc
+ (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
+static bfd_reloc_status_type
+mips_refhi_reloc
+ (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
+static bfd_reloc_status_type
+mips_reflo_reloc
+ (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
+static bfd_reloc_status_type
+mips_gprel_reloc
+ (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
+
+
+/* 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 */
+
+ EMPTY_HOWTO (8),
+ EMPTY_HOWTO (9),
+ EMPTY_HOWTO (10),
+ EMPTY_HOWTO (11),
+
+ /* FIXME: This relocation is used (internally only) to represent branches
+ when assembling. It should never appear in output files, and
+ be removed. (It used to be used for embedded-PIC support.) */
+ 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 */
+};
+
+#define MIPS_HOWTO_COUNT \
+ (sizeof mips_howto_table / sizeof mips_howto_table[0])
+
+/* See whether the magic number matches. */
+
+static bfd_boolean
+mips_ecoff_bad_format_hook (bfd * abfd, void * 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 (bfd * abfd,
+ void * ext_ptr,
+ struct internal_reloc *intern)
+{
+ const RELOC *ext = (RELOC *) ext_ptr;
+
+ intern->r_vaddr = H_GET_32 (abfd, 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;
+ }
+}
+
+/* Swap a reloc out. */
+
+static void
+mips_ecoff_swap_reloc_out (bfd * abfd,
+ const struct internal_reloc * intern,
+ void * dst)
+{
+ RELOC *ext = (RELOC *) dst;
+ long r_symndx;
+
+ BFD_ASSERT (intern->r_extern
+ || (intern->r_symndx >= 0 && intern->r_symndx <= 12));
+
+ r_symndx = intern->r_symndx;
+
+ H_PUT_32 (abfd, intern->r_vaddr, 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 (bfd *abfd,
+ const struct internal_reloc *intern,
+ arelent *rptr)
+{
+ if (intern->r_type > MIPS_R_PCREL16)
+ 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;
+
+ 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 (bfd *abfd ATTRIBUTE_UNUSED,
+ const arelent *rel ATTRIBUTE_UNUSED,
+ struct internal_reloc *intern ATTRIBUTE_UNUSED)
+{
+}
+
+/* ECOFF relocs are either against external symbols, or against
+ sections. If we are producing relocatable 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
+ relocatable output against an external symbol. */
+
+static bfd_reloc_status_type
+mips_generic_reloc (bfd *abfd ATTRIBUTE_UNUSED,
+ arelent *reloc_entry,
+ asymbol *symbol,
+ void * data ATTRIBUTE_UNUSED,
+ asection *input_section,
+ bfd *output_bfd,
+ char **error_message ATTRIBUTE_UNUSED)
+{
+ 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 (bfd *abfd ATTRIBUTE_UNUSED,
+ arelent *reloc_entry,
+ asymbol *symbol,
+ void * data,
+ asection *input_section,
+ bfd *output_bfd,
+ char **error_message ATTRIBUTE_UNUSED)
+{
+ 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 > bfd_get_section_limit (abfd, input_section))
+ return bfd_reloc_outofrange;
+
+ /* Save the information, and let REFLO do the actual relocation. */
+ n = (struct mips_hi *) bfd_malloc ((bfd_size_type) 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 (bfd *abfd ATTRIBUTE_UNUSED,
+ arelent *reloc_entry,
+ asymbol *symbol,
+ void * data,
+ asection *input_section,
+ bfd *output_bfd,
+ char **error_message ATTRIBUTE_UNUSED)
+{
+ 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 &~ (unsigned) 0xffff) | ((val >> 16) & 0xffff);
+ bfd_put_32 (abfd, (bfd_vma) 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 (bfd *abfd ATTRIBUTE_UNUSED,
+ arelent *reloc_entry,
+ asymbol *symbol,
+ void * data,
+ asection *input_section,
+ bfd *output_bfd,
+ char **error_message ATTRIBUTE_UNUSED)
+{
+ bfd_boolean relocatable;
+ 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)
+ relocatable = TRUE;
+ else
+ {
+ relocatable = FALSE;
+ output_bfd = symbol->section->output_section->owner;
+ }
+
+ if (bfd_is_und_section (symbol->section) && ! relocatable)
+ 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 relocatable output. */
+ gp = _bfd_get_gp_value (output_bfd);
+ if (gp == 0
+ && (! relocatable
+ || (symbol->flags & BSF_SECTION_SYM) != 0))
+ {
+ if (relocatable)
+ {
+ /* 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 > bfd_get_section_limit (abfd, input_section))
+ 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 relocatable output, we don't want to do this for
+ an external symbol. */
+ if (! relocatable
+ || (symbol->flags & BSF_SECTION_SYM) != 0)
+ val += relocation - gp;
+
+ insn = (insn &~ (unsigned) 0xffff) | (val & 0xffff);
+ bfd_put_32 (abfd, (bfd_vma) insn, (bfd_byte *) data + reloc_entry->address);
+
+ if (relocatable)
+ reloc_entry->address += input_section->output_offset;
+
+ /* Make sure it fit in 16 bits. */
+ if ((long) val >= 0x8000 || (long) val < -0x8000)
+ return bfd_reloc_overflow;
+
+ return bfd_reloc_ok;
+}
+
+/* Get the howto structure for a generic reloc type. */
+
+static reloc_howto_type *
+mips_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ 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_GPREL16:
+ 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;
+ default:
+ return (reloc_howto_type *) NULL;
+ }
+
+ return &mips_howto_table[mips_type];
+}
+
+static reloc_howto_type *
+mips_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ const char *r_name)
+{
+ unsigned int i;
+
+ for (i = 0;
+ i < sizeof (mips_howto_table) / sizeof (mips_howto_table[0]);
+ i++)
+ if (mips_howto_table[i].name != NULL
+ && strcasecmp (mips_howto_table[i].name, r_name) == 0)
+ return &mips_howto_table[i];
+
+ return NULL;
+}
+
+/* A helper routine for mips_relocate_section which handles the REFHI
+ relocations. The REFHI relocation must be followed by a REFLO
+ relocation, and the addend used is formed from the addends of both
+ instructions. */
+
+static void
+mips_relocate_hi (struct internal_reloc *refhi,
+ struct internal_reloc *reflo,
+ bfd *input_bfd,
+ asection *input_section,
+ bfd_byte *contents,
+ bfd_vma relocation)
+{
+ unsigned long insn;
+ unsigned long val;
+ unsigned long vallo;
+
+ if (refhi == NULL)
+ return;
+
+ insn = bfd_get_32 (input_bfd,
+ contents + refhi->r_vaddr - input_section->vma);
+ if (reflo == NULL)
+ vallo = 0;
+ else
+ vallo = (bfd_get_32 (input_bfd,
+ contents + 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 ((val & 0x8000) != 0)
+ val += 0x10000;
+
+ insn = (insn &~ (unsigned) 0xffff) | ((val >> 16) & 0xffff);
+ bfd_put_32 (input_bfd, (bfd_vma) insn,
+ contents + refhi->r_vaddr - input_section->vma);
+}
+
+/* Relocate a section while linking a MIPS ECOFF file. */
+
+static bfd_boolean
+mips_relocate_section (bfd *output_bfd,
+ struct bfd_link_info *info,
+ bfd *input_bfd,
+ asection *input_section,
+ bfd_byte *contents,
+ void * external_relocs)
+{
+ asection **symndx_to_section;
+ struct ecoff_link_hash_entry **sym_hashes;
+ bfd_vma gp;
+ bfd_boolean gp_undefined;
+ struct external_reloc *ext_rel;
+ struct external_reloc *ext_rel_end;
+ unsigned int i;
+ bfd_boolean got_lo;
+ struct internal_reloc lo_int_rel;
+ bfd_size_type amt;
+
+ 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)
+ {
+ amt = NUM_RELOC_SECTIONS * sizeof (asection *);
+ symndx_to_section = (asection **) bfd_alloc (input_bfd, amt);
+ 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;
+
+ 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;
+ bfd_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, 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 reloc requires special handling. It must be followed
+ by a REFLO reloc, and the addend is formed from both relocs. */
+ if (int_rel.r_type == MIPS_R_REFHI)
+ {
+ struct external_reloc *lo_ext_rel;
+
+ /* As a GNU extension, permit an arbitrary number of REFHI
+ relocs before the REFLO 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, 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 == MIPS_R_REFLO
+ && 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];
+
+ 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 used 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->relocatable
+ || 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 relocatable output, and we
+ aren't going to define this symbol, so we just leave
+ the instruction alone. */
+ addend = 0;
+ }
+ }
+
+ if (info->relocatable)
+ {
+ /* We are generating relocatable 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;
+
+ 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. */
+ if (howto->pc_relative)
+ 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)
+ r = _bfd_relocate_contents (howto, input_bfd, relocation,
+ (contents
+ + int_rel.r_vaddr
+ - input_section->vma));
+ else
+ {
+ mips_relocate_hi (&int_rel,
+ use_lo ? &lo_int_rel : NULL,
+ input_bfd, input_section, contents,
+ relocation);
+ 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, 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, TRUE)))
+ 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)
+ relocation += int_rel.r_vaddr;
+ }
+
+ if (int_rel.r_type != MIPS_R_REFHI)
+ r = _bfd_final_link_relocate (howto,
+ input_bfd,
+ input_section,
+ contents,
+ (int_rel.r_vaddr
+ - input_section->vma),
+ relocation,
+ addend);
+ else
+ {
+ mips_relocate_hi (&int_rel,
+ use_lo ? &lo_int_rel : NULL,
+ input_bfd, input_section, contents,
+ relocation);
+ 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))
+ & 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 = NULL;
+ else
+ name = bfd_section_name (input_bfd, s);
+ if (! ((*info->callbacks->reloc_overflow)
+ (info, (h ? &h->root : NULL), name, howto->name,
+ (bfd_vma) 0, input_bfd, input_section,
+ int_rel.r_vaddr - input_section->vma)))
+ return FALSE;
+ }
+ break;
+ }
+ }
+ }
+
+ 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 (*) (bfd *,void *,int,int,int,int,void *)) bfd_void, /* aux_in */
+ (void (*) (bfd *,void *,void *)) bfd_void, /* sym_in */
+ (void (*) (bfd *,void *,void *)) bfd_void, /* lineno_in */
+ (unsigned (*) (bfd *,void *,int,int,int,int,void *)) bfd_void,/*aux_out*/
+ (unsigned (*) (bfd *,void *,void *)) bfd_void, /* sym_out */
+ (unsigned (*) (bfd *,void *,void *)) bfd_void, /* lineno_out */
+ (unsigned (*) (bfd *,void *,void *)) 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, FILNMLEN, TRUE,
+ ECOFF_NO_LONG_SECTION_NAMES, 4, FALSE, 2, 32768,
+ 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,
+ 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
+#define _bfd_ecoff_bfd_reloc_name_lookup mips_bfd_reloc_name_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 bfd_generic_relax_section
+
+/* GC of sections is not done. */
+#define _bfd_ecoff_bfd_gc_sections bfd_generic_gc_sections
+
+/* Input section flags is not implemented. */
+#define _bfd_ecoff_bfd_lookup_section_flags bfd_generic_lookup_section_flags
+
+/* Merging of sections is not done. */
+#define _bfd_ecoff_bfd_merge_sections bfd_generic_merge_sections
+
+#define _bfd_ecoff_bfd_is_group_section bfd_generic_is_group_section
+#define _bfd_ecoff_bfd_discard_group bfd_generic_discard_group
+#define _bfd_ecoff_section_already_linked \
+ _bfd_coff_section_already_linked
+#define _bfd_ecoff_bfd_define_common_symbol bfd_generic_define_common_symbol
+
+extern const bfd_target mips_ecoff_be_vec;
+
+const bfd_target mips_ecoff_le_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 */
+ 0, /* match priority. */
+ 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, _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),
+
+ & mips_ecoff_be_vec,
+
+ & mips_ecoff_backend_data
+};
+
+const bfd_target mips_ecoff_be_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 */
+ 0, /* match priority. */
+ 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_generic_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),
+
+ & mips_ecoff_le_vec,
+
+ & mips_ecoff_backend_data
+};
+
+const bfd_target mips_ecoff_bele_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 */
+ 0, /* match priority. */
+ 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, _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),
+
+ NULL,
+
+ & mips_ecoff_backend_data
+};
diff --git a/bfd/coff-ppc.c b/bfd/coff-ppc.c
new file mode 100644
index 0000000..32d3012
--- /dev/null
+++ b/bfd/coff-ppc.c
@@ -0,0 +1,2592 @@
+/* BFD back-end for PowerPC Microsoft Portable Executable files.
+ Copyright (C) 1990-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, 51 Franklin Street - Fifth Floor,
+ Boston, MA 02110-1301, 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 "sysdep.h"
+#include "bfd.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 bfd_boolean ppc_bfd_coff_final_link (bfd *, struct bfd_link_info *);
+extern void dump_toc (void *);
+
+/* 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 initialized 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. */
+};
+
+/* Routine to create an entry in the link hash table. */
+
+static struct bfd_hash_entry *
+ppc_coff_link_hash_newfunc (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 bfd_boolean
+ppc_coff_link_hash_table_init (struct ppc_coff_link_hash_table *table,
+ bfd *abfd,
+ struct bfd_hash_entry *(*newfunc)
+ (struct bfd_hash_entry *,
+ struct bfd_hash_table *,
+ const char *),
+ unsigned int entsize)
+{
+ return _bfd_coff_link_hash_table_init (&table->root, abfd, newfunc, entsize);
+}
+
+/* Create a PE linker hash table. */
+
+static struct bfd_link_hash_table *
+ppc_coff_link_hash_table_create (bfd *abfd)
+{
+ struct ppc_coff_link_hash_table *ret;
+ bfd_size_type amt = sizeof (struct ppc_coff_link_hash_table);
+
+ ret = (struct ppc_coff_link_hash_table *) bfd_malloc (amt);
+ if (ret == NULL)
+ return NULL;
+ if (!ppc_coff_link_hash_table_init (ret, abfd,
+ ppc_coff_link_hash_newfunc,
+ sizeof (struct ppc_coff_link_hash_entry)))
+ {
+ free (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
+ (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
+static bfd_reloc_status_type ppc_pair_reloc
+ (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
+static bfd_reloc_status_type ppc_toc16_reloc
+ (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
+static bfd_reloc_status_type ppc_section_reloc
+ (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
+static bfd_reloc_status_type ppc_secrel_reloc
+ (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
+static bfd_reloc_status_type ppc_imglue_reloc
+ (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
+
+/* 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,
+ tocdata
+};
+
+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 (asection *toc_section,
+ bfd_signed_vma our_toc_offset,
+ enum ref_category cat,
+ const char *name)
+{
+ /* Add this entry to our toc addr-offset-name list. */
+ bfd_size_type amt = sizeof (struct list_ele);
+ struct list_ele *t = (struct list_ele *) bfd_malloc (amt);
+
+ 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
+
+/* Record a toc offset against a symbol. */
+static bfd_boolean
+ppc_record_toc_entry (bfd *abfd,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ asection *sec ATTRIBUTE_UNUSED,
+ int sym,
+ enum toc_type toc_kind ATTRIBUTE_UNUSED)
+{
+ struct ppc_coff_link_hash_entry *h;
+ 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;
+ bfd_size_type amt;
+
+ /* allocate a table */
+ amt = (bfd_size_type) obj_raw_syment_count (abfd) * sizeof (int);
+ local_syms = (int *) bfd_zalloc (abfd, amt);
+ 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 16-bit displacement. */
+ if (global_toc_size > 65535)
+ {
+ (*_bfd_error_handler) (_("TOC overflow"));
+ bfd_set_error (bfd_error_file_too_big);
+ return FALSE;
+ }
+ }
+ }
+ else
+ {
+ /* 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 16-bit displacement. */
+ 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 (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 bfd_boolean
+in_reloc_p (bfd * abfd ATTRIBUTE_UNUSED,
+ 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) ;
+}
+
+static bfd_boolean
+write_base_file_entry (bfd *obfd, struct bfd_link_info *info, bfd_vma addr)
+{
+ if (coff_data (obfd)->pe)
+ addr -= pe_data (obfd)->pe_opthdr.ImageBase;
+ if (fwrite (&addr, sizeof (addr), 1, (FILE *) info->base_file) == 1)
+ return TRUE;
+
+ bfd_set_error (bfd_error_system_call);
+ return FALSE;
+}
+
+/* The reloc processing routine for the optimized COFF linker. */
+
+static bfd_boolean
+coff_ppc_relocate_section (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;
+ asection *toc_section = 0;
+ bfd_vma relocation;
+ reloc_howto_type *howto = 0;
+
+ /* If we are performing a relocatable link, we don't need to do a
+ thing. The caller will take care of adjusting the reloc
+ addresses and symbol indices. */
+ if (info->relocatable)
+ return TRUE;
+
+ 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, TRUE)))
+ return FALSE;
+ }
+ }
+
+ rstat = bfd_reloc_ok;
+
+ /* Each case must do its own relocation, setting rstat appropriately. */
+ switch (r_type)
+ {
+ default:
+ (*_bfd_error_handler)
+ (_("%B: unsupported relocation type 0x%02x"), input_bfd, r_type);
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ case IMAGE_REL_PPC_TOCREL16:
+ {
+ bfd_signed_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;
+ char name[SYMNMLEN + 1];
+
+ sym = syms + symndx;
+ strncpy (name, sym->_n._n_name, SYMNMLEN);
+ name[SYMNMLEN] = '\0';
+
+ 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 16-bit displacement. */
+ if ((bfd_vma) our_toc_offset >= 65535)
+ {
+ (*_bfd_error_handler)
+ (_("%B: Relocation for %s of %lx exceeds Toc size limit"),
+ input_bfd, name,
+ (unsigned long) 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 (!write_base_file_entry (output_bfd, info, addr))
+ return FALSE;
+ }
+
+ /* FIXME: this test is conservative. */
+ if ((r_flags & IMAGE_REL_PPC_TOCDEFN) != IMAGE_REL_PPC_TOCDEFN
+ && (bfd_vma) our_toc_offset > toc_section->size)
+ {
+ (*_bfd_error_handler)
+ (_("%B: Relocation exceeds allocated TOC (%lx)"),
+ input_bfd, (unsigned long) toc_section->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. */
+ DUMP_RELOC2 (howto->name, rel);
+
+ if (h != 0)
+ {
+ if (h->symbol_is_glue == 1)
+ {
+ bfd_put_32 (input_bfd, (bfd_vma) 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;
+ char buf[SYMNMLEN + 1];
+
+ if (h == 0)
+ {
+ strncpy (buf, (syms+symndx)->_n._n_name, SYMNMLEN);
+ buf[SYMNMLEN] = '\0';
+ my_name = buf;
+ }
+ else
+ my_name = h->root.root.root.string;
+
+ (*_bfd_error_handler)
+ (_("Warning: unsupported reloc %s <file %B, section %A>\n"
+ "sym %ld (%s), r_vaddr %ld (%lx)"),
+ input_bfd, input_section, howto->name,
+ 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)
+ (_("%B: Out of order IMGLUE reloc for %s"), input_bfd, my_name);
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+
+ case IMAGE_REL_PPC_ADDR32NB:
+ {
+ const char *name = 0;
+
+ DUMP_RELOC2 (howto->name, rel);
+
+ if (CONST_STRNEQ (input_section->name, ".idata$2") && first_thunk_address == 0)
+ {
+ /* Set magic values. */
+ int idata5offset;
+ struct coff_link_hash_entry *myh;
+
+ 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;
+ 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)
+ {
+ struct coff_link_hash_entry *myh;
+
+ 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 (!write_base_file_entry (output_bfd, info, addr))
+ return FALSE;
+ }
+ }
+
+ 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 = NULL;
+ 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, (h ? &h->root.root : NULL), 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 (void * vfile)
+{
+ FILE *file = (FILE *) vfile;
+ struct list_ele *t;
+
+ fputs (_(h1), file);
+ fputs (_(h2), file);
+ fputs (_(h3), file);
+
+ 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 == tocdata)
+ 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, (unsigned long) global_toc_size,
+ thunk_size, (unsigned long) 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");
+}
+
+bfd_boolean
+ppc_allocate_toc_section (struct bfd_link_info *info ATTRIBUTE_UNUSED)
+{
+ asection *s;
+ bfd_byte *foo;
+ bfd_size_type amt;
+ 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 ();
+
+ amt = global_toc_size;
+ foo = (bfd_byte *) bfd_alloc (bfd_of_toc_owner, amt);
+ memset(foo, test_char, (size_t) global_toc_size);
+
+ s->size = global_toc_size;
+ s->contents = foo;
+
+ return TRUE;
+}
+
+bfd_boolean
+ppc_process_before_allocation (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);
+ bfd_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 (bfd *abfd ATTRIBUTE_UNUSED,
+ arelent *reloc_entry ATTRIBUTE_UNUSED,
+ asymbol *symbol ATTRIBUTE_UNUSED,
+ void * data ATTRIBUTE_UNUSED,
+ asection *input_section ATTRIBUTE_UNUSED,
+ bfd *output_bfd,
+ char **error_message ATTRIBUTE_UNUSED)
+{
+ UN_IMPL("REFHI");
+ DUMP_RELOC("REFHI",reloc_entry);
+
+ if (output_bfd == (bfd *) NULL)
+ return bfd_reloc_continue;
+
+ return bfd_reloc_undefined;
+}
+
+static bfd_reloc_status_type
+ppc_pair_reloc (bfd *abfd ATTRIBUTE_UNUSED,
+ arelent *reloc_entry ATTRIBUTE_UNUSED,
+ asymbol *symbol ATTRIBUTE_UNUSED,
+ void * data ATTRIBUTE_UNUSED,
+ asection *input_section ATTRIBUTE_UNUSED,
+ bfd *output_bfd,
+ char **error_message ATTRIBUTE_UNUSED)
+{
+ 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 (bfd *abfd ATTRIBUTE_UNUSED,
+ arelent *reloc_entry ATTRIBUTE_UNUSED,
+ asymbol *symbol ATTRIBUTE_UNUSED,
+ void * data ATTRIBUTE_UNUSED,
+ asection *input_section ATTRIBUTE_UNUSED,
+ bfd *output_bfd,
+ char **error_message ATTRIBUTE_UNUSED)
+{
+ UN_IMPL ("TOCREL16");
+ DUMP_RELOC ("TOCREL16",reloc_entry);
+
+ if (output_bfd == (bfd *) NULL)
+ return bfd_reloc_continue;
+
+ return bfd_reloc_ok;
+}
+
+static bfd_reloc_status_type
+ppc_secrel_reloc (bfd *abfd ATTRIBUTE_UNUSED,
+ arelent *reloc_entry ATTRIBUTE_UNUSED,
+ asymbol *symbol ATTRIBUTE_UNUSED,
+ void * data ATTRIBUTE_UNUSED,
+ asection *input_section ATTRIBUTE_UNUSED,
+ bfd *output_bfd,
+ char **error_message ATTRIBUTE_UNUSED)
+{
+ 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 (bfd *abfd ATTRIBUTE_UNUSED,
+ arelent *reloc_entry ATTRIBUTE_UNUSED,
+ asymbol *symbol ATTRIBUTE_UNUSED,
+ void * data ATTRIBUTE_UNUSED,
+ asection *input_section ATTRIBUTE_UNUSED,
+ bfd *output_bfd,
+ char **error_message ATTRIBUTE_UNUSED)
+{
+ 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 (bfd *abfd ATTRIBUTE_UNUSED,
+ arelent *reloc_entry ATTRIBUTE_UNUSED,
+ asymbol *symbol ATTRIBUTE_UNUSED,
+ void * data ATTRIBUTE_UNUSED,
+ asection *input_section ATTRIBUTE_UNUSED,
+ bfd *output_bfd,
+ char **error_message ATTRIBUTE_UNUSED)
+
+{
+ 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 possibility 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 (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:
+ (*_bfd_error_handler) (_("warning: unsupported reloc %s [%d] used -- it may not work"),
+ 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 (bfd *abfd ATTRIBUTE_UNUSED,
+ asection *sec,
+ struct internal_reloc *rel,
+ struct coff_link_hash_entry *h ATTRIBUTE_UNUSED,
+ struct internal_syment *sym ATTRIBUTE_UNUSED,
+ 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:
+ (*_bfd_error_handler) (_("warning: unsupported reloc %s [%d] used -- it may not work"),
+ 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 (bfd *abfd ATTRIBUTE_UNUSED,
+ 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;
+ }
+}
+#undef HOW2MAP
+
+static reloc_howto_type *
+ppc_coff_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ const char *r_name)
+{
+ unsigned int i;
+
+ for (i = 0;
+ i < sizeof (ppc_coff_howto_table) / sizeof (ppc_coff_howto_table[0]);
+ i++)
+ if (ppc_coff_howto_table[i].name != NULL
+ && strcasecmp (ppc_coff_howto_table[i].name, r_name) == 0)
+ return &ppc_coff_howto_table[i];
+
+ return NULL;
+}
+
+/* Tailor coffcode.h -- macro heaven. */
+
+#define RTYPE2HOWTO(cache_ptr, dst) ppc_coff_rtype2howto (cache_ptr, dst)
+
+/* 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_bfd_reloc_name_lookup ppc_coff_reloc_name_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
+#endif
+
+#define SELECT_RELOC(internal, howto) {internal.r_type=howto->type;}
+
+#define COFF_PAGE_SIZE 0x1000
+
+/* FIXME: This controls some code that used to be in peicode.h and is
+ now in peigen.c. It will not control the code in peigen.c. If
+ anybody wants to get this working, you will need to fix that. */
+#define POWERPC_LE_PE
+
+#define COFF_SECTION_ALIGNMENT_ENTRIES \
+{ COFF_SECTION_NAME_EXACT_MATCH (".idata$2"), \
+ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 0 }, \
+{ COFF_SECTION_NAME_EXACT_MATCH (".idata$3"), \
+ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 0 }, \
+{ COFF_SECTION_NAME_EXACT_MATCH (".idata$4"), \
+ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 2 }, \
+{ COFF_SECTION_NAME_EXACT_MATCH (".idata$5"), \
+ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 2 }, \
+{ COFF_SECTION_NAME_EXACT_MATCH (".idata$6"), \
+ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 1 }, \
+{ COFF_SECTION_NAME_EXACT_MATCH (".reloc"), \
+ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 1 }
+
+#include "coffcode.h"
+
+#ifndef COFF_IMAGE_WITH_PE
+
+static bfd_boolean
+ppc_do_last (bfd *abfd)
+{
+ if (abfd == bfd_of_toc_owner)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+static bfd *
+ppc_get_last (void)
+{
+ 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 */
+
+/* Do the final link step. */
+
+bfd_boolean
+ppc_bfd_coff_final_link (bfd *abfd, struct bfd_link_info *info)
+{
+ bfd_size_type symesz;
+ struct coff_final_link_info flaginfo;
+ bfd_boolean debug_merge_allocated;
+ asection *o;
+ struct bfd_link_order *p;
+ bfd_size_type max_sym_count;
+ bfd_size_type max_lineno_count;
+ bfd_size_type max_reloc_count;
+ bfd_size_type max_output_reloc_count;
+ bfd_size_type 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];
+ bfd_size_type amt;
+
+ symesz = bfd_coff_symesz (abfd);
+
+ flaginfo.info = info;
+ flaginfo.output_bfd = abfd;
+ flaginfo.strtab = NULL;
+ flaginfo.section_info = NULL;
+ flaginfo.last_file_index = -1;
+ flaginfo.last_bf_index = -1;
+ flaginfo.internal_syms = NULL;
+ flaginfo.sec_ptrs = NULL;
+ flaginfo.sym_indices = NULL;
+ flaginfo.outsyms = NULL;
+ flaginfo.linenos = NULL;
+ flaginfo.contents = NULL;
+ flaginfo.external_relocs = NULL;
+ flaginfo.internal_relocs = NULL;
+ debug_merge_allocated = FALSE;
+
+ coff_data (abfd)->link_info = info;
+
+ flaginfo.strtab = _bfd_stringtab_init ();
+ if (flaginfo.strtab == NULL)
+ goto error_return;
+
+ if (! coff_debug_merge_hash_table_init (&flaginfo.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->map_head.link_order; 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->relocatable)
+ o->reloc_count += sec->reloc_count;
+
+ if (sec->rawsize > max_contents_size)
+ max_contents_size = sec->rawsize;
+ if (sec->size > max_contents_size)
+ max_contents_size = sec->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->relocatable
+ && (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 relocatable link, allocate space for the pointers we
+ need to keep. */
+ if (info->relocatable)
+ {
+ unsigned int i;
+
+ /* We use section_count + 1, rather than section_count, because
+ the target_index fields are 1 based. */
+ amt = abfd->section_count + 1;
+ amt *= sizeof (struct coff_link_section_info);
+ flaginfo.section_info = (struct coff_link_section_info *) bfd_malloc (amt);
+
+ if (flaginfo.section_info == NULL)
+ goto error_return;
+
+ for (i = 0; i <= abfd->section_count; i++)
+ {
+ flaginfo.section_info[i].relocs = NULL;
+ flaginfo.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 relocatable link, which is not the
+ common case. */
+ BFD_ASSERT (info->relocatable);
+ amt = o->reloc_count;
+ amt *= sizeof (struct internal_reloc);
+ flaginfo.section_info[o->target_index].relocs =
+ (struct internal_reloc *) bfd_malloc (amt);
+ amt = o->reloc_count;
+ amt *= sizeof (struct coff_link_hash_entry *);
+ flaginfo.section_info[o->target_index].rel_hashes =
+ (struct coff_link_hash_entry **) bfd_malloc (amt);
+ if (flaginfo.section_info[o->target_index].relocs == NULL
+ || flaginfo.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)
+ {
+ bfd_size_type 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. */
+ amt = max_sym_count * sizeof (struct internal_syment);
+ flaginfo.internal_syms = (struct internal_syment *) bfd_malloc (amt);
+ amt = max_sym_count * sizeof (asection *);
+ flaginfo.sec_ptrs = (asection **) bfd_malloc (amt);
+ amt = max_sym_count * sizeof (long);
+ flaginfo.sym_indices = (long *) bfd_malloc (amt);
+ amt = (max_sym_count + 1) * symesz;
+ flaginfo.outsyms = (bfd_byte *) bfd_malloc (amt);
+ amt = max_lineno_count * bfd_coff_linesz (abfd);
+ flaginfo.linenos = (bfd_byte *) bfd_malloc (amt);
+ flaginfo.contents = (bfd_byte *) bfd_malloc (max_contents_size);
+ flaginfo.external_relocs = (bfd_byte *) bfd_malloc (max_reloc_count * relsz);
+ if (! info->relocatable)
+ {
+ amt = max_reloc_count * sizeof (struct internal_reloc);
+ flaginfo.internal_relocs = (struct internal_reloc *) bfd_malloc (amt);
+ }
+ if ((flaginfo.internal_syms == NULL && max_sym_count > 0)
+ || (flaginfo.sec_ptrs == NULL && max_sym_count > 0)
+ || (flaginfo.sym_indices == NULL && max_sym_count > 0)
+ || flaginfo.outsyms == NULL
+ || (flaginfo.linenos == NULL && max_lineno_count > 0)
+ || (flaginfo.contents == NULL && max_contents_size > 0)
+ || (flaginfo.external_relocs == NULL && max_reloc_count > 0)
+ || (! info->relocatable
+ && flaginfo.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->map_head.link_order; 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 (&flaginfo, 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, &flaginfo, 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 (&flaginfo, 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 (&flaginfo.debug_merge);
+ debug_merge_allocated = FALSE;
+
+ if (flaginfo.internal_syms != NULL)
+ {
+ free (flaginfo.internal_syms);
+ flaginfo.internal_syms = NULL;
+ }
+ if (flaginfo.sec_ptrs != NULL)
+ {
+ free (flaginfo.sec_ptrs);
+ flaginfo.sec_ptrs = NULL;
+ }
+ if (flaginfo.sym_indices != NULL)
+ {
+ free (flaginfo.sym_indices);
+ flaginfo.sym_indices = NULL;
+ }
+ if (flaginfo.linenos != NULL)
+ {
+ free (flaginfo.linenos);
+ flaginfo.linenos = NULL;
+ }
+ if (flaginfo.contents != NULL)
+ {
+ free (flaginfo.contents);
+ flaginfo.contents = NULL;
+ }
+ if (flaginfo.external_relocs != NULL)
+ {
+ free (flaginfo.external_relocs);
+ flaginfo.external_relocs = NULL;
+ }
+ if (flaginfo.internal_relocs != NULL)
+ {
+ free (flaginfo.internal_relocs);
+ flaginfo.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 (flaginfo.last_file_index != -1
+ && (unsigned int) flaginfo.last_file.n_value != obj_raw_syment_count (abfd))
+ {
+ file_ptr pos;
+
+ flaginfo.last_file.n_value = obj_raw_syment_count (abfd);
+ bfd_coff_swap_sym_out (abfd, &flaginfo.last_file,
+ flaginfo.outsyms);
+ pos = obj_sym_filepos (abfd) + flaginfo.last_file_index * symesz;
+ if (bfd_seek (abfd, pos, SEEK_SET) != 0
+ || bfd_bwrite (flaginfo.outsyms, symesz, abfd) != symesz)
+ return FALSE;
+ }
+
+ /* Write out the global symbols. */
+ flaginfo.failed = FALSE;
+ bfd_hash_traverse (&info->hash->table, _bfd_coff_write_global_sym, &flaginfo);
+ if (flaginfo.failed)
+ goto error_return;
+
+ /* The outsyms buffer is used by _bfd_coff_write_global_sym. */
+ if (flaginfo.outsyms != NULL)
+ {
+ free (flaginfo.outsyms);
+ flaginfo.outsyms = NULL;
+ }
+
+ if (info->relocatable)
+ {
+ /* 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. */
+ amt = max_output_reloc_count * relsz;
+ external_relocs = (bfd_byte *) bfd_malloc (amt);
+ 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 = flaginfo.section_info[o->target_index].relocs;
+ irelend = irel + o->reloc_count;
+ rel_hash = flaginfo.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, irel, erel);
+ }
+
+ amt = relsz * o->reloc_count;
+ if (bfd_seek (abfd, o->rel_filepos, SEEK_SET) != 0
+ || bfd_bwrite (external_relocs, amt, abfd) != amt)
+ goto error_return;
+ }
+
+ free (external_relocs);
+ external_relocs = NULL;
+ }
+
+ /* Free up the section information. */
+ if (flaginfo.section_info != NULL)
+ {
+ unsigned int i;
+
+ for (i = 0; i < abfd->section_count; i++)
+ {
+ if (flaginfo.section_info[i].relocs != NULL)
+ free (flaginfo.section_info[i].relocs);
+ if (flaginfo.section_info[i].rel_hashes != NULL)
+ free (flaginfo.section_info[i].rel_hashes);
+ }
+ free (flaginfo.section_info);
+ flaginfo.section_info = NULL;
+ }
+
+ /* If we have optimized stabs strings, output them. */
+ if (coff_hash_table (info)->stab_info.stabstr != 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)
+ {
+ file_ptr pos;
+
+ pos = obj_sym_filepos (abfd) + obj_raw_syment_count (abfd) * symesz;
+ if (bfd_seek (abfd, pos, SEEK_SET) != 0)
+ return FALSE;
+
+#if STRING_SIZE_SIZE == 4
+ H_PUT_32 (abfd,
+ _bfd_stringtab_size (flaginfo.strtab) + STRING_SIZE_SIZE,
+ strbuf);
+#else
+ #error Change H_PUT_32 above
+#endif
+
+ if (bfd_bwrite (strbuf, (bfd_size_type) STRING_SIZE_SIZE, abfd)
+ != STRING_SIZE_SIZE)
+ return FALSE;
+
+ if (! _bfd_stringtab_emit (abfd, flaginfo.strtab))
+ return FALSE;
+ }
+
+ _bfd_stringtab_free (flaginfo.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 (&flaginfo.debug_merge);
+ if (flaginfo.strtab != NULL)
+ _bfd_stringtab_free (flaginfo.strtab);
+ if (flaginfo.section_info != NULL)
+ {
+ unsigned int i;
+
+ for (i = 0; i < abfd->section_count; i++)
+ {
+ if (flaginfo.section_info[i].relocs != NULL)
+ free (flaginfo.section_info[i].relocs);
+ if (flaginfo.section_info[i].rel_hashes != NULL)
+ free (flaginfo.section_info[i].rel_hashes);
+ }
+ free (flaginfo.section_info);
+ }
+ if (flaginfo.internal_syms != NULL)
+ free (flaginfo.internal_syms);
+ if (flaginfo.sec_ptrs != NULL)
+ free (flaginfo.sec_ptrs);
+ if (flaginfo.sym_indices != NULL)
+ free (flaginfo.sym_indices);
+ if (flaginfo.outsyms != NULL)
+ free (flaginfo.outsyms);
+ if (flaginfo.linenos != NULL)
+ free (flaginfo.linenos);
+ if (flaginfo.contents != NULL)
+ free (flaginfo.contents);
+ if (flaginfo.external_relocs != NULL)
+ free (flaginfo.external_relocs);
+ if (flaginfo.internal_relocs != NULL)
+ free (flaginfo.internal_relocs);
+ if (external_relocs != NULL)
+ free (external_relocs);
+ return FALSE;
+}
+#endif
+
+/* Forward declaration for use by alternative_target field. */
+#ifdef TARGET_BIG_SYM
+extern const bfd_target TARGET_BIG_SYM;
+#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_CODE | SEC_READONLY
+ | SEC_RELOC), /* section flags */
+#else
+ (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_READONLY
+ | SEC_RELOC | SEC_LINK_ONCE | SEC_LINK_DUPLICATES),
+#endif
+
+ 0, /* leading char */
+ '/', /* ar_pad_char */
+ 15, /* ar_max_namelen??? FIXMEmgo */
+ 0, /* match priority. */
+
+ 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),
+
+ /* Alternative_target. */
+#ifdef TARGET_BIG_SYM
+ & TARGET_BIG_SYM,
+#else
+ NULL,
+#endif
+
+ 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_CODE | SEC_READONLY
+ | SEC_RELOC), /* section flags */
+#else
+ (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_READONLY
+ | SEC_RELOC | SEC_LINK_ONCE | SEC_LINK_DUPLICATES),
+#endif
+
+ 0, /* leading char */
+ '/', /* ar_pad_char */
+ 15, /* ar_max_namelen??? FIXMEmgo */
+ 0, /* match priority. */
+
+ 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),
+
+ /* Alternative_target. */
+#ifdef TARGET_LITTLE_SYM
+ & TARGET_LITTLE_SYM,
+#else
+ NULL,
+#endif
+
+ COFF_SWAP_TABLE
+};
+
+#endif
diff --git a/bfd/coff-rs6000.c b/bfd/coff-rs6000.c
new file mode 100644
index 0000000..fea5f3b
--- /dev/null
+++ b/bfd/coff-rs6000.c
@@ -0,0 +1,4400 @@
+/* BFD back-end for IBM RS/6000 "XCOFF" files.
+ Copyright (C) 1990-2014 Free Software Foundation, Inc.
+ Written by Metin G. Ozisik, Mimi Phuong-Thao Vo, 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "libiberty.h"
+#include "bfd.h"
+#include "bfdlink.h"
+#include "libbfd.h"
+#include "coff/internal.h"
+#include "coff/xcoff.h"
+#include "coff/rs6000.h"
+#include "libcoff.h"
+#include "libxcoff.h"
+
+extern bfd_boolean _bfd_xcoff_mkobject (bfd *);
+extern bfd_boolean _bfd_xcoff_copy_private_bfd_data (bfd *, bfd *);
+extern bfd_boolean _bfd_xcoff_is_local_label_name (bfd *, const char *);
+extern reloc_howto_type *_bfd_xcoff_reloc_type_lookup
+ (bfd *, bfd_reloc_code_real_type);
+extern bfd_boolean _bfd_xcoff_slurp_armap (bfd *);
+extern const bfd_target *_bfd_xcoff_archive_p (bfd *);
+extern void * _bfd_xcoff_read_ar_hdr (bfd *);
+extern bfd *_bfd_xcoff_openr_next_archived_file (bfd *, bfd *);
+extern int _bfd_xcoff_stat_arch_elt (bfd *, struct stat *);
+extern bfd_boolean _bfd_xcoff_write_armap
+ (bfd *, unsigned int, struct orl *, unsigned int, int);
+extern bfd_boolean _bfd_xcoff_write_archive_contents (bfd *);
+extern int _bfd_xcoff_sizeof_headers (bfd *, struct bfd_link_info *);
+extern void _bfd_xcoff_swap_sym_in (bfd *, void *, void *);
+extern unsigned int _bfd_xcoff_swap_sym_out (bfd *, void *, void *);
+extern void _bfd_xcoff_swap_aux_in (bfd *, void *, int, int, int, int, void *);
+extern unsigned int _bfd_xcoff_swap_aux_out
+ (bfd *, void *, int, int, int, int, void *);
+static void xcoff_swap_reloc_in (bfd *, void *, void *);
+static unsigned int xcoff_swap_reloc_out (bfd *, void *, void *);
+
+/* Forward declare xcoff_rtype2howto for coffcode.h macro. */
+void xcoff_rtype2howto (arelent *, struct internal_reloc *);
+
+/* coffcode.h needs these to be defined. */
+#define RS6000COFF_C 1
+
+#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 NO_COFF_SYMBOLS
+#define RTYPE2HOWTO(cache_ptr, dst) xcoff_rtype2howto (cache_ptr, dst)
+#define coff_mkobject _bfd_xcoff_mkobject
+#define coff_bfd_is_local_label_name _bfd_xcoff_is_local_label_name
+#ifdef AIX_CORE
+extern const bfd_target * rs6000coff_core_p (bfd *abfd);
+extern bfd_boolean rs6000coff_core_file_matches_executable_p
+ (bfd *cbfd, bfd *ebfd);
+extern char *rs6000coff_core_file_failing_command (bfd *abfd);
+extern int rs6000coff_core_file_failing_signal (bfd *abfd);
+#define CORE_FILE_P rs6000coff_core_p
+#define coff_core_file_failing_command \
+ rs6000coff_core_file_failing_command
+#define coff_core_file_failing_signal \
+ rs6000coff_core_file_failing_signal
+#define coff_core_file_matches_executable_p \
+ rs6000coff_core_file_matches_executable_p
+#define coff_core_file_pid \
+ _bfd_nocore_core_file_pid
+#else
+#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
+#define coff_core_file_pid \
+ _bfd_nocore_core_file_pid
+#endif
+#define coff_SWAP_sym_in _bfd_xcoff_swap_sym_in
+#define coff_SWAP_sym_out _bfd_xcoff_swap_sym_out
+#define coff_SWAP_aux_in _bfd_xcoff_swap_aux_in
+#define coff_SWAP_aux_out _bfd_xcoff_swap_aux_out
+#define coff_swap_reloc_in xcoff_swap_reloc_in
+#define coff_swap_reloc_out xcoff_swap_reloc_out
+#define NO_COFF_RELOCS
+
+#ifndef bfd_pe_print_pdata
+#define bfd_pe_print_pdata NULL
+#endif
+
+#include <stdint.h>
+#include "coffcode.h"
+
+/* The main body of code is in coffcode.h. */
+
+static const char *normalize_filename (bfd *);
+static bfd_boolean xcoff_write_armap_old
+ (bfd *, unsigned int, struct orl *, unsigned int, int);
+static bfd_boolean xcoff_write_armap_big
+ (bfd *, unsigned int, struct orl *, unsigned int, int);
+static bfd_boolean xcoff_write_archive_contents_old (bfd *);
+static bfd_boolean xcoff_write_archive_contents_big (bfd *);
+static void xcoff_swap_ldhdr_in (bfd *, const void *, struct internal_ldhdr *);
+static void xcoff_swap_ldhdr_out (bfd *, const struct internal_ldhdr *, void *);
+static void xcoff_swap_ldsym_in (bfd *, const void *, struct internal_ldsym *);
+static void xcoff_swap_ldsym_out (bfd *, const struct internal_ldsym *, void *);
+static void xcoff_swap_ldrel_in (bfd *, const void *, struct internal_ldrel *);
+static void xcoff_swap_ldrel_out (bfd *, const struct internal_ldrel *, void *);
+static bfd_boolean xcoff_ppc_relocate_section
+ (bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
+ struct internal_reloc *, struct internal_syment *, asection **);
+static bfd_boolean _bfd_xcoff_put_ldsymbol_name
+ (bfd *, struct xcoff_loader_info *, struct internal_ldsym *, const char *);
+static asection *xcoff_create_csect_from_smclas
+ (bfd *, union internal_auxent *, const char *);
+static bfd_boolean xcoff_is_lineno_count_overflow (bfd *, bfd_vma);
+static bfd_boolean xcoff_is_reloc_count_overflow (bfd *, bfd_vma);
+static bfd_vma xcoff_loader_symbol_offset (bfd *, struct internal_ldhdr *);
+static bfd_vma xcoff_loader_reloc_offset (bfd *, struct internal_ldhdr *);
+static bfd_boolean xcoff_generate_rtinit
+ (bfd *, const char *, const char *, bfd_boolean);
+static bfd_boolean do_pad (bfd *, unsigned int);
+static bfd_boolean do_copy (bfd *, bfd *);
+
+/* Relocation functions */
+static bfd_boolean xcoff_reloc_type_br (XCOFF_RELOC_FUNCTION_ARGS);
+
+static bfd_boolean xcoff_complain_overflow_dont_func
+ (XCOFF_COMPLAIN_FUNCTION_ARGS);
+static bfd_boolean xcoff_complain_overflow_bitfield_func
+ (XCOFF_COMPLAIN_FUNCTION_ARGS);
+static bfd_boolean xcoff_complain_overflow_signed_func
+ (XCOFF_COMPLAIN_FUNCTION_ARGS);
+static bfd_boolean xcoff_complain_overflow_unsigned_func
+ (XCOFF_COMPLAIN_FUNCTION_ARGS);
+
+bfd_boolean (*xcoff_calculate_relocation[XCOFF_MAX_CALCULATE_RELOCATION])
+ (XCOFF_RELOC_FUNCTION_ARGS) =
+{
+ xcoff_reloc_type_pos, /* R_POS (0x00) */
+ xcoff_reloc_type_neg, /* R_NEG (0x01) */
+ xcoff_reloc_type_rel, /* R_REL (0x02) */
+ xcoff_reloc_type_toc, /* R_TOC (0x03) */
+ xcoff_reloc_type_fail, /* R_RTB (0x04) */
+ xcoff_reloc_type_toc, /* R_GL (0x05) */
+ xcoff_reloc_type_toc, /* R_TCL (0x06) */
+ xcoff_reloc_type_fail, /* (0x07) */
+ xcoff_reloc_type_ba, /* R_BA (0x08) */
+ xcoff_reloc_type_fail, /* (0x09) */
+ xcoff_reloc_type_br, /* R_BR (0x0a) */
+ xcoff_reloc_type_fail, /* (0x0b) */
+ xcoff_reloc_type_pos, /* R_RL (0x0c) */
+ xcoff_reloc_type_pos, /* R_RLA (0x0d) */
+ xcoff_reloc_type_fail, /* (0x0e) */
+ xcoff_reloc_type_noop, /* R_REF (0x0f) */
+ xcoff_reloc_type_fail, /* (0x10) */
+ xcoff_reloc_type_fail, /* (0x11) */
+ xcoff_reloc_type_toc, /* R_TRL (0x12) */
+ xcoff_reloc_type_toc, /* R_TRLA (0x13) */
+ xcoff_reloc_type_fail, /* R_RRTBI (0x14) */
+ xcoff_reloc_type_fail, /* R_RRTBA (0x15) */
+ xcoff_reloc_type_ba, /* R_CAI (0x16) */
+ xcoff_reloc_type_crel, /* R_CREL (0x17) */
+ xcoff_reloc_type_ba, /* R_RBA (0x18) */
+ xcoff_reloc_type_ba, /* R_RBAC (0x19) */
+ xcoff_reloc_type_br, /* R_RBR (0x1a) */
+ xcoff_reloc_type_ba, /* R_RBRC (0x1b) */
+};
+
+bfd_boolean (*xcoff_complain_overflow[XCOFF_MAX_COMPLAIN_OVERFLOW])
+ (XCOFF_COMPLAIN_FUNCTION_ARGS) =
+{
+ xcoff_complain_overflow_dont_func,
+ xcoff_complain_overflow_bitfield_func,
+ xcoff_complain_overflow_signed_func,
+ xcoff_complain_overflow_unsigned_func,
+};
+
+/* Information about one member of an archive. */
+struct member_layout {
+ /* The archive member that this structure describes. */
+ bfd *member;
+
+ /* The number of bytes of padding that must be inserted before the
+ start of the member in order to ensure that the section contents
+ are correctly aligned. */
+ unsigned int leading_padding;
+
+ /* The offset of MEMBER from the start of the archive (i.e. the end
+ of the leading padding). */
+ file_ptr offset;
+
+ /* The normalized name of MEMBER. */
+ const char *name;
+
+ /* The length of NAME, without padding. */
+ bfd_size_type namlen;
+
+ /* The length of NAME, with padding. */
+ bfd_size_type padded_namlen;
+
+ /* The size of MEMBER's header, including the name and magic sequence. */
+ bfd_size_type header_size;
+
+ /* The size of the MEMBER's contents. */
+ bfd_size_type contents_size;
+
+ /* The number of bytes of padding that must be inserted after MEMBER
+ in order to preserve even alignment. */
+ bfd_size_type trailing_padding;
+};
+
+/* A structure used for iterating over the members of an archive. */
+struct archive_iterator {
+ /* The archive itself. */
+ bfd *archive;
+
+ /* Information about the current archive member. */
+ struct member_layout current;
+
+ /* Information about the next archive member. MEMBER is null if there
+ are no more archive members, in which case OFFSET is the offset of
+ the first unused byte. */
+ struct member_layout next;
+};
+
+/* Initialize INFO so that it describes member MEMBER of archive ARCHIVE.
+ OFFSET is the even-padded offset of MEMBER, not including any leading
+ padding needed for section alignment. */
+
+static void
+member_layout_init (struct member_layout *info, bfd *archive,
+ bfd *member, file_ptr offset)
+{
+ info->member = member;
+ info->leading_padding = 0;
+ if (member)
+ {
+ info->name = normalize_filename (member);
+ info->namlen = strlen (info->name);
+ info->padded_namlen = info->namlen + (info->namlen & 1);
+ if (xcoff_big_format_p (archive))
+ info->header_size = SIZEOF_AR_HDR_BIG;
+ else
+ info->header_size = SIZEOF_AR_HDR;
+ info->header_size += info->padded_namlen + SXCOFFARFMAG;
+ info->contents_size = arelt_size (member);
+ info->trailing_padding = info->contents_size & 1;
+
+ if (bfd_check_format (member, bfd_object)
+ && bfd_get_flavour (member) == bfd_target_xcoff_flavour
+ && (member->flags & DYNAMIC) != 0)
+ info->leading_padding
+ = (-(offset + info->header_size)
+ & ((1 << bfd_xcoff_text_align_power (member)) - 1));
+ }
+ info->offset = offset + info->leading_padding;
+}
+
+/* Set up ITERATOR to iterate through archive ARCHIVE. */
+
+static void
+archive_iterator_begin (struct archive_iterator *iterator,
+ bfd *archive)
+{
+ iterator->archive = archive;
+ member_layout_init (&iterator->next, archive, archive->archive_head,
+ xcoff_big_format_p (archive)
+ ? SIZEOF_AR_FILE_HDR_BIG
+ : SIZEOF_AR_FILE_HDR);
+}
+
+/* Make ITERATOR visit the first unvisited archive member. Return true
+ on success; return false if all members have been visited. */
+
+static bfd_boolean
+archive_iterator_next (struct archive_iterator *iterator)
+{
+ if (!iterator->next.member)
+ return FALSE;
+
+ iterator->current = iterator->next;
+ member_layout_init (&iterator->next, iterator->archive,
+ iterator->current.member->archive_next,
+ iterator->current.offset
+ + iterator->current.header_size
+ + iterator->current.contents_size
+ + iterator->current.trailing_padding);
+ return TRUE;
+}
+
+/* We use our own tdata type. Its first field is the COFF tdata type,
+ so the COFF routines are compatible. */
+
+bfd_boolean
+_bfd_xcoff_mkobject (bfd *abfd)
+{
+ coff_data_type *coff;
+ bfd_size_type amt = sizeof (struct xcoff_tdata);
+
+ abfd->tdata.xcoff_obj_data = (struct xcoff_tdata *) bfd_zalloc (abfd, amt);
+ 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;
+
+ /* text section alignment is different than the default */
+ bfd_xcoff_text_align_power (abfd) = 2;
+
+ return TRUE;
+}
+
+/* Copy XCOFF data from one BFD to another. */
+
+bfd_boolean
+_bfd_xcoff_copy_private_bfd_data (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;
+ }
+ bfd_xcoff_text_align_power (obfd) = bfd_xcoff_text_align_power (ibfd);
+ bfd_xcoff_data_align_power (obfd) = bfd_xcoff_data_align_power (ibfd);
+ 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. */
+
+bfd_boolean
+_bfd_xcoff_is_local_label_name (bfd *abfd ATTRIBUTE_UNUSED,
+ const char *name ATTRIBUTE_UNUSED)
+{
+ return FALSE;
+}
+
+static const struct dwarf_debug_section xcoff_debug_sections[] =
+{
+ { ".dwabrev", NULL },
+ { ".dwarnge", NULL },
+ { NULL, NULL }, /* .debug_frame */
+ { ".dwinfo", NULL },
+ { ".dwline", NULL },
+ { NULL, NULL }, /* .debug_loc */
+ { NULL, NULL }, /* .debug_macinfo */
+ { NULL, NULL }, /* .debug_macro */
+ { ".dwpbnms", NULL },
+ { ".dwpbtyp", NULL },
+ { ".dwrnges", NULL },
+ { NULL, NULL }, /* .debug_static_func */
+ { NULL, NULL }, /* .debug_static_vars */
+ { ".dwstr", NULL },
+ { NULL, NULL }, /* .debug_types */
+ /* GNU DWARF 1 extensions */
+ { NULL, NULL }, /* .debug_sfnames */
+ { NULL, NULL }, /* .debug_srcinfo */
+ /* SGI/MIPS DWARF 2 extensions */
+ { NULL, NULL }, /* .debug_funcnames */
+ { NULL, NULL }, /* .debug_typenames */
+ { NULL, NULL }, /* .debug_varnames */
+ { NULL, NULL }, /* .debug_weaknames */
+ { NULL, NULL },
+};
+
+void
+_bfd_xcoff_swap_sym_in (bfd *abfd, void * ext1, void * in1)
+{
+ SYMENT *ext = (SYMENT *)ext1;
+ struct internal_syment * in = (struct internal_syment *)in1;
+
+ if (ext->e.e_name[0] != 0)
+ {
+ memcpy (in->_n._n_name, ext->e.e_name, SYMNMLEN);
+ }
+ else
+ {
+ in->_n._n_n._n_zeroes = 0;
+ in->_n._n_n._n_offset = H_GET_32 (abfd, ext->e.e.e_offset);
+ }
+
+ in->n_value = H_GET_32 (abfd, ext->e_value);
+ in->n_scnum = H_GET_16 (abfd, ext->e_scnum);
+ in->n_type = H_GET_16 (abfd, ext->e_type);
+ in->n_sclass = H_GET_8 (abfd, ext->e_sclass);
+ in->n_numaux = H_GET_8 (abfd, ext->e_numaux);
+}
+
+unsigned int
+_bfd_xcoff_swap_sym_out (bfd *abfd, void * inp, void * extp)
+{
+ struct internal_syment *in = (struct internal_syment *)inp;
+ SYMENT *ext =(SYMENT *)extp;
+
+ if (in->_n._n_name[0] != 0)
+ {
+ memcpy (ext->e.e_name, in->_n._n_name, SYMNMLEN);
+ }
+ else
+ {
+ H_PUT_32 (abfd, 0, ext->e.e.e_zeroes);
+ H_PUT_32 (abfd, in->_n._n_n._n_offset, ext->e.e.e_offset);
+ }
+
+ H_PUT_32 (abfd, in->n_value, ext->e_value);
+ H_PUT_16 (abfd, in->n_scnum, ext->e_scnum);
+ H_PUT_16 (abfd, in->n_type, ext->e_type);
+ H_PUT_8 (abfd, in->n_sclass, ext->e_sclass);
+ H_PUT_8 (abfd, in->n_numaux, ext->e_numaux);
+ return bfd_coff_symesz (abfd);
+}
+
+void
+_bfd_xcoff_swap_aux_in (bfd *abfd, void * ext1, int type, int in_class,
+ int indx, int numaux, void * in1)
+{
+ AUXENT * ext = (AUXENT *)ext1;
+ union internal_auxent *in = (union internal_auxent *)in1;
+
+ switch (in_class)
+ {
+ case C_FILE:
+ if (ext->x_file.x_n.x_fname[0] == 0)
+ {
+ in->x_file.x_n.x_zeroes = 0;
+ in->x_file.x_n.x_offset =
+ H_GET_32 (abfd, ext->x_file.x_n.x_n.x_offset);
+ }
+ else
+ {
+ if (numaux > 1)
+ {
+ if (indx == 0)
+ memcpy (in->x_file.x_fname, ext->x_file.x_n.x_fname,
+ numaux * sizeof (AUXENT));
+ }
+ else
+ {
+ memcpy (in->x_file.x_fname, ext->x_file.x_n.x_fname, FILNMLEN);
+ }
+ }
+ goto end;
+
+ /* RS/6000 "csect" auxents */
+ case C_EXT:
+ case C_AIX_WEAKEXT:
+ case C_HIDEXT:
+ if (indx + 1 == numaux)
+ {
+ in->x_csect.x_scnlen.l = H_GET_32 (abfd, ext->x_csect.x_scnlen);
+ in->x_csect.x_parmhash = H_GET_32 (abfd, ext->x_csect.x_parmhash);
+ in->x_csect.x_snhash = 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 = H_GET_8 (abfd, ext->x_csect.x_smtyp);
+ in->x_csect.x_smclas = H_GET_8 (abfd, ext->x_csect.x_smclas);
+ in->x_csect.x_stab = H_GET_32 (abfd, ext->x_csect.x_stab);
+ in->x_csect.x_snstab = H_GET_16 (abfd, ext->x_csect.x_snstab);
+ goto end;
+ }
+ break;
+
+ case C_STAT:
+ case C_LEAFSTAT:
+ case C_HIDDEN:
+ if (type == T_NULL)
+ {
+ in->x_scn.x_scnlen = H_GET_32 (abfd, ext->x_scn.x_scnlen);
+ in->x_scn.x_nreloc = H_GET_16 (abfd, ext->x_scn.x_nreloc);
+ in->x_scn.x_nlinno = H_GET_16 (abfd, ext->x_scn.x_nlinno);
+ /* 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 = H_GET_32 (abfd, ext->x_sym.x_tagndx);
+ in->x_sym.x_tvndx = H_GET_16 (abfd, ext->x_sym.x_tvndx);
+
+ if (in_class == C_BLOCK || in_class == C_FCN || ISFCN (type)
+ || ISTAG (in_class))
+ {
+ in->x_sym.x_fcnary.x_fcn.x_lnnoptr =
+ H_GET_32 (abfd, ext->x_sym.x_fcnary.x_fcn.x_lnnoptr);
+ in->x_sym.x_fcnary.x_fcn.x_endndx.l =
+ H_GET_32 (abfd, ext->x_sym.x_fcnary.x_fcn.x_endndx);
+ }
+ else
+ {
+ in->x_sym.x_fcnary.x_ary.x_dimen[0] =
+ H_GET_16 (abfd, ext->x_sym.x_fcnary.x_ary.x_dimen[0]);
+ in->x_sym.x_fcnary.x_ary.x_dimen[1] =
+ H_GET_16 (abfd, ext->x_sym.x_fcnary.x_ary.x_dimen[1]);
+ in->x_sym.x_fcnary.x_ary.x_dimen[2] =
+ H_GET_16 (abfd, ext->x_sym.x_fcnary.x_ary.x_dimen[2]);
+ in->x_sym.x_fcnary.x_ary.x_dimen[3] =
+ H_GET_16 (abfd, ext->x_sym.x_fcnary.x_ary.x_dimen[3]);
+ }
+
+ if (ISFCN (type))
+ {
+ in->x_sym.x_misc.x_fsize = H_GET_32 (abfd, ext->x_sym.x_misc.x_fsize);
+ }
+ else
+ {
+ in->x_sym.x_misc.x_lnsz.x_lnno =
+ H_GET_16 (abfd, ext->x_sym.x_misc.x_lnsz.x_lnno);
+ in->x_sym.x_misc.x_lnsz.x_size =
+ H_GET_16 (abfd, ext->x_sym.x_misc.x_lnsz.x_size);
+ }
+
+ end: ;
+ /* The semicolon is because MSVC doesn't like labels at
+ end of block. */
+}
+
+unsigned int
+_bfd_xcoff_swap_aux_out (bfd *abfd, void * inp, int type, int in_class,
+ int indx ATTRIBUTE_UNUSED,
+ int numaux ATTRIBUTE_UNUSED,
+ void * extp)
+{
+ union internal_auxent *in = (union internal_auxent *)inp;
+ AUXENT *ext = (AUXENT *)extp;
+
+ memset (ext, 0, bfd_coff_auxesz (abfd));
+ switch (in_class)
+ {
+ case C_FILE:
+ if (in->x_file.x_fname[0] == 0)
+ {
+ H_PUT_32 (abfd, 0, ext->x_file.x_n.x_n.x_zeroes);
+ H_PUT_32 (abfd, in->x_file.x_n.x_offset,
+ ext->x_file.x_n.x_n.x_offset);
+ }
+ else
+ {
+ memcpy (ext->x_file.x_n.x_fname, in->x_file.x_fname, FILNMLEN);
+ }
+ goto end;
+
+ /* RS/6000 "csect" auxents */
+ case C_EXT:
+ case C_AIX_WEAKEXT:
+ case C_HIDEXT:
+ if (indx + 1 == numaux)
+ {
+ H_PUT_32 (abfd, in->x_csect.x_scnlen.l, ext->x_csect.x_scnlen);
+ H_PUT_32 (abfd, in->x_csect.x_parmhash, ext->x_csect.x_parmhash);
+ H_PUT_16 (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. */
+ H_PUT_8 (abfd, in->x_csect.x_smtyp, ext->x_csect.x_smtyp);
+ H_PUT_8 (abfd, in->x_csect.x_smclas, ext->x_csect.x_smclas);
+ H_PUT_32 (abfd, in->x_csect.x_stab, ext->x_csect.x_stab);
+ H_PUT_16 (abfd, in->x_csect.x_snstab, ext->x_csect.x_snstab);
+ goto end;
+ }
+ break;
+
+ case C_STAT:
+ case C_LEAFSTAT:
+ case C_HIDDEN:
+ if (type == T_NULL)
+ {
+ H_PUT_32 (abfd, in->x_scn.x_scnlen, ext->x_scn.x_scnlen);
+ H_PUT_16 (abfd, in->x_scn.x_nreloc, ext->x_scn.x_nreloc);
+ H_PUT_16 (abfd, in->x_scn.x_nlinno, ext->x_scn.x_nlinno);
+ goto end;
+ }
+ break;
+ }
+
+ H_PUT_32 (abfd, in->x_sym.x_tagndx.l, ext->x_sym.x_tagndx);
+ H_PUT_16 (abfd, in->x_sym.x_tvndx, ext->x_sym.x_tvndx);
+
+ if (in_class == C_BLOCK || in_class == C_FCN || ISFCN (type)
+ || ISTAG (in_class))
+ {
+ H_PUT_32 (abfd, in->x_sym.x_fcnary.x_fcn.x_lnnoptr,
+ ext->x_sym.x_fcnary.x_fcn.x_lnnoptr);
+ H_PUT_32 (abfd, in->x_sym.x_fcnary.x_fcn.x_endndx.l,
+ ext->x_sym.x_fcnary.x_fcn.x_endndx);
+ }
+ else
+ {
+ H_PUT_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[0],
+ ext->x_sym.x_fcnary.x_ary.x_dimen[0]);
+ H_PUT_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[1],
+ ext->x_sym.x_fcnary.x_ary.x_dimen[1]);
+ H_PUT_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[2],
+ ext->x_sym.x_fcnary.x_ary.x_dimen[2]);
+ H_PUT_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[3],
+ ext->x_sym.x_fcnary.x_ary.x_dimen[3]);
+ }
+
+ if (ISFCN (type))
+ H_PUT_32 (abfd, in->x_sym.x_misc.x_fsize, ext->x_sym.x_misc.x_fsize);
+ else
+ {
+ H_PUT_16 (abfd, in->x_sym.x_misc.x_lnsz.x_lnno,
+ ext->x_sym.x_misc.x_lnsz.x_lnno);
+ H_PUT_16 (abfd, in->x_sym.x_misc.x_lnsz.x_size,
+ ext->x_sym.x_misc.x_lnsz.x_size);
+ }
+
+end:
+ return bfd_coff_auxesz (abfd);
+}
+
+
+
+/* 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. */
+
+
+reloc_howto_type xcoff_howto_table[] =
+{
+ /* 0x00: Standard 32 bit relocation. */
+ HOWTO (R_POS, /* 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 */
+
+ /* 0x01: 32 bit relocation, but store negative value. */
+ HOWTO (R_NEG, /* 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 */
+
+ /* 0x02: 32 bit PC relative relocation. */
+ HOWTO (R_REL, /* 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 */
+
+ /* 0x03: 16 bit TOC relative relocation. */
+ HOWTO (R_TOC, /* 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 */
+
+ /* 0x04: I don't really know what this is. */
+ HOWTO (R_RTB, /* 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 */
+
+ /* 0x05: External TOC relative symbol. */
+ HOWTO (R_GL, /* 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_GL", /* name */
+ TRUE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* 0x06: Local TOC relative symbol. */
+ HOWTO (R_TCL, /* 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_TCL", /* name */
+ TRUE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ EMPTY_HOWTO (7),
+
+ /* 0x08: Non modifiable absolute branch. */
+ HOWTO (R_BA, /* 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_26", /* name */
+ TRUE, /* partial_inplace */
+ 0x03fffffc, /* src_mask */
+ 0x03fffffc, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ EMPTY_HOWTO (9),
+
+ /* 0x0a: Non modifiable relative branch. */
+ HOWTO (R_BR, /* 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 */
+ 0x03fffffc, /* src_mask */
+ 0x03fffffc, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ EMPTY_HOWTO (0xb),
+
+ /* 0x0c: Indirect load. */
+ HOWTO (R_RL, /* 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_RL", /* name */
+ TRUE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* 0x0d: Load address. */
+ HOWTO (R_RLA, /* 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_RLA", /* name */
+ TRUE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ EMPTY_HOWTO (0xe),
+
+ /* 0x0f: Non-relocating reference. Bitsize is 1 so that r_rsize is 0. */
+ HOWTO (R_REF, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 1, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ 0, /* special_function */
+ "R_REF", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ EMPTY_HOWTO (0x10),
+ EMPTY_HOWTO (0x11),
+
+ /* 0x12: TOC relative indirect load. */
+ HOWTO (R_TRL, /* 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_TRL", /* name */
+ TRUE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* 0x13: TOC relative load address. */
+ HOWTO (R_TRLA, /* 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_TRLA", /* name */
+ TRUE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* 0x14: Modifiable relative branch. */
+ HOWTO (R_RRTBI, /* 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 */
+
+ /* 0x15: Modifiable absolute branch. */
+ HOWTO (R_RRTBA, /* 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 */
+
+ /* 0x16: Modifiable call absolute indirect. */
+ HOWTO (R_CAI, /* 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_CAI", /* name */
+ TRUE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* 0x17: Modifiable call relative. */
+ HOWTO (R_CREL, /* 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_CREL", /* name */
+ TRUE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* 0x18: Modifiable branch absolute. */
+ HOWTO (R_RBA, /* 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_RBA", /* name */
+ TRUE, /* partial_inplace */
+ 0x03fffffc, /* src_mask */
+ 0x03fffffc, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* 0x19: Modifiable branch absolute. */
+ HOWTO (R_RBAC, /* 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_RBAC", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* 0x1a: Modifiable branch relative. */
+ HOWTO (R_RBR, /* 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_26", /* name */
+ TRUE, /* partial_inplace */
+ 0x03fffffc, /* src_mask */
+ 0x03fffffc, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* 0x1b: Modifiable branch absolute. */
+ HOWTO (R_RBRC, /* 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_RBRC", /* name */
+ TRUE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* 0x1c: 16 bit Non modifiable absolute branch. */
+ HOWTO (R_BA, /* 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_BA_16", /* name */
+ TRUE, /* partial_inplace */
+ 0xfffc, /* src_mask */
+ 0xfffc, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* 0x1d: Modifiable branch relative. */
+ HOWTO (R_RBR, /* 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 */
+ "R_RBR_16", /* name */
+ TRUE, /* partial_inplace */
+ 0xfffc, /* src_mask */
+ 0xfffc, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* 0x1e: Modifiable branch relative. */
+ HOWTO (R_RBA, /* 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_RBA_16", /* name */
+ TRUE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+};
+
+void
+xcoff_rtype2howto (arelent *relent, struct internal_reloc *internal)
+{
+ if (internal->r_type > R_RBRC)
+ abort ();
+
+ /* Default howto layout works most of the time */
+ relent->howto = &xcoff_howto_table[internal->r_type];
+
+ /* Special case some 16 bit reloc */
+ if (15 == (internal->r_size & 0x1f))
+ {
+ if (R_BA == internal->r_type)
+ relent->howto = &xcoff_howto_table[0x1c];
+ else if (R_RBR == internal->r_type)
+ relent->howto = &xcoff_howto_table[0x1d];
+ else if (R_RBA == internal->r_type)
+ relent->howto = &xcoff_howto_table[0x1e];
+ }
+
+ /* 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. The bitsize is not significant
+ for R_REF relocs. */
+ if (relent->howto->dst_mask != 0
+ && (relent->howto->bitsize
+ != ((unsigned int) internal->r_size & 0x1f) + 1))
+ abort ();
+}
+
+reloc_howto_type *
+_bfd_xcoff_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ bfd_reloc_code_real_type code)
+{
+ switch (code)
+ {
+ case BFD_RELOC_PPC_B26:
+ return &xcoff_howto_table[0xa];
+ case BFD_RELOC_PPC_BA16:
+ return &xcoff_howto_table[0x1c];
+ case BFD_RELOC_PPC_BA26:
+ return &xcoff_howto_table[8];
+ case BFD_RELOC_PPC_TOC16:
+ return &xcoff_howto_table[3];
+ case BFD_RELOC_16:
+ /* Note that this relocation is only internally used by gas. */
+ return &xcoff_howto_table[0xc];
+ case BFD_RELOC_PPC_B16:
+ return &xcoff_howto_table[0x1d];
+ case BFD_RELOC_32:
+ case BFD_RELOC_CTOR:
+ return &xcoff_howto_table[0];
+ case BFD_RELOC_NONE:
+ return &xcoff_howto_table[0xf];
+ default:
+ return NULL;
+ }
+}
+
+static reloc_howto_type *
+_bfd_xcoff_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ const char *r_name)
+{
+ unsigned int i;
+
+ for (i = 0;
+ i < sizeof (xcoff_howto_table) / sizeof (xcoff_howto_table[0]);
+ i++)
+ if (xcoff_howto_table[i].name != NULL
+ && strcasecmp (xcoff_howto_table[i].name, r_name) == 0)
+ return &xcoff_howto_table[i];
+
+ return NULL;
+}
+
+/* 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.
+
+ AIX 4.3 introduced a new archive format which can handle larger
+ files and also 32- and 64-bit objects in the same archive. The
+ things said above remain true except that there is now more than
+ one global symbol table. The one is used to index 32-bit objects,
+ the other for 64-bit objects.
+
+ The new archives (recognizable by the new ARMAG string) has larger
+ field lengths so that we cannot really share any code. Also we have
+ to take care that we are not generating the new form of archives
+ on AIX 4.2 or earlier systems. */
+
+/* XCOFF archives use this as a magic string. Note that both strings
+ have the same length. */
+
+/* Set the magic for archive. */
+
+bfd_boolean
+bfd_xcoff_ar_archive_set_magic (bfd *abfd ATTRIBUTE_UNUSED,
+ char *magic ATTRIBUTE_UNUSED)
+{
+ /* Not supported yet. */
+ return FALSE;
+ /* bfd_xcoff_archive_set_magic (abfd, magic); */
+}
+
+/* Read in the armap of an XCOFF archive. */
+
+bfd_boolean
+_bfd_xcoff_slurp_armap (bfd *abfd)
+{
+ file_ptr off;
+ size_t namlen;
+ bfd_size_type sz;
+ bfd_byte *contents, *cend;
+ bfd_vma c, i;
+ carsym *arsym;
+ bfd_byte *p;
+
+ if (xcoff_ardata (abfd) == NULL)
+ {
+ bfd_has_map (abfd) = FALSE;
+ return TRUE;
+ }
+
+ if (! xcoff_big_format_p (abfd))
+ {
+ /* This is for the old format. */
+ struct xcoff_ar_hdr hdr;
+
+ 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_bread (&hdr, (bfd_size_type) SIZEOF_AR_HDR, abfd)
+ != SIZEOF_AR_HDR)
+ return FALSE;
+
+ /* Skip the name (normally empty). */
+ namlen = strtol (hdr.namlen, (char **) NULL, 10);
+ off = ((namlen + 1) & ~ (size_t) 1) + SXCOFFARFMAG;
+ if (bfd_seek (abfd, off, SEEK_CUR) != 0)
+ return FALSE;
+
+ sz = strtol (hdr.size, (char **) NULL, 10);
+
+ /* Read in the entire symbol table. */
+ contents = (bfd_byte *) bfd_alloc (abfd, sz);
+ if (contents == NULL)
+ return FALSE;
+ if (bfd_bread (contents, sz, abfd) != sz)
+ return FALSE;
+
+ /* The symbol table starts with a four byte count. */
+ c = 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 = H_GET_32 (abfd, p);
+ }
+ else
+ {
+ /* This is for the new format. */
+ struct xcoff_ar_hdr_big hdr;
+
+ off = strtol (xcoff_ardata_big (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_bread (&hdr, (bfd_size_type) SIZEOF_AR_HDR_BIG, abfd)
+ != SIZEOF_AR_HDR_BIG)
+ return FALSE;
+
+ /* Skip the name (normally empty). */
+ namlen = strtol (hdr.namlen, (char **) NULL, 10);
+ off = ((namlen + 1) & ~ (size_t) 1) + SXCOFFARFMAG;
+ if (bfd_seek (abfd, off, SEEK_CUR) != 0)
+ return FALSE;
+
+ /* XXX This actually has to be a call to strtoll (at least on 32-bit
+ machines) since the field width is 20 and there numbers with more
+ than 32 bits can be represented. */
+ sz = strtol (hdr.size, (char **) NULL, 10);
+
+ /* Read in the entire symbol table. */
+ contents = (bfd_byte *) bfd_alloc (abfd, sz);
+ if (contents == NULL)
+ return FALSE;
+ if (bfd_bread (contents, sz, abfd) != sz)
+ return FALSE;
+
+ /* The symbol table starts with an eight byte count. */
+ c = H_GET_64 (abfd, contents);
+
+ if (c * 8 >= 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 eight byte file offsets. */
+ for (i = 0, arsym = bfd_ardata (abfd)->symdefs, p = contents + 8;
+ i < c;
+ ++i, ++arsym, p += 8)
+ arsym->file_offset = H_GET_64 (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. */
+
+const bfd_target *
+_bfd_xcoff_archive_p (bfd *abfd)
+{
+ struct artdata *tdata_hold;
+ char magic[SXCOFFARMAG];
+ bfd_size_type amt = SXCOFFARMAG;
+
+ if (bfd_bread (magic, amt, abfd) != amt)
+ {
+ if (bfd_get_error () != bfd_error_system_call)
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+
+ if (strncmp (magic, XCOFFARMAG, SXCOFFARMAG) != 0
+ && strncmp (magic, XCOFFARMAGBIG, SXCOFFARMAG) != 0)
+ {
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+
+ tdata_hold = bfd_ardata (abfd);
+
+ amt = sizeof (struct artdata);
+ bfd_ardata (abfd) = (struct artdata *) bfd_zalloc (abfd, amt);
+ if (bfd_ardata (abfd) == (struct artdata *) NULL)
+ goto error_ret_restore;
+
+ /* Cleared by bfd_zalloc above.
+ 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)->extended_names_size = 0; */
+
+ /* Now handle the two formats. */
+ if (magic[1] != 'b')
+ {
+ /* This is the old format. */
+ struct xcoff_ar_file_hdr hdr;
+
+ /* Copy over the magic string. */
+ memcpy (hdr.magic, magic, SXCOFFARMAG);
+
+ /* Now read the rest of the file header. */
+ amt = SIZEOF_AR_FILE_HDR - SXCOFFARMAG;
+ if (bfd_bread (&hdr.memoff, amt, abfd) != amt)
+ {
+ if (bfd_get_error () != bfd_error_system_call)
+ bfd_set_error (bfd_error_wrong_format);
+ goto error_ret;
+ }
+
+ bfd_ardata (abfd)->first_file_filepos = strtol (hdr.firstmemoff,
+ (char **) NULL, 10);
+
+ amt = SIZEOF_AR_FILE_HDR;
+ bfd_ardata (abfd)->tdata = bfd_zalloc (abfd, amt);
+ if (bfd_ardata (abfd)->tdata == NULL)
+ goto error_ret;
+
+ memcpy (bfd_ardata (abfd)->tdata, &hdr, SIZEOF_AR_FILE_HDR);
+ }
+ else
+ {
+ /* This is the new format. */
+ struct xcoff_ar_file_hdr_big hdr;
+
+ /* Copy over the magic string. */
+ memcpy (hdr.magic, magic, SXCOFFARMAG);
+
+ /* Now read the rest of the file header. */
+ amt = SIZEOF_AR_FILE_HDR_BIG - SXCOFFARMAG;
+ if (bfd_bread (&hdr.memoff, amt, abfd) != amt)
+ {
+ if (bfd_get_error () != bfd_error_system_call)
+ bfd_set_error (bfd_error_wrong_format);
+ goto error_ret;
+ }
+
+ bfd_ardata (abfd)->first_file_filepos = bfd_scan_vma (hdr.firstmemoff,
+ (const char **) 0,
+ 10);
+
+ amt = SIZEOF_AR_FILE_HDR_BIG;
+ bfd_ardata (abfd)->tdata = bfd_zalloc (abfd, amt);
+ if (bfd_ardata (abfd)->tdata == NULL)
+ goto error_ret;
+
+ memcpy (bfd_ardata (abfd)->tdata, &hdr, SIZEOF_AR_FILE_HDR_BIG);
+ }
+
+ if (! _bfd_xcoff_slurp_armap (abfd))
+ {
+ error_ret:
+ bfd_release (abfd, bfd_ardata (abfd));
+ error_ret_restore:
+ bfd_ardata (abfd) = tdata_hold;
+ return NULL;
+ }
+
+ return abfd->xvec;
+}
+
+/* Read the archive header in an XCOFF archive. */
+
+void *
+_bfd_xcoff_read_ar_hdr (bfd *abfd)
+{
+ bfd_size_type namlen;
+ struct areltdata *ret;
+ bfd_size_type amt = sizeof (struct areltdata);
+
+ ret = (struct areltdata *) bfd_zmalloc (amt);
+ if (ret == NULL)
+ return NULL;
+
+ if (! xcoff_big_format_p (abfd))
+ {
+ struct xcoff_ar_hdr hdr;
+ struct xcoff_ar_hdr *hdrp;
+
+ if (bfd_bread (&hdr, (bfd_size_type) SIZEOF_AR_HDR, abfd)
+ != SIZEOF_AR_HDR)
+ {
+ free (ret);
+ return NULL;
+ }
+
+ namlen = strtol (hdr.namlen, (char **) NULL, 10);
+ amt = SIZEOF_AR_HDR + namlen + 1;
+ hdrp = (struct xcoff_ar_hdr *) bfd_alloc (abfd, amt);
+ if (hdrp == NULL)
+ {
+ free (ret);
+ return NULL;
+ }
+ memcpy (hdrp, &hdr, SIZEOF_AR_HDR);
+ if (bfd_bread ((char *) hdrp + SIZEOF_AR_HDR, namlen, abfd) != namlen)
+ {
+ free (ret);
+ return NULL;
+ }
+ ((char *) hdrp)[SIZEOF_AR_HDR + namlen] = '\0';
+
+ ret->arch_header = (char *) hdrp;
+ ret->parsed_size = strtol (hdr.size, (char **) NULL, 10);
+ ret->filename = (char *) hdrp + SIZEOF_AR_HDR;
+ }
+ else
+ {
+ struct xcoff_ar_hdr_big hdr;
+ struct xcoff_ar_hdr_big *hdrp;
+
+ if (bfd_bread (&hdr, (bfd_size_type) SIZEOF_AR_HDR_BIG, abfd)
+ != SIZEOF_AR_HDR_BIG)
+ {
+ free (ret);
+ return NULL;
+ }
+
+ namlen = strtol (hdr.namlen, (char **) NULL, 10);
+ amt = SIZEOF_AR_HDR_BIG + namlen + 1;
+ hdrp = (struct xcoff_ar_hdr_big *) bfd_alloc (abfd, amt);
+ if (hdrp == NULL)
+ {
+ free (ret);
+ return NULL;
+ }
+ memcpy (hdrp, &hdr, SIZEOF_AR_HDR_BIG);
+ if (bfd_bread ((char *) hdrp + SIZEOF_AR_HDR_BIG, namlen, abfd) != namlen)
+ {
+ free (ret);
+ return NULL;
+ }
+ ((char *) hdrp)[SIZEOF_AR_HDR_BIG + namlen] = '\0';
+
+ ret->arch_header = (char *) hdrp;
+ /* XXX This actually has to be a call to strtoll (at least on 32-bit
+ machines) since the field width is 20 and there numbers with more
+ than 32 bits can be represented. */
+ ret->parsed_size = strtol (hdr.size, (char **) NULL, 10);
+ ret->filename = (char *) hdrp + SIZEOF_AR_HDR_BIG;
+ }
+
+ /* Skip over the XCOFFARFMAG at the end of the file name. */
+ if (bfd_seek (abfd, (file_ptr) ((namlen & 1) + SXCOFFARFMAG), SEEK_CUR) != 0)
+ return NULL;
+
+ return ret;
+}
+
+/* Open the next element in an XCOFF archive. */
+
+bfd *
+_bfd_xcoff_openr_next_archived_file (bfd *archive, bfd *last_file)
+{
+ file_ptr filestart;
+
+ if (xcoff_ardata (archive) == NULL)
+ {
+ bfd_set_error (bfd_error_invalid_operation);
+ return NULL;
+ }
+
+ if (! xcoff_big_format_p (archive))
+ {
+ 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;
+ }
+ }
+ else
+ {
+ if (last_file == NULL)
+ filestart = bfd_ardata (archive)->first_file_filepos;
+ else
+ /* XXX These actually have to be a calls to strtoll (at least
+ on 32-bit machines) since the fields's width is 20 and
+ there numbers with more than 32 bits can be represented. */
+ filestart = strtol (arch_xhdr_big (last_file)->nextoff, (char **) NULL,
+ 10);
+
+ /* XXX These actually have to be calls to strtoll (at least on 32-bit
+ machines) since the fields's width is 20 and there numbers with more
+ than 32 bits can be represented. */
+ if (filestart == 0
+ || filestart == strtol (xcoff_ardata_big (archive)->memoff,
+ (char **) NULL, 10)
+ || filestart == strtol (xcoff_ardata_big (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. */
+
+int
+_bfd_xcoff_stat_arch_elt (bfd *abfd, struct stat *s)
+{
+ if (abfd->arelt_data == NULL)
+ {
+ bfd_set_error (bfd_error_invalid_operation);
+ return -1;
+ }
+
+ if (! xcoff_big_format_p (abfd->my_archive))
+ {
+ struct xcoff_ar_hdr *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;
+ }
+ else
+ {
+ struct xcoff_ar_hdr_big *hdrp = arch_xhdr_big (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 (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. */
+
+static bfd_boolean
+xcoff_write_armap_old (bfd *abfd, unsigned int elength ATTRIBUTE_UNUSED,
+ struct orl *map, unsigned int orl_count, int stridx)
+{
+ struct archive_iterator iterator;
+ struct xcoff_ar_hdr hdr;
+ char *p;
+ unsigned char buf[4];
+ 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, XCOFFARMAG_ELEMENT_SIZE);
+ 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_bwrite (&hdr, (bfd_size_type) SIZEOF_AR_HDR, abfd)
+ != SIZEOF_AR_HDR
+ || (bfd_bwrite (XCOFFARFMAG, (bfd_size_type) SXCOFFARFMAG, abfd)
+ != SXCOFFARFMAG))
+ return FALSE;
+
+ H_PUT_32 (abfd, orl_count, buf);
+ if (bfd_bwrite (buf, (bfd_size_type) 4, abfd) != 4)
+ return FALSE;
+
+ i = 0;
+ archive_iterator_begin (&iterator, abfd);
+ while (i < orl_count && archive_iterator_next (&iterator))
+ while (map[i].u.abfd == iterator.current.member)
+ {
+ H_PUT_32 (abfd, iterator.current.offset, buf);
+ if (bfd_bwrite (buf, (bfd_size_type) 4, abfd) != 4)
+ return FALSE;
+ ++i;
+ }
+
+ for (i = 0; i < orl_count; i++)
+ {
+ const char *name;
+ size_t namlen;
+
+ name = *map[i].name;
+ namlen = strlen (name);
+ if (bfd_bwrite (name, (bfd_size_type) (namlen + 1), abfd) != namlen + 1)
+ return FALSE;
+ }
+
+ if ((stridx & 1) != 0)
+ {
+ char b;
+
+ b = '\0';
+ if (bfd_bwrite (&b, (bfd_size_type) 1, abfd) != 1)
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static char buff20[XCOFFARMAGBIG_ELEMENT_SIZE + 1];
+#define FMT20 "%-20lld"
+#define FMT12 "%-12d"
+#define FMT12_OCTAL "%-12o"
+#define FMT4 "%-4d"
+#define PRINT20(d, v) \
+ sprintf (buff20, FMT20, (long long)(v)), \
+ memcpy ((void *) (d), buff20, 20)
+
+#define PRINT12(d, v) \
+ sprintf (buff20, FMT12, (int)(v)), \
+ memcpy ((void *) (d), buff20, 12)
+
+#define PRINT12_OCTAL(d, v) \
+ sprintf (buff20, FMT12_OCTAL, (unsigned int)(v)), \
+ memcpy ((void *) (d), buff20, 12)
+
+#define PRINT4(d, v) \
+ sprintf (buff20, FMT4, (int)(v)), \
+ memcpy ((void *) (d), buff20, 4)
+
+#define READ20(d, v) \
+ buff20[20] = 0, \
+ memcpy (buff20, (d), 20), \
+ (v) = bfd_scan_vma (buff20, (const char **) NULL, 10)
+
+static bfd_boolean
+do_pad (bfd *abfd, unsigned int number)
+{
+ bfd_byte b = 0;
+
+ /* Limit pad to <= 4096. */
+ if (number > 4096)
+ return FALSE;
+
+ while (number--)
+ if (bfd_bwrite (&b, (bfd_size_type) 1, abfd) != 1)
+ return FALSE;
+
+ return TRUE;
+}
+
+static bfd_boolean
+do_copy (bfd *out_bfd, bfd *in_bfd)
+{
+ bfd_size_type remaining;
+ bfd_byte buffer[DEFAULT_BUFFERSIZE];
+
+ if (bfd_seek (in_bfd, (file_ptr) 0, SEEK_SET) != 0)
+ return FALSE;
+
+ remaining = arelt_size (in_bfd);
+
+ while (remaining >= DEFAULT_BUFFERSIZE)
+ {
+ if (bfd_bread (buffer, DEFAULT_BUFFERSIZE, in_bfd) != DEFAULT_BUFFERSIZE
+ || bfd_bwrite (buffer, DEFAULT_BUFFERSIZE, out_bfd) != DEFAULT_BUFFERSIZE)
+ return FALSE;
+
+ remaining -= DEFAULT_BUFFERSIZE;
+ }
+
+ if (remaining)
+ {
+ if (bfd_bread (buffer, remaining, in_bfd) != remaining
+ || bfd_bwrite (buffer, remaining, out_bfd) != remaining)
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static bfd_boolean
+xcoff_write_armap_big (bfd *abfd, unsigned int elength ATTRIBUTE_UNUSED,
+ struct orl *map, unsigned int orl_count, int stridx)
+{
+ struct archive_iterator iterator;
+ struct xcoff_ar_file_hdr_big *fhdr;
+ bfd_vma i, sym_32, sym_64, str_32, str_64;
+ const bfd_arch_info_type *arch_info;
+ bfd *current_bfd;
+ size_t string_length;
+ file_ptr nextoff, prevoff;
+
+ /* First, we look through the symbols and work out which are
+ from 32-bit objects and which from 64-bit ones. */
+ sym_32 = sym_64 = str_32 = str_64 = 0;
+
+ i = 0;
+ for (current_bfd = abfd->archive_head;
+ current_bfd != NULL && i < orl_count;
+ current_bfd = current_bfd->archive_next)
+ {
+ arch_info = bfd_get_arch_info (current_bfd);
+ while (map[i].u.abfd == current_bfd)
+ {
+ string_length = strlen (*map[i].name) + 1;
+ if (arch_info->bits_per_address == 64)
+ {
+ sym_64++;
+ str_64 += string_length;
+ }
+ else
+ {
+ sym_32++;
+ str_32 += string_length;
+ }
+ i++;
+ }
+ }
+
+ /* A quick sanity check... */
+ BFD_ASSERT (sym_64 + sym_32 == orl_count);
+ /* Explicit cast to int for compiler. */
+ BFD_ASSERT ((int)(str_64 + str_32) == stridx);
+
+ fhdr = xcoff_ardata_big (abfd);
+
+ /* xcoff_write_archive_contents_big passes nextoff in symoff. */
+ READ20 (fhdr->memoff, prevoff);
+ READ20 (fhdr->symoff, nextoff);
+
+ BFD_ASSERT (nextoff == bfd_tell (abfd));
+
+ /* Write out the symbol table.
+ Layout :
+
+ standard big archive header
+ 0x0000 ar_size [0x14]
+ 0x0014 ar_nxtmem [0x14]
+ 0x0028 ar_prvmem [0x14]
+ 0x003C ar_date [0x0C]
+ 0x0048 ar_uid [0x0C]
+ 0x0054 ar_gid [0x0C]
+ 0x0060 ar_mod [0x0C]
+ 0x006C ar_namelen[0x04]
+ 0x0070 ar_fmag [SXCOFFARFMAG]
+
+ Symbol table
+ 0x0072 num_syms [0x08], binary
+ 0x0078 offsets [0x08 * num_syms], binary
+ 0x0086 + 0x08 * num_syms names [??]
+ ?? pad to even bytes.
+ */
+
+ if (sym_32)
+ {
+ struct xcoff_ar_hdr_big *hdr;
+ char *symbol_table;
+ char *st;
+
+ bfd_vma symbol_table_size =
+ SIZEOF_AR_HDR_BIG
+ + SXCOFFARFMAG
+ + 8
+ + 8 * sym_32
+ + str_32 + (str_32 & 1);
+
+ symbol_table = bfd_zmalloc (symbol_table_size);
+ if (symbol_table == NULL)
+ return FALSE;
+
+ hdr = (struct xcoff_ar_hdr_big *) symbol_table;
+
+ PRINT20 (hdr->size, 8 + 8 * sym_32 + str_32 + (str_32 & 1));
+
+ if (sym_64)
+ PRINT20 (hdr->nextoff, nextoff + symbol_table_size);
+ else
+ PRINT20 (hdr->nextoff, 0);
+
+ PRINT20 (hdr->prevoff, prevoff);
+ PRINT12 (hdr->date, 0);
+ PRINT12 (hdr->uid, 0);
+ PRINT12 (hdr->gid, 0);
+ PRINT12 (hdr->mode, 0);
+ PRINT4 (hdr->namlen, 0) ;
+
+ st = symbol_table + SIZEOF_AR_HDR_BIG;
+ memcpy (st, XCOFFARFMAG, SXCOFFARFMAG);
+ st += SXCOFFARFMAG;
+
+ bfd_h_put_64 (abfd, sym_32, st);
+ st += 8;
+
+ /* loop over the 32 bit offsets */
+ i = 0;
+ archive_iterator_begin (&iterator, abfd);
+ while (i < orl_count && archive_iterator_next (&iterator))
+ {
+ arch_info = bfd_get_arch_info (iterator.current.member);
+ while (map[i].u.abfd == iterator.current.member)
+ {
+ if (arch_info->bits_per_address == 32)
+ {
+ bfd_h_put_64 (abfd, iterator.current.offset, st);
+ st += 8;
+ }
+ i++;
+ }
+ }
+
+ /* loop over the 32 bit symbol names */
+ i = 0;
+ for (current_bfd = abfd->archive_head;
+ current_bfd != NULL && i < orl_count;
+ current_bfd = current_bfd->archive_next)
+ {
+ arch_info = bfd_get_arch_info (current_bfd);
+ while (map[i].u.abfd == current_bfd)
+ {
+ if (arch_info->bits_per_address == 32)
+ {
+ string_length = sprintf (st, "%s", *map[i].name);
+ st += string_length + 1;
+ }
+ i++;
+ }
+ }
+
+ bfd_bwrite (symbol_table, symbol_table_size, abfd);
+
+ free (symbol_table);
+
+ prevoff = nextoff;
+ nextoff = nextoff + symbol_table_size;
+ }
+ else
+ PRINT20 (fhdr->symoff, 0);
+
+ if (sym_64)
+ {
+ struct xcoff_ar_hdr_big *hdr;
+ char *symbol_table;
+ char *st;
+
+ bfd_vma symbol_table_size =
+ SIZEOF_AR_HDR_BIG
+ + SXCOFFARFMAG
+ + 8
+ + 8 * sym_64
+ + str_64 + (str_64 & 1);
+
+ symbol_table = bfd_zmalloc (symbol_table_size);
+ if (symbol_table == NULL)
+ return FALSE;
+
+ hdr = (struct xcoff_ar_hdr_big *) symbol_table;
+
+ PRINT20 (hdr->size, 8 + 8 * sym_64 + str_64 + (str_64 & 1));
+ PRINT20 (hdr->nextoff, 0);
+ PRINT20 (hdr->prevoff, prevoff);
+ PRINT12 (hdr->date, 0);
+ PRINT12 (hdr->uid, 0);
+ PRINT12 (hdr->gid, 0);
+ PRINT12 (hdr->mode, 0);
+ PRINT4 (hdr->namlen, 0);
+
+ st = symbol_table + SIZEOF_AR_HDR_BIG;
+ memcpy (st, XCOFFARFMAG, SXCOFFARFMAG);
+ st += SXCOFFARFMAG;
+
+ bfd_h_put_64 (abfd, sym_64, st);
+ st += 8;
+
+ /* loop over the 64 bit offsets */
+ i = 0;
+ archive_iterator_begin (&iterator, abfd);
+ while (i < orl_count && archive_iterator_next (&iterator))
+ {
+ arch_info = bfd_get_arch_info (iterator.current.member);
+ while (map[i].u.abfd == iterator.current.member)
+ {
+ if (arch_info->bits_per_address == 64)
+ {
+ bfd_h_put_64 (abfd, iterator.current.offset, st);
+ st += 8;
+ }
+ i++;
+ }
+ }
+
+ /* loop over the 64 bit symbol names */
+ i = 0;
+ for (current_bfd = abfd->archive_head;
+ current_bfd != NULL && i < orl_count;
+ current_bfd = current_bfd->archive_next)
+ {
+ arch_info = bfd_get_arch_info (current_bfd);
+ while (map[i].u.abfd == current_bfd)
+ {
+ if (arch_info->bits_per_address == 64)
+ {
+ string_length = sprintf (st, "%s", *map[i].name);
+ st += string_length + 1;
+ }
+ i++;
+ }
+ }
+
+ bfd_bwrite (symbol_table, symbol_table_size, abfd);
+
+ free (symbol_table);
+
+ PRINT20 (fhdr->symoff64, nextoff);
+ }
+ else
+ PRINT20 (fhdr->symoff64, 0);
+
+ return TRUE;
+}
+
+bfd_boolean
+_bfd_xcoff_write_armap (bfd *abfd, unsigned int elength ATTRIBUTE_UNUSED,
+ struct orl *map, unsigned int orl_count, int stridx)
+{
+ if (! xcoff_big_format_p (abfd))
+ return xcoff_write_armap_old (abfd, elength, map, orl_count, stridx);
+ else
+ return xcoff_write_armap_big (abfd, elength, map, orl_count, stridx);
+}
+
+/* Write out an XCOFF archive. We always write an entire archive,
+ rather than fussing with the freelist and so forth. */
+
+static bfd_boolean
+xcoff_write_archive_contents_old (bfd *abfd)
+{
+ struct archive_iterator iterator;
+ struct xcoff_ar_file_hdr fhdr;
+ bfd_size_type count;
+ bfd_size_type total_namlen;
+ file_ptr *offsets;
+ bfd_boolean makemap;
+ bfd_boolean hasobjects;
+ file_ptr prevoff, nextoff;
+ bfd *sub;
+ size_t i;
+ struct xcoff_ar_hdr ahdr;
+ bfd_size_type size;
+ char *p;
+ char decbuf[XCOFFARMAG_ELEMENT_SIZE + 1];
+
+ memset (&fhdr, 0, sizeof fhdr);
+ (void) 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->archive_next)
+ {
+ ++count;
+ total_namlen += strlen (normalize_filename (sub)) + 1;
+ if (sub->arelt_data == NULL)
+ {
+ sub->arelt_data = bfd_zmalloc (sizeof (struct areltdata));
+ if (sub->arelt_data == NULL)
+ return FALSE;
+ }
+ if (arch_xhdr (sub) == NULL)
+ {
+ struct xcoff_ar_hdr *ahdrp;
+ struct stat s;
+
+ if (stat (bfd_get_filename (sub), &s) != 0)
+ {
+ bfd_set_error (bfd_error_system_call);
+ return FALSE;
+ }
+
+ ahdrp = bfd_zalloc (sub, sizeof (*ahdrp));
+ if (ahdrp == NULL)
+ 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);
+
+ arch_eltdata (sub)->arch_header = (char *) ahdrp;
+ arch_eltdata (sub)->parsed_size = s.st_size;
+ }
+ }
+ offsets = (file_ptr *) bfd_alloc (abfd, count * sizeof (file_ptr));
+ if (offsets == NULL)
+ return FALSE;
+
+ if (bfd_seek (abfd, (file_ptr) SIZEOF_AR_FILE_HDR, SEEK_SET) != 0)
+ return FALSE;
+
+ makemap = bfd_has_map (abfd);
+ hasobjects = FALSE;
+ prevoff = 0;
+ for (archive_iterator_begin (&iterator, abfd), i = 0;
+ archive_iterator_next (&iterator);
+ i++)
+ {
+ bfd_size_type namlen;
+ struct xcoff_ar_hdr *ahdrp;
+
+ if (makemap && ! hasobjects)
+ {
+ if (bfd_check_format (iterator.current.member, bfd_object))
+ hasobjects = TRUE;
+ }
+
+ ahdrp = arch_xhdr (iterator.current.member);
+ sprintf (ahdrp->prevoff, "%ld", (long) prevoff);
+ sprintf (ahdrp->namlen, "%ld", (long) iterator.current.namlen);
+ sprintf (ahdrp->nextoff, "%ld", (long) iterator.next.offset);
+
+ /* 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 (!do_pad (abfd, iterator.current.leading_padding))
+ return FALSE;
+
+ BFD_ASSERT (iterator.current.offset == bfd_tell (abfd));
+ namlen = iterator.current.padded_namlen;
+ if (bfd_bwrite (ahdrp, SIZEOF_AR_HDR, abfd) != SIZEOF_AR_HDR
+ || bfd_bwrite (iterator.current.name, namlen, abfd) != namlen
+ || bfd_bwrite (XCOFFARFMAG, SXCOFFARFMAG, abfd) != SXCOFFARFMAG
+ || bfd_seek (iterator.current.member, 0, SEEK_SET) != 0
+ || !do_copy (abfd, iterator.current.member)
+ || !do_pad (abfd, iterator.current.trailing_padding))
+ return FALSE;
+
+ offsets[i] = iterator.current.offset;
+ prevoff = iterator.current.offset;
+ }
+
+ sprintf (fhdr.lastmemoff, "%ld", (long) prevoff);
+
+ /* Write out the member table. */
+
+ nextoff = iterator.next.offset;
+ BFD_ASSERT (nextoff == bfd_tell (abfd));
+ sprintf (fhdr.memoff, "%ld", (long) nextoff);
+
+ memset (&ahdr, 0, sizeof ahdr);
+ sprintf (ahdr.size, "%ld", (long) (XCOFFARMAG_ELEMENT_SIZE
+ + count * XCOFFARMAG_ELEMENT_SIZE
+ + 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
+ + XCOFFARMAG_ELEMENT_SIZE
+ + count * XCOFFARMAG_ELEMENT_SIZE
+ + 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_bwrite (&ahdr, (bfd_size_type) SIZEOF_AR_HDR, abfd)
+ != SIZEOF_AR_HDR)
+ || (bfd_bwrite (XCOFFARFMAG, (bfd_size_type) SXCOFFARFMAG, abfd)
+ != SXCOFFARFMAG))
+ return FALSE;
+
+ sprintf (decbuf, "%-12ld", (long) count);
+ if (bfd_bwrite (decbuf, (bfd_size_type) XCOFFARMAG_ELEMENT_SIZE, abfd)
+ != XCOFFARMAG_ELEMENT_SIZE)
+ return FALSE;
+ for (i = 0; i < (size_t) count; i++)
+ {
+ sprintf (decbuf, "%-12ld", (long) offsets[i]);
+ if (bfd_bwrite (decbuf, (bfd_size_type) XCOFFARMAG_ELEMENT_SIZE,
+ abfd) != XCOFFARMAG_ELEMENT_SIZE)
+ return FALSE;
+ }
+ for (sub = abfd->archive_head; sub != NULL; sub = sub->archive_next)
+ {
+ const char *name;
+ bfd_size_type namlen;
+
+ name = normalize_filename (sub);
+ namlen = strlen (name);
+ if (bfd_bwrite (name, namlen + 1, abfd) != namlen + 1)
+ return FALSE;
+ }
+
+ if (! do_pad (abfd, size & 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 = &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_bwrite (&fhdr, (bfd_size_type) SIZEOF_AR_FILE_HDR, abfd)
+ != SIZEOF_AR_FILE_HDR))
+ return FALSE;
+
+ return TRUE;
+}
+
+static bfd_boolean
+xcoff_write_archive_contents_big (bfd *abfd)
+{
+ struct xcoff_ar_file_hdr_big fhdr;
+ bfd_size_type count;
+ bfd_size_type total_namlen;
+ file_ptr *offsets;
+ bfd_boolean makemap;
+ bfd_boolean hasobjects;
+ file_ptr prevoff, nextoff;
+ bfd *current_bfd;
+ size_t i;
+ struct xcoff_ar_hdr_big *hdr;
+ bfd_size_type size;
+ char *member_table, *mt;
+ bfd_vma member_table_size;
+ struct archive_iterator iterator;
+
+ memset (&fhdr, 0, SIZEOF_AR_FILE_HDR_BIG);
+ memcpy (fhdr.magic, XCOFFARMAGBIG, SXCOFFARMAG);
+
+ if (bfd_seek (abfd, (file_ptr) SIZEOF_AR_FILE_HDR_BIG, SEEK_SET) != 0)
+ return FALSE;
+
+ /* Calculate count and total_namlen. */
+ makemap = bfd_has_map (abfd);
+ hasobjects = FALSE;
+ for (current_bfd = abfd->archive_head, count = 0, total_namlen = 0;
+ current_bfd != NULL;
+ current_bfd = current_bfd->archive_next, count++)
+ {
+ total_namlen += strlen (normalize_filename (current_bfd)) + 1;
+
+ if (makemap
+ && ! hasobjects
+ && bfd_check_format (current_bfd, bfd_object))
+ hasobjects = TRUE;
+
+ if (current_bfd->arelt_data == NULL)
+ {
+ size = sizeof (struct areltdata);
+ current_bfd->arelt_data = bfd_zmalloc (size);
+ if (current_bfd->arelt_data == NULL)
+ return FALSE;
+ }
+
+ if (arch_xhdr_big (current_bfd) == NULL)
+ {
+ struct xcoff_ar_hdr_big *ahdrp;
+ struct stat s;
+
+ /* XXX This should actually be a call to stat64 (at least on
+ 32-bit machines).
+ XXX This call will fail if the original object is not found. */
+ if (stat (bfd_get_filename (current_bfd), &s) != 0)
+ {
+ bfd_set_error (bfd_error_system_call);
+ return FALSE;
+ }
+
+ ahdrp = bfd_zalloc (current_bfd, sizeof (*ahdrp));
+ if (ahdrp == NULL)
+ return FALSE;
+
+ PRINT20 (ahdrp->size, s.st_size);
+ PRINT12 (ahdrp->date, s.st_mtime);
+ PRINT12 (ahdrp->uid, s.st_uid);
+ PRINT12 (ahdrp->gid, s.st_gid);
+ PRINT12_OCTAL (ahdrp->mode, s.st_mode);
+
+ arch_eltdata (current_bfd)->arch_header = (char *) ahdrp;
+ arch_eltdata (current_bfd)->parsed_size = s.st_size;
+ }
+ }
+
+ offsets = NULL;
+ if (count)
+ {
+ offsets = (file_ptr *) bfd_malloc (count * sizeof (file_ptr));
+ if (offsets == NULL)
+ return FALSE;
+ }
+
+ prevoff = 0;
+ for (archive_iterator_begin (&iterator, abfd), i = 0;
+ archive_iterator_next (&iterator);
+ i++)
+ {
+ bfd_size_type namlen;
+ struct xcoff_ar_hdr_big *ahdrp;
+
+ ahdrp = arch_xhdr_big (iterator.current.member);
+ PRINT20 (ahdrp->prevoff, prevoff);
+ PRINT4 (ahdrp->namlen, iterator.current.namlen);
+ PRINT20 (ahdrp->nextoff, iterator.next.offset);
+
+ if (!do_pad (abfd, iterator.current.leading_padding))
+ {
+ free (offsets);
+ return FALSE;
+ }
+
+ BFD_ASSERT (iterator.current.offset == bfd_tell (abfd));
+ namlen = iterator.current.padded_namlen;
+ if (bfd_bwrite (ahdrp, SIZEOF_AR_HDR_BIG, abfd) != SIZEOF_AR_HDR_BIG
+ || bfd_bwrite (iterator.current.name, namlen, abfd) != namlen
+ || bfd_bwrite (XCOFFARFMAG, SXCOFFARFMAG, abfd) != SXCOFFARFMAG
+ || bfd_seek (iterator.current.member, 0, SEEK_SET) != 0
+ || !do_copy (abfd, iterator.current.member)
+ || !do_pad (abfd, iterator.current.trailing_padding))
+ {
+ free (offsets);
+ return FALSE;
+ }
+
+ offsets[i] = iterator.current.offset;
+ prevoff = iterator.current.offset;
+ }
+
+ if (count)
+ {
+ PRINT20 (fhdr.firstmemoff, offsets[0]);
+ PRINT20 (fhdr.lastmemoff, prevoff);
+ }
+
+ /* Write out the member table.
+ Layout :
+
+ standard big archive header
+ 0x0000 ar_size [0x14]
+ 0x0014 ar_nxtmem [0x14]
+ 0x0028 ar_prvmem [0x14]
+ 0x003C ar_date [0x0C]
+ 0x0048 ar_uid [0x0C]
+ 0x0054 ar_gid [0x0C]
+ 0x0060 ar_mod [0x0C]
+ 0x006C ar_namelen[0x04]
+ 0x0070 ar_fmag [0x02]
+
+ Member table
+ 0x0072 count [0x14]
+ 0x0086 offsets [0x14 * counts]
+ 0x0086 + 0x14 * counts names [??]
+ ?? pad to even bytes.
+ */
+
+ nextoff = iterator.next.offset;
+ BFD_ASSERT (nextoff == bfd_tell (abfd));
+
+ member_table_size = (SIZEOF_AR_HDR_BIG
+ + SXCOFFARFMAG
+ + XCOFFARMAGBIG_ELEMENT_SIZE
+ + count * XCOFFARMAGBIG_ELEMENT_SIZE
+ + total_namlen);
+
+ member_table_size += member_table_size & 1;
+ member_table = bfd_zmalloc (member_table_size);
+ if (member_table == NULL)
+ {
+ free (offsets);
+ return FALSE;
+ }
+
+ hdr = (struct xcoff_ar_hdr_big *) member_table;
+
+ PRINT20 (hdr->size, (XCOFFARMAGBIG_ELEMENT_SIZE
+ + count * XCOFFARMAGBIG_ELEMENT_SIZE
+ + total_namlen + (total_namlen & 1)));
+ if (makemap && hasobjects)
+ PRINT20 (hdr->nextoff, nextoff + member_table_size);
+ else
+ PRINT20 (hdr->nextoff, 0);
+ PRINT20 (hdr->prevoff, prevoff);
+ PRINT12 (hdr->date, 0);
+ PRINT12 (hdr->uid, 0);
+ PRINT12 (hdr->gid, 0);
+ PRINT12 (hdr->mode, 0);
+ PRINT4 (hdr->namlen, 0);
+
+ mt = member_table + SIZEOF_AR_HDR_BIG;
+ memcpy (mt, XCOFFARFMAG, SXCOFFARFMAG);
+ mt += SXCOFFARFMAG;
+
+ PRINT20 (mt, count);
+ mt += XCOFFARMAGBIG_ELEMENT_SIZE;
+ for (i = 0; i < (size_t) count; i++)
+ {
+ PRINT20 (mt, offsets[i]);
+ mt += XCOFFARMAGBIG_ELEMENT_SIZE;
+ }
+
+ if (count)
+ {
+ free (offsets);
+ offsets = NULL;
+ }
+
+ for (current_bfd = abfd->archive_head;
+ current_bfd != NULL;
+ current_bfd = current_bfd->archive_next)
+ {
+ const char *name;
+ size_t namlen;
+
+ name = normalize_filename (current_bfd);
+ namlen = sprintf (mt, "%s", name);
+ mt += namlen + 1;
+ }
+
+ if (bfd_bwrite (member_table, member_table_size, abfd) != member_table_size)
+ return FALSE;
+
+ free (member_table);
+
+ PRINT20 (fhdr.memoff, nextoff);
+
+ prevoff = nextoff;
+ nextoff += member_table_size;
+
+ /* Write out the armap, if appropriate. */
+
+ if (! makemap || ! hasobjects)
+ PRINT20 (fhdr.symoff, 0);
+ else
+ {
+ BFD_ASSERT (nextoff == bfd_tell (abfd));
+
+ /* Save nextoff in fhdr.symoff so the armap routine can use it. */
+ PRINT20 (fhdr.symoff, nextoff);
+
+ bfd_ardata (abfd)->tdata = &fhdr;
+ if (! _bfd_compute_and_write_armap (abfd, 0))
+ return FALSE;
+ }
+
+ /* Write out the archive file header. */
+
+ if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0
+ || (bfd_bwrite (&fhdr, (bfd_size_type) SIZEOF_AR_FILE_HDR_BIG,
+ abfd) != SIZEOF_AR_FILE_HDR_BIG))
+ return FALSE;
+
+ return TRUE;
+}
+
+bfd_boolean
+_bfd_xcoff_write_archive_contents (bfd *abfd)
+{
+ if (! xcoff_big_format_p (abfd))
+ return xcoff_write_archive_contents_old (abfd);
+ else
+ return xcoff_write_archive_contents_big (abfd);
+}
+
+/* We can't use the usual coff_sizeof_headers routine, because AIX
+ always uses an a.out header. */
+
+int
+_bfd_xcoff_sizeof_headers (bfd *abfd,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED)
+{
+ int size;
+
+ size = FILHSZ;
+ if (xcoff_data (abfd)->full_aouthdr)
+ size += AOUTSZ;
+ else
+ size += SMALL_AOUTSZ;
+ size += abfd->section_count * SCNHSZ;
+
+ if (info->strip != strip_all)
+ {
+ /* There can be additional sections just for dealing with overflow in
+ reloc and lineno counts. But the numbers of relocs and lineno aren't
+ known when bfd_sizeof_headers is called, so we compute them by
+ summing the numbers from input sections. */
+ struct nbr_reloc_lineno
+ {
+ unsigned int reloc_count;
+ unsigned int lineno_count;
+ };
+ struct nbr_reloc_lineno *n_rl;
+ bfd *sub;
+ int max_index;
+ asection *s;
+
+ /* Although the number of sections is known, the maximum value of
+ section->index isn't (because some sections may have been removed).
+ Don't try to renumber sections, just compute the upper bound. */
+ max_index = 0;
+ for (s = abfd->sections; s != NULL; s = s->next)
+ if (s->index > max_index)
+ max_index = s->index;
+
+ /* Allocate the per section counters. It could be possible to use a
+ preallocated array as the number of sections is limited on XCOFF,
+ but this creates a maintainance issue. */
+ n_rl = bfd_zmalloc ((max_index + 1) * sizeof (*n_rl));
+ if (n_rl == NULL)
+ return -1;
+
+ /* Sum. */
+ for (sub = info->input_bfds; sub != NULL; sub = sub->link.next)
+ for (s = sub->sections; s != NULL; s = s->next)
+ {
+ struct nbr_reloc_lineno *e = &n_rl[s->output_section->index];
+ e->reloc_count += s->reloc_count;
+ e->lineno_count += s->lineno_count;
+ }
+
+ /* Add the size of a section for each section with an overflow. */
+ for (s = abfd->sections; s != NULL; s = s->next)
+ {
+ struct nbr_reloc_lineno *e = &n_rl[s->index];
+
+ if (e->reloc_count >= 0xffff
+ || (e->lineno_count >= 0xffff && info->strip != strip_debugger))
+ size += SCNHSZ;
+ }
+
+ free (n_rl);
+ }
+
+ return size;
+}
+
+/* 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 (bfd *abfd, const void * s, struct internal_ldhdr *dst)
+{
+ const struct external_ldhdr *src = (const struct external_ldhdr *) s;
+
+ 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 (bfd *abfd, const struct internal_ldhdr *src, void * d)
+{
+ struct external_ldhdr *dst = (struct external_ldhdr *) d;
+
+ bfd_put_32 (abfd, (bfd_vma) 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 (bfd *abfd, const void * s, struct internal_ldsym *dst)
+{
+ const struct external_ldsym *src = (const struct external_ldsym *) s;
+
+ 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 (bfd *abfd, const struct internal_ldsym *src, void * d)
+{
+ struct external_ldsym *dst = (struct external_ldsym *) d;
+
+ if (src->_l._l_l._l_zeroes != 0)
+ memcpy (dst->_l._l_name, src->_l._l_name, SYMNMLEN);
+ else
+ {
+ bfd_put_32 (abfd, (bfd_vma) 0, dst->_l._l_l._l_zeroes);
+ bfd_put_32 (abfd, (bfd_vma) 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, (bfd_vma) 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);
+}
+
+static void
+xcoff_swap_reloc_in (bfd *abfd, void * s, void * d)
+{
+ struct external_reloc *src = (struct external_reloc *) s;
+ struct internal_reloc *dst = (struct internal_reloc *) d;
+
+ memset (dst, 0, sizeof (struct internal_reloc));
+
+ dst->r_vaddr = bfd_get_32 (abfd, src->r_vaddr);
+ dst->r_symndx = bfd_get_32 (abfd, src->r_symndx);
+ dst->r_size = bfd_get_8 (abfd, src->r_size);
+ dst->r_type = bfd_get_8 (abfd, src->r_type);
+}
+
+static unsigned int
+xcoff_swap_reloc_out (bfd *abfd, void * s, void * d)
+{
+ struct internal_reloc *src = (struct internal_reloc *) s;
+ struct external_reloc *dst = (struct external_reloc *) d;
+
+ bfd_put_32 (abfd, src->r_vaddr, dst->r_vaddr);
+ bfd_put_32 (abfd, src->r_symndx, dst->r_symndx);
+ bfd_put_8 (abfd, src->r_type, dst->r_type);
+ bfd_put_8 (abfd, src->r_size, dst->r_size);
+
+ return bfd_coff_relsz (abfd);
+}
+
+/* Swap in the ldrel structure. */
+
+static void
+xcoff_swap_ldrel_in (bfd *abfd, const void * s, struct internal_ldrel *dst)
+{
+ const struct external_ldrel *src = (const struct external_ldrel *) s;
+
+ 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 (bfd *abfd, const struct internal_ldrel *src, void * d)
+{
+ struct external_ldrel *dst = (struct external_ldrel *) d;
+
+ bfd_put_32 (abfd, src->l_vaddr, dst->l_vaddr);
+ bfd_put_32 (abfd, src->l_symndx, dst->l_symndx);
+ bfd_put_16 (abfd, (bfd_vma) src->l_rtype, dst->l_rtype);
+ bfd_put_16 (abfd, (bfd_vma) src->l_rsecnm, dst->l_rsecnm);
+}
+
+
+bfd_boolean
+xcoff_reloc_type_noop (bfd *input_bfd ATTRIBUTE_UNUSED,
+ asection *input_section ATTRIBUTE_UNUSED,
+ bfd *output_bfd ATTRIBUTE_UNUSED,
+ struct internal_reloc *rel ATTRIBUTE_UNUSED,
+ struct internal_syment *sym ATTRIBUTE_UNUSED,
+ struct reloc_howto_struct *howto ATTRIBUTE_UNUSED,
+ bfd_vma val ATTRIBUTE_UNUSED,
+ bfd_vma addend ATTRIBUTE_UNUSED,
+ bfd_vma *relocation ATTRIBUTE_UNUSED,
+ bfd_byte *contents ATTRIBUTE_UNUSED)
+{
+ return TRUE;
+}
+
+bfd_boolean
+xcoff_reloc_type_fail (bfd *input_bfd,
+ asection *input_section ATTRIBUTE_UNUSED,
+ bfd *output_bfd ATTRIBUTE_UNUSED,
+ struct internal_reloc *rel,
+ struct internal_syment *sym ATTRIBUTE_UNUSED,
+ struct reloc_howto_struct *howto ATTRIBUTE_UNUSED,
+ bfd_vma val ATTRIBUTE_UNUSED,
+ bfd_vma addend ATTRIBUTE_UNUSED,
+ bfd_vma *relocation ATTRIBUTE_UNUSED,
+ bfd_byte *contents ATTRIBUTE_UNUSED)
+{
+ (*_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;
+}
+
+bfd_boolean
+xcoff_reloc_type_pos (bfd *input_bfd ATTRIBUTE_UNUSED,
+ asection *input_section ATTRIBUTE_UNUSED,
+ bfd *output_bfd ATTRIBUTE_UNUSED,
+ struct internal_reloc *rel ATTRIBUTE_UNUSED,
+ struct internal_syment *sym ATTRIBUTE_UNUSED,
+ struct reloc_howto_struct *howto ATTRIBUTE_UNUSED,
+ bfd_vma val,
+ bfd_vma addend,
+ bfd_vma *relocation,
+ bfd_byte *contents ATTRIBUTE_UNUSED)
+{
+ *relocation = val + addend;
+ return TRUE;
+}
+
+bfd_boolean
+xcoff_reloc_type_neg (bfd *input_bfd ATTRIBUTE_UNUSED,
+ asection *input_section ATTRIBUTE_UNUSED,
+ bfd *output_bfd ATTRIBUTE_UNUSED,
+ struct internal_reloc *rel ATTRIBUTE_UNUSED,
+ struct internal_syment *sym ATTRIBUTE_UNUSED,
+ struct reloc_howto_struct *howto ATTRIBUTE_UNUSED,
+ bfd_vma val,
+ bfd_vma addend,
+ bfd_vma *relocation,
+ bfd_byte *contents ATTRIBUTE_UNUSED)
+{
+ *relocation = addend - val;
+ return TRUE;
+}
+
+bfd_boolean
+xcoff_reloc_type_rel (bfd *input_bfd ATTRIBUTE_UNUSED,
+ asection *input_section,
+ bfd *output_bfd ATTRIBUTE_UNUSED,
+ struct internal_reloc *rel ATTRIBUTE_UNUSED,
+ struct internal_syment *sym ATTRIBUTE_UNUSED,
+ struct reloc_howto_struct *howto,
+ bfd_vma val,
+ bfd_vma addend,
+ bfd_vma *relocation,
+ bfd_byte *contents ATTRIBUTE_UNUSED)
+{
+ howto->pc_relative = TRUE;
+
+ /* A PC relative reloc includes the section address. */
+ addend += input_section->vma;
+
+ *relocation = val + addend;
+ *relocation -= (input_section->output_section->vma
+ + input_section->output_offset);
+ return TRUE;
+}
+
+bfd_boolean
+xcoff_reloc_type_toc (bfd *input_bfd,
+ asection *input_section ATTRIBUTE_UNUSED,
+ bfd *output_bfd,
+ struct internal_reloc *rel,
+ struct internal_syment *sym,
+ struct reloc_howto_struct *howto ATTRIBUTE_UNUSED,
+ bfd_vma val,
+ bfd_vma addend ATTRIBUTE_UNUSED,
+ bfd_vma *relocation,
+ bfd_byte *contents ATTRIBUTE_UNUSED)
+{
+ struct xcoff_link_hash_entry *h;
+
+ if (0 > rel->r_symndx)
+ return FALSE;
+
+ h = obj_xcoff_sym_hashes (input_bfd)[rel->r_symndx];
+
+ 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);
+ }
+
+ *relocation = ((val - xcoff_data (output_bfd)->toc)
+ - (sym->n_value - xcoff_data (input_bfd)->toc));
+ return TRUE;
+}
+
+bfd_boolean
+xcoff_reloc_type_ba (bfd *input_bfd ATTRIBUTE_UNUSED,
+ asection *input_section ATTRIBUTE_UNUSED,
+ bfd *output_bfd ATTRIBUTE_UNUSED,
+ struct internal_reloc *rel ATTRIBUTE_UNUSED,
+ struct internal_syment *sym ATTRIBUTE_UNUSED,
+ struct reloc_howto_struct *howto,
+ bfd_vma val,
+ bfd_vma addend,
+ bfd_vma *relocation,
+ bfd_byte *contents ATTRIBUTE_UNUSED)
+{
+ howto->src_mask &= ~3;
+ howto->dst_mask = howto->src_mask;
+
+ *relocation = val + addend;
+
+ return TRUE;
+}
+
+static bfd_boolean
+xcoff_reloc_type_br (bfd *input_bfd,
+ asection *input_section,
+ bfd *output_bfd ATTRIBUTE_UNUSED,
+ struct internal_reloc *rel,
+ struct internal_syment *sym ATTRIBUTE_UNUSED,
+ struct reloc_howto_struct *howto,
+ bfd_vma val,
+ bfd_vma addend,
+ bfd_vma *relocation,
+ bfd_byte *contents)
+{
+ struct xcoff_link_hash_entry *h;
+ bfd_vma section_offset;
+
+ if (0 > rel->r_symndx)
+ return FALSE;
+
+ h = obj_xcoff_sym_hashes (input_bfd)[rel->r_symndx];
+ section_offset = rel->r_vaddr - input_section->vma;
+
+ /* 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 (NULL != h
+ && (bfd_link_hash_defined == h->root.type
+ || bfd_link_hash_defweak == h->root.type)
+ && section_offset + 8 <= input_section->size)
+ {
+ bfd_byte *pnext;
+ unsigned long next;
+
+ pnext = contents + section_offset + 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 */
+ || next == 0x60000000) /* ori r0,r0,0 */
+ bfd_put_32 (input_bfd, 0x80410014, pnext); /* lwz r2,20(r1) */
+
+ }
+ else
+ {
+ if (next == 0x80410014) /* lwz r2,20(r1) */
+ bfd_put_32 (input_bfd, 0x60000000, pnext); /* ori r0,r0,0 */
+ }
+ }
+ else if (NULL != h && bfd_link_hash_undefined == h->root.type)
+ {
+ /* Normally, this relocation is against a defined symbol. In the
+ case where this is a partial link and the output section offset
+ is greater than 2^25, the linker will return an invalid error
+ message that the relocation has been truncated. Yes it has been
+ truncated but no it not important. For this case, disable the
+ overflow checking. */
+
+ howto->complain_on_overflow = complain_overflow_dont;
+ }
+
+ /* The original PC-relative relocation is biased by -r_vaddr, so adding
+ the value below will give the absolute target address. */
+ *relocation = val + addend + rel->r_vaddr;
+
+ howto->src_mask &= ~3;
+ howto->dst_mask = howto->src_mask;
+
+ if (h != NULL
+ && (h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak)
+ && bfd_is_abs_section (h->root.u.def.section)
+ && section_offset + 4 <= input_section->size)
+ {
+ bfd_byte *ptr;
+ bfd_vma insn;
+
+ /* Turn the relative branch into an absolute one by setting the
+ AA bit. */
+ ptr = contents + section_offset;
+ insn = bfd_get_32 (input_bfd, ptr);
+ insn |= 2;
+ bfd_put_32 (input_bfd, insn, ptr);
+
+ /* Make the howto absolute too. */
+ howto->pc_relative = FALSE;
+ howto->complain_on_overflow = complain_overflow_bitfield;
+ }
+ else
+ {
+ /* Use a PC-relative howto and subtract the instruction's address
+ from the target address we calculated above. */
+ howto->pc_relative = TRUE;
+ *relocation -= (input_section->output_section->vma
+ + input_section->output_offset
+ + section_offset);
+ }
+ return TRUE;
+}
+
+bfd_boolean
+xcoff_reloc_type_crel (bfd *input_bfd ATTRIBUTE_UNUSED,
+ asection *input_section,
+ bfd *output_bfd ATTRIBUTE_UNUSED,
+ struct internal_reloc *rel ATTRIBUTE_UNUSED,
+ struct internal_syment *sym ATTRIBUTE_UNUSED,
+ struct reloc_howto_struct *howto,
+ bfd_vma val ATTRIBUTE_UNUSED,
+ bfd_vma addend,
+ bfd_vma *relocation,
+ bfd_byte *contents ATTRIBUTE_UNUSED)
+{
+ howto->pc_relative = TRUE;
+ howto->src_mask &= ~3;
+ howto->dst_mask = howto->src_mask;
+
+ /* A PC relative reloc includes the section address. */
+ addend += input_section->vma;
+
+ *relocation = val + addend;
+ *relocation -= (input_section->output_section->vma
+ + input_section->output_offset);
+ return TRUE;
+}
+
+static bfd_boolean
+xcoff_complain_overflow_dont_func (bfd *input_bfd ATTRIBUTE_UNUSED,
+ bfd_vma val ATTRIBUTE_UNUSED,
+ bfd_vma relocation ATTRIBUTE_UNUSED,
+ struct reloc_howto_struct *
+ howto ATTRIBUTE_UNUSED)
+{
+ return FALSE;
+}
+
+static bfd_boolean
+xcoff_complain_overflow_bitfield_func (bfd *input_bfd,
+ bfd_vma val,
+ bfd_vma relocation,
+ struct reloc_howto_struct *howto)
+{
+ bfd_vma 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);
+ a = relocation;
+ b = val & howto->src_mask;
+
+ /* 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 >>= howto->rightshift;
+ b >>= howto->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 << howto->rightshift) - 1;
+ if ((ss | relocation) != ~ (bfd_vma) 0)
+ return TRUE;
+ a &= fieldmask;
+ }
+
+ /* We just assume (b & ~ fieldmask) == 0. */
+
+ /* We explicitly permit wrap around if this relocation
+ covers the high bit of an address. The Linux kernel
+ relies on it, and it is the only way to write assembler
+ code which can run when loaded at a location 0x80000000
+ away from the location at which it is linked. */
+ if (howto->bitsize + howto->rightshift
+ == bfd_arch_bits_per_address (input_bfd))
+ return FALSE;
+
+ 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)
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static bfd_boolean
+xcoff_complain_overflow_signed_func (bfd *input_bfd,
+ bfd_vma val,
+ bfd_vma relocation,
+ struct reloc_howto_struct *howto)
+{
+ 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 = val & howto->src_mask;
+
+ a = (a & addrmask) >> howto->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 >> howto->rightshift) & signmask))
+ return 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) >> howto->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)
+ return TRUE;
+
+ return FALSE;
+}
+
+static bfd_boolean
+xcoff_complain_overflow_unsigned_func (bfd *input_bfd,
+ bfd_vma val,
+ bfd_vma relocation,
+ struct reloc_howto_struct *howto)
+{
+ bfd_vma addrmask, fieldmask;
+ 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 = val & howto->src_mask;
+
+ /* 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) >> howto->rightshift;
+ b = (b & addrmask) >> howto->bitpos;
+ sum = (a + b) & addrmask;
+ if ((a | b | sum) & ~ fieldmask)
+ return TRUE;
+
+ return FALSE;
+}
+
+/* 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.
+
+ 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.
+
+ Unsupported r_type's
+
+ R_RTB:
+ R_RRTBI:
+ 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.
+
+ Supported r_type's
+
+ R_POS:
+ Simple positive relocation.
+
+ R_NEG:
+ Simple negative relocation.
+
+ R_REL:
+ Simple PC relative relocation.
+
+ 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.
+
+ R_GL:
+ GL linkage relocation. The value of this relocation
+ is the address of the entry in the TOC section.
+
+ R_TCL:
+ Local object TOC address. I can't figure out the
+ difference between this and case R_GL.
+
+ 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.
+
+ 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.
+
+ R_BA:
+ Absolute branch. We don't want to mess with the lower
+ two bits of the instruction.
+
+ 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.
+
+ R_RBA:
+ Absolute branch which may be modified to become a
+ relative branch.
+
+ 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.
+
+ 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.
+
+ R_BR:
+ Relative branch. We don't want to mess with the lower
+ two bits of the instruction.
+
+ 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.
+
+ R_RBR:
+ A relative branch which may be modified to become an
+ absolute branch.
+
+ 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.
+
+ 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.
+*/
+
+bfd_boolean
+xcoff_ppc_relocate_section (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_vma relocation;
+ bfd_vma value_to_relocate;
+ bfd_vma address;
+ bfd_byte *location;
+
+ /* 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;
+
+ /* howto */
+ howto.type = rel->r_type;
+ howto.rightshift = 0;
+ howto.bitsize = (rel->r_size & 0x1f) + 1;
+ howto.size = howto.bitsize > 16 ? 2 : 1;
+ howto.pc_relative = FALSE;
+ howto.bitpos = 0;
+ howto.complain_on_overflow = (rel->r_size & 0x80
+ ? complain_overflow_signed
+ : complain_overflow_bitfield);
+ howto.special_function = NULL;
+ howto.name = "internal";
+ howto.partial_inplace = TRUE;
+ howto.src_mask = howto.dst_mask = N_ONES (howto.bitsize);
+ howto.pcrel_offset = FALSE;
+
+ /* symbol */
+ val = 0;
+ addend = 0;
+ h = NULL;
+ sym = NULL;
+ symndx = rel->r_symndx;
+
+ if (-1 != symndx)
+ {
+ asection *sec;
+
+ h = obj_xcoff_sym_hashes (input_bfd)[symndx];
+ sym = syms + symndx;
+ addend = - sym->n_value;
+
+ if (NULL == h)
+ {
+ 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 (info->unresolved_syms_in_objects != RM_IGNORE
+ && (h->flags & XCOFF_WAS_UNDEFINED) != 0)
+ {
+ if (! ((*info->callbacks->undefined_symbol)
+ (info, h->root.root.string,
+ input_bfd, input_section,
+ rel->r_vaddr - input_section->vma,
+ (info->unresolved_syms_in_objects
+ == RM_GENERATE_ERROR))))
+ return FALSE;
+ }
+ 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 (h->root.type == bfd_link_hash_common)
+ {
+ sec = h->root.u.c.p->section;
+ val = (sec->output_section->vma
+ + sec->output_offset);
+
+ }
+ else
+ {
+ BFD_ASSERT (info->relocatable
+ || (info->static_link
+ && (h->flags & XCOFF_WAS_UNDEFINED) != 0)
+ || (h->flags & XCOFF_DEF_DYNAMIC) != 0
+ || (h->flags & XCOFF_IMPORT) != 0);
+ }
+ }
+ }
+
+ if (rel->r_type >= XCOFF_MAX_CALCULATE_RELOCATION
+ || !((*xcoff_calculate_relocation[rel->r_type])
+ (input_bfd, input_section, output_bfd, rel, sym, &howto, val,
+ addend, &relocation, contents)))
+ return FALSE;
+
+ /* address */
+ address = rel->r_vaddr - input_section->vma;
+ location = contents + address;
+
+ if (address > input_section->size)
+ abort ();
+
+ /* Get the value we are going to relocate. */
+ if (1 == howto.size)
+ value_to_relocate = bfd_get_16 (input_bfd, location);
+ else
+ value_to_relocate = bfd_get_32 (input_bfd, location);
+
+ /* 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. */
+
+ if ((unsigned int) howto.complain_on_overflow
+ >= XCOFF_MAX_COMPLAIN_OVERFLOW)
+ abort ();
+
+ if (((*xcoff_complain_overflow[howto.complain_on_overflow])
+ (input_bfd, value_to_relocate, relocation, &howto)))
+ {
+ const char *name;
+ char buf[SYMNMLEN + 1];
+ char reloc_type_name[10];
+
+ if (symndx == -1)
+ {
+ name = "*ABS*";
+ }
+ else if (h != NULL)
+ {
+ name = NULL;
+ }
+ else
+ {
+ name = _bfd_coff_internal_syment_name (input_bfd, sym, buf);
+ if (name == NULL)
+ name = "UNKNOWN";
+ }
+ sprintf (reloc_type_name, "0x%02x", rel->r_type);
+
+ if (! ((*info->callbacks->reloc_overflow)
+ (info, (h ? &h->root : NULL), name, reloc_type_name,
+ (bfd_vma) 0, input_bfd, input_section,
+ rel->r_vaddr - input_section->vma)))
+ return FALSE;
+ }
+
+ /* Add RELOCATION to the right bits of VALUE_TO_RELOCATE. */
+ value_to_relocate = ((value_to_relocate & ~howto.dst_mask)
+ | (((value_to_relocate & howto.src_mask)
+ + relocation) & howto.dst_mask));
+
+ /* Put the value back in the object file. */
+ if (1 == howto.size)
+ bfd_put_16 (input_bfd, value_to_relocate, location);
+ else
+ bfd_put_32 (input_bfd, value_to_relocate, location);
+ }
+
+ return TRUE;
+}
+
+static bfd_boolean
+_bfd_xcoff_put_ldsymbol_name (bfd *abfd ATTRIBUTE_UNUSED,
+ struct xcoff_loader_info *ldinfo,
+ struct internal_ldsym *ldsym,
+ const char *name)
+{
+ size_t len;
+ len = strlen (name);
+
+ if (len <= SYMNMLEN)
+ strncpy (ldsym->_l._l_name, name, SYMNMLEN);
+ else
+ {
+ if (ldinfo->string_size + len + 3 > ldinfo->string_alc)
+ {
+ bfd_size_type newalc;
+ char *newstrings;
+
+ newalc = ldinfo->string_alc * 2;
+ if (newalc == 0)
+ newalc = 32;
+ while (ldinfo->string_size + len + 3 > newalc)
+ newalc *= 2;
+
+ newstrings = bfd_realloc (ldinfo->strings, newalc);
+ if (newstrings == NULL)
+ {
+ ldinfo->failed = TRUE;
+ return FALSE;
+ }
+ ldinfo->string_alc = newalc;
+ ldinfo->strings = newstrings;
+ }
+
+ bfd_put_16 (ldinfo->output_bfd, (bfd_vma) (len + 1),
+ ldinfo->strings + ldinfo->string_size);
+ strcpy (ldinfo->strings + ldinfo->string_size + 2, name);
+ ldsym->_l._l_l._l_zeroes = 0;
+ ldsym->_l._l_l._l_offset = ldinfo->string_size + 2;
+ ldinfo->string_size += len + 3;
+ }
+
+ return TRUE;
+}
+
+static bfd_boolean
+_bfd_xcoff_put_symbol_name (bfd *abfd, struct bfd_strtab_hash *strtab,
+ struct internal_syment *sym,
+ const char *name)
+{
+ if (strlen (name) <= SYMNMLEN)
+ {
+ strncpy (sym->_n._n_name, name, SYMNMLEN);
+ }
+ else
+ {
+ bfd_boolean hash;
+ bfd_size_type indx;
+
+ hash = TRUE;
+ if ((abfd->flags & BFD_TRADITIONAL_FORMAT) != 0)
+ hash = FALSE;
+ indx = _bfd_stringtab_add (strtab, name, hash, FALSE);
+ if (indx == (bfd_size_type) -1)
+ return FALSE;
+ sym->_n._n_n._n_zeroes = 0;
+ sym->_n._n_n._n_offset = STRING_SIZE_SIZE + indx;
+ }
+ return TRUE;
+}
+
+static asection *
+xcoff_create_csect_from_smclas (bfd *abfd,
+ union internal_auxent *aux,
+ const char *symbol_name)
+{
+ asection *return_value = NULL;
+
+ /* .sv64 = x_smclas == 17
+ This is an invalid csect for 32 bit apps. */
+ static const char * const names[] =
+ {
+ ".pr", ".ro", ".db", ".tc", ".ua", ".rw", ".gl", ".xo", /* 0 - 7 */
+ ".sv", ".bs", ".ds", ".uc", ".ti", ".tb", NULL, ".tc0", /* 8 - 15 */
+ ".td", NULL, ".sv3264", NULL, ".tl", ".ul", ".te"
+ };
+
+ if ((aux->x_csect.x_smclas < ARRAY_SIZE (names))
+ && (NULL != names[aux->x_csect.x_smclas]))
+ {
+ return_value = bfd_make_section_anyway
+ (abfd, names[aux->x_csect.x_smclas]);
+ }
+ else
+ {
+ (*_bfd_error_handler)
+ (_("%B: symbol `%s' has unrecognized smclas %d"),
+ abfd, symbol_name, aux->x_csect.x_smclas);
+ bfd_set_error (bfd_error_bad_value);
+ }
+
+ return return_value;
+}
+
+static bfd_boolean
+xcoff_is_lineno_count_overflow (bfd *abfd ATTRIBUTE_UNUSED, bfd_vma value)
+{
+ if (0xffff <= value)
+ return TRUE;
+
+ return FALSE;
+}
+
+static bfd_boolean
+xcoff_is_reloc_count_overflow (bfd *abfd ATTRIBUTE_UNUSED, bfd_vma value)
+{
+ if (0xffff <= value)
+ return TRUE;
+
+ return FALSE;
+}
+
+static bfd_vma
+xcoff_loader_symbol_offset (bfd *abfd,
+ struct internal_ldhdr *ldhdr ATTRIBUTE_UNUSED)
+{
+ return bfd_xcoff_ldhdrsz (abfd);
+}
+
+static bfd_vma
+xcoff_loader_reloc_offset (bfd *abfd, struct internal_ldhdr *ldhdr)
+{
+ return bfd_xcoff_ldhdrsz (abfd) + ldhdr->l_nsyms * bfd_xcoff_ldsymsz (abfd);
+}
+
+static bfd_boolean
+xcoff_generate_rtinit (bfd *abfd, const char *init, const char *fini,
+ bfd_boolean rtld)
+{
+ bfd_byte filehdr_ext[FILHSZ];
+ bfd_byte scnhdr_ext[SCNHSZ];
+ bfd_byte syment_ext[SYMESZ * 10];
+ bfd_byte reloc_ext[RELSZ * 3];
+ bfd_byte *data_buffer;
+ bfd_size_type data_buffer_size;
+ bfd_byte *string_table = NULL, *st_tmp = NULL;
+ bfd_size_type string_table_size;
+ bfd_vma val;
+ size_t initsz, finisz;
+ struct internal_filehdr filehdr;
+ struct internal_scnhdr scnhdr;
+ struct internal_syment syment;
+ union internal_auxent auxent;
+ struct internal_reloc reloc;
+
+ char *data_name = ".data";
+ char *rtinit_name = "__rtinit";
+ char *rtld_name = "__rtld";
+
+ if (! bfd_xcoff_rtinit_size (abfd))
+ return FALSE;
+
+ initsz = (init == NULL ? 0 : 1 + strlen (init));
+ finisz = (fini == NULL ? 0 : 1 + strlen (fini));
+
+ /* file header */
+ memset (filehdr_ext, 0, FILHSZ);
+ memset (&filehdr, 0, sizeof (struct internal_filehdr));
+ filehdr.f_magic = bfd_xcoff_magic_number (abfd);
+ filehdr.f_nscns = 1;
+ filehdr.f_timdat = 0;
+ filehdr.f_nsyms = 0; /* at least 6, no more than 10 */
+ filehdr.f_symptr = 0; /* set below */
+ filehdr.f_opthdr = 0;
+ filehdr.f_flags = 0;
+
+ /* section header */
+ memset (scnhdr_ext, 0, SCNHSZ);
+ memset (&scnhdr, 0, sizeof (struct internal_scnhdr));
+ memcpy (scnhdr.s_name, data_name, strlen (data_name));
+ scnhdr.s_paddr = 0;
+ scnhdr.s_vaddr = 0;
+ scnhdr.s_size = 0; /* set below */
+ scnhdr.s_scnptr = FILHSZ + SCNHSZ;
+ scnhdr.s_relptr = 0; /* set below */
+ scnhdr.s_lnnoptr = 0;
+ scnhdr.s_nreloc = 0; /* either 1 or 2 */
+ scnhdr.s_nlnno = 0;
+ scnhdr.s_flags = STYP_DATA;
+
+ /* .data
+ 0x0000 0x00000000 : rtl
+ 0x0004 0x00000010 : offset to init, or 0
+ 0x0008 0x00000028 : offset to fini, or 0
+ 0x000C 0x0000000C : size of descriptor
+ 0x0010 0x00000000 : init, needs a reloc
+ 0x0014 0x00000040 : offset to init name
+ 0x0018 0x00000000 : flags, padded to a word
+ 0x001C 0x00000000 : empty init
+ 0x0020 0x00000000 :
+ 0x0024 0x00000000 :
+ 0x0028 0x00000000 : fini, needs a reloc
+ 0x002C 0x00000??? : offset to fini name
+ 0x0030 0x00000000 : flags, padded to a word
+ 0x0034 0x00000000 : empty fini
+ 0x0038 0x00000000 :
+ 0x003C 0x00000000 :
+ 0x0040 init name
+ 0x0040 + initsz fini name */
+
+ data_buffer_size = 0x0040 + initsz + finisz;
+ data_buffer_size = (data_buffer_size + 7) &~ (bfd_size_type) 7;
+ data_buffer = NULL;
+ data_buffer = (bfd_byte *) bfd_zmalloc (data_buffer_size);
+ if (data_buffer == NULL)
+ return FALSE;
+
+ if (initsz)
+ {
+ val = 0x10;
+ bfd_h_put_32 (abfd, val, &data_buffer[0x04]);
+ val = 0x40;
+ bfd_h_put_32 (abfd, val, &data_buffer[0x14]);
+ memcpy (&data_buffer[val], init, initsz);
+ }
+
+ if (finisz)
+ {
+ val = 0x28;
+ bfd_h_put_32 (abfd, val, &data_buffer[0x08]);
+ val = 0x40 + initsz;
+ bfd_h_put_32 (abfd, val, &data_buffer[0x2C]);
+ memcpy (&data_buffer[val], fini, finisz);
+ }
+
+ val = 0x0C;
+ bfd_h_put_32 (abfd, val, &data_buffer[0x0C]);
+
+ scnhdr.s_size = data_buffer_size;
+
+ /* string table */
+ string_table_size = 0;
+ if (initsz > 9)
+ string_table_size += initsz;
+ if (finisz > 9)
+ string_table_size += finisz;
+ if (string_table_size)
+ {
+ string_table_size += 4;
+ string_table = (bfd_byte *) bfd_zmalloc (string_table_size);
+ if (string_table == NULL)
+ return FALSE;
+
+ val = string_table_size;
+ bfd_h_put_32 (abfd, val, &string_table[0]);
+ st_tmp = string_table + 4;
+ }
+
+ /* symbols
+ 0. .data csect
+ 2. __rtinit
+ 4. init function
+ 6. fini function
+ 8. __rtld */
+ memset (syment_ext, 0, 10 * SYMESZ);
+ memset (reloc_ext, 0, 3 * RELSZ);
+
+ /* .data csect */
+ memset (&syment, 0, sizeof (struct internal_syment));
+ memset (&auxent, 0, sizeof (union internal_auxent));
+ memcpy (syment._n._n_name, data_name, strlen (data_name));
+ syment.n_scnum = 1;
+ syment.n_sclass = C_HIDEXT;
+ syment.n_numaux = 1;
+ auxent.x_csect.x_scnlen.l = data_buffer_size;
+ auxent.x_csect.x_smtyp = 3 << 3 | XTY_SD;
+ auxent.x_csect.x_smclas = XMC_RW;
+ bfd_coff_swap_sym_out (abfd, &syment,
+ &syment_ext[filehdr.f_nsyms * SYMESZ]);
+ bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0,
+ syment.n_numaux,
+ &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]);
+ filehdr.f_nsyms += 2;
+
+ /* __rtinit */
+ memset (&syment, 0, sizeof (struct internal_syment));
+ memset (&auxent, 0, sizeof (union internal_auxent));
+ memcpy (syment._n._n_name, rtinit_name, strlen (rtinit_name));
+ syment.n_scnum = 1;
+ syment.n_sclass = C_EXT;
+ syment.n_numaux = 1;
+ auxent.x_csect.x_smtyp = XTY_LD;
+ auxent.x_csect.x_smclas = XMC_RW;
+ bfd_coff_swap_sym_out (abfd, &syment,
+ &syment_ext[filehdr.f_nsyms * SYMESZ]);
+ bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0,
+ syment.n_numaux,
+ &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]);
+ filehdr.f_nsyms += 2;
+
+ /* init */
+ if (initsz)
+ {
+ memset (&syment, 0, sizeof (struct internal_syment));
+ memset (&auxent, 0, sizeof (union internal_auxent));
+
+ if (initsz > 9)
+ {
+ syment._n._n_n._n_offset = st_tmp - string_table;
+ memcpy (st_tmp, init, initsz);
+ st_tmp += initsz;
+ }
+ else
+ memcpy (syment._n._n_name, init, initsz - 1);
+
+ syment.n_sclass = C_EXT;
+ syment.n_numaux = 1;
+ bfd_coff_swap_sym_out (abfd, &syment,
+ &syment_ext[filehdr.f_nsyms * SYMESZ]);
+ bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0,
+ syment.n_numaux,
+ &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]);
+
+ /* reloc */
+ memset (&reloc, 0, sizeof (struct internal_reloc));
+ reloc.r_vaddr = 0x0010;
+ reloc.r_symndx = filehdr.f_nsyms;
+ reloc.r_type = R_POS;
+ reloc.r_size = 31;
+ bfd_coff_swap_reloc_out (abfd, &reloc, &reloc_ext[0]);
+
+ filehdr.f_nsyms += 2;
+ scnhdr.s_nreloc += 1;
+ }
+
+ /* fini */
+ if (finisz)
+ {
+ memset (&syment, 0, sizeof (struct internal_syment));
+ memset (&auxent, 0, sizeof (union internal_auxent));
+
+ if (finisz > 9)
+ {
+ syment._n._n_n._n_offset = st_tmp - string_table;
+ memcpy (st_tmp, fini, finisz);
+ st_tmp += finisz;
+ }
+ else
+ memcpy (syment._n._n_name, fini, finisz - 1);
+
+ syment.n_sclass = C_EXT;
+ syment.n_numaux = 1;
+ bfd_coff_swap_sym_out (abfd, &syment,
+ &syment_ext[filehdr.f_nsyms * SYMESZ]);
+ bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0,
+ syment.n_numaux,
+ &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]);
+
+ /* reloc */
+ memset (&reloc, 0, sizeof (struct internal_reloc));
+ reloc.r_vaddr = 0x0028;
+ reloc.r_symndx = filehdr.f_nsyms;
+ reloc.r_type = R_POS;
+ reloc.r_size = 31;
+ bfd_coff_swap_reloc_out (abfd, &reloc,
+ &reloc_ext[scnhdr.s_nreloc * RELSZ]);
+
+ filehdr.f_nsyms += 2;
+ scnhdr.s_nreloc += 1;
+ }
+
+ if (rtld)
+ {
+ memset (&syment, 0, sizeof (struct internal_syment));
+ memset (&auxent, 0, sizeof (union internal_auxent));
+ memcpy (syment._n._n_name, rtld_name, strlen (rtld_name));
+ syment.n_sclass = C_EXT;
+ syment.n_numaux = 1;
+ bfd_coff_swap_sym_out (abfd, &syment,
+ &syment_ext[filehdr.f_nsyms * SYMESZ]);
+ bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0,
+ syment.n_numaux,
+ &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]);
+
+ /* reloc */
+ memset (&reloc, 0, sizeof (struct internal_reloc));
+ reloc.r_vaddr = 0x0000;
+ reloc.r_symndx = filehdr.f_nsyms;
+ reloc.r_type = R_POS;
+ reloc.r_size = 31;
+ bfd_coff_swap_reloc_out (abfd, &reloc,
+ &reloc_ext[scnhdr.s_nreloc * RELSZ]);
+
+ filehdr.f_nsyms += 2;
+ scnhdr.s_nreloc += 1;
+ }
+
+ scnhdr.s_relptr = scnhdr.s_scnptr + data_buffer_size;
+ filehdr.f_symptr = scnhdr.s_relptr + scnhdr.s_nreloc * RELSZ;
+
+ bfd_coff_swap_filehdr_out (abfd, &filehdr, filehdr_ext);
+ bfd_bwrite (filehdr_ext, FILHSZ, abfd);
+ bfd_coff_swap_scnhdr_out (abfd, &scnhdr, scnhdr_ext);
+ bfd_bwrite (scnhdr_ext, SCNHSZ, abfd);
+ bfd_bwrite (data_buffer, data_buffer_size, abfd);
+ bfd_bwrite (reloc_ext, scnhdr.s_nreloc * RELSZ, abfd);
+ bfd_bwrite (syment_ext, filehdr.f_nsyms * SYMESZ, abfd);
+ bfd_bwrite (string_table, string_table_size, abfd);
+
+ free (data_buffer);
+ data_buffer = NULL;
+
+ return TRUE;
+}
+
+
+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 */
+
+/* glink
+
+ The first word of global linkage code must be modified by filling in
+ the correct TOC offset. */
+
+static unsigned long xcoff_glink_code[9] =
+ {
+ 0x81820000, /* lwz r12,0(r2) */
+ 0x90410014, /* stw r2,20(r1) */
+ 0x800c0000, /* lwz r0,0(r12) */
+ 0x804c0004, /* lwz r2,4(r12) */
+ 0x7c0903a6, /* mtctr r0 */
+ 0x4e800420, /* bctr */
+ 0x00000000, /* start of traceback table */
+ 0x000c8000, /* traceback table */
+ 0x00000000, /* traceback table */
+ };
+
+/* Table to convert DWARF flags to section names. */
+
+const struct xcoff_dwsect_name xcoff_dwsect_names[] = {
+ { SSUBTYP_DWINFO, ".dwinfo", TRUE },
+ { SSUBTYP_DWLINE, ".dwline", TRUE },
+ { SSUBTYP_DWPBNMS, ".dwpbnms", TRUE },
+ { SSUBTYP_DWPBTYP, ".dwpbtyp", TRUE },
+ { SSUBTYP_DWARNGE, ".dwarnge", TRUE },
+ { SSUBTYP_DWABREV, ".dwabrev", FALSE },
+ { SSUBTYP_DWSTR, ".dwstr", TRUE },
+ { SSUBTYP_DWRNGES, ".dwrnges", TRUE }
+};
+
+/* For generic entry points. */
+#define _bfd_xcoff_close_and_cleanup _bfd_archive_close_and_cleanup
+#define _bfd_xcoff_bfd_free_cached_info bfd_true
+#define _bfd_xcoff_new_section_hook coff_new_section_hook
+#define _bfd_xcoff_get_section_contents _bfd_generic_get_section_contents
+#define _bfd_xcoff_get_section_contents_in_window \
+ _bfd_generic_get_section_contents_in_window
+
+/* For copy private data entry points. */
+#define _bfd_xcoff_bfd_copy_private_bfd_data \
+ _bfd_xcoff_copy_private_bfd_data
+#define _bfd_xcoff_bfd_merge_private_bfd_data \
+ _bfd_generic_bfd_merge_private_bfd_data
+#define _bfd_xcoff_bfd_copy_private_section_data \
+ _bfd_generic_bfd_copy_private_section_data
+#define _bfd_xcoff_bfd_copy_private_symbol_data \
+ _bfd_generic_bfd_copy_private_symbol_data
+#define _bfd_xcoff_bfd_copy_private_header_data \
+ _bfd_generic_bfd_copy_private_header_data
+#define _bfd_xcoff_bfd_set_private_flags \
+ _bfd_generic_bfd_set_private_flags
+#define _bfd_xcoff_bfd_print_private_bfd_data \
+ _bfd_generic_bfd_print_private_bfd_data
+
+/* For archive entry points. */
+#define _bfd_xcoff_slurp_extended_name_table \
+ _bfd_noarchive_slurp_extended_name_table
+#define _bfd_xcoff_construct_extended_name_table \
+ _bfd_noarchive_construct_extended_name_table
+#define _bfd_xcoff_truncate_arname bfd_dont_truncate_arname
+#define _bfd_xcoff_write_ar_hdr _bfd_generic_write_ar_hdr
+#define _bfd_xcoff_get_elt_at_index _bfd_generic_get_elt_at_index
+#define _bfd_xcoff_generic_stat_arch_elt _bfd_xcoff_stat_arch_elt
+#define _bfd_xcoff_update_armap_timestamp bfd_true
+
+/* For symbols entry points. */
+#define _bfd_xcoff_get_symtab_upper_bound coff_get_symtab_upper_bound
+#define _bfd_xcoff_canonicalize_symtab coff_canonicalize_symtab
+#define _bfd_xcoff_make_empty_symbol coff_make_empty_symbol
+#define _bfd_xcoff_print_symbol coff_print_symbol
+#define _bfd_xcoff_get_symbol_info coff_get_symbol_info
+#define _bfd_xcoff_bfd_is_local_label_name _bfd_xcoff_is_local_label_name
+#define _bfd_xcoff_bfd_is_target_special_symbol \
+ coff_bfd_is_target_special_symbol
+#define _bfd_xcoff_get_lineno coff_get_lineno
+#define _bfd_xcoff_find_nearest_line coff_find_nearest_line
+#define _bfd_xcoff_find_line coff_find_line
+#define _bfd_xcoff_find_inliner_info coff_find_inliner_info
+#define _bfd_xcoff_bfd_make_debug_symbol coff_bfd_make_debug_symbol
+#define _bfd_xcoff_read_minisymbols _bfd_generic_read_minisymbols
+#define _bfd_xcoff_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol
+
+/* For reloc entry points. */
+#define _bfd_xcoff_get_reloc_upper_bound coff_get_reloc_upper_bound
+#define _bfd_xcoff_canonicalize_reloc coff_canonicalize_reloc
+#define _bfd_xcoff_bfd_reloc_type_lookup _bfd_xcoff_reloc_type_lookup
+#define _bfd_xcoff_bfd_reloc_name_lookup _bfd_xcoff_reloc_name_lookup
+
+/* For link entry points. */
+#define _bfd_xcoff_bfd_get_relocated_section_contents \
+ bfd_generic_get_relocated_section_contents
+#define _bfd_xcoff_bfd_relax_section bfd_generic_relax_section
+#define _bfd_xcoff_bfd_link_hash_table_free _bfd_generic_link_hash_table_free
+#define _bfd_xcoff_bfd_link_just_syms _bfd_generic_link_just_syms
+#define _bfd_xcoff_bfd_copy_link_hash_symbol_type \
+ _bfd_generic_copy_link_hash_symbol_type
+#define _bfd_xcoff_bfd_link_split_section _bfd_generic_link_split_section
+#define _bfd_xcoff_bfd_gc_sections bfd_generic_gc_sections
+#define _bfd_xcoff_bfd_lookup_section_flags bfd_generic_lookup_section_flags
+#define _bfd_xcoff_bfd_merge_sections bfd_generic_merge_sections
+#define _bfd_xcoff_bfd_is_group_section bfd_generic_is_group_section
+#define _bfd_xcoff_bfd_discard_group bfd_generic_discard_group
+#define _bfd_xcoff_section_already_linked _bfd_generic_section_already_linked
+#define _bfd_xcoff_bfd_define_common_symbol _bfd_xcoff_define_common_symbol
+
+/* For dynamic symbols and relocs entry points. */
+#define _bfd_xcoff_get_synthetic_symtab _bfd_nodynamic_get_synthetic_symtab
+
+static const struct xcoff_backend_data_rec bfd_xcoff_backend_data =
+ {
+ { /* COFF backend, defined in libcoff.h. */
+ _bfd_xcoff_swap_aux_in,
+ _bfd_xcoff_swap_sym_in,
+ coff_swap_lineno_in,
+ _bfd_xcoff_swap_aux_out,
+ _bfd_xcoff_swap_sym_out,
+ coff_swap_lineno_out,
+ xcoff_swap_reloc_out,
+ coff_swap_filehdr_out,
+ coff_swap_aouthdr_out,
+ coff_swap_scnhdr_out,
+ FILHSZ,
+ AOUTSZ,
+ SCNHSZ,
+ SYMESZ,
+ AUXESZ,
+ RELSZ,
+ LINESZ,
+ FILNMLEN,
+ TRUE, /* _bfd_coff_long_filenames */
+ XCOFF_NO_LONG_SECTION_NAMES, /* _bfd_coff_long_section_names */
+ 3, /* _bfd_coff_default_section_alignment_power */
+ FALSE, /* _bfd_coff_force_symnames_in_strings */
+ 2, /* _bfd_coff_debug_string_prefix_length */
+ 32768, /* _bfd_coff_max_nscns */
+ coff_swap_filehdr_in,
+ coff_swap_aouthdr_in,
+ coff_swap_scnhdr_in,
+ xcoff_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,
+ dummy_reloc16_extra_cases,
+ dummy_reloc16_estimate,
+ NULL, /* bfd_coff_sym_is_global */
+ coff_compute_section_file_positions,
+ NULL, /* _bfd_coff_start_final_link */
+ xcoff_ppc_relocate_section,
+ coff_rtype_to_howto,
+ NULL, /* _bfd_coff_adjust_symndx */
+ _bfd_generic_link_add_one_symbol,
+ coff_link_output_has_begun,
+ coff_final_link_postscript,
+ NULL /* print_pdata. */
+ },
+
+ 0x01DF, /* magic number */
+ bfd_arch_rs6000,
+ bfd_mach_rs6k,
+
+ /* Function pointers to xcoff specific swap routines. */
+ xcoff_swap_ldhdr_in,
+ xcoff_swap_ldhdr_out,
+ xcoff_swap_ldsym_in,
+ xcoff_swap_ldsym_out,
+ xcoff_swap_ldrel_in,
+ xcoff_swap_ldrel_out,
+
+ /* Sizes. */
+ LDHDRSZ,
+ LDSYMSZ,
+ LDRELSZ,
+ 12, /* _xcoff_function_descriptor_size */
+ SMALL_AOUTSZ,
+
+ /* Versions. */
+ 1, /* _xcoff_ldhdr_version */
+
+ _bfd_xcoff_put_symbol_name,
+ _bfd_xcoff_put_ldsymbol_name,
+ &xcoff_dynamic_reloc,
+ xcoff_create_csect_from_smclas,
+
+ /* Lineno and reloc count overflow. */
+ xcoff_is_lineno_count_overflow,
+ xcoff_is_reloc_count_overflow,
+
+ xcoff_loader_symbol_offset,
+ xcoff_loader_reloc_offset,
+
+ /* glink. */
+ &xcoff_glink_code[0],
+ 36, /* _xcoff_glink_size */
+
+ /* rtinit */
+ 64, /* _xcoff_rtinit_size */
+ xcoff_generate_rtinit,
+ };
+
+/* The transfer vector that leads the outside world to all of the above. */
+const bfd_target rs6000_xcoff_vec =
+ {
+ "aixcoff-rs6000",
+ bfd_target_xcoff_flavour,
+ BFD_ENDIAN_BIG, /* data byte order is big */
+ BFD_ENDIAN_BIG, /* header byte order is big */
+
+ (HAS_RELOC | EXEC_P | HAS_LINENO | HAS_DEBUG | DYNAMIC
+ | HAS_SYMS | HAS_LOCALS | WP_TEXT),
+
+ SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_DATA,
+ 0, /* leading char */
+ '/', /* ar_pad_char */
+ 15, /* ar_max_namelen */
+ 0, /* match priority. */
+
+ /* 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_check_format */
+ _bfd_dummy_target,
+ coff_object_p,
+ _bfd_xcoff_archive_p,
+ CORE_FILE_P
+ },
+
+ { /* bfd_set_format */
+ bfd_false,
+ coff_mkobject,
+ _bfd_generic_mkarchive,
+ bfd_false
+ },
+
+ {/* bfd_write_contents */
+ bfd_false,
+ coff_write_object_contents,
+ _bfd_xcoff_write_archive_contents,
+ bfd_false
+ },
+
+ BFD_JUMP_TABLE_GENERIC (_bfd_xcoff),
+ BFD_JUMP_TABLE_COPY (_bfd_xcoff),
+ BFD_JUMP_TABLE_CORE (coff),
+ BFD_JUMP_TABLE_ARCHIVE (_bfd_xcoff),
+ BFD_JUMP_TABLE_SYMBOLS (_bfd_xcoff),
+ BFD_JUMP_TABLE_RELOCS (_bfd_xcoff),
+ BFD_JUMP_TABLE_WRITE (coff),
+ BFD_JUMP_TABLE_LINK (_bfd_xcoff),
+ BFD_JUMP_TABLE_DYNAMIC (_bfd_xcoff),
+
+ /* Opposite endian version, none exists */
+ NULL,
+
+ & bfd_xcoff_backend_data,
+ };
+
+/* xcoff-powermac target
+ Old target.
+ Only difference between this target and the rs6000 target is the
+ the default architecture and machine type used in coffcode.h
+
+ PowerPC Macs use the same magic numbers as RS/6000
+ (because that's how they were bootstrapped originally),
+ but they are always PowerPC architecture. */
+static const struct xcoff_backend_data_rec bfd_pmac_xcoff_backend_data =
+ {
+ { /* COFF backend, defined in libcoff.h. */
+ _bfd_xcoff_swap_aux_in,
+ _bfd_xcoff_swap_sym_in,
+ coff_swap_lineno_in,
+ _bfd_xcoff_swap_aux_out,
+ _bfd_xcoff_swap_sym_out,
+ coff_swap_lineno_out,
+ xcoff_swap_reloc_out,
+ coff_swap_filehdr_out,
+ coff_swap_aouthdr_out,
+ coff_swap_scnhdr_out,
+ FILHSZ,
+ AOUTSZ,
+ SCNHSZ,
+ SYMESZ,
+ AUXESZ,
+ RELSZ,
+ LINESZ,
+ FILNMLEN,
+ TRUE, /* _bfd_coff_long_filenames */
+ XCOFF_NO_LONG_SECTION_NAMES, /* _bfd_coff_long_section_names */
+ 3, /* _bfd_coff_default_section_alignment_power */
+ FALSE, /* _bfd_coff_force_symnames_in_strings */
+ 2, /* _bfd_coff_debug_string_prefix_length */
+ 32768, /* _bfd_coff_max_nscns */
+ coff_swap_filehdr_in,
+ coff_swap_aouthdr_in,
+ coff_swap_scnhdr_in,
+ xcoff_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,
+ dummy_reloc16_extra_cases,
+ dummy_reloc16_estimate,
+ NULL, /* bfd_coff_sym_is_global */
+ coff_compute_section_file_positions,
+ NULL, /* _bfd_coff_start_final_link */
+ xcoff_ppc_relocate_section,
+ coff_rtype_to_howto,
+ NULL, /* _bfd_coff_adjust_symndx */
+ _bfd_generic_link_add_one_symbol,
+ coff_link_output_has_begun,
+ coff_final_link_postscript,
+ NULL /* print_pdata. */
+ },
+
+ 0x01DF, /* magic number */
+ bfd_arch_powerpc,
+ bfd_mach_ppc,
+
+ /* Function pointers to xcoff specific swap routines. */
+ xcoff_swap_ldhdr_in,
+ xcoff_swap_ldhdr_out,
+ xcoff_swap_ldsym_in,
+ xcoff_swap_ldsym_out,
+ xcoff_swap_ldrel_in,
+ xcoff_swap_ldrel_out,
+
+ /* Sizes. */
+ LDHDRSZ,
+ LDSYMSZ,
+ LDRELSZ,
+ 12, /* _xcoff_function_descriptor_size */
+ SMALL_AOUTSZ,
+
+ /* Versions. */
+ 1, /* _xcoff_ldhdr_version */
+
+ _bfd_xcoff_put_symbol_name,
+ _bfd_xcoff_put_ldsymbol_name,
+ &xcoff_dynamic_reloc,
+ xcoff_create_csect_from_smclas,
+
+ /* Lineno and reloc count overflow. */
+ xcoff_is_lineno_count_overflow,
+ xcoff_is_reloc_count_overflow,
+
+ xcoff_loader_symbol_offset,
+ xcoff_loader_reloc_offset,
+
+ /* glink. */
+ &xcoff_glink_code[0],
+ 36, /* _xcoff_glink_size */
+
+ /* rtinit */
+ 0, /* _xcoff_rtinit_size */
+ xcoff_generate_rtinit,
+ };
+
+/* The transfer vector that leads the outside world to all of the above. */
+const bfd_target powerpc_xcoff_vec =
+ {
+ "xcoff-powermac",
+ bfd_target_xcoff_flavour,
+ BFD_ENDIAN_BIG, /* data byte order is big */
+ BFD_ENDIAN_BIG, /* header byte order is big */
+
+ (HAS_RELOC | EXEC_P | HAS_LINENO | HAS_DEBUG | DYNAMIC
+ | HAS_SYMS | HAS_LOCALS | WP_TEXT),
+
+ SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_DATA,
+ 0, /* leading char */
+ '/', /* ar_pad_char */
+ 15, /* ar_max_namelen */
+ 0, /* match priority. */
+
+ /* 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_check_format */
+ _bfd_dummy_target,
+ coff_object_p,
+ _bfd_xcoff_archive_p,
+ CORE_FILE_P
+ },
+
+ { /* bfd_set_format */
+ bfd_false,
+ coff_mkobject,
+ _bfd_generic_mkarchive,
+ bfd_false
+ },
+
+ {/* bfd_write_contents */
+ bfd_false,
+ coff_write_object_contents,
+ _bfd_xcoff_write_archive_contents,
+ bfd_false
+ },
+
+ BFD_JUMP_TABLE_GENERIC (_bfd_xcoff),
+ BFD_JUMP_TABLE_COPY (_bfd_xcoff),
+ BFD_JUMP_TABLE_CORE (coff),
+ BFD_JUMP_TABLE_ARCHIVE (_bfd_xcoff),
+ BFD_JUMP_TABLE_SYMBOLS (_bfd_xcoff),
+ BFD_JUMP_TABLE_RELOCS (_bfd_xcoff),
+ BFD_JUMP_TABLE_WRITE (coff),
+ BFD_JUMP_TABLE_LINK (_bfd_xcoff),
+ BFD_JUMP_TABLE_DYNAMIC (_bfd_xcoff),
+
+ /* Opposite endian version, none exists */
+ NULL,
+
+ & bfd_pmac_xcoff_backend_data,
+ };
diff --git a/bfd/coff-sh.c b/bfd/coff-sh.c
new file mode 100644
index 0000000..23e32ec
--- /dev/null
+++ b/bfd/coff-sh.c
@@ -0,0 +1,3206 @@
+/* BFD back-end for Renesas Super-H COFF binaries.
+ Copyright (C) 1993-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libiberty.h"
+#include "libbfd.h"
+#include "bfdlink.h"
+#include "coff/sh.h"
+#include "coff/internal.h"
+
+#undef bfd_pe_print_pdata
+
+#ifdef COFF_WITH_PE
+#include "coff/pe.h"
+
+#ifndef COFF_IMAGE_WITH_PE
+static bfd_boolean sh_align_load_span
+ (bfd *, asection *, bfd_byte *,
+ bfd_boolean (*) (bfd *, asection *, void *, bfd_byte *, bfd_vma),
+ void *, bfd_vma **, bfd_vma *, bfd_vma, bfd_vma, bfd_boolean *);
+
+#define _bfd_sh_align_load_span sh_align_load_span
+#endif
+
+#define bfd_pe_print_pdata _bfd_pe_print_ce_compressed_pdata
+
+#else
+
+#define bfd_pe_print_pdata NULL
+
+#endif /* COFF_WITH_PE. */
+
+#include "libcoff.h"
+
+/* Internal functions. */
+
+#ifdef COFF_WITH_PE
+/* Can't build import tables with 2**4 alignment. */
+#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER 2
+#else
+/* Default section alignment to 2**4. */
+#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER 4
+#endif
+
+#ifdef COFF_IMAGE_WITH_PE
+/* Align PE executables. */
+#define COFF_PAGE_SIZE 0x1000
+#endif
+
+/* Generate long file names. */
+#define COFF_LONG_FILENAMES
+
+#ifdef COFF_WITH_PE
+/* Return TRUE if this relocation should
+ appear in the output .reloc section. */
+
+static bfd_boolean
+in_reloc_p (bfd * abfd ATTRIBUTE_UNUSED,
+ reloc_howto_type * howto)
+{
+ return ! howto->pc_relative && howto->type != R_SH_IMAGEBASE;
+}
+#endif
+
+static bfd_reloc_status_type
+sh_reloc (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
+static bfd_boolean
+sh_relocate_section (bfd *, struct bfd_link_info *, bfd *, asection *,
+ bfd_byte *, struct internal_reloc *,
+ struct internal_syment *, asection **);
+static bfd_boolean
+sh_align_loads (bfd *, asection *, struct internal_reloc *,
+ bfd_byte *, bfd_boolean *);
+
+/* 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[] =
+{
+ EMPTY_HOWTO (0),
+ EMPTY_HOWTO (1),
+#ifdef COFF_WITH_PE
+ /* Windows CE */
+ HOWTO (R_SH_IMM32CE, /* 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_imm32ce", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+#else
+ EMPTY_HOWTO (2),
+#endif
+ EMPTY_HOWTO (3), /* R_SH_PCREL8 */
+ EMPTY_HOWTO (4), /* R_SH_PCREL16 */
+ EMPTY_HOWTO (5), /* R_SH_HIGH8 */
+ EMPTY_HOWTO (6), /* R_SH_IMM24 */
+ EMPTY_HOWTO (7), /* R_SH_LOW16 */
+ EMPTY_HOWTO (8),
+ EMPTY_HOWTO (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 */
+
+ EMPTY_HOWTO (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 */
+
+ EMPTY_HOWTO (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 */
+
+ EMPTY_HOWTO (15),
+#ifdef COFF_WITH_PE
+ HOWTO (R_SH_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 */
+ sh_reloc, /* special_function */
+ "rva32", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+#else
+ EMPTY_HOWTO (16), /* R_SH_IMM8 */
+#endif
+ EMPTY_HOWTO (17), /* R_SH_IMM8BY2 */
+ EMPTY_HOWTO (18), /* R_SH_IMM8BY4 */
+ EMPTY_HOWTO (19), /* R_SH_IMM4 */
+ EMPTY_HOWTO (20), /* R_SH_IMM4BY2 */
+ EMPTY_HOWTO (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__
+
+#ifndef COFF_WITH_PE
+/* Swap the r_offset field in and out. */
+#define SWAP_IN_RELOC_OFFSET H_GET_32
+#define SWAP_OUT_RELOC_OFFSET 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)
+#endif
+
+/* Get the value of a symbol, when performing a relocation. */
+
+static long
+get_symbol_value (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;
+}
+
+#ifdef COFF_WITH_PE
+/* Convert an rtype to howto for the COFF backend linker.
+ Copied from coff-i386. */
+#define coff_rtype_to_howto coff_sh_rtype_to_howto
+
+
+static reloc_howto_type *
+coff_sh_rtype_to_howto (bfd * abfd ATTRIBUTE_UNUSED,
+ asection * sec,
+ struct internal_reloc * rel,
+ struct coff_link_hash_entry * h,
+ struct internal_syment * sym,
+ bfd_vma * addendp)
+{
+ reloc_howto_type * howto;
+
+ howto = sh_coff_howtos + rel->r_type;
+
+ *addendp = 0;
+
+ 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);
+ }
+
+ 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_SH_IMAGEBASE)
+ *addendp -= pe_data (sec->output_section->owner)->pe_opthdr.ImageBase;
+
+ return howto;
+}
+
+#endif /* COFF_WITH_PE */
+
+/* This structure is used to map BFD reloc codes to SH PE relocs. */
+struct shcoff_reloc_map
+{
+ bfd_reloc_code_real_type bfd_reloc_val;
+ unsigned char shcoff_reloc_val;
+};
+
+#ifdef COFF_WITH_PE
+/* An array mapping BFD reloc codes to SH PE relocs. */
+static const struct shcoff_reloc_map sh_reloc_map[] =
+{
+ { BFD_RELOC_32, R_SH_IMM32CE },
+ { BFD_RELOC_RVA, R_SH_IMAGEBASE },
+ { BFD_RELOC_CTOR, R_SH_IMM32CE },
+};
+#else
+/* An array mapping BFD reloc codes to SH PE relocs. */
+static const struct shcoff_reloc_map sh_reloc_map[] =
+{
+ { BFD_RELOC_32, R_SH_IMM32 },
+ { BFD_RELOC_CTOR, R_SH_IMM32 },
+};
+#endif
+
+/* Given a BFD reloc code, return the howto structure for the
+ corresponding SH PE reloc. */
+#define coff_bfd_reloc_type_lookup sh_coff_reloc_type_lookup
+#define coff_bfd_reloc_name_lookup sh_coff_reloc_name_lookup
+
+static reloc_howto_type *
+sh_coff_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED,
+ bfd_reloc_code_real_type code)
+{
+ unsigned int i;
+
+ for (i = ARRAY_SIZE (sh_reloc_map); i--;)
+ if (sh_reloc_map[i].bfd_reloc_val == code)
+ return &sh_coff_howtos[(int) sh_reloc_map[i].shcoff_reloc_val];
+
+ (*_bfd_error_handler) (_("SH Error: unknown reloc type %d"), code);
+ return NULL;
+}
+
+static reloc_howto_type *
+sh_coff_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ const char *r_name)
+{
+ unsigned int i;
+
+ for (i = 0; i < sizeof (sh_coff_howtos) / sizeof (sh_coff_howtos[0]); i++)
+ if (sh_coff_howtos[i].name != NULL
+ && strcasecmp (sh_coff_howtos[i].name, r_name) == 0)
+ return &sh_coff_howtos[i];
+
+ return NULL;
+}
+
+/* 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 (bfd * abfd,
+ arelent * reloc_entry,
+ asymbol * symbol_in,
+ void * data,
+ asection * input_section,
+ bfd * output_bfd,
+ char ** error_message ATTRIBUTE_UNUSED)
+{
+ 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
+#ifdef COFF_WITH_PE
+ && r_type != R_SH_IMM32CE
+ && r_type != R_SH_IMAGEBASE
+#endif
+ && (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:
+#ifdef COFF_WITH_PE
+ case R_SH_IMM32CE:
+#endif
+ insn = bfd_get_32 (abfd, hit_data);
+ insn += sym_value + reloc_entry->addend;
+ bfd_put_32 (abfd, (bfd_vma) insn, hit_data);
+ break;
+#ifdef COFF_WITH_PE
+ case R_SH_IMAGEBASE:
+ insn = bfd_get_32 (abfd, hit_data);
+ insn += sym_value + reloc_entry->addend;
+ insn -= pe_data (input_section->output_section->owner)->pe_opthdr.ImageBase;
+ bfd_put_32 (abfd, (bfd_vma) insn, hit_data);
+ break;
+#endif
+ 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, (bfd_vma) insn, hit_data);
+ if (sym_value < (bfd_vma) -0x1000 || sym_value >= 0x1000)
+ return bfd_reloc_overflow;
+ break;
+ default:
+ abort ();
+ break;
+ }
+
+ return bfd_reloc_ok;
+}
+
+#define coff_bfd_merge_private_bfd_data _bfd_generic_verify_endian_match
+
+/* 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"
+
+static bfd_boolean
+sh_relax_delete_bytes (bfd *, asection *, bfd_vma, int);
+
+/* 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 bfd_boolean
+sh_relax_section (bfd *abfd,
+ asection *sec,
+ struct bfd_link_info *link_info,
+ bfd_boolean *again)
+{
+ struct internal_reloc *internal_relocs;
+ bfd_boolean have_code;
+ struct internal_reloc *irel, *irelend;
+ bfd_byte *contents = NULL;
+
+ *again = FALSE;
+
+ if (link_info->relocatable
+ || (sec->flags & SEC_RELOC) == 0
+ || sec->reloc_count == 0)
+ return TRUE;
+
+ if (coff_section_data (abfd, sec) == NULL)
+ {
+ bfd_size_type amt = sizeof (struct coff_section_tdata);
+ sec->used_by_bfd = bfd_zalloc (abfd, amt);
+ if (sec->used_by_bfd == NULL)
+ return FALSE;
+ }
+
+ 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;
+
+ 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)->contents != NULL)
+ contents = coff_section_data (abfd, sec)->contents;
+ else
+ {
+ if (!bfd_malloc_and_get_section (abfd, sec, &contents))
+ 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->size)
+ {
+ (*_bfd_error_handler) ("%B: 0x%lx: warning: bad R_SH_USES offset",
+ 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)
+ ("%B: 0x%lx: warning: R_SH_USES points to unrecognized insn 0x%x",
+ 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) &~ (bfd_vma) 3;
+ if (paddr >= sec->size)
+ {
+ ((*_bfd_error_handler)
+ ("%B: 0x%lx: warning: bad R_SH_USES load offset",
+ 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
+#ifdef COFF_WITH_PE
+ && (irelfn->r_type == R_SH_IMM32
+ || irelfn->r_type == R_SH_IMM32CE
+ || irelfn->r_type == R_SH_IMAGEBASE)
+
+#else
+ && irelfn->r_type == R_SH_IMM32
+#endif
+ )
+ break;
+ if (irelfn >= irelend)
+ {
+ ((*_bfd_error_handler)
+ ("%B: 0x%lx: warning: could not find expected reloc",
+ 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)
+ ("%B: 0x%lx: warning: symbol in unexpected section",
+ 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. */
+
+ coff_section_data (abfd, sec)->relocs = internal_relocs;
+ coff_section_data (abfd, sec)->keep_relocs = TRUE;
+
+ coff_section_data (abfd, sec)->contents = contents;
+ coff_section_data (abfd, sec)->keep_contents = TRUE;
+
+ 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,
+ (bfd_vma) 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, (bfd_vma) 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)
+ ("%B: 0x%lx: warning: could not find expected COUNT reloc",
+ 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) ("%B: 0x%lx: warning: bad count",
+ 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)
+ {
+ bfd_boolean swapped;
+
+ /* Get the section contents. */
+ if (contents == NULL)
+ {
+ if (coff_section_data (abfd, sec)->contents != NULL)
+ contents = coff_section_data (abfd, sec)->contents;
+ else
+ {
+ if (!bfd_malloc_and_get_section (abfd, sec, &contents))
+ goto error_return;
+ }
+ }
+
+ if (! sh_align_loads (abfd, sec, internal_relocs, contents, &swapped))
+ goto error_return;
+
+ if (swapped)
+ {
+ coff_section_data (abfd, sec)->relocs = internal_relocs;
+ coff_section_data (abfd, sec)->keep_relocs = TRUE;
+
+ coff_section_data (abfd, sec)->contents = contents;
+ coff_section_data (abfd, sec)->keep_contents = TRUE;
+
+ obj_coff_keep_syms (abfd) = TRUE;
+ }
+ }
+
+ if (internal_relocs != NULL
+ && internal_relocs != coff_section_data (abfd, sec)->relocs)
+ {
+ if (! link_info->keep_memory)
+ free (internal_relocs);
+ else
+ coff_section_data (abfd, sec)->relocs = internal_relocs;
+ }
+
+ if (contents != NULL && contents != coff_section_data (abfd, sec)->contents)
+ {
+ if (! link_info->keep_memory)
+ free (contents);
+ else
+ /* Cache the section contents for coff_link_input_bfd. */
+ coff_section_data (abfd, sec)->contents = contents;
+ }
+
+ return TRUE;
+
+ error_return:
+ if (internal_relocs != NULL
+ && internal_relocs != coff_section_data (abfd, sec)->relocs)
+ free (internal_relocs);
+ if (contents != NULL && contents != coff_section_data (abfd, sec)->contents)
+ free (contents);
+ return FALSE;
+}
+
+/* Delete some bytes from a section while relaxing. */
+
+static bfd_boolean
+sh_relax_delete_bytes (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->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,
+ (size_t) (toaddr - addr - count));
+ if (irelalign == NULL)
+ sec->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, (bfd_vma) 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;
+ bfd_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:
+#ifdef COFF_WITH_PE
+ case R_SH_IMM32CE:
+ case R_SH_IMAGEBASE:
+#endif
+ /* 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, (bfd_vma) insn, contents + nraddr);
+ break;
+
+ case R_SH_PCDISP:
+ insn += adjust / 2;
+ if ((oinsn & 0xf000) != (insn & 0xf000))
+ overflow = TRUE;
+ bfd_put_16 (abfd, (bfd_vma) 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, (bfd_vma) insn, contents + nraddr);
+ break;
+
+ case R_SH_SWITCH8:
+ voff += adjust;
+ if (voff < 0 || voff >= 0xff)
+ overflow = TRUE;
+ bfd_put_8 (abfd, (bfd_vma) voff, contents + nraddr);
+ break;
+
+ case R_SH_SWITCH16:
+ voff += adjust;
+ if (voff < - 0x8000 || voff >= 0x8000)
+ overflow = TRUE;
+ bfd_put_signed_16 (abfd, (bfd_vma) voff, contents + nraddr);
+ break;
+
+ case R_SH_SWITCH32:
+ voff += adjust;
+ bfd_put_signed_32 (abfd, (bfd_vma) voff, contents + nraddr);
+ break;
+
+ case R_SH_USES:
+ irel->r_offset += adjust;
+ break;
+ }
+
+ if (overflow)
+ {
+ ((*_bfd_error_handler)
+ ("%B: 0x%lx: fatal: reloc overflow while relaxing",
+ 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;
+
+#ifdef COFF_WITH_PE
+ if (irelscan->r_type != R_SH_IMM32
+ && irelscan->r_type != R_SH_IMAGEBASE
+ && irelscan->r_type != R_SH_IMM32CE)
+#else
+ if (irelscan->r_type != R_SH_IMM32)
+#endif
+ 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
+ {
+ if (!bfd_malloc_and_get_section (abfd, o, &ocontents))
+ return FALSE;
+ /* 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. */
+ 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)
+ ("%B: fatal: generic symbols retrieved before relaxing", 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, esym, &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, &isym, 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,
+ (int) (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 long 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)
+#define USES1_REG(x) ((x & 0x0f00) >> 8)
+
+/* This instruction uses the value in the register in the field at
+ mask 0x00f0 of the instruction. */
+#define USES2 (0x20)
+#define USES2_REG(x) ((x & 0x00f0) >> 4)
+
+/* 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)
+#define SETS1_REG(x) ((x & 0x0f00) >> 8)
+
+/* This instruction sets the value in the register in the field at
+ mask 0x00f0 of the instruction. */
+#define SETS2 (0x100)
+#define SETS2_REG(x) ((x & 0x00f0) >> 4)
+
+/* 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)
+#define USESF1_REG(x) ((x & 0x0f00) >> 8)
+
+/* This instruction uses the floating point register in the field at
+ mask 0x00f0 of the instruction. */
+#define USESF2 (0x2000)
+#define USESF2_REG(x) ((x & 0x00f0) >> 4)
+
+/* 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)
+#define SETSF1_REG(x) ((x & 0x0f00) >> 8)
+
+#define USESAS (0x10000)
+#define USESAS_REG(x) (((((x) >> 8) - 2) & 3) + 2)
+#define USESR8 (0x20000)
+#define SETSAS (0x40000)
+#define SETSAS_REG(x) USESAS_REG (x)
+
+#define MAP(a) a, sizeof a / sizeof a[0]
+
+#ifndef COFF_IMAGE_WITH_PE
+
+/* The opcode maps. */
+
+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[] =
+{
+ { 0x0003, BRANCH | DELAY | USES1 | SETSSP }, /* bsrf rn */
+ { 0x000a, SETS1 | USESSP }, /* sts mach,rn */
+ { 0x001a, SETS1 | USESSP }, /* sts macl,rn */
+ { 0x0023, BRANCH | DELAY | USES1 }, /* braf rn */
+ { 0x0029, SETS1 | USESSP }, /* movt rn */
+ { 0x002a, SETS1 | USESSP }, /* sts pr,rn */
+ { 0x005a, SETS1 | USESSP }, /* sts fpul,rn */
+ { 0x006a, SETS1 | USESSP }, /* sts fpscr,rn / sts dsr,rn */
+ { 0x0083, LOAD | USES1 }, /* pref @rn */
+ { 0x007a, SETS1 | USESSP }, /* sts a0,rn */
+ { 0x008a, SETS1 | USESSP }, /* sts x0,rn */
+ { 0x009a, SETS1 | USESSP }, /* sts x1,rn */
+ { 0x00aa, SETS1 | USESSP }, /* sts y0,rn */
+ { 0x00ba, SETS1 | USESSP } /* sts y1,rn */
+};
+
+static const struct sh_opcode sh_opcode02[] =
+{
+ { 0x0002, SETS1 | USESSP }, /* stc <special_reg>,rn */
+ { 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 */
+ { 0x4004, SETS1 | SETSSP | USES1 }, /* rotl rn */
+ { 0x4005, SETS1 | SETSSP | USES1 }, /* rotr rn */
+ { 0x4006, LOAD | SETS1 | SETSSP | USES1 }, /* lds.l @rm+,mach */
+ { 0x4008, SETS1 | USES1 }, /* shll2 rn */
+ { 0x4009, SETS1 | USES1 }, /* shlr2 rn */
+ { 0x400a, SETSSP | USES1 }, /* lds rm,mach */
+ { 0x400b, BRANCH | DELAY | USES1 }, /* jsr @rn */
+ { 0x4010, SETS1 | SETSSP | USES1 }, /* dt rn */
+ { 0x4011, SETSSP | USES1 }, /* cmp/pz rn */
+ { 0x4012, STORE | SETS1 | USES1 | USESSP }, /* sts.l macl,@-rn */
+ { 0x4014, SETSSP | USES1 }, /* setrc rm */
+ { 0x4015, SETSSP | USES1 }, /* cmp/pl rn */
+ { 0x4016, LOAD | SETS1 | SETSSP | USES1 }, /* lds.l @rm+,macl */
+ { 0x4018, SETS1 | USES1 }, /* shll8 rn */
+ { 0x4019, SETS1 | USES1 }, /* shlr8 rn */
+ { 0x401a, SETSSP | USES1 }, /* lds rm,macl */
+ { 0x401b, LOAD | SETSSP | USES1 }, /* tas.b @rn */
+ { 0x4020, SETS1 | SETSSP | USES1 }, /* shal rn */
+ { 0x4021, SETS1 | SETSSP | USES1 }, /* shar rn */
+ { 0x4022, STORE | SETS1 | USES1 | USESSP }, /* sts.l pr,@-rn */
+ { 0x4024, SETS1 | SETSSP | USES1 | USESSP }, /* rotcl rn */
+ { 0x4025, SETS1 | SETSSP | USES1 | USESSP }, /* rotcr rn */
+ { 0x4026, LOAD | SETS1 | SETSSP | USES1 }, /* lds.l @rm+,pr */
+ { 0x4028, SETS1 | USES1 }, /* shll16 rn */
+ { 0x4029, SETS1 | USES1 }, /* shlr16 rn */
+ { 0x402a, SETSSP | USES1 }, /* lds rm,pr */
+ { 0x402b, BRANCH | DELAY | USES1 }, /* jmp @rn */
+ { 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 / dsr,@-rn */
+ { 0x4066, LOAD | SETS1 | SETSSP | USES1 }, /* lds.l @rm+,fpscr / dsr */
+ { 0x406a, SETSSP | USES1 }, /* lds rm,fpscr / lds rm,dsr */
+ { 0x4072, STORE | SETS1 | USES1 | USESSP }, /* sts.l a0,@-rn */
+ { 0x4076, LOAD | SETS1 | SETSSP | USES1 }, /* lds.l @rm+,a0 */
+ { 0x407a, SETSSP | USES1 }, /* lds.l rm,a0 */
+ { 0x4082, STORE | SETS1 | USES1 | USESSP }, /* sts.l x0,@-rn */
+ { 0x4086, LOAD | SETS1 | SETSSP | USES1 }, /* lds.l @rm+,x0 */
+ { 0x408a, SETSSP | USES1 }, /* lds.l rm,x0 */
+ { 0x4092, STORE | SETS1 | USES1 | USESSP }, /* sts.l x1,@-rn */
+ { 0x4096, LOAD | SETS1 | SETSSP | USES1 }, /* lds.l @rm+,x1 */
+ { 0x409a, SETSSP | USES1 }, /* lds.l rm,x1 */
+ { 0x40a2, STORE | SETS1 | USES1 | USESSP }, /* sts.l y0,@-rn */
+ { 0x40a6, LOAD | SETS1 | SETSSP | USES1 }, /* lds.l @rm+,y0 */
+ { 0x40aa, SETSSP | USES1 }, /* lds.l rm,y0 */
+ { 0x40b2, STORE | SETS1 | USES1 | USESSP }, /* sts.l y1,@-rn */
+ { 0x40b6, LOAD | SETS1 | SETSSP | USES1 }, /* lds.l @rm+,y1 */
+ { 0x40ba, SETSSP | USES1 } /* lds.l rm,y1 */
+};
+
+static const struct sh_opcode sh_opcode41[] =
+{
+ { 0x4003, STORE | SETS1 | USES1 | USESSP }, /* stc.l <special_reg>,@-rn */
+ { 0x4007, LOAD | SETS1 | SETSSP | USES1 }, /* ldc.l @rm+,<special_reg> */
+ { 0x400c, SETS1 | USES1 | USES2 }, /* shad rm,rn */
+ { 0x400d, SETS1 | USES1 | USES2 }, /* shld rm,rn */
+ { 0x400e, SETSSP | USES1 }, /* ldc rm,<special_reg> */
+ { 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), 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) */
+ { 0x8200, SETSSP }, /* setrc #imm */
+ { 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 */
+ { 0x8c00, SETSSP }, /* ldrs @(disp,pc) */
+ { 0x8d00, BRANCH | DELAY | USESSP }, /* bt/s label */
+ { 0x8e00, SETSSP }, /* ldre @(disp,pc) */
+ { 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 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) }
+};
+
+/* The double data transfer / parallel processing insns are not
+ described here. This will cause sh_align_load_span to leave them alone. */
+
+static const struct sh_opcode sh_dsp_opcodef0[] =
+{
+ { 0xf400, USESAS | SETSAS | LOAD | SETSSP }, /* movs.x @-as,ds */
+ { 0xf401, USESAS | SETSAS | STORE | USESSP }, /* movs.x ds,@-as */
+ { 0xf404, USESAS | LOAD | SETSSP }, /* movs.x @as,ds */
+ { 0xf405, USESAS | STORE | USESSP }, /* movs.x ds,@as */
+ { 0xf408, USESAS | SETSAS | LOAD | SETSSP }, /* movs.x @as+,ds */
+ { 0xf409, USESAS | SETSAS | STORE | USESSP }, /* movs.x ds,@as+ */
+ { 0xf40c, USESAS | SETSAS | LOAD | SETSSP | USESR8 }, /* movs.x @as+r8,ds */
+ { 0xf40d, USESAS | SETSAS | STORE | USESSP | USESR8 } /* movs.x ds,@as+r8 */
+};
+
+static const struct sh_minor_opcode sh_dsp_opcodef[] =
+{
+ { MAP (sh_dsp_opcodef0), 0xfc0d }
+};
+
+/* 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 (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 bfd_boolean
+sh_insn_uses_reg (unsigned int insn,
+ const struct sh_opcode *op,
+ unsigned int reg)
+{
+ unsigned int f;
+
+ f = op->flags;
+
+ if ((f & USES1) != 0
+ && USES1_REG (insn) == reg)
+ return TRUE;
+ if ((f & USES2) != 0
+ && USES2_REG (insn) == reg)
+ return TRUE;
+ if ((f & USESR0) != 0
+ && reg == 0)
+ return TRUE;
+ if ((f & USESAS) && reg == USESAS_REG (insn))
+ return TRUE;
+ if ((f & USESR8) && reg == 8)
+ return TRUE;
+
+ return FALSE;
+}
+
+/* See whether an instruction sets a general purpose register. */
+
+static bfd_boolean
+sh_insn_sets_reg (unsigned int insn,
+ const struct sh_opcode *op,
+ unsigned int reg)
+{
+ unsigned int f;
+
+ f = op->flags;
+
+ if ((f & SETS1) != 0
+ && SETS1_REG (insn) == reg)
+ return TRUE;
+ if ((f & SETS2) != 0
+ && SETS2_REG (insn) == reg)
+ return TRUE;
+ if ((f & SETSR0) != 0
+ && reg == 0)
+ return TRUE;
+ if ((f & SETSAS) && reg == SETSAS_REG (insn))
+ return TRUE;
+
+ return FALSE;
+}
+
+/* See whether an instruction uses or sets a general purpose register */
+
+static bfd_boolean
+sh_insn_uses_or_sets_reg (unsigned int insn,
+ const struct sh_opcode *op,
+ unsigned int reg)
+{
+ if (sh_insn_uses_reg (insn, op, reg))
+ return TRUE;
+
+ return sh_insn_sets_reg (insn, op, reg);
+}
+
+/* See whether an instruction uses a floating point register. */
+
+static bfd_boolean
+sh_insn_uses_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
+ && (USESF1_REG (insn) & 0xe) == (freg & 0xe))
+ return TRUE;
+ if ((f & USESF2) != 0
+ && (USESF2_REG (insn) & 0xe) == (freg & 0xe))
+ return TRUE;
+ if ((f & USESF0) != 0
+ && freg == 0)
+ return TRUE;
+
+ return FALSE;
+}
+
+/* See whether an instruction sets a floating point register. */
+
+static bfd_boolean
+sh_insn_sets_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 & SETSF1) != 0
+ && (SETSF1_REG (insn) & 0xe) == (freg & 0xe))
+ return TRUE;
+
+ return FALSE;
+}
+
+/* See whether an instruction uses or sets a floating point register */
+
+static bfd_boolean
+sh_insn_uses_or_sets_freg (unsigned int insn,
+ const struct sh_opcode *op,
+ unsigned int reg)
+{
+ if (sh_insn_uses_freg (insn, op, reg))
+ return TRUE;
+
+ return sh_insn_sets_freg (insn, op, reg);
+}
+
+/* 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 bfd_boolean
+sh_insns_conflict (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 | f2) & SETSSP)
+ && (f1 & (SETSSP | USESSP))
+ && (f2 & (SETSSP | USESSP)))
+ return TRUE;
+
+ if ((f1 & SETS1) != 0
+ && sh_insn_uses_or_sets_reg (i2, op2, SETS1_REG (i1)))
+ return TRUE;
+ if ((f1 & SETS2) != 0
+ && sh_insn_uses_or_sets_reg (i2, op2, SETS2_REG (i1)))
+ return TRUE;
+ if ((f1 & SETSR0) != 0
+ && sh_insn_uses_or_sets_reg (i2, op2, 0))
+ return TRUE;
+ if ((f1 & SETSAS)
+ && sh_insn_uses_or_sets_reg (i2, op2, SETSAS_REG (i1)))
+ return TRUE;
+ if ((f1 & SETSF1) != 0
+ && sh_insn_uses_or_sets_freg (i2, op2, SETSF1_REG (i1)))
+ return TRUE;
+
+ if ((f2 & SETS1) != 0
+ && sh_insn_uses_or_sets_reg (i1, op1, SETS1_REG (i2)))
+ return TRUE;
+ if ((f2 & SETS2) != 0
+ && sh_insn_uses_or_sets_reg (i1, op1, SETS2_REG (i2)))
+ return TRUE;
+ if ((f2 & SETSR0) != 0
+ && sh_insn_uses_or_sets_reg (i1, op1, 0))
+ return TRUE;
+ if ((f2 & SETSAS)
+ && sh_insn_uses_or_sets_reg (i1, op1, SETSAS_REG (i2)))
+ return TRUE;
+ if ((f2 & SETSF1) != 0
+ && sh_insn_uses_or_sets_freg (i1, op1, SETSF1_REG (i2)))
+ 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 bfd_boolean
+sh_load_use (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. */
+
+#ifdef COFF_WITH_PE
+static
+#endif
+bfd_boolean
+_bfd_sh_align_load_span (bfd *abfd,
+ asection *sec,
+ bfd_byte *contents,
+ bfd_boolean (*swap) (bfd *, asection *, void *, bfd_byte *, bfd_vma),
+ void * relocs,
+ bfd_vma **plabel,
+ bfd_vma *label_end,
+ bfd_vma start,
+ bfd_vma stop,
+ bfd_boolean *pswapped)
+{
+ int dsp = (abfd->arch_info->mach == bfd_mach_sh_dsp
+ || abfd->arch_info->mach == bfd_mach_sh3_dsp);
+ bfd_vma i;
+
+ /* The SH4 has a Harvard architecture, hence aligning loads is not
+ desirable. In fact, it is counter-productive, since it interferes
+ with the schedules generated by the compiler. */
+ if (abfd->arch_info->mach == bfd_mach_sh4)
+ return TRUE;
+
+ /* If we are linking sh[3]-dsp code, swap the FPU instructions for DSP
+ instructions. */
+ if (dsp)
+ {
+ sh_opcodes[0xf].minor_opcodes = sh_dsp_opcodef;
+ sh_opcodes[0xf].count = sizeof sh_dsp_opcodef / sizeof sh_dsp_opcodef;
+ }
+
+ /* 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);
+ /* If INSN is the field b of a parallel processing insn, it is not
+ a load / store after all. Note that the test here might mistake
+ the field_b of a pcopy insn for the starting code of a parallel
+ processing insn; this might miss a swapping opportunity, but at
+ least we're on the safe side. */
+ if (dsp && (prev_insn & 0xfc00) == 0xf800)
+ continue;
+
+ /* Check if prev_insn is actually the field b of a parallel
+ processing insn. Again, this can give a spurious match
+ after a pcopy. */
+ if (dsp && i - 2 > start)
+ {
+ unsigned pprev_insn = bfd_get_16 (abfd, contents + i - 4);
+
+ if ((pprev_insn & 0xfc00) == 0xf800)
+ prev_op = NULL;
+ else
+ prev_op = sh_insn_info (prev_insn);
+ }
+ else
+ 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))
+ {
+ bfd_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))
+ {
+ bfd_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 == NULL
+ || ((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;
+}
+#endif /* not COFF_IMAGE_WITH_PE */
+
+/* Swap two SH instructions. */
+
+static bfd_boolean
+sh_swap_insns (bfd * abfd,
+ asection * sec,
+ void * 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, (bfd_vma) i2, contents + addr);
+ bfd_put_16 (abfd, (bfd_vma) 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;
+ bfd_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, (bfd_vma) 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, (bfd_vma) 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, (bfd_vma) insn, loc);
+ }
+
+ break;
+ }
+
+ if (overflow)
+ {
+ ((*_bfd_error_handler)
+ ("%B: 0x%lx: fatal: reloc overflow while relaxing",
+ abfd, (unsigned long) irel->r_vaddr));
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+ }
+ }
+
+ 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 bfd_boolean
+sh_align_loads (bfd *abfd,
+ asection *sec,
+ struct internal_reloc *internal_relocs,
+ bfd_byte *contents,
+ bfd_boolean *pswapped)
+{
+ struct internal_reloc *irel, *irelend;
+ bfd_vma *labels = NULL;
+ bfd_vma *label, *label_end;
+ bfd_size_type amt;
+
+ *pswapped = FALSE;
+
+ irelend = internal_relocs + sec->reloc_count;
+
+ /* Get all the addresses with labels on them. */
+ amt = (bfd_size_type) sec->reloc_count * sizeof (bfd_vma);
+ labels = (bfd_vma *) bfd_malloc (amt);
+ 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->size;
+
+ if (! _bfd_sh_align_load_span (abfd, sec, contents, sh_swap_insns,
+ internal_relocs, &label,
+ label_end, start, stop, pswapped))
+ goto error_return;
+ }
+
+ free (labels);
+
+ return TRUE;
+
+ error_return:
+ if (labels != NULL)
+ free (labels);
+ return FALSE;
+}
+
+/* This is a modification of _bfd_coff_generic_relocate_section, which
+ will handle SH relaxing. */
+
+static bfd_boolean
+sh_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
+ 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
+#ifdef COFF_WITH_PE
+ && rel->r_type != R_SH_IMM32CE
+ && rel->r_type != R_SH_IMAGEBASE
+#endif
+ && 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)
+ ("%B: illegal symbol index %ld in relocs",
+ 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;
+ }
+
+#ifdef COFF_WITH_PE
+ if (rel->r_type == R_SH_IMAGEBASE)
+ addend -= pe_data (input_section->output_section->owner)->pe_opthdr.ImageBase;
+#endif
+
+ 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->relocatable)
+ {
+ if (! ((*info->callbacks->undefined_symbol)
+ (info, h->root.root.string, input_bfd, input_section,
+ rel->r_vaddr - input_section->vma, TRUE)))
+ 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 = NULL;
+ 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, (h ? &h->root : NULL), 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 (bfd *output_bfd,
+ struct bfd_link_info *link_info,
+ struct bfd_link_order *link_order,
+ bfd_byte *data,
+ bfd_boolean relocatable,
+ 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 (relocatable
+ || 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,
+ relocatable,
+ symbols);
+
+ memcpy (data, coff_section_data (input_bfd, input_section)->contents,
+ (size_t) input_section->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;
+ bfd_size_type amt;
+
+ 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;
+
+ amt = obj_raw_syment_count (input_bfd);
+ amt *= sizeof (struct internal_syment);
+ internal_syms = (struct internal_syment *) bfd_malloc (amt);
+ if (internal_syms == NULL)
+ goto error_return;
+
+ amt = obj_raw_syment_count (input_bfd);
+ amt *= sizeof (asection *);
+ sections = (asection **) bfd_malloc (amt);
+ 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, esym, 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. */
+
+#ifndef TARGET_SHL_SYM
+CREATE_BIG_COFF_TARGET_VEC (sh_coff_vec, "coff-sh", BFD_IS_RELAXABLE, 0, '_', NULL, COFF_SWAP_TABLE)
+#endif
+
+#ifdef TARGET_SHL_SYM
+#define TARGET_SYM TARGET_SHL_SYM
+#else
+#define TARGET_SYM sh_coff_le_vec
+#endif
+
+#ifndef TARGET_SHL_NAME
+#define TARGET_SHL_NAME "coff-shl"
+#endif
+
+#ifdef COFF_WITH_PE
+CREATE_LITTLE_COFF_TARGET_VEC (TARGET_SYM, TARGET_SHL_NAME, BFD_IS_RELAXABLE,
+ SEC_CODE | SEC_DATA, '_', NULL, COFF_SWAP_TABLE);
+#else
+CREATE_LITTLE_COFF_TARGET_VEC (TARGET_SYM, TARGET_SHL_NAME, BFD_IS_RELAXABLE,
+ 0, '_', NULL, COFF_SWAP_TABLE)
+#endif
+
+#ifndef TARGET_SHL_SYM
+
+/* 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 (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 bfd_boolean
+coff_small_new_section_hook (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 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, FILNMLEN,
+#ifdef COFF_LONG_FILENAMES
+ TRUE,
+#else
+ FALSE,
+#endif
+ COFF_DEFAULT_LONG_SECTION_NAMES,
+ 2,
+#ifdef COFF_FORCE_SYMBOLS_IN_STRINGS
+ TRUE,
+#else
+ FALSE,
+#endif
+#ifdef COFF_DEBUG_STRING_WIDE_PREFIX
+ 4,
+#else
+ 2,
+#endif
+ 32768,
+ 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_classify_symbol, 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,
+ bfd_pe_print_pdata
+};
+
+#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
+
+extern const bfd_target sh_coff_small_le_vec;
+
+const bfd_target sh_coff_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 */
+ 0, /* match priority. */
+ 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),
+
+ & sh_coff_small_le_vec,
+
+ & bfd_coff_small_swap_table
+};
+
+const bfd_target sh_coff_small_le_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 */
+ 0, /* match priority. */
+ 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),
+
+ & sh_coff_small_vec,
+
+ & bfd_coff_small_swap_table
+};
+#endif
diff --git a/bfd/coff-sparc.c b/bfd/coff-sparc.c
new file mode 100644
index 0000000..031dcd0
--- /dev/null
+++ b/bfd/coff-sparc.c
@@ -0,0 +1,208 @@
+/* BFD back-end for Sparc COFF files.
+ Copyright (C) 1990-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.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
+ };
+
+/* This is stolen pretty directly from elf.c. */
+
+static bfd_reloc_status_type
+bfd_coff_generic_reloc (bfd *abfd ATTRIBUTE_UNUSED,
+ arelent *reloc_entry,
+ asymbol *symbol,
+ void * data ATTRIBUTE_UNUSED,
+ asection *input_section,
+ bfd *output_bfd,
+ char **error_message ATTRIBUTE_UNUSED)
+{
+ 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 (bfd *abfd ATTRIBUTE_UNUSED,
+ 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 reloc_howto_type *
+coff_sparc_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ const char *r_name)
+{
+ unsigned int i;
+
+ for (i = 0;
+ i < (sizeof (coff_sparc_howto_table)
+ / sizeof (coff_sparc_howto_table[0]));
+ i++)
+ if (coff_sparc_howto_table[i].name != NULL
+ && strcasecmp (coff_sparc_howto_table[i].name, r_name) == 0)
+ return &coff_sparc_howto_table[i];
+
+ return NULL;
+}
+#define coff_bfd_reloc_name_lookup coff_sparc_reloc_name_lookup
+
+static void
+rtype2howto (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 H_GET_32
+#define SWAP_OUT_RELOC_OFFSET 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
+
+#define bfd_pe_print_pdata NULL
+
+#include "coffcode.h"
+
+#ifndef TARGET_SYM
+#define TARGET_SYM sparc_coff_vec
+#endif
+
+#ifndef TARGET_NAME
+#define TARGET_NAME "coff-sparc"
+#endif
+
+CREATE_BIG_COFF_TARGET_VEC (TARGET_SYM, TARGET_NAME, D_PAGED, 0, '_', NULL, COFF_SWAP_TABLE)
diff --git a/bfd/coff-stgo32.c b/bfd/coff-stgo32.c
new file mode 100644
index 0000000..4dc9014
--- /dev/null
+++ b/bfd/coff-stgo32.c
@@ -0,0 +1,424 @@
+/* BFD back-end for Intel 386 COFF files (DJGPP variant with a stub).
+ Copyright (C) 1997-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, 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 i386_coff_go32stubbed_vec
+#define TARGET_NAME "coff-go32-exe"
+#define TARGET_UNDERSCORE '_'
+#define COFF_GO32_EXE
+#define COFF_LONG_SECTION_NAMES
+#define COFF_SUPPORT_GNU_LINKONCE
+#define COFF_LONG_FILENAMES
+
+#define COFF_SECTION_ALIGNMENT_ENTRIES \
+{ COFF_SECTION_NAME_EXACT_MATCH (".data"), \
+ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 4 }, \
+{ COFF_SECTION_NAME_EXACT_MATCH (".text"), \
+ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 4 }, \
+{ COFF_SECTION_NAME_PARTIAL_MATCH (".debug"), \
+ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 0 }, \
+{ COFF_SECTION_NAME_PARTIAL_MATCH (".gnu.linkonce.wi"), \
+ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 0 }
+
+#include "sysdep.h"
+#include "bfd.h"
+
+/* 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. */
+
+static void
+adjust_filehdr_in_post (bfd *, void *, void *);
+static void
+adjust_filehdr_out_pre (bfd *, void *, void *);
+static void
+adjust_filehdr_out_post (bfd *, void *, void *);
+static void
+adjust_scnhdr_in_post (bfd *, void *, void *);
+static void
+adjust_scnhdr_out_pre (bfd *, void *, void *);
+static void
+adjust_scnhdr_out_post (bfd *, void *, void *);
+static void
+adjust_aux_in_post (bfd *, void *, int, int, int, int, void *);
+static void
+adjust_aux_out_pre (bfd *, void *, int, int, int, int, void *);
+static void
+adjust_aux_out_post (bfd *, void *, int, int, int, int, void *);
+static void
+create_go32_stub (bfd *);
+
+#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 const bfd_target *go32_check_format (bfd *);
+
+#define COFF_CHECK_FORMAT go32_check_format
+
+static bfd_boolean
+ go32_stubbed_coff_bfd_copy_private_bfd_data (bfd *, bfd *);
+
+#define coff_bfd_copy_private_bfd_data go32_stubbed_coff_bfd_copy_private_bfd_data
+
+#include "coff-i386.c"
+
+/* This macro is used, because I cannot assume the endianness of the
+ host system. */
+#define _H(index) (H_GET_16 (abfd, (header + index * 2)))
+
+/* These bytes are a 2048-byte DOS executable, which loads the COFF
+ image into memory and then runs it. It is called 'stub'. */
+
+static const unsigned char stub_bytes[GO32_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 GO32_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 (bfd * abfd ATTRIBUTE_UNUSED,
+ void * src,
+ void * dst)
+{
+ FILHDR *filehdr_src = (FILHDR *) src;
+ struct internal_filehdr *filehdr_dst = (struct internal_filehdr *) dst;
+
+ ADJUST_VAL (filehdr_dst->f_symptr, GO32_STUBSIZE);
+
+ /* Save now the stub to be used later. Put the stub data to FILEHDR_DST
+ first as coff_data (abfd) still does not exist. It may not even be ever
+ created as we are just checking the file format of ABFD. */
+ memcpy (filehdr_dst->go32stub, filehdr_src->stub, GO32_STUBSIZE);
+ filehdr_dst->f_flags |= F_GO32STUB;
+}
+
+static void
+adjust_filehdr_out_pre (bfd * abfd, void * in, void * 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 (coff_data (abfd)->go32stub != NULL)
+ memcpy (filehdr_out->stub, coff_data (abfd)->go32stub, GO32_STUBSIZE);
+ else
+ /* Use the default. */
+ memcpy (filehdr_out->stub, stub_bytes, GO32_STUBSIZE);
+
+ ADJUST_VAL (filehdr_in->f_symptr, -GO32_STUBSIZE);
+}
+
+static void
+adjust_filehdr_out_post (bfd * abfd ATTRIBUTE_UNUSED,
+ void * in,
+ void * out ATTRIBUTE_UNUSED)
+{
+ struct internal_filehdr *filehdr_in = (struct internal_filehdr *) in;
+ /* Undo the above change. */
+ ADJUST_VAL (filehdr_in->f_symptr, GO32_STUBSIZE);
+}
+
+static void
+adjust_scnhdr_in_post (bfd * abfd ATTRIBUTE_UNUSED,
+ void * ext ATTRIBUTE_UNUSED,
+ void * in)
+{
+ struct internal_scnhdr *scnhdr_int = (struct internal_scnhdr *) in;
+
+ ADJUST_VAL (scnhdr_int->s_scnptr, GO32_STUBSIZE);
+ ADJUST_VAL (scnhdr_int->s_relptr, GO32_STUBSIZE);
+ ADJUST_VAL (scnhdr_int->s_lnnoptr, GO32_STUBSIZE);
+}
+
+static void
+adjust_scnhdr_out_pre (bfd * abfd ATTRIBUTE_UNUSED,
+ void * in,
+ void * out ATTRIBUTE_UNUSED)
+{
+ struct internal_scnhdr *scnhdr_int = (struct internal_scnhdr *) in;
+
+ ADJUST_VAL (scnhdr_int->s_scnptr, -GO32_STUBSIZE);
+ ADJUST_VAL (scnhdr_int->s_relptr, -GO32_STUBSIZE);
+ ADJUST_VAL (scnhdr_int->s_lnnoptr, -GO32_STUBSIZE);
+}
+
+static void
+adjust_scnhdr_out_post (bfd * abfd ATTRIBUTE_UNUSED,
+ void * in,
+ void * out ATTRIBUTE_UNUSED)
+{
+ struct internal_scnhdr *scnhdr_int = (struct internal_scnhdr *) in;
+
+ ADJUST_VAL (scnhdr_int->s_scnptr, GO32_STUBSIZE);
+ ADJUST_VAL (scnhdr_int->s_relptr, GO32_STUBSIZE);
+ ADJUST_VAL (scnhdr_int->s_lnnoptr, GO32_STUBSIZE);
+}
+
+static void
+adjust_aux_in_post (bfd * abfd ATTRIBUTE_UNUSED,
+ void * ext1 ATTRIBUTE_UNUSED,
+ int type,
+ int in_class,
+ int indx ATTRIBUTE_UNUSED,
+ int numaux ATTRIBUTE_UNUSED,
+ void * in1)
+{
+ union internal_auxent *in = (union internal_auxent *) in1;
+
+ if (in_class == C_BLOCK || in_class == C_FCN || ISFCN (type)
+ || ISTAG (in_class))
+ {
+ ADJUST_VAL (in->x_sym.x_fcnary.x_fcn.x_lnnoptr, GO32_STUBSIZE);
+ }
+}
+
+static void
+adjust_aux_out_pre (bfd *abfd ATTRIBUTE_UNUSED,
+ void * inp,
+ int type,
+ int in_class,
+ int indx ATTRIBUTE_UNUSED,
+ int numaux ATTRIBUTE_UNUSED,
+ void * extp ATTRIBUTE_UNUSED)
+{
+ union internal_auxent *in = (union internal_auxent *) inp;
+
+ if (in_class == C_BLOCK || in_class == C_FCN || ISFCN (type)
+ || ISTAG (in_class))
+ {
+ ADJUST_VAL (in->x_sym.x_fcnary.x_fcn.x_lnnoptr, -GO32_STUBSIZE);
+ }
+}
+
+static void
+adjust_aux_out_post (bfd *abfd ATTRIBUTE_UNUSED,
+ void * inp,
+ int type,
+ int in_class,
+ int indx ATTRIBUTE_UNUSED,
+ int numaux ATTRIBUTE_UNUSED,
+ void * extp ATTRIBUTE_UNUSED)
+{
+ union internal_auxent *in = (union internal_auxent *) inp;
+
+ if (in_class == C_BLOCK || in_class == C_FCN || ISFCN (type)
+ || ISTAG (in_class))
+ {
+ ADJUST_VAL (in->x_sym.x_fcnary.x_fcn.x_lnnoptr, GO32_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 (bfd *abfd)
+{
+ /* Do it only once. */
+ if (coff_data (abfd)->go32stub == NULL)
+ {
+ char *stub;
+ struct stat st;
+ int f;
+ unsigned char header[10];
+ char magic[8];
+ unsigned long coff_start;
+ long 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 ((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 (! CONST_STRNEQ (magic, "go32stub"))
+ {
+ close (f);
+ goto stub_end;
+ }
+ /* Now we found a correct stub (hopefully). */
+ coff_data (abfd)->go32stub = bfd_alloc (abfd, (bfd_size_type) coff_start);
+ if (coff_data (abfd)->go32stub == NULL)
+ {
+ close (f);
+ return;
+ }
+ lseek (f, 0L, SEEK_SET);
+ if ((unsigned long) read (f, coff_data (abfd)->go32stub, coff_start)
+ != coff_start)
+ {
+ bfd_release (abfd, coff_data (abfd)->go32stub);
+ coff_data (abfd)->go32stub = NULL;
+ }
+ close (f);
+ }
+stub_end:
+ /* There was something wrong above, so use now the standard builtin
+ stub. */
+ if (coff_data (abfd)->go32stub == NULL)
+ {
+ coff_data (abfd)->go32stub
+ = bfd_alloc (abfd, (bfd_size_type) GO32_STUBSIZE);
+ if (coff_data (abfd)->go32stub == NULL)
+ return;
+ memcpy (coff_data (abfd)->go32stub, stub_bytes, GO32_STUBSIZE);
+ }
+}
+
+/* If ibfd was a stubbed coff image, copy the stub from that bfd
+ to the new obfd. */
+
+static bfd_boolean
+go32_stubbed_coff_bfd_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
+{
+ /* Check if both are the same targets. */
+ if (ibfd->xvec != obfd->xvec)
+ return TRUE;
+
+ /* Check if we have a source stub. */
+ if (coff_data (ibfd)->go32stub == NULL)
+ return TRUE;
+
+ /* As adjust_filehdr_out_pre may get called only after this function,
+ optionally allocate the output stub. */
+ if (coff_data (obfd)->go32stub == NULL)
+ coff_data (obfd)->go32stub = bfd_alloc (obfd,
+ (bfd_size_type) GO32_STUBSIZE);
+
+ /* Now copy the stub. */
+ if (coff_data (obfd)->go32stub != NULL)
+ memcpy (coff_data (obfd)->go32stub, coff_data (ibfd)->go32stub,
+ GO32_STUBSIZE);
+
+ return TRUE;
+}
+
+/* coff_object_p only checks 2 bytes F_MAGIC at GO32_STUBSIZE inside the file
+ which is too fragile. */
+
+static const bfd_target *
+go32_check_format (bfd *abfd)
+{
+ char mz[2];
+
+ if (bfd_bread (mz, 2, abfd) != 2 || mz[0] != 'M' || mz[1] != 'Z')
+ {
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+
+ if (bfd_seek (abfd, 0, SEEK_SET) != 0)
+ return NULL;
+
+ return coff_object_p (abfd);
+}
diff --git a/bfd/coff-svm68k.c b/bfd/coff-svm68k.c
new file mode 100644
index 0000000..f759abb
--- /dev/null
+++ b/bfd/coff-svm68k.c
@@ -0,0 +1,27 @@
+/* BFD back-end for Motorola sysv68
+ Copyright (C) 1997-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#define TARGET_SYM m68k_coff_sysv_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 0000000..740c82c
--- /dev/null
+++ b/bfd/coff-tic30.c
@@ -0,0 +1,222 @@
+/* BFD back-end for TMS320C30 coff binaries.
+ Copyright (C) 1998-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
+ 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.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),
+ EMPTY_HOWTO (-1)
+ };
+
+#ifndef coff_bfd_reloc_type_lookup
+#define coff_bfd_reloc_type_lookup tic30_coff_reloc_type_lookup
+#define coff_bfd_reloc_name_lookup tic30_coff_reloc_name_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. */
+
+static reloc_howto_type *
+tic30_coff_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ 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;
+ }
+}
+
+static reloc_howto_type *
+tic30_coff_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ const char *r_name)
+{
+ unsigned int i;
+
+ for (i = 0;
+ i < (sizeof (tic30_coff_howto_table)
+ / sizeof (tic30_coff_howto_table[0]));
+ i++)
+ if (tic30_coff_howto_table[i].name != NULL
+ && strcasecmp (tic30_coff_howto_table[i].name, r_name) == 0)
+ return &tic30_coff_howto_table[i];
+
+ return NULL;
+}
+
+#endif
+
+/* Turn a howto into a reloc number. */
+
+static int
+coff_tic30_select_reloc (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 H_GET_32
+#define SWAP_OUT_RELOC_OFFSET 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 (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 (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;
+}
+
+#ifndef bfd_pe_print_pdata
+#define bfd_pe_print_pdata NULL
+#endif
+
+#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 */
+ 0, /* match priority. */
+ 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),
+
+ NULL,
+
+ COFF_SWAP_TABLE
+};
diff --git a/bfd/coff-tic4x.c b/bfd/coff-tic4x.c
new file mode 100644
index 0000000..1e7166f
--- /dev/null
+++ b/bfd/coff-tic4x.c
@@ -0,0 +1,290 @@
+/* BFD back-end for TMS320C4X coff binaries.
+ Copyright (C) 1996-2014 Free Software Foundation, Inc.
+
+ Contributed by Michael Hayes (m.hayes@elec.canterbury.ac.nz)
+
+ This file is part of BFD, the Binary File Descriptor library.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
+ 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+#include "bfdlink.h"
+#include "coff/tic4x.h"
+#include "coff/internal.h"
+#include "libcoff.h"
+
+#undef F_LSYMS
+#define F_LSYMS F_LSYMS_TICOFF
+
+static reloc_howto_type *
+coff_tic4x_rtype_to_howto (bfd *, asection *, struct internal_reloc *,
+ struct coff_link_hash_entry *,
+ struct internal_syment *, bfd_vma *);
+static void
+tic4x_reloc_processing (arelent *, struct internal_reloc *,
+ asymbol **, bfd *, asection *);
+
+/* Replace the stock _bfd_coff_is_local_label_name to recognize TI COFF local
+ labels. */
+static bfd_boolean
+ticoff_bfd_is_local_label_name (bfd *abfd ATTRIBUTE_UNUSED,
+ const char *name)
+{
+ if (TICOFF_LOCAL_LABEL_P(name))
+ return TRUE;
+ return FALSE;
+}
+
+#define coff_bfd_is_local_label_name ticoff_bfd_is_local_label_name
+
+#define RELOC_PROCESSING(RELENT,RELOC,SYMS,ABFD,SECT)\
+ tic4x_reloc_processing (RELENT,RELOC,SYMS,ABFD,SECT)
+
+/* Customize coffcode.h; the default coff_ functions are set up to use
+ COFF2; coff_bad_format_hook uses BADMAG, so set that for COFF2.
+ The COFF1 and COFF0 vectors use custom _bad_format_hook procs
+ instead of setting BADMAG. */
+#define BADMAG(x) COFF2_BADMAG(x)
+
+#undef coff_rtype_to_howto
+#define coff_rtype_to_howto coff_tic4x_rtype_to_howto
+
+#ifndef bfd_pe_print_pdata
+#define bfd_pe_print_pdata NULL
+#endif
+
+#include "coffcode.h"
+
+static bfd_reloc_status_type
+tic4x_relocation (bfd *abfd ATTRIBUTE_UNUSED,
+ arelent *reloc_entry,
+ asymbol *symbol ATTRIBUTE_UNUSED,
+ void * data ATTRIBUTE_UNUSED,
+ asection *input_section,
+ bfd *output_bfd,
+ char **error_message ATTRIBUTE_UNUSED)
+{
+ 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;
+ }
+ return bfd_reloc_continue;
+}
+
+reloc_howto_type tic4x_howto_table[] =
+{
+ HOWTO(R_RELWORD, 0, 2, 16, FALSE, 0, complain_overflow_signed, tic4x_relocation, "RELWORD", TRUE, 0x0000ffff, 0x0000ffff, FALSE),
+ HOWTO(R_REL24, 0, 2, 24, FALSE, 0, complain_overflow_bitfield, tic4x_relocation, "REL24", TRUE, 0x00ffffff, 0x00ffffff, FALSE),
+ HOWTO(R_RELLONG, 0, 2, 32, FALSE, 0, complain_overflow_dont, tic4x_relocation, "RELLONG", TRUE, 0xffffffff, 0xffffffff, FALSE),
+ HOWTO(R_PCRWORD, 0, 2, 16, TRUE, 0, complain_overflow_signed, tic4x_relocation, "PCRWORD", TRUE, 0x0000ffff, 0x0000ffff, FALSE),
+ HOWTO(R_PCR24, 0, 2, 24, TRUE, 0, complain_overflow_signed, tic4x_relocation, "PCR24", TRUE, 0x00ffffff, 0x00ffffff, FALSE),
+ HOWTO(R_PARTLS16, 0, 2, 16, FALSE, 0, complain_overflow_dont, tic4x_relocation, "PARTLS16", TRUE, 0x0000ffff, 0x0000ffff, FALSE),
+ HOWTO(R_PARTMS8, 16, 2, 16, FALSE, 0, complain_overflow_dont, tic4x_relocation, "PARTMS8", TRUE, 0x0000ffff, 0x0000ffff, FALSE),
+ HOWTO(R_RELWORD, 0, 2, 16, FALSE, 0, complain_overflow_signed, tic4x_relocation, "ARELWORD", TRUE, 0x0000ffff, 0x0000ffff, FALSE),
+ HOWTO(R_REL24, 0, 2, 24, FALSE, 0, complain_overflow_signed, tic4x_relocation, "AREL24", TRUE, 0x00ffffff, 0x00ffffff, FALSE),
+ HOWTO(R_RELLONG, 0, 2, 32, FALSE, 0, complain_overflow_signed, tic4x_relocation, "ARELLONG", TRUE, 0xffffffff, 0xffffffff, FALSE),
+ HOWTO(R_PCRWORD, 0, 2, 16, TRUE, 0, complain_overflow_signed, tic4x_relocation, "APCRWORD", TRUE, 0x0000ffff, 0x0000ffff, FALSE),
+ HOWTO(R_PCR24, 0, 2, 24, TRUE, 0, complain_overflow_signed, tic4x_relocation, "APCR24", TRUE, 0x00ffffff, 0x00ffffff, FALSE),
+ HOWTO(R_PARTLS16, 0, 2, 16, FALSE, 0, complain_overflow_dont, tic4x_relocation, "APARTLS16", TRUE, 0x0000ffff, 0x0000ffff, FALSE),
+ HOWTO(R_PARTMS8, 16, 2, 16, FALSE, 0, complain_overflow_dont, tic4x_relocation, "APARTMS8", TRUE, 0x0000ffff, 0x0000ffff, FALSE),
+};
+#define HOWTO_SIZE (sizeof(tic4x_howto_table) / sizeof(tic4x_howto_table[0]))
+
+#undef coff_bfd_reloc_type_lookup
+#define coff_bfd_reloc_type_lookup tic4x_coff_reloc_type_lookup
+#undef coff_bfd_reloc_name_lookup
+#define coff_bfd_reloc_name_lookup tic4x_coff_reloc_name_lookup
+
+/* For the case statement use the code values used tc_gen_reloc (defined in
+ bfd/reloc.c) to map to the howto table entries. */
+
+static reloc_howto_type *
+tic4x_coff_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ bfd_reloc_code_real_type code)
+{
+ unsigned int type;
+ unsigned int i;
+
+ switch (code)
+ {
+ case BFD_RELOC_32: type = R_RELLONG; break;
+ case BFD_RELOC_24: type = R_REL24; break;
+ case BFD_RELOC_16: type = R_RELWORD; break;
+ case BFD_RELOC_24_PCREL: type = R_PCR24; break;
+ case BFD_RELOC_16_PCREL: type = R_PCRWORD; break;
+ case BFD_RELOC_HI16: type = R_PARTMS8; break;
+ case BFD_RELOC_LO16: type = R_PARTLS16; break;
+ default:
+ return NULL;
+ }
+
+ for (i = 0; i < HOWTO_SIZE; i++)
+ {
+ if (tic4x_howto_table[i].type == type)
+ return tic4x_howto_table + i;
+ }
+ return NULL;
+}
+
+static reloc_howto_type *
+tic4x_coff_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ const char *r_name)
+{
+ unsigned int i;
+
+ for (i = 0;
+ i < sizeof (tic4x_howto_table) / sizeof (tic4x_howto_table[0]);
+ i++)
+ if (tic4x_howto_table[i].name != NULL
+ && strcasecmp (tic4x_howto_table[i].name, r_name) == 0)
+ return &tic4x_howto_table[i];
+
+ return NULL;
+}
+
+/* Code to turn a r_type into a howto ptr, uses the above howto table.
+ Called after some initial checking by the tic4x_rtype_to_howto fn
+ below. */
+static void
+tic4x_lookup_howto (arelent *internal,
+ struct internal_reloc *dst)
+{
+ unsigned int i;
+ int bank = (dst->r_symndx == -1) ? HOWTO_BANK : 0;
+
+ for (i = 0; i < HOWTO_SIZE; i++)
+ {
+ if (tic4x_howto_table[i].type == dst->r_type)
+ {
+ internal->howto = tic4x_howto_table + i + bank;
+ return;
+ }
+ }
+
+ (*_bfd_error_handler) (_("Unrecognized reloc type 0x%x"),
+ (unsigned int) dst->r_type);
+ abort();
+}
+
+static reloc_howto_type *
+coff_tic4x_rtype_to_howto (bfd *abfd ATTRIBUTE_UNUSED,
+ asection *sec,
+ struct internal_reloc *rel,
+ struct coff_link_hash_entry *h ATTRIBUTE_UNUSED,
+ struct internal_syment *sym ATTRIBUTE_UNUSED,
+ 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;
+
+ tic4x_lookup_howto (&genrel, rel);
+
+ return genrel.howto;
+}
+
+
+static void
+tic4x_reloc_processing (arelent *relent,
+ struct internal_reloc *reloc,
+ asymbol **symbols,
+ bfd *abfd,
+ asection *section)
+{
+ asymbol *ptr;
+
+ relent->address = reloc->r_vaddr;
+
+ if (reloc->r_symndx != -1)
+ {
+ if (reloc->r_symndx < 0 || reloc->r_symndx >= obj_conv_table_size (abfd))
+ {
+ (*_bfd_error_handler)
+ (_("%s: warning: illegal symbol index %ld in relocs"),
+ bfd_get_filename (abfd), reloc->r_symndx);
+ relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
+ ptr = NULL;
+ }
+ else
+ {
+ relent->sym_ptr_ptr = (symbols
+ + obj_convert (abfd)[reloc->r_symndx]);
+ ptr = *(relent->sym_ptr_ptr);
+ }
+ }
+ else
+ {
+ relent->sym_ptr_ptr = section->symbol_ptr_ptr;
+ ptr = *(relent->sym_ptr_ptr);
+ }
+
+ /* 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, *reloc, relent);
+
+ relent->address -= section->vma;
+ /* !! relent->section = (asection *) NULL; */
+
+ /* Fill in the relent->howto field from reloc->r_type. */
+ tic4x_lookup_howto (relent, reloc);
+}
+
+
+/* TI COFF v0, DOS tools (little-endian headers). */
+CREATE_LITTLE_COFF_TARGET_VEC(tic4x_coff0_vec, "coff0-tic4x",
+ 0, SEC_CODE | SEC_READONLY, '_',
+ NULL, &ticoff0_swap_table);
+
+/* TI COFF v0, SPARC tools (big-endian headers). */
+CREATE_BIGHDR_COFF_TARGET_VEC(tic4x_coff0_beh_vec, "coff0-beh-tic4x",
+ 0, SEC_CODE | SEC_READONLY, '_',
+ &tic4x_coff0_vec, &ticoff0_swap_table);
+
+/* TI COFF v1, DOS tools (little-endian headers). */
+CREATE_LITTLE_COFF_TARGET_VEC(tic4x_coff1_vec, "coff1-tic4x",
+ 0, SEC_CODE | SEC_READONLY, '_',
+ &tic4x_coff0_beh_vec, &ticoff1_swap_table);
+
+/* TI COFF v1, SPARC tools (big-endian headers). */
+CREATE_BIGHDR_COFF_TARGET_VEC(tic4x_coff1_beh_vec, "coff1-beh-tic4x",
+ 0, SEC_CODE | SEC_READONLY, '_',
+ &tic4x_coff1_vec, &ticoff1_swap_table);
+
+/* TI COFF v2, TI DOS tools output (little-endian headers). */
+CREATE_LITTLE_COFF_TARGET_VEC(tic4x_coff2_vec, "coff2-tic4x",
+ 0, SEC_CODE | SEC_READONLY, '_',
+ &tic4x_coff1_beh_vec, COFF_SWAP_TABLE);
+
+/* TI COFF v2, TI SPARC tools output (big-endian headers). */
+CREATE_BIGHDR_COFF_TARGET_VEC(tic4x_coff2_beh_vec, "coff2-beh-tic4x",
+ 0, SEC_CODE | SEC_READONLY, '_',
+ &tic4x_coff2_vec, COFF_SWAP_TABLE);
diff --git a/bfd/coff-tic54x.c b/bfd/coff-tic54x.c
new file mode 100644
index 0000000..3027c9e
--- /dev/null
+++ b/bfd/coff-tic54x.c
@@ -0,0 +1,672 @@
+/* BFD back-end for TMS320C54X coff binaries.
+ Copyright (C) 1999-2014 Free Software Foundation, Inc.
+ Contributed by Timothy Wall (twall@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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
+ 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+#include "bfdlink.h"
+#include "coff/tic54x.h"
+#include "coff/internal.h"
+#include "libcoff.h"
+
+#undef F_LSYMS
+#define F_LSYMS F_LSYMS_TICOFF
+
+static void
+tic54x_reloc_processing (arelent *, struct internal_reloc *,
+ asymbol **, bfd *, asection *);
+
+/* 32-bit operations
+ The octet order is screwy. words are LSB first (LS octet, actually), but
+ longwords are MSW first. For example, 0x12345678 is encoded 0x5678 in the
+ first word and 0x1234 in the second. When looking at the data as stored in
+ the COFF file, you would see the octets ordered as 0x78, 0x56, 0x34, 0x12.
+ Don't bother with 64-bits, as there aren't any. */
+
+static bfd_vma
+tic54x_getl32 (const void *p)
+{
+ const bfd_byte *addr = p;
+ unsigned long v;
+
+ v = (unsigned long) addr[2];
+ v |= (unsigned long) addr[3] << 8;
+ v |= (unsigned long) addr[0] << 16;
+ v |= (unsigned long) addr[1] << 24;
+ return v;
+}
+
+static void
+tic54x_putl32 (bfd_vma data, void *p)
+{
+ bfd_byte *addr = p;
+ addr[2] = data & 0xff;
+ addr[3] = (data >> 8) & 0xff;
+ addr[0] = (data >> 16) & 0xff;
+ addr[1] = (data >> 24) & 0xff;
+}
+
+static bfd_signed_vma
+tic54x_getl_signed_32 (const void *p)
+{
+ const bfd_byte *addr = p;
+ unsigned long v;
+
+ v = (unsigned long) addr[2];
+ v |= (unsigned long) addr[3] << 8;
+ v |= (unsigned long) addr[0] << 16;
+ v |= (unsigned long) addr[1] << 24;
+#define COERCE32(x) \
+ ((bfd_signed_vma) (long) (((unsigned long) (x) ^ 0x80000000) - 0x80000000))
+ return COERCE32 (v);
+}
+
+#define coff_get_section_load_page bfd_ticoff_get_section_load_page
+#define coff_set_section_load_page bfd_ticoff_set_section_load_page
+
+void
+bfd_ticoff_set_section_load_page (asection *sect,
+ int page)
+{
+ sect->lma = (sect->lma & ADDR_MASK) | PG_TO_FLAG(page);
+}
+
+int
+bfd_ticoff_get_section_load_page (asection *sect)
+{
+ int page;
+
+ /* Provide meaningful defaults for predefined sections. */
+ if (sect == bfd_com_section_ptr)
+ page = PG_DATA;
+
+ else if (bfd_is_und_section (sect)
+ || bfd_is_abs_section (sect)
+ || bfd_is_ind_section (sect))
+ page = PG_PROG;
+
+ else
+ page = FLAG_TO_PG (sect->lma);
+
+ return page;
+}
+
+/* Set the architecture appropriately. Allow unkown architectures
+ (e.g. binary). */
+
+static bfd_boolean
+tic54x_set_arch_mach (bfd *abfd,
+ enum bfd_architecture arch,
+ unsigned long machine)
+{
+ if (arch == bfd_arch_unknown)
+ arch = bfd_arch_tic54x;
+
+ else if (arch != bfd_arch_tic54x)
+ return FALSE;
+
+ return bfd_default_set_arch_mach (abfd, arch, machine);
+}
+
+static bfd_reloc_status_type
+tic54x_relocation (bfd *abfd ATTRIBUTE_UNUSED,
+ arelent *reloc_entry,
+ asymbol *symbol ATTRIBUTE_UNUSED,
+ void * data ATTRIBUTE_UNUSED,
+ asection *input_section,
+ bfd *output_bfd,
+ char **error_message ATTRIBUTE_UNUSED)
+{
+ 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;
+ }
+ return bfd_reloc_continue;
+}
+
+reloc_howto_type tic54x_howto_table[] =
+ {
+ /* type,rightshift,size (0=byte, 1=short, 2=long),
+ bit size, pc_relative, bitpos, dont complain_on_overflow,
+ special_function, name, partial_inplace, src_mask, dst_mask, pcrel_offset. */
+
+ /* NORMAL BANK */
+ /* 16-bit direct reference to symbol's address. */
+ HOWTO (R_RELWORD,0,1,16,FALSE,0,complain_overflow_dont,
+ tic54x_relocation,"REL16",FALSE,0xFFFF,0xFFFF,FALSE),
+
+ /* 7 LSBs of an address */
+ HOWTO (R_PARTLS7,0,1,7,FALSE,0,complain_overflow_dont,
+ tic54x_relocation,"LS7",FALSE,0x007F,0x007F,FALSE),
+
+ /* 9 MSBs of an address */
+ /* TI assembler doesn't shift its encoding, and is thus incompatible */
+ HOWTO (R_PARTMS9,7,1,9,FALSE,0,complain_overflow_dont,
+ tic54x_relocation,"MS9",FALSE,0x01FF,0x01FF,FALSE),
+
+ /* 23-bit relocation */
+ HOWTO (R_EXTWORD,0,2,23,FALSE,0,complain_overflow_dont,
+ tic54x_relocation,"RELEXT",FALSE,0x7FFFFF,0x7FFFFF,FALSE),
+
+ /* 16 bits of 23-bit extended address */
+ HOWTO (R_EXTWORD16,0,1,16,FALSE,0,complain_overflow_dont,
+ tic54x_relocation,"RELEXT16",FALSE,0x7FFFFF,0x7FFFFF,FALSE),
+
+ /* upper 7 bits of 23-bit extended address */
+ HOWTO (R_EXTWORDMS7,16,1,7,FALSE,0,complain_overflow_dont,
+ tic54x_relocation,"RELEXTMS7",FALSE,0x7F,0x7F,FALSE),
+
+ /* ABSOLUTE BANK */
+ /* 16-bit direct reference to symbol's address, absolute */
+ HOWTO (R_RELWORD,0,1,16,FALSE,0,complain_overflow_dont,
+ tic54x_relocation,"AREL16",FALSE,0xFFFF,0xFFFF,FALSE),
+
+ /* 7 LSBs of an address, absolute */
+ HOWTO (R_PARTLS7,0,1,7,FALSE,0,complain_overflow_dont,
+ tic54x_relocation,"ALS7",FALSE,0x007F,0x007F,FALSE),
+
+ /* 9 MSBs of an address, absolute */
+ /* TI assembler doesn't shift its encoding, and is thus incompatible */
+ HOWTO (R_PARTMS9,7,1,9,FALSE,0,complain_overflow_dont,
+ tic54x_relocation,"AMS9",FALSE,0x01FF,0x01FF,FALSE),
+
+ /* 23-bit direct reference, absolute */
+ HOWTO (R_EXTWORD,0,2,23,FALSE,0,complain_overflow_dont,
+ tic54x_relocation,"ARELEXT",FALSE,0x7FFFFF,0x7FFFFF,FALSE),
+
+ /* 16 bits of 23-bit extended address, absolute */
+ HOWTO (R_EXTWORD16,0,1,16,FALSE,0,complain_overflow_dont,
+ tic54x_relocation,"ARELEXT16",FALSE,0x7FFFFF,0x7FFFFF,FALSE),
+
+ /* upper 7 bits of 23-bit extended address, absolute */
+ HOWTO (R_EXTWORDMS7,16,1,7,FALSE,0,complain_overflow_dont,
+ tic54x_relocation,"ARELEXTMS7",FALSE,0x7F,0x7F,FALSE),
+
+ /* 32-bit relocation exclusively for stabs */
+ HOWTO (R_RELLONG,0,2,32,FALSE,0,complain_overflow_dont,
+ tic54x_relocation,"STAB",FALSE,0xFFFFFFFF,0xFFFFFFFF,FALSE),
+ };
+
+#define coff_bfd_reloc_type_lookup tic54x_coff_reloc_type_lookup
+#define coff_bfd_reloc_name_lookup tic54x_coff_reloc_name_lookup
+
+/* For the case statement use the code values used tc_gen_reloc (defined in
+ bfd/reloc.c) to map to the howto table entries. */
+
+static reloc_howto_type *
+tic54x_coff_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ bfd_reloc_code_real_type code)
+{
+ switch (code)
+ {
+ case BFD_RELOC_16:
+ return &tic54x_howto_table[0];
+ case BFD_RELOC_TIC54X_PARTLS7:
+ return &tic54x_howto_table[1];
+ case BFD_RELOC_TIC54X_PARTMS9:
+ return &tic54x_howto_table[2];
+ case BFD_RELOC_TIC54X_23:
+ return &tic54x_howto_table[3];
+ case BFD_RELOC_TIC54X_16_OF_23:
+ return &tic54x_howto_table[4];
+ case BFD_RELOC_TIC54X_MS7_OF_23:
+ return &tic54x_howto_table[5];
+ case BFD_RELOC_32:
+ return &tic54x_howto_table[12];
+ default:
+ return (reloc_howto_type *) NULL;
+ }
+}
+
+static reloc_howto_type *
+tic54x_coff_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ const char *r_name)
+{
+ unsigned int i;
+
+ for (i = 0;
+ i < sizeof (tic54x_howto_table) / sizeof (tic54x_howto_table[0]);
+ i++)
+ if (tic54x_howto_table[i].name != NULL
+ && strcasecmp (tic54x_howto_table[i].name, r_name) == 0)
+ return &tic54x_howto_table[i];
+
+ return NULL;
+}
+
+/* Code to turn a r_type into a howto ptr, uses the above howto table.
+ Called after some initial checking by the tic54x_rtype_to_howto fn below. */
+
+static void
+tic54x_lookup_howto (arelent *internal,
+ struct internal_reloc *dst)
+{
+ unsigned i;
+ int bank = (dst->r_symndx == -1) ? HOWTO_BANK : 0;
+
+ for (i = 0; i < sizeof tic54x_howto_table/sizeof tic54x_howto_table[0]; i++)
+ {
+ if (tic54x_howto_table[i].type == dst->r_type)
+ {
+ internal->howto = tic54x_howto_table + i + bank;
+ return;
+ }
+ }
+
+ (*_bfd_error_handler) (_("Unrecognized reloc type 0x%x"),
+ (unsigned int) dst->r_type);
+ abort ();
+}
+
+#define RELOC_PROCESSING(RELENT,RELOC,SYMS,ABFD,SECT)\
+ tic54x_reloc_processing(RELENT,RELOC,SYMS,ABFD,SECT)
+
+#define coff_rtype_to_howto coff_tic54x_rtype_to_howto
+
+static reloc_howto_type *
+coff_tic54x_rtype_to_howto (bfd *abfd ATTRIBUTE_UNUSED,
+ asection *sec,
+ struct internal_reloc *rel,
+ struct coff_link_hash_entry *h ATTRIBUTE_UNUSED,
+ struct internal_syment *sym ATTRIBUTE_UNUSED,
+ 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;
+ }
+
+ tic54x_lookup_howto (&genrel, rel);
+
+ return genrel.howto;
+}
+
+/* Replace the stock _bfd_coff_is_local_label_name to recognize TI COFF local
+ labels. */
+
+static bfd_boolean
+ticoff_bfd_is_local_label_name (bfd *abfd ATTRIBUTE_UNUSED,
+ const char *name)
+{
+ if (TICOFF_LOCAL_LABEL_P(name))
+ return TRUE;
+ return FALSE;
+}
+
+#define coff_bfd_is_local_label_name ticoff_bfd_is_local_label_name
+
+/* Customize coffcode.h; the default coff_ functions are set up to use COFF2;
+ coff_bad_format_hook uses BADMAG, so set that for COFF2. The COFF1
+ and COFF0 vectors use custom _bad_format_hook procs instead of setting
+ BADMAG. */
+#define BADMAG(x) COFF2_BADMAG(x)
+
+#ifndef bfd_pe_print_pdata
+#define bfd_pe_print_pdata NULL
+#endif
+
+#include "coffcode.h"
+
+static bfd_boolean
+tic54x_set_section_contents (bfd *abfd,
+ sec_ptr section,
+ const void * location,
+ file_ptr offset,
+ bfd_size_type bytes_to_do)
+{
+ return coff_set_section_contents (abfd, section, location,
+ offset, bytes_to_do);
+}
+
+static void
+tic54x_reloc_processing (arelent *relent,
+ struct internal_reloc *reloc,
+ asymbol **symbols,
+ bfd *abfd,
+ asection *section)
+{
+ asymbol *ptr;
+
+ relent->address = reloc->r_vaddr;
+
+ if (reloc->r_symndx != -1)
+ {
+ if (reloc->r_symndx < 0 || reloc->r_symndx >= obj_conv_table_size (abfd))
+ {
+ (*_bfd_error_handler)
+ (_("%B: warning: illegal symbol index %ld in relocs"),
+ abfd, reloc->r_symndx);
+ relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
+ ptr = NULL;
+ }
+ else
+ {
+ relent->sym_ptr_ptr = (symbols
+ + obj_convert (abfd)[reloc->r_symndx]);
+ ptr = *(relent->sym_ptr_ptr);
+ }
+ }
+ else
+ {
+ relent->sym_ptr_ptr = section->symbol_ptr_ptr;
+ ptr = *(relent->sym_ptr_ptr);
+ }
+
+ /* 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, *reloc, relent);
+
+ relent->address -= section->vma;
+ /* !! relent->section = (asection *) NULL;*/
+
+ /* Fill in the relent->howto field from reloc->r_type. */
+ tic54x_lookup_howto (relent, reloc);
+}
+
+/* TI COFF v0, DOS tools (little-endian headers). */
+const bfd_target tic54x_coff0_vec =
+ {
+ "coff0-c54x", /* name */
+ bfd_target_coff_flavour,
+ BFD_ENDIAN_LITTLE, /* data byte order is little */
+ BFD_ENDIAN_LITTLE, /* header byte order is little (DOS tools) */
+
+ (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 */
+ 0, /* match priority. */
+ bfd_getl64, bfd_getl_signed_64, bfd_putl64,
+ tic54x_getl32, tic54x_getl_signed_32, tic54x_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 (tic54x),
+ BFD_JUMP_TABLE_LINK (coff),
+ BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
+ NULL,
+
+ & ticoff0_swap_table
+ };
+
+/* TI COFF v0, SPARC tools (big-endian headers). */
+const bfd_target tic54x_coff0_beh_vec =
+ {
+ "coff0-beh-c54x", /* 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 symbol underscore */
+ '/', /* ar_pad_char */
+ 15, /* ar_max_namelen */
+ 0, /* match priority. */
+ bfd_getl64, bfd_getl_signed_64, bfd_putl64,
+ tic54x_getl32, tic54x_getl_signed_32, tic54x_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_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 (tic54x),
+ BFD_JUMP_TABLE_LINK (coff),
+ BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
+
+ & tic54x_coff0_vec,
+
+ & ticoff0_swap_table
+ };
+
+/* TI COFF v1, DOS tools (little-endian headers). */
+const bfd_target tic54x_coff1_vec =
+ {
+ "coff1-c54x", /* name */
+ bfd_target_coff_flavour,
+ BFD_ENDIAN_LITTLE, /* data byte order is little */
+ BFD_ENDIAN_LITTLE, /* header byte order is little (DOS tools) */
+
+ (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 */
+ 0, /* match priority. */
+ bfd_getl64, bfd_getl_signed_64, bfd_putl64,
+ tic54x_getl32, tic54x_getl_signed_32, tic54x_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 (tic54x),
+ BFD_JUMP_TABLE_LINK (coff),
+ BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
+
+ & tic54x_coff0_beh_vec,
+
+ & ticoff1_swap_table
+};
+
+/* TI COFF v1, SPARC tools (big-endian headers). */
+const bfd_target tic54x_coff1_beh_vec =
+ {
+ "coff1-beh-c54x", /* 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 symbol underscore */
+ '/', /* ar_pad_char */
+ 15, /* ar_max_namelen */
+ 0, /* match priority. */
+ bfd_getl64, bfd_getl_signed_64, bfd_putl64,
+ tic54x_getl32, tic54x_getl_signed_32, tic54x_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_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 (tic54x),
+ BFD_JUMP_TABLE_LINK (coff),
+ BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
+
+ & tic54x_coff1_vec,
+
+ & ticoff1_swap_table
+ };
+
+/* TI COFF v2, TI DOS tools output (little-endian headers). */
+const bfd_target tic54x_coff2_vec =
+ {
+ "coff2-c54x", /* name */
+ bfd_target_coff_flavour,
+ BFD_ENDIAN_LITTLE, /* data byte order is little */
+ BFD_ENDIAN_LITTLE, /* header byte order is little (DOS tools) */
+
+ (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 */
+ 0, /* match priority. */
+ bfd_getl64, bfd_getl_signed_64, bfd_putl64,
+ tic54x_getl32, tic54x_getl_signed_32, tic54x_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 (tic54x),
+ BFD_JUMP_TABLE_LINK (coff),
+ BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
+
+ & tic54x_coff1_beh_vec,
+
+ COFF_SWAP_TABLE
+ };
+
+/* TI COFF v2, TI SPARC tools output (big-endian headers). */
+const bfd_target tic54x_coff2_beh_vec =
+ {
+ "coff2-beh-c54x", /* 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 symbol underscore */
+ '/', /* ar_pad_char */
+ 15, /* ar_max_namelen */
+ 0, /* match priority. */
+ bfd_getl64, bfd_getl_signed_64, bfd_putl64,
+ tic54x_getl32, tic54x_getl_signed_32, tic54x_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_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 (tic54x),
+ BFD_JUMP_TABLE_LINK (coff),
+ BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
+
+ & tic54x_coff2_vec,
+
+ COFF_SWAP_TABLE
+ };
diff --git a/bfd/coff-tic80.c b/bfd/coff-tic80.c
new file mode 100644
index 0000000..80bb05e
--- /dev/null
+++ b/bfd/coff-tic80.c
@@ -0,0 +1,712 @@
+/* BFD back-end for Texas Instruments TMS320C80 Multimedia Video Processor (MVP).
+ Copyright (C) 1996-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, 51 Franklin Street - Fifth Floor,
+ Boston, MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "bfdlink.h"
+#include "libbfd.h"
+#ifdef _CONST
+/* Newlib-based hosts define _CONST as a STDC-safe alias for const,
+ but to the tic80 toolchain it means something altogether different.
+ Since sysdep.h will have pulled in stdio.h and hence _ansi.h which
+ contains this definition, we must undef it before including the
+ tic80-specific definition. */
+#undef _CONST
+#endif /* _CONST */
+#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 H_GET_16
+#define PUT_SCNHDR_FLAGS H_PUT_16
+
+static bfd_reloc_status_type ppbase_reloc
+ (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
+static bfd_reloc_status_type glob15_reloc
+ (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
+static bfd_reloc_status_type glob16_reloc
+ (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
+static bfd_reloc_status_type local16_reloc
+ (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
+
+
+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 (bfd *abfd ATTRIBUTE_UNUSED,
+ arelent *reloc_entry ATTRIBUTE_UNUSED,
+ asymbol *symbol_in ATTRIBUTE_UNUSED,
+ void * data ATTRIBUTE_UNUSED,
+ asection *input_section ATTRIBUTE_UNUSED,
+ bfd *output_bfd ATTRIBUTE_UNUSED,
+ char **error_message ATTRIBUTE_UNUSED)
+{
+ /* FIXME. */
+ abort ();
+}
+
+/* This special function is used for the global 15 bit relocations. */
+
+static bfd_reloc_status_type
+glob15_reloc (bfd *abfd ATTRIBUTE_UNUSED,
+ arelent *reloc_entry ATTRIBUTE_UNUSED,
+ asymbol *symbol_in ATTRIBUTE_UNUSED,
+ void * data ATTRIBUTE_UNUSED,
+ asection *input_section ATTRIBUTE_UNUSED,
+ bfd *output_bfd ATTRIBUTE_UNUSED,
+ char **error_message ATTRIBUTE_UNUSED)
+{
+ /* FIXME. */
+ abort ();
+}
+
+/* This special function is used for the global 16 bit relocations. */
+
+static bfd_reloc_status_type
+glob16_reloc (bfd *abfd ATTRIBUTE_UNUSED,
+ arelent *reloc_entry ATTRIBUTE_UNUSED,
+ asymbol *symbol_in ATTRIBUTE_UNUSED,
+ void * data ATTRIBUTE_UNUSED,
+ asection *input_section ATTRIBUTE_UNUSED,
+ bfd *output_bfd ATTRIBUTE_UNUSED,
+ char **error_message ATTRIBUTE_UNUSED)
+{
+ /* FIXME. */
+ abort ();
+}
+
+/* This special function is used for the local 16 bit relocations. */
+
+static bfd_reloc_status_type
+local16_reloc (bfd *abfd ATTRIBUTE_UNUSED,
+ arelent *reloc_entry ATTRIBUTE_UNUSED,
+ asymbol *symbol_in ATTRIBUTE_UNUSED,
+ void * data ATTRIBUTE_UNUSED,
+ asection *input_section ATTRIBUTE_UNUSED,
+ bfd *output_bfd ATTRIBUTE_UNUSED,
+ char **error_message ATTRIBUTE_UNUSED)
+{
+ /* 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 (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 (bfd *abfd ATTRIBUTE_UNUSED,
+ asection *sec,
+ struct internal_reloc *rel,
+ struct coff_link_hash_entry *h ATTRIBUTE_UNUSED,
+ struct internal_syment *sym ATTRIBUTE_UNUSED,
+ 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 bfd_boolean
+coff_tic80_relocate_section (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->relocatable)
+ {
+ if (! ((*info->callbacks->undefined_symbol)
+ (info, h->root.root.string, input_bfd, input_section,
+ rel->r_vaddr - input_section->vma, TRUE)))
+ 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)
+ (_("%B: bad reloc address 0x%lx in section `%A'"),
+ input_bfd, input_section, (unsigned long) rel->r_vaddr);
+ return FALSE;
+ case bfd_reloc_overflow:
+ {
+ const char *name;
+ char buf[SYMNMLEN + 1];
+
+ if (symndx == -1)
+ name = "*ABS*";
+ else if (h != NULL)
+ name = NULL;
+ else
+ {
+ name = _bfd_coff_internal_syment_name (input_bfd, sym, buf);
+ if (name == NULL)
+ return FALSE;
+ }
+
+ if (! ((*info->callbacks->reloc_overflow)
+ (info, (h ? &h->root : NULL), 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 */
+
+#ifndef bfd_pe_print_pdata
+#define bfd_pe_print_pdata NULL
+#endif
+
+#include "coffcode.h"
+
+CREATE_LITTLE_COFF_TARGET_VEC (tic80_coff_vec, "coff-tic80", D_PAGED, 0, '_', NULL, COFF_SWAP_TABLE)
diff --git a/bfd/coff-u68k.c b/bfd/coff-u68k.c
new file mode 100644
index 0000000..260853c
--- /dev/null
+++ b/bfd/coff-u68k.c
@@ -0,0 +1,36 @@
+/* BFD back-end for Motorola 68000 COFF binaries having underscore with name.
+ Copyright (C) 1990-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#define TARGET_SYM m68k_coff_un_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 0000000..f208730
--- /dev/null
+++ b/bfd/coff-w65.c
@@ -0,0 +1,377 @@
+/* BFD back-end for WDC 65816 COFF binaries.
+ Copyright (C) 1995-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.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 H_GET_32
+#define SWAP_OUT_RELOC_OFFSET 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 (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 (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 (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_section_ptr->symbol_ptr_ptr;
+
+ relent->addend = reloc->r_offset;
+
+ relent->address -= section->vma;
+ /* relent->section = 0;*/
+}
+
+static int
+w65_reloc16_estimate (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
+w65_reloc16_extra_cases (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, (bfd_vma) 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, (bfd_vma) 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, (bfd_vma) 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, (bfd_vma) 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 = (dst_address
+ + input_section->output_offset
+ + input_section->output_section->vma);
+
+ gap -= dot + 1;
+ if (gap < -128 || gap > 127)
+ {
+ if (! ((*link_info->callbacks->reloc_overflow)
+ (link_info, NULL,
+ 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 = (dst_address
+ + input_section->output_offset
+ + input_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, NULL,
+ 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 w65_reloc16_extra_cases
+#define coff_reloc16_estimate w65_reloc16_estimate
+
+#ifndef bfd_pe_print_pdata
+#define bfd_pe_print_pdata NULL
+#endif
+
+#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
+
+CREATE_LITTLE_COFF_TARGET_VEC (w65_coff_vec, "coff-w65", BFD_IS_RELAXABLE, 0, '_', NULL, COFF_SWAP_TABLE)
diff --git a/bfd/coff-we32k.c b/bfd/coff-we32k.c
new file mode 100644
index 0000000..d5481b8
--- /dev/null
+++ b/bfd/coff-we32k.c
@@ -0,0 +1,73 @@
+/* BFD back-end for we32k COFF files.
+ Copyright (C) 1992-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.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[] =
+{
+ EMPTY_HOWTO (0),
+ EMPTY_HOWTO (1),
+ EMPTY_HOWTO (2),
+ EMPTY_HOWTO (3),
+ EMPTY_HOWTO (4),
+ EMPTY_HOWTO (5),
+ HOWTO(R_DIR32, 0, 2, 32, FALSE, 0,complain_overflow_bitfield, 0, "dir32", TRUE, 0xffffffff,0xffffffff, FALSE),
+ EMPTY_HOWTO (7),
+ EMPTY_HOWTO (010),
+ EMPTY_HOWTO (011),
+ EMPTY_HOWTO (012),
+ EMPTY_HOWTO (013),
+ EMPTY_HOWTO (014),
+ EMPTY_HOWTO (015),
+ EMPTY_HOWTO (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;
+
+#ifndef bfd_pe_print_pdata
+#define bfd_pe_print_pdata NULL
+#endif
+
+#include "coffcode.h"
+
+#define coff_write_armap bsd_write_armap
+
+CREATE_BIG_COFF_TARGET_VEC (we32k_coff_vec, "coff-we32k", 0, 0, 0, NULL, COFF_SWAP_TABLE)
diff --git a/bfd/coff-x86_64.c b/bfd/coff-x86_64.c
new file mode 100644
index 0000000..2a21bb8
--- /dev/null
+++ b/bfd/coff-x86_64.c
@@ -0,0 +1,799 @@
+/* BFD back-end for AMD 64 COFF files.
+ Copyright (C) 2006-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA.
+
+ Written by Kai Tietz, OneVision Software GmbH&CoKg. */
+
+#ifndef COFF_WITH_pex64
+#define COFF_WITH_pex64
+#endif
+
+/* Note we have to make sure not to include headers twice.
+ Not all headers are wrapped in #ifdef guards, so we define
+ PEI_HEADERS to prevent double including here. */
+#ifndef PEI_HEADERS
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+#include "coff/x86_64.h"
+#include "coff/internal.h"
+#include "coff/pe.h"
+#include "libcoff.h"
+#include "libiberty.h"
+#endif
+
+#define BADMAG(x) AMD64BADMAG(x)
+
+#ifdef COFF_WITH_pex64
+# undef AOUTSZ
+# define AOUTSZ PEPAOUTSZ
+# define PEAOUTHDR PEPAOUTHDR
+#endif
+
+#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 AMD 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 relocatable 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_amd64_reloc (bfd *abfd,
+ arelent *reloc_entry,
+ asymbol *symbol,
+ void * data,
+ asection *input_section ATTRIBUTE_UNUSED,
+ bfd *output_bfd,
+ char **error_message ATTRIBUTE_UNUSED)
+{
+ symvalue diff;
+
+#if !defined(COFF_WITH_PE)
+ if (output_bfd == NULL)
+ return bfd_reloc_continue;
+#endif
+
+ if (bfd_is_com_section (symbol->section))
+ {
+#if !defined(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
+ relocatable output. This seems to be always wrong for 386
+ COFF, so we handle the addend here instead. */
+#if defined(COFF_WITH_PE)
+ if (output_bfd == NULL)
+ {
+ reloc_howto_type *howto = reloc_entry->howto;
+
+ /* Although PC relative relocations are very similar between
+ PE and non-PE formats, but they are off by 1 << howto->size
+ bytes. For the external relocation, PE is very different
+ from others. See md_apply_fix3 () in gas/config/tc-amd64.c.
+ When we link PE and non-PE object files together to
+ generate a non-PE executable, we have to compensate it
+ here. */
+ if(howto->pc_relative && howto->pcrel_offset)
+ diff = -(1 << howto->size);
+ else if(symbol->flags & BSF_WEAK)
+ diff = reloc_entry->addend - symbol->value;
+ else
+ diff = -reloc_entry->addend;
+ }
+ else
+#endif
+ diff = reloc_entry->addend;
+ }
+
+#if defined(COFF_WITH_PE)
+ /* FIXME: How should this case be handled? */
+ if (reloc_entry->howto->type == R_AMD64_IMAGEBASE
+ && output_bfd != NULL
+ && bfd_get_flavour (output_bfd) == bfd_target_coff_flavour)
+ diff -= pe_data (output_bfd)->pe_opthdr.ImageBase;
+#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, (bfd_vma) x, addr);
+ }
+ break;
+
+ case 2:
+ {
+ long x = bfd_get_32 (abfd, addr);
+ DOIT (x);
+ bfd_put_32 (abfd, (bfd_vma) x, addr);
+ }
+ break;
+ case 4:
+ {
+ long long x = bfd_get_64 (abfd, addr);
+ DOIT (x);
+ bfd_put_64 (abfd, (bfd_vma) x, addr);
+ }
+ break;
+
+ default:
+ abort ();
+ }
+ }
+
+ /* Now let bfd_perform_relocation finish everything up. */
+ return bfd_reloc_continue;
+}
+
+#if defined(COFF_WITH_PE)
+/* Return TRUE if this relocation should appear in the output .reloc
+ section. */
+
+static bfd_boolean
+in_reloc_p (bfd *abfd ATTRIBUTE_UNUSED, reloc_howto_type *howto)
+{
+ return ! howto->pc_relative && howto->type != R_AMD64_IMAGEBASE
+ && howto->type != R_AMD64_SECREL;
+}
+#endif /* COFF_WITH_PE */
+
+#ifndef PCRELOFFSET
+#define PCRELOFFSET TRUE
+#endif
+
+static reloc_howto_type howto_table[] =
+{
+ EMPTY_HOWTO (0),
+ HOWTO (R_AMD64_DIR64, /* type 1*/
+ 0, /* rightshift */
+ 4, /* size (0 = byte, 1 = short, 2 = long, 4 = long long) */
+ 64, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ coff_amd64_reloc, /* special_function */
+ "R_X86_64_64", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffffffffffffll, /* src_mask */
+ 0xffffffffffffffffll, /* dst_mask */
+ TRUE), /* pcrel_offset */
+ HOWTO (R_AMD64_DIR32, /* type 2 */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ coff_amd64_reloc, /* special_function */
+ "R_X86_64_32", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+ /* PE IMAGE_REL_AMD64_ADDR32NB relocation (3). */
+ HOWTO (R_AMD64_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_amd64_reloc, /* special_function */
+ "rva32", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ /* 32-bit longword PC relative relocation (4). */
+ HOWTO (R_AMD64_PCRLONG, /* type 4 */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ coff_amd64_reloc, /* special_function */
+ "R_X86_64_PC32", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ PCRELOFFSET), /* pcrel_offset */
+
+ HOWTO (R_AMD64_PCRLONG_1, /* type 5 */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ coff_amd64_reloc, /* special_function */
+ "DISP32+1", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ PCRELOFFSET), /* pcrel_offset */
+ HOWTO (R_AMD64_PCRLONG_2, /* type 6 */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ coff_amd64_reloc, /* special_function */
+ "DISP32+2", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ PCRELOFFSET), /* pcrel_offset */
+ HOWTO (R_AMD64_PCRLONG_3, /* type 7 */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ coff_amd64_reloc, /* special_function */
+ "DISP32+3", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ PCRELOFFSET), /* pcrel_offset */
+ HOWTO (R_AMD64_PCRLONG_4, /* type 8 */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ coff_amd64_reloc, /* special_function */
+ "DISP32+4", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ PCRELOFFSET), /* pcrel_offset */
+ HOWTO (R_AMD64_PCRLONG_5, /* type 9 */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ coff_amd64_reloc, /* special_function */
+ "DISP32+5", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ PCRELOFFSET), /* pcrel_offset */
+ EMPTY_HOWTO (10), /* R_AMD64_SECTION 10 */
+#if defined(COFF_WITH_PE)
+ /* 32-bit longword section relative relocation (11). */
+ HOWTO (R_AMD64_SECREL, /* 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_amd64_reloc, /* special_function */
+ "secrel32", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+#else
+ EMPTY_HOWTO (11),
+#endif
+ EMPTY_HOWTO (12),
+ EMPTY_HOWTO (13),
+#ifndef DONT_EXTEND_AMD64
+ HOWTO (R_AMD64_PCRQUAD,
+ 0, /* rightshift */
+ 4, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ coff_amd64_reloc, /* special_function */
+ "R_X86_64_PC64", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffffffffffffll, /* src_mask */
+ 0xffffffffffffffffll, /* dst_mask */
+ PCRELOFFSET), /* pcrel_offset */
+#else
+ EMPTY_HOWTO (14),
+#endif
+ /* Byte relocation (15). */
+ 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_amd64_reloc, /* special_function */
+ "R_X86_64_8", /* name */
+ TRUE, /* partial_inplace */
+ 0x000000ff, /* src_mask */
+ 0x000000ff, /* dst_mask */
+ PCRELOFFSET), /* pcrel_offset */
+ /* 16-bit word relocation (16). */
+ 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_amd64_reloc, /* special_function */
+ "R_X86_64_16", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ PCRELOFFSET), /* pcrel_offset */
+ /* 32-bit longword relocation (17). */
+ 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_amd64_reloc, /* special_function */
+ "R_X86_64_32S", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ PCRELOFFSET), /* pcrel_offset */
+ /* Byte PC relative relocation (18). */
+ 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_amd64_reloc, /* special_function */
+ "R_X86_64_PC8", /* name */
+ TRUE, /* partial_inplace */
+ 0x000000ff, /* src_mask */
+ 0x000000ff, /* dst_mask */
+ PCRELOFFSET), /* pcrel_offset */
+ /* 16-bit word PC relative relocation (19). */
+ 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_amd64_reloc, /* special_function */
+ "R_X86_64_PC16", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ PCRELOFFSET), /* pcrel_offset */
+ /* 32-bit longword PC relative relocation (20). */
+ 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_amd64_reloc, /* special_function */
+ "R_X86_64_PC32", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ PCRELOFFSET) /* pcrel_offset */
+};
+
+#define NUM_HOWTOS ARRAY_SIZE (howto_table)
+
+/* Turn a howto into a reloc nunmber */
+
+#define SELECT_RELOC(x,howto) { x.r_type = howto->type; }
+#define I386 1 /* Customize coffcode.h */
+#define AMD64 1
+
+#define RTYPE2HOWTO(cache_ptr, dst) \
+ ((cache_ptr)->howto = \
+ ((dst)->r_type < NUM_HOWTOS) \
+ ? howto_table + (dst)->r_type \
+ : NULL)
+
+/* 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 = 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 != 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 != NULL) \
+ cache_ptr->addend = - (ptr->section->vma + ptr->value); \
+ else \
+ cache_ptr->addend = 0; \
+ if (ptr && reloc.r_type < NUM_HOWTOS \
+ && howto_table[reloc.r_type].pc_relative) \
+ cache_ptr->addend += asect->vma; \
+ }
+
+/* We use the special COFF backend linker. For normal AMD64 COFF, we
+ can use the generic relocate_section routine. For PE, we need our
+ own routine. */
+
+#if !defined(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
+ relocatable link. */
+
+static bfd_boolean
+coff_pe_amd64_relocate_section (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->relocatable)
+ 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_amd64_relocate_section
+
+#endif /* COFF_WITH_PE */
+
+/* Convert an rtype to howto for the COFF backend linker. */
+
+static reloc_howto_type *
+coff_amd64_rtype_to_howto (bfd *abfd ATTRIBUTE_UNUSED,
+ 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_HOWTOS)
+ {
+ bfd_set_error (bfd_error_bad_value);
+ return NULL;
+ }
+ howto = howto_table + rel->r_type;
+
+#if defined(COFF_WITH_PE)
+ /* Cancel out code in _bfd_coff_generic_relocate_section. */
+ *addendp = 0;
+ if (rel->r_type >= R_AMD64_PCRLONG_1 && rel->r_type <= R_AMD64_PCRLONG_5)
+ {
+ *addendp -= (bfd_vma)(rel->r_type - R_AMD64_PCRLONG);
+ rel->r_type = R_AMD64_PCRLONG;
+ }
+#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);
+
+#if !defined(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
+ }
+
+#if !defined(COFF_WITH_PE)
+ /* If the output symbol is common (in which case this must be a
+ relocatable 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
+
+#if defined(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_AMD64_IMAGEBASE
+ && (bfd_get_flavour (sec->output_section->owner) == bfd_target_coff_flavour))
+ *addendp -= pe_data (sec->output_section->owner)->pe_opthdr.ImageBase;
+
+ if (rel->r_type == R_AMD64_SECREL)
+ {
+ bfd_vma osect_vma;
+
+ if (h && (h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak))
+ osect_vma = h->root.u.def.section->output_section->vma;
+ else
+ {
+ asection *s;
+ int i;
+
+ /* Sigh, the only way to get the section to offset against
+ is to find it the hard way. */
+ for (s = abfd->sections, i = 1; i < sym->n_scnum; i++)
+ s = s->next;
+
+ osect_vma = s->output_section->vma;
+ }
+
+ *addendp -= osect_vma;
+ }
+#endif
+
+ return howto;
+}
+
+#define coff_bfd_reloc_type_lookup coff_amd64_reloc_type_lookup
+#define coff_bfd_reloc_name_lookup coff_amd64_reloc_name_lookup
+
+static reloc_howto_type *
+coff_amd64_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, bfd_reloc_code_real_type code)
+{
+ switch (code)
+ {
+ case BFD_RELOC_RVA:
+ return howto_table + R_AMD64_IMAGEBASE;
+ case BFD_RELOC_32:
+ return howto_table + R_AMD64_DIR32;
+ case BFD_RELOC_64:
+ return howto_table + R_AMD64_DIR64;
+ case BFD_RELOC_64_PCREL:
+#ifndef DONT_EXTEND_AMD64
+ return howto_table + R_AMD64_PCRQUAD;
+#else
+ /* Fall through. */
+#endif
+ case BFD_RELOC_32_PCREL:
+ return howto_table + R_AMD64_PCRLONG;
+ case BFD_RELOC_X86_64_32S:
+ return howto_table + R_RELLONG;
+ case BFD_RELOC_16:
+ return howto_table + R_RELWORD;
+ case BFD_RELOC_16_PCREL:
+ return howto_table + R_PCRWORD;
+ case BFD_RELOC_8:
+ return howto_table + R_RELBYTE;
+ case BFD_RELOC_8_PCREL:
+ return howto_table + R_PCRBYTE;
+#if defined(COFF_WITH_PE)
+ case BFD_RELOC_32_SECREL:
+ return howto_table + R_AMD64_SECREL;
+#endif
+ default:
+ BFD_FAIL ();
+ return 0;
+ }
+}
+
+static reloc_howto_type *
+coff_amd64_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ const char *r_name)
+{
+ unsigned int i;
+
+ for (i = 0; i < NUM_HOWTOS; i++)
+ if (howto_table[i].name != NULL
+ && strcasecmp (howto_table[i].name, r_name) == 0)
+ return &howto_table[i];
+
+ return NULL;
+}
+
+#define coff_rtype_to_howto coff_amd64_rtype_to_howto
+
+#ifdef TARGET_UNDERSCORE
+
+/* If amd64 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 bfd_boolean
+coff_amd64_is_local_label_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_amd64_is_local_label_name
+
+#endif /* TARGET_UNDERSCORE */
+
+#ifndef bfd_pe_print_pdata
+#define bfd_pe_print_pdata NULL
+#endif
+
+#include "coffcode.h"
+
+#ifdef PE
+#define amd64coff_object_p pe_bfd_object_p
+#else
+#define amd64coff_object_p coff_object_p
+#endif
+
+const bfd_target
+#ifdef TARGET_SYM
+ TARGET_SYM =
+#else
+ x86_64_coff_vec =
+#endif
+{
+#ifdef TARGET_NAME
+ TARGET_NAME,
+#else
+ "coff-x86-64", /* 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 | BFD_COMPRESS | BFD_DECOMPRESS),
+
+ (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC /* Section flags. */
+#if defined(COFF_WITH_PE)
+ | SEC_LINK_ONCE | SEC_LINK_DUPLICATES | SEC_READONLY | SEC_DEBUGGING
+#endif
+ | SEC_CODE | SEC_DATA | SEC_EXCLUDE ),
+
+#ifdef TARGET_UNDERSCORE
+ TARGET_UNDERSCORE, /* Leading underscore. */
+#else
+ 0, /* Leading underscore. */
+#endif
+ '/', /* Ar_pad_char. */
+ 15, /* Ar_max_namelen. */
+ 0, /* match priority. */
+
+ 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, amd64coff_object_p, /* BFD_check_format. */
+ bfd_generic_archive_p, amd64coff_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),
+
+ NULL,
+
+ COFF_SWAP_TABLE
+};
diff --git a/bfd/coff-z80.c b/bfd/coff-z80.c
new file mode 100644
index 0000000..7b62cdf
--- /dev/null
+++ b/bfd/coff-z80.c
@@ -0,0 +1,289 @@
+/* BFD back-end for Zilog Z80 COFF binaries.
+ Copyright (C) 2005-2014 Free Software Foundation, Inc.
+ Contributed by Arnold Metselaar <arnold_m@operamail.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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+#include "bfdlink.h"
+#include "coff/z80.h"
+#include "coff/internal.h"
+#include "libcoff.h"
+
+#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER 0
+
+static reloc_howto_type r_imm32 =
+HOWTO (R_IMM32, 0, 2, 32, FALSE, 0,
+ complain_overflow_dont, 0, "r_imm32", TRUE, 0xffffffff, 0xffffffff,
+ FALSE);
+
+static reloc_howto_type r_imm24 =
+HOWTO (R_IMM24, 0, 1, 24, FALSE, 0,
+ complain_overflow_dont, 0, "r_imm24", TRUE, 0x00ffffff, 0x00ffffff,
+ FALSE);
+
+static reloc_howto_type r_imm16 =
+HOWTO (R_IMM16, 0, 1, 16, FALSE, 0,
+ complain_overflow_dont, 0, "r_imm16", TRUE, 0x0000ffff, 0x0000ffff,
+ FALSE);
+
+static reloc_howto_type r_imm8 =
+HOWTO (R_IMM8, 0, 0, 8, FALSE, 0,
+ complain_overflow_bitfield, 0, "r_imm8", TRUE, 0x000000ff, 0x000000ff,
+ FALSE);
+
+static reloc_howto_type r_jr =
+HOWTO (R_JR, 0, 0, 8, TRUE, 0,
+ complain_overflow_signed, 0, "r_jr", FALSE, 0, 0xFF,
+ FALSE);
+
+static reloc_howto_type r_off8 =
+HOWTO (R_OFF8, 0, 0, 8, FALSE, 0,
+ complain_overflow_signed, 0,"r_off8", FALSE, 0, 0xff,
+ FALSE);
+
+
+#define BADMAG(x) Z80BADMAG(x)
+#define Z80 1 /* Customize coffcode.h. */
+#define __A_MAGIC_SET__
+
+/* Code to swap in the reloc. */
+
+#define SWAP_IN_RELOC_OFFSET H_GET_32
+#define SWAP_OUT_RELOC_OFFSET 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 (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_imm16;
+ break;
+ case R_IMM24:
+ internal->howto = &r_imm24;
+ break;
+ case R_IMM32:
+ internal->howto = &r_imm32;
+ break;
+ case R_JR:
+ internal->howto = &r_jr;
+ break;
+ case R_OFF8:
+ internal->howto = &r_off8;
+ break;
+ }
+}
+
+#define RTYPE2HOWTO(internal, relocentry) rtype2howto (internal, relocentry)
+
+static reloc_howto_type *
+coff_z80_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ bfd_reloc_code_real_type code)
+{
+ switch (code)
+ {
+ case BFD_RELOC_8: return & r_imm8;
+ case BFD_RELOC_16: return & r_imm16;
+ case BFD_RELOC_24: return & r_imm24;
+ case BFD_RELOC_32: return & r_imm32;
+ case BFD_RELOC_8_PCREL: return & r_jr;
+ case BFD_RELOC_Z80_DISP8: return & r_off8;
+ default: BFD_FAIL ();
+ return NULL;
+ }
+}
+
+static reloc_howto_type *
+coff_z80_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ const char *r_name)
+{
+ if (strcasecmp (r_imm8.name, r_name) == 0)
+ return &r_imm8;
+ if (strcasecmp (r_imm16.name, r_name) == 0)
+ return &r_imm16;
+ if (strcasecmp (r_imm24.name, r_name) == 0)
+ return &r_imm24;
+ if (strcasecmp (r_imm32.name, r_name) == 0)
+ return &r_imm32;
+ if (strcasecmp (r_jr.name, r_name) == 0)
+ return &r_jr;
+ if (strcasecmp (r_off8.name, r_name) == 0)
+ return &r_off8;
+
+ return NULL;
+}
+
+/* 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 (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 (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;
+ int val;
+
+ switch (reloc->howto->type)
+ {
+ case R_OFF8:
+ val = bfd_coff_reloc16_get_value (reloc, link_info,
+ input_section);
+ if (val>127 || val<-128) /* Test for overflow. */
+ {
+ if (! ((*link_info->callbacks->reloc_overflow)
+ (link_info, NULL,
+ 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, val, data + *dst_ptr);
+ (*dst_ptr) += 1;
+ (*src_ptr) += 1;
+ break;
+
+ case R_IMM8:
+ val = bfd_get_8 ( in_abfd, data+*src_ptr)
+ + bfd_coff_reloc16_get_value (reloc, link_info, input_section);
+ bfd_put_8 (in_abfd, val, data + *dst_ptr);
+ (*dst_ptr) += 1;
+ (*src_ptr) += 1;
+ break;
+
+ case R_IMM16:
+ val = bfd_get_16 ( in_abfd, data+*src_ptr)
+ + bfd_coff_reloc16_get_value (reloc, link_info, input_section);
+ bfd_put_16 (in_abfd, val, data + *dst_ptr);
+ (*dst_ptr) += 2;
+ (*src_ptr) += 2;
+ break;
+
+ case R_IMM24:
+ val = bfd_get_16 ( in_abfd, data+*src_ptr)
+ + (bfd_get_8 ( in_abfd, data+*src_ptr+2) << 16)
+ + bfd_coff_reloc16_get_value (reloc, link_info, input_section);
+ bfd_put_16 (in_abfd, val, data + *dst_ptr);
+ bfd_put_8 (in_abfd, val >> 16, data + *dst_ptr+2);
+ (*dst_ptr) += 3;
+ (*src_ptr) += 3;
+ break;
+
+ case R_IMM32:
+ val = bfd_get_32 ( in_abfd, data+*src_ptr)
+ + bfd_coff_reloc16_get_value (reloc, link_info, input_section);
+ bfd_put_32 (in_abfd, val, data + *dst_ptr);
+ (*dst_ptr) += 4;
+ (*src_ptr) += 4;
+ break;
+
+ case R_JR:
+ {
+ bfd_vma dst = bfd_coff_reloc16_get_value (reloc, link_info,
+ input_section);
+ bfd_vma dot = (*dst_ptr
+ + input_section->output_offset
+ + input_section->output_section->vma);
+ int gap = dst - dot - 1; /* -1, Since the offset is relative
+ to the value of PC after reading
+ the offset. */
+
+ if (gap >= 128 || gap < -128)
+ {
+ if (! ((*link_info->callbacks->reloc_overflow)
+ (link_info, NULL,
+ 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
+#define coff_bfd_reloc_type_lookup coff_z80_reloc_type_lookup
+#define coff_bfd_reloc_name_lookup coff_z80_reloc_name_lookup
+
+#ifndef bfd_pe_print_pdata
+#define bfd_pe_print_pdata NULL
+#endif
+
+#include "coffcode.h"
+
+#undef coff_bfd_get_relocated_section_contents
+#define coff_bfd_get_relocated_section_contents \
+ bfd_coff_reloc16_get_relocated_section_contents
+
+#undef coff_bfd_relax_section
+#define coff_bfd_relax_section bfd_coff_reloc16_relax_section
+
+CREATE_LITTLE_COFF_TARGET_VEC (z80_coff_vec, "coff-z80", 0,
+ SEC_CODE | SEC_DATA, '\0', NULL,
+ COFF_SWAP_TABLE)
+
diff --git a/bfd/coff-z8k.c b/bfd/coff-z8k.c
new file mode 100644
index 0000000..c85713f
--- /dev/null
+++ b/bfd/coff-z8k.c
@@ -0,0 +1,387 @@
+/* BFD back-end for Zilog Z800n COFF binaries.
+ Copyright (C) 1992-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.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, 2, 32, FALSE, 0,
+ complain_overflow_bitfield, 0, "r_imm32", TRUE, 0xffffffff,
+ 0xffffffff, FALSE);
+
+static reloc_howto_type r_imm4l =
+HOWTO (R_IMM4L, 0, 0, 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, 0, 8, FALSE, 0,
+ complain_overflow_bitfield, 0, "r_imm8", TRUE, 0x000000ff, 0x000000ff,
+ FALSE);
+
+static reloc_howto_type r_rel16 =
+HOWTO (R_REL16, 0, 1, 16, FALSE, 0,
+ complain_overflow_bitfield, 0, "r_rel16", TRUE, 0x0000ffff, 0x0000ffff,
+ TRUE);
+
+static reloc_howto_type r_jr =
+HOWTO (R_JR, 1, 0, 8, TRUE, 0, complain_overflow_signed, 0,
+ "r_jr", TRUE, 0xff, 0xff, TRUE);
+
+static reloc_howto_type r_disp7 =
+HOWTO (R_DISP7, 0, 0, 7, TRUE, 0, complain_overflow_bitfield, 0,
+ "r_disp7", TRUE, 0x7f, 0x7f, TRUE);
+
+static reloc_howto_type r_callr =
+HOWTO (R_CALLR, 1, 1, 12, TRUE, 0, complain_overflow_signed, 0,
+ "r_callr", TRUE, 0xfff, 0xfff, TRUE);
+
+#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 H_GET_32
+#define SWAP_OUT_RELOC_OFFSET 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 (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_DISP7:
+ internal->howto = &r_disp7;
+ break;
+ case R_CALLR:
+ internal->howto = &r_callr;
+ break;
+ case R_REL16:
+ internal->howto = &r_rel16;
+ break;
+ case R_IMM32:
+ internal->howto = &r_imm32;
+ break;
+ case R_IMM4L:
+ internal->howto = &r_imm4l;
+ break;
+ }
+}
+
+#define RTYPE2HOWTO(internal, relocentry) rtype2howto (internal, relocentry)
+
+static reloc_howto_type *
+coff_z8k_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ bfd_reloc_code_real_type code)
+{
+ switch (code)
+ {
+ case BFD_RELOC_8: return & r_imm8;
+ case BFD_RELOC_16: return & r_da;
+ case BFD_RELOC_32: return & r_imm32;
+ case BFD_RELOC_8_PCREL: return & r_jr;
+ case BFD_RELOC_16_PCREL: return & r_rel16;
+ case BFD_RELOC_Z8K_DISP7: return & r_disp7;
+ case BFD_RELOC_Z8K_CALLR: return & r_callr;
+ case BFD_RELOC_Z8K_IMM4L: return & r_imm4l;
+ default: BFD_FAIL ();
+ return 0;
+ }
+}
+
+static reloc_howto_type *
+coff_z8k_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ const char *r_name)
+{
+ if (strcasecmp (r_imm8.name, r_name) == 0)
+ return &r_imm8;
+ if (strcasecmp (r_da.name, r_name) == 0)
+ return &r_da;
+ if (strcasecmp (r_imm32.name, r_name) == 0)
+ return &r_imm32;
+ if (strcasecmp (r_jr.name, r_name) == 0)
+ return &r_jr;
+ if (strcasecmp (r_rel16.name, r_name) == 0)
+ return &r_rel16;
+ if (strcasecmp (r_disp7.name, r_name) == 0)
+ return &r_disp7;
+ if (strcasecmp (r_callr.name, r_name) == 0)
+ return &r_callr;
+ if (strcasecmp (r_imm4l.name, r_name) == 0)
+ return &r_imm4l;
+
+ return NULL;
+}
+
+/* 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 (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 (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:
+ /* If no flags are set, assume immediate value. */
+ if (! (*reloc->sym_ptr_ptr)->section->flags)
+ {
+ bfd_put_32 (in_abfd,
+ bfd_coff_reloc16_get_value (reloc, link_info,
+ input_section),
+ data + *dst_ptr);
+ }
+ else
+ {
+ bfd_vma dst = bfd_coff_reloc16_get_value (reloc, link_info,
+ input_section);
+ /* Addresses are 23 bit, and the layout of those in a 32-bit
+ value is as follows:
+ 1AAAAAAA xxxxxxxx AAAAAAAA AAAAAAAA
+ (A - address bits, x - ignore). */
+ dst = (dst & 0xffff) | ((dst & 0xff0000) << 8) | 0x80000000;
+ bfd_put_32 (in_abfd, dst, 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 = (*dst_ptr
+ + input_section->output_offset
+ + input_section->output_section->vma);
+ int gap = dst - dot - 1; /* -1, since we're 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, NULL,
+ 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_DISP7:
+ {
+ bfd_vma dst = bfd_coff_reloc16_get_value (reloc, link_info,
+ input_section);
+ bfd_vma dot = (*dst_ptr
+ + input_section->output_offset
+ + input_section->output_section->vma);
+ int gap = dst - dot - 1; /* -1, since we're in the odd byte of the
+ word and the pc's been incremented. */
+
+ if (gap & 1)
+ abort ();
+ gap /= 2;
+
+ if (gap > 0 || gap < -127)
+ {
+ if (! ((*link_info->callbacks->reloc_overflow)
+ (link_info, NULL,
+ 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,
+ (bfd_get_8 ( in_abfd, data + *dst_ptr) & 0x80) + (-gap & 0x7f),
+ data + *dst_ptr);
+ (*dst_ptr)++;
+ (*src_ptr)++;
+ break;
+ }
+
+ case R_CALLR:
+ {
+ bfd_vma dst = bfd_coff_reloc16_get_value (reloc, link_info,
+ input_section);
+ bfd_vma dot = (*dst_ptr
+ + input_section->output_offset
+ + input_section->output_section->vma);
+ int gap = dst - dot - 2;
+
+ if (gap & 1)
+ abort ();
+ if (gap > 4096 || gap < -4095)
+ {
+ if (! ((*link_info->callbacks->reloc_overflow)
+ (link_info, NULL,
+ bfd_asymbol_name (*reloc->sym_ptr_ptr),
+ reloc->howto->name, reloc->addend, input_section->owner,
+ input_section, reloc->address)))
+ abort ();
+ }
+ gap /= 2;
+ bfd_put_16 (in_abfd,
+ (bfd_get_16 ( in_abfd, data + *dst_ptr) & 0xf000) | (-gap & 0x0fff),
+ data + *dst_ptr);
+ (*dst_ptr) += 2;
+ (*src_ptr) += 2;
+ break;
+ }
+
+ case R_REL16:
+ {
+ bfd_vma dst = bfd_coff_reloc16_get_value (reloc, link_info,
+ input_section);
+ bfd_vma dot = (*dst_ptr
+ + input_section->output_offset
+ + input_section->output_section->vma);
+ int gap = dst - dot - 2;
+
+ if (gap > 32767 || gap < -32768)
+ {
+ if (! ((*link_info->callbacks->reloc_overflow)
+ (link_info, NULL,
+ 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, (bfd_vma) gap, data + *dst_ptr);
+ (*dst_ptr) += 2;
+ (*src_ptr) += 2;
+ break;
+ }
+
+ default:
+ abort ();
+ }
+}
+
+#define coff_reloc16_extra_cases extra_case
+#define coff_bfd_reloc_type_lookup coff_z8k_reloc_type_lookup
+#define coff_bfd_reloc_name_lookup coff_z8k_reloc_name_lookup
+
+#ifndef bfd_pe_print_pdata
+#define bfd_pe_print_pdata NULL
+#endif
+
+#include "coffcode.h"
+
+#undef coff_bfd_get_relocated_section_contents
+#define coff_bfd_get_relocated_section_contents \
+ bfd_coff_reloc16_get_relocated_section_contents
+
+#undef coff_bfd_relax_section
+#define coff_bfd_relax_section bfd_coff_reloc16_relax_section
+
+CREATE_BIG_COFF_TARGET_VEC (z8k_coff_vec, "coff-z8k", 0, 0, '_', NULL, COFF_SWAP_TABLE)
diff --git a/bfd/coff64-rs6000.c b/bfd/coff64-rs6000.c
new file mode 100644
index 0000000..5985d81
--- /dev/null
+++ b/bfd/coff64-rs6000.c
@@ -0,0 +1,3021 @@
+/* BFD back-end for IBM RS/6000 "XCOFF64" files.
+ Copyright (C) 2000-2014 Free Software Foundation, Inc.
+ Written Clinton Popetz.
+ Contributed 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "bfdlink.h"
+#include "libbfd.h"
+#include "coff/internal.h"
+#include "coff/xcoff.h"
+#include "coff/rs6k64.h"
+#include "libcoff.h"
+#include "libxcoff.h"
+
+#define GET_FILEHDR_SYMPTR H_GET_64
+#define PUT_FILEHDR_SYMPTR H_PUT_64
+#define GET_AOUTHDR_DATA_START H_GET_64
+#define PUT_AOUTHDR_DATA_START H_PUT_64
+#define GET_AOUTHDR_TEXT_START H_GET_64
+#define PUT_AOUTHDR_TEXT_START H_PUT_64
+#define GET_AOUTHDR_TSIZE H_GET_64
+#define PUT_AOUTHDR_TSIZE H_PUT_64
+#define GET_AOUTHDR_DSIZE H_GET_64
+#define PUT_AOUTHDR_DSIZE H_PUT_64
+#define GET_AOUTHDR_BSIZE H_GET_64
+#define PUT_AOUTHDR_BSIZE H_PUT_64
+#define GET_AOUTHDR_ENTRY H_GET_64
+#define PUT_AOUTHDR_ENTRY H_PUT_64
+#define GET_SCNHDR_PADDR H_GET_64
+#define PUT_SCNHDR_PADDR H_PUT_64
+#define GET_SCNHDR_VADDR H_GET_64
+#define PUT_SCNHDR_VADDR H_PUT_64
+#define GET_SCNHDR_SIZE H_GET_64
+#define PUT_SCNHDR_SIZE H_PUT_64
+#define GET_SCNHDR_SCNPTR H_GET_64
+#define PUT_SCNHDR_SCNPTR H_PUT_64
+#define GET_SCNHDR_RELPTR H_GET_64
+#define PUT_SCNHDR_RELPTR H_PUT_64
+#define GET_SCNHDR_LNNOPTR H_GET_64
+#define PUT_SCNHDR_LNNOPTR H_PUT_64
+#define GET_SCNHDR_NRELOC H_GET_32
+#define MAX_SCNHDR_NRELOC 0xffffffff
+#define PUT_SCNHDR_NRELOC H_PUT_32
+#define GET_SCNHDR_NLNNO H_GET_32
+#define MAX_SCNHDR_NLNNO 0xffffffff
+#define PUT_SCNHDR_NLNNO H_PUT_32
+#define GET_RELOC_VADDR H_GET_64
+#define PUT_RELOC_VADDR H_PUT_64
+
+#define COFF_FORCE_SYMBOLS_IN_STRINGS
+#define COFF_DEBUG_STRING_WIDE_PREFIX
+
+
+#define COFF_ADJUST_SCNHDR_OUT_POST(ABFD, INT, EXT) \
+ do \
+ { \
+ memset (((SCNHDR *) EXT)->s_pad, 0, \
+ sizeof (((SCNHDR *) EXT)->s_pad)); \
+ } \
+ while (0)
+
+#define NO_COFF_LINENOS
+
+#define coff_SWAP_lineno_in _bfd_xcoff64_swap_lineno_in
+#define coff_SWAP_lineno_out _bfd_xcoff64_swap_lineno_out
+
+static void _bfd_xcoff64_swap_lineno_in
+ (bfd *, void *, void *);
+static unsigned int _bfd_xcoff64_swap_lineno_out
+ (bfd *, void *, void *);
+static bfd_boolean _bfd_xcoff64_put_symbol_name
+ (bfd *, struct bfd_strtab_hash *, struct internal_syment *, const char *);
+static bfd_boolean _bfd_xcoff64_put_ldsymbol_name
+ (bfd *, struct xcoff_loader_info *, struct internal_ldsym *, const char *);
+static void _bfd_xcoff64_swap_sym_in
+ (bfd *, void *, void *);
+static unsigned int _bfd_xcoff64_swap_sym_out
+ (bfd *, void *, void *);
+static void _bfd_xcoff64_swap_aux_in
+ (bfd *, void *, int, int, int, int, void *);
+static unsigned int _bfd_xcoff64_swap_aux_out
+ (bfd *, void *, int, int, int, int, void *);
+static void xcoff64_swap_reloc_in
+ (bfd *, void *, void *);
+static unsigned int xcoff64_swap_reloc_out
+ (bfd *, void *, void *);
+extern bfd_boolean _bfd_xcoff_mkobject
+ (bfd *);
+extern bfd_boolean _bfd_xcoff_copy_private_bfd_data
+ (bfd *, bfd *);
+extern bfd_boolean _bfd_xcoff_is_local_label_name
+ (bfd *, const char *);
+extern void xcoff64_rtype2howto
+ (arelent *, struct internal_reloc *);
+extern reloc_howto_type * xcoff64_reloc_type_lookup
+ (bfd *, bfd_reloc_code_real_type);
+extern bfd_boolean _bfd_xcoff_slurp_armap
+ (bfd *);
+extern void *_bfd_xcoff_read_ar_hdr
+ (bfd *);
+extern bfd *_bfd_xcoff_openr_next_archived_file
+ (bfd *, bfd *);
+extern int _bfd_xcoff_stat_arch_elt
+ (bfd *, struct stat *);
+extern bfd_boolean _bfd_xcoff_write_armap
+ (bfd *, unsigned int, struct orl *, unsigned int, int);
+extern bfd_boolean _bfd_xcoff_write_archive_contents
+ (bfd *);
+extern int _bfd_xcoff_sizeof_headers
+ (bfd *, struct bfd_link_info *);
+extern void _bfd_xcoff_swap_sym_in
+ (bfd *, void *, void *);
+extern unsigned int _bfd_xcoff_swap_sym_out
+ (bfd *, void *, void *);
+extern void _bfd_xcoff_swap_aux_in
+ (bfd *, void *, int, int, int, int, void *);
+extern unsigned int _bfd_xcoff_swap_aux_out
+ (bfd *, void *, int, int, int, int, void *);
+static void xcoff64_swap_ldhdr_in
+ (bfd *, const void *, struct internal_ldhdr *);
+static void xcoff64_swap_ldhdr_out
+ (bfd *, const struct internal_ldhdr *, void *d);
+static void xcoff64_swap_ldsym_in
+ (bfd *, const void *, struct internal_ldsym *);
+static void xcoff64_swap_ldsym_out
+ (bfd *, const struct internal_ldsym *, void *d);
+static void xcoff64_swap_ldrel_in
+ (bfd *, const void *, struct internal_ldrel *);
+static void xcoff64_swap_ldrel_out
+ (bfd *, const struct internal_ldrel *, void *d);
+static bfd_boolean xcoff64_write_object_contents
+ (bfd *);
+static bfd_boolean xcoff64_ppc_relocate_section
+ (bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
+ struct internal_reloc *, struct internal_syment *,
+ asection **);
+static bfd_boolean xcoff64_slurp_armap
+ (bfd *);
+static const bfd_target *xcoff64_archive_p
+ (bfd *);
+static bfd *xcoff64_openr_next_archived_file
+ (bfd *, bfd *);
+static int xcoff64_sizeof_headers
+ (bfd *, struct bfd_link_info *);
+static asection *xcoff64_create_csect_from_smclas
+ (bfd *, union internal_auxent *, const char *);
+static bfd_boolean xcoff64_is_lineno_count_overflow
+ (bfd *, bfd_vma);
+static bfd_boolean xcoff64_is_reloc_count_overflow
+ (bfd *, bfd_vma);
+static bfd_vma xcoff64_loader_symbol_offset
+ (bfd *, struct internal_ldhdr *);
+static bfd_vma xcoff64_loader_reloc_offset
+ (bfd *, struct internal_ldhdr *);
+static bfd_boolean xcoff64_generate_rtinit
+ (bfd *, const char *, const char *, bfd_boolean);
+static bfd_boolean xcoff64_bad_format_hook
+ (bfd *, void *);
+
+/* Relocation functions */
+static bfd_boolean xcoff64_reloc_type_br
+ (XCOFF_RELOC_FUNCTION_ARGS);
+
+bfd_boolean (*xcoff64_calculate_relocation[XCOFF_MAX_CALCULATE_RELOCATION])
+ (XCOFF_RELOC_FUNCTION_ARGS) =
+{
+ xcoff_reloc_type_pos, /* R_POS (0x00) */
+ xcoff_reloc_type_neg, /* R_NEG (0x01) */
+ xcoff_reloc_type_rel, /* R_REL (0x02) */
+ xcoff_reloc_type_toc, /* R_TOC (0x03) */
+ xcoff_reloc_type_fail, /* R_RTB (0x04) */
+ xcoff_reloc_type_toc, /* R_GL (0x05) */
+ xcoff_reloc_type_toc, /* R_TCL (0x06) */
+ xcoff_reloc_type_fail, /* (0x07) */
+ xcoff_reloc_type_ba, /* R_BA (0x08) */
+ xcoff_reloc_type_fail, /* (0x09) */
+ xcoff64_reloc_type_br, /* R_BR (0x0a) */
+ xcoff_reloc_type_fail, /* (0x0b) */
+ xcoff_reloc_type_pos, /* R_RL (0x0c) */
+ xcoff_reloc_type_pos, /* R_RLA (0x0d) */
+ xcoff_reloc_type_fail, /* (0x0e) */
+ xcoff_reloc_type_noop, /* R_REF (0x0f) */
+ xcoff_reloc_type_fail, /* (0x10) */
+ xcoff_reloc_type_fail, /* (0x11) */
+ xcoff_reloc_type_toc, /* R_TRL (0x12) */
+ xcoff_reloc_type_toc, /* R_TRLA (0x13) */
+ xcoff_reloc_type_fail, /* R_RRTBI (0x14) */
+ xcoff_reloc_type_fail, /* R_RRTBA (0x15) */
+ xcoff_reloc_type_ba, /* R_CAI (0x16) */
+ xcoff_reloc_type_crel, /* R_CREL (0x17) */
+ xcoff_reloc_type_ba, /* R_RBA (0x18) */
+ xcoff_reloc_type_ba, /* R_RBAC (0x19) */
+ xcoff64_reloc_type_br, /* R_RBR (0x1a) */
+ xcoff_reloc_type_ba, /* R_RBRC (0x1b) */
+};
+
+/* coffcode.h needs these to be defined. */
+/* Internalcoff.h and coffcode.h modify themselves based on these flags. */
+#define XCOFF64
+#define RS6000COFF_C 1
+
+#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 NO_COFF_SYMBOLS
+#define RTYPE2HOWTO(cache_ptr, dst) xcoff64_rtype2howto (cache_ptr, dst)
+#define coff_mkobject _bfd_xcoff_mkobject
+#define coff_bfd_copy_private_bfd_data _bfd_xcoff_copy_private_bfd_data
+#define coff_bfd_is_local_label_name _bfd_xcoff_is_local_label_name
+#define coff_bfd_reloc_type_lookup xcoff64_reloc_type_lookup
+#define coff_bfd_reloc_name_lookup xcoff64_reloc_name_lookup
+#ifdef AIX_CORE
+extern const bfd_target * rs6000coff_core_p
+ (bfd *abfd);
+extern bfd_boolean rs6000coff_core_file_matches_executable_p
+ (bfd *cbfd, bfd *ebfd);
+extern char *rs6000coff_core_file_failing_command
+ (bfd *abfd);
+extern int rs6000coff_core_file_failing_signal
+ (bfd *abfd);
+#define CORE_FILE_P rs6000coff_core_p
+#define coff_core_file_failing_command \
+ rs6000coff_core_file_failing_command
+#define coff_core_file_failing_signal \
+ rs6000coff_core_file_failing_signal
+#define coff_core_file_matches_executable_p \
+ rs6000coff_core_file_matches_executable_p
+#define coff_core_file_pid \
+ _bfd_nocore_core_file_pid
+#else
+#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
+#define coff_core_file_pid \
+ _bfd_nocore_core_file_pid
+#endif
+#define coff_SWAP_sym_in _bfd_xcoff64_swap_sym_in
+#define coff_SWAP_sym_out _bfd_xcoff64_swap_sym_out
+#define coff_SWAP_aux_in _bfd_xcoff64_swap_aux_in
+#define coff_SWAP_aux_out _bfd_xcoff64_swap_aux_out
+#define coff_swap_reloc_in xcoff64_swap_reloc_in
+#define coff_swap_reloc_out xcoff64_swap_reloc_out
+#define NO_COFF_RELOCS
+
+#ifndef bfd_pe_print_pdata
+#define bfd_pe_print_pdata NULL
+#endif
+
+#include <stdint.h>
+#include "coffcode.h"
+
+/* For XCOFF64, the effective width of symndx changes depending on
+ whether we are the first entry. Sigh. */
+static void
+_bfd_xcoff64_swap_lineno_in (bfd *abfd, void *ext1, void *in1)
+{
+ LINENO *ext = (LINENO *) ext1;
+ struct internal_lineno *in = (struct internal_lineno *) in1;
+
+ in->l_lnno = H_GET_32 (abfd, (ext->l_lnno));
+ if (in->l_lnno == 0)
+ in->l_addr.l_symndx = H_GET_32 (abfd, ext->l_addr.l_symndx);
+ else
+ in->l_addr.l_paddr = H_GET_64 (abfd, ext->l_addr.l_paddr);
+}
+
+static unsigned int
+_bfd_xcoff64_swap_lineno_out (bfd *abfd, void *inp, void *outp)
+{
+ struct internal_lineno *in = (struct internal_lineno *) inp;
+ struct external_lineno *ext = (struct external_lineno *) outp;
+
+ H_PUT_32 (abfd, in->l_addr.l_symndx, ext->l_addr.l_symndx);
+ H_PUT_32 (abfd, in->l_lnno, (ext->l_lnno));
+
+ if (in->l_lnno == 0)
+ H_PUT_32 (abfd, in->l_addr.l_symndx, ext->l_addr.l_symndx);
+ else
+ H_PUT_64 (abfd, in->l_addr.l_paddr, ext->l_addr.l_paddr);
+
+ return bfd_coff_linesz (abfd);
+}
+
+static void
+_bfd_xcoff64_swap_sym_in (bfd *abfd, void *ext1, void *in1)
+{
+ struct external_syment *ext = (struct external_syment *) ext1;
+ struct internal_syment *in = (struct internal_syment *) in1;
+
+ in->_n._n_n._n_zeroes = 0;
+ in->_n._n_n._n_offset = H_GET_32 (abfd, ext->e_offset);
+ in->n_value = H_GET_64 (abfd, ext->e_value);
+ in->n_scnum = H_GET_16 (abfd, ext->e_scnum);
+ in->n_type = H_GET_16 (abfd, ext->e_type);
+ in->n_sclass = H_GET_8 (abfd, ext->e_sclass);
+ in->n_numaux = H_GET_8 (abfd, ext->e_numaux);
+}
+
+static unsigned int
+_bfd_xcoff64_swap_sym_out (bfd *abfd, void *inp, void *extp)
+{
+ struct internal_syment *in = (struct internal_syment *) inp;
+ struct external_syment *ext = (struct external_syment *) extp;
+
+ H_PUT_32 (abfd, in->_n._n_n._n_offset, ext->e_offset);
+ H_PUT_64 (abfd, in->n_value, ext->e_value);
+ H_PUT_16 (abfd, in->n_scnum, ext->e_scnum);
+ H_PUT_16 (abfd, in->n_type, ext->e_type);
+ H_PUT_8 (abfd, in->n_sclass, ext->e_sclass);
+ H_PUT_8 (abfd, in->n_numaux, ext->e_numaux);
+ return bfd_coff_symesz (abfd);
+}
+
+static void
+_bfd_xcoff64_swap_aux_in (bfd *abfd, void *ext1, int type, int in_class,
+ int indx, int numaux, void *in1)
+{
+ union external_auxent *ext = (union external_auxent *) ext1;
+ union internal_auxent *in = (union internal_auxent *) in1;
+
+ switch (in_class)
+ {
+ case C_FILE:
+ if (ext->x_file.x_n.x_n.x_zeroes[0] == 0)
+ {
+ in->x_file.x_n.x_zeroes = 0;
+ in->x_file.x_n.x_offset =
+ H_GET_32 (abfd, ext->x_file.x_n.x_n.x_offset);
+ }
+ else
+ {
+ memcpy (in->x_file.x_fname, ext->x_file.x_n.x_fname, FILNMLEN);
+ }
+ goto end;
+
+ /* RS/6000 "csect" auxents */
+ case C_EXT:
+ case C_AIX_WEAKEXT:
+ case C_HIDEXT:
+ if (indx + 1 == numaux)
+ {
+ bfd_signed_vma h = 0;
+ bfd_vma l = 0;
+
+ h = H_GET_S32 (abfd, ext->x_csect.x_scnlen_hi);
+ l = H_GET_32 (abfd, ext->x_csect.x_scnlen_lo);
+
+ in->x_csect.x_scnlen.l = h << 32 | (l & 0xffffffff);
+
+ in->x_csect.x_parmhash = H_GET_32 (abfd, ext->x_csect.x_parmhash);
+ in->x_csect.x_snhash = 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 = H_GET_8 (abfd, ext->x_csect.x_smtyp);
+ in->x_csect.x_smclas = H_GET_8 (abfd, ext->x_csect.x_smclas);
+ goto end;
+ }
+ break;
+
+ case C_STAT:
+ case C_LEAFSTAT:
+ case C_HIDDEN:
+ if (type == T_NULL)
+ {
+ /* 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;
+ }
+
+ if (in_class == C_BLOCK || in_class == C_FCN || ISFCN (type)
+ || ISTAG (in_class))
+ {
+ in->x_sym.x_fcnary.x_fcn.x_lnnoptr
+ = H_GET_64 (abfd, ext->x_sym.x_fcnary.x_fcn.x_lnnoptr);
+ in->x_sym.x_fcnary.x_fcn.x_endndx.l
+ = H_GET_32 (abfd, ext->x_sym.x_fcnary.x_fcn.x_endndx);
+ }
+ if (ISFCN (type))
+ {
+ in->x_sym.x_misc.x_fsize
+ = H_GET_32 (abfd, ext->x_sym.x_fcnary.x_fcn.x_fsize);
+ }
+ else
+ {
+ in->x_sym.x_misc.x_lnsz.x_lnno
+ = H_GET_32 (abfd, ext->x_sym.x_fcnary.x_lnsz.x_lnno);
+ in->x_sym.x_misc.x_lnsz.x_size
+ = H_GET_16 (abfd, ext->x_sym.x_fcnary.x_lnsz.x_size);
+ }
+
+ end: ;
+}
+
+static unsigned int
+_bfd_xcoff64_swap_aux_out (bfd *abfd, void *inp, int type, int in_class,
+ int indx ATTRIBUTE_UNUSED,
+ int numaux ATTRIBUTE_UNUSED,
+ void *extp)
+{
+ union internal_auxent *in = (union internal_auxent *) inp;
+ union external_auxent *ext = (union external_auxent *) extp;
+
+ memset (ext, 0, bfd_coff_auxesz (abfd));
+ switch (in_class)
+ {
+ case C_FILE:
+ if (in->x_file.x_n.x_zeroes == 0)
+ {
+ H_PUT_32 (abfd, 0, ext->x_file.x_n.x_n.x_zeroes);
+ H_PUT_32 (abfd, in->x_file.x_n.x_offset,
+ ext->x_file.x_n.x_n.x_offset);
+ }
+ else
+ {
+ memcpy (ext->x_file.x_n.x_fname, in->x_file.x_fname, FILNMLEN);
+ }
+ H_PUT_8 (abfd, _AUX_FILE, ext->x_auxtype.x_auxtype);
+ goto end;
+
+ /* RS/6000 "csect" auxents */
+ case C_EXT:
+ case C_AIX_WEAKEXT:
+ case C_HIDEXT:
+ if (indx + 1 == numaux)
+ {
+ bfd_vma temp;
+
+ temp = in->x_csect.x_scnlen.l & 0xffffffff;
+ H_PUT_32 (abfd, temp, ext->x_csect.x_scnlen_lo);
+ temp = in->x_csect.x_scnlen.l >> 32;
+ H_PUT_32 (abfd, temp, ext->x_csect.x_scnlen_hi);
+ H_PUT_32 (abfd, in->x_csect.x_parmhash, ext->x_csect.x_parmhash);
+ H_PUT_16 (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. */
+ H_PUT_8 (abfd, in->x_csect.x_smtyp, ext->x_csect.x_smtyp);
+ H_PUT_8 (abfd, in->x_csect.x_smclas, ext->x_csect.x_smclas);
+ H_PUT_8 (abfd, _AUX_CSECT, ext->x_auxtype.x_auxtype);
+ goto end;
+ }
+ break;
+
+ case C_STAT:
+ case C_LEAFSTAT:
+ case C_HIDDEN:
+ if (type == T_NULL)
+ {
+ goto end;
+ }
+ break;
+ }
+
+ if (in_class == C_BLOCK || in_class == C_FCN || ISFCN (type)
+ || ISTAG (in_class))
+ {
+ H_PUT_64 (abfd, in->x_sym.x_fcnary.x_fcn.x_lnnoptr,
+ ext->x_sym.x_fcnary.x_fcn.x_lnnoptr);
+ H_PUT_8 (abfd, _AUX_FCN,
+ ext->x_auxtype.x_auxtype);
+ H_PUT_32 (abfd, in->x_sym.x_fcnary.x_fcn.x_endndx.l,
+ ext->x_sym.x_fcnary.x_fcn.x_endndx);
+ }
+ if (ISFCN (type))
+ {
+ H_PUT_32 (abfd, in->x_sym.x_misc.x_fsize,
+ ext->x_sym.x_fcnary.x_fcn.x_fsize);
+ }
+ else
+ {
+ H_PUT_32 (abfd, in->x_sym.x_misc.x_lnsz.x_lnno,
+ ext->x_sym.x_fcnary.x_lnsz.x_lnno);
+ H_PUT_16 (abfd, in->x_sym.x_misc.x_lnsz.x_size,
+ ext->x_sym.x_fcnary.x_lnsz.x_size);
+ }
+
+ end:
+
+ return bfd_coff_auxesz (abfd);
+}
+
+static bfd_boolean
+_bfd_xcoff64_put_symbol_name (bfd *abfd, struct bfd_strtab_hash *strtab,
+ struct internal_syment *sym,
+ const char *name)
+{
+ bfd_boolean hash;
+ bfd_size_type indx;
+
+ hash = TRUE;
+
+ if ((abfd->flags & BFD_TRADITIONAL_FORMAT) != 0)
+ hash = FALSE;
+
+ indx = _bfd_stringtab_add (strtab, name, hash, FALSE);
+
+ if (indx == (bfd_size_type) -1)
+ return FALSE;
+
+ sym->_n._n_n._n_zeroes = 0;
+ sym->_n._n_n._n_offset = STRING_SIZE_SIZE + indx;
+
+ return TRUE;
+}
+
+static bfd_boolean
+_bfd_xcoff64_put_ldsymbol_name (bfd *abfd ATTRIBUTE_UNUSED,
+ struct xcoff_loader_info *ldinfo,
+ struct internal_ldsym *ldsym,
+ const char *name)
+{
+ size_t len;
+ len = strlen (name);
+
+ if (ldinfo->string_size + len + 3 > ldinfo->string_alc)
+ {
+ bfd_size_type newalc;
+ char *newstrings;
+
+ newalc = ldinfo->string_alc * 2;
+ if (newalc == 0)
+ newalc = 32;
+ while (ldinfo->string_size + len + 3 > newalc)
+ newalc *= 2;
+
+ newstrings = bfd_realloc (ldinfo->strings, newalc);
+ if (newstrings == NULL)
+ {
+ ldinfo->failed = TRUE;
+ return FALSE;
+ }
+ ldinfo->string_alc = newalc;
+ ldinfo->strings = newstrings;
+ }
+
+ bfd_put_16 (ldinfo->output_bfd, (bfd_vma) (len + 1),
+ ldinfo->strings + ldinfo->string_size);
+ strcpy (ldinfo->strings + ldinfo->string_size + 2, name);
+ ldsym->_l._l_l._l_zeroes = 0;
+ ldsym->_l._l_l._l_offset = ldinfo->string_size + 2;
+ ldinfo->string_size += len + 3;
+
+ return TRUE;
+}
+
+/* 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
+xcoff64_swap_ldhdr_in (bfd *abfd,
+ const void *s,
+ struct internal_ldhdr *dst)
+{
+ const struct external_ldhdr *src = (const struct external_ldhdr *) s;
+
+ 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_stlen = bfd_get_32 (abfd, src->l_stlen);
+ dst->l_impoff = bfd_get_64 (abfd, src->l_impoff);
+ dst->l_stoff = bfd_get_64 (abfd, src->l_stoff);
+ dst->l_symoff = bfd_get_64 (abfd, src->l_symoff);
+ dst->l_rldoff = bfd_get_64 (abfd, src->l_rldoff);
+}
+
+/* Swap out the ldhdr structure. */
+
+static void
+xcoff64_swap_ldhdr_out (bfd *abfd, const struct internal_ldhdr *src, void *d)
+{
+ struct external_ldhdr *dst = (struct external_ldhdr *) d;
+
+ bfd_put_32 (abfd, (bfd_vma) 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_stlen, dst->l_stlen);
+ bfd_put_64 (abfd, src->l_impoff, dst->l_impoff);
+ bfd_put_64 (abfd, src->l_stoff, dst->l_stoff);
+ bfd_put_64 (abfd, src->l_symoff, dst->l_symoff);
+ bfd_put_64 (abfd, src->l_rldoff, dst->l_rldoff);
+}
+
+/* Swap in the ldsym structure. */
+
+static void
+xcoff64_swap_ldsym_in (bfd *abfd, const void *s, struct internal_ldsym *dst)
+{
+ const struct external_ldsym *src = (const struct external_ldsym *) s;
+ /* XCOFF64 does not use l_zeroes like XCOFF32
+ Set the internal l_zeroes to 0 so the common 32/64 code uses l_value
+ as an offset into the loader symbol table. */
+ dst->_l._l_l._l_zeroes = 0;
+ dst->_l._l_l._l_offset = bfd_get_32 (abfd, src->l_offset);
+ dst->l_value = bfd_get_64 (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
+xcoff64_swap_ldsym_out (bfd *abfd, const struct internal_ldsym *src, void *d)
+{
+ struct external_ldsym *dst = (struct external_ldsym *) d;
+
+ bfd_put_64 (abfd, src->l_value, dst->l_value);
+ bfd_put_32 (abfd, (bfd_vma) src->_l._l_l._l_offset, dst->l_offset);
+ bfd_put_16 (abfd, (bfd_vma) 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);
+}
+
+static void
+xcoff64_swap_reloc_in (bfd *abfd, void *s, void *d)
+{
+ struct external_reloc *src = (struct external_reloc *) s;
+ struct internal_reloc *dst = (struct internal_reloc *) d;
+
+ memset (dst, 0, sizeof (struct internal_reloc));
+
+ dst->r_vaddr = bfd_get_64 (abfd, src->r_vaddr);
+ dst->r_symndx = bfd_get_32 (abfd, src->r_symndx);
+ dst->r_size = bfd_get_8 (abfd, src->r_size);
+ dst->r_type = bfd_get_8 (abfd, src->r_type);
+}
+
+static unsigned int
+xcoff64_swap_reloc_out (bfd *abfd, void *s, void *d)
+{
+ struct internal_reloc *src = (struct internal_reloc *) s;
+ struct external_reloc *dst = (struct external_reloc *) d;
+
+ bfd_put_64 (abfd, src->r_vaddr, dst->r_vaddr);
+ bfd_put_32 (abfd, src->r_symndx, dst->r_symndx);
+ bfd_put_8 (abfd, src->r_type, dst->r_type);
+ bfd_put_8 (abfd, src->r_size, dst->r_size);
+
+ return bfd_coff_relsz (abfd);
+}
+
+/* Swap in the ldrel structure. */
+
+static void
+xcoff64_swap_ldrel_in (bfd *abfd, const void *s, struct internal_ldrel *dst)
+{
+ const struct external_ldrel *src = (const struct external_ldrel *) s;
+
+ dst->l_vaddr = bfd_get_64 (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
+xcoff64_swap_ldrel_out (bfd *abfd, const struct internal_ldrel *src, void *d)
+{
+ struct external_ldrel *dst = (struct external_ldrel *) d;
+
+ bfd_put_64 (abfd, src->l_vaddr, dst->l_vaddr);
+ bfd_put_16 (abfd, (bfd_vma) src->l_rtype, dst->l_rtype);
+ bfd_put_16 (abfd, (bfd_vma) src->l_rsecnm, dst->l_rsecnm);
+ bfd_put_32 (abfd, src->l_symndx, dst->l_symndx);
+}
+
+static bfd_boolean
+xcoff64_write_object_contents (bfd *abfd)
+{
+ asection *current;
+ bfd_boolean hasrelocs = FALSE;
+ bfd_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;
+ asection *text_sec = NULL;
+ asection *data_sec = NULL;
+ asection *bss_sec = NULL;
+ struct internal_filehdr internal_f;
+ struct internal_aouthdr internal_a;
+
+ bfd_set_error (bfd_error_system_call);
+
+ if (! abfd->output_has_begun)
+ {
+ if (! bfd_coff_compute_section_file_positions (abfd))
+ return FALSE;
+ }
+
+ /* Work out the size of the reloc and linno areas. */
+ reloc_base = obj_relocbase (abfd);
+
+ for (current = abfd->sections; current != NULL; current = current->next)
+ reloc_size += current->reloc_count * bfd_coff_relsz (abfd);
+
+ lineno_base = reloc_base + reloc_size;
+
+ /* 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) * bfd_coff_linesz (abfd);
+
+ 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 * bfd_coff_linesz (abfd);
+ }
+ else
+ {
+ current->line_filepos = 0;
+ }
+
+ if (current->reloc_count)
+ {
+ current->rel_filepos = reloc_base;
+ reloc_base += current->reloc_count * bfd_coff_relsz (abfd);
+ }
+ else
+ {
+ current->rel_filepos = 0;
+ }
+ }
+
+ if ((abfd->flags & EXEC_P) != 0)
+ {
+ scn_base = bfd_coff_filhsz (abfd) + bfd_coff_aoutsz (abfd);
+ internal_f.f_opthdr = bfd_coff_aoutsz (abfd);
+ }
+ else
+ {
+ scn_base = bfd_coff_filhsz (abfd);
+ internal_f.f_opthdr = 0;
+ }
+
+ internal_f.f_nscns = 0;
+
+ if (bfd_seek (abfd, scn_base, SEEK_SET) != 0)
+ return FALSE;
+
+ for (current = abfd->sections; current != NULL; current = current->next)
+ {
+ struct internal_scnhdr section;
+ struct external_scnhdr buff;
+ bfd_size_type amount;
+
+ internal_f.f_nscns++;
+
+ strncpy (section.s_name, current->name, SCNNMLEN);
+
+ section.s_vaddr = current->vma;
+ section.s_paddr = current->lma;
+ section.s_size = current->size;
+
+ /* If this section has no size or is unloadable then the scnptr
+ will be 0 too. */
+ if (current->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;
+
+ 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;
+ }
+
+ amount = bfd_coff_scnhsz (abfd);
+ if (bfd_coff_swap_scnhdr_out (abfd, &section, &buff) == 0
+ || bfd_bwrite (&buff, amount, abfd) != amount)
+ return FALSE;
+ }
+
+ internal_f.f_timdat = 0;
+
+ internal_f.f_flags = 0;
+
+ 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;
+
+ 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;
+
+ memset (&internal_a, 0, sizeof internal_a);
+
+ internal_f.f_magic = bfd_xcoff_magic_number (abfd);
+ internal_a.magic = (abfd->flags & D_PAGED
+ ? RS6K_AOUTHDR_ZMAGIC
+ : (abfd->flags & WP_TEXT
+ ? RS6K_AOUTHDR_NMAGIC
+ : RS6K_AOUTHDR_OMAGIC));
+
+ /* 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;
+
+ internal_f.f_symptr = 0;
+ internal_f.f_nsyms = 0;
+
+ /* 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 (bfd_get_symcount (abfd) != 0)
+ {
+ int firstundef;
+
+ 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;
+
+ internal_f.f_symptr = sym_base;
+ internal_f.f_nsyms = bfd_get_symcount (abfd);
+ }
+ else if (obj_raw_syment_count (abfd) != 0)
+ {
+ internal_f.f_symptr = sym_base;
+
+ /* AIX appears to require that F_RELFLG not be set if there are
+ local symbols but no relocations. */
+ internal_f.f_flags &=~ F_RELFLG;
+ }
+ else
+ {
+ internal_f.f_flags |= F_LSYMS;
+ }
+
+ if (text_sec)
+ {
+ internal_a.tsize = text_sec->size;
+ internal_a.text_start = internal_a.tsize ? text_sec->vma : 0;
+ }
+
+ if (data_sec)
+ {
+ internal_a.dsize = data_sec->size;
+ internal_a.data_start = internal_a.dsize ? data_sec->vma : 0;
+ }
+
+ if (bss_sec)
+ {
+ internal_a.bsize = bss_sec->size;
+ 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);
+
+ 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) == bfd_mach_ppc)
+ internal_a.o_cputype = 3;
+ else if (bfd_get_mach (abfd) == bfd_mach_ppc_620)
+ internal_a.o_cputype = 2;
+ 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;
+ }
+
+ if (bfd_seek (abfd, (file_ptr) 0, 0) != 0)
+ return FALSE;
+
+ {
+ char * buff;
+ bfd_size_type amount = bfd_coff_filhsz (abfd);
+
+ buff = bfd_malloc (amount);
+ if (buff == NULL)
+ return FALSE;
+
+ bfd_coff_swap_filehdr_out (abfd, &internal_f, buff);
+ amount = bfd_bwrite (buff, amount, abfd);
+
+ free (buff);
+
+ if (amount != bfd_coff_filhsz (abfd))
+ return FALSE;
+ }
+
+ if (abfd->flags & EXEC_P)
+ {
+ char * buff;
+ bfd_size_type amount = bfd_coff_aoutsz (abfd);
+
+ buff = bfd_malloc (amount);
+ if (buff == NULL)
+ return FALSE;
+
+ bfd_coff_swap_aouthdr_out (abfd, &internal_a, buff);
+ amount = bfd_bwrite (buff, amount, abfd);
+
+ free (buff);
+
+ if (amount != bfd_coff_aoutsz (abfd))
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static bfd_boolean
+xcoff64_reloc_type_br (bfd *input_bfd,
+ asection *input_section,
+ bfd *output_bfd ATTRIBUTE_UNUSED,
+ struct internal_reloc *rel,
+ struct internal_syment *sym ATTRIBUTE_UNUSED,
+ struct reloc_howto_struct *howto,
+ bfd_vma val,
+ bfd_vma addend,
+ bfd_vma *relocation,
+ bfd_byte *contents)
+{
+ struct xcoff_link_hash_entry *h;
+ bfd_vma section_offset;
+
+ if (0 > rel->r_symndx)
+ return FALSE;
+
+ h = obj_xcoff_sym_hashes (input_bfd)[rel->r_symndx];
+ section_offset = rel->r_vaddr - input_section->vma;
+
+ /* 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 ld r2,40(r1). This
+ restores the TOC after the glink code. Contrariwise, if the
+ call is followed by a ld r2,40(r1), but the call is not
+ going to global linkage code, we can replace the load with a
+ cror. */
+ if (NULL != h
+ && (bfd_link_hash_defined == h->root.type
+ || bfd_link_hash_defweak == h->root.type)
+ && section_offset + 8 <= input_section->size)
+ {
+ bfd_byte *pnext;
+ unsigned long next;
+
+ pnext = contents + section_offset + 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 */
+ || next == 0x60000000) /* ori r0,r0,0 */
+ bfd_put_32 (input_bfd, 0xe8410028, pnext); /* ld r2,40(r1) */
+ }
+ else
+ {
+ if (next == 0xe8410028) /* ld r2,40(r1) */
+ bfd_put_32 (input_bfd, 0x60000000, pnext); /* ori r0,r0,0 */
+ }
+ }
+ else if (NULL != h && bfd_link_hash_undefined == h->root.type)
+ {
+ /* Normally, this relocation is against a defined symbol. In the
+ case where this is a partial link and the output section offset
+ is greater than 2^25, the linker will return an invalid error
+ message that the relocation has been truncated. Yes it has been
+ truncated but no it not important. For this case, disable the
+ overflow checking. */
+ howto->complain_on_overflow = complain_overflow_dont;
+ }
+
+ /* The original PC-relative relocation is biased by -r_vaddr, so adding
+ the value below will give the absolute target address. */
+ *relocation = val + addend + rel->r_vaddr;
+
+ howto->src_mask &= ~3;
+ howto->dst_mask = howto->src_mask;
+
+ if (h != NULL
+ && (h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak)
+ && bfd_is_abs_section (h->root.u.def.section)
+ && section_offset + 4 <= input_section->size)
+ {
+ bfd_byte *ptr;
+ bfd_vma insn;
+
+ /* Turn the relative branch into an absolute one by setting the
+ AA bit. */
+ ptr = contents + section_offset;
+ insn = bfd_get_32 (input_bfd, ptr);
+ insn |= 2;
+ bfd_put_32 (input_bfd, insn, ptr);
+
+ /* Make the howto absolute too. */
+ howto->pc_relative = FALSE;
+ howto->complain_on_overflow = complain_overflow_bitfield;
+ }
+ else
+ {
+ /* Use a PC-relative howto and subtract the instruction's address
+ from the target address we calculated above. */
+ howto->pc_relative = TRUE;
+ *relocation -= (input_section->output_section->vma
+ + input_section->output_offset
+ + section_offset);
+ }
+ return TRUE;
+}
+
+/* This is the relocation function for the PowerPC64.
+ See xcoff_ppc_relocation_section for more information. */
+
+bfd_boolean
+xcoff64_ppc_relocate_section (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_vma relocation;
+ bfd_vma value_to_relocate;
+ bfd_vma address;
+ bfd_byte *location;
+
+ /* 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;
+
+ /* howto */
+ howto.type = rel->r_type;
+ howto.rightshift = 0;
+ howto.bitsize = (rel->r_size & 0x3f) + 1;
+ howto.size = howto.bitsize > 16 ? (howto.bitsize > 32 ? 4 : 2) : 1;
+ howto.pc_relative = FALSE;
+ howto.bitpos = 0;
+ howto.complain_on_overflow = (rel->r_size & 0x80
+ ? complain_overflow_signed
+ : complain_overflow_bitfield);
+ howto.special_function = NULL;
+ howto.name = "internal";
+ howto.partial_inplace = TRUE;
+ howto.src_mask = howto.dst_mask = N_ONES (howto.bitsize);
+ howto.pcrel_offset = FALSE;
+
+ /* symbol */
+ val = 0;
+ addend = 0;
+ h = NULL;
+ sym = NULL;
+ symndx = rel->r_symndx;
+
+ if (-1 != symndx)
+ {
+ asection *sec;
+
+ h = obj_xcoff_sym_hashes (input_bfd)[symndx];
+ sym = syms + symndx;
+ addend = - sym->n_value;
+
+ if (NULL == h)
+ {
+ 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 (info->unresolved_syms_in_objects != RM_IGNORE
+ && (h->flags & XCOFF_WAS_UNDEFINED) != 0)
+ {
+ if (! ((*info->callbacks->undefined_symbol)
+ (info, h->root.root.string,
+ input_bfd, input_section,
+ rel->r_vaddr - input_section->vma,
+ (info->unresolved_syms_in_objects
+ == RM_GENERATE_ERROR))))
+ return FALSE;
+ }
+ 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 (h->root.type == bfd_link_hash_common)
+ {
+ sec = h->root.u.c.p->section;
+ val = (sec->output_section->vma
+ + sec->output_offset);
+ }
+ else
+ {
+ BFD_ASSERT (info->relocatable
+ || (h->flags & XCOFF_DEF_DYNAMIC) != 0
+ || (h->flags & XCOFF_IMPORT) != 0);
+ }
+ }
+ }
+
+ if (rel->r_type >= XCOFF_MAX_CALCULATE_RELOCATION
+ || !((*xcoff64_calculate_relocation[rel->r_type])
+ (input_bfd, input_section, output_bfd, rel, sym, &howto, val,
+ addend, &relocation, contents)))
+ return FALSE;
+
+ /* address */
+ address = rel->r_vaddr - input_section->vma;
+ location = contents + address;
+
+ if (address > input_section->size)
+ abort ();
+
+ /* Get the value we are going to relocate. */
+ if (1 == howto.size)
+ value_to_relocate = bfd_get_16 (input_bfd, location);
+ else if (2 == howto.size)
+ value_to_relocate = bfd_get_32 (input_bfd, location);
+ else
+ value_to_relocate = bfd_get_64 (input_bfd, location);
+
+ /* 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. */
+
+ if ((unsigned int) howto.complain_on_overflow
+ >= XCOFF_MAX_COMPLAIN_OVERFLOW)
+ abort ();
+
+ if (((*xcoff_complain_overflow[howto.complain_on_overflow])
+ (input_bfd, value_to_relocate, relocation, &howto)))
+ {
+ const char *name;
+ char buf[SYMNMLEN + 1];
+ char reloc_type_name[10];
+
+ if (symndx == -1)
+ {
+ name = "*ABS*";
+ }
+ else if (h != NULL)
+ {
+ name = NULL;
+ }
+ else
+ {
+ name = _bfd_coff_internal_syment_name (input_bfd, sym, buf);
+ if (name == NULL)
+ name = "UNKNOWN";
+ }
+ sprintf (reloc_type_name, "0x%02x", rel->r_type);
+
+ if (! ((*info->callbacks->reloc_overflow)
+ (info, (h ? &h->root : NULL), name, reloc_type_name,
+ (bfd_vma) 0, input_bfd, input_section,
+ rel->r_vaddr - input_section->vma)))
+ return FALSE;
+ }
+
+ /* Add RELOCATION to the right bits of VALUE_TO_RELOCATE. */
+ value_to_relocate = ((value_to_relocate & ~howto.dst_mask)
+ | (((value_to_relocate & howto.src_mask)
+ + relocation) & howto.dst_mask));
+
+ /* Put the value back in the object file. */
+ if (1 == howto.size)
+ bfd_put_16 (input_bfd, value_to_relocate, location);
+ else if (2 == howto.size)
+ bfd_put_32 (input_bfd, value_to_relocate, location);
+ else
+ bfd_put_64 (input_bfd, value_to_relocate, location);
+
+ }
+ return TRUE;
+}
+
+
+/* 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. */
+
+reloc_howto_type xcoff64_howto_table[] =
+{
+ /* 0x00: Standard 64 bit relocation. */
+ HOWTO (R_POS, /* 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 */
+ "R_POS_64", /* name */
+ TRUE, /* partial_inplace */
+ MINUS_ONE, /* src_mask */
+ MINUS_ONE, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* 0x01: 64 bit relocation, but store negative value. */
+ HOWTO (R_NEG, /* 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 */
+ "R_NEG", /* name */
+ TRUE, /* partial_inplace */
+ MINUS_ONE, /* src_mask */
+ MINUS_ONE, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* 0x02: 32 bit PC relative relocation. */
+ HOWTO (R_REL, /* 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 */
+
+ /* 0x03: 16 bit TOC relative relocation. */
+ HOWTO (R_TOC, /* 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 */
+
+ /* 0x04: I don't really know what this is. */
+ HOWTO (R_RTB, /* 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 */
+
+ /* 0x05: External TOC relative symbol. */
+ HOWTO (R_GL, /* 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_GL", /* name */
+ TRUE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* 0x06: Local TOC relative symbol. */
+ HOWTO (R_TCL, /* 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_TCL", /* name */
+ TRUE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ EMPTY_HOWTO (7),
+
+ /* 0x08: Non modifiable absolute branch. */
+ HOWTO (R_BA, /* 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_26", /* name */
+ TRUE, /* partial_inplace */
+ 0x03fffffc, /* src_mask */
+ 0x03fffffc, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ EMPTY_HOWTO (9),
+
+ /* 0x0a: Non modifiable relative branch. */
+ HOWTO (R_BR, /* 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 */
+ 0x03fffffc, /* src_mask */
+ 0x03fffffc, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ EMPTY_HOWTO (0xb),
+
+ /* 0x0c: Indirect load. */
+ HOWTO (R_RL, /* 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_RL", /* name */
+ TRUE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* 0x0d: Load address. */
+ HOWTO (R_RLA, /* 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_RLA", /* name */
+ TRUE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ EMPTY_HOWTO (0xe),
+
+ /* 0x0f: Non-relocating reference. Bitsize is 1 so that r_rsize is 0. */
+ HOWTO (R_REF, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 1, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ 0, /* special_function */
+ "R_REF", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ EMPTY_HOWTO (0x10),
+ EMPTY_HOWTO (0x11),
+
+ /* 0x12: TOC relative indirect load. */
+ HOWTO (R_TRL, /* 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_TRL", /* name */
+ TRUE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* 0x13: TOC relative load address. */
+ HOWTO (R_TRLA, /* 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_TRLA", /* name */
+ TRUE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* 0x14: Modifiable relative branch. */
+ HOWTO (R_RRTBI, /* 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 */
+
+ /* 0x15: Modifiable absolute branch. */
+ HOWTO (R_RRTBA, /* 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 */
+
+ /* 0x16: Modifiable call absolute indirect. */
+ HOWTO (R_CAI, /* 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_CAI", /* name */
+ TRUE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* 0x17: Modifiable call relative. */
+ HOWTO (R_CREL, /* 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_CREL", /* name */
+ TRUE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* 0x18: Modifiable branch absolute. */
+ HOWTO (R_RBA, /* 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_RBA", /* name */
+ TRUE, /* partial_inplace */
+ 0x03fffffc, /* src_mask */
+ 0x03fffffc, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* 0x19: Modifiable branch absolute. */
+ HOWTO (R_RBAC, /* 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_RBAC", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* 0x1a: Modifiable branch relative. */
+ HOWTO (R_RBR, /* 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_26", /* name */
+ TRUE, /* partial_inplace */
+ 0x03fffffc, /* src_mask */
+ 0x03fffffc, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* 0x1b: Modifiable branch absolute. */
+ HOWTO (R_RBRC, /* 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_RBRC", /* name */
+ TRUE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* 0x1c: Standard 32 bit relocation. */
+ HOWTO (R_POS, /* 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_32", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* 0x1d: 16 bit Non modifiable absolute branch. */
+ HOWTO (R_BA, /* 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_BA_16", /* name */
+ TRUE, /* partial_inplace */
+ 0xfffc, /* src_mask */
+ 0xfffc, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* 0x1e: Modifiable branch relative. */
+ HOWTO (R_RBR, /* 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 */
+ "R_RBR_16", /* name */
+ TRUE, /* partial_inplace */
+ 0xfffc, /* src_mask */
+ 0xfffc, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* 0x1f: Modifiable branch absolute. */
+ HOWTO (R_RBA, /* 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_RBA_16", /* name */
+ TRUE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+};
+
+void
+xcoff64_rtype2howto (arelent *relent, struct internal_reloc *internal)
+{
+ if (internal->r_type > R_RBRC)
+ abort ();
+
+ /* Default howto layout works most of the time */
+ relent->howto = &xcoff64_howto_table[internal->r_type];
+
+ /* Special case some 16 bit reloc */
+ if (15 == (internal->r_size & 0x3f))
+ {
+ if (R_BA == internal->r_type)
+ relent->howto = &xcoff64_howto_table[0x1d];
+ else if (R_RBR == internal->r_type)
+ relent->howto = &xcoff64_howto_table[0x1e];
+ else if (R_RBA == internal->r_type)
+ relent->howto = &xcoff64_howto_table[0x1f];
+ }
+ /* Special case 32 bit */
+ else if (31 == (internal->r_size & 0x3f))
+ {
+ if (R_POS == internal->r_type)
+ relent->howto = &xcoff64_howto_table[0x1c];
+ }
+
+ /* 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. The bitsize is not significant
+ for R_REF relocs. */
+ if (relent->howto->dst_mask != 0
+ && (relent->howto->bitsize
+ != ((unsigned int) internal->r_size & 0x3f) + 1))
+ abort ();
+}
+
+reloc_howto_type *
+xcoff64_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ bfd_reloc_code_real_type code)
+{
+ switch (code)
+ {
+ case BFD_RELOC_PPC_B26:
+ return &xcoff64_howto_table[0xa];
+ case BFD_RELOC_PPC_BA16:
+ return &xcoff64_howto_table[0x1d];
+ case BFD_RELOC_PPC_BA26:
+ return &xcoff64_howto_table[8];
+ case BFD_RELOC_PPC_TOC16:
+ return &xcoff64_howto_table[3];
+ case BFD_RELOC_16:
+ /* Note that this relocation is only internally used by gas. */
+ return &xcoff64_howto_table[0xc];
+ case BFD_RELOC_PPC_B16:
+ return &xcoff64_howto_table[0x1e];
+ case BFD_RELOC_32:
+ case BFD_RELOC_CTOR:
+ return &xcoff64_howto_table[0x1c];
+ case BFD_RELOC_64:
+ return &xcoff64_howto_table[0];
+ case BFD_RELOC_NONE:
+ return &xcoff64_howto_table[0xf];
+ default:
+ return NULL;
+ }
+}
+
+static reloc_howto_type *
+xcoff64_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ const char *r_name)
+{
+ unsigned int i;
+
+ for (i = 0;
+ i < sizeof (xcoff64_howto_table) / sizeof (xcoff64_howto_table[0]);
+ i++)
+ if (xcoff64_howto_table[i].name != NULL
+ && strcasecmp (xcoff64_howto_table[i].name, r_name) == 0)
+ return &xcoff64_howto_table[i];
+
+ return NULL;
+}
+
+/* Read in the armap of an XCOFF archive. */
+
+static bfd_boolean
+xcoff64_slurp_armap (bfd *abfd)
+{
+ file_ptr off;
+ size_t namlen;
+ bfd_size_type sz, amt;
+ bfd_byte *contents, *cend;
+ bfd_vma c, i;
+ carsym *arsym;
+ bfd_byte *p;
+ file_ptr pos;
+
+ /* This is for the new format. */
+ struct xcoff_ar_hdr_big hdr;
+
+ if (xcoff_ardata (abfd) == NULL)
+ {
+ bfd_has_map (abfd) = FALSE;
+ return TRUE;
+ }
+
+ off = bfd_scan_vma (xcoff_ardata_big (abfd)->symoff64,
+ (const 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_bread (&hdr, (bfd_size_type) SIZEOF_AR_HDR_BIG, abfd)
+ != SIZEOF_AR_HDR_BIG)
+ return FALSE;
+
+ /* Skip the name (normally empty). */
+ namlen = strtol (hdr.namlen, (char **) NULL, 10);
+ pos = ((namlen + 1) & ~(size_t) 1) + SXCOFFARFMAG;
+ if (bfd_seek (abfd, pos, SEEK_CUR) != 0)
+ return FALSE;
+
+ sz = bfd_scan_vma (hdr.size, (const char **) NULL, 10);
+
+ /* Read in the entire symbol table. */
+ contents = (bfd_byte *) bfd_alloc (abfd, sz);
+ if (contents == NULL)
+ return FALSE;
+ if (bfd_bread (contents, sz, abfd) != sz)
+ return FALSE;
+
+ /* The symbol table starts with an eight byte count. */
+ c = H_GET_64 (abfd, contents);
+
+ if (c * 8 >= sz)
+ {
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+ amt = c;
+ amt *= sizeof (carsym);
+ bfd_ardata (abfd)->symdefs = (carsym *) bfd_alloc (abfd, amt);
+ if (bfd_ardata (abfd)->symdefs == NULL)
+ return FALSE;
+
+ /* After the count comes a list of eight byte file offsets. */
+ for (i = 0, arsym = bfd_ardata (abfd)->symdefs, p = contents + 8;
+ i < c;
+ ++i, ++arsym, p += 8)
+ arsym->file_offset = H_GET_64 (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 NEW XCOFF archive. */
+
+static const bfd_target *
+xcoff64_archive_p (bfd *abfd)
+{
+ struct artdata *tdata_hold;
+ char magic[SXCOFFARMAG];
+ /* This is the new format. */
+ struct xcoff_ar_file_hdr_big hdr;
+ bfd_size_type amt = SXCOFFARMAG;
+
+ if (bfd_bread (magic, amt, abfd) != amt)
+ {
+ if (bfd_get_error () != bfd_error_system_call)
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+
+ if (strncmp (magic, XCOFFARMAGBIG, SXCOFFARMAG) != 0)
+ {
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+
+ /* Copy over the magic string. */
+ memcpy (hdr.magic, magic, SXCOFFARMAG);
+
+ /* Now read the rest of the file header. */
+ amt = SIZEOF_AR_FILE_HDR_BIG - SXCOFFARMAG;
+ if (bfd_bread (&hdr.memoff, amt, abfd) != amt)
+ {
+ if (bfd_get_error () != bfd_error_system_call)
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+
+ tdata_hold = bfd_ardata (abfd);
+
+ amt = sizeof (struct artdata);
+ bfd_ardata (abfd) = (struct artdata *) bfd_zalloc (abfd, amt);
+ if (bfd_ardata (abfd) == (struct artdata *) NULL)
+ goto error_ret_restore;
+
+ /* Already cleared by bfd_zalloc above.
+ 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)->extended_names_size = 0; */
+ bfd_ardata (abfd)->first_file_filepos = bfd_scan_vma (hdr.firstmemoff,
+ (const char **) NULL,
+ 10);
+
+ amt = SIZEOF_AR_FILE_HDR_BIG;
+ bfd_ardata (abfd)->tdata = bfd_zalloc (abfd, amt);
+ if (bfd_ardata (abfd)->tdata == NULL)
+ goto error_ret;
+
+ memcpy (bfd_ardata (abfd)->tdata, &hdr, SIZEOF_AR_FILE_HDR_BIG);
+
+ if (! xcoff64_slurp_armap (abfd))
+ {
+ error_ret:
+ bfd_release (abfd, bfd_ardata (abfd));
+ error_ret_restore:
+ bfd_ardata (abfd) = tdata_hold;
+ return NULL;
+ }
+
+ return abfd->xvec;
+}
+
+
+/* Open the next element in an XCOFF archive. */
+
+static bfd *
+xcoff64_openr_next_archived_file (bfd *archive, bfd *last_file)
+{
+ bfd_vma filestart;
+
+ if ((xcoff_ardata (archive) == NULL)
+ || ! xcoff_big_format_p (archive))
+ {
+ bfd_set_error (bfd_error_invalid_operation);
+ return NULL;
+ }
+
+ if (last_file == NULL)
+ {
+ filestart = bfd_ardata (archive)->first_file_filepos;
+ }
+ else
+ {
+ filestart = bfd_scan_vma (arch_xhdr_big (last_file)->nextoff,
+ (const char **) NULL, 10);
+ }
+
+ if (filestart == 0
+ || filestart == bfd_scan_vma (xcoff_ardata_big (archive)->memoff,
+ (const char **) NULL, 10)
+ || filestart == bfd_scan_vma (xcoff_ardata_big (archive)->symoff,
+ (const char **) NULL, 10))
+ {
+ bfd_set_error (bfd_error_no_more_archived_files);
+ return NULL;
+ }
+
+ return _bfd_get_elt_at_filepos (archive, (file_ptr) filestart);
+}
+
+/* We can't use the usual coff_sizeof_headers routine, because AIX
+ always uses an a.out header. */
+
+static int
+xcoff64_sizeof_headers (bfd *abfd,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED)
+{
+ int size;
+
+ size = bfd_coff_filhsz (abfd);
+
+ /* Don't think the small aout header can be used since some of the
+ old elements have been reordered past the end of the old coff
+ small aout size. */
+
+ if (xcoff_data (abfd)->full_aouthdr)
+ size += bfd_coff_aoutsz (abfd);
+
+ size += abfd->section_count * bfd_coff_scnhsz (abfd);
+ return size;
+}
+
+static asection *
+xcoff64_create_csect_from_smclas (bfd *abfd, union internal_auxent *aux,
+ const char *symbol_name)
+{
+ asection *return_value = NULL;
+
+ /* Changes from 32 :
+ .sv == 8, is only for 32 bit programs
+ .ti == 12 and .tb == 13 are now reserved. */
+ static const char *names[19] =
+ {
+ ".pr", ".ro", ".db", ".tc", ".ua", ".rw", ".gl", ".xo",
+ NULL, ".bs", ".ds", ".uc", NULL, NULL, NULL, ".tc0",
+ ".td", ".sv64", ".sv3264"
+ };
+
+ if ((19 >= aux->x_csect.x_smclas)
+ && (NULL != names[aux->x_csect.x_smclas]))
+ {
+
+ return_value = bfd_make_section_anyway
+ (abfd, names[aux->x_csect.x_smclas]);
+
+ }
+ else
+ {
+ (*_bfd_error_handler)
+ (_("%B: symbol `%s' has unrecognized smclas %d"),
+ abfd, symbol_name, aux->x_csect.x_smclas);
+ bfd_set_error (bfd_error_bad_value);
+ }
+
+ return return_value;
+}
+
+static bfd_boolean
+xcoff64_is_lineno_count_overflow (bfd *abfd ATTRIBUTE_UNUSED,
+ bfd_vma value ATTRIBUTE_UNUSED)
+{
+ return FALSE;
+}
+
+static bfd_boolean
+xcoff64_is_reloc_count_overflow (bfd *abfd ATTRIBUTE_UNUSED,
+ bfd_vma value ATTRIBUTE_UNUSED)
+{
+ return FALSE;
+}
+
+static bfd_vma
+xcoff64_loader_symbol_offset (bfd *abfd ATTRIBUTE_UNUSED,
+ struct internal_ldhdr *ldhdr)
+{
+ return (ldhdr->l_symoff);
+}
+
+static bfd_vma
+xcoff64_loader_reloc_offset (bfd *abfd ATTRIBUTE_UNUSED,
+ struct internal_ldhdr *ldhdr)
+{
+ return (ldhdr->l_rldoff);
+}
+
+static bfd_boolean
+xcoff64_bad_format_hook (bfd * abfd, void *filehdr)
+{
+ struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr;
+
+ /* Check flavor first. */
+ if (bfd_get_flavour (abfd) != bfd_target_xcoff_flavour)
+ return FALSE;
+
+ if (bfd_xcoff_magic_number (abfd) != internal_f->f_magic)
+ return FALSE;
+
+ return TRUE;
+}
+
+static bfd_boolean
+xcoff64_generate_rtinit (bfd *abfd, const char *init, const char *fini,
+ bfd_boolean rtld)
+{
+ bfd_byte filehdr_ext[FILHSZ];
+ bfd_byte scnhdr_ext[SCNHSZ * 3];
+ bfd_byte syment_ext[SYMESZ * 10];
+ bfd_byte reloc_ext[RELSZ * 3];
+ bfd_byte *data_buffer;
+ bfd_size_type data_buffer_size;
+ bfd_byte *string_table, *st_tmp;
+ bfd_size_type string_table_size;
+ bfd_vma val;
+ size_t initsz, finisz;
+ struct internal_filehdr filehdr;
+ struct internal_scnhdr text_scnhdr;
+ struct internal_scnhdr data_scnhdr;
+ struct internal_scnhdr bss_scnhdr;
+ struct internal_syment syment;
+ union internal_auxent auxent;
+ struct internal_reloc reloc;
+
+ char *text_name = ".text";
+ char *data_name = ".data";
+ char *bss_name = ".bss";
+ char *rtinit_name = "__rtinit";
+ char *rtld_name = "__rtld";
+
+ if (! bfd_xcoff_rtinit_size (abfd))
+ return FALSE;
+
+ initsz = (init == NULL ? 0 : 1 + strlen (init));
+ finisz = (fini == NULL ? 0 : 1 + strlen (fini));
+
+ /* File header. */
+ memset (filehdr_ext, 0, FILHSZ);
+ memset (&filehdr, 0, sizeof (struct internal_filehdr));
+ filehdr.f_magic = bfd_xcoff_magic_number (abfd);
+ filehdr.f_nscns = 3;
+ filehdr.f_timdat = 0;
+ filehdr.f_nsyms = 0; /* at least 6, no more than 8 */
+ filehdr.f_symptr = 0; /* set below */
+ filehdr.f_opthdr = 0;
+ filehdr.f_flags = 0;
+
+ /* Section headers. */
+ memset (scnhdr_ext, 0, 3 * SCNHSZ);
+
+ /* Text. */
+ memset (&text_scnhdr, 0, sizeof (struct internal_scnhdr));
+ memcpy (text_scnhdr.s_name, text_name, strlen (text_name));
+ text_scnhdr.s_paddr = 0;
+ text_scnhdr.s_vaddr = 0;
+ text_scnhdr.s_size = 0;
+ text_scnhdr.s_scnptr = 0;
+ text_scnhdr.s_relptr = 0;
+ text_scnhdr.s_lnnoptr = 0;
+ text_scnhdr.s_nreloc = 0;
+ text_scnhdr.s_nlnno = 0;
+ text_scnhdr.s_flags = STYP_TEXT;
+
+ /* Data. */
+ memset (&data_scnhdr, 0, sizeof (struct internal_scnhdr));
+ memcpy (data_scnhdr.s_name, data_name, strlen (data_name));
+ data_scnhdr.s_paddr = 0;
+ data_scnhdr.s_vaddr = 0;
+ data_scnhdr.s_size = 0; /* set below */
+ data_scnhdr.s_scnptr = FILHSZ + 3 * SCNHSZ;
+ data_scnhdr.s_relptr = 0; /* set below */
+ data_scnhdr.s_lnnoptr = 0;
+ data_scnhdr.s_nreloc = 0; /* either 1 or 2 */
+ data_scnhdr.s_nlnno = 0;
+ data_scnhdr.s_flags = STYP_DATA;
+
+ /* Bss. */
+ memset (&bss_scnhdr, 0, sizeof (struct internal_scnhdr));
+ memcpy (bss_scnhdr.s_name, bss_name, strlen (bss_name));
+ bss_scnhdr.s_paddr = 0; /* set below */
+ bss_scnhdr.s_vaddr = 0; /* set below */
+ bss_scnhdr.s_size = 0; /* set below */
+ bss_scnhdr.s_scnptr = 0;
+ bss_scnhdr.s_relptr = 0;
+ bss_scnhdr.s_lnnoptr = 0;
+ bss_scnhdr.s_nreloc = 0;
+ bss_scnhdr.s_nlnno = 0;
+ bss_scnhdr.s_flags = STYP_BSS;
+
+ /* .data
+ 0x0000 0x00000000 : rtl
+ 0x0004 0x00000000 :
+ 0x0008 0x00000018 : offset to init, or 0
+ 0x000C 0x00000038 : offset to fini, or 0
+ 0x0010 0x00000010 : size of descriptor
+ 0x0014 0x00000000 : pad
+ 0x0018 0x00000000 : init, needs a reloc
+ 0x001C 0x00000000 :
+ 0x0020 0x00000058 : offset to init name
+ 0x0024 0x00000000 : flags, padded to a word
+ 0x0028 0x00000000 : empty init
+ 0x002C 0x00000000 :
+ 0x0030 0x00000000 :
+ 0x0034 0x00000000 :
+ 0x0038 0x00000000 : fini, needs a reloc
+ 0x003C 0x00000000 :
+ 0x0040 0x00000??? : offset to fini name
+ 0x0044 0x00000000 : flags, padded to a word
+ 0x0048 0x00000000 : empty fini
+ 0x004C 0x00000000 :
+ 0x0050 0x00000000 :
+ 0x0054 0x00000000 :
+ 0x0058 init name
+ 0x0058 + initsz fini name */
+
+ data_buffer_size = 0x0058 + initsz + finisz;
+ data_buffer_size = (data_buffer_size + 7) &~ (bfd_size_type) 7;
+ data_buffer = NULL;
+ data_buffer = (bfd_byte *) bfd_zmalloc (data_buffer_size);
+ if (data_buffer == NULL)
+ return FALSE;
+
+ if (initsz)
+ {
+ val = 0x18;
+ bfd_put_32 (abfd, val, &data_buffer[0x08]);
+ val = 0x58;
+ bfd_put_32 (abfd, val, &data_buffer[0x20]);
+ memcpy (&data_buffer[val], init, initsz);
+ }
+
+ if (finisz)
+ {
+ val = 0x38;
+ bfd_put_32 (abfd, val, &data_buffer[0x0C]);
+ val = 0x58 + initsz;
+ bfd_put_32 (abfd, val, &data_buffer[0x40]);
+ memcpy (&data_buffer[val], fini, finisz);
+ }
+
+ val = 0x10;
+ bfd_put_32 (abfd, val, &data_buffer[0x10]);
+ data_scnhdr.s_size = data_buffer_size;
+ bss_scnhdr.s_paddr = bss_scnhdr.s_vaddr = data_scnhdr.s_size;
+
+ /* String table. */
+ string_table_size = 4;
+ string_table_size += strlen (data_name) + 1;
+ string_table_size += strlen (rtinit_name) + 1;
+ string_table_size += initsz;
+ string_table_size += finisz;
+ if (rtld)
+ string_table_size += strlen (rtld_name) + 1;
+
+ string_table = (bfd_byte *) bfd_zmalloc (string_table_size);
+ if (string_table == NULL)
+ return FALSE;
+
+ val = string_table_size;
+ bfd_put_32 (abfd, val, &string_table[0]);
+ st_tmp = string_table + 4;
+
+ /* symbols
+ 0. .data csect
+ 2. __rtinit
+ 4. init function
+ 6. fini function
+ 8. __rtld */
+ memset (syment_ext, 0, 10 * SYMESZ);
+ memset (reloc_ext, 0, 3 * RELSZ);
+
+ /* .data csect */
+ memset (&syment, 0, sizeof (struct internal_syment));
+ memset (&auxent, 0, sizeof (union internal_auxent));
+
+ syment._n._n_n._n_offset = st_tmp - string_table;
+ memcpy (st_tmp, data_name, strlen (data_name));
+ st_tmp += strlen (data_name) + 1;
+
+ syment.n_scnum = 2;
+ syment.n_sclass = C_HIDEXT;
+ syment.n_numaux = 1;
+ auxent.x_csect.x_scnlen.l = data_buffer_size;
+ auxent.x_csect.x_smtyp = 3 << 3 | XTY_SD;
+ auxent.x_csect.x_smclas = XMC_RW;
+ bfd_coff_swap_sym_out (abfd, &syment,
+ &syment_ext[filehdr.f_nsyms * SYMESZ]);
+ bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0,
+ syment.n_numaux,
+ &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]);
+ filehdr.f_nsyms += 2;
+
+ /* __rtinit */
+ memset (&syment, 0, sizeof (struct internal_syment));
+ memset (&auxent, 0, sizeof (union internal_auxent));
+ syment._n._n_n._n_offset = st_tmp - string_table;
+ memcpy (st_tmp, rtinit_name, strlen (rtinit_name));
+ st_tmp += strlen (rtinit_name) + 1;
+
+ syment.n_scnum = 2;
+ syment.n_sclass = C_EXT;
+ syment.n_numaux = 1;
+ auxent.x_csect.x_smtyp = XTY_LD;
+ auxent.x_csect.x_smclas = XMC_RW;
+ bfd_coff_swap_sym_out (abfd, &syment,
+ &syment_ext[filehdr.f_nsyms * SYMESZ]);
+ bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0,
+ syment.n_numaux,
+ &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]);
+ filehdr.f_nsyms += 2;
+
+ /* Init. */
+ if (initsz)
+ {
+ memset (&syment, 0, sizeof (struct internal_syment));
+ memset (&auxent, 0, sizeof (union internal_auxent));
+
+ syment._n._n_n._n_offset = st_tmp - string_table;
+ memcpy (st_tmp, init, initsz);
+ st_tmp += initsz;
+
+ syment.n_sclass = C_EXT;
+ syment.n_numaux = 1;
+ bfd_coff_swap_sym_out (abfd, &syment,
+ &syment_ext[filehdr.f_nsyms * SYMESZ]);
+ bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0,
+ syment.n_numaux,
+ &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]);
+ /* Reloc. */
+ memset (&reloc, 0, sizeof (struct internal_reloc));
+ reloc.r_vaddr = 0x0018;
+ reloc.r_symndx = filehdr.f_nsyms;
+ reloc.r_type = R_POS;
+ reloc.r_size = 63;
+ bfd_coff_swap_reloc_out (abfd, &reloc, &reloc_ext[0]);
+
+ filehdr.f_nsyms += 2;
+ data_scnhdr.s_nreloc += 1;
+ }
+
+ /* Finit. */
+ if (finisz)
+ {
+ memset (&syment, 0, sizeof (struct internal_syment));
+ memset (&auxent, 0, sizeof (union internal_auxent));
+
+ syment._n._n_n._n_offset = st_tmp - string_table;
+ memcpy (st_tmp, fini, finisz);
+ st_tmp += finisz;
+
+ syment.n_sclass = C_EXT;
+ syment.n_numaux = 1;
+ bfd_coff_swap_sym_out (abfd, &syment,
+ &syment_ext[filehdr.f_nsyms * SYMESZ]);
+ bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0,
+ syment.n_numaux,
+ &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]);
+
+ /* Reloc. */
+ memset (&reloc, 0, sizeof (struct internal_reloc));
+ reloc.r_vaddr = 0x0038;
+ reloc.r_symndx = filehdr.f_nsyms;
+ reloc.r_type = R_POS;
+ reloc.r_size = 63;
+ bfd_coff_swap_reloc_out (abfd, &reloc,
+ &reloc_ext[data_scnhdr.s_nreloc * RELSZ]);
+
+ filehdr.f_nsyms += 2;
+ data_scnhdr.s_nreloc += 1;
+ }
+
+ if (rtld)
+ {
+ memset (&syment, 0, sizeof (struct internal_syment));
+ memset (&auxent, 0, sizeof (union internal_auxent));
+
+ syment._n._n_n._n_offset = st_tmp - string_table;
+ memcpy (st_tmp, rtld_name, strlen (rtld_name));
+ st_tmp += strlen (rtld_name) + 1;
+
+ syment.n_sclass = C_EXT;
+ syment.n_numaux = 1;
+ bfd_coff_swap_sym_out (abfd, &syment,
+ &syment_ext[filehdr.f_nsyms * SYMESZ]);
+ bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0,
+ syment.n_numaux,
+ &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]);
+
+ /* Reloc. */
+ memset (&reloc, 0, sizeof (struct internal_reloc));
+ reloc.r_vaddr = 0x0000;
+ reloc.r_symndx = filehdr.f_nsyms;
+ reloc.r_type = R_POS;
+ reloc.r_size = 63;
+ bfd_coff_swap_reloc_out (abfd, &reloc,
+ &reloc_ext[data_scnhdr.s_nreloc * RELSZ]);
+
+ filehdr.f_nsyms += 2;
+ data_scnhdr.s_nreloc += 1;
+
+ bss_scnhdr.s_size = 0;
+ }
+
+ data_scnhdr.s_relptr = data_scnhdr.s_scnptr + data_buffer_size;
+ filehdr.f_symptr = data_scnhdr.s_relptr + data_scnhdr.s_nreloc * RELSZ;
+
+ bfd_coff_swap_filehdr_out (abfd, &filehdr, filehdr_ext);
+ bfd_bwrite (filehdr_ext, FILHSZ, abfd);
+ bfd_coff_swap_scnhdr_out (abfd, &text_scnhdr, &scnhdr_ext[SCNHSZ * 0]);
+ bfd_coff_swap_scnhdr_out (abfd, &data_scnhdr, &scnhdr_ext[SCNHSZ * 1]);
+ bfd_coff_swap_scnhdr_out (abfd, &bss_scnhdr, &scnhdr_ext[SCNHSZ * 2]);
+ bfd_bwrite (scnhdr_ext, 3 * SCNHSZ, abfd);
+ bfd_bwrite (data_buffer, data_buffer_size, abfd);
+ bfd_bwrite (reloc_ext, data_scnhdr.s_nreloc * RELSZ, abfd);
+ bfd_bwrite (syment_ext, filehdr.f_nsyms * SYMESZ, abfd);
+ bfd_bwrite (string_table, string_table_size, abfd);
+
+ free (data_buffer);
+ data_buffer = NULL;
+
+ return TRUE;
+}
+
+/* The typical dynamic reloc. */
+
+static reloc_howto_type xcoff64_dynamic_reloc =
+HOWTO (0, /* 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 */
+ "R_POS", /* name */
+ TRUE, /* partial_inplace */
+ MINUS_ONE, /* src_mask */
+ MINUS_ONE, /* dst_mask */
+ FALSE); /* pcrel_offset */
+
+static unsigned long xcoff64_glink_code[10] =
+{
+ 0xe9820000, /* ld r12,0(r2) */
+ 0xf8410028, /* std r2,40(r1) */
+ 0xe80c0000, /* ld r0,0(r12) */
+ 0xe84c0008, /* ld r0,8(r12) */
+ 0x7c0903a6, /* mtctr r0 */
+ 0x4e800420, /* bctr */
+ 0x00000000, /* start of traceback table */
+ 0x000ca000, /* traceback table */
+ 0x00000000, /* traceback table */
+ 0x00000018, /* ??? */
+};
+
+static const struct xcoff_backend_data_rec bfd_xcoff_backend_data =
+ {
+ { /* COFF backend, defined in libcoff.h. */
+ _bfd_xcoff64_swap_aux_in,
+ _bfd_xcoff64_swap_sym_in,
+ _bfd_xcoff64_swap_lineno_in,
+ _bfd_xcoff64_swap_aux_out,
+ _bfd_xcoff64_swap_sym_out,
+ _bfd_xcoff64_swap_lineno_out,
+ xcoff64_swap_reloc_out,
+ coff_swap_filehdr_out,
+ coff_swap_aouthdr_out,
+ coff_swap_scnhdr_out,
+ FILHSZ,
+ AOUTSZ,
+ SCNHSZ,
+ SYMESZ,
+ AUXESZ,
+ RELSZ,
+ LINESZ,
+ FILNMLEN,
+ TRUE, /* _bfd_coff_long_filenames */
+ XCOFF_NO_LONG_SECTION_NAMES, /* _bfd_coff_long_section_names */
+ 3, /* _bfd_coff_default_section_alignment_power */
+ TRUE, /* _bfd_coff_force_symnames_in_strings */
+ 4, /* _bfd_coff_debug_string_prefix_length */
+ 32768, /* _bfd_coff_max_nscns */
+ coff_swap_filehdr_in,
+ coff_swap_aouthdr_in,
+ coff_swap_scnhdr_in,
+ xcoff64_swap_reloc_in,
+ xcoff64_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,
+ dummy_reloc16_extra_cases,
+ dummy_reloc16_estimate,
+ NULL, /* bfd_coff_symbol_classification */
+ coff_compute_section_file_positions,
+ NULL, /* _bfd_coff_start_final_link */
+ xcoff64_ppc_relocate_section,
+ coff_rtype_to_howto,
+ NULL, /* _bfd_coff_adjust_symndx */
+ _bfd_generic_link_add_one_symbol,
+ coff_link_output_has_begun,
+ coff_final_link_postscript,
+ NULL /* print_pdata. */
+ },
+
+ 0x01EF, /* magic number */
+ bfd_arch_powerpc,
+ bfd_mach_ppc_620,
+
+ /* Function pointers to xcoff specific swap routines. */
+ xcoff64_swap_ldhdr_in,
+ xcoff64_swap_ldhdr_out,
+ xcoff64_swap_ldsym_in,
+ xcoff64_swap_ldsym_out,
+ xcoff64_swap_ldrel_in,
+ xcoff64_swap_ldrel_out,
+
+ /* Sizes. */
+ LDHDRSZ,
+ LDSYMSZ,
+ LDRELSZ,
+ 24, /* _xcoff_function_descriptor_size */
+ 0, /* _xcoff_small_aout_header_size */
+
+ /* Versions. */
+ 2, /* _xcoff_ldhdr_version */
+
+ _bfd_xcoff64_put_symbol_name,
+ _bfd_xcoff64_put_ldsymbol_name,
+ &xcoff64_dynamic_reloc,
+ xcoff64_create_csect_from_smclas,
+
+ /* Lineno and reloc count overflow. */
+ xcoff64_is_lineno_count_overflow,
+ xcoff64_is_reloc_count_overflow,
+
+ xcoff64_loader_symbol_offset,
+ xcoff64_loader_reloc_offset,
+
+ /* glink. */
+ &xcoff64_glink_code[0],
+ 40, /* _xcoff_glink_size */
+
+ /* rtinit. */
+ 88, /* _xcoff_rtinit_size */
+ xcoff64_generate_rtinit,
+ };
+
+/* The transfer vector that leads the outside world to all of the above. */
+const bfd_target rs6000_xcoff64_vec =
+ {
+ "aixcoff64-rs6000",
+ bfd_target_xcoff_flavour,
+ BFD_ENDIAN_BIG, /* data byte order is big */
+ BFD_ENDIAN_BIG, /* header byte order is big */
+
+ (HAS_RELOC | EXEC_P | HAS_LINENO | HAS_DEBUG | DYNAMIC
+ | HAS_SYMS | HAS_LOCALS | WP_TEXT),
+
+ SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_DATA,
+ 0, /* leading char */
+ '/', /* ar_pad_char */
+ 15, /* ar_max_namelen */
+ 0, /* match priority. */
+
+ /* 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_check_format */
+ _bfd_dummy_target,
+ coff_object_p,
+ xcoff64_archive_p,
+ CORE_FILE_P
+ },
+
+ { /* bfd_set_format */
+ bfd_false,
+ coff_mkobject,
+ _bfd_generic_mkarchive,
+ bfd_false
+ },
+
+ {/* bfd_write_contents */
+ bfd_false,
+ xcoff64_write_object_contents,
+ _bfd_xcoff_write_archive_contents,
+ bfd_false
+ },
+
+ /* Generic */
+ _bfd_archive_close_and_cleanup,
+ bfd_true,
+ coff_new_section_hook,
+ _bfd_generic_get_section_contents,
+ _bfd_generic_get_section_contents_in_window,
+
+ /* Copy */
+ _bfd_xcoff_copy_private_bfd_data,
+ _bfd_generic_bfd_merge_private_bfd_data,
+ _bfd_generic_init_private_section_data,
+ _bfd_generic_bfd_copy_private_section_data,
+ _bfd_generic_bfd_copy_private_symbol_data,
+ _bfd_generic_bfd_copy_private_header_data,
+ _bfd_generic_bfd_set_private_flags,
+ _bfd_generic_bfd_print_private_bfd_data,
+
+ /* Core */
+ BFD_JUMP_TABLE_CORE (coff),
+
+ /* Archive */
+ xcoff64_slurp_armap,
+ _bfd_noarchive_slurp_extended_name_table,
+ _bfd_noarchive_construct_extended_name_table,
+ bfd_dont_truncate_arname,
+ _bfd_xcoff_write_armap,
+ _bfd_xcoff_read_ar_hdr,
+ _bfd_generic_write_ar_hdr,
+ xcoff64_openr_next_archived_file,
+ _bfd_generic_get_elt_at_index,
+ _bfd_xcoff_stat_arch_elt,
+ bfd_true,
+
+ /* Symbols */
+ coff_get_symtab_upper_bound,
+ coff_canonicalize_symtab,
+ coff_make_empty_symbol,
+ coff_print_symbol,
+ coff_get_symbol_info,
+ _bfd_xcoff_is_local_label_name,
+ coff_bfd_is_target_special_symbol,
+ coff_get_lineno,
+ coff_find_nearest_line,
+ coff_find_line,
+ coff_find_inliner_info,
+ coff_bfd_make_debug_symbol,
+ _bfd_generic_read_minisymbols,
+ _bfd_generic_minisymbol_to_symbol,
+
+ /* Reloc */
+ coff_get_reloc_upper_bound,
+ coff_canonicalize_reloc,
+ xcoff64_reloc_type_lookup,
+ xcoff64_reloc_name_lookup,
+
+ /* Write */
+ coff_set_arch_mach,
+ coff_set_section_contents,
+
+ /* Link */
+ xcoff64_sizeof_headers,
+ bfd_generic_get_relocated_section_contents,
+ bfd_generic_relax_section,
+ _bfd_xcoff_bfd_link_hash_table_create,
+ _bfd_xcoff_bfd_link_add_symbols,
+ _bfd_generic_link_just_syms,
+ _bfd_generic_copy_link_hash_symbol_type,
+ _bfd_xcoff_bfd_final_link,
+ _bfd_generic_link_split_section,
+ bfd_generic_gc_sections,
+ bfd_generic_lookup_section_flags,
+ bfd_generic_merge_sections,
+ bfd_generic_is_group_section,
+ bfd_generic_discard_group,
+ _bfd_generic_section_already_linked,
+ _bfd_xcoff_define_common_symbol,
+
+ /* Dynamic */
+ _bfd_xcoff_get_dynamic_symtab_upper_bound,
+ _bfd_xcoff_canonicalize_dynamic_symtab,
+ _bfd_nodynamic_get_synthetic_symtab,
+ _bfd_xcoff_get_dynamic_reloc_upper_bound,
+ _bfd_xcoff_canonicalize_dynamic_reloc,
+
+ /* Opposite endian version, none exists */
+ NULL,
+
+ &bfd_xcoff_backend_data,
+ };
+
+extern const bfd_target *xcoff64_core_p
+ (bfd *);
+extern bfd_boolean xcoff64_core_file_matches_executable_p
+ (bfd *, bfd *);
+extern char *xcoff64_core_file_failing_command
+ (bfd *);
+extern int xcoff64_core_file_failing_signal
+ (bfd *);
+#define xcoff64_core_file_pid _bfd_nocore_core_file_pid
+
+/* AIX 5 */
+static const struct xcoff_backend_data_rec bfd_xcoff_aix5_backend_data =
+ {
+ { /* COFF backend, defined in libcoff.h. */
+ _bfd_xcoff64_swap_aux_in,
+ _bfd_xcoff64_swap_sym_in,
+ _bfd_xcoff64_swap_lineno_in,
+ _bfd_xcoff64_swap_aux_out,
+ _bfd_xcoff64_swap_sym_out,
+ _bfd_xcoff64_swap_lineno_out,
+ xcoff64_swap_reloc_out,
+ coff_swap_filehdr_out,
+ coff_swap_aouthdr_out,
+ coff_swap_scnhdr_out,
+ FILHSZ,
+ AOUTSZ,
+ SCNHSZ,
+ SYMESZ,
+ AUXESZ,
+ RELSZ,
+ LINESZ,
+ FILNMLEN,
+ TRUE, /* _bfd_coff_long_filenames */
+ XCOFF_NO_LONG_SECTION_NAMES, /* _bfd_coff_long_section_names */
+ 3, /* _bfd_coff_default_section_alignment_power */
+ TRUE, /* _bfd_coff_force_symnames_in_strings */
+ 4, /* _bfd_coff_debug_string_prefix_length */
+ 32768, /* _bfd_coff_max_nscns */
+ coff_swap_filehdr_in,
+ coff_swap_aouthdr_in,
+ coff_swap_scnhdr_in,
+ xcoff64_swap_reloc_in,
+ xcoff64_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,
+ dummy_reloc16_extra_cases,
+ dummy_reloc16_estimate,
+ NULL, /* bfd_coff_sym_is_global */
+ coff_compute_section_file_positions,
+ NULL, /* _bfd_coff_start_final_link */
+ xcoff64_ppc_relocate_section,
+ coff_rtype_to_howto,
+ NULL, /* _bfd_coff_adjust_symndx */
+ _bfd_generic_link_add_one_symbol,
+ coff_link_output_has_begun,
+ coff_final_link_postscript,
+ NULL /* print_pdata. */
+ },
+
+ U64_TOCMAGIC, /* magic number */
+ bfd_arch_powerpc,
+ bfd_mach_ppc_620,
+
+ /* Function pointers to xcoff specific swap routines. */
+ xcoff64_swap_ldhdr_in,
+ xcoff64_swap_ldhdr_out,
+ xcoff64_swap_ldsym_in,
+ xcoff64_swap_ldsym_out,
+ xcoff64_swap_ldrel_in,
+ xcoff64_swap_ldrel_out,
+
+ /* Sizes. */
+ LDHDRSZ,
+ LDSYMSZ,
+ LDRELSZ,
+ 24, /* _xcoff_function_descriptor_size */
+ 0, /* _xcoff_small_aout_header_size */
+ /* Versions. */
+ 2, /* _xcoff_ldhdr_version */
+
+ _bfd_xcoff64_put_symbol_name,
+ _bfd_xcoff64_put_ldsymbol_name,
+ &xcoff64_dynamic_reloc,
+ xcoff64_create_csect_from_smclas,
+
+ /* Lineno and reloc count overflow. */
+ xcoff64_is_lineno_count_overflow,
+ xcoff64_is_reloc_count_overflow,
+
+ xcoff64_loader_symbol_offset,
+ xcoff64_loader_reloc_offset,
+
+ /* glink. */
+ &xcoff64_glink_code[0],
+ 40, /* _xcoff_glink_size */
+
+ /* rtinit. */
+ 88, /* _xcoff_rtinit_size */
+ xcoff64_generate_rtinit,
+ };
+
+/* The transfer vector that leads the outside world to all of the above. */
+const bfd_target rs6000_xcoff64_aix_vec =
+ {
+ "aix5coff64-rs6000",
+ bfd_target_xcoff_flavour,
+ BFD_ENDIAN_BIG, /* data byte order is big */
+ BFD_ENDIAN_BIG, /* header byte order is big */
+
+ (HAS_RELOC | EXEC_P | HAS_LINENO | HAS_DEBUG | DYNAMIC
+ | HAS_SYMS | HAS_LOCALS | WP_TEXT),
+
+ SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_DATA,
+ 0, /* leading char */
+ '/', /* ar_pad_char */
+ 15, /* ar_max_namelen */
+ 0, /* match priority. */
+
+ /* 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_check_format */
+ _bfd_dummy_target,
+ coff_object_p,
+ xcoff64_archive_p,
+ xcoff64_core_p
+ },
+
+ { /* bfd_set_format */
+ bfd_false,
+ coff_mkobject,
+ _bfd_generic_mkarchive,
+ bfd_false
+ },
+
+ {/* bfd_write_contents */
+ bfd_false,
+ xcoff64_write_object_contents,
+ _bfd_xcoff_write_archive_contents,
+ bfd_false
+ },
+
+ /* Generic */
+ _bfd_archive_close_and_cleanup,
+ bfd_true,
+ coff_new_section_hook,
+ _bfd_generic_get_section_contents,
+ _bfd_generic_get_section_contents_in_window,
+
+ /* Copy */
+ _bfd_xcoff_copy_private_bfd_data,
+ _bfd_generic_bfd_merge_private_bfd_data,
+ _bfd_generic_init_private_section_data,
+ _bfd_generic_bfd_copy_private_section_data,
+ _bfd_generic_bfd_copy_private_symbol_data,
+ _bfd_generic_bfd_copy_private_header_data,
+ _bfd_generic_bfd_set_private_flags,
+ _bfd_generic_bfd_print_private_bfd_data,
+
+ /* Core */
+ BFD_JUMP_TABLE_CORE (xcoff64),
+
+ /* Archive */
+ xcoff64_slurp_armap,
+ _bfd_noarchive_slurp_extended_name_table,
+ _bfd_noarchive_construct_extended_name_table,
+ bfd_dont_truncate_arname,
+ _bfd_xcoff_write_armap,
+ _bfd_xcoff_read_ar_hdr,
+ _bfd_generic_write_ar_hdr,
+ xcoff64_openr_next_archived_file,
+ _bfd_generic_get_elt_at_index,
+ _bfd_xcoff_stat_arch_elt,
+ bfd_true,
+
+ /* Symbols */
+ coff_get_symtab_upper_bound,
+ coff_canonicalize_symtab,
+ coff_make_empty_symbol,
+ coff_print_symbol,
+ coff_get_symbol_info,
+ _bfd_xcoff_is_local_label_name,
+ coff_bfd_is_target_special_symbol,
+ coff_get_lineno,
+ coff_find_nearest_line,
+ coff_find_line,
+ coff_find_inliner_info,
+ coff_bfd_make_debug_symbol,
+ _bfd_generic_read_minisymbols,
+ _bfd_generic_minisymbol_to_symbol,
+
+ /* Reloc */
+ coff_get_reloc_upper_bound,
+ coff_canonicalize_reloc,
+ xcoff64_reloc_type_lookup,
+ xcoff64_reloc_name_lookup,
+
+ /* Write */
+ coff_set_arch_mach,
+ coff_set_section_contents,
+
+ /* Link */
+ xcoff64_sizeof_headers,
+ bfd_generic_get_relocated_section_contents,
+ bfd_generic_relax_section,
+ _bfd_xcoff_bfd_link_hash_table_create,
+ _bfd_xcoff_bfd_link_add_symbols,
+ _bfd_generic_link_just_syms,
+ _bfd_generic_copy_link_hash_symbol_type,
+ _bfd_xcoff_bfd_final_link,
+ _bfd_generic_link_split_section,
+ bfd_generic_gc_sections,
+ bfd_generic_lookup_section_flags,
+ bfd_generic_merge_sections,
+ bfd_generic_is_group_section,
+ bfd_generic_discard_group,
+ _bfd_generic_section_already_linked,
+ _bfd_xcoff_define_common_symbol,
+
+ /* Dynamic */
+ _bfd_xcoff_get_dynamic_symtab_upper_bound,
+ _bfd_xcoff_canonicalize_dynamic_symtab,
+ _bfd_nodynamic_get_synthetic_symtab,
+ _bfd_xcoff_get_dynamic_reloc_upper_bound,
+ _bfd_xcoff_canonicalize_dynamic_reloc,
+
+ /* Opposite endian version, none exists. */
+ NULL,
+
+ & bfd_xcoff_aix5_backend_data,
+ };
diff --git a/bfd/coffcode.h b/bfd/coffcode.h
new file mode 100644
index 0000000..9990b16
--- /dev/null
+++ b/bfd/coffcode.h
@@ -0,0 +1,6134 @@
+/* Support for the generic parts of most COFF variants, for BFD.
+ Copyright (C) 1990-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, 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
+ Coff long section names
+
+ In the standard Coff object format, section names are limited to
+ the eight bytes available in the @code{s_name} field of the
+ @code{SCNHDR} section header structure. The format requires the
+ field to be NUL-padded, but not necessarily NUL-terminated, so
+ the longest section names permitted are a full eight characters.
+
+ The Microsoft PE variants of the Coff object file format add
+ an extension to support the use of long section names. This
+ extension is defined in section 4 of the Microsoft PE/COFF
+ specification (rev 8.1). If a section name is too long to fit
+ into the section header's @code{s_name} field, it is instead
+ placed into the string table, and the @code{s_name} field is
+ filled with a slash ("/") followed by the ASCII decimal
+ representation of the offset of the full name relative to the
+ string table base.
+
+ Note that this implies that the extension can only be used in object
+ files, as executables do not contain a string table. The standard
+ specifies that long section names from objects emitted into executable
+ images are to be truncated.
+
+ However, as a GNU extension, BFD can generate executable images
+ that contain a string table and long section names. This
+ would appear to be technically valid, as the standard only says
+ that Coff debugging information is deprecated, not forbidden,
+ and in practice it works, although some tools that parse PE files
+ expecting the MS standard format may become confused; @file{PEview} is
+ one known example.
+
+ The functionality is supported in BFD by code implemented under
+ the control of the macro @code{COFF_LONG_SECTION_NAMES}. If not
+ defined, the format does not support long section names in any way.
+ If defined, it is used to initialise a flag,
+ @code{_bfd_coff_long_section_names}, and a hook function pointer,
+ @code{_bfd_coff_set_long_section_names}, in the Coff backend data
+ structure. The flag controls the generation of long section names
+ in output BFDs at runtime; if it is false, as it will be by default
+ when generating an executable image, long section names are truncated;
+ if true, the long section names extension is employed. The hook
+ points to a function that allows the value of the flag to be altered
+ at runtime, on formats that support long section names at all; on
+ other formats it points to a stub that returns an error indication.
+
+ With input BFDs, the flag is set according to whether any long section
+ names are detected while reading the section headers. For a completely
+ new BFD, the flag is set to the default for the target format. This
+ information can be used by a client of the BFD library when deciding
+ what output format to generate, and means that a BFD that is opened
+ for read and subsequently converted to a writeable BFD and modified
+ in-place will retain whatever format it had on input.
+
+ If @code{COFF_LONG_SECTION_NAMES} is simply defined (blank), or is
+ defined to the value "1", then long section names are enabled by
+ default; if it is defined to the value zero, they are disabled by
+ default (but still accepted in input BFDs). The header @file{coffcode.h}
+ defines a macro, @code{COFF_DEFAULT_LONG_SECTION_NAMES}, which is
+ used in the backends to initialise the backend data structure fields
+ appropriately; see the comments for further detail.
+
+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_lineno_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 hierarchy 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;
+.
+. {* Selector for the union above. *}
+. bfd_boolean is_sym;
+.} 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 ? *}
+. bfd_boolean done_lineno;
+.} coff_symbol_type;
+
+*/
+
+#include "libiberty.h"
+
+#ifdef COFF_WITH_PE
+#include "peicode.h"
+#else
+#include "coffswap.h"
+#endif
+
+#define STRING_SIZE_SIZE 4
+
+#define DOT_DEBUG ".debug"
+#define DOT_ZDEBUG ".zdebug"
+#define GNU_LINKONCE_WI ".gnu.linkonce.wi."
+#define GNU_LINKONCE_WT ".gnu.linkonce.wt."
+#define DOT_RELOC ".reloc"
+
+#if defined (COFF_LONG_SECTION_NAMES)
+/* Needed to expand the inputs to BLANKOR1TOODD. */
+#define COFFLONGSECTIONCATHELPER(x,y) x ## y
+/* If the input macro Y is blank or '1', return an odd number; if it is
+ '0', return an even number. Result undefined in all other cases. */
+#define BLANKOR1TOODD(y) COFFLONGSECTIONCATHELPER(1,y)
+/* Defined to numerical 0 or 1 according to whether generation of long
+ section names is disabled or enabled by default. */
+#define COFF_ENABLE_LONG_SECTION_NAMES (BLANKOR1TOODD(COFF_LONG_SECTION_NAMES) & 1)
+/* Where long section names are supported, we allow them to be enabled
+ and disabled at runtime, so select an appropriate hook function for
+ _bfd_coff_set_long_section_names. */
+#define COFF_LONG_SECTION_NAMES_SETTER bfd_coff_set_long_section_names_allowed
+#else /* !defined (COFF_LONG_SECTION_NAMES) */
+/* If long section names are not supported, this stub disallows any
+ attempt to enable them at run-time. */
+#define COFF_LONG_SECTION_NAMES_SETTER bfd_coff_set_long_section_names_disallowed
+#endif /* defined (COFF_LONG_SECTION_NAMES) */
+
+/* Define a macro that can be used to initialise both the fields relating
+ to long section names in the backend data struct simultaneously. */
+#if COFF_ENABLE_LONG_SECTION_NAMES
+#define COFF_DEFAULT_LONG_SECTION_NAMES (TRUE), COFF_LONG_SECTION_NAMES_SETTER
+#else /* !COFF_ENABLE_LONG_SECTION_NAMES */
+#define COFF_DEFAULT_LONG_SECTION_NAMES (FALSE), COFF_LONG_SECTION_NAMES_SETTER
+#endif /* COFF_ENABLE_LONG_SECTION_NAMES */
+
+#if defined (COFF_LONG_SECTION_NAMES)
+static bfd_boolean bfd_coff_set_long_section_names_allowed
+ (bfd *, int);
+#else /* !defined (COFF_LONG_SECTION_NAMES) */
+static bfd_boolean bfd_coff_set_long_section_names_disallowed
+ (bfd *, int);
+#endif /* defined (COFF_LONG_SECTION_NAMES) */
+static long sec_to_styp_flags
+ (const char *, flagword);
+static bfd_boolean styp_to_sec_flags
+ (bfd *, void *, const char *, asection *, flagword *);
+static bfd_boolean coff_bad_format_hook
+ (bfd *, void *);
+static void coff_set_custom_section_alignment
+ (bfd *, asection *, const struct coff_section_alignment_entry *,
+ const unsigned int);
+static bfd_boolean coff_new_section_hook
+ (bfd *, asection *);
+static bfd_boolean coff_set_arch_mach_hook
+ (bfd *, void *);
+static bfd_boolean coff_write_relocs
+ (bfd *, int);
+static bfd_boolean coff_set_flags
+ (bfd *, unsigned int *, unsigned short *);
+static bfd_boolean coff_set_arch_mach
+ (bfd *, enum bfd_architecture, unsigned long) ATTRIBUTE_UNUSED;
+static bfd_boolean coff_compute_section_file_positions
+ (bfd *);
+static bfd_boolean coff_write_object_contents
+ (bfd *) ATTRIBUTE_UNUSED;
+static bfd_boolean coff_set_section_contents
+ (bfd *, asection *, const void *, file_ptr, bfd_size_type);
+static void * buy_and_read
+ (bfd *, file_ptr, bfd_size_type);
+static bfd_boolean coff_slurp_line_table
+ (bfd *, asection *);
+static bfd_boolean coff_slurp_symbol_table
+ (bfd *);
+static enum coff_symbol_classification coff_classify_symbol
+ (bfd *, struct internal_syment *);
+static bfd_boolean coff_slurp_reloc_table
+ (bfd *, asection *, asymbol **);
+static long coff_canonicalize_reloc
+ (bfd *, asection *, arelent **, asymbol **);
+#ifndef coff_mkobject_hook
+static void * coff_mkobject_hook
+ (bfd *, void *, void *);
+#endif
+#ifdef COFF_WITH_PE
+static flagword handle_COMDAT
+ (bfd *, flagword, void *, const char *, asection *);
+#endif
+#ifdef COFF_IMAGE_WITH_PE
+static bfd_boolean coff_read_word
+ (bfd *, unsigned int *);
+static unsigned int coff_compute_checksum
+ (bfd *);
+static bfd_boolean coff_apply_checksum
+ (bfd *);
+#endif
+#ifdef TICOFF
+static bfd_boolean ticoff0_bad_format_hook
+ (bfd *, void * );
+static bfd_boolean ticoff1_bad_format_hook
+ (bfd *, void * );
+#endif
+
+/* void warning(); */
+
+#if defined (COFF_LONG_SECTION_NAMES)
+static bfd_boolean
+bfd_coff_set_long_section_names_allowed (bfd *abfd, int enable)
+{
+ coff_backend_info (abfd)->_bfd_coff_long_section_names = enable;
+ return TRUE;
+}
+#else /* !defined (COFF_LONG_SECTION_NAMES) */
+static bfd_boolean
+bfd_coff_set_long_section_names_disallowed (bfd *abfd, int enable)
+{
+ (void) abfd;
+ (void) enable;
+ return FALSE;
+}
+#endif /* defined (COFF_LONG_SECTION_NAMES) */
+
+/* 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 probably mirror the changes in styp_to_sec_flags(). */
+
+#ifndef COFF_WITH_PE
+
+/* Macros for setting debugging flags. */
+
+#ifdef STYP_DEBUG
+#define STYP_XCOFF_DEBUG STYP_DEBUG
+#else
+#define STYP_XCOFF_DEBUG STYP_INFO
+#endif
+
+#ifdef COFF_ALIGN_IN_S_FLAGS
+#define STYP_DEBUG_INFO STYP_DSECT
+#else
+#define STYP_DEBUG_INFO STYP_INFO
+#endif
+
+static long
+sec_to_styp_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 (CONST_STRNEQ (sec_name, DOT_DEBUG)
+ || CONST_STRNEQ (sec_name, DOT_ZDEBUG))
+ {
+ /* Handle the XCOFF debug section and DWARF2 debug sections. */
+ if (!sec_name[6])
+ styp_flags = STYP_XCOFF_DEBUG;
+ else
+ styp_flags = STYP_DEBUG_INFO;
+ }
+ else if (CONST_STRNEQ (sec_name, ".stab"))
+ {
+ styp_flags = STYP_DEBUG_INFO;
+ }
+#ifdef COFF_LONG_SECTION_NAMES
+ else if (CONST_STRNEQ (sec_name, GNU_LINKONCE_WI)
+ || CONST_STRNEQ (sec_name, GNU_LINKONCE_WT))
+ {
+ styp_flags = STYP_DEBUG_INFO;
+ }
+#endif
+#ifdef RS6000COFF_C
+ else if (!strcmp (sec_name, _PAD))
+ {
+ styp_flags = STYP_PAD;
+ }
+ else if (!strcmp (sec_name, _LOADER))
+ {
+ styp_flags = STYP_LOADER;
+ }
+ else if (!strcmp (sec_name, _EXCEPT))
+ {
+ styp_flags = STYP_EXCEPT;
+ }
+ else if (!strcmp (sec_name, _TYPCHK))
+ {
+ styp_flags = STYP_TYPCHK;
+ }
+ else if (sec_flags & SEC_DEBUGGING)
+ {
+ int i;
+
+ for (i = 0; i < XCOFF_DWSECT_NBR_NAMES; i++)
+ if (!strcmp (sec_name, xcoff_dwsect_names[i].name))
+ {
+ styp_flags = STYP_DWARF | xcoff_dwsect_names[i].flag;
+ break;
+ }
+ }
+#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_CLINK
+ if (sec_flags & SEC_TIC54X_CLINK)
+ styp_flags |= STYP_CLINK;
+#endif
+
+#ifdef STYP_BLOCK
+ if (sec_flags & SEC_TIC54X_BLOCK)
+ styp_flags |= STYP_BLOCK;
+#endif
+
+#ifdef STYP_NOLOAD
+ if ((sec_flags & (SEC_NEVER_LOAD | SEC_COFF_SHARED_LIBRARY)) != 0)
+ styp_flags |= STYP_NOLOAD;
+#endif
+
+ return styp_flags;
+}
+
+#else /* COFF_WITH_PE */
+
+/* The PE version; see above for the general comments. The non-PE
+ case seems to be more guessing, and breaks PE format; specifically,
+ .rdata is readonly, but it sure ain't text. Really, all this
+ should be set up properly in gas (or whatever assembler is in use),
+ and honor whatever objcopy/strip, etc. sent us as input. */
+
+static long
+sec_to_styp_flags (const char *sec_name, flagword sec_flags)
+{
+ long styp_flags = 0;
+ bfd_boolean is_dbg = FALSE;
+
+ if (CONST_STRNEQ (sec_name, DOT_DEBUG)
+ || CONST_STRNEQ (sec_name, DOT_ZDEBUG)
+#ifdef COFF_LONG_SECTION_NAMES
+ || CONST_STRNEQ (sec_name, GNU_LINKONCE_WI)
+ || CONST_STRNEQ (sec_name, GNU_LINKONCE_WT)
+#endif
+ || CONST_STRNEQ (sec_name, ".stab"))
+ is_dbg = TRUE;
+
+ /* caution: there are at least three groups of symbols that have
+ very similar bits and meanings: IMAGE_SCN*, SEC_*, and STYP_*.
+ SEC_* are the BFD internal flags, used for generic BFD
+ information. STYP_* are the COFF section flags which appear in
+ COFF files. IMAGE_SCN_* are the PE section flags which appear in
+ PE files. The STYP_* flags and the IMAGE_SCN_* flags overlap,
+ but there are more IMAGE_SCN_* flags. */
+
+ /* FIXME: There is no gas syntax to specify the debug section flag. */
+ if (is_dbg)
+ {
+ sec_flags &= (SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD
+ | SEC_LINK_DUPLICATES_SAME_CONTENTS
+ | SEC_LINK_DUPLICATES_SAME_SIZE);
+ sec_flags |= SEC_DEBUGGING | SEC_READONLY;
+ }
+
+ /* skip LOAD */
+ /* READONLY later */
+ /* skip RELOC */
+ if ((sec_flags & SEC_CODE) != 0)
+ styp_flags |= IMAGE_SCN_CNT_CODE;
+ if ((sec_flags & (SEC_DATA | SEC_DEBUGGING)) != 0)
+ styp_flags |= IMAGE_SCN_CNT_INITIALIZED_DATA;
+ if ((sec_flags & SEC_ALLOC) != 0 && (sec_flags & SEC_LOAD) == 0)
+ styp_flags |= IMAGE_SCN_CNT_UNINITIALIZED_DATA; /* ==STYP_BSS */
+ /* skip ROM */
+ /* skip constRUCTOR */
+ /* skip CONTENTS */
+ if ((sec_flags & SEC_IS_COMMON) != 0)
+ styp_flags |= IMAGE_SCN_LNK_COMDAT;
+ if ((sec_flags & SEC_DEBUGGING) != 0)
+ styp_flags |= IMAGE_SCN_MEM_DISCARDABLE;
+ if ((sec_flags & SEC_EXCLUDE) != 0 && !is_dbg)
+ styp_flags |= IMAGE_SCN_LNK_REMOVE;
+ if ((sec_flags & SEC_NEVER_LOAD) != 0 && !is_dbg)
+ styp_flags |= IMAGE_SCN_LNK_REMOVE;
+ /* skip IN_MEMORY */
+ /* skip SORT */
+ if (sec_flags & SEC_LINK_ONCE)
+ styp_flags |= IMAGE_SCN_LNK_COMDAT;
+ if ((sec_flags
+ & (SEC_LINK_DUPLICATES_DISCARD | SEC_LINK_DUPLICATES_SAME_CONTENTS
+ | SEC_LINK_DUPLICATES_SAME_SIZE)) != 0)
+ styp_flags |= IMAGE_SCN_LNK_COMDAT;
+
+ /* skip LINKER_CREATED */
+
+ if ((sec_flags & SEC_COFF_NOREAD) == 0)
+ styp_flags |= IMAGE_SCN_MEM_READ; /* Invert NOREAD for read. */
+ if ((sec_flags & SEC_READONLY) == 0)
+ styp_flags |= IMAGE_SCN_MEM_WRITE; /* Invert READONLY for write. */
+ if (sec_flags & SEC_CODE)
+ styp_flags |= IMAGE_SCN_MEM_EXECUTE; /* CODE->EXECUTE. */
+ if (sec_flags & SEC_COFF_SHARED)
+ styp_flags |= IMAGE_SCN_MEM_SHARED; /* Shared remains meaningful. */
+
+ return styp_flags;
+}
+
+#endif /* COFF_WITH_PE */
+
+/* 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 probably mirror the changes in sec_to_styp_flags(). */
+
+#ifndef COFF_WITH_PE
+
+static bfd_boolean
+styp_to_sec_flags (bfd *abfd ATTRIBUTE_UNUSED,
+ void * hdr,
+ const char *name,
+ asection *section ATTRIBUTE_UNUSED,
+ flagword *flags_ptr)
+{
+ struct internal_scnhdr *internal_s = (struct internal_scnhdr *) hdr;
+ long styp_flags = internal_s->s_flags;
+ flagword sec_flags = 0;
+
+#ifdef STYP_BLOCK
+ if (styp_flags & STYP_BLOCK)
+ sec_flags |= SEC_TIC54X_BLOCK;
+#endif
+
+#ifdef STYP_CLINK
+ if (styp_flags & STYP_CLINK)
+ sec_flags |= SEC_TIC54X_CLINK;
+#endif
+
+#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;
+#ifdef RS6000COFF_C
+ else if (styp_flags & STYP_EXCEPT)
+ sec_flags |= SEC_LOAD;
+ else if (styp_flags & STYP_LOADER)
+ sec_flags |= SEC_LOAD;
+ else if (styp_flags & STYP_TYPCHK)
+ sec_flags |= SEC_LOAD;
+ else if (styp_flags & STYP_DWARF)
+ sec_flags |= SEC_DEBUGGING;
+#endif
+ 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 (CONST_STRNEQ (name, DOT_DEBUG)
+ || CONST_STRNEQ (name, DOT_ZDEBUG)
+#ifdef _COMMENT
+ || strcmp (name, _COMMENT) == 0
+#endif
+#ifdef COFF_LONG_SECTION_NAMES
+ || CONST_STRNEQ (name, GNU_LINKONCE_WI)
+ || CONST_STRNEQ (name, GNU_LINKONCE_WT)
+#endif
+ || CONST_STRNEQ (name, ".stab"))
+ {
+#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 */
+
+#if defined (COFF_LONG_SECTION_NAMES) && defined (COFF_SUPPORT_GNU_LINKONCE)
+ /* 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 (CONST_STRNEQ (name, ".gnu.linkonce"))
+ sec_flags |= SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD;
+#endif
+
+ if (flags_ptr == NULL)
+ return FALSE;
+
+ * flags_ptr = sec_flags;
+ return TRUE;
+}
+
+#else /* COFF_WITH_PE */
+
+static flagword
+handle_COMDAT (bfd * abfd,
+ flagword sec_flags,
+ void * hdr,
+ const char *name,
+ asection *section)
+{
+ struct internal_scnhdr *internal_s = (struct internal_scnhdr *) hdr;
+ bfd_byte *esymstart, *esym, *esymend;
+ int seen_state = 0;
+ char *target_name = NULL;
+
+ 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. */
+
+ /* COMDAT sections are special. The first symbol is the section
+ symbol, which tells what kind of COMDAT section it is. The
+ second symbol is the "comdat symbol" - the one with the
+ unique name. GNU uses the section symbol for the unique
+ name; MS uses ".text" for every comdat section. Sigh. - DJ */
+
+ /* This is not mirrored in sec_to_styp_flags(), but there
+ doesn't seem to be a need to, either, and it would at best be
+ rather messy. */
+
+ if (! _bfd_coff_get_external_symbols (abfd))
+ return sec_flags;
+
+ esymstart = esym = (bfd_byte *) obj_coff_external_syms (abfd);
+ esymend = esym + obj_raw_syment_count (abfd) * bfd_coff_symesz (abfd);
+
+ while (esym < esymend)
+ {
+ struct internal_syment isym;
+ char buf[SYMNMLEN + 1];
+ const char *symname;
+
+ bfd_coff_swap_sym_in (abfd, esym, & isym);
+
+ BFD_ASSERT (sizeof (internal_s->s_name) <= SYMNMLEN);
+
+ if (isym.n_scnum == section->target_index)
+ {
+ /* According to the MSVC documentation, the first
+ TWO entries with the section # are both of
+ interest to us. The first one is the "section
+ symbol" (section name). The second is the comdat
+ symbol name. Here, we've found the first
+ qualifying entry; we distinguish it from the
+ second with a state flag.
+
+ In the case of gas-generated (at least until that
+ is fixed) .o files, it isn't necessarily the
+ second one. It may be some other later symbol.
+
+ Since gas also doesn't follow MS conventions and
+ emits the section similar to .text$<name>, where
+ <something> is the name we're looking for, we
+ distinguish the two as follows:
+
+ If the section name is simply a section name (no
+ $) we presume it's MS-generated, and look at
+ precisely the second symbol for the comdat name.
+ If the section name has a $, we assume it's
+ gas-generated, and look for <something> (whatever
+ follows the $) as the comdat symbol. */
+
+ /* All 3 branches use this. */
+ symname = _bfd_coff_internal_syment_name (abfd, &isym, buf);
+
+ /* PR 17512 file: 078-11867-0.004 */
+ if (symname == NULL)
+ {
+ _bfd_error_handler (_("%B: unable to load COMDAT section name"), abfd);
+ break;
+ }
+
+ switch (seen_state)
+ {
+ case 0:
+ {
+ /* The first time we've seen the symbol. */
+ union internal_auxent aux;
+
+ /* If it isn't the stuff we're expecting, die;
+ The MS documentation is vague, but it
+ appears that the second entry serves BOTH
+ as the comdat symbol and the defining
+ symbol record (either C_STAT or C_EXT,
+ possibly with an aux entry with debug
+ information if it's a function.) It
+ appears the only way to find the second one
+ is to count. (On Intel, they appear to be
+ adjacent, but on Alpha, they have been
+ found separated.)
+
+ Here, we think we've found the first one,
+ but there's some checking we can do to be
+ sure. */
+
+ if (! ((isym.n_sclass == C_STAT
+ || isym.n_sclass == C_EXT)
+ && BTYPE (isym.n_type) == T_NULL
+ && isym.n_value == 0))
+ abort ();
+
+ /* FIXME LATER: MSVC generates section names
+ like .text for comdats. Gas generates
+ names like .text$foo__Fv (in the case of a
+ function). See comment above for more. */
+
+ if (isym.n_sclass == C_STAT && strcmp (name, symname) != 0)
+ _bfd_error_handler (_("%B: warning: COMDAT symbol '%s' does not match section name '%s'"),
+ abfd, symname, name);
+
+ seen_state = 1;
+
+ /* This is the section symbol. */
+ bfd_coff_swap_aux_in (abfd, (esym + bfd_coff_symesz (abfd)),
+ isym.n_type, isym.n_sclass,
+ 0, isym.n_numaux, & aux);
+
+ target_name = strchr (name, '$');
+ if (target_name != NULL)
+ {
+ /* Gas mode. */
+ seen_state = 2;
+ /* Skip the `$'. */
+ target_name += 1;
+ }
+
+ /* FIXME: Microsoft uses NODUPLICATES and
+ ASSOCIATIVE, but gnu uses ANY and
+ SAME_SIZE. Unfortunately, gnu doesn't do
+ the comdat symbols right. So, until we can
+ fix it to do the right thing, we are
+ temporarily disabling comdats for the MS
+ types (they're used in DLLs and C++, but we
+ don't support *their* C++ libraries anyway
+ - DJ. */
+
+ /* Cygwin does not follow the MS style, and
+ uses ANY and SAME_SIZE where NODUPLICATES
+ and ASSOCIATIVE should be used. For
+ Interix, we just do the right thing up
+ front. */
+
+ switch (aux.x_scn.x_comdat)
+ {
+ case IMAGE_COMDAT_SELECT_NODUPLICATES:
+#ifdef STRICT_PE_FORMAT
+ sec_flags |= SEC_LINK_DUPLICATES_ONE_ONLY;
+#else
+ sec_flags &= ~SEC_LINK_ONCE;
+#endif
+ break;
+
+ 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:
+ /* Not yet fully implemented ??? */
+ sec_flags |= SEC_LINK_DUPLICATES_SAME_CONTENTS;
+ break;
+
+ /* debug$S gets this case; other
+ implications ??? */
+
+ /* There may be no symbol... we'll search
+ the whole table... Is this the right
+ place to play this game? Or should we do
+ it when reading it in. */
+ case IMAGE_COMDAT_SELECT_ASSOCIATIVE:
+#ifdef STRICT_PE_FORMAT
+ /* FIXME: This is not currently implemented. */
+ sec_flags |= SEC_LINK_DUPLICATES_DISCARD;
+#else
+ sec_flags &= ~SEC_LINK_ONCE;
+#endif
+ break;
+
+ default: /* 0 means "no symbol" */
+ /* debug$F gets this case; other
+ implications ??? */
+ sec_flags |= SEC_LINK_DUPLICATES_DISCARD;
+ break;
+ }
+ }
+ break;
+
+ case 2:
+ /* Gas mode: the first matching on partial name. */
+
+#ifndef TARGET_UNDERSCORE
+#define TARGET_UNDERSCORE 0
+#endif
+ /* Is this the name we're looking for ? */
+ if (strcmp (target_name,
+ symname + (TARGET_UNDERSCORE ? 1 : 0)) != 0)
+ {
+ /* Not the name we're looking for */
+ esym += (isym.n_numaux + 1) * bfd_coff_symesz (abfd);
+ continue;
+ }
+ /* Fall through. */
+ case 1:
+ /* MSVC mode: the lexically second symbol (or
+ drop through from the above). */
+ {
+ char *newname;
+ bfd_size_type amt;
+
+ /* This must the second symbol with the
+ section #. It is the actual symbol name.
+ Intel puts the two adjacent, but Alpha (at
+ least) spreads them out. */
+
+ amt = sizeof (struct coff_comdat_info);
+ coff_section_data (abfd, section)->comdat
+ = (struct coff_comdat_info *) bfd_alloc (abfd, amt);
+ if (coff_section_data (abfd, section)->comdat == NULL)
+ abort ();
+
+ coff_section_data (abfd, section)->comdat->symbol =
+ (esym - esymstart) / bfd_coff_symesz (abfd);
+
+ amt = strlen (symname) + 1;
+ newname = (char *) bfd_alloc (abfd, amt);
+ if (newname == NULL)
+ abort ();
+
+ strcpy (newname, symname);
+ coff_section_data (abfd, section)->comdat->name
+ = newname;
+ }
+
+ goto breakloop;
+ }
+ }
+
+ esym += (isym.n_numaux + 1) * bfd_coff_symesz (abfd);
+ }
+
+ breakloop:
+ return sec_flags;
+}
+
+
+/* The PE version; see above for the general comments.
+
+ Since to set the SEC_LINK_ONCE and associated flags, we have to
+ look at the symbol table anyway, we return the symbol table index
+ of the symbol being used as the COMDAT symbol. This is admittedly
+ ugly, but there's really nowhere else that we have access to the
+ required information. FIXME: Is the COMDAT symbol index used for
+ any purpose other than objdump? */
+
+static bfd_boolean
+styp_to_sec_flags (bfd *abfd,
+ void * hdr,
+ const char *name,
+ asection *section,
+ flagword *flags_ptr)
+{
+ struct internal_scnhdr *internal_s = (struct internal_scnhdr *) hdr;
+ long styp_flags = internal_s->s_flags;
+ flagword sec_flags;
+ bfd_boolean result = TRUE;
+ bfd_boolean is_dbg = FALSE;
+
+ if (CONST_STRNEQ (name, DOT_DEBUG)
+ || CONST_STRNEQ (name, DOT_ZDEBUG)
+#ifdef COFF_LONG_SECTION_NAMES
+ || CONST_STRNEQ (name, GNU_LINKONCE_WI)
+ || CONST_STRNEQ (name, GNU_LINKONCE_WT)
+#endif
+ || CONST_STRNEQ (name, ".stab"))
+ is_dbg = TRUE;
+ /* Assume read only unless IMAGE_SCN_MEM_WRITE is specified. */
+ sec_flags = SEC_READONLY;
+
+ /* If section disallows read, then set the NOREAD flag. */
+ if ((styp_flags & IMAGE_SCN_MEM_READ) == 0)
+ sec_flags |= SEC_COFF_NOREAD;
+
+ /* Process each flag bit in styp_flags in turn. */
+ while (styp_flags)
+ {
+ long flag = styp_flags & - styp_flags;
+ char * unhandled = NULL;
+
+ styp_flags &= ~ flag;
+
+ /* We infer from the distinct read/write/execute bits the settings
+ of some of the bfd flags; the actual values, should we need them,
+ are also in pei_section_data (abfd, section)->pe_flags. */
+
+ switch (flag)
+ {
+ case STYP_DSECT:
+ unhandled = "STYP_DSECT";
+ break;
+ case STYP_GROUP:
+ unhandled = "STYP_GROUP";
+ break;
+ case STYP_COPY:
+ unhandled = "STYP_COPY";
+ break;
+ case STYP_OVER:
+ unhandled = "STYP_OVER";
+ break;
+#ifdef SEC_NEVER_LOAD
+ case STYP_NOLOAD:
+ sec_flags |= SEC_NEVER_LOAD;
+ break;
+#endif
+ case IMAGE_SCN_MEM_READ:
+ sec_flags &= ~SEC_COFF_NOREAD;
+ break;
+ case IMAGE_SCN_TYPE_NO_PAD:
+ /* Skip. */
+ break;
+ case IMAGE_SCN_LNK_OTHER:
+ unhandled = "IMAGE_SCN_LNK_OTHER";
+ break;
+ case IMAGE_SCN_MEM_NOT_CACHED:
+ unhandled = "IMAGE_SCN_MEM_NOT_CACHED";
+ break;
+ case IMAGE_SCN_MEM_NOT_PAGED:
+ /* Generate a warning message rather using the 'unhandled'
+ variable as this will allow some .sys files generate by
+ other toolchains to be processed. See bugzilla issue 196. */
+ _bfd_error_handler (_("%B: Warning: Ignoring section flag IMAGE_SCN_MEM_NOT_PAGED in section %s"),
+ abfd, name);
+ break;
+ case IMAGE_SCN_MEM_EXECUTE:
+ sec_flags |= SEC_CODE;
+ break;
+ case IMAGE_SCN_MEM_WRITE:
+ sec_flags &= ~ SEC_READONLY;
+ break;
+ case IMAGE_SCN_MEM_DISCARDABLE:
+ /* The MS PE spec says that debug sections are DISCARDABLE,
+ but the presence of a DISCARDABLE flag does not necessarily
+ mean that a given section contains debug information. Thus
+ we only set the SEC_DEBUGGING flag on sections that we
+ recognise as containing debug information. */
+ if (is_dbg
+#ifdef _COMMENT
+ || strcmp (name, _COMMENT) == 0
+#endif
+ )
+ {
+ sec_flags |= SEC_DEBUGGING | SEC_READONLY;
+ }
+ break;
+ case IMAGE_SCN_MEM_SHARED:
+ sec_flags |= SEC_COFF_SHARED;
+ break;
+ case IMAGE_SCN_LNK_REMOVE:
+ if (!is_dbg)
+ sec_flags |= SEC_EXCLUDE;
+ break;
+ case IMAGE_SCN_CNT_CODE:
+ sec_flags |= SEC_CODE | SEC_ALLOC | SEC_LOAD;
+ break;
+ case IMAGE_SCN_CNT_INITIALIZED_DATA:
+ if (is_dbg)
+ sec_flags |= SEC_DEBUGGING;
+ else
+ sec_flags |= SEC_DATA | SEC_ALLOC | SEC_LOAD;
+ break;
+ case IMAGE_SCN_CNT_UNINITIALIZED_DATA:
+ sec_flags |= SEC_ALLOC;
+ break;
+ case IMAGE_SCN_LNK_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. */
+#ifdef COFF_PAGE_SIZE
+ sec_flags |= SEC_DEBUGGING;
+#endif
+ break;
+ case IMAGE_SCN_LNK_COMDAT:
+ /* COMDAT gets very special treatment. */
+ sec_flags = handle_COMDAT (abfd, sec_flags, hdr, name, section);
+ break;
+ default:
+ /* Silently ignore for now. */
+ break;
+ }
+
+ /* If the section flag was not handled, report it here. */
+ if (unhandled != NULL)
+ {
+ (*_bfd_error_handler)
+ (_("%B (%s): Section flag %s (0x%x) ignored"),
+ abfd, name, unhandled, flag);
+ result = FALSE;
+ }
+ }
+
+#if defined (COFF_LONG_SECTION_NAMES) && defined (COFF_SUPPORT_GNU_LINKONCE)
+ /* 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 (CONST_STRNEQ (name, ".gnu.linkonce"))
+ sec_flags |= SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD;
+#endif
+
+ if (flags_ptr)
+ * flags_ptr = sec_flags;
+
+ return result;
+}
+
+#endif /* COFF_WITH_PE */
+
+#define get_index(symbol) ((symbol)->udata.i)
+
+/*
+INTERNAL_DEFINITION
+ bfd_coff_backend_data
+
+CODE_FRAGMENT
+
+.{* COFF symbol classifications. *}
+.
+.enum coff_symbol_classification
+.{
+. {* Global symbol. *}
+. COFF_SYMBOL_GLOBAL,
+. {* Common symbol. *}
+. COFF_SYMBOL_COMMON,
+. {* Undefined symbol. *}
+. COFF_SYMBOL_UNDEFINED,
+. {* Local symbol. *}
+. COFF_SYMBOL_LOCAL,
+. {* PE section symbol. *}
+. COFF_SYMBOL_PE_SECTION
+.};
+.
+Special entry points for gdb to swap in coff symbol table parts:
+.typedef struct
+.{
+. void (*_bfd_coff_swap_aux_in)
+. (bfd *, void *, int, int, int, int, void *);
+.
+. void (*_bfd_coff_swap_sym_in)
+. (bfd *, void *, void *);
+.
+. void (*_bfd_coff_swap_lineno_in)
+. (bfd *, void *, void *);
+.
+. unsigned int (*_bfd_coff_swap_aux_out)
+. (bfd *, void *, int, int, int, int, void *);
+.
+. unsigned int (*_bfd_coff_swap_sym_out)
+. (bfd *, void *, void *);
+.
+. unsigned int (*_bfd_coff_swap_lineno_out)
+. (bfd *, void *, void *);
+.
+. unsigned int (*_bfd_coff_swap_reloc_out)
+. (bfd *, void *, void *);
+.
+. unsigned int (*_bfd_coff_swap_filehdr_out)
+. (bfd *, void *, void *);
+.
+. unsigned int (*_bfd_coff_swap_aouthdr_out)
+. (bfd *, void *, void *);
+.
+. unsigned int (*_bfd_coff_swap_scnhdr_out)
+. (bfd *, void *, void *);
+.
+. 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;
+. unsigned int _bfd_filnmlen;
+. bfd_boolean _bfd_coff_long_filenames;
+.
+. bfd_boolean _bfd_coff_long_section_names;
+. bfd_boolean (*_bfd_coff_set_long_section_names)
+. (bfd *, int);
+.
+. unsigned int _bfd_coff_default_section_alignment_power;
+. bfd_boolean _bfd_coff_force_symnames_in_strings;
+. unsigned int _bfd_coff_debug_string_prefix_length;
+. unsigned int _bfd_coff_max_nscns;
+.
+. void (*_bfd_coff_swap_filehdr_in)
+. (bfd *, void *, void *);
+.
+. void (*_bfd_coff_swap_aouthdr_in)
+. (bfd *, void *, void *);
+.
+. void (*_bfd_coff_swap_scnhdr_in)
+. (bfd *, void *, void *);
+.
+. void (*_bfd_coff_swap_reloc_in)
+. (bfd *abfd, void *, void *);
+.
+. bfd_boolean (*_bfd_coff_bad_format_hook)
+. (bfd *, void *);
+.
+. bfd_boolean (*_bfd_coff_set_arch_mach_hook)
+. (bfd *, void *);
+.
+. void * (*_bfd_coff_mkobject_hook)
+. (bfd *, void *, void *);
+.
+. bfd_boolean (*_bfd_styp_to_sec_flags_hook)
+. (bfd *, void *, const char *, asection *, flagword *);
+.
+. void (*_bfd_set_alignment_hook)
+. (bfd *, asection *, void *);
+.
+. bfd_boolean (*_bfd_coff_slurp_symbol_table)
+. (bfd *);
+.
+. bfd_boolean (*_bfd_coff_symname_in_debug)
+. (bfd *, struct internal_syment *);
+.
+. bfd_boolean (*_bfd_coff_pointerize_aux_hook)
+. (bfd *, combined_entry_type *, combined_entry_type *,
+. unsigned int, combined_entry_type *);
+.
+. bfd_boolean (*_bfd_coff_print_aux)
+. (bfd *, FILE *, combined_entry_type *, combined_entry_type *,
+. combined_entry_type *, unsigned int);
+.
+. void (*_bfd_coff_reloc16_extra_cases)
+. (bfd *, struct bfd_link_info *, struct bfd_link_order *, arelent *,
+. bfd_byte *, unsigned int *, unsigned int *);
+.
+. int (*_bfd_coff_reloc16_estimate)
+. (bfd *, asection *, arelent *, unsigned int,
+. struct bfd_link_info *);
+.
+. enum coff_symbol_classification (*_bfd_coff_classify_symbol)
+. (bfd *, struct internal_syment *);
+.
+. bfd_boolean (*_bfd_coff_compute_section_file_positions)
+. (bfd *);
+.
+. bfd_boolean (*_bfd_coff_start_final_link)
+. (bfd *, struct bfd_link_info *);
+.
+. bfd_boolean (*_bfd_coff_relocate_section)
+. (bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
+. struct internal_reloc *, struct internal_syment *, asection **);
+.
+. reloc_howto_type *(*_bfd_coff_rtype_to_howto)
+. (bfd *, asection *, struct internal_reloc *,
+. struct coff_link_hash_entry *, struct internal_syment *,
+. bfd_vma *);
+.
+. bfd_boolean (*_bfd_coff_adjust_symndx)
+. (bfd *, struct bfd_link_info *, bfd *, asection *,
+. struct internal_reloc *, bfd_boolean *);
+.
+. bfd_boolean (*_bfd_coff_link_add_one_symbol)
+. (struct bfd_link_info *, bfd *, const char *, flagword,
+. asection *, bfd_vma, const char *, bfd_boolean, bfd_boolean,
+. struct bfd_link_hash_entry **);
+.
+. bfd_boolean (*_bfd_coff_link_output_has_begun)
+. (bfd *, struct coff_final_link_info *);
+.
+. bfd_boolean (*_bfd_coff_final_link_postscript)
+. (bfd *, struct coff_final_link_info *);
+.
+. bfd_boolean (*_bfd_coff_print_pdata)
+. (bfd *, void *);
+.
+.} 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_filnmlen(abfd) (coff_backend_info (abfd)->_bfd_filnmlen)
+.#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_set_long_section_names(abfd, enable) \
+. ((coff_backend_info (abfd)->_bfd_coff_set_long_section_names) (abfd, enable))
+.#define bfd_coff_default_section_alignment_power(abfd) \
+. (coff_backend_info (abfd)->_bfd_coff_default_section_alignment_power)
+.#define bfd_coff_max_nscns(abfd) \
+. (coff_backend_info (abfd)->_bfd_coff_max_nscns)
+.
+.#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, section, flags_ptr)\
+. ((coff_backend_info (abfd)->_bfd_styp_to_sec_flags_hook)\
+. (abfd, scnhdr, name, section, flags_ptr))
+.
+.#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_force_symnames_in_strings(abfd)\
+. (coff_backend_info (abfd)->_bfd_coff_force_symnames_in_strings)
+.
+.#define bfd_coff_debug_string_prefix_length(abfd)\
+. (coff_backend_info (abfd)->_bfd_coff_debug_string_prefix_length)
+.
+.#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_classify_symbol(abfd, sym)\
+. ((coff_backend_info (abfd)->_bfd_coff_classify_symbol)\
+. (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))
+.
+.#define bfd_coff_have_print_pdata(a) \
+. (coff_backend_info (a)->_bfd_coff_print_pdata)
+.#define bfd_coff_print_pdata(a,p) \
+. ((coff_backend_info (a)->_bfd_coff_print_pdata) (a, p))
+.
+.{* Macro: Returns true if the bfd is a PE executable as opposed to a
+. PE object file. *}
+.#define bfd_pei_p(abfd) \
+. (CONST_STRNEQ ((abfd)->xvec->name, "pei-"))
+*/
+
+/* See whether the magic number matches. */
+
+static bfd_boolean
+coff_bad_format_hook (bfd * abfd ATTRIBUTE_UNUSED, void * 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 && bfd_coff_aoutsz (abfd) != internal_f->f_opthdr)
+ return FALSE;
+#endif
+
+ return TRUE;
+}
+
+#ifdef TICOFF
+static bfd_boolean
+ticoff0_bad_format_hook (bfd *abfd ATTRIBUTE_UNUSED, void * filehdr)
+{
+ struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr;
+
+ if (COFF0_BADMAG (*internal_f))
+ return FALSE;
+
+ return TRUE;
+}
+#endif
+
+#ifdef TICOFF
+static bfd_boolean
+ticoff1_bad_format_hook (bfd *abfd ATTRIBUTE_UNUSED, void * filehdr)
+{
+ struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr;
+
+ if (COFF1_BADMAG (*internal_f))
+ return FALSE;
+
+ return TRUE;
+}
+#endif
+
+/* Check whether this section uses an alignment other than the
+ default. */
+
+static void
+coff_set_custom_section_alignment (bfd *abfd ATTRIBUTE_UNUSED,
+ asection *section,
+ const struct coff_section_alignment_entry *alignment_table,
+ const unsigned int table_size)
+{
+ const unsigned int default_alignment = COFF_DEFAULT_SECTION_ALIGNMENT_POWER;
+ unsigned int i;
+
+ for (i = 0; i < table_size; ++i)
+ {
+ const char *secname = bfd_get_section_name (abfd, section);
+
+ if (alignment_table[i].comparison_length == (unsigned int) -1
+ ? strcmp (alignment_table[i].name, secname) == 0
+ : strncmp (alignment_table[i].name, secname,
+ alignment_table[i].comparison_length) == 0)
+ break;
+ }
+ if (i >= table_size)
+ return;
+
+ if (alignment_table[i].default_alignment_min != COFF_ALIGNMENT_FIELD_EMPTY
+ && default_alignment < alignment_table[i].default_alignment_min)
+ return;
+
+ if (alignment_table[i].default_alignment_max != COFF_ALIGNMENT_FIELD_EMPTY
+#if COFF_DEFAULT_SECTION_ALIGNMENT_POWER != 0
+ && default_alignment > alignment_table[i].default_alignment_max
+#endif
+ )
+ return;
+
+ section->alignment_power = alignment_table[i].alignment_power;
+}
+
+/* Custom section alignment records. */
+
+static const struct coff_section_alignment_entry
+coff_section_alignment_table[] =
+{
+#ifdef COFF_SECTION_ALIGNMENT_ENTRIES
+ COFF_SECTION_ALIGNMENT_ENTRIES,
+#endif
+ /* There must not be any gaps between .stabstr sections. */
+ { COFF_SECTION_NAME_PARTIAL_MATCH (".stabstr"),
+ 1, COFF_ALIGNMENT_FIELD_EMPTY, 0 },
+ /* The .stab section must be aligned to 2**2 at most, to avoid gaps. */
+ { COFF_SECTION_NAME_PARTIAL_MATCH (".stab"),
+ 3, COFF_ALIGNMENT_FIELD_EMPTY, 2 },
+ /* Similarly for the .ctors and .dtors sections. */
+ { COFF_SECTION_NAME_EXACT_MATCH (".ctors"),
+ 3, COFF_ALIGNMENT_FIELD_EMPTY, 2 },
+ { COFF_SECTION_NAME_EXACT_MATCH (".dtors"),
+ 3, COFF_ALIGNMENT_FIELD_EMPTY, 2 }
+};
+
+static const unsigned int coff_section_alignment_table_size =
+ sizeof coff_section_alignment_table / sizeof coff_section_alignment_table[0];
+
+/* Initialize a section structure with information peculiar to this
+ particular implementation of COFF. */
+
+static bfd_boolean
+coff_new_section_hook (bfd * abfd, asection * section)
+{
+ combined_entry_type *native;
+ bfd_size_type amt;
+ unsigned char sclass = C_STAT;
+
+ section->alignment_power = COFF_DEFAULT_SECTION_ALIGNMENT_POWER;
+
+#ifdef RS6000COFF_C
+ if (bfd_xcoff_text_align_power (abfd) != 0
+ && strcmp (bfd_get_section_name (abfd, section), ".text") == 0)
+ section->alignment_power = bfd_xcoff_text_align_power (abfd);
+ else if (bfd_xcoff_data_align_power (abfd) != 0
+ && strcmp (bfd_get_section_name (abfd, section), ".data") == 0)
+ section->alignment_power = bfd_xcoff_data_align_power (abfd);
+ else
+ {
+ int i;
+
+ for (i = 0; i < XCOFF_DWSECT_NBR_NAMES; i++)
+ if (strcmp (bfd_get_section_name (abfd, section),
+ xcoff_dwsect_names[i].name) == 0)
+ {
+ section->alignment_power = 0;
+ sclass = C_DWARF;
+ break;
+ }
+ }
+#endif
+
+ /* Set up the section symbol. */
+ if (!_bfd_generic_new_section_hook (abfd, section))
+ return FALSE;
+
+ /* 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). */
+ amt = sizeof (combined_entry_type) * 10;
+ native = (combined_entry_type *) bfd_zalloc (abfd, amt);
+ 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 overridden 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->is_sym = TRUE;
+ native->u.syment.n_type = T_NULL;
+ native->u.syment.n_sclass = sclass;
+
+ coffsymbol (section->symbol)->native = native;
+
+ coff_set_custom_section_alignment (abfd, section,
+ coff_section_alignment_table,
+ coff_section_alignment_table_size);
+
+ return TRUE;
+}
+
+#ifdef COFF_ALIGN_IN_SECTION_HEADER
+
+/* Set the alignment of a BFD section. */
+
+static void
+coff_set_alignment_hook (bfd * abfd ATTRIBUTE_UNUSED,
+ asection * section,
+ void * 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 puts the alignment power in bits 8-11. */
+ i = (hdr->s_flags >> 8) & 0xF ;
+#endif
+#ifdef COFF_DECODE_ALIGNMENT
+ i = COFF_DECODE_ALIGNMENT(hdr->s_flags);
+#endif
+ section->alignment_power = i;
+
+#ifdef coff_set_section_load_page
+ coff_set_section_load_page (section, hdr->s_page);
+#endif
+}
+
+#else /* ! COFF_ALIGN_IN_SECTION_HEADER */
+#ifdef COFF_WITH_PE
+
+static void
+coff_set_alignment_hook (bfd * abfd ATTRIBUTE_UNUSED,
+ asection * section,
+ void * scnhdr)
+{
+ struct internal_scnhdr *hdr = (struct internal_scnhdr *) scnhdr;
+ bfd_size_type amt;
+ unsigned int alignment_power_const
+ = hdr->s_flags & IMAGE_SCN_ALIGN_POWER_BIT_MASK;
+
+ switch (alignment_power_const)
+ {
+ case IMAGE_SCN_ALIGN_8192BYTES:
+ case IMAGE_SCN_ALIGN_4096BYTES:
+ case IMAGE_SCN_ALIGN_2048BYTES:
+ case IMAGE_SCN_ALIGN_1024BYTES:
+ case IMAGE_SCN_ALIGN_512BYTES:
+ case IMAGE_SCN_ALIGN_256BYTES:
+ case IMAGE_SCN_ALIGN_128BYTES:
+ case IMAGE_SCN_ALIGN_64BYTES:
+ case IMAGE_SCN_ALIGN_32BYTES:
+ case IMAGE_SCN_ALIGN_16BYTES:
+ case IMAGE_SCN_ALIGN_8BYTES:
+ case IMAGE_SCN_ALIGN_4BYTES:
+ case IMAGE_SCN_ALIGN_2BYTES:
+ case IMAGE_SCN_ALIGN_1BYTES:
+ section->alignment_power
+ = IMAGE_SCN_ALIGN_POWER_NUM (alignment_power_const);
+ break;
+ default:
+ break;
+ }
+
+ /* 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. We also keep
+ the original section flag value, since not every bit can be
+ mapped onto a generic BFD section bit. */
+ if (coff_section_data (abfd, section) == NULL)
+ {
+ amt = sizeof (struct coff_section_tdata);
+ section->used_by_bfd = bfd_zalloc (abfd, amt);
+ if (section->used_by_bfd == NULL)
+ /* FIXME: Return error. */
+ abort ();
+ }
+
+ if (pei_section_data (abfd, section) == NULL)
+ {
+ amt = sizeof (struct pei_section_tdata);
+ coff_section_data (abfd, section)->tdata = bfd_zalloc (abfd, amt);
+ if (coff_section_data (abfd, section)->tdata == NULL)
+ /* FIXME: Return error. */
+ abort ();
+ }
+ pei_section_data (abfd, section)->virt_size = hdr->s_paddr;
+ pei_section_data (abfd, section)->pe_flags = hdr->s_flags;
+
+ section->lma = hdr->s_vaddr;
+
+ /* Check for extended relocs. */
+ if (hdr->s_flags & IMAGE_SCN_LNK_NRELOC_OVFL)
+ {
+ struct external_reloc dst;
+ struct internal_reloc n;
+ file_ptr oldpos = bfd_tell (abfd);
+ bfd_size_type relsz = bfd_coff_relsz (abfd);
+
+ if (bfd_seek (abfd, (file_ptr) hdr->s_relptr, 0) != 0)
+ return;
+ if (bfd_bread (& dst, relsz, abfd) != relsz)
+ return;
+
+ coff_swap_reloc_in (abfd, &dst, &n);
+ if (bfd_seek (abfd, oldpos, 0) != 0)
+ return;
+ section->reloc_count = hdr->s_nreloc = n.r_vaddr - 1;
+ section->rel_filepos += relsz;
+ }
+ else if (hdr->s_nreloc == 0xffff)
+ (*_bfd_error_handler)
+ ("%s: warning: claims to have 0xffff relocs, without overflow",
+ bfd_get_filename (abfd));
+}
+#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 (bfd *abfd, asection *section, void * scnhdr)
+{
+ struct internal_scnhdr *hdr = (struct internal_scnhdr *) scnhdr;
+ asection *real_sec;
+
+ if ((hdr->s_flags & STYP_OVRFLO) == 0)
+ return;
+
+ real_sec = coff_section_from_bfd_index (abfd, (int) hdr->s_nreloc);
+ if (real_sec == NULL)
+ return;
+
+ real_sec->reloc_count = hdr->s_paddr;
+ real_sec->lineno_count = hdr->s_vaddr;
+
+ if (!bfd_section_removed_from_list (abfd, section))
+ {
+ bfd_section_list_remove (abfd, section);
+ --abfd->section_count;
+ }
+}
+
+#else /* ! RS6000COFF_C */
+
+#define coff_set_alignment_hook \
+ ((void (*) (bfd *, asection *, void *)) bfd_void)
+
+#endif /* ! RS6000COFF_C */
+#endif /* ! COFF_WITH_PE */
+#endif /* ! COFF_ALIGN_IN_SECTION_HEADER */
+
+#ifndef coff_mkobject
+
+static bfd_boolean
+coff_mkobject (bfd * abfd)
+{
+ coff_data_type *coff;
+ bfd_size_type amt = sizeof (coff_data_type);
+
+ abfd->tdata.coff_obj_data = bfd_zalloc (abfd, amt);
+ if (abfd->tdata.coff_obj_data == NULL)
+ return FALSE;
+ coff = coff_data (abfd);
+ coff->symbols = NULL;
+ coff->conversion_table = NULL;
+ coff->raw_syments = 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 void *
+coff_mkobject_hook (bfd * abfd,
+ void * filehdr,
+ void * aouthdr ATTRIBUTE_UNUSED)
+{
+ struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr;
+ coff_data_type *coff;
+
+ if (! coff_mkobject (abfd))
+ 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 = bfd_coff_symesz (abfd);
+ coff->local_auxesz = bfd_coff_auxesz (abfd);
+ coff->local_linesz = bfd_coff_linesz (abfd);
+
+ coff->timestamp = internal_f->f_timdat;
+
+ 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 >= bfd_coff_aoutsz (abfd))
+ {
+ struct internal_aouthdr *internal_a =
+ (struct internal_aouthdr *) aouthdr;
+ struct xcoff_tdata *xcoff;
+
+ xcoff = xcoff_data (abfd);
+# ifdef U803XTOCMAGIC
+ xcoff->xcoff64 = internal_f->f_magic == U803XTOCMAGIC;
+# else
+ xcoff->xcoff64 = 0;
+# endif
+ xcoff->full_aouthdr = TRUE;
+ xcoff->toc = internal_a->o_toc;
+ xcoff->sntoc = internal_a->o_sntoc;
+ xcoff->snentry = internal_a->o_snentry;
+ bfd_xcoff_text_align_power (abfd) = internal_a->o_algntext;
+ bfd_xcoff_data_align_power (abfd) = 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
+
+#ifdef COFF_WITH_PE
+ /* FIXME: I'm not sure this is ever executed, since peicode.h
+ defines coff_mkobject_hook. */
+ if ((internal_f->f_flags & IMAGE_FILE_DEBUG_STRIPPED) == 0)
+ abfd->flags |= HAS_DEBUG;
+#endif
+
+ if ((internal_f->f_flags & F_GO32STUB) != 0)
+ coff->go32stub = (char *) bfd_alloc (abfd, (bfd_size_type) GO32_STUBSIZE);
+ if (coff->go32stub != NULL)
+ memcpy (coff->go32stub, internal_f->go32stub, GO32_STUBSIZE);
+
+ return 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 bfd_boolean
+coff_set_arch_mach_hook (bfd *abfd, void * filehdr)
+{
+ unsigned long machine;
+ enum bfd_architecture arch;
+ struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr;
+
+ /* Zero selects the default machine for an arch. */
+ machine = 0;
+ switch (internal_f->f_magic)
+ {
+#ifdef PPCMAGIC
+ case PPCMAGIC:
+ arch = bfd_arch_powerpc;
+ 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;
+ break;
+#endif
+#ifdef AMD64MAGIC
+ case AMD64MAGIC:
+ arch = bfd_arch_i386;
+ machine = bfd_mach_x86_64;
+ break;
+#endif
+#ifdef IA64MAGIC
+ case IA64MAGIC:
+ arch = bfd_arch_ia64;
+ break;
+#endif
+#ifdef ARMMAGIC
+ case ARMMAGIC:
+ case ARMPEMAGIC:
+ case THUMBPEMAGIC:
+ arch = bfd_arch_arm;
+ machine = bfd_arm_get_mach_from_notes (abfd, ARM_NOTE_SECTION);
+ if (machine == bfd_mach_arm_unknown)
+ {
+ switch (internal_f->f_flags & F_ARM_ARCHITECTURE_MASK)
+ {
+ case F_ARM_2: machine = bfd_mach_arm_2; break;
+ case F_ARM_2a: machine = bfd_mach_arm_2a; break;
+ case F_ARM_3: machine = bfd_mach_arm_3; break;
+ default:
+ case F_ARM_3M: machine = bfd_mach_arm_3M; break;
+ case F_ARM_4: machine = bfd_mach_arm_4; break;
+ case F_ARM_4T: machine = bfd_mach_arm_4T; break;
+ /* The COFF header does not have enough bits available
+ to cover all the different ARM architectures. So
+ we interpret F_ARM_5, the highest flag value to mean
+ "the highest ARM architecture known to BFD" which is
+ currently the XScale. */
+ case F_ARM_5: machine = bfd_mach_arm_XScale; 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 Z80MAGIC
+ case Z80MAGIC:
+ arch = bfd_arch_z80;
+ switch (internal_f->f_flags & F_MACHMASK)
+ {
+ case 0:
+ case bfd_mach_z80strict << 12:
+ case bfd_mach_z80 << 12:
+ case bfd_mach_z80full << 12:
+ case bfd_mach_r800 << 12:
+ machine = ((unsigned)internal_f->f_flags & F_MACHMASK) >> 12;
+ break;
+ default:
+ return FALSE;
+ }
+ 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
+#ifdef XCOFF64
+ case U64_TOCMAGIC:
+ case U803XTOCMAGIC:
+#else
+ case U802ROMAGIC:
+ case U802WRMAGIC:
+ case U802TOCMAGIC:
+#endif
+ {
+ 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;
+ struct internal_syment sym;
+ bfd_size_type amt = bfd_coff_symesz (abfd);
+
+ buf = bfd_malloc (amt);
+ if (bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET) != 0
+ || bfd_bread (buf, amt, abfd) != amt)
+ {
+ free (buf);
+ return FALSE;
+ }
+ bfd_coff_swap_sym_in (abfd, buf, & sym);
+ if (sym.n_sclass == C_FILE)
+ cputype = sym.n_type & 0xff;
+ else
+ cputype = 0;
+ free (buf);
+ }
+ }
+
+ /* FIXME: We don't handle all cases here. */
+ switch (cputype)
+ {
+ default:
+ case 0:
+ arch = bfd_xcoff_architecture (abfd);
+ machine = bfd_xcoff_machine (abfd);
+ break;
+
+ case 1:
+ arch = bfd_arch_powerpc;
+ machine = bfd_mach_ppc_601;
+ break;
+ case 2: /* 64 bit PowerPC */
+ arch = bfd_arch_powerpc;
+ machine = bfd_mach_ppc_620;
+ break;
+ case 3:
+ arch = bfd_arch_powerpc;
+ machine = bfd_mach_ppc;
+ break;
+ case 4:
+ arch = bfd_arch_rs6000;
+ machine = bfd_mach_rs6k;
+ break;
+ }
+ }
+ break;
+#endif
+
+#ifdef WE32KMAGIC
+ case WE32KMAGIC:
+ arch = bfd_arch_we32k;
+ 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 H8300HNMAGIC
+ case H8300HNMAGIC:
+ arch = bfd_arch_h8300;
+ machine = bfd_mach_h8300hn;
+ /* !! FIXME this probably isn't the right place for this. */
+ abfd->flags |= BFD_IS_RELAXABLE;
+ break;
+#endif
+
+#ifdef H8300SNMAGIC
+ case H8300SNMAGIC:
+ arch = bfd_arch_h8300;
+ machine = bfd_mach_h8300sn;
+ /* !! 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:
+#ifdef COFF_WITH_PE
+ case SH_ARCH_MAGIC_WINCE:
+#endif
+ arch = bfd_arch_sh;
+ break;
+#endif
+
+#ifdef MIPS_ARCH_MAGIC_WINCE
+ case MIPS_ARCH_MAGIC_WINCE:
+ arch = bfd_arch_mips;
+ break;
+#endif
+
+#ifdef H8500MAGIC
+ case H8500MAGIC:
+ arch = bfd_arch_h8500;
+ break;
+#endif
+
+#ifdef SPARCMAGIC
+ case SPARCMAGIC:
+#ifdef LYNXCOFFMAGIC
+ case LYNXCOFFMAGIC:
+#endif
+ arch = bfd_arch_sparc;
+ break;
+#endif
+
+#ifdef TIC30MAGIC
+ case TIC30MAGIC:
+ arch = bfd_arch_tic30;
+ break;
+#endif
+
+#ifdef TICOFF0MAGIC
+#ifdef TICOFF_TARGET_ARCH
+ /* This TI COFF section should be used by all new TI COFF v0 targets. */
+ case TICOFF0MAGIC:
+ arch = TICOFF_TARGET_ARCH;
+ machine = TICOFF_TARGET_MACHINE_GET (internal_f->f_flags);
+ break;
+#endif
+#endif
+
+#ifdef TICOFF1MAGIC
+ /* This TI COFF section should be used by all new TI COFF v1/2 targets. */
+ /* TI COFF1 and COFF2 use the target_id field to specify which arch. */
+ case TICOFF1MAGIC:
+ case TICOFF2MAGIC:
+ switch (internal_f->f_target_id)
+ {
+#ifdef TI_TARGET_ID
+ case TI_TARGET_ID:
+ arch = TICOFF_TARGET_ARCH;
+ machine = TICOFF_TARGET_MACHINE_GET (internal_f->f_flags);
+ break;
+#endif
+ default:
+ arch = bfd_arch_obscure;
+ (*_bfd_error_handler)
+ (_("Unrecognized TI COFF target id '0x%x'"),
+ internal_f->f_target_id);
+ break;
+ }
+ 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
+
+#ifdef W65MAGIC
+ case W65MAGIC:
+ arch = bfd_arch_w65;
+ 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 bfd_boolean
+symname_in_debug_hook (bfd * abfd ATTRIBUTE_UNUSED, struct internal_syment *sym)
+{
+ return SYMNAME_IN_DEBUG (sym) != 0;
+}
+
+#else
+
+#define symname_in_debug_hook \
+ (bfd_boolean (*) (bfd *, struct internal_syment *)) bfd_false
+
+#endif
+
+#ifdef RS6000COFF_C
+
+#ifdef XCOFF64
+#define FORCE_SYMNAMES_IN_STRINGS
+#endif
+
+/* Handle the csect auxent of a C_EXT, C_AIX_WEAKEXT or C_HIDEXT symbol. */
+
+static bfd_boolean
+coff_pointerize_aux_hook (bfd *abfd ATTRIBUTE_UNUSED,
+ combined_entry_type *table_base,
+ combined_entry_type *symbol,
+ unsigned int indaux,
+ combined_entry_type *aux)
+{
+ BFD_ASSERT (symbol->is_sym);
+ int n_sclass = symbol->u.syment.n_sclass;
+
+ if (CSECT_SYM_P (n_sclass)
+ && indaux + 1 == symbol->u.syment.n_numaux)
+ {
+ BFD_ASSERT (! aux->is_sym);
+ 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 bfd_boolean
+coff_pointerize_aux_hook (bfd *abfd ATTRIBUTE_UNUSED,
+ combined_entry_type *table_base ATTRIBUTE_UNUSED,
+ combined_entry_type *symbol,
+ unsigned int indaux,
+ combined_entry_type *aux ATTRIBUTE_UNUSED)
+{
+ /* 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->is_sym
+ && (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 bfd_boolean
+coff_print_aux (bfd *abfd ATTRIBUTE_UNUSED,
+ FILE *file ATTRIBUTE_UNUSED,
+ combined_entry_type *table_base ATTRIBUTE_UNUSED,
+ combined_entry_type *symbol ATTRIBUTE_UNUSED,
+ combined_entry_type *aux ATTRIBUTE_UNUSED,
+ unsigned int indaux ATTRIBUTE_UNUSED)
+{
+ BFD_ASSERT (symbol->is_sym);
+ BFD_ASSERT (! aux->is_sym);
+#ifdef RS6000COFF_C
+ if (CSECT_SYM_P (symbol->u.syment.n_sclass)
+ && 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);
+#ifdef XCOFF64
+ fprintf (file, "val %5lld",
+ (long long) aux->u.auxent.x_csect.x_scnlen.l);
+#else
+ fprintf (file, "val %5ld", (long) aux->u.auxent.x_csect.x_scnlen.l);
+#endif
+ }
+ else
+ {
+ fprintf (file, "indx ");
+ if (! aux->fix_scnlen)
+#ifdef XCOFF64
+ fprintf (file, "%4lld",
+ (long long) aux->u.auxent.x_csect.x_scnlen.l);
+#else
+ fprintf (file, "%4ld", (long) aux->u.auxent.x_csect.x_scnlen.l);
+#endif
+ 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
+
+
+/* AUX's ld wants relocations to be sorted. */
+static int
+compare_arelent_ptr (const void * x, const void * 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 bfd_boolean
+coff_write_relocs (bfd * abfd, int first_undef)
+{
+ asection *s;
+
+ for (s = abfd->sections; s != 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. */
+ bfd_size_type amt;
+
+ amt = s->reloc_count;
+ amt *= sizeof (arelent *);
+ p = bfd_malloc (amt);
+ if (p == NULL && s->reloc_count > 0)
+ return FALSE;
+ memcpy (p, s->orelocation, (size_t) amt);
+ qsort (p, s->reloc_count, sizeof (arelent *), compare_arelent_ptr);
+ }
+#endif
+
+ if (bfd_seek (abfd, s->rel_filepos, SEEK_SET) != 0)
+ return FALSE;
+
+#ifdef COFF_WITH_PE
+ if (obj_pe (abfd) && s->reloc_count >= 0xffff)
+ {
+ /* Encode real count here as first reloc. */
+ struct internal_reloc n;
+
+ memset (& n, 0, sizeof (n));
+ /* Add one to count *this* reloc (grr). */
+ n.r_vaddr = s->reloc_count + 1;
+ coff_swap_reloc_out (abfd, &n, &dst);
+ if (bfd_bwrite (& dst, (bfd_size_type) bfd_coff_relsz (abfd),
+ abfd) != bfd_coff_relsz (abfd))
+ return FALSE;
+ }
+#endif
+
+ for (i = 0; i < s->reloc_count; i++)
+ {
+ struct internal_reloc n;
+ arelent *q = p[i];
+
+ memset (& 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] != NULL && q->sym_ptr_ptr[0]->the_bfd != abfd)
+ {
+ int j;
+ const char *sname = q->sym_ptr_ptr[0]->name;
+ asymbol **outsyms = abfd->outsymbols;
+
+ for (j = first_undef; outsyms[j]; j++)
+ {
+ const char *intable = outsyms[j]->name;
+
+ if (strcmp (intable, sname) == 0)
+ {
+ /* Got a hit, so repoint the reloc. */
+ q->sym_ptr_ptr = outsyms + j;
+ 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 && q->sym_ptr_ptr[0] != NULL)
+ {
+#ifdef SECTION_RELATIVE_ABSOLUTE_SYMBOL_P
+ if (SECTION_RELATIVE_ABSOLUTE_SYMBOL_P (q, s))
+#else
+ if ((*q->sym_ptr_ptr)->section == bfd_abs_section_ptr
+ && ((*q->sym_ptr_ptr)->flags & BSF_SECTION_SYM) != 0)
+#endif
+ /* This is a relocation relative to the absolute symbol. */
+ n.r_symndx = -1;
+ else
+ {
+ n.r_symndx = get_index ((*(q->sym_ptr_ptr)));
+ /* Check to see if the symbol reloc points to a symbol
+ we don't have in our symbol table. */
+ if (n.r_symndx > obj_conv_table_size (abfd))
+ {
+ bfd_set_error (bfd_error_bad_value);
+ _bfd_error_handler (_("%B: reloc against a non-existant symbol index: %ld"),
+ abfd, n.r_symndx);
+ return FALSE;
+ }
+ }
+ }
+
+#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_bwrite (& dst, (bfd_size_type) bfd_coff_relsz (abfd),
+ abfd) != bfd_coff_relsz (abfd))
+ 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 bfd_boolean
+coff_set_flags (bfd * abfd,
+ unsigned int *magicp ATTRIBUTE_UNUSED,
+ unsigned short *flagsp ATTRIBUTE_UNUSED)
+{
+ switch (bfd_get_arch (abfd))
+ {
+#ifdef Z80MAGIC
+ case bfd_arch_z80:
+ *magicp = Z80MAGIC;
+ switch (bfd_get_mach (abfd))
+ {
+ case 0:
+ case bfd_mach_z80strict:
+ case bfd_mach_z80:
+ case bfd_mach_z80full:
+ case bfd_mach_r800:
+ *flagsp = bfd_get_mach (abfd) << 12;
+ break;
+ default:
+ return FALSE;
+ }
+ return TRUE;
+#endif
+
+#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;
+
+ 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 TICOFF_DEFAULT_MAGIC
+ case TICOFF_TARGET_ARCH:
+ /* If there's no indication of which version we want, use the default. */
+ if (!abfd->xvec )
+ *magicp = TICOFF_DEFAULT_MAGIC;
+ else
+ {
+ /* We may want to output in a different COFF version. */
+ switch (abfd->xvec->name[4])
+ {
+ case '0':
+ *magicp = TICOFF0MAGIC;
+ break;
+ case '1':
+ *magicp = TICOFF1MAGIC;
+ break;
+ case '2':
+ *magicp = TICOFF2MAGIC;
+ break;
+ default:
+ return FALSE;
+ }
+ }
+ TICOFF_TARGET_MACHINE_SET (flagsp, bfd_get_mach (abfd));
+ return TRUE;
+#endif
+
+#ifdef TIC80_ARCH_MAGIC
+ case bfd_arch_tic80:
+ *magicp = TIC80_ARCH_MAGIC;
+ return TRUE;
+#endif
+
+#ifdef ARMMAGIC
+ case bfd_arch_arm:
+#ifdef ARM_WINCE
+ * magicp = ARMPEMAGIC;
+#else
+ * magicp = ARMMAGIC;
+#endif
+ * 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;
+ }
+ 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;
+ case bfd_mach_arm_5: * flagsp |= F_ARM_5; break;
+ /* FIXME: we do not have F_ARM vaues greater than F_ARM_5.
+ See also the comment in coff_set_arch_mach_hook(). */
+ case bfd_mach_arm_5T: * flagsp |= F_ARM_5; break;
+ case bfd_mach_arm_5TE: * flagsp |= F_ARM_5; break;
+ case bfd_mach_arm_XScale: * flagsp |= F_ARM_5; break;
+ }
+ return TRUE;
+#endif
+
+#ifdef PPCMAGIC
+ case bfd_arch_powerpc:
+ *magicp = PPCMAGIC;
+ return TRUE;
+#endif
+
+#if defined(I386MAGIC) || defined(AMD64MAGIC)
+ case bfd_arch_i386:
+#if defined(I386MAGIC)
+ *magicp = I386MAGIC;
+#endif
+#if defined LYNXOS
+ /* Just overwrite the usual value if we're doing Lynx. */
+ *magicp = LYNXCOFFMAGIC;
+#endif
+#if defined AMD64MAGIC
+ *magicp = AMD64MAGIC;
+#endif
+ return TRUE;
+#endif
+
+#ifdef I860MAGIC
+ case bfd_arch_i860:
+ *magicp = I860MAGIC;
+ return TRUE;
+#endif
+
+#ifdef IA64MAGIC
+ case bfd_arch_ia64:
+ *magicp = IA64MAGIC;
+ return TRUE;
+#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;
+#endif
+
+#ifdef MC88MAGIC
+ case bfd_arch_m88k:
+ *magicp = MC88OMAGIC;
+ return TRUE;
+#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;
+ case bfd_mach_h8300hn: *magicp = H8300HNMAGIC; return TRUE;
+ case bfd_mach_h8300sn: *magicp = H8300SNMAGIC; return TRUE;
+ default: break;
+ }
+ break;
+#endif
+
+#ifdef SH_ARCH_MAGIC_BIG
+ case bfd_arch_sh:
+#ifdef COFF_IMAGE_WITH_PE
+ *magicp = SH_ARCH_MAGIC_WINCE;
+#else
+ if (bfd_big_endian (abfd))
+ *magicp = SH_ARCH_MAGIC_BIG;
+ else
+ *magicp = SH_ARCH_MAGIC_LITTLE;
+#endif
+ return TRUE;
+#endif
+
+#ifdef MIPS_ARCH_MAGIC_WINCE
+ case bfd_arch_mips:
+ *magicp = MIPS_ARCH_MAGIC_WINCE;
+ return TRUE;
+#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;
+#endif
+
+#ifdef H8500MAGIC
+ case bfd_arch_h8500:
+ *magicp = H8500MAGIC;
+ return TRUE;
+ break;
+#endif
+
+#ifdef WE32KMAGIC
+ case bfd_arch_we32k:
+ *magicp = WE32KMAGIC;
+ return TRUE;
+#endif
+
+#ifdef RS6000COFF_C
+ case bfd_arch_rs6000:
+#ifndef PPCMAGIC
+ case bfd_arch_powerpc:
+#endif
+ BFD_ASSERT (bfd_get_flavour (abfd) == bfd_target_xcoff_flavour);
+ *magicp = bfd_xcoff_magic_number (abfd);
+ return TRUE;
+#endif
+
+#ifdef MCOREMAGIC
+ case bfd_arch_mcore:
+ * magicp = MCOREMAGIC;
+ return TRUE;
+#endif
+
+#ifdef W65MAGIC
+ case bfd_arch_w65:
+ *magicp = W65MAGIC;
+ return TRUE;
+#endif
+
+ default: /* Unknown architecture. */
+ /* Fall through to "return FALSE" below, to avoid
+ "statement never reached" errors on the one below. */
+ break;
+ }
+
+ return FALSE;
+}
+
+static bfd_boolean
+coff_set_arch_mach (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))
+ return FALSE; /* We can't represent this type. */
+
+ return TRUE; /* We're easy... */
+}
+
+#ifdef COFF_IMAGE_WITH_PE
+
+/* This is used to sort sections by VMA, as required by PE image
+ files. */
+
+static int
+sort_by_secaddr (const void * arg1, const void * arg2)
+{
+ const asection *a = *(const asection **) arg1;
+ const asection *b = *(const asection **) arg2;
+
+ if (a->vma < b->vma)
+ return -1;
+ else if (a->vma > b->vma)
+ return 1;
+
+ return 0;
+}
+
+#endif /* COFF_IMAGE_WITH_PE */
+
+/* Calculate the file position for each section. */
+
+#ifndef I960
+#define ALIGN_SECTIONS_IN_FILE
+#endif
+#if defined(TIC80COFF) || defined(TICOFF)
+#undef ALIGN_SECTIONS_IN_FILE
+#endif
+
+static bfd_boolean
+coff_compute_section_file_positions (bfd * abfd)
+{
+ asection *current;
+ file_ptr sofar = bfd_coff_filhsz (abfd);
+ bfd_boolean align_adjust;
+ unsigned int target_index;
+#ifdef ALIGN_SECTIONS_IN_FILE
+ asection *previous = NULL;
+ file_ptr old_sofar;
+#endif
+
+#ifdef COFF_IMAGE_WITH_PE
+ int page_size;
+
+ if (coff_data (abfd)->link_info
+ || (pe_data (abfd) && pe_data (abfd)->pe_opthdr.FileAlignment))
+ {
+ page_size = pe_data (abfd)->pe_opthdr.FileAlignment;
+
+ /* If no file alignment has been set, default to one.
+ This repairs 'ld -r' for arm-wince-pe target. */
+ if (page_size == 0)
+ page_size = 1;
+ }
+ else
+ page_size = PE_DEF_FILE_ALIGNMENT;
+#else
+#ifdef COFF_PAGE_SIZE
+ int page_size = COFF_PAGE_SIZE;
+#endif
+#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
+ && cf->native->is_sym
+ && SYMNAME_IN_DEBUG (&cf->native->u.syment))
+ {
+ size_t len;
+
+ len = strlen (bfd_asymbol_name (*symp));
+ if (len > SYMNMLEN || bfd_coff_force_symnames_in_strings (abfd))
+ sz += len + 1 + bfd_coff_debug_string_prefix_length (abfd);
+ }
+ }
+ if (sz > 0)
+ {
+ asection *dsec;
+
+ dsec = bfd_make_section_old_way (abfd, DOT_DEBUG);
+ if (dsec == NULL)
+ abort ();
+ dsec->size = sz;
+ dsec->flags |= SEC_HAS_CONTENTS;
+ }
+ }
+#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 += bfd_coff_aoutsz (abfd);
+#ifdef RS6000COFF_C
+ else if (xcoff_data (abfd)->full_aouthdr)
+ sofar += bfd_coff_aoutsz (abfd);
+ else
+ sofar += SMALL_AOUTSZ;
+#endif
+
+ sofar += abfd->section_count * bfd_coff_scnhsz (abfd);
+
+#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 += bfd_coff_scnhsz (abfd);
+#endif
+
+#ifdef COFF_IMAGE_WITH_PE
+ {
+ /* PE requires the sections to be in memory order when listed in
+ the section headers. It also does not like empty loadable
+ sections. The sections apparently do not have to be in the
+ right order in the image file itself, but we do need to get the
+ target_index values right. */
+
+ unsigned int count;
+ asection **section_list;
+ unsigned int i;
+ bfd_size_type amt;
+
+#ifdef COFF_PAGE_SIZE
+ /* Clear D_PAGED if section alignment is smaller than
+ COFF_PAGE_SIZE. */
+ if (pe_data (abfd)->pe_opthdr.SectionAlignment < COFF_PAGE_SIZE)
+ abfd->flags &= ~D_PAGED;
+#endif
+
+ count = 0;
+ for (current = abfd->sections; current != NULL; current = current->next)
+ ++count;
+
+ /* We allocate an extra cell to simplify the final loop. */
+ amt = sizeof (struct asection *) * (count + 1);
+ section_list = (asection **) bfd_malloc (amt);
+ if (section_list == NULL)
+ return FALSE;
+
+ i = 0;
+ for (current = abfd->sections; current != NULL; current = current->next)
+ {
+ section_list[i] = current;
+ ++i;
+ }
+ section_list[i] = NULL;
+
+ qsort (section_list, count, sizeof (asection *), sort_by_secaddr);
+
+ /* Rethread the linked list into sorted order; at the same time,
+ assign target_index values. */
+ target_index = 1;
+ abfd->sections = NULL;
+ abfd->section_last = NULL;
+ for (i = 0; i < count; i++)
+ {
+ current = section_list[i];
+ bfd_section_list_append (abfd, current);
+
+ /* Later, if the section has zero size, we'll be throwing it
+ away, so we don't want to number it now. Note that having
+ a zero size and having real contents are different
+ concepts: .bss has no contents, but (usually) non-zero
+ size. */
+ if (current->size == 0)
+ {
+ /* Discard. However, it still might have (valid) symbols
+ in it, so arbitrarily set it to section 1 (indexing is
+ 1-based here; usually .text). __end__ and other
+ contents of .endsection really have this happen.
+ FIXME: This seems somewhat dubious. */
+ current->target_index = 1;
+ }
+ else
+ current->target_index = target_index++;
+ }
+
+ free (section_list);
+ }
+#else /* ! COFF_IMAGE_WITH_PE */
+ {
+ /* Set the target_index field. */
+ target_index = 1;
+ for (current = abfd->sections; current != NULL; current = current->next)
+ current->target_index = target_index++;
+ }
+#endif /* ! COFF_IMAGE_WITH_PE */
+
+ if (target_index >= bfd_coff_max_nscns (abfd))
+ {
+ bfd_set_error (bfd_error_file_too_big);
+ (*_bfd_error_handler)
+ (_("%B: too many sections (%d)"), abfd, target_index);
+ return FALSE;
+ }
+
+ align_adjust = FALSE;
+ for (current = abfd->sections;
+ current != NULL;
+ current = current->next)
+ {
+#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)
+ {
+ bfd_size_type amt = sizeof (struct coff_section_tdata);
+
+ current->used_by_bfd = bfd_zalloc (abfd, amt);
+ if (current->used_by_bfd == NULL)
+ return FALSE;
+ }
+ if (pei_section_data (abfd, current) == NULL)
+ {
+ bfd_size_type amt = sizeof (struct pei_section_tdata);
+
+ coff_section_data (abfd, current)->tdata = bfd_zalloc (abfd, amt);
+ 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->size;
+#endif
+
+ /* Only deal with sections which have contents. */
+ if (!(current->flags & SEC_HAS_CONTENTS))
+ continue;
+
+ current->rawsize = current->size;
+
+#ifdef COFF_IMAGE_WITH_PE
+ /* Make sure we skip empty sections in a PE image. */
+ if (current->size == 0)
+ continue;
+#endif
+
+ /* 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);
+
+#ifdef RS6000COFF_C
+ /* Make sure the file offset and the vma of .text/.data are at the
+ same page offset, so that the file can be mmap'ed without being
+ relocated. Failing that, AIX is able to load and execute the
+ program, but it will be silently relocated (possible as
+ executables are PIE). But the relocation is slightly costly and
+ complexify the use of addr2line or gdb. So better to avoid it,
+ like does the native linker. Usually gnu ld makes sure that
+ the vma of .text is the file offset so this issue shouldn't
+ appear unless you are stripping such an executable.
+
+ AIX loader checks the text section alignment of (vma - filepos),
+ and the native linker doesn't try to align the text sections.
+ For example:
+
+ 0 .text 000054cc 10000128 10000128 00000128 2**5
+ CONTENTS, ALLOC, LOAD, CODE
+ */
+
+ if (!strcmp (current->name, _TEXT)
+ || !strcmp (current->name, _DATA))
+ {
+ bfd_vma align = 4096;
+ bfd_vma sofar_off = sofar % align;
+ bfd_vma vma_off = current->vma % align;
+
+ if (vma_off > sofar_off)
+ sofar += vma_off - sofar_off;
+ else if (vma_off < sofar_off)
+ sofar += align + vma_off - sofar_off;
+ }
+#endif
+ if (previous != NULL)
+ previous->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 - (bfd_vma) sofar) % page_size;
+#endif
+ current->filepos = sofar;
+
+#ifdef COFF_IMAGE_WITH_PE
+ /* Set the padded size. */
+ current->size = (current->size + page_size - 1) & -page_size;
+#endif
+
+ sofar += current->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->size;
+ current->size = BFD_ALIGN (current->size,
+ 1 << current->alignment_power);
+ align_adjust = current->size != old_size;
+ sofar += current->size - old_size;
+ }
+ else
+ {
+ old_sofar = sofar;
+ sofar = BFD_ALIGN (sofar, 1 << current->alignment_power);
+ align_adjust = sofar != old_sofar;
+ current->size += sofar - old_sofar;
+ }
+#endif
+
+#ifdef COFF_IMAGE_WITH_PE
+ /* For PE we need to make sure we pad out to the aligned
+ size, in case the caller only writes out data to the
+ unaligned size. */
+ if (pei_section_data (abfd, current)->virt_size < current->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)
+ (void) bfd_set_section_vma (abfd, current, 0);
+#endif
+
+#ifdef ALIGN_SECTIONS_IN_FILE
+ previous = current;
+#endif
+ }
+
+ /* 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_bwrite (&b, (bfd_size_type) 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;
+}
+
+#ifdef COFF_IMAGE_WITH_PE
+
+static unsigned int pelength;
+static unsigned int peheader;
+
+static bfd_boolean
+coff_read_word (bfd *abfd, unsigned int *value)
+{
+ unsigned char b[2];
+ int status;
+
+ status = bfd_bread (b, (bfd_size_type) 2, abfd);
+ if (status < 1)
+ {
+ *value = 0;
+ return FALSE;
+ }
+
+ if (status == 1)
+ *value = (unsigned int) b[0];
+ else
+ *value = (unsigned int) (b[0] + (b[1] << 8));
+
+ pelength += (unsigned int) status;
+
+ return TRUE;
+}
+
+static unsigned int
+coff_compute_checksum (bfd *abfd)
+{
+ bfd_boolean more_data;
+ file_ptr filepos;
+ unsigned int value;
+ unsigned int total;
+
+ total = 0;
+ pelength = 0;
+ filepos = (file_ptr) 0;
+
+ do
+ {
+ if (bfd_seek (abfd, filepos, SEEK_SET) != 0)
+ return 0;
+
+ more_data = coff_read_word (abfd, &value);
+ total += value;
+ total = 0xffff & (total + (total >> 0x10));
+ filepos += 2;
+ }
+ while (more_data);
+
+ return (0xffff & (total + (total >> 0x10)));
+}
+
+static bfd_boolean
+coff_apply_checksum (bfd *abfd)
+{
+ unsigned int computed;
+ unsigned int checksum = 0;
+
+ if (bfd_seek (abfd, 0x3c, SEEK_SET) != 0)
+ return FALSE;
+
+ if (!coff_read_word (abfd, &peheader))
+ return FALSE;
+
+ if (bfd_seek (abfd, peheader + 0x58, SEEK_SET) != 0)
+ return FALSE;
+
+ checksum = 0;
+ bfd_bwrite (&checksum, (bfd_size_type) 4, abfd);
+
+ if (bfd_seek (abfd, peheader, SEEK_SET) != 0)
+ return FALSE;
+
+ computed = coff_compute_checksum (abfd);
+
+ checksum = computed + pelength;
+
+ if (bfd_seek (abfd, peheader + 0x58, SEEK_SET) != 0)
+ return FALSE;
+
+ bfd_bwrite (&checksum, (bfd_size_type) 4, abfd);
+
+ return TRUE;
+}
+
+#endif /* COFF_IMAGE_WITH_PE */
+
+static bfd_boolean
+coff_write_object_contents (bfd * abfd)
+{
+ asection *current;
+ bfd_boolean hasrelocs = FALSE;
+ bfd_boolean haslinno = FALSE;
+#ifdef COFF_IMAGE_WITH_PE
+ bfd_boolean hasdebug = FALSE;
+#endif
+ file_ptr scn_base;
+ file_ptr reloc_base;
+ file_ptr lineno_base;
+ file_ptr sym_base;
+ unsigned long reloc_size = 0, reloc_count = 0;
+ unsigned long lnno_size = 0;
+ bfd_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) * bfd_coff_linesz (abfd);
+
+ if (! abfd->output_has_begun)
+ {
+ 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)
+ {
+#ifdef COFF_WITH_PE
+ /* We store the actual reloc count in the first reloc's addr. */
+ if (obj_pe (abfd) && current->reloc_count >= 0xffff)
+ reloc_count ++;
+#endif
+ reloc_count += current->reloc_count;
+ }
+
+ reloc_size = reloc_count * bfd_coff_relsz (abfd);
+
+ 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 * bfd_coff_linesz (abfd);
+ }
+ else
+ current->line_filepos = 0;
+
+ if (current->reloc_count)
+ {
+ current->rel_filepos = reloc_base;
+ reloc_base += current->reloc_count * bfd_coff_relsz (abfd);
+#ifdef COFF_WITH_PE
+ /* Extra reloc to hold real count. */
+ if (obj_pe (abfd) && current->reloc_count >= 0xffff)
+ reloc_base += bfd_coff_relsz (abfd);
+#endif
+ }
+ else
+ current->rel_filepos = 0;
+ }
+
+ /* Write section headers to the file. */
+ internal_f.f_nscns = 0;
+
+ if ((abfd->flags & EXEC_P) != 0)
+ scn_base = bfd_coff_filhsz (abfd) + bfd_coff_aoutsz (abfd);
+ else
+ {
+ scn_base = bfd_coff_filhsz (abfd);
+#ifdef RS6000COFF_C
+#ifndef XCOFF64
+ if (xcoff_data (abfd)->full_aouthdr)
+ scn_base += bfd_coff_aoutsz (abfd);
+ else
+ scn_base += SMALL_AOUTSZ;
+#endif
+#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_IMAGE_WITH_PE
+ bfd_boolean is_reloc_section = FALSE;
+
+ if (strcmp (current->name, DOT_RELOC) == 0)
+ {
+ is_reloc_section = TRUE;
+ hasrelocs = TRUE;
+ pe_data (abfd)->has_reloc_section = 1;
+ }
+#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 and _bfd_coff_final_link. */
+ if (bfd_coff_long_section_names (abfd))
+ {
+ size_t len;
+
+ len = strlen (current->name);
+ if (len > SCNNMLEN)
+ {
+ /* The s_name field is defined to be NUL-padded but need not be
+ NUL-terminated. We use a temporary buffer so that we can still
+ sprintf all eight chars without splatting a terminating NUL
+ over the first byte of the following member (s_paddr). */
+ char s_name_buf[SCNNMLEN + 1];
+
+ /* An inherent limitation of the /nnnnnnn notation used to indicate
+ the offset of the long name in the string table is that we
+ cannot address entries beyone the ten million byte boundary. */
+ if (string_size >= 10000000)
+ {
+ bfd_set_error (bfd_error_file_too_big);
+ (*_bfd_error_handler)
+ (_("%B: section %s: string table overflow at offset %ld"),
+ abfd, current->name, string_size);
+ return FALSE;
+ }
+
+ /* snprintf not strictly necessary now we've verified the value
+ has less than eight ASCII digits, but never mind. */
+ snprintf (s_name_buf, SCNNMLEN + 1, "/%lu", (unsigned long) string_size);
+ /* Then strncpy takes care of any padding for us. */
+ strncpy (section.s_name, s_name_buf, SCNNMLEN);
+ 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->size;
+#ifdef coff_get_section_load_page
+ section.s_page = coff_get_section_load_page (current);
+#else
+ section.s_page = 0;
+#endif
+
+#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->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;
+#ifndef COFF_IMAGE_WITH_PE
+ /* In PEI, relocs come in the .reloc section. */
+ if (current->reloc_count != 0)
+ hasrelocs = TRUE;
+#endif
+ if (current->lineno_count != 0)
+ haslinno = TRUE;
+#ifdef COFF_IMAGE_WITH_PE
+ if ((current->flags & SEC_DEBUGGING) != 0
+ && ! is_reloc_section)
+ hasdebug = TRUE;
+#endif
+
+#ifdef RS6000COFF_C
+#ifndef XCOFF64
+ /* 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
+#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);
+#endif
+#ifdef TIC80COFF
+ /* TI COFF puts the alignment power in bits 8-11 of the flags. */
+ section.s_flags |= (current->alignment_power & 0xF) << 8;
+#endif
+#ifdef COFF_ENCODE_ALIGNMENT
+ COFF_ENCODE_ALIGNMENT(section, current->alignment_power);
+#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. See also coff_compute_section_file_positions. */
+ if (section.s_size == 0)
+ internal_f.f_nscns--;
+ else
+#endif
+ {
+ SCNHDR buff;
+ bfd_size_type amt = bfd_coff_scnhsz (abfd);
+
+ if (coff_swap_scnhdr_out (abfd, &section, &buff) == 0
+ || bfd_bwrite (& buff, amt, abfd) != amt)
+ 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->is_sym
+ || 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;
+ BFD_ASSERT (! aux->is_sym);
+ 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
+#ifndef XCOFF64
+ /* 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;
+ bfd_size_type amt;
+
+ internal_f.f_nscns++;
+ memcpy (scnhdr.s_name, ".ovrflo", 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;
+ amt = bfd_coff_scnhsz (abfd);
+ if (coff_swap_scnhdr_out (abfd, &scnhdr, &buff) == 0
+ || bfd_bwrite (& buff, amt, abfd) != amt)
+ return FALSE;
+ }
+ }
+#endif
+#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 = bfd_coff_aoutsz (abfd);
+ else
+ {
+ internal_f.f_opthdr = 0;
+#ifdef RS6000COFF_C
+#ifndef XCOFF64
+ if (xcoff_data (abfd)->full_aouthdr)
+ internal_f.f_opthdr = bfd_coff_aoutsz (abfd);
+ else
+ internal_f.f_opthdr = SMALL_AOUTSZ;
+#endif
+#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;
+#ifdef COFF_IMAGE_WITH_PE
+ if (! hasdebug)
+ internal_f.f_flags |= IMAGE_FILE_DEBUG_STRIPPED;
+ if (pe_data (abfd)->real_flags & IMAGE_FILE_LARGE_ADDRESS_AWARE)
+ internal_f.f_flags |= IMAGE_FILE_LARGE_ADDRESS_AWARE;
+#endif
+
+#ifndef COFF_WITH_pex64
+#ifdef COFF_WITH_PE
+ internal_f.f_flags |= IMAGE_FILE_32BIT_MACHINE;
+#else
+ if (bfd_little_endian (abfd))
+ internal_f.f_flags |= F_AR32WR;
+ else
+ internal_f.f_flags |= F_AR32W;
+#endif
+#endif
+
+#ifdef TI_TARGET_ID
+ /* Target id is used in TI COFF v1 and later; COFF0 won't use this field,
+ but it doesn't hurt to set it internally. */
+ internal_f.f_target_id = TI_TARGET_ID;
+#endif
+#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
+
+ /* 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 TICOFF_AOUT_MAGIC
+ internal_a.magic = TICOFF_AOUT_MAGIC;
+#define __A_MAGIC_SET__
+#endif
+#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;
+#elif defined AMD64
+ internal_a.magic = IMAGE_NT_OPTIONAL_HDR64_MAGIC;
+#else
+ internal_a.magic = ZMAGIC;
+#endif
+#endif /* I386 */
+
+#if defined(IA64)
+#define __A_MAGIC_SET__
+ internal_a.magic = PE32PMAGIC;
+#endif /* IA64 */
+
+#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
+
+#if defined(SH) && defined(COFF_WITH_PE)
+#define __A_MAGIC_SET__
+ internal_a.magic = SH_PE_MAGIC;
+#endif
+
+#if defined(MIPS) && defined(COFF_WITH_PE)
+#define __A_MAGIC_SET__
+ internal_a.magic = MIPS_PE_MAGIC;
+#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 (!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 && ! obj_coff_strings_written (abfd))
+ {
+ /* 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,
+ (file_ptr) BFD_ALIGN (sym_base, COFF_PAGE_SIZE) - 1,
+ SEEK_SET) != 0
+ || bfd_bwrite (&b, (bfd_size_type) 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 = text_sec->size;
+ internal_a.text_start = internal_a.tsize ? text_sec->vma : 0;
+ }
+ if (data_sec)
+ {
+ internal_a.dsize = data_sec->size;
+ internal_a.data_start = internal_a.dsize ? data_sec->vma : 0;
+ }
+ if (bss_sec)
+ {
+ internal_a.bsize = bss_sec->size;
+ 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) == bfd_mach_ppc)
+ 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
+
+#ifdef COFF_WITH_PE
+ {
+ /* After object contents are finalized so we can compute a reasonable hash,
+ but before header is written so we can update it to point to debug directory. */
+ struct pe_tdata *pe = pe_data (abfd);
+
+ if (pe->build_id.after_write_object_contents != NULL)
+ (*pe->build_id.after_write_object_contents) (abfd);
+ }
+#endif
+
+ /* Now write header. */
+ if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
+ return FALSE;
+
+ {
+ char * buff;
+ bfd_size_type amount = bfd_coff_filhsz (abfd);
+
+ buff = (char *) bfd_malloc (amount);
+ if (buff == NULL)
+ return FALSE;
+
+ bfd_coff_swap_filehdr_out (abfd, & internal_f, buff);
+ amount = bfd_bwrite (buff, amount, abfd);
+
+ free (buff);
+
+ if (amount != bfd_coff_filhsz (abfd))
+ 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;
+ bfd_size_type amount = bfd_coff_aoutsz (abfd);
+
+ buff = (char *) bfd_malloc (amount);
+ if (buff == NULL)
+ return FALSE;
+
+ coff_swap_aouthdr_out (abfd, & internal_a, buff);
+ amount = bfd_bwrite (buff, amount, abfd);
+
+ free (buff);
+
+ if (amount != bfd_coff_aoutsz (abfd))
+ return FALSE;
+
+#ifdef COFF_IMAGE_WITH_PE
+ if (! coff_apply_checksum (abfd))
+ return FALSE;
+#endif
+ }
+#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, & internal_a, & buff);
+ if (xcoff_data (abfd)->full_aouthdr)
+ size = bfd_coff_aoutsz (abfd);
+ else
+ size = SMALL_AOUTSZ;
+ if (bfd_bwrite (& buff, (bfd_size_type) size, abfd) != size)
+ return FALSE;
+ }
+#endif
+
+ return TRUE;
+}
+
+static bfd_boolean
+coff_set_section_contents (bfd * abfd,
+ sec_ptr section,
+ const void * location,
+ file_ptr offset,
+ bfd_size_type count)
+{
+ if (! abfd->output_has_begun) /* 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, section->filepos + offset, SEEK_SET) != 0)
+ return FALSE;
+
+ if (count == 0)
+ return TRUE;
+
+ return bfd_bwrite (location, count, abfd) == count;
+}
+
+static void *
+buy_and_read (bfd *abfd, file_ptr where, bfd_size_type size)
+{
+ void * area = bfd_alloc (abfd, size);
+
+ if (!area)
+ return NULL;
+ if (bfd_seek (abfd, where, SEEK_SET) != 0
+ || bfd_bread (area, size, abfd) != size)
+ return NULL;
+ return area;
+}
+
+/*
+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.
+
+ Note: The PE format uses line number 0 for a flag indicating a
+ new source file.
+
+ 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 int
+coff_sort_func_alent (const void * arg1, const void * arg2)
+{
+ const alent *al1 = *(const alent **) arg1;
+ const alent *al2 = *(const alent **) arg2;
+ const coff_symbol_type *s1 = (const coff_symbol_type *) (al1->u.sym);
+ const coff_symbol_type *s2 = (const coff_symbol_type *) (al2->u.sym);
+
+ if (s1 == NULL || s2 == NULL)
+ return 0;
+ if (s1->symbol.value < s2->symbol.value)
+ return -1;
+ else if (s1->symbol.value > s2->symbol.value)
+ return 1;
+
+ return 0;
+}
+
+static bfd_boolean
+coff_slurp_line_table (bfd *abfd, asection *asect)
+{
+ LINENO *native_lineno;
+ alent *lineno_cache;
+ bfd_size_type amt;
+ unsigned int counter;
+ alent *cache_ptr;
+ bfd_vma prev_offset = 0;
+ bfd_boolean ordered = TRUE;
+ unsigned int nbr_func;
+ LINENO *src;
+ bfd_boolean have_func;
+
+ BFD_ASSERT (asect->lineno == NULL);
+
+ amt = ((bfd_size_type) asect->lineno_count + 1) * sizeof (alent);
+ lineno_cache = (alent *) bfd_alloc (abfd, amt);
+ if (lineno_cache == NULL)
+ return FALSE;
+
+ amt = (bfd_size_type) bfd_coff_linesz (abfd) * asect->lineno_count;
+ native_lineno = (LINENO *) buy_and_read (abfd, asect->line_filepos, amt);
+ if (native_lineno == NULL)
+ {
+ (*_bfd_error_handler)
+ (_("%B: warning: line number table read failed"), abfd);
+ bfd_release (abfd, lineno_cache);
+ return FALSE;
+ }
+
+ cache_ptr = lineno_cache;
+ asect->lineno = lineno_cache;
+ src = native_lineno;
+ nbr_func = 0;
+ have_func = FALSE;
+
+ for (counter = 0; counter < asect->lineno_count; counter++, src++)
+ {
+ struct internal_lineno dst;
+
+ bfd_coff_swap_lineno_in (abfd, src, &dst);
+ cache_ptr->line_number = dst.l_lnno;
+ /* Appease memory checkers that get all excited about
+ uninitialised memory when copying alents if u.offset is
+ larger than u.sym. (64-bit BFD on 32-bit host.) */
+ memset (&cache_ptr->u, 0, sizeof (cache_ptr->u));
+
+ if (cache_ptr->line_number == 0)
+ {
+ combined_entry_type * ent;
+ bfd_vma symndx;
+ coff_symbol_type *sym;
+
+ have_func = FALSE;
+ symndx = dst.l_addr.l_symndx;
+ if (symndx >= obj_raw_syment_count (abfd))
+ {
+ (*_bfd_error_handler)
+ (_("%B: warning: illegal symbol index 0x%lx in line number entry %d"),
+ abfd, (long) symndx, counter);
+ cache_ptr->line_number = -1;
+ continue;
+ }
+
+ ent = obj_raw_syments (abfd) + symndx;
+ /* FIXME: We should not be casting between ints and
+ pointers like this. */
+ if (! ent->is_sym)
+ {
+ (*_bfd_error_handler)
+ (_("%B: warning: illegal symbol index 0x%lx in line number entry %d"),
+ abfd, (long) symndx, counter);
+ cache_ptr->line_number = -1;
+ continue;
+ }
+ sym = (coff_symbol_type *) (ent->u.syment._n._n_n._n_zeroes);
+
+ /* PR 17512 file: 078-10659-0.004 */
+ if (sym < obj_symbols (abfd)
+ || sym >= obj_symbols (abfd) + bfd_get_symcount (abfd))
+ {
+ (*_bfd_error_handler)
+ (_("%B: warning: illegal symbol in line number entry %d"),
+ abfd, counter);
+ cache_ptr->line_number = -1;
+ continue;
+ }
+
+ have_func = TRUE;
+ nbr_func++;
+ cache_ptr->u.sym = (asymbol *) sym;
+ if (sym->lineno != NULL)
+ (*_bfd_error_handler)
+ (_("%B: warning: duplicate line number information for `%s'"),
+ abfd, bfd_asymbol_name (&sym->symbol));
+
+ sym->lineno = cache_ptr;
+ if (sym->symbol.value < prev_offset)
+ ordered = FALSE;
+ prev_offset = sym->symbol.value;
+ }
+ else if (!have_func)
+ /* Drop line information that has no associated function.
+ PR 17521: file: 078-10659-0.004. */
+ continue;
+ else
+ cache_ptr->u.offset = (dst.l_addr.l_paddr
+ - bfd_section_vma (abfd, asect));
+ cache_ptr++;
+ }
+
+ asect->lineno_count = cache_ptr - lineno_cache;
+ memset (cache_ptr, 0, sizeof (*cache_ptr));
+ bfd_release (abfd, native_lineno);
+
+ /* On some systems (eg AIX5.3) the lineno table may not be sorted. */
+ if (!ordered)
+ {
+ /* Sort the table. */
+ alent **func_table;
+ alent *n_lineno_cache;
+
+ /* Create a table of functions. */
+ func_table = (alent **) bfd_alloc (abfd, nbr_func * sizeof (alent *));
+ if (func_table != NULL)
+ {
+ alent **p = func_table;
+ unsigned int i;
+
+ for (i = 0; i < asect->lineno_count; i++)
+ if (lineno_cache[i].line_number == 0)
+ *p++ = &lineno_cache[i];
+
+ BFD_ASSERT ((unsigned int) (p - func_table) == nbr_func);
+
+ /* Sort by functions. */
+ qsort (func_table, nbr_func, sizeof (alent *), coff_sort_func_alent);
+
+ /* Create the new sorted table. */
+ amt = (bfd_size_type) asect->lineno_count * sizeof (alent);
+ n_lineno_cache = (alent *) bfd_alloc (abfd, amt);
+ if (n_lineno_cache != NULL)
+ {
+ alent *n_cache_ptr = n_lineno_cache;
+
+ for (i = 0; i < nbr_func; i++)
+ {
+ coff_symbol_type *sym;
+ alent *old_ptr = func_table[i];
+
+ /* Update the function entry. */
+ sym = (coff_symbol_type *) old_ptr->u.sym;
+ /* PR binutils/17512: Point the lineno to where
+ this entry will be after the memcpy below. */
+ sym->lineno = lineno_cache + (n_cache_ptr - n_lineno_cache);
+ /* Copy the function and line number entries. */
+ do
+ *n_cache_ptr++ = *old_ptr++;
+ while (old_ptr->line_number != 0);
+ }
+ BFD_ASSERT ((bfd_size_type) (n_cache_ptr - n_lineno_cache) == (amt / sizeof (alent)));
+
+ memcpy (lineno_cache, n_lineno_cache, amt);
+ }
+ bfd_release (abfd, func_table);
+ }
+ }
+
+ return TRUE;
+}
+
+/* Slurp in the symbol table, converting it to generic form. Note
+ that if coff_relocate_section is defined, the linker will read
+ symbols via coff_link_add_symbols, rather than via this routine. */
+
+static bfd_boolean
+coff_slurp_symbol_table (bfd * abfd)
+{
+ combined_entry_type *native_symbols;
+ coff_symbol_type *cached_area;
+ unsigned int *table_ptr;
+ bfd_size_type amt;
+ 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;
+
+ /* Allocate enough room for all the symbols in cached form. */
+ amt = obj_raw_syment_count (abfd);
+ amt *= sizeof (coff_symbol_type);
+ cached_area = (coff_symbol_type *) bfd_alloc (abfd, amt);
+ if (cached_area == NULL)
+ return FALSE;
+
+ amt = obj_raw_syment_count (abfd);
+ amt *= sizeof (unsigned int);
+ table_ptr = (unsigned int *) bfd_zalloc (abfd, amt);
+
+ 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;
+ BFD_ASSERT (src->is_sym);
+ 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 = (bfd_hostptr_t) dst;
+ dst->symbol.section = coff_section_from_bfd_index (abfd,
+ src->u.syment.n_scnum);
+ dst->symbol.flags = 0;
+ /* PR 17512: file: 079-7098-0.001:0.1. */
+ dst->symbol.value = 0;
+ dst->done_lineno = FALSE;
+
+ switch (src->u.syment.n_sclass)
+ {
+#ifdef I960
+ case C_LEAFEXT:
+ /* 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
+ /* In PE, 0x68 (104) denotes a section symbol. */
+ case C_SECTION:
+ /* In PE, 0x69 (105) denotes a weak external symbol. */
+ case C_NT_WEAK:
+#endif
+ switch (coff_classify_symbol (abfd, &src->u.syment))
+ {
+ case COFF_SYMBOL_GLOBAL:
+ 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;
+ break;
+
+ case COFF_SYMBOL_COMMON:
+ dst->symbol.section = bfd_com_section_ptr;
+ dst->symbol.value = src->u.syment.n_value;
+ break;
+
+ case COFF_SYMBOL_UNDEFINED:
+ dst->symbol.section = bfd_und_section_ptr;
+ dst->symbol.value = 0;
+ break;
+
+ case COFF_SYMBOL_PE_SECTION:
+ dst->symbol.flags |= BSF_EXPORT | BSF_SECTION_SYM;
+ dst->symbol.value = 0;
+ break;
+
+ case COFF_SYMBOL_LOCAL:
+ 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
+ dst->symbol.value = (src->u.syment.n_value
+ - dst->symbol.section->vma);
+#endif
+ if (ISFCN ((src->u.syment.n_type)))
+ dst->symbol.flags |= BSF_NOT_AT_END | BSF_FUNCTION;
+ break;
+ }
+
+#ifdef RS6000COFF_C
+ /* 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;
+
+ if (src->u.syment.n_sclass == C_SECTION
+ && src->u.syment.n_scnum > 0)
+ dst->symbol.flags = BSF_LOCAL;
+#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
+#ifdef RS6000COFF_C
+ case C_DWARF: /* A label in a dwarf section. */
+ case C_INFO: /* A label in a comment section. */
+#endif
+ case C_LABEL: /* Label. */
+ if (src->u.syment.n_scnum == N_DEBUG)
+ 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. */
+ case C_REGPARM: /* Register parameter. */
+ case C_REG: /* register variable. */
+ /* C_AUTOARG conflicts with TI COFF C_UEXT. */
+#if !defined (TIC80COFF) && !defined (TICOFF)
+#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_TCSYM:
+ case C_BCOMM:
+ case C_ECOML:
+ 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 * bfd_coff_linesz (abfd))
+ > (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)
+ / bfd_coff_linesz (abfd));
+ 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) (intptr_t) (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" (or PE ".lf"). */
+ case C_EFCN: /* Physical end of function. */
+#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;
+ if (strcmp (dst->symbol.name, ".bf") != 0)
+ {
+ /* PE uses funny values for .ef and .lf; don't
+ relocate them. */
+ dst->symbol.flags = BSF_DEBUGGING;
+ }
+ else
+ dst->symbol.flags = BSF_DEBUGGING | BSF_DEBUGGING_RELOC;
+#else
+ /* Base the value as an index from the base of the
+ section. */
+ dst->symbol.flags = BSF_LOCAL;
+ dst->symbol.value = (src->u.syment.n_value
+ - dst->symbol.section->vma);
+#endif
+ break;
+
+ case C_STATLAB: /* Static load time label. */
+ dst->symbol.value = src->u.syment.n_value;
+ dst->symbol.flags = BSF_GLOBAL;
+ break;
+
+ case C_NULL:
+ /* PE DLLs sometimes have zeroed out symbols for some
+ reason. Just ignore them without a warning. */
+ if (src->u.syment.n_type == 0
+ && src->u.syment.n_value == 0
+ && src->u.syment.n_scnum == 0)
+ break;
+#ifdef RS6000COFF_C
+ /* XCOFF specific: deleted entry. */
+ if (src->u.syment.n_value == C_NULL_VALUE)
+ break;
+#endif
+ /* Fall through. */
+ 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 TI COFF. */
+#if defined(TIC80COFF) || defined(TICOFF)
+ case C_UEXT: /* Tentative external definition. */
+#endif
+ case C_EXTLAB: /* External load time label. */
+ case C_HIDDEN: /* Ext symbol in dmert public lib. */
+ default:
+ (*_bfd_error_handler)
+ (_("%B: Unrecognized storage class %d for %s symbol `%s'"),
+ 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;
+ }
+
+ dst->native = src;
+ dst->symbol.udata.i = 0;
+ dst->lineno = NULL;
+
+ this_index += (src->u.syment.n_numaux) + 1;
+ dst++;
+ number_of_symbols++;
+ }
+ }
+
+ 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;
+}
+
+/* Classify a COFF symbol. A couple of targets have globally visible
+ symbols which are not class C_EXT, and this handles those. It also
+ recognizes some special PE cases. */
+
+static enum coff_symbol_classification
+coff_classify_symbol (bfd *abfd,
+ struct internal_syment *syment)
+{
+ /* FIXME: This partially duplicates the switch in
+ coff_slurp_symbol_table. */
+ switch (syment->n_sclass)
+ {
+ case C_EXT:
+ case C_WEAKEXT:
+#ifdef I960
+ case C_LEAFEXT:
+#endif
+#ifdef ARM
+ case C_THUMBEXT:
+ case C_THUMBEXTFUNC:
+#endif
+#ifdef C_SYSTEM
+ case C_SYSTEM:
+#endif
+#ifdef COFF_WITH_PE
+ case C_NT_WEAK:
+#endif
+ if (syment->n_scnum == 0)
+ {
+ if (syment->n_value == 0)
+ return COFF_SYMBOL_UNDEFINED;
+ else
+ return COFF_SYMBOL_COMMON;
+ }
+ return COFF_SYMBOL_GLOBAL;
+
+ default:
+ break;
+ }
+
+#ifdef COFF_WITH_PE
+ if (syment->n_sclass == C_STAT)
+ {
+ if (syment->n_scnum == 0)
+ /* The Microsoft compiler sometimes generates these if a
+ small static function is inlined every time it is used.
+ The function is discarded, but the symbol table entry
+ remains. */
+ return COFF_SYMBOL_LOCAL;
+
+#ifdef STRICT_PE_FORMAT
+ /* This is correct for Microsoft generated objects, but it
+ breaks gas generated objects. */
+ if (syment->n_value == 0)
+ {
+ asection *sec;
+ char * name;
+ char buf[SYMNMLEN + 1];
+
+ name = _bfd_coff_internal_syment_name (abfd, syment, buf)
+ sec = coff_section_from_bfd_index (abfd, syment->n_scnum);
+ if (sec != NULL && name != NULL
+ && (strcmp (bfd_get_section_name (abfd, sec), name) == 0))
+ return COFF_SYMBOL_PE_SECTION;
+ }
+#endif
+
+ return COFF_SYMBOL_LOCAL;
+ }
+
+ if (syment->n_sclass == C_SECTION)
+ {
+ /* In some cases in a DLL generated by the Microsoft linker, the
+ n_value field will contain garbage. FIXME: This should
+ probably be handled by the swapping function instead. */
+ syment->n_value = 0;
+ if (syment->n_scnum == 0)
+ return COFF_SYMBOL_UNDEFINED;
+ return COFF_SYMBOL_PE_SECTION;
+ }
+#endif /* COFF_WITH_PE */
+
+ /* If it is not a global symbol, we presume it is a local symbol. */
+ if (syment->n_scnum == 0)
+ {
+ char buf[SYMNMLEN + 1];
+
+ (*_bfd_error_handler)
+ (_("warning: %B: local symbol `%s' has no section"),
+ abfd, _bfd_coff_internal_syment_name (abfd, syment, buf));
+ }
+
+ return COFF_SYMBOL_LOCAL;
+}
+
+/*
+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 = 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 != NULL \
+ && coffsym->native->is_sym \
+ && coffsym->native->u.syment.n_scnum == 0) \
+ cache_ptr->addend = 0; \
+ else if (ptr && bfd_asymbol_bfd (ptr) == abfd \
+ && ptr->section != NULL) \
+ cache_ptr->addend = - (ptr->section->vma + ptr->value); \
+ else \
+ cache_ptr->addend = 0; \
+ }
+#endif
+
+static bfd_boolean
+coff_slurp_reloc_table (bfd * abfd, sec_ptr asect, asymbol ** symbols)
+{
+ RELOC *native_relocs;
+ arelent *reloc_cache;
+ arelent *cache_ptr;
+ unsigned int idx;
+ bfd_size_type amt;
+
+ 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;
+
+ amt = (bfd_size_type) bfd_coff_relsz (abfd) * asect->reloc_count;
+ native_relocs = (RELOC *) buy_and_read (abfd, asect->rel_filepos, amt);
+ amt = (bfd_size_type) asect->reloc_count * sizeof (arelent);
+ reloc_cache = (arelent *) bfd_alloc (abfd, amt);
+
+ if (reloc_cache == NULL || native_relocs == 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;
+
+ dst.r_offset = 0;
+ 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)
+ (_("%B: warning: illegal symbol index %ld in relocs"),
+ abfd, (long) 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);
+ (void) ptr;
+
+ cache_ptr->address -= asect->vma;
+ /* !! cache_ptr->section = 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)
+ (_("%B: illegal relocation type %d at address 0x%lx"),
+ 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 (bfd *abfd ATTRIBUTE_UNUSED,
+ asection *sec ATTRIBUTE_UNUSED,
+ struct internal_reloc *rel,
+ struct coff_link_hash_entry *h ATTRIBUTE_UNUSED,
+ struct internal_syment *sym ATTRIBUTE_UNUSED,
+ bfd_vma *addendp ATTRIBUTE_UNUSED)
+{
+ arelent genrel;
+
+ genrel.howto = NULL;
+ 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 (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;
+}
+
+#ifndef coff_reloc16_estimate
+#define coff_reloc16_estimate dummy_reloc16_estimate
+
+static int
+dummy_reloc16_estimate (bfd *abfd ATTRIBUTE_UNUSED,
+ asection *input_section ATTRIBUTE_UNUSED,
+ arelent *reloc ATTRIBUTE_UNUSED,
+ unsigned int shrink ATTRIBUTE_UNUSED,
+ struct bfd_link_info *link_info ATTRIBUTE_UNUSED)
+{
+ abort ();
+ return 0;
+}
+
+#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 (bfd *abfd ATTRIBUTE_UNUSED,
+ struct bfd_link_info *link_info ATTRIBUTE_UNUSED,
+ struct bfd_link_order *link_order ATTRIBUTE_UNUSED,
+ arelent *reloc ATTRIBUTE_UNUSED,
+ bfd_byte *data ATTRIBUTE_UNUSED,
+ unsigned int *src_ptr ATTRIBUTE_UNUSED,
+ unsigned int *dst_ptr ATTRIBUTE_UNUSED)
+{
+ 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_just_syms _bfd_generic_link_just_syms
+#define coff_bfd_copy_link_hash_symbol_type \
+ _bfd_generic_copy_link_hash_symbol_type
+#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 bfd_boolean
+coff_link_output_has_begun (bfd * abfd,
+ struct coff_final_link_info * info ATTRIBUTE_UNUSED)
+{
+ return abfd->output_has_begun;
+}
+#endif
+
+#ifndef coff_final_link_postscript
+
+static bfd_boolean
+coff_final_link_postscript (bfd * abfd ATTRIBUTE_UNUSED,
+ struct coff_final_link_info * pfinfo ATTRIBUTE_UNUSED)
+{
+ 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 bfd_coff_backend_data bfd_coff_std_swap_table ATTRIBUTE_UNUSED =
+{
+ 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, FILNMLEN,
+#ifdef COFF_LONG_FILENAMES
+ TRUE,
+#else
+ FALSE,
+#endif
+ COFF_DEFAULT_LONG_SECTION_NAMES,
+ COFF_DEFAULT_SECTION_ALIGNMENT_POWER,
+#ifdef COFF_FORCE_SYMBOLS_IN_STRINGS
+ TRUE,
+#else
+ FALSE,
+#endif
+#ifdef COFF_DEBUG_STRING_WIDE_PREFIX
+ 4,
+#else
+ 2,
+#endif
+ 32768,
+ 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_classify_symbol, 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,
+ bfd_pe_print_pdata
+};
+
+#ifdef TICOFF
+/* COFF0 differs in file/section header size and relocation entry size. */
+
+static bfd_coff_backend_data ticoff0_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_V0, AOUTSZ, SCNHSZ_V01, SYMESZ, AUXESZ, RELSZ_V0, LINESZ, FILNMLEN,
+#ifdef COFF_LONG_FILENAMES
+ TRUE,
+#else
+ FALSE,
+#endif
+ COFF_DEFAULT_LONG_SECTION_NAMES,
+ COFF_DEFAULT_SECTION_ALIGNMENT_POWER,
+#ifdef COFF_FORCE_SYMBOLS_IN_STRINGS
+ TRUE,
+#else
+ FALSE,
+#endif
+#ifdef COFF_DEBUG_STRING_WIDE_PREFIX
+ 4,
+#else
+ 2,
+#endif
+ 32768,
+ coff_SWAP_filehdr_in, coff_SWAP_aouthdr_in, coff_SWAP_scnhdr_in,
+ coff_SWAP_reloc_in, ticoff0_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_classify_symbol, 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,
+ bfd_pe_print_pdata
+};
+#endif
+
+#ifdef TICOFF
+/* COFF1 differs in section header size. */
+
+static bfd_coff_backend_data ticoff1_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_V01, SYMESZ, AUXESZ, RELSZ, LINESZ, FILNMLEN,
+#ifdef COFF_LONG_FILENAMES
+ TRUE,
+#else
+ FALSE,
+#endif
+ COFF_DEFAULT_LONG_SECTION_NAMES,
+ COFF_DEFAULT_SECTION_ALIGNMENT_POWER,
+#ifdef COFF_FORCE_SYMBOLS_IN_STRINGS
+ TRUE,
+#else
+ FALSE,
+#endif
+#ifdef COFF_DEBUG_STRING_WIDE_PREFIX
+ 4,
+#else
+ 2,
+#endif
+ 32768,
+ coff_SWAP_filehdr_in, coff_SWAP_aouthdr_in, coff_SWAP_scnhdr_in,
+ coff_SWAP_reloc_in, ticoff1_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_classify_symbol, 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,
+ bfd_pe_print_pdata /* huh */
+};
+#endif
+
+#ifdef COFF_WITH_PE_BIGOBJ
+/* The UID for bigobj files. */
+
+static const char header_bigobj_classid[16] =
+{
+ 0xC7, 0xA1, 0xBA, 0xD1,
+ 0xEE, 0xBA,
+ 0xa9, 0x4b,
+ 0xAF, 0x20,
+ 0xFA, 0xF6, 0x6A, 0xA4, 0xDC, 0xB8
+};
+
+/* Swap routines. */
+
+static void
+coff_bigobj_swap_filehdr_in (bfd * abfd, void * src, void * dst)
+{
+ struct external_ANON_OBJECT_HEADER_BIGOBJ *filehdr_src =
+ (struct external_ANON_OBJECT_HEADER_BIGOBJ *) src;
+ struct internal_filehdr *filehdr_dst = (struct internal_filehdr *) dst;
+
+ filehdr_dst->f_magic = H_GET_16 (abfd, filehdr_src->Machine);
+ filehdr_dst->f_nscns = H_GET_32 (abfd, filehdr_src->NumberOfSections);
+ filehdr_dst->f_timdat = H_GET_32 (abfd, filehdr_src->TimeDateStamp);
+ filehdr_dst->f_symptr =
+ GET_FILEHDR_SYMPTR (abfd, filehdr_src->PointerToSymbolTable);
+ filehdr_dst->f_nsyms = H_GET_32 (abfd, filehdr_src->NumberOfSymbols);
+ filehdr_dst->f_opthdr = 0;
+ filehdr_dst->f_flags = 0;
+
+ /* Check other magic numbers. */
+ if (H_GET_16 (abfd, filehdr_src->Sig1) != IMAGE_FILE_MACHINE_UNKNOWN
+ || H_GET_16 (abfd, filehdr_src->Sig2) != 0xffff
+ || H_GET_16 (abfd, filehdr_src->Version) != 2
+ || memcmp (filehdr_src->ClassID, header_bigobj_classid, 16) != 0)
+ filehdr_dst->f_opthdr = 0xffff;
+
+ /* Note that CLR metadata are ignored. */
+}
+
+static unsigned int
+coff_bigobj_swap_filehdr_out (bfd *abfd, void * in, void * out)
+{
+ struct internal_filehdr *filehdr_in = (struct internal_filehdr *) in;
+ struct external_ANON_OBJECT_HEADER_BIGOBJ *filehdr_out =
+ (struct external_ANON_OBJECT_HEADER_BIGOBJ *) out;
+
+ memset (filehdr_out, 0, sizeof (*filehdr_out));
+
+ H_PUT_16 (abfd, IMAGE_FILE_MACHINE_UNKNOWN, filehdr_out->Sig1);
+ H_PUT_16 (abfd, 0xffff, filehdr_out->Sig2);
+ H_PUT_16 (abfd, 2, filehdr_out->Version);
+ memcpy (filehdr_out->ClassID, header_bigobj_classid, 16);
+ H_PUT_16 (abfd, filehdr_in->f_magic, filehdr_out->Machine);
+ H_PUT_32 (abfd, filehdr_in->f_nscns, filehdr_out->NumberOfSections);
+ H_PUT_32 (abfd, filehdr_in->f_timdat, filehdr_out->TimeDateStamp);
+ PUT_FILEHDR_SYMPTR (abfd, filehdr_in->f_symptr,
+ filehdr_out->PointerToSymbolTable);
+ H_PUT_32 (abfd, filehdr_in->f_nsyms, filehdr_out->NumberOfSymbols);
+
+ return bfd_coff_filhsz (abfd);
+}
+
+static void
+coff_bigobj_swap_sym_in (bfd * abfd, void * ext1, void * in1)
+{
+ SYMENT_BIGOBJ *ext = (SYMENT_BIGOBJ *) 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 = H_GET_32 (abfd, 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 = H_GET_32 (abfd, ext->e_value);
+ in->n_scnum = H_GET_32 (abfd, ext->e_scnum);
+ in->n_type = H_GET_16 (abfd, ext->e_type);
+ in->n_sclass = H_GET_8 (abfd, ext->e_sclass);
+ in->n_numaux = H_GET_8 (abfd, ext->e_numaux);
+}
+
+static unsigned int
+coff_bigobj_swap_sym_out (bfd * abfd, void * inp, void * extp)
+{
+ struct internal_syment *in = (struct internal_syment *) inp;
+ SYMENT_BIGOBJ *ext = (SYMENT_BIGOBJ *) extp;
+
+ if (in->_n._n_name[0] == 0)
+ {
+ H_PUT_32 (abfd, 0, ext->e.e.e_zeroes);
+ H_PUT_32 (abfd, in->_n._n_n._n_offset, 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
+ }
+
+ H_PUT_32 (abfd, in->n_value, ext->e_value);
+ H_PUT_32 (abfd, in->n_scnum, ext->e_scnum);
+
+ H_PUT_16 (abfd, in->n_type, ext->e_type);
+ H_PUT_8 (abfd, in->n_sclass, ext->e_sclass);
+ H_PUT_8 (abfd, in->n_numaux, ext->e_numaux);
+
+ return SYMESZ_BIGOBJ;
+}
+
+static void
+coff_bigobj_swap_aux_in (bfd *abfd,
+ void * ext1,
+ int type,
+ int in_class,
+ int indx,
+ int numaux,
+ void * in1)
+{
+ AUXENT_BIGOBJ *ext = (AUXENT_BIGOBJ *) ext1;
+ union internal_auxent *in = (union internal_auxent *) in1;
+
+ switch (in_class)
+ {
+ case C_FILE:
+ if (numaux > 1)
+ {
+ if (indx == 0)
+ memcpy (in->x_file.x_fname, ext->File.Name,
+ numaux * sizeof (AUXENT_BIGOBJ));
+ }
+ else
+ memcpy (in->x_file.x_fname, ext->File.Name, sizeof (ext->File.Name));
+ break;
+
+ case C_STAT:
+ case C_LEAFSTAT:
+ case C_HIDDEN:
+ if (type == T_NULL)
+ {
+ in->x_scn.x_scnlen = H_GET_32 (abfd, ext->Section.Length);
+ in->x_scn.x_nreloc =
+ H_GET_16 (abfd, ext->Section.NumberOfRelocations);
+ in->x_scn.x_nlinno =
+ H_GET_16 (abfd, ext->Section.NumberOfLinenumbers);
+ in->x_scn.x_checksum = H_GET_32 (abfd, ext->Section.Checksum);
+ in->x_scn.x_associated = H_GET_16 (abfd, ext->Section.Number)
+ | (H_GET_16 (abfd, ext->Section.HighNumber) << 16);
+ in->x_scn.x_comdat = H_GET_8 (abfd, ext->Section.Selection);
+ return;
+ }
+ break;
+
+ default:
+ in->x_sym.x_tagndx.l = H_GET_32 (abfd, ext->Sym.WeakDefaultSymIndex);
+ /* Characteristics is ignored. */
+ break;
+ }
+}
+
+static unsigned int
+coff_bigobj_swap_aux_out (bfd * abfd,
+ void * inp,
+ int type,
+ int in_class,
+ int indx ATTRIBUTE_UNUSED,
+ int numaux ATTRIBUTE_UNUSED,
+ void * extp)
+{
+ union internal_auxent * in = (union internal_auxent *) inp;
+ AUXENT_BIGOBJ *ext = (AUXENT_BIGOBJ *) extp;
+
+ memset (ext, 0, AUXESZ);
+
+ switch (in_class)
+ {
+ case C_FILE:
+ memcpy (ext->File.Name, in->x_file.x_fname, sizeof (ext->File.Name));
+
+ return AUXESZ;
+
+ case C_STAT:
+ case C_LEAFSTAT:
+ case C_HIDDEN:
+ if (type == T_NULL)
+ {
+ H_PUT_32 (abfd, in->x_scn.x_scnlen, ext->Section.Length);
+ H_PUT_16 (abfd, in->x_scn.x_nreloc,
+ ext->Section.NumberOfRelocations);
+ H_PUT_16 (abfd, in->x_scn.x_nlinno,
+ ext->Section.NumberOfLinenumbers);
+ H_PUT_32 (abfd, in->x_scn.x_checksum, ext->Section.Checksum);
+ H_PUT_16 (abfd, in->x_scn.x_associated & 0xffff,
+ ext->Section.Number);
+ H_PUT_16 (abfd, (in->x_scn.x_associated >> 16),
+ ext->Section.HighNumber);
+ H_PUT_8 (abfd, in->x_scn.x_comdat, ext->Section.Selection);
+ return AUXESZ;
+ }
+ break;
+ }
+
+ H_PUT_32 (abfd, in->x_sym.x_tagndx.l, ext->Sym.WeakDefaultSymIndex);
+ H_PUT_32 (abfd, 1, ext->Sym.WeakSearchType);
+
+ return AUXESZ;
+}
+
+static bfd_coff_backend_data bigobj_swap_table =
+{
+ coff_bigobj_swap_aux_in, coff_bigobj_swap_sym_in, coff_SWAP_lineno_in,
+ coff_bigobj_swap_aux_out, coff_bigobj_swap_sym_out,
+ coff_SWAP_lineno_out, coff_SWAP_reloc_out,
+ coff_bigobj_swap_filehdr_out, coff_SWAP_aouthdr_out,
+ coff_SWAP_scnhdr_out,
+ FILHSZ_BIGOBJ, AOUTSZ, SCNHSZ, SYMESZ_BIGOBJ, AUXESZ_BIGOBJ,
+ RELSZ, LINESZ, FILNMLEN_BIGOBJ,
+ TRUE,
+ COFF_DEFAULT_LONG_SECTION_NAMES,
+ COFF_DEFAULT_SECTION_ALIGNMENT_POWER,
+ FALSE,
+ 2,
+ 1U << 31,
+ coff_bigobj_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_classify_symbol, 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,
+ bfd_pe_print_pdata /* huh */
+};
+
+#endif /* COFF_WITH_PE_BIGOBJ */
+
+#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_header_data
+#define coff_bfd_copy_private_header_data _bfd_generic_bfd_copy_private_header_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_bfd_is_target_special_symbol
+#define coff_bfd_is_target_special_symbol ((bfd_boolean (*) (bfd *, asymbol *)) bfd_false)
+#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_reloc_name_lookup
+#define coff_bfd_reloc_name_lookup _bfd_norelocs_bfd_reloc_name_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
+
+#ifndef coff_bfd_lookup_section_flags
+#define coff_bfd_lookup_section_flags bfd_generic_lookup_section_flags
+#endif
+
+#ifndef coff_bfd_merge_sections
+#define coff_bfd_merge_sections bfd_generic_merge_sections
+#endif
+
+#ifndef coff_bfd_is_group_section
+#define coff_bfd_is_group_section bfd_generic_is_group_section
+#endif
+
+#ifndef coff_bfd_discard_group
+#define coff_bfd_discard_group bfd_generic_discard_group
+#endif
+
+#ifndef coff_section_already_linked
+#define coff_section_already_linked \
+ _bfd_coff_section_already_linked
+#endif
+
+#ifndef coff_bfd_define_common_symbol
+#define coff_bfd_define_common_symbol bfd_generic_define_common_symbol
+#endif
+
+#define CREATE_BIG_COFF_TARGET_VEC(VAR, NAME, EXTRA_O_FLAGS, EXTRA_S_FLAGS, UNDER, ALTERNATIVE, SWAP_TABLE) \
+const bfd_target VAR = \
+{ \
+ NAME , \
+ bfd_target_coff_flavour, \
+ BFD_ENDIAN_BIG, /* Data byte order is big. */ \
+ BFD_ENDIAN_BIG, /* Header byte order is big. */ \
+ /* object flags */ \
+ (HAS_RELOC | EXEC_P | HAS_LINENO | HAS_DEBUG | \
+ HAS_SYMS | HAS_LOCALS | WP_TEXT | EXTRA_O_FLAGS), \
+ /* section flags */ \
+ (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | EXTRA_S_FLAGS),\
+ UNDER, /* Leading symbol underscore. */ \
+ '/', /* AR_pad_char. */ \
+ 15, /* AR_max_namelen. */ \
+ 0, /* match priority. */ \
+ \
+ /* Data conversion functions. */ \
+ bfd_getb64, bfd_getb_signed_64, bfd_putb64, \
+ bfd_getb32, bfd_getb_signed_32, bfd_putb32, \
+ bfd_getb16, bfd_getb_signed_16, bfd_putb16, \
+ \
+ /* Header conversion functions. */ \
+ 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. */ \
+ { _bfd_dummy_target, coff_object_p, bfd_generic_archive_p, \
+ _bfd_dummy_target }, \
+ /* bfd_set_format. */ \
+ { bfd_false, coff_mkobject, _bfd_generic_mkarchive, bfd_false }, \
+ /* bfd_write_contents. */ \
+ { 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), \
+ \
+ ALTERNATIVE, \
+ \
+ SWAP_TABLE \
+};
+
+#define CREATE_BIGHDR_COFF_TARGET_VEC(VAR, NAME, EXTRA_O_FLAGS, EXTRA_S_FLAGS, UNDER, ALTERNATIVE, SWAP_TABLE) \
+const bfd_target VAR = \
+{ \
+ NAME , \
+ bfd_target_coff_flavour, \
+ BFD_ENDIAN_LITTLE, /* Data byte order is little. */ \
+ BFD_ENDIAN_BIG, /* Header byte order is big. */ \
+ /* object flags */ \
+ (HAS_RELOC | EXEC_P | HAS_LINENO | HAS_DEBUG | \
+ HAS_SYMS | HAS_LOCALS | WP_TEXT | EXTRA_O_FLAGS), \
+ /* section flags */ \
+ (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | EXTRA_S_FLAGS),\
+ UNDER, /* Leading symbol underscore. */ \
+ '/', /* AR_pad_char. */ \
+ 15, /* AR_max_namelen. */ \
+ 0, /* match priority. */ \
+ \
+ /* Data conversion functions. */ \
+ bfd_getb64, bfd_getb_signed_64, bfd_putb64, \
+ bfd_getb32, bfd_getb_signed_32, bfd_putb32, \
+ bfd_getb16, bfd_getb_signed_16, bfd_putb16, \
+ \
+ /* Header conversion functions. */ \
+ 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. */ \
+ { _bfd_dummy_target, coff_object_p, bfd_generic_archive_p, \
+ _bfd_dummy_target }, \
+ /* bfd_set_format. */ \
+ { bfd_false, coff_mkobject, _bfd_generic_mkarchive, bfd_false }, \
+ /* bfd_write_contents. */ \
+ { 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), \
+ \
+ ALTERNATIVE, \
+ \
+ SWAP_TABLE \
+};
+
+#define CREATE_LITTLE_COFF_TARGET_VEC(VAR, NAME, EXTRA_O_FLAGS, EXTRA_S_FLAGS, UNDER, ALTERNATIVE, SWAP_TABLE) \
+const bfd_target VAR = \
+{ \
+ NAME , \
+ bfd_target_coff_flavour, \
+ BFD_ENDIAN_LITTLE, /* Data byte order is little. */ \
+ BFD_ENDIAN_LITTLE, /* Header byte order is little. */ \
+ /* object flags */ \
+ (HAS_RELOC | EXEC_P | HAS_LINENO | HAS_DEBUG | \
+ HAS_SYMS | HAS_LOCALS | WP_TEXT | EXTRA_O_FLAGS), \
+ /* section flags */ \
+ (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | EXTRA_S_FLAGS),\
+ UNDER, /* Leading symbol underscore. */ \
+ '/', /* AR_pad_char. */ \
+ 15, /* AR_max_namelen. */ \
+ 0, /* match priority. */ \
+ \
+ /* Data conversion functions. */ \
+ bfd_getl64, bfd_getl_signed_64, bfd_putl64, \
+ bfd_getl32, bfd_getl_signed_32, bfd_putl32, \
+ bfd_getl16, bfd_getl_signed_16, bfd_putl16, \
+ /* Header conversion functions. */ \
+ 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. */ \
+ { _bfd_dummy_target, coff_object_p, bfd_generic_archive_p, \
+ _bfd_dummy_target }, \
+ /* bfd_set_format. */ \
+ { bfd_false, coff_mkobject, _bfd_generic_mkarchive, bfd_false }, \
+ /* bfd_write_contents. */ \
+ { 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), \
+ \
+ ALTERNATIVE, \
+ \
+ SWAP_TABLE \
+};
diff --git a/bfd/coffgen.c b/bfd/coffgen.c
new file mode 100644
index 0000000..a22f67a
--- /dev/null
+++ b/bfd/coffgen.c
@@ -0,0 +1,2681 @@
+/* Support for the generic parts of COFF, for BFD.
+ Copyright (C) 1990-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, 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 "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+#include "coff/internal.h"
+#include "libcoff.h"
+
+/* 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 bfd_boolean
+make_a_section_from_file (bfd *abfd,
+ struct internal_scnhdr *hdr,
+ unsigned int target_index)
+{
+ asection *return_section;
+ char *name;
+ bfd_boolean result = TRUE;
+ flagword flags;
+
+ name = NULL;
+
+ /* Handle long section names as in PE. On reading, we want to
+ accept long names if the format permits them at all, regardless
+ of the current state of the flag that dictates if we would generate
+ them in outputs; this construct checks if that is the case by
+ attempting to set the flag, without changing its state; the call
+ will fail for formats that do not support long names at all. */
+ if (bfd_coff_set_long_section_names (abfd, bfd_coff_long_section_names (abfd))
+ && hdr->s_name[0] == '/')
+ {
+ char buf[SCNNMLEN];
+ long strindex;
+ char *p;
+ const char *strings;
+
+ /* Flag that this BFD uses long names, even though the format might
+ expect them to be off by default. This won't directly affect the
+ format of any output BFD created from this one, but the information
+ can be used to decide what to do. */
+ bfd_coff_set_long_section_names (abfd, TRUE);
+ 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;
+ if ((bfd_size_type)(strindex + 2) >= obj_coff_strings_len (abfd))
+ return FALSE;
+ strings += strindex;
+ name = (char *) bfd_alloc (abfd,
+ (bfd_size_type) strlen (strings) + 1 + 1);
+ if (name == NULL)
+ return FALSE;
+ strcpy (name, strings);
+ }
+ }
+
+ if (name == NULL)
+ {
+ /* Assorted wastage to null-terminate the name, thanks AT&T! */
+ name = (char *) bfd_alloc (abfd,
+ (bfd_size_type) sizeof (hdr->s_name) + 1 + 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->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 = NULL;
+ return_section->target_index = target_index;
+
+ if (! bfd_coff_styp_to_sec_flags_hook (abfd, hdr, name, return_section,
+ & flags))
+ result = FALSE;
+
+ return_section->flags = flags;
+
+ /* 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;
+
+ /* Compress/decompress DWARF debug sections with names: .debug_* and
+ .zdebug_*, after the section flags is set. */
+ if ((flags & SEC_DEBUGGING)
+ && ((name[1] == 'd' && name[6] == '_')
+ || (name[1] == 'z' && name[7] == '_')))
+ {
+ enum { nothing, compress, decompress } action = nothing;
+ char *new_name = NULL;
+
+ if (bfd_is_section_compressed (abfd, return_section))
+ {
+ /* Compressed section. Check if we should decompress. */
+ if ((abfd->flags & BFD_DECOMPRESS))
+ action = decompress;
+ }
+ else if (!bfd_is_section_compressed (abfd, return_section))
+ {
+ /* Normal section. Check if we should compress. */
+ if ((abfd->flags & BFD_COMPRESS) && return_section->size != 0)
+ action = compress;
+ }
+
+ switch (action)
+ {
+ case nothing:
+ break;
+ case compress:
+ if (!bfd_init_section_compress_status (abfd, return_section))
+ {
+ (*_bfd_error_handler)
+ (_("%B: unable to initialize compress status for section %s"),
+ abfd, name);
+ return FALSE;
+ }
+ if (name[1] != 'z')
+ {
+ unsigned int len = strlen (name);
+
+ new_name = bfd_alloc (abfd, len + 2);
+ if (new_name == NULL)
+ return FALSE;
+ new_name[0] = '.';
+ new_name[1] = 'z';
+ memcpy (new_name + 2, name + 1, len);
+ }
+ break;
+ case decompress:
+ if (!bfd_init_section_decompress_status (abfd, return_section))
+ {
+ (*_bfd_error_handler)
+ (_("%B: unable to initialize decompress status for section %s"),
+ abfd, name);
+ return FALSE;
+ }
+ if (name[1] == 'z')
+ {
+ unsigned int len = strlen (name);
+
+ new_name = bfd_alloc (abfd, len);
+ if (new_name == NULL)
+ return FALSE;
+ new_name[0] = '.';
+ memcpy (new_name + 1, name + 2, len - 1);
+ }
+ break;
+ }
+ if (new_name != NULL)
+ bfd_rename_section (abfd, return_section, new_name);
+ }
+
+ return result;
+}
+
+/* Read in a COFF object and make it into a BFD. This is used by
+ ECOFF as well. */
+const bfd_target *
+coff_real_object_p (bfd *,
+ unsigned,
+ struct internal_filehdr *,
+ struct internal_aouthdr *);
+const bfd_target *
+coff_real_object_p (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);
+ void * tdata;
+ void * tdata_save;
+ bfd_size_type 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_save = abfd->tdata.any;
+ tdata = bfd_coff_mkobject_hook (abfd, (void *) internal_f, (void *) internal_a);
+ if (tdata == NULL)
+ goto fail2;
+
+ scnhsz = bfd_coff_scnhsz (abfd);
+ readsize = (bfd_size_type) nscns * scnhsz;
+ external_sections = (char *) bfd_alloc (abfd, readsize);
+ if (!external_sections)
+ goto fail;
+
+ if (bfd_bread ((void *) external_sections, readsize, abfd) != readsize)
+ goto fail;
+
+ /* Set the arch/mach *before* swapping in sections; section header swapping
+ may depend on arch/mach info. */
+ if (! bfd_coff_set_arch_mach_hook (abfd, (void *) internal_f))
+ 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,
+ (void *) (external_sections + i * scnhsz),
+ (void *) & tmp);
+ if (! make_a_section_from_file (abfd, &tmp, i + 1))
+ goto fail;
+ }
+ }
+
+ return abfd->xvec;
+
+ fail:
+ bfd_release (abfd, tdata);
+ fail2:
+ abfd->tdata.any = tdata_save;
+ 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 (bfd *abfd)
+{
+ bfd_size_type filhsz;
+ bfd_size_type aoutsz;
+ unsigned int nscns;
+ void * 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 NULL;
+ if (bfd_bread (filehdr, filhsz, abfd) != filhsz)
+ {
+ if (bfd_get_error () != bfd_error_system_call)
+ bfd_set_error (bfd_error_wrong_format);
+ bfd_release (abfd, filehdr);
+ return NULL;
+ }
+ bfd_coff_swap_filehdr_in (abfd, filehdr, &internal_f);
+ bfd_release (abfd, filehdr);
+
+ /* The XCOFF format has two sizes for the f_opthdr. SMALL_AOUTSZ
+ (less than aoutsz) used in object files and AOUTSZ (equal to
+ aoutsz) in executables. The bfd_coff_swap_aouthdr_in function
+ expects this header to be aoutsz bytes in length, so we use that
+ value in the call to bfd_alloc below. But we must be careful to
+ only read in f_opthdr bytes in the call to bfd_bread. We should
+ also attempt to catch corrupt or non-COFF binaries with a strange
+ value for f_opthdr. */
+ if (! bfd_coff_bad_format_hook (abfd, &internal_f)
+ || internal_f.f_opthdr > aoutsz)
+ {
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+ nscns = internal_f.f_nscns;
+
+ if (internal_f.f_opthdr)
+ {
+ void * opthdr;
+
+ opthdr = bfd_alloc (abfd, aoutsz);
+ if (opthdr == NULL)
+ return NULL;
+ if (bfd_bread (opthdr, (bfd_size_type) internal_f.f_opthdr, abfd)
+ != internal_f.f_opthdr)
+ {
+ bfd_release (abfd, opthdr);
+ return NULL;
+ }
+ bfd_coff_swap_aouthdr_in (abfd, opthdr, (void *) &internal_a);
+ bfd_release (abfd, opthdr);
+ }
+
+ 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 (bfd *abfd, int section_index)
+{
+ struct bfd_section *answer = abfd->sections;
+
+ if (section_index == N_ABS)
+ return bfd_abs_section_ptr;
+ if (section_index == N_UNDEF)
+ return bfd_und_section_ptr;
+ if (section_index == N_DEBUG)
+ return bfd_abs_section_ptr;
+
+ while (answer)
+ {
+ if (answer->target_index == section_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 (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_canonicalize_symtab (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 (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;
+ }
+ if (sym->_n._n_n._n_offset >= obj_coff_strings_len (abfd))
+ 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 (bfd *abfd,
+ asection *sec,
+ bfd_boolean cache,
+ bfd_byte *external_relocs,
+ bfd_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;
+ bfd_size_type amt;
+
+ if (sec->reloc_count == 0)
+ return internal_relocs; /* Nothing to do. */
+
+ 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);
+
+ amt = sec->reloc_count * relsz;
+ if (external_relocs == NULL)
+ {
+ free_external = (bfd_byte *) bfd_malloc (amt);
+ if (free_external == NULL)
+ goto error_return;
+ external_relocs = free_external;
+ }
+
+ if (bfd_seek (abfd, sec->rel_filepos, SEEK_SET) != 0
+ || bfd_bread (external_relocs, amt, abfd) != amt)
+ goto error_return;
+
+ if (internal_relocs == NULL)
+ {
+ amt = sec->reloc_count;
+ amt *= sizeof (struct internal_reloc);
+ free_internal = (struct internal_reloc *) bfd_malloc (amt);
+ if (free_internal == NULL)
+ 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, (void *) erel, (void *) irel);
+
+ if (free_external != NULL)
+ {
+ free (free_external);
+ free_external = NULL;
+ }
+
+ if (cache && free_internal != NULL)
+ {
+ if (coff_section_data (abfd, sec) == NULL)
+ {
+ amt = sizeof (struct coff_section_tdata);
+ sec->used_by_bfd = bfd_zalloc (abfd, amt);
+ 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 (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_family_coff (bfd_asymbol_bfd (q_maybe)))
+ {
+ 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;
+
+ do
+ {
+ asection * sec = q->symbol.section->output_section;
+
+ /* Do not try to update fields in read-only sections. */
+ if (! bfd_is_const_section (sec))
+ sec->lineno_count ++;
+
+ ++total;
+ ++l;
+ }
+ while (l->line_number != 0);
+ }
+ }
+ }
+
+ return total;
+}
+
+/* Takes a bfd and a symbol, returns a pointer to the coff specific
+ area of the symbol if there is one. */
+
+coff_symbol_type *
+coff_symbol_from (bfd *ignore_abfd ATTRIBUTE_UNUSED,
+ asymbol *symbol)
+{
+ if (!bfd_family_coff (bfd_asymbol_bfd (symbol)))
+ 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 (bfd *abfd,
+ coff_symbol_type *coff_symbol_ptr,
+ struct internal_syment *syment)
+{
+ /* Normalize the symbol flags. */
+ if (coff_symbol_ptr->symbol.section
+ && 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) != 0
+ && (coff_symbol_ptr->symbol.flags & BSF_DEBUGGING_RELOC) == 0)
+ {
+ 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;
+ }
+ /* FIXME: Do we need to handle the absolute section here? */
+ 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 += (syment->n_sclass == C_STATLAB)
+ ? coff_symbol_ptr->symbol.section->output_section->lma
+ : 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. */
+
+bfd_boolean
+coff_renumber_symbols (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 = 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;
+ bfd_size_type amt;
+
+ amt = sizeof (asymbol *) * ((bfd_size_type) symbol_count + 1);
+ newsyms = (asymbol **) bfd_alloc (bfd_ptr, amt);
+ 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;
+
+ BFD_ASSERT (s->is_sym);
+ if (s->u.syment.n_sclass == C_FILE)
+ {
+ if (last_file != 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 *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;
+
+ BFD_ASSERT (s->is_sym);
+ if (s->fix_value)
+ {
+ /* FIXME: We should use a union here. */
+ s->u.syment.n_value =
+ (bfd_hostptr_t) ((combined_entry_type *)
+ ((bfd_hostptr_t) 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;
+
+ BFD_ASSERT (! a->is_sym);
+ 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 (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 == NULL)
+ {
+ /* COFF symbols always have names, so we'll make one up. */
+ symbol->name = "strange";
+ name = (char *) symbol->name;
+ }
+ name_length = strlen (name);
+
+ BFD_ASSERT (native->is_sym);
+ if (native->u.syment.n_sclass == C_FILE
+ && native->u.syment.n_numaux > 0)
+ {
+ unsigned int filnmlen;
+
+ if (bfd_coff_force_symnames_in_strings (abfd))
+ {
+ 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 += 6; /* strlen(".file") + 1 */
+ }
+ else
+ strncpy (native->u.syment._n._n_name, ".file", SYMNMLEN);
+
+ BFD_ASSERT (! (native + 1)->is_sym);
+ auxent = &(native + 1)->u.auxent;
+
+ filnmlen = bfd_coff_filnmlen (abfd);
+
+ 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 && !bfd_coff_force_symnames_in_strings (abfd))
+ /* 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
+ {
+ file_ptr filepos;
+ bfd_byte buf[4];
+ int prefix_len = bfd_coff_debug_string_prefix_length (abfd);
+
+ /* 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);
+ if (prefix_len == 4)
+ bfd_put_32 (abfd, (bfd_vma) (name_length + 1), buf);
+ else
+ bfd_put_16 (abfd, (bfd_vma) (name_length + 1), buf);
+
+ if (!bfd_set_section_contents (abfd,
+ *debug_string_section_p,
+ (void *) buf,
+ (file_ptr) *debug_string_size_p,
+ (bfd_size_type) prefix_len)
+ || !bfd_set_section_contents (abfd,
+ *debug_string_section_p,
+ (void *) symbol->name,
+ (file_ptr) (*debug_string_size_p
+ + prefix_len),
+ (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 + prefix_len;
+ native->u.syment._n._n_n._n_zeroes = 0;
+ *debug_string_size_p += name_length + 1 + prefix_len;
+ }
+ }
+}
+
+/* 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 bfd_boolean
+coff_write_symbol (bfd *abfd,
+ asymbol *symbol,
+ combined_entry_type *native,
+ bfd_vma *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 n_sclass = (int) native->u.syment.n_sclass;
+ asection *output_section = symbol->section->output_section
+ ? symbol->section->output_section
+ : symbol->section;
+ void * buf;
+ bfd_size_type symesz;
+
+ BFD_ASSERT (native->is_sym);
+
+ 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 =
+ 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_bwrite (buf, 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_ASSERT (! (native + j + 1)->is_sym);
+ bfd_coff_swap_aux_out (abfd,
+ &((native + j + 1)->u.auxent),
+ type, n_sclass, (int) j,
+ native->u.syment.n_numaux,
+ buf);
+ if (bfd_bwrite (buf, 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. */
+
+bfd_boolean
+coff_write_alien_symbol (bfd *abfd,
+ asymbol *symbol,
+ struct internal_syment *isym,
+ bfd_vma *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[2];
+ asection *output_section = symbol->section->output_section
+ ? symbol->section->output_section
+ : symbol->section;
+ struct bfd_link_info *link_info = coff_data (abfd)->link_info;
+ bfd_boolean ret;
+
+ if ((!link_info || link_info->strip_discarded)
+ && !bfd_is_abs_section (symbol->section)
+ && symbol->section->output_section == bfd_abs_section_ptr)
+ {
+ symbol->name = "";
+ if (isym != NULL)
+ memset (isym, 0, sizeof (*isym));
+ return TRUE;
+ }
+ native = dummy;
+ native->is_sym = TRUE;
+ native[1].is_sym = FALSE;
+ native->u.syment.n_type = T_NULL;
+ native->u.syment.n_flags = 0;
+ native->u.syment.n_numaux = 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_FILE)
+ {
+ native->u.syment.n_scnum = N_DEBUG;
+ native->u.syment.n_numaux = 1;
+ }
+ 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 = "";
+ if (isym != NULL)
+ memset (isym, 0, sizeof (*isym));
+ return TRUE;
+ }
+ else
+ {
+ native->u.syment.n_scnum = output_section->target_index;
+ native->u.syment.n_value = (symbol->value
+ + symbol->section->output_offset);
+ if (! obj_pe (abfd))
+ native->u.syment.n_value += output_section->vma;
+
+ /* Copy the any flags from 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_FILE)
+ native->u.syment.n_sclass = C_FILE;
+ else 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;
+
+ ret = coff_write_symbol (abfd, symbol, native, written, string_size_p,
+ debug_string_section_p, debug_string_size_p);
+ if (isym != NULL)
+ *isym = native->u.syment;
+ return ret;
+}
+
+/* Write a native symbol to a COFF file. */
+
+static bfd_boolean
+coff_write_native_symbol (bfd *abfd,
+ coff_symbol_type *symbol,
+ bfd_vma *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;
+ struct bfd_link_info *link_info = coff_data (abfd)->link_info;
+
+ if ((!link_info || link_info->strip_discarded)
+ && !bfd_is_abs_section (symbol->symbol.section)
+ && symbol->symbol.section->output_section == bfd_abs_section_ptr)
+ {
+ symbol->symbol.name = "";
+ return TRUE;
+ }
+
+ BFD_ASSERT (native->is_sym);
+ /* 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)
+ {
+ lineno[count].u.offset +=
+ (symbol->symbol.section->output_section->vma
+ + symbol->symbol.section->output_offset);
+ count++;
+ }
+ symbol->done_lineno = TRUE;
+
+ if (! bfd_is_const_section (symbol->symbol.section->output_section))
+ 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);
+}
+
+static void
+null_error_handler (const char * fmt ATTRIBUTE_UNUSED, ...)
+{
+}
+
+/* Write out the COFF symbols. */
+
+bfd_boolean
+coff_write_symbols (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);
+ bfd_vma 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, NULL, &written,
+ &string_size, &debug_string_section,
+ &debug_string_size))
+ return FALSE;
+ }
+ else
+ {
+ if (coff_backend_info (abfd)->_bfd_coff_classify_symbol != NULL)
+ {
+ bfd_error_handler_type current_error_handler;
+ enum coff_symbol_classification sym_class;
+ unsigned char *n_sclass;
+
+ /* Suppress error reporting by bfd_coff_classify_symbol.
+ Error messages can be generated when we are processing a local
+ symbol which has no associated section and we do not have to
+ worry about this, all we need to know is that it is local. */
+ current_error_handler = bfd_set_error_handler (null_error_handler);
+ BFD_ASSERT (c_symbol->native->is_sym);
+ sym_class = bfd_coff_classify_symbol (abfd,
+ &c_symbol->native->u.syment);
+ (void) bfd_set_error_handler (current_error_handler);
+
+ n_sclass = &c_symbol->native->u.syment.n_sclass;
+
+ /* If the symbol class has been changed (eg objcopy/ld script/etc)
+ we cannot retain the existing sclass from the original symbol.
+ Weak symbols only have one valid sclass, so just set it always.
+ If it is not local class and should be, set it C_STAT.
+ If it is global and not classified as global, or if it is
+ weak (which is also classified as global), set it C_EXT. */
+
+ if (symbol->flags & BSF_WEAK)
+ *n_sclass = obj_pe (abfd) ? C_NT_WEAK : C_WEAKEXT;
+ else if (symbol->flags & BSF_LOCAL && sym_class != COFF_SYMBOL_LOCAL)
+ *n_sclass = C_STAT;
+ else if (symbol->flags & BSF_GLOBAL
+ && (sym_class != COFF_SYMBOL_GLOBAL
+#ifdef COFF_WITH_PE
+ || *n_sclass == C_NT_WEAK
+#endif
+ || *n_sclass == C_WEAKEXT))
+ c_symbol->native->u.syment.n_sclass = C_EXT;
+ }
+
+ 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
+ H_PUT_32 (abfd, size, buffer);
+#else
+ #error Change H_PUT_32
+#endif
+ if (bfd_bwrite ((void *) buffer, (bfd_size_type) 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_bwrite (o->name, (bfd_size_type) (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 = bfd_coff_force_symnames_in_strings (abfd) ? 0 : SYMNMLEN;
+
+ else if (! c_symbol->native->is_sym)
+ maxlen = bfd_coff_force_symnames_in_strings (abfd) ? 0 : 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)
+ {
+ if (bfd_coff_force_symnames_in_strings (abfd))
+ {
+ if (bfd_bwrite (".file", (bfd_size_type) 6, abfd) != 6)
+ return FALSE;
+ }
+ maxlen = bfd_coff_filnmlen (abfd);
+ }
+ else
+ maxlen = bfd_coff_force_symnames_in_strings (abfd) ? 0 : SYMNMLEN;
+
+ if (name_length > maxlen)
+ {
+ if (bfd_bwrite ((void *) (q->name), (bfd_size_type) 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
+ H_PUT_32 (abfd, size, buffer);
+#else
+ #error Change H_PUT_32
+#endif
+ if (bfd_bwrite ((void *) buffer, (bfd_size_type) 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)
+ == debug_string_section->size)));
+
+ return TRUE;
+}
+
+bfd_boolean
+coff_write_linenumbers (bfd *abfd)
+{
+ asection *s;
+ bfd_size_type linesz;
+ void * 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 ((void *) & 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_bwrite (buff, (bfd_size_type) 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_bwrite (buff, (bfd_size_type) linesz, abfd)
+ != linesz)
+ return FALSE;
+ l++;
+ }
+ }
+ }
+ q++;
+ }
+ }
+ }
+ bfd_release (abfd, buff);
+ return TRUE;
+}
+
+alent *
+coff_get_lineno (bfd *ignore_abfd ATTRIBUTE_UNUSED, asymbol *symbol)
+{
+ return coffsymbol (symbol)->lineno;
+}
+
+/* This function transforms the offsets into the symbol table into
+ pointers to syments. */
+
+static void
+coff_pointerize_aux (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 n_sclass = symbol->u.syment.n_sclass;
+
+ BFD_ASSERT (symbol->is_sym);
+ 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 (n_sclass == C_STAT && type == T_NULL)
+ return;
+ if (n_sclass == C_FILE)
+ return;
+
+ BFD_ASSERT (! auxent->is_sym);
+ /* 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 (n_sclass) || n_sclass == C_BLOCK
+ || n_sclass == 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 (bfd *abfd, asection ** sect_return)
+{
+ char *debug_section;
+ file_ptr position;
+ bfd_size_type sec_size;
+
+ asection *sect = bfd_get_section_by_name (abfd, ".debug");
+
+ if (!sect)
+ {
+ bfd_set_error (bfd_error_no_debug_section);
+ return NULL;
+ }
+
+ sec_size = sect->size;
+ debug_section = (char *) bfd_alloc (abfd, sec_size);
+ 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_bread (debug_section, sec_size, abfd) != sec_size
+ || bfd_seek (abfd, position, SEEK_SET) != 0)
+ return NULL;
+
+ * sect_return = sect;
+ 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 (bfd *abfd, char *name, size_t maxlen)
+{
+ size_t len;
+ char *newname;
+
+ for (len = 0; len < maxlen; ++len)
+ if (name[len] == '\0')
+ break;
+
+ if ((newname = (char *) bfd_alloc (abfd, (bfd_size_type) len + 1)) == NULL)
+ return NULL;
+
+ strncpy (newname, name, len);
+ newname[len] = '\0';
+ return newname;
+}
+
+/* Read in the external symbols. */
+
+bfd_boolean
+_bfd_coff_get_external_symbols (bfd *abfd)
+{
+ bfd_size_type symesz;
+ bfd_size_type size;
+ void * syms;
+
+ if (obj_coff_external_syms (abfd) != NULL)
+ return TRUE;
+
+ symesz = bfd_coff_symesz (abfd);
+
+ size = obj_raw_syment_count (abfd) * symesz;
+ if (size == 0)
+ return TRUE;
+
+ syms = bfd_malloc (size);
+ if (syms == NULL)
+ return FALSE;
+
+ if (bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET) != 0
+ || bfd_bread (syms, size, 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. If the strings
+ are loaded then the STRINGS and STRINGS_LEN fields in the
+ coff_tdata structure will be set. */
+
+const char *
+_bfd_coff_read_string_table (bfd *abfd)
+{
+ char extstrsize[STRING_SIZE_SIZE];
+ bfd_size_type strsize;
+ char *strings;
+ file_ptr pos;
+
+ 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;
+ }
+
+ pos = obj_sym_filepos (abfd);
+ pos += obj_raw_syment_count (abfd) * bfd_coff_symesz (abfd);
+ if (bfd_seek (abfd, pos, SEEK_SET) != 0)
+ return NULL;
+
+ if (bfd_bread (extstrsize, (bfd_size_type) sizeof extstrsize, 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 = H_GET_32 (abfd, extstrsize);
+#else
+ #error Change H_GET_32
+#endif
+ }
+
+ if (strsize < STRING_SIZE_SIZE)
+ {
+ (*_bfd_error_handler)
+ (_("%B: bad string table size %lu"), abfd, (unsigned long) strsize);
+ bfd_set_error (bfd_error_bad_value);
+ return NULL;
+ }
+
+ strings = (char *) bfd_malloc (strsize + 1);
+ /* PR 17521 file: 079-54929-0.004.
+ A corrupt file could contain an index that points into the first
+ STRING_SIZE_SIZE bytes of the string table, so make sure that
+ they are zero. */
+ memset (strings, 0, STRING_SIZE_SIZE);
+
+ if (strings == NULL)
+ return NULL;
+
+ if (bfd_bread (strings + STRING_SIZE_SIZE, strsize - STRING_SIZE_SIZE, abfd)
+ != strsize - STRING_SIZE_SIZE)
+ {
+ free (strings);
+ return NULL;
+ }
+
+ obj_coff_strings (abfd) = strings;
+ obj_coff_strings_len (abfd) = strsize;
+ /* Terminate the string table, just in case. */
+ strings[strsize] = 0;
+ return strings;
+}
+
+/* Free up the external symbols and strings read from a COFF file. */
+
+bfd_boolean
+_bfd_coff_free_symbols (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;
+ obj_coff_strings_len (abfd) = 0;
+ }
+ 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 (bfd *abfd)
+{
+ combined_entry_type *internal;
+ combined_entry_type *internal_ptr;
+ combined_entry_type *symbol_ptr;
+ combined_entry_type *internal_end;
+ size_t symesz;
+ char *raw_src;
+ char *raw_end;
+ const char *string_table = NULL;
+ asection * debug_sec = NULL;
+ char *debug_sec_data = NULL;
+ bfd_size_type size;
+
+ if (obj_raw_syments (abfd) != NULL)
+ return obj_raw_syments (abfd);
+
+ if (! _bfd_coff_get_external_symbols (abfd))
+ return NULL;
+
+ 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);
+
+ 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, (void *) raw_src,
+ (void *) & internal_ptr->u.syment);
+ symbol_ptr = internal_ptr;
+ internal_ptr->is_sym = TRUE;
+
+ for (i = 0;
+ i < symbol_ptr->u.syment.n_numaux;
+ i++)
+ {
+ internal_ptr++;
+ /* PR 17512: Prevent buffer overrun. */
+ if (internal_ptr >= internal_end)
+ return NULL;
+
+ raw_src += symesz;
+ bfd_coff_swap_aux_in (abfd, (void *) raw_src,
+ symbol_ptr->u.syment.n_type,
+ symbol_ptr->u.syment.n_sclass,
+ (int) i, symbol_ptr->u.syment.n_numaux,
+ &(internal_ptr->u.auxent));
+ internal_ptr->is_sym = FALSE;
+ 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++)
+ {
+ BFD_ASSERT (internal_ptr->is_sym);
+
+ if (internal_ptr->u.syment.n_sclass == C_FILE
+ && internal_ptr->u.syment.n_numaux > 0)
+ {
+ combined_entry_type * aux = internal_ptr + 1;
+
+ /* Make a file symbol point to the name in the auxent, since
+ the text ".file" is redundant. */
+ BFD_ASSERT (! aux->is_sym);
+
+ if (aux->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;
+ }
+
+ if ((bfd_size_type)(aux->u.auxent.x_file.x_n.x_offset)
+ >= obj_coff_strings_len (abfd))
+ internal_ptr->u.syment._n._n_n._n_offset = (bfd_hostptr_t) _("<corrupt>");
+ else
+ internal_ptr->u.syment._n._n_n._n_offset =
+ (bfd_hostptr_t) (string_table + (aux->u.auxent.x_file.x_n.x_offset));
+ }
+ else
+ {
+ /* Ordinary short filename, put into memory anyway. The
+ Microsoft PE tools sometimes store a filename in
+ multiple AUX entries. */
+ if (internal_ptr->u.syment.n_numaux > 1
+ && coff_data (abfd)->pe)
+ internal_ptr->u.syment._n._n_n._n_offset =
+ (bfd_hostptr_t)
+ copy_name (abfd,
+ aux->u.auxent.x_file.x_fname,
+ internal_ptr->u.syment.n_numaux * symesz);
+ else
+ internal_ptr->u.syment._n._n_n._n_offset =
+ ((bfd_hostptr_t)
+ copy_name (abfd,
+ aux->u.auxent.x_file.x_fname,
+ (size_t) bfd_coff_filnmlen (abfd)));
+ }
+ }
+ else
+ {
+ if (internal_ptr->u.syment._n._n_n._n_zeroes != 0)
+ {
+ /* This is a "short" name. Make it long. */
+ size_t i;
+ char *newstring;
+
+ /* 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;
+
+ newstring = (char *) bfd_zalloc (abfd, (bfd_size_type) (i + 1));
+ if (newstring == NULL)
+ return NULL;
+ strncpy (newstring, internal_ptr->u.syment._n._n_name, i);
+ internal_ptr->u.syment._n._n_n._n_offset = (bfd_hostptr_t) 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 = (bfd_hostptr_t) "";
+ 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;
+ }
+ if (internal_ptr->u.syment._n._n_n._n_offset >= obj_coff_strings_len (abfd)
+ || string_table + internal_ptr->u.syment._n._n_n._n_offset < string_table)
+ internal_ptr->u.syment._n._n_n._n_offset = (bfd_hostptr_t) _("<corrupt>");
+ else
+ internal_ptr->u.syment._n._n_n._n_offset =
+ ((bfd_hostptr_t)
+ (string_table
+ + internal_ptr->u.syment._n._n_n._n_offset));
+ }
+ else
+ {
+ /* Long name in debug section. Very similar. */
+ if (debug_sec_data == NULL)
+ debug_sec_data = build_debug_section (abfd, & debug_sec);
+ if (debug_sec_data != NULL)
+ {
+ BFD_ASSERT (debug_sec != NULL);
+ /* PR binutils/17512: Catch out of range offsets into the debug data. */
+ if (internal_ptr->u.syment._n._n_n._n_offset > debug_sec->size
+ || debug_sec_data + internal_ptr->u.syment._n._n_n._n_offset < debug_sec_data)
+ internal_ptr->u.syment._n._n_n._n_offset = (bfd_hostptr_t) _("<corrupt>");
+ else
+ internal_ptr->u.syment._n._n_n._n_offset = (bfd_hostptr_t)
+ (debug_sec_data + internal_ptr->u.syment._n._n_n._n_offset);
+ }
+ else
+ internal_ptr->u.syment._n._n_n._n_offset = (bfd_hostptr_t) "";
+ }
+ }
+ 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;
+}
+
+long
+coff_get_reloc_upper_bound (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 (bfd *abfd)
+{
+ bfd_size_type amt = sizeof (coff_symbol_type);
+ coff_symbol_type *new_symbol = (coff_symbol_type *) bfd_zalloc (abfd, amt);
+
+ if (new_symbol == NULL)
+ return NULL;
+ new_symbol->symbol.section = 0;
+ new_symbol->native = NULL;
+ new_symbol->lineno = NULL;
+ new_symbol->done_lineno = FALSE;
+ new_symbol->symbol.the_bfd = abfd;
+
+ return & new_symbol->symbol;
+}
+
+/* Make a debugging symbol. */
+
+asymbol *
+coff_bfd_make_debug_symbol (bfd *abfd,
+ void * ptr ATTRIBUTE_UNUSED,
+ unsigned long sz ATTRIBUTE_UNUSED)
+{
+ bfd_size_type amt = sizeof (coff_symbol_type);
+ coff_symbol_type *new_symbol = (coff_symbol_type *) bfd_alloc (abfd, amt);
+
+ if (new_symbol == NULL)
+ return NULL;
+ /* @@ The 10 is a guess at a plausible maximum number of aux entries
+ (but shouldn't be a constant). */
+ amt = sizeof (combined_entry_type) * 10;
+ new_symbol->native = (combined_entry_type *) bfd_zalloc (abfd, amt);
+ if (!new_symbol->native)
+ return NULL;
+ new_symbol->native->is_sym = TRUE;
+ new_symbol->symbol.section = bfd_abs_section_ptr;
+ new_symbol->symbol.flags = BSF_DEBUGGING;
+ new_symbol->lineno = NULL;
+ new_symbol->done_lineno = FALSE;
+ new_symbol->symbol.the_bfd = abfd;
+
+ return & new_symbol->symbol;
+}
+
+void
+coff_get_symbol_info (bfd *abfd, asymbol *symbol, symbol_info *ret)
+{
+ bfd_symbol_info (symbol, ret);
+
+ if (coffsymbol (symbol)->native != NULL
+ && coffsymbol (symbol)->native->fix_value
+ && coffsymbol (symbol)->native->is_sym)
+ ret->value = coffsymbol (symbol)->native->u.syment.n_value -
+ (bfd_hostptr_t) obj_raw_syments (abfd);
+}
+
+/* Return the COFF syment for a symbol. */
+
+bfd_boolean
+bfd_coff_get_syment (bfd *abfd,
+ asymbol *symbol,
+ struct internal_syment *psyment)
+{
+ coff_symbol_type *csym;
+
+ csym = coff_symbol_from (abfd, symbol);
+ if (csym == NULL || csym->native == NULL
+ || ! csym->native->is_sym)
+ {
+ bfd_set_error (bfd_error_invalid_operation);
+ return FALSE;
+ }
+
+ *psyment = csym->native->u.syment;
+
+ if (csym->native->fix_value)
+ psyment->n_value = psyment->n_value -
+ (bfd_hostptr_t) obj_raw_syments (abfd);
+
+ /* FIXME: We should handle fix_line here. */
+
+ return TRUE;
+}
+
+/* Return the COFF auxent for a symbol. */
+
+bfd_boolean
+bfd_coff_get_auxent (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
+ || ! csym->native->is_sym
+ || indx >= csym->native->u.syment.n_numaux)
+ {
+ bfd_set_error (bfd_error_invalid_operation);
+ return FALSE;
+ }
+
+ ent = csym->native + indx + 1;
+
+ BFD_ASSERT (! ent->is_sym);
+ *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 (bfd *abfd,
+ void * 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)
+ {
+ bfd_vma 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));
+
+ /* PR 17512: file: 079-33786-0.001:0.1. */
+ if (combined < obj_raw_syments (abfd)
+ || combined >= obj_raw_syments (abfd) + obj_raw_syment_count (abfd))
+ {
+ fprintf (file, _("<corrupt info> %s"), symbol->name);
+ break;
+ }
+
+ BFD_ASSERT (combined->is_sym);
+ if (! combined->fix_value)
+ val = (bfd_vma) combined->u.syment.n_value;
+ else
+ val = combined->u.syment.n_value - (bfd_hostptr_t) root;
+
+ fprintf (file, "(sec %2d)(fl 0x%02x)(ty %3x)(scl %3d) (nx %d) 0x",
+ 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);
+ bfd_fprintf_vma (abfd, file, val);
+ fprintf (file, " %s", symbol->name);
+
+ for (aux = 0; aux < combined->u.syment.n_numaux; aux++)
+ {
+ combined_entry_type *auxp = combined + aux + 1;
+ long tagndx;
+
+ BFD_ASSERT (! auxp->is_sym);
+ 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",
+ (unsigned 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;
+ }
+ /* Otherwise fall through. */
+ case C_EXT:
+ case C_AIX_WEAKEXT:
+ if (ISFCN (combined->u.syment.n_type))
+ {
+ long next, llnos;
+
+ if (auxp->fix_end)
+ next = (auxp->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.p
+ - root);
+ else
+ next = auxp->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.l;
+ llnos = auxp->u.auxent.x_sym.x_fcnary.x_fcn.x_lnnoptr;
+ fprintf (file,
+ "AUX tagndx %ld ttlsiz 0x%lx lnnos %ld next %ld",
+ tagndx,
+ (unsigned long) auxp->u.auxent.x_sym.x_misc.x_fsize,
+ llnos, next);
+ break;
+ }
+ /* Otherwise 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)
+ {
+ if (l->line_number > 0)
+ {
+ fprintf (file, "\n%4d : ", l->line_number);
+ bfd_fprintf_vma (abfd, file, l->u.offset + symbol->section->vma);
+ }
+ l++;
+ }
+ }
+ }
+ else
+ {
+ bfd_print_symbol_vandf (abfd, (void *) 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. */
+
+bfd_boolean
+_bfd_coff_is_local_label_name (bfd *abfd ATTRIBUTE_UNUSED,
+ const char *name)
+{
+ return name[0] == '.' && name[1] == 'L';
+}
+
+/* Provided a BFD, a section and an offset (in bytes, not octets) into the
+ section, calculate and return the name of the source file and the line
+ nearest to the wanted location. */
+
+bfd_boolean
+coff_find_nearest_line_with_names (bfd *abfd,
+ asymbol **symbols,
+ asection *section,
+ bfd_vma offset,
+ const char **filename_ptr,
+ const char **functionname_ptr,
+ unsigned int *line_ptr,
+ const struct dwarf_debug_section *debug_sections)
+{
+ bfd_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;
+ bfd_size_type amt;
+
+ /* 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;
+
+ /* Also try examining DWARF2 debugging information. */
+ if (_bfd_dwarf2_find_nearest_line (abfd, symbols, NULL, section, offset,
+ filename_ptr, functionname_ptr,
+ line_ptr, NULL, debug_sections, 0,
+ &coff_data(abfd)->dwarf2_find_line_info))
+ return TRUE;
+
+ *filename_ptr = 0;
+ *functionname_ptr = 0;
+ *line_ptr = 0;
+
+ /* Don't try and find line numbers in a non coff file. */
+ if (!bfd_family_coff (abfd))
+ 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)
+ {
+ BFD_ASSERT (p->is_sym);
+ 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)
+ {
+ bfd_vma file_addr;
+ combined_entry_type *p2;
+
+ for (p2 = p + 1 + p->u.syment.n_numaux;
+ p2 < pend;
+ p2 += 1 + p2->u.syment.n_numaux)
+ {
+ BFD_ASSERT (p2->is_sym);
+ 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)
+ break;
+
+ file_addr = (bfd_vma) p2->u.syment.n_value;
+ /* PR 11512: Include the section address of the function name symbol. */
+ if (p2->u.syment.n_scnum > 0)
+ file_addr += coff_section_from_bfd_index (abfd,
+ p2->u.syment.n_scnum)->vma;
+ /* We use <= MAXDIFF here so that if we get a zero length
+ file, we actually use the next file entry. */
+ if (p2 < pend
+ && offset + sec_vma >= file_addr
+ && offset + sec_vma - file_addr <= 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)
+ {
+ bfd_vma last_value = 0;
+
+ 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;
+ last_value = coff->symbol.value;
+ if (coff->native)
+ {
+ combined_entry_type *s = coff->native;
+
+ BFD_ASSERT (s->is_sym);
+ 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++;
+ }
+
+ /* If we fell off the end of the loop, then assume that this
+ symbol has no line number info. Otherwise, symbols with no
+ line number info get reported with the line number of the
+ last line of the last symbol which does have line number
+ info. We use 0x100 as a slop to account for cases where the
+ last line has executable code. */
+ if (i >= section->lineno_count
+ && last_value != 0
+ && offset - last_value > 0x100)
+ {
+ *functionname_ptr = NULL;
+ *line_ptr = 0;
+ }
+ }
+
+ /* Cache the results for the next call. */
+ if (sec_data == NULL && section->owner == abfd)
+ {
+ amt = sizeof (struct coff_section_tdata);
+ section->used_by_bfd = bfd_zalloc (abfd, amt);
+ sec_data = (struct coff_section_tdata *) section->used_by_bfd;
+ }
+ if (sec_data != NULL)
+ {
+ sec_data->offset = offset;
+ sec_data->i = i - 1;
+ sec_data->function = *functionname_ptr;
+ sec_data->line_base = line_base;
+ }
+
+ return TRUE;
+}
+
+bfd_boolean
+coff_find_nearest_line (bfd *abfd,
+ asymbol **symbols,
+ asection *section,
+ bfd_vma offset,
+ const char **filename_ptr,
+ const char **functionname_ptr,
+ unsigned int *line_ptr,
+ unsigned int *discriminator_ptr)
+{
+ if (discriminator_ptr)
+ *discriminator_ptr = 0;
+ return coff_find_nearest_line_with_names (abfd, symbols, section, offset,
+ filename_ptr, functionname_ptr,
+ line_ptr, dwarf_debug_sections);
+}
+
+bfd_boolean
+coff_find_inliner_info (bfd *abfd,
+ const char **filename_ptr,
+ const char **functionname_ptr,
+ unsigned int *line_ptr)
+{
+ bfd_boolean found;
+
+ found = _bfd_dwarf2_find_inliner_info (abfd, filename_ptr,
+ functionname_ptr, line_ptr,
+ &coff_data(abfd)->dwarf2_find_line_info);
+ return (found);
+}
+
+int
+coff_sizeof_headers (bfd *abfd, struct bfd_link_info *info)
+{
+ size_t size;
+
+ if (!info->relocatable)
+ 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. */
+
+bfd_boolean
+bfd_coff_set_symbol_class (bfd * abfd,
+ asymbol * symbol,
+ unsigned int symbol_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;
+ bfd_size_type amt = sizeof (* native);
+
+ native = (combined_entry_type *) bfd_zalloc (abfd, amt);
+ if (native == NULL)
+ return FALSE;
+
+ native->is_sym = TRUE;
+ native->u.syment.n_type = T_NULL;
+ native->u.syment.n_sclass = symbol_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 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 = symbol_class;
+
+ return TRUE;
+}
+
+struct coff_comdat_info *
+bfd_coff_get_comdat_section (bfd *abfd, struct bfd_section *sec)
+{
+ if (bfd_get_flavour (abfd) == bfd_target_coff_flavour
+ && coff_section_data (abfd, sec) != NULL)
+ return coff_section_data (abfd, sec)->comdat;
+ else
+ return NULL;
+}
+
+bfd_boolean
+_bfd_coff_section_already_linked (bfd *abfd,
+ asection *sec,
+ struct bfd_link_info *info)
+{
+ flagword flags;
+ const char *name, *key;
+ struct bfd_section_already_linked *l;
+ struct bfd_section_already_linked_hash_entry *already_linked_list;
+ struct coff_comdat_info *s_comdat;
+
+ flags = sec->flags;
+ if ((flags & SEC_LINK_ONCE) == 0)
+ return FALSE;
+
+ /* The COFF backend linker doesn't support group sections. */
+ if ((flags & SEC_GROUP) != 0)
+ return FALSE;
+
+ name = bfd_get_section_name (abfd, sec);
+ s_comdat = bfd_coff_get_comdat_section (abfd, sec);
+
+ if (s_comdat != NULL)
+ key = s_comdat->name;
+ else
+ {
+ if (CONST_STRNEQ (name, ".gnu.linkonce.")
+ && (key = strchr (name + sizeof (".gnu.linkonce.") - 1, '.')) != NULL)
+ key++;
+ else
+ /* FIXME: gcc as of 2011-09 emits sections like .text$<key>,
+ .xdata$<key> and .pdata$<key> only the first of which has a
+ comdat key. Should these all match the LTO IR key? */
+ key = name;
+ }
+
+ already_linked_list = bfd_section_already_linked_table_lookup (key);
+
+ for (l = already_linked_list->entry; l != NULL; l = l->next)
+ {
+ struct coff_comdat_info *l_comdat;
+
+ l_comdat = bfd_coff_get_comdat_section (l->sec->owner, l->sec);
+
+ /* The section names must match, and both sections must be
+ comdat and have the same comdat name, or both sections must
+ be non-comdat. LTO IR plugin sections are an exception. They
+ are always named .gnu.linkonce.t.<key> (<key> is some string)
+ and match any comdat section with comdat name of <key>, and
+ any linkonce section with the same suffix, ie.
+ .gnu.linkonce.*.<key>. */
+ if (((s_comdat != NULL) == (l_comdat != NULL)
+ && strcmp (name, l->sec->name) == 0)
+ || (l->sec->owner->flags & BFD_PLUGIN) != 0)
+ {
+ /* The section has already been linked. See if we should
+ issue a warning. */
+ return _bfd_handle_already_linked (sec, l, info);
+ }
+ }
+
+ /* This is the first section with this name. Record it. */
+ if (!bfd_section_already_linked_table_insert (already_linked_list, sec))
+ info->callbacks->einfo (_("%F%P: already_linked_table: %E\n"));
+ return FALSE;
+}
diff --git a/bfd/cofflink.c b/bfd/cofflink.c
new file mode 100644
index 0000000..2782795
--- /dev/null
+++ b/bfd/cofflink.c
@@ -0,0 +1,3119 @@
+/* COFF specific linker code.
+ Copyright (C) 1994-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+/* This file contains the COFF backend linker code. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "bfdlink.h"
+#include "libbfd.h"
+#include "coff/internal.h"
+#include "libcoff.h"
+#include "safe-ctype.h"
+
+static bfd_boolean coff_link_add_object_symbols (bfd *, struct bfd_link_info *);
+static bfd_boolean coff_link_check_archive_element
+ (bfd *, struct bfd_link_info *, struct bfd_link_hash_entry *, const char *,
+ bfd_boolean *);
+static bfd_boolean coff_link_add_symbols (bfd *, struct bfd_link_info *);
+
+/* Return TRUE if SYM is a weak, external symbol. */
+#define IS_WEAK_EXTERNAL(abfd, sym) \
+ ((sym).n_sclass == C_WEAKEXT \
+ || (obj_pe (abfd) && (sym).n_sclass == C_NT_WEAK))
+
+/* Return TRUE if SYM is an external symbol. */
+#define IS_EXTERNAL(abfd, sym) \
+ ((sym).n_sclass == C_EXT || IS_WEAK_EXTERNAL (abfd, sym))
+
+/* Define macros so that the ISFCN, et. al., macros work correctly.
+ These macros are defined in include/coff/internal.h in terms of
+ N_TMASK, etc. These definitions require a user to define local
+ variables with the appropriate names, and with values from the
+ coff_data (abfd) structure. */
+
+#define N_TMASK n_tmask
+#define N_BTSHFT n_btshft
+#define N_BTMASK n_btmask
+
+/* Create an entry in a COFF linker hash table. */
+
+struct bfd_hash_entry *
+_bfd_coff_link_hash_newfunc (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->symbol_class = C_NULL;
+ ret->numaux = 0;
+ ret->auxbfd = NULL;
+ ret->aux = NULL;
+ }
+
+ return (struct bfd_hash_entry *) ret;
+}
+
+/* Initialize a COFF linker hash table. */
+
+bfd_boolean
+_bfd_coff_link_hash_table_init (struct coff_link_hash_table *table,
+ bfd *abfd,
+ struct bfd_hash_entry *(*newfunc) (struct bfd_hash_entry *,
+ struct bfd_hash_table *,
+ const char *),
+ unsigned int entsize)
+{
+ memset (&table->stab_info, 0, sizeof (table->stab_info));
+ return _bfd_link_hash_table_init (&table->root, abfd, newfunc, entsize);
+}
+
+/* Create a COFF linker hash table. */
+
+struct bfd_link_hash_table *
+_bfd_coff_link_hash_table_create (bfd *abfd)
+{
+ struct coff_link_hash_table *ret;
+ bfd_size_type amt = sizeof (struct coff_link_hash_table);
+
+ ret = (struct coff_link_hash_table *) bfd_malloc (amt);
+ if (ret == NULL)
+ return NULL;
+
+ if (! _bfd_coff_link_hash_table_init (ret, abfd,
+ _bfd_coff_link_hash_newfunc,
+ sizeof (struct coff_link_hash_entry)))
+ {
+ free (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 (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. */
+
+bfd_boolean
+_bfd_coff_link_add_symbols (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 bfd_boolean
+coff_link_add_object_symbols (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
+ && ! _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 bfd_boolean
+coff_link_check_archive_element (bfd *abfd,
+ struct bfd_link_info *info,
+ struct bfd_link_hash_entry *h,
+ const char *name,
+ bfd_boolean *pneeded)
+{
+ *pneeded = FALSE;
+
+ /* 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->type != bfd_link_hash_undefined)
+ return TRUE;
+
+ if (!(*info->callbacks->add_archive_element) (info, abfd, name, &abfd))
+ return FALSE;
+ *pneeded = TRUE;
+
+ return coff_link_add_object_symbols (abfd, info);
+}
+
+/* Add all the symbols from an object file to the hash table. */
+
+static bfd_boolean
+coff_link_add_symbols (bfd *abfd,
+ struct bfd_link_info *info)
+{
+ unsigned int n_tmask = coff_data (abfd)->local_n_tmask;
+ unsigned int n_btshft = coff_data (abfd)->local_n_btshft;
+ unsigned int n_btmask = coff_data (abfd)->local_n_btmask;
+ bfd_boolean keep_syms;
+ bfd_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;
+ bfd_size_type amt;
+
+ symcount = obj_raw_syment_count (abfd);
+
+ if (symcount == 0)
+ return TRUE; /* Nothing to do. */
+
+ /* 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;
+
+ if (info->keep_memory)
+ default_copy = FALSE;
+ else
+ default_copy = TRUE;
+
+ /* We keep a list of the linker hash table entries that correspond
+ to particular symbols. */
+ amt = symcount * sizeof (struct coff_link_hash_entry *);
+ sym_hash = (struct coff_link_hash_entry **) bfd_zalloc (abfd, amt);
+ if (sym_hash == NULL)
+ goto error_return;
+ obj_coff_sym_hashes (abfd) = sym_hash;
+
+ 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;
+ enum coff_symbol_classification classification;
+ bfd_boolean copy;
+
+ bfd_coff_swap_sym_in (abfd, esym, &sym);
+
+ classification = bfd_coff_classify_symbol (abfd, &sym);
+ if (classification != COFF_SYMBOL_LOCAL)
+ {
+ const char *name;
+ char buf[SYMNMLEN + 1];
+ flagword flags;
+ asection *section;
+ bfd_vma value;
+ bfd_boolean addit;
+
+ /* 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;
+
+ switch (classification)
+ {
+ default:
+ abort ();
+
+ case COFF_SYMBOL_GLOBAL:
+ flags = BSF_EXPORT | BSF_GLOBAL;
+ section = coff_section_from_bfd_index (abfd, sym.n_scnum);
+ if (! obj_pe (abfd))
+ value -= section->vma;
+ break;
+
+ case COFF_SYMBOL_UNDEFINED:
+ flags = 0;
+ section = bfd_und_section_ptr;
+ break;
+
+ case COFF_SYMBOL_COMMON:
+ flags = BSF_GLOBAL;
+ section = bfd_com_section_ptr;
+ break;
+
+ case COFF_SYMBOL_PE_SECTION:
+ flags = BSF_SECTION_SYM | BSF_GLOBAL;
+ section = coff_section_from_bfd_index (abfd, sym.n_scnum);
+ break;
+ }
+
+ if (IS_WEAK_EXTERNAL (abfd, sym))
+ flags = BSF_WEAK;
+
+ addit = TRUE;
+
+ /* In the PE format, section symbols actually refer to the
+ start of the output section. We handle them specially
+ here. */
+ if (obj_pe (abfd) && (flags & BSF_SECTION_SYM) != 0)
+ {
+ *sym_hash = coff_link_hash_lookup (coff_hash_table (info),
+ name, FALSE, copy, FALSE);
+ if (*sym_hash != NULL)
+ {
+ if (((*sym_hash)->coff_link_hash_flags
+ & COFF_LINK_HASH_PE_SECTION_SYMBOL) == 0
+ && (*sym_hash)->root.type != bfd_link_hash_undefined
+ && (*sym_hash)->root.type != bfd_link_hash_undefweak)
+ (*_bfd_error_handler)
+ ("Warning: symbol `%s' is both section and non-section",
+ name);
+
+ addit = FALSE;
+ }
+ }
+
+ /* The Microsoft Visual C compiler does string pooling by
+ hashing the constants to an internal symbol name, and
+ relying on the linker comdat support to discard
+ duplicate names. However, if one string is a literal and
+ one is a data initializer, one will end up in the .data
+ section and one will end up in the .rdata section. The
+ Microsoft linker will combine them into the .data
+ section, which seems to be wrong since it might cause the
+ literal to change.
+
+ As long as there are no external references to the
+ symbols, which there shouldn't be, we can treat the .data
+ and .rdata instances as separate symbols. The comdat
+ code in the linker will do the appropriate merging. Here
+ we avoid getting a multiple definition error for one of
+ these special symbols.
+
+ FIXME: I don't think this will work in the case where
+ there are two object files which use the constants as a
+ literal and two object files which use it as a data
+ initializer. One or the other of the second object files
+ is going to wind up with an inappropriate reference. */
+ if (obj_pe (abfd)
+ && (classification == COFF_SYMBOL_GLOBAL
+ || classification == COFF_SYMBOL_PE_SECTION)
+ && coff_section_data (abfd, section) != NULL
+ && coff_section_data (abfd, section)->comdat != NULL
+ && CONST_STRNEQ (name, "??_")
+ && strcmp (name, coff_section_data (abfd, section)->comdat->name) == 0)
+ {
+ if (*sym_hash == NULL)
+ *sym_hash = coff_link_hash_lookup (coff_hash_table (info),
+ name, FALSE, copy, FALSE);
+ if (*sym_hash != NULL
+ && (*sym_hash)->root.type == bfd_link_hash_defined
+ && coff_section_data (abfd, (*sym_hash)->root.u.def.section)->comdat != NULL
+ && strcmp (coff_section_data (abfd, (*sym_hash)->root.u.def.section)->comdat->name,
+ coff_section_data (abfd, section)->comdat->name) == 0)
+ addit = FALSE;
+ }
+
+ if (addit)
+ {
+ 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 (obj_pe (abfd) && (flags & BSF_SECTION_SYM) != 0)
+ (*sym_hash)->coff_link_hash_flags |=
+ COFF_LINK_HASH_PE_SECTION_SYMBOL;
+
+ /* Limit the alignment of a common symbol to the possible
+ alignment of a section. There is no point to permitting
+ a higher alignment for a common symbol: we can not
+ guarantee it, and it may cause us to allocate extra space
+ in the common section. */
+ 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 (bfd_get_flavour (info->output_bfd) == bfd_get_flavour (abfd))
+ {
+ /* If we don't have any symbol information currently in
+ the hash table, or if we are looking at a symbol
+ definition, then update the symbol class and type in
+ the hash table. */
+ if (((*sym_hash)->symbol_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)->symbol_class = sym.n_sclass;
+ if (sym.n_type != T_NULL)
+ {
+ /* We want to warn if the type changed, but not
+ if it changed from an unspecified type.
+ Testing the whole type byte may work, but the
+ change from (e.g.) a function of unspecified
+ type to function of known type also wants to
+ skip the warning. */
+ if ((*sym_hash)->type != T_NULL
+ && (*sym_hash)->type != sym.n_type
+ && !(DTYPE ((*sym_hash)->type) == DTYPE (sym.n_type)
+ && (BTYPE ((*sym_hash)->type) == T_NULL
+ || BTYPE (sym.n_type) == T_NULL)))
+ (*_bfd_error_handler)
+ (_("Warning: type of symbol `%s' changed from %d to %d in %B"),
+ abfd, name, (*sym_hash)->type, sym.n_type);
+
+ /* We don't want to change from a meaningful
+ base type to a null one, but if we know
+ nothing, take what little we might now know. */
+ if (BTYPE (sym.n_type) != T_NULL
+ || (*sym_hash)->type == T_NULL)
+ (*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, eaux, sym.n_type,
+ sym.n_sclass, (int) i,
+ sym.n_numaux, iaux);
+ (*sym_hash)->aux = alloc;
+ }
+ }
+ }
+
+ if (classification == COFF_SYMBOL_PE_SECTION
+ && (*sym_hash)->numaux != 0)
+ {
+ /* Some PE sections (such as .bss) have a zero size in
+ the section header, but a non-zero size in the AUX
+ record. Correct that here.
+
+ FIXME: This is not at all the right place to do this.
+ For example, it won't help objdump. This needs to be
+ done when we swap in the section header. */
+ BFD_ASSERT ((*sym_hash)->numaux == 1);
+ if (section->size == 0)
+ section->size = (*sym_hash)->aux[0].x_scn.x_scnlen;
+
+ /* FIXME: We could test whether the section sizes
+ matches the size in the aux entry, but apparently
+ that sometimes fails unexpectedly. */
+ }
+ }
+
+ esym += (sym.n_numaux + 1) * symesz;
+ sym_hash += sym.n_numaux + 1;
+ }
+
+ /* If this is a non-traditional, non-relocatable link, try to
+ optimize the handling of any .stab/.stabstr sections. */
+ if (! info->relocatable
+ && ! info->traditional_format
+ && bfd_get_flavour (info->output_bfd) == bfd_get_flavour (abfd)
+ && (info->strip != strip_all && info->strip != strip_debugger))
+ {
+ asection *stabstr;
+
+ stabstr = bfd_get_section_by_name (abfd, ".stabstr");
+
+ if (stabstr != NULL)
+ {
+ bfd_size_type string_offset = 0;
+ asection *stab;
+
+ for (stab = abfd->sections; stab; stab = stab->next)
+ if (CONST_STRNEQ (stab->name, ".stab")
+ && (!stab->name[5]
+ || (stab->name[5] == '.' && ISDIGIT (stab->name[6]))))
+ {
+ struct coff_link_hash_table *table;
+ struct coff_section_tdata *secdata
+ = coff_section_data (abfd, stab);
+
+ if (secdata == NULL)
+ {
+ amt = sizeof (struct coff_section_tdata);
+ stab->used_by_bfd = bfd_zalloc (abfd, amt);
+ 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,
+ &string_offset))
+ 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. */
+
+bfd_boolean
+_bfd_coff_final_link (bfd *abfd,
+ struct bfd_link_info *info)
+{
+ bfd_size_type symesz;
+ struct coff_final_link_info flaginfo;
+ bfd_boolean debug_merge_allocated;
+ bfd_boolean long_section_names;
+ asection *o;
+ struct bfd_link_order *p;
+ bfd_size_type max_sym_count;
+ bfd_size_type max_lineno_count;
+ bfd_size_type max_reloc_count;
+ bfd_size_type max_output_reloc_count;
+ bfd_size_type 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];
+ bfd_size_type amt;
+
+ symesz = bfd_coff_symesz (abfd);
+
+ flaginfo.info = info;
+ flaginfo.output_bfd = abfd;
+ flaginfo.strtab = NULL;
+ flaginfo.section_info = NULL;
+ flaginfo.last_file_index = -1;
+ flaginfo.last_bf_index = -1;
+ flaginfo.internal_syms = NULL;
+ flaginfo.sec_ptrs = NULL;
+ flaginfo.sym_indices = NULL;
+ flaginfo.outsyms = NULL;
+ flaginfo.linenos = NULL;
+ flaginfo.contents = NULL;
+ flaginfo.external_relocs = NULL;
+ flaginfo.internal_relocs = NULL;
+ flaginfo.global_to_static = FALSE;
+ debug_merge_allocated = FALSE;
+
+ coff_data (abfd)->link_info = info;
+
+ flaginfo.strtab = _bfd_stringtab_init ();
+ if (flaginfo.strtab == NULL)
+ goto error_return;
+
+ if (! coff_debug_merge_hash_table_init (&flaginfo.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->map_head.link_order; 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->relocatable)
+ o->reloc_count += sec->reloc_count;
+
+ if (sec->rawsize > max_contents_size)
+ max_contents_size = sec->rawsize;
+ if (sec->size > max_contents_size)
+ max_contents_size = sec->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->relocatable
+ && (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;
+ /* In PE COFF, if there are at least 0xffff relocations an
+ extra relocation will be written out to encode the count. */
+ if (obj_pe (abfd) && o->reloc_count >= 0xffff)
+ rel_filepos += 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 (flaginfo.strtab, o->name, FALSE, FALSE)
+ == (bfd_size_type) -1)
+ goto error_return;
+ long_section_names = TRUE;
+ }
+ }
+
+ /* If doing a relocatable link, allocate space for the pointers we
+ need to keep. */
+ if (info->relocatable)
+ {
+ unsigned int i;
+
+ /* We use section_count + 1, rather than section_count, because
+ the target_index fields are 1 based. */
+ amt = abfd->section_count + 1;
+ amt *= sizeof (struct coff_link_section_info);
+ flaginfo.section_info = (struct coff_link_section_info *) bfd_malloc (amt);
+ if (flaginfo.section_info == NULL)
+ goto error_return;
+ for (i = 0; i <= abfd->section_count; i++)
+ {
+ flaginfo.section_info[i].relocs = NULL;
+ flaginfo.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 relocatable link, which is not the
+ common case. */
+ BFD_ASSERT (info->relocatable);
+ amt = o->reloc_count;
+ amt *= sizeof (struct internal_reloc);
+ flaginfo.section_info[o->target_index].relocs =
+ (struct internal_reloc *) bfd_malloc (amt);
+ amt = o->reloc_count;
+ amt *= sizeof (struct coff_link_hash_entry *);
+ flaginfo.section_info[o->target_index].rel_hashes =
+ (struct coff_link_hash_entry **) bfd_malloc (amt);
+ if (flaginfo.section_info[o->target_index].relocs == NULL
+ || flaginfo.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 = bfd_family_coff (sub) ? obj_raw_syment_count (sub) : 2;
+ if (sz > max_sym_count)
+ max_sym_count = sz;
+ }
+
+ /* Allocate some buffers used while linking. */
+ amt = max_sym_count * sizeof (struct internal_syment);
+ flaginfo.internal_syms = (struct internal_syment *) bfd_malloc (amt);
+ amt = max_sym_count * sizeof (asection *);
+ flaginfo.sec_ptrs = (asection **) bfd_malloc (amt);
+ amt = max_sym_count * sizeof (long);
+ flaginfo.sym_indices = (long int *) bfd_malloc (amt);
+ flaginfo.outsyms = (bfd_byte *) bfd_malloc ((max_sym_count + 1) * symesz);
+ amt = max_lineno_count * bfd_coff_linesz (abfd);
+ flaginfo.linenos = (bfd_byte *) bfd_malloc (amt);
+ flaginfo.contents = (bfd_byte *) bfd_malloc (max_contents_size);
+ amt = max_reloc_count * relsz;
+ flaginfo.external_relocs = (bfd_byte *) bfd_malloc (amt);
+ if (! info->relocatable)
+ {
+ amt = max_reloc_count * sizeof (struct internal_reloc);
+ flaginfo.internal_relocs = (struct internal_reloc *) bfd_malloc (amt);
+ }
+ if ((flaginfo.internal_syms == NULL && max_sym_count > 0)
+ || (flaginfo.sec_ptrs == NULL && max_sym_count > 0)
+ || (flaginfo.sym_indices == NULL && max_sym_count > 0)
+ || flaginfo.outsyms == NULL
+ || (flaginfo.linenos == NULL && max_lineno_count > 0)
+ || (flaginfo.contents == NULL && max_contents_size > 0)
+ || (flaginfo.external_relocs == NULL && max_reloc_count > 0)
+ || (! info->relocatable
+ && flaginfo.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->map_head.link_order; p != NULL; p = p->next)
+ {
+ if (p->type == bfd_indirect_link_order
+ && bfd_family_coff (p->u.indirect.section->owner))
+ {
+ sub = p->u.indirect.section->owner;
+ if (! bfd_coff_link_output_has_begun (sub, & flaginfo))
+ {
+ if (! _bfd_coff_link_input_bfd (&flaginfo, 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, &flaginfo, o, p))
+ goto error_return;
+ }
+ else
+ {
+ if (! _bfd_default_link_order (abfd, info, o, p))
+ goto error_return;
+ }
+ }
+ }
+
+ if (flaginfo.info->strip != strip_all && flaginfo.info->discard != discard_all)
+ {
+ /* Add local symbols from foreign inputs. */
+ for (sub = info->input_bfds; sub != NULL; sub = sub->link.next)
+ {
+ unsigned int i;
+
+ if (bfd_family_coff (sub) || ! bfd_get_outsymbols (sub))
+ continue;
+ for (i = 0; i < bfd_get_symcount (sub); ++i)
+ {
+ asymbol *sym = bfd_get_outsymbols (sub) [i];
+ file_ptr pos;
+ struct internal_syment isym;
+ bfd_size_type string_size = 0;
+ bfd_vma written = 0;
+ bfd_boolean rewrite = FALSE;
+
+ if (! (sym->flags & BSF_LOCAL)
+ || (sym->flags & (BSF_SECTION_SYM | BSF_DEBUGGING_RELOC
+ | BSF_THREAD_LOCAL | BSF_RELC | BSF_SRELC
+ | BSF_SYNTHETIC))
+ || ((sym->flags & BSF_DEBUGGING)
+ && ! (sym->flags & BSF_FILE)))
+ continue;
+
+ /* See if we are discarding symbols with this name. */
+ if ((flaginfo.info->strip == strip_some
+ && (bfd_hash_lookup (flaginfo.info->keep_hash,
+ bfd_asymbol_name(sym), FALSE, FALSE)
+ == NULL))
+ || (((flaginfo.info->discard == discard_sec_merge
+ && (bfd_get_section (sym)->flags & SEC_MERGE)
+ && ! flaginfo.info->relocatable)
+ || flaginfo.info->discard == discard_l)
+ && bfd_is_local_label_name (sub, bfd_asymbol_name(sym))))
+ continue;
+
+ pos = obj_sym_filepos (abfd) + obj_raw_syment_count (abfd)
+ * symesz;
+ if (bfd_seek (abfd, pos, SEEK_SET) != 0)
+ goto error_return;
+ if (! coff_write_alien_symbol(abfd, sym, &isym, &written,
+ &string_size, NULL, NULL))
+ goto error_return;
+
+ if (string_size)
+ {
+ bfd_boolean hash = ! (abfd->flags & BFD_TRADITIONAL_FORMAT);
+ bfd_size_type indx;
+
+ indx = _bfd_stringtab_add (flaginfo.strtab,
+ bfd_asymbol_name (sym), hash,
+ FALSE);
+ if (indx == (bfd_size_type) -1)
+ goto error_return;
+ isym._n._n_n._n_offset = STRING_SIZE_SIZE + indx;
+ bfd_coff_swap_sym_out (abfd, &isym, flaginfo.outsyms);
+ rewrite = TRUE;
+ }
+
+ if (isym.n_sclass == C_FILE)
+ {
+ if (flaginfo.last_file_index != -1)
+ {
+ flaginfo.last_file.n_value = obj_raw_syment_count (abfd);
+ bfd_coff_swap_sym_out (abfd, &flaginfo.last_file,
+ flaginfo.outsyms);
+ pos = obj_sym_filepos (abfd) + flaginfo.last_file_index
+ * symesz;
+ rewrite = TRUE;
+ }
+ flaginfo.last_file_index = obj_raw_syment_count (abfd);
+ flaginfo.last_file = isym;
+ }
+
+ if (rewrite
+ && (bfd_seek (abfd, pos, SEEK_SET) != 0
+ || bfd_bwrite (flaginfo.outsyms, symesz, abfd) != symesz))
+ goto error_return;
+
+ obj_raw_syment_count (abfd) += written;
+ }
+ }
+ }
+
+ if (! bfd_coff_final_link_postscript (abfd, & flaginfo))
+ goto error_return;
+
+ /* Free up the buffers used by _bfd_coff_link_input_bfd. */
+
+ coff_debug_merge_hash_table_free (&flaginfo.debug_merge);
+ debug_merge_allocated = FALSE;
+
+ if (flaginfo.internal_syms != NULL)
+ {
+ free (flaginfo.internal_syms);
+ flaginfo.internal_syms = NULL;
+ }
+ if (flaginfo.sec_ptrs != NULL)
+ {
+ free (flaginfo.sec_ptrs);
+ flaginfo.sec_ptrs = NULL;
+ }
+ if (flaginfo.sym_indices != NULL)
+ {
+ free (flaginfo.sym_indices);
+ flaginfo.sym_indices = NULL;
+ }
+ if (flaginfo.linenos != NULL)
+ {
+ free (flaginfo.linenos);
+ flaginfo.linenos = NULL;
+ }
+ if (flaginfo.contents != NULL)
+ {
+ free (flaginfo.contents);
+ flaginfo.contents = NULL;
+ }
+ if (flaginfo.external_relocs != NULL)
+ {
+ free (flaginfo.external_relocs);
+ flaginfo.external_relocs = NULL;
+ }
+ if (flaginfo.internal_relocs != NULL)
+ {
+ free (flaginfo.internal_relocs);
+ flaginfo.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 (flaginfo.last_file_index != -1
+ && (unsigned int) flaginfo.last_file.n_value != obj_raw_syment_count (abfd))
+ {
+ file_ptr pos;
+
+ flaginfo.last_file.n_value = obj_raw_syment_count (abfd);
+ bfd_coff_swap_sym_out (abfd, &flaginfo.last_file,
+ flaginfo.outsyms);
+
+ pos = obj_sym_filepos (abfd) + flaginfo.last_file_index * symesz;
+ if (bfd_seek (abfd, pos, SEEK_SET) != 0
+ || bfd_bwrite (flaginfo.outsyms, symesz, 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)
+ {
+ flaginfo.failed = FALSE;
+ coff_link_hash_traverse (coff_hash_table (info),
+ _bfd_coff_write_task_globals, &flaginfo);
+ if (flaginfo.failed)
+ goto error_return;
+ }
+
+ /* Write out the global symbols. */
+ flaginfo.failed = FALSE;
+ bfd_hash_traverse (&info->hash->table, _bfd_coff_write_global_sym, &flaginfo);
+ if (flaginfo.failed)
+ goto error_return;
+
+ /* The outsyms buffer is used by _bfd_coff_write_global_sym. */
+ if (flaginfo.outsyms != NULL)
+ {
+ free (flaginfo.outsyms);
+ flaginfo.outsyms = NULL;
+ }
+
+ if (info->relocatable && 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. */
+ amt = max_output_reloc_count * relsz;
+ external_relocs = (bfd_byte *) bfd_malloc (amt);
+ 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 = flaginfo.section_info[o->target_index].relocs;
+ irelend = irel + o->reloc_count;
+ rel_hash = flaginfo.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, irel, erel);
+ }
+
+ if (bfd_seek (abfd, o->rel_filepos, SEEK_SET) != 0)
+ goto error_return;
+ if (obj_pe (abfd) && o->reloc_count >= 0xffff)
+ {
+ /* In PE COFF, write the count of relocs as the first
+ reloc. The header overflow bit will be set
+ elsewhere. */
+ struct internal_reloc incount;
+ bfd_byte *excount = (bfd_byte *)bfd_malloc (relsz);
+
+ memset (&incount, 0, sizeof (incount));
+ incount.r_vaddr = o->reloc_count + 1;
+ bfd_coff_swap_reloc_out (abfd, &incount, excount);
+ if (bfd_bwrite (excount, relsz, abfd) != relsz)
+ /* We'll leak, but it's an error anyway. */
+ goto error_return;
+ free (excount);
+ }
+ if (bfd_bwrite (external_relocs,
+ (bfd_size_type) relsz * o->reloc_count, abfd)
+ != (bfd_size_type) relsz * o->reloc_count)
+ goto error_return;
+ }
+
+ free (external_relocs);
+ external_relocs = NULL;
+ }
+
+ /* Free up the section information. */
+ if (flaginfo.section_info != NULL)
+ {
+ unsigned int i;
+
+ for (i = 0; i < abfd->section_count; i++)
+ {
+ if (flaginfo.section_info[i].relocs != NULL)
+ free (flaginfo.section_info[i].relocs);
+ if (flaginfo.section_info[i].rel_hashes != NULL)
+ free (flaginfo.section_info[i].rel_hashes);
+ }
+ free (flaginfo.section_info);
+ flaginfo.section_info = NULL;
+ }
+
+ /* If we have optimized stabs strings, output them. */
+ if (coff_hash_table (info)->stab_info.stabstr != 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)
+ {
+ file_ptr pos;
+
+ pos = obj_sym_filepos (abfd) + obj_raw_syment_count (abfd) * symesz;
+ if (bfd_seek (abfd, pos, SEEK_SET) != 0)
+ return FALSE;
+
+#if STRING_SIZE_SIZE == 4
+ H_PUT_32 (abfd,
+ _bfd_stringtab_size (flaginfo.strtab) + STRING_SIZE_SIZE,
+ strbuf);
+#else
+ #error Change H_PUT_32 above
+#endif
+
+ if (bfd_bwrite (strbuf, (bfd_size_type) STRING_SIZE_SIZE, abfd)
+ != STRING_SIZE_SIZE)
+ return FALSE;
+
+ if (! _bfd_stringtab_emit (abfd, flaginfo.strtab))
+ return FALSE;
+
+ obj_coff_strings_written (abfd) = TRUE;
+ }
+
+ _bfd_stringtab_free (flaginfo.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 (&flaginfo.debug_merge);
+ if (flaginfo.strtab != NULL)
+ _bfd_stringtab_free (flaginfo.strtab);
+ if (flaginfo.section_info != NULL)
+ {
+ unsigned int i;
+
+ for (i = 0; i < abfd->section_count; i++)
+ {
+ if (flaginfo.section_info[i].relocs != NULL)
+ free (flaginfo.section_info[i].relocs);
+ if (flaginfo.section_info[i].rel_hashes != NULL)
+ free (flaginfo.section_info[i].rel_hashes);
+ }
+ free (flaginfo.section_info);
+ }
+ if (flaginfo.internal_syms != NULL)
+ free (flaginfo.internal_syms);
+ if (flaginfo.sec_ptrs != NULL)
+ free (flaginfo.sec_ptrs);
+ if (flaginfo.sym_indices != NULL)
+ free (flaginfo.sym_indices);
+ if (flaginfo.outsyms != NULL)
+ free (flaginfo.outsyms);
+ if (flaginfo.linenos != NULL)
+ free (flaginfo.linenos);
+ if (flaginfo.contents != NULL)
+ free (flaginfo.contents);
+ if (flaginfo.external_relocs != NULL)
+ free (flaginfo.external_relocs);
+ if (flaginfo.internal_relocs != NULL)
+ free (flaginfo.internal_relocs);
+ if (external_relocs != NULL)
+ free (external_relocs);
+ return FALSE;
+}
+
+/* Parse out a -heap <reserved>,<commit> line. */
+
+static char *
+dores_com (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] == ',')
+ {
+ 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 (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 (bfd *output_bfd,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ bfd *abfd)
+{
+ asection *sec = bfd_get_section_by_name (abfd, ".drectve");
+ char *s;
+ char *e;
+ bfd_byte *copy;
+
+ if (!sec)
+ return 1;
+
+ if (!bfd_malloc_and_get_section (abfd, sec, &copy))
+ {
+ if (copy != NULL)
+ free (copy);
+ return 0;
+ }
+ e = (char *) copy + sec->size;
+
+ for (s = (char *) copy; s < e ; )
+ {
+ if (s[0] != '-')
+ {
+ s++;
+ continue;
+ }
+ if (CONST_STRNEQ (s, "-attr"))
+ {
+ char *name;
+ char *attribs;
+ asection *asec;
+ int loop = 1;
+ int had_write = 0;
+ int had_exec= 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':
+ break;
+ case 'S':
+ 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 (CONST_STRNEQ (s, "-heap"))
+ s = dores_com (s + 5, output_bfd, 1);
+
+ else if (CONST_STRNEQ (s, "-stack"))
+ s = dores_com (s + 6, output_bfd, 0);
+
+ /* GNU extension for aligned commons. */
+ else if (CONST_STRNEQ (s, "-aligncomm:"))
+ {
+ /* Common symbols must be aligned on reading, as it
+ is too late to do anything here, after they have
+ already been allocated, so just skip the directive. */
+ s += 11;
+ }
+
+ 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 (struct coff_final_link_info *flaginfo, 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
+ || a->linker_mark == 0)
+ continue;
+ /* Don't mark relocs in excluded sections. */
+ if (a->output_section == bfd_abs_section_ptr)
+ continue;
+
+ /* Read in the relocs. */
+ internal_relocs = _bfd_coff_read_internal_relocs
+ (input_bfd, a, FALSE,
+ flaginfo->external_relocs,
+ flaginfo->info->relocatable,
+ (flaginfo->info->relocatable
+ ? (flaginfo->section_info[ a->output_section->target_index ].relocs + a->output_section->reloc_count)
+ : flaginfo->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-skip pass. */
+ for (; irel < irelend; irel++)
+ flaginfo->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. */
+
+bfd_boolean
+_bfd_coff_link_input_bfd (struct coff_final_link_info *flaginfo, bfd *input_bfd)
+{
+ unsigned int n_tmask = coff_data (input_bfd)->local_n_tmask;
+ unsigned int n_btshft = coff_data (input_bfd)->local_n_btshft;
+ bfd_boolean (*adjust_symndx)
+ (bfd *, struct bfd_link_info *, bfd *, asection *,
+ struct internal_reloc *, bfd_boolean *);
+ bfd *output_bfd;
+ const char *strings;
+ bfd_size_type syment_base;
+ bfd_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 = flaginfo->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));
+
+ copy = FALSE;
+ if (! flaginfo->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 = flaginfo->internal_syms;
+ secpp = flaginfo->sec_ptrs;
+ indexp = flaginfo->sym_indices;
+ output_index = syment_base;
+ outsym = flaginfo->outsyms;
+
+ if (coff_data (output_bfd)->pe
+ && ! process_embedded_commands (output_bfd, flaginfo->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 (( flaginfo->info->strip != strip_none
+ || flaginfo->info->discard != discard_none)
+ && flaginfo->info->relocatable)
+ {
+ /* Mark the symbol array as 'not-used'. */
+ memset (indexp, 0, obj_raw_syment_count (input_bfd) * sizeof * indexp);
+
+ mark_relocs (flaginfo, input_bfd);
+ }
+
+ while (esym < esym_end)
+ {
+ struct internal_syment isym;
+ enum coff_symbol_classification classification;
+ bfd_boolean skip;
+ bfd_boolean global;
+ bfd_boolean dont_skip_symbol;
+ int add;
+
+ bfd_coff_swap_sym_in (input_bfd, esym, 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;
+
+ classification = bfd_coff_classify_symbol (input_bfd, &isym);
+ switch (classification)
+ {
+ default:
+ abort ();
+ case COFF_SYMBOL_GLOBAL:
+ case COFF_SYMBOL_PE_SECTION:
+ case COFF_SYMBOL_LOCAL:
+ *secpp = coff_section_from_bfd_index (input_bfd, isym.n_scnum);
+ break;
+ case COFF_SYMBOL_COMMON:
+ *secpp = bfd_com_section_ptr;
+ break;
+ case COFF_SYMBOL_UNDEFINED:
+ *secpp = bfd_und_section_ptr;
+ break;
+ }
+
+ /* Extract the flag indicating if this symbol is used by a
+ relocation. */
+ if ((flaginfo->info->strip != strip_none
+ || flaginfo->info->discard != discard_none)
+ && flaginfo->info->relocatable)
+ 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 (flaginfo->info->strip == strip_all && ! dont_skip_symbol)
+ skip = TRUE;
+
+ if (! skip)
+ {
+ switch (classification)
+ {
+ default:
+ abort ();
+ case COFF_SYMBOL_GLOBAL:
+ case COFF_SYMBOL_COMMON:
+ case COFF_SYMBOL_PE_SECTION:
+ /* 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))
+ skip = TRUE;
+ break;
+
+ case COFF_SYMBOL_UNDEFINED:
+ /* Undefined symbols are left for the end. */
+ global = TRUE;
+ skip = TRUE;
+ break;
+
+ case COFF_SYMBOL_LOCAL:
+ /* This is a local symbol. Skip it if we are discarding
+ local symbols. */
+ if (flaginfo->info->discard == discard_all && ! dont_skip_symbol)
+ skip = TRUE;
+ break;
+ }
+ }
+
+#ifndef COFF_WITH_PE
+ /* Skip section symbols for sections which are not going to be
+ emitted. */
+ if (!skip
+ && !dont_skip_symbol
+ && isym.n_sclass == C_STAT
+ && isym.n_type == T_NULL
+ && isym.n_numaux > 0
+ && ((*secpp)->output_section == bfd_abs_section_ptr
+ || bfd_section_removed_from_list (output_bfd,
+ (*secpp)->output_section)))
+ skip = TRUE;
+#endif
+
+ /* 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
+ && flaginfo->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
+ && (flaginfo->info->strip == strip_some
+ || flaginfo->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
+ && ((flaginfo->info->strip == strip_some
+ && (bfd_hash_lookup (flaginfo->info->keep_hash, name, FALSE,
+ FALSE) == NULL))
+ || (! global
+ && flaginfo->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
+ && (flaginfo->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;
+ bfd_size_type amt;
+
+ 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 (&flaginfo->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. */
+ amt = sizeof (struct coff_debug_merge_type);
+ mt = (struct coff_debug_merge_type *) bfd_alloc (input_bfd, amt);
+ if (mt == NULL)
+ return FALSE;
+ mt->type_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, (esym + isymesz),
+ isym.n_type, isym.n_sclass, 0, isym.n_numaux,
+ &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 *name_copy;
+
+ bfd_coff_swap_sym_in (input_bfd, esl, islp);
+
+ amt = sizeof (struct coff_debug_merge_element);
+ *epp = (struct coff_debug_merge_element *)
+ bfd_alloc (input_bfd, amt);
+ if (*epp == NULL)
+ return FALSE;
+
+ elename = _bfd_coff_internal_syment_name (input_bfd, islp,
+ elebuf);
+ if (elename == NULL)
+ return FALSE;
+
+ amt = strlen (elename) + 1;
+ name_copy = (char *) bfd_alloc (input_bfd, amt);
+ if (name_copy == NULL)
+ return FALSE;
+ strcpy (name_copy, elename);
+
+ (*epp)->name = 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, (esl + isymesz),
+ islp->n_type, islp->n_sclass, 0,
+ islp->n_numaux, &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 = flaginfo->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, 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->type_class != mt->type_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, 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, NULL);
+ if (name == NULL)
+ return FALSE;
+ indx = _bfd_stringtab_add (flaginfo->strtab, name, hash, copy);
+ if (indx == (bfd_size_type) -1)
+ return FALSE;
+ isym._n._n_n._n_offset = STRING_SIZE_SIZE + indx;
+ }
+
+ switch (isym.n_sclass)
+ {
+ case C_AUTO:
+ case C_MOS:
+ case C_EOS:
+ case C_MOE:
+ case C_MOU:
+ case C_UNTAG:
+ case C_STRTAG:
+ case C_ENTAG:
+ case C_TPDEF:
+ case C_ARG:
+ case C_USTATIC:
+ case C_REG:
+ case C_REGPARM:
+ case C_FIELD:
+ /* The symbol value should not be modified. */
+ break;
+
+ case C_FCN:
+ if (obj_pe (input_bfd)
+ && strcmp (isym.n_name, ".bf") != 0
+ && isym.n_scnum > 0)
+ {
+ /* For PE, .lf and .ef get their value left alone,
+ while .bf gets relocated. However, they all have
+ "real" section numbers, and need to be moved into
+ the new section. */
+ isym.n_scnum = (*secpp)->output_section->target_index;
+ break;
+ }
+ /* Fall through. */
+ default:
+ case C_LABEL: /* Not completely sure about these 2 */
+ case C_EXTDEF:
+ case C_BLOCK:
+ case C_EFCN:
+ case C_NULL:
+ case C_EXT:
+ case C_STAT:
+ case C_SECTION:
+ case C_NT_WEAK:
+ /* Compute new symbol location. */
+ 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 (flaginfo->output_bfd))
+ isym.n_value += (*secpp)->output_section->vma;
+ }
+ break;
+
+ case C_FILE:
+ /* 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 (flaginfo->last_file_index != -1
+ && flaginfo->last_file.n_value != (bfd_vma) output_index)
+ {
+ /* We must correct the value of the last C_FILE
+ entry. */
+ flaginfo->last_file.n_value = output_index;
+ if ((bfd_size_type) flaginfo->last_file_index >= syment_base)
+ {
+ /* The last C_FILE symbol is in this input file. */
+ bfd_coff_swap_sym_out (output_bfd,
+ &flaginfo->last_file,
+ (flaginfo->outsyms
+ + ((flaginfo->last_file_index
+ - syment_base)
+ * osymesz)));
+ }
+ else
+ {
+ file_ptr pos;
+
+ /* 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,
+ &flaginfo->last_file, outsym);
+ pos = obj_sym_filepos (output_bfd);
+ pos += flaginfo->last_file_index * osymesz;
+ if (bfd_seek (output_bfd, pos, SEEK_SET) != 0
+ || bfd_bwrite (outsym, osymesz, output_bfd) != osymesz)
+ return FALSE;
+ }
+ }
+
+ flaginfo->last_file_index = output_index;
+ flaginfo->last_file = isym;
+ break;
+ }
+
+ /* If doing task linking, convert normal global function symbols to
+ static functions. */
+ if (flaginfo->info->task_link && IS_EXTERNAL (input_bfd, isym))
+ isym.n_sclass = C_STAT;
+
+ /* Output the symbol. */
+ bfd_coff_swap_sym_out (output_bfd, &isym, 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 = flaginfo->internal_syms;
+ indexp = flaginfo->sym_indices;
+ sym_hash = obj_coff_sym_hashes (input_bfd);
+ outsym = flaginfo->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 == 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 && h->aux != NULL && (h->numaux > i))
+ auxp = h->aux + i;
+ else
+ {
+ bfd_coff_swap_aux_in (input_bfd, esym, isymp->n_type,
+ isymp->n_sclass, i, isymp->n_numaux, &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;
+ }
+ if ((bfd_size_type) auxp->x_file.x_n.x_offset >= obj_coff_strings_len (input_bfd))
+ filename = _("<corrupt>");
+ else
+ filename = strings + auxp->x_file.x_n.x_offset;
+ indx = _bfd_stringtab_add (flaginfo->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)
+ && isymp->n_sclass != C_NT_WEAK)
+ {
+ 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 ((flaginfo->sym_indices[indx] < 0
+ || ((bfd_size_type) flaginfo->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 = flaginfo->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 = flaginfo->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 (flaginfo->last_bf_index != -1)
+ {
+ flaginfo->last_bf.x_sym.x_fcnary.x_fcn.x_endndx.l =
+ *indexp;
+
+ if ((bfd_size_type) flaginfo->last_bf_index
+ >= syment_base)
+ {
+ void *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 = (flaginfo->outsyms
+ + ((flaginfo->last_bf_index
+ - syment_base)
+ * osymesz));
+
+ bfd_coff_swap_aux_out (output_bfd,
+ &flaginfo->last_bf,
+ isymp->n_type,
+ isymp->n_sclass,
+ 0, isymp->n_numaux,
+ auxout);
+ }
+ else
+ {
+ file_ptr pos;
+
+ /* 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,
+ &flaginfo->last_bf,
+ isymp->n_type,
+ isymp->n_sclass,
+ 0, isymp->n_numaux,
+ outsym);
+ pos = obj_sym_filepos (output_bfd);
+ pos += flaginfo->last_bf_index * osymesz;
+ if (bfd_seek (output_bfd, pos, SEEK_SET) != 0
+ || (bfd_bwrite (outsym, osymesz, output_bfd)
+ != osymesz))
+ return FALSE;
+ }
+ }
+
+ if (auxp->x_sym.x_fcnary.x_fcn.x_endndx.l != 0)
+ flaginfo->last_bf_index = -1;
+ else
+ {
+ /* The endndx field of this aux entry must
+ be updated with the symbol number of the
+ next .bf symbol. */
+ flaginfo->last_bf = *auxp;
+ flaginfo->last_bf_index = (((outsym - flaginfo->outsyms)
+ / osymesz)
+ + syment_base);
+ }
+ }
+ }
+
+ if (h == NULL)
+ {
+ bfd_coff_swap_aux_out (output_bfd, auxp, isymp->n_type,
+ isymp->n_sclass, i, isymp->n_numaux,
+ outsym);
+ outsym += osymesz;
+ }
+
+ esym += isymesz;
+ }
+ }
+
+ indexp += add;
+ isymp += add;
+ sym_hash += add;
+ }
+
+ /* Relocate the line numbers, unless we are stripping them. */
+ if (flaginfo->info->strip == strip_none
+ || flaginfo->info->strip == strip_some)
+ {
+ for (o = input_bfd->sections; o != NULL; o = o->next)
+ {
+ bfd_vma offset;
+ bfd_byte *eline;
+ bfd_byte *elineend;
+ bfd_byte *oeline;
+ bfd_boolean skipping;
+ file_ptr pos;
+ bfd_size_type amt;
+
+ /* 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_bread (flaginfo->linenos, linesz * o->lineno_count,
+ input_bfd) != linesz * o->lineno_count)
+ return FALSE;
+
+ offset = o->output_section->vma + o->output_offset - o->vma;
+ eline = flaginfo->linenos;
+ oeline = flaginfo->linenos;
+ elineend = eline + linesz * o->lineno_count;
+ skipping = FALSE;
+ for (; eline < elineend; eline += linesz)
+ {
+ struct internal_lineno iline;
+
+ bfd_coff_swap_lineno_in (input_bfd, eline, &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 = flaginfo->sym_indices[iline.l_addr.l_symndx];
+
+ if (indx < 0)
+ {
+ /* These line numbers are attached to a symbol
+ which we are stripping. We must discard the
+ line numbers because reading them back with
+ no associated symbol (or associating them all
+ with symbol #0) will fail. We can't regain
+ the space in the output file, but at least
+ they're dense. */
+ skipping = TRUE;
+ }
+ 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,
+ (flaginfo->outsyms
+ + ((indx - syment_base)
+ * osymesz)), &is);
+ if ((ISFCN (is.n_type)
+ || is.n_sclass == C_BLOCK)
+ && is.n_numaux >= 1)
+ {
+ void *auxptr;
+
+ auxptr = (flaginfo->outsyms
+ + ((indx - syment_base + 1)
+ * osymesz));
+ bfd_coff_swap_aux_in (output_bfd, auxptr,
+ is.n_type, is.n_sclass,
+ 0, is.n_numaux, &ia);
+ ia.x_sym.x_fcnary.x_fcn.x_lnnoptr =
+ (o->output_section->line_filepos
+ + o->output_section->lineno_count * linesz
+ + eline - flaginfo->linenos);
+ bfd_coff_swap_aux_out (output_bfd, &ia,
+ is.n_type, is.n_sclass, 0,
+ is.n_numaux, auxptr);
+ }
+
+ skipping = FALSE;
+ }
+
+ iline.l_addr.l_symndx = indx;
+ }
+
+ if (!skipping)
+ {
+ bfd_coff_swap_lineno_out (output_bfd, &iline, oeline);
+ oeline += linesz;
+ }
+ }
+
+ pos = o->output_section->line_filepos;
+ pos += o->output_section->lineno_count * linesz;
+ amt = oeline - flaginfo->linenos;
+ if (bfd_seek (output_bfd, pos, SEEK_SET) != 0
+ || bfd_bwrite (flaginfo->linenos, amt, output_bfd) != amt)
+ return FALSE;
+
+ o->output_section->lineno_count += amt / linesz;
+ }
+ }
+
+ /* 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 (flaginfo->last_file_index != -1
+ && (bfd_size_type) flaginfo->last_file_index >= syment_base)
+ {
+ flaginfo->last_file.n_value = output_index;
+ bfd_coff_swap_sym_out (output_bfd, &flaginfo->last_file,
+ (flaginfo->outsyms
+ + ((flaginfo->last_file_index - syment_base)
+ * osymesz)));
+ }
+
+ /* Write the modified symbols to the output file. */
+ if (outsym > flaginfo->outsyms)
+ {
+ file_ptr pos;
+ bfd_size_type amt;
+
+ pos = obj_sym_filepos (output_bfd) + syment_base * osymesz;
+ amt = outsym - flaginfo->outsyms;
+ if (bfd_seek (output_bfd, pos, SEEK_SET) != 0
+ || bfd_bwrite (flaginfo->outsyms, amt, output_bfd) != amt)
+ return FALSE;
+
+ BFD_ASSERT ((obj_raw_syment_count (output_bfd)
+ + (outsym - flaginfo->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_LINKER_CREATED) != 0)
+ continue;
+
+ if ((o->flags & SEC_HAS_CONTENTS) == 0
+ || (o->size == 0 && (o->flags & SEC_RELOC) == 0))
+ {
+ if ((o->flags & SEC_RELOC) != 0
+ && o->reloc_count != 0)
+ {
+ (*_bfd_error_handler)
+ (_("%B: relocs in section `%A', but it has no contents"),
+ 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
+ {
+ contents = flaginfo->contents;
+ if (! bfd_get_full_section_contents (input_bfd, o, &contents))
+ return FALSE;
+ }
+
+ 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, flaginfo->external_relocs,
+ flaginfo->info->relocatable,
+ (flaginfo->info->relocatable
+ ? (flaginfo->section_info[target_index].relocs
+ + o->output_section->reloc_count)
+ : flaginfo->internal_relocs)));
+ if (internal_relocs == NULL
+ && o->reloc_count > 0)
+ return FALSE;
+
+ /* Run through the relocs looking for relocs against symbols
+ coming from discarded sections and complain about them. */
+ irel = internal_relocs;
+ for (; irel < &internal_relocs[o->reloc_count]; irel++)
+ {
+ struct coff_link_hash_entry *h;
+ asection *ps = NULL;
+ long symndx = irel->r_symndx;
+ if (symndx < 0)
+ continue;
+ h = obj_coff_sym_hashes (input_bfd)[symndx];
+ if (h == NULL)
+ continue;
+ while (h->root.type == bfd_link_hash_indirect
+ || h->root.type == bfd_link_hash_warning)
+ h = (struct coff_link_hash_entry *) h->root.u.i.link;
+ if (h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak)
+ ps = h->root.u.def.section;
+ if (ps == NULL)
+ continue;
+ /* Complain if definition comes from an excluded section. */
+ if (ps->flags & SEC_EXCLUDE)
+ (*flaginfo->info->callbacks->einfo)
+ (_("%X`%s' referenced in section `%A' of %B: "
+ "defined in discarded section `%A' of %B\n"),
+ h->root.root.string, o, input_bfd, ps, ps->owner);
+ }
+
+ /* Call processor specific code to relocate the section
+ contents. */
+ if (! bfd_coff_relocate_section (output_bfd, flaginfo->info,
+ input_bfd, o,
+ contents,
+ internal_relocs,
+ flaginfo->internal_syms,
+ flaginfo->sec_ptrs))
+ return FALSE;
+
+ if (flaginfo->info->relocatable)
+ {
+ 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 = (flaginfo->section_info[target_index].rel_hashes
+ + o->output_section->reloc_count);
+ for (; irel < irelend; irel++, rel_hash++)
+ {
+ struct coff_link_hash_entry *h;
+ bfd_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, flaginfo->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 = flaginfo->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 = flaginfo->internal_syms + irel->r_symndx;
+
+ name = (_bfd_coff_internal_syment_name
+ (input_bfd, is, buf));
+ if (name == NULL)
+ return FALSE;
+
+ if (! ((*flaginfo->info->callbacks->unattached_reloc)
+ (flaginfo->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)
+ {
+ file_ptr loc = o->output_offset * bfd_octets_per_byte (output_bfd);
+ if (! bfd_set_section_contents (output_bfd, o->output_section,
+ contents, loc, o->size))
+ return FALSE;
+ }
+ else
+ {
+ if (! (_bfd_write_section_stabs
+ (output_bfd, &coff_hash_table (flaginfo->info)->stab_info,
+ o, &secdata->stab_info, contents)))
+ return FALSE;
+ }
+ }
+
+ if (! flaginfo->info->keep_memory
+ && ! _bfd_coff_free_symbols (input_bfd))
+ return FALSE;
+
+ return TRUE;
+}
+
+/* Write out a global symbol. Called via bfd_hash_traverse. */
+
+bfd_boolean
+_bfd_coff_write_global_sym (struct bfd_hash_entry *bh, void *data)
+{
+ struct coff_link_hash_entry *h = (struct coff_link_hash_entry *) bh;
+ struct coff_final_link_info *flaginfo = (struct coff_final_link_info *) data;
+ bfd *output_bfd;
+ struct internal_syment isym;
+ bfd_size_type symesz;
+ unsigned int i;
+ file_ptr pos;
+
+ output_bfd = flaginfo->output_bfd;
+
+ if (h->root.type == bfd_link_hash_warning)
+ {
+ h = (struct coff_link_hash_entry *) h->root.u.i.link;
+ if (h->root.type == bfd_link_hash_new)
+ return TRUE;
+ }
+
+ if (h->indx >= 0)
+ return TRUE;
+
+ if (h->indx != -2
+ && (flaginfo->info->strip == strip_all
+ || (flaginfo->info->strip == strip_some
+ && (bfd_hash_lookup (flaginfo->info->keep_hash,
+ h->root.root.string, FALSE, FALSE)
+ == NULL))))
+ return TRUE;
+
+ switch (h->root.type)
+ {
+ default:
+ case bfd_link_hash_new:
+ case bfd_link_hash_warning:
+ 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 (flaginfo->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:
+ /* 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
+ {
+ bfd_boolean hash;
+ bfd_size_type indx;
+
+ hash = TRUE;
+ if ((output_bfd->flags & BFD_TRADITIONAL_FORMAT) != 0)
+ hash = FALSE;
+ indx = _bfd_stringtab_add (flaginfo->strtab, h->root.root.string, hash,
+ FALSE);
+ if (indx == (bfd_size_type) -1)
+ {
+ flaginfo->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->symbol_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 (flaginfo->global_to_static)
+ {
+ if (! IS_EXTERNAL (output_bfd, isym))
+ return TRUE;
+
+ isym.n_sclass = C_STAT;
+ }
+
+ /* When a weak symbol is not overridden by a strong one,
+ turn it into an external symbol when not building a
+ shared or relocatable object. */
+ if (! flaginfo->info->shared
+ && ! flaginfo->info->relocatable
+ && IS_WEAK_EXTERNAL (flaginfo->output_bfd, isym))
+ isym.n_sclass = C_EXT;
+
+ isym.n_numaux = h->numaux;
+
+ bfd_coff_swap_sym_out (output_bfd, &isym, flaginfo->outsyms);
+
+ symesz = bfd_coff_symesz (output_bfd);
+
+ pos = obj_sym_filepos (output_bfd);
+ pos += obj_raw_syment_count (output_bfd) * symesz;
+ if (bfd_seek (output_bfd, pos, SEEK_SET) != 0
+ || bfd_bwrite (flaginfo->outsyms, symesz, output_bfd) != symesz)
+ {
+ flaginfo->failed = TRUE;
+ return FALSE;
+ }
+
+ h->indx = obj_raw_syment_count (output_bfd);
+
+ ++obj_raw_syment_count (output_bfd);
+
+ /* Write out any associated aux entries. Most of the aux entries
+ will have been modified in _bfd_coff_link_input_bfd. We have to
+ handle section aux entries here, now that we have the final
+ relocation and line number counts. */
+ for (i = 0; i < isym.n_numaux; i++)
+ {
+ union internal_auxent *auxp;
+
+ auxp = h->aux + i;
+
+ /* Look for a section aux entry here using the same tests that
+ coff_swap_aux_out uses. */
+ if (i == 0
+ && (isym.n_sclass == C_STAT
+ || isym.n_sclass == C_HIDDEN)
+ && isym.n_type == T_NULL
+ && (h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak))
+ {
+ asection *sec;
+
+ sec = h->root.u.def.section->output_section;
+ if (sec != NULL)
+ {
+ auxp->x_scn.x_scnlen = sec->size;
+
+ /* For PE, an overflow on the final link reportedly does
+ not matter. FIXME: Why not? */
+ if (sec->reloc_count > 0xffff
+ && (! obj_pe (output_bfd)
+ || flaginfo->info->relocatable))
+ (*_bfd_error_handler)
+ (_("%s: %s: reloc overflow: 0x%lx > 0xffff"),
+ bfd_get_filename (output_bfd),
+ bfd_get_section_name (output_bfd, sec),
+ sec->reloc_count);
+
+ if (sec->lineno_count > 0xffff
+ && (! obj_pe (output_bfd)
+ || flaginfo->info->relocatable))
+ (*_bfd_error_handler)
+ (_("%s: warning: %s: line number overflow: 0x%lx > 0xffff"),
+ bfd_get_filename (output_bfd),
+ bfd_get_section_name (output_bfd, sec),
+ sec->lineno_count);
+
+ auxp->x_scn.x_nreloc = sec->reloc_count;
+ auxp->x_scn.x_nlinno = sec->lineno_count;
+ auxp->x_scn.x_checksum = 0;
+ auxp->x_scn.x_associated = 0;
+ auxp->x_scn.x_comdat = 0;
+ }
+ }
+
+ bfd_coff_swap_aux_out (output_bfd, auxp, isym.n_type,
+ isym.n_sclass, (int) i, isym.n_numaux,
+ flaginfo->outsyms);
+ if (bfd_bwrite (flaginfo->outsyms, symesz, output_bfd) != symesz)
+ {
+ flaginfo->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. */
+
+bfd_boolean
+_bfd_coff_write_task_globals (struct coff_link_hash_entry *h, void *data)
+{
+ struct coff_final_link_info *flaginfo = (struct coff_final_link_info *) data;
+ bfd_boolean rtnval = TRUE;
+ bfd_boolean save_global_to_static;
+
+ if (h->root.type == bfd_link_hash_warning)
+ h = (struct coff_link_hash_entry *) h->root.u.i.link;
+
+ if (h->indx < 0)
+ {
+ switch (h->root.type)
+ {
+ case bfd_link_hash_defined:
+ case bfd_link_hash_defweak:
+ save_global_to_static = flaginfo->global_to_static;
+ flaginfo->global_to_static = TRUE;
+ rtnval = _bfd_coff_write_global_sym (&h->root.root, data);
+ flaginfo->global_to_static = save_global_to_static;
+ break;
+ default:
+ break;
+ }
+ }
+ return (rtnval);
+}
+
+/* Handle a link order which is supposed to generate a reloc. */
+
+bfd_boolean
+_bfd_coff_reloc_link_order (bfd *output_bfd,
+ struct coff_final_link_info *flaginfo,
+ 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;
+ bfd_boolean ok;
+ file_ptr loc;
+
+ size = bfd_get_reloc_size (howto);
+ buf = (bfd_byte *) bfd_zmalloc (size);
+ if (buf == NULL)
+ return FALSE;
+
+ rstat = _bfd_relocate_contents (howto, output_bfd,
+ (bfd_vma) 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 (! ((*flaginfo->info->callbacks->reloc_overflow)
+ (flaginfo->info, NULL,
+ (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;
+ }
+ loc = link_order->offset * bfd_octets_per_byte (output_bfd);
+ ok = bfd_set_section_contents (output_bfd, output_section, buf,
+ loc, 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 = (flaginfo->section_info[output_section->target_index].relocs
+ + output_section->reloc_count);
+ rel_hash_ptr = (flaginfo->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, flaginfo->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 (! ((*flaginfo->info->callbacks->unattached_reloc)
+ (flaginfo->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. */
+
+bfd_boolean
+_bfd_coff_generic_relocate_section (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 if (symndx < 0
+ || (unsigned long) symndx >= obj_raw_syment_count (input_bfd))
+ {
+ (*_bfd_error_handler)
+ ("%B: illegal symbol index %ld in relocs", input_bfd, symndx);
+ return FALSE;
+ }
+ 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 relocatable 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 relocatable link,
+ then we should ignore the symbol value. */
+ if (howto->pc_relative && howto->pcrel_offset)
+ {
+ if (info->relocatable)
+ 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];
+
+ /* If the output section has been discarded then ignore this reloc. */
+ if (sec->output_section->vma == 0)
+ continue;
+
+ 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)
+ {
+ /* Defined weak symbols are a GNU extension. */
+ 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_undefweak)
+ {
+ if (h->symbol_class == C_NT_WEAK && h->numaux == 1)
+ {
+ /* See _Microsoft Portable Executable and Common Object
+ File Format Specification_, section 5.5.3.
+ Note that weak symbols without aux records are a GNU
+ extension.
+ FIXME: All weak externals are treated as having
+ characteristic IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY (1).
+ These behave as per SVR4 ABI: A library member
+ will resolve a weak external only if a normal
+ external causes the library member to be linked.
+ See also linker.c: generic_link_check_archive_element. */
+ asection *sec;
+ struct coff_link_hash_entry *h2 =
+ h->auxbfd->tdata.coff_obj_data->sym_hashes[
+ h->aux->x_sym.x_tagndx.l];
+
+ if (!h2 || h2->root.type == bfd_link_hash_undefined)
+ {
+ sec = bfd_abs_section_ptr;
+ val = 0;
+ }
+ else
+ {
+ sec = h2->root.u.def.section;
+ val = h2->root.u.def.value
+ + sec->output_section->vma + sec->output_offset;
+ }
+ }
+ else
+ /* This is a GNU extension. */
+ val = 0;
+ }
+
+ else if (! info->relocatable)
+ {
+ if (! ((*info->callbacks->undefined_symbol)
+ (info, h->root.root.string, input_bfd, input_section,
+ rel->r_vaddr - input_section->vma, TRUE)))
+ 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 bfd_vma here,
+ and dlltool reads in a bfd_vma. */
+ 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;
+ if (fwrite (&addr, 1, sizeof (bfd_vma), (FILE *) info->base_file)
+ != sizeof (bfd_vma))
+ {
+ 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)
+ (_("%B: bad reloc address 0x%lx in section `%A'"),
+ input_bfd, input_section, (unsigned long) rel->r_vaddr);
+ return FALSE;
+ case bfd_reloc_overflow:
+ {
+ const char *name;
+ char buf[SYMNMLEN + 1];
+
+ if (symndx == -1)
+ name = "*ABS*";
+ else if (h != NULL)
+ name = NULL;
+ else
+ {
+ name = _bfd_coff_internal_syment_name (input_bfd, sym, buf);
+ if (name == NULL)
+ return FALSE;
+ }
+
+ if (! ((*info->callbacks->reloc_overflow)
+ (info, (h ? &h->root : NULL), 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 0000000..c62be2e
--- /dev/null
+++ b/bfd/coffswap.h
@@ -0,0 +1,840 @@
+/* Generic COFF swapping routines, for BFD.
+ Copyright (C) 1990-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, 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 GET_FCN_LNNOPTR
+#define GET_FCN_LNNOPTR(abfd, ext) \
+ H_GET_32 (abfd, ext->x_sym.x_fcnary.x_fcn.x_lnnoptr)
+#endif
+
+#ifndef GET_FCN_ENDNDX
+#define GET_FCN_ENDNDX(abfd, ext) \
+ H_GET_32 (abfd, ext->x_sym.x_fcnary.x_fcn.x_endndx)
+#endif
+
+#ifndef PUT_FCN_LNNOPTR
+#define PUT_FCN_LNNOPTR(abfd, in, ext) \
+ H_PUT_32 (abfd, in, ext->x_sym.x_fcnary.x_fcn.x_lnnoptr)
+#endif
+#ifndef PUT_FCN_ENDNDX
+#define PUT_FCN_ENDNDX(abfd, in, ext) \
+ H_PUT_32 (abfd, in, ext->x_sym.x_fcnary.x_fcn.x_endndx)
+#endif
+#ifndef GET_LNSZ_LNNO
+#define GET_LNSZ_LNNO(abfd, ext) \
+ H_GET_16 (abfd, ext->x_sym.x_misc.x_lnsz.x_lnno)
+#endif
+#ifndef GET_LNSZ_SIZE
+#define GET_LNSZ_SIZE(abfd, ext) \
+ H_GET_16 (abfd, ext->x_sym.x_misc.x_lnsz.x_size)
+#endif
+#ifndef PUT_LNSZ_LNNO
+#define PUT_LNSZ_LNNO(abfd, in, ext) \
+ H_PUT_16 (abfd, in, ext->x_sym.x_misc.x_lnsz.x_lnno)
+#endif
+#ifndef PUT_LNSZ_SIZE
+#define PUT_LNSZ_SIZE(abfd, in, ext) \
+ H_PUT_16 (abfd, in, ext->x_sym.x_misc.x_lnsz.x_size)
+#endif
+#ifndef GET_SCN_SCNLEN
+#define GET_SCN_SCNLEN(abfd, ext) \
+ H_GET_32 (abfd, ext->x_scn.x_scnlen)
+#endif
+#ifndef GET_SCN_NRELOC
+#define GET_SCN_NRELOC(abfd, ext) \
+ H_GET_16 (abfd, ext->x_scn.x_nreloc)
+#endif
+#ifndef GET_SCN_NLINNO
+#define GET_SCN_NLINNO(abfd, ext) \
+ H_GET_16 (abfd, ext->x_scn.x_nlinno)
+#endif
+#ifndef PUT_SCN_SCNLEN
+#define PUT_SCN_SCNLEN(abfd, in, ext) \
+ H_PUT_32 (abfd, in, ext->x_scn.x_scnlen)
+#endif
+#ifndef PUT_SCN_NRELOC
+#define PUT_SCN_NRELOC(abfd, in, ext) \
+ H_PUT_16 (abfd, in, ext->x_scn.x_nreloc)
+#endif
+#ifndef PUT_SCN_NLINNO
+#define PUT_SCN_NLINNO(abfd, in, ext) \
+ H_PUT_16 (abfd, in, ext->x_scn.x_nlinno)
+#endif
+#ifndef GET_LINENO_LNNO
+#define GET_LINENO_LNNO(abfd, ext) \
+ H_GET_16 (abfd, ext->l_lnno);
+#endif
+#ifndef PUT_LINENO_LNNO
+#define PUT_LINENO_LNNO(abfd, val, ext) \
+ H_PUT_16 (abfd, val, ext->l_lnno);
+#endif
+
+/* The f_symptr field in the filehdr is sometimes 64 bits. */
+#ifndef GET_FILEHDR_SYMPTR
+#define GET_FILEHDR_SYMPTR H_GET_32
+#endif
+#ifndef PUT_FILEHDR_SYMPTR
+#define PUT_FILEHDR_SYMPTR H_PUT_32
+#endif
+
+/* Some fields in the aouthdr are sometimes 64 bits. */
+#ifndef GET_AOUTHDR_TSIZE
+#define GET_AOUTHDR_TSIZE H_GET_32
+#endif
+#ifndef PUT_AOUTHDR_TSIZE
+#define PUT_AOUTHDR_TSIZE H_PUT_32
+#endif
+#ifndef GET_AOUTHDR_DSIZE
+#define GET_AOUTHDR_DSIZE H_GET_32
+#endif
+#ifndef PUT_AOUTHDR_DSIZE
+#define PUT_AOUTHDR_DSIZE H_PUT_32
+#endif
+#ifndef GET_AOUTHDR_BSIZE
+#define GET_AOUTHDR_BSIZE H_GET_32
+#endif
+#ifndef PUT_AOUTHDR_BSIZE
+#define PUT_AOUTHDR_BSIZE H_PUT_32
+#endif
+#ifndef GET_AOUTHDR_ENTRY
+#define GET_AOUTHDR_ENTRY H_GET_32
+#endif
+#ifndef PUT_AOUTHDR_ENTRY
+#define PUT_AOUTHDR_ENTRY H_PUT_32
+#endif
+#ifndef GET_AOUTHDR_TEXT_START
+#define GET_AOUTHDR_TEXT_START H_GET_32
+#endif
+#ifndef PUT_AOUTHDR_TEXT_START
+#define PUT_AOUTHDR_TEXT_START H_PUT_32
+#endif
+#ifndef GET_AOUTHDR_DATA_START
+#define GET_AOUTHDR_DATA_START H_GET_32
+#endif
+#ifndef PUT_AOUTHDR_DATA_START
+#define PUT_AOUTHDR_DATA_START H_PUT_32
+#endif
+
+/* Some fields in the scnhdr are sometimes 64 bits. */
+#ifndef GET_SCNHDR_PADDR
+#define GET_SCNHDR_PADDR H_GET_32
+#endif
+#ifndef PUT_SCNHDR_PADDR
+#define PUT_SCNHDR_PADDR H_PUT_32
+#endif
+#ifndef GET_SCNHDR_VADDR
+#define GET_SCNHDR_VADDR H_GET_32
+#endif
+#ifndef PUT_SCNHDR_VADDR
+#define PUT_SCNHDR_VADDR H_PUT_32
+#endif
+#ifndef GET_SCNHDR_SIZE
+#define GET_SCNHDR_SIZE H_GET_32
+#endif
+#ifndef PUT_SCNHDR_SIZE
+#define PUT_SCNHDR_SIZE H_PUT_32
+#endif
+#ifndef GET_SCNHDR_SCNPTR
+#define GET_SCNHDR_SCNPTR H_GET_32
+#endif
+#ifndef PUT_SCNHDR_SCNPTR
+#define PUT_SCNHDR_SCNPTR H_PUT_32
+#endif
+#ifndef GET_SCNHDR_RELPTR
+#define GET_SCNHDR_RELPTR H_GET_32
+#endif
+#ifndef PUT_SCNHDR_RELPTR
+#define PUT_SCNHDR_RELPTR H_PUT_32
+#endif
+#ifndef GET_SCNHDR_LNNOPTR
+#define GET_SCNHDR_LNNOPTR H_GET_32
+#endif
+#ifndef PUT_SCNHDR_LNNOPTR
+#define PUT_SCNHDR_LNNOPTR H_PUT_32
+#endif
+#ifndef GET_SCNHDR_NRELOC
+#define GET_SCNHDR_NRELOC H_GET_16
+#endif
+#ifndef MAX_SCNHDR_NRELOC
+#define MAX_SCNHDR_NRELOC 0xffff
+#endif
+#ifndef PUT_SCNHDR_NRELOC
+#define PUT_SCNHDR_NRELOC H_PUT_16
+#endif
+#ifndef GET_SCNHDR_NLNNO
+#define GET_SCNHDR_NLNNO H_GET_16
+#endif
+#ifndef MAX_SCNHDR_NLNNO
+#define MAX_SCNHDR_NLNNO 0xffff
+#endif
+#ifndef PUT_SCNHDR_NLNNO
+#define PUT_SCNHDR_NLNNO H_PUT_16
+#endif
+#ifndef GET_SCNHDR_FLAGS
+#define GET_SCNHDR_FLAGS H_GET_32
+#endif
+#ifndef PUT_SCNHDR_FLAGS
+#define PUT_SCNHDR_FLAGS H_PUT_32
+#endif
+
+#ifndef GET_RELOC_VADDR
+#define GET_RELOC_VADDR H_GET_32
+#endif
+#ifndef PUT_RELOC_VADDR
+#define PUT_RELOC_VADDR H_PUT_32
+#endif
+
+#ifndef NO_COFF_RELOCS
+
+static void
+coff_swap_reloc_in (bfd * abfd, void * src, void * dst)
+{
+ RELOC *reloc_src = (RELOC *) src;
+ struct internal_reloc *reloc_dst = (struct internal_reloc *) dst;
+
+ reloc_dst->r_vaddr = GET_RELOC_VADDR (abfd, reloc_src->r_vaddr);
+ reloc_dst->r_symndx = H_GET_S32 (abfd, reloc_src->r_symndx);
+ reloc_dst->r_type = H_GET_16 (abfd, reloc_src->r_type);
+
+#ifdef SWAP_IN_RELOC_OFFSET
+ reloc_dst->r_offset = SWAP_IN_RELOC_OFFSET (abfd, reloc_src->r_offset);
+#endif
+}
+
+static unsigned int
+coff_swap_reloc_out (bfd * abfd, void * src, void * dst)
+{
+ struct internal_reloc *reloc_src = (struct internal_reloc *) src;
+ struct external_reloc *reloc_dst = (struct external_reloc *) dst;
+
+ PUT_RELOC_VADDR (abfd, reloc_src->r_vaddr, reloc_dst->r_vaddr);
+ H_PUT_32 (abfd, reloc_src->r_symndx, reloc_dst->r_symndx);
+ H_PUT_16 (abfd, reloc_src->r_type, reloc_dst->r_type);
+
+#ifdef SWAP_OUT_RELOC_OFFSET
+ SWAP_OUT_RELOC_OFFSET (abfd, reloc_src->r_offset, reloc_dst->r_offset);
+#endif
+#ifdef SWAP_OUT_RELOC_EXTRA
+ SWAP_OUT_RELOC_EXTRA (abfd, reloc_src, reloc_dst);
+#endif
+
+ return bfd_coff_relsz (abfd);
+}
+
+#endif /* NO_COFF_RELOCS */
+
+static void
+coff_swap_filehdr_in (bfd * abfd, void * src, void * 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 = H_GET_16 (abfd, filehdr_src->f_magic);
+ filehdr_dst->f_nscns = H_GET_16 (abfd, filehdr_src->f_nscns);
+ filehdr_dst->f_timdat = H_GET_32 (abfd, filehdr_src->f_timdat);
+ filehdr_dst->f_symptr = GET_FILEHDR_SYMPTR (abfd, filehdr_src->f_symptr);
+ filehdr_dst->f_nsyms = H_GET_32 (abfd, filehdr_src->f_nsyms);
+ filehdr_dst->f_opthdr = H_GET_16 (abfd, filehdr_src->f_opthdr);
+ filehdr_dst->f_flags = H_GET_16 (abfd, filehdr_src->f_flags);
+#ifdef TIC80_TARGET_ID
+ filehdr_dst->f_target_id = H_GET_16 (abfd, 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 (bfd *abfd, void * in, void * 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
+ H_PUT_16 (abfd, filehdr_in->f_magic, filehdr_out->f_magic);
+ H_PUT_16 (abfd, filehdr_in->f_nscns, filehdr_out->f_nscns);
+ H_PUT_32 (abfd, filehdr_in->f_timdat, filehdr_out->f_timdat);
+ PUT_FILEHDR_SYMPTR (abfd, filehdr_in->f_symptr, filehdr_out->f_symptr);
+ H_PUT_32 (abfd, filehdr_in->f_nsyms, filehdr_out->f_nsyms);
+ H_PUT_16 (abfd, filehdr_in->f_opthdr, filehdr_out->f_opthdr);
+ H_PUT_16 (abfd, filehdr_in->f_flags, filehdr_out->f_flags);
+#ifdef TIC80_TARGET_ID
+ H_PUT_16 (abfd, filehdr_in->f_target_id, filehdr_out->f_target_id);
+#endif
+
+#ifdef COFF_ADJUST_FILEHDR_OUT_POST
+ COFF_ADJUST_FILEHDR_OUT_POST (abfd, in, out);
+#endif
+ return bfd_coff_filhsz (abfd);
+}
+
+#ifndef NO_COFF_SYMBOLS
+
+static void
+coff_swap_sym_in (bfd * abfd, void * ext1, void * 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 = H_GET_32 (abfd, 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 = H_GET_32 (abfd, ext->e_value);
+ in->n_scnum = H_GET_16 (abfd, ext->e_scnum);
+ if (sizeof (ext->e_type) == 2)
+ in->n_type = H_GET_16 (abfd, ext->e_type);
+ else
+ in->n_type = H_GET_32 (abfd, ext->e_type);
+ in->n_sclass = H_GET_8 (abfd, ext->e_sclass);
+ in->n_numaux = H_GET_8 (abfd, ext->e_numaux);
+#ifdef COFF_ADJUST_SYM_IN_POST
+ COFF_ADJUST_SYM_IN_POST (abfd, ext1, in1);
+#endif
+}
+
+static unsigned int
+coff_swap_sym_out (bfd * abfd, void * inp, void * extp)
+{
+ struct internal_syment *in = (struct internal_syment *) inp;
+ SYMENT *ext =(SYMENT *) extp;
+
+#ifdef COFF_ADJUST_SYM_OUT_PRE
+ COFF_ADJUST_SYM_OUT_PRE (abfd, inp, extp);
+#endif
+
+ if (in->_n._n_name[0] == 0)
+ {
+ H_PUT_32 (abfd, 0, ext->e.e.e_zeroes);
+ H_PUT_32 (abfd, in->_n._n_n._n_offset, 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
+ }
+
+ H_PUT_32 (abfd, in->n_value, ext->e_value);
+ H_PUT_16 (abfd, in->n_scnum, ext->e_scnum);
+
+ if (sizeof (ext->e_type) == 2)
+ H_PUT_16 (abfd, in->n_type, ext->e_type);
+ else
+ H_PUT_32 (abfd, in->n_type, ext->e_type);
+
+ H_PUT_8 (abfd, in->n_sclass, ext->e_sclass);
+ H_PUT_8 (abfd, in->n_numaux, ext->e_numaux);
+
+#ifdef COFF_ADJUST_SYM_OUT_POST
+ COFF_ADJUST_SYM_OUT_POST (abfd, inp, extp);
+#endif
+
+ return SYMESZ;
+}
+
+static void
+coff_swap_aux_in (bfd *abfd,
+ void * ext1,
+ int type,
+ int in_class,
+ int indx,
+ int numaux,
+ void * 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, in_class, indx, numaux, in1);
+#endif
+
+ switch (in_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 = H_GET_32 (abfd, ext->x_file.x_n.x_offset);
+ }
+ else
+ {
+#if FILNMLEN != E_FILNMLEN
+#error we need to cope with truncating or extending FILNMLEN
+#else
+ if (numaux > 1)
+ {
+ if (indx == 0)
+ memcpy (in->x_file.x_fname, ext->x_file.x_fname,
+ numaux * sizeof (AUXENT));
+ }
+ else
+ memcpy (in->x_file.x_fname, ext->x_file.x_fname, FILNMLEN);
+#endif
+ }
+ goto end;
+
+ 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 = H_GET_32 (abfd, ext->x_sym.x_tagndx);
+#ifndef NO_TVNDX
+ in->x_sym.x_tvndx = H_GET_16 (abfd, ext->x_sym.x_tvndx);
+#endif
+
+ if (in_class == C_BLOCK || in_class == C_FCN || ISFCN (type)
+ || ISTAG (in_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] =
+ H_GET_16 (abfd, ext->x_sym.x_fcnary.x_ary.x_dimen[0]);
+ in->x_sym.x_fcnary.x_ary.x_dimen[1] =
+ H_GET_16 (abfd, ext->x_sym.x_fcnary.x_ary.x_dimen[1]);
+ in->x_sym.x_fcnary.x_ary.x_dimen[2] =
+ H_GET_16 (abfd, ext->x_sym.x_fcnary.x_ary.x_dimen[2]);
+ in->x_sym.x_fcnary.x_ary.x_dimen[3] =
+ H_GET_16 (abfd, ext->x_sym.x_fcnary.x_ary.x_dimen[3]);
+ }
+
+ if (ISFCN (type))
+ in->x_sym.x_misc.x_fsize = H_GET_32 (abfd, 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: ;
+
+#ifdef COFF_ADJUST_AUX_IN_POST
+ COFF_ADJUST_AUX_IN_POST (abfd, ext1, type, in_class, indx, numaux, in1);
+#endif
+}
+
+static unsigned int
+coff_swap_aux_out (bfd * abfd,
+ void * inp,
+ int type,
+ int in_class,
+ int indx ATTRIBUTE_UNUSED,
+ int numaux ATTRIBUTE_UNUSED,
+ void * 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, in_class, indx, numaux, extp);
+#endif
+
+ memset (ext, 0, AUXESZ);
+
+ switch (in_class)
+ {
+ case C_FILE:
+ if (in->x_file.x_fname[0] == 0)
+ {
+ H_PUT_32 (abfd, 0, ext->x_file.x_n.x_zeroes);
+ H_PUT_32 (abfd, in->x_file.x_n.x_offset, 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;
+
+ 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;
+ }
+
+ H_PUT_32 (abfd, in->x_sym.x_tagndx.l, ext->x_sym.x_tagndx);
+#ifndef NO_TVNDX
+ H_PUT_16 (abfd, in->x_sym.x_tvndx, ext->x_sym.x_tvndx);
+#endif
+
+ if (in_class == C_BLOCK || in_class == C_FCN || ISFCN (type)
+ || ISTAG (in_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
+ H_PUT_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[0],
+ ext->x_sym.x_fcnary.x_ary.x_dimen[0]);
+ H_PUT_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[1],
+ ext->x_sym.x_fcnary.x_ary.x_dimen[1]);
+ H_PUT_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[2],
+ ext->x_sym.x_fcnary.x_ary.x_dimen[2]);
+ H_PUT_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[3],
+ ext->x_sym.x_fcnary.x_ary.x_dimen[3]);
+ }
+
+ if (ISFCN (type))
+ H_PUT_32 (abfd, in->x_sym.x_misc.x_fsize, 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, in_class, indx, numaux, extp);
+#endif
+ return AUXESZ;
+}
+
+#endif /* NO_COFF_SYMBOLS */
+
+#ifndef NO_COFF_LINENOS
+
+static void
+coff_swap_lineno_in (bfd * abfd, void * ext1, void * in1)
+{
+ LINENO *ext = (LINENO *) ext1;
+ struct internal_lineno *in = (struct internal_lineno *) in1;
+
+ in->l_addr.l_symndx = H_GET_32 (abfd, ext->l_addr.l_symndx);
+ in->l_lnno = GET_LINENO_LNNO (abfd, ext);
+}
+
+static unsigned int
+coff_swap_lineno_out (bfd * abfd, void * inp, void * outp)
+{
+ struct internal_lineno *in = (struct internal_lineno *) inp;
+ struct external_lineno *ext = (struct external_lineno *) outp;
+ H_PUT_32 (abfd, in->l_addr.l_symndx, 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 (bfd * abfd, void * aouthdr_ext1, void * aouthdr_int1)
+{
+ AOUTHDR *aouthdr_ext;
+ struct internal_aouthdr *aouthdr_int;
+
+ aouthdr_ext = (AOUTHDR *) aouthdr_ext1;
+ aouthdr_int = (struct internal_aouthdr *) aouthdr_int1;
+ aouthdr_int->magic = H_GET_16 (abfd, aouthdr_ext->magic);
+ aouthdr_int->vstamp = H_GET_16 (abfd, aouthdr_ext->vstamp);
+ aouthdr_int->tsize = GET_AOUTHDR_TSIZE (abfd, aouthdr_ext->tsize);
+ aouthdr_int->dsize = GET_AOUTHDR_DSIZE (abfd, aouthdr_ext->dsize);
+ aouthdr_int->bsize = GET_AOUTHDR_BSIZE (abfd, aouthdr_ext->bsize);
+ aouthdr_int->entry = GET_AOUTHDR_ENTRY (abfd, aouthdr_ext->entry);
+ aouthdr_int->text_start =
+ GET_AOUTHDR_TEXT_START (abfd, aouthdr_ext->text_start);
+ aouthdr_int->data_start =
+ GET_AOUTHDR_DATA_START (abfd, aouthdr_ext->data_start);
+
+#ifdef I960
+ aouthdr_int->tagentries = H_GET_32 (abfd, aouthdr_ext->tagentries);
+#endif
+
+#ifdef APOLLO_M68
+ H_PUT_32 (abfd, aouthdr_int->o_inlib, aouthdr_ext->o_inlib);
+ H_PUT_32 (abfd, aouthdr_int->o_sri, aouthdr_ext->o_sri);
+ H_PUT_32 (abfd, aouthdr_int->vid[0], aouthdr_ext->vid);
+ H_PUT_32 (abfd, aouthdr_int->vid[1], aouthdr_ext->vid + 4);
+#endif
+
+#ifdef RS6000COFF_C
+#ifdef XCOFF64
+ aouthdr_int->o_toc = H_GET_64 (abfd, aouthdr_ext->o_toc);
+#else
+ aouthdr_int->o_toc = H_GET_32 (abfd, aouthdr_ext->o_toc);
+#endif
+ aouthdr_int->o_snentry = H_GET_16 (abfd, aouthdr_ext->o_snentry);
+ aouthdr_int->o_sntext = H_GET_16 (abfd, aouthdr_ext->o_sntext);
+ aouthdr_int->o_sndata = H_GET_16 (abfd, aouthdr_ext->o_sndata);
+ aouthdr_int->o_sntoc = H_GET_16 (abfd, aouthdr_ext->o_sntoc);
+ aouthdr_int->o_snloader = H_GET_16 (abfd, aouthdr_ext->o_snloader);
+ aouthdr_int->o_snbss = H_GET_16 (abfd, aouthdr_ext->o_snbss);
+ aouthdr_int->o_algntext = H_GET_16 (abfd, aouthdr_ext->o_algntext);
+ aouthdr_int->o_algndata = H_GET_16 (abfd, aouthdr_ext->o_algndata);
+ aouthdr_int->o_modtype = H_GET_16 (abfd, aouthdr_ext->o_modtype);
+ aouthdr_int->o_cputype = H_GET_16 (abfd, aouthdr_ext->o_cputype);
+#ifdef XCOFF64
+ aouthdr_int->o_maxstack = H_GET_64 (abfd, aouthdr_ext->o_maxstack);
+ aouthdr_int->o_maxdata = H_GET_64 (abfd, aouthdr_ext->o_maxdata);
+#else
+ aouthdr_int->o_maxstack = H_GET_32 (abfd, aouthdr_ext->o_maxstack);
+ aouthdr_int->o_maxdata = H_GET_32 (abfd, aouthdr_ext->o_maxdata);
+#endif
+#endif
+
+#ifdef MIPSECOFF
+ aouthdr_int->bss_start = H_GET_32 (abfd, aouthdr_ext->bss_start);
+ aouthdr_int->gp_value = H_GET_32 (abfd, aouthdr_ext->gp_value);
+ aouthdr_int->gprmask = H_GET_32 (abfd, aouthdr_ext->gprmask);
+ aouthdr_int->cprmask[0] = H_GET_32 (abfd, aouthdr_ext->cprmask[0]);
+ aouthdr_int->cprmask[1] = H_GET_32 (abfd, aouthdr_ext->cprmask[1]);
+ aouthdr_int->cprmask[2] = H_GET_32 (abfd, aouthdr_ext->cprmask[2]);
+ aouthdr_int->cprmask[3] = H_GET_32 (abfd, aouthdr_ext->cprmask[3]);
+#endif
+
+#ifdef ALPHAECOFF
+ aouthdr_int->bss_start = H_GET_64 (abfd, aouthdr_ext->bss_start);
+ aouthdr_int->gp_value = H_GET_64 (abfd, aouthdr_ext->gp_value);
+ aouthdr_int->gprmask = H_GET_32 (abfd, aouthdr_ext->gprmask);
+ aouthdr_int->fprmask = H_GET_32 (abfd, aouthdr_ext->fprmask);
+#endif
+}
+
+static unsigned int
+coff_swap_aouthdr_out (bfd * abfd, void * in, void * out)
+{
+ struct internal_aouthdr *aouthdr_in = (struct internal_aouthdr *) in;
+ AOUTHDR *aouthdr_out = (AOUTHDR *) out;
+
+ H_PUT_16 (abfd, aouthdr_in->magic, aouthdr_out->magic);
+ H_PUT_16 (abfd, aouthdr_in->vstamp, aouthdr_out->vstamp);
+ PUT_AOUTHDR_TSIZE (abfd, aouthdr_in->tsize, aouthdr_out->tsize);
+ PUT_AOUTHDR_DSIZE (abfd, aouthdr_in->dsize, aouthdr_out->dsize);
+ PUT_AOUTHDR_BSIZE (abfd, aouthdr_in->bsize, aouthdr_out->bsize);
+ PUT_AOUTHDR_ENTRY (abfd, aouthdr_in->entry, aouthdr_out->entry);
+ PUT_AOUTHDR_TEXT_START (abfd, aouthdr_in->text_start,
+ aouthdr_out->text_start);
+ PUT_AOUTHDR_DATA_START (abfd, aouthdr_in->data_start,
+ aouthdr_out->data_start);
+
+#ifdef I960
+ H_PUT_32 (abfd, aouthdr_in->tagentries, aouthdr_out->tagentries);
+#endif
+
+#ifdef RS6000COFF_C
+#ifdef XCOFF64
+ H_PUT_64 (abfd, aouthdr_in->o_toc, aouthdr_out->o_toc);
+#else
+ H_PUT_32 (abfd, aouthdr_in->o_toc, aouthdr_out->o_toc);
+#endif
+ H_PUT_16 (abfd, aouthdr_in->o_snentry, aouthdr_out->o_snentry);
+ H_PUT_16 (abfd, aouthdr_in->o_sntext, aouthdr_out->o_sntext);
+ H_PUT_16 (abfd, aouthdr_in->o_sndata, aouthdr_out->o_sndata);
+ H_PUT_16 (abfd, aouthdr_in->o_sntoc, aouthdr_out->o_sntoc);
+ H_PUT_16 (abfd, aouthdr_in->o_snloader, aouthdr_out->o_snloader);
+ H_PUT_16 (abfd, aouthdr_in->o_snbss, aouthdr_out->o_snbss);
+ H_PUT_16 (abfd, aouthdr_in->o_algntext, aouthdr_out->o_algntext);
+ H_PUT_16 (abfd, aouthdr_in->o_algndata, aouthdr_out->o_algndata);
+ H_PUT_16 (abfd, aouthdr_in->o_modtype, aouthdr_out->o_modtype);
+ H_PUT_16 (abfd, aouthdr_in->o_cputype, aouthdr_out->o_cputype);
+#ifdef XCOFF64
+ H_PUT_64 (abfd, aouthdr_in->o_maxstack, aouthdr_out->o_maxstack);
+ H_PUT_64 (abfd, aouthdr_in->o_maxdata, aouthdr_out->o_maxdata);
+#else
+ H_PUT_32 (abfd, aouthdr_in->o_maxstack, aouthdr_out->o_maxstack);
+ H_PUT_32 (abfd, aouthdr_in->o_maxdata, aouthdr_out->o_maxdata);
+#endif
+ memset (aouthdr_out->o_resv2, 0, sizeof aouthdr_out->o_resv2);
+#ifdef XCOFF64
+ memset (aouthdr_out->o_debugger, 0, sizeof aouthdr_out->o_debugger);
+ memset (aouthdr_out->o_resv3, 0, sizeof aouthdr_out->o_resv3);
+#endif
+#endif
+
+#ifdef MIPSECOFF
+ H_PUT_32 (abfd, aouthdr_in->bss_start, aouthdr_out->bss_start);
+ H_PUT_32 (abfd, aouthdr_in->gp_value, aouthdr_out->gp_value);
+ H_PUT_32 (abfd, aouthdr_in->gprmask, aouthdr_out->gprmask);
+ H_PUT_32 (abfd, aouthdr_in->cprmask[0], aouthdr_out->cprmask[0]);
+ H_PUT_32 (abfd, aouthdr_in->cprmask[1], aouthdr_out->cprmask[1]);
+ H_PUT_32 (abfd, aouthdr_in->cprmask[2], aouthdr_out->cprmask[2]);
+ H_PUT_32 (abfd, aouthdr_in->cprmask[3], aouthdr_out->cprmask[3]);
+#endif
+
+#ifdef ALPHAECOFF
+ /* FIXME: What does bldrev mean? */
+ H_PUT_16 (abfd, 2, aouthdr_out->bldrev);
+ H_PUT_16 (abfd, 0, aouthdr_out->padding);
+ H_PUT_64 (abfd, aouthdr_in->bss_start, aouthdr_out->bss_start);
+ H_PUT_64 (abfd, aouthdr_in->gp_value, aouthdr_out->gp_value);
+ H_PUT_32 (abfd, aouthdr_in->gprmask, aouthdr_out->gprmask);
+ H_PUT_32 (abfd, aouthdr_in->fprmask, aouthdr_out->fprmask);
+#endif
+
+ return AOUTSZ;
+}
+
+static void
+coff_swap_scnhdr_in (bfd * abfd, void * ext, void * 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, scnhdr_ext->s_vaddr);
+ scnhdr_int->s_paddr = GET_SCNHDR_PADDR (abfd, scnhdr_ext->s_paddr);
+ scnhdr_int->s_size = GET_SCNHDR_SIZE (abfd, scnhdr_ext->s_size);
+
+ scnhdr_int->s_scnptr = GET_SCNHDR_SCNPTR (abfd, scnhdr_ext->s_scnptr);
+ scnhdr_int->s_relptr = GET_SCNHDR_RELPTR (abfd, scnhdr_ext->s_relptr);
+ scnhdr_int->s_lnnoptr = GET_SCNHDR_LNNOPTR (abfd, scnhdr_ext->s_lnnoptr);
+ scnhdr_int->s_flags = GET_SCNHDR_FLAGS (abfd, scnhdr_ext->s_flags);
+ scnhdr_int->s_nreloc = GET_SCNHDR_NRELOC (abfd, scnhdr_ext->s_nreloc);
+ scnhdr_int->s_nlnno = GET_SCNHDR_NLNNO (abfd, scnhdr_ext->s_nlnno);
+#ifdef I960
+ scnhdr_int->s_align = GET_SCNHDR_ALIGN (abfd, 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 (bfd * abfd, void * in, void * out)
+{
+ struct internal_scnhdr *scnhdr_int = (struct internal_scnhdr *) in;
+ SCNHDR *scnhdr_ext = (SCNHDR *) out;
+ unsigned int ret = bfd_coff_scnhsz (abfd);
+
+#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, scnhdr_ext->s_vaddr);
+ PUT_SCNHDR_PADDR (abfd, scnhdr_int->s_paddr, scnhdr_ext->s_paddr);
+ PUT_SCNHDR_SIZE (abfd, scnhdr_int->s_size, scnhdr_ext->s_size);
+ PUT_SCNHDR_SCNPTR (abfd, scnhdr_int->s_scnptr, scnhdr_ext->s_scnptr);
+ PUT_SCNHDR_RELPTR (abfd, scnhdr_int->s_relptr, scnhdr_ext->s_relptr);
+ PUT_SCNHDR_LNNOPTR (abfd, scnhdr_int->s_lnnoptr, scnhdr_ext->s_lnnoptr);
+ PUT_SCNHDR_FLAGS (abfd, scnhdr_int->s_flags, scnhdr_ext->s_flags);
+#if defined(M88)
+ H_PUT_32 (abfd, scnhdr_int->s_nlnno, scnhdr_ext->s_nlnno);
+ H_PUT_32 (abfd, scnhdr_int->s_nreloc, scnhdr_ext->s_nreloc);
+#else
+ if (scnhdr_int->s_nlnno <= MAX_SCNHDR_NLNNO)
+ PUT_SCNHDR_NLNNO (abfd, scnhdr_int->s_nlnno, 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);
+ PUT_SCNHDR_NLNNO (abfd, 0xffff, scnhdr_ext->s_nlnno);
+ }
+
+ if (scnhdr_int->s_nreloc <= MAX_SCNHDR_NRELOC)
+ PUT_SCNHDR_NRELOC (abfd, scnhdr_int->s_nreloc, 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);
+ PUT_SCNHDR_NRELOC (abfd, 0xffff, scnhdr_ext->s_nreloc);
+ ret = 0;
+ }
+#endif
+
+#ifdef I960
+ PUT_SCNHDR_ALIGN (abfd, scnhdr_int->s_align, 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/compress.c b/bfd/compress.c
new file mode 100644
index 0000000..20eef95
--- /dev/null
+++ b/bfd/compress.c
@@ -0,0 +1,438 @@
+/* Compressed section support (intended for debug sections).
+ Copyright (C) 2008-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+#ifdef HAVE_ZLIB_H
+#include <zlib.h>
+#endif
+#include "safe-ctype.h"
+
+#ifdef HAVE_ZLIB_H
+static bfd_boolean
+decompress_contents (bfd_byte *compressed_buffer,
+ bfd_size_type compressed_size,
+ bfd_byte *uncompressed_buffer,
+ bfd_size_type uncompressed_size)
+{
+ z_stream strm;
+ int rc;
+
+ /* It is possible the section consists of several compressed
+ buffers concatenated together, so we uncompress in a loop. */
+ strm.zalloc = NULL;
+ strm.zfree = NULL;
+ strm.opaque = NULL;
+ strm.avail_in = compressed_size - 12;
+ strm.next_in = (Bytef*) compressed_buffer + 12;
+ strm.avail_out = uncompressed_size;
+
+ BFD_ASSERT (Z_OK == 0);
+ rc = inflateInit (&strm);
+ while (strm.avail_in > 0 && strm.avail_out > 0)
+ {
+ if (rc != Z_OK)
+ break;
+ strm.next_out = ((Bytef*) uncompressed_buffer
+ + (uncompressed_size - strm.avail_out));
+ rc = inflate (&strm, Z_FINISH);
+ if (rc != Z_STREAM_END)
+ break;
+ rc = inflateReset (&strm);
+ }
+ rc |= inflateEnd (&strm);
+ return rc == Z_OK && strm.avail_out == 0;
+}
+#endif
+
+/*
+FUNCTION
+ bfd_compress_section_contents
+
+SYNOPSIS
+ bfd_boolean bfd_compress_section_contents
+ (bfd *abfd, asection *section, bfd_byte *uncompressed_buffer,
+ bfd_size_type uncompressed_size);
+
+DESCRIPTION
+
+ Compress data of the size specified in @var{uncompressed_size}
+ and pointed to by @var{uncompressed_buffer} using zlib and store
+ as the contents field. This function assumes the contents
+ field was allocated using bfd_malloc() or equivalent. If zlib
+ is not installed on this machine, the input is unmodified.
+
+ Return @code{TRUE} if the full section contents is compressed
+ successfully.
+*/
+
+bfd_boolean
+bfd_compress_section_contents (bfd *abfd ATTRIBUTE_UNUSED,
+ sec_ptr sec ATTRIBUTE_UNUSED,
+ bfd_byte *uncompressed_buffer ATTRIBUTE_UNUSED,
+ bfd_size_type uncompressed_size ATTRIBUTE_UNUSED)
+{
+#ifndef HAVE_ZLIB_H
+ bfd_set_error (bfd_error_invalid_operation);
+ return FALSE;
+#else
+ uLong compressed_size;
+ bfd_byte *compressed_buffer;
+
+ compressed_size = compressBound (uncompressed_size) + 12;
+ compressed_buffer = (bfd_byte *) bfd_malloc (compressed_size);
+
+ if (compressed_buffer == NULL)
+ return FALSE;
+
+ if (compress ((Bytef*) compressed_buffer + 12,
+ &compressed_size,
+ (const Bytef*) uncompressed_buffer,
+ uncompressed_size) != Z_OK)
+ {
+ free (compressed_buffer);
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+
+ /* Write the zlib header. In this case, it should be "ZLIB" followed
+ by the uncompressed section size, 8 bytes in big-endian order. */
+ memcpy (compressed_buffer, "ZLIB", 4);
+ compressed_buffer[11] = uncompressed_size; uncompressed_size >>= 8;
+ compressed_buffer[10] = uncompressed_size; uncompressed_size >>= 8;
+ compressed_buffer[9] = uncompressed_size; uncompressed_size >>= 8;
+ compressed_buffer[8] = uncompressed_size; uncompressed_size >>= 8;
+ compressed_buffer[7] = uncompressed_size; uncompressed_size >>= 8;
+ compressed_buffer[6] = uncompressed_size; uncompressed_size >>= 8;
+ compressed_buffer[5] = uncompressed_size; uncompressed_size >>= 8;
+ compressed_buffer[4] = uncompressed_size;
+ compressed_size += 12;
+
+ /* Free the uncompressed contents if we compress in place. */
+ if (uncompressed_buffer == sec->contents)
+ free (uncompressed_buffer);
+
+ sec->contents = compressed_buffer;
+ sec->size = compressed_size;
+ sec->compress_status = COMPRESS_SECTION_DONE;
+
+ return TRUE;
+#endif /* HAVE_ZLIB_H */
+}
+
+/*
+FUNCTION
+ bfd_get_full_section_contents
+
+SYNOPSIS
+ bfd_boolean bfd_get_full_section_contents
+ (bfd *abfd, asection *section, bfd_byte **ptr);
+
+DESCRIPTION
+ Read all data from @var{section} in BFD @var{abfd}, decompress
+ if needed, and store in @var{*ptr}. If @var{*ptr} is NULL,
+ return @var{*ptr} with memory malloc'd by this function.
+
+ Return @code{TRUE} if the full section contents is retrieved
+ successfully.
+*/
+
+bfd_boolean
+bfd_get_full_section_contents (bfd *abfd, sec_ptr sec, bfd_byte **ptr)
+{
+ bfd_size_type sz;
+ bfd_byte *p = *ptr;
+#ifdef HAVE_ZLIB_H
+ bfd_boolean ret;
+ bfd_size_type save_size;
+ bfd_size_type save_rawsize;
+ bfd_byte *compressed_buffer;
+#endif
+
+ if (abfd->direction != write_direction && sec->rawsize != 0)
+ sz = sec->rawsize;
+ else
+ sz = sec->size;
+ if (sz == 0)
+ return TRUE;
+
+ switch (sec->compress_status)
+ {
+ case COMPRESS_SECTION_NONE:
+ if (p == NULL)
+ {
+ p = (bfd_byte *) bfd_malloc (sz);
+ if (p == NULL)
+ return FALSE;
+ }
+ if (!bfd_get_section_contents (abfd, sec, p, 0, sz))
+ {
+ if (*ptr != p)
+ free (p);
+ return FALSE;
+ }
+ *ptr = p;
+ return TRUE;
+
+ case DECOMPRESS_SECTION_SIZED:
+#ifndef HAVE_ZLIB_H
+ bfd_set_error (bfd_error_invalid_operation);
+ return FALSE;
+#else
+ /* Read in the full compressed section contents. */
+ compressed_buffer = (bfd_byte *) bfd_malloc (sec->compressed_size);
+ if (compressed_buffer == NULL)
+ return FALSE;
+ save_rawsize = sec->rawsize;
+ save_size = sec->size;
+ /* Clear rawsize, set size to compressed size and set compress_status
+ to COMPRESS_SECTION_NONE. If the compressed size is bigger than
+ the uncompressed size, bfd_get_section_contents will fail. */
+ sec->rawsize = 0;
+ sec->size = sec->compressed_size;
+ sec->compress_status = COMPRESS_SECTION_NONE;
+ ret = bfd_get_section_contents (abfd, sec, compressed_buffer,
+ 0, sec->compressed_size);
+ /* Restore rawsize and size. */
+ sec->rawsize = save_rawsize;
+ sec->size = save_size;
+ sec->compress_status = DECOMPRESS_SECTION_SIZED;
+ if (!ret)
+ goto fail_compressed;
+
+ if (p == NULL)
+ p = (bfd_byte *) bfd_malloc (sz);
+ if (p == NULL)
+ goto fail_compressed;
+
+ if (!decompress_contents (compressed_buffer, sec->compressed_size, p, sz))
+ {
+ bfd_set_error (bfd_error_bad_value);
+ if (p != *ptr)
+ free (p);
+ fail_compressed:
+ free (compressed_buffer);
+ return FALSE;
+ }
+
+ free (compressed_buffer);
+ *ptr = p;
+ return TRUE;
+#endif
+
+ case COMPRESS_SECTION_DONE:
+ if (p == NULL)
+ {
+ p = (bfd_byte *) bfd_malloc (sz);
+ if (p == NULL)
+ return FALSE;
+ *ptr = p;
+ }
+ memcpy (p, sec->contents, sz);
+ return TRUE;
+
+ default:
+ abort ();
+ }
+}
+
+/*
+FUNCTION
+ bfd_cache_section_contents
+
+SYNOPSIS
+ void bfd_cache_section_contents
+ (asection *sec, void *contents);
+
+DESCRIPTION
+ Stash @var(contents) so any following reads of @var(sec) do
+ not need to decompress again.
+*/
+
+void
+bfd_cache_section_contents (asection *sec, void *contents)
+{
+ if (sec->compress_status == DECOMPRESS_SECTION_SIZED)
+ sec->compress_status = COMPRESS_SECTION_DONE;
+ sec->contents = contents;
+ sec->flags |= SEC_IN_MEMORY;
+}
+
+
+/*
+FUNCTION
+ bfd_is_section_compressed
+
+SYNOPSIS
+ bfd_boolean bfd_is_section_compressed
+ (bfd *abfd, asection *section);
+
+DESCRIPTION
+ Return @code{TRUE} if @var{section} is compressed.
+*/
+
+bfd_boolean
+bfd_is_section_compressed (bfd *abfd, sec_ptr sec)
+{
+ bfd_byte compressed_buffer [12];
+ unsigned int saved = sec->compress_status;
+ bfd_boolean compressed;
+
+ /* Don't decompress the section. */
+ sec->compress_status = COMPRESS_SECTION_NONE;
+
+ /* Read the zlib header. In this case, it should be "ZLIB" followed
+ by the uncompressed section size, 8 bytes in big-endian order. */
+ compressed = (bfd_get_section_contents (abfd, sec, compressed_buffer, 0, 12)
+ && CONST_STRNEQ ((char*) compressed_buffer, "ZLIB"));
+
+ /* Check for the pathalogical case of a debug string section that
+ contains the string ZLIB.... as the first entry. We assume that
+ no uncompressed .debug_str section would ever be big enough to
+ have the first byte of its (big-endian) size be non-zero. */
+ if (compressed
+ && strcmp (sec->name, ".debug_str") == 0
+ && ISPRINT (compressed_buffer[4]))
+ compressed = FALSE;
+
+ /* Restore compress_status. */
+ sec->compress_status = saved;
+ return compressed;
+}
+
+/*
+FUNCTION
+ bfd_init_section_decompress_status
+
+SYNOPSIS
+ bfd_boolean bfd_init_section_decompress_status
+ (bfd *abfd, asection *section);
+
+DESCRIPTION
+ Record compressed section size, update section size with
+ decompressed size and set compress_status to
+ DECOMPRESS_SECTION_SIZED.
+
+ Return @code{FALSE} if the section is not a valid compressed
+ section or zlib is not installed on this machine. Otherwise,
+ return @code{TRUE}.
+*/
+
+bfd_boolean
+bfd_init_section_decompress_status (bfd *abfd ATTRIBUTE_UNUSED,
+ sec_ptr sec ATTRIBUTE_UNUSED)
+{
+#ifndef HAVE_ZLIB_H
+ bfd_set_error (bfd_error_invalid_operation);
+ return FALSE;
+#else
+ bfd_byte compressed_buffer [12];
+ bfd_size_type uncompressed_size;
+
+ if (sec->rawsize != 0
+ || sec->contents != NULL
+ || sec->compress_status != COMPRESS_SECTION_NONE
+ || !bfd_get_section_contents (abfd, sec, compressed_buffer, 0, 12))
+ {
+ bfd_set_error (bfd_error_invalid_operation);
+ return FALSE;
+ }
+
+ /* Read the zlib header. In this case, it should be "ZLIB" followed
+ by the uncompressed section size, 8 bytes in big-endian order. */
+ if (! CONST_STRNEQ ((char*) compressed_buffer, "ZLIB"))
+ {
+ bfd_set_error (bfd_error_wrong_format);
+ return FALSE;
+ }
+
+ uncompressed_size = compressed_buffer[4]; uncompressed_size <<= 8;
+ uncompressed_size += compressed_buffer[5]; uncompressed_size <<= 8;
+ uncompressed_size += compressed_buffer[6]; uncompressed_size <<= 8;
+ uncompressed_size += compressed_buffer[7]; uncompressed_size <<= 8;
+ uncompressed_size += compressed_buffer[8]; uncompressed_size <<= 8;
+ uncompressed_size += compressed_buffer[9]; uncompressed_size <<= 8;
+ uncompressed_size += compressed_buffer[10]; uncompressed_size <<= 8;
+ uncompressed_size += compressed_buffer[11];
+
+ sec->compressed_size = sec->size;
+ sec->size = uncompressed_size;
+ sec->compress_status = DECOMPRESS_SECTION_SIZED;
+
+ return TRUE;
+#endif
+}
+
+/*
+FUNCTION
+ bfd_init_section_compress_status
+
+SYNOPSIS
+ bfd_boolean bfd_init_section_compress_status
+ (bfd *abfd, asection *section);
+
+DESCRIPTION
+ If open for read, compress section, update section size with
+ compressed size and set compress_status to COMPRESS_SECTION_DONE.
+
+ Return @code{FALSE} if the section is not a valid compressed
+ section or zlib is not installed on this machine. Otherwise,
+ return @code{TRUE}.
+*/
+
+bfd_boolean
+bfd_init_section_compress_status (bfd *abfd ATTRIBUTE_UNUSED,
+ sec_ptr sec ATTRIBUTE_UNUSED)
+{
+#ifndef HAVE_ZLIB_H
+ bfd_set_error (bfd_error_invalid_operation);
+ return FALSE;
+#else
+ bfd_size_type uncompressed_size;
+ bfd_byte *uncompressed_buffer;
+ bfd_boolean ret;
+
+ /* Error if not opened for read. */
+ if (abfd->direction != read_direction
+ || sec->size == 0
+ || sec->rawsize != 0
+ || sec->contents != NULL
+ || sec->compress_status != COMPRESS_SECTION_NONE)
+ {
+ bfd_set_error (bfd_error_invalid_operation);
+ return FALSE;
+ }
+
+ /* Read in the full section contents and compress it. */
+ uncompressed_size = sec->size;
+ uncompressed_buffer = (bfd_byte *) bfd_malloc (uncompressed_size);
+ if (!bfd_get_section_contents (abfd, sec, uncompressed_buffer,
+ 0, uncompressed_size))
+ ret = FALSE;
+ else
+ ret = bfd_compress_section_contents (abfd, sec,
+ uncompressed_buffer,
+ uncompressed_size);
+
+ free (uncompressed_buffer);
+ return ret;
+#endif
+}
diff --git a/bfd/config.bfd b/bfd/config.bfd
new file mode 100644
index 0000000..7bcb92a
--- /dev/null
+++ b/bfd/config.bfd
@@ -0,0 +1,1759 @@
+# config.bfd
+#
+# Copyright (C) 2012-2014 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 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 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 COPYING3. If not see
+# <http://www.gnu.org/licenses/>.
+#
+# 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
+# targ64_selvecs Vectors to build if --enable-64-bit-bfd is given
+# or if host is 64 bit.
+# 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=
+targ64_selvecs=
+targ_cflags=
+targ_underscore=no
+
+# Catch obsolete configurations.
+case $targ in
+ openrisc-*-* | or32-*-*)
+ echo "*** Configuration $targ is obsolete." >&2
+ echo "*** Use or1k-*-elf or or1k-*-linux as the target instead" >&2
+ exit 1
+ ;;
+ null)
+ if test "x$enable_obsolete" != xyes; then
+ echo "*** Configuration $targ is obsolete." >&2
+ echo "*** Specify --enable-obsolete to build it anyway." >&2
+ echo "*** Support will be REMOVED in the next major release of BINUTILS," >&2
+ echo "*** unless a maintainer comes forward." >&2
+ exit 1
+ fi;;
+esac
+
+case $targ in
+ *-go32-rtems* | \
+ a29k-* | \
+ arm-*-oabi | \
+ hppa*-*-rtems* | \
+ i960-*-rtems* | \
+ i[3-7]86*-*-rtemscoff* | \
+ m68*-*-lynxos* | \
+ m68*-*-rtemscoff* | \
+ m68*-apollo-* | \
+ m68*-apple-aux* | \
+ m68*-bull-sysv* | \
+ maxq-*-coff | \
+ mips*el-*-rtems* | \
+ powerpcle-*-rtems* | \
+ sparc*-*-rtemsaout* | \
+ sparc-*-lynxos* | \
+ vax-*-vms* | \
+ null)
+ echo "*** Configuration $targ is obsolete." >&2
+ echo "*** Support has been REMOVED." >&2
+ exit 1
+ ;;
+esac
+
+targ_cpu=`echo $targ | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+case "${targ_cpu}" in
+aarch64*) targ_archs="bfd_aarch64_arch bfd_arm_arch";;
+alpha*) targ_archs=bfd_alpha_arch ;;
+am34*|am33_2.0*) targ_archs=bfd_mn10300_arch ;;
+arm*) targ_archs=bfd_arm_arch ;;
+bfin*) targ_archs=bfd_bfin_arch ;;
+c30*) targ_archs=bfd_tic30_arch ;;
+c4x*) targ_archs=bfd_tic4x_arch ;;
+c54x*) targ_archs=bfd_tic54x_arch ;;
+cr16*) targ_archs=bfd_cr16_arch ;;
+crisv32) targ_archs=bfd_cris_arch ;;
+crx*) targ_archs=bfd_crx_arch ;;
+dlx*) targ_archs=bfd_dlx_arch ;;
+fido*) targ_archs=bfd_m68k_arch ;;
+hppa*) targ_archs=bfd_hppa_arch ;;
+i[3-7]86) targ_archs=bfd_i386_arch ;;
+i370) targ_archs=bfd_i370_arch ;;
+lm32) targ_archs=bfd_lm32_arch ;;
+m6811*|m68hc11*) targ_archs="bfd_m68hc11_arch bfd_m68hc12_arch bfd_m9s12x_arch bfd_m9s12xg_arch" ;;
+m6812*|m68hc12*) targ_archs="bfd_m68hc12_arch bfd_m68hc11_arch bfd_m9s12x_arch bfd_m9s12xg_arch" ;;
+m68*) targ_archs=bfd_m68k_arch ;;
+m88*) targ_archs=bfd_m88k_arch ;;
+microblaze*) targ_archs=bfd_microblaze_arch ;;
+mips*) targ_archs=bfd_mips_arch ;;
+nds32*) targ_archs=bfd_nds32_arch ;;
+nios2*) targ_archs=bfd_nios2_arch ;;
+or1k*|or1knd*) targ_archs=bfd_or1k_arch ;;
+pdp11*) targ_archs=bfd_pdp11_arch ;;
+pj*) targ_archs="bfd_pj_arch bfd_i386_arch";;
+powerpc*) targ_archs="bfd_rs6000_arch bfd_powerpc_arch" ;;
+rs6000) targ_archs="bfd_rs6000_arch bfd_powerpc_arch" ;;
+s390*) targ_archs=bfd_s390_arch ;;
+sh*) targ_archs=bfd_sh_arch ;;
+sparc*) targ_archs=bfd_sparc_arch ;;
+spu*) targ_archs=bfd_spu_arch ;;
+tilegx*) targ_archs=bfd_tilegx_arch ;;
+tilepro*) targ_archs=bfd_tilepro_arch ;;
+v850*) targ_archs="bfd_v850_arch bfd_v850_rh850_arch" ;;
+x86_64*) targ_archs=bfd_i386_arch ;;
+xtensa*) targ_archs=bfd_xtensa_arch ;;
+xgate) targ_archs=bfd_xgate_arch ;;
+z80|r800) targ_archs=bfd_z80_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.
+#
+# Keep obsolete entries above the START comment, to keep them out of
+# targmatch.h.
+
+case "${targ}" in
+ mips*-dec-bsd*)
+ echo "This target is obsolete and has been removed."
+ exit 1
+ ;;
+
+ mips*-*-mach3*)
+ echo "This target is obsolete and has been removed."
+ exit 1
+ ;;
+
+ mips*-*-pe*)
+ echo "This target is obsolete and has been removed."
+ exit 1
+ ;;
+
+ plugin)
+ targ_defvec=plugin_vec
+ targ_selvecs="plugin_vec"
+ ;;
+
+# START OF targmatch.h
+#ifdef BFD64
+ aarch64-*-elf)
+ targ_defvec=aarch64_elf64_le_vec
+ targ_selvecs="aarch64_elf64_be_vec aarch64_elf32_le_vec aarch64_elf32_be_vec arm_elf32_le_vec arm_elf32_be_vec"
+ want64=true
+ ;;
+ aarch64_be-*-elf)
+ targ_defvec=aarch64_elf64_be_vec
+ targ_selvecs="aarch64_elf64_le_vec aarch64_elf32_le_vec aarch64_elf32_be_vec arm_elf32_be_vec arm_elf32_le_vec"
+ want64=true
+ ;;
+ aarch64-*-linux*)
+ targ_defvec=aarch64_elf64_le_vec
+ targ_selvecs="aarch64_elf64_be_vec aarch64_elf32_le_vec aarch64_elf32_be_vec arm_elf32_le_vec arm_elf32_be_vec"
+ want64=true
+ ;;
+ aarch64_be-*-linux*)
+ targ_defvec=aarch64_elf64_be_vec
+ targ_selvecs="aarch64_elf64_le_vec aarch64_elf32_le_vec aarch64_elf32_be_vec arm_elf32_be_vec arm_elf32_le_vec"
+ want64=true
+ ;;
+ alpha*-*-freebsd* | alpha*-*-kfreebsd*-gnu)
+ targ_defvec=alpha_elf64_fbsd_vec
+ targ_selvecs="alpha_elf64_vec alpha_ecoff_le_vec"
+ want64=true
+ # FreeBSD <= 4.0 supports only the old nonstandard way of ABI labelling.
+ case "${targ}" in
+ alpha*-*-freebsd3* | alpha*-*-freebsd4 | alpha*-*-freebsd4.0*)
+ targ_cflags=-DOLD_FREEBSD_ABI_LABEL ;;
+ esac
+ ;;
+ alpha*-*-netbsd* | alpha*-*-openbsd*)
+ targ_defvec=alpha_elf64_vec
+ targ_selvecs=alpha_ecoff_le_vec
+ want64=true
+ ;;
+ alpha*-*-netware*)
+ targ_defvec=alpha_ecoff_le_vec
+ targ_selvecs=alpha_nlm32_vec
+ want64=true
+ ;;
+ alpha*-*-linux*ecoff*)
+ targ_defvec=alpha_ecoff_le_vec
+ targ_selvecs=alpha_elf64_vec
+ want64=true
+ ;;
+ alpha*-*-linux-* | alpha*-*-elf*)
+ targ_defvec=alpha_elf64_vec
+ targ_selvecs=alpha_ecoff_le_vec
+ want64=true
+ ;;
+ alpha*-*-*vms*)
+ targ_defvec=alpha_vms_vec
+ targ_selvecs=alpha_vms_lib_txt_vec
+ want64=true
+ ;;
+ alpha*-*-*)
+ targ_defvec=alpha_ecoff_le_vec
+ want64=true
+ ;;
+ ia64*-*-freebsd* | ia64*-*-netbsd* | ia64*-*-linux-* | ia64*-*-elf* | ia64*-*-kfreebsd*-gnu)
+ targ_defvec=ia64_elf64_le_vec
+ targ_selvecs="ia64_elf64_be_vec ia64_pei_vec"
+ want64=true
+ ;;
+ ia64*-*-hpux*)
+ targ_defvec=ia64_elf32_hpux_be_vec
+ targ_selvecs="ia64_elf64_hpux_be_vec"
+ want64=true
+ ;;
+ ia64*-*-*vms*)
+ targ_defvec=ia64_elf64_vms_vec
+ targ_selvecs=alpha_vms_lib_txt_vec
+ want64=true
+ ;;
+ sparc64-*-freebsd* | sparc64-*-kfreebsd*-gnu)
+ targ_defvec=sparc_elf64_fbsd_vec
+ targ_selvecs="sparc_elf64_vec sparc_elf32_vec sparc_aout_sunos_be_vec"
+ ;;
+ sparc64-*-netbsd* | sparc64-*-openbsd*)
+ targ_defvec=sparc_elf64_vec
+ targ_selvecs="sparc_elf32_vec sparc_aout_sunos_be_vec"
+ want64=true
+ ;;
+#endif /* BFD64 */
+
+ am34-*-linux* | am33_2.0-*-linux*)
+ targ_defvec=am33_elf32_linux_vec
+ ;;
+
+ arc-*-elf*)
+ targ_defvec=arc_elf32_le_vec
+ targ_selvecs=arc_elf32_be_vec
+ ;;
+
+ arm-*-nacl*)
+ targ_defvec=arm_elf32_nacl_le_vec
+ targ_selvecs="arm_elf32_nacl_be_vec i386_elf32_nacl_vec"
+ targ64_selvecs="x86_64_elf32_nacl_vec x86_64_elf64_nacl_vec"
+ targ_archs="$targ_archs bfd_i386_arch"
+ ;;
+ armeb-*-nacl*)
+ targ_defvec=arm_elf32_nacl_be_vec
+ targ_selvecs="arm_elf32_nacl_le_vec i386_elf32_nacl_vec"
+ targ64_selvecs="x86_64_elf32_nacl_vec x86_64_elf64_nacl_vec"
+ targ_archs="$targ_archs bfd_i386_arch"
+ ;;
+ armeb-*-netbsdelf*)
+ targ_defvec=arm_elf32_be_vec
+ targ_selvecs="arm_elf32_le_vec arm_aout_nbsd_vec"
+ ;;
+ arm-*-netbsdelf*)
+ targ_defvec=arm_elf32_le_vec
+ targ_selvecs="arm_elf32_be_vec arm_aout_nbsd_vec"
+ ;;
+ arm-*-netbsd* | arm-*-openbsd*)
+ targ_defvec=arm_aout_nbsd_vec
+ targ_selvecs="arm_elf32_le_vec arm_elf32_be_vec"
+ targ_underscore=yes
+ ;;
+ arm-*-nto* | nto*arm*)
+ targ_defvec=arm_elf32_le_vec
+ targ_selvecs=arm_elf32_be_vec
+ targ_cflags=-D__QNXTARGET__
+ ;;
+ arm-*-riscix*)
+ targ_defvec=arm_aout_riscix_vec
+ ;;
+ arm-epoc-pe*)
+ targ_defvec=arm_pe_epoc_le_vec
+ targ_selvecs="arm_pe_epoc_le_vec arm_pe_epoc_be_vec arm_pei_epoc_le_vec arm_pei_epoc_be_vec"
+ targ_underscore=no
+ targ_cflags=-DARM_COFF_BUGFIX
+ ;;
+ arm-wince-pe | arm-*-wince | arm*-*-mingw32ce* | arm*-*-cegcc*)
+ targ_defvec=arm_pe_wince_le_vec
+ targ_selvecs="arm_pe_wince_le_vec arm_pe_wince_be_vec arm_pei_wince_le_vec arm_pei_wince_be_vec"
+ targ_underscore=no
+ targ_cflags="-DARM_WINCE -DARM_COFF_BUGFIX"
+ ;;
+ arm-*-pe*)
+ targ_defvec=arm_pe_le_vec
+ targ_selvecs="arm_pe_le_vec arm_pe_be_vec arm_pei_le_vec arm_pei_be_vec"
+ targ_underscore=yes
+ ;;
+ arm-*-aout | armel-*-aout)
+ targ_defvec=arm_aout_le_vec
+ targ_selvecs=arm_aout_be_vec
+ ;;
+ armeb-*-aout)
+ targ_defvec=arm_aout_be_vec
+ targ_selvecs=arm_aout_le_vec
+ ;;
+ arm-*-coff)
+ targ_defvec=arm_coff_le_vec
+ targ_selvecs=arm_coff_be_vec
+ targ_underscore=yes
+ ;;
+ arm-*-rtems*)
+ targ_defvec=arm_elf32_le_vec
+ targ_selvecs=arm_elf32_be_vec
+ ;;
+ armeb-*-elf | arm*b-*-freebsd* | arm*b-*-linux-* | armeb-*-eabi*)
+ targ_defvec=arm_elf32_be_vec
+ targ_selvecs=arm_elf32_le_vec
+ ;;
+ arm-*-kaos*)
+ targ_defvec=arm_elf32_le_vec
+ targ_selvecs=arm_elf32_be_vec
+ ;;
+ arm-*-elf | arm*-*-freebsd* | arm*-*-linux-* | arm*-*-conix* | \
+ arm*-*-uclinux* | arm-*-kfreebsd*-gnu | \
+ arm*-*-eabi* )
+ targ_defvec=arm_elf32_le_vec
+ targ_selvecs=arm_elf32_be_vec
+ ;;
+ arm*-*-vxworks | arm*-*-windiss)
+ targ_defvec=arm_elf32_vxworks_le_vec
+ targ_selvecs=arm_elf32_vxworks_be_vec
+ ;;
+ arm*-*-symbianelf*)
+ targ_defvec=arm_elf32_symbian_le_vec
+ targ_selvecs=arm_elf32_symbian_be_vec
+ ;;
+ arm9e-*-elf)
+ targ_defvec=arm_elf32_le_vec
+ targ_selvecs=arm_elf32_be_vec
+ ;;
+
+ avr-*-*)
+ targ_defvec=avr_elf32_vec
+ ;;
+
+ bfin-*-*)
+ targ_defvec=bfin_elf32_vec
+ targ_selvecs=bfin_elf32_fdpic_vec
+ targ_underscore=yes
+ ;;
+
+ c30-*-*aout* | tic30-*-*aout*)
+ targ_defvec=tic30_aout_vec
+ ;;
+ c30-*-*coff* | tic30-*-*coff*)
+ targ_defvec=tic30_coff_vec
+ ;;
+
+ c4x-*-*coff* | tic4x-*-*coff* | tic4x-*-rtems*)
+ targ_defvec=tic4x_coff1_vec
+ targ_selvecs="tic4x_coff1_beh_vec tic4x_coff2_vec tic4x_coff2_beh_vec tic4x_coff0_vec tic4x_coff0_beh_vec"
+ targ_underscore=yes
+ ;;
+
+ c54x*-*-*coff* | tic54x-*-*coff*)
+ targ_defvec=tic54x_coff1_vec
+ targ_selvecs="tic54x_coff1_beh_vec tic54x_coff2_vec tic54x_coff2_beh_vec tic54x_coff0_vec tic54x_coff0_beh_vec"
+ targ_underscore=yes
+ ;;
+
+ cr16-*-elf* | cr16*-*-uclinux*)
+ targ_defvec=cr16_elf32_vec
+ targ_underscore=yes
+ ;;
+
+ cr16c-*-elf*)
+ targ_defvec=cr16c_elf32_vec
+ targ_underscore=yes
+ ;;
+
+ cris-*-* | crisv32-*-*)
+ targ_defvec=cris_aout_vec
+ targ_selvecs="cris_elf32_us_vec cris_elf32_vec ieee_vec"
+ targ_underscore=yes # Note: not true for cris_elf32_vec.
+ ;;
+
+ crx-*-elf*)
+ targ_defvec=crx_elf32_vec
+ targ_underscore=yes
+ ;;
+
+ d10v-*-*)
+ targ_defvec=d10v_elf32_vec
+ ;;
+
+ dlx-*-elf*)
+ targ_defvec=dlx_elf32_be_vec
+ targ_selvecs="dlx_elf32_be_vec"
+ ;;
+
+ d30v-*-*)
+ targ_defvec=d30v_elf32_vec
+ ;;
+
+ epiphany-*-elf)
+ targ_defvec=epiphany_elf32_vec
+ ;;
+
+ fido-*-elf* )
+ targ_defvec=m68k_elf32_vec
+ targ_selvecs="m68k_coff_vec ieee_vec"
+ ;;
+
+ fr30-*-elf)
+ targ_defvec=fr30_elf32_vec
+ ;;
+
+ frv-*-elf)
+ targ_defvec=frv_elf32_vec
+ targ_selvecs=frv_elf32_fdpic_vec
+ ;;
+
+ frv-*-*linux*)
+ targ_defvec=frv_elf32_fdpic_vec
+ targ_selvecs=frv_elf32_vec
+ ;;
+
+ moxie-*-elf | moxie-*-rtems* | moxie-*-uclinux)
+ targ_defvec=moxie_elf32_be_vec
+ targ_selvecs=moxie_elf32_le_vec
+ ;;
+
+ moxie-*-moxiebox*)
+ targ_defvec=moxie_elf32_le_vec
+ ;;
+
+ h8300*-*-rtemscoff*)
+ targ_defvec=h8300_coff_vec
+ targ_underscore=yes
+ ;;
+
+ h8300*-*-elf | h8300*-*-rtems*)
+ targ_defvec=h8300_elf32_vec
+ targ_underscore=yes
+ ;;
+
+ h8300*-*-*)
+ targ_defvec=h8300_coff_vec
+ targ_underscore=yes
+ ;;
+
+ h8500-*-*)
+ targ_defvec=h8500_coff_vec
+ targ_underscore=yes
+ ;;
+
+#ifdef BFD64
+ hppa*64*-*-linux-*)
+ targ_defvec=hppa_elf64_linux_vec
+ targ_selvecs=hppa_elf64_vec
+ want64=true
+ ;;
+ hppa*64*-*-hpux11*)
+ targ_defvec=hppa_elf64_vec
+ targ_selvecs=hppa_elf64_linux_vec
+ targ_cflags=-DHPUX_LARGE_AR_IDS
+ want64=true
+ ;;
+#endif
+
+ hppa*-*-linux-*)
+ targ_defvec=hppa_elf32_linux_vec
+ targ_selvecs=hppa_elf32_vec
+ ;;
+ hppa*-*-netbsd*)
+ targ_defvec=hppa_elf32_nbsd_vec
+ targ_selvecs="hppa_elf32_vec hppa_elf32_linux_vec"
+ ;;
+ hppa*-*-*elf* | hppa*-*-lites* | hppa*-*-sysv4* | hppa*-*-openbsd*)
+ targ_defvec=hppa_elf32_vec
+ targ_selvecs=hppa_elf32_linux_vec
+ ;;
+
+ hppa*-*-bsd*)
+ targ_defvec=hppa_som_vec
+ targ_selvecs=hppa_elf32_vec
+ ;;
+ hppa*-*-hpux* | hppa*-*-hiux* | hppa*-*-mpeix*)
+ targ_defvec=hppa_som_vec
+ ;;
+ hppa*-*-osf*)
+ targ_defvec=hppa_som_vec
+ targ_selvecs=hppa_elf32_vec
+ ;;
+
+ i370-*-*)
+ targ_defvec=i370_elf32_vec
+ targ_selvecs="i370_elf32_vec"
+ ;;
+ i[3-7]86-*-sco3.2v5*coff)
+ targ_defvec=i386_coff_vec
+ targ_selvecs=i386_elf32_vec
+ ;;
+ i[3-7]86-*-sysv4* | i[3-7]86-*-unixware* | \
+ i[3-7]86-*-elf | i[3-7]86-*-sco3.2v5* | \
+ i[3-7]86-*-dgux* | i[3-7]86-*-sysv5*)
+ targ_defvec=i386_elf32_vec
+ targ_selvecs=i386_coff_vec
+ ;;
+ i[3-7]86-*-solaris2*)
+ targ_defvec=i386_elf32_sol2_vec
+ targ_selvecs="i386_coff_vec"
+ targ64_selvecs="x86_64_elf64_sol2_vec l1om_elf64_vec k1om_elf64_vec"
+ want64=true
+ ;;
+#ifdef BFD64
+ x86_64-*-solaris2*)
+ targ_defvec=i386_elf32_sol2_vec
+ targ_selvecs="x86_64_elf64_sol2_vec l1om_elf64_vec k1om_elf64_vec i386_coff_vec"
+ want64=true
+ ;;
+#endif
+ i[3-7]86-*-kaos*)
+ targ_defvec=i386_elf32_vec
+ targ_selvecs=i386_elf32_vec
+ ;;
+ i[3-7]86-*-nto*)
+ targ_defvec=i386_elf32_vec
+ targ_selvecs=i386_coff_vec
+ ;;
+ i[3-7]86-*-aros*)
+ targ_defvec=i386_elf32_vec
+ ;;
+ i[3-7]86-*-chorus*)
+ targ_defvec=i386_elf32_vec
+ ;;
+ i[3-7]86-*-dicos*)
+ targ_defvec=i386_elf32_vec
+ targ64_selvecs="x86_64_elf64_vec l1om_elf64_vec k1om_elf64_vec"
+ ;;
+ *-*-msdosdjgpp* | *-*-go32* )
+ targ_defvec=i386_coff_go32_vec
+ targ_selvecs="i386_coff_go32stubbed_vec i386_aout_vec"
+ ;;
+ i[3-7]86-*-sysv* | i[3-7]86-*-isc* | i[3-7]86-*-sco* | i[3-7]86-*-coff | \
+ i[3-7]86-*-aix*)
+ targ_defvec=i386_coff_vec
+ ;;
+ i[3-7]86-*-rtems*)
+ targ_defvec=i386_elf32_vec
+ targ_selvecs="i386_coff_vec i386_aout_vec"
+ ;;
+ i[3-7]86-*-darwin* | i[3-7]86-*-macos10* | i[3-7]86-*-rhapsody*)
+ targ_defvec=i386_mach_o_vec
+ targ_selvecs="mach_o_le_vec mach_o_be_vec mach_o_fat_vec pef_vec pef_xlib_vec sym_vec"
+ targ64_selvecs=x86_64_mach_o_vec
+ targ_archs="$targ_archs bfd_powerpc_arch bfd_rs6000_arch"
+ ;;
+ i[3-7]86-sequent-bsd*)
+ targ_defvec=i386_aout_dynix_vec
+ targ_underscore=yes
+ ;;
+ i[3-7]86-*-bsd*)
+ targ_defvec=i386_aout_bsd_vec
+ targ_underscore=yes
+ ;;
+ i[3-7]86-*-dragonfly*)
+ targ_defvec=i386_elf32_vec
+ targ64_selvecs="x86_64_elf64_vec l1om_elf64_vec k1om_elf64_vec"
+ ;;
+ i[3-7]86-*-freebsdaout* | i[3-7]86-*-freebsd[12].* | \
+ i[3-7]86-*-freebsd[12])
+ targ_defvec=i386_aout_fbsd_vec
+ targ_selvecs=i386_aout_bsd_vec
+ targ_underscore=yes
+ ;;
+ i[3-7]86-*-freebsd* | i[3-7]86-*-kfreebsd*-gnu)
+ targ_defvec=i386_elf32_fbsd_vec
+ targ_selvecs="i386_elf32_vec i386_pei_vec i386_coff_vec"
+ targ64_selvecs="x86_64_elf64_fbsd_vec x86_64_elf64_vec x86_64_pei_vec l1om_elf64_vec l1om_elf64_fbsd_vec k1om_elf64_vec k1om_elf64_fbsd_vec"
+ # FreeBSD <= 4.0 supports only the old nonstandard way of ABI labelling.
+ case "${targ}" in
+ i[3-7]86-*-freebsd3* | i[3-7]86-*-freebsd4 | i[3-7]86-*-freebsd4.0*)
+ targ_cflags=-DOLD_FREEBSD_ABI_LABEL ;;
+ esac
+ ;;
+ i[3-7]86-*-netbsdelf* | i[3-7]86-*-netbsd*-gnu* | i[3-7]86-*-knetbsd*-gnu)
+ targ_defvec=i386_elf32_vec
+ targ_selvecs=i386_aout_nbsd_vec
+ targ64_selvecs="x86_64_elf64_vec l1om_elf64_vec k1om_elf64_vec"
+ ;;
+ i[3-7]86-*-netbsdpe*)
+ targ_defvec=i386_pe_vec
+ targ_selvecs="i386_pe_vec i386_pei_vec i386_elf32_vec"
+ ;;
+ i[3-7]86-*-netbsdaout* | i[3-7]86-*-netbsd* | \
+ i[3-7]86-*-openbsd[0-2].* | i[3-7]86-*-openbsd3.[0-3])
+ targ_defvec=i386_aout_nbsd_vec
+ targ_selvecs="i386_elf32_vec i386_aout_bsd_vec"
+ targ_underscore=yes
+ ;;
+ i[3-7]86-*-openbsd*)
+ targ_defvec=i386_elf32_vec
+ targ_selvecs=i386_aout_nbsd_vec
+ ;;
+ i[3-7]86-*-netware*)
+ targ_defvec=i386_elf32_vec
+ targ_selvecs="i386_nlm32_vec i386_coff_vec i386_aout_vec"
+ ;;
+ i[3-7]86-*-linux*aout*)
+ targ_defvec=i386_aout_linux_vec
+ targ_selvecs=i386_elf32_vec
+ targ_underscore=yes
+ ;;
+ i[3-7]86-*-linux-*)
+ targ_defvec=i386_elf32_vec
+ targ_selvecs="i386_aout_linux_vec i386_pei_vec"
+ targ64_selvecs="x86_64_elf64_vec x86_64_elf32_vec x86_64_pei_vec l1om_elf64_vec k1om_elf64_vec"
+ ;;
+ i[3-7]86-*-nacl*)
+ targ_defvec=i386_elf32_nacl_vec
+ targ_selvecs="arm_elf32_nacl_be_vec arm_elf32_nacl_le_vec"
+ targ64_selvecs="x86_64_elf64_nacl_vec x86_64_elf32_nacl_vec"
+ targ_archs="$targ_archs bfd_arm_arch"
+ ;;
+#ifdef BFD64
+ x86_64-*-darwin*)
+ targ_defvec=x86_64_mach_o_vec
+ targ_selvecs="i386_mach_o_vec mach_o_le_vec mach_o_be_vec mach_o_fat_vec pef_vec pef_xlib_vec sym_vec"
+ targ_archs="$targ_archs bfd_powerpc_arch bfd_rs6000_arch"
+ want64=true
+ ;;
+ x86_64-*-dicos*)
+ targ_defvec=x86_64_elf64_vec
+ targ_selvecs="i386_elf32_vec l1om_elf64_vec k1om_elf64_vec"
+ want64=true
+ ;;
+ x86_64-*-elf*)
+ targ_defvec=x86_64_elf64_vec
+ targ_selvecs="i386_elf32_vec x86_64_elf32_vec l1om_elf64_vec k1om_elf64_vec"
+ want64=true
+ ;;
+ x86_64-*-dragonfly*)
+ targ_defvec=x86_64_elf64_vec
+ targ_selvecs="i386_elf32_vec l1om_elf64_vec k1om_elf64_vec"
+ want64=true
+ ;;
+ x86_64-*-freebsd* | x86_64-*-kfreebsd*-gnu)
+ targ_defvec=x86_64_elf64_fbsd_vec
+ targ_selvecs="i386_elf32_fbsd_vec i386_coff_vec i386_pei_vec x86_64_pei_vec i386_elf32_vec x86_64_elf64_vec l1om_elf64_vec l1om_elf64_fbsd_vec k1om_elf64_vec k1om_elf64_fbsd_vec"
+ want64=true
+ ;;
+ x86_64-*-netbsd* | x86_64-*-openbsd*)
+ targ_defvec=x86_64_elf64_vec
+ targ_selvecs="i386_elf32_vec i386_aout_nbsd_vec i386_coff_vec i386_pei_vec x86_64_pei_vec l1om_elf64_vec k1om_elf64_vec"
+ want64=true
+ ;;
+ x86_64-*-linux-*)
+ targ_defvec=x86_64_elf64_vec
+ targ_selvecs="i386_elf32_vec x86_64_elf32_vec i386_aout_linux_vec i386_pei_vec x86_64_pei_vec l1om_elf64_vec k1om_elf64_vec"
+ want64=true
+ ;;
+ x86_64-*-nacl*)
+ targ_defvec=x86_64_elf32_nacl_vec
+ targ_selvecs="i386_elf32_nacl_vec x86_64_elf64_nacl_vec arm_elf32_nacl_be_vec arm_elf32_nacl_le_vec"
+ targ_archs="$targ_archs bfd_arm_arch"
+ want64=true
+ ;;
+ x86_64-*-mingw* | x86_64-*-pe | x86_64-*-pep | x86_64-*-cygwin)
+ targ_defvec=x86_64_pe_vec
+ targ_selvecs="x86_64_pe_vec x86_64_pei_vec x86_64_pe_be_vec x86_64_elf64_vec l1om_elf64_vec k1om_elf64_vec i386_pe_vec i386_pei_vec i386_elf32_vec"
+ want64=true
+ targ_underscore=no
+ ;;
+ x86_64-*-rdos*)
+ targ_defvec=x86_64_elf64_vec
+ want64=true
+ ;;
+#endif
+ i[3-7]86-*-lynxos*)
+ targ_defvec=i386_elf32_vec
+ targ_selvecs="i386_coff_lynx_vec i386_aout_lynx_vec"
+ ;;
+ i[3-7]86-*-gnu*)
+ targ_defvec=i386_elf32_vec
+ ;;
+ i[3-7]86-*-mach* | i[3-7]86-*-osf1mk*)
+ targ_defvec=i386_aout_mach3_vec
+ targ_cflags=-DSTAT_FOR_EXEC
+ targ_underscore=yes
+ ;;
+ i[3-7]86-*-os9k)
+ targ_defvec=i386_aout_os9k_vec
+ ;;
+ i[3-7]86-*-msdos*)
+ targ_defvec=i386_aout_vec
+ targ_selvecs=i386_msdos_vec
+ ;;
+ i[3-7]86-*-moss*)
+ targ_defvec=i386_elf32_vec
+ targ_selvecs="i386_msdos_vec i386_aout_vec"
+ ;;
+ i[3-7]86-*-beospe*)
+ targ_defvec=i386_pe_vec
+ targ_selvecs="i386_pe_vec i386_pei_vec"
+ ;;
+ i[3-7]86-*-beoself* | i[3-7]86-*-beos*)
+ targ_defvec=i386_elf32_vec
+ targ_selvecs="i386_pe_vec i386_pei_vec"
+ ;;
+ i[3-7]86-*-interix*)
+ targ_defvec=i386_pei_vec
+ targ_selvecs="i386_pe_vec"
+ # FIXME: This should eventually be checked at runtime.
+ targ_cflags=-DSTRICT_PE_FORMAT
+ ;;
+ i[3-7]86-*-rdos*)
+ targ_defvec=i386_elf32_vec
+ targ_selvecs=i386_coff_vec
+ ;;
+ i[3-7]86-*-mingw32* | i[3-7]86-*-cygwin* | i[3-7]86-*-winnt | i[3-7]86-*-pe)
+ targ_defvec=i386_pe_vec
+ targ_selvecs="i386_pe_vec i386_pei_vec i386_elf32_vec"
+ targ_underscore=yes
+ ;;
+ i[3-7]86-none-*)
+ targ_defvec=i386_coff_vec
+ ;;
+ i[3-7]86-*-aout* | i[3-7]86*-*-vsta*)
+ targ_defvec=i386_aout_vec
+ ;;
+ i[3-7]86-*-vxworks*)
+ targ_defvec=i386_elf32_vxworks_vec
+ targ_underscore=yes
+ ;;
+ i[3-7]86-*-chaos)
+ targ_defvec=i386_elf32_vec
+ targ_selfvecs=i386chaos_vec
+ ;;
+
+ i860-*-mach3* | i860-*-osf1* | i860-*-coff*)
+ targ_defvec=i860_coff_vec
+ ;;
+ i860-stardent-sysv4* | i860-stardent-elf*)
+ targ_defvec=i860_elf32_le_vec
+ targ_selvecs="i860_elf32_vec i860_elf32_le_vec"
+ ;;
+ i860-*-sysv4* | i860-*-elf*)
+ targ_defvec=i860_elf32_vec
+ ;;
+
+ i960-*-vxworks4* | i960-*-vxworks5.0)
+ targ_defvec=bout_le_vec
+ targ_selvecs="bout_be_vec icoff_le_vec icoff_be_vec ieee_vec"
+ targ_underscore=yes
+ ;;
+ i960-*-vxworks5.* | i960-*-coff* | i960-*-sysv*)
+ targ_defvec=icoff_le_vec
+ targ_selvecs="icoff_be_vec bout_le_vec bout_be_vec ieee_vec"
+ targ_underscore=yes
+ ;;
+ i960-*-vxworks* | i960-*-aout* | i960-*-bout* | i960-*-nindy*)
+ targ_defvec=bout_le_vec
+ targ_selvecs="bout_be_vec icoff_le_vec icoff_be_vec ieee_vec"
+ targ_underscore=yes
+ ;;
+ i960-*-elf*)
+ targ_defvec=i960_elf32_vec
+ targ_selvecs="icoff_le_vec icoff_be_vec"
+ ;;
+
+ ip2k-*-elf)
+ targ_defvec=ip2k_elf32_vec
+ ;;
+
+ iq2000-*-elf)
+ targ_defvec=iq2000_elf32_vec
+ ;;
+
+ lm32-*-elf | lm32-*-rtems*)
+ targ_defvec=lm32_elf32_vec
+ targ_selvecs=lm32_elf32_fdpic_vec
+ ;;
+
+ lm32-*-*linux*)
+ targ_defvec=lm32_elf32_fdpic_vec
+ targ_selvecs=lm32_elf32_vec
+ ;;
+
+ m32c-*-elf | m32c-*-rtems*)
+ targ_defvec=m32c_elf32_vec
+ ;;
+
+ m32r*le-*-linux*)
+ targ_defvec=m32r_elf32_linux_le_vec
+ targ_selvecs="m32r_elf32_linux_vec m32r_elf32_linux_le_vec"
+ ;;
+ m32r*-*-linux*)
+ targ_defvec=m32r_elf32_linux_vec
+ targ_selvecs="m32r_elf32_linux_vec m32r_elf32_linux_le_vec"
+ ;;
+ m32r*le-*-*)
+ targ_defvec=m32r_elf32_le_vec
+ targ_selvecs="m32r_elf32_vec m32r_elf32_le_vec"
+ ;;
+ m32r-*-*)
+ targ_defvec=m32r_elf32_vec
+ ;;
+
+ m68hc11-*-* | m6811-*-*)
+ targ_defvec=m68hc11_elf32_vec
+ targ_selvecs="m68hc11_elf32_vec m68hc12_elf32_vec"
+ ;;
+ m68hc12-*-* | m6812-*-*)
+ targ_defvec=m68hc12_elf32_vec
+ targ_selvecs="m68hc11_elf32_vec m68hc12_elf32_vec"
+ ;;
+
+ m68*-motorola-sysv*)
+ targ_defvec=m68k_coff_sysv_vec
+ ;;
+ m68*-hp-bsd*)
+ targ_defvec=m68k_aout_hp300bsd_vec
+ targ_underscore=yes
+ ;;
+ m68*-*-aout*)
+ targ_defvec=aout0_be_vec
+ # We include core_cisco_be_vec here, rather than making a separate cisco
+ # configuration, so that cisco-core.c gets routinely tested at
+ # least for compilation.
+ targ_selvecs="core_cisco_be_vec ieee_vec"
+ targ_underscore=yes
+ ;;
+ m68*-*-elf* | m68*-*-sysv4* | m68*-*-uclinux*)
+ targ_defvec=m68k_elf32_vec
+ targ_selvecs="m68k_coff_vec ieee_vec"
+ ;;
+ m68*-*-rtems*)
+ targ_defvec=m68k_elf32_vec
+ targ_selvecs="m68k_coff_vec m68k_versados_vec ieee_vec aout0_be_vec"
+ ;;
+ m68*-*-coff* | m68*-*-sysv*)
+ targ_defvec=m68k_coff_vec
+ targ_selvecs="m68k_coff_vec m68k_versados_vec ieee_vec"
+ ;;
+ m68*-*-hpux*)
+ targ_defvec=m68k_aout_hp300hpux_vec
+ targ_underscore=yes
+ ;;
+ m68*-*-linux*aout*)
+ targ_defvec=m68k_aout_linux_vec
+ targ_selvecs=m68k_elf32_vec
+ targ_underscore=yes
+ ;;
+ m68*-*-linux-*)
+ targ_defvec=m68k_elf32_vec
+ targ_selvecs=m68k_aout_linux_vec
+ ;;
+ m68*-*-gnu*)
+ targ_defvec=m68k_elf32_vec
+ # targ_selvecs=m68kmach3_vec
+ # targ_cflags=-DSTAT_FOR_EXEC
+ ;;
+ m68*-hp*-netbsd*)
+ targ_defvec=m68k_aout_4knbsd_vec
+ targ_selvecs="m68k_aout_nbsd_vec m68k_aout_hp300bsd_vec sparc_aout_sunos_be_vec"
+ targ_underscore=yes
+ ;;
+ m68*-*-netbsdelf*)
+ targ_defvec=m68k_elf32_vec
+ targ_selvecs="m68k_aout_nbsd_vec m68k_aout_4knbsd_vec m68k_aout_hp300bsd_vec sparc_aout_sunos_be_vec"
+ ;;
+ m68*-*-netbsdaout* | m68*-*-netbsd*)
+ targ_defvec=m68k_aout_nbsd_vec
+ targ_selvecs="m68k_aout_4knbsd_vec m68k_elf32_vec m68k_aout_hp300bsd_vec sparc_aout_sunos_be_vec"
+ targ_underscore=yes
+ ;;
+ m68*-*-openbsd*)
+ targ_defvec=m68k_aout_nbsd_vec
+ targ_selvecs="m68k_aout_4knbsd_vec m68k_aout_hp300bsd_vec sparc_aout_sunos_be_vec"
+ targ_underscore=yes
+ ;;
+ m68*-*-sunos* | m68*-*-os68k* | m68*-*-vxworks* | m68*-netx-* | \
+ m68*-*-bsd* | m68*-*-vsta*)
+ targ_defvec=sparc_aout_sunos_be_vec
+ targ_underscore=yes
+ ;;
+ m68*-ericsson-*)
+ targ_defvec=sparc_aout_sunos_be_vec
+ targ_selvecs="m68k_coff_vec m68k_versados_vec tekhex_vec"
+ targ_underscore=yes
+ ;;
+ m68*-cbm-*)
+ targ_defvec=m68k_elf32_vec
+ targ_selvecs=m68k_coff_vec
+ ;;
+ m68*-*-psos*)
+ targ_defvec=m68k_elf32_vec
+ targ_selvecs=ieee_vec
+ targ_underscore=yes
+ ;;
+
+ m88*-harris-cxux* | m88*-*-dgux* | m88*-*-sysv4*)
+ targ_defvec=m88k_elf32_vec
+ targ_selvecs=m88k_coff_bcs_vec
+ ;;
+ m88*-*-mach3*)
+ targ_defvec=m88k_aout_mach3_vec
+ targ_cflags=-DSTAT_FOR_EXEC
+ ;;
+ m88*-*-openbsd*)
+ targ_defvec=m88k_aout_obsd_vec
+ targ_underscore=yes
+ ;;
+ m88*-*-*)
+ targ_defvec=m88k_coff_bcs_vec
+ targ_underscore=yes
+ ;;
+
+ mcore-*-elf)
+ targ_defvec=mcore_elf32_be_vec
+ targ_selvecs="mcore_elf32_be_vec mcore_elf32_le_vec"
+ ;;
+ mcore-*-pe)
+ targ_defvec=mcore_pe_be_vec
+ targ_selvecs="mcore_pe_be_vec mcore_pe_le_vec mcore_pei_be_vec mcore_pei_le_vec"
+ ;;
+
+ mep-*-elf)
+ targ_defvec=mep_elf32_vec
+ targ_selvecs=mep_elf32_le_vec
+ ;;
+
+ metag-*-*)
+ targ_defvec=metag_elf32_vec
+ targ_underscore=yes
+ ;;
+
+ microblazeel*-*)
+ targ_defvec=microblaze_elf32_le_vec
+ targ_selvecs=microblaze_elf32_vec
+ ;;
+
+ microblaze*-*)
+ targ_defvec=microblaze_elf32_vec
+ targ_selvecs=microblaze_elf32_le_vec
+ ;;
+
+ mips*-big-*)
+ targ_defvec=mips_ecoff_be_vec
+ targ_selvecs=mips_ecoff_le_vec
+ ;;
+#ifdef BFD64
+ mips*el-*-netbsd*)
+ targ_defvec=mips_elf32_trad_le_vec
+ targ_selvecs="mips_elf32_trad_be_vec mips_elf64_trad_be_vec mips_elf64_trad_le_vec mips_ecoff_le_vec mips_ecoff_be_vec"
+ ;;
+ mips*-*-netbsd*)
+ targ_defvec=mips_elf32_trad_be_vec
+ targ_selvecs="mips_elf32_trad_le_vec mips_elf64_trad_be_vec mips_elf64_trad_le_vec mips_ecoff_be_vec mips_ecoff_le_vec"
+ ;;
+#endif
+ mips*-dec-* | mips*el-*-ecoff*)
+ targ_defvec=mips_ecoff_le_vec
+ targ_selvecs=mips_ecoff_be_vec
+ ;;
+ mips*-*-ecoff*)
+ targ_defvec=mips_ecoff_be_vec
+ targ_selvecs=mips_ecoff_le_vec
+ ;;
+#ifdef BFD64
+ mips*-*-irix6*)
+ targ_defvec=mips_elf32_n_be_vec
+ targ_selvecs="mips_elf32_n_le_vec mips_elf32_be_vec mips_elf32_le_vec mips_elf64_be_vec mips_elf64_le_vec"
+ ;;
+ mips64*-ps2-elf*)
+ targ_defvec=mips_elf32_n_le_vec
+ targ_selvecs="mips_elf32_n_le_vec mips_elf32_n_be_vec mips_elf32_be_vec mips_elf32_le_vec mips_elf64_be_vec mips_elf64_le_vec"
+ ;;
+ mips*-ps2-elf*)
+ targ_defvec=mips_elf32_le_vec
+ targ_selvecs="mips_elf32_be_vec mips_elf32_le_vec mips_elf64_be_vec mips_elf64_le_vec"
+ ;;
+ mips*-*-irix5*)
+ targ_defvec=mips_elf32_be_vec
+ targ_selvecs="mips_elf32_le_vec mips_ecoff_be_vec mips_ecoff_le_vec"
+ ;;
+#endif
+ mips*-sgi-* | mips*-*-bsd*)
+ targ_defvec=mips_ecoff_be_vec
+ targ_selvecs=mips_ecoff_le_vec
+ ;;
+ mips*-*-lnews*)
+ targ_defvec=mips_ecoff_bele_vec
+ targ_selvecs="mips_ecoff_le_vec mips_ecoff_be_vec"
+ ;;
+#ifdef BFD64
+ mips*-*-sysv4*)
+ targ_defvec=mips_elf32_trad_be_vec
+ targ_selvecs="mips_elf32_trad_le_vec mips_ecoff_be_vec mips_ecoff_le_vec"
+ ;;
+#endif
+ mips*-*-sysv* | mips*-*-riscos*)
+ targ_defvec=mips_ecoff_be_vec
+ targ_selvecs=mips_ecoff_le_vec
+ ;;
+#ifdef BFD64
+ mips*el-*-vxworks*)
+ targ_defvec=mips_elf32_vxworks_le_vec
+ targ_selvecs="mips_elf32_le_vec mips_elf32_vxworks_be_vec mips_elf32_be_vec mips_elf64_be_vec mips_elf64_le_vec"
+ ;;
+ mips*-*-vxworks*)
+ targ_defvec=mips_elf32_vxworks_be_vec
+ targ_selvecs="mips_elf32_be_vec mips_elf32_vxworks_le_vec mips_elf32_be_vec mips_elf64_be_vec mips_elf64_le_vec"
+ ;;
+ mips*el-sde-elf*)
+ targ_defvec=mips_elf32_trad_le_vec
+ targ_selvecs="mips_elf32_trad_be_vec mips_elf32_ntrad_be_vec mips_elf32_ntrad_le_vec mips_elf64_trad_be_vec mips_elf64_trad_le_vec"
+ ;;
+ mips*-sde-elf* | mips*-mti-elf* | mips*-img-elf*)
+ targ_defvec=mips_elf32_trad_be_vec
+ targ_selvecs="mips_elf32_trad_le_vec mips_elf32_ntrad_be_vec mips_elf32_ntrad_le_vec mips_elf64_trad_be_vec mips_elf64_trad_le_vec"
+ ;;
+ mips*el-*-elf* | mips*el-*-vxworks* | mips*-*-chorus*)
+ targ_defvec=mips_elf32_le_vec
+ targ_selvecs="mips_elf32_be_vec mips_elf64_be_vec mips_elf64_le_vec"
+ ;;
+ mips*-*-elf* | mips*-*-rtems* | mips*-*-vxworks | mips*-*-windiss)
+ targ_defvec=mips_elf32_be_vec
+ targ_selvecs="mips_elf32_le_vec mips_elf64_be_vec mips_elf64_le_vec"
+ ;;
+ mips*-*-none)
+ targ_defvec=mips_elf32_be_vec
+ targ_selvecs="mips_elf32_le_vec mips_elf64_be_vec mips_elf64_le_vec"
+ ;;
+ mips64*-*-openbsd*)
+ targ_defvec=mips_elf64_trad_be_vec
+ targ_selvecs="mips_elf32_ntrad_le_vec mips_elf32_ntrad_be_vec mips_elf32_trad_le_vec mips_elf32_trad_be_vec mips_elf64_trad_le_vec"
+ ;;
+ mips*el-*-openbsd*)
+ targ_defvec=mips_elf32_le_vec
+ targ_selvecs="mips_elf32_be_vec mips_elf64_be_vec mips_elf64_le_vec mips_ecoff_le_vec mips_ecoff_be_vec"
+ ;;
+ mips*-*-openbsd*)
+ targ_defvec=mips_elf32_be_vec
+ targ_selvecs="mips_elf32_le_vec mips_elf64_be_vec mips_elf64_le_vec mips_ecoff_be_vec mips_ecoff_le_vec"
+ ;;
+ mips64*el-*-linux*)
+ targ_defvec=mips_elf32_ntrad_le_vec
+ targ_selvecs="mips_elf32_ntrad_be_vec mips_elf32_trad_le_vec mips_elf32_trad_be_vec mips_elf64_trad_le_vec mips_elf64_trad_be_vec"
+ ;;
+ mips64*-*-linux*)
+ targ_defvec=mips_elf32_ntrad_be_vec
+ targ_selvecs="mips_elf32_ntrad_le_vec mips_elf32_trad_be_vec mips_elf32_trad_le_vec mips_elf64_trad_be_vec mips_elf64_trad_le_vec"
+ ;;
+ mips*el-*-linux*)
+ targ_defvec=mips_elf32_trad_le_vec
+ targ_selvecs="mips_elf32_trad_be_vec mips_ecoff_le_vec mips_ecoff_be_vec mips_elf32_ntrad_le_vec mips_elf64_trad_le_vec mips_elf32_ntrad_be_vec mips_elf64_trad_be_vec"
+ ;;
+ mips*-*-linux*)
+ targ_defvec=mips_elf32_trad_be_vec
+ targ_selvecs="mips_elf32_trad_le_vec mips_ecoff_be_vec mips_ecoff_le_vec mips_elf32_ntrad_be_vec mips_elf64_trad_be_vec mips_elf32_ntrad_le_vec mips_elf64_trad_le_vec"
+ ;;
+ mips64*el-*-freebsd* | mips64*el-*-kfreebsd*-gnu)
+ # FreeBSD vectors
+ targ_defvec=mips_elf32_ntradfbsd_le_vec
+ targ_selvecs="mips_elf32_ntradfbsd_be_vec mips_elf32_tradfbsd_le_vec mips_elf32_tradfbsd_be_vec mips_elf64_tradfbsd_le_vec mips_elf64_tradfbsd_be_vec"
+ # Generic vectors
+ targ_selvecs="${targ_selvecs} mips_elf32_ntrad_le_vec mips_elf32_ntrad_be_vec mips_elf32_trad_le_vec mips_elf32_trad_be_vec mips_elf64_trad_le_vec mips_elf64_trad_be_vec"
+ ;;
+ mips64*-*-freebsd* | mips64*-*-kfreebsd*-gnu)
+ # FreeBSD vectors
+ targ_defvec=mips_elf32_ntradfbsd_be_vec
+ targ_selvecs="mips_elf32_ntradfbsd_le_vec mips_elf32_tradfbsd_be_vec mips_elf32_tradfbsd_le_vec mips_elf64_tradfbsd_be_vec mips_elf64_tradfbsd_le_vec"
+ # Generic vectors
+ targ_selvecs="${targ_selvecs} mips_elf32_ntrad_be_vec mips_elf32_ntrad_le_vec mips_elf32_trad_be_vec mips_elf32_trad_le_vec mips_elf64_trad_be_vec mips_elf64_trad_le_vec"
+ ;;
+ mips*el-*-freebsd* | mips*el-*-kfreebsd*-gnu)
+ # FreeBSD vectors
+ targ_defvec=mips_elf32_tradfbsd_le_vec
+ targ_selvecs="mips_elf32_tradfbsd_be_vec mips_elf32_ntradfbsd_le_vec mips_elf64_tradfbsd_le_vec mips_elf32_ntradfbsd_be_vec mips_elf64_tradfbsd_be_vec"
+ # Generic vectors
+ targ_selvecs="${targ_selvecs} mips_elf32_trad_le_vec mips_elf32_trad_be_vec mips_elf32_ntrad_le_vec mips_elf64_trad_le_vec mips_elf32_ntrad_be_vec mips_elf64_trad_be_vec"
+ ;;
+ mips*-*-freebsd* | mips*-*-kfreebsd*-gnu)
+ # FreeBSD vectors
+ targ_defvec=mips_elf32_tradfbsd_be_vec
+ targ_selvecs="mips_elf32_tradfbsd_le_vec mips_elf32_ntradfbsd_be_vec mips_elf64_tradfbsd_be_vec mips_elf32_ntradfbsd_le_vec mips_elf64_tradfbsd_le_vec"
+ # Generic vectors
+ targ_selvecs="${targ_selvecs} mips_elf32_trad_be_vec mips_elf32_trad_le_vec mips_elf32_ntrad_be_vec mips_elf64_trad_be_vec mips_elf32_ntrad_le_vec mips_elf64_trad_le_vec"
+ ;;
+ mmix-*-*)
+ targ_defvec=mmix_elf64_vec
+ targ_selvecs=mmix_mmo_vec
+ want64=true
+ ;;
+#endif
+ mn10200-*-*)
+ targ_defvec=mn10200_elf32_vec
+ ;;
+
+ mn10300-*-*)
+ targ_defvec=mn10300_elf32_vec
+ targ_underscore=yes
+ ;;
+
+ mt-*-elf)
+ targ_defvec=mt_elf32_vec
+ ;;
+
+ msp430-*-*)
+ targ_defvec=msp430_elf32_vec
+ targ_selvecs=msp430_elf32_ti_vec
+ ;;
+
+ nds32*le-*-linux*)
+ targ_defvec=nds32_elf32_linux_le_vec
+ targ_selvecs=nds32_elf32_linux_be_vec
+ ;;
+
+ nds32*be-*-linux*)
+ targ_defvec=nds32_elf32_linux_be_vec
+ targ_selvecs=nds32_elf32_linux_le_vec
+ ;;
+
+ nds32*le-*-*)
+ targ_defvec=nds32_elf32_le_vec
+ targ_selvecs=nds32_elf32_be_vec
+ ;;
+
+ nds32*be-*-*)
+ targ_defvec=nds32_elf32_be_vec
+ targ_selvecs=nds32_elf32_le_vec
+ ;;
+
+ ns32k-pc532-mach* | ns32k-pc532-ux*)
+ targ_defvec=ns32k_aout_pc532mach_vec
+ targ_underscore=yes
+ ;;
+ ns32k-*-netbsd* | ns32k-*-lites* | ns32k-*-openbsd*)
+ targ_defvec=ns32k_aout_pc532nbsd_vec
+ targ_underscore=yes
+ ;;
+
+ nios2eb-*-*)
+ targ_defvec=nios2_elf32_be_vec
+ targ_selvecs=nios2_elf32_le_vec
+ ;;
+
+ nios2el-*-*)
+ targ_defvec=nios2_elf32_le_vec
+ targ_selvecs=nios2_elf32_be_vec
+ ;;
+
+ nios2-*-*)
+ targ_defvec=nios2_elf32_le_vec
+ targ_selvecs=nios2_elf32_be_vec
+ ;;
+
+ or1k-*-elf | or1k-*-linux* | or1k-*-rtems*)
+ targ_defvec=or1k_elf32_vec
+ ;;
+
+ or1knd-*-elf | or1knd-*-linux* | or1knd-*-rtems*)
+ targ_defvec=or1k_elf32_vec
+ ;;
+
+ pdp11-*-*)
+ targ_defvec=pdp11_aout_vec
+ targ_underscore=yes
+ ;;
+
+ pj-*-*)
+ targ_defvec=pj_elf32_vec
+ targ_selvecs="pj_elf32_vec pj_elf32_le_vec"
+ ;;
+
+ pjl-*-*)
+ targ_defvec=pj_elf32_le_vec
+ targ_selvecs="pj_elf32_le_vec pj_elf32_vec i386_elf32_vec"
+ ;;
+
+ powerpc-*-aix5.[01] | rs6000-*-aix5.[01])
+ targ_defvec=rs6000_xcoff_vec
+ targ_selvecs="rs6000_xcoff64_aix_vec"
+ want64=true
+ ;;
+#ifdef BFD64
+ powerpc64-*-aix5.[01] | rs6000-*-aix5.[01])
+ targ_defvec=rs6000_xcoff64_aix_vec
+ targ_selvecs="rs6000_xcoff_vec"
+ want64=true
+ ;;
+#endif
+ powerpc-*-aix[5-9]* | rs6000-*-aix[5-9]*)
+ targ_cflags=-DAIX_WEAK_SUPPORT
+ targ_defvec=rs6000_xcoff_vec
+ targ_selvecs="rs6000_xcoff64_aix_vec"
+ want64=true
+ ;;
+#ifdef BFD64
+ powerpc64-*-aix[5-9]* | rs6000-*-aix[5-9]*)
+ targ_cflags=-DAIX_WEAK_SUPPORT
+ targ_defvec=rs6000_xcoff64_aix_vec
+ targ_selvecs="rs6000_xcoff_vec"
+ want64=true
+ ;;
+#endif
+
+ powerpc-*-aix* | powerpc-*-beos* | rs6000-*-*)
+ targ_defvec=rs6000_xcoff_vec
+ targ64_selvecs=rs6000_xcoff64_vec
+ case "${targ}" in
+ *-*-aix4.[3456789]* | *-*-aix[56789]*)
+ want64=true;;
+ *)
+ targ_cflags=-DSMALL_ARCHIVE;;
+ esac
+ ;;
+#ifdef BFD64
+ powerpc64-*-aix*)
+ targ_defvec=rs6000_xcoff64_vec
+ targ_selvecs=rs6000_xcoff_vec
+ want64=true
+ ;;
+ powerpc64-*-freebsd*)
+ targ_defvec=powerpc_elf64_fbsd_vec
+ targ_selvecs="powerpc_elf64_vec powerpc_elf32_vec powerpc_elf32_fbsd_vec powerpc_elf32_le_vec rs6000_xcoff_vec rs6000_xcoff64_vec rs6000_xcoff64_aix_vec"
+ want64=true
+ ;;
+ powerpc64-*-elf* | powerpc-*-elf64* | powerpc64-*-linux* | \
+ powerpc64-*-*bsd*)
+ targ_defvec=powerpc_elf64_vec
+ targ_selvecs="powerpc_elf64_le_vec powerpc_elf32_vec powerpc_elf32_le_vec rs6000_xcoff_vec rs6000_xcoff64_vec rs6000_xcoff64_aix_vec"
+ want64=true
+ ;;
+ powerpc64le-*-elf* | powerpcle-*-elf64* | powerpc64le-*-linux* | \
+ powerpc64le-*-*bsd*)
+ targ_defvec=powerpc_elf64_le_vec
+ targ_selvecs="powerpc_elf64_vec powerpc_elf32_le_vec powerpc_elf32_vec rs6000_xcoff_vec rs6000_xcoff64_vec rs6000_xcoff64_aix_vec"
+ want64=true
+ ;;
+#endif
+ powerpc-*-*freebsd*)
+ targ_defvec=powerpc_elf32_fbsd_vec
+ targ_selvecs="rs6000_xcoff_vec powerpc_elf32_vec powerpc_elf32_le_vec powerpc_boot_vec"
+ targ64_selvecs="powerpc_elf64_vec powerpc_elf64_le_vec powerpc_elf64_fbsd_vec"
+ ;;
+ powerpc-*-*bsd* | powerpc-*-elf* | powerpc-*-sysv4* | powerpc-*-eabi* | \
+ powerpc-*-solaris2* | powerpc-*-linux-* | powerpc-*-rtems* | \
+ powerpc-*-chorus*)
+ targ_defvec=powerpc_elf32_vec
+ targ_selvecs="rs6000_xcoff_vec powerpc_elf32_le_vec powerpc_boot_vec"
+ targ64_selvecs="powerpc_elf64_vec powerpc_elf64_le_vec"
+ ;;
+ powerpc-*-kaos*)
+ targ_defvec=powerpc_elf32_vec
+ targ_selvecs="powerpc_elf32_le_vec powerpc_boot_vec"
+ targ64_selvecs="powerpc_elf64_vec powerpc_elf64_le_vec"
+ ;;
+ powerpc-*-darwin* | powerpc-*-macos10* | powerpc-*-rhapsody*)
+ targ_defvec=mach_o_be_vec
+ targ_selvecs="mach_o_be_vec mach_o_le_vec mach_o_fat_vec pef_vec pef_xlib_vec sym_vec"
+ targ_archs="$targ_archs bfd_i386_arch"
+ ;;
+ powerpc-*-macos*)
+ targ_defvec=powerpc_xcoff_vec
+ ;;
+ powerpc-*-lynxos*)
+ targ_defvec=powerpc_elf32_vec
+ targ_selvecs="rs6000_xcoff_vec"
+ targ_cflags=-DSMALL_ARCHIVE
+ ;;
+ powerpc-*-netware*)
+ targ_defvec=powerpc_elf32_vec
+ targ_selvecs="powerpc_nlm32_vec rs6000_xcoff_vec"
+ ;;
+ powerpc-*-nto*)
+ targ_defvec=powerpc_elf32_vec
+ targ_selvecs="rs6000_xcoff_vec powerpc_elf32_le_vec powerpc_boot_vec"
+ ;;
+ powerpc-*-vxworks* | powerpc-*-windiss*)
+ targ_defvec=powerpc_elf32_vxworks_vec
+ targ_selvecs="rs6000_xcoff_vec powerpc_elf32_vec powerpc_elf32_le_vec powerpc_boot_vec"
+ targ64_selvecs="powerpc_elf64_vec powerpc_elf64_le_vec"
+ ;;
+ powerpcle-*-nto*)
+ targ_defvec=powerpc_elf32_le_vec
+ targ_selvecs="rs6000_xcoff_vec powerpc_elf32_vec powerpc_boot_vec"
+ ;;
+ powerpcle-*-elf* | powerpcle-*-sysv4* | powerpcle-*-eabi* | \
+ powerpcle-*-solaris2* | powerpcle-*-linux-* | powerpcle-*-vxworks*)
+ targ_defvec=powerpc_elf32_le_vec
+ targ_selvecs="rs6000_xcoff_vec powerpc_elf32_vec powerpc_boot_vec"
+ targ64_selvecs="powerpc_elf64_vec powerpc_elf64_le_vec"
+ ;;
+ powerpcle-*-pe | powerpcle-*-winnt* | powerpcle-*-cygwin*)
+ targ_defvec=powerpc_pe_le_vec
+ targ_selvecs="powerpc_pei_le_vec powerpc_pei_vec powerpc_pe_le_vec powerpc_pe_vec"
+ ;;
+
+ rl78-*-elf)
+ targ_defvec=rl78_elf32_vec
+ ;;
+
+ rx-*-elf)
+ targ_defvec=rx_elf32_le_vec
+ targ_selvecs="rx_elf32_be_vec rx_elf32_le_vec rx_elf32_be_ns_vec"
+ ;;
+
+ s390-*-linux*)
+ targ_defvec=s390_elf32_vec
+ targ64_selvecs=s390_elf64_vec
+ want64=true
+ ;;
+#ifdef BFD64
+ s390x-*-linux*)
+ targ_defvec=s390_elf64_vec
+ targ_selvecs=s390_elf32_vec
+ want64=true
+ ;;
+ s390x-*-tpf*)
+ targ_defvec=s390_elf64_vec
+ want64=true
+ ;;
+
+ score*-*-elf*)
+ targ_defvec=score_elf32_be_vec
+ targ_selvecs=score_elf32_le_vec
+ ;;
+
+ sh64l*-*-elf*)
+ targ_defvec=sh64_elf32_le_vec
+ targ_selvecs="sh64_elf32_vec sh64_elf64_le_vec sh64_elf64_vec sh_elf32_le_vec sh_elf32_vec"
+ targ_underscore=yes
+ want64=true
+ ;;
+ sh64-*-elf*)
+ targ_defvec=sh64_elf32_vec
+ targ_selvecs="sh64_elf32_le_vec sh64_elf64_vec sh64_elf64_le_vec sh_elf32_vec sh_elf32_le_vec"
+ targ_underscore=yes
+ want64=true
+ ;;
+ sh64eb-*-linux*)
+ targ_defvec=sh64_elf32_linux_be_vec
+ targ_selvecs="sh64_elf32_linux_vec sh64_elf64_linux_be_vec sh64_elf64_linux_vec sh_elf32_linux_be_vec sh_elf32_linux_vec"
+ want64=true
+ ;;
+ sh64-*-linux*)
+ targ_defvec=sh64_elf32_linux_vec
+ targ_selvecs="sh64_elf32_linux_be_vec sh64_elf64_linux_vec sh64_elf64_linux_be_vec sh_elf32_linux_vec sh_elf32_linux_be_vec"
+ want64=true
+ ;;
+ sh-*-linux*)
+ targ_defvec=sh_elf32_linux_be_vec
+ targ_selvecs="sh_elf32_linux_vec sh64_elf32_linux_vec sh64_elf32_linux_be_vec sh64_elf64_linux_vec sh64_elf64_linux_be_vec"
+ want64=true
+ ;;
+#endif /* BFD64 */
+
+ sh*eb-*-linux*)
+ targ_defvec=sh_elf32_linux_be_vec
+ targ_selvecs=sh_elf32_linux_vec
+ ;;
+ sh*-*-linux*)
+ targ_defvec=sh_elf32_linux_vec
+ targ_selvecs=sh_elf32_linux_be_vec
+ ;;
+
+ sh-*-uclinux* | sh[12]-*-uclinux*)
+ targ_defvec=sh_elf32_vec
+ targ_selvecs="sh_elf32_le_vec sh_elf32_linux_be_vec sh_elf32_linux_vec sh_elf32_fdpic_le_vec sh_elf32_fdpic_be_vec"
+#ifdef BFD64
+ targ_selvecs="${targ_selvecs} sh64_elf32_linux_vec sh64_elf32_linux_be_vec sh64_elf64_linux_vec sh64_elf64_linux_be_vec"
+#endif
+ ;;
+
+#ifdef BFD64
+ sh5le-*-netbsd*)
+ targ_defvec=sh64_elf32_nbsd_le_vec
+ targ_selvecs="sh64_elf32_nbsd_vec sh64_elf64_nbsd_le_vec sh64_elf64_nbsd_vec sh_elf32_nbsd_vec sh_elf32_nbsd_le_vec"
+ want64=true
+ ;;
+ sh5-*-netbsd*)
+ targ_defvec=sh64_elf32_nbsd_vec
+ targ_selvecs="sh64_elf32_nbsd_le_vec sh64_elf64_nbsd_le_vec sh64_elf64_nbsd_vec sh_elf32_nbsd_vec sh_elf32_nbsd_le_vec"
+ want64=true
+ ;;
+
+ sh64le-*-netbsd*)
+ targ_defvec=sh64_elf64_nbsd_le_vec
+ targ_selvecs="sh64_elf64_nbsd_vec sh64_elf32_nbsd_le_vec sh64_elf32_nbsd_vec sh_elf32_nbsd_vec sh_elf32_nbsd_le_vec"
+ want64=true
+ ;;
+ sh64-*-netbsd*)
+ targ_defvec=sh64_elf64_nbsd_vec
+ targ_selvecs="sh64_elf64_nbsd_le_vec sh64_elf32_nbsd_le_vec sh64_elf32_nbsd_vec sh_elf32_nbsd_vec sh_elf32_nbsd_le_vec"
+ want64=true
+ ;;
+
+ sh*l*-*-netbsdelf*)
+ targ_defvec=sh_elf32_nbsd_le_vec
+ targ_selvecs="sh_elf32_nbsd_vec sh_coff_vec sh_coff_le_vec sh64_elf32_nbsd_le_vec sh64_elf32_nbsd_vec sh64_elf64_nbsd_le_vec sh64_elf64_nbsd_vec"
+ want64=true
+ ;;
+ sh-*-netbsdelf*)
+ targ_defvec=sh_elf32_nbsd_vec
+ targ_selvecs="sh_elf32_nbsd_le_vec sh_coff_vec sh_coff_le_vec sh64_elf32_nbsd_le_vec sh64_elf32_nbsd_vec sh64_elf64_nbsd_le_vec sh64_elf64_nbsd_vec"
+ want64=true
+ ;;
+#endif
+
+ sh*-*-netbsdelf*)
+ targ_defvec=sh_elf32_nbsd_vec
+ targ_selvecs="sh_elf32_nbsd_le_vec sh_coff_vec sh_coff_le_vec"
+ ;;
+ sh*-*-symbianelf*)
+ targ_defvec=sh_elf32_symbian_le_vec
+ targ_selvecs="sh_coff_le_vec sh_coff_small_le_vec"
+ targ_underscore=yes
+ ;;
+
+#ifdef BFD64
+ shl*-*-elf* | sh[1234]l*-*-elf* | sh3el*-*-elf* | shl*-*-kaos*)
+ targ_defvec=sh_elf32_le_vec
+ targ_selvecs="sh_elf32_vec sh_coff_le_vec sh_coff_vec sh_coff_small_le_vec sh_coff_small_vec sh64_elf32_vec sh64_elf32_le_vec sh64_elf64_vec sh64_elf64_le_vec"
+ targ_underscore=yes
+ want64=true
+ ;;
+#endif
+
+ sh-*-rtemscoff*)
+ targ_defvec=sh_coff_vec
+ targ_selvecs="sh_coff_vec sh_coff_le_vec sh_coff_small_vec sh_coff_small_le_vec"
+ targ_underscore=yes
+ ;;
+
+#ifdef BFD64
+ sh-*-elf* | sh[1234]*-elf* | sh-*-rtems* | sh-*-kaos*)
+ targ_defvec=sh_elf32_vec
+ targ_selvecs="sh_elf32_le_vec sh_coff_vec sh_coff_le_vec sh_coff_small_vec sh_coff_small_le_vec sh64_elf32_vec sh64_elf32_le_vec sh64_elf64_vec sh64_elf64_le_vec"
+ targ_underscore=yes
+ want64=true
+ ;;
+#endif
+
+ sh-*-nto*)
+ targ_defvec=sh_elf32_vec
+ targ_selvecs="sh_elf32_le_vec sh_coff_vec sh_coff_le_vec sh_coff_small_vec sh_coff_small_le_vec"
+ targ_underscore=yes
+ ;;
+ sh*-*-openbsd*)
+ targ_defvec=sh_elf32_nbsd_le_vec
+ targ_selvecs="sh_elf32_nbsd_vec sh_coff_vec sh_coff_le_vec"
+ ;;
+ sh-*-pe)
+ targ_defvec=sh_pe_le_vec
+ targ_selvecs="sh_pe_le_vec sh_pei_le_vec"
+ targ_underscore=yes
+ ;;
+ sh-*-vxworks)
+ targ_defvec=sh_elf32_vxworks_vec
+ targ_selvecs="sh_elf32_vxworks_le_vec"
+ # FIXME None of the following are actually used on this target, but
+ # they're necessary for coff-sh.c (which is unconditionally used) to be
+ # compiled correctly.
+ targ_selvecs="$targ_selvecs sh_coff_vec sh_coff_le_vec sh_coff_small_vec sh_coff_small_le_vec"
+ targ_underscore=yes
+ ;;
+ sh-*-*)
+ targ_defvec=sh_coff_vec
+ targ_selvecs="sh_coff_vec sh_coff_le_vec sh_coff_small_vec sh_coff_small_le_vec"
+ targ_underscore=yes
+ ;;
+
+ sparclet-*-aout*)
+ targ_defvec=sparc_aout_sunos_be_vec
+ targ_selvecs=sparc_aout_le_vec
+ targ_underscore=yes
+ ;;
+ sparc86x-*-aout*)
+ targ_defvec=sparc_aout_sunos_be_vec
+ targ_underscore=yes
+ ;;
+ sparclite-*-elf* | sparc86x-*-elf*)
+ targ_defvec=sparc_elf32_vec
+ ;;
+ sparc*-*-chorus*)
+ targ_defvec=sparc_elf32_vec
+ ;;
+ sparc-*-linux*aout*)
+ targ_defvec=sparc_aout_linux_vec
+ targ_selvecs="sparc_elf32_vec sparc_aout_sunos_be_vec"
+ targ_underscore=yes
+ ;;
+ sparc-*-linux-* | sparcv*-*-linux-*)
+ targ_defvec=sparc_elf32_vec
+ targ_selvecs="sparc_aout_linux_vec sparc_elf64_vec sparc_aout_sunos_be_vec"
+ ;;
+ sparc-*-netbsdelf*)
+ targ_defvec=sparc_elf32_vec
+ targ_selvecs=sparc_aout_nbsd_vec
+ ;;
+ sparc-*-netbsdaout* | sparc-*-netbsd*)
+ targ_defvec=sparc_aout_nbsd_vec
+ targ_selvecs=sparc_elf32_vec
+ targ_underscore=yes
+ ;;
+ sparc-*-openbsd[0-2].* | sparc-*-openbsd3.[0-1])
+ targ_defvec=sparc_aout_nbsd_vec
+ targ_underscore=yes
+ ;;
+ sparc-*-openbsd*)
+ targ_defvec=sparc_elf32_vec
+ targ_selvecs=sparc_aout_nbsd_vec
+ ;;
+ sparc-*-elf*)
+ targ_defvec=sparc_elf32_vec
+ targ_selvecs=sparc_aout_sunos_be_vec
+ ;;
+ sparc-*-solaris2.[0-6] | sparc-*-solaris2.[0-6].*)
+ targ_defvec=sparc_elf32_sol2_vec
+ targ_selvecs=sparc_aout_sunos_be_vec
+ ;;
+#ifdef BFD64
+ sparc-*-solaris2* | sparcv9-*-solaris2* | sparc64-*-solaris2*)
+ targ_defvec=sparc_elf32_sol2_vec
+ targ_selvecs="sparc_elf64_sol2_vec sparc_aout_sunos_be_vec"
+ want64=true
+ ;;
+#endif
+ sparc-*-sysv4*)
+ targ_defvec=sparc_elf32_vec
+ ;;
+ sparc-*-vxworks*)
+ targ_defvec=sparc_elf32_vxworks_vec
+ targ_selvecs="sparc_elf32_vec sparc_aout_sunos_be_vec"
+ ;;
+ sparc-*-netware*)
+ targ_defvec=sparc_elf32_vec
+ targ_selvecs="sparc_nlm32_vec sparc_aout_sunos_be_vec"
+ ;;
+#ifdef BFD64
+ sparc64-*-aout*)
+ targ_defvec=sparc_aout_sunos_be_vec
+ targ_underscore=yes
+ want64=true
+ ;;
+ sparc64*-*-linux-*)
+ targ_defvec=sparc_elf64_vec
+ targ_selvecs="sparc_elf32_vec sparc_aout_linux_vec sparc_aout_sunos_be_vec"
+ want64=true
+ ;;
+ sparc64-*-elf* | sparc64-*-rtems* )
+ targ_defvec=sparc_elf64_vec
+ targ_selvecs=sparc_elf32_vec
+ want64=true
+ ;;
+#endif /* BFD64 */
+ sparc*-*-coff*)
+ targ_defvec=sparc_coff_vec
+ ;;
+ sparc-*-rtems*)
+ targ_defvec=sparc_elf32_vec
+ targ_selvecs="sparc_aout_sunos_be_vec sparc_coff_vec"
+ ;;
+ sparc*-*-*)
+ targ_defvec=sparc_aout_sunos_be_vec
+ targ_underscore=yes
+ ;;
+
+ spu-*-elf)
+ targ_defvec=spu_elf32_vec
+ want64=true
+ ;;
+
+#if HAVE_aout_vec
+ tahoe-*-*)
+ targ_defvec=aout_vec
+ targ_underscore=yes
+ ;;
+#endif
+
+ tic6x-*-elf)
+ targ_defvec=tic6x_elf32_c6000_le_vec
+ targ_selvecs="tic6x_elf32_c6000_be_vec tic6x_elf32_le_vec tic6x_elf32_be_vec"
+ ;;
+
+ tic6x-*-uclinux)
+ targ_defvec=tic6x_elf32_linux_le_vec
+ targ_selvecs="tic6x_elf32_linux_be_vec tic6x_elf32_le_vec tic6x_elf32_be_vec"
+ ;;
+
+ tic80*-*-*)
+ targ_defvec=tic80_coff_vec
+ targ_underscore=yes
+ ;;
+
+#ifdef BFD64
+ tilegx-*-*)
+ targ_defvec=tilegx_elf64_le_vec
+ targ_selvecs="tilegx_elf64_be_vec tilegx_elf32_be_vec tilegx_elf32_le_vec"
+ ;;
+ tilegxbe-*-*)
+ targ_defvec=tilegx_elf64_be_vec
+ targ_selvecs="tilegx_elf64_le_vec tilegx_elf32_be_vec tilegx_elf32_le_vec"
+ ;;
+#endif
+
+ tilepro-*-*)
+ targ_defvec=tilepro_elf32_vec
+ ;;
+
+ v850*-*-*)
+ targ_defvec=v850_elf32_vec
+ targ_selvecs="v800_elf32_vec"
+ ;;
+
+ vax-*-netbsdelf*)
+ targ_defvec=vax_elf32_vec
+ targ_selvecs="vax_aout_nbsd_vec vax_aout_1knbsd_vec"
+ ;;
+
+ vax-*-netbsdaout* | vax-*-netbsd*)
+ targ_defvec=vax_aout_nbsd_vec
+ targ_selvecs="vax_elf32_vec vax_aout_1knbsd_vec"
+ targ_underscore=yes
+ ;;
+
+ vax-*-bsd* | vax-*-ultrix*)
+ targ_defvec=vax_aout_bsd_vec
+ targ_underscore=yes
+ ;;
+
+ vax-*-openbsd*)
+ targ_defvec=vax_aout_nbsd_vec
+ targ_underscore=yes
+ ;;
+
+ vax-*-linux-*)
+ targ_defvec=vax_elf32_vec
+ ;;
+
+ we32k-*-*)
+ targ_defvec=we32k_coff_vec
+ ;;
+
+ w65-*-*)
+ targ_defvec=w65_coff_vec
+ ;;
+
+ xgate-*-*)
+ targ_defvec=xgate_elf32_vec
+ targ_selvecs="xgate_elf32_vec"
+ ;;
+
+ xstormy16-*-elf)
+ targ_defvec=xstormy16_elf32_vec
+ ;;
+
+ xtensa*-*-*)
+ targ_defvec=xtensa_elf32_le_vec
+ targ_selvecs=xtensa_elf32_be_vec
+ ;;
+ xc16x-*-elf)
+ targ_defvec=xc16x_elf32_vec
+ ;;
+
+ z80-*-*)
+ targ_defvec=z80_coff_vec
+ targ_underscore=no
+ ;;
+
+ z8k*-*-*)
+ targ_defvec=z8k_coff_vec
+ targ_underscore=yes
+ ;;
+
+ *-*-ieee*)
+ targ_defvec=ieee_vec
+ ;;
+
+ *-adobe-*)
+ targ_defvec=aout_adobe_vec
+ targ_underscore=yes
+ ;;
+
+ *-sony-*)
+ targ_defvec=m68k_aout_newsos3_vec
+ targ_underscore=yes
+ ;;
+
+ *-tandem-*)
+ targ_defvec=m68k_coff_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
+
+# All MIPS ELF targets need a 64-bit bfd_vma.
+case "${targ_defvec} ${targ_selvecs}" in
+ *mips_elf*)
+ want64=true
+ ;;
+esac
+
+case "${host64}${want64}" in
+ *true*)
+ targ_selvecs="${targ_selvecs} ${targ64_selvecs}"
+ ;;
+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
+ *elf64* | *mips_elf32_n*)
+ targ_selvecs="${targ_selvecs} elf64_le_vec elf64_be_vec elf32_le_vec elf32_be_vec"
+ ;;
+ *elf32*)
+ targ_selvecs="${targ_selvecs} elf32_le_vec elf32_be_vec"
+ ;;
+esac
+
+# If we support Intel L1OM target, then add support for bfd_l1om_arch.
+case "${targ_defvec} ${targ_selvecs}" in
+ *l1om_elf64*)
+ targ_archs="$targ_archs bfd_l1om_arch"
+ ;;
+esac
+
+# If we support Intel K1OM target, then add support for bfd_k1om_arch.
+case "${targ_defvec} ${targ_selvecs}" in
+ *k1om_elf64*)
+ targ_archs="$targ_archs bfd_k1om_arch"
+ ;;
+esac
diff --git a/bfd/config.in b/bfd/config.in
new file mode 100644
index 0000000..b911bf6
--- /dev/null
+++ b/bfd/config.in
@@ -0,0 +1,386 @@
+/* config.in. Generated from configure.ac by autoheader. */
+
+/* Check that config.h is #included before system headers
+ (this works only for glibc, but that should be enough). */
+#if defined(__GLIBC__) && !defined(__FreeBSD_kernel__) && !defined(__CONFIG_H__)
+# error config.h must be #included before system headers
+#endif
+#define __CONFIG_H__ 1
+
+/* Name of host specific core header file to include in elf.c. */
+#undef CORE_HEADER
+
+/* Define to 1 if translation of program messages to the user's native
+ language is requested. */
+#undef ENABLE_NLS
+
+/* Define to 1 if you have the <alloca.h> header file. */
+#undef HAVE_ALLOCA_H
+
+/* Define to 1 if you have the declaration of `basename', and to 0 if you
+ don't. */
+#undef HAVE_DECL_BASENAME
+
+/* Define to 1 if you have the declaration of `ffs', and to 0 if you don't. */
+#undef HAVE_DECL_FFS
+
+/* Define to 1 if you have the declaration of `free', and to 0 if you don't.
+ */
+#undef HAVE_DECL_FREE
+
+/* Define to 1 if you have the declaration of `fseeko', and to 0 if you don't.
+ */
+#undef HAVE_DECL_FSEEKO
+
+/* Define to 1 if you have the declaration of `fseeko64', and to 0 if you
+ don't. */
+#undef HAVE_DECL_FSEEKO64
+
+/* Define to 1 if you have the declaration of `ftello', and to 0 if you don't.
+ */
+#undef HAVE_DECL_FTELLO
+
+/* Define to 1 if you have the declaration of `ftello64', and to 0 if you
+ don't. */
+#undef HAVE_DECL_FTELLO64
+
+/* Define to 1 if you have the declaration of `getenv', and to 0 if you don't.
+ */
+#undef HAVE_DECL_GETENV
+
+/* Define to 1 if you have the declaration of `malloc', and to 0 if you don't.
+ */
+#undef HAVE_DECL_MALLOC
+
+/* Define to 1 if you have the declaration of `realloc', and to 0 if you
+ don't. */
+#undef HAVE_DECL_REALLOC
+
+/* Define to 1 if you have the declaration of `snprintf', and to 0 if you
+ don't. */
+#undef HAVE_DECL_SNPRINTF
+
+/* Define to 1 if you have the declaration of `stpcpy', and to 0 if you don't.
+ */
+#undef HAVE_DECL_STPCPY
+
+/* Define to 1 if you have the declaration of `strnlen', and to 0 if you
+ don't. */
+#undef HAVE_DECL_STRNLEN
+
+/* Define to 1 if you have the declaration of `strstr', and to 0 if you don't.
+ */
+#undef HAVE_DECL_STRSTR
+
+/* Define to 1 if you have the declaration of `vsnprintf', and to 0 if you
+ don't. */
+#undef HAVE_DECL_VSNPRINTF
+
+/* Define to 1 if you have the <dirent.h> header file, and it defines `DIR'.
+ */
+#undef HAVE_DIRENT_H
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#undef HAVE_DLFCN_H
+
+/* Define to 1 if you have the `fcntl' function. */
+#undef HAVE_FCNTL
+
+/* Define to 1 if you have the <fcntl.h> header file. */
+#undef HAVE_FCNTL_H
+
+/* Define to 1 if you have the `fdopen' function. */
+#undef HAVE_FDOPEN
+
+/* Define to 1 if you have the `fileno' function. */
+#undef HAVE_FILENO
+
+/* Define to 1 if you have the `fopen64' function. */
+#undef HAVE_FOPEN64
+
+/* Define to 1 if you have the `fseeko' function. */
+#undef HAVE_FSEEKO
+
+/* Define to 1 if you have the `fseeko64' function. */
+#undef HAVE_FSEEKO64
+
+/* Define to 1 if you have the `ftello' function. */
+#undef HAVE_FTELLO
+
+/* Define to 1 if you have the `ftello64' function. */
+#undef HAVE_FTELLO64
+
+/* Define to 1 if you have the `getgid' function. */
+#undef HAVE_GETGID
+
+/* Define to 1 if you have the `getpagesize' function. */
+#undef HAVE_GETPAGESIZE
+
+/* Define to 1 if you have the `getrlimit' function. */
+#undef HAVE_GETRLIMIT
+
+/* Define to 1 if you have the `getuid' function. */
+#undef HAVE_GETUID
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#undef HAVE_INTTYPES_H
+
+/* 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_fpreg. */
+#undef HAVE_LWPSTATUS_T_PR_FPREG
+
+/* Define if <sys/procfs.h> has lwpstatus_t.pr_reg. */
+#undef HAVE_LWPSTATUS_T_PR_REG
+
+/* Define if <sys/procfs.h> has lwpxstatus_t. */
+#undef HAVE_LWPXSTATUS_T
+
+/* Define to 1 if you have the `madvise' function. */
+#undef HAVE_MADVISE
+
+/* Define to 1 if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* Define to 1 if you have a working `mmap' system call. */
+#undef HAVE_MMAP
+
+/* Define to 1 if you have the `mprotect' function. */
+#undef HAVE_MPROTECT
+
+/* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */
+#undef HAVE_NDIR_H
+
+/* Define if <sys/procfs.h> has prpsinfo32_t. */
+#undef HAVE_PRPSINFO32_T
+
+/* Define if <sys/procfs.h> has prpsinfo32_t.pr_pid. */
+#undef HAVE_PRPSINFO32_T_PR_PID
+
+/* Define if <sys/procfs.h> has prpsinfo_t. */
+#undef HAVE_PRPSINFO_T
+
+/* Define if <sys/procfs.h> has prpsinfo_t.pr_pid. */
+#undef HAVE_PRPSINFO_T_PR_PID
+
+/* Define if <sys/procfs.h> has prstatus32_t. */
+#undef HAVE_PRSTATUS32_T
+
+/* Define if <sys/procfs.h> has prstatus32_t.pr_who. */
+#undef HAVE_PRSTATUS32_T_PR_WHO
+
+/* 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 psinfo32_t. */
+#undef HAVE_PSINFO32_T
+
+/* Define if <sys/procfs.h> has psinfo32_t.pr_pid. */
+#undef HAVE_PSINFO32_T_PR_PID
+
+/* Define if <sys/procfs.h> has psinfo_t. */
+#undef HAVE_PSINFO_T
+
+/* Define if <sys/procfs.h> has psinfo_t.pr_pid. */
+#undef HAVE_PSINFO_T_PR_PID
+
+/* Define if <sys/procfs.h> has pstatus32_t. */
+#undef HAVE_PSTATUS32_T
+
+/* Define if <sys/procfs.h> has pstatus_t. */
+#undef HAVE_PSTATUS_T
+
+/* Define if <sys/procfs.h> has pxstatus_t. */
+#undef HAVE_PXSTATUS_T
+
+/* Define to 1 if you have the `setitimer' function. */
+#undef HAVE_SETITIMER
+
+/* Define to 1 if you have the <stddef.h> header file. */
+#undef HAVE_STDDEF_H
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#undef HAVE_STDINT_H
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#undef HAVE_STDLIB_H
+
+/* Define to 1 if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define to 1 if you have the <string.h> header file. */
+#undef HAVE_STRING_H
+
+/* Define to 1 if you have the `strtoull' function. */
+#undef HAVE_STRTOULL
+
+/* Define if struct core_dumpx has member c_impl */
+#undef HAVE_ST_C_IMPL
+
+/* Define to 1 if you have the `sysconf' function. */
+#undef HAVE_SYSCONF
+
+/* Define to 1 if you have the <sys/dir.h> header file, and it defines `DIR'.
+ */
+#undef HAVE_SYS_DIR_H
+
+/* Define to 1 if you have the <sys/file.h> header file. */
+#undef HAVE_SYS_FILE_H
+
+/* Define to 1 if you have the <sys/ndir.h> header file, and it defines `DIR'.
+ */
+#undef HAVE_SYS_NDIR_H
+
+/* Define to 1 if you have the <sys/procfs.h> header file. */
+#undef HAVE_SYS_PROCFS_H
+
+/* Define to 1 if you have the <sys/resource.h> header file. */
+#undef HAVE_SYS_RESOURCE_H
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#undef HAVE_SYS_STAT_H
+
+/* Define to 1 if you have the <sys/time.h> header file. */
+#undef HAVE_SYS_TIME_H
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#undef HAVE_SYS_TYPES_H
+
+/* Define to 1 if you have the <time.h> header file. */
+#undef HAVE_TIME_H
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* Define to 1 if you have the <wchar.h> header file. */
+#undef HAVE_WCHAR_H
+
+/* Define if <sys/procfs.h> has win32_pstatus_t. */
+#undef HAVE_WIN32_PSTATUS_T
+
+/* Define to 1 if you have the <windows.h> header file. */
+#undef HAVE_WINDOWS_H
+
+/* Define to 1 if you have the <zlib.h> header file. */
+#undef HAVE_ZLIB_H
+
+/* Define to the sub-directory in which libtool stores uninstalled libraries.
+ */
+#undef LT_OBJDIR
+
+/* Name of package */
+#undef PACKAGE
+
+/* Define to the address where bug reports for this package should be sent. */
+#undef PACKAGE_BUGREPORT
+
+/* Define to the full name of this package. */
+#undef PACKAGE_NAME
+
+/* Define to the full name and version of this package. */
+#undef PACKAGE_STRING
+
+/* Define to the one symbol short name of this package. */
+#undef PACKAGE_TARNAME
+
+/* Define to the home page for this package. */
+#undef PACKAGE_URL
+
+/* Define to the version of this package. */
+#undef PACKAGE_VERSION
+
+/* The size of `char', as computed by sizeof. */
+#undef SIZEOF_CHAR
+
+/* The size of `int', as computed by sizeof. */
+#undef SIZEOF_INT
+
+/* The size of `long', as computed by sizeof. */
+#undef SIZEOF_LONG
+
+/* The size of `long long', as computed by sizeof. */
+#undef SIZEOF_LONG_LONG
+
+/* The size of `off_t', as computed by sizeof. */
+#undef SIZEOF_OFF_T
+
+/* The size of `short', as computed by sizeof. */
+#undef SIZEOF_SHORT
+
+/* The size of `void *', as computed by sizeof. */
+#undef SIZEOF_VOID_P
+
+/* Define to 1 if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Define if you can safely include both <string.h> and <strings.h>. */
+#undef STRING_WITH_STRINGS
+
+/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
+#undef TIME_WITH_SYS_TIME
+
+/* Name of host specific header file to include in trad-core.c. */
+#undef TRAD_HEADER
+
+/* Use b modifier when opening binary files? */
+#undef USE_BINARY_FOPEN
+
+/* Define if we should use leading underscore on 64 bit mingw targets */
+#undef USE_MINGW64_LEADING_UNDERSCORES
+
+/* Use mmap if it's available? */
+#undef USE_MMAP
+
+/* Define if we should default to creating read-only plt entries */
+#undef USE_SECUREPLT
+
+/* Define if we may generate symbols with ELF's STT_COMMON type */
+#undef USE_STT_COMMON
+
+/* Enable extensions on AIX 3, Interix. */
+#ifndef _ALL_SOURCE
+# undef _ALL_SOURCE
+#endif
+/* Enable GNU extensions on systems that have them. */
+#ifndef _GNU_SOURCE
+# undef _GNU_SOURCE
+#endif
+/* Enable threading extensions on Solaris. */
+#ifndef _POSIX_PTHREAD_SEMANTICS
+# undef _POSIX_PTHREAD_SEMANTICS
+#endif
+/* Enable extensions on HP NonStop. */
+#ifndef _TANDEM_SOURCE
+# undef _TANDEM_SOURCE
+#endif
+/* Enable general extensions on Solaris. */
+#ifndef __EXTENSIONS__
+# undef __EXTENSIONS__
+#endif
+
+
+/* Version number of package */
+#undef VERSION
+
+/* Number of bits in a file offset, on hosts where this is settable. */
+#undef _FILE_OFFSET_BITS
+
+/* Define for large files, on AIX-style hosts. */
+#undef _LARGE_FILES
+
+/* Define to 1 if on MINIX. */
+#undef _MINIX
+
+/* Define to 2 if the system does not provide POSIX.1 features except with
+ this defined. */
+#undef _POSIX_1_SOURCE
+
+/* Define to 1 if you need to in order for `stat' and other things to work. */
+#undef _POSIX_SOURCE
diff --git a/bfd/configure b/bfd/configure
new file mode 100755
index 0000000..7016194
--- /dev/null
+++ b/bfd/configure
@@ -0,0 +1,18897 @@
+#! /bin/sh
+# Guess values for system-dependent variables and create Makefiles.
+# Generated by GNU Autoconf 2.64 for bfd 2.25.
+#
+# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
+# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software
+# Foundation, Inc.
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+## -------------------- ##
+## M4sh Initialization. ##
+## -------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
+ emulate sh
+ NULLCMD=:
+ # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+else
+ case `(set -o) 2>/dev/null` in #(
+ *posix*) :
+ set -o posix ;; #(
+ *) :
+ ;;
+esac
+fi
+
+
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+# Prefer a ksh shell builtin over an external printf program on Solaris,
+# but without wasting forks for bash or zsh.
+if test -z "$BASH_VERSION$ZSH_VERSION" \
+ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='print -r --'
+ as_echo_n='print -rn --'
+elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='printf %s\n'
+ as_echo_n='printf %s'
+else
+ if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+ as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+ as_echo_n='/usr/ucb/echo -n'
+ else
+ as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+ as_echo_n_body='eval
+ arg=$1;
+ case $arg in #(
+ *"$as_nl"*)
+ expr "X$arg" : "X\\(.*\\)$as_nl";
+ arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+ esac;
+ expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+ '
+ export as_echo_n_body
+ as_echo_n='sh -c $as_echo_n_body as_echo'
+ fi
+ export as_echo_body
+ as_echo='sh -c $as_echo_body as_echo'
+fi
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ PATH_SEPARATOR=:
+ (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+ (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+ PATH_SEPARATOR=';'
+ }
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order. Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+IFS=" "" $as_nl"
+
+# Find who we are. Look in the path if we contain no directory separator.
+case $0 in #((
+ *[\\/]* ) as_myself=$0 ;;
+ *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+ as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+ $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+ exit 1
+fi
+
+# Unset variables that we do not need and which cause bugs (e.g. in
+# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1"
+# suppresses any "Segmentation fault" message there. '((' could
+# trigger a bug in pdksh 5.2.14.
+for as_var in BASH_ENV ENV MAIL MAILPATH
+do eval test x\${$as_var+set} = xset \
+ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# CDPATH.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+if test "x$CONFIG_SHELL" = x; then
+ as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then :
+ emulate sh
+ NULLCMD=:
+ # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '\${1+\"\$@\"}'='\"\$@\"'
+ setopt NO_GLOB_SUBST
+else
+ case \`(set -o) 2>/dev/null\` in #(
+ *posix*) :
+ set -o posix ;; #(
+ *) :
+ ;;
+esac
+fi
+"
+ as_required="as_fn_return () { (exit \$1); }
+as_fn_success () { as_fn_return 0; }
+as_fn_failure () { as_fn_return 1; }
+as_fn_ret_success () { return 0; }
+as_fn_ret_failure () { return 1; }
+
+exitcode=0
+as_fn_success || { exitcode=1; echo as_fn_success failed.; }
+as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; }
+as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; }
+as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; }
+if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then :
+
+else
+ exitcode=1; echo positional parameters were not saved.
+fi
+test x\$exitcode = x0 || exit 1"
+ as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO
+ as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO
+ eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" &&
+ test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1
+test \$(( 1 + 1 )) = 2 || exit 1
+
+ test -n \"\${ZSH_VERSION+set}\${BASH_VERSION+set}\" || (
+ ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+ ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO
+ ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO
+ PATH=/empty FPATH=/empty; export PATH FPATH
+ test \"X\`printf %s \$ECHO\`\" = \"X\$ECHO\" \\
+ || test \"X\`print -r -- \$ECHO\`\" = \"X\$ECHO\" ) || exit 1"
+ if (eval "$as_required") 2>/dev/null; then :
+ as_have_required=yes
+else
+ as_have_required=no
+fi
+ if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then :
+
+else
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+as_found=false
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ as_found=:
+ case $as_dir in #(
+ /*)
+ for as_base in sh bash ksh sh5; do
+ # Try only shells that exist, to save several forks.
+ as_shell=$as_dir/$as_base
+ if { test -f "$as_shell" || test -f "$as_shell.exe"; } &&
+ { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then :
+ CONFIG_SHELL=$as_shell as_have_required=yes
+ if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then :
+ break 2
+fi
+fi
+ done;;
+ esac
+ as_found=false
+done
+$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } &&
+ { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then :
+ CONFIG_SHELL=$SHELL as_have_required=yes
+fi; }
+IFS=$as_save_IFS
+
+
+ if test "x$CONFIG_SHELL" != x; then :
+ # We cannot yet assume a decent shell, so we have to provide a
+ # neutralization value for shells without unset; and this also
+ # works around shells that cannot unset nonexistent variables.
+ BASH_ENV=/dev/null
+ ENV=/dev/null
+ (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+ export CONFIG_SHELL
+ exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"}
+fi
+
+ if test x$as_have_required = xno; then :
+ $as_echo "$0: This script requires a shell more modern than all"
+ $as_echo "$0: the shells that I found on your system."
+ if test x${ZSH_VERSION+set} = xset ; then
+ $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should"
+ $as_echo "$0: be upgraded to zsh 4.3.4 or later."
+ else
+ $as_echo "$0: Please tell bug-autoconf@gnu.org about your system,
+$0: including any error possibly output before this
+$0: message. Then install a modern shell, or manually run
+$0: the script under such a shell if you do have one."
+ fi
+ exit 1
+fi
+fi
+fi
+SHELL=${CONFIG_SHELL-/bin/sh}
+export SHELL
+# Unset more variables known to interfere with behavior of common tools.
+CLICOLOR_FORCE= GREP_OPTIONS=
+unset CLICOLOR_FORCE GREP_OPTIONS
+
+## --------------------- ##
+## M4sh Shell Functions. ##
+## --------------------- ##
+# as_fn_unset VAR
+# ---------------
+# Portably unset VAR.
+as_fn_unset ()
+{
+ { eval $1=; unset $1;}
+}
+as_unset=as_fn_unset
+
+# as_fn_set_status STATUS
+# -----------------------
+# Set $? to STATUS, without forking.
+as_fn_set_status ()
+{
+ return $1
+} # as_fn_set_status
+
+# as_fn_exit STATUS
+# -----------------
+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
+as_fn_exit ()
+{
+ set +e
+ as_fn_set_status $1
+ exit $1
+} # as_fn_exit
+
+# as_fn_mkdir_p
+# -------------
+# Create "$as_dir" as a directory, including parents if necessary.
+as_fn_mkdir_p ()
+{
+
+ case $as_dir in #(
+ -*) as_dir=./$as_dir;;
+ esac
+ test -d "$as_dir" || eval $as_mkdir_p || {
+ as_dirs=
+ while :; do
+ case $as_dir in #(
+ *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+ *) as_qdir=$as_dir;;
+ esac
+ as_dirs="'$as_qdir' $as_dirs"
+ as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_dir" : 'X\(//\)[^/]' \| \
+ X"$as_dir" : 'X\(//\)$' \| \
+ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_dir" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ test -d "$as_dir" && break
+ done
+ test -z "$as_dirs" || eval "mkdir $as_dirs"
+ } || test -d "$as_dir" || as_fn_error "cannot create directory $as_dir"
+
+
+} # as_fn_mkdir_p
+# as_fn_append VAR VALUE
+# ----------------------
+# Append the text in VALUE to the end of the definition contained in VAR. Take
+# advantage of any shell optimizations that allow amortized linear growth over
+# repeated appends, instead of the typical quadratic growth present in naive
+# implementations.
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
+ eval 'as_fn_append ()
+ {
+ eval $1+=\$2
+ }'
+else
+ as_fn_append ()
+ {
+ eval $1=\$$1\$2
+ }
+fi # as_fn_append
+
+# as_fn_arith ARG...
+# ------------------
+# Perform arithmetic evaluation on the ARGs, and store the result in the
+# global $as_val. Take advantage of shells that can avoid forks. The arguments
+# must be portable across $(()) and expr.
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
+ eval 'as_fn_arith ()
+ {
+ as_val=$(( $* ))
+ }'
+else
+ as_fn_arith ()
+ {
+ as_val=`expr "$@" || test $? -eq 1`
+ }
+fi # as_fn_arith
+
+
+# as_fn_error ERROR [LINENO LOG_FD]
+# ---------------------------------
+# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
+# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
+# script with status $?, using 1 if that was 0.
+as_fn_error ()
+{
+ as_status=$?; test $as_status -eq 0 && as_status=1
+ if test "$3"; then
+ as_lineno=${as_lineno-"$2"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ $as_echo "$as_me:${as_lineno-$LINENO}: error: $1" >&$3
+ fi
+ $as_echo "$as_me: error: $1" >&2
+ as_fn_exit $as_status
+} # as_fn_error
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+ test "X`expr 00001 : '.*\(...\)'`" = X001; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+ as_basename=basename
+else
+ as_basename=false
+fi
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+ as_dirname=dirname
+else
+ as_dirname=false
+fi
+
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$0" |
+ sed '/^.*\/\([^/][^/]*\)\/*$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+
+ as_lineno_1=$LINENO as_lineno_1a=$LINENO
+ as_lineno_2=$LINENO as_lineno_2a=$LINENO
+ eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" &&
+ test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || {
+ # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-)
+ sed -n '
+ p
+ /[$]LINENO/=
+ ' <$as_myself |
+ sed '
+ s/[$]LINENO.*/&-/
+ t lineno
+ b
+ :lineno
+ N
+ :loop
+ s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
+ t loop
+ s/-\n.*//
+ ' >$as_me.lineno &&
+ chmod +x "$as_me.lineno" ||
+ { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }
+
+ # Don't try to exec as it changes $[0], causing all sort of problems
+ # (the dirname of $[0] is not the place where we might find the
+ # original and so on. Autoconf is especially sensitive to this).
+ . "./$as_me.lineno"
+ # Exit status is that of the last command.
+ exit
+}
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in #(((((
+-n*)
+ case `echo 'xy\c'` in
+ *c*) ECHO_T=' ';; # ECHO_T is single tab character.
+ xy) ECHO_C='\c';;
+ *) echo `echo ksh88 bug on AIX 6.1` > /dev/null
+ ECHO_T=' ';;
+ esac;;
+*)
+ ECHO_N='-n';;
+esac
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+ rm -f conf$$.dir/conf$$.file
+else
+ rm -f conf$$.dir
+ mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+ if ln -s conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s='ln -s'
+ # ... but there are two gotchas:
+ # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+ # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+ # In both cases, we have to default to `cp -p'.
+ ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+ as_ln_s='cp -p'
+ elif ln conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s=ln
+ else
+ as_ln_s='cp -p'
+ fi
+else
+ as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+if mkdir -p . 2>/dev/null; then
+ as_mkdir_p='mkdir -p "$as_dir"'
+else
+ test -d ./-p && rmdir ./-p
+ as_mkdir_p=false
+fi
+
+if test -x / >/dev/null 2>&1; then
+ as_test_x='test -x'
+else
+ if ls -dL / >/dev/null 2>&1; then
+ as_ls_L_option=L
+ else
+ as_ls_L_option=
+ fi
+ as_test_x='
+ eval sh -c '\''
+ if test -d "$1"; then
+ test -d "$1/.";
+ else
+ case $1 in #(
+ -*)set "./$1";;
+ esac;
+ case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #((
+ ???[sx]*):;;*)false;;esac;fi
+ '\'' sh
+ '
+fi
+as_executable_p=$as_test_x
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+
+exec 7<&0 </dev/null 6>&1
+
+# Name of the host.
+# hostname on some systems (SVR3.2, Linux) returns a bogus exit status,
+# so uname gets run too.
+ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
+
+#
+# Initializations.
+#
+ac_default_prefix=/usr/local
+ac_clean_files=
+ac_config_libobj_dir=.
+LIBOBJS=
+cross_compiling=no
+subdirs=
+MFLAGS=
+MAKEFLAGS=
+
+# Identity of this package.
+PACKAGE_NAME='bfd'
+PACKAGE_TARNAME='bfd'
+PACKAGE_VERSION='2.25'
+PACKAGE_STRING='bfd 2.25'
+PACKAGE_BUGREPORT=''
+PACKAGE_URL=''
+
+ac_unique_file="libbfd.c"
+# Factoring default headers for most tests.
+ac_includes_default="\
+#include <stdio.h>
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# ifdef HAVE_STDLIB_H
+# include <stdlib.h>
+# endif
+#endif
+#ifdef HAVE_STRING_H
+# if !defined STDC_HEADERS && defined HAVE_MEMORY_H
+# include <memory.h>
+# endif
+# include <string.h>
+#endif
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif
+#ifdef HAVE_INTTYPES_H
+# include <inttypes.h>
+#endif
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif"
+
+ac_subst_vars='am__EXEEXT_FALSE
+am__EXEEXT_TRUE
+LTLIBOBJS
+LIBOBJS
+havevecs
+tdefaults
+bfd_ufile_ptr
+bfd_file_ptr
+lt_cv_dlopen_libs
+supports_plugins
+bfd_default_target_size
+bfd_machines
+bfd_backends
+all_backends
+bfd64_libs
+wordsize
+TDEFINES
+SHARED_LIBADD
+SHARED_LDFLAGS
+LIBM
+COREFLAG
+COREFILE
+EXEEXT_FOR_BUILD
+CC_FOR_BUILD
+BFD_HOSTPTR_T
+BFD_HOST_U_64_BIT
+BFD_HOST_64_BIT
+BFD_HOST_64_BIT_DEFINED
+BFD_HOST_64BIT_LONG_LONG
+BFD_HOST_64BIT_LONG
+HDEFINES
+MSGMERGE
+MSGFMT
+MKINSTALLDIRS
+CATOBJEXT
+GENCAT
+INSTOBJEXT
+DATADIRNAME
+CATALOGS
+POSUB
+GMSGFMT
+XGETTEXT
+INCINTL
+LIBINTL_DEP
+LIBINTL
+USE_NLS
+bfdincludedir
+bfdlibdir
+target_noncanonical
+host_noncanonical
+INSTALL_LIBBFD_FALSE
+INSTALL_LIBBFD_TRUE
+GENINSRC_NEVER_FALSE
+GENINSRC_NEVER_TRUE
+MAINT
+MAINTAINER_MODE_FALSE
+MAINTAINER_MODE_TRUE
+NO_WERROR
+WARN_CFLAGS
+REPORT_BUGS_TEXI
+REPORT_BUGS_TO
+PKGVERSION
+DEBUGDIR
+PLUGINS_FALSE
+PLUGINS_TRUE
+OTOOL64
+OTOOL
+LIPO
+NMEDIT
+DSYMUTIL
+OBJDUMP
+LN_S
+NM
+ac_ct_DUMPBIN
+DUMPBIN
+LD
+FGREP
+SED
+LIBTOOL
+EGREP
+GREP
+CPP
+RANLIB
+AR
+am__fastdepCC_FALSE
+am__fastdepCC_TRUE
+CCDEPMODE
+AMDEPBACKSLASH
+AMDEP_FALSE
+AMDEP_TRUE
+am__quote
+am__include
+DEPDIR
+am__untar
+am__tar
+AMTAR
+am__leading_dot
+SET_MAKE
+AWK
+mkdir_p
+MKDIR_P
+INSTALL_STRIP_PROGRAM
+STRIP
+install_sh
+MAKEINFO
+AUTOHEADER
+AUTOMAKE
+AUTOCONF
+ACLOCAL
+VERSION
+PACKAGE
+CYGPATH_W
+am__isrc
+INSTALL_DATA
+INSTALL_SCRIPT
+INSTALL_PROGRAM
+OBJEXT
+EXEEXT
+ac_ct_CC
+CPPFLAGS
+LDFLAGS
+CFLAGS
+CC
+target_os
+target_vendor
+target_cpu
+target
+host_os
+host_vendor
+host_cpu
+host
+build_os
+build_vendor
+build_cpu
+build
+target_alias
+host_alias
+build_alias
+LIBS
+ECHO_T
+ECHO_N
+ECHO_C
+DEFS
+mandir
+localedir
+libdir
+psdir
+pdfdir
+dvidir
+htmldir
+infodir
+docdir
+oldincludedir
+includedir
+localstatedir
+sharedstatedir
+sysconfdir
+datadir
+datarootdir
+libexecdir
+sbindir
+bindir
+program_transform_name
+prefix
+exec_prefix
+PACKAGE_URL
+PACKAGE_BUGREPORT
+PACKAGE_STRING
+PACKAGE_VERSION
+PACKAGE_TARNAME
+PACKAGE_NAME
+PATH_SEPARATOR
+SHELL'
+ac_subst_files=''
+ac_user_opts='
+enable_option_checking
+enable_dependency_tracking
+enable_shared
+enable_static
+with_pic
+enable_fast_install
+with_gnu_ld
+enable_libtool_lock
+enable_plugins
+enable_largefile
+enable_64_bit_bfd
+enable_targets
+with_mmap
+enable_secureplt
+enable_leading_mingw64_underscores
+with_separate_debug_dir
+enable_elf_stt_common
+with_pkgversion
+with_bugurl
+enable_werror
+enable_build_warnings
+enable_maintainer_mode
+enable_install_libbfd
+enable_nls
+with_zlib
+'
+ ac_precious_vars='build_alias
+host_alias
+target_alias
+CC
+CFLAGS
+LDFLAGS
+LIBS
+CPPFLAGS
+CPP'
+
+
+# Initialize some variables set by options.
+ac_init_help=
+ac_init_version=false
+ac_unrecognized_opts=
+ac_unrecognized_sep=
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+cache_file=/dev/null
+exec_prefix=NONE
+no_create=
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+verbose=
+x_includes=NONE
+x_libraries=NONE
+
+# Installation directory options.
+# These are left unexpanded so users can "make install exec_prefix=/foo"
+# and all the variables that are supposed to be based on exec_prefix
+# by default will actually change.
+# Use braces instead of parens because sh, perl, etc. also accept them.
+# (The list follows the same order as the GNU Coding Standards.)
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datarootdir='${prefix}/share'
+datadir='${datarootdir}'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
+infodir='${datarootdir}/info'
+htmldir='${docdir}'
+dvidir='${docdir}'
+pdfdir='${docdir}'
+psdir='${docdir}'
+libdir='${exec_prefix}/lib'
+localedir='${datarootdir}/locale'
+mandir='${datarootdir}/man'
+
+ac_prev=
+ac_dashdash=
+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=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;
+ *) ac_optarg=yes ;;
+ esac
+
+ # Accept the important Cygnus configure options, so we can diagnose typos.
+
+ case $ac_dashdash$ac_option in
+ --)
+ ac_dashdash=yes ;;
+
+ -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_alias ;;
+ -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+ build_alias=$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 ;;
+
+ --config-cache | -C)
+ cache_file=config.cache ;;
+
+ -datadir | --datadir | --datadi | --datad)
+ ac_prev=datadir ;;
+ -datadir=* | --datadir=* | --datadi=* | --datad=*)
+ datadir=$ac_optarg ;;
+
+ -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \
+ | --dataroo | --dataro | --datar)
+ ac_prev=datarootdir ;;
+ -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \
+ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*)
+ datarootdir=$ac_optarg ;;
+
+ -disable-* | --disable-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ as_fn_error "invalid feature name: $ac_useropt"
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"enable_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval enable_$ac_useropt=no ;;
+
+ -docdir | --docdir | --docdi | --doc | --do)
+ ac_prev=docdir ;;
+ -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*)
+ docdir=$ac_optarg ;;
+
+ -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv)
+ ac_prev=dvidir ;;
+ -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*)
+ dvidir=$ac_optarg ;;
+
+ -enable-* | --enable-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ as_fn_error "invalid feature name: $ac_useropt"
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"enable_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval enable_$ac_useropt=\$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 | -h)
+ ac_init_help=long ;;
+ -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
+ ac_init_help=recursive ;;
+ -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
+ ac_init_help=short ;;
+
+ -host | --host | --hos | --ho)
+ ac_prev=host_alias ;;
+ -host=* | --host=* | --hos=* | --ho=*)
+ host_alias=$ac_optarg ;;
+
+ -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht)
+ ac_prev=htmldir ;;
+ -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \
+ | --ht=*)
+ htmldir=$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 ;;
+
+ -localedir | --localedir | --localedi | --localed | --locale)
+ ac_prev=localedir ;;
+ -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*)
+ localedir=$ac_optarg ;;
+
+ -localstatedir | --localstatedir | --localstatedi | --localstated \
+ | --localstate | --localstat | --localsta | --localst | --locals)
+ ac_prev=localstatedir ;;
+ -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*)
+ 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 | -n)
+ 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 ;;
+
+ -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd)
+ ac_prev=pdfdir ;;
+ -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*)
+ pdfdir=$ac_optarg ;;
+
+ -psdir | --psdir | --psdi | --psd | --ps)
+ ac_prev=psdir ;;
+ -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*)
+ psdir=$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_alias ;;
+ -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+ target_alias=$ac_optarg ;;
+
+ -v | -verbose | --verbose | --verbos | --verbo | --verb)
+ verbose=yes ;;
+
+ -version | --version | --versio | --versi | --vers | -V)
+ ac_init_version=: ;;
+
+ -with-* | --with-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ as_fn_error "invalid package name: $ac_useropt"
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"with_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval with_$ac_useropt=\$ac_optarg ;;
+
+ -without-* | --without-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ as_fn_error "invalid package name: $ac_useropt"
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"with_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval with_$ac_useropt=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 ;;
+
+ -*) as_fn_error "unrecognized option: \`$ac_option'
+Try \`$0 --help' for more information."
+ ;;
+
+ *=*)
+ ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
+ # Reject names that are not valid shell variable names.
+ case $ac_envvar in #(
+ '' | [0-9]* | *[!_$as_cr_alnum]* )
+ as_fn_error "invalid variable name: \`$ac_envvar'" ;;
+ esac
+ eval $ac_envvar=\$ac_optarg
+ export $ac_envvar ;;
+
+ *)
+ # FIXME: should be removed in autoconf 3.0.
+ $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2
+ expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+ $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2
+ : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}
+ ;;
+
+ esac
+done
+
+if test -n "$ac_prev"; then
+ ac_option=--`echo $ac_prev | sed 's/_/-/g'`
+ as_fn_error "missing argument to $ac_option"
+fi
+
+if test -n "$ac_unrecognized_opts"; then
+ case $enable_option_checking in
+ no) ;;
+ fatal) as_fn_error "unrecognized options: $ac_unrecognized_opts" ;;
+ *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;;
+ esac
+fi
+
+# Check all directory arguments for consistency.
+for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \
+ datadir sysconfdir sharedstatedir localstatedir includedir \
+ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
+ libdir localedir mandir
+do
+ eval ac_val=\$$ac_var
+ # Remove trailing slashes.
+ case $ac_val in
+ */ )
+ ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'`
+ eval $ac_var=\$ac_val;;
+ esac
+ # Be sure to have absolute directory names.
+ case $ac_val in
+ [\\/$]* | ?:[\\/]* ) continue;;
+ NONE | '' ) case $ac_var in *prefix ) continue;; esac;;
+ esac
+ as_fn_error "expected an absolute directory name for --$ac_var: $ac_val"
+done
+
+# There might be people who depend on the old broken behavior: `$host'
+# used to hold the argument of --host etc.
+# FIXME: To remove some day.
+build=$build_alias
+host=$host_alias
+target=$target_alias
+
+# FIXME: To remove some day.
+if test "x$host_alias" != x; then
+ if test "x$build_alias" = x; then
+ cross_compiling=maybe
+ $as_echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host.
+ If a cross compiler is detected then cross compile mode will be used." >&2
+ elif test "x$build_alias" != "x$host_alias"; then
+ cross_compiling=yes
+ fi
+fi
+
+ac_tool_prefix=
+test -n "$host_alias" && ac_tool_prefix=$host_alias-
+
+test "$silent" = yes && exec 6>/dev/null
+
+
+ac_pwd=`pwd` && test -n "$ac_pwd" &&
+ac_ls_di=`ls -di .` &&
+ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` ||
+ as_fn_error "working directory cannot be determined"
+test "X$ac_ls_di" = "X$ac_pwd_ls_di" ||
+ as_fn_error "pwd does not report name of working directory"
+
+
+# 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 the parent directory.
+ ac_confdir=`$as_dirname -- "$as_myself" ||
+$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_myself" : 'X\(//\)[^/]' \| \
+ X"$as_myself" : 'X\(//\)$' \| \
+ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_myself" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ 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
+ test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .."
+ as_fn_error "cannot find sources ($ac_unique_file) in $srcdir"
+fi
+ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work"
+ac_abs_confdir=`(
+ cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error "$ac_msg"
+ pwd)`
+# When building in place, set srcdir=.
+if test "$ac_abs_confdir" = "$ac_pwd"; then
+ srcdir=.
+fi
+# Remove unnecessary trailing slashes from srcdir.
+# Double slashes in file names in object file debugging info
+# mess up M-x gdb in Emacs.
+case $srcdir in
+*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;;
+esac
+for ac_var in $ac_precious_vars; do
+ eval ac_env_${ac_var}_set=\${${ac_var}+set}
+ eval ac_env_${ac_var}_value=\$${ac_var}
+ eval ac_cv_env_${ac_var}_set=\${${ac_var}+set}
+ eval ac_cv_env_${ac_var}_value=\$${ac_var}
+done
+
+#
+# Report the --help message.
+#
+if test "$ac_init_help" = "long"; then
+ # 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 <<_ACEOF
+\`configure' configures bfd 2.25 to adapt to many kinds of systems.
+
+Usage: $0 [OPTION]... [VAR=VALUE]...
+
+To assign environment variables (e.g., CC, CFLAGS...), specify them as
+VAR=VALUE. See below for descriptions of some of the useful variables.
+
+Defaults for the options are specified in brackets.
+
+Configuration:
+ -h, --help display this help and exit
+ --help=short display options specific to this package
+ --help=recursive display the short help of all the included packages
+ -V, --version display version information and exit
+ -q, --quiet, --silent do not print \`checking...' messages
+ --cache-file=FILE cache test results in FILE [disabled]
+ -C, --config-cache alias for \`--cache-file=config.cache'
+ -n, --no-create do not create output files
+ --srcdir=DIR find the sources in DIR [configure dir or \`..']
+
+Installation directories:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+ [$ac_default_prefix]
+ --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
+ [PREFIX]
+
+By default, \`make install' will install all the files in
+\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify
+an installation prefix other than \`$ac_default_prefix' using \`--prefix',
+for instance \`--prefix=\$HOME'.
+
+For better control, use the options below.
+
+Fine tuning of the installation directories:
+ --bindir=DIR user executables [EPREFIX/bin]
+ --sbindir=DIR system admin executables [EPREFIX/sbin]
+ --libexecdir=DIR program executables [EPREFIX/libexec]
+ --sysconfdir=DIR read-only single-machine data [PREFIX/etc]
+ --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
+ --localstatedir=DIR modifiable single-machine data [PREFIX/var]
+ --libdir=DIR object code libraries [EPREFIX/lib]
+ --includedir=DIR C header files [PREFIX/include]
+ --oldincludedir=DIR C header files for non-gcc [/usr/include]
+ --datarootdir=DIR read-only arch.-independent data root [PREFIX/share]
+ --datadir=DIR read-only architecture-independent data [DATAROOTDIR]
+ --infodir=DIR info documentation [DATAROOTDIR/info]
+ --localedir=DIR locale-dependent data [DATAROOTDIR/locale]
+ --mandir=DIR man documentation [DATAROOTDIR/man]
+ --docdir=DIR documentation root [DATAROOTDIR/doc/bfd]
+ --htmldir=DIR html documentation [DOCDIR]
+ --dvidir=DIR dvi documentation [DOCDIR]
+ --pdfdir=DIR pdf documentation [DOCDIR]
+ --psdir=DIR ps documentation [DOCDIR]
+_ACEOF
+
+ cat <<\_ACEOF
+
+Program names:
+ --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
+
+System types:
+ --build=BUILD configure for building on BUILD [guessed]
+ --host=HOST cross-compile to build programs to run on HOST [BUILD]
+ --target=TARGET configure for building compilers for TARGET [HOST]
+_ACEOF
+fi
+
+if test -n "$ac_init_help"; then
+ case $ac_init_help in
+ short | recursive ) echo "Configuration of bfd 2.25:";;
+ esac
+ cat <<\_ACEOF
+
+Optional Features:
+ --disable-option-checking ignore unrecognized --enable/--with options
+ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
+ --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
+ --disable-dependency-tracking speeds up one-time build
+ --enable-dependency-tracking do not reject slow dependency extractors
+ --enable-shared[=PKGS] build shared libraries [default=no]
+ --enable-static[=PKGS] build static libraries [default=yes]
+ --enable-fast-install[=PKGS]
+ optimize for fast installation [default=yes]
+ --disable-libtool-lock avoid locking (might break parallel builds)
+ --enable-plugins Enable support for plugins
+ --disable-largefile omit support for large files
+ --enable-64-bit-bfd 64-bit support (on hosts with narrower word sizes)
+ --enable-targets alternative target configurations
+ --enable-secureplt Default to creating read-only plt entries
+ --enable-leading-mingw64-underscores
+ Enable leading underscores on 64 bit mingw targets
+ --enable-elf-stt-common Allow the generation of ELF symbols with the STT_COMMON type
+ --enable-werror treat compile warnings as errors
+ --enable-build-warnings enable build-time compiler warnings
+ --enable-maintainer-mode enable make rules and dependencies not useful
+ (and sometimes confusing) to the casual installer
+ --enable-install-libbfd controls installation of libbfd and related headers
+ --disable-nls do not use Native Language Support
+
+Optional Packages:
+ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
+ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
+ --with-pic try to use only PIC/non-PIC objects [default=use
+ both]
+ --with-gnu-ld assume the C compiler uses GNU ld [default=no]
+ --with-mmap try using mmap for BFD input files if available
+ --with-separate-debug-dir=DIR
+ Look for global separate debug info in DIR
+ [default=LIBDIR/debug]
+ --with-pkgversion=PKG Use PKG in the version string in place of "GNU
+ Binutils"
+ --with-bugurl=URL Direct users to URL to report a bug
+ --with-zlib include zlib support (auto/yes/no) default=auto
+
+Some influential environment variables:
+ CC C compiler command
+ CFLAGS C compiler flags
+ LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a
+ nonstandard directory <lib dir>
+ LIBS libraries to pass to the linker, e.g. -l<library>
+ CPPFLAGS C/C++/Objective C preprocessor flags, e.g. -I<include dir> if
+ you have headers in a nonstandard directory <include dir>
+ CPP C preprocessor
+
+Use these variables to override the choices made by `configure' or to help
+it to find libraries and programs with nonstandard names/locations.
+
+Report bugs to the package provider.
+_ACEOF
+ac_status=$?
+fi
+
+if test "$ac_init_help" = "recursive"; then
+ # If there are subdirs, report their specific --help.
+ for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
+ test -d "$ac_dir" ||
+ { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } ||
+ continue
+ ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+ ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+ # A ".." for each directory in $ac_dir_suffix.
+ ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+ case $ac_top_builddir_sub in
+ "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+ *) ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+ esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+ .) # We are building in place.
+ ac_srcdir=.
+ ac_top_srcdir=$ac_top_builddir_sub
+ ac_abs_top_srcdir=$ac_pwd ;;
+ [\\/]* | ?:[\\/]* ) # Absolute name.
+ ac_srcdir=$srcdir$ac_dir_suffix;
+ ac_top_srcdir=$srcdir
+ ac_abs_top_srcdir=$srcdir ;;
+ *) # Relative name.
+ ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+ ac_top_srcdir=$ac_top_build_prefix$srcdir
+ ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+ cd "$ac_dir" || { ac_status=$?; continue; }
+ # Check for guested configure.
+ if test -f "$ac_srcdir/configure.gnu"; then
+ echo &&
+ $SHELL "$ac_srcdir/configure.gnu" --help=recursive
+ elif test -f "$ac_srcdir/configure"; then
+ echo &&
+ $SHELL "$ac_srcdir/configure" --help=recursive
+ else
+ $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
+ fi || ac_status=$?
+ cd "$ac_pwd" || { ac_status=$?; break; }
+ done
+fi
+
+test -n "$ac_init_help" && exit $ac_status
+if $ac_init_version; then
+ cat <<\_ACEOF
+bfd configure 2.25
+generated by GNU Autoconf 2.64
+
+Copyright (C) 2009 Free Software Foundation, Inc.
+This configure script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it.
+_ACEOF
+ exit
+fi
+
+## ------------------------ ##
+## Autoconf initialization. ##
+## ------------------------ ##
+
+# ac_fn_c_try_compile LINENO
+# --------------------------
+# Try to compile conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_compile ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ rm -f conftest.$ac_objext
+ if { { ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_compile") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ grep -v '^ *+' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ mv -f conftest.er1 conftest.err
+ fi
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=1
+fi
+ eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+ return $ac_retval
+
+} # ac_fn_c_try_compile
+
+# ac_fn_c_try_link LINENO
+# -----------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_link ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ rm -f conftest.$ac_objext conftest$ac_exeext
+ if { { ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ grep -v '^ *+' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ mv -f conftest.er1 conftest.err
+ fi
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest$ac_exeext && {
+ test "$cross_compiling" = yes ||
+ $as_test_x conftest$ac_exeext
+ }; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=1
+fi
+ # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information
+ # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would
+ # interfere with the next link command; also delete a directory that is
+ # left behind by Apple's compiler. We do this before executing the actions.
+ rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+ eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+ return $ac_retval
+
+} # ac_fn_c_try_link
+
+# ac_fn_c_try_cpp LINENO
+# ----------------------
+# Try to preprocess conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_cpp ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ if { { ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ grep -v '^ *+' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ mv -f conftest.er1 conftest.err
+ fi
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } >/dev/null && {
+ test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ }; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=1
+fi
+ eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+ return $ac_retval
+
+} # ac_fn_c_try_cpp
+
+# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES
+# -------------------------------------------------------
+# Tests whether HEADER exists, giving a warning if it cannot be compiled using
+# the include files in INCLUDES and setting the cache variable VAR
+# accordingly.
+ac_fn_c_check_header_mongrel ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
+ $as_echo_n "(cached) " >&6
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+else
+ # Is the header compilable?
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5
+$as_echo_n "checking $2 usability... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+#include <$2>
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_header_compiler=yes
+else
+ ac_header_compiler=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5
+$as_echo "$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5
+$as_echo_n "checking $2 presence... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <$2>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+ ac_header_preproc=yes
+else
+ ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5
+$as_echo "$ac_header_preproc" >&6; }
+
+# So? What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #((
+ yes:no: )
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5
+$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
+ ;;
+ no:yes:* )
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5
+$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5
+$as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5
+$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5
+$as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
+ ;;
+esac
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
+ $as_echo_n "(cached) " >&6
+else
+ eval "$3=\$ac_header_compiler"
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+fi
+ eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+
+} # ac_fn_c_check_header_mongrel
+
+# ac_fn_c_try_run LINENO
+# ----------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes
+# that executables *can* be run.
+ac_fn_c_try_run ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ if { { ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && { ac_try='./conftest$ac_exeext'
+ { { case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: program exited with status $ac_status" >&5
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=$ac_status
+fi
+ rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+ eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+ return $ac_retval
+
+} # ac_fn_c_try_run
+
+# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES
+# -------------------------------------------------------
+# Tests whether HEADER exists and can be compiled using the include files in
+# INCLUDES, setting the cache variable VAR accordingly.
+ac_fn_c_check_header_compile ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+#include <$2>
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ eval "$3=yes"
+else
+ eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+ eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+
+} # ac_fn_c_check_header_compile
+
+# ac_fn_c_check_func LINENO FUNC VAR
+# ----------------------------------
+# Tests whether FUNC exists, setting the cache variable VAR accordingly
+ac_fn_c_check_func ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+/* Define $2 to an innocuous variant, in case <limits.h> declares $2.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $2 innocuous_$2
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $2 (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $2
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char $2 ();
+/* 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_$2 || defined __stub___$2
+choke me
+#endif
+
+int
+main ()
+{
+return $2 ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ eval "$3=yes"
+else
+ eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+ eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+
+} # ac_fn_c_check_func
+
+# ac_fn_c_compute_int LINENO EXPR VAR INCLUDES
+# --------------------------------------------
+# Tries to find the compile-time value of EXPR in a program that includes
+# INCLUDES, setting VAR accordingly. Returns whether the value could be
+# computed
+ac_fn_c_compute_int ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ if test "$cross_compiling" = yes; then
+ # Depending upon the size, compute the lo and hi bounds.
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) >= 0)];
+test_array [0] = 0
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_lo=0 ac_mid=0
+ while :; do
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) <= $ac_mid)];
+test_array [0] = 0
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_hi=$ac_mid; break
+else
+ as_fn_arith $ac_mid + 1 && ac_lo=$as_val
+ if test $ac_lo -le $ac_mid; then
+ ac_lo= ac_hi=
+ break
+ fi
+ as_fn_arith 2 '*' $ac_mid + 1 && ac_mid=$as_val
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ done
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) < 0)];
+test_array [0] = 0
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_hi=-1 ac_mid=-1
+ while :; do
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) >= $ac_mid)];
+test_array [0] = 0
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_lo=$ac_mid; break
+else
+ as_fn_arith '(' $ac_mid ')' - 1 && ac_hi=$as_val
+ if test $ac_mid -le $ac_hi; then
+ ac_lo= ac_hi=
+ break
+ fi
+ as_fn_arith 2 '*' $ac_mid && ac_mid=$as_val
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ done
+else
+ ac_lo= ac_hi=
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+# Binary search between lo and hi bounds.
+while test "x$ac_lo" != "x$ac_hi"; do
+ as_fn_arith '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo && ac_mid=$as_val
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) <= $ac_mid)];
+test_array [0] = 0
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_hi=$ac_mid
+else
+ as_fn_arith '(' $ac_mid ')' + 1 && ac_lo=$as_val
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+case $ac_lo in #((
+?*) eval "$3=\$ac_lo"; ac_retval=0 ;;
+'') ac_retval=1 ;;
+esac
+ else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+static long int longval () { return $2; }
+static unsigned long int ulongval () { return $2; }
+#include <stdio.h>
+#include <stdlib.h>
+int
+main ()
+{
+
+ FILE *f = fopen ("conftest.val", "w");
+ if (! f)
+ return 1;
+ if (($2) < 0)
+ {
+ long int i = longval ();
+ if (i != ($2))
+ return 1;
+ fprintf (f, "%ld", i);
+ }
+ else
+ {
+ unsigned long int i = ulongval ();
+ if (i != ($2))
+ return 1;
+ fprintf (f, "%lu", i);
+ }
+ /* Do not output a trailing newline, as this causes \r\n confusion
+ on some platforms. */
+ return ferror (f) || fclose (f) != 0;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+ echo >>conftest.val; read $3 <conftest.val; ac_retval=0
+else
+ ac_retval=1
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+rm -f conftest.val
+
+ fi
+ eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+ return $ac_retval
+
+} # ac_fn_c_compute_int
+
+# ac_fn_c_check_type LINENO TYPE VAR INCLUDES
+# -------------------------------------------
+# Tests whether TYPE exists after having included INCLUDES, setting cache
+# variable VAR accordingly.
+ac_fn_c_check_type ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
+ $as_echo_n "(cached) " >&6
+else
+ eval "$3=no"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+int
+main ()
+{
+if (sizeof ($2))
+ return 0;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+int
+main ()
+{
+if (sizeof (($2)))
+ return 0;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+else
+ eval "$3=yes"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+ eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+
+} # ac_fn_c_check_type
+
+# ac_fn_c_check_decl LINENO SYMBOL VAR
+# ------------------------------------
+# Tests whether SYMBOL is declared, setting cache variable VAR accordingly.
+ac_fn_c_check_decl ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ as_decl_name=`echo $2|sed 's/ *(.*//'`
+ as_decl_use=`echo $2|sed -e 's/(/((/' -e 's/)/) 0&/' -e 's/,/) 0& (/g'`
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $as_decl_name is declared" >&5
+$as_echo_n "checking whether $as_decl_name is declared... " >&6; }
+if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+int
+main ()
+{
+#ifndef $as_decl_name
+#ifdef __cplusplus
+ (void) $as_decl_use;
+#else
+ (void) $as_decl_name;
+#endif
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ eval "$3=yes"
+else
+ eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+ eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+
+} # ac_fn_c_check_decl
+cat >config.log <<_ACEOF
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+
+It was created by bfd $as_me 2.25, which was
+generated by GNU Autoconf 2.64. Invocation command line was
+
+ $ $0 $@
+
+_ACEOF
+exec 5>>config.log
+{
+cat <<_ASUNAME
+## --------- ##
+## Platform. ##
+## --------- ##
+
+hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
+/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown`
+
+/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown`
+/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
+/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown`
+/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown`
+/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown`
+/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown`
+
+_ASUNAME
+
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ $as_echo "PATH: $as_dir"
+ done
+IFS=$as_save_IFS
+
+} >&5
+
+cat >&5 <<_ACEOF
+
+
+## ----------- ##
+## Core tests. ##
+## ----------- ##
+
+_ACEOF
+
+
+# Keep a trace of the command line.
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Strip out --silent because we don't want to record it for future runs.
+# Also quote any args containing shell meta-characters.
+# Make two passes to allow for proper duplicate-argument suppression.
+ac_configure_args=
+ac_configure_args0=
+ac_configure_args1=
+ac_must_keep_next=false
+for ac_pass in 1 2
+do
+ for ac_arg
+ do
+ case $ac_arg in
+ -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ continue ;;
+ *\'*)
+ ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ esac
+ case $ac_pass in
+ 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;;
+ 2)
+ as_fn_append ac_configure_args1 " '$ac_arg'"
+ if test $ac_must_keep_next = true; then
+ ac_must_keep_next=false # Got value, back to normal.
+ else
+ case $ac_arg in
+ *=* | --config-cache | -C | -disable-* | --disable-* \
+ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
+ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
+ | -with-* | --with-* | -without-* | --without-* | --x)
+ case "$ac_configure_args0 " in
+ "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
+ esac
+ ;;
+ -* ) ac_must_keep_next=true ;;
+ esac
+ fi
+ as_fn_append ac_configure_args " '$ac_arg'"
+ ;;
+ esac
+ done
+done
+{ ac_configure_args0=; unset ac_configure_args0;}
+{ ac_configure_args1=; unset ac_configure_args1;}
+
+# When interrupted or exit'd, cleanup temporary files, and complete
+# config.log. We remove comments because anyway the quotes in there
+# would cause problems or look ugly.
+# WARNING: Use '\'' to represent an apostrophe within the trap.
+# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug.
+trap 'exit_status=$?
+ # Save into config.log some information that might help in debugging.
+ {
+ echo
+
+ cat <<\_ASBOX
+## ---------------- ##
+## Cache variables. ##
+## ---------------- ##
+_ASBOX
+ echo
+ # The following way of writing the cache mishandles newlines in values,
+(
+ for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do
+ eval ac_val=\$$ac_var
+ case $ac_val in #(
+ *${as_nl}*)
+ case $ac_var in #(
+ *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+ esac
+ case $ac_var in #(
+ _ | IFS | as_nl) ;; #(
+ BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+ *) { eval $ac_var=; unset $ac_var;} ;;
+ esac ;;
+ esac
+ done
+ (set) 2>&1 |
+ case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #(
+ *${as_nl}ac_space=\ *)
+ sed -n \
+ "s/'\''/'\''\\\\'\'''\''/g;
+ s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p"
+ ;; #(
+ *)
+ sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+ ;;
+ esac |
+ sort
+)
+ echo
+
+ cat <<\_ASBOX
+## ----------------- ##
+## Output variables. ##
+## ----------------- ##
+_ASBOX
+ echo
+ for ac_var in $ac_subst_vars
+ do
+ eval ac_val=\$$ac_var
+ case $ac_val in
+ *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+ esac
+ $as_echo "$ac_var='\''$ac_val'\''"
+ done | sort
+ echo
+
+ if test -n "$ac_subst_files"; then
+ cat <<\_ASBOX
+## ------------------- ##
+## File substitutions. ##
+## ------------------- ##
+_ASBOX
+ echo
+ for ac_var in $ac_subst_files
+ do
+ eval ac_val=\$$ac_var
+ case $ac_val in
+ *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+ esac
+ $as_echo "$ac_var='\''$ac_val'\''"
+ done | sort
+ echo
+ fi
+
+ if test -s confdefs.h; then
+ cat <<\_ASBOX
+## ----------- ##
+## confdefs.h. ##
+## ----------- ##
+_ASBOX
+ echo
+ cat confdefs.h
+ echo
+ fi
+ test "$ac_signal" != 0 &&
+ $as_echo "$as_me: caught signal $ac_signal"
+ $as_echo "$as_me: exit $exit_status"
+ } >&5
+ rm -f core *.core core.conftest.* &&
+ rm -f -r conftest* confdefs* conf$$* $ac_clean_files &&
+ exit $exit_status
+' 0
+for ac_signal in 1 2 13 15; do
+ trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal
+done
+ac_signal=0
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -f -r conftest* confdefs.h
+
+$as_echo "/* confdefs.h */" > confdefs.h
+
+# Predefined preprocessor variables.
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_NAME "$PACKAGE_NAME"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_VERSION "$PACKAGE_VERSION"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_STRING "$PACKAGE_STRING"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_URL "$PACKAGE_URL"
+_ACEOF
+
+
+# Let the site file select an alternate cache file if it wants to.
+# Prefer an explicitly selected file to automatically selected ones.
+ac_site_file1=NONE
+ac_site_file2=NONE
+if test -n "$CONFIG_SITE"; then
+ ac_site_file1=$CONFIG_SITE
+elif test "x$prefix" != xNONE; then
+ ac_site_file1=$prefix/share/config.site
+ ac_site_file2=$prefix/etc/config.site
+else
+ ac_site_file1=$ac_default_prefix/share/config.site
+ ac_site_file2=$ac_default_prefix/etc/config.site
+fi
+for ac_site_file in "$ac_site_file1" "$ac_site_file2"
+do
+ test "x$ac_site_file" = xNONE && continue
+ if test -r "$ac_site_file"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5
+$as_echo "$as_me: loading site script $ac_site_file" >&6;}
+ sed 's/^/| /' "$ac_site_file" >&5
+ . "$ac_site_file"
+ fi
+done
+
+if test -r "$cache_file"; then
+ # Some versions of bash will fail to source /dev/null (special
+ # files actually), so we avoid doing that.
+ if test -f "$cache_file"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5
+$as_echo "$as_me: loading cache $cache_file" >&6;}
+ case $cache_file in
+ [\\/]* | ?:[\\/]* ) . "$cache_file";;
+ *) . "./$cache_file";;
+ esac
+ fi
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5
+$as_echo "$as_me: creating cache $cache_file" >&6;}
+ >$cache_file
+fi
+
+# Check that the precious variables saved in the cache have kept the same
+# value.
+ac_cache_corrupted=false
+for ac_var in $ac_precious_vars; do
+ eval ac_old_set=\$ac_cv_env_${ac_var}_set
+ eval ac_new_set=\$ac_env_${ac_var}_set
+ eval ac_old_val=\$ac_cv_env_${ac_var}_value
+ eval ac_new_val=\$ac_env_${ac_var}_value
+ case $ac_old_set,$ac_new_set in
+ set,)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
+$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
+ ac_cache_corrupted=: ;;
+ ,set)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5
+$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
+ ac_cache_corrupted=: ;;
+ ,);;
+ *)
+ if test "x$ac_old_val" != "x$ac_new_val"; then
+ # differences in whitespace do not lead to failure.
+ ac_old_val_w=`echo x $ac_old_val`
+ ac_new_val_w=`echo x $ac_new_val`
+ if test "$ac_old_val_w" != "$ac_new_val_w"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5
+$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+ ac_cache_corrupted=:
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5
+$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;}
+ eval $ac_var=\$ac_old_val
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5
+$as_echo "$as_me: former value: \`$ac_old_val'" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5
+$as_echo "$as_me: current value: \`$ac_new_val'" >&2;}
+ fi;;
+ esac
+ # Pass precious variables to config.status.
+ if test "$ac_new_set" = set; then
+ case $ac_new_val in
+ *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
+ *) ac_arg=$ac_var=$ac_new_val ;;
+ esac
+ case " $ac_configure_args " in
+ *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy.
+ *) as_fn_append ac_configure_args " '$ac_arg'" ;;
+ esac
+ fi
+done
+if $ac_cache_corrupted; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5
+$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;}
+ as_fn_error "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5
+fi
+## -------------------- ##
+## Main body of script. ##
+## -------------------- ##
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+
+
+
+
+ac_aux_dir=
+for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do
+ for ac_t in install-sh install.sh shtool; do
+ if test -f "$ac_dir/$ac_t"; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/$ac_t -c"
+ break 2
+ fi
+ done
+done
+if test -z "$ac_aux_dir"; then
+ as_fn_error "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5
+fi
+
+# These three variables are undocumented and unsupported,
+# and are intended to be withdrawn in a future Autoconf release.
+# They can cause serious problems if a builder's source tree is in a directory
+# whose full name contains unusual characters.
+ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var.
+ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var.
+ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var.
+
+
+# Make sure we can run config.sub.
+$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 ||
+ as_fn_error "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5
+$as_echo_n "checking build system type... " >&6; }
+if test "${ac_cv_build+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_build_alias=$build_alias
+test "x$ac_build_alias" = x &&
+ ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"`
+test "x$ac_build_alias" = x &&
+ as_fn_error "cannot guess build type; you must specify one" "$LINENO" 5
+ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` ||
+ as_fn_error "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5
+$as_echo "$ac_cv_build" >&6; }
+case $ac_cv_build in
+*-*-*) ;;
+*) as_fn_error "invalid value of canonical build" "$LINENO" 5;;
+esac
+build=$ac_cv_build
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_build
+shift
+build_cpu=$1
+build_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+build_os=$*
+IFS=$ac_save_IFS
+case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5
+$as_echo_n "checking host system type... " >&6; }
+if test "${ac_cv_host+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test "x$host_alias" = x; then
+ ac_cv_host=$ac_cv_build
+else
+ ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` ||
+ as_fn_error "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5
+$as_echo "$ac_cv_host" >&6; }
+case $ac_cv_host in
+*-*-*) ;;
+*) as_fn_error "invalid value of canonical host" "$LINENO" 5;;
+esac
+host=$ac_cv_host
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_host
+shift
+host_cpu=$1
+host_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+host_os=$*
+IFS=$ac_save_IFS
+case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking target system type" >&5
+$as_echo_n "checking target system type... " >&6; }
+if test "${ac_cv_target+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test "x$target_alias" = x; then
+ ac_cv_target=$ac_cv_host
+else
+ ac_cv_target=`$SHELL "$ac_aux_dir/config.sub" $target_alias` ||
+ as_fn_error "$SHELL $ac_aux_dir/config.sub $target_alias failed" "$LINENO" 5
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_target" >&5
+$as_echo "$ac_cv_target" >&6; }
+case $ac_cv_target in
+*-*-*) ;;
+*) as_fn_error "invalid value of canonical target" "$LINENO" 5;;
+esac
+target=$ac_cv_target
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_target
+shift
+target_cpu=$1
+target_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+target_os=$*
+IFS=$ac_save_IFS
+case $target_os in *\ *) target_os=`echo "$target_os" | sed 's/ /-/g'`;; esac
+
+
+# The aliases save the names the user supplied, while $host etc.
+# will get canonicalized.
+test -n "$target_alias" &&
+ test "$program_prefix$program_suffix$program_transform_name" = \
+ NONENONEs,x,x, &&
+ program_prefix=${target_alias}-
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}gcc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_CC="${ac_tool_prefix}gcc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+ ac_ct_CC=$CC
+ # Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_ac_ct_CC="gcc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_CC" = x; then
+ CC=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ CC=$ac_ct_CC
+ fi
+else
+ CC="$ac_cv_prog_CC"
+fi
+
+if test -z "$CC"; then
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_CC="${ac_tool_prefix}cc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ fi
+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
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ ac_prog_rejected=no
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+ ac_prog_rejected=yes
+ continue
+ fi
+ ac_cv_prog_CC="cc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_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 $# != 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
+ ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
+ fi
+fi
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$CC"; then
+ if test -n "$ac_tool_prefix"; then
+ for ac_prog in cl.exe
+ do
+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$CC" && break
+ done
+fi
+if test -z "$CC"; then
+ ac_ct_CC=$CC
+ for ac_prog in cl.exe
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_ac_ct_CC="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$ac_ct_CC" && break
+done
+
+ if test "x$ac_ct_CC" = x; then
+ CC=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ CC=$ac_ct_CC
+ fi
+fi
+
+fi
+
+
+test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error "no acceptable C compiler found in \$PATH
+See \`config.log' for more details." "$LINENO" 5; }
+
+# Provide some information about the compiler.
+$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5
+set X $ac_compile
+ac_compiler=$2
+for ac_option in --version -v -V -qversion; do
+ { { ac_try="$ac_compiler $ac_option >&5"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_compiler $ac_option >&5") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ sed '10a\
+... rest of stderr output deleted ...
+ 10q' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ rm -f conftest.er1 conftest.err
+ fi
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+done
+
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out conftest.out"
+# Try to create an executable without -o first, disregard a.out.
+# It will help us diagnose broken compilers, and finding out an intuition
+# of exeext.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5
+$as_echo_n "checking for C compiler default output file name... " >&6; }
+ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
+
+# The possible output files:
+ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*"
+
+ac_rmfiles=
+for ac_file in $ac_files
+do
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
+ * ) ac_rmfiles="$ac_rmfiles $ac_file";;
+ esac
+done
+rm -f $ac_rmfiles
+
+if { { ac_try="$ac_link_default"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link_default") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then :
+ # Autoconf-2.13 could set the ac_cv_exeext variable to `no'.
+# So ignore a value of `no', otherwise this would lead to `EXEEXT = no'
+# in a Makefile. We should not override ac_cv_exeext if it was cached,
+# so that the user can short-circuit this test for compilers unknown to
+# Autoconf.
+for ac_file in $ac_files ''
+do
+ test -f "$ac_file" || continue
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj )
+ ;;
+ [ab].out )
+ # We found the default executable, but exeext='' is most
+ # certainly right.
+ break;;
+ *.* )
+ if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no;
+ then :; else
+ ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+ fi
+ # We set ac_cv_exeext here because the later test for it is not
+ # safe: cross compilers may not add the suffix if given an `-o'
+ # argument, so we may need to know it at that point already.
+ # Even if this section looks crufty: it has the advantage of
+ # actually working.
+ break;;
+ * )
+ break;;
+ esac
+done
+test "$ac_cv_exeext" = no && ac_cv_exeext=
+
+else
+ ac_file=''
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5
+$as_echo "$ac_file" >&6; }
+if test -z "$ac_file"; then :
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+{ as_fn_set_status 77
+as_fn_error "C compiler cannot create executables
+See \`config.log' for more details." "$LINENO" 5; }; }
+fi
+ac_exeext=$ac_cv_exeext
+
+# Check that the compiler produces executables we can run. If not, either
+# the compiler is broken, or we cross compile.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5
+$as_echo_n "checking whether the C compiler works... " >&6; }
+# If not cross compiling, check that we can run a simple program.
+if test "$cross_compiling" != yes; then
+ if { ac_try='./$ac_file'
+ { { case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }; then
+ cross_compiling=no
+ else
+ if test "$cross_compiling" = maybe; then
+ cross_compiling=yes
+ else
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error "cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details." "$LINENO" 5; }
+ fi
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out conftest.out
+ac_clean_files=$ac_clean_files_save
+# Check that the compiler produces executables we can run. If not, either
+# the compiler is broken, or we cross compile.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5
+$as_echo_n "checking whether we are cross compiling... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5
+$as_echo "$cross_compiling" >&6; }
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5
+$as_echo_n "checking for suffix of executables... " >&6; }
+if { { ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then :
+ # If both `conftest.exe' and `conftest' are `present' (well, observable)
+# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will
+# work properly (i.e., refer to `conftest.exe'), while it won't with
+# `rm'.
+for ac_file in conftest.exe conftest conftest.*; do
+ test -f "$ac_file" || continue
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
+ *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+ break;;
+ * ) break;;
+ esac
+done
+else
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error "cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details." "$LINENO" 5; }
+fi
+rm -f conftest$ac_cv_exeext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5
+$as_echo "$ac_cv_exeext" >&6; }
+
+rm -f conftest.$ac_ext
+EXEEXT=$ac_cv_exeext
+ac_exeext=$EXEEXT
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5
+$as_echo_n "checking for suffix of object files... " >&6; }
+if test "${ac_cv_objext+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.o conftest.obj
+if { { ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_compile") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then :
+ for ac_file in conftest.o conftest.obj conftest.*; do
+ test -f "$ac_file" || continue;
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;;
+ *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
+ break;;
+ esac
+done
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error "cannot compute suffix of object files: cannot compile
+See \`config.log' for more details." "$LINENO" 5; }
+fi
+rm -f conftest.$ac_cv_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5
+$as_echo "$ac_cv_objext" >&6; }
+OBJEXT=$ac_cv_objext
+ac_objext=$OBJEXT
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5
+$as_echo_n "checking whether we are using the GNU C compiler... " >&6; }
+if test "${ac_cv_c_compiler_gnu+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+#ifndef __GNUC__
+ choke me
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_compiler_gnu=yes
+else
+ ac_compiler_gnu=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_c_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5
+$as_echo "$ac_cv_c_compiler_gnu" >&6; }
+if test $ac_compiler_gnu = yes; then
+ GCC=yes
+else
+ GCC=
+fi
+ac_test_CFLAGS=${CFLAGS+set}
+ac_save_CFLAGS=$CFLAGS
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5
+$as_echo_n "checking whether $CC accepts -g... " >&6; }
+if test "${ac_cv_prog_cc_g+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_save_c_werror_flag=$ac_c_werror_flag
+ ac_c_werror_flag=yes
+ ac_cv_prog_cc_g=no
+ CFLAGS="-g"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_prog_cc_g=yes
+else
+ CFLAGS=""
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+else
+ ac_c_werror_flag=$ac_save_c_werror_flag
+ CFLAGS="-g"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_prog_cc_g=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_c_werror_flag=$ac_save_c_werror_flag
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5
+$as_echo "$ac_cv_prog_cc_g" >&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
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5
+$as_echo_n "checking for $CC option to accept ISO C89... " >&6; }
+if test "${ac_cv_prog_cc_c89+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_cv_prog_cc_c89=no
+ac_save_CC=$CC
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdarg.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+ char **p;
+ int i;
+{
+ return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+ char *s;
+ va_list v;
+ va_start (v,p);
+ s = g (p, va_arg (v,int));
+ va_end (v);
+ return s;
+}
+
+/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has
+ function prototypes and stuff, but not '\xHH' hex character constants.
+ These don't provoke an error unfortunately, instead are silently treated
+ as 'x'. The following induces an error, until -std is added to get
+ proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an
+ array size at least. It's necessary to write '\x00'==0 to get something
+ that's true only with -std. */
+int osf4_cc_array ['\x00' == 0 ? 1 : -1];
+
+/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
+ inside strings and character constants. */
+#define FOO(x) 'x'
+int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];
+
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+int
+main ()
+{
+return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1];
+ ;
+ return 0;
+}
+_ACEOF
+for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \
+ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+ CC="$ac_save_CC $ac_arg"
+ if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_prog_cc_c89=$ac_arg
+fi
+rm -f core conftest.err conftest.$ac_objext
+ test "x$ac_cv_prog_cc_c89" != "xno" && break
+done
+rm -f conftest.$ac_ext
+CC=$ac_save_CC
+
+fi
+# AC_CACHE_VAL
+case "x$ac_cv_prog_cc_c89" in
+ x)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
+$as_echo "none needed" >&6; } ;;
+ xno)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
+$as_echo "unsupported" >&6; } ;;
+ *)
+ CC="$CC $ac_cv_prog_cc_c89"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5
+$as_echo "$ac_cv_prog_cc_c89" >&6; } ;;
+esac
+if test "x$ac_cv_prog_cc_c89" != xno; then :
+
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing strerror" >&5
+$as_echo_n "checking for library containing strerror... " >&6; }
+if test "${ac_cv_search_strerror+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_func_search_save_LIBS=$LIBS
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char strerror ();
+int
+main ()
+{
+return strerror ();
+ ;
+ return 0;
+}
+_ACEOF
+for ac_lib in '' cposix; do
+ if test -z "$ac_lib"; then
+ ac_res="none required"
+ else
+ ac_res=-l$ac_lib
+ LIBS="-l$ac_lib $ac_func_search_save_LIBS"
+ fi
+ if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_search_strerror=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext
+ if test "${ac_cv_search_strerror+set}" = set; then :
+ break
+fi
+done
+if test "${ac_cv_search_strerror+set}" = set; then :
+
+else
+ ac_cv_search_strerror=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_strerror" >&5
+$as_echo "$ac_cv_search_strerror" >&6; }
+ac_res=$ac_cv_search_strerror
+if test "$ac_res" != no; then :
+ test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+fi
+
+
+am__api_version='1.11'
+
+# 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
+# AmigaOS /C/install, which installs bootblocks on floppy discs
+# 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"
+# OS/2's system install, which has a completely different semantic
+# ./install, which can be erroneously created by make from ./install.sh.
+# Reject install programs that cannot install multiple files.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5
+$as_echo_n "checking for a BSD-compatible install... " >&6; }
+if test -z "$INSTALL"; then
+if test "${ac_cv_path_install+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ # Account for people who put trailing slashes in PATH elements.
+case $as_dir/ in #((
+ ./ | .// | /[cC]/* | \
+ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
+ ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \
+ /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
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then
+ if test $ac_prog = install &&
+ grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+ # AIX install. It has an incompatible calling convention.
+ :
+ elif test $ac_prog = install &&
+ grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+ # program-specific install script used by HP pwplus--don't use.
+ :
+ else
+ rm -rf conftest.one conftest.two conftest.dir
+ echo one > conftest.one
+ echo two > conftest.two
+ mkdir conftest.dir
+ if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" &&
+ test -s conftest.one && test -s conftest.two &&
+ test -s conftest.dir/conftest.one &&
+ test -s conftest.dir/conftest.two
+ then
+ ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
+ break 3
+ fi
+ fi
+ fi
+ done
+ done
+ ;;
+esac
+
+ done
+IFS=$as_save_IFS
+
+rm -rf conftest.one conftest.two conftest.dir
+
+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. Don't cache a
+ # value for INSTALL within a source directory, because that will
+ # break other packages using the cache if that directory is
+ # removed, or if the value is a relative name.
+ INSTALL=$ac_install_sh
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5
+$as_echo "$INSTALL" >&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}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5
+$as_echo_n "checking whether build environment is sane... " >&6; }
+# Just in case
+sleep 1
+echo timestamp > conftest.file
+# Reject unsafe characters in $srcdir or the absolute working directory
+# name. Accept space and tab only in the latter.
+am_lf='
+'
+case `pwd` in
+ *[\\\"\#\$\&\'\`$am_lf]*)
+ as_fn_error "unsafe absolute working directory name" "$LINENO" 5;;
+esac
+case $srcdir in
+ *[\\\"\#\$\&\'\`$am_lf\ \ ]*)
+ as_fn_error "unsafe srcdir value: \`$srcdir'" "$LINENO" 5;;
+esac
+
+# 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" conftest.file 2> /dev/null`
+ if test "$*" = "X"; then
+ # -L didn't work.
+ set X `ls -t "$srcdir/configure" conftest.file`
+ fi
+ rm -f conftest.file
+ if test "$*" != "X $srcdir/configure conftest.file" \
+ && test "$*" != "X conftest.file $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".
+ as_fn_error "ls -t appears to fail. Make sure there is not a broken
+alias in your environment" "$LINENO" 5
+ fi
+
+ test "$2" = conftest.file
+ )
+then
+ # Ok.
+ :
+else
+ as_fn_error "newly created file is older than distributed files!
+Check your system clock" "$LINENO" 5
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+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"
+# Double any \ or $.
+# By default was `s,x,x', remove it if useless.
+ac_script='s/[\\$]/&&/g;s/;s,x,x,$//'
+program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"`
+
+# expand $ac_aux_dir to an absolute path
+am_aux_dir=`cd $ac_aux_dir && pwd`
+
+if test x"${MISSING+set}" != xset; then
+ case $am_aux_dir in
+ *\ * | *\ *)
+ MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;;
+ *)
+ MISSING="\${SHELL} $am_aux_dir/missing" ;;
+ esac
+fi
+# Use eval to expand $SHELL
+if eval "$MISSING --run true"; then
+ am_missing_run="$MISSING --run "
+else
+ am_missing_run=
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`missing' script is too old or missing" >&5
+$as_echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;}
+fi
+
+if test x"${install_sh}" != xset; then
+ case $am_aux_dir in
+ *\ * | *\ *)
+ install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;;
+ *)
+ install_sh="\${SHELL} $am_aux_dir/install-sh"
+ esac
+fi
+
+# Installed binaries are usually stripped using `strip' when the user
+# run `make install-strip'. However `strip' might not be the right
+# tool to use in cross-compilation environments, therefore Automake
+# will honor the `STRIP' environment variable to overrule this program.
+if test "$cross_compiling" != no; then
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args.
+set dummy ${ac_tool_prefix}strip; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_STRIP+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$STRIP"; then
+ ac_cv_prog_STRIP="$STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_STRIP="${ac_tool_prefix}strip"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+STRIP=$ac_cv_prog_STRIP
+if test -n "$STRIP"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5
+$as_echo "$STRIP" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_STRIP"; then
+ ac_ct_STRIP=$STRIP
+ # Extract the first word of "strip", so it can be a program name with args.
+set dummy strip; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_STRIP"; then
+ ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_ac_ct_STRIP="strip"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP
+if test -n "$ac_ct_STRIP"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5
+$as_echo "$ac_ct_STRIP" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_STRIP" = x; then
+ STRIP=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ STRIP=$ac_ct_STRIP
+ fi
+else
+ STRIP="$ac_cv_prog_STRIP"
+fi
+
+fi
+INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5
+$as_echo_n "checking for a thread-safe mkdir -p... " >&6; }
+if test -z "$MKDIR_P"; then
+ if test "${ac_cv_path_mkdir+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in mkdir gmkdir; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; } || continue
+ case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #(
+ 'mkdir (GNU coreutils) '* | \
+ 'mkdir (coreutils) '* | \
+ 'mkdir (fileutils) '4.1*)
+ ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext
+ break 3;;
+ esac
+ done
+ done
+ done
+IFS=$as_save_IFS
+
+fi
+
+ if test "${ac_cv_path_mkdir+set}" = set; then
+ MKDIR_P="$ac_cv_path_mkdir -p"
+ else
+ # As a last resort, use the slow shell script. Don't cache a
+ # value for MKDIR_P within a source directory, because that will
+ # break other packages using the cache if that directory is
+ # removed, or if the value is a relative name.
+ test -d ./--version && rmdir ./--version
+ MKDIR_P="$ac_install_sh -d"
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5
+$as_echo "$MKDIR_P" >&6; }
+
+mkdir_p="$MKDIR_P"
+case $mkdir_p in
+ [\\/$]* | ?:[\\/]*) ;;
+ */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;;
+esac
+
+for ac_prog in gawk mawk nawk awk
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_AWK+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$AWK"; then
+ ac_cv_prog_AWK="$AWK" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_AWK="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+AWK=$ac_cv_prog_AWK
+if test -n "$AWK"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5
+$as_echo "$AWK" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$AWK" && break
+done
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5
+$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; }
+set x ${MAKE-make}
+ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'`
+if { as_var=ac_cv_prog_make_${ac_make}_set; eval "test \"\${$as_var+set}\" = set"; }; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat >conftest.make <<\_ACEOF
+SHELL = /bin/sh
+all:
+ @echo '@@@%%%=$(MAKE)=@@@%%%'
+_ACEOF
+# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
+case `${MAKE-make} -f conftest.make 2>/dev/null` in
+ *@@@%%%=?*=@@@%%%*)
+ eval ac_cv_prog_make_${ac_make}_set=yes;;
+ *)
+ eval ac_cv_prog_make_${ac_make}_set=no;;
+esac
+rm -f conftest.make
+fi
+if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ SET_MAKE=
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+rm -rf .tst 2>/dev/null
+mkdir .tst 2>/dev/null
+if test -d .tst; then
+ am__leading_dot=.
+else
+ am__leading_dot=_
+fi
+rmdir .tst 2>/dev/null
+
+DEPDIR="${am__leading_dot}deps"
+
+ac_config_commands="$ac_config_commands depfiles"
+
+
+am_make=${MAKE-make}
+cat > confinc << 'END'
+am__doit:
+ @echo this is the am__doit target
+.PHONY: am__doit
+END
+# If we don't find an include directive, just comment out the code.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5
+$as_echo_n "checking for style of include used by $am_make... " >&6; }
+am__include="#"
+am__quote=
+_am_result=none
+# First try GNU make style include.
+echo "include confinc" > confmf
+# Ignore all kinds of additional output from `make'.
+case `$am_make -s -f confmf 2> /dev/null` in #(
+*the\ am__doit\ target*)
+ am__include=include
+ am__quote=
+ _am_result=GNU
+ ;;
+esac
+# Now try BSD make style include.
+if test "$am__include" = "#"; then
+ echo '.include "confinc"' > confmf
+ case `$am_make -s -f confmf 2> /dev/null` in #(
+ *the\ am__doit\ target*)
+ am__include=.include
+ am__quote="\""
+ _am_result=BSD
+ ;;
+ esac
+fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5
+$as_echo "$_am_result" >&6; }
+rm -f confinc confmf
+
+# Check whether --enable-dependency-tracking was given.
+if test "${enable_dependency_tracking+set}" = set; then :
+ enableval=$enable_dependency_tracking;
+fi
+
+if test "x$enable_dependency_tracking" != xno; then
+ am_depcomp="$ac_aux_dir/depcomp"
+ AMDEPBACKSLASH='\'
+fi
+ if test "x$enable_dependency_tracking" != xno; then
+ AMDEP_TRUE=
+ AMDEP_FALSE='#'
+else
+ AMDEP_TRUE='#'
+ AMDEP_FALSE=
+fi
+
+
+if test "`cd $srcdir && pwd`" != "`pwd`"; then
+ # Use -I$(srcdir) only when $(srcdir) != ., so that make's output
+ # is not polluted with repeated "-I."
+ am__isrc=' -I$(srcdir)'
+ # test to see if srcdir already configured
+ if test -f $srcdir/config.status; then
+ as_fn_error "source directory already configured; run \"make distclean\" there first" "$LINENO" 5
+ fi
+fi
+
+# test whether we have cygpath
+if test -z "$CYGPATH_W"; then
+ if (cygpath --version) >/dev/null 2>/dev/null; then
+ CYGPATH_W='cygpath -w'
+ else
+ CYGPATH_W=echo
+ fi
+fi
+
+
+# Define the identity of the package.
+ PACKAGE='bfd'
+ VERSION='2.25'
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE "$PACKAGE"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define VERSION "$VERSION"
+_ACEOF
+
+# Some tools Automake needs.
+
+ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"}
+
+
+AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"}
+
+
+AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"}
+
+
+AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"}
+
+
+MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"}
+
+# We need awk for the "check" target. The system "awk" is bad on
+# some platforms.
+# Always define AMTAR for backward compatibility.
+
+AMTAR=${AMTAR-"${am_missing_run}tar"}
+
+am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'
+
+
+
+
+depcc="$CC" am_compiler_list=
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5
+$as_echo_n "checking dependency style of $depcc... " >&6; }
+if test "${am_cv_CC_dependencies_compiler_type+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
+ # We make a subdir and do the tests there. Otherwise we can end up
+ # making bogus files that we don't know about and never remove. For
+ # instance it was reported that on HP-UX the gcc test will end up
+ # making a dummy file named `D' -- because `-MD' means `put the output
+ # in D'.
+ mkdir conftest.dir
+ # Copy depcomp to subdir because otherwise we won't find it if we're
+ # using a relative directory.
+ cp "$am_depcomp" conftest.dir
+ cd conftest.dir
+ # We will build objects and dependencies in a subdirectory because
+ # it helps to detect inapplicable dependency modes. For instance
+ # both Tru64's cc and ICC support -MD to output dependencies as a
+ # side effect of compilation, but ICC will put the dependencies in
+ # the current directory while Tru64 will put them in the object
+ # directory.
+ mkdir sub
+
+ am_cv_CC_dependencies_compiler_type=none
+ if test "$am_compiler_list" = ""; then
+ am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp`
+ fi
+ am__universal=false
+ case " $depcc " in #(
+ *\ -arch\ *\ -arch\ *) am__universal=true ;;
+ esac
+
+ for depmode in $am_compiler_list; do
+ # Setup a source with many dependencies, because some compilers
+ # like to wrap large dependency lists on column 80 (with \), and
+ # we should not choose a depcomp mode which is confused by this.
+ #
+ # We need to recreate these files for each test, as the compiler may
+ # overwrite some of them when testing with obscure command lines.
+ # This happens at least with the AIX C compiler.
+ : > sub/conftest.c
+ for i in 1 2 3 4 5 6; do
+ echo '#include "conftst'$i'.h"' >> sub/conftest.c
+ # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with
+ # Solaris 8's {/usr,}/bin/sh.
+ touch sub/conftst$i.h
+ done
+ echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
+
+ # We check with `-c' and `-o' for the sake of the "dashmstdout"
+ # mode. It turns out that the SunPro C++ compiler does not properly
+ # handle `-M -o', and we need to detect this. Also, some Intel
+ # versions had trouble with output in subdirs
+ am__obj=sub/conftest.${OBJEXT-o}
+ am__minus_obj="-o $am__obj"
+ case $depmode in
+ gcc)
+ # This depmode causes a compiler race in universal mode.
+ test "$am__universal" = false || continue
+ ;;
+ nosideeffect)
+ # after this tag, mechanisms are not by side-effect, so they'll
+ # only be used when explicitly requested
+ if test "x$enable_dependency_tracking" = xyes; then
+ continue
+ else
+ break
+ fi
+ ;;
+ msvisualcpp | msvcmsys)
+ # This compiler won't grok `-c -o', but also, the minuso test has
+ # not run yet. These depmodes are late enough in the game, and
+ # so weak that their functioning should not be impacted.
+ am__obj=conftest.${OBJEXT-o}
+ am__minus_obj=
+ ;;
+ none) break ;;
+ esac
+ if depmode=$depmode \
+ source=sub/conftest.c object=$am__obj \
+ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
+ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \
+ >/dev/null 2>conftest.err &&
+ grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep $am__obj sub/conftest.Po > /dev/null 2>&1 &&
+ ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
+ # icc doesn't choke on unknown options, it will just issue warnings
+ # or remarks (even with -Werror). So we grep stderr for any message
+ # that says an option was ignored or not supported.
+ # When given -MP, icc 7.0 and 7.1 complain thusly:
+ # icc: Command line warning: ignoring option '-M'; no argument required
+ # The diagnosis changed in icc 8.0:
+ # icc: Command line remark: option '-MP' not supported
+ if (grep 'ignoring option' conftest.err ||
+ grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
+ am_cv_CC_dependencies_compiler_type=$depmode
+ break
+ fi
+ fi
+ done
+
+ cd ..
+ rm -rf conftest.dir
+else
+ am_cv_CC_dependencies_compiler_type=none
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5
+$as_echo "$am_cv_CC_dependencies_compiler_type" >&6; }
+CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type
+
+ if
+ test "x$enable_dependency_tracking" != xno \
+ && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then
+ am__fastdepCC_TRUE=
+ am__fastdepCC_FALSE='#'
+else
+ am__fastdepCC_TRUE='#'
+ am__fastdepCC_FALSE=
+fi
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+ # 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
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_AR+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$AR"; then
+ ac_cv_prog_AR="$AR" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_AR="${ac_tool_prefix}ar"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+AR=$ac_cv_prog_AR
+if test -n "$AR"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5
+$as_echo "$AR" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_AR"; then
+ ac_ct_AR=$AR
+ # Extract the first word of "ar", so it can be a program name with args.
+set dummy ar; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_AR+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_AR"; then
+ ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_ac_ct_AR="ar"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_AR=$ac_cv_prog_ac_ct_AR
+if test -n "$ac_ct_AR"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5
+$as_echo "$ac_ct_AR" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_AR" = x; then
+ AR=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ AR=$ac_ct_AR
+ fi
+else
+ AR="$ac_cv_prog_AR"
+fi
+
+if test -n "$ac_tool_prefix"; then
+ # 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
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_RANLIB+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$RANLIB"; then
+ ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+RANLIB=$ac_cv_prog_RANLIB
+if test -n "$RANLIB"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5
+$as_echo "$RANLIB" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_RANLIB"; then
+ ac_ct_RANLIB=$RANLIB
+ # Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_RANLIB"; then
+ ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_ac_ct_RANLIB="ranlib"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB
+if test -n "$ac_ct_RANLIB"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5
+$as_echo "$ac_ct_RANLIB" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_RANLIB" = x; then
+ RANLIB=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ RANLIB=$ac_ct_RANLIB
+ fi
+else
+ RANLIB="$ac_cv_prog_RANLIB"
+fi
+
+
+# Check whether --enable-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.
+ lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+ for pkg in $enableval; do
+ IFS="$lt_save_ifs"
+ if test "X$pkg" = "X$p"; then
+ enable_shared=yes
+ fi
+ done
+ IFS="$lt_save_ifs"
+ ;;
+ esac
+else
+ enable_shared=no
+fi
+
+
+
+
+
+
+
+
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}gcc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_CC="${ac_tool_prefix}gcc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+ ac_ct_CC=$CC
+ # Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_ac_ct_CC="gcc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_CC" = x; then
+ CC=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ CC=$ac_ct_CC
+ fi
+else
+ CC="$ac_cv_prog_CC"
+fi
+
+if test -z "$CC"; then
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_CC="${ac_tool_prefix}cc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ fi
+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
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ ac_prog_rejected=no
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+ ac_prog_rejected=yes
+ continue
+ fi
+ ac_cv_prog_CC="cc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_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 $# != 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
+ ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
+ fi
+fi
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$CC"; then
+ if test -n "$ac_tool_prefix"; then
+ for ac_prog in cl.exe
+ do
+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$CC" && break
+ done
+fi
+if test -z "$CC"; then
+ ac_ct_CC=$CC
+ for ac_prog in cl.exe
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_ac_ct_CC="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$ac_ct_CC" && break
+done
+
+ if test "x$ac_ct_CC" = x; then
+ CC=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ CC=$ac_ct_CC
+ fi
+fi
+
+fi
+
+
+test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error "no acceptable C compiler found in \$PATH
+See \`config.log' for more details." "$LINENO" 5; }
+
+# Provide some information about the compiler.
+$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5
+set X $ac_compile
+ac_compiler=$2
+for ac_option in --version -v -V -qversion; do
+ { { ac_try="$ac_compiler $ac_option >&5"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_compiler $ac_option >&5") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ sed '10a\
+... rest of stderr output deleted ...
+ 10q' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ rm -f conftest.er1 conftest.err
+ fi
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+done
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5
+$as_echo_n "checking whether we are using the GNU C compiler... " >&6; }
+if test "${ac_cv_c_compiler_gnu+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+#ifndef __GNUC__
+ choke me
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_compiler_gnu=yes
+else
+ ac_compiler_gnu=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_c_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5
+$as_echo "$ac_cv_c_compiler_gnu" >&6; }
+if test $ac_compiler_gnu = yes; then
+ GCC=yes
+else
+ GCC=
+fi
+ac_test_CFLAGS=${CFLAGS+set}
+ac_save_CFLAGS=$CFLAGS
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5
+$as_echo_n "checking whether $CC accepts -g... " >&6; }
+if test "${ac_cv_prog_cc_g+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_save_c_werror_flag=$ac_c_werror_flag
+ ac_c_werror_flag=yes
+ ac_cv_prog_cc_g=no
+ CFLAGS="-g"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_prog_cc_g=yes
+else
+ CFLAGS=""
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+else
+ ac_c_werror_flag=$ac_save_c_werror_flag
+ CFLAGS="-g"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_prog_cc_g=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_c_werror_flag=$ac_save_c_werror_flag
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5
+$as_echo "$ac_cv_prog_cc_g" >&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
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5
+$as_echo_n "checking for $CC option to accept ISO C89... " >&6; }
+if test "${ac_cv_prog_cc_c89+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_cv_prog_cc_c89=no
+ac_save_CC=$CC
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdarg.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+ char **p;
+ int i;
+{
+ return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+ char *s;
+ va_list v;
+ va_start (v,p);
+ s = g (p, va_arg (v,int));
+ va_end (v);
+ return s;
+}
+
+/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has
+ function prototypes and stuff, but not '\xHH' hex character constants.
+ These don't provoke an error unfortunately, instead are silently treated
+ as 'x'. The following induces an error, until -std is added to get
+ proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an
+ array size at least. It's necessary to write '\x00'==0 to get something
+ that's true only with -std. */
+int osf4_cc_array ['\x00' == 0 ? 1 : -1];
+
+/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
+ inside strings and character constants. */
+#define FOO(x) 'x'
+int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];
+
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+int
+main ()
+{
+return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1];
+ ;
+ return 0;
+}
+_ACEOF
+for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \
+ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+ CC="$ac_save_CC $ac_arg"
+ if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_prog_cc_c89=$ac_arg
+fi
+rm -f core conftest.err conftest.$ac_objext
+ test "x$ac_cv_prog_cc_c89" != "xno" && break
+done
+rm -f conftest.$ac_ext
+CC=$ac_save_CC
+
+fi
+# AC_CACHE_VAL
+case "x$ac_cv_prog_cc_c89" in
+ x)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
+$as_echo "none needed" >&6; } ;;
+ xno)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
+$as_echo "unsupported" >&6; } ;;
+ *)
+ CC="$CC $ac_cv_prog_cc_c89"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5
+$as_echo "$ac_cv_prog_cc_c89" >&6; } ;;
+esac
+if test "x$ac_cv_prog_cc_c89" != xno; then :
+
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5
+$as_echo_n "checking how to run the C preprocessor... " >&6; }
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+ CPP=
+fi
+if test -z "$CPP"; then
+ if test "${ac_cv_prog_CPP+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ # Double quotes because CPP needs to be expanded
+ for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
+ do
+ ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+
+else
+ # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether nonexistent headers
+ # can be detected and how.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+ # Broken: success on invalid input.
+continue
+else
+ # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+ break
+fi
+
+ done
+ ac_cv_prog_CPP=$CPP
+
+fi
+ CPP=$ac_cv_prog_CPP
+else
+ ac_cv_prog_CPP=$CPP
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5
+$as_echo "$CPP" >&6; }
+ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+
+else
+ # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether nonexistent headers
+ # can be detected and how.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+ # Broken: success on invalid input.
+continue
+else
+ # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+
+else
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error "C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details." "$LINENO" 5; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5
+$as_echo_n "checking for grep that handles long lines and -e... " >&6; }
+if test "${ac_cv_path_GREP+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -z "$GREP"; then
+ ac_path_GREP_found=false
+ # Loop through the user's path and test for each of PROGNAME-LIST
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in grep ggrep; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
+ { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue
+# Check for GNU ac_path_GREP and select it if it is found.
+ # Check for GNU $ac_path_GREP
+case `"$ac_path_GREP" --version 2>&1` in
+*GNU*)
+ ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;;
+*)
+ ac_count=0
+ $as_echo_n 0123456789 >"conftest.in"
+ while :
+ do
+ cat "conftest.in" "conftest.in" >"conftest.tmp"
+ mv "conftest.tmp" "conftest.in"
+ cp "conftest.in" "conftest.nl"
+ $as_echo 'GREP' >> "conftest.nl"
+ "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+ as_fn_arith $ac_count + 1 && ac_count=$as_val
+ if test $ac_count -gt ${ac_path_GREP_max-0}; then
+ # Best one so far, save it but keep looking for a better one
+ ac_cv_path_GREP="$ac_path_GREP"
+ ac_path_GREP_max=$ac_count
+ fi
+ # 10*(2^10) chars as input seems more than enough
+ test $ac_count -gt 10 && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+ $ac_path_GREP_found && break 3
+ done
+ done
+ done
+IFS=$as_save_IFS
+ if test -z "$ac_cv_path_GREP"; then
+ as_fn_error "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+ fi
+else
+ ac_cv_path_GREP=$GREP
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5
+$as_echo "$ac_cv_path_GREP" >&6; }
+ GREP="$ac_cv_path_GREP"
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5
+$as_echo_n "checking for egrep... " >&6; }
+if test "${ac_cv_path_EGREP+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if echo a | $GREP -E '(a|b)' >/dev/null 2>&1
+ then ac_cv_path_EGREP="$GREP -E"
+ else
+ if test -z "$EGREP"; then
+ ac_path_EGREP_found=false
+ # Loop through the user's path and test for each of PROGNAME-LIST
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in egrep; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"
+ { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue
+# Check for GNU ac_path_EGREP and select it if it is found.
+ # Check for GNU $ac_path_EGREP
+case `"$ac_path_EGREP" --version 2>&1` in
+*GNU*)
+ ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;;
+*)
+ ac_count=0
+ $as_echo_n 0123456789 >"conftest.in"
+ while :
+ do
+ cat "conftest.in" "conftest.in" >"conftest.tmp"
+ mv "conftest.tmp" "conftest.in"
+ cp "conftest.in" "conftest.nl"
+ $as_echo 'EGREP' >> "conftest.nl"
+ "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+ as_fn_arith $ac_count + 1 && ac_count=$as_val
+ if test $ac_count -gt ${ac_path_EGREP_max-0}; then
+ # Best one so far, save it but keep looking for a better one
+ ac_cv_path_EGREP="$ac_path_EGREP"
+ ac_path_EGREP_max=$ac_count
+ fi
+ # 10*(2^10) chars as input seems more than enough
+ test $ac_count -gt 10 && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+ $ac_path_EGREP_found && break 3
+ done
+ done
+ done
+IFS=$as_save_IFS
+ if test -z "$ac_cv_path_EGREP"; then
+ as_fn_error "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+ fi
+else
+ ac_cv_path_EGREP=$EGREP
+fi
+
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5
+$as_echo "$ac_cv_path_EGREP" >&6; }
+ EGREP="$ac_cv_path_EGREP"
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5
+$as_echo_n "checking for ANSI C header files... " >&6; }
+if test "${ac_cv_header_stdc+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_header_stdc=yes
+else
+ ac_cv_header_stdc=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+ # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "memchr" >/dev/null 2>&1; then :
+
+else
+ 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 confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "free" >/dev/null 2>&1; then :
+
+else
+ 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 confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <ctype.h>
+#include <stdlib.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+ (('a' <= (c) && (c) <= 'i') \
+ || ('j' <= (c) && (c) <= 'r') \
+ || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#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))
+ return 2;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+
+else
+ ac_cv_header_stdc=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5
+$as_echo "$ac_cv_header_stdc" >&6; }
+if test $ac_cv_header_stdc = yes; then
+
+$as_echo "#define STDC_HEADERS 1" >>confdefs.h
+
+fi
+
+# On IRIX 5.3, sys/types and inttypes.h are conflicting.
+for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
+ inttypes.h stdint.h unistd.h
+do :
+ as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default
+"
+eval as_val=\$$as_ac_Header
+ if test "x$as_val" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+
+ ac_fn_c_check_header_mongrel "$LINENO" "minix/config.h" "ac_cv_header_minix_config_h" "$ac_includes_default"
+if test "x$ac_cv_header_minix_config_h" = x""yes; then :
+ MINIX=yes
+else
+ MINIX=
+fi
+
+
+ if test "$MINIX" = yes; then
+
+$as_echo "#define _POSIX_SOURCE 1" >>confdefs.h
+
+
+$as_echo "#define _POSIX_1_SOURCE 2" >>confdefs.h
+
+
+$as_echo "#define _MINIX 1" >>confdefs.h
+
+ fi
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether it is safe to define __EXTENSIONS__" >&5
+$as_echo_n "checking whether it is safe to define __EXTENSIONS__... " >&6; }
+if test "${ac_cv_safe_to_define___extensions__+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+# define __EXTENSIONS__ 1
+ $ac_includes_default
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_safe_to_define___extensions__=yes
+else
+ ac_cv_safe_to_define___extensions__=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_safe_to_define___extensions__" >&5
+$as_echo "$ac_cv_safe_to_define___extensions__" >&6; }
+ test $ac_cv_safe_to_define___extensions__ = yes &&
+ $as_echo "#define __EXTENSIONS__ 1" >>confdefs.h
+
+ $as_echo "#define _ALL_SOURCE 1" >>confdefs.h
+
+ $as_echo "#define _GNU_SOURCE 1" >>confdefs.h
+
+ $as_echo "#define _POSIX_PTHREAD_SEMANTICS 1" >>confdefs.h
+
+ $as_echo "#define _TANDEM_SOURCE 1" >>confdefs.h
+
+
+
+
+
+case `pwd` in
+ *\ * | *\ *)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5
+$as_echo "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;;
+esac
+
+
+
+macro_version='2.2.7a'
+macro_revision='1.3134'
+
+
+
+
+
+
+
+
+
+
+
+
+
+ltmain="$ac_aux_dir/ltmain.sh"
+
+# Backslashify metacharacters that are still active within
+# double-quoted strings.
+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'
+
+# Sed substitution to delay expansion of an escaped single quote.
+delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g'
+
+# Sed substitution to avoid accidental globbing in evaled expressions
+no_glob_subst='s/\*/\\\*/g'
+
+ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO
+ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5
+$as_echo_n "checking how to print strings... " >&6; }
+# Test print first, because it will be a builtin if present.
+if test "X`print -r -- -n 2>/dev/null`" = X-n && \
+ test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then
+ ECHO='print -r --'
+elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then
+ ECHO='printf %s\n'
+else
+ # Use this function as a fallback that always works.
+ func_fallback_echo ()
+ {
+ eval 'cat <<_LTECHO_EOF
+$1
+_LTECHO_EOF'
+ }
+ ECHO='func_fallback_echo'
+fi
+
+# func_echo_all arg...
+# Invoke $ECHO with all args, space-separated.
+func_echo_all ()
+{
+ $ECHO ""
+}
+
+case "$ECHO" in
+ printf*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: printf" >&5
+$as_echo "printf" >&6; } ;;
+ print*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: print -r" >&5
+$as_echo "print -r" >&6; } ;;
+ *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: cat" >&5
+$as_echo "cat" >&6; } ;;
+esac
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5
+$as_echo_n "checking for a sed that does not truncate output... " >&6; }
+if test "${ac_cv_path_SED+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/
+ for ac_i in 1 2 3 4 5 6 7; do
+ ac_script="$ac_script$as_nl$ac_script"
+ done
+ echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed
+ { ac_script=; unset ac_script;}
+ if test -z "$SED"; then
+ ac_path_SED_found=false
+ # Loop through the user's path and test for each of PROGNAME-LIST
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in sed gsed; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ ac_path_SED="$as_dir/$ac_prog$ac_exec_ext"
+ { test -f "$ac_path_SED" && $as_test_x "$ac_path_SED"; } || continue
+# Check for GNU ac_path_SED and select it if it is found.
+ # Check for GNU $ac_path_SED
+case `"$ac_path_SED" --version 2>&1` in
+*GNU*)
+ ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;;
+*)
+ ac_count=0
+ $as_echo_n 0123456789 >"conftest.in"
+ while :
+ do
+ cat "conftest.in" "conftest.in" >"conftest.tmp"
+ mv "conftest.tmp" "conftest.in"
+ cp "conftest.in" "conftest.nl"
+ $as_echo '' >> "conftest.nl"
+ "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break
+ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+ as_fn_arith $ac_count + 1 && ac_count=$as_val
+ if test $ac_count -gt ${ac_path_SED_max-0}; then
+ # Best one so far, save it but keep looking for a better one
+ ac_cv_path_SED="$ac_path_SED"
+ ac_path_SED_max=$ac_count
+ fi
+ # 10*(2^10) chars as input seems more than enough
+ test $ac_count -gt 10 && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+ $ac_path_SED_found && break 3
+ done
+ done
+ done
+IFS=$as_save_IFS
+ if test -z "$ac_cv_path_SED"; then
+ as_fn_error "no acceptable sed could be found in \$PATH" "$LINENO" 5
+ fi
+else
+ ac_cv_path_SED=$SED
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5
+$as_echo "$ac_cv_path_SED" >&6; }
+ SED="$ac_cv_path_SED"
+ rm -f conftest.sed
+
+test -z "$SED" && SED=sed
+Xsed="$SED -e 1s/^X//"
+
+
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5
+$as_echo_n "checking for fgrep... " >&6; }
+if test "${ac_cv_path_FGREP+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1
+ then ac_cv_path_FGREP="$GREP -F"
+ else
+ if test -z "$FGREP"; then
+ ac_path_FGREP_found=false
+ # Loop through the user's path and test for each of PROGNAME-LIST
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in fgrep; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ ac_path_FGREP="$as_dir/$ac_prog$ac_exec_ext"
+ { test -f "$ac_path_FGREP" && $as_test_x "$ac_path_FGREP"; } || continue
+# Check for GNU ac_path_FGREP and select it if it is found.
+ # Check for GNU $ac_path_FGREP
+case `"$ac_path_FGREP" --version 2>&1` in
+*GNU*)
+ ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_found=:;;
+*)
+ ac_count=0
+ $as_echo_n 0123456789 >"conftest.in"
+ while :
+ do
+ cat "conftest.in" "conftest.in" >"conftest.tmp"
+ mv "conftest.tmp" "conftest.in"
+ cp "conftest.in" "conftest.nl"
+ $as_echo 'FGREP' >> "conftest.nl"
+ "$ac_path_FGREP" FGREP < "conftest.nl" >"conftest.out" 2>/dev/null || break
+ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+ as_fn_arith $ac_count + 1 && ac_count=$as_val
+ if test $ac_count -gt ${ac_path_FGREP_max-0}; then
+ # Best one so far, save it but keep looking for a better one
+ ac_cv_path_FGREP="$ac_path_FGREP"
+ ac_path_FGREP_max=$ac_count
+ fi
+ # 10*(2^10) chars as input seems more than enough
+ test $ac_count -gt 10 && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+ $ac_path_FGREP_found && break 3
+ done
+ done
+ done
+IFS=$as_save_IFS
+ if test -z "$ac_cv_path_FGREP"; then
+ as_fn_error "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+ fi
+else
+ ac_cv_path_FGREP=$FGREP
+fi
+
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5
+$as_echo "$ac_cv_path_FGREP" >&6; }
+ FGREP="$ac_cv_path_FGREP"
+
+
+test -z "$GREP" && GREP=grep
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# Check whether --with-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 "$GCC" = yes; then
+ # Check if gcc -print-prog-name=ld gives a path.
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5
+$as_echo_n "checking for ld used by $CC... " >&6; }
+ case $host in
+ *-*-mingw*)
+ # gcc leaves a trailing carriage return which upsets mingw
+ ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
+ *)
+ ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
+ esac
+ case $ac_prog in
+ # Accept absolute paths.
+ [\\/]* | ?:[\\/]*)
+ re_direlt='/[^/][^/]*/\.\./'
+ # Canonicalize the pathname 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
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5
+$as_echo_n "checking for GNU ld... " >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5
+$as_echo_n "checking for non-GNU ld... " >&6; }
+fi
+if test "${lt_cv_path_LD+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -z "$LD"; then
+ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+ for ac_dir in $PATH; do
+ IFS="$lt_save_ifs"
+ test -z "$ac_dir" && ac_dir=.
+ if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+ lt_cv_path_LD="$ac_dir/$ac_prog"
+ # Check to see if the program is GNU ld. I'd rather use --version,
+ # but apparently some variants of GNU ld only accept -v.
+ # Break only if it was the GNU/non-GNU ld that we prefer.
+ case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in
+ *GNU* | *'with BFD'*)
+ test "$with_gnu_ld" != no && break
+ ;;
+ *)
+ test "$with_gnu_ld" != yes && break
+ ;;
+ esac
+ fi
+ done
+ IFS="$lt_save_ifs"
+else
+ lt_cv_path_LD="$LD" # Let the user override the test with a path.
+fi
+fi
+
+LD="$lt_cv_path_LD"
+if test -n "$LD"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LD" >&5
+$as_echo "$LD" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+test -z "$LD" && as_fn_error "no acceptable ld found in \$PATH" "$LINENO" 5
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5
+$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; }
+if test "${lt_cv_prog_gnu_ld+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ # I'd rather use --version here, but apparently some GNU lds only accept -v.
+case `$LD -v 2>&1 </dev/null` in
+*GNU* | *'with BFD'*)
+ lt_cv_prog_gnu_ld=yes
+ ;;
+*)
+ lt_cv_prog_gnu_ld=no
+ ;;
+esac
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_gnu_ld" >&5
+$as_echo "$lt_cv_prog_gnu_ld" >&6; }
+with_gnu_ld=$lt_cv_prog_gnu_ld
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)" >&5
+$as_echo_n "checking for BSD- or MS-compatible name lister (nm)... " >&6; }
+if test "${lt_cv_path_NM+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$NM"; then
+ # Let the user override the test.
+ lt_cv_path_NM="$NM"
+else
+ lt_nm_to_check="${ac_tool_prefix}nm"
+ if test -n "$ac_tool_prefix" && test "$build" = "$host"; then
+ lt_nm_to_check="$lt_nm_to_check nm"
+ fi
+ for lt_tmp_nm in $lt_nm_to_check; do
+ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+ for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do
+ IFS="$lt_save_ifs"
+ test -z "$ac_dir" && ac_dir=.
+ tmp_nm="$ac_dir/$lt_tmp_nm"
+ if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; 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
+ # Tru64's nm complains that /dev/null is an invalid object file
+ case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in
+ */dev/null* | *'Invalid file or object type'*)
+ lt_cv_path_NM="$tmp_nm -B"
+ break
+ ;;
+ *)
+ case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in
+ */dev/null*)
+ lt_cv_path_NM="$tmp_nm -p"
+ break
+ ;;
+ *)
+ lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but
+ continue # so that we can try to find one that supports BSD flags
+ ;;
+ esac
+ ;;
+ esac
+ fi
+ done
+ IFS="$lt_save_ifs"
+ done
+ : ${lt_cv_path_NM=no}
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5
+$as_echo "$lt_cv_path_NM" >&6; }
+if test "$lt_cv_path_NM" != "no"; then
+ NM="$lt_cv_path_NM"
+else
+ # Didn't find any BSD compatible name lister, look for dumpbin.
+ if test -n "$DUMPBIN"; then :
+ # Let the user override the test.
+ else
+ if test -n "$ac_tool_prefix"; then
+ for ac_prog in dumpbin "link -dump"
+ do
+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_DUMPBIN+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$DUMPBIN"; then
+ ac_cv_prog_DUMPBIN="$DUMPBIN" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+DUMPBIN=$ac_cv_prog_DUMPBIN
+if test -n "$DUMPBIN"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DUMPBIN" >&5
+$as_echo "$DUMPBIN" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$DUMPBIN" && break
+ done
+fi
+if test -z "$DUMPBIN"; then
+ ac_ct_DUMPBIN=$DUMPBIN
+ for ac_prog in dumpbin "link -dump"
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_DUMPBIN+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_DUMPBIN"; then
+ ac_cv_prog_ac_ct_DUMPBIN="$ac_ct_DUMPBIN" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_ac_ct_DUMPBIN="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_DUMPBIN=$ac_cv_prog_ac_ct_DUMPBIN
+if test -n "$ac_ct_DUMPBIN"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DUMPBIN" >&5
+$as_echo "$ac_ct_DUMPBIN" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$ac_ct_DUMPBIN" && break
+done
+
+ if test "x$ac_ct_DUMPBIN" = x; then
+ DUMPBIN=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ DUMPBIN=$ac_ct_DUMPBIN
+ fi
+fi
+
+ case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in
+ *COFF*)
+ DUMPBIN="$DUMPBIN -symbols"
+ ;;
+ *)
+ DUMPBIN=:
+ ;;
+ esac
+ fi
+
+ if test "$DUMPBIN" != ":"; then
+ NM="$DUMPBIN"
+ fi
+fi
+test -z "$NM" && NM=nm
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5
+$as_echo_n "checking the name lister ($NM) interface... " >&6; }
+if test "${lt_cv_nm_interface+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_nm_interface="BSD nm"
+ echo "int some_variable = 0;" > conftest.$ac_ext
+ (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&5)
+ (eval "$ac_compile" 2>conftest.err)
+ cat conftest.err >&5
+ (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
+ (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
+ cat conftest.err >&5
+ (eval echo "\"\$as_me:$LINENO: output\"" >&5)
+ cat conftest.out >&5
+ if $GREP 'External.*some_variable' conftest.out > /dev/null; then
+ lt_cv_nm_interface="MS dumpbin"
+ fi
+ rm -f conftest*
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5
+$as_echo "$lt_cv_nm_interface" >&6; }
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5
+$as_echo_n "checking whether ln -s works... " >&6; }
+LN_S=$as_ln_s
+if test "$LN_S" = "ln -s"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5
+$as_echo "no, using $LN_S" >&6; }
+fi
+
+# find the maximum length of command line arguments
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the maximum length of command line arguments" >&5
+$as_echo_n "checking the maximum length of command line arguments... " >&6; }
+if test "${lt_cv_sys_max_cmd_len+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ i=0
+ teststring="ABCD"
+
+ case $build_os in
+ msdosdjgpp*)
+ # On DJGPP, this test can blow up pretty badly due to problems in libc
+ # (any single argument exceeding 2000 bytes causes a buffer overrun
+ # during glob expansion). Even if it were fixed, the result of this
+ # check would be larger than it should be.
+ lt_cv_sys_max_cmd_len=12288; # 12K is about right
+ ;;
+
+ gnu*)
+ # Under GNU Hurd, this test is not required because there is
+ # no limit to the length of command line arguments.
+ # Libtool will interpret -1 as no limit whatsoever
+ lt_cv_sys_max_cmd_len=-1;
+ ;;
+
+ cygwin* | mingw* | cegcc*)
+ # On Win9x/ME, this test blows up -- it succeeds, but takes
+ # about 5 minutes as the teststring grows exponentially.
+ # Worse, since 9x/ME are not pre-emptively multitasking,
+ # you end up with a "frozen" computer, even though with patience
+ # the test eventually succeeds (with a max line length of 256k).
+ # Instead, let's just punt: use the minimum linelength reported by
+ # all of the supported platforms: 8192 (on NT/2K/XP).
+ lt_cv_sys_max_cmd_len=8192;
+ ;;
+
+ mint*)
+ # On MiNT this can take a long time and run out of memory.
+ lt_cv_sys_max_cmd_len=8192;
+ ;;
+
+ amigaos*)
+ # On AmigaOS with pdksh, this test takes hours, literally.
+ # So we just punt and use a minimum line length of 8192.
+ lt_cv_sys_max_cmd_len=8192;
+ ;;
+
+ netbsd* | freebsd* | openbsd* | darwin* | dragonfly*)
+ # This has been around since 386BSD, at least. Likely further.
+ if test -x /sbin/sysctl; then
+ lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax`
+ elif test -x /usr/sbin/sysctl; then
+ lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax`
+ else
+ lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs
+ fi
+ # And add a safety zone
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
+ ;;
+
+ interix*)
+ # We know the value 262144 and hardcode it with a safety zone (like BSD)
+ lt_cv_sys_max_cmd_len=196608
+ ;;
+
+ osf*)
+ # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure
+ # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not
+ # nice to cause kernel panics so lets avoid the loop below.
+ # First set a reasonable default.
+ lt_cv_sys_max_cmd_len=16384
+ #
+ if test -x /sbin/sysconfig; then
+ case `/sbin/sysconfig -q proc exec_disable_arg_limit` in
+ *1*) lt_cv_sys_max_cmd_len=-1 ;;
+ esac
+ fi
+ ;;
+ sco3.2v5*)
+ lt_cv_sys_max_cmd_len=102400
+ ;;
+ sysv5* | sco5v6* | sysv4.2uw2*)
+ kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null`
+ if test -n "$kargmax"; then
+ lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[ ]//'`
+ else
+ lt_cv_sys_max_cmd_len=32768
+ fi
+ ;;
+ *)
+ lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null`
+ if test -n "$lt_cv_sys_max_cmd_len"; then
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
+ else
+ # Make teststring a little bigger before we do anything with it.
+ # a 1K string should be a reasonable start.
+ for i in 1 2 3 4 5 6 7 8 ; do
+ teststring=$teststring$teststring
+ done
+ SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}}
+ # If test is not a shell built-in, we'll probably end up computing a
+ # maximum length that is only half of the actual maximum length, but
+ # we can't tell.
+ while { test "X"`func_fallback_echo "$teststring$teststring" 2>/dev/null` \
+ = "X$teststring$teststring"; } >/dev/null 2>&1 &&
+ test $i != 17 # 1/2 MB should be enough
+ do
+ i=`expr $i + 1`
+ teststring=$teststring$teststring
+ done
+ # Only check the string length outside the loop.
+ lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1`
+ teststring=
+ # Add a significant safety factor because C++ compilers can tack on
+ # massive amounts of additional arguments before passing them to the
+ # linker. It appears as though 1/2 is a usable value.
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2`
+ fi
+ ;;
+ esac
+
+fi
+
+if test -n $lt_cv_sys_max_cmd_len ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len" >&5
+$as_echo "$lt_cv_sys_max_cmd_len" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5
+$as_echo "none" >&6; }
+fi
+max_cmd_len=$lt_cv_sys_max_cmd_len
+
+
+
+
+
+
+: ${CP="cp -f"}
+: ${MV="mv -f"}
+: ${RM="rm -f"}
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands some XSI constructs" >&5
+$as_echo_n "checking whether the shell understands some XSI constructs... " >&6; }
+# Try some XSI features
+xsi_shell=no
+( _lt_dummy="a/b/c"
+ test "${_lt_dummy##*/},${_lt_dummy%/*},"${_lt_dummy%"$_lt_dummy"}, \
+ = c,a/b,, \
+ && eval 'test $(( 1 + 1 )) -eq 2 \
+ && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \
+ && xsi_shell=yes
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $xsi_shell" >&5
+$as_echo "$xsi_shell" >&6; }
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands \"+=\"" >&5
+$as_echo_n "checking whether the shell understands \"+=\"... " >&6; }
+lt_shell_append=no
+( foo=bar; set foo baz; eval "$1+=\$2" && test "$foo" = barbaz ) \
+ >/dev/null 2>&1 \
+ && lt_shell_append=yes
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_shell_append" >&5
+$as_echo "$lt_shell_append" >&6; }
+
+
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+ lt_unset=unset
+else
+ lt_unset=false
+fi
+
+
+
+
+
+# test EBCDIC or ASCII
+case `echo X|tr X '\101'` in
+ A) # ASCII based system
+ # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr
+ lt_SP2NL='tr \040 \012'
+ lt_NL2SP='tr \015\012 \040\040'
+ ;;
+ *) # EBCDIC based system
+ lt_SP2NL='tr \100 \n'
+ lt_NL2SP='tr \r\n \100\100'
+ ;;
+esac
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5
+$as_echo_n "checking for $LD option to reload object files... " >&6; }
+if test "${lt_cv_ld_reload_flag+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_ld_reload_flag='-r'
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_reload_flag" >&5
+$as_echo "$lt_cv_ld_reload_flag" >&6; }
+reload_flag=$lt_cv_ld_reload_flag
+case $reload_flag in
+"" | " "*) ;;
+*) reload_flag=" $reload_flag" ;;
+esac
+reload_cmds='$LD$reload_flag -o $output$reload_objs'
+case $host_os in
+ darwin*)
+ if test "$GCC" = yes; then
+ reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs'
+ else
+ reload_cmds='$LD$reload_flag -o $output$reload_objs'
+ fi
+ ;;
+esac
+
+
+
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args.
+set dummy ${ac_tool_prefix}objdump; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_OBJDUMP+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$OBJDUMP"; then
+ ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+OBJDUMP=$ac_cv_prog_OBJDUMP
+if test -n "$OBJDUMP"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5
+$as_echo "$OBJDUMP" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_OBJDUMP"; then
+ ac_ct_OBJDUMP=$OBJDUMP
+ # Extract the first word of "objdump", so it can be a program name with args.
+set dummy objdump; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_OBJDUMP+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_OBJDUMP"; then
+ ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_ac_ct_OBJDUMP="objdump"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP
+if test -n "$ac_ct_OBJDUMP"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5
+$as_echo "$ac_ct_OBJDUMP" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_OBJDUMP" = x; then
+ OBJDUMP="false"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ OBJDUMP=$ac_ct_OBJDUMP
+ fi
+else
+ OBJDUMP="$ac_cv_prog_OBJDUMP"
+fi
+
+test -z "$OBJDUMP" && OBJDUMP=objdump
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries" >&5
+$as_echo_n "checking how to recognize dependent libraries... " >&6; }
+if test "${lt_cv_deplibs_check_method+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_file_magic_cmd='$MAGIC_CMD'
+lt_cv_file_magic_test_file=
+lt_cv_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 extended 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.
+
+case $host_os in
+aix[4-9]*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+beos*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+bsdi[45]*)
+ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)'
+ lt_cv_file_magic_cmd='/usr/bin/file -L'
+ lt_cv_file_magic_test_file=/shlib/libc.so
+ ;;
+
+cygwin*)
+ # func_win32_libid is a shell function defined in ltmain.sh
+ lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+ lt_cv_file_magic_cmd='func_win32_libid'
+ ;;
+
+mingw* | pw32*)
+ # Base MSYS/MinGW do not provide the 'file' command needed by
+ # func_win32_libid shell function, so use a weaker test based on 'objdump',
+ # unless we find 'file', for example because we are cross-compiling.
+ # func_win32_libid assumes BSD nm, so disallow it if using MS dumpbin.
+ if ( test "$lt_cv_nm_interface" = "BSD nm" && file / ) >/dev/null 2>&1; then
+ lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+ lt_cv_file_magic_cmd='func_win32_libid'
+ else
+ lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?'
+ lt_cv_file_magic_cmd='$OBJDUMP -f'
+ fi
+ ;;
+
+cegcc*)
+ # use the weaker test based on 'objdump'. See mingw*.
+ lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?'
+ lt_cv_file_magic_cmd='$OBJDUMP -f'
+ ;;
+
+darwin* | rhapsody*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+freebsd* | dragonfly*)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
+ case $host_cpu in
+ i*86 )
+ # Not sure whether the presence of OpenBSD here was a mistake.
+ # Let's accept both of them until this is cleared up.
+ lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library'
+ lt_cv_file_magic_cmd=/usr/bin/file
+ lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*`
+ ;;
+ esac
+ else
+ lt_cv_deplibs_check_method=pass_all
+ fi
+ ;;
+
+gnu*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+haiku*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+hpux10.20* | hpux11*)
+ lt_cv_file_magic_cmd=/usr/bin/file
+ case $host_cpu in
+ ia64*)
+ lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64'
+ lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so
+ ;;
+ hppa*64*)
+ lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]'
+ lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl
+ ;;
+ *)
+ lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9]\.[0-9]) shared library'
+ lt_cv_file_magic_test_file=/usr/lib/libc.sl
+ ;;
+ esac
+ ;;
+
+interix[3-9]*)
+ # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here
+ lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$'
+ ;;
+
+irix5* | irix6* | nonstopux*)
+ case $LD in
+ *-32|*"-32 ") libmagic=32-bit;;
+ *-n32|*"-n32 ") libmagic=N32;;
+ *-64|*"-64 ") libmagic=64-bit;;
+ *) libmagic=never-match;;
+ esac
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+# This must be Linux ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+netbsd*)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
+ lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$'
+ else
+ lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$'
+ fi
+ ;;
+
+newos6*)
+ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)'
+ lt_cv_file_magic_cmd=/usr/bin/file
+ lt_cv_file_magic_test_file=/usr/lib/libnls.so
+ ;;
+
+*nto* | *qnx*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+openbsd*)
+ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+ lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$'
+ else
+ lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$'
+ fi
+ ;;
+
+osf3* | osf4* | osf5*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+rdos*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+solaris*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+sysv4 | sysv4.3*)
+ case $host_vendor in
+ motorola)
+ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]'
+ lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*`
+ ;;
+ ncr)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+ sequent)
+ lt_cv_file_magic_cmd='/bin/file'
+ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )'
+ ;;
+ sni)
+ lt_cv_file_magic_cmd='/bin/file'
+ lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib"
+ lt_cv_file_magic_test_file=/lib/libc.so
+ ;;
+ siemens)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+ pc)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+ esac
+ ;;
+
+tpf*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+esac
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5
+$as_echo "$lt_cv_deplibs_check_method" >&6; }
+file_magic_cmd=$lt_cv_file_magic_cmd
+deplibs_check_method=$lt_cv_deplibs_check_method
+test -z "$deplibs_check_method" && deplibs_check_method=unknown
+
+
+
+
+
+
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+ # 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
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_AR+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$AR"; then
+ ac_cv_prog_AR="$AR" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_AR="${ac_tool_prefix}ar"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+AR=$ac_cv_prog_AR
+if test -n "$AR"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5
+$as_echo "$AR" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_AR"; then
+ ac_ct_AR=$AR
+ # Extract the first word of "ar", so it can be a program name with args.
+set dummy ar; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_AR+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_AR"; then
+ ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_ac_ct_AR="ar"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_AR=$ac_cv_prog_ac_ct_AR
+if test -n "$ac_ct_AR"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5
+$as_echo "$ac_ct_AR" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_AR" = x; then
+ AR="false"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ AR=$ac_ct_AR
+ fi
+else
+ AR="$ac_cv_prog_AR"
+fi
+
+test -z "$AR" && AR=ar
+test -z "$AR_FLAGS" && AR_FLAGS=cru
+
+
+
+
+
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args.
+set dummy ${ac_tool_prefix}strip; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_STRIP+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$STRIP"; then
+ ac_cv_prog_STRIP="$STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_STRIP="${ac_tool_prefix}strip"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+STRIP=$ac_cv_prog_STRIP
+if test -n "$STRIP"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5
+$as_echo "$STRIP" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_STRIP"; then
+ ac_ct_STRIP=$STRIP
+ # Extract the first word of "strip", so it can be a program name with args.
+set dummy strip; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_STRIP"; then
+ ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_ac_ct_STRIP="strip"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP
+if test -n "$ac_ct_STRIP"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5
+$as_echo "$ac_ct_STRIP" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_STRIP" = x; then
+ STRIP=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ STRIP=$ac_ct_STRIP
+ fi
+else
+ STRIP="$ac_cv_prog_STRIP"
+fi
+
+test -z "$STRIP" && STRIP=:
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+ # 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
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_RANLIB+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$RANLIB"; then
+ ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+RANLIB=$ac_cv_prog_RANLIB
+if test -n "$RANLIB"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5
+$as_echo "$RANLIB" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_RANLIB"; then
+ ac_ct_RANLIB=$RANLIB
+ # Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_RANLIB"; then
+ ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_ac_ct_RANLIB="ranlib"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB
+if test -n "$ac_ct_RANLIB"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5
+$as_echo "$ac_ct_RANLIB" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_RANLIB" = x; then
+ RANLIB=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ RANLIB=$ac_ct_RANLIB
+ fi
+else
+ RANLIB="$ac_cv_prog_RANLIB"
+fi
+
+test -z "$RANLIB" && RANLIB=:
+
+
+
+
+
+
+# Determine commands to create old-style static archives.
+old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs'
+old_postinstall_cmds='chmod 644 $oldlib'
+old_postuninstall_cmds=
+
+if test -n "$RANLIB"; then
+ case $host_os in
+ openbsd*)
+ old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$oldlib"
+ ;;
+ *)
+ old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$oldlib"
+ ;;
+ esac
+ old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib"
+fi
+
+case $host_os in
+ darwin*)
+ lock_old_archive_extraction=yes ;;
+ *)
+ lock_old_archive_extraction=no ;;
+esac
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+
+
+# Check for command to grab the raw symbol name followed by C symbol from nm.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking command to parse $NM output from $compiler object" >&5
+$as_echo_n "checking command to parse $NM output from $compiler object... " >&6; }
+if test "${lt_cv_sys_global_symbol_pipe+set}" = set; then :
+ $as_echo_n "(cached) " >&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.
+symcode='[BCDEGRST]'
+
+# Regexp to match symbols that can be accessed directly from C.
+sympat='\([_A-Za-z][_A-Za-z0-9]*\)'
+
+# Define system-specific variables.
+case $host_os in
+aix*)
+ symcode='[BCDT]'
+ ;;
+cygwin* | mingw* | pw32* | cegcc*)
+ symcode='[ABCDGISTW]'
+ ;;
+hpux*)
+ if test "$host_cpu" = ia64; then
+ symcode='[ABCDEGRST]'
+ fi
+ ;;
+irix* | nonstopux*)
+ symcode='[BCDEGRST]'
+ ;;
+osf*)
+ symcode='[BCDEGQRST]'
+ ;;
+solaris*)
+ symcode='[BDRT]'
+ ;;
+sco3.2v5*)
+ symcode='[DT]'
+ ;;
+sysv4.2uw2*)
+ symcode='[DT]'
+ ;;
+sysv5* | sco5v6* | unixware* | OpenUNIX*)
+ symcode='[ABDT]'
+ ;;
+sysv4)
+ symcode='[DFNSTU]'
+ ;;
+esac
+
+# If we're using GNU nm, then use its standard symbol codes.
+case `$NM -V 2>&1` in
+*GNU* | *'with BFD'*)
+ symcode='[ABCDGIRSTW]' ;;
+esac
+
+# Transform an extracted symbol line into a proper C declaration.
+# Some systems (esp. on ia64) link data and code symbols differently,
+# so use this general approach.
+lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'"
+
+# Transform an extracted symbol line into symbol name and symbol address
+lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\) $/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"\2\", (void *) \&\2},/p'"
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([^ ]*\) $/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \(lib[^ ]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"lib\2\", (void *) \&\2},/p'"
+
+# Handle CRLF in mingw tool chain
+opt_cr=
+case $build_os in
+mingw*)
+ opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp
+ ;;
+esac
+
+# Try without a prefix underscore, then with it.
+for ac_symprfx in "" "_"; do
+
+ # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol.
+ symxfrm="\\1 $ac_symprfx\\2 \\2"
+
+ # Write the raw and C identifiers.
+ if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+ # Fake it for dumpbin and say T for any non-static function
+ # and D for any global variable.
+ # Also find C++ and __fastcall symbols from MSVC++,
+ # which start with @ or ?.
+ lt_cv_sys_global_symbol_pipe="$AWK '"\
+" {last_section=section; section=\$ 3};"\
+" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\
+" \$ 0!~/External *\|/{next};"\
+" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\
+" {if(hide[section]) next};"\
+" {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\
+" {split(\$ 0, a, /\||\r/); split(a[2], s)};"\
+" s[1]~/^[@?]/{print s[1], s[1]; next};"\
+" s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\
+" ' prfx=^$ac_symprfx"
+ else
+ lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'"
+ fi
+
+ # Check to see that the pipe works correctly.
+ pipe_works=no
+
+ rm -f conftest*
+ cat > conftest.$ac_ext <<_LT_EOF
+#ifdef __cplusplus
+extern "C" {
+#endif
+char nm_test_var;
+void nm_test_func(void);
+void nm_test_func(void){}
+#ifdef __cplusplus
+}
+#endif
+int main(){nm_test_var='a';nm_test_func();return(0);}
+_LT_EOF
+
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ # Now try to grab the symbols.
+ nlist=conftest.nm
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist\""; } >&5
+ (eval $NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && 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 $GREP ' nm_test_var$' "$nlist" >/dev/null; then
+ if $GREP ' nm_test_func$' "$nlist" >/dev/null; then
+ cat <<_LT_EOF > conftest.$ac_ext
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+_LT_EOF
+ # Now generate the symbol file.
+ eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext'
+
+ cat <<_LT_EOF >> conftest.$ac_ext
+
+/* The mapping between symbol names and symbols. */
+const struct {
+ const char *name;
+ void *address;
+}
+lt__PROGRAM__LTX_preloaded_symbols[] =
+{
+ { "@PROGRAM@", (void *) 0 },
+_LT_EOF
+ $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext
+ cat <<\_LT_EOF >> conftest.$ac_ext
+ {0, (void *) 0}
+};
+
+/* This works around a problem in FreeBSD linker */
+#ifdef FREEBSD_WORKAROUND
+static const void *lt_preloaded_setup() {
+ return lt__PROGRAM__LTX_preloaded_symbols;
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+_LT_EOF
+ # Now try linking the two files.
+ mv conftest.$ac_objext conftstm.$ac_objext
+ lt_save_LIBS="$LIBS"
+ lt_save_CFLAGS="$CFLAGS"
+ LIBS="conftstm.$ac_objext"
+ CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag"
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && test -s conftest${ac_exeext}; then
+ pipe_works=yes
+ fi
+ LIBS="$lt_save_LIBS"
+ CFLAGS="$lt_save_CFLAGS"
+ 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 $lt_cv_sys_global_symbol_pipe" >&5
+ fi
+ else
+ echo "$progname: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ fi
+ rm -rf conftest* conftst*
+
+ # Do not use the global_symbol_pipe unless it works.
+ if test "$pipe_works" = yes; then
+ break
+ else
+ lt_cv_sys_global_symbol_pipe=
+ fi
+done
+
+fi
+
+if test -z "$lt_cv_sys_global_symbol_pipe"; then
+ lt_cv_sys_global_symbol_to_cdecl=
+fi
+if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5
+$as_echo "failed" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5
+$as_echo "ok" >&6; }
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# Check whether --enable-libtool-lock was given.
+if test "${enable_libtool_lock+set}" = set; then :
+ enableval=$enable_libtool_lock;
+fi
+
+test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes
+
+# Some flags need to be propagated to the compiler or linker for good
+# libtool support.
+case $host in
+ia64-*-hpux*)
+ # Find out which ABI we are using.
+ echo 'int i;' > conftest.$ac_ext
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ case `/usr/bin/file conftest.$ac_objext` in
+ *ELF-32*)
+ HPUX_IA64_MODE="32"
+ ;;
+ *ELF-64*)
+ HPUX_IA64_MODE="64"
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+*-*-irix6*)
+ # Find out which ABI we are using.
+ echo '#line '$LINENO' "configure"' > conftest.$ac_ext
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ if test "$lt_cv_prog_gnu_ld" = yes; then
+ case `/usr/bin/file conftest.$ac_objext` in
+ *32-bit*)
+ LD="${LD-ld} -melf32bsmip"
+ ;;
+ *N32*)
+ LD="${LD-ld} -melf32bmipn32"
+ ;;
+ *64-bit*)
+ LD="${LD-ld} -melf64bmip"
+ ;;
+ esac
+ else
+ case `/usr/bin/file conftest.$ac_objext` in
+ *32-bit*)
+ LD="${LD-ld} -32"
+ ;;
+ *N32*)
+ LD="${LD-ld} -n32"
+ ;;
+ *64-bit*)
+ LD="${LD-ld} -64"
+ ;;
+ esac
+ fi
+ fi
+ rm -rf conftest*
+ ;;
+
+x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \
+s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
+ # Find out which ABI we are using.
+ echo 'int i;' > conftest.$ac_ext
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ case `/usr/bin/file conftest.o` in
+ *32-bit*)
+ case $host in
+ x86_64-*kfreebsd*-gnu)
+ LD="${LD-ld} -m elf_i386_fbsd"
+ ;;
+ x86_64-*linux*)
+ case `/usr/bin/file conftest.o` in
+ *x86-64*)
+ LD="${LD-ld} -m elf32_x86_64"
+ ;;
+ *)
+ LD="${LD-ld} -m elf_i386"
+ ;;
+ esac
+ ;;
+ powerpc64le-*linux*)
+ LD="${LD-ld} -m elf32lppclinux"
+ ;;
+ powerpc64-*linux*)
+ LD="${LD-ld} -m elf32ppclinux"
+ ;;
+ s390x-*linux*)
+ LD="${LD-ld} -m elf_s390"
+ ;;
+ sparc64-*linux*)
+ LD="${LD-ld} -m elf32_sparc"
+ ;;
+ esac
+ ;;
+ *64-bit*)
+ case $host in
+ x86_64-*kfreebsd*-gnu)
+ LD="${LD-ld} -m elf_x86_64_fbsd"
+ ;;
+ x86_64-*linux*)
+ LD="${LD-ld} -m elf_x86_64"
+ ;;
+ powerpcle-*linux*)
+ LD="${LD-ld} -m elf64lppc"
+ ;;
+ powerpc-*linux*)
+ LD="${LD-ld} -m elf64ppc"
+ ;;
+ s390*-*linux*|s390*-*tpf*)
+ LD="${LD-ld} -m elf64_s390"
+ ;;
+ sparc*-*linux*)
+ LD="${LD-ld} -m elf64_sparc"
+ ;;
+ esac
+ ;;
+ 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"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5
+$as_echo_n "checking whether the C compiler needs -belf... " >&6; }
+if test "${lt_cv_cc_needs_belf+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ lt_cv_cc_needs_belf=yes
+else
+ lt_cv_cc_needs_belf=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5
+$as_echo "$lt_cv_cc_needs_belf" >&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
+ ;;
+sparc*-*solaris*)
+ # Find out which ABI we are using.
+ echo 'int i;' > conftest.$ac_ext
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ case `/usr/bin/file conftest.o` in
+ *64-bit*)
+ case $lt_cv_prog_gnu_ld in
+ yes*) LD="${LD-ld} -m elf64_sparc" ;;
+ *)
+ if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then
+ LD="${LD-ld} -64"
+ fi
+ ;;
+ esac
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+esac
+
+need_locks="$enable_libtool_lock"
+
+
+ case $host_os in
+ rhapsody* | darwin*)
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}dsymutil", so it can be a program name with args.
+set dummy ${ac_tool_prefix}dsymutil; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_DSYMUTIL+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$DSYMUTIL"; then
+ ac_cv_prog_DSYMUTIL="$DSYMUTIL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+DSYMUTIL=$ac_cv_prog_DSYMUTIL
+if test -n "$DSYMUTIL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL" >&5
+$as_echo "$DSYMUTIL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_DSYMUTIL"; then
+ ac_ct_DSYMUTIL=$DSYMUTIL
+ # Extract the first word of "dsymutil", so it can be a program name with args.
+set dummy dsymutil; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_DSYMUTIL+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_DSYMUTIL"; then
+ ac_cv_prog_ac_ct_DSYMUTIL="$ac_ct_DSYMUTIL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_ac_ct_DSYMUTIL="dsymutil"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_DSYMUTIL=$ac_cv_prog_ac_ct_DSYMUTIL
+if test -n "$ac_ct_DSYMUTIL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DSYMUTIL" >&5
+$as_echo "$ac_ct_DSYMUTIL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_DSYMUTIL" = x; then
+ DSYMUTIL=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ DSYMUTIL=$ac_ct_DSYMUTIL
+ fi
+else
+ DSYMUTIL="$ac_cv_prog_DSYMUTIL"
+fi
+
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}nmedit", so it can be a program name with args.
+set dummy ${ac_tool_prefix}nmedit; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_NMEDIT+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$NMEDIT"; then
+ ac_cv_prog_NMEDIT="$NMEDIT" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+NMEDIT=$ac_cv_prog_NMEDIT
+if test -n "$NMEDIT"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NMEDIT" >&5
+$as_echo "$NMEDIT" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_NMEDIT"; then
+ ac_ct_NMEDIT=$NMEDIT
+ # Extract the first word of "nmedit", so it can be a program name with args.
+set dummy nmedit; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_NMEDIT+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_NMEDIT"; then
+ ac_cv_prog_ac_ct_NMEDIT="$ac_ct_NMEDIT" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_ac_ct_NMEDIT="nmedit"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_NMEDIT=$ac_cv_prog_ac_ct_NMEDIT
+if test -n "$ac_ct_NMEDIT"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NMEDIT" >&5
+$as_echo "$ac_ct_NMEDIT" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_NMEDIT" = x; then
+ NMEDIT=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ NMEDIT=$ac_ct_NMEDIT
+ fi
+else
+ NMEDIT="$ac_cv_prog_NMEDIT"
+fi
+
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}lipo", so it can be a program name with args.
+set dummy ${ac_tool_prefix}lipo; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_LIPO+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$LIPO"; then
+ ac_cv_prog_LIPO="$LIPO" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_LIPO="${ac_tool_prefix}lipo"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+LIPO=$ac_cv_prog_LIPO
+if test -n "$LIPO"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIPO" >&5
+$as_echo "$LIPO" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_LIPO"; then
+ ac_ct_LIPO=$LIPO
+ # Extract the first word of "lipo", so it can be a program name with args.
+set dummy lipo; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_LIPO+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_LIPO"; then
+ ac_cv_prog_ac_ct_LIPO="$ac_ct_LIPO" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_ac_ct_LIPO="lipo"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_LIPO=$ac_cv_prog_ac_ct_LIPO
+if test -n "$ac_ct_LIPO"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LIPO" >&5
+$as_echo "$ac_ct_LIPO" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_LIPO" = x; then
+ LIPO=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ LIPO=$ac_ct_LIPO
+ fi
+else
+ LIPO="$ac_cv_prog_LIPO"
+fi
+
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}otool", so it can be a program name with args.
+set dummy ${ac_tool_prefix}otool; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_OTOOL+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$OTOOL"; then
+ ac_cv_prog_OTOOL="$OTOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_OTOOL="${ac_tool_prefix}otool"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+OTOOL=$ac_cv_prog_OTOOL
+if test -n "$OTOOL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5
+$as_echo "$OTOOL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_OTOOL"; then
+ ac_ct_OTOOL=$OTOOL
+ # Extract the first word of "otool", so it can be a program name with args.
+set dummy otool; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_OTOOL+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_OTOOL"; then
+ ac_cv_prog_ac_ct_OTOOL="$ac_ct_OTOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_ac_ct_OTOOL="otool"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_OTOOL=$ac_cv_prog_ac_ct_OTOOL
+if test -n "$ac_ct_OTOOL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL" >&5
+$as_echo "$ac_ct_OTOOL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_OTOOL" = x; then
+ OTOOL=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ OTOOL=$ac_ct_OTOOL
+ fi
+else
+ OTOOL="$ac_cv_prog_OTOOL"
+fi
+
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}otool64", so it can be a program name with args.
+set dummy ${ac_tool_prefix}otool64; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_OTOOL64+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$OTOOL64"; then
+ ac_cv_prog_OTOOL64="$OTOOL64" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+OTOOL64=$ac_cv_prog_OTOOL64
+if test -n "$OTOOL64"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL64" >&5
+$as_echo "$OTOOL64" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_OTOOL64"; then
+ ac_ct_OTOOL64=$OTOOL64
+ # Extract the first word of "otool64", so it can be a program name with args.
+set dummy otool64; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_OTOOL64+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_OTOOL64"; then
+ ac_cv_prog_ac_ct_OTOOL64="$ac_ct_OTOOL64" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_ac_ct_OTOOL64="otool64"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_OTOOL64=$ac_cv_prog_ac_ct_OTOOL64
+if test -n "$ac_ct_OTOOL64"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL64" >&5
+$as_echo "$ac_ct_OTOOL64" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_OTOOL64" = x; then
+ OTOOL64=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ OTOOL64=$ac_ct_OTOOL64
+ fi
+else
+ OTOOL64="$ac_cv_prog_OTOOL64"
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -single_module linker flag" >&5
+$as_echo_n "checking for -single_module linker flag... " >&6; }
+if test "${lt_cv_apple_cc_single_mod+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_apple_cc_single_mod=no
+ if test -z "${LT_MULTI_MODULE}"; then
+ # By default we will add the -single_module flag. You can override
+ # by either setting the environment variable LT_MULTI_MODULE
+ # non-empty at configure time, or by adding -multi_module to the
+ # link flags.
+ rm -rf libconftest.dylib*
+ echo "int foo(void){return 1;}" > conftest.c
+ echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
+-dynamiclib -Wl,-single_module conftest.c" >&5
+ $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
+ -dynamiclib -Wl,-single_module conftest.c 2>conftest.err
+ _lt_result=$?
+ if test -f libconftest.dylib && test ! -s conftest.err && test $_lt_result = 0; then
+ lt_cv_apple_cc_single_mod=yes
+ else
+ cat conftest.err >&5
+ fi
+ rm -rf libconftest.dylib*
+ rm -f conftest.*
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5
+$as_echo "$lt_cv_apple_cc_single_mod" >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5
+$as_echo_n "checking for -exported_symbols_list linker flag... " >&6; }
+if test "${lt_cv_ld_exported_symbols_list+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_ld_exported_symbols_list=no
+ save_LDFLAGS=$LDFLAGS
+ echo "_main" > conftest.sym
+ LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ lt_cv_ld_exported_symbols_list=yes
+else
+ lt_cv_ld_exported_symbols_list=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ LDFLAGS="$save_LDFLAGS"
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5
+$as_echo "$lt_cv_ld_exported_symbols_list" >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -force_load linker flag" >&5
+$as_echo_n "checking for -force_load linker flag... " >&6; }
+if test "${lt_cv_ld_force_load+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_ld_force_load=no
+ cat > conftest.c << _LT_EOF
+int forced_loaded() { return 2;}
+_LT_EOF
+ echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5
+ $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5
+ echo "$AR cru libconftest.a conftest.o" >&5
+ $AR cru libconftest.a conftest.o 2>&5
+ cat > conftest.c << _LT_EOF
+int main() { return 0;}
+_LT_EOF
+ echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&5
+ $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err
+ _lt_result=$?
+ if test -f conftest && test ! -s conftest.err && test $_lt_result = 0 && $GREP forced_load conftest 2>&1 >/dev/null; then
+ lt_cv_ld_force_load=yes
+ else
+ cat conftest.err >&5
+ fi
+ rm -f conftest.err libconftest.a conftest conftest.c
+ rm -rf conftest.dSYM
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_force_load" >&5
+$as_echo "$lt_cv_ld_force_load" >&6; }
+ case $host_os in
+ rhapsody* | darwin1.[012])
+ _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;;
+ darwin1.*)
+ _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;;
+ darwin*) # darwin 5.x on
+ # if running on 10.5 or later, the deployment target defaults
+ # to the OS version, if on x86, and 10.4, the deployment
+ # target defaults to 10.4. Don't you love it?
+ case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in
+ 10.0,*86*-darwin8*|10.0,*-darwin[91]*)
+ _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;
+ 10.[012]*)
+ _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;;
+ 10.*)
+ _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;
+ esac
+ ;;
+ esac
+ if test "$lt_cv_apple_cc_single_mod" = "yes"; then
+ _lt_dar_single_mod='$single_module'
+ fi
+ if test "$lt_cv_ld_exported_symbols_list" = "yes"; then
+ _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym'
+ else
+ _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}'
+ fi
+ if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then
+ _lt_dsymutil='~$DSYMUTIL $lib || :'
+ else
+ _lt_dsymutil=
+ fi
+ ;;
+ esac
+
+for ac_header in dlfcn.h
+do :
+ ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default
+"
+if test "x$ac_cv_header_dlfcn_h" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_DLFCN_H 1
+_ACEOF
+
+fi
+
+done
+
+
+
+
+
+# Set options
+enable_dlopen=yes
+
+
+
+
+ enable_win32_dll=no
+
+
+
+ # Check whether --enable-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.
+ lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+ for pkg in $enableval; do
+ IFS="$lt_save_ifs"
+ if test "X$pkg" = "X$p"; then
+ enable_static=yes
+ fi
+ done
+ IFS="$lt_save_ifs"
+ ;;
+ esac
+else
+ enable_static=yes
+fi
+
+
+
+
+
+
+
+
+
+
+# Check whether --with-pic was given.
+if test "${with_pic+set}" = set; then :
+ withval=$with_pic; pic_mode="$withval"
+else
+ pic_mode=default
+fi
+
+
+test -z "$pic_mode" && pic_mode=default
+
+
+
+
+
+
+
+ # Check whether --enable-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.
+ lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+ for pkg in $enableval; do
+ IFS="$lt_save_ifs"
+ if test "X$pkg" = "X$p"; then
+ enable_fast_install=yes
+ fi
+ done
+ IFS="$lt_save_ifs"
+ ;;
+ esac
+else
+ enable_fast_install=yes
+fi
+
+
+
+
+
+
+
+
+
+
+
+# This can be used to rebuild libtool when needed
+LIBTOOL_DEPS="$ltmain"
+
+# Always use our own libtool.
+LIBTOOL='$(SHELL) $(top_builddir)/libtool'
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+test -z "$LN_S" && LN_S="ln -s"
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+if test -n "${ZSH_VERSION+set}" ; then
+ setopt NO_GLOB_SUBST
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for objdir" >&5
+$as_echo_n "checking for objdir... " >&6; }
+if test "${lt_cv_objdir+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ rm -f .libs 2>/dev/null
+mkdir .libs 2>/dev/null
+if test -d .libs; then
+ lt_cv_objdir=.libs
+else
+ # MS-DOS does not allow filenames that begin with a dot.
+ lt_cv_objdir=_libs
+fi
+rmdir .libs 2>/dev/null
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_objdir" >&5
+$as_echo "$lt_cv_objdir" >&6; }
+objdir=$lt_cv_objdir
+
+
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define LT_OBJDIR "$lt_cv_objdir/"
+_ACEOF
+
+
+
+
+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 "X${COLLECT_NAMES+set}" != Xset; then
+ COLLECT_NAMES=
+ export COLLECT_NAMES
+ fi
+ ;;
+esac
+
+# Global variables:
+ofile=libtool
+can_build_shared=yes
+
+# All known linkers require a `.a' archive for static linking (except MSVC,
+# which needs '.lib').
+libext=a
+
+with_gnu_ld="$lt_cv_prog_gnu_ld"
+
+old_CC="$CC"
+old_CFLAGS="$CFLAGS"
+
+# Set sane defaults for various variables
+test -z "$CC" && CC=cc
+test -z "$LTCC" && LTCC=$CC
+test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS
+test -z "$LD" && LD=ld
+test -z "$ac_objext" && ac_objext=o
+
+for cc_temp in $compiler""; do
+ case $cc_temp in
+ compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
+ distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
+ \-*) ;;
+ *) break;;
+ esac
+done
+cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"`
+
+
+# Only perform the check for file, if the check method requires it
+test -z "$MAGIC_CMD" && MAGIC_CMD=file
+case $deplibs_check_method in
+file_magic*)
+ if test "$file_magic_cmd" = '$MAGIC_CMD'; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${ac_tool_prefix}file" >&5
+$as_echo_n "checking for ${ac_tool_prefix}file... " >&6; }
+if test "${lt_cv_path_MAGIC_CMD+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $MAGIC_CMD in
+[\\/*] | ?:[\\/]*)
+ lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
+ ;;
+*)
+ lt_save_MAGIC_CMD="$MAGIC_CMD"
+ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+ ac_dummy="/usr/bin$PATH_SEPARATOR$PATH"
+ for ac_dir in $ac_dummy; do
+ IFS="$lt_save_ifs"
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/${ac_tool_prefix}file; then
+ lt_cv_path_MAGIC_CMD="$ac_dir/${ac_tool_prefix}file"
+ if test -n "$file_magic_test_file"; then
+ case $deplibs_check_method in
+ "file_magic "*)
+ file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
+ MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+ if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+ $EGREP "$file_magic_regex" > /dev/null; then
+ :
+ else
+ cat <<_LT_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
+
+_LT_EOF
+ fi ;;
+ esac
+ fi
+ break
+ fi
+ done
+ IFS="$lt_save_ifs"
+ MAGIC_CMD="$lt_save_MAGIC_CMD"
+ ;;
+esac
+fi
+
+MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+if test -n "$MAGIC_CMD"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5
+$as_echo "$MAGIC_CMD" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+
+
+
+if test -z "$lt_cv_path_MAGIC_CMD"; then
+ if test -n "$ac_tool_prefix"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for file" >&5
+$as_echo_n "checking for file... " >&6; }
+if test "${lt_cv_path_MAGIC_CMD+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $MAGIC_CMD in
+[\\/*] | ?:[\\/]*)
+ lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
+ ;;
+*)
+ lt_save_MAGIC_CMD="$MAGIC_CMD"
+ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+ ac_dummy="/usr/bin$PATH_SEPARATOR$PATH"
+ for ac_dir in $ac_dummy; do
+ IFS="$lt_save_ifs"
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/file; then
+ lt_cv_path_MAGIC_CMD="$ac_dir/file"
+ if test -n "$file_magic_test_file"; then
+ case $deplibs_check_method in
+ "file_magic "*)
+ file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
+ MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+ if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+ $EGREP "$file_magic_regex" > /dev/null; then
+ :
+ else
+ cat <<_LT_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
+
+_LT_EOF
+ fi ;;
+ esac
+ fi
+ break
+ fi
+ done
+ IFS="$lt_save_ifs"
+ MAGIC_CMD="$lt_save_MAGIC_CMD"
+ ;;
+esac
+fi
+
+MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+if test -n "$MAGIC_CMD"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5
+$as_echo "$MAGIC_CMD" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ else
+ MAGIC_CMD=:
+ fi
+fi
+
+ fi
+ ;;
+esac
+
+# Use C for the default configuration in the libtool script
+
+lt_save_CC="$CC"
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+# Source file extension for C test sources.
+ac_ext=c
+
+# Object file extension for compiled C test sources.
+objext=o
+objext=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="int some_variable = 0;"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='int main(){return(0);}'
+
+
+
+
+
+
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+
+# Save the default compiler, since it gets overwritten when the other
+# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP.
+compiler_DEFAULT=$CC
+
+# save warnings/boilerplate of simple test code
+ac_outfile=conftest.$ac_objext
+echo "$lt_simple_compile_test_code" >conftest.$ac_ext
+eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_compiler_boilerplate=`cat conftest.err`
+$RM conftest*
+
+ac_outfile=conftest.$ac_objext
+echo "$lt_simple_link_test_code" >conftest.$ac_ext
+eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_linker_boilerplate=`cat conftest.err`
+$RM -r conftest*
+
+
+## CAVEAT EMPTOR:
+## There is no encapsulation within the following macros, do not change
+## the running order or otherwise move them around unless you know exactly
+## what you are doing...
+if test -n "$compiler"; then
+
+lt_prog_compiler_no_builtin_flag=
+
+if test "$GCC" = yes; then
+ case $cc_basename in
+ nvcc*)
+ lt_prog_compiler_no_builtin_flag=' -Xcompiler -fno-builtin' ;;
+ *)
+ lt_prog_compiler_no_builtin_flag=' -fno-builtin' ;;
+ esac
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5
+$as_echo_n "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; }
+if test "${lt_cv_prog_compiler_rtti_exceptions+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_rtti_exceptions=no
+ ac_outfile=conftest.$ac_objext
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+ lt_compiler_flag="-fno-rtti -fno-exceptions"
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ # The option is referenced via a variable to avoid confusing sed.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
+ (eval "$lt_compile" 2>conftest.err)
+ ac_status=$?
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ if (exit $ac_status) && test -s "$ac_outfile"; then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings other than the usual output.
+ $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler_rtti_exceptions=yes
+ fi
+ fi
+ $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5
+$as_echo "$lt_cv_prog_compiler_rtti_exceptions" >&6; }
+
+if test x"$lt_cv_prog_compiler_rtti_exceptions" = xyes; then
+ lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions"
+else
+ :
+fi
+
+fi
+
+
+
+
+
+
+ lt_prog_compiler_wl=
+lt_prog_compiler_pic=
+lt_prog_compiler_static=
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5
+$as_echo_n "checking for $compiler option to produce PIC... " >&6; }
+
+ if test "$GCC" = yes; then
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_static='-static'
+
+ case $host_os in
+ aix*)
+ # All AIX code is PIC.
+ if test "$host_cpu" = ia64; then
+ # AIX 5 now supports IA64 processor
+ lt_prog_compiler_static='-Bstatic'
+ fi
+ lt_prog_compiler_pic='-fPIC'
+ ;;
+
+ amigaos*)
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+ lt_prog_compiler_pic='-fPIC'
+ ;;
+ m68k)
+ # FIXME: we need at least 68020 code to build shared libraries, but
+ # adding the `-m68020' flag to GCC prevents building anything better,
+ # like `-m68040'.
+ lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4'
+ ;;
+ esac
+ ;;
+
+ beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+ # PIC is the default for these OSes.
+ ;;
+
+ mingw* | cygwin* | pw32* | os2* | cegcc*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ # Although the cygwin gcc ignores -fPIC, still need this for old-style
+ # (--disable-auto-import) libraries
+ lt_prog_compiler_pic='-DDLL_EXPORT'
+ ;;
+
+ darwin* | rhapsody*)
+ # PIC is the default on this platform
+ # Common symbols not allowed in MH_DYLIB files
+ lt_prog_compiler_pic='-fno-common'
+ ;;
+
+ haiku*)
+ # PIC is the default for Haiku.
+ # The "-static" flag exists, but is broken.
+ lt_prog_compiler_static=
+ ;;
+
+ hpux*)
+ # PIC is the default for 64-bit PA HP-UX, but not for 32-bit
+ # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag
+ # sets the default TLS model and affects inlining.
+ case $host_cpu in
+ hppa*64*)
+ # +Z the default
+ ;;
+ *)
+ lt_prog_compiler_pic='-fPIC'
+ ;;
+ esac
+ ;;
+
+ interix[3-9]*)
+ # Interix 3.x gcc -fpic/-fPIC options generate broken code.
+ # Instead, we relocate shared libraries at runtime.
+ ;;
+
+ msdosdjgpp*)
+ # Just because we use GCC doesn't mean we suddenly get shared libraries
+ # on systems that don't support them.
+ lt_prog_compiler_can_build_shared=no
+ enable_shared=no
+ ;;
+
+ *nto* | *qnx*)
+ # QNX uses GNU C++, but need to define -shared option too, otherwise
+ # it will coredump.
+ lt_prog_compiler_pic='-fPIC -shared'
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ lt_prog_compiler_pic=-Kconform_pic
+ fi
+ ;;
+
+ *)
+ lt_prog_compiler_pic='-fPIC'
+ ;;
+ esac
+
+ case $cc_basename in
+ nvcc*) # Cuda Compiler Driver 2.2
+ lt_prog_compiler_wl='-Xlinker '
+ lt_prog_compiler_pic='-Xcompiler -fPIC'
+ ;;
+ esac
+ else
+ # PORTME Check for flag to pass linker flags through the system compiler.
+ case $host_os in
+ aix*)
+ lt_prog_compiler_wl='-Wl,'
+ if test "$host_cpu" = ia64; then
+ # AIX 5 now supports IA64 processor
+ lt_prog_compiler_static='-Bstatic'
+ else
+ lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp'
+ fi
+ ;;
+
+ mingw* | cygwin* | pw32* | os2* | cegcc*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ lt_prog_compiler_pic='-DDLL_EXPORT'
+ ;;
+
+ hpux9* | hpux10* | hpux11*)
+ lt_prog_compiler_wl='-Wl,'
+ # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
+ # not for PA HP-UX.
+ case $host_cpu in
+ hppa*64*|ia64*)
+ # +Z the default
+ ;;
+ *)
+ lt_prog_compiler_pic='+Z'
+ ;;
+ esac
+ # Is there a better lt_prog_compiler_static that works with the bundled CC?
+ lt_prog_compiler_static='${wl}-a ${wl}archive'
+ ;;
+
+ irix5* | irix6* | nonstopux*)
+ lt_prog_compiler_wl='-Wl,'
+ # PIC (with -KPIC) is the default.
+ lt_prog_compiler_static='-non_shared'
+ ;;
+
+ linux* | k*bsd*-gnu | kopensolaris*-gnu)
+ case $cc_basename in
+ # old Intel for x86_64 which still supported -KPIC.
+ ecc*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-static'
+ ;;
+ # icc used to be incompatible with GCC.
+ # ICC 10 doesn't accept -KPIC any more.
+ icc* | ifort*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-fPIC'
+ lt_prog_compiler_static='-static'
+ ;;
+ # Lahey Fortran 8.1.
+ lf95*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='--shared'
+ lt_prog_compiler_static='--static'
+ ;;
+ pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*)
+ # Portland Group compilers (*not* the Pentium gcc compiler,
+ # which looks to be a dead project)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-fpic'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+ ccc*)
+ lt_prog_compiler_wl='-Wl,'
+ # All Alpha code is PIC.
+ lt_prog_compiler_static='-non_shared'
+ ;;
+ xl* | bgxl* | bgf* | mpixl*)
+ # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-qpic'
+ lt_prog_compiler_static='-qstaticlink'
+ ;;
+ *)
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ F* | *Sun*Fortran*)
+ # Sun Fortran 8.3 passes all unrecognized flags to the linker
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ lt_prog_compiler_wl=''
+ ;;
+ *Sun\ C*)
+ # Sun C 5.9
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ lt_prog_compiler_wl='-Wl,'
+ ;;
+ esac
+ ;;
+ esac
+ ;;
+
+ newsos6)
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+
+ *nto* | *qnx*)
+ # QNX uses GNU C++, but need to define -shared option too, otherwise
+ # it will coredump.
+ lt_prog_compiler_pic='-fPIC -shared'
+ ;;
+
+ osf3* | osf4* | osf5*)
+ lt_prog_compiler_wl='-Wl,'
+ # All OSF/1 code is PIC.
+ lt_prog_compiler_static='-non_shared'
+ ;;
+
+ rdos*)
+ lt_prog_compiler_static='-non_shared'
+ ;;
+
+ solaris*)
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ case $cc_basename in
+ f77* | f90* | f95*)
+ lt_prog_compiler_wl='-Qoption ld ';;
+ *)
+ lt_prog_compiler_wl='-Wl,';;
+ esac
+ ;;
+
+ sunos4*)
+ lt_prog_compiler_wl='-Qoption ld '
+ lt_prog_compiler_pic='-PIC'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+
+ sysv4 | sysv4.2uw2* | sysv4.3*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec ;then
+ lt_prog_compiler_pic='-Kconform_pic'
+ lt_prog_compiler_static='-Bstatic'
+ fi
+ ;;
+
+ sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+
+ unicos*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_can_build_shared=no
+ ;;
+
+ uts4*)
+ lt_prog_compiler_pic='-pic'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+
+ *)
+ lt_prog_compiler_can_build_shared=no
+ ;;
+ esac
+ fi
+
+case $host_os in
+ # For platforms which do not support PIC, -DPIC is meaningless:
+ *djgpp*)
+ lt_prog_compiler_pic=
+ ;;
+ *)
+ lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC"
+ ;;
+esac
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_prog_compiler_pic" >&5
+$as_echo "$lt_prog_compiler_pic" >&6; }
+
+
+
+
+
+
+#
+# Check to make sure the PIC flag actually works.
+#
+if test -n "$lt_prog_compiler_pic"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5
+$as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; }
+if test "${lt_cv_prog_compiler_pic_works+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_pic_works=no
+ ac_outfile=conftest.$ac_objext
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+ lt_compiler_flag="$lt_prog_compiler_pic -DPIC"
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ # The option is referenced via a variable to avoid confusing sed.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
+ (eval "$lt_compile" 2>conftest.err)
+ ac_status=$?
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ if (exit $ac_status) && test -s "$ac_outfile"; then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings other than the usual output.
+ $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler_pic_works=yes
+ fi
+ fi
+ $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5
+$as_echo "$lt_cv_prog_compiler_pic_works" >&6; }
+
+if test x"$lt_cv_prog_compiler_pic_works" = xyes; then
+ case $lt_prog_compiler_pic in
+ "" | " "*) ;;
+ *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;;
+ esac
+else
+ lt_prog_compiler_pic=
+ lt_prog_compiler_can_build_shared=no
+fi
+
+fi
+
+
+
+
+
+
+#
+# Check to make sure the static flag actually works.
+#
+wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\"
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5
+$as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; }
+if test "${lt_cv_prog_compiler_static_works+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_static_works=no
+ save_LDFLAGS="$LDFLAGS"
+ LDFLAGS="$LDFLAGS $lt_tmp_static_flag"
+ echo "$lt_simple_link_test_code" > conftest.$ac_ext
+ if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
+ # The linker can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ if test -s conftest.err; then
+ # Append any errors to the config.log.
+ cat conftest.err 1>&5
+ $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if diff conftest.exp conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler_static_works=yes
+ fi
+ else
+ lt_cv_prog_compiler_static_works=yes
+ fi
+ fi
+ $RM -r conftest*
+ LDFLAGS="$save_LDFLAGS"
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5
+$as_echo "$lt_cv_prog_compiler_static_works" >&6; }
+
+if test x"$lt_cv_prog_compiler_static_works" = xyes; then
+ :
+else
+ lt_prog_compiler_static=
+fi
+
+
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5
+$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; }
+if test "${lt_cv_prog_compiler_c_o+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_c_o=no
+ $RM -r conftest 2>/dev/null
+ mkdir conftest
+ cd conftest
+ mkdir out
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+ lt_compiler_flag="-o out/conftest2.$ac_objext"
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
+ (eval "$lt_compile" 2>out/conftest.err)
+ ac_status=$?
+ cat out/conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ if (exit $ac_status) && test -s out/conftest2.$ac_objext
+ then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp
+ $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+ if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler_c_o=yes
+ fi
+ fi
+ chmod u+w . 2>&5
+ $RM conftest*
+ # SGI C++ compiler will create directory out/ii_files/ for
+ # template instantiation
+ test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
+ $RM out/* && rmdir out
+ cd ..
+ $RM -r conftest
+ $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5
+$as_echo "$lt_cv_prog_compiler_c_o" >&6; }
+
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5
+$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; }
+if test "${lt_cv_prog_compiler_c_o+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_c_o=no
+ $RM -r conftest 2>/dev/null
+ mkdir conftest
+ cd conftest
+ mkdir out
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+ lt_compiler_flag="-o out/conftest2.$ac_objext"
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
+ (eval "$lt_compile" 2>out/conftest.err)
+ ac_status=$?
+ cat out/conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ if (exit $ac_status) && test -s out/conftest2.$ac_objext
+ then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp
+ $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+ if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler_c_o=yes
+ fi
+ fi
+ chmod u+w . 2>&5
+ $RM conftest*
+ # SGI C++ compiler will create directory out/ii_files/ for
+ # template instantiation
+ test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
+ $RM out/* && rmdir out
+ cd ..
+ $RM -r conftest
+ $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5
+$as_echo "$lt_cv_prog_compiler_c_o" >&6; }
+
+
+
+
+hard_links="nottested"
+if test "$lt_cv_prog_compiler_c_o" = no && test "$need_locks" != no; then
+ # do not overwrite the value of need_locks provided by the user
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5
+$as_echo_n "checking if we can lock with hard links... " >&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
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5
+$as_echo "$hard_links" >&6; }
+ if test "$hard_links" = no; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5
+$as_echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;}
+ need_locks=warn
+ fi
+else
+ need_locks=no
+fi
+
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5
+$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; }
+
+ runpath_var=
+ allow_undefined_flag=
+ always_export_symbols=no
+ archive_cmds=
+ archive_expsym_cmds=
+ compiler_needs_object=no
+ enable_shared_with_static_runtimes=no
+ export_dynamic_flag_spec=
+ export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+ hardcode_automatic=no
+ hardcode_direct=no
+ hardcode_direct_absolute=no
+ hardcode_libdir_flag_spec=
+ hardcode_libdir_flag_spec_ld=
+ hardcode_libdir_separator=
+ hardcode_minus_L=no
+ hardcode_shlibpath_var=unsupported
+ inherit_rpath=no
+ link_all_deplibs=unknown
+ module_cmds=
+ module_expsym_cmds=
+ old_archive_from_new_cmds=
+ old_archive_from_expsyms_cmds=
+ thread_safe_flag_spec=
+ whole_archive_flag_spec=
+ # 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 extended regexp 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='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'
+ # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out
+ # platforms (ab)use it in PIC code, but their linkers get confused if
+ # the symbol is explicitly referenced. Since portable code cannot
+ # rely on this symbol name, it's probably fine to never include it in
+ # preloaded symbol tables.
+ # Exclude shared library initialization/finalization symbols.
+ extract_expsyms_cmds=
+
+ case $host_os in
+ cygwin* | mingw* | pw32* | cegcc*)
+ # 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 "$GCC" != yes; then
+ with_gnu_ld=no
+ fi
+ ;;
+ interix*)
+ # we just hope/assume this is gcc and not c89 (= MSVC++)
+ with_gnu_ld=yes
+ ;;
+ openbsd*)
+ with_gnu_ld=no
+ ;;
+ esac
+
+ ld_shlibs=yes
+
+ # On some targets, GNU ld is compatible enough with the native linker
+ # that we're better off using the native interface for both.
+ lt_use_gnu_ld_interface=no
+ if test "$with_gnu_ld" = yes; then
+ case $host_os in
+ aix*)
+ # The AIX port of GNU ld has always aspired to compatibility
+ # with the native linker. However, as the warning in the GNU ld
+ # block says, versions before 2.19.5* couldn't really create working
+ # shared libraries, regardless of the interface used.
+ case `$LD -v 2>&1` in
+ *\ \(GNU\ Binutils\)\ 2.19.5*) ;;
+ *\ \(GNU\ Binutils\)\ 2.[2-9]*) ;;
+ *\ \(GNU\ Binutils\)\ [3-9]*) ;;
+ *)
+ lt_use_gnu_ld_interface=yes
+ ;;
+ esac
+ ;;
+ *)
+ lt_use_gnu_ld_interface=yes
+ ;;
+ esac
+ fi
+
+ if test "$lt_use_gnu_ld_interface" = yes; then
+ # If archive_cmds runs LD, not CC, wlarc should be empty
+ wlarc='${wl}'
+
+ # Set some defaults for GNU ld with shared library support. These
+ # are reset later if shared libraries are not supported. Putting them
+ # here allows them to be overridden if necessary.
+ runpath_var=LD_RUN_PATH
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ export_dynamic_flag_spec='${wl}--export-dynamic'
+ # ancient GNU ld didn't support --whole-archive et. al.
+ if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then
+ whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+ else
+ whole_archive_flag_spec=
+ fi
+ supports_anon_versioning=no
+ case `$LD -v 2>&1` in
+ *GNU\ gold*) supports_anon_versioning=yes ;;
+ *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11
+ *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ...
+ *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ...
+ *\ 2.11.*) ;; # other 2.11 versions
+ *) supports_anon_versioning=yes ;;
+ esac
+
+ # See if GNU ld supports shared libraries.
+ case $host_os in
+ aix[3-9]*)
+ # On AIX/PPC, the GNU linker is very broken
+ if test "$host_cpu" != ia64; then
+ ld_shlibs=no
+ cat <<_LT_EOF 1>&2
+
+*** Warning: the GNU linker, at least up to release 2.19, 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 install binutils
+*** 2.20 or above, or modify your PATH so that a non-GNU linker is found.
+*** You will then need to restart the configuration process.
+
+_LT_EOF
+ fi
+ ;;
+
+ amigaos*)
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds=''
+ ;;
+ m68k)
+ archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+ ;;
+ esac
+ ;;
+
+ beos*)
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ allow_undefined_flag=unsupported
+ # Joseph Beckenbach <jrb3@best.com> says some releases of gcc
+ # support --undefined. This deserves some investigation. FIXME
+ archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+
+ cygwin* | mingw* | pw32* | cegcc*)
+ # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless,
+ # as there is no search path for DLLs.
+ hardcode_libdir_flag_spec='-L$libdir'
+ export_dynamic_flag_spec='${wl}--export-all-symbols'
+ allow_undefined_flag=unsupported
+ always_export_symbols=no
+ enable_shared_with_static_runtimes=yes
+ export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols'
+
+ if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ # If the export-symbols file already is a .def file (1st line
+ # is EXPORTS), use it as is; otherwise, prepend...
+ archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+ cp $export_symbols $output_objdir/$soname.def;
+ else
+ echo EXPORTS > $output_objdir/$soname.def;
+ cat $export_symbols >> $output_objdir/$soname.def;
+ fi~
+ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+
+ haiku*)
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ link_all_deplibs=yes
+ ;;
+
+ interix[3-9]*)
+ hardcode_direct=no
+ hardcode_shlibpath_var=no
+ hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+ export_dynamic_flag_spec='${wl}-E'
+ # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
+ # Instead, shared libraries are loaded at an image base (0x10000000 by
+ # default) and relocated if they conflict, which is a slow very memory
+ # consuming and fragmenting process. To avoid this, we pick a random,
+ # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
+ # time. Moving up from 0x10000000 also allows more sbrk(2) space.
+ archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ archive_expsym_cmds='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ ;;
+
+ gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu)
+ tmp_diet=no
+ if test "$host_os" = linux-dietlibc; then
+ case $cc_basename in
+ diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn)
+ esac
+ fi
+ if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \
+ && test "$tmp_diet" = no
+ then
+ tmp_addflag=
+ tmp_sharedflag='-shared'
+ case $cc_basename,$host_cpu in
+ pgcc*) # Portland Group C compiler
+ whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+ tmp_addflag=' $pic_flag'
+ ;;
+ pgf77* | pgf90* | pgf95* | pgfortran*)
+ # Portland Group f77 and f90 compilers
+ whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+ tmp_addflag=' $pic_flag -Mnomain' ;;
+ ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64
+ tmp_addflag=' -i_dynamic' ;;
+ efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64
+ tmp_addflag=' -i_dynamic -nofor_main' ;;
+ ifc* | ifort*) # Intel Fortran compiler
+ tmp_addflag=' -nofor_main' ;;
+ lf95*) # Lahey Fortran 8.1
+ whole_archive_flag_spec=
+ tmp_sharedflag='--shared' ;;
+ xl[cC]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below)
+ tmp_sharedflag='-qmkshrobj'
+ tmp_addflag= ;;
+ nvcc*) # Cuda Compiler Driver 2.2
+ whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+ compiler_needs_object=yes
+ ;;
+ esac
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ C*) # Sun C 5.9
+ whole_archive_flag_spec='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+ compiler_needs_object=yes
+ tmp_sharedflag='-G' ;;
+ *Sun\ F*) # Sun Fortran 8.3
+ tmp_sharedflag='-G' ;;
+ esac
+ archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+
+ if test "x$supports_anon_versioning" = xyes; then
+ archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~
+ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+ echo "local: *; };" >> $output_objdir/$libname.ver~
+ $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
+ fi
+
+ case $cc_basename in
+ xlf* | bgf* | bgxlf* | mpixlf*)
+ # IBM XL Fortran 10.1 on PPC cannot create shared libs itself
+ whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive'
+ hardcode_libdir_flag_spec=
+ hardcode_libdir_flag_spec_ld='-rpath $libdir'
+ archive_cmds='$LD -shared $libobjs $deplibs $compiler_flags -soname $soname -o $lib'
+ if test "x$supports_anon_versioning" = xyes; then
+ archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~
+ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+ echo "local: *; };" >> $output_objdir/$libname.ver~
+ $LD -shared $libobjs $deplibs $compiler_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib'
+ fi
+ ;;
+ esac
+ else
+ ld_shlibs=no
+ fi
+ ;;
+
+ netbsd*)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
+ wlarc=
+ else
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ fi
+ ;;
+
+ solaris*)
+ if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then
+ ld_shlibs=no
+ cat <<_LT_EOF 1>&2
+
+*** Warning: The releases 2.8.* of the GNU linker cannot reliably
+*** create shared libraries on Solaris systems. Therefore, libtool
+*** is disabling shared libraries support. We urge you to upgrade GNU
+*** binutils to release 2.9.1 or newer. Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+ elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+
+ sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)
+ case `$LD -v 2>&1` in
+ *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*)
+ ld_shlibs=no
+ cat <<_LT_EOF 1>&2
+
+*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not
+*** reliably create shared libraries on SCO systems. Therefore, libtool
+*** is disabling shared libraries support. We urge you to upgrade GNU
+*** binutils to release 2.16.91.0.3 or newer. Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+ ;;
+ *)
+ # For security reasons, it is highly recommended that you always
+ # use absolute paths for naming shared libraries, and exclude the
+ # DT_RUNPATH tag from executables and libraries. But doing so
+ # requires that you compile everything twice, which is a pain.
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ esac
+ ;;
+
+ sunos4*)
+ archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+ wlarc=
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ *)
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ esac
+
+ if test "$ld_shlibs" = no; then
+ runpath_var=
+ hardcode_libdir_flag_spec=
+ export_dynamic_flag_spec=
+ whole_archive_flag_spec=
+ 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 $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname'
+ # Note: this linker hardcodes the directories in LIBPATH if there
+ # are no directories specified by -L.
+ hardcode_minus_L=yes
+ if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then
+ # Neither direct hardcoding nor static linking is supported with a
+ # broken collect2.
+ hardcode_direct=unsupported
+ fi
+ ;;
+
+ aix[4-9]*)
+ if test "$host_cpu" = ia64; then
+ # On IA64, the linker does run time linking by default, so we don't
+ # have to do anything special.
+ aix_use_runtimelinking=no
+ exp_sym_flag='-Bexport'
+ no_entry_flag=""
+ else
+ # If we're using GNU nm, then we don't want the "-C" option.
+ # -C means demangle to AIX nm, but means don't demangle with GNU nm
+ # Also, AIX nm treats weak defined symbols like other global
+ # defined symbols, whereas GNU nm marks them as "W".
+ if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
+ export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+ else
+ export_symbols_cmds='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+ fi
+ aix_use_runtimelinking=no
+
+ # Test if we are trying to use run time linking or normal
+ # AIX style linking. If -brtl is somewhere in LDFLAGS, we
+ # need to do runtime linking.
+ case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*)
+ for ld_flag in $LDFLAGS; do
+ if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
+ aix_use_runtimelinking=yes
+ break
+ fi
+ done
+ ;;
+ esac
+
+ exp_sym_flag='-bexport'
+ no_entry_flag='-bnoentry'
+ fi
+
+ # When large executables or shared objects are built, AIX ld can
+ # have problems creating the table of contents. If linking a library
+ # or program results in "error TOC overflow" add -mminimal-toc to
+ # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not
+ # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+ archive_cmds=''
+ hardcode_direct=yes
+ hardcode_direct_absolute=yes
+ hardcode_libdir_separator=':'
+ link_all_deplibs=yes
+ file_list_spec='${wl}-f,'
+
+ if test "$GCC" = yes; then
+ case $host_os in aix4.[012]|aix4.[012].*)
+ # We only want to do this on AIX 4.2 and lower, the check
+ # below for broken collect2 doesn't work under 4.3+
+ collect2name=`${CC} -print-prog-name=collect2`
+ if test -f "$collect2name" &&
+ strings "$collect2name" | $GREP resolve_lib_name >/dev/null
+ then
+ # We have reworked collect2
+ :
+ else
+ # We have old collect2
+ hardcode_direct=unsupported
+ # It fails to find uninstalled libraries when the uninstalled
+ # path is not listed in the libpath. Setting hardcode_minus_L
+ # to unsupported forces relinking
+ hardcode_minus_L=yes
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_libdir_separator=
+ fi
+ ;;
+ esac
+ shared_flag='-shared'
+ if test "$aix_use_runtimelinking" = yes; then
+ shared_flag="$shared_flag "'${wl}-G'
+ fi
+ else
+ # not using gcc
+ if test "$host_cpu" = ia64; then
+ # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+ # chokes on -Wl,-G. The following line is correct:
+ shared_flag='-G'
+ else
+ if test "$aix_use_runtimelinking" = yes; then
+ shared_flag='${wl}-G'
+ else
+ shared_flag='${wl}-bM:SRE'
+ fi
+ fi
+ fi
+
+ export_dynamic_flag_spec='${wl}-bexpall'
+ # It seems that -bexpall does not export symbols beginning with
+ # underscore (_), so it is better to generate a list of symbols to export.
+ always_export_symbols=yes
+ if test "$aix_use_runtimelinking" = yes; then
+ # Warning - without using the other runtime loading flags (-brtl),
+ # -berok will link without error, but may produce a broken library.
+ allow_undefined_flag='-berok'
+ # Determine the default libpath from the value encoded in an
+ # empty executable.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+
+lt_aix_libpath_sed='
+ /Import File Strings/,/^$/ {
+ /^0/ {
+ s/^0 *\(.*\)$/\1/
+ p
+ }
+ }'
+aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+# Check for a 64-bit object if we didn't find anything.
+if test -z "$aix_libpath"; then
+ aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+fi
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
+
+ hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
+ archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+ else
+ if test "$host_cpu" = ia64; then
+ hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib'
+ allow_undefined_flag="-z nodefs"
+ archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
+ else
+ # Determine the default libpath from the value encoded in an
+ # empty executable.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+
+lt_aix_libpath_sed='
+ /Import File Strings/,/^$/ {
+ /^0/ {
+ s/^0 *\(.*\)$/\1/
+ p
+ }
+ }'
+aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+# Check for a 64-bit object if we didn't find anything.
+if test -z "$aix_libpath"; then
+ aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+fi
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
+
+ hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
+ # Warning - without using the other run time loading flags,
+ # -berok will link without error, but may produce a broken library.
+ no_undefined_flag=' ${wl}-bernotok'
+ allow_undefined_flag=' ${wl}-berok'
+ if test "$with_gnu_ld" = yes; then
+ # We only use this code for GNU lds that support --whole-archive.
+ whole_archive_flag_spec='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
+ else
+ # Exported symbols can be pulled into shared objects from archives
+ whole_archive_flag_spec='$convenience'
+ fi
+ archive_cmds_need_lc=yes
+ # This is similar to how AIX traditionally builds its shared libraries.
+ archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
+ fi
+ fi
+ ;;
+
+ amigaos*)
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds=''
+ ;;
+ m68k)
+ archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+ ;;
+ esac
+ ;;
+
+ bsdi[45]*)
+ export_dynamic_flag_spec=-rdynamic
+ ;;
+
+ cygwin* | mingw* | pw32* | cegcc*)
+ # 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
+ # Tell ltmain to make .dll files, not .so files.
+ shrext_cmds=".dll"
+ # FIXME: Setting linknames here is a bad hack.
+ archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''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$old_deplibs'
+ fix_srcfile_path='`cygpath -w "$srcfile"`'
+ enable_shared_with_static_runtimes=yes
+ ;;
+
+ darwin* | rhapsody*)
+
+
+ archive_cmds_need_lc=no
+ hardcode_direct=no
+ hardcode_automatic=yes
+ hardcode_shlibpath_var=unsupported
+ if test "$lt_cv_ld_force_load" = "yes"; then
+ whole_archive_flag_spec='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`'
+ else
+ whole_archive_flag_spec=''
+ fi
+ link_all_deplibs=yes
+ allow_undefined_flag="$_lt_dar_allow_undefined"
+ case $cc_basename in
+ ifort*) _lt_dar_can_shared=yes ;;
+ *) _lt_dar_can_shared=$GCC ;;
+ esac
+ if test "$_lt_dar_can_shared" = "yes"; then
+ output_verbose_link_cmd=func_echo_all
+ archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}"
+ module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}"
+ archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}"
+ module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}"
+
+ else
+ ld_shlibs=no
+ fi
+
+ ;;
+
+ dgux*)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_shlibpath_var=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 $linker_flags /usr/lib/c++rt0.o'
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ # Unfortunately, older versions of FreeBSD 2 do not have this feature.
+ freebsd2.*)
+ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_direct=yes
+ hardcode_minus_L=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
+ freebsd* | dragonfly*)
+ archive_cmds='$CC -shared -o $lib $libobjs $deplibs $compiler_flags'
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ hpux9*)
+ if test "$GCC" = yes; then
+ archive_cmds='$RM $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+ else
+ archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+ fi
+ hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+ hardcode_libdir_separator=:
+ hardcode_direct=yes
+
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ hardcode_minus_L=yes
+ export_dynamic_flag_spec='${wl}-E'
+ ;;
+
+ hpux10*)
+ if test "$GCC" = yes && test "$with_gnu_ld" = no; then
+ archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+ fi
+ if test "$with_gnu_ld" = no; then
+ hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+ hardcode_libdir_flag_spec_ld='+b $libdir'
+ hardcode_libdir_separator=:
+ hardcode_direct=yes
+ hardcode_direct_absolute=yes
+ export_dynamic_flag_spec='${wl}-E'
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ hardcode_minus_L=yes
+ fi
+ ;;
+
+ hpux11*)
+ if test "$GCC" = yes && test "$with_gnu_ld" = no; then
+ case $host_cpu in
+ hppa*64*)
+ archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ ia64*)
+ archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ *)
+ archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ esac
+ else
+ case $host_cpu in
+ hppa*64*)
+ archive_cmds='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ ia64*)
+ archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ *)
+
+ # Older versions of the 11.00 compiler do not understand -b yet
+ # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC understands -b" >&5
+$as_echo_n "checking if $CC understands -b... " >&6; }
+if test "${lt_cv_prog_compiler__b+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler__b=no
+ save_LDFLAGS="$LDFLAGS"
+ LDFLAGS="$LDFLAGS -b"
+ echo "$lt_simple_link_test_code" > conftest.$ac_ext
+ if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
+ # The linker can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ if test -s conftest.err; then
+ # Append any errors to the config.log.
+ cat conftest.err 1>&5
+ $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if diff conftest.exp conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler__b=yes
+ fi
+ else
+ lt_cv_prog_compiler__b=yes
+ fi
+ fi
+ $RM -r conftest*
+ LDFLAGS="$save_LDFLAGS"
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5
+$as_echo "$lt_cv_prog_compiler__b" >&6; }
+
+if test x"$lt_cv_prog_compiler__b" = xyes; then
+ archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+else
+ archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+fi
+
+ ;;
+ esac
+ fi
+ if test "$with_gnu_ld" = no; then
+ hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+ hardcode_libdir_separator=:
+
+ case $host_cpu in
+ hppa*64*|ia64*)
+ hardcode_direct=no
+ hardcode_shlibpath_var=no
+ ;;
+ *)
+ hardcode_direct=yes
+ hardcode_direct_absolute=yes
+ export_dynamic_flag_spec='${wl}-E'
+
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ hardcode_minus_L=yes
+ ;;
+ esac
+ fi
+ ;;
+
+ irix5* | irix6* | nonstopux*)
+ if test "$GCC" = yes; then
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ # Try to use the -exported_symbol ld option, if it does not
+ # work, assume that -exports_file does not work either and
+ # implicitly export all symbols.
+ save_LDFLAGS="$LDFLAGS"
+ LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+int foo(void) {}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib'
+
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ LDFLAGS="$save_LDFLAGS"
+ else
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+ archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib'
+ fi
+ archive_cmds_need_lc='no'
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ hardcode_libdir_separator=:
+ inherit_rpath=yes
+ link_all_deplibs=yes
+ ;;
+
+ netbsd*)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out
+ else
+ archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF
+ fi
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ newsos6)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_direct=yes
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ hardcode_libdir_separator=:
+ hardcode_shlibpath_var=no
+ ;;
+
+ *nto* | *qnx*)
+ ;;
+
+ openbsd*)
+ if test -f /usr/libexec/ld.so; then
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ hardcode_direct_absolute=yes
+ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+ archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols'
+ hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+ export_dynamic_flag_spec='${wl}-E'
+ else
+ case $host_os in
+ openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*)
+ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_libdir_flag_spec='-R$libdir'
+ ;;
+ *)
+ archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+ hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+ ;;
+ esac
+ fi
+ else
+ ld_shlibs=no
+ fi
+ ;;
+
+ os2*)
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+ allow_undefined_flag=unsupported
+ archive_cmds='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def'
+ old_archive_from_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def'
+ ;;
+
+ osf3*)
+ if test "$GCC" = yes; then
+ allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*'
+ archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ else
+ allow_undefined_flag=' -expect_unresolved \*'
+ archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+ fi
+ archive_cmds_need_lc='no'
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ hardcode_libdir_separator=:
+ ;;
+
+ osf4* | osf5*) # as osf3* with the addition of -msym flag
+ if test "$GCC" = yes; then
+ allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*'
+ archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ else
+ allow_undefined_flag=' -expect_unresolved \*'
+ archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+ archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~
+ $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp'
+
+ # Both c and cxx compiler support -rpath directly
+ hardcode_libdir_flag_spec='-rpath $libdir'
+ fi
+ archive_cmds_need_lc='no'
+ hardcode_libdir_separator=:
+ ;;
+
+ solaris*)
+ no_undefined_flag=' -z defs'
+ if test "$GCC" = yes; then
+ wlarc='${wl}'
+ archive_cmds='$CC -shared ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -shared ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+ else
+ case `$CC -V 2>&1` in
+ *"Compilers 5.0"*)
+ wlarc=''
+ archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ 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 $linker_flags~$RM $lib.exp'
+ ;;
+ *)
+ wlarc='${wl}'
+ archive_cmds='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+ ;;
+ esac
+ fi
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_shlibpath_var=no
+ case $host_os in
+ solaris2.[0-5] | solaris2.[0-5].*) ;;
+ *)
+ # The compiler driver will combine and reorder linker options,
+ # but understands `-z linker_flag'. GCC discards it without `$wl',
+ # but is careful enough not to reorder.
+ # Supported since Solaris 2.6 (maybe 2.5.1?)
+ if test "$GCC" = yes; then
+ whole_archive_flag_spec='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'
+ else
+ whole_archive_flag_spec='-z allextract$convenience -z defaultextract'
+ fi
+ ;;
+ esac
+ link_all_deplibs=yes
+ ;;
+
+ sunos4*)
+ if test "x$host_vendor" = xsequent; then
+ # Use $CC to link under sequent, because it throws in some extra .o
+ # files that make .init and .fini sections work.
+ archive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags'
+ fi
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_direct=yes
+ hardcode_minus_L=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ sysv4)
+ case $host_vendor in
+ sni)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_direct=yes # is this really true???
+ ;;
+ siemens)
+ ## LD is ld it makes a PLAMLIB
+ ## CC just makes a GrossModule.
+ archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags'
+ reload_cmds='$CC -r -o $output$reload_objs'
+ hardcode_direct=no
+ ;;
+ motorola)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_direct=no #Motorola manual says yes, but my tests say they lie
+ ;;
+ esac
+ runpath_var='LD_RUN_PATH'
+ hardcode_shlibpath_var=no
+ ;;
+
+ sysv4.3*)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_shlibpath_var=no
+ export_dynamic_flag_spec='-Bexport'
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_shlibpath_var=no
+ runpath_var=LD_RUN_PATH
+ hardcode_runpath_var=yes
+ ld_shlibs=yes
+ fi
+ ;;
+
+ sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*)
+ no_undefined_flag='${wl}-z,text'
+ archive_cmds_need_lc=no
+ hardcode_shlibpath_var=no
+ runpath_var='LD_RUN_PATH'
+
+ if test "$GCC" = yes; then
+ archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ fi
+ ;;
+
+ sysv5* | sco3.2v5* | sco5v6*)
+ # Note: We can NOT use -z defs as we might desire, because we do not
+ # link with -lc, and that would cause any symbols used from libc to
+ # always be unresolved, which means just about no library would
+ # ever link correctly. If we're not using GNU ld we use -z text
+ # though, which does catch some bad symbols but isn't as heavy-handed
+ # as -z defs.
+ no_undefined_flag='${wl}-z,text'
+ allow_undefined_flag='${wl}-z,nodefs'
+ archive_cmds_need_lc=no
+ hardcode_shlibpath_var=no
+ hardcode_libdir_flag_spec='${wl}-R,$libdir'
+ hardcode_libdir_separator=':'
+ link_all_deplibs=yes
+ export_dynamic_flag_spec='${wl}-Bexport'
+ runpath_var='LD_RUN_PATH'
+
+ if test "$GCC" = yes; then
+ archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ fi
+ ;;
+
+ uts4*)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_shlibpath_var=no
+ ;;
+
+ *)
+ ld_shlibs=no
+ ;;
+ esac
+
+ if test x$host_vendor = xsni; then
+ case $host in
+ sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+ export_dynamic_flag_spec='${wl}-Blargedynsym'
+ ;;
+ esac
+ fi
+ fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5
+$as_echo "$ld_shlibs" >&6; }
+test "$ld_shlibs" = no && can_build_shared=no
+
+with_gnu_ld=$with_gnu_ld
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+#
+# Do we need to explicitly link libc?
+#
+case "x$archive_cmds_need_lc" in
+x|xyes)
+ # Assume -lc should be added
+ archive_cmds_need_lc=yes
+
+ if test "$enable_shared" = yes && test "$GCC" = yes; then
+ case $archive_cmds in
+ *'~'*)
+ # FIXME: we may have to deal with multi-command sequences.
+ ;;
+ '$CC '*)
+ # Test whether the compiler implicitly links with -lc since on some
+ # systems, -lgcc has to come before -lc. If gcc already passes -lc
+ # to ld, don't add -lc before -lgcc.
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5
+$as_echo_n "checking whether -lc should be explicitly linked in... " >&6; }
+if test "${lt_cv_archive_cmds_need_lc+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ $RM conftest*
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } 2>conftest.err; then
+ soname=conftest
+ lib=conftest
+ libobjs=conftest.$ac_objext
+ deplibs=
+ wl=$lt_prog_compiler_wl
+ pic_flag=$lt_prog_compiler_pic
+ compiler_flags=-v
+ linker_flags=-v
+ verstring=
+ output_objdir=.
+ libname=conftest
+ lt_save_allow_undefined_flag=$allow_undefined_flag
+ allow_undefined_flag=
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5
+ (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ then
+ lt_cv_archive_cmds_need_lc=no
+ else
+ lt_cv_archive_cmds_need_lc=yes
+ fi
+ allow_undefined_flag=$lt_save_allow_undefined_flag
+ else
+ cat conftest.err 1>&5
+ fi
+ $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc" >&5
+$as_echo "$lt_cv_archive_cmds_need_lc" >&6; }
+ archive_cmds_need_lc=$lt_cv_archive_cmds_need_lc
+ ;;
+ esac
+ fi
+ ;;
+esac
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5
+$as_echo_n "checking dynamic linker characteristics... " >&6; }
+
+if test "$GCC" = yes; then
+ case $host_os in
+ darwin*) lt_awk_arg="/^libraries:/,/LR/" ;;
+ *) lt_awk_arg="/^libraries:/" ;;
+ esac
+ case $host_os in
+ mingw* | cegcc*) lt_sed_strip_eq="s,=\([A-Za-z]:\),\1,g" ;;
+ *) lt_sed_strip_eq="s,=/,/,g" ;;
+ esac
+ lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq`
+ case $lt_search_path_spec in
+ *\;*)
+ # if the path contains ";" then we assume it to be the separator
+ # otherwise default to the standard path separator (i.e. ":") - it is
+ # assumed that no part of a normal pathname contains ";" but that should
+ # okay in the real world where ";" in dirpaths is itself problematic.
+ lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'`
+ ;;
+ *)
+ lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"`
+ ;;
+ esac
+ # Ok, now we have the path, separated by spaces, we can step through it
+ # and add multilib dir if necessary.
+ lt_tmp_lt_search_path_spec=
+ lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null`
+ for lt_sys_path in $lt_search_path_spec; do
+ if test -d "$lt_sys_path/$lt_multi_os_dir"; then
+ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir"
+ else
+ test -d "$lt_sys_path" && \
+ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path"
+ fi
+ done
+ lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk '
+BEGIN {RS=" "; FS="/|\n";} {
+ lt_foo="";
+ lt_count=0;
+ for (lt_i = NF; lt_i > 0; lt_i--) {
+ if ($lt_i != "" && $lt_i != ".") {
+ if ($lt_i == "..") {
+ lt_count++;
+ } else {
+ if (lt_count == 0) {
+ lt_foo="/" $lt_i lt_foo;
+ } else {
+ lt_count--;
+ }
+ }
+ }
+ }
+ if (lt_foo != "") { lt_freq[lt_foo]++; }
+ if (lt_freq[lt_foo] == 1) { print lt_foo; }
+}'`
+ # AWK program above erroneously prepends '/' to C:/dos/paths
+ # for these hosts.
+ case $host_os in
+ mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\
+ $SED 's,/\([A-Za-z]:\),\1,g'` ;;
+ esac
+ sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP`
+else
+ sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
+fi
+library_names_spec=
+libname_spec='lib$name'
+soname_spec=
+shrext_cmds=".so"
+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"
+need_lib_prefix=unknown
+hardcode_into_libs=no
+
+# when you set need_version to no, make sure it does not cause -set_version
+# flags to be left without arguments
+need_version=unknown
+
+case $host_os in
+aix3*)
+ version_type=linux
+ library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a'
+ shlibpath_var=LIBPATH
+
+ # AIX 3 has no versioning support, so we append a major version to the name.
+ soname_spec='${libname}${release}${shared_ext}$major'
+ ;;
+
+aix[4-9]*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ hardcode_into_libs=yes
+ if test "$host_cpu" = ia64; then
+ # AIX 5 supports IA64
+ library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}'
+ shlibpath_var=LD_LIBRARY_PATH
+ else
+ # With GCC up to 2.95.x, collect2 would create an import file
+ # for dependence libraries. The import file would start with
+ # the line `#! .'. This would cause the generated library to
+ # depend on `.', always an invalid library. This was fixed in
+ # development snapshots of GCC prior to 3.0.
+ case $host_os in
+ aix4 | aix4.[01] | aix4.[01].*)
+ if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
+ echo ' yes '
+ echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then
+ :
+ else
+ can_build_shared=no
+ fi
+ ;;
+ esac
+ # AIX (on Power*) 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.
+ if test "$aix_use_runtimelinking" = yes; then
+ # If using run time linking (on AIX 4.2 or later) use lib<name>.so
+ # instead of lib<name>.a to let people know that these are not
+ # typical AIX shared libraries.
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ else
+ # We preserve .a as extension for shared libraries through AIX4.2
+ # and later when we are not doing run time linking.
+ library_names_spec='${libname}${release}.a $libname.a'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ fi
+ shlibpath_var=LIBPATH
+ fi
+ ;;
+
+amigaos*)
+ case $host_cpu in
+ powerpc)
+ # Since July 2007 AmigaOS4 officially supports .so libraries.
+ # When compiling the executable, add -use-dynld -Lsobjs: to the compileline.
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ ;;
+ m68k)
+ 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=`func_echo_all "$lib" | $SED '\''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'
+ ;;
+ esac
+ ;;
+
+beos*)
+ library_names_spec='${libname}${shared_ext}'
+ dynamic_linker="$host_os ld.so"
+ shlibpath_var=LIBRARY_PATH
+ ;;
+
+bsdi[45]*)
+ version_type=linux
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ 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* | pw32* | cegcc*)
+ version_type=windows
+ shrext_cmds=".dll"
+ need_version=no
+ need_lib_prefix=no
+
+ case $GCC,$host_os in
+ yes,cygwin* | yes,mingw* | yes,pw32* | yes,cegcc*)
+ library_names_spec='$libname.dll.a'
+ # DLL is installed to $(libdir)/../bin by postinstall_cmds
+ postinstall_cmds='base_file=`basename \${file}`~
+ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~
+ dldir=$destdir/`dirname \$dlpath`~
+ test -d \$dldir || mkdir -p \$dldir~
+ $install_prog $dir/$dlname \$dldir/$dlname~
+ chmod a+x \$dldir/$dlname~
+ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then
+ eval '\''$striplib \$dldir/$dlname'\'' || exit \$?;
+ fi'
+ postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+ dlpath=$dir/\$dldll~
+ $RM \$dlpath'
+ shlibpath_overrides_runpath=yes
+
+ case $host_os in
+ cygwin*)
+ # Cygwin DLLs use 'cyg' prefix rather than 'lib'
+ soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+
+ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"
+ ;;
+ mingw* | cegcc*)
+ # MinGW DLLs use traditional 'lib' prefix
+ soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+ ;;
+ pw32*)
+ # pw32 DLLs use 'pw' prefix rather than 'lib'
+ library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+ ;;
+ esac
+ ;;
+
+ *)
+ library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib'
+ ;;
+ esac
+ dynamic_linker='Win32 ld.exe'
+ # FIXME: first we should search . and the directory the executable is in
+ shlibpath_var=PATH
+ ;;
+
+darwin* | rhapsody*)
+ dynamic_linker="$host_os dyld"
+ version_type=darwin
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext'
+ soname_spec='${libname}${release}${major}$shared_ext'
+ shlibpath_overrides_runpath=yes
+ shlibpath_var=DYLD_LIBRARY_PATH
+ shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'
+
+ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"
+ sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'
+ ;;
+
+dgux*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+freebsd* | dragonfly*)
+ # DragonFly does not have aout. When/if they implement a new
+ # versioning mechanism, adjust this.
+ if test -x /usr/bin/objformat; then
+ objformat=`/usr/bin/objformat`
+ else
+ case $host_os in
+ freebsd[23].*) objformat=aout ;;
+ *) objformat=elf ;;
+ esac
+ fi
+ version_type=freebsd-$objformat
+ case $version_type in
+ freebsd-elf*)
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+ need_version=no
+ need_lib_prefix=no
+ ;;
+ freebsd-*)
+ library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix'
+ need_version=yes
+ ;;
+ esac
+ shlibpath_var=LD_LIBRARY_PATH
+ case $host_os in
+ freebsd2.*)
+ shlibpath_overrides_runpath=yes
+ ;;
+ freebsd3.[01]* | freebsdelf3.[01]*)
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+ freebsd3.[2-9]* | freebsdelf3.[2-9]* | \
+ freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1)
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+ *) # from 4.6 on, and DragonFly
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+ esac
+ ;;
+
+gnu*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ hardcode_into_libs=yes
+ ;;
+
+haiku*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ dynamic_linker="$host_os runtime_loader"
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/beos/system/lib'
+ hardcode_into_libs=yes
+ ;;
+
+hpux9* | hpux10* | hpux11*)
+ # Give a soname corresponding to the major version so that dld.sl refuses to
+ # link against other versions.
+ version_type=sunos
+ need_lib_prefix=no
+ need_version=no
+ case $host_cpu in
+ ia64*)
+ shrext_cmds='.so'
+ hardcode_into_libs=yes
+ dynamic_linker="$host_os dld.so"
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ if test "X$HPUX_IA64_MODE" = X32; then
+ sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"
+ else
+ sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"
+ fi
+ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+ ;;
+ hppa*64*)
+ shrext_cmds='.sl'
+ hardcode_into_libs=yes
+ dynamic_linker="$host_os dld.sl"
+ shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
+ shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
+ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+ ;;
+ *)
+ shrext_cmds='.sl'
+ dynamic_linker="$host_os dld.sl"
+ shlibpath_var=SHLIB_PATH
+ shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ ;;
+ esac
+ # HP-UX runs *really* slowly unless shared libraries are mode 555, ...
+ postinstall_cmds='chmod 555 $lib'
+ # or fails outright, so override atomically:
+ install_override_mode=555
+ ;;
+
+interix[3-9]*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+
+irix5* | irix6* | nonstopux*)
+ case $host_os in
+ nonstopux*) version_type=nonstopux ;;
+ *)
+ if test "$lt_cv_prog_gnu_ld" = yes; then
+ version_type=linux
+ else
+ version_type=irix
+ fi ;;
+ esac
+ need_lib_prefix=no
+ need_version=no
+ soname_spec='${libname}${release}${shared_ext}$major'
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}'
+ case $host_os in
+ irix5* | nonstopux*)
+ libsuff= shlibsuff=
+ ;;
+ *)
+ case $LD in # libtool.m4 will add one of these switches to LD
+ *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ")
+ libsuff= shlibsuff= libmagic=32-bit;;
+ *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ")
+ libsuff=32 shlibsuff=N32 libmagic=N32;;
+ *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ")
+ libsuff=64 shlibsuff=64 libmagic=64-bit;;
+ *) libsuff= shlibsuff= libmagic=never-match;;
+ esac
+ ;;
+ esac
+ shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
+ shlibpath_overrides_runpath=no
+ sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}"
+ sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}"
+ hardcode_into_libs=yes
+ ;;
+
+# No shared lib support for Linux oldld, aout, or coff.
+linux*oldld* | linux*aout* | linux*coff*)
+ dynamic_linker=no
+ ;;
+
+# This must be Linux ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+
+ # Some binutils ld are patched to set DT_RUNPATH
+ if test "${lt_cv_shlibpath_overrides_runpath+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_shlibpath_overrides_runpath=no
+ save_LDFLAGS=$LDFLAGS
+ save_libdir=$libdir
+ eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \
+ LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\""
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then :
+ lt_cv_shlibpath_overrides_runpath=yes
+fi
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ LDFLAGS=$save_LDFLAGS
+ libdir=$save_libdir
+
+fi
+
+ shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath
+
+ # This implies no fast_install, which is unacceptable.
+ # Some rework will be needed to allow for fast_install
+ # before this can be enabled.
+ hardcode_into_libs=yes
+
+ # Append ld.so.conf contents to the search path
+ if test -f /etc/ld.so.conf; then
+ lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '`
+ sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
+ fi
+
+ # We used to test for /lib/ld.so.1 and disable shared libraries on
+ # powerpc, because MkLinux only supported shared libraries with the
+ # GNU dynamic linker. Since this was broken with cross compilers,
+ # most powerpc-linux boxes support dynamic linking these days and
+ # people can always --disable-shared, the test was removed, and we
+ # assume the GNU/Linux dynamic linker is in use.
+ dynamic_linker='GNU/Linux ld.so'
+ ;;
+
+netbsd*)
+ version_type=sunos
+ need_lib_prefix=no
+ need_version=no
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+ dynamic_linker='NetBSD (a.out) ld.so'
+ else
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ dynamic_linker='NetBSD ld.elf_so'
+ fi
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+
+newsos6)
+ version_type=linux
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ ;;
+
+*nto* | *qnx*)
+ version_type=qnx
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ dynamic_linker='ldqnx.so'
+ ;;
+
+openbsd*)
+ version_type=sunos
+ sys_lib_dlsearch_path_spec="/usr/lib"
+ need_lib_prefix=no
+ # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs.
+ case $host_os in
+ openbsd3.3 | openbsd3.3.*) need_version=yes ;;
+ *) need_version=no ;;
+ esac
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+ case $host_os in
+ openbsd2.[89] | openbsd2.[89].*)
+ shlibpath_overrides_runpath=no
+ ;;
+ *)
+ shlibpath_overrides_runpath=yes
+ ;;
+ esac
+ else
+ shlibpath_overrides_runpath=yes
+ fi
+ ;;
+
+os2*)
+ libname_spec='$name'
+ shrext_cmds=".dll"
+ need_lib_prefix=no
+ library_names_spec='$libname${shared_ext} $libname.a'
+ dynamic_linker='OS/2 ld.exe'
+ shlibpath_var=LIBPATH
+ ;;
+
+osf3* | osf4* | osf5*)
+ version_type=osf
+ need_lib_prefix=no
+ need_version=no
+ soname_spec='${libname}${release}${shared_ext}$major'
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ shlibpath_var=LD_LIBRARY_PATH
+ 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"
+ ;;
+
+rdos*)
+ dynamic_linker=no
+ ;;
+
+solaris*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ # ldd complains unless libraries are executable
+ postinstall_cmds='chmod +x $lib'
+ ;;
+
+sunos4*)
+ version_type=sunos
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$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 | sysv4.3*)
+ version_type=linux
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ case $host_vendor in
+ sni)
+ shlibpath_overrides_runpath=no
+ need_lib_prefix=no
+ runpath_var=LD_RUN_PATH
+ ;;
+ siemens)
+ need_lib_prefix=no
+ ;;
+ motorola)
+ need_lib_prefix=no
+ need_version=no
+ shlibpath_overrides_runpath=no
+ sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
+ ;;
+ esac
+ ;;
+
+sysv4*MP*)
+ if test -d /usr/nec ;then
+ version_type=linux
+ library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}'
+ soname_spec='$libname${shared_ext}.$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ fi
+ ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+ version_type=freebsd-elf
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ if test "$with_gnu_ld" = yes; then
+ sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'
+ else
+ sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'
+ case $host_os in
+ sco3.2v5*)
+ sys_lib_search_path_spec="$sys_lib_search_path_spec /lib"
+ ;;
+ esac
+ fi
+ sys_lib_dlsearch_path_spec='/usr/lib'
+ ;;
+
+tpf*)
+ # TPF is a cross-target only. Preferred cross-host = GNU/Linux.
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+
+uts4*)
+ version_type=linux
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+*)
+ dynamic_linker=no
+ ;;
+esac
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5
+$as_echo "$dynamic_linker" >&6; }
+test "$dynamic_linker" = no && can_build_shared=no
+
+variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
+if test "$GCC" = yes; then
+ variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
+fi
+
+if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then
+ sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec"
+fi
+if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then
+ sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec"
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5
+$as_echo_n "checking how to hardcode library paths into programs... " >&6; }
+hardcode_action=
+if test -n "$hardcode_libdir_flag_spec" ||
+ test -n "$runpath_var" ||
+ test "X$hardcode_automatic" = "Xyes" ; then
+
+ # We can hardcode non-existent directories.
+ if test "$hardcode_direct" != no &&
+ # If the only mechanism to avoid hardcoding is shlibpath_var, we
+ # have to relink, otherwise we might link with an installed library
+ # when we should be linking with a yet-to-be-installed one
+ ## test "$_LT_TAGVAR(hardcode_shlibpath_var, )" != no &&
+ test "$hardcode_minus_L" != 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
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5
+$as_echo "$hardcode_action" >&6; }
+
+if test "$hardcode_action" = relink ||
+ test "$inherit_rpath" = yes; 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
+
+
+
+
+
+
+ if test "x$enable_dlopen" != xyes; then
+ enable_dlopen=unknown
+ enable_dlopen_self=unknown
+ enable_dlopen_self_static=unknown
+else
+ lt_cv_dlopen=no
+ lt_cv_dlopen_libs=
+
+ case $host_os in
+ beos*)
+ lt_cv_dlopen="load_add_on"
+ lt_cv_dlopen_libs=
+ lt_cv_dlopen_self=yes
+ ;;
+
+ mingw* | pw32* | cegcc*)
+ lt_cv_dlopen="LoadLibrary"
+ lt_cv_dlopen_libs=
+ ;;
+
+ cygwin*)
+ lt_cv_dlopen="dlopen"
+ lt_cv_dlopen_libs=
+ ;;
+
+ darwin*)
+ # if libdl is installed we need to link against it
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5
+$as_echo_n "checking for dlopen in -ldl... " >&6; }
+if test "${ac_cv_lib_dl_dlopen+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldl $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dlopen ();
+int
+main ()
+{
+return dlopen ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_dl_dlopen=yes
+else
+ ac_cv_lib_dl_dlopen=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5
+$as_echo "$ac_cv_lib_dl_dlopen" >&6; }
+if test "x$ac_cv_lib_dl_dlopen" = x""yes; then :
+ lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"
+else
+
+ lt_cv_dlopen="dyld"
+ lt_cv_dlopen_libs=
+ lt_cv_dlopen_self=yes
+
+fi
+
+ ;;
+
+ *)
+ ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load"
+if test "x$ac_cv_func_shl_load" = x""yes; then :
+ lt_cv_dlopen="shl_load"
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5
+$as_echo_n "checking for shl_load in -ldld... " >&6; }
+if test "${ac_cv_lib_dld_shl_load+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldld $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char shl_load ();
+int
+main ()
+{
+return shl_load ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_dld_shl_load=yes
+else
+ ac_cv_lib_dld_shl_load=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5
+$as_echo "$ac_cv_lib_dld_shl_load" >&6; }
+if test "x$ac_cv_lib_dld_shl_load" = x""yes; then :
+ lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"
+else
+ ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen"
+if test "x$ac_cv_func_dlopen" = x""yes; then :
+ lt_cv_dlopen="dlopen"
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5
+$as_echo_n "checking for dlopen in -ldl... " >&6; }
+if test "${ac_cv_lib_dl_dlopen+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldl $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dlopen ();
+int
+main ()
+{
+return dlopen ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_dl_dlopen=yes
+else
+ ac_cv_lib_dl_dlopen=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5
+$as_echo "$ac_cv_lib_dl_dlopen" >&6; }
+if test "x$ac_cv_lib_dl_dlopen" = x""yes; then :
+ lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5
+$as_echo_n "checking for dlopen in -lsvld... " >&6; }
+if test "${ac_cv_lib_svld_dlopen+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsvld $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dlopen ();
+int
+main ()
+{
+return dlopen ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_svld_dlopen=yes
+else
+ ac_cv_lib_svld_dlopen=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5
+$as_echo "$ac_cv_lib_svld_dlopen" >&6; }
+if test "x$ac_cv_lib_svld_dlopen" = x""yes; then :
+ lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5
+$as_echo_n "checking for dld_link in -ldld... " >&6; }
+if test "${ac_cv_lib_dld_dld_link+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldld $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dld_link ();
+int
+main ()
+{
+return dld_link ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_dld_dld_link=yes
+else
+ ac_cv_lib_dld_dld_link=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5
+$as_echo "$ac_cv_lib_dld_dld_link" >&6; }
+if test "x$ac_cv_lib_dld_dld_link" = x""yes; then :
+ lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+ ;;
+ esac
+
+ if test "x$lt_cv_dlopen" != xno; then
+ enable_dlopen=yes
+ else
+ enable_dlopen=no
+ fi
+
+ case $lt_cv_dlopen in
+ dlopen)
+ save_CPPFLAGS="$CPPFLAGS"
+ test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
+
+ save_LDFLAGS="$LDFLAGS"
+ wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
+
+ save_LIBS="$LIBS"
+ LIBS="$lt_cv_dlopen_libs $LIBS"
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5
+$as_echo_n "checking whether a program can dlopen itself... " >&6; }
+if test "${lt_cv_dlopen_self+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test "$cross_compiling" = yes; then :
+ lt_cv_dlopen_self=cross
+else
+ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+ lt_status=$lt_dlunknown
+ cat > conftest.$ac_ext <<_LT_EOF
+#line 11424 "configure"
+#include "confdefs.h"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+# define LT_DLGLOBAL RTLD_GLOBAL
+#else
+# ifdef DL_GLOBAL
+# define LT_DLGLOBAL DL_GLOBAL
+# else
+# define LT_DLGLOBAL 0
+# endif
+#endif
+
+/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
+ find out it does not work in some platform. */
+#ifndef LT_DLLAZY_OR_NOW
+# ifdef RTLD_LAZY
+# define LT_DLLAZY_OR_NOW RTLD_LAZY
+# else
+# ifdef DL_LAZY
+# define LT_DLLAZY_OR_NOW DL_LAZY
+# else
+# ifdef RTLD_NOW
+# define LT_DLLAZY_OR_NOW RTLD_NOW
+# else
+# ifdef DL_NOW
+# define LT_DLLAZY_OR_NOW DL_NOW
+# else
+# define LT_DLLAZY_OR_NOW 0
+# endif
+# endif
+# endif
+# endif
+#endif
+
+/* When -fvisbility=hidden is used, assume the code has been annotated
+ correspondingly for the symbols needed. */
+#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
+void fnord () __attribute__((visibility("default")));
+#endif
+
+void fnord () { int i=42; }
+int main ()
+{
+ void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+ int status = $lt_dlunknown;
+
+ if (self)
+ {
+ if (dlsym (self,"fnord")) status = $lt_dlno_uscore;
+ else
+ {
+ if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
+ else puts (dlerror ());
+ }
+ /* dlclose (self); */
+ }
+ else
+ puts (dlerror ());
+
+ return status;
+}
+_LT_EOF
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then
+ (./conftest; exit; ) >&5 2>/dev/null
+ lt_status=$?
+ case x$lt_status in
+ x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;;
+ x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;;
+ x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;;
+ esac
+ else :
+ # compilation failed
+ lt_cv_dlopen_self=no
+ fi
+fi
+rm -fr conftest*
+
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5
+$as_echo "$lt_cv_dlopen_self" >&6; }
+
+ if test "x$lt_cv_dlopen_self" = xyes; then
+ wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5
+$as_echo_n "checking whether a statically linked program can dlopen itself... " >&6; }
+if test "${lt_cv_dlopen_self_static+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test "$cross_compiling" = yes; then :
+ lt_cv_dlopen_self_static=cross
+else
+ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+ lt_status=$lt_dlunknown
+ cat > conftest.$ac_ext <<_LT_EOF
+#line 11530 "configure"
+#include "confdefs.h"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+# define LT_DLGLOBAL RTLD_GLOBAL
+#else
+# ifdef DL_GLOBAL
+# define LT_DLGLOBAL DL_GLOBAL
+# else
+# define LT_DLGLOBAL 0
+# endif
+#endif
+
+/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
+ find out it does not work in some platform. */
+#ifndef LT_DLLAZY_OR_NOW
+# ifdef RTLD_LAZY
+# define LT_DLLAZY_OR_NOW RTLD_LAZY
+# else
+# ifdef DL_LAZY
+# define LT_DLLAZY_OR_NOW DL_LAZY
+# else
+# ifdef RTLD_NOW
+# define LT_DLLAZY_OR_NOW RTLD_NOW
+# else
+# ifdef DL_NOW
+# define LT_DLLAZY_OR_NOW DL_NOW
+# else
+# define LT_DLLAZY_OR_NOW 0
+# endif
+# endif
+# endif
+# endif
+#endif
+
+/* When -fvisbility=hidden is used, assume the code has been annotated
+ correspondingly for the symbols needed. */
+#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
+void fnord () __attribute__((visibility("default")));
+#endif
+
+void fnord () { int i=42; }
+int main ()
+{
+ void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+ int status = $lt_dlunknown;
+
+ if (self)
+ {
+ if (dlsym (self,"fnord")) status = $lt_dlno_uscore;
+ else
+ {
+ if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
+ else puts (dlerror ());
+ }
+ /* dlclose (self); */
+ }
+ else
+ puts (dlerror ());
+
+ return status;
+}
+_LT_EOF
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then
+ (./conftest; exit; ) >&5 2>/dev/null
+ lt_status=$?
+ case x$lt_status in
+ x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;;
+ x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;;
+ x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;;
+ esac
+ else :
+ # compilation failed
+ lt_cv_dlopen_self_static=no
+ fi
+fi
+rm -fr conftest*
+
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static" >&5
+$as_echo "$lt_cv_dlopen_self_static" >&6; }
+ fi
+
+ CPPFLAGS="$save_CPPFLAGS"
+ LDFLAGS="$save_LDFLAGS"
+ LIBS="$save_LIBS"
+ ;;
+ 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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+striplib=
+old_striplib=
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5
+$as_echo_n "checking whether stripping libraries is possible... " >&6; }
+if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then
+ test -z "$old_striplib" && old_striplib="$STRIP --strip-debug"
+ test -z "$striplib" && striplib="$STRIP --strip-unneeded"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+# FIXME - insert some real tests, host_os isn't really good enough
+ case $host_os in
+ darwin*)
+ if test -n "$STRIP" ; then
+ striplib="$STRIP -x"
+ old_striplib="$STRIP -S"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ fi
+ ;;
+ *)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ ;;
+ esac
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+ # Report which library types will actually be built
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5
+$as_echo_n "checking if libtool supports shared libraries... " >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5
+$as_echo "$can_build_shared" >&6; }
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5
+$as_echo_n "checking whether to build shared libraries... " >&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
+ ;;
+
+ aix[4-9]*)
+ if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
+ test "$enable_shared" = yes && enable_static=no
+ fi
+ ;;
+ esac
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5
+$as_echo "$enable_shared" >&6; }
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5
+$as_echo_n "checking whether to build static libraries... " >&6; }
+ # Make sure either enable_shared or enable_static is yes.
+ test "$enable_shared" = yes || enable_static=yes
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5
+$as_echo "$enable_static" >&6; }
+
+
+
+
+fi
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+CC="$lt_save_CC"
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ac_config_commands="$ac_config_commands libtool"
+
+
+
+
+# Only expand once:
+
+
+
+# AC_PLUGINS setting $plugins is called by ACX_LARGEFILE.
+
+# The tests for host and target for $enable_largefile require
+# canonical names.
+
+
+
+# As the $enable_largefile decision depends on --enable-plugins we must set it
+# even in directories otherwise not depending on the $plugins option.
+
+
+ maybe_plugins=no
+ for ac_header in dlfcn.h
+do :
+ ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default
+"
+if test "x$ac_cv_header_dlfcn_h" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_DLFCN_H 1
+_ACEOF
+ maybe_plugins=yes
+fi
+
+done
+
+ for ac_header in windows.h
+do :
+ ac_fn_c_check_header_compile "$LINENO" "windows.h" "ac_cv_header_windows_h" "$ac_includes_default
+"
+if test "x$ac_cv_header_windows_h" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_WINDOWS_H 1
+_ACEOF
+ maybe_plugins=yes
+fi
+
+done
+
+
+ # Check whether --enable-plugins was given.
+if test "${enable_plugins+set}" = set; then :
+ enableval=$enable_plugins; case "${enableval}" in
+ no) plugins=no ;;
+ *) plugins=yes
+ if test "$maybe_plugins" != "yes" ; then
+ as_fn_error "Building with plugin support requires a host that supports dlopen." "$LINENO" 5
+ fi ;;
+ esac
+else
+ plugins=$maybe_plugins
+
+fi
+
+ if test "$plugins" = "yes"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing dlopen" >&5
+$as_echo_n "checking for library containing dlopen... " >&6; }
+if test "${ac_cv_search_dlopen+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_func_search_save_LIBS=$LIBS
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dlopen ();
+int
+main ()
+{
+return dlopen ();
+ ;
+ return 0;
+}
+_ACEOF
+for ac_lib in '' dl; do
+ if test -z "$ac_lib"; then
+ ac_res="none required"
+ else
+ ac_res=-l$ac_lib
+ LIBS="-l$ac_lib $ac_func_search_save_LIBS"
+ fi
+ if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_search_dlopen=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext
+ if test "${ac_cv_search_dlopen+set}" = set; then :
+ break
+fi
+done
+if test "${ac_cv_search_dlopen+set}" = set; then :
+
+else
+ ac_cv_search_dlopen=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_dlopen" >&5
+$as_echo "$ac_cv_search_dlopen" >&6; }
+ac_res=$ac_cv_search_dlopen
+if test "$ac_res" != no; then :
+ test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+fi
+
+ fi
+
+
+case "${host}" in
+ sparc-*-solaris*|i[3-7]86-*-solaris*)
+ # On native 32bit sparc and ia32 solaris, large-file and procfs support
+ # are mutually exclusive; and without procfs support, the bfd/ elf module
+ # cannot provide certain routines such as elfcore_write_prpsinfo
+ # or elfcore_write_prstatus. So unless the user explicitly requested
+ # large-file support through the --enable-largefile switch, disable
+ # large-file support in favor of procfs support.
+ test "${target}" = "${host}" -a "x$plugins" = xno \
+ && : ${enable_largefile="no"}
+ ;;
+esac
+
+# Check whether --enable-largefile was given.
+if test "${enable_largefile+set}" = set; then :
+ enableval=$enable_largefile;
+fi
+
+if test "$enable_largefile" != no; then
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for special C compiler options needed for large files" >&5
+$as_echo_n "checking for special C compiler options needed for large files... " >&6; }
+if test "${ac_cv_sys_largefile_CC+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_cv_sys_largefile_CC=no
+ if test "$GCC" != yes; then
+ ac_save_CC=$CC
+ while :; do
+ # IRIX 6.2 and later do not support large files by default,
+ # so use the C compiler's -n32 option if that helps.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <sys/types.h>
+ /* Check that off_t can represent 2**63 - 1 correctly.
+ We can't simply define LARGE_OFF_T to be 9223372036854775807,
+ since some C++ compilers masquerading as C compilers
+ incorrectly reject 9223372036854775807. */
+#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+ int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
+ && LARGE_OFF_T % 2147483647 == 1)
+ ? 1 : -1];
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+ if ac_fn_c_try_compile "$LINENO"; then :
+ break
+fi
+rm -f core conftest.err conftest.$ac_objext
+ CC="$CC -n32"
+ if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_sys_largefile_CC=' -n32'; break
+fi
+rm -f core conftest.err conftest.$ac_objext
+ break
+ done
+ CC=$ac_save_CC
+ rm -f conftest.$ac_ext
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_largefile_CC" >&5
+$as_echo "$ac_cv_sys_largefile_CC" >&6; }
+ if test "$ac_cv_sys_largefile_CC" != no; then
+ CC=$CC$ac_cv_sys_largefile_CC
+ fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _FILE_OFFSET_BITS value needed for large files" >&5
+$as_echo_n "checking for _FILE_OFFSET_BITS value needed for large files... " >&6; }
+if test "${ac_cv_sys_file_offset_bits+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ while :; do
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <sys/types.h>
+ /* Check that off_t can represent 2**63 - 1 correctly.
+ We can't simply define LARGE_OFF_T to be 9223372036854775807,
+ since some C++ compilers masquerading as C compilers
+ incorrectly reject 9223372036854775807. */
+#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+ int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
+ && LARGE_OFF_T % 2147483647 == 1)
+ ? 1 : -1];
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_sys_file_offset_bits=no; break
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#define _FILE_OFFSET_BITS 64
+#include <sys/types.h>
+ /* Check that off_t can represent 2**63 - 1 correctly.
+ We can't simply define LARGE_OFF_T to be 9223372036854775807,
+ since some C++ compilers masquerading as C compilers
+ incorrectly reject 9223372036854775807. */
+#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+ int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
+ && LARGE_OFF_T % 2147483647 == 1)
+ ? 1 : -1];
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_sys_file_offset_bits=64; break
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_cv_sys_file_offset_bits=unknown
+ break
+done
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_file_offset_bits" >&5
+$as_echo "$ac_cv_sys_file_offset_bits" >&6; }
+case $ac_cv_sys_file_offset_bits in #(
+ no | unknown) ;;
+ *)
+cat >>confdefs.h <<_ACEOF
+#define _FILE_OFFSET_BITS $ac_cv_sys_file_offset_bits
+_ACEOF
+;;
+esac
+rm -rf conftest*
+ if test $ac_cv_sys_file_offset_bits = unknown; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _LARGE_FILES value needed for large files" >&5
+$as_echo_n "checking for _LARGE_FILES value needed for large files... " >&6; }
+if test "${ac_cv_sys_large_files+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ while :; do
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <sys/types.h>
+ /* Check that off_t can represent 2**63 - 1 correctly.
+ We can't simply define LARGE_OFF_T to be 9223372036854775807,
+ since some C++ compilers masquerading as C compilers
+ incorrectly reject 9223372036854775807. */
+#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+ int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
+ && LARGE_OFF_T % 2147483647 == 1)
+ ? 1 : -1];
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_sys_large_files=no; break
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#define _LARGE_FILES 1
+#include <sys/types.h>
+ /* Check that off_t can represent 2**63 - 1 correctly.
+ We can't simply define LARGE_OFF_T to be 9223372036854775807,
+ since some C++ compilers masquerading as C compilers
+ incorrectly reject 9223372036854775807. */
+#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+ int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
+ && LARGE_OFF_T % 2147483647 == 1)
+ ? 1 : -1];
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_sys_large_files=1; break
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_cv_sys_large_files=unknown
+ break
+done
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_large_files" >&5
+$as_echo "$ac_cv_sys_large_files" >&6; }
+case $ac_cv_sys_large_files in #(
+ no | unknown) ;;
+ *)
+cat >>confdefs.h <<_ACEOF
+#define _LARGE_FILES $ac_cv_sys_large_files
+_ACEOF
+;;
+esac
+rm -rf conftest*
+ fi
+fi
+
+
+
+ if test "$plugins" = "yes"; then
+ PLUGINS_TRUE=
+ PLUGINS_FALSE='#'
+else
+ PLUGINS_TRUE='#'
+ PLUGINS_FALSE=
+fi
+
+
+if test "$plugins" = "yes"; then
+ enable_targets="$enable_targets plugin"
+fi
+
+# Check whether --enable-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 ;;
+ *) as_fn_error "bad value ${enableval} for 64-bit-bfd option" "$LINENO" 5 ;;
+esac
+else
+ want64=false
+fi
+
+# Check whether --enable-targets was given.
+if test "${enable_targets+set}" = set; then :
+ enableval=$enable_targets; case "${enableval}" in
+ yes | "") as_fn_error "enable-targets option must specify target names or 'all'" "$LINENO" 5
+ ;;
+ no) enable_targets= ;;
+ *) enable_targets=$enableval ;;
+esac
+fi
+
+
+# Check whether --with-mmap was given.
+if test "${with_mmap+set}" = set; then :
+ withval=$with_mmap; case "${withval}" in
+ yes) want_mmap=true ;;
+ no) want_mmap=false ;;
+ *) as_fn_error "bad value ${withval} for BFD with-mmap option" "$LINENO" 5 ;;
+esac
+else
+ want_mmap=false
+fi
+
+# Check whether --enable-secureplt was given.
+if test "${enable_secureplt+set}" = set; then :
+ enableval=$enable_secureplt; case "${enableval}" in
+ yes) use_secureplt=true ;;
+ no) use_secureplt=false ;;
+ *) as_fn_error "bad value ${enableval} for secureplt option" "$LINENO" 5 ;;
+esac
+else
+ use_secureplt=true
+fi
+if test $use_secureplt = true; then
+
+$as_echo "#define USE_SECUREPLT 1" >>confdefs.h
+
+fi
+
+# Check whether --enable-leading-mingw64-underscores was given.
+if test "${enable_leading_mingw64_underscores+set}" = set; then :
+ enableval=$enable_leading_mingw64_underscores;
+fi
+
+if test x"$enable_leading_mingw64_underscores" = xyes ; then :
+
+$as_echo "#define USE_MINGW64_LEADING_UNDERSCORES 1" >>confdefs.h
+
+fi
+
+DEBUGDIR=${libdir}/debug
+
+# Check whether --with-separate-debug-dir was given.
+if test "${with_separate_debug_dir+set}" = set; then :
+ withval=$with_separate_debug_dir; DEBUGDIR="${withval}"
+fi
+
+
+
+# Check to see if we should allow the generation of
+# symbols with the ELF standard's STT_COMMON type.
+# Check whether --enable-elf-stt-common was given.
+if test "${enable_elf_stt_common+set}" = set; then :
+ enableval=$enable_elf_stt_common; case "${enableval}" in
+ yes) want_elf_stt_common=true ;;
+ no) want_elf_stt_common=false ;;
+ *) as_fn_error "bad value ${enableval} for ELF STT_COMMON option" "$LINENO" 5 ;;
+ esac
+else
+ # We have to choose a default behaviour. For native builds we could
+# test whether the loader supports the STT_COMMON type, but that would
+# mean that built binaries could not be exported to older systems where
+# the loader does not support it. So by default we always choose to
+# disable this feature.
+ want_elf_stt_common=false
+fi
+if test $want_elf_stt_common = true; then
+
+$as_echo "#define USE_STT_COMMON 1" >>confdefs.h
+
+fi
+
+
+
+# Check whether --with-pkgversion was given.
+if test "${with_pkgversion+set}" = set; then :
+ withval=$with_pkgversion; case "$withval" in
+ yes) as_fn_error "package version not specified" "$LINENO" 5 ;;
+ no) PKGVERSION= ;;
+ *) PKGVERSION="($withval) " ;;
+ esac
+else
+ PKGVERSION="(GNU Binutils) "
+
+fi
+
+
+
+
+
+# Check whether --with-bugurl was given.
+if test "${with_bugurl+set}" = set; then :
+ withval=$with_bugurl; case "$withval" in
+ yes) as_fn_error "bug URL not specified" "$LINENO" 5 ;;
+ no) BUGURL=
+ ;;
+ *) BUGURL="$withval"
+ ;;
+ esac
+else
+ BUGURL="http://www.sourceware.org/bugzilla/"
+
+fi
+
+ case ${BUGURL} in
+ "")
+ REPORT_BUGS_TO=
+ REPORT_BUGS_TEXI=
+ ;;
+ *)
+ REPORT_BUGS_TO="<$BUGURL>"
+ REPORT_BUGS_TEXI=@uref{`echo "$BUGURL" | sed 's/@/@@/g'`}
+ ;;
+ esac;
+
+
+
+
+
+# Set the 'development' global.
+. $srcdir/../bfd/development.sh
+
+GCC_WARN_CFLAGS="-W -Wall -Wstrict-prototypes -Wmissing-prototypes"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+__GNUC__
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "^[0-3]$" >/dev/null 2>&1; then :
+
+else
+ GCC_WARN_CFLAGS="$GCC_WARN_CFLAGS -Wshadow"
+fi
+rm -f conftest*
+
+
+# Check whether --enable-werror was given.
+if test "${enable_werror+set}" = set; then :
+ enableval=$enable_werror; case "${enableval}" in
+ yes | y) ERROR_ON_WARNING="yes" ;;
+ no | n) ERROR_ON_WARNING="no" ;;
+ *) as_fn_error "bad value ${enableval} for --enable-werror" "$LINENO" 5 ;;
+ esac
+fi
+
+
+# Disable -Wformat by default when using gcc on mingw
+case "${host}" in
+ *-*-mingw32*)
+ if test "${GCC}" = yes -a -z "${ERROR_ON_WARNING}" ; then
+ GCC_WARN_CFLAGS="$GCC_WARN_CFLAGS -Wno-format"
+ fi
+ ;;
+ *) ;;
+esac
+
+# Enable -Werror by default when using gcc. Turn it off for releases.
+if test "${GCC}" = yes -a -z "${ERROR_ON_WARNING}" -a "$development" = true ; then
+ ERROR_ON_WARNING=yes
+fi
+
+NO_WERROR=
+if test "${ERROR_ON_WARNING}" = yes ; then
+ GCC_WARN_CFLAGS="$GCC_WARN_CFLAGS -Werror"
+ NO_WERROR="-Wno-error"
+fi
+
+if test "${GCC}" = yes ; then
+ WARN_CFLAGS="${GCC_WARN_CFLAGS}"
+fi
+
+# Check whether --enable-build-warnings was given.
+if test "${enable_build_warnings+set}" = set; then :
+ enableval=$enable_build_warnings; case "${enableval}" in
+ yes) WARN_CFLAGS="${GCC_WARN_CFLAGS}";;
+ no) if test "${GCC}" = yes ; then
+ WARN_CFLAGS="-w"
+ fi;;
+ ,*) t=`echo "${enableval}" | sed -e "s/,/ /g"`
+ WARN_CFLAGS="${GCC_WARN_CFLAGS} ${t}";;
+ *,) t=`echo "${enableval}" | sed -e "s/,/ /g"`
+ WARN_CFLAGS="${t} ${GCC_WARN_CFLAGS}";;
+ *) WARN_CFLAGS=`echo "${enableval}" | sed -e "s/,/ /g"`;;
+esac
+fi
+
+
+if test x"$silent" != x"yes" && test x"$WARN_CFLAGS" != x""; then
+ echo "Setting warning flags = $WARN_CFLAGS" 6>&1
+fi
+
+
+
+
+
+ac_config_headers="$ac_config_headers config.h:config.in"
+
+
+# PR 14072
+
+
+if test -z "$target" ; then
+ as_fn_error "Unrecognized target system type; please check config.sub." "$LINENO" 5
+fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable maintainer-specific portions of Makefiles" >&5
+$as_echo_n "checking whether to enable maintainer-specific portions of Makefiles... " >&6; }
+ # Check whether --enable-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
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $USE_MAINTAINER_MODE" >&5
+$as_echo "$USE_MAINTAINER_MODE" >&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
+
+
+ if false; then
+ GENINSRC_NEVER_TRUE=
+ GENINSRC_NEVER_FALSE='#'
+else
+ GENINSRC_NEVER_TRUE='#'
+ GENINSRC_NEVER_FALSE=
+fi
+
+ case ${build_alias} in
+ "") build_noncanonical=${build} ;;
+ *) build_noncanonical=${build_alias} ;;
+esac
+
+ case ${host_alias} in
+ "") host_noncanonical=${build_noncanonical} ;;
+ *) host_noncanonical=${host_alias} ;;
+esac
+
+ case ${target_alias} in
+ "") target_noncanonical=${host_noncanonical} ;;
+ *) target_noncanonical=${target_alias} ;;
+esac
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to install libbfd" >&5
+$as_echo_n "checking whether to install libbfd... " >&6; }
+ # Check whether --enable-install-libbfd was given.
+if test "${enable_install_libbfd+set}" = set; then :
+ enableval=$enable_install_libbfd; install_libbfd_p=$enableval
+else
+ if test "${host}" = "${target}" || test "$enable_shared" = "yes"; then
+ install_libbfd_p=yes
+ else
+ install_libbfd_p=no
+ fi
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $install_libbfd_p" >&5
+$as_echo "$install_libbfd_p" >&6; }
+ if test $install_libbfd_p = yes; then
+ INSTALL_LIBBFD_TRUE=
+ INSTALL_LIBBFD_FALSE='#'
+else
+ INSTALL_LIBBFD_TRUE='#'
+ INSTALL_LIBBFD_FALSE=
+fi
+
+ # Need _noncanonical variables for this.
+
+
+
+
+ # libbfd.a is a host library containing target dependent code
+ bfdlibdir='$(libdir)'
+ bfdincludedir='$(includedir)'
+ if test "${host}" != "${target}"; then
+ bfdlibdir='$(exec_prefix)/$(host_noncanonical)/$(target_noncanonical)/lib'
+ bfdincludedir='$(exec_prefix)/$(host_noncanonical)/$(target_noncanonical)/include'
+ fi
+
+
+
+
+
+
+
+
+host64=false
+target64=false
+bfd_default_target_size=32
+
+# host stuff:
+
+ALL_LINGUAS="fr tr ja es sv da zh_CN ro rw vi fi id ru uk"
+# If we haven't got the data from the intl directory,
+# assume NLS is disabled.
+USE_NLS=no
+LIBINTL=
+LIBINTL_DEP=
+INCINTL=
+XGETTEXT=
+GMSGFMT=
+POSUB=
+
+if test -f ../intl/config.intl; then
+ . ../intl/config.intl
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether NLS is requested" >&5
+$as_echo_n "checking whether NLS is requested... " >&6; }
+if test x"$USE_NLS" != xyes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define ENABLE_NLS 1" >>confdefs.h
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for catalogs to be installed" >&5
+$as_echo_n "checking for catalogs to be installed... " >&6; }
+ # Look for .po and .gmo files in the source directory.
+ CATALOGS=
+ XLINGUAS=
+ for cat in $srcdir/po/*.gmo $srcdir/po/*.po; do
+ # If there aren't any .gmo files the shell will give us the
+ # literal string "../path/to/srcdir/po/*.gmo" which has to be
+ # weeded out.
+ case "$cat" in *\**)
+ continue;;
+ esac
+ # The quadruple backslash is collapsed to a double backslash
+ # by the backticks, then collapsed again by the double quotes,
+ # leaving us with one backslash in the sed expression (right
+ # before the dot that mustn't act as a wildcard).
+ cat=`echo $cat | sed -e "s!$srcdir/po/!!" -e "s!\\\\.po!.gmo!"`
+ lang=`echo $cat | sed -e "s!\\\\.gmo!!"`
+ # The user is allowed to set LINGUAS to a list of languages to
+ # install catalogs for. If it's empty that means "all of them."
+ if test "x$LINGUAS" = x; then
+ CATALOGS="$CATALOGS $cat"
+ XLINGUAS="$XLINGUAS $lang"
+ else
+ case "$LINGUAS" in *$lang*)
+ CATALOGS="$CATALOGS $cat"
+ XLINGUAS="$XLINGUAS $lang"
+ ;;
+ esac
+ fi
+ done
+ LINGUAS="$XLINGUAS"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LINGUAS" >&5
+$as_echo "$LINGUAS" >&6; }
+
+
+ DATADIRNAME=share
+
+ INSTOBJEXT=.mo
+
+ GENCAT=gencat
+
+ CATOBJEXT=.gmo
+
+fi
+
+ MKINSTALLDIRS=
+ if test -n "$ac_aux_dir"; then
+ case "$ac_aux_dir" in
+ /*) MKINSTALLDIRS="$ac_aux_dir/mkinstalldirs" ;;
+ *) MKINSTALLDIRS="\$(top_builddir)/$ac_aux_dir/mkinstalldirs" ;;
+ esac
+ fi
+ if test -z "$MKINSTALLDIRS"; then
+ MKINSTALLDIRS="\$(top_srcdir)/mkinstalldirs"
+ fi
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether NLS is requested" >&5
+$as_echo_n "checking whether NLS is requested... " >&6; }
+ # Check whether --enable-nls was given.
+if test "${enable_nls+set}" = set; then :
+ enableval=$enable_nls; USE_NLS=$enableval
+else
+ USE_NLS=yes
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $USE_NLS" >&5
+$as_echo "$USE_NLS" >&6; }
+
+
+
+
+
+
+# Prepare PATH_SEPARATOR.
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ echo "#! /bin/sh" >conf$$.sh
+ echo "exit 0" >>conf$$.sh
+ chmod +x conf$$.sh
+ if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+ PATH_SEPARATOR=';'
+ else
+ PATH_SEPARATOR=:
+ fi
+ rm -f conf$$.sh
+fi
+
+# Find out how to test for executable files. Don't use a zero-byte file,
+# as systems may use methods other than mode bits to determine executability.
+cat >conf$$.file <<_ASEOF
+#! /bin/sh
+exit 0
+_ASEOF
+chmod +x conf$$.file
+if test -x conf$$.file >/dev/null 2>&1; then
+ ac_executable_p="test -x"
+else
+ ac_executable_p="test -f"
+fi
+rm -f conf$$.file
+
+# Extract the first word of "msgfmt", so it can be a program name with args.
+set dummy msgfmt; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_path_MSGFMT+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ case "$MSGFMT" in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_MSGFMT="$MSGFMT" # Let the user override the test with a path.
+ ;;
+ *)
+ ac_save_IFS="$IFS"; IFS=$PATH_SEPARATOR
+ for ac_dir in $PATH; do
+ IFS="$ac_save_IFS"
+ test -z "$ac_dir" && ac_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $ac_executable_p "$ac_dir/$ac_word$ac_exec_ext"; then
+ if $ac_dir/$ac_word --statistics /dev/null >/dev/null 2>&1 &&
+ (if $ac_dir/$ac_word --statistics /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi); then
+ ac_cv_path_MSGFMT="$ac_dir/$ac_word$ac_exec_ext"
+ break 2
+ fi
+ fi
+ done
+ done
+ IFS="$ac_save_IFS"
+ test -z "$ac_cv_path_MSGFMT" && ac_cv_path_MSGFMT=":"
+ ;;
+esac
+fi
+MSGFMT="$ac_cv_path_MSGFMT"
+if test "$MSGFMT" != ":"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MSGFMT" >&5
+$as_echo "$MSGFMT" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ # Extract the first word of "gmsgfmt", so it can be a program name with args.
+set dummy gmsgfmt; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_path_GMSGFMT+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $GMSGFMT in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_path_GMSGFMT="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_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
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GMSGFMT" >&5
+$as_echo "$GMSGFMT" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+
+
+# Prepare PATH_SEPARATOR.
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ echo "#! /bin/sh" >conf$$.sh
+ echo "exit 0" >>conf$$.sh
+ chmod +x conf$$.sh
+ if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+ PATH_SEPARATOR=';'
+ else
+ PATH_SEPARATOR=:
+ fi
+ rm -f conf$$.sh
+fi
+
+# Find out how to test for executable files. Don't use a zero-byte file,
+# as systems may use methods other than mode bits to determine executability.
+cat >conf$$.file <<_ASEOF
+#! /bin/sh
+exit 0
+_ASEOF
+chmod +x conf$$.file
+if test -x conf$$.file >/dev/null 2>&1; then
+ ac_executable_p="test -x"
+else
+ ac_executable_p="test -f"
+fi
+rm -f conf$$.file
+
+# Extract the first word of "xgettext", so it can be a program name with args.
+set dummy xgettext; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_path_XGETTEXT+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ case "$XGETTEXT" in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_XGETTEXT="$XGETTEXT" # Let the user override the test with a path.
+ ;;
+ *)
+ ac_save_IFS="$IFS"; IFS=$PATH_SEPARATOR
+ for ac_dir in $PATH; do
+ IFS="$ac_save_IFS"
+ test -z "$ac_dir" && ac_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $ac_executable_p "$ac_dir/$ac_word$ac_exec_ext"; then
+ if $ac_dir/$ac_word --omit-header --copyright-holder= --msgid-bugs-address= /dev/null >/dev/null 2>&1 &&
+ (if $ac_dir/$ac_word --omit-header --copyright-holder= --msgid-bugs-address= /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi); then
+ ac_cv_path_XGETTEXT="$ac_dir/$ac_word$ac_exec_ext"
+ break 2
+ fi
+ fi
+ done
+ done
+ IFS="$ac_save_IFS"
+ test -z "$ac_cv_path_XGETTEXT" && ac_cv_path_XGETTEXT=":"
+ ;;
+esac
+fi
+XGETTEXT="$ac_cv_path_XGETTEXT"
+if test "$XGETTEXT" != ":"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $XGETTEXT" >&5
+$as_echo "$XGETTEXT" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ rm -f messages.po
+
+
+# Prepare PATH_SEPARATOR.
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ echo "#! /bin/sh" >conf$$.sh
+ echo "exit 0" >>conf$$.sh
+ chmod +x conf$$.sh
+ if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+ PATH_SEPARATOR=';'
+ else
+ PATH_SEPARATOR=:
+ fi
+ rm -f conf$$.sh
+fi
+
+# Find out how to test for executable files. Don't use a zero-byte file,
+# as systems may use methods other than mode bits to determine executability.
+cat >conf$$.file <<_ASEOF
+#! /bin/sh
+exit 0
+_ASEOF
+chmod +x conf$$.file
+if test -x conf$$.file >/dev/null 2>&1; then
+ ac_executable_p="test -x"
+else
+ ac_executable_p="test -f"
+fi
+rm -f conf$$.file
+
+# Extract the first word of "msgmerge", so it can be a program name with args.
+set dummy msgmerge; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_path_MSGMERGE+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ case "$MSGMERGE" in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_MSGMERGE="$MSGMERGE" # Let the user override the test with a path.
+ ;;
+ *)
+ ac_save_IFS="$IFS"; IFS=$PATH_SEPARATOR
+ for ac_dir in $PATH; do
+ IFS="$ac_save_IFS"
+ test -z "$ac_dir" && ac_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $ac_executable_p "$ac_dir/$ac_word$ac_exec_ext"; then
+ if $ac_dir/$ac_word --update -q /dev/null /dev/null >/dev/null 2>&1; then
+ ac_cv_path_MSGMERGE="$ac_dir/$ac_word$ac_exec_ext"
+ break 2
+ fi
+ fi
+ done
+ done
+ IFS="$ac_save_IFS"
+ test -z "$ac_cv_path_MSGMERGE" && ac_cv_path_MSGMERGE=":"
+ ;;
+esac
+fi
+MSGMERGE="$ac_cv_path_MSGMERGE"
+if test "$MSGMERGE" != ":"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MSGMERGE" >&5
+$as_echo "$MSGMERGE" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ if test "$GMSGFMT" != ":"; then
+ if $GMSGFMT --statistics /dev/null >/dev/null 2>&1 &&
+ (if $GMSGFMT --statistics /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi); then
+ : ;
+ else
+ GMSGFMT=`echo "$GMSGFMT" | sed -e 's,^.*/,,'`
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: found $GMSGFMT program is not GNU msgfmt; ignore it" >&5
+$as_echo "found $GMSGFMT program is not GNU msgfmt; ignore it" >&6; }
+ GMSGFMT=":"
+ fi
+ fi
+
+ if test "$XGETTEXT" != ":"; then
+ if $XGETTEXT --omit-header --copyright-holder= --msgid-bugs-address= /dev/null >/dev/null 2>&1 &&
+ (if $XGETTEXT --omit-header --copyright-holder= --msgid-bugs-address= /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi); then
+ : ;
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: found xgettext program is not GNU xgettext; ignore it" >&5
+$as_echo "found xgettext program is not GNU xgettext; ignore it" >&6; }
+ XGETTEXT=":"
+ fi
+ rm -f messages.po
+ fi
+
+ ac_config_commands="$ac_config_commands default-1"
+
+
+
+# Permit host specific settings.
+. ${srcdir}/configure.host
+
+
+
+
+BFD_HOST_64BIT_LONG=0
+BFD_HOST_64BIT_LONG_LONG=0
+BFD_HOST_64_BIT_DEFINED=0
+BFD_HOST_64_BIT=
+BFD_HOST_U_64_BIT=
+BFD_HOSTPTR_T="unsigned long"
+
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of long long" >&5
+$as_echo_n "checking size of long long... " >&6; }
+if test "${ac_cv_sizeof_long_long+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (long long))" "ac_cv_sizeof_long_long" "$ac_includes_default"; then :
+
+else
+ if test "$ac_cv_type_long_long" = yes; then
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+{ as_fn_set_status 77
+as_fn_error "cannot compute sizeof (long long)
+See \`config.log' for more details." "$LINENO" 5; }; }
+ else
+ ac_cv_sizeof_long_long=0
+ fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long_long" >&5
+$as_echo "$ac_cv_sizeof_long_long" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_LONG_LONG $ac_cv_sizeof_long_long
+_ACEOF
+
+
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of void *" >&5
+$as_echo_n "checking size of void *... " >&6; }
+if test "${ac_cv_sizeof_void_p+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (void *))" "ac_cv_sizeof_void_p" "$ac_includes_default"; then :
+
+else
+ if test "$ac_cv_type_void_p" = yes; then
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+{ as_fn_set_status 77
+as_fn_error "cannot compute sizeof (void *)
+See \`config.log' for more details." "$LINENO" 5; }; }
+ else
+ ac_cv_sizeof_void_p=0
+ fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_void_p" >&5
+$as_echo "$ac_cv_sizeof_void_p" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_VOID_P $ac_cv_sizeof_void_p
+_ACEOF
+
+
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of long" >&5
+$as_echo_n "checking size of long... " >&6; }
+if test "${ac_cv_sizeof_long+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (long))" "ac_cv_sizeof_long" "$ac_includes_default"; then :
+
+else
+ if test "$ac_cv_type_long" = yes; then
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+{ as_fn_set_status 77
+as_fn_error "cannot compute sizeof (long)
+See \`config.log' for more details." "$LINENO" 5; }; }
+ else
+ ac_cv_sizeof_long=0
+ fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long" >&5
+$as_echo "$ac_cv_sizeof_long" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_LONG $ac_cv_sizeof_long
+_ACEOF
+
+
+
+if test "x${ac_cv_sizeof_void_p}" = "x8"; then
+ host64=true
+fi
+
+if test "x${ac_cv_sizeof_long}" = "x8"; then
+ BFD_HOST_64BIT_LONG=1
+ test -n "${HOST_64BIT_TYPE}" || HOST_64BIT_TYPE="long"
+ test -n "${HOST_U_64BIT_TYPE}" || HOST_U_64BIT_TYPE="unsigned long"
+elif test "x${ac_cv_sizeof_long_long}" = "x8"; then
+ BFD_HOST_64BIT_LONG_LONG=1
+ test -n "${HOST_64BIT_TYPE}" || HOST_64BIT_TYPE="long long"
+ test -n "${HOST_U_64BIT_TYPE}" || HOST_U_64BIT_TYPE="unsigned long long"
+ if test "x${ac_cv_sizeof_void_p}" = "x8"; then
+ BFD_HOSTPTR_T="unsigned long long"
+ fi
+fi
+
+if test -n "${HOST_64BIT_TYPE}" -a -n "${HOST_U_64BIT_TYPE}"; 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
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for build system executable suffix" >&5
+$as_echo_n "checking for build system executable suffix... " >&6; }
+if test "${bfd_cv_build_exeext+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ rm -f conftest*
+ echo 'int main () { return 0; }' > conftest.c
+ bfd_cv_build_exeext=
+ ${CC_FOR_BUILD} -o conftest conftest.c 1>&5 2>&5
+ for file in conftest.*; do
+ case $file in
+ *.c | *.o | *.obj | *.ilk | *.pdb) ;;
+ *) bfd_cv_build_exeext=`echo $file | sed -e s/conftest//` ;;
+ esac
+ done
+ rm -f conftest*
+ test x"${bfd_cv_build_exeext}" = x && bfd_cv_build_exeext=no
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $bfd_cv_build_exeext" >&5
+$as_echo "$bfd_cv_build_exeext" >&6; }
+ EXEEXT_FOR_BUILD=""
+ test x"${bfd_cv_build_exeext}" != xno && EXEEXT_FOR_BUILD=${bfd_cv_build_exeext}
+fi
+
+
+for ac_header in alloca.h stddef.h string.h strings.h stdlib.h time.h unistd.h wchar.h
+do :
+ as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
+eval as_val=\$$as_ac_Header
+ if test "x$as_val" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+for ac_header in fcntl.h sys/file.h sys/time.h sys/stat.h sys/resource.h
+do :
+ as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
+eval as_val=\$$as_ac_Header
+ if test "x$as_val" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+
+inttype_headers=`echo inttypes.h sys/inttypes.h | sed -e 's/,/ /g'`
+
+acx_cv_header_stdint=stddef.h
+acx_cv_header_stdint_kind="(already complete)"
+for i in stdint.h $inttype_headers; do
+ unset ac_cv_type_uintptr_t
+ unset ac_cv_type_uintmax_t
+ unset ac_cv_type_int_least32_t
+ unset ac_cv_type_int_fast32_t
+ unset ac_cv_type_uint64_t
+ $as_echo_n "looking for a compliant stdint.h in $i, " >&6
+ ac_fn_c_check_type "$LINENO" "uintmax_t" "ac_cv_type_uintmax_t" "#include <sys/types.h>
+#include <$i>
+"
+if test "x$ac_cv_type_uintmax_t" = x""yes; then :
+ acx_cv_header_stdint=$i
+else
+ continue
+fi
+
+ ac_fn_c_check_type "$LINENO" "uintptr_t" "ac_cv_type_uintptr_t" "#include <sys/types.h>
+#include <$i>
+"
+if test "x$ac_cv_type_uintptr_t" = x""yes; then :
+
+else
+ acx_cv_header_stdint_kind="(mostly complete)"
+fi
+
+ ac_fn_c_check_type "$LINENO" "int_least32_t" "ac_cv_type_int_least32_t" "#include <sys/types.h>
+#include <$i>
+"
+if test "x$ac_cv_type_int_least32_t" = x""yes; then :
+
+else
+ acx_cv_header_stdint_kind="(mostly complete)"
+fi
+
+ ac_fn_c_check_type "$LINENO" "int_fast32_t" "ac_cv_type_int_fast32_t" "#include <sys/types.h>
+#include <$i>
+"
+if test "x$ac_cv_type_int_fast32_t" = x""yes; then :
+
+else
+ acx_cv_header_stdint_kind="(mostly complete)"
+fi
+
+ ac_fn_c_check_type "$LINENO" "uint64_t" "ac_cv_type_uint64_t" "#include <sys/types.h>
+#include <$i>
+"
+if test "x$ac_cv_type_uint64_t" = x""yes; then :
+
+else
+ acx_cv_header_stdint_kind="(lacks uint64_t)"
+fi
+
+ break
+done
+if test "$acx_cv_header_stdint" = stddef.h; then
+ acx_cv_header_stdint_kind="(lacks uintmax_t)"
+ for i in stdint.h $inttype_headers; do
+ unset ac_cv_type_uintptr_t
+ unset ac_cv_type_uint32_t
+ unset ac_cv_type_uint64_t
+ $as_echo_n "looking for an incomplete stdint.h in $i, " >&6
+ ac_fn_c_check_type "$LINENO" "uint32_t" "ac_cv_type_uint32_t" "#include <sys/types.h>
+#include <$i>
+"
+if test "x$ac_cv_type_uint32_t" = x""yes; then :
+ acx_cv_header_stdint=$i
+else
+ continue
+fi
+
+ ac_fn_c_check_type "$LINENO" "uint64_t" "ac_cv_type_uint64_t" "#include <sys/types.h>
+#include <$i>
+"
+if test "x$ac_cv_type_uint64_t" = x""yes; then :
+
+fi
+
+ ac_fn_c_check_type "$LINENO" "uintptr_t" "ac_cv_type_uintptr_t" "#include <sys/types.h>
+#include <$i>
+"
+if test "x$ac_cv_type_uintptr_t" = x""yes; then :
+
+fi
+
+ break
+ done
+fi
+if test "$acx_cv_header_stdint" = stddef.h; then
+ acx_cv_header_stdint_kind="(u_intXX_t style)"
+ for i in sys/types.h $inttype_headers; do
+ unset ac_cv_type_u_int32_t
+ unset ac_cv_type_u_int64_t
+ $as_echo_n "looking for u_intXX_t types in $i, " >&6
+ ac_fn_c_check_type "$LINENO" "u_int32_t" "ac_cv_type_u_int32_t" "#include <sys/types.h>
+#include <$i>
+"
+if test "x$ac_cv_type_u_int32_t" = x""yes; then :
+ acx_cv_header_stdint=$i
+else
+ continue
+fi
+
+ ac_fn_c_check_type "$LINENO" "u_int64_t" "ac_cv_type_u_int64_t" "#include <sys/types.h>
+#include <$i>
+"
+if test "x$ac_cv_type_u_int64_t" = x""yes; then :
+
+fi
+
+ break
+ done
+fi
+if test "$acx_cv_header_stdint" = stddef.h; then
+ acx_cv_header_stdint_kind="(using manual detection)"
+fi
+
+test -z "$ac_cv_type_uintptr_t" && ac_cv_type_uintptr_t=no
+test -z "$ac_cv_type_uint64_t" && ac_cv_type_uint64_t=no
+test -z "$ac_cv_type_u_int64_t" && ac_cv_type_u_int64_t=no
+test -z "$ac_cv_type_int_least32_t" && ac_cv_type_int_least32_t=no
+test -z "$ac_cv_type_int_fast32_t" && ac_cv_type_int_fast32_t=no
+
+# ----------------- Summarize what we found so far
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking what to include in bfd_stdint.h" >&5
+$as_echo_n "checking what to include in bfd_stdint.h... " >&6; }
+
+case `$as_basename -- bfd_stdint.h ||
+$as_expr X/bfd_stdint.h : '.*/\([^/][^/]*\)/*$' \| \
+ Xbfd_stdint.h : 'X\(//\)$' \| \
+ Xbfd_stdint.h : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/bfd_stdint.h |
+ sed '/^.*\/\([^/][^/]*\)\/*$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'` in
+ stdint.h) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: are you sure you want it there?" >&5
+$as_echo "$as_me: WARNING: are you sure you want it there?" >&2;} ;;
+ inttypes.h) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: are you sure you want it there?" >&5
+$as_echo "$as_me: WARNING: are you sure you want it there?" >&2;} ;;
+ *) ;;
+esac
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $acx_cv_header_stdint $acx_cv_header_stdint_kind" >&5
+$as_echo "$acx_cv_header_stdint $acx_cv_header_stdint_kind" >&6; }
+
+# ----------------- done included file, check C basic types --------
+
+# Lacking an uintptr_t? Test size of void *
+case "$acx_cv_header_stdint:$ac_cv_type_uintptr_t" in
+ stddef.h:* | *:no) # The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of void *" >&5
+$as_echo_n "checking size of void *... " >&6; }
+if test "${ac_cv_sizeof_void_p+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (void *))" "ac_cv_sizeof_void_p" "$ac_includes_default"; then :
+
+else
+ if test "$ac_cv_type_void_p" = yes; then
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+{ as_fn_set_status 77
+as_fn_error "cannot compute sizeof (void *)
+See \`config.log' for more details." "$LINENO" 5; }; }
+ else
+ ac_cv_sizeof_void_p=0
+ fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_void_p" >&5
+$as_echo "$ac_cv_sizeof_void_p" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_VOID_P $ac_cv_sizeof_void_p
+_ACEOF
+
+ ;;
+esac
+
+# Lacking an uint64_t? Test size of long
+case "$acx_cv_header_stdint:$ac_cv_type_uint64_t:$ac_cv_type_u_int64_t" in
+ stddef.h:*:* | *:no:no) # The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of long" >&5
+$as_echo_n "checking size of long... " >&6; }
+if test "${ac_cv_sizeof_long+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (long))" "ac_cv_sizeof_long" "$ac_includes_default"; then :
+
+else
+ if test "$ac_cv_type_long" = yes; then
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+{ as_fn_set_status 77
+as_fn_error "cannot compute sizeof (long)
+See \`config.log' for more details." "$LINENO" 5; }; }
+ else
+ ac_cv_sizeof_long=0
+ fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long" >&5
+$as_echo "$ac_cv_sizeof_long" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_LONG $ac_cv_sizeof_long
+_ACEOF
+
+ ;;
+esac
+
+if test $acx_cv_header_stdint = stddef.h; then
+ # Lacking a good header? Test size of everything and deduce all types.
+ # The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of int" >&5
+$as_echo_n "checking size of int... " >&6; }
+if test "${ac_cv_sizeof_int+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (int))" "ac_cv_sizeof_int" "$ac_includes_default"; then :
+
+else
+ if test "$ac_cv_type_int" = yes; then
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+{ as_fn_set_status 77
+as_fn_error "cannot compute sizeof (int)
+See \`config.log' for more details." "$LINENO" 5; }; }
+ else
+ ac_cv_sizeof_int=0
+ fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_int" >&5
+$as_echo "$ac_cv_sizeof_int" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_INT $ac_cv_sizeof_int
+_ACEOF
+
+
+ # The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of short" >&5
+$as_echo_n "checking size of short... " >&6; }
+if test "${ac_cv_sizeof_short+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (short))" "ac_cv_sizeof_short" "$ac_includes_default"; then :
+
+else
+ if test "$ac_cv_type_short" = yes; then
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+{ as_fn_set_status 77
+as_fn_error "cannot compute sizeof (short)
+See \`config.log' for more details." "$LINENO" 5; }; }
+ else
+ ac_cv_sizeof_short=0
+ fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_short" >&5
+$as_echo "$ac_cv_sizeof_short" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_SHORT $ac_cv_sizeof_short
+_ACEOF
+
+
+ # The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of char" >&5
+$as_echo_n "checking size of char... " >&6; }
+if test "${ac_cv_sizeof_char+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (char))" "ac_cv_sizeof_char" "$ac_includes_default"; then :
+
+else
+ if test "$ac_cv_type_char" = yes; then
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+{ as_fn_set_status 77
+as_fn_error "cannot compute sizeof (char)
+See \`config.log' for more details." "$LINENO" 5; }; }
+ else
+ ac_cv_sizeof_char=0
+ fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_char" >&5
+$as_echo "$ac_cv_sizeof_char" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_CHAR $ac_cv_sizeof_char
+_ACEOF
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for type equivalent to int8_t" >&5
+$as_echo_n "checking for type equivalent to int8_t... " >&6; }
+ case "$ac_cv_sizeof_char" in
+ 1) acx_cv_type_int8_t=char ;;
+ *) as_fn_error "no 8-bit type, please report a bug" "$LINENO" 5
+ esac
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $acx_cv_type_int8_t" >&5
+$as_echo "$acx_cv_type_int8_t" >&6; }
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for type equivalent to int16_t" >&5
+$as_echo_n "checking for type equivalent to int16_t... " >&6; }
+ case "$ac_cv_sizeof_int:$ac_cv_sizeof_short" in
+ 2:*) acx_cv_type_int16_t=int ;;
+ *:2) acx_cv_type_int16_t=short ;;
+ *) as_fn_error "no 16-bit type, please report a bug" "$LINENO" 5
+ esac
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $acx_cv_type_int16_t" >&5
+$as_echo "$acx_cv_type_int16_t" >&6; }
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for type equivalent to int32_t" >&5
+$as_echo_n "checking for type equivalent to int32_t... " >&6; }
+ case "$ac_cv_sizeof_int:$ac_cv_sizeof_long" in
+ 4:*) acx_cv_type_int32_t=int ;;
+ *:4) acx_cv_type_int32_t=long ;;
+ *) as_fn_error "no 32-bit type, please report a bug" "$LINENO" 5
+ esac
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $acx_cv_type_int32_t" >&5
+$as_echo "$acx_cv_type_int32_t" >&6; }
+fi
+
+# These tests are here to make the output prettier
+
+if test "$ac_cv_type_uint64_t" != yes && test "$ac_cv_type_u_int64_t" != yes; then
+ case "$ac_cv_sizeof_long" in
+ 8) acx_cv_type_int64_t=long ;;
+ esac
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for type equivalent to int64_t" >&5
+$as_echo_n "checking for type equivalent to int64_t... " >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${acx_cv_type_int64_t-'using preprocessor symbols'}" >&5
+$as_echo "${acx_cv_type_int64_t-'using preprocessor symbols'}" >&6; }
+fi
+
+# Now we can use the above types
+
+if test "$ac_cv_type_uintptr_t" != yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for type equivalent to intptr_t" >&5
+$as_echo_n "checking for type equivalent to intptr_t... " >&6; }
+ case $ac_cv_sizeof_void_p in
+ 2) acx_cv_type_intptr_t=int16_t ;;
+ 4) acx_cv_type_intptr_t=int32_t ;;
+ 8) acx_cv_type_intptr_t=int64_t ;;
+ *) as_fn_error "no equivalent for intptr_t, please report a bug" "$LINENO" 5
+ esac
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $acx_cv_type_intptr_t" >&5
+$as_echo "$acx_cv_type_intptr_t" >&6; }
+fi
+
+# ----------------- done all checks, emit header -------------
+ac_config_commands="$ac_config_commands bfd_stdint.h"
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether time.h and sys/time.h may both be included" >&5
+$as_echo_n "checking whether time.h and sys/time.h may both be included... " >&6; }
+if test "${ac_cv_header_time+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <sys/types.h>
+#include <sys/time.h>
+#include <time.h>
+
+int
+main ()
+{
+if ((struct tm *) 0)
+return 0;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_header_time=yes
+else
+ ac_cv_header_time=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_time" >&5
+$as_echo "$ac_cv_header_time" >&6; }
+if test $ac_cv_header_time = yes; then
+
+$as_echo "#define TIME_WITH_SYS_TIME 1" >>confdefs.h
+
+fi
+
+ac_header_dirent=no
+for ac_hdr in dirent.h sys/ndir.h sys/dir.h ndir.h; do
+ as_ac_Header=`$as_echo "ac_cv_header_dirent_$ac_hdr" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_hdr that defines DIR" >&5
+$as_echo_n "checking for $ac_hdr that defines DIR... " >&6; }
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <sys/types.h>
+#include <$ac_hdr>
+
+int
+main ()
+{
+if ((DIR *) 0)
+return 0;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ eval "$as_ac_Header=yes"
+else
+ eval "$as_ac_Header=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$as_ac_Header
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+eval as_val=\$$as_ac_Header
+ if test "x$as_val" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_hdr" | $as_tr_cpp` 1
+_ACEOF
+
+ac_header_dirent=$ac_hdr; break
+fi
+
+done
+# Two versions of opendir et al. are in -ldir and -lx on SCO Xenix.
+if test $ac_header_dirent = dirent.h; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing opendir" >&5
+$as_echo_n "checking for library containing opendir... " >&6; }
+if test "${ac_cv_search_opendir+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_func_search_save_LIBS=$LIBS
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char opendir ();
+int
+main ()
+{
+return opendir ();
+ ;
+ return 0;
+}
+_ACEOF
+for ac_lib in '' dir; do
+ if test -z "$ac_lib"; then
+ ac_res="none required"
+ else
+ ac_res=-l$ac_lib
+ LIBS="-l$ac_lib $ac_func_search_save_LIBS"
+ fi
+ if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_search_opendir=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext
+ if test "${ac_cv_search_opendir+set}" = set; then :
+ break
+fi
+done
+if test "${ac_cv_search_opendir+set}" = set; then :
+
+else
+ ac_cv_search_opendir=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_opendir" >&5
+$as_echo "$ac_cv_search_opendir" >&6; }
+ac_res=$ac_cv_search_opendir
+if test "$ac_res" != no; then :
+ test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+fi
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing opendir" >&5
+$as_echo_n "checking for library containing opendir... " >&6; }
+if test "${ac_cv_search_opendir+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_func_search_save_LIBS=$LIBS
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char opendir ();
+int
+main ()
+{
+return opendir ();
+ ;
+ return 0;
+}
+_ACEOF
+for ac_lib in '' x; do
+ if test -z "$ac_lib"; then
+ ac_res="none required"
+ else
+ ac_res=-l$ac_lib
+ LIBS="-l$ac_lib $ac_func_search_save_LIBS"
+ fi
+ if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_search_opendir=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext
+ if test "${ac_cv_search_opendir+set}" = set; then :
+ break
+fi
+done
+if test "${ac_cv_search_opendir+set}" = set; then :
+
+else
+ ac_cv_search_opendir=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_opendir" >&5
+$as_echo "$ac_cv_search_opendir" >&6; }
+ac_res=$ac_cv_search_opendir
+if test "$ac_res" != no; then :
+ test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+fi
+
+fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether string.h and strings.h may both be included" >&5
+$as_echo_n "checking whether string.h and strings.h may both be included... " >&6; }
+if test "${gcc_cv_header_string+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <string.h>
+#include <strings.h>
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ gcc_cv_header_string=yes
+else
+ gcc_cv_header_string=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_header_string" >&5
+$as_echo "$gcc_cv_header_string" >&6; }
+if test $gcc_cv_header_string = yes; then
+
+$as_echo "#define STRING_WITH_STRINGS 1" >>confdefs.h
+
+fi
+
+for ac_func in fcntl getpagesize setitimer sysconf fdopen getuid getgid fileno
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+eval as_val=\$$as_ac_var
+ if test "x$as_val" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+for ac_func in strtoull getrlimit
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+eval as_val=\$$as_ac_var
+ if test "x$as_val" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+
+ac_fn_c_check_decl "$LINENO" "basename" "ac_cv_have_decl_basename" "$ac_includes_default"
+if test "x$ac_cv_have_decl_basename" = x""yes; then :
+ ac_have_decl=1
+else
+ ac_have_decl=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_BASENAME $ac_have_decl
+_ACEOF
+
+ac_fn_c_check_decl "$LINENO" "ftello" "ac_cv_have_decl_ftello" "$ac_includes_default"
+if test "x$ac_cv_have_decl_ftello" = x""yes; then :
+ ac_have_decl=1
+else
+ ac_have_decl=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_FTELLO $ac_have_decl
+_ACEOF
+
+ac_fn_c_check_decl "$LINENO" "ftello64" "ac_cv_have_decl_ftello64" "$ac_includes_default"
+if test "x$ac_cv_have_decl_ftello64" = x""yes; then :
+ ac_have_decl=1
+else
+ ac_have_decl=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_FTELLO64 $ac_have_decl
+_ACEOF
+
+ac_fn_c_check_decl "$LINENO" "fseeko" "ac_cv_have_decl_fseeko" "$ac_includes_default"
+if test "x$ac_cv_have_decl_fseeko" = x""yes; then :
+ ac_have_decl=1
+else
+ ac_have_decl=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_FSEEKO $ac_have_decl
+_ACEOF
+
+ac_fn_c_check_decl "$LINENO" "fseeko64" "ac_cv_have_decl_fseeko64" "$ac_includes_default"
+if test "x$ac_cv_have_decl_fseeko64" = x""yes; then :
+ ac_have_decl=1
+else
+ ac_have_decl=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_FSEEKO64 $ac_have_decl
+_ACEOF
+
+
+
+case "${host}" in
+*-*-msdos* | *-*-go32* | *-*-mingw32* | *-*-cygwin* | *-*-windows*)
+
+$as_echo "#define USE_BINARY_FOPEN 1" >>confdefs.h
+ ;;
+esac
+
+ac_fn_c_check_decl "$LINENO" "ffs" "ac_cv_have_decl_ffs" "$ac_includes_default"
+if test "x$ac_cv_have_decl_ffs" = x""yes; then :
+ ac_have_decl=1
+else
+ ac_have_decl=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_FFS $ac_have_decl
+_ACEOF
+
+ac_fn_c_check_decl "$LINENO" "free" "ac_cv_have_decl_free" "$ac_includes_default"
+if test "x$ac_cv_have_decl_free" = x""yes; then :
+ ac_have_decl=1
+else
+ ac_have_decl=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_FREE $ac_have_decl
+_ACEOF
+
+ac_fn_c_check_decl "$LINENO" "getenv" "ac_cv_have_decl_getenv" "$ac_includes_default"
+if test "x$ac_cv_have_decl_getenv" = x""yes; then :
+ ac_have_decl=1
+else
+ ac_have_decl=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_GETENV $ac_have_decl
+_ACEOF
+
+ac_fn_c_check_decl "$LINENO" "malloc" "ac_cv_have_decl_malloc" "$ac_includes_default"
+if test "x$ac_cv_have_decl_malloc" = x""yes; then :
+ ac_have_decl=1
+else
+ ac_have_decl=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_MALLOC $ac_have_decl
+_ACEOF
+
+ac_fn_c_check_decl "$LINENO" "realloc" "ac_cv_have_decl_realloc" "$ac_includes_default"
+if test "x$ac_cv_have_decl_realloc" = x""yes; then :
+ ac_have_decl=1
+else
+ ac_have_decl=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_REALLOC $ac_have_decl
+_ACEOF
+
+ac_fn_c_check_decl "$LINENO" "stpcpy" "ac_cv_have_decl_stpcpy" "$ac_includes_default"
+if test "x$ac_cv_have_decl_stpcpy" = x""yes; then :
+ ac_have_decl=1
+else
+ ac_have_decl=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_STPCPY $ac_have_decl
+_ACEOF
+
+ac_fn_c_check_decl "$LINENO" "strstr" "ac_cv_have_decl_strstr" "$ac_includes_default"
+if test "x$ac_cv_have_decl_strstr" = x""yes; then :
+ ac_have_decl=1
+else
+ ac_have_decl=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_STRSTR $ac_have_decl
+_ACEOF
+
+ac_fn_c_check_decl "$LINENO" "snprintf" "ac_cv_have_decl_snprintf" "$ac_includes_default"
+if test "x$ac_cv_have_decl_snprintf" = x""yes; then :
+ ac_have_decl=1
+else
+ ac_have_decl=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_SNPRINTF $ac_have_decl
+_ACEOF
+
+ac_fn_c_check_decl "$LINENO" "vsnprintf" "ac_cv_have_decl_vsnprintf" "$ac_includes_default"
+if test "x$ac_cv_have_decl_vsnprintf" = x""yes; then :
+ ac_have_decl=1
+else
+ ac_have_decl=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_VSNPRINTF $ac_have_decl
+_ACEOF
+
+ac_fn_c_check_decl "$LINENO" "strnlen" "ac_cv_have_decl_strnlen" "$ac_includes_default"
+if test "x$ac_cv_have_decl_strnlen" = x""yes; then :
+ ac_have_decl=1
+else
+ ac_have_decl=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_STRNLEN $ac_have_decl
+_ACEOF
+
+
+# Link in zlib if we can. This allows us to read compressed debug sections.
+# This is used only by compress.c.
+
+ # See if the user specified whether he wants zlib support or not.
+
+# Check whether --with-zlib was given.
+if test "${with_zlib+set}" = set; then :
+ withval=$with_zlib;
+else
+ with_zlib=auto
+fi
+
+
+ if test "$with_zlib" != "no"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing zlibVersion" >&5
+$as_echo_n "checking for library containing zlibVersion... " >&6; }
+if test "${ac_cv_search_zlibVersion+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_func_search_save_LIBS=$LIBS
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char zlibVersion ();
+int
+main ()
+{
+return zlibVersion ();
+ ;
+ return 0;
+}
+_ACEOF
+for ac_lib in '' z; do
+ if test -z "$ac_lib"; then
+ ac_res="none required"
+ else
+ ac_res=-l$ac_lib
+ LIBS="-l$ac_lib $ac_func_search_save_LIBS"
+ fi
+ if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_search_zlibVersion=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext
+ if test "${ac_cv_search_zlibVersion+set}" = set; then :
+ break
+fi
+done
+if test "${ac_cv_search_zlibVersion+set}" = set; then :
+
+else
+ ac_cv_search_zlibVersion=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_zlibVersion" >&5
+$as_echo "$ac_cv_search_zlibVersion" >&6; }
+ac_res=$ac_cv_search_zlibVersion
+if test "$ac_res" != no; then :
+ test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+ for ac_header in zlib.h
+do :
+ ac_fn_c_check_header_mongrel "$LINENO" "zlib.h" "ac_cv_header_zlib_h" "$ac_includes_default"
+if test "x$ac_cv_header_zlib_h" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_ZLIB_H 1
+_ACEOF
+
+fi
+
+done
+
+fi
+
+ if test "$with_zlib" = "yes" -a "$ac_cv_header_zlib_h" != "yes"; then
+ as_fn_error "zlib (libz) library was explicitly requested but not found" "$LINENO" 5
+ fi
+ fi
+
+
+# If we are configured native, pick a core file support file.
+COREFILE=
+COREFLAG=
+CORE_HEADER=
+TRAD_HEADER=
+if test "${target}" = "${host}"; then
+ case "${host}" in
+ alpha*-*-freebsd* | alpha*-*-kfreebsd*-gnu | alpha*-*-*vms*)
+ COREFILE=''
+ ;;
+ alpha*-*-linux-*)
+ COREFILE=trad-core.lo
+ TRAD_HEADER='"hosts/alphalinux.h"'
+ ;;
+ alpha*-*-netbsd* | alpha*-*-openbsd*)
+ COREFILE=netbsd-core.lo
+ ;;
+ alpha*-*-*)
+ COREFILE=osf-core.lo
+ ;;
+ arm-*-freebsd* | arm-*-kfreebsd*-gnu)
+ COREFILE='' ;;
+ arm-*-netbsd* | arm-*-openbsd*)
+ COREFILE=netbsd-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" ;;
+ hppa*-*-netbsd* | hppa*-*-openbsd*)
+ COREFILE=netbsd-core.lo
+ ;;
+
+ i370-*-*)
+ COREFILE=trad-core.lo
+ TRAD_HEADER='"hosts/i370linux.h"'
+ ;;
+
+ i[3-7]86-sequent-bsd*)
+ COREFILE=trad-core.lo
+ TRAD_HEADER='"hosts/symmetry.h"'
+ ;;
+ i[3-7]86-sequent-sysv4*) ;;
+ i[3-7]86-sequent-sysv*)
+ COREFILE=trad-core.lo
+ TRAD_HEADER='"hosts/symmetry.h"'
+ ;;
+ i[3-7]86-*-bsdi)
+ COREFILE=
+ ;;
+ i[3-7]86-*-bsd* | i[3-7]86-*-freebsd[123] | i[3-7]86-*-freebsd[123]\.* | i[3-7]86-*-freebsd4\.[01234] | i[3-7]86-*-freebsd4\.[01234]\.* | i[3-7]86-*-freebsd*aout*)
+ COREFILE=trad-core.lo
+ TRAD_HEADER='"hosts/i386bsd.h"'
+ ;;
+ i[3-7]86-*-freebsd* | i[3-7]86-*-kfreebsd*-gnu | i[3-7]86-*-dragonfly*)
+ COREFILE=''
+ TRAD_HEADER='"hosts/i386bsd.h"'
+ ;;
+ i[3-7]86-*-netbsd* | i[3-7]86-*-knetbsd*-gnu | i[3-7]86-*-openbsd*)
+ COREFILE=netbsd-core.lo
+ ;;
+ i[3-7]86-esix-sysv3*)
+ COREFILE=trad-core.lo
+ TRAD_HEADER='"hosts/esix.h"'
+ ;;
+ i[3-7]86-*-sco3.2v5*)
+ COREFILE=sco5-core.lo
+ ;;
+ i[3-7]86-*-sco* | i[3-7]86-*-isc*)
+ COREFILE=trad-core.lo
+ TRAD_HEADER='"hosts/i386sco.h"'
+ ;;
+ i[3-7]86-*-mach3*)
+ COREFILE=trad-core.lo
+ TRAD_HEADER='"hosts/i386mach3.h"'
+ ;;
+ i[3-7]86-*-linux-*)
+ COREFILE=trad-core.lo
+ TRAD_HEADER='"hosts/i386linux.h"'
+ case "$enable_targets"-"$want64" in
+ *x86_64-*linux*|*-true)
+ CORE_HEADER='"hosts/x86-64linux.h"'
+ esac
+ ;;
+ i[3-7]86-*-isc*) COREFILE=trad-core.lo ;;
+ i[3-7]86-*-aix*) COREFILE=aix386-core.lo ;;
+ i860-*-mach3* | i860-*-osf1*)
+ COREFILE=trad-core.lo
+ TRAD_HEADER='"hosts/i860mach3.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-*-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-*)
+ 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"'
+ ;;
+ m88*-*-openbsd*)
+ COREFILE=netbsd-core.lo
+ ;;
+ 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-*-aix[5-9].* | powerpc-*-aix[5-9].*)
+ COREFILE=rs6000-core.lo
+ COREFLAG="$COREFLAG -DAIX_5_CORE -DAIX_CORE_DUMPX_CORE"
+ ;;
+ rs6000-*-aix4.[3-9]* | powerpc-*-aix4.[3-9]*)
+ COREFILE=rs6000-core.lo
+ COREFLAG="$COREFLAG -DAIX_CORE_DUMPX_CORE"
+ # Not all versions of AIX with -DAIX_CORE_DUMPX_CORE
+ # have c_impl as a member of struct core_dumpx
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for c_impl in struct core_dumpx" >&5
+$as_echo_n "checking for c_impl in struct core_dumpx... " >&6; }
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <core.h>
+int
+main ()
+{
+struct core_dumpx c; c.c_impl = 0;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+$as_echo "#define HAVE_ST_C_IMPL 1" >>confdefs.h
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ;;
+ rs6000-*-aix4*) COREFILE=rs6000-core.lo ;;
+ rs6000-*-*) COREFILE=rs6000-core.lo ;;
+ powerpc-*-aix4*) COREFILE=rs6000-core.lo ;;
+ powerpc-*-aix*) COREFILE=rs6000-core.lo ;;
+ powerpc-*-beos*) ;;
+ powerpc-*-freebsd* | powerpc-*-kfreebsd*-gnu)
+ COREFILE='' ;;
+ powerpc-*-netbsd*) COREFILE=netbsd-core.lo ;;
+ powerpc-*-*bsd*) COREFILE=netbsd-core.lo ;;
+ s390*-*-*) COREFILE=trad-core.lo ;;
+ sh*-*-netbsd* | sh*-*-openbsd*)
+ COREFILE=netbsd-core.lo
+ ;;
+ sparc-*-netbsd* | sparc*-*-openbsd*)
+ COREFILE=netbsd-core.lo
+ ;;
+ tahoe-*-*)
+ COREFILE=trad-core.lo
+ TRAD_HEADER='"hosts/tahoe.h"'
+ ;;
+ vax-*-netbsd* | vax-*-openbsd*)
+ COREFILE=netbsd-core.lo
+ ;;
+ vax-*-ultrix2*)
+ COREFILE=trad-core.lo
+ TRAD_HEADER='"hosts/vaxult2.h"'
+ ;;
+ vax-*-ultrix*)
+ COREFILE=trad-core.lo
+ TRAD_HEADER='"hosts/vaxult2.h"'
+ ;;
+ vax-*-linux-*)
+ COREFILE=trad-core.lo
+ TRAD_HEADER='"hosts/vaxlinux.h"'
+ ;;
+ vax-*-*)
+ COREFILE=trad-core.lo
+ TRAD_HEADER='"hosts/vaxbsd.h"'
+ ;;
+ x86_64-*-linux*)
+ CORE_HEADER='"hosts/x86-64linux.h"'
+ ;;
+ x86_64-*-netbsd* | x86_64-*-openbsd*)
+ COREFILE=netbsd-core.lo
+ ;;
+ 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_header in sys/procfs.h
+do :
+ ac_fn_c_check_header_mongrel "$LINENO" "sys/procfs.h" "ac_cv_header_sys_procfs_h" "$ac_includes_default"
+if test "x$ac_cv_header_sys_procfs_h" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_SYS_PROCFS_H 1
+_ACEOF
+
+fi
+
+done
+
+ if test "$ac_cv_header_sys_procfs_h" = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for prstatus_t in sys/procfs.h" >&5
+$as_echo_n "checking for prstatus_t in sys/procfs.h... " >&6; }
+ if test "${bfd_cv_have_sys_procfs_type_prstatus_t+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#define _SYSCALL32
+/* Needed for new procfs interface on sparc-solaris. */
+#define _STRUCTURED_PROC 1
+#include <sys/procfs.h>
+int
+main ()
+{
+prstatus_t avar
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ bfd_cv_have_sys_procfs_type_prstatus_t=yes
+else
+ bfd_cv_have_sys_procfs_type_prstatus_t=no
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+ if test $bfd_cv_have_sys_procfs_type_prstatus_t = yes; then
+
+$as_echo "#define HAVE_PRSTATUS_T 1" >>confdefs.h
+
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $bfd_cv_have_sys_procfs_type_prstatus_t" >&5
+$as_echo "$bfd_cv_have_sys_procfs_type_prstatus_t" >&6; }
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for prstatus32_t in sys/procfs.h" >&5
+$as_echo_n "checking for prstatus32_t in sys/procfs.h... " >&6; }
+ if test "${bfd_cv_have_sys_procfs_type_prstatus32_t+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#define _SYSCALL32
+/* Needed for new procfs interface on sparc-solaris. */
+#define _STRUCTURED_PROC 1
+#include <sys/procfs.h>
+int
+main ()
+{
+prstatus32_t avar
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ bfd_cv_have_sys_procfs_type_prstatus32_t=yes
+else
+ bfd_cv_have_sys_procfs_type_prstatus32_t=no
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+ if test $bfd_cv_have_sys_procfs_type_prstatus32_t = yes; then
+
+$as_echo "#define HAVE_PRSTATUS32_T 1" >>confdefs.h
+
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $bfd_cv_have_sys_procfs_type_prstatus32_t" >&5
+$as_echo "$bfd_cv_have_sys_procfs_type_prstatus32_t" >&6; }
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for prstatus_t.pr_who in sys/procfs.h" >&5
+$as_echo_n "checking for prstatus_t.pr_who in sys/procfs.h... " >&6; }
+ if test "${bfd_cv_have_sys_procfs_type_member_prstatus_t_pr_who+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#define _SYSCALL32
+/* Needed for new procfs interface on sparc-solaris. */
+#define _STRUCTURED_PROC 1
+#include <sys/procfs.h>
+int
+main ()
+{
+prstatus_t avar; void* aref = (void*) &avar.pr_who
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ bfd_cv_have_sys_procfs_type_member_prstatus_t_pr_who=yes
+else
+ bfd_cv_have_sys_procfs_type_member_prstatus_t_pr_who=no
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+ if test $bfd_cv_have_sys_procfs_type_member_prstatus_t_pr_who = yes; then
+
+$as_echo "#define HAVE_PRSTATUS_T_PR_WHO 1" >>confdefs.h
+
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $bfd_cv_have_sys_procfs_type_member_prstatus_t_pr_who" >&5
+$as_echo "$bfd_cv_have_sys_procfs_type_member_prstatus_t_pr_who" >&6; }
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for prstatus32_t.pr_who in sys/procfs.h" >&5
+$as_echo_n "checking for prstatus32_t.pr_who in sys/procfs.h... " >&6; }
+ if test "${bfd_cv_have_sys_procfs_type_member_prstatus32_t_pr_who+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#define _SYSCALL32
+/* Needed for new procfs interface on sparc-solaris. */
+#define _STRUCTURED_PROC 1
+#include <sys/procfs.h>
+int
+main ()
+{
+prstatus32_t avar; void* aref = (void*) &avar.pr_who
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ bfd_cv_have_sys_procfs_type_member_prstatus32_t_pr_who=yes
+else
+ bfd_cv_have_sys_procfs_type_member_prstatus32_t_pr_who=no
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+ if test $bfd_cv_have_sys_procfs_type_member_prstatus32_t_pr_who = yes; then
+
+$as_echo "#define HAVE_PRSTATUS32_T_PR_WHO 1" >>confdefs.h
+
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $bfd_cv_have_sys_procfs_type_member_prstatus32_t_pr_who" >&5
+$as_echo "$bfd_cv_have_sys_procfs_type_member_prstatus32_t_pr_who" >&6; }
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pstatus_t in sys/procfs.h" >&5
+$as_echo_n "checking for pstatus_t in sys/procfs.h... " >&6; }
+ if test "${bfd_cv_have_sys_procfs_type_pstatus_t+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#define _SYSCALL32
+/* Needed for new procfs interface on sparc-solaris. */
+#define _STRUCTURED_PROC 1
+#include <sys/procfs.h>
+int
+main ()
+{
+pstatus_t avar
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ bfd_cv_have_sys_procfs_type_pstatus_t=yes
+else
+ bfd_cv_have_sys_procfs_type_pstatus_t=no
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+ if test $bfd_cv_have_sys_procfs_type_pstatus_t = yes; then
+
+$as_echo "#define HAVE_PSTATUS_T 1" >>confdefs.h
+
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $bfd_cv_have_sys_procfs_type_pstatus_t" >&5
+$as_echo "$bfd_cv_have_sys_procfs_type_pstatus_t" >&6; }
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pxstatus_t in sys/procfs.h" >&5
+$as_echo_n "checking for pxstatus_t in sys/procfs.h... " >&6; }
+ if test "${bfd_cv_have_sys_procfs_type_pxstatus_t+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#define _SYSCALL32
+/* Needed for new procfs interface on sparc-solaris. */
+#define _STRUCTURED_PROC 1
+#include <sys/procfs.h>
+int
+main ()
+{
+pxstatus_t avar
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ bfd_cv_have_sys_procfs_type_pxstatus_t=yes
+else
+ bfd_cv_have_sys_procfs_type_pxstatus_t=no
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+ if test $bfd_cv_have_sys_procfs_type_pxstatus_t = yes; then
+
+$as_echo "#define HAVE_PXSTATUS_T 1" >>confdefs.h
+
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $bfd_cv_have_sys_procfs_type_pxstatus_t" >&5
+$as_echo "$bfd_cv_have_sys_procfs_type_pxstatus_t" >&6; }
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pstatus32_t in sys/procfs.h" >&5
+$as_echo_n "checking for pstatus32_t in sys/procfs.h... " >&6; }
+ if test "${bfd_cv_have_sys_procfs_type_pstatus32_t+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#define _SYSCALL32
+/* Needed for new procfs interface on sparc-solaris. */
+#define _STRUCTURED_PROC 1
+#include <sys/procfs.h>
+int
+main ()
+{
+pstatus32_t avar
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ bfd_cv_have_sys_procfs_type_pstatus32_t=yes
+else
+ bfd_cv_have_sys_procfs_type_pstatus32_t=no
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+ if test $bfd_cv_have_sys_procfs_type_pstatus32_t = yes; then
+
+$as_echo "#define HAVE_PSTATUS32_T 1" >>confdefs.h
+
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $bfd_cv_have_sys_procfs_type_pstatus32_t" >&5
+$as_echo "$bfd_cv_have_sys_procfs_type_pstatus32_t" >&6; }
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for prpsinfo_t in sys/procfs.h" >&5
+$as_echo_n "checking for prpsinfo_t in sys/procfs.h... " >&6; }
+ if test "${bfd_cv_have_sys_procfs_type_prpsinfo_t+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#define _SYSCALL32
+/* Needed for new procfs interface on sparc-solaris. */
+#define _STRUCTURED_PROC 1
+#include <sys/procfs.h>
+int
+main ()
+{
+prpsinfo_t avar
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ bfd_cv_have_sys_procfs_type_prpsinfo_t=yes
+else
+ bfd_cv_have_sys_procfs_type_prpsinfo_t=no
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+ if test $bfd_cv_have_sys_procfs_type_prpsinfo_t = yes; then
+
+$as_echo "#define HAVE_PRPSINFO_T 1" >>confdefs.h
+
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $bfd_cv_have_sys_procfs_type_prpsinfo_t" >&5
+$as_echo "$bfd_cv_have_sys_procfs_type_prpsinfo_t" >&6; }
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for prpsinfo_t.pr_pid in sys/procfs.h" >&5
+$as_echo_n "checking for prpsinfo_t.pr_pid in sys/procfs.h... " >&6; }
+ if test "${bfd_cv_have_sys_procfs_type_member_prpsinfo_t_pr_pid+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#define _SYSCALL32
+/* Needed for new procfs interface on sparc-solaris. */
+#define _STRUCTURED_PROC 1
+#include <sys/procfs.h>
+int
+main ()
+{
+prpsinfo_t avar; void* aref = (void*) &avar.pr_pid
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ bfd_cv_have_sys_procfs_type_member_prpsinfo_t_pr_pid=yes
+else
+ bfd_cv_have_sys_procfs_type_member_prpsinfo_t_pr_pid=no
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+ if test $bfd_cv_have_sys_procfs_type_member_prpsinfo_t_pr_pid = yes; then
+
+$as_echo "#define HAVE_PRPSINFO_T_PR_PID 1" >>confdefs.h
+
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $bfd_cv_have_sys_procfs_type_member_prpsinfo_t_pr_pid" >&5
+$as_echo "$bfd_cv_have_sys_procfs_type_member_prpsinfo_t_pr_pid" >&6; }
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for prpsinfo32_t in sys/procfs.h" >&5
+$as_echo_n "checking for prpsinfo32_t in sys/procfs.h... " >&6; }
+ if test "${bfd_cv_have_sys_procfs_type_prpsinfo32_t+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#define _SYSCALL32
+/* Needed for new procfs interface on sparc-solaris. */
+#define _STRUCTURED_PROC 1
+#include <sys/procfs.h>
+int
+main ()
+{
+prpsinfo32_t avar
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ bfd_cv_have_sys_procfs_type_prpsinfo32_t=yes
+else
+ bfd_cv_have_sys_procfs_type_prpsinfo32_t=no
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+ if test $bfd_cv_have_sys_procfs_type_prpsinfo32_t = yes; then
+
+$as_echo "#define HAVE_PRPSINFO32_T 1" >>confdefs.h
+
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $bfd_cv_have_sys_procfs_type_prpsinfo32_t" >&5
+$as_echo "$bfd_cv_have_sys_procfs_type_prpsinfo32_t" >&6; }
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for prpsinfo32_t.pr_pid in sys/procfs.h" >&5
+$as_echo_n "checking for prpsinfo32_t.pr_pid in sys/procfs.h... " >&6; }
+ if test "${bfd_cv_have_sys_procfs_type_member_prpsinfo32_t_pr_pid+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#define _SYSCALL32
+/* Needed for new procfs interface on sparc-solaris. */
+#define _STRUCTURED_PROC 1
+#include <sys/procfs.h>
+int
+main ()
+{
+prpsinfo32_t avar; void* aref = (void*) &avar.pr_pid
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ bfd_cv_have_sys_procfs_type_member_prpsinfo32_t_pr_pid=yes
+else
+ bfd_cv_have_sys_procfs_type_member_prpsinfo32_t_pr_pid=no
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+ if test $bfd_cv_have_sys_procfs_type_member_prpsinfo32_t_pr_pid = yes; then
+
+$as_echo "#define HAVE_PRPSINFO32_T_PR_PID 1" >>confdefs.h
+
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $bfd_cv_have_sys_procfs_type_member_prpsinfo32_t_pr_pid" >&5
+$as_echo "$bfd_cv_have_sys_procfs_type_member_prpsinfo32_t_pr_pid" >&6; }
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for psinfo_t in sys/procfs.h" >&5
+$as_echo_n "checking for psinfo_t in sys/procfs.h... " >&6; }
+ if test "${bfd_cv_have_sys_procfs_type_psinfo_t+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#define _SYSCALL32
+/* Needed for new procfs interface on sparc-solaris. */
+#define _STRUCTURED_PROC 1
+#include <sys/procfs.h>
+int
+main ()
+{
+psinfo_t avar
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ bfd_cv_have_sys_procfs_type_psinfo_t=yes
+else
+ bfd_cv_have_sys_procfs_type_psinfo_t=no
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+ if test $bfd_cv_have_sys_procfs_type_psinfo_t = yes; then
+
+$as_echo "#define HAVE_PSINFO_T 1" >>confdefs.h
+
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $bfd_cv_have_sys_procfs_type_psinfo_t" >&5
+$as_echo "$bfd_cv_have_sys_procfs_type_psinfo_t" >&6; }
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for psinfo_t.pr_pid in sys/procfs.h" >&5
+$as_echo_n "checking for psinfo_t.pr_pid in sys/procfs.h... " >&6; }
+ if test "${bfd_cv_have_sys_procfs_type_member_psinfo_t_pr_pid+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#define _SYSCALL32
+/* Needed for new procfs interface on sparc-solaris. */
+#define _STRUCTURED_PROC 1
+#include <sys/procfs.h>
+int
+main ()
+{
+psinfo_t avar; void* aref = (void*) &avar.pr_pid
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ bfd_cv_have_sys_procfs_type_member_psinfo_t_pr_pid=yes
+else
+ bfd_cv_have_sys_procfs_type_member_psinfo_t_pr_pid=no
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+ if test $bfd_cv_have_sys_procfs_type_member_psinfo_t_pr_pid = yes; then
+
+$as_echo "#define HAVE_PSINFO_T_PR_PID 1" >>confdefs.h
+
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $bfd_cv_have_sys_procfs_type_member_psinfo_t_pr_pid" >&5
+$as_echo "$bfd_cv_have_sys_procfs_type_member_psinfo_t_pr_pid" >&6; }
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for psinfo32_t in sys/procfs.h" >&5
+$as_echo_n "checking for psinfo32_t in sys/procfs.h... " >&6; }
+ if test "${bfd_cv_have_sys_procfs_type_psinfo32_t+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#define _SYSCALL32
+/* Needed for new procfs interface on sparc-solaris. */
+#define _STRUCTURED_PROC 1
+#include <sys/procfs.h>
+int
+main ()
+{
+psinfo32_t avar
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ bfd_cv_have_sys_procfs_type_psinfo32_t=yes
+else
+ bfd_cv_have_sys_procfs_type_psinfo32_t=no
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+ if test $bfd_cv_have_sys_procfs_type_psinfo32_t = yes; then
+
+$as_echo "#define HAVE_PSINFO32_T 1" >>confdefs.h
+
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $bfd_cv_have_sys_procfs_type_psinfo32_t" >&5
+$as_echo "$bfd_cv_have_sys_procfs_type_psinfo32_t" >&6; }
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for psinfo32_t.pr_pid in sys/procfs.h" >&5
+$as_echo_n "checking for psinfo32_t.pr_pid in sys/procfs.h... " >&6; }
+ if test "${bfd_cv_have_sys_procfs_type_member_psinfo32_t_pr_pid+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#define _SYSCALL32
+/* Needed for new procfs interface on sparc-solaris. */
+#define _STRUCTURED_PROC 1
+#include <sys/procfs.h>
+int
+main ()
+{
+psinfo32_t avar; void* aref = (void*) &avar.pr_pid
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ bfd_cv_have_sys_procfs_type_member_psinfo32_t_pr_pid=yes
+else
+ bfd_cv_have_sys_procfs_type_member_psinfo32_t_pr_pid=no
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+ if test $bfd_cv_have_sys_procfs_type_member_psinfo32_t_pr_pid = yes; then
+
+$as_echo "#define HAVE_PSINFO32_T_PR_PID 1" >>confdefs.h
+
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $bfd_cv_have_sys_procfs_type_member_psinfo32_t_pr_pid" >&5
+$as_echo "$bfd_cv_have_sys_procfs_type_member_psinfo32_t_pr_pid" >&6; }
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for lwpstatus_t in sys/procfs.h" >&5
+$as_echo_n "checking for lwpstatus_t in sys/procfs.h... " >&6; }
+ if test "${bfd_cv_have_sys_procfs_type_lwpstatus_t+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#define _SYSCALL32
+/* Needed for new procfs interface on sparc-solaris. */
+#define _STRUCTURED_PROC 1
+#include <sys/procfs.h>
+int
+main ()
+{
+lwpstatus_t avar
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ bfd_cv_have_sys_procfs_type_lwpstatus_t=yes
+else
+ bfd_cv_have_sys_procfs_type_lwpstatus_t=no
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+ if test $bfd_cv_have_sys_procfs_type_lwpstatus_t = yes; then
+
+$as_echo "#define HAVE_LWPSTATUS_T 1" >>confdefs.h
+
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $bfd_cv_have_sys_procfs_type_lwpstatus_t" >&5
+$as_echo "$bfd_cv_have_sys_procfs_type_lwpstatus_t" >&6; }
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for lwpxstatus_t in sys/procfs.h" >&5
+$as_echo_n "checking for lwpxstatus_t in sys/procfs.h... " >&6; }
+ if test "${bfd_cv_have_sys_procfs_type_lwpxstatus_t+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#define _SYSCALL32
+/* Needed for new procfs interface on sparc-solaris. */
+#define _STRUCTURED_PROC 1
+#include <sys/procfs.h>
+int
+main ()
+{
+lwpxstatus_t avar
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ bfd_cv_have_sys_procfs_type_lwpxstatus_t=yes
+else
+ bfd_cv_have_sys_procfs_type_lwpxstatus_t=no
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+ if test $bfd_cv_have_sys_procfs_type_lwpxstatus_t = yes; then
+
+$as_echo "#define HAVE_LWPXSTATUS_T 1" >>confdefs.h
+
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $bfd_cv_have_sys_procfs_type_lwpxstatus_t" >&5
+$as_echo "$bfd_cv_have_sys_procfs_type_lwpxstatus_t" >&6; }
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for lwpstatus_t.pr_context in sys/procfs.h" >&5
+$as_echo_n "checking for lwpstatus_t.pr_context in sys/procfs.h... " >&6; }
+ if test "${bfd_cv_have_sys_procfs_type_member_lwpstatus_t_pr_context+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#define _SYSCALL32
+/* Needed for new procfs interface on sparc-solaris. */
+#define _STRUCTURED_PROC 1
+#include <sys/procfs.h>
+int
+main ()
+{
+lwpstatus_t avar; void* aref = (void*) &avar.pr_context
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ bfd_cv_have_sys_procfs_type_member_lwpstatus_t_pr_context=yes
+else
+ bfd_cv_have_sys_procfs_type_member_lwpstatus_t_pr_context=no
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+ if test $bfd_cv_have_sys_procfs_type_member_lwpstatus_t_pr_context = yes; then
+
+$as_echo "#define HAVE_LWPSTATUS_T_PR_CONTEXT 1" >>confdefs.h
+
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $bfd_cv_have_sys_procfs_type_member_lwpstatus_t_pr_context" >&5
+$as_echo "$bfd_cv_have_sys_procfs_type_member_lwpstatus_t_pr_context" >&6; }
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for lwpstatus_t.pr_reg in sys/procfs.h" >&5
+$as_echo_n "checking for lwpstatus_t.pr_reg in sys/procfs.h... " >&6; }
+ if test "${bfd_cv_have_sys_procfs_type_member_lwpstatus_t_pr_reg+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#define _SYSCALL32
+/* Needed for new procfs interface on sparc-solaris. */
+#define _STRUCTURED_PROC 1
+#include <sys/procfs.h>
+int
+main ()
+{
+lwpstatus_t avar; void* aref = (void*) &avar.pr_reg
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ bfd_cv_have_sys_procfs_type_member_lwpstatus_t_pr_reg=yes
+else
+ bfd_cv_have_sys_procfs_type_member_lwpstatus_t_pr_reg=no
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+ if test $bfd_cv_have_sys_procfs_type_member_lwpstatus_t_pr_reg = yes; then
+
+$as_echo "#define HAVE_LWPSTATUS_T_PR_REG 1" >>confdefs.h
+
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $bfd_cv_have_sys_procfs_type_member_lwpstatus_t_pr_reg" >&5
+$as_echo "$bfd_cv_have_sys_procfs_type_member_lwpstatus_t_pr_reg" >&6; }
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for lwpstatus_t.pr_fpreg in sys/procfs.h" >&5
+$as_echo_n "checking for lwpstatus_t.pr_fpreg in sys/procfs.h... " >&6; }
+ if test "${bfd_cv_have_sys_procfs_type_member_lwpstatus_t_pr_fpreg+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#define _SYSCALL32
+/* Needed for new procfs interface on sparc-solaris. */
+#define _STRUCTURED_PROC 1
+#include <sys/procfs.h>
+int
+main ()
+{
+lwpstatus_t avar; void* aref = (void*) &avar.pr_fpreg
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ bfd_cv_have_sys_procfs_type_member_lwpstatus_t_pr_fpreg=yes
+else
+ bfd_cv_have_sys_procfs_type_member_lwpstatus_t_pr_fpreg=no
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+ if test $bfd_cv_have_sys_procfs_type_member_lwpstatus_t_pr_fpreg = yes; then
+
+$as_echo "#define HAVE_LWPSTATUS_T_PR_FPREG 1" >>confdefs.h
+
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $bfd_cv_have_sys_procfs_type_member_lwpstatus_t_pr_fpreg" >&5
+$as_echo "$bfd_cv_have_sys_procfs_type_member_lwpstatus_t_pr_fpreg" >&6; }
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for win32_pstatus_t in sys/procfs.h" >&5
+$as_echo_n "checking for win32_pstatus_t in sys/procfs.h... " >&6; }
+ if test "${bfd_cv_have_sys_procfs_type_win32_pstatus_t+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#define _SYSCALL32
+/* Needed for new procfs interface on sparc-solaris. */
+#define _STRUCTURED_PROC 1
+#include <sys/procfs.h>
+int
+main ()
+{
+win32_pstatus_t avar
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ bfd_cv_have_sys_procfs_type_win32_pstatus_t=yes
+else
+ bfd_cv_have_sys_procfs_type_win32_pstatus_t=no
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+ if test $bfd_cv_have_sys_procfs_type_win32_pstatus_t = yes; then
+
+$as_echo "#define HAVE_WIN32_PSTATUS_T 1" >>confdefs.h
+
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $bfd_cv_have_sys_procfs_type_win32_pstatus_t" >&5
+$as_echo "$bfd_cv_have_sys_procfs_type_win32_pstatus_t" >&6; }
+
+ fi
+fi
+
+
+if test -n "$CORE_HEADER"; then
+
+cat >>confdefs.h <<_ACEOF
+#define CORE_HEADER $CORE_HEADER
+_ACEOF
+
+fi
+if test -n "$TRAD_HEADER"; then
+
+cat >>confdefs.h <<_ACEOF
+#define TRAD_HEADER $TRAD_HEADER
+_ACEOF
+
+fi
+
+# Check if linker supports --as-needed and --no-as-needed options
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking linker --as-needed support" >&5
+$as_echo_n "checking linker --as-needed support... " >&6; }
+if test "${bfd_cv_ld_as_needed+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ bfd_cv_ld_as_needed=no
+ if $LD --help 2>/dev/null | grep as-needed > /dev/null; then
+ bfd_cv_ld_as_needed=yes
+ fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $bfd_cv_ld_as_needed" >&5
+$as_echo "$bfd_cv_ld_as_needed" >&6; }
+
+LIBM=
+case $host in
+*-*-beos* | *-*-cegcc* | *-*-cygwin* | *-*-haiku* | *-*-pw32* | *-*-darwin*)
+ # These system don't have libm, or don't need it
+ ;;
+*-ncr-sysv4.3*)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _mwvalidcheckl in -lmw" >&5
+$as_echo_n "checking for _mwvalidcheckl in -lmw... " >&6; }
+if test "${ac_cv_lib_mw__mwvalidcheckl+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lmw $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char _mwvalidcheckl ();
+int
+main ()
+{
+return _mwvalidcheckl ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_mw__mwvalidcheckl=yes
+else
+ ac_cv_lib_mw__mwvalidcheckl=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_mw__mwvalidcheckl" >&5
+$as_echo "$ac_cv_lib_mw__mwvalidcheckl" >&6; }
+if test "x$ac_cv_lib_mw__mwvalidcheckl" = x""yes; then :
+ LIBM="-lmw"
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for cos in -lm" >&5
+$as_echo_n "checking for cos in -lm... " >&6; }
+if test "${ac_cv_lib_m_cos+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lm $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char cos ();
+int
+main ()
+{
+return cos ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_m_cos=yes
+else
+ ac_cv_lib_m_cos=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_cos" >&5
+$as_echo "$ac_cv_lib_m_cos" >&6; }
+if test "x$ac_cv_lib_m_cos" = x""yes; then :
+ LIBM="$LIBM -lm"
+fi
+
+ ;;
+*)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for cos in -lm" >&5
+$as_echo_n "checking for cos in -lm... " >&6; }
+if test "${ac_cv_lib_m_cos+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lm $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char cos ();
+int
+main ()
+{
+return cos ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_m_cos=yes
+else
+ ac_cv_lib_m_cos=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_cos" >&5
+$as_echo "$ac_cv_lib_m_cos" >&6; }
+if test "x$ac_cv_lib_m_cos" = x""yes; then :
+ LIBM="-lm"
+fi
+
+ ;;
+esac
+
+
+
+# When building a shared libbfd, link against the pic version of libiberty
+# so that apps that use libbfd won't need libiberty just to satisfy any
+# libbfd references.
+# We can't do that if a pic libiberty is unavailable since including non-pic
+# code would insert text relocations into libbfd.
+SHARED_LIBADD=
+SHARED_LDFLAGS=
+if test "$enable_shared" = "yes"; then
+ x=`sed -n -e 's/^[ ]*PICFLAG[ ]*=[ ]*//p' < ../libiberty/Makefile | sed -n '$p'`
+ if test -n "$x"; then
+ SHARED_LIBADD="-L`pwd`/../libiberty/pic -liberty"
+ fi
+
+# More hacks to build DLLs on Windows.
+ case "${host}" in
+ *-*-cygwin*)
+ SHARED_LDFLAGS="-no-undefined"
+ SHARED_LIBADD="-L`pwd`/../libiberty -liberty -L`pwd`/../intl -lintl -lcygwin -lkernel32"
+ ;;
+
+ # Hack to build or1k-src on OSX
+ or1k*-*-darwin*)
+ SHARED_LIBADD="-L`pwd`/../libiberty/pic -L`pwd`/../intl -liberty -lintl"
+ ;;
+ esac
+
+ if test -n "$SHARED_LIBADD"; then
+ if test -n "$LIBM"; then
+ if test x"$bfd_cv_ld_as_needed" = xyes; then
+ # Link against libm only when needed. Put -lc, -lm inside -Wl
+ # to stop libtool reordering these options.
+ SHARED_LIBADD="$SHARED_LIBADD -Wl,-lc,--as-needed,`echo $LIBM | sed 's/ /,/g'`,--no-as-needed"
+ else
+ SHARED_LIBADD="$SHARED_LIBADD $LIBM"
+ fi
+ fi
+ fi
+fi
+
+
+
+# target stuff:
+
+# Canonicalize the secondary target names.
+if test -n "$enable_targets" ; then
+ for targ in `echo $enable_targets | sed 's/,/ /g'`
+ do
+ result=`$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=
+assocvecs=
+selarchs=
+TDEFINES=
+for targ in $target $canon_targets
+do
+ if test "x$targ" = "xall"; then
+ all_targets=true
+ assocvecs="$assocvecs $targ_defvec $targ_selvecs"
+ 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 "--enable-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 associated vectors in all the configured targets.
+f=""
+for i in $assocvecs ; do
+ case " $f " in
+ *" $i "*) ;;
+ *) f="$f $i" ;;
+ esac
+done
+assocvecs="$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 elf-attrs.lo elf-strtab.lo
+ elf-eh-frame.lo dwarf1.lo"
+
+for vec in $selvecs
+do
+ target_size=32
+ case "$vec" in
+ # This list is alphabetized to make it easy to compare
+ # with the two vector lists in targets.c. For the same reason,
+ # use one entry per line, even though this leads to long lines.
+ aarch64_elf32_be_vec) tb="$tb elf32-aarch64.lo elfxx-aarch64.lo elf-ifunc.lo elf32.lo $elf"; target_size=64 ;;
+ aarch64_elf32_le_vec) tb="$tb elf32-aarch64.lo elfxx-aarch64.lo elf-ifunc.lo elf32.lo $elf"; target_size=64 ;;
+ aarch64_elf64_be_vec) tb="$tb elf64-aarch64.lo elfxx-aarch64.lo elf-ifunc.lo elf64.lo $elf"; target_size=64 ;;
+ aarch64_elf64_le_vec) tb="$tb elf64-aarch64.lo elfxx-aarch64.lo elf-ifunc.lo elf64.lo $elf"; target_size=64 ;;
+ alpha_ecoff_le_vec) tb="$tb coff-alpha.lo ecoff.lo ecofflink.lo"; target_size=64 ;;
+ alpha_elf64_vec) tb="$tb elf64-alpha.lo elf64.lo $elf"; target_size=64 ;;
+ alpha_elf64_fbsd_vec) tb="$tb elf64-alpha.lo elf64.lo $elf"; target_size=64 ;;
+ alpha_nlm32_vec) tb="$tb nlm32-alpha.lo nlm32.lo nlm.lo"; target_size=64 ;;
+ alpha_vms_vec) tb="$tb vms-alpha.lo vms-misc.lo vms-lib.lo"; target_size=64 ;;
+ alpha_vms_lib_txt_vec) tb="$tb vms-lib.lo vms-misc.lo" ;;
+ am33_elf32_linux_vec) tb="$tb elf32-am33lin.lo elf32.lo $elf" ;;
+ aout0_be_vec) tb="$tb aout0.lo aout32.lo" ;;
+ aout64_vec) tb="$tb demo64.lo aout64.lo"; target_size=64 ;;
+ aout_vec) tb="$tb host-aout.lo aout32.lo" ;;
+ aout_adobe_vec) tb="$tb aout-adobe.lo aout32.lo" ;;
+ arc_elf32_be_vec) tb="$tb elf32-arc.lo elf32.lo $elf" ;;
+ arc_elf32_le_vec) tb="$tb elf32-arc.lo elf32.lo $elf" ;;
+ arm_aout_be_vec) tb="$tb aout-arm.lo aout32.lo" ;;
+ arm_aout_le_vec) tb="$tb aout-arm.lo aout32.lo" ;;
+ arm_aout_nbsd_vec) tb="$tb armnetbsd.lo aout32.lo" ;;
+ arm_aout_riscix_vec) tb="$tb aout32.lo riscix.lo" ;;
+ arm_coff_be_vec) tb="$tb coff-arm.lo cofflink.lo " ;;
+ arm_coff_le_vec) tb="$tb coff-arm.lo cofflink.lo " ;;
+ arm_elf32_be_vec) tb="$tb elf32-arm.lo elf32.lo elf-nacl.lo elf-vxworks.lo $elf" ;;
+ arm_elf32_le_vec) tb="$tb elf32-arm.lo elf32.lo elf-nacl.lo elf-vxworks.lo $elf" ;;
+ arm_elf32_nacl_be_vec) tb="$tb elf32-arm.lo elf32.lo elf-nacl.lo elf-vxworks.lo $elf" ;;
+ arm_elf32_nacl_le_vec) tb="$tb elf32-arm.lo elf32.lo elf-nacl.lo elf-vxworks.lo $elf" ;;
+ arm_elf32_symbian_be_vec) tb="$tb elf32-arm.lo elf32.lo elf-nacl.lo elf-vxworks.lo $elf" ;;
+ arm_elf32_symbian_le_vec) tb="$tb elf32-arm.lo elf32.lo elf-nacl.lo elf-vxworks.lo $elf" ;;
+ arm_elf32_vxworks_be_vec) tb="$tb elf32-arm.lo elf32.lo elf-nacl.lo elf-vxworks.lo $elf" ;;
+ arm_elf32_vxworks_le_vec) tb="$tb elf32-arm.lo elf32.lo elf-nacl.lo elf-vxworks.lo $elf" ;;
+ arm_pe_be_vec) tb="$tb pe-arm.lo peigen.lo cofflink.lo " ;;
+ arm_pe_le_vec) tb="$tb pe-arm.lo peigen.lo cofflink.lo " ;;
+ arm_pe_epoc_be_vec) tb="$tb epoc-pe-arm.lo peigen.lo cofflink.lo " ;;
+ arm_pe_epoc_le_vec) tb="$tb epoc-pe-arm.lo peigen.lo cofflink.lo " ;;
+ arm_pe_wince_be_vec) tb="$tb pe-arm-wince.lo pe-arm.lo peigen.lo cofflink.lo " ;;
+ arm_pe_wince_le_vec) tb="$tb pe-arm-wince.lo pe-arm.lo peigen.lo cofflink.lo " ;;
+ arm_pei_be_vec) tb="$tb pei-arm.lo peigen.lo cofflink.lo " ;;
+ arm_pei_le_vec) tb="$tb pei-arm.lo peigen.lo cofflink.lo " ;;
+ arm_pei_epoc_be_vec) tb="$tb epoc-pei-arm.lo peigen.lo cofflink.lo " ;;
+ arm_pei_epoc_le_vec) tb="$tb epoc-pei-arm.lo peigen.lo cofflink.lo " ;;
+ arm_pei_wince_be_vec) tb="$tb pei-arm-wince.lo pei-arm.lo peigen.lo cofflink.lo " ;;
+ arm_pei_wince_le_vec) tb="$tb pei-arm-wince.lo pei-arm.lo peigen.lo cofflink.lo " ;;
+ avr_elf32_vec) tb="$tb elf32-avr.lo elf32.lo $elf" ;;
+ bfin_elf32_vec) tb="$tb elf32-bfin.lo elf32.lo $elf" ;;
+ bfin_elf32_fdpic_vec) tb="$tb elf32-bfin.lo elf32.lo $elf" ;;
+ bout_be_vec) tb="$tb bout.lo aout32.lo" ;;
+ bout_le_vec) tb="$tb bout.lo aout32.lo" ;;
+ cr16_elf32_vec) tb="$tb elf32-cr16.lo elf32.lo $elf" ;;
+ cr16c_elf32_vec) tb="$tb elf32-cr16c.lo elf32.lo $elf" ;;
+ cris_aout_vec) tb="$tb aout-cris.lo" ;;
+ cris_elf32_vec) tb="$tb elf32-cris.lo elf32.lo $elf" ;;
+ cris_elf32_us_vec) tb="$tb elf32-cris.lo elf32.lo $elf" ;;
+ crx_elf32_vec) tb="$tb elf32-crx.lo elf32.lo $elf" ;;
+ d10v_elf32_vec) tb="$tb elf32-d10v.lo elf32.lo $elf" ;;
+ d30v_elf32_vec) tb="$tb elf32-d30v.lo elf32.lo $elf" ;;
+ dlx_elf32_be_vec) tb="$tb elf32-dlx.lo elf32.lo $elf" ;;
+ elf32_be_vec) tb="$tb elf32-gen.lo elf32.lo $elf" ;;
+ elf32_le_vec) tb="$tb elf32-gen.lo elf32.lo $elf" ;;
+ elf64_be_vec) tb="$tb elf64-gen.lo elf64.lo $elf"; target_size=64 ;;
+ elf64_le_vec) tb="$tb elf64-gen.lo elf64.lo $elf"; target_size=64 ;;
+ epiphany_elf32_vec) tb="$tb elf32-epiphany.lo elf32.lo $elf" ;;
+ fr30_elf32_vec) tb="$tb elf32-fr30.lo elf32.lo $elf" ;;
+ frv_elf32_vec) tb="$tb elf32-frv.lo elf32.lo $elf" ;;
+ frv_elf32_fdpic_vec) tb="$tb elf32-frv.lo elf32.lo $elf" ;;
+ h8300_coff_vec) tb="$tb coff-h8300.lo reloc16.lo" ;;
+ h8300_elf32_vec) tb="$tb elf32-h8300.lo elf32.lo $elf" ;;
+ h8500_coff_vec) tb="$tb coff-h8500.lo reloc16.lo" ;;
+ hppa_elf32_vec) tb="$tb elf32-hppa.lo elf32.lo $elf" ;;
+ hppa_elf32_linux_vec) tb="$tb elf32-hppa.lo elf32.lo $elf" ;;
+ hppa_elf32_nbsd_vec) tb="$tb elf32-hppa.lo elf32.lo $elf" ;;
+ hppa_elf64_vec) tb="$tb elf64-hppa.lo elf64.lo $elf"; target_size=64 ;;
+ hppa_elf64_linux_vec) tb="$tb elf64-hppa.lo elf64.lo $elf"; target_size=64 ;;
+ hppa_som_vec) tb="$tb som.lo" ;;
+ i370_elf32_vec) tb="$tb elf32-i370.lo elf32.lo $elf" ;;
+ i386_aout_vec) tb="$tb i386aout.lo aout32.lo" ;;
+ i386_aout_bsd_vec) tb="$tb i386bsd.lo aout32.lo" ;;
+ i386_aout_dynix_vec) tb="$tb i386dynix.lo aout32.lo" ;;
+ i386_aout_fbsd_vec) tb="$tb i386freebsd.lo aout32.lo" ;;
+ i386_aout_linux_vec) tb="$tb i386linux.lo aout32.lo" ;;
+ i386_aout_lynx_vec) tb="$tb i386lynx.lo lynx-core.lo aout32.lo" ;;
+ i386_aout_mach3_vec) tb="$tb i386mach3.lo aout32.lo" ;;
+ i386_aout_nbsd_vec) tb="$tb i386netbsd.lo aout32.lo" ;;
+ i386_aout_os9k_vec) tb="$tb i386os9k.lo aout32.lo" ;;
+ i386_coff_vec) tb="$tb coff-i386.lo cofflink.lo" ;;
+ i386_coff_go32_vec) tb="$tb coff-go32.lo cofflink.lo" ;;
+ i386_coff_go32stubbed_vec) tb="$tb coff-stgo32.lo cofflink.lo" ;;
+ i386_coff_lynx_vec) tb="$tb cf-i386lynx.lo cofflink.lo lynx-core.lo" ;;
+ i386_elf32_vec) tb="$tb elf32-i386.lo elf-ifunc.lo elf-nacl.lo elf-vxworks.lo elf32.lo $elf" ;;
+ i386_elf32_fbsd_vec) tb="$tb elf32-i386.lo elf-ifunc.lo elf-nacl.lo elf-vxworks.lo elf32.lo $elf" ;;
+ i386_elf32_nacl_vec) tb="$tb elf32-i386.lo elf-ifunc.lo elf-nacl.lo elf-vxworks.lo elf32.lo $elf" ;;
+ i386_elf32_sol2_vec) tb="$tb elf32-i386.lo elf-ifunc.lo elf-nacl.lo elf-vxworks.lo elf32.lo $elf" ;;
+ i386_elf32_vxworks_vec) tb="$tb elf32-i386.lo elf-ifunc.lo elf-nacl.lo elf-vxworks.lo elf32.lo $elf" ;;
+ i386_mach_o_vec) tb="$tb mach-o-i386.lo" ;;
+ i386_msdos_vec) tb="$tb i386msdos.lo" ;;
+ i386_nlm32_vec) tb="$tb nlm32-i386.lo nlm32.lo nlm.lo" ;;
+ i386_pe_vec) tb="$tb pe-i386.lo peigen.lo cofflink.lo" ;;
+ i386_pei_vec) tb="$tb pei-i386.lo peigen.lo cofflink.lo" ;;
+ i860_coff_vec) tb="$tb coff-i860.lo cofflink.lo" ;;
+ i860_elf32_vec) tb="$tb elf32-i860.lo elf32.lo $elf" ;;
+ i860_elf32_le_vec) tb="$tb elf32-i860.lo elf32.lo $elf" ;;
+ i960_elf32_vec) tb="$tb elf32-i960.lo elf32.lo $elf" ;;
+ ia64_elf32_be_vec) tb="$tb elf32-ia64.lo elfxx-ia64.lo elf32.lo $elf" ;;
+ ia64_elf32_hpux_be_vec) tb="$tb elf32-ia64.lo elfxx-ia64.lo elf32.lo $elf" ;;
+ ia64_elf64_be_vec) tb="$tb elf64-ia64.lo elfxx-ia64.lo elf64.lo $elf"; target_size=64 ;;
+ ia64_elf64_le_vec) tb="$tb elf64-ia64.lo elfxx-ia64.lo elf64.lo $elf"; target_size=64 ;;
+ ia64_elf64_hpux_be_vec) tb="$tb elf64-ia64.lo elfxx-ia64.lo elf64.lo $elf"; target_size=64 ;;
+ ia64_elf64_vms_vec) tb="$tb elf64-ia64-vms.lo elf64-ia64.lo elfxx-ia64.lo elf64.lo vms-lib.lo vms-misc.lo $elf"; target_size=64 ;;
+ ia64_pei_vec) tb="$tb pei-ia64.lo pepigen.lo cofflink.lo"; target_size=64 ;;
+ icoff_be_vec) tb="$tb coff-i960.lo cofflink.lo" ;;
+ icoff_le_vec) tb="$tb coff-i960.lo cofflink.lo" ;;
+ ieee_vec) tb="$tb ieee.lo" ;;
+ ip2k_elf32_vec) tb="$tb elf32-ip2k.lo elf32.lo $elf" ;;
+ iq2000_elf32_vec) tb="$tb elf32-iq2000.lo elf32.lo $elf" ;;
+ k1om_elf64_vec) tb="$tb elf64-x86-64.lo elf-ifunc.lo elf-nacl.lo elf64.lo $elf"; target_size=64 ;;
+ k1om_elf64_fbsd_vec) tb="$tb elf64-x86-64.lo elf-ifunc.lo elf-nacl.lo elf64.lo $elf"; target_size=64 ;;
+ l1om_elf64_vec) tb="$tb elf64-x86-64.lo elf-ifunc.lo elf-nacl.lo elf64.lo $elf"; target_size=64 ;;
+ l1om_elf64_fbsd_vec) tb="$tb elf64-x86-64.lo elf-ifunc.lo elf-nacl.lo elf64.lo $elf"; target_size=64 ;;
+ lm32_elf32_vec) tb="$tb elf32-lm32.lo elf32.lo $elf" ;;
+ lm32_elf32_fdpic_vec) tb="$tb elf32-lm32.lo elf32.lo $elf" ;;
+ m32c_elf32_vec) tb="$tb elf32-m32c.lo elf32.lo $elf" ;;
+ m32r_elf32_vec) tb="$tb elf32-m32r.lo elf32.lo $elf" ;;
+ m32r_elf32_le_vec) tb="$tb elf32-m32r.lo elf32.lo $elf" ;;
+ m32r_elf32_linux_vec) tb="$tb elf32-m32r.lo elf32.lo $elf" ;;
+ m32r_elf32_linux_le_vec) tb="$tb elf32-m32r.lo elf32.lo $elf" ;;
+ m68hc11_elf32_vec) tb="$tb elf32-m68hc11.lo elf32-m68hc1x.lo elf32.lo $elf" ;;
+ m68hc12_elf32_vec) tb="$tb elf32-m68hc12.lo elf32-m68hc1x.lo elf32.lo $elf" ;;
+ m68k_aout_4knbsd_vec) tb="$tb m68k4knetbsd.lo aout32.lo" ;;
+ m68k_aout_hp300bsd_vec) tb="$tb hp300bsd.lo aout32.lo" ;;
+ m68k_aout_hp300hpux_vec) tb="$tb hp300hpux.lo aout32.lo" ;;
+ m68k_aout_linux_vec) tb="$tb m68klinux.lo aout32.lo" ;;
+ m68k_aout_nbsd_vec) tb="$tb m68knetbsd.lo aout32.lo" ;;
+ m68k_aout_newsos3_vec) tb="$tb newsos3.lo aout32.lo" ;;
+ m68k_coff_vec) tb="$tb coff-m68k.lo cofflink.lo" ;;
+ m68k_coff_apollo_vec) tb="$tb coff-apollo.lo" ;;
+ m68k_coff_aux_vec) tb="$tb coff-aux.lo coff-m68k.lo cofflink.lo" ;;
+ m68k_coff_sysv_vec) tb="$tb coff-svm68k.lo cofflink.lo" ;;
+ m68k_coff_un_vec) tb="$tb coff-u68k.lo coff-m68k.lo cofflink.lo" ;;
+ m68k_elf32_vec) tb="$tb elf32-m68k.lo elf32.lo $elf" ;;
+ m68k_versados_vec) tb="$tb versados.lo" ;;
+ m88k_aout_mach3_vec) tb="$tb m88kmach3.lo aout32.lo" ;;
+ m88k_aout_obsd_vec) tb="$tb m88kopenbsd.lo aout32.lo" ;;
+ m88k_coff_bcs_vec) tb="$tb coff-m88k.lo" ;;
+ m88k_elf32_vec) tb="$tb elf32-m88k.lo elf32.lo $elf" ;;
+ mach_o_be_vec) tb="$tb mach-o.lo" ;;
+ mach_o_le_vec) tb="$tb mach-o.lo" ;;
+ mach_o_fat_vec) tb="$tb mach-o.lo" ;;
+ mcore_elf32_be_vec) tb="$tb elf32-mcore.lo elf32.lo $elf" ;;
+ mcore_elf32_le_vec) tb="$tb elf32-mcore.lo elf32.lo $elf" ;;
+ mcore_pe_be_vec) tb="$tb pe-mcore.lo peigen.lo cofflink.lo" ;;
+ mcore_pe_le_vec) tb="$tb pe-mcore.lo peigen.lo cofflink.lo" ;;
+ mcore_pei_be_vec) tb="$tb pei-mcore.lo peigen.lo cofflink.lo" ;;
+ mcore_pei_le_vec) tb="$tb pei-mcore.lo peigen.lo cofflink.lo" ;;
+ mep_elf32_vec) tb="$tb elf32-mep.lo elf32.lo $elf" ;;
+ mep_elf32_le_vec) tb="$tb elf32-mep.lo elf32.lo $elf" ;;
+ metag_elf32_vec) tb="$tb elf32-metag.lo elf32.lo $elf" ;;
+ microblaze_elf32_vec) tb="$tb elf32-microblaze.lo elf32.lo $elf" ;;
+ microblaze_elf32_le_vec) tb="$tb elf32-microblaze.lo elf32.lo $elf" ;;
+ mips_ecoff_be_vec) tb="$tb coff-mips.lo ecoff.lo ecofflink.lo" ;;
+ mips_ecoff_le_vec) tb="$tb coff-mips.lo ecoff.lo ecofflink.lo" ;;
+ mips_ecoff_bele_vec) tb="$tb coff-mips.lo ecoff.lo ecofflink.lo" ;;
+ mips_elf32_be_vec) tb="$tb elf32-mips.lo elfxx-mips.lo elf-vxworks.lo elf32.lo $elf ecofflink.lo" ;;
+ mips_elf32_le_vec) tb="$tb elf32-mips.lo elfxx-mips.lo elf-vxworks.lo elf32.lo $elf ecofflink.lo" ;;
+ mips_elf32_n_be_vec) tb="$tb elfn32-mips.lo elfxx-mips.lo elf-vxworks.lo elf32.lo $elf ecofflink.lo"; target_size=64 ;;
+ mips_elf32_n_le_vec) tb="$tb elfn32-mips.lo elfxx-mips.lo elf-vxworks.lo elf32.lo $elf ecofflink.lo"; target_size=64 ;;
+ mips_elf32_ntrad_be_vec) tb="$tb elfn32-mips.lo elfxx-mips.lo elf-vxworks.lo elf32.lo $elf ecofflink.lo"; target_size=64 ;;
+ mips_elf32_ntrad_le_vec) tb="$tb elfn32-mips.lo elfxx-mips.lo elf-vxworks.lo elf32.lo $elf ecofflink.lo"; target_size=64 ;;
+ mips_elf32_ntradfbsd_be_vec) tb="$tb elfn32-mips.lo elfxx-mips.lo elf-vxworks.lo elf32.lo $elf ecofflink.lo"; target_size=64 ;;
+ mips_elf32_ntradfbsd_le_vec) tb="$tb elfn32-mips.lo elfxx-mips.lo elf-vxworks.lo elf32.lo $elf ecofflink.lo"; target_size=64 ;;
+ mips_elf32_trad_be_vec) tb="$tb elf32-mips.lo elfxx-mips.lo elf-vxworks.lo elf32.lo $elf ecofflink.lo" ;;
+ mips_elf32_trad_le_vec) tb="$tb elf32-mips.lo elfxx-mips.lo elf-vxworks.lo elf32.lo $elf ecofflink.lo" ;;
+ mips_elf32_tradfbsd_be_vec) tb="$tb elf32-mips.lo elfxx-mips.lo elf-vxworks.lo elf32.lo $elf ecofflink.lo" ;;
+ mips_elf32_tradfbsd_le_vec) tb="$tb elf32-mips.lo elfxx-mips.lo elf-vxworks.lo elf32.lo $elf ecofflink.lo" ;;
+ mips_elf32_vxworks_be_vec) tb="$tb elf32-mips.lo elfxx-mips.lo elf-vxworks.lo elf32.lo $elf ecofflink.lo" ;;
+ mips_elf32_vxworks_le_vec) tb="$tb elf32-mips.lo elfxx-mips.lo elf-vxworks.lo elf32.lo $elf ecofflink.lo" ;;
+ mips_elf64_be_vec) tb="$tb elf64-mips.lo elf64.lo elfxx-mips.lo elf-vxworks.lo elf32.lo $elf ecofflink.lo"; target_size=64 ;;
+ mips_elf64_le_vec) tb="$tb elf64-mips.lo elf64.lo elfxx-mips.lo elf-vxworks.lo elf32.lo $elf ecofflink.lo"; target_size=64 ;;
+ mips_elf64_trad_be_vec) tb="$tb elf64-mips.lo elf64.lo elfxx-mips.lo elf-vxworks.lo elf32.lo $elf ecofflink.lo"; target_size=64 ;;
+ mips_elf64_trad_le_vec) tb="$tb elf64-mips.lo elf64.lo elfxx-mips.lo elf-vxworks.lo elf32.lo $elf ecofflink.lo"; target_size=64 ;;
+ mips_elf64_tradfbsd_be_vec) tb="$tb elf64-mips.lo elf64.lo elfxx-mips.lo elf-vxworks.lo elf32.lo $elf ecofflink.lo"; target_size=64 ;;
+ mips_elf64_tradfbsd_le_vec) tb="$tb elf64-mips.lo elf64.lo elfxx-mips.lo elf-vxworks.lo elf32.lo $elf ecofflink.lo"; target_size=64 ;;
+ mips_pe_le_vec) tb="$tb pe-mips.lo peigen.lo cofflink.lo" ;;
+ mips_pei_le_vec) tb="$tb pei-mips.lo peigen.lo cofflink.lo" ;;
+ mmix_elf64_vec) tb="$tb elf64-mmix.lo elf64.lo $elf" target_size=64 ;;
+ mmix_mmo_vec) tb="$tb mmo.lo" target_size=64 ;;
+ mn10200_elf32_vec) tb="$tb elf-m10200.lo elf32.lo $elf" ;;
+ mn10300_elf32_vec) tb="$tb elf-m10300.lo elf32.lo $elf" ;;
+ moxie_elf32_be_vec) tb="$tb elf32-moxie.lo elf32.lo $elf" ;;
+ moxie_elf32_le_vec) tb="$tb elf32-moxie.lo elf32.lo $elf" ;;
+ msp430_elf32_vec) tb="$tb elf32-msp430.lo elf32.lo $elf" ;;
+ msp430_elf32_ti_vec) tb="$tb elf32-msp430.lo elf32.lo $elf" ;;
+ mt_elf32_vec) tb="$tb elf32-mt.lo elf32.lo $elf" ;;
+ nds32_elf32_be_vec) tb="$tb elf32-nds32.lo elf32.lo $elf" ;;
+ nds32_elf32_le_vec) tb="$tb elf32-nds32.lo elf32.lo $elf" ;;
+ nds32_elf32_linux_be_vec) tb="$tb elf32-nds32.lo elf32.lo $elf" ;;
+ nds32_elf32_linux_le_vec) tb="$tb elf32-nds32.lo elf32.lo $elf" ;;
+ nios2_elf32_be_vec) tb="$tb elf32-nios2.lo elf32.lo $elf" ;;
+ nios2_elf32_le_vec) tb="$tb elf32-nios2.lo elf32.lo $elf" ;;
+ ns32k_aout_pc532mach_vec) tb="$tb pc532-mach.lo aout-ns32k.lo" ;;
+ ns32k_aout_pc532nbsd_vec) tb="$tb ns32knetbsd.lo aout-ns32k.lo" ;;
+ or1k_elf32_vec) tb="$tb elf32-or1k.lo elf32.lo $elf" ;;
+ pdp11_aout_vec) tb="$tb pdp11.lo" ;;
+ pef_vec) tb="$tb pef.lo" ;;
+ pef_xlib_vec) tb="$tb pef.lo" ;;
+ pj_elf32_vec) tb="$tb elf32-pj.lo elf32.lo $elf" ;;
+ pj_elf32_le_vec) tb="$tb elf32-pj.lo elf32.lo $elf" ;;
+ plugin_vec) tb="$tb plugin.lo" ;;
+ powerpc_boot_vec) tb="$tb ppcboot.lo" ;;
+ powerpc_elf32_vec) tb="$tb elf32-ppc.lo elf-vxworks.lo elf32.lo $elf" ;;
+ powerpc_elf32_le_vec) tb="$tb elf32-ppc.lo elf-vxworks.lo elf32.lo $elf" ;;
+ powerpc_elf32_fbsd_vec) tb="$tb elf32-ppc.lo elf-vxworks.lo elf32.lo $elf" ;;
+ powerpc_elf32_vxworks_vec) tb="$tb elf32-ppc.lo elf-vxworks.lo elf32.lo $elf" ;;
+ powerpc_elf64_vec) tb="$tb elf64-ppc.lo elf64-gen.lo elf64.lo $elf"; target_size=64 ;;
+ powerpc_elf64_le_vec) tb="$tb elf64-ppc.lo elf64-gen.lo elf64.lo $elf" target_size=64 ;;
+ powerpc_elf64_fbsd_vec) tb="$tb elf64-ppc.lo elf64-gen.lo elf64.lo $elf" target_size=64 ;;
+ powerpc_nlm32_vec) tb="$tb nlm32-ppc.lo nlm32.lo nlm.lo" ;;
+ powerpc_pe_vec) tb="$tb pe-ppc.lo peigen.lo cofflink.lo" ;;
+ powerpc_pe_le_vec) tb="$tb pe-ppc.lo peigen.lo cofflink.lo" ;;
+ powerpc_pei_vec) tb="$tb pei-ppc.lo peigen.lo cofflink.lo" ;;
+ powerpc_pei_le_vec) tb="$tb pei-ppc.lo peigen.lo cofflink.lo" ;;
+ powerpc_xcoff_vec) tb="$tb coff-rs6000.lo xcofflink.lo" ;;
+ rl78_elf32_vec) tb="$tb elf32-rl78.lo elf32.lo $elf" ;;
+ rs6000_xcoff64_vec) tb="$tb coff64-rs6000.lo xcofflink.lo aix5ppc-core.lo"; target_size=64 ;;
+ rs6000_xcoff64_aix_vec) tb="$tb coff64-rs6000.lo xcofflink.lo aix5ppc-core.lo"; target_size=64 ;;
+ rs6000_xcoff_vec) tb="$tb coff-rs6000.lo xcofflink.lo" ;;
+ rx_elf32_be_vec) tb="$tb elf32-rx.lo elf32.lo $elf" ;;
+ rx_elf32_be_ns_vec) tb="$tb elf32-rx.lo elf32.lo $elf" ;;
+ rx_elf32_le_vec) tb="$tb elf32-rx.lo elf32.lo $elf" ;;
+ s390_elf32_vec) tb="$tb elf32-s390.lo elf32.lo $elf" ;;
+ s390_elf64_vec) tb="$tb elf64-s390.lo elf64.lo $elf"; target_size=64 ;;
+ score_elf32_be_vec) tb="$tb elf32-score.lo elf32-score7.lo elf32.lo $elf"; want64=true; target_size=64 ;;
+ score_elf32_le_vec) tb="$tb elf32-score.lo elf32-score7.lo elf32.lo $elf"; want64=true; target_size=64 ;;
+ # FIXME: We include cofflink.lo not because it's needed for
+ # sh64_elf32[_le]_vec, but because we include sh_elf32[_le]_vec
+ # which needs it but does not list it. Should be fixed in right place.
+ sh64_elf32_vec) tb="$tb elf32-sh64.lo elf32-sh64-com.lo elf-vxworks.lo elf32.lo $elf cofflink.lo" target_size=64 ;;
+ sh64_elf32_le_vec) tb="$tb elf32-sh64.lo elf32-sh64-com.lo elf-vxworks.lo elf32.lo $elf cofflink.lo" target_size=64 ;;
+ sh64_elf32_linux_vec) tb="$tb elf32-sh64.lo elf32-sh64-com.lo elf-vxworks.lo elf32.lo $elf cofflink.lo" target_size=64 ;;
+ sh64_elf32_linux_be_vec) tb="$tb elf32-sh64.lo elf32-sh64-com.lo elf-vxworks.lo elf32.lo $elf cofflink.lo" target_size=64 ;;
+ sh64_elf32_nbsd_vec) tb="$tb elf32-sh64.lo elf32-sh64-com.lo elf-vxworks.lo elf32.lo $elf cofflink.lo" ;;
+ sh64_elf32_nbsd_le_vec) tb="$tb elf32-sh64.lo elf32-sh64-com.lo elf-vxworks.lo elf32.lo $elf cofflink.lo" ;;
+ sh64_elf64_vec) tb="$tb elf64-sh64.lo elf64.lo $elf" target_size=64 ;;
+ sh64_elf64_le_vec) tb="$tb elf64-sh64.lo elf64.lo $elf" target_size=64 ;;
+ sh64_elf64_linux_vec) tb="$tb elf64-sh64.lo elf64.lo $elf" target_size=64 ;;
+ sh64_elf64_linux_be_vec) tb="$tb elf64-sh64.lo elf64.lo $elf" target_size=64 ;;
+ sh64_elf64_nbsd_vec) tb="$tb elf64-sh64.lo elf64.lo $elf" target_size=64 ;;
+ sh64_elf64_nbsd_le_vec) tb="$tb elf64-sh64.lo elf64.lo $elf" target_size=64 ;;
+ sh_coff_vec) tb="$tb coff-sh.lo cofflink.lo" ;;
+ sh_coff_le_vec) tb="$tb coff-sh.lo cofflink.lo" ;;
+ sh_coff_small_vec) tb="$tb coff-sh.lo cofflink.lo" ;;
+ sh_coff_small_le_vec) tb="$tb coff-sh.lo cofflink.lo" ;;
+ sh_elf32_vec) tb="$tb elf32-sh.lo elf-vxworks.lo elf32.lo $elf coff-sh.lo" ;;
+ sh_elf32_le_vec) tb="$tb elf32-sh.lo elf-vxworks.lo elf32.lo $elf coff-sh.lo" ;;
+ sh_elf32_fdpic_be_vec) tb="$tb elf32-sh.lo elf-vxworks.lo elf32.lo $elf coff-sh.lo cofflink.lo" ;;
+ sh_elf32_fdpic_le_vec) tb="$tb elf32-sh.lo elf-vxworks.lo elf32.lo $elf coff-sh.lo cofflink.lo" ;;
+ sh_elf32_linux_vec) tb="$tb elf32-sh.lo elf-vxworks.lo elf32.lo $elf coff-sh.lo cofflink.lo" ;;
+ sh_elf32_linux_be_vec) tb="$tb elf32-sh.lo elf-vxworks.lo elf32.lo $elf coff-sh.lo cofflink.lo" ;;
+ sh_elf32_nbsd_vec) tb="$tb elf32-sh.lo elf-vxworks.lo elf32.lo $elf coff-sh.lo cofflink.lo" ;;
+ sh_elf32_nbsd_le_vec) tb="$tb elf32-sh.lo elf-vxworks.lo elf32.lo $elf coff-sh.lo cofflink.lo" ;;
+ sh_elf32_symbian_le_vec) tb="$tb elf32-sh-symbian.lo elf32-sh64-com.lo elf-vxworks.lo elf32.lo $elf coff-sh.lo" ;;
+ sh_elf32_vxworks_vec) tb="$tb elf32-sh.lo elf-vxworks.lo elf32.lo $elf coff-sh.lo" ;;
+ sh_elf32_vxworks_le_vec) tb="$tb elf32-sh.lo elf-vxworks.lo elf32.lo $elf coff-sh.lo" ;;
+ sh_pe_le_vec) tb="$tb pe-sh.lo coff-sh.lo peigen.lo cofflink.lo" ;;
+ sh_pei_le_vec) tb="$tb pei-sh.lo coff-sh.lo peigen.lo cofflink.lo" ;;
+ sparc_aout_le_vec) tb="$tb aout-sparcle.lo aout32.lo" ;;
+ sparc_aout_linux_vec) tb="$tb sparclinux.lo aout32.lo" ;;
+ sparc_aout_lynx_vec) tb="$tb sparclynx.lo lynx-core.lo aout32.lo" ;;
+ sparc_aout_nbsd_vec) tb="$tb sparcnetbsd.lo aout32.lo" ;;
+ sparc_aout_sunos_be_vec) tb="$tb sunos.lo aout32.lo" ;;
+ sparc_coff_vec) tb="$tb coff-sparc.lo" ;;
+ sparc_coff_lynx_vec) tb="$tb cf-sparclynx.lo lynx-core.lo" ;;
+ sparc_elf32_vec) tb="$tb elf32-sparc.lo elfxx-sparc.lo elf-vxworks.lo elf32.lo $elf" ;;
+ sparc_elf32_sol2_vec) tb="$tb elf32-sparc.lo elfxx-sparc.lo elf-vxworks.lo elf32.lo $elf" ;;
+ sparc_elf32_vxworks_vec) tb="$tb elf32-sparc.lo elfxx-sparc.lo elf-vxworks.lo elf32.lo $elf" ;;
+ sparc_elf64_vec) tb="$tb elf64-sparc.lo elfxx-sparc.lo elf-vxworks.lo elf64.lo $elf"; target_size=64 ;;
+ sparc_elf64_fbsd_vec) tb="$tb elf64-sparc.lo elfxx-sparc.lo elf-vxworks.lo elf64.lo $elf"; target_size=64 ;;
+ sparc_elf64_sol2_vec) tb="$tb elf64-sparc.lo elfxx-sparc.lo elf-vxworks.lo elf64.lo $elf"; target_size=64 ;;
+ sparc_nlm32_vec) tb="$tb nlm32-sparc.lo nlm32.lo nlm.lo" ;;
+ spu_elf32_vec) tb="$tb elf32-spu.lo elf32.lo $elf" ;;
+ sym_vec) tb="$tb xsym.lo" ;;
+ tic30_aout_vec) tb="$tb aout-tic30.lo" ;;
+ tic30_coff_vec) tb="$tb coff-tic30.lo" ;;
+ tic4x_coff0_vec) tb="$tb coff-tic4x.lo" ;;
+ tic4x_coff0_beh_vec) tb="$tb coff-tic4x.lo" ;;
+ tic4x_coff1_vec) tb="$tb coff-tic4x.lo" ;;
+ tic4x_coff1_beh_vec) tb="$tb coff-tic4x.lo" ;;
+ tic4x_coff2_vec) tb="$tb coff-tic4x.lo" ;;
+ tic4x_coff2_beh_vec) tb="$tb coff-tic4x.lo" ;;
+ tic54x_coff0_vec) tb="$tb coff-tic54x.lo" ;;
+ tic54x_coff0_beh_vec) tb="$tb coff-tic54x.lo" ;;
+ tic54x_coff1_vec) tb="$tb coff-tic54x.lo" ;;
+ tic54x_coff1_beh_vec) tb="$tb coff-tic54x.lo" ;;
+ tic54x_coff2_vec) tb="$tb coff-tic54x.lo" ;;
+ tic54x_coff2_beh_vec) tb="$tb coff-tic54x.lo" ;;
+ tic6x_elf32_be_vec) tb="$tb elf32-tic6x.lo elf32.lo $elf" ;;
+ tic6x_elf32_le_vec) tb="$tb elf32-tic6x.lo elf32.lo $elf" ;;
+ tic6x_elf32_c6000_be_vec) tb="$tb elf32-tic6x.lo elf32.lo $elf" ;;
+ tic6x_elf32_c6000_le_vec) tb="$tb elf32-tic6x.lo elf32.lo $elf" ;;
+ tic6x_elf32_linux_be_vec) tb="$tb elf32-tic6x.lo elf32.lo $elf" ;;
+ tic6x_elf32_linux_le_vec) tb="$tb elf32-tic6x.lo elf32.lo $elf" ;;
+ tic80_coff_vec) tb="$tb coff-tic80.lo cofflink.lo" ;;
+ tilegx_elf32_be_vec) tb="$tb elf32-tilegx.lo elfxx-tilegx.lo elf32.lo $elf" ; target_size=32 ;;
+ tilegx_elf32_le_vec) tb="$tb elf32-tilegx.lo elfxx-tilegx.lo elf32.lo $elf" ; target_size=32 ;;
+ tilegx_elf64_be_vec) tb="$tb elf64-tilegx.lo elfxx-tilegx.lo elf64.lo $elf" ; target_size=64 ;;
+ tilegx_elf64_le_vec) tb="$tb elf64-tilegx.lo elfxx-tilegx.lo elf64.lo $elf" ; target_size=64 ;;
+ tilepro_elf32_vec) tb="$tb elf32-tilepro.lo elf32.lo $elf" ;;
+ v800_elf32_vec) tb="$tb elf32-v850.lo elf32.lo $elf" ;;
+ v850_elf32_vec) tb="$tb elf32-v850.lo elf32.lo $elf" ;;
+ vax_aout_1knbsd_vec) tb="$tb vax1knetbsd.lo aout32.lo" ;;
+ vax_aout_bsd_vec) tb="$tb vaxbsd.lo aout32.lo" ;;
+ vax_aout_nbsd_vec) tb="$tb vaxnetbsd.lo aout32.lo" ;;
+ vax_elf32_vec) tb="$tb elf32-vax.lo elf32.lo $elf" ;;
+ w65_coff_vec) tb="$tb coff-w65.lo reloc16.lo" ;;
+ we32k_coff_vec) tb="$tb coff-we32k.lo" ;;
+ x86_64_coff_vec) tb="$tb coff-x86_64.lo cofflink.lo"; target_size=64 ;;
+ x86_64_elf32_vec) tb="$tb elf64-x86-64.lo elf-ifunc.lo elf-nacl.lo elf64.lo elf32.lo $elf"; target_size=64 ;;
+ x86_64_elf32_nacl_vec) tb="$tb elf64-x86-64.lo elf-ifunc.lo elf-nacl.lo elf64.lo elf32.lo $elf"; target_size=64 ;;
+ x86_64_elf64_vec) tb="$tb elf64-x86-64.lo elf-ifunc.lo elf-nacl.lo elf64.lo $elf"; target_size=64 ;;
+ x86_64_elf64_fbsd_vec) tb="$tb elf64-x86-64.lo elf-ifunc.lo elf-nacl.lo elf64.lo $elf"; target_size=64 ;;
+ x86_64_elf64_nacl_vec) tb="$tb elf64-x86-64.lo elf-ifunc.lo elf-nacl.lo elf64.lo $elf"; target_size=64 ;;
+ x86_64_elf64_sol2_vec) tb="$tb elf64-x86-64.lo elf-ifunc.lo elf-nacl.lo elf64.lo $elf"; target_size=64 ;;
+ x86_64_mach_o_vec) tb="$tb mach-o-x86-64.lo" ;;
+ x86_64_pe_vec) tb="$tb pe-x86_64.lo pex64igen.lo cofflink.lo"; target_size=64 ;;
+ x86_64_pe_be_vec) tb="$tb pe-x86_64.lo pex64igen.lo cofflink.lo"; target_size=64 ;;
+ x86_64_pei_vec) tb="$tb pei-x86_64.lo pex64igen.lo cofflink.lo"; target_size=64 ;;
+ xc16x_elf32_vec) tb="$tb elf32-xc16x.lo elf32.lo $elf" ;;
+ xgate_elf32_vec) tb="$tb elf32-xgate.lo elf32.lo $elf" ;;
+ xstormy16_elf32_vec) tb="$tb elf32-xstormy16.lo elf32.lo $elf" ;;
+ xtensa_elf32_be_vec) tb="$tb xtensa-isa.lo xtensa-modules.lo elf32-xtensa.lo elf32.lo $elf" ;;
+ xtensa_elf32_le_vec) tb="$tb xtensa-isa.lo xtensa-modules.lo elf32-xtensa.lo elf32.lo $elf" ;;
+ z80_coff_vec) tb="$tb coff-z80.lo reloc16.lo" ;;
+ z8k_coff_vec) tb="$tb coff-z8k.lo reloc16.lo cofflink.lo" ;;
+
+ # These appear out of order in targets.c
+ srec_vec) tb="$tb srec.lo" ;;
+ symbolsrec_vec) tb="$tb srec.lo" ;;
+ tekhex_vec) tb="$tb tekhex.lo" ;;
+ core_cisco_be_vec) tb="$tb cisco-core.lo" ;;
+ core_cisco_le_vec) tb="$tb cisco-core.lo" ;;
+
+ "") ;;
+ *) as_fn_error "*** unknown target vector $vec" "$LINENO" 5 ;;
+ esac
+
+ if test ${target_size} = 64; then
+ target64=true
+ fi
+ if test x"${vec}" = x"${defvec}"; then
+ bfd_default_target_size=${target_size}
+ fi
+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=-DHAVE_all_vecs
+ selarchs=
+ test -n "$assocvecs" &&
+ assocvecs=`echo $assocvecs | sed -e 's/^/\&/' -e 's/ \(.\)/,\&\1/g'`
+else # all_targets is true
+ # Only set these if they will be nonempty, for the clever echo.
+ havevecs=
+ assocvecs=
+ 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
+ bfd64_libs='$(BFD64_LIBS)'
+ all_backends='$(BFD64_BACKENDS) $(BFD32_BACKENDS)'
+ if test $BFD_HOST_64_BIT_DEFINED = 0; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: You have requested a 64 bit BFD configuration, but" >&5
+$as_echo "$as_me: WARNING: You have requested a 64 bit BFD configuration, but" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: your compiler may not have a 64 bit integral type" >&5
+$as_echo "$as_me: WARNING: your compiler may not have a 64 bit integral type" >&2;}
+ fi
+ if test -n "$GCC" ; then
+ bad_64bit_gcc=no;
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gcc version with buggy 64-bit support" >&5
+$as_echo_n "checking for gcc version with buggy 64-bit support... " >&6; }
+ # Add more tests for gcc versions with non-working 64-bit support here.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+:__GNUC__:__GNUC_MINOR__:__i386__:
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP ": 2 : 91 : 1 :" >/dev/null 2>&1; then :
+ bad_64bit_gcc=yes;
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes: egcs-1.1.2 on ix86 spotted" >&5
+$as_echo "yes: egcs-1.1.2 on ix86 spotted" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+rm -f conftest*
+
+ if test $bad_64bit_gcc = yes ; then
+ as_fn_error "A newer version of gcc is needed for the requested 64-bit BFD configuration" "$LINENO" 5
+ fi
+ fi
+ ;;
+ false-false-false)
+ wordsize=32
+ all_backends='$(BFD32_BACKENDS)'
+ ;;
+esac
+
+
+
+
+
+
+
+
+if test "$plugins" = "yes"; then
+ supports_plugins=1
+else
+ supports_plugins=0
+fi
+
+
+
+# Determine the host dependant file_ptr a.k.a. off_t type. In order
+# prefer: off64_t - if ftello64 and fseeko64, off_t - if ftello and
+# fseeko, long. This assumes that sizeof off_t is .ge. sizeof long.
+# Hopefully a reasonable assumption since fseeko et.al. should be
+# upward compatible.
+for ac_func in ftello ftello64 fseeko fseeko64 fopen64
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+eval as_val=\$$as_ac_var
+ if test "x$as_val" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+if test x"$ac_cv_func_ftello" = xyes -a x"$ac_cv_func_fseeko" = xyes; then
+ # The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of off_t" >&5
+$as_echo_n "checking size of off_t... " >&6; }
+if test "${ac_cv_sizeof_off_t+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (off_t))" "ac_cv_sizeof_off_t" "$ac_includes_default"; then :
+
+else
+ if test "$ac_cv_type_off_t" = yes; then
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+{ as_fn_set_status 77
+as_fn_error "cannot compute sizeof (off_t)
+See \`config.log' for more details." "$LINENO" 5; }; }
+ else
+ ac_cv_sizeof_off_t=0
+ fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_off_t" >&5
+$as_echo "$ac_cv_sizeof_off_t" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_OFF_T $ac_cv_sizeof_off_t
+_ACEOF
+
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking file_ptr type" >&5
+$as_echo_n "checking file_ptr type... " >&6; }
+bfd_file_ptr="long"
+bfd_ufile_ptr="unsigned long"
+if test x"$ac_cv_func_ftello64" = xyes -a x"$ac_cv_func_fseeko64" = xyes \
+ -o x"${ac_cv_sizeof_off_t}" = x8; then
+ bfd_file_ptr=BFD_HOST_64_BIT
+ bfd_ufile_ptr=BFD_HOST_U_64_BIT
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $bfd_file_ptr" >&5
+$as_echo "$bfd_file_ptr" >&6; }
+
+
+
+
+tdefaults=""
+test -n "${defvec}" && tdefaults="${tdefaults} -DDEFAULT_VECTOR=${defvec}"
+test -n "${selvecs}" && tdefaults="${tdefaults} -DSELECT_VECS='${selvecs}'"
+test -n "${assocvecs}" && tdefaults="${tdefaults} -DASSOCIATED_VECS='${assocvecs}'"
+test -n "${selarchs}" && tdefaults="${tdefaults} -DSELECT_ARCHITECTURES='${selarchs}'"
+
+
+
+for ac_header in stdlib.h unistd.h
+do :
+ as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
+eval as_val=\$$as_ac_Header
+ if test "x$as_val" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+for ac_func in getpagesize
+do :
+ ac_fn_c_check_func "$LINENO" "getpagesize" "ac_cv_func_getpagesize"
+if test "x$ac_cv_func_getpagesize" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_GETPAGESIZE 1
+_ACEOF
+
+fi
+done
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for working mmap" >&5
+$as_echo_n "checking for working mmap... " >&6; }
+if test "${ac_cv_func_mmap_fixed_mapped+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test "$cross_compiling" = yes; then :
+ ac_cv_func_mmap_fixed_mapped=no
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$ac_includes_default
+/* malloc might have been renamed as rpl_malloc. */
+#undef malloc
+
+/* 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 file system buffer cache
+ like early versions of FreeBSD and possibly contemporary NetBSD.)
+ For shared mappings, we should conversely verify that changes get
+ propagated 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 <fcntl.h>
+#include <sys/mman.h>
+
+#if !defined STDC_HEADERS && !defined HAVE_STDLIB_H
+char *malloc ();
+#endif
+
+/* This mess was copied from the GNU getpagesize.h. */
+#ifndef HAVE_GETPAGESIZE
+/* 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 */
+
+int
+main ()
+{
+ char *data, *data2, *data3;
+ int i, pagesize;
+ int fd;
+
+ pagesize = getpagesize ();
+
+ /* First, make a file with some known garbage in it. */
+ data = (char *) malloc (pagesize);
+ if (!data)
+ return 1;
+ for (i = 0; i < pagesize; ++i)
+ *(data + i) = rand ();
+ umask (0);
+ fd = creat ("conftest.mmap", 0600);
+ if (fd < 0)
+ return 1;
+ if (write (fd, data, pagesize) != pagesize)
+ return 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 ("conftest.mmap", O_RDWR);
+ if (fd < 0)
+ return 1;
+ data2 = (char *) malloc (2 * pagesize);
+ if (!data2)
+ return 1;
+ data2 += (pagesize - ((long int) data2 & (pagesize - 1))) & (pagesize - 1);
+ if (data2 != mmap (data2, pagesize, PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_FIXED, fd, 0L))
+ return 1;
+ for (i = 0; i < pagesize; ++i)
+ if (*(data + i) != *(data2 + i))
+ return 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 = (char *) malloc (pagesize);
+ if (!data3)
+ return 1;
+ if (read (fd, data3, pagesize) != pagesize)
+ return 1;
+ for (i = 0; i < pagesize; ++i)
+ if (*(data + i) != *(data3 + i))
+ return 1;
+ close (fd);
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+ ac_cv_func_mmap_fixed_mapped=yes
+else
+ ac_cv_func_mmap_fixed_mapped=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_mmap_fixed_mapped" >&5
+$as_echo "$ac_cv_func_mmap_fixed_mapped" >&6; }
+if test $ac_cv_func_mmap_fixed_mapped = yes; then
+
+$as_echo "#define HAVE_MMAP 1" >>confdefs.h
+
+fi
+rm -f conftest.mmap
+
+for ac_func in madvise mprotect
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+eval as_val=\$$as_ac_var
+ if test "x$as_val" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+case ${want_mmap}+${ac_cv_func_mmap_fixed_mapped} in
+ true+yes )
+$as_echo "#define USE_MMAP 1" >>confdefs.h
+ ;;
+esac
+
+rm -f doc/config.status
+ac_config_files="$ac_config_files Makefile doc/Makefile bfd-in3.h:bfd-in2.h po/Makefile.in:po/Make-in"
+
+
+ac_config_commands="$ac_config_commands default"
+
+
+
+
+
+
+
+cat >confcache <<\_ACEOF
+# 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, see configure's option --config-cache.
+# It is not useful on other systems. If it contains results you don't
+# want to keep, you may remove or edit it.
+#
+# config.status only pays attention to the cache file if you give it
+# the --recheck option to rerun configure.
+#
+# `ac_cv_env_foo' variables (set or unset) will be overridden when
+# loading this file, other *unset* `ac_cv_foo' will be assigned the
+# following values.
+
+_ACEOF
+
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, we kill variables containing newlines.
+# 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.
+(
+ for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do
+ eval ac_val=\$$ac_var
+ case $ac_val in #(
+ *${as_nl}*)
+ case $ac_var in #(
+ *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+ esac
+ case $ac_var in #(
+ _ | IFS | as_nl) ;; #(
+ BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+ *) { eval $ac_var=; unset $ac_var;} ;;
+ esac ;;
+ esac
+ done
+
+ (set) 2>&1 |
+ case $as_nl`(ac_space=' '; set) 2>&1` in #(
+ *${as_nl}ac_space=\ *)
+ # `set' does not quote correctly, so add quotes: double-quote
+ # substitution turns \\\\ into \\, and sed turns \\ into \.
+ sed -n \
+ "s/'/'\\\\''/g;
+ s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
+ ;; #(
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+ ;;
+ esac |
+ sort
+) |
+ sed '
+ /^ac_cv_env_/b end
+ t clear
+ :clear
+ s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
+ t end
+ s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
+ :end' >>confcache
+if diff "$cache_file" confcache >/dev/null 2>&1; then :; else
+ if test -w "$cache_file"; then
+ test "x$cache_file" != "x/dev/null" &&
+ { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5
+$as_echo "$as_me: updating cache $cache_file" >&6;}
+ cat confcache >$cache_file
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5
+$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;}
+ fi
+fi
+rm -f confcache
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+DEFS=-DHAVE_CONFIG_H
+
+ac_libobjs=
+ac_ltlibobjs=
+for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
+ # 1. Remove the extension, and $U if already installed.
+ ac_script='s/\$U\././;s/\.o$//;s/\.obj$//'
+ ac_i=`$as_echo "$ac_i" | sed "$ac_script"`
+ # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR
+ # will be set to the directory where LIBOBJS objects are built.
+ as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext"
+ as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo'
+done
+LIBOBJS=$ac_libobjs
+
+LTLIBOBJS=$ac_ltlibobjs
+
+
+if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then
+ as_fn_error "conditional \"AMDEP\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then
+ as_fn_error "conditional \"am__fastdepCC\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+ if test -n "$EXEEXT"; then
+ am__EXEEXT_TRUE=
+ am__EXEEXT_FALSE='#'
+else
+ am__EXEEXT_TRUE='#'
+ am__EXEEXT_FALSE=
+fi
+
+if test -z "${PLUGINS_TRUE}" && test -z "${PLUGINS_FALSE}"; then
+ as_fn_error "conditional \"PLUGINS\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then
+ as_fn_error "conditional \"MAINTAINER_MODE\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${GENINSRC_NEVER_TRUE}" && test -z "${GENINSRC_NEVER_FALSE}"; then
+ as_fn_error "conditional \"GENINSRC_NEVER\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${INSTALL_LIBBFD_TRUE}" && test -z "${INSTALL_LIBBFD_FALSE}"; then
+ as_fn_error "conditional \"INSTALL_LIBBFD\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+
+: ${CONFIG_STATUS=./config.status}
+ac_write_fail=0
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files $CONFIG_STATUS"
+{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5
+$as_echo "$as_me: creating $CONFIG_STATUS" >&6;}
+as_write_fail=0
+cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1
+#! $SHELL
+# Generated by $as_me.
+# Run this file to recreate the current configuration.
+# Compiler output produced by configure, useful for debugging
+# configure, is in config.log if it exists.
+
+debug=false
+ac_cs_recheck=false
+ac_cs_silent=false
+
+SHELL=\${CONFIG_SHELL-$SHELL}
+export SHELL
+_ASEOF
+cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1
+## -------------------- ##
+## M4sh Initialization. ##
+## -------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
+ emulate sh
+ NULLCMD=:
+ # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+else
+ case `(set -o) 2>/dev/null` in #(
+ *posix*) :
+ set -o posix ;; #(
+ *) :
+ ;;
+esac
+fi
+
+
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+# Prefer a ksh shell builtin over an external printf program on Solaris,
+# but without wasting forks for bash or zsh.
+if test -z "$BASH_VERSION$ZSH_VERSION" \
+ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='print -r --'
+ as_echo_n='print -rn --'
+elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='printf %s\n'
+ as_echo_n='printf %s'
+else
+ if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+ as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+ as_echo_n='/usr/ucb/echo -n'
+ else
+ as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+ as_echo_n_body='eval
+ arg=$1;
+ case $arg in #(
+ *"$as_nl"*)
+ expr "X$arg" : "X\\(.*\\)$as_nl";
+ arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+ esac;
+ expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+ '
+ export as_echo_n_body
+ as_echo_n='sh -c $as_echo_n_body as_echo'
+ fi
+ export as_echo_body
+ as_echo='sh -c $as_echo_body as_echo'
+fi
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ PATH_SEPARATOR=:
+ (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+ (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+ PATH_SEPARATOR=';'
+ }
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order. Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+IFS=" "" $as_nl"
+
+# Find who we are. Look in the path if we contain no directory separator.
+case $0 in #((
+ *[\\/]* ) as_myself=$0 ;;
+ *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+ as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+ $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+ exit 1
+fi
+
+# Unset variables that we do not need and which cause bugs (e.g. in
+# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1"
+# suppresses any "Segmentation fault" message there. '((' could
+# trigger a bug in pdksh 5.2.14.
+for as_var in BASH_ENV ENV MAIL MAILPATH
+do eval test x\${$as_var+set} = xset \
+ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# CDPATH.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+
+# as_fn_error ERROR [LINENO LOG_FD]
+# ---------------------------------
+# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
+# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
+# script with status $?, using 1 if that was 0.
+as_fn_error ()
+{
+ as_status=$?; test $as_status -eq 0 && as_status=1
+ if test "$3"; then
+ as_lineno=${as_lineno-"$2"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ $as_echo "$as_me:${as_lineno-$LINENO}: error: $1" >&$3
+ fi
+ $as_echo "$as_me: error: $1" >&2
+ as_fn_exit $as_status
+} # as_fn_error
+
+
+# as_fn_set_status STATUS
+# -----------------------
+# Set $? to STATUS, without forking.
+as_fn_set_status ()
+{
+ return $1
+} # as_fn_set_status
+
+# as_fn_exit STATUS
+# -----------------
+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
+as_fn_exit ()
+{
+ set +e
+ as_fn_set_status $1
+ exit $1
+} # as_fn_exit
+
+# as_fn_unset VAR
+# ---------------
+# Portably unset VAR.
+as_fn_unset ()
+{
+ { eval $1=; unset $1;}
+}
+as_unset=as_fn_unset
+# as_fn_append VAR VALUE
+# ----------------------
+# Append the text in VALUE to the end of the definition contained in VAR. Take
+# advantage of any shell optimizations that allow amortized linear growth over
+# repeated appends, instead of the typical quadratic growth present in naive
+# implementations.
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
+ eval 'as_fn_append ()
+ {
+ eval $1+=\$2
+ }'
+else
+ as_fn_append ()
+ {
+ eval $1=\$$1\$2
+ }
+fi # as_fn_append
+
+# as_fn_arith ARG...
+# ------------------
+# Perform arithmetic evaluation on the ARGs, and store the result in the
+# global $as_val. Take advantage of shells that can avoid forks. The arguments
+# must be portable across $(()) and expr.
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
+ eval 'as_fn_arith ()
+ {
+ as_val=$(( $* ))
+ }'
+else
+ as_fn_arith ()
+ {
+ as_val=`expr "$@" || test $? -eq 1`
+ }
+fi # as_fn_arith
+
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+ test "X`expr 00001 : '.*\(...\)'`" = X001; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+ as_basename=basename
+else
+ as_basename=false
+fi
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+ as_dirname=dirname
+else
+ as_dirname=false
+fi
+
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$0" |
+ sed '/^.*\/\([^/][^/]*\)\/*$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in #(((((
+-n*)
+ case `echo 'xy\c'` in
+ *c*) ECHO_T=' ';; # ECHO_T is single tab character.
+ xy) ECHO_C='\c';;
+ *) echo `echo ksh88 bug on AIX 6.1` > /dev/null
+ ECHO_T=' ';;
+ esac;;
+*)
+ ECHO_N='-n';;
+esac
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+ rm -f conf$$.dir/conf$$.file
+else
+ rm -f conf$$.dir
+ mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+ if ln -s conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s='ln -s'
+ # ... but there are two gotchas:
+ # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+ # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+ # In both cases, we have to default to `cp -p'.
+ ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+ as_ln_s='cp -p'
+ elif ln conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s=ln
+ else
+ as_ln_s='cp -p'
+ fi
+else
+ as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+
+# as_fn_mkdir_p
+# -------------
+# Create "$as_dir" as a directory, including parents if necessary.
+as_fn_mkdir_p ()
+{
+
+ case $as_dir in #(
+ -*) as_dir=./$as_dir;;
+ esac
+ test -d "$as_dir" || eval $as_mkdir_p || {
+ as_dirs=
+ while :; do
+ case $as_dir in #(
+ *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+ *) as_qdir=$as_dir;;
+ esac
+ as_dirs="'$as_qdir' $as_dirs"
+ as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_dir" : 'X\(//\)[^/]' \| \
+ X"$as_dir" : 'X\(//\)$' \| \
+ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_dir" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ test -d "$as_dir" && break
+ done
+ test -z "$as_dirs" || eval "mkdir $as_dirs"
+ } || test -d "$as_dir" || as_fn_error "cannot create directory $as_dir"
+
+
+} # as_fn_mkdir_p
+if mkdir -p . 2>/dev/null; then
+ as_mkdir_p='mkdir -p "$as_dir"'
+else
+ test -d ./-p && rmdir ./-p
+ as_mkdir_p=false
+fi
+
+if test -x / >/dev/null 2>&1; then
+ as_test_x='test -x'
+else
+ if ls -dL / >/dev/null 2>&1; then
+ as_ls_L_option=L
+ else
+ as_ls_L_option=
+ fi
+ as_test_x='
+ eval sh -c '\''
+ if test -d "$1"; then
+ test -d "$1/.";
+ else
+ case $1 in #(
+ -*)set "./$1";;
+ esac;
+ case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #((
+ ???[sx]*):;;*)false;;esac;fi
+ '\'' sh
+ '
+fi
+as_executable_p=$as_test_x
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+exec 6>&1
+## ----------------------------------- ##
+## Main body of $CONFIG_STATUS script. ##
+## ----------------------------------- ##
+_ASEOF
+test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# Save the log message, to keep $0 and so on meaningful, and to
+# report actual input values of CONFIG_FILES etc. instead of their
+# values after options handling.
+ac_log="
+This file was extended by bfd $as_me 2.25, which was
+generated by GNU Autoconf 2.64. Invocation command line was
+
+ CONFIG_FILES = $CONFIG_FILES
+ CONFIG_HEADERS = $CONFIG_HEADERS
+ CONFIG_LINKS = $CONFIG_LINKS
+ CONFIG_COMMANDS = $CONFIG_COMMANDS
+ $ $0 $@
+
+on `(hostname || uname -n) 2>/dev/null | sed 1q`
+"
+
+_ACEOF
+
+case $ac_config_files in *"
+"*) set x $ac_config_files; shift; ac_config_files=$*;;
+esac
+
+case $ac_config_headers in *"
+"*) set x $ac_config_headers; shift; ac_config_headers=$*;;
+esac
+
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+# Files that config.status was made for.
+config_files="$ac_config_files"
+config_headers="$ac_config_headers"
+config_commands="$ac_config_commands"
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+ac_cs_usage="\
+\`$as_me' instantiates files and other configuration actions
+from templates according to the current configuration. Unless the files
+and actions are specified as TAGs, all are instantiated by default.
+
+Usage: $0 [OPTION]... [TAG]...
+
+ -h, --help print this help, then exit
+ -V, --version print version number and configuration settings, then exit
+ -q, --quiet, --silent
+ do not print progress messages
+ -d, --debug don't remove temporary files
+ --recheck update $as_me by reconfiguring in the same conditions
+ --file=FILE[:TEMPLATE]
+ instantiate the configuration file FILE
+ --header=FILE[:TEMPLATE]
+ instantiate the configuration header FILE
+
+Configuration files:
+$config_files
+
+Configuration headers:
+$config_headers
+
+Configuration commands:
+$config_commands
+
+Report bugs to the package provider."
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_cs_version="\\
+bfd config.status 2.25
+configured by $0, generated by GNU Autoconf 2.64,
+ with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"
+
+Copyright (C) 2009 Free Software Foundation, Inc.
+This config.status script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it."
+
+ac_pwd='$ac_pwd'
+srcdir='$srcdir'
+INSTALL='$INSTALL'
+MKDIR_P='$MKDIR_P'
+AWK='$AWK'
+test -n "\$AWK" || AWK=awk
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# The default lists apply if the user does not specify any file.
+ac_need_defaults=:
+while test $# != 0
+do
+ case $1 in
+ --*=*)
+ ac_option=`expr "X$1" : 'X\([^=]*\)='`
+ ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'`
+ ac_shift=:
+ ;;
+ *)
+ ac_option=$1
+ ac_optarg=$2
+ ac_shift=shift
+ ;;
+ esac
+
+ case $ac_option in
+ # Handling of the options.
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ ac_cs_recheck=: ;;
+ --version | --versio | --versi | --vers | --ver | --ve | --v | -V )
+ $as_echo "$ac_cs_version"; exit ;;
+ --debug | --debu | --deb | --de | --d | -d )
+ debug=: ;;
+ --file | --fil | --fi | --f )
+ $ac_shift
+ case $ac_optarg in
+ *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ esac
+ as_fn_append CONFIG_FILES " '$ac_optarg'"
+ ac_need_defaults=false;;
+ --header | --heade | --head | --hea )
+ $ac_shift
+ case $ac_optarg in
+ *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ esac
+ as_fn_append CONFIG_HEADERS " '$ac_optarg'"
+ ac_need_defaults=false;;
+ --he | --h)
+ # Conflict between --help and --header
+ as_fn_error "ambiguous option: \`$1'
+Try \`$0 --help' for more information.";;
+ --help | --hel | -h )
+ $as_echo "$ac_cs_usage"; exit ;;
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil | --si | --s)
+ ac_cs_silent=: ;;
+
+ # This is an error.
+ -*) as_fn_error "unrecognized option: \`$1'
+Try \`$0 --help' for more information." ;;
+
+ *) as_fn_append ac_config_targets " $1"
+ ac_need_defaults=false ;;
+
+ esac
+ shift
+done
+
+ac_configure_extra_args=
+
+if $ac_cs_silent; then
+ exec 6>/dev/null
+ ac_configure_extra_args="$ac_configure_extra_args --silent"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+if \$ac_cs_recheck; then
+ set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+ shift
+ \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6
+ CONFIG_SHELL='$SHELL'
+ export CONFIG_SHELL
+ exec "\$@"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+exec 5>>config.log
+{
+ echo
+ sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## Running $as_me. ##
+_ASBOX
+ $as_echo "$ac_log"
+} >&5
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+#
+# INIT-COMMANDS
+#
+AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"
+
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+sed_quote_subst='$sed_quote_subst'
+double_quote_subst='$double_quote_subst'
+delay_variable_subst='$delay_variable_subst'
+enable_shared='`$ECHO "$enable_shared" | $SED "$delay_single_quote_subst"`'
+macro_version='`$ECHO "$macro_version" | $SED "$delay_single_quote_subst"`'
+macro_revision='`$ECHO "$macro_revision" | $SED "$delay_single_quote_subst"`'
+enable_static='`$ECHO "$enable_static" | $SED "$delay_single_quote_subst"`'
+pic_mode='`$ECHO "$pic_mode" | $SED "$delay_single_quote_subst"`'
+enable_fast_install='`$ECHO "$enable_fast_install" | $SED "$delay_single_quote_subst"`'
+SHELL='`$ECHO "$SHELL" | $SED "$delay_single_quote_subst"`'
+ECHO='`$ECHO "$ECHO" | $SED "$delay_single_quote_subst"`'
+host_alias='`$ECHO "$host_alias" | $SED "$delay_single_quote_subst"`'
+host='`$ECHO "$host" | $SED "$delay_single_quote_subst"`'
+host_os='`$ECHO "$host_os" | $SED "$delay_single_quote_subst"`'
+build_alias='`$ECHO "$build_alias" | $SED "$delay_single_quote_subst"`'
+build='`$ECHO "$build" | $SED "$delay_single_quote_subst"`'
+build_os='`$ECHO "$build_os" | $SED "$delay_single_quote_subst"`'
+SED='`$ECHO "$SED" | $SED "$delay_single_quote_subst"`'
+Xsed='`$ECHO "$Xsed" | $SED "$delay_single_quote_subst"`'
+GREP='`$ECHO "$GREP" | $SED "$delay_single_quote_subst"`'
+EGREP='`$ECHO "$EGREP" | $SED "$delay_single_quote_subst"`'
+FGREP='`$ECHO "$FGREP" | $SED "$delay_single_quote_subst"`'
+LD='`$ECHO "$LD" | $SED "$delay_single_quote_subst"`'
+NM='`$ECHO "$NM" | $SED "$delay_single_quote_subst"`'
+LN_S='`$ECHO "$LN_S" | $SED "$delay_single_quote_subst"`'
+max_cmd_len='`$ECHO "$max_cmd_len" | $SED "$delay_single_quote_subst"`'
+ac_objext='`$ECHO "$ac_objext" | $SED "$delay_single_quote_subst"`'
+exeext='`$ECHO "$exeext" | $SED "$delay_single_quote_subst"`'
+lt_unset='`$ECHO "$lt_unset" | $SED "$delay_single_quote_subst"`'
+lt_SP2NL='`$ECHO "$lt_SP2NL" | $SED "$delay_single_quote_subst"`'
+lt_NL2SP='`$ECHO "$lt_NL2SP" | $SED "$delay_single_quote_subst"`'
+reload_flag='`$ECHO "$reload_flag" | $SED "$delay_single_quote_subst"`'
+reload_cmds='`$ECHO "$reload_cmds" | $SED "$delay_single_quote_subst"`'
+OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`'
+deplibs_check_method='`$ECHO "$deplibs_check_method" | $SED "$delay_single_quote_subst"`'
+file_magic_cmd='`$ECHO "$file_magic_cmd" | $SED "$delay_single_quote_subst"`'
+AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`'
+AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`'
+STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`'
+RANLIB='`$ECHO "$RANLIB" | $SED "$delay_single_quote_subst"`'
+old_postinstall_cmds='`$ECHO "$old_postinstall_cmds" | $SED "$delay_single_quote_subst"`'
+old_postuninstall_cmds='`$ECHO "$old_postuninstall_cmds" | $SED "$delay_single_quote_subst"`'
+old_archive_cmds='`$ECHO "$old_archive_cmds" | $SED "$delay_single_quote_subst"`'
+lock_old_archive_extraction='`$ECHO "$lock_old_archive_extraction" | $SED "$delay_single_quote_subst"`'
+CC='`$ECHO "$CC" | $SED "$delay_single_quote_subst"`'
+CFLAGS='`$ECHO "$CFLAGS" | $SED "$delay_single_quote_subst"`'
+compiler='`$ECHO "$compiler" | $SED "$delay_single_quote_subst"`'
+GCC='`$ECHO "$GCC" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_pipe='`$ECHO "$lt_cv_sys_global_symbol_pipe" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`'
+objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`'
+MAGIC_CMD='`$ECHO "$MAGIC_CMD" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_no_builtin_flag='`$ECHO "$lt_prog_compiler_no_builtin_flag" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_pic='`$ECHO "$lt_prog_compiler_pic" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_static='`$ECHO "$lt_prog_compiler_static" | $SED "$delay_single_quote_subst"`'
+lt_cv_prog_compiler_c_o='`$ECHO "$lt_cv_prog_compiler_c_o" | $SED "$delay_single_quote_subst"`'
+need_locks='`$ECHO "$need_locks" | $SED "$delay_single_quote_subst"`'
+DSYMUTIL='`$ECHO "$DSYMUTIL" | $SED "$delay_single_quote_subst"`'
+NMEDIT='`$ECHO "$NMEDIT" | $SED "$delay_single_quote_subst"`'
+LIPO='`$ECHO "$LIPO" | $SED "$delay_single_quote_subst"`'
+OTOOL='`$ECHO "$OTOOL" | $SED "$delay_single_quote_subst"`'
+OTOOL64='`$ECHO "$OTOOL64" | $SED "$delay_single_quote_subst"`'
+libext='`$ECHO "$libext" | $SED "$delay_single_quote_subst"`'
+shrext_cmds='`$ECHO "$shrext_cmds" | $SED "$delay_single_quote_subst"`'
+extract_expsyms_cmds='`$ECHO "$extract_expsyms_cmds" | $SED "$delay_single_quote_subst"`'
+archive_cmds_need_lc='`$ECHO "$archive_cmds_need_lc" | $SED "$delay_single_quote_subst"`'
+enable_shared_with_static_runtimes='`$ECHO "$enable_shared_with_static_runtimes" | $SED "$delay_single_quote_subst"`'
+export_dynamic_flag_spec='`$ECHO "$export_dynamic_flag_spec" | $SED "$delay_single_quote_subst"`'
+whole_archive_flag_spec='`$ECHO "$whole_archive_flag_spec" | $SED "$delay_single_quote_subst"`'
+compiler_needs_object='`$ECHO "$compiler_needs_object" | $SED "$delay_single_quote_subst"`'
+old_archive_from_new_cmds='`$ECHO "$old_archive_from_new_cmds" | $SED "$delay_single_quote_subst"`'
+old_archive_from_expsyms_cmds='`$ECHO "$old_archive_from_expsyms_cmds" | $SED "$delay_single_quote_subst"`'
+archive_cmds='`$ECHO "$archive_cmds" | $SED "$delay_single_quote_subst"`'
+archive_expsym_cmds='`$ECHO "$archive_expsym_cmds" | $SED "$delay_single_quote_subst"`'
+module_cmds='`$ECHO "$module_cmds" | $SED "$delay_single_quote_subst"`'
+module_expsym_cmds='`$ECHO "$module_expsym_cmds" | $SED "$delay_single_quote_subst"`'
+with_gnu_ld='`$ECHO "$with_gnu_ld" | $SED "$delay_single_quote_subst"`'
+allow_undefined_flag='`$ECHO "$allow_undefined_flag" | $SED "$delay_single_quote_subst"`'
+no_undefined_flag='`$ECHO "$no_undefined_flag" | $SED "$delay_single_quote_subst"`'
+hardcode_libdir_flag_spec='`$ECHO "$hardcode_libdir_flag_spec" | $SED "$delay_single_quote_subst"`'
+hardcode_libdir_flag_spec_ld='`$ECHO "$hardcode_libdir_flag_spec_ld" | $SED "$delay_single_quote_subst"`'
+hardcode_libdir_separator='`$ECHO "$hardcode_libdir_separator" | $SED "$delay_single_quote_subst"`'
+hardcode_direct='`$ECHO "$hardcode_direct" | $SED "$delay_single_quote_subst"`'
+hardcode_direct_absolute='`$ECHO "$hardcode_direct_absolute" | $SED "$delay_single_quote_subst"`'
+hardcode_minus_L='`$ECHO "$hardcode_minus_L" | $SED "$delay_single_quote_subst"`'
+hardcode_shlibpath_var='`$ECHO "$hardcode_shlibpath_var" | $SED "$delay_single_quote_subst"`'
+hardcode_automatic='`$ECHO "$hardcode_automatic" | $SED "$delay_single_quote_subst"`'
+inherit_rpath='`$ECHO "$inherit_rpath" | $SED "$delay_single_quote_subst"`'
+link_all_deplibs='`$ECHO "$link_all_deplibs" | $SED "$delay_single_quote_subst"`'
+fix_srcfile_path='`$ECHO "$fix_srcfile_path" | $SED "$delay_single_quote_subst"`'
+always_export_symbols='`$ECHO "$always_export_symbols" | $SED "$delay_single_quote_subst"`'
+export_symbols_cmds='`$ECHO "$export_symbols_cmds" | $SED "$delay_single_quote_subst"`'
+exclude_expsyms='`$ECHO "$exclude_expsyms" | $SED "$delay_single_quote_subst"`'
+include_expsyms='`$ECHO "$include_expsyms" | $SED "$delay_single_quote_subst"`'
+prelink_cmds='`$ECHO "$prelink_cmds" | $SED "$delay_single_quote_subst"`'
+file_list_spec='`$ECHO "$file_list_spec" | $SED "$delay_single_quote_subst"`'
+variables_saved_for_relink='`$ECHO "$variables_saved_for_relink" | $SED "$delay_single_quote_subst"`'
+need_lib_prefix='`$ECHO "$need_lib_prefix" | $SED "$delay_single_quote_subst"`'
+need_version='`$ECHO "$need_version" | $SED "$delay_single_quote_subst"`'
+version_type='`$ECHO "$version_type" | $SED "$delay_single_quote_subst"`'
+runpath_var='`$ECHO "$runpath_var" | $SED "$delay_single_quote_subst"`'
+shlibpath_var='`$ECHO "$shlibpath_var" | $SED "$delay_single_quote_subst"`'
+shlibpath_overrides_runpath='`$ECHO "$shlibpath_overrides_runpath" | $SED "$delay_single_quote_subst"`'
+libname_spec='`$ECHO "$libname_spec" | $SED "$delay_single_quote_subst"`'
+library_names_spec='`$ECHO "$library_names_spec" | $SED "$delay_single_quote_subst"`'
+soname_spec='`$ECHO "$soname_spec" | $SED "$delay_single_quote_subst"`'
+install_override_mode='`$ECHO "$install_override_mode" | $SED "$delay_single_quote_subst"`'
+postinstall_cmds='`$ECHO "$postinstall_cmds" | $SED "$delay_single_quote_subst"`'
+postuninstall_cmds='`$ECHO "$postuninstall_cmds" | $SED "$delay_single_quote_subst"`'
+finish_cmds='`$ECHO "$finish_cmds" | $SED "$delay_single_quote_subst"`'
+finish_eval='`$ECHO "$finish_eval" | $SED "$delay_single_quote_subst"`'
+hardcode_into_libs='`$ECHO "$hardcode_into_libs" | $SED "$delay_single_quote_subst"`'
+sys_lib_search_path_spec='`$ECHO "$sys_lib_search_path_spec" | $SED "$delay_single_quote_subst"`'
+sys_lib_dlsearch_path_spec='`$ECHO "$sys_lib_dlsearch_path_spec" | $SED "$delay_single_quote_subst"`'
+hardcode_action='`$ECHO "$hardcode_action" | $SED "$delay_single_quote_subst"`'
+enable_dlopen='`$ECHO "$enable_dlopen" | $SED "$delay_single_quote_subst"`'
+enable_dlopen_self='`$ECHO "$enable_dlopen_self" | $SED "$delay_single_quote_subst"`'
+enable_dlopen_self_static='`$ECHO "$enable_dlopen_self_static" | $SED "$delay_single_quote_subst"`'
+old_striplib='`$ECHO "$old_striplib" | $SED "$delay_single_quote_subst"`'
+striplib='`$ECHO "$striplib" | $SED "$delay_single_quote_subst"`'
+
+LTCC='$LTCC'
+LTCFLAGS='$LTCFLAGS'
+compiler='$compiler_DEFAULT'
+
+# A function that is used when there is no print builtin or printf.
+func_fallback_echo ()
+{
+ eval 'cat <<_LTECHO_EOF
+\$1
+_LTECHO_EOF'
+}
+
+# Quote evaled strings.
+for var in SHELL \
+ECHO \
+SED \
+GREP \
+EGREP \
+FGREP \
+LD \
+NM \
+LN_S \
+lt_SP2NL \
+lt_NL2SP \
+reload_flag \
+OBJDUMP \
+deplibs_check_method \
+file_magic_cmd \
+AR \
+AR_FLAGS \
+STRIP \
+RANLIB \
+CC \
+CFLAGS \
+compiler \
+lt_cv_sys_global_symbol_pipe \
+lt_cv_sys_global_symbol_to_cdecl \
+lt_cv_sys_global_symbol_to_c_name_address \
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \
+lt_prog_compiler_no_builtin_flag \
+lt_prog_compiler_wl \
+lt_prog_compiler_pic \
+lt_prog_compiler_static \
+lt_cv_prog_compiler_c_o \
+need_locks \
+DSYMUTIL \
+NMEDIT \
+LIPO \
+OTOOL \
+OTOOL64 \
+shrext_cmds \
+export_dynamic_flag_spec \
+whole_archive_flag_spec \
+compiler_needs_object \
+with_gnu_ld \
+allow_undefined_flag \
+no_undefined_flag \
+hardcode_libdir_flag_spec \
+hardcode_libdir_flag_spec_ld \
+hardcode_libdir_separator \
+fix_srcfile_path \
+exclude_expsyms \
+include_expsyms \
+file_list_spec \
+variables_saved_for_relink \
+libname_spec \
+library_names_spec \
+soname_spec \
+install_override_mode \
+finish_eval \
+old_striplib \
+striplib; do
+ case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
+ *[\\\\\\\`\\"\\\$]*)
+ eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\""
+ ;;
+ *)
+ eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
+ ;;
+ esac
+done
+
+# Double-quote double-evaled strings.
+for var in reload_cmds \
+old_postinstall_cmds \
+old_postuninstall_cmds \
+old_archive_cmds \
+extract_expsyms_cmds \
+old_archive_from_new_cmds \
+old_archive_from_expsyms_cmds \
+archive_cmds \
+archive_expsym_cmds \
+module_cmds \
+module_expsym_cmds \
+export_symbols_cmds \
+prelink_cmds \
+postinstall_cmds \
+postuninstall_cmds \
+finish_cmds \
+sys_lib_search_path_spec \
+sys_lib_dlsearch_path_spec; do
+ case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
+ *[\\\\\\\`\\"\\\$]*)
+ eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\""
+ ;;
+ *)
+ eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
+ ;;
+ esac
+done
+
+ac_aux_dir='$ac_aux_dir'
+xsi_shell='$xsi_shell'
+lt_shell_append='$lt_shell_append'
+
+# See if we are running on zsh, and set the options which allow our
+# commands through without removal of \ escapes INIT.
+if test -n "\${ZSH_VERSION+set}" ; then
+ setopt NO_GLOB_SUBST
+fi
+
+
+ PACKAGE='$PACKAGE'
+ VERSION='$VERSION'
+ TIMESTAMP='$TIMESTAMP'
+ RM='$RM'
+ ofile='$ofile'
+
+
+
+# Capture the value of obsolete ALL_LINGUAS because we need it to compute
+ # POFILES, GMOFILES, UPDATEPOFILES, DUMMYPOFILES, CATALOGS. But hide it
+ # from automake.
+ eval 'OBSOLETE_ALL_LINGUAS''="$ALL_LINGUAS"'
+ # Capture the value of LINGUAS because we need it to compute CATALOGS.
+ LINGUAS="${LINGUAS-%UNSET%}"
+
+
+GCC="$GCC"
+CC="$CC"
+acx_cv_header_stdint="$acx_cv_header_stdint"
+acx_cv_type_int8_t="$acx_cv_type_int8_t"
+acx_cv_type_int16_t="$acx_cv_type_int16_t"
+acx_cv_type_int32_t="$acx_cv_type_int32_t"
+acx_cv_type_int64_t="$acx_cv_type_int64_t"
+acx_cv_type_intptr_t="$acx_cv_type_intptr_t"
+ac_cv_type_uintmax_t="$ac_cv_type_uintmax_t"
+ac_cv_type_uintptr_t="$ac_cv_type_uintptr_t"
+ac_cv_type_uint64_t="$ac_cv_type_uint64_t"
+ac_cv_type_u_int64_t="$ac_cv_type_u_int64_t"
+ac_cv_type_u_int32_t="$ac_cv_type_u_int32_t"
+ac_cv_type_int_least32_t="$ac_cv_type_int_least32_t"
+ac_cv_type_int_fast32_t="$ac_cv_type_int_fast32_t"
+ac_cv_sizeof_void_p="$ac_cv_sizeof_void_p"
+
+
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+
+# Handling of arguments.
+for ac_config_target in $ac_config_targets
+do
+ case $ac_config_target in
+ "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;;
+ "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;;
+ "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h:config.in" ;;
+ "default-1") CONFIG_COMMANDS="$CONFIG_COMMANDS default-1" ;;
+ "bfd_stdint.h") CONFIG_COMMANDS="$CONFIG_COMMANDS bfd_stdint.h" ;;
+ "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
+ "doc/Makefile") CONFIG_FILES="$CONFIG_FILES doc/Makefile" ;;
+ "bfd-in3.h") CONFIG_FILES="$CONFIG_FILES bfd-in3.h:bfd-in2.h" ;;
+ "po/Makefile.in") CONFIG_FILES="$CONFIG_FILES po/Makefile.in:po/Make-in" ;;
+ "default") CONFIG_COMMANDS="$CONFIG_COMMANDS default" ;;
+
+ *) as_fn_error "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
+ esac
+done
+
+
+# If the user did not use the arguments to specify the items to instantiate,
+# then the envvar interface is used. Set only those that are not.
+# We use the long form for the default assignment because of an extremely
+# bizarre bug on SunOS 4.1.3.
+if $ac_need_defaults; then
+ test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
+ test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers
+ test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands
+fi
+
+# Have a temporary directory for convenience. Make it in the build tree
+# simply because there is no reason against having it here, and in addition,
+# creating and moving files from /tmp can sometimes cause problems.
+# Hook for its removal unless debugging.
+# Note that there is a small window in which the directory will not be cleaned:
+# after its creation but before its name has been assigned to `$tmp'.
+$debug ||
+{
+ tmp=
+ trap 'exit_status=$?
+ { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status
+' 0
+ trap 'as_fn_exit 1' 1 2 13 15
+}
+# Create a (secure) tmp directory for tmp files.
+
+{
+ tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` &&
+ test -n "$tmp" && test -d "$tmp"
+} ||
+{
+ tmp=./conf$$-$RANDOM
+ (umask 077 && mkdir "$tmp")
+} || as_fn_error "cannot create a temporary directory in ." "$LINENO" 5
+
+# Set up the scripts for CONFIG_FILES section.
+# No need to generate them if there are no CONFIG_FILES.
+# This happens for instance with `./config.status config.h'.
+if test -n "$CONFIG_FILES"; then
+
+
+ac_cr=`echo X | tr X '\015'`
+# On cygwin, bash can eat \r inside `` if the user requested igncr.
+# But we know of no other shell where ac_cr would be empty at this
+# point, so we can use a bashism as a fallback.
+if test "x$ac_cr" = x; then
+ eval ac_cr=\$\'\\r\'
+fi
+ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' </dev/null 2>/dev/null`
+if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then
+ ac_cs_awk_cr='\r'
+else
+ ac_cs_awk_cr=$ac_cr
+fi
+
+echo 'BEGIN {' >"$tmp/subs1.awk" &&
+_ACEOF
+
+
+{
+ echo "cat >conf$$subs.awk <<_ACEOF" &&
+ echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' &&
+ echo "_ACEOF"
+} >conf$$subs.sh ||
+ as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5
+ac_delim_num=`echo "$ac_subst_vars" | grep -c '$'`
+ac_delim='%!_!# '
+for ac_last_try in false false false false false :; do
+ . ./conf$$subs.sh ||
+ as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5
+
+ ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X`
+ if test $ac_delim_n = $ac_delim_num; then
+ break
+ elif $ac_last_try; then
+ as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5
+ else
+ ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
+ fi
+done
+rm -f conf$$subs.sh
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+cat >>"\$tmp/subs1.awk" <<\\_ACAWK &&
+_ACEOF
+sed -n '
+h
+s/^/S["/; s/!.*/"]=/
+p
+g
+s/^[^!]*!//
+:repl
+t repl
+s/'"$ac_delim"'$//
+t delim
+:nl
+h
+s/\(.\{148\}\).*/\1/
+t more1
+s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/
+p
+n
+b repl
+:more1
+s/["\\]/\\&/g; s/^/"/; s/$/"\\/
+p
+g
+s/.\{148\}//
+t nl
+:delim
+h
+s/\(.\{148\}\).*/\1/
+t more2
+s/["\\]/\\&/g; s/^/"/; s/$/"/
+p
+b
+:more2
+s/["\\]/\\&/g; s/^/"/; s/$/"\\/
+p
+g
+s/.\{148\}//
+t delim
+' <conf$$subs.awk | sed '
+/^[^""]/{
+ N
+ s/\n//
+}
+' >>$CONFIG_STATUS || ac_write_fail=1
+rm -f conf$$subs.awk
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+_ACAWK
+cat >>"\$tmp/subs1.awk" <<_ACAWK &&
+ for (key in S) S_is_set[key] = 1
+ FS = ""
+
+}
+{
+ line = $ 0
+ nfields = split(line, field, "@")
+ substed = 0
+ len = length(field[1])
+ for (i = 2; i < nfields; i++) {
+ key = field[i]
+ keylen = length(key)
+ if (S_is_set[key]) {
+ value = S[key]
+ line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3)
+ len += length(value) + length(field[++i])
+ substed = 1
+ } else
+ len += 1 + keylen
+ }
+
+ print line
+}
+
+_ACAWK
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then
+ sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g"
+else
+ cat
+fi < "$tmp/subs1.awk" > "$tmp/subs.awk" \
+ || as_fn_error "could not setup config files machinery" "$LINENO" 5
+_ACEOF
+
+# VPATH may cause trouble with some makes, so we remove $(srcdir),
+# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and
+# trailing colons and then remove the whole line if VPATH becomes empty
+# (actually we leave an empty line to preserve line numbers).
+if test "x$srcdir" = x.; then
+ ac_vpsub='/^[ ]*VPATH[ ]*=/{
+s/:*\$(srcdir):*/:/
+s/:*\${srcdir}:*/:/
+s/:*@srcdir@:*/:/
+s/^\([^=]*=[ ]*\):*/\1/
+s/:*$//
+s/^[^=]*=[ ]*$//
+}'
+fi
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+fi # test -n "$CONFIG_FILES"
+
+# Set up the scripts for CONFIG_HEADERS section.
+# No need to generate them if there are no CONFIG_HEADERS.
+# This happens for instance with `./config.status Makefile'.
+if test -n "$CONFIG_HEADERS"; then
+cat >"$tmp/defines.awk" <<\_ACAWK ||
+BEGIN {
+_ACEOF
+
+# Transform confdefs.h into an awk script `defines.awk', embedded as
+# here-document in config.status, that substitutes the proper values into
+# config.h.in to produce config.h.
+
+# Create a delimiter string that does not exist in confdefs.h, to ease
+# handling of long lines.
+ac_delim='%!_!# '
+for ac_last_try in false false :; do
+ ac_t=`sed -n "/$ac_delim/p" confdefs.h`
+ if test -z "$ac_t"; then
+ break
+ elif $ac_last_try; then
+ as_fn_error "could not make $CONFIG_HEADERS" "$LINENO" 5
+ else
+ ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
+ fi
+done
+
+# For the awk script, D is an array of macro values keyed by name,
+# likewise P contains macro parameters if any. Preserve backslash
+# newline sequences.
+
+ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]*
+sed -n '
+s/.\{148\}/&'"$ac_delim"'/g
+t rset
+:rset
+s/^[ ]*#[ ]*define[ ][ ]*/ /
+t def
+d
+:def
+s/\\$//
+t bsnl
+s/["\\]/\\&/g
+s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\
+D["\1"]=" \3"/p
+s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p
+d
+:bsnl
+s/["\\]/\\&/g
+s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\
+D["\1"]=" \3\\\\\\n"\\/p
+t cont
+s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p
+t cont
+d
+:cont
+n
+s/.\{148\}/&'"$ac_delim"'/g
+t clear
+:clear
+s/\\$//
+t bsnlc
+s/["\\]/\\&/g; s/^/"/; s/$/"/p
+d
+:bsnlc
+s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p
+b cont
+' <confdefs.h | sed '
+s/'"$ac_delim"'/"\\\
+"/g' >>$CONFIG_STATUS || ac_write_fail=1
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ for (key in D) D_is_set[key] = 1
+ FS = ""
+}
+/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ {
+ line = \$ 0
+ split(line, arg, " ")
+ if (arg[1] == "#") {
+ defundef = arg[2]
+ mac1 = arg[3]
+ } else {
+ defundef = substr(arg[1], 2)
+ mac1 = arg[2]
+ }
+ split(mac1, mac2, "(") #)
+ macro = mac2[1]
+ prefix = substr(line, 1, index(line, defundef) - 1)
+ if (D_is_set[macro]) {
+ # Preserve the white space surrounding the "#".
+ print prefix "define", macro P[macro] D[macro]
+ next
+ } else {
+ # Replace #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.
+ if (defundef == "undef") {
+ print "/*", prefix defundef, macro, "*/"
+ next
+ }
+ }
+}
+{ print }
+_ACAWK
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+ as_fn_error "could not setup config headers machinery" "$LINENO" 5
+fi # test -n "$CONFIG_HEADERS"
+
+
+eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS"
+shift
+for ac_tag
+do
+ case $ac_tag in
+ :[FHLC]) ac_mode=$ac_tag; continue;;
+ esac
+ case $ac_mode$ac_tag in
+ :[FHL]*:*);;
+ :L* | :C*:*) as_fn_error "invalid tag \`$ac_tag'" "$LINENO" 5;;
+ :[FH]-) ac_tag=-:-;;
+ :[FH]*) ac_tag=$ac_tag:$ac_tag.in;;
+ esac
+ ac_save_IFS=$IFS
+ IFS=:
+ set x $ac_tag
+ IFS=$ac_save_IFS
+ shift
+ ac_file=$1
+ shift
+
+ case $ac_mode in
+ :L) ac_source=$1;;
+ :[FH])
+ ac_file_inputs=
+ for ac_f
+ do
+ case $ac_f in
+ -) ac_f="$tmp/stdin";;
+ *) # Look for the file first in the build tree, then in the source tree
+ # (if the path is not absolute). The absolute path cannot be DOS-style,
+ # because $ac_f cannot contain `:'.
+ test -f "$ac_f" ||
+ case $ac_f in
+ [\\/$]*) false;;
+ *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;
+ esac ||
+ as_fn_error "cannot find input file: \`$ac_f'" "$LINENO" 5;;
+ esac
+ case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac
+ as_fn_append ac_file_inputs " '$ac_f'"
+ done
+
+ # Let's still pretend it is `configure' which instantiates (i.e., don't
+ # use $as_me), people would be surprised to read:
+ # /* config.h. Generated by config.status. */
+ configure_input='Generated from '`
+ $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g'
+ `' by configure.'
+ if test x"$ac_file" != x-; then
+ configure_input="$ac_file. $configure_input"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5
+$as_echo "$as_me: creating $ac_file" >&6;}
+ fi
+ # Neutralize special characters interpreted by sed in replacement strings.
+ case $configure_input in #(
+ *\&* | *\|* | *\\* )
+ ac_sed_conf_input=`$as_echo "$configure_input" |
+ sed 's/[\\\\&|]/\\\\&/g'`;; #(
+ *) ac_sed_conf_input=$configure_input;;
+ esac
+
+ case $ac_tag in
+ *:-:* | *:-) cat >"$tmp/stdin" \
+ || as_fn_error "could not create $ac_file" "$LINENO" 5 ;;
+ esac
+ ;;
+ esac
+
+ ac_dir=`$as_dirname -- "$ac_file" ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$ac_file" : 'X\(//\)[^/]' \| \
+ X"$ac_file" : 'X\(//\)$' \| \
+ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$ac_file" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ as_dir="$ac_dir"; as_fn_mkdir_p
+ ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+ ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+ # A ".." for each directory in $ac_dir_suffix.
+ ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+ case $ac_top_builddir_sub in
+ "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+ *) ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+ esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+ .) # We are building in place.
+ ac_srcdir=.
+ ac_top_srcdir=$ac_top_builddir_sub
+ ac_abs_top_srcdir=$ac_pwd ;;
+ [\\/]* | ?:[\\/]* ) # Absolute name.
+ ac_srcdir=$srcdir$ac_dir_suffix;
+ ac_top_srcdir=$srcdir
+ ac_abs_top_srcdir=$srcdir ;;
+ *) # Relative name.
+ ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+ ac_top_srcdir=$ac_top_build_prefix$srcdir
+ ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+
+ case $ac_mode in
+ :F)
+ #
+ # CONFIG_FILE
+ #
+
+ case $INSTALL in
+ [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;;
+ *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;;
+ esac
+ ac_MKDIR_P=$MKDIR_P
+ case $MKDIR_P in
+ [\\/$]* | ?:[\\/]* ) ;;
+ */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;;
+ esac
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# If the template does not know about datarootdir, expand it.
+# FIXME: This hack should be removed a few years after 2.60.
+ac_datarootdir_hack=; ac_datarootdir_seen=
+ac_sed_dataroot='
+/datarootdir/ {
+ p
+ q
+}
+/@datadir@/p
+/@docdir@/p
+/@infodir@/p
+/@localedir@/p
+/@mandir@/p'
+case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in
+*datarootdir*) ac_datarootdir_seen=yes;;
+*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5
+$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;}
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ ac_datarootdir_hack='
+ s&@datadir@&$datadir&g
+ s&@docdir@&$docdir&g
+ s&@infodir@&$infodir&g
+ s&@localedir@&$localedir&g
+ s&@mandir@&$mandir&g
+ s&\\\${datarootdir}&$datarootdir&g' ;;
+esac
+_ACEOF
+
+# Neutralize VPATH when `$srcdir' = `.'.
+# Shell code in configure.ac might set extrasub.
+# FIXME: do we really want to maintain this feature?
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_sed_extra="$ac_vpsub
+$extrasub
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+:t
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
+s|@configure_input@|$ac_sed_conf_input|;t t
+s&@top_builddir@&$ac_top_builddir_sub&;t t
+s&@top_build_prefix@&$ac_top_build_prefix&;t t
+s&@srcdir@&$ac_srcdir&;t t
+s&@abs_srcdir@&$ac_abs_srcdir&;t t
+s&@top_srcdir@&$ac_top_srcdir&;t t
+s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t
+s&@builddir@&$ac_builddir&;t t
+s&@abs_builddir@&$ac_abs_builddir&;t t
+s&@abs_top_builddir@&$ac_abs_top_builddir&;t t
+s&@INSTALL@&$ac_INSTALL&;t t
+s&@MKDIR_P@&$ac_MKDIR_P&;t t
+$ac_datarootdir_hack
+"
+eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$tmp/subs.awk" >$tmp/out \
+ || as_fn_error "could not create $ac_file" "$LINENO" 5
+
+test -z "$ac_datarootdir_hack$ac_datarootdir_seen" &&
+ { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } &&
+ { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } &&
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined. Please make sure it is defined." >&5
+$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined. Please make sure it is defined." >&2;}
+
+ rm -f "$tmp/stdin"
+ case $ac_file in
+ -) cat "$tmp/out" && rm -f "$tmp/out";;
+ *) rm -f "$ac_file" && mv "$tmp/out" "$ac_file";;
+ esac \
+ || as_fn_error "could not create $ac_file" "$LINENO" 5
+ ;;
+ :H)
+ #
+ # CONFIG_HEADER
+ #
+ if test x"$ac_file" != x-; then
+ {
+ $as_echo "/* $configure_input */" \
+ && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs"
+ } >"$tmp/config.h" \
+ || as_fn_error "could not create $ac_file" "$LINENO" 5
+ if diff "$ac_file" "$tmp/config.h" >/dev/null 2>&1; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5
+$as_echo "$as_me: $ac_file is unchanged" >&6;}
+ else
+ rm -f "$ac_file"
+ mv "$tmp/config.h" "$ac_file" \
+ || as_fn_error "could not create $ac_file" "$LINENO" 5
+ fi
+ else
+ $as_echo "/* $configure_input */" \
+ && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs" \
+ || as_fn_error "could not create -" "$LINENO" 5
+ fi
+# Compute "$ac_file"'s index in $config_headers.
+_am_arg="$ac_file"
+_am_stamp_count=1
+for _am_header in $config_headers :; do
+ case $_am_header in
+ $_am_arg | $_am_arg:* )
+ break ;;
+ * )
+ _am_stamp_count=`expr $_am_stamp_count + 1` ;;
+ esac
+done
+echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" ||
+$as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$_am_arg" : 'X\(//\)[^/]' \| \
+ X"$_am_arg" : 'X\(//\)$' \| \
+ X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$_am_arg" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`/stamp-h$_am_stamp_count
+ ;;
+
+ :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5
+$as_echo "$as_me: executing $ac_file commands" >&6;}
+ ;;
+ esac
+
+
+ case $ac_file$ac_mode in
+ "depfiles":C) test x"$AMDEP_TRUE" != x"" || {
+ # Autoconf 2.62 quotes --file arguments for eval, but not when files
+ # are listed without --file. Let's play safe and only enable the eval
+ # if we detect the quoting.
+ case $CONFIG_FILES in
+ *\'*) eval set x "$CONFIG_FILES" ;;
+ *) set x $CONFIG_FILES ;;
+ esac
+ shift
+ for mf
+ do
+ # Strip MF so we end up with the name of the file.
+ mf=`echo "$mf" | sed -e 's/:.*$//'`
+ # Check whether this is an Automake generated Makefile or not.
+ # We used to match only the files named `Makefile.in', but
+ # some people rename them; so instead we look at the file content.
+ # Grep'ing the first line is not enough: some people post-process
+ # each Makefile.in and add a new line on top of each file to say so.
+ # Grep'ing the whole file is not good either: AIX grep has a line
+ # limit of 2048, but all sed's we know have understand at least 4000.
+ if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then
+ dirpart=`$as_dirname -- "$mf" ||
+$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$mf" : 'X\(//\)[^/]' \| \
+ X"$mf" : 'X\(//\)$' \| \
+ X"$mf" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$mf" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ else
+ continue
+ fi
+ # Extract the definition of DEPDIR, am__include, and am__quote
+ # from the Makefile without running `make'.
+ DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
+ test -z "$DEPDIR" && continue
+ am__include=`sed -n 's/^am__include = //p' < "$mf"`
+ test -z "am__include" && continue
+ am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
+ # When using ansi2knr, U may be empty or an underscore; expand it
+ U=`sed -n 's/^U = //p' < "$mf"`
+ # Find all dependency output files, they are included files with
+ # $(DEPDIR) in their names. We invoke sed twice because it is the
+ # simplest approach to changing $(DEPDIR) to its actual value in the
+ # expansion.
+ for file in `sed -n "
+ s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
+ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do
+ # Make sure the directory exists.
+ test -f "$dirpart/$file" && continue
+ fdir=`$as_dirname -- "$file" ||
+$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$file" : 'X\(//\)[^/]' \| \
+ X"$file" : 'X\(//\)$' \| \
+ X"$file" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$file" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ as_dir=$dirpart/$fdir; as_fn_mkdir_p
+ # echo "creating $dirpart/$file"
+ echo '# dummy' > "$dirpart/$file"
+ done
+ done
+}
+ ;;
+ "libtool":C)
+
+ # See if we are running on zsh, and set the options which allow our
+ # commands through without removal of \ escapes.
+ if test -n "${ZSH_VERSION+set}" ; then
+ setopt NO_GLOB_SUBST
+ fi
+
+ cfgfile="${ofile}T"
+ trap "$RM \"$cfgfile\"; exit 1" 1 2 15
+ $RM "$cfgfile"
+
+ cat <<_LT_EOF >> "$cfgfile"
+#! $SHELL
+
+# `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services.
+# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION
+# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+# NOTE: Changes made to this file will be lost: look at ltmain.sh.
+#
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005,
+# 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
+# Written by Gordon Matzigkeit, 1996
+#
+# This file is part of GNU Libtool.
+#
+# GNU Libtool is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# As a special exception to the GNU General Public License,
+# if you distribute this file as part of a program or library that
+# is built using GNU Libtool, you may include this file under the
+# same distribution terms that you use for the rest of that program.
+#
+# GNU Libtool is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR 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 Libtool; see the file COPYING. If not, a copy
+# can be downloaded from http://www.gnu.org/licenses/gpl.html, or
+# obtained by writing to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+
+# The names of the tagged configurations supported by this script.
+available_tags=""
+
+# ### BEGIN LIBTOOL CONFIG
+
+# Whether or not to build shared libraries.
+build_libtool_libs=$enable_shared
+
+# Which release of libtool.m4 was used?
+macro_version=$macro_version
+macro_revision=$macro_revision
+
+# Whether or not to build static libraries.
+build_old_libs=$enable_static
+
+# What type of objects to build.
+pic_mode=$pic_mode
+
+# Whether or not to optimize for fast installation.
+fast_install=$enable_fast_install
+
+# Shell to use when invoking shell scripts.
+SHELL=$lt_SHELL
+
+# An echo program that protects backslashes.
+ECHO=$lt_ECHO
+
+# The host system.
+host_alias=$host_alias
+host=$host
+host_os=$host_os
+
+# The build system.
+build_alias=$build_alias
+build=$build
+build_os=$build_os
+
+# A sed program that does not truncate output.
+SED=$lt_SED
+
+# Sed that helps us avoid accidentally triggering echo(1) options like -n.
+Xsed="\$SED -e 1s/^X//"
+
+# A grep program that handles long lines.
+GREP=$lt_GREP
+
+# An ERE matcher.
+EGREP=$lt_EGREP
+
+# A literal string matcher.
+FGREP=$lt_FGREP
+
+# A BSD- or MS-compatible name lister.
+NM=$lt_NM
+
+# Whether we need soft or hard links.
+LN_S=$lt_LN_S
+
+# What is the maximum length of a command?
+max_cmd_len=$max_cmd_len
+
+# Object file suffix (normally "o").
+objext=$ac_objext
+
+# Executable file suffix (normally "").
+exeext=$exeext
+
+# whether the shell understands "unset".
+lt_unset=$lt_unset
+
+# turn spaces into newlines.
+SP2NL=$lt_lt_SP2NL
+
+# turn newlines into spaces.
+NL2SP=$lt_lt_NL2SP
+
+# An object symbol dumper.
+OBJDUMP=$lt_OBJDUMP
+
+# Method to check whether dependent libraries are shared objects.
+deplibs_check_method=$lt_deplibs_check_method
+
+# Command to use when deplibs_check_method == "file_magic".
+file_magic_cmd=$lt_file_magic_cmd
+
+# The archiver.
+AR=$lt_AR
+AR_FLAGS=$lt_AR_FLAGS
+
+# A symbol stripping program.
+STRIP=$lt_STRIP
+
+# Commands used to install an old-style archive.
+RANLIB=$lt_RANLIB
+old_postinstall_cmds=$lt_old_postinstall_cmds
+old_postuninstall_cmds=$lt_old_postuninstall_cmds
+
+# Whether to use a lock for old archive extraction.
+lock_old_archive_extraction=$lock_old_archive_extraction
+
+# A C compiler.
+LTCC=$lt_CC
+
+# LTCC compiler flags.
+LTCFLAGS=$lt_CFLAGS
+
+# Take the output of nm and produce a listing of raw symbols and C names.
+global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe
+
+# Transform the output of nm in a proper C declaration.
+global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl
+
+# Transform the output of nm in a C name address pair.
+global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address
+
+# Transform the output of nm in a C name address pair when lib prefix is needed.
+global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix
+
+# The name of the directory that contains temporary libtool files.
+objdir=$objdir
+
+# Used to examine libraries when file_magic_cmd begins with "file".
+MAGIC_CMD=$MAGIC_CMD
+
+# Must we lock files when doing compilation?
+need_locks=$lt_need_locks
+
+# Tool to manipulate archived DWARF debug symbol files on Mac OS X.
+DSYMUTIL=$lt_DSYMUTIL
+
+# Tool to change global to local symbols on Mac OS X.
+NMEDIT=$lt_NMEDIT
+
+# Tool to manipulate fat objects and archives on Mac OS X.
+LIPO=$lt_LIPO
+
+# ldd/readelf like tool for Mach-O binaries on Mac OS X.
+OTOOL=$lt_OTOOL
+
+# ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4.
+OTOOL64=$lt_OTOOL64
+
+# Old archive suffix (normally "a").
+libext=$libext
+
+# Shared library suffix (normally ".so").
+shrext_cmds=$lt_shrext_cmds
+
+# The commands to extract the exported symbol list from a shared archive.
+extract_expsyms_cmds=$lt_extract_expsyms_cmds
+
+# Variables whose values should be saved in libtool wrapper scripts and
+# restored at link time.
+variables_saved_for_relink=$lt_variables_saved_for_relink
+
+# 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
+
+# Library versioning type.
+version_type=$version_type
+
+# Shared library runtime path variable.
+runpath_var=$runpath_var
+
+# Shared library path variable.
+shlibpath_var=$shlibpath_var
+
+# Is shlibpath searched before the hard-coded library search path?
+shlibpath_overrides_runpath=$shlibpath_overrides_runpath
+
+# Format of library name prefix.
+libname_spec=$lt_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=$lt_library_names_spec
+
+# The coded name of the library, if different from the real name.
+soname_spec=$lt_soname_spec
+
+# Permission mode override for installation of shared libraries.
+install_override_mode=$lt_install_override_mode
+
+# Command to use after installation of a shared archive.
+postinstall_cmds=$lt_postinstall_cmds
+
+# Command to use after uninstallation of a shared archive.
+postuninstall_cmds=$lt_postuninstall_cmds
+
+# Commands used to finish a libtool library installation in a directory.
+finish_cmds=$lt_finish_cmds
+
+# As "finish_cmds", except a single script fragment to be evaled but
+# not shown.
+finish_eval=$lt_finish_eval
+
+# Whether we should hardcode library paths into libraries.
+hardcode_into_libs=$hardcode_into_libs
+
+# Compile-time system search path for libraries.
+sys_lib_search_path_spec=$lt_sys_lib_search_path_spec
+
+# Run-time system search path for libraries.
+sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec
+
+# Whether dlopen is supported.
+dlopen_support=$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
+
+# Commands to strip libraries.
+old_striplib=$lt_old_striplib
+striplib=$lt_striplib
+
+
+# The linker used to build libraries.
+LD=$lt_LD
+
+# How to create reloadable object files.
+reload_flag=$lt_reload_flag
+reload_cmds=$lt_reload_cmds
+
+# Commands used to build an old-style archive.
+old_archive_cmds=$lt_old_archive_cmds
+
+# A language specific compiler.
+CC=$lt_compiler
+
+# Is the compiler the GNU compiler?
+with_gcc=$GCC
+
+# Compiler flag to turn off builtin functions.
+no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag
+
+# How to pass a linker flag through the compiler.
+wl=$lt_lt_prog_compiler_wl
+
+# Additional compiler flags for building library objects.
+pic_flag=$lt_lt_prog_compiler_pic
+
+# Compiler flag to prevent dynamic linking.
+link_static_flag=$lt_lt_prog_compiler_static
+
+# Does compiler simultaneously support -c and -o options?
+compiler_c_o=$lt_lt_cv_prog_compiler_c_o
+
+# Whether or not to add -lc for building shared libraries.
+build_libtool_need_lc=$archive_cmds_need_lc
+
+# Whether or not to disallow shared libs when runtime libs are static.
+allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes
+
+# Compiler flag to allow reflexive dlopens.
+export_dynamic_flag_spec=$lt_export_dynamic_flag_spec
+
+# Compiler flag to generate shared objects directly from archives.
+whole_archive_flag_spec=$lt_whole_archive_flag_spec
+
+# Whether the compiler copes with passing no objects directly.
+compiler_needs_object=$lt_compiler_needs_object
+
+# Create an old-style archive from a shared archive.
+old_archive_from_new_cmds=$lt_old_archive_from_new_cmds
+
+# Create a temporary old-style archive to link instead of a shared archive.
+old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds
+
+# Commands used to build a shared archive.
+archive_cmds=$lt_archive_cmds
+archive_expsym_cmds=$lt_archive_expsym_cmds
+
+# Commands used to build a loadable module if different from building
+# a shared archive.
+module_cmds=$lt_module_cmds
+module_expsym_cmds=$lt_module_expsym_cmds
+
+# Whether we are building with GNU ld or not.
+with_gnu_ld=$lt_with_gnu_ld
+
+# Flag that allows shared libraries with undefined symbols to be built.
+allow_undefined_flag=$lt_allow_undefined_flag
+
+# Flag that enforces no undefined symbols.
+no_undefined_flag=$lt_no_undefined_flag
+
+# Flag to hardcode \$libdir into a binary during linking.
+# This must work even if \$libdir does not exist
+hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec
+
+# If ld is used when linking, flag to hardcode \$libdir into a binary
+# during linking. This must work even if \$libdir does not exist.
+hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld
+
+# Whether we need a single "-rpath" flag with a separated argument.
+hardcode_libdir_separator=$lt_hardcode_libdir_separator
+
+# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes
+# DIR into the resulting binary.
+hardcode_direct=$hardcode_direct
+
+# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes
+# DIR into the resulting binary and the resulting library dependency is
+# "absolute",i.e impossible to change by setting \${shlibpath_var} if the
+# library is relocated.
+hardcode_direct_absolute=$hardcode_direct_absolute
+
+# 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
+
+# Set to "yes" if building a shared library automatically hardcodes DIR
+# into the library and all subsequent libraries and executables linked
+# against it.
+hardcode_automatic=$hardcode_automatic
+
+# Set to yes if linker adds runtime paths of dependent libraries
+# to runtime path list.
+inherit_rpath=$inherit_rpath
+
+# Whether libtool must link a program against all its dependency libraries.
+link_all_deplibs=$link_all_deplibs
+
+# Fix the shell variable \$srcfile for the compiler.
+fix_srcfile_path=$lt_fix_srcfile_path
+
+# Set to "yes" if exported symbols are required.
+always_export_symbols=$always_export_symbols
+
+# The commands to list exported symbols.
+export_symbols_cmds=$lt_export_symbols_cmds
+
+# Symbols that should not be listed in the preloaded symbols.
+exclude_expsyms=$lt_exclude_expsyms
+
+# Symbols that must always be exported.
+include_expsyms=$lt_include_expsyms
+
+# Commands necessary for linking programs (against libraries) with templates.
+prelink_cmds=$lt_prelink_cmds
+
+# Specify filename containing input files.
+file_list_spec=$lt_file_list_spec
+
+# How to hardcode a shared library path into an executable.
+hardcode_action=$hardcode_action
+
+# ### END LIBTOOL CONFIG
+
+_LT_EOF
+
+ case $host_os in
+ aix3*)
+ cat <<\_LT_EOF >> "$cfgfile"
+# 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 "X${COLLECT_NAMES+set}" != Xset; then
+ COLLECT_NAMES=
+ export COLLECT_NAMES
+fi
+_LT_EOF
+ ;;
+ esac
+
+
+ltmain="$ac_aux_dir/ltmain.sh"
+
+
+ # We use sed instead of cat because bash on DJGPP gets confused if
+ # if finds mixed CR/LF and LF-only lines. Since sed operates in
+ # text mode, it properly converts lines to CR/LF. This bash problem
+ # is reportedly fixed, but why not run on old versions too?
+ sed '/^# Generated shell functions inserted here/q' "$ltmain" >> "$cfgfile" \
+ || (rm -f "$cfgfile"; exit 1)
+
+ case $xsi_shell in
+ yes)
+ cat << \_LT_EOF >> "$cfgfile"
+
+# func_dirname file append nondir_replacement
+# Compute the dirname of FILE. If nonempty, add APPEND to the result,
+# otherwise set result to NONDIR_REPLACEMENT.
+func_dirname ()
+{
+ case ${1} in
+ */*) func_dirname_result="${1%/*}${2}" ;;
+ * ) func_dirname_result="${3}" ;;
+ esac
+}
+
+# func_basename file
+func_basename ()
+{
+ func_basename_result="${1##*/}"
+}
+
+# func_dirname_and_basename file append nondir_replacement
+# perform func_basename and func_dirname in a single function
+# call:
+# dirname: Compute the dirname of FILE. If nonempty,
+# add APPEND to the result, otherwise set result
+# to NONDIR_REPLACEMENT.
+# value returned in "$func_dirname_result"
+# basename: Compute filename of FILE.
+# value retuned in "$func_basename_result"
+# Implementation must be kept synchronized with func_dirname
+# and func_basename. For efficiency, we do not delegate to
+# those functions but instead duplicate the functionality here.
+func_dirname_and_basename ()
+{
+ case ${1} in
+ */*) func_dirname_result="${1%/*}${2}" ;;
+ * ) func_dirname_result="${3}" ;;
+ esac
+ func_basename_result="${1##*/}"
+}
+
+# func_stripname prefix suffix name
+# strip PREFIX and SUFFIX off of NAME.
+# PREFIX and SUFFIX must not contain globbing or regex special
+# characters, hashes, percent signs, but SUFFIX may contain a leading
+# dot (in which case that matches only a dot).
+func_stripname ()
+{
+ # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are
+ # positional parameters, so assign one to ordinary parameter first.
+ func_stripname_result=${3}
+ func_stripname_result=${func_stripname_result#"${1}"}
+ func_stripname_result=${func_stripname_result%"${2}"}
+}
+
+# func_opt_split
+func_opt_split ()
+{
+ func_opt_split_opt=${1%%=*}
+ func_opt_split_arg=${1#*=}
+}
+
+# func_lo2o object
+func_lo2o ()
+{
+ case ${1} in
+ *.lo) func_lo2o_result=${1%.lo}.${objext} ;;
+ *) func_lo2o_result=${1} ;;
+ esac
+}
+
+# func_xform libobj-or-source
+func_xform ()
+{
+ func_xform_result=${1%.*}.lo
+}
+
+# func_arith arithmetic-term...
+func_arith ()
+{
+ func_arith_result=$(( $* ))
+}
+
+# func_len string
+# STRING may not start with a hyphen.
+func_len ()
+{
+ func_len_result=${#1}
+}
+
+_LT_EOF
+ ;;
+ *) # Bourne compatible functions.
+ cat << \_LT_EOF >> "$cfgfile"
+
+# func_dirname file append nondir_replacement
+# Compute the dirname of FILE. If nonempty, add APPEND to the result,
+# otherwise set result to NONDIR_REPLACEMENT.
+func_dirname ()
+{
+ # Extract subdirectory from the argument.
+ func_dirname_result=`$ECHO "${1}" | $SED "$dirname"`
+ if test "X$func_dirname_result" = "X${1}"; then
+ func_dirname_result="${3}"
+ else
+ func_dirname_result="$func_dirname_result${2}"
+ fi
+}
+
+# func_basename file
+func_basename ()
+{
+ func_basename_result=`$ECHO "${1}" | $SED "$basename"`
+}
+
+
+# func_stripname prefix suffix name
+# strip PREFIX and SUFFIX off of NAME.
+# PREFIX and SUFFIX must not contain globbing or regex special
+# characters, hashes, percent signs, but SUFFIX may contain a leading
+# dot (in which case that matches only a dot).
+# func_strip_suffix prefix name
+func_stripname ()
+{
+ case ${2} in
+ .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;;
+ *) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;;
+ esac
+}
+
+# sed scripts:
+my_sed_long_opt='1s/^\(-[^=]*\)=.*/\1/;q'
+my_sed_long_arg='1s/^-[^=]*=//'
+
+# func_opt_split
+func_opt_split ()
+{
+ func_opt_split_opt=`$ECHO "${1}" | $SED "$my_sed_long_opt"`
+ func_opt_split_arg=`$ECHO "${1}" | $SED "$my_sed_long_arg"`
+}
+
+# func_lo2o object
+func_lo2o ()
+{
+ func_lo2o_result=`$ECHO "${1}" | $SED "$lo2o"`
+}
+
+# func_xform libobj-or-source
+func_xform ()
+{
+ func_xform_result=`$ECHO "${1}" | $SED 's/\.[^.]*$/.lo/'`
+}
+
+# func_arith arithmetic-term...
+func_arith ()
+{
+ func_arith_result=`expr "$@"`
+}
+
+# func_len string
+# STRING may not start with a hyphen.
+func_len ()
+{
+ func_len_result=`expr "$1" : ".*" 2>/dev/null || echo $max_cmd_len`
+}
+
+_LT_EOF
+esac
+
+case $lt_shell_append in
+ yes)
+ cat << \_LT_EOF >> "$cfgfile"
+
+# func_append var value
+# Append VALUE to the end of shell variable VAR.
+func_append ()
+{
+ eval "$1+=\$2"
+}
+_LT_EOF
+ ;;
+ *)
+ cat << \_LT_EOF >> "$cfgfile"
+
+# func_append var value
+# Append VALUE to the end of shell variable VAR.
+func_append ()
+{
+ eval "$1=\$$1\$2"
+}
+
+_LT_EOF
+ ;;
+ esac
+
+
+ sed -n '/^# Generated shell functions inserted here/,$p' "$ltmain" >> "$cfgfile" \
+ || (rm -f "$cfgfile"; exit 1)
+
+ mv -f "$cfgfile" "$ofile" ||
+ (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile")
+ chmod +x "$ofile"
+
+ ;;
+ "default-1":C)
+ for ac_file in $CONFIG_FILES; do
+ # Support "outfile[:infile[:infile...]]"
+ case "$ac_file" in
+ *:*) ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+ esac
+ # PO directories have a Makefile.in generated from Makefile.in.in.
+ case "$ac_file" in */Makefile.in)
+ # Adjust a relative srcdir.
+ ac_dir=`echo "$ac_file"|sed 's%/[^/][^/]*$%%'`
+ ac_dir_suffix=/`echo "$ac_dir"|sed 's%^\./%%'`
+ ac_dots=`echo "$ac_dir_suffix"|sed 's%/[^/]*%../%g'`
+ # In autoconf-2.13 it is called $ac_given_srcdir.
+ # In autoconf-2.50 it is called $srcdir.
+ test -n "$ac_given_srcdir" || ac_given_srcdir="$srcdir"
+ case "$ac_given_srcdir" in
+ .) top_srcdir=`echo $ac_dots|sed 's%/$%%'` ;;
+ /*) top_srcdir="$ac_given_srcdir" ;;
+ *) top_srcdir="$ac_dots$ac_given_srcdir" ;;
+ esac
+ if test -f "$ac_given_srcdir/$ac_dir/POTFILES.in"; then
+ rm -f "$ac_dir/POTFILES"
+ test -n "$as_me" && echo "$as_me: creating $ac_dir/POTFILES" || echo "creating $ac_dir/POTFILES"
+ cat "$ac_given_srcdir/$ac_dir/POTFILES.in" | sed -e "/^#/d" -e "/^[ ]*\$/d" -e "s,.*, $top_srcdir/& \\\\," | sed -e "\$s/\(.*\) \\\\/\1/" > "$ac_dir/POTFILES"
+ POMAKEFILEDEPS="POTFILES.in"
+ # ALL_LINGUAS, POFILES, GMOFILES, UPDATEPOFILES, DUMMYPOFILES depend
+ # on $ac_dir but don't depend on user-specified configuration
+ # parameters.
+ if test -f "$ac_given_srcdir/$ac_dir/LINGUAS"; then
+ # The LINGUAS file contains the set of available languages.
+ if test -n "$OBSOLETE_ALL_LINGUAS"; then
+ test -n "$as_me" && echo "$as_me: setting ALL_LINGUAS in configure.in is obsolete" || echo "setting ALL_LINGUAS in configure.in is obsolete"
+ fi
+ ALL_LINGUAS_=`sed -e "/^#/d" "$ac_given_srcdir/$ac_dir/LINGUAS"`
+ # Hide the ALL_LINGUAS assigment from automake.
+ eval 'ALL_LINGUAS''=$ALL_LINGUAS_'
+ POMAKEFILEDEPS="$POMAKEFILEDEPS LINGUAS"
+ else
+ # The set of available languages was given in configure.in.
+ eval 'ALL_LINGUAS''=$OBSOLETE_ALL_LINGUAS'
+ fi
+ case "$ac_given_srcdir" in
+ .) srcdirpre= ;;
+ *) srcdirpre='$(srcdir)/' ;;
+ esac
+ POFILES=
+ GMOFILES=
+ UPDATEPOFILES=
+ DUMMYPOFILES=
+ for lang in $ALL_LINGUAS; do
+ POFILES="$POFILES $srcdirpre$lang.po"
+ GMOFILES="$GMOFILES $srcdirpre$lang.gmo"
+ UPDATEPOFILES="$UPDATEPOFILES $lang.po-update"
+ DUMMYPOFILES="$DUMMYPOFILES $lang.nop"
+ done
+ # CATALOGS depends on both $ac_dir and the user's LINGUAS
+ # environment variable.
+ INST_LINGUAS=
+ if test -n "$ALL_LINGUAS"; then
+ for presentlang in $ALL_LINGUAS; do
+ useit=no
+ if test "%UNSET%" != "$LINGUAS"; then
+ desiredlanguages="$LINGUAS"
+ else
+ desiredlanguages="$ALL_LINGUAS"
+ fi
+ for desiredlang in $desiredlanguages; do
+ # Use the presentlang catalog if desiredlang is
+ # a. equal to presentlang, or
+ # b. a variant of presentlang (because in this case,
+ # presentlang can be used as a fallback for messages
+ # which are not translated in the desiredlang catalog).
+ case "$desiredlang" in
+ "$presentlang"*) useit=yes;;
+ esac
+ done
+ if test $useit = yes; then
+ INST_LINGUAS="$INST_LINGUAS $presentlang"
+ fi
+ done
+ fi
+ CATALOGS=
+ if test -n "$INST_LINGUAS"; then
+ for lang in $INST_LINGUAS; do
+ CATALOGS="$CATALOGS $lang.gmo"
+ done
+ fi
+ test -n "$as_me" && echo "$as_me: creating $ac_dir/Makefile" || echo "creating $ac_dir/Makefile"
+ sed -e "/^POTFILES =/r $ac_dir/POTFILES" -e "/^# Makevars/r $ac_given_srcdir/$ac_dir/Makevars" -e "s|@POFILES@|$POFILES|g" -e "s|@GMOFILES@|$GMOFILES|g" -e "s|@UPDATEPOFILES@|$UPDATEPOFILES|g" -e "s|@DUMMYPOFILES@|$DUMMYPOFILES|g" -e "s|@CATALOGS@|$CATALOGS|g" -e "s|@POMAKEFILEDEPS@|$POMAKEFILEDEPS|g" "$ac_dir/Makefile.in" > "$ac_dir/Makefile"
+ for f in "$ac_given_srcdir/$ac_dir"/Rules-*; do
+ if test -f "$f"; then
+ case "$f" in
+ *.orig | *.bak | *~) ;;
+ *) cat "$f" >> "$ac_dir/Makefile" ;;
+ esac
+ fi
+ done
+ fi
+ ;;
+ esac
+ done ;;
+ "bfd_stdint.h":C)
+if test "$GCC" = yes; then
+ echo "/* generated for " `$CC --version | sed 1q` "*/" > tmp-stdint.h
+else
+ echo "/* generated for $CC */" > tmp-stdint.h
+fi
+
+sed 's/^ *//' >> tmp-stdint.h <<EOF
+
+ #ifndef GCC_GENERATED_STDINT_H
+ #define GCC_GENERATED_STDINT_H 1
+
+ #include <sys/types.h>
+EOF
+
+if test "$acx_cv_header_stdint" != stdint.h; then
+ echo "#include <stddef.h>" >> tmp-stdint.h
+fi
+if test "$acx_cv_header_stdint" != stddef.h; then
+ echo "#include <$acx_cv_header_stdint>" >> tmp-stdint.h
+fi
+
+sed 's/^ *//' >> tmp-stdint.h <<EOF
+ /* glibc uses these symbols as guards to prevent redefinitions. */
+ #ifdef __int8_t_defined
+ #define _INT8_T
+ #define _INT16_T
+ #define _INT32_T
+ #endif
+ #ifdef __uint32_t_defined
+ #define _UINT32_T
+ #endif
+
+EOF
+
+# ----------------- done header, emit basic int types -------------
+if test "$acx_cv_header_stdint" = stddef.h; then
+ sed 's/^ *//' >> tmp-stdint.h <<EOF
+
+ #ifndef _UINT8_T
+ #define _UINT8_T
+ #ifndef __uint8_t_defined
+ #define __uint8_t_defined
+ #ifndef uint8_t
+ typedef unsigned $acx_cv_type_int8_t uint8_t;
+ #endif
+ #endif
+ #endif
+
+ #ifndef _UINT16_T
+ #define _UINT16_T
+ #ifndef __uint16_t_defined
+ #define __uint16_t_defined
+ #ifndef uint16_t
+ typedef unsigned $acx_cv_type_int16_t uint16_t;
+ #endif
+ #endif
+ #endif
+
+ #ifndef _UINT32_T
+ #define _UINT32_T
+ #ifndef __uint32_t_defined
+ #define __uint32_t_defined
+ #ifndef uint32_t
+ typedef unsigned $acx_cv_type_int32_t uint32_t;
+ #endif
+ #endif
+ #endif
+
+ #ifndef _INT8_T
+ #define _INT8_T
+ #ifndef __int8_t_defined
+ #define __int8_t_defined
+ #ifndef int8_t
+ typedef $acx_cv_type_int8_t int8_t;
+ #endif
+ #endif
+ #endif
+
+ #ifndef _INT16_T
+ #define _INT16_T
+ #ifndef __int16_t_defined
+ #define __int16_t_defined
+ #ifndef int16_t
+ typedef $acx_cv_type_int16_t int16_t;
+ #endif
+ #endif
+ #endif
+
+ #ifndef _INT32_T
+ #define _INT32_T
+ #ifndef __int32_t_defined
+ #define __int32_t_defined
+ #ifndef int32_t
+ typedef $acx_cv_type_int32_t int32_t;
+ #endif
+ #endif
+ #endif
+EOF
+elif test "$ac_cv_type_u_int32_t" = yes; then
+ sed 's/^ *//' >> tmp-stdint.h <<EOF
+
+ /* int8_t int16_t int32_t defined by inet code, we do the u_intXX types */
+ #ifndef _INT8_T
+ #define _INT8_T
+ #endif
+ #ifndef _INT16_T
+ #define _INT16_T
+ #endif
+ #ifndef _INT32_T
+ #define _INT32_T
+ #endif
+
+ #ifndef _UINT8_T
+ #define _UINT8_T
+ #ifndef __uint8_t_defined
+ #define __uint8_t_defined
+ #ifndef uint8_t
+ typedef u_int8_t uint8_t;
+ #endif
+ #endif
+ #endif
+
+ #ifndef _UINT16_T
+ #define _UINT16_T
+ #ifndef __uint16_t_defined
+ #define __uint16_t_defined
+ #ifndef uint16_t
+ typedef u_int16_t uint16_t;
+ #endif
+ #endif
+ #endif
+
+ #ifndef _UINT32_T
+ #define _UINT32_T
+ #ifndef __uint32_t_defined
+ #define __uint32_t_defined
+ #ifndef uint32_t
+ typedef u_int32_t uint32_t;
+ #endif
+ #endif
+ #endif
+EOF
+else
+ sed 's/^ *//' >> tmp-stdint.h <<EOF
+
+ /* Some systems have guard macros to prevent redefinitions, define them. */
+ #ifndef _INT8_T
+ #define _INT8_T
+ #endif
+ #ifndef _INT16_T
+ #define _INT16_T
+ #endif
+ #ifndef _INT32_T
+ #define _INT32_T
+ #endif
+ #ifndef _UINT8_T
+ #define _UINT8_T
+ #endif
+ #ifndef _UINT16_T
+ #define _UINT16_T
+ #endif
+ #ifndef _UINT32_T
+ #define _UINT32_T
+ #endif
+EOF
+fi
+
+# ------------- done basic int types, emit int64_t types ------------
+if test "$ac_cv_type_uint64_t" = yes; then
+ sed 's/^ *//' >> tmp-stdint.h <<EOF
+
+ /* system headers have good uint64_t and int64_t */
+ #ifndef _INT64_T
+ #define _INT64_T
+ #endif
+ #ifndef _UINT64_T
+ #define _UINT64_T
+ #endif
+EOF
+elif test "$ac_cv_type_u_int64_t" = yes; then
+ sed 's/^ *//' >> tmp-stdint.h <<EOF
+
+ /* system headers have an u_int64_t (and int64_t) */
+ #ifndef _INT64_T
+ #define _INT64_T
+ #endif
+ #ifndef _UINT64_T
+ #define _UINT64_T
+ #ifndef __uint64_t_defined
+ #define __uint64_t_defined
+ #ifndef uint64_t
+ typedef u_int64_t uint64_t;
+ #endif
+ #endif
+ #endif
+EOF
+elif test -n "$acx_cv_type_int64_t"; then
+ sed 's/^ *//' >> tmp-stdint.h <<EOF
+
+ /* architecture has a 64-bit type, $acx_cv_type_int64_t */
+ #ifndef _INT64_T
+ #define _INT64_T
+ #ifndef int64_t
+ typedef $acx_cv_type_int64_t int64_t;
+ #endif
+ #endif
+ #ifndef _UINT64_T
+ #define _UINT64_T
+ #ifndef __uint64_t_defined
+ #define __uint64_t_defined
+ #ifndef uint64_t
+ typedef unsigned $acx_cv_type_int64_t uint64_t;
+ #endif
+ #endif
+ #endif
+EOF
+else
+ sed 's/^ *//' >> tmp-stdint.h <<EOF
+
+ /* some common heuristics for int64_t, using compiler-specific tests */
+ #if defined __STDC_VERSION__ && (__STDC_VERSION__-0) >= 199901L
+ #ifndef _INT64_T
+ #define _INT64_T
+ #ifndef __int64_t_defined
+ #ifndef int64_t
+ typedef long long int64_t;
+ #endif
+ #endif
+ #endif
+ #ifndef _UINT64_T
+ #define _UINT64_T
+ #ifndef uint64_t
+ typedef unsigned long long uint64_t;
+ #endif
+ #endif
+
+ #elif defined __GNUC__ && defined (__STDC__) && __STDC__-0
+ /* 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
+
+ # ifndef _INT64_T
+ # define _INT64_T
+ # ifndef int64_t
+ __extension__ typedef long long int64_t;
+ # endif
+ # endif
+ # ifndef _UINT64_T
+ # define _UINT64_T
+ # ifndef uint64_t
+ __extension__ typedef unsigned long long uint64_t;
+ # endif
+ # endif
+
+ #elif !defined __STRICT_ANSI__
+ # if defined _MSC_VER || defined __WATCOMC__ || defined __BORLANDC__
+
+ # ifndef _INT64_T
+ # define _INT64_T
+ # ifndef int64_t
+ typedef __int64 int64_t;
+ # endif
+ # endif
+ # ifndef _UINT64_T
+ # define _UINT64_T
+ # ifndef uint64_t
+ typedef unsigned __int64 uint64_t;
+ # endif
+ # endif
+ # endif /* compiler */
+
+ #endif /* ANSI version */
+EOF
+fi
+
+# ------------- done int64_t types, emit intptr types ------------
+if test "$ac_cv_type_uintptr_t" != yes; then
+ sed 's/^ *//' >> tmp-stdint.h <<EOF
+
+ /* Define intptr_t based on sizeof(void*) = $ac_cv_sizeof_void_p */
+ #ifndef __uintptr_t_defined
+ #ifndef uintptr_t
+ typedef u$acx_cv_type_intptr_t uintptr_t;
+ #endif
+ #endif
+ #ifndef __intptr_t_defined
+ #ifndef intptr_t
+ typedef $acx_cv_type_intptr_t intptr_t;
+ #endif
+ #endif
+EOF
+fi
+
+# ------------- done intptr types, emit int_least types ------------
+if test "$ac_cv_type_int_least32_t" != yes; then
+ sed 's/^ *//' >> tmp-stdint.h <<EOF
+
+ /* Define int_least types */
+ typedef int8_t int_least8_t;
+ typedef int16_t int_least16_t;
+ typedef int32_t int_least32_t;
+ #ifdef _INT64_T
+ typedef int64_t int_least64_t;
+ #endif
+
+ typedef uint8_t uint_least8_t;
+ typedef uint16_t uint_least16_t;
+ typedef uint32_t uint_least32_t;
+ #ifdef _UINT64_T
+ typedef uint64_t uint_least64_t;
+ #endif
+EOF
+fi
+
+# ------------- done intptr types, emit int_fast types ------------
+if test "$ac_cv_type_int_fast32_t" != yes; then
+ sed 's/^ *//' >> tmp-stdint.h <<EOF
+
+ /* Define int_fast types. short is often slow */
+ typedef int8_t int_fast8_t;
+ typedef int int_fast16_t;
+ typedef int32_t int_fast32_t;
+ #ifdef _INT64_T
+ typedef int64_t int_fast64_t;
+ #endif
+
+ typedef uint8_t uint_fast8_t;
+ typedef unsigned int uint_fast16_t;
+ typedef uint32_t uint_fast32_t;
+ #ifdef _UINT64_T
+ typedef uint64_t uint_fast64_t;
+ #endif
+EOF
+fi
+
+if test "$ac_cv_type_uintmax_t" != yes; then
+ sed 's/^ *//' >> tmp-stdint.h <<EOF
+
+ /* Define intmax based on what we found */
+ #ifndef intmax_t
+ #ifdef _INT64_T
+ typedef int64_t intmax_t;
+ #else
+ typedef long intmax_t;
+ #endif
+ #endif
+ #ifndef uintmax_t
+ #ifdef _UINT64_T
+ typedef uint64_t uintmax_t;
+ #else
+ typedef unsigned long uintmax_t;
+ #endif
+ #endif
+EOF
+fi
+
+sed 's/^ *//' >> tmp-stdint.h <<EOF
+
+ #endif /* GCC_GENERATED_STDINT_H */
+EOF
+
+if test -r bfd_stdint.h && cmp -s tmp-stdint.h bfd_stdint.h; then
+ rm -f tmp-stdint.h
+else
+ mv -f tmp-stdint.h bfd_stdint.h
+fi
+
+ ;;
+ "default":C)
+case "$srcdir" in
+ .) srcdirpre= ;;
+ *) srcdirpre='$(srcdir)/' ;;
+esac
+POFILES=
+GMOFILES=
+for lang in dummy $OBSOLETE_ALL_LINGUAS; do
+ if test $lang != dummy; then
+ POFILES="$POFILES $srcdirpre$lang.po"
+ GMOFILES="$GMOFILES $srcdirpre$lang.gmo"
+ fi
+done
+sed -e '/SRC-POTFILES =/r po/SRC-POTFILES' \
+ -e '/BLD-POTFILES =/r po/BLD-POTFILES' \
+ -e "s,@POFILES@,$POFILES," \
+ -e "s,@GMOFILES@,$GMOFILES," \
+ po/Makefile.in > po/Makefile ;;
+
+ esac
+done # for ac_tag
+
+
+as_fn_exit 0
+_ACEOF
+ac_clean_files=$ac_clean_files_save
+
+test $ac_write_fail = 0 ||
+ as_fn_error "write failure creating $CONFIG_STATUS" "$LINENO" 5
+
+
+# configure is writing to config.log, and then calls config.status.
+# config.status does its own redirection, appending to config.log.
+# Unfortunately, on DOS this fails, as config.log is still kept open
+# by configure, so config.status won't be able to write to it; its
+# output is simply discarded. So we exec the FD to /dev/null,
+# effectively closing config.log, so it can be properly (re)opened and
+# appended to by config.status. When coming back to configure, we
+# need to make the FD available again.
+if test "$no_create" != yes; then
+ ac_cs_success=:
+ ac_config_status_args=
+ test "$silent" = yes &&
+ ac_config_status_args="$ac_config_status_args --quiet"
+ exec 5>/dev/null
+ $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
+ exec 5>>config.log
+ # Use ||, not &&, to avoid exiting from the if with $? = 1, which
+ # would make configure fail if this is the last instruction.
+ $ac_cs_success || as_fn_exit $?
+fi
+if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5
+$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;}
+fi
+
diff --git a/bfd/configure.ac b/bfd/configure.ac
new file mode 100644
index 0000000..ba98e39
--- /dev/null
+++ b/bfd/configure.ac
@@ -0,0 +1,1199 @@
+dnl Process this file with autoconf to produce a configure script.
+dnl
+dnl Copyright (C) 2012-2014 Free Software Foundation, Inc.
+dnl
+dnl This file is free software; you can redistribute it and/or modify
+dnl it under the terms of the GNU General Public License as published by
+dnl the Free Software Foundation; either version 3 of the License, or
+dnl (at your option) any later version.
+dnl
+dnl This program is distributed in the hope that it will be useful,
+dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
+dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+dnl GNU General Public License for more details.
+dnl
+dnl You should have received a copy of the GNU General Public License
+dnl along with this program; see the file COPYING3. If not see
+dnl <http://www.gnu.org/licenses/>.
+dnl
+
+AC_PREREQ(2.59)
+m4_include([version.m4])
+AC_INIT([bfd], BFD_VERSION)
+AC_CONFIG_SRCDIR([libbfd.c])
+
+AC_CANONICAL_TARGET
+AC_ISC_POSIX
+
+AM_INIT_AUTOMAKE
+
+dnl These must be called before LT_INIT, 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.
+AC_DISABLE_SHARED
+
+AC_PROG_CC
+AC_GNU_SOURCE
+AC_USE_SYSTEM_EXTENSIONS
+
+LT_INIT([dlopen])
+
+# AC_PLUGINS setting $plugins is called by ACX_LARGEFILE.
+ACX_LARGEFILE
+
+AM_CONDITIONAL(PLUGINS, test "$plugins" = "yes")
+
+if test "$plugins" = "yes"; then
+ enable_targets="$enable_targets plugin"
+fi
+
+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_MSG_ERROR([enable-targets option must specify target names or 'all'])
+ ;;
+ no) enable_targets= ;;
+ *) enable_targets=$enableval ;;
+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
+
+AC_ARG_ENABLE(secureplt,
+[ --enable-secureplt Default to creating read-only plt entries],
+[case "${enableval}" in
+ yes) use_secureplt=true ;;
+ no) use_secureplt=false ;;
+ *) AC_MSG_ERROR(bad value ${enableval} for secureplt option) ;;
+esac],[use_secureplt=true])dnl
+if test $use_secureplt = true; then
+ AC_DEFINE(USE_SECUREPLT, 1,
+ [Define if we should default to creating read-only plt entries])
+fi
+
+AC_ARG_ENABLE(leading-mingw64-underscores,
+ AS_HELP_STRING([--enable-leading-mingw64-underscores],
+ [Enable leading underscores on 64 bit mingw targets]),
+ [],[])
+AS_IF([ test x"$enable_leading_mingw64_underscores" = xyes ],
+ [AC_DEFINE(USE_MINGW64_LEADING_UNDERSCORES, 1,
+ [Define if we should use leading underscore on 64 bit mingw targets])])
+
+DEBUGDIR=${libdir}/debug
+AC_ARG_WITH(separate-debug-dir,
+ AS_HELP_STRING([--with-separate-debug-dir=DIR],
+ [Look for global separate debug info in DIR [[default=LIBDIR/debug]]]),
+[DEBUGDIR="${withval}"])
+AC_SUBST(DEBUGDIR)
+
+# Check to see if we should allow the generation of
+# symbols with the ELF standard's STT_COMMON type.
+AC_ARG_ENABLE(elf-stt-common,
+[ --enable-elf-stt-common Allow the generation of ELF symbols with the STT_COMMON type],
+[case "${enableval}" in
+ yes) want_elf_stt_common=true ;;
+ no) want_elf_stt_common=false ;;
+ *) AC_MSG_ERROR(bad value ${enableval} for ELF STT_COMMON option) ;;
+ esac],
+# We have to choose a default behaviour. For native builds we could
+# test whether the loader supports the STT_COMMON type, but that would
+# mean that built binaries could not be exported to older systems where
+# the loader does not support it. So by default we always choose to
+# disable this feature.
+ want_elf_stt_common=false)dnl
+if test $want_elf_stt_common = true; then
+ AC_DEFINE(USE_STT_COMMON, 1,
+ [Define if we may generate symbols with ELF's STT_COMMON type])
+fi
+
+ACX_PKGVERSION([GNU Binutils])
+ACX_BUGURL([http://www.sourceware.org/bugzilla/])
+
+AM_BINUTILS_WARNINGS
+
+AC_CONFIG_HEADERS(config.h:config.in)
+
+# PR 14072
+AH_VERBATIM([00_CONFIG_H_CHECK],
+[/* Check that config.h is #included before system headers
+ (this works only for glibc, but that should be enough). */
+#if defined(__GLIBC__) && !defined(__FreeBSD_kernel__) && !defined(__CONFIG_H__)
+# error config.h must be #included before system headers
+#endif
+#define __CONFIG_H__ 1])
+
+if test -z "$target" ; then
+ AC_MSG_ERROR(Unrecognized target system type; please check config.sub.)
+fi
+
+AM_MAINTAINER_MODE
+AM_CONDITIONAL(GENINSRC_NEVER, false)
+AM_INSTALL_LIBBFD
+AC_EXEEXT
+
+host64=false
+target64=false
+bfd_default_target_size=32
+
+# host stuff:
+
+ALL_LINGUAS="fr tr ja es sv da zh_CN ro rw vi fi id ru uk"
+ZW_GNU_GETTEXT_SISTER_DIR
+AM_PO_SUBDIRS
+
+# Permit host specific settings.
+. ${srcdir}/configure.host
+
+AC_SUBST(HDEFINES)
+AC_PROG_INSTALL
+
+BFD_HOST_64BIT_LONG=0
+BFD_HOST_64BIT_LONG_LONG=0
+BFD_HOST_64_BIT_DEFINED=0
+BFD_HOST_64_BIT=
+BFD_HOST_U_64_BIT=
+BFD_HOSTPTR_T="unsigned long"
+
+AC_CHECK_SIZEOF(long long)
+AC_CHECK_SIZEOF(void *)
+AC_CHECK_SIZEOF(long)
+
+if test "x${ac_cv_sizeof_void_p}" = "x8"; then
+ host64=true
+fi
+
+if test "x${ac_cv_sizeof_long}" = "x8"; then
+ BFD_HOST_64BIT_LONG=1
+ test -n "${HOST_64BIT_TYPE}" || HOST_64BIT_TYPE="long"
+ test -n "${HOST_U_64BIT_TYPE}" || HOST_U_64BIT_TYPE="unsigned long"
+elif test "x${ac_cv_sizeof_long_long}" = "x8"; then
+ BFD_HOST_64BIT_LONG_LONG=1
+ test -n "${HOST_64BIT_TYPE}" || HOST_64BIT_TYPE="long long"
+ test -n "${HOST_U_64BIT_TYPE}" || HOST_U_64BIT_TYPE="unsigned long long"
+ if test "x${ac_cv_sizeof_void_p}" = "x8"; then
+ BFD_HOSTPTR_T="unsigned long long"
+ fi
+fi
+
+if test -n "${HOST_64BIT_TYPE}" -a -n "${HOST_U_64BIT_TYPE}"; 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_64BIT_LONG_LONG)
+AC_SUBST(BFD_HOST_64_BIT_DEFINED)
+AC_SUBST(BFD_HOST_64_BIT)
+AC_SUBST(BFD_HOST_U_64_BIT)
+AC_SUBST(BFD_HOSTPTR_T)
+
+BFD_CC_FOR_BUILD
+
+AC_CHECK_HEADERS(alloca.h stddef.h string.h strings.h stdlib.h time.h unistd.h wchar.h)
+AC_CHECK_HEADERS(fcntl.h sys/file.h sys/time.h sys/stat.h sys/resource.h)
+GCC_HEADER_STDINT(bfd_stdint.h)
+AC_HEADER_TIME
+AC_HEADER_DIRENT
+
+ACX_HEADER_STRING
+AC_CHECK_FUNCS(fcntl getpagesize setitimer sysconf fdopen getuid getgid fileno)
+AC_CHECK_FUNCS(strtoull getrlimit)
+
+AC_CHECK_DECLS(basename)
+AC_CHECK_DECLS(ftello)
+AC_CHECK_DECLS(ftello64)
+AC_CHECK_DECLS(fseeko)
+AC_CHECK_DECLS(fseeko64)
+
+BFD_BINARY_FOPEN
+
+AC_CHECK_DECLS(ffs)
+AC_CHECK_DECLS(free)
+AC_CHECK_DECLS(getenv)
+AC_CHECK_DECLS(malloc)
+AC_CHECK_DECLS(realloc)
+AC_CHECK_DECLS(stpcpy)
+AC_CHECK_DECLS(strstr)
+AC_CHECK_DECLS(snprintf)
+AC_CHECK_DECLS(vsnprintf)
+AC_CHECK_DECLS(strnlen)
+
+# Link in zlib if we can. This allows us to read compressed debug sections.
+# This is used only by compress.c.
+AM_ZLIB
+
+# If we are configured native, pick a core file support file.
+COREFILE=
+COREFLAG=
+CORE_HEADER=
+TRAD_HEADER=
+if test "${target}" = "${host}"; then
+ case "${host}" in
+ alpha*-*-freebsd* | alpha*-*-kfreebsd*-gnu | alpha*-*-*vms*)
+ COREFILE=''
+ ;;
+ alpha*-*-linux-*)
+ COREFILE=trad-core.lo
+ TRAD_HEADER='"hosts/alphalinux.h"'
+ ;;
+ alpha*-*-netbsd* | alpha*-*-openbsd*)
+ COREFILE=netbsd-core.lo
+ ;;
+ alpha*-*-*)
+ COREFILE=osf-core.lo
+ ;;
+ arm-*-freebsd* | arm-*-kfreebsd*-gnu)
+ COREFILE='' ;;
+ arm-*-netbsd* | arm-*-openbsd*)
+ COREFILE=netbsd-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" ;;
+ hppa*-*-netbsd* | hppa*-*-openbsd*)
+ COREFILE=netbsd-core.lo
+ ;;
+
+ i370-*-*)
+ COREFILE=trad-core.lo
+ TRAD_HEADER='"hosts/i370linux.h"'
+ ;;
+
+changequote(,)dnl
+ i[3-7]86-sequent-bsd*)
+changequote([,])dnl
+ COREFILE=trad-core.lo
+ TRAD_HEADER='"hosts/symmetry.h"'
+ ;;
+changequote(,)dnl
+ i[3-7]86-sequent-sysv4*) ;;
+ i[3-7]86-sequent-sysv*)
+changequote([,])dnl
+ COREFILE=trad-core.lo
+ TRAD_HEADER='"hosts/symmetry.h"'
+ ;;
+changequote(,)dnl
+ i[3-7]86-*-bsdi)
+changequote([,])dnl
+ COREFILE=
+ ;;
+changequote(,)dnl
+ i[3-7]86-*-bsd* | i[3-7]86-*-freebsd[123] | i[3-7]86-*-freebsd[123]\.* | i[3-7]86-*-freebsd4\.[01234] | i[3-7]86-*-freebsd4\.[01234]\.* | i[3-7]86-*-freebsd*aout*)
+changequote([,])dnl
+ COREFILE=trad-core.lo
+ TRAD_HEADER='"hosts/i386bsd.h"'
+ ;;
+changequote(,)dnl
+ i[3-7]86-*-freebsd* | i[3-7]86-*-kfreebsd*-gnu | i[3-7]86-*-dragonfly*)
+changequote([,])dnl
+ COREFILE=''
+ TRAD_HEADER='"hosts/i386bsd.h"'
+ ;;
+changequote(,)dnl
+ i[3-7]86-*-netbsd* | i[3-7]86-*-knetbsd*-gnu | i[3-7]86-*-openbsd*)
+changequote([,])dnl
+ COREFILE=netbsd-core.lo
+ ;;
+changequote(,)dnl
+ i[3-7]86-esix-sysv3*)
+changequote([,])dnl
+ COREFILE=trad-core.lo
+ TRAD_HEADER='"hosts/esix.h"'
+ ;;
+changequote(,)dnl
+ i[3-7]86-*-sco3.2v5*)
+changequote([,])dnl
+ COREFILE=sco5-core.lo
+ ;;
+changequote(,)dnl
+ i[3-7]86-*-sco* | i[3-7]86-*-isc*)
+changequote([,])dnl
+ COREFILE=trad-core.lo
+ TRAD_HEADER='"hosts/i386sco.h"'
+ ;;
+changequote(,)dnl
+ i[3-7]86-*-mach3*)
+changequote([,])dnl
+ COREFILE=trad-core.lo
+ TRAD_HEADER='"hosts/i386mach3.h"'
+ ;;
+changequote(,)dnl
+ i[3-7]86-*-linux-*)
+changequote([,])dnl
+ COREFILE=trad-core.lo
+ TRAD_HEADER='"hosts/i386linux.h"'
+ case "$enable_targets"-"$want64" in
+ *x86_64-*linux*|*-true)
+ CORE_HEADER='"hosts/x86-64linux.h"'
+ esac
+ ;;
+changequote(,)dnl
+ i[3-7]86-*-isc*) COREFILE=trad-core.lo ;;
+ i[3-7]86-*-aix*) COREFILE=aix386-core.lo ;;
+changequote([,])dnl
+ i860-*-mach3* | i860-*-osf1*)
+ COREFILE=trad-core.lo
+ TRAD_HEADER='"hosts/i860mach3.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-*-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-*)
+ 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"'
+ ;;
+ m88*-*-openbsd*)
+ COREFILE=netbsd-core.lo
+ ;;
+ 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
+ ;;
+changequote(,)dnl
+ rs6000-*-aix[5-9].* | powerpc-*-aix[5-9].*)
+changequote([,])dnl
+ COREFILE=rs6000-core.lo
+ COREFLAG="$COREFLAG -DAIX_5_CORE -DAIX_CORE_DUMPX_CORE"
+ ;;
+changequote(,)dnl
+ rs6000-*-aix4.[3-9]* | powerpc-*-aix4.[3-9]*)
+changequote([,])dnl
+ COREFILE=rs6000-core.lo
+ COREFLAG="$COREFLAG -DAIX_CORE_DUMPX_CORE"
+ # Not all versions of AIX with -DAIX_CORE_DUMPX_CORE
+ # have c_impl as a member of struct core_dumpx
+ AC_MSG_CHECKING([for c_impl in struct core_dumpx])
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <core.h>]], [[struct core_dumpx c; c.c_impl = 0;]])],[AC_DEFINE(HAVE_ST_C_IMPL, 1,
+ [Define if struct core_dumpx has member c_impl])
+ AC_MSG_RESULT(yes)],[AC_MSG_RESULT(no)])
+ ;;
+ rs6000-*-aix4*) COREFILE=rs6000-core.lo ;;
+ rs6000-*-*) COREFILE=rs6000-core.lo ;;
+ powerpc-*-aix4*) COREFILE=rs6000-core.lo ;;
+ powerpc-*-aix*) COREFILE=rs6000-core.lo ;;
+ powerpc-*-beos*) ;;
+ powerpc-*-freebsd* | powerpc-*-kfreebsd*-gnu)
+ COREFILE='' ;;
+ powerpc-*-netbsd*) COREFILE=netbsd-core.lo ;;
+ powerpc-*-*bsd*) COREFILE=netbsd-core.lo ;;
+ s390*-*-*) COREFILE=trad-core.lo ;;
+ sh*-*-netbsd* | sh*-*-openbsd*)
+ COREFILE=netbsd-core.lo
+ ;;
+ sparc-*-netbsd* | sparc*-*-openbsd*)
+ COREFILE=netbsd-core.lo
+ ;;
+ tahoe-*-*)
+ COREFILE=trad-core.lo
+ TRAD_HEADER='"hosts/tahoe.h"'
+ ;;
+ vax-*-netbsd* | vax-*-openbsd*)
+ COREFILE=netbsd-core.lo
+ ;;
+ vax-*-ultrix2*)
+ COREFILE=trad-core.lo
+ TRAD_HEADER='"hosts/vaxult2.h"'
+ ;;
+ vax-*-ultrix*)
+ COREFILE=trad-core.lo
+ TRAD_HEADER='"hosts/vaxult2.h"'
+ ;;
+ vax-*-linux-*)
+ COREFILE=trad-core.lo
+ TRAD_HEADER='"hosts/vaxlinux.h"'
+ ;;
+ vax-*-*)
+ COREFILE=trad-core.lo
+ TRAD_HEADER='"hosts/vaxbsd.h"'
+ ;;
+ x86_64-*-linux*)
+ CORE_HEADER='"hosts/x86-64linux.h"'
+ ;;
+ x86_64-*-netbsd* | x86_64-*-openbsd*)
+ COREFILE=netbsd-core.lo
+ ;;
+ 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(prstatus32_t)
+ BFD_HAVE_SYS_PROCFS_TYPE_MEMBER(prstatus_t, pr_who)
+ BFD_HAVE_SYS_PROCFS_TYPE_MEMBER(prstatus32_t, pr_who)
+ BFD_HAVE_SYS_PROCFS_TYPE(pstatus_t)
+ BFD_HAVE_SYS_PROCFS_TYPE(pxstatus_t)
+ BFD_HAVE_SYS_PROCFS_TYPE(pstatus32_t)
+ BFD_HAVE_SYS_PROCFS_TYPE(prpsinfo_t)
+ BFD_HAVE_SYS_PROCFS_TYPE_MEMBER(prpsinfo_t, pr_pid)
+ BFD_HAVE_SYS_PROCFS_TYPE(prpsinfo32_t)
+ BFD_HAVE_SYS_PROCFS_TYPE_MEMBER(prpsinfo32_t, pr_pid)
+ BFD_HAVE_SYS_PROCFS_TYPE(psinfo_t)
+ BFD_HAVE_SYS_PROCFS_TYPE_MEMBER(psinfo_t, pr_pid)
+ BFD_HAVE_SYS_PROCFS_TYPE(psinfo32_t)
+ BFD_HAVE_SYS_PROCFS_TYPE_MEMBER(psinfo32_t, pr_pid)
+ BFD_HAVE_SYS_PROCFS_TYPE(lwpstatus_t)
+ BFD_HAVE_SYS_PROCFS_TYPE(lwpxstatus_t)
+ BFD_HAVE_SYS_PROCFS_TYPE_MEMBER(lwpstatus_t, pr_context)
+ BFD_HAVE_SYS_PROCFS_TYPE_MEMBER(lwpstatus_t, pr_reg)
+ BFD_HAVE_SYS_PROCFS_TYPE_MEMBER(lwpstatus_t, pr_fpreg)
+ BFD_HAVE_SYS_PROCFS_TYPE(win32_pstatus_t)
+ fi
+fi
+AC_SUBST(COREFILE)
+AC_SUBST(COREFLAG)
+if test -n "$CORE_HEADER"; then
+ AC_DEFINE_UNQUOTED(CORE_HEADER, $CORE_HEADER,
+ [Name of host specific core header file to include in elf.c.])
+fi
+if test -n "$TRAD_HEADER"; then
+ AC_DEFINE_UNQUOTED(TRAD_HEADER, $TRAD_HEADER,
+ [Name of host specific header file to include in trad-core.c.])
+fi
+
+# Check if linker supports --as-needed and --no-as-needed options
+AC_CACHE_CHECK(linker --as-needed support, bfd_cv_ld_as_needed,
+ [bfd_cv_ld_as_needed=no
+ if $LD --help 2>/dev/null | grep as-needed > /dev/null; then
+ bfd_cv_ld_as_needed=yes
+ fi
+ ])
+
+LT_LIB_M
+
+# When building a shared libbfd, link against the pic version of libiberty
+# so that apps that use libbfd won't need libiberty just to satisfy any
+# libbfd references.
+# We can't do that if a pic libiberty is unavailable since including non-pic
+# code would insert text relocations into libbfd.
+SHARED_LIBADD=
+SHARED_LDFLAGS=
+if test "$enable_shared" = "yes"; then
+changequote(,)dnl
+ x=`sed -n -e 's/^[ ]*PICFLAG[ ]*=[ ]*//p' < ../libiberty/Makefile | sed -n '$p'`
+changequote([,])dnl
+ if test -n "$x"; then
+ SHARED_LIBADD="-L`pwd`/../libiberty/pic -liberty"
+ fi
+
+# More hacks to build DLLs on Windows.
+ case "${host}" in
+ *-*-cygwin*)
+ SHARED_LDFLAGS="-no-undefined"
+ SHARED_LIBADD="-L`pwd`/../libiberty -liberty -L`pwd`/../intl -lintl -lcygwin -lkernel32"
+ ;;
+
+ # Hack to build or1k-src on OSX
+ or1k*-*-darwin*)
+ SHARED_LIBADD="-L`pwd`/../libiberty/pic -L`pwd`/../intl -liberty -lintl"
+ ;;
+ esac
+
+ if test -n "$SHARED_LIBADD"; then
+ if test -n "$LIBM"; then
+ if test x"$bfd_cv_ld_as_needed" = xyes; then
+ # Link against libm only when needed. Put -lc, -lm inside -Wl
+ # to stop libtool reordering these options.
+ SHARED_LIBADD="$SHARED_LIBADD -Wl,-lc,--as-needed,`echo $LIBM | sed 's/ /,/g'`,--no-as-needed"
+ else
+ SHARED_LIBADD="$SHARED_LIBADD $LIBM"
+ fi
+ fi
+ fi
+fi
+AC_SUBST(SHARED_LDFLAGS)
+AC_SUBST(SHARED_LIBADD)
+
+# target stuff:
+
+# Canonicalize the secondary target names.
+if test -n "$enable_targets" ; then
+ for targ in `echo $enable_targets | sed 's/,/ /g'`
+ do
+ result=`$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=
+assocvecs=
+selarchs=
+TDEFINES=
+for targ in $target $canon_targets
+do
+ if test "x$targ" = "xall"; then
+ all_targets=true
+ assocvecs="$assocvecs $targ_defvec $targ_selvecs"
+ 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 "--enable-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 associated vectors in all the configured targets.
+f=""
+for i in $assocvecs ; do
+ case " $f " in
+ *" $i "*) ;;
+ *) f="$f $i" ;;
+ esac
+done
+assocvecs="$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 elf-attrs.lo elf-strtab.lo
+ elf-eh-frame.lo dwarf1.lo"
+
+for vec in $selvecs
+do
+ target_size=32
+ case "$vec" in
+ # This list is alphabetized to make it easy to compare
+ # with the two vector lists in targets.c. For the same reason,
+ # use one entry per line, even though this leads to long lines.
+ aarch64_elf32_be_vec) tb="$tb elf32-aarch64.lo elfxx-aarch64.lo elf-ifunc.lo elf32.lo $elf"; target_size=64 ;;
+ aarch64_elf32_le_vec) tb="$tb elf32-aarch64.lo elfxx-aarch64.lo elf-ifunc.lo elf32.lo $elf"; target_size=64 ;;
+ aarch64_elf64_be_vec) tb="$tb elf64-aarch64.lo elfxx-aarch64.lo elf-ifunc.lo elf64.lo $elf"; target_size=64 ;;
+ aarch64_elf64_le_vec) tb="$tb elf64-aarch64.lo elfxx-aarch64.lo elf-ifunc.lo elf64.lo $elf"; target_size=64 ;;
+ alpha_ecoff_le_vec) tb="$tb coff-alpha.lo ecoff.lo ecofflink.lo"; target_size=64 ;;
+ alpha_elf64_vec) tb="$tb elf64-alpha.lo elf64.lo $elf"; target_size=64 ;;
+ alpha_elf64_fbsd_vec) tb="$tb elf64-alpha.lo elf64.lo $elf"; target_size=64 ;;
+ alpha_nlm32_vec) tb="$tb nlm32-alpha.lo nlm32.lo nlm.lo"; target_size=64 ;;
+ alpha_vms_vec) tb="$tb vms-alpha.lo vms-misc.lo vms-lib.lo"; target_size=64 ;;
+ alpha_vms_lib_txt_vec) tb="$tb vms-lib.lo vms-misc.lo" ;;
+ am33_elf32_linux_vec) tb="$tb elf32-am33lin.lo elf32.lo $elf" ;;
+ aout0_be_vec) tb="$tb aout0.lo aout32.lo" ;;
+ aout64_vec) tb="$tb demo64.lo aout64.lo"; target_size=64 ;;
+ aout_vec) tb="$tb host-aout.lo aout32.lo" ;;
+ aout_adobe_vec) tb="$tb aout-adobe.lo aout32.lo" ;;
+ arc_elf32_be_vec) tb="$tb elf32-arc.lo elf32.lo $elf" ;;
+ arc_elf32_le_vec) tb="$tb elf32-arc.lo elf32.lo $elf" ;;
+ arm_aout_be_vec) tb="$tb aout-arm.lo aout32.lo" ;;
+ arm_aout_le_vec) tb="$tb aout-arm.lo aout32.lo" ;;
+ arm_aout_nbsd_vec) tb="$tb armnetbsd.lo aout32.lo" ;;
+ arm_aout_riscix_vec) tb="$tb aout32.lo riscix.lo" ;;
+ arm_coff_be_vec) tb="$tb coff-arm.lo cofflink.lo " ;;
+ arm_coff_le_vec) tb="$tb coff-arm.lo cofflink.lo " ;;
+ arm_elf32_be_vec) tb="$tb elf32-arm.lo elf32.lo elf-nacl.lo elf-vxworks.lo $elf" ;;
+ arm_elf32_le_vec) tb="$tb elf32-arm.lo elf32.lo elf-nacl.lo elf-vxworks.lo $elf" ;;
+ arm_elf32_nacl_be_vec) tb="$tb elf32-arm.lo elf32.lo elf-nacl.lo elf-vxworks.lo $elf" ;;
+ arm_elf32_nacl_le_vec) tb="$tb elf32-arm.lo elf32.lo elf-nacl.lo elf-vxworks.lo $elf" ;;
+ arm_elf32_symbian_be_vec) tb="$tb elf32-arm.lo elf32.lo elf-nacl.lo elf-vxworks.lo $elf" ;;
+ arm_elf32_symbian_le_vec) tb="$tb elf32-arm.lo elf32.lo elf-nacl.lo elf-vxworks.lo $elf" ;;
+ arm_elf32_vxworks_be_vec) tb="$tb elf32-arm.lo elf32.lo elf-nacl.lo elf-vxworks.lo $elf" ;;
+ arm_elf32_vxworks_le_vec) tb="$tb elf32-arm.lo elf32.lo elf-nacl.lo elf-vxworks.lo $elf" ;;
+ arm_pe_be_vec) tb="$tb pe-arm.lo peigen.lo cofflink.lo " ;;
+ arm_pe_le_vec) tb="$tb pe-arm.lo peigen.lo cofflink.lo " ;;
+ arm_pe_epoc_be_vec) tb="$tb epoc-pe-arm.lo peigen.lo cofflink.lo " ;;
+ arm_pe_epoc_le_vec) tb="$tb epoc-pe-arm.lo peigen.lo cofflink.lo " ;;
+ arm_pe_wince_be_vec) tb="$tb pe-arm-wince.lo pe-arm.lo peigen.lo cofflink.lo " ;;
+ arm_pe_wince_le_vec) tb="$tb pe-arm-wince.lo pe-arm.lo peigen.lo cofflink.lo " ;;
+ arm_pei_be_vec) tb="$tb pei-arm.lo peigen.lo cofflink.lo " ;;
+ arm_pei_le_vec) tb="$tb pei-arm.lo peigen.lo cofflink.lo " ;;
+ arm_pei_epoc_be_vec) tb="$tb epoc-pei-arm.lo peigen.lo cofflink.lo " ;;
+ arm_pei_epoc_le_vec) tb="$tb epoc-pei-arm.lo peigen.lo cofflink.lo " ;;
+ arm_pei_wince_be_vec) tb="$tb pei-arm-wince.lo pei-arm.lo peigen.lo cofflink.lo " ;;
+ arm_pei_wince_le_vec) tb="$tb pei-arm-wince.lo pei-arm.lo peigen.lo cofflink.lo " ;;
+ avr_elf32_vec) tb="$tb elf32-avr.lo elf32.lo $elf" ;;
+ bfin_elf32_vec) tb="$tb elf32-bfin.lo elf32.lo $elf" ;;
+ bfin_elf32_fdpic_vec) tb="$tb elf32-bfin.lo elf32.lo $elf" ;;
+ bout_be_vec) tb="$tb bout.lo aout32.lo" ;;
+ bout_le_vec) tb="$tb bout.lo aout32.lo" ;;
+ cr16_elf32_vec) tb="$tb elf32-cr16.lo elf32.lo $elf" ;;
+ cr16c_elf32_vec) tb="$tb elf32-cr16c.lo elf32.lo $elf" ;;
+ cris_aout_vec) tb="$tb aout-cris.lo" ;;
+ cris_elf32_vec) tb="$tb elf32-cris.lo elf32.lo $elf" ;;
+ cris_elf32_us_vec) tb="$tb elf32-cris.lo elf32.lo $elf" ;;
+ crx_elf32_vec) tb="$tb elf32-crx.lo elf32.lo $elf" ;;
+ d10v_elf32_vec) tb="$tb elf32-d10v.lo elf32.lo $elf" ;;
+ d30v_elf32_vec) tb="$tb elf32-d30v.lo elf32.lo $elf" ;;
+ dlx_elf32_be_vec) tb="$tb elf32-dlx.lo elf32.lo $elf" ;;
+ elf32_be_vec) tb="$tb elf32-gen.lo elf32.lo $elf" ;;
+ elf32_le_vec) tb="$tb elf32-gen.lo elf32.lo $elf" ;;
+ elf64_be_vec) tb="$tb elf64-gen.lo elf64.lo $elf"; target_size=64 ;;
+ elf64_le_vec) tb="$tb elf64-gen.lo elf64.lo $elf"; target_size=64 ;;
+ epiphany_elf32_vec) tb="$tb elf32-epiphany.lo elf32.lo $elf" ;;
+ fr30_elf32_vec) tb="$tb elf32-fr30.lo elf32.lo $elf" ;;
+ frv_elf32_vec) tb="$tb elf32-frv.lo elf32.lo $elf" ;;
+ frv_elf32_fdpic_vec) tb="$tb elf32-frv.lo elf32.lo $elf" ;;
+ h8300_coff_vec) tb="$tb coff-h8300.lo reloc16.lo" ;;
+ h8300_elf32_vec) tb="$tb elf32-h8300.lo elf32.lo $elf" ;;
+ h8500_coff_vec) tb="$tb coff-h8500.lo reloc16.lo" ;;
+ hppa_elf32_vec) tb="$tb elf32-hppa.lo elf32.lo $elf" ;;
+ hppa_elf32_linux_vec) tb="$tb elf32-hppa.lo elf32.lo $elf" ;;
+ hppa_elf32_nbsd_vec) tb="$tb elf32-hppa.lo elf32.lo $elf" ;;
+ hppa_elf64_vec) tb="$tb elf64-hppa.lo elf64.lo $elf"; target_size=64 ;;
+ hppa_elf64_linux_vec) tb="$tb elf64-hppa.lo elf64.lo $elf"; target_size=64 ;;
+ hppa_som_vec) tb="$tb som.lo" ;;
+ i370_elf32_vec) tb="$tb elf32-i370.lo elf32.lo $elf" ;;
+ i386_aout_vec) tb="$tb i386aout.lo aout32.lo" ;;
+ i386_aout_bsd_vec) tb="$tb i386bsd.lo aout32.lo" ;;
+ i386_aout_dynix_vec) tb="$tb i386dynix.lo aout32.lo" ;;
+ i386_aout_fbsd_vec) tb="$tb i386freebsd.lo aout32.lo" ;;
+ i386_aout_linux_vec) tb="$tb i386linux.lo aout32.lo" ;;
+ i386_aout_lynx_vec) tb="$tb i386lynx.lo lynx-core.lo aout32.lo" ;;
+ i386_aout_mach3_vec) tb="$tb i386mach3.lo aout32.lo" ;;
+ i386_aout_nbsd_vec) tb="$tb i386netbsd.lo aout32.lo" ;;
+ i386_aout_os9k_vec) tb="$tb i386os9k.lo aout32.lo" ;;
+ i386_coff_vec) tb="$tb coff-i386.lo cofflink.lo" ;;
+ i386_coff_go32_vec) tb="$tb coff-go32.lo cofflink.lo" ;;
+ i386_coff_go32stubbed_vec) tb="$tb coff-stgo32.lo cofflink.lo" ;;
+ i386_coff_lynx_vec) tb="$tb cf-i386lynx.lo cofflink.lo lynx-core.lo" ;;
+ i386_elf32_vec) tb="$tb elf32-i386.lo elf-ifunc.lo elf-nacl.lo elf-vxworks.lo elf32.lo $elf" ;;
+ i386_elf32_fbsd_vec) tb="$tb elf32-i386.lo elf-ifunc.lo elf-nacl.lo elf-vxworks.lo elf32.lo $elf" ;;
+ i386_elf32_nacl_vec) tb="$tb elf32-i386.lo elf-ifunc.lo elf-nacl.lo elf-vxworks.lo elf32.lo $elf" ;;
+ i386_elf32_sol2_vec) tb="$tb elf32-i386.lo elf-ifunc.lo elf-nacl.lo elf-vxworks.lo elf32.lo $elf" ;;
+ i386_elf32_vxworks_vec) tb="$tb elf32-i386.lo elf-ifunc.lo elf-nacl.lo elf-vxworks.lo elf32.lo $elf" ;;
+ i386_mach_o_vec) tb="$tb mach-o-i386.lo" ;;
+ i386_msdos_vec) tb="$tb i386msdos.lo" ;;
+ i386_nlm32_vec) tb="$tb nlm32-i386.lo nlm32.lo nlm.lo" ;;
+ i386_pe_vec) tb="$tb pe-i386.lo peigen.lo cofflink.lo" ;;
+ i386_pei_vec) tb="$tb pei-i386.lo peigen.lo cofflink.lo" ;;
+ i860_coff_vec) tb="$tb coff-i860.lo cofflink.lo" ;;
+ i860_elf32_vec) tb="$tb elf32-i860.lo elf32.lo $elf" ;;
+ i860_elf32_le_vec) tb="$tb elf32-i860.lo elf32.lo $elf" ;;
+ i960_elf32_vec) tb="$tb elf32-i960.lo elf32.lo $elf" ;;
+ ia64_elf32_be_vec) tb="$tb elf32-ia64.lo elfxx-ia64.lo elf32.lo $elf" ;;
+ ia64_elf32_hpux_be_vec) tb="$tb elf32-ia64.lo elfxx-ia64.lo elf32.lo $elf" ;;
+ ia64_elf64_be_vec) tb="$tb elf64-ia64.lo elfxx-ia64.lo elf64.lo $elf"; target_size=64 ;;
+ ia64_elf64_le_vec) tb="$tb elf64-ia64.lo elfxx-ia64.lo elf64.lo $elf"; target_size=64 ;;
+ ia64_elf64_hpux_be_vec) tb="$tb elf64-ia64.lo elfxx-ia64.lo elf64.lo $elf"; target_size=64 ;;
+ ia64_elf64_vms_vec) tb="$tb elf64-ia64-vms.lo elf64-ia64.lo elfxx-ia64.lo elf64.lo vms-lib.lo vms-misc.lo $elf"; target_size=64 ;;
+ ia64_pei_vec) tb="$tb pei-ia64.lo pepigen.lo cofflink.lo"; target_size=64 ;;
+ icoff_be_vec) tb="$tb coff-i960.lo cofflink.lo" ;;
+ icoff_le_vec) tb="$tb coff-i960.lo cofflink.lo" ;;
+ ieee_vec) tb="$tb ieee.lo" ;;
+ ip2k_elf32_vec) tb="$tb elf32-ip2k.lo elf32.lo $elf" ;;
+ iq2000_elf32_vec) tb="$tb elf32-iq2000.lo elf32.lo $elf" ;;
+ k1om_elf64_vec) tb="$tb elf64-x86-64.lo elf-ifunc.lo elf-nacl.lo elf64.lo $elf"; target_size=64 ;;
+ k1om_elf64_fbsd_vec) tb="$tb elf64-x86-64.lo elf-ifunc.lo elf-nacl.lo elf64.lo $elf"; target_size=64 ;;
+ l1om_elf64_vec) tb="$tb elf64-x86-64.lo elf-ifunc.lo elf-nacl.lo elf64.lo $elf"; target_size=64 ;;
+ l1om_elf64_fbsd_vec) tb="$tb elf64-x86-64.lo elf-ifunc.lo elf-nacl.lo elf64.lo $elf"; target_size=64 ;;
+ lm32_elf32_vec) tb="$tb elf32-lm32.lo elf32.lo $elf" ;;
+ lm32_elf32_fdpic_vec) tb="$tb elf32-lm32.lo elf32.lo $elf" ;;
+ m32c_elf32_vec) tb="$tb elf32-m32c.lo elf32.lo $elf" ;;
+ m32r_elf32_vec) tb="$tb elf32-m32r.lo elf32.lo $elf" ;;
+ m32r_elf32_le_vec) tb="$tb elf32-m32r.lo elf32.lo $elf" ;;
+ m32r_elf32_linux_vec) tb="$tb elf32-m32r.lo elf32.lo $elf" ;;
+ m32r_elf32_linux_le_vec) tb="$tb elf32-m32r.lo elf32.lo $elf" ;;
+ m68hc11_elf32_vec) tb="$tb elf32-m68hc11.lo elf32-m68hc1x.lo elf32.lo $elf" ;;
+ m68hc12_elf32_vec) tb="$tb elf32-m68hc12.lo elf32-m68hc1x.lo elf32.lo $elf" ;;
+ m68k_aout_4knbsd_vec) tb="$tb m68k4knetbsd.lo aout32.lo" ;;
+ m68k_aout_hp300bsd_vec) tb="$tb hp300bsd.lo aout32.lo" ;;
+ m68k_aout_hp300hpux_vec) tb="$tb hp300hpux.lo aout32.lo" ;;
+ m68k_aout_linux_vec) tb="$tb m68klinux.lo aout32.lo" ;;
+ m68k_aout_nbsd_vec) tb="$tb m68knetbsd.lo aout32.lo" ;;
+ m68k_aout_newsos3_vec) tb="$tb newsos3.lo aout32.lo" ;;
+ m68k_coff_vec) tb="$tb coff-m68k.lo cofflink.lo" ;;
+ m68k_coff_apollo_vec) tb="$tb coff-apollo.lo" ;;
+ m68k_coff_aux_vec) tb="$tb coff-aux.lo coff-m68k.lo cofflink.lo" ;;
+ m68k_coff_sysv_vec) tb="$tb coff-svm68k.lo cofflink.lo" ;;
+ m68k_coff_un_vec) tb="$tb coff-u68k.lo coff-m68k.lo cofflink.lo" ;;
+ m68k_elf32_vec) tb="$tb elf32-m68k.lo elf32.lo $elf" ;;
+ m68k_versados_vec) tb="$tb versados.lo" ;;
+ m88k_aout_mach3_vec) tb="$tb m88kmach3.lo aout32.lo" ;;
+ m88k_aout_obsd_vec) tb="$tb m88kopenbsd.lo aout32.lo" ;;
+ m88k_coff_bcs_vec) tb="$tb coff-m88k.lo" ;;
+ m88k_elf32_vec) tb="$tb elf32-m88k.lo elf32.lo $elf" ;;
+ mach_o_be_vec) tb="$tb mach-o.lo" ;;
+ mach_o_le_vec) tb="$tb mach-o.lo" ;;
+ mach_o_fat_vec) tb="$tb mach-o.lo" ;;
+ mcore_elf32_be_vec) tb="$tb elf32-mcore.lo elf32.lo $elf" ;;
+ mcore_elf32_le_vec) tb="$tb elf32-mcore.lo elf32.lo $elf" ;;
+ mcore_pe_be_vec) tb="$tb pe-mcore.lo peigen.lo cofflink.lo" ;;
+ mcore_pe_le_vec) tb="$tb pe-mcore.lo peigen.lo cofflink.lo" ;;
+ mcore_pei_be_vec) tb="$tb pei-mcore.lo peigen.lo cofflink.lo" ;;
+ mcore_pei_le_vec) tb="$tb pei-mcore.lo peigen.lo cofflink.lo" ;;
+ mep_elf32_vec) tb="$tb elf32-mep.lo elf32.lo $elf" ;;
+ mep_elf32_le_vec) tb="$tb elf32-mep.lo elf32.lo $elf" ;;
+ metag_elf32_vec) tb="$tb elf32-metag.lo elf32.lo $elf" ;;
+ microblaze_elf32_vec) tb="$tb elf32-microblaze.lo elf32.lo $elf" ;;
+ microblaze_elf32_le_vec) tb="$tb elf32-microblaze.lo elf32.lo $elf" ;;
+ mips_ecoff_be_vec) tb="$tb coff-mips.lo ecoff.lo ecofflink.lo" ;;
+ mips_ecoff_le_vec) tb="$tb coff-mips.lo ecoff.lo ecofflink.lo" ;;
+ mips_ecoff_bele_vec) tb="$tb coff-mips.lo ecoff.lo ecofflink.lo" ;;
+ mips_elf32_be_vec) tb="$tb elf32-mips.lo elfxx-mips.lo elf-vxworks.lo elf32.lo $elf ecofflink.lo" ;;
+ mips_elf32_le_vec) tb="$tb elf32-mips.lo elfxx-mips.lo elf-vxworks.lo elf32.lo $elf ecofflink.lo" ;;
+ mips_elf32_n_be_vec) tb="$tb elfn32-mips.lo elfxx-mips.lo elf-vxworks.lo elf32.lo $elf ecofflink.lo"; target_size=64 ;;
+ mips_elf32_n_le_vec) tb="$tb elfn32-mips.lo elfxx-mips.lo elf-vxworks.lo elf32.lo $elf ecofflink.lo"; target_size=64 ;;
+ mips_elf32_ntrad_be_vec) tb="$tb elfn32-mips.lo elfxx-mips.lo elf-vxworks.lo elf32.lo $elf ecofflink.lo"; target_size=64 ;;
+ mips_elf32_ntrad_le_vec) tb="$tb elfn32-mips.lo elfxx-mips.lo elf-vxworks.lo elf32.lo $elf ecofflink.lo"; target_size=64 ;;
+ mips_elf32_ntradfbsd_be_vec) tb="$tb elfn32-mips.lo elfxx-mips.lo elf-vxworks.lo elf32.lo $elf ecofflink.lo"; target_size=64 ;;
+ mips_elf32_ntradfbsd_le_vec) tb="$tb elfn32-mips.lo elfxx-mips.lo elf-vxworks.lo elf32.lo $elf ecofflink.lo"; target_size=64 ;;
+ mips_elf32_trad_be_vec) tb="$tb elf32-mips.lo elfxx-mips.lo elf-vxworks.lo elf32.lo $elf ecofflink.lo" ;;
+ mips_elf32_trad_le_vec) tb="$tb elf32-mips.lo elfxx-mips.lo elf-vxworks.lo elf32.lo $elf ecofflink.lo" ;;
+ mips_elf32_tradfbsd_be_vec) tb="$tb elf32-mips.lo elfxx-mips.lo elf-vxworks.lo elf32.lo $elf ecofflink.lo" ;;
+ mips_elf32_tradfbsd_le_vec) tb="$tb elf32-mips.lo elfxx-mips.lo elf-vxworks.lo elf32.lo $elf ecofflink.lo" ;;
+ mips_elf32_vxworks_be_vec) tb="$tb elf32-mips.lo elfxx-mips.lo elf-vxworks.lo elf32.lo $elf ecofflink.lo" ;;
+ mips_elf32_vxworks_le_vec) tb="$tb elf32-mips.lo elfxx-mips.lo elf-vxworks.lo elf32.lo $elf ecofflink.lo" ;;
+ mips_elf64_be_vec) tb="$tb elf64-mips.lo elf64.lo elfxx-mips.lo elf-vxworks.lo elf32.lo $elf ecofflink.lo"; target_size=64 ;;
+ mips_elf64_le_vec) tb="$tb elf64-mips.lo elf64.lo elfxx-mips.lo elf-vxworks.lo elf32.lo $elf ecofflink.lo"; target_size=64 ;;
+ mips_elf64_trad_be_vec) tb="$tb elf64-mips.lo elf64.lo elfxx-mips.lo elf-vxworks.lo elf32.lo $elf ecofflink.lo"; target_size=64 ;;
+ mips_elf64_trad_le_vec) tb="$tb elf64-mips.lo elf64.lo elfxx-mips.lo elf-vxworks.lo elf32.lo $elf ecofflink.lo"; target_size=64 ;;
+ mips_elf64_tradfbsd_be_vec) tb="$tb elf64-mips.lo elf64.lo elfxx-mips.lo elf-vxworks.lo elf32.lo $elf ecofflink.lo"; target_size=64 ;;
+ mips_elf64_tradfbsd_le_vec) tb="$tb elf64-mips.lo elf64.lo elfxx-mips.lo elf-vxworks.lo elf32.lo $elf ecofflink.lo"; target_size=64 ;;
+ mips_pe_le_vec) tb="$tb pe-mips.lo peigen.lo cofflink.lo" ;;
+ mips_pei_le_vec) tb="$tb pei-mips.lo peigen.lo cofflink.lo" ;;
+ mmix_elf64_vec) tb="$tb elf64-mmix.lo elf64.lo $elf" target_size=64 ;;
+ mmix_mmo_vec) tb="$tb mmo.lo" target_size=64 ;;
+ mn10200_elf32_vec) tb="$tb elf-m10200.lo elf32.lo $elf" ;;
+ mn10300_elf32_vec) tb="$tb elf-m10300.lo elf32.lo $elf" ;;
+ moxie_elf32_be_vec) tb="$tb elf32-moxie.lo elf32.lo $elf" ;;
+ moxie_elf32_le_vec) tb="$tb elf32-moxie.lo elf32.lo $elf" ;;
+ msp430_elf32_vec) tb="$tb elf32-msp430.lo elf32.lo $elf" ;;
+ msp430_elf32_ti_vec) tb="$tb elf32-msp430.lo elf32.lo $elf" ;;
+ mt_elf32_vec) tb="$tb elf32-mt.lo elf32.lo $elf" ;;
+ nds32_elf32_be_vec) tb="$tb elf32-nds32.lo elf32.lo $elf" ;;
+ nds32_elf32_le_vec) tb="$tb elf32-nds32.lo elf32.lo $elf" ;;
+ nds32_elf32_linux_be_vec) tb="$tb elf32-nds32.lo elf32.lo $elf" ;;
+ nds32_elf32_linux_le_vec) tb="$tb elf32-nds32.lo elf32.lo $elf" ;;
+ nios2_elf32_be_vec) tb="$tb elf32-nios2.lo elf32.lo $elf" ;;
+ nios2_elf32_le_vec) tb="$tb elf32-nios2.lo elf32.lo $elf" ;;
+ ns32k_aout_pc532mach_vec) tb="$tb pc532-mach.lo aout-ns32k.lo" ;;
+ ns32k_aout_pc532nbsd_vec) tb="$tb ns32knetbsd.lo aout-ns32k.lo" ;;
+ or1k_elf32_vec) tb="$tb elf32-or1k.lo elf32.lo $elf" ;;
+ pdp11_aout_vec) tb="$tb pdp11.lo" ;;
+ pef_vec) tb="$tb pef.lo" ;;
+ pef_xlib_vec) tb="$tb pef.lo" ;;
+ pj_elf32_vec) tb="$tb elf32-pj.lo elf32.lo $elf" ;;
+ pj_elf32_le_vec) tb="$tb elf32-pj.lo elf32.lo $elf" ;;
+ plugin_vec) tb="$tb plugin.lo" ;;
+ powerpc_boot_vec) tb="$tb ppcboot.lo" ;;
+ powerpc_elf32_vec) tb="$tb elf32-ppc.lo elf-vxworks.lo elf32.lo $elf" ;;
+ powerpc_elf32_le_vec) tb="$tb elf32-ppc.lo elf-vxworks.lo elf32.lo $elf" ;;
+ powerpc_elf32_fbsd_vec) tb="$tb elf32-ppc.lo elf-vxworks.lo elf32.lo $elf" ;;
+ powerpc_elf32_vxworks_vec) tb="$tb elf32-ppc.lo elf-vxworks.lo elf32.lo $elf" ;;
+ powerpc_elf64_vec) tb="$tb elf64-ppc.lo elf64-gen.lo elf64.lo $elf"; target_size=64 ;;
+ powerpc_elf64_le_vec) tb="$tb elf64-ppc.lo elf64-gen.lo elf64.lo $elf" target_size=64 ;;
+ powerpc_elf64_fbsd_vec) tb="$tb elf64-ppc.lo elf64-gen.lo elf64.lo $elf" target_size=64 ;;
+ powerpc_nlm32_vec) tb="$tb nlm32-ppc.lo nlm32.lo nlm.lo" ;;
+ powerpc_pe_vec) tb="$tb pe-ppc.lo peigen.lo cofflink.lo" ;;
+ powerpc_pe_le_vec) tb="$tb pe-ppc.lo peigen.lo cofflink.lo" ;;
+ powerpc_pei_vec) tb="$tb pei-ppc.lo peigen.lo cofflink.lo" ;;
+ powerpc_pei_le_vec) tb="$tb pei-ppc.lo peigen.lo cofflink.lo" ;;
+ powerpc_xcoff_vec) tb="$tb coff-rs6000.lo xcofflink.lo" ;;
+ rl78_elf32_vec) tb="$tb elf32-rl78.lo elf32.lo $elf" ;;
+ rs6000_xcoff64_vec) tb="$tb coff64-rs6000.lo xcofflink.lo aix5ppc-core.lo"; target_size=64 ;;
+ rs6000_xcoff64_aix_vec) tb="$tb coff64-rs6000.lo xcofflink.lo aix5ppc-core.lo"; target_size=64 ;;
+ rs6000_xcoff_vec) tb="$tb coff-rs6000.lo xcofflink.lo" ;;
+ rx_elf32_be_vec) tb="$tb elf32-rx.lo elf32.lo $elf" ;;
+ rx_elf32_be_ns_vec) tb="$tb elf32-rx.lo elf32.lo $elf" ;;
+ rx_elf32_le_vec) tb="$tb elf32-rx.lo elf32.lo $elf" ;;
+ s390_elf32_vec) tb="$tb elf32-s390.lo elf32.lo $elf" ;;
+ s390_elf64_vec) tb="$tb elf64-s390.lo elf64.lo $elf"; target_size=64 ;;
+ score_elf32_be_vec) tb="$tb elf32-score.lo elf32-score7.lo elf32.lo $elf"; want64=true; target_size=64 ;;
+ score_elf32_le_vec) tb="$tb elf32-score.lo elf32-score7.lo elf32.lo $elf"; want64=true; target_size=64 ;;
+ # FIXME: We include cofflink.lo not because it's needed for
+ # sh64_elf32[_le]_vec, but because we include sh_elf32[_le]_vec
+ # which needs it but does not list it. Should be fixed in right place.
+ sh64_elf32_vec) tb="$tb elf32-sh64.lo elf32-sh64-com.lo elf-vxworks.lo elf32.lo $elf cofflink.lo" target_size=64 ;;
+ sh64_elf32_le_vec) tb="$tb elf32-sh64.lo elf32-sh64-com.lo elf-vxworks.lo elf32.lo $elf cofflink.lo" target_size=64 ;;
+ sh64_elf32_linux_vec) tb="$tb elf32-sh64.lo elf32-sh64-com.lo elf-vxworks.lo elf32.lo $elf cofflink.lo" target_size=64 ;;
+ sh64_elf32_linux_be_vec) tb="$tb elf32-sh64.lo elf32-sh64-com.lo elf-vxworks.lo elf32.lo $elf cofflink.lo" target_size=64 ;;
+ sh64_elf32_nbsd_vec) tb="$tb elf32-sh64.lo elf32-sh64-com.lo elf-vxworks.lo elf32.lo $elf cofflink.lo" ;;
+ sh64_elf32_nbsd_le_vec) tb="$tb elf32-sh64.lo elf32-sh64-com.lo elf-vxworks.lo elf32.lo $elf cofflink.lo" ;;
+ sh64_elf64_vec) tb="$tb elf64-sh64.lo elf64.lo $elf" target_size=64 ;;
+ sh64_elf64_le_vec) tb="$tb elf64-sh64.lo elf64.lo $elf" target_size=64 ;;
+ sh64_elf64_linux_vec) tb="$tb elf64-sh64.lo elf64.lo $elf" target_size=64 ;;
+ sh64_elf64_linux_be_vec) tb="$tb elf64-sh64.lo elf64.lo $elf" target_size=64 ;;
+ sh64_elf64_nbsd_vec) tb="$tb elf64-sh64.lo elf64.lo $elf" target_size=64 ;;
+ sh64_elf64_nbsd_le_vec) tb="$tb elf64-sh64.lo elf64.lo $elf" target_size=64 ;;
+ sh_coff_vec) tb="$tb coff-sh.lo cofflink.lo" ;;
+ sh_coff_le_vec) tb="$tb coff-sh.lo cofflink.lo" ;;
+ sh_coff_small_vec) tb="$tb coff-sh.lo cofflink.lo" ;;
+ sh_coff_small_le_vec) tb="$tb coff-sh.lo cofflink.lo" ;;
+ sh_elf32_vec) tb="$tb elf32-sh.lo elf-vxworks.lo elf32.lo $elf coff-sh.lo" ;;
+ sh_elf32_le_vec) tb="$tb elf32-sh.lo elf-vxworks.lo elf32.lo $elf coff-sh.lo" ;;
+ sh_elf32_fdpic_be_vec) tb="$tb elf32-sh.lo elf-vxworks.lo elf32.lo $elf coff-sh.lo cofflink.lo" ;;
+ sh_elf32_fdpic_le_vec) tb="$tb elf32-sh.lo elf-vxworks.lo elf32.lo $elf coff-sh.lo cofflink.lo" ;;
+ sh_elf32_linux_vec) tb="$tb elf32-sh.lo elf-vxworks.lo elf32.lo $elf coff-sh.lo cofflink.lo" ;;
+ sh_elf32_linux_be_vec) tb="$tb elf32-sh.lo elf-vxworks.lo elf32.lo $elf coff-sh.lo cofflink.lo" ;;
+ sh_elf32_nbsd_vec) tb="$tb elf32-sh.lo elf-vxworks.lo elf32.lo $elf coff-sh.lo cofflink.lo" ;;
+ sh_elf32_nbsd_le_vec) tb="$tb elf32-sh.lo elf-vxworks.lo elf32.lo $elf coff-sh.lo cofflink.lo" ;;
+ sh_elf32_symbian_le_vec) tb="$tb elf32-sh-symbian.lo elf32-sh64-com.lo elf-vxworks.lo elf32.lo $elf coff-sh.lo" ;;
+ sh_elf32_vxworks_vec) tb="$tb elf32-sh.lo elf-vxworks.lo elf32.lo $elf coff-sh.lo" ;;
+ sh_elf32_vxworks_le_vec) tb="$tb elf32-sh.lo elf-vxworks.lo elf32.lo $elf coff-sh.lo" ;;
+ sh_pe_le_vec) tb="$tb pe-sh.lo coff-sh.lo peigen.lo cofflink.lo" ;;
+ sh_pei_le_vec) tb="$tb pei-sh.lo coff-sh.lo peigen.lo cofflink.lo" ;;
+ sparc_aout_le_vec) tb="$tb aout-sparcle.lo aout32.lo" ;;
+ sparc_aout_linux_vec) tb="$tb sparclinux.lo aout32.lo" ;;
+ sparc_aout_lynx_vec) tb="$tb sparclynx.lo lynx-core.lo aout32.lo" ;;
+ sparc_aout_nbsd_vec) tb="$tb sparcnetbsd.lo aout32.lo" ;;
+ sparc_aout_sunos_be_vec) tb="$tb sunos.lo aout32.lo" ;;
+ sparc_coff_vec) tb="$tb coff-sparc.lo" ;;
+ sparc_coff_lynx_vec) tb="$tb cf-sparclynx.lo lynx-core.lo" ;;
+ sparc_elf32_vec) tb="$tb elf32-sparc.lo elfxx-sparc.lo elf-vxworks.lo elf32.lo $elf" ;;
+ sparc_elf32_sol2_vec) tb="$tb elf32-sparc.lo elfxx-sparc.lo elf-vxworks.lo elf32.lo $elf" ;;
+ sparc_elf32_vxworks_vec) tb="$tb elf32-sparc.lo elfxx-sparc.lo elf-vxworks.lo elf32.lo $elf" ;;
+ sparc_elf64_vec) tb="$tb elf64-sparc.lo elfxx-sparc.lo elf-vxworks.lo elf64.lo $elf"; target_size=64 ;;
+ sparc_elf64_fbsd_vec) tb="$tb elf64-sparc.lo elfxx-sparc.lo elf-vxworks.lo elf64.lo $elf"; target_size=64 ;;
+ sparc_elf64_sol2_vec) tb="$tb elf64-sparc.lo elfxx-sparc.lo elf-vxworks.lo elf64.lo $elf"; target_size=64 ;;
+ sparc_nlm32_vec) tb="$tb nlm32-sparc.lo nlm32.lo nlm.lo" ;;
+ spu_elf32_vec) tb="$tb elf32-spu.lo elf32.lo $elf" ;;
+ sym_vec) tb="$tb xsym.lo" ;;
+ tic30_aout_vec) tb="$tb aout-tic30.lo" ;;
+ tic30_coff_vec) tb="$tb coff-tic30.lo" ;;
+ tic4x_coff0_vec) tb="$tb coff-tic4x.lo" ;;
+ tic4x_coff0_beh_vec) tb="$tb coff-tic4x.lo" ;;
+ tic4x_coff1_vec) tb="$tb coff-tic4x.lo" ;;
+ tic4x_coff1_beh_vec) tb="$tb coff-tic4x.lo" ;;
+ tic4x_coff2_vec) tb="$tb coff-tic4x.lo" ;;
+ tic4x_coff2_beh_vec) tb="$tb coff-tic4x.lo" ;;
+ tic54x_coff0_vec) tb="$tb coff-tic54x.lo" ;;
+ tic54x_coff0_beh_vec) tb="$tb coff-tic54x.lo" ;;
+ tic54x_coff1_vec) tb="$tb coff-tic54x.lo" ;;
+ tic54x_coff1_beh_vec) tb="$tb coff-tic54x.lo" ;;
+ tic54x_coff2_vec) tb="$tb coff-tic54x.lo" ;;
+ tic54x_coff2_beh_vec) tb="$tb coff-tic54x.lo" ;;
+ tic6x_elf32_be_vec) tb="$tb elf32-tic6x.lo elf32.lo $elf" ;;
+ tic6x_elf32_le_vec) tb="$tb elf32-tic6x.lo elf32.lo $elf" ;;
+ tic6x_elf32_c6000_be_vec) tb="$tb elf32-tic6x.lo elf32.lo $elf" ;;
+ tic6x_elf32_c6000_le_vec) tb="$tb elf32-tic6x.lo elf32.lo $elf" ;;
+ tic6x_elf32_linux_be_vec) tb="$tb elf32-tic6x.lo elf32.lo $elf" ;;
+ tic6x_elf32_linux_le_vec) tb="$tb elf32-tic6x.lo elf32.lo $elf" ;;
+ tic80_coff_vec) tb="$tb coff-tic80.lo cofflink.lo" ;;
+ tilegx_elf32_be_vec) tb="$tb elf32-tilegx.lo elfxx-tilegx.lo elf32.lo $elf" ; target_size=32 ;;
+ tilegx_elf32_le_vec) tb="$tb elf32-tilegx.lo elfxx-tilegx.lo elf32.lo $elf" ; target_size=32 ;;
+ tilegx_elf64_be_vec) tb="$tb elf64-tilegx.lo elfxx-tilegx.lo elf64.lo $elf" ; target_size=64 ;;
+ tilegx_elf64_le_vec) tb="$tb elf64-tilegx.lo elfxx-tilegx.lo elf64.lo $elf" ; target_size=64 ;;
+ tilepro_elf32_vec) tb="$tb elf32-tilepro.lo elf32.lo $elf" ;;
+ v800_elf32_vec) tb="$tb elf32-v850.lo elf32.lo $elf" ;;
+ v850_elf32_vec) tb="$tb elf32-v850.lo elf32.lo $elf" ;;
+ vax_aout_1knbsd_vec) tb="$tb vax1knetbsd.lo aout32.lo" ;;
+ vax_aout_bsd_vec) tb="$tb vaxbsd.lo aout32.lo" ;;
+ vax_aout_nbsd_vec) tb="$tb vaxnetbsd.lo aout32.lo" ;;
+ vax_elf32_vec) tb="$tb elf32-vax.lo elf32.lo $elf" ;;
+ w65_coff_vec) tb="$tb coff-w65.lo reloc16.lo" ;;
+ we32k_coff_vec) tb="$tb coff-we32k.lo" ;;
+ x86_64_coff_vec) tb="$tb coff-x86_64.lo cofflink.lo"; target_size=64 ;;
+ x86_64_elf32_vec) tb="$tb elf64-x86-64.lo elf-ifunc.lo elf-nacl.lo elf64.lo elf32.lo $elf"; target_size=64 ;;
+ x86_64_elf32_nacl_vec) tb="$tb elf64-x86-64.lo elf-ifunc.lo elf-nacl.lo elf64.lo elf32.lo $elf"; target_size=64 ;;
+ x86_64_elf64_vec) tb="$tb elf64-x86-64.lo elf-ifunc.lo elf-nacl.lo elf64.lo $elf"; target_size=64 ;;
+ x86_64_elf64_fbsd_vec) tb="$tb elf64-x86-64.lo elf-ifunc.lo elf-nacl.lo elf64.lo $elf"; target_size=64 ;;
+ x86_64_elf64_nacl_vec) tb="$tb elf64-x86-64.lo elf-ifunc.lo elf-nacl.lo elf64.lo $elf"; target_size=64 ;;
+ x86_64_elf64_sol2_vec) tb="$tb elf64-x86-64.lo elf-ifunc.lo elf-nacl.lo elf64.lo $elf"; target_size=64 ;;
+ x86_64_mach_o_vec) tb="$tb mach-o-x86-64.lo" ;;
+ x86_64_pe_vec) tb="$tb pe-x86_64.lo pex64igen.lo cofflink.lo"; target_size=64 ;;
+ x86_64_pe_be_vec) tb="$tb pe-x86_64.lo pex64igen.lo cofflink.lo"; target_size=64 ;;
+ x86_64_pei_vec) tb="$tb pei-x86_64.lo pex64igen.lo cofflink.lo"; target_size=64 ;;
+ xc16x_elf32_vec) tb="$tb elf32-xc16x.lo elf32.lo $elf" ;;
+ xgate_elf32_vec) tb="$tb elf32-xgate.lo elf32.lo $elf" ;;
+ xstormy16_elf32_vec) tb="$tb elf32-xstormy16.lo elf32.lo $elf" ;;
+ xtensa_elf32_be_vec) tb="$tb xtensa-isa.lo xtensa-modules.lo elf32-xtensa.lo elf32.lo $elf" ;;
+ xtensa_elf32_le_vec) tb="$tb xtensa-isa.lo xtensa-modules.lo elf32-xtensa.lo elf32.lo $elf" ;;
+ z80_coff_vec) tb="$tb coff-z80.lo reloc16.lo" ;;
+ z8k_coff_vec) tb="$tb coff-z8k.lo reloc16.lo cofflink.lo" ;;
+
+ # These appear out of order in targets.c
+ srec_vec) tb="$tb srec.lo" ;;
+ symbolsrec_vec) tb="$tb srec.lo" ;;
+ tekhex_vec) tb="$tb tekhex.lo" ;;
+ core_cisco_be_vec) tb="$tb cisco-core.lo" ;;
+ core_cisco_le_vec) tb="$tb cisco-core.lo" ;;
+
+ "") ;;
+ *) AC_MSG_ERROR(*** unknown target vector $vec) ;;
+ esac
+
+ if test ${target_size} = 64; then
+ target64=true
+ fi
+ if test x"${vec}" = x"${defvec}"; then
+ bfd_default_target_size=${target_size}
+ fi
+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=-DHAVE_all_vecs
+ selarchs=
+ test -n "$assocvecs" &&
+ assocvecs=`echo $assocvecs | sed -e 's/^/\&/' -e 's/ \(.\)/,\&\1/g'`
+else # all_targets is true
+ # Only set these if they will be nonempty, for the clever echo.
+ havevecs=
+ assocvecs=
+ 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
+ bfd64_libs='$(BFD64_LIBS)'
+ all_backends='$(BFD64_BACKENDS) $(BFD32_BACKENDS)'
+ if 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
+ if test -n "$GCC" ; then
+ bad_64bit_gcc=no;
+ AC_MSG_CHECKING([for gcc version with buggy 64-bit support])
+ # Add more tests for gcc versions with non-working 64-bit support here.
+ AC_EGREP_CPP([: 2 : 91 : 1 :],[:__GNUC__:__GNUC_MINOR__:__i386__:],
+ bad_64bit_gcc=yes;
+ AC_MSG_RESULT([yes: egcs-1.1.2 on ix86 spotted]),
+ AC_MSG_RESULT(no))
+ if test $bad_64bit_gcc = yes ; then
+ AC_MSG_ERROR([A newer version of gcc is needed for the requested 64-bit BFD configuration])
+ fi
+ fi
+ ;;
+ false-false-false)
+ wordsize=32
+ all_backends='$(BFD32_BACKENDS)'
+ ;;
+esac
+
+AC_SUBST(wordsize)
+AC_SUBST(bfd64_libs)
+AC_SUBST(all_backends)
+AC_SUBST(bfd_backends)
+AC_SUBST(bfd_machines)
+AC_SUBST(bfd_default_target_size)
+
+if test "$plugins" = "yes"; then
+ supports_plugins=1
+else
+ supports_plugins=0
+fi
+AC_SUBST(supports_plugins)
+AC_SUBST(lt_cv_dlopen_libs)
+
+# Determine the host dependant file_ptr a.k.a. off_t type. In order
+# prefer: off64_t - if ftello64 and fseeko64, off_t - if ftello and
+# fseeko, long. This assumes that sizeof off_t is .ge. sizeof long.
+# Hopefully a reasonable assumption since fseeko et.al. should be
+# upward compatible.
+AC_CHECK_FUNCS(ftello ftello64 fseeko fseeko64 fopen64)
+if test x"$ac_cv_func_ftello" = xyes -a x"$ac_cv_func_fseeko" = xyes; then
+ AC_CHECK_SIZEOF(off_t)
+fi
+AC_MSG_CHECKING([file_ptr type])
+bfd_file_ptr="long"
+bfd_ufile_ptr="unsigned long"
+if test x"$ac_cv_func_ftello64" = xyes -a x"$ac_cv_func_fseeko64" = xyes \
+ -o x"${ac_cv_sizeof_off_t}" = x8; then
+ bfd_file_ptr=BFD_HOST_64_BIT
+ bfd_ufile_ptr=BFD_HOST_U_64_BIT
+fi
+AC_MSG_RESULT($bfd_file_ptr)
+AC_SUBST(bfd_file_ptr)
+AC_SUBST(bfd_ufile_ptr)
+
+
+tdefaults=""
+test -n "${defvec}" && tdefaults="${tdefaults} -DDEFAULT_VECTOR=${defvec}"
+test -n "${selvecs}" && tdefaults="${tdefaults} -DSELECT_VECS='${selvecs}'"
+test -n "${assocvecs}" && tdefaults="${tdefaults} -DASSOCIATED_VECS='${assocvecs}'"
+test -n "${selarchs}" && tdefaults="${tdefaults} -DSELECT_ARCHITECTURES='${selarchs}'"
+AC_SUBST(tdefaults)
+AC_SUBST(havevecs)
+
+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_CONFIG_FILES([Makefile doc/Makefile bfd-in3.h:bfd-in2.h po/Makefile.in:po/Make-in])
+
+dnl We need this duplication, even though we use AM_PO_SUBDIRS, because of
+dnl our two separate POTFILES. Yuck.
+AC_CONFIG_COMMANDS([default],
+[[
+case "$srcdir" in
+ .) srcdirpre= ;;
+ *) srcdirpre='$(srcdir)/' ;;
+esac
+POFILES=
+GMOFILES=
+for lang in dummy $OBSOLETE_ALL_LINGUAS; do
+ if test $lang != dummy; then
+ POFILES="$POFILES $srcdirpre$lang.po"
+ GMOFILES="$GMOFILES $srcdirpre$lang.gmo"
+ fi
+done
+sed -e '/SRC-POTFILES =/r po/SRC-POTFILES' \
+ -e '/BLD-POTFILES =/r po/BLD-POTFILES' \
+ -e "s,@POFILES@,$POFILES," \
+ -e "s,@GMOFILES@,$GMOFILES," \
+ po/Makefile.in > po/Makefile]],[[]])
+
+dnl Required by html, pdf, install-pdf and install-html
+AC_SUBST(datarootdir)
+AC_SUBST(docdir)
+AC_SUBST(htmldir)
+AC_SUBST(pdfdir)
+
+AC_OUTPUT
diff --git a/bfd/configure.com b/bfd/configure.com
new file mode 100644
index 0000000..707ba49
--- /dev/null
+++ b/bfd/configure.com
@@ -0,0 +1,407 @@
+$!
+$! This file configures the bfd library for use with openVMS.
+$!
+$! 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)
+$! Rewritten by Tristan Gingold (gingold@adacore.com)
+$!
+$! Copyright (C) 2012-2014 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 3 of the License, or
+$! (at your option) any later version.
+$!
+$! This program is distributed in the hope that it will be useful,
+$! but WITHOUT ANY WARRANTY; without even the implied warranty of
+$! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 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 COPYING3. If not see
+$! <http://www.gnu.org/licenses/>.
+$!
+$ arch=F$GETSYI("ARCH_NAME")
+$ arch=F$EDIT(arch,"LOWERCASE")
+$if arch .eqs. "alpha" then target = "alpha"
+$if arch .eqs. "ia64" then target = "ia64"
+$!
+$if (arch .eqs. "alpha") .or. (arch .eqs. "ia64")
+$then
+$!
+$ write sys$output "Configuring BFD for ''target' target"
+$!
+$!
+$! 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 (@@)
+!
+!
+ set (success,off);
+
+ file := CREATE_BUFFER("file", GET_INFO(COMMAND_LINE, "file_name"));
+ rang := CREATE_RANGE(BEGINNING_OF(file), END_OF(file));
+
+ 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_default_target_size@', 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_LONG_LONG@', FORWARD, EXACT, rang);
+ IF match_pos <> 0 THEN;
+ POSITION(BEGINNING_OF(match_pos));
+ ERASE(match_pos);
+ COPY_TEXT('1');
+ ENDIF;
+ match_pos := SEARCH_QUIETLY('@BFD_HOST_64BIT_LONG_LONG@', FORWARD, EXACT, rang);
+ IF match_pos <> 0 THEN;
+ POSITION(BEGINNING_OF(match_pos));
+ ERASE(match_pos);
+ COPY_TEXT('1');
+ 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('1');
+ 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('unsigned __int64');
+ ENDIF;
+ match_pos := SEARCH_QUIETLY('@BFD_HOSTPTR_T@', FORWARD, EXACT, rang);
+ IF match_pos <> 0 THEN;
+ POSITION(BEGINNING_OF(match_pos));
+ ERASE(match_pos);
+ COPY_TEXT('unsigned __int64');
+ ENDIF;
+ match_pos := SEARCH_QUIETLY('@bfd_file_ptr@', FORWARD, EXACT, rang);
+ IF match_pos <> 0 THEN;
+ POSITION(BEGINNING_OF(match_pos));
+ ERASE(match_pos);
+ COPY_TEXT('bfd_signed_vma');
+ ENDIF;
+ match_pos := SEARCH_QUIETLY('unsigned @bfd_file_ptr@ ufile_ptr', FORWARD, EXACT, rang);
+ IF match_pos <> 0 THEN;
+ POSITION(BEGINNING_OF(match_pos));
+ ERASE(match_pos);
+ COPY_TEXT('bfd_vma ufile_ptr');
+ ENDIF;
+ match_pos := SEARCH_QUIETLY('@supports_plugins@', FORWARD, EXACT, rang);
+ IF match_pos <> 0 THEN;
+ POSITION(BEGINNING_OF(match_pos));
+ ERASE(match_pos);
+ COPY_TEXT('0');
+ 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
+$!
+$ write sys$output "Generated `bfd.h' from `bfd-in2.h'."
+$ edit/tpu/nojournal/nosection/nodisplay/command=sys$input -
+ []bfd-in2.h /output=[]bfd.h
+$DECK
+!
+! Copy file, changing lines with macros (@@)
+!
+!
+ set (success,off);
+
+ file := CREATE_BUFFER("file", GET_INFO(COMMAND_LINE, "file_name"));
+ rang := CREATE_RANGE(BEGINNING_OF(file), END_OF(file));
+
+ 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
+$
+$!
+$! create bfdver.h
+$!
+$ write sys$output "Generate `bfdver.h' from 'version.h' and `configure.in'."
+$ edit/tpu/nojournal/nosection/nodisplay/command=sys$input -
+ []version.h /output=[]bfdver.h
+$DECK
+!
+! Copy file, changing lines with macros (@@)
+!
+!
+ set (success,off);
+ vfile := CREATE_BUFFER("vfile", "configure.in");
+ rang := CREATE_RANGE(BEGINNING_OF(vfile), END_OF(vfile));
+ match_pos := SEARCH_QUIETLY('AC_INIT([bfd], [', FORWARD, EXACT, rang);
+ IF match_pos <> 0 THEN;
+ POSITION(BEGINNING_OF(match_pos));
+ ERASE(match_pos);
+ vers := CURRENT_LINE-"])";
+ ELSE;
+ vers := "unknown";
+ ENDIF;
+ versnum := vers - "." - ".";
+
+ file := CREATE_BUFFER("file", GET_INFO(COMMAND_LINE, "file_name"));
+ rang := CREATE_RANGE(BEGINNING_OF(file), END_OF(file));
+
+ match_pos := SEARCH_QUIETLY('@bfd_version@', FORWARD, EXACT, rang);
+ IF match_pos <> 0 THEN;
+ POSITION(BEGINNING_OF(match_pos));
+ ERASE(match_pos);
+ COPY_TEXT(versnum);
+ ENDIF;
+ match_pos := SEARCH_QUIETLY('@bfd_version_string@', FORWARD, EXACT, rang);
+ IF match_pos <> 0 THEN;
+ POSITION(BEGINNING_OF(match_pos));
+ ERASE(match_pos);
+ COPY_TEXT('"');
+ COPY_TEXT(vers);
+ COPY_TEXT('"');
+ ENDIF;
+ match_pos := SEARCH_QUIETLY('@bfd_version_package@', FORWARD, EXACT, rang);
+ IF match_pos <> 0 THEN;
+ POSITION(BEGINNING_OF(match_pos));
+ ERASE(match_pos);
+ COPY_TEXT('"(GNU Binutils) "');
+ ENDIF;
+ match_pos := SEARCH_QUIETLY('@report_bugs_to@', FORWARD, EXACT, rang);
+ IF match_pos <> 0 THEN;
+ POSITION(BEGINNING_OF(match_pos));
+ ERASE(match_pos);
+ COPY_TEXT('"<http://www.sourceware.org/bugzilla/>"');
+ ENDIF;
+ WRITE_FILE(file, GET_INFO(COMMAND_LINE, "output_file"));
+ QUIT
+$ EOD
+$!
+$!
+$! create bfd_stdint.h
+$!
+$ write sys$output "Generate `bfd_stdint.h'"
+$ create []bfd_stdint.h
+#include <inttypes.h>
+$!
+$!
+$! create targmatch.h
+$!
+$ write sys$output "Generate `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
+$!
+$!
+$! create config.h
+$!
+$ write sys$output "Generate `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
+/* Disable NLS */
+#undef ENABLE_NLS
+/* Name of package */
+#define PACKAGE "bfd"
+/* Define to the address where bug reports for this package should be sent. */
+#define PACKAGE_BUGREPORT ""
+/* Define to the full name of this package. */
+#define PACKAGE_NAME "bfd"
+/* Define to the full name and version of this package. */
+#define PACKAGE_STRING "bfd"
+/* Define to the one symbol short name of this package. */
+#define PACKAGE_TARNAME "bfd"
+/* Define to the home page for this package. */
+#define PACKAGE_URL ""
+/* Define to the version of this package. */
+#define PACKAGE_VERSION "(package version)"
+$!
+$ write sys$output "Copy sysdep.h"
+$ copy [.hosts]alphavms.h sysdep.h
+$
+$ write sys$output "Generate build.com"
+$!
+$ if ARCH.eqs."alpha"
+$ then
+$ create build.com
+$DECK
+$ DEFS="""SELECT_VECS=&alpha_vms_vec"","+-
+ """SELECT_ARCHITECTURES=&bfd_alpha_arch"""
+$ FILES="cpu-alpha,vms,vms-hdr,vms-gsd,vms-tir,vms-misc,"
+$EOD
+$ endif
+$ if ARCH.eqs."ia64"
+$ then
+$ create build.com
+$DECK
+$ DEFS="""SELECT_VECS=&ia64_elf64_vms_vec"","+-
+ """SELECT_ARCHITECTURES=&bfd_ia64_arch"""
+$ FILES="cpu-ia64,elf64-ia64,elf-strtab,corefile,stabs,merge,elf-eh-frame,"+-
+ "elflink,elf-attrs,dwarf1,elf64,"
+$EOD
+$ create substxx.tpu
+$DECK
+ set (success,off);
+ file := CREATE_BUFFER("file", GET_INFO(COMMAND_LINE, "file_name"));
+ found_range := CREATE_RANGE(BEGINNING_OF(file), BEGINNING_OF(file));
+
+ LOOP
+ rang := CREATE_RANGE (END_OF(found_range),END_OF(file));
+ match_pos := SEARCH_QUIETLY('NN', FORWARD, EXACT, rang);
+ EXITIF match_pos = 0;
+ POSITION(BEGINNING_OF(match_pos));
+ ERASE(match_pos);
+ COPY_TEXT('64');
+ ENDLOOP;
+ WRITE_FILE(file, GET_INFO(COMMAND_LINE, "output_file"));
+ QUIT
+$ EOD
+$ write sys$output "Generate elf64-target.h from elfxx-target.h"
+$ edit/tpu/nojournal/nosection/nodisplay/command=substxx.tpu -
+ []elfXX-target.h /output=[]elf64-target.h
+$ del substxx.tpu;*
+$ endif
+$ append sys$input build.com
+$DECK
+$ DEFS=DEFS + ",""unlink=remove"",""DEBUGDIR=""""GNU$DEBUGDIR:"""""""
+$ OPT="/noopt/debug"
+$ CFLAGS="/name=(as_is,shortened)" + -
+ "/include=([],""../"",""../include"")" + -
+ "/define=(" + DEFS + ")" + OPT
+$ FILES=FILES + "archive,archive64,archures,bfd,bfdio,binary,cache,coffgen,"+-
+ "compress,corefile,dwarf2,elf,format,hash,ihex,init,libbfd,linker,"+-
+ "opncls,reloc,section,simple,srec,stab-syms,syms,targets,tekhex,verilog"
+$ write sys$output "CFLAGS=",CFLAGS
+$ cflags_libbfd="/warning=(disable=missingreturn)"
+$ cflags_nil=""
+$ NUM = 0
+$ OBJS=""
+$ LOOP:
+$ F = F$ELEMENT(NUM,",",FILES)
+$ IF F.EQS."," THEN GOTO END
+$ eflags_name="cflags_''f'"
+$ name_len=f$length(eflags_name)
+$ dash_pos=f$locate("-",eflags_name)
+$ if dash_pos.ne.name_len
+$ then
+$ eflags_name['dash_pos,1]:="_"
+$ dash_pos=f$locate("-",eflags_name)
+$ if dash_pos.ne.name_len then eflags_name['dash_pos,1]:="_"
+$ endif
+$ if f$type('eflags_name).eqs."" then eflags_name="cflags_nil"
+$ eflags='eflags_name
+$ write sys$output "Compiling ", F, ".c", eflags
+$ cc 'CFLAGS 'eflags 'F.c
+$ IF OBJS.NES."" THEN OBJS=OBJS + ","
+$ OBJS=OBJS + F + ".obj"
+$ NUM = NUM + 1
+$ GOTO LOOP
+$ END:
+$ purge
+$ lib/create libbfd 'OBJS
+$EOD
diff --git a/bfd/configure.host b/bfd/configure.host
new file mode 100644
index 0000000..5942e57
--- /dev/null
+++ b/bfd/configure.host
@@ -0,0 +1,102 @@
+#
+# Copyright (C) 2012-2014 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 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 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 COPYING3. If not see
+# <http://www.gnu.org/licenses/>.
+#
+# 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.ac 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
+
+hppa*64*-*-hpux*) # HP/UX's ftello64 et.al. declarations are only
+ # visible when _LARGEFILE64_SOURCE is defined.
+ # Without those declarations, real_ftell et.al.
+ # get mis-compiled.
+ HDEFINES="-DHOST_HPPAHPUX -D_LARGEFILE64_SOURCE"
+ host64=true;;
+hppa*-*-hpux*) HDEFINES="-DHOST_HPPAHPUX -D_LARGEFILE64_SOURCE" ;;
+hppa*-*-hiux*) HDEFINES=-DHOST_HPPAHPUX ;;
+hppa*-*-mpeix*) HDEFINES=-DHOST_HPPAMPEIX ;;
+hppa*-*-bsd*) HDEFINES=-DHOST_HPPABSD ;;
+hppa*-*-osf*) HDEFINES=-DHOST_HPPAOSF ;;
+
+ia64-*-hpux*) HDEFINES=-D_LARGEFILE64_SOURCE
+ host64=true;;
+ia64-*-*) host64=true;;
+
+# Workaround for limitations on win9x where file contents are
+# not zero'd out if you seek past the end and then write.
+i[3-7]86-*-mingw32*) HDEFINES=-D__USE_MINGW_FSEEK;;
+
+i[3-7]86-sequent-bsd*) HDEFINES=-Dshared=genshared ;;
+i[3-7]86-sequent-sysv4*) ;;
+i[3-7]86-sequent-sysv*) HDEFINES=-Dshared=genshared ;;
+
+mips*-*-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;;
+mips64*-*-linux*) host64=true;;
+mips64*-*-freebsd* | mips64*-*-kfreebsd*-gnu) host64=true;;
+mips*-*-sysv4*) ;;
+mips*-*-sysv*) HDEFINES="-G 4" ;;
+mips*-*-riscos*) HDEFINES="-G 4" ;;
+
+m68*-hp-hpux*) HDEFINES=-DHOST_HP300HPUX ;;
+
+# Some Solaris systems (osol0906 at least) have a libc that doesn't recognise
+# the "MS-ANSI" code page name, so we define an override for CP_ACP (sets the
+# default code page used by windres/windmc when not specified by a commandline
+# option) to select the "WINDOWS-1252" name instead. See PR11280 for details.
+*-*-solaris2.11) HDEFINES=-DCP_ACP=1 ;;
+
+*-*-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_func_getuid=no
+ ac_cv_func_getgid=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/corefile.c b/bfd/corefile.c
new file mode 100644
index 0000000..1b87e86
--- /dev/null
+++ b/bfd/corefile.c
@@ -0,0 +1,190 @@
+/* Core file generic interface routines for BFD.
+ Copyright (C) 1990-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+/*
+SECTION
+ Core files
+
+SUBSECTION
+ Core file functions
+
+DESCRIPTION
+ These are functions pertaining to core files.
+*/
+
+#include "sysdep.h"
+#include "bfd.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 (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 (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
+ bfd_core_file_pid
+
+SYNOPSIS
+ int bfd_core_file_pid (bfd *abfd);
+
+DESCRIPTION
+
+ Returns the PID of the process the core dump the BFD
+ @var{abfd} is attached to was generated from.
+*/
+
+int
+bfd_core_file_pid (bfd *abfd)
+{
+ if (abfd->format != bfd_core)
+ {
+ bfd_set_error (bfd_error_invalid_operation);
+ return 0;
+ }
+ return BFD_SEND (abfd, _core_file_pid, (abfd));
+}
+
+
+/*
+FUNCTION
+ core_file_matches_executable_p
+
+SYNOPSIS
+ bfd_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.
+*/
+
+bfd_boolean
+core_file_matches_executable_p (bfd *core_bfd, 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));
+}
+
+/*
+FUNCTION
+ generic_core_file_matches_executable_p
+
+SYNOPSIS
+ bfd_boolean generic_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}. The match is based on executable
+ basenames only.
+
+ Note: When not able to determine the core file failing
+ command or the executable name, we still return TRUE even
+ though we're not sure that core file and executable match.
+ This is to avoid generating a false warning in situations
+ where we really don't know whether they match or not.
+*/
+
+bfd_boolean
+generic_core_file_matches_executable_p (bfd *core_bfd, bfd *exec_bfd)
+{
+ char *exec;
+ char *core;
+ char *last_slash;
+
+ if (exec_bfd == NULL || core_bfd == NULL)
+ return TRUE;
+
+ /* The cast below is to avoid a compiler warning due to the assignment
+ of the const char * returned by bfd_core_file_failing_command to a
+ non-const char *. In this case, the assignement does not lead to
+ breaking the const, as we're only reading the string. */
+
+ core = (char *) bfd_core_file_failing_command (core_bfd);
+ if (core == NULL)
+ return TRUE;
+
+ exec = bfd_get_filename (exec_bfd);
+ if (exec == NULL)
+ return TRUE;
+
+ last_slash = strrchr (core, '/');
+ if (last_slash != NULL)
+ core = last_slash + 1;
+
+ last_slash = strrchr (exec, '/');
+ if (last_slash != NULL)
+ exec = last_slash + 1;
+
+ return filename_cmp (exec, core) == 0;
+}
+
diff --git a/bfd/cpu-aarch64.c b/bfd/cpu-aarch64.c
new file mode 100644
index 0000000..616eb27
--- /dev/null
+++ b/bfd/cpu-aarch64.c
@@ -0,0 +1,127 @@
+/* BFD support for AArch64.
+ Copyright (C) 2009-2014 Free Software Foundation, Inc.
+ Contributed by ARM Ltd.
+
+ This file is part of BFD, the Binary File Descriptor library.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 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 COPYING3. If not,
+ see <http://www.gnu.org/licenses/>. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+#include "libiberty.h"
+
+/* This routine is provided two arch_infos and works out which Aarch64
+ machine which would be compatible with both and returns a pointer
+ to its info structure. */
+
+static const bfd_arch_info_type *
+compatible (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;
+
+ /* Don't allow mixing ilp32 with lp64. */
+ if ((a->mach & bfd_mach_aarch64_ilp32) != (b->mach & bfd_mach_aarch64_ilp32))
+ return NULL;
+
+ /* 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 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
+{
+ unsigned int mach;
+ char *name;
+}
+processors[] =
+{
+ /* These two are example CPUs supported in GCC, once we have real
+ CPUs they will be removed. */
+ { bfd_mach_aarch64, "example-1" },
+ { bfd_mach_aarch64, "example-2" }
+};
+
+static bfd_boolean
+scan (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->mach == processors[i].mach)
+ return TRUE;
+
+ /* Finally check for the default architecture. */
+ if (strcasecmp (string, "aarch64") == 0)
+ return info->the_default;
+
+ return FALSE;
+}
+
+#define N(NUMBER, PRINT, DEFAULT, NEXT) \
+ { 64, 64, 8, bfd_arch_aarch64, NUMBER, \
+ "aarch64", PRINT, 4, DEFAULT, compatible, scan, \
+ bfd_arch_default_fill, NEXT }
+
+static const bfd_arch_info_type bfd_aarch64_arch_ilp32 =
+ N (bfd_mach_aarch64_ilp32, "aarch64:ilp32", FALSE, NULL);
+
+const bfd_arch_info_type bfd_aarch64_arch =
+ N (0, "aarch64", TRUE, &bfd_aarch64_arch_ilp32);
+
+bfd_boolean
+bfd_is_aarch64_special_symbol_name (const char *name, int type)
+{
+ if (!name || name[0] != '$')
+ return FALSE;
+ if (name[1] == 'x' || name[1] == 'd')
+ type &= BFD_AARCH64_SPECIAL_SYM_TYPE_MAP;
+ else if (name[1] == 'm' || name[1] == 'f' || name[1] == 'p')
+ type &= BFD_AARCH64_SPECIAL_SYM_TYPE_TAG;
+ else
+ return FALSE;
+
+ return (type != 0 && (name[2] == 0 || name[2] == '.'));
+}
diff --git a/bfd/cpu-alpha.c b/bfd/cpu-alpha.c
new file mode 100644
index 0000000..da16661
--- /dev/null
+++ b/bfd/cpu-alpha.c
@@ -0,0 +1,53 @@
+/* BFD support for the Alpha architecture.
+ Copyright (C) 1992-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.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, \
+ bfd_arch_default_fill, \
+ NEXT, \
+ }
+
+#define NN(index) (&arch_info_struct[index])
+
+/* These exist only so that we can reasonably 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 0000000..0636105
--- /dev/null
+++ b/bfd/cpu-arc.c
@@ -0,0 +1,71 @@
+/* BFD support for the ARC processor
+ Copyright (C) 1994-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.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, \
+ bfd_arch_default_fill, \
+ next, \
+ }
+
+static const bfd_arch_info_type arch_info_struct[] =
+{
+ ARC ( bfd_mach_arc_5, "arc5", FALSE, &arch_info_struct[1] ),
+ ARC ( bfd_mach_arc_5, "base", FALSE, &arch_info_struct[2] ),
+ ARC ( bfd_mach_arc_6, "arc6", FALSE, &arch_info_struct[3] ),
+ ARC ( bfd_mach_arc_7, "arc7", FALSE, &arch_info_struct[4] ),
+ ARC ( bfd_mach_arc_8, "arc8", FALSE, NULL ),
+};
+
+const bfd_arch_info_type bfd_arc_arch =
+ ARC ( bfd_mach_arc_6, "arc", TRUE, &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 (char *);
+
+int
+arc_get_mach (char *name)
+{
+ const bfd_arch_info_type *p;
+
+ for (p = &bfd_arc_arch; p != NULL; p = p->next)
+ if (strcmp (name, p->printable_name) == 0)
+ return p->mach;
+ return -1;
+}
diff --git a/bfd/cpu-arm.c b/bfd/cpu-arm.c
new file mode 100644
index 0000000..149c2e5
--- /dev/null
+++ b/bfd/cpu-arm.c
@@ -0,0 +1,433 @@
+/* BFD support for the ARM processor
+ Copyright (C) 1994-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+#include "libiberty.h"
+
+/* 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 (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
+{
+ unsigned int mach;
+ 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_4T, "arm7tdmi" },
+ { bfd_mach_arm_4, "arm8" },
+ { bfd_mach_arm_4, "arm810" },
+ { bfd_mach_arm_4, "arm9" },
+ { bfd_mach_arm_4, "arm920" },
+ { bfd_mach_arm_4T, "arm920t" },
+ { bfd_mach_arm_4T, "arm9tdmi" },
+ { bfd_mach_arm_4, "sa1" },
+ { bfd_mach_arm_4, "strongarm"},
+ { bfd_mach_arm_4, "strongarm110" },
+ { bfd_mach_arm_4, "strongarm1100" },
+ { bfd_mach_arm_XScale, "xscale" },
+ { bfd_mach_arm_ep9312, "ep9312" },
+ { bfd_mach_arm_iWMMXt, "iwmmxt" },
+ { bfd_mach_arm_iWMMXt2, "iwmmxt2" }
+};
+
+static bfd_boolean
+scan (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->mach == processors [i].mach)
+ 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, bfd_arch_default_fill, 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, & arch_info_struct[6]),
+ N (bfd_mach_arm_5, "armv5", FALSE, & arch_info_struct[7]),
+ N (bfd_mach_arm_5T, "armv5t", FALSE, & arch_info_struct[8]),
+ N (bfd_mach_arm_5TE, "armv5te", FALSE, & arch_info_struct[9]),
+ N (bfd_mach_arm_XScale, "xscale", FALSE, & arch_info_struct[10]),
+ N (bfd_mach_arm_ep9312, "ep9312", FALSE, & arch_info_struct[11]),
+ N (bfd_mach_arm_iWMMXt, "iwmmxt", FALSE, & arch_info_struct[12]),
+ N (bfd_mach_arm_iWMMXt2, "iwmmxt2", FALSE, NULL)
+};
+
+const bfd_arch_info_type bfd_arm_arch =
+ N (0, "arm", TRUE, & arch_info_struct[0]);
+
+/* Support functions used by both the COFF and ELF versions of the ARM port. */
+
+/* Handle the merging of the 'machine' settings of input file IBFD
+ and an output file OBFD. These values actually represent the
+ different possible ARM architecture variants.
+ Returns TRUE if they were merged successfully or FALSE otherwise. */
+
+bfd_boolean
+bfd_arm_merge_machines (bfd *ibfd, bfd *obfd)
+{
+ unsigned int in = bfd_get_mach (ibfd);
+ unsigned int out = bfd_get_mach (obfd);
+
+ /* If the output architecture is unknown, we now have a value to set. */
+ if (out == bfd_mach_arm_unknown)
+ bfd_set_arch_mach (obfd, bfd_arch_arm, in);
+
+ /* If the input architecture is unknown,
+ then so must be the output architecture. */
+ else if (in == bfd_mach_arm_unknown)
+ /* FIXME: We ought to have some way to
+ override this on the command line. */
+ bfd_set_arch_mach (obfd, bfd_arch_arm, bfd_mach_arm_unknown);
+
+ /* If they are the same then nothing needs to be done. */
+ else if (out == in)
+ ;
+
+ /* Otherwise the general principle that a earlier architecture can be
+ linked with a later architecture to produce a binary that will execute
+ on the later architecture.
+
+ We fail however if we attempt to link a Cirrus EP9312 binary with an
+ Intel XScale binary, since these architecture have co-processors which
+ will not both be present on the same physical hardware. */
+ else if (in == bfd_mach_arm_ep9312
+ && (out == bfd_mach_arm_XScale
+ || out == bfd_mach_arm_iWMMXt
+ || out == bfd_mach_arm_iWMMXt2))
+ {
+ _bfd_error_handler (_("\
+error: %B is compiled for the EP9312, whereas %B is compiled for XScale"),
+ ibfd, obfd);
+ bfd_set_error (bfd_error_wrong_format);
+ return FALSE;
+ }
+ else if (out == bfd_mach_arm_ep9312
+ && (in == bfd_mach_arm_XScale
+ || in == bfd_mach_arm_iWMMXt
+ || in == bfd_mach_arm_iWMMXt2))
+ {
+ _bfd_error_handler (_("\
+error: %B is compiled for the EP9312, whereas %B is compiled for XScale"),
+ obfd, ibfd);
+ bfd_set_error (bfd_error_wrong_format);
+ return FALSE;
+ }
+ else if (in > out)
+ bfd_set_arch_mach (obfd, bfd_arch_arm, in);
+ /* else
+ Nothing to do. */
+
+ return TRUE;
+}
+
+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. */
+} arm_Note;
+
+static bfd_boolean
+arm_check_note (bfd *abfd,
+ bfd_byte *buffer,
+ bfd_size_type buffer_size,
+ const char *expected_name,
+ char **description_return)
+{
+ unsigned long namesz;
+ unsigned long descsz;
+ unsigned long type;
+ char * descr;
+
+ if (buffer_size < offsetof (arm_Note, name))
+ return FALSE;
+
+ /* We have to extract the values this way to allow for a
+ host whose endian-ness is different from the target. */
+ namesz = bfd_get_32 (abfd, buffer);
+ descsz = bfd_get_32 (abfd, buffer + offsetof (arm_Note, descsz));
+ type = bfd_get_32 (abfd, buffer + offsetof (arm_Note, type));
+ descr = (char *) buffer + offsetof (arm_Note, name);
+
+ /* Check for buffer overflow. */
+ if (namesz + descsz + offsetof (arm_Note, name) > buffer_size)
+ return FALSE;
+
+ if (expected_name == NULL)
+ {
+ if (namesz != 0)
+ return FALSE;
+ }
+ else
+ {
+ if (namesz != ((strlen (expected_name) + 1 + 3) & ~3))
+ return FALSE;
+
+ if (strcmp (descr, expected_name) != 0)
+ return FALSE;
+
+ descr += (namesz + 3) & ~3;
+ }
+
+ /* FIXME: We should probably check the type as well. */
+ (void) type;
+
+ if (description_return != NULL)
+ * description_return = descr;
+
+ return TRUE;
+}
+
+#define NOTE_ARCH_STRING "arch: "
+
+bfd_boolean
+bfd_arm_update_notes (bfd *abfd, const char *note_section)
+{
+ asection * arm_arch_section;
+ bfd_size_type buffer_size;
+ bfd_byte * buffer;
+ char * arch_string;
+ char * expected;
+
+ /* Look for a note section. If one is present check the architecture
+ string encoded in it, and set it to the current architecture if it is
+ different. */
+ arm_arch_section = bfd_get_section_by_name (abfd, note_section);
+
+ if (arm_arch_section == NULL)
+ return TRUE;
+
+ buffer_size = arm_arch_section->size;
+ if (buffer_size == 0)
+ return FALSE;
+
+ if (!bfd_malloc_and_get_section (abfd, arm_arch_section, &buffer))
+ goto FAIL;
+
+ /* Parse the note. */
+ if (! arm_check_note (abfd, buffer, buffer_size, NOTE_ARCH_STRING, & arch_string))
+ goto FAIL;
+
+ /* Check the architecture in the note against the architecture of the bfd. */
+ switch (bfd_get_mach (abfd))
+ {
+ default:
+ case bfd_mach_arm_unknown: expected = "unknown"; break;
+ case bfd_mach_arm_2: expected = "armv2"; break;
+ case bfd_mach_arm_2a: expected = "armv2a"; break;
+ case bfd_mach_arm_3: expected = "armv3"; break;
+ case bfd_mach_arm_3M: expected = "armv3M"; break;
+ case bfd_mach_arm_4: expected = "armv4"; break;
+ case bfd_mach_arm_4T: expected = "armv4t"; break;
+ case bfd_mach_arm_5: expected = "armv5"; break;
+ case bfd_mach_arm_5T: expected = "armv5t"; break;
+ case bfd_mach_arm_5TE: expected = "armv5te"; break;
+ case bfd_mach_arm_XScale: expected = "XScale"; break;
+ case bfd_mach_arm_ep9312: expected = "ep9312"; break;
+ case bfd_mach_arm_iWMMXt: expected = "iWMMXt"; break;
+ case bfd_mach_arm_iWMMXt2: expected = "iWMMXt2"; break;
+ }
+
+ if (strcmp (arch_string, expected) != 0)
+ {
+ strcpy ((char *) buffer + (offsetof (arm_Note, name)
+ + ((strlen (NOTE_ARCH_STRING) + 3) & ~3)),
+ expected);
+
+ if (! bfd_set_section_contents (abfd, arm_arch_section, buffer,
+ (file_ptr) 0, buffer_size))
+ {
+ (*_bfd_error_handler)
+ (_("warning: unable to update contents of %s section in %s"),
+ note_section, bfd_get_filename (abfd));
+ goto FAIL;
+ }
+ }
+
+ free (buffer);
+ return TRUE;
+
+ FAIL:
+ if (buffer != NULL)
+ free (buffer);
+ return FALSE;
+}
+
+
+static struct
+{
+ const char * string;
+ unsigned int mach;
+}
+architectures[] =
+{
+ { "armv2", bfd_mach_arm_2 },
+ { "armv2a", bfd_mach_arm_2a },
+ { "armv3", bfd_mach_arm_3 },
+ { "armv3M", bfd_mach_arm_3M },
+ { "armv4", bfd_mach_arm_4 },
+ { "armv4t", bfd_mach_arm_4T },
+ { "armv5", bfd_mach_arm_5 },
+ { "armv5t", bfd_mach_arm_5T },
+ { "armv5te", bfd_mach_arm_5TE },
+ { "XScale", bfd_mach_arm_XScale },
+ { "ep9312", bfd_mach_arm_ep9312 },
+ { "iWMMXt", bfd_mach_arm_iWMMXt },
+ { "iWMMXt2", bfd_mach_arm_iWMMXt2 }
+};
+
+/* Extract the machine number stored in a note section. */
+unsigned int
+bfd_arm_get_mach_from_notes (bfd *abfd, const char *note_section)
+{
+ asection * arm_arch_section;
+ bfd_size_type buffer_size;
+ bfd_byte * buffer;
+ char * arch_string;
+ int i;
+
+ /* Look for a note section. If one is present check the architecture
+ string encoded in it, and set it to the current architecture if it is
+ different. */
+ arm_arch_section = bfd_get_section_by_name (abfd, note_section);
+
+ if (arm_arch_section == NULL)
+ return bfd_mach_arm_unknown;
+
+ buffer_size = arm_arch_section->size;
+ if (buffer_size == 0)
+ return bfd_mach_arm_unknown;
+
+ if (!bfd_malloc_and_get_section (abfd, arm_arch_section, &buffer))
+ goto FAIL;
+
+ /* Parse the note. */
+ if (! arm_check_note (abfd, buffer, buffer_size, NOTE_ARCH_STRING, & arch_string))
+ goto FAIL;
+
+ /* Interpret the architecture string. */
+ for (i = ARRAY_SIZE (architectures); i--;)
+ if (strcmp (arch_string, architectures[i].string) == 0)
+ {
+ free (buffer);
+ return architectures[i].mach;
+ }
+
+ FAIL:
+ if (buffer != NULL)
+ free (buffer);
+ return bfd_mach_arm_unknown;
+}
+
+bfd_boolean
+bfd_is_arm_special_symbol_name (const char * name, int type)
+{
+ /* The ARM compiler outputs several obsolete forms. Recognize them
+ in addition to the standard $a, $t and $d. We are somewhat loose
+ in what we accept here, since the full set is not documented. */
+ if (!name || name[0] != '$')
+ return FALSE;
+ if (name[1] == 'a' || name[1] == 't' || name[1] == 'd')
+ type &= BFD_ARM_SPECIAL_SYM_TYPE_MAP;
+ else if (name[1] == 'm' || name[1] == 'f' || name[1] == 'p')
+ type &= BFD_ARM_SPECIAL_SYM_TYPE_TAG;
+ else if (name[1] >= 'a' && name[1] <= 'z')
+ type &= BFD_ARM_SPECIAL_SYM_TYPE_OTHER;
+ else
+ return FALSE;
+
+ return (type != 0 && (name[2] == 0 || name[2] == '.'));
+}
+
diff --git a/bfd/cpu-avr.c b/bfd/cpu-avr.c
new file mode 100644
index 0000000..d3da25a
--- /dev/null
+++ b/bfd/cpu-avr.c
@@ -0,0 +1,163 @@
+/* BFD library support routines for the AVR architecture.
+ Copyright (C) 1999-2014 Free Software Foundation, Inc.
+ Contributed by Denis Chertykov <denisc@overta.ru>
+
+ This file is part of BFD, the Binary File Descriptor library.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+
+/* This routine is provided two arch_infos and works out which AVR
+ machine which would be compatible with both and returns a pointer
+ to its info structure. */
+
+static const bfd_arch_info_type *
+compatible (const bfd_arch_info_type * a,
+ const bfd_arch_info_type * b)
+{
+ /* If a & b are for different architectures we can do nothing. */
+ if (a->arch != b->arch)
+ return NULL;
+
+ if (a->mach == b->mach)
+ return a;
+
+ /* avr-6 is compatible only with itself as its call convention is not
+ compatible with other avr (the mcu saves the return address on 3 bytes
+ instead of 2). */
+ if (a->mach == bfd_mach_avr6 || b->mach == bfd_mach_avr6)
+ return NULL;
+
+ if (a->mach < bfd_mach_avr6 && b->mach < bfd_mach_avr6)
+ {
+ /* Special case for ATmega[16]03 (avr:3) and ATmega83 (avr:4). */
+ if ((a->mach == bfd_mach_avr3 && b->mach == bfd_mach_avr4)
+ || (a->mach == bfd_mach_avr4 && b->mach == bfd_mach_avr3))
+ return NULL;
+
+ if (a->mach <= b->mach)
+ return b;
+
+ if (a->mach >= b->mach)
+ return a;
+ }
+
+ if (a->mach == bfd_mach_avr2 && b->mach == bfd_mach_avr25)
+ return a;
+ if (a->mach == bfd_mach_avr25 && b->mach == bfd_mach_avr2)
+ return b;
+
+ if (a->mach == bfd_mach_avr3 && b->mach == bfd_mach_avr31)
+ return a;
+ if (a->mach == bfd_mach_avr31 && b->mach == bfd_mach_avr3)
+ return b;
+ if (a->mach == bfd_mach_avr3 && b->mach == bfd_mach_avr35)
+ return a;
+ if (a->mach == bfd_mach_avr35 && b->mach == bfd_mach_avr3)
+ return b;
+
+ if (a->mach == bfd_mach_avr5 && b->mach == bfd_mach_avr51)
+ return a;
+ if (a->mach == bfd_mach_avr51 && b->mach == bfd_mach_avr5)
+ return b;
+
+ return NULL;
+}
+
+#define N(addr_bits, machine, print, default, next) \
+{ \
+ 8, /* 8 bits in a word. */ \
+ addr_bits, /* bits in an address. */ \
+ 8, /* 8 bits in a byte. */ \
+ bfd_arch_avr, \
+ machine, /* Machine number. */ \
+ "avr", /* Architecture name. */ \
+ print, /* Printable name. */ \
+ 1, /* Section align power. */ \
+ default, /* Is this the default ? */ \
+ compatible, \
+ bfd_default_scan, \
+ bfd_arch_default_fill, \
+ next \
+}
+
+static const bfd_arch_info_type arch_info_struct[] =
+{
+ /* Assembler only. */
+ N (16, bfd_mach_avr1, "avr:1", FALSE, & arch_info_struct[1]),
+
+ /* Classic, <= 8K. */
+ N (16, bfd_mach_avr2, "avr:2", FALSE, & arch_info_struct[2]),
+
+ /* Classic + MOVW, <= 8K. */
+ N (16, bfd_mach_avr25, "avr:25", FALSE, & arch_info_struct[3]),
+
+ /* Classic, > 8K, <= 64K. */
+ /* TODO: addr_bits should be 16, but set to 22 for some following
+ version of GCC (from 4.3) for backward compatibility. */
+ N (22, bfd_mach_avr3, "avr:3", FALSE, & arch_info_struct[4]),
+
+ /* Classic, == 128K. */
+ N (22, bfd_mach_avr31, "avr:31", FALSE, & arch_info_struct[5]),
+
+ /* Classic + MOVW + JMP/CALL, > 8K, <= 64K. */
+ N (16, bfd_mach_avr35, "avr:35", FALSE, & arch_info_struct[6]),
+
+ /* Enhanced, <= 8K. */
+ N (16, bfd_mach_avr4, "avr:4", FALSE, & arch_info_struct[7]),
+
+ /* Enhanced, > 8K, <= 64K. */
+ /* TODO: addr_bits should be 16, but set to 22 for some following
+ version of GCC (from 4.3) for backward compatibility. */
+ N (22, bfd_mach_avr5, "avr:5", FALSE, & arch_info_struct[8]),
+
+ /* Enhanced, == 128K. */
+ N (22, bfd_mach_avr51, "avr:51", FALSE, & arch_info_struct[9]),
+
+ /* 3-Byte PC. */
+ N (22, bfd_mach_avr6, "avr:6", FALSE, & arch_info_struct[10]),
+
+ /* Tiny core (AVR Tiny). */
+ N (16, bfd_mach_avrtiny, "avr:100", FALSE, & arch_info_struct[11]),
+
+ /* Xmega 1. */
+ N (24, bfd_mach_avrxmega1, "avr:101", FALSE, & arch_info_struct[12]),
+
+ /* Xmega 2. */
+ N (24, bfd_mach_avrxmega2, "avr:102", FALSE, & arch_info_struct[13]),
+
+ /* Xmega 3. */
+ N (24, bfd_mach_avrxmega3, "avr:103", FALSE, & arch_info_struct[14]),
+
+ /* Xmega 4. */
+ N (24, bfd_mach_avrxmega4, "avr:104", FALSE, & arch_info_struct[15]),
+
+ /* Xmega 5. */
+ N (24, bfd_mach_avrxmega5, "avr:105", FALSE, & arch_info_struct[16]),
+
+ /* Xmega 6. */
+ N (24, bfd_mach_avrxmega6, "avr:106", FALSE, & arch_info_struct[17]),
+
+ /* Xmega 7. */
+ N (24, bfd_mach_avrxmega7, "avr:107", FALSE, NULL)
+
+};
+
+const bfd_arch_info_type bfd_avr_arch =
+ N (16, bfd_mach_avr2, "avr", TRUE, & arch_info_struct[0]);
diff --git a/bfd/cpu-bfin.c b/bfd/cpu-bfin.c
new file mode 100644
index 0000000..433904d
--- /dev/null
+++ b/bfd/cpu-bfin.c
@@ -0,0 +1,41 @@
+/* BFD Support for the ADI Blackfin processor.
+
+ Copyright (C) 2005-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+
+const bfd_arch_info_type bfd_bfin_arch =
+ {
+ 16, /* Bits in a word. */
+ 32, /* Bits in an address. */
+ 8, /* Bits in a byte. */
+ bfd_arch_bfin,
+ 0, /* Only one machine. */
+ "bfin", /* Arch name. */
+ "bfin", /* Arch printable name. */
+ 4, /* Section align power. */
+ TRUE, /* The one and only. */
+ bfd_default_compatible,
+ bfd_default_scan,
+ bfd_arch_default_fill,
+ 0,
+ };
diff --git a/bfd/cpu-cr16.c b/bfd/cpu-cr16.c
new file mode 100644
index 0000000..2b1af76
--- /dev/null
+++ b/bfd/cpu-cr16.c
@@ -0,0 +1,41 @@
+/* BFD support for the CR16 processor.
+ Copyright (C) 2007-2014 Free Software Foundation, Inc.
+ Written by M R Swami Reddy
+
+ This file is part of BFD, the Binary File Descriptor library.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+
+
+const bfd_arch_info_type bfd_cr16_arch =
+ {
+ 16, /* 16 bits in a word. */
+ 32, /* 32 bits in an address. */
+ 8, /* 8 bits in a byte. */
+ bfd_arch_cr16, /* enum bfd_architecture arch. */
+ bfd_mach_cr16,
+ "cr16", /* Arch name. */
+ "cr16", /* Printable name. */
+ 1, /* Unsigned int section alignment power. */
+ TRUE, /* The one and only. */
+ bfd_default_compatible,
+ bfd_default_scan,
+ bfd_arch_default_fill,
+ 0,
+ };
diff --git a/bfd/cpu-cr16c.c b/bfd/cpu-cr16c.c
new file mode 100644
index 0000000..00d9b9c
--- /dev/null
+++ b/bfd/cpu-cr16c.c
@@ -0,0 +1,40 @@
+/* BFD support for the CR16C processor.
+ Copyright (C) 2004-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+
+const bfd_arch_info_type bfd_cr16c_arch =
+ {
+ 16, /* 16 bits in a word. */
+ 32, /* 32 bits in an address. */
+ 8, /* 8 bits in a byte. */
+ bfd_arch_cr16c,
+ bfd_mach_cr16c,
+ "cr16c",
+ "cr16c",
+ 1,
+ TRUE, /* The one and only. */
+ bfd_default_compatible,
+ bfd_default_scan,
+ bfd_arch_default_fill,
+ 0,
+ };
diff --git a/bfd/cpu-cris.c b/bfd/cpu-cris.c
new file mode 100644
index 0000000..0a35d9b
--- /dev/null
+++ b/bfd/cpu-cris.c
@@ -0,0 +1,109 @@
+/* BFD support for the Axis CRIS architecture.
+ Copyright (C) 2000-2014 Free Software Foundation, Inc.
+ Contributed by Axis Communications AB.
+ Written by Hans-Peter Nilsson.
+
+ This file is part of BFD, the Binary File Descriptor library.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+
+/* This routine is provided two arch_infos and returns the lowest common
+ denominator. CRIS v0..v10 vs. v32 are not compatible in general, but
+ there's a compatible subset for which we provide an arch_info. */
+
+static const bfd_arch_info_type * get_compatible
+ (const bfd_arch_info_type *, const bfd_arch_info_type *);
+
+static const bfd_arch_info_type *
+get_compatible (const bfd_arch_info_type *a,
+ const bfd_arch_info_type *b)
+{
+ /* Arches must match. */
+ if (a->arch != b->arch)
+ return NULL;
+
+ /* If either is the compatible mach, return the other. */
+ if (a->mach == bfd_mach_cris_v10_v32)
+ return b;
+ if (b->mach == bfd_mach_cris_v10_v32)
+ return a;
+
+#if 0
+ /* The code below is disabled but kept as a warning.
+ See ldlang.c:lang_check. Quite illogically, incompatible arches
+ (as signalled by this function) are only *warned* about, while with
+ this function signalling compatible ones, we can have the
+ cris_elf_merge_private_bfd_data function return an error. This is
+ undoubtedly a FIXME: in general. Also, the
+ command_line.warn_mismatch flag and the --no-warn-mismatch option
+ are misnamed for the multitude of ports that signal compatibility:
+ it is there an error, not a warning. We work around it by
+ pretending matching machs here. */
+
+ /* Except for the compatible mach, machs must match. */
+ if (a->mach != b->mach)
+ return NULL;
+#endif
+
+ return a;
+}
+
+#define N(NUMBER, PRINT, NEXT) \
+ { 32, 32, 8, bfd_arch_cris, NUMBER, "cris", PRINT, 1, FALSE, \
+ get_compatible, bfd_default_scan, bfd_arch_default_fill, NEXT }
+
+static const bfd_arch_info_type bfd_cris_arch_compat_v10_v32 =
+ N (bfd_mach_cris_v10_v32, "cris:common_v10_v32", NULL);
+
+static const bfd_arch_info_type bfd_cris_arch_v32 =
+ N (bfd_mach_cris_v32, "crisv32", &bfd_cris_arch_compat_v10_v32);
+
+const bfd_arch_info_type bfd_cris_arch =
+{
+ 32, /* There's 32 bits_per_word. */
+ 32, /* There's 32 bits_per_address. */
+ 8, /* There's 8 bits_per_byte. */
+ bfd_arch_cris, /* One of enum bfd_architecture, defined
+ in archures.c and provided in
+ generated header files. */
+ bfd_mach_cris_v0_v10, /* Random BFD-internal number for this
+ machine, similarly listed in
+ archures.c. Not emitted in output. */
+ "cris", /* The arch_name. */
+ "cris", /* The printable name is the same. */
+ 1, /* Section alignment power; each section
+ is aligned to (only) 2^1 bytes. */
+ TRUE, /* This is the default "machine". */
+ get_compatible, /* A function for testing
+ "machine" compatibility of two
+ bfd_arch_info_type. */
+ bfd_default_scan, /* Check if a bfd_arch_info_type is a
+ match. */
+ bfd_arch_default_fill, /* Default fill. */
+ &bfd_cris_arch_v32 /* Pointer to next bfd_arch_info_type in
+ the same family. */
+};
+
+/*
+ * Local variables:
+ * eval: (c-set-style "gnu")
+ * indent-tabs-mode: t
+ * End:
+ */
diff --git a/bfd/cpu-crx.c b/bfd/cpu-crx.c
new file mode 100644
index 0000000..f393cb7
--- /dev/null
+++ b/bfd/cpu-crx.c
@@ -0,0 +1,41 @@
+/* BFD support for the CRX processor.
+ Copyright (C) 2004-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+
+
+const bfd_arch_info_type bfd_crx_arch =
+ {
+ 16, /* 16 bits in a word. */
+ 32, /* 32 bits in an address. */
+ 8, /* 8 bits in a byte. */
+ bfd_arch_crx, /* enum bfd_architecture arch. */
+ bfd_mach_crx,
+ "crx", /* Arch name. */
+ "crx", /* Printable name. */
+ 1, /* Unsigned int section alignment power. */
+ TRUE, /* The one and only. */
+ bfd_default_compatible,
+ bfd_default_scan,
+ bfd_arch_default_fill,
+ 0,
+ };
diff --git a/bfd/cpu-d10v.c b/bfd/cpu-d10v.c
new file mode 100644
index 0000000..367b999
--- /dev/null
+++ b/bfd/cpu-d10v.c
@@ -0,0 +1,75 @@
+/* BFD support for the D10V processor
+ Copyright (C) 1996-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+
+static const bfd_arch_info_type d10v_ts3_info =
+{
+ 16, /* 16 bits in a word. */
+ 18, /* really 16 bits in an address, but code has 18 bit range. */
+ 8, /* 8 bits in a byte. */
+ bfd_arch_d10v,
+ bfd_mach_d10v_ts3,
+ "d10v",
+ "d10v:ts3",
+ 4, /* Section alignment power. */
+ FALSE,
+ bfd_default_compatible,
+ bfd_default_scan,
+ bfd_arch_default_fill,
+ 0,
+};
+
+static const bfd_arch_info_type d10v_ts2_info =
+{
+ 16,
+ 18,
+ 8,
+ bfd_arch_d10v,
+ bfd_mach_d10v_ts2,
+ "d10v",
+ "d10v:ts2",
+ 4,
+ FALSE,
+ bfd_default_compatible,
+ bfd_default_scan,
+ bfd_arch_default_fill,
+ & d10v_ts3_info,
+};
+
+const bfd_arch_info_type bfd_d10v_arch =
+{
+ 16,
+ 18,
+ 8,
+ bfd_arch_d10v,
+ bfd_mach_d10v,
+ "d10v",
+ "d10v",
+ 4,
+ TRUE,
+ bfd_default_compatible,
+ bfd_default_scan,
+ bfd_arch_default_fill,
+ & d10v_ts2_info,
+};
diff --git a/bfd/cpu-d30v.c b/bfd/cpu-d30v.c
new file mode 100644
index 0000000..11eae81
--- /dev/null
+++ b/bfd/cpu-d30v.c
@@ -0,0 +1,41 @@
+/* BFD support for the Mitsubishi D30V processor
+ Copyright (C) 1997-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.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,
+ bfd_arch_default_fill,
+ 0,
+};
diff --git a/bfd/cpu-dlx.c b/bfd/cpu-dlx.c
new file mode 100644
index 0000000..00e1336
--- /dev/null
+++ b/bfd/cpu-dlx.c
@@ -0,0 +1,41 @@
+/* BFD support for the DLX Microprocessor architecture.
+ Copyright (C) 2002-2014 Free Software Foundation, Inc.
+ Hacked by Kuang Hwa Lin <kuang@sbcglobal.net>
+
+ This file is part of BFD, the Binary File Descriptor library.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+
+const bfd_arch_info_type bfd_dlx_arch =
+ {
+ 32, /* 32 bits in a word. */
+ 32, /* 32 bits in an address. */
+ 8, /* 8 bits in a byte. */
+ bfd_arch_dlx,
+ 0, /* Only 1 machine. */
+ "dlx",
+ "dlx",
+ 4,
+ TRUE, /* The one and only. */
+ bfd_default_compatible,
+ bfd_default_scan,
+ bfd_arch_default_fill,
+ 0,
+};
diff --git a/bfd/cpu-epiphany.c b/bfd/cpu-epiphany.c
new file mode 100644
index 0000000..26ffc03
--- /dev/null
+++ b/bfd/cpu-epiphany.c
@@ -0,0 +1,58 @@
+/* BFD support for the Adapteva EPIPHANY processor.
+ Copyright (C) 2009-2014 Free Software Foundation, Inc.
+ Contributed by Embecosm on behalf of Adapteva, 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+
+const bfd_arch_info_type bfd_epiphany16_arch =
+{
+ 32, /* Bits per word */
+ 32, /* Bits per address. */
+ 8, /* Bits per byte. */
+ bfd_arch_epiphany, /* Architecture. */
+ bfd_mach_epiphany16, /* Machine. */
+ "epiphany", /* Architecture name. */
+ "epiphany16", /* Machine name. */
+ 1, /* Section align power. */
+ FALSE, /* The default ? */
+ bfd_default_compatible, /* Architecture comparison fn. */
+ bfd_default_scan, /* String to architecture convert fn. */
+ bfd_arch_default_fill, /* Default fill. */
+ NULL /* Next in list. */
+};
+
+const bfd_arch_info_type bfd_epiphany_arch =
+{
+ 32, /* Bits per word - not really true. */
+ 32, /* Bits per address. */
+ 8, /* Bits per byte. */
+ bfd_arch_epiphany, /* Architecture. */
+ bfd_mach_epiphany32, /* Machine. */
+ "epiphany", /* Architecture name. */
+ "epiphany32", /* Machine name. */
+ 2, /* Section align power. */
+ TRUE, /* The default ? */
+ bfd_default_compatible, /* Architecture comparison fn. */
+ bfd_default_scan, /* String to architecture convert fn. */
+ bfd_arch_default_fill, /* Default fill. */
+ & bfd_epiphany16_arch /* Next in list. */
+};
diff --git a/bfd/cpu-fr30.c b/bfd/cpu-fr30.c
new file mode 100644
index 0000000..9af19a5
--- /dev/null
+++ b/bfd/cpu-fr30.c
@@ -0,0 +1,40 @@
+/* BFD support for the FR30 processor.
+ Copyright (C) 1998-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.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 */
+ bfd_arch_default_fill, /* Default fill. */
+ NULL /* next in list */
+};
diff --git a/bfd/cpu-frv.c b/bfd/cpu-frv.c
new file mode 100644
index 0000000..fe611d7
--- /dev/null
+++ b/bfd/cpu-frv.c
@@ -0,0 +1,65 @@
+/* BFD support for the FRV processor.
+ Copyright (C) 2002-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+
+#define FRV_ARCH(MACHINE, NAME, DEFAULT, NEXT) \
+{ \
+ 32, /* 32 bits in a word */ \
+ 32, /* 32 bits in an address */ \
+ 8, /* 8 bits in a byte */ \
+ bfd_arch_frv, /* architecture */ \
+ MACHINE, /* which machine */ \
+ "frv", /* architecture name */ \
+ NAME, /* machine name */ \
+ 4, /* default alignment */ \
+ DEFAULT, /* is this the default? */ \
+ bfd_default_compatible, /* architecture comparison fn */ \
+ bfd_default_scan, /* string to architecture convert fn */ \
+ bfd_arch_default_fill, /* Default fill. */ \
+ NEXT /* next in list */ \
+}
+
+static const bfd_arch_info_type arch_info_300
+ = FRV_ARCH (bfd_mach_fr300, "fr300", FALSE, (bfd_arch_info_type *)0);
+
+static const bfd_arch_info_type arch_info_400
+ = FRV_ARCH (bfd_mach_fr400, "fr400", FALSE, &arch_info_300);
+
+static const bfd_arch_info_type arch_info_450
+ = FRV_ARCH (bfd_mach_fr450, "fr450", FALSE, &arch_info_400);
+
+static const bfd_arch_info_type arch_info_500
+ = FRV_ARCH (bfd_mach_fr500, "fr500", FALSE, &arch_info_450);
+
+static const bfd_arch_info_type arch_info_550
+ = FRV_ARCH (bfd_mach_fr550, "fr550", FALSE, &arch_info_500);
+
+static const bfd_arch_info_type arch_info_simple
+ = FRV_ARCH (bfd_mach_frvsimple, "simple", FALSE, &arch_info_550);
+
+static const bfd_arch_info_type arch_info_tomcat
+ = FRV_ARCH (bfd_mach_frvtomcat, "tomcat", FALSE, &arch_info_simple);
+
+const bfd_arch_info_type bfd_frv_arch
+ = FRV_ARCH (bfd_mach_frv, "frv", TRUE, &arch_info_tomcat);
+
diff --git a/bfd/cpu-h8300.c b/bfd/cpu-h8300.c
new file mode 100644
index 0000000..cd6e8ed
--- /dev/null
+++ b/bfd/cpu-h8300.c
@@ -0,0 +1,268 @@
+/* BFD library support routines for the Renesas H8/300 architecture.
+ Copyright (C) 1990-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+
+static bfd_boolean
+h8300_scan (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++;
+
+ /* In ELF linker scripts, we typically express the architecture/machine
+ as architecture:machine.
+
+ So if we've matched so far and encounter a colon, try to match the
+ string following the colon. */
+ if (*string == ':')
+ {
+ string++;
+ return h8300_scan (info, string);
+ }
+
+ if (*string == 'h' || *string == 'H')
+ {
+ string++;
+ if (*string == 'n' || *string == 'N')
+ return (info->mach == bfd_mach_h8300hn);
+
+ return (info->mach == bfd_mach_h8300h);
+ }
+ else if (*string == 's' || *string == 'S')
+ {
+ string++;
+ if (*string == 'n' || *string == 'N')
+ return (info->mach == bfd_mach_h8300sn);
+
+ if (*string == 'x' || *string == 'X')
+ {
+ string++;
+ if (*string == 'n' || *string == 'N')
+ return (info->mach == bfd_mach_h8300sxn);
+
+ return (info->mach == bfd_mach_h8300sx);
+ }
+
+ 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 (const bfd_arch_info_type *in, const bfd_arch_info_type *out)
+{
+ if (in->arch != out->arch)
+ return 0;
+ if (in->mach == bfd_mach_h8300sx && out->mach == bfd_mach_h8300s)
+ return in;
+ if (in->mach == bfd_mach_h8300s && out->mach == bfd_mach_h8300sx)
+ return out;
+ if (in->mach == bfd_mach_h8300sxn && out->mach == bfd_mach_h8300sn)
+ return in;
+ if (in->mach == bfd_mach_h8300sn && out->mach == bfd_mach_h8300sxn)
+ return 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 h8300sxn_info_struct =
+{
+ 32, /* 32 bits in a word */
+ 16, /* 16 bits in an address */
+ 8, /* 8 bits in a byte */
+ bfd_arch_h8300,
+ bfd_mach_h8300sxn,
+ "h8300sxn", /* arch_name */
+ "h8300sxn", /* printable name */
+ 1,
+ FALSE, /* the default machine */
+ compatible,
+ h8300_scan,
+ bfd_arch_default_fill,
+ 0
+};
+
+static const bfd_arch_info_type h8300sx_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_h8300sx,
+ "h8300sx", /* arch_name */
+ "h8300sx", /* printable name */
+ 1,
+ FALSE, /* the default machine */
+ compatible,
+ h8300_scan,
+ bfd_arch_default_fill,
+ &h8300sxn_info_struct
+};
+
+static const bfd_arch_info_type h8300sn_info_struct =
+{
+ 32, /* 32 bits in a word. */
+ 16, /* 16 bits in an address. */
+ 8, /* 8 bits in a byte. */
+ bfd_arch_h8300,
+ bfd_mach_h8300sn,
+ "h8300sn", /* Architecture name. */
+ "h8300sn", /* Printable name. */
+ 1,
+ FALSE, /* The default machine. */
+ compatible,
+ h8300_scan,
+ bfd_arch_default_fill,
+ &h8300sx_info_struct
+};
+
+static const bfd_arch_info_type h8300hn_info_struct =
+{
+ 32, /* 32 bits in a word. */
+ 16, /* 16 bits in an address. */
+ 8, /* 8 bits in a byte. */
+ bfd_arch_h8300,
+ bfd_mach_h8300hn,
+ "h8300hn", /* Architecture name. */
+ "h8300hn", /* Printable name. */
+ 1,
+ FALSE, /* The default machine. */
+ compatible,
+ h8300_scan,
+ bfd_arch_default_fill,
+ &h8300sn_info_struct
+};
+
+static const bfd_arch_info_type h8300s_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_h8300s,
+ "h8300s", /* Architecture name. */
+ "h8300s", /* Printable name. */
+ 1,
+ FALSE, /* The default machine. */
+ compatible,
+ h8300_scan,
+ bfd_arch_default_fill,
+ & h8300hn_info_struct
+};
+
+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", /* Architecture name. */
+ "h8300h", /* Printable name. */
+ 1,
+ FALSE, /* The default machine. */
+ compatible,
+ h8300_scan,
+ bfd_arch_default_fill,
+ &h8300s_info_struct
+};
+
+const bfd_arch_info_type bfd_h8300_arch =
+{
+ 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", /* Architecture name. */
+ "h8300", /* Printable name. */
+ 1,
+ TRUE, /* The default machine. */
+ compatible,
+ h8300_scan,
+ bfd_arch_default_fill,
+ &h8300h_info_struct
+};
+
+/* Pad the given address to 32 bits, converting 16-bit and 24-bit
+ addresses into the values they would have had on a h8s target. */
+
+bfd_vma
+bfd_h8300_pad_address (bfd *abfd, bfd_vma address)
+{
+ /* Cope with bfd_vma's larger than 32 bits. */
+ address &= 0xffffffffu;
+
+ switch (bfd_get_mach (abfd))
+ {
+ case bfd_mach_h8300:
+ case bfd_mach_h8300hn:
+ case bfd_mach_h8300sn:
+ case bfd_mach_h8300sxn:
+ /* Sign extend a 16-bit address. */
+ if (address >= 0x8000)
+ return address | 0xffff0000u;
+ return address;
+
+ case bfd_mach_h8300h:
+ /* Sign extend a 24-bit address. */
+ if (address >= 0x800000)
+ return address | 0xff000000u;
+ return address;
+
+ case bfd_mach_h8300s:
+ case bfd_mach_h8300sx:
+ return address;
+
+ default:
+ abort ();
+ }
+}
diff --git a/bfd/cpu-h8500.c b/bfd/cpu-h8500.c
new file mode 100644
index 0000000..d01984a
--- /dev/null
+++ b/bfd/cpu-h8500.c
@@ -0,0 +1,59 @@
+/* BFD library support routines for the H8/500 architecture.
+ Copyright (C) 1993-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+
+static bfd_boolean scan_mach
+ (const struct bfd_arch_info *, const char *);
+
+static bfd_boolean
+scan_mach (const struct bfd_arch_info *info ATTRIBUTE_UNUSED,
+ 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;
+}
+
+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,
+ bfd_arch_default_fill,
+ 0,
+};
diff --git a/bfd/cpu-hppa.c b/bfd/cpu-hppa.c
new file mode 100644
index 0000000..8089a95
--- /dev/null
+++ b/bfd/cpu-hppa.c
@@ -0,0 +1,93 @@
+/* BFD support for the HP Precision Architecture architecture.
+ Copyright (C) 1992-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.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,
+ bfd_mach_hppa10, /* By convention PA1.0 = 10 */
+ "hppa",
+ "hppa1.0",
+ 3,
+ TRUE, /* Unless we use 1.1 specific features */
+ bfd_default_compatible,
+ bfd_default_scan,
+ bfd_arch_default_fill,
+ 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,
+ bfd_mach_hppa20, /* By convention PA2.0 = 20 */
+ "hppa",
+ "hppa2.0",
+ 3,
+ FALSE, /* Unless we use 1.1 specific features */
+ bfd_default_compatible,
+ bfd_default_scan,
+ bfd_arch_default_fill,
+ &bfd_hppa10_arch,
+};
+
+/* PA2.0 in wide mode */
+static const bfd_arch_info_type bfd_hppa20w_arch =
+{
+ 64, /* 64 bits in a word */
+ 64, /* 64 bits in an address */
+ 8, /* 8 bits in a byte */
+ bfd_arch_hppa,
+ bfd_mach_hppa20w, /* ??? How best to describe wide mode here? */
+ "hppa",
+ "hppa2.0w",
+ 3,
+ FALSE, /* Unless we use 1.1 specific features */
+ bfd_default_compatible,
+ bfd_default_scan,
+ bfd_arch_default_fill,
+ &bfd_hppa20_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,
+ bfd_mach_hppa11, /* By convention PA1.1 = 11 */
+ "hppa",
+ "hppa1.1",
+ 3,
+ FALSE, /* 1.1 specific features used */
+ bfd_default_compatible,
+ bfd_default_scan,
+ bfd_arch_default_fill,
+ &bfd_hppa20w_arch,
+};
diff --git a/bfd/cpu-i370.c b/bfd/cpu-i370.c
new file mode 100644
index 0000000..bb5bc2f
--- /dev/null
+++ b/bfd/cpu-i370.c
@@ -0,0 +1,77 @@
+/* BFD i370 CPU definition
+ Copyright (C) 1994-2014 Free Software Foundation, Inc.
+ Contributed by Ian Lance Taylor, Cygnus Support.
+ Hacked by Linas Vepstas <linas@linas.org> in 1998, 1999
+
+ This file is part of BFD, the Binary File Descriptor library.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+
+static const bfd_arch_info_type arch_info_struct[] =
+{
+ /* Hack alert: old old machines are really 16 and 24 bit arch ... */
+ {
+ 32, /* 32 bits in a word. */
+ 32, /* 32 bits in an address. */
+ 8, /* 8 bits in a byte. */
+ bfd_arch_i370,
+ 360, /* For the 360. */
+ "i370",
+ "i370:360",
+ 3,
+ FALSE, /* Not the default. */
+ bfd_default_compatible,
+ bfd_default_scan,
+ bfd_arch_default_fill,
+ &arch_info_struct[1]
+ },
+ {
+ 32, /* 32 bits in a word. */
+ 32, /* 32 bits in an address. */
+ 8, /* 8 bits in a byte. */
+ bfd_arch_i370,
+ 370, /* For the 370. */
+ "i370",
+ "i370:370",
+ 3,
+ FALSE, /* Not the default. */
+ bfd_default_compatible,
+ bfd_default_scan,
+ bfd_arch_default_fill,
+ 0
+ },
+};
+
+const bfd_arch_info_type bfd_i370_arch =
+{
+ 32, /* 32 bits in a word. */
+ 32, /* 32 bits in an address. */
+ 8, /* 8 bits in a byte. */
+ bfd_arch_i370,
+ 0, /* For the 360/370 common architecture. */
+ "i370",
+ "i370:common",
+ 3,
+ TRUE, /* The default. */
+ bfd_default_compatible,
+ bfd_default_scan,
+ bfd_arch_default_fill,
+ & arch_info_struct[0]
+};
diff --git a/bfd/cpu-i386.c b/bfd/cpu-i386.c
new file mode 100644
index 0000000..5e48852
--- /dev/null
+++ b/bfd/cpu-i386.c
@@ -0,0 +1,302 @@
+/* BFD support for the Intel 386 architecture.
+ Copyright (C) 1992-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+#include "libiberty.h"
+
+extern void * bfd_arch_i386_short_nop_fill (bfd_size_type, bfd_boolean,
+ bfd_boolean);
+
+static const bfd_arch_info_type *
+bfd_i386_compatible (const bfd_arch_info_type *a,
+ const bfd_arch_info_type *b)
+{
+ const bfd_arch_info_type *compat = bfd_default_compatible (a, b);
+
+ /* Don't allow mixing x64_32 with x86_64. */
+ if (compat
+ && (a->mach & bfd_mach_x64_32) != (b->mach & bfd_mach_x64_32))
+ compat = NULL;
+
+ return compat;
+}
+
+/* Fill the buffer with zero or nop instruction if CODE is TRUE. Use
+ multi byte nop instructions if LONG_NOP is TRUE. */
+
+static void *
+bfd_arch_i386_fill (bfd_size_type count, bfd_boolean code,
+ bfd_boolean long_nop)
+{
+ /* nop */
+ static const char nop_1[] = { 0x90 };
+ /* xchg %ax,%ax */
+ static const char nop_2[] = { 0x66, 0x90 };
+ /* nopl (%[re]ax) */
+ static const char nop_3[] = { 0x0f, 0x1f, 0x00 };
+ /* nopl 0(%[re]ax) */
+ static const char nop_4[] = { 0x0f, 0x1f, 0x40, 0x00 };
+ /* nopl 0(%[re]ax,%[re]ax,1) */
+ static const char nop_5[] = { 0x0f, 0x1f, 0x44, 0x00, 0x00 };
+ /* nopw 0(%[re]ax,%[re]ax,1) */
+ static const char nop_6[] = { 0x66, 0x0f, 0x1f, 0x44, 0x00, 0x00 };
+ /* nopl 0L(%[re]ax) */
+ static const char nop_7[] = { 0x0f, 0x1f, 0x80, 0x00, 0x00, 0x00, 0x00 };
+ /* nopl 0L(%[re]ax,%[re]ax,1) */
+ static const char nop_8[] =
+ { 0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00};
+ /* nopw 0L(%[re]ax,%[re]ax,1) */
+ static const char nop_9[] =
+ { 0x66, 0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00 };
+ /* nopw %cs:0L(%[re]ax,%[re]ax,1) */
+ static const char nop_10[] =
+ { 0x66, 0x2e, 0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00 };
+ static const char *const nops[] =
+ { nop_1, nop_2, nop_3, nop_4, nop_5,
+ nop_6, nop_7, nop_8, nop_9, nop_10 };
+ bfd_size_type nop_size = long_nop ? ARRAY_SIZE (nops) : 2;
+
+ void *fill = bfd_malloc (count);
+ if (fill == NULL)
+ return fill;
+
+ if (code)
+ {
+ bfd_byte *p = fill;
+ while (count >= nop_size)
+ {
+ memcpy (p, nops[nop_size - 1], nop_size);
+ p += nop_size;
+ count -= nop_size;
+ }
+ if (count != 0)
+ memcpy (p, nops[count - 1], count);
+ }
+ else
+ memset (fill, 0, count);
+
+ return fill;
+}
+
+/* Fill the buffer with zero or short nop instruction if CODE is TRUE. */
+
+void *
+bfd_arch_i386_short_nop_fill (bfd_size_type count,
+ bfd_boolean is_bigendian ATTRIBUTE_UNUSED,
+ bfd_boolean code)
+{
+ return bfd_arch_i386_fill (count, code, FALSE);
+}
+
+/* Fill the buffer with zero or long nop instruction if CODE is TRUE. */
+
+static void *
+bfd_arch_i386_long_nop_fill (bfd_size_type count,
+ bfd_boolean is_bigendian ATTRIBUTE_UNUSED,
+ bfd_boolean code)
+{
+ return bfd_arch_i386_fill (count, code, TRUE);
+}
+
+/* Fill the buffer with zero, or one-byte nop instructions if CODE is TRUE. */
+
+static void *
+bfd_arch_i386_onebyte_nop_fill (bfd_size_type count,
+ bfd_boolean is_bigendian ATTRIBUTE_UNUSED,
+ bfd_boolean code)
+{
+ void *fill = bfd_malloc (count);
+ if (fill != NULL)
+ memset (fill, code ? 0x90 : 0, count);
+ return fill;
+}
+
+
+static const bfd_arch_info_type bfd_x64_32_nacl_arch =
+{
+ 64, /* 64 bits in a word */
+ 64, /* 64 bits in an address */
+ 8, /* 8 bits in a byte */
+ bfd_arch_i386,
+ bfd_mach_x64_32_nacl,
+ "i386",
+ "i386:x64-32:nacl",
+ 3,
+ FALSE,
+ bfd_i386_compatible,
+ bfd_default_scan,
+ bfd_arch_i386_onebyte_nop_fill,
+ NULL
+};
+
+static const bfd_arch_info_type bfd_x86_64_nacl_arch =
+{
+ 64, /* 64 bits in a word */
+ 64, /* 64 bits in an address */
+ 8, /* 8 bits in a byte */
+ bfd_arch_i386,
+ bfd_mach_x86_64_nacl,
+ "i386",
+ "i386:x86-64:nacl",
+ 3,
+ FALSE,
+ bfd_i386_compatible,
+ bfd_default_scan,
+ bfd_arch_i386_onebyte_nop_fill,
+ &bfd_x64_32_nacl_arch
+};
+
+const bfd_arch_info_type bfd_i386_nacl_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_nacl,
+ "i386",
+ "i386:nacl",
+ 3,
+ TRUE,
+ bfd_i386_compatible,
+ bfd_default_scan,
+ bfd_arch_i386_onebyte_nop_fill,
+ &bfd_x86_64_nacl_arch
+};
+
+static const bfd_arch_info_type bfd_x64_32_arch_intel_syntax =
+{
+ 64, /* 64 bits in a word */
+ 64, /* 64 bits in an address */
+ 8, /* 8 bits in a byte */
+ bfd_arch_i386,
+ bfd_mach_x64_32_intel_syntax,
+ "i386:intel",
+ "i386:x64-32:intel",
+ 3,
+ FALSE,
+ bfd_i386_compatible,
+ bfd_default_scan,
+ bfd_arch_i386_long_nop_fill,
+ &bfd_i386_nacl_arch
+};
+
+static const bfd_arch_info_type bfd_x86_64_arch_intel_syntax =
+{
+ 64, /* 64 bits in a word */
+ 64, /* 64 bits in an address */
+ 8, /* 8 bits in a byte */
+ bfd_arch_i386,
+ bfd_mach_x86_64_intel_syntax,
+ "i386:intel",
+ "i386:x86-64:intel",
+ 3,
+ FALSE,
+ bfd_i386_compatible,
+ bfd_default_scan,
+ bfd_arch_i386_long_nop_fill,
+ &bfd_x64_32_arch_intel_syntax,
+};
+
+static 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_i386_compatible,
+ bfd_default_scan,
+ bfd_arch_i386_short_nop_fill,
+ &bfd_x86_64_arch_intel_syntax
+};
+
+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_i386_compatible,
+ bfd_default_scan,
+ bfd_arch_i386_short_nop_fill,
+ &bfd_i386_arch_intel_syntax
+};
+
+static const bfd_arch_info_type bfd_x64_32_arch =
+{
+ 64, /* 64 bits in a word */
+ 64, /* 64 bits in an address */
+ 8, /* 8 bits in a byte */
+ bfd_arch_i386,
+ bfd_mach_x64_32,
+ "i386",
+ "i386:x64-32",
+ 3,
+ FALSE,
+ bfd_i386_compatible,
+ bfd_default_scan,
+ bfd_arch_i386_long_nop_fill,
+ &i8086_arch
+};
+
+static const bfd_arch_info_type bfd_x86_64_arch =
+{
+ 64, /* 64 bits in a word */
+ 64, /* 64 bits in an address */
+ 8, /* 8 bits in a byte */
+ bfd_arch_i386,
+ bfd_mach_x86_64,
+ "i386",
+ "i386:x86-64",
+ 3,
+ FALSE,
+ bfd_i386_compatible,
+ bfd_default_scan,
+ bfd_arch_i386_long_nop_fill,
+ &bfd_x64_32_arch
+};
+
+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_i386_compatible,
+ bfd_default_scan,
+ bfd_arch_i386_short_nop_fill,
+ &bfd_x86_64_arch
+};
diff --git a/bfd/cpu-i860.c b/bfd/cpu-i860.c
new file mode 100644
index 0000000..71452ba
--- /dev/null
+++ b/bfd/cpu-i860.c
@@ -0,0 +1,42 @@
+/* BFD support for the Intel 860 architecture.
+ Copyright (C) 1992-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.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, /* Architecture */
+ 0, /* Only one machine */
+ "i860", /* Architecture name */
+ "i860", /* Printable name */
+ 3, /* Section alignment exponent */
+ TRUE, /* Is this the default architecture? */
+ bfd_default_compatible,
+ bfd_default_scan,
+ bfd_arch_default_fill,
+ 0, /* Next in list */
+ };
diff --git a/bfd/cpu-i960.c b/bfd/cpu-i960.c
new file mode 100644
index 0000000..bdcae8c
--- /dev/null
+++ b/bfd/cpu-i960.c
@@ -0,0 +1,172 @@
+/* BFD library support routines for the i960 architecture.
+ Copyright (C) 1990-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.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 bfd_boolean
+scan_960_mach (const bfd_arch_info_type *ap,
+ const char *string)
+{
+ unsigned long machine;
+ int fail_because_not_80960 = FALSE;
+
+ /* Look for the string i960 at the front of the string. */
+ if (strncasecmp ("i960", string, 4) == 0)
+ {
+ string += 4;
+
+ /* i960 on it's own means core to us. */
+ if (* string == 0)
+ return ap->mach == bfd_mach_i960_core;
+
+ /* "i960:*" is valid, anything else is not. */
+ if (* string != ':')
+ return FALSE;
+
+ string ++;
+ }
+ /* In some bfds the cpu-id is written as "80960KA", "80960KB",
+ "80960CA" or "80960MC". */
+ else if (CONST_STRNEQ (string, "80960"))
+ {
+ string += 5;
+
+ /* Set this to TRUE here. If a correct matching postfix
+ is detected below it will be reset to FALSE. */
+ fail_because_not_80960 = TRUE;
+ }
+ /* No match, can't be us. */
+ else
+ return FALSE;
+
+ if (* string == '\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 (strcasecmp (string, "ka_sa") == 0)
+ machine = bfd_mach_i960_ka_sa;
+ else if (strcasecmp (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; fail_because_not_80960 = FALSE; }
+ 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; fail_because_not_80960 = FALSE; }
+ 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; fail_because_not_80960 = FALSE; }
+ else if (string[0] == 'k' && string[1] == 'a')
+ { machine = bfd_mach_i960_ka_sa; fail_because_not_80960 = FALSE; }
+ 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 (fail_because_not_80960)
+ 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 (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;
+
+ return (a->mach == matrix[a->mach][b->mach]) ? a : b;
+}
+
+#define N(a,b,d,n) \
+{ 32, 32, 8,bfd_arch_i960,a,"i960",b,3,d,compatible,scan_960_mach, \
+ bfd_arch_default_fill, 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-ia64-opc.c b/bfd/cpu-ia64-opc.c
new file mode 100644
index 0000000..dd023fd
--- /dev/null
+++ b/bfd/cpu-ia64-opc.c
@@ -0,0 +1,669 @@
+/* Copyright (C) 1998-2014 Free Software Foundation, Inc.
+ Contributed by David Mosberger-Tang <davidm@hpl.hp.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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+/* Logically, this code should be part of libopcode but since some of
+ the operand insertion/extraction functions help bfd to implement
+ relocations, this code is included as part of cpu-ia64.c. This
+ avoids circular dependencies between libopcode and libbfd and also
+ obviates the need for applications to link in libopcode when all
+ they really want is libbfd.
+
+ --davidm Mon Apr 13 22:14:02 1998 */
+
+#include "../opcodes/ia64-opc.h"
+
+#define NELEMS(a) ((int) (sizeof (a) / sizeof ((a)[0])))
+
+static const char*
+ins_rsvd (const struct ia64_operand *self ATTRIBUTE_UNUSED,
+ ia64_insn value ATTRIBUTE_UNUSED, ia64_insn *code ATTRIBUTE_UNUSED)
+{
+ return "internal error---this shouldn't happen";
+}
+
+static const char*
+ext_rsvd (const struct ia64_operand *self ATTRIBUTE_UNUSED,
+ ia64_insn code ATTRIBUTE_UNUSED, ia64_insn *valuep ATTRIBUTE_UNUSED)
+{
+ return "internal error---this shouldn't happen";
+}
+
+static const char*
+ins_const (const struct ia64_operand *self ATTRIBUTE_UNUSED,
+ ia64_insn value ATTRIBUTE_UNUSED, ia64_insn *code ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+static const char*
+ext_const (const struct ia64_operand *self ATTRIBUTE_UNUSED,
+ ia64_insn code ATTRIBUTE_UNUSED, ia64_insn *valuep ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+static const char*
+ins_reg (const struct ia64_operand *self, ia64_insn value, ia64_insn *code)
+{
+ if (value >= 1u << self->field[0].bits)
+ return "register number out of range";
+
+ *code |= value << self->field[0].shift;
+ return 0;
+}
+
+static const char*
+ext_reg (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep)
+{
+ *valuep = ((code >> self->field[0].shift)
+ & ((1u << self->field[0].bits) - 1));
+ return 0;
+}
+
+static const char*
+ins_immu (const struct ia64_operand *self, ia64_insn value, ia64_insn *code)
+{
+ ia64_insn new_insn = 0;
+ int i;
+
+ for (i = 0; i < NELEMS (self->field) && self->field[i].bits; ++i)
+ {
+ new_insn |= ((value & ((((ia64_insn) 1) << self->field[i].bits) - 1))
+ << self->field[i].shift);
+ value >>= self->field[i].bits;
+ }
+ if (value)
+ return "integer operand out of range";
+
+ *code |= new_insn;
+ return 0;
+}
+
+static const char*
+ext_immu (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep)
+{
+ BFD_HOST_U_64_BIT value = 0;
+ int i, bits = 0, total = 0;
+
+ for (i = 0; i < NELEMS (self->field) && self->field[i].bits; ++i)
+ {
+ bits = self->field[i].bits;
+ value |= ((code >> self->field[i].shift)
+ & ((((BFD_HOST_U_64_BIT) 1) << bits) - 1)) << total;
+ total += bits;
+ }
+ *valuep = value;
+ return 0;
+}
+
+static const char*
+ins_immu5b (const struct ia64_operand *self, ia64_insn value,
+ ia64_insn *code)
+{
+ if (value < 32 || value > 63)
+ return "value must be between 32 and 63";
+ return ins_immu (self, value - 32, code);
+}
+
+static const char*
+ext_immu5b (const struct ia64_operand *self, ia64_insn code,
+ ia64_insn *valuep)
+{
+ const char *result;
+
+ result = ext_immu (self, code, valuep);
+ if (result)
+ return result;
+
+ *valuep = *valuep + 32;
+ return 0;
+}
+
+static const char*
+ins_immus8 (const struct ia64_operand *self, ia64_insn value, ia64_insn *code)
+{
+ if (value & 0x7)
+ return "value not an integer multiple of 8";
+ return ins_immu (self, value >> 3, code);
+}
+
+static const char*
+ext_immus8 (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep)
+{
+ const char *result;
+
+ result = ext_immu (self, code, valuep);
+ if (result)
+ return result;
+
+ *valuep = *valuep << 3;
+ return 0;
+}
+
+static const char*
+ins_imms_scaled (const struct ia64_operand *self, ia64_insn value,
+ ia64_insn *code, int scale)
+{
+ BFD_HOST_64_BIT svalue = value, sign_bit = 0;
+ ia64_insn new_insn = 0;
+ int i;
+
+ svalue >>= scale;
+
+ for (i = 0; i < NELEMS (self->field) && self->field[i].bits; ++i)
+ {
+ new_insn |= ((svalue & ((((ia64_insn) 1) << self->field[i].bits) - 1))
+ << self->field[i].shift);
+ sign_bit = (svalue >> (self->field[i].bits - 1)) & 1;
+ svalue >>= self->field[i].bits;
+ }
+ if ((!sign_bit && svalue != 0) || (sign_bit && svalue != -1))
+ return "integer operand out of range";
+
+ *code |= new_insn;
+ return 0;
+}
+
+static const char*
+ext_imms_scaled (const struct ia64_operand *self, ia64_insn code,
+ ia64_insn *valuep, int scale)
+{
+ int i, bits = 0, total = 0;
+ BFD_HOST_64_BIT val = 0, sign;
+
+ for (i = 0; i < NELEMS (self->field) && self->field[i].bits; ++i)
+ {
+ bits = self->field[i].bits;
+ val |= ((code >> self->field[i].shift)
+ & ((((BFD_HOST_U_64_BIT) 1) << bits) - 1)) << total;
+ total += bits;
+ }
+ /* sign extend: */
+ sign = (BFD_HOST_64_BIT) 1 << (total - 1);
+ val = (val ^ sign) - sign;
+
+ *valuep = (val << scale);
+ return 0;
+}
+
+static const char*
+ins_imms (const struct ia64_operand *self, ia64_insn value, ia64_insn *code)
+{
+ return ins_imms_scaled (self, value, code, 0);
+}
+
+static const char*
+ins_immsu4 (const struct ia64_operand *self, ia64_insn value, ia64_insn *code)
+{
+ value = ((value & 0xffffffff) ^ 0x80000000) - 0x80000000;
+
+ return ins_imms_scaled (self, value, code, 0);
+}
+
+static const char*
+ext_imms (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep)
+{
+ return ext_imms_scaled (self, code, valuep, 0);
+}
+
+static const char*
+ins_immsm1 (const struct ia64_operand *self, ia64_insn value, ia64_insn *code)
+{
+ --value;
+ return ins_imms_scaled (self, value, code, 0);
+}
+
+static const char*
+ins_immsm1u4 (const struct ia64_operand *self, ia64_insn value,
+ ia64_insn *code)
+{
+ value = ((value & 0xffffffff) ^ 0x80000000) - 0x80000000;
+
+ --value;
+ return ins_imms_scaled (self, value, code, 0);
+}
+
+static const char*
+ext_immsm1 (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep)
+{
+ const char *res = ext_imms_scaled (self, code, valuep, 0);
+
+ ++*valuep;
+ return res;
+}
+
+static const char*
+ins_imms1 (const struct ia64_operand *self, ia64_insn value, ia64_insn *code)
+{
+ return ins_imms_scaled (self, value, code, 1);
+}
+
+static const char*
+ext_imms1 (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep)
+{
+ return ext_imms_scaled (self, code, valuep, 1);
+}
+
+static const char*
+ins_imms4 (const struct ia64_operand *self, ia64_insn value, ia64_insn *code)
+{
+ return ins_imms_scaled (self, value, code, 4);
+}
+
+static const char*
+ext_imms4 (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep)
+{
+ return ext_imms_scaled (self, code, valuep, 4);
+}
+
+static const char*
+ins_imms16 (const struct ia64_operand *self, ia64_insn value, ia64_insn *code)
+{
+ return ins_imms_scaled (self, value, code, 16);
+}
+
+static const char*
+ext_imms16 (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep)
+{
+ return ext_imms_scaled (self, code, valuep, 16);
+}
+
+static const char*
+ins_cimmu (const struct ia64_operand *self, ia64_insn value, ia64_insn *code)
+{
+ ia64_insn mask = (((ia64_insn) 1) << self->field[0].bits) - 1;
+ return ins_immu (self, value ^ mask, code);
+}
+
+static const char*
+ext_cimmu (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep)
+{
+ const char *result;
+ ia64_insn mask;
+
+ mask = (((ia64_insn) 1) << self->field[0].bits) - 1;
+ result = ext_immu (self, code, valuep);
+ if (!result)
+ {
+ mask = (((ia64_insn) 1) << self->field[0].bits) - 1;
+ *valuep ^= mask;
+ }
+ return result;
+}
+
+static const char*
+ins_cnt (const struct ia64_operand *self, ia64_insn value, ia64_insn *code)
+{
+ --value;
+ if (value >= ((BFD_HOST_U_64_BIT) 1) << self->field[0].bits)
+ return "count out of range";
+
+ *code |= value << self->field[0].shift;
+ return 0;
+}
+
+static const char*
+ext_cnt (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep)
+{
+ *valuep = ((code >> self->field[0].shift)
+ & ((((BFD_HOST_U_64_BIT) 1) << self->field[0].bits) - 1)) + 1;
+ return 0;
+}
+
+static const char*
+ins_cnt2b (const struct ia64_operand *self, ia64_insn value, ia64_insn *code)
+{
+ --value;
+
+ if (value > 2)
+ return "count must be in range 1..3";
+
+ *code |= value << self->field[0].shift;
+ return 0;
+}
+
+static const char*
+ext_cnt2b (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep)
+{
+ *valuep = ((code >> self->field[0].shift) & 0x3) + 1;
+ return 0;
+}
+
+static const char*
+ins_cnt2c (const struct ia64_operand *self, ia64_insn value, ia64_insn *code)
+{
+ switch (value)
+ {
+ case 0: value = 0; break;
+ case 7: value = 1; break;
+ case 15: value = 2; break;
+ case 16: value = 3; break;
+ default: return "count must be 0, 7, 15, or 16";
+ }
+ *code |= value << self->field[0].shift;
+ return 0;
+}
+
+static const char*
+ext_cnt2c (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep)
+{
+ ia64_insn value;
+
+ value = (code >> self->field[0].shift) & 0x3;
+ switch (value)
+ {
+ case 0: value = 0; break;
+ case 1: value = 7; break;
+ case 2: value = 15; break;
+ case 3: value = 16; break;
+ }
+ *valuep = value;
+ return 0;
+}
+
+static const char*
+ins_cnt6a (const struct ia64_operand *self, ia64_insn value,
+ ia64_insn *code)
+{
+ if (value < 1 || value > 64)
+ return "value must be between 1 and 64";
+ return ins_immu (self, value - 1, code);
+}
+
+static const char*
+ext_cnt6a (const struct ia64_operand *self, ia64_insn code,
+ ia64_insn *valuep)
+{
+ const char *result;
+
+ result = ext_immu (self, code, valuep);
+ if (result)
+ return result;
+
+ *valuep = *valuep + 1;
+ return 0;
+}
+
+static const char*
+ins_strd5b (const struct ia64_operand *self, ia64_insn value,
+ ia64_insn *code)
+{
+ if ( value & 0x3f )
+ return "value must be a multiple of 64";
+ return ins_imms_scaled (self, value, code, 6);
+}
+
+static const char*
+ext_strd5b (const struct ia64_operand *self, ia64_insn code,
+ ia64_insn *valuep)
+{
+ return ext_imms_scaled (self, code, valuep, 6);
+}
+
+
+static const char*
+ins_inc3 (const struct ia64_operand *self, ia64_insn value, ia64_insn *code)
+{
+ BFD_HOST_64_BIT val = value;
+ BFD_HOST_U_64_BIT sign = 0;
+
+ if (val < 0)
+ {
+ sign = 0x4;
+ value = -value;
+ }
+ switch (value)
+ {
+ case 1: value = 3; break;
+ case 4: value = 2; break;
+ case 8: value = 1; break;
+ case 16: value = 0; break;
+ default: return "count must be +/- 1, 4, 8, or 16";
+ }
+ *code |= (sign | value) << self->field[0].shift;
+ return 0;
+}
+
+static const char*
+ext_inc3 (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep)
+{
+ BFD_HOST_64_BIT val;
+ int negate;
+
+ val = (code >> self->field[0].shift) & 0x7;
+ negate = val & 0x4;
+ switch (val & 0x3)
+ {
+ case 0: val = 16; break;
+ case 1: val = 8; break;
+ case 2: val = 4; break;
+ case 3: val = 1; break;
+ }
+ if (negate)
+ val = -val;
+
+ *valuep = val;
+ return 0;
+}
+
+#define CST IA64_OPND_CLASS_CST
+#define REG IA64_OPND_CLASS_REG
+#define IND IA64_OPND_CLASS_IND
+#define ABS IA64_OPND_CLASS_ABS
+#define REL IA64_OPND_CLASS_REL
+
+#define SDEC IA64_OPND_FLAG_DECIMAL_SIGNED
+#define UDEC IA64_OPND_FLAG_DECIMAL_UNSIGNED
+
+const struct ia64_operand elf64_ia64_operands[IA64_OPND_COUNT] =
+ {
+ /* constants: */
+ { CST, ins_const, ext_const, "NIL", {{ 0, 0}}, 0, "<none>" },
+ { CST, ins_const, ext_const, "ar.csd", {{ 0, 0}}, 0, "ar.csd" },
+ { CST, ins_const, ext_const, "ar.ccv", {{ 0, 0}}, 0, "ar.ccv" },
+ { CST, ins_const, ext_const, "ar.pfs", {{ 0, 0}}, 0, "ar.pfs" },
+ { CST, ins_const, ext_const, "1", {{ 0, 0}}, 0, "1" },
+ { CST, ins_const, ext_const, "8", {{ 0, 0}}, 0, "8" },
+ { CST, ins_const, ext_const, "16", {{ 0, 0}}, 0, "16" },
+ { CST, ins_const, ext_const, "r0", {{ 0, 0}}, 0, "r0" },
+ { CST, ins_const, ext_const, "ip", {{ 0, 0}}, 0, "ip" },
+ { CST, ins_const, ext_const, "pr", {{ 0, 0}}, 0, "pr" },
+ { CST, ins_const, ext_const, "pr.rot", {{ 0, 0}}, 0, "pr.rot" },
+ { CST, ins_const, ext_const, "psr", {{ 0, 0}}, 0, "psr" },
+ { CST, ins_const, ext_const, "psr.l", {{ 0, 0}}, 0, "psr.l" },
+ { CST, ins_const, ext_const, "psr.um", {{ 0, 0}}, 0, "psr.um" },
+
+ /* register operands: */
+ { REG, ins_reg, ext_reg, "ar", {{ 7, 20}}, 0, /* AR3 */
+ "an application register" },
+ { REG, ins_reg, ext_reg, "b", {{ 3, 6}}, 0, /* B1 */
+ "a branch register" },
+ { REG, ins_reg, ext_reg, "b", {{ 3, 13}}, 0, /* B2 */
+ "a branch register"},
+ { REG, ins_reg, ext_reg, "cr", {{ 7, 20}}, 0, /* CR */
+ "a control register"},
+ { REG, ins_reg, ext_reg, "f", {{ 7, 6}}, 0, /* F1 */
+ "a floating-point register" },
+ { REG, ins_reg, ext_reg, "f", {{ 7, 13}}, 0, /* F2 */
+ "a floating-point register" },
+ { REG, ins_reg, ext_reg, "f", {{ 7, 20}}, 0, /* F3 */
+ "a floating-point register" },
+ { REG, ins_reg, ext_reg, "f", {{ 7, 27}}, 0, /* F4 */
+ "a floating-point register" },
+ { REG, ins_reg, ext_reg, "p", {{ 6, 6}}, 0, /* P1 */
+ "a predicate register" },
+ { REG, ins_reg, ext_reg, "p", {{ 6, 27}}, 0, /* P2 */
+ "a predicate register" },
+ { REG, ins_reg, ext_reg, "r", {{ 7, 6}}, 0, /* R1 */
+ "a general register" },
+ { REG, ins_reg, ext_reg, "r", {{ 7, 13}}, 0, /* R2 */
+ "a general register" },
+ { REG, ins_reg, ext_reg, "r", {{ 7, 20}}, 0, /* R3 */
+ "a general register" },
+ { REG, ins_reg, ext_reg, "r", {{ 2, 20}}, 0, /* R3_2 */
+ "a general register r0-r3" },
+ { REG, ins_reg, ext_reg, "dahr", {{ 3, 23}}, 0, /* DAHR */
+ "a dahr register dahr0-7" },
+
+ /* memory operands: */
+ { IND, ins_reg, ext_reg, "", {{7, 20}}, 0, /* MR3 */
+ "a memory address" },
+
+ /* indirect operands: */
+ { IND, ins_reg, ext_reg, "cpuid", {{7, 20}}, 0, /* CPUID_R3 */
+ "a cpuid register" },
+ { IND, ins_reg, ext_reg, "dbr", {{7, 20}}, 0, /* DBR_R3 */
+ "a dbr register" },
+ { IND, ins_reg, ext_reg, "dtr", {{7, 20}}, 0, /* DTR_R3 */
+ "a dtr register" },
+ { IND, ins_reg, ext_reg, "itr", {{7, 20}}, 0, /* ITR_R3 */
+ "an itr register" },
+ { IND, ins_reg, ext_reg, "ibr", {{7, 20}}, 0, /* IBR_R3 */
+ "an ibr register" },
+ { IND, ins_reg, ext_reg, "msr", {{7, 20}}, 0, /* MSR_R3 */
+ "an msr register" },
+ { IND, ins_reg, ext_reg, "pkr", {{7, 20}}, 0, /* PKR_R3 */
+ "a pkr register" },
+ { IND, ins_reg, ext_reg, "pmc", {{7, 20}}, 0, /* PMC_R3 */
+ "a pmc register" },
+ { IND, ins_reg, ext_reg, "pmd", {{7, 20}}, 0, /* PMD_R3 */
+ "a pmd register" },
+ { IND, ins_reg, ext_reg, "dahr", {{7, 20}}, 0, /* DAHR_R3 */
+ "a dahr register" },
+ { IND, ins_reg, ext_reg, "rr", {{7, 20}}, 0, /* RR_R3 */
+ "an rr register" },
+
+ /* immediate operands: */
+ { ABS, ins_cimmu, ext_cimmu, 0, {{ 5, 20 }}, UDEC, /* CCNT5 */
+ "a 5-bit count (0-31)" },
+ { ABS, ins_cnt, ext_cnt, 0, {{ 2, 27 }}, UDEC, /* CNT2a */
+ "a 2-bit count (1-4)" },
+ { ABS, ins_cnt2b, ext_cnt2b, 0, {{ 2, 27 }}, UDEC, /* CNT2b */
+ "a 2-bit count (1-3)" },
+ { ABS, ins_cnt2c, ext_cnt2c, 0, {{ 2, 30 }}, UDEC, /* CNT2c */
+ "a count (0, 7, 15, or 16)" },
+ { ABS, ins_immu, ext_immu, 0, {{ 5, 14}}, UDEC, /* CNT5 */
+ "a 5-bit count (0-31)" },
+ { ABS, ins_immu, ext_immu, 0, {{ 6, 27}}, UDEC, /* CNT6 */
+ "a 6-bit count (0-63)" },
+ { ABS, ins_cimmu, ext_cimmu, 0, {{ 6, 20}}, UDEC, /* CPOS6a */
+ "a 6-bit bit pos (0-63)" },
+ { ABS, ins_cimmu, ext_cimmu, 0, {{ 6, 14}}, UDEC, /* CPOS6b */
+ "a 6-bit bit pos (0-63)" },
+ { ABS, ins_cimmu, ext_cimmu, 0, {{ 6, 31}}, UDEC, /* CPOS6c */
+ "a 6-bit bit pos (0-63)" },
+ { ABS, ins_imms, ext_imms, 0, {{ 1, 36}}, SDEC, /* IMM1 */
+ "a 1-bit integer (-1, 0)" },
+ { ABS, ins_immu, ext_immu, 0, {{ 2, 13}}, UDEC, /* IMMU2 */
+ "a 2-bit unsigned (0-3)" },
+ { ABS, ins_immu5b, ext_immu5b, 0, {{ 5, 14}}, UDEC, /* IMMU5b */
+ "a 5-bit unsigned (32 + (0-31))" },
+ { ABS, ins_immu, ext_immu, 0, {{ 7, 13}}, 0, /* IMMU7a */
+ "a 7-bit unsigned (0-127)" },
+ { ABS, ins_immu, ext_immu, 0, {{ 7, 20}}, 0, /* IMMU7b */
+ "a 7-bit unsigned (0-127)" },
+ { ABS, ins_immu, ext_immu, 0, {{ 7, 13}}, UDEC, /* SOF */
+ "a frame size (register count)" },
+ { ABS, ins_immu, ext_immu, 0, {{ 7, 20}}, UDEC, /* SOL */
+ "a local register count" },
+ { ABS, ins_immus8,ext_immus8,0, {{ 4, 27}}, UDEC, /* SOR */
+ "a rotating register count (integer multiple of 8)" },
+ { ABS, ins_imms, ext_imms, 0, /* IMM8 */
+ {{ 7, 13}, { 1, 36}}, SDEC,
+ "an 8-bit integer (-128-127)" },
+ { ABS, ins_immsu4, ext_imms, 0, /* IMM8U4 */
+ {{ 7, 13}, { 1, 36}}, SDEC,
+ "an 8-bit signed integer for 32-bit unsigned compare (-128-127)" },
+ { ABS, ins_immsm1, ext_immsm1, 0, /* IMM8M1 */
+ {{ 7, 13}, { 1, 36}}, SDEC,
+ "an 8-bit integer (-127-128)" },
+ { ABS, ins_immsm1u4, ext_immsm1, 0, /* IMM8M1U4 */
+ {{ 7, 13}, { 1, 36}}, SDEC,
+ "an 8-bit integer for 32-bit unsigned compare (-127-(-1),1-128,0x100000000)" },
+ { ABS, ins_immsm1, ext_immsm1, 0, /* IMM8M1U8 */
+ {{ 7, 13}, { 1, 36}}, SDEC,
+ "an 8-bit integer for 64-bit unsigned compare (-127-(-1),1-128,0x10000000000000000)" },
+ { ABS, ins_immu, ext_immu, 0, {{ 2, 33}, { 7, 20}}, 0, /* IMMU9 */
+ "a 9-bit unsigned (0-511)" },
+ { ABS, ins_imms, ext_imms, 0, /* IMM9a */
+ {{ 7, 6}, { 1, 27}, { 1, 36}}, SDEC,
+ "a 9-bit integer (-256-255)" },
+ { ABS, ins_imms, ext_imms, 0, /* IMM9b */
+ {{ 7, 13}, { 1, 27}, { 1, 36}}, SDEC,
+ "a 9-bit integer (-256-255)" },
+ { ABS, ins_imms, ext_imms, 0, /* IMM14 */
+ {{ 7, 13}, { 6, 27}, { 1, 36}}, SDEC,
+ "a 14-bit integer (-8192-8191)" },
+ { ABS, ins_immu, ext_immu, 0, /* IMMU16 */
+ {{4, 6}, {11, 12}, { 1, 36}}, UDEC,
+ "a 16-bit unsigned" },
+ { ABS, ins_imms1, ext_imms1, 0, /* IMM17 */
+ {{ 7, 6}, { 8, 24}, { 1, 36}}, 0,
+ "a 17-bit integer (-65536-65535)" },
+ { ABS, ins_immu, ext_immu, 0, /* IMMU19 */
+ {{4, 6}, {14, 12}, { 1, 36}}, UDEC,
+ "a 19-bit unsigned" },
+ { ABS, ins_immu, ext_immu, 0, {{20, 6}, { 1, 36}}, 0, /* IMMU21 */
+ "a 21-bit unsigned" },
+ { ABS, ins_imms, ext_imms, 0, /* IMM22 */
+ {{ 7, 13}, { 9, 27}, { 5, 22}, { 1, 36}}, SDEC,
+ "a 22-bit signed integer" },
+ { ABS, ins_immu, ext_immu, 0, /* IMMU24 */
+ {{21, 6}, { 2, 31}, { 1, 36}}, 0,
+ "a 24-bit unsigned" },
+ { ABS, ins_imms16,ext_imms16,0, {{27, 6}, { 1, 36}}, 0, /* IMM44 */
+ "a 44-bit unsigned (least 16 bits ignored/zeroes)" },
+ { ABS, ins_rsvd, ext_rsvd, 0, {{0, 0}}, 0, /* IMMU62 */
+ "a 62-bit unsigned" },
+ { ABS, ins_rsvd, ext_rsvd, 0, {{0, 0}}, 0, /* IMMU64 */
+ "a 64-bit unsigned" },
+ { ABS, ins_inc3, ext_inc3, 0, {{ 3, 13}}, SDEC, /* INC3 */
+ "an increment (+/- 1, 4, 8, or 16)" },
+ { ABS, ins_cnt, ext_cnt, 0, {{ 4, 27}}, UDEC, /* LEN4 */
+ "a 4-bit length (1-16)" },
+ { ABS, ins_cnt, ext_cnt, 0, {{ 6, 27}}, UDEC, /* LEN6 */
+ "a 6-bit length (1-64)" },
+ { ABS, ins_immu, ext_immu, 0, {{ 4, 20}}, 0, /* MBTYPE4 */
+ "a mix type (@rev, @mix, @shuf, @alt, or @brcst)" },
+ { ABS, ins_immu, ext_immu, 0, {{ 8, 20}}, 0, /* MBTYPE8 */
+ "an 8-bit mix type" },
+ { ABS, ins_immu, ext_immu, 0, {{ 6, 14}}, UDEC, /* POS6 */
+ "a 6-bit bit pos (0-63)" },
+ { REL, ins_imms4, ext_imms4, 0, {{ 7, 6}, { 2, 33}}, 0, /* TAG13 */
+ "a branch tag" },
+ { REL, ins_imms4, ext_imms4, 0, {{ 9, 24}}, 0, /* TAG13b */
+ "a branch tag" },
+ { REL, ins_imms4, ext_imms4, 0, {{20, 6}, { 1, 36}}, 0, /* TGT25 */
+ "a branch target" },
+ { REL, ins_imms4, ext_imms4, 0, /* TGT25b */
+ {{ 7, 6}, {13, 20}, { 1, 36}}, 0,
+ "a branch target" },
+ { REL, ins_imms4, ext_imms4, 0, {{20, 13}, { 1, 36}}, 0, /* TGT25c */
+ "a branch target" },
+ { REL, ins_rsvd, ext_rsvd, 0, {{0, 0}}, 0, /* TGT64 */
+ "a branch target" },
+
+ { ABS, ins_const, ext_const, 0, {{0, 0}}, 0, /* LDXMOV */
+ "ldxmov target" },
+ { ABS, ins_cnt6a, ext_cnt6a, 0, {{6, 6}}, UDEC, /* CNT6a */
+ "lfetch count" },
+ { ABS, ins_strd5b, ext_strd5b, 0, {{5, 13}}, SDEC, /* STRD5b*/
+ "lfetch stride" },
+ };
diff --git a/bfd/cpu-ia64.c b/bfd/cpu-ia64.c
new file mode 100644
index 0000000..6017e45
--- /dev/null
+++ b/bfd/cpu-ia64.c
@@ -0,0 +1,60 @@
+/* BFD support for the ia64 architecture.
+ Copyright (C) 1998-2014 Free Software Foundation, Inc.
+ Contributed by David Mosberger-Tang <davidm@hpl.hp.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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+
+const bfd_arch_info_type bfd_ia64_elf32_arch =
+ {
+ 64, /* 64 bits in a word */
+ 32, /* 32 bits in an address */
+ 8, /* 8 bits in a byte */
+ bfd_arch_ia64,
+ bfd_mach_ia64_elf32,
+ "ia64",
+ "ia64-elf32",
+ 3, /* log2 of section alignment */
+ TRUE, /* the one and only */
+ bfd_default_compatible,
+ bfd_default_scan,
+ bfd_arch_default_fill,
+ 0,
+ };
+
+const bfd_arch_info_type bfd_ia64_arch =
+ {
+ 64, /* 64 bits in a word */
+ 64, /* 64 bits in an address */
+ 8, /* 8 bits in a byte */
+ bfd_arch_ia64,
+ bfd_mach_ia64_elf64,
+ "ia64",
+ "ia64-elf64",
+ 3, /* log2 of section alignment */
+ TRUE, /* the one and only */
+ bfd_default_compatible,
+ bfd_default_scan,
+ bfd_arch_default_fill,
+ &bfd_ia64_elf32_arch,
+ };
+
+#include "cpu-ia64-opc.c"
diff --git a/bfd/cpu-ip2k.c b/bfd/cpu-ip2k.c
new file mode 100644
index 0000000..a9c12cb
--- /dev/null
+++ b/bfd/cpu-ip2k.c
@@ -0,0 +1,57 @@
+/* BFD support for the Scenix IP2xxx processor.
+ Copyright (C) 2000-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+
+const bfd_arch_info_type bfd_ip2k_nonext_arch =
+{
+ 32, /* Bits per word - not really true. */
+ 16, /* Bits per address. */
+ 8, /* Bits per byte. */
+ bfd_arch_ip2k, /* Architecture. */
+ bfd_mach_ip2022, /* Machine. */
+ "ip2k", /* Architecture name. */
+ "ip2022", /* Machine name. */
+ 1, /* Section align power. */
+ FALSE, /* The default ? */
+ bfd_default_compatible, /* Architecture comparison fn. */
+ bfd_default_scan, /* String to architecture convert fn. */
+ bfd_arch_default_fill, /* Default fill. */
+ NULL /* Next in list. */
+};
+
+const bfd_arch_info_type bfd_ip2k_arch =
+{
+ 32, /* Bits per word - not really true. */
+ 16, /* Bits per address. */
+ 8, /* Bits per byte. */
+ bfd_arch_ip2k, /* Architecture. */
+ bfd_mach_ip2022ext, /* Machine. */
+ "ip2k", /* Architecture name. */
+ "ip2022ext", /* Machine name. */
+ 1, /* Section align power. */
+ TRUE, /* The default ? */
+ bfd_default_compatible, /* Architecture comparison fn. */
+ bfd_default_scan, /* String to architecture convert fn. */
+ bfd_arch_default_fill, /* Default fill. */
+ & bfd_ip2k_nonext_arch /* Next in list. */
+};
diff --git a/bfd/cpu-iq2000.c b/bfd/cpu-iq2000.c
new file mode 100644
index 0000000..82524f4
--- /dev/null
+++ b/bfd/cpu-iq2000.c
@@ -0,0 +1,59 @@
+/* BFD support for the Vitesse IQ2000 processor.
+ Copyright (C) 2003-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+
+static const bfd_arch_info_type arch_info_struct[] =
+{
+ {
+ 32, /* bits per word */
+ 32, /* bits per address */
+ 8, /* bits per byte */
+ bfd_arch_iq2000, /* architecture */
+ bfd_mach_iq10, /* machine */
+ "iq2000", /* architecture name */
+ "iq10", /* printable name */
+ 3, /* section align power */
+ FALSE, /* the default ? */
+ bfd_default_compatible, /* architecture comparison fn */
+ bfd_default_scan, /* string to architecture convert fn */
+ bfd_arch_default_fill, /* Default fill. */
+ NULL /* next in list */
+ }
+};
+
+const bfd_arch_info_type bfd_iq2000_arch =
+{
+ 32, /* bits per word */
+ 32, /* bits per address */
+ 8, /* bits per byte */
+ bfd_arch_iq2000, /* architecture */
+ bfd_mach_iq2000, /* machine */
+ "iq2000", /* architecture name */
+ "iq2000", /* printable name */
+ 3, /* section align power */
+ TRUE, /* the default ? */
+ bfd_default_compatible, /* architecture comparison fn */
+ bfd_default_scan, /* string to architecture convert fn */
+ bfd_arch_default_fill, /* Default fill. */
+ &arch_info_struct[0], /* next in list */
+};
diff --git a/bfd/cpu-k1om.c b/bfd/cpu-k1om.c
new file mode 100644
index 0000000..c946d14
--- /dev/null
+++ b/bfd/cpu-k1om.c
@@ -0,0 +1,60 @@
+/* BFD support for the Intel K1OM architecture.
+ Copyright (C) 2011-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+
+extern void * bfd_arch_i386_short_nop_fill (bfd_size_type, bfd_boolean,
+ bfd_boolean);
+
+static const bfd_arch_info_type bfd_k1om_arch_intel_syntax =
+{
+ 64, /* 64 bits in a word */
+ 64, /* 64 bits in an address */
+ 8, /* 8 bits in a byte */
+ bfd_arch_k1om,
+ bfd_mach_k1om_intel_syntax,
+ "k1om:intel",
+ "k1om:intel",
+ 3,
+ TRUE,
+ bfd_default_compatible,
+ bfd_default_scan,
+ bfd_arch_i386_short_nop_fill,
+ 0
+};
+
+const bfd_arch_info_type bfd_k1om_arch =
+{
+ 64, /* 64 bits in a word */
+ 64, /* 64 bits in an address */
+ 8, /* 8 bits in a byte */
+ bfd_arch_k1om,
+ bfd_mach_k1om,
+ "k1om",
+ "k1om",
+ 3,
+ TRUE,
+ bfd_default_compatible,
+ bfd_default_scan,
+ bfd_arch_i386_short_nop_fill,
+ &bfd_k1om_arch_intel_syntax
+};
diff --git a/bfd/cpu-l1om.c b/bfd/cpu-l1om.c
new file mode 100644
index 0000000..3648959
--- /dev/null
+++ b/bfd/cpu-l1om.c
@@ -0,0 +1,60 @@
+/* BFD support for the Intel L1OM architecture.
+ Copyright (C) 2009-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+
+extern void * bfd_arch_i386_short_nop_fill (bfd_size_type, bfd_boolean,
+ bfd_boolean);
+
+static const bfd_arch_info_type bfd_l1om_arch_intel_syntax =
+{
+ 64, /* 64 bits in a word */
+ 64, /* 64 bits in an address */
+ 8, /* 8 bits in a byte */
+ bfd_arch_l1om,
+ bfd_mach_l1om_intel_syntax,
+ "l1om:intel",
+ "l1om:intel",
+ 3,
+ TRUE,
+ bfd_default_compatible,
+ bfd_default_scan,
+ bfd_arch_i386_short_nop_fill,
+ 0
+};
+
+const bfd_arch_info_type bfd_l1om_arch =
+{
+ 64, /* 64 bits in a word */
+ 64, /* 64 bits in an address */
+ 8, /* 8 bits in a byte */
+ bfd_arch_l1om,
+ bfd_mach_l1om,
+ "l1om",
+ "l1om",
+ 3,
+ TRUE,
+ bfd_default_compatible,
+ bfd_default_scan,
+ bfd_arch_i386_short_nop_fill,
+ &bfd_l1om_arch_intel_syntax
+};
diff --git a/bfd/cpu-lm32.c b/bfd/cpu-lm32.c
new file mode 100644
index 0000000..e935997
--- /dev/null
+++ b/bfd/cpu-lm32.c
@@ -0,0 +1,42 @@
+/* BFD support for the Lattice Mico32 architecture.
+ Copyright (C) 2008-2014 Free Software Foundation, Inc.
+ Contributed by Jon Beniston <jon@beniston.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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+
+const bfd_arch_info_type bfd_lm32_arch =
+{
+ 32, /* Bits in word. */
+ 32, /* Bits in address. */
+ 8, /* Bits in byte. */
+ bfd_arch_lm32, /* Enum bfd_architecture. */
+ bfd_mach_lm32, /* Machine number. */
+ "lm32", /* Architecture name. */
+ "lm32", /* Printable name. */
+ 4, /* Alignment. */
+ TRUE, /* Is this the default machine for the target. */
+ bfd_default_compatible, /* Function callback to test if two files have compatible machines. */
+ bfd_default_scan,
+ bfd_arch_default_fill,
+ NULL /* Next. */
+};
+
diff --git a/bfd/cpu-m10200.c b/bfd/cpu-m10200.c
new file mode 100644
index 0000000..003ff9c
--- /dev/null
+++ b/bfd/cpu-m10200.c
@@ -0,0 +1,40 @@
+/* BFD support for the Matsushita 10200 processor
+ Copyright (C) 1996-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.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,
+ bfd_arch_default_fill,
+ 0,
+ };
diff --git a/bfd/cpu-m10300.c b/bfd/cpu-m10300.c
new file mode 100644
index 0000000..c7f68da
--- /dev/null
+++ b/bfd/cpu-m10300.c
@@ -0,0 +1,74 @@
+/* BFD support for the Matsushita 10300 processor
+ Copyright (C) 1996-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+
+const bfd_arch_info_type bfd_am33_2_arch =
+ {
+ 32, /* 32 bits in a word */
+ 32, /* 32 bits in an address */
+ 8, /* 8 bits in a byte */
+ bfd_arch_mn10300,
+ 332,
+ "am33_2",
+ "am33-2",
+ 2,
+ FALSE,
+ bfd_default_compatible,
+ bfd_default_scan,
+ bfd_arch_default_fill,
+ 0,
+ };
+
+const bfd_arch_info_type bfd_am33_arch =
+ {
+ 32, /* 32 bits in a word */
+ 32, /* 32 bits in an address */
+ 8, /* 8 bits in a byte */
+ bfd_arch_mn10300,
+ 330,
+ "am33",
+ "am33",
+ 2,
+ FALSE,
+ bfd_default_compatible,
+ bfd_default_scan,
+ bfd_arch_default_fill,
+ &bfd_am33_2_arch,
+ };
+
+const bfd_arch_info_type bfd_mn10300_arch =
+ {
+ 32, /* 32 bits in a word */
+ 32, /* 32 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,
+ bfd_arch_default_fill,
+ &bfd_am33_arch,
+ };
diff --git a/bfd/cpu-m32c.c b/bfd/cpu-m32c.c
new file mode 100644
index 0000000..bb915df
--- /dev/null
+++ b/bfd/cpu-m32c.c
@@ -0,0 +1,72 @@
+/* BFD support for the M16C/M32C processors.
+ Copyright (C) 2004-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+
+/* Like bfd_default_scan but if the string is just "m32c" then
+ skip the m16c architecture. */
+
+static bfd_boolean
+m32c_scan (const bfd_arch_info_type * info, const char * string)
+{
+ if (strcmp (string, "m32c") == 0
+ && info->mach == bfd_mach_m16c)
+ return FALSE;
+
+ return bfd_default_scan (info, string);
+}
+
+static const bfd_arch_info_type arch_info_struct[] =
+{
+ {
+ 32, /* bits per word */
+ 32, /* bits per address */
+ 8, /* bits per byte */
+ bfd_arch_m32c, /* architecture */
+ bfd_mach_m32c, /* machine */
+ "m32c", /* architecture name */
+ "m32c", /* printable name */
+ 3, /* section align power */
+ FALSE, /* the default ? */
+ bfd_default_compatible, /* architecture comparison fn */
+ m32c_scan, /* string to architecture convert fn */
+ bfd_arch_default_fill, /* Default fill. */
+ NULL /* next in list */
+ },
+};
+
+const bfd_arch_info_type bfd_m32c_arch =
+{
+ 32, /* Bits per word. */
+ 32, /* Bits per address. */
+ 8, /* Bits per byte. */
+ bfd_arch_m32c, /* Architecture. */
+ bfd_mach_m16c, /* Machine. */
+ "m32c", /* Architecture name. */
+ "m16c", /* Printable name. */
+ 4, /* Section align power. */
+ TRUE, /* The default ? */
+ bfd_default_compatible, /* Architecture comparison fn. */
+ m32c_scan, /* String to architecture convert fn. */
+ bfd_arch_default_fill, /* Default fill. */
+ &arch_info_struct[0], /* Next in list. */
+};
diff --git a/bfd/cpu-m32r.c b/bfd/cpu-m32r.c
new file mode 100644
index 0000000..24a1034
--- /dev/null
+++ b/bfd/cpu-m32r.c
@@ -0,0 +1,39 @@
+/* BFD support for the M32R processor.
+ Copyright (C) 1996-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.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, bfd_arch_default_fill, next }
+
+#define M32R2_NEXT & arch_info_struct [1]
+#define NEXT & arch_info_struct [0]
+
+static const bfd_arch_info_type arch_info_struct[] =
+{
+ N (bfd_mach_m32rx, "m32rx", FALSE, M32R2_NEXT) ,
+ N (bfd_mach_m32r2, "m32r2", FALSE, NULL)
+};
+
+const bfd_arch_info_type bfd_m32r_arch =
+ N (bfd_mach_m32r, "m32r", TRUE, NEXT);
diff --git a/bfd/cpu-m68hc11.c b/bfd/cpu-m68hc11.c
new file mode 100644
index 0000000..68af7f2
--- /dev/null
+++ b/bfd/cpu-m68hc11.c
@@ -0,0 +1,40 @@
+/* BFD support for the Motorola 68HC11 processor
+ Copyright (C) 1999-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+
+const bfd_arch_info_type bfd_m68hc11_arch =
+{
+ 16, /* 16 bits in a word */
+ 16, /* 16 bits in an address */
+ 8, /* 8 bits in a byte */
+ bfd_arch_m68hc11,
+ 0,
+ "m68hc11",
+ "m68hc11",
+ 4, /* section alignment power */
+ TRUE,
+ bfd_default_compatible,
+ bfd_default_scan,
+ bfd_arch_default_fill,
+ 0,
+};
diff --git a/bfd/cpu-m68hc12.c b/bfd/cpu-m68hc12.c
new file mode 100644
index 0000000..4b6fe20
--- /dev/null
+++ b/bfd/cpu-m68hc12.c
@@ -0,0 +1,57 @@
+/* BFD support for the Motorola 68HC12 processor
+ Copyright (C) 1999-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+
+const bfd_arch_info_type bfd_m68hc12s_arch =
+{
+ 16, /* 16 bits in a word */
+ 32, /* 16 bits in an address */
+ 8, /* 8 bits in a byte */
+ bfd_arch_m68hc12,
+ bfd_mach_m6812s,
+ "m68hc12:HCS12",
+ "m68hc12",
+ 4, /* section alignment power */
+ TRUE,
+ bfd_default_compatible,
+ bfd_default_scan,
+ bfd_arch_default_fill,
+ 0,
+};
+
+const bfd_arch_info_type bfd_m68hc12_arch =
+{
+ 16, /* 16 bits in a word */
+ 32, /* 16 bits in an address */
+ 8, /* 8 bits in a byte */
+ bfd_arch_m68hc12,
+ 0,
+ "m68hc12",
+ "m68hc12",
+ 4, /* section alignment power */
+ TRUE,
+ bfd_default_compatible,
+ bfd_default_scan,
+ bfd_arch_default_fill,
+ &bfd_m68hc12s_arch,
+};
diff --git a/bfd/cpu-m68k.c b/bfd/cpu-m68k.c
new file mode 100644
index 0000000..2810994
--- /dev/null
+++ b/bfd/cpu-m68k.c
@@ -0,0 +1,273 @@
+/* BFD library support routines for architectures.
+ Copyright (C) 1990-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+#include "opcode/m68k.h"
+
+static const bfd_arch_info_type *
+bfd_m68k_compatible (const bfd_arch_info_type *a,
+ const bfd_arch_info_type *b);
+
+#define N(name, print,d,next) \
+{ 32, 32, 8, bfd_arch_m68k, name, "m68k",print,2,d,bfd_m68k_compatible, \
+ bfd_default_scan, bfd_arch_default_fill, 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_m68060, "m68k:68060", FALSE, &arch_info_struct[7]),
+ N(bfd_mach_cpu32, "m68k:cpu32", FALSE, &arch_info_struct[8]),
+ N(bfd_mach_fido, "m68k:fido", FALSE, &arch_info_struct[9]),
+
+ /* Various combinations of CF architecture features */
+ N(bfd_mach_mcf_isa_a_nodiv, "m68k:isa-a:nodiv",
+ FALSE, &arch_info_struct[10]),
+ N(bfd_mach_mcf_isa_a, "m68k:isa-a",
+ FALSE, &arch_info_struct[11]),
+ N(bfd_mach_mcf_isa_a_mac, "m68k:isa-a:mac",
+ FALSE, &arch_info_struct[12]),
+ N(bfd_mach_mcf_isa_a_emac, "m68k:isa-a:emac",
+ FALSE, &arch_info_struct[13]),
+ N(bfd_mach_mcf_isa_aplus, "m68k:isa-aplus",
+ FALSE, &arch_info_struct[14]),
+ N(bfd_mach_mcf_isa_aplus_mac, "m68k:isa-aplus:mac",
+ FALSE, &arch_info_struct[15]),
+ N(bfd_mach_mcf_isa_aplus_emac, "m68k:isa-aplus:emac",
+ FALSE, &arch_info_struct[16]),
+ N(bfd_mach_mcf_isa_b_nousp, "m68k:isa-b:nousp",
+ FALSE, &arch_info_struct[17]),
+ N(bfd_mach_mcf_isa_b_nousp_mac, "m68k:isa-b:nousp:mac",
+ FALSE, &arch_info_struct[18]),
+ N(bfd_mach_mcf_isa_b_nousp_emac, "m68k:isa-b:nousp:emac",
+ FALSE, &arch_info_struct[19]),
+ N(bfd_mach_mcf_isa_b, "m68k:isa-b",
+ FALSE, &arch_info_struct[20]),
+ N(bfd_mach_mcf_isa_b_mac, "m68k:isa-b:mac",
+ FALSE, &arch_info_struct[21]),
+ N(bfd_mach_mcf_isa_b_emac, "m68k:isa-b:emac",
+ FALSE, &arch_info_struct[22]),
+ N(bfd_mach_mcf_isa_b_float, "m68k:isa-b:float",
+ FALSE, &arch_info_struct[23]),
+ N(bfd_mach_mcf_isa_b_float_mac, "m68k:isa-b:float:mac",
+ FALSE, &arch_info_struct[24]),
+ N(bfd_mach_mcf_isa_b_float_emac, "m68k:isa-b:float:emac",
+ FALSE, &arch_info_struct[25]),
+ N(bfd_mach_mcf_isa_c, "m68k:isa-c",
+ FALSE, &arch_info_struct[26]),
+ N(bfd_mach_mcf_isa_c_mac, "m68k:isa-c:mac",
+ FALSE, &arch_info_struct[27]),
+ N(bfd_mach_mcf_isa_c_emac, "m68k:isa-c:emac",
+ FALSE, &arch_info_struct[28]),
+ N(bfd_mach_mcf_isa_c_nodiv, "m68k:isa-c:nodiv",
+ FALSE, &arch_info_struct[29]),
+ N(bfd_mach_mcf_isa_c_nodiv_mac, "m68k:isa-c:nodiv:mac",
+ FALSE, &arch_info_struct[30]),
+ N(bfd_mach_mcf_isa_c_nodiv_emac, "m68k:isa-c:nodiv:emac",
+ FALSE, &arch_info_struct[31]),
+
+ /* Legacy names for CF architectures */
+ N(bfd_mach_mcf_isa_a_nodiv, "m68k:5200", FALSE, &arch_info_struct[32]),
+ N(bfd_mach_mcf_isa_a_mac,"m68k:5206e", FALSE, &arch_info_struct[33]),
+ N(bfd_mach_mcf_isa_a_mac, "m68k:5307", FALSE, &arch_info_struct[34]),
+ N(bfd_mach_mcf_isa_b_nousp_mac, "m68k:5407", FALSE, &arch_info_struct[35]),
+ N(bfd_mach_mcf_isa_aplus_emac, "m68k:528x", FALSE, &arch_info_struct[36]),
+ N(bfd_mach_mcf_isa_aplus_emac, "m68k:521x", FALSE, &arch_info_struct[37]),
+ N(bfd_mach_mcf_isa_a_emac, "m68k:5249", FALSE, &arch_info_struct[38]),
+ N(bfd_mach_mcf_isa_b_float_emac, "m68k:547x",
+ FALSE, &arch_info_struct[39]),
+ N(bfd_mach_mcf_isa_b_float_emac, "m68k:548x",
+ FALSE, &arch_info_struct[40]),
+ N(bfd_mach_mcf_isa_b_float_emac, "m68k:cfv4e", FALSE, 0),
+ };
+
+const bfd_arch_info_type bfd_m68k_arch =
+ N(0, "m68k", TRUE, &arch_info_struct[0]);
+
+/* Table indexed by bfd_mach_arch number indicating which
+ architectural features are supported. */
+static const unsigned m68k_arch_features[] =
+{
+ 0,
+ m68000|m68881|m68851,
+ m68000|m68881|m68851,
+ m68010|m68881|m68851,
+ m68020|m68881|m68851,
+ m68030|m68881|m68851,
+ m68040|m68881|m68851,
+ m68060|m68881|m68851,
+ cpu32|m68881,
+ fido_a|m68881,
+ mcfisa_a,
+ mcfisa_a|mcfhwdiv,
+ mcfisa_a|mcfhwdiv|mcfmac,
+ mcfisa_a|mcfhwdiv|mcfemac,
+ mcfisa_a|mcfisa_aa|mcfhwdiv|mcfusp,
+ mcfisa_a|mcfisa_aa|mcfhwdiv|mcfusp|mcfmac,
+ mcfisa_a|mcfisa_aa|mcfhwdiv|mcfusp|mcfemac,
+ mcfisa_a|mcfhwdiv|mcfisa_b,
+ mcfisa_a|mcfhwdiv|mcfisa_b|mcfmac,
+ mcfisa_a|mcfhwdiv|mcfisa_b|mcfemac,
+ mcfisa_a|mcfhwdiv|mcfisa_b|mcfusp,
+ mcfisa_a|mcfhwdiv|mcfisa_b|mcfusp|mcfmac,
+ mcfisa_a|mcfhwdiv|mcfisa_b|mcfusp|mcfemac,
+ mcfisa_a|mcfhwdiv|mcfisa_b|mcfusp|cfloat,
+ mcfisa_a|mcfhwdiv|mcfisa_b|mcfusp|cfloat|mcfmac,
+ mcfisa_a|mcfhwdiv|mcfisa_b|mcfusp|cfloat|mcfemac,
+ mcfisa_a|mcfhwdiv|mcfisa_c|mcfusp,
+ mcfisa_a|mcfhwdiv|mcfisa_c|mcfusp|mcfmac,
+ mcfisa_a|mcfhwdiv|mcfisa_c|mcfusp|mcfemac,
+ mcfisa_a|mcfisa_c|mcfusp,
+ mcfisa_a|mcfisa_c|mcfusp|mcfmac,
+ mcfisa_a|mcfisa_c|mcfusp|mcfemac,
+};
+
+/* Return the count of bits set in MASK */
+static unsigned
+bit_count (unsigned mask)
+{
+ unsigned ix;
+
+ for (ix = 0; mask; ix++)
+ /* Clear the LSB set */
+ mask ^= mask & -mask;
+ return ix;
+}
+
+/* Return the architectural features supported by MACH */
+
+unsigned
+bfd_m68k_mach_to_features (int mach)
+{
+ if ((unsigned)mach
+ >= sizeof (m68k_arch_features) / sizeof (m68k_arch_features[0]))
+ mach = 0;
+ return m68k_arch_features[mach];
+}
+
+/* Return the bfd machine that most closely represents the
+ architectural features. We find the machine with the smallest
+ number of additional features. If there is no such machine, we
+ find the one with the smallest number of missing features. */
+
+int bfd_m68k_features_to_mach (unsigned features)
+{
+ int superset = 0, subset = 0;
+ unsigned extra = 99, missing = 99;
+ unsigned ix;
+
+ for (ix = 0;
+ ix != sizeof (m68k_arch_features) / sizeof (m68k_arch_features[0]);
+ ix++)
+ {
+ unsigned this_extra, this_missing;
+
+ if (m68k_arch_features[ix] == features)
+ return ix;
+ this_extra = bit_count (m68k_arch_features[ix] & ~features);
+ if (this_extra < extra)
+ {
+ extra = this_extra;
+ superset = ix;
+ }
+
+ this_missing = bit_count (features & ~m68k_arch_features[ix]);
+ if (this_missing < missing)
+ {
+ missing = this_missing;
+ superset = ix;
+ }
+ }
+ return superset ? superset : subset;
+}
+
+static const bfd_arch_info_type *
+bfd_m68k_compatible (const bfd_arch_info_type *a,
+ const bfd_arch_info_type *b)
+{
+ if (a->arch != b->arch)
+ return NULL;
+
+ if (a->bits_per_word != b->bits_per_word)
+ return NULL;
+
+ if (!a->mach)
+ return b;
+ if (!b->mach)
+ return a;
+
+ if (a->mach <= bfd_mach_m68060 && b->mach <= bfd_mach_m68060)
+ /* Merge m68k machine. */
+ return a->mach > b->mach ? a : b;
+ else if (a->mach >= bfd_mach_cpu32 && b->mach >= bfd_mach_cpu32)
+ {
+ /* Merge the machine features. */
+ unsigned features = (bfd_m68k_mach_to_features (a->mach)
+ | bfd_m68k_mach_to_features (b->mach));
+
+ /* CPU32 and Coldfire are incompatible. */
+ if ((~features & (cpu32 | mcfisa_a)) == 0)
+ return NULL;
+
+ /* Fido and Coldfire are incompatible. */
+ if ((~features & (fido_a | mcfisa_a)) == 0)
+ return NULL;
+
+ /* ISA A+ and ISA B are incompatible. */
+ if ((~features & (mcfisa_aa | mcfisa_b)) == 0)
+ return NULL;
+
+ /* ISA B and ISA C are incompatible. */
+ if ((~features & (mcfisa_b | mcfisa_c)) == 0)
+ return NULL;
+
+ /* MAC and EMAC code cannot be merged. */
+ if ((~features & (mcfmac | mcfemac)) == 0)
+ return NULL;
+
+ /* CPU32 is compatible with Fido except that Fido does not
+ support tbl instructions. Warn when the user wants to mix
+ the two. */
+ if ((a->mach == bfd_mach_cpu32 && b->mach == bfd_mach_fido)
+ || (a->mach == bfd_mach_fido && b->mach == bfd_mach_cpu32))
+ {
+ static int cpu32_fido_mix_warning;
+ if (!cpu32_fido_mix_warning)
+ {
+ cpu32_fido_mix_warning = 1;
+ (*_bfd_error_handler) ("warning: linking CPU32 objects with fido objects");
+ }
+ return bfd_lookup_arch (a->arch,
+ bfd_m68k_features_to_mach (fido_a | m68881));
+ }
+
+ return bfd_lookup_arch (a->arch, bfd_m68k_features_to_mach (features));
+ }
+ else
+ /* They are incompatible. */
+ return NULL;
+}
diff --git a/bfd/cpu-m88k.c b/bfd/cpu-m88k.c
new file mode 100644
index 0000000..da4f03c
--- /dev/null
+++ b/bfd/cpu-m88k.c
@@ -0,0 +1,41 @@
+/* bfd back-end for m88k support
+ Copyright (C) 1990-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.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,
+ bfd_arch_default_fill,
+ 0,
+ };
diff --git a/bfd/cpu-m9s12x.c b/bfd/cpu-m9s12x.c
new file mode 100644
index 0000000..83bbfa3
--- /dev/null
+++ b/bfd/cpu-m9s12x.c
@@ -0,0 +1,41 @@
+/* BFD support for the Freescale 9S12X processor
+ Copyright (C) 2008-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+
+const bfd_arch_info_type bfd_m9s12x_arch =
+{
+ 16, /* 16 bits in a word. */
+ 32, /* 16 bits in an address. */
+ 8, /* 8 bits in a byte. */
+ bfd_arch_m9s12x,
+ 0,
+ "m9s12x",
+ "m9s12x",
+ 4, /* Section alignment power. */
+ TRUE,
+ bfd_default_compatible,
+ bfd_default_scan,
+ bfd_arch_default_fill,
+ 0,
+};
+
diff --git a/bfd/cpu-m9s12xg.c b/bfd/cpu-m9s12xg.c
new file mode 100644
index 0000000..a547568
--- /dev/null
+++ b/bfd/cpu-m9s12xg.c
@@ -0,0 +1,41 @@
+/* BFD support for the Freescale 9S12-XGATE co-processor
+ Copyright (C) 2008-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+
+const bfd_arch_info_type bfd_m9s12xg_arch =
+{
+ 16, /* 16 bits in a word. */
+ 32, /* 16 bits in an address. */
+ 8, /* 8 bits in a byte. */
+ bfd_arch_m9s12xg,
+ 0,
+ "m9s12xg",
+ "m9s12xg",
+ 4, /* Section alignment power. */
+ TRUE,
+ bfd_default_compatible,
+ bfd_default_scan,
+ bfd_arch_default_fill,
+ 0,
+};
+
diff --git a/bfd/cpu-mcore.c b/bfd/cpu-mcore.c
new file mode 100644
index 0000000..06a6e30
--- /dev/null
+++ b/bfd/cpu-mcore.c
@@ -0,0 +1,40 @@
+/* BFD library support routines for Motorola's MCore architecture
+ Copyright (C) 1993-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.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 */
+ bfd_arch_default_fill, /* Default fill. */
+ NULL /* Next in list */
+};
diff --git a/bfd/cpu-mep.c b/bfd/cpu-mep.c
new file mode 100644
index 0000000..5c74792
--- /dev/null
+++ b/bfd/cpu-mep.c
@@ -0,0 +1,30 @@
+/* BFD support for the Toshiba Media Engine Processor.
+ Copyright (C) 2001-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+
+#define MA(x, n, def, y) { 32, 32, 8, bfd_arch_mep, x, "mep", n, \
+ 2, def, bfd_default_compatible, bfd_default_scan, \
+ bfd_arch_default_fill, y }
+
+static const bfd_arch_info_type bfd_c5_arch = MA (bfd_mach_mep_c5, "c5", FALSE, NULL);
+static const bfd_arch_info_type bfd_h1_arch = MA (bfd_mach_mep_h1, "h1", FALSE, & bfd_c5_arch);
+const bfd_arch_info_type bfd_mep_arch = MA (bfd_mach_mep, "mep", TRUE, & bfd_h1_arch);
diff --git a/bfd/cpu-metag.c b/bfd/cpu-metag.c
new file mode 100644
index 0000000..a1aa92d
--- /dev/null
+++ b/bfd/cpu-metag.c
@@ -0,0 +1,41 @@
+/* BFD support for the Imagination Technologies Meta processor.
+ Copyright (C) 2013-2014 Free Software Foundation, Inc.
+ Contributed by Imagination Technologies Ltd.
+
+ This file is part of BFD, the Binary File Descriptor library.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+
+const bfd_arch_info_type bfd_metag_arch =
+{
+ 32, /* Bits per word. */
+ 32, /* Bits per address. */
+ 8, /* Bits per byte. */
+ bfd_arch_metag, /* Architecture. */
+ bfd_mach_metag, /* Machine. */
+ "metag", /* Architecture name. */
+ "metag", /* Printable name. */
+ 4, /* Section align power. */
+ TRUE, /* The default ? */
+ bfd_default_compatible, /* Architecture comparison fn. */
+ bfd_default_scan, /* String to architecture convert fn. */
+ bfd_arch_default_fill, /* Default fill. */
+ NULL /* Next in list. */
+};
diff --git a/bfd/cpu-microblaze.c b/bfd/cpu-microblaze.c
new file mode 100644
index 0000000..023aa6c
--- /dev/null
+++ b/bfd/cpu-microblaze.c
@@ -0,0 +1,41 @@
+/* BFD Xilinx MicroBlaze architecture definition
+
+ Copyright (C) 2009-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+
+const bfd_arch_info_type bfd_microblaze_arch =
+{
+ 32, /* 32 bits in a word. */
+ 32, /* 32 bits in an address. */
+ 8, /* 8 bits in a byte. */
+ bfd_arch_microblaze, /* Architecture. */
+ 0, /* Machine number - 0 for now. */
+ "microblaze", /* Architecture name. */
+ "MicroBlaze", /* 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. */
+ bfd_arch_default_fill, /* Default fill. */
+ NULL /* Next in list. */
+};
diff --git a/bfd/cpu-mips.c b/bfd/cpu-mips.c
new file mode 100644
index 0000000..b617aaa
--- /dev/null
+++ b/bfd/cpu-mips.c
@@ -0,0 +1,164 @@
+/* bfd back-end for mips support
+ Copyright (C) 1990-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+
+static const bfd_arch_info_type *mips_compatible
+ (const bfd_arch_info_type *, const bfd_arch_info_type *);
+
+/* The default routine tests bits_per_word, which is wrong on mips as
+ mips word size doesn't correlate with reloc size. */
+
+static const bfd_arch_info_type *
+mips_compatible (const bfd_arch_info_type *a, const bfd_arch_info_type *b)
+{
+ if (a->arch != b->arch)
+ return NULL;
+
+ /* Machine compatibility is checked in
+ _bfd_mips_elf_merge_private_bfd_data. */
+
+ return a;
+}
+
+#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, \
+ mips_compatible, \
+ bfd_default_scan, \
+ bfd_arch_default_fill, \
+ NEXT, \
+ }
+
+enum
+{
+ I_mips3000,
+ I_mips3900,
+ I_mips4000,
+ I_mips4010,
+ I_mips4100,
+ I_mips4111,
+ I_mips4120,
+ I_mips4300,
+ I_mips4400,
+ I_mips4600,
+ I_mips4650,
+ I_mips5000,
+ I_mips5400,
+ I_mips5500,
+ I_mips5900,
+ I_mips6000,
+ I_mips7000,
+ I_mips8000,
+ I_mips9000,
+ I_mips10000,
+ I_mips12000,
+ I_mips14000,
+ I_mips16000,
+ I_mips16,
+ I_mips5,
+ I_mipsisa32,
+ I_mipsisa32r2,
+ I_mipsisa32r3,
+ I_mipsisa32r5,
+ I_mipsisa32r6,
+ I_mipsisa64,
+ I_mipsisa64r2,
+ I_mipsisa64r3,
+ I_mipsisa64r5,
+ I_mipsisa64r6,
+ I_sb1,
+ I_loongson_2e,
+ I_loongson_2f,
+ I_loongson_3a,
+ I_mipsocteon,
+ I_mipsocteonp,
+ I_mipsocteon2,
+ I_xlr,
+ I_micromips
+};
+
+#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_mips4120, "mips:4120", FALSE, NN(I_mips4120)),
+ 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 (64, 64, bfd_mach_mips5400, "mips:5400", FALSE, NN(I_mips5400)),
+ N (64, 64, bfd_mach_mips5500, "mips:5500", FALSE, NN(I_mips5500)),
+ N (64, 32, bfd_mach_mips5900, "mips:5900", FALSE, NN(I_mips5900)),
+ N (32, 32, bfd_mach_mips6000, "mips:6000", FALSE, NN(I_mips6000)),
+ N (64, 64, bfd_mach_mips7000, "mips:7000", FALSE, NN(I_mips7000)),
+ N (64, 64, bfd_mach_mips8000, "mips:8000", FALSE, NN(I_mips8000)),
+ N (64, 64, bfd_mach_mips9000, "mips:9000", FALSE, NN(I_mips9000)),
+ N (64, 64, bfd_mach_mips10000,"mips:10000", FALSE, NN(I_mips10000)),
+ N (64, 64, bfd_mach_mips12000,"mips:12000", FALSE, NN(I_mips12000)),
+ N (64, 64, bfd_mach_mips14000,"mips:14000", FALSE, NN(I_mips14000)),
+ N (64, 64, bfd_mach_mips16000,"mips:16000", FALSE, NN(I_mips16000)),
+ N (64, 64, bfd_mach_mips16, "mips:16", FALSE, NN(I_mips16)),
+ N (64, 64, bfd_mach_mips5, "mips:mips5", FALSE, NN(I_mips5)),
+ N (32, 32, bfd_mach_mipsisa32, "mips:isa32", FALSE, NN(I_mipsisa32)),
+ N (32, 32, bfd_mach_mipsisa32r2,"mips:isa32r2", FALSE, NN(I_mipsisa32r2)),
+ N (32, 32, bfd_mach_mipsisa32r3,"mips:isa32r3", FALSE, NN(I_mipsisa32r3)),
+ N (32, 32, bfd_mach_mipsisa32r5,"mips:isa32r5", FALSE, NN(I_mipsisa32r5)),
+ N (32, 32, bfd_mach_mipsisa32r6,"mips:isa32r6", FALSE, NN(I_mipsisa32r6)),
+ N (64, 64, bfd_mach_mipsisa64, "mips:isa64", FALSE, NN(I_mipsisa64)),
+ N (64, 64, bfd_mach_mipsisa64r2,"mips:isa64r2", FALSE, NN(I_mipsisa64r2)),
+ N (64, 64, bfd_mach_mipsisa64r3,"mips:isa64r3", FALSE, NN(I_mipsisa64r3)),
+ N (64, 64, bfd_mach_mipsisa64r5,"mips:isa64r5", FALSE, NN(I_mipsisa64r5)),
+ N (64, 64, bfd_mach_mipsisa64r6,"mips:isa64r6", FALSE, NN(I_mipsisa64r6)),
+ N (64, 64, bfd_mach_mips_sb1, "mips:sb1", FALSE, NN(I_sb1)),
+ N (64, 64, bfd_mach_mips_loongson_2e, "mips:loongson_2e", FALSE, NN(I_loongson_2e)),
+ N (64, 64, bfd_mach_mips_loongson_2f, "mips:loongson_2f", FALSE, NN(I_loongson_2f)),
+ N (64, 64, bfd_mach_mips_loongson_3a, "mips:loongson_3a", FALSE, NN(I_loongson_3a)),
+ N (64, 64, bfd_mach_mips_octeon,"mips:octeon", FALSE, NN(I_mipsocteon)),
+ N (64, 64, bfd_mach_mips_octeonp,"mips:octeon+", FALSE, NN(I_mipsocteonp)),
+ N (64, 64, bfd_mach_mips_octeon2,"mips:octeon2", FALSE, NN(I_mipsocteon2)),
+ N (64, 64, bfd_mach_mips_xlr, "mips:xlr", FALSE, NN(I_xlr)),
+ N (64, 64, bfd_mach_mips_micromips,"mips:micromips",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-mmix.c b/bfd/cpu-mmix.c
new file mode 100644
index 0000000..0d8584c
--- /dev/null
+++ b/bfd/cpu-mmix.c
@@ -0,0 +1,43 @@
+/* BFD library support routines for MMIX.
+ Copyright (C) 2001-2014 Free Software Foundation, Inc.
+ Contributed by Hans-Peter Nilsson (hp@bitrange.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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+
+const bfd_arch_info_type
+bfd_mmix_arch =
+ {
+ 64, /* 64 bits in a word. */
+ 64, /* 64 bits in an address. */
+ 8, /* 8 bits in a byte. */
+ bfd_arch_mmix, /* Architecture. */
+ 0, /* Machine number - 0 for now. */
+ /* Sorry, these are by custom and creeping assumption lower-case. */
+ "mmix", /* Architecture name. */
+ "mmix", /* Printable name. */
+ 3, /* Section align power. */
+ TRUE, /* This is the default architecture. */
+ bfd_default_compatible, /* Architecture comparison function. */
+ bfd_default_scan, /* String to architecture conversion. */
+ bfd_arch_default_fill, /* Default fill. */
+ NULL /* Next in list. */
+};
diff --git a/bfd/cpu-moxie.c b/bfd/cpu-moxie.c
new file mode 100644
index 0000000..949dd2b
--- /dev/null
+++ b/bfd/cpu-moxie.c
@@ -0,0 +1,41 @@
+/* BFD support for the moxie processor.
+ Copyright (C) 2009-2014 Free Software Foundation, Inc.
+ Written by Anthony Green
+
+ This file is part of BFD, the Binary File Descriptor library.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+
+
+const bfd_arch_info_type bfd_moxie_arch =
+ {
+ 32, /* 32 bits in a word. */
+ 32, /* 32 bits in an address. */
+ 8, /* 8 bits in a byte. */
+ bfd_arch_moxie, /* enum bfd_architecture arch. */
+ bfd_mach_moxie,
+ "moxie", /* Arch name. */
+ "moxie", /* Printable name. */
+ 2, /* Unsigned int section alignment power. */
+ TRUE, /* The one and only. */
+ bfd_default_compatible,
+ bfd_default_scan,
+ bfd_arch_default_fill,
+ 0,
+ };
diff --git a/bfd/cpu-msp430.c b/bfd/cpu-msp430.c
new file mode 100644
index 0000000..275a0ab
--- /dev/null
+++ b/bfd/cpu-msp430.c
@@ -0,0 +1,138 @@
+/* BFD library support routines for the MSP architecture.
+ Copyright (C) 2002-2014 Free Software Foundation, Inc.
+ Contributed by Dmitry Diky <diwil@mail.ru>
+
+ This file is part of BFD, the Binary File Descriptor library.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+
+/* This routine is provided two arch_infos and works out which MSP
+ machine which would be compatible with both and returns a pointer
+ to its info structure. */
+
+static const bfd_arch_info_type *
+compatible (const bfd_arch_info_type * a,
+ const bfd_arch_info_type * b)
+{
+ /* If a & b are for different architectures we can do nothing. */
+ if (a->arch != b->arch)
+ return NULL;
+
+ if (a->mach <= b->mach)
+ return b;
+
+ return a;
+}
+
+#define N(addr_bits, machine, print, default, next) \
+{ \
+ 16, /* 16 bits in a word. */ \
+ addr_bits, /* Bits in an address. */ \
+ 8, /* 8 bits in a byte. */ \
+ bfd_arch_msp430, \
+ machine, /* Machine number. */ \
+ "msp430", /* Architecture name. */ \
+ print, /* Printable name. */ \
+ 1, /* Section align power. */ \
+ default, /* The default machine. */ \
+ compatible, \
+ bfd_default_scan, \
+ bfd_arch_default_fill, \
+ next \
+}
+
+static const bfd_arch_info_type arch_info_struct[] =
+{
+ /* msp430x11x. */
+ N (16, bfd_mach_msp11, "MSP430", FALSE, & arch_info_struct[1]),
+
+ /* msp430x11x1. */
+ N (16, bfd_mach_msp110, "MSP430x11x1", FALSE, & arch_info_struct[2]),
+
+ /* msp430x12x. */
+ N (16, bfd_mach_msp12, "MSP430x12", FALSE, & arch_info_struct[3]),
+
+ /* msp430x13x. */
+ N (16, bfd_mach_msp13, "MSP430x13", FALSE, & arch_info_struct[4]),
+
+ /* msp430x14x. */
+ N (16, bfd_mach_msp14, "MSP430x14", FALSE, & arch_info_struct[5]),
+
+ /* msp430x15x. */
+ N (16, bfd_mach_msp15, "MSP430x15", FALSE, & arch_info_struct[6]),
+
+ /* msp430x16x. */
+ N (16, bfd_mach_msp16, "MSP430x16", FALSE, & arch_info_struct[7]),
+
+ /* msp430x20x. */
+ N (16, bfd_mach_msp20, "MSP430x20", FALSE, & arch_info_struct[8]),
+
+ /* msp430x21x. */
+ N (16, bfd_mach_msp21, "MSP430x21", FALSE, & arch_info_struct[9]),
+
+ /* msp430x22x. */
+ N (16, bfd_mach_msp22, "MSP430x22", FALSE, & arch_info_struct[10]),
+
+ /* msp430x23x. */
+ N (16, bfd_mach_msp23, "MSP430x23", FALSE, & arch_info_struct[11]),
+
+ /* msp430x24x. */
+ N (16, bfd_mach_msp24, "MSP430x24", FALSE, & arch_info_struct[12]),
+
+ /* msp430x26x. */
+ N (16, bfd_mach_msp26, "MSP430x26", FALSE, & arch_info_struct[13]),
+
+ /* msp430x31x. */
+ N (16, bfd_mach_msp31, "MSP430x31", FALSE, & arch_info_struct[14]),
+
+ /* msp430x32x. */
+ N (16, bfd_mach_msp32, "MSP430x32", FALSE, & arch_info_struct[15]),
+
+ /* msp430x33x. */
+ N (16, bfd_mach_msp33, "MSP430x33", FALSE, & arch_info_struct[16]),
+
+ /* msp430x41x. */
+ N (16, bfd_mach_msp41, "MSP430x41", FALSE, & arch_info_struct[17]),
+
+ /* msp430x42x. */
+ N (16, bfd_mach_msp42, "MSP430x42", FALSE, & arch_info_struct[18]),
+
+ /* msp430x43x. */
+ N (16, bfd_mach_msp43, "MSP430x43", FALSE, & arch_info_struct[19]),
+
+ /* msp430x44x. */
+ N (16, bfd_mach_msp43, "MSP430x44", FALSE, & arch_info_struct[20]),
+
+ /* msp430x46x. */
+ N (16, bfd_mach_msp46, "MSP430x46", FALSE, & arch_info_struct[21]),
+
+ /* msp430x47x. */
+ N (16, bfd_mach_msp47, "MSP430x47", FALSE, & arch_info_struct[22]),
+
+ /* msp430x54x. */
+ N (16, bfd_mach_msp54, "MSP430x54", FALSE, & arch_info_struct[23]),
+
+ N (32, bfd_mach_msp430x, "MSP430X", FALSE, NULL)
+
+};
+
+const bfd_arch_info_type bfd_msp430_arch =
+ N (16, bfd_mach_msp14, "msp:14", TRUE, & arch_info_struct[0]);
+
diff --git a/bfd/cpu-mt.c b/bfd/cpu-mt.c
new file mode 100644
index 0000000..ea5fc5a
--- /dev/null
+++ b/bfd/cpu-mt.c
@@ -0,0 +1,75 @@
+/* BFD support for the Morpho Technologies MT processor.
+ Copyright (C) 2001-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public 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 "bfd.h"
+#include "libbfd.h"
+
+const bfd_arch_info_type arch_info_struct[] =
+{
+{
+ 32, /* Bits per word - not really true. */
+ 32, /* Bits per address. */
+ 8, /* Bits per byte. */
+ bfd_arch_mt, /* Architecture. */
+ bfd_mach_mrisc2, /* Machine. */
+ "mt", /* Architecture name. */
+ "ms1-003", /* Printable name. */
+ 1, /* Section align power. */
+ FALSE, /* The default ? */
+ bfd_default_compatible, /* Architecture comparison fn. */
+ bfd_default_scan, /* String to architecture convert fn. */
+ bfd_arch_default_fill, /* Default fill. */
+ &arch_info_struct[1] /* Next in list. */
+},
+{
+ 32, /* Bits per word - not really true. */
+ 32, /* Bits per address. */
+ 8, /* Bits per byte. */
+ bfd_arch_mt, /* Architecture. */
+ bfd_mach_ms2, /* Machine. */
+ "mt", /* Architecture name. */
+ "ms2", /* Printable name. */
+ 1, /* Section align power. */
+ FALSE, /* The default ? */
+ bfd_default_compatible, /* Architecture comparison fn. */
+ bfd_default_scan, /* String to architecture convert fn. */
+ bfd_arch_default_fill, /* Default fill. */
+ NULL /* Next in list. */
+},
+};
+
+const bfd_arch_info_type bfd_mt_arch =
+{
+ 32, /* Bits per word - not really true. */
+ 32, /* Bits per address. */
+ 8, /* Bits per byte. */
+ bfd_arch_mt, /* Architecture. */
+ bfd_mach_ms1, /* Machine. */
+ "mt", /* Architecture name. */
+ "ms1", /* Printable name. */
+ 1, /* Section align power. */
+ TRUE, /* The default ? */
+ bfd_default_compatible, /* Architecture comparison fn. */
+ bfd_default_scan, /* String to architecture convert fn. */
+ bfd_arch_default_fill, /* Default fill. */
+ &arch_info_struct[0] /* Next in list. */
+};
+
diff --git a/bfd/cpu-nds32.c b/bfd/cpu-nds32.c
new file mode 100644
index 0000000..d40d56a
--- /dev/null
+++ b/bfd/cpu-nds32.c
@@ -0,0 +1,45 @@
+/* BFD support for the NDS32 processor
+ Copyright (C) 2012-2014 Free Software Foundation, Inc.
+ Contributed by Andes Technology Corporation.
+
+ This file is part of BFD, the Binary File Descriptor library.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
+ 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+#include "elf-bfd.h"
+
+#define N(number, print, default, next) \
+ {32, 32, 8, bfd_arch_nds32, number, "nds32", print, 4, default, \
+ bfd_default_compatible, bfd_default_scan, bfd_arch_default_fill, next }
+
+#define NEXT &arch_info_struct[0]
+#define NDS32V2_NEXT &arch_info_struct[1]
+#define NDS32V3_NEXT &arch_info_struct[2]
+#define NDS32V3M_NEXT &arch_info_struct[3]
+
+static const bfd_arch_info_type arch_info_struct[] =
+{
+ N (bfd_mach_n1h, "n1h", FALSE, NDS32V2_NEXT),
+ N (bfd_mach_n1h_v2, "n1h_v2", FALSE, NDS32V3_NEXT),
+ N (bfd_mach_n1h_v3, "n1h_v3", FALSE, NDS32V3M_NEXT),
+ N (bfd_mach_n1h_v3m, "n1h_v3m", FALSE, NULL),
+};
+
+const bfd_arch_info_type bfd_nds32_arch =
+ N (bfd_mach_n1, "n1h", TRUE, NEXT);
diff --git a/bfd/cpu-nios2.c b/bfd/cpu-nios2.c
new file mode 100644
index 0000000..95ae1d9
--- /dev/null
+++ b/bfd/cpu-nios2.c
@@ -0,0 +1,44 @@
+/* BFD support for the Altera Nios II processor.
+ Copyright (C) 2012-2014 Free Software Foundation, Inc.
+ Contributed by Nigel Gray (ngray@altera.com).
+ Contributed by Mentor Graphics, 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.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_nios2, \
+ NUMBER, \
+ "nios2", \
+ PRINT, \
+ 3, \
+ DEFAULT, \
+ bfd_default_compatible, \
+ bfd_default_scan, \
+ bfd_arch_default_fill, \
+ NEXT \
+ }
+
+const bfd_arch_info_type bfd_nios2_arch = N (32, 32, 0, "nios2", TRUE, NULL);
diff --git a/bfd/cpu-ns32k.c b/bfd/cpu-ns32k.c
new file mode 100644
index 0000000..55ee030
--- /dev/null
+++ b/bfd/cpu-ns32k.c
@@ -0,0 +1,809 @@
+/* BFD support for the ns32k architecture.
+ Copyright (C) 1990-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.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,bfd_arch_default_fill,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]);
+
+bfd_vma
+_bfd_ns32k_get_displacement (bfd_byte *buffer, int size)
+{
+ bfd_signed_vma value;
+
+ switch (size)
+ {
+ case 1:
+ value = ((*buffer & 0x7f) ^ 0x40) - 0x40;
+ break;
+
+ case 2:
+ value = ((*buffer++ & 0x3f) ^ 0x20) - 0x20;
+ value = (value << 8) | (0xff & *buffer);
+ break;
+
+ case 4:
+ value = ((*buffer++ & 0x3f) ^ 0x20) - 0x20;
+ value = (value << 8) | (0xff & *buffer++);
+ value = (value << 8) | (0xff & *buffer++);
+ value = (value << 8) | (0xff & *buffer);
+ break;
+
+ default:
+ abort ();
+ return 0;
+ }
+
+ return value;
+}
+
+void
+_bfd_ns32k_put_displacement (bfd_vma value, bfd_byte *buffer, int size)
+{
+ switch (size)
+ {
+ case 1:
+ value &= 0x7f;
+ *buffer++ = value;
+ break;
+
+ case 2:
+ value &= 0x3fff;
+ value |= 0x8000;
+ *buffer++ = (value >> 8);
+ *buffer++ = value;
+ break;
+
+ case 4:
+ value |= (bfd_vma) 0xc0000000;
+ *buffer++ = (value >> 24);
+ *buffer++ = (value >> 16);
+ *buffer++ = (value >> 8);
+ *buffer++ = value;
+ break;
+ }
+ return;
+}
+
+bfd_vma
+_bfd_ns32k_get_immediate (bfd_byte *buffer, int size)
+{
+ bfd_vma value = 0;
+
+ switch (size)
+ {
+ case 4:
+ value = (value << 8) | (*buffer++ & 0xff);
+ value = (value << 8) | (*buffer++ & 0xff);
+ case 2:
+ value = (value << 8) | (*buffer++ & 0xff);
+ case 1:
+ value = (value << 8) | (*buffer++ & 0xff);
+ break;
+ default:
+ abort ();
+ }
+ return value;
+}
+
+void
+_bfd_ns32k_put_immediate (bfd_vma value, bfd_byte *buffer, int size)
+{
+ buffer += size - 1;
+ switch (size)
+ {
+ case 4:
+ *buffer-- = (value & 0xff); value >>= 8;
+ *buffer-- = (value & 0xff); value >>= 8;
+ case 2:
+ *buffer-- = (value & 0xff); value >>= 8;
+ case 1:
+ *buffer-- = (value & 0xff); value >>= 8;
+ }
+}
+
+/* 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 (bfd * abfd,
+ arelent * reloc_entry,
+ struct bfd_symbol * symbol,
+ void * data,
+ asection * input_section,
+ bfd * output_bfd,
+ char ** error_message ATTRIBUTE_UNUSED,
+ bfd_vma (* get_data) (bfd_byte *, int),
+ void (* put_data) (bfd_vma, bfd_byte *, int))
+{
+ 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;
+ bfd_byte *location;
+
+ 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 relocatable 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;
+
+ /* Is the address of the relocation really within the section? */
+ if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
+ return bfd_reloc_outofrange;
+
+ /* Work out which section the relocation is targeted 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 != NULL && ! howto->partial_inplace)
+ 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)
+ {
+ /* 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 relocatable 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 relocatable 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)
+ relocation -= reloc_entry->address;
+ }
+
+ if (output_bfd != (bfd *) NULL)
+ {
+ if (! howto->partial_inplace)
+ {
+ /* 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)
+ {
+ /* 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 relocatable 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 relocatable
+ output. When we are producing relocatable output, logically
+ we should do exactly what we do when not producing
+ relocatable 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 relocatable 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;
+ 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)
+ != (-(bfd_vma) 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)
+ != (-(bfd_vma) 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))
+
+ location = (bfd_byte *) data + addr;
+ switch (howto->size)
+ {
+ case 0:
+ {
+ bfd_vma x = get_data (location, 1);
+ DOIT (x);
+ put_data ((bfd_vma) x, location, 1);
+ }
+ break;
+
+ case 1:
+ if (relocation)
+ {
+ bfd_vma x = get_data (location, 2);
+ DOIT (x);
+ put_data ((bfd_vma) x, location, 2);
+ }
+ break;
+ case 2:
+ if (relocation)
+ {
+ bfd_vma x = get_data (location, 4);
+ DOIT (x);
+ put_data ((bfd_vma) x, location, 4);
+ }
+ break;
+ case -2:
+ {
+ bfd_vma x = get_data (location, 4);
+ relocation = -relocation;
+ DOIT(x);
+ put_data ((bfd_vma) x, location, 4);
+ }
+ break;
+
+ case 3:
+ /* Do nothing. */
+ break;
+
+ case 4:
+#ifdef BFD64
+ if (relocation)
+ {
+ bfd_vma x = get_data (location, 8);
+ DOIT (x);
+ put_data (x, location, 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 (reloc_howto_type *howto,
+ bfd *input_bfd ATTRIBUTE_UNUSED,
+ bfd_vma relocation,
+ bfd_byte *location,
+ bfd_vma (*get_data) (bfd_byte *, int),
+ void (*put_data) (bfd_vma, bfd_byte *, int))
+{
+ int size;
+ bfd_vma x;
+ bfd_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, 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
+ explicitly 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)
+ != (-(bfd_vma) 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, size);
+ break;
+ }
+
+ return overflow ? bfd_reloc_overflow : bfd_reloc_ok;
+}
+
+bfd_reloc_status_type
+_bfd_ns32k_reloc_disp (bfd *abfd,
+ arelent *reloc_entry,
+ struct bfd_symbol *symbol,
+ void * 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 (bfd *abfd,
+ arelent *reloc_entry,
+ struct bfd_symbol *symbol,
+ void * 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 (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 > bfd_get_section_limit (input_bfd, input_section))
+ 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-or1k.c b/bfd/cpu-or1k.c
new file mode 100644
index 0000000..7abf2cb
--- /dev/null
+++ b/bfd/cpu-or1k.c
@@ -0,0 +1,59 @@
+/* BFD support for the OpenRISC 1000 architecture.
+ Copyright 2002-2014 Free Software Foundation, Inc.
+ Contributed for OR32 by Ivan Guzvinec <ivang@opencores.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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, see <http://www.gnu.org/licenses/>. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+
+const bfd_arch_info_type bfd_or1k_arch;
+const bfd_arch_info_type bfd_or1knd_arch;
+
+const bfd_arch_info_type bfd_or1k_arch =
+ {
+ 32, /* 32 bits in a word. */
+ 32, /* 32 bits in an address. */
+ 8, /* 8 bits in a byte. */
+ bfd_arch_or1k,
+ bfd_mach_or1k,
+ "or1k",
+ "or1k",
+ 4,
+ TRUE,
+ bfd_default_compatible,
+ bfd_default_scan,
+ bfd_arch_default_fill,
+ &bfd_or1knd_arch,
+ };
+
+const bfd_arch_info_type bfd_or1knd_arch =
+ {
+ 32, /* 32 bits in a word. */
+ 32, /* 32 bits in an address. */
+ 8, /* 8 bits in a byte. */
+ bfd_arch_or1k,
+ bfd_mach_or1knd,
+ "or1knd",
+ "or1knd",
+ 4,
+ FALSE,
+ bfd_default_compatible,
+ bfd_default_scan,
+ bfd_arch_default_fill,
+ NULL,
+ };
diff --git a/bfd/cpu-pdp11.c b/bfd/cpu-pdp11.c
new file mode 100644
index 0000000..cf8e7e2
--- /dev/null
+++ b/bfd/cpu-pdp11.c
@@ -0,0 +1,41 @@
+/* BFD back-end for PDP-11 support.
+ Copyright (C) 2001-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+
+const bfd_arch_info_type bfd_pdp11_arch =
+ {
+ 16, /* 16 bits in a word */
+ 16, /* 16 bits in an address */
+ 8, /* 8 bits in a byte */
+ bfd_arch_pdp11,
+ 0, /* only 1 machine */
+ "pdp11",
+ "pdp11",
+ 1, /* aligment = 16 bit */
+ TRUE, /* the one and only */
+ bfd_default_compatible,
+ bfd_default_scan,
+ bfd_arch_default_fill,
+ 0,
+ };
+
diff --git a/bfd/cpu-pj.c b/bfd/cpu-pj.c
new file mode 100644
index 0000000..dfbe8c4
--- /dev/null
+++ b/bfd/cpu-pj.c
@@ -0,0 +1,41 @@
+/* BFD library support routines for the Pico Java architecture.
+ Copyright (C) 1999-2014 Free Software Foundation, Inc.
+ Hacked by Steve Chamberlain of Transmeta. sac@pobox.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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+
+const bfd_arch_info_type bfd_pj_arch =
+{
+ 32, /* 32 bits in a word */
+ 32, /* 32 bits in an address */
+ 8, /* 8 bits in a byte */
+ bfd_arch_pj,
+ 0,
+ "pj", /* arch_name */
+ "pj", /* printable name */
+ 1,
+ TRUE, /* the default machine */
+ bfd_default_compatible,
+ bfd_default_scan,
+ bfd_arch_default_fill,
+ 0
+};
diff --git a/bfd/cpu-plugin.c b/bfd/cpu-plugin.c
new file mode 100644
index 0000000..76fd687
--- /dev/null
+++ b/bfd/cpu-plugin.c
@@ -0,0 +1,40 @@
+/* BFD support for plugins.
+ Copyright (C) 2009-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+
+const bfd_arch_info_type bfd_plugin_arch =
+{
+ 32, /* 32 bits in a word. */
+ 32, /* 32 bits in an address. */
+ 8, /* 8 bits in a byte. */
+ bfd_arch_plugin,
+ 0, /* Only 1 machine. */
+ "plugin",
+ "plugin",
+ 3,
+ TRUE,
+ bfd_default_compatible,
+ bfd_default_scan,
+ bfd_arch_default_fill,
+ 0
+};
diff --git a/bfd/cpu-powerpc.c b/bfd/cpu-powerpc.c
new file mode 100644
index 0000000..8d7bebc
--- /dev/null
+++ b/bfd/cpu-powerpc.c
@@ -0,0 +1,418 @@
+/* BFD PowerPC CPU definition
+ Copyright (C) 1994-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+
+/* The common PowerPC architecture is compatible with the RS/6000. */
+
+static const bfd_arch_info_type *
+powerpc_compatible (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 (b->mach == bfd_mach_rs6k)
+ return a;
+ return NULL;
+ }
+ /*NOTREACHED*/
+}
+
+const bfd_arch_info_type bfd_powerpc_archs[] =
+{
+#if BFD_DEFAULT_TARGET_SIZE == 64
+ /* Default arch must come first. */
+ {
+ 64, /* 64 bits in a word */
+ 64, /* 64 bits in an address */
+ 8, /* 8 bits in a byte */
+ bfd_arch_powerpc,
+ bfd_mach_ppc64,
+ "powerpc",
+ "powerpc:common64",
+ 3,
+ TRUE, /* default for 64 bit target */
+ powerpc_compatible,
+ bfd_default_scan,
+ bfd_arch_default_fill,
+ &bfd_powerpc_archs[1]
+ },
+ /* elf32-ppc:ppc_elf_object_p relies on the default 32 bit arch
+ being immediately after the 64 bit default. */
+ {
+ 32, /* 32 bits in a word */
+ 32, /* 32 bits in an address */
+ 8, /* 8 bits in a byte */
+ bfd_arch_powerpc,
+ bfd_mach_ppc, /* for the POWER/PowerPC common architecture */
+ "powerpc",
+ "powerpc:common",
+ 3,
+ FALSE,
+ powerpc_compatible,
+ bfd_default_scan,
+ bfd_arch_default_fill,
+ &bfd_powerpc_archs[2],
+ },
+#else
+ /* Default arch must come first. */
+ {
+ 32, /* 32 bits in a word */
+ 32, /* 32 bits in an address */
+ 8, /* 8 bits in a byte */
+ bfd_arch_powerpc,
+ bfd_mach_ppc, /* for the POWER/PowerPC common architecture */
+ "powerpc",
+ "powerpc:common",
+ 3,
+ TRUE, /* default for 32 bit target */
+ powerpc_compatible,
+ bfd_default_scan,
+ bfd_arch_default_fill,
+ &bfd_powerpc_archs[1],
+ },
+ /* elf64-ppc:ppc64_elf_object_p relies on the default 64 bit arch
+ being immediately after the 32 bit default. */
+ {
+ 64, /* 64 bits in a word */
+ 64, /* 64 bits in an address */
+ 8, /* 8 bits in a byte */
+ bfd_arch_powerpc,
+ bfd_mach_ppc64,
+ "powerpc",
+ "powerpc:common64",
+ 3,
+ FALSE,
+ powerpc_compatible,
+ bfd_default_scan,
+ bfd_arch_default_fill,
+ &bfd_powerpc_archs[2]
+ },
+#endif
+ {
+ 32, /* 32 bits in a word */
+ 32, /* 32 bits in an address */
+ 8, /* 8 bits in a byte */
+ bfd_arch_powerpc,
+ bfd_mach_ppc_603,
+ "powerpc",
+ "powerpc:603",
+ 3,
+ FALSE, /* not the default */
+ powerpc_compatible,
+ bfd_default_scan,
+ bfd_arch_default_fill,
+ &bfd_powerpc_archs[3]
+ },
+ {
+ 32, /* 32 bits in a word */
+ 32, /* 32 bits in an address */
+ 8, /* 8 bits in a byte */
+ bfd_arch_powerpc,
+ bfd_mach_ppc_ec603e,
+ "powerpc",
+ "powerpc:EC603e",
+ 3,
+ FALSE, /* not the default */
+ powerpc_compatible,
+ bfd_default_scan,
+ bfd_arch_default_fill,
+ &bfd_powerpc_archs[4]
+ },
+ {
+ 32, /* 32 bits in a word */
+ 32, /* 32 bits in an address */
+ 8, /* 8 bits in a byte */
+ bfd_arch_powerpc,
+ bfd_mach_ppc_604,
+ "powerpc",
+ "powerpc:604",
+ 3,
+ FALSE, /* not the default */
+ powerpc_compatible,
+ bfd_default_scan,
+ bfd_arch_default_fill,
+ &bfd_powerpc_archs[5]
+ },
+ {
+ 32, /* 32 bits in a word */
+ 32, /* 32 bits in an address */
+ 8, /* 8 bits in a byte */
+ bfd_arch_powerpc,
+ bfd_mach_ppc_403,
+ "powerpc",
+ "powerpc:403",
+ 3,
+ FALSE, /* not the default */
+ powerpc_compatible,
+ bfd_default_scan,
+ bfd_arch_default_fill,
+ &bfd_powerpc_archs[6]
+ },
+ {
+ 32, /* 32 bits in a word */
+ 32, /* 32 bits in an address */
+ 8, /* 8 bits in a byte */
+ bfd_arch_powerpc,
+ bfd_mach_ppc_601,
+ "powerpc",
+ "powerpc:601",
+ 3,
+ FALSE, /* not the default */
+ powerpc_compatible,
+ bfd_default_scan,
+ bfd_arch_default_fill,
+ &bfd_powerpc_archs[7]
+ },
+ {
+ 64, /* 64 bits in a word */
+ 64, /* 64 bits in an address */
+ 8, /* 8 bits in a byte */
+ bfd_arch_powerpc,
+ bfd_mach_ppc_620,
+ "powerpc",
+ "powerpc:620",
+ 3,
+ FALSE, /* not the default */
+ powerpc_compatible,
+ bfd_default_scan,
+ bfd_arch_default_fill,
+ &bfd_powerpc_archs[8]
+ },
+ {
+ 64, /* 64 bits in a word */
+ 64, /* 64 bits in an address */
+ 8, /* 8 bits in a byte */
+ bfd_arch_powerpc,
+ bfd_mach_ppc_630,
+ "powerpc",
+ "powerpc:630",
+ 3,
+ FALSE, /* not the default */
+ powerpc_compatible,
+ bfd_default_scan,
+ bfd_arch_default_fill,
+ &bfd_powerpc_archs[9]
+ },
+ {
+ 64, /* 64 bits in a word */
+ 64, /* 64 bits in an address */
+ 8, /* 8 bits in a byte */
+ bfd_arch_powerpc,
+ bfd_mach_ppc_a35,
+ "powerpc",
+ "powerpc:a35",
+ 3,
+ FALSE, /* not the default */
+ powerpc_compatible,
+ bfd_default_scan,
+ bfd_arch_default_fill,
+ &bfd_powerpc_archs[10]
+ },
+ {
+ 64, /* 64 bits in a word */
+ 64, /* 64 bits in an address */
+ 8, /* 8 bits in a byte */
+ bfd_arch_powerpc,
+ bfd_mach_ppc_rs64ii,
+ "powerpc",
+ "powerpc:rs64ii",
+ 3,
+ FALSE, /* not the default */
+ powerpc_compatible,
+ bfd_default_scan,
+ bfd_arch_default_fill,
+ &bfd_powerpc_archs[11]
+ },
+ {
+ 64, /* 64 bits in a word */
+ 64, /* 64 bits in an address */
+ 8, /* 8 bits in a byte */
+ bfd_arch_powerpc,
+ bfd_mach_ppc_rs64iii,
+ "powerpc",
+ "powerpc:rs64iii",
+ 3,
+ FALSE, /* not the default */
+ powerpc_compatible,
+ bfd_default_scan,
+ bfd_arch_default_fill,
+ &bfd_powerpc_archs[12]
+ },
+ {
+ 32, /* 32 bits in a word */
+ 32, /* 32 bits in an address */
+ 8, /* 8 bits in a byte */
+ bfd_arch_powerpc,
+ bfd_mach_ppc_7400,
+ "powerpc",
+ "powerpc:7400",
+ 3,
+ FALSE, /* not the default */
+ powerpc_compatible,
+ bfd_default_scan,
+ bfd_arch_default_fill,
+ &bfd_powerpc_archs[13]
+ },
+ {
+ 32, /* 32 bits in a word */
+ 32, /* 32 bits in an address */
+ 8, /* 8 bits in a byte */
+ bfd_arch_powerpc,
+ bfd_mach_ppc_e500,
+ "powerpc",
+ "powerpc:e500",
+ 3,
+ FALSE,
+ powerpc_compatible,
+ bfd_default_scan,
+ bfd_arch_default_fill,
+ &bfd_powerpc_archs[14]
+ },
+ {
+ 32, /* 32 bits in a word */
+ 32, /* 32 bits in an address */
+ 8, /* 8 bits in a byte */
+ bfd_arch_powerpc,
+ bfd_mach_ppc_e500mc,
+ "powerpc",
+ "powerpc:e500mc",
+ 3,
+ FALSE, /* not the default */
+ powerpc_compatible,
+ bfd_default_scan,
+ bfd_arch_default_fill,
+ &bfd_powerpc_archs[15]
+ },
+ {
+ 64, /* 64 bits in a word */
+ 64, /* 64 bits in an address */
+ 8, /* 8 bits in a byte */
+ bfd_arch_powerpc,
+ bfd_mach_ppc_e500mc64,
+ "powerpc",
+ "powerpc:e500mc64",
+ 3,
+ FALSE, /* not the default */
+ powerpc_compatible,
+ bfd_default_scan,
+ bfd_arch_default_fill,
+ &bfd_powerpc_archs[16]
+ },
+ {
+ 32, /* 32 bits in a word */
+ 32, /* 32 bits in an address */
+ 8, /* 8 bits in a byte */
+ bfd_arch_powerpc,
+ bfd_mach_ppc_860,
+ "powerpc",
+ "powerpc:MPC8XX",
+ 3,
+ FALSE, /* not the default */
+ powerpc_compatible,
+ bfd_default_scan,
+ bfd_arch_default_fill,
+ &bfd_powerpc_archs[17]
+ },
+ {
+ 32, /* 32 bits in a word */
+ 32, /* 32 bits in an address */
+ 8, /* 8 bits in a byte */
+ bfd_arch_powerpc,
+ bfd_mach_ppc_750,
+ "powerpc",
+ "powerpc:750",
+ 3,
+ FALSE, /* not the default */
+ powerpc_compatible,
+ bfd_default_scan,
+ bfd_arch_default_fill,
+ &bfd_powerpc_archs[18]
+ },
+ {
+ 32, /* 32 bits in a word */
+ 32, /* 32 bits in an address */
+ 8, /* 8 bits in a byte */
+ bfd_arch_powerpc,
+ bfd_mach_ppc_titan,
+ "powerpc",
+ "powerpc:titan",
+ 3,
+ FALSE, /* not the default */
+ powerpc_compatible,
+ bfd_default_scan,
+ bfd_arch_default_fill,
+ &bfd_powerpc_archs[19]
+ },
+ {
+ 16, /* 16 or 32 bits in a word */
+ 32, /* 32 bits in an address */
+ 8, /* 8 bits in a byte */
+ bfd_arch_powerpc,
+ bfd_mach_ppc_vle,
+ "powerpc",
+ "powerpc:vle",
+ 3,
+ FALSE, /* not the default */
+ powerpc_compatible,
+ bfd_default_scan,
+ bfd_arch_default_fill,
+ &bfd_powerpc_archs[20]
+ },
+ {
+ 64, /* 64 bits in a word */
+ 64, /* 64 bits in an address */
+ 8, /* 8 bits in a byte */
+ bfd_arch_powerpc,
+ bfd_mach_ppc_e5500,
+ "powerpc",
+ "powerpc:e5500",
+ 3,
+ FALSE, /* not the default */
+ powerpc_compatible,
+ bfd_default_scan,
+ bfd_arch_default_fill,
+ &bfd_powerpc_archs[21]
+ },
+ {
+ 64, /* 64 bits in a word */
+ 64, /* 64 bits in an address */
+ 8, /* 8 bits in a byte */
+ bfd_arch_powerpc,
+ bfd_mach_ppc_e6500,
+ "powerpc",
+ "powerpc:e6500",
+ 3,
+ FALSE, /* not the default */
+ powerpc_compatible,
+ bfd_default_scan,
+ bfd_arch_default_fill,
+ 0
+ }
+};
diff --git a/bfd/cpu-rl78.c b/bfd/cpu-rl78.c
new file mode 100644
index 0000000..2b30626
--- /dev/null
+++ b/bfd/cpu-rl78.c
@@ -0,0 +1,40 @@
+/* BFD support for the RL78 processor.
+ Copyright (C) 2011-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+
+const bfd_arch_info_type bfd_rl78_arch =
+{
+ 32, /* Bits per word. */
+ 32, /* Bits per address. */
+ 8, /* Bits per byte. */
+ bfd_arch_rl78, /* Architecture. */
+ bfd_mach_rl78, /* Machine. */
+ "rl78", /* Architecture name. */
+ "rl78", /* Printable name. */
+ 4, /* Section align power. */
+ TRUE, /* The default ? */
+ bfd_default_compatible, /* Architecture comparison fn. */
+ bfd_default_scan, /* String to architecture convert fn. */
+ bfd_arch_default_fill, /* Default fill. */
+ NULL /* Next in list. */
+};
diff --git a/bfd/cpu-rs6000.c b/bfd/cpu-rs6000.c
new file mode 100644
index 0000000..b8022c3
--- /dev/null
+++ b/bfd/cpu-rs6000.c
@@ -0,0 +1,113 @@
+/* BFD back-end for rs6000 support
+ Copyright (C) 1990-2014 Free Software Foundation, Inc.
+ Written by Mimi Phuong-Thao Vo 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+
+/* The RS/6000 architecture is compatible with the PowerPC common
+ architecture. */
+
+static const bfd_arch_info_type *
+rs6000_compatible (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 (a->mach == bfd_mach_rs6k)
+ return b;
+ 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_rs6000,
+ bfd_mach_rs6k_rs1,
+ "rs6000",
+ "rs6000:rs1",
+ 3,
+ FALSE, /* not the default */
+ rs6000_compatible,
+ bfd_default_scan,
+ bfd_arch_default_fill,
+ &arch_info_struct[1]
+ },
+ {
+ 32, /* 32 bits in a word */
+ 32, /* 32 bits in an address */
+ 8, /* 8 bits in a byte */
+ bfd_arch_rs6000,
+ bfd_mach_rs6k_rsc,
+ "rs6000",
+ "rs6000:rsc",
+ 3,
+ FALSE, /* not the default */
+ rs6000_compatible,
+ bfd_default_scan,
+ bfd_arch_default_fill,
+ &arch_info_struct[2]
+ },
+ {
+ 32, /* 32 bits in a word */
+ 32, /* 32 bits in an address */
+ 8, /* 8 bits in a byte */
+ bfd_arch_rs6000,
+ bfd_mach_rs6k_rs2,
+ "rs6000",
+ "rs6000:rs2",
+ 3,
+ FALSE, /* not the default */
+ rs6000_compatible,
+ bfd_default_scan,
+ bfd_arch_default_fill,
+ 0
+ }
+};
+
+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,
+ bfd_mach_rs6k, /* POWER common architecture */
+ "rs6000",
+ "rs6000:6000",
+ 3,
+ TRUE, /* the default */
+ rs6000_compatible,
+ bfd_default_scan,
+ bfd_arch_default_fill,
+ &arch_info_struct[0]
+ };
diff --git a/bfd/cpu-rx.c b/bfd/cpu-rx.c
new file mode 100644
index 0000000..677c490
--- /dev/null
+++ b/bfd/cpu-rx.c
@@ -0,0 +1,59 @@
+/* BFD support for the RX processor.
+ Copyright (C) 2008-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+
+static const bfd_arch_info_type arch_info_struct[] =
+{
+ {
+ 32, /* Bits per word. */
+ 32, /* Bits per address. */
+ 8, /* Bits per byte. */
+ bfd_arch_rx, /* Architecture. */
+ bfd_mach_rx, /* Machine. */
+ "rx", /* Architecture name. */
+ "rx", /* Printable name. */
+ 3, /* Section align power. */
+ FALSE, /* The default ? */
+ bfd_default_compatible, /* Architecture comparison fn. */
+ bfd_default_scan, /* String to architecture convert fn. */
+ bfd_arch_default_fill, /* Default fill. */
+ NULL /* Next in list. */
+ },
+};
+
+const bfd_arch_info_type bfd_rx_arch =
+{
+ 32, /* Bits per word. */
+ 32, /* Bits per address. */
+ 8, /* Bits per byte. */
+ bfd_arch_rx, /* Architecture. */
+ bfd_mach_rx, /* Machine. */
+ "rx", /* Architecture name. */
+ "rx", /* Printable name. */
+ 4, /* Section align power. */
+ TRUE, /* The default ? */
+ bfd_default_compatible, /* Architecture comparison fn. */
+ bfd_default_scan, /* String to architecture convert fn. */
+ bfd_arch_default_fill, /* Default fill. */
+ & arch_info_struct[0], /* Next in list. */
+};
diff --git a/bfd/cpu-s390.c b/bfd/cpu-s390.c
new file mode 100644
index 0000000..badf39d
--- /dev/null
+++ b/bfd/cpu-s390.c
@@ -0,0 +1,66 @@
+/* BFD support for the s390 processor.
+ Copyright (C) 2000-2014 Free Software Foundation, Inc.
+ Contributed by Carl B. Pedersen and Martin Schwidefsky.
+
+ This file is part of BFD, the Binary File Descriptor library.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
+ 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+
+const bfd_arch_info_type bfd_s390_64_arch =
+{
+ 64, /* bits in a word */
+ 64, /* bits in an address */
+ 8, /* bits in a byte */
+ bfd_arch_s390,
+ bfd_mach_s390_64,
+ "s390",
+ "s390:64-bit",
+ 3, /* section alignment power */
+#if BFD_DEFAULT_TARGET_SIZE == 64
+ TRUE, /* the default */
+#else
+ FALSE, /* the default */
+#endif
+ bfd_default_compatible,
+ bfd_default_scan,
+ bfd_arch_default_fill,
+ NULL
+};
+
+const bfd_arch_info_type bfd_s390_arch =
+{
+ 32, /* bits in a word */
+ 32, /* bits in an address */
+ 8, /* bits in a byte */
+ bfd_arch_s390,
+ bfd_mach_s390_31,
+ "s390",
+ "s390:31-bit",
+ 3, /* section alignment power */
+#if BFD_DEFAULT_TARGET_SIZE == 64
+ FALSE, /* the default */
+#else
+ TRUE, /* the default */
+#endif
+ bfd_default_compatible,
+ bfd_default_scan,
+ bfd_arch_default_fill,
+ &bfd_s390_64_arch
+};
diff --git a/bfd/cpu-score.c b/bfd/cpu-score.c
new file mode 100644
index 0000000..42db5b3
--- /dev/null
+++ b/bfd/cpu-score.c
@@ -0,0 +1,69 @@
+/* BFD support for the score processor
+ Copyright (C) 2006-2014 Free Software Foundation, Inc.
+ Contributed by
+ Brain.lin (brain.lin@sunplusct.com)
+ Mei Ligang (ligang@sunnorth.com.cn)
+ Pei-Lin Tsai (pltsai@sunplus.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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+
+/* This routine is provided two arch_infos and works out which Score
+ machine which would be compatible with both and returns a pointer
+ to its info structure. */
+
+static const bfd_arch_info_type *
+compatible (const bfd_arch_info_type * a, const bfd_arch_info_type * b)
+{
+ /* If a & b are for different architectures we can do nothing. */
+ if (a->arch != b->arch)
+ return NULL;
+
+ if (a->mach != b->mach)
+ return NULL;
+
+ return a;
+}
+
+#define N(addr_bits, machine, print, default, next) \
+{ \
+ 32, /* 16 bits in a word. */ \
+ 32, /* Bits in an address. */ \
+ 8, /* 8 bits in a byte. */ \
+ bfd_arch_score, \
+ machine, /* Machine number. */ \
+ "score", /* Architecture name. */ \
+ print, /* Printable name. */ \
+ 4, /* Section align power. */ \
+ default, /* The default machine. */ \
+ compatible, \
+ bfd_default_scan, \
+ bfd_arch_default_fill, \
+ next \
+}
+
+static const bfd_arch_info_type arch_info_struct[] =
+{
+ N (16, bfd_mach_score3, "score3", FALSE, NULL),
+};
+
+const bfd_arch_info_type bfd_score_arch =
+ N (16, bfd_mach_score7, "score7", TRUE, & arch_info_struct[0]);
diff --git a/bfd/cpu-sh.c b/bfd/cpu-sh.c
new file mode 100644
index 0000000..2a8b931
--- /dev/null
+++ b/bfd/cpu-sh.c
@@ -0,0 +1,545 @@
+/* BFD library support routines for the Renesas / SuperH SH architecture.
+ Copyright (C) 1993-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+#include "../opcodes/sh-opc.h"
+
+#define SH_NEXT arch_info_struct + 0
+#define SH2_NEXT arch_info_struct + 1
+#define SH2E_NEXT arch_info_struct + 2
+#define SH_DSP_NEXT arch_info_struct + 3
+#define SH3_NEXT arch_info_struct + 4
+#define SH3_NOMMU_NEXT arch_info_struct + 5
+#define SH3_DSP_NEXT arch_info_struct + 6
+#define SH3E_NEXT arch_info_struct + 7
+#define SH4_NEXT arch_info_struct + 8
+#define SH4A_NEXT arch_info_struct + 9
+#define SH4AL_DSP_NEXT arch_info_struct + 10
+#define SH4_NOFPU_NEXT arch_info_struct + 11
+#define SH4_NOMMU_NOFPU_NEXT arch_info_struct + 12
+#define SH4A_NOFPU_NEXT arch_info_struct + 13
+#define SH2A_NEXT arch_info_struct + 14
+#define SH2A_NOFPU_NEXT arch_info_struct + 15
+#define SH2A_NOFPU_OR_SH4_NOMMU_NOFPU_NEXT arch_info_struct + 16
+#define SH2A_NOFPU_OR_SH3_NOMMU_NEXT arch_info_struct + 17
+#define SH2A_OR_SH4_NEXT arch_info_struct + 18
+#define SH2A_OR_SH3E_NEXT arch_info_struct + 19
+#define SH64_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_sh2,
+ "sh", /* Architecture name. */
+ "sh2", /* Machine name. */
+ 1,
+ FALSE, /* Not the default. */
+ bfd_default_compatible,
+ bfd_default_scan,
+ bfd_arch_default_fill,
+ SH2_NEXT
+ },
+ {
+ 32, /* 32 bits in a word. */
+ 32, /* 32 bits in an address. */
+ 8, /* 8 bits in a byte. */
+ bfd_arch_sh,
+ bfd_mach_sh2e,
+ "sh", /* Architecture name. */
+ "sh2e", /* Machine name. */
+ 1,
+ FALSE, /* Not the default. */
+ bfd_default_compatible,
+ bfd_default_scan,
+ bfd_arch_default_fill,
+ SH2E_NEXT
+ },
+ {
+ 32, /* 32 bits in a word. */
+ 32, /* 32 bits in an address. */
+ 8, /* 8 bits in a byte. */
+ bfd_arch_sh,
+ bfd_mach_sh_dsp,
+ "sh", /* Architecture name. */
+ "sh-dsp", /* Machine name. */
+ 1,
+ FALSE, /* Not the default. */
+ bfd_default_compatible,
+ bfd_default_scan,
+ bfd_arch_default_fill,
+ SH_DSP_NEXT
+ },
+ {
+ 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", /* Architecture name. */
+ "sh3", /* Machine name. */
+ 1,
+ FALSE, /* Not the default. */
+ bfd_default_compatible,
+ bfd_default_scan,
+ bfd_arch_default_fill,
+ 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_sh3_nommu,
+ "sh", /* Architecture name. */
+ "sh3-nommu", /* Machine name. */
+ 1,
+ FALSE, /* Not the default. */
+ bfd_default_compatible,
+ bfd_default_scan,
+ bfd_arch_default_fill,
+ SH3_NOMMU_NEXT
+ },
+ {
+ 32, /* 32 bits in a word. */
+ 32, /* 32 bits in an address. */
+ 8, /* 8 bits in a byte. */
+ bfd_arch_sh,
+ bfd_mach_sh3_dsp,
+ "sh", /* Architecture name. */
+ "sh3-dsp", /* Machine name. */
+ 1,
+ FALSE, /* Not the default. */
+ bfd_default_compatible,
+ bfd_default_scan,
+ bfd_arch_default_fill,
+ SH3_DSP_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", /* Architecture name. */
+ "sh3e", /* Machine name. */
+ 1,
+ FALSE, /* Not the default. */
+ bfd_default_compatible,
+ bfd_default_scan,
+ bfd_arch_default_fill,
+ SH3E_NEXT
+ },
+ {
+ 32, /* 32 bits in a word. */
+ 32, /* 32 bits in an address. */
+ 8, /* 8 bits in a byte. */
+ bfd_arch_sh,
+ bfd_mach_sh4,
+ "sh", /* Architecture name. */
+ "sh4", /* Machine name. */
+ 1,
+ FALSE, /* Not the default. */
+ bfd_default_compatible,
+ bfd_default_scan,
+ bfd_arch_default_fill,
+ SH4_NEXT
+ },
+ {
+ 32, /* 32 bits in a word. */
+ 32, /* 32 bits in an address. */
+ 8, /* 8 bits in a byte. */
+ bfd_arch_sh,
+ bfd_mach_sh4a,
+ "sh", /* Architecture name. */
+ "sh4a", /* Machine name. */
+ 1,
+ FALSE, /* Not the default. */
+ bfd_default_compatible,
+ bfd_default_scan,
+ bfd_arch_default_fill,
+ SH4A_NEXT
+ },
+ {
+ 32, /* 32 bits in a word. */
+ 32, /* 32 bits in an address. */
+ 8, /* 8 bits in a byte. */
+ bfd_arch_sh,
+ bfd_mach_sh4al_dsp,
+ "sh", /* Architecture name. */
+ "sh4al-dsp", /* Machine name. */
+ 1,
+ FALSE, /* Not the default. */
+ bfd_default_compatible,
+ bfd_default_scan,
+ bfd_arch_default_fill,
+ SH4AL_DSP_NEXT
+ },
+ {
+ 32, /* 32 bits in a word. */
+ 32, /* 32 bits in an address. */
+ 8, /* 8 bits in a byte. */
+ bfd_arch_sh,
+ bfd_mach_sh4_nofpu,
+ "sh", /* Architecture name. */
+ "sh4-nofpu", /* Machine name. */
+ 1,
+ FALSE, /* Not the default. */
+ bfd_default_compatible,
+ bfd_default_scan,
+ bfd_arch_default_fill,
+ SH4_NOFPU_NEXT
+ },
+ {
+ 32, /* 32 bits in a word. */
+ 32, /* 32 bits in an address. */
+ 8, /* 8 bits in a byte. */
+ bfd_arch_sh,
+ bfd_mach_sh4_nommu_nofpu,
+ "sh", /* Architecture name. */
+ "sh4-nommu-nofpu", /* Machine name. */
+ 1,
+ FALSE, /* Not the default. */
+ bfd_default_compatible,
+ bfd_default_scan,
+ bfd_arch_default_fill,
+ SH4_NOMMU_NOFPU_NEXT
+ },
+ {
+ 32, /* 32 bits in a word. */
+ 32, /* 32 bits in an address. */
+ 8, /* 8 bits in a byte. */
+ bfd_arch_sh,
+ bfd_mach_sh4a_nofpu,
+ "sh", /* Architecture name. */
+ "sh4a-nofpu", /* Machine name. */
+ 1,
+ FALSE, /* Not the default. */
+ bfd_default_compatible,
+ bfd_default_scan,
+ bfd_arch_default_fill,
+ SH4A_NOFPU_NEXT
+ },
+ {
+ 32, /* 32 bits in a word. */
+ 32, /* 32 bits in an address. */
+ 8, /* 8 bits in a byte. */
+ bfd_arch_sh,
+ bfd_mach_sh2a,
+ "sh", /* Architecture name. */
+ "sh2a", /* Machine name. */
+ 1,
+ FALSE, /* Not the default. */
+ bfd_default_compatible,
+ bfd_default_scan,
+ bfd_arch_default_fill,
+ SH2A_NEXT
+ },
+ {
+ 32, /* 32 bits in a word. */
+ 32, /* 32 bits in an address. */
+ 8, /* 8 bits in a byte. */
+ bfd_arch_sh,
+ bfd_mach_sh2a_nofpu,
+ "sh", /* Architecture name. */
+ "sh2a-nofpu", /* Machine name. */
+ 1,
+ FALSE, /* Not the default. */
+ bfd_default_compatible,
+ bfd_default_scan,
+ bfd_arch_default_fill,
+ SH2A_NOFPU_NEXT
+ },
+ {
+ 32, /* 32 bits in a word. */
+ 32, /* 32 bits in an address. */
+ 8, /* 8 bits in a byte. */
+ bfd_arch_sh,
+ bfd_mach_sh2a_nofpu_or_sh4_nommu_nofpu,
+ "sh", /* Architecture name. */
+ "sh2a-nofpu-or-sh4-nommu-nofpu", /* Machine name. */
+ 1,
+ FALSE, /* Not the default. */
+ bfd_default_compatible,
+ bfd_default_scan,
+ bfd_arch_default_fill,
+ SH2A_NOFPU_OR_SH4_NOMMU_NOFPU_NEXT
+ },
+ {
+ 32, /* 32 bits in a word. */
+ 32, /* 32 bits in an address. */
+ 8, /* 8 bits in a byte. */
+ bfd_arch_sh,
+ bfd_mach_sh2a_nofpu_or_sh3_nommu,
+ "sh", /* Architecture name. . */
+ "sh2a-nofpu-or-sh3-nommu", /* Machine name. */
+ 1,
+ FALSE, /* Not the default. */
+ bfd_default_compatible,
+ bfd_default_scan,
+ bfd_arch_default_fill,
+ SH2A_NOFPU_OR_SH3_NOMMU_NEXT
+ },
+ {
+ 32, /* 32 bits in a word. */
+ 32, /* 32 bits in an address. */
+ 8, /* 8 bits in a byte. */
+ bfd_arch_sh,
+ bfd_mach_sh2a_or_sh4,
+ "sh", /* Architecture name. */
+ "sh2a-or-sh4", /* Machine name. */
+ 1,
+ FALSE, /* Not the default. */
+ bfd_default_compatible,
+ bfd_default_scan,
+ bfd_arch_default_fill,
+ SH2A_OR_SH4_NEXT
+ },
+ {
+ 32, /* 32 bits in a word. */
+ 32, /* 32 bits in an address. */
+ 8, /* 8 bits in a byte. */
+ bfd_arch_sh,
+ bfd_mach_sh2a_or_sh3e,
+ "sh", /* Architecture name. */
+ "sh2a-or-sh3e", /* Machine name. */
+ 1,
+ FALSE, /* Not the default. */
+ bfd_default_compatible,
+ bfd_default_scan,
+ bfd_arch_default_fill,
+ SH2A_OR_SH3E_NEXT
+ },
+ {
+ 64, /* 64 bits in a word. */
+ 64, /* 64 bits in an address. */
+ 8, /* 8 bits in a byte. */
+ bfd_arch_sh,
+ bfd_mach_sh5,
+ "sh", /* Architecture name. */
+ "sh5", /* Machine name. */
+ 1,
+ FALSE, /* Not the default. */
+ bfd_default_compatible,
+ bfd_default_scan,
+ bfd_arch_default_fill,
+ SH64_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", /* Architecture name. */
+ "sh", /* Machine name. */
+ 1,
+ TRUE, /* The default machine. */
+ bfd_default_compatible,
+ bfd_default_scan,
+ bfd_arch_default_fill,
+ SH_NEXT
+};
+
+
+/* This table defines the mappings from the BFD internal numbering
+ system to the opcodes internal flags system.
+ It is used by the functions defined below.
+ The prototypes for these SH specific functions are found in
+ sh-opc.h . */
+
+static struct { unsigned long bfd_mach, arch, arch_up; } bfd_to_arch_table[] =
+{
+ { bfd_mach_sh, arch_sh1, arch_sh_up },
+ { bfd_mach_sh2, arch_sh2, arch_sh2_up },
+ { bfd_mach_sh2e, arch_sh2e, arch_sh2e_up },
+ { bfd_mach_sh_dsp, arch_sh_dsp, arch_sh_dsp_up },
+ { bfd_mach_sh2a, arch_sh2a, arch_sh2a_up },
+ { bfd_mach_sh2a_nofpu, arch_sh2a_nofpu, arch_sh2a_nofpu_up },
+
+ { bfd_mach_sh2a_nofpu_or_sh4_nommu_nofpu, arch_sh2a_nofpu_or_sh4_nommu_nofpu, arch_sh2a_nofpu_or_sh4_nommu_nofpu_up },
+ { bfd_mach_sh2a_nofpu_or_sh3_nommu, arch_sh2a_nofpu_or_sh3_nommu, arch_sh2a_nofpu_or_sh3_nommu_up },
+ { bfd_mach_sh2a_or_sh4, arch_sh2a_or_sh4, arch_sh2a_or_sh4_up },
+ { bfd_mach_sh2a_or_sh3e, arch_sh2a_or_sh3e, arch_sh2a_or_sh3e_up },
+
+ { bfd_mach_sh3, arch_sh3, arch_sh3_up },
+ { bfd_mach_sh3_nommu, arch_sh3_nommu, arch_sh3_nommu_up },
+ { bfd_mach_sh3_dsp, arch_sh3_dsp, arch_sh3_dsp_up },
+ { bfd_mach_sh3e, arch_sh3e, arch_sh3e_up },
+ { bfd_mach_sh4, arch_sh4, arch_sh4_up },
+ { bfd_mach_sh4a, arch_sh4a, arch_sh4a_up },
+ { bfd_mach_sh4al_dsp, arch_sh4al_dsp, arch_sh4al_dsp_up },
+ { bfd_mach_sh4_nofpu, arch_sh4_nofpu, arch_sh4_nofpu_up },
+ { bfd_mach_sh4_nommu_nofpu, arch_sh4_nommu_nofpu, arch_sh4_nommu_nofpu_up },
+ { bfd_mach_sh4a_nofpu, arch_sh4a_nofpu, arch_sh4a_nofpu_up },
+ { 0, 0, 0 } /* Terminator. */
+};
+
+
+/* Convert a BFD mach number into the right opcodes arch flags
+ using the table above. */
+
+unsigned int
+sh_get_arch_from_bfd_mach (unsigned long mach)
+{
+ int i = 0;
+
+ while (bfd_to_arch_table[i].bfd_mach != 0)
+ if (bfd_to_arch_table[i].bfd_mach == mach)
+ return bfd_to_arch_table[i].arch;
+ else
+ i++;
+
+ /* Machine not found. */
+ BFD_FAIL();
+
+ return SH_ARCH_UNKNOWN_ARCH;
+}
+
+
+/* Convert a BFD mach number into a set of opcodes arch flags
+ describing all the compatible architectures (i.e. arch_up)
+ using the table above. */
+
+unsigned int
+sh_get_arch_up_from_bfd_mach (unsigned long mach)
+{
+ int i = 0;
+
+ while (bfd_to_arch_table[i].bfd_mach != 0)
+ if (bfd_to_arch_table[i].bfd_mach == mach)
+ return bfd_to_arch_table[i].arch_up;
+ else
+ i++;
+
+ /* Machine not found. */
+ BFD_FAIL();
+
+ return SH_ARCH_UNKNOWN_ARCH;
+}
+
+
+/* Convert an arbitary arch_set - not necessarily corresponding
+ directly to anything in the table above - to the most generic
+ architecture which supports all the required features, and
+ return the corresponding BFD mach. */
+
+unsigned long
+sh_get_bfd_mach_from_arch_set (unsigned int arch_set)
+{
+ unsigned long result = 0;
+ unsigned int best = ~arch_set;
+ unsigned int co_mask = ~0;
+ int i = 0;
+
+ /* If arch_set permits variants with no coprocessor then do not allow
+ the other irrelevant co-processor bits to influence the choice:
+ e.g. if dsp is disallowed by arch_set, then the algorithm would
+ prefer fpu variants over nofpu variants because they also disallow
+ dsp - even though the nofpu would be the most correct choice.
+ This assumes that EVERY fpu/dsp variant has a no-coprocessor
+ counter-part, or their non-fpu/dsp instructions do not have the
+ no co-processor bit set. */
+ if (arch_set & arch_sh_no_co)
+ co_mask = ~(arch_sh_sp_fpu | arch_sh_dp_fpu | arch_sh_has_dsp);
+
+ while (bfd_to_arch_table[i].bfd_mach != 0)
+ {
+ unsigned int try = bfd_to_arch_table[i].arch_up & co_mask;
+
+ /* Conceptually: Find the architecture with the least number
+ of extra features or, if they have the same number, then
+ the greatest number of required features. Disregard
+ architectures where the required features alone do
+ not describe a valid architecture. */
+ if (((try & ~arch_set) < (best & ~arch_set)
+ || ((try & ~arch_set) == (best & ~arch_set)
+ && (~try & arch_set) < (~best & arch_set)))
+ && SH_MERGE_ARCH_SET_VALID (try, arch_set))
+ {
+ result = bfd_to_arch_table[i].bfd_mach;
+ best = try;
+ }
+
+ i++;
+ }
+
+ /* This might happen if a new variant is added to sh-opc.h
+ but no corresponding entry is added to the table above. */
+ BFD_ASSERT (result != 0);
+
+ return result;
+}
+
+
+/* Merge the architecture type of two BFD files, such that the
+ resultant architecture supports all the features required
+ by the two input BFDs.
+ If the input BFDs are multually incompatible - i.e. one uses
+ DSP while the other uses FPU - or there is no known architecture
+ that fits the requirements then an error is emitted. */
+
+bfd_boolean
+sh_merge_bfd_arch (bfd *ibfd, bfd *obfd)
+{
+ unsigned int old_arch, new_arch, merged_arch;
+
+ if (! _bfd_generic_verify_endian_match (ibfd, obfd))
+ return FALSE;
+
+ old_arch = sh_get_arch_up_from_bfd_mach (bfd_get_mach (obfd));
+ new_arch = sh_get_arch_up_from_bfd_mach (bfd_get_mach (ibfd));
+
+ merged_arch = SH_MERGE_ARCH_SET (old_arch, new_arch);
+
+ if (!SH_VALID_CO_ARCH_SET (merged_arch))
+ {
+ (*_bfd_error_handler)
+ ("%B: uses %s instructions while previous modules use %s instructions",
+ ibfd,
+ SH_ARCH_SET_HAS_DSP (new_arch) ? "dsp" : "floating point",
+ SH_ARCH_SET_HAS_DSP (new_arch) ? "floating point" : "dsp");
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+ else if (!SH_VALID_ARCH_SET (merged_arch))
+ {
+ (*_bfd_error_handler)
+ ("internal error: merge of architecture '%s' with architecture '%s' produced unknown architecture\n",
+ bfd_printable_name (obfd),
+ bfd_printable_name (ibfd));
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+
+ bfd_default_set_arch_mach (obfd, bfd_arch_sh,
+ sh_get_bfd_mach_from_arch_set (merged_arch));
+
+ return TRUE;
+}
diff --git a/bfd/cpu-sparc.c b/bfd/cpu-sparc.c
new file mode 100644
index 0000000..f215c67
--- /dev/null
+++ b/bfd/cpu-sparc.c
@@ -0,0 +1,179 @@
+/* BFD support for the SPARC architecture.
+ Copyright (C) 1992-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+
+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,
+ bfd_default_compatible,
+ bfd_default_scan,
+ bfd_arch_default_fill,
+ &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,
+ bfd_default_compatible,
+ bfd_default_scan,
+ bfd_arch_default_fill,
+ &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,
+ bfd_default_compatible,
+ bfd_default_scan,
+ bfd_arch_default_fill,
+ &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,
+ bfd_default_compatible,
+ bfd_default_scan,
+ bfd_arch_default_fill,
+ &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,
+ bfd_default_compatible,
+ bfd_default_scan,
+ bfd_arch_default_fill,
+ &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,
+ bfd_default_compatible,
+ bfd_default_scan,
+ bfd_arch_default_fill,
+ &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,
+ bfd_default_compatible,
+ bfd_default_scan,
+ bfd_arch_default_fill,
+ &arch_info_struct[7],
+ },
+ {
+ 32, /* bits in a word */
+ 32, /* bits in an address */
+ 8, /* bits in a byte */
+ bfd_arch_sparc,
+ bfd_mach_sparc_v8plusb,
+ "sparc",
+ "sparc:v8plusb",
+ 3,
+ FALSE,
+ bfd_default_compatible,
+ bfd_default_scan,
+ bfd_arch_default_fill,
+ &arch_info_struct[8],
+ },
+ {
+ 64, /* bits in a word */
+ 64, /* bits in an address */
+ 8, /* bits in a byte */
+ bfd_arch_sparc,
+ bfd_mach_sparc_v9b,
+ "sparc",
+ "sparc:v9b",
+ 3,
+ FALSE,
+ bfd_default_compatible,
+ bfd_default_scan,
+ bfd_arch_default_fill,
+ 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 */
+ bfd_default_compatible,
+ bfd_default_scan,
+ bfd_arch_default_fill,
+ &arch_info_struct[0],
+ };
diff --git a/bfd/cpu-spu.c b/bfd/cpu-spu.c
new file mode 100644
index 0000000..3e0db39
--- /dev/null
+++ b/bfd/cpu-spu.c
@@ -0,0 +1,55 @@
+/* Copyright (C) 2006-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+
+
+static const bfd_arch_info_type *
+spu_compatible (const bfd_arch_info_type *a, const bfd_arch_info_type *b)
+{
+ BFD_ASSERT (a->arch == bfd_arch_spu);
+ switch (b->arch)
+ {
+ default:
+ return NULL;
+ case bfd_arch_spu:
+ return bfd_default_compatible (a, b);
+ }
+ /*NOTREACHED*/
+}
+
+const bfd_arch_info_type bfd_spu_arch[] =
+{
+ {
+ 32, /* 32 bits in a word */
+ 32, /* 32 bits in an address */
+ 8, /* 8 bits in a byte */
+ bfd_arch_spu, /* architecture */
+ bfd_mach_spu, /* machine */
+ "spu", /* architecture name */
+ "spu:256K", /* printable name */
+ 3, /* aligned power */
+ TRUE, /* the default machine for the architecture */
+ spu_compatible, /* the spu is only compatible with itself, see above */
+ bfd_default_scan,
+ bfd_arch_default_fill,
+ 0, /* next -- there are none! */
+ }
+};
diff --git a/bfd/cpu-tic30.c b/bfd/cpu-tic30.c
new file mode 100644
index 0000000..f866b89
--- /dev/null
+++ b/bfd/cpu-tic30.c
@@ -0,0 +1,40 @@
+/* BFD support for the Texas Instruments TMS320C30 architecture.
+ Copyright (C) 1998-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
+ 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.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,
+ bfd_arch_default_fill,
+ 0,
+};
diff --git a/bfd/cpu-tic4x.c b/bfd/cpu-tic4x.c
new file mode 100644
index 0000000..551afe8
--- /dev/null
+++ b/bfd/cpu-tic4x.c
@@ -0,0 +1,83 @@
+/* bfd back-end for TMS320C[34]x support
+ Copyright (C) 1996-2014 Free Software Foundation, Inc.
+
+ Contributed by Michael Hayes (m.hayes@elec.canterbury.ac.nz)
+
+ This file is part of BFD, the Binary File Descriptor library.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+
+static bfd_boolean
+tic4x_scan (const struct bfd_arch_info *info,
+ const char *string)
+{
+ /* Allow strings of form [ti][Cc][34][0-9], let's not be too picky
+ about strange numbered machines in C3x or C4x series. */
+ if (string[0] == 't' && string[1] == 'i')
+ string += 2;
+ if (*string == 'C' || *string == 'c')
+ string++;
+ if (string[1] < '0' && string[1] > '9')
+ return FALSE;
+
+ if (*string == '3')
+ return (info->mach == bfd_mach_tic3x);
+ else if (*string == '4')
+ return info->mach == bfd_mach_tic4x;
+
+ return FALSE;
+}
+
+
+const bfd_arch_info_type bfd_tic3x_arch =
+ {
+ 32, /* 32 bits in a word. */
+ 32, /* 32 bits in an address. */
+ 32, /* 32 bits in a byte. */
+ bfd_arch_tic4x,
+ bfd_mach_tic3x, /* Machine number. */
+ "tic3x", /* Architecture name. */
+ "tms320c3x", /* Printable name. */
+ 0, /* Alignment power. */
+ FALSE, /* Not the default architecture. */
+ bfd_default_compatible,
+ tic4x_scan,
+ bfd_arch_default_fill,
+ 0
+ };
+
+const bfd_arch_info_type bfd_tic4x_arch =
+ {
+ 32, /* 32 bits in a word. */
+ 32, /* 32 bits in an address. */
+ 32, /* 32 bits in a byte. */
+ bfd_arch_tic4x,
+ bfd_mach_tic4x, /* Machine number. */
+ "tic4x", /* Architecture name. */
+ "tms320c4x", /* Printable name. */
+ 0, /* Alignment power. */
+ TRUE, /* The default architecture. */
+ bfd_default_compatible,
+ tic4x_scan,
+ bfd_arch_default_fill,
+ &bfd_tic3x_arch,
+ };
+
+
diff --git a/bfd/cpu-tic54x.c b/bfd/cpu-tic54x.c
new file mode 100644
index 0000000..0e3b56d
--- /dev/null
+++ b/bfd/cpu-tic54x.c
@@ -0,0 +1,40 @@
+/* BFD support for the Texas Instruments TMS320C54X architecture.
+ Copyright (C) 1999-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
+ 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+
+const bfd_arch_info_type bfd_tic54x_arch =
+{
+ 16, /* 16 bits in a word */
+ 16, /* 16 bits in an address (except '548) */
+ 16, /* 16 bits in a byte */
+ bfd_arch_tic54x,
+ 0, /* only 1 machine */
+ "tic54x",
+ "tms320c54x",
+ 1,
+ TRUE, /* the one and only */
+ bfd_default_compatible,
+ bfd_default_scan,
+ bfd_arch_default_fill,
+ 0,
+};
diff --git a/bfd/cpu-tic6x.c b/bfd/cpu-tic6x.c
new file mode 100644
index 0000000..ed9581c
--- /dev/null
+++ b/bfd/cpu-tic6x.c
@@ -0,0 +1,40 @@
+/* BFD support for the TI C6X processor.
+ Copyright (C) 2010-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+
+const bfd_arch_info_type bfd_tic6x_arch =
+ {
+ 32, /* 32 bits in a word. */
+ 32, /* 32 bits in an address. */
+ 8, /* 8 bits in a byte. */
+ bfd_arch_tic6x, /* Architecture. */
+ 0, /* No BFD machine numbers needed. */
+ "tic6x", /* Architecture name. */
+ "tic6x", /* Printable name. */
+ 2, /* Section alignment power. */
+ TRUE, /* Default machine for this architecture. */
+ bfd_default_compatible,
+ bfd_default_scan,
+ bfd_arch_default_fill,
+ 0,
+ };
diff --git a/bfd/cpu-tic80.c b/bfd/cpu-tic80.c
new file mode 100644
index 0000000..83995e0
--- /dev/null
+++ b/bfd/cpu-tic80.c
@@ -0,0 +1,41 @@
+/* bfd back-end for TI TMS320C80 (MVP) support
+ Copyright (C) 1996-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.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,
+ bfd_arch_default_fill,
+ NULL, /* Pointer to next in chain */
+ };
diff --git a/bfd/cpu-tilegx.c b/bfd/cpu-tilegx.c
new file mode 100644
index 0000000..f5126f5
--- /dev/null
+++ b/bfd/cpu-tilegx.c
@@ -0,0 +1,57 @@
+/* BFD support for the TILE-Gx processor.
+ Copyright (C) 2011-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+
+const bfd_arch_info_type bfd_tilegx32_arch =
+ {
+ 32, /* 32 bits in a word */
+ 32, /* 32 bits in an address */
+ 8, /* 8 bits in a byte */
+ bfd_arch_tilegx,
+ bfd_mach_tilegx32,
+ "tilegx32",
+ "tilegx32",
+ 3,
+ FALSE,
+ bfd_default_compatible,
+ bfd_default_scan,
+ bfd_arch_default_fill,
+ 0,
+ };
+
+const bfd_arch_info_type bfd_tilegx_arch =
+ {
+ 64, /* 64 bits in a word */
+ 64, /* 64 bits in an address */
+ 8, /* 8 bits in a byte */
+ bfd_arch_tilegx,
+ bfd_mach_tilegx,
+ "tilegx",
+ "tilegx",
+ 3,
+ TRUE,
+ bfd_default_compatible,
+ bfd_default_scan,
+ bfd_arch_default_fill,
+ &bfd_tilegx32_arch,
+ };
diff --git a/bfd/cpu-tilepro.c b/bfd/cpu-tilepro.c
new file mode 100644
index 0000000..6be1d7b
--- /dev/null
+++ b/bfd/cpu-tilepro.c
@@ -0,0 +1,40 @@
+/* BFD support for the TILEPro processor.
+ Copyright (C) 2011-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+
+const bfd_arch_info_type bfd_tilepro_arch =
+ {
+ 32, /* 32 bits in a word */
+ 32, /* 32 bits in an address */
+ 8, /* 8 bits in a byte */
+ bfd_arch_tilepro,
+ bfd_mach_tilepro,
+ "tilepro",
+ "tilepro",
+ 3,
+ TRUE,
+ bfd_default_compatible,
+ bfd_default_scan,
+ bfd_arch_default_fill,
+ 0,
+ };
diff --git a/bfd/cpu-v850.c b/bfd/cpu-v850.c
new file mode 100644
index 0000000..60b6563
--- /dev/null
+++ b/bfd/cpu-v850.c
@@ -0,0 +1,46 @@
+/* BFD support for the NEC V850 processor
+ Copyright (C) 1996-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+#include "safe-ctype.h"
+
+#define N(number, print, default, next) \
+{ 32, 32, 8, bfd_arch_v850, number, "v850", print " (using old gcc ABI)", 2, default, \
+ bfd_default_compatible, bfd_default_scan, bfd_arch_default_fill, next }
+
+#define NEXT NULL
+
+static const bfd_arch_info_type arch_info_struct[] =
+{
+ N (bfd_mach_v850e3v5, "v850e3v5", FALSE, & arch_info_struct[1]),
+ N (bfd_mach_v850e3v5, "v850e2v4", FALSE, & arch_info_struct[2]),
+ N (bfd_mach_v850e2v3, "v850e2v3", FALSE, & arch_info_struct[3]),
+ N (bfd_mach_v850e2, "v850e2", FALSE, & arch_info_struct[4]),
+ N (bfd_mach_v850e1, "v850e1", FALSE, & arch_info_struct[5]),
+ N (bfd_mach_v850e, "v850e", 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-v850_rh850.c b/bfd/cpu-v850_rh850.c
new file mode 100644
index 0000000..7962845
--- /dev/null
+++ b/bfd/cpu-v850_rh850.c
@@ -0,0 +1,41 @@
+/* BFD support for the NEC V850 processor with the RH850 ABI.
+ Copyright (C) 2012-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+#include "safe-ctype.h"
+
+#define R(number, print, default, next) \
+{ 32, 32, 8, bfd_arch_v850_rh850, number, "v850", print, 2, default, \
+ bfd_default_compatible, bfd_default_scan, bfd_arch_default_fill, next }
+
+static const bfd_arch_info_type arch_info_struct[] =
+{
+ R (bfd_mach_v850e3v5, "v850e3v5", FALSE, & arch_info_struct[1]),
+ R (bfd_mach_v850e3v5, "v850e2v4", FALSE, & arch_info_struct[2]),
+ R (bfd_mach_v850e2v3, "v850e2v3", FALSE, & arch_info_struct[3]),
+ R (bfd_mach_v850e2, "v850e2", FALSE, & arch_info_struct[4]),
+ R (bfd_mach_v850e1, "v850e1", FALSE, & arch_info_struct[5]),
+ R (bfd_mach_v850e, "v850e", FALSE, NULL)
+};
+
+const bfd_arch_info_type bfd_v850_rh850_arch =
+ R (bfd_mach_v850, "v850-rh850", TRUE, & arch_info_struct[0]);
diff --git a/bfd/cpu-vax.c b/bfd/cpu-vax.c
new file mode 100644
index 0000000..225b3f4
--- /dev/null
+++ b/bfd/cpu-vax.c
@@ -0,0 +1,41 @@
+/* bfd back-end for vax support
+ Copyright (C) 1990-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.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,
+ bfd_arch_default_fill,
+ 0,
+ };
diff --git a/bfd/cpu-w65.c b/bfd/cpu-w65.c
new file mode 100644
index 0000000..f3d0d52
--- /dev/null
+++ b/bfd/cpu-w65.c
@@ -0,0 +1,52 @@
+/* BFD library support routines for the WDC 65816 architecture.
+ Copyright (C) 1995-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY 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., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+
+static bfd_boolean
+scan_mach (const struct bfd_arch_info *info ATTRIBUTE_UNUSED,
+ 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,
+ bfd_arch_default_fill,
+ 0,
+};
diff --git a/bfd/cpu-we32k.c b/bfd/cpu-we32k.c
new file mode 100644
index 0000000..5577ae8
--- /dev/null
+++ b/bfd/cpu-we32k.c
@@ -0,0 +1,41 @@
+/* bfd back-end for we32k support
+ Copyright (C) 1992-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.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 ,
+ bfd_arch_default_fill,
+ 0,
+ };
diff --git a/bfd/cpu-xc16x.c b/bfd/cpu-xc16x.c
new file mode 100644
index 0000000..cdcc4e8
--- /dev/null
+++ b/bfd/cpu-xc16x.c
@@ -0,0 +1,76 @@
+/* BFD support for the Infineon XC16X Microcontroller.
+ Copyright (C) 2006-2014 Free Software Foundation, Inc.
+ Contributed by KPIT Cummins Infosystems
+
+ This file is part of BFD, the Binary File Descriptor library.
+ Contributed by Anil Paranjpe(anilp1@kpitcummins.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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
+ 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+
+const bfd_arch_info_type xc16xs_info_struct =
+{
+ 16, /* Bits per word. */
+ 16, /* Bits per address. */
+ 8, /* Bits per byte. */
+ bfd_arch_xc16x, /* Architecture. */
+ bfd_mach_xc16xs, /* Machine. */
+ "xc16x", /* Architecture name. */
+ "xc16xs", /* Printable name. */
+ 1, /* Section alignment - 16 bit. */
+ TRUE, /* The default ? */
+ bfd_default_compatible, /* Architecture comparison fn. */
+ bfd_default_scan, /* String to architecture convert fn. */
+ bfd_arch_default_fill, /* Default fill. */
+ NULL /* Next in list. */
+};
+
+const bfd_arch_info_type xc16xl_info_struct =
+{
+ 16, /* Bits per word. */
+ 32, /* Bits per address. */
+ 8, /* Bits per byte. */
+ bfd_arch_xc16x, /* Architecture. */
+ bfd_mach_xc16xl, /* Machine. */
+ "xc16x", /* Architecture name. */
+ "xc16xl", /* Printable name. */
+ 1, /* Section alignment - 16 bit. */
+ TRUE, /* The default ? */
+ bfd_default_compatible, /* Architecture comparison fn. */
+ bfd_default_scan, /* String to architecture convert fn. */
+ bfd_arch_default_fill, /* Default fill. */
+ & xc16xs_info_struct /* Next in list. */
+};
+
+const bfd_arch_info_type bfd_xc16x_arch =
+{
+ 16, /* Bits per word. */
+ 16, /* Bits per address. */
+ 8, /* Bits per byte. */
+ bfd_arch_xc16x, /* Architecture. */
+ bfd_mach_xc16x, /* Machine. */
+ "xc16x", /* Architecture name. */
+ "xc16x", /* Printable name. */
+ 1, /* Section alignment - 16 bit. */
+ TRUE, /* The default ? */
+ bfd_default_compatible, /* Architecture comparison fn. */
+ bfd_default_scan, /* String to architecture convert fn. */
+ bfd_arch_default_fill, /* Default fill. */
+ & xc16xl_info_struct /* Next in list. */
+};
diff --git a/bfd/cpu-xgate.c b/bfd/cpu-xgate.c
new file mode 100644
index 0000000..f8bfdf9
--- /dev/null
+++ b/bfd/cpu-xgate.c
@@ -0,0 +1,40 @@
+/* BFD support for the Freescale XGATE processor
+ Copyright (C) 2010-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+
+const bfd_arch_info_type bfd_xgate_arch =
+{
+ 16, /* 16 bits in a word. */
+ 32, /* 32 bits used as 16 bit address and PPAGE value. */
+ 8, /* 8 bits in a byte. */
+ bfd_arch_xgate,
+ bfd_mach_xgate,
+ "xgate",
+ "xgate",
+ 4, /* Section alignment power. */
+ TRUE,
+ bfd_default_compatible,
+ bfd_default_scan,
+ bfd_arch_default_fill,
+ 0,
+};
diff --git a/bfd/cpu-xstormy16.c b/bfd/cpu-xstormy16.c
new file mode 100644
index 0000000..2e2578b
--- /dev/null
+++ b/bfd/cpu-xstormy16.c
@@ -0,0 +1,40 @@
+/* BFD support for the XSTORMY16 processor.
+ Copyright (C) 2001-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+
+const bfd_arch_info_type bfd_xstormy16_arch =
+{
+ 16, /* bits per word */
+ 32, /* bits per address */
+ 8, /* bits per byte */
+ bfd_arch_xstormy16, /* architecture */
+ bfd_mach_xstormy16, /* machine */
+ "xstormy16", /* architecture name */
+ "xstormy16", /* printable name */
+ 2, /* section align power */
+ TRUE, /* the default ? */
+ bfd_default_compatible, /* architecture comparison fn */
+ bfd_default_scan, /* string to architecture convert fn */
+ bfd_arch_default_fill, /* Default fill. */
+ NULL /* next in list */
+};
diff --git a/bfd/cpu-xtensa.c b/bfd/cpu-xtensa.c
new file mode 100644
index 0000000..5eb02e9
--- /dev/null
+++ b/bfd/cpu-xtensa.c
@@ -0,0 +1,40 @@
+/* BFD support for the Xtensa processor.
+ Copyright (C) 2003-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+
+const bfd_arch_info_type bfd_xtensa_arch =
+{
+ 32, /* Bits per word. */
+ 32, /* Bits per address. */
+ 8, /* Bits per byte. */
+ bfd_arch_xtensa, /* Architecture. */
+ bfd_mach_xtensa, /* Machine. */
+ "xtensa", /* Architecture name. */
+ "xtensa", /* Printable name. */
+ 4, /* Section align power. */
+ TRUE, /* The default? */
+ bfd_default_compatible, /* Architecture comparison fn. */
+ bfd_default_scan, /* String to architecture convert fn. */
+ bfd_arch_default_fill, /* Default fill. */
+ NULL /* Next in list. */
+};
diff --git a/bfd/cpu-z80.c b/bfd/cpu-z80.c
new file mode 100644
index 0000000..d7bb6f2
--- /dev/null
+++ b/bfd/cpu-z80.c
@@ -0,0 +1,57 @@
+/* BFD library support routines for the Z80 architecture.
+ Copyright (C) 2005-2014 Free Software Foundation, Inc.
+ Contributed by Arnold Metselaar <arnold_m@operamail.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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+
+const bfd_arch_info_type bfd_z80_arch;
+
+/* This routine is provided two arch_infos and
+ returns whether they'd be compatible. */
+
+static const bfd_arch_info_type *
+compatible (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;
+
+ return (a->arch == bfd_arch_z80) ? & bfd_z80_arch : NULL;
+}
+
+#define N(name,print,default,next) \
+{ 16, 16, 8, bfd_arch_z80, name, "z80", print, 0, default, \
+ compatible, bfd_default_scan, bfd_arch_default_fill, next }
+
+#define M(n) &arch_info_struct[n]
+
+static const bfd_arch_info_type arch_info_struct[] =
+{
+ N (bfd_mach_z80strict, "z80-strict", FALSE, M(1)),
+ N (bfd_mach_z80, "z80", FALSE, M(2)),
+ N (bfd_mach_z80full, "z80-full", FALSE, M(3)),
+ N (bfd_mach_r800, "r800", FALSE, NULL)
+};
+
+const bfd_arch_info_type bfd_z80_arch = N (0, "z80-any", TRUE, M(0));
diff --git a/bfd/cpu-z8k.c b/bfd/cpu-z8k.c
new file mode 100644
index 0000000..9c6547c
--- /dev/null
+++ b/bfd/cpu-z8k.c
@@ -0,0 +1,48 @@
+/* BFD library support routines for the Z800n architecture.
+ Copyright (C) 1992-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+
+/* This routine is provided two arch_infos and returns whether
+ they'd be compatible */
+
+static const bfd_arch_info_type *
+compatible (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, 16, 8, bfd_arch_z8k, bfd_mach_z8002, "z8k", "z8002", 1, FALSE,
+ compatible, bfd_default_scan, bfd_arch_default_fill, 0 }
+};
+
+const bfd_arch_info_type bfd_z8k_arch =
+{
+ 32, 32, 8, bfd_arch_z8k, bfd_mach_z8001, "z8k", "z8001", 1, TRUE,
+ compatible, bfd_default_scan, bfd_arch_default_fill,
+ &arch_info_struct[0]
+};
diff --git a/bfd/demo64.c b/bfd/demo64.c
new file mode 100644
index 0000000..83db63e
--- /dev/null
+++ b/bfd/demo64.c
@@ -0,0 +1,30 @@
+/* BFD backend for demonstration 64-bit a.out binaries.
+ Copyright (C) 1990-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#define ARCH_SIZE 64
+
+/* Do not "beautify" the CONCAT* macro args. Traditional C will not
+ remove whitespace added here, and thus will fail to concatenate
+ the tokens. */
+#define MY(OP) CONCAT2 (aout64_,OP)
+
+#define TARGETNAME "demo64"
+#include "aoutf1.h"
diff --git a/bfd/dep-in.sed b/bfd/dep-in.sed
new file mode 100644
index 0000000..2e0a4fb
--- /dev/null
+++ b/bfd/dep-in.sed
@@ -0,0 +1,28 @@
+:loop
+/\\$/N
+s/\\\n */ /g
+t loop
+
+s! \./! !g
+s! @BFD_H@!!g
+s!@SRCDIR@/../include!$(INCDIR)!g
+s!@TOPDIR@/include!$(INCDIR)!g
+s!@SRCDIR@/../opcodes!$(srcdir)/../opcodes!g
+s!@TOPDIR@/opcodes!$(srcdir)/../opcodes!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! \$(INCDIR)/symcat\.h!!g
+s! \.\./intl/libintl\.h!!g
+
+s/ *$//
+s/ */ /g
+s/^ */A/
+s/ / \\\
+B/g
+$s/$/ \\/
diff --git a/bfd/development.sh b/bfd/development.sh
new file mode 100644
index 0000000..416ec8c
--- /dev/null
+++ b/bfd/development.sh
@@ -0,0 +1,19 @@
+# Copyright (C) 2012-2014 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 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# Controls whether to enable development-mode features by default.
+development=false
diff --git a/bfd/doc/ChangeLog b/bfd/doc/ChangeLog
new file mode 100644
index 0000000..e2987ed
--- /dev/null
+++ b/bfd/doc/ChangeLog
@@ -0,0 +1,318 @@
+2014-08-05 Doug Evans <dje@google.com>
+
+ * chew.c (skip_past_newline_1): New function.
+ (outputdots): Call it.
+ (skip_past_newline): Ditto.
+
+2014-08-05 Alan Modra <amodra@gmail.com>
+
+ * chew.c (print_stack_level, main): Cast result of pointer
+ difference to match format string.
+
+2014-04-09 Alan Modra <amodra@gmail.com>
+
+ * Makefile.am ($(MKDOC)): New rule, depend on chew.stamp. Move
+ old rule to..
+ (chew.stamp): ..here.
+ (DISTCLEANFILES): Move *.stamp..
+ (MOSTLYCLEANFILES): ..to here.
+ * Makefile.in: Regenerate.
+
+2014-04-09 Alan Modra <amodra@gmail.com>
+
+ * Makefile.am (MKDOC): Use $@ in command.
+ (aoutx.texi): New rule, depend on aoutx.stamp. Move old rule..
+ (aoutx.stamp): .. to here. Don't depend on chew.c, depend on MKDOC
+ and omit recursive MAKE. Use $< in command.
+ (archive.texi, archures.texi, bfdt.texi, cache.texi, coffcode.texi,
+ core.texi, elf.texi, elfcode.texi, mmo.texi, format.texi, libbfd.texi,
+ bfdio.texi, bfdwin.texi, opncls.texi, reloc.texi, section.texi,
+ syms.texi, targets.texi, init.texi, hash.texi, linker.texi): Similarly.
+ (DISTCLEANFILES): Remove *.stamp.
+ * Makefile.in: Regenerate.
+
+2014-03-12 Alan Modra <amodra@gmail.com>
+
+ * Makefile.in: Regenerate.
+
+2013-10-14 Nick Clifton <nickc@redhat.com>
+
+ * chew.c (perform): Free next.
+
+2013-04-15 Alan Modra <amodra@gmail.com>
+
+ * Makefile.am ($(MKDOC)): Append $(EXEEXT_FOR_BUILD) to temp file.
+ * Makefile.in: Regenerate.
+
+2013-04-09 Mingjie Xing <mingjie.xing@gmail.com>
+
+ * bfd.texinfo (typedef bfd, Error reporting, Miscellaneous):
+ Add menu items.
+
+2013-01-07 Patrice Dumas <pertusus@free.fr>
+
+ * bfd.texinfo: Replace @ with @@ when it is part of the text.
+
+2012-12-17 Nick Clifton <nickc@redhat.com>
+
+ * Makefile.am: Add copyright notice.
+ * bfdsumm.texi: Likewise.
+ * makefile.vms: Likewise.
+ * Makefile.in: Regenerate.
+
+2012-11-08 Alan Modra <amodra@gmail.com>
+
+ * Makefile.in: Regenerate.
+
+2012-02-27 Alan Modra <amodra@gmail.com>
+
+ * chew.c (print_stack_level, main): Use %ld to print stack delta.
+
+2010-10-28 Matthias Klose <doko@ubuntu.com>
+
+ * bfd.texinfo: Add directory section for info document.
+
+2010-05-07 Tristan Gingold <gingold@adacore.com>
+
+ * Makefile.in: Regenerate with automake 1.11.1.
+
+2010-01-09 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
+
+ * Makefile.in: Regenerate.
+
+2009-09-25 Martin Thuresson <martint@google.com>
+
+ Update soruces to make alpha targets compile cleanly with
+ -Wc++-compat:
+ * chew.c: Add casts.
+
+2009-08-29 Martin Thuresson <martin@mtme.org>
+
+ * chew.c (newentry, add_intrinsic): Rename variable new to
+ new_d.
+
+2009-08-27 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
+
+ * Makefile.in: Regenerate.
+
+2009-08-22 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
+
+ * Makefile.am (pdf__strip_dir, install-pdf, install-pdf-am)
+ (html__strip_dir, install-html, install-html-am): Remove.
+ * Makefile.in: Regenerate.
+
+ * Makefile.in: Regenerate.
+
+2009-05-22 Alan Modra <amodra@bigpond.net.au>
+
+ * Makefile.in: Regenerate.
+
+2009-04-22 Anthony Green <green@moxielogic.com>
+
+ * bfdint.texi (BFD target vector miscellaneous): Mention verilog
+ flavour.
+
+2008-11-19 Nick Clifton <nickc@redhat.com>
+
+ * fdl.texi: Update to v1.3
+ * bfd.texinfo: Change license to v1.3.
+
+2008-08-24 Alan Modra <amodra@bigpond.net.au>
+
+ * Makefile.am (chew.o): Delete rule.
+ ($(MKDOC)): Move options before C file.
+ * Makefile.in: Regenerate.
+
+2008-08-15 Alan Modra <amodra@bigpond.net.au>
+
+ * Makefile.in: Regenerate.
+
+2008-07-09 Craig Silverstein <csilvers@google.com>
+
+ * Makefile.am (BFD_H_DEP): Add ../compress.c.
+ * Makefile.in: Regenerate.
+
+2008-05-14 Alan Modra <amodra@bigpond.net.au>
+
+ * Makefile.in: Regenerate.
+
+2008-03-17 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
+
+ * Makefile.in: Regenerate.
+
+2008-03-13 Alan Modra <amodra@bigpond.net.au>
+
+ * Makefile.in: Regenerate.
+
+2007-10-15 Alan Modra <amodra@bigpond.net.au>
+
+ * chew.c (write_buffer): Check fwrite return value.
+
+2007-09-14 Alan Modra <amodra@bigpond.net.au>
+
+ * Makefile.in: Regenerate.
+
+2007-07-02 Alan Modra <amodra@bigpond.net.au>
+
+ * Makefile.in: Regenerate.
+
+2007-06-30 H.J. Lu <hongjiu.lu@intel.com>
+
+ * Makefile.in: Likewise.
+
+2007-06-14 H.J. Lu <hongjiu.lu@intel.com>
+
+ * Makefile.in: Regenerated.
+
+2007-05-22 Nick Clifton <nickc@redhat.com>
+
+ * bfd.texinfo: Use @copying around the copyright notice.
+ * bfdint.texi: Likewise.
+
+2007-05-21 Nick Clifton <nickc@redhat.com>
+
+ * bfdint.texi: Add GNU Free Documentation License notice.
+
+2007-04-24 Alan Modra <amodra@bigpond.net.au>
+
+ * Makefile.in: Regenerate.
+
+2007-02-17 Mark Mitchell <mark@codesourcery.com>
+ Nathan Sidwell <nathan@codesourcery.com>
+ Vladimir Prus <vladimir@codesourcery.com
+ Joseph Myers <joseph@codesourcery.com>
+
+ * Makefile.in: Regenerate.
+
+2006-07-24 Ralk Wildenhues <Ralf.Wildenhues@gmx.de>
+
+ * bfd..texinfo: Fix spelling mistakes.
+ * bfdint.texinfo: Likewise.
+
+2006-07-18 Nigel Stephens <nigel@mips.com>
+
+ * bfd.texinfo: Add @section for "What to Put Where".
+
+2006-06-07 Joseph S. Myers <joseph@codesourcery.com>
+
+ * bfd.texinfo: Remove local @tex code.
+
+2006-06-05 Alan Modra <amodra@bigpond.net.au>
+
+ * Makefile.in: Regenerate.
+
+2006-05-11 Carlos O'Donell <carlos@codesourcery.com>
+
+ * bfd.texinfo: Rename "Index" to "BFD Index"
+
+2006-04-06 Carlos O'Donell <carlos@codesourcery.com>
+
+ * Makefile.am: Add install-html and install-html-am targets.
+ Define datarootdir, docdir and htmldir.
+ * Makefile.in: Regenerate.
+
+2006-02-27 Carlos O'Donell <carlos@codesourcery.com>
+
+ * Makefile.am: Add html target.
+ * Makefile.in: Regenerate.
+
+2005-07-24 Daniel Jacobowitz <dan@codesourcery.com>
+
+ * chew.c: Include <string.h>.
+
+2005-07-22 DJ Delorie <dj@redhat.com>
+
+ * chew.c: Include stdlib.h.
+
+2005-07-22 Kazu Hirata <kazu@codesourcery.com>
+
+ * chew.c: Don't include sysdep.h.
+
+2005-05-09 Daniel Jacobowitz <dan@codesourcery.com>
+
+ * Makefile.am: Use a temporary file to build chew.
+ * Makefile.in: Regenerated.
+
+2005-05-04 Nick Clifton <nickc@redhat.com>
+
+ * chew.c: Update the address and phone number of the FSF
+ organization in the GPL notice.
+
+2005-05-05 H.J. Lu <hongjiu.lu@intel.com>
+
+ * Makefile.am (INCLUDES): Remove -D_GNU_SOURCE.
+ * Makefile.in: Regenerate.
+
+2005-04-29 Daniel Jacobowitz <dan@codesourcery.com>
+
+ * Makefile.am: Remove stamp rules. Depend on chew.c
+ instead of $(MKDOC).
+ * Makefile.in: Regnerated.
+
+2005-04-21 H.J. Lu <hongjiu.lu@intel.com>
+
+ * Makefile.am (INCLUDES): New. Add -D_GNU_SOURCE.
+ (chew.o): Use it.
+ * Makefile.in: Regenerate.
+
+2005-04-14 Alan Modra <amodra@bigpond.net.au>
+
+ * Makefile.in: Regenerate.
+
+2005-04-12 Alan Modra <amodra@bigpond.net.au>
+
+ * Makefile.in: Regenerate.
+
+2005-02-21 Alan Modra <amodra@bigpond.net.au>
+
+ * Makefile.in: Regenerate.
+
+2005-02-13 Maciej W. Rozycki <macro@linux-mips.org>
+
+ * Makefile.am: Use CFLAGS_FOR_BUILD and LDFLAGS_FOR_BUILD for
+ building chew.
+ * Makefile.in: Regenerate.
+
+2005-02-01 Ben Elliston <bje@au.ibm.com>
+
+ * chew.c: Remove #if 0'd code throughout. Similarly, collapse #if
+ 1'd code.
+
+2004-12-20 Ian Lance Taylor <ian@c2microsystems.com>
+
+ * Makefile.am: Use $(SHELL) whenever we run move-if-change.
+ * Makefile.in: Rebuild.
+
+2004-09-19 H.J. Lu <hongjiu.lu@intel.com>
+
+ * Makefile.am (AUTOMAKE_OPTIONS): Require 1.9.
+ (bfd.info): Rename the target to ...
+ ($(srcdir)/bfd.info): This.
+ * Makefile.in: Regenerated.
+
+2004-09-17 Alan Modra <amodra@bigpond.net.au>
+
+ * Makefile.in: Regenerate.
+
+2004-03-27 Alan Modra <amodra@bigpond.net.au>
+
+ * bfdint.texi: Remove all mention of elflink.h.
+
+2004-03-19 Alan Modra <amodra@bigpond.net.au>
+
+ * Makefile.in: Regenerate.
+
+For older changes see ChangeLog-9103
+
+Copyright (C) 2004-2014 Free Software Foundation, Inc.
+
+Copying and distribution of this file, with or without modification,
+are permitted in any medium without royalty provided the copyright
+notice and this notice are preserved.
+
+Local Variables:
+mode: change-log
+left-margin: 8
+fill-column: 74
+version-control: never
+End:
diff --git a/bfd/doc/ChangeLog-9103 b/bfd/doc/ChangeLog-9103
new file mode 100644
index 0000000..0b5d836
--- /dev/null
+++ b/bfd/doc/ChangeLog-9103
@@ -0,0 +1,600 @@
+2003-10-15 Andrew Cagney <cagney@redhat.com>
+
+ * bfdint.texi (BFD target vector symbols): Rename _get_symtab to
+ _canonicalize_symtab.
+
+2003-10-08 David Taylor <dtaylor@emc.com>
+
+ * bfd.texinfo: Remove spurious backslash.
+
+2003-07-04 Josh Baratz <baratz@intersystems.com>
+
+ * Makefile.am (MKDOC rule): Add $(CFLAGS) in case it contains
+ CC_FOR_BUILD specific switches.
+ * Makefile.in: Regenerate.
+
+2003-06-29 Alan Modra <amodra@bigpond.net.au>
+
+ * chew.c (paramstuff): Don't emit PARAMS.
+
+2003-02-12 Bob Wilson <bob.wilson@acm.org>
+
+ * bfd.texinfo: Fix quotes for texinfo. Make section title
+ capitalization more consistent. Use @example instead of @lisp.
+ Replace FDL appendix with include of fdl.texi.
+ * fdl.texi: New file.
+
+2002-11-18 Klee Dienes <kdienes@apple.com>
+
+ * Makefile.am (DOCFILES): Add bfdwin.texi, bfdio.texi.
+ (PROTOS): Add bfdio.p, bfdwin.p.
+ (SRCDOC): Add bfdio.c, bfdwin.c.
+ (SRCPROT): Add bfdio.c, bfdwin.c.
+ (SRCIPROT): Add bfdio.c, bfdwin.c.
+ (LIBBFD_H_DEP): Add bfdio.c, bfdwin.c.
+ (BFD_H_DEP): Add bfdio.c, bfdwin.c.
+ Add rules for bfdio.texi, bfdwin.text.
+ * bfd.texinfo: Include bfdio.texi.
+
+2002-10-14 Alan Modra <amodra@bigpond.net.au>
+
+ * Makefile.in: Regenerate.
+
+2002-10-11 Daniel Jacobowitz <drow@mvista.com>
+
+ * Makefile.in: Regenerated.
+
+2002-08-29 John David Anglin <dave@hiauly1.hia.nrc.ca>
+
+ * chew.c (paramstuff, outputdots, perform, bang and usage): Remove
+ void from function definitions.
+
+2002-08-13 Alan Modra <amodra@bigpond.net.au>
+
+ * header.sed: Strip tabs.
+
+2002-06-08 Alan Modra <amodra@bigpond.net.au>
+
+ * Makefile.am: Fix quote style in last change.
+ * Makefile.in: Regenerate.
+
+2002-06-07 Alan Modra <amodra@bigpond.net.au>
+
+ * Makefile.am (libbfd.h): Don't use "echo -n".
+ (libcoff.h, bfd.h): Likewise.
+ * Makefile.in: Regenerate.
+
+2002-06-06 Lars Brinkhoff <lars@nocrew.org>
+
+ * bfdint.texi: Change registry@sco.com to registry@caldera.com.
+
+2002-06-05 Alan Modra <amodra@bigpond.net.au>
+
+ * Makefile.am (libbfd.h): Add "Extracted from.." comment.
+ (libcoff.h, bfd.h): Likewise.
+ * Makefile.in: Regenerate.
+
+2002-05-25 Alan Modra <amodra@bigpond.net.au>
+
+ * chew.c: Use #include "" instead of <> for local header files.
+
+2002-04-20 Alan Modra <amodra@bigpond.net.au>
+
+ * Makefile.in: Regenerate.
+
+2002-02-11 Alan Modra <amodra@bigpond.net.au>
+
+ * Makefile.in: Regenerate.
+
+2002-02-01 Alan Modra <amodra@bigpond.net.au>
+
+ * chew.c (WORD): Eliminate.
+
+2002-01-31 Ivan Guzvinec <ivang@opencores.org>
+
+ * Makefile.in: Regenerate.
+
+2002-01-31 Alan Modra <amodra@bigpond.net.au>
+
+ * chew.c (courierize): Don't modify @command params.
+
+2002-01-30 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * proto.str (ENUMDOC): Place two spaces between the end of
+ the text and the closing comment marker.
+
+2001-10-30 Hans-Peter Nilsson <hp@bitrange.com>
+
+ * bfdint.texi (BFD target vector miscellaneous): Add
+ bfd_target_mmo_flavour.
+ * bfd.texinfo (BFD back ends): Add entry for mmo.
+ * Makefile.am (DOCFILES): Add mmo.texi.
+ (SRCDOC): Add mmo.c.
+ (s-mmo, mmo.texi): New rules.
+
+2001-10-29 Kazu Hirata <kazu@hxi.com>
+
+ * bfdsumm.texi: Fix a typo.
+
+2001-10-26 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * bfd.texinfo: Change footer to refer to FSF. Change subtitle
+ to refer to original creation date.
+
+2002-01-26 Hans-Peter Nilsson <hp@bitrange.com>
+
+ * Makefile.am (install): Depend on install-info.
+ * Makefile.in: Regenerate.
+
+2001-10-03 Alan Modra <amodra@bigpond.net.au>
+
+ * Makefile.am (BFD_H_DEP): Add ../version.h.
+ * Makefile.in: Regenerate.
+
+2001-10-02 Alan Modra <amodra@bigpond.net.au>
+
+ * Makefile.in: Regenerate.
+
+2001-10-01 Alan Modra <amodra@bigpond.net.au>
+
+ * header.sed: New file, adds header to generated files.
+ * Makefile.am: Rewrite rules generating libbfd.h, libcoff.h and
+ bfd.h, using above. Add missing elf.c dependecy for libbfd.h.
+ * Makefile.in: Regenerate.
+
+2001-09-21 Alan Modra <amodra@bigpond.net.au>
+
+ * Makefile.in: Regenerate.
+
+2001-09-18 Alan Modra <amodra@bigpond.net.au>
+
+ * bfdint.texi: Replace reference to bfd_read with bfd_bread.
+ Likewise for bfd_write.
+
+2001-07-24 Alan Modra <amodra@bigpond.net.au>
+
+ * Makefile.in: Regenerate.
+
+2001-06-21 Hans-Peter Nilsson <hp@axis.com>
+
+ * bfdint.texi (BFD relocation functions) <different formats>:
+ Mention that the GNU linker is aware of input-output format
+ restrictions when generating relocatable output. Make new
+ paragraph for final-link case.
+ (BFD target vector swap): Fix typo.
+
+2001-01-25 Kazu Hirata <kazu@hxi.com>
+
+ * chew.c: Do not output trailing whitespaces in type and
+ functionname. Update copyright.
+
+2001-01-24 Kazu Hirata <kazu@hxi.com>
+
+ * chew.c: Do not output a trailing whitespace.
+
+2000-11-06 Nick Clifton <nickc@redhat.com>
+
+ * bfd.texinfo: Add GNU Free Documentation License.
+
+2000-07-09 Alan Modra <alan@linuxcare.com.au>
+
+ * Makefile.in: Regenerate.
+
+2000-07-08 Alan Modra <alan@linuxcare.com.au>
+
+ * chew.c (outputdots): Don't add a space before `/*'.
+ (courierize): Likewise.
+
+Wed May 24 12:03:25 2000 Hans-Peter Nilsson <hp@axis.com>
+
+ * bfdint.texi (BFD ELF processor required): Add paragraph about
+ target necessities for readelf.
+
+2000-04-30 Ben Elliston <bje@redhat.com>
+
+ * bfdint.texi (BFD generated files): Fix another typo.
+
+2000-04-17 Ben Elliston <bje@redhat.com>
+
+ * bfdint.texi (BFD_JUMP_TABLE macros): Fix typo.
+
+2000-04-07 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * Makefile.in: Rebuild with current autoconf/automake.
+
+1999-02-04 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in: Rebuild with current autoconf/automake.
+
+1998-07-23 Nick Clifton <nickc@cygnus.com>
+
+ * bfdint.texi (BFD ELF processor required): Add paragraph
+ describing the necessity to create "include/elf/CPU.h".
+
+1998-05-07 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.am (chew.o): Add -I options for intl srcdir and
+ objdir.
+ * Makefile.in: Rebuild.
+
+1998-04-27 Ian Lance Taylor <ian@cygnus.com>
+
+ * bfdint.texi: New file.
+ * Makefile.am (noinst_TEXINFOS): New variable.
+ * Makefile.in: Rebuild.
+
+1998-04-13 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in: Rebuild.
+
+1998-04-06 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.am (STAGESTUFF): Remove variable.
+ (CLEANFILES): Don't remove $(STAGESTUFF).
+ (DISTCLEANFILES, MAINTAINERCLEANFILES): New variables.
+ * Makefile.in: Rebuild.
+
+1998-03-27 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.
+
+1998-02-13 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.am (AUTOMAKE_OPTIONS): Define.
+ * Makefile.in: Rebuild.
+
+1998-01-26 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.
+
+1997-10-01 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.
+
+1997-08-15 Doug Evans <dje@canuck.cygnus.com>
+
+ * Makefile.am (libbfd.h, libcoff.h): Invoke $(MKDOC) as ./$(MKDOC).
+ * Makefile.in: Rebuild.
+
+1997-08-01 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.am (CC_FOR_BUILD): Don't set explicitly.
+ * Makefile.in: Rebuild.
+
+1997-07-31 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.am: New file, based on old Makefile.in.
+ * Makefile.in: Now built with automake.
+
+1997-07-22 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.
+
+1997-06-16 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in (CC, CFLAGS): Substitute from configure script.
+ From Jeff Makey <jeff@cts.com>.
+
+1997-04-15 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in (install-info): Use mkinstalldirs to build
+ $(infodir).
+
+1997-04-08 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).
+
+1997-04-07 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in (distclean): Don't remove *.info files.
+
+1997-02-13 Klaus Kaempf (kkaempf@progis.de)
+
+ * makefile.vms: New file.
+
+1996-06-18 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>.
+
+1996-01-30 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.
+
+1995-11-03 Fred Fish <fnf@cygnus.com>
+
+ * Makefile.in (SRCDOC, SRCPROT, core.texi, bfd.h): Use corefile.c,
+ renamed from core.c.
+
+1995-11-01 Manfred Hollstein KS/EF4A 60/1F/110 #40283 <manfred@lts.sel.alcatel.de>
+
+ * chew.c: Include <ctype.h>.
+
+1995-10-06 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.
+
+1995-10-04 Ken Raeburn <raeburn@cygnus.com>
+
+ * chew.c: Include <stdio.h>.
+
+1995-09-12 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in (maintainer-clean): New target.
+
+1995-08-31 Ian Lance Taylor <ian@cygnus.com>
+
+ * Makefile.in (bfd.h): Add additional #endif at end of bfd.h if
+ __cplusplus is defined.
+
+1994-11-29 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.
+
+1994-09-12 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.
+
+1994-09-02 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.
+
+1994-01-12 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * bfd.texinfo: Added Linker Functions node.
+ * Makefile.in (DOCFILES): Added linker.texi.
+ (SRCDOC): Added linker.c.
+ (linker.texi): New target.
+
+1994-01-04 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.
+
+1994-01-03 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.
+
+1993-12-30 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!).
+
+1993-11-05 David J. Mackenzie (djm@thepub.cygnus.com)
+
+ * bfd.texinfo: Small cleanups.
+
+1993-11-19 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * Makefile.in (archures.texi): Depends on $(MKDOC).
+
+1993-08-10 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.
+
+1993-08-09 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.
+
+1993-06-24 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.
+
+1993-06-14 david d `zoo' zuhn (zoo at rtl.cygnus.com)
+
+ * Makefile.in (install-info): remove parentdir cruft,
+
+1993-06-09 Jim Kingdon (kingdon@cygnus.com)
+
+ * Makefile.in (mostlyclean): Remove chew.o.
+
+1993-05-25 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * Makefile.in (libbfd.h): Use elfcode.h, not elf32.c.
+
+1993-05-24 Ken Raeburn (raeburn@cygnus.com)
+
+ * chew.c (compile): Add a couple of missing casts.
+
+1993-05-12 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.
+
+1993-04-07 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.
+
+1993-03-24 david d `zoo' zuhn (zoo at poseidon.cygnus.com)
+
+ * Makefile.in: fix typo (bfd.texinfo not bfd.texino)
+
+1993-03-19 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.
+
+1993-03-16 Per Bothner (bothner@rtl.cygnus.com)
+
+ * Makefile.in: Add *clean rules.
+
+1993-01-11 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.
+
+1992-12-17 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
+
+ * Makefile.in: added dvi target, define and use $(TEXI2DVI)
+
+1992-12-03 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.
+
+1992-11-05 John Gilmore (gnu@cygnus.com)
+
+ Cleanup: Replace all uses of EXFUN in the BFD sources, with PARAMS.
+
+ * chew.c (exfunstuff): Eliminate.
+ (paramstuff): Replace exfunstuff with function to generate PARAMS.
+ * proto.str: Use paramstuff rather than exfunstuff.
+
+1992-08-17 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * chew.c: various patches provided by Howard Chu.
+
+1992-06-19 John Gilmore (gnu at cygnus.com)
+
+ * Makefile.in (libbfd.h): Add elf.c as a source of prototypes.
+
+1992-05-11 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.
+
+1992-05-04 K. Richard Pixley (rich@rtl.cygnus.com)
+
+ * Makefile.in: another CFLAGS correction.
+
+1992-04-28 K. Richard Pixley (rich@rtl.cygnus.com)
+
+ * Makefile.in: Do the CFLAGS thing.
+
+1992-04-11 Fred Fish (fnf@cygnus.com)
+
+ * Makefile.in (MINUS_G): Add macro and default to -g.
+
+1992-03-06 Steve Chamberlain (sac@thepub.cygnus.com)
+
+ * chew.c: now has -w switch turn on warnings
+
+1992-02-26 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.
+
+1991-12-10 K. Richard Pixley (rich at rtl.cygnus.com)
+
+ * Makefile.in: build chew into the current directory. Complete
+ the MKDOC macro transition.
+
+1991-12-10 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
+
+1991-12-10 K. Richard Pixley (rich at rtl.cygnus.com)
+
+ * Makefile.in: infodir belongs in datadir.
+
+1991-12-07 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.
+
+
+1991-12-06 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.
+
+1991-12-05 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.
+
+
+Copyright (C) 1991-2003 Free Software Foundation, Inc.
+
+Copying and distribution of this file, with or without modification,
+are permitted in any medium without royalty provided the copyright
+notice and this notice are preserved.
+
+Local Variables:
+version-control: never
+End:
diff --git a/bfd/doc/Makefile.am b/bfd/doc/Makefile.am
new file mode 100644
index 0000000..3f69859
--- /dev/null
+++ b/bfd/doc/Makefile.am
@@ -0,0 +1,348 @@
+## Process this file with automake to generate Makefile.in
+#
+# Copyright (C) 2012-2014 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 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 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 COPYING3. If not see
+# <http://www.gnu.org/licenses/>.
+#
+
+AUTOMAKE_OPTIONS = 1.9 cygnus
+
+DOCFILES = aoutx.texi archive.texi archures.texi \
+ bfdt.texi cache.texi coffcode.texi \
+ core.texi elf.texi elfcode.texi format.texi \
+ libbfd.texi bfdwin.texi bfdio.texi \
+ opncls.texi reloc.texi section.texi \
+ syms.texi targets.texi init.texi hash.texi linker.texi \
+ mmo.texi \
+ bfdver.texi
+
+PROTOS = archive.p archures.p bfd.p \
+ core.p format.p \
+ bfdio.p bfdwin.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)/../bfdio.c $(srcdir)/../bfdwin.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 \
+ $(srcdir)/../mmo.c
+
+SRCPROT = $(srcdir)/../archive.c $(srcdir)/../archures.c \
+ $(srcdir)/../bfd.c $(srcdir)/../coffcode.h $(srcdir)/../corefile.c \
+ $(srcdir)/../format.c $(srcdir)/../libbfd.c \
+ $(srcdir)/../bfdio.c $(srcdir)/../bfdwin.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)/../bfdio.c $(srcdir)/../bfdwin.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
+bfd_TEXINFOS = $(DOCFILES) bfdsumm.texi
+
+MKDOC = chew$(EXEEXT_FOR_BUILD)
+
+AM_CPPFLAGS = -I.. -I$(srcdir)/.. -I$(srcdir)/../../include \
+ -I$(srcdir)/../../intl -I../../intl
+
+$(MKDOC): chew.stamp ; @true
+chew.stamp: $(srcdir)/chew.c
+ $(CC_FOR_BUILD) -o chw$$$$$(EXEEXT_FOR_BUILD) $(CFLAGS_FOR_BUILD) \
+ $(LDFLAGS_FOR_BUILD) $(H_CFLAGS) $(AM_CPPFLAGS) $(srcdir)/chew.c; \
+ $(SHELL) $(srcdir)/../../move-if-change \
+ chw$$$$$(EXEEXT_FOR_BUILD) $(MKDOC); \
+ touch $@
+
+protos: libbfd.h libcoff.h bfd.h
+
+# We can't replace these rules with an implicit rule, because
+# makes without VPATH support couldn't find the .h files in `..'.
+
+# We do not depend on chew directly 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 nothing will be rebuilt.
+
+aoutx.texi: aoutx.stamp ; @true
+aoutx.stamp: $(srcdir)/../aoutx.h $(srcdir)/doc.str $(MKDOC)
+ ./$(MKDOC) -f $(srcdir)/doc.str < $< >aoutx.tmp
+ $(SHELL) $(srcdir)/../../move-if-change aoutx.tmp aoutx.texi
+ touch $@
+
+archive.texi: archive.stamp ; @true
+archive.stamp: $(srcdir)/../archive.c $(srcdir)/doc.str $(MKDOC)
+ ./$(MKDOC) -f $(srcdir)/doc.str < $< >archive.tmp
+ $(SHELL) $(srcdir)/../../move-if-change archive.tmp archive.texi
+ touch $@
+
+archures.texi: archures.stamp ; @true
+archures.stamp: $(srcdir)/../archures.c $(srcdir)/doc.str $(MKDOC)
+ ./$(MKDOC) -f $(srcdir)/doc.str < $< >archures.tmp
+ $(SHELL) $(srcdir)/../../move-if-change archures.tmp archures.texi
+ touch $@
+
+# We use bfdt.texi, rather than bfd.texi, to avoid conflicting with
+# bfd.texinfo on an 8.3 filesystem.
+bfdt.texi: bfdt.stamp ; @true
+bfdt.stamp: $(srcdir)/../bfd.c $(srcdir)/doc.str $(MKDOC)
+ ./$(MKDOC) -f $(srcdir)/doc.str < $< >bfd.tmp
+ $(SHELL) $(srcdir)/../../move-if-change bfd.tmp bfdt.texi
+ touch $@
+
+cache.texi: cache.stamp ; @true
+cache.stamp: $(srcdir)/../cache.c $(srcdir)/doc.str $(MKDOC)
+ ./$(MKDOC) -f $(srcdir)/doc.str < $< >cache.tmp
+ $(SHELL) $(srcdir)/../../move-if-change cache.tmp cache.texi
+ touch $@
+
+coffcode.texi: coffcode.stamp ; @true
+coffcode.stamp: $(srcdir)/../coffcode.h $(srcdir)/doc.str $(MKDOC)
+ ./$(MKDOC) -f $(srcdir)/doc.str < $< >coffcode.tmp
+ $(SHELL) $(srcdir)/../../move-if-change coffcode.tmp coffcode.texi
+ touch $@
+
+core.texi: core.stamp ; @true
+core.stamp: $(srcdir)/../corefile.c $(srcdir)/doc.str $(MKDOC)
+ ./$(MKDOC) -f $(srcdir)/doc.str < $< >core.tmp
+ $(SHELL) $(srcdir)/../../move-if-change core.tmp core.texi
+ touch $@
+
+elf.texi: elf.stamp ; @true
+elf.stamp: $(srcdir)/../elf.c $(srcdir)/doc.str $(MKDOC)
+ ./$(MKDOC) -f $(srcdir)/doc.str < $< >elf.tmp
+ $(SHELL) $(srcdir)/../../move-if-change elf.tmp elf.texi
+ touch $@
+
+elfcode.texi: elfcode.stamp ; @true
+elfcode.stamp: $(srcdir)/../elfcode.h $(srcdir)/doc.str $(MKDOC)
+ ./$(MKDOC) -f $(srcdir)/doc.str < $< >elfcode.tmp
+ $(SHELL) $(srcdir)/../../move-if-change elfcode.tmp elfcode.texi
+ touch $@
+
+mmo.texi: mmo.stamp ; @true
+mmo.stamp: $(srcdir)/../mmo.c $(srcdir)/doc.str $(MKDOC)
+ ./$(MKDOC) -f $(srcdir)/doc.str < $< >mmo.tmp
+ $(SHELL) $(srcdir)/../../move-if-change mmo.tmp mmo.texi
+ touch $@
+
+format.texi: format.stamp ; @true
+format.stamp: $(srcdir)/../format.c $(srcdir)/doc.str $(MKDOC)
+ ./$(MKDOC) -f $(srcdir)/doc.str < $< >format.tmp
+ $(SHELL) $(srcdir)/../../move-if-change format.tmp format.texi
+ touch $@
+
+libbfd.texi: libbfd.stamp ; @true
+libbfd.stamp: $(srcdir)/../libbfd.c $(srcdir)/doc.str $(MKDOC)
+ ./$(MKDOC) -f $(srcdir)/doc.str < $< >libbfd.tmp
+ $(SHELL) $(srcdir)/../../move-if-change libbfd.tmp libbfd.texi
+ touch $@
+
+bfdio.texi: bfdio.stamp ; @true
+bfdio.stamp: $(srcdir)/../bfdio.c $(srcdir)/doc.str $(MKDOC)
+ ./$(MKDOC) -f $(srcdir)/doc.str < $< >bfdio.tmp
+ $(SHELL) $(srcdir)/../../move-if-change bfdio.tmp bfdio.texi
+ touch $@
+
+bfdwin.texi: bfdwin.stamp ; @true
+bfdwin.stamp: $(srcdir)/../bfdwin.c $(srcdir)/doc.str $(MKDOC)
+ ./$(MKDOC) -f $(srcdir)/doc.str < $< >bfdwin.tmp
+ $(SHELL) $(srcdir)/../../move-if-change bfdwin.tmp bfdwin.texi
+ touch $@
+
+opncls.texi: opncls.stamp ; @true
+opncls.stamp: $(srcdir)/../opncls.c $(srcdir)/doc.str $(MKDOC)
+ ./$(MKDOC) -f $(srcdir)/doc.str < $< >opncls.tmp
+ $(SHELL) $(srcdir)/../../move-if-change opncls.tmp opncls.texi
+ touch $@
+
+reloc.texi: reloc.stamp ; @true
+reloc.stamp: $(srcdir)/../reloc.c $(srcdir)/doc.str $(MKDOC)
+ ./$(MKDOC) -f $(srcdir)/doc.str < $< >reloc.tmp
+ $(SHELL) $(srcdir)/../../move-if-change reloc.tmp reloc.texi
+ touch $@
+
+section.texi: section.stamp ; @true
+section.stamp: $(srcdir)/../section.c $(srcdir)/doc.str $(MKDOC)
+ ./$(MKDOC) -f $(srcdir)/doc.str < $< >section.tmp
+ $(SHELL) $(srcdir)/../../move-if-change section.tmp section.texi
+ touch $@
+
+syms.texi: syms.stamp ; @true
+syms.stamp: $(srcdir)/../syms.c $(srcdir)/doc.str $(MKDOC)
+ ./$(MKDOC) -f $(srcdir)/doc.str < $< >syms.tmp
+ $(SHELL) $(srcdir)/../../move-if-change syms.tmp syms.texi
+ touch $@
+
+targets.texi: targets.stamp ; @true
+targets.stamp: $(srcdir)/../targets.c $(srcdir)/doc.str $(MKDOC)
+ ./$(MKDOC) -f $(srcdir)/doc.str < $< >targets.tmp
+ $(SHELL) $(srcdir)/../../move-if-change targets.tmp targets.texi
+ touch $@
+
+init.texi: init.stamp ; @true
+init.stamp: $(srcdir)/../init.c $(srcdir)/doc.str $(MKDOC)
+ ./$(MKDOC) -f $(srcdir)/doc.str < $< >init.tmp
+ $(SHELL) $(srcdir)/../../move-if-change init.tmp init.texi
+ touch $@
+
+hash.texi: hash.stamp ; @true
+hash.stamp: $(srcdir)/../hash.c $(srcdir)/doc.str $(MKDOC)
+ ./$(MKDOC) -f $(srcdir)/doc.str < $< >hash.tmp
+ $(SHELL) $(srcdir)/../../move-if-change hash.tmp hash.texi
+ touch $@
+
+linker.texi: linker.stamp ; @true
+linker.stamp: $(srcdir)/../linker.c $(srcdir)/doc.str $(MKDOC)
+ ./$(MKDOC) -f $(srcdir)/doc.str < $< >linker.tmp
+ $(SHELL) $(srcdir)/../../move-if-change linker.tmp linker.texi
+ touch $@
+
+LIBBFD_H_DEP = \
+ $(srcdir)/../libbfd-in.h \
+ $(srcdir)/../init.c \
+ $(srcdir)/../libbfd.c \
+ $(srcdir)/../bfdio.c \
+ $(srcdir)/../bfdwin.c \
+ $(srcdir)/../cache.c \
+ $(srcdir)/../reloc.c \
+ $(srcdir)/../archures.c \
+ $(srcdir)/../elf.c \
+ $(srcdir)/header.sed \
+ $(srcdir)/proto.str \
+ $(MKDOC)
+
+libbfd.h: $(LIBBFD_H_DEP)
+ echo "$(LIBBFD_H_DEP)" | sed -f $(srcdir)/header.sed > $@
+ for file in $(LIBBFD_H_DEP); do \
+ case $$file in \
+ *-in.h) cat $$file >> $@ ;; \
+ */header.sed) break ;; \
+ *) echo $$file | sed -e 's,.*/,,' -e 's,^,/* Extracted from ,' \
+ -e 's,$$,. */,' >> $@ ; \
+ ./$(MKDOC) -i -f $(srcdir)/proto.str < $$file >> $@ ;; \
+ esac; \
+ done
+
+LIBCOFF_H_DEP = \
+ $(srcdir)/../libcoff-in.h \
+ $(srcdir)/../coffcode.h \
+ $(srcdir)/header.sed \
+ $(srcdir)/proto.str \
+ $(MKDOC)
+
+libcoff.h: $(LIBCOFF_H_DEP)
+ echo "$(LIBCOFF_H_DEP)" | sed -f $(srcdir)/header.sed > $@
+ for file in $(LIBCOFF_H_DEP); do \
+ case $$file in \
+ *-in.h) cat $$file >> $@ ;; \
+ */header.sed) break ;; \
+ *) echo $$file | sed -e 's,.*/,,' -e 's,^,/* Extracted from ,' \
+ -e 's,$$,. */,' >> $@ ; \
+ ./$(MKDOC) -i -f $(srcdir)/proto.str < $$file >> $@ ;; \
+ esac; \
+ done
+
+BFD_H_DEP = \
+ $(srcdir)/../bfd-in.h \
+ $(srcdir)/../init.c \
+ $(srcdir)/../opncls.c \
+ $(srcdir)/../libbfd.c \
+ $(srcdir)/../bfdio.c \
+ $(srcdir)/../bfdwin.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)/../linker.c \
+ $(srcdir)/../simple.c \
+ $(srcdir)/../compress.c \
+ $(srcdir)/header.sed \
+ $(srcdir)/proto.str \
+ $(srcdir)/../version.h \
+ $(MKDOC)
+
+bfd.h: $(BFD_H_DEP)
+ echo "$(BFD_H_DEP)" | sed -f $(srcdir)/header.sed > $@
+ for file in $(BFD_H_DEP); do \
+ case $$file in \
+ *-in.h) cat $$file >> $@ ;; \
+ */header.sed) break ;; \
+ *) echo $$file | sed -e 's,.*/,,' -e 's,^,/* Extracted from ,' \
+ -e 's,$$,. */,' >> $@ ; \
+ ./$(MKDOC) -f $(srcdir)/proto.str < $$file >> $@ ;; \
+ esac; \
+ done
+ echo "#ifdef __cplusplus" >> $@
+ echo "}" >> $@
+ echo "#endif" >> $@
+ echo "#endif" >> $@
+
+bfdver.texi: $(srcdir)/Makefile.in
+ @echo "creating $@"; \
+ echo "@set VERSION $(VERSION)" > bfdver.texi; \
+ if [ -n "$(PKGVERSION)" ]; then \
+ echo "@set VERSION_PACKAGE $(PKGVERSION)" >> bfdver.texi; \
+ fi; \
+ echo "@set UPDATED `date '+%B %Y'`" >> bfdver.texi; \
+ if [ -n "$(REPORT_BUGS_TEXI)" ]; then \
+ echo "@set BUGURL $(REPORT_BUGS_TEXI)" >> bfdver.texi; \
+ fi
+
+noinst_TEXINFOS = bfdint.texi
+
+MOSTLYCLEANFILES = $(MKDOC) *.o *.stamp
+
+CLEANFILES = *.p *.ip
+
+DISTCLEANFILES = bfd.?? bfd.??? bfd.h libbfd.h libcoff.h texput.log
+
+MAINTAINERCLEANFILES = $(DOCFILES)
+
+# We want install to imply install-info as per GNU standards, despite the
+# cygnus option.
+install: install-info
+
+MAINTAINERCLEANFILES += bfd.info
+
+# Automake 1.9 will only build info files in the objdir if they are
+# mentioned in DISTCLEANFILES. It doesn't have to be unconditional,
+# though, so we use a bogus condition.
+if GENINSRC_NEVER
+DISTCLEANFILES += bfd.info
+endif
diff --git a/bfd/doc/Makefile.in b/bfd/doc/Makefile.in
new file mode 100644
index 0000000..65ad42d
--- /dev/null
+++ b/bfd/doc/Makefile.in
@@ -0,0 +1,987 @@
+# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009 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.
+
+@SET_MAKE@
+
+#
+# Copyright (C) 2012-2014 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 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 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 COPYING3. If not see
+# <http://www.gnu.org/licenses/>.
+#
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+target_triplet = @target@
+
+# Automake 1.9 will only build info files in the objdir if they are
+# mentioned in DISTCLEANFILES. It doesn't have to be unconditional,
+# though, so we use a bogus condition.
+@GENINSRC_NEVER_TRUE@am__append_1 = bfd.info
+subdir = doc
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+ $(bfd_TEXINFOS)
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/../config/acx.m4 \
+ $(top_srcdir)/../config/depstand.m4 \
+ $(top_srcdir)/../config/gettext-sister.m4 \
+ $(top_srcdir)/../config/largefile.m4 \
+ $(top_srcdir)/../config/lead-dot.m4 \
+ $(top_srcdir)/../config/nls.m4 \
+ $(top_srcdir)/../config/override.m4 \
+ $(top_srcdir)/../config/plugins.m4 \
+ $(top_srcdir)/../config/po.m4 \
+ $(top_srcdir)/../config/progtest.m4 \
+ $(top_srcdir)/../config/stdint.m4 $(top_srcdir)/../libtool.m4 \
+ $(top_srcdir)/../ltoptions.m4 $(top_srcdir)/../ltsugar.m4 \
+ $(top_srcdir)/../ltversion.m4 $(top_srcdir)/../lt~obsolete.m4 \
+ $(top_srcdir)/bfd.m4 $(top_srcdir)/warning.m4 \
+ $(top_srcdir)/acinclude.m4 $(top_srcdir)/../config/zlib.m4 \
+ $(top_srcdir)/version.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(SHELL) $(top_srcdir)/../mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+depcomp =
+am__depfiles_maybe =
+SOURCES =
+INFO_DEPS = bfd.info
+TEXINFO_TEX = $(top_srcdir)/../texinfo/texinfo.tex
+am__TEXINFO_TEX_DIR = $(top_srcdir)/../texinfo
+DVIS = bfd.dvi
+PDFS = bfd.pdf
+PSS = bfd.ps
+HTMLS = bfd.html
+TEXINFOS = bfd.texinfo
+TEXI2DVI = `if test -f $(top_srcdir)/../texinfo/util/texi2dvi; then \
+ echo $(top_srcdir)/../texinfo/util/texi2dvi; \
+ else \
+ echo texi2dvi; \
+ fi`
+TEXI2PDF = $(TEXI2DVI) --pdf --batch
+MAKEINFOHTML = $(MAKEINFO) --html
+AM_MAKEINFOHTMLFLAGS = $(AM_MAKEINFOFLAGS)
+DVIPS = dvips
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BFD_HOSTPTR_T = @BFD_HOSTPTR_T@
+BFD_HOST_64BIT_LONG = @BFD_HOST_64BIT_LONG@
+BFD_HOST_64BIT_LONG_LONG = @BFD_HOST_64BIT_LONG_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@
+CCDEPMODE = @CCDEPMODE@
+CC_FOR_BUILD = @CC_FOR_BUILD@
+CFLAGS = @CFLAGS@
+COREFILE = @COREFILE@
+COREFLAG = @COREFLAG@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DATADIRNAME = @DATADIRNAME@
+DEBUGDIR = @DEBUGDIR@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+EXEEXT_FOR_BUILD = @EXEEXT_FOR_BUILD@
+FGREP = @FGREP@
+GENCAT = @GENCAT@
+GMSGFMT = @GMSGFMT@
+GREP = @GREP@
+HDEFINES = @HDEFINES@
+INCINTL = @INCINTL@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INSTOBJEXT = @INSTOBJEXT@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBINTL = @LIBINTL@
+LIBINTL_DEP = @LIBINTL_DEP@
+LIBM = @LIBM@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+MKINSTALLDIRS = @MKINSTALLDIRS@
+MSGFMT = @MSGFMT@
+MSGMERGE = @MSGMERGE@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NO_WERROR = @NO_WERROR@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKGVERSION = @PKGVERSION@
+POSUB = @POSUB@
+RANLIB = @RANLIB@
+REPORT_BUGS_TEXI = @REPORT_BUGS_TEXI@
+REPORT_BUGS_TO = @REPORT_BUGS_TO@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHARED_LDFLAGS = @SHARED_LDFLAGS@
+SHARED_LIBADD = @SHARED_LIBADD@
+SHELL = @SHELL@
+STRIP = @STRIP@
+TDEFINES = @TDEFINES@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+WARN_CFLAGS = @WARN_CFLAGS@
+XGETTEXT = @XGETTEXT@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+all_backends = @all_backends@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bfd64_libs = @bfd64_libs@
+bfd_backends = @bfd_backends@
+bfd_default_target_size = @bfd_default_target_size@
+bfd_file_ptr = @bfd_file_ptr@
+bfd_machines = @bfd_machines@
+bfd_ufile_ptr = @bfd_ufile_ptr@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+havevecs = @havevecs@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_noncanonical = @host_noncanonical@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+lt_cv_dlopen_libs = @lt_cv_dlopen_libs@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+supports_plugins = @supports_plugins@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_noncanonical = @target_noncanonical@
+target_os = @target_os@
+target_vendor = @target_vendor@
+tdefaults = @tdefaults@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+wordsize = @wordsize@
+AUTOMAKE_OPTIONS = 1.9 cygnus
+DOCFILES = aoutx.texi archive.texi archures.texi \
+ bfdt.texi cache.texi coffcode.texi \
+ core.texi elf.texi elfcode.texi format.texi \
+ libbfd.texi bfdwin.texi bfdio.texi \
+ opncls.texi reloc.texi section.texi \
+ syms.texi targets.texi init.texi hash.texi linker.texi \
+ mmo.texi \
+ bfdver.texi
+
+PROTOS = archive.p archures.p bfd.p \
+ core.p format.p \
+ bfdio.p bfdwin.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)/../bfdio.c $(srcdir)/../bfdwin.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 \
+ $(srcdir)/../mmo.c
+
+SRCPROT = $(srcdir)/../archive.c $(srcdir)/../archures.c \
+ $(srcdir)/../bfd.c $(srcdir)/../coffcode.h $(srcdir)/../corefile.c \
+ $(srcdir)/../format.c $(srcdir)/../libbfd.c \
+ $(srcdir)/../bfdio.c $(srcdir)/../bfdwin.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)/../bfdio.c $(srcdir)/../bfdwin.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
+bfd_TEXINFOS = $(DOCFILES) bfdsumm.texi
+MKDOC = chew$(EXEEXT_FOR_BUILD)
+AM_CPPFLAGS = -I.. -I$(srcdir)/.. -I$(srcdir)/../../include \
+ -I$(srcdir)/../../intl -I../../intl
+
+LIBBFD_H_DEP = \
+ $(srcdir)/../libbfd-in.h \
+ $(srcdir)/../init.c \
+ $(srcdir)/../libbfd.c \
+ $(srcdir)/../bfdio.c \
+ $(srcdir)/../bfdwin.c \
+ $(srcdir)/../cache.c \
+ $(srcdir)/../reloc.c \
+ $(srcdir)/../archures.c \
+ $(srcdir)/../elf.c \
+ $(srcdir)/header.sed \
+ $(srcdir)/proto.str \
+ $(MKDOC)
+
+LIBCOFF_H_DEP = \
+ $(srcdir)/../libcoff-in.h \
+ $(srcdir)/../coffcode.h \
+ $(srcdir)/header.sed \
+ $(srcdir)/proto.str \
+ $(MKDOC)
+
+BFD_H_DEP = \
+ $(srcdir)/../bfd-in.h \
+ $(srcdir)/../init.c \
+ $(srcdir)/../opncls.c \
+ $(srcdir)/../libbfd.c \
+ $(srcdir)/../bfdio.c \
+ $(srcdir)/../bfdwin.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)/../linker.c \
+ $(srcdir)/../simple.c \
+ $(srcdir)/../compress.c \
+ $(srcdir)/header.sed \
+ $(srcdir)/proto.str \
+ $(srcdir)/../version.h \
+ $(MKDOC)
+
+noinst_TEXINFOS = bfdint.texi
+MOSTLYCLEANFILES = $(MKDOC) *.o *.stamp
+CLEANFILES = *.p *.ip
+DISTCLEANFILES = bfd.?? bfd.??? bfd.h libbfd.h libcoff.h texput.log \
+ $(am__append_1)
+MAINTAINERCLEANFILES = $(DOCFILES) bfd.info
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .dvi .ps
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign doc/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign doc/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+bfd.info: bfd.texinfo $(bfd_TEXINFOS)
+ restore=: && backupdir="$(am__leading_dot)am$$$$" && \
+ rm -rf $$backupdir && mkdir $$backupdir && \
+ if ($(MAKEINFO) --version) >/dev/null 2>&1; then \
+ for f in $@ $@-[0-9] $@-[0-9][0-9] $(@:.info=).i[0-9] $(@:.info=).i[0-9][0-9]; do \
+ if test -f $$f; then mv $$f $$backupdir; restore=mv; else :; fi; \
+ done; \
+ else :; fi && \
+ if $(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir) \
+ -o $@ `test -f 'bfd.texinfo' || echo '$(srcdir)/'`bfd.texinfo; \
+ then \
+ rc=0; \
+ else \
+ rc=$$?; \
+ $$restore $$backupdir/* `echo "./$@" | sed 's|[^/]*$$||'`; \
+ fi; \
+ rm -rf $$backupdir; exit $$rc
+
+bfd.dvi: bfd.texinfo $(bfd_TEXINFOS)
+ TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \
+ MAKEINFO='$(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir)' \
+ $(TEXI2DVI) -o $@ `test -f 'bfd.texinfo' || echo '$(srcdir)/'`bfd.texinfo
+
+bfd.pdf: bfd.texinfo $(bfd_TEXINFOS)
+ TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \
+ MAKEINFO='$(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir)' \
+ $(TEXI2PDF) -o $@ `test -f 'bfd.texinfo' || echo '$(srcdir)/'`bfd.texinfo
+
+bfd.html: bfd.texinfo $(bfd_TEXINFOS)
+ rm -rf $(@:.html=.htp)
+ if $(MAKEINFOHTML) $(AM_MAKEINFOHTMLFLAGS) $(MAKEINFOFLAGS) -I $(srcdir) \
+ -o $(@:.html=.htp) `test -f 'bfd.texinfo' || echo '$(srcdir)/'`bfd.texinfo; \
+ then \
+ rm -rf $@; \
+ if test ! -d $(@:.html=.htp) && test -d $(@:.html=); then \
+ mv $(@:.html=) $@; else mv $(@:.html=.htp) $@; fi; \
+ else \
+ if test ! -d $(@:.html=.htp) && test -d $(@:.html=); then \
+ rm -rf $(@:.html=); else rm -Rf $(@:.html=.htp) $@; fi; \
+ exit 1; \
+ fi
+.dvi.ps:
+ TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \
+ $(DVIPS) -o $@ $<
+
+uninstall-dvi-am:
+ @$(NORMAL_UNINSTALL)
+ @list='$(DVIS)'; test -n "$(dvidir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " rm -f '$(DESTDIR)$(dvidir)/$$f'"; \
+ rm -f "$(DESTDIR)$(dvidir)/$$f"; \
+ done
+
+uninstall-html-am:
+ @$(NORMAL_UNINSTALL)
+ @list='$(HTMLS)'; test -n "$(htmldir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " rm -rf '$(DESTDIR)$(htmldir)/$$f'"; \
+ rm -rf "$(DESTDIR)$(htmldir)/$$f"; \
+ done
+
+uninstall-info-am:
+ @$(PRE_UNINSTALL)
+ @if test -d '$(DESTDIR)$(infodir)' && \
+ (install-info --version && \
+ install-info --version 2>&1 | sed 1q | grep -i -v debian) >/dev/null 2>&1; then \
+ list='$(INFO_DEPS)'; \
+ for file in $$list; do \
+ relfile=`echo "$$file" | sed 's|^.*/||'`; \
+ echo " install-info --info-dir='$(DESTDIR)$(infodir)' --remove '$(DESTDIR)$(infodir)/$$relfile'"; \
+ if install-info --info-dir="$(DESTDIR)$(infodir)" --remove "$(DESTDIR)$(infodir)/$$relfile"; \
+ then :; else test ! -f "$(DESTDIR)$(infodir)/$$relfile" || exit 1; fi; \
+ done; \
+ else :; fi
+ @$(NORMAL_UNINSTALL)
+ @list='$(INFO_DEPS)'; \
+ for file in $$list; do \
+ relfile=`echo "$$file" | sed 's|^.*/||'`; \
+ relfile_i=`echo "$$relfile" | sed 's|\.info$$||;s|$$|.i|'`; \
+ (if test -d "$(DESTDIR)$(infodir)" && cd "$(DESTDIR)$(infodir)"; then \
+ echo " cd '$(DESTDIR)$(infodir)' && rm -f $$relfile $$relfile-[0-9] $$relfile-[0-9][0-9] $$relfile_i[0-9] $$relfile_i[0-9][0-9]"; \
+ rm -f $$relfile $$relfile-[0-9] $$relfile-[0-9][0-9] $$relfile_i[0-9] $$relfile_i[0-9][0-9]; \
+ else :; fi); \
+ done
+
+uninstall-pdf-am:
+ @$(NORMAL_UNINSTALL)
+ @list='$(PDFS)'; test -n "$(pdfdir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " rm -f '$(DESTDIR)$(pdfdir)/$$f'"; \
+ rm -f "$(DESTDIR)$(pdfdir)/$$f"; \
+ done
+
+uninstall-ps-am:
+ @$(NORMAL_UNINSTALL)
+ @list='$(PSS)'; test -n "$(psdir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " rm -f '$(DESTDIR)$(psdir)/$$f'"; \
+ rm -f "$(DESTDIR)$(psdir)/$$f"; \
+ done
+
+dist-info: $(INFO_DEPS)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
+ list='$(INFO_DEPS)'; \
+ for base in $$list; do \
+ case $$base in \
+ $(srcdir)/*) base=`echo "$$base" | sed "s|^$$srcdirstrip/||"`;; \
+ esac; \
+ if test -f $$base; then d=.; else d=$(srcdir); fi; \
+ base_i=`echo "$$base" | sed 's|\.info$$||;s|$$|.i|'`; \
+ for file in $$d/$$base $$d/$$base-[0-9] $$d/$$base-[0-9][0-9] $$d/$$base_i[0-9] $$d/$$base_i[0-9][0-9]; do \
+ if test -f $$file; then \
+ relfile=`expr "$$file" : "$$d/\(.*\)"`; \
+ test -f "$(distdir)/$$relfile" || \
+ cp -p $$file "$(distdir)/$$relfile"; \
+ else :; fi; \
+ done; \
+ done
+
+mostlyclean-aminfo:
+ -rm -rf bfd.aux bfd.cp bfd.cps bfd.fn bfd.ky bfd.kys bfd.log bfd.pg bfd.pgs \
+ bfd.tmp bfd.toc bfd.tp bfd.tps bfd.vr bfd.vrs
+
+clean-aminfo:
+ -test -z "bfd.dvi bfd.pdf bfd.ps bfd.html" \
+ || rm -rf bfd.dvi bfd.pdf bfd.ps bfd.html
+
+maintainer-clean-aminfo:
+ @list='$(INFO_DEPS)'; for i in $$list; do \
+ i_i=`echo "$$i" | sed 's|\.info$$||;s|$$|.i|'`; \
+ echo " rm -f $$i $$i-[0-9] $$i-[0-9][0-9] $$i_i[0-9] $$i_i[0-9][0-9]"; \
+ rm -f $$i $$i-[0-9] $$i-[0-9][0-9] $$i_i[0-9] $$i_i[0-9][0-9]; \
+ done
+
+clean-info: mostlyclean-aminfo clean-aminfo
+tags: TAGS
+TAGS:
+
+ctags: CTAGS
+CTAGS:
+
+check-am:
+check: check-am
+all-am: Makefile
+installdirs:
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+ -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES)
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+ -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+ -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+clean: clean-am
+
+clean-am: clean-aminfo clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-am
+ -rm -f Makefile
+distclean-am: clean-am distclean-generic
+
+dvi: dvi-am
+
+dvi-am: $(DVIS)
+
+html: html-am
+
+html-am: $(HTMLS)
+
+info: info-am
+
+info-am: $(INFO_DEPS)
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am: $(DVIS)
+ @$(NORMAL_INSTALL)
+ test -z "$(dvidir)" || $(MKDIR_P) "$(DESTDIR)$(dvidir)"
+ @list='$(DVIS)'; test -n "$(dvidir)" || list=; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(dvidir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(dvidir)" || exit $$?; \
+ done
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am: $(HTMLS)
+ @$(NORMAL_INSTALL)
+ test -z "$(htmldir)" || $(MKDIR_P) "$(DESTDIR)$(htmldir)"
+ @list='$(HTMLS)'; list2=; test -n "$(htmldir)" || list=; \
+ for p in $$list; do \
+ if test -f "$$p" || test -d "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ $(am__strip_dir) \
+ if test -d "$$d$$p"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(htmldir)/$$f'"; \
+ $(MKDIR_P) "$(DESTDIR)$(htmldir)/$$f" || exit 1; \
+ echo " $(INSTALL_DATA) '$$d$$p'/* '$(DESTDIR)$(htmldir)/$$f'"; \
+ $(INSTALL_DATA) "$$d$$p"/* "$(DESTDIR)$(htmldir)/$$f" || exit $$?; \
+ else \
+ list2="$$list2 $$d$$p"; \
+ fi; \
+ done; \
+ test -z "$$list2" || { echo "$$list2" | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(htmldir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(htmldir)" || exit $$?; \
+ done; }
+install-info: install-info-am
+
+install-info-am: $(INFO_DEPS)
+ @$(NORMAL_INSTALL)
+ test -z "$(infodir)" || $(MKDIR_P) "$(DESTDIR)$(infodir)"
+ @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
+ list='$(INFO_DEPS)'; test -n "$(infodir)" || list=; \
+ for file in $$list; do \
+ case $$file in \
+ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
+ esac; \
+ if test -f $$file; then d=.; else d=$(srcdir); fi; \
+ file_i=`echo "$$file" | sed 's|\.info$$||;s|$$|.i|'`; \
+ for ifile in $$d/$$file $$d/$$file-[0-9] $$d/$$file-[0-9][0-9] \
+ $$d/$$file_i[0-9] $$d/$$file_i[0-9][0-9] ; do \
+ if test -f $$ifile; then \
+ echo "$$ifile"; \
+ else : ; fi; \
+ done; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(infodir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(infodir)" || exit $$?; done
+ @$(POST_INSTALL)
+ @if (install-info --version && \
+ install-info --version 2>&1 | sed 1q | grep -i -v debian) >/dev/null 2>&1; then \
+ list='$(INFO_DEPS)'; test -n "$(infodir)" || list=; \
+ for file in $$list; do \
+ relfile=`echo "$$file" | sed 's|^.*/||'`; \
+ echo " install-info --info-dir='$(DESTDIR)$(infodir)' '$(DESTDIR)$(infodir)/$$relfile'";\
+ install-info --info-dir="$(DESTDIR)$(infodir)" "$(DESTDIR)$(infodir)/$$relfile" || :;\
+ done; \
+ else : ; fi
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am: $(PDFS)
+ @$(NORMAL_INSTALL)
+ test -z "$(pdfdir)" || $(MKDIR_P) "$(DESTDIR)$(pdfdir)"
+ @list='$(PDFS)'; test -n "$(pdfdir)" || list=; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pdfdir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(pdfdir)" || exit $$?; done
+install-ps: install-ps-am
+
+install-ps-am: $(PSS)
+ @$(NORMAL_INSTALL)
+ test -z "$(psdir)" || $(MKDIR_P) "$(DESTDIR)$(psdir)"
+ @list='$(PSS)'; test -n "$(psdir)" || list=; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(psdir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(psdir)" || exit $$?; done
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-aminfo \
+ maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-aminfo mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am: $(PDFS)
+
+ps: ps-am
+
+ps-am: $(PSS)
+
+uninstall-am: uninstall-dvi-am uninstall-html-am uninstall-info-am \
+ uninstall-pdf-am uninstall-ps-am
+
+.MAKE: install-am install-strip
+
+.PHONY: all all-am check check-am clean clean-aminfo clean-generic \
+ clean-info clean-libtool dist-info distclean distclean-generic \
+ distclean-libtool dvi dvi-am html html-am info info-am install \
+ install-am install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-pdf install-pdf-am install-ps install-ps-am \
+ install-strip installcheck installcheck-am installdirs \
+ maintainer-clean maintainer-clean-aminfo \
+ maintainer-clean-generic mostlyclean mostlyclean-aminfo \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ uninstall uninstall-am uninstall-dvi-am uninstall-html-am \
+ uninstall-info-am uninstall-pdf-am uninstall-ps-am
+
+
+$(MKDOC): chew.stamp ; @true
+chew.stamp: $(srcdir)/chew.c
+ $(CC_FOR_BUILD) -o chw$$$$$(EXEEXT_FOR_BUILD) $(CFLAGS_FOR_BUILD) \
+ $(LDFLAGS_FOR_BUILD) $(H_CFLAGS) $(AM_CPPFLAGS) $(srcdir)/chew.c; \
+ $(SHELL) $(srcdir)/../../move-if-change \
+ chw$$$$$(EXEEXT_FOR_BUILD) $(MKDOC); \
+ touch $@
+
+protos: libbfd.h libcoff.h bfd.h
+
+# We can't replace these rules with an implicit rule, because
+# makes without VPATH support couldn't find the .h files in `..'.
+
+# We do not depend on chew directly 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 nothing will be rebuilt.
+
+aoutx.texi: aoutx.stamp ; @true
+aoutx.stamp: $(srcdir)/../aoutx.h $(srcdir)/doc.str $(MKDOC)
+ ./$(MKDOC) -f $(srcdir)/doc.str < $< >aoutx.tmp
+ $(SHELL) $(srcdir)/../../move-if-change aoutx.tmp aoutx.texi
+ touch $@
+
+archive.texi: archive.stamp ; @true
+archive.stamp: $(srcdir)/../archive.c $(srcdir)/doc.str $(MKDOC)
+ ./$(MKDOC) -f $(srcdir)/doc.str < $< >archive.tmp
+ $(SHELL) $(srcdir)/../../move-if-change archive.tmp archive.texi
+ touch $@
+
+archures.texi: archures.stamp ; @true
+archures.stamp: $(srcdir)/../archures.c $(srcdir)/doc.str $(MKDOC)
+ ./$(MKDOC) -f $(srcdir)/doc.str < $< >archures.tmp
+ $(SHELL) $(srcdir)/../../move-if-change archures.tmp archures.texi
+ touch $@
+
+# We use bfdt.texi, rather than bfd.texi, to avoid conflicting with
+# bfd.texinfo on an 8.3 filesystem.
+bfdt.texi: bfdt.stamp ; @true
+bfdt.stamp: $(srcdir)/../bfd.c $(srcdir)/doc.str $(MKDOC)
+ ./$(MKDOC) -f $(srcdir)/doc.str < $< >bfd.tmp
+ $(SHELL) $(srcdir)/../../move-if-change bfd.tmp bfdt.texi
+ touch $@
+
+cache.texi: cache.stamp ; @true
+cache.stamp: $(srcdir)/../cache.c $(srcdir)/doc.str $(MKDOC)
+ ./$(MKDOC) -f $(srcdir)/doc.str < $< >cache.tmp
+ $(SHELL) $(srcdir)/../../move-if-change cache.tmp cache.texi
+ touch $@
+
+coffcode.texi: coffcode.stamp ; @true
+coffcode.stamp: $(srcdir)/../coffcode.h $(srcdir)/doc.str $(MKDOC)
+ ./$(MKDOC) -f $(srcdir)/doc.str < $< >coffcode.tmp
+ $(SHELL) $(srcdir)/../../move-if-change coffcode.tmp coffcode.texi
+ touch $@
+
+core.texi: core.stamp ; @true
+core.stamp: $(srcdir)/../corefile.c $(srcdir)/doc.str $(MKDOC)
+ ./$(MKDOC) -f $(srcdir)/doc.str < $< >core.tmp
+ $(SHELL) $(srcdir)/../../move-if-change core.tmp core.texi
+ touch $@
+
+elf.texi: elf.stamp ; @true
+elf.stamp: $(srcdir)/../elf.c $(srcdir)/doc.str $(MKDOC)
+ ./$(MKDOC) -f $(srcdir)/doc.str < $< >elf.tmp
+ $(SHELL) $(srcdir)/../../move-if-change elf.tmp elf.texi
+ touch $@
+
+elfcode.texi: elfcode.stamp ; @true
+elfcode.stamp: $(srcdir)/../elfcode.h $(srcdir)/doc.str $(MKDOC)
+ ./$(MKDOC) -f $(srcdir)/doc.str < $< >elfcode.tmp
+ $(SHELL) $(srcdir)/../../move-if-change elfcode.tmp elfcode.texi
+ touch $@
+
+mmo.texi: mmo.stamp ; @true
+mmo.stamp: $(srcdir)/../mmo.c $(srcdir)/doc.str $(MKDOC)
+ ./$(MKDOC) -f $(srcdir)/doc.str < $< >mmo.tmp
+ $(SHELL) $(srcdir)/../../move-if-change mmo.tmp mmo.texi
+ touch $@
+
+format.texi: format.stamp ; @true
+format.stamp: $(srcdir)/../format.c $(srcdir)/doc.str $(MKDOC)
+ ./$(MKDOC) -f $(srcdir)/doc.str < $< >format.tmp
+ $(SHELL) $(srcdir)/../../move-if-change format.tmp format.texi
+ touch $@
+
+libbfd.texi: libbfd.stamp ; @true
+libbfd.stamp: $(srcdir)/../libbfd.c $(srcdir)/doc.str $(MKDOC)
+ ./$(MKDOC) -f $(srcdir)/doc.str < $< >libbfd.tmp
+ $(SHELL) $(srcdir)/../../move-if-change libbfd.tmp libbfd.texi
+ touch $@
+
+bfdio.texi: bfdio.stamp ; @true
+bfdio.stamp: $(srcdir)/../bfdio.c $(srcdir)/doc.str $(MKDOC)
+ ./$(MKDOC) -f $(srcdir)/doc.str < $< >bfdio.tmp
+ $(SHELL) $(srcdir)/../../move-if-change bfdio.tmp bfdio.texi
+ touch $@
+
+bfdwin.texi: bfdwin.stamp ; @true
+bfdwin.stamp: $(srcdir)/../bfdwin.c $(srcdir)/doc.str $(MKDOC)
+ ./$(MKDOC) -f $(srcdir)/doc.str < $< >bfdwin.tmp
+ $(SHELL) $(srcdir)/../../move-if-change bfdwin.tmp bfdwin.texi
+ touch $@
+
+opncls.texi: opncls.stamp ; @true
+opncls.stamp: $(srcdir)/../opncls.c $(srcdir)/doc.str $(MKDOC)
+ ./$(MKDOC) -f $(srcdir)/doc.str < $< >opncls.tmp
+ $(SHELL) $(srcdir)/../../move-if-change opncls.tmp opncls.texi
+ touch $@
+
+reloc.texi: reloc.stamp ; @true
+reloc.stamp: $(srcdir)/../reloc.c $(srcdir)/doc.str $(MKDOC)
+ ./$(MKDOC) -f $(srcdir)/doc.str < $< >reloc.tmp
+ $(SHELL) $(srcdir)/../../move-if-change reloc.tmp reloc.texi
+ touch $@
+
+section.texi: section.stamp ; @true
+section.stamp: $(srcdir)/../section.c $(srcdir)/doc.str $(MKDOC)
+ ./$(MKDOC) -f $(srcdir)/doc.str < $< >section.tmp
+ $(SHELL) $(srcdir)/../../move-if-change section.tmp section.texi
+ touch $@
+
+syms.texi: syms.stamp ; @true
+syms.stamp: $(srcdir)/../syms.c $(srcdir)/doc.str $(MKDOC)
+ ./$(MKDOC) -f $(srcdir)/doc.str < $< >syms.tmp
+ $(SHELL) $(srcdir)/../../move-if-change syms.tmp syms.texi
+ touch $@
+
+targets.texi: targets.stamp ; @true
+targets.stamp: $(srcdir)/../targets.c $(srcdir)/doc.str $(MKDOC)
+ ./$(MKDOC) -f $(srcdir)/doc.str < $< >targets.tmp
+ $(SHELL) $(srcdir)/../../move-if-change targets.tmp targets.texi
+ touch $@
+
+init.texi: init.stamp ; @true
+init.stamp: $(srcdir)/../init.c $(srcdir)/doc.str $(MKDOC)
+ ./$(MKDOC) -f $(srcdir)/doc.str < $< >init.tmp
+ $(SHELL) $(srcdir)/../../move-if-change init.tmp init.texi
+ touch $@
+
+hash.texi: hash.stamp ; @true
+hash.stamp: $(srcdir)/../hash.c $(srcdir)/doc.str $(MKDOC)
+ ./$(MKDOC) -f $(srcdir)/doc.str < $< >hash.tmp
+ $(SHELL) $(srcdir)/../../move-if-change hash.tmp hash.texi
+ touch $@
+
+linker.texi: linker.stamp ; @true
+linker.stamp: $(srcdir)/../linker.c $(srcdir)/doc.str $(MKDOC)
+ ./$(MKDOC) -f $(srcdir)/doc.str < $< >linker.tmp
+ $(SHELL) $(srcdir)/../../move-if-change linker.tmp linker.texi
+ touch $@
+
+libbfd.h: $(LIBBFD_H_DEP)
+ echo "$(LIBBFD_H_DEP)" | sed -f $(srcdir)/header.sed > $@
+ for file in $(LIBBFD_H_DEP); do \
+ case $$file in \
+ *-in.h) cat $$file >> $@ ;; \
+ */header.sed) break ;; \
+ *) echo $$file | sed -e 's,.*/,,' -e 's,^,/* Extracted from ,' \
+ -e 's,$$,. */,' >> $@ ; \
+ ./$(MKDOC) -i -f $(srcdir)/proto.str < $$file >> $@ ;; \
+ esac; \
+ done
+
+libcoff.h: $(LIBCOFF_H_DEP)
+ echo "$(LIBCOFF_H_DEP)" | sed -f $(srcdir)/header.sed > $@
+ for file in $(LIBCOFF_H_DEP); do \
+ case $$file in \
+ *-in.h) cat $$file >> $@ ;; \
+ */header.sed) break ;; \
+ *) echo $$file | sed -e 's,.*/,,' -e 's,^,/* Extracted from ,' \
+ -e 's,$$,. */,' >> $@ ; \
+ ./$(MKDOC) -i -f $(srcdir)/proto.str < $$file >> $@ ;; \
+ esac; \
+ done
+
+bfd.h: $(BFD_H_DEP)
+ echo "$(BFD_H_DEP)" | sed -f $(srcdir)/header.sed > $@
+ for file in $(BFD_H_DEP); do \
+ case $$file in \
+ *-in.h) cat $$file >> $@ ;; \
+ */header.sed) break ;; \
+ *) echo $$file | sed -e 's,.*/,,' -e 's,^,/* Extracted from ,' \
+ -e 's,$$,. */,' >> $@ ; \
+ ./$(MKDOC) -f $(srcdir)/proto.str < $$file >> $@ ;; \
+ esac; \
+ done
+ echo "#ifdef __cplusplus" >> $@
+ echo "}" >> $@
+ echo "#endif" >> $@
+ echo "#endif" >> $@
+
+bfdver.texi: $(srcdir)/Makefile.in
+ @echo "creating $@"; \
+ echo "@set VERSION $(VERSION)" > bfdver.texi; \
+ if [ -n "$(PKGVERSION)" ]; then \
+ echo "@set VERSION_PACKAGE $(PKGVERSION)" >> bfdver.texi; \
+ fi; \
+ echo "@set UPDATED `date '+%B %Y'`" >> bfdver.texi; \
+ if [ -n "$(REPORT_BUGS_TEXI)" ]; then \
+ echo "@set BUGURL $(REPORT_BUGS_TEXI)" >> bfdver.texi; \
+ fi
+
+# We want install to imply install-info as per GNU standards, despite the
+# cygnus option.
+install: install-info
+
+# 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/aoutx.texi b/bfd/doc/aoutx.texi
new file mode 100644
index 0000000..2afe59d
--- /dev/null
+++ b/bfd/doc/aoutx.texi
@@ -0,0 +1,213 @@
+@section a.out backends
+
+
+@strong{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
+@code{aout_32_swap_exec_header_in}, @code{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}:
+
+@example
+ #define ARCH_SIZE 32
+ #include "aoutx.h"
+@end example
+
+Which exports names:
+
+@example
+ ...
+ aout_32_canonicalize_reloc
+ aout_32_find_nearest_line
+ aout_32_get_lineno
+ aout_32_get_reloc_upper_bound
+ ...
+@end example
+
+from @file{sunos.c}:
+
+@example
+ #define TARGET_NAME "a.out-sunos-big"
+ #define VECNAME sparc_aout_sunos_be_vec
+ #include "aoutf1.h"
+@end example
+
+requires all the names from @file{aout32.c}, and produces the jump vector
+
+@example
+ sparc_aout_sunos_be_vec
+@end example
+
+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:
+
+@example
+ HOST_PAGE_SIZE
+ HOST_SEGMENT_SIZE
+ HOST_MACHINE_ARCH (optional)
+ HOST_MACHINE_MACHINE (optional)
+ HOST_TEXT_START_ADDR
+ HOST_STACK_END_ADDR
+@end example
+
+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:
+
+@example
+ TDEFAULTS = -DDEFAULT_VECTOR=host_aout_big_vec
+ TDEPFILES= host-aout.o trad-core.o
+@end example
+
+in the @file{config/@var{XXX}.mt} file, and modify @file{configure.ac}
+to use the
+@file{@var{XXX}.mt} file (by setting "@code{bfd_target=XXX}") when your
+configuration is selected.
+
+@subsection Relocations
+
+
+@strong{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.
+
+@subsection Internal entry points
+
+
+@strong{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).
+
+@findex aout_@var{size}_swap_exec_header_in
+@subsubsection @code{aout_@var{size}_swap_exec_header_in}
+@strong{Synopsis}
+@example
+void aout_@var{size}_swap_exec_header_in,
+ (bfd *abfd,
+ struct external_exec *bytes,
+ struct internal_exec *execp);
+@end example
+@strong{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}.
+
+@findex aout_@var{size}_swap_exec_header_out
+@subsubsection @code{aout_@var{size}_swap_exec_header_out}
+@strong{Synopsis}
+@example
+void aout_@var{size}_swap_exec_header_out
+ (bfd *abfd,
+ struct internal_exec *execp,
+ struct external_exec *raw_bytes);
+@end example
+@strong{Description}@*
+Swap the information in an internal exec header structure
+@var{execp} into the buffer @var{raw_bytes} ready for writing to disk.
+
+@findex aout_@var{size}_some_aout_object_p
+@subsubsection @code{aout_@var{size}_some_aout_object_p}
+@strong{Synopsis}
+@example
+const bfd_target *aout_@var{size}_some_aout_object_p
+ (bfd *abfd,
+ struct internal_exec *execp,
+ const bfd_target *(*callback_to_real_object_p) (bfd *));
+@end example
+@strong{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.
+
+@findex aout_@var{size}_mkobject
+@subsubsection @code{aout_@var{size}_mkobject}
+@strong{Synopsis}
+@example
+bfd_boolean aout_@var{size}_mkobject, (bfd *abfd);
+@end example
+@strong{Description}@*
+Initialize BFD @var{abfd} for use with a.out files.
+
+@findex aout_@var{size}_machine_type
+@subsubsection @code{aout_@var{size}_machine_type}
+@strong{Synopsis}
+@example
+enum machine_type aout_@var{size}_machine_type
+ (enum bfd_architecture arch,
+ unsigned long machine,
+ bfd_boolean *unknown);
+@end example
+@strong{Description}@*
+Keep track of machine architecture and machine type for
+a.out's. Return the @code{machine_type} for a particular
+architecture and machine, or @code{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.
+
+@findex aout_@var{size}_set_arch_mach
+@subsubsection @code{aout_@var{size}_set_arch_mach}
+@strong{Synopsis}
+@example
+bfd_boolean aout_@var{size}_set_arch_mach,
+ (bfd *,
+ enum bfd_architecture arch,
+ unsigned long machine);
+@end example
+@strong{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.
+
+@findex aout_@var{size}_new_section_hook
+@subsubsection @code{aout_@var{size}_new_section_hook}
+@strong{Synopsis}
+@example
+bfd_boolean aout_@var{size}_new_section_hook,
+ (bfd *abfd,
+ asection *newsect);
+@end example
+@strong{Description}@*
+Called by the BFD in response to a @code{bfd_make_section}
+request.
+
diff --git a/bfd/doc/archive.texi b/bfd/doc/archive.texi
new file mode 100644
index 0000000..cfb391c
--- /dev/null
+++ b/bfd/doc/archive.texi
@@ -0,0 +1,105 @@
+@section Archives
+
+
+@strong{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 @code{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.
+
+A BFD returned by @code{bfd_openr_next_archived_file} can be
+closed manually with @code{bfd_close}. If you do not close it,
+then a second iteration through the members of an archive may
+return the same BFD. If you close the archive BFD, then all
+the member BFDs will automatically be closed as well.
+
+Archive contents of output BFDs are chained through the
+@code{archive_next} pointer in a BFD. The first one is findable
+through the @code{archive_head} slot of the archive. Set it with
+@code{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 @code{archive.c}.
+
+@subsection Archive functions
+
+
+@findex bfd_get_next_mapent
+@subsubsection @code{bfd_get_next_mapent}
+@strong{Synopsis}
+@example
+symindex bfd_get_next_mapent
+ (bfd *abfd, symindex previous, carsym **sym);
+@end example
+@strong{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 @code{BFD_NO_MORE_SYMBOLS} as the @var{previous} entry to get
+the first one; returns @code{BFD_NO_MORE_SYMBOLS} when you've already
+got the last one.
+
+A @code{carsym} is a canonical archive symbol. The only
+user-visible element is its name, a null-terminated string.
+
+@findex bfd_set_archive_head
+@subsubsection @code{bfd_set_archive_head}
+@strong{Synopsis}
+@example
+bfd_boolean bfd_set_archive_head (bfd *output, bfd *new_head);
+@end example
+@strong{Description}@*
+Set the head of the chain of
+BFDs contained in the archive @var{output} to @var{new_head}.
+
+@findex bfd_openr_next_archived_file
+@subsubsection @code{bfd_openr_next_archived_file}
+@strong{Synopsis}
+@example
+bfd *bfd_openr_next_archived_file (bfd *archive, bfd *previous);
+@end example
+@strong{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.
+
diff --git a/bfd/doc/archures.texi b/bfd/doc/archures.texi
new file mode 100644
index 0000000..3157e50
--- /dev/null
+++ b/bfd/doc/archures.texi
@@ -0,0 +1,720 @@
+@section Architectures
+BFD keeps one atom in a BFD describing the
+architecture of the data attached to the BFD: a pointer to a
+@code{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
+@code{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
+
+
+@strong{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.
+@example
+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
+#define bfd_mach_fido 9
+#define bfd_mach_mcf_isa_a_nodiv 10
+#define bfd_mach_mcf_isa_a 11
+#define bfd_mach_mcf_isa_a_mac 12
+#define bfd_mach_mcf_isa_a_emac 13
+#define bfd_mach_mcf_isa_aplus 14
+#define bfd_mach_mcf_isa_aplus_mac 15
+#define bfd_mach_mcf_isa_aplus_emac 16
+#define bfd_mach_mcf_isa_b_nousp 17
+#define bfd_mach_mcf_isa_b_nousp_mac 18
+#define bfd_mach_mcf_isa_b_nousp_emac 19
+#define bfd_mach_mcf_isa_b 20
+#define bfd_mach_mcf_isa_b_mac 21
+#define bfd_mach_mcf_isa_b_emac 22
+#define bfd_mach_mcf_isa_b_float 23
+#define bfd_mach_mcf_isa_b_float_mac 24
+#define bfd_mach_mcf_isa_b_float_emac 25
+#define bfd_mach_mcf_isa_c 26
+#define bfd_mach_mcf_isa_c_mac 27
+#define bfd_mach_mcf_isa_c_emac 28
+#define bfd_mach_mcf_isa_c_nodiv 29
+#define bfd_mach_mcf_isa_c_nodiv_mac 30
+#define bfd_mach_mcf_isa_c_nodiv_emac 31
+ 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_or1k, /* OpenRISC 1000 */
+#define bfd_mach_or1k 1
+#define bfd_mach_or1knd 2
+
+ 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. */
+#define bfd_mach_sparc_v8plusb 9 /* with cheetah add'ns. */
+#define bfd_mach_sparc_v9b 10 /* with cheetah 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_v9b \
+ && (mach) != bfd_mach_sparc_sparclite_le)
+/* Nonzero if MACH is a 64 bit sparc architecture. */
+#define bfd_mach_sparc_64bit_p(mach) \
+ ((mach) >= bfd_mach_sparc_v9 && (mach) != bfd_mach_sparc_v8plusb)
+ bfd_arch_spu, /* PowerPC SPU */
+#define bfd_mach_spu 256
+ 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_mips4120 4120
+#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_mips5400 5400
+#define bfd_mach_mips5500 5500
+#define bfd_mach_mips5900 5900
+#define bfd_mach_mips6000 6000
+#define bfd_mach_mips7000 7000
+#define bfd_mach_mips8000 8000
+#define bfd_mach_mips9000 9000
+#define bfd_mach_mips10000 10000
+#define bfd_mach_mips12000 12000
+#define bfd_mach_mips14000 14000
+#define bfd_mach_mips16000 16000
+#define bfd_mach_mips16 16
+#define bfd_mach_mips5 5
+#define bfd_mach_mips_loongson_2e 3001
+#define bfd_mach_mips_loongson_2f 3002
+#define bfd_mach_mips_loongson_3a 3003
+#define bfd_mach_mips_sb1 12310201 /* octal 'SB', 01 */
+#define bfd_mach_mips_octeon 6501
+#define bfd_mach_mips_octeonp 6601
+#define bfd_mach_mips_octeon2 6502
+#define bfd_mach_mips_xlr 887682 /* decimal 'XLR' */
+#define bfd_mach_mipsisa32 32
+#define bfd_mach_mipsisa32r2 33
+#define bfd_mach_mipsisa32r3 34
+#define bfd_mach_mipsisa32r5 36
+#define bfd_mach_mipsisa32r6 37
+#define bfd_mach_mipsisa64 64
+#define bfd_mach_mipsisa64r2 65
+#define bfd_mach_mipsisa64r3 66
+#define bfd_mach_mipsisa64r5 68
+#define bfd_mach_mipsisa64r6 69
+#define bfd_mach_mips_micromips 96
+ bfd_arch_i386, /* Intel 386 */
+#define bfd_mach_i386_intel_syntax (1 << 0)
+#define bfd_mach_i386_i8086 (1 << 1)
+#define bfd_mach_i386_i386 (1 << 2)
+#define bfd_mach_x86_64 (1 << 3)
+#define bfd_mach_x64_32 (1 << 4)
+#define bfd_mach_i386_i386_intel_syntax (bfd_mach_i386_i386 | bfd_mach_i386_intel_syntax)
+#define bfd_mach_x86_64_intel_syntax (bfd_mach_x86_64 | bfd_mach_i386_intel_syntax)
+#define bfd_mach_x64_32_intel_syntax (bfd_mach_x64_32 | bfd_mach_i386_intel_syntax)
+ bfd_arch_l1om, /* Intel L1OM */
+#define bfd_mach_l1om (1 << 5)
+#define bfd_mach_l1om_intel_syntax (bfd_mach_l1om | bfd_mach_i386_intel_syntax)
+ bfd_arch_k1om, /* Intel K1OM */
+#define bfd_mach_k1om (1 << 6)
+#define bfd_mach_k1om_intel_syntax (bfd_mach_k1om | bfd_mach_i386_intel_syntax)
+#define bfd_mach_i386_nacl (1 << 7)
+#define bfd_mach_i386_i386_nacl (bfd_mach_i386_i386 | bfd_mach_i386_nacl)
+#define bfd_mach_x86_64_nacl (bfd_mach_x86_64 | bfd_mach_i386_nacl)
+#define bfd_mach_x64_32_nacl (bfd_mach_x64_32 | bfd_mach_i386_nacl)
+ bfd_arch_we32k, /* AT&T WE32xxx */
+ bfd_arch_tahoe, /* CCI/Harris Tahoe */
+ bfd_arch_i860, /* Intel 860 */
+ bfd_arch_i370, /* IBM 360/370 Mainframes */
+ bfd_arch_romp, /* IBM ROMP PC/RT */
+ bfd_arch_convex, /* Convex */
+ bfd_arch_m88k, /* Motorola 88xxx */
+ bfd_arch_m98k, /* Motorola 98xxx */
+ bfd_arch_pyramid, /* Pyramid Technology */
+ bfd_arch_h8300, /* Renesas H8/300 (formerly Hitachi H8/300) */
+#define bfd_mach_h8300 1
+#define bfd_mach_h8300h 2
+#define bfd_mach_h8300s 3
+#define bfd_mach_h8300hn 4
+#define bfd_mach_h8300sn 5
+#define bfd_mach_h8300sx 6
+#define bfd_mach_h8300sxn 7
+ bfd_arch_pdp11, /* DEC PDP-11 */
+ bfd_arch_plugin,
+ bfd_arch_powerpc, /* PowerPC */
+#define bfd_mach_ppc 32
+#define bfd_mach_ppc64 64
+#define bfd_mach_ppc_403 403
+#define bfd_mach_ppc_403gc 4030
+#define bfd_mach_ppc_405 405
+#define bfd_mach_ppc_505 505
+#define bfd_mach_ppc_601 601
+#define bfd_mach_ppc_602 602
+#define bfd_mach_ppc_603 603
+#define bfd_mach_ppc_ec603e 6031
+#define bfd_mach_ppc_604 604
+#define bfd_mach_ppc_620 620
+#define bfd_mach_ppc_630 630
+#define bfd_mach_ppc_750 750
+#define bfd_mach_ppc_860 860
+#define bfd_mach_ppc_a35 35
+#define bfd_mach_ppc_rs64ii 642
+#define bfd_mach_ppc_rs64iii 643
+#define bfd_mach_ppc_7400 7400
+#define bfd_mach_ppc_e500 500
+#define bfd_mach_ppc_e500mc 5001
+#define bfd_mach_ppc_e500mc64 5005
+#define bfd_mach_ppc_e5500 5006
+#define bfd_mach_ppc_e6500 5007
+#define bfd_mach_ppc_titan 83
+#define bfd_mach_ppc_vle 84
+ bfd_arch_rs6000, /* IBM RS/6000 */
+#define bfd_mach_rs6k 6000
+#define bfd_mach_rs6k_rs1 6001
+#define bfd_mach_rs6k_rsc 6003
+#define bfd_mach_rs6k_rs2 6002
+ bfd_arch_hppa, /* HP PA RISC */
+#define bfd_mach_hppa10 10
+#define bfd_mach_hppa11 11
+#define bfd_mach_hppa20 20
+#define bfd_mach_hppa20w 25
+ bfd_arch_d10v, /* Mitsubishi D10V */
+#define bfd_mach_d10v 1
+#define bfd_mach_d10v_ts2 2
+#define bfd_mach_d10v_ts3 3
+ bfd_arch_d30v, /* Mitsubishi D30V */
+ bfd_arch_dlx, /* DLX */
+ bfd_arch_m68hc11, /* Motorola 68HC11 */
+ bfd_arch_m68hc12, /* Motorola 68HC12 */
+#define bfd_mach_m6812_default 0
+#define bfd_mach_m6812 1
+#define bfd_mach_m6812s 2
+ bfd_arch_m9s12x, /* Freescale S12X */
+ bfd_arch_m9s12xg, /* Freescale XGATE */
+ bfd_arch_z8k, /* Zilog Z8000 */
+#define bfd_mach_z8001 1
+#define bfd_mach_z8002 2
+ bfd_arch_h8500, /* Renesas H8/500 (formerly Hitachi H8/500) */
+ bfd_arch_sh, /* Renesas / SuperH SH (formerly Hitachi SH) */
+#define bfd_mach_sh 1
+#define bfd_mach_sh2 0x20
+#define bfd_mach_sh_dsp 0x2d
+#define bfd_mach_sh2a 0x2a
+#define bfd_mach_sh2a_nofpu 0x2b
+#define bfd_mach_sh2a_nofpu_or_sh4_nommu_nofpu 0x2a1
+#define bfd_mach_sh2a_nofpu_or_sh3_nommu 0x2a2
+#define bfd_mach_sh2a_or_sh4 0x2a3
+#define bfd_mach_sh2a_or_sh3e 0x2a4
+#define bfd_mach_sh2e 0x2e
+#define bfd_mach_sh3 0x30
+#define bfd_mach_sh3_nommu 0x31
+#define bfd_mach_sh3_dsp 0x3d
+#define bfd_mach_sh3e 0x3e
+#define bfd_mach_sh4 0x40
+#define bfd_mach_sh4_nofpu 0x41
+#define bfd_mach_sh4_nommu_nofpu 0x42
+#define bfd_mach_sh4a 0x4a
+#define bfd_mach_sh4a_nofpu 0x4b
+#define bfd_mach_sh4al_dsp 0x4d
+#define bfd_mach_sh5 0x50
+ 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_unknown 0
+#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
+#define bfd_mach_arm_5 7
+#define bfd_mach_arm_5T 8
+#define bfd_mach_arm_5TE 9
+#define bfd_mach_arm_XScale 10
+#define bfd_mach_arm_ep9312 11
+#define bfd_mach_arm_iWMMXt 12
+#define bfd_mach_arm_iWMMXt2 13
+ bfd_arch_nds32, /* Andes NDS32 */
+#define bfd_mach_n1 1
+#define bfd_mach_n1h 2
+#define bfd_mach_n1h_v2 3
+#define bfd_mach_n1h_v3 4
+#define bfd_mach_n1h_v3m 5
+ bfd_arch_ns32k, /* National Semiconductors ns32000 */
+ bfd_arch_w65, /* WDC 65816 */
+ bfd_arch_tic30, /* Texas Instruments TMS320C30 */
+ bfd_arch_tic4x, /* Texas Instruments TMS320C3X/4X */
+#define bfd_mach_tic3x 30
+#define bfd_mach_tic4x 40
+ bfd_arch_tic54x, /* Texas Instruments TMS320C54X */
+ bfd_arch_tic6x, /* Texas Instruments TMS320C6X */
+ bfd_arch_tic80, /* TI TMS320c80 (MVP) */
+ bfd_arch_v850, /* NEC V850 */
+ bfd_arch_v850_rh850,/* NEC V850 (using RH850 ABI) */
+#define bfd_mach_v850 1
+#define bfd_mach_v850e 'E'
+#define bfd_mach_v850e1 '1'
+#define bfd_mach_v850e2 0x4532
+#define bfd_mach_v850e2v3 0x45325633
+#define bfd_mach_v850e3v5 0x45335635 /* ('E'|'3'|'V'|'5') */
+ bfd_arch_arc, /* ARC Cores */
+#define bfd_mach_arc_5 5
+#define bfd_mach_arc_6 6
+#define bfd_mach_arc_7 7
+#define bfd_mach_arc_8 8
+ bfd_arch_m32c, /* Renesas M16C/M32C. */
+#define bfd_mach_m16c 0x75
+#define bfd_mach_m32c 0x78
+ bfd_arch_m32r, /* Renesas M32R (formerly Mitsubishi M32R/D) */
+#define bfd_mach_m32r 1 /* For backwards compatibility. */
+#define bfd_mach_m32rx 'x'
+#define bfd_mach_m32r2 '2'
+ bfd_arch_mn10200, /* Matsushita MN10200 */
+ bfd_arch_mn10300, /* Matsushita MN10300 */
+#define bfd_mach_mn10300 300
+#define bfd_mach_am33 330
+#define bfd_mach_am33_2 332
+ bfd_arch_fr30,
+#define bfd_mach_fr30 0x46523330
+ bfd_arch_frv,
+#define bfd_mach_frv 1
+#define bfd_mach_frvsimple 2
+#define bfd_mach_fr300 300
+#define bfd_mach_fr400 400
+#define bfd_mach_fr450 450
+#define bfd_mach_frvtomcat 499 /* fr500 prototype */
+#define bfd_mach_fr500 500
+#define bfd_mach_fr550 550
+ bfd_arch_moxie, /* The moxie processor */
+#define bfd_mach_moxie 1
+ bfd_arch_mcore,
+ bfd_arch_mep,
+#define bfd_mach_mep 1
+#define bfd_mach_mep_h1 0x6831
+#define bfd_mach_mep_c5 0x6335
+ bfd_arch_metag,
+#define bfd_mach_metag 1
+ bfd_arch_ia64, /* HP/Intel ia64 */
+#define bfd_mach_ia64_elf64 64
+#define bfd_mach_ia64_elf32 32
+ bfd_arch_ip2k, /* Ubicom IP2K microcontrollers. */
+#define bfd_mach_ip2022 1
+#define bfd_mach_ip2022ext 2
+ bfd_arch_iq2000, /* Vitesse IQ2000. */
+#define bfd_mach_iq2000 1
+#define bfd_mach_iq10 2
+ bfd_arch_epiphany, /* Adapteva EPIPHANY */
+#define bfd_mach_epiphany16 1
+#define bfd_mach_epiphany32 2
+ bfd_arch_mt,
+#define bfd_mach_ms1 1
+#define bfd_mach_mrisc2 2
+#define bfd_mach_ms2 3
+ bfd_arch_pj,
+ bfd_arch_avr, /* Atmel AVR microcontrollers. */
+#define bfd_mach_avr1 1
+#define bfd_mach_avr2 2
+#define bfd_mach_avr25 25
+#define bfd_mach_avr3 3
+#define bfd_mach_avr31 31
+#define bfd_mach_avr35 35
+#define bfd_mach_avr4 4
+#define bfd_mach_avr5 5
+#define bfd_mach_avr51 51
+#define bfd_mach_avr6 6
+#define bfd_mach_avrtiny 100
+#define bfd_mach_avrxmega1 101
+#define bfd_mach_avrxmega2 102
+#define bfd_mach_avrxmega3 103
+#define bfd_mach_avrxmega4 104
+#define bfd_mach_avrxmega5 105
+#define bfd_mach_avrxmega6 106
+#define bfd_mach_avrxmega7 107
+ bfd_arch_bfin, /* ADI Blackfin */
+#define bfd_mach_bfin 1
+ bfd_arch_cr16, /* National Semiconductor CompactRISC (ie CR16). */
+#define bfd_mach_cr16 1
+ bfd_arch_cr16c, /* National Semiconductor CompactRISC. */
+#define bfd_mach_cr16c 1
+ bfd_arch_crx, /* National Semiconductor CRX. */
+#define bfd_mach_crx 1
+ bfd_arch_cris, /* Axis CRIS */
+#define bfd_mach_cris_v0_v10 255
+#define bfd_mach_cris_v32 32
+#define bfd_mach_cris_v10_v32 1032
+ bfd_arch_rl78,
+#define bfd_mach_rl78 0x75
+ bfd_arch_rx, /* Renesas RX. */
+#define bfd_mach_rx 0x75
+ bfd_arch_s390, /* IBM s390 */
+#define bfd_mach_s390_31 31
+#define bfd_mach_s390_64 64
+ bfd_arch_score, /* Sunplus score */
+#define bfd_mach_score3 3
+#define bfd_mach_score7 7
+ bfd_arch_mmix, /* Donald Knuth's educational processor. */
+ bfd_arch_xstormy16,
+#define bfd_mach_xstormy16 1
+ bfd_arch_msp430, /* Texas Instruments MSP430 architecture. */
+#define bfd_mach_msp11 11
+#define bfd_mach_msp110 110
+#define bfd_mach_msp12 12
+#define bfd_mach_msp13 13
+#define bfd_mach_msp14 14
+#define bfd_mach_msp15 15
+#define bfd_mach_msp16 16
+#define bfd_mach_msp20 20
+#define bfd_mach_msp21 21
+#define bfd_mach_msp22 22
+#define bfd_mach_msp23 23
+#define bfd_mach_msp24 24
+#define bfd_mach_msp26 26
+#define bfd_mach_msp31 31
+#define bfd_mach_msp32 32
+#define bfd_mach_msp33 33
+#define bfd_mach_msp41 41
+#define bfd_mach_msp42 42
+#define bfd_mach_msp43 43
+#define bfd_mach_msp44 44
+#define bfd_mach_msp430x 45
+#define bfd_mach_msp46 46
+#define bfd_mach_msp47 47
+#define bfd_mach_msp54 54
+ bfd_arch_xc16x, /* Infineon's XC16X Series. */
+#define bfd_mach_xc16x 1
+#define bfd_mach_xc16xl 2
+#define bfd_mach_xc16xs 3
+ bfd_arch_xgate, /* Freescale XGATE */
+#define bfd_mach_xgate 1
+ bfd_arch_xtensa, /* Tensilica's Xtensa cores. */
+#define bfd_mach_xtensa 1
+ bfd_arch_z80,
+#define bfd_mach_z80strict 1 /* No undocumented opcodes. */
+#define bfd_mach_z80 3 /* With ixl, ixh, iyl, and iyh. */
+#define bfd_mach_z80full 7 /* All undocumented instructions. */
+#define bfd_mach_r800 11 /* R800: successor with multiplication. */
+ bfd_arch_lm32, /* Lattice Mico32 */
+#define bfd_mach_lm32 1
+ bfd_arch_microblaze,/* Xilinx MicroBlaze. */
+ bfd_arch_tilepro, /* Tilera TILEPro */
+ bfd_arch_tilegx, /* Tilera TILE-Gx */
+#define bfd_mach_tilepro 1
+#define bfd_mach_tilegx 1
+#define bfd_mach_tilegx32 2
+ bfd_arch_aarch64, /* AArch64 */
+#define bfd_mach_aarch64 0
+#define bfd_mach_aarch64_ilp32 32
+ bfd_arch_nios2,
+#define bfd_mach_nios2 0
+ bfd_arch_last
+ @};
+@end example
+
+@subsection bfd_arch_info
+
+
+@strong{Description}@*
+This structure contains information on architectures for use
+within BFD.
+@example
+
+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.
+ The default arch should be the first entry for an arch so that
+ all the entries for that arch can be accessed via @code{next}. */
+ bfd_boolean the_default;
+ const struct bfd_arch_info * (*compatible)
+ (const struct bfd_arch_info *a, const struct bfd_arch_info *b);
+
+ bfd_boolean (*scan) (const struct bfd_arch_info *, const char *);
+
+ /* Allocate via bfd_malloc and return a fill buffer of size COUNT. If
+ IS_BIGENDIAN is TRUE, the order of bytes is big endian. If CODE is
+ TRUE, the buffer contains code. */
+ void *(*fill) (bfd_size_type count, bfd_boolean is_bigendian,
+ bfd_boolean code);
+
+ const struct bfd_arch_info *next;
+@}
+bfd_arch_info_type;
+
+@end example
+
+@findex bfd_printable_name
+@subsubsection @code{bfd_printable_name}
+@strong{Synopsis}
+@example
+const char *bfd_printable_name (bfd *abfd);
+@end example
+@strong{Description}@*
+Return a printable string representing the architecture and machine
+from the pointer to the architecture info structure.
+
+@findex bfd_scan_arch
+@subsubsection @code{bfd_scan_arch}
+@strong{Synopsis}
+@example
+const bfd_arch_info_type *bfd_scan_arch (const char *string);
+@end example
+@strong{Description}@*
+Figure out if BFD supports any cpu which could be described with
+the name @var{string}. Return a pointer to an @code{arch_info}
+structure if a machine is found, otherwise NULL.
+
+@findex bfd_arch_list
+@subsubsection @code{bfd_arch_list}
+@strong{Synopsis}
+@example
+const char **bfd_arch_list (void);
+@end example
+@strong{Description}@*
+Return a freshly malloced NULL-terminated vector of the names
+of all the valid BFD architectures. Do not modify the names.
+
+@findex bfd_arch_get_compatible
+@subsubsection @code{bfd_arch_get_compatible}
+@strong{Synopsis}
+@example
+const bfd_arch_info_type *bfd_arch_get_compatible
+ (const bfd *abfd, const bfd *bbfd, bfd_boolean accept_unknowns);
+@end example
+@strong{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 @code{arch_info} structure
+describing the compatible machine.
+
+@findex bfd_default_arch_struct
+@subsubsection @code{bfd_default_arch_struct}
+@strong{Description}@*
+The @code{bfd_default_arch_struct} is an item of
+@code{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.
+@example
+extern const bfd_arch_info_type bfd_default_arch_struct;
+@end example
+
+@findex bfd_set_arch_info
+@subsubsection @code{bfd_set_arch_info}
+@strong{Synopsis}
+@example
+void bfd_set_arch_info (bfd *abfd, const bfd_arch_info_type *arg);
+@end example
+@strong{Description}@*
+Set the architecture info of @var{abfd} to @var{arg}.
+
+@findex bfd_default_set_arch_mach
+@subsubsection @code{bfd_default_set_arch_mach}
+@strong{Synopsis}
+@example
+bfd_boolean bfd_default_set_arch_mach
+ (bfd *abfd, enum bfd_architecture arch, unsigned long mach);
+@end example
+@strong{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 @code{arch_info}
+pointer.
+
+@findex bfd_get_arch
+@subsubsection @code{bfd_get_arch}
+@strong{Synopsis}
+@example
+enum bfd_architecture bfd_get_arch (bfd *abfd);
+@end example
+@strong{Description}@*
+Return the enumerated type which describes the BFD @var{abfd}'s
+architecture.
+
+@findex bfd_get_mach
+@subsubsection @code{bfd_get_mach}
+@strong{Synopsis}
+@example
+unsigned long bfd_get_mach (bfd *abfd);
+@end example
+@strong{Description}@*
+Return the long type which describes the BFD @var{abfd}'s
+machine.
+
+@findex bfd_arch_bits_per_byte
+@subsubsection @code{bfd_arch_bits_per_byte}
+@strong{Synopsis}
+@example
+unsigned int bfd_arch_bits_per_byte (bfd *abfd);
+@end example
+@strong{Description}@*
+Return the number of bits in one of the BFD @var{abfd}'s
+architecture's bytes.
+
+@findex bfd_arch_bits_per_address
+@subsubsection @code{bfd_arch_bits_per_address}
+@strong{Synopsis}
+@example
+unsigned int bfd_arch_bits_per_address (bfd *abfd);
+@end example
+@strong{Description}@*
+Return the number of bits in one of the BFD @var{abfd}'s
+architecture's addresses.
+
+@findex bfd_default_compatible
+@subsubsection @code{bfd_default_compatible}
+@strong{Synopsis}
+@example
+const bfd_arch_info_type *bfd_default_compatible
+ (const bfd_arch_info_type *a, const bfd_arch_info_type *b);
+@end example
+@strong{Description}@*
+The default function for testing for compatibility.
+
+@findex bfd_default_scan
+@subsubsection @code{bfd_default_scan}
+@strong{Synopsis}
+@example
+bfd_boolean bfd_default_scan
+ (const struct bfd_arch_info *info, const char *string);
+@end example
+@strong{Description}@*
+The default function for working out whether this is an
+architecture hit and a machine hit.
+
+@findex bfd_get_arch_info
+@subsubsection @code{bfd_get_arch_info}
+@strong{Synopsis}
+@example
+const bfd_arch_info_type *bfd_get_arch_info (bfd *abfd);
+@end example
+@strong{Description}@*
+Return the architecture info struct in @var{abfd}.
+
+@findex bfd_lookup_arch
+@subsubsection @code{bfd_lookup_arch}
+@strong{Synopsis}
+@example
+const bfd_arch_info_type *bfd_lookup_arch
+ (enum bfd_architecture arch, unsigned long machine);
+@end example
+@strong{Description}@*
+Look for the architecture 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.
+
+@findex bfd_printable_arch_mach
+@subsubsection @code{bfd_printable_arch_mach}
+@strong{Synopsis}
+@example
+const char *bfd_printable_arch_mach
+ (enum bfd_architecture arch, unsigned long machine);
+@end example
+@strong{Description}@*
+Return a printable string representing the architecture and
+machine type.
+
+This routine is depreciated.
+
+@findex bfd_octets_per_byte
+@subsubsection @code{bfd_octets_per_byte}
+@strong{Synopsis}
+@example
+unsigned int bfd_octets_per_byte (bfd *abfd);
+@end example
+@strong{Description}@*
+Return the number of octets (8-bit quantities) per target byte
+(minimum addressable unit). In most cases, this will be one, but some
+DSP targets have 16, 32, or even 48 bits per byte.
+
+@findex bfd_arch_mach_octets_per_byte
+@subsubsection @code{bfd_arch_mach_octets_per_byte}
+@strong{Synopsis}
+@example
+unsigned int bfd_arch_mach_octets_per_byte
+ (enum bfd_architecture arch, unsigned long machine);
+@end example
+@strong{Description}@*
+See bfd_octets_per_byte.
+
+This routine is provided for those cases where a bfd * is not
+available
+
+@findex bfd_arch_default_fill
+@subsubsection @code{bfd_arch_default_fill}
+@strong{Synopsis}
+@example
+void *bfd_arch_default_fill (bfd_size_type count,
+ bfd_boolean is_bigendian,
+ bfd_boolean code);
+@end example
+@strong{Description}@*
+Allocate via bfd_malloc and return a fill buffer of size COUNT.
+If IS_BIGENDIAN is TRUE, the order of bytes is big endian. If
+CODE is TRUE, the buffer contains code.
+
diff --git a/bfd/doc/bfd.info b/bfd/doc/bfd.info
new file mode 100644
index 0000000..2b46faa
--- /dev/null
+++ b/bfd/doc/bfd.info
@@ -0,0 +1,13716 @@
+This is bfd.info, produced by makeinfo version 4.8 from bfd.texinfo.
+
+INFO-DIR-SECTION Software development
+START-INFO-DIR-ENTRY
+* Bfd: (bfd). The Binary File Descriptor library.
+END-INFO-DIR-ENTRY
+
+ This file documents the BFD library.
+
+ Copyright (C) 1991-2014 Free Software Foundation, Inc.
+
+ Permission is granted to copy, distribute and/or modify this document
+under the terms of the GNU Free Documentation License, Version 1.3 or
+any later version published by the Free Software Foundation; with the
+Invariant Sections being "GNU General Public License" and "Funding Free
+Software", the Front-Cover texts being (a) (see below), and with the
+Back-Cover Texts being (b) (see below). A copy of the license is
+included in the section entitled "GNU Free Documentation License".
+
+ (a) The FSF's Front-Cover Text is:
+
+ A GNU Manual
+
+ (b) The FSF's Back-Cover Text is:
+
+ You have freedom to copy and modify this GNU Manual, like GNU
+software. Copies published by the Free Software Foundation raise
+funds for GNU development.
+
+
+File: bfd.info, Node: Top, Next: Overview, Prev: (dir), Up: (dir)
+
+ This file documents the binary file descriptor library libbfd.
+
+* Menu:
+
+* Overview:: Overview of BFD
+* BFD front end:: BFD front end
+* BFD back ends:: BFD back ends
+* GNU Free Documentation License:: GNU Free Documentation License
+* BFD Index:: BFD Index
+
+
+File: bfd.info, Node: Overview, Next: BFD front end, Prev: Top, Up: Top
+
+1 Introduction
+**************
+
+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).
+ * 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.
+
+ * 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.
+
+* Menu:
+
+* History:: History
+* How It Works:: How It Works
+* What BFD Version 2 Can Do:: What BFD Version 2 Can Do
+
+
+File: bfd.info, Node: History, Next: How It Works, Prev: Overview, Up: Overview
+
+1.1 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 (`sac@cygnus.com'), John Gilmore (`gnu@cygnus.com'), K.
+Richard Pixley (`rich@cygnus.com') and David Henkel-Wallace
+(`gumby@cygnus.com').
+
+
+File: bfd.info, Node: How It Works, Next: What BFD Version 2 Can Do, Prev: History, Up: Overview
+
+1.2 How To Use BFD
+==================
+
+To use the library, include `bfd.h' and link with `libbfd.a'.
+
+ BFD provides a common interface to the parts of an object file for a
+calling application.
+
+ When an application successfully opens a target file (object,
+archive, or whatever), a pointer to an internal structure is returned.
+This pointer points to a structure called `bfd', described in `bfd.h'.
+Our convention is to call this pointer a BFD, and instances of it
+within code `abfd'. All operations on the target object file are
+applied as methods to the BFD. The mapping is defined within `bfd.h'
+in a set of macros, all beginning with `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
+`abfd'.
+
+ #include "bfd.h"
+
+ unsigned int number_of_sections (abfd)
+ bfd *abfd;
+ {
+ return bfd_count_sections (abfd);
+ }
+
+ The abstraction used within BFD is that an object file has:
+
+ * a header,
+
+ * a number of sections containing raw data (*note Sections::),
+
+ * a set of relocations (*note Relocations::), and
+
+ * some symbol information (*note Symbols::).
+ 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.
+
+
+File: bfd.info, Node: What BFD Version 2 Can Do, Prev: How It Works, Up: Overview
+
+1.3 What BFD Version 2 Can Do
+=============================
+
+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 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
+
+
+File: bfd.info, Node: BFD information loss, Next: Canonical format, Up: What BFD Version 2 Can Do
+
+1.3.1 Information Loss
+----------------------
+
+_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 `b.out'. There is nowhere
+in an `a.out' format file to store alignment information on the
+contained data, so when a file is linked from `b.out' and an `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., `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.
+
+ _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 `a.out' to
+`b.out'. When a mixture of formats is linked, the information is only
+lost from the files whose format differs from the destination.
+
+
+File: bfd.info, Node: Canonical format, Prev: BFD information loss, Up: What BFD Version 2 Can Do
+
+1.3.2 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.
+
+_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 `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.
+
+_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.
+
+_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. `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 `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.
+
+_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.
+
+_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).
+
+
+File: bfd.info, Node: BFD front end, Next: BFD back ends, Prev: Overview, Up: Top
+
+2 BFD Front End
+***************
+
+* Menu:
+
+* typedef bfd::
+* Error reporting::
+* Miscellaneous::
+* Memory Usage::
+* Initialization::
+* Sections::
+* Symbols::
+* Archives::
+* Formats::
+* Relocations::
+* Core Files::
+* Targets::
+* Architectures::
+* Opening and Closing::
+* Internal::
+* File Caching::
+* Linker Functions::
+* Hash Tables::
+
+
+File: bfd.info, Node: typedef bfd, Next: Error reporting, Prev: BFD front end, Up: BFD front end
+
+2.1 `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.
+
+
+ enum bfd_direction
+ {
+ no_direction = 0,
+ read_direction = 1,
+ write_direction = 2,
+ both_direction = 3
+ };
+
+ 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;
+
+ /* The IOSTREAM, and corresponding IO vector that provide access
+ to the file backing the BFD. */
+ void *iostream;
+ const struct bfd_iovec *iovec;
+
+ /* 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... */
+ ufile_ptr where;
+
+ /* File modified time, if mtime_set is TRUE. */
+ long mtime;
+
+ /* A unique identifier of the BFD */
+ unsigned int id;
+
+ /* The format which belongs to the BFD. (object, core, etc.) */
+ ENUM_BITFIELD (bfd_format) format : 3;
+
+ /* The direction with which the BFD was opened. */
+ ENUM_BITFIELD (bfd_direction) direction : 2;
+
+ /* Format_specific flags. */
+ flagword flags : 17;
+
+ /* 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). */
+
+ #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
+
+ /* This BFD has been created by the linker and doesn't correspond
+ to any input file. */
+ #define BFD_LINKER_CREATED 0x1000
+
+ /* This may be set before writing out a BFD to request that it
+ be written using values for UIDs, GIDs, timestamps, etc. that
+ will be consistent from run to run. */
+ #define BFD_DETERMINISTIC_OUTPUT 0x2000
+
+ /* Compress sections in this BFD. */
+ #define BFD_COMPRESS 0x4000
+
+ /* Decompress sections in this BFD. */
+ #define BFD_DECOMPRESS 0x8000
+
+ /* BFD is a dummy, for plugins. */
+ #define BFD_PLUGIN 0x10000
+
+ /* Flags bits to be saved in bfd_preserve_save. */
+ #define BFD_FLAGS_SAVED \
+ (BFD_IN_MEMORY | BFD_COMPRESS | BFD_DECOMPRESS | BFD_PLUGIN)
+
+ /* Flags bits which are for BFD use only. */
+ #define BFD_FLAGS_FOR_BFD_USE_MASK \
+ (BFD_IN_MEMORY | BFD_COMPRESS | BFD_DECOMPRESS | BFD_LINKER_CREATED \
+ | BFD_PLUGIN | BFD_TRADITIONAL_FORMAT | BFD_DETERMINISTIC_OUTPUT)
+
+ /* Is the file descriptor being cached? That is, can it be closed as
+ needed, and re-opened when accessed later? */
+ unsigned int cacheable : 1;
+
+ /* 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. */
+ unsigned int target_defaulted : 1;
+
+ /* ... and here: (``once'' means at least once). */
+ unsigned int opened_once : 1;
+
+ /* Set if we have a locally maintained mtime value, rather than
+ getting it from the file each time. */
+ unsigned int mtime_set : 1;
+
+ /* Flag set if symbols from this BFD should not be exported. */
+ unsigned int no_export : 1;
+
+ /* Remember when output has begun, to stop strange things
+ from happening. */
+ unsigned int output_has_begun : 1;
+
+ /* Have archive map. */
+ unsigned int has_armap : 1;
+
+ /* Set if this is a thin archive. */
+ unsigned int is_thin_archive : 1;
+
+ /* Set if only required symbols should be added in the link hash table for
+ this object. Used by VMS linkers. */
+ unsigned int selective_search : 1;
+
+ /* Set if this is the linker output BFD. */
+ unsigned int is_linker_output : 1;
+
+ /* 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. */
+ ufile_ptr origin;
+
+ /* The origin in the archive of the proxy entry. This will
+ normally be the same as origin, except for thin archives,
+ when it will contain the current offset of the proxy in the
+ thin archive rather than the offset of the bfd in its actual
+ container. */
+ ufile_ptr proxy_origin;
+
+ /* A hash table for section names. */
+ struct bfd_hash_table section_htab;
+
+ /* Pointer to linked list of sections. */
+ struct bfd_section *sections;
+
+ /* The last section on the section list. */
+ struct bfd_section *section_last;
+
+ /* The number of sections. */
+ unsigned int section_count;
+
+ /* A field used by _bfd_generic_link_add_archive_symbols. This will
+ be used only for archive elements. */
+ int archive_pass;
+
+ /* Stuff only useful for object files:
+ The start address. */
+ bfd_vma start_address;
+
+ /* Symbol table for output BFD (with symcount entries).
+ Also used by the linker to cache input BFD symbols. */
+ struct bfd_symbol **outsymbols;
+
+ /* Used for input and output. */
+ unsigned int symcount;
+
+ /* Used for slurped dynamic symbol tables. */
+ unsigned int dynsymcount;
+
+ /* Pointer to structure which contains architecture information. */
+ const struct bfd_arch_info *arch_info;
+
+ /* Stuff only useful for archives. */
+ void *arelt_data;
+ struct bfd *my_archive; /* The containing archive BFD. */
+ struct bfd *archive_next; /* The next BFD in the archive. */
+ struct bfd *archive_head; /* The first BFD in the archive. */
+ struct bfd *nested_archives; /* List of nested archive in a flattened
+ thin archive. */
+
+ union {
+ /* For input BFDs, a chain of BFDs involved in a link. */
+ struct bfd *next;
+ /* For output BFD, the linker hash table. */
+ struct bfd_link_hash_table *hash;
+ } link;
+
+ /* 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 verilog_data_struct *verilog_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 mmo_data_struct *mmo_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;
+ struct mach_o_data_struct *mach_o_data;
+ struct mach_o_fat_data_struct *mach_o_fat_data;
+ struct plugin_data_struct *plugin_data;
+ struct bfd_pef_data_struct *pef_data;
+ struct bfd_pef_xlib_data_struct *pef_xlib_data;
+ struct bfd_sym_data_struct *sym_data;
+ void *any;
+ }
+ tdata;
+
+ /* Used by the application to hold private data. */
+ void *usrdata;
+
+ /* Where all the allocated stuff under this BFD goes. This is a
+ struct objalloc *, but we use void * to avoid requiring the inclusion
+ of objalloc.h. */
+ void *memory;
+ };
+
+ /* See note beside bfd_set_section_userdata. */
+ static inline bfd_boolean
+ bfd_set_cacheable (bfd * abfd, bfd_boolean val)
+ {
+ abfd->cacheable = val;
+ return TRUE;
+ }
+
+
+File: bfd.info, Node: Error reporting, Next: Miscellaneous, Prev: typedef bfd, Up: BFD front end
+
+2.2 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'.
+
+2.2.1 Type `bfd_error_type'
+---------------------------
+
+The values returned by `bfd_get_error' are defined by the enumerated
+type `bfd_error_type'.
+
+
+ typedef enum bfd_error
+ {
+ bfd_error_no_error = 0,
+ bfd_error_system_call,
+ bfd_error_invalid_target,
+ bfd_error_wrong_format,
+ bfd_error_wrong_object_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_missing_dso,
+ 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_on_input,
+ bfd_error_invalid_error_code
+ }
+ bfd_error_type;
+
+2.2.1.1 `bfd_get_error'
+.......................
+
+*Synopsis*
+ bfd_error_type bfd_get_error (void);
+ *Description*
+Return the current BFD error condition.
+
+2.2.1.2 `bfd_set_error'
+.......................
+
+*Synopsis*
+ void bfd_set_error (bfd_error_type error_tag, ...);
+ *Description*
+Set the BFD error condition to be ERROR_TAG. If ERROR_TAG is
+bfd_error_on_input, then this function takes two more parameters, the
+input bfd where the error occurred, and the bfd_error_type error.
+
+2.2.1.3 `bfd_errmsg'
+....................
+
+*Synopsis*
+ const char *bfd_errmsg (bfd_error_type error_tag);
+ *Description*
+Return a string describing the error ERROR_TAG, or the system error if
+ERROR_TAG is `bfd_error_system_call'.
+
+2.2.1.4 `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 MESSAGE is non-NULL and non-empty, the error
+string printed is preceded by MESSAGE, a colon, and a space. It is
+followed by a newline.
+
+2.2.2 BFD error handler
+-----------------------
+
+Some BFD functions want to print messages describing the problem. They
+call a BFD error handler function. This function may be overridden by
+the program.
+
+ The BFD error handler acts like printf.
+
+
+ typedef void (*bfd_error_handler_type) (const char *, ...);
+
+2.2.2.1 `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.
+
+2.2.2.2 `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.
+
+2.2.2.3 `bfd_get_error_handler'
+...............................
+
+*Synopsis*
+ bfd_error_handler_type bfd_get_error_handler (void);
+ *Description*
+Return the BFD error handler function.
+
+2.2.3 BFD assert handler
+------------------------
+
+If BFD finds an internal inconsistency, the bfd assert handler is
+called with information on the BFD version, BFD source file and line.
+If this happens, most programs linked against BFD are expected to want
+to exit with an error, or mark the current BFD operation as failed, so
+it is recommended to override the default handler, which just calls
+_bfd_error_handler and continues.
+
+
+ typedef void (*bfd_assert_handler_type) (const char *bfd_formatmsg,
+ const char *bfd_version,
+ const char *bfd_file,
+ int bfd_line);
+
+2.2.3.1 `bfd_set_assert_handler'
+................................
+
+*Synopsis*
+ bfd_assert_handler_type bfd_set_assert_handler (bfd_assert_handler_type);
+ *Description*
+Set the BFD assert handler function. Returns the previous function.
+
+2.2.3.2 `bfd_get_assert_handler'
+................................
+
+*Synopsis*
+ bfd_assert_handler_type bfd_get_assert_handler (void);
+ *Description*
+Return the BFD assert handler function.
+
+
+File: bfd.info, Node: Miscellaneous, Next: Memory Usage, Prev: Error reporting, Up: BFD front end
+
+2.3 Miscellaneous
+=================
+
+2.3.1 Miscellaneous functions
+-----------------------------
+
+2.3.1.1 `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 SECT attached to bfd ABFD. If an error occurs,
+return -1.
+
+2.3.1.2 `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 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.
+
+ The SYMS table is also needed for horrible internal magic reasons.
+
+2.3.1.3 `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 SEC to the values
+REL and COUNT. The argument ABFD is ignored.
+
+2.3.1.4 `bfd_set_file_flags'
+............................
+
+*Synopsis*
+ bfd_boolean bfd_set_file_flags (bfd *abfd, flagword flags);
+ *Description*
+Set the flag word in the BFD ABFD to the value FLAGS.
+
+ Possible errors are:
+ * `bfd_error_wrong_format' - The target bfd was not of object format.
+
+ * `bfd_error_invalid_operation' - The target bfd was open for
+ reading.
+
+ * `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.
+
+2.3.1.5 `bfd_get_arch_size'
+...........................
+
+*Synopsis*
+ int bfd_get_arch_size (bfd *abfd);
+ *Description*
+Returns the normalized architecture address size, in bits, as
+determined by the object file's format. By normalized, we mean either
+32 or 64. For ELF, this information is included in the header. Use
+bfd_arch_bits_per_address for number of bits in the architecture
+address.
+
+ *Returns*
+Returns the arch size in bits if known, `-1' otherwise.
+
+2.3.1.6 `bfd_get_sign_extend_vma'
+.................................
+
+*Synopsis*
+ int bfd_get_sign_extend_vma (bfd *abfd);
+ *Description*
+Indicates if the target architecture "naturally" sign extends an
+address. Some architectures implicitly sign extend address values when
+they are converted to types larger than the size of an address. For
+instance, bfd_get_start_address() will return an address sign extended
+to fill a bfd_vma when this is the case.
+
+ *Returns*
+Returns `1' if the target architecture is known to sign extend
+addresses, `0' if the target architecture is known to not sign extend
+addresses, and `-1' otherwise.
+
+2.3.1.7 `bfd_set_start_address'
+...............................
+
+*Synopsis*
+ bfd_boolean bfd_set_start_address (bfd *abfd, bfd_vma vma);
+ *Description*
+Make VMA the entry point of output BFD ABFD.
+
+ *Returns*
+Returns `TRUE' on success, `FALSE' otherwise.
+
+2.3.1.8 `bfd_get_gp_size'
+.........................
+
+*Synopsis*
+ unsigned 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.
+
+2.3.1.9 `bfd_set_gp_size'
+.........................
+
+*Synopsis*
+ void bfd_set_gp_size (bfd *abfd, unsigned 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.
+
+2.3.1.10 `bfd_scan_vma'
+.......................
+
+*Synopsis*
+ bfd_vma bfd_scan_vma (const char *string, const char **end, int base);
+ *Description*
+Convert, like `strtoul', a numerical expression 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 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.
+
+ If the value would overflow, the maximum `bfd_vma' value is returned.
+
+2.3.1.11 `bfd_copy_private_header_data'
+.......................................
+
+*Synopsis*
+ bfd_boolean bfd_copy_private_header_data (bfd *ibfd, bfd *obfd);
+ *Description*
+Copy private BFD header information from the BFD IBFD to the the BFD
+OBFD. This copies information that may require sections to exist, but
+does not require symbol tables. Return `true' on success, `false' on
+error. Possible error returns are:
+
+ * `bfd_error_no_memory' - Not enough memory exists to create private
+ data for OBFD.
+
+ #define bfd_copy_private_header_data(ibfd, obfd) \
+ BFD_SEND (obfd, _bfd_copy_private_header_data, \
+ (ibfd, obfd))
+
+2.3.1.12 `bfd_copy_private_bfd_data'
+....................................
+
+*Synopsis*
+ bfd_boolean bfd_copy_private_bfd_data (bfd *ibfd, bfd *obfd);
+ *Description*
+Copy private BFD information from the BFD IBFD to the the BFD OBFD.
+Return `TRUE' on success, `FALSE' on error. Possible error returns are:
+
+ * `bfd_error_no_memory' - Not enough memory exists to create private
+ data for OBFD.
+
+ #define bfd_copy_private_bfd_data(ibfd, obfd) \
+ BFD_SEND (obfd, _bfd_copy_private_bfd_data, \
+ (ibfd, obfd))
+
+2.3.1.13 `bfd_merge_private_bfd_data'
+.....................................
+
+*Synopsis*
+ bfd_boolean bfd_merge_private_bfd_data (bfd *ibfd, bfd *obfd);
+ *Description*
+Merge private BFD information from the BFD IBFD to the the output file
+BFD OBFD when linking. Return `TRUE' on success, `FALSE' on error.
+Possible error returns are:
+
+ * `bfd_error_no_memory' - Not enough memory exists to create private
+ data for OBFD.
+
+ #define bfd_merge_private_bfd_data(ibfd, obfd) \
+ BFD_SEND (obfd, _bfd_merge_private_bfd_data, \
+ (ibfd, obfd))
+
+2.3.1.14 `bfd_set_private_flags'
+................................
+
+*Synopsis*
+ bfd_boolean bfd_set_private_flags (bfd *abfd, flagword flags);
+ *Description*
+Set private BFD flag information in the BFD ABFD. Return `TRUE' on
+success, `FALSE' on error. Possible error returns are:
+
+ * `bfd_error_no_memory' - Not enough memory exists to create private
+ data for OBFD.
+
+ #define bfd_set_private_flags(abfd, flags) \
+ BFD_SEND (abfd, _bfd_set_private_flags, (abfd, flags))
+
+2.3.1.15 `Other functions'
+..........................
+
+*Description*
+The following functions exist but have not yet been documented.
+ #define bfd_sizeof_headers(abfd, info) \
+ BFD_SEND (abfd, _bfd_sizeof_headers, (abfd, info))
+
+ #define bfd_find_nearest_line(abfd, sec, syms, off, file, func, line) \
+ BFD_SEND (abfd, _bfd_find_nearest_line, \
+ (abfd, syms, sec, off, file, func, line, NULL))
+
+ #define bfd_find_nearest_line_discriminator(abfd, sec, syms, off, file, func, \
+ line, disc) \
+ BFD_SEND (abfd, _bfd_find_nearest_line, \
+ (abfd, syms, sec, off, file, func, line, disc))
+
+ #define bfd_find_line(abfd, syms, sym, file, line) \
+ BFD_SEND (abfd, _bfd_find_line, \
+ (abfd, syms, sym, file, line))
+
+ #define bfd_find_inliner_info(abfd, file, func, line) \
+ BFD_SEND (abfd, _bfd_find_inliner_info, \
+ (abfd, file, func, line))
+
+ #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_lookup_section_flags(link_info, flag_info, section) \
+ BFD_SEND (abfd, _bfd_lookup_section_flags, (link_info, flag_info, section))
+
+ #define bfd_merge_sections(abfd, link_info) \
+ BFD_SEND (abfd, _bfd_merge_sections, (abfd, link_info))
+
+ #define bfd_is_group_section(abfd, sec) \
+ BFD_SEND (abfd, _bfd_is_group_section, (abfd, sec))
+
+ #define bfd_discard_group(abfd, sec) \
+ BFD_SEND (abfd, _bfd_discard_group, (abfd, sec))
+
+ #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_link_just_syms(abfd, sec, info) \
+ BFD_SEND (abfd, _bfd_link_just_syms, (sec, 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_synthetic_symtab(abfd, count, syms, dyncount, dynsyms, ret) \
+ BFD_SEND (abfd, _bfd_get_synthetic_symtab, (abfd, count, syms, \
+ dyncount, dynsyms, ret))
+
+ #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
+ (bfd *, struct bfd_link_info *, struct bfd_link_order *, bfd_byte *,
+ bfd_boolean, asymbol **);
+
+2.3.1.16 `bfd_alt_mach_code'
+............................
+
+*Synopsis*
+ bfd_boolean bfd_alt_mach_code (bfd *abfd, int alternative);
+ *Description*
+When more than one machine code number is available for the same
+machine type, this function can be used to switch between the preferred
+one (alternative == 0) and any others. Currently, only ELF supports
+this feature, with up to two alternate machine codes.
+
+2.3.1.17 `bfd_emul_get_maxpagesize'
+...................................
+
+*Synopsis*
+ bfd_vma bfd_emul_get_maxpagesize (const char *);
+ *Description*
+Returns the maximum page size, in bytes, as determined by emulation.
+
+ *Returns*
+Returns the maximum page size in bytes for ELF, 0 otherwise.
+
+2.3.1.18 `bfd_emul_set_maxpagesize'
+...................................
+
+*Synopsis*
+ void bfd_emul_set_maxpagesize (const char *, bfd_vma);
+ *Description*
+For ELF, set the maximum page size for the emulation. It is a no-op
+for other formats.
+
+2.3.1.19 `bfd_emul_get_commonpagesize'
+......................................
+
+*Synopsis*
+ bfd_vma bfd_emul_get_commonpagesize (const char *);
+ *Description*
+Returns the common page size, in bytes, as determined by emulation.
+
+ *Returns*
+Returns the common page size in bytes for ELF, 0 otherwise.
+
+2.3.1.20 `bfd_emul_set_commonpagesize'
+......................................
+
+*Synopsis*
+ void bfd_emul_set_commonpagesize (const char *, bfd_vma);
+ *Description*
+For ELF, set the common page size for the emulation. It is a no-op for
+other formats.
+
+2.3.1.21 `bfd_demangle'
+.......................
+
+*Synopsis*
+ char *bfd_demangle (bfd *, const char *, int);
+ *Description*
+Wrapper around cplus_demangle. Strips leading underscores and other
+such chars that would otherwise confuse the demangler. If passed a g++
+v3 ABI mangled name, returns a buffer allocated with malloc holding the
+demangled name. Returns NULL otherwise and on memory alloc failure.
+
+2.3.1.22 `struct bfd_iovec'
+...........................
+
+*Description*
+The `struct bfd_iovec' contains the internal file I/O class. Each
+`BFD' has an instance of this class and all file I/O is routed through
+it (it is assumed that the instance implements all methods listed
+below).
+ struct bfd_iovec
+ {
+ /* To avoid problems with macros, a "b" rather than "f"
+ prefix is prepended to each method name. */
+ /* Attempt to read/write NBYTES on ABFD's IOSTREAM storing/fetching
+ bytes starting at PTR. Return the number of bytes actually
+ transfered (a read past end-of-file returns less than NBYTES),
+ or -1 (setting `bfd_error') if an error occurs. */
+ file_ptr (*bread) (struct bfd *abfd, void *ptr, file_ptr nbytes);
+ file_ptr (*bwrite) (struct bfd *abfd, const void *ptr,
+ file_ptr nbytes);
+ /* Return the current IOSTREAM file offset, or -1 (setting `bfd_error'
+ if an error occurs. */
+ file_ptr (*btell) (struct bfd *abfd);
+ /* For the following, on successful completion a value of 0 is returned.
+ Otherwise, a value of -1 is returned (and `bfd_error' is set). */
+ int (*bseek) (struct bfd *abfd, file_ptr offset, int whence);
+ int (*bclose) (struct bfd *abfd);
+ int (*bflush) (struct bfd *abfd);
+ int (*bstat) (struct bfd *abfd, struct stat *sb);
+ /* Mmap a part of the files. ADDR, LEN, PROT, FLAGS and OFFSET are the usual
+ mmap parameter, except that LEN and OFFSET do not need to be page
+ aligned. Returns (void *)-1 on failure, mmapped address on success.
+ Also write in MAP_ADDR the address of the page aligned buffer and in
+ MAP_LEN the size mapped (a page multiple). Use unmap with MAP_ADDR and
+ MAP_LEN to unmap. */
+ void *(*bmmap) (struct bfd *abfd, void *addr, bfd_size_type len,
+ int prot, int flags, file_ptr offset,
+ void **map_addr, bfd_size_type *map_len);
+ };
+ extern const struct bfd_iovec _bfd_memory_iovec;
+
+2.3.1.23 `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).
+
+2.3.1.24 `bfd_get_size'
+.......................
+
+*Synopsis*
+ file_ptr bfd_get_size (bfd *abfd);
+ *Description*
+Return the file size (as read from file system) for the file associated
+with BFD 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 question, "is
+the size reasonable?".
+
+2.3.1.25 `bfd_mmap'
+...................
+
+*Synopsis*
+ void *bfd_mmap (bfd *abfd, void *addr, bfd_size_type len,
+ int prot, int flags, file_ptr offset,
+ void **map_addr, bfd_size_type *map_len);
+ *Description*
+Return mmap()ed region of the file, if possible and implemented. LEN
+and OFFSET do not need to be page aligned. The page aligned address
+and length are written to MAP_ADDR and MAP_LEN.
+
+
+File: bfd.info, Node: Memory Usage, Next: Initialization, Prev: Miscellaneous, Up: BFD front end
+
+2.4 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 `bfd' structures become invalid on a `bfd_close'; for example,
+after a `bfd_close' the vector passed to `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 (`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.
+
+
+File: bfd.info, Node: Initialization, Next: Sections, Prev: Memory Usage, Up: BFD front end
+
+2.5 Initialization
+==================
+
+2.5.1 Initialization functions
+------------------------------
+
+These are the functions that handle initializing a BFD.
+
+2.5.1.1 `bfd_init'
+..................
+
+*Synopsis*
+ void bfd_init (void);
+ *Description*
+This routine must be called before any other BFD function to initialize
+magical internal data structures.
+
+
+File: bfd.info, Node: Sections, Next: Symbols, Prev: Initialization, Up: BFD front end
+
+2.6 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::
+
+
+File: bfd.info, Node: Section Input, Next: Section Output, Prev: Sections, Up: Sections
+
+2.6.1 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.
+
+
+File: bfd.info, Node: Section Output, Next: typedef asection, Prev: Section Input, Up: Sections
+
+2.6.2 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 --------|
+
+2.6.3 Link orders
+-----------------
+
+The data within a section is stored in a "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.
+
+
+File: bfd.info, Node: typedef asection, Next: section prototypes, Prev: Section Output, Up: Sections
+
+2.6.4 typedef asection
+----------------------
+
+Here is the section structure:
+
+
+ typedef struct bfd_section
+ {
+ /* 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;
+
+ /* A unique sequence number. */
+ int id;
+
+ /* Which section in the bfd; 0..n-1 as sections are created in a bfd. */
+ int index;
+
+ /* The next section in the list belonging to the BFD, or NULL. */
+ struct bfd_section *next;
+
+ /* The previous section in the list belonging to the BFD, or NULL. */
+ struct bfd_section *prev;
+
+ /* 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
+
+ /* A signal to the OS that the section contains read only data. */
+ #define SEC_READONLY 0x008
+
+ /* The section contains code only. */
+ #define SEC_CODE 0x010
+
+ /* The section contains data only. */
+ #define SEC_DATA 0x020
+
+ /* The section will reside in ROM. */
+ #define SEC_ROM 0x040
+
+ /* 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 0x080
+
+ /* 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 0x100
+
+ /* An instruction to the linker to not output the section
+ even if it has information which would normally be written. */
+ #define SEC_NEVER_LOAD 0x200
+
+ /* The section contains thread local data. */
+ #define SEC_THREAD_LOCAL 0x400
+
+ /* The section has GOT references. This flag is only for the
+ linker, and is currently only used by the elf32-hppa back end.
+ It will be set if global offset table references were detected
+ in this section, which indicate to the linker that the section
+ contains PIC code, and must be handled specially when doing a
+ static link. */
+ #define SEC_HAS_GOT_REF 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 0x1000
+
+ /* 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 0x2000
+
+ /* 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 0x4000
+
+ /* 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 0x8000
+
+ /* The contents of this section are to be sorted based on the sum of
+ the symbol and addend values specified by the associated relocation
+ entries. Entries without associated relocation entries will be
+ appended to the end of the section in an unspecified order. */
+ #define SEC_SORT_ENTRIES 0x10000
+
+ /* 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 0x20000
+
+ /* If SEC_LINK_ONCE is set, this bitfield describes how the linker
+ should handle duplicate sections. */
+ #define SEC_LINK_DUPLICATES 0xc0000
+
+ /* 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 0x40000
+
+ /* 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 0x80000
+
+ /* 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 \
+ (SEC_LINK_DUPLICATES_ONE_ONLY | SEC_LINK_DUPLICATES_SAME_SIZE)
+
+ /* 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 0x100000
+
+ /* This section should not be subject to garbage collection.
+ Also set to inform the linker that this section should not be
+ listed in the link map as discarded. */
+ #define SEC_KEEP 0x200000
+
+ /* This section contains "short" data, and should be placed
+ "near" the GP. */
+ #define SEC_SMALL_DATA 0x400000
+
+ /* Attempt to merge identical entities in the section.
+ Entity size is given in the entsize field. */
+ #define SEC_MERGE 0x800000
+
+ /* If given with SEC_MERGE, entities to merge are zero terminated
+ strings where entsize specifies character size instead of fixed
+ size entries. */
+ #define SEC_STRINGS 0x1000000
+
+ /* This section contains data about section groups. */
+ #define SEC_GROUP 0x2000000
+
+ /* 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 0x4000000
+
+ /* This input section should be copied to output in reverse order
+ as an array of pointers. This is for ELF linker internal use
+ only. */
+ #define SEC_ELF_REVERSE_COPY 0x4000000
+
+ /* This section contains data which may be shared with other
+ executables or shared objects. This is for COFF only. */
+ #define SEC_COFF_SHARED 0x8000000
+
+ /* When a section with this flag is being linked, then if the size of
+ the input section is less than a page, it should not cross a page
+ boundary. If the size of the input section is one page or more,
+ it should be aligned on a page boundary. This is for TI
+ TMS320C54X only. */
+ #define SEC_TIC54X_BLOCK 0x10000000
+
+ /* Conditionally link this section; do not link if there are no
+ references found to any symbol in the section. This is for TI
+ TMS320C54X only. */
+ #define SEC_TIC54X_CLINK 0x20000000
+
+ /* Indicate that section has the no read flag set. This happens
+ when memory read flag isn't set. */
+ #define SEC_COFF_NOREAD 0x40000000
+
+ /* End of section flags. */
+
+ /* Some internal packed boolean fields. */
+
+ /* See the vma field. */
+ unsigned int user_set_vma : 1;
+
+ /* A mark flag used by some of the linker backends. */
+ unsigned int linker_mark : 1;
+
+ /* Another mark flag used by some of the linker backends. Set for
+ output sections that have an input section. */
+ unsigned int linker_has_input : 1;
+
+ /* Mark flag used by some linker backends for garbage collection. */
+ unsigned int gc_mark : 1;
+
+ /* Section compression status. */
+ unsigned int compress_status : 2;
+ #define COMPRESS_SECTION_NONE 0
+ #define COMPRESS_SECTION_DONE 1
+ #define DECOMPRESS_SECTION_SIZED 2
+
+ /* The following flags are used by the ELF linker. */
+
+ /* Mark sections which have been allocated to segments. */
+ unsigned int segment_mark : 1;
+
+ /* Type of sec_info information. */
+ unsigned int sec_info_type:3;
+ #define SEC_INFO_TYPE_NONE 0
+ #define SEC_INFO_TYPE_STABS 1
+ #define SEC_INFO_TYPE_MERGE 2
+ #define SEC_INFO_TYPE_EH_FRAME 3
+ #define SEC_INFO_TYPE_JUST_SYMS 4
+ #define SEC_INFO_TYPE_TARGET 5
+
+ /* Nonzero if this section uses RELA relocations, rather than REL. */
+ unsigned int use_rela_p:1;
+
+ /* Bits used by various backends. The generic code doesn't touch
+ these fields. */
+
+ unsigned int sec_flg0:1;
+ unsigned int sec_flg1:1;
+ unsigned int sec_flg2:1;
+ unsigned int sec_flg3:1;
+ unsigned int sec_flg4:1;
+ unsigned int sec_flg5: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 octets, as it will be output.
+ Contains a value even if the section has no contents (e.g., the
+ size of `.bss'). */
+ bfd_size_type size;
+
+ /* For input sections, the original size on disk of the section, in
+ octets. This field should be set for any section whose size is
+ changed by linker relaxation. It is required for sections where
+ the linker relaxation scheme doesn't cache altered section and
+ reloc contents (stabs, eh_frame, SEC_MERGE, some coff relaxing
+ targets), and thus the original size needs to be kept to read the
+ section multiple times. For output sections, rawsize holds the
+ section size calculated on a previous linker relaxation pass. */
+ bfd_size_type rawsize;
+
+ /* The compressed size of the section in octets. */
+ bfd_size_type compressed_size;
+
+ /* Relaxation table. */
+ struct relax_table *relax;
+
+ /* Count of used relaxation table entries. */
+ int relax_count;
+
+
+ /* If this section is going to be output, then this value is the
+ offset in *bytes* into the output section of the first byte in the
+ input section (byte ==> smallest addressable unit on the
+ target). In most cases, if this was going to start at the
+ 100th octet (8-bit quantity) in the output section, this value
+ would be 100. However, if the target byte size is 16 bits
+ (bfd_octets_per_byte is "2"), this value would be 50. */
+ bfd_vma output_offset;
+
+ /* The output section through which to map on output. */
+ struct bfd_section *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. */
+ void *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;
+
+ /* Entity size for merging purposes. */
+ unsigned int entsize;
+
+ /* Points to the kept section if this section is a link-once section,
+ and is discarded. */
+ struct bfd_section *kept_section;
+
+ /* 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;
+
+ void *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 bfd_symbol *symbol;
+ struct bfd_symbol **symbol_ptr_ptr;
+
+ /* Early in the link process, map_head and map_tail are used to build
+ a list of input sections attached to an output section. Later,
+ output sections use these fields for a list of bfd_link_order
+ structs. */
+ union {
+ struct bfd_link_order *link_order;
+ struct bfd_section *s;
+ } map_head, map_tail;
+ } asection;
+
+ /* Relax table contains information about instructions which can
+ be removed by relaxation -- replacing a long address with a
+ short address. */
+ struct relax_table {
+ /* Address where bytes may be deleted. */
+ bfd_vma addr;
+
+ /* Number of bytes to be deleted. */
+ int size;
+ };
+
+ /* Note: the following are provided as inline functions rather than macros
+ because not all callers use the return value. A macro implementation
+ would use a comma expression, eg: "((ptr)->foo = val, TRUE)" and some
+ compilers will complain about comma expressions that have no effect. */
+ static inline bfd_boolean
+ bfd_set_section_userdata (bfd * abfd ATTRIBUTE_UNUSED, asection * ptr, void * val)
+ {
+ ptr->userdata = val;
+ return TRUE;
+ }
+
+ static inline bfd_boolean
+ bfd_set_section_vma (bfd * abfd ATTRIBUTE_UNUSED, asection * ptr, bfd_vma val)
+ {
+ ptr->vma = ptr->lma = val;
+ ptr->user_set_vma = TRUE;
+ return TRUE;
+ }
+
+ static inline bfd_boolean
+ bfd_set_section_alignment (bfd * abfd ATTRIBUTE_UNUSED, asection * ptr, unsigned int val)
+ {
+ ptr->alignment_power = val;
+ return TRUE;
+ }
+
+ /* 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. */
+ extern asection _bfd_std_section[4];
+
+ #define BFD_ABS_SECTION_NAME "*ABS*"
+ #define BFD_UND_SECTION_NAME "*UND*"
+ #define BFD_COM_SECTION_NAME "*COM*"
+ #define BFD_IND_SECTION_NAME "*IND*"
+
+ /* Pointer to the common section. */
+ #define bfd_com_section_ptr (&_bfd_std_section[0])
+ /* Pointer to the undefined section. */
+ #define bfd_und_section_ptr (&_bfd_std_section[1])
+ /* Pointer to the absolute section. */
+ #define bfd_abs_section_ptr (&_bfd_std_section[2])
+ /* Pointer to the indirect section. */
+ #define bfd_ind_section_ptr (&_bfd_std_section[3])
+
+ #define bfd_is_und_section(sec) ((sec) == bfd_und_section_ptr)
+ #define bfd_is_abs_section(sec) ((sec) == bfd_abs_section_ptr)
+ #define bfd_is_ind_section(sec) ((sec) == bfd_ind_section_ptr)
+
+ #define bfd_is_const_section(SEC) \
+ ( ((SEC) == bfd_abs_section_ptr) \
+ || ((SEC) == bfd_und_section_ptr) \
+ || ((SEC) == bfd_com_section_ptr) \
+ || ((SEC) == bfd_ind_section_ptr))
+
+ /* Macros to handle insertion and deletion of a bfd's sections. These
+ only handle the list pointers, ie. do not adjust section_count,
+ target_index etc. */
+ #define bfd_section_list_remove(ABFD, S) \
+ do \
+ { \
+ asection *_s = S; \
+ asection *_next = _s->next; \
+ asection *_prev = _s->prev; \
+ if (_prev) \
+ _prev->next = _next; \
+ else \
+ (ABFD)->sections = _next; \
+ if (_next) \
+ _next->prev = _prev; \
+ else \
+ (ABFD)->section_last = _prev; \
+ } \
+ while (0)
+ #define bfd_section_list_append(ABFD, S) \
+ do \
+ { \
+ asection *_s = S; \
+ bfd *_abfd = ABFD; \
+ _s->next = NULL; \
+ if (_abfd->section_last) \
+ { \
+ _s->prev = _abfd->section_last; \
+ _abfd->section_last->next = _s; \
+ } \
+ else \
+ { \
+ _s->prev = NULL; \
+ _abfd->sections = _s; \
+ } \
+ _abfd->section_last = _s; \
+ } \
+ while (0)
+ #define bfd_section_list_prepend(ABFD, S) \
+ do \
+ { \
+ asection *_s = S; \
+ bfd *_abfd = ABFD; \
+ _s->prev = NULL; \
+ if (_abfd->sections) \
+ { \
+ _s->next = _abfd->sections; \
+ _abfd->sections->prev = _s; \
+ } \
+ else \
+ { \
+ _s->next = NULL; \
+ _abfd->section_last = _s; \
+ } \
+ _abfd->sections = _s; \
+ } \
+ while (0)
+ #define bfd_section_list_insert_after(ABFD, A, S) \
+ do \
+ { \
+ asection *_a = A; \
+ asection *_s = S; \
+ asection *_next = _a->next; \
+ _s->next = _next; \
+ _s->prev = _a; \
+ _a->next = _s; \
+ if (_next) \
+ _next->prev = _s; \
+ else \
+ (ABFD)->section_last = _s; \
+ } \
+ while (0)
+ #define bfd_section_list_insert_before(ABFD, B, S) \
+ do \
+ { \
+ asection *_b = B; \
+ asection *_s = S; \
+ asection *_prev = _b->prev; \
+ _s->prev = _prev; \
+ _s->next = _b; \
+ _b->prev = _s; \
+ if (_prev) \
+ _prev->next = _s; \
+ else \
+ (ABFD)->sections = _s; \
+ } \
+ while (0)
+ #define bfd_section_removed_from_list(ABFD, S) \
+ ((S)->next == NULL ? (ABFD)->section_last != (S) : (S)->next->prev != (S))
+
+ #define BFD_FAKE_SECTION(SEC, FLAGS, SYM, NAME, IDX) \
+ /* name, id, index, next, prev, flags, user_set_vma, */ \
+ { NAME, IDX, 0, NULL, NULL, FLAGS, 0, \
+ \
+ /* linker_mark, linker_has_input, gc_mark, decompress_status, */ \
+ 0, 0, 1, 0, \
+ \
+ /* segment_mark, sec_info_type, use_rela_p, */ \
+ 0, 0, 0, \
+ \
+ /* sec_flg0, sec_flg1, sec_flg2, sec_flg3, sec_flg4, sec_flg5, */ \
+ 0, 0, 0, 0, 0, 0, \
+ \
+ /* vma, lma, size, rawsize, compressed_size, relax, relax_count, */ \
+ 0, 0, 0, 0, 0, 0, 0, \
+ \
+ /* output_offset, output_section, alignment_power, */ \
+ 0, &SEC, 0, \
+ \
+ /* relocation, orelocation, reloc_count, filepos, rel_filepos, */ \
+ NULL, NULL, 0, 0, 0, \
+ \
+ /* line_filepos, userdata, contents, lineno, lineno_count, */ \
+ 0, NULL, NULL, NULL, 0, \
+ \
+ /* entsize, kept_section, moving_line_filepos, */ \
+ 0, NULL, 0, \
+ \
+ /* target_index, used_by_bfd, constructor_chain, owner, */ \
+ 0, NULL, NULL, NULL, \
+ \
+ /* symbol, symbol_ptr_ptr, */ \
+ (struct bfd_symbol *) SYM, &SEC.symbol, \
+ \
+ /* map_head, map_tail */ \
+ { NULL }, { NULL } \
+ }
+
+
+File: bfd.info, Node: section prototypes, Prev: typedef asection, Up: Sections
+
+2.6.5 Section prototypes
+------------------------
+
+These are the functions exported by the section handling part of BFD.
+
+2.6.5.1 `bfd_section_list_clear'
+................................
+
+*Synopsis*
+ void bfd_section_list_clear (bfd *);
+ *Description*
+Clears the section list, and also resets the section count and hash
+table entries.
+
+2.6.5.2 `bfd_get_section_by_name'
+.................................
+
+*Synopsis*
+ asection *bfd_get_section_by_name (bfd *abfd, const char *name);
+ *Description*
+Return the most recently created section attached to ABFD named NAME.
+Return NULL if no such section exists.
+
+2.6.5.3 `bfd_get_next_section_by_name'
+......................................
+
+*Synopsis*
+ asection *bfd_get_next_section_by_name (asection *sec);
+ *Description*
+Given SEC is a section returned by `bfd_get_section_by_name', return
+the next most recently created section attached to the same BFD with
+the same name. Return NULL if no such section exists.
+
+2.6.5.4 `bfd_get_linker_section'
+................................
+
+*Synopsis*
+ asection *bfd_get_linker_section (bfd *abfd, const char *name);
+ *Description*
+Return the linker created section attached to ABFD named NAME. Return
+NULL if no such section exists.
+
+2.6.5.5 `bfd_get_section_by_name_if'
+....................................
+
+*Synopsis*
+ asection *bfd_get_section_by_name_if
+ (bfd *abfd,
+ const char *name,
+ bfd_boolean (*func) (bfd *abfd, asection *sect, void *obj),
+ void *obj);
+ *Description*
+Call the provided function FUNC for each section attached to the BFD
+ABFD whose name matches NAME, passing OBJ as an argument. The function
+will be called as if by
+
+ func (abfd, the_section, obj);
+
+ It returns the first section for which FUNC returns true, otherwise
+`NULL'.
+
+2.6.5.6 `bfd_get_unique_section_name'
+.....................................
+
+*Synopsis*
+ char *bfd_get_unique_section_name
+ (bfd *abfd, const char *templat, int *count);
+ *Description*
+Invent a section name that is unique in ABFD by tacking a dot and a
+digit suffix onto the original TEMPLAT. If COUNT is non-NULL, then it
+specifies the first number tried as a suffix to generate a unique name.
+The value pointed to by COUNT will be incremented in this case.
+
+2.6.5.7 `bfd_make_section_old_way'
+..................................
+
+*Synopsis*
+ asection *bfd_make_section_old_way (bfd *abfd, const char *name);
+ *Description*
+Create a new empty section called NAME and attach it to the end of the
+chain of sections for the BFD 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:
+ * `bfd_error_invalid_operation' - If output has already started for
+ this BFD.
+
+ * `bfd_error_no_memory' - If memory allocation fails.
+
+2.6.5.8 `bfd_make_section_anyway_with_flags'
+............................................
+
+*Synopsis*
+ asection *bfd_make_section_anyway_with_flags
+ (bfd *abfd, const char *name, flagword flags);
+ *Description*
+Create a new empty section called NAME and attach it to the end of the
+chain of sections for ABFD. Create a new section even if there is
+already a section with that name. Also set the attributes of the new
+section to the value FLAGS.
+
+ Return `NULL' and set `bfd_error' on error; possible errors are:
+ * `bfd_error_invalid_operation' - If output has already started for
+ ABFD.
+
+ * `bfd_error_no_memory' - If memory allocation fails.
+
+2.6.5.9 `bfd_make_section_anyway'
+.................................
+
+*Synopsis*
+ asection *bfd_make_section_anyway (bfd *abfd, const char *name);
+ *Description*
+Create a new empty section called NAME and attach it to the end of the
+chain of sections for 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:
+ * `bfd_error_invalid_operation' - If output has already started for
+ ABFD.
+
+ * `bfd_error_no_memory' - If memory allocation fails.
+
+2.6.5.10 `bfd_make_section_with_flags'
+......................................
+
+*Synopsis*
+ asection *bfd_make_section_with_flags
+ (bfd *, const char *name, flagword flags);
+ *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 NAME. Also set the attributes of the new
+section to the value FLAGS. If there is an error, return `NULL' and set
+`bfd_error'.
+
+2.6.5.11 `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 NAME. If there is an error, return `NULL' and
+set `bfd_error'.
+
+2.6.5.12 `bfd_set_section_flags'
+................................
+
+*Synopsis*
+ bfd_boolean bfd_set_section_flags
+ (bfd *abfd, asection *sec, flagword flags);
+ *Description*
+Set the attributes of the section SEC in the BFD ABFD to the value
+FLAGS. Return `TRUE' on success, `FALSE' on error. Possible error
+returns are:
+
+ * `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.
+
+2.6.5.13 `bfd_rename_section'
+.............................
+
+*Synopsis*
+ void bfd_rename_section
+ (bfd *abfd, asection *sec, const char *newname);
+ *Description*
+Rename section SEC in ABFD to NEWNAME.
+
+2.6.5.14 `bfd_map_over_sections'
+................................
+
+*Synopsis*
+ void bfd_map_over_sections
+ (bfd *abfd,
+ void (*func) (bfd *abfd, asection *sect, void *obj),
+ void *obj);
+ *Description*
+Call the provided function FUNC for each section attached to the BFD
+ABFD, passing OBJ as an argument. The function will be called as if by
+
+ func (abfd, the_section, obj);
+
+ This is the preferred method for iterating over sections; an
+alternative would be to use a loop:
+
+ asection *p;
+ for (p = abfd->sections; p != NULL; p = p->next)
+ func (abfd, p, ...)
+
+2.6.5.15 `bfd_sections_find_if'
+...............................
+
+*Synopsis*
+ asection *bfd_sections_find_if
+ (bfd *abfd,
+ bfd_boolean (*operation) (bfd *abfd, asection *sect, void *obj),
+ void *obj);
+ *Description*
+Call the provided function OPERATION for each section attached to the
+BFD ABFD, passing OBJ as an argument. The function will be called as if
+by
+
+ operation (abfd, the_section, obj);
+
+ It returns the first section for which OPERATION returns true.
+
+2.6.5.16 `bfd_set_section_size'
+...............................
+
+*Synopsis*
+ bfd_boolean bfd_set_section_size
+ (bfd *abfd, asection *sec, bfd_size_type val);
+ *Description*
+Set SEC to the size VAL. If the operation is ok, then `TRUE' is
+returned, else `FALSE'.
+
+ Possible error returns:
+ * `bfd_error_invalid_operation' - Writing has started to the BFD, so
+ setting the size is invalid.
+
+2.6.5.17 `bfd_set_section_contents'
+...................................
+
+*Synopsis*
+ bfd_boolean bfd_set_section_contents
+ (bfd *abfd, asection *section, const void *data,
+ file_ptr offset, bfd_size_type count);
+ *Description*
+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 octets.
+
+ Normally `TRUE' is returned, else `FALSE'. Possible error returns
+are:
+ * `bfd_error_no_contents' - The output section does not have the
+ `SEC_HAS_CONTENTS' attribute, so nothing can be written to it.
+
+ * and some more too
+ This routine is front end to the back end function
+`_bfd_set_section_contents'.
+
+2.6.5.18 `bfd_get_section_contents'
+...................................
+
+*Synopsis*
+ bfd_boolean bfd_get_section_contents
+ (bfd *abfd, asection *section, void *location, file_ptr offset,
+ bfd_size_type count);
+ *Description*
+Read data from SECTION in BFD ABFD into memory starting at LOCATION.
+The data is read at an offset of OFFSET from the start of the input
+section, and is read for 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 LOCATION is filled with zeroes. If no errors occur,
+`TRUE' is returned, else `FALSE'.
+
+2.6.5.19 `bfd_malloc_and_get_section'
+.....................................
+
+*Synopsis*
+ bfd_boolean bfd_malloc_and_get_section
+ (bfd *abfd, asection *section, bfd_byte **buf);
+ *Description*
+Read all data from SECTION in BFD ABFD into a buffer, *BUF, malloc'd by
+this function.
+
+2.6.5.20 `bfd_copy_private_section_data'
+........................................
+
+*Synopsis*
+ bfd_boolean bfd_copy_private_section_data
+ (bfd *ibfd, asection *isec, bfd *obfd, asection *osec);
+ *Description*
+Copy private section information from ISEC in the BFD IBFD to the
+section OSEC in the BFD OBFD. Return `TRUE' on success, `FALSE' on
+error. Possible error returns are:
+
+ * `bfd_error_no_memory' - Not enough memory exists to create private
+ data for OSEC.
+
+ #define bfd_copy_private_section_data(ibfd, isection, obfd, osection) \
+ BFD_SEND (obfd, _bfd_copy_private_section_data, \
+ (ibfd, isection, obfd, osection))
+
+2.6.5.21 `bfd_generic_is_group_section'
+.......................................
+
+*Synopsis*
+ bfd_boolean bfd_generic_is_group_section (bfd *, const asection *sec);
+ *Description*
+Returns TRUE if SEC is a member of a group.
+
+2.6.5.22 `bfd_generic_discard_group'
+....................................
+
+*Synopsis*
+ bfd_boolean bfd_generic_discard_group (bfd *abfd, asection *group);
+ *Description*
+Remove all members of GROUP from the output.
+
+
+File: bfd.info, Node: Symbols, Next: Archives, Prev: Sections, Up: BFD front end
+
+2.7 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::
+
+
+File: bfd.info, Node: Reading Symbols, Next: Writing Symbols, Prev: Symbols, Up: Symbols
+
+2.7.1 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 = 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.
+
+
+File: bfd.info, Node: Writing Symbols, Next: Mini Symbols, Prev: Reading Symbols, Up: Symbols
+
+2.7.2 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 "sysdep.h"
+ #include "bfd.h"
+ int main (void)
+ {
+ 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] = 0;
+
+ bfd_set_symtab (abfd, ptrs, 1);
+ bfd_close (abfd);
+ return 0;
+ }
+
+ ./makesym
+ nm foo
+ 00012345 A dummy_symbol
+
+ Many formats cannot represent arbitrary symbol information; for
+instance, the `a.out' object format does not allow an arbitrary number
+of sections. A symbol pointing to a section which is not one of
+`.text', `.data' or `.bss' cannot be described.
+
+
+File: bfd.info, Node: Mini Symbols, Next: typedef asymbol, Prev: Writing Symbols, Up: Symbols
+
+2.7.3 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.
+
+
+File: bfd.info, Node: typedef asymbol, Next: symbol handling functions, Prev: Mini Symbols, Up: Symbols
+
+2.7.4 typedef asymbol
+---------------------
+
+An `asymbol' has the form:
+
+
+ typedef struct bfd_symbol
+ {
+ /* 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 (1 << 0)
+
+ /* The symbol has global scope; initialized data in `C'. The
+ value is the offset into the section of the data. */
+ #define BSF_GLOBAL (1 << 1)
+
+ /* 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_COMMON', `BSF_UNDEFINED' or
+ `BSF_GLOBAL'. */
+
+ /* The symbol is a debugging record. The value has an arbitrary
+ meaning, unless BSF_DEBUGGING_RELOC is also set. */
+ #define BSF_DEBUGGING (1 << 2)
+
+ /* The symbol denotes a function entry point. Used in ELF,
+ perhaps others someday. */
+ #define BSF_FUNCTION (1 << 3)
+
+ /* Used by the linker. */
+ #define BSF_KEEP (1 << 5)
+ #define BSF_KEEP_G (1 << 6)
+
+ /* A weak global symbol, overridable without warnings by
+ a regular global symbol of the same name. */
+ #define BSF_WEAK (1 << 7)
+
+ /* This symbol was created to point to a section, e.g. ELF's
+ STT_SECTION symbols. */
+ #define BSF_SECTION_SYM (1 << 8)
+
+ /* The symbol used to be a common symbol, but now it is
+ allocated. */
+ #define BSF_OLD_COMMON (1 << 9)
+
+ /* 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 (1 << 10)
+
+ /* Signal that the symbol is the label of constructor section. */
+ #define BSF_CONSTRUCTOR (1 << 11)
+
+ /* 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 (1 << 12)
+
+ /* 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 (1 << 13)
+
+ /* BSF_FILE marks symbols that contain a file name. This is used
+ for ELF STT_FILE symbols. */
+ #define BSF_FILE (1 << 14)
+
+ /* Symbol is from dynamic linking information. */
+ #define BSF_DYNAMIC (1 << 15)
+
+ /* The symbol denotes a data object. Used in ELF, and perhaps
+ others someday. */
+ #define BSF_OBJECT (1 << 16)
+
+ /* This symbol is a debugging symbol. The value is the offset
+ into the section of the data. BSF_DEBUGGING should be set
+ as well. */
+ #define BSF_DEBUGGING_RELOC (1 << 17)
+
+ /* This symbol is thread local. Used in ELF. */
+ #define BSF_THREAD_LOCAL (1 << 18)
+
+ /* This symbol represents a complex relocation expression,
+ with the expression tree serialized in the symbol name. */
+ #define BSF_RELC (1 << 19)
+
+ /* This symbol represents a signed complex relocation expression,
+ with the expression tree serialized in the symbol name. */
+ #define BSF_SRELC (1 << 20)
+
+ /* This symbol was created by bfd_get_synthetic_symtab. */
+ #define BSF_SYNTHETIC (1 << 21)
+
+ /* This symbol is an indirect code object. Unrelated to BSF_INDIRECT.
+ The dynamic linker will compute the value of this symbol by
+ calling the function that it points to. BSF_FUNCTION must
+ also be also set. */
+ #define BSF_GNU_INDIRECT_FUNCTION (1 << 22)
+ /* This symbol is a globally unique data object. The dynamic linker
+ will make sure that in the entire process there is just one symbol
+ with this name and type in use. BSF_OBJECT must also be set. */
+ #define BSF_GNU_UNIQUE (1 << 23)
+
+ 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 bfd_section *section;
+
+ /* Back end special data. */
+ union
+ {
+ void *p;
+ bfd_vma i;
+ }
+ udata;
+ }
+ asymbol;
+
+
+File: bfd.info, Node: symbol handling functions, Prev: typedef asymbol, Up: Symbols
+
+2.7.5 Symbol handling functions
+-------------------------------
+
+2.7.5.1 `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 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))
+
+2.7.5.2 `bfd_is_local_label'
+............................
+
+*Synopsis*
+ bfd_boolean bfd_is_local_label (bfd *abfd, asymbol *sym);
+ *Description*
+Return TRUE if the given symbol SYM in the BFD ABFD is a compiler
+generated local label, else return FALSE.
+
+2.7.5.3 `bfd_is_local_label_name'
+.................................
+
+*Synopsis*
+ bfd_boolean bfd_is_local_label_name (bfd *abfd, const char *name);
+ *Description*
+Return TRUE if a symbol with the name NAME in the BFD 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))
+
+2.7.5.4 `bfd_is_target_special_symbol'
+......................................
+
+*Synopsis*
+ bfd_boolean bfd_is_target_special_symbol (bfd *abfd, asymbol *sym);
+ *Description*
+Return TRUE iff a symbol SYM in the BFD ABFD is something special to
+the particular target represented by the BFD. Such symbols should
+normally not be mentioned to the user.
+ #define bfd_is_target_special_symbol(abfd, sym) \
+ BFD_SEND (abfd, _bfd_is_target_special_symbol, (abfd, sym))
+
+2.7.5.5 `bfd_canonicalize_symtab'
+.................................
+
+*Description*
+Read the symbols from the BFD ABFD, and fills in the vector 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))
+
+2.7.5.6 `bfd_set_symtab'
+........................
+
+*Synopsis*
+ bfd_boolean bfd_set_symtab
+ (bfd *abfd, asymbol **location, unsigned int count);
+ *Description*
+Arrange that when the output BFD ABFD is closed, the table LOCATION of
+COUNT pointers to symbols will be written.
+
+2.7.5.7 `bfd_print_symbol_vandf'
+................................
+
+*Synopsis*
+ void bfd_print_symbol_vandf (bfd *abfd, void *file, asymbol *symbol);
+ *Description*
+Print the value and flags of the SYMBOL supplied to the stream FILE.
+
+2.7.5.8 `bfd_make_empty_symbol'
+...............................
+
+*Description*
+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.
+ #define bfd_make_empty_symbol(abfd) \
+ BFD_SEND (abfd, _bfd_make_empty_symbol, (abfd))
+
+2.7.5.9 `_bfd_generic_make_empty_symbol'
+........................................
+
+*Synopsis*
+ asymbol *_bfd_generic_make_empty_symbol (bfd *);
+ *Description*
+Create a new `asymbol' structure for the BFD ABFD and return a pointer
+to it. Used by core file routines, binary back-end and anywhere else
+where no private info is needed.
+
+2.7.5.10 `bfd_make_debug_symbol'
+................................
+
+*Description*
+Create a new `asymbol' structure for the BFD 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))
+
+2.7.5.11 `bfd_decode_symclass'
+..............................
+
+*Description*
+Return a character corresponding to the symbol class of SYMBOL, or '?'
+for an unknown class.
+
+ *Synopsis*
+ int bfd_decode_symclass (asymbol *symbol);
+
+2.7.5.12 `bfd_is_undefined_symclass'
+....................................
+
+*Description*
+Returns non-zero if the class symbol returned by bfd_decode_symclass
+represents an undefined symbol. Returns zero otherwise.
+
+ *Synopsis*
+ bfd_boolean bfd_is_undefined_symclass (int symclass);
+
+2.7.5.13 `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);
+
+2.7.5.14 `bfd_copy_private_symbol_data'
+.......................................
+
+*Synopsis*
+ bfd_boolean bfd_copy_private_symbol_data
+ (bfd *ibfd, asymbol *isym, bfd *obfd, asymbol *osym);
+ *Description*
+Copy private symbol information from ISYM in the BFD IBFD to the symbol
+OSYM in the BFD OBFD. Return `TRUE' on success, `FALSE' on error.
+Possible error returns are:
+
+ * `bfd_error_no_memory' - Not enough memory exists to create private
+ data for OSEC.
+
+ #define bfd_copy_private_symbol_data(ibfd, isymbol, obfd, osymbol) \
+ BFD_SEND (obfd, _bfd_copy_private_symbol_data, \
+ (ibfd, isymbol, obfd, osymbol))
+
+
+File: bfd.info, Node: Archives, Next: Formats, Prev: Symbols, Up: BFD front end
+
+2.8 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.
+
+ A BFD returned by `bfd_openr_next_archived_file' can be closed
+manually with `bfd_close'. If you do not close it, then a second
+iteration through the members of an archive may return the same BFD.
+If you close the archive BFD, then all the member BFDs will
+automatically be closed as well.
+
+ Archive contents of output BFDs are chained through the
+`archive_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'.
+
+2.8.1 Archive functions
+-----------------------
+
+2.8.1.1 `bfd_get_next_mapent'
+.............................
+
+*Synopsis*
+ symindex bfd_get_next_mapent
+ (bfd *abfd, symindex previous, carsym **sym);
+ *Description*
+Step through archive ABFD's symbol table (if it has one). Successively
+update SYM with the next symbol's information, returning that symbol's
+(internal) index into the symbol table.
+
+ Supply `BFD_NO_MORE_SYMBOLS' as the 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.
+
+2.8.1.2 `bfd_set_archive_head'
+..............................
+
+*Synopsis*
+ bfd_boolean bfd_set_archive_head (bfd *output, bfd *new_head);
+ *Description*
+Set the head of the chain of BFDs contained in the archive OUTPUT to
+NEW_HEAD.
+
+2.8.1.3 `bfd_openr_next_archived_file'
+......................................
+
+*Synopsis*
+ bfd *bfd_openr_next_archived_file (bfd *archive, bfd *previous);
+ *Description*
+Provided a BFD, 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.
+
+
+File: bfd.info, Node: Formats, Next: Relocations, Prev: Archives, Up: BFD front end
+
+2.9 File formats
+================
+
+A format is a BFD concept of high level file contents type. The formats
+supported by BFD are:
+
+ * `bfd_object'
+ The BFD may contain data, symbols, relocations and debug info.
+
+ * `bfd_archive'
+ The BFD contains other BFDs and an optional index.
+
+ * `bfd_core'
+ The BFD contains the result of an executable core dump.
+
+2.9.1 File format functions
+---------------------------
+
+2.9.1.1 `bfd_check_format'
+..........................
+
+*Synopsis*
+ bfd_boolean bfd_check_format (bfd *abfd, bfd_format format);
+ *Description*
+Verify if the file attached to the BFD ABFD is compatible with the
+format 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:
+
+ * `bfd_error_invalid_operation' - if `format' is not one of
+ `bfd_object', `bfd_archive' or `bfd_core'.
+
+ * `bfd_error_system_call' - if an error occured during a read - even
+ some file mismatches can cause bfd_error_system_calls.
+
+ * `file_not_recognised' - none of the backends recognised the file
+ format.
+
+ * `bfd_error_file_ambiguously_recognized' - more than one backend
+ recognised the file format.
+
+2.9.1.2 `bfd_check_format_matches'
+..................................
+
+*Synopsis*
+ bfd_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
+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 MATCHING points to, the caller should
+free it.
+
+2.9.1.3 `bfd_set_format'
+........................
+
+*Synopsis*
+ bfd_boolean bfd_set_format (bfd *abfd, bfd_format format);
+ *Description*
+This function sets the file format of the BFD ABFD to the format
+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.
+
+2.9.1.4 `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 FORMAT.
+
+
+File: bfd.info, Node: Relocations, Next: Core Files, Prev: Formats, Up: BFD front end
+
+2.10 Relocations
+================
+
+BFD maintains relocations in much the same way it maintains symbols:
+they are left alone until required, then read in en-masse 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::
+
+
+File: bfd.info, Node: typedef arelent, Next: howto manager, Prev: Relocations, Up: Relocations
+
+2.10.1 typedef arelent
+----------------------
+
+This is the structure of a relocation entry:
+
+
+ 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 bfd_symbol **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':
+
+ * `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 `canonicalize_symtab' action. *Note
+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.
+
+ * `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.
+
+ * `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
+
+ * `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.
+
+2.10.1.1 `enum complain_overflow'
+.................................
+
+Indicates what sort of overflow checking should be done when performing
+a relocation.
+
+
+ enum complain_overflow
+ {
+ /* Do not complain on overflow. */
+ complain_overflow_dont,
+
+ /* Complain if the value overflows when considered as a signed
+ number one bit larger than the field. ie. A bitfield of N bits
+ is allowed to represent -2**n to 2**n-1. */
+ complain_overflow_bitfield,
+
+ /* Complain if the value overflows when considered as a signed
+ number. */
+ complain_overflow_signed,
+
+ /* Complain if the value overflows when considered as an
+ unsigned number. */
+ complain_overflow_unsigned
+ };
+
+2.10.1.2 `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.
+
+ struct bfd_symbol; /* 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;
+
+ /* The relocation is relative to the field being relocated. */
+ bfd_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 accommodated (e.g., i960 callj
+ instructions). */
+ bfd_reloc_status_type (*special_function)
+ (bfd *, arelent *, struct bfd_symbol *, void *, asection *,
+ bfd *, char **);
+
+ /* The textual name of the relocation type. */
+ char *name;
+
+ /* Some formats record a relocation addend in the section contents
+ rather than with the relocation. For ELF formats this is the
+ distinction between USE_REL and USE_RELA (though the code checks
+ for USE_REL == 1/0). The value of this field is TRUE if the
+ addend is recorded with the section contents; when performing a
+ partial link (ld -r) the section contents (the data) will be
+ modified. The value of this field is FALSE if addends are
+ recorded with the relocation (in arelent.addend); when performing
+ a partial link the relocation will be modified.
+ All relocations for all ELF USE_RELA targets should set this field
+ to FALSE (values of TRUE should be looked on with suspicion).
+ However, the converse is not true: not all relocations of all ELF
+ USE_REL targets set this field to TRUE. Why this is so is peculiar
+ to each particular target. For relocs that aren't used in partial
+ links (e.g. GOT stuff) it doesn't matter what this is set to. */
+ bfd_boolean partial_inplace;
+
+ /* src_mask selects the part of the instruction (or data) to be used
+ in the relocation sum. If the target relocations don't have an
+ addend in the reloc, eg. ELF USE_REL, src_mask will normally equal
+ dst_mask to extract the addend from the section contents. If
+ relocations do have an addend in the reloc, eg. ELF USE_RELA, this
+ field should be zero. Non-zero values for ELF USE_RELA targets are
+ bogus as in those cases the value in the dst_mask part of the
+ section contents should be treated as garbage. */
+ bfd_vma src_mask;
+
+ /* dst_mask selects which parts of the instruction (or data) are
+ replaced with a relocated value. */
+ 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. */
+ bfd_boolean pcrel_offset;
+ };
+
+2.10.1.3 `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*
+This is used to fill in an empty howto entry in an array.
+ #define EMPTY_HOWTO(C) \
+ HOWTO ((C), 0, 0, 0, FALSE, 0, complain_overflow_dont, NULL, \
+ NULL, FALSE, 0, 0, FALSE)
+
+ *Description*
+Helper routine to turn a symbol into a relocation value.
+ #define HOWTO_PREPARE(relocation, symbol) \
+ { \
+ if (symbol != NULL) \
+ { \
+ if (bfd_is_com_section (symbol->section)) \
+ { \
+ relocation = 0; \
+ } \
+ else \
+ { \
+ relocation = symbol->value; \
+ } \
+ } \
+ }
+
+2.10.1.4 `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.
+
+2.10.1.5 `arelent_chain'
+........................
+
+*Description*
+How relocs are tied together in an `asection':
+ typedef struct relent_chain
+ {
+ arelent relent;
+ struct relent_chain *next;
+ }
+ arelent_chain;
+
+2.10.1.6 `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 RELOCATION which has BITSIZE significant
+bits and will be shifted right by RIGHTSHIFT bits, on a machine with
+addresses containing ADDRSIZE significant bits. The result is either of
+`bfd_reloc_ok' or `bfd_reloc_overflow'.
+
+2.10.1.7 `bfd_perform_relocation'
+.................................
+
+*Synopsis*
+ bfd_reloc_status_type bfd_perform_relocation
+ (bfd *abfd,
+ arelent *reloc_entry,
+ void *data,
+ asection *input_section,
+ bfd *output_bfd,
+ char **error_message);
+ *Description*
+If 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
+ERROR_MESSAGE argument is set to an error message if this return
+`bfd_reloc_dangerous'.
+
+2.10.1.8 `bfd_install_relocation'
+.................................
+
+*Synopsis*
+ bfd_reloc_status_type bfd_install_relocation
+ (bfd *abfd,
+ arelent *reloc_entry,
+ void *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.
+
+
+File: bfd.info, Node: howto manager, Prev: typedef arelent, Up: Relocations
+
+2.10.2 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.
+
+2.10.2.1 `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.
+
+ Here are the possible values for `enum bfd_reloc_code_real':
+
+ -- : BFD_RELOC_64
+ -- : BFD_RELOC_32
+ -- : BFD_RELOC_26
+ -- : BFD_RELOC_24
+ -- : BFD_RELOC_16
+ -- : BFD_RELOC_14
+ -- : BFD_RELOC_8
+ Basic absolute relocations of N bits.
+
+ -- : BFD_RELOC_64_PCREL
+ -- : BFD_RELOC_32_PCREL
+ -- : BFD_RELOC_24_PCREL
+ -- : BFD_RELOC_16_PCREL
+ -- : BFD_RELOC_12_PCREL
+ -- : BFD_RELOC_8_PCREL
+ 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_32_SECREL
+ Section relative relocations. Some targets need this for DWARF2.
+
+ -- : 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_64_PLT_PCREL
+ -- : BFD_RELOC_32_PLT_PCREL
+ -- : BFD_RELOC_24_PLT_PCREL
+ -- : BFD_RELOC_16_PLT_PCREL
+ -- : BFD_RELOC_8_PLT_PCREL
+ -- : BFD_RELOC_64_PLTOFF
+ -- : 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
+ For ELF.
+
+ -- : BFD_RELOC_SIZE32
+ -- : BFD_RELOC_SIZE64
+ Size relocations.
+
+ -- : BFD_RELOC_68K_GLOB_DAT
+ -- : BFD_RELOC_68K_JMP_SLOT
+ -- : BFD_RELOC_68K_RELATIVE
+ -- : BFD_RELOC_68K_TLS_GD32
+ -- : BFD_RELOC_68K_TLS_GD16
+ -- : BFD_RELOC_68K_TLS_GD8
+ -- : BFD_RELOC_68K_TLS_LDM32
+ -- : BFD_RELOC_68K_TLS_LDM16
+ -- : BFD_RELOC_68K_TLS_LDM8
+ -- : BFD_RELOC_68K_TLS_LDO32
+ -- : BFD_RELOC_68K_TLS_LDO16
+ -- : BFD_RELOC_68K_TLS_LDO8
+ -- : BFD_RELOC_68K_TLS_IE32
+ -- : BFD_RELOC_68K_TLS_IE16
+ -- : BFD_RELOC_68K_TLS_IE8
+ -- : BFD_RELOC_68K_TLS_LE32
+ -- : BFD_RELOC_68K_TLS_LE16
+ -- : BFD_RELOC_68K_TLS_LE8
+ Relocations used by 68K ELF.
+
+ -- : 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
+ Linkage-table relative.
+
+ -- : BFD_RELOC_8_FFnn
+ Absolute 8-bit relocation, but used to form an address like 0xFFnn.
+
+ -- : BFD_RELOC_32_PCREL_S2
+ -- : BFD_RELOC_16_PCREL_S2
+ -- : BFD_RELOC_23_PCREL_S2
+ 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_HI22
+ -- : BFD_RELOC_LO10
+ 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_GPREL16
+ -- : BFD_RELOC_GPREL32
+ 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_I960_CALLJ
+ Reloc types used for i960/b.out.
+
+ -- : 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_UA16
+ -- : BFD_RELOC_SPARC_UA32
+ -- : BFD_RELOC_SPARC_UA64
+ -- : BFD_RELOC_SPARC_GOTDATA_HIX22
+ -- : BFD_RELOC_SPARC_GOTDATA_LOX10
+ -- : BFD_RELOC_SPARC_GOTDATA_OP_HIX22
+ -- : BFD_RELOC_SPARC_GOTDATA_OP_LOX10
+ -- : BFD_RELOC_SPARC_GOTDATA_OP
+ -- : BFD_RELOC_SPARC_JMP_IREL
+ -- : BFD_RELOC_SPARC_IRELATIVE
+ SPARC ELF relocations. There is probably some overlap with other
+ relocation types already defined.
+
+ -- : BFD_RELOC_SPARC_BASE13
+ -- : BFD_RELOC_SPARC_BASE22
+ I think these are specific to SPARC a.out (e.g., Sun 4).
+
+ -- : BFD_RELOC_SPARC_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
+ -- : BFD_RELOC_SPARC_DISP64
+ -- : BFD_RELOC_SPARC_PLT32
+ -- : 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_H34
+ -- : BFD_RELOC_SPARC_SIZE32
+ -- : BFD_RELOC_SPARC_SIZE64
+ -- : BFD_RELOC_SPARC_WDISP10
+ SPARC64 relocations
+
+ -- : BFD_RELOC_SPARC_REV32
+ SPARC little endian relocation
+
+ -- : BFD_RELOC_SPARC_TLS_GD_HI22
+ -- : BFD_RELOC_SPARC_TLS_GD_LO10
+ -- : BFD_RELOC_SPARC_TLS_GD_ADD
+ -- : BFD_RELOC_SPARC_TLS_GD_CALL
+ -- : BFD_RELOC_SPARC_TLS_LDM_HI22
+ -- : BFD_RELOC_SPARC_TLS_LDM_LO10
+ -- : BFD_RELOC_SPARC_TLS_LDM_ADD
+ -- : BFD_RELOC_SPARC_TLS_LDM_CALL
+ -- : BFD_RELOC_SPARC_TLS_LDO_HIX22
+ -- : BFD_RELOC_SPARC_TLS_LDO_LOX10
+ -- : BFD_RELOC_SPARC_TLS_LDO_ADD
+ -- : BFD_RELOC_SPARC_TLS_IE_HI22
+ -- : BFD_RELOC_SPARC_TLS_IE_LO10
+ -- : BFD_RELOC_SPARC_TLS_IE_LD
+ -- : BFD_RELOC_SPARC_TLS_IE_LDX
+ -- : BFD_RELOC_SPARC_TLS_IE_ADD
+ -- : BFD_RELOC_SPARC_TLS_LE_HIX22
+ -- : BFD_RELOC_SPARC_TLS_LE_LOX10
+ -- : BFD_RELOC_SPARC_TLS_DTPMOD32
+ -- : BFD_RELOC_SPARC_TLS_DTPMOD64
+ -- : BFD_RELOC_SPARC_TLS_DTPOFF32
+ -- : BFD_RELOC_SPARC_TLS_DTPOFF64
+ -- : BFD_RELOC_SPARC_TLS_TPOFF32
+ -- : BFD_RELOC_SPARC_TLS_TPOFF64
+ SPARC TLS relocations
+
+ -- : BFD_RELOC_SPU_IMM7
+ -- : BFD_RELOC_SPU_IMM8
+ -- : BFD_RELOC_SPU_IMM10
+ -- : BFD_RELOC_SPU_IMM10W
+ -- : BFD_RELOC_SPU_IMM16
+ -- : BFD_RELOC_SPU_IMM16W
+ -- : BFD_RELOC_SPU_IMM18
+ -- : BFD_RELOC_SPU_PCREL9a
+ -- : BFD_RELOC_SPU_PCREL9b
+ -- : BFD_RELOC_SPU_PCREL16
+ -- : BFD_RELOC_SPU_LO16
+ -- : BFD_RELOC_SPU_HI16
+ -- : BFD_RELOC_SPU_PPU32
+ -- : BFD_RELOC_SPU_PPU64
+ -- : BFD_RELOC_SPU_ADD_PIC
+ SPU Relocations.
+
+ -- : BFD_RELOC_ALPHA_GPDISP_HI16
+ 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_LO16
+ 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
+ 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_LITERAL
+ -- : BFD_RELOC_ALPHA_ELF_LITERAL
+ -- : BFD_RELOC_ALPHA_LITUSE
+ 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)
+
+ -- : BFD_RELOC_ALPHA_HINT
+ 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_LINKAGE
+ The LINKAGE relocation outputs a linkage pair in the object file,
+ which is filled by the linker.
+
+ -- : BFD_RELOC_ALPHA_CODEADDR
+ The CODEADDR relocation outputs a STO_CA in the object file, which
+ is filled by the linker.
+
+ -- : BFD_RELOC_ALPHA_GPREL_HI16
+ -- : BFD_RELOC_ALPHA_GPREL_LO16
+ The GPREL_HI/LO relocations together form a 32-bit offset from the
+ GP register.
+
+ -- : BFD_RELOC_ALPHA_BRSGP
+ Like BFD_RELOC_23_PCREL_S2, except that the source and target must
+ share a common GP, and the target address is adjusted for
+ STO_ALPHA_STD_GPLOAD.
+
+ -- : BFD_RELOC_ALPHA_NOP
+ The NOP relocation outputs a NOP if the longword displacement
+ between two procedure entry points is < 2^21.
+
+ -- : BFD_RELOC_ALPHA_BSR
+ The BSR relocation outputs a BSR if the longword displacement
+ between two procedure entry points is < 2^21.
+
+ -- : BFD_RELOC_ALPHA_LDA
+ The LDA relocation outputs a LDA if the longword displacement
+ between two procedure entry points is < 2^16.
+
+ -- : BFD_RELOC_ALPHA_BOH
+ The BOH relocation outputs a BSR if the longword displacement
+ between two procedure entry points is < 2^21, or else a hint.
+
+ -- : BFD_RELOC_ALPHA_TLSGD
+ -- : BFD_RELOC_ALPHA_TLSLDM
+ -- : BFD_RELOC_ALPHA_DTPMOD64
+ -- : BFD_RELOC_ALPHA_GOTDTPREL16
+ -- : BFD_RELOC_ALPHA_DTPREL64
+ -- : BFD_RELOC_ALPHA_DTPREL_HI16
+ -- : BFD_RELOC_ALPHA_DTPREL_LO16
+ -- : BFD_RELOC_ALPHA_DTPREL16
+ -- : BFD_RELOC_ALPHA_GOTTPREL16
+ -- : BFD_RELOC_ALPHA_TPREL64
+ -- : BFD_RELOC_ALPHA_TPREL_HI16
+ -- : BFD_RELOC_ALPHA_TPREL_LO16
+ -- : BFD_RELOC_ALPHA_TPREL16
+ Alpha thread-local storage relocations.
+
+ -- : BFD_RELOC_MIPS_JMP
+ -- : BFD_RELOC_MICROMIPS_JMP
+ The MIPS jump instruction.
+
+ -- : BFD_RELOC_MIPS16_JMP
+ The MIPS16 jump instruction.
+
+ -- : BFD_RELOC_MIPS16_GPREL
+ MIPS16 GP relative reloc.
+
+ -- : BFD_RELOC_HI16
+ High 16 bits of 32-bit value; simple reloc.
+
+ -- : BFD_RELOC_HI16_S
+ 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_LO16
+ Low 16 bits.
+
+ -- : BFD_RELOC_HI16_PCREL
+ High 16 bits of 32-bit pc-relative value
+
+ -- : BFD_RELOC_HI16_S_PCREL
+ High 16 bits of 32-bit pc-relative value, adjusted
+
+ -- : BFD_RELOC_LO16_PCREL
+ Low 16 bits of pc-relative value
+
+ -- : BFD_RELOC_MIPS16_GOT16
+ -- : BFD_RELOC_MIPS16_CALL16
+ Equivalent of BFD_RELOC_MIPS_*, but with the MIPS16 layout of
+ 16-bit immediate fields
+
+ -- : BFD_RELOC_MIPS16_HI16
+ MIPS16 high 16 bits of 32-bit value.
+
+ -- : BFD_RELOC_MIPS16_HI16_S
+ MIPS16 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_MIPS16_LO16
+ MIPS16 low 16 bits.
+
+ -- : BFD_RELOC_MIPS16_TLS_GD
+ -- : BFD_RELOC_MIPS16_TLS_LDM
+ -- : BFD_RELOC_MIPS16_TLS_DTPREL_HI16
+ -- : BFD_RELOC_MIPS16_TLS_DTPREL_LO16
+ -- : BFD_RELOC_MIPS16_TLS_GOTTPREL
+ -- : BFD_RELOC_MIPS16_TLS_TPREL_HI16
+ -- : BFD_RELOC_MIPS16_TLS_TPREL_LO16
+ MIPS16 TLS relocations
+
+ -- : BFD_RELOC_MIPS_LITERAL
+ -- : BFD_RELOC_MICROMIPS_LITERAL
+ Relocation against a MIPS literal section.
+
+ -- : BFD_RELOC_MICROMIPS_7_PCREL_S1
+ -- : BFD_RELOC_MICROMIPS_10_PCREL_S1
+ -- : BFD_RELOC_MICROMIPS_16_PCREL_S1
+ microMIPS PC-relative relocations.
+
+ -- : BFD_RELOC_MIPS_21_PCREL_S2
+ -- : BFD_RELOC_MIPS_26_PCREL_S2
+ -- : BFD_RELOC_MIPS_18_PCREL_S3
+ -- : BFD_RELOC_MIPS_19_PCREL_S2
+ MIPS PC-relative relocations.
+
+ -- : BFD_RELOC_MICROMIPS_GPREL16
+ -- : BFD_RELOC_MICROMIPS_HI16
+ -- : BFD_RELOC_MICROMIPS_HI16_S
+ -- : BFD_RELOC_MICROMIPS_LO16
+ microMIPS versions of generic BFD relocs.
+
+ -- : BFD_RELOC_MIPS_GOT16
+ -- : BFD_RELOC_MICROMIPS_GOT16
+ -- : BFD_RELOC_MIPS_CALL16
+ -- : BFD_RELOC_MICROMIPS_CALL16
+ -- : BFD_RELOC_MIPS_GOT_HI16
+ -- : BFD_RELOC_MICROMIPS_GOT_HI16
+ -- : BFD_RELOC_MIPS_GOT_LO16
+ -- : BFD_RELOC_MICROMIPS_GOT_LO16
+ -- : BFD_RELOC_MIPS_CALL_HI16
+ -- : BFD_RELOC_MICROMIPS_CALL_HI16
+ -- : BFD_RELOC_MIPS_CALL_LO16
+ -- : BFD_RELOC_MICROMIPS_CALL_LO16
+ -- : BFD_RELOC_MIPS_SUB
+ -- : BFD_RELOC_MICROMIPS_SUB
+ -- : BFD_RELOC_MIPS_GOT_PAGE
+ -- : BFD_RELOC_MICROMIPS_GOT_PAGE
+ -- : BFD_RELOC_MIPS_GOT_OFST
+ -- : BFD_RELOC_MICROMIPS_GOT_OFST
+ -- : BFD_RELOC_MIPS_GOT_DISP
+ -- : BFD_RELOC_MICROMIPS_GOT_DISP
+ -- : BFD_RELOC_MIPS_SHIFT5
+ -- : BFD_RELOC_MIPS_SHIFT6
+ -- : BFD_RELOC_MIPS_INSERT_A
+ -- : BFD_RELOC_MIPS_INSERT_B
+ -- : BFD_RELOC_MIPS_DELETE
+ -- : BFD_RELOC_MIPS_HIGHEST
+ -- : BFD_RELOC_MICROMIPS_HIGHEST
+ -- : BFD_RELOC_MIPS_HIGHER
+ -- : BFD_RELOC_MICROMIPS_HIGHER
+ -- : BFD_RELOC_MIPS_SCN_DISP
+ -- : BFD_RELOC_MICROMIPS_SCN_DISP
+ -- : BFD_RELOC_MIPS_REL16
+ -- : BFD_RELOC_MIPS_RELGOT
+ -- : BFD_RELOC_MIPS_JALR
+ -- : BFD_RELOC_MICROMIPS_JALR
+ -- : BFD_RELOC_MIPS_TLS_DTPMOD32
+ -- : BFD_RELOC_MIPS_TLS_DTPREL32
+ -- : BFD_RELOC_MIPS_TLS_DTPMOD64
+ -- : BFD_RELOC_MIPS_TLS_DTPREL64
+ -- : BFD_RELOC_MIPS_TLS_GD
+ -- : BFD_RELOC_MICROMIPS_TLS_GD
+ -- : BFD_RELOC_MIPS_TLS_LDM
+ -- : BFD_RELOC_MICROMIPS_TLS_LDM
+ -- : BFD_RELOC_MIPS_TLS_DTPREL_HI16
+ -- : BFD_RELOC_MICROMIPS_TLS_DTPREL_HI16
+ -- : BFD_RELOC_MIPS_TLS_DTPREL_LO16
+ -- : BFD_RELOC_MICROMIPS_TLS_DTPREL_LO16
+ -- : BFD_RELOC_MIPS_TLS_GOTTPREL
+ -- : BFD_RELOC_MICROMIPS_TLS_GOTTPREL
+ -- : BFD_RELOC_MIPS_TLS_TPREL32
+ -- : BFD_RELOC_MIPS_TLS_TPREL64
+ -- : BFD_RELOC_MIPS_TLS_TPREL_HI16
+ -- : BFD_RELOC_MICROMIPS_TLS_TPREL_HI16
+ -- : BFD_RELOC_MIPS_TLS_TPREL_LO16
+ -- : BFD_RELOC_MICROMIPS_TLS_TPREL_LO16
+ -- : BFD_RELOC_MIPS_EH
+ MIPS ELF relocations.
+
+ -- : BFD_RELOC_MIPS_COPY
+ -- : BFD_RELOC_MIPS_JUMP_SLOT
+ MIPS ELF relocations (VxWorks and PLT extensions).
+
+ -- : BFD_RELOC_MOXIE_10_PCREL
+ Moxie ELF relocations.
+
+ -- : BFD_RELOC_FRV_LABEL16
+ -- : BFD_RELOC_FRV_LABEL24
+ -- : BFD_RELOC_FRV_LO16
+ -- : BFD_RELOC_FRV_HI16
+ -- : BFD_RELOC_FRV_GPREL12
+ -- : BFD_RELOC_FRV_GPRELU12
+ -- : BFD_RELOC_FRV_GPREL32
+ -- : BFD_RELOC_FRV_GPRELHI
+ -- : BFD_RELOC_FRV_GPRELLO
+ -- : BFD_RELOC_FRV_GOT12
+ -- : BFD_RELOC_FRV_GOTHI
+ -- : BFD_RELOC_FRV_GOTLO
+ -- : BFD_RELOC_FRV_FUNCDESC
+ -- : BFD_RELOC_FRV_FUNCDESC_GOT12
+ -- : BFD_RELOC_FRV_FUNCDESC_GOTHI
+ -- : BFD_RELOC_FRV_FUNCDESC_GOTLO
+ -- : BFD_RELOC_FRV_FUNCDESC_VALUE
+ -- : BFD_RELOC_FRV_FUNCDESC_GOTOFF12
+ -- : BFD_RELOC_FRV_FUNCDESC_GOTOFFHI
+ -- : BFD_RELOC_FRV_FUNCDESC_GOTOFFLO
+ -- : BFD_RELOC_FRV_GOTOFF12
+ -- : BFD_RELOC_FRV_GOTOFFHI
+ -- : BFD_RELOC_FRV_GOTOFFLO
+ -- : BFD_RELOC_FRV_GETTLSOFF
+ -- : BFD_RELOC_FRV_TLSDESC_VALUE
+ -- : BFD_RELOC_FRV_GOTTLSDESC12
+ -- : BFD_RELOC_FRV_GOTTLSDESCHI
+ -- : BFD_RELOC_FRV_GOTTLSDESCLO
+ -- : BFD_RELOC_FRV_TLSMOFF12
+ -- : BFD_RELOC_FRV_TLSMOFFHI
+ -- : BFD_RELOC_FRV_TLSMOFFLO
+ -- : BFD_RELOC_FRV_GOTTLSOFF12
+ -- : BFD_RELOC_FRV_GOTTLSOFFHI
+ -- : BFD_RELOC_FRV_GOTTLSOFFLO
+ -- : BFD_RELOC_FRV_TLSOFF
+ -- : BFD_RELOC_FRV_TLSDESC_RELAX
+ -- : BFD_RELOC_FRV_GETTLSOFF_RELAX
+ -- : BFD_RELOC_FRV_TLSOFF_RELAX
+ -- : BFD_RELOC_FRV_TLSMOFF
+ Fujitsu Frv Relocations.
+
+ -- : BFD_RELOC_MN10300_GOTOFF24
+ This is a 24bit GOT-relative reloc for the mn10300.
+
+ -- : BFD_RELOC_MN10300_GOT32
+ This is a 32bit GOT-relative reloc for the mn10300, offset by two
+ bytes in the instruction.
+
+ -- : BFD_RELOC_MN10300_GOT24
+ This is a 24bit GOT-relative reloc for the mn10300, offset by two
+ bytes in the instruction.
+
+ -- : BFD_RELOC_MN10300_GOT16
+ This is a 16bit GOT-relative reloc for the mn10300, offset by two
+ bytes in the instruction.
+
+ -- : BFD_RELOC_MN10300_COPY
+ Copy symbol at runtime.
+
+ -- : BFD_RELOC_MN10300_GLOB_DAT
+ Create GOT entry.
+
+ -- : BFD_RELOC_MN10300_JMP_SLOT
+ Create PLT entry.
+
+ -- : BFD_RELOC_MN10300_RELATIVE
+ Adjust by program base.
+
+ -- : BFD_RELOC_MN10300_SYM_DIFF
+ Together with another reloc targeted at the same location, allows
+ for a value that is the difference of two symbols in the same
+ section.
+
+ -- : BFD_RELOC_MN10300_ALIGN
+ The addend of this reloc is an alignment power that must be
+ honoured at the offset's location, regardless of linker relaxation.
+
+ -- : BFD_RELOC_MN10300_TLS_GD
+ -- : BFD_RELOC_MN10300_TLS_LD
+ -- : BFD_RELOC_MN10300_TLS_LDO
+ -- : BFD_RELOC_MN10300_TLS_GOTIE
+ -- : BFD_RELOC_MN10300_TLS_IE
+ -- : BFD_RELOC_MN10300_TLS_LE
+ -- : BFD_RELOC_MN10300_TLS_DTPMOD
+ -- : BFD_RELOC_MN10300_TLS_DTPOFF
+ -- : BFD_RELOC_MN10300_TLS_TPOFF
+ Various TLS-related relocations.
+
+ -- : BFD_RELOC_MN10300_32_PCREL
+ This is a 32bit pcrel reloc for the mn10300, offset by two bytes
+ in the instruction.
+
+ -- : BFD_RELOC_MN10300_16_PCREL
+ This is a 16bit pcrel reloc for the mn10300, offset by two bytes
+ in the instruction.
+
+ -- : 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_386_TLS_TPOFF
+ -- : BFD_RELOC_386_TLS_IE
+ -- : BFD_RELOC_386_TLS_GOTIE
+ -- : BFD_RELOC_386_TLS_LE
+ -- : BFD_RELOC_386_TLS_GD
+ -- : BFD_RELOC_386_TLS_LDM
+ -- : BFD_RELOC_386_TLS_LDO_32
+ -- : BFD_RELOC_386_TLS_IE_32
+ -- : BFD_RELOC_386_TLS_LE_32
+ -- : BFD_RELOC_386_TLS_DTPMOD32
+ -- : BFD_RELOC_386_TLS_DTPOFF32
+ -- : BFD_RELOC_386_TLS_TPOFF32
+ -- : BFD_RELOC_386_TLS_GOTDESC
+ -- : BFD_RELOC_386_TLS_DESC_CALL
+ -- : BFD_RELOC_386_TLS_DESC
+ -- : BFD_RELOC_386_IRELATIVE
+ i386/elf relocations
+
+ -- : BFD_RELOC_X86_64_GOT32
+ -- : BFD_RELOC_X86_64_PLT32
+ -- : BFD_RELOC_X86_64_COPY
+ -- : BFD_RELOC_X86_64_GLOB_DAT
+ -- : BFD_RELOC_X86_64_JUMP_SLOT
+ -- : BFD_RELOC_X86_64_RELATIVE
+ -- : BFD_RELOC_X86_64_GOTPCREL
+ -- : BFD_RELOC_X86_64_32S
+ -- : BFD_RELOC_X86_64_DTPMOD64
+ -- : BFD_RELOC_X86_64_DTPOFF64
+ -- : BFD_RELOC_X86_64_TPOFF64
+ -- : BFD_RELOC_X86_64_TLSGD
+ -- : BFD_RELOC_X86_64_TLSLD
+ -- : BFD_RELOC_X86_64_DTPOFF32
+ -- : BFD_RELOC_X86_64_GOTTPOFF
+ -- : BFD_RELOC_X86_64_TPOFF32
+ -- : BFD_RELOC_X86_64_GOTOFF64
+ -- : BFD_RELOC_X86_64_GOTPC32
+ -- : BFD_RELOC_X86_64_GOT64
+ -- : BFD_RELOC_X86_64_GOTPCREL64
+ -- : BFD_RELOC_X86_64_GOTPC64
+ -- : BFD_RELOC_X86_64_GOTPLT64
+ -- : BFD_RELOC_X86_64_PLTOFF64
+ -- : BFD_RELOC_X86_64_GOTPC32_TLSDESC
+ -- : BFD_RELOC_X86_64_TLSDESC_CALL
+ -- : BFD_RELOC_X86_64_TLSDESC
+ -- : BFD_RELOC_X86_64_IRELATIVE
+ -- : BFD_RELOC_X86_64_PC32_BND
+ -- : BFD_RELOC_X86_64_PLT32_BND
+ x86-64/elf 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
+ ns32k relocations
+
+ -- : BFD_RELOC_PDP11_DISP_8_PCREL
+ -- : BFD_RELOC_PDP11_DISP_6_PCREL
+ PDP11 relocations
+
+ -- : BFD_RELOC_PJ_CODE_HI16
+ -- : BFD_RELOC_PJ_CODE_LO16
+ -- : BFD_RELOC_PJ_CODE_DIR16
+ -- : BFD_RELOC_PJ_CODE_DIR32
+ -- : BFD_RELOC_PJ_CODE_REL16
+ -- : BFD_RELOC_PJ_CODE_REL32
+ Picojava relocs. Not all of these appear in object files.
+
+ -- : 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_PPC_VLE_REL8
+ -- : BFD_RELOC_PPC_VLE_REL15
+ -- : BFD_RELOC_PPC_VLE_REL24
+ -- : BFD_RELOC_PPC_VLE_LO16A
+ -- : BFD_RELOC_PPC_VLE_LO16D
+ -- : BFD_RELOC_PPC_VLE_HI16A
+ -- : BFD_RELOC_PPC_VLE_HI16D
+ -- : BFD_RELOC_PPC_VLE_HA16A
+ -- : BFD_RELOC_PPC_VLE_HA16D
+ -- : BFD_RELOC_PPC_VLE_SDA21
+ -- : BFD_RELOC_PPC_VLE_SDA21_LO
+ -- : BFD_RELOC_PPC_VLE_SDAREL_LO16A
+ -- : BFD_RELOC_PPC_VLE_SDAREL_LO16D
+ -- : BFD_RELOC_PPC_VLE_SDAREL_HI16A
+ -- : BFD_RELOC_PPC_VLE_SDAREL_HI16D
+ -- : BFD_RELOC_PPC_VLE_SDAREL_HA16A
+ -- : BFD_RELOC_PPC_VLE_SDAREL_HA16D
+ -- : BFD_RELOC_PPC64_HIGHER
+ -- : BFD_RELOC_PPC64_HIGHER_S
+ -- : BFD_RELOC_PPC64_HIGHEST
+ -- : BFD_RELOC_PPC64_HIGHEST_S
+ -- : BFD_RELOC_PPC64_TOC16_LO
+ -- : BFD_RELOC_PPC64_TOC16_HI
+ -- : BFD_RELOC_PPC64_TOC16_HA
+ -- : BFD_RELOC_PPC64_TOC
+ -- : BFD_RELOC_PPC64_PLTGOT16
+ -- : BFD_RELOC_PPC64_PLTGOT16_LO
+ -- : BFD_RELOC_PPC64_PLTGOT16_HI
+ -- : BFD_RELOC_PPC64_PLTGOT16_HA
+ -- : BFD_RELOC_PPC64_ADDR16_DS
+ -- : BFD_RELOC_PPC64_ADDR16_LO_DS
+ -- : BFD_RELOC_PPC64_GOT16_DS
+ -- : BFD_RELOC_PPC64_GOT16_LO_DS
+ -- : BFD_RELOC_PPC64_PLT16_LO_DS
+ -- : BFD_RELOC_PPC64_SECTOFF_DS
+ -- : BFD_RELOC_PPC64_SECTOFF_LO_DS
+ -- : BFD_RELOC_PPC64_TOC16_DS
+ -- : BFD_RELOC_PPC64_TOC16_LO_DS
+ -- : BFD_RELOC_PPC64_PLTGOT16_DS
+ -- : BFD_RELOC_PPC64_PLTGOT16_LO_DS
+ -- : BFD_RELOC_PPC64_ADDR16_HIGH
+ -- : BFD_RELOC_PPC64_ADDR16_HIGHA
+ -- : BFD_RELOC_PPC64_ADDR64_LOCAL
+ Power(rs6000) and PowerPC relocations.
+
+ -- : BFD_RELOC_PPC_TLS
+ -- : BFD_RELOC_PPC_TLSGD
+ -- : BFD_RELOC_PPC_TLSLD
+ -- : BFD_RELOC_PPC_DTPMOD
+ -- : BFD_RELOC_PPC_TPREL16
+ -- : BFD_RELOC_PPC_TPREL16_LO
+ -- : BFD_RELOC_PPC_TPREL16_HI
+ -- : BFD_RELOC_PPC_TPREL16_HA
+ -- : BFD_RELOC_PPC_TPREL
+ -- : BFD_RELOC_PPC_DTPREL16
+ -- : BFD_RELOC_PPC_DTPREL16_LO
+ -- : BFD_RELOC_PPC_DTPREL16_HI
+ -- : BFD_RELOC_PPC_DTPREL16_HA
+ -- : BFD_RELOC_PPC_DTPREL
+ -- : BFD_RELOC_PPC_GOT_TLSGD16
+ -- : BFD_RELOC_PPC_GOT_TLSGD16_LO
+ -- : BFD_RELOC_PPC_GOT_TLSGD16_HI
+ -- : BFD_RELOC_PPC_GOT_TLSGD16_HA
+ -- : BFD_RELOC_PPC_GOT_TLSLD16
+ -- : BFD_RELOC_PPC_GOT_TLSLD16_LO
+ -- : BFD_RELOC_PPC_GOT_TLSLD16_HI
+ -- : BFD_RELOC_PPC_GOT_TLSLD16_HA
+ -- : BFD_RELOC_PPC_GOT_TPREL16
+ -- : BFD_RELOC_PPC_GOT_TPREL16_LO
+ -- : BFD_RELOC_PPC_GOT_TPREL16_HI
+ -- : BFD_RELOC_PPC_GOT_TPREL16_HA
+ -- : BFD_RELOC_PPC_GOT_DTPREL16
+ -- : BFD_RELOC_PPC_GOT_DTPREL16_LO
+ -- : BFD_RELOC_PPC_GOT_DTPREL16_HI
+ -- : BFD_RELOC_PPC_GOT_DTPREL16_HA
+ -- : BFD_RELOC_PPC64_TPREL16_DS
+ -- : BFD_RELOC_PPC64_TPREL16_LO_DS
+ -- : BFD_RELOC_PPC64_TPREL16_HIGHER
+ -- : BFD_RELOC_PPC64_TPREL16_HIGHERA
+ -- : BFD_RELOC_PPC64_TPREL16_HIGHEST
+ -- : BFD_RELOC_PPC64_TPREL16_HIGHESTA
+ -- : BFD_RELOC_PPC64_DTPREL16_DS
+ -- : BFD_RELOC_PPC64_DTPREL16_LO_DS
+ -- : BFD_RELOC_PPC64_DTPREL16_HIGHER
+ -- : BFD_RELOC_PPC64_DTPREL16_HIGHERA
+ -- : BFD_RELOC_PPC64_DTPREL16_HIGHEST
+ -- : BFD_RELOC_PPC64_DTPREL16_HIGHESTA
+ -- : BFD_RELOC_PPC64_TPREL16_HIGH
+ -- : BFD_RELOC_PPC64_TPREL16_HIGHA
+ -- : BFD_RELOC_PPC64_DTPREL16_HIGH
+ -- : BFD_RELOC_PPC64_DTPREL16_HIGHA
+ PowerPC and PowerPC64 thread-local storage relocations.
+
+ -- : BFD_RELOC_I370_D12
+ IBM 370/390 relocations
+
+ -- : BFD_RELOC_CTOR
+ The type of reloc used to build a constructor 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_ARM_PCREL_BRANCH
+ ARM 26 bit pc-relative branch. The lowest two bits must be zero
+ and are not stored in the instruction.
+
+ -- : BFD_RELOC_ARM_PCREL_BLX
+ ARM 26 bit pc-relative branch. The lowest bit must be zero and is
+ not stored in the instruction. The 2nd lowest bit comes from a 1
+ bit field in the instruction.
+
+ -- : BFD_RELOC_THUMB_PCREL_BLX
+ Thumb 22 bit pc-relative branch. The lowest bit must be zero and
+ is not stored in the instruction. The 2nd lowest bit comes from a
+ 1 bit field in the instruction.
+
+ -- : BFD_RELOC_ARM_PCREL_CALL
+ ARM 26-bit pc-relative branch for an unconditional BL or BLX
+ instruction.
+
+ -- : BFD_RELOC_ARM_PCREL_JUMP
+ ARM 26-bit pc-relative branch for B or conditional BL instruction.
+
+ -- : BFD_RELOC_THUMB_PCREL_BRANCH7
+ -- : BFD_RELOC_THUMB_PCREL_BRANCH9
+ -- : BFD_RELOC_THUMB_PCREL_BRANCH12
+ -- : BFD_RELOC_THUMB_PCREL_BRANCH20
+ -- : BFD_RELOC_THUMB_PCREL_BRANCH23
+ -- : BFD_RELOC_THUMB_PCREL_BRANCH25
+ Thumb 7-, 9-, 12-, 20-, 23-, and 25-bit pc-relative branches. The
+ lowest bit must be zero and is not stored in the instruction.
+ Note that the corresponding ELF R_ARM_THM_JUMPnn constant has an
+ "nn" one smaller in all cases. Note further that BRANCH23
+ corresponds to R_ARM_THM_CALL.
+
+ -- : BFD_RELOC_ARM_OFFSET_IMM
+ 12-bit immediate offset, used in ARM-format ldr and str
+ instructions.
+
+ -- : BFD_RELOC_ARM_THUMB_OFFSET
+ 5-bit immediate offset, used in Thumb-format ldr and str
+ instructions.
+
+ -- : BFD_RELOC_ARM_TARGET1
+ Pc-relative or absolute relocation depending on target. Used for
+ entries in .init_array sections.
+
+ -- : BFD_RELOC_ARM_ROSEGREL32
+ Read-only segment base relative address.
+
+ -- : BFD_RELOC_ARM_SBREL32
+ Data segment base relative address.
+
+ -- : BFD_RELOC_ARM_TARGET2
+ This reloc is used for references to RTTI data from exception
+ handling tables. The actual definition depends on the target. It
+ may be a pc-relative or some form of GOT-indirect relocation.
+
+ -- : BFD_RELOC_ARM_PREL31
+ 31-bit PC relative address.
+
+ -- : BFD_RELOC_ARM_MOVW
+ -- : BFD_RELOC_ARM_MOVT
+ -- : BFD_RELOC_ARM_MOVW_PCREL
+ -- : BFD_RELOC_ARM_MOVT_PCREL
+ -- : BFD_RELOC_ARM_THUMB_MOVW
+ -- : BFD_RELOC_ARM_THUMB_MOVT
+ -- : BFD_RELOC_ARM_THUMB_MOVW_PCREL
+ -- : BFD_RELOC_ARM_THUMB_MOVT_PCREL
+ Low and High halfword relocations for MOVW and MOVT instructions.
+
+ -- : BFD_RELOC_ARM_JUMP_SLOT
+ -- : BFD_RELOC_ARM_GLOB_DAT
+ -- : BFD_RELOC_ARM_GOT32
+ -- : BFD_RELOC_ARM_PLT32
+ -- : BFD_RELOC_ARM_RELATIVE
+ -- : BFD_RELOC_ARM_GOTOFF
+ -- : BFD_RELOC_ARM_GOTPC
+ -- : BFD_RELOC_ARM_GOT_PREL
+ Relocations for setting up GOTs and PLTs for shared libraries.
+
+ -- : BFD_RELOC_ARM_TLS_GD32
+ -- : BFD_RELOC_ARM_TLS_LDO32
+ -- : BFD_RELOC_ARM_TLS_LDM32
+ -- : BFD_RELOC_ARM_TLS_DTPOFF32
+ -- : BFD_RELOC_ARM_TLS_DTPMOD32
+ -- : BFD_RELOC_ARM_TLS_TPOFF32
+ -- : BFD_RELOC_ARM_TLS_IE32
+ -- : BFD_RELOC_ARM_TLS_LE32
+ -- : BFD_RELOC_ARM_TLS_GOTDESC
+ -- : BFD_RELOC_ARM_TLS_CALL
+ -- : BFD_RELOC_ARM_THM_TLS_CALL
+ -- : BFD_RELOC_ARM_TLS_DESCSEQ
+ -- : BFD_RELOC_ARM_THM_TLS_DESCSEQ
+ -- : BFD_RELOC_ARM_TLS_DESC
+ ARM thread-local storage relocations.
+
+ -- : BFD_RELOC_ARM_ALU_PC_G0_NC
+ -- : BFD_RELOC_ARM_ALU_PC_G0
+ -- : BFD_RELOC_ARM_ALU_PC_G1_NC
+ -- : BFD_RELOC_ARM_ALU_PC_G1
+ -- : BFD_RELOC_ARM_ALU_PC_G2
+ -- : BFD_RELOC_ARM_LDR_PC_G0
+ -- : BFD_RELOC_ARM_LDR_PC_G1
+ -- : BFD_RELOC_ARM_LDR_PC_G2
+ -- : BFD_RELOC_ARM_LDRS_PC_G0
+ -- : BFD_RELOC_ARM_LDRS_PC_G1
+ -- : BFD_RELOC_ARM_LDRS_PC_G2
+ -- : BFD_RELOC_ARM_LDC_PC_G0
+ -- : BFD_RELOC_ARM_LDC_PC_G1
+ -- : BFD_RELOC_ARM_LDC_PC_G2
+ -- : BFD_RELOC_ARM_ALU_SB_G0_NC
+ -- : BFD_RELOC_ARM_ALU_SB_G0
+ -- : BFD_RELOC_ARM_ALU_SB_G1_NC
+ -- : BFD_RELOC_ARM_ALU_SB_G1
+ -- : BFD_RELOC_ARM_ALU_SB_G2
+ -- : BFD_RELOC_ARM_LDR_SB_G0
+ -- : BFD_RELOC_ARM_LDR_SB_G1
+ -- : BFD_RELOC_ARM_LDR_SB_G2
+ -- : BFD_RELOC_ARM_LDRS_SB_G0
+ -- : BFD_RELOC_ARM_LDRS_SB_G1
+ -- : BFD_RELOC_ARM_LDRS_SB_G2
+ -- : BFD_RELOC_ARM_LDC_SB_G0
+ -- : BFD_RELOC_ARM_LDC_SB_G1
+ -- : BFD_RELOC_ARM_LDC_SB_G2
+ ARM group relocations.
+
+ -- : BFD_RELOC_ARM_V4BX
+ Annotation of BX instructions.
+
+ -- : BFD_RELOC_ARM_IRELATIVE
+ ARM support for STT_GNU_IFUNC.
+
+ -- : BFD_RELOC_ARM_IMMEDIATE
+ -- : BFD_RELOC_ARM_ADRL_IMMEDIATE
+ -- : BFD_RELOC_ARM_T32_IMMEDIATE
+ -- : BFD_RELOC_ARM_T32_ADD_IMM
+ -- : BFD_RELOC_ARM_T32_IMM12
+ -- : BFD_RELOC_ARM_T32_ADD_PC12
+ -- : BFD_RELOC_ARM_SHIFT_IMM
+ -- : BFD_RELOC_ARM_SMC
+ -- : BFD_RELOC_ARM_HVC
+ -- : BFD_RELOC_ARM_SWI
+ -- : BFD_RELOC_ARM_MULTI
+ -- : BFD_RELOC_ARM_CP_OFF_IMM
+ -- : BFD_RELOC_ARM_CP_OFF_IMM_S2
+ -- : BFD_RELOC_ARM_T32_CP_OFF_IMM
+ -- : BFD_RELOC_ARM_T32_CP_OFF_IMM_S2
+ -- : 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_T32_OFFSET_U8
+ -- : BFD_RELOC_ARM_T32_OFFSET_IMM
+ -- : BFD_RELOC_ARM_HWLITERAL
+ -- : BFD_RELOC_ARM_THUMB_ADD
+ -- : BFD_RELOC_ARM_THUMB_IMM
+ -- : BFD_RELOC_ARM_THUMB_SHIFT
+ These relocs are only used within the ARM assembler. They are not
+ (at present) written to any object files.
+
+ -- : BFD_RELOC_SH_PCDISP8BY2
+ -- : BFD_RELOC_SH_PCDISP12BY2
+ -- : BFD_RELOC_SH_IMM3
+ -- : BFD_RELOC_SH_IMM3U
+ -- : BFD_RELOC_SH_DISP12
+ -- : BFD_RELOC_SH_DISP12BY2
+ -- : BFD_RELOC_SH_DISP12BY4
+ -- : BFD_RELOC_SH_DISP12BY8
+ -- : BFD_RELOC_SH_DISP20
+ -- : BFD_RELOC_SH_DISP20BY8
+ -- : 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_SH_LOOP_START
+ -- : BFD_RELOC_SH_LOOP_END
+ -- : BFD_RELOC_SH_COPY
+ -- : BFD_RELOC_SH_GLOB_DAT
+ -- : BFD_RELOC_SH_JMP_SLOT
+ -- : BFD_RELOC_SH_RELATIVE
+ -- : BFD_RELOC_SH_GOTPC
+ -- : BFD_RELOC_SH_GOT_LOW16
+ -- : BFD_RELOC_SH_GOT_MEDLOW16
+ -- : BFD_RELOC_SH_GOT_MEDHI16
+ -- : BFD_RELOC_SH_GOT_HI16
+ -- : BFD_RELOC_SH_GOTPLT_LOW16
+ -- : BFD_RELOC_SH_GOTPLT_MEDLOW16
+ -- : BFD_RELOC_SH_GOTPLT_MEDHI16
+ -- : BFD_RELOC_SH_GOTPLT_HI16
+ -- : BFD_RELOC_SH_PLT_LOW16
+ -- : BFD_RELOC_SH_PLT_MEDLOW16
+ -- : BFD_RELOC_SH_PLT_MEDHI16
+ -- : BFD_RELOC_SH_PLT_HI16
+ -- : BFD_RELOC_SH_GOTOFF_LOW16
+ -- : BFD_RELOC_SH_GOTOFF_MEDLOW16
+ -- : BFD_RELOC_SH_GOTOFF_MEDHI16
+ -- : BFD_RELOC_SH_GOTOFF_HI16
+ -- : BFD_RELOC_SH_GOTPC_LOW16
+ -- : BFD_RELOC_SH_GOTPC_MEDLOW16
+ -- : BFD_RELOC_SH_GOTPC_MEDHI16
+ -- : BFD_RELOC_SH_GOTPC_HI16
+ -- : BFD_RELOC_SH_COPY64
+ -- : BFD_RELOC_SH_GLOB_DAT64
+ -- : BFD_RELOC_SH_JMP_SLOT64
+ -- : BFD_RELOC_SH_RELATIVE64
+ -- : BFD_RELOC_SH_GOT10BY4
+ -- : BFD_RELOC_SH_GOT10BY8
+ -- : BFD_RELOC_SH_GOTPLT10BY4
+ -- : BFD_RELOC_SH_GOTPLT10BY8
+ -- : BFD_RELOC_SH_GOTPLT32
+ -- : BFD_RELOC_SH_SHMEDIA_CODE
+ -- : BFD_RELOC_SH_IMMU5
+ -- : BFD_RELOC_SH_IMMS6
+ -- : BFD_RELOC_SH_IMMS6BY32
+ -- : BFD_RELOC_SH_IMMU6
+ -- : BFD_RELOC_SH_IMMS10
+ -- : BFD_RELOC_SH_IMMS10BY2
+ -- : BFD_RELOC_SH_IMMS10BY4
+ -- : BFD_RELOC_SH_IMMS10BY8
+ -- : BFD_RELOC_SH_IMMS16
+ -- : BFD_RELOC_SH_IMMU16
+ -- : BFD_RELOC_SH_IMM_LOW16
+ -- : BFD_RELOC_SH_IMM_LOW16_PCREL
+ -- : BFD_RELOC_SH_IMM_MEDLOW16
+ -- : BFD_RELOC_SH_IMM_MEDLOW16_PCREL
+ -- : BFD_RELOC_SH_IMM_MEDHI16
+ -- : BFD_RELOC_SH_IMM_MEDHI16_PCREL
+ -- : BFD_RELOC_SH_IMM_HI16
+ -- : BFD_RELOC_SH_IMM_HI16_PCREL
+ -- : BFD_RELOC_SH_PT_16
+ -- : BFD_RELOC_SH_TLS_GD_32
+ -- : BFD_RELOC_SH_TLS_LD_32
+ -- : BFD_RELOC_SH_TLS_LDO_32
+ -- : BFD_RELOC_SH_TLS_IE_32
+ -- : BFD_RELOC_SH_TLS_LE_32
+ -- : BFD_RELOC_SH_TLS_DTPMOD32
+ -- : BFD_RELOC_SH_TLS_DTPOFF32
+ -- : BFD_RELOC_SH_TLS_TPOFF32
+ -- : BFD_RELOC_SH_GOT20
+ -- : BFD_RELOC_SH_GOTOFF20
+ -- : BFD_RELOC_SH_GOTFUNCDESC
+ -- : BFD_RELOC_SH_GOTFUNCDESC20
+ -- : BFD_RELOC_SH_GOTOFFFUNCDESC
+ -- : BFD_RELOC_SH_GOTOFFFUNCDESC20
+ -- : BFD_RELOC_SH_FUNCDESC
+ Renesas / SuperH SH relocs. Not all of these appear in object
+ files.
+
+ -- : BFD_RELOC_ARC_B22_PCREL
+ ARC Cores 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_B26
+ 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_BFIN_16_IMM
+ ADI Blackfin 16 bit immediate absolute reloc.
+
+ -- : BFD_RELOC_BFIN_16_HIGH
+ ADI Blackfin 16 bit immediate absolute reloc higher 16 bits.
+
+ -- : BFD_RELOC_BFIN_4_PCREL
+ ADI Blackfin 'a' part of LSETUP.
+
+ -- : BFD_RELOC_BFIN_5_PCREL
+ ADI Blackfin.
+
+ -- : BFD_RELOC_BFIN_16_LOW
+ ADI Blackfin 16 bit immediate absolute reloc lower 16 bits.
+
+ -- : BFD_RELOC_BFIN_10_PCREL
+ ADI Blackfin.
+
+ -- : BFD_RELOC_BFIN_11_PCREL
+ ADI Blackfin 'b' part of LSETUP.
+
+ -- : BFD_RELOC_BFIN_12_PCREL_JUMP
+ ADI Blackfin.
+
+ -- : BFD_RELOC_BFIN_12_PCREL_JUMP_S
+ ADI Blackfin Short jump, pcrel.
+
+ -- : BFD_RELOC_BFIN_24_PCREL_CALL_X
+ ADI Blackfin Call.x not implemented.
+
+ -- : BFD_RELOC_BFIN_24_PCREL_JUMP_L
+ ADI Blackfin Long Jump pcrel.
+
+ -- : BFD_RELOC_BFIN_GOT17M4
+ -- : BFD_RELOC_BFIN_GOTHI
+ -- : BFD_RELOC_BFIN_GOTLO
+ -- : BFD_RELOC_BFIN_FUNCDESC
+ -- : BFD_RELOC_BFIN_FUNCDESC_GOT17M4
+ -- : BFD_RELOC_BFIN_FUNCDESC_GOTHI
+ -- : BFD_RELOC_BFIN_FUNCDESC_GOTLO
+ -- : BFD_RELOC_BFIN_FUNCDESC_VALUE
+ -- : BFD_RELOC_BFIN_FUNCDESC_GOTOFF17M4
+ -- : BFD_RELOC_BFIN_FUNCDESC_GOTOFFHI
+ -- : BFD_RELOC_BFIN_FUNCDESC_GOTOFFLO
+ -- : BFD_RELOC_BFIN_GOTOFF17M4
+ -- : BFD_RELOC_BFIN_GOTOFFHI
+ -- : BFD_RELOC_BFIN_GOTOFFLO
+ ADI Blackfin FD-PIC relocations.
+
+ -- : BFD_RELOC_BFIN_GOT
+ ADI Blackfin GOT relocation.
+
+ -- : BFD_RELOC_BFIN_PLTPC
+ ADI Blackfin PLTPC relocation.
+
+ -- : BFD_ARELOC_BFIN_PUSH
+ ADI Blackfin arithmetic relocation.
+
+ -- : BFD_ARELOC_BFIN_CONST
+ ADI Blackfin arithmetic relocation.
+
+ -- : BFD_ARELOC_BFIN_ADD
+ ADI Blackfin arithmetic relocation.
+
+ -- : BFD_ARELOC_BFIN_SUB
+ ADI Blackfin arithmetic relocation.
+
+ -- : BFD_ARELOC_BFIN_MULT
+ ADI Blackfin arithmetic relocation.
+
+ -- : BFD_ARELOC_BFIN_DIV
+ ADI Blackfin arithmetic relocation.
+
+ -- : BFD_ARELOC_BFIN_MOD
+ ADI Blackfin arithmetic relocation.
+
+ -- : BFD_ARELOC_BFIN_LSHIFT
+ ADI Blackfin arithmetic relocation.
+
+ -- : BFD_ARELOC_BFIN_RSHIFT
+ ADI Blackfin arithmetic relocation.
+
+ -- : BFD_ARELOC_BFIN_AND
+ ADI Blackfin arithmetic relocation.
+
+ -- : BFD_ARELOC_BFIN_OR
+ ADI Blackfin arithmetic relocation.
+
+ -- : BFD_ARELOC_BFIN_XOR
+ ADI Blackfin arithmetic relocation.
+
+ -- : BFD_ARELOC_BFIN_LAND
+ ADI Blackfin arithmetic relocation.
+
+ -- : BFD_ARELOC_BFIN_LOR
+ ADI Blackfin arithmetic relocation.
+
+ -- : BFD_ARELOC_BFIN_LEN
+ ADI Blackfin arithmetic relocation.
+
+ -- : BFD_ARELOC_BFIN_NEG
+ ADI Blackfin arithmetic relocation.
+
+ -- : BFD_ARELOC_BFIN_COMP
+ ADI Blackfin arithmetic relocation.
+
+ -- : BFD_ARELOC_BFIN_PAGE
+ ADI Blackfin arithmetic relocation.
+
+ -- : BFD_ARELOC_BFIN_HWPAGE
+ ADI Blackfin arithmetic relocation.
+
+ -- : BFD_ARELOC_BFIN_ADDR
+ ADI Blackfin arithmetic relocation.
+
+ -- : BFD_RELOC_D10V_10_PCREL_R
+ Mitsubishi D10V relocs. This is a 10-bit reloc with the right 2
+ bits assumed to be 0.
+
+ -- : BFD_RELOC_D10V_10_PCREL_L
+ 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_18
+ This is an 18-bit reloc with the right 2 bits assumed to be 0.
+
+ -- : BFD_RELOC_D10V_18_PCREL
+ This is an 18-bit reloc with the right 2 bits assumed to be 0.
+
+ -- : BFD_RELOC_D30V_6
+ Mitsubishi D30V relocs. This is a 6-bit absolute reloc.
+
+ -- : BFD_RELOC_D30V_9_PCREL
+ This is a 6-bit pc-relative reloc with the right 3 bits assumed to
+ be 0.
+
+ -- : BFD_RELOC_D30V_9_PCREL_R
+ 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_15
+ This is a 12-bit absolute reloc with the right 3 bitsassumed 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.
+
+ -- : BFD_RELOC_D30V_15_PCREL_R
+ 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_21
+ This is an 18-bit absolute 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.
+
+ -- : BFD_RELOC_D30V_21_PCREL_R
+ 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_32
+ This is a 32-bit absolute reloc.
+
+ -- : BFD_RELOC_D30V_32_PCREL
+ This is a 32-bit pc-relative reloc.
+
+ -- : BFD_RELOC_DLX_HI16_S
+ DLX relocs
+
+ -- : BFD_RELOC_DLX_LO16
+ DLX relocs
+
+ -- : BFD_RELOC_DLX_JMP26
+ DLX relocs
+
+ -- : BFD_RELOC_M32C_HI8
+ -- : BFD_RELOC_M32C_RL_JUMP
+ -- : BFD_RELOC_M32C_RL_1ADDR
+ -- : BFD_RELOC_M32C_RL_2ADDR
+ Renesas M16C/M32C Relocations.
+
+ -- : BFD_RELOC_M32R_24
+ Renesas M32R (formerly Mitsubishi M32R) relocs. This is a 24 bit
+ absolute address.
+
+ -- : BFD_RELOC_M32R_10_PCREL
+ This is a 10-bit pc-relative reloc with the right 2 bits assumed
+ to be 0.
+
+ -- : BFD_RELOC_M32R_18_PCREL
+ This is an 18-bit reloc with the right 2 bits assumed to be 0.
+
+ -- : BFD_RELOC_M32R_26_PCREL
+ This is a 26-bit reloc with the right 2 bits assumed to be 0.
+
+ -- : 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 unsigned.
+
+ -- : BFD_RELOC_M32R_HI16_SLO
+ 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_LO16
+ This is a 16-bit reloc containing the lower 16 bits of an address.
+
+ -- : BFD_RELOC_M32R_SDA16
+ This is a 16-bit reloc containing the small data area offset for
+ use in add3, load, and store instructions.
+
+ -- : BFD_RELOC_M32R_GOT24
+ -- : BFD_RELOC_M32R_26_PLTREL
+ -- : BFD_RELOC_M32R_COPY
+ -- : BFD_RELOC_M32R_GLOB_DAT
+ -- : BFD_RELOC_M32R_JMP_SLOT
+ -- : BFD_RELOC_M32R_RELATIVE
+ -- : BFD_RELOC_M32R_GOTOFF
+ -- : BFD_RELOC_M32R_GOTOFF_HI_ULO
+ -- : BFD_RELOC_M32R_GOTOFF_HI_SLO
+ -- : BFD_RELOC_M32R_GOTOFF_LO
+ -- : BFD_RELOC_M32R_GOTPC24
+ -- : BFD_RELOC_M32R_GOT16_HI_ULO
+ -- : BFD_RELOC_M32R_GOT16_HI_SLO
+ -- : BFD_RELOC_M32R_GOT16_LO
+ -- : BFD_RELOC_M32R_GOTPC_HI_ULO
+ -- : BFD_RELOC_M32R_GOTPC_HI_SLO
+ -- : BFD_RELOC_M32R_GOTPC_LO
+ For PIC.
+
+ -- : BFD_RELOC_NDS32_20
+ NDS32 relocs. This is a 20 bit absolute address.
+
+ -- : BFD_RELOC_NDS32_9_PCREL
+ This is a 9-bit pc-relative reloc with the right 1 bit assumed to
+ be 0.
+
+ -- : BFD_RELOC_NDS32_WORD_9_PCREL
+ This is a 9-bit pc-relative reloc with the right 1 bit assumed to
+ be 0.
+
+ -- : BFD_RELOC_NDS32_15_PCREL
+ This is an 15-bit reloc with the right 1 bit assumed to be 0.
+
+ -- : BFD_RELOC_NDS32_17_PCREL
+ This is an 17-bit reloc with the right 1 bit assumed to be 0.
+
+ -- : BFD_RELOC_NDS32_25_PCREL
+ This is a 25-bit reloc with the right 1 bit assumed to be 0.
+
+ -- : BFD_RELOC_NDS32_HI20
+ This is a 20-bit reloc containing the high 20 bits of an address
+ used with the lower 12 bits
+
+ -- : BFD_RELOC_NDS32_LO12S3
+ This is a 12-bit reloc containing the lower 12 bits of an address
+ then shift right by 3. This is used with ldi,sdi...
+
+ -- : BFD_RELOC_NDS32_LO12S2
+ This is a 12-bit reloc containing the lower 12 bits of an address
+ then shift left by 2. This is used with lwi,swi...
+
+ -- : BFD_RELOC_NDS32_LO12S1
+ This is a 12-bit reloc containing the lower 12 bits of an address
+ then shift left by 1. This is used with lhi,shi...
+
+ -- : BFD_RELOC_NDS32_LO12S0
+ This is a 12-bit reloc containing the lower 12 bits of an address
+ then shift left by 0. This is used with lbisbi...
+
+ -- : BFD_RELOC_NDS32_LO12S0_ORI
+ This is a 12-bit reloc containing the lower 12 bits of an address
+ then shift left by 0. This is only used with branch relaxations
+
+ -- : BFD_RELOC_NDS32_SDA15S3
+ This is a 15-bit reloc containing the small data area 18-bit
+ signed offset and shift left by 3 for use in ldi, sdi...
+
+ -- : BFD_RELOC_NDS32_SDA15S2
+ This is a 15-bit reloc containing the small data area 17-bit
+ signed offset and shift left by 2 for use in lwi, swi...
+
+ -- : BFD_RELOC_NDS32_SDA15S1
+ This is a 15-bit reloc containing the small data area 16-bit
+ signed offset and shift left by 1 for use in lhi, shi...
+
+ -- : BFD_RELOC_NDS32_SDA15S0
+ This is a 15-bit reloc containing the small data area 15-bit
+ signed offset and shift left by 0 for use in lbi, sbi...
+
+ -- : BFD_RELOC_NDS32_SDA16S3
+ This is a 16-bit reloc containing the small data area 16-bit
+ signed offset and shift left by 3
+
+ -- : BFD_RELOC_NDS32_SDA17S2
+ This is a 17-bit reloc containing the small data area 17-bit
+ signed offset and shift left by 2 for use in lwi.gp, swi.gp...
+
+ -- : BFD_RELOC_NDS32_SDA18S1
+ This is a 18-bit reloc containing the small data area 18-bit
+ signed offset and shift left by 1 for use in lhi.gp, shi.gp...
+
+ -- : BFD_RELOC_NDS32_SDA19S0
+ This is a 19-bit reloc containing the small data area 19-bit
+ signed offset and shift left by 0 for use in lbi.gp, sbi.gp...
+
+ -- : BFD_RELOC_NDS32_GOT20
+ -- : BFD_RELOC_NDS32_9_PLTREL
+ -- : BFD_RELOC_NDS32_25_PLTREL
+ -- : BFD_RELOC_NDS32_COPY
+ -- : BFD_RELOC_NDS32_GLOB_DAT
+ -- : BFD_RELOC_NDS32_JMP_SLOT
+ -- : BFD_RELOC_NDS32_RELATIVE
+ -- : BFD_RELOC_NDS32_GOTOFF
+ -- : BFD_RELOC_NDS32_GOTOFF_HI20
+ -- : BFD_RELOC_NDS32_GOTOFF_LO12
+ -- : BFD_RELOC_NDS32_GOTPC20
+ -- : BFD_RELOC_NDS32_GOT_HI20
+ -- : BFD_RELOC_NDS32_GOT_LO12
+ -- : BFD_RELOC_NDS32_GOTPC_HI20
+ -- : BFD_RELOC_NDS32_GOTPC_LO12
+ for PIC
+
+ -- : BFD_RELOC_NDS32_INSN16
+ -- : BFD_RELOC_NDS32_LABEL
+ -- : BFD_RELOC_NDS32_LONGCALL1
+ -- : BFD_RELOC_NDS32_LONGCALL2
+ -- : BFD_RELOC_NDS32_LONGCALL3
+ -- : BFD_RELOC_NDS32_LONGJUMP1
+ -- : BFD_RELOC_NDS32_LONGJUMP2
+ -- : BFD_RELOC_NDS32_LONGJUMP3
+ -- : BFD_RELOC_NDS32_LOADSTORE
+ -- : BFD_RELOC_NDS32_9_FIXED
+ -- : BFD_RELOC_NDS32_15_FIXED
+ -- : BFD_RELOC_NDS32_17_FIXED
+ -- : BFD_RELOC_NDS32_25_FIXED
+ -- : BFD_RELOC_NDS32_LONGCALL4
+ -- : BFD_RELOC_NDS32_LONGCALL5
+ -- : BFD_RELOC_NDS32_LONGCALL6
+ -- : BFD_RELOC_NDS32_LONGJUMP4
+ -- : BFD_RELOC_NDS32_LONGJUMP5
+ -- : BFD_RELOC_NDS32_LONGJUMP6
+ -- : BFD_RELOC_NDS32_LONGJUMP7
+ for relax
+
+ -- : BFD_RELOC_NDS32_PLTREL_HI20
+ -- : BFD_RELOC_NDS32_PLTREL_LO12
+ -- : BFD_RELOC_NDS32_PLT_GOTREL_HI20
+ -- : BFD_RELOC_NDS32_PLT_GOTREL_LO12
+ for PIC
+
+ -- : BFD_RELOC_NDS32_SDA12S2_DP
+ -- : BFD_RELOC_NDS32_SDA12S2_SP
+ -- : BFD_RELOC_NDS32_LO12S2_DP
+ -- : BFD_RELOC_NDS32_LO12S2_SP
+ for floating point
+
+ -- : BFD_RELOC_NDS32_DWARF2_OP1
+ -- : BFD_RELOC_NDS32_DWARF2_OP2
+ -- : BFD_RELOC_NDS32_DWARF2_LEB
+ for dwarf2 debug_line.
+
+ -- : BFD_RELOC_NDS32_UPDATE_TA
+ for eliminate 16-bit instructions
+
+ -- : BFD_RELOC_NDS32_PLT_GOTREL_LO20
+ -- : BFD_RELOC_NDS32_PLT_GOTREL_LO15
+ -- : BFD_RELOC_NDS32_PLT_GOTREL_LO19
+ -- : BFD_RELOC_NDS32_GOT_LO15
+ -- : BFD_RELOC_NDS32_GOT_LO19
+ -- : BFD_RELOC_NDS32_GOTOFF_LO15
+ -- : BFD_RELOC_NDS32_GOTOFF_LO19
+ -- : BFD_RELOC_NDS32_GOT15S2
+ -- : BFD_RELOC_NDS32_GOT17S2
+ for PIC object relaxation
+
+ -- : BFD_RELOC_NDS32_5
+ NDS32 relocs. This is a 5 bit absolute address.
+
+ -- : BFD_RELOC_NDS32_10_UPCREL
+ This is a 10-bit unsigned pc-relative reloc with the right 1 bit
+ assumed to be 0.
+
+ -- : BFD_RELOC_NDS32_SDA_FP7U2_RELA
+ If fp were omitted, fp can used as another gp.
+
+ -- : BFD_RELOC_NDS32_RELAX_ENTRY
+ -- : BFD_RELOC_NDS32_GOT_SUFF
+ -- : BFD_RELOC_NDS32_GOTOFF_SUFF
+ -- : BFD_RELOC_NDS32_PLT_GOT_SUFF
+ -- : BFD_RELOC_NDS32_MULCALL_SUFF
+ -- : BFD_RELOC_NDS32_PTR
+ -- : BFD_RELOC_NDS32_PTR_COUNT
+ -- : BFD_RELOC_NDS32_PTR_RESOLVED
+ -- : BFD_RELOC_NDS32_PLTBLOCK
+ -- : BFD_RELOC_NDS32_RELAX_REGION_BEGIN
+ -- : BFD_RELOC_NDS32_RELAX_REGION_END
+ -- : BFD_RELOC_NDS32_MINUEND
+ -- : BFD_RELOC_NDS32_SUBTRAHEND
+ -- : BFD_RELOC_NDS32_DIFF8
+ -- : BFD_RELOC_NDS32_DIFF16
+ -- : BFD_RELOC_NDS32_DIFF32
+ -- : BFD_RELOC_NDS32_DIFF_ULEB128
+ -- : BFD_RELOC_NDS32_EMPTY
+ relaxation relative relocation types
+
+ -- : BFD_RELOC_NDS32_25_ABS
+ This is a 25 bit absolute address.
+
+ -- : BFD_RELOC_NDS32_DATA
+ -- : BFD_RELOC_NDS32_TRAN
+ -- : BFD_RELOC_NDS32_17IFC_PCREL
+ -- : BFD_RELOC_NDS32_10IFCU_PCREL
+ For ex9 and ifc using.
+
+ -- : BFD_RELOC_NDS32_TPOFF
+ -- : BFD_RELOC_NDS32_TLS_LE_HI20
+ -- : BFD_RELOC_NDS32_TLS_LE_LO12
+ -- : BFD_RELOC_NDS32_TLS_LE_ADD
+ -- : BFD_RELOC_NDS32_TLS_LE_LS
+ -- : BFD_RELOC_NDS32_GOTTPOFF
+ -- : BFD_RELOC_NDS32_TLS_IE_HI20
+ -- : BFD_RELOC_NDS32_TLS_IE_LO12S2
+ -- : BFD_RELOC_NDS32_TLS_TPOFF
+ -- : BFD_RELOC_NDS32_TLS_LE_20
+ -- : BFD_RELOC_NDS32_TLS_LE_15S0
+ -- : BFD_RELOC_NDS32_TLS_LE_15S1
+ -- : BFD_RELOC_NDS32_TLS_LE_15S2
+ For TLS.
+
+ -- : BFD_RELOC_V850_9_PCREL
+ This is a 9-bit reloc
+
+ -- : BFD_RELOC_V850_22_PCREL
+ This is a 22-bit reloc
+
+ -- : BFD_RELOC_V850_SDA_16_16_OFFSET
+ This is a 16 bit offset from the short data area pointer.
+
+ -- : BFD_RELOC_V850_SDA_15_16_OFFSET
+ This is a 16 bit offset (of which only 15 bits are used) from the
+ short data area pointer.
+
+ -- : BFD_RELOC_V850_ZDA_16_16_OFFSET
+ This is a 16 bit offset from the zero data area pointer.
+
+ -- : BFD_RELOC_V850_ZDA_15_16_OFFSET
+ This is a 16 bit offset (of which only 15 bits are used) from the
+ zero data area pointer.
+
+ -- : BFD_RELOC_V850_TDA_6_8_OFFSET
+ This is an 8 bit offset (of which only 6 bits are used) from the
+ tiny data area pointer.
+
+ -- : BFD_RELOC_V850_TDA_7_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_7_OFFSET
+ This is a 7 bit offset from the tiny data area pointer.
+
+ -- : BFD_RELOC_V850_TDA_16_16_OFFSET
+ This is a 16 bit offset from the tiny data area pointer.
+
+ -- : BFD_RELOC_V850_TDA_4_5_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_4_OFFSET
+ This is a 4 bit offset from the tiny data area pointer.
+
+ -- : BFD_RELOC_V850_SDA_16_16_SPLIT_OFFSET
+ This is a 16 bit offset from the short data area pointer, with the
+ bits placed non-contiguously in the instruction.
+
+ -- : BFD_RELOC_V850_ZDA_16_16_SPLIT_OFFSET
+ This is a 16 bit offset from the zero data area pointer, with the
+ bits placed non-contiguously in the instruction.
+
+ -- : BFD_RELOC_V850_CALLT_6_7_OFFSET
+ This is a 6 bit offset from the call table base pointer.
+
+ -- : BFD_RELOC_V850_CALLT_16_16_OFFSET
+ This is a 16 bit offset from the call table base pointer.
+
+ -- : BFD_RELOC_V850_LONGCALL
+ Used for relaxing indirect function calls.
+
+ -- : BFD_RELOC_V850_LONGJUMP
+ Used for relaxing indirect jumps.
+
+ -- : BFD_RELOC_V850_ALIGN
+ Used to maintain alignment whilst relaxing.
+
+ -- : BFD_RELOC_V850_LO16_SPLIT_OFFSET
+ This is a variation of BFD_RELOC_LO16 that can be used in v850e
+ ld.bu instructions.
+
+ -- : BFD_RELOC_V850_16_PCREL
+ This is a 16-bit reloc.
+
+ -- : BFD_RELOC_V850_17_PCREL
+ This is a 17-bit reloc.
+
+ -- : BFD_RELOC_V850_23
+ This is a 23-bit reloc.
+
+ -- : BFD_RELOC_V850_32_PCREL
+ This is a 32-bit reloc.
+
+ -- : BFD_RELOC_V850_32_ABS
+ This is a 32-bit reloc.
+
+ -- : BFD_RELOC_V850_16_SPLIT_OFFSET
+ This is a 16-bit reloc.
+
+ -- : BFD_RELOC_V850_16_S1
+ This is a 16-bit reloc.
+
+ -- : BFD_RELOC_V850_LO16_S1
+ Low 16 bits. 16 bit shifted by 1.
+
+ -- : BFD_RELOC_V850_CALLT_15_16_OFFSET
+ This is a 16 bit offset from the call table base pointer.
+
+ -- : BFD_RELOC_V850_32_GOTPCREL
+ DSO relocations.
+
+ -- : BFD_RELOC_V850_16_GOT
+ DSO relocations.
+
+ -- : BFD_RELOC_V850_32_GOT
+ DSO relocations.
+
+ -- : BFD_RELOC_V850_22_PLT_PCREL
+ DSO relocations.
+
+ -- : BFD_RELOC_V850_32_PLT_PCREL
+ DSO relocations.
+
+ -- : BFD_RELOC_V850_COPY
+ DSO relocations.
+
+ -- : BFD_RELOC_V850_GLOB_DAT
+ DSO relocations.
+
+ -- : BFD_RELOC_V850_JMP_SLOT
+ DSO relocations.
+
+ -- : BFD_RELOC_V850_RELATIVE
+ DSO relocations.
+
+ -- : BFD_RELOC_V850_16_GOTOFF
+ DSO relocations.
+
+ -- : BFD_RELOC_V850_32_GOTOFF
+ DSO relocations.
+
+ -- : BFD_RELOC_V850_CODE
+ start code.
+
+ -- : BFD_RELOC_V850_DATA
+ start data in text.
+
+ -- : BFD_RELOC_TIC30_LDP
+ 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_TIC54X_PARTLS7
+ This is a 7bit reloc for the tms320c54x, where the least
+ significant 7 bits of a 16 bit word are placed into the least
+ significant 7 bits of the opcode.
+
+ -- : BFD_RELOC_TIC54X_PARTMS9
+ This is a 9bit DP reloc for the tms320c54x, where the most
+ significant 9 bits of a 16 bit word are placed into the least
+ significant 9 bits of the opcode.
+
+ -- : BFD_RELOC_TIC54X_23
+ This is an extended address 23-bit reloc for the tms320c54x.
+
+ -- : BFD_RELOC_TIC54X_16_OF_23
+ This is a 16-bit reloc for the tms320c54x, where the least
+ significant 16 bits of a 23-bit extended address are placed into
+ the opcode.
+
+ -- : BFD_RELOC_TIC54X_MS7_OF_23
+ This is a reloc for the tms320c54x, where the most significant 7
+ bits of a 23-bit extended address are placed into the opcode.
+
+ -- : BFD_RELOC_C6000_PCR_S21
+ -- : BFD_RELOC_C6000_PCR_S12
+ -- : BFD_RELOC_C6000_PCR_S10
+ -- : BFD_RELOC_C6000_PCR_S7
+ -- : BFD_RELOC_C6000_ABS_S16
+ -- : BFD_RELOC_C6000_ABS_L16
+ -- : BFD_RELOC_C6000_ABS_H16
+ -- : BFD_RELOC_C6000_SBR_U15_B
+ -- : BFD_RELOC_C6000_SBR_U15_H
+ -- : BFD_RELOC_C6000_SBR_U15_W
+ -- : BFD_RELOC_C6000_SBR_S16
+ -- : BFD_RELOC_C6000_SBR_L16_B
+ -- : BFD_RELOC_C6000_SBR_L16_H
+ -- : BFD_RELOC_C6000_SBR_L16_W
+ -- : BFD_RELOC_C6000_SBR_H16_B
+ -- : BFD_RELOC_C6000_SBR_H16_H
+ -- : BFD_RELOC_C6000_SBR_H16_W
+ -- : BFD_RELOC_C6000_SBR_GOT_U15_W
+ -- : BFD_RELOC_C6000_SBR_GOT_L16_W
+ -- : BFD_RELOC_C6000_SBR_GOT_H16_W
+ -- : BFD_RELOC_C6000_DSBT_INDEX
+ -- : BFD_RELOC_C6000_PREL31
+ -- : BFD_RELOC_C6000_COPY
+ -- : BFD_RELOC_C6000_JUMP_SLOT
+ -- : BFD_RELOC_C6000_EHTYPE
+ -- : BFD_RELOC_C6000_PCR_H16
+ -- : BFD_RELOC_C6000_PCR_L16
+ -- : BFD_RELOC_C6000_ALIGN
+ -- : BFD_RELOC_C6000_FPHEAD
+ -- : BFD_RELOC_C6000_NOCMP
+ TMS320C6000 relocations.
+
+ -- : BFD_RELOC_FR30_48
+ This is a 48 bit reloc for the FR30 that stores 32 bits.
+
+ -- : BFD_RELOC_FR30_20
+ This is a 32 bit reloc for the FR30 that stores 20 bits split up
+ into two sections.
+
+ -- : BFD_RELOC_FR30_6_IN_4
+ This is a 16 bit reloc for the FR30 that stores a 6 bit word
+ offset in 4 bits.
+
+ -- : BFD_RELOC_FR30_8_IN_8
+ This is a 16 bit reloc for the FR30 that stores an 8 bit byte
+ offset into 8 bits.
+
+ -- : BFD_RELOC_FR30_9_IN_8
+ This is a 16 bit reloc for the FR30 that stores a 9 bit short
+ offset into 8 bits.
+
+ -- : BFD_RELOC_FR30_10_IN_8
+ This is a 16 bit reloc for the FR30 that stores a 10 bit word
+ offset into 8 bits.
+
+ -- : BFD_RELOC_FR30_9_PCREL
+ This is a 16 bit reloc for the FR30 that stores a 9 bit pc relative
+ short offset into 8 bits.
+
+ -- : BFD_RELOC_FR30_12_PCREL
+ This is a 16 bit reloc for the FR30 that stores a 12 bit pc
+ relative short offset into 11 bits.
+
+ -- : 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_MCORE_RVA
+ Motorola Mcore relocations.
+
+ -- : BFD_RELOC_MEP_8
+ -- : BFD_RELOC_MEP_16
+ -- : BFD_RELOC_MEP_32
+ -- : BFD_RELOC_MEP_PCREL8A2
+ -- : BFD_RELOC_MEP_PCREL12A2
+ -- : BFD_RELOC_MEP_PCREL17A2
+ -- : BFD_RELOC_MEP_PCREL24A2
+ -- : BFD_RELOC_MEP_PCABS24A2
+ -- : BFD_RELOC_MEP_LOW16
+ -- : BFD_RELOC_MEP_HI16U
+ -- : BFD_RELOC_MEP_HI16S
+ -- : BFD_RELOC_MEP_GPREL
+ -- : BFD_RELOC_MEP_TPREL
+ -- : BFD_RELOC_MEP_TPREL7
+ -- : BFD_RELOC_MEP_TPREL7A2
+ -- : BFD_RELOC_MEP_TPREL7A4
+ -- : BFD_RELOC_MEP_UIMM24
+ -- : BFD_RELOC_MEP_ADDR24A4
+ -- : BFD_RELOC_MEP_GNU_VTINHERIT
+ -- : BFD_RELOC_MEP_GNU_VTENTRY
+ Toshiba Media Processor Relocations.
+
+ -- : BFD_RELOC_METAG_HIADDR16
+ -- : BFD_RELOC_METAG_LOADDR16
+ -- : BFD_RELOC_METAG_RELBRANCH
+ -- : BFD_RELOC_METAG_GETSETOFF
+ -- : BFD_RELOC_METAG_HIOG
+ -- : BFD_RELOC_METAG_LOOG
+ -- : BFD_RELOC_METAG_REL8
+ -- : BFD_RELOC_METAG_REL16
+ -- : BFD_RELOC_METAG_HI16_GOTOFF
+ -- : BFD_RELOC_METAG_LO16_GOTOFF
+ -- : BFD_RELOC_METAG_GETSET_GOTOFF
+ -- : BFD_RELOC_METAG_GETSET_GOT
+ -- : BFD_RELOC_METAG_HI16_GOTPC
+ -- : BFD_RELOC_METAG_LO16_GOTPC
+ -- : BFD_RELOC_METAG_HI16_PLT
+ -- : BFD_RELOC_METAG_LO16_PLT
+ -- : BFD_RELOC_METAG_RELBRANCH_PLT
+ -- : BFD_RELOC_METAG_GOTOFF
+ -- : BFD_RELOC_METAG_PLT
+ -- : BFD_RELOC_METAG_COPY
+ -- : BFD_RELOC_METAG_JMP_SLOT
+ -- : BFD_RELOC_METAG_RELATIVE
+ -- : BFD_RELOC_METAG_GLOB_DAT
+ -- : BFD_RELOC_METAG_TLS_GD
+ -- : BFD_RELOC_METAG_TLS_LDM
+ -- : BFD_RELOC_METAG_TLS_LDO_HI16
+ -- : BFD_RELOC_METAG_TLS_LDO_LO16
+ -- : BFD_RELOC_METAG_TLS_LDO
+ -- : BFD_RELOC_METAG_TLS_IE
+ -- : BFD_RELOC_METAG_TLS_IENONPIC
+ -- : BFD_RELOC_METAG_TLS_IENONPIC_HI16
+ -- : BFD_RELOC_METAG_TLS_IENONPIC_LO16
+ -- : BFD_RELOC_METAG_TLS_TPOFF
+ -- : BFD_RELOC_METAG_TLS_DTPMOD
+ -- : BFD_RELOC_METAG_TLS_DTPOFF
+ -- : BFD_RELOC_METAG_TLS_LE
+ -- : BFD_RELOC_METAG_TLS_LE_HI16
+ -- : BFD_RELOC_METAG_TLS_LE_LO16
+ Imagination Technologies Meta relocations.
+
+ -- : BFD_RELOC_MMIX_GETA
+ -- : BFD_RELOC_MMIX_GETA_1
+ -- : BFD_RELOC_MMIX_GETA_2
+ -- : BFD_RELOC_MMIX_GETA_3
+ These are relocations for the GETA instruction.
+
+ -- : BFD_RELOC_MMIX_CBRANCH
+ -- : BFD_RELOC_MMIX_CBRANCH_J
+ -- : BFD_RELOC_MMIX_CBRANCH_1
+ -- : BFD_RELOC_MMIX_CBRANCH_2
+ -- : BFD_RELOC_MMIX_CBRANCH_3
+ These are relocations for a conditional branch instruction.
+
+ -- : BFD_RELOC_MMIX_PUSHJ
+ -- : BFD_RELOC_MMIX_PUSHJ_1
+ -- : BFD_RELOC_MMIX_PUSHJ_2
+ -- : BFD_RELOC_MMIX_PUSHJ_3
+ -- : BFD_RELOC_MMIX_PUSHJ_STUBBABLE
+ These are relocations for the PUSHJ instruction.
+
+ -- : BFD_RELOC_MMIX_JMP
+ -- : BFD_RELOC_MMIX_JMP_1
+ -- : BFD_RELOC_MMIX_JMP_2
+ -- : BFD_RELOC_MMIX_JMP_3
+ These are relocations for the JMP instruction.
+
+ -- : BFD_RELOC_MMIX_ADDR19
+ This is a relocation for a relative address as in a GETA
+ instruction or a branch.
+
+ -- : BFD_RELOC_MMIX_ADDR27
+ This is a relocation for a relative address as in a JMP
+ instruction.
+
+ -- : BFD_RELOC_MMIX_REG_OR_BYTE
+ This is a relocation for an instruction field that may be a general
+ register or a value 0..255.
+
+ -- : BFD_RELOC_MMIX_REG
+ This is a relocation for an instruction field that may be a general
+ register.
+
+ -- : BFD_RELOC_MMIX_BASE_PLUS_OFFSET
+ This is a relocation for two instruction fields holding a register
+ and an offset, the equivalent of the relocation.
+
+ -- : BFD_RELOC_MMIX_LOCAL
+ This relocation is an assertion that the expression is not
+ allocated as a global register. It does not modify contents.
+
+ -- : BFD_RELOC_AVR_7_PCREL
+ This is a 16 bit reloc for the AVR that stores 8 bit pc relative
+ short offset into 7 bits.
+
+ -- : BFD_RELOC_AVR_13_PCREL
+ This is a 16 bit reloc for the AVR that stores 13 bit pc relative
+ short offset into 12 bits.
+
+ -- : BFD_RELOC_AVR_16_PM
+ This is a 16 bit reloc for the AVR that stores 17 bit value
+ (usually program memory address) into 16 bits.
+
+ -- : BFD_RELOC_AVR_LO8_LDI
+ This is a 16 bit reloc for the AVR that stores 8 bit value (usually
+ data memory address) into 8 bit immediate value of LDI insn.
+
+ -- : BFD_RELOC_AVR_HI8_LDI
+ This is a 16 bit reloc for the AVR that stores 8 bit value (high 8
+ bit of data memory address) into 8 bit immediate value of LDI insn.
+
+ -- : BFD_RELOC_AVR_HH8_LDI
+ This is a 16 bit reloc for the AVR that stores 8 bit value (most
+ high 8 bit of program memory address) into 8 bit immediate value
+ of LDI insn.
+
+ -- : BFD_RELOC_AVR_MS8_LDI
+ This is a 16 bit reloc for the AVR that stores 8 bit value (most
+ high 8 bit of 32 bit value) into 8 bit immediate value of LDI insn.
+
+ -- : BFD_RELOC_AVR_LO8_LDI_NEG
+ This is a 16 bit reloc for the AVR that stores negated 8 bit value
+ (usually data memory address) into 8 bit immediate value of SUBI
+ insn.
+
+ -- : BFD_RELOC_AVR_HI8_LDI_NEG
+ This is a 16 bit reloc for the AVR that stores negated 8 bit value
+ (high 8 bit of data memory address) into 8 bit immediate value of
+ SUBI insn.
+
+ -- : BFD_RELOC_AVR_HH8_LDI_NEG
+ This is a 16 bit reloc for the AVR that stores negated 8 bit value
+ (most high 8 bit of program memory address) into 8 bit immediate
+ value of LDI or SUBI insn.
+
+ -- : BFD_RELOC_AVR_MS8_LDI_NEG
+ This is a 16 bit reloc for the AVR that stores negated 8 bit value
+ (msb of 32 bit value) into 8 bit immediate value of LDI insn.
+
+ -- : BFD_RELOC_AVR_LO8_LDI_PM
+ This is a 16 bit reloc for the AVR that stores 8 bit value (usually
+ command address) into 8 bit immediate value of LDI insn.
+
+ -- : BFD_RELOC_AVR_LO8_LDI_GS
+ This is a 16 bit reloc for the AVR that stores 8 bit value
+ (command address) into 8 bit immediate value of LDI insn. If the
+ address is beyond the 128k boundary, the linker inserts a jump
+ stub for this reloc in the lower 128k.
+
+ -- : BFD_RELOC_AVR_HI8_LDI_PM
+ This is a 16 bit reloc for the AVR that stores 8 bit value (high 8
+ bit of command address) into 8 bit immediate value of LDI insn.
+
+ -- : BFD_RELOC_AVR_HI8_LDI_GS
+ This is a 16 bit reloc for the AVR that stores 8 bit value (high 8
+ bit of command address) into 8 bit immediate value of LDI insn.
+ If the address is beyond the 128k boundary, the linker inserts a
+ jump stub for this reloc below 128k.
+
+ -- : BFD_RELOC_AVR_HH8_LDI_PM
+ This is a 16 bit reloc for the AVR that stores 8 bit value (most
+ high 8 bit of command address) into 8 bit immediate value of LDI
+ insn.
+
+ -- : BFD_RELOC_AVR_LO8_LDI_PM_NEG
+ This is a 16 bit reloc for the AVR that stores negated 8 bit value
+ (usually command address) into 8 bit immediate value of SUBI insn.
+
+ -- : BFD_RELOC_AVR_HI8_LDI_PM_NEG
+ This is a 16 bit reloc for the AVR that stores negated 8 bit value
+ (high 8 bit of 16 bit command address) into 8 bit immediate value
+ of SUBI insn.
+
+ -- : BFD_RELOC_AVR_HH8_LDI_PM_NEG
+ This is a 16 bit reloc for the AVR that stores negated 8 bit value
+ (high 6 bit of 22 bit command address) into 8 bit immediate value
+ of SUBI insn.
+
+ -- : BFD_RELOC_AVR_CALL
+ This is a 32 bit reloc for the AVR that stores 23 bit value into
+ 22 bits.
+
+ -- : BFD_RELOC_AVR_LDI
+ This is a 16 bit reloc for the AVR that stores all needed bits for
+ absolute addressing with ldi with overflow check to linktime
+
+ -- : BFD_RELOC_AVR_6
+ This is a 6 bit reloc for the AVR that stores offset for ldd/std
+ instructions
+
+ -- : BFD_RELOC_AVR_6_ADIW
+ This is a 6 bit reloc for the AVR that stores offset for adiw/sbiw
+ instructions
+
+ -- : BFD_RELOC_AVR_8_LO
+ This is a 8 bit reloc for the AVR that stores bits 0..7 of a symbol
+ in .byte lo8(symbol)
+
+ -- : BFD_RELOC_AVR_8_HI
+ This is a 8 bit reloc for the AVR that stores bits 8..15 of a
+ symbol in .byte hi8(symbol)
+
+ -- : BFD_RELOC_AVR_8_HLO
+ This is a 8 bit reloc for the AVR that stores bits 16..23 of a
+ symbol in .byte hlo8(symbol)
+
+ -- : BFD_RELOC_AVR_DIFF8
+ -- : BFD_RELOC_AVR_DIFF16
+ -- : BFD_RELOC_AVR_DIFF32
+ AVR relocations to mark the difference of two local symbols.
+ These are only needed to support linker relaxation and can be
+ ignored when not relaxing. The field is set to the value of the
+ difference assuming no relaxation. The relocation encodes the
+ position of the second symbol so the linker can determine whether
+ to adjust the field value.
+
+ -- : BFD_RELOC_AVR_LDS_STS_16
+ This is a 7 bit reloc for the AVR that stores SRAM address for
+ 16bit lds and sts instructions supported only tiny core.
+
+ -- : BFD_RELOC_AVR_PORT6
+ This is a 6 bit reloc for the AVR that stores an I/O register
+ number for the IN and OUT instructions
+
+ -- : BFD_RELOC_AVR_PORT5
+ This is a 5 bit reloc for the AVR that stores an I/O register
+ number for the SBIC, SBIS, SBI and CBI instructions
+
+ -- : BFD_RELOC_RL78_NEG8
+ -- : BFD_RELOC_RL78_NEG16
+ -- : BFD_RELOC_RL78_NEG24
+ -- : BFD_RELOC_RL78_NEG32
+ -- : BFD_RELOC_RL78_16_OP
+ -- : BFD_RELOC_RL78_24_OP
+ -- : BFD_RELOC_RL78_32_OP
+ -- : BFD_RELOC_RL78_8U
+ -- : BFD_RELOC_RL78_16U
+ -- : BFD_RELOC_RL78_24U
+ -- : BFD_RELOC_RL78_DIR3U_PCREL
+ -- : BFD_RELOC_RL78_DIFF
+ -- : BFD_RELOC_RL78_GPRELB
+ -- : BFD_RELOC_RL78_GPRELW
+ -- : BFD_RELOC_RL78_GPRELL
+ -- : BFD_RELOC_RL78_SYM
+ -- : BFD_RELOC_RL78_OP_SUBTRACT
+ -- : BFD_RELOC_RL78_OP_NEG
+ -- : BFD_RELOC_RL78_OP_AND
+ -- : BFD_RELOC_RL78_OP_SHRA
+ -- : BFD_RELOC_RL78_ABS8
+ -- : BFD_RELOC_RL78_ABS16
+ -- : BFD_RELOC_RL78_ABS16_REV
+ -- : BFD_RELOC_RL78_ABS32
+ -- : BFD_RELOC_RL78_ABS32_REV
+ -- : BFD_RELOC_RL78_ABS16U
+ -- : BFD_RELOC_RL78_ABS16UW
+ -- : BFD_RELOC_RL78_ABS16UL
+ -- : BFD_RELOC_RL78_RELAX
+ -- : BFD_RELOC_RL78_HI16
+ -- : BFD_RELOC_RL78_HI8
+ -- : BFD_RELOC_RL78_LO16
+ -- : BFD_RELOC_RL78_CODE
+ Renesas RL78 Relocations.
+
+ -- : BFD_RELOC_RX_NEG8
+ -- : BFD_RELOC_RX_NEG16
+ -- : BFD_RELOC_RX_NEG24
+ -- : BFD_RELOC_RX_NEG32
+ -- : BFD_RELOC_RX_16_OP
+ -- : BFD_RELOC_RX_24_OP
+ -- : BFD_RELOC_RX_32_OP
+ -- : BFD_RELOC_RX_8U
+ -- : BFD_RELOC_RX_16U
+ -- : BFD_RELOC_RX_24U
+ -- : BFD_RELOC_RX_DIR3U_PCREL
+ -- : BFD_RELOC_RX_DIFF
+ -- : BFD_RELOC_RX_GPRELB
+ -- : BFD_RELOC_RX_GPRELW
+ -- : BFD_RELOC_RX_GPRELL
+ -- : BFD_RELOC_RX_SYM
+ -- : BFD_RELOC_RX_OP_SUBTRACT
+ -- : BFD_RELOC_RX_OP_NEG
+ -- : BFD_RELOC_RX_ABS8
+ -- : BFD_RELOC_RX_ABS16
+ -- : BFD_RELOC_RX_ABS16_REV
+ -- : BFD_RELOC_RX_ABS32
+ -- : BFD_RELOC_RX_ABS32_REV
+ -- : BFD_RELOC_RX_ABS16U
+ -- : BFD_RELOC_RX_ABS16UW
+ -- : BFD_RELOC_RX_ABS16UL
+ -- : BFD_RELOC_RX_RELAX
+ Renesas RX Relocations.
+
+ -- : BFD_RELOC_390_12
+ Direct 12 bit.
+
+ -- : BFD_RELOC_390_GOT12
+ 12 bit GOT offset.
+
+ -- : BFD_RELOC_390_PLT32
+ 32 bit PC relative PLT address.
+
+ -- : BFD_RELOC_390_COPY
+ Copy symbol at runtime.
+
+ -- : BFD_RELOC_390_GLOB_DAT
+ Create GOT entry.
+
+ -- : BFD_RELOC_390_JMP_SLOT
+ Create PLT entry.
+
+ -- : BFD_RELOC_390_RELATIVE
+ Adjust by program base.
+
+ -- : BFD_RELOC_390_GOTPC
+ 32 bit PC relative offset to GOT.
+
+ -- : BFD_RELOC_390_GOT16
+ 16 bit GOT offset.
+
+ -- : BFD_RELOC_390_PC12DBL
+ PC relative 12 bit shifted by 1.
+
+ -- : BFD_RELOC_390_PLT12DBL
+ 12 bit PC rel. PLT shifted by 1.
+
+ -- : BFD_RELOC_390_PC16DBL
+ PC relative 16 bit shifted by 1.
+
+ -- : BFD_RELOC_390_PLT16DBL
+ 16 bit PC rel. PLT shifted by 1.
+
+ -- : BFD_RELOC_390_PC24DBL
+ PC relative 24 bit shifted by 1.
+
+ -- : BFD_RELOC_390_PLT24DBL
+ 24 bit PC rel. PLT shifted by 1.
+
+ -- : BFD_RELOC_390_PC32DBL
+ PC relative 32 bit shifted by 1.
+
+ -- : BFD_RELOC_390_PLT32DBL
+ 32 bit PC rel. PLT shifted by 1.
+
+ -- : BFD_RELOC_390_GOTPCDBL
+ 32 bit PC rel. GOT shifted by 1.
+
+ -- : BFD_RELOC_390_GOT64
+ 64 bit GOT offset.
+
+ -- : BFD_RELOC_390_PLT64
+ 64 bit PC relative PLT address.
+
+ -- : BFD_RELOC_390_GOTENT
+ 32 bit rel. offset to GOT entry.
+
+ -- : BFD_RELOC_390_GOTOFF64
+ 64 bit offset to GOT.
+
+ -- : BFD_RELOC_390_GOTPLT12
+ 12-bit offset to symbol-entry within GOT, with PLT handling.
+
+ -- : BFD_RELOC_390_GOTPLT16
+ 16-bit offset to symbol-entry within GOT, with PLT handling.
+
+ -- : BFD_RELOC_390_GOTPLT32
+ 32-bit offset to symbol-entry within GOT, with PLT handling.
+
+ -- : BFD_RELOC_390_GOTPLT64
+ 64-bit offset to symbol-entry within GOT, with PLT handling.
+
+ -- : BFD_RELOC_390_GOTPLTENT
+ 32-bit rel. offset to symbol-entry within GOT, with PLT handling.
+
+ -- : BFD_RELOC_390_PLTOFF16
+ 16-bit rel. offset from the GOT to a PLT entry.
+
+ -- : BFD_RELOC_390_PLTOFF32
+ 32-bit rel. offset from the GOT to a PLT entry.
+
+ -- : BFD_RELOC_390_PLTOFF64
+ 64-bit rel. offset from the GOT to a PLT entry.
+
+ -- : BFD_RELOC_390_TLS_LOAD
+ -- : BFD_RELOC_390_TLS_GDCALL
+ -- : BFD_RELOC_390_TLS_LDCALL
+ -- : BFD_RELOC_390_TLS_GD32
+ -- : BFD_RELOC_390_TLS_GD64
+ -- : BFD_RELOC_390_TLS_GOTIE12
+ -- : BFD_RELOC_390_TLS_GOTIE32
+ -- : BFD_RELOC_390_TLS_GOTIE64
+ -- : BFD_RELOC_390_TLS_LDM32
+ -- : BFD_RELOC_390_TLS_LDM64
+ -- : BFD_RELOC_390_TLS_IE32
+ -- : BFD_RELOC_390_TLS_IE64
+ -- : BFD_RELOC_390_TLS_IEENT
+ -- : BFD_RELOC_390_TLS_LE32
+ -- : BFD_RELOC_390_TLS_LE64
+ -- : BFD_RELOC_390_TLS_LDO32
+ -- : BFD_RELOC_390_TLS_LDO64
+ -- : BFD_RELOC_390_TLS_DTPMOD
+ -- : BFD_RELOC_390_TLS_DTPOFF
+ -- : BFD_RELOC_390_TLS_TPOFF
+ s390 tls relocations.
+
+ -- : BFD_RELOC_390_20
+ -- : BFD_RELOC_390_GOT20
+ -- : BFD_RELOC_390_GOTPLT20
+ -- : BFD_RELOC_390_TLS_GOTIE20
+ Long displacement extension.
+
+ -- : BFD_RELOC_390_IRELATIVE
+ STT_GNU_IFUNC relocation.
+
+ -- : BFD_RELOC_SCORE_GPREL15
+ Score relocations Low 16 bit for load/store
+
+ -- : BFD_RELOC_SCORE_DUMMY2
+ -- : BFD_RELOC_SCORE_JMP
+ This is a 24-bit reloc with the right 1 bit assumed to be 0
+
+ -- : BFD_RELOC_SCORE_BRANCH
+ This is a 19-bit reloc with the right 1 bit assumed to be 0
+
+ -- : BFD_RELOC_SCORE_IMM30
+ This is a 32-bit reloc for 48-bit instructions.
+
+ -- : BFD_RELOC_SCORE_IMM32
+ This is a 32-bit reloc for 48-bit instructions.
+
+ -- : BFD_RELOC_SCORE16_JMP
+ This is a 11-bit reloc with the right 1 bit assumed to be 0
+
+ -- : BFD_RELOC_SCORE16_BRANCH
+ This is a 8-bit reloc with the right 1 bit assumed to be 0
+
+ -- : BFD_RELOC_SCORE_BCMP
+ This is a 9-bit reloc with the right 1 bit assumed to be 0
+
+ -- : BFD_RELOC_SCORE_GOT15
+ -- : BFD_RELOC_SCORE_GOT_LO16
+ -- : BFD_RELOC_SCORE_CALL15
+ -- : BFD_RELOC_SCORE_DUMMY_HI16
+ Undocumented Score relocs
+
+ -- : BFD_RELOC_IP2K_FR9
+ Scenix IP2K - 9-bit register number / data address
+
+ -- : BFD_RELOC_IP2K_BANK
+ Scenix IP2K - 4-bit register/data bank number
+
+ -- : BFD_RELOC_IP2K_ADDR16CJP
+ Scenix IP2K - low 13 bits of instruction word address
+
+ -- : BFD_RELOC_IP2K_PAGE3
+ Scenix IP2K - high 3 bits of instruction word address
+
+ -- : BFD_RELOC_IP2K_LO8DATA
+ -- : BFD_RELOC_IP2K_HI8DATA
+ -- : BFD_RELOC_IP2K_EX8DATA
+ Scenix IP2K - ext/low/high 8 bits of data address
+
+ -- : BFD_RELOC_IP2K_LO8INSN
+ -- : BFD_RELOC_IP2K_HI8INSN
+ Scenix IP2K - low/high 8 bits of instruction word address
+
+ -- : BFD_RELOC_IP2K_PC_SKIP
+ Scenix IP2K - even/odd PC modifier to modify snb pcl.0
+
+ -- : BFD_RELOC_IP2K_TEXT
+ Scenix IP2K - 16 bit word address in text section.
+
+ -- : BFD_RELOC_IP2K_FR_OFFSET
+ Scenix IP2K - 7-bit sp or dp offset
+
+ -- : BFD_RELOC_VPE4KMATH_DATA
+ -- : BFD_RELOC_VPE4KMATH_INSN
+ Scenix VPE4K coprocessor - data/insn-space addressing
+
+ -- : BFD_RELOC_VTABLE_INHERIT
+ -- : BFD_RELOC_VTABLE_ENTRY
+ 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 inheritance 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_IA64_IMM14
+ -- : BFD_RELOC_IA64_IMM22
+ -- : BFD_RELOC_IA64_IMM64
+ -- : BFD_RELOC_IA64_DIR32MSB
+ -- : BFD_RELOC_IA64_DIR32LSB
+ -- : BFD_RELOC_IA64_DIR64MSB
+ -- : BFD_RELOC_IA64_DIR64LSB
+ -- : BFD_RELOC_IA64_GPREL22
+ -- : BFD_RELOC_IA64_GPREL64I
+ -- : BFD_RELOC_IA64_GPREL32MSB
+ -- : BFD_RELOC_IA64_GPREL32LSB
+ -- : BFD_RELOC_IA64_GPREL64MSB
+ -- : BFD_RELOC_IA64_GPREL64LSB
+ -- : BFD_RELOC_IA64_LTOFF22
+ -- : BFD_RELOC_IA64_LTOFF64I
+ -- : BFD_RELOC_IA64_PLTOFF22
+ -- : BFD_RELOC_IA64_PLTOFF64I
+ -- : BFD_RELOC_IA64_PLTOFF64MSB
+ -- : BFD_RELOC_IA64_PLTOFF64LSB
+ -- : BFD_RELOC_IA64_FPTR64I
+ -- : BFD_RELOC_IA64_FPTR32MSB
+ -- : BFD_RELOC_IA64_FPTR32LSB
+ -- : BFD_RELOC_IA64_FPTR64MSB
+ -- : BFD_RELOC_IA64_FPTR64LSB
+ -- : BFD_RELOC_IA64_PCREL21B
+ -- : BFD_RELOC_IA64_PCREL21BI
+ -- : BFD_RELOC_IA64_PCREL21M
+ -- : BFD_RELOC_IA64_PCREL21F
+ -- : BFD_RELOC_IA64_PCREL22
+ -- : BFD_RELOC_IA64_PCREL60B
+ -- : BFD_RELOC_IA64_PCREL64I
+ -- : BFD_RELOC_IA64_PCREL32MSB
+ -- : BFD_RELOC_IA64_PCREL32LSB
+ -- : BFD_RELOC_IA64_PCREL64MSB
+ -- : BFD_RELOC_IA64_PCREL64LSB
+ -- : BFD_RELOC_IA64_LTOFF_FPTR22
+ -- : BFD_RELOC_IA64_LTOFF_FPTR64I
+ -- : BFD_RELOC_IA64_LTOFF_FPTR32MSB
+ -- : BFD_RELOC_IA64_LTOFF_FPTR32LSB
+ -- : BFD_RELOC_IA64_LTOFF_FPTR64MSB
+ -- : BFD_RELOC_IA64_LTOFF_FPTR64LSB
+ -- : BFD_RELOC_IA64_SEGREL32MSB
+ -- : BFD_RELOC_IA64_SEGREL32LSB
+ -- : BFD_RELOC_IA64_SEGREL64MSB
+ -- : BFD_RELOC_IA64_SEGREL64LSB
+ -- : BFD_RELOC_IA64_SECREL32MSB
+ -- : BFD_RELOC_IA64_SECREL32LSB
+ -- : BFD_RELOC_IA64_SECREL64MSB
+ -- : BFD_RELOC_IA64_SECREL64LSB
+ -- : BFD_RELOC_IA64_REL32MSB
+ -- : BFD_RELOC_IA64_REL32LSB
+ -- : BFD_RELOC_IA64_REL64MSB
+ -- : BFD_RELOC_IA64_REL64LSB
+ -- : BFD_RELOC_IA64_LTV32MSB
+ -- : BFD_RELOC_IA64_LTV32LSB
+ -- : BFD_RELOC_IA64_LTV64MSB
+ -- : BFD_RELOC_IA64_LTV64LSB
+ -- : BFD_RELOC_IA64_IPLTMSB
+ -- : BFD_RELOC_IA64_IPLTLSB
+ -- : BFD_RELOC_IA64_COPY
+ -- : BFD_RELOC_IA64_LTOFF22X
+ -- : BFD_RELOC_IA64_LDXMOV
+ -- : BFD_RELOC_IA64_TPREL14
+ -- : BFD_RELOC_IA64_TPREL22
+ -- : BFD_RELOC_IA64_TPREL64I
+ -- : BFD_RELOC_IA64_TPREL64MSB
+ -- : BFD_RELOC_IA64_TPREL64LSB
+ -- : BFD_RELOC_IA64_LTOFF_TPREL22
+ -- : BFD_RELOC_IA64_DTPMOD64MSB
+ -- : BFD_RELOC_IA64_DTPMOD64LSB
+ -- : BFD_RELOC_IA64_LTOFF_DTPMOD22
+ -- : BFD_RELOC_IA64_DTPREL14
+ -- : BFD_RELOC_IA64_DTPREL22
+ -- : BFD_RELOC_IA64_DTPREL64I
+ -- : BFD_RELOC_IA64_DTPREL32MSB
+ -- : BFD_RELOC_IA64_DTPREL32LSB
+ -- : BFD_RELOC_IA64_DTPREL64MSB
+ -- : BFD_RELOC_IA64_DTPREL64LSB
+ -- : BFD_RELOC_IA64_LTOFF_DTPREL22
+ Intel IA64 Relocations.
+
+ -- : BFD_RELOC_M68HC11_HI8
+ Motorola 68HC11 reloc. This is the 8 bit high part of an absolute
+ address.
+
+ -- : BFD_RELOC_M68HC11_LO8
+ Motorola 68HC11 reloc. This is the 8 bit low part of an absolute
+ address.
+
+ -- : BFD_RELOC_M68HC11_3B
+ Motorola 68HC11 reloc. This is the 3 bit of a value.
+
+ -- : BFD_RELOC_M68HC11_RL_JUMP
+ Motorola 68HC11 reloc. This reloc marks the beginning of a
+ jump/call instruction. It is used for linker relaxation to
+ correctly identify beginning of instruction and change some
+ branches to use PC-relative addressing mode.
+
+ -- : BFD_RELOC_M68HC11_RL_GROUP
+ Motorola 68HC11 reloc. This reloc marks a group of several
+ instructions that gcc generates and for which the linker
+ relaxation pass can modify and/or remove some of them.
+
+ -- : BFD_RELOC_M68HC11_LO16
+ Motorola 68HC11 reloc. This is the 16-bit lower part of an
+ address. It is used for 'call' instruction to specify the symbol
+ address without any special transformation (due to memory bank
+ window).
+
+ -- : BFD_RELOC_M68HC11_PAGE
+ Motorola 68HC11 reloc. This is a 8-bit reloc that specifies the
+ page number of an address. It is used by 'call' instruction to
+ specify the page number of the symbol.
+
+ -- : BFD_RELOC_M68HC11_24
+ Motorola 68HC11 reloc. This is a 24-bit reloc that represents the
+ address with a 16-bit value and a 8-bit page number. The symbol
+ address is transformed to follow the 16K memory bank of 68HC12
+ (seen as mapped in the window).
+
+ -- : BFD_RELOC_M68HC12_5B
+ Motorola 68HC12 reloc. This is the 5 bits of a value.
+
+ -- : BFD_RELOC_XGATE_RL_JUMP
+ Freescale XGATE reloc. This reloc marks the beginning of a
+ bra/jal instruction.
+
+ -- : BFD_RELOC_XGATE_RL_GROUP
+ Freescale XGATE reloc. This reloc marks a group of several
+ instructions that gcc generates and for which the linker
+ relaxation pass can modify and/or remove some of them.
+
+ -- : BFD_RELOC_XGATE_LO16
+ Freescale XGATE reloc. This is the 16-bit lower part of an
+ address. It is used for the '16-bit' instructions.
+
+ -- : BFD_RELOC_XGATE_GPAGE
+ Freescale XGATE reloc.
+
+ -- : BFD_RELOC_XGATE_24
+ Freescale XGATE reloc.
+
+ -- : BFD_RELOC_XGATE_PCREL_9
+ Freescale XGATE reloc. This is a 9-bit pc-relative reloc.
+
+ -- : BFD_RELOC_XGATE_PCREL_10
+ Freescale XGATE reloc. This is a 10-bit pc-relative reloc.
+
+ -- : BFD_RELOC_XGATE_IMM8_LO
+ Freescale XGATE reloc. This is the 16-bit lower part of an
+ address. It is used for the '16-bit' instructions.
+
+ -- : BFD_RELOC_XGATE_IMM8_HI
+ Freescale XGATE reloc. This is the 16-bit higher part of an
+ address. It is used for the '16-bit' instructions.
+
+ -- : BFD_RELOC_XGATE_IMM3
+ Freescale XGATE reloc. This is a 3-bit pc-relative reloc.
+
+ -- : BFD_RELOC_XGATE_IMM4
+ Freescale XGATE reloc. This is a 4-bit pc-relative reloc.
+
+ -- : BFD_RELOC_XGATE_IMM5
+ Freescale XGATE reloc. This is a 5-bit pc-relative reloc.
+
+ -- : BFD_RELOC_M68HC12_9B
+ Motorola 68HC12 reloc. This is the 9 bits of a value.
+
+ -- : BFD_RELOC_M68HC12_16B
+ Motorola 68HC12 reloc. This is the 16 bits of a value.
+
+ -- : BFD_RELOC_M68HC12_9_PCREL
+ Motorola 68HC12/XGATE reloc. This is a PCREL9 branch.
+
+ -- : BFD_RELOC_M68HC12_10_PCREL
+ Motorola 68HC12/XGATE reloc. This is a PCREL10 branch.
+
+ -- : BFD_RELOC_M68HC12_LO8XG
+ Motorola 68HC12/XGATE reloc. This is the 8 bit low part of an
+ absolute address and immediately precedes a matching HI8XG part.
+
+ -- : BFD_RELOC_M68HC12_HI8XG
+ Motorola 68HC12/XGATE reloc. This is the 8 bit high part of an
+ absolute address and immediately follows a matching LO8XG part.
+
+ -- : BFD_RELOC_16C_NUM08
+ -- : BFD_RELOC_16C_NUM08_C
+ -- : BFD_RELOC_16C_NUM16
+ -- : BFD_RELOC_16C_NUM16_C
+ -- : BFD_RELOC_16C_NUM32
+ -- : BFD_RELOC_16C_NUM32_C
+ -- : BFD_RELOC_16C_DISP04
+ -- : BFD_RELOC_16C_DISP04_C
+ -- : BFD_RELOC_16C_DISP08
+ -- : BFD_RELOC_16C_DISP08_C
+ -- : BFD_RELOC_16C_DISP16
+ -- : BFD_RELOC_16C_DISP16_C
+ -- : BFD_RELOC_16C_DISP24
+ -- : BFD_RELOC_16C_DISP24_C
+ -- : BFD_RELOC_16C_DISP24a
+ -- : BFD_RELOC_16C_DISP24a_C
+ -- : BFD_RELOC_16C_REG04
+ -- : BFD_RELOC_16C_REG04_C
+ -- : BFD_RELOC_16C_REG04a
+ -- : BFD_RELOC_16C_REG04a_C
+ -- : BFD_RELOC_16C_REG14
+ -- : BFD_RELOC_16C_REG14_C
+ -- : BFD_RELOC_16C_REG16
+ -- : BFD_RELOC_16C_REG16_C
+ -- : BFD_RELOC_16C_REG20
+ -- : BFD_RELOC_16C_REG20_C
+ -- : BFD_RELOC_16C_ABS20
+ -- : BFD_RELOC_16C_ABS20_C
+ -- : BFD_RELOC_16C_ABS24
+ -- : BFD_RELOC_16C_ABS24_C
+ -- : BFD_RELOC_16C_IMM04
+ -- : BFD_RELOC_16C_IMM04_C
+ -- : BFD_RELOC_16C_IMM16
+ -- : BFD_RELOC_16C_IMM16_C
+ -- : BFD_RELOC_16C_IMM20
+ -- : BFD_RELOC_16C_IMM20_C
+ -- : BFD_RELOC_16C_IMM24
+ -- : BFD_RELOC_16C_IMM24_C
+ -- : BFD_RELOC_16C_IMM32
+ -- : BFD_RELOC_16C_IMM32_C
+ NS CR16C Relocations.
+
+ -- : BFD_RELOC_CR16_NUM8
+ -- : BFD_RELOC_CR16_NUM16
+ -- : BFD_RELOC_CR16_NUM32
+ -- : BFD_RELOC_CR16_NUM32a
+ -- : BFD_RELOC_CR16_REGREL0
+ -- : BFD_RELOC_CR16_REGREL4
+ -- : BFD_RELOC_CR16_REGREL4a
+ -- : BFD_RELOC_CR16_REGREL14
+ -- : BFD_RELOC_CR16_REGREL14a
+ -- : BFD_RELOC_CR16_REGREL16
+ -- : BFD_RELOC_CR16_REGREL20
+ -- : BFD_RELOC_CR16_REGREL20a
+ -- : BFD_RELOC_CR16_ABS20
+ -- : BFD_RELOC_CR16_ABS24
+ -- : BFD_RELOC_CR16_IMM4
+ -- : BFD_RELOC_CR16_IMM8
+ -- : BFD_RELOC_CR16_IMM16
+ -- : BFD_RELOC_CR16_IMM20
+ -- : BFD_RELOC_CR16_IMM24
+ -- : BFD_RELOC_CR16_IMM32
+ -- : BFD_RELOC_CR16_IMM32a
+ -- : BFD_RELOC_CR16_DISP4
+ -- : BFD_RELOC_CR16_DISP8
+ -- : BFD_RELOC_CR16_DISP16
+ -- : BFD_RELOC_CR16_DISP20
+ -- : BFD_RELOC_CR16_DISP24
+ -- : BFD_RELOC_CR16_DISP24a
+ -- : BFD_RELOC_CR16_SWITCH8
+ -- : BFD_RELOC_CR16_SWITCH16
+ -- : BFD_RELOC_CR16_SWITCH32
+ -- : BFD_RELOC_CR16_GOT_REGREL20
+ -- : BFD_RELOC_CR16_GOTC_REGREL20
+ -- : BFD_RELOC_CR16_GLOB_DAT
+ NS CR16 Relocations.
+
+ -- : BFD_RELOC_CRX_REL4
+ -- : BFD_RELOC_CRX_REL8
+ -- : BFD_RELOC_CRX_REL8_CMP
+ -- : BFD_RELOC_CRX_REL16
+ -- : BFD_RELOC_CRX_REL24
+ -- : BFD_RELOC_CRX_REL32
+ -- : BFD_RELOC_CRX_REGREL12
+ -- : BFD_RELOC_CRX_REGREL22
+ -- : BFD_RELOC_CRX_REGREL28
+ -- : BFD_RELOC_CRX_REGREL32
+ -- : BFD_RELOC_CRX_ABS16
+ -- : BFD_RELOC_CRX_ABS32
+ -- : BFD_RELOC_CRX_NUM8
+ -- : BFD_RELOC_CRX_NUM16
+ -- : BFD_RELOC_CRX_NUM32
+ -- : BFD_RELOC_CRX_IMM16
+ -- : BFD_RELOC_CRX_IMM32
+ -- : BFD_RELOC_CRX_SWITCH8
+ -- : BFD_RELOC_CRX_SWITCH16
+ -- : BFD_RELOC_CRX_SWITCH32
+ NS CRX Relocations.
+
+ -- : BFD_RELOC_CRIS_BDISP8
+ -- : BFD_RELOC_CRIS_UNSIGNED_5
+ -- : BFD_RELOC_CRIS_SIGNED_6
+ -- : BFD_RELOC_CRIS_UNSIGNED_6
+ -- : BFD_RELOC_CRIS_SIGNED_8
+ -- : BFD_RELOC_CRIS_UNSIGNED_8
+ -- : BFD_RELOC_CRIS_SIGNED_16
+ -- : BFD_RELOC_CRIS_UNSIGNED_16
+ -- : BFD_RELOC_CRIS_LAPCQ_OFFSET
+ -- : BFD_RELOC_CRIS_UNSIGNED_4
+ These relocs are only used within the CRIS assembler. They are not
+ (at present) written to any object files.
+
+ -- : BFD_RELOC_CRIS_COPY
+ -- : BFD_RELOC_CRIS_GLOB_DAT
+ -- : BFD_RELOC_CRIS_JUMP_SLOT
+ -- : BFD_RELOC_CRIS_RELATIVE
+ Relocs used in ELF shared libraries for CRIS.
+
+ -- : BFD_RELOC_CRIS_32_GOT
+ 32-bit offset to symbol-entry within GOT.
+
+ -- : BFD_RELOC_CRIS_16_GOT
+ 16-bit offset to symbol-entry within GOT.
+
+ -- : BFD_RELOC_CRIS_32_GOTPLT
+ 32-bit offset to symbol-entry within GOT, with PLT handling.
+
+ -- : BFD_RELOC_CRIS_16_GOTPLT
+ 16-bit offset to symbol-entry within GOT, with PLT handling.
+
+ -- : BFD_RELOC_CRIS_32_GOTREL
+ 32-bit offset to symbol, relative to GOT.
+
+ -- : BFD_RELOC_CRIS_32_PLT_GOTREL
+ 32-bit offset to symbol with PLT entry, relative to GOT.
+
+ -- : BFD_RELOC_CRIS_32_PLT_PCREL
+ 32-bit offset to symbol with PLT entry, relative to this
+ relocation.
+
+ -- : BFD_RELOC_CRIS_32_GOT_GD
+ -- : BFD_RELOC_CRIS_16_GOT_GD
+ -- : BFD_RELOC_CRIS_32_GD
+ -- : BFD_RELOC_CRIS_DTP
+ -- : BFD_RELOC_CRIS_32_DTPREL
+ -- : BFD_RELOC_CRIS_16_DTPREL
+ -- : BFD_RELOC_CRIS_32_GOT_TPREL
+ -- : BFD_RELOC_CRIS_16_GOT_TPREL
+ -- : BFD_RELOC_CRIS_32_TPREL
+ -- : BFD_RELOC_CRIS_16_TPREL
+ -- : BFD_RELOC_CRIS_DTPMOD
+ -- : BFD_RELOC_CRIS_32_IE
+ Relocs used in TLS code for CRIS.
+
+ -- : BFD_RELOC_860_COPY
+ -- : BFD_RELOC_860_GLOB_DAT
+ -- : BFD_RELOC_860_JUMP_SLOT
+ -- : BFD_RELOC_860_RELATIVE
+ -- : BFD_RELOC_860_PC26
+ -- : BFD_RELOC_860_PLT26
+ -- : BFD_RELOC_860_PC16
+ -- : BFD_RELOC_860_LOW0
+ -- : BFD_RELOC_860_SPLIT0
+ -- : BFD_RELOC_860_LOW1
+ -- : BFD_RELOC_860_SPLIT1
+ -- : BFD_RELOC_860_LOW2
+ -- : BFD_RELOC_860_SPLIT2
+ -- : BFD_RELOC_860_LOW3
+ -- : BFD_RELOC_860_LOGOT0
+ -- : BFD_RELOC_860_SPGOT0
+ -- : BFD_RELOC_860_LOGOT1
+ -- : BFD_RELOC_860_SPGOT1
+ -- : BFD_RELOC_860_LOGOTOFF0
+ -- : BFD_RELOC_860_SPGOTOFF0
+ -- : BFD_RELOC_860_LOGOTOFF1
+ -- : BFD_RELOC_860_SPGOTOFF1
+ -- : BFD_RELOC_860_LOGOTOFF2
+ -- : BFD_RELOC_860_LOGOTOFF3
+ -- : BFD_RELOC_860_LOPC
+ -- : BFD_RELOC_860_HIGHADJ
+ -- : BFD_RELOC_860_HAGOT
+ -- : BFD_RELOC_860_HAGOTOFF
+ -- : BFD_RELOC_860_HAPC
+ -- : BFD_RELOC_860_HIGH
+ -- : BFD_RELOC_860_HIGOT
+ -- : BFD_RELOC_860_HIGOTOFF
+ Intel i860 Relocations.
+
+ -- : BFD_RELOC_OR1K_REL_26
+ -- : BFD_RELOC_OR1K_GOTPC_HI16
+ -- : BFD_RELOC_OR1K_GOTPC_LO16
+ -- : BFD_RELOC_OR1K_GOT16
+ -- : BFD_RELOC_OR1K_PLT26
+ -- : BFD_RELOC_OR1K_GOTOFF_HI16
+ -- : BFD_RELOC_OR1K_GOTOFF_LO16
+ -- : BFD_RELOC_OR1K_COPY
+ -- : BFD_RELOC_OR1K_GLOB_DAT
+ -- : BFD_RELOC_OR1K_JMP_SLOT
+ -- : BFD_RELOC_OR1K_RELATIVE
+ -- : BFD_RELOC_OR1K_TLS_GD_HI16
+ -- : BFD_RELOC_OR1K_TLS_GD_LO16
+ -- : BFD_RELOC_OR1K_TLS_LDM_HI16
+ -- : BFD_RELOC_OR1K_TLS_LDM_LO16
+ -- : BFD_RELOC_OR1K_TLS_LDO_HI16
+ -- : BFD_RELOC_OR1K_TLS_LDO_LO16
+ -- : BFD_RELOC_OR1K_TLS_IE_HI16
+ -- : BFD_RELOC_OR1K_TLS_IE_LO16
+ -- : BFD_RELOC_OR1K_TLS_LE_HI16
+ -- : BFD_RELOC_OR1K_TLS_LE_LO16
+ -- : BFD_RELOC_OR1K_TLS_TPOFF
+ -- : BFD_RELOC_OR1K_TLS_DTPOFF
+ -- : BFD_RELOC_OR1K_TLS_DTPMOD
+ OpenRISC 1000 Relocations.
+
+ -- : BFD_RELOC_H8_DIR16A8
+ -- : BFD_RELOC_H8_DIR16R8
+ -- : BFD_RELOC_H8_DIR24A8
+ -- : BFD_RELOC_H8_DIR24R8
+ -- : BFD_RELOC_H8_DIR32A16
+ -- : BFD_RELOC_H8_DISP32A16
+ H8 elf Relocations.
+
+ -- : BFD_RELOC_XSTORMY16_REL_12
+ -- : BFD_RELOC_XSTORMY16_12
+ -- : BFD_RELOC_XSTORMY16_24
+ -- : BFD_RELOC_XSTORMY16_FPTR16
+ Sony Xstormy16 Relocations.
+
+ -- : BFD_RELOC_RELC
+ Self-describing complex relocations.
+
+ -- : BFD_RELOC_XC16X_PAG
+ -- : BFD_RELOC_XC16X_POF
+ -- : BFD_RELOC_XC16X_SEG
+ -- : BFD_RELOC_XC16X_SOF
+ Infineon Relocations.
+
+ -- : BFD_RELOC_VAX_GLOB_DAT
+ -- : BFD_RELOC_VAX_JMP_SLOT
+ -- : BFD_RELOC_VAX_RELATIVE
+ Relocations used by VAX ELF.
+
+ -- : BFD_RELOC_MT_PC16
+ Morpho MT - 16 bit immediate relocation.
+
+ -- : BFD_RELOC_MT_HI16
+ Morpho MT - Hi 16 bits of an address.
+
+ -- : BFD_RELOC_MT_LO16
+ Morpho MT - Low 16 bits of an address.
+
+ -- : BFD_RELOC_MT_GNU_VTINHERIT
+ Morpho MT - Used to tell the linker which vtable entries are used.
+
+ -- : BFD_RELOC_MT_GNU_VTENTRY
+ Morpho MT - Used to tell the linker which vtable entries are used.
+
+ -- : BFD_RELOC_MT_PCINSN8
+ Morpho MT - 8 bit immediate relocation.
+
+ -- : BFD_RELOC_MSP430_10_PCREL
+ -- : BFD_RELOC_MSP430_16_PCREL
+ -- : BFD_RELOC_MSP430_16
+ -- : BFD_RELOC_MSP430_16_PCREL_BYTE
+ -- : BFD_RELOC_MSP430_16_BYTE
+ -- : BFD_RELOC_MSP430_2X_PCREL
+ -- : BFD_RELOC_MSP430_RL_PCREL
+ -- : BFD_RELOC_MSP430_ABS8
+ -- : BFD_RELOC_MSP430X_PCR20_EXT_SRC
+ -- : BFD_RELOC_MSP430X_PCR20_EXT_DST
+ -- : BFD_RELOC_MSP430X_PCR20_EXT_ODST
+ -- : BFD_RELOC_MSP430X_ABS20_EXT_SRC
+ -- : BFD_RELOC_MSP430X_ABS20_EXT_DST
+ -- : BFD_RELOC_MSP430X_ABS20_EXT_ODST
+ -- : BFD_RELOC_MSP430X_ABS20_ADR_SRC
+ -- : BFD_RELOC_MSP430X_ABS20_ADR_DST
+ -- : BFD_RELOC_MSP430X_PCR16
+ -- : BFD_RELOC_MSP430X_PCR20_CALL
+ -- : BFD_RELOC_MSP430X_ABS16
+ -- : BFD_RELOC_MSP430_ABS_HI16
+ -- : BFD_RELOC_MSP430_PREL31
+ -- : BFD_RELOC_MSP430_SYM_DIFF
+ msp430 specific relocation codes
+
+ -- : BFD_RELOC_NIOS2_S16
+ -- : BFD_RELOC_NIOS2_U16
+ -- : BFD_RELOC_NIOS2_CALL26
+ -- : BFD_RELOC_NIOS2_IMM5
+ -- : BFD_RELOC_NIOS2_CACHE_OPX
+ -- : BFD_RELOC_NIOS2_IMM6
+ -- : BFD_RELOC_NIOS2_IMM8
+ -- : BFD_RELOC_NIOS2_HI16
+ -- : BFD_RELOC_NIOS2_LO16
+ -- : BFD_RELOC_NIOS2_HIADJ16
+ -- : BFD_RELOC_NIOS2_GPREL
+ -- : BFD_RELOC_NIOS2_UJMP
+ -- : BFD_RELOC_NIOS2_CJMP
+ -- : BFD_RELOC_NIOS2_CALLR
+ -- : BFD_RELOC_NIOS2_ALIGN
+ -- : BFD_RELOC_NIOS2_GOT16
+ -- : BFD_RELOC_NIOS2_CALL16
+ -- : BFD_RELOC_NIOS2_GOTOFF_LO
+ -- : BFD_RELOC_NIOS2_GOTOFF_HA
+ -- : BFD_RELOC_NIOS2_PCREL_LO
+ -- : BFD_RELOC_NIOS2_PCREL_HA
+ -- : BFD_RELOC_NIOS2_TLS_GD16
+ -- : BFD_RELOC_NIOS2_TLS_LDM16
+ -- : BFD_RELOC_NIOS2_TLS_LDO16
+ -- : BFD_RELOC_NIOS2_TLS_IE16
+ -- : BFD_RELOC_NIOS2_TLS_LE16
+ -- : BFD_RELOC_NIOS2_TLS_DTPMOD
+ -- : BFD_RELOC_NIOS2_TLS_DTPREL
+ -- : BFD_RELOC_NIOS2_TLS_TPREL
+ -- : BFD_RELOC_NIOS2_COPY
+ -- : BFD_RELOC_NIOS2_GLOB_DAT
+ -- : BFD_RELOC_NIOS2_JUMP_SLOT
+ -- : BFD_RELOC_NIOS2_RELATIVE
+ -- : BFD_RELOC_NIOS2_GOTOFF
+ -- : BFD_RELOC_NIOS2_CALL26_NOAT
+ -- : BFD_RELOC_NIOS2_GOT_LO
+ -- : BFD_RELOC_NIOS2_GOT_HA
+ -- : BFD_RELOC_NIOS2_CALL_LO
+ -- : BFD_RELOC_NIOS2_CALL_HA
+ Relocations used by the Altera Nios II core.
+
+ -- : BFD_RELOC_IQ2000_OFFSET_16
+ -- : BFD_RELOC_IQ2000_OFFSET_21
+ -- : BFD_RELOC_IQ2000_UHI16
+ IQ2000 Relocations.
+
+ -- : BFD_RELOC_XTENSA_RTLD
+ Special Xtensa relocation used only by PLT entries in ELF shared
+ objects to indicate that the runtime linker should set the value
+ to one of its own internal functions or data structures.
+
+ -- : BFD_RELOC_XTENSA_GLOB_DAT
+ -- : BFD_RELOC_XTENSA_JMP_SLOT
+ -- : BFD_RELOC_XTENSA_RELATIVE
+ Xtensa relocations for ELF shared objects.
+
+ -- : BFD_RELOC_XTENSA_PLT
+ Xtensa relocation used in ELF object files for symbols that may
+ require PLT entries. Otherwise, this is just a generic 32-bit
+ relocation.
+
+ -- : BFD_RELOC_XTENSA_DIFF8
+ -- : BFD_RELOC_XTENSA_DIFF16
+ -- : BFD_RELOC_XTENSA_DIFF32
+ Xtensa relocations to mark the difference of two local symbols.
+ These are only needed to support linker relaxation and can be
+ ignored when not relaxing. The field is set to the value of the
+ difference assuming no relaxation. The relocation encodes the
+ position of the first symbol so the linker can determine whether
+ to adjust the field value.
+
+ -- : BFD_RELOC_XTENSA_SLOT0_OP
+ -- : BFD_RELOC_XTENSA_SLOT1_OP
+ -- : BFD_RELOC_XTENSA_SLOT2_OP
+ -- : BFD_RELOC_XTENSA_SLOT3_OP
+ -- : BFD_RELOC_XTENSA_SLOT4_OP
+ -- : BFD_RELOC_XTENSA_SLOT5_OP
+ -- : BFD_RELOC_XTENSA_SLOT6_OP
+ -- : BFD_RELOC_XTENSA_SLOT7_OP
+ -- : BFD_RELOC_XTENSA_SLOT8_OP
+ -- : BFD_RELOC_XTENSA_SLOT9_OP
+ -- : BFD_RELOC_XTENSA_SLOT10_OP
+ -- : BFD_RELOC_XTENSA_SLOT11_OP
+ -- : BFD_RELOC_XTENSA_SLOT12_OP
+ -- : BFD_RELOC_XTENSA_SLOT13_OP
+ -- : BFD_RELOC_XTENSA_SLOT14_OP
+ Generic Xtensa relocations for instruction operands. Only the slot
+ number is encoded in the relocation. The relocation applies to the
+ last PC-relative immediate operand, or if there are no PC-relative
+ immediates, to the last immediate operand.
+
+ -- : BFD_RELOC_XTENSA_SLOT0_ALT
+ -- : BFD_RELOC_XTENSA_SLOT1_ALT
+ -- : BFD_RELOC_XTENSA_SLOT2_ALT
+ -- : BFD_RELOC_XTENSA_SLOT3_ALT
+ -- : BFD_RELOC_XTENSA_SLOT4_ALT
+ -- : BFD_RELOC_XTENSA_SLOT5_ALT
+ -- : BFD_RELOC_XTENSA_SLOT6_ALT
+ -- : BFD_RELOC_XTENSA_SLOT7_ALT
+ -- : BFD_RELOC_XTENSA_SLOT8_ALT
+ -- : BFD_RELOC_XTENSA_SLOT9_ALT
+ -- : BFD_RELOC_XTENSA_SLOT10_ALT
+ -- : BFD_RELOC_XTENSA_SLOT11_ALT
+ -- : BFD_RELOC_XTENSA_SLOT12_ALT
+ -- : BFD_RELOC_XTENSA_SLOT13_ALT
+ -- : BFD_RELOC_XTENSA_SLOT14_ALT
+ Alternate Xtensa relocations. Only the slot is encoded in the
+ relocation. The meaning of these relocations is opcode-specific.
+
+ -- : BFD_RELOC_XTENSA_OP0
+ -- : BFD_RELOC_XTENSA_OP1
+ -- : BFD_RELOC_XTENSA_OP2
+ Xtensa relocations for backward compatibility. These have all been
+ replaced by BFD_RELOC_XTENSA_SLOT0_OP.
+
+ -- : BFD_RELOC_XTENSA_ASM_EXPAND
+ Xtensa relocation to mark that the assembler expanded the
+ instructions from an original target. The expansion size is
+ encoded in the reloc size.
+
+ -- : BFD_RELOC_XTENSA_ASM_SIMPLIFY
+ Xtensa relocation to mark that the linker should simplify
+ assembler-expanded instructions. This is commonly used internally
+ by the linker after analysis of a BFD_RELOC_XTENSA_ASM_EXPAND.
+
+ -- : BFD_RELOC_XTENSA_TLSDESC_FN
+ -- : BFD_RELOC_XTENSA_TLSDESC_ARG
+ -- : BFD_RELOC_XTENSA_TLS_DTPOFF
+ -- : BFD_RELOC_XTENSA_TLS_TPOFF
+ -- : BFD_RELOC_XTENSA_TLS_FUNC
+ -- : BFD_RELOC_XTENSA_TLS_ARG
+ -- : BFD_RELOC_XTENSA_TLS_CALL
+ Xtensa TLS relocations.
+
+ -- : BFD_RELOC_Z80_DISP8
+ 8 bit signed offset in (ix+d) or (iy+d).
+
+ -- : BFD_RELOC_Z8K_DISP7
+ DJNZ offset.
+
+ -- : BFD_RELOC_Z8K_CALLR
+ CALR offset.
+
+ -- : BFD_RELOC_Z8K_IMM4L
+ 4 bit value.
+
+ -- : BFD_RELOC_LM32_CALL
+ -- : BFD_RELOC_LM32_BRANCH
+ -- : BFD_RELOC_LM32_16_GOT
+ -- : BFD_RELOC_LM32_GOTOFF_HI16
+ -- : BFD_RELOC_LM32_GOTOFF_LO16
+ -- : BFD_RELOC_LM32_COPY
+ -- : BFD_RELOC_LM32_GLOB_DAT
+ -- : BFD_RELOC_LM32_JMP_SLOT
+ -- : BFD_RELOC_LM32_RELATIVE
+ Lattice Mico32 relocations.
+
+ -- : BFD_RELOC_MACH_O_SECTDIFF
+ Difference between two section addreses. Must be followed by a
+ BFD_RELOC_MACH_O_PAIR.
+
+ -- : BFD_RELOC_MACH_O_LOCAL_SECTDIFF
+ Like BFD_RELOC_MACH_O_SECTDIFF but with a local symbol.
+
+ -- : BFD_RELOC_MACH_O_PAIR
+ Pair of relocation. Contains the first symbol.
+
+ -- : BFD_RELOC_MACH_O_X86_64_BRANCH32
+ -- : BFD_RELOC_MACH_O_X86_64_BRANCH8
+ PCREL relocations. They are marked as branch to create PLT entry
+ if required.
+
+ -- : BFD_RELOC_MACH_O_X86_64_GOT
+ Used when referencing a GOT entry.
+
+ -- : BFD_RELOC_MACH_O_X86_64_GOT_LOAD
+ Used when loading a GOT entry with movq. It is specially marked
+ so that the linker could optimize the movq to a leaq if possible.
+
+ -- : BFD_RELOC_MACH_O_X86_64_SUBTRACTOR32
+ Symbol will be substracted. Must be followed by a BFD_RELOC_64.
+
+ -- : BFD_RELOC_MACH_O_X86_64_SUBTRACTOR64
+ Symbol will be substracted. Must be followed by a BFD_RELOC_64.
+
+ -- : BFD_RELOC_MACH_O_X86_64_PCREL32_1
+ Same as BFD_RELOC_32_PCREL but with an implicit -1 addend.
+
+ -- : BFD_RELOC_MACH_O_X86_64_PCREL32_2
+ Same as BFD_RELOC_32_PCREL but with an implicit -2 addend.
+
+ -- : BFD_RELOC_MACH_O_X86_64_PCREL32_4
+ Same as BFD_RELOC_32_PCREL but with an implicit -4 addend.
+
+ -- : BFD_RELOC_MICROBLAZE_32_LO
+ This is a 32 bit reloc for the microblaze that stores the low 16
+ bits of a value
+
+ -- : BFD_RELOC_MICROBLAZE_32_LO_PCREL
+ This is a 32 bit pc-relative reloc for the microblaze that stores
+ the low 16 bits of a value
+
+ -- : BFD_RELOC_MICROBLAZE_32_ROSDA
+ This is a 32 bit reloc for the microblaze that stores a value
+ relative to the read-only small data area anchor
+
+ -- : BFD_RELOC_MICROBLAZE_32_RWSDA
+ This is a 32 bit reloc for the microblaze that stores a value
+ relative to the read-write small data area anchor
+
+ -- : BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM
+ This is a 32 bit reloc for the microblaze to handle expressions of
+ the form "Symbol Op Symbol"
+
+ -- : BFD_RELOC_MICROBLAZE_64_NONE
+ This is a 64 bit reloc that stores the 32 bit pc relative value in
+ two words (with an imm instruction). No relocation is done here -
+ only used for relaxing
+
+ -- : BFD_RELOC_MICROBLAZE_64_GOTPC
+ This is a 64 bit reloc that stores the 32 bit pc relative value in
+ two words (with an imm instruction). The relocation is
+ PC-relative GOT offset
+
+ -- : BFD_RELOC_MICROBLAZE_64_GOT
+ This is a 64 bit reloc that stores the 32 bit pc relative value in
+ two words (with an imm instruction). The relocation is GOT offset
+
+ -- : BFD_RELOC_MICROBLAZE_64_PLT
+ This is a 64 bit reloc that stores the 32 bit pc relative value in
+ two words (with an imm instruction). The relocation is
+ PC-relative offset into PLT
+
+ -- : BFD_RELOC_MICROBLAZE_64_GOTOFF
+ This is a 64 bit reloc that stores the 32 bit GOT relative value
+ in two words (with an imm instruction). The relocation is
+ relative offset from _GLOBAL_OFFSET_TABLE_
+
+ -- : BFD_RELOC_MICROBLAZE_32_GOTOFF
+ This is a 32 bit reloc that stores the 32 bit GOT relative value
+ in a word. The relocation is relative offset from
+
+ -- : BFD_RELOC_MICROBLAZE_COPY
+ This is used to tell the dynamic linker to copy the value out of
+ the dynamic object into the runtime process image.
+
+ -- : BFD_RELOC_MICROBLAZE_64_TLS
+ Unused Reloc
+
+ -- : BFD_RELOC_MICROBLAZE_64_TLSGD
+ This is a 64 bit reloc that stores the 32 bit GOT relative value
+ of the GOT TLS GD info entry in two words (with an imm
+ instruction). The relocation is GOT offset.
+
+ -- : BFD_RELOC_MICROBLAZE_64_TLSLD
+ This is a 64 bit reloc that stores the 32 bit GOT relative value
+ of the GOT TLS LD info entry in two words (with an imm
+ instruction). The relocation is GOT offset.
+
+ -- : BFD_RELOC_MICROBLAZE_32_TLSDTPMOD
+ This is a 32 bit reloc that stores the Module ID to GOT(n).
+
+ -- : BFD_RELOC_MICROBLAZE_32_TLSDTPREL
+ This is a 32 bit reloc that stores TLS offset to GOT(n+1).
+
+ -- : BFD_RELOC_MICROBLAZE_64_TLSDTPREL
+ This is a 32 bit reloc for storing TLS offset to two words (uses
+ imm instruction)
+
+ -- : BFD_RELOC_MICROBLAZE_64_TLSGOTTPREL
+ This is a 64 bit reloc that stores 32-bit thread pointer relative
+ offset to two words (uses imm instruction).
+
+ -- : BFD_RELOC_MICROBLAZE_64_TLSTPREL
+ This is a 64 bit reloc that stores 32-bit thread pointer relative
+ offset to two words (uses imm instruction).
+
+ -- : BFD_RELOC_AARCH64_RELOC_START
+ AArch64 pseudo relocation code to mark the start of the AArch64
+ relocation enumerators. N.B. the order of the enumerators is
+ important as several tables in the AArch64 bfd backend are indexed
+ by these enumerators; make sure they are all synced.
+
+ -- : BFD_RELOC_AARCH64_NONE
+ AArch64 null relocation code.
+
+ -- : BFD_RELOC_AARCH64_64
+ -- : BFD_RELOC_AARCH64_32
+ -- : BFD_RELOC_AARCH64_16
+ Basic absolute relocations of N bits. These are equivalent to
+ BFD_RELOC_N and they were added to assist the indexing of the howto
+ table.
+
+ -- : BFD_RELOC_AARCH64_64_PCREL
+ -- : BFD_RELOC_AARCH64_32_PCREL
+ -- : BFD_RELOC_AARCH64_16_PCREL
+ PC-relative relocations. These are equivalent to BFD_RELOC_N_PCREL
+ and they were added to assist the indexing of the howto table.
+
+ -- : BFD_RELOC_AARCH64_MOVW_G0
+ AArch64 MOV[NZK] instruction with most significant bits 0 to 15 of
+ an unsigned address/value.
+
+ -- : BFD_RELOC_AARCH64_MOVW_G0_NC
+ AArch64 MOV[NZK] instruction with less significant bits 0 to 15 of
+ an address/value. No overflow checking.
+
+ -- : BFD_RELOC_AARCH64_MOVW_G1
+ AArch64 MOV[NZK] instruction with most significant bits 16 to 31
+ of an unsigned address/value.
+
+ -- : BFD_RELOC_AARCH64_MOVW_G1_NC
+ AArch64 MOV[NZK] instruction with less significant bits 16 to 31
+ of an address/value. No overflow checking.
+
+ -- : BFD_RELOC_AARCH64_MOVW_G2
+ AArch64 MOV[NZK] instruction with most significant bits 32 to 47
+ of an unsigned address/value.
+
+ -- : BFD_RELOC_AARCH64_MOVW_G2_NC
+ AArch64 MOV[NZK] instruction with less significant bits 32 to 47
+ of an address/value. No overflow checking.
+
+ -- : BFD_RELOC_AARCH64_MOVW_G3
+ AArch64 MOV[NZK] instruction with most signficant bits 48 to 64 of
+ a signed or unsigned address/value.
+
+ -- : BFD_RELOC_AARCH64_MOVW_G0_S
+ AArch64 MOV[NZ] instruction with most significant bits 0 to 15 of
+ a signed value. Changes instruction to MOVZ or MOVN depending on
+ the value's sign.
+
+ -- : BFD_RELOC_AARCH64_MOVW_G1_S
+ AArch64 MOV[NZ] instruction with most significant bits 16 to 31 of
+ a signed value. Changes instruction to MOVZ or MOVN depending on
+ the value's sign.
+
+ -- : BFD_RELOC_AARCH64_MOVW_G2_S
+ AArch64 MOV[NZ] instruction with most significant bits 32 to 47 of
+ a signed value. Changes instruction to MOVZ or MOVN depending on
+ the value's sign.
+
+ -- : BFD_RELOC_AARCH64_LD_LO19_PCREL
+ AArch64 Load Literal instruction, holding a 19 bit pc-relative word
+ offset. The lowest two bits must be zero and are not stored in the
+ instruction, giving a 21 bit signed byte offset.
+
+ -- : BFD_RELOC_AARCH64_ADR_LO21_PCREL
+ AArch64 ADR instruction, holding a simple 21 bit pc-relative byte
+ offset.
+
+ -- : BFD_RELOC_AARCH64_ADR_HI21_PCREL
+ AArch64 ADRP instruction, with bits 12 to 32 of a pc-relative page
+ offset, giving a 4KB aligned page base address.
+
+ -- : BFD_RELOC_AARCH64_ADR_HI21_NC_PCREL
+ AArch64 ADRP instruction, with bits 12 to 32 of a pc-relative page
+ offset, giving a 4KB aligned page base address, but with no
+ overflow checking.
+
+ -- : BFD_RELOC_AARCH64_ADD_LO12
+ AArch64 ADD immediate instruction, holding bits 0 to 11 of the
+ address. Used in conjunction with
+ BFD_RELOC_AARCH64_ADR_HI21_PCREL.
+
+ -- : BFD_RELOC_AARCH64_LDST8_LO12
+ AArch64 8-bit load/store instruction, holding bits 0 to 11 of the
+ address. Used in conjunction with
+ BFD_RELOC_AARCH64_ADR_HI21_PCREL.
+
+ -- : BFD_RELOC_AARCH64_TSTBR14
+ AArch64 14 bit pc-relative test bit and branch. The lowest two
+ bits must be zero and are not stored in the instruction, giving a
+ 16 bit signed byte offset.
+
+ -- : BFD_RELOC_AARCH64_BRANCH19
+ AArch64 19 bit pc-relative conditional branch and compare & branch.
+ The lowest two bits must be zero and are not stored in the
+ instruction, giving a 21 bit signed byte offset.
+
+ -- : BFD_RELOC_AARCH64_JUMP26
+ AArch64 26 bit pc-relative unconditional branch. The lowest two
+ bits must be zero and are not stored in the instruction, giving a
+ 28 bit signed byte offset.
+
+ -- : BFD_RELOC_AARCH64_CALL26
+ AArch64 26 bit pc-relative unconditional branch and link. The
+ lowest two bits must be zero and are not stored in the instruction,
+ giving a 28 bit signed byte offset.
+
+ -- : BFD_RELOC_AARCH64_LDST16_LO12
+ AArch64 16-bit load/store instruction, holding bits 0 to 11 of the
+ address. Used in conjunction with
+ BFD_RELOC_AARCH64_ADR_HI21_PCREL.
+
+ -- : BFD_RELOC_AARCH64_LDST32_LO12
+ AArch64 32-bit load/store instruction, holding bits 0 to 11 of the
+ address. Used in conjunction with
+ BFD_RELOC_AARCH64_ADR_HI21_PCREL.
+
+ -- : BFD_RELOC_AARCH64_LDST64_LO12
+ AArch64 64-bit load/store instruction, holding bits 0 to 11 of the
+ address. Used in conjunction with
+ BFD_RELOC_AARCH64_ADR_HI21_PCREL.
+
+ -- : BFD_RELOC_AARCH64_LDST128_LO12
+ AArch64 128-bit load/store instruction, holding bits 0 to 11 of the
+ address. Used in conjunction with
+ BFD_RELOC_AARCH64_ADR_HI21_PCREL.
+
+ -- : BFD_RELOC_AARCH64_GOT_LD_PREL19
+ AArch64 Load Literal instruction, holding a 19 bit PC relative word
+ offset of the global offset table entry for a symbol. The lowest
+ two bits must be zero and are not stored in the instruction,
+ giving a 21 bit signed byte offset. This relocation type requires
+ signed overflow checking.
+
+ -- : BFD_RELOC_AARCH64_ADR_GOT_PAGE
+ Get to the page base of the global offset table entry for a symbol
+ as part of an ADRP instruction using a 21 bit PC relative
+ value.Used in conjunction with BFD_RELOC_AARCH64_LD64_GOT_LO12_NC.
+
+ -- : BFD_RELOC_AARCH64_LD64_GOT_LO12_NC
+ Unsigned 12 bit byte offset for 64 bit load/store from the page of
+ the GOT entry for this symbol. Used in conjunction with
+ BFD_RELOC_AARCH64_ADR_GOTPAGE. Valid in LP64 ABI only.
+
+ -- : BFD_RELOC_AARCH64_LD32_GOT_LO12_NC
+ Unsigned 12 bit byte offset for 32 bit load/store from the page of
+ the GOT entry for this symbol. Used in conjunction with
+ BFD_RELOC_AARCH64_ADR_GOTPAGE. Valid in ILP32 ABI only.
+
+ -- : BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21
+ Get to the page base of the global offset table entry for a symbols
+ tls_index structure as part of an adrp instruction using a 21 bit
+ PC relative value. Used in conjunction with
+ BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC.
+
+ -- : BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC
+ Unsigned 12 bit byte offset to global offset table entry for a
+ symbols tls_index structure. Used in conjunction with
+ BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21.
+
+ -- : BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G1
+ AArch64 TLS INITIAL EXEC relocation.
+
+ -- : BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC
+ AArch64 TLS INITIAL EXEC relocation.
+
+ -- : BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21
+ AArch64 TLS INITIAL EXEC relocation.
+
+ -- : BFD_RELOC_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC
+ AArch64 TLS INITIAL EXEC relocation.
+
+ -- : BFD_RELOC_AARCH64_TLSIE_LD32_GOTTPREL_LO12_NC
+ AArch64 TLS INITIAL EXEC relocation.
+
+ -- : BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19
+ AArch64 TLS INITIAL EXEC relocation.
+
+ -- : BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G2
+ AArch64 TLS LOCAL EXEC relocation.
+
+ -- : BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1
+ AArch64 TLS LOCAL EXEC relocation.
+
+ -- : BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1_NC
+ AArch64 TLS LOCAL EXEC relocation.
+
+ -- : BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0
+ AArch64 TLS LOCAL EXEC relocation.
+
+ -- : BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC
+ AArch64 TLS LOCAL EXEC relocation.
+
+ -- : BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_HI12
+ AArch64 TLS LOCAL EXEC relocation.
+
+ -- : BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12
+ AArch64 TLS LOCAL EXEC relocation.
+
+ -- : BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12_NC
+ AArch64 TLS LOCAL EXEC relocation.
+
+ -- : BFD_RELOC_AARCH64_TLSDESC_LD_PREL19
+ AArch64 TLS DESC relocation.
+
+ -- : BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21
+ AArch64 TLS DESC relocation.
+
+ -- : BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21
+ AArch64 TLS DESC relocation.
+
+ -- : BFD_RELOC_AARCH64_TLSDESC_LD64_LO12_NC
+ AArch64 TLS DESC relocation.
+
+ -- : BFD_RELOC_AARCH64_TLSDESC_LD32_LO12_NC
+ AArch64 TLS DESC relocation.
+
+ -- : BFD_RELOC_AARCH64_TLSDESC_ADD_LO12_NC
+ AArch64 TLS DESC relocation.
+
+ -- : BFD_RELOC_AARCH64_TLSDESC_OFF_G1
+ AArch64 TLS DESC relocation.
+
+ -- : BFD_RELOC_AARCH64_TLSDESC_OFF_G0_NC
+ AArch64 TLS DESC relocation.
+
+ -- : BFD_RELOC_AARCH64_TLSDESC_LDR
+ AArch64 TLS DESC relocation.
+
+ -- : BFD_RELOC_AARCH64_TLSDESC_ADD
+ AArch64 TLS DESC relocation.
+
+ -- : BFD_RELOC_AARCH64_TLSDESC_CALL
+ AArch64 TLS DESC relocation.
+
+ -- : BFD_RELOC_AARCH64_COPY
+ AArch64 TLS relocation.
+
+ -- : BFD_RELOC_AARCH64_GLOB_DAT
+ AArch64 TLS relocation.
+
+ -- : BFD_RELOC_AARCH64_JUMP_SLOT
+ AArch64 TLS relocation.
+
+ -- : BFD_RELOC_AARCH64_RELATIVE
+ AArch64 TLS relocation.
+
+ -- : BFD_RELOC_AARCH64_TLS_DTPMOD
+ AArch64 TLS relocation.
+
+ -- : BFD_RELOC_AARCH64_TLS_DTPREL
+ AArch64 TLS relocation.
+
+ -- : BFD_RELOC_AARCH64_TLS_TPREL
+ AArch64 TLS relocation.
+
+ -- : BFD_RELOC_AARCH64_TLSDESC
+ AArch64 TLS relocation.
+
+ -- : BFD_RELOC_AARCH64_IRELATIVE
+ AArch64 support for STT_GNU_IFUNC.
+
+ -- : BFD_RELOC_AARCH64_RELOC_END
+ AArch64 pseudo relocation code to mark the end of the AArch64
+ relocation enumerators that have direct mapping to ELF reloc codes.
+ There are a few more enumerators after this one; those are mainly
+ used by the AArch64 assembler for the internal fixup or to select
+ one of the above enumerators.
+
+ -- : BFD_RELOC_AARCH64_GAS_INTERNAL_FIXUP
+ AArch64 pseudo relocation code to be used internally by the AArch64
+ assembler and not (currently) written to any object files.
+
+ -- : BFD_RELOC_AARCH64_LDST_LO12
+ AArch64 unspecified load/store instruction, holding bits 0 to 11
+ of the address. Used in conjunction with
+ BFD_RELOC_AARCH64_ADR_HI21_PCREL.
+
+ -- : BFD_RELOC_AARCH64_LD_GOT_LO12_NC
+ AArch64 pseudo relocation code to be used internally by the AArch64
+ assembler and not (currently) written to any object files.
+
+ -- : BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_LO12_NC
+ AArch64 pseudo relocation code to be used internally by the AArch64
+ assembler and not (currently) written to any object files.
+
+ -- : BFD_RELOC_AARCH64_TLSDESC_LD_LO12_NC
+ AArch64 pseudo relocation code to be used internally by the AArch64
+ assembler and not (currently) written to any object files.
+
+ -- : BFD_RELOC_TILEPRO_COPY
+ -- : BFD_RELOC_TILEPRO_GLOB_DAT
+ -- : BFD_RELOC_TILEPRO_JMP_SLOT
+ -- : BFD_RELOC_TILEPRO_RELATIVE
+ -- : BFD_RELOC_TILEPRO_BROFF_X1
+ -- : BFD_RELOC_TILEPRO_JOFFLONG_X1
+ -- : BFD_RELOC_TILEPRO_JOFFLONG_X1_PLT
+ -- : BFD_RELOC_TILEPRO_IMM8_X0
+ -- : BFD_RELOC_TILEPRO_IMM8_Y0
+ -- : BFD_RELOC_TILEPRO_IMM8_X1
+ -- : BFD_RELOC_TILEPRO_IMM8_Y1
+ -- : BFD_RELOC_TILEPRO_DEST_IMM8_X1
+ -- : BFD_RELOC_TILEPRO_MT_IMM15_X1
+ -- : BFD_RELOC_TILEPRO_MF_IMM15_X1
+ -- : BFD_RELOC_TILEPRO_IMM16_X0
+ -- : BFD_RELOC_TILEPRO_IMM16_X1
+ -- : BFD_RELOC_TILEPRO_IMM16_X0_LO
+ -- : BFD_RELOC_TILEPRO_IMM16_X1_LO
+ -- : BFD_RELOC_TILEPRO_IMM16_X0_HI
+ -- : BFD_RELOC_TILEPRO_IMM16_X1_HI
+ -- : BFD_RELOC_TILEPRO_IMM16_X0_HA
+ -- : BFD_RELOC_TILEPRO_IMM16_X1_HA
+ -- : BFD_RELOC_TILEPRO_IMM16_X0_PCREL
+ -- : BFD_RELOC_TILEPRO_IMM16_X1_PCREL
+ -- : BFD_RELOC_TILEPRO_IMM16_X0_LO_PCREL
+ -- : BFD_RELOC_TILEPRO_IMM16_X1_LO_PCREL
+ -- : BFD_RELOC_TILEPRO_IMM16_X0_HI_PCREL
+ -- : BFD_RELOC_TILEPRO_IMM16_X1_HI_PCREL
+ -- : BFD_RELOC_TILEPRO_IMM16_X0_HA_PCREL
+ -- : BFD_RELOC_TILEPRO_IMM16_X1_HA_PCREL
+ -- : BFD_RELOC_TILEPRO_IMM16_X0_GOT
+ -- : BFD_RELOC_TILEPRO_IMM16_X1_GOT
+ -- : BFD_RELOC_TILEPRO_IMM16_X0_GOT_LO
+ -- : BFD_RELOC_TILEPRO_IMM16_X1_GOT_LO
+ -- : BFD_RELOC_TILEPRO_IMM16_X0_GOT_HI
+ -- : BFD_RELOC_TILEPRO_IMM16_X1_GOT_HI
+ -- : BFD_RELOC_TILEPRO_IMM16_X0_GOT_HA
+ -- : BFD_RELOC_TILEPRO_IMM16_X1_GOT_HA
+ -- : BFD_RELOC_TILEPRO_MMSTART_X0
+ -- : BFD_RELOC_TILEPRO_MMEND_X0
+ -- : BFD_RELOC_TILEPRO_MMSTART_X1
+ -- : BFD_RELOC_TILEPRO_MMEND_X1
+ -- : BFD_RELOC_TILEPRO_SHAMT_X0
+ -- : BFD_RELOC_TILEPRO_SHAMT_X1
+ -- : BFD_RELOC_TILEPRO_SHAMT_Y0
+ -- : BFD_RELOC_TILEPRO_SHAMT_Y1
+ -- : BFD_RELOC_TILEPRO_TLS_GD_CALL
+ -- : BFD_RELOC_TILEPRO_IMM8_X0_TLS_GD_ADD
+ -- : BFD_RELOC_TILEPRO_IMM8_X1_TLS_GD_ADD
+ -- : BFD_RELOC_TILEPRO_IMM8_Y0_TLS_GD_ADD
+ -- : BFD_RELOC_TILEPRO_IMM8_Y1_TLS_GD_ADD
+ -- : BFD_RELOC_TILEPRO_TLS_IE_LOAD
+ -- : BFD_RELOC_TILEPRO_IMM16_X0_TLS_GD
+ -- : BFD_RELOC_TILEPRO_IMM16_X1_TLS_GD
+ -- : BFD_RELOC_TILEPRO_IMM16_X0_TLS_GD_LO
+ -- : BFD_RELOC_TILEPRO_IMM16_X1_TLS_GD_LO
+ -- : BFD_RELOC_TILEPRO_IMM16_X0_TLS_GD_HI
+ -- : BFD_RELOC_TILEPRO_IMM16_X1_TLS_GD_HI
+ -- : BFD_RELOC_TILEPRO_IMM16_X0_TLS_GD_HA
+ -- : BFD_RELOC_TILEPRO_IMM16_X1_TLS_GD_HA
+ -- : BFD_RELOC_TILEPRO_IMM16_X0_TLS_IE
+ -- : BFD_RELOC_TILEPRO_IMM16_X1_TLS_IE
+ -- : BFD_RELOC_TILEPRO_IMM16_X0_TLS_IE_LO
+ -- : BFD_RELOC_TILEPRO_IMM16_X1_TLS_IE_LO
+ -- : BFD_RELOC_TILEPRO_IMM16_X0_TLS_IE_HI
+ -- : BFD_RELOC_TILEPRO_IMM16_X1_TLS_IE_HI
+ -- : BFD_RELOC_TILEPRO_IMM16_X0_TLS_IE_HA
+ -- : BFD_RELOC_TILEPRO_IMM16_X1_TLS_IE_HA
+ -- : BFD_RELOC_TILEPRO_TLS_DTPMOD32
+ -- : BFD_RELOC_TILEPRO_TLS_DTPOFF32
+ -- : BFD_RELOC_TILEPRO_TLS_TPOFF32
+ -- : BFD_RELOC_TILEPRO_IMM16_X0_TLS_LE
+ -- : BFD_RELOC_TILEPRO_IMM16_X1_TLS_LE
+ -- : BFD_RELOC_TILEPRO_IMM16_X0_TLS_LE_LO
+ -- : BFD_RELOC_TILEPRO_IMM16_X1_TLS_LE_LO
+ -- : BFD_RELOC_TILEPRO_IMM16_X0_TLS_LE_HI
+ -- : BFD_RELOC_TILEPRO_IMM16_X1_TLS_LE_HI
+ -- : BFD_RELOC_TILEPRO_IMM16_X0_TLS_LE_HA
+ -- : BFD_RELOC_TILEPRO_IMM16_X1_TLS_LE_HA
+ Tilera TILEPro Relocations.
+
+ -- : BFD_RELOC_TILEGX_HW0
+ -- : BFD_RELOC_TILEGX_HW1
+ -- : BFD_RELOC_TILEGX_HW2
+ -- : BFD_RELOC_TILEGX_HW3
+ -- : BFD_RELOC_TILEGX_HW0_LAST
+ -- : BFD_RELOC_TILEGX_HW1_LAST
+ -- : BFD_RELOC_TILEGX_HW2_LAST
+ -- : BFD_RELOC_TILEGX_COPY
+ -- : BFD_RELOC_TILEGX_GLOB_DAT
+ -- : BFD_RELOC_TILEGX_JMP_SLOT
+ -- : BFD_RELOC_TILEGX_RELATIVE
+ -- : BFD_RELOC_TILEGX_BROFF_X1
+ -- : BFD_RELOC_TILEGX_JUMPOFF_X1
+ -- : BFD_RELOC_TILEGX_JUMPOFF_X1_PLT
+ -- : BFD_RELOC_TILEGX_IMM8_X0
+ -- : BFD_RELOC_TILEGX_IMM8_Y0
+ -- : BFD_RELOC_TILEGX_IMM8_X1
+ -- : BFD_RELOC_TILEGX_IMM8_Y1
+ -- : BFD_RELOC_TILEGX_DEST_IMM8_X1
+ -- : BFD_RELOC_TILEGX_MT_IMM14_X1
+ -- : BFD_RELOC_TILEGX_MF_IMM14_X1
+ -- : BFD_RELOC_TILEGX_MMSTART_X0
+ -- : BFD_RELOC_TILEGX_MMEND_X0
+ -- : BFD_RELOC_TILEGX_SHAMT_X0
+ -- : BFD_RELOC_TILEGX_SHAMT_X1
+ -- : BFD_RELOC_TILEGX_SHAMT_Y0
+ -- : BFD_RELOC_TILEGX_SHAMT_Y1
+ -- : BFD_RELOC_TILEGX_IMM16_X0_HW0
+ -- : BFD_RELOC_TILEGX_IMM16_X1_HW0
+ -- : BFD_RELOC_TILEGX_IMM16_X0_HW1
+ -- : BFD_RELOC_TILEGX_IMM16_X1_HW1
+ -- : BFD_RELOC_TILEGX_IMM16_X0_HW2
+ -- : BFD_RELOC_TILEGX_IMM16_X1_HW2
+ -- : BFD_RELOC_TILEGX_IMM16_X0_HW3
+ -- : BFD_RELOC_TILEGX_IMM16_X1_HW3
+ -- : BFD_RELOC_TILEGX_IMM16_X0_HW0_LAST
+ -- : BFD_RELOC_TILEGX_IMM16_X1_HW0_LAST
+ -- : BFD_RELOC_TILEGX_IMM16_X0_HW1_LAST
+ -- : BFD_RELOC_TILEGX_IMM16_X1_HW1_LAST
+ -- : BFD_RELOC_TILEGX_IMM16_X0_HW2_LAST
+ -- : BFD_RELOC_TILEGX_IMM16_X1_HW2_LAST
+ -- : BFD_RELOC_TILEGX_IMM16_X0_HW0_PCREL
+ -- : BFD_RELOC_TILEGX_IMM16_X1_HW0_PCREL
+ -- : BFD_RELOC_TILEGX_IMM16_X0_HW1_PCREL
+ -- : BFD_RELOC_TILEGX_IMM16_X1_HW1_PCREL
+ -- : BFD_RELOC_TILEGX_IMM16_X0_HW2_PCREL
+ -- : BFD_RELOC_TILEGX_IMM16_X1_HW2_PCREL
+ -- : BFD_RELOC_TILEGX_IMM16_X0_HW3_PCREL
+ -- : BFD_RELOC_TILEGX_IMM16_X1_HW3_PCREL
+ -- : BFD_RELOC_TILEGX_IMM16_X0_HW0_LAST_PCREL
+ -- : BFD_RELOC_TILEGX_IMM16_X1_HW0_LAST_PCREL
+ -- : BFD_RELOC_TILEGX_IMM16_X0_HW1_LAST_PCREL
+ -- : BFD_RELOC_TILEGX_IMM16_X1_HW1_LAST_PCREL
+ -- : BFD_RELOC_TILEGX_IMM16_X0_HW2_LAST_PCREL
+ -- : BFD_RELOC_TILEGX_IMM16_X1_HW2_LAST_PCREL
+ -- : BFD_RELOC_TILEGX_IMM16_X0_HW0_GOT
+ -- : BFD_RELOC_TILEGX_IMM16_X1_HW0_GOT
+ -- : BFD_RELOC_TILEGX_IMM16_X0_HW0_PLT_PCREL
+ -- : BFD_RELOC_TILEGX_IMM16_X1_HW0_PLT_PCREL
+ -- : BFD_RELOC_TILEGX_IMM16_X0_HW1_PLT_PCREL
+ -- : BFD_RELOC_TILEGX_IMM16_X1_HW1_PLT_PCREL
+ -- : BFD_RELOC_TILEGX_IMM16_X0_HW2_PLT_PCREL
+ -- : BFD_RELOC_TILEGX_IMM16_X1_HW2_PLT_PCREL
+ -- : BFD_RELOC_TILEGX_IMM16_X0_HW0_LAST_GOT
+ -- : BFD_RELOC_TILEGX_IMM16_X1_HW0_LAST_GOT
+ -- : BFD_RELOC_TILEGX_IMM16_X0_HW1_LAST_GOT
+ -- : BFD_RELOC_TILEGX_IMM16_X1_HW1_LAST_GOT
+ -- : BFD_RELOC_TILEGX_IMM16_X0_HW3_PLT_PCREL
+ -- : BFD_RELOC_TILEGX_IMM16_X1_HW3_PLT_PCREL
+ -- : BFD_RELOC_TILEGX_IMM16_X0_HW0_TLS_GD
+ -- : BFD_RELOC_TILEGX_IMM16_X1_HW0_TLS_GD
+ -- : BFD_RELOC_TILEGX_IMM16_X0_HW0_TLS_LE
+ -- : BFD_RELOC_TILEGX_IMM16_X1_HW0_TLS_LE
+ -- : BFD_RELOC_TILEGX_IMM16_X0_HW0_LAST_TLS_LE
+ -- : BFD_RELOC_TILEGX_IMM16_X1_HW0_LAST_TLS_LE
+ -- : BFD_RELOC_TILEGX_IMM16_X0_HW1_LAST_TLS_LE
+ -- : BFD_RELOC_TILEGX_IMM16_X1_HW1_LAST_TLS_LE
+ -- : BFD_RELOC_TILEGX_IMM16_X0_HW0_LAST_TLS_GD
+ -- : BFD_RELOC_TILEGX_IMM16_X1_HW0_LAST_TLS_GD
+ -- : BFD_RELOC_TILEGX_IMM16_X0_HW1_LAST_TLS_GD
+ -- : BFD_RELOC_TILEGX_IMM16_X1_HW1_LAST_TLS_GD
+ -- : BFD_RELOC_TILEGX_IMM16_X0_HW0_TLS_IE
+ -- : BFD_RELOC_TILEGX_IMM16_X1_HW0_TLS_IE
+ -- : BFD_RELOC_TILEGX_IMM16_X0_HW0_LAST_PLT_PCREL
+ -- : BFD_RELOC_TILEGX_IMM16_X1_HW0_LAST_PLT_PCREL
+ -- : BFD_RELOC_TILEGX_IMM16_X0_HW1_LAST_PLT_PCREL
+ -- : BFD_RELOC_TILEGX_IMM16_X1_HW1_LAST_PLT_PCREL
+ -- : BFD_RELOC_TILEGX_IMM16_X0_HW2_LAST_PLT_PCREL
+ -- : BFD_RELOC_TILEGX_IMM16_X1_HW2_LAST_PLT_PCREL
+ -- : BFD_RELOC_TILEGX_IMM16_X0_HW0_LAST_TLS_IE
+ -- : BFD_RELOC_TILEGX_IMM16_X1_HW0_LAST_TLS_IE
+ -- : BFD_RELOC_TILEGX_IMM16_X0_HW1_LAST_TLS_IE
+ -- : BFD_RELOC_TILEGX_IMM16_X1_HW1_LAST_TLS_IE
+ -- : BFD_RELOC_TILEGX_TLS_DTPMOD64
+ -- : BFD_RELOC_TILEGX_TLS_DTPOFF64
+ -- : BFD_RELOC_TILEGX_TLS_TPOFF64
+ -- : BFD_RELOC_TILEGX_TLS_DTPMOD32
+ -- : BFD_RELOC_TILEGX_TLS_DTPOFF32
+ -- : BFD_RELOC_TILEGX_TLS_TPOFF32
+ -- : BFD_RELOC_TILEGX_TLS_GD_CALL
+ -- : BFD_RELOC_TILEGX_IMM8_X0_TLS_GD_ADD
+ -- : BFD_RELOC_TILEGX_IMM8_X1_TLS_GD_ADD
+ -- : BFD_RELOC_TILEGX_IMM8_Y0_TLS_GD_ADD
+ -- : BFD_RELOC_TILEGX_IMM8_Y1_TLS_GD_ADD
+ -- : BFD_RELOC_TILEGX_TLS_IE_LOAD
+ -- : BFD_RELOC_TILEGX_IMM8_X0_TLS_ADD
+ -- : BFD_RELOC_TILEGX_IMM8_X1_TLS_ADD
+ -- : BFD_RELOC_TILEGX_IMM8_Y0_TLS_ADD
+ -- : BFD_RELOC_TILEGX_IMM8_Y1_TLS_ADD
+ Tilera TILE-Gx Relocations.
+
+ -- : BFD_RELOC_EPIPHANY_SIMM8
+ Adapteva EPIPHANY - 8 bit signed pc-relative displacement
+
+ -- : BFD_RELOC_EPIPHANY_SIMM24
+ Adapteva EPIPHANY - 24 bit signed pc-relative displacement
+
+ -- : BFD_RELOC_EPIPHANY_HIGH
+ Adapteva EPIPHANY - 16 most-significant bits of absolute address
+
+ -- : BFD_RELOC_EPIPHANY_LOW
+ Adapteva EPIPHANY - 16 least-significant bits of absolute address
+
+ -- : BFD_RELOC_EPIPHANY_SIMM11
+ Adapteva EPIPHANY - 11 bit signed number - add/sub immediate
+
+ -- : BFD_RELOC_EPIPHANY_IMM11
+ Adapteva EPIPHANY - 11 bit sign-magnitude number (ld/st
+ displacement)
+
+ -- : BFD_RELOC_EPIPHANY_IMM8
+ Adapteva EPIPHANY - 8 bit immediate for 16 bit mov instruction.
+
+
+ typedef enum bfd_reloc_code_real bfd_reloc_code_real_type;
+
+2.10.2.2 `bfd_reloc_type_lookup'
+................................
+
+*Synopsis*
+ reloc_howto_type *bfd_reloc_type_lookup
+ (bfd *abfd, bfd_reloc_code_real_type code);
+ reloc_howto_type *bfd_reloc_name_lookup
+ (bfd *abfd, const char *reloc_name);
+ *Description*
+Return a pointer to a howto structure which, when invoked, will perform
+the relocation CODE on data from the architecture noted.
+
+2.10.2.3 `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.
+
+2.10.2.4 `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.
+
+2.10.2.5 `bfd_generic_relax_section'
+....................................
+
+*Synopsis*
+ bfd_boolean bfd_generic_relax_section
+ (bfd *abfd,
+ asection *section,
+ struct bfd_link_info *,
+ bfd_boolean *);
+ *Description*
+Provides default handling for relaxing for back ends which don't do
+relaxing.
+
+2.10.2.6 `bfd_generic_gc_sections'
+..................................
+
+*Synopsis*
+ bfd_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.
+
+2.10.2.7 `bfd_generic_lookup_section_flags'
+...........................................
+
+*Synopsis*
+ bfd_boolean bfd_generic_lookup_section_flags
+ (struct bfd_link_info *, struct flag_info *, asection *);
+ *Description*
+Provides default handling for section flags lookup - i.e., does nothing.
+Returns FALSE if the section should be omitted, otherwise TRUE.
+
+2.10.2.8 `bfd_generic_merge_sections'
+.....................................
+
+*Synopsis*
+ bfd_boolean bfd_generic_merge_sections
+ (bfd *, struct bfd_link_info *);
+ *Description*
+Provides default handling for SEC_MERGE section merging for back ends
+which don't have SEC_MERGE support - i.e., does nothing.
+
+2.10.2.9 `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,
+ bfd_boolean relocatable,
+ asymbol **symbols);
+ *Description*
+Provides default handling of relocation effort for back ends which
+can't be bothered to do it efficiently.
+
+
+File: bfd.info, Node: Core Files, Next: Targets, Prev: Relocations, Up: BFD front end
+
+2.11 Core files
+===============
+
+2.11.1 Core file functions
+--------------------------
+
+*Description*
+These are functions pertaining to core files.
+
+2.11.1.1 `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 ABFD.
+
+2.11.1.2 `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 ABFD is attached to.
+
+2.11.1.3 `bfd_core_file_pid'
+............................
+
+*Synopsis*
+ int bfd_core_file_pid (bfd *abfd);
+ *Description*
+Returns the PID of the process the core dump the BFD ABFD is attached
+to was generated from.
+
+2.11.1.4 `core_file_matches_executable_p'
+.........................................
+
+*Synopsis*
+ bfd_boolean core_file_matches_executable_p
+ (bfd *core_bfd, bfd *exec_bfd);
+ *Description*
+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.
+
+2.11.1.5 `generic_core_file_matches_executable_p'
+.................................................
+
+*Synopsis*
+ bfd_boolean generic_core_file_matches_executable_p
+ (bfd *core_bfd, bfd *exec_bfd);
+ *Description*
+Return TRUE if the core file attached to CORE_BFD was generated by a
+run of the executable file attached to EXEC_BFD. The match is based on
+executable basenames only.
+
+ Note: When not able to determine the core file failing command or
+the executable name, we still return TRUE even though we're not sure
+that core file and executable match. This is to avoid generating a
+false warning in situations where we really don't know whether they
+match or not.
+
+
+File: bfd.info, Node: Targets, Next: Architectures, Prev: Core Files, Up: BFD front end
+
+2.12 Targets
+============
+
+*Description*
+Each port of BFD to a different machine requires 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:
+
+ * 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.
+
+ * If a null target string was provided to `bfd_find_target', look up
+ the environment variable `GNUTARGET' and use that as the target
+ string.
+
+ * 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. *Note
+ bfd_target::. *Note Formats::.
+
+ * Otherwise, inspect the elements in the target vector one by one,
+ until a match on target name is found. When found, use it.
+
+ * Otherwise return the error `bfd_error_invalid_target' to
+ `bfd_openr'.
+
+ * `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::
+
+
+File: bfd.info, Node: bfd_target, Prev: Targets, Up: Targets
+
+2.12.1 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 `bfd.h', and are also used when calling various routines by hand
+inside the BFD implementation. The 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_xcoff_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_verilog_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,
+ bfd_target_mmo_flavour,
+ bfd_target_mach_o_flavour,
+ bfd_target_pef_flavour,
+ bfd_target_pef_xlib_flavour,
+ bfd_target_sym_flavour
+ };
+
+ enum bfd_endian { BFD_ENDIAN_BIG, BFD_ENDIAN_LITTLE, BFD_ENDIAN_UNKNOWN };
+
+ /* Forward declaration. */
+ typedef struct bfd_link_info _bfd_link_info;
+
+ /* Forward declaration. */
+ typedef struct flag_info flag_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 char ar_max_namelen;
+
+ /* How well this target matches, used to select between various
+ possible targets when more than one target matches. */
+ unsigned char match_priority;
+
+ /* Entries for byte swapping for data. These are different from the
+ other entry points, since they don't take a BFD as the first argument.
+ Certain other handlers could do the same. */
+ bfd_uint64_t (*bfd_getx64) (const void *);
+ bfd_int64_t (*bfd_getx_signed_64) (const void *);
+ void (*bfd_putx64) (bfd_uint64_t, void *);
+ bfd_vma (*bfd_getx32) (const void *);
+ bfd_signed_vma (*bfd_getx_signed_32) (const void *);
+ void (*bfd_putx32) (bfd_vma, void *);
+ bfd_vma (*bfd_getx16) (const void *);
+ bfd_signed_vma (*bfd_getx_signed_16) (const void *);
+ void (*bfd_putx16) (bfd_vma, void *);
+
+ /* Byte swapping for the headers. */
+ bfd_uint64_t (*bfd_h_getx64) (const void *);
+ bfd_int64_t (*bfd_h_getx_signed_64) (const void *);
+ void (*bfd_h_putx64) (bfd_uint64_t, void *);
+ bfd_vma (*bfd_h_getx32) (const void *);
+ bfd_signed_vma (*bfd_h_getx_signed_32) (const void *);
+ void (*bfd_h_putx32) (bfd_vma, void *);
+ bfd_vma (*bfd_h_getx16) (const void *);
+ bfd_signed_vma (*bfd_h_getx_signed_16) (const void *);
+ void (*bfd_h_putx16) (bfd_vma, void *);
+
+ /* 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]) (bfd *);
+
+ /* Set the format of a file being written. */
+ bfd_boolean (*_bfd_set_format[bfd_type_end]) (bfd *);
+
+ /* Write cached information into a file being written, at `bfd_close'. */
+ bfd_boolean (*_bfd_write_contents[bfd_type_end]) (bfd *);
+ The general target vector. These vectors are initialized using the
+BFD_JUMP_TABLE macros.
+
+ /* Generic entry points. */
+ #define BFD_JUMP_TABLE_GENERIC(NAME) \
+ NAME##_close_and_cleanup, \
+ NAME##_bfd_free_cached_info, \
+ NAME##_new_section_hook, \
+ NAME##_get_section_contents, \
+ NAME##_get_section_contents_in_window
+
+ /* Called when the BFD is being closed to do any necessary cleanup. */
+ bfd_boolean (*_close_and_cleanup) (bfd *);
+ /* Ask the BFD to free all cached information. */
+ bfd_boolean (*_bfd_free_cached_info) (bfd *);
+ /* Called when a new section is created. */
+ bfd_boolean (*_new_section_hook) (bfd *, sec_ptr);
+ /* Read the contents of a section. */
+ bfd_boolean (*_bfd_get_section_contents)
+ (bfd *, sec_ptr, void *, file_ptr, bfd_size_type);
+ bfd_boolean (*_bfd_get_section_contents_in_window)
+ (bfd *, sec_ptr, bfd_window *, file_ptr, bfd_size_type);
+
+ /* Entry points to copy private data. */
+ #define BFD_JUMP_TABLE_COPY(NAME) \
+ NAME##_bfd_copy_private_bfd_data, \
+ NAME##_bfd_merge_private_bfd_data, \
+ _bfd_generic_init_private_section_data, \
+ NAME##_bfd_copy_private_section_data, \
+ NAME##_bfd_copy_private_symbol_data, \
+ NAME##_bfd_copy_private_header_data, \
+ NAME##_bfd_set_private_flags, \
+ NAME##_bfd_print_private_bfd_data
+
+ /* Called to copy BFD general private data from one object file
+ to another. */
+ bfd_boolean (*_bfd_copy_private_bfd_data) (bfd *, bfd *);
+ /* Called to merge BFD general private data from one object file
+ to a common output file when linking. */
+ bfd_boolean (*_bfd_merge_private_bfd_data) (bfd *, bfd *);
+ /* Called to initialize BFD private section data from one object file
+ to another. */
+ #define bfd_init_private_section_data(ibfd, isec, obfd, osec, link_info) \
+ BFD_SEND (obfd, _bfd_init_private_section_data, (ibfd, isec, obfd, osec, link_info))
+ bfd_boolean (*_bfd_init_private_section_data)
+ (bfd *, sec_ptr, bfd *, sec_ptr, struct bfd_link_info *);
+ /* Called to copy BFD private section data from one object file
+ to another. */
+ bfd_boolean (*_bfd_copy_private_section_data)
+ (bfd *, sec_ptr, bfd *, sec_ptr);
+ /* Called to copy BFD private symbol data from one symbol
+ to another. */
+ bfd_boolean (*_bfd_copy_private_symbol_data)
+ (bfd *, asymbol *, bfd *, asymbol *);
+ /* Called to copy BFD private header data from one object file
+ to another. */
+ bfd_boolean (*_bfd_copy_private_header_data)
+ (bfd *, bfd *);
+ /* Called to set private backend flags. */
+ bfd_boolean (*_bfd_set_private_flags) (bfd *, flagword);
+
+ /* Called to print private BFD data. */
+ bfd_boolean (*_bfd_print_private_bfd_data) (bfd *, void *);
+
+ /* Core file entry points. */
+ #define BFD_JUMP_TABLE_CORE(NAME) \
+ NAME##_core_file_failing_command, \
+ NAME##_core_file_failing_signal, \
+ NAME##_core_file_matches_executable_p, \
+ NAME##_core_file_pid
+
+ char * (*_core_file_failing_command) (bfd *);
+ int (*_core_file_failing_signal) (bfd *);
+ bfd_boolean (*_core_file_matches_executable_p) (bfd *, bfd *);
+ int (*_core_file_pid) (bfd *);
+
+ /* Archive entry points. */
+ #define BFD_JUMP_TABLE_ARCHIVE(NAME) \
+ NAME##_slurp_armap, \
+ NAME##_slurp_extended_name_table, \
+ NAME##_construct_extended_name_table, \
+ NAME##_truncate_arname, \
+ NAME##_write_armap, \
+ NAME##_read_ar_hdr, \
+ NAME##_write_ar_hdr, \
+ NAME##_openr_next_archived_file, \
+ NAME##_get_elt_at_index, \
+ NAME##_generic_stat_arch_elt, \
+ NAME##_update_armap_timestamp
+
+ bfd_boolean (*_bfd_slurp_armap) (bfd *);
+ bfd_boolean (*_bfd_slurp_extended_name_table) (bfd *);
+ bfd_boolean (*_bfd_construct_extended_name_table)
+ (bfd *, char **, bfd_size_type *, const char **);
+ void (*_bfd_truncate_arname) (bfd *, const char *, char *);
+ bfd_boolean (*write_armap)
+ (bfd *, unsigned int, struct orl *, unsigned int, int);
+ void * (*_bfd_read_ar_hdr_fn) (bfd *);
+ bfd_boolean (*_bfd_write_ar_hdr_fn) (bfd *, bfd *);
+ bfd * (*openr_next_archived_file) (bfd *, bfd *);
+ #define bfd_get_elt_at_index(b,i) BFD_SEND (b, _bfd_get_elt_at_index, (b,i))
+ bfd * (*_bfd_get_elt_at_index) (bfd *, symindex);
+ int (*_bfd_stat_arch_elt) (bfd *, struct stat *);
+ bfd_boolean (*_bfd_update_armap_timestamp) (bfd *);
+
+ /* Entry points used for symbols. */
+ #define BFD_JUMP_TABLE_SYMBOLS(NAME) \
+ NAME##_get_symtab_upper_bound, \
+ NAME##_canonicalize_symtab, \
+ NAME##_make_empty_symbol, \
+ NAME##_print_symbol, \
+ NAME##_get_symbol_info, \
+ NAME##_bfd_is_local_label_name, \
+ NAME##_bfd_is_target_special_symbol, \
+ NAME##_get_lineno, \
+ NAME##_find_nearest_line, \
+ NAME##_find_line, \
+ NAME##_find_inliner_info, \
+ NAME##_bfd_make_debug_symbol, \
+ NAME##_read_minisymbols, \
+ NAME##_minisymbol_to_symbol
+
+ long (*_bfd_get_symtab_upper_bound) (bfd *);
+ long (*_bfd_canonicalize_symtab)
+ (bfd *, struct bfd_symbol **);
+ struct bfd_symbol *
+ (*_bfd_make_empty_symbol) (bfd *);
+ void (*_bfd_print_symbol)
+ (bfd *, void *, struct bfd_symbol *, 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)
+ (bfd *, struct bfd_symbol *, symbol_info *);
+ #define bfd_get_symbol_info(b,p,e) BFD_SEND (b, _bfd_get_symbol_info, (b,p,e))
+ bfd_boolean (*_bfd_is_local_label_name) (bfd *, const char *);
+ bfd_boolean (*_bfd_is_target_special_symbol) (bfd *, asymbol *);
+ alent * (*_get_lineno) (bfd *, struct bfd_symbol *);
+ bfd_boolean (*_bfd_find_nearest_line)
+ (bfd *, struct bfd_symbol **, struct bfd_section *, bfd_vma,
+ const char **, const char **, unsigned int *, unsigned int *);
+ bfd_boolean (*_bfd_find_line)
+ (bfd *, struct bfd_symbol **, struct bfd_symbol *,
+ const char **, unsigned int *);
+ bfd_boolean (*_bfd_find_inliner_info)
+ (bfd *, const char **, const char **, unsigned int *);
+ /* 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)
+ (bfd *, void *, unsigned long size);
+ #define bfd_read_minisymbols(b, d, m, s) \
+ BFD_SEND (b, _read_minisymbols, (b, d, m, s))
+ long (*_read_minisymbols)
+ (bfd *, bfd_boolean, void **, 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)
+ (bfd *, bfd_boolean, const void *, asymbol *);
+
+ /* Routines for relocs. */
+ #define BFD_JUMP_TABLE_RELOCS(NAME) \
+ NAME##_get_reloc_upper_bound, \
+ NAME##_canonicalize_reloc, \
+ NAME##_bfd_reloc_type_lookup, \
+ NAME##_bfd_reloc_name_lookup
+
+ long (*_get_reloc_upper_bound) (bfd *, sec_ptr);
+ long (*_bfd_canonicalize_reloc)
+ (bfd *, sec_ptr, arelent **, struct bfd_symbol **);
+ /* See documentation on reloc types. */
+ reloc_howto_type *
+ (*reloc_type_lookup) (bfd *, bfd_reloc_code_real_type);
+ reloc_howto_type *
+ (*reloc_name_lookup) (bfd *, const char *);
+
+
+ /* Routines used when writing an object file. */
+ #define BFD_JUMP_TABLE_WRITE(NAME) \
+ NAME##_set_arch_mach, \
+ NAME##_set_section_contents
+
+ bfd_boolean (*_bfd_set_arch_mach)
+ (bfd *, enum bfd_architecture, unsigned long);
+ bfd_boolean (*_bfd_set_section_contents)
+ (bfd *, sec_ptr, const void *, file_ptr, bfd_size_type);
+
+ /* Routines used by the linker. */
+ #define BFD_JUMP_TABLE_LINK(NAME) \
+ NAME##_sizeof_headers, \
+ NAME##_bfd_get_relocated_section_contents, \
+ NAME##_bfd_relax_section, \
+ NAME##_bfd_link_hash_table_create, \
+ NAME##_bfd_link_add_symbols, \
+ NAME##_bfd_link_just_syms, \
+ NAME##_bfd_copy_link_hash_symbol_type, \
+ NAME##_bfd_final_link, \
+ NAME##_bfd_link_split_section, \
+ NAME##_bfd_gc_sections, \
+ NAME##_bfd_lookup_section_flags, \
+ NAME##_bfd_merge_sections, \
+ NAME##_bfd_is_group_section, \
+ NAME##_bfd_discard_group, \
+ NAME##_section_already_linked, \
+ NAME##_bfd_define_common_symbol
+
+ int (*_bfd_sizeof_headers) (bfd *, struct bfd_link_info *);
+ bfd_byte * (*_bfd_get_relocated_section_contents)
+ (bfd *, struct bfd_link_info *, struct bfd_link_order *,
+ bfd_byte *, bfd_boolean, struct bfd_symbol **);
+
+ bfd_boolean (*_bfd_relax_section)
+ (bfd *, struct bfd_section *, struct bfd_link_info *, bfd_boolean *);
+
+ /* 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) (bfd *);
+
+ /* Add symbols from this object file into the hash table. */
+ bfd_boolean (*_bfd_link_add_symbols) (bfd *, struct bfd_link_info *);
+
+ /* Indicate that we are only retrieving symbol values from this section. */
+ void (*_bfd_link_just_syms) (asection *, struct bfd_link_info *);
+
+ /* Copy the symbol type and other attributes for a linker script
+ assignment of one symbol to another. */
+ #define bfd_copy_link_hash_symbol_type(b, t, f) \
+ BFD_SEND (b, _bfd_copy_link_hash_symbol_type, (b, t, f))
+ void (*_bfd_copy_link_hash_symbol_type)
+ (bfd *, struct bfd_link_hash_entry *, struct bfd_link_hash_entry *);
+
+ /* Do a link based on the link_order structures attached to each
+ section of the BFD. */
+ bfd_boolean (*_bfd_final_link) (bfd *, struct bfd_link_info *);
+
+ /* Should this section be split up into smaller pieces during linking. */
+ bfd_boolean (*_bfd_link_split_section) (bfd *, struct bfd_section *);
+
+ /* Remove sections that are not referenced from the output. */
+ bfd_boolean (*_bfd_gc_sections) (bfd *, struct bfd_link_info *);
+
+ /* Sets the bitmask of allowed and disallowed section flags. */
+ bfd_boolean (*_bfd_lookup_section_flags) (struct bfd_link_info *,
+ struct flag_info *,
+ asection *);
+
+ /* Attempt to merge SEC_MERGE sections. */
+ bfd_boolean (*_bfd_merge_sections) (bfd *, struct bfd_link_info *);
+
+ /* Is this section a member of a group? */
+ bfd_boolean (*_bfd_is_group_section) (bfd *, const struct bfd_section *);
+
+ /* Discard members of a group. */
+ bfd_boolean (*_bfd_discard_group) (bfd *, struct bfd_section *);
+
+ /* Check if SEC has been already linked during a reloceatable or
+ final link. */
+ bfd_boolean (*_section_already_linked) (bfd *, asection *,
+ struct bfd_link_info *);
+
+ /* Define a common symbol. */
+ bfd_boolean (*_bfd_define_common_symbol) (bfd *, struct bfd_link_info *,
+ struct bfd_link_hash_entry *);
+
+ /* Routines to handle dynamic symbols and relocs. */
+ #define BFD_JUMP_TABLE_DYNAMIC(NAME) \
+ NAME##_get_dynamic_symtab_upper_bound, \
+ NAME##_canonicalize_dynamic_symtab, \
+ NAME##_get_synthetic_symtab, \
+ NAME##_get_dynamic_reloc_upper_bound, \
+ NAME##_canonicalize_dynamic_reloc
+
+ /* Get the amount of memory required to hold the dynamic symbols. */
+ long (*_bfd_get_dynamic_symtab_upper_bound) (bfd *);
+ /* Read in the dynamic symbols. */
+ long (*_bfd_canonicalize_dynamic_symtab)
+ (bfd *, struct bfd_symbol **);
+ /* Create synthetized symbols. */
+ long (*_bfd_get_synthetic_symtab)
+ (bfd *, long, struct bfd_symbol **, long, struct bfd_symbol **,
+ struct bfd_symbol **);
+ /* Get the amount of memory required to hold the dynamic relocs. */
+ long (*_bfd_get_dynamic_reloc_upper_bound) (bfd *);
+ /* Read in the dynamic relocs. */
+ long (*_bfd_canonicalize_dynamic_reloc)
+ (bfd *, arelent **, struct bfd_symbol **);
+ A pointer to an alternative bfd_target in case the current one is not
+satisfactory. This can happen when the target cpu supports both big
+and little endian code, and target chosen by the linker has the wrong
+endianness. The function open_output() in ld/ldlang.c uses this field
+to find an alternative output format that is suitable.
+ /* Opposite endian version of this target. */
+ const struct bfd_target * alternative_target;
+
+ /* Data for use by back-end routines, which isn't
+ generic enough to belong in this structure. */
+ const void *backend_data;
+
+ } bfd_target;
+
+2.12.1.1 `bfd_set_default_target'
+.................................
+
+*Synopsis*
+ bfd_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.
+
+2.12.1.2 `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
+TARGET_NAME. If 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 if ABFD isn't `NULL'. This
+causes `bfd_check_format' to loop over all the targets to find the one
+that matches the file being read.
+
+2.12.1.3 `bfd_get_target_info'
+..............................
+
+*Synopsis*
+ const bfd_target *bfd_get_target_info (const char *target_name,
+ bfd *abfd,
+ bfd_boolean *is_bigendian,
+ int *underscoring,
+ const char **def_target_arch);
+ *Description*
+Return a pointer to the transfer vector for the object target named
+TARGET_NAME. If 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 if ABFD isn't `NULL'. This
+causes `bfd_check_format' to loop over all the targets to find the one
+that matches the file being read. If IS_BIGENDIAN is not `NULL', then
+set this value to target's endian mode. True for big-endian, FALSE for
+little-endian or for invalid target. If UNDERSCORING is not `NULL',
+then set this value to target's underscoring mode. Zero for
+none-underscoring, -1 for invalid target, else the value of target
+vector's symbol underscoring. If DEF_TARGET_ARCH is not `NULL', then
+set it to the architecture string specified by the target_name.
+
+2.12.1.4 `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.
+
+2.12.1.5 `bfd_seach_for_target'
+...............................
+
+*Synopsis*
+ const bfd_target *bfd_search_for_target
+ (int (*search_func) (const bfd_target *, void *),
+ void *);
+ *Description*
+Return a pointer to the first transfer vector in the list of transfer
+vectors maintained by BFD that produces a non-zero result when passed
+to the function SEARCH_FUNC. The parameter DATA is passed, unexamined,
+to the search function.
+
+
+File: bfd.info, Node: Architectures, Next: Opening and Closing, Prev: Targets, Up: BFD front end
+
+2.13 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
+`config/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 `archures.c'.
+
+2.13.1 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
+ #define bfd_mach_fido 9
+ #define bfd_mach_mcf_isa_a_nodiv 10
+ #define bfd_mach_mcf_isa_a 11
+ #define bfd_mach_mcf_isa_a_mac 12
+ #define bfd_mach_mcf_isa_a_emac 13
+ #define bfd_mach_mcf_isa_aplus 14
+ #define bfd_mach_mcf_isa_aplus_mac 15
+ #define bfd_mach_mcf_isa_aplus_emac 16
+ #define bfd_mach_mcf_isa_b_nousp 17
+ #define bfd_mach_mcf_isa_b_nousp_mac 18
+ #define bfd_mach_mcf_isa_b_nousp_emac 19
+ #define bfd_mach_mcf_isa_b 20
+ #define bfd_mach_mcf_isa_b_mac 21
+ #define bfd_mach_mcf_isa_b_emac 22
+ #define bfd_mach_mcf_isa_b_float 23
+ #define bfd_mach_mcf_isa_b_float_mac 24
+ #define bfd_mach_mcf_isa_b_float_emac 25
+ #define bfd_mach_mcf_isa_c 26
+ #define bfd_mach_mcf_isa_c_mac 27
+ #define bfd_mach_mcf_isa_c_emac 28
+ #define bfd_mach_mcf_isa_c_nodiv 29
+ #define bfd_mach_mcf_isa_c_nodiv_mac 30
+ #define bfd_mach_mcf_isa_c_nodiv_emac 31
+ 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_or1k, /* OpenRISC 1000 */
+ #define bfd_mach_or1k 1
+ #define bfd_mach_or1knd 2
+
+ 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. */
+ #define bfd_mach_sparc_v8plusb 9 /* with cheetah add'ns. */
+ #define bfd_mach_sparc_v9b 10 /* with cheetah 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_v9b \
+ && (mach) != bfd_mach_sparc_sparclite_le)
+ /* Nonzero if MACH is a 64 bit sparc architecture. */
+ #define bfd_mach_sparc_64bit_p(mach) \
+ ((mach) >= bfd_mach_sparc_v9 && (mach) != bfd_mach_sparc_v8plusb)
+ bfd_arch_spu, /* PowerPC SPU */
+ #define bfd_mach_spu 256
+ 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_mips4120 4120
+ #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_mips5400 5400
+ #define bfd_mach_mips5500 5500
+ #define bfd_mach_mips5900 5900
+ #define bfd_mach_mips6000 6000
+ #define bfd_mach_mips7000 7000
+ #define bfd_mach_mips8000 8000
+ #define bfd_mach_mips9000 9000
+ #define bfd_mach_mips10000 10000
+ #define bfd_mach_mips12000 12000
+ #define bfd_mach_mips14000 14000
+ #define bfd_mach_mips16000 16000
+ #define bfd_mach_mips16 16
+ #define bfd_mach_mips5 5
+ #define bfd_mach_mips_loongson_2e 3001
+ #define bfd_mach_mips_loongson_2f 3002
+ #define bfd_mach_mips_loongson_3a 3003
+ #define bfd_mach_mips_sb1 12310201 /* octal 'SB', 01 */
+ #define bfd_mach_mips_octeon 6501
+ #define bfd_mach_mips_octeonp 6601
+ #define bfd_mach_mips_octeon2 6502
+ #define bfd_mach_mips_xlr 887682 /* decimal 'XLR' */
+ #define bfd_mach_mipsisa32 32
+ #define bfd_mach_mipsisa32r2 33
+ #define bfd_mach_mipsisa32r3 34
+ #define bfd_mach_mipsisa32r5 36
+ #define bfd_mach_mipsisa32r6 37
+ #define bfd_mach_mipsisa64 64
+ #define bfd_mach_mipsisa64r2 65
+ #define bfd_mach_mipsisa64r3 66
+ #define bfd_mach_mipsisa64r5 68
+ #define bfd_mach_mipsisa64r6 69
+ #define bfd_mach_mips_micromips 96
+ bfd_arch_i386, /* Intel 386 */
+ #define bfd_mach_i386_intel_syntax (1 << 0)
+ #define bfd_mach_i386_i8086 (1 << 1)
+ #define bfd_mach_i386_i386 (1 << 2)
+ #define bfd_mach_x86_64 (1 << 3)
+ #define bfd_mach_x64_32 (1 << 4)
+ #define bfd_mach_i386_i386_intel_syntax (bfd_mach_i386_i386 | bfd_mach_i386_intel_syntax)
+ #define bfd_mach_x86_64_intel_syntax (bfd_mach_x86_64 | bfd_mach_i386_intel_syntax)
+ #define bfd_mach_x64_32_intel_syntax (bfd_mach_x64_32 | bfd_mach_i386_intel_syntax)
+ bfd_arch_l1om, /* Intel L1OM */
+ #define bfd_mach_l1om (1 << 5)
+ #define bfd_mach_l1om_intel_syntax (bfd_mach_l1om | bfd_mach_i386_intel_syntax)
+ bfd_arch_k1om, /* Intel K1OM */
+ #define bfd_mach_k1om (1 << 6)
+ #define bfd_mach_k1om_intel_syntax (bfd_mach_k1om | bfd_mach_i386_intel_syntax)
+ #define bfd_mach_i386_nacl (1 << 7)
+ #define bfd_mach_i386_i386_nacl (bfd_mach_i386_i386 | bfd_mach_i386_nacl)
+ #define bfd_mach_x86_64_nacl (bfd_mach_x86_64 | bfd_mach_i386_nacl)
+ #define bfd_mach_x64_32_nacl (bfd_mach_x64_32 | bfd_mach_i386_nacl)
+ bfd_arch_we32k, /* AT&T WE32xxx */
+ bfd_arch_tahoe, /* CCI/Harris Tahoe */
+ bfd_arch_i860, /* Intel 860 */
+ bfd_arch_i370, /* IBM 360/370 Mainframes */
+ bfd_arch_romp, /* IBM ROMP PC/RT */
+ bfd_arch_convex, /* Convex */
+ bfd_arch_m88k, /* Motorola 88xxx */
+ bfd_arch_m98k, /* Motorola 98xxx */
+ bfd_arch_pyramid, /* Pyramid Technology */
+ bfd_arch_h8300, /* Renesas H8/300 (formerly Hitachi H8/300) */
+ #define bfd_mach_h8300 1
+ #define bfd_mach_h8300h 2
+ #define bfd_mach_h8300s 3
+ #define bfd_mach_h8300hn 4
+ #define bfd_mach_h8300sn 5
+ #define bfd_mach_h8300sx 6
+ #define bfd_mach_h8300sxn 7
+ bfd_arch_pdp11, /* DEC PDP-11 */
+ bfd_arch_plugin,
+ bfd_arch_powerpc, /* PowerPC */
+ #define bfd_mach_ppc 32
+ #define bfd_mach_ppc64 64
+ #define bfd_mach_ppc_403 403
+ #define bfd_mach_ppc_403gc 4030
+ #define bfd_mach_ppc_405 405
+ #define bfd_mach_ppc_505 505
+ #define bfd_mach_ppc_601 601
+ #define bfd_mach_ppc_602 602
+ #define bfd_mach_ppc_603 603
+ #define bfd_mach_ppc_ec603e 6031
+ #define bfd_mach_ppc_604 604
+ #define bfd_mach_ppc_620 620
+ #define bfd_mach_ppc_630 630
+ #define bfd_mach_ppc_750 750
+ #define bfd_mach_ppc_860 860
+ #define bfd_mach_ppc_a35 35
+ #define bfd_mach_ppc_rs64ii 642
+ #define bfd_mach_ppc_rs64iii 643
+ #define bfd_mach_ppc_7400 7400
+ #define bfd_mach_ppc_e500 500
+ #define bfd_mach_ppc_e500mc 5001
+ #define bfd_mach_ppc_e500mc64 5005
+ #define bfd_mach_ppc_e5500 5006
+ #define bfd_mach_ppc_e6500 5007
+ #define bfd_mach_ppc_titan 83
+ #define bfd_mach_ppc_vle 84
+ bfd_arch_rs6000, /* IBM RS/6000 */
+ #define bfd_mach_rs6k 6000
+ #define bfd_mach_rs6k_rs1 6001
+ #define bfd_mach_rs6k_rsc 6003
+ #define bfd_mach_rs6k_rs2 6002
+ bfd_arch_hppa, /* HP PA RISC */
+ #define bfd_mach_hppa10 10
+ #define bfd_mach_hppa11 11
+ #define bfd_mach_hppa20 20
+ #define bfd_mach_hppa20w 25
+ bfd_arch_d10v, /* Mitsubishi D10V */
+ #define bfd_mach_d10v 1
+ #define bfd_mach_d10v_ts2 2
+ #define bfd_mach_d10v_ts3 3
+ bfd_arch_d30v, /* Mitsubishi D30V */
+ bfd_arch_dlx, /* DLX */
+ bfd_arch_m68hc11, /* Motorola 68HC11 */
+ bfd_arch_m68hc12, /* Motorola 68HC12 */
+ #define bfd_mach_m6812_default 0
+ #define bfd_mach_m6812 1
+ #define bfd_mach_m6812s 2
+ bfd_arch_m9s12x, /* Freescale S12X */
+ bfd_arch_m9s12xg, /* Freescale XGATE */
+ bfd_arch_z8k, /* Zilog Z8000 */
+ #define bfd_mach_z8001 1
+ #define bfd_mach_z8002 2
+ bfd_arch_h8500, /* Renesas H8/500 (formerly Hitachi H8/500) */
+ bfd_arch_sh, /* Renesas / SuperH SH (formerly Hitachi SH) */
+ #define bfd_mach_sh 1
+ #define bfd_mach_sh2 0x20
+ #define bfd_mach_sh_dsp 0x2d
+ #define bfd_mach_sh2a 0x2a
+ #define bfd_mach_sh2a_nofpu 0x2b
+ #define bfd_mach_sh2a_nofpu_or_sh4_nommu_nofpu 0x2a1
+ #define bfd_mach_sh2a_nofpu_or_sh3_nommu 0x2a2
+ #define bfd_mach_sh2a_or_sh4 0x2a3
+ #define bfd_mach_sh2a_or_sh3e 0x2a4
+ #define bfd_mach_sh2e 0x2e
+ #define bfd_mach_sh3 0x30
+ #define bfd_mach_sh3_nommu 0x31
+ #define bfd_mach_sh3_dsp 0x3d
+ #define bfd_mach_sh3e 0x3e
+ #define bfd_mach_sh4 0x40
+ #define bfd_mach_sh4_nofpu 0x41
+ #define bfd_mach_sh4_nommu_nofpu 0x42
+ #define bfd_mach_sh4a 0x4a
+ #define bfd_mach_sh4a_nofpu 0x4b
+ #define bfd_mach_sh4al_dsp 0x4d
+ #define bfd_mach_sh5 0x50
+ 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_unknown 0
+ #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
+ #define bfd_mach_arm_5 7
+ #define bfd_mach_arm_5T 8
+ #define bfd_mach_arm_5TE 9
+ #define bfd_mach_arm_XScale 10
+ #define bfd_mach_arm_ep9312 11
+ #define bfd_mach_arm_iWMMXt 12
+ #define bfd_mach_arm_iWMMXt2 13
+ bfd_arch_nds32, /* Andes NDS32 */
+ #define bfd_mach_n1 1
+ #define bfd_mach_n1h 2
+ #define bfd_mach_n1h_v2 3
+ #define bfd_mach_n1h_v3 4
+ #define bfd_mach_n1h_v3m 5
+ bfd_arch_ns32k, /* National Semiconductors ns32000 */
+ bfd_arch_w65, /* WDC 65816 */
+ bfd_arch_tic30, /* Texas Instruments TMS320C30 */
+ bfd_arch_tic4x, /* Texas Instruments TMS320C3X/4X */
+ #define bfd_mach_tic3x 30
+ #define bfd_mach_tic4x 40
+ bfd_arch_tic54x, /* Texas Instruments TMS320C54X */
+ bfd_arch_tic6x, /* Texas Instruments TMS320C6X */
+ bfd_arch_tic80, /* TI TMS320c80 (MVP) */
+ bfd_arch_v850, /* NEC V850 */
+ bfd_arch_v850_rh850,/* NEC V850 (using RH850 ABI) */
+ #define bfd_mach_v850 1
+ #define bfd_mach_v850e 'E'
+ #define bfd_mach_v850e1 '1'
+ #define bfd_mach_v850e2 0x4532
+ #define bfd_mach_v850e2v3 0x45325633
+ #define bfd_mach_v850e3v5 0x45335635 /* ('E'|'3'|'V'|'5') */
+ bfd_arch_arc, /* ARC Cores */
+ #define bfd_mach_arc_5 5
+ #define bfd_mach_arc_6 6
+ #define bfd_mach_arc_7 7
+ #define bfd_mach_arc_8 8
+ bfd_arch_m32c, /* Renesas M16C/M32C. */
+ #define bfd_mach_m16c 0x75
+ #define bfd_mach_m32c 0x78
+ bfd_arch_m32r, /* Renesas M32R (formerly Mitsubishi M32R/D) */
+ #define bfd_mach_m32r 1 /* For backwards compatibility. */
+ #define bfd_mach_m32rx 'x'
+ #define bfd_mach_m32r2 '2'
+ bfd_arch_mn10200, /* Matsushita MN10200 */
+ bfd_arch_mn10300, /* Matsushita MN10300 */
+ #define bfd_mach_mn10300 300
+ #define bfd_mach_am33 330
+ #define bfd_mach_am33_2 332
+ bfd_arch_fr30,
+ #define bfd_mach_fr30 0x46523330
+ bfd_arch_frv,
+ #define bfd_mach_frv 1
+ #define bfd_mach_frvsimple 2
+ #define bfd_mach_fr300 300
+ #define bfd_mach_fr400 400
+ #define bfd_mach_fr450 450
+ #define bfd_mach_frvtomcat 499 /* fr500 prototype */
+ #define bfd_mach_fr500 500
+ #define bfd_mach_fr550 550
+ bfd_arch_moxie, /* The moxie processor */
+ #define bfd_mach_moxie 1
+ bfd_arch_mcore,
+ bfd_arch_mep,
+ #define bfd_mach_mep 1
+ #define bfd_mach_mep_h1 0x6831
+ #define bfd_mach_mep_c5 0x6335
+ bfd_arch_metag,
+ #define bfd_mach_metag 1
+ bfd_arch_ia64, /* HP/Intel ia64 */
+ #define bfd_mach_ia64_elf64 64
+ #define bfd_mach_ia64_elf32 32
+ bfd_arch_ip2k, /* Ubicom IP2K microcontrollers. */
+ #define bfd_mach_ip2022 1
+ #define bfd_mach_ip2022ext 2
+ bfd_arch_iq2000, /* Vitesse IQ2000. */
+ #define bfd_mach_iq2000 1
+ #define bfd_mach_iq10 2
+ bfd_arch_epiphany, /* Adapteva EPIPHANY */
+ #define bfd_mach_epiphany16 1
+ #define bfd_mach_epiphany32 2
+ bfd_arch_mt,
+ #define bfd_mach_ms1 1
+ #define bfd_mach_mrisc2 2
+ #define bfd_mach_ms2 3
+ bfd_arch_pj,
+ bfd_arch_avr, /* Atmel AVR microcontrollers. */
+ #define bfd_mach_avr1 1
+ #define bfd_mach_avr2 2
+ #define bfd_mach_avr25 25
+ #define bfd_mach_avr3 3
+ #define bfd_mach_avr31 31
+ #define bfd_mach_avr35 35
+ #define bfd_mach_avr4 4
+ #define bfd_mach_avr5 5
+ #define bfd_mach_avr51 51
+ #define bfd_mach_avr6 6
+ #define bfd_mach_avrtiny 100
+ #define bfd_mach_avrxmega1 101
+ #define bfd_mach_avrxmega2 102
+ #define bfd_mach_avrxmega3 103
+ #define bfd_mach_avrxmega4 104
+ #define bfd_mach_avrxmega5 105
+ #define bfd_mach_avrxmega6 106
+ #define bfd_mach_avrxmega7 107
+ bfd_arch_bfin, /* ADI Blackfin */
+ #define bfd_mach_bfin 1
+ bfd_arch_cr16, /* National Semiconductor CompactRISC (ie CR16). */
+ #define bfd_mach_cr16 1
+ bfd_arch_cr16c, /* National Semiconductor CompactRISC. */
+ #define bfd_mach_cr16c 1
+ bfd_arch_crx, /* National Semiconductor CRX. */
+ #define bfd_mach_crx 1
+ bfd_arch_cris, /* Axis CRIS */
+ #define bfd_mach_cris_v0_v10 255
+ #define bfd_mach_cris_v32 32
+ #define bfd_mach_cris_v10_v32 1032
+ bfd_arch_rl78,
+ #define bfd_mach_rl78 0x75
+ bfd_arch_rx, /* Renesas RX. */
+ #define bfd_mach_rx 0x75
+ bfd_arch_s390, /* IBM s390 */
+ #define bfd_mach_s390_31 31
+ #define bfd_mach_s390_64 64
+ bfd_arch_score, /* Sunplus score */
+ #define bfd_mach_score3 3
+ #define bfd_mach_score7 7
+ bfd_arch_mmix, /* Donald Knuth's educational processor. */
+ bfd_arch_xstormy16,
+ #define bfd_mach_xstormy16 1
+ bfd_arch_msp430, /* Texas Instruments MSP430 architecture. */
+ #define bfd_mach_msp11 11
+ #define bfd_mach_msp110 110
+ #define bfd_mach_msp12 12
+ #define bfd_mach_msp13 13
+ #define bfd_mach_msp14 14
+ #define bfd_mach_msp15 15
+ #define bfd_mach_msp16 16
+ #define bfd_mach_msp20 20
+ #define bfd_mach_msp21 21
+ #define bfd_mach_msp22 22
+ #define bfd_mach_msp23 23
+ #define bfd_mach_msp24 24
+ #define bfd_mach_msp26 26
+ #define bfd_mach_msp31 31
+ #define bfd_mach_msp32 32
+ #define bfd_mach_msp33 33
+ #define bfd_mach_msp41 41
+ #define bfd_mach_msp42 42
+ #define bfd_mach_msp43 43
+ #define bfd_mach_msp44 44
+ #define bfd_mach_msp430x 45
+ #define bfd_mach_msp46 46
+ #define bfd_mach_msp47 47
+ #define bfd_mach_msp54 54
+ bfd_arch_xc16x, /* Infineon's XC16X Series. */
+ #define bfd_mach_xc16x 1
+ #define bfd_mach_xc16xl 2
+ #define bfd_mach_xc16xs 3
+ bfd_arch_xgate, /* Freescale XGATE */
+ #define bfd_mach_xgate 1
+ bfd_arch_xtensa, /* Tensilica's Xtensa cores. */
+ #define bfd_mach_xtensa 1
+ bfd_arch_z80,
+ #define bfd_mach_z80strict 1 /* No undocumented opcodes. */
+ #define bfd_mach_z80 3 /* With ixl, ixh, iyl, and iyh. */
+ #define bfd_mach_z80full 7 /* All undocumented instructions. */
+ #define bfd_mach_r800 11 /* R800: successor with multiplication. */
+ bfd_arch_lm32, /* Lattice Mico32 */
+ #define bfd_mach_lm32 1
+ bfd_arch_microblaze,/* Xilinx MicroBlaze. */
+ bfd_arch_tilepro, /* Tilera TILEPro */
+ bfd_arch_tilegx, /* Tilera TILE-Gx */
+ #define bfd_mach_tilepro 1
+ #define bfd_mach_tilegx 1
+ #define bfd_mach_tilegx32 2
+ bfd_arch_aarch64, /* AArch64 */
+ #define bfd_mach_aarch64 0
+ #define bfd_mach_aarch64_ilp32 32
+ bfd_arch_nios2,
+ #define bfd_mach_nios2 0
+ bfd_arch_last
+ };
+
+2.13.2 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.
+ The default arch should be the first entry for an arch so that
+ all the entries for that arch can be accessed via `next'. */
+ bfd_boolean the_default;
+ const struct bfd_arch_info * (*compatible)
+ (const struct bfd_arch_info *a, const struct bfd_arch_info *b);
+
+ bfd_boolean (*scan) (const struct bfd_arch_info *, const char *);
+
+ /* Allocate via bfd_malloc and return a fill buffer of size COUNT. If
+ IS_BIGENDIAN is TRUE, the order of bytes is big endian. If CODE is
+ TRUE, the buffer contains code. */
+ void *(*fill) (bfd_size_type count, bfd_boolean is_bigendian,
+ bfd_boolean code);
+
+ const struct bfd_arch_info *next;
+ }
+ bfd_arch_info_type;
+
+2.13.2.1 `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.
+
+2.13.2.2 `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 STRING. Return a pointer to an `arch_info' structure if a machine
+is found, otherwise NULL.
+
+2.13.2.3 `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.
+
+2.13.2.4 `bfd_arch_get_compatible'
+..................................
+
+*Synopsis*
+ const bfd_arch_info_type *bfd_arch_get_compatible
+ (const bfd *abfd, const bfd *bbfd, bfd_boolean accept_unknowns);
+ *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.
+
+2.13.2.5 `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;
+
+2.13.2.6 `bfd_set_arch_info'
+............................
+
+*Synopsis*
+ void bfd_set_arch_info (bfd *abfd, const bfd_arch_info_type *arg);
+ *Description*
+Set the architecture info of ABFD to ARG.
+
+2.13.2.7 `bfd_default_set_arch_mach'
+....................................
+
+*Synopsis*
+ bfd_boolean bfd_default_set_arch_mach
+ (bfd *abfd, enum bfd_architecture arch, unsigned long mach);
+ *Description*
+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.
+
+2.13.2.8 `bfd_get_arch'
+.......................
+
+*Synopsis*
+ enum bfd_architecture bfd_get_arch (bfd *abfd);
+ *Description*
+Return the enumerated type which describes the BFD ABFD's architecture.
+
+2.13.2.9 `bfd_get_mach'
+.......................
+
+*Synopsis*
+ unsigned long bfd_get_mach (bfd *abfd);
+ *Description*
+Return the long type which describes the BFD ABFD's machine.
+
+2.13.2.10 `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 ABFD's architecture's bytes.
+
+2.13.2.11 `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 ABFD's architecture's
+addresses.
+
+2.13.2.12 `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.
+
+2.13.2.13 `bfd_default_scan'
+............................
+
+*Synopsis*
+ bfd_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.
+
+2.13.2.14 `bfd_get_arch_info'
+.............................
+
+*Synopsis*
+ const bfd_arch_info_type *bfd_get_arch_info (bfd *abfd);
+ *Description*
+Return the architecture info struct in ABFD.
+
+2.13.2.15 `bfd_lookup_arch'
+...........................
+
+*Synopsis*
+ const bfd_arch_info_type *bfd_lookup_arch
+ (enum bfd_architecture arch, unsigned long machine);
+ *Description*
+Look for the architecture info structure which matches the arguments
+ARCH and MACHINE. A machine of 0 matches the machine/architecture
+structure which marks itself as the default.
+
+2.13.2.16 `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.
+
+2.13.2.17 `bfd_octets_per_byte'
+...............................
+
+*Synopsis*
+ unsigned int bfd_octets_per_byte (bfd *abfd);
+ *Description*
+Return the number of octets (8-bit quantities) per target byte (minimum
+addressable unit). In most cases, this will be one, but some DSP
+targets have 16, 32, or even 48 bits per byte.
+
+2.13.2.18 `bfd_arch_mach_octets_per_byte'
+.........................................
+
+*Synopsis*
+ unsigned int bfd_arch_mach_octets_per_byte
+ (enum bfd_architecture arch, unsigned long machine);
+ *Description*
+See bfd_octets_per_byte.
+
+ This routine is provided for those cases where a bfd * is not
+available
+
+2.13.2.19 `bfd_arch_default_fill'
+.................................
+
+*Synopsis*
+ void *bfd_arch_default_fill (bfd_size_type count,
+ bfd_boolean is_bigendian,
+ bfd_boolean code);
+ *Description*
+Allocate via bfd_malloc and return a fill buffer of size COUNT. If
+IS_BIGENDIAN is TRUE, the order of bytes is big endian. If CODE is
+TRUE, the buffer contains code.
+
+
+File: bfd.info, Node: Opening and Closing, Next: Internal, Prev: Architectures, Up: BFD front end
+
+ /* Set to N to open the next N BFDs using an alternate id space. */
+ extern unsigned int bfd_use_reserved_id;
+
+2.14 Opening and closing BFDs
+=============================
+
+2.14.1 Functions for opening and closing
+----------------------------------------
+
+2.14.1.1 `bfd_fopen'
+....................
+
+*Synopsis*
+ bfd *bfd_fopen (const char *filename, const char *target,
+ const char *mode, int fd);
+ *Description*
+Open the file FILENAME with the target TARGET. Return a pointer to the
+created BFD. If FD is not -1, then `fdopen' is used to open the file;
+otherwise, `fopen' is used. MODE is passed directly to `fopen' or
+`fdopen'.
+
+ Calls `bfd_find_target', so TARGET is interpreted as by that
+function.
+
+ The new BFD is marked as cacheable iff FD is -1.
+
+ If `NULL' is returned then an error has occured. Possible errors
+are `bfd_error_no_memory', `bfd_error_invalid_target' or `system_call'
+error.
+
+ On error, FD is always closed.
+
+ A copy of the FILENAME argument is stored in the newly created BFD.
+It can be accessed via the bfd_get_filename() macro.
+
+2.14.1.2 `bfd_openr'
+....................
+
+*Synopsis*
+ bfd *bfd_openr (const char *filename, const char *target);
+ *Description*
+Open the file FILENAME (using `fopen') with the target TARGET. Return
+a pointer to the created BFD.
+
+ Calls `bfd_find_target', so 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.
+
+ A copy of the FILENAME argument is stored in the newly created BFD.
+It can be accessed via the bfd_get_filename() macro.
+
+2.14.1.3 `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 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 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 caching; 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'.
+
+ On error, FD is closed.
+
+ A copy of the FILENAME argument is stored in the newly created BFD.
+It can be accessed via the bfd_get_filename() macro.
+
+2.14.1.4 `bfd_openstreamr'
+..........................
+
+*Synopsis*
+ bfd *bfd_openstreamr (const char * filename, const char * target, void * stream);
+ *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.
+
+ A copy of the FILENAME argument is stored in the newly created BFD.
+It can be accessed via the bfd_get_filename() macro.
+
+2.14.1.5 `bfd_openr_iovec'
+..........................
+
+*Synopsis*
+ bfd *bfd_openr_iovec (const char *filename, const char *target,
+ void *(*open_func) (struct bfd *nbfd,
+ void *open_closure),
+ void *open_closure,
+ file_ptr (*pread_func) (struct bfd *nbfd,
+ void *stream,
+ void *buf,
+ file_ptr nbytes,
+ file_ptr offset),
+ int (*close_func) (struct bfd *nbfd,
+ void *stream),
+ int (*stat_func) (struct bfd *abfd,
+ void *stream,
+ struct stat *sb));
+ *Description*
+Create and return a BFD backed by a read-only STREAM. The STREAM is
+created using OPEN_FUNC, accessed using PREAD_FUNC and destroyed using
+CLOSE_FUNC.
+
+ Calls `bfd_find_target', so TARGET is interpreted as by that
+function.
+
+ Calls OPEN_FUNC (which can call `bfd_zalloc' and `bfd_get_filename')
+to obtain the read-only stream backing the BFD. OPEN_FUNC either
+succeeds returning the non-`NULL' STREAM, or fails returning `NULL'
+(setting `bfd_error').
+
+ Calls PREAD_FUNC to request NBYTES of data from STREAM starting at
+OFFSET (e.g., via a call to `bfd_read'). PREAD_FUNC either succeeds
+returning the number of bytes read (which can be less than NBYTES when
+end-of-file), or fails returning -1 (setting `bfd_error').
+
+ Calls CLOSE_FUNC when the BFD is later closed using `bfd_close'.
+CLOSE_FUNC either succeeds returning 0, or fails returning -1 (setting
+`bfd_error').
+
+ Calls STAT_FUNC to fill in a stat structure for bfd_stat,
+bfd_get_size, and bfd_get_mtime calls. STAT_FUNC returns 0 on success,
+or returns -1 on failure (setting `bfd_error').
+
+ If `bfd_openr_iovec' returns `NULL' then an error has occurred.
+Possible errors are `bfd_error_no_memory', `bfd_error_invalid_target'
+and `bfd_error_system_call'.
+
+ A copy of the FILENAME argument is stored in the newly created BFD.
+It can be accessed via the bfd_get_filename() macro.
+
+2.14.1.6 `bfd_openw'
+....................
+
+*Synopsis*
+ bfd *bfd_openw (const char *filename, const char *target);
+ *Description*
+Create a BFD, associated with file FILENAME, using the file format
+TARGET, and return a pointer to it.
+
+ Possible errors are `bfd_error_system_call', `bfd_error_no_memory',
+`bfd_error_invalid_target'.
+
+ A copy of the FILENAME argument is stored in the newly created BFD.
+It can be accessed via the bfd_get_filename() macro.
+
+2.14.1.7 `bfd_close'
+....................
+
+*Synopsis*
+ bfd_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'.
+
+2.14.1.8 `bfd_close_all_done'
+.............................
+
+*Synopsis*
+ bfd_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'.
+
+2.14.1.9 `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 TEMPL. The
+format is always set to `bfd_object'.
+
+ A copy of the FILENAME argument is stored in the newly created BFD.
+It can be accessed via the bfd_get_filename() macro.
+
+2.14.1.10 `bfd_make_writable'
+.............................
+
+*Synopsis*
+ bfd_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'.
+
+2.14.1.11 `bfd_make_readable'
+.............................
+
+*Synopsis*
+ bfd_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'.
+
+2.14.1.12 `bfd_alloc'
+.....................
+
+*Synopsis*
+ void *bfd_alloc (bfd *abfd, bfd_size_type wanted);
+ *Description*
+Allocate a block of WANTED bytes of memory attached to `abfd' and
+return a pointer to it.
+
+2.14.1.13 `bfd_alloc2'
+......................
+
+*Synopsis*
+ void *bfd_alloc2 (bfd *abfd, bfd_size_type nmemb, bfd_size_type size);
+ *Description*
+Allocate a block of NMEMB elements of SIZE bytes each of memory
+attached to `abfd' and return a pointer to it.
+
+2.14.1.14 `bfd_zalloc'
+......................
+
+*Synopsis*
+ void *bfd_zalloc (bfd *abfd, bfd_size_type wanted);
+ *Description*
+Allocate a block of WANTED bytes of zeroed memory attached to `abfd'
+and return a pointer to it.
+
+2.14.1.15 `bfd_zalloc2'
+.......................
+
+*Synopsis*
+ void *bfd_zalloc2 (bfd *abfd, bfd_size_type nmemb, bfd_size_type size);
+ *Description*
+Allocate a block of NMEMB elements of SIZE bytes each of zeroed memory
+attached to `abfd' and return a pointer to it.
+
+2.14.1.16 `bfd_calc_gnu_debuglink_crc32'
+........................................
+
+*Synopsis*
+ unsigned long bfd_calc_gnu_debuglink_crc32
+ (unsigned long crc, const unsigned char *buf, bfd_size_type len);
+ *Description*
+Computes a CRC value as used in the .gnu_debuglink section. Advances
+the previously computed CRC value by computing and adding in the crc32
+for LEN bytes of BUF.
+
+ *Returns*
+Return the updated CRC32 value.
+
+2.14.1.17 `bfd_get_debug_link_info'
+...................................
+
+*Synopsis*
+ char *bfd_get_debug_link_info (bfd *abfd, unsigned long *crc32_out);
+ *Description*
+Fetch the filename and CRC32 value for any separate debuginfo
+associated with ABFD. Return NULL if no such info found, otherwise
+return filename and update CRC32_OUT. The returned filename is
+allocated with `malloc'; freeing it is the responsibility of the caller.
+
+2.14.1.18 `bfd_get_alt_debug_link_info'
+.......................................
+
+*Synopsis*
+ char *bfd_get_alt_debug_link_info (bfd * abfd,
+ bfd_size_type *buildid_len,
+ bfd_byte **buildid_out);
+ *Description*
+Fetch the filename and BuildID value for any alternate debuginfo
+associated with ABFD. Return NULL if no such info found, otherwise
+return filename and update BUILDID_LEN and BUILDID_OUT. The returned
+filename and build_id are allocated with `malloc'; freeing them is the
+responsibility of the caller.
+
+2.14.1.19 `separate_debug_file_exists'
+......................................
+
+*Synopsis*
+ bfd_boolean separate_debug_file_exists
+ (char *name, unsigned long crc32);
+ *Description*
+Checks to see if NAME is a file and if its contents match CRC32.
+
+2.14.1.20 `separate_alt_debug_file_exists'
+..........................................
+
+*Synopsis*
+ bfd_boolean separate_alt_debug_file_exists
+ (char *name, unsigned long crc32);
+ *Description*
+Checks to see if NAME is a file and if its BuildID matches BUILDID.
+
+2.14.1.21 `find_separate_debug_file'
+....................................
+
+*Synopsis*
+ char *find_separate_debug_file (bfd *abfd);
+ *Description*
+Searches ABFD for a section called SECTION_NAME which is expected to
+contain a reference to a file containing separate debugging
+information. The function scans various locations in the filesystem,
+including the file tree rooted at DEBUG_FILE_DIRECTORY, and returns the
+first matching filename that it finds. If CHECK_CRC is TRUE then the
+contents of the file must also match the CRC value contained in
+SECTION_NAME. Returns NULL if no valid file could be found.
+
+2.14.1.22 `bfd_follow_gnu_debuglink'
+....................................
+
+*Synopsis*
+ char *bfd_follow_gnu_debuglink (bfd *abfd, const char *dir);
+ *Description*
+Takes a BFD and searches it for a .gnu_debuglink section. If this
+section is found, it examines the section for the name and checksum of
+a '.debug' file containing auxiliary debugging information. It then
+searches the filesystem for this .debug file in some standard
+locations, including the directory tree rooted at DIR, and if found
+returns the full filename.
+
+ If DIR is NULL, it will search a default path configured into libbfd
+at build time. [XXX this feature is not currently implemented].
+
+ *Returns*
+`NULL' on any errors or failure to locate the .debug file, otherwise a
+pointer to a heap-allocated string containing the filename. The caller
+is responsible for freeing this string.
+
+2.14.1.23 `bfd_follow_gnu_debugaltlink'
+.......................................
+
+*Synopsis*
+ char *bfd_follow_gnu_debugaltlink (bfd *abfd, const char *dir);
+ *Description*
+Takes a BFD and searches it for a .gnu_debugaltlink section. If this
+section is found, it examines the section for the name of a file
+containing auxiliary debugging information. It then searches the
+filesystem for this file in a set of standard locations, including the
+directory tree rooted at DIR, and if found returns the full filename.
+
+ If DIR is NULL, it will search a default path configured into libbfd
+at build time. [FIXME: This feature is not currently implemented].
+
+ *Returns*
+`NULL' on any errors or failure to locate the debug file, otherwise a
+pointer to a heap-allocated string containing the filename. The caller
+is responsible for freeing this string.
+
+2.14.1.24 `bfd_create_gnu_debuglink_section'
+............................................
+
+*Synopsis*
+ struct bfd_section *bfd_create_gnu_debuglink_section
+ (bfd *abfd, const char *filename);
+ *Description*
+Takes a BFD and adds a .gnu_debuglink section to it. The section is
+sized to be big enough to contain a link to the specified FILENAME.
+
+ *Returns*
+A pointer to the new section is returned if all is ok. Otherwise
+`NULL' is returned and bfd_error is set.
+
+2.14.1.25 `bfd_fill_in_gnu_debuglink_section'
+.............................................
+
+*Synopsis*
+ bfd_boolean bfd_fill_in_gnu_debuglink_section
+ (bfd *abfd, struct bfd_section *sect, const char *filename);
+ *Description*
+Takes a BFD and containing a .gnu_debuglink section SECT and fills in
+the contents of the section to contain a link to the specified
+FILENAME. The filename should be relative to the current directory.
+
+ *Returns*
+`TRUE' is returned if all is ok. Otherwise `FALSE' is returned and
+bfd_error is set.
+
+
+File: bfd.info, Node: Internal, Next: File Caching, Prev: Opening and Closing, Up: BFD front end
+
+2.15 Implementation details
+===========================
+
+2.15.1 Internal functions
+-------------------------
+
+*Description*
+These routines are used within BFD. They are not intended for export,
+but are documented here for completeness.
+
+2.15.1.1 `bfd_write_bigendian_4byte_int'
+........................................
+
+*Synopsis*
+ bfd_boolean bfd_write_bigendian_4byte_int (bfd *, unsigned int);
+ *Description*
+Write a 4 byte integer I to the output BFD ABFD, in big endian order
+regardless of what else is going on. This is useful in archives.
+
+2.15.1.2 `bfd_put_size'
+.......................
+
+2.15.1.3 `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, `libaout.h' defines `GET_WORD'
+to either `bfd_get_32' or `bfd_get_64'.
+
+ In the put routines, 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) \
+ ((void) (*((unsigned char *) (ptr)) = (val) & 0xff))
+ #define bfd_put_signed_8 \
+ bfd_put_8
+ #define bfd_get_8(abfd, ptr) \
+ (*(const unsigned char *) (ptr) & 0xff)
+ #define bfd_get_signed_8(abfd, ptr) \
+ (((*(const unsigned char *) (ptr) & 0xff) ^ 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))
+
+ #define bfd_get(bits, abfd, ptr) \
+ ((bits) == 8 ? (bfd_vma) bfd_get_8 (abfd, ptr) \
+ : (bits) == 16 ? bfd_get_16 (abfd, ptr) \
+ : (bits) == 32 ? bfd_get_32 (abfd, ptr) \
+ : (bits) == 64 ? bfd_get_64 (abfd, ptr) \
+ : (abort (), (bfd_vma) - 1))
+
+ #define bfd_put(bits, abfd, val, ptr) \
+ ((bits) == 8 ? bfd_put_8 (abfd, val, ptr) \
+ : (bits) == 16 ? bfd_put_16 (abfd, val, ptr) \
+ : (bits) == 32 ? bfd_put_32 (abfd, val, ptr) \
+ : (bits) == 64 ? bfd_put_64 (abfd, val, ptr) \
+ : (abort (), (void) 0))
+
+2.15.1.4 `bfd_h_put_size'
+.........................
+
+*Description*
+These macros have the same function as their `bfd_get_x' brethren,
+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))
+
+ /* Aliases for the above, which should eventually go away. */
+
+ #define H_PUT_64 bfd_h_put_64
+ #define H_PUT_32 bfd_h_put_32
+ #define H_PUT_16 bfd_h_put_16
+ #define H_PUT_8 bfd_h_put_8
+ #define H_PUT_S64 bfd_h_put_signed_64
+ #define H_PUT_S32 bfd_h_put_signed_32
+ #define H_PUT_S16 bfd_h_put_signed_16
+ #define H_PUT_S8 bfd_h_put_signed_8
+ #define H_GET_64 bfd_h_get_64
+ #define H_GET_32 bfd_h_get_32
+ #define H_GET_16 bfd_h_get_16
+ #define H_GET_8 bfd_h_get_8
+ #define H_GET_S64 bfd_h_get_signed_64
+ #define H_GET_S32 bfd_h_get_signed_32
+ #define H_GET_S16 bfd_h_get_signed_16
+ #define H_GET_S8 bfd_h_get_signed_8
+
+2.15.1.5 `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 X of
+1025 returns 11. A X of 0 returns 0.
+
+
+File: bfd.info, Node: File Caching, Next: Linker Functions, Prev: Internal, Up: BFD front end
+
+2.16 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.
+
+2.16.1 Caching functions
+------------------------
+
+2.16.1.1 `bfd_cache_init'
+.........................
+
+*Synopsis*
+ bfd_boolean bfd_cache_init (bfd *abfd);
+ *Description*
+Add a newly opened BFD to the cache.
+
+2.16.1.2 `bfd_cache_close'
+..........................
+
+*Synopsis*
+ bfd_boolean bfd_cache_close (bfd *abfd);
+ *Description*
+Remove the BFD 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.
+
+2.16.1.3 `bfd_cache_close_all'
+..............................
+
+*Synopsis*
+ bfd_boolean bfd_cache_close_all (void);
+ *Description*
+Remove all BFDs from the cache. If the attached file is open, then
+close it too.
+
+ *Returns*
+`FALSE' is returned if closing one of the file fails, `TRUE' is
+returned if all is well.
+
+2.16.1.4 `bfd_open_file'
+........................
+
+*Synopsis*
+ FILE* bfd_open_file (bfd *abfd);
+ *Description*
+Call the OS to open a file for 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.info, Node: Linker Functions, Next: Hash Tables, Prev: File Caching, Up: BFD front end
+
+2.17 Linker Functions
+=====================
+
+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::
+
+
+File: bfd.info, Node: Creating a Linker Hash Table, Next: Adding Symbols to the Hash Table, Prev: Linker Functions, Up: Linker Functions
+
+2.17.1 Creating a linker hash table
+-----------------------------------
+
+The linker routines must create a hash table, which must be derived
+from `struct bfd_link_hash_table' described in `bfdlink.c'. *Note 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 relocatable 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.
+
+
+File: bfd.info, Node: Adding Symbols to the Hash Table, Next: Performing the Final Link, Prev: Creating a Linker Hash Table, Up: Linker Functions
+
+2.17.2 Adding symbols to the hash table
+---------------------------------------
+
+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::
+
+
+File: bfd.info, Node: Differing file formats, Next: Adding symbols from an object file, Prev: Adding Symbols to the Hash Table, Up: Adding Symbols to the Hash Table
+
+2.17.2.1 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 output bfd xvec 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
+output bfd before saving information (in this case, the ECOFF external
+symbol debugging information) in a hash table entry.
+
+
+File: bfd.info, Node: Adding symbols from an object file, Next: Adding symbols from an archive, Prev: Differing file formats, Up: Adding Symbols to the Hash Table
+
+2.17.2.2 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.
+
+ `_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.
+
+
+File: bfd.info, Node: Adding symbols from an archive, Prev: Adding symbols from an object file, Up: Adding Symbols to the Hash Table
+
+2.17.2.3 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.
+(The callback may in fact indicate that a replacement BFD should be
+used, in which case the symbols from that BFD should be added to the
+linker hash table instead.)
+
+ 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.
+`_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.
+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 element's 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 - possibly those of a
+substitute BFD, if the `add_archive_element' callback avails itself of
+that option.
+
+ 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.
+
+
+File: bfd.info, Node: Performing the Final Link, Prev: Adding Symbols to the Hash Table, Up: Linker Functions
+
+2.17.3 Performing the 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 relocatable 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::
+
+
+File: bfd.info, Node: Information provided by the linker, Next: Relocating the section contents, Prev: Performing the Final Link, Up: Performing the Final Link
+
+2.17.3.1 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 `map_head.link_order' 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 relocatable object file.
+
+
+File: bfd.info, Node: Relocating the section contents, Next: Writing the symbol table, Prev: Information provided by the linker, Up: Performing the Final Link
+
+2.17.3.2 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 relocatable link, the relocs themselves must also be
+modified and written out.
+
+ 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'.
+
+
+File: bfd.info, Node: Writing the symbol table, Prev: Relocating the section contents, Up: Performing the Final Link
+
+2.17.3.3 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)'.
+
+2.17.3.4 `bfd_link_split_section'
+.................................
+
+*Synopsis*
+ bfd_boolean bfd_link_split_section (bfd *abfd, asection *sec);
+ *Description*
+Return nonzero if 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))
+
+2.17.3.5 `bfd_section_already_linked'
+.....................................
+
+*Synopsis*
+ bfd_boolean bfd_section_already_linked (bfd *abfd,
+ asection *sec,
+ struct bfd_link_info *info);
+ *Description*
+Check if DATA has been already linked during a reloceatable or final
+link. Return TRUE if it has.
+ #define bfd_section_already_linked(abfd, sec, info) \
+ BFD_SEND (abfd, _section_already_linked, (abfd, sec, info))
+
+2.17.3.6 `bfd_generic_define_common_symbol'
+...........................................
+
+*Synopsis*
+ bfd_boolean bfd_generic_define_common_symbol
+ (bfd *output_bfd, struct bfd_link_info *info,
+ struct bfd_link_hash_entry *h);
+ *Description*
+Convert common symbol H into a defined symbol. Return TRUE on success
+and FALSE on failure.
+ #define bfd_define_common_symbol(output_bfd, info, h) \
+ BFD_SEND (output_bfd, _bfd_define_common_symbol, (output_bfd, info, h))
+
+2.17.3.7 `bfd_find_version_for_sym'
+...................................
+
+*Synopsis*
+ struct bfd_elf_version_tree * bfd_find_version_for_sym
+ (struct bfd_elf_version_tree *verdefs,
+ const char *sym_name, bfd_boolean *hide);
+ *Description*
+Search an elf version script tree for symbol versioning info and export
+/ don't-export status for a given symbol. Return non-NULL on success
+and NULL on failure; also sets the output `hide' boolean parameter.
+
+2.17.3.8 `bfd_hide_sym_by_version'
+..................................
+
+*Synopsis*
+ bfd_boolean bfd_hide_sym_by_version
+ (struct bfd_elf_version_tree *verdefs, const char *sym_name);
+ *Description*
+Search an elf version script tree for symbol versioning info for a
+given symbol. Return TRUE if the symbol is hidden.
+
+
+File: bfd.info, Node: Hash Tables, Prev: Linker Functions, Up: BFD front end
+
+2.18 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::
+
+
+File: bfd.info, Node: Creating and Freeing a Hash Table, Next: Looking Up or Entering a String, Prev: Hash Tables, Up: Hash Tables
+
+2.18.1 Creating and freeing a hash table
+----------------------------------------
+
+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 SIZE argument, may be used).
+`bfd_hash_table_init' returns `FALSE' if some sort of error occurs.
+
+ 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'. *Note Deriving a New Hash Table Type::, for why
+you would want to use a different value for this argument.
+
+ `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'.
+
+ 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.
+
+ Use `bfd_hash_set_default_size' to set the default size of hash
+table to use.
+
+
+File: bfd.info, Node: Looking Up or Entering a String, Next: Traversing a Hash Table, Prev: Creating and Freeing a Hash Table, Up: Hash Tables
+
+2.18.2 Looking up or entering a string
+--------------------------------------
+
+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 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 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 CREATE argument is `TRUE', and a new entry is created, the
+COPY argument is used to decide whether to copy the string onto the
+hash table objalloc or not. If COPY is passed as `FALSE', you must be
+careful not to deallocate or modify the string as long as the hash table
+exists.
+
+
+File: bfd.info, Node: Traversing a Hash Table, Next: Deriving a New Hash Table Type, Prev: Looking Up or Entering a String, Up: Hash Tables
+
+2.18.3 Traversing a hash table
+------------------------------
+
+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.
+
+
+File: bfd.info, Node: Deriving a New Hash Table Type, Prev: Traversing a Hash Table, Up: Hash Tables
+
+2.18.4 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::
+
+
+File: bfd.info, Node: Define the Derived Structures, Next: Write the Derived Creation Routine, Prev: Deriving a New Hash Table Type, Up: Deriving a New Hash Table Type
+
+2.18.4.1 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'.
+
+
+File: bfd.info, Node: Write the Derived Creation Routine, Next: Write Other Derived Routines, Prev: Define the Derived Structures, Up: Deriving a New Hash Table Type
+
+2.18.4.2 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. FUNCTION_NAME
+is the name of the routine. ENTRY_TYPE is the type of an entry in the
+hash table you are creating. BASE_NEWFUNC is the name of the creation
+routine of the hash table type your hash table is derived from.
+
+ struct bfd_hash_entry *
+ FUNCTION_NAME (struct bfd_hash_entry *entry,
+ struct bfd_hash_table *table,
+ const char *string)
+ {
+ struct ENTRY_TYPE *ret = (ENTRY_TYPE *) entry;
+
+ /* Allocate the structure if it has not already been allocated by a
+ derived class. */
+ if (ret == NULL)
+ {
+ ret = bfd_hash_allocate (table, sizeof (* ret));
+ if (ret == NULL)
+ return NULL;
+ }
+
+ /* Call the allocation method of the base class. */
+ ret = ((ENTRY_TYPE *)
+ 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. FUNCTION_NAME is
+`_bfd_link_hash_newfunc'. ENTRY_TYPE is `struct bfd_link_hash_entry'.
+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'.
+
+
+File: bfd.info, Node: Write Other Derived Routines, Prev: Write the Derived Creation Routine, Up: Deriving a New Hash Table Type
+
+2.18.4.3 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.
+
+
+File: bfd.info, Node: BFD back ends, Next: GNU Free Documentation License, Prev: BFD front end, Up: Top
+
+3 BFD back ends
+***************
+
+* Menu:
+
+* What to Put Where::
+* aout :: a.out backends
+* coff :: coff backends
+* elf :: elf backends
+* mmo :: mmo backend
+
+
+File: bfd.info, Node: What to Put Where, Next: aout, Prev: BFD back ends, Up: BFD back ends
+
+3.1 What to Put Where
+=====================
+
+All of BFD lives in one directory.
+
+
+File: bfd.info, Node: aout, Next: coff, Prev: What to Put Where, Up: BFD back ends
+
+3.2 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 `aoutx.h' and other
+files which derive functions from the base. One derivation file is
+`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 `sunos.c' for sun3 and sun4, `newsos3.c' for
+the Sony NEWS, and `demo64.c' for a demonstration of a 64 bit a.out
+format.
+
+ The base 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 `aout32.c' and `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 `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 `sunos.c':
+
+ #define TARGET_NAME "a.out-sunos-big"
+ #define VECNAME sparc_aout_sunos_be_vec
+ #include "aoutf1.h"
+
+ requires all the names from `aout32.c', and produces the jump vector
+
+ sparc_aout_sunos_be_vec
+
+ The 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 `../include/sys/h-XXX.h' (for your host). These values,
+plus the structures and macros defined in `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 `host-aout.c', specify:
+
+ TDEFAULTS = -DDEFAULT_VECTOR=host_aout_big_vec
+ TDEPFILES= host-aout.o trad-core.o
+
+ in the `config/XXX.mt' file, and modify `configure.ac' to use the
+`XXX.mt' file (by setting "`bfd_target=XXX'") when your configuration
+is selected.
+
+3.2.1 Relocations
+-----------------
+
+*Description*
+The file `aoutx.h' provides for both the _standard_ and _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.
+
+3.2.2 Internal entry points
+---------------------------
+
+*Description*
+`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).
+
+3.2.2.1 `aout_SIZE_swap_exec_header_in'
+.......................................
+
+*Synopsis*
+ void aout_SIZE_swap_exec_header_in,
+ (bfd *abfd,
+ struct external_exec *bytes,
+ struct internal_exec *execp);
+ *Description*
+Swap the information in an executable header RAW_BYTES taken from a raw
+byte stream memory image into the internal exec header structure EXECP.
+
+3.2.2.2 `aout_SIZE_swap_exec_header_out'
+........................................
+
+*Synopsis*
+ void aout_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 EXECP into
+the buffer RAW_BYTES ready for writing to disk.
+
+3.2.2.3 `aout_SIZE_some_aout_object_p'
+......................................
+
+*Synopsis*
+ const bfd_target *aout_SIZE_some_aout_object_p
+ (bfd *abfd,
+ struct internal_exec *execp,
+ const bfd_target *(*callback_to_real_object_p) (bfd *));
+ *Description*
+Some a.out variant thinks that the file open in 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.
+
+3.2.2.4 `aout_SIZE_mkobject'
+............................
+
+*Synopsis*
+ bfd_boolean aout_SIZE_mkobject, (bfd *abfd);
+ *Description*
+Initialize BFD ABFD for use with a.out files.
+
+3.2.2.5 `aout_SIZE_machine_type'
+................................
+
+*Synopsis*
+ enum machine_type aout_SIZE_machine_type
+ (enum bfd_architecture arch,
+ unsigned long machine,
+ bfd_boolean *unknown);
+ *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.
+
+3.2.2.6 `aout_SIZE_set_arch_mach'
+.................................
+
+*Synopsis*
+ bfd_boolean aout_SIZE_set_arch_mach,
+ (bfd *,
+ enum bfd_architecture arch,
+ unsigned long machine);
+ *Description*
+Set the architecture and the machine of the BFD ABFD to the values ARCH
+and MACHINE. Verify that ABFD's format can support the architecture
+required.
+
+3.2.2.7 `aout_SIZE_new_section_hook'
+....................................
+
+*Synopsis*
+ bfd_boolean aout_SIZE_new_section_hook,
+ (bfd *abfd,
+ asection *newsect);
+ *Description*
+Called by the BFD in response to a `bfd_make_section' request.
+
+
+File: bfd.info, Node: coff, Next: elf, Prev: aout, Up: BFD back ends
+
+3.3 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 `coff-m88k.c'. This file
+`#include's `coff/m88k.h' which defines the external structure of the
+coff format for the 88k, and `coff/internal.h' which defines the
+internal structure. `coff-m88k.c' also defines the relocations used by
+the 88k format *Note Relocations::.
+
+ The Intel i960 processor version of coff is implemented in
+`coff-i960.c'. This file has the same structure as `coff-m88k.c',
+except that it includes `coff/i960.h' rather than `coff-m88k.h'.
+
+3.3.1 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 `i386coff.c' to `foocoff.c', copy
+`../include/coff/i386.h' to `../include/coff/foo.h', and add the lines
+to `targets.c' and `Makefile.in' so that your new back end is used.
+Alter the shapes of the structures in `../include/coff/foo.h' so that
+they match what you need. You will probably also have to add `#ifdef's
+to the code in `coff/internal.h' and `coffcode.h' if your version of
+coff is too wild.
+
+ You can verify that your new BFD backend works quite simply by
+building `objdump' from the `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 `att-dump' or
+just `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.
+
+3.3.2 How the coff backend works
+--------------------------------
+
+3.3.2.1 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 `coffgen.c'. These routines work for
+any Coff target. They use some hooks into the target specific code;
+the hooks are in a `bfd_coff_backend_data' structure, one of which
+exists for each target.
+
+ The essentially similar target-specific routines are in
+`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 `coffcode.h'.
+
+ Some of the Coff targets then also have additional routines in the
+target source file itself.
+
+ For example, `coff-i960.c' includes `coff/internal.h' and
+`coff/i960.h'. It then defines a few constants, such as `I960', and
+includes `coffcode.h'. Since the i960 has complex relocation types,
+`coff-i960.c' also includes some code to manipulate the i960 relocs.
+This code is not in `coffcode.h' because it would not be used by any
+other target.
+
+3.3.2.2 Coff long section names
+...............................
+
+In the standard Coff object format, section names are limited to the
+eight bytes available in the `s_name' field of the `SCNHDR' section
+header structure. The format requires the field to be NUL-padded, but
+not necessarily NUL-terminated, so the longest section names permitted
+are a full eight characters.
+
+ The Microsoft PE variants of the Coff object file format add an
+extension to support the use of long section names. This extension is
+defined in section 4 of the Microsoft PE/COFF specification (rev 8.1).
+If a section name is too long to fit into the section header's `s_name'
+field, it is instead placed into the string table, and the `s_name'
+field is filled with a slash ("/") followed by the ASCII decimal
+representation of the offset of the full name relative to the string
+table base.
+
+ Note that this implies that the extension can only be used in object
+files, as executables do not contain a string table. The standard
+specifies that long section names from objects emitted into executable
+images are to be truncated.
+
+ However, as a GNU extension, BFD can generate executable images that
+contain a string table and long section names. This would appear to be
+technically valid, as the standard only says that Coff debugging
+information is deprecated, not forbidden, and in practice it works,
+although some tools that parse PE files expecting the MS standard
+format may become confused; `PEview' is one known example.
+
+ The functionality is supported in BFD by code implemented under the
+control of the macro `COFF_LONG_SECTION_NAMES'. If not defined, the
+format does not support long section names in any way. If defined, it
+is used to initialise a flag, `_bfd_coff_long_section_names', and a
+hook function pointer, `_bfd_coff_set_long_section_names', in the Coff
+backend data structure. The flag controls the generation of long
+section names in output BFDs at runtime; if it is false, as it will be
+by default when generating an executable image, long section names are
+truncated; if true, the long section names extension is employed. The
+hook points to a function that allows the value of the flag to be
+altered at runtime, on formats that support long section names at all;
+on other formats it points to a stub that returns an error indication.
+
+ With input BFDs, the flag is set according to whether any long
+section names are detected while reading the section headers. For a
+completely new BFD, the flag is set to the default for the target
+format. This information can be used by a client of the BFD library
+when deciding what output format to generate, and means that a BFD that
+is opened for read and subsequently converted to a writeable BFD and
+modified in-place will retain whatever format it had on input.
+
+ If `COFF_LONG_SECTION_NAMES' is simply defined (blank), or is
+defined to the value "1", then long section names are enabled by
+default; if it is defined to the value zero, they are disabled by
+default (but still accepted in input BFDs). The header `coffcode.h'
+defines a macro, `COFF_DEFAULT_LONG_SECTION_NAMES', which is used in
+the backends to initialise the backend data structure fields
+appropriately; see the comments for further detail.
+
+3.3.2.3 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 `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 `bfd_swap'_thing_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 `coffcode.h'.
+E.g., the size of line number entry in coff is sometimes 16 bits, and
+sometimes 32 bits. `#define'ing `PUT_LNSZ_LNNO' and `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 `#defines'.
+Three of the bit twiddling routines are exported to `gdb';
+`coff_swap_aux_in', `coff_swap_sym_in' and `coff_swap_lineno_in'. `GDB'
+reads the symbol table on its own, but uses BFD to fix things up. More
+of the bit twiddlers are exported for `gas'; `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'. `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 `gas', which makes one avenue to disaster
+disappear.
+
+3.3.2.4 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
+`bfd_canonicalize_symtab'), a request gets through to
+`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 (`".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 `sclass' field) about the
+various flags to set in the `asymbol'. *Note 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.
+
+3.3.2.5 Symbol writing
+......................
+
+Writing a symbol to a coff file which didn't come from a coff file will
+lose any debugging information. The `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 (`C_FILE') to point to the
+next file place holder in the list. It also marks each `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 `asymbol''s `asection' *Note Sections::.
+
+ * `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 hierarchy
+required by coff. It changes each pointer to a symbol into the index
+into the symbol table of the asymbol.
+
+ * `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.
+
+3.3.2.6 `coff_symbol_type'
+..........................
+
+*Description*
+The hidden information for an `asymbol' is described in a
+`combined_entry_type':
+
+
+ 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;
+
+ /* Selector for the union above. */
+ bfd_boolean is_sym;
+ } 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 ? */
+ bfd_boolean done_lineno;
+ } coff_symbol_type;
+
+3.3.2.7 `bfd_coff_backend_data'
+...............................
+
+ /* COFF symbol classifications. */
+
+ enum coff_symbol_classification
+ {
+ /* Global symbol. */
+ COFF_SYMBOL_GLOBAL,
+ /* Common symbol. */
+ COFF_SYMBOL_COMMON,
+ /* Undefined symbol. */
+ COFF_SYMBOL_UNDEFINED,
+ /* Local symbol. */
+ COFF_SYMBOL_LOCAL,
+ /* PE section symbol. */
+ COFF_SYMBOL_PE_SECTION
+ };
+Special entry points for gdb to swap in coff symbol table parts:
+ typedef struct
+ {
+ void (*_bfd_coff_swap_aux_in)
+ (bfd *, void *, int, int, int, int, void *);
+
+ void (*_bfd_coff_swap_sym_in)
+ (bfd *, void *, void *);
+
+ void (*_bfd_coff_swap_lineno_in)
+ (bfd *, void *, void *);
+
+ unsigned int (*_bfd_coff_swap_aux_out)
+ (bfd *, void *, int, int, int, int, void *);
+
+ unsigned int (*_bfd_coff_swap_sym_out)
+ (bfd *, void *, void *);
+
+ unsigned int (*_bfd_coff_swap_lineno_out)
+ (bfd *, void *, void *);
+
+ unsigned int (*_bfd_coff_swap_reloc_out)
+ (bfd *, void *, void *);
+
+ unsigned int (*_bfd_coff_swap_filehdr_out)
+ (bfd *, void *, void *);
+
+ unsigned int (*_bfd_coff_swap_aouthdr_out)
+ (bfd *, void *, void *);
+
+ unsigned int (*_bfd_coff_swap_scnhdr_out)
+ (bfd *, void *, void *);
+
+ 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;
+ unsigned int _bfd_filnmlen;
+ bfd_boolean _bfd_coff_long_filenames;
+
+ bfd_boolean _bfd_coff_long_section_names;
+ bfd_boolean (*_bfd_coff_set_long_section_names)
+ (bfd *, int);
+
+ unsigned int _bfd_coff_default_section_alignment_power;
+ bfd_boolean _bfd_coff_force_symnames_in_strings;
+ unsigned int _bfd_coff_debug_string_prefix_length;
+ unsigned int _bfd_coff_max_nscns;
+
+ void (*_bfd_coff_swap_filehdr_in)
+ (bfd *, void *, void *);
+
+ void (*_bfd_coff_swap_aouthdr_in)
+ (bfd *, void *, void *);
+
+ void (*_bfd_coff_swap_scnhdr_in)
+ (bfd *, void *, void *);
+
+ void (*_bfd_coff_swap_reloc_in)
+ (bfd *abfd, void *, void *);
+
+ bfd_boolean (*_bfd_coff_bad_format_hook)
+ (bfd *, void *);
+
+ bfd_boolean (*_bfd_coff_set_arch_mach_hook)
+ (bfd *, void *);
+
+ void * (*_bfd_coff_mkobject_hook)
+ (bfd *, void *, void *);
+
+ bfd_boolean (*_bfd_styp_to_sec_flags_hook)
+ (bfd *, void *, const char *, asection *, flagword *);
+
+ void (*_bfd_set_alignment_hook)
+ (bfd *, asection *, void *);
+
+ bfd_boolean (*_bfd_coff_slurp_symbol_table)
+ (bfd *);
+
+ bfd_boolean (*_bfd_coff_symname_in_debug)
+ (bfd *, struct internal_syment *);
+
+ bfd_boolean (*_bfd_coff_pointerize_aux_hook)
+ (bfd *, combined_entry_type *, combined_entry_type *,
+ unsigned int, combined_entry_type *);
+
+ bfd_boolean (*_bfd_coff_print_aux)
+ (bfd *, FILE *, combined_entry_type *, combined_entry_type *,
+ combined_entry_type *, unsigned int);
+
+ void (*_bfd_coff_reloc16_extra_cases)
+ (bfd *, struct bfd_link_info *, struct bfd_link_order *, arelent *,
+ bfd_byte *, unsigned int *, unsigned int *);
+
+ int (*_bfd_coff_reloc16_estimate)
+ (bfd *, asection *, arelent *, unsigned int,
+ struct bfd_link_info *);
+
+ enum coff_symbol_classification (*_bfd_coff_classify_symbol)
+ (bfd *, struct internal_syment *);
+
+ bfd_boolean (*_bfd_coff_compute_section_file_positions)
+ (bfd *);
+
+ bfd_boolean (*_bfd_coff_start_final_link)
+ (bfd *, struct bfd_link_info *);
+
+ bfd_boolean (*_bfd_coff_relocate_section)
+ (bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
+ struct internal_reloc *, struct internal_syment *, asection **);
+
+ reloc_howto_type *(*_bfd_coff_rtype_to_howto)
+ (bfd *, asection *, struct internal_reloc *,
+ struct coff_link_hash_entry *, struct internal_syment *,
+ bfd_vma *);
+
+ bfd_boolean (*_bfd_coff_adjust_symndx)
+ (bfd *, struct bfd_link_info *, bfd *, asection *,
+ struct internal_reloc *, bfd_boolean *);
+
+ bfd_boolean (*_bfd_coff_link_add_one_symbol)
+ (struct bfd_link_info *, bfd *, const char *, flagword,
+ asection *, bfd_vma, const char *, bfd_boolean, bfd_boolean,
+ struct bfd_link_hash_entry **);
+
+ bfd_boolean (*_bfd_coff_link_output_has_begun)
+ (bfd *, struct coff_final_link_info *);
+
+ bfd_boolean (*_bfd_coff_final_link_postscript)
+ (bfd *, struct coff_final_link_info *);
+
+ bfd_boolean (*_bfd_coff_print_pdata)
+ (bfd *, void *);
+
+ } 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_filnmlen(abfd) (coff_backend_info (abfd)->_bfd_filnmlen)
+ #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_set_long_section_names(abfd, enable) \
+ ((coff_backend_info (abfd)->_bfd_coff_set_long_section_names) (abfd, enable))
+ #define bfd_coff_default_section_alignment_power(abfd) \
+ (coff_backend_info (abfd)->_bfd_coff_default_section_alignment_power)
+ #define bfd_coff_max_nscns(abfd) \
+ (coff_backend_info (abfd)->_bfd_coff_max_nscns)
+
+ #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, section, flags_ptr)\
+ ((coff_backend_info (abfd)->_bfd_styp_to_sec_flags_hook)\
+ (abfd, scnhdr, name, section, flags_ptr))
+
+ #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_force_symnames_in_strings(abfd)\
+ (coff_backend_info (abfd)->_bfd_coff_force_symnames_in_strings)
+
+ #define bfd_coff_debug_string_prefix_length(abfd)\
+ (coff_backend_info (abfd)->_bfd_coff_debug_string_prefix_length)
+
+ #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_classify_symbol(abfd, sym)\
+ ((coff_backend_info (abfd)->_bfd_coff_classify_symbol)\
+ (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))
+
+ #define bfd_coff_have_print_pdata(a) \
+ (coff_backend_info (a)->_bfd_coff_print_pdata)
+ #define bfd_coff_print_pdata(a,p) \
+ ((coff_backend_info (a)->_bfd_coff_print_pdata) (a, p))
+
+ /* Macro: Returns true if the bfd is a PE executable as opposed to a
+ PE object file. */
+ #define bfd_pei_p(abfd) \
+ (CONST_STRNEQ ((abfd)->xvec->name, "pei-"))
+
+3.3.2.8 Writing relocations
+...........................
+
+To write relocations, the back end steps though the canonical
+relocation table and create an `internal_reloc'. The symbol index to
+use is removed from the `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 `internal_reloc' is swapped into the shape of an
+`external_reloc' and written out to disk.
+
+3.3.2.9 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.
+
+ Note: The PE format uses line number 0 for a flag indicating a new
+source file.
+
+ 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 ?
+
+3.3.2.10 Reading relocations
+............................
+
+Coff relocations are easily transformed into the internal BFD form
+(`arelent').
+
+ Reading a coff relocation table is done in the following stages:
+
+ * Read the entire coff relocation table into memory.
+
+ * Process each relocation in turn; first swap it from the external
+ to the internal form.
+
+ * 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 `bfd_canonicalize_symtab'. The
+ back end will call that routine and save the result if a
+ canonicalization hasn't been done.
+
+ * 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
+ `r_type' to directly produce an index into a howto table vector;
+ the 88k subtracts a number from the `r_type' field and creates an
+ addend field.
+
+
+File: bfd.info, Node: elf, Next: mmo, Prev: coff, Up: BFD back ends
+
+3.4 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.
+
+
+File: bfd.info, Node: mmo, Prev: elf, Up: BFD back ends
+
+3.5 mmo backend
+===============
+
+The mmo object format is used exclusively together with Professor
+Donald E. Knuth's educational 64-bit processor MMIX. The simulator
+`mmix' which is available at `http://mmix.cs.hm.edu/src/index.html'
+understands this format. That package also includes a combined
+assembler and linker called `mmixal'. The mmo format has no advantages
+feature-wise compared to e.g. ELF. It is a simple non-relocatable
+object format with no support for archives or debugging information,
+except for symbol value information and line numbers (which is not yet
+implemented in BFD). See `http://mmix.cs.hm.edu/' for more information
+about MMIX. The ELF format is used for intermediate object files in
+the BFD implementation.
+
+* Menu:
+
+* File layout::
+* Symbol-table::
+* mmo section mapping::
+
+
+File: bfd.info, Node: File layout, Next: Symbol-table, Prev: mmo, Up: mmo
+
+3.5.1 File layout
+-----------------
+
+The mmo file contents is not partitioned into named sections as with
+e.g. ELF. Memory areas is formed by specifying the location of the
+data that follows. Only the memory area `0x0000...00' to `0x01ff...ff'
+is executable, so it is used for code (and constants) and the area
+`0x2000...00' to `0x20ff...ff' is used for writable data. *Note mmo
+section mapping::.
+
+ There is provision for specifying "special data" of 65536 different
+types. We use type 80 (decimal), arbitrarily chosen the same as the
+ELF `e_machine' number for MMIX, filling it with section information
+normally found in ELF objects. *Note mmo section mapping::.
+
+ Contents is entered as 32-bit words, xor:ed over previous contents,
+always zero-initialized. A word that starts with the byte `0x98' forms
+a command called a `lopcode', where the next byte distinguished between
+the thirteen lopcodes. The two remaining bytes, called the `Y' and `Z'
+fields, or the `YZ' field (a 16-bit big-endian number), are used for
+various purposes different for each lopcode. As documented in
+`http://mmix.cs.hm.edu/doc/mmixal.pdf', the lopcodes are:
+
+`lop_quote'
+ 0x98000001. The next word is contents, regardless of whether it
+ starts with 0x98 or not.
+
+`lop_loc'
+ 0x9801YYZZ, where `Z' is 1 or 2. This is a location directive,
+ setting the location for the next data to the next 32-bit word
+ (for Z = 1) or 64-bit word (for Z = 2), plus Y * 2^56. Normally
+ `Y' is 0 for the text segment and 2 for the data segment. Beware
+ that the low bits of non- tetrabyte-aligned values are silently
+ discarded when being automatically incremented and when storing
+ contents (in contrast to e.g. its use as current location when
+ followed by lop_fixo et al before the next possibly-quoted
+ tetrabyte contents).
+
+`lop_skip'
+ 0x9802YYZZ. Increase the current location by `YZ' bytes.
+
+`lop_fixo'
+ 0x9803YYZZ, where `Z' is 1 or 2. Store the current location as 64
+ bits into the location pointed to by the next 32-bit (Z = 1) or
+ 64-bit (Z = 2) word, plus Y * 2^56.
+
+`lop_fixr'
+ 0x9804YYZZ. `YZ' is stored into the current location plus 2 - 4 *
+ YZ.
+
+`lop_fixrx'
+ 0x980500ZZ. `Z' is 16 or 24. A value `L' derived from the
+ following 32-bit word are used in a manner similar to `YZ' in
+ lop_fixr: it is xor:ed into the current location minus 4 * L. The
+ first byte of the word is 0 or 1. If it is 1, then L = (LOWEST 24
+ BITS OF WORD) - 2^Z, if 0, then L = (LOWEST 24 BITS OF WORD).
+
+`lop_file'
+ 0x9806YYZZ. `Y' is the file number, `Z' is count of 32-bit words.
+ Set the file number to `Y' and the line counter to 0. The next Z
+ * 4 bytes contain the file name, padded with zeros if the count is
+ not a multiple of four. The same `Y' may occur multiple times,
+ but `Z' must be 0 for all but the first occurrence.
+
+`lop_line'
+ 0x9807YYZZ. `YZ' is the line number. Together with lop_file, it
+ forms the source location for the next 32-bit word. Note that for
+ each non-lopcode 32-bit word, line numbers are assumed incremented
+ by one.
+
+`lop_spec'
+ 0x9808YYZZ. `YZ' is the type number. Data until the next lopcode
+ other than lop_quote forms special data of type `YZ'. *Note mmo
+ section mapping::.
+
+ Other types than 80, (or type 80 with a content that does not
+ parse) is stored in sections named `.MMIX.spec_data.N' where N is
+ the `YZ'-type. The flags for such a sections say not to allocate
+ or load the data. The vma is 0. Contents of multiple occurrences
+ of special data N is concatenated to the data of the previous
+ lop_spec Ns. The location in data or code at which the lop_spec
+ occurred is lost.
+
+`lop_pre'
+ 0x980901ZZ. The first lopcode in a file. The `Z' field forms the
+ length of header information in 32-bit words, where the first word
+ tells the time in seconds since `00:00:00 GMT Jan 1 1970'.
+
+`lop_post'
+ 0x980a00ZZ. Z > 32. This lopcode follows after all
+ content-generating lopcodes in a program. The `Z' field denotes
+ the value of `rG' at the beginning of the program. The following
+ 256 - Z big-endian 64-bit words are loaded into global registers
+ `$G' ... `$255'.
+
+`lop_stab'
+ 0x980b0000. The next-to-last lopcode in a program. Must follow
+ immediately after the lop_post lopcode and its data. After this
+ lopcode follows all symbols in a compressed format (*note
+ Symbol-table::).
+
+`lop_end'
+ 0x980cYYZZ. The last lopcode in a program. It must follow the
+ lop_stab lopcode and its data. The `YZ' field contains the number
+ of 32-bit words of symbol table information after the preceding
+ lop_stab lopcode.
+
+ Note that the lopcode "fixups"; `lop_fixr', `lop_fixrx' and
+`lop_fixo' are not generated by BFD, but are handled. They are
+generated by `mmixal'.
+
+ This trivial one-label, one-instruction file:
+
+ :Main TRAP 1,2,3
+
+ can be represented this way in mmo:
+
+ 0x98090101 - lop_pre, one 32-bit word with timestamp.
+ <timestamp>
+ 0x98010002 - lop_loc, text segment, using a 64-bit address.
+ Note that mmixal does not emit this for the file above.
+ 0x00000000 - Address, high 32 bits.
+ 0x00000000 - Address, low 32 bits.
+ 0x98060002 - lop_file, 2 32-bit words for file-name.
+ 0x74657374 - "test"
+ 0x2e730000 - ".s\0\0"
+ 0x98070001 - lop_line, line 1.
+ 0x00010203 - TRAP 1,2,3
+ 0x980a00ff - lop_post, setting $255 to 0.
+ 0x00000000
+ 0x00000000
+ 0x980b0000 - lop_stab for ":Main" = 0, serial 1.
+ 0x203a4040 *Note Symbol-table::.
+ 0x10404020
+ 0x4d206120
+ 0x69016e00
+ 0x81000000
+ 0x980c0005 - lop_end; symbol table contained five 32-bit words.
+
+
+File: bfd.info, Node: Symbol-table, Next: mmo section mapping, Prev: File layout, Up: mmo
+
+3.5.2 Symbol table format
+-------------------------
+
+From mmixal.w (or really, the generated mmixal.tex) in the MMIXware
+package which also contains the `mmix' simulator: "Symbols are stored
+and retrieved by means of a `ternary search trie', following ideas of
+Bentley and Sedgewick. (See ACM-SIAM Symp. on Discrete Algorithms `8'
+(1997), 360-369; R.Sedgewick, `Algorithms in C' (Reading, Mass.
+Addison-Wesley, 1998), `15.4'.) Each trie node stores a character, and
+there are branches to subtries for the cases where a given character is
+less than, equal to, or greater than the character in the trie. There
+also is a pointer to a symbol table entry if a symbol ends at the
+current node."
+
+ So it's a tree encoded as a stream of bytes. The stream of bytes
+acts on a single virtual global symbol, adding and removing characters
+and signalling complete symbol points. Here, we read the stream and
+create symbols at the completion points.
+
+ First, there's a control byte `m'. If any of the listed bits in `m'
+is nonzero, we execute what stands at the right, in the listed order:
+
+ (MMO3_LEFT)
+ 0x40 - Traverse left trie.
+ (Read a new command byte and recurse.)
+
+ (MMO3_SYMBITS)
+ 0x2f - Read the next byte as a character and store it in the
+ current character position; increment character position.
+ Test the bits of `m':
+
+ (MMO3_WCHAR)
+ 0x80 - The character is 16-bit (so read another byte,
+ merge into current character.
+
+ (MMO3_TYPEBITS)
+ 0xf - We have a complete symbol; parse the type, value
+ and serial number and do what should be done
+ with a symbol. The type and length information
+ is in j = (m & 0xf).
+
+ (MMO3_REGQUAL_BITS)
+ j == 0xf: A register variable. The following
+ byte tells which register.
+ j <= 8: An absolute symbol. Read j bytes as the
+ big-endian number the symbol equals.
+ A j = 2 with two zero bytes denotes an
+ unknown symbol.
+ j > 8: As with j <= 8, but add (0x20 << 56)
+ to the value in the following j - 8
+ bytes.
+
+ Then comes the serial number, as a variant of
+ uleb128, but better named ubeb128:
+ Read bytes and shift the previous value left 7
+ (multiply by 128). Add in the new byte, repeat
+ until a byte has bit 7 set. The serial number
+ is the computed value minus 128.
+
+ (MMO3_MIDDLE)
+ 0x20 - Traverse middle trie. (Read a new command byte
+ and recurse.) Decrement character position.
+
+ (MMO3_RIGHT)
+ 0x10 - Traverse right trie. (Read a new command byte and
+ recurse.)
+
+ Let's look again at the `lop_stab' for the trivial file (*note File
+layout::).
+
+ 0x980b0000 - lop_stab for ":Main" = 0, serial 1.
+ 0x203a4040
+ 0x10404020
+ 0x4d206120
+ 0x69016e00
+ 0x81000000
+
+ This forms the trivial trie (note that the path between ":" and "M"
+is redundant):
+
+ 203a ":"
+ 40 /
+ 40 /
+ 10 \
+ 40 /
+ 40 /
+ 204d "M"
+ 2061 "a"
+ 2069 "i"
+ 016e "n" is the last character in a full symbol, and
+ with a value represented in one byte.
+ 00 The value is 0.
+ 81 The serial number is 1.
+
+
+File: bfd.info, Node: mmo section mapping, Prev: Symbol-table, Up: mmo
+
+3.5.3 mmo section mapping
+-------------------------
+
+The implementation in BFD uses special data type 80 (decimal) to
+encapsulate and describe named sections, containing e.g. debug
+information. If needed, any datum in the encapsulation will be quoted
+using lop_quote. First comes a 32-bit word holding the number of
+32-bit words containing the zero-terminated zero-padded segment name.
+After the name there's a 32-bit word holding flags describing the
+section type. Then comes a 64-bit big-endian word with the section
+length (in bytes), then another with the section start address.
+Depending on the type of section, the contents might follow,
+zero-padded to 32-bit boundary. For a loadable section (such as data
+or code), the contents might follow at some later point, not
+necessarily immediately, as a lop_loc with the same start address as in
+the section description, followed by the contents. This in effect
+forms a descriptor that must be emitted before the actual contents.
+Sections described this way must not overlap.
+
+ For areas that don't have such descriptors, synthetic sections are
+formed by BFD. Consecutive contents in the two memory areas
+`0x0000...00' to `0x01ff...ff' and `0x2000...00' to `0x20ff...ff' are
+entered in sections named `.text' and `.data' respectively. If an area
+is not otherwise described, but would together with a neighboring lower
+area be less than `0x40000000' bytes long, it is joined with the lower
+area and the gap is zero-filled. For other cases, a new section is
+formed, named `.MMIX.sec.N'. Here, N is a number, a running count
+through the mmo file, starting at 0.
+
+ A loadable section specified as:
+
+ .section secname,"ax"
+ TETRA 1,2,3,4,-1,-2009
+ BYTE 80
+
+ and linked to address `0x4', is represented by the sequence:
+
+ 0x98080050 - lop_spec 80
+ 0x00000002 - two 32-bit words for the section name
+ 0x7365636e - "secn"
+ 0x616d6500 - "ame\0"
+ 0x00000033 - flags CODE, READONLY, LOAD, ALLOC
+ 0x00000000 - high 32 bits of section length
+ 0x0000001c - section length is 28 bytes; 6 * 4 + 1 + alignment to 32 bits
+ 0x00000000 - high 32 bits of section address
+ 0x00000004 - section address is 4
+ 0x98010002 - 64 bits with address of following data
+ 0x00000000 - high 32 bits of address
+ 0x00000004 - low 32 bits: data starts at address 4
+ 0x00000001 - 1
+ 0x00000002 - 2
+ 0x00000003 - 3
+ 0x00000004 - 4
+ 0xffffffff - -1
+ 0xfffff827 - -2009
+ 0x50000000 - 80 as a byte, padded with zeros.
+
+ Note that the lop_spec wrapping does not include the section
+contents. Compare this to a non-loaded section specified as:
+
+ .section thirdsec
+ TETRA 200001,100002
+ BYTE 38,40
+
+ This, when linked to address `0x200000000000001c', is represented by:
+
+ 0x98080050 - lop_spec 80
+ 0x00000002 - two 32-bit words for the section name
+ 0x7365636e - "thir"
+ 0x616d6500 - "dsec"
+ 0x00000010 - flag READONLY
+ 0x00000000 - high 32 bits of section length
+ 0x0000000c - section length is 12 bytes; 2 * 4 + 2 + alignment to 32 bits
+ 0x20000000 - high 32 bits of address
+ 0x0000001c - low 32 bits of address 0x200000000000001c
+ 0x00030d41 - 200001
+ 0x000186a2 - 100002
+ 0x26280000 - 38, 40 as bytes, padded with zeros
+
+ For the latter example, the section contents must not be loaded in
+memory, and is therefore specified as part of the special data. The
+address is usually unimportant but might provide information for e.g.
+the DWARF 2 debugging format.
+
+
+File: bfd.info, Node: GNU Free Documentation License, Next: BFD Index, Prev: BFD back ends, Up: Top
+
+ Version 1.3, 3 November 2008
+
+ Copyright (C) 2000, 2001, 2002, 2007, 2008 Free Software Foundation, Inc.
+ `http://fsf.org/'
+
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ 0. PREAMBLE
+
+ The purpose of this License is to make a manual, textbook, or other
+ functional and useful document "free" in the sense of freedom: to
+ assure everyone the effective freedom to copy and redistribute it,
+ with or without modifying it, either commercially or
+ noncommercially. Secondarily, this License preserves for the
+ author and publisher a way to get credit for their work, while not
+ being considered responsible for modifications made by others.
+
+ This License is a kind of "copyleft", which means that derivative
+ works of the document must themselves be free in the same sense.
+ It complements the GNU General Public License, which is a copyleft
+ license designed for free software.
+
+ We have designed this License in order to use it for manuals for
+ free software, because free software needs free documentation: a
+ free program should come with manuals providing the same freedoms
+ that the software does. But this License is not limited to
+ software manuals; it can be used for any textual work, regardless
+ of subject matter or whether it is published as a printed book.
+ We recommend this License principally for works whose purpose is
+ instruction or reference.
+
+ 1. APPLICABILITY AND DEFINITIONS
+
+ This License applies to any manual or other work, in any medium,
+ that contains a notice placed by the copyright holder saying it
+ can be distributed under the terms of this License. Such a notice
+ grants a world-wide, royalty-free license, unlimited in duration,
+ to use that work under the conditions stated herein. The
+ "Document", below, refers to any such manual or work. Any member
+ of the public is a licensee, and is addressed as "you". You
+ accept the license if you copy, modify or distribute the work in a
+ way requiring permission under copyright law.
+
+ A "Modified Version" of the Document means any work containing the
+ Document or a portion of it, either copied verbatim, or with
+ modifications and/or translated into another language.
+
+ A "Secondary Section" is a named appendix or a front-matter section
+ of the Document that deals exclusively with the relationship of the
+ publishers or authors of the Document to the Document's overall
+ subject (or to related matters) and contains nothing that could
+ fall directly within that overall subject. (Thus, if the Document
+ is in part a textbook of mathematics, a Secondary Section may not
+ explain any mathematics.) The relationship could be a matter of
+ historical connection with the subject or with related matters, or
+ of legal, commercial, philosophical, ethical or political position
+ regarding them.
+
+ The "Invariant Sections" are certain Secondary Sections whose
+ titles are designated, as being those of Invariant Sections, in
+ the notice that says that the Document is released under this
+ License. If a section does not fit the above definition of
+ Secondary then it is not allowed to be designated as Invariant.
+ The Document may contain zero Invariant Sections. If the Document
+ does not identify any Invariant Sections then there are none.
+
+ The "Cover Texts" are certain short passages of text that are
+ listed, as Front-Cover Texts or Back-Cover Texts, in the notice
+ that says that the Document is released under this License. A
+ Front-Cover Text may be at most 5 words, and a Back-Cover Text may
+ be at most 25 words.
+
+ A "Transparent" copy of the Document means a machine-readable copy,
+ represented in a format whose specification is available to the
+ general public, that is suitable for revising the document
+ straightforwardly with generic text editors or (for images
+ composed of pixels) generic paint programs or (for drawings) some
+ widely available drawing editor, and that is suitable for input to
+ text formatters or for automatic translation to a variety of
+ formats suitable for input to text formatters. A copy made in an
+ otherwise Transparent file format whose markup, or absence of
+ markup, has been arranged to thwart or discourage subsequent
+ modification by readers is not Transparent. An image format is
+ not Transparent if used for any substantial amount of text. A
+ copy that is not "Transparent" is called "Opaque".
+
+ Examples of suitable formats for Transparent copies include plain
+ ASCII without markup, Texinfo input format, LaTeX input format,
+ SGML or XML using a publicly available DTD, and
+ standard-conforming simple HTML, PostScript or PDF designed for
+ human modification. Examples of transparent image formats include
+ PNG, XCF and JPG. Opaque formats include proprietary formats that
+ can be read and edited only by proprietary word processors, SGML or
+ XML for which the DTD and/or processing tools are not generally
+ available, and the machine-generated HTML, PostScript or PDF
+ produced by some word processors for output purposes only.
+
+ The "Title Page" means, for a printed book, the title page itself,
+ plus such following pages as are needed to hold, legibly, the
+ material this License requires to appear in the title page. For
+ works in formats which do not have any title page as such, "Title
+ Page" means the text near the most prominent appearance of the
+ work's title, preceding the beginning of the body of the text.
+
+ The "publisher" means any person or entity that distributes copies
+ of the Document to the public.
+
+ A section "Entitled XYZ" means a named subunit of the Document
+ whose title either is precisely XYZ or contains XYZ in parentheses
+ following text that translates XYZ in another language. (Here XYZ
+ stands for a specific section name mentioned below, such as
+ "Acknowledgements", "Dedications", "Endorsements", or "History".)
+ To "Preserve the Title" of such a section when you modify the
+ Document means that it remains a section "Entitled XYZ" according
+ to this definition.
+
+ The Document may include Warranty Disclaimers next to the notice
+ which states that this License applies to the Document. These
+ Warranty Disclaimers are considered to be included by reference in
+ this License, but only as regards disclaiming warranties: any other
+ implication that these Warranty Disclaimers may have is void and
+ has no effect on the meaning of this License.
+
+ 2. VERBATIM COPYING
+
+ You may copy and distribute the Document in any medium, either
+ commercially or noncommercially, provided that this License, the
+ copyright notices, and the license notice saying this License
+ applies to the Document are reproduced in all copies, and that you
+ add no other conditions whatsoever to those of this License. You
+ may not use technical measures to obstruct or control the reading
+ or further copying of the copies you make or distribute. However,
+ you may accept compensation in exchange for copies. If you
+ distribute a large enough number of copies you must also follow
+ the conditions in section 3.
+
+ You may also lend copies, under the same conditions stated above,
+ and you may publicly display copies.
+
+ 3. COPYING IN QUANTITY
+
+ If you publish printed copies (or copies in media that commonly
+ have printed covers) of the Document, numbering more than 100, and
+ the Document's license notice requires Cover Texts, you must
+ enclose the copies in covers that carry, clearly and legibly, all
+ these Cover Texts: Front-Cover Texts on the front cover, and
+ Back-Cover Texts on the back cover. Both covers must also clearly
+ and legibly identify you as the publisher of these copies. The
+ front cover must present the full title with all words of the
+ title equally prominent and visible. You may add other material
+ on the covers in addition. Copying with changes limited to the
+ covers, as long as they preserve the title of the Document and
+ satisfy these conditions, can be treated as verbatim copying in
+ other respects.
+
+ If the required texts for either cover are too voluminous to fit
+ legibly, you should put the first ones listed (as many as fit
+ reasonably) on the actual cover, and continue the rest onto
+ adjacent pages.
+
+ If you publish or distribute Opaque copies of the Document
+ numbering more than 100, you must either include a
+ machine-readable Transparent copy along with each Opaque copy, or
+ state in or with each Opaque copy a computer-network location from
+ which the general network-using public has access to download
+ using public-standard network protocols a complete Transparent
+ copy of the Document, free of added material. If you use the
+ latter option, you must take reasonably prudent steps, when you
+ begin distribution of Opaque copies in quantity, to ensure that
+ this Transparent copy will remain thus accessible at the stated
+ location until at least one year after the last time you
+ distribute an Opaque copy (directly or through your agents or
+ retailers) of that edition to the public.
+
+ It is requested, but not required, that you contact the authors of
+ the Document well before redistributing any large number of
+ copies, to give them a chance to provide you with an updated
+ version of the Document.
+
+ 4. MODIFICATIONS
+
+ You may copy and distribute a Modified Version of the Document
+ under the conditions of sections 2 and 3 above, provided that you
+ release the Modified Version under precisely this License, with
+ the Modified Version filling the role of the Document, thus
+ licensing distribution and modification of the Modified Version to
+ whoever possesses a copy of it. In addition, you must do these
+ things in the Modified Version:
+
+ A. Use in the Title Page (and on the covers, if any) a title
+ distinct from that of the Document, and from those of
+ previous versions (which should, if there were any, be listed
+ in the History section of the Document). You may use the
+ same title as a previous version if the original publisher of
+ that version gives permission.
+
+ B. List on the Title Page, as authors, one or more persons or
+ entities responsible for authorship of the modifications in
+ the Modified Version, together with at least five of the
+ principal authors of the Document (all of its principal
+ authors, if it has fewer than five), unless they release you
+ from this requirement.
+
+ C. State on the Title page the name of the publisher of the
+ Modified Version, as the publisher.
+
+ D. Preserve all the copyright notices of the Document.
+
+ E. Add an appropriate copyright notice for your modifications
+ adjacent to the other copyright notices.
+
+ F. Include, immediately after the copyright notices, a license
+ notice giving the public permission to use the Modified
+ Version under the terms of this License, in the form shown in
+ the Addendum below.
+
+ G. Preserve in that license notice the full lists of Invariant
+ Sections and required Cover Texts given in the Document's
+ license notice.
+
+ H. Include an unaltered copy of this License.
+
+ I. Preserve the section Entitled "History", Preserve its Title,
+ and add to it an item stating at least the title, year, new
+ authors, and publisher of the Modified Version as given on
+ the Title Page. If there is no section Entitled "History" in
+ the Document, create one stating the title, year, authors,
+ and publisher of the Document as given on its Title Page,
+ then add an item describing the Modified Version as stated in
+ the previous sentence.
+
+ J. Preserve the network location, if any, given in the Document
+ for public access to a Transparent copy of the Document, and
+ likewise the network locations given in the Document for
+ previous versions it was based on. These may be placed in
+ the "History" section. You may omit a network location for a
+ work that was published at least four years before the
+ Document itself, or if the original publisher of the version
+ it refers to gives permission.
+
+ K. For any section Entitled "Acknowledgements" or "Dedications",
+ Preserve the Title of the section, and preserve in the
+ section all the substance and tone of each of the contributor
+ acknowledgements and/or dedications given therein.
+
+ L. Preserve all the Invariant Sections of the Document,
+ unaltered in their text and in their titles. Section numbers
+ or the equivalent are not considered part of the section
+ titles.
+
+ M. Delete any section Entitled "Endorsements". Such a section
+ may not be included in the Modified Version.
+
+ N. Do not retitle any existing section to be Entitled
+ "Endorsements" or to conflict in title with any Invariant
+ Section.
+
+ O. Preserve any Warranty Disclaimers.
+
+ If the Modified Version includes new front-matter sections or
+ appendices that qualify as Secondary Sections and contain no
+ material copied from the Document, you may at your option
+ designate some or all of these sections as invariant. To do this,
+ add their titles to the list of Invariant Sections in the Modified
+ Version's license notice. These titles must be distinct from any
+ other section titles.
+
+ You may add a section Entitled "Endorsements", provided it contains
+ nothing but endorsements of your Modified Version by various
+ parties--for example, statements of peer review or that the text
+ has been approved by an organization as the authoritative
+ definition of a standard.
+
+ You may add a passage of up to five words as a Front-Cover Text,
+ and a passage of up to 25 words as a Back-Cover Text, to the end
+ of the list of Cover Texts in the Modified Version. Only one
+ passage of Front-Cover Text and one of Back-Cover Text may be
+ added by (or through arrangements made by) any one entity. If the
+ Document already includes a cover text for the same cover,
+ previously added by you or by arrangement made by the same entity
+ you are acting on behalf of, you may not add another; but you may
+ replace the old one, on explicit permission from the previous
+ publisher that added the old one.
+
+ The author(s) and publisher(s) of the Document do not by this
+ License give permission to use their names for publicity for or to
+ assert or imply endorsement of any Modified Version.
+
+ 5. COMBINING DOCUMENTS
+
+ You may combine the Document with other documents released under
+ this License, under the terms defined in section 4 above for
+ modified versions, provided that you include in the combination
+ all of the Invariant Sections of all of the original documents,
+ unmodified, and list them all as Invariant Sections of your
+ combined work in its license notice, and that you preserve all
+ their Warranty Disclaimers.
+
+ The combined work need only contain one copy of this License, and
+ multiple identical Invariant Sections may be replaced with a single
+ copy. If there are multiple Invariant Sections with the same name
+ but different contents, make the title of each such section unique
+ by adding at the end of it, in parentheses, the name of the
+ original author or publisher of that section if known, or else a
+ unique number. Make the same adjustment to the section titles in
+ the list of Invariant Sections in the license notice of the
+ combined work.
+
+ In the combination, you must combine any sections Entitled
+ "History" in the various original documents, forming one section
+ Entitled "History"; likewise combine any sections Entitled
+ "Acknowledgements", and any sections Entitled "Dedications". You
+ must delete all sections Entitled "Endorsements."
+
+ 6. COLLECTIONS OF DOCUMENTS
+
+ You may make a collection consisting of the Document and other
+ documents released under this License, and replace the individual
+ copies of this License in the various documents with a single copy
+ that is included in the collection, provided that you follow the
+ rules of this License for verbatim copying of each of the
+ documents in all other respects.
+
+ You may extract a single document from such a collection, and
+ distribute it individually under this License, provided you insert
+ a copy of this License into the extracted document, and follow
+ this License in all other respects regarding verbatim copying of
+ that document.
+
+ 7. AGGREGATION WITH INDEPENDENT WORKS
+
+ A compilation of the Document or its derivatives with other
+ separate and independent documents or works, in or on a volume of
+ a storage or distribution medium, is called an "aggregate" if the
+ copyright resulting from the compilation is not used to limit the
+ legal rights of the compilation's users beyond what the individual
+ works permit. When the Document is included in an aggregate, this
+ License does not apply to the other works in the aggregate which
+ are not themselves derivative works of the Document.
+
+ If the Cover Text requirement of section 3 is applicable to these
+ copies of the Document, then if the Document is less than one half
+ of the entire aggregate, the Document's Cover Texts may be placed
+ on covers that bracket the Document within the aggregate, or the
+ electronic equivalent of covers if the Document is in electronic
+ form. Otherwise they must appear on printed covers that bracket
+ the whole aggregate.
+
+ 8. TRANSLATION
+
+ Translation is considered a kind of modification, so you may
+ distribute translations of the Document under the terms of section
+ 4. Replacing Invariant Sections with translations requires special
+ permission from their copyright holders, but you may include
+ translations of some or all Invariant Sections in addition to the
+ original versions of these Invariant Sections. You may include a
+ translation of this License, and all the license notices in the
+ Document, and any Warranty Disclaimers, provided that you also
+ include the original English version of this License and the
+ original versions of those notices and disclaimers. In case of a
+ disagreement between the translation and the original version of
+ this License or a notice or disclaimer, the original version will
+ prevail.
+
+ If a section in the Document is Entitled "Acknowledgements",
+ "Dedications", or "History", the requirement (section 4) to
+ Preserve its Title (section 1) will typically require changing the
+ actual title.
+
+ 9. TERMINATION
+
+ You may not copy, modify, sublicense, or distribute the Document
+ except as expressly provided under this License. Any attempt
+ otherwise to copy, modify, sublicense, or distribute it is void,
+ and will automatically terminate your rights under this License.
+
+ However, if you cease all violation of this License, then your
+ license from a particular copyright holder is reinstated (a)
+ provisionally, unless and until the copyright holder explicitly
+ and finally terminates your license, and (b) permanently, if the
+ copyright holder fails to notify you of the violation by some
+ reasonable means prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+ reinstated permanently if the copyright holder notifies you of the
+ violation by some reasonable means, this is the first time you have
+ received notice of violation of this License (for any work) from
+ that copyright holder, and you cure the violation prior to 30 days
+ after your receipt of the notice.
+
+ Termination of your rights under this section does not terminate
+ the licenses of parties who have received copies or rights from
+ you under this License. If your rights have been terminated and
+ not permanently reinstated, receipt of a copy of some or all of
+ the same material does not give you any rights to use it.
+
+ 10. FUTURE REVISIONS OF THIS LICENSE
+
+ The Free Software Foundation may publish new, revised versions of
+ the GNU Free Documentation 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. See
+ `http://www.gnu.org/copyleft/'.
+
+ Each version of the License is given a distinguishing version
+ number. If the Document specifies that a particular numbered
+ version of this License "or any later version" applies to it, you
+ have the option of following the terms and conditions either of
+ that specified version or of any later version that has been
+ published (not as a draft) by the Free Software Foundation. If
+ the Document does not specify a version number of this License,
+ you may choose any version ever published (not as a draft) by the
+ Free Software Foundation. If the Document specifies that a proxy
+ can decide which future versions of this License can be used, that
+ proxy's public statement of acceptance of a version permanently
+ authorizes you to choose that version for the Document.
+
+ 11. RELICENSING
+
+ "Massive Multiauthor Collaboration Site" (or "MMC Site") means any
+ World Wide Web server that publishes copyrightable works and also
+ provides prominent facilities for anybody to edit those works. A
+ public wiki that anybody can edit is an example of such a server.
+ A "Massive Multiauthor Collaboration" (or "MMC") contained in the
+ site means any set of copyrightable works thus published on the MMC
+ site.
+
+ "CC-BY-SA" means the Creative Commons Attribution-Share Alike 3.0
+ license published by Creative Commons Corporation, a not-for-profit
+ corporation with a principal place of business in San Francisco,
+ California, as well as future copyleft versions of that license
+ published by that same organization.
+
+ "Incorporate" means to publish or republish a Document, in whole or
+ in part, as part of another Document.
+
+ An MMC is "eligible for relicensing" if it is licensed under this
+ License, and if all works that were first published under this
+ License somewhere other than this MMC, and subsequently
+ incorporated in whole or in part into the MMC, (1) had no cover
+ texts or invariant sections, and (2) were thus incorporated prior
+ to November 1, 2008.
+
+ The operator of an MMC Site may republish an MMC contained in the
+ site under CC-BY-SA on the same site at any time before August 1,
+ 2009, provided the MMC is eligible for relicensing.
+
+
+ADDENDUM: How to use this License for your documents
+====================================================
+
+To use this License in a document you have written, include a copy of
+the License in the document and put the following copyright and license
+notices just after the title page:
+
+ Copyright (C) YEAR YOUR NAME.
+ Permission is granted to copy, distribute and/or modify this document
+ under the terms of the GNU Free Documentation License, Version 1.3
+ or any later version published by the Free Software Foundation;
+ with no Invariant Sections, no Front-Cover Texts, and no Back-Cover
+ Texts. A copy of the license is included in the section entitled ``GNU
+ Free Documentation License''.
+
+ If you have Invariant Sections, Front-Cover Texts and Back-Cover
+Texts, replace the "with...Texts." line with this:
+
+ with the Invariant Sections being LIST THEIR TITLES, with
+ the Front-Cover Texts being LIST, and with the Back-Cover Texts
+ being LIST.
+
+ If you have Invariant Sections without Cover Texts, or some other
+combination of the three, merge those two alternatives to suit the
+situation.
+
+ If your document contains nontrivial examples of program code, we
+recommend releasing these examples in parallel under your choice of
+free software license, such as the GNU General Public License, to
+permit their use in free software.
+
+
+File: bfd.info, Node: BFD Index, Prev: GNU Free Documentation License, Up: Top
+
+BFD Index
+*********
+
+
+* Menu:
+
+* _bfd_final_link_relocate: Relocating the section contents.
+ (line 22)
+* _bfd_generic_link_add_archive_symbols: Adding symbols from an archive.
+ (line 15)
+* _bfd_generic_link_add_one_symbol: Adding symbols from an object file.
+ (line 19)
+* _bfd_generic_make_empty_symbol: symbol handling functions.
+ (line 92)
+* _bfd_link_add_symbols in target vector: Adding Symbols to the Hash Table.
+ (line 6)
+* _bfd_link_final_link in target vector: Performing the Final Link.
+ (line 6)
+* _bfd_link_hash_table_create in target vector: Creating a Linker Hash Table.
+ (line 6)
+* _bfd_relocate_contents: Relocating the section contents.
+ (line 22)
+* aout_SIZE_machine_type: aout. (line 147)
+* aout_SIZE_mkobject: aout. (line 139)
+* aout_SIZE_new_section_hook: aout. (line 177)
+* aout_SIZE_set_arch_mach: aout. (line 164)
+* aout_SIZE_some_aout_object_p: aout. (line 125)
+* aout_SIZE_swap_exec_header_in: aout. (line 101)
+* aout_SIZE_swap_exec_header_out: aout. (line 113)
+* arelent_chain: typedef arelent. (line 336)
+* BFD: Overview. (line 6)
+* BFD canonical format: Canonical format. (line 11)
+* bfd_alloc: Opening and Closing.
+ (line 239)
+* bfd_alloc2: Opening and Closing.
+ (line 248)
+* bfd_alt_mach_code: Miscellaneous. (line 307)
+* bfd_arch_bits_per_address: Architectures. (line 598)
+* bfd_arch_bits_per_byte: Architectures. (line 590)
+* bfd_arch_default_fill: Architectures. (line 679)
+* bfd_arch_get_compatible: Architectures. (line 533)
+* bfd_arch_list: Architectures. (line 524)
+* bfd_arch_mach_octets_per_byte: Architectures. (line 667)
+* BFD_ARELOC_BFIN_ADD: howto manager. (line 1127)
+* BFD_ARELOC_BFIN_ADDR: howto manager. (line 1178)
+* BFD_ARELOC_BFIN_AND: howto manager. (line 1148)
+* BFD_ARELOC_BFIN_COMP: howto manager. (line 1169)
+* BFD_ARELOC_BFIN_CONST: howto manager. (line 1124)
+* BFD_ARELOC_BFIN_DIV: howto manager. (line 1136)
+* BFD_ARELOC_BFIN_HWPAGE: howto manager. (line 1175)
+* BFD_ARELOC_BFIN_LAND: howto manager. (line 1157)
+* BFD_ARELOC_BFIN_LEN: howto manager. (line 1163)
+* BFD_ARELOC_BFIN_LOR: howto manager. (line 1160)
+* BFD_ARELOC_BFIN_LSHIFT: howto manager. (line 1142)
+* BFD_ARELOC_BFIN_MOD: howto manager. (line 1139)
+* BFD_ARELOC_BFIN_MULT: howto manager. (line 1133)
+* BFD_ARELOC_BFIN_NEG: howto manager. (line 1166)
+* BFD_ARELOC_BFIN_OR: howto manager. (line 1151)
+* BFD_ARELOC_BFIN_PAGE: howto manager. (line 1172)
+* BFD_ARELOC_BFIN_PUSH: howto manager. (line 1121)
+* BFD_ARELOC_BFIN_RSHIFT: howto manager. (line 1145)
+* BFD_ARELOC_BFIN_SUB: howto manager. (line 1130)
+* BFD_ARELOC_BFIN_XOR: howto manager. (line 1154)
+* bfd_cache_close: File Caching. (line 26)
+* bfd_cache_close_all: File Caching. (line 39)
+* bfd_cache_init: File Caching. (line 18)
+* bfd_calc_gnu_debuglink_crc32: Opening and Closing.
+ (line 275)
+* bfd_canonicalize_reloc: Miscellaneous. (line 19)
+* bfd_canonicalize_symtab: symbol handling functions.
+ (line 50)
+* bfd_check_format: Formats. (line 21)
+* bfd_check_format_matches: Formats. (line 52)
+* bfd_check_overflow: typedef arelent. (line 348)
+* bfd_close: Opening and Closing.
+ (line 161)
+* bfd_close_all_done: Opening and Closing.
+ (line 179)
+* bfd_coff_backend_data: coff. (line 308)
+* bfd_copy_private_bfd_data: Miscellaneous. (line 160)
+* bfd_copy_private_header_data: Miscellaneous. (line 142)
+* bfd_copy_private_section_data: section prototypes. (line 278)
+* bfd_copy_private_symbol_data: symbol handling functions.
+ (line 140)
+* bfd_core_file_failing_command: Core Files. (line 12)
+* bfd_core_file_failing_signal: Core Files. (line 21)
+* bfd_core_file_pid: Core Files. (line 30)
+* bfd_create: Opening and Closing.
+ (line 198)
+* bfd_create_gnu_debuglink_section: Opening and Closing.
+ (line 387)
+* bfd_decode_symclass: symbol handling functions.
+ (line 111)
+* bfd_default_arch_struct: Architectures. (line 545)
+* bfd_default_compatible: Architectures. (line 607)
+* bfd_default_reloc_type_lookup: howto manager. (line 3524)
+* bfd_default_scan: Architectures. (line 616)
+* bfd_default_set_arch_mach: Architectures. (line 563)
+* bfd_demangle: Miscellaneous. (line 358)
+* bfd_emul_get_commonpagesize: Miscellaneous. (line 338)
+* bfd_emul_get_maxpagesize: Miscellaneous. (line 318)
+* bfd_emul_set_commonpagesize: Miscellaneous. (line 349)
+* bfd_emul_set_maxpagesize: Miscellaneous. (line 329)
+* bfd_errmsg: Error reporting. (line 67)
+* bfd_fdopenr: Opening and Closing.
+ (line 57)
+* bfd_fill_in_gnu_debuglink_section: Opening and Closing.
+ (line 401)
+* bfd_find_target: bfd_target. (line 466)
+* bfd_find_version_for_sym: Writing the symbol table.
+ (line 81)
+* bfd_follow_gnu_debugaltlink: Opening and Closing.
+ (line 367)
+* bfd_follow_gnu_debuglink: Opening and Closing.
+ (line 346)
+* bfd_fopen: Opening and Closing.
+ (line 12)
+* bfd_format_string: Formats. (line 79)
+* bfd_generic_define_common_symbol: Writing the symbol table.
+ (line 68)
+* bfd_generic_discard_group: section prototypes. (line 304)
+* bfd_generic_gc_sections: howto manager. (line 3555)
+* bfd_generic_get_relocated_section_contents: howto manager. (line 3585)
+* bfd_generic_is_group_section: section prototypes. (line 296)
+* bfd_generic_lookup_section_flags: howto manager. (line 3565)
+* bfd_generic_merge_sections: howto manager. (line 3575)
+* bfd_generic_relax_section: howto manager. (line 3542)
+* bfd_get_alt_debug_link_info: Opening and Closing.
+ (line 300)
+* bfd_get_arch: Architectures. (line 574)
+* bfd_get_arch_info: Architectures. (line 626)
+* bfd_get_arch_size: Miscellaneous. (line 63)
+* bfd_get_assert_handler: Error reporting. (line 150)
+* bfd_get_debug_link_info: Opening and Closing.
+ (line 289)
+* bfd_get_error: Error reporting. (line 48)
+* bfd_get_error_handler: Error reporting. (line 118)
+* bfd_get_gp_size: Miscellaneous. (line 106)
+* bfd_get_linker_section: section prototypes. (line 36)
+* bfd_get_mach: Architectures. (line 582)
+* bfd_get_mtime: Miscellaneous. (line 409)
+* bfd_get_next_mapent: Archives. (line 58)
+* bfd_get_next_section_by_name: section prototypes. (line 26)
+* bfd_get_reloc_code_name: howto manager. (line 3533)
+* bfd_get_reloc_size: typedef arelent. (line 327)
+* bfd_get_reloc_upper_bound: Miscellaneous. (line 9)
+* bfd_get_section_by_name: section prototypes. (line 17)
+* bfd_get_section_by_name_if: section prototypes. (line 45)
+* bfd_get_section_contents: section prototypes. (line 251)
+* bfd_get_sign_extend_vma: Miscellaneous. (line 78)
+* bfd_get_size <1>: Internal. (line 25)
+* bfd_get_size: Miscellaneous. (line 418)
+* bfd_get_symtab_upper_bound: symbol handling functions.
+ (line 6)
+* bfd_get_target_info: bfd_target. (line 482)
+* bfd_get_unique_section_name: section prototypes. (line 64)
+* bfd_h_put_size: Internal. (line 97)
+* bfd_hash_allocate: Creating and Freeing a Hash Table.
+ (line 17)
+* bfd_hash_lookup: Looking Up or Entering a String.
+ (line 6)
+* bfd_hash_newfunc: Creating and Freeing a Hash Table.
+ (line 12)
+* bfd_hash_set_default_size: Creating and Freeing a Hash Table.
+ (line 25)
+* bfd_hash_table_free: Creating and Freeing a Hash Table.
+ (line 21)
+* bfd_hash_table_init: Creating and Freeing a Hash Table.
+ (line 6)
+* bfd_hash_table_init_n: Creating and Freeing a Hash Table.
+ (line 6)
+* bfd_hash_traverse: Traversing a Hash Table.
+ (line 6)
+* bfd_hide_sym_by_version: Writing the symbol table.
+ (line 93)
+* bfd_init: Initialization. (line 11)
+* bfd_install_relocation: typedef arelent. (line 389)
+* bfd_is_local_label: symbol handling functions.
+ (line 17)
+* bfd_is_local_label_name: symbol handling functions.
+ (line 26)
+* bfd_is_target_special_symbol: symbol handling functions.
+ (line 38)
+* bfd_is_undefined_symclass: symbol handling functions.
+ (line 120)
+* bfd_link_split_section: Writing the symbol table.
+ (line 44)
+* bfd_log2: Internal. (line 164)
+* bfd_lookup_arch: Architectures. (line 634)
+* bfd_make_debug_symbol: symbol handling functions.
+ (line 102)
+* bfd_make_empty_symbol: symbol handling functions.
+ (line 78)
+* bfd_make_readable: Opening and Closing.
+ (line 225)
+* bfd_make_section: section prototypes. (line 143)
+* bfd_make_section_anyway: section prototypes. (line 114)
+* bfd_make_section_anyway_with_flags: section prototypes. (line 96)
+* bfd_make_section_old_way: section prototypes. (line 76)
+* bfd_make_section_with_flags: section prototypes. (line 130)
+* bfd_make_writable: Opening and Closing.
+ (line 211)
+* bfd_malloc_and_get_section: section prototypes. (line 268)
+* bfd_map_over_sections: section prototypes. (line 178)
+* bfd_merge_private_bfd_data: Miscellaneous. (line 176)
+* bfd_mmap: Miscellaneous. (line 447)
+* bfd_octets_per_byte: Architectures. (line 657)
+* bfd_open_file: File Caching. (line 52)
+* bfd_openr: Opening and Closing.
+ (line 38)
+* bfd_openr_iovec: Opening and Closing.
+ (line 95)
+* bfd_openr_next_archived_file: Archives. (line 84)
+* bfd_openstreamr: Opening and Closing.
+ (line 83)
+* bfd_openw: Opening and Closing.
+ (line 146)
+* bfd_perform_relocation: typedef arelent. (line 364)
+* bfd_perror: Error reporting. (line 76)
+* bfd_print_symbol_vandf: symbol handling functions.
+ (line 70)
+* bfd_printable_arch_mach: Architectures. (line 645)
+* bfd_printable_name: Architectures. (line 505)
+* bfd_put_size: Internal. (line 22)
+* BFD_RELOC_12_PCREL: howto manager. (line 39)
+* BFD_RELOC_14: howto manager. (line 31)
+* BFD_RELOC_16: howto manager. (line 30)
+* BFD_RELOC_16_BASEREL: howto manager. (line 99)
+* BFD_RELOC_16_GOT_PCREL: howto manager. (line 52)
+* BFD_RELOC_16_GOTOFF: howto manager. (line 55)
+* BFD_RELOC_16_PCREL: howto manager. (line 38)
+* BFD_RELOC_16_PCREL_S2: howto manager. (line 111)
+* BFD_RELOC_16_PLT_PCREL: howto manager. (line 63)
+* BFD_RELOC_16_PLTOFF: howto manager. (line 67)
+* BFD_RELOC_16C_ABS20: howto manager. (line 2465)
+* BFD_RELOC_16C_ABS20_C: howto manager. (line 2466)
+* BFD_RELOC_16C_ABS24: howto manager. (line 2467)
+* BFD_RELOC_16C_ABS24_C: howto manager. (line 2468)
+* BFD_RELOC_16C_DISP04: howto manager. (line 2445)
+* BFD_RELOC_16C_DISP04_C: howto manager. (line 2446)
+* BFD_RELOC_16C_DISP08: howto manager. (line 2447)
+* BFD_RELOC_16C_DISP08_C: howto manager. (line 2448)
+* BFD_RELOC_16C_DISP16: howto manager. (line 2449)
+* BFD_RELOC_16C_DISP16_C: howto manager. (line 2450)
+* BFD_RELOC_16C_DISP24: howto manager. (line 2451)
+* BFD_RELOC_16C_DISP24_C: howto manager. (line 2452)
+* BFD_RELOC_16C_DISP24a: howto manager. (line 2453)
+* BFD_RELOC_16C_DISP24a_C: howto manager. (line 2454)
+* BFD_RELOC_16C_IMM04: howto manager. (line 2469)
+* BFD_RELOC_16C_IMM04_C: howto manager. (line 2470)
+* BFD_RELOC_16C_IMM16: howto manager. (line 2471)
+* BFD_RELOC_16C_IMM16_C: howto manager. (line 2472)
+* BFD_RELOC_16C_IMM20: howto manager. (line 2473)
+* BFD_RELOC_16C_IMM20_C: howto manager. (line 2474)
+* BFD_RELOC_16C_IMM24: howto manager. (line 2475)
+* BFD_RELOC_16C_IMM24_C: howto manager. (line 2476)
+* BFD_RELOC_16C_IMM32: howto manager. (line 2477)
+* BFD_RELOC_16C_IMM32_C: howto manager. (line 2478)
+* BFD_RELOC_16C_NUM08: howto manager. (line 2439)
+* BFD_RELOC_16C_NUM08_C: howto manager. (line 2440)
+* BFD_RELOC_16C_NUM16: howto manager. (line 2441)
+* BFD_RELOC_16C_NUM16_C: howto manager. (line 2442)
+* BFD_RELOC_16C_NUM32: howto manager. (line 2443)
+* BFD_RELOC_16C_NUM32_C: howto manager. (line 2444)
+* BFD_RELOC_16C_REG04: howto manager. (line 2455)
+* BFD_RELOC_16C_REG04_C: howto manager. (line 2456)
+* BFD_RELOC_16C_REG04a: howto manager. (line 2457)
+* BFD_RELOC_16C_REG04a_C: howto manager. (line 2458)
+* BFD_RELOC_16C_REG14: howto manager. (line 2459)
+* BFD_RELOC_16C_REG14_C: howto manager. (line 2460)
+* BFD_RELOC_16C_REG16: howto manager. (line 2461)
+* BFD_RELOC_16C_REG16_C: howto manager. (line 2462)
+* BFD_RELOC_16C_REG20: howto manager. (line 2463)
+* BFD_RELOC_16C_REG20_C: howto manager. (line 2464)
+* BFD_RELOC_23_PCREL_S2: howto manager. (line 112)
+* BFD_RELOC_24: howto manager. (line 29)
+* BFD_RELOC_24_PCREL: howto manager. (line 37)
+* BFD_RELOC_24_PLT_PCREL: howto manager. (line 62)
+* BFD_RELOC_26: howto manager. (line 28)
+* BFD_RELOC_32: howto manager. (line 27)
+* BFD_RELOC_32_BASEREL: howto manager. (line 98)
+* BFD_RELOC_32_GOT_PCREL: howto manager. (line 51)
+* BFD_RELOC_32_GOTOFF: howto manager. (line 54)
+* BFD_RELOC_32_PCREL: howto manager. (line 36)
+* BFD_RELOC_32_PCREL_S2: howto manager. (line 110)
+* BFD_RELOC_32_PLT_PCREL: howto manager. (line 61)
+* BFD_RELOC_32_PLTOFF: howto manager. (line 66)
+* BFD_RELOC_32_SECREL: howto manager. (line 48)
+* BFD_RELOC_386_COPY: howto manager. (line 583)
+* BFD_RELOC_386_GLOB_DAT: howto manager. (line 584)
+* BFD_RELOC_386_GOT32: howto manager. (line 581)
+* BFD_RELOC_386_GOTOFF: howto manager. (line 587)
+* BFD_RELOC_386_GOTPC: howto manager. (line 588)
+* BFD_RELOC_386_IRELATIVE: howto manager. (line 604)
+* BFD_RELOC_386_JUMP_SLOT: howto manager. (line 585)
+* BFD_RELOC_386_PLT32: howto manager. (line 582)
+* BFD_RELOC_386_RELATIVE: howto manager. (line 586)
+* BFD_RELOC_386_TLS_DESC: howto manager. (line 603)
+* BFD_RELOC_386_TLS_DESC_CALL: howto manager. (line 602)
+* BFD_RELOC_386_TLS_DTPMOD32: howto manager. (line 598)
+* BFD_RELOC_386_TLS_DTPOFF32: howto manager. (line 599)
+* BFD_RELOC_386_TLS_GD: howto manager. (line 593)
+* BFD_RELOC_386_TLS_GOTDESC: howto manager. (line 601)
+* BFD_RELOC_386_TLS_GOTIE: howto manager. (line 591)
+* BFD_RELOC_386_TLS_IE: howto manager. (line 590)
+* BFD_RELOC_386_TLS_IE_32: howto manager. (line 596)
+* BFD_RELOC_386_TLS_LDM: howto manager. (line 594)
+* BFD_RELOC_386_TLS_LDO_32: howto manager. (line 595)
+* BFD_RELOC_386_TLS_LE: howto manager. (line 592)
+* BFD_RELOC_386_TLS_LE_32: howto manager. (line 597)
+* BFD_RELOC_386_TLS_TPOFF: howto manager. (line 589)
+* BFD_RELOC_386_TLS_TPOFF32: howto manager. (line 600)
+* BFD_RELOC_390_12: howto manager. (line 2048)
+* BFD_RELOC_390_20: howto manager. (line 2160)
+* BFD_RELOC_390_COPY: howto manager. (line 2057)
+* BFD_RELOC_390_GLOB_DAT: howto manager. (line 2060)
+* BFD_RELOC_390_GOT12: howto manager. (line 2051)
+* BFD_RELOC_390_GOT16: howto manager. (line 2072)
+* BFD_RELOC_390_GOT20: howto manager. (line 2161)
+* BFD_RELOC_390_GOT64: howto manager. (line 2102)
+* BFD_RELOC_390_GOTENT: howto manager. (line 2108)
+* BFD_RELOC_390_GOTOFF64: howto manager. (line 2111)
+* BFD_RELOC_390_GOTPC: howto manager. (line 2069)
+* BFD_RELOC_390_GOTPCDBL: howto manager. (line 2099)
+* BFD_RELOC_390_GOTPLT12: howto manager. (line 2114)
+* BFD_RELOC_390_GOTPLT16: howto manager. (line 2117)
+* BFD_RELOC_390_GOTPLT20: howto manager. (line 2162)
+* BFD_RELOC_390_GOTPLT32: howto manager. (line 2120)
+* BFD_RELOC_390_GOTPLT64: howto manager. (line 2123)
+* BFD_RELOC_390_GOTPLTENT: howto manager. (line 2126)
+* BFD_RELOC_390_IRELATIVE: howto manager. (line 2166)
+* BFD_RELOC_390_JMP_SLOT: howto manager. (line 2063)
+* BFD_RELOC_390_PC12DBL: howto manager. (line 2075)
+* BFD_RELOC_390_PC16DBL: howto manager. (line 2081)
+* BFD_RELOC_390_PC24DBL: howto manager. (line 2087)
+* BFD_RELOC_390_PC32DBL: howto manager. (line 2093)
+* BFD_RELOC_390_PLT12DBL: howto manager. (line 2078)
+* BFD_RELOC_390_PLT16DBL: howto manager. (line 2084)
+* BFD_RELOC_390_PLT24DBL: howto manager. (line 2090)
+* BFD_RELOC_390_PLT32: howto manager. (line 2054)
+* BFD_RELOC_390_PLT32DBL: howto manager. (line 2096)
+* BFD_RELOC_390_PLT64: howto manager. (line 2105)
+* BFD_RELOC_390_PLTOFF16: howto manager. (line 2129)
+* BFD_RELOC_390_PLTOFF32: howto manager. (line 2132)
+* BFD_RELOC_390_PLTOFF64: howto manager. (line 2135)
+* BFD_RELOC_390_RELATIVE: howto manager. (line 2066)
+* BFD_RELOC_390_TLS_DTPMOD: howto manager. (line 2155)
+* BFD_RELOC_390_TLS_DTPOFF: howto manager. (line 2156)
+* BFD_RELOC_390_TLS_GD32: howto manager. (line 2141)
+* BFD_RELOC_390_TLS_GD64: howto manager. (line 2142)
+* BFD_RELOC_390_TLS_GDCALL: howto manager. (line 2139)
+* BFD_RELOC_390_TLS_GOTIE12: howto manager. (line 2143)
+* BFD_RELOC_390_TLS_GOTIE20: howto manager. (line 2163)
+* BFD_RELOC_390_TLS_GOTIE32: howto manager. (line 2144)
+* BFD_RELOC_390_TLS_GOTIE64: howto manager. (line 2145)
+* BFD_RELOC_390_TLS_IE32: howto manager. (line 2148)
+* BFD_RELOC_390_TLS_IE64: howto manager. (line 2149)
+* BFD_RELOC_390_TLS_IEENT: howto manager. (line 2150)
+* BFD_RELOC_390_TLS_LDCALL: howto manager. (line 2140)
+* BFD_RELOC_390_TLS_LDM32: howto manager. (line 2146)
+* BFD_RELOC_390_TLS_LDM64: howto manager. (line 2147)
+* BFD_RELOC_390_TLS_LDO32: howto manager. (line 2153)
+* BFD_RELOC_390_TLS_LDO64: howto manager. (line 2154)
+* BFD_RELOC_390_TLS_LE32: howto manager. (line 2151)
+* BFD_RELOC_390_TLS_LE64: howto manager. (line 2152)
+* BFD_RELOC_390_TLS_LOAD: howto manager. (line 2138)
+* BFD_RELOC_390_TLS_TPOFF: howto manager. (line 2157)
+* BFD_RELOC_64: howto manager. (line 26)
+* BFD_RELOC_64_PCREL: howto manager. (line 35)
+* BFD_RELOC_64_PLT_PCREL: howto manager. (line 60)
+* BFD_RELOC_64_PLTOFF: howto manager. (line 65)
+* BFD_RELOC_68K_GLOB_DAT: howto manager. (line 78)
+* BFD_RELOC_68K_JMP_SLOT: howto manager. (line 79)
+* BFD_RELOC_68K_RELATIVE: howto manager. (line 80)
+* BFD_RELOC_68K_TLS_GD16: howto manager. (line 82)
+* BFD_RELOC_68K_TLS_GD32: howto manager. (line 81)
+* BFD_RELOC_68K_TLS_GD8: howto manager. (line 83)
+* BFD_RELOC_68K_TLS_IE16: howto manager. (line 91)
+* BFD_RELOC_68K_TLS_IE32: howto manager. (line 90)
+* BFD_RELOC_68K_TLS_IE8: howto manager. (line 92)
+* BFD_RELOC_68K_TLS_LDM16: howto manager. (line 85)
+* BFD_RELOC_68K_TLS_LDM32: howto manager. (line 84)
+* BFD_RELOC_68K_TLS_LDM8: howto manager. (line 86)
+* BFD_RELOC_68K_TLS_LDO16: howto manager. (line 88)
+* BFD_RELOC_68K_TLS_LDO32: howto manager. (line 87)
+* BFD_RELOC_68K_TLS_LDO8: howto manager. (line 89)
+* BFD_RELOC_68K_TLS_LE16: howto manager. (line 94)
+* BFD_RELOC_68K_TLS_LE32: howto manager. (line 93)
+* BFD_RELOC_68K_TLS_LE8: howto manager. (line 95)
+* BFD_RELOC_8: howto manager. (line 32)
+* BFD_RELOC_860_COPY: howto manager. (line 2593)
+* BFD_RELOC_860_GLOB_DAT: howto manager. (line 2594)
+* BFD_RELOC_860_HAGOT: howto manager. (line 2619)
+* BFD_RELOC_860_HAGOTOFF: howto manager. (line 2620)
+* BFD_RELOC_860_HAPC: howto manager. (line 2621)
+* BFD_RELOC_860_HIGH: howto manager. (line 2622)
+* BFD_RELOC_860_HIGHADJ: howto manager. (line 2618)
+* BFD_RELOC_860_HIGOT: howto manager. (line 2623)
+* BFD_RELOC_860_HIGOTOFF: howto manager. (line 2624)
+* BFD_RELOC_860_JUMP_SLOT: howto manager. (line 2595)
+* BFD_RELOC_860_LOGOT0: howto manager. (line 2607)
+* BFD_RELOC_860_LOGOT1: howto manager. (line 2609)
+* BFD_RELOC_860_LOGOTOFF0: howto manager. (line 2611)
+* BFD_RELOC_860_LOGOTOFF1: howto manager. (line 2613)
+* BFD_RELOC_860_LOGOTOFF2: howto manager. (line 2615)
+* BFD_RELOC_860_LOGOTOFF3: howto manager. (line 2616)
+* BFD_RELOC_860_LOPC: howto manager. (line 2617)
+* BFD_RELOC_860_LOW0: howto manager. (line 2600)
+* BFD_RELOC_860_LOW1: howto manager. (line 2602)
+* BFD_RELOC_860_LOW2: howto manager. (line 2604)
+* BFD_RELOC_860_LOW3: howto manager. (line 2606)
+* BFD_RELOC_860_PC16: howto manager. (line 2599)
+* BFD_RELOC_860_PC26: howto manager. (line 2597)
+* BFD_RELOC_860_PLT26: howto manager. (line 2598)
+* BFD_RELOC_860_RELATIVE: howto manager. (line 2596)
+* BFD_RELOC_860_SPGOT0: howto manager. (line 2608)
+* BFD_RELOC_860_SPGOT1: howto manager. (line 2610)
+* BFD_RELOC_860_SPGOTOFF0: howto manager. (line 2612)
+* BFD_RELOC_860_SPGOTOFF1: howto manager. (line 2614)
+* BFD_RELOC_860_SPLIT0: howto manager. (line 2601)
+* BFD_RELOC_860_SPLIT1: howto manager. (line 2603)
+* BFD_RELOC_860_SPLIT2: howto manager. (line 2605)
+* BFD_RELOC_8_BASEREL: howto manager. (line 103)
+* BFD_RELOC_8_FFnn: howto manager. (line 107)
+* BFD_RELOC_8_GOT_PCREL: howto manager. (line 53)
+* BFD_RELOC_8_GOTOFF: howto manager. (line 59)
+* BFD_RELOC_8_PCREL: howto manager. (line 40)
+* BFD_RELOC_8_PLT_PCREL: howto manager. (line 64)
+* BFD_RELOC_8_PLTOFF: howto manager. (line 71)
+* BFD_RELOC_AARCH64_16: howto manager. (line 3011)
+* BFD_RELOC_AARCH64_16_PCREL: howto manager. (line 3018)
+* BFD_RELOC_AARCH64_32: howto manager. (line 3010)
+* BFD_RELOC_AARCH64_32_PCREL: howto manager. (line 3017)
+* BFD_RELOC_AARCH64_64: howto manager. (line 3009)
+* BFD_RELOC_AARCH64_64_PCREL: howto manager. (line 3016)
+* BFD_RELOC_AARCH64_ADD_LO12: howto manager. (line 3083)
+* BFD_RELOC_AARCH64_ADR_GOT_PAGE: howto manager. (line 3140)
+* BFD_RELOC_AARCH64_ADR_HI21_NC_PCREL: howto manager. (line 3078)
+* BFD_RELOC_AARCH64_ADR_HI21_PCREL: howto manager. (line 3074)
+* BFD_RELOC_AARCH64_ADR_LO21_PCREL: howto manager. (line 3070)
+* BFD_RELOC_AARCH64_BRANCH19: howto manager. (line 3098)
+* BFD_RELOC_AARCH64_CALL26: howto manager. (line 3108)
+* BFD_RELOC_AARCH64_COPY: howto manager. (line 3241)
+* BFD_RELOC_AARCH64_GAS_INTERNAL_FIXUP: howto manager. (line 3275)
+* BFD_RELOC_AARCH64_GLOB_DAT: howto manager. (line 3244)
+* BFD_RELOC_AARCH64_GOT_LD_PREL19: howto manager. (line 3133)
+* BFD_RELOC_AARCH64_IRELATIVE: howto manager. (line 3265)
+* BFD_RELOC_AARCH64_JUMP26: howto manager. (line 3103)
+* BFD_RELOC_AARCH64_JUMP_SLOT: howto manager. (line 3247)
+* BFD_RELOC_AARCH64_LD32_GOT_LO12_NC: howto manager. (line 3150)
+* BFD_RELOC_AARCH64_LD64_GOT_LO12_NC: howto manager. (line 3145)
+* BFD_RELOC_AARCH64_LD_GOT_LO12_NC: howto manager. (line 3284)
+* BFD_RELOC_AARCH64_LD_LO19_PCREL: howto manager. (line 3065)
+* BFD_RELOC_AARCH64_LDST128_LO12: howto manager. (line 3128)
+* BFD_RELOC_AARCH64_LDST16_LO12: howto manager. (line 3113)
+* BFD_RELOC_AARCH64_LDST32_LO12: howto manager. (line 3118)
+* BFD_RELOC_AARCH64_LDST64_LO12: howto manager. (line 3123)
+* BFD_RELOC_AARCH64_LDST8_LO12: howto manager. (line 3088)
+* BFD_RELOC_AARCH64_LDST_LO12: howto manager. (line 3279)
+* BFD_RELOC_AARCH64_MOVW_G0: howto manager. (line 3022)
+* BFD_RELOC_AARCH64_MOVW_G0_NC: howto manager. (line 3026)
+* BFD_RELOC_AARCH64_MOVW_G0_S: howto manager. (line 3050)
+* BFD_RELOC_AARCH64_MOVW_G1: howto manager. (line 3030)
+* BFD_RELOC_AARCH64_MOVW_G1_NC: howto manager. (line 3034)
+* BFD_RELOC_AARCH64_MOVW_G1_S: howto manager. (line 3055)
+* BFD_RELOC_AARCH64_MOVW_G2: howto manager. (line 3038)
+* BFD_RELOC_AARCH64_MOVW_G2_NC: howto manager. (line 3042)
+* BFD_RELOC_AARCH64_MOVW_G2_S: howto manager. (line 3060)
+* BFD_RELOC_AARCH64_MOVW_G3: howto manager. (line 3046)
+* BFD_RELOC_AARCH64_NONE: howto manager. (line 3006)
+* BFD_RELOC_AARCH64_RELATIVE: howto manager. (line 3250)
+* BFD_RELOC_AARCH64_RELOC_END: howto manager. (line 3268)
+* BFD_RELOC_AARCH64_RELOC_START: howto manager. (line 3000)
+* BFD_RELOC_AARCH64_TLS_DTPMOD: howto manager. (line 3253)
+* BFD_RELOC_AARCH64_TLS_DTPREL: howto manager. (line 3256)
+* BFD_RELOC_AARCH64_TLS_TPREL: howto manager. (line 3259)
+* BFD_RELOC_AARCH64_TLSDESC: howto manager. (line 3262)
+* BFD_RELOC_AARCH64_TLSDESC_ADD: howto manager. (line 3235)
+* BFD_RELOC_AARCH64_TLSDESC_ADD_LO12_NC: howto manager. (line 3223)
+* BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21: howto manager. (line 3214)
+* BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21: howto manager. (line 3211)
+* BFD_RELOC_AARCH64_TLSDESC_CALL: howto manager. (line 3238)
+* BFD_RELOC_AARCH64_TLSDESC_LD32_LO12_NC: howto manager. (line 3220)
+* BFD_RELOC_AARCH64_TLSDESC_LD64_LO12_NC: howto manager. (line 3217)
+* BFD_RELOC_AARCH64_TLSDESC_LD_LO12_NC: howto manager. (line 3292)
+* BFD_RELOC_AARCH64_TLSDESC_LD_PREL19: howto manager. (line 3208)
+* BFD_RELOC_AARCH64_TLSDESC_LDR: howto manager. (line 3232)
+* BFD_RELOC_AARCH64_TLSDESC_OFF_G0_NC: howto manager. (line 3229)
+* BFD_RELOC_AARCH64_TLSDESC_OFF_G1: howto manager. (line 3226)
+* BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC: howto manager. (line 3161)
+* BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21: howto manager. (line 3155)
+* BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21: howto manager.
+ (line 3172)
+* BFD_RELOC_AARCH64_TLSIE_LD32_GOTTPREL_LO12_NC: howto manager.
+ (line 3178)
+* BFD_RELOC_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC: howto manager.
+ (line 3175)
+* BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_LO12_NC: howto manager.
+ (line 3288)
+* BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19: howto manager. (line 3181)
+* BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC: howto manager.
+ (line 3169)
+* BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G1: howto manager. (line 3166)
+* BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_HI12: howto manager. (line 3199)
+* BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12: howto manager. (line 3202)
+* BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12_NC: howto manager. (line 3205)
+* BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0: howto manager. (line 3193)
+* BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC: howto manager. (line 3196)
+* BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1: howto manager. (line 3187)
+* BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1_NC: howto manager. (line 3190)
+* BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G2: howto manager. (line 3184)
+* BFD_RELOC_AARCH64_TSTBR14: howto manager. (line 3093)
+* BFD_RELOC_ALPHA_BOH: howto manager. (line 323)
+* BFD_RELOC_ALPHA_BRSGP: howto manager. (line 306)
+* BFD_RELOC_ALPHA_BSR: howto manager. (line 315)
+* BFD_RELOC_ALPHA_CODEADDR: howto manager. (line 297)
+* BFD_RELOC_ALPHA_DTPMOD64: howto manager. (line 329)
+* BFD_RELOC_ALPHA_DTPREL16: howto manager. (line 334)
+* BFD_RELOC_ALPHA_DTPREL64: howto manager. (line 331)
+* BFD_RELOC_ALPHA_DTPREL_HI16: howto manager. (line 332)
+* BFD_RELOC_ALPHA_DTPREL_LO16: howto manager. (line 333)
+* BFD_RELOC_ALPHA_ELF_LITERAL: howto manager. (line 262)
+* BFD_RELOC_ALPHA_GOTDTPREL16: howto manager. (line 330)
+* BFD_RELOC_ALPHA_GOTTPREL16: howto manager. (line 335)
+* BFD_RELOC_ALPHA_GPDISP: howto manager. (line 256)
+* BFD_RELOC_ALPHA_GPDISP_HI16: howto manager. (line 242)
+* BFD_RELOC_ALPHA_GPDISP_LO16: howto manager. (line 250)
+* BFD_RELOC_ALPHA_GPREL_HI16: howto manager. (line 301)
+* BFD_RELOC_ALPHA_GPREL_LO16: howto manager. (line 302)
+* BFD_RELOC_ALPHA_HINT: howto manager. (line 288)
+* BFD_RELOC_ALPHA_LDA: howto manager. (line 319)
+* BFD_RELOC_ALPHA_LINKAGE: howto manager. (line 293)
+* BFD_RELOC_ALPHA_LITERAL: howto manager. (line 261)
+* BFD_RELOC_ALPHA_LITUSE: howto manager. (line 263)
+* BFD_RELOC_ALPHA_NOP: howto manager. (line 311)
+* BFD_RELOC_ALPHA_TLSGD: howto manager. (line 327)
+* BFD_RELOC_ALPHA_TLSLDM: howto manager. (line 328)
+* BFD_RELOC_ALPHA_TPREL16: howto manager. (line 339)
+* BFD_RELOC_ALPHA_TPREL64: howto manager. (line 336)
+* BFD_RELOC_ALPHA_TPREL_HI16: howto manager. (line 337)
+* BFD_RELOC_ALPHA_TPREL_LO16: howto manager. (line 338)
+* BFD_RELOC_ARC_B22_PCREL: howto manager. (line 1056)
+* BFD_RELOC_ARC_B26: howto manager. (line 1061)
+* BFD_RELOC_ARM_ADR_IMM: howto manager. (line 942)
+* BFD_RELOC_ARM_ADRL_IMMEDIATE: howto manager. (line 928)
+* BFD_RELOC_ARM_ALU_PC_G0: howto manager. (line 892)
+* BFD_RELOC_ARM_ALU_PC_G0_NC: howto manager. (line 891)
+* BFD_RELOC_ARM_ALU_PC_G1: howto manager. (line 894)
+* BFD_RELOC_ARM_ALU_PC_G1_NC: howto manager. (line 893)
+* BFD_RELOC_ARM_ALU_PC_G2: howto manager. (line 895)
+* BFD_RELOC_ARM_ALU_SB_G0: howto manager. (line 906)
+* BFD_RELOC_ARM_ALU_SB_G0_NC: howto manager. (line 905)
+* BFD_RELOC_ARM_ALU_SB_G1: howto manager. (line 908)
+* BFD_RELOC_ARM_ALU_SB_G1_NC: howto manager. (line 907)
+* BFD_RELOC_ARM_ALU_SB_G2: howto manager. (line 909)
+* BFD_RELOC_ARM_CP_OFF_IMM: howto manager. (line 938)
+* BFD_RELOC_ARM_CP_OFF_IMM_S2: howto manager. (line 939)
+* BFD_RELOC_ARM_GLOB_DAT: howto manager. (line 866)
+* BFD_RELOC_ARM_GOT32: howto manager. (line 867)
+* BFD_RELOC_ARM_GOT_PREL: howto manager. (line 872)
+* BFD_RELOC_ARM_GOTOFF: howto manager. (line 870)
+* BFD_RELOC_ARM_GOTPC: howto manager. (line 871)
+* BFD_RELOC_ARM_HVC: howto manager. (line 935)
+* BFD_RELOC_ARM_HWLITERAL: howto manager. (line 949)
+* BFD_RELOC_ARM_IMMEDIATE: howto manager. (line 927)
+* BFD_RELOC_ARM_IN_POOL: howto manager. (line 945)
+* BFD_RELOC_ARM_IRELATIVE: howto manager. (line 924)
+* BFD_RELOC_ARM_JUMP_SLOT: howto manager. (line 865)
+* BFD_RELOC_ARM_LDC_PC_G0: howto manager. (line 902)
+* BFD_RELOC_ARM_LDC_PC_G1: howto manager. (line 903)
+* BFD_RELOC_ARM_LDC_PC_G2: howto manager. (line 904)
+* BFD_RELOC_ARM_LDC_SB_G0: howto manager. (line 916)
+* BFD_RELOC_ARM_LDC_SB_G1: howto manager. (line 917)
+* BFD_RELOC_ARM_LDC_SB_G2: howto manager. (line 918)
+* BFD_RELOC_ARM_LDR_IMM: howto manager. (line 943)
+* BFD_RELOC_ARM_LDR_PC_G0: howto manager. (line 896)
+* BFD_RELOC_ARM_LDR_PC_G1: howto manager. (line 897)
+* BFD_RELOC_ARM_LDR_PC_G2: howto manager. (line 898)
+* BFD_RELOC_ARM_LDR_SB_G0: howto manager. (line 910)
+* BFD_RELOC_ARM_LDR_SB_G1: howto manager. (line 911)
+* BFD_RELOC_ARM_LDR_SB_G2: howto manager. (line 912)
+* BFD_RELOC_ARM_LDRS_PC_G0: howto manager. (line 899)
+* BFD_RELOC_ARM_LDRS_PC_G1: howto manager. (line 900)
+* BFD_RELOC_ARM_LDRS_PC_G2: howto manager. (line 901)
+* BFD_RELOC_ARM_LDRS_SB_G0: howto manager. (line 913)
+* BFD_RELOC_ARM_LDRS_SB_G1: howto manager. (line 914)
+* BFD_RELOC_ARM_LDRS_SB_G2: howto manager. (line 915)
+* BFD_RELOC_ARM_LITERAL: howto manager. (line 944)
+* BFD_RELOC_ARM_MOVT: howto manager. (line 856)
+* BFD_RELOC_ARM_MOVT_PCREL: howto manager. (line 858)
+* BFD_RELOC_ARM_MOVW: howto manager. (line 855)
+* BFD_RELOC_ARM_MOVW_PCREL: howto manager. (line 857)
+* BFD_RELOC_ARM_MULTI: howto manager. (line 937)
+* BFD_RELOC_ARM_OFFSET_IMM: howto manager. (line 829)
+* BFD_RELOC_ARM_OFFSET_IMM8: howto manager. (line 946)
+* BFD_RELOC_ARM_PCREL_BLX: howto manager. (line 800)
+* BFD_RELOC_ARM_PCREL_BRANCH: howto manager. (line 796)
+* BFD_RELOC_ARM_PCREL_CALL: howto manager. (line 810)
+* BFD_RELOC_ARM_PCREL_JUMP: howto manager. (line 814)
+* BFD_RELOC_ARM_PLT32: howto manager. (line 868)
+* BFD_RELOC_ARM_PREL31: howto manager. (line 852)
+* BFD_RELOC_ARM_RELATIVE: howto manager. (line 869)
+* BFD_RELOC_ARM_ROSEGREL32: howto manager. (line 841)
+* BFD_RELOC_ARM_SBREL32: howto manager. (line 844)
+* BFD_RELOC_ARM_SHIFT_IMM: howto manager. (line 933)
+* BFD_RELOC_ARM_SMC: howto manager. (line 934)
+* BFD_RELOC_ARM_SWI: howto manager. (line 936)
+* BFD_RELOC_ARM_T32_ADD_IMM: howto manager. (line 930)
+* BFD_RELOC_ARM_T32_ADD_PC12: howto manager. (line 932)
+* BFD_RELOC_ARM_T32_CP_OFF_IMM: howto manager. (line 940)
+* BFD_RELOC_ARM_T32_CP_OFF_IMM_S2: howto manager. (line 941)
+* BFD_RELOC_ARM_T32_IMM12: howto manager. (line 931)
+* BFD_RELOC_ARM_T32_IMMEDIATE: howto manager. (line 929)
+* BFD_RELOC_ARM_T32_OFFSET_IMM: howto manager. (line 948)
+* BFD_RELOC_ARM_T32_OFFSET_U8: howto manager. (line 947)
+* BFD_RELOC_ARM_TARGET1: howto manager. (line 837)
+* BFD_RELOC_ARM_TARGET2: howto manager. (line 847)
+* BFD_RELOC_ARM_THM_TLS_CALL: howto manager. (line 885)
+* BFD_RELOC_ARM_THM_TLS_DESCSEQ: howto manager. (line 887)
+* BFD_RELOC_ARM_THUMB_ADD: howto manager. (line 950)
+* BFD_RELOC_ARM_THUMB_IMM: howto manager. (line 951)
+* BFD_RELOC_ARM_THUMB_MOVT: howto manager. (line 860)
+* BFD_RELOC_ARM_THUMB_MOVT_PCREL: howto manager. (line 862)
+* BFD_RELOC_ARM_THUMB_MOVW: howto manager. (line 859)
+* BFD_RELOC_ARM_THUMB_MOVW_PCREL: howto manager. (line 861)
+* BFD_RELOC_ARM_THUMB_OFFSET: howto manager. (line 833)
+* BFD_RELOC_ARM_THUMB_SHIFT: howto manager. (line 952)
+* BFD_RELOC_ARM_TLS_CALL: howto manager. (line 884)
+* BFD_RELOC_ARM_TLS_DESC: howto manager. (line 888)
+* BFD_RELOC_ARM_TLS_DESCSEQ: howto manager. (line 886)
+* BFD_RELOC_ARM_TLS_DTPMOD32: howto manager. (line 879)
+* BFD_RELOC_ARM_TLS_DTPOFF32: howto manager. (line 878)
+* BFD_RELOC_ARM_TLS_GD32: howto manager. (line 875)
+* BFD_RELOC_ARM_TLS_GOTDESC: howto manager. (line 883)
+* BFD_RELOC_ARM_TLS_IE32: howto manager. (line 881)
+* BFD_RELOC_ARM_TLS_LDM32: howto manager. (line 877)
+* BFD_RELOC_ARM_TLS_LDO32: howto manager. (line 876)
+* BFD_RELOC_ARM_TLS_LE32: howto manager. (line 882)
+* BFD_RELOC_ARM_TLS_TPOFF32: howto manager. (line 880)
+* BFD_RELOC_ARM_V4BX: howto manager. (line 921)
+* BFD_RELOC_AVR_13_PCREL: howto manager. (line 1851)
+* BFD_RELOC_AVR_16_PM: howto manager. (line 1855)
+* BFD_RELOC_AVR_6: howto manager. (line 1942)
+* BFD_RELOC_AVR_6_ADIW: howto manager. (line 1946)
+* BFD_RELOC_AVR_7_PCREL: howto manager. (line 1847)
+* BFD_RELOC_AVR_8_HI: howto manager. (line 1954)
+* BFD_RELOC_AVR_8_HLO: howto manager. (line 1958)
+* BFD_RELOC_AVR_8_LO: howto manager. (line 1950)
+* BFD_RELOC_AVR_CALL: howto manager. (line 1934)
+* BFD_RELOC_AVR_DIFF16: howto manager. (line 1963)
+* BFD_RELOC_AVR_DIFF32: howto manager. (line 1964)
+* BFD_RELOC_AVR_DIFF8: howto manager. (line 1962)
+* BFD_RELOC_AVR_HH8_LDI: howto manager. (line 1867)
+* BFD_RELOC_AVR_HH8_LDI_NEG: howto manager. (line 1886)
+* BFD_RELOC_AVR_HH8_LDI_PM: howto manager. (line 1915)
+* BFD_RELOC_AVR_HH8_LDI_PM_NEG: howto manager. (line 1929)
+* BFD_RELOC_AVR_HI8_LDI: howto manager. (line 1863)
+* BFD_RELOC_AVR_HI8_LDI_GS: howto manager. (line 1909)
+* BFD_RELOC_AVR_HI8_LDI_NEG: howto manager. (line 1881)
+* BFD_RELOC_AVR_HI8_LDI_PM: howto manager. (line 1905)
+* BFD_RELOC_AVR_HI8_LDI_PM_NEG: howto manager. (line 1924)
+* BFD_RELOC_AVR_LDI: howto manager. (line 1938)
+* BFD_RELOC_AVR_LDS_STS_16: howto manager. (line 1972)
+* BFD_RELOC_AVR_LO8_LDI: howto manager. (line 1859)
+* BFD_RELOC_AVR_LO8_LDI_GS: howto manager. (line 1899)
+* BFD_RELOC_AVR_LO8_LDI_NEG: howto manager. (line 1876)
+* BFD_RELOC_AVR_LO8_LDI_PM: howto manager. (line 1895)
+* BFD_RELOC_AVR_LO8_LDI_PM_NEG: howto manager. (line 1920)
+* BFD_RELOC_AVR_MS8_LDI: howto manager. (line 1872)
+* BFD_RELOC_AVR_MS8_LDI_NEG: howto manager. (line 1891)
+* BFD_RELOC_AVR_PORT5: howto manager. (line 1980)
+* BFD_RELOC_AVR_PORT6: howto manager. (line 1976)
+* BFD_RELOC_BFIN_10_PCREL: howto manager. (line 1081)
+* BFD_RELOC_BFIN_11_PCREL: howto manager. (line 1084)
+* BFD_RELOC_BFIN_12_PCREL_JUMP: howto manager. (line 1087)
+* BFD_RELOC_BFIN_12_PCREL_JUMP_S: howto manager. (line 1090)
+* BFD_RELOC_BFIN_16_HIGH: howto manager. (line 1069)
+* BFD_RELOC_BFIN_16_IMM: howto manager. (line 1066)
+* BFD_RELOC_BFIN_16_LOW: howto manager. (line 1078)
+* BFD_RELOC_BFIN_24_PCREL_CALL_X: howto manager. (line 1093)
+* BFD_RELOC_BFIN_24_PCREL_JUMP_L: howto manager. (line 1096)
+* BFD_RELOC_BFIN_4_PCREL: howto manager. (line 1072)
+* BFD_RELOC_BFIN_5_PCREL: howto manager. (line 1075)
+* BFD_RELOC_BFIN_FUNCDESC: howto manager. (line 1102)
+* BFD_RELOC_BFIN_FUNCDESC_GOT17M4: howto manager. (line 1103)
+* BFD_RELOC_BFIN_FUNCDESC_GOTHI: howto manager. (line 1104)
+* BFD_RELOC_BFIN_FUNCDESC_GOTLO: howto manager. (line 1105)
+* BFD_RELOC_BFIN_FUNCDESC_GOTOFF17M4: howto manager. (line 1107)
+* BFD_RELOC_BFIN_FUNCDESC_GOTOFFHI: howto manager. (line 1108)
+* BFD_RELOC_BFIN_FUNCDESC_GOTOFFLO: howto manager. (line 1109)
+* BFD_RELOC_BFIN_FUNCDESC_VALUE: howto manager. (line 1106)
+* BFD_RELOC_BFIN_GOT: howto manager. (line 1115)
+* BFD_RELOC_BFIN_GOT17M4: howto manager. (line 1099)
+* BFD_RELOC_BFIN_GOTHI: howto manager. (line 1100)
+* BFD_RELOC_BFIN_GOTLO: howto manager. (line 1101)
+* BFD_RELOC_BFIN_GOTOFF17M4: howto manager. (line 1110)
+* BFD_RELOC_BFIN_GOTOFFHI: howto manager. (line 1111)
+* BFD_RELOC_BFIN_GOTOFFLO: howto manager. (line 1112)
+* BFD_RELOC_BFIN_PLTPC: howto manager. (line 1118)
+* BFD_RELOC_C6000_ABS_H16: howto manager. (line 1670)
+* BFD_RELOC_C6000_ABS_L16: howto manager. (line 1669)
+* BFD_RELOC_C6000_ABS_S16: howto manager. (line 1668)
+* BFD_RELOC_C6000_ALIGN: howto manager. (line 1691)
+* BFD_RELOC_C6000_COPY: howto manager. (line 1686)
+* BFD_RELOC_C6000_DSBT_INDEX: howto manager. (line 1684)
+* BFD_RELOC_C6000_EHTYPE: howto manager. (line 1688)
+* BFD_RELOC_C6000_FPHEAD: howto manager. (line 1692)
+* BFD_RELOC_C6000_JUMP_SLOT: howto manager. (line 1687)
+* BFD_RELOC_C6000_NOCMP: howto manager. (line 1693)
+* BFD_RELOC_C6000_PCR_H16: howto manager. (line 1689)
+* BFD_RELOC_C6000_PCR_L16: howto manager. (line 1690)
+* BFD_RELOC_C6000_PCR_S10: howto manager. (line 1666)
+* BFD_RELOC_C6000_PCR_S12: howto manager. (line 1665)
+* BFD_RELOC_C6000_PCR_S21: howto manager. (line 1664)
+* BFD_RELOC_C6000_PCR_S7: howto manager. (line 1667)
+* BFD_RELOC_C6000_PREL31: howto manager. (line 1685)
+* BFD_RELOC_C6000_SBR_GOT_H16_W: howto manager. (line 1683)
+* BFD_RELOC_C6000_SBR_GOT_L16_W: howto manager. (line 1682)
+* BFD_RELOC_C6000_SBR_GOT_U15_W: howto manager. (line 1681)
+* BFD_RELOC_C6000_SBR_H16_B: howto manager. (line 1678)
+* BFD_RELOC_C6000_SBR_H16_H: howto manager. (line 1679)
+* BFD_RELOC_C6000_SBR_H16_W: howto manager. (line 1680)
+* BFD_RELOC_C6000_SBR_L16_B: howto manager. (line 1675)
+* BFD_RELOC_C6000_SBR_L16_H: howto manager. (line 1676)
+* BFD_RELOC_C6000_SBR_L16_W: howto manager. (line 1677)
+* BFD_RELOC_C6000_SBR_S16: howto manager. (line 1674)
+* BFD_RELOC_C6000_SBR_U15_B: howto manager. (line 1671)
+* BFD_RELOC_C6000_SBR_U15_H: howto manager. (line 1672)
+* BFD_RELOC_C6000_SBR_U15_W: howto manager. (line 1673)
+* bfd_reloc_code_type: howto manager. (line 10)
+* BFD_RELOC_CR16_ABS20: howto manager. (line 2493)
+* BFD_RELOC_CR16_ABS24: howto manager. (line 2494)
+* BFD_RELOC_CR16_DISP16: howto manager. (line 2504)
+* BFD_RELOC_CR16_DISP20: howto manager. (line 2505)
+* BFD_RELOC_CR16_DISP24: howto manager. (line 2506)
+* BFD_RELOC_CR16_DISP24a: howto manager. (line 2507)
+* BFD_RELOC_CR16_DISP4: howto manager. (line 2502)
+* BFD_RELOC_CR16_DISP8: howto manager. (line 2503)
+* BFD_RELOC_CR16_GLOB_DAT: howto manager. (line 2513)
+* BFD_RELOC_CR16_GOT_REGREL20: howto manager. (line 2511)
+* BFD_RELOC_CR16_GOTC_REGREL20: howto manager. (line 2512)
+* BFD_RELOC_CR16_IMM16: howto manager. (line 2497)
+* BFD_RELOC_CR16_IMM20: howto manager. (line 2498)
+* BFD_RELOC_CR16_IMM24: howto manager. (line 2499)
+* BFD_RELOC_CR16_IMM32: howto manager. (line 2500)
+* BFD_RELOC_CR16_IMM32a: howto manager. (line 2501)
+* BFD_RELOC_CR16_IMM4: howto manager. (line 2495)
+* BFD_RELOC_CR16_IMM8: howto manager. (line 2496)
+* BFD_RELOC_CR16_NUM16: howto manager. (line 2482)
+* BFD_RELOC_CR16_NUM32: howto manager. (line 2483)
+* BFD_RELOC_CR16_NUM32a: howto manager. (line 2484)
+* BFD_RELOC_CR16_NUM8: howto manager. (line 2481)
+* BFD_RELOC_CR16_REGREL0: howto manager. (line 2485)
+* BFD_RELOC_CR16_REGREL14: howto manager. (line 2488)
+* BFD_RELOC_CR16_REGREL14a: howto manager. (line 2489)
+* BFD_RELOC_CR16_REGREL16: howto manager. (line 2490)
+* BFD_RELOC_CR16_REGREL20: howto manager. (line 2491)
+* BFD_RELOC_CR16_REGREL20a: howto manager. (line 2492)
+* BFD_RELOC_CR16_REGREL4: howto manager. (line 2486)
+* BFD_RELOC_CR16_REGREL4a: howto manager. (line 2487)
+* BFD_RELOC_CR16_SWITCH16: howto manager. (line 2509)
+* BFD_RELOC_CR16_SWITCH32: howto manager. (line 2510)
+* BFD_RELOC_CR16_SWITCH8: howto manager. (line 2508)
+* BFD_RELOC_CRIS_16_DTPREL: howto manager. (line 2584)
+* BFD_RELOC_CRIS_16_GOT: howto manager. (line 2560)
+* BFD_RELOC_CRIS_16_GOT_GD: howto manager. (line 2580)
+* BFD_RELOC_CRIS_16_GOT_TPREL: howto manager. (line 2586)
+* BFD_RELOC_CRIS_16_GOTPLT: howto manager. (line 2566)
+* BFD_RELOC_CRIS_16_TPREL: howto manager. (line 2588)
+* BFD_RELOC_CRIS_32_DTPREL: howto manager. (line 2583)
+* BFD_RELOC_CRIS_32_GD: howto manager. (line 2581)
+* BFD_RELOC_CRIS_32_GOT: howto manager. (line 2557)
+* BFD_RELOC_CRIS_32_GOT_GD: howto manager. (line 2579)
+* BFD_RELOC_CRIS_32_GOT_TPREL: howto manager. (line 2585)
+* BFD_RELOC_CRIS_32_GOTPLT: howto manager. (line 2563)
+* BFD_RELOC_CRIS_32_GOTREL: howto manager. (line 2569)
+* BFD_RELOC_CRIS_32_IE: howto manager. (line 2590)
+* BFD_RELOC_CRIS_32_PLT_GOTREL: howto manager. (line 2572)
+* BFD_RELOC_CRIS_32_PLT_PCREL: howto manager. (line 2575)
+* BFD_RELOC_CRIS_32_TPREL: howto manager. (line 2587)
+* BFD_RELOC_CRIS_BDISP8: howto manager. (line 2538)
+* BFD_RELOC_CRIS_COPY: howto manager. (line 2551)
+* BFD_RELOC_CRIS_DTP: howto manager. (line 2582)
+* BFD_RELOC_CRIS_DTPMOD: howto manager. (line 2589)
+* BFD_RELOC_CRIS_GLOB_DAT: howto manager. (line 2552)
+* BFD_RELOC_CRIS_JUMP_SLOT: howto manager. (line 2553)
+* BFD_RELOC_CRIS_LAPCQ_OFFSET: howto manager. (line 2546)
+* BFD_RELOC_CRIS_RELATIVE: howto manager. (line 2554)
+* BFD_RELOC_CRIS_SIGNED_16: howto manager. (line 2544)
+* BFD_RELOC_CRIS_SIGNED_6: howto manager. (line 2540)
+* BFD_RELOC_CRIS_SIGNED_8: howto manager. (line 2542)
+* BFD_RELOC_CRIS_UNSIGNED_16: howto manager. (line 2545)
+* BFD_RELOC_CRIS_UNSIGNED_4: howto manager. (line 2547)
+* BFD_RELOC_CRIS_UNSIGNED_5: howto manager. (line 2539)
+* BFD_RELOC_CRIS_UNSIGNED_6: howto manager. (line 2541)
+* BFD_RELOC_CRIS_UNSIGNED_8: howto manager. (line 2543)
+* BFD_RELOC_CRX_ABS16: howto manager. (line 2526)
+* BFD_RELOC_CRX_ABS32: howto manager. (line 2527)
+* BFD_RELOC_CRX_IMM16: howto manager. (line 2531)
+* BFD_RELOC_CRX_IMM32: howto manager. (line 2532)
+* BFD_RELOC_CRX_NUM16: howto manager. (line 2529)
+* BFD_RELOC_CRX_NUM32: howto manager. (line 2530)
+* BFD_RELOC_CRX_NUM8: howto manager. (line 2528)
+* BFD_RELOC_CRX_REGREL12: howto manager. (line 2522)
+* BFD_RELOC_CRX_REGREL22: howto manager. (line 2523)
+* BFD_RELOC_CRX_REGREL28: howto manager. (line 2524)
+* BFD_RELOC_CRX_REGREL32: howto manager. (line 2525)
+* BFD_RELOC_CRX_REL16: howto manager. (line 2519)
+* BFD_RELOC_CRX_REL24: howto manager. (line 2520)
+* BFD_RELOC_CRX_REL32: howto manager. (line 2521)
+* BFD_RELOC_CRX_REL4: howto manager. (line 2516)
+* BFD_RELOC_CRX_REL8: howto manager. (line 2517)
+* BFD_RELOC_CRX_REL8_CMP: howto manager. (line 2518)
+* BFD_RELOC_CRX_SWITCH16: howto manager. (line 2534)
+* BFD_RELOC_CRX_SWITCH32: howto manager. (line 2535)
+* BFD_RELOC_CRX_SWITCH8: howto manager. (line 2533)
+* BFD_RELOC_CTOR: howto manager. (line 790)
+* BFD_RELOC_D10V_10_PCREL_L: howto manager. (line 1185)
+* BFD_RELOC_D10V_10_PCREL_R: howto manager. (line 1181)
+* BFD_RELOC_D10V_18: howto manager. (line 1190)
+* BFD_RELOC_D10V_18_PCREL: howto manager. (line 1193)
+* BFD_RELOC_D30V_15: howto manager. (line 1208)
+* BFD_RELOC_D30V_15_PCREL: howto manager. (line 1212)
+* BFD_RELOC_D30V_15_PCREL_R: howto manager. (line 1216)
+* BFD_RELOC_D30V_21: howto manager. (line 1221)
+* BFD_RELOC_D30V_21_PCREL: howto manager. (line 1225)
+* BFD_RELOC_D30V_21_PCREL_R: howto manager. (line 1229)
+* BFD_RELOC_D30V_32: howto manager. (line 1234)
+* BFD_RELOC_D30V_32_PCREL: howto manager. (line 1237)
+* BFD_RELOC_D30V_6: howto manager. (line 1196)
+* BFD_RELOC_D30V_9_PCREL: howto manager. (line 1199)
+* BFD_RELOC_D30V_9_PCREL_R: howto manager. (line 1203)
+* BFD_RELOC_DLX_HI16_S: howto manager. (line 1240)
+* BFD_RELOC_DLX_JMP26: howto manager. (line 1246)
+* BFD_RELOC_DLX_LO16: howto manager. (line 1243)
+* BFD_RELOC_EPIPHANY_HIGH: howto manager. (line 3494)
+* BFD_RELOC_EPIPHANY_IMM11: howto manager. (line 3503)
+* BFD_RELOC_EPIPHANY_IMM8: howto manager. (line 3507)
+* BFD_RELOC_EPIPHANY_LOW: howto manager. (line 3497)
+* BFD_RELOC_EPIPHANY_SIMM11: howto manager. (line 3500)
+* BFD_RELOC_EPIPHANY_SIMM24: howto manager. (line 3491)
+* BFD_RELOC_EPIPHANY_SIMM8: howto manager. (line 3488)
+* BFD_RELOC_FR30_10_IN_8: howto manager. (line 1715)
+* BFD_RELOC_FR30_12_PCREL: howto manager. (line 1723)
+* BFD_RELOC_FR30_20: howto manager. (line 1699)
+* BFD_RELOC_FR30_48: howto manager. (line 1696)
+* BFD_RELOC_FR30_6_IN_4: howto manager. (line 1703)
+* BFD_RELOC_FR30_8_IN_8: howto manager. (line 1707)
+* BFD_RELOC_FR30_9_IN_8: howto manager. (line 1711)
+* BFD_RELOC_FR30_9_PCREL: howto manager. (line 1719)
+* BFD_RELOC_FRV_FUNCDESC: howto manager. (line 497)
+* BFD_RELOC_FRV_FUNCDESC_GOT12: howto manager. (line 498)
+* BFD_RELOC_FRV_FUNCDESC_GOTHI: howto manager. (line 499)
+* BFD_RELOC_FRV_FUNCDESC_GOTLO: howto manager. (line 500)
+* BFD_RELOC_FRV_FUNCDESC_GOTOFF12: howto manager. (line 502)
+* BFD_RELOC_FRV_FUNCDESC_GOTOFFHI: howto manager. (line 503)
+* BFD_RELOC_FRV_FUNCDESC_GOTOFFLO: howto manager. (line 504)
+* BFD_RELOC_FRV_FUNCDESC_VALUE: howto manager. (line 501)
+* BFD_RELOC_FRV_GETTLSOFF: howto manager. (line 508)
+* BFD_RELOC_FRV_GETTLSOFF_RELAX: howto manager. (line 521)
+* BFD_RELOC_FRV_GOT12: howto manager. (line 494)
+* BFD_RELOC_FRV_GOTHI: howto manager. (line 495)
+* BFD_RELOC_FRV_GOTLO: howto manager. (line 496)
+* BFD_RELOC_FRV_GOTOFF12: howto manager. (line 505)
+* BFD_RELOC_FRV_GOTOFFHI: howto manager. (line 506)
+* BFD_RELOC_FRV_GOTOFFLO: howto manager. (line 507)
+* BFD_RELOC_FRV_GOTTLSDESC12: howto manager. (line 510)
+* BFD_RELOC_FRV_GOTTLSDESCHI: howto manager. (line 511)
+* BFD_RELOC_FRV_GOTTLSDESCLO: howto manager. (line 512)
+* BFD_RELOC_FRV_GOTTLSOFF12: howto manager. (line 516)
+* BFD_RELOC_FRV_GOTTLSOFFHI: howto manager. (line 517)
+* BFD_RELOC_FRV_GOTTLSOFFLO: howto manager. (line 518)
+* BFD_RELOC_FRV_GPREL12: howto manager. (line 489)
+* BFD_RELOC_FRV_GPREL32: howto manager. (line 491)
+* BFD_RELOC_FRV_GPRELHI: howto manager. (line 492)
+* BFD_RELOC_FRV_GPRELLO: howto manager. (line 493)
+* BFD_RELOC_FRV_GPRELU12: howto manager. (line 490)
+* BFD_RELOC_FRV_HI16: howto manager. (line 488)
+* BFD_RELOC_FRV_LABEL16: howto manager. (line 485)
+* BFD_RELOC_FRV_LABEL24: howto manager. (line 486)
+* BFD_RELOC_FRV_LO16: howto manager. (line 487)
+* BFD_RELOC_FRV_TLSDESC_RELAX: howto manager. (line 520)
+* BFD_RELOC_FRV_TLSDESC_VALUE: howto manager. (line 509)
+* BFD_RELOC_FRV_TLSMOFF: howto manager. (line 523)
+* BFD_RELOC_FRV_TLSMOFF12: howto manager. (line 513)
+* BFD_RELOC_FRV_TLSMOFFHI: howto manager. (line 514)
+* BFD_RELOC_FRV_TLSMOFFLO: howto manager. (line 515)
+* BFD_RELOC_FRV_TLSOFF: howto manager. (line 519)
+* BFD_RELOC_FRV_TLSOFF_RELAX: howto manager. (line 522)
+* BFD_RELOC_GPREL16: howto manager. (line 125)
+* BFD_RELOC_GPREL32: howto manager. (line 126)
+* BFD_RELOC_H8_DIR16A8: howto manager. (line 2653)
+* BFD_RELOC_H8_DIR16R8: howto manager. (line 2654)
+* BFD_RELOC_H8_DIR24A8: howto manager. (line 2655)
+* BFD_RELOC_H8_DIR24R8: howto manager. (line 2656)
+* BFD_RELOC_H8_DIR32A16: howto manager. (line 2657)
+* BFD_RELOC_H8_DISP32A16: howto manager. (line 2658)
+* BFD_RELOC_HI16: howto manager. (line 352)
+* BFD_RELOC_HI16_BASEREL: howto manager. (line 101)
+* BFD_RELOC_HI16_GOTOFF: howto manager. (line 57)
+* BFD_RELOC_HI16_PCREL: howto manager. (line 364)
+* BFD_RELOC_HI16_PLTOFF: howto manager. (line 69)
+* BFD_RELOC_HI16_S: howto manager. (line 355)
+* BFD_RELOC_HI16_S_BASEREL: howto manager. (line 102)
+* BFD_RELOC_HI16_S_GOTOFF: howto manager. (line 58)
+* BFD_RELOC_HI16_S_PCREL: howto manager. (line 367)
+* BFD_RELOC_HI16_S_PLTOFF: howto manager. (line 70)
+* BFD_RELOC_HI22: howto manager. (line 120)
+* BFD_RELOC_I370_D12: howto manager. (line 787)
+* BFD_RELOC_I960_CALLJ: howto manager. (line 132)
+* BFD_RELOC_IA64_COPY: howto manager. (line 2313)
+* BFD_RELOC_IA64_DIR32LSB: howto manager. (line 2258)
+* BFD_RELOC_IA64_DIR32MSB: howto manager. (line 2257)
+* BFD_RELOC_IA64_DIR64LSB: howto manager. (line 2260)
+* BFD_RELOC_IA64_DIR64MSB: howto manager. (line 2259)
+* BFD_RELOC_IA64_DTPMOD64LSB: howto manager. (line 2323)
+* BFD_RELOC_IA64_DTPMOD64MSB: howto manager. (line 2322)
+* BFD_RELOC_IA64_DTPREL14: howto manager. (line 2325)
+* BFD_RELOC_IA64_DTPREL22: howto manager. (line 2326)
+* BFD_RELOC_IA64_DTPREL32LSB: howto manager. (line 2329)
+* BFD_RELOC_IA64_DTPREL32MSB: howto manager. (line 2328)
+* BFD_RELOC_IA64_DTPREL64I: howto manager. (line 2327)
+* BFD_RELOC_IA64_DTPREL64LSB: howto manager. (line 2331)
+* BFD_RELOC_IA64_DTPREL64MSB: howto manager. (line 2330)
+* BFD_RELOC_IA64_FPTR32LSB: howto manager. (line 2275)
+* BFD_RELOC_IA64_FPTR32MSB: howto manager. (line 2274)
+* BFD_RELOC_IA64_FPTR64I: howto manager. (line 2273)
+* BFD_RELOC_IA64_FPTR64LSB: howto manager. (line 2277)
+* BFD_RELOC_IA64_FPTR64MSB: howto manager. (line 2276)
+* BFD_RELOC_IA64_GPREL22: howto manager. (line 2261)
+* BFD_RELOC_IA64_GPREL32LSB: howto manager. (line 2264)
+* BFD_RELOC_IA64_GPREL32MSB: howto manager. (line 2263)
+* BFD_RELOC_IA64_GPREL64I: howto manager. (line 2262)
+* BFD_RELOC_IA64_GPREL64LSB: howto manager. (line 2266)
+* BFD_RELOC_IA64_GPREL64MSB: howto manager. (line 2265)
+* BFD_RELOC_IA64_IMM14: howto manager. (line 2254)
+* BFD_RELOC_IA64_IMM22: howto manager. (line 2255)
+* BFD_RELOC_IA64_IMM64: howto manager. (line 2256)
+* BFD_RELOC_IA64_IPLTLSB: howto manager. (line 2312)
+* BFD_RELOC_IA64_IPLTMSB: howto manager. (line 2311)
+* BFD_RELOC_IA64_LDXMOV: howto manager. (line 2315)
+* BFD_RELOC_IA64_LTOFF22: howto manager. (line 2267)
+* BFD_RELOC_IA64_LTOFF22X: howto manager. (line 2314)
+* BFD_RELOC_IA64_LTOFF64I: howto manager. (line 2268)
+* BFD_RELOC_IA64_LTOFF_DTPMOD22: howto manager. (line 2324)
+* BFD_RELOC_IA64_LTOFF_DTPREL22: howto manager. (line 2332)
+* BFD_RELOC_IA64_LTOFF_FPTR22: howto manager. (line 2289)
+* BFD_RELOC_IA64_LTOFF_FPTR32LSB: howto manager. (line 2292)
+* BFD_RELOC_IA64_LTOFF_FPTR32MSB: howto manager. (line 2291)
+* BFD_RELOC_IA64_LTOFF_FPTR64I: howto manager. (line 2290)
+* BFD_RELOC_IA64_LTOFF_FPTR64LSB: howto manager. (line 2294)
+* BFD_RELOC_IA64_LTOFF_FPTR64MSB: howto manager. (line 2293)
+* BFD_RELOC_IA64_LTOFF_TPREL22: howto manager. (line 2321)
+* BFD_RELOC_IA64_LTV32LSB: howto manager. (line 2308)
+* BFD_RELOC_IA64_LTV32MSB: howto manager. (line 2307)
+* BFD_RELOC_IA64_LTV64LSB: howto manager. (line 2310)
+* BFD_RELOC_IA64_LTV64MSB: howto manager. (line 2309)
+* BFD_RELOC_IA64_PCREL21B: howto manager. (line 2278)
+* BFD_RELOC_IA64_PCREL21BI: howto manager. (line 2279)
+* BFD_RELOC_IA64_PCREL21F: howto manager. (line 2281)
+* BFD_RELOC_IA64_PCREL21M: howto manager. (line 2280)
+* BFD_RELOC_IA64_PCREL22: howto manager. (line 2282)
+* BFD_RELOC_IA64_PCREL32LSB: howto manager. (line 2286)
+* BFD_RELOC_IA64_PCREL32MSB: howto manager. (line 2285)
+* BFD_RELOC_IA64_PCREL60B: howto manager. (line 2283)
+* BFD_RELOC_IA64_PCREL64I: howto manager. (line 2284)
+* BFD_RELOC_IA64_PCREL64LSB: howto manager. (line 2288)
+* BFD_RELOC_IA64_PCREL64MSB: howto manager. (line 2287)
+* BFD_RELOC_IA64_PLTOFF22: howto manager. (line 2269)
+* BFD_RELOC_IA64_PLTOFF64I: howto manager. (line 2270)
+* BFD_RELOC_IA64_PLTOFF64LSB: howto manager. (line 2272)
+* BFD_RELOC_IA64_PLTOFF64MSB: howto manager. (line 2271)
+* BFD_RELOC_IA64_REL32LSB: howto manager. (line 2304)
+* BFD_RELOC_IA64_REL32MSB: howto manager. (line 2303)
+* BFD_RELOC_IA64_REL64LSB: howto manager. (line 2306)
+* BFD_RELOC_IA64_REL64MSB: howto manager. (line 2305)
+* BFD_RELOC_IA64_SECREL32LSB: howto manager. (line 2300)
+* BFD_RELOC_IA64_SECREL32MSB: howto manager. (line 2299)
+* BFD_RELOC_IA64_SECREL64LSB: howto manager. (line 2302)
+* BFD_RELOC_IA64_SECREL64MSB: howto manager. (line 2301)
+* BFD_RELOC_IA64_SEGREL32LSB: howto manager. (line 2296)
+* BFD_RELOC_IA64_SEGREL32MSB: howto manager. (line 2295)
+* BFD_RELOC_IA64_SEGREL64LSB: howto manager. (line 2298)
+* BFD_RELOC_IA64_SEGREL64MSB: howto manager. (line 2297)
+* BFD_RELOC_IA64_TPREL14: howto manager. (line 2316)
+* BFD_RELOC_IA64_TPREL22: howto manager. (line 2317)
+* BFD_RELOC_IA64_TPREL64I: howto manager. (line 2318)
+* BFD_RELOC_IA64_TPREL64LSB: howto manager. (line 2320)
+* BFD_RELOC_IA64_TPREL64MSB: howto manager. (line 2319)
+* BFD_RELOC_IP2K_ADDR16CJP: howto manager. (line 2206)
+* BFD_RELOC_IP2K_BANK: howto manager. (line 2203)
+* BFD_RELOC_IP2K_EX8DATA: howto manager. (line 2214)
+* BFD_RELOC_IP2K_FR9: howto manager. (line 2200)
+* BFD_RELOC_IP2K_FR_OFFSET: howto manager. (line 2227)
+* BFD_RELOC_IP2K_HI8DATA: howto manager. (line 2213)
+* BFD_RELOC_IP2K_HI8INSN: howto manager. (line 2218)
+* BFD_RELOC_IP2K_LO8DATA: howto manager. (line 2212)
+* BFD_RELOC_IP2K_LO8INSN: howto manager. (line 2217)
+* BFD_RELOC_IP2K_PAGE3: howto manager. (line 2209)
+* BFD_RELOC_IP2K_PC_SKIP: howto manager. (line 2221)
+* BFD_RELOC_IP2K_TEXT: howto manager. (line 2224)
+* BFD_RELOC_IQ2000_OFFSET_16: howto manager. (line 2764)
+* BFD_RELOC_IQ2000_OFFSET_21: howto manager. (line 2765)
+* BFD_RELOC_IQ2000_UHI16: howto manager. (line 2766)
+* BFD_RELOC_LM32_16_GOT: howto manager. (line 2871)
+* BFD_RELOC_LM32_BRANCH: howto manager. (line 2870)
+* BFD_RELOC_LM32_CALL: howto manager. (line 2869)
+* BFD_RELOC_LM32_COPY: howto manager. (line 2874)
+* BFD_RELOC_LM32_GLOB_DAT: howto manager. (line 2875)
+* BFD_RELOC_LM32_GOTOFF_HI16: howto manager. (line 2872)
+* BFD_RELOC_LM32_GOTOFF_LO16: howto manager. (line 2873)
+* BFD_RELOC_LM32_JMP_SLOT: howto manager. (line 2876)
+* BFD_RELOC_LM32_RELATIVE: howto manager. (line 2877)
+* BFD_RELOC_LO10: howto manager. (line 121)
+* BFD_RELOC_LO16: howto manager. (line 361)
+* BFD_RELOC_LO16_BASEREL: howto manager. (line 100)
+* BFD_RELOC_LO16_GOTOFF: howto manager. (line 56)
+* BFD_RELOC_LO16_PCREL: howto manager. (line 370)
+* BFD_RELOC_LO16_PLTOFF: howto manager. (line 68)
+* BFD_RELOC_M32C_HI8: howto manager. (line 1249)
+* BFD_RELOC_M32C_RL_1ADDR: howto manager. (line 1251)
+* BFD_RELOC_M32C_RL_2ADDR: howto manager. (line 1252)
+* BFD_RELOC_M32C_RL_JUMP: howto manager. (line 1250)
+* BFD_RELOC_M32R_10_PCREL: howto manager. (line 1259)
+* BFD_RELOC_M32R_18_PCREL: howto manager. (line 1263)
+* BFD_RELOC_M32R_24: howto manager. (line 1255)
+* BFD_RELOC_M32R_26_PCREL: howto manager. (line 1266)
+* BFD_RELOC_M32R_26_PLTREL: howto manager. (line 1285)
+* BFD_RELOC_M32R_COPY: howto manager. (line 1286)
+* BFD_RELOC_M32R_GLOB_DAT: howto manager. (line 1287)
+* BFD_RELOC_M32R_GOT16_HI_SLO: howto manager. (line 1296)
+* BFD_RELOC_M32R_GOT16_HI_ULO: howto manager. (line 1295)
+* BFD_RELOC_M32R_GOT16_LO: howto manager. (line 1297)
+* BFD_RELOC_M32R_GOT24: howto manager. (line 1284)
+* BFD_RELOC_M32R_GOTOFF: howto manager. (line 1290)
+* BFD_RELOC_M32R_GOTOFF_HI_SLO: howto manager. (line 1292)
+* BFD_RELOC_M32R_GOTOFF_HI_ULO: howto manager. (line 1291)
+* BFD_RELOC_M32R_GOTOFF_LO: howto manager. (line 1293)
+* BFD_RELOC_M32R_GOTPC24: howto manager. (line 1294)
+* BFD_RELOC_M32R_GOTPC_HI_SLO: howto manager. (line 1299)
+* BFD_RELOC_M32R_GOTPC_HI_ULO: howto manager. (line 1298)
+* BFD_RELOC_M32R_GOTPC_LO: howto manager. (line 1300)
+* BFD_RELOC_M32R_HI16_SLO: howto manager. (line 1273)
+* BFD_RELOC_M32R_HI16_ULO: howto manager. (line 1269)
+* BFD_RELOC_M32R_JMP_SLOT: howto manager. (line 1288)
+* BFD_RELOC_M32R_LO16: howto manager. (line 1277)
+* BFD_RELOC_M32R_RELATIVE: howto manager. (line 1289)
+* BFD_RELOC_M32R_SDA16: howto manager. (line 1280)
+* BFD_RELOC_M68HC11_24: howto manager. (line 2368)
+* BFD_RELOC_M68HC11_3B: howto manager. (line 2343)
+* BFD_RELOC_M68HC11_HI8: howto manager. (line 2335)
+* BFD_RELOC_M68HC11_LO16: howto manager. (line 2357)
+* BFD_RELOC_M68HC11_LO8: howto manager. (line 2339)
+* BFD_RELOC_M68HC11_PAGE: howto manager. (line 2363)
+* BFD_RELOC_M68HC11_RL_GROUP: howto manager. (line 2352)
+* BFD_RELOC_M68HC11_RL_JUMP: howto manager. (line 2346)
+* BFD_RELOC_M68HC12_10_PCREL: howto manager. (line 2428)
+* BFD_RELOC_M68HC12_16B: howto manager. (line 2422)
+* BFD_RELOC_M68HC12_5B: howto manager. (line 2374)
+* BFD_RELOC_M68HC12_9_PCREL: howto manager. (line 2425)
+* BFD_RELOC_M68HC12_9B: howto manager. (line 2419)
+* BFD_RELOC_M68HC12_HI8XG: howto manager. (line 2435)
+* BFD_RELOC_M68HC12_LO8XG: howto manager. (line 2431)
+* BFD_RELOC_MACH_O_LOCAL_SECTDIFF: howto manager. (line 2884)
+* BFD_RELOC_MACH_O_PAIR: howto manager. (line 2887)
+* BFD_RELOC_MACH_O_SECTDIFF: howto manager. (line 2880)
+* BFD_RELOC_MACH_O_X86_64_BRANCH32: howto manager. (line 2890)
+* BFD_RELOC_MACH_O_X86_64_BRANCH8: howto manager. (line 2891)
+* BFD_RELOC_MACH_O_X86_64_GOT: howto manager. (line 2895)
+* BFD_RELOC_MACH_O_X86_64_GOT_LOAD: howto manager. (line 2898)
+* BFD_RELOC_MACH_O_X86_64_PCREL32_1: howto manager. (line 2908)
+* BFD_RELOC_MACH_O_X86_64_PCREL32_2: howto manager. (line 2911)
+* BFD_RELOC_MACH_O_X86_64_PCREL32_4: howto manager. (line 2914)
+* BFD_RELOC_MACH_O_X86_64_SUBTRACTOR32: howto manager. (line 2902)
+* BFD_RELOC_MACH_O_X86_64_SUBTRACTOR64: howto manager. (line 2905)
+* BFD_RELOC_MCORE_PCREL_32: howto manager. (line 1730)
+* BFD_RELOC_MCORE_PCREL_IMM11BY2: howto manager. (line 1728)
+* BFD_RELOC_MCORE_PCREL_IMM4BY2: howto manager. (line 1729)
+* BFD_RELOC_MCORE_PCREL_IMM8BY4: howto manager. (line 1727)
+* BFD_RELOC_MCORE_PCREL_JSR_IMM11BY2: howto manager. (line 1731)
+* BFD_RELOC_MCORE_RVA: howto manager. (line 1732)
+* BFD_RELOC_MEP_16: howto manager. (line 1736)
+* BFD_RELOC_MEP_32: howto manager. (line 1737)
+* BFD_RELOC_MEP_8: howto manager. (line 1735)
+* BFD_RELOC_MEP_ADDR24A4: howto manager. (line 1752)
+* BFD_RELOC_MEP_GNU_VTENTRY: howto manager. (line 1754)
+* BFD_RELOC_MEP_GNU_VTINHERIT: howto manager. (line 1753)
+* BFD_RELOC_MEP_GPREL: howto manager. (line 1746)
+* BFD_RELOC_MEP_HI16S: howto manager. (line 1745)
+* BFD_RELOC_MEP_HI16U: howto manager. (line 1744)
+* BFD_RELOC_MEP_LOW16: howto manager. (line 1743)
+* BFD_RELOC_MEP_PCABS24A2: howto manager. (line 1742)
+* BFD_RELOC_MEP_PCREL12A2: howto manager. (line 1739)
+* BFD_RELOC_MEP_PCREL17A2: howto manager. (line 1740)
+* BFD_RELOC_MEP_PCREL24A2: howto manager. (line 1741)
+* BFD_RELOC_MEP_PCREL8A2: howto manager. (line 1738)
+* BFD_RELOC_MEP_TPREL: howto manager. (line 1747)
+* BFD_RELOC_MEP_TPREL7: howto manager. (line 1748)
+* BFD_RELOC_MEP_TPREL7A2: howto manager. (line 1749)
+* BFD_RELOC_MEP_TPREL7A4: howto manager. (line 1750)
+* BFD_RELOC_MEP_UIMM24: howto manager. (line 1751)
+* BFD_RELOC_METAG_COPY: howto manager. (line 1776)
+* BFD_RELOC_METAG_GETSET_GOT: howto manager. (line 1768)
+* BFD_RELOC_METAG_GETSET_GOTOFF: howto manager. (line 1767)
+* BFD_RELOC_METAG_GETSETOFF: howto manager. (line 1760)
+* BFD_RELOC_METAG_GLOB_DAT: howto manager. (line 1779)
+* BFD_RELOC_METAG_GOTOFF: howto manager. (line 1774)
+* BFD_RELOC_METAG_HI16_GOTOFF: howto manager. (line 1765)
+* BFD_RELOC_METAG_HI16_GOTPC: howto manager. (line 1769)
+* BFD_RELOC_METAG_HI16_PLT: howto manager. (line 1771)
+* BFD_RELOC_METAG_HIADDR16: howto manager. (line 1757)
+* BFD_RELOC_METAG_HIOG: howto manager. (line 1761)
+* BFD_RELOC_METAG_JMP_SLOT: howto manager. (line 1777)
+* BFD_RELOC_METAG_LO16_GOTOFF: howto manager. (line 1766)
+* BFD_RELOC_METAG_LO16_GOTPC: howto manager. (line 1770)
+* BFD_RELOC_METAG_LO16_PLT: howto manager. (line 1772)
+* BFD_RELOC_METAG_LOADDR16: howto manager. (line 1758)
+* BFD_RELOC_METAG_LOOG: howto manager. (line 1762)
+* BFD_RELOC_METAG_PLT: howto manager. (line 1775)
+* BFD_RELOC_METAG_REL16: howto manager. (line 1764)
+* BFD_RELOC_METAG_REL8: howto manager. (line 1763)
+* BFD_RELOC_METAG_RELATIVE: howto manager. (line 1778)
+* BFD_RELOC_METAG_RELBRANCH: howto manager. (line 1759)
+* BFD_RELOC_METAG_RELBRANCH_PLT: howto manager. (line 1773)
+* BFD_RELOC_METAG_TLS_DTPMOD: howto manager. (line 1790)
+* BFD_RELOC_METAG_TLS_DTPOFF: howto manager. (line 1791)
+* BFD_RELOC_METAG_TLS_GD: howto manager. (line 1780)
+* BFD_RELOC_METAG_TLS_IE: howto manager. (line 1785)
+* BFD_RELOC_METAG_TLS_IENONPIC: howto manager. (line 1786)
+* BFD_RELOC_METAG_TLS_IENONPIC_HI16: howto manager. (line 1787)
+* BFD_RELOC_METAG_TLS_IENONPIC_LO16: howto manager. (line 1788)
+* BFD_RELOC_METAG_TLS_LDM: howto manager. (line 1781)
+* BFD_RELOC_METAG_TLS_LDO: howto manager. (line 1784)
+* BFD_RELOC_METAG_TLS_LDO_HI16: howto manager. (line 1782)
+* BFD_RELOC_METAG_TLS_LDO_LO16: howto manager. (line 1783)
+* BFD_RELOC_METAG_TLS_LE: howto manager. (line 1792)
+* BFD_RELOC_METAG_TLS_LE_HI16: howto manager. (line 1793)
+* BFD_RELOC_METAG_TLS_LE_LO16: howto manager. (line 1794)
+* BFD_RELOC_METAG_TLS_TPOFF: howto manager. (line 1789)
+* BFD_RELOC_MICROBLAZE_32_GOTOFF: howto manager. (line 2961)
+* BFD_RELOC_MICROBLAZE_32_LO: howto manager. (line 2917)
+* BFD_RELOC_MICROBLAZE_32_LO_PCREL: howto manager. (line 2921)
+* BFD_RELOC_MICROBLAZE_32_ROSDA: howto manager. (line 2925)
+* BFD_RELOC_MICROBLAZE_32_RWSDA: howto manager. (line 2929)
+* BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM: howto manager. (line 2933)
+* BFD_RELOC_MICROBLAZE_32_TLSDTPMOD: howto manager. (line 2982)
+* BFD_RELOC_MICROBLAZE_32_TLSDTPREL: howto manager. (line 2985)
+* BFD_RELOC_MICROBLAZE_64_GOT: howto manager. (line 2947)
+* BFD_RELOC_MICROBLAZE_64_GOTOFF: howto manager. (line 2956)
+* BFD_RELOC_MICROBLAZE_64_GOTPC: howto manager. (line 2942)
+* BFD_RELOC_MICROBLAZE_64_NONE: howto manager. (line 2937)
+* BFD_RELOC_MICROBLAZE_64_PLT: howto manager. (line 2951)
+* BFD_RELOC_MICROBLAZE_64_TLS: howto manager. (line 2969)
+* BFD_RELOC_MICROBLAZE_64_TLSDTPREL: howto manager. (line 2988)
+* BFD_RELOC_MICROBLAZE_64_TLSGD: howto manager. (line 2972)
+* BFD_RELOC_MICROBLAZE_64_TLSGOTTPREL: howto manager. (line 2992)
+* BFD_RELOC_MICROBLAZE_64_TLSLD: howto manager. (line 2977)
+* BFD_RELOC_MICROBLAZE_64_TLSTPREL: howto manager. (line 2996)
+* BFD_RELOC_MICROBLAZE_COPY: howto manager. (line 2965)
+* BFD_RELOC_MICROMIPS_10_PCREL_S1: howto manager. (line 404)
+* BFD_RELOC_MICROMIPS_16_PCREL_S1: howto manager. (line 405)
+* BFD_RELOC_MICROMIPS_7_PCREL_S1: howto manager. (line 403)
+* BFD_RELOC_MICROMIPS_CALL16: howto manager. (line 423)
+* BFD_RELOC_MICROMIPS_CALL_HI16: howto manager. (line 429)
+* BFD_RELOC_MICROMIPS_CALL_LO16: howto manager. (line 431)
+* BFD_RELOC_MICROMIPS_GOT16: howto manager. (line 421)
+* BFD_RELOC_MICROMIPS_GOT_DISP: howto manager. (line 439)
+* BFD_RELOC_MICROMIPS_GOT_HI16: howto manager. (line 425)
+* BFD_RELOC_MICROMIPS_GOT_LO16: howto manager. (line 427)
+* BFD_RELOC_MICROMIPS_GOT_OFST: howto manager. (line 437)
+* BFD_RELOC_MICROMIPS_GOT_PAGE: howto manager. (line 435)
+* BFD_RELOC_MICROMIPS_GPREL16: howto manager. (line 414)
+* BFD_RELOC_MICROMIPS_HI16: howto manager. (line 415)
+* BFD_RELOC_MICROMIPS_HI16_S: howto manager. (line 416)
+* BFD_RELOC_MICROMIPS_HIGHER: howto manager. (line 448)
+* BFD_RELOC_MICROMIPS_HIGHEST: howto manager. (line 446)
+* BFD_RELOC_MICROMIPS_JALR: howto manager. (line 454)
+* BFD_RELOC_MICROMIPS_JMP: howto manager. (line 343)
+* BFD_RELOC_MICROMIPS_LITERAL: howto manager. (line 400)
+* BFD_RELOC_MICROMIPS_LO16: howto manager. (line 417)
+* BFD_RELOC_MICROMIPS_SCN_DISP: howto manager. (line 450)
+* BFD_RELOC_MICROMIPS_SUB: howto manager. (line 433)
+* BFD_RELOC_MICROMIPS_TLS_DTPREL_HI16: howto manager. (line 464)
+* BFD_RELOC_MICROMIPS_TLS_DTPREL_LO16: howto manager. (line 466)
+* BFD_RELOC_MICROMIPS_TLS_GD: howto manager. (line 460)
+* BFD_RELOC_MICROMIPS_TLS_GOTTPREL: howto manager. (line 468)
+* BFD_RELOC_MICROMIPS_TLS_LDM: howto manager. (line 462)
+* BFD_RELOC_MICROMIPS_TLS_TPREL_HI16: howto manager. (line 472)
+* BFD_RELOC_MICROMIPS_TLS_TPREL_LO16: howto manager. (line 474)
+* BFD_RELOC_MIPS16_CALL16: howto manager. (line 374)
+* BFD_RELOC_MIPS16_GOT16: howto manager. (line 373)
+* BFD_RELOC_MIPS16_GPREL: howto manager. (line 349)
+* BFD_RELOC_MIPS16_HI16: howto manager. (line 378)
+* BFD_RELOC_MIPS16_HI16_S: howto manager. (line 381)
+* BFD_RELOC_MIPS16_JMP: howto manager. (line 346)
+* BFD_RELOC_MIPS16_LO16: howto manager. (line 387)
+* BFD_RELOC_MIPS16_TLS_DTPREL_HI16: howto manager. (line 392)
+* BFD_RELOC_MIPS16_TLS_DTPREL_LO16: howto manager. (line 393)
+* BFD_RELOC_MIPS16_TLS_GD: howto manager. (line 390)
+* BFD_RELOC_MIPS16_TLS_GOTTPREL: howto manager. (line 394)
+* BFD_RELOC_MIPS16_TLS_LDM: howto manager. (line 391)
+* BFD_RELOC_MIPS16_TLS_TPREL_HI16: howto manager. (line 395)
+* BFD_RELOC_MIPS16_TLS_TPREL_LO16: howto manager. (line 396)
+* BFD_RELOC_MIPS_18_PCREL_S3: howto manager. (line 410)
+* BFD_RELOC_MIPS_19_PCREL_S2: howto manager. (line 411)
+* BFD_RELOC_MIPS_21_PCREL_S2: howto manager. (line 408)
+* BFD_RELOC_MIPS_26_PCREL_S2: howto manager. (line 409)
+* BFD_RELOC_MIPS_CALL16: howto manager. (line 422)
+* BFD_RELOC_MIPS_CALL_HI16: howto manager. (line 428)
+* BFD_RELOC_MIPS_CALL_LO16: howto manager. (line 430)
+* BFD_RELOC_MIPS_COPY: howto manager. (line 478)
+* BFD_RELOC_MIPS_DELETE: howto manager. (line 444)
+* BFD_RELOC_MIPS_EH: howto manager. (line 475)
+* BFD_RELOC_MIPS_GOT16: howto manager. (line 420)
+* BFD_RELOC_MIPS_GOT_DISP: howto manager. (line 438)
+* BFD_RELOC_MIPS_GOT_HI16: howto manager. (line 424)
+* BFD_RELOC_MIPS_GOT_LO16: howto manager. (line 426)
+* BFD_RELOC_MIPS_GOT_OFST: howto manager. (line 436)
+* BFD_RELOC_MIPS_GOT_PAGE: howto manager. (line 434)
+* BFD_RELOC_MIPS_HIGHER: howto manager. (line 447)
+* BFD_RELOC_MIPS_HIGHEST: howto manager. (line 445)
+* BFD_RELOC_MIPS_INSERT_A: howto manager. (line 442)
+* BFD_RELOC_MIPS_INSERT_B: howto manager. (line 443)
+* BFD_RELOC_MIPS_JALR: howto manager. (line 453)
+* BFD_RELOC_MIPS_JMP: howto manager. (line 342)
+* BFD_RELOC_MIPS_JUMP_SLOT: howto manager. (line 479)
+* BFD_RELOC_MIPS_LITERAL: howto manager. (line 399)
+* BFD_RELOC_MIPS_REL16: howto manager. (line 451)
+* BFD_RELOC_MIPS_RELGOT: howto manager. (line 452)
+* BFD_RELOC_MIPS_SCN_DISP: howto manager. (line 449)
+* BFD_RELOC_MIPS_SHIFT5: howto manager. (line 440)
+* BFD_RELOC_MIPS_SHIFT6: howto manager. (line 441)
+* BFD_RELOC_MIPS_SUB: howto manager. (line 432)
+* BFD_RELOC_MIPS_TLS_DTPMOD32: howto manager. (line 455)
+* BFD_RELOC_MIPS_TLS_DTPMOD64: howto manager. (line 457)
+* BFD_RELOC_MIPS_TLS_DTPREL32: howto manager. (line 456)
+* BFD_RELOC_MIPS_TLS_DTPREL64: howto manager. (line 458)
+* BFD_RELOC_MIPS_TLS_DTPREL_HI16: howto manager. (line 463)
+* BFD_RELOC_MIPS_TLS_DTPREL_LO16: howto manager. (line 465)
+* BFD_RELOC_MIPS_TLS_GD: howto manager. (line 459)
+* BFD_RELOC_MIPS_TLS_GOTTPREL: howto manager. (line 467)
+* BFD_RELOC_MIPS_TLS_LDM: howto manager. (line 461)
+* BFD_RELOC_MIPS_TLS_TPREL32: howto manager. (line 469)
+* BFD_RELOC_MIPS_TLS_TPREL64: howto manager. (line 470)
+* BFD_RELOC_MIPS_TLS_TPREL_HI16: howto manager. (line 471)
+* BFD_RELOC_MIPS_TLS_TPREL_LO16: howto manager. (line 473)
+* BFD_RELOC_MMIX_ADDR19: howto manager. (line 1823)
+* BFD_RELOC_MMIX_ADDR27: howto manager. (line 1827)
+* BFD_RELOC_MMIX_BASE_PLUS_OFFSET: howto manager. (line 1839)
+* BFD_RELOC_MMIX_CBRANCH: howto manager. (line 1803)
+* BFD_RELOC_MMIX_CBRANCH_1: howto manager. (line 1805)
+* BFD_RELOC_MMIX_CBRANCH_2: howto manager. (line 1806)
+* BFD_RELOC_MMIX_CBRANCH_3: howto manager. (line 1807)
+* BFD_RELOC_MMIX_CBRANCH_J: howto manager. (line 1804)
+* BFD_RELOC_MMIX_GETA: howto manager. (line 1797)
+* BFD_RELOC_MMIX_GETA_1: howto manager. (line 1798)
+* BFD_RELOC_MMIX_GETA_2: howto manager. (line 1799)
+* BFD_RELOC_MMIX_GETA_3: howto manager. (line 1800)
+* BFD_RELOC_MMIX_JMP: howto manager. (line 1817)
+* BFD_RELOC_MMIX_JMP_1: howto manager. (line 1818)
+* BFD_RELOC_MMIX_JMP_2: howto manager. (line 1819)
+* BFD_RELOC_MMIX_JMP_3: howto manager. (line 1820)
+* BFD_RELOC_MMIX_LOCAL: howto manager. (line 1843)
+* BFD_RELOC_MMIX_PUSHJ: howto manager. (line 1810)
+* BFD_RELOC_MMIX_PUSHJ_1: howto manager. (line 1811)
+* BFD_RELOC_MMIX_PUSHJ_2: howto manager. (line 1812)
+* BFD_RELOC_MMIX_PUSHJ_3: howto manager. (line 1813)
+* BFD_RELOC_MMIX_PUSHJ_STUBBABLE: howto manager. (line 1814)
+* BFD_RELOC_MMIX_REG: howto manager. (line 1835)
+* BFD_RELOC_MMIX_REG_OR_BYTE: howto manager. (line 1831)
+* BFD_RELOC_MN10300_16_PCREL: howto manager. (line 577)
+* BFD_RELOC_MN10300_32_PCREL: howto manager. (line 573)
+* BFD_RELOC_MN10300_ALIGN: howto manager. (line 558)
+* BFD_RELOC_MN10300_COPY: howto manager. (line 541)
+* BFD_RELOC_MN10300_GLOB_DAT: howto manager. (line 544)
+* BFD_RELOC_MN10300_GOT16: howto manager. (line 537)
+* BFD_RELOC_MN10300_GOT24: howto manager. (line 533)
+* BFD_RELOC_MN10300_GOT32: howto manager. (line 529)
+* BFD_RELOC_MN10300_GOTOFF24: howto manager. (line 526)
+* BFD_RELOC_MN10300_JMP_SLOT: howto manager. (line 547)
+* BFD_RELOC_MN10300_RELATIVE: howto manager. (line 550)
+* BFD_RELOC_MN10300_SYM_DIFF: howto manager. (line 553)
+* BFD_RELOC_MN10300_TLS_DTPMOD: howto manager. (line 568)
+* BFD_RELOC_MN10300_TLS_DTPOFF: howto manager. (line 569)
+* BFD_RELOC_MN10300_TLS_GD: howto manager. (line 562)
+* BFD_RELOC_MN10300_TLS_GOTIE: howto manager. (line 565)
+* BFD_RELOC_MN10300_TLS_IE: howto manager. (line 566)
+* BFD_RELOC_MN10300_TLS_LD: howto manager. (line 563)
+* BFD_RELOC_MN10300_TLS_LDO: howto manager. (line 564)
+* BFD_RELOC_MN10300_TLS_LE: howto manager. (line 567)
+* BFD_RELOC_MN10300_TLS_TPOFF: howto manager. (line 570)
+* BFD_RELOC_MOXIE_10_PCREL: howto manager. (line 482)
+* BFD_RELOC_MSP430_10_PCREL: howto manager. (line 2699)
+* BFD_RELOC_MSP430_16: howto manager. (line 2701)
+* BFD_RELOC_MSP430_16_BYTE: howto manager. (line 2703)
+* BFD_RELOC_MSP430_16_PCREL: howto manager. (line 2700)
+* BFD_RELOC_MSP430_16_PCREL_BYTE: howto manager. (line 2702)
+* BFD_RELOC_MSP430_2X_PCREL: howto manager. (line 2704)
+* BFD_RELOC_MSP430_ABS8: howto manager. (line 2706)
+* BFD_RELOC_MSP430_ABS_HI16: howto manager. (line 2718)
+* BFD_RELOC_MSP430_PREL31: howto manager. (line 2719)
+* BFD_RELOC_MSP430_RL_PCREL: howto manager. (line 2705)
+* BFD_RELOC_MSP430_SYM_DIFF: howto manager. (line 2720)
+* BFD_RELOC_MSP430X_ABS16: howto manager. (line 2717)
+* BFD_RELOC_MSP430X_ABS20_ADR_DST: howto manager. (line 2714)
+* BFD_RELOC_MSP430X_ABS20_ADR_SRC: howto manager. (line 2713)
+* BFD_RELOC_MSP430X_ABS20_EXT_DST: howto manager. (line 2711)
+* BFD_RELOC_MSP430X_ABS20_EXT_ODST: howto manager. (line 2712)
+* BFD_RELOC_MSP430X_ABS20_EXT_SRC: howto manager. (line 2710)
+* BFD_RELOC_MSP430X_PCR16: howto manager. (line 2715)
+* BFD_RELOC_MSP430X_PCR20_CALL: howto manager. (line 2716)
+* BFD_RELOC_MSP430X_PCR20_EXT_DST: howto manager. (line 2708)
+* BFD_RELOC_MSP430X_PCR20_EXT_ODST: howto manager. (line 2709)
+* BFD_RELOC_MSP430X_PCR20_EXT_SRC: howto manager. (line 2707)
+* BFD_RELOC_MT_GNU_VTENTRY: howto manager. (line 2693)
+* BFD_RELOC_MT_GNU_VTINHERIT: howto manager. (line 2690)
+* BFD_RELOC_MT_HI16: howto manager. (line 2684)
+* BFD_RELOC_MT_LO16: howto manager. (line 2687)
+* BFD_RELOC_MT_PC16: howto manager. (line 2681)
+* BFD_RELOC_MT_PCINSN8: howto manager. (line 2696)
+* BFD_RELOC_NDS32_10_UPCREL: howto manager. (line 1452)
+* BFD_RELOC_NDS32_10IFCU_PCREL: howto manager. (line 1485)
+* BFD_RELOC_NDS32_15_FIXED: howto manager. (line 1406)
+* BFD_RELOC_NDS32_15_PCREL: howto manager. (line 1314)
+* BFD_RELOC_NDS32_17_FIXED: howto manager. (line 1407)
+* BFD_RELOC_NDS32_17_PCREL: howto manager. (line 1317)
+* BFD_RELOC_NDS32_17IFC_PCREL: howto manager. (line 1484)
+* BFD_RELOC_NDS32_20: howto manager. (line 1303)
+* BFD_RELOC_NDS32_25_ABS: howto manager. (line 1479)
+* BFD_RELOC_NDS32_25_FIXED: howto manager. (line 1408)
+* BFD_RELOC_NDS32_25_PCREL: howto manager. (line 1320)
+* BFD_RELOC_NDS32_25_PLTREL: howto manager. (line 1381)
+* BFD_RELOC_NDS32_5: howto manager. (line 1449)
+* BFD_RELOC_NDS32_9_FIXED: howto manager. (line 1405)
+* BFD_RELOC_NDS32_9_PCREL: howto manager. (line 1306)
+* BFD_RELOC_NDS32_9_PLTREL: howto manager. (line 1380)
+* BFD_RELOC_NDS32_COPY: howto manager. (line 1382)
+* BFD_RELOC_NDS32_DATA: howto manager. (line 1482)
+* BFD_RELOC_NDS32_DIFF16: howto manager. (line 1473)
+* BFD_RELOC_NDS32_DIFF32: howto manager. (line 1474)
+* BFD_RELOC_NDS32_DIFF8: howto manager. (line 1472)
+* BFD_RELOC_NDS32_DIFF_ULEB128: howto manager. (line 1475)
+* BFD_RELOC_NDS32_DWARF2_LEB: howto manager. (line 1432)
+* BFD_RELOC_NDS32_DWARF2_OP1: howto manager. (line 1430)
+* BFD_RELOC_NDS32_DWARF2_OP2: howto manager. (line 1431)
+* BFD_RELOC_NDS32_EMPTY: howto manager. (line 1476)
+* BFD_RELOC_NDS32_GLOB_DAT: howto manager. (line 1383)
+* BFD_RELOC_NDS32_GOT15S2: howto manager. (line 1445)
+* BFD_RELOC_NDS32_GOT17S2: howto manager. (line 1446)
+* BFD_RELOC_NDS32_GOT20: howto manager. (line 1379)
+* BFD_RELOC_NDS32_GOT_HI20: howto manager. (line 1390)
+* BFD_RELOC_NDS32_GOT_LO12: howto manager. (line 1391)
+* BFD_RELOC_NDS32_GOT_LO15: howto manager. (line 1441)
+* BFD_RELOC_NDS32_GOT_LO19: howto manager. (line 1442)
+* BFD_RELOC_NDS32_GOT_SUFF: howto manager. (line 1460)
+* BFD_RELOC_NDS32_GOTOFF: howto manager. (line 1386)
+* BFD_RELOC_NDS32_GOTOFF_HI20: howto manager. (line 1387)
+* BFD_RELOC_NDS32_GOTOFF_LO12: howto manager. (line 1388)
+* BFD_RELOC_NDS32_GOTOFF_LO15: howto manager. (line 1443)
+* BFD_RELOC_NDS32_GOTOFF_LO19: howto manager. (line 1444)
+* BFD_RELOC_NDS32_GOTOFF_SUFF: howto manager. (line 1461)
+* BFD_RELOC_NDS32_GOTPC20: howto manager. (line 1389)
+* BFD_RELOC_NDS32_GOTPC_HI20: howto manager. (line 1392)
+* BFD_RELOC_NDS32_GOTPC_LO12: howto manager. (line 1393)
+* BFD_RELOC_NDS32_GOTTPOFF: howto manager. (line 1493)
+* BFD_RELOC_NDS32_HI20: howto manager. (line 1323)
+* BFD_RELOC_NDS32_INSN16: howto manager. (line 1396)
+* BFD_RELOC_NDS32_JMP_SLOT: howto manager. (line 1384)
+* BFD_RELOC_NDS32_LABEL: howto manager. (line 1397)
+* BFD_RELOC_NDS32_LO12S0: howto manager. (line 1339)
+* BFD_RELOC_NDS32_LO12S0_ORI: howto manager. (line 1343)
+* BFD_RELOC_NDS32_LO12S1: howto manager. (line 1335)
+* BFD_RELOC_NDS32_LO12S2: howto manager. (line 1331)
+* BFD_RELOC_NDS32_LO12S2_DP: howto manager. (line 1426)
+* BFD_RELOC_NDS32_LO12S2_SP: howto manager. (line 1427)
+* BFD_RELOC_NDS32_LO12S3: howto manager. (line 1327)
+* BFD_RELOC_NDS32_LOADSTORE: howto manager. (line 1404)
+* BFD_RELOC_NDS32_LONGCALL1: howto manager. (line 1398)
+* BFD_RELOC_NDS32_LONGCALL2: howto manager. (line 1399)
+* BFD_RELOC_NDS32_LONGCALL3: howto manager. (line 1400)
+* BFD_RELOC_NDS32_LONGCALL4: howto manager. (line 1409)
+* BFD_RELOC_NDS32_LONGCALL5: howto manager. (line 1410)
+* BFD_RELOC_NDS32_LONGCALL6: howto manager. (line 1411)
+* BFD_RELOC_NDS32_LONGJUMP1: howto manager. (line 1401)
+* BFD_RELOC_NDS32_LONGJUMP2: howto manager. (line 1402)
+* BFD_RELOC_NDS32_LONGJUMP3: howto manager. (line 1403)
+* BFD_RELOC_NDS32_LONGJUMP4: howto manager. (line 1412)
+* BFD_RELOC_NDS32_LONGJUMP5: howto manager. (line 1413)
+* BFD_RELOC_NDS32_LONGJUMP6: howto manager. (line 1414)
+* BFD_RELOC_NDS32_LONGJUMP7: howto manager. (line 1415)
+* BFD_RELOC_NDS32_MINUEND: howto manager. (line 1470)
+* BFD_RELOC_NDS32_MULCALL_SUFF: howto manager. (line 1463)
+* BFD_RELOC_NDS32_PLT_GOT_SUFF: howto manager. (line 1462)
+* BFD_RELOC_NDS32_PLT_GOTREL_HI20: howto manager. (line 1420)
+* BFD_RELOC_NDS32_PLT_GOTREL_LO12: howto manager. (line 1421)
+* BFD_RELOC_NDS32_PLT_GOTREL_LO15: howto manager. (line 1439)
+* BFD_RELOC_NDS32_PLT_GOTREL_LO19: howto manager. (line 1440)
+* BFD_RELOC_NDS32_PLT_GOTREL_LO20: howto manager. (line 1438)
+* BFD_RELOC_NDS32_PLTBLOCK: howto manager. (line 1467)
+* BFD_RELOC_NDS32_PLTREL_HI20: howto manager. (line 1418)
+* BFD_RELOC_NDS32_PLTREL_LO12: howto manager. (line 1419)
+* BFD_RELOC_NDS32_PTR: howto manager. (line 1464)
+* BFD_RELOC_NDS32_PTR_COUNT: howto manager. (line 1465)
+* BFD_RELOC_NDS32_PTR_RESOLVED: howto manager. (line 1466)
+* BFD_RELOC_NDS32_RELATIVE: howto manager. (line 1385)
+* BFD_RELOC_NDS32_RELAX_ENTRY: howto manager. (line 1459)
+* BFD_RELOC_NDS32_RELAX_REGION_BEGIN: howto manager. (line 1468)
+* BFD_RELOC_NDS32_RELAX_REGION_END: howto manager. (line 1469)
+* BFD_RELOC_NDS32_SDA12S2_DP: howto manager. (line 1424)
+* BFD_RELOC_NDS32_SDA12S2_SP: howto manager. (line 1425)
+* BFD_RELOC_NDS32_SDA15S0: howto manager. (line 1359)
+* BFD_RELOC_NDS32_SDA15S1: howto manager. (line 1355)
+* BFD_RELOC_NDS32_SDA15S2: howto manager. (line 1351)
+* BFD_RELOC_NDS32_SDA15S3: howto manager. (line 1347)
+* BFD_RELOC_NDS32_SDA16S3: howto manager. (line 1363)
+* BFD_RELOC_NDS32_SDA17S2: howto manager. (line 1367)
+* BFD_RELOC_NDS32_SDA18S1: howto manager. (line 1371)
+* BFD_RELOC_NDS32_SDA19S0: howto manager. (line 1375)
+* BFD_RELOC_NDS32_SDA_FP7U2_RELA: howto manager. (line 1456)
+* BFD_RELOC_NDS32_SUBTRAHEND: howto manager. (line 1471)
+* BFD_RELOC_NDS32_TLS_IE_HI20: howto manager. (line 1494)
+* BFD_RELOC_NDS32_TLS_IE_LO12S2: howto manager. (line 1495)
+* BFD_RELOC_NDS32_TLS_LE_15S0: howto manager. (line 1498)
+* BFD_RELOC_NDS32_TLS_LE_15S1: howto manager. (line 1499)
+* BFD_RELOC_NDS32_TLS_LE_15S2: howto manager. (line 1500)
+* BFD_RELOC_NDS32_TLS_LE_20: howto manager. (line 1497)
+* BFD_RELOC_NDS32_TLS_LE_ADD: howto manager. (line 1491)
+* BFD_RELOC_NDS32_TLS_LE_HI20: howto manager. (line 1489)
+* BFD_RELOC_NDS32_TLS_LE_LO12: howto manager. (line 1490)
+* BFD_RELOC_NDS32_TLS_LE_LS: howto manager. (line 1492)
+* BFD_RELOC_NDS32_TLS_TPOFF: howto manager. (line 1496)
+* BFD_RELOC_NDS32_TPOFF: howto manager. (line 1488)
+* BFD_RELOC_NDS32_TRAN: howto manager. (line 1483)
+* BFD_RELOC_NDS32_UPDATE_TA: howto manager. (line 1435)
+* BFD_RELOC_NDS32_WORD_9_PCREL: howto manager. (line 1310)
+* BFD_RELOC_NIOS2_ALIGN: howto manager. (line 2737)
+* BFD_RELOC_NIOS2_CACHE_OPX: howto manager. (line 2727)
+* BFD_RELOC_NIOS2_CALL16: howto manager. (line 2739)
+* BFD_RELOC_NIOS2_CALL26: howto manager. (line 2725)
+* BFD_RELOC_NIOS2_CALL26_NOAT: howto manager. (line 2757)
+* BFD_RELOC_NIOS2_CALL_HA: howto manager. (line 2761)
+* BFD_RELOC_NIOS2_CALL_LO: howto manager. (line 2760)
+* BFD_RELOC_NIOS2_CALLR: howto manager. (line 2736)
+* BFD_RELOC_NIOS2_CJMP: howto manager. (line 2735)
+* BFD_RELOC_NIOS2_COPY: howto manager. (line 2752)
+* BFD_RELOC_NIOS2_GLOB_DAT: howto manager. (line 2753)
+* BFD_RELOC_NIOS2_GOT16: howto manager. (line 2738)
+* BFD_RELOC_NIOS2_GOT_HA: howto manager. (line 2759)
+* BFD_RELOC_NIOS2_GOT_LO: howto manager. (line 2758)
+* BFD_RELOC_NIOS2_GOTOFF: howto manager. (line 2756)
+* BFD_RELOC_NIOS2_GOTOFF_HA: howto manager. (line 2741)
+* BFD_RELOC_NIOS2_GOTOFF_LO: howto manager. (line 2740)
+* BFD_RELOC_NIOS2_GPREL: howto manager. (line 2733)
+* BFD_RELOC_NIOS2_HI16: howto manager. (line 2730)
+* BFD_RELOC_NIOS2_HIADJ16: howto manager. (line 2732)
+* BFD_RELOC_NIOS2_IMM5: howto manager. (line 2726)
+* BFD_RELOC_NIOS2_IMM6: howto manager. (line 2728)
+* BFD_RELOC_NIOS2_IMM8: howto manager. (line 2729)
+* BFD_RELOC_NIOS2_JUMP_SLOT: howto manager. (line 2754)
+* BFD_RELOC_NIOS2_LO16: howto manager. (line 2731)
+* BFD_RELOC_NIOS2_PCREL_HA: howto manager. (line 2743)
+* BFD_RELOC_NIOS2_PCREL_LO: howto manager. (line 2742)
+* BFD_RELOC_NIOS2_RELATIVE: howto manager. (line 2755)
+* BFD_RELOC_NIOS2_S16: howto manager. (line 2723)
+* BFD_RELOC_NIOS2_TLS_DTPMOD: howto manager. (line 2749)
+* BFD_RELOC_NIOS2_TLS_DTPREL: howto manager. (line 2750)
+* BFD_RELOC_NIOS2_TLS_GD16: howto manager. (line 2744)
+* BFD_RELOC_NIOS2_TLS_IE16: howto manager. (line 2747)
+* BFD_RELOC_NIOS2_TLS_LDM16: howto manager. (line 2745)
+* BFD_RELOC_NIOS2_TLS_LDO16: howto manager. (line 2746)
+* BFD_RELOC_NIOS2_TLS_LE16: howto manager. (line 2748)
+* BFD_RELOC_NIOS2_TLS_TPREL: howto manager. (line 2751)
+* BFD_RELOC_NIOS2_U16: howto manager. (line 2724)
+* BFD_RELOC_NIOS2_UJMP: howto manager. (line 2734)
+* BFD_RELOC_NONE: howto manager. (line 135)
+* BFD_RELOC_NS32K_DISP_16: howto manager. (line 645)
+* BFD_RELOC_NS32K_DISP_16_PCREL: howto manager. (line 648)
+* BFD_RELOC_NS32K_DISP_32: howto manager. (line 646)
+* BFD_RELOC_NS32K_DISP_32_PCREL: howto manager. (line 649)
+* BFD_RELOC_NS32K_DISP_8: howto manager. (line 644)
+* BFD_RELOC_NS32K_DISP_8_PCREL: howto manager. (line 647)
+* BFD_RELOC_NS32K_IMM_16: howto manager. (line 639)
+* BFD_RELOC_NS32K_IMM_16_PCREL: howto manager. (line 642)
+* BFD_RELOC_NS32K_IMM_32: howto manager. (line 640)
+* BFD_RELOC_NS32K_IMM_32_PCREL: howto manager. (line 643)
+* BFD_RELOC_NS32K_IMM_8: howto manager. (line 638)
+* BFD_RELOC_NS32K_IMM_8_PCREL: howto manager. (line 641)
+* BFD_RELOC_OR1K_COPY: howto manager. (line 2634)
+* BFD_RELOC_OR1K_GLOB_DAT: howto manager. (line 2635)
+* BFD_RELOC_OR1K_GOT16: howto manager. (line 2630)
+* BFD_RELOC_OR1K_GOTOFF_HI16: howto manager. (line 2632)
+* BFD_RELOC_OR1K_GOTOFF_LO16: howto manager. (line 2633)
+* BFD_RELOC_OR1K_GOTPC_HI16: howto manager. (line 2628)
+* BFD_RELOC_OR1K_GOTPC_LO16: howto manager. (line 2629)
+* BFD_RELOC_OR1K_JMP_SLOT: howto manager. (line 2636)
+* BFD_RELOC_OR1K_PLT26: howto manager. (line 2631)
+* BFD_RELOC_OR1K_REL_26: howto manager. (line 2627)
+* BFD_RELOC_OR1K_RELATIVE: howto manager. (line 2637)
+* BFD_RELOC_OR1K_TLS_DTPMOD: howto manager. (line 2650)
+* BFD_RELOC_OR1K_TLS_DTPOFF: howto manager. (line 2649)
+* BFD_RELOC_OR1K_TLS_GD_HI16: howto manager. (line 2638)
+* BFD_RELOC_OR1K_TLS_GD_LO16: howto manager. (line 2639)
+* BFD_RELOC_OR1K_TLS_IE_HI16: howto manager. (line 2644)
+* BFD_RELOC_OR1K_TLS_IE_LO16: howto manager. (line 2645)
+* BFD_RELOC_OR1K_TLS_LDM_HI16: howto manager. (line 2640)
+* BFD_RELOC_OR1K_TLS_LDM_LO16: howto manager. (line 2641)
+* BFD_RELOC_OR1K_TLS_LDO_HI16: howto manager. (line 2642)
+* BFD_RELOC_OR1K_TLS_LDO_LO16: howto manager. (line 2643)
+* BFD_RELOC_OR1K_TLS_LE_HI16: howto manager. (line 2646)
+* BFD_RELOC_OR1K_TLS_LE_LO16: howto manager. (line 2647)
+* BFD_RELOC_OR1K_TLS_TPOFF: howto manager. (line 2648)
+* BFD_RELOC_PDP11_DISP_6_PCREL: howto manager. (line 653)
+* BFD_RELOC_PDP11_DISP_8_PCREL: howto manager. (line 652)
+* BFD_RELOC_PJ_CODE_DIR16: howto manager. (line 658)
+* BFD_RELOC_PJ_CODE_DIR32: howto manager. (line 659)
+* BFD_RELOC_PJ_CODE_HI16: howto manager. (line 656)
+* BFD_RELOC_PJ_CODE_LO16: howto manager. (line 657)
+* BFD_RELOC_PJ_CODE_REL16: howto manager. (line 660)
+* BFD_RELOC_PJ_CODE_REL32: howto manager. (line 661)
+* BFD_RELOC_PPC64_ADDR16_DS: howto manager. (line 723)
+* BFD_RELOC_PPC64_ADDR16_HIGH: howto manager. (line 734)
+* BFD_RELOC_PPC64_ADDR16_HIGHA: howto manager. (line 735)
+* BFD_RELOC_PPC64_ADDR16_LO_DS: howto manager. (line 724)
+* BFD_RELOC_PPC64_ADDR64_LOCAL: howto manager. (line 736)
+* BFD_RELOC_PPC64_DTPREL16_DS: howto manager. (line 775)
+* BFD_RELOC_PPC64_DTPREL16_HIGH: howto manager. (line 783)
+* BFD_RELOC_PPC64_DTPREL16_HIGHA: howto manager. (line 784)
+* BFD_RELOC_PPC64_DTPREL16_HIGHER: howto manager. (line 777)
+* BFD_RELOC_PPC64_DTPREL16_HIGHERA: howto manager. (line 778)
+* BFD_RELOC_PPC64_DTPREL16_HIGHEST: howto manager. (line 779)
+* BFD_RELOC_PPC64_DTPREL16_HIGHESTA: howto manager. (line 780)
+* BFD_RELOC_PPC64_DTPREL16_LO_DS: howto manager. (line 776)
+* BFD_RELOC_PPC64_GOT16_DS: howto manager. (line 725)
+* BFD_RELOC_PPC64_GOT16_LO_DS: howto manager. (line 726)
+* BFD_RELOC_PPC64_HIGHER: howto manager. (line 711)
+* BFD_RELOC_PPC64_HIGHER_S: howto manager. (line 712)
+* BFD_RELOC_PPC64_HIGHEST: howto manager. (line 713)
+* BFD_RELOC_PPC64_HIGHEST_S: howto manager. (line 714)
+* BFD_RELOC_PPC64_PLT16_LO_DS: howto manager. (line 727)
+* BFD_RELOC_PPC64_PLTGOT16: howto manager. (line 719)
+* BFD_RELOC_PPC64_PLTGOT16_DS: howto manager. (line 732)
+* BFD_RELOC_PPC64_PLTGOT16_HA: howto manager. (line 722)
+* BFD_RELOC_PPC64_PLTGOT16_HI: howto manager. (line 721)
+* BFD_RELOC_PPC64_PLTGOT16_LO: howto manager. (line 720)
+* BFD_RELOC_PPC64_PLTGOT16_LO_DS: howto manager. (line 733)
+* BFD_RELOC_PPC64_SECTOFF_DS: howto manager. (line 728)
+* BFD_RELOC_PPC64_SECTOFF_LO_DS: howto manager. (line 729)
+* BFD_RELOC_PPC64_TOC: howto manager. (line 718)
+* BFD_RELOC_PPC64_TOC16_DS: howto manager. (line 730)
+* BFD_RELOC_PPC64_TOC16_HA: howto manager. (line 717)
+* BFD_RELOC_PPC64_TOC16_HI: howto manager. (line 716)
+* BFD_RELOC_PPC64_TOC16_LO: howto manager. (line 715)
+* BFD_RELOC_PPC64_TOC16_LO_DS: howto manager. (line 731)
+* BFD_RELOC_PPC64_TPREL16_DS: howto manager. (line 769)
+* BFD_RELOC_PPC64_TPREL16_HIGH: howto manager. (line 781)
+* BFD_RELOC_PPC64_TPREL16_HIGHA: howto manager. (line 782)
+* BFD_RELOC_PPC64_TPREL16_HIGHER: howto manager. (line 771)
+* BFD_RELOC_PPC64_TPREL16_HIGHERA: howto manager. (line 772)
+* BFD_RELOC_PPC64_TPREL16_HIGHEST: howto manager. (line 773)
+* BFD_RELOC_PPC64_TPREL16_HIGHESTA: howto manager. (line 774)
+* BFD_RELOC_PPC64_TPREL16_LO_DS: howto manager. (line 770)
+* BFD_RELOC_PPC_B16: howto manager. (line 667)
+* BFD_RELOC_PPC_B16_BRNTAKEN: howto manager. (line 669)
+* BFD_RELOC_PPC_B16_BRTAKEN: howto manager. (line 668)
+* BFD_RELOC_PPC_B26: howto manager. (line 664)
+* BFD_RELOC_PPC_BA16: howto manager. (line 670)
+* BFD_RELOC_PPC_BA16_BRNTAKEN: howto manager. (line 672)
+* BFD_RELOC_PPC_BA16_BRTAKEN: howto manager. (line 671)
+* BFD_RELOC_PPC_BA26: howto manager. (line 665)
+* BFD_RELOC_PPC_COPY: howto manager. (line 673)
+* BFD_RELOC_PPC_DTPMOD: howto manager. (line 742)
+* BFD_RELOC_PPC_DTPREL: howto manager. (line 752)
+* BFD_RELOC_PPC_DTPREL16: howto manager. (line 748)
+* BFD_RELOC_PPC_DTPREL16_HA: howto manager. (line 751)
+* BFD_RELOC_PPC_DTPREL16_HI: howto manager. (line 750)
+* BFD_RELOC_PPC_DTPREL16_LO: howto manager. (line 749)
+* BFD_RELOC_PPC_EMB_BIT_FLD: howto manager. (line 692)
+* BFD_RELOC_PPC_EMB_MRKREF: howto manager. (line 687)
+* BFD_RELOC_PPC_EMB_NADDR16: howto manager. (line 679)
+* BFD_RELOC_PPC_EMB_NADDR16_HA: howto manager. (line 682)
+* BFD_RELOC_PPC_EMB_NADDR16_HI: howto manager. (line 681)
+* BFD_RELOC_PPC_EMB_NADDR16_LO: howto manager. (line 680)
+* BFD_RELOC_PPC_EMB_NADDR32: howto manager. (line 678)
+* BFD_RELOC_PPC_EMB_RELSDA: howto manager. (line 693)
+* BFD_RELOC_PPC_EMB_RELSEC16: howto manager. (line 688)
+* BFD_RELOC_PPC_EMB_RELST_HA: howto manager. (line 691)
+* BFD_RELOC_PPC_EMB_RELST_HI: howto manager. (line 690)
+* BFD_RELOC_PPC_EMB_RELST_LO: howto manager. (line 689)
+* BFD_RELOC_PPC_EMB_SDA21: howto manager. (line 686)
+* BFD_RELOC_PPC_EMB_SDA2I16: howto manager. (line 684)
+* BFD_RELOC_PPC_EMB_SDA2REL: howto manager. (line 685)
+* BFD_RELOC_PPC_EMB_SDAI16: howto manager. (line 683)
+* BFD_RELOC_PPC_GLOB_DAT: howto manager. (line 674)
+* BFD_RELOC_PPC_GOT_DTPREL16: howto manager. (line 765)
+* BFD_RELOC_PPC_GOT_DTPREL16_HA: howto manager. (line 768)
+* BFD_RELOC_PPC_GOT_DTPREL16_HI: howto manager. (line 767)
+* BFD_RELOC_PPC_GOT_DTPREL16_LO: howto manager. (line 766)
+* BFD_RELOC_PPC_GOT_TLSGD16: howto manager. (line 753)
+* BFD_RELOC_PPC_GOT_TLSGD16_HA: howto manager. (line 756)
+* BFD_RELOC_PPC_GOT_TLSGD16_HI: howto manager. (line 755)
+* BFD_RELOC_PPC_GOT_TLSGD16_LO: howto manager. (line 754)
+* BFD_RELOC_PPC_GOT_TLSLD16: howto manager. (line 757)
+* BFD_RELOC_PPC_GOT_TLSLD16_HA: howto manager. (line 760)
+* BFD_RELOC_PPC_GOT_TLSLD16_HI: howto manager. (line 759)
+* BFD_RELOC_PPC_GOT_TLSLD16_LO: howto manager. (line 758)
+* BFD_RELOC_PPC_GOT_TPREL16: howto manager. (line 761)
+* BFD_RELOC_PPC_GOT_TPREL16_HA: howto manager. (line 764)
+* BFD_RELOC_PPC_GOT_TPREL16_HI: howto manager. (line 763)
+* BFD_RELOC_PPC_GOT_TPREL16_LO: howto manager. (line 762)
+* BFD_RELOC_PPC_JMP_SLOT: howto manager. (line 675)
+* BFD_RELOC_PPC_LOCAL24PC: howto manager. (line 677)
+* BFD_RELOC_PPC_RELATIVE: howto manager. (line 676)
+* BFD_RELOC_PPC_TLS: howto manager. (line 739)
+* BFD_RELOC_PPC_TLSGD: howto manager. (line 740)
+* BFD_RELOC_PPC_TLSLD: howto manager. (line 741)
+* BFD_RELOC_PPC_TOC16: howto manager. (line 666)
+* BFD_RELOC_PPC_TPREL: howto manager. (line 747)
+* BFD_RELOC_PPC_TPREL16: howto manager. (line 743)
+* BFD_RELOC_PPC_TPREL16_HA: howto manager. (line 746)
+* BFD_RELOC_PPC_TPREL16_HI: howto manager. (line 745)
+* BFD_RELOC_PPC_TPREL16_LO: howto manager. (line 744)
+* BFD_RELOC_PPC_VLE_HA16A: howto manager. (line 701)
+* BFD_RELOC_PPC_VLE_HA16D: howto manager. (line 702)
+* BFD_RELOC_PPC_VLE_HI16A: howto manager. (line 699)
+* BFD_RELOC_PPC_VLE_HI16D: howto manager. (line 700)
+* BFD_RELOC_PPC_VLE_LO16A: howto manager. (line 697)
+* BFD_RELOC_PPC_VLE_LO16D: howto manager. (line 698)
+* BFD_RELOC_PPC_VLE_REL15: howto manager. (line 695)
+* BFD_RELOC_PPC_VLE_REL24: howto manager. (line 696)
+* BFD_RELOC_PPC_VLE_REL8: howto manager. (line 694)
+* BFD_RELOC_PPC_VLE_SDA21: howto manager. (line 703)
+* BFD_RELOC_PPC_VLE_SDA21_LO: howto manager. (line 704)
+* BFD_RELOC_PPC_VLE_SDAREL_HA16A: howto manager. (line 709)
+* BFD_RELOC_PPC_VLE_SDAREL_HA16D: howto manager. (line 710)
+* BFD_RELOC_PPC_VLE_SDAREL_HI16A: howto manager. (line 707)
+* BFD_RELOC_PPC_VLE_SDAREL_HI16D: howto manager. (line 708)
+* BFD_RELOC_PPC_VLE_SDAREL_LO16A: howto manager. (line 705)
+* BFD_RELOC_PPC_VLE_SDAREL_LO16D: howto manager. (line 706)
+* BFD_RELOC_RELC: howto manager. (line 2667)
+* BFD_RELOC_RL78_16_OP: howto manager. (line 1988)
+* BFD_RELOC_RL78_16U: howto manager. (line 1992)
+* BFD_RELOC_RL78_24_OP: howto manager. (line 1989)
+* BFD_RELOC_RL78_24U: howto manager. (line 1993)
+* BFD_RELOC_RL78_32_OP: howto manager. (line 1990)
+* BFD_RELOC_RL78_8U: howto manager. (line 1991)
+* BFD_RELOC_RL78_ABS16: howto manager. (line 2005)
+* BFD_RELOC_RL78_ABS16_REV: howto manager. (line 2006)
+* BFD_RELOC_RL78_ABS16U: howto manager. (line 2009)
+* BFD_RELOC_RL78_ABS16UL: howto manager. (line 2011)
+* BFD_RELOC_RL78_ABS16UW: howto manager. (line 2010)
+* BFD_RELOC_RL78_ABS32: howto manager. (line 2007)
+* BFD_RELOC_RL78_ABS32_REV: howto manager. (line 2008)
+* BFD_RELOC_RL78_ABS8: howto manager. (line 2004)
+* BFD_RELOC_RL78_CODE: howto manager. (line 2016)
+* BFD_RELOC_RL78_DIFF: howto manager. (line 1995)
+* BFD_RELOC_RL78_DIR3U_PCREL: howto manager. (line 1994)
+* BFD_RELOC_RL78_GPRELB: howto manager. (line 1996)
+* BFD_RELOC_RL78_GPRELL: howto manager. (line 1998)
+* BFD_RELOC_RL78_GPRELW: howto manager. (line 1997)
+* BFD_RELOC_RL78_HI16: howto manager. (line 2013)
+* BFD_RELOC_RL78_HI8: howto manager. (line 2014)
+* BFD_RELOC_RL78_LO16: howto manager. (line 2015)
+* BFD_RELOC_RL78_NEG16: howto manager. (line 1985)
+* BFD_RELOC_RL78_NEG24: howto manager. (line 1986)
+* BFD_RELOC_RL78_NEG32: howto manager. (line 1987)
+* BFD_RELOC_RL78_NEG8: howto manager. (line 1984)
+* BFD_RELOC_RL78_OP_AND: howto manager. (line 2002)
+* BFD_RELOC_RL78_OP_NEG: howto manager. (line 2001)
+* BFD_RELOC_RL78_OP_SHRA: howto manager. (line 2003)
+* BFD_RELOC_RL78_OP_SUBTRACT: howto manager. (line 2000)
+* BFD_RELOC_RL78_RELAX: howto manager. (line 2012)
+* BFD_RELOC_RL78_SYM: howto manager. (line 1999)
+* BFD_RELOC_RVA: howto manager. (line 104)
+* BFD_RELOC_RX_16_OP: howto manager. (line 2023)
+* BFD_RELOC_RX_16U: howto manager. (line 2027)
+* BFD_RELOC_RX_24_OP: howto manager. (line 2024)
+* BFD_RELOC_RX_24U: howto manager. (line 2028)
+* BFD_RELOC_RX_32_OP: howto manager. (line 2025)
+* BFD_RELOC_RX_8U: howto manager. (line 2026)
+* BFD_RELOC_RX_ABS16: howto manager. (line 2038)
+* BFD_RELOC_RX_ABS16_REV: howto manager. (line 2039)
+* BFD_RELOC_RX_ABS16U: howto manager. (line 2042)
+* BFD_RELOC_RX_ABS16UL: howto manager. (line 2044)
+* BFD_RELOC_RX_ABS16UW: howto manager. (line 2043)
+* BFD_RELOC_RX_ABS32: howto manager. (line 2040)
+* BFD_RELOC_RX_ABS32_REV: howto manager. (line 2041)
+* BFD_RELOC_RX_ABS8: howto manager. (line 2037)
+* BFD_RELOC_RX_DIFF: howto manager. (line 2030)
+* BFD_RELOC_RX_DIR3U_PCREL: howto manager. (line 2029)
+* BFD_RELOC_RX_GPRELB: howto manager. (line 2031)
+* BFD_RELOC_RX_GPRELL: howto manager. (line 2033)
+* BFD_RELOC_RX_GPRELW: howto manager. (line 2032)
+* BFD_RELOC_RX_NEG16: howto manager. (line 2020)
+* BFD_RELOC_RX_NEG24: howto manager. (line 2021)
+* BFD_RELOC_RX_NEG32: howto manager. (line 2022)
+* BFD_RELOC_RX_NEG8: howto manager. (line 2019)
+* BFD_RELOC_RX_OP_NEG: howto manager. (line 2036)
+* BFD_RELOC_RX_OP_SUBTRACT: howto manager. (line 2035)
+* BFD_RELOC_RX_RELAX: howto manager. (line 2045)
+* BFD_RELOC_RX_SYM: howto manager. (line 2034)
+* BFD_RELOC_SCORE16_BRANCH: howto manager. (line 2188)
+* BFD_RELOC_SCORE16_JMP: howto manager. (line 2185)
+* BFD_RELOC_SCORE_BCMP: howto manager. (line 2191)
+* BFD_RELOC_SCORE_BRANCH: howto manager. (line 2176)
+* BFD_RELOC_SCORE_CALL15: howto manager. (line 2196)
+* BFD_RELOC_SCORE_DUMMY2: howto manager. (line 2172)
+* BFD_RELOC_SCORE_DUMMY_HI16: howto manager. (line 2197)
+* BFD_RELOC_SCORE_GOT15: howto manager. (line 2194)
+* BFD_RELOC_SCORE_GOT_LO16: howto manager. (line 2195)
+* BFD_RELOC_SCORE_GPREL15: howto manager. (line 2169)
+* BFD_RELOC_SCORE_IMM30: howto manager. (line 2179)
+* BFD_RELOC_SCORE_IMM32: howto manager. (line 2182)
+* BFD_RELOC_SCORE_JMP: howto manager. (line 2173)
+* BFD_RELOC_SH_ALIGN: howto manager. (line 978)
+* BFD_RELOC_SH_CODE: howto manager. (line 979)
+* BFD_RELOC_SH_COPY: howto manager. (line 984)
+* BFD_RELOC_SH_COPY64: howto manager. (line 1009)
+* BFD_RELOC_SH_COUNT: howto manager. (line 977)
+* BFD_RELOC_SH_DATA: howto manager. (line 980)
+* BFD_RELOC_SH_DISP12: howto manager. (line 960)
+* BFD_RELOC_SH_DISP12BY2: howto manager. (line 961)
+* BFD_RELOC_SH_DISP12BY4: howto manager. (line 962)
+* BFD_RELOC_SH_DISP12BY8: howto manager. (line 963)
+* BFD_RELOC_SH_DISP20: howto manager. (line 964)
+* BFD_RELOC_SH_DISP20BY8: howto manager. (line 965)
+* BFD_RELOC_SH_FUNCDESC: howto manager. (line 1052)
+* BFD_RELOC_SH_GLOB_DAT: howto manager. (line 985)
+* BFD_RELOC_SH_GLOB_DAT64: howto manager. (line 1010)
+* BFD_RELOC_SH_GOT10BY4: howto manager. (line 1013)
+* BFD_RELOC_SH_GOT10BY8: howto manager. (line 1014)
+* BFD_RELOC_SH_GOT20: howto manager. (line 1046)
+* BFD_RELOC_SH_GOT_HI16: howto manager. (line 992)
+* BFD_RELOC_SH_GOT_LOW16: howto manager. (line 989)
+* BFD_RELOC_SH_GOT_MEDHI16: howto manager. (line 991)
+* BFD_RELOC_SH_GOT_MEDLOW16: howto manager. (line 990)
+* BFD_RELOC_SH_GOTFUNCDESC: howto manager. (line 1048)
+* BFD_RELOC_SH_GOTFUNCDESC20: howto manager. (line 1049)
+* BFD_RELOC_SH_GOTOFF20: howto manager. (line 1047)
+* BFD_RELOC_SH_GOTOFF_HI16: howto manager. (line 1004)
+* BFD_RELOC_SH_GOTOFF_LOW16: howto manager. (line 1001)
+* BFD_RELOC_SH_GOTOFF_MEDHI16: howto manager. (line 1003)
+* BFD_RELOC_SH_GOTOFF_MEDLOW16: howto manager. (line 1002)
+* BFD_RELOC_SH_GOTOFFFUNCDESC: howto manager. (line 1050)
+* BFD_RELOC_SH_GOTOFFFUNCDESC20: howto manager. (line 1051)
+* BFD_RELOC_SH_GOTPC: howto manager. (line 988)
+* BFD_RELOC_SH_GOTPC_HI16: howto manager. (line 1008)
+* BFD_RELOC_SH_GOTPC_LOW16: howto manager. (line 1005)
+* BFD_RELOC_SH_GOTPC_MEDHI16: howto manager. (line 1007)
+* BFD_RELOC_SH_GOTPC_MEDLOW16: howto manager. (line 1006)
+* BFD_RELOC_SH_GOTPLT10BY4: howto manager. (line 1015)
+* BFD_RELOC_SH_GOTPLT10BY8: howto manager. (line 1016)
+* BFD_RELOC_SH_GOTPLT32: howto manager. (line 1017)
+* BFD_RELOC_SH_GOTPLT_HI16: howto manager. (line 996)
+* BFD_RELOC_SH_GOTPLT_LOW16: howto manager. (line 993)
+* BFD_RELOC_SH_GOTPLT_MEDHI16: howto manager. (line 995)
+* BFD_RELOC_SH_GOTPLT_MEDLOW16: howto manager. (line 994)
+* BFD_RELOC_SH_IMM3: howto manager. (line 958)
+* BFD_RELOC_SH_IMM3U: howto manager. (line 959)
+* BFD_RELOC_SH_IMM4: howto manager. (line 966)
+* BFD_RELOC_SH_IMM4BY2: howto manager. (line 967)
+* BFD_RELOC_SH_IMM4BY4: howto manager. (line 968)
+* BFD_RELOC_SH_IMM8: howto manager. (line 969)
+* BFD_RELOC_SH_IMM8BY2: howto manager. (line 970)
+* BFD_RELOC_SH_IMM8BY4: howto manager. (line 971)
+* BFD_RELOC_SH_IMM_HI16: howto manager. (line 1035)
+* BFD_RELOC_SH_IMM_HI16_PCREL: howto manager. (line 1036)
+* BFD_RELOC_SH_IMM_LOW16: howto manager. (line 1029)
+* BFD_RELOC_SH_IMM_LOW16_PCREL: howto manager. (line 1030)
+* BFD_RELOC_SH_IMM_MEDHI16: howto manager. (line 1033)
+* BFD_RELOC_SH_IMM_MEDHI16_PCREL: howto manager. (line 1034)
+* BFD_RELOC_SH_IMM_MEDLOW16: howto manager. (line 1031)
+* BFD_RELOC_SH_IMM_MEDLOW16_PCREL: howto manager. (line 1032)
+* BFD_RELOC_SH_IMMS10: howto manager. (line 1023)
+* BFD_RELOC_SH_IMMS10BY2: howto manager. (line 1024)
+* BFD_RELOC_SH_IMMS10BY4: howto manager. (line 1025)
+* BFD_RELOC_SH_IMMS10BY8: howto manager. (line 1026)
+* BFD_RELOC_SH_IMMS16: howto manager. (line 1027)
+* BFD_RELOC_SH_IMMS6: howto manager. (line 1020)
+* BFD_RELOC_SH_IMMS6BY32: howto manager. (line 1021)
+* BFD_RELOC_SH_IMMU16: howto manager. (line 1028)
+* BFD_RELOC_SH_IMMU5: howto manager. (line 1019)
+* BFD_RELOC_SH_IMMU6: howto manager. (line 1022)
+* BFD_RELOC_SH_JMP_SLOT: howto manager. (line 986)
+* BFD_RELOC_SH_JMP_SLOT64: howto manager. (line 1011)
+* BFD_RELOC_SH_LABEL: howto manager. (line 981)
+* BFD_RELOC_SH_LOOP_END: howto manager. (line 983)
+* BFD_RELOC_SH_LOOP_START: howto manager. (line 982)
+* BFD_RELOC_SH_PCDISP12BY2: howto manager. (line 957)
+* BFD_RELOC_SH_PCDISP8BY2: howto manager. (line 956)
+* BFD_RELOC_SH_PCRELIMM8BY2: howto manager. (line 972)
+* BFD_RELOC_SH_PCRELIMM8BY4: howto manager. (line 973)
+* BFD_RELOC_SH_PLT_HI16: howto manager. (line 1000)
+* BFD_RELOC_SH_PLT_LOW16: howto manager. (line 997)
+* BFD_RELOC_SH_PLT_MEDHI16: howto manager. (line 999)
+* BFD_RELOC_SH_PLT_MEDLOW16: howto manager. (line 998)
+* BFD_RELOC_SH_PT_16: howto manager. (line 1037)
+* BFD_RELOC_SH_RELATIVE: howto manager. (line 987)
+* BFD_RELOC_SH_RELATIVE64: howto manager. (line 1012)
+* BFD_RELOC_SH_SHMEDIA_CODE: howto manager. (line 1018)
+* BFD_RELOC_SH_SWITCH16: howto manager. (line 974)
+* BFD_RELOC_SH_SWITCH32: howto manager. (line 975)
+* BFD_RELOC_SH_TLS_DTPMOD32: howto manager. (line 1043)
+* BFD_RELOC_SH_TLS_DTPOFF32: howto manager. (line 1044)
+* BFD_RELOC_SH_TLS_GD_32: howto manager. (line 1038)
+* BFD_RELOC_SH_TLS_IE_32: howto manager. (line 1041)
+* BFD_RELOC_SH_TLS_LD_32: howto manager. (line 1039)
+* BFD_RELOC_SH_TLS_LDO_32: howto manager. (line 1040)
+* BFD_RELOC_SH_TLS_LE_32: howto manager. (line 1042)
+* BFD_RELOC_SH_TLS_TPOFF32: howto manager. (line 1045)
+* BFD_RELOC_SH_USES: howto manager. (line 976)
+* BFD_RELOC_SIZE32: howto manager. (line 74)
+* BFD_RELOC_SIZE64: howto manager. (line 75)
+* BFD_RELOC_SPARC13: howto manager. (line 138)
+* BFD_RELOC_SPARC22: howto manager. (line 137)
+* BFD_RELOC_SPARC_10: howto manager. (line 167)
+* BFD_RELOC_SPARC_11: howto manager. (line 168)
+* BFD_RELOC_SPARC_5: howto manager. (line 180)
+* BFD_RELOC_SPARC_6: howto manager. (line 179)
+* BFD_RELOC_SPARC_64: howto manager. (line 166)
+* BFD_RELOC_SPARC_7: howto manager. (line 178)
+* BFD_RELOC_SPARC_BASE13: howto manager. (line 162)
+* BFD_RELOC_SPARC_BASE22: howto manager. (line 163)
+* BFD_RELOC_SPARC_COPY: howto manager. (line 145)
+* BFD_RELOC_SPARC_DISP64: howto manager. (line 181)
+* BFD_RELOC_SPARC_GLOB_DAT: howto manager. (line 146)
+* BFD_RELOC_SPARC_GOT10: howto manager. (line 139)
+* BFD_RELOC_SPARC_GOT13: howto manager. (line 140)
+* BFD_RELOC_SPARC_GOT22: howto manager. (line 141)
+* BFD_RELOC_SPARC_GOTDATA_HIX22: howto manager. (line 152)
+* BFD_RELOC_SPARC_GOTDATA_LOX10: howto manager. (line 153)
+* BFD_RELOC_SPARC_GOTDATA_OP: howto manager. (line 156)
+* BFD_RELOC_SPARC_GOTDATA_OP_HIX22: howto manager. (line 154)
+* BFD_RELOC_SPARC_GOTDATA_OP_LOX10: howto manager. (line 155)
+* BFD_RELOC_SPARC_H34: howto manager. (line 190)
+* BFD_RELOC_SPARC_H44: howto manager. (line 186)
+* BFD_RELOC_SPARC_HH22: howto manager. (line 170)
+* BFD_RELOC_SPARC_HIX22: howto manager. (line 184)
+* BFD_RELOC_SPARC_HM10: howto manager. (line 171)
+* BFD_RELOC_SPARC_IRELATIVE: howto manager. (line 158)
+* BFD_RELOC_SPARC_JMP_IREL: howto manager. (line 157)
+* BFD_RELOC_SPARC_JMP_SLOT: howto manager. (line 147)
+* BFD_RELOC_SPARC_L44: howto manager. (line 188)
+* BFD_RELOC_SPARC_LM22: howto manager. (line 172)
+* BFD_RELOC_SPARC_LOX10: howto manager. (line 185)
+* BFD_RELOC_SPARC_M44: howto manager. (line 187)
+* BFD_RELOC_SPARC_OLO10: howto manager. (line 169)
+* BFD_RELOC_SPARC_PC10: howto manager. (line 142)
+* BFD_RELOC_SPARC_PC22: howto manager. (line 143)
+* BFD_RELOC_SPARC_PC_HH22: howto manager. (line 173)
+* BFD_RELOC_SPARC_PC_HM10: howto manager. (line 174)
+* BFD_RELOC_SPARC_PC_LM22: howto manager. (line 175)
+* BFD_RELOC_SPARC_PLT32: howto manager. (line 182)
+* BFD_RELOC_SPARC_PLT64: howto manager. (line 183)
+* BFD_RELOC_SPARC_REGISTER: howto manager. (line 189)
+* BFD_RELOC_SPARC_RELATIVE: howto manager. (line 148)
+* BFD_RELOC_SPARC_REV32: howto manager. (line 196)
+* BFD_RELOC_SPARC_SIZE32: howto manager. (line 191)
+* BFD_RELOC_SPARC_SIZE64: howto manager. (line 192)
+* BFD_RELOC_SPARC_TLS_DTPMOD32: howto manager. (line 217)
+* BFD_RELOC_SPARC_TLS_DTPMOD64: howto manager. (line 218)
+* BFD_RELOC_SPARC_TLS_DTPOFF32: howto manager. (line 219)
+* BFD_RELOC_SPARC_TLS_DTPOFF64: howto manager. (line 220)
+* BFD_RELOC_SPARC_TLS_GD_ADD: howto manager. (line 201)
+* BFD_RELOC_SPARC_TLS_GD_CALL: howto manager. (line 202)
+* BFD_RELOC_SPARC_TLS_GD_HI22: howto manager. (line 199)
+* BFD_RELOC_SPARC_TLS_GD_LO10: howto manager. (line 200)
+* BFD_RELOC_SPARC_TLS_IE_ADD: howto manager. (line 214)
+* BFD_RELOC_SPARC_TLS_IE_HI22: howto manager. (line 210)
+* BFD_RELOC_SPARC_TLS_IE_LD: howto manager. (line 212)
+* BFD_RELOC_SPARC_TLS_IE_LDX: howto manager. (line 213)
+* BFD_RELOC_SPARC_TLS_IE_LO10: howto manager. (line 211)
+* BFD_RELOC_SPARC_TLS_LDM_ADD: howto manager. (line 205)
+* BFD_RELOC_SPARC_TLS_LDM_CALL: howto manager. (line 206)
+* BFD_RELOC_SPARC_TLS_LDM_HI22: howto manager. (line 203)
+* BFD_RELOC_SPARC_TLS_LDM_LO10: howto manager. (line 204)
+* BFD_RELOC_SPARC_TLS_LDO_ADD: howto manager. (line 209)
+* BFD_RELOC_SPARC_TLS_LDO_HIX22: howto manager. (line 207)
+* BFD_RELOC_SPARC_TLS_LDO_LOX10: howto manager. (line 208)
+* BFD_RELOC_SPARC_TLS_LE_HIX22: howto manager. (line 215)
+* BFD_RELOC_SPARC_TLS_LE_LOX10: howto manager. (line 216)
+* BFD_RELOC_SPARC_TLS_TPOFF32: howto manager. (line 221)
+* BFD_RELOC_SPARC_TLS_TPOFF64: howto manager. (line 222)
+* BFD_RELOC_SPARC_UA16: howto manager. (line 149)
+* BFD_RELOC_SPARC_UA32: howto manager. (line 150)
+* BFD_RELOC_SPARC_UA64: howto manager. (line 151)
+* BFD_RELOC_SPARC_WDISP10: howto manager. (line 193)
+* BFD_RELOC_SPARC_WDISP16: howto manager. (line 176)
+* BFD_RELOC_SPARC_WDISP19: howto manager. (line 177)
+* BFD_RELOC_SPARC_WDISP22: howto manager. (line 136)
+* BFD_RELOC_SPARC_WPLT30: howto manager. (line 144)
+* BFD_RELOC_SPU_ADD_PIC: howto manager. (line 239)
+* BFD_RELOC_SPU_HI16: howto manager. (line 236)
+* BFD_RELOC_SPU_IMM10: howto manager. (line 227)
+* BFD_RELOC_SPU_IMM10W: howto manager. (line 228)
+* BFD_RELOC_SPU_IMM16: howto manager. (line 229)
+* BFD_RELOC_SPU_IMM16W: howto manager. (line 230)
+* BFD_RELOC_SPU_IMM18: howto manager. (line 231)
+* BFD_RELOC_SPU_IMM7: howto manager. (line 225)
+* BFD_RELOC_SPU_IMM8: howto manager. (line 226)
+* BFD_RELOC_SPU_LO16: howto manager. (line 235)
+* BFD_RELOC_SPU_PCREL16: howto manager. (line 234)
+* BFD_RELOC_SPU_PCREL9a: howto manager. (line 232)
+* BFD_RELOC_SPU_PCREL9b: howto manager. (line 233)
+* BFD_RELOC_SPU_PPU32: howto manager. (line 237)
+* BFD_RELOC_SPU_PPU64: howto manager. (line 238)
+* BFD_RELOC_THUMB_PCREL_BLX: howto manager. (line 805)
+* BFD_RELOC_THUMB_PCREL_BRANCH12: howto manager. (line 819)
+* BFD_RELOC_THUMB_PCREL_BRANCH20: howto manager. (line 820)
+* BFD_RELOC_THUMB_PCREL_BRANCH23: howto manager. (line 821)
+* BFD_RELOC_THUMB_PCREL_BRANCH25: howto manager. (line 822)
+* BFD_RELOC_THUMB_PCREL_BRANCH7: howto manager. (line 817)
+* BFD_RELOC_THUMB_PCREL_BRANCH9: howto manager. (line 818)
+* BFD_RELOC_TIC30_LDP: howto manager. (line 1637)
+* BFD_RELOC_TIC54X_16_OF_23: howto manager. (line 1655)
+* BFD_RELOC_TIC54X_23: howto manager. (line 1652)
+* BFD_RELOC_TIC54X_MS7_OF_23: howto manager. (line 1660)
+* BFD_RELOC_TIC54X_PARTLS7: howto manager. (line 1642)
+* BFD_RELOC_TIC54X_PARTMS9: howto manager. (line 1647)
+* BFD_RELOC_TILEGX_BROFF_X1: howto manager. (line 3388)
+* BFD_RELOC_TILEGX_COPY: howto manager. (line 3384)
+* BFD_RELOC_TILEGX_DEST_IMM8_X1: howto manager. (line 3395)
+* BFD_RELOC_TILEGX_GLOB_DAT: howto manager. (line 3385)
+* BFD_RELOC_TILEGX_HW0: howto manager. (line 3377)
+* BFD_RELOC_TILEGX_HW0_LAST: howto manager. (line 3381)
+* BFD_RELOC_TILEGX_HW1: howto manager. (line 3378)
+* BFD_RELOC_TILEGX_HW1_LAST: howto manager. (line 3382)
+* BFD_RELOC_TILEGX_HW2: howto manager. (line 3379)
+* BFD_RELOC_TILEGX_HW2_LAST: howto manager. (line 3383)
+* BFD_RELOC_TILEGX_HW3: howto manager. (line 3380)
+* BFD_RELOC_TILEGX_IMM16_X0_HW0: howto manager. (line 3404)
+* BFD_RELOC_TILEGX_IMM16_X0_HW0_GOT: howto manager. (line 3432)
+* BFD_RELOC_TILEGX_IMM16_X0_HW0_LAST: howto manager. (line 3412)
+* BFD_RELOC_TILEGX_IMM16_X0_HW0_LAST_GOT: howto manager. (line 3440)
+* BFD_RELOC_TILEGX_IMM16_X0_HW0_LAST_PCREL: howto manager. (line 3426)
+* BFD_RELOC_TILEGX_IMM16_X0_HW0_LAST_PLT_PCREL: howto manager.
+ (line 3460)
+* BFD_RELOC_TILEGX_IMM16_X0_HW0_LAST_TLS_GD: howto manager. (line 3454)
+* BFD_RELOC_TILEGX_IMM16_X0_HW0_LAST_TLS_IE: howto manager. (line 3466)
+* BFD_RELOC_TILEGX_IMM16_X0_HW0_LAST_TLS_LE: howto manager. (line 3450)
+* BFD_RELOC_TILEGX_IMM16_X0_HW0_PCREL: howto manager. (line 3418)
+* BFD_RELOC_TILEGX_IMM16_X0_HW0_PLT_PCREL: howto manager. (line 3434)
+* BFD_RELOC_TILEGX_IMM16_X0_HW0_TLS_GD: howto manager. (line 3446)
+* BFD_RELOC_TILEGX_IMM16_X0_HW0_TLS_IE: howto manager. (line 3458)
+* BFD_RELOC_TILEGX_IMM16_X0_HW0_TLS_LE: howto manager. (line 3448)
+* BFD_RELOC_TILEGX_IMM16_X0_HW1: howto manager. (line 3406)
+* BFD_RELOC_TILEGX_IMM16_X0_HW1_LAST: howto manager. (line 3414)
+* BFD_RELOC_TILEGX_IMM16_X0_HW1_LAST_GOT: howto manager. (line 3442)
+* BFD_RELOC_TILEGX_IMM16_X0_HW1_LAST_PCREL: howto manager. (line 3428)
+* BFD_RELOC_TILEGX_IMM16_X0_HW1_LAST_PLT_PCREL: howto manager.
+ (line 3462)
+* BFD_RELOC_TILEGX_IMM16_X0_HW1_LAST_TLS_GD: howto manager. (line 3456)
+* BFD_RELOC_TILEGX_IMM16_X0_HW1_LAST_TLS_IE: howto manager. (line 3468)
+* BFD_RELOC_TILEGX_IMM16_X0_HW1_LAST_TLS_LE: howto manager. (line 3452)
+* BFD_RELOC_TILEGX_IMM16_X0_HW1_PCREL: howto manager. (line 3420)
+* BFD_RELOC_TILEGX_IMM16_X0_HW1_PLT_PCREL: howto manager. (line 3436)
+* BFD_RELOC_TILEGX_IMM16_X0_HW2: howto manager. (line 3408)
+* BFD_RELOC_TILEGX_IMM16_X0_HW2_LAST: howto manager. (line 3416)
+* BFD_RELOC_TILEGX_IMM16_X0_HW2_LAST_PCREL: howto manager. (line 3430)
+* BFD_RELOC_TILEGX_IMM16_X0_HW2_LAST_PLT_PCREL: howto manager.
+ (line 3464)
+* BFD_RELOC_TILEGX_IMM16_X0_HW2_PCREL: howto manager. (line 3422)
+* BFD_RELOC_TILEGX_IMM16_X0_HW2_PLT_PCREL: howto manager. (line 3438)
+* BFD_RELOC_TILEGX_IMM16_X0_HW3: howto manager. (line 3410)
+* BFD_RELOC_TILEGX_IMM16_X0_HW3_PCREL: howto manager. (line 3424)
+* BFD_RELOC_TILEGX_IMM16_X0_HW3_PLT_PCREL: howto manager. (line 3444)
+* BFD_RELOC_TILEGX_IMM16_X1_HW0: howto manager. (line 3405)
+* BFD_RELOC_TILEGX_IMM16_X1_HW0_GOT: howto manager. (line 3433)
+* BFD_RELOC_TILEGX_IMM16_X1_HW0_LAST: howto manager. (line 3413)
+* BFD_RELOC_TILEGX_IMM16_X1_HW0_LAST_GOT: howto manager. (line 3441)
+* BFD_RELOC_TILEGX_IMM16_X1_HW0_LAST_PCREL: howto manager. (line 3427)
+* BFD_RELOC_TILEGX_IMM16_X1_HW0_LAST_PLT_PCREL: howto manager.
+ (line 3461)
+* BFD_RELOC_TILEGX_IMM16_X1_HW0_LAST_TLS_GD: howto manager. (line 3455)
+* BFD_RELOC_TILEGX_IMM16_X1_HW0_LAST_TLS_IE: howto manager. (line 3467)
+* BFD_RELOC_TILEGX_IMM16_X1_HW0_LAST_TLS_LE: howto manager. (line 3451)
+* BFD_RELOC_TILEGX_IMM16_X1_HW0_PCREL: howto manager. (line 3419)
+* BFD_RELOC_TILEGX_IMM16_X1_HW0_PLT_PCREL: howto manager. (line 3435)
+* BFD_RELOC_TILEGX_IMM16_X1_HW0_TLS_GD: howto manager. (line 3447)
+* BFD_RELOC_TILEGX_IMM16_X1_HW0_TLS_IE: howto manager. (line 3459)
+* BFD_RELOC_TILEGX_IMM16_X1_HW0_TLS_LE: howto manager. (line 3449)
+* BFD_RELOC_TILEGX_IMM16_X1_HW1: howto manager. (line 3407)
+* BFD_RELOC_TILEGX_IMM16_X1_HW1_LAST: howto manager. (line 3415)
+* BFD_RELOC_TILEGX_IMM16_X1_HW1_LAST_GOT: howto manager. (line 3443)
+* BFD_RELOC_TILEGX_IMM16_X1_HW1_LAST_PCREL: howto manager. (line 3429)
+* BFD_RELOC_TILEGX_IMM16_X1_HW1_LAST_PLT_PCREL: howto manager.
+ (line 3463)
+* BFD_RELOC_TILEGX_IMM16_X1_HW1_LAST_TLS_GD: howto manager. (line 3457)
+* BFD_RELOC_TILEGX_IMM16_X1_HW1_LAST_TLS_IE: howto manager. (line 3469)
+* BFD_RELOC_TILEGX_IMM16_X1_HW1_LAST_TLS_LE: howto manager. (line 3453)
+* BFD_RELOC_TILEGX_IMM16_X1_HW1_PCREL: howto manager. (line 3421)
+* BFD_RELOC_TILEGX_IMM16_X1_HW1_PLT_PCREL: howto manager. (line 3437)
+* BFD_RELOC_TILEGX_IMM16_X1_HW2: howto manager. (line 3409)
+* BFD_RELOC_TILEGX_IMM16_X1_HW2_LAST: howto manager. (line 3417)
+* BFD_RELOC_TILEGX_IMM16_X1_HW2_LAST_PCREL: howto manager. (line 3431)
+* BFD_RELOC_TILEGX_IMM16_X1_HW2_LAST_PLT_PCREL: howto manager.
+ (line 3465)
+* BFD_RELOC_TILEGX_IMM16_X1_HW2_PCREL: howto manager. (line 3423)
+* BFD_RELOC_TILEGX_IMM16_X1_HW2_PLT_PCREL: howto manager. (line 3439)
+* BFD_RELOC_TILEGX_IMM16_X1_HW3: howto manager. (line 3411)
+* BFD_RELOC_TILEGX_IMM16_X1_HW3_PCREL: howto manager. (line 3425)
+* BFD_RELOC_TILEGX_IMM16_X1_HW3_PLT_PCREL: howto manager. (line 3445)
+* BFD_RELOC_TILEGX_IMM8_X0: howto manager. (line 3391)
+* BFD_RELOC_TILEGX_IMM8_X0_TLS_ADD: howto manager. (line 3482)
+* BFD_RELOC_TILEGX_IMM8_X0_TLS_GD_ADD: howto manager. (line 3477)
+* BFD_RELOC_TILEGX_IMM8_X1: howto manager. (line 3393)
+* BFD_RELOC_TILEGX_IMM8_X1_TLS_ADD: howto manager. (line 3483)
+* BFD_RELOC_TILEGX_IMM8_X1_TLS_GD_ADD: howto manager. (line 3478)
+* BFD_RELOC_TILEGX_IMM8_Y0: howto manager. (line 3392)
+* BFD_RELOC_TILEGX_IMM8_Y0_TLS_ADD: howto manager. (line 3484)
+* BFD_RELOC_TILEGX_IMM8_Y0_TLS_GD_ADD: howto manager. (line 3479)
+* BFD_RELOC_TILEGX_IMM8_Y1: howto manager. (line 3394)
+* BFD_RELOC_TILEGX_IMM8_Y1_TLS_ADD: howto manager. (line 3485)
+* BFD_RELOC_TILEGX_IMM8_Y1_TLS_GD_ADD: howto manager. (line 3480)
+* BFD_RELOC_TILEGX_JMP_SLOT: howto manager. (line 3386)
+* BFD_RELOC_TILEGX_JUMPOFF_X1: howto manager. (line 3389)
+* BFD_RELOC_TILEGX_JUMPOFF_X1_PLT: howto manager. (line 3390)
+* BFD_RELOC_TILEGX_MF_IMM14_X1: howto manager. (line 3397)
+* BFD_RELOC_TILEGX_MMEND_X0: howto manager. (line 3399)
+* BFD_RELOC_TILEGX_MMSTART_X0: howto manager. (line 3398)
+* BFD_RELOC_TILEGX_MT_IMM14_X1: howto manager. (line 3396)
+* BFD_RELOC_TILEGX_RELATIVE: howto manager. (line 3387)
+* BFD_RELOC_TILEGX_SHAMT_X0: howto manager. (line 3400)
+* BFD_RELOC_TILEGX_SHAMT_X1: howto manager. (line 3401)
+* BFD_RELOC_TILEGX_SHAMT_Y0: howto manager. (line 3402)
+* BFD_RELOC_TILEGX_SHAMT_Y1: howto manager. (line 3403)
+* BFD_RELOC_TILEGX_TLS_DTPMOD32: howto manager. (line 3473)
+* BFD_RELOC_TILEGX_TLS_DTPMOD64: howto manager. (line 3470)
+* BFD_RELOC_TILEGX_TLS_DTPOFF32: howto manager. (line 3474)
+* BFD_RELOC_TILEGX_TLS_DTPOFF64: howto manager. (line 3471)
+* BFD_RELOC_TILEGX_TLS_GD_CALL: howto manager. (line 3476)
+* BFD_RELOC_TILEGX_TLS_IE_LOAD: howto manager. (line 3481)
+* BFD_RELOC_TILEGX_TLS_TPOFF32: howto manager. (line 3475)
+* BFD_RELOC_TILEGX_TLS_TPOFF64: howto manager. (line 3472)
+* BFD_RELOC_TILEPRO_BROFF_X1: howto manager. (line 3300)
+* BFD_RELOC_TILEPRO_COPY: howto manager. (line 3296)
+* BFD_RELOC_TILEPRO_DEST_IMM8_X1: howto manager. (line 3307)
+* BFD_RELOC_TILEPRO_GLOB_DAT: howto manager. (line 3297)
+* BFD_RELOC_TILEPRO_IMM16_X0: howto manager. (line 3310)
+* BFD_RELOC_TILEPRO_IMM16_X0_GOT: howto manager. (line 3326)
+* BFD_RELOC_TILEPRO_IMM16_X0_GOT_HA: howto manager. (line 3332)
+* BFD_RELOC_TILEPRO_IMM16_X0_GOT_HI: howto manager. (line 3330)
+* BFD_RELOC_TILEPRO_IMM16_X0_GOT_LO: howto manager. (line 3328)
+* BFD_RELOC_TILEPRO_IMM16_X0_HA: howto manager. (line 3316)
+* BFD_RELOC_TILEPRO_IMM16_X0_HA_PCREL: howto manager. (line 3324)
+* BFD_RELOC_TILEPRO_IMM16_X0_HI: howto manager. (line 3314)
+* BFD_RELOC_TILEPRO_IMM16_X0_HI_PCREL: howto manager. (line 3322)
+* BFD_RELOC_TILEPRO_IMM16_X0_LO: howto manager. (line 3312)
+* BFD_RELOC_TILEPRO_IMM16_X0_LO_PCREL: howto manager. (line 3320)
+* BFD_RELOC_TILEPRO_IMM16_X0_PCREL: howto manager. (line 3318)
+* BFD_RELOC_TILEPRO_IMM16_X0_TLS_GD: howto manager. (line 3348)
+* BFD_RELOC_TILEPRO_IMM16_X0_TLS_GD_HA: howto manager. (line 3354)
+* BFD_RELOC_TILEPRO_IMM16_X0_TLS_GD_HI: howto manager. (line 3352)
+* BFD_RELOC_TILEPRO_IMM16_X0_TLS_GD_LO: howto manager. (line 3350)
+* BFD_RELOC_TILEPRO_IMM16_X0_TLS_IE: howto manager. (line 3356)
+* BFD_RELOC_TILEPRO_IMM16_X0_TLS_IE_HA: howto manager. (line 3362)
+* BFD_RELOC_TILEPRO_IMM16_X0_TLS_IE_HI: howto manager. (line 3360)
+* BFD_RELOC_TILEPRO_IMM16_X0_TLS_IE_LO: howto manager. (line 3358)
+* BFD_RELOC_TILEPRO_IMM16_X0_TLS_LE: howto manager. (line 3367)
+* BFD_RELOC_TILEPRO_IMM16_X0_TLS_LE_HA: howto manager. (line 3373)
+* BFD_RELOC_TILEPRO_IMM16_X0_TLS_LE_HI: howto manager. (line 3371)
+* BFD_RELOC_TILEPRO_IMM16_X0_TLS_LE_LO: howto manager. (line 3369)
+* BFD_RELOC_TILEPRO_IMM16_X1: howto manager. (line 3311)
+* BFD_RELOC_TILEPRO_IMM16_X1_GOT: howto manager. (line 3327)
+* BFD_RELOC_TILEPRO_IMM16_X1_GOT_HA: howto manager. (line 3333)
+* BFD_RELOC_TILEPRO_IMM16_X1_GOT_HI: howto manager. (line 3331)
+* BFD_RELOC_TILEPRO_IMM16_X1_GOT_LO: howto manager. (line 3329)
+* BFD_RELOC_TILEPRO_IMM16_X1_HA: howto manager. (line 3317)
+* BFD_RELOC_TILEPRO_IMM16_X1_HA_PCREL: howto manager. (line 3325)
+* BFD_RELOC_TILEPRO_IMM16_X1_HI: howto manager. (line 3315)
+* BFD_RELOC_TILEPRO_IMM16_X1_HI_PCREL: howto manager. (line 3323)
+* BFD_RELOC_TILEPRO_IMM16_X1_LO: howto manager. (line 3313)
+* BFD_RELOC_TILEPRO_IMM16_X1_LO_PCREL: howto manager. (line 3321)
+* BFD_RELOC_TILEPRO_IMM16_X1_PCREL: howto manager. (line 3319)
+* BFD_RELOC_TILEPRO_IMM16_X1_TLS_GD: howto manager. (line 3349)
+* BFD_RELOC_TILEPRO_IMM16_X1_TLS_GD_HA: howto manager. (line 3355)
+* BFD_RELOC_TILEPRO_IMM16_X1_TLS_GD_HI: howto manager. (line 3353)
+* BFD_RELOC_TILEPRO_IMM16_X1_TLS_GD_LO: howto manager. (line 3351)
+* BFD_RELOC_TILEPRO_IMM16_X1_TLS_IE: howto manager. (line 3357)
+* BFD_RELOC_TILEPRO_IMM16_X1_TLS_IE_HA: howto manager. (line 3363)
+* BFD_RELOC_TILEPRO_IMM16_X1_TLS_IE_HI: howto manager. (line 3361)
+* BFD_RELOC_TILEPRO_IMM16_X1_TLS_IE_LO: howto manager. (line 3359)
+* BFD_RELOC_TILEPRO_IMM16_X1_TLS_LE: howto manager. (line 3368)
+* BFD_RELOC_TILEPRO_IMM16_X1_TLS_LE_HA: howto manager. (line 3374)
+* BFD_RELOC_TILEPRO_IMM16_X1_TLS_LE_HI: howto manager. (line 3372)
+* BFD_RELOC_TILEPRO_IMM16_X1_TLS_LE_LO: howto manager. (line 3370)
+* BFD_RELOC_TILEPRO_IMM8_X0: howto manager. (line 3303)
+* BFD_RELOC_TILEPRO_IMM8_X0_TLS_GD_ADD: howto manager. (line 3343)
+* BFD_RELOC_TILEPRO_IMM8_X1: howto manager. (line 3305)
+* BFD_RELOC_TILEPRO_IMM8_X1_TLS_GD_ADD: howto manager. (line 3344)
+* BFD_RELOC_TILEPRO_IMM8_Y0: howto manager. (line 3304)
+* BFD_RELOC_TILEPRO_IMM8_Y0_TLS_GD_ADD: howto manager. (line 3345)
+* BFD_RELOC_TILEPRO_IMM8_Y1: howto manager. (line 3306)
+* BFD_RELOC_TILEPRO_IMM8_Y1_TLS_GD_ADD: howto manager. (line 3346)
+* BFD_RELOC_TILEPRO_JMP_SLOT: howto manager. (line 3298)
+* BFD_RELOC_TILEPRO_JOFFLONG_X1: howto manager. (line 3301)
+* BFD_RELOC_TILEPRO_JOFFLONG_X1_PLT: howto manager. (line 3302)
+* BFD_RELOC_TILEPRO_MF_IMM15_X1: howto manager. (line 3309)
+* BFD_RELOC_TILEPRO_MMEND_X0: howto manager. (line 3335)
+* BFD_RELOC_TILEPRO_MMEND_X1: howto manager. (line 3337)
+* BFD_RELOC_TILEPRO_MMSTART_X0: howto manager. (line 3334)
+* BFD_RELOC_TILEPRO_MMSTART_X1: howto manager. (line 3336)
+* BFD_RELOC_TILEPRO_MT_IMM15_X1: howto manager. (line 3308)
+* BFD_RELOC_TILEPRO_RELATIVE: howto manager. (line 3299)
+* BFD_RELOC_TILEPRO_SHAMT_X0: howto manager. (line 3338)
+* BFD_RELOC_TILEPRO_SHAMT_X1: howto manager. (line 3339)
+* BFD_RELOC_TILEPRO_SHAMT_Y0: howto manager. (line 3340)
+* BFD_RELOC_TILEPRO_SHAMT_Y1: howto manager. (line 3341)
+* BFD_RELOC_TILEPRO_TLS_DTPMOD32: howto manager. (line 3364)
+* BFD_RELOC_TILEPRO_TLS_DTPOFF32: howto manager. (line 3365)
+* BFD_RELOC_TILEPRO_TLS_GD_CALL: howto manager. (line 3342)
+* BFD_RELOC_TILEPRO_TLS_IE_LOAD: howto manager. (line 3347)
+* BFD_RELOC_TILEPRO_TLS_TPOFF32: howto manager. (line 3366)
+* bfd_reloc_type_lookup: howto manager. (line 3511)
+* BFD_RELOC_V850_16_GOT: howto manager. (line 1601)
+* BFD_RELOC_V850_16_GOTOFF: howto manager. (line 1625)
+* BFD_RELOC_V850_16_PCREL: howto manager. (line 1571)
+* BFD_RELOC_V850_16_S1: howto manager. (line 1589)
+* BFD_RELOC_V850_16_SPLIT_OFFSET: howto manager. (line 1586)
+* BFD_RELOC_V850_17_PCREL: howto manager. (line 1574)
+* BFD_RELOC_V850_22_PCREL: howto manager. (line 1506)
+* BFD_RELOC_V850_22_PLT_PCREL: howto manager. (line 1607)
+* BFD_RELOC_V850_23: howto manager. (line 1577)
+* BFD_RELOC_V850_32_ABS: howto manager. (line 1583)
+* BFD_RELOC_V850_32_GOT: howto manager. (line 1604)
+* BFD_RELOC_V850_32_GOTOFF: howto manager. (line 1628)
+* BFD_RELOC_V850_32_GOTPCREL: howto manager. (line 1598)
+* BFD_RELOC_V850_32_PCREL: howto manager. (line 1580)
+* BFD_RELOC_V850_32_PLT_PCREL: howto manager. (line 1610)
+* BFD_RELOC_V850_9_PCREL: howto manager. (line 1503)
+* BFD_RELOC_V850_ALIGN: howto manager. (line 1564)
+* BFD_RELOC_V850_CALLT_15_16_OFFSET: howto manager. (line 1595)
+* BFD_RELOC_V850_CALLT_16_16_OFFSET: howto manager. (line 1555)
+* BFD_RELOC_V850_CALLT_6_7_OFFSET: howto manager. (line 1552)
+* BFD_RELOC_V850_CODE: howto manager. (line 1631)
+* BFD_RELOC_V850_COPY: howto manager. (line 1613)
+* BFD_RELOC_V850_DATA: howto manager. (line 1634)
+* BFD_RELOC_V850_GLOB_DAT: howto manager. (line 1616)
+* BFD_RELOC_V850_JMP_SLOT: howto manager. (line 1619)
+* BFD_RELOC_V850_LO16_S1: howto manager. (line 1592)
+* BFD_RELOC_V850_LO16_SPLIT_OFFSET: howto manager. (line 1567)
+* BFD_RELOC_V850_LONGCALL: howto manager. (line 1558)
+* BFD_RELOC_V850_LONGJUMP: howto manager. (line 1561)
+* BFD_RELOC_V850_RELATIVE: howto manager. (line 1622)
+* BFD_RELOC_V850_SDA_15_16_OFFSET: howto manager. (line 1512)
+* BFD_RELOC_V850_SDA_16_16_OFFSET: howto manager. (line 1509)
+* BFD_RELOC_V850_SDA_16_16_SPLIT_OFFSET: howto manager. (line 1544)
+* BFD_RELOC_V850_TDA_16_16_OFFSET: howto manager. (line 1534)
+* BFD_RELOC_V850_TDA_4_4_OFFSET: howto manager. (line 1541)
+* BFD_RELOC_V850_TDA_4_5_OFFSET: howto manager. (line 1537)
+* BFD_RELOC_V850_TDA_6_8_OFFSET: howto manager. (line 1523)
+* BFD_RELOC_V850_TDA_7_7_OFFSET: howto manager. (line 1531)
+* BFD_RELOC_V850_TDA_7_8_OFFSET: howto manager. (line 1527)
+* BFD_RELOC_V850_ZDA_15_16_OFFSET: howto manager. (line 1519)
+* BFD_RELOC_V850_ZDA_16_16_OFFSET: howto manager. (line 1516)
+* BFD_RELOC_V850_ZDA_16_16_SPLIT_OFFSET: howto manager. (line 1548)
+* BFD_RELOC_VAX_GLOB_DAT: howto manager. (line 2676)
+* BFD_RELOC_VAX_JMP_SLOT: howto manager. (line 2677)
+* BFD_RELOC_VAX_RELATIVE: howto manager. (line 2678)
+* BFD_RELOC_VPE4KMATH_DATA: howto manager. (line 2230)
+* BFD_RELOC_VPE4KMATH_INSN: howto manager. (line 2231)
+* BFD_RELOC_VTABLE_ENTRY: howto manager. (line 2235)
+* BFD_RELOC_VTABLE_INHERIT: howto manager. (line 2234)
+* BFD_RELOC_X86_64_32S: howto manager. (line 614)
+* BFD_RELOC_X86_64_COPY: howto manager. (line 609)
+* BFD_RELOC_X86_64_DTPMOD64: howto manager. (line 615)
+* BFD_RELOC_X86_64_DTPOFF32: howto manager. (line 620)
+* BFD_RELOC_X86_64_DTPOFF64: howto manager. (line 616)
+* BFD_RELOC_X86_64_GLOB_DAT: howto manager. (line 610)
+* BFD_RELOC_X86_64_GOT32: howto manager. (line 607)
+* BFD_RELOC_X86_64_GOT64: howto manager. (line 625)
+* BFD_RELOC_X86_64_GOTOFF64: howto manager. (line 623)
+* BFD_RELOC_X86_64_GOTPC32: howto manager. (line 624)
+* BFD_RELOC_X86_64_GOTPC32_TLSDESC: howto manager. (line 630)
+* BFD_RELOC_X86_64_GOTPC64: howto manager. (line 627)
+* BFD_RELOC_X86_64_GOTPCREL: howto manager. (line 613)
+* BFD_RELOC_X86_64_GOTPCREL64: howto manager. (line 626)
+* BFD_RELOC_X86_64_GOTPLT64: howto manager. (line 628)
+* BFD_RELOC_X86_64_GOTTPOFF: howto manager. (line 621)
+* BFD_RELOC_X86_64_IRELATIVE: howto manager. (line 633)
+* BFD_RELOC_X86_64_JUMP_SLOT: howto manager. (line 611)
+* BFD_RELOC_X86_64_PC32_BND: howto manager. (line 634)
+* BFD_RELOC_X86_64_PLT32: howto manager. (line 608)
+* BFD_RELOC_X86_64_PLT32_BND: howto manager. (line 635)
+* BFD_RELOC_X86_64_PLTOFF64: howto manager. (line 629)
+* BFD_RELOC_X86_64_RELATIVE: howto manager. (line 612)
+* BFD_RELOC_X86_64_TLSDESC: howto manager. (line 632)
+* BFD_RELOC_X86_64_TLSDESC_CALL: howto manager. (line 631)
+* BFD_RELOC_X86_64_TLSGD: howto manager. (line 618)
+* BFD_RELOC_X86_64_TLSLD: howto manager. (line 619)
+* BFD_RELOC_X86_64_TPOFF32: howto manager. (line 622)
+* BFD_RELOC_X86_64_TPOFF64: howto manager. (line 617)
+* BFD_RELOC_XC16X_PAG: howto manager. (line 2670)
+* BFD_RELOC_XC16X_POF: howto manager. (line 2671)
+* BFD_RELOC_XC16X_SEG: howto manager. (line 2672)
+* BFD_RELOC_XC16X_SOF: howto manager. (line 2673)
+* BFD_RELOC_XGATE_24: howto manager. (line 2393)
+* BFD_RELOC_XGATE_GPAGE: howto manager. (line 2390)
+* BFD_RELOC_XGATE_IMM3: howto manager. (line 2410)
+* BFD_RELOC_XGATE_IMM4: howto manager. (line 2413)
+* BFD_RELOC_XGATE_IMM5: howto manager. (line 2416)
+* BFD_RELOC_XGATE_IMM8_HI: howto manager. (line 2406)
+* BFD_RELOC_XGATE_IMM8_LO: howto manager. (line 2402)
+* BFD_RELOC_XGATE_LO16: howto manager. (line 2386)
+* BFD_RELOC_XGATE_PCREL_10: howto manager. (line 2399)
+* BFD_RELOC_XGATE_PCREL_9: howto manager. (line 2396)
+* BFD_RELOC_XGATE_RL_GROUP: howto manager. (line 2381)
+* BFD_RELOC_XGATE_RL_JUMP: howto manager. (line 2377)
+* BFD_RELOC_XSTORMY16_12: howto manager. (line 2662)
+* BFD_RELOC_XSTORMY16_24: howto manager. (line 2663)
+* BFD_RELOC_XSTORMY16_FPTR16: howto manager. (line 2664)
+* BFD_RELOC_XSTORMY16_REL_12: howto manager. (line 2661)
+* BFD_RELOC_XTENSA_ASM_EXPAND: howto manager. (line 2838)
+* BFD_RELOC_XTENSA_ASM_SIMPLIFY: howto manager. (line 2843)
+* BFD_RELOC_XTENSA_DIFF16: howto manager. (line 2785)
+* BFD_RELOC_XTENSA_DIFF32: howto manager. (line 2786)
+* BFD_RELOC_XTENSA_DIFF8: howto manager. (line 2784)
+* BFD_RELOC_XTENSA_GLOB_DAT: howto manager. (line 2774)
+* BFD_RELOC_XTENSA_JMP_SLOT: howto manager. (line 2775)
+* BFD_RELOC_XTENSA_OP0: howto manager. (line 2832)
+* BFD_RELOC_XTENSA_OP1: howto manager. (line 2833)
+* BFD_RELOC_XTENSA_OP2: howto manager. (line 2834)
+* BFD_RELOC_XTENSA_PLT: howto manager. (line 2779)
+* BFD_RELOC_XTENSA_RELATIVE: howto manager. (line 2776)
+* BFD_RELOC_XTENSA_RTLD: howto manager. (line 2769)
+* BFD_RELOC_XTENSA_SLOT0_ALT: howto manager. (line 2814)
+* BFD_RELOC_XTENSA_SLOT0_OP: howto manager. (line 2794)
+* BFD_RELOC_XTENSA_SLOT10_ALT: howto manager. (line 2824)
+* BFD_RELOC_XTENSA_SLOT10_OP: howto manager. (line 2804)
+* BFD_RELOC_XTENSA_SLOT11_ALT: howto manager. (line 2825)
+* BFD_RELOC_XTENSA_SLOT11_OP: howto manager. (line 2805)
+* BFD_RELOC_XTENSA_SLOT12_ALT: howto manager. (line 2826)
+* BFD_RELOC_XTENSA_SLOT12_OP: howto manager. (line 2806)
+* BFD_RELOC_XTENSA_SLOT13_ALT: howto manager. (line 2827)
+* BFD_RELOC_XTENSA_SLOT13_OP: howto manager. (line 2807)
+* BFD_RELOC_XTENSA_SLOT14_ALT: howto manager. (line 2828)
+* BFD_RELOC_XTENSA_SLOT14_OP: howto manager. (line 2808)
+* BFD_RELOC_XTENSA_SLOT1_ALT: howto manager. (line 2815)
+* BFD_RELOC_XTENSA_SLOT1_OP: howto manager. (line 2795)
+* BFD_RELOC_XTENSA_SLOT2_ALT: howto manager. (line 2816)
+* BFD_RELOC_XTENSA_SLOT2_OP: howto manager. (line 2796)
+* BFD_RELOC_XTENSA_SLOT3_ALT: howto manager. (line 2817)
+* BFD_RELOC_XTENSA_SLOT3_OP: howto manager. (line 2797)
+* BFD_RELOC_XTENSA_SLOT4_ALT: howto manager. (line 2818)
+* BFD_RELOC_XTENSA_SLOT4_OP: howto manager. (line 2798)
+* BFD_RELOC_XTENSA_SLOT5_ALT: howto manager. (line 2819)
+* BFD_RELOC_XTENSA_SLOT5_OP: howto manager. (line 2799)
+* BFD_RELOC_XTENSA_SLOT6_ALT: howto manager. (line 2820)
+* BFD_RELOC_XTENSA_SLOT6_OP: howto manager. (line 2800)
+* BFD_RELOC_XTENSA_SLOT7_ALT: howto manager. (line 2821)
+* BFD_RELOC_XTENSA_SLOT7_OP: howto manager. (line 2801)
+* BFD_RELOC_XTENSA_SLOT8_ALT: howto manager. (line 2822)
+* BFD_RELOC_XTENSA_SLOT8_OP: howto manager. (line 2802)
+* BFD_RELOC_XTENSA_SLOT9_ALT: howto manager. (line 2823)
+* BFD_RELOC_XTENSA_SLOT9_OP: howto manager. (line 2803)
+* BFD_RELOC_XTENSA_TLS_ARG: howto manager. (line 2853)
+* BFD_RELOC_XTENSA_TLS_CALL: howto manager. (line 2854)
+* BFD_RELOC_XTENSA_TLS_DTPOFF: howto manager. (line 2850)
+* BFD_RELOC_XTENSA_TLS_FUNC: howto manager. (line 2852)
+* BFD_RELOC_XTENSA_TLS_TPOFF: howto manager. (line 2851)
+* BFD_RELOC_XTENSA_TLSDESC_ARG: howto manager. (line 2849)
+* BFD_RELOC_XTENSA_TLSDESC_FN: howto manager. (line 2848)
+* BFD_RELOC_Z80_DISP8: howto manager. (line 2857)
+* BFD_RELOC_Z8K_CALLR: howto manager. (line 2863)
+* BFD_RELOC_Z8K_DISP7: howto manager. (line 2860)
+* BFD_RELOC_Z8K_IMM4L: howto manager. (line 2866)
+* bfd_rename_section: section prototypes. (line 169)
+* bfd_scan_arch: Architectures. (line 514)
+* bfd_scan_vma: Miscellaneous. (line 126)
+* bfd_seach_for_target: bfd_target. (line 517)
+* bfd_section_already_linked: Writing the symbol table.
+ (line 55)
+* bfd_section_list_clear: section prototypes. (line 8)
+* bfd_sections_find_if: section prototypes. (line 199)
+* bfd_set_arch_info: Architectures. (line 555)
+* bfd_set_archive_head: Archives. (line 75)
+* bfd_set_assert_handler: Error reporting. (line 141)
+* bfd_set_default_target: bfd_target. (line 456)
+* bfd_set_error: Error reporting. (line 57)
+* bfd_set_error_handler: Error reporting. (line 99)
+* bfd_set_error_program_name: Error reporting. (line 108)
+* bfd_set_file_flags: Miscellaneous. (line 44)
+* bfd_set_format: Formats. (line 68)
+* bfd_set_gp_size: Miscellaneous. (line 116)
+* bfd_set_private_flags: Miscellaneous. (line 193)
+* bfd_set_reloc: Miscellaneous. (line 34)
+* bfd_set_section_contents: section prototypes. (line 230)
+* bfd_set_section_flags: section prototypes. (line 154)
+* bfd_set_section_size: section prototypes. (line 216)
+* bfd_set_start_address: Miscellaneous. (line 95)
+* bfd_set_symtab: symbol handling functions.
+ (line 60)
+* bfd_symbol_info: symbol handling functions.
+ (line 130)
+* bfd_target_list: bfd_target. (line 508)
+* bfd_write_bigendian_4byte_int: Internal. (line 13)
+* bfd_zalloc: Opening and Closing.
+ (line 257)
+* bfd_zalloc2: Opening and Closing.
+ (line 266)
+* coff_symbol_type: coff. (line 245)
+* core_file_matches_executable_p: Core Files. (line 39)
+* find_separate_debug_file: Opening and Closing.
+ (line 332)
+* generic_core_file_matches_executable_p: Core Files. (line 49)
+* Hash tables: Hash Tables. (line 6)
+* internal object-file format: Canonical format. (line 11)
+* Linker: Linker Functions. (line 6)
+* Other functions: Miscellaneous. (line 208)
+* separate_alt_debug_file_exists: Opening and Closing.
+ (line 323)
+* separate_debug_file_exists: Opening and Closing.
+ (line 314)
+* struct bfd_iovec: Miscellaneous. (line 369)
+* target vector (_bfd_final_link): Performing the Final Link.
+ (line 6)
+* target vector (_bfd_link_add_symbols): Adding Symbols to the Hash Table.
+ (line 6)
+* target vector (_bfd_link_hash_table_create): Creating a Linker Hash Table.
+ (line 6)
+* The HOWTO Macro: typedef arelent. (line 288)
+* what is it?: Overview. (line 6)
+
+
+
+Tag Table:
+Node: Top1058
+Node: Overview1397
+Node: History2448
+Node: How It Works3394
+Node: What BFD Version 2 Can Do4937
+Node: BFD information loss6252
+Node: Canonical format8784
+Node: BFD front end13156
+Node: typedef bfd13580
+Node: Error reporting24586
+Node: Miscellaneous29453
+Node: Memory Usage46603
+Node: Initialization47831
+Node: Sections48290
+Node: Section Input48773
+Node: Section Output50138
+Node: typedef asection52624
+Node: section prototypes78807
+Node: Symbols89064
+Node: Reading Symbols90659
+Node: Writing Symbols91766
+Node: Mini Symbols93507
+Node: typedef asymbol94481
+Node: symbol handling functions100540
+Node: Archives105882
+Node: Formats109911
+Node: Relocations112859
+Node: typedef arelent113586
+Node: howto manager129222
+Node: Core Files244197
+Node: Targets246235
+Node: bfd_target248205
+Node: Architectures271043
+Node: Opening and Closing298508
+Node: Internal312830
+Node: File Caching319175
+Node: Linker Functions321089
+Node: Creating a Linker Hash Table322762
+Node: Adding Symbols to the Hash Table324500
+Node: Differing file formats325400
+Node: Adding symbols from an object file327125
+Node: Adding symbols from an archive329276
+Node: Performing the Final Link331622
+Node: Information provided by the linker332864
+Node: Relocating the section contents334018
+Node: Writing the symbol table335769
+Node: Hash Tables340153
+Node: Creating and Freeing a Hash Table341351
+Node: Looking Up or Entering a String342601
+Node: Traversing a Hash Table343854
+Node: Deriving a New Hash Table Type344643
+Node: Define the Derived Structures345709
+Node: Write the Derived Creation Routine346790
+Node: Write Other Derived Routines349414
+Node: BFD back ends350729
+Node: What to Put Where350999
+Node: aout351179
+Node: coff357517
+Node: elf386166
+Node: mmo386567
+Node: File layout387440
+Node: Symbol-table393367
+Node: mmo section mapping397131
+Node: GNU Free Documentation License400783
+Node: BFD Index425866
+
+End Tag Table
diff --git a/bfd/doc/bfd.texinfo b/bfd/doc/bfd.texinfo
new file mode 100644
index 0000000..040b8d8
--- /dev/null
+++ b/bfd/doc/bfd.texinfo
@@ -0,0 +1,341 @@
+\input texinfo.tex
+@setfilename bfd.info
+@c Copyright (C) 1988-2014 Free Software Foundation, Inc.
+@c
+@synindex fn cp
+
+@ifnottex
+@dircategory Software development
+@direntry
+* Bfd: (bfd). The Binary File Descriptor library.
+@end direntry
+@end ifnottex
+
+@copying
+This file documents the BFD library.
+
+Copyright @copyright{} 1991-2014 Free Software Foundation, Inc.
+
+Permission is granted to copy, distribute and/or modify this document
+under the terms of the GNU Free Documentation License, Version 1.3 or
+any later version published by the Free Software Foundation; with the
+Invariant Sections being ``GNU General Public License'' and ``Funding
+Free Software'', the Front-Cover texts being (a) (see below), and with
+the Back-Cover Texts being (b) (see below). A copy of the license is
+included in the section entitled ``GNU Free Documentation License''.
+
+(a) The FSF's Front-Cover Text is:
+
+ A GNU Manual
+
+(b) The FSF's Back-Cover Text is:
+
+ You have freedom to copy and modify this GNU Manual, like GNU
+ software. Copies published by the Free Software Foundation raise
+ funds for GNU development.
+@end copying
+@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 % Since no product is stable before version 3.0 :-)
+@subtitle Original Document Created: April 1991
+@author {Steve Chamberlain}
+@author {Cygnus Support}
+@page
+
+@tex
+\def\$#1${{#1}} % Kluge: collect RCS revision info without $...$
+\xdef\manvers{1.5} % For use in headers, footers too
+{\parskip=0pt
+\hfill Free Software Foundation\par
+\hfill sac\@www.gnu.org\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-2014 Free Software Foundation, Inc.
+
+ Permission is granted to copy, distribute and/or modify this document
+ under the terms of the GNU Free Documentation License, Version 1.3
+ or any later version published by the Free Software Foundation;
+ with no Invariant Sections, with no Front-Cover Texts, and with no
+ Back-Cover Texts. A copy of the license is included in the
+ section entitled ``GNU Free Documentation License''.
+
+@end titlepage
+@end iftex
+@contents
+
+@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
+* GNU Free Documentation License:: GNU Free Documentation License
+* BFD Index:: BFD 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 successfully 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}.
+
+@example
+@c @cartouche
+#include "bfd.h"
+
+unsigned int number_of_sections (abfd)
+bfd *abfd;
+@{
+ return bfd_count_sections (abfd);
+@}
+@c @end cartouche
+@end example
+
+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
+
+@menu
+* typedef bfd::
+* Error reporting::
+* Miscellaneous::
+* Memory Usage::
+* Initialization::
+* Sections::
+* Symbols::
+* Archives::
+* Formats::
+* Relocations::
+* Core Files::
+* Targets::
+* Architectures::
+* Opening and Closing::
+* Internal::
+* File Caching::
+* Linker Functions::
+* Hash Tables::
+@end menu
+
+@include bfdt.texi
+@include bfdio.texi
+
+@node Memory Usage, Initialization, Miscellaneous, 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, GNU Free Documentation License, BFD front end, Top
+@chapter BFD back ends
+@menu
+* What to Put Where::
+* aout :: a.out backends
+* coff :: coff backends
+* elf :: elf backends
+* mmo :: mmo backend
+@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
+@section What to Put Where
+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, mmo, coff, BFD back ends
+@include elf.texi
+@c Leave this out until the file has some actual contents...
+@c @include elfcode.texi
+
+@node mmo, , elf, BFD back ends
+@include mmo.texi
+
+@node GNU Free Documentation License, BFD Index, BFD back ends, Top
+@include fdl.texi
+
+@node BFD Index, , GNU Free Documentation License, Top
+@unnumbered BFD 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
+
+@bye
diff --git a/bfd/doc/bfdint.texi b/bfd/doc/bfdint.texi
new file mode 100644
index 0000000..5e335c8
--- /dev/null
+++ b/bfd/doc/bfdint.texi
@@ -0,0 +1,1898 @@
+\input texinfo
+@c Copyright (C) 1988-2014 Free Software Foundation, Inc.
+@setfilename bfdint.info
+
+@settitle BFD Internals
+@iftex
+@titlepage
+@title{BFD Internals}
+@author{Ian Lance Taylor}
+@author{Cygnus Solutions}
+@page
+@end iftex
+
+@copying
+This file documents the internals of the BFD library.
+
+Copyright @copyright{} 1988-2014 Free Software Foundation, Inc.
+Contributed by Cygnus Support.
+
+Permission is granted to copy, distribute and/or modify this document
+under the terms of the GNU Free Documentation License, Version 1.1 or
+any later version published by the Free Software Foundation; with the
+Invariant Sections being ``GNU General Public License'' and ``Funding
+Free Software'', the Front-Cover texts being (a) (see below), and with
+the Back-Cover Texts being (b) (see below). A copy of the license is
+included in the section entitled ``GNU Free Documentation License''.
+
+(a) The FSF's Front-Cover Text is:
+
+ A GNU Manual
+
+(b) The FSF's Back-Cover Text is:
+
+ You have freedom to copy and modify this GNU Manual, like GNU
+ software. Copies published by the Free Software Foundation raise
+ funds for GNU development.
+@end copying
+
+@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.
+
+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 symbols 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 @samp{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_verilog_flavour
+Verilog memory hex dump format.
+@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.
+@item bfd_target_mmo_flavour
+Donald Knuth's MMIXware object format.
+@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 function 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_bound}, 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_bread}. 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_bwrite}.
+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 _canonicalize_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 relocatable 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
+BFD. 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 git 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 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 relocatable 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 relocatable link, and after a final
+link. Make sure you clearly understand the operations the linker must
+perform during a relocatable 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
+relocatable 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 relocatable 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 relocatable link, whether the
+symbol is defined or undefined in the relocatable output. For both the
+final and relocatable 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 relocatable output in a different object
+file format is impossible in the general case, so you generally don't
+have to worry about that. The GNU linker makes sure to stop that from
+happening when an input file in a different format has relocations.
+
+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 relocatable 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.
+Relocatable 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}. 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.ac}. 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 Caldera; if you want to get a magic
+number for a particular processor, try sending a note to
+@email{registry@@caldera.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 relocatable 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 relocatable 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 identify a
+relocation to a name describing that relocation.
+
+While not a BFD component, you probably also want to make the binutils
+program @samp{readelf} parse your ELF objects. For this, you need to add
+code for @code{EM_@var{cpu}} as appropriate in @file{binutils/readelf.c}.
+
+@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
+relocatable 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.
+
+@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 executable
+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/bfdio.texi b/bfd/doc/bfdio.texi
new file mode 100644
index 0000000..ff8275f
--- /dev/null
+++ b/bfd/doc/bfdio.texi
@@ -0,0 +1,95 @@
+@findex struct bfd_iovec
+@subsubsection @code{struct bfd_iovec}
+@strong{Description}@*
+The @code{struct bfd_iovec} contains the internal file I/O class.
+Each @code{BFD} has an instance of this class and all file I/O is
+routed through it (it is assumed that the instance implements
+all methods listed below).
+@example
+struct bfd_iovec
+@{
+ /* To avoid problems with macros, a "b" rather than "f"
+ prefix is prepended to each method name. */
+ /* Attempt to read/write NBYTES on ABFD's IOSTREAM storing/fetching
+ bytes starting at PTR. Return the number of bytes actually
+ transfered (a read past end-of-file returns less than NBYTES),
+ or -1 (setting @code{bfd_error}) if an error occurs. */
+ file_ptr (*bread) (struct bfd *abfd, void *ptr, file_ptr nbytes);
+ file_ptr (*bwrite) (struct bfd *abfd, const void *ptr,
+ file_ptr nbytes);
+ /* Return the current IOSTREAM file offset, or -1 (setting @code{bfd_error}
+ if an error occurs. */
+ file_ptr (*btell) (struct bfd *abfd);
+ /* For the following, on successful completion a value of 0 is returned.
+ Otherwise, a value of -1 is returned (and @code{bfd_error} is set). */
+ int (*bseek) (struct bfd *abfd, file_ptr offset, int whence);
+ int (*bclose) (struct bfd *abfd);
+ int (*bflush) (struct bfd *abfd);
+ int (*bstat) (struct bfd *abfd, struct stat *sb);
+ /* Mmap a part of the files. ADDR, LEN, PROT, FLAGS and OFFSET are the usual
+ mmap parameter, except that LEN and OFFSET do not need to be page
+ aligned. Returns (void *)-1 on failure, mmapped address on success.
+ Also write in MAP_ADDR the address of the page aligned buffer and in
+ MAP_LEN the size mapped (a page multiple). Use unmap with MAP_ADDR and
+ MAP_LEN to unmap. */
+ void *(*bmmap) (struct bfd *abfd, void *addr, bfd_size_type len,
+ int prot, int flags, file_ptr offset,
+ void **map_addr, bfd_size_type *map_len);
+@};
+extern const struct bfd_iovec _bfd_memory_iovec;
+@end example
+
+@findex bfd_get_mtime
+@subsubsection @code{bfd_get_mtime}
+@strong{Synopsis}
+@example
+long bfd_get_mtime (bfd *abfd);
+@end example
+@strong{Description}@*
+Return the file modification time (as read from the file system, or
+from the archive header for archive members).
+
+@findex bfd_get_size
+@subsubsection @code{bfd_get_size}
+@strong{Synopsis}
+@example
+file_ptr bfd_get_size (bfd *abfd);
+@end example
+@strong{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 @code{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 question, "is the
+size reasonable?".
+
+@findex bfd_mmap
+@subsubsection @code{bfd_mmap}
+@strong{Synopsis}
+@example
+void *bfd_mmap (bfd *abfd, void *addr, bfd_size_type len,
+ int prot, int flags, file_ptr offset,
+ void **map_addr, bfd_size_type *map_len);
+@end example
+@strong{Description}@*
+Return mmap()ed region of the file, if possible and implemented.
+LEN and OFFSET do not need to be page aligned. The page aligned
+address and length are written to MAP_ADDR and MAP_LEN.
+
diff --git a/bfd/doc/bfdsumm.texi b/bfd/doc/bfdsumm.texi
new file mode 100644
index 0000000..1616be4
--- /dev/null
+++ b/bfd/doc/bfdsumm.texi
@@ -0,0 +1,150 @@
+@c This summary of BFD is shared by the BFD and LD docs.
+@c Copyright (C) 2012-2014 Free Software Foundation, Inc.
+
+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 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/bfdt.texi b/bfd/doc/bfdt.texi
new file mode 100644
index 0000000..3d8f104
--- /dev/null
+++ b/bfd/doc/bfdt.texi
@@ -0,0 +1,896 @@
+@node typedef bfd, Error reporting, BFD front end, BFD front end
+@section @code{typedef bfd}
+A BFD has type @code{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 @code{bfd}. It
+contains the major data about the file and pointers
+to the rest of the data.
+
+
+@example
+
+enum bfd_direction
+ @{
+ no_direction = 0,
+ read_direction = 1,
+ write_direction = 2,
+ both_direction = 3
+ @};
+
+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;
+
+ /* The IOSTREAM, and corresponding IO vector that provide access
+ to the file backing the BFD. */
+ void *iostream;
+ const struct bfd_iovec *iovec;
+
+ /* 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... */
+ ufile_ptr where;
+
+ /* File modified time, if mtime_set is TRUE. */
+ long mtime;
+
+ /* A unique identifier of the BFD */
+ unsigned int id;
+
+ /* The format which belongs to the BFD. (object, core, etc.) */
+ ENUM_BITFIELD (bfd_format) format : 3;
+
+ /* The direction with which the BFD was opened. */
+ ENUM_BITFIELD (bfd_direction) direction : 2;
+
+ /* Format_specific flags. */
+ flagword flags : 17;
+
+ /* 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). */
+
+#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
+
+ /* This BFD has been created by the linker and doesn't correspond
+ to any input file. */
+#define BFD_LINKER_CREATED 0x1000
+
+ /* This may be set before writing out a BFD to request that it
+ be written using values for UIDs, GIDs, timestamps, etc. that
+ will be consistent from run to run. */
+#define BFD_DETERMINISTIC_OUTPUT 0x2000
+
+ /* Compress sections in this BFD. */
+#define BFD_COMPRESS 0x4000
+
+ /* Decompress sections in this BFD. */
+#define BFD_DECOMPRESS 0x8000
+
+ /* BFD is a dummy, for plugins. */
+#define BFD_PLUGIN 0x10000
+
+ /* Flags bits to be saved in bfd_preserve_save. */
+#define BFD_FLAGS_SAVED \
+ (BFD_IN_MEMORY | BFD_COMPRESS | BFD_DECOMPRESS | BFD_PLUGIN)
+
+ /* Flags bits which are for BFD use only. */
+#define BFD_FLAGS_FOR_BFD_USE_MASK \
+ (BFD_IN_MEMORY | BFD_COMPRESS | BFD_DECOMPRESS | BFD_LINKER_CREATED \
+ | BFD_PLUGIN | BFD_TRADITIONAL_FORMAT | BFD_DETERMINISTIC_OUTPUT)
+
+ /* Is the file descriptor being cached? That is, can it be closed as
+ needed, and re-opened when accessed later? */
+ unsigned int cacheable : 1;
+
+ /* 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. */
+ unsigned int target_defaulted : 1;
+
+ /* ... and here: (``once'' means at least once). */
+ unsigned int opened_once : 1;
+
+ /* Set if we have a locally maintained mtime value, rather than
+ getting it from the file each time. */
+ unsigned int mtime_set : 1;
+
+ /* Flag set if symbols from this BFD should not be exported. */
+ unsigned int no_export : 1;
+
+ /* Remember when output has begun, to stop strange things
+ from happening. */
+ unsigned int output_has_begun : 1;
+
+ /* Have archive map. */
+ unsigned int has_armap : 1;
+
+ /* Set if this is a thin archive. */
+ unsigned int is_thin_archive : 1;
+
+ /* Set if only required symbols should be added in the link hash table for
+ this object. Used by VMS linkers. */
+ unsigned int selective_search : 1;
+
+ /* Set if this is the linker output BFD. */
+ unsigned int is_linker_output : 1;
+
+ /* 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. */
+ ufile_ptr origin;
+
+ /* The origin in the archive of the proxy entry. This will
+ normally be the same as origin, except for thin archives,
+ when it will contain the current offset of the proxy in the
+ thin archive rather than the offset of the bfd in its actual
+ container. */
+ ufile_ptr proxy_origin;
+
+ /* A hash table for section names. */
+ struct bfd_hash_table section_htab;
+
+ /* Pointer to linked list of sections. */
+ struct bfd_section *sections;
+
+ /* The last section on the section list. */
+ struct bfd_section *section_last;
+
+ /* The number of sections. */
+ unsigned int section_count;
+
+ /* A field used by _bfd_generic_link_add_archive_symbols. This will
+ be used only for archive elements. */
+ int archive_pass;
+
+ /* Stuff only useful for object files:
+ The start address. */
+ bfd_vma start_address;
+
+ /* Symbol table for output BFD (with symcount entries).
+ Also used by the linker to cache input BFD symbols. */
+ struct bfd_symbol **outsymbols;
+
+ /* Used for input and output. */
+ unsigned int symcount;
+
+ /* Used for slurped dynamic symbol tables. */
+ unsigned int dynsymcount;
+
+ /* Pointer to structure which contains architecture information. */
+ const struct bfd_arch_info *arch_info;
+
+ /* Stuff only useful for archives. */
+ void *arelt_data;
+ struct bfd *my_archive; /* The containing archive BFD. */
+ struct bfd *archive_next; /* The next BFD in the archive. */
+ struct bfd *archive_head; /* The first BFD in the archive. */
+ struct bfd *nested_archives; /* List of nested archive in a flattened
+ thin archive. */
+
+ union @{
+ /* For input BFDs, a chain of BFDs involved in a link. */
+ struct bfd *next;
+ /* For output BFD, the linker hash table. */
+ struct bfd_link_hash_table *hash;
+ @} link;
+
+ /* 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 verilog_data_struct *verilog_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 mmo_data_struct *mmo_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;
+ struct mach_o_data_struct *mach_o_data;
+ struct mach_o_fat_data_struct *mach_o_fat_data;
+ struct plugin_data_struct *plugin_data;
+ struct bfd_pef_data_struct *pef_data;
+ struct bfd_pef_xlib_data_struct *pef_xlib_data;
+ struct bfd_sym_data_struct *sym_data;
+ void *any;
+ @}
+ tdata;
+
+ /* Used by the application to hold private data. */
+ void *usrdata;
+
+ /* Where all the allocated stuff under this BFD goes. This is a
+ struct objalloc *, but we use void * to avoid requiring the inclusion
+ of objalloc.h. */
+ void *memory;
+@};
+
+/* See note beside bfd_set_section_userdata. */
+static inline bfd_boolean
+bfd_set_cacheable (bfd * abfd, bfd_boolean val)
+@{
+ abfd->cacheable = val;
+ return TRUE;
+@}
+
+@end example
+@node Error reporting, Miscellaneous, typedef bfd, BFD front end
+@section Error reporting
+Most BFD functions return nonzero on success (check their
+individual documentation for precise semantics). On an error,
+they call @code{bfd_set_error} to set an error condition that callers
+can check by calling @code{bfd_get_error}.
+If that returns @code{bfd_error_system_call}, then check
+@code{errno}.
+
+The easiest way to report a BFD error to the user is to
+use @code{bfd_perror}.
+
+@subsection Type @code{bfd_error_type}
+The values returned by @code{bfd_get_error} are defined by the
+enumerated type @code{bfd_error_type}.
+
+
+@example
+
+typedef enum bfd_error
+@{
+ bfd_error_no_error = 0,
+ bfd_error_system_call,
+ bfd_error_invalid_target,
+ bfd_error_wrong_format,
+ bfd_error_wrong_object_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_missing_dso,
+ 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_on_input,
+ bfd_error_invalid_error_code
+@}
+bfd_error_type;
+
+@end example
+@findex bfd_get_error
+@subsubsection @code{bfd_get_error}
+@strong{Synopsis}
+@example
+bfd_error_type bfd_get_error (void);
+@end example
+@strong{Description}@*
+Return the current BFD error condition.
+
+@findex bfd_set_error
+@subsubsection @code{bfd_set_error}
+@strong{Synopsis}
+@example
+void bfd_set_error (bfd_error_type error_tag, ...);
+@end example
+@strong{Description}@*
+Set the BFD error condition to be @var{error_tag}.
+If @var{error_tag} is bfd_error_on_input, then this function
+takes two more parameters, the input bfd where the error
+occurred, and the bfd_error_type error.
+
+@findex bfd_errmsg
+@subsubsection @code{bfd_errmsg}
+@strong{Synopsis}
+@example
+const char *bfd_errmsg (bfd_error_type error_tag);
+@end example
+@strong{Description}@*
+Return a string describing the error @var{error_tag}, or
+the system error if @var{error_tag} is @code{bfd_error_system_call}.
+
+@findex bfd_perror
+@subsubsection @code{bfd_perror}
+@strong{Synopsis}
+@example
+void bfd_perror (const char *message);
+@end example
+@strong{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.
+
+@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 overridden by the program.
+
+The BFD error handler acts like printf.
+
+
+@example
+
+typedef void (*bfd_error_handler_type) (const char *, ...);
+
+@end example
+@findex bfd_set_error_handler
+@subsubsection @code{bfd_set_error_handler}
+@strong{Synopsis}
+@example
+bfd_error_handler_type bfd_set_error_handler (bfd_error_handler_type);
+@end example
+@strong{Description}@*
+Set the BFD error handler function. Returns the previous
+function.
+
+@findex bfd_set_error_program_name
+@subsubsection @code{bfd_set_error_program_name}
+@strong{Synopsis}
+@example
+void bfd_set_error_program_name (const char *);
+@end example
+@strong{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.
+
+@findex bfd_get_error_handler
+@subsubsection @code{bfd_get_error_handler}
+@strong{Synopsis}
+@example
+bfd_error_handler_type bfd_get_error_handler (void);
+@end example
+@strong{Description}@*
+Return the BFD error handler function.
+
+@subsection BFD assert handler
+If BFD finds an internal inconsistency, the bfd assert
+handler is called with information on the BFD version, BFD
+source file and line. If this happens, most programs linked
+against BFD are expected to want to exit with an error, or mark
+the current BFD operation as failed, so it is recommended to
+override the default handler, which just calls
+_bfd_error_handler and continues.
+
+
+@example
+
+typedef void (*bfd_assert_handler_type) (const char *bfd_formatmsg,
+ const char *bfd_version,
+ const char *bfd_file,
+ int bfd_line);
+
+@end example
+@findex bfd_set_assert_handler
+@subsubsection @code{bfd_set_assert_handler}
+@strong{Synopsis}
+@example
+bfd_assert_handler_type bfd_set_assert_handler (bfd_assert_handler_type);
+@end example
+@strong{Description}@*
+Set the BFD assert handler function. Returns the previous
+function.
+
+@findex bfd_get_assert_handler
+@subsubsection @code{bfd_get_assert_handler}
+@strong{Synopsis}
+@example
+bfd_assert_handler_type bfd_get_assert_handler (void);
+@end example
+@strong{Description}@*
+Return the BFD assert handler function.
+
+@node Miscellaneous, Memory Usage, Error reporting, BFD front end
+@section Miscellaneous
+
+
+@subsection Miscellaneous functions
+
+
+@findex bfd_get_reloc_upper_bound
+@subsubsection @code{bfd_get_reloc_upper_bound}
+@strong{Synopsis}
+@example
+long bfd_get_reloc_upper_bound (bfd *abfd, asection *sect);
+@end example
+@strong{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.
+
+@findex bfd_canonicalize_reloc
+@subsubsection @code{bfd_canonicalize_reloc}
+@strong{Synopsis}
+@example
+long bfd_canonicalize_reloc
+ (bfd *abfd, asection *sec, arelent **loc, asymbol **syms);
+@end example
+@strong{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
+@code{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.
+
+@findex bfd_set_reloc
+@subsubsection @code{bfd_set_reloc}
+@strong{Synopsis}
+@example
+void bfd_set_reloc
+ (bfd *abfd, asection *sec, arelent **rel, unsigned int count);
+@end example
+@strong{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.
+
+@findex bfd_set_file_flags
+@subsubsection @code{bfd_set_file_flags}
+@strong{Synopsis}
+@example
+bfd_boolean bfd_set_file_flags (bfd *abfd, flagword flags);
+@end example
+@strong{Description}@*
+Set the flag word in the BFD @var{abfd} to the value @var{flags}.
+
+Possible errors are:
+@itemize @bullet
+
+@item
+@code{bfd_error_wrong_format} - The target bfd was not of object format.
+@item
+@code{bfd_error_invalid_operation} - The target bfd was open for reading.
+@item
+@code{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 @code{D_PAGED} bit
+on a BFD format which does not support demand paging.
+@end itemize
+
+@findex bfd_get_arch_size
+@subsubsection @code{bfd_get_arch_size}
+@strong{Synopsis}
+@example
+int bfd_get_arch_size (bfd *abfd);
+@end example
+@strong{Description}@*
+Returns the normalized architecture address size, in bits, as
+determined by the object file's format. By normalized, we mean
+either 32 or 64. For ELF, this information is included in the
+header. Use bfd_arch_bits_per_address for number of bits in
+the architecture address.
+
+@strong{Returns}@*
+Returns the arch size in bits if known, @code{-1} otherwise.
+
+@findex bfd_get_sign_extend_vma
+@subsubsection @code{bfd_get_sign_extend_vma}
+@strong{Synopsis}
+@example
+int bfd_get_sign_extend_vma (bfd *abfd);
+@end example
+@strong{Description}@*
+Indicates if the target architecture "naturally" sign extends
+an address. Some architectures implicitly sign extend address
+values when they are converted to types larger than the size
+of an address. For instance, bfd_get_start_address() will
+return an address sign extended to fill a bfd_vma when this is
+the case.
+
+@strong{Returns}@*
+Returns @code{1} if the target architecture is known to sign
+extend addresses, @code{0} if the target architecture is known to
+not sign extend addresses, and @code{-1} otherwise.
+
+@findex bfd_set_start_address
+@subsubsection @code{bfd_set_start_address}
+@strong{Synopsis}
+@example
+bfd_boolean bfd_set_start_address (bfd *abfd, bfd_vma vma);
+@end example
+@strong{Description}@*
+Make @var{vma} the entry point of output BFD @var{abfd}.
+
+@strong{Returns}@*
+Returns @code{TRUE} on success, @code{FALSE} otherwise.
+
+@findex bfd_get_gp_size
+@subsubsection @code{bfd_get_gp_size}
+@strong{Synopsis}
+@example
+unsigned int bfd_get_gp_size (bfd *abfd);
+@end example
+@strong{Description}@*
+Return the maximum size of objects to be optimized using the GP
+register under MIPS ECOFF. This is typically set by the @code{-G}
+argument to the compiler, assembler or linker.
+
+@findex bfd_set_gp_size
+@subsubsection @code{bfd_set_gp_size}
+@strong{Synopsis}
+@example
+void bfd_set_gp_size (bfd *abfd, unsigned int i);
+@end example
+@strong{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 @code{-G} argument to the compiler, assembler or linker.
+
+@findex bfd_scan_vma
+@subsubsection @code{bfd_scan_vma}
+@strong{Synopsis}
+@example
+bfd_vma bfd_scan_vma (const char *string, const char **end, int base);
+@end example
+@strong{Description}@*
+Convert, like @code{strtoul}, a numerical expression
+@var{string} into a @code{bfd_vma} integer, and return that integer.
+(Though without as many bells and whistles as @code{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.
+
+If the value would overflow, the maximum @code{bfd_vma} value is
+returned.
+
+@findex bfd_copy_private_header_data
+@subsubsection @code{bfd_copy_private_header_data}
+@strong{Synopsis}
+@example
+bfd_boolean bfd_copy_private_header_data (bfd *ibfd, bfd *obfd);
+@end example
+@strong{Description}@*
+Copy private BFD header information from the BFD @var{ibfd} to the
+the BFD @var{obfd}. This copies information that may require
+sections to exist, but does not require symbol tables. Return
+@code{true} on success, @code{false} on error.
+Possible error returns are:
+
+@itemize @bullet
+
+@item
+@code{bfd_error_no_memory} -
+Not enough memory exists to create private data for @var{obfd}.
+@end itemize
+@example
+#define bfd_copy_private_header_data(ibfd, obfd) \
+ BFD_SEND (obfd, _bfd_copy_private_header_data, \
+ (ibfd, obfd))
+@end example
+
+@findex bfd_copy_private_bfd_data
+@subsubsection @code{bfd_copy_private_bfd_data}
+@strong{Synopsis}
+@example
+bfd_boolean bfd_copy_private_bfd_data (bfd *ibfd, bfd *obfd);
+@end example
+@strong{Description}@*
+Copy private BFD information from the BFD @var{ibfd} to the
+the BFD @var{obfd}. Return @code{TRUE} on success, @code{FALSE} on error.
+Possible error returns are:
+
+@itemize @bullet
+
+@item
+@code{bfd_error_no_memory} -
+Not enough memory exists to create private data for @var{obfd}.
+@end itemize
+@example
+#define bfd_copy_private_bfd_data(ibfd, obfd) \
+ BFD_SEND (obfd, _bfd_copy_private_bfd_data, \
+ (ibfd, obfd))
+@end example
+
+@findex bfd_merge_private_bfd_data
+@subsubsection @code{bfd_merge_private_bfd_data}
+@strong{Synopsis}
+@example
+bfd_boolean bfd_merge_private_bfd_data (bfd *ibfd, bfd *obfd);
+@end example
+@strong{Description}@*
+Merge private BFD information from the BFD @var{ibfd} to the
+the output file BFD @var{obfd} when linking. Return @code{TRUE}
+on success, @code{FALSE} on error. Possible error returns are:
+
+@itemize @bullet
+
+@item
+@code{bfd_error_no_memory} -
+Not enough memory exists to create private data for @var{obfd}.
+@end itemize
+@example
+#define bfd_merge_private_bfd_data(ibfd, obfd) \
+ BFD_SEND (obfd, _bfd_merge_private_bfd_data, \
+ (ibfd, obfd))
+@end example
+
+@findex bfd_set_private_flags
+@subsubsection @code{bfd_set_private_flags}
+@strong{Synopsis}
+@example
+bfd_boolean bfd_set_private_flags (bfd *abfd, flagword flags);
+@end example
+@strong{Description}@*
+Set private BFD flag information in the BFD @var{abfd}.
+Return @code{TRUE} on success, @code{FALSE} on error. Possible error
+returns are:
+
+@itemize @bullet
+
+@item
+@code{bfd_error_no_memory} -
+Not enough memory exists to create private data for @var{obfd}.
+@end itemize
+@example
+#define bfd_set_private_flags(abfd, flags) \
+ BFD_SEND (abfd, _bfd_set_private_flags, (abfd, flags))
+@end example
+
+@findex Other functions
+@subsubsection @code{Other functions}
+@strong{Description}@*
+The following functions exist but have not yet been documented.
+@example
+#define bfd_sizeof_headers(abfd, info) \
+ BFD_SEND (abfd, _bfd_sizeof_headers, (abfd, info))
+
+#define bfd_find_nearest_line(abfd, sec, syms, off, file, func, line) \
+ BFD_SEND (abfd, _bfd_find_nearest_line, \
+ (abfd, syms, sec, off, file, func, line, NULL))
+
+#define bfd_find_nearest_line_discriminator(abfd, sec, syms, off, file, func, \
+ line, disc) \
+ BFD_SEND (abfd, _bfd_find_nearest_line, \
+ (abfd, syms, sec, off, file, func, line, disc))
+
+#define bfd_find_line(abfd, syms, sym, file, line) \
+ BFD_SEND (abfd, _bfd_find_line, \
+ (abfd, syms, sym, file, line))
+
+#define bfd_find_inliner_info(abfd, file, func, line) \
+ BFD_SEND (abfd, _bfd_find_inliner_info, \
+ (abfd, file, func, line))
+
+#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_lookup_section_flags(link_info, flag_info, section) \
+ BFD_SEND (abfd, _bfd_lookup_section_flags, (link_info, flag_info, section))
+
+#define bfd_merge_sections(abfd, link_info) \
+ BFD_SEND (abfd, _bfd_merge_sections, (abfd, link_info))
+
+#define bfd_is_group_section(abfd, sec) \
+ BFD_SEND (abfd, _bfd_is_group_section, (abfd, sec))
+
+#define bfd_discard_group(abfd, sec) \
+ BFD_SEND (abfd, _bfd_discard_group, (abfd, sec))
+
+#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_link_just_syms(abfd, sec, info) \
+ BFD_SEND (abfd, _bfd_link_just_syms, (sec, 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_synthetic_symtab(abfd, count, syms, dyncount, dynsyms, ret) \
+ BFD_SEND (abfd, _bfd_get_synthetic_symtab, (abfd, count, syms, \
+ dyncount, dynsyms, ret))
+
+#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
+ (bfd *, struct bfd_link_info *, struct bfd_link_order *, bfd_byte *,
+ bfd_boolean, asymbol **);
+
+@end example
+
+@findex bfd_alt_mach_code
+@subsubsection @code{bfd_alt_mach_code}
+@strong{Synopsis}
+@example
+bfd_boolean bfd_alt_mach_code (bfd *abfd, int alternative);
+@end example
+@strong{Description}@*
+When more than one machine code number is available for the
+same machine type, this function can be used to switch between
+the preferred one (alternative == 0) and any others. Currently,
+only ELF supports this feature, with up to two alternate
+machine codes.
+
+@findex bfd_emul_get_maxpagesize
+@subsubsection @code{bfd_emul_get_maxpagesize}
+@strong{Synopsis}
+@example
+bfd_vma bfd_emul_get_maxpagesize (const char *);
+@end example
+@strong{Description}@*
+Returns the maximum page size, in bytes, as determined by
+emulation.
+
+@strong{Returns}@*
+Returns the maximum page size in bytes for ELF, 0 otherwise.
+
+@findex bfd_emul_set_maxpagesize
+@subsubsection @code{bfd_emul_set_maxpagesize}
+@strong{Synopsis}
+@example
+void bfd_emul_set_maxpagesize (const char *, bfd_vma);
+@end example
+@strong{Description}@*
+For ELF, set the maximum page size for the emulation. It is
+a no-op for other formats.
+
+@findex bfd_emul_get_commonpagesize
+@subsubsection @code{bfd_emul_get_commonpagesize}
+@strong{Synopsis}
+@example
+bfd_vma bfd_emul_get_commonpagesize (const char *);
+@end example
+@strong{Description}@*
+Returns the common page size, in bytes, as determined by
+emulation.
+
+@strong{Returns}@*
+Returns the common page size in bytes for ELF, 0 otherwise.
+
+@findex bfd_emul_set_commonpagesize
+@subsubsection @code{bfd_emul_set_commonpagesize}
+@strong{Synopsis}
+@example
+void bfd_emul_set_commonpagesize (const char *, bfd_vma);
+@end example
+@strong{Description}@*
+For ELF, set the common page size for the emulation. It is
+a no-op for other formats.
+
+@findex bfd_demangle
+@subsubsection @code{bfd_demangle}
+@strong{Synopsis}
+@example
+char *bfd_demangle (bfd *, const char *, int);
+@end example
+@strong{Description}@*
+Wrapper around cplus_demangle. Strips leading underscores and
+other such chars that would otherwise confuse the demangler.
+If passed a g++ v3 ABI mangled name, returns a buffer allocated
+with malloc holding the demangled name. Returns NULL otherwise
+and on memory alloc failure.
+
diff --git a/bfd/doc/bfdver.texi b/bfd/doc/bfdver.texi
new file mode 100644
index 0000000..e854b40
--- /dev/null
+++ b/bfd/doc/bfdver.texi
@@ -0,0 +1,4 @@
+@set VERSION 2.25
+@set VERSION_PACKAGE (GNU Binutils)
+@set UPDATED December 2014
+@set BUGURL @uref{http://www.sourceware.org/bugzilla/}
diff --git a/bfd/doc/bfdwin.texi b/bfd/doc/bfdwin.texi
new file mode 100644
index 0000000..b1fd7d5
--- /dev/null
+++ b/bfd/doc/bfdwin.texi
@@ -0,0 +1,2 @@
+@findex
+@subsubsection @code{}
diff --git a/bfd/doc/cache.texi b/bfd/doc/cache.texi
new file mode 100644
index 0000000..05b627e
--- /dev/null
+++ b/bfd/doc/cache.texi
@@ -0,0 +1,65 @@
+@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
+@code{cache.c} maintains a least recently used list of
+@code{bfd_cache_max_open} files, and exports the name
+@code{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.
+
+@subsection Caching functions
+
+
+@findex bfd_cache_init
+@subsubsection @code{bfd_cache_init}
+@strong{Synopsis}
+@example
+bfd_boolean bfd_cache_init (bfd *abfd);
+@end example
+@strong{Description}@*
+Add a newly opened BFD to the cache.
+
+@findex bfd_cache_close
+@subsubsection @code{bfd_cache_close}
+@strong{Synopsis}
+@example
+bfd_boolean bfd_cache_close (bfd *abfd);
+@end example
+@strong{Description}@*
+Remove the BFD @var{abfd} from the cache. If the attached file is open,
+then close it too.
+
+@strong{Returns}@*
+@code{FALSE} is returned if closing the file fails, @code{TRUE} is
+returned if all is well.
+
+@findex bfd_cache_close_all
+@subsubsection @code{bfd_cache_close_all}
+@strong{Synopsis}
+@example
+bfd_boolean bfd_cache_close_all (void);
+@end example
+@strong{Description}@*
+Remove all BFDs from the cache. If the attached file is open,
+then close it too.
+
+@strong{Returns}@*
+@code{FALSE} is returned if closing one of the file fails, @code{TRUE} is
+returned if all is well.
+
+@findex bfd_open_file
+@subsubsection @code{bfd_open_file}
+@strong{Synopsis}
+@example
+FILE* bfd_open_file (bfd *abfd);
+@end example
+@strong{Description}@*
+Call the OS to open a file for @var{abfd}. Return the @code{FILE *}
+(possibly @code{NULL}) that results from this operation. Set up the
+BFD so that future accesses know the file is open. If the @code{FILE *}
+returned is @code{NULL}, then it won't have been put in the
+cache, so it won't have to be removed from it.
+
diff --git a/bfd/doc/chew.c b/bfd/doc/chew.c
new file mode 100644
index 0000000..9ad88aa
--- /dev/null
+++ b/bfd/doc/chew.c
@@ -0,0 +1,1585 @@
+/* chew
+ Copyright (C) 1990-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, 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 <assert.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.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 *);
+static void die (char *);
+#endif
+
+static void
+init_string_with_size (buffer, size)
+ string_type *buffer;
+ unsigned int size;
+{
+ buffer->write_idx = 0;
+ buffer->size = size;
+ buffer->ptr = (char *) malloc (size);
+}
+
+static void
+init_string (buffer)
+ string_type *buffer;
+{
+ init_string_with_size (buffer, DEF_SIZE);
+}
+
+static int
+find (str, what)
+ string_type *str;
+ 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
+write_buffer (buffer, f)
+ string_type *buffer;
+ FILE *f;
+{
+ if (buffer->write_idx != 0
+ && fwrite (buffer->ptr, buffer->write_idx, 1, f) != 1)
+ die ("cannot write output");
+}
+
+static void
+delete_string (buffer)
+ string_type *buffer;
+{
+ free (buffer->ptr);
+}
+
+static char *
+addr (buffer, idx)
+ string_type *buffer;
+ unsigned int idx;
+{
+ return buffer->ptr + idx;
+}
+
+static char
+at (buffer, pos)
+ string_type *buffer;
+ unsigned int pos;
+{
+ if (pos >= buffer->write_idx)
+ return 0;
+ return buffer->ptr[pos];
+}
+
+static void
+catchar (buffer, ch)
+ string_type *buffer;
+ int ch;
+{
+ if (buffer->write_idx == buffer->size)
+ {
+ buffer->size *= 2;
+ buffer->ptr = (char *) realloc (buffer->ptr, buffer->size);
+ }
+
+ buffer->ptr[buffer->write_idx++] = ch;
+}
+
+static void
+overwrite_string (dst, src)
+ string_type *dst;
+ string_type *src;
+{
+ free (dst->ptr);
+ dst->size = src->size;
+ dst->write_idx = src->write_idx;
+ dst->ptr = src->ptr;
+}
+
+static void
+catbuf (buffer, buf, len)
+ string_type *buffer;
+ char *buf;
+ unsigned int len;
+{
+ if (buffer->write_idx + len >= buffer->size)
+ {
+ while (buffer->write_idx + len >= buffer->size)
+ buffer->size *= 2;
+ buffer->ptr = (char *) realloc (buffer->ptr, buffer->size);
+ }
+ memcpy (buffer->ptr + buffer->write_idx, buf, len);
+ buffer->write_idx += len;
+}
+
+static void
+cattext (buffer, string)
+ string_type *buffer;
+ char *string;
+{
+ catbuf (buffer, string, (unsigned int) strlen (string));
+}
+
+static void
+catstr (dst, src)
+ string_type *dst;
+ string_type *src;
+{
+ catbuf (dst, src->ptr, src->write_idx);
+}
+
+static unsigned int
+skip_white_and_stars (src, idx)
+ string_type *src;
+ 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;
+}
+
+static unsigned int
+skip_past_newline_1 (ptr, idx)
+ string_type *ptr;
+ unsigned int idx;
+{
+ while (at (ptr, idx)
+ && at (ptr, idx) != '\n')
+ idx++;
+ if (at (ptr, idx) == '\n')
+ return idx + 1;
+ 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;
+
+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
+exec (word)
+ dict_type *word;
+{
+ pc = word->code;
+ while (*pc)
+ (*pc) ();
+}
+
+static void
+call ()
+{
+ stinst_type *oldpc = pc;
+ dict_type *e;
+ e = (dict_type *) (pc[1]);
+ exec (e);
+ pc = oldpc + 2;
+}
+
+static void
+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++;
+}
+
+static void
+push_number ()
+{
+ isp++;
+ icheck_range ();
+ pc++;
+ *isp = (long) (*pc);
+ pc++;
+}
+
+static void
+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
+remove_noncomments (src, dst)
+ string_type *src;
+ 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 = %ld, ",
+ (long) (tos - stack));
+ fprintf (stderr, "current integer stack depth = %ld\n",
+ (long) (isp - istack));
+ pc++;
+}
+
+/* turn:
+ foobar name(stuff);
+ into:
+ foobar
+ name PARAMS ((stuff));
+ and a blank line.
+ */
+
+static void
+paramstuff ()
+{
+ unsigned int openp;
+ unsigned int fname;
+ unsigned int idx;
+ unsigned int len;
+ string_type out;
+ init_string (&out);
+
+#define NO_PARAMS 1
+
+ /* Make sure that it's not already param'd or proto'd. */
+ if (NO_PARAMS
+ || 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++;
+
+ /* Output type, omitting trailing whitespace character(s), if
+ any. */
+ for (len = fname; 0 < len; len--)
+ {
+ if (!isspace ((unsigned char) at (tos, len - 1)))
+ break;
+ }
+ for (idx = 0; idx < len; idx++)
+ catchar (&out, at (tos, idx));
+
+ cattext (&out, "\n"); /* Insert a newline between type and fnname */
+
+ /* Output function name, omitting trailing whitespace
+ character(s), if any. */
+ for (len = openp; 0 < len; len--)
+ {
+ if (!isspace ((unsigned char) at (tos, len - 1)))
+ break;
+ }
+ for (idx = fname; idx < len; idx++)
+ catchar (&out, at (tos, idx));
+
+ cattext (&out, " PARAMS (");
+
+ for (idx = openp; at (tos, idx) && at (tos, idx) != ';'; idx++)
+ catchar (&out, at (tos, idx));
+
+ cattext (&out, ");\n\n");
+ }
+ overwrite_string (tos, &out);
+ pc++;
+
+}
+
+/* turn {*
+ and *} into comments */
+
+static void
+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++;
+}
+
+/* Mod tos so that only lines with leading dots remain */
+static void
+outputdots ()
+{
+ unsigned int idx = 0;
+ string_type out;
+ init_string (&out);
+
+ while (at (tos, idx))
+ {
+ /* Every iteration begins at the start of a line. */
+ if (at (tos, idx) == '.')
+ {
+ char c;
+
+ idx++;
+
+ 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++;
+ }
+ }
+ if (c == '\n')
+ idx++;
+ catchar (&out, '\n');
+ }
+ else
+ {
+ idx = skip_past_newline_1 (tos, idx);
+ }
+ }
+
+ overwrite_string (tos, &out);
+ pc++;
+}
+
+/* Find lines starting with . and | and put example around them on tos */
+static void
+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 (command > 1)
+ {
+ /* We are inside {} parameters of some command;
+ Just pass through until matching brace. */
+ if (at (tos, idx) == '{')
+ ++command;
+ else if (at (tos, idx) == '}')
+ --command;
+ }
+ else if (command != 0)
+ {
+ if (at (tos, idx) == '{')
+ ++command;
+ else if (!islower ((unsigned char) at (tos, idx)))
+ --command;
+ }
+ else if (at (tos, idx) == '@'
+ && islower ((unsigned char) at (tos, idx + 1)))
+ {
+ ++command;
+ }
+ else if (at (tos, idx) == '{' && at (tos, idx + 1) == '*')
+ {
+ cattext (&out, "/*");
+ idx += 2;
+ continue;
+ }
+ else if (at (tos, idx) == '*' && at (tos, idx + 1) == '}')
+ {
+ cattext (&out, "*/");
+ idx += 2;
+ continue;
+ }
+ else if (at (tos, idx) == '{'
+ || at (tos, idx) == '}')
+ {
+ catchar (&out, '@');
+ }
+
+ 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*/
+
+static void
+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*/
+
+static void
+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
+iscommand (ptr, idx)
+ string_type *ptr;
+ 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
+copy_past_newline (ptr, idx, dst)
+ string_type *ptr;
+ unsigned int idx;
+ 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;
+
+}
+
+static void
+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. */
+
+static void
+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;
+
+}
+
+static void
+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;
+
+}
+
+static void
+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++;
+}
+
+static void
+swap ()
+{
+ string_type t;
+
+ t = tos[0];
+ tos[0] = tos[-1];
+ tos[-1] = t;
+ pc++;
+}
+
+static void
+other_dup ()
+{
+ tos++;
+ check_range ();
+ init_string (tos);
+ catstr (tos, tos - 1);
+ pc++;
+}
+
+static void
+drop ()
+{
+ tos--;
+ check_range ();
+ pc++;
+}
+
+static void
+idrop ()
+{
+ isp--;
+ icheck_range ();
+ pc++;
+}
+
+static void
+icatstr ()
+{
+ tos--;
+ check_range ();
+ catstr (tos, tos + 1);
+ delete_string (tos + 1);
+ pc++;
+}
+
+static void
+skip_past_newline ()
+{
+ idx = skip_past_newline_1 (ptr, idx);
+ pc++;
+}
+
+static void
+internalmode ()
+{
+ internal_mode = *(isp);
+ isp--;
+ icheck_range ();
+ pc++;
+}
+
+static void
+maybecatstr ()
+{
+ if (internal_wanted == internal_mode)
+ {
+ catstr (tos - 1, tos);
+ }
+ delete_string (tos);
+ tos--;
+ check_range ();
+ pc++;
+}
+
+char *
+nextword (string, word)
+ char *string;
+ 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 = (char *) 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 *
+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
+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 ();
+ }
+ free (next);
+ }
+ else
+ skip_past_newline ();
+ }
+}
+
+dict_type *
+newentry (word)
+ char *word;
+{
+ dict_type *new_d = (dict_type *) malloc (sizeof (dict_type));
+ new_d->word = word;
+ new_d->next = root;
+ root = new_d;
+ new_d->code = (stinst_type *) malloc (sizeof (stinst_type));
+ new_d->code_length = 1;
+ new_d->code_end = 0;
+ return new_d;
+}
+
+unsigned int
+add_to_definition (entry, word)
+ dict_type *entry;
+ 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
+add_intrinsic (name, func)
+ char *name;
+ void (*func) ();
+{
+ dict_type *new_d = newentry (name);
+ add_to_definition (new_d, func);
+ add_to_definition (new_d, 0);
+}
+
+void
+add_var (name)
+ char *name;
+{
+ dict_type *new_d = newentry (name);
+ add_to_definition (new_d, push_number);
+ add_to_definition (new_d, (stinst_type) (&(new_d->var)));
+ add_to_definition (new_d, 0);
+}
+
+void
+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
+bang ()
+{
+ *(long *) ((isp[0])) = isp[-1];
+ isp -= 2;
+ icheck_range ();
+ pc++;
+}
+
+static void
+atsign ()
+{
+ isp[0] = *(long *) (isp[0]);
+ pc++;
+}
+
+static void
+hello ()
+{
+ printf ("hello\n");
+ pc++;
+}
+
+static void
+stdout_ ()
+{
+ isp++;
+ icheck_range ();
+ *isp = 1;
+ pc++;
+}
+
+static void
+stderr_ ()
+{
+ isp++;
+ icheck_range ();
+ *isp = 2;
+ pc++;
+}
+
+static void
+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
+read_in (str, file)
+ string_type *str;
+ 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
+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
+main (ac, av)
+ int ac;
+ 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 %ld\n",
+ (long) (tos - stack));
+ return 1;
+ }
+ return 0;
+}
diff --git a/bfd/doc/coffcode.texi b/bfd/doc/coffcode.texi
new file mode 100644
index 0000000..bbf0469
--- /dev/null
+++ b/bfd/doc/coffcode.texi
@@ -0,0 +1,693 @@
+@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 Coff long section names
+In the standard Coff object format, section names are limited to
+the eight bytes available in the @code{s_name} field of the
+@code{SCNHDR} section header structure. The format requires the
+field to be NUL-padded, but not necessarily NUL-terminated, so
+the longest section names permitted are a full eight characters.
+
+The Microsoft PE variants of the Coff object file format add
+an extension to support the use of long section names. This
+extension is defined in section 4 of the Microsoft PE/COFF
+specification (rev 8.1). If a section name is too long to fit
+into the section header's @code{s_name} field, it is instead
+placed into the string table, and the @code{s_name} field is
+filled with a slash ("/") followed by the ASCII decimal
+representation of the offset of the full name relative to the
+string table base.
+
+Note that this implies that the extension can only be used in object
+files, as executables do not contain a string table. The standard
+specifies that long section names from objects emitted into executable
+images are to be truncated.
+
+However, as a GNU extension, BFD can generate executable images
+that contain a string table and long section names. This
+would appear to be technically valid, as the standard only says
+that Coff debugging information is deprecated, not forbidden,
+and in practice it works, although some tools that parse PE files
+expecting the MS standard format may become confused; @file{PEview} is
+one known example.
+
+The functionality is supported in BFD by code implemented under
+the control of the macro @code{COFF_LONG_SECTION_NAMES}. If not
+defined, the format does not support long section names in any way.
+If defined, it is used to initialise a flag,
+@code{_bfd_coff_long_section_names}, and a hook function pointer,
+@code{_bfd_coff_set_long_section_names}, in the Coff backend data
+structure. The flag controls the generation of long section names
+in output BFDs at runtime; if it is false, as it will be by default
+when generating an executable image, long section names are truncated;
+if true, the long section names extension is employed. The hook
+points to a function that allows the value of the flag to be altered
+at runtime, on formats that support long section names at all; on
+other formats it points to a stub that returns an error indication.
+
+With input BFDs, the flag is set according to whether any long section
+names are detected while reading the section headers. For a completely
+new BFD, the flag is set to the default for the target format. This
+information can be used by a client of the BFD library when deciding
+what output format to generate, and means that a BFD that is opened
+for read and subsequently converted to a writeable BFD and modified
+in-place will retain whatever format it had on input.
+
+If @code{COFF_LONG_SECTION_NAMES} is simply defined (blank), or is
+defined to the value "1", then long section names are enabled by
+default; if it is defined to the value zero, they are disabled by
+default (but still accepted in input BFDs). The header @file{coffcode.h}
+defines a macro, @code{COFF_DEFAULT_LONG_SECTION_NAMES}, which is
+used in the backends to initialise the backend data structure fields
+appropriately; see the comments for further detail.
+
+@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_lineno_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
+(@code{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
+@code{output_section} field of the @code{asymbol}'s
+@code{asection} @xref{Sections}.
+
+@itemize @bullet
+
+@item
+@code{coff_mangle_symbols}
+@end itemize
+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 hierarchy required by coff. It changes each pointer
+to a symbol into the index into the symbol table of the asymbol.
+
+@itemize @bullet
+
+@item
+@code{coff_write_symbols}
+@end itemize
+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.
+
+@findex coff_symbol_type
+@subsubsection @code{coff_symbol_type}
+@strong{Description}@*
+The hidden information for an @code{asymbol} is described in a
+@code{combined_entry_type}:
+
+
+@example
+
+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;
+
+ /* Selector for the union above. */
+ bfd_boolean is_sym;
+@} 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 ? */
+ bfd_boolean done_lineno;
+@} coff_symbol_type;
+@end example
+@findex bfd_coff_backend_data
+@subsubsection @code{bfd_coff_backend_data}
+
+@example
+/* COFF symbol classifications. */
+
+enum coff_symbol_classification
+@{
+ /* Global symbol. */
+ COFF_SYMBOL_GLOBAL,
+ /* Common symbol. */
+ COFF_SYMBOL_COMMON,
+ /* Undefined symbol. */
+ COFF_SYMBOL_UNDEFINED,
+ /* Local symbol. */
+ COFF_SYMBOL_LOCAL,
+ /* PE section symbol. */
+ COFF_SYMBOL_PE_SECTION
+@};
+
+@end example
+Special entry points for gdb to swap in coff symbol table parts:
+@example
+typedef struct
+@{
+ void (*_bfd_coff_swap_aux_in)
+ (bfd *, void *, int, int, int, int, void *);
+
+ void (*_bfd_coff_swap_sym_in)
+ (bfd *, void *, void *);
+
+ void (*_bfd_coff_swap_lineno_in)
+ (bfd *, void *, void *);
+
+ unsigned int (*_bfd_coff_swap_aux_out)
+ (bfd *, void *, int, int, int, int, void *);
+
+ unsigned int (*_bfd_coff_swap_sym_out)
+ (bfd *, void *, void *);
+
+ unsigned int (*_bfd_coff_swap_lineno_out)
+ (bfd *, void *, void *);
+
+ unsigned int (*_bfd_coff_swap_reloc_out)
+ (bfd *, void *, void *);
+
+ unsigned int (*_bfd_coff_swap_filehdr_out)
+ (bfd *, void *, void *);
+
+ unsigned int (*_bfd_coff_swap_aouthdr_out)
+ (bfd *, void *, void *);
+
+ unsigned int (*_bfd_coff_swap_scnhdr_out)
+ (bfd *, void *, void *);
+
+ 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;
+ unsigned int _bfd_filnmlen;
+ bfd_boolean _bfd_coff_long_filenames;
+
+ bfd_boolean _bfd_coff_long_section_names;
+ bfd_boolean (*_bfd_coff_set_long_section_names)
+ (bfd *, int);
+
+ unsigned int _bfd_coff_default_section_alignment_power;
+ bfd_boolean _bfd_coff_force_symnames_in_strings;
+ unsigned int _bfd_coff_debug_string_prefix_length;
+ unsigned int _bfd_coff_max_nscns;
+
+ void (*_bfd_coff_swap_filehdr_in)
+ (bfd *, void *, void *);
+
+ void (*_bfd_coff_swap_aouthdr_in)
+ (bfd *, void *, void *);
+
+ void (*_bfd_coff_swap_scnhdr_in)
+ (bfd *, void *, void *);
+
+ void (*_bfd_coff_swap_reloc_in)
+ (bfd *abfd, void *, void *);
+
+ bfd_boolean (*_bfd_coff_bad_format_hook)
+ (bfd *, void *);
+
+ bfd_boolean (*_bfd_coff_set_arch_mach_hook)
+ (bfd *, void *);
+
+ void * (*_bfd_coff_mkobject_hook)
+ (bfd *, void *, void *);
+
+ bfd_boolean (*_bfd_styp_to_sec_flags_hook)
+ (bfd *, void *, const char *, asection *, flagword *);
+
+ void (*_bfd_set_alignment_hook)
+ (bfd *, asection *, void *);
+
+ bfd_boolean (*_bfd_coff_slurp_symbol_table)
+ (bfd *);
+
+ bfd_boolean (*_bfd_coff_symname_in_debug)
+ (bfd *, struct internal_syment *);
+
+ bfd_boolean (*_bfd_coff_pointerize_aux_hook)
+ (bfd *, combined_entry_type *, combined_entry_type *,
+ unsigned int, combined_entry_type *);
+
+ bfd_boolean (*_bfd_coff_print_aux)
+ (bfd *, FILE *, combined_entry_type *, combined_entry_type *,
+ combined_entry_type *, unsigned int);
+
+ void (*_bfd_coff_reloc16_extra_cases)
+ (bfd *, struct bfd_link_info *, struct bfd_link_order *, arelent *,
+ bfd_byte *, unsigned int *, unsigned int *);
+
+ int (*_bfd_coff_reloc16_estimate)
+ (bfd *, asection *, arelent *, unsigned int,
+ struct bfd_link_info *);
+
+ enum coff_symbol_classification (*_bfd_coff_classify_symbol)
+ (bfd *, struct internal_syment *);
+
+ bfd_boolean (*_bfd_coff_compute_section_file_positions)
+ (bfd *);
+
+ bfd_boolean (*_bfd_coff_start_final_link)
+ (bfd *, struct bfd_link_info *);
+
+ bfd_boolean (*_bfd_coff_relocate_section)
+ (bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
+ struct internal_reloc *, struct internal_syment *, asection **);
+
+ reloc_howto_type *(*_bfd_coff_rtype_to_howto)
+ (bfd *, asection *, struct internal_reloc *,
+ struct coff_link_hash_entry *, struct internal_syment *,
+ bfd_vma *);
+
+ bfd_boolean (*_bfd_coff_adjust_symndx)
+ (bfd *, struct bfd_link_info *, bfd *, asection *,
+ struct internal_reloc *, bfd_boolean *);
+
+ bfd_boolean (*_bfd_coff_link_add_one_symbol)
+ (struct bfd_link_info *, bfd *, const char *, flagword,
+ asection *, bfd_vma, const char *, bfd_boolean, bfd_boolean,
+ struct bfd_link_hash_entry **);
+
+ bfd_boolean (*_bfd_coff_link_output_has_begun)
+ (bfd *, struct coff_final_link_info *);
+
+ bfd_boolean (*_bfd_coff_final_link_postscript)
+ (bfd *, struct coff_final_link_info *);
+
+ bfd_boolean (*_bfd_coff_print_pdata)
+ (bfd *, void *);
+
+@} 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_filnmlen(abfd) (coff_backend_info (abfd)->_bfd_filnmlen)
+#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_set_long_section_names(abfd, enable) \
+ ((coff_backend_info (abfd)->_bfd_coff_set_long_section_names) (abfd, enable))
+#define bfd_coff_default_section_alignment_power(abfd) \
+ (coff_backend_info (abfd)->_bfd_coff_default_section_alignment_power)
+#define bfd_coff_max_nscns(abfd) \
+ (coff_backend_info (abfd)->_bfd_coff_max_nscns)
+
+#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, section, flags_ptr)\
+ ((coff_backend_info (abfd)->_bfd_styp_to_sec_flags_hook)\
+ (abfd, scnhdr, name, section, flags_ptr))
+
+#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_force_symnames_in_strings(abfd)\
+ (coff_backend_info (abfd)->_bfd_coff_force_symnames_in_strings)
+
+#define bfd_coff_debug_string_prefix_length(abfd)\
+ (coff_backend_info (abfd)->_bfd_coff_debug_string_prefix_length)
+
+#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_classify_symbol(abfd, sym)\
+ ((coff_backend_info (abfd)->_bfd_coff_classify_symbol)\
+ (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))
+
+#define bfd_coff_have_print_pdata(a) \
+ (coff_backend_info (a)->_bfd_coff_print_pdata)
+#define bfd_coff_print_pdata(a,p) \
+ ((coff_backend_info (a)->_bfd_coff_print_pdata) (a, p))
+
+/* Macro: Returns true if the bfd is a PE executable as opposed to a
+ PE object file. */
+#define bfd_pei_p(abfd) \
+ (CONST_STRNEQ ((abfd)->xvec->name, "pei-"))
+@end example
+@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.
+
+@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.
+
+Note: The PE format uses line number 0 for a flag indicating a
+new source file.
+
+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 ?
+
+@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:
+
+@itemize @bullet
+
+@item
+Read the entire coff relocation table into memory.
+
+@item
+Process each relocation in turn; first swap it from the
+external to the internal form.
+
+@item
+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.
+
+@item
+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.
+@end itemize
+
diff --git a/bfd/doc/core.texi b/bfd/doc/core.texi
new file mode 100644
index 0000000..cd98c4a
--- /dev/null
+++ b/bfd/doc/core.texi
@@ -0,0 +1,70 @@
+@section Core files
+
+
+@subsection Core file functions
+
+
+@strong{Description}@*
+These are functions pertaining to core files.
+
+@findex bfd_core_file_failing_command
+@subsubsection @code{bfd_core_file_failing_command}
+@strong{Synopsis}
+@example
+const char *bfd_core_file_failing_command (bfd *abfd);
+@end example
+@strong{Description}@*
+Return a read-only string explaining which program was running
+when it failed and produced the core file @var{abfd}.
+
+@findex bfd_core_file_failing_signal
+@subsubsection @code{bfd_core_file_failing_signal}
+@strong{Synopsis}
+@example
+int bfd_core_file_failing_signal (bfd *abfd);
+@end example
+@strong{Description}@*
+Returns the signal number which caused the core dump which
+generated the file the BFD @var{abfd} is attached to.
+
+@findex bfd_core_file_pid
+@subsubsection @code{bfd_core_file_pid}
+@strong{Synopsis}
+@example
+int bfd_core_file_pid (bfd *abfd);
+@end example
+@strong{Description}@*
+Returns the PID of the process the core dump the BFD
+@var{abfd} is attached to was generated from.
+
+@findex core_file_matches_executable_p
+@subsubsection @code{core_file_matches_executable_p}
+@strong{Synopsis}
+@example
+bfd_boolean core_file_matches_executable_p
+ (bfd *core_bfd, bfd *exec_bfd);
+@end example
+@strong{Description}@*
+Return @code{TRUE} if the core file attached to @var{core_bfd}
+was generated by a run of the executable file attached to
+@var{exec_bfd}, @code{FALSE} otherwise.
+
+@findex generic_core_file_matches_executable_p
+@subsubsection @code{generic_core_file_matches_executable_p}
+@strong{Synopsis}
+@example
+bfd_boolean generic_core_file_matches_executable_p
+ (bfd *core_bfd, bfd *exec_bfd);
+@end example
+@strong{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}. The match is based on executable
+basenames only.
+
+Note: When not able to determine the core file failing
+command or the executable name, we still return TRUE even
+though we're not sure that core file and executable match.
+This is to avoid generating a false warning in situations
+where we really don't know whether they match or not.
+
diff --git a/bfd/doc/doc.str b/bfd/doc/doc.str
new file mode 100644
index 0000000..7a276fe
--- /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/elf.texi b/bfd/doc/elf.texi
new file mode 100644
index 0000000..4053386
--- /dev/null
+++ b/bfd/doc/elf.texi
@@ -0,0 +1,9 @@
+@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.
+
diff --git a/bfd/doc/elfcode.texi b/bfd/doc/elfcode.texi
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/bfd/doc/elfcode.texi
diff --git a/bfd/doc/fdl.texi b/bfd/doc/fdl.texi
new file mode 100644
index 0000000..8805f1a
--- /dev/null
+++ b/bfd/doc/fdl.texi
@@ -0,0 +1,506 @@
+@c The GNU Free Documentation License.
+@center Version 1.3, 3 November 2008
+
+@c This file is intended to be included within another document,
+@c hence no sectioning command or @node.
+
+@display
+Copyright @copyright{} 2000, 2001, 2002, 2007, 2008 Free Software Foundation, Inc.
+@uref{http://fsf.org/}
+
+Everyone is permitted to copy and distribute verbatim copies
+of this license document, but changing it is not allowed.
+@end display
+
+@enumerate 0
+@item
+PREAMBLE
+
+The purpose of this License is to make a manual, textbook, or other
+functional and useful document @dfn{free} in the sense of freedom: to
+assure everyone the effective freedom to copy and redistribute it,
+with or without modifying it, either commercially or noncommercially.
+Secondarily, this License preserves for the author and publisher a way
+to get credit for their work, while not being considered responsible
+for modifications made by others.
+
+This License is a kind of ``copyleft'', which means that derivative
+works of the document must themselves be free in the same sense. It
+complements the GNU General Public License, which is a copyleft
+license designed for free software.
+
+We have designed this License in order to use it for manuals for free
+software, because free software needs free documentation: a free
+program should come with manuals providing the same freedoms that the
+software does. But this License is not limited to software manuals;
+it can be used for any textual work, regardless of subject matter or
+whether it is published as a printed book. We recommend this License
+principally for works whose purpose is instruction or reference.
+
+@item
+APPLICABILITY AND DEFINITIONS
+
+This License applies to any manual or other work, in any medium, that
+contains a notice placed by the copyright holder saying it can be
+distributed under the terms of this License. Such a notice grants a
+world-wide, royalty-free license, unlimited in duration, to use that
+work under the conditions stated herein. The ``Document'', below,
+refers to any such manual or work. Any member of the public is a
+licensee, and is addressed as ``you''. You accept the license if you
+copy, modify or distribute the work in a way requiring permission
+under copyright law.
+
+A ``Modified Version'' of the Document means any work containing the
+Document or a portion of it, either copied verbatim, or with
+modifications and/or translated into another language.
+
+A ``Secondary Section'' is a named appendix or a front-matter section
+of the Document that deals exclusively with the relationship of the
+publishers or authors of the Document to the Document's overall
+subject (or to related matters) and contains nothing that could fall
+directly within that overall subject. (Thus, if the Document is in
+part a textbook of mathematics, a Secondary Section may not explain
+any mathematics.) The relationship could be a matter of historical
+connection with the subject or with related matters, or of legal,
+commercial, philosophical, ethical or political position regarding
+them.
+
+The ``Invariant Sections'' are certain Secondary Sections whose titles
+are designated, as being those of Invariant Sections, in the notice
+that says that the Document is released under this License. If a
+section does not fit the above definition of Secondary then it is not
+allowed to be designated as Invariant. The Document may contain zero
+Invariant Sections. If the Document does not identify any Invariant
+Sections then there are none.
+
+The ``Cover Texts'' are certain short passages of text that are listed,
+as Front-Cover Texts or Back-Cover Texts, in the notice that says that
+the Document is released under this License. A Front-Cover Text may
+be at most 5 words, and a Back-Cover Text may be at most 25 words.
+
+A ``Transparent'' copy of the Document means a machine-readable copy,
+represented in a format whose specification is available to the
+general public, that is suitable for revising the document
+straightforwardly with generic text editors or (for images composed of
+pixels) generic paint programs or (for drawings) some widely available
+drawing editor, and that is suitable for input to text formatters or
+for automatic translation to a variety of formats suitable for input
+to text formatters. A copy made in an otherwise Transparent file
+format whose markup, or absence of markup, has been arranged to thwart
+or discourage subsequent modification by readers is not Transparent.
+An image format is not Transparent if used for any substantial amount
+of text. A copy that is not ``Transparent'' is called ``Opaque''.
+
+Examples of suitable formats for Transparent copies include plain
+@sc{ascii} without markup, Texinfo input format, La@TeX{} input
+format, @acronym{SGML} or @acronym{XML} using a publicly available
+@acronym{DTD}, and standard-conforming simple @acronym{HTML},
+PostScript or @acronym{PDF} designed for human modification. Examples
+of transparent image formats include @acronym{PNG}, @acronym{XCF} and
+@acronym{JPG}. Opaque formats include proprietary formats that can be
+read and edited only by proprietary word processors, @acronym{SGML} or
+@acronym{XML} for which the @acronym{DTD} and/or processing tools are
+not generally available, and the machine-generated @acronym{HTML},
+PostScript or @acronym{PDF} produced by some word processors for
+output purposes only.
+
+The ``Title Page'' means, for a printed book, the title page itself,
+plus such following pages as are needed to hold, legibly, the material
+this License requires to appear in the title page. For works in
+formats which do not have any title page as such, ``Title Page'' means
+the text near the most prominent appearance of the work's title,
+preceding the beginning of the body of the text.
+
+The ``publisher'' means any person or entity that distributes copies
+of the Document to the public.
+
+A section ``Entitled XYZ'' means a named subunit of the Document whose
+title either is precisely XYZ or contains XYZ in parentheses following
+text that translates XYZ in another language. (Here XYZ stands for a
+specific section name mentioned below, such as ``Acknowledgements'',
+``Dedications'', ``Endorsements'', or ``History''.) To ``Preserve the Title''
+of such a section when you modify the Document means that it remains a
+section ``Entitled XYZ'' according to this definition.
+
+The Document may include Warranty Disclaimers next to the notice which
+states that this License applies to the Document. These Warranty
+Disclaimers are considered to be included by reference in this
+License, but only as regards disclaiming warranties: any other
+implication that these Warranty Disclaimers may have is void and has
+no effect on the meaning of this License.
+
+@item
+VERBATIM COPYING
+
+You may copy and distribute the Document in any medium, either
+commercially or noncommercially, provided that this License, the
+copyright notices, and the license notice saying this License applies
+to the Document are reproduced in all copies, and that you add no other
+conditions whatsoever to those of this License. You may not use
+technical measures to obstruct or control the reading or further
+copying of the copies you make or distribute. However, you may accept
+compensation in exchange for copies. If you distribute a large enough
+number of copies you must also follow the conditions in section 3.
+
+You may also lend copies, under the same conditions stated above, and
+you may publicly display copies.
+
+@item
+COPYING IN QUANTITY
+
+If you publish printed copies (or copies in media that commonly have
+printed covers) of the Document, numbering more than 100, and the
+Document's license notice requires Cover Texts, you must enclose the
+copies in covers that carry, clearly and legibly, all these Cover
+Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on
+the back cover. Both covers must also clearly and legibly identify
+you as the publisher of these copies. The front cover must present
+the full title with all words of the title equally prominent and
+visible. You may add other material on the covers in addition.
+Copying with changes limited to the covers, as long as they preserve
+the title of the Document and satisfy these conditions, can be treated
+as verbatim copying in other respects.
+
+If the required texts for either cover are too voluminous to fit
+legibly, you should put the first ones listed (as many as fit
+reasonably) on the actual cover, and continue the rest onto adjacent
+pages.
+
+If you publish or distribute Opaque copies of the Document numbering
+more than 100, you must either include a machine-readable Transparent
+copy along with each Opaque copy, or state in or with each Opaque copy
+a computer-network location from which the general network-using
+public has access to download using public-standard network protocols
+a complete Transparent copy of the Document, free of added material.
+If you use the latter option, you must take reasonably prudent steps,
+when you begin distribution of Opaque copies in quantity, to ensure
+that this Transparent copy will remain thus accessible at the stated
+location until at least one year after the last time you distribute an
+Opaque copy (directly or through your agents or retailers) of that
+edition to the public.
+
+It is requested, but not required, that you contact the authors of the
+Document well before redistributing any large number of copies, to give
+them a chance to provide you with an updated version of the Document.
+
+@item
+MODIFICATIONS
+
+You may copy and distribute a Modified Version of the Document under
+the conditions of sections 2 and 3 above, provided that you release
+the Modified Version under precisely this License, with the Modified
+Version filling the role of the Document, thus licensing distribution
+and modification of the Modified Version to whoever possesses a copy
+of it. In addition, you must do these things in the Modified Version:
+
+@enumerate A
+@item
+Use in the Title Page (and on the covers, if any) a title distinct
+from that of the Document, and from those of previous versions
+(which should, if there were any, be listed in the History section
+of the Document). You may use the same title as a previous version
+if the original publisher of that version gives permission.
+
+@item
+List on the Title Page, as authors, one or more persons or entities
+responsible for authorship of the modifications in the Modified
+Version, together with at least five of the principal authors of the
+Document (all of its principal authors, if it has fewer than five),
+unless they release you from this requirement.
+
+@item
+State on the Title page the name of the publisher of the
+Modified Version, as the publisher.
+
+@item
+Preserve all the copyright notices of the Document.
+
+@item
+Add an appropriate copyright notice for your modifications
+adjacent to the other copyright notices.
+
+@item
+Include, immediately after the copyright notices, a license notice
+giving the public permission to use the Modified Version under the
+terms of this License, in the form shown in the Addendum below.
+
+@item
+Preserve in that license notice the full lists of Invariant Sections
+and required Cover Texts given in the Document's license notice.
+
+@item
+Include an unaltered copy of this License.
+
+@item
+Preserve the section Entitled ``History'', Preserve its Title, and add
+to it an item stating at least the title, year, new authors, and
+publisher of the Modified Version as given on the Title Page. If
+there is no section Entitled ``History'' in the Document, create one
+stating the title, year, authors, and publisher of the Document as
+given on its Title Page, then add an item describing the Modified
+Version as stated in the previous sentence.
+
+@item
+Preserve the network location, if any, given in the Document for
+public access to a Transparent copy of the Document, and likewise
+the network locations given in the Document for previous versions
+it was based on. These may be placed in the ``History'' section.
+You may omit a network location for a work that was published at
+least four years before the Document itself, or if the original
+publisher of the version it refers to gives permission.
+
+@item
+For any section Entitled ``Acknowledgements'' or ``Dedications'', Preserve
+the Title of the section, and preserve in the section all the
+substance and tone of each of the contributor acknowledgements and/or
+dedications given therein.
+
+@item
+Preserve all the Invariant Sections of the Document,
+unaltered in their text and in their titles. Section numbers
+or the equivalent are not considered part of the section titles.
+
+@item
+Delete any section Entitled ``Endorsements''. Such a section
+may not be included in the Modified Version.
+
+@item
+Do not retitle any existing section to be Entitled ``Endorsements'' or
+to conflict in title with any Invariant Section.
+
+@item
+Preserve any Warranty Disclaimers.
+@end enumerate
+
+If the Modified Version includes new front-matter sections or
+appendices that qualify as Secondary Sections and contain no material
+copied from the Document, you may at your option designate some or all
+of these sections as invariant. To do this, add their titles to the
+list of Invariant Sections in the Modified Version's license notice.
+These titles must be distinct from any other section titles.
+
+You may add a section Entitled ``Endorsements'', provided it contains
+nothing but endorsements of your Modified Version by various
+parties---for example, statements of peer review or that the text has
+been approved by an organization as the authoritative definition of a
+standard.
+
+You may add a passage of up to five words as a Front-Cover Text, and a
+passage of up to 25 words as a Back-Cover Text, to the end of the list
+of Cover Texts in the Modified Version. Only one passage of
+Front-Cover Text and one of Back-Cover Text may be added by (or
+through arrangements made by) any one entity. If the Document already
+includes a cover text for the same cover, previously added by you or
+by arrangement made by the same entity you are acting on behalf of,
+you may not add another; but you may replace the old one, on explicit
+permission from the previous publisher that added the old one.
+
+The author(s) and publisher(s) of the Document do not by this License
+give permission to use their names for publicity for or to assert or
+imply endorsement of any Modified Version.
+
+@item
+COMBINING DOCUMENTS
+
+You may combine the Document with other documents released under this
+License, under the terms defined in section 4 above for modified
+versions, provided that you include in the combination all of the
+Invariant Sections of all of the original documents, unmodified, and
+list them all as Invariant Sections of your combined work in its
+license notice, and that you preserve all their Warranty Disclaimers.
+
+The combined work need only contain one copy of this License, and
+multiple identical Invariant Sections may be replaced with a single
+copy. If there are multiple Invariant Sections with the same name but
+different contents, make the title of each such section unique by
+adding at the end of it, in parentheses, the name of the original
+author or publisher of that section if known, or else a unique number.
+Make the same adjustment to the section titles in the list of
+Invariant Sections in the license notice of the combined work.
+
+In the combination, you must combine any sections Entitled ``History''
+in the various original documents, forming one section Entitled
+``History''; likewise combine any sections Entitled ``Acknowledgements'',
+and any sections Entitled ``Dedications''. You must delete all
+sections Entitled ``Endorsements.''
+
+@item
+COLLECTIONS OF DOCUMENTS
+
+You may make a collection consisting of the Document and other documents
+released under this License, and replace the individual copies of this
+License in the various documents with a single copy that is included in
+the collection, provided that you follow the rules of this License for
+verbatim copying of each of the documents in all other respects.
+
+You may extract a single document from such a collection, and distribute
+it individually under this License, provided you insert a copy of this
+License into the extracted document, and follow this License in all
+other respects regarding verbatim copying of that document.
+
+@item
+AGGREGATION WITH INDEPENDENT WORKS
+
+A compilation of the Document or its derivatives with other separate
+and independent documents or works, in or on a volume of a storage or
+distribution medium, is called an ``aggregate'' if the copyright
+resulting from the compilation is not used to limit the legal rights
+of the compilation's users beyond what the individual works permit.
+When the Document is included in an aggregate, this License does not
+apply to the other works in the aggregate which are not themselves
+derivative works of the Document.
+
+If the Cover Text requirement of section 3 is applicable to these
+copies of the Document, then if the Document is less than one half of
+the entire aggregate, the Document's Cover Texts may be placed on
+covers that bracket the Document within the aggregate, or the
+electronic equivalent of covers if the Document is in electronic form.
+Otherwise they must appear on printed covers that bracket the whole
+aggregate.
+
+@item
+TRANSLATION
+
+Translation is considered a kind of modification, so you may
+distribute translations of the Document under the terms of section 4.
+Replacing Invariant Sections with translations requires special
+permission from their copyright holders, but you may include
+translations of some or all Invariant Sections in addition to the
+original versions of these Invariant Sections. You may include a
+translation of this License, and all the license notices in the
+Document, and any Warranty Disclaimers, provided that you also include
+the original English version of this License and the original versions
+of those notices and disclaimers. In case of a disagreement between
+the translation and the original version of this License or a notice
+or disclaimer, the original version will prevail.
+
+If a section in the Document is Entitled ``Acknowledgements'',
+``Dedications'', or ``History'', the requirement (section 4) to Preserve
+its Title (section 1) will typically require changing the actual
+title.
+
+@item
+TERMINATION
+
+You may not copy, modify, sublicense, or distribute the Document
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense, or distribute it is void, and
+will automatically terminate your rights under this License.
+
+However, if you cease all violation of this License, then your license
+from a particular copyright holder is reinstated (a) provisionally,
+unless and until the copyright holder explicitly and finally
+terminates your license, and (b) permanently, if the copyright holder
+fails to notify you of the violation by some reasonable means prior to
+60 days after the cessation.
+
+Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, receipt of a copy of some or all of the same material does
+not give you any rights to use it.
+
+@item
+FUTURE REVISIONS OF THIS LICENSE
+
+The Free Software Foundation may publish new, revised versions
+of the GNU Free Documentation 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. See
+@uref{http://www.gnu.org/copyleft/}.
+
+Each version of the License is given a distinguishing version number.
+If the Document specifies that a particular numbered version of this
+License ``or any later version'' applies to it, you have the option of
+following the terms and conditions either of that specified version or
+of any later version that has been published (not as a draft) by the
+Free Software Foundation. If the Document does not specify a version
+number of this License, you may choose any version ever published (not
+as a draft) by the Free Software Foundation. If the Document
+specifies that a proxy can decide which future versions of this
+License can be used, that proxy's public statement of acceptance of a
+version permanently authorizes you to choose that version for the
+Document.
+
+@item
+RELICENSING
+
+``Massive Multiauthor Collaboration Site'' (or ``MMC Site'') means any
+World Wide Web server that publishes copyrightable works and also
+provides prominent facilities for anybody to edit those works. A
+public wiki that anybody can edit is an example of such a server. A
+``Massive Multiauthor Collaboration'' (or ``MMC'') contained in the
+site means any set of copyrightable works thus published on the MMC
+site.
+
+``CC-BY-SA'' means the Creative Commons Attribution-Share Alike 3.0
+license published by Creative Commons Corporation, a not-for-profit
+corporation with a principal place of business in San Francisco,
+California, as well as future copyleft versions of that license
+published by that same organization.
+
+``Incorporate'' means to publish or republish a Document, in whole or
+in part, as part of another Document.
+
+An MMC is ``eligible for relicensing'' if it is licensed under this
+License, and if all works that were first published under this License
+somewhere other than this MMC, and subsequently incorporated in whole
+or in part into the MMC, (1) had no cover texts or invariant sections,
+and (2) were thus incorporated prior to November 1, 2008.
+
+The operator of an MMC Site may republish an MMC contained in the site
+under CC-BY-SA on the same site at any time before August 1, 2009,
+provided the MMC is eligible for relicensing.
+
+@end enumerate
+
+@page
+@heading ADDENDUM: How to use this License for your documents
+
+To use this License in a document you have written, include a copy of
+the License in the document and put the following copyright and
+license notices just after the title page:
+
+@smallexample
+@group
+ Copyright (C) @var{year} @var{your name}.
+ Permission is granted to copy, distribute and/or modify this document
+ under the terms of the GNU Free Documentation License, Version 1.3
+ or any later version published by the Free Software Foundation;
+ with no Invariant Sections, no Front-Cover Texts, and no Back-Cover
+ Texts. A copy of the license is included in the section entitled ``GNU
+ Free Documentation License''.
+@end group
+@end smallexample
+
+If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts,
+replace the ``with@dots{}Texts.'' line with this:
+
+@smallexample
+@group
+ with the Invariant Sections being @var{list their titles}, with
+ the Front-Cover Texts being @var{list}, and with the Back-Cover Texts
+ being @var{list}.
+@end group
+@end smallexample
+
+If you have Invariant Sections without Cover Texts, or some other
+combination of the three, merge those two alternatives to suit the
+situation.
+
+If your document contains nontrivial examples of program code, we
+recommend releasing these examples in parallel under your choice of
+free software license, such as the GNU General Public License,
+to permit their use in free software.
+
+@c Local Variables:
+@c ispell-local-pdict: "ispell-dict"
+@c End:
+
diff --git a/bfd/doc/format.texi b/bfd/doc/format.texi
new file mode 100644
index 0000000..9674acf
--- /dev/null
+++ b/bfd/doc/format.texi
@@ -0,0 +1,112 @@
+@section File formats
+A format is a BFD concept of high level file contents type. The
+formats supported by BFD are:
+
+@itemize @bullet
+
+@item
+@code{bfd_object}
+@end itemize
+The BFD may contain data, symbols, relocations and debug info.
+
+@itemize @bullet
+
+@item
+@code{bfd_archive}
+@end itemize
+The BFD contains other BFDs and an optional index.
+
+@itemize @bullet
+
+@item
+@code{bfd_core}
+@end itemize
+The BFD contains the result of an executable core dump.
+
+@subsection File format functions
+
+
+@findex bfd_check_format
+@subsubsection @code{bfd_check_format}
+@strong{Synopsis}
+@example
+bfd_boolean bfd_check_format (bfd *abfd, bfd_format format);
+@end example
+@strong{Description}@*
+Verify if the file attached to the BFD @var{abfd} is compatible
+with the format @var{format} (i.e., one of @code{bfd_object},
+@code{bfd_archive} or @code{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
+@code{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 @code{TRUE} on success, otherwise @code{FALSE}
+with one of the following error codes:
+
+@itemize @bullet
+
+@item
+@code{bfd_error_invalid_operation} -
+if @code{format} is not one of @code{bfd_object}, @code{bfd_archive} or
+@code{bfd_core}.
+
+@item
+@code{bfd_error_system_call} -
+if an error occured during a read - even some file mismatches
+can cause bfd_error_system_calls.
+
+@item
+@code{file_not_recognised} -
+none of the backends recognised the file format.
+
+@item
+@code{bfd_error_file_ambiguously_recognized} -
+more than one backend recognised the file format.
+@end itemize
+
+@findex bfd_check_format_matches
+@subsubsection @code{bfd_check_format_matches}
+@strong{Synopsis}
+@example
+bfd_boolean bfd_check_format_matches
+ (bfd *abfd, bfd_format format, char ***matching);
+@end example
+@strong{Description}@*
+Like @code{bfd_check_format}, except when it returns FALSE with
+@code{bfd_errno} set to @code{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 @code{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.
+
+@findex bfd_set_format
+@subsubsection @code{bfd_set_format}
+@strong{Synopsis}
+@example
+bfd_boolean bfd_set_format (bfd *abfd, bfd_format format);
+@end example
+@strong{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.
+
+@findex bfd_format_string
+@subsubsection @code{bfd_format_string}
+@strong{Synopsis}
+@example
+const char *bfd_format_string (bfd_format format);
+@end example
+@strong{Description}@*
+Return a pointer to a const string
+@code{invalid}, @code{object}, @code{archive}, @code{core}, or @code{unknown},
+depending upon the value of @var{format}.
+
diff --git a/bfd/doc/hash.texi b/bfd/doc/hash.texi
new file mode 100644
index 0000000..88d9585
--- /dev/null
+++ b/bfd/doc/hash.texi
@@ -0,0 +1,247 @@
+@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 @code{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
+
+@node 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 @code{struct
+bfd_hash_table} (defined in @code{bfd.h}) and call
+@code{bfd_hash_table_init} (if you know approximately how many
+entries you will need, the function @code{bfd_hash_table_init_n},
+which takes a @var{size} argument, may be used).
+@code{bfd_hash_table_init} returns @code{FALSE} if some sort of
+error occurs.
+
+@findex bfd_hash_newfunc
+The function @code{bfd_hash_table_init} take as an argument a
+function to use to create new entries. For a basic hash
+table, use the function @code{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
+@code{bfd_hash_table_init} will create an objalloc which will be
+used to allocate new entries. You may allocate memory on this
+objalloc using @code{bfd_hash_allocate}.
+
+@findex bfd_hash_table_free
+Use @code{bfd_hash_table_free} to free up all the memory that has
+been allocated for a hash table. This will not free up the
+@code{struct bfd_hash_table} itself, which you must provide.
+
+@findex bfd_hash_set_default_size
+Use @code{bfd_hash_set_default_size} to set the default size of
+hash table to use.
+
+@node 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 @code{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 @code{FALSE}, @code{bfd_hash_lookup}
+will look up a string. If the string is found, it will
+returns a pointer to a @code{struct bfd_hash_entry}. If the
+string is not found in the table @code{bfd_hash_lookup} will
+return @code{NULL}. You should not modify any of the fields in
+the returns @code{struct bfd_hash_entry}.
+
+If the @var{create} argument is @code{TRUE}, the string will be
+entered into the hash table if it is not already there.
+Either way a pointer to a @code{struct bfd_hash_entry} will be
+returned, either to the existing structure or to a newly
+created one. In this case, a @code{NULL} return means that an
+error occurred.
+
+If the @var{create} argument is @code{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 @code{FALSE}, you must be careful not to
+deallocate or modify the string as long as the hash table
+exists.
+
+@node 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 @code{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.
+
+@code{bfd_hash_traverse} takes as arguments a function and a
+generic @code{void *} pointer. The function is called with a
+hash table entry (a @code{struct bfd_hash_entry *}) and the
+generic pointer passed to @code{bfd_hash_traverse}. The function
+must return a @code{boolean} value, which indicates whether to
+continue traversing the hash table. If the function returns
+@code{FALSE}, @code{bfd_hash_traverse} will stop the traversal and
+return immediately.
+
+@node 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 @code{bfdlink.h}. The
+functions are in @code{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
+
+@node 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 @code{struct bfd_hash_entry}, which is defined in
+@code{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 @code{struct bfd_hash_table}.
+
+For example, the linker hash table defines @code{struct
+bfd_link_hash_entry} (in @code{bfdlink.h}). The first field,
+@code{root}, is of type @code{struct bfd_hash_entry}. Similarly,
+the first field in @code{struct bfd_link_hash_table}, @code{table},
+is of type @code{struct bfd_hash_table}.
+
+@node 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 @code{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 @code{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} (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 == NULL)
+ @{
+ ret = bfd_hash_allocate (table, sizeof (* ret));
+ if (ret == 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;
+@}
+@end example
+@strong{Description}@*
+The creation routine for the linker hash table, which is in
+@code{linker.c}, looks just like this example.
+@var{function_name} is @code{_bfd_link_hash_newfunc}.
+@var{entry_type} is @code{struct bfd_link_hash_entry}.
+@var{base_newfunc} is @code{bfd_hash_newfunc}, the creation
+routine for a basic hash table.
+
+@code{_bfd_link_hash_newfunc} also initializes the local fields
+in a linker hash table entry: @code{type}, @code{written} and
+@code{next}.
+
+@node 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 @code{_bfd_link_hash_table_init} in @code{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 @code{bfd_link_hash_lookup} in
+@code{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
+@code{bfd_link_hash_traverse} in @code{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 @code{aout_link_hash_lookup} and
+@code{aout_link_hash_traverse} in aoutx.h.
+
diff --git a/bfd/doc/header.sed b/bfd/doc/header.sed
new file mode 100644
index 0000000..c58dc60
--- /dev/null
+++ b/bfd/doc/header.sed
@@ -0,0 +1,13 @@
+s|[ ][ ]*| |g
+s|\(.*\) [^ ]*header.sed.*|\1|
+s|[^ ]*/||g
+s|^ *|"|
+s| |", "|g
+s|$|"|
+s|, \([^ ]*\)$| and \1|
+s|^|/* DO NOT EDIT! -*- buffer-read-only: t -*- This file is automatically generated from |
+s|\(.\{60\}[^ ]* \)|\1\
+ |g
+s|$|.\
+ Run "make headers" in your build bfd/ to regenerate. */\
+|
diff --git a/bfd/doc/init.texi b/bfd/doc/init.texi
new file mode 100644
index 0000000..ab735f8
--- /dev/null
+++ b/bfd/doc/init.texi
@@ -0,0 +1,16 @@
+@section Initialization
+
+
+@subsection Initialization functions
+These are the functions that handle initializing a BFD.
+
+@findex bfd_init
+@subsubsection @code{bfd_init}
+@strong{Synopsis}
+@example
+void bfd_init (void);
+@end example
+@strong{Description}@*
+This routine must be called before any other BFD function to
+initialize magical internal data structures.
+
diff --git a/bfd/doc/libbfd.texi b/bfd/doc/libbfd.texi
new file mode 100644
index 0000000..b0b0300
--- /dev/null
+++ b/bfd/doc/libbfd.texi
@@ -0,0 +1,179 @@
+@section Implementation details
+
+
+@subsection Internal functions
+
+
+@strong{Description}@*
+These routines are used within BFD.
+They are not intended for export, but are documented here for
+completeness.
+
+@findex bfd_write_bigendian_4byte_int
+@subsubsection @code{bfd_write_bigendian_4byte_int}
+@strong{Synopsis}
+@example
+bfd_boolean bfd_write_bigendian_4byte_int (bfd *, unsigned int);
+@end example
+@strong{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.
+
+@findex bfd_put_size
+@subsubsection @code{bfd_put_size}
+@findex bfd_get_size
+@subsubsection @code{bfd_get_size}
+@strong{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 @code{GET_WORD}
+to either @code{bfd_get_32} or @code{bfd_get_64}.
+
+In the put routines, @var{val} must be a @code{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 @code{lint}
+or @code{gcc -Wall} from detecting sins such as passing a pointer.
+To detect calling these with less than a @code{bfd_vma}, use
+@code{gcc -Wconversion} on a host with 64 bit @code{bfd_vma}'s.
+@example
+
+/* Byte swapping macros for user section data. */
+
+#define bfd_put_8(abfd, val, ptr) \
+ ((void) (*((unsigned char *) (ptr)) = (val) & 0xff))
+#define bfd_put_signed_8 \
+ bfd_put_8
+#define bfd_get_8(abfd, ptr) \
+ (*(const unsigned char *) (ptr) & 0xff)
+#define bfd_get_signed_8(abfd, ptr) \
+ (((*(const unsigned char *) (ptr) & 0xff) ^ 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))
+
+#define bfd_get(bits, abfd, ptr) \
+ ((bits) == 8 ? (bfd_vma) bfd_get_8 (abfd, ptr) \
+ : (bits) == 16 ? bfd_get_16 (abfd, ptr) \
+ : (bits) == 32 ? bfd_get_32 (abfd, ptr) \
+ : (bits) == 64 ? bfd_get_64 (abfd, ptr) \
+ : (abort (), (bfd_vma) - 1))
+
+#define bfd_put(bits, abfd, val, ptr) \
+ ((bits) == 8 ? bfd_put_8 (abfd, val, ptr) \
+ : (bits) == 16 ? bfd_put_16 (abfd, val, ptr) \
+ : (bits) == 32 ? bfd_put_32 (abfd, val, ptr) \
+ : (bits) == 64 ? bfd_put_64 (abfd, val, ptr) \
+ : (abort (), (void) 0))
+
+@end example
+
+@findex bfd_h_put_size
+@subsubsection @code{bfd_h_put_size}
+@strong{Description}@*
+These macros have the same function as their @code{bfd_get_x}
+brethren, 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.
+@example
+
+/* 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))
+
+/* Aliases for the above, which should eventually go away. */
+
+#define H_PUT_64 bfd_h_put_64
+#define H_PUT_32 bfd_h_put_32
+#define H_PUT_16 bfd_h_put_16
+#define H_PUT_8 bfd_h_put_8
+#define H_PUT_S64 bfd_h_put_signed_64
+#define H_PUT_S32 bfd_h_put_signed_32
+#define H_PUT_S16 bfd_h_put_signed_16
+#define H_PUT_S8 bfd_h_put_signed_8
+#define H_GET_64 bfd_h_get_64
+#define H_GET_32 bfd_h_get_32
+#define H_GET_16 bfd_h_get_16
+#define H_GET_8 bfd_h_get_8
+#define H_GET_S64 bfd_h_get_signed_64
+#define H_GET_S32 bfd_h_get_signed_32
+#define H_GET_S16 bfd_h_get_signed_16
+#define H_GET_S8 bfd_h_get_signed_8
+
+
+@end example
+
+@findex bfd_log2
+@subsubsection @code{bfd_log2}
+@strong{Synopsis}
+@example
+unsigned int bfd_log2 (bfd_vma x);
+@end example
+@strong{Description}@*
+Return the log base 2 of the value supplied, rounded up. E.g., an
+@var{x} of 1025 returns 11. A @var{x} of 0 returns 0.
+
diff --git a/bfd/doc/linker.texi b/bfd/doc/linker.texi
new file mode 100644
index 0000000..81c208b
--- /dev/null
+++ b/bfd/doc/linker.texi
@@ -0,0 +1,420 @@
+@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 @code{struct bfd_link_info} structure (defined in
+@code{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 @code{linker.c}, and use the
+header file @code{genlink.h}. As of this writing, the only back
+ends which have implemented versions of these routines are
+a.out (in @code{aoutx.h}) and ECOFF (in @code{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
+
+@node 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 @code{struct bfd_link_hash_table} described in
+@code{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 @code{_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 @code{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 relocatable
+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 @code{struct bfd_link_hash_table}. The a.out linker
+hash table is created by the function
+@code{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.
+
+@node 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 @code{_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
+@code{NAME(aout,link_add_symbols)}.
+
+@menu
+* Differing file formats::
+* Adding symbols from an object file::
+* Adding symbols from an archive::
+@end menu
+
+@node 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
+@code{_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
+@code{_bfd_link_hash_table_create} vector. All the
+@code{_bfd_link_add_symbols} function can assume about the hash
+table is that it is derived from @code{struct
+bfd_link_hash_table}.
+
+Sometimes the @code{_bfd_link_add_symbols} function must store
+some information in the hash table entry to be used by the
+@code{_bfd_final_link} function. In such a case the output bfd
+xvec must be checked to make sure that the hash table was
+created by an object file of the same format.
+
+The @code{_bfd_final_link} routine must be prepared to handle a
+hash entry without any extra information added by the
+@code{_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 @code{ecoff_link_add_externals} for an example of how to
+check the output bfd before saving information (in this
+case, the ECOFF external symbol debugging information) in a
+hash table entry.
+
+@node 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 @code{_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
+@code{_bfd_generic_link_add_one_symbol}. The
+@code{_bfd_link_add_symbols} routine is responsible for reading
+all the symbols from the object file and passing the correct
+information to @code{_bfd_generic_link_add_one_symbol}.
+
+The @code{_bfd_link_add_symbols} routine should not use
+@code{bfd_canonicalize_symtab} to read the symbols. The point of
+providing this routine is to avoid the overhead of converting
+the symbols into generic @code{asymbol} structures.
+
+@findex _bfd_generic_link_add_one_symbol
+@code{_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 @code{BSF_WEAK} or
+@code{BSF_INDIRECT}. The section is a section in the object
+file, or something like @code{bfd_und_section_ptr} for an undefined
+symbol or @code{bfd_com_section_ptr} for a common symbol.
+
+If the @code{_bfd_final_link} routine is also going to need to
+read the symbol information, the @code{_bfd_link_add_symbols}
+routine should save it somewhere attached to the object file
+BFD. However, the information should only be saved if the
+@code{keep_memory} field of the @code{info} argument is TRUE, so
+that the @code{-no-keep-memory} linker switch is effective.
+
+The a.out function which adds symbols from an object file is
+@code{aout_link_add_object_symbols}, and most of the interesting
+work is in @code{aout_link_add_symbols}. The latter saves
+pointers to the hash tables entries created by
+@code{_bfd_generic_link_add_one_symbol} indexed by symbol number,
+so that the @code{_bfd_final_link} routine does not have to call
+the hash table lookup routine to locate the entry.
+
+@node 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 @code{_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
+@code{add_archive_element} linker callback, and it must add the
+symbols from the object file to the linker hash table. (The
+callback may in fact indicate that a replacement BFD should be
+used, in which case the symbols from that BFD should be added
+to the linker hash table instead.)
+
+@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
+@code{_bfd_generic_link_add_archive_symbols} function.
+@code{_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. If the element is to
+be included, the @code{add_archive_element} linker callback
+routine must be called with the element as an argument, and
+the element's symbols must be added to the linker hash table
+just as though the element had itself been passed to the
+@code{_bfd_link_add_symbols} function.
+
+When the a.out @code{_bfd_link_add_symbols} function receives an
+archive, it calls @code{_bfd_generic_link_add_archive_symbols}
+passing @code{aout_link_check_archive_element} as the function
+argument. @code{aout_link_check_archive_element} calls
+@code{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 @code{add_archive_element} callback and then
+@code{aout_link_check_archive_element} calls
+@code{aout_link_add_symbols} to actually add the symbols to the
+linker hash table - possibly those of a substitute BFD, if the
+@code{add_archive_element} callback avails itself of that option.
+
+The ECOFF back end is unusual in that it does not normally
+call @code{_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.
+
+@node 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 @code{_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 relocatable 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 @code{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
+@code{_bfd_final_link} routine is @code{NAME(aout,final_link)}.
+
+@menu
+* Information provided by the linker::
+* Relocating the section contents::
+* Writing the symbol table::
+@end menu
+
+@node 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 @code{_bfd_final_link} entry point,
+it sets up some data structures for the function to use.
+
+The @code{input_bfds} field of the @code{bfd_link_info} structure
+will point to a list of all the input files included in the
+link. These files are linked through the @code{link.next} field
+of the @code{bfd} structure.
+
+Each section in the output file will have a list of
+@code{link_order} structures attached to the @code{map_head.link_order}
+field (the @code{link_order} structure is defined in
+@code{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 relocatable object file.
+
+@node Relocating the section contents, Writing the symbol table, Information provided by the linker, Performing the Final Link
+@subsubsection Relocating the section contents
+The @code{_bfd_final_link} function should look through the
+@code{link_order} structures attached to each section of the
+output file. Each @code{link_order} structure should either be
+handled specially, or it should be passed to the function
+@code{_bfd_default_link_order} which will do the right thing
+(@code{_bfd_default_link_order} is defined in @code{linker.c}).
+
+For efficiency, a @code{link_order} of type
+@code{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 @code{link_order} describes part of an
+output section in terms of a section belonging to one of the
+input files. The @code{_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 relocatable link, the
+relocs themselves must also be modified and written out.
+
+@findex _bfd_relocate_contents
+@findex _bfd_final_link_relocate
+The functions @code{_bfd_relocate_contents} and
+@code{_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 @code{reloc_howto_type} argument
+which describes the relocation to perform. These functions
+are defined in @code{reloc.c}.
+
+The a.out function which handles reading, relocating, and
+writing section contents is @code{aout_link_input_section}. The
+actual relocation is done in @code{aout_link_input_section_std}
+and @code{aout_link_input_section_ext}.
+
+@node Writing the symbol table, , Relocating the section contents, Performing the Final Link
+@subsubsection Writing the symbol table
+The @code{_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 @code{strip} and @code{discard} fields of the
+@code{bfd_link_info} structure.
+
+The local symbols of the input files will not have been
+entered into the linker hash table. The @code{_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 @code{link_order} structures, or it may be
+done by stepping through the @code{input_bfds} list.
+
+The @code{_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 @code{strip} field of the @code{bfd_link_info} structure
+controls which symbols are written out. The possible values
+are listed in @code{bfdlink.h}. If the value is @code{strip_some},
+then the @code{keep_hash} field of the @code{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 @code{strip} field of the @code{bfd_link_info} structure
+permits local symbols to be written out, the @code{discard} field
+is used to further controls which local symbols are included
+in the output file. If the value is @code{discard_l}, then all
+local symbols which begin with a certain prefix are discarded;
+this is controlled by the @code{bfd_is_local_label_name} entry point.
+
+The a.out backend handles symbols by calling
+@code{aout_link_write_symbols} on each input BFD and then
+traversing the global hash table with the function
+@code{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 @code{NAME(aout,final_link)}.
+
+@findex bfd_link_split_section
+@subsubsection @code{bfd_link_split_section}
+@strong{Synopsis}
+@example
+bfd_boolean bfd_link_split_section (bfd *abfd, asection *sec);
+@end example
+@strong{Description}@*
+Return nonzero if @var{sec} should be split during a
+reloceatable or final link.
+@example
+#define bfd_link_split_section(abfd, sec) \
+ BFD_SEND (abfd, _bfd_link_split_section, (abfd, sec))
+
+@end example
+
+@findex bfd_section_already_linked
+@subsubsection @code{bfd_section_already_linked}
+@strong{Synopsis}
+@example
+bfd_boolean bfd_section_already_linked (bfd *abfd,
+ asection *sec,
+ struct bfd_link_info *info);
+@end example
+@strong{Description}@*
+Check if @var{data} has been already linked during a reloceatable
+or final link. Return TRUE if it has.
+@example
+#define bfd_section_already_linked(abfd, sec, info) \
+ BFD_SEND (abfd, _section_already_linked, (abfd, sec, info))
+
+@end example
+
+@findex bfd_generic_define_common_symbol
+@subsubsection @code{bfd_generic_define_common_symbol}
+@strong{Synopsis}
+@example
+bfd_boolean bfd_generic_define_common_symbol
+ (bfd *output_bfd, struct bfd_link_info *info,
+ struct bfd_link_hash_entry *h);
+@end example
+@strong{Description}@*
+Convert common symbol @var{h} into a defined symbol.
+Return TRUE on success and FALSE on failure.
+@example
+#define bfd_define_common_symbol(output_bfd, info, h) \
+ BFD_SEND (output_bfd, _bfd_define_common_symbol, (output_bfd, info, h))
+
+@end example
+
+@findex bfd_find_version_for_sym
+@subsubsection @code{bfd_find_version_for_sym}
+@strong{Synopsis}
+@example
+struct bfd_elf_version_tree * bfd_find_version_for_sym
+ (struct bfd_elf_version_tree *verdefs,
+ const char *sym_name, bfd_boolean *hide);
+@end example
+@strong{Description}@*
+Search an elf version script tree for symbol versioning
+info and export / don't-export status for a given symbol.
+Return non-NULL on success and NULL on failure; also sets
+the output @samp{hide} boolean parameter.
+
+@findex bfd_hide_sym_by_version
+@subsubsection @code{bfd_hide_sym_by_version}
+@strong{Synopsis}
+@example
+bfd_boolean bfd_hide_sym_by_version
+ (struct bfd_elf_version_tree *verdefs, const char *sym_name);
+@end example
+@strong{Description}@*
+Search an elf version script tree for symbol versioning
+info for a given symbol. Return TRUE if the symbol is hidden.
+
diff --git a/bfd/doc/makefile.vms b/bfd/doc/makefile.vms
new file mode 100644
index 0000000..26feca6
--- /dev/null
+++ b/bfd/doc/makefile.vms
@@ -0,0 +1,22 @@
+# Copyright (C) 2012-2014 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 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 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 COPYING3. If not see
+# <http://www.gnu.org/licenses/>.
+#
+
+CFLAGS = /noopt/include=([],[-],[-.-.include])
+LDFLAGS = /nomap
+LDLIBS = ,sys$$library:vaxcrtl.olb/lib
+
+all: chew.exe
diff --git a/bfd/doc/mmo.texi b/bfd/doc/mmo.texi
new file mode 100644
index 0000000..f9c2358
--- /dev/null
+++ b/bfd/doc/mmo.texi
@@ -0,0 +1,369 @@
+@section mmo backend
+The mmo object format is used exclusively together with Professor
+Donald E.@: Knuth's educational 64-bit processor MMIX. The simulator
+@command{mmix} which is available at
+@url{http://mmix.cs.hm.edu/src/index.html}
+understands this format. That package also includes a combined
+assembler and linker called @command{mmixal}. The mmo format has
+no advantages feature-wise compared to e.g. ELF. It is a simple
+non-relocatable object format with no support for archives or
+debugging information, except for symbol value information and
+line numbers (which is not yet implemented in BFD). See
+@url{http://mmix.cs.hm.edu/} for more
+information about MMIX. The ELF format is used for intermediate
+object files in the BFD implementation.
+
+@c We want to xref the symbol table node. A feature in "chew"
+@c requires that "commands" do not contain spaces in the
+@c arguments. Hence the hyphen in "Symbol-table".
+@menu
+* File layout::
+* Symbol-table::
+* mmo section mapping::
+@end menu
+
+@node File layout, Symbol-table, mmo, mmo
+@subsection File layout
+The mmo file contents is not partitioned into named sections as
+with e.g.@: ELF. Memory areas is formed by specifying the
+location of the data that follows. Only the memory area
+@samp{0x0000@dots{}00} to @samp{0x01ff@dots{}ff} is executable, so
+it is used for code (and constants) and the area
+@samp{0x2000@dots{}00} to @samp{0x20ff@dots{}ff} is used for
+writable data. @xref{mmo section mapping}.
+
+There is provision for specifying ``special data'' of 65536
+different types. We use type 80 (decimal), arbitrarily chosen the
+same as the ELF @code{e_machine} number for MMIX, filling it with
+section information normally found in ELF objects. @xref{mmo
+section mapping}.
+
+Contents is entered as 32-bit words, xor:ed over previous
+contents, always zero-initialized. A word that starts with the
+byte @samp{0x98} forms a command called a @samp{lopcode}, where
+the next byte distinguished between the thirteen lopcodes. The
+two remaining bytes, called the @samp{Y} and @samp{Z} fields, or
+the @samp{YZ} field (a 16-bit big-endian number), are used for
+various purposes different for each lopcode. As documented in
+@url{http://mmix.cs.hm.edu/doc/mmixal.pdf},
+the lopcodes are:
+
+@table @code
+@item lop_quote
+0x98000001. The next word is contents, regardless of whether it
+starts with 0x98 or not.
+
+@item lop_loc
+0x9801YYZZ, where @samp{Z} is 1 or 2. This is a location
+directive, setting the location for the next data to the next
+32-bit word (for @math{Z = 1}) or 64-bit word (for @math{Z = 2}),
+plus @math{Y * 2^56}. Normally @samp{Y} is 0 for the text segment
+and 2 for the data segment. Beware that the low bits of non-
+tetrabyte-aligned values are silently discarded when being
+automatically incremented and when storing contents (in contrast
+to e.g. its use as current location when followed by lop_fixo
+et al before the next possibly-quoted tetrabyte contents).
+
+@item lop_skip
+0x9802YYZZ. Increase the current location by @samp{YZ} bytes.
+
+@item lop_fixo
+0x9803YYZZ, where @samp{Z} is 1 or 2. Store the current location
+as 64 bits into the location pointed to by the next 32-bit
+(@math{Z = 1}) or 64-bit (@math{Z = 2}) word, plus @math{Y *
+2^56}.
+
+@item lop_fixr
+0x9804YYZZ. @samp{YZ} is stored into the current location plus
+@math{2 - 4 * YZ}.
+
+@item lop_fixrx
+0x980500ZZ. @samp{Z} is 16 or 24. A value @samp{L} derived from
+the following 32-bit word are used in a manner similar to
+@samp{YZ} in lop_fixr: it is xor:ed into the current location
+minus @math{4 * L}. The first byte of the word is 0 or 1. If it
+is 1, then @math{L = (@var{lowest 24 bits of word}) - 2^Z}, if 0,
+then @math{L = (@var{lowest 24 bits of word})}.
+
+@item lop_file
+0x9806YYZZ. @samp{Y} is the file number, @samp{Z} is count of
+32-bit words. Set the file number to @samp{Y} and the line
+counter to 0. The next @math{Z * 4} bytes contain the file name,
+padded with zeros if the count is not a multiple of four. The
+same @samp{Y} may occur multiple times, but @samp{Z} must be 0 for
+all but the first occurrence.
+
+@item lop_line
+0x9807YYZZ. @samp{YZ} is the line number. Together with
+lop_file, it forms the source location for the next 32-bit word.
+Note that for each non-lopcode 32-bit word, line numbers are
+assumed incremented by one.
+
+@item lop_spec
+0x9808YYZZ. @samp{YZ} is the type number. Data until the next
+lopcode other than lop_quote forms special data of type @samp{YZ}.
+@xref{mmo section mapping}.
+
+Other types than 80, (or type 80 with a content that does not
+parse) is stored in sections named @code{.MMIX.spec_data.@var{n}}
+where @var{n} is the @samp{YZ}-type. The flags for such a
+sections say not to allocate or load the data. The vma is 0.
+Contents of multiple occurrences of special data @var{n} is
+concatenated to the data of the previous lop_spec @var{n}s. The
+location in data or code at which the lop_spec occurred is lost.
+
+@item lop_pre
+0x980901ZZ. The first lopcode in a file. The @samp{Z} field forms the
+length of header information in 32-bit words, where the first word
+tells the time in seconds since @samp{00:00:00 GMT Jan 1 1970}.
+
+@item lop_post
+0x980a00ZZ. @math{Z > 32}. This lopcode follows after all
+content-generating lopcodes in a program. The @samp{Z} field
+denotes the value of @samp{rG} at the beginning of the program.
+The following @math{256 - Z} big-endian 64-bit words are loaded
+into global registers @samp{$G} @dots{} @samp{$255}.
+
+@item lop_stab
+0x980b0000. The next-to-last lopcode in a program. Must follow
+immediately after the lop_post lopcode and its data. After this
+lopcode follows all symbols in a compressed format
+(@pxref{Symbol-table}).
+
+@item lop_end
+0x980cYYZZ. The last lopcode in a program. It must follow the
+lop_stab lopcode and its data. The @samp{YZ} field contains the
+number of 32-bit words of symbol table information after the
+preceding lop_stab lopcode.
+@end table
+
+Note that the lopcode "fixups"; @code{lop_fixr}, @code{lop_fixrx} and
+@code{lop_fixo} are not generated by BFD, but are handled. They are
+generated by @code{mmixal}.
+
+This trivial one-label, one-instruction file:
+
+@example
+ :Main TRAP 1,2,3
+@end example
+
+can be represented this way in mmo:
+
+@example
+ 0x98090101 - lop_pre, one 32-bit word with timestamp.
+ <timestamp>
+ 0x98010002 - lop_loc, text segment, using a 64-bit address.
+ Note that mmixal does not emit this for the file above.
+ 0x00000000 - Address, high 32 bits.
+ 0x00000000 - Address, low 32 bits.
+ 0x98060002 - lop_file, 2 32-bit words for file-name.
+ 0x74657374 - "test"
+ 0x2e730000 - ".s\0\0"
+ 0x98070001 - lop_line, line 1.
+ 0x00010203 - TRAP 1,2,3
+ 0x980a00ff - lop_post, setting $255 to 0.
+ 0x00000000
+ 0x00000000
+ 0x980b0000 - lop_stab for ":Main" = 0, serial 1.
+ 0x203a4040 @xref{Symbol-table}.
+ 0x10404020
+ 0x4d206120
+ 0x69016e00
+ 0x81000000
+ 0x980c0005 - lop_end; symbol table contained five 32-bit words.
+@end example
+@node Symbol-table, mmo section mapping, File layout, mmo
+@subsection Symbol table format
+From mmixal.w (or really, the generated mmixal.tex) in the
+MMIXware package which also contains the @command{mmix} simulator:
+``Symbols are stored and retrieved by means of a @samp{ternary
+search trie}, following ideas of Bentley and Sedgewick. (See
+ACM--SIAM Symp.@: on Discrete Algorithms @samp{8} (1997), 360--369;
+R.@:Sedgewick, @samp{Algorithms in C} (Reading, Mass.@:
+Addison--Wesley, 1998), @samp{15.4}.) Each trie node stores a
+character, and there are branches to subtries for the cases where
+a given character is less than, equal to, or greater than the
+character in the trie. There also is a pointer to a symbol table
+entry if a symbol ends at the current node.''
+
+So it's a tree encoded as a stream of bytes. The stream of bytes
+acts on a single virtual global symbol, adding and removing
+characters and signalling complete symbol points. Here, we read
+the stream and create symbols at the completion points.
+
+First, there's a control byte @code{m}. If any of the listed bits
+in @code{m} is nonzero, we execute what stands at the right, in
+the listed order:
+
+@example
+ (MMO3_LEFT)
+ 0x40 - Traverse left trie.
+ (Read a new command byte and recurse.)
+
+ (MMO3_SYMBITS)
+ 0x2f - Read the next byte as a character and store it in the
+ current character position; increment character position.
+ Test the bits of @code{m}:
+
+ (MMO3_WCHAR)
+ 0x80 - The character is 16-bit (so read another byte,
+ merge into current character.
+
+ (MMO3_TYPEBITS)
+ 0xf - We have a complete symbol; parse the type, value
+ and serial number and do what should be done
+ with a symbol. The type and length information
+ is in j = (m & 0xf).
+
+ (MMO3_REGQUAL_BITS)
+ j == 0xf: A register variable. The following
+ byte tells which register.
+ j <= 8: An absolute symbol. Read j bytes as the
+ big-endian number the symbol equals.
+ A j = 2 with two zero bytes denotes an
+ unknown symbol.
+ j > 8: As with j <= 8, but add (0x20 << 56)
+ to the value in the following j - 8
+ bytes.
+
+ Then comes the serial number, as a variant of
+ uleb128, but better named ubeb128:
+ Read bytes and shift the previous value left 7
+ (multiply by 128). Add in the new byte, repeat
+ until a byte has bit 7 set. The serial number
+ is the computed value minus 128.
+
+ (MMO3_MIDDLE)
+ 0x20 - Traverse middle trie. (Read a new command byte
+ and recurse.) Decrement character position.
+
+ (MMO3_RIGHT)
+ 0x10 - Traverse right trie. (Read a new command byte and
+ recurse.)
+@end example
+
+Let's look again at the @code{lop_stab} for the trivial file
+(@pxref{File layout}).
+
+@example
+ 0x980b0000 - lop_stab for ":Main" = 0, serial 1.
+ 0x203a4040
+ 0x10404020
+ 0x4d206120
+ 0x69016e00
+ 0x81000000
+@end example
+
+This forms the trivial trie (note that the path between ``:'' and
+``M'' is redundant):
+
+@example
+ 203a ":"
+ 40 /
+ 40 /
+ 10 \
+ 40 /
+ 40 /
+ 204d "M"
+ 2061 "a"
+ 2069 "i"
+ 016e "n" is the last character in a full symbol, and
+ with a value represented in one byte.
+ 00 The value is 0.
+ 81 The serial number is 1.
+@end example
+
+@node mmo section mapping, , Symbol-table, mmo
+@subsection mmo section mapping
+The implementation in BFD uses special data type 80 (decimal) to
+encapsulate and describe named sections, containing e.g.@: debug
+information. If needed, any datum in the encapsulation will be
+quoted using lop_quote. First comes a 32-bit word holding the
+number of 32-bit words containing the zero-terminated zero-padded
+segment name. After the name there's a 32-bit word holding flags
+describing the section type. Then comes a 64-bit big-endian word
+with the section length (in bytes), then another with the section
+start address. Depending on the type of section, the contents
+might follow, zero-padded to 32-bit boundary. For a loadable
+section (such as data or code), the contents might follow at some
+later point, not necessarily immediately, as a lop_loc with the
+same start address as in the section description, followed by the
+contents. This in effect forms a descriptor that must be emitted
+before the actual contents. Sections described this way must not
+overlap.
+
+For areas that don't have such descriptors, synthetic sections are
+formed by BFD. Consecutive contents in the two memory areas
+@samp{0x0000@dots{}00} to @samp{0x01ff@dots{}ff} and
+@samp{0x2000@dots{}00} to @samp{0x20ff@dots{}ff} are entered in
+sections named @code{.text} and @code{.data} respectively. If an area
+is not otherwise described, but would together with a neighboring
+lower area be less than @samp{0x40000000} bytes long, it is joined
+with the lower area and the gap is zero-filled. For other cases,
+a new section is formed, named @code{.MMIX.sec.@var{n}}. Here,
+@var{n} is a number, a running count through the mmo file,
+starting at 0.
+
+A loadable section specified as:
+
+@example
+ .section secname,"ax"
+ TETRA 1,2,3,4,-1,-2009
+ BYTE 80
+@end example
+
+and linked to address @samp{0x4}, is represented by the sequence:
+
+@example
+ 0x98080050 - lop_spec 80
+ 0x00000002 - two 32-bit words for the section name
+ 0x7365636e - "secn"
+ 0x616d6500 - "ame\0"
+ 0x00000033 - flags CODE, READONLY, LOAD, ALLOC
+ 0x00000000 - high 32 bits of section length
+ 0x0000001c - section length is 28 bytes; 6 * 4 + 1 + alignment to 32 bits
+ 0x00000000 - high 32 bits of section address
+ 0x00000004 - section address is 4
+ 0x98010002 - 64 bits with address of following data
+ 0x00000000 - high 32 bits of address
+ 0x00000004 - low 32 bits: data starts at address 4
+ 0x00000001 - 1
+ 0x00000002 - 2
+ 0x00000003 - 3
+ 0x00000004 - 4
+ 0xffffffff - -1
+ 0xfffff827 - -2009
+ 0x50000000 - 80 as a byte, padded with zeros.
+@end example
+
+Note that the lop_spec wrapping does not include the section
+contents. Compare this to a non-loaded section specified as:
+
+@example
+ .section thirdsec
+ TETRA 200001,100002
+ BYTE 38,40
+@end example
+
+This, when linked to address @samp{0x200000000000001c}, is
+represented by:
+
+@example
+ 0x98080050 - lop_spec 80
+ 0x00000002 - two 32-bit words for the section name
+ 0x7365636e - "thir"
+ 0x616d6500 - "dsec"
+ 0x00000010 - flag READONLY
+ 0x00000000 - high 32 bits of section length
+ 0x0000000c - section length is 12 bytes; 2 * 4 + 2 + alignment to 32 bits
+ 0x20000000 - high 32 bits of address
+ 0x0000001c - low 32 bits of address 0x200000000000001c
+ 0x00030d41 - 200001
+ 0x000186a2 - 100002
+ 0x26280000 - 38, 40 as bytes, padded with zeros
+@end example
+
+For the latter example, the section contents must not be
+loaded in memory, and is therefore specified as part of the
+special data. The address is usually unimportant but might
+provide information for e.g.@: the DWARF 2 debugging format.
diff --git a/bfd/doc/opncls.texi b/bfd/doc/opncls.texi
new file mode 100644
index 0000000..a7a57a6
--- /dev/null
+++ b/bfd/doc/opncls.texi
@@ -0,0 +1,456 @@
+
+@example
+/* Set to N to open the next N BFDs using an alternate id space. */
+extern unsigned int bfd_use_reserved_id;
+@end example
+@section Opening and closing BFDs
+
+
+@subsection Functions for opening and closing
+
+
+@findex bfd_fopen
+@subsubsection @code{bfd_fopen}
+@strong{Synopsis}
+@example
+bfd *bfd_fopen (const char *filename, const char *target,
+ const char *mode, int fd);
+@end example
+@strong{Description}@*
+Open the file @var{filename} with the target @var{target}.
+Return a pointer to the created BFD. If @var{fd} is not -1,
+then @code{fdopen} is used to open the file; otherwise, @code{fopen}
+is used. @var{mode} is passed directly to @code{fopen} or
+@code{fdopen}.
+
+Calls @code{bfd_find_target}, so @var{target} is interpreted as by
+that function.
+
+The new BFD is marked as cacheable iff @var{fd} is -1.
+
+If @code{NULL} is returned then an error has occured. Possible errors
+are @code{bfd_error_no_memory}, @code{bfd_error_invalid_target} or
+@code{system_call} error.
+
+On error, @var{fd} is always closed.
+
+A copy of the @var{filename} argument is stored in the newly created
+BFD. It can be accessed via the bfd_get_filename() macro.
+
+@findex bfd_openr
+@subsubsection @code{bfd_openr}
+@strong{Synopsis}
+@example
+bfd *bfd_openr (const char *filename, const char *target);
+@end example
+@strong{Description}@*
+Open the file @var{filename} (using @code{fopen}) with the target
+@var{target}. Return a pointer to the created BFD.
+
+Calls @code{bfd_find_target}, so @var{target} is interpreted as by
+that function.
+
+If @code{NULL} is returned then an error has occured. Possible errors
+are @code{bfd_error_no_memory}, @code{bfd_error_invalid_target} or
+@code{system_call} error.
+
+A copy of the @var{filename} argument is stored in the newly created
+BFD. It can be accessed via the bfd_get_filename() macro.
+
+@findex bfd_fdopenr
+@subsubsection @code{bfd_fdopenr}
+@strong{Synopsis}
+@example
+bfd *bfd_fdopenr (const char *filename, const char *target, int fd);
+@end example
+@strong{Description}@*
+@code{bfd_fdopenr} is to @code{bfd_fopenr} much like @code{fdopen} is to
+@code{fopen}. It opens a BFD on a file already described by the
+@var{fd} supplied.
+
+When the file is later @code{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 caching; the file descriptor will remain open
+until @code{bfd_close}, and will not be affected by BFD operations
+on other files.
+
+Possible errors are @code{bfd_error_no_memory},
+@code{bfd_error_invalid_target} and @code{bfd_error_system_call}.
+
+On error, @var{fd} is closed.
+
+A copy of the @var{filename} argument is stored in the newly created
+BFD. It can be accessed via the bfd_get_filename() macro.
+
+@findex bfd_openstreamr
+@subsubsection @code{bfd_openstreamr}
+@strong{Synopsis}
+@example
+bfd *bfd_openstreamr (const char * filename, const char * target, void * stream);
+@end example
+@strong{Description}@*
+Open a BFD for read access on an existing stdio stream. When
+the BFD is passed to @code{bfd_close}, the stream will be closed.
+
+A copy of the @var{filename} argument is stored in the newly created
+BFD. It can be accessed via the bfd_get_filename() macro.
+
+@findex bfd_openr_iovec
+@subsubsection @code{bfd_openr_iovec}
+@strong{Synopsis}
+@example
+bfd *bfd_openr_iovec (const char *filename, const char *target,
+ void *(*open_func) (struct bfd *nbfd,
+ void *open_closure),
+ void *open_closure,
+ file_ptr (*pread_func) (struct bfd *nbfd,
+ void *stream,
+ void *buf,
+ file_ptr nbytes,
+ file_ptr offset),
+ int (*close_func) (struct bfd *nbfd,
+ void *stream),
+ int (*stat_func) (struct bfd *abfd,
+ void *stream,
+ struct stat *sb));
+@end example
+@strong{Description}@*
+Create and return a BFD backed by a read-only @var{stream}.
+The @var{stream} is created using @var{open_func}, accessed using
+@var{pread_func} and destroyed using @var{close_func}.
+
+Calls @code{bfd_find_target}, so @var{target} is interpreted as by
+that function.
+
+Calls @var{open_func} (which can call @code{bfd_zalloc} and
+@code{bfd_get_filename}) to obtain the read-only stream backing
+the BFD. @var{open_func} either succeeds returning the
+non-@code{NULL} @var{stream}, or fails returning @code{NULL}
+(setting @code{bfd_error}).
+
+Calls @var{pread_func} to request @var{nbytes} of data from
+@var{stream} starting at @var{offset} (e.g., via a call to
+@code{bfd_read}). @var{pread_func} either succeeds returning the
+number of bytes read (which can be less than @var{nbytes} when
+end-of-file), or fails returning -1 (setting @code{bfd_error}).
+
+Calls @var{close_func} when the BFD is later closed using
+@code{bfd_close}. @var{close_func} either succeeds returning 0, or
+fails returning -1 (setting @code{bfd_error}).
+
+Calls @var{stat_func} to fill in a stat structure for bfd_stat,
+bfd_get_size, and bfd_get_mtime calls. @var{stat_func} returns 0
+on success, or returns -1 on failure (setting @code{bfd_error}).
+
+If @code{bfd_openr_iovec} returns @code{NULL} then an error has
+occurred. Possible errors are @code{bfd_error_no_memory},
+@code{bfd_error_invalid_target} and @code{bfd_error_system_call}.
+
+A copy of the @var{filename} argument is stored in the newly created
+BFD. It can be accessed via the bfd_get_filename() macro.
+
+@findex bfd_openw
+@subsubsection @code{bfd_openw}
+@strong{Synopsis}
+@example
+bfd *bfd_openw (const char *filename, const char *target);
+@end example
+@strong{Description}@*
+Create a BFD, associated with file @var{filename}, using the
+file format @var{target}, and return a pointer to it.
+
+Possible errors are @code{bfd_error_system_call}, @code{bfd_error_no_memory},
+@code{bfd_error_invalid_target}.
+
+A copy of the @var{filename} argument is stored in the newly created
+BFD. It can be accessed via the bfd_get_filename() macro.
+
+@findex bfd_close
+@subsubsection @code{bfd_close}
+@strong{Synopsis}
+@example
+bfd_boolean bfd_close (bfd *abfd);
+@end example
+@strong{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 @code{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 @code{bfd_fdopenr}).
+
+@strong{Returns}@*
+@code{TRUE} is returned if all is ok, otherwise @code{FALSE}.
+
+@findex bfd_close_all_done
+@subsubsection @code{bfd_close_all_done}
+@strong{Synopsis}
+@example
+bfd_boolean bfd_close_all_done (bfd *);
+@end example
+@strong{Description}@*
+Close a BFD. Differs from @code{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 @code{chmod} is called
+to mark it as such.
+
+All memory attached to the BFD is released.
+
+@strong{Returns}@*
+@code{TRUE} is returned if all is ok, otherwise @code{FALSE}.
+
+@findex bfd_create
+@subsubsection @code{bfd_create}
+@strong{Synopsis}
+@example
+bfd *bfd_create (const char *filename, bfd *templ);
+@end example
+@strong{Description}@*
+Create a new BFD in the manner of @code{bfd_openw}, but without
+opening a file. The new BFD takes the target from the target
+used by @var{templ}. The format is always set to @code{bfd_object}.
+
+A copy of the @var{filename} argument is stored in the newly created
+BFD. It can be accessed via the bfd_get_filename() macro.
+
+@findex bfd_make_writable
+@subsubsection @code{bfd_make_writable}
+@strong{Synopsis}
+@example
+bfd_boolean bfd_make_writable (bfd *abfd);
+@end example
+@strong{Description}@*
+Takes a BFD as created by @code{bfd_create} and converts it
+into one like as returned by @code{bfd_openw}. It does this
+by converting the BFD to BFD_IN_MEMORY. It's assumed that
+you will call @code{bfd_make_readable} on this bfd later.
+
+@strong{Returns}@*
+@code{TRUE} is returned if all is ok, otherwise @code{FALSE}.
+
+@findex bfd_make_readable
+@subsubsection @code{bfd_make_readable}
+@strong{Synopsis}
+@example
+bfd_boolean bfd_make_readable (bfd *abfd);
+@end example
+@strong{Description}@*
+Takes a BFD as created by @code{bfd_create} and
+@code{bfd_make_writable} and converts it into one like as
+returned by @code{bfd_openr}. It does this by writing the
+contents out to the memory buffer, then reversing the
+direction.
+
+@strong{Returns}@*
+@code{TRUE} is returned if all is ok, otherwise @code{FALSE}.
+
+@findex bfd_alloc
+@subsubsection @code{bfd_alloc}
+@strong{Synopsis}
+@example
+void *bfd_alloc (bfd *abfd, bfd_size_type wanted);
+@end example
+@strong{Description}@*
+Allocate a block of @var{wanted} bytes of memory attached to
+@code{abfd} and return a pointer to it.
+
+@findex bfd_alloc2
+@subsubsection @code{bfd_alloc2}
+@strong{Synopsis}
+@example
+void *bfd_alloc2 (bfd *abfd, bfd_size_type nmemb, bfd_size_type size);
+@end example
+@strong{Description}@*
+Allocate a block of @var{nmemb} elements of @var{size} bytes each
+of memory attached to @code{abfd} and return a pointer to it.
+
+@findex bfd_zalloc
+@subsubsection @code{bfd_zalloc}
+@strong{Synopsis}
+@example
+void *bfd_zalloc (bfd *abfd, bfd_size_type wanted);
+@end example
+@strong{Description}@*
+Allocate a block of @var{wanted} bytes of zeroed memory
+attached to @code{abfd} and return a pointer to it.
+
+@findex bfd_zalloc2
+@subsubsection @code{bfd_zalloc2}
+@strong{Synopsis}
+@example
+void *bfd_zalloc2 (bfd *abfd, bfd_size_type nmemb, bfd_size_type size);
+@end example
+@strong{Description}@*
+Allocate a block of @var{nmemb} elements of @var{size} bytes each
+of zeroed memory attached to @code{abfd} and return a pointer to it.
+
+@findex bfd_calc_gnu_debuglink_crc32
+@subsubsection @code{bfd_calc_gnu_debuglink_crc32}
+@strong{Synopsis}
+@example
+unsigned long bfd_calc_gnu_debuglink_crc32
+ (unsigned long crc, const unsigned char *buf, bfd_size_type len);
+@end example
+@strong{Description}@*
+Computes a CRC value as used in the .gnu_debuglink section.
+Advances the previously computed @var{crc} value by computing
+and adding in the crc32 for @var{len} bytes of @var{buf}.
+
+@strong{Returns}@*
+Return the updated CRC32 value.
+
+@findex bfd_get_debug_link_info
+@subsubsection @code{bfd_get_debug_link_info}
+@strong{Synopsis}
+@example
+char *bfd_get_debug_link_info (bfd *abfd, unsigned long *crc32_out);
+@end example
+@strong{Description}@*
+Fetch the filename and CRC32 value for any separate debuginfo
+associated with @var{abfd}. Return NULL if no such info found,
+otherwise return filename and update @var{crc32_out}. The
+returned filename is allocated with @code{malloc}; freeing it
+is the responsibility of the caller.
+
+@findex bfd_get_alt_debug_link_info
+@subsubsection @code{bfd_get_alt_debug_link_info}
+@strong{Synopsis}
+@example
+char *bfd_get_alt_debug_link_info (bfd * abfd,
+ bfd_size_type *buildid_len,
+ bfd_byte **buildid_out);
+@end example
+@strong{Description}@*
+Fetch the filename and BuildID value for any alternate debuginfo
+associated with @var{abfd}. Return NULL if no such info found,
+otherwise return filename and update @var{buildid_len} and
+@var{buildid_out}. The returned filename and build_id are
+allocated with @code{malloc}; freeing them is the
+responsibility of the caller.
+
+@findex separate_debug_file_exists
+@subsubsection @code{separate_debug_file_exists}
+@strong{Synopsis}
+@example
+bfd_boolean separate_debug_file_exists
+ (char *name, unsigned long crc32);
+@end example
+@strong{Description}@*
+Checks to see if @var{name} is a file and if its contents
+match @var{crc32}.
+
+@findex separate_alt_debug_file_exists
+@subsubsection @code{separate_alt_debug_file_exists}
+@strong{Synopsis}
+@example
+bfd_boolean separate_alt_debug_file_exists
+ (char *name, unsigned long crc32);
+@end example
+@strong{Description}@*
+Checks to see if @var{name} is a file and if its BuildID
+matches @var{buildid}.
+
+@findex find_separate_debug_file
+@subsubsection @code{find_separate_debug_file}
+@strong{Synopsis}
+@example
+char *find_separate_debug_file (bfd *abfd);
+@end example
+@strong{Description}@*
+Searches @var{abfd} for a section called @var{section_name} which
+is expected to contain a reference to a file containing separate
+debugging information. The function scans various locations in
+the filesystem, including the file tree rooted at
+@var{debug_file_directory}, and returns the first matching
+filename that it finds. If @var{check_crc} is TRUE then the
+contents of the file must also match the CRC value contained in
+@var{section_name}. Returns NULL if no valid file could be found.
+
+@findex bfd_follow_gnu_debuglink
+@subsubsection @code{bfd_follow_gnu_debuglink}
+@strong{Synopsis}
+@example
+char *bfd_follow_gnu_debuglink (bfd *abfd, const char *dir);
+@end example
+@strong{Description}@*
+Takes a BFD and searches it for a .gnu_debuglink section. If this
+section is found, it examines the section for the name and checksum
+of a '.debug' file containing auxiliary debugging information. It
+then searches the filesystem for this .debug file in some standard
+locations, including the directory tree rooted at @var{dir}, and if
+found returns the full filename.
+
+If @var{dir} is NULL, it will search a default path configured into
+libbfd at build time. [XXX this feature is not currently
+implemented].
+
+@strong{Returns}@*
+@code{NULL} on any errors or failure to locate the .debug file,
+otherwise a pointer to a heap-allocated string containing the
+filename. The caller is responsible for freeing this string.
+
+@findex bfd_follow_gnu_debugaltlink
+@subsubsection @code{bfd_follow_gnu_debugaltlink}
+@strong{Synopsis}
+@example
+char *bfd_follow_gnu_debugaltlink (bfd *abfd, const char *dir);
+@end example
+@strong{Description}@*
+Takes a BFD and searches it for a .gnu_debugaltlink section. If this
+section is found, it examines the section for the name of a file
+containing auxiliary debugging information. It then searches the
+filesystem for this file in a set of standard locations, including
+the directory tree rooted at @var{dir}, and if found returns the
+full filename.
+
+If @var{dir} is NULL, it will search a default path configured into
+libbfd at build time. [FIXME: This feature is not currently
+implemented].
+
+@strong{Returns}@*
+@code{NULL} on any errors or failure to locate the debug file,
+otherwise a pointer to a heap-allocated string containing the
+filename. The caller is responsible for freeing this string.
+
+@findex bfd_create_gnu_debuglink_section
+@subsubsection @code{bfd_create_gnu_debuglink_section}
+@strong{Synopsis}
+@example
+struct bfd_section *bfd_create_gnu_debuglink_section
+ (bfd *abfd, const char *filename);
+@end example
+@strong{Description}@*
+Takes a @var{BFD} and adds a .gnu_debuglink section to it. The section is sized
+to be big enough to contain a link to the specified @var{filename}.
+
+@strong{Returns}@*
+A pointer to the new section is returned if all is ok. Otherwise @code{NULL} is
+returned and bfd_error is set.
+
+@findex bfd_fill_in_gnu_debuglink_section
+@subsubsection @code{bfd_fill_in_gnu_debuglink_section}
+@strong{Synopsis}
+@example
+bfd_boolean bfd_fill_in_gnu_debuglink_section
+ (bfd *abfd, struct bfd_section *sect, const char *filename);
+@end example
+@strong{Description}@*
+Takes a @var{BFD} and containing a .gnu_debuglink section @var{SECT}
+and fills in the contents of the section to contain a link to the
+specified @var{filename}. The filename should be relative to the
+current directory.
+
+@strong{Returns}@*
+@code{TRUE} is returned if all is ok. Otherwise @code{FALSE} is returned
+and bfd_error is set.
+
diff --git a/bfd/doc/proto.str b/bfd/doc/proto.str
new file mode 100644
index 0000000..702d9f5
--- /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/doc/reloc.texi b/bfd/doc/reloc.texi
new file mode 100644
index 0000000..92b5cf5
--- /dev/null
+++ b/bfd/doc/reloc.texi
@@ -0,0 +1,4104 @@
+@section Relocations
+BFD maintains relocations in much the same way it maintains
+symbols: they are left alone until required, then read in
+en-masse and translated into an internal form. A common
+routine @code{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 @code{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
+
+
+@node typedef arelent, howto manager, Relocations, Relocations
+@subsection typedef arelent
+This is the structure of a relocation entry:
+
+
+@example
+
+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 bfd_symbol **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;
+
+@end example
+@strong{Description}@*
+Here is a description of each of the fields within an @code{arelent}:
+
+@itemize @bullet
+
+@item
+@code{sym_ptr_ptr}
+@end itemize
+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
+@code{canonicalize_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.
+
+@itemize @bullet
+
+@item
+@code{address}
+@end itemize
+The @code{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.
+
+@itemize @bullet
+
+@item
+@code{addend}
+@end itemize
+The @code{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:
+
+@example
+ char foo[];
+ main()
+ @{
+ return foo[0x12345678];
+ @}
+@end example
+
+Could be compiled into:
+
+@example
+ linkw fp,#-4
+ moveb @@#12345678,d0
+ extbl d0
+ unlk fp
+ rts
+@end example
+
+This could create a reloc pointing to @code{foo}, but leave the
+offset in the data, something like:
+
+@example
+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
+@end example
+
+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:
+
+@example
+ or.u r13,r0,hi16(_foo+0x12345678)
+ ld.b r2,r13,lo16(_foo+0x12345678)
+ jmp r1
+@end example
+
+This should create two relocs, both pointing to @code{_foo}, and with
+0x12340000 in their addend field. The data would consist of:
+
+@example
+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
+@end example
+
+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 @code{_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.
+
+@example
+ save %sp,-112,%sp
+ sethi %hi(_foo+0x12345678),%g2
+ ldsb [%g2+%lo(_foo+0x12345678)],%i0
+ ret
+ restore
+@end example
+
+Both relocs contain a pointer to @code{foo}, and the offsets
+contain junk.
+
+@example
+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
+@end example
+
+@itemize @bullet
+
+@item
+@code{howto}
+@end itemize
+The @code{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 @code{enum complain_overflow}
+Indicates what sort of overflow checking should be done when
+performing a relocation.
+
+
+@example
+
+enum complain_overflow
+@{
+ /* Do not complain on overflow. */
+ complain_overflow_dont,
+
+ /* Complain if the value overflows when considered as a signed
+ number one bit larger than the field. ie. A bitfield of N bits
+ is allowed to represent -2**n to 2**n-1. */
+ complain_overflow_bitfield,
+
+ /* Complain if the value overflows when considered as a signed
+ number. */
+ complain_overflow_signed,
+
+ /* Complain if the value overflows when considered as an
+ unsigned number. */
+ complain_overflow_unsigned
+@};
+@end example
+@subsubsection @code{reloc_howto_type}
+The @code{reloc_howto_type} is a structure which contains all the
+information that libbfd needs to know to tie up a back end's data.
+
+
+@example
+struct bfd_symbol; /* 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;
+
+ /* The relocation is relative to the field being relocated. */
+ bfd_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 accommodated (e.g., i960 callj
+ instructions). */
+ bfd_reloc_status_type (*special_function)
+ (bfd *, arelent *, struct bfd_symbol *, void *, asection *,
+ bfd *, char **);
+
+ /* The textual name of the relocation type. */
+ char *name;
+
+ /* Some formats record a relocation addend in the section contents
+ rather than with the relocation. For ELF formats this is the
+ distinction between USE_REL and USE_RELA (though the code checks
+ for USE_REL == 1/0). The value of this field is TRUE if the
+ addend is recorded with the section contents; when performing a
+ partial link (ld -r) the section contents (the data) will be
+ modified. The value of this field is FALSE if addends are
+ recorded with the relocation (in arelent.addend); when performing
+ a partial link the relocation will be modified.
+ All relocations for all ELF USE_RELA targets should set this field
+ to FALSE (values of TRUE should be looked on with suspicion).
+ However, the converse is not true: not all relocations of all ELF
+ USE_REL targets set this field to TRUE. Why this is so is peculiar
+ to each particular target. For relocs that aren't used in partial
+ links (e.g. GOT stuff) it doesn't matter what this is set to. */
+ bfd_boolean partial_inplace;
+
+ /* src_mask selects the part of the instruction (or data) to be used
+ in the relocation sum. If the target relocations don't have an
+ addend in the reloc, eg. ELF USE_REL, src_mask will normally equal
+ dst_mask to extract the addend from the section contents. If
+ relocations do have an addend in the reloc, eg. ELF USE_RELA, this
+ field should be zero. Non-zero values for ELF USE_RELA targets are
+ bogus as in those cases the value in the dst_mask part of the
+ section contents should be treated as garbage. */
+ bfd_vma src_mask;
+
+ /* dst_mask selects which parts of the instruction (or data) are
+ replaced with a relocated value. */
+ 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. */
+ bfd_boolean pcrel_offset;
+@};
+
+@end example
+@findex The HOWTO Macro
+@subsubsection @code{The HOWTO Macro}
+@strong{Description}@*
+The HOWTO define is horrible and will go away.
+@example
+#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 @}
+@end example
+
+@strong{Description}@*
+And will be replaced with the totally magic way. But for the
+moment, we are compatible, so do it this way.
+@example
+#define NEWHOWTO(FUNCTION, NAME, SIZE, REL, IN) \
+ HOWTO (0, 0, SIZE, 0, REL, 0, complain_overflow_dont, FUNCTION, \
+ NAME, FALSE, 0, 0, IN)
+
+@end example
+
+@strong{Description}@*
+This is used to fill in an empty howto entry in an array.
+@example
+#define EMPTY_HOWTO(C) \
+ HOWTO ((C), 0, 0, 0, FALSE, 0, complain_overflow_dont, NULL, \
+ NULL, FALSE, 0, 0, FALSE)
+
+@end example
+
+@strong{Description}@*
+Helper routine to turn a symbol into a relocation value.
+@example
+#define HOWTO_PREPARE(relocation, symbol) \
+ @{ \
+ if (symbol != NULL) \
+ @{ \
+ if (bfd_is_com_section (symbol->section)) \
+ @{ \
+ relocation = 0; \
+ @} \
+ else \
+ @{ \
+ relocation = symbol->value; \
+ @} \
+ @} \
+ @}
+
+@end example
+
+@findex bfd_get_reloc_size
+@subsubsection @code{bfd_get_reloc_size}
+@strong{Synopsis}
+@example
+unsigned int bfd_get_reloc_size (reloc_howto_type *);
+@end example
+@strong{Description}@*
+For a reloc_howto_type that operates on a fixed number of bytes,
+this returns the number of bytes operated on.
+
+@findex arelent_chain
+@subsubsection @code{arelent_chain}
+@strong{Description}@*
+How relocs are tied together in an @code{asection}:
+@example
+typedef struct relent_chain
+@{
+ arelent relent;
+ struct relent_chain *next;
+@}
+arelent_chain;
+
+@end example
+
+@findex bfd_check_overflow
+@subsubsection @code{bfd_check_overflow}
+@strong{Synopsis}
+@example
+bfd_reloc_status_type bfd_check_overflow
+ (enum complain_overflow how,
+ unsigned int bitsize,
+ unsigned int rightshift,
+ unsigned int addrsize,
+ bfd_vma relocation);
+@end example
+@strong{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}.
+
+@findex bfd_perform_relocation
+@subsubsection @code{bfd_perform_relocation}
+@strong{Synopsis}
+@example
+bfd_reloc_status_type bfd_perform_relocation
+ (bfd *abfd,
+ arelent *reloc_entry,
+ void *data,
+ asection *input_section,
+ bfd *output_bfd,
+ char **error_message);
+@end example
+@strong{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}.
+
+@findex bfd_install_relocation
+@subsubsection @code{bfd_install_relocation}
+@strong{Synopsis}
+@example
+bfd_reloc_status_type bfd_install_relocation
+ (bfd *abfd,
+ arelent *reloc_entry,
+ void *data, bfd_vma data_start,
+ asection *input_section,
+ char **error_message);
+@end example
+@strong{Description}@*
+This looks remarkably like @code{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.
+
+
+@node howto manager, , typedef arelent, Relocations
+@subsection 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.
+
+@findex bfd_reloc_code_type
+@subsubsection @code{bfd_reloc_code_type}
+@strong{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 @code{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.
+
+Here are the possible values for @code{enum bfd_reloc_code_real}:
+
+@deffn {} BFD_RELOC_64
+@deffnx {} BFD_RELOC_32
+@deffnx {} BFD_RELOC_26
+@deffnx {} BFD_RELOC_24
+@deffnx {} BFD_RELOC_16
+@deffnx {} BFD_RELOC_14
+@deffnx {} BFD_RELOC_8
+Basic absolute relocations of N bits.
+@end deffn
+@deffn {} BFD_RELOC_64_PCREL
+@deffnx {} BFD_RELOC_32_PCREL
+@deffnx {} BFD_RELOC_24_PCREL
+@deffnx {} BFD_RELOC_16_PCREL
+@deffnx {} BFD_RELOC_12_PCREL
+@deffnx {} BFD_RELOC_8_PCREL
+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.
+@end deffn
+@deffn {} BFD_RELOC_32_SECREL
+Section relative relocations. Some targets need this for DWARF2.
+@end deffn
+@deffn {} BFD_RELOC_32_GOT_PCREL
+@deffnx {} BFD_RELOC_16_GOT_PCREL
+@deffnx {} BFD_RELOC_8_GOT_PCREL
+@deffnx {} BFD_RELOC_32_GOTOFF
+@deffnx {} BFD_RELOC_16_GOTOFF
+@deffnx {} BFD_RELOC_LO16_GOTOFF
+@deffnx {} BFD_RELOC_HI16_GOTOFF
+@deffnx {} BFD_RELOC_HI16_S_GOTOFF
+@deffnx {} BFD_RELOC_8_GOTOFF
+@deffnx {} BFD_RELOC_64_PLT_PCREL
+@deffnx {} BFD_RELOC_32_PLT_PCREL
+@deffnx {} BFD_RELOC_24_PLT_PCREL
+@deffnx {} BFD_RELOC_16_PLT_PCREL
+@deffnx {} BFD_RELOC_8_PLT_PCREL
+@deffnx {} BFD_RELOC_64_PLTOFF
+@deffnx {} BFD_RELOC_32_PLTOFF
+@deffnx {} BFD_RELOC_16_PLTOFF
+@deffnx {} BFD_RELOC_LO16_PLTOFF
+@deffnx {} BFD_RELOC_HI16_PLTOFF
+@deffnx {} BFD_RELOC_HI16_S_PLTOFF
+@deffnx {} BFD_RELOC_8_PLTOFF
+For ELF.
+@end deffn
+@deffn {} BFD_RELOC_SIZE32
+@deffnx {} BFD_RELOC_SIZE64
+Size relocations.
+@end deffn
+@deffn {} BFD_RELOC_68K_GLOB_DAT
+@deffnx {} BFD_RELOC_68K_JMP_SLOT
+@deffnx {} BFD_RELOC_68K_RELATIVE
+@deffnx {} BFD_RELOC_68K_TLS_GD32
+@deffnx {} BFD_RELOC_68K_TLS_GD16
+@deffnx {} BFD_RELOC_68K_TLS_GD8
+@deffnx {} BFD_RELOC_68K_TLS_LDM32
+@deffnx {} BFD_RELOC_68K_TLS_LDM16
+@deffnx {} BFD_RELOC_68K_TLS_LDM8
+@deffnx {} BFD_RELOC_68K_TLS_LDO32
+@deffnx {} BFD_RELOC_68K_TLS_LDO16
+@deffnx {} BFD_RELOC_68K_TLS_LDO8
+@deffnx {} BFD_RELOC_68K_TLS_IE32
+@deffnx {} BFD_RELOC_68K_TLS_IE16
+@deffnx {} BFD_RELOC_68K_TLS_IE8
+@deffnx {} BFD_RELOC_68K_TLS_LE32
+@deffnx {} BFD_RELOC_68K_TLS_LE16
+@deffnx {} BFD_RELOC_68K_TLS_LE8
+Relocations used by 68K ELF.
+@end deffn
+@deffn {} BFD_RELOC_32_BASEREL
+@deffnx {} BFD_RELOC_16_BASEREL
+@deffnx {} BFD_RELOC_LO16_BASEREL
+@deffnx {} BFD_RELOC_HI16_BASEREL
+@deffnx {} BFD_RELOC_HI16_S_BASEREL
+@deffnx {} BFD_RELOC_8_BASEREL
+@deffnx {} BFD_RELOC_RVA
+Linkage-table relative.
+@end deffn
+@deffn {} BFD_RELOC_8_FFnn
+Absolute 8-bit relocation, but used to form an address like 0xFFnn.
+@end deffn
+@deffn {} BFD_RELOC_32_PCREL_S2
+@deffnx {} BFD_RELOC_16_PCREL_S2
+@deffnx {} BFD_RELOC_23_PCREL_S2
+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.
+@end deffn
+@deffn {} BFD_RELOC_HI22
+@deffnx {} BFD_RELOC_LO10
+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.
+@end deffn
+@deffn {} BFD_RELOC_GPREL16
+@deffnx {} BFD_RELOC_GPREL32
+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.
+@end deffn
+@deffn {} BFD_RELOC_I960_CALLJ
+Reloc types used for i960/b.out.
+@end deffn
+@deffn {} BFD_RELOC_NONE
+@deffnx {} BFD_RELOC_SPARC_WDISP22
+@deffnx {} BFD_RELOC_SPARC22
+@deffnx {} BFD_RELOC_SPARC13
+@deffnx {} BFD_RELOC_SPARC_GOT10
+@deffnx {} BFD_RELOC_SPARC_GOT13
+@deffnx {} BFD_RELOC_SPARC_GOT22
+@deffnx {} BFD_RELOC_SPARC_PC10
+@deffnx {} BFD_RELOC_SPARC_PC22
+@deffnx {} BFD_RELOC_SPARC_WPLT30
+@deffnx {} BFD_RELOC_SPARC_COPY
+@deffnx {} BFD_RELOC_SPARC_GLOB_DAT
+@deffnx {} BFD_RELOC_SPARC_JMP_SLOT
+@deffnx {} BFD_RELOC_SPARC_RELATIVE
+@deffnx {} BFD_RELOC_SPARC_UA16
+@deffnx {} BFD_RELOC_SPARC_UA32
+@deffnx {} BFD_RELOC_SPARC_UA64
+@deffnx {} BFD_RELOC_SPARC_GOTDATA_HIX22
+@deffnx {} BFD_RELOC_SPARC_GOTDATA_LOX10
+@deffnx {} BFD_RELOC_SPARC_GOTDATA_OP_HIX22
+@deffnx {} BFD_RELOC_SPARC_GOTDATA_OP_LOX10
+@deffnx {} BFD_RELOC_SPARC_GOTDATA_OP
+@deffnx {} BFD_RELOC_SPARC_JMP_IREL
+@deffnx {} BFD_RELOC_SPARC_IRELATIVE
+SPARC ELF relocations. There is probably some overlap with other
+relocation types already defined.
+@end deffn
+@deffn {} BFD_RELOC_SPARC_BASE13
+@deffnx {} BFD_RELOC_SPARC_BASE22
+I think these are specific to SPARC a.out (e.g., Sun 4).
+@end deffn
+@deffn {} BFD_RELOC_SPARC_64
+@deffnx {} BFD_RELOC_SPARC_10
+@deffnx {} BFD_RELOC_SPARC_11
+@deffnx {} BFD_RELOC_SPARC_OLO10
+@deffnx {} BFD_RELOC_SPARC_HH22
+@deffnx {} BFD_RELOC_SPARC_HM10
+@deffnx {} BFD_RELOC_SPARC_LM22
+@deffnx {} BFD_RELOC_SPARC_PC_HH22
+@deffnx {} BFD_RELOC_SPARC_PC_HM10
+@deffnx {} BFD_RELOC_SPARC_PC_LM22
+@deffnx {} BFD_RELOC_SPARC_WDISP16
+@deffnx {} BFD_RELOC_SPARC_WDISP19
+@deffnx {} BFD_RELOC_SPARC_7
+@deffnx {} BFD_RELOC_SPARC_6
+@deffnx {} BFD_RELOC_SPARC_5
+@deffnx {} BFD_RELOC_SPARC_DISP64
+@deffnx {} BFD_RELOC_SPARC_PLT32
+@deffnx {} BFD_RELOC_SPARC_PLT64
+@deffnx {} BFD_RELOC_SPARC_HIX22
+@deffnx {} BFD_RELOC_SPARC_LOX10
+@deffnx {} BFD_RELOC_SPARC_H44
+@deffnx {} BFD_RELOC_SPARC_M44
+@deffnx {} BFD_RELOC_SPARC_L44
+@deffnx {} BFD_RELOC_SPARC_REGISTER
+@deffnx {} BFD_RELOC_SPARC_H34
+@deffnx {} BFD_RELOC_SPARC_SIZE32
+@deffnx {} BFD_RELOC_SPARC_SIZE64
+@deffnx {} BFD_RELOC_SPARC_WDISP10
+SPARC64 relocations
+@end deffn
+@deffn {} BFD_RELOC_SPARC_REV32
+SPARC little endian relocation
+@end deffn
+@deffn {} BFD_RELOC_SPARC_TLS_GD_HI22
+@deffnx {} BFD_RELOC_SPARC_TLS_GD_LO10
+@deffnx {} BFD_RELOC_SPARC_TLS_GD_ADD
+@deffnx {} BFD_RELOC_SPARC_TLS_GD_CALL
+@deffnx {} BFD_RELOC_SPARC_TLS_LDM_HI22
+@deffnx {} BFD_RELOC_SPARC_TLS_LDM_LO10
+@deffnx {} BFD_RELOC_SPARC_TLS_LDM_ADD
+@deffnx {} BFD_RELOC_SPARC_TLS_LDM_CALL
+@deffnx {} BFD_RELOC_SPARC_TLS_LDO_HIX22
+@deffnx {} BFD_RELOC_SPARC_TLS_LDO_LOX10
+@deffnx {} BFD_RELOC_SPARC_TLS_LDO_ADD
+@deffnx {} BFD_RELOC_SPARC_TLS_IE_HI22
+@deffnx {} BFD_RELOC_SPARC_TLS_IE_LO10
+@deffnx {} BFD_RELOC_SPARC_TLS_IE_LD
+@deffnx {} BFD_RELOC_SPARC_TLS_IE_LDX
+@deffnx {} BFD_RELOC_SPARC_TLS_IE_ADD
+@deffnx {} BFD_RELOC_SPARC_TLS_LE_HIX22
+@deffnx {} BFD_RELOC_SPARC_TLS_LE_LOX10
+@deffnx {} BFD_RELOC_SPARC_TLS_DTPMOD32
+@deffnx {} BFD_RELOC_SPARC_TLS_DTPMOD64
+@deffnx {} BFD_RELOC_SPARC_TLS_DTPOFF32
+@deffnx {} BFD_RELOC_SPARC_TLS_DTPOFF64
+@deffnx {} BFD_RELOC_SPARC_TLS_TPOFF32
+@deffnx {} BFD_RELOC_SPARC_TLS_TPOFF64
+SPARC TLS relocations
+@end deffn
+@deffn {} BFD_RELOC_SPU_IMM7
+@deffnx {} BFD_RELOC_SPU_IMM8
+@deffnx {} BFD_RELOC_SPU_IMM10
+@deffnx {} BFD_RELOC_SPU_IMM10W
+@deffnx {} BFD_RELOC_SPU_IMM16
+@deffnx {} BFD_RELOC_SPU_IMM16W
+@deffnx {} BFD_RELOC_SPU_IMM18
+@deffnx {} BFD_RELOC_SPU_PCREL9a
+@deffnx {} BFD_RELOC_SPU_PCREL9b
+@deffnx {} BFD_RELOC_SPU_PCREL16
+@deffnx {} BFD_RELOC_SPU_LO16
+@deffnx {} BFD_RELOC_SPU_HI16
+@deffnx {} BFD_RELOC_SPU_PPU32
+@deffnx {} BFD_RELOC_SPU_PPU64
+@deffnx {} BFD_RELOC_SPU_ADD_PIC
+SPU Relocations.
+@end deffn
+@deffn {} BFD_RELOC_ALPHA_GPDISP_HI16
+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).
+@end deffn
+@deffn {} BFD_RELOC_ALPHA_GPDISP_LO16
+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.
+@end deffn
+@deffn {} BFD_RELOC_ALPHA_GPDISP
+The ELF GPDISP relocation is exactly the same as the GPDISP_HI16
+relocation except that there is no accompanying GPDISP_LO16
+relocation.
+@end deffn
+@deffn {} BFD_RELOC_ALPHA_LITERAL
+@deffnx {} BFD_RELOC_ALPHA_ELF_LITERAL
+@deffnx {} BFD_RELOC_ALPHA_LITUSE
+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)
+@end deffn
+@deffn {} BFD_RELOC_ALPHA_HINT
+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.
+@end deffn
+@deffn {} BFD_RELOC_ALPHA_LINKAGE
+The LINKAGE relocation outputs a linkage pair in the object file,
+which is filled by the linker.
+@end deffn
+@deffn {} BFD_RELOC_ALPHA_CODEADDR
+The CODEADDR relocation outputs a STO_CA in the object file,
+which is filled by the linker.
+@end deffn
+@deffn {} BFD_RELOC_ALPHA_GPREL_HI16
+@deffnx {} BFD_RELOC_ALPHA_GPREL_LO16
+The GPREL_HI/LO relocations together form a 32-bit offset from the
+GP register.
+@end deffn
+@deffn {} BFD_RELOC_ALPHA_BRSGP
+Like BFD_RELOC_23_PCREL_S2, except that the source and target must
+share a common GP, and the target address is adjusted for
+STO_ALPHA_STD_GPLOAD.
+@end deffn
+@deffn {} BFD_RELOC_ALPHA_NOP
+The NOP relocation outputs a NOP if the longword displacement
+between two procedure entry points is < 2^21.
+@end deffn
+@deffn {} BFD_RELOC_ALPHA_BSR
+The BSR relocation outputs a BSR if the longword displacement
+between two procedure entry points is < 2^21.
+@end deffn
+@deffn {} BFD_RELOC_ALPHA_LDA
+The LDA relocation outputs a LDA if the longword displacement
+between two procedure entry points is < 2^16.
+@end deffn
+@deffn {} BFD_RELOC_ALPHA_BOH
+The BOH relocation outputs a BSR if the longword displacement
+between two procedure entry points is < 2^21, or else a hint.
+@end deffn
+@deffn {} BFD_RELOC_ALPHA_TLSGD
+@deffnx {} BFD_RELOC_ALPHA_TLSLDM
+@deffnx {} BFD_RELOC_ALPHA_DTPMOD64
+@deffnx {} BFD_RELOC_ALPHA_GOTDTPREL16
+@deffnx {} BFD_RELOC_ALPHA_DTPREL64
+@deffnx {} BFD_RELOC_ALPHA_DTPREL_HI16
+@deffnx {} BFD_RELOC_ALPHA_DTPREL_LO16
+@deffnx {} BFD_RELOC_ALPHA_DTPREL16
+@deffnx {} BFD_RELOC_ALPHA_GOTTPREL16
+@deffnx {} BFD_RELOC_ALPHA_TPREL64
+@deffnx {} BFD_RELOC_ALPHA_TPREL_HI16
+@deffnx {} BFD_RELOC_ALPHA_TPREL_LO16
+@deffnx {} BFD_RELOC_ALPHA_TPREL16
+Alpha thread-local storage relocations.
+@end deffn
+@deffn {} BFD_RELOC_MIPS_JMP
+@deffnx {} BFD_RELOC_MICROMIPS_JMP
+The MIPS jump instruction.
+@end deffn
+@deffn {} BFD_RELOC_MIPS16_JMP
+The MIPS16 jump instruction.
+@end deffn
+@deffn {} BFD_RELOC_MIPS16_GPREL
+MIPS16 GP relative reloc.
+@end deffn
+@deffn {} BFD_RELOC_HI16
+High 16 bits of 32-bit value; simple reloc.
+@end deffn
+@deffn {} BFD_RELOC_HI16_S
+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.
+@end deffn
+@deffn {} BFD_RELOC_LO16
+Low 16 bits.
+@end deffn
+@deffn {} BFD_RELOC_HI16_PCREL
+High 16 bits of 32-bit pc-relative value
+@end deffn
+@deffn {} BFD_RELOC_HI16_S_PCREL
+High 16 bits of 32-bit pc-relative value, adjusted
+@end deffn
+@deffn {} BFD_RELOC_LO16_PCREL
+Low 16 bits of pc-relative value
+@end deffn
+@deffn {} BFD_RELOC_MIPS16_GOT16
+@deffnx {} BFD_RELOC_MIPS16_CALL16
+Equivalent of BFD_RELOC_MIPS_*, but with the MIPS16 layout of
+16-bit immediate fields
+@end deffn
+@deffn {} BFD_RELOC_MIPS16_HI16
+MIPS16 high 16 bits of 32-bit value.
+@end deffn
+@deffn {} BFD_RELOC_MIPS16_HI16_S
+MIPS16 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.
+@end deffn
+@deffn {} BFD_RELOC_MIPS16_LO16
+MIPS16 low 16 bits.
+@end deffn
+@deffn {} BFD_RELOC_MIPS16_TLS_GD
+@deffnx {} BFD_RELOC_MIPS16_TLS_LDM
+@deffnx {} BFD_RELOC_MIPS16_TLS_DTPREL_HI16
+@deffnx {} BFD_RELOC_MIPS16_TLS_DTPREL_LO16
+@deffnx {} BFD_RELOC_MIPS16_TLS_GOTTPREL
+@deffnx {} BFD_RELOC_MIPS16_TLS_TPREL_HI16
+@deffnx {} BFD_RELOC_MIPS16_TLS_TPREL_LO16
+MIPS16 TLS relocations
+@end deffn
+@deffn {} BFD_RELOC_MIPS_LITERAL
+@deffnx {} BFD_RELOC_MICROMIPS_LITERAL
+Relocation against a MIPS literal section.
+@end deffn
+@deffn {} BFD_RELOC_MICROMIPS_7_PCREL_S1
+@deffnx {} BFD_RELOC_MICROMIPS_10_PCREL_S1
+@deffnx {} BFD_RELOC_MICROMIPS_16_PCREL_S1
+microMIPS PC-relative relocations.
+@end deffn
+@deffn {} BFD_RELOC_MIPS_21_PCREL_S2
+@deffnx {} BFD_RELOC_MIPS_26_PCREL_S2
+@deffnx {} BFD_RELOC_MIPS_18_PCREL_S3
+@deffnx {} BFD_RELOC_MIPS_19_PCREL_S2
+MIPS PC-relative relocations.
+@end deffn
+@deffn {} BFD_RELOC_MICROMIPS_GPREL16
+@deffnx {} BFD_RELOC_MICROMIPS_HI16
+@deffnx {} BFD_RELOC_MICROMIPS_HI16_S
+@deffnx {} BFD_RELOC_MICROMIPS_LO16
+microMIPS versions of generic BFD relocs.
+@end deffn
+@deffn {} BFD_RELOC_MIPS_GOT16
+@deffnx {} BFD_RELOC_MICROMIPS_GOT16
+@deffnx {} BFD_RELOC_MIPS_CALL16
+@deffnx {} BFD_RELOC_MICROMIPS_CALL16
+@deffnx {} BFD_RELOC_MIPS_GOT_HI16
+@deffnx {} BFD_RELOC_MICROMIPS_GOT_HI16
+@deffnx {} BFD_RELOC_MIPS_GOT_LO16
+@deffnx {} BFD_RELOC_MICROMIPS_GOT_LO16
+@deffnx {} BFD_RELOC_MIPS_CALL_HI16
+@deffnx {} BFD_RELOC_MICROMIPS_CALL_HI16
+@deffnx {} BFD_RELOC_MIPS_CALL_LO16
+@deffnx {} BFD_RELOC_MICROMIPS_CALL_LO16
+@deffnx {} BFD_RELOC_MIPS_SUB
+@deffnx {} BFD_RELOC_MICROMIPS_SUB
+@deffnx {} BFD_RELOC_MIPS_GOT_PAGE
+@deffnx {} BFD_RELOC_MICROMIPS_GOT_PAGE
+@deffnx {} BFD_RELOC_MIPS_GOT_OFST
+@deffnx {} BFD_RELOC_MICROMIPS_GOT_OFST
+@deffnx {} BFD_RELOC_MIPS_GOT_DISP
+@deffnx {} BFD_RELOC_MICROMIPS_GOT_DISP
+@deffnx {} BFD_RELOC_MIPS_SHIFT5
+@deffnx {} BFD_RELOC_MIPS_SHIFT6
+@deffnx {} BFD_RELOC_MIPS_INSERT_A
+@deffnx {} BFD_RELOC_MIPS_INSERT_B
+@deffnx {} BFD_RELOC_MIPS_DELETE
+@deffnx {} BFD_RELOC_MIPS_HIGHEST
+@deffnx {} BFD_RELOC_MICROMIPS_HIGHEST
+@deffnx {} BFD_RELOC_MIPS_HIGHER
+@deffnx {} BFD_RELOC_MICROMIPS_HIGHER
+@deffnx {} BFD_RELOC_MIPS_SCN_DISP
+@deffnx {} BFD_RELOC_MICROMIPS_SCN_DISP
+@deffnx {} BFD_RELOC_MIPS_REL16
+@deffnx {} BFD_RELOC_MIPS_RELGOT
+@deffnx {} BFD_RELOC_MIPS_JALR
+@deffnx {} BFD_RELOC_MICROMIPS_JALR
+@deffnx {} BFD_RELOC_MIPS_TLS_DTPMOD32
+@deffnx {} BFD_RELOC_MIPS_TLS_DTPREL32
+@deffnx {} BFD_RELOC_MIPS_TLS_DTPMOD64
+@deffnx {} BFD_RELOC_MIPS_TLS_DTPREL64
+@deffnx {} BFD_RELOC_MIPS_TLS_GD
+@deffnx {} BFD_RELOC_MICROMIPS_TLS_GD
+@deffnx {} BFD_RELOC_MIPS_TLS_LDM
+@deffnx {} BFD_RELOC_MICROMIPS_TLS_LDM
+@deffnx {} BFD_RELOC_MIPS_TLS_DTPREL_HI16
+@deffnx {} BFD_RELOC_MICROMIPS_TLS_DTPREL_HI16
+@deffnx {} BFD_RELOC_MIPS_TLS_DTPREL_LO16
+@deffnx {} BFD_RELOC_MICROMIPS_TLS_DTPREL_LO16
+@deffnx {} BFD_RELOC_MIPS_TLS_GOTTPREL
+@deffnx {} BFD_RELOC_MICROMIPS_TLS_GOTTPREL
+@deffnx {} BFD_RELOC_MIPS_TLS_TPREL32
+@deffnx {} BFD_RELOC_MIPS_TLS_TPREL64
+@deffnx {} BFD_RELOC_MIPS_TLS_TPREL_HI16
+@deffnx {} BFD_RELOC_MICROMIPS_TLS_TPREL_HI16
+@deffnx {} BFD_RELOC_MIPS_TLS_TPREL_LO16
+@deffnx {} BFD_RELOC_MICROMIPS_TLS_TPREL_LO16
+@deffnx {} BFD_RELOC_MIPS_EH
+MIPS ELF relocations.
+@end deffn
+@deffn {} BFD_RELOC_MIPS_COPY
+@deffnx {} BFD_RELOC_MIPS_JUMP_SLOT
+MIPS ELF relocations (VxWorks and PLT extensions).
+@end deffn
+@deffn {} BFD_RELOC_MOXIE_10_PCREL
+Moxie ELF relocations.
+@end deffn
+@deffn {} BFD_RELOC_FRV_LABEL16
+@deffnx {} BFD_RELOC_FRV_LABEL24
+@deffnx {} BFD_RELOC_FRV_LO16
+@deffnx {} BFD_RELOC_FRV_HI16
+@deffnx {} BFD_RELOC_FRV_GPREL12
+@deffnx {} BFD_RELOC_FRV_GPRELU12
+@deffnx {} BFD_RELOC_FRV_GPREL32
+@deffnx {} BFD_RELOC_FRV_GPRELHI
+@deffnx {} BFD_RELOC_FRV_GPRELLO
+@deffnx {} BFD_RELOC_FRV_GOT12
+@deffnx {} BFD_RELOC_FRV_GOTHI
+@deffnx {} BFD_RELOC_FRV_GOTLO
+@deffnx {} BFD_RELOC_FRV_FUNCDESC
+@deffnx {} BFD_RELOC_FRV_FUNCDESC_GOT12
+@deffnx {} BFD_RELOC_FRV_FUNCDESC_GOTHI
+@deffnx {} BFD_RELOC_FRV_FUNCDESC_GOTLO
+@deffnx {} BFD_RELOC_FRV_FUNCDESC_VALUE
+@deffnx {} BFD_RELOC_FRV_FUNCDESC_GOTOFF12
+@deffnx {} BFD_RELOC_FRV_FUNCDESC_GOTOFFHI
+@deffnx {} BFD_RELOC_FRV_FUNCDESC_GOTOFFLO
+@deffnx {} BFD_RELOC_FRV_GOTOFF12
+@deffnx {} BFD_RELOC_FRV_GOTOFFHI
+@deffnx {} BFD_RELOC_FRV_GOTOFFLO
+@deffnx {} BFD_RELOC_FRV_GETTLSOFF
+@deffnx {} BFD_RELOC_FRV_TLSDESC_VALUE
+@deffnx {} BFD_RELOC_FRV_GOTTLSDESC12
+@deffnx {} BFD_RELOC_FRV_GOTTLSDESCHI
+@deffnx {} BFD_RELOC_FRV_GOTTLSDESCLO
+@deffnx {} BFD_RELOC_FRV_TLSMOFF12
+@deffnx {} BFD_RELOC_FRV_TLSMOFFHI
+@deffnx {} BFD_RELOC_FRV_TLSMOFFLO
+@deffnx {} BFD_RELOC_FRV_GOTTLSOFF12
+@deffnx {} BFD_RELOC_FRV_GOTTLSOFFHI
+@deffnx {} BFD_RELOC_FRV_GOTTLSOFFLO
+@deffnx {} BFD_RELOC_FRV_TLSOFF
+@deffnx {} BFD_RELOC_FRV_TLSDESC_RELAX
+@deffnx {} BFD_RELOC_FRV_GETTLSOFF_RELAX
+@deffnx {} BFD_RELOC_FRV_TLSOFF_RELAX
+@deffnx {} BFD_RELOC_FRV_TLSMOFF
+Fujitsu Frv Relocations.
+@end deffn
+@deffn {} BFD_RELOC_MN10300_GOTOFF24
+This is a 24bit GOT-relative reloc for the mn10300.
+@end deffn
+@deffn {} BFD_RELOC_MN10300_GOT32
+This is a 32bit GOT-relative reloc for the mn10300, offset by two bytes
+in the instruction.
+@end deffn
+@deffn {} BFD_RELOC_MN10300_GOT24
+This is a 24bit GOT-relative reloc for the mn10300, offset by two bytes
+in the instruction.
+@end deffn
+@deffn {} BFD_RELOC_MN10300_GOT16
+This is a 16bit GOT-relative reloc for the mn10300, offset by two bytes
+in the instruction.
+@end deffn
+@deffn {} BFD_RELOC_MN10300_COPY
+Copy symbol at runtime.
+@end deffn
+@deffn {} BFD_RELOC_MN10300_GLOB_DAT
+Create GOT entry.
+@end deffn
+@deffn {} BFD_RELOC_MN10300_JMP_SLOT
+Create PLT entry.
+@end deffn
+@deffn {} BFD_RELOC_MN10300_RELATIVE
+Adjust by program base.
+@end deffn
+@deffn {} BFD_RELOC_MN10300_SYM_DIFF
+Together with another reloc targeted at the same location,
+allows for a value that is the difference of two symbols
+in the same section.
+@end deffn
+@deffn {} BFD_RELOC_MN10300_ALIGN
+The addend of this reloc is an alignment power that must
+be honoured at the offset's location, regardless of linker
+relaxation.
+@end deffn
+@deffn {} BFD_RELOC_MN10300_TLS_GD
+@deffnx {} BFD_RELOC_MN10300_TLS_LD
+@deffnx {} BFD_RELOC_MN10300_TLS_LDO
+@deffnx {} BFD_RELOC_MN10300_TLS_GOTIE
+@deffnx {} BFD_RELOC_MN10300_TLS_IE
+@deffnx {} BFD_RELOC_MN10300_TLS_LE
+@deffnx {} BFD_RELOC_MN10300_TLS_DTPMOD
+@deffnx {} BFD_RELOC_MN10300_TLS_DTPOFF
+@deffnx {} BFD_RELOC_MN10300_TLS_TPOFF
+Various TLS-related relocations.
+@end deffn
+@deffn {} BFD_RELOC_MN10300_32_PCREL
+This is a 32bit pcrel reloc for the mn10300, offset by two bytes in the
+instruction.
+@end deffn
+@deffn {} BFD_RELOC_MN10300_16_PCREL
+This is a 16bit pcrel reloc for the mn10300, offset by two bytes in the
+instruction.
+@end deffn
+@deffn {} BFD_RELOC_386_GOT32
+@deffnx {} BFD_RELOC_386_PLT32
+@deffnx {} BFD_RELOC_386_COPY
+@deffnx {} BFD_RELOC_386_GLOB_DAT
+@deffnx {} BFD_RELOC_386_JUMP_SLOT
+@deffnx {} BFD_RELOC_386_RELATIVE
+@deffnx {} BFD_RELOC_386_GOTOFF
+@deffnx {} BFD_RELOC_386_GOTPC
+@deffnx {} BFD_RELOC_386_TLS_TPOFF
+@deffnx {} BFD_RELOC_386_TLS_IE
+@deffnx {} BFD_RELOC_386_TLS_GOTIE
+@deffnx {} BFD_RELOC_386_TLS_LE
+@deffnx {} BFD_RELOC_386_TLS_GD
+@deffnx {} BFD_RELOC_386_TLS_LDM
+@deffnx {} BFD_RELOC_386_TLS_LDO_32
+@deffnx {} BFD_RELOC_386_TLS_IE_32
+@deffnx {} BFD_RELOC_386_TLS_LE_32
+@deffnx {} BFD_RELOC_386_TLS_DTPMOD32
+@deffnx {} BFD_RELOC_386_TLS_DTPOFF32
+@deffnx {} BFD_RELOC_386_TLS_TPOFF32
+@deffnx {} BFD_RELOC_386_TLS_GOTDESC
+@deffnx {} BFD_RELOC_386_TLS_DESC_CALL
+@deffnx {} BFD_RELOC_386_TLS_DESC
+@deffnx {} BFD_RELOC_386_IRELATIVE
+i386/elf relocations
+@end deffn
+@deffn {} BFD_RELOC_X86_64_GOT32
+@deffnx {} BFD_RELOC_X86_64_PLT32
+@deffnx {} BFD_RELOC_X86_64_COPY
+@deffnx {} BFD_RELOC_X86_64_GLOB_DAT
+@deffnx {} BFD_RELOC_X86_64_JUMP_SLOT
+@deffnx {} BFD_RELOC_X86_64_RELATIVE
+@deffnx {} BFD_RELOC_X86_64_GOTPCREL
+@deffnx {} BFD_RELOC_X86_64_32S
+@deffnx {} BFD_RELOC_X86_64_DTPMOD64
+@deffnx {} BFD_RELOC_X86_64_DTPOFF64
+@deffnx {} BFD_RELOC_X86_64_TPOFF64
+@deffnx {} BFD_RELOC_X86_64_TLSGD
+@deffnx {} BFD_RELOC_X86_64_TLSLD
+@deffnx {} BFD_RELOC_X86_64_DTPOFF32
+@deffnx {} BFD_RELOC_X86_64_GOTTPOFF
+@deffnx {} BFD_RELOC_X86_64_TPOFF32
+@deffnx {} BFD_RELOC_X86_64_GOTOFF64
+@deffnx {} BFD_RELOC_X86_64_GOTPC32
+@deffnx {} BFD_RELOC_X86_64_GOT64
+@deffnx {} BFD_RELOC_X86_64_GOTPCREL64
+@deffnx {} BFD_RELOC_X86_64_GOTPC64
+@deffnx {} BFD_RELOC_X86_64_GOTPLT64
+@deffnx {} BFD_RELOC_X86_64_PLTOFF64
+@deffnx {} BFD_RELOC_X86_64_GOTPC32_TLSDESC
+@deffnx {} BFD_RELOC_X86_64_TLSDESC_CALL
+@deffnx {} BFD_RELOC_X86_64_TLSDESC
+@deffnx {} BFD_RELOC_X86_64_IRELATIVE
+@deffnx {} BFD_RELOC_X86_64_PC32_BND
+@deffnx {} BFD_RELOC_X86_64_PLT32_BND
+x86-64/elf relocations
+@end deffn
+@deffn {} BFD_RELOC_NS32K_IMM_8
+@deffnx {} BFD_RELOC_NS32K_IMM_16
+@deffnx {} BFD_RELOC_NS32K_IMM_32
+@deffnx {} BFD_RELOC_NS32K_IMM_8_PCREL
+@deffnx {} BFD_RELOC_NS32K_IMM_16_PCREL
+@deffnx {} BFD_RELOC_NS32K_IMM_32_PCREL
+@deffnx {} BFD_RELOC_NS32K_DISP_8
+@deffnx {} BFD_RELOC_NS32K_DISP_16
+@deffnx {} BFD_RELOC_NS32K_DISP_32
+@deffnx {} BFD_RELOC_NS32K_DISP_8_PCREL
+@deffnx {} BFD_RELOC_NS32K_DISP_16_PCREL
+@deffnx {} BFD_RELOC_NS32K_DISP_32_PCREL
+ns32k relocations
+@end deffn
+@deffn {} BFD_RELOC_PDP11_DISP_8_PCREL
+@deffnx {} BFD_RELOC_PDP11_DISP_6_PCREL
+PDP11 relocations
+@end deffn
+@deffn {} BFD_RELOC_PJ_CODE_HI16
+@deffnx {} BFD_RELOC_PJ_CODE_LO16
+@deffnx {} BFD_RELOC_PJ_CODE_DIR16
+@deffnx {} BFD_RELOC_PJ_CODE_DIR32
+@deffnx {} BFD_RELOC_PJ_CODE_REL16
+@deffnx {} BFD_RELOC_PJ_CODE_REL32
+Picojava relocs. Not all of these appear in object files.
+@end deffn
+@deffn {} BFD_RELOC_PPC_B26
+@deffnx {} BFD_RELOC_PPC_BA26
+@deffnx {} BFD_RELOC_PPC_TOC16
+@deffnx {} BFD_RELOC_PPC_B16
+@deffnx {} BFD_RELOC_PPC_B16_BRTAKEN
+@deffnx {} BFD_RELOC_PPC_B16_BRNTAKEN
+@deffnx {} BFD_RELOC_PPC_BA16
+@deffnx {} BFD_RELOC_PPC_BA16_BRTAKEN
+@deffnx {} BFD_RELOC_PPC_BA16_BRNTAKEN
+@deffnx {} BFD_RELOC_PPC_COPY
+@deffnx {} BFD_RELOC_PPC_GLOB_DAT
+@deffnx {} BFD_RELOC_PPC_JMP_SLOT
+@deffnx {} BFD_RELOC_PPC_RELATIVE
+@deffnx {} BFD_RELOC_PPC_LOCAL24PC
+@deffnx {} BFD_RELOC_PPC_EMB_NADDR32
+@deffnx {} BFD_RELOC_PPC_EMB_NADDR16
+@deffnx {} BFD_RELOC_PPC_EMB_NADDR16_LO
+@deffnx {} BFD_RELOC_PPC_EMB_NADDR16_HI
+@deffnx {} BFD_RELOC_PPC_EMB_NADDR16_HA
+@deffnx {} BFD_RELOC_PPC_EMB_SDAI16
+@deffnx {} BFD_RELOC_PPC_EMB_SDA2I16
+@deffnx {} BFD_RELOC_PPC_EMB_SDA2REL
+@deffnx {} BFD_RELOC_PPC_EMB_SDA21
+@deffnx {} BFD_RELOC_PPC_EMB_MRKREF
+@deffnx {} BFD_RELOC_PPC_EMB_RELSEC16
+@deffnx {} BFD_RELOC_PPC_EMB_RELST_LO
+@deffnx {} BFD_RELOC_PPC_EMB_RELST_HI
+@deffnx {} BFD_RELOC_PPC_EMB_RELST_HA
+@deffnx {} BFD_RELOC_PPC_EMB_BIT_FLD
+@deffnx {} BFD_RELOC_PPC_EMB_RELSDA
+@deffnx {} BFD_RELOC_PPC_VLE_REL8
+@deffnx {} BFD_RELOC_PPC_VLE_REL15
+@deffnx {} BFD_RELOC_PPC_VLE_REL24
+@deffnx {} BFD_RELOC_PPC_VLE_LO16A
+@deffnx {} BFD_RELOC_PPC_VLE_LO16D
+@deffnx {} BFD_RELOC_PPC_VLE_HI16A
+@deffnx {} BFD_RELOC_PPC_VLE_HI16D
+@deffnx {} BFD_RELOC_PPC_VLE_HA16A
+@deffnx {} BFD_RELOC_PPC_VLE_HA16D
+@deffnx {} BFD_RELOC_PPC_VLE_SDA21
+@deffnx {} BFD_RELOC_PPC_VLE_SDA21_LO
+@deffnx {} BFD_RELOC_PPC_VLE_SDAREL_LO16A
+@deffnx {} BFD_RELOC_PPC_VLE_SDAREL_LO16D
+@deffnx {} BFD_RELOC_PPC_VLE_SDAREL_HI16A
+@deffnx {} BFD_RELOC_PPC_VLE_SDAREL_HI16D
+@deffnx {} BFD_RELOC_PPC_VLE_SDAREL_HA16A
+@deffnx {} BFD_RELOC_PPC_VLE_SDAREL_HA16D
+@deffnx {} BFD_RELOC_PPC64_HIGHER
+@deffnx {} BFD_RELOC_PPC64_HIGHER_S
+@deffnx {} BFD_RELOC_PPC64_HIGHEST
+@deffnx {} BFD_RELOC_PPC64_HIGHEST_S
+@deffnx {} BFD_RELOC_PPC64_TOC16_LO
+@deffnx {} BFD_RELOC_PPC64_TOC16_HI
+@deffnx {} BFD_RELOC_PPC64_TOC16_HA
+@deffnx {} BFD_RELOC_PPC64_TOC
+@deffnx {} BFD_RELOC_PPC64_PLTGOT16
+@deffnx {} BFD_RELOC_PPC64_PLTGOT16_LO
+@deffnx {} BFD_RELOC_PPC64_PLTGOT16_HI
+@deffnx {} BFD_RELOC_PPC64_PLTGOT16_HA
+@deffnx {} BFD_RELOC_PPC64_ADDR16_DS
+@deffnx {} BFD_RELOC_PPC64_ADDR16_LO_DS
+@deffnx {} BFD_RELOC_PPC64_GOT16_DS
+@deffnx {} BFD_RELOC_PPC64_GOT16_LO_DS
+@deffnx {} BFD_RELOC_PPC64_PLT16_LO_DS
+@deffnx {} BFD_RELOC_PPC64_SECTOFF_DS
+@deffnx {} BFD_RELOC_PPC64_SECTOFF_LO_DS
+@deffnx {} BFD_RELOC_PPC64_TOC16_DS
+@deffnx {} BFD_RELOC_PPC64_TOC16_LO_DS
+@deffnx {} BFD_RELOC_PPC64_PLTGOT16_DS
+@deffnx {} BFD_RELOC_PPC64_PLTGOT16_LO_DS
+@deffnx {} BFD_RELOC_PPC64_ADDR16_HIGH
+@deffnx {} BFD_RELOC_PPC64_ADDR16_HIGHA
+@deffnx {} BFD_RELOC_PPC64_ADDR64_LOCAL
+Power(rs6000) and PowerPC relocations.
+@end deffn
+@deffn {} BFD_RELOC_PPC_TLS
+@deffnx {} BFD_RELOC_PPC_TLSGD
+@deffnx {} BFD_RELOC_PPC_TLSLD
+@deffnx {} BFD_RELOC_PPC_DTPMOD
+@deffnx {} BFD_RELOC_PPC_TPREL16
+@deffnx {} BFD_RELOC_PPC_TPREL16_LO
+@deffnx {} BFD_RELOC_PPC_TPREL16_HI
+@deffnx {} BFD_RELOC_PPC_TPREL16_HA
+@deffnx {} BFD_RELOC_PPC_TPREL
+@deffnx {} BFD_RELOC_PPC_DTPREL16
+@deffnx {} BFD_RELOC_PPC_DTPREL16_LO
+@deffnx {} BFD_RELOC_PPC_DTPREL16_HI
+@deffnx {} BFD_RELOC_PPC_DTPREL16_HA
+@deffnx {} BFD_RELOC_PPC_DTPREL
+@deffnx {} BFD_RELOC_PPC_GOT_TLSGD16
+@deffnx {} BFD_RELOC_PPC_GOT_TLSGD16_LO
+@deffnx {} BFD_RELOC_PPC_GOT_TLSGD16_HI
+@deffnx {} BFD_RELOC_PPC_GOT_TLSGD16_HA
+@deffnx {} BFD_RELOC_PPC_GOT_TLSLD16
+@deffnx {} BFD_RELOC_PPC_GOT_TLSLD16_LO
+@deffnx {} BFD_RELOC_PPC_GOT_TLSLD16_HI
+@deffnx {} BFD_RELOC_PPC_GOT_TLSLD16_HA
+@deffnx {} BFD_RELOC_PPC_GOT_TPREL16
+@deffnx {} BFD_RELOC_PPC_GOT_TPREL16_LO
+@deffnx {} BFD_RELOC_PPC_GOT_TPREL16_HI
+@deffnx {} BFD_RELOC_PPC_GOT_TPREL16_HA
+@deffnx {} BFD_RELOC_PPC_GOT_DTPREL16
+@deffnx {} BFD_RELOC_PPC_GOT_DTPREL16_LO
+@deffnx {} BFD_RELOC_PPC_GOT_DTPREL16_HI
+@deffnx {} BFD_RELOC_PPC_GOT_DTPREL16_HA
+@deffnx {} BFD_RELOC_PPC64_TPREL16_DS
+@deffnx {} BFD_RELOC_PPC64_TPREL16_LO_DS
+@deffnx {} BFD_RELOC_PPC64_TPREL16_HIGHER
+@deffnx {} BFD_RELOC_PPC64_TPREL16_HIGHERA
+@deffnx {} BFD_RELOC_PPC64_TPREL16_HIGHEST
+@deffnx {} BFD_RELOC_PPC64_TPREL16_HIGHESTA
+@deffnx {} BFD_RELOC_PPC64_DTPREL16_DS
+@deffnx {} BFD_RELOC_PPC64_DTPREL16_LO_DS
+@deffnx {} BFD_RELOC_PPC64_DTPREL16_HIGHER
+@deffnx {} BFD_RELOC_PPC64_DTPREL16_HIGHERA
+@deffnx {} BFD_RELOC_PPC64_DTPREL16_HIGHEST
+@deffnx {} BFD_RELOC_PPC64_DTPREL16_HIGHESTA
+@deffnx {} BFD_RELOC_PPC64_TPREL16_HIGH
+@deffnx {} BFD_RELOC_PPC64_TPREL16_HIGHA
+@deffnx {} BFD_RELOC_PPC64_DTPREL16_HIGH
+@deffnx {} BFD_RELOC_PPC64_DTPREL16_HIGHA
+PowerPC and PowerPC64 thread-local storage relocations.
+@end deffn
+@deffn {} BFD_RELOC_I370_D12
+IBM 370/390 relocations
+@end deffn
+@deffn {} BFD_RELOC_CTOR
+The type of reloc used to build a constructor 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.
+@end deffn
+@deffn {} BFD_RELOC_ARM_PCREL_BRANCH
+ARM 26 bit pc-relative branch. The lowest two bits must be zero and are
+not stored in the instruction.
+@end deffn
+@deffn {} BFD_RELOC_ARM_PCREL_BLX
+ARM 26 bit pc-relative branch. The lowest bit must be zero and is
+not stored in the instruction. The 2nd lowest bit comes from a 1 bit
+field in the instruction.
+@end deffn
+@deffn {} BFD_RELOC_THUMB_PCREL_BLX
+Thumb 22 bit pc-relative branch. The lowest bit must be zero and is
+not stored in the instruction. The 2nd lowest bit comes from a 1 bit
+field in the instruction.
+@end deffn
+@deffn {} BFD_RELOC_ARM_PCREL_CALL
+ARM 26-bit pc-relative branch for an unconditional BL or BLX instruction.
+@end deffn
+@deffn {} BFD_RELOC_ARM_PCREL_JUMP
+ARM 26-bit pc-relative branch for B or conditional BL instruction.
+@end deffn
+@deffn {} BFD_RELOC_THUMB_PCREL_BRANCH7
+@deffnx {} BFD_RELOC_THUMB_PCREL_BRANCH9
+@deffnx {} BFD_RELOC_THUMB_PCREL_BRANCH12
+@deffnx {} BFD_RELOC_THUMB_PCREL_BRANCH20
+@deffnx {} BFD_RELOC_THUMB_PCREL_BRANCH23
+@deffnx {} BFD_RELOC_THUMB_PCREL_BRANCH25
+Thumb 7-, 9-, 12-, 20-, 23-, and 25-bit pc-relative branches.
+The lowest bit must be zero and is not stored in the instruction.
+Note that the corresponding ELF R_ARM_THM_JUMPnn constant has an
+"nn" one smaller in all cases. Note further that BRANCH23
+corresponds to R_ARM_THM_CALL.
+@end deffn
+@deffn {} BFD_RELOC_ARM_OFFSET_IMM
+12-bit immediate offset, used in ARM-format ldr and str instructions.
+@end deffn
+@deffn {} BFD_RELOC_ARM_THUMB_OFFSET
+5-bit immediate offset, used in Thumb-format ldr and str instructions.
+@end deffn
+@deffn {} BFD_RELOC_ARM_TARGET1
+Pc-relative or absolute relocation depending on target. Used for
+entries in .init_array sections.
+@end deffn
+@deffn {} BFD_RELOC_ARM_ROSEGREL32
+Read-only segment base relative address.
+@end deffn
+@deffn {} BFD_RELOC_ARM_SBREL32
+Data segment base relative address.
+@end deffn
+@deffn {} BFD_RELOC_ARM_TARGET2
+This reloc is used for references to RTTI data from exception handling
+tables. The actual definition depends on the target. It may be a
+pc-relative or some form of GOT-indirect relocation.
+@end deffn
+@deffn {} BFD_RELOC_ARM_PREL31
+31-bit PC relative address.
+@end deffn
+@deffn {} BFD_RELOC_ARM_MOVW
+@deffnx {} BFD_RELOC_ARM_MOVT
+@deffnx {} BFD_RELOC_ARM_MOVW_PCREL
+@deffnx {} BFD_RELOC_ARM_MOVT_PCREL
+@deffnx {} BFD_RELOC_ARM_THUMB_MOVW
+@deffnx {} BFD_RELOC_ARM_THUMB_MOVT
+@deffnx {} BFD_RELOC_ARM_THUMB_MOVW_PCREL
+@deffnx {} BFD_RELOC_ARM_THUMB_MOVT_PCREL
+Low and High halfword relocations for MOVW and MOVT instructions.
+@end deffn
+@deffn {} BFD_RELOC_ARM_JUMP_SLOT
+@deffnx {} BFD_RELOC_ARM_GLOB_DAT
+@deffnx {} BFD_RELOC_ARM_GOT32
+@deffnx {} BFD_RELOC_ARM_PLT32
+@deffnx {} BFD_RELOC_ARM_RELATIVE
+@deffnx {} BFD_RELOC_ARM_GOTOFF
+@deffnx {} BFD_RELOC_ARM_GOTPC
+@deffnx {} BFD_RELOC_ARM_GOT_PREL
+Relocations for setting up GOTs and PLTs for shared libraries.
+@end deffn
+@deffn {} BFD_RELOC_ARM_TLS_GD32
+@deffnx {} BFD_RELOC_ARM_TLS_LDO32
+@deffnx {} BFD_RELOC_ARM_TLS_LDM32
+@deffnx {} BFD_RELOC_ARM_TLS_DTPOFF32
+@deffnx {} BFD_RELOC_ARM_TLS_DTPMOD32
+@deffnx {} BFD_RELOC_ARM_TLS_TPOFF32
+@deffnx {} BFD_RELOC_ARM_TLS_IE32
+@deffnx {} BFD_RELOC_ARM_TLS_LE32
+@deffnx {} BFD_RELOC_ARM_TLS_GOTDESC
+@deffnx {} BFD_RELOC_ARM_TLS_CALL
+@deffnx {} BFD_RELOC_ARM_THM_TLS_CALL
+@deffnx {} BFD_RELOC_ARM_TLS_DESCSEQ
+@deffnx {} BFD_RELOC_ARM_THM_TLS_DESCSEQ
+@deffnx {} BFD_RELOC_ARM_TLS_DESC
+ARM thread-local storage relocations.
+@end deffn
+@deffn {} BFD_RELOC_ARM_ALU_PC_G0_NC
+@deffnx {} BFD_RELOC_ARM_ALU_PC_G0
+@deffnx {} BFD_RELOC_ARM_ALU_PC_G1_NC
+@deffnx {} BFD_RELOC_ARM_ALU_PC_G1
+@deffnx {} BFD_RELOC_ARM_ALU_PC_G2
+@deffnx {} BFD_RELOC_ARM_LDR_PC_G0
+@deffnx {} BFD_RELOC_ARM_LDR_PC_G1
+@deffnx {} BFD_RELOC_ARM_LDR_PC_G2
+@deffnx {} BFD_RELOC_ARM_LDRS_PC_G0
+@deffnx {} BFD_RELOC_ARM_LDRS_PC_G1
+@deffnx {} BFD_RELOC_ARM_LDRS_PC_G2
+@deffnx {} BFD_RELOC_ARM_LDC_PC_G0
+@deffnx {} BFD_RELOC_ARM_LDC_PC_G1
+@deffnx {} BFD_RELOC_ARM_LDC_PC_G2
+@deffnx {} BFD_RELOC_ARM_ALU_SB_G0_NC
+@deffnx {} BFD_RELOC_ARM_ALU_SB_G0
+@deffnx {} BFD_RELOC_ARM_ALU_SB_G1_NC
+@deffnx {} BFD_RELOC_ARM_ALU_SB_G1
+@deffnx {} BFD_RELOC_ARM_ALU_SB_G2
+@deffnx {} BFD_RELOC_ARM_LDR_SB_G0
+@deffnx {} BFD_RELOC_ARM_LDR_SB_G1
+@deffnx {} BFD_RELOC_ARM_LDR_SB_G2
+@deffnx {} BFD_RELOC_ARM_LDRS_SB_G0
+@deffnx {} BFD_RELOC_ARM_LDRS_SB_G1
+@deffnx {} BFD_RELOC_ARM_LDRS_SB_G2
+@deffnx {} BFD_RELOC_ARM_LDC_SB_G0
+@deffnx {} BFD_RELOC_ARM_LDC_SB_G1
+@deffnx {} BFD_RELOC_ARM_LDC_SB_G2
+ARM group relocations.
+@end deffn
+@deffn {} BFD_RELOC_ARM_V4BX
+Annotation of BX instructions.
+@end deffn
+@deffn {} BFD_RELOC_ARM_IRELATIVE
+ARM support for STT_GNU_IFUNC.
+@end deffn
+@deffn {} BFD_RELOC_ARM_IMMEDIATE
+@deffnx {} BFD_RELOC_ARM_ADRL_IMMEDIATE
+@deffnx {} BFD_RELOC_ARM_T32_IMMEDIATE
+@deffnx {} BFD_RELOC_ARM_T32_ADD_IMM
+@deffnx {} BFD_RELOC_ARM_T32_IMM12
+@deffnx {} BFD_RELOC_ARM_T32_ADD_PC12
+@deffnx {} BFD_RELOC_ARM_SHIFT_IMM
+@deffnx {} BFD_RELOC_ARM_SMC
+@deffnx {} BFD_RELOC_ARM_HVC
+@deffnx {} BFD_RELOC_ARM_SWI
+@deffnx {} BFD_RELOC_ARM_MULTI
+@deffnx {} BFD_RELOC_ARM_CP_OFF_IMM
+@deffnx {} BFD_RELOC_ARM_CP_OFF_IMM_S2
+@deffnx {} BFD_RELOC_ARM_T32_CP_OFF_IMM
+@deffnx {} BFD_RELOC_ARM_T32_CP_OFF_IMM_S2
+@deffnx {} BFD_RELOC_ARM_ADR_IMM
+@deffnx {} BFD_RELOC_ARM_LDR_IMM
+@deffnx {} BFD_RELOC_ARM_LITERAL
+@deffnx {} BFD_RELOC_ARM_IN_POOL
+@deffnx {} BFD_RELOC_ARM_OFFSET_IMM8
+@deffnx {} BFD_RELOC_ARM_T32_OFFSET_U8
+@deffnx {} BFD_RELOC_ARM_T32_OFFSET_IMM
+@deffnx {} BFD_RELOC_ARM_HWLITERAL
+@deffnx {} BFD_RELOC_ARM_THUMB_ADD
+@deffnx {} BFD_RELOC_ARM_THUMB_IMM
+@deffnx {} BFD_RELOC_ARM_THUMB_SHIFT
+These relocs are only used within the ARM assembler. They are not
+(at present) written to any object files.
+@end deffn
+@deffn {} BFD_RELOC_SH_PCDISP8BY2
+@deffnx {} BFD_RELOC_SH_PCDISP12BY2
+@deffnx {} BFD_RELOC_SH_IMM3
+@deffnx {} BFD_RELOC_SH_IMM3U
+@deffnx {} BFD_RELOC_SH_DISP12
+@deffnx {} BFD_RELOC_SH_DISP12BY2
+@deffnx {} BFD_RELOC_SH_DISP12BY4
+@deffnx {} BFD_RELOC_SH_DISP12BY8
+@deffnx {} BFD_RELOC_SH_DISP20
+@deffnx {} BFD_RELOC_SH_DISP20BY8
+@deffnx {} BFD_RELOC_SH_IMM4
+@deffnx {} BFD_RELOC_SH_IMM4BY2
+@deffnx {} BFD_RELOC_SH_IMM4BY4
+@deffnx {} BFD_RELOC_SH_IMM8
+@deffnx {} BFD_RELOC_SH_IMM8BY2
+@deffnx {} BFD_RELOC_SH_IMM8BY4
+@deffnx {} BFD_RELOC_SH_PCRELIMM8BY2
+@deffnx {} BFD_RELOC_SH_PCRELIMM8BY4
+@deffnx {} BFD_RELOC_SH_SWITCH16
+@deffnx {} BFD_RELOC_SH_SWITCH32
+@deffnx {} BFD_RELOC_SH_USES
+@deffnx {} BFD_RELOC_SH_COUNT
+@deffnx {} BFD_RELOC_SH_ALIGN
+@deffnx {} BFD_RELOC_SH_CODE
+@deffnx {} BFD_RELOC_SH_DATA
+@deffnx {} BFD_RELOC_SH_LABEL
+@deffnx {} BFD_RELOC_SH_LOOP_START
+@deffnx {} BFD_RELOC_SH_LOOP_END
+@deffnx {} BFD_RELOC_SH_COPY
+@deffnx {} BFD_RELOC_SH_GLOB_DAT
+@deffnx {} BFD_RELOC_SH_JMP_SLOT
+@deffnx {} BFD_RELOC_SH_RELATIVE
+@deffnx {} BFD_RELOC_SH_GOTPC
+@deffnx {} BFD_RELOC_SH_GOT_LOW16
+@deffnx {} BFD_RELOC_SH_GOT_MEDLOW16
+@deffnx {} BFD_RELOC_SH_GOT_MEDHI16
+@deffnx {} BFD_RELOC_SH_GOT_HI16
+@deffnx {} BFD_RELOC_SH_GOTPLT_LOW16
+@deffnx {} BFD_RELOC_SH_GOTPLT_MEDLOW16
+@deffnx {} BFD_RELOC_SH_GOTPLT_MEDHI16
+@deffnx {} BFD_RELOC_SH_GOTPLT_HI16
+@deffnx {} BFD_RELOC_SH_PLT_LOW16
+@deffnx {} BFD_RELOC_SH_PLT_MEDLOW16
+@deffnx {} BFD_RELOC_SH_PLT_MEDHI16
+@deffnx {} BFD_RELOC_SH_PLT_HI16
+@deffnx {} BFD_RELOC_SH_GOTOFF_LOW16
+@deffnx {} BFD_RELOC_SH_GOTOFF_MEDLOW16
+@deffnx {} BFD_RELOC_SH_GOTOFF_MEDHI16
+@deffnx {} BFD_RELOC_SH_GOTOFF_HI16
+@deffnx {} BFD_RELOC_SH_GOTPC_LOW16
+@deffnx {} BFD_RELOC_SH_GOTPC_MEDLOW16
+@deffnx {} BFD_RELOC_SH_GOTPC_MEDHI16
+@deffnx {} BFD_RELOC_SH_GOTPC_HI16
+@deffnx {} BFD_RELOC_SH_COPY64
+@deffnx {} BFD_RELOC_SH_GLOB_DAT64
+@deffnx {} BFD_RELOC_SH_JMP_SLOT64
+@deffnx {} BFD_RELOC_SH_RELATIVE64
+@deffnx {} BFD_RELOC_SH_GOT10BY4
+@deffnx {} BFD_RELOC_SH_GOT10BY8
+@deffnx {} BFD_RELOC_SH_GOTPLT10BY4
+@deffnx {} BFD_RELOC_SH_GOTPLT10BY8
+@deffnx {} BFD_RELOC_SH_GOTPLT32
+@deffnx {} BFD_RELOC_SH_SHMEDIA_CODE
+@deffnx {} BFD_RELOC_SH_IMMU5
+@deffnx {} BFD_RELOC_SH_IMMS6
+@deffnx {} BFD_RELOC_SH_IMMS6BY32
+@deffnx {} BFD_RELOC_SH_IMMU6
+@deffnx {} BFD_RELOC_SH_IMMS10
+@deffnx {} BFD_RELOC_SH_IMMS10BY2
+@deffnx {} BFD_RELOC_SH_IMMS10BY4
+@deffnx {} BFD_RELOC_SH_IMMS10BY8
+@deffnx {} BFD_RELOC_SH_IMMS16
+@deffnx {} BFD_RELOC_SH_IMMU16
+@deffnx {} BFD_RELOC_SH_IMM_LOW16
+@deffnx {} BFD_RELOC_SH_IMM_LOW16_PCREL
+@deffnx {} BFD_RELOC_SH_IMM_MEDLOW16
+@deffnx {} BFD_RELOC_SH_IMM_MEDLOW16_PCREL
+@deffnx {} BFD_RELOC_SH_IMM_MEDHI16
+@deffnx {} BFD_RELOC_SH_IMM_MEDHI16_PCREL
+@deffnx {} BFD_RELOC_SH_IMM_HI16
+@deffnx {} BFD_RELOC_SH_IMM_HI16_PCREL
+@deffnx {} BFD_RELOC_SH_PT_16
+@deffnx {} BFD_RELOC_SH_TLS_GD_32
+@deffnx {} BFD_RELOC_SH_TLS_LD_32
+@deffnx {} BFD_RELOC_SH_TLS_LDO_32
+@deffnx {} BFD_RELOC_SH_TLS_IE_32
+@deffnx {} BFD_RELOC_SH_TLS_LE_32
+@deffnx {} BFD_RELOC_SH_TLS_DTPMOD32
+@deffnx {} BFD_RELOC_SH_TLS_DTPOFF32
+@deffnx {} BFD_RELOC_SH_TLS_TPOFF32
+@deffnx {} BFD_RELOC_SH_GOT20
+@deffnx {} BFD_RELOC_SH_GOTOFF20
+@deffnx {} BFD_RELOC_SH_GOTFUNCDESC
+@deffnx {} BFD_RELOC_SH_GOTFUNCDESC20
+@deffnx {} BFD_RELOC_SH_GOTOFFFUNCDESC
+@deffnx {} BFD_RELOC_SH_GOTOFFFUNCDESC20
+@deffnx {} BFD_RELOC_SH_FUNCDESC
+Renesas / SuperH SH relocs. Not all of these appear in object files.
+@end deffn
+@deffn {} BFD_RELOC_ARC_B22_PCREL
+ARC Cores 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.
+@end deffn
+@deffn {} BFD_RELOC_ARC_B26
+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.
+@end deffn
+@deffn {} BFD_RELOC_BFIN_16_IMM
+ADI Blackfin 16 bit immediate absolute reloc.
+@end deffn
+@deffn {} BFD_RELOC_BFIN_16_HIGH
+ADI Blackfin 16 bit immediate absolute reloc higher 16 bits.
+@end deffn
+@deffn {} BFD_RELOC_BFIN_4_PCREL
+ADI Blackfin 'a' part of LSETUP.
+@end deffn
+@deffn {} BFD_RELOC_BFIN_5_PCREL
+ADI Blackfin.
+@end deffn
+@deffn {} BFD_RELOC_BFIN_16_LOW
+ADI Blackfin 16 bit immediate absolute reloc lower 16 bits.
+@end deffn
+@deffn {} BFD_RELOC_BFIN_10_PCREL
+ADI Blackfin.
+@end deffn
+@deffn {} BFD_RELOC_BFIN_11_PCREL
+ADI Blackfin 'b' part of LSETUP.
+@end deffn
+@deffn {} BFD_RELOC_BFIN_12_PCREL_JUMP
+ADI Blackfin.
+@end deffn
+@deffn {} BFD_RELOC_BFIN_12_PCREL_JUMP_S
+ADI Blackfin Short jump, pcrel.
+@end deffn
+@deffn {} BFD_RELOC_BFIN_24_PCREL_CALL_X
+ADI Blackfin Call.x not implemented.
+@end deffn
+@deffn {} BFD_RELOC_BFIN_24_PCREL_JUMP_L
+ADI Blackfin Long Jump pcrel.
+@end deffn
+@deffn {} BFD_RELOC_BFIN_GOT17M4
+@deffnx {} BFD_RELOC_BFIN_GOTHI
+@deffnx {} BFD_RELOC_BFIN_GOTLO
+@deffnx {} BFD_RELOC_BFIN_FUNCDESC
+@deffnx {} BFD_RELOC_BFIN_FUNCDESC_GOT17M4
+@deffnx {} BFD_RELOC_BFIN_FUNCDESC_GOTHI
+@deffnx {} BFD_RELOC_BFIN_FUNCDESC_GOTLO
+@deffnx {} BFD_RELOC_BFIN_FUNCDESC_VALUE
+@deffnx {} BFD_RELOC_BFIN_FUNCDESC_GOTOFF17M4
+@deffnx {} BFD_RELOC_BFIN_FUNCDESC_GOTOFFHI
+@deffnx {} BFD_RELOC_BFIN_FUNCDESC_GOTOFFLO
+@deffnx {} BFD_RELOC_BFIN_GOTOFF17M4
+@deffnx {} BFD_RELOC_BFIN_GOTOFFHI
+@deffnx {} BFD_RELOC_BFIN_GOTOFFLO
+ADI Blackfin FD-PIC relocations.
+@end deffn
+@deffn {} BFD_RELOC_BFIN_GOT
+ADI Blackfin GOT relocation.
+@end deffn
+@deffn {} BFD_RELOC_BFIN_PLTPC
+ADI Blackfin PLTPC relocation.
+@end deffn
+@deffn {} BFD_ARELOC_BFIN_PUSH
+ADI Blackfin arithmetic relocation.
+@end deffn
+@deffn {} BFD_ARELOC_BFIN_CONST
+ADI Blackfin arithmetic relocation.
+@end deffn
+@deffn {} BFD_ARELOC_BFIN_ADD
+ADI Blackfin arithmetic relocation.
+@end deffn
+@deffn {} BFD_ARELOC_BFIN_SUB
+ADI Blackfin arithmetic relocation.
+@end deffn
+@deffn {} BFD_ARELOC_BFIN_MULT
+ADI Blackfin arithmetic relocation.
+@end deffn
+@deffn {} BFD_ARELOC_BFIN_DIV
+ADI Blackfin arithmetic relocation.
+@end deffn
+@deffn {} BFD_ARELOC_BFIN_MOD
+ADI Blackfin arithmetic relocation.
+@end deffn
+@deffn {} BFD_ARELOC_BFIN_LSHIFT
+ADI Blackfin arithmetic relocation.
+@end deffn
+@deffn {} BFD_ARELOC_BFIN_RSHIFT
+ADI Blackfin arithmetic relocation.
+@end deffn
+@deffn {} BFD_ARELOC_BFIN_AND
+ADI Blackfin arithmetic relocation.
+@end deffn
+@deffn {} BFD_ARELOC_BFIN_OR
+ADI Blackfin arithmetic relocation.
+@end deffn
+@deffn {} BFD_ARELOC_BFIN_XOR
+ADI Blackfin arithmetic relocation.
+@end deffn
+@deffn {} BFD_ARELOC_BFIN_LAND
+ADI Blackfin arithmetic relocation.
+@end deffn
+@deffn {} BFD_ARELOC_BFIN_LOR
+ADI Blackfin arithmetic relocation.
+@end deffn
+@deffn {} BFD_ARELOC_BFIN_LEN
+ADI Blackfin arithmetic relocation.
+@end deffn
+@deffn {} BFD_ARELOC_BFIN_NEG
+ADI Blackfin arithmetic relocation.
+@end deffn
+@deffn {} BFD_ARELOC_BFIN_COMP
+ADI Blackfin arithmetic relocation.
+@end deffn
+@deffn {} BFD_ARELOC_BFIN_PAGE
+ADI Blackfin arithmetic relocation.
+@end deffn
+@deffn {} BFD_ARELOC_BFIN_HWPAGE
+ADI Blackfin arithmetic relocation.
+@end deffn
+@deffn {} BFD_ARELOC_BFIN_ADDR
+ADI Blackfin arithmetic relocation.
+@end deffn
+@deffn {} BFD_RELOC_D10V_10_PCREL_R
+Mitsubishi D10V relocs.
+This is a 10-bit reloc with the right 2 bits
+assumed to be 0.
+@end deffn
+@deffn {} BFD_RELOC_D10V_10_PCREL_L
+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.
+@end deffn
+@deffn {} BFD_RELOC_D10V_18
+This is an 18-bit reloc with the right 2 bits
+assumed to be 0.
+@end deffn
+@deffn {} BFD_RELOC_D10V_18_PCREL
+This is an 18-bit reloc with the right 2 bits
+assumed to be 0.
+@end deffn
+@deffn {} BFD_RELOC_D30V_6
+Mitsubishi D30V relocs.
+This is a 6-bit absolute reloc.
+@end deffn
+@deffn {} BFD_RELOC_D30V_9_PCREL
+This is a 6-bit pc-relative reloc with
+the right 3 bits assumed to be 0.
+@end deffn
+@deffn {} BFD_RELOC_D30V_9_PCREL_R
+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.
+@end deffn
+@deffn {} BFD_RELOC_D30V_15
+This is a 12-bit absolute reloc with the
+right 3 bitsassumed to be 0.
+@end deffn
+@deffn {} BFD_RELOC_D30V_15_PCREL
+This is a 12-bit pc-relative reloc with
+the right 3 bits assumed to be 0.
+@end deffn
+@deffn {} BFD_RELOC_D30V_15_PCREL_R
+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.
+@end deffn
+@deffn {} BFD_RELOC_D30V_21
+This is an 18-bit absolute reloc with
+the right 3 bits assumed to be 0.
+@end deffn
+@deffn {} BFD_RELOC_D30V_21_PCREL
+This is an 18-bit pc-relative reloc with
+the right 3 bits assumed to be 0.
+@end deffn
+@deffn {} BFD_RELOC_D30V_21_PCREL_R
+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.
+@end deffn
+@deffn {} BFD_RELOC_D30V_32
+This is a 32-bit absolute reloc.
+@end deffn
+@deffn {} BFD_RELOC_D30V_32_PCREL
+This is a 32-bit pc-relative reloc.
+@end deffn
+@deffn {} BFD_RELOC_DLX_HI16_S
+DLX relocs
+@end deffn
+@deffn {} BFD_RELOC_DLX_LO16
+DLX relocs
+@end deffn
+@deffn {} BFD_RELOC_DLX_JMP26
+DLX relocs
+@end deffn
+@deffn {} BFD_RELOC_M32C_HI8
+@deffnx {} BFD_RELOC_M32C_RL_JUMP
+@deffnx {} BFD_RELOC_M32C_RL_1ADDR
+@deffnx {} BFD_RELOC_M32C_RL_2ADDR
+Renesas M16C/M32C Relocations.
+@end deffn
+@deffn {} BFD_RELOC_M32R_24
+Renesas M32R (formerly Mitsubishi M32R) relocs.
+This is a 24 bit absolute address.
+@end deffn
+@deffn {} BFD_RELOC_M32R_10_PCREL
+This is a 10-bit pc-relative reloc with the right 2 bits assumed to be 0.
+@end deffn
+@deffn {} BFD_RELOC_M32R_18_PCREL
+This is an 18-bit reloc with the right 2 bits assumed to be 0.
+@end deffn
+@deffn {} BFD_RELOC_M32R_26_PCREL
+This is a 26-bit reloc with the right 2 bits assumed to be 0.
+@end deffn
+@deffn {} 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 unsigned.
+@end deffn
+@deffn {} BFD_RELOC_M32R_HI16_SLO
+This is a 16-bit reloc containing the high 16 bits of an address
+used when the lower 16 bits are treated as signed.
+@end deffn
+@deffn {} BFD_RELOC_M32R_LO16
+This is a 16-bit reloc containing the lower 16 bits of an address.
+@end deffn
+@deffn {} BFD_RELOC_M32R_SDA16
+This is a 16-bit reloc containing the small data area offset for use in
+add3, load, and store instructions.
+@end deffn
+@deffn {} BFD_RELOC_M32R_GOT24
+@deffnx {} BFD_RELOC_M32R_26_PLTREL
+@deffnx {} BFD_RELOC_M32R_COPY
+@deffnx {} BFD_RELOC_M32R_GLOB_DAT
+@deffnx {} BFD_RELOC_M32R_JMP_SLOT
+@deffnx {} BFD_RELOC_M32R_RELATIVE
+@deffnx {} BFD_RELOC_M32R_GOTOFF
+@deffnx {} BFD_RELOC_M32R_GOTOFF_HI_ULO
+@deffnx {} BFD_RELOC_M32R_GOTOFF_HI_SLO
+@deffnx {} BFD_RELOC_M32R_GOTOFF_LO
+@deffnx {} BFD_RELOC_M32R_GOTPC24
+@deffnx {} BFD_RELOC_M32R_GOT16_HI_ULO
+@deffnx {} BFD_RELOC_M32R_GOT16_HI_SLO
+@deffnx {} BFD_RELOC_M32R_GOT16_LO
+@deffnx {} BFD_RELOC_M32R_GOTPC_HI_ULO
+@deffnx {} BFD_RELOC_M32R_GOTPC_HI_SLO
+@deffnx {} BFD_RELOC_M32R_GOTPC_LO
+For PIC.
+@end deffn
+@deffn {} BFD_RELOC_NDS32_20
+NDS32 relocs.
+This is a 20 bit absolute address.
+@end deffn
+@deffn {} BFD_RELOC_NDS32_9_PCREL
+This is a 9-bit pc-relative reloc with the right 1 bit assumed to be 0.
+@end deffn
+@deffn {} BFD_RELOC_NDS32_WORD_9_PCREL
+This is a 9-bit pc-relative reloc with the right 1 bit assumed to be 0.
+@end deffn
+@deffn {} BFD_RELOC_NDS32_15_PCREL
+This is an 15-bit reloc with the right 1 bit assumed to be 0.
+@end deffn
+@deffn {} BFD_RELOC_NDS32_17_PCREL
+This is an 17-bit reloc with the right 1 bit assumed to be 0.
+@end deffn
+@deffn {} BFD_RELOC_NDS32_25_PCREL
+This is a 25-bit reloc with the right 1 bit assumed to be 0.
+@end deffn
+@deffn {} BFD_RELOC_NDS32_HI20
+This is a 20-bit reloc containing the high 20 bits of an address
+used with the lower 12 bits
+@end deffn
+@deffn {} BFD_RELOC_NDS32_LO12S3
+This is a 12-bit reloc containing the lower 12 bits of an address
+then shift right by 3. This is used with ldi,sdi...
+@end deffn
+@deffn {} BFD_RELOC_NDS32_LO12S2
+This is a 12-bit reloc containing the lower 12 bits of an address
+then shift left by 2. This is used with lwi,swi...
+@end deffn
+@deffn {} BFD_RELOC_NDS32_LO12S1
+This is a 12-bit reloc containing the lower 12 bits of an address
+then shift left by 1. This is used with lhi,shi...
+@end deffn
+@deffn {} BFD_RELOC_NDS32_LO12S0
+This is a 12-bit reloc containing the lower 12 bits of an address
+then shift left by 0. This is used with lbisbi...
+@end deffn
+@deffn {} BFD_RELOC_NDS32_LO12S0_ORI
+This is a 12-bit reloc containing the lower 12 bits of an address
+then shift left by 0. This is only used with branch relaxations
+@end deffn
+@deffn {} BFD_RELOC_NDS32_SDA15S3
+This is a 15-bit reloc containing the small data area 18-bit signed offset
+and shift left by 3 for use in ldi, sdi...
+@end deffn
+@deffn {} BFD_RELOC_NDS32_SDA15S2
+This is a 15-bit reloc containing the small data area 17-bit signed offset
+and shift left by 2 for use in lwi, swi...
+@end deffn
+@deffn {} BFD_RELOC_NDS32_SDA15S1
+This is a 15-bit reloc containing the small data area 16-bit signed offset
+and shift left by 1 for use in lhi, shi...
+@end deffn
+@deffn {} BFD_RELOC_NDS32_SDA15S0
+This is a 15-bit reloc containing the small data area 15-bit signed offset
+and shift left by 0 for use in lbi, sbi...
+@end deffn
+@deffn {} BFD_RELOC_NDS32_SDA16S3
+This is a 16-bit reloc containing the small data area 16-bit signed offset
+and shift left by 3
+@end deffn
+@deffn {} BFD_RELOC_NDS32_SDA17S2
+This is a 17-bit reloc containing the small data area 17-bit signed offset
+and shift left by 2 for use in lwi.gp, swi.gp...
+@end deffn
+@deffn {} BFD_RELOC_NDS32_SDA18S1
+This is a 18-bit reloc containing the small data area 18-bit signed offset
+and shift left by 1 for use in lhi.gp, shi.gp...
+@end deffn
+@deffn {} BFD_RELOC_NDS32_SDA19S0
+This is a 19-bit reloc containing the small data area 19-bit signed offset
+and shift left by 0 for use in lbi.gp, sbi.gp...
+@end deffn
+@deffn {} BFD_RELOC_NDS32_GOT20
+@deffnx {} BFD_RELOC_NDS32_9_PLTREL
+@deffnx {} BFD_RELOC_NDS32_25_PLTREL
+@deffnx {} BFD_RELOC_NDS32_COPY
+@deffnx {} BFD_RELOC_NDS32_GLOB_DAT
+@deffnx {} BFD_RELOC_NDS32_JMP_SLOT
+@deffnx {} BFD_RELOC_NDS32_RELATIVE
+@deffnx {} BFD_RELOC_NDS32_GOTOFF
+@deffnx {} BFD_RELOC_NDS32_GOTOFF_HI20
+@deffnx {} BFD_RELOC_NDS32_GOTOFF_LO12
+@deffnx {} BFD_RELOC_NDS32_GOTPC20
+@deffnx {} BFD_RELOC_NDS32_GOT_HI20
+@deffnx {} BFD_RELOC_NDS32_GOT_LO12
+@deffnx {} BFD_RELOC_NDS32_GOTPC_HI20
+@deffnx {} BFD_RELOC_NDS32_GOTPC_LO12
+for PIC
+@end deffn
+@deffn {} BFD_RELOC_NDS32_INSN16
+@deffnx {} BFD_RELOC_NDS32_LABEL
+@deffnx {} BFD_RELOC_NDS32_LONGCALL1
+@deffnx {} BFD_RELOC_NDS32_LONGCALL2
+@deffnx {} BFD_RELOC_NDS32_LONGCALL3
+@deffnx {} BFD_RELOC_NDS32_LONGJUMP1
+@deffnx {} BFD_RELOC_NDS32_LONGJUMP2
+@deffnx {} BFD_RELOC_NDS32_LONGJUMP3
+@deffnx {} BFD_RELOC_NDS32_LOADSTORE
+@deffnx {} BFD_RELOC_NDS32_9_FIXED
+@deffnx {} BFD_RELOC_NDS32_15_FIXED
+@deffnx {} BFD_RELOC_NDS32_17_FIXED
+@deffnx {} BFD_RELOC_NDS32_25_FIXED
+@deffnx {} BFD_RELOC_NDS32_LONGCALL4
+@deffnx {} BFD_RELOC_NDS32_LONGCALL5
+@deffnx {} BFD_RELOC_NDS32_LONGCALL6
+@deffnx {} BFD_RELOC_NDS32_LONGJUMP4
+@deffnx {} BFD_RELOC_NDS32_LONGJUMP5
+@deffnx {} BFD_RELOC_NDS32_LONGJUMP6
+@deffnx {} BFD_RELOC_NDS32_LONGJUMP7
+for relax
+@end deffn
+@deffn {} BFD_RELOC_NDS32_PLTREL_HI20
+@deffnx {} BFD_RELOC_NDS32_PLTREL_LO12
+@deffnx {} BFD_RELOC_NDS32_PLT_GOTREL_HI20
+@deffnx {} BFD_RELOC_NDS32_PLT_GOTREL_LO12
+for PIC
+@end deffn
+@deffn {} BFD_RELOC_NDS32_SDA12S2_DP
+@deffnx {} BFD_RELOC_NDS32_SDA12S2_SP
+@deffnx {} BFD_RELOC_NDS32_LO12S2_DP
+@deffnx {} BFD_RELOC_NDS32_LO12S2_SP
+for floating point
+@end deffn
+@deffn {} BFD_RELOC_NDS32_DWARF2_OP1
+@deffnx {} BFD_RELOC_NDS32_DWARF2_OP2
+@deffnx {} BFD_RELOC_NDS32_DWARF2_LEB
+for dwarf2 debug_line.
+@end deffn
+@deffn {} BFD_RELOC_NDS32_UPDATE_TA
+for eliminate 16-bit instructions
+@end deffn
+@deffn {} BFD_RELOC_NDS32_PLT_GOTREL_LO20
+@deffnx {} BFD_RELOC_NDS32_PLT_GOTREL_LO15
+@deffnx {} BFD_RELOC_NDS32_PLT_GOTREL_LO19
+@deffnx {} BFD_RELOC_NDS32_GOT_LO15
+@deffnx {} BFD_RELOC_NDS32_GOT_LO19
+@deffnx {} BFD_RELOC_NDS32_GOTOFF_LO15
+@deffnx {} BFD_RELOC_NDS32_GOTOFF_LO19
+@deffnx {} BFD_RELOC_NDS32_GOT15S2
+@deffnx {} BFD_RELOC_NDS32_GOT17S2
+for PIC object relaxation
+@end deffn
+@deffn {} BFD_RELOC_NDS32_5
+NDS32 relocs.
+This is a 5 bit absolute address.
+@end deffn
+@deffn {} BFD_RELOC_NDS32_10_UPCREL
+This is a 10-bit unsigned pc-relative reloc with the right 1 bit assumed to be 0.
+@end deffn
+@deffn {} BFD_RELOC_NDS32_SDA_FP7U2_RELA
+If fp were omitted, fp can used as another gp.
+@end deffn
+@deffn {} BFD_RELOC_NDS32_RELAX_ENTRY
+@deffnx {} BFD_RELOC_NDS32_GOT_SUFF
+@deffnx {} BFD_RELOC_NDS32_GOTOFF_SUFF
+@deffnx {} BFD_RELOC_NDS32_PLT_GOT_SUFF
+@deffnx {} BFD_RELOC_NDS32_MULCALL_SUFF
+@deffnx {} BFD_RELOC_NDS32_PTR
+@deffnx {} BFD_RELOC_NDS32_PTR_COUNT
+@deffnx {} BFD_RELOC_NDS32_PTR_RESOLVED
+@deffnx {} BFD_RELOC_NDS32_PLTBLOCK
+@deffnx {} BFD_RELOC_NDS32_RELAX_REGION_BEGIN
+@deffnx {} BFD_RELOC_NDS32_RELAX_REGION_END
+@deffnx {} BFD_RELOC_NDS32_MINUEND
+@deffnx {} BFD_RELOC_NDS32_SUBTRAHEND
+@deffnx {} BFD_RELOC_NDS32_DIFF8
+@deffnx {} BFD_RELOC_NDS32_DIFF16
+@deffnx {} BFD_RELOC_NDS32_DIFF32
+@deffnx {} BFD_RELOC_NDS32_DIFF_ULEB128
+@deffnx {} BFD_RELOC_NDS32_EMPTY
+relaxation relative relocation types
+@end deffn
+@deffn {} BFD_RELOC_NDS32_25_ABS
+This is a 25 bit absolute address.
+@end deffn
+@deffn {} BFD_RELOC_NDS32_DATA
+@deffnx {} BFD_RELOC_NDS32_TRAN
+@deffnx {} BFD_RELOC_NDS32_17IFC_PCREL
+@deffnx {} BFD_RELOC_NDS32_10IFCU_PCREL
+For ex9 and ifc using.
+@end deffn
+@deffn {} BFD_RELOC_NDS32_TPOFF
+@deffnx {} BFD_RELOC_NDS32_TLS_LE_HI20
+@deffnx {} BFD_RELOC_NDS32_TLS_LE_LO12
+@deffnx {} BFD_RELOC_NDS32_TLS_LE_ADD
+@deffnx {} BFD_RELOC_NDS32_TLS_LE_LS
+@deffnx {} BFD_RELOC_NDS32_GOTTPOFF
+@deffnx {} BFD_RELOC_NDS32_TLS_IE_HI20
+@deffnx {} BFD_RELOC_NDS32_TLS_IE_LO12S2
+@deffnx {} BFD_RELOC_NDS32_TLS_TPOFF
+@deffnx {} BFD_RELOC_NDS32_TLS_LE_20
+@deffnx {} BFD_RELOC_NDS32_TLS_LE_15S0
+@deffnx {} BFD_RELOC_NDS32_TLS_LE_15S1
+@deffnx {} BFD_RELOC_NDS32_TLS_LE_15S2
+For TLS.
+@end deffn
+@deffn {} BFD_RELOC_V850_9_PCREL
+This is a 9-bit reloc
+@end deffn
+@deffn {} BFD_RELOC_V850_22_PCREL
+This is a 22-bit reloc
+@end deffn
+@deffn {} BFD_RELOC_V850_SDA_16_16_OFFSET
+This is a 16 bit offset from the short data area pointer.
+@end deffn
+@deffn {} BFD_RELOC_V850_SDA_15_16_OFFSET
+This is a 16 bit offset (of which only 15 bits are used) from the
+short data area pointer.
+@end deffn
+@deffn {} BFD_RELOC_V850_ZDA_16_16_OFFSET
+This is a 16 bit offset from the zero data area pointer.
+@end deffn
+@deffn {} BFD_RELOC_V850_ZDA_15_16_OFFSET
+This is a 16 bit offset (of which only 15 bits are used) from the
+zero data area pointer.
+@end deffn
+@deffn {} BFD_RELOC_V850_TDA_6_8_OFFSET
+This is an 8 bit offset (of which only 6 bits are used) from the
+tiny data area pointer.
+@end deffn
+@deffn {} BFD_RELOC_V850_TDA_7_8_OFFSET
+This is an 8bit offset (of which only 7 bits are used) from the tiny
+data area pointer.
+@end deffn
+@deffn {} BFD_RELOC_V850_TDA_7_7_OFFSET
+This is a 7 bit offset from the tiny data area pointer.
+@end deffn
+@deffn {} BFD_RELOC_V850_TDA_16_16_OFFSET
+This is a 16 bit offset from the tiny data area pointer.
+@end deffn
+@deffn {} BFD_RELOC_V850_TDA_4_5_OFFSET
+This is a 5 bit offset (of which only 4 bits are used) from the tiny
+data area pointer.
+@end deffn
+@deffn {} BFD_RELOC_V850_TDA_4_4_OFFSET
+This is a 4 bit offset from the tiny data area pointer.
+@end deffn
+@deffn {} BFD_RELOC_V850_SDA_16_16_SPLIT_OFFSET
+This is a 16 bit offset from the short data area pointer, with the
+bits placed non-contiguously in the instruction.
+@end deffn
+@deffn {} BFD_RELOC_V850_ZDA_16_16_SPLIT_OFFSET
+This is a 16 bit offset from the zero data area pointer, with the
+bits placed non-contiguously in the instruction.
+@end deffn
+@deffn {} BFD_RELOC_V850_CALLT_6_7_OFFSET
+This is a 6 bit offset from the call table base pointer.
+@end deffn
+@deffn {} BFD_RELOC_V850_CALLT_16_16_OFFSET
+This is a 16 bit offset from the call table base pointer.
+@end deffn
+@deffn {} BFD_RELOC_V850_LONGCALL
+Used for relaxing indirect function calls.
+@end deffn
+@deffn {} BFD_RELOC_V850_LONGJUMP
+Used for relaxing indirect jumps.
+@end deffn
+@deffn {} BFD_RELOC_V850_ALIGN
+Used to maintain alignment whilst relaxing.
+@end deffn
+@deffn {} BFD_RELOC_V850_LO16_SPLIT_OFFSET
+This is a variation of BFD_RELOC_LO16 that can be used in v850e ld.bu
+instructions.
+@end deffn
+@deffn {} BFD_RELOC_V850_16_PCREL
+This is a 16-bit reloc.
+@end deffn
+@deffn {} BFD_RELOC_V850_17_PCREL
+This is a 17-bit reloc.
+@end deffn
+@deffn {} BFD_RELOC_V850_23
+This is a 23-bit reloc.
+@end deffn
+@deffn {} BFD_RELOC_V850_32_PCREL
+This is a 32-bit reloc.
+@end deffn
+@deffn {} BFD_RELOC_V850_32_ABS
+This is a 32-bit reloc.
+@end deffn
+@deffn {} BFD_RELOC_V850_16_SPLIT_OFFSET
+This is a 16-bit reloc.
+@end deffn
+@deffn {} BFD_RELOC_V850_16_S1
+This is a 16-bit reloc.
+@end deffn
+@deffn {} BFD_RELOC_V850_LO16_S1
+Low 16 bits. 16 bit shifted by 1.
+@end deffn
+@deffn {} BFD_RELOC_V850_CALLT_15_16_OFFSET
+This is a 16 bit offset from the call table base pointer.
+@end deffn
+@deffn {} BFD_RELOC_V850_32_GOTPCREL
+DSO relocations.
+@end deffn
+@deffn {} BFD_RELOC_V850_16_GOT
+DSO relocations.
+@end deffn
+@deffn {} BFD_RELOC_V850_32_GOT
+DSO relocations.
+@end deffn
+@deffn {} BFD_RELOC_V850_22_PLT_PCREL
+DSO relocations.
+@end deffn
+@deffn {} BFD_RELOC_V850_32_PLT_PCREL
+DSO relocations.
+@end deffn
+@deffn {} BFD_RELOC_V850_COPY
+DSO relocations.
+@end deffn
+@deffn {} BFD_RELOC_V850_GLOB_DAT
+DSO relocations.
+@end deffn
+@deffn {} BFD_RELOC_V850_JMP_SLOT
+DSO relocations.
+@end deffn
+@deffn {} BFD_RELOC_V850_RELATIVE
+DSO relocations.
+@end deffn
+@deffn {} BFD_RELOC_V850_16_GOTOFF
+DSO relocations.
+@end deffn
+@deffn {} BFD_RELOC_V850_32_GOTOFF
+DSO relocations.
+@end deffn
+@deffn {} BFD_RELOC_V850_CODE
+start code.
+@end deffn
+@deffn {} BFD_RELOC_V850_DATA
+start data in text.
+@end deffn
+@deffn {} BFD_RELOC_TIC30_LDP
+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.
+@end deffn
+@deffn {} BFD_RELOC_TIC54X_PARTLS7
+This is a 7bit reloc for the tms320c54x, where the least
+significant 7 bits of a 16 bit word are placed into the least
+significant 7 bits of the opcode.
+@end deffn
+@deffn {} BFD_RELOC_TIC54X_PARTMS9
+This is a 9bit DP reloc for the tms320c54x, where the most
+significant 9 bits of a 16 bit word are placed into the least
+significant 9 bits of the opcode.
+@end deffn
+@deffn {} BFD_RELOC_TIC54X_23
+This is an extended address 23-bit reloc for the tms320c54x.
+@end deffn
+@deffn {} BFD_RELOC_TIC54X_16_OF_23
+This is a 16-bit reloc for the tms320c54x, where the least
+significant 16 bits of a 23-bit extended address are placed into
+the opcode.
+@end deffn
+@deffn {} BFD_RELOC_TIC54X_MS7_OF_23
+This is a reloc for the tms320c54x, where the most
+significant 7 bits of a 23-bit extended address are placed into
+the opcode.
+@end deffn
+@deffn {} BFD_RELOC_C6000_PCR_S21
+@deffnx {} BFD_RELOC_C6000_PCR_S12
+@deffnx {} BFD_RELOC_C6000_PCR_S10
+@deffnx {} BFD_RELOC_C6000_PCR_S7
+@deffnx {} BFD_RELOC_C6000_ABS_S16
+@deffnx {} BFD_RELOC_C6000_ABS_L16
+@deffnx {} BFD_RELOC_C6000_ABS_H16
+@deffnx {} BFD_RELOC_C6000_SBR_U15_B
+@deffnx {} BFD_RELOC_C6000_SBR_U15_H
+@deffnx {} BFD_RELOC_C6000_SBR_U15_W
+@deffnx {} BFD_RELOC_C6000_SBR_S16
+@deffnx {} BFD_RELOC_C6000_SBR_L16_B
+@deffnx {} BFD_RELOC_C6000_SBR_L16_H
+@deffnx {} BFD_RELOC_C6000_SBR_L16_W
+@deffnx {} BFD_RELOC_C6000_SBR_H16_B
+@deffnx {} BFD_RELOC_C6000_SBR_H16_H
+@deffnx {} BFD_RELOC_C6000_SBR_H16_W
+@deffnx {} BFD_RELOC_C6000_SBR_GOT_U15_W
+@deffnx {} BFD_RELOC_C6000_SBR_GOT_L16_W
+@deffnx {} BFD_RELOC_C6000_SBR_GOT_H16_W
+@deffnx {} BFD_RELOC_C6000_DSBT_INDEX
+@deffnx {} BFD_RELOC_C6000_PREL31
+@deffnx {} BFD_RELOC_C6000_COPY
+@deffnx {} BFD_RELOC_C6000_JUMP_SLOT
+@deffnx {} BFD_RELOC_C6000_EHTYPE
+@deffnx {} BFD_RELOC_C6000_PCR_H16
+@deffnx {} BFD_RELOC_C6000_PCR_L16
+@deffnx {} BFD_RELOC_C6000_ALIGN
+@deffnx {} BFD_RELOC_C6000_FPHEAD
+@deffnx {} BFD_RELOC_C6000_NOCMP
+TMS320C6000 relocations.
+@end deffn
+@deffn {} BFD_RELOC_FR30_48
+This is a 48 bit reloc for the FR30 that stores 32 bits.
+@end deffn
+@deffn {} BFD_RELOC_FR30_20
+This is a 32 bit reloc for the FR30 that stores 20 bits split up into
+two sections.
+@end deffn
+@deffn {} BFD_RELOC_FR30_6_IN_4
+This is a 16 bit reloc for the FR30 that stores a 6 bit word offset in
+4 bits.
+@end deffn
+@deffn {} BFD_RELOC_FR30_8_IN_8
+This is a 16 bit reloc for the FR30 that stores an 8 bit byte offset
+into 8 bits.
+@end deffn
+@deffn {} BFD_RELOC_FR30_9_IN_8
+This is a 16 bit reloc for the FR30 that stores a 9 bit short offset
+into 8 bits.
+@end deffn
+@deffn {} BFD_RELOC_FR30_10_IN_8
+This is a 16 bit reloc for the FR30 that stores a 10 bit word offset
+into 8 bits.
+@end deffn
+@deffn {} BFD_RELOC_FR30_9_PCREL
+This is a 16 bit reloc for the FR30 that stores a 9 bit pc relative
+short offset into 8 bits.
+@end deffn
+@deffn {} BFD_RELOC_FR30_12_PCREL
+This is a 16 bit reloc for the FR30 that stores a 12 bit pc relative
+short offset into 11 bits.
+@end deffn
+@deffn {} BFD_RELOC_MCORE_PCREL_IMM8BY4
+@deffnx {} BFD_RELOC_MCORE_PCREL_IMM11BY2
+@deffnx {} BFD_RELOC_MCORE_PCREL_IMM4BY2
+@deffnx {} BFD_RELOC_MCORE_PCREL_32
+@deffnx {} BFD_RELOC_MCORE_PCREL_JSR_IMM11BY2
+@deffnx {} BFD_RELOC_MCORE_RVA
+Motorola Mcore relocations.
+@end deffn
+@deffn {} BFD_RELOC_MEP_8
+@deffnx {} BFD_RELOC_MEP_16
+@deffnx {} BFD_RELOC_MEP_32
+@deffnx {} BFD_RELOC_MEP_PCREL8A2
+@deffnx {} BFD_RELOC_MEP_PCREL12A2
+@deffnx {} BFD_RELOC_MEP_PCREL17A2
+@deffnx {} BFD_RELOC_MEP_PCREL24A2
+@deffnx {} BFD_RELOC_MEP_PCABS24A2
+@deffnx {} BFD_RELOC_MEP_LOW16
+@deffnx {} BFD_RELOC_MEP_HI16U
+@deffnx {} BFD_RELOC_MEP_HI16S
+@deffnx {} BFD_RELOC_MEP_GPREL
+@deffnx {} BFD_RELOC_MEP_TPREL
+@deffnx {} BFD_RELOC_MEP_TPREL7
+@deffnx {} BFD_RELOC_MEP_TPREL7A2
+@deffnx {} BFD_RELOC_MEP_TPREL7A4
+@deffnx {} BFD_RELOC_MEP_UIMM24
+@deffnx {} BFD_RELOC_MEP_ADDR24A4
+@deffnx {} BFD_RELOC_MEP_GNU_VTINHERIT
+@deffnx {} BFD_RELOC_MEP_GNU_VTENTRY
+Toshiba Media Processor Relocations.
+@end deffn
+@deffn {} BFD_RELOC_METAG_HIADDR16
+@deffnx {} BFD_RELOC_METAG_LOADDR16
+@deffnx {} BFD_RELOC_METAG_RELBRANCH
+@deffnx {} BFD_RELOC_METAG_GETSETOFF
+@deffnx {} BFD_RELOC_METAG_HIOG
+@deffnx {} BFD_RELOC_METAG_LOOG
+@deffnx {} BFD_RELOC_METAG_REL8
+@deffnx {} BFD_RELOC_METAG_REL16
+@deffnx {} BFD_RELOC_METAG_HI16_GOTOFF
+@deffnx {} BFD_RELOC_METAG_LO16_GOTOFF
+@deffnx {} BFD_RELOC_METAG_GETSET_GOTOFF
+@deffnx {} BFD_RELOC_METAG_GETSET_GOT
+@deffnx {} BFD_RELOC_METAG_HI16_GOTPC
+@deffnx {} BFD_RELOC_METAG_LO16_GOTPC
+@deffnx {} BFD_RELOC_METAG_HI16_PLT
+@deffnx {} BFD_RELOC_METAG_LO16_PLT
+@deffnx {} BFD_RELOC_METAG_RELBRANCH_PLT
+@deffnx {} BFD_RELOC_METAG_GOTOFF
+@deffnx {} BFD_RELOC_METAG_PLT
+@deffnx {} BFD_RELOC_METAG_COPY
+@deffnx {} BFD_RELOC_METAG_JMP_SLOT
+@deffnx {} BFD_RELOC_METAG_RELATIVE
+@deffnx {} BFD_RELOC_METAG_GLOB_DAT
+@deffnx {} BFD_RELOC_METAG_TLS_GD
+@deffnx {} BFD_RELOC_METAG_TLS_LDM
+@deffnx {} BFD_RELOC_METAG_TLS_LDO_HI16
+@deffnx {} BFD_RELOC_METAG_TLS_LDO_LO16
+@deffnx {} BFD_RELOC_METAG_TLS_LDO
+@deffnx {} BFD_RELOC_METAG_TLS_IE
+@deffnx {} BFD_RELOC_METAG_TLS_IENONPIC
+@deffnx {} BFD_RELOC_METAG_TLS_IENONPIC_HI16
+@deffnx {} BFD_RELOC_METAG_TLS_IENONPIC_LO16
+@deffnx {} BFD_RELOC_METAG_TLS_TPOFF
+@deffnx {} BFD_RELOC_METAG_TLS_DTPMOD
+@deffnx {} BFD_RELOC_METAG_TLS_DTPOFF
+@deffnx {} BFD_RELOC_METAG_TLS_LE
+@deffnx {} BFD_RELOC_METAG_TLS_LE_HI16
+@deffnx {} BFD_RELOC_METAG_TLS_LE_LO16
+Imagination Technologies Meta relocations.
+@end deffn
+@deffn {} BFD_RELOC_MMIX_GETA
+@deffnx {} BFD_RELOC_MMIX_GETA_1
+@deffnx {} BFD_RELOC_MMIX_GETA_2
+@deffnx {} BFD_RELOC_MMIX_GETA_3
+These are relocations for the GETA instruction.
+@end deffn
+@deffn {} BFD_RELOC_MMIX_CBRANCH
+@deffnx {} BFD_RELOC_MMIX_CBRANCH_J
+@deffnx {} BFD_RELOC_MMIX_CBRANCH_1
+@deffnx {} BFD_RELOC_MMIX_CBRANCH_2
+@deffnx {} BFD_RELOC_MMIX_CBRANCH_3
+These are relocations for a conditional branch instruction.
+@end deffn
+@deffn {} BFD_RELOC_MMIX_PUSHJ
+@deffnx {} BFD_RELOC_MMIX_PUSHJ_1
+@deffnx {} BFD_RELOC_MMIX_PUSHJ_2
+@deffnx {} BFD_RELOC_MMIX_PUSHJ_3
+@deffnx {} BFD_RELOC_MMIX_PUSHJ_STUBBABLE
+These are relocations for the PUSHJ instruction.
+@end deffn
+@deffn {} BFD_RELOC_MMIX_JMP
+@deffnx {} BFD_RELOC_MMIX_JMP_1
+@deffnx {} BFD_RELOC_MMIX_JMP_2
+@deffnx {} BFD_RELOC_MMIX_JMP_3
+These are relocations for the JMP instruction.
+@end deffn
+@deffn {} BFD_RELOC_MMIX_ADDR19
+This is a relocation for a relative address as in a GETA instruction or
+a branch.
+@end deffn
+@deffn {} BFD_RELOC_MMIX_ADDR27
+This is a relocation for a relative address as in a JMP instruction.
+@end deffn
+@deffn {} BFD_RELOC_MMIX_REG_OR_BYTE
+This is a relocation for an instruction field that may be a general
+register or a value 0..255.
+@end deffn
+@deffn {} BFD_RELOC_MMIX_REG
+This is a relocation for an instruction field that may be a general
+register.
+@end deffn
+@deffn {} BFD_RELOC_MMIX_BASE_PLUS_OFFSET
+This is a relocation for two instruction fields holding a register and
+an offset, the equivalent of the relocation.
+@end deffn
+@deffn {} BFD_RELOC_MMIX_LOCAL
+This relocation is an assertion that the expression is not allocated as
+a global register. It does not modify contents.
+@end deffn
+@deffn {} BFD_RELOC_AVR_7_PCREL
+This is a 16 bit reloc for the AVR that stores 8 bit pc relative
+short offset into 7 bits.
+@end deffn
+@deffn {} BFD_RELOC_AVR_13_PCREL
+This is a 16 bit reloc for the AVR that stores 13 bit pc relative
+short offset into 12 bits.
+@end deffn
+@deffn {} BFD_RELOC_AVR_16_PM
+This is a 16 bit reloc for the AVR that stores 17 bit value (usually
+program memory address) into 16 bits.
+@end deffn
+@deffn {} BFD_RELOC_AVR_LO8_LDI
+This is a 16 bit reloc for the AVR that stores 8 bit value (usually
+data memory address) into 8 bit immediate value of LDI insn.
+@end deffn
+@deffn {} BFD_RELOC_AVR_HI8_LDI
+This is a 16 bit reloc for the AVR that stores 8 bit value (high 8 bit
+of data memory address) into 8 bit immediate value of LDI insn.
+@end deffn
+@deffn {} BFD_RELOC_AVR_HH8_LDI
+This is a 16 bit reloc for the AVR that stores 8 bit value (most high 8 bit
+of program memory address) into 8 bit immediate value of LDI insn.
+@end deffn
+@deffn {} BFD_RELOC_AVR_MS8_LDI
+This is a 16 bit reloc for the AVR that stores 8 bit value (most high 8 bit
+of 32 bit value) into 8 bit immediate value of LDI insn.
+@end deffn
+@deffn {} BFD_RELOC_AVR_LO8_LDI_NEG
+This is a 16 bit reloc for the AVR that stores negated 8 bit value
+(usually data memory address) into 8 bit immediate value of SUBI insn.
+@end deffn
+@deffn {} BFD_RELOC_AVR_HI8_LDI_NEG
+This is a 16 bit reloc for the AVR that stores negated 8 bit value
+(high 8 bit of data memory address) into 8 bit immediate value of
+SUBI insn.
+@end deffn
+@deffn {} BFD_RELOC_AVR_HH8_LDI_NEG
+This is a 16 bit reloc for the AVR that stores negated 8 bit value
+(most high 8 bit of program memory address) into 8 bit immediate value
+of LDI or SUBI insn.
+@end deffn
+@deffn {} BFD_RELOC_AVR_MS8_LDI_NEG
+This is a 16 bit reloc for the AVR that stores negated 8 bit value (msb
+of 32 bit value) into 8 bit immediate value of LDI insn.
+@end deffn
+@deffn {} BFD_RELOC_AVR_LO8_LDI_PM
+This is a 16 bit reloc for the AVR that stores 8 bit value (usually
+command address) into 8 bit immediate value of LDI insn.
+@end deffn
+@deffn {} BFD_RELOC_AVR_LO8_LDI_GS
+This is a 16 bit reloc for the AVR that stores 8 bit value
+(command address) into 8 bit immediate value of LDI insn. If the address
+is beyond the 128k boundary, the linker inserts a jump stub for this reloc
+in the lower 128k.
+@end deffn
+@deffn {} BFD_RELOC_AVR_HI8_LDI_PM
+This is a 16 bit reloc for the AVR that stores 8 bit value (high 8 bit
+of command address) into 8 bit immediate value of LDI insn.
+@end deffn
+@deffn {} BFD_RELOC_AVR_HI8_LDI_GS
+This is a 16 bit reloc for the AVR that stores 8 bit value (high 8 bit
+of command address) into 8 bit immediate value of LDI insn. If the address
+is beyond the 128k boundary, the linker inserts a jump stub for this reloc
+below 128k.
+@end deffn
+@deffn {} BFD_RELOC_AVR_HH8_LDI_PM
+This is a 16 bit reloc for the AVR that stores 8 bit value (most high 8 bit
+of command address) into 8 bit immediate value of LDI insn.
+@end deffn
+@deffn {} BFD_RELOC_AVR_LO8_LDI_PM_NEG
+This is a 16 bit reloc for the AVR that stores negated 8 bit value
+(usually command address) into 8 bit immediate value of SUBI insn.
+@end deffn
+@deffn {} BFD_RELOC_AVR_HI8_LDI_PM_NEG
+This is a 16 bit reloc for the AVR that stores negated 8 bit value
+(high 8 bit of 16 bit command address) into 8 bit immediate value
+of SUBI insn.
+@end deffn
+@deffn {} BFD_RELOC_AVR_HH8_LDI_PM_NEG
+This is a 16 bit reloc for the AVR that stores negated 8 bit value
+(high 6 bit of 22 bit command address) into 8 bit immediate
+value of SUBI insn.
+@end deffn
+@deffn {} BFD_RELOC_AVR_CALL
+This is a 32 bit reloc for the AVR that stores 23 bit value
+into 22 bits.
+@end deffn
+@deffn {} BFD_RELOC_AVR_LDI
+This is a 16 bit reloc for the AVR that stores all needed bits
+for absolute addressing with ldi with overflow check to linktime
+@end deffn
+@deffn {} BFD_RELOC_AVR_6
+This is a 6 bit reloc for the AVR that stores offset for ldd/std
+instructions
+@end deffn
+@deffn {} BFD_RELOC_AVR_6_ADIW
+This is a 6 bit reloc for the AVR that stores offset for adiw/sbiw
+instructions
+@end deffn
+@deffn {} BFD_RELOC_AVR_8_LO
+This is a 8 bit reloc for the AVR that stores bits 0..7 of a symbol
+in .byte lo8(symbol)
+@end deffn
+@deffn {} BFD_RELOC_AVR_8_HI
+This is a 8 bit reloc for the AVR that stores bits 8..15 of a symbol
+in .byte hi8(symbol)
+@end deffn
+@deffn {} BFD_RELOC_AVR_8_HLO
+This is a 8 bit reloc for the AVR that stores bits 16..23 of a symbol
+in .byte hlo8(symbol)
+@end deffn
+@deffn {} BFD_RELOC_AVR_DIFF8
+@deffnx {} BFD_RELOC_AVR_DIFF16
+@deffnx {} BFD_RELOC_AVR_DIFF32
+AVR relocations to mark the difference of two local symbols.
+These are only needed to support linker relaxation and can be ignored
+when not relaxing. The field is set to the value of the difference
+assuming no relaxation. The relocation encodes the position of the
+second symbol so the linker can determine whether to adjust the field
+value.
+@end deffn
+@deffn {} BFD_RELOC_AVR_LDS_STS_16
+This is a 7 bit reloc for the AVR that stores SRAM address for 16bit
+lds and sts instructions supported only tiny core.
+@end deffn
+@deffn {} BFD_RELOC_AVR_PORT6
+This is a 6 bit reloc for the AVR that stores an I/O register
+number for the IN and OUT instructions
+@end deffn
+@deffn {} BFD_RELOC_AVR_PORT5
+This is a 5 bit reloc for the AVR that stores an I/O register
+number for the SBIC, SBIS, SBI and CBI instructions
+@end deffn
+@deffn {} BFD_RELOC_RL78_NEG8
+@deffnx {} BFD_RELOC_RL78_NEG16
+@deffnx {} BFD_RELOC_RL78_NEG24
+@deffnx {} BFD_RELOC_RL78_NEG32
+@deffnx {} BFD_RELOC_RL78_16_OP
+@deffnx {} BFD_RELOC_RL78_24_OP
+@deffnx {} BFD_RELOC_RL78_32_OP
+@deffnx {} BFD_RELOC_RL78_8U
+@deffnx {} BFD_RELOC_RL78_16U
+@deffnx {} BFD_RELOC_RL78_24U
+@deffnx {} BFD_RELOC_RL78_DIR3U_PCREL
+@deffnx {} BFD_RELOC_RL78_DIFF
+@deffnx {} BFD_RELOC_RL78_GPRELB
+@deffnx {} BFD_RELOC_RL78_GPRELW
+@deffnx {} BFD_RELOC_RL78_GPRELL
+@deffnx {} BFD_RELOC_RL78_SYM
+@deffnx {} BFD_RELOC_RL78_OP_SUBTRACT
+@deffnx {} BFD_RELOC_RL78_OP_NEG
+@deffnx {} BFD_RELOC_RL78_OP_AND
+@deffnx {} BFD_RELOC_RL78_OP_SHRA
+@deffnx {} BFD_RELOC_RL78_ABS8
+@deffnx {} BFD_RELOC_RL78_ABS16
+@deffnx {} BFD_RELOC_RL78_ABS16_REV
+@deffnx {} BFD_RELOC_RL78_ABS32
+@deffnx {} BFD_RELOC_RL78_ABS32_REV
+@deffnx {} BFD_RELOC_RL78_ABS16U
+@deffnx {} BFD_RELOC_RL78_ABS16UW
+@deffnx {} BFD_RELOC_RL78_ABS16UL
+@deffnx {} BFD_RELOC_RL78_RELAX
+@deffnx {} BFD_RELOC_RL78_HI16
+@deffnx {} BFD_RELOC_RL78_HI8
+@deffnx {} BFD_RELOC_RL78_LO16
+@deffnx {} BFD_RELOC_RL78_CODE
+Renesas RL78 Relocations.
+@end deffn
+@deffn {} BFD_RELOC_RX_NEG8
+@deffnx {} BFD_RELOC_RX_NEG16
+@deffnx {} BFD_RELOC_RX_NEG24
+@deffnx {} BFD_RELOC_RX_NEG32
+@deffnx {} BFD_RELOC_RX_16_OP
+@deffnx {} BFD_RELOC_RX_24_OP
+@deffnx {} BFD_RELOC_RX_32_OP
+@deffnx {} BFD_RELOC_RX_8U
+@deffnx {} BFD_RELOC_RX_16U
+@deffnx {} BFD_RELOC_RX_24U
+@deffnx {} BFD_RELOC_RX_DIR3U_PCREL
+@deffnx {} BFD_RELOC_RX_DIFF
+@deffnx {} BFD_RELOC_RX_GPRELB
+@deffnx {} BFD_RELOC_RX_GPRELW
+@deffnx {} BFD_RELOC_RX_GPRELL
+@deffnx {} BFD_RELOC_RX_SYM
+@deffnx {} BFD_RELOC_RX_OP_SUBTRACT
+@deffnx {} BFD_RELOC_RX_OP_NEG
+@deffnx {} BFD_RELOC_RX_ABS8
+@deffnx {} BFD_RELOC_RX_ABS16
+@deffnx {} BFD_RELOC_RX_ABS16_REV
+@deffnx {} BFD_RELOC_RX_ABS32
+@deffnx {} BFD_RELOC_RX_ABS32_REV
+@deffnx {} BFD_RELOC_RX_ABS16U
+@deffnx {} BFD_RELOC_RX_ABS16UW
+@deffnx {} BFD_RELOC_RX_ABS16UL
+@deffnx {} BFD_RELOC_RX_RELAX
+Renesas RX Relocations.
+@end deffn
+@deffn {} BFD_RELOC_390_12
+Direct 12 bit.
+@end deffn
+@deffn {} BFD_RELOC_390_GOT12
+12 bit GOT offset.
+@end deffn
+@deffn {} BFD_RELOC_390_PLT32
+32 bit PC relative PLT address.
+@end deffn
+@deffn {} BFD_RELOC_390_COPY
+Copy symbol at runtime.
+@end deffn
+@deffn {} BFD_RELOC_390_GLOB_DAT
+Create GOT entry.
+@end deffn
+@deffn {} BFD_RELOC_390_JMP_SLOT
+Create PLT entry.
+@end deffn
+@deffn {} BFD_RELOC_390_RELATIVE
+Adjust by program base.
+@end deffn
+@deffn {} BFD_RELOC_390_GOTPC
+32 bit PC relative offset to GOT.
+@end deffn
+@deffn {} BFD_RELOC_390_GOT16
+16 bit GOT offset.
+@end deffn
+@deffn {} BFD_RELOC_390_PC12DBL
+PC relative 12 bit shifted by 1.
+@end deffn
+@deffn {} BFD_RELOC_390_PLT12DBL
+12 bit PC rel. PLT shifted by 1.
+@end deffn
+@deffn {} BFD_RELOC_390_PC16DBL
+PC relative 16 bit shifted by 1.
+@end deffn
+@deffn {} BFD_RELOC_390_PLT16DBL
+16 bit PC rel. PLT shifted by 1.
+@end deffn
+@deffn {} BFD_RELOC_390_PC24DBL
+PC relative 24 bit shifted by 1.
+@end deffn
+@deffn {} BFD_RELOC_390_PLT24DBL
+24 bit PC rel. PLT shifted by 1.
+@end deffn
+@deffn {} BFD_RELOC_390_PC32DBL
+PC relative 32 bit shifted by 1.
+@end deffn
+@deffn {} BFD_RELOC_390_PLT32DBL
+32 bit PC rel. PLT shifted by 1.
+@end deffn
+@deffn {} BFD_RELOC_390_GOTPCDBL
+32 bit PC rel. GOT shifted by 1.
+@end deffn
+@deffn {} BFD_RELOC_390_GOT64
+64 bit GOT offset.
+@end deffn
+@deffn {} BFD_RELOC_390_PLT64
+64 bit PC relative PLT address.
+@end deffn
+@deffn {} BFD_RELOC_390_GOTENT
+32 bit rel. offset to GOT entry.
+@end deffn
+@deffn {} BFD_RELOC_390_GOTOFF64
+64 bit offset to GOT.
+@end deffn
+@deffn {} BFD_RELOC_390_GOTPLT12
+12-bit offset to symbol-entry within GOT, with PLT handling.
+@end deffn
+@deffn {} BFD_RELOC_390_GOTPLT16
+16-bit offset to symbol-entry within GOT, with PLT handling.
+@end deffn
+@deffn {} BFD_RELOC_390_GOTPLT32
+32-bit offset to symbol-entry within GOT, with PLT handling.
+@end deffn
+@deffn {} BFD_RELOC_390_GOTPLT64
+64-bit offset to symbol-entry within GOT, with PLT handling.
+@end deffn
+@deffn {} BFD_RELOC_390_GOTPLTENT
+32-bit rel. offset to symbol-entry within GOT, with PLT handling.
+@end deffn
+@deffn {} BFD_RELOC_390_PLTOFF16
+16-bit rel. offset from the GOT to a PLT entry.
+@end deffn
+@deffn {} BFD_RELOC_390_PLTOFF32
+32-bit rel. offset from the GOT to a PLT entry.
+@end deffn
+@deffn {} BFD_RELOC_390_PLTOFF64
+64-bit rel. offset from the GOT to a PLT entry.
+@end deffn
+@deffn {} BFD_RELOC_390_TLS_LOAD
+@deffnx {} BFD_RELOC_390_TLS_GDCALL
+@deffnx {} BFD_RELOC_390_TLS_LDCALL
+@deffnx {} BFD_RELOC_390_TLS_GD32
+@deffnx {} BFD_RELOC_390_TLS_GD64
+@deffnx {} BFD_RELOC_390_TLS_GOTIE12
+@deffnx {} BFD_RELOC_390_TLS_GOTIE32
+@deffnx {} BFD_RELOC_390_TLS_GOTIE64
+@deffnx {} BFD_RELOC_390_TLS_LDM32
+@deffnx {} BFD_RELOC_390_TLS_LDM64
+@deffnx {} BFD_RELOC_390_TLS_IE32
+@deffnx {} BFD_RELOC_390_TLS_IE64
+@deffnx {} BFD_RELOC_390_TLS_IEENT
+@deffnx {} BFD_RELOC_390_TLS_LE32
+@deffnx {} BFD_RELOC_390_TLS_LE64
+@deffnx {} BFD_RELOC_390_TLS_LDO32
+@deffnx {} BFD_RELOC_390_TLS_LDO64
+@deffnx {} BFD_RELOC_390_TLS_DTPMOD
+@deffnx {} BFD_RELOC_390_TLS_DTPOFF
+@deffnx {} BFD_RELOC_390_TLS_TPOFF
+s390 tls relocations.
+@end deffn
+@deffn {} BFD_RELOC_390_20
+@deffnx {} BFD_RELOC_390_GOT20
+@deffnx {} BFD_RELOC_390_GOTPLT20
+@deffnx {} BFD_RELOC_390_TLS_GOTIE20
+Long displacement extension.
+@end deffn
+@deffn {} BFD_RELOC_390_IRELATIVE
+STT_GNU_IFUNC relocation.
+@end deffn
+@deffn {} BFD_RELOC_SCORE_GPREL15
+Score relocations
+Low 16 bit for load/store
+@end deffn
+@deffn {} BFD_RELOC_SCORE_DUMMY2
+@deffnx {} BFD_RELOC_SCORE_JMP
+This is a 24-bit reloc with the right 1 bit assumed to be 0
+@end deffn
+@deffn {} BFD_RELOC_SCORE_BRANCH
+This is a 19-bit reloc with the right 1 bit assumed to be 0
+@end deffn
+@deffn {} BFD_RELOC_SCORE_IMM30
+This is a 32-bit reloc for 48-bit instructions.
+@end deffn
+@deffn {} BFD_RELOC_SCORE_IMM32
+This is a 32-bit reloc for 48-bit instructions.
+@end deffn
+@deffn {} BFD_RELOC_SCORE16_JMP
+This is a 11-bit reloc with the right 1 bit assumed to be 0
+@end deffn
+@deffn {} BFD_RELOC_SCORE16_BRANCH
+This is a 8-bit reloc with the right 1 bit assumed to be 0
+@end deffn
+@deffn {} BFD_RELOC_SCORE_BCMP
+This is a 9-bit reloc with the right 1 bit assumed to be 0
+@end deffn
+@deffn {} BFD_RELOC_SCORE_GOT15
+@deffnx {} BFD_RELOC_SCORE_GOT_LO16
+@deffnx {} BFD_RELOC_SCORE_CALL15
+@deffnx {} BFD_RELOC_SCORE_DUMMY_HI16
+Undocumented Score relocs
+@end deffn
+@deffn {} BFD_RELOC_IP2K_FR9
+Scenix IP2K - 9-bit register number / data address
+@end deffn
+@deffn {} BFD_RELOC_IP2K_BANK
+Scenix IP2K - 4-bit register/data bank number
+@end deffn
+@deffn {} BFD_RELOC_IP2K_ADDR16CJP
+Scenix IP2K - low 13 bits of instruction word address
+@end deffn
+@deffn {} BFD_RELOC_IP2K_PAGE3
+Scenix IP2K - high 3 bits of instruction word address
+@end deffn
+@deffn {} BFD_RELOC_IP2K_LO8DATA
+@deffnx {} BFD_RELOC_IP2K_HI8DATA
+@deffnx {} BFD_RELOC_IP2K_EX8DATA
+Scenix IP2K - ext/low/high 8 bits of data address
+@end deffn
+@deffn {} BFD_RELOC_IP2K_LO8INSN
+@deffnx {} BFD_RELOC_IP2K_HI8INSN
+Scenix IP2K - low/high 8 bits of instruction word address
+@end deffn
+@deffn {} BFD_RELOC_IP2K_PC_SKIP
+Scenix IP2K - even/odd PC modifier to modify snb pcl.0
+@end deffn
+@deffn {} BFD_RELOC_IP2K_TEXT
+Scenix IP2K - 16 bit word address in text section.
+@end deffn
+@deffn {} BFD_RELOC_IP2K_FR_OFFSET
+Scenix IP2K - 7-bit sp or dp offset
+@end deffn
+@deffn {} BFD_RELOC_VPE4KMATH_DATA
+@deffnx {} BFD_RELOC_VPE4KMATH_INSN
+Scenix VPE4K coprocessor - data/insn-space addressing
+@end deffn
+@deffn {} BFD_RELOC_VTABLE_INHERIT
+@deffnx {} BFD_RELOC_VTABLE_ENTRY
+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 inheritance 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.
+@end deffn
+@deffn {} BFD_RELOC_IA64_IMM14
+@deffnx {} BFD_RELOC_IA64_IMM22
+@deffnx {} BFD_RELOC_IA64_IMM64
+@deffnx {} BFD_RELOC_IA64_DIR32MSB
+@deffnx {} BFD_RELOC_IA64_DIR32LSB
+@deffnx {} BFD_RELOC_IA64_DIR64MSB
+@deffnx {} BFD_RELOC_IA64_DIR64LSB
+@deffnx {} BFD_RELOC_IA64_GPREL22
+@deffnx {} BFD_RELOC_IA64_GPREL64I
+@deffnx {} BFD_RELOC_IA64_GPREL32MSB
+@deffnx {} BFD_RELOC_IA64_GPREL32LSB
+@deffnx {} BFD_RELOC_IA64_GPREL64MSB
+@deffnx {} BFD_RELOC_IA64_GPREL64LSB
+@deffnx {} BFD_RELOC_IA64_LTOFF22
+@deffnx {} BFD_RELOC_IA64_LTOFF64I
+@deffnx {} BFD_RELOC_IA64_PLTOFF22
+@deffnx {} BFD_RELOC_IA64_PLTOFF64I
+@deffnx {} BFD_RELOC_IA64_PLTOFF64MSB
+@deffnx {} BFD_RELOC_IA64_PLTOFF64LSB
+@deffnx {} BFD_RELOC_IA64_FPTR64I
+@deffnx {} BFD_RELOC_IA64_FPTR32MSB
+@deffnx {} BFD_RELOC_IA64_FPTR32LSB
+@deffnx {} BFD_RELOC_IA64_FPTR64MSB
+@deffnx {} BFD_RELOC_IA64_FPTR64LSB
+@deffnx {} BFD_RELOC_IA64_PCREL21B
+@deffnx {} BFD_RELOC_IA64_PCREL21BI
+@deffnx {} BFD_RELOC_IA64_PCREL21M
+@deffnx {} BFD_RELOC_IA64_PCREL21F
+@deffnx {} BFD_RELOC_IA64_PCREL22
+@deffnx {} BFD_RELOC_IA64_PCREL60B
+@deffnx {} BFD_RELOC_IA64_PCREL64I
+@deffnx {} BFD_RELOC_IA64_PCREL32MSB
+@deffnx {} BFD_RELOC_IA64_PCREL32LSB
+@deffnx {} BFD_RELOC_IA64_PCREL64MSB
+@deffnx {} BFD_RELOC_IA64_PCREL64LSB
+@deffnx {} BFD_RELOC_IA64_LTOFF_FPTR22
+@deffnx {} BFD_RELOC_IA64_LTOFF_FPTR64I
+@deffnx {} BFD_RELOC_IA64_LTOFF_FPTR32MSB
+@deffnx {} BFD_RELOC_IA64_LTOFF_FPTR32LSB
+@deffnx {} BFD_RELOC_IA64_LTOFF_FPTR64MSB
+@deffnx {} BFD_RELOC_IA64_LTOFF_FPTR64LSB
+@deffnx {} BFD_RELOC_IA64_SEGREL32MSB
+@deffnx {} BFD_RELOC_IA64_SEGREL32LSB
+@deffnx {} BFD_RELOC_IA64_SEGREL64MSB
+@deffnx {} BFD_RELOC_IA64_SEGREL64LSB
+@deffnx {} BFD_RELOC_IA64_SECREL32MSB
+@deffnx {} BFD_RELOC_IA64_SECREL32LSB
+@deffnx {} BFD_RELOC_IA64_SECREL64MSB
+@deffnx {} BFD_RELOC_IA64_SECREL64LSB
+@deffnx {} BFD_RELOC_IA64_REL32MSB
+@deffnx {} BFD_RELOC_IA64_REL32LSB
+@deffnx {} BFD_RELOC_IA64_REL64MSB
+@deffnx {} BFD_RELOC_IA64_REL64LSB
+@deffnx {} BFD_RELOC_IA64_LTV32MSB
+@deffnx {} BFD_RELOC_IA64_LTV32LSB
+@deffnx {} BFD_RELOC_IA64_LTV64MSB
+@deffnx {} BFD_RELOC_IA64_LTV64LSB
+@deffnx {} BFD_RELOC_IA64_IPLTMSB
+@deffnx {} BFD_RELOC_IA64_IPLTLSB
+@deffnx {} BFD_RELOC_IA64_COPY
+@deffnx {} BFD_RELOC_IA64_LTOFF22X
+@deffnx {} BFD_RELOC_IA64_LDXMOV
+@deffnx {} BFD_RELOC_IA64_TPREL14
+@deffnx {} BFD_RELOC_IA64_TPREL22
+@deffnx {} BFD_RELOC_IA64_TPREL64I
+@deffnx {} BFD_RELOC_IA64_TPREL64MSB
+@deffnx {} BFD_RELOC_IA64_TPREL64LSB
+@deffnx {} BFD_RELOC_IA64_LTOFF_TPREL22
+@deffnx {} BFD_RELOC_IA64_DTPMOD64MSB
+@deffnx {} BFD_RELOC_IA64_DTPMOD64LSB
+@deffnx {} BFD_RELOC_IA64_LTOFF_DTPMOD22
+@deffnx {} BFD_RELOC_IA64_DTPREL14
+@deffnx {} BFD_RELOC_IA64_DTPREL22
+@deffnx {} BFD_RELOC_IA64_DTPREL64I
+@deffnx {} BFD_RELOC_IA64_DTPREL32MSB
+@deffnx {} BFD_RELOC_IA64_DTPREL32LSB
+@deffnx {} BFD_RELOC_IA64_DTPREL64MSB
+@deffnx {} BFD_RELOC_IA64_DTPREL64LSB
+@deffnx {} BFD_RELOC_IA64_LTOFF_DTPREL22
+Intel IA64 Relocations.
+@end deffn
+@deffn {} BFD_RELOC_M68HC11_HI8
+Motorola 68HC11 reloc.
+This is the 8 bit high part of an absolute address.
+@end deffn
+@deffn {} BFD_RELOC_M68HC11_LO8
+Motorola 68HC11 reloc.
+This is the 8 bit low part of an absolute address.
+@end deffn
+@deffn {} BFD_RELOC_M68HC11_3B
+Motorola 68HC11 reloc.
+This is the 3 bit of a value.
+@end deffn
+@deffn {} BFD_RELOC_M68HC11_RL_JUMP
+Motorola 68HC11 reloc.
+This reloc marks the beginning of a jump/call instruction.
+It is used for linker relaxation to correctly identify beginning
+of instruction and change some branches to use PC-relative
+addressing mode.
+@end deffn
+@deffn {} BFD_RELOC_M68HC11_RL_GROUP
+Motorola 68HC11 reloc.
+This reloc marks a group of several instructions that gcc generates
+and for which the linker relaxation pass can modify and/or remove
+some of them.
+@end deffn
+@deffn {} BFD_RELOC_M68HC11_LO16
+Motorola 68HC11 reloc.
+This is the 16-bit lower part of an address. It is used for 'call'
+instruction to specify the symbol address without any special
+transformation (due to memory bank window).
+@end deffn
+@deffn {} BFD_RELOC_M68HC11_PAGE
+Motorola 68HC11 reloc.
+This is a 8-bit reloc that specifies the page number of an address.
+It is used by 'call' instruction to specify the page number of
+the symbol.
+@end deffn
+@deffn {} BFD_RELOC_M68HC11_24
+Motorola 68HC11 reloc.
+This is a 24-bit reloc that represents the address with a 16-bit
+value and a 8-bit page number. The symbol address is transformed
+to follow the 16K memory bank of 68HC12 (seen as mapped in the window).
+@end deffn
+@deffn {} BFD_RELOC_M68HC12_5B
+Motorola 68HC12 reloc.
+This is the 5 bits of a value.
+@end deffn
+@deffn {} BFD_RELOC_XGATE_RL_JUMP
+Freescale XGATE reloc.
+This reloc marks the beginning of a bra/jal instruction.
+@end deffn
+@deffn {} BFD_RELOC_XGATE_RL_GROUP
+Freescale XGATE reloc.
+This reloc marks a group of several instructions that gcc generates
+and for which the linker relaxation pass can modify and/or remove
+some of them.
+@end deffn
+@deffn {} BFD_RELOC_XGATE_LO16
+Freescale XGATE reloc.
+This is the 16-bit lower part of an address. It is used for the '16-bit'
+instructions.
+@end deffn
+@deffn {} BFD_RELOC_XGATE_GPAGE
+Freescale XGATE reloc.
+@end deffn
+@deffn {} BFD_RELOC_XGATE_24
+Freescale XGATE reloc.
+@end deffn
+@deffn {} BFD_RELOC_XGATE_PCREL_9
+Freescale XGATE reloc.
+This is a 9-bit pc-relative reloc.
+@end deffn
+@deffn {} BFD_RELOC_XGATE_PCREL_10
+Freescale XGATE reloc.
+This is a 10-bit pc-relative reloc.
+@end deffn
+@deffn {} BFD_RELOC_XGATE_IMM8_LO
+Freescale XGATE reloc.
+This is the 16-bit lower part of an address. It is used for the '16-bit'
+instructions.
+@end deffn
+@deffn {} BFD_RELOC_XGATE_IMM8_HI
+Freescale XGATE reloc.
+This is the 16-bit higher part of an address. It is used for the '16-bit'
+instructions.
+@end deffn
+@deffn {} BFD_RELOC_XGATE_IMM3
+Freescale XGATE reloc.
+This is a 3-bit pc-relative reloc.
+@end deffn
+@deffn {} BFD_RELOC_XGATE_IMM4
+Freescale XGATE reloc.
+This is a 4-bit pc-relative reloc.
+@end deffn
+@deffn {} BFD_RELOC_XGATE_IMM5
+Freescale XGATE reloc.
+This is a 5-bit pc-relative reloc.
+@end deffn
+@deffn {} BFD_RELOC_M68HC12_9B
+Motorola 68HC12 reloc.
+This is the 9 bits of a value.
+@end deffn
+@deffn {} BFD_RELOC_M68HC12_16B
+Motorola 68HC12 reloc.
+This is the 16 bits of a value.
+@end deffn
+@deffn {} BFD_RELOC_M68HC12_9_PCREL
+Motorola 68HC12/XGATE reloc.
+This is a PCREL9 branch.
+@end deffn
+@deffn {} BFD_RELOC_M68HC12_10_PCREL
+Motorola 68HC12/XGATE reloc.
+This is a PCREL10 branch.
+@end deffn
+@deffn {} BFD_RELOC_M68HC12_LO8XG
+Motorola 68HC12/XGATE reloc.
+This is the 8 bit low part of an absolute address and immediately precedes
+a matching HI8XG part.
+@end deffn
+@deffn {} BFD_RELOC_M68HC12_HI8XG
+Motorola 68HC12/XGATE reloc.
+This is the 8 bit high part of an absolute address and immediately follows
+a matching LO8XG part.
+@end deffn
+@deffn {} BFD_RELOC_16C_NUM08
+@deffnx {} BFD_RELOC_16C_NUM08_C
+@deffnx {} BFD_RELOC_16C_NUM16
+@deffnx {} BFD_RELOC_16C_NUM16_C
+@deffnx {} BFD_RELOC_16C_NUM32
+@deffnx {} BFD_RELOC_16C_NUM32_C
+@deffnx {} BFD_RELOC_16C_DISP04
+@deffnx {} BFD_RELOC_16C_DISP04_C
+@deffnx {} BFD_RELOC_16C_DISP08
+@deffnx {} BFD_RELOC_16C_DISP08_C
+@deffnx {} BFD_RELOC_16C_DISP16
+@deffnx {} BFD_RELOC_16C_DISP16_C
+@deffnx {} BFD_RELOC_16C_DISP24
+@deffnx {} BFD_RELOC_16C_DISP24_C
+@deffnx {} BFD_RELOC_16C_DISP24a
+@deffnx {} BFD_RELOC_16C_DISP24a_C
+@deffnx {} BFD_RELOC_16C_REG04
+@deffnx {} BFD_RELOC_16C_REG04_C
+@deffnx {} BFD_RELOC_16C_REG04a
+@deffnx {} BFD_RELOC_16C_REG04a_C
+@deffnx {} BFD_RELOC_16C_REG14
+@deffnx {} BFD_RELOC_16C_REG14_C
+@deffnx {} BFD_RELOC_16C_REG16
+@deffnx {} BFD_RELOC_16C_REG16_C
+@deffnx {} BFD_RELOC_16C_REG20
+@deffnx {} BFD_RELOC_16C_REG20_C
+@deffnx {} BFD_RELOC_16C_ABS20
+@deffnx {} BFD_RELOC_16C_ABS20_C
+@deffnx {} BFD_RELOC_16C_ABS24
+@deffnx {} BFD_RELOC_16C_ABS24_C
+@deffnx {} BFD_RELOC_16C_IMM04
+@deffnx {} BFD_RELOC_16C_IMM04_C
+@deffnx {} BFD_RELOC_16C_IMM16
+@deffnx {} BFD_RELOC_16C_IMM16_C
+@deffnx {} BFD_RELOC_16C_IMM20
+@deffnx {} BFD_RELOC_16C_IMM20_C
+@deffnx {} BFD_RELOC_16C_IMM24
+@deffnx {} BFD_RELOC_16C_IMM24_C
+@deffnx {} BFD_RELOC_16C_IMM32
+@deffnx {} BFD_RELOC_16C_IMM32_C
+NS CR16C Relocations.
+@end deffn
+@deffn {} BFD_RELOC_CR16_NUM8
+@deffnx {} BFD_RELOC_CR16_NUM16
+@deffnx {} BFD_RELOC_CR16_NUM32
+@deffnx {} BFD_RELOC_CR16_NUM32a
+@deffnx {} BFD_RELOC_CR16_REGREL0
+@deffnx {} BFD_RELOC_CR16_REGREL4
+@deffnx {} BFD_RELOC_CR16_REGREL4a
+@deffnx {} BFD_RELOC_CR16_REGREL14
+@deffnx {} BFD_RELOC_CR16_REGREL14a
+@deffnx {} BFD_RELOC_CR16_REGREL16
+@deffnx {} BFD_RELOC_CR16_REGREL20
+@deffnx {} BFD_RELOC_CR16_REGREL20a
+@deffnx {} BFD_RELOC_CR16_ABS20
+@deffnx {} BFD_RELOC_CR16_ABS24
+@deffnx {} BFD_RELOC_CR16_IMM4
+@deffnx {} BFD_RELOC_CR16_IMM8
+@deffnx {} BFD_RELOC_CR16_IMM16
+@deffnx {} BFD_RELOC_CR16_IMM20
+@deffnx {} BFD_RELOC_CR16_IMM24
+@deffnx {} BFD_RELOC_CR16_IMM32
+@deffnx {} BFD_RELOC_CR16_IMM32a
+@deffnx {} BFD_RELOC_CR16_DISP4
+@deffnx {} BFD_RELOC_CR16_DISP8
+@deffnx {} BFD_RELOC_CR16_DISP16
+@deffnx {} BFD_RELOC_CR16_DISP20
+@deffnx {} BFD_RELOC_CR16_DISP24
+@deffnx {} BFD_RELOC_CR16_DISP24a
+@deffnx {} BFD_RELOC_CR16_SWITCH8
+@deffnx {} BFD_RELOC_CR16_SWITCH16
+@deffnx {} BFD_RELOC_CR16_SWITCH32
+@deffnx {} BFD_RELOC_CR16_GOT_REGREL20
+@deffnx {} BFD_RELOC_CR16_GOTC_REGREL20
+@deffnx {} BFD_RELOC_CR16_GLOB_DAT
+NS CR16 Relocations.
+@end deffn
+@deffn {} BFD_RELOC_CRX_REL4
+@deffnx {} BFD_RELOC_CRX_REL8
+@deffnx {} BFD_RELOC_CRX_REL8_CMP
+@deffnx {} BFD_RELOC_CRX_REL16
+@deffnx {} BFD_RELOC_CRX_REL24
+@deffnx {} BFD_RELOC_CRX_REL32
+@deffnx {} BFD_RELOC_CRX_REGREL12
+@deffnx {} BFD_RELOC_CRX_REGREL22
+@deffnx {} BFD_RELOC_CRX_REGREL28
+@deffnx {} BFD_RELOC_CRX_REGREL32
+@deffnx {} BFD_RELOC_CRX_ABS16
+@deffnx {} BFD_RELOC_CRX_ABS32
+@deffnx {} BFD_RELOC_CRX_NUM8
+@deffnx {} BFD_RELOC_CRX_NUM16
+@deffnx {} BFD_RELOC_CRX_NUM32
+@deffnx {} BFD_RELOC_CRX_IMM16
+@deffnx {} BFD_RELOC_CRX_IMM32
+@deffnx {} BFD_RELOC_CRX_SWITCH8
+@deffnx {} BFD_RELOC_CRX_SWITCH16
+@deffnx {} BFD_RELOC_CRX_SWITCH32
+NS CRX Relocations.
+@end deffn
+@deffn {} BFD_RELOC_CRIS_BDISP8
+@deffnx {} BFD_RELOC_CRIS_UNSIGNED_5
+@deffnx {} BFD_RELOC_CRIS_SIGNED_6
+@deffnx {} BFD_RELOC_CRIS_UNSIGNED_6
+@deffnx {} BFD_RELOC_CRIS_SIGNED_8
+@deffnx {} BFD_RELOC_CRIS_UNSIGNED_8
+@deffnx {} BFD_RELOC_CRIS_SIGNED_16
+@deffnx {} BFD_RELOC_CRIS_UNSIGNED_16
+@deffnx {} BFD_RELOC_CRIS_LAPCQ_OFFSET
+@deffnx {} BFD_RELOC_CRIS_UNSIGNED_4
+These relocs are only used within the CRIS assembler. They are not
+(at present) written to any object files.
+@end deffn
+@deffn {} BFD_RELOC_CRIS_COPY
+@deffnx {} BFD_RELOC_CRIS_GLOB_DAT
+@deffnx {} BFD_RELOC_CRIS_JUMP_SLOT
+@deffnx {} BFD_RELOC_CRIS_RELATIVE
+Relocs used in ELF shared libraries for CRIS.
+@end deffn
+@deffn {} BFD_RELOC_CRIS_32_GOT
+32-bit offset to symbol-entry within GOT.
+@end deffn
+@deffn {} BFD_RELOC_CRIS_16_GOT
+16-bit offset to symbol-entry within GOT.
+@end deffn
+@deffn {} BFD_RELOC_CRIS_32_GOTPLT
+32-bit offset to symbol-entry within GOT, with PLT handling.
+@end deffn
+@deffn {} BFD_RELOC_CRIS_16_GOTPLT
+16-bit offset to symbol-entry within GOT, with PLT handling.
+@end deffn
+@deffn {} BFD_RELOC_CRIS_32_GOTREL
+32-bit offset to symbol, relative to GOT.
+@end deffn
+@deffn {} BFD_RELOC_CRIS_32_PLT_GOTREL
+32-bit offset to symbol with PLT entry, relative to GOT.
+@end deffn
+@deffn {} BFD_RELOC_CRIS_32_PLT_PCREL
+32-bit offset to symbol with PLT entry, relative to this relocation.
+@end deffn
+@deffn {} BFD_RELOC_CRIS_32_GOT_GD
+@deffnx {} BFD_RELOC_CRIS_16_GOT_GD
+@deffnx {} BFD_RELOC_CRIS_32_GD
+@deffnx {} BFD_RELOC_CRIS_DTP
+@deffnx {} BFD_RELOC_CRIS_32_DTPREL
+@deffnx {} BFD_RELOC_CRIS_16_DTPREL
+@deffnx {} BFD_RELOC_CRIS_32_GOT_TPREL
+@deffnx {} BFD_RELOC_CRIS_16_GOT_TPREL
+@deffnx {} BFD_RELOC_CRIS_32_TPREL
+@deffnx {} BFD_RELOC_CRIS_16_TPREL
+@deffnx {} BFD_RELOC_CRIS_DTPMOD
+@deffnx {} BFD_RELOC_CRIS_32_IE
+Relocs used in TLS code for CRIS.
+@end deffn
+@deffn {} BFD_RELOC_860_COPY
+@deffnx {} BFD_RELOC_860_GLOB_DAT
+@deffnx {} BFD_RELOC_860_JUMP_SLOT
+@deffnx {} BFD_RELOC_860_RELATIVE
+@deffnx {} BFD_RELOC_860_PC26
+@deffnx {} BFD_RELOC_860_PLT26
+@deffnx {} BFD_RELOC_860_PC16
+@deffnx {} BFD_RELOC_860_LOW0
+@deffnx {} BFD_RELOC_860_SPLIT0
+@deffnx {} BFD_RELOC_860_LOW1
+@deffnx {} BFD_RELOC_860_SPLIT1
+@deffnx {} BFD_RELOC_860_LOW2
+@deffnx {} BFD_RELOC_860_SPLIT2
+@deffnx {} BFD_RELOC_860_LOW3
+@deffnx {} BFD_RELOC_860_LOGOT0
+@deffnx {} BFD_RELOC_860_SPGOT0
+@deffnx {} BFD_RELOC_860_LOGOT1
+@deffnx {} BFD_RELOC_860_SPGOT1
+@deffnx {} BFD_RELOC_860_LOGOTOFF0
+@deffnx {} BFD_RELOC_860_SPGOTOFF0
+@deffnx {} BFD_RELOC_860_LOGOTOFF1
+@deffnx {} BFD_RELOC_860_SPGOTOFF1
+@deffnx {} BFD_RELOC_860_LOGOTOFF2
+@deffnx {} BFD_RELOC_860_LOGOTOFF3
+@deffnx {} BFD_RELOC_860_LOPC
+@deffnx {} BFD_RELOC_860_HIGHADJ
+@deffnx {} BFD_RELOC_860_HAGOT
+@deffnx {} BFD_RELOC_860_HAGOTOFF
+@deffnx {} BFD_RELOC_860_HAPC
+@deffnx {} BFD_RELOC_860_HIGH
+@deffnx {} BFD_RELOC_860_HIGOT
+@deffnx {} BFD_RELOC_860_HIGOTOFF
+Intel i860 Relocations.
+@end deffn
+@deffn {} BFD_RELOC_OR1K_REL_26
+@deffnx {} BFD_RELOC_OR1K_GOTPC_HI16
+@deffnx {} BFD_RELOC_OR1K_GOTPC_LO16
+@deffnx {} BFD_RELOC_OR1K_GOT16
+@deffnx {} BFD_RELOC_OR1K_PLT26
+@deffnx {} BFD_RELOC_OR1K_GOTOFF_HI16
+@deffnx {} BFD_RELOC_OR1K_GOTOFF_LO16
+@deffnx {} BFD_RELOC_OR1K_COPY
+@deffnx {} BFD_RELOC_OR1K_GLOB_DAT
+@deffnx {} BFD_RELOC_OR1K_JMP_SLOT
+@deffnx {} BFD_RELOC_OR1K_RELATIVE
+@deffnx {} BFD_RELOC_OR1K_TLS_GD_HI16
+@deffnx {} BFD_RELOC_OR1K_TLS_GD_LO16
+@deffnx {} BFD_RELOC_OR1K_TLS_LDM_HI16
+@deffnx {} BFD_RELOC_OR1K_TLS_LDM_LO16
+@deffnx {} BFD_RELOC_OR1K_TLS_LDO_HI16
+@deffnx {} BFD_RELOC_OR1K_TLS_LDO_LO16
+@deffnx {} BFD_RELOC_OR1K_TLS_IE_HI16
+@deffnx {} BFD_RELOC_OR1K_TLS_IE_LO16
+@deffnx {} BFD_RELOC_OR1K_TLS_LE_HI16
+@deffnx {} BFD_RELOC_OR1K_TLS_LE_LO16
+@deffnx {} BFD_RELOC_OR1K_TLS_TPOFF
+@deffnx {} BFD_RELOC_OR1K_TLS_DTPOFF
+@deffnx {} BFD_RELOC_OR1K_TLS_DTPMOD
+OpenRISC 1000 Relocations.
+@end deffn
+@deffn {} BFD_RELOC_H8_DIR16A8
+@deffnx {} BFD_RELOC_H8_DIR16R8
+@deffnx {} BFD_RELOC_H8_DIR24A8
+@deffnx {} BFD_RELOC_H8_DIR24R8
+@deffnx {} BFD_RELOC_H8_DIR32A16
+@deffnx {} BFD_RELOC_H8_DISP32A16
+H8 elf Relocations.
+@end deffn
+@deffn {} BFD_RELOC_XSTORMY16_REL_12
+@deffnx {} BFD_RELOC_XSTORMY16_12
+@deffnx {} BFD_RELOC_XSTORMY16_24
+@deffnx {} BFD_RELOC_XSTORMY16_FPTR16
+Sony Xstormy16 Relocations.
+@end deffn
+@deffn {} BFD_RELOC_RELC
+Self-describing complex relocations.
+@end deffn
+@deffn {} BFD_RELOC_XC16X_PAG
+@deffnx {} BFD_RELOC_XC16X_POF
+@deffnx {} BFD_RELOC_XC16X_SEG
+@deffnx {} BFD_RELOC_XC16X_SOF
+Infineon Relocations.
+@end deffn
+@deffn {} BFD_RELOC_VAX_GLOB_DAT
+@deffnx {} BFD_RELOC_VAX_JMP_SLOT
+@deffnx {} BFD_RELOC_VAX_RELATIVE
+Relocations used by VAX ELF.
+@end deffn
+@deffn {} BFD_RELOC_MT_PC16
+Morpho MT - 16 bit immediate relocation.
+@end deffn
+@deffn {} BFD_RELOC_MT_HI16
+Morpho MT - Hi 16 bits of an address.
+@end deffn
+@deffn {} BFD_RELOC_MT_LO16
+Morpho MT - Low 16 bits of an address.
+@end deffn
+@deffn {} BFD_RELOC_MT_GNU_VTINHERIT
+Morpho MT - Used to tell the linker which vtable entries are used.
+@end deffn
+@deffn {} BFD_RELOC_MT_GNU_VTENTRY
+Morpho MT - Used to tell the linker which vtable entries are used.
+@end deffn
+@deffn {} BFD_RELOC_MT_PCINSN8
+Morpho MT - 8 bit immediate relocation.
+@end deffn
+@deffn {} BFD_RELOC_MSP430_10_PCREL
+@deffnx {} BFD_RELOC_MSP430_16_PCREL
+@deffnx {} BFD_RELOC_MSP430_16
+@deffnx {} BFD_RELOC_MSP430_16_PCREL_BYTE
+@deffnx {} BFD_RELOC_MSP430_16_BYTE
+@deffnx {} BFD_RELOC_MSP430_2X_PCREL
+@deffnx {} BFD_RELOC_MSP430_RL_PCREL
+@deffnx {} BFD_RELOC_MSP430_ABS8
+@deffnx {} BFD_RELOC_MSP430X_PCR20_EXT_SRC
+@deffnx {} BFD_RELOC_MSP430X_PCR20_EXT_DST
+@deffnx {} BFD_RELOC_MSP430X_PCR20_EXT_ODST
+@deffnx {} BFD_RELOC_MSP430X_ABS20_EXT_SRC
+@deffnx {} BFD_RELOC_MSP430X_ABS20_EXT_DST
+@deffnx {} BFD_RELOC_MSP430X_ABS20_EXT_ODST
+@deffnx {} BFD_RELOC_MSP430X_ABS20_ADR_SRC
+@deffnx {} BFD_RELOC_MSP430X_ABS20_ADR_DST
+@deffnx {} BFD_RELOC_MSP430X_PCR16
+@deffnx {} BFD_RELOC_MSP430X_PCR20_CALL
+@deffnx {} BFD_RELOC_MSP430X_ABS16
+@deffnx {} BFD_RELOC_MSP430_ABS_HI16
+@deffnx {} BFD_RELOC_MSP430_PREL31
+@deffnx {} BFD_RELOC_MSP430_SYM_DIFF
+msp430 specific relocation codes
+@end deffn
+@deffn {} BFD_RELOC_NIOS2_S16
+@deffnx {} BFD_RELOC_NIOS2_U16
+@deffnx {} BFD_RELOC_NIOS2_CALL26
+@deffnx {} BFD_RELOC_NIOS2_IMM5
+@deffnx {} BFD_RELOC_NIOS2_CACHE_OPX
+@deffnx {} BFD_RELOC_NIOS2_IMM6
+@deffnx {} BFD_RELOC_NIOS2_IMM8
+@deffnx {} BFD_RELOC_NIOS2_HI16
+@deffnx {} BFD_RELOC_NIOS2_LO16
+@deffnx {} BFD_RELOC_NIOS2_HIADJ16
+@deffnx {} BFD_RELOC_NIOS2_GPREL
+@deffnx {} BFD_RELOC_NIOS2_UJMP
+@deffnx {} BFD_RELOC_NIOS2_CJMP
+@deffnx {} BFD_RELOC_NIOS2_CALLR
+@deffnx {} BFD_RELOC_NIOS2_ALIGN
+@deffnx {} BFD_RELOC_NIOS2_GOT16
+@deffnx {} BFD_RELOC_NIOS2_CALL16
+@deffnx {} BFD_RELOC_NIOS2_GOTOFF_LO
+@deffnx {} BFD_RELOC_NIOS2_GOTOFF_HA
+@deffnx {} BFD_RELOC_NIOS2_PCREL_LO
+@deffnx {} BFD_RELOC_NIOS2_PCREL_HA
+@deffnx {} BFD_RELOC_NIOS2_TLS_GD16
+@deffnx {} BFD_RELOC_NIOS2_TLS_LDM16
+@deffnx {} BFD_RELOC_NIOS2_TLS_LDO16
+@deffnx {} BFD_RELOC_NIOS2_TLS_IE16
+@deffnx {} BFD_RELOC_NIOS2_TLS_LE16
+@deffnx {} BFD_RELOC_NIOS2_TLS_DTPMOD
+@deffnx {} BFD_RELOC_NIOS2_TLS_DTPREL
+@deffnx {} BFD_RELOC_NIOS2_TLS_TPREL
+@deffnx {} BFD_RELOC_NIOS2_COPY
+@deffnx {} BFD_RELOC_NIOS2_GLOB_DAT
+@deffnx {} BFD_RELOC_NIOS2_JUMP_SLOT
+@deffnx {} BFD_RELOC_NIOS2_RELATIVE
+@deffnx {} BFD_RELOC_NIOS2_GOTOFF
+@deffnx {} BFD_RELOC_NIOS2_CALL26_NOAT
+@deffnx {} BFD_RELOC_NIOS2_GOT_LO
+@deffnx {} BFD_RELOC_NIOS2_GOT_HA
+@deffnx {} BFD_RELOC_NIOS2_CALL_LO
+@deffnx {} BFD_RELOC_NIOS2_CALL_HA
+Relocations used by the Altera Nios II core.
+@end deffn
+@deffn {} BFD_RELOC_IQ2000_OFFSET_16
+@deffnx {} BFD_RELOC_IQ2000_OFFSET_21
+@deffnx {} BFD_RELOC_IQ2000_UHI16
+IQ2000 Relocations.
+@end deffn
+@deffn {} BFD_RELOC_XTENSA_RTLD
+Special Xtensa relocation used only by PLT entries in ELF shared
+objects to indicate that the runtime linker should set the value
+to one of its own internal functions or data structures.
+@end deffn
+@deffn {} BFD_RELOC_XTENSA_GLOB_DAT
+@deffnx {} BFD_RELOC_XTENSA_JMP_SLOT
+@deffnx {} BFD_RELOC_XTENSA_RELATIVE
+Xtensa relocations for ELF shared objects.
+@end deffn
+@deffn {} BFD_RELOC_XTENSA_PLT
+Xtensa relocation used in ELF object files for symbols that may require
+PLT entries. Otherwise, this is just a generic 32-bit relocation.
+@end deffn
+@deffn {} BFD_RELOC_XTENSA_DIFF8
+@deffnx {} BFD_RELOC_XTENSA_DIFF16
+@deffnx {} BFD_RELOC_XTENSA_DIFF32
+Xtensa relocations to mark the difference of two local symbols.
+These are only needed to support linker relaxation and can be ignored
+when not relaxing. The field is set to the value of the difference
+assuming no relaxation. The relocation encodes the position of the
+first symbol so the linker can determine whether to adjust the field
+value.
+@end deffn
+@deffn {} BFD_RELOC_XTENSA_SLOT0_OP
+@deffnx {} BFD_RELOC_XTENSA_SLOT1_OP
+@deffnx {} BFD_RELOC_XTENSA_SLOT2_OP
+@deffnx {} BFD_RELOC_XTENSA_SLOT3_OP
+@deffnx {} BFD_RELOC_XTENSA_SLOT4_OP
+@deffnx {} BFD_RELOC_XTENSA_SLOT5_OP
+@deffnx {} BFD_RELOC_XTENSA_SLOT6_OP
+@deffnx {} BFD_RELOC_XTENSA_SLOT7_OP
+@deffnx {} BFD_RELOC_XTENSA_SLOT8_OP
+@deffnx {} BFD_RELOC_XTENSA_SLOT9_OP
+@deffnx {} BFD_RELOC_XTENSA_SLOT10_OP
+@deffnx {} BFD_RELOC_XTENSA_SLOT11_OP
+@deffnx {} BFD_RELOC_XTENSA_SLOT12_OP
+@deffnx {} BFD_RELOC_XTENSA_SLOT13_OP
+@deffnx {} BFD_RELOC_XTENSA_SLOT14_OP
+Generic Xtensa relocations for instruction operands. Only the slot
+number is encoded in the relocation. The relocation applies to the
+last PC-relative immediate operand, or if there are no PC-relative
+immediates, to the last immediate operand.
+@end deffn
+@deffn {} BFD_RELOC_XTENSA_SLOT0_ALT
+@deffnx {} BFD_RELOC_XTENSA_SLOT1_ALT
+@deffnx {} BFD_RELOC_XTENSA_SLOT2_ALT
+@deffnx {} BFD_RELOC_XTENSA_SLOT3_ALT
+@deffnx {} BFD_RELOC_XTENSA_SLOT4_ALT
+@deffnx {} BFD_RELOC_XTENSA_SLOT5_ALT
+@deffnx {} BFD_RELOC_XTENSA_SLOT6_ALT
+@deffnx {} BFD_RELOC_XTENSA_SLOT7_ALT
+@deffnx {} BFD_RELOC_XTENSA_SLOT8_ALT
+@deffnx {} BFD_RELOC_XTENSA_SLOT9_ALT
+@deffnx {} BFD_RELOC_XTENSA_SLOT10_ALT
+@deffnx {} BFD_RELOC_XTENSA_SLOT11_ALT
+@deffnx {} BFD_RELOC_XTENSA_SLOT12_ALT
+@deffnx {} BFD_RELOC_XTENSA_SLOT13_ALT
+@deffnx {} BFD_RELOC_XTENSA_SLOT14_ALT
+Alternate Xtensa relocations. Only the slot is encoded in the
+relocation. The meaning of these relocations is opcode-specific.
+@end deffn
+@deffn {} BFD_RELOC_XTENSA_OP0
+@deffnx {} BFD_RELOC_XTENSA_OP1
+@deffnx {} BFD_RELOC_XTENSA_OP2
+Xtensa relocations for backward compatibility. These have all been
+replaced by BFD_RELOC_XTENSA_SLOT0_OP.
+@end deffn
+@deffn {} BFD_RELOC_XTENSA_ASM_EXPAND
+Xtensa relocation to mark that the assembler expanded the
+instructions from an original target. The expansion size is
+encoded in the reloc size.
+@end deffn
+@deffn {} BFD_RELOC_XTENSA_ASM_SIMPLIFY
+Xtensa relocation to mark that the linker should simplify
+assembler-expanded instructions. This is commonly used
+internally by the linker after analysis of a
+BFD_RELOC_XTENSA_ASM_EXPAND.
+@end deffn
+@deffn {} BFD_RELOC_XTENSA_TLSDESC_FN
+@deffnx {} BFD_RELOC_XTENSA_TLSDESC_ARG
+@deffnx {} BFD_RELOC_XTENSA_TLS_DTPOFF
+@deffnx {} BFD_RELOC_XTENSA_TLS_TPOFF
+@deffnx {} BFD_RELOC_XTENSA_TLS_FUNC
+@deffnx {} BFD_RELOC_XTENSA_TLS_ARG
+@deffnx {} BFD_RELOC_XTENSA_TLS_CALL
+Xtensa TLS relocations.
+@end deffn
+@deffn {} BFD_RELOC_Z80_DISP8
+8 bit signed offset in (ix+d) or (iy+d).
+@end deffn
+@deffn {} BFD_RELOC_Z8K_DISP7
+DJNZ offset.
+@end deffn
+@deffn {} BFD_RELOC_Z8K_CALLR
+CALR offset.
+@end deffn
+@deffn {} BFD_RELOC_Z8K_IMM4L
+4 bit value.
+@end deffn
+@deffn {} BFD_RELOC_LM32_CALL
+@deffnx {} BFD_RELOC_LM32_BRANCH
+@deffnx {} BFD_RELOC_LM32_16_GOT
+@deffnx {} BFD_RELOC_LM32_GOTOFF_HI16
+@deffnx {} BFD_RELOC_LM32_GOTOFF_LO16
+@deffnx {} BFD_RELOC_LM32_COPY
+@deffnx {} BFD_RELOC_LM32_GLOB_DAT
+@deffnx {} BFD_RELOC_LM32_JMP_SLOT
+@deffnx {} BFD_RELOC_LM32_RELATIVE
+Lattice Mico32 relocations.
+@end deffn
+@deffn {} BFD_RELOC_MACH_O_SECTDIFF
+Difference between two section addreses. Must be followed by a
+BFD_RELOC_MACH_O_PAIR.
+@end deffn
+@deffn {} BFD_RELOC_MACH_O_LOCAL_SECTDIFF
+Like BFD_RELOC_MACH_O_SECTDIFF but with a local symbol.
+@end deffn
+@deffn {} BFD_RELOC_MACH_O_PAIR
+Pair of relocation. Contains the first symbol.
+@end deffn
+@deffn {} BFD_RELOC_MACH_O_X86_64_BRANCH32
+@deffnx {} BFD_RELOC_MACH_O_X86_64_BRANCH8
+PCREL relocations. They are marked as branch to create PLT entry if
+required.
+@end deffn
+@deffn {} BFD_RELOC_MACH_O_X86_64_GOT
+Used when referencing a GOT entry.
+@end deffn
+@deffn {} BFD_RELOC_MACH_O_X86_64_GOT_LOAD
+Used when loading a GOT entry with movq. It is specially marked so that
+the linker could optimize the movq to a leaq if possible.
+@end deffn
+@deffn {} BFD_RELOC_MACH_O_X86_64_SUBTRACTOR32
+Symbol will be substracted. Must be followed by a BFD_RELOC_64.
+@end deffn
+@deffn {} BFD_RELOC_MACH_O_X86_64_SUBTRACTOR64
+Symbol will be substracted. Must be followed by a BFD_RELOC_64.
+@end deffn
+@deffn {} BFD_RELOC_MACH_O_X86_64_PCREL32_1
+Same as BFD_RELOC_32_PCREL but with an implicit -1 addend.
+@end deffn
+@deffn {} BFD_RELOC_MACH_O_X86_64_PCREL32_2
+Same as BFD_RELOC_32_PCREL but with an implicit -2 addend.
+@end deffn
+@deffn {} BFD_RELOC_MACH_O_X86_64_PCREL32_4
+Same as BFD_RELOC_32_PCREL but with an implicit -4 addend.
+@end deffn
+@deffn {} BFD_RELOC_MICROBLAZE_32_LO
+This is a 32 bit reloc for the microblaze that stores the
+low 16 bits of a value
+@end deffn
+@deffn {} BFD_RELOC_MICROBLAZE_32_LO_PCREL
+This is a 32 bit pc-relative reloc for the microblaze that
+stores the low 16 bits of a value
+@end deffn
+@deffn {} BFD_RELOC_MICROBLAZE_32_ROSDA
+This is a 32 bit reloc for the microblaze that stores a
+value relative to the read-only small data area anchor
+@end deffn
+@deffn {} BFD_RELOC_MICROBLAZE_32_RWSDA
+This is a 32 bit reloc for the microblaze that stores a
+value relative to the read-write small data area anchor
+@end deffn
+@deffn {} BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM
+This is a 32 bit reloc for the microblaze to handle
+expressions of the form "Symbol Op Symbol"
+@end deffn
+@deffn {} BFD_RELOC_MICROBLAZE_64_NONE
+This is a 64 bit reloc that stores the 32 bit pc relative
+value in two words (with an imm instruction). No relocation is
+done here - only used for relaxing
+@end deffn
+@deffn {} BFD_RELOC_MICROBLAZE_64_GOTPC
+This is a 64 bit reloc that stores the 32 bit pc relative
+value in two words (with an imm instruction). The relocation is
+PC-relative GOT offset
+@end deffn
+@deffn {} BFD_RELOC_MICROBLAZE_64_GOT
+This is a 64 bit reloc that stores the 32 bit pc relative
+value in two words (with an imm instruction). The relocation is
+GOT offset
+@end deffn
+@deffn {} BFD_RELOC_MICROBLAZE_64_PLT
+This is a 64 bit reloc that stores the 32 bit pc relative
+value in two words (with an imm instruction). The relocation is
+PC-relative offset into PLT
+@end deffn
+@deffn {} BFD_RELOC_MICROBLAZE_64_GOTOFF
+This is a 64 bit reloc that stores the 32 bit GOT relative
+value in two words (with an imm instruction). The relocation is
+relative offset from _GLOBAL_OFFSET_TABLE_
+@end deffn
+@deffn {} BFD_RELOC_MICROBLAZE_32_GOTOFF
+This is a 32 bit reloc that stores the 32 bit GOT relative
+value in a word. The relocation is relative offset from
+@end deffn
+@deffn {} BFD_RELOC_MICROBLAZE_COPY
+This is used to tell the dynamic linker to copy the value out of
+the dynamic object into the runtime process image.
+@end deffn
+@deffn {} BFD_RELOC_MICROBLAZE_64_TLS
+Unused Reloc
+@end deffn
+@deffn {} BFD_RELOC_MICROBLAZE_64_TLSGD
+This is a 64 bit reloc that stores the 32 bit GOT relative value
+of the GOT TLS GD info entry in two words (with an imm instruction). The
+relocation is GOT offset.
+@end deffn
+@deffn {} BFD_RELOC_MICROBLAZE_64_TLSLD
+This is a 64 bit reloc that stores the 32 bit GOT relative value
+of the GOT TLS LD info entry in two words (with an imm instruction). The
+relocation is GOT offset.
+@end deffn
+@deffn {} BFD_RELOC_MICROBLAZE_32_TLSDTPMOD
+This is a 32 bit reloc that stores the Module ID to GOT(n).
+@end deffn
+@deffn {} BFD_RELOC_MICROBLAZE_32_TLSDTPREL
+This is a 32 bit reloc that stores TLS offset to GOT(n+1).
+@end deffn
+@deffn {} BFD_RELOC_MICROBLAZE_64_TLSDTPREL
+This is a 32 bit reloc for storing TLS offset to two words (uses imm
+instruction)
+@end deffn
+@deffn {} BFD_RELOC_MICROBLAZE_64_TLSGOTTPREL
+This is a 64 bit reloc that stores 32-bit thread pointer relative offset
+to two words (uses imm instruction).
+@end deffn
+@deffn {} BFD_RELOC_MICROBLAZE_64_TLSTPREL
+This is a 64 bit reloc that stores 32-bit thread pointer relative offset
+to two words (uses imm instruction).
+@end deffn
+@deffn {} BFD_RELOC_AARCH64_RELOC_START
+AArch64 pseudo relocation code to mark the start of the AArch64
+relocation enumerators. N.B. the order of the enumerators is
+important as several tables in the AArch64 bfd backend are indexed
+by these enumerators; make sure they are all synced.
+@end deffn
+@deffn {} BFD_RELOC_AARCH64_NONE
+AArch64 null relocation code.
+@end deffn
+@deffn {} BFD_RELOC_AARCH64_64
+@deffnx {} BFD_RELOC_AARCH64_32
+@deffnx {} BFD_RELOC_AARCH64_16
+Basic absolute relocations of N bits. These are equivalent to
+BFD_RELOC_N and they were added to assist the indexing of the howto
+table.
+@end deffn
+@deffn {} BFD_RELOC_AARCH64_64_PCREL
+@deffnx {} BFD_RELOC_AARCH64_32_PCREL
+@deffnx {} BFD_RELOC_AARCH64_16_PCREL
+PC-relative relocations. These are equivalent to BFD_RELOC_N_PCREL
+and they were added to assist the indexing of the howto table.
+@end deffn
+@deffn {} BFD_RELOC_AARCH64_MOVW_G0
+AArch64 MOV[NZK] instruction with most significant bits 0 to 15
+of an unsigned address/value.
+@end deffn
+@deffn {} BFD_RELOC_AARCH64_MOVW_G0_NC
+AArch64 MOV[NZK] instruction with less significant bits 0 to 15 of
+an address/value. No overflow checking.
+@end deffn
+@deffn {} BFD_RELOC_AARCH64_MOVW_G1
+AArch64 MOV[NZK] instruction with most significant bits 16 to 31
+of an unsigned address/value.
+@end deffn
+@deffn {} BFD_RELOC_AARCH64_MOVW_G1_NC
+AArch64 MOV[NZK] instruction with less significant bits 16 to 31
+of an address/value. No overflow checking.
+@end deffn
+@deffn {} BFD_RELOC_AARCH64_MOVW_G2
+AArch64 MOV[NZK] instruction with most significant bits 32 to 47
+of an unsigned address/value.
+@end deffn
+@deffn {} BFD_RELOC_AARCH64_MOVW_G2_NC
+AArch64 MOV[NZK] instruction with less significant bits 32 to 47
+of an address/value. No overflow checking.
+@end deffn
+@deffn {} BFD_RELOC_AARCH64_MOVW_G3
+AArch64 MOV[NZK] instruction with most signficant bits 48 to 64
+of a signed or unsigned address/value.
+@end deffn
+@deffn {} BFD_RELOC_AARCH64_MOVW_G0_S
+AArch64 MOV[NZ] instruction with most significant bits 0 to 15
+of a signed value. Changes instruction to MOVZ or MOVN depending on the
+value's sign.
+@end deffn
+@deffn {} BFD_RELOC_AARCH64_MOVW_G1_S
+AArch64 MOV[NZ] instruction with most significant bits 16 to 31
+of a signed value. Changes instruction to MOVZ or MOVN depending on the
+value's sign.
+@end deffn
+@deffn {} BFD_RELOC_AARCH64_MOVW_G2_S
+AArch64 MOV[NZ] instruction with most significant bits 32 to 47
+of a signed value. Changes instruction to MOVZ or MOVN depending on the
+value's sign.
+@end deffn
+@deffn {} BFD_RELOC_AARCH64_LD_LO19_PCREL
+AArch64 Load Literal instruction, holding a 19 bit pc-relative word
+offset. The lowest two bits must be zero and are not stored in the
+instruction, giving a 21 bit signed byte offset.
+@end deffn
+@deffn {} BFD_RELOC_AARCH64_ADR_LO21_PCREL
+AArch64 ADR instruction, holding a simple 21 bit pc-relative byte offset.
+@end deffn
+@deffn {} BFD_RELOC_AARCH64_ADR_HI21_PCREL
+AArch64 ADRP instruction, with bits 12 to 32 of a pc-relative page
+offset, giving a 4KB aligned page base address.
+@end deffn
+@deffn {} BFD_RELOC_AARCH64_ADR_HI21_NC_PCREL
+AArch64 ADRP instruction, with bits 12 to 32 of a pc-relative page
+offset, giving a 4KB aligned page base address, but with no overflow
+checking.
+@end deffn
+@deffn {} BFD_RELOC_AARCH64_ADD_LO12
+AArch64 ADD immediate instruction, holding bits 0 to 11 of the address.
+Used in conjunction with BFD_RELOC_AARCH64_ADR_HI21_PCREL.
+@end deffn
+@deffn {} BFD_RELOC_AARCH64_LDST8_LO12
+AArch64 8-bit load/store instruction, holding bits 0 to 11 of the
+address. Used in conjunction with BFD_RELOC_AARCH64_ADR_HI21_PCREL.
+@end deffn
+@deffn {} BFD_RELOC_AARCH64_TSTBR14
+AArch64 14 bit pc-relative test bit and branch.
+The lowest two bits must be zero and are not stored in the instruction,
+giving a 16 bit signed byte offset.
+@end deffn
+@deffn {} BFD_RELOC_AARCH64_BRANCH19
+AArch64 19 bit pc-relative conditional branch and compare & branch.
+The lowest two bits must be zero and are not stored in the instruction,
+giving a 21 bit signed byte offset.
+@end deffn
+@deffn {} BFD_RELOC_AARCH64_JUMP26
+AArch64 26 bit pc-relative unconditional branch.
+The lowest two bits must be zero and are not stored in the instruction,
+giving a 28 bit signed byte offset.
+@end deffn
+@deffn {} BFD_RELOC_AARCH64_CALL26
+AArch64 26 bit pc-relative unconditional branch and link.
+The lowest two bits must be zero and are not stored in the instruction,
+giving a 28 bit signed byte offset.
+@end deffn
+@deffn {} BFD_RELOC_AARCH64_LDST16_LO12
+AArch64 16-bit load/store instruction, holding bits 0 to 11 of the
+address. Used in conjunction with BFD_RELOC_AARCH64_ADR_HI21_PCREL.
+@end deffn
+@deffn {} BFD_RELOC_AARCH64_LDST32_LO12
+AArch64 32-bit load/store instruction, holding bits 0 to 11 of the
+address. Used in conjunction with BFD_RELOC_AARCH64_ADR_HI21_PCREL.
+@end deffn
+@deffn {} BFD_RELOC_AARCH64_LDST64_LO12
+AArch64 64-bit load/store instruction, holding bits 0 to 11 of the
+address. Used in conjunction with BFD_RELOC_AARCH64_ADR_HI21_PCREL.
+@end deffn
+@deffn {} BFD_RELOC_AARCH64_LDST128_LO12
+AArch64 128-bit load/store instruction, holding bits 0 to 11 of the
+address. Used in conjunction with BFD_RELOC_AARCH64_ADR_HI21_PCREL.
+@end deffn
+@deffn {} BFD_RELOC_AARCH64_GOT_LD_PREL19
+AArch64 Load Literal instruction, holding a 19 bit PC relative word
+offset of the global offset table entry for a symbol. The lowest two
+bits must be zero and are not stored in the instruction, giving a 21
+bit signed byte offset. This relocation type requires signed overflow
+checking.
+@end deffn
+@deffn {} BFD_RELOC_AARCH64_ADR_GOT_PAGE
+Get to the page base of the global offset table entry for a symbol as
+part of an ADRP instruction using a 21 bit PC relative value.Used in
+conjunction with BFD_RELOC_AARCH64_LD64_GOT_LO12_NC.
+@end deffn
+@deffn {} BFD_RELOC_AARCH64_LD64_GOT_LO12_NC
+Unsigned 12 bit byte offset for 64 bit load/store from the page of
+the GOT entry for this symbol. Used in conjunction with
+BFD_RELOC_AARCH64_ADR_GOTPAGE. Valid in LP64 ABI only.
+@end deffn
+@deffn {} BFD_RELOC_AARCH64_LD32_GOT_LO12_NC
+Unsigned 12 bit byte offset for 32 bit load/store from the page of
+the GOT entry for this symbol. Used in conjunction with
+BFD_RELOC_AARCH64_ADR_GOTPAGE. Valid in ILP32 ABI only.
+@end deffn
+@deffn {} BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21
+Get to the page base of the global offset table entry for a symbols
+tls_index structure as part of an adrp instruction using a 21 bit PC
+relative value. Used in conjunction with
+BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC.
+@end deffn
+@deffn {} BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC
+Unsigned 12 bit byte offset to global offset table entry for a symbols
+tls_index structure. Used in conjunction with
+BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21.
+@end deffn
+@deffn {} BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G1
+AArch64 TLS INITIAL EXEC relocation.
+@end deffn
+@deffn {} BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC
+AArch64 TLS INITIAL EXEC relocation.
+@end deffn
+@deffn {} BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21
+AArch64 TLS INITIAL EXEC relocation.
+@end deffn
+@deffn {} BFD_RELOC_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC
+AArch64 TLS INITIAL EXEC relocation.
+@end deffn
+@deffn {} BFD_RELOC_AARCH64_TLSIE_LD32_GOTTPREL_LO12_NC
+AArch64 TLS INITIAL EXEC relocation.
+@end deffn
+@deffn {} BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19
+AArch64 TLS INITIAL EXEC relocation.
+@end deffn
+@deffn {} BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G2
+AArch64 TLS LOCAL EXEC relocation.
+@end deffn
+@deffn {} BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1
+AArch64 TLS LOCAL EXEC relocation.
+@end deffn
+@deffn {} BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1_NC
+AArch64 TLS LOCAL EXEC relocation.
+@end deffn
+@deffn {} BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0
+AArch64 TLS LOCAL EXEC relocation.
+@end deffn
+@deffn {} BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC
+AArch64 TLS LOCAL EXEC relocation.
+@end deffn
+@deffn {} BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_HI12
+AArch64 TLS LOCAL EXEC relocation.
+@end deffn
+@deffn {} BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12
+AArch64 TLS LOCAL EXEC relocation.
+@end deffn
+@deffn {} BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12_NC
+AArch64 TLS LOCAL EXEC relocation.
+@end deffn
+@deffn {} BFD_RELOC_AARCH64_TLSDESC_LD_PREL19
+AArch64 TLS DESC relocation.
+@end deffn
+@deffn {} BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21
+AArch64 TLS DESC relocation.
+@end deffn
+@deffn {} BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21
+AArch64 TLS DESC relocation.
+@end deffn
+@deffn {} BFD_RELOC_AARCH64_TLSDESC_LD64_LO12_NC
+AArch64 TLS DESC relocation.
+@end deffn
+@deffn {} BFD_RELOC_AARCH64_TLSDESC_LD32_LO12_NC
+AArch64 TLS DESC relocation.
+@end deffn
+@deffn {} BFD_RELOC_AARCH64_TLSDESC_ADD_LO12_NC
+AArch64 TLS DESC relocation.
+@end deffn
+@deffn {} BFD_RELOC_AARCH64_TLSDESC_OFF_G1
+AArch64 TLS DESC relocation.
+@end deffn
+@deffn {} BFD_RELOC_AARCH64_TLSDESC_OFF_G0_NC
+AArch64 TLS DESC relocation.
+@end deffn
+@deffn {} BFD_RELOC_AARCH64_TLSDESC_LDR
+AArch64 TLS DESC relocation.
+@end deffn
+@deffn {} BFD_RELOC_AARCH64_TLSDESC_ADD
+AArch64 TLS DESC relocation.
+@end deffn
+@deffn {} BFD_RELOC_AARCH64_TLSDESC_CALL
+AArch64 TLS DESC relocation.
+@end deffn
+@deffn {} BFD_RELOC_AARCH64_COPY
+AArch64 TLS relocation.
+@end deffn
+@deffn {} BFD_RELOC_AARCH64_GLOB_DAT
+AArch64 TLS relocation.
+@end deffn
+@deffn {} BFD_RELOC_AARCH64_JUMP_SLOT
+AArch64 TLS relocation.
+@end deffn
+@deffn {} BFD_RELOC_AARCH64_RELATIVE
+AArch64 TLS relocation.
+@end deffn
+@deffn {} BFD_RELOC_AARCH64_TLS_DTPMOD
+AArch64 TLS relocation.
+@end deffn
+@deffn {} BFD_RELOC_AARCH64_TLS_DTPREL
+AArch64 TLS relocation.
+@end deffn
+@deffn {} BFD_RELOC_AARCH64_TLS_TPREL
+AArch64 TLS relocation.
+@end deffn
+@deffn {} BFD_RELOC_AARCH64_TLSDESC
+AArch64 TLS relocation.
+@end deffn
+@deffn {} BFD_RELOC_AARCH64_IRELATIVE
+AArch64 support for STT_GNU_IFUNC.
+@end deffn
+@deffn {} BFD_RELOC_AARCH64_RELOC_END
+AArch64 pseudo relocation code to mark the end of the AArch64
+relocation enumerators that have direct mapping to ELF reloc codes.
+There are a few more enumerators after this one; those are mainly
+used by the AArch64 assembler for the internal fixup or to select
+one of the above enumerators.
+@end deffn
+@deffn {} BFD_RELOC_AARCH64_GAS_INTERNAL_FIXUP
+AArch64 pseudo relocation code to be used internally by the AArch64
+assembler and not (currently) written to any object files.
+@end deffn
+@deffn {} BFD_RELOC_AARCH64_LDST_LO12
+AArch64 unspecified load/store instruction, holding bits 0 to 11 of the
+address. Used in conjunction with BFD_RELOC_AARCH64_ADR_HI21_PCREL.
+@end deffn
+@deffn {} BFD_RELOC_AARCH64_LD_GOT_LO12_NC
+AArch64 pseudo relocation code to be used internally by the AArch64
+assembler and not (currently) written to any object files.
+@end deffn
+@deffn {} BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_LO12_NC
+AArch64 pseudo relocation code to be used internally by the AArch64
+assembler and not (currently) written to any object files.
+@end deffn
+@deffn {} BFD_RELOC_AARCH64_TLSDESC_LD_LO12_NC
+AArch64 pseudo relocation code to be used internally by the AArch64
+assembler and not (currently) written to any object files.
+@end deffn
+@deffn {} BFD_RELOC_TILEPRO_COPY
+@deffnx {} BFD_RELOC_TILEPRO_GLOB_DAT
+@deffnx {} BFD_RELOC_TILEPRO_JMP_SLOT
+@deffnx {} BFD_RELOC_TILEPRO_RELATIVE
+@deffnx {} BFD_RELOC_TILEPRO_BROFF_X1
+@deffnx {} BFD_RELOC_TILEPRO_JOFFLONG_X1
+@deffnx {} BFD_RELOC_TILEPRO_JOFFLONG_X1_PLT
+@deffnx {} BFD_RELOC_TILEPRO_IMM8_X0
+@deffnx {} BFD_RELOC_TILEPRO_IMM8_Y0
+@deffnx {} BFD_RELOC_TILEPRO_IMM8_X1
+@deffnx {} BFD_RELOC_TILEPRO_IMM8_Y1
+@deffnx {} BFD_RELOC_TILEPRO_DEST_IMM8_X1
+@deffnx {} BFD_RELOC_TILEPRO_MT_IMM15_X1
+@deffnx {} BFD_RELOC_TILEPRO_MF_IMM15_X1
+@deffnx {} BFD_RELOC_TILEPRO_IMM16_X0
+@deffnx {} BFD_RELOC_TILEPRO_IMM16_X1
+@deffnx {} BFD_RELOC_TILEPRO_IMM16_X0_LO
+@deffnx {} BFD_RELOC_TILEPRO_IMM16_X1_LO
+@deffnx {} BFD_RELOC_TILEPRO_IMM16_X0_HI
+@deffnx {} BFD_RELOC_TILEPRO_IMM16_X1_HI
+@deffnx {} BFD_RELOC_TILEPRO_IMM16_X0_HA
+@deffnx {} BFD_RELOC_TILEPRO_IMM16_X1_HA
+@deffnx {} BFD_RELOC_TILEPRO_IMM16_X0_PCREL
+@deffnx {} BFD_RELOC_TILEPRO_IMM16_X1_PCREL
+@deffnx {} BFD_RELOC_TILEPRO_IMM16_X0_LO_PCREL
+@deffnx {} BFD_RELOC_TILEPRO_IMM16_X1_LO_PCREL
+@deffnx {} BFD_RELOC_TILEPRO_IMM16_X0_HI_PCREL
+@deffnx {} BFD_RELOC_TILEPRO_IMM16_X1_HI_PCREL
+@deffnx {} BFD_RELOC_TILEPRO_IMM16_X0_HA_PCREL
+@deffnx {} BFD_RELOC_TILEPRO_IMM16_X1_HA_PCREL
+@deffnx {} BFD_RELOC_TILEPRO_IMM16_X0_GOT
+@deffnx {} BFD_RELOC_TILEPRO_IMM16_X1_GOT
+@deffnx {} BFD_RELOC_TILEPRO_IMM16_X0_GOT_LO
+@deffnx {} BFD_RELOC_TILEPRO_IMM16_X1_GOT_LO
+@deffnx {} BFD_RELOC_TILEPRO_IMM16_X0_GOT_HI
+@deffnx {} BFD_RELOC_TILEPRO_IMM16_X1_GOT_HI
+@deffnx {} BFD_RELOC_TILEPRO_IMM16_X0_GOT_HA
+@deffnx {} BFD_RELOC_TILEPRO_IMM16_X1_GOT_HA
+@deffnx {} BFD_RELOC_TILEPRO_MMSTART_X0
+@deffnx {} BFD_RELOC_TILEPRO_MMEND_X0
+@deffnx {} BFD_RELOC_TILEPRO_MMSTART_X1
+@deffnx {} BFD_RELOC_TILEPRO_MMEND_X1
+@deffnx {} BFD_RELOC_TILEPRO_SHAMT_X0
+@deffnx {} BFD_RELOC_TILEPRO_SHAMT_X1
+@deffnx {} BFD_RELOC_TILEPRO_SHAMT_Y0
+@deffnx {} BFD_RELOC_TILEPRO_SHAMT_Y1
+@deffnx {} BFD_RELOC_TILEPRO_TLS_GD_CALL
+@deffnx {} BFD_RELOC_TILEPRO_IMM8_X0_TLS_GD_ADD
+@deffnx {} BFD_RELOC_TILEPRO_IMM8_X1_TLS_GD_ADD
+@deffnx {} BFD_RELOC_TILEPRO_IMM8_Y0_TLS_GD_ADD
+@deffnx {} BFD_RELOC_TILEPRO_IMM8_Y1_TLS_GD_ADD
+@deffnx {} BFD_RELOC_TILEPRO_TLS_IE_LOAD
+@deffnx {} BFD_RELOC_TILEPRO_IMM16_X0_TLS_GD
+@deffnx {} BFD_RELOC_TILEPRO_IMM16_X1_TLS_GD
+@deffnx {} BFD_RELOC_TILEPRO_IMM16_X0_TLS_GD_LO
+@deffnx {} BFD_RELOC_TILEPRO_IMM16_X1_TLS_GD_LO
+@deffnx {} BFD_RELOC_TILEPRO_IMM16_X0_TLS_GD_HI
+@deffnx {} BFD_RELOC_TILEPRO_IMM16_X1_TLS_GD_HI
+@deffnx {} BFD_RELOC_TILEPRO_IMM16_X0_TLS_GD_HA
+@deffnx {} BFD_RELOC_TILEPRO_IMM16_X1_TLS_GD_HA
+@deffnx {} BFD_RELOC_TILEPRO_IMM16_X0_TLS_IE
+@deffnx {} BFD_RELOC_TILEPRO_IMM16_X1_TLS_IE
+@deffnx {} BFD_RELOC_TILEPRO_IMM16_X0_TLS_IE_LO
+@deffnx {} BFD_RELOC_TILEPRO_IMM16_X1_TLS_IE_LO
+@deffnx {} BFD_RELOC_TILEPRO_IMM16_X0_TLS_IE_HI
+@deffnx {} BFD_RELOC_TILEPRO_IMM16_X1_TLS_IE_HI
+@deffnx {} BFD_RELOC_TILEPRO_IMM16_X0_TLS_IE_HA
+@deffnx {} BFD_RELOC_TILEPRO_IMM16_X1_TLS_IE_HA
+@deffnx {} BFD_RELOC_TILEPRO_TLS_DTPMOD32
+@deffnx {} BFD_RELOC_TILEPRO_TLS_DTPOFF32
+@deffnx {} BFD_RELOC_TILEPRO_TLS_TPOFF32
+@deffnx {} BFD_RELOC_TILEPRO_IMM16_X0_TLS_LE
+@deffnx {} BFD_RELOC_TILEPRO_IMM16_X1_TLS_LE
+@deffnx {} BFD_RELOC_TILEPRO_IMM16_X0_TLS_LE_LO
+@deffnx {} BFD_RELOC_TILEPRO_IMM16_X1_TLS_LE_LO
+@deffnx {} BFD_RELOC_TILEPRO_IMM16_X0_TLS_LE_HI
+@deffnx {} BFD_RELOC_TILEPRO_IMM16_X1_TLS_LE_HI
+@deffnx {} BFD_RELOC_TILEPRO_IMM16_X0_TLS_LE_HA
+@deffnx {} BFD_RELOC_TILEPRO_IMM16_X1_TLS_LE_HA
+Tilera TILEPro Relocations.
+@end deffn
+@deffn {} BFD_RELOC_TILEGX_HW0
+@deffnx {} BFD_RELOC_TILEGX_HW1
+@deffnx {} BFD_RELOC_TILEGX_HW2
+@deffnx {} BFD_RELOC_TILEGX_HW3
+@deffnx {} BFD_RELOC_TILEGX_HW0_LAST
+@deffnx {} BFD_RELOC_TILEGX_HW1_LAST
+@deffnx {} BFD_RELOC_TILEGX_HW2_LAST
+@deffnx {} BFD_RELOC_TILEGX_COPY
+@deffnx {} BFD_RELOC_TILEGX_GLOB_DAT
+@deffnx {} BFD_RELOC_TILEGX_JMP_SLOT
+@deffnx {} BFD_RELOC_TILEGX_RELATIVE
+@deffnx {} BFD_RELOC_TILEGX_BROFF_X1
+@deffnx {} BFD_RELOC_TILEGX_JUMPOFF_X1
+@deffnx {} BFD_RELOC_TILEGX_JUMPOFF_X1_PLT
+@deffnx {} BFD_RELOC_TILEGX_IMM8_X0
+@deffnx {} BFD_RELOC_TILEGX_IMM8_Y0
+@deffnx {} BFD_RELOC_TILEGX_IMM8_X1
+@deffnx {} BFD_RELOC_TILEGX_IMM8_Y1
+@deffnx {} BFD_RELOC_TILEGX_DEST_IMM8_X1
+@deffnx {} BFD_RELOC_TILEGX_MT_IMM14_X1
+@deffnx {} BFD_RELOC_TILEGX_MF_IMM14_X1
+@deffnx {} BFD_RELOC_TILEGX_MMSTART_X0
+@deffnx {} BFD_RELOC_TILEGX_MMEND_X0
+@deffnx {} BFD_RELOC_TILEGX_SHAMT_X0
+@deffnx {} BFD_RELOC_TILEGX_SHAMT_X1
+@deffnx {} BFD_RELOC_TILEGX_SHAMT_Y0
+@deffnx {} BFD_RELOC_TILEGX_SHAMT_Y1
+@deffnx {} BFD_RELOC_TILEGX_IMM16_X0_HW0
+@deffnx {} BFD_RELOC_TILEGX_IMM16_X1_HW0
+@deffnx {} BFD_RELOC_TILEGX_IMM16_X0_HW1
+@deffnx {} BFD_RELOC_TILEGX_IMM16_X1_HW1
+@deffnx {} BFD_RELOC_TILEGX_IMM16_X0_HW2
+@deffnx {} BFD_RELOC_TILEGX_IMM16_X1_HW2
+@deffnx {} BFD_RELOC_TILEGX_IMM16_X0_HW3
+@deffnx {} BFD_RELOC_TILEGX_IMM16_X1_HW3
+@deffnx {} BFD_RELOC_TILEGX_IMM16_X0_HW0_LAST
+@deffnx {} BFD_RELOC_TILEGX_IMM16_X1_HW0_LAST
+@deffnx {} BFD_RELOC_TILEGX_IMM16_X0_HW1_LAST
+@deffnx {} BFD_RELOC_TILEGX_IMM16_X1_HW1_LAST
+@deffnx {} BFD_RELOC_TILEGX_IMM16_X0_HW2_LAST
+@deffnx {} BFD_RELOC_TILEGX_IMM16_X1_HW2_LAST
+@deffnx {} BFD_RELOC_TILEGX_IMM16_X0_HW0_PCREL
+@deffnx {} BFD_RELOC_TILEGX_IMM16_X1_HW0_PCREL
+@deffnx {} BFD_RELOC_TILEGX_IMM16_X0_HW1_PCREL
+@deffnx {} BFD_RELOC_TILEGX_IMM16_X1_HW1_PCREL
+@deffnx {} BFD_RELOC_TILEGX_IMM16_X0_HW2_PCREL
+@deffnx {} BFD_RELOC_TILEGX_IMM16_X1_HW2_PCREL
+@deffnx {} BFD_RELOC_TILEGX_IMM16_X0_HW3_PCREL
+@deffnx {} BFD_RELOC_TILEGX_IMM16_X1_HW3_PCREL
+@deffnx {} BFD_RELOC_TILEGX_IMM16_X0_HW0_LAST_PCREL
+@deffnx {} BFD_RELOC_TILEGX_IMM16_X1_HW0_LAST_PCREL
+@deffnx {} BFD_RELOC_TILEGX_IMM16_X0_HW1_LAST_PCREL
+@deffnx {} BFD_RELOC_TILEGX_IMM16_X1_HW1_LAST_PCREL
+@deffnx {} BFD_RELOC_TILEGX_IMM16_X0_HW2_LAST_PCREL
+@deffnx {} BFD_RELOC_TILEGX_IMM16_X1_HW2_LAST_PCREL
+@deffnx {} BFD_RELOC_TILEGX_IMM16_X0_HW0_GOT
+@deffnx {} BFD_RELOC_TILEGX_IMM16_X1_HW0_GOT
+@deffnx {} BFD_RELOC_TILEGX_IMM16_X0_HW0_PLT_PCREL
+@deffnx {} BFD_RELOC_TILEGX_IMM16_X1_HW0_PLT_PCREL
+@deffnx {} BFD_RELOC_TILEGX_IMM16_X0_HW1_PLT_PCREL
+@deffnx {} BFD_RELOC_TILEGX_IMM16_X1_HW1_PLT_PCREL
+@deffnx {} BFD_RELOC_TILEGX_IMM16_X0_HW2_PLT_PCREL
+@deffnx {} BFD_RELOC_TILEGX_IMM16_X1_HW2_PLT_PCREL
+@deffnx {} BFD_RELOC_TILEGX_IMM16_X0_HW0_LAST_GOT
+@deffnx {} BFD_RELOC_TILEGX_IMM16_X1_HW0_LAST_GOT
+@deffnx {} BFD_RELOC_TILEGX_IMM16_X0_HW1_LAST_GOT
+@deffnx {} BFD_RELOC_TILEGX_IMM16_X1_HW1_LAST_GOT
+@deffnx {} BFD_RELOC_TILEGX_IMM16_X0_HW3_PLT_PCREL
+@deffnx {} BFD_RELOC_TILEGX_IMM16_X1_HW3_PLT_PCREL
+@deffnx {} BFD_RELOC_TILEGX_IMM16_X0_HW0_TLS_GD
+@deffnx {} BFD_RELOC_TILEGX_IMM16_X1_HW0_TLS_GD
+@deffnx {} BFD_RELOC_TILEGX_IMM16_X0_HW0_TLS_LE
+@deffnx {} BFD_RELOC_TILEGX_IMM16_X1_HW0_TLS_LE
+@deffnx {} BFD_RELOC_TILEGX_IMM16_X0_HW0_LAST_TLS_LE
+@deffnx {} BFD_RELOC_TILEGX_IMM16_X1_HW0_LAST_TLS_LE
+@deffnx {} BFD_RELOC_TILEGX_IMM16_X0_HW1_LAST_TLS_LE
+@deffnx {} BFD_RELOC_TILEGX_IMM16_X1_HW1_LAST_TLS_LE
+@deffnx {} BFD_RELOC_TILEGX_IMM16_X0_HW0_LAST_TLS_GD
+@deffnx {} BFD_RELOC_TILEGX_IMM16_X1_HW0_LAST_TLS_GD
+@deffnx {} BFD_RELOC_TILEGX_IMM16_X0_HW1_LAST_TLS_GD
+@deffnx {} BFD_RELOC_TILEGX_IMM16_X1_HW1_LAST_TLS_GD
+@deffnx {} BFD_RELOC_TILEGX_IMM16_X0_HW0_TLS_IE
+@deffnx {} BFD_RELOC_TILEGX_IMM16_X1_HW0_TLS_IE
+@deffnx {} BFD_RELOC_TILEGX_IMM16_X0_HW0_LAST_PLT_PCREL
+@deffnx {} BFD_RELOC_TILEGX_IMM16_X1_HW0_LAST_PLT_PCREL
+@deffnx {} BFD_RELOC_TILEGX_IMM16_X0_HW1_LAST_PLT_PCREL
+@deffnx {} BFD_RELOC_TILEGX_IMM16_X1_HW1_LAST_PLT_PCREL
+@deffnx {} BFD_RELOC_TILEGX_IMM16_X0_HW2_LAST_PLT_PCREL
+@deffnx {} BFD_RELOC_TILEGX_IMM16_X1_HW2_LAST_PLT_PCREL
+@deffnx {} BFD_RELOC_TILEGX_IMM16_X0_HW0_LAST_TLS_IE
+@deffnx {} BFD_RELOC_TILEGX_IMM16_X1_HW0_LAST_TLS_IE
+@deffnx {} BFD_RELOC_TILEGX_IMM16_X0_HW1_LAST_TLS_IE
+@deffnx {} BFD_RELOC_TILEGX_IMM16_X1_HW1_LAST_TLS_IE
+@deffnx {} BFD_RELOC_TILEGX_TLS_DTPMOD64
+@deffnx {} BFD_RELOC_TILEGX_TLS_DTPOFF64
+@deffnx {} BFD_RELOC_TILEGX_TLS_TPOFF64
+@deffnx {} BFD_RELOC_TILEGX_TLS_DTPMOD32
+@deffnx {} BFD_RELOC_TILEGX_TLS_DTPOFF32
+@deffnx {} BFD_RELOC_TILEGX_TLS_TPOFF32
+@deffnx {} BFD_RELOC_TILEGX_TLS_GD_CALL
+@deffnx {} BFD_RELOC_TILEGX_IMM8_X0_TLS_GD_ADD
+@deffnx {} BFD_RELOC_TILEGX_IMM8_X1_TLS_GD_ADD
+@deffnx {} BFD_RELOC_TILEGX_IMM8_Y0_TLS_GD_ADD
+@deffnx {} BFD_RELOC_TILEGX_IMM8_Y1_TLS_GD_ADD
+@deffnx {} BFD_RELOC_TILEGX_TLS_IE_LOAD
+@deffnx {} BFD_RELOC_TILEGX_IMM8_X0_TLS_ADD
+@deffnx {} BFD_RELOC_TILEGX_IMM8_X1_TLS_ADD
+@deffnx {} BFD_RELOC_TILEGX_IMM8_Y0_TLS_ADD
+@deffnx {} BFD_RELOC_TILEGX_IMM8_Y1_TLS_ADD
+Tilera TILE-Gx Relocations.
+@end deffn
+@deffn {} BFD_RELOC_EPIPHANY_SIMM8
+Adapteva EPIPHANY - 8 bit signed pc-relative displacement
+@end deffn
+@deffn {} BFD_RELOC_EPIPHANY_SIMM24
+Adapteva EPIPHANY - 24 bit signed pc-relative displacement
+@end deffn
+@deffn {} BFD_RELOC_EPIPHANY_HIGH
+Adapteva EPIPHANY - 16 most-significant bits of absolute address
+@end deffn
+@deffn {} BFD_RELOC_EPIPHANY_LOW
+Adapteva EPIPHANY - 16 least-significant bits of absolute address
+@end deffn
+@deffn {} BFD_RELOC_EPIPHANY_SIMM11
+Adapteva EPIPHANY - 11 bit signed number - add/sub immediate
+@end deffn
+@deffn {} BFD_RELOC_EPIPHANY_IMM11
+Adapteva EPIPHANY - 11 bit sign-magnitude number (ld/st displacement)
+@end deffn
+@deffn {} BFD_RELOC_EPIPHANY_IMM8
+Adapteva EPIPHANY - 8 bit immediate for 16 bit mov instruction.
+@end deffn
+
+@example
+
+typedef enum bfd_reloc_code_real bfd_reloc_code_real_type;
+@end example
+@findex bfd_reloc_type_lookup
+@subsubsection @code{bfd_reloc_type_lookup}
+@strong{Synopsis}
+@example
+reloc_howto_type *bfd_reloc_type_lookup
+ (bfd *abfd, bfd_reloc_code_real_type code);
+reloc_howto_type *bfd_reloc_name_lookup
+ (bfd *abfd, const char *reloc_name);
+@end example
+@strong{Description}@*
+Return a pointer to a howto structure which, when
+invoked, will perform the relocation @var{code} on data from the
+architecture noted.
+
+@findex bfd_default_reloc_type_lookup
+@subsubsection @code{bfd_default_reloc_type_lookup}
+@strong{Synopsis}
+@example
+reloc_howto_type *bfd_default_reloc_type_lookup
+ (bfd *abfd, bfd_reloc_code_real_type code);
+@end example
+@strong{Description}@*
+Provides a default relocation lookup routine for any architecture.
+
+@findex bfd_get_reloc_code_name
+@subsubsection @code{bfd_get_reloc_code_name}
+@strong{Synopsis}
+@example
+const char *bfd_get_reloc_code_name (bfd_reloc_code_real_type code);
+@end example
+@strong{Description}@*
+Provides a printable name for the supplied relocation code.
+Useful mainly for printing error messages.
+
+@findex bfd_generic_relax_section
+@subsubsection @code{bfd_generic_relax_section}
+@strong{Synopsis}
+@example
+bfd_boolean bfd_generic_relax_section
+ (bfd *abfd,
+ asection *section,
+ struct bfd_link_info *,
+ bfd_boolean *);
+@end example
+@strong{Description}@*
+Provides default handling for relaxing for back ends which
+don't do relaxing.
+
+@findex bfd_generic_gc_sections
+@subsubsection @code{bfd_generic_gc_sections}
+@strong{Synopsis}
+@example
+bfd_boolean bfd_generic_gc_sections
+ (bfd *, struct bfd_link_info *);
+@end example
+@strong{Description}@*
+Provides default handling for relaxing for back ends which
+don't do section gc -- i.e., does nothing.
+
+@findex bfd_generic_lookup_section_flags
+@subsubsection @code{bfd_generic_lookup_section_flags}
+@strong{Synopsis}
+@example
+bfd_boolean bfd_generic_lookup_section_flags
+ (struct bfd_link_info *, struct flag_info *, asection *);
+@end example
+@strong{Description}@*
+Provides default handling for section flags lookup
+-- i.e., does nothing.
+Returns FALSE if the section should be omitted, otherwise TRUE.
+
+@findex bfd_generic_merge_sections
+@subsubsection @code{bfd_generic_merge_sections}
+@strong{Synopsis}
+@example
+bfd_boolean bfd_generic_merge_sections
+ (bfd *, struct bfd_link_info *);
+@end example
+@strong{Description}@*
+Provides default handling for SEC_MERGE section merging for back ends
+which don't have SEC_MERGE support -- i.e., does nothing.
+
+@findex bfd_generic_get_relocated_section_contents
+@subsubsection @code{bfd_generic_get_relocated_section_contents}
+@strong{Synopsis}
+@example
+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,
+ bfd_boolean relocatable,
+ asymbol **symbols);
+@end example
+@strong{Description}@*
+Provides default handling of relocation effort for back ends
+which can't be bothered to do it efficiently.
+
diff --git a/bfd/doc/section.texi b/bfd/doc/section.texi
new file mode 100644
index 0000000..8f856db
--- /dev/null
+++ b/bfd/doc/section.texi
@@ -0,0 +1,1062 @@
+@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 @code{section.c}.
+
+@menu
+* Section Input::
+* Section Output::
+* typedef asection::
+* section prototypes::
+@end menu
+
+@node 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, @code{a.out} would contain at least
+three sections, called @code{.text}, @code{.data} and @code{.bss}.
+
+Names need not be unique; for example a COFF file may have several
+sections named @code{.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
+@code{bfd_make_section}) to the sections attached to an already open
+BFD. For example, the linker creates an extra section
+@code{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 @code{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.
+
+@node 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 @code{bfd_set_section_contents}.
+
+Any program that creates or combines sections (e.g., the assembler
+and linker) must use the @code{asection} fields @code{output_section} and
+@code{output_offset} to indicate the file sections to which each
+section must be written. (If the section is being created from
+scratch, @code{output_section} should probably point to the section
+itself and @code{output_offset} should probably be zero.)
+
+The data to be written comes from input sections attached
+(via @code{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 @code{asection}
+structures would look like:
+
+@example
+ 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 --------|
+@end example
+
+@subsection Link orders
+The data within a section is stored in a @dfn{link_order}.
+These are much like the fixups in @code{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.
+
+
+@node typedef asection, section prototypes, Section Output, Sections
+@subsection typedef asection
+Here is the section structure:
+
+
+@example
+
+typedef struct bfd_section
+@{
+ /* 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;
+
+ /* A unique sequence number. */
+ int id;
+
+ /* Which section in the bfd; 0..n-1 as sections are created in a bfd. */
+ int index;
+
+ /* The next section in the list belonging to the BFD, or NULL. */
+ struct bfd_section *next;
+
+ /* The previous section in the list belonging to the BFD, or NULL. */
+ struct bfd_section *prev;
+
+ /* 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
+
+ /* A signal to the OS that the section contains read only data. */
+#define SEC_READONLY 0x008
+
+ /* The section contains code only. */
+#define SEC_CODE 0x010
+
+ /* The section contains data only. */
+#define SEC_DATA 0x020
+
+ /* The section will reside in ROM. */
+#define SEC_ROM 0x040
+
+ /* The section contains constructor information. This section
+ type is used by the linker to create lists of constructors and
+ destructors used by @code{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., @code{__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 @code{__CTOR_LIST__} and relocate the data
+ contained within - exactly the operations it would peform on
+ standard data. */
+#define SEC_CONSTRUCTOR 0x080
+
+ /* The section has contents - a data section could be
+ @code{SEC_ALLOC} | @code{SEC_HAS_CONTENTS}; a debug section could be
+ @code{SEC_HAS_CONTENTS} */
+#define SEC_HAS_CONTENTS 0x100
+
+ /* An instruction to the linker to not output the section
+ even if it has information which would normally be written. */
+#define SEC_NEVER_LOAD 0x200
+
+ /* The section contains thread local data. */
+#define SEC_THREAD_LOCAL 0x400
+
+ /* The section has GOT references. This flag is only for the
+ linker, and is currently only used by the elf32-hppa back end.
+ It will be set if global offset table references were detected
+ in this section, which indicate to the linker that the section
+ contains PIC code, and must be handled specially when doing a
+ static link. */
+#define SEC_HAS_GOT_REF 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 0x1000
+
+ /* 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 0x2000
+
+ /* 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 0x4000
+
+ /* 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 0x8000
+
+ /* The contents of this section are to be sorted based on the sum of
+ the symbol and addend values specified by the associated relocation
+ entries. Entries without associated relocation entries will be
+ appended to the end of the section in an unspecified order. */
+#define SEC_SORT_ENTRIES 0x10000
+
+ /* 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 0x20000
+
+ /* If SEC_LINK_ONCE is set, this bitfield describes how the linker
+ should handle duplicate sections. */
+#define SEC_LINK_DUPLICATES 0xc0000
+
+ /* 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 0x40000
+
+ /* 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 0x80000
+
+ /* 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 \
+ (SEC_LINK_DUPLICATES_ONE_ONLY | SEC_LINK_DUPLICATES_SAME_SIZE)
+
+ /* 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 0x100000
+
+ /* This section should not be subject to garbage collection.
+ Also set to inform the linker that this section should not be
+ listed in the link map as discarded. */
+#define SEC_KEEP 0x200000
+
+ /* This section contains "short" data, and should be placed
+ "near" the GP. */
+#define SEC_SMALL_DATA 0x400000
+
+ /* Attempt to merge identical entities in the section.
+ Entity size is given in the entsize field. */
+#define SEC_MERGE 0x800000
+
+ /* If given with SEC_MERGE, entities to merge are zero terminated
+ strings where entsize specifies character size instead of fixed
+ size entries. */
+#define SEC_STRINGS 0x1000000
+
+ /* This section contains data about section groups. */
+#define SEC_GROUP 0x2000000
+
+ /* 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 0x4000000
+
+ /* This input section should be copied to output in reverse order
+ as an array of pointers. This is for ELF linker internal use
+ only. */
+#define SEC_ELF_REVERSE_COPY 0x4000000
+
+ /* This section contains data which may be shared with other
+ executables or shared objects. This is for COFF only. */
+#define SEC_COFF_SHARED 0x8000000
+
+ /* When a section with this flag is being linked, then if the size of
+ the input section is less than a page, it should not cross a page
+ boundary. If the size of the input section is one page or more,
+ it should be aligned on a page boundary. This is for TI
+ TMS320C54X only. */
+#define SEC_TIC54X_BLOCK 0x10000000
+
+ /* Conditionally link this section; do not link if there are no
+ references found to any symbol in the section. This is for TI
+ TMS320C54X only. */
+#define SEC_TIC54X_CLINK 0x20000000
+
+ /* Indicate that section has the no read flag set. This happens
+ when memory read flag isn't set. */
+#define SEC_COFF_NOREAD 0x40000000
+
+ /* End of section flags. */
+
+ /* Some internal packed boolean fields. */
+
+ /* See the vma field. */
+ unsigned int user_set_vma : 1;
+
+ /* A mark flag used by some of the linker backends. */
+ unsigned int linker_mark : 1;
+
+ /* Another mark flag used by some of the linker backends. Set for
+ output sections that have an input section. */
+ unsigned int linker_has_input : 1;
+
+ /* Mark flag used by some linker backends for garbage collection. */
+ unsigned int gc_mark : 1;
+
+ /* Section compression status. */
+ unsigned int compress_status : 2;
+#define COMPRESS_SECTION_NONE 0
+#define COMPRESS_SECTION_DONE 1
+#define DECOMPRESS_SECTION_SIZED 2
+
+ /* The following flags are used by the ELF linker. */
+
+ /* Mark sections which have been allocated to segments. */
+ unsigned int segment_mark : 1;
+
+ /* Type of sec_info information. */
+ unsigned int sec_info_type:3;
+#define SEC_INFO_TYPE_NONE 0
+#define SEC_INFO_TYPE_STABS 1
+#define SEC_INFO_TYPE_MERGE 2
+#define SEC_INFO_TYPE_EH_FRAME 3
+#define SEC_INFO_TYPE_JUST_SYMS 4
+#define SEC_INFO_TYPE_TARGET 5
+
+ /* Nonzero if this section uses RELA relocations, rather than REL. */
+ unsigned int use_rela_p:1;
+
+ /* Bits used by various backends. The generic code doesn't touch
+ these fields. */
+
+ unsigned int sec_flg0:1;
+ unsigned int sec_flg1:1;
+ unsigned int sec_flg2:1;
+ unsigned int sec_flg3:1;
+ unsigned int sec_flg4:1;
+ unsigned int sec_flg5: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 @code{a.out}, where
+ the default address for @code{.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 octets, as it will be output.
+ Contains a value even if the section has no contents (e.g., the
+ size of @code{.bss}). */
+ bfd_size_type size;
+
+ /* For input sections, the original size on disk of the section, in
+ octets. This field should be set for any section whose size is
+ changed by linker relaxation. It is required for sections where
+ the linker relaxation scheme doesn't cache altered section and
+ reloc contents (stabs, eh_frame, SEC_MERGE, some coff relaxing
+ targets), and thus the original size needs to be kept to read the
+ section multiple times. For output sections, rawsize holds the
+ section size calculated on a previous linker relaxation pass. */
+ bfd_size_type rawsize;
+
+ /* The compressed size of the section in octets. */
+ bfd_size_type compressed_size;
+
+ /* Relaxation table. */
+ struct relax_table *relax;
+
+ /* Count of used relaxation table entries. */
+ int relax_count;
+
+
+ /* If this section is going to be output, then this value is the
+ offset in *bytes* into the output section of the first byte in the
+ input section (byte ==> smallest addressable unit on the
+ target). In most cases, if this was going to start at the
+ 100th octet (8-bit quantity) in the output section, this value
+ would be 100. However, if the target byte size is 16 bits
+ (bfd_octets_per_byte is "2"), this value would be 50. */
+ bfd_vma output_offset;
+
+ /* The output section through which to map on output. */
+ struct bfd_section *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. */
+ void *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;
+
+ /* Entity size for merging purposes. */
+ unsigned int entsize;
+
+ /* Points to the kept section if this section is a link-once section,
+ and is discarded. */
+ struct bfd_section *kept_section;
+
+ /* 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;
+
+ void *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 bfd_symbol *symbol;
+ struct bfd_symbol **symbol_ptr_ptr;
+
+ /* Early in the link process, map_head and map_tail are used to build
+ a list of input sections attached to an output section. Later,
+ output sections use these fields for a list of bfd_link_order
+ structs. */
+ union @{
+ struct bfd_link_order *link_order;
+ struct bfd_section *s;
+ @} map_head, map_tail;
+@} asection;
+
+/* Relax table contains information about instructions which can
+ be removed by relaxation -- replacing a long address with a
+ short address. */
+struct relax_table @{
+ /* Address where bytes may be deleted. */
+ bfd_vma addr;
+
+ /* Number of bytes to be deleted. */
+ int size;
+@};
+
+/* Note: the following are provided as inline functions rather than macros
+ because not all callers use the return value. A macro implementation
+ would use a comma expression, eg: "((ptr)->foo = val, TRUE)" and some
+ compilers will complain about comma expressions that have no effect. */
+static inline bfd_boolean
+bfd_set_section_userdata (bfd * abfd ATTRIBUTE_UNUSED, asection * ptr, void * val)
+@{
+ ptr->userdata = val;
+ return TRUE;
+@}
+
+static inline bfd_boolean
+bfd_set_section_vma (bfd * abfd ATTRIBUTE_UNUSED, asection * ptr, bfd_vma val)
+@{
+ ptr->vma = ptr->lma = val;
+ ptr->user_set_vma = TRUE;
+ return TRUE;
+@}
+
+static inline bfd_boolean
+bfd_set_section_alignment (bfd * abfd ATTRIBUTE_UNUSED, asection * ptr, unsigned int val)
+@{
+ ptr->alignment_power = val;
+ return TRUE;
+@}
+
+/* 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. */
+extern asection _bfd_std_section[4];
+
+#define BFD_ABS_SECTION_NAME "*ABS*"
+#define BFD_UND_SECTION_NAME "*UND*"
+#define BFD_COM_SECTION_NAME "*COM*"
+#define BFD_IND_SECTION_NAME "*IND*"
+
+/* Pointer to the common section. */
+#define bfd_com_section_ptr (&_bfd_std_section[0])
+/* Pointer to the undefined section. */
+#define bfd_und_section_ptr (&_bfd_std_section[1])
+/* Pointer to the absolute section. */
+#define bfd_abs_section_ptr (&_bfd_std_section[2])
+/* Pointer to the indirect section. */
+#define bfd_ind_section_ptr (&_bfd_std_section[3])
+
+#define bfd_is_und_section(sec) ((sec) == bfd_und_section_ptr)
+#define bfd_is_abs_section(sec) ((sec) == bfd_abs_section_ptr)
+#define bfd_is_ind_section(sec) ((sec) == bfd_ind_section_ptr)
+
+#define bfd_is_const_section(SEC) \
+ ( ((SEC) == bfd_abs_section_ptr) \
+ || ((SEC) == bfd_und_section_ptr) \
+ || ((SEC) == bfd_com_section_ptr) \
+ || ((SEC) == bfd_ind_section_ptr))
+
+/* Macros to handle insertion and deletion of a bfd's sections. These
+ only handle the list pointers, ie. do not adjust section_count,
+ target_index etc. */
+#define bfd_section_list_remove(ABFD, S) \
+ do \
+ @{ \
+ asection *_s = S; \
+ asection *_next = _s->next; \
+ asection *_prev = _s->prev; \
+ if (_prev) \
+ _prev->next = _next; \
+ else \
+ (ABFD)->sections = _next; \
+ if (_next) \
+ _next->prev = _prev; \
+ else \
+ (ABFD)->section_last = _prev; \
+ @} \
+ while (0)
+#define bfd_section_list_append(ABFD, S) \
+ do \
+ @{ \
+ asection *_s = S; \
+ bfd *_abfd = ABFD; \
+ _s->next = NULL; \
+ if (_abfd->section_last) \
+ @{ \
+ _s->prev = _abfd->section_last; \
+ _abfd->section_last->next = _s; \
+ @} \
+ else \
+ @{ \
+ _s->prev = NULL; \
+ _abfd->sections = _s; \
+ @} \
+ _abfd->section_last = _s; \
+ @} \
+ while (0)
+#define bfd_section_list_prepend(ABFD, S) \
+ do \
+ @{ \
+ asection *_s = S; \
+ bfd *_abfd = ABFD; \
+ _s->prev = NULL; \
+ if (_abfd->sections) \
+ @{ \
+ _s->next = _abfd->sections; \
+ _abfd->sections->prev = _s; \
+ @} \
+ else \
+ @{ \
+ _s->next = NULL; \
+ _abfd->section_last = _s; \
+ @} \
+ _abfd->sections = _s; \
+ @} \
+ while (0)
+#define bfd_section_list_insert_after(ABFD, A, S) \
+ do \
+ @{ \
+ asection *_a = A; \
+ asection *_s = S; \
+ asection *_next = _a->next; \
+ _s->next = _next; \
+ _s->prev = _a; \
+ _a->next = _s; \
+ if (_next) \
+ _next->prev = _s; \
+ else \
+ (ABFD)->section_last = _s; \
+ @} \
+ while (0)
+#define bfd_section_list_insert_before(ABFD, B, S) \
+ do \
+ @{ \
+ asection *_b = B; \
+ asection *_s = S; \
+ asection *_prev = _b->prev; \
+ _s->prev = _prev; \
+ _s->next = _b; \
+ _b->prev = _s; \
+ if (_prev) \
+ _prev->next = _s; \
+ else \
+ (ABFD)->sections = _s; \
+ @} \
+ while (0)
+#define bfd_section_removed_from_list(ABFD, S) \
+ ((S)->next == NULL ? (ABFD)->section_last != (S) : (S)->next->prev != (S))
+
+#define BFD_FAKE_SECTION(SEC, FLAGS, SYM, NAME, IDX) \
+ /* name, id, index, next, prev, flags, user_set_vma, */ \
+ @{ NAME, IDX, 0, NULL, NULL, FLAGS, 0, \
+ \
+ /* linker_mark, linker_has_input, gc_mark, decompress_status, */ \
+ 0, 0, 1, 0, \
+ \
+ /* segment_mark, sec_info_type, use_rela_p, */ \
+ 0, 0, 0, \
+ \
+ /* sec_flg0, sec_flg1, sec_flg2, sec_flg3, sec_flg4, sec_flg5, */ \
+ 0, 0, 0, 0, 0, 0, \
+ \
+ /* vma, lma, size, rawsize, compressed_size, relax, relax_count, */ \
+ 0, 0, 0, 0, 0, 0, 0, \
+ \
+ /* output_offset, output_section, alignment_power, */ \
+ 0, &SEC, 0, \
+ \
+ /* relocation, orelocation, reloc_count, filepos, rel_filepos, */ \
+ NULL, NULL, 0, 0, 0, \
+ \
+ /* line_filepos, userdata, contents, lineno, lineno_count, */ \
+ 0, NULL, NULL, NULL, 0, \
+ \
+ /* entsize, kept_section, moving_line_filepos, */ \
+ 0, NULL, 0, \
+ \
+ /* target_index, used_by_bfd, constructor_chain, owner, */ \
+ 0, NULL, NULL, NULL, \
+ \
+ /* symbol, symbol_ptr_ptr, */ \
+ (struct bfd_symbol *) SYM, &SEC.symbol, \
+ \
+ /* map_head, map_tail */ \
+ @{ NULL @}, @{ NULL @} \
+ @}
+
+@end example
+
+@node section prototypes, , typedef asection, Sections
+@subsection Section prototypes
+These are the functions exported by the section handling part of BFD.
+
+@findex bfd_section_list_clear
+@subsubsection @code{bfd_section_list_clear}
+@strong{Synopsis}
+@example
+void bfd_section_list_clear (bfd *);
+@end example
+@strong{Description}@*
+Clears the section list, and also resets the section count and
+hash table entries.
+
+@findex bfd_get_section_by_name
+@subsubsection @code{bfd_get_section_by_name}
+@strong{Synopsis}
+@example
+asection *bfd_get_section_by_name (bfd *abfd, const char *name);
+@end example
+@strong{Description}@*
+Return the most recently created section attached to @var{abfd}
+named @var{name}. Return NULL if no such section exists.
+
+@findex bfd_get_next_section_by_name
+@subsubsection @code{bfd_get_next_section_by_name}
+@strong{Synopsis}
+@example
+asection *bfd_get_next_section_by_name (asection *sec);
+@end example
+@strong{Description}@*
+Given @var{sec} is a section returned by @code{bfd_get_section_by_name},
+return the next most recently created section attached to the same
+BFD with the same name. Return NULL if no such section exists.
+
+@findex bfd_get_linker_section
+@subsubsection @code{bfd_get_linker_section}
+@strong{Synopsis}
+@example
+asection *bfd_get_linker_section (bfd *abfd, const char *name);
+@end example
+@strong{Description}@*
+Return the linker created section attached to @var{abfd}
+named @var{name}. Return NULL if no such section exists.
+
+@findex bfd_get_section_by_name_if
+@subsubsection @code{bfd_get_section_by_name_if}
+@strong{Synopsis}
+@example
+asection *bfd_get_section_by_name_if
+ (bfd *abfd,
+ const char *name,
+ bfd_boolean (*func) (bfd *abfd, asection *sect, void *obj),
+ void *obj);
+@end example
+@strong{Description}@*
+Call the provided function @var{func} for each section
+attached to the BFD @var{abfd} whose name matches @var{name},
+passing @var{obj} as an argument. The function will be called
+as if by
+
+@example
+ func (abfd, the_section, obj);
+@end example
+
+It returns the first section for which @var{func} returns true,
+otherwise @code{NULL}.
+
+@findex bfd_get_unique_section_name
+@subsubsection @code{bfd_get_unique_section_name}
+@strong{Synopsis}
+@example
+char *bfd_get_unique_section_name
+ (bfd *abfd, const char *templat, int *count);
+@end example
+@strong{Description}@*
+Invent a section name that is unique in @var{abfd} by tacking
+a dot and a digit suffix onto the original @var{templat}. If
+@var{count} is non-NULL, then it specifies the first number
+tried as a suffix to generate a unique name. The value
+pointed to by @var{count} will be incremented in this case.
+
+@findex bfd_make_section_old_way
+@subsubsection @code{bfd_make_section_old_way}
+@strong{Synopsis}
+@example
+asection *bfd_make_section_old_way (bfd *abfd, const char *name);
+@end example
+@strong{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:
+@itemize @bullet
+
+@item
+@code{bfd_error_invalid_operation} -
+If output has already started for this BFD.
+@item
+@code{bfd_error_no_memory} -
+If memory allocation fails.
+@end itemize
+
+@findex bfd_make_section_anyway_with_flags
+@subsubsection @code{bfd_make_section_anyway_with_flags}
+@strong{Synopsis}
+@example
+asection *bfd_make_section_anyway_with_flags
+ (bfd *abfd, const char *name, flagword flags);
+@end example
+@strong{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. Also set the attributes of the
+new section to the value @var{flags}.
+
+Return @code{NULL} and set @code{bfd_error} on error; possible errors are:
+@itemize @bullet
+
+@item
+@code{bfd_error_invalid_operation} - If output has already started for @var{abfd}.
+@item
+@code{bfd_error_no_memory} - If memory allocation fails.
+@end itemize
+
+@findex bfd_make_section_anyway
+@subsubsection @code{bfd_make_section_anyway}
+@strong{Synopsis}
+@example
+asection *bfd_make_section_anyway (bfd *abfd, const char *name);
+@end example
+@strong{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 @code{NULL} and set @code{bfd_error} on error; possible errors are:
+@itemize @bullet
+
+@item
+@code{bfd_error_invalid_operation} - If output has already started for @var{abfd}.
+@item
+@code{bfd_error_no_memory} - If memory allocation fails.
+@end itemize
+
+@findex bfd_make_section_with_flags
+@subsubsection @code{bfd_make_section_with_flags}
+@strong{Synopsis}
+@example
+asection *bfd_make_section_with_flags
+ (bfd *, const char *name, flagword flags);
+@end example
+@strong{Description}@*
+Like @code{bfd_make_section_anyway}, but return @code{NULL} (without calling
+bfd_set_error ()) without changing the section chain if there is already a
+section named @var{name}. Also set the attributes of the new section to
+the value @var{flags}. If there is an error, return @code{NULL} and set
+@code{bfd_error}.
+
+@findex bfd_make_section
+@subsubsection @code{bfd_make_section}
+@strong{Synopsis}
+@example
+asection *bfd_make_section (bfd *, const char *name);
+@end example
+@strong{Description}@*
+Like @code{bfd_make_section_anyway}, but return @code{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 @code{NULL} and set
+@code{bfd_error}.
+
+@findex bfd_set_section_flags
+@subsubsection @code{bfd_set_section_flags}
+@strong{Synopsis}
+@example
+bfd_boolean bfd_set_section_flags
+ (bfd *abfd, asection *sec, flagword flags);
+@end example
+@strong{Description}@*
+Set the attributes of the section @var{sec} in the BFD
+@var{abfd} to the value @var{flags}. Return @code{TRUE} on success,
+@code{FALSE} on error. Possible error returns are:
+
+@itemize @bullet
+
+@item
+@code{bfd_error_invalid_operation} -
+The section cannot have one or more of the attributes
+requested. For example, a .bss section in @code{a.out} may not
+have the @code{SEC_HAS_CONTENTS} field set.
+@end itemize
+
+@findex bfd_rename_section
+@subsubsection @code{bfd_rename_section}
+@strong{Synopsis}
+@example
+void bfd_rename_section
+ (bfd *abfd, asection *sec, const char *newname);
+@end example
+@strong{Description}@*
+Rename section @var{sec} in @var{abfd} to @var{newname}.
+
+@findex bfd_map_over_sections
+@subsubsection @code{bfd_map_over_sections}
+@strong{Synopsis}
+@example
+void bfd_map_over_sections
+ (bfd *abfd,
+ void (*func) (bfd *abfd, asection *sect, void *obj),
+ void *obj);
+@end example
+@strong{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
+
+@example
+ func (abfd, the_section, obj);
+@end example
+
+This is the preferred method for iterating over sections; an
+alternative would be to use a loop:
+
+@example
+ asection *p;
+ for (p = abfd->sections; p != NULL; p = p->next)
+ func (abfd, p, ...)
+@end example
+
+@findex bfd_sections_find_if
+@subsubsection @code{bfd_sections_find_if}
+@strong{Synopsis}
+@example
+asection *bfd_sections_find_if
+ (bfd *abfd,
+ bfd_boolean (*operation) (bfd *abfd, asection *sect, void *obj),
+ void *obj);
+@end example
+@strong{Description}@*
+Call the provided function @var{operation} for each section
+attached to the BFD @var{abfd}, passing @var{obj} as an
+argument. The function will be called as if by
+
+@example
+ operation (abfd, the_section, obj);
+@end example
+
+It returns the first section for which @var{operation} returns true.
+
+@findex bfd_set_section_size
+@subsubsection @code{bfd_set_section_size}
+@strong{Synopsis}
+@example
+bfd_boolean bfd_set_section_size
+ (bfd *abfd, asection *sec, bfd_size_type val);
+@end example
+@strong{Description}@*
+Set @var{sec} to the size @var{val}. If the operation is
+ok, then @code{TRUE} is returned, else @code{FALSE}.
+
+Possible error returns:
+@itemize @bullet
+
+@item
+@code{bfd_error_invalid_operation} -
+Writing has started to the BFD, so setting the size is invalid.
+@end itemize
+
+@findex bfd_set_section_contents
+@subsubsection @code{bfd_set_section_contents}
+@strong{Synopsis}
+@example
+bfd_boolean bfd_set_section_contents
+ (bfd *abfd, asection *section, const void *data,
+ file_ptr offset, bfd_size_type count);
+@end example
+@strong{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} octets.
+
+Normally @code{TRUE} is returned, else @code{FALSE}. Possible error
+returns are:
+@itemize @bullet
+
+@item
+@code{bfd_error_no_contents} -
+The output section does not have the @code{SEC_HAS_CONTENTS}
+attribute, so nothing can be written to it.
+@item
+and some more too
+@end itemize
+This routine is front end to the back end function
+@code{_bfd_set_section_contents}.
+
+@findex bfd_get_section_contents
+@subsubsection @code{bfd_get_section_contents}
+@strong{Synopsis}
+@example
+bfd_boolean bfd_get_section_contents
+ (bfd *abfd, asection *section, void *location, file_ptr offset,
+ bfd_size_type count);
+@end example
+@strong{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 @code{SEC_CONSTRUCTOR}
+flag set are requested or if the section does not have the
+@code{SEC_HAS_CONTENTS} flag set, then the @var{location} is filled
+with zeroes. If no errors occur, @code{TRUE} is returned, else
+@code{FALSE}.
+
+@findex bfd_malloc_and_get_section
+@subsubsection @code{bfd_malloc_and_get_section}
+@strong{Synopsis}
+@example
+bfd_boolean bfd_malloc_and_get_section
+ (bfd *abfd, asection *section, bfd_byte **buf);
+@end example
+@strong{Description}@*
+Read all data from @var{section} in BFD @var{abfd}
+into a buffer, *@var{buf}, malloc'd by this function.
+
+@findex bfd_copy_private_section_data
+@subsubsection @code{bfd_copy_private_section_data}
+@strong{Synopsis}
+@example
+bfd_boolean bfd_copy_private_section_data
+ (bfd *ibfd, asection *isec, bfd *obfd, asection *osec);
+@end example
+@strong{Description}@*
+Copy private section information from @var{isec} in the BFD
+@var{ibfd} to the section @var{osec} in the BFD @var{obfd}.
+Return @code{TRUE} on success, @code{FALSE} on error. Possible error
+returns are:
+
+@itemize @bullet
+
+@item
+@code{bfd_error_no_memory} -
+Not enough memory exists to create private data for @var{osec}.
+@end itemize
+@example
+#define bfd_copy_private_section_data(ibfd, isection, obfd, osection) \
+ BFD_SEND (obfd, _bfd_copy_private_section_data, \
+ (ibfd, isection, obfd, osection))
+@end example
+
+@findex bfd_generic_is_group_section
+@subsubsection @code{bfd_generic_is_group_section}
+@strong{Synopsis}
+@example
+bfd_boolean bfd_generic_is_group_section (bfd *, const asection *sec);
+@end example
+@strong{Description}@*
+Returns TRUE if @var{sec} is a member of a group.
+
+@findex bfd_generic_discard_group
+@subsubsection @code{bfd_generic_discard_group}
+@strong{Synopsis}
+@example
+bfd_boolean bfd_generic_discard_group (bfd *abfd, asection *group);
+@end example
+@strong{Description}@*
+Remove all members of @var{group} from the output.
+
diff --git a/bfd/doc/syms.texi b/bfd/doc/syms.texi
new file mode 100644
index 0000000..6834d10
--- /dev/null
+++ b/bfd/doc/syms.texi
@@ -0,0 +1,480 @@
+@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 @code{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 @code{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
+
+@node 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:
+
+@example
+ 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 = 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]);
+@end example
+
+All storage for the symbols themselves is in an objalloc
+connected to the BFD; it is freed when the BFD is closed.
+
+@node 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 @code{bfd_make_empty_symbol}. Here is an
+example showing the creation of a symbol table with only one element:
+
+@example
+ #include "sysdep.h"
+ #include "bfd.h"
+ int main (void)
+ @{
+ 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] = 0;
+
+ bfd_set_symtab (abfd, ptrs, 1);
+ bfd_close (abfd);
+ return 0;
+ @}
+
+ ./makesym
+ nm foo
+ 00012345 A dummy_symbol
+@end example
+
+Many formats cannot represent arbitrary symbol information; for
+instance, the @code{a.out} object format does not allow an
+arbitrary number of sections. A symbol pointing to a section
+which is not one of @code{.text}, @code{.data} or @code{.bss} cannot
+be described.
+
+@node 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 @code{bfd_read_minisymbols} function will read the symbols
+into memory in an internal form. It will return a @code{void *}
+pointer to a block of memory, a symbol count, and the size of
+each symbol. The pointer is allocated using @code{malloc}, and
+should be freed by the caller when it is no longer needed.
+
+The function @code{bfd_minisymbol_to_symbol} will take a pointer
+to a minisymbol, and a pointer to a structure returned by
+@code{bfd_make_empty_symbol}, and return a @code{asymbol} structure.
+The return value may or may not be the same as the value from
+@code{bfd_make_empty_symbol} which was passed in.
+
+
+@node typedef asymbol, symbol handling functions, Mini Symbols, Symbols
+@subsection typedef asymbol
+An @code{asymbol} has the form:
+
+
+@example
+
+typedef struct bfd_symbol
+@{
+ /* 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; @code{static} in @code{C}. The value
+ is the offset into the section of the data. */
+#define BSF_LOCAL (1 << 0)
+
+ /* The symbol has global scope; initialized data in @code{C}. The
+ value is the offset into the section of the data. */
+#define BSF_GLOBAL (1 << 1)
+
+ /* 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:
+ @code{BSF_LOCAL}, @code{BSF_COMMON}, @code{BSF_UNDEFINED} or
+ @code{BSF_GLOBAL}. */
+
+ /* The symbol is a debugging record. The value has an arbitrary
+ meaning, unless BSF_DEBUGGING_RELOC is also set. */
+#define BSF_DEBUGGING (1 << 2)
+
+ /* The symbol denotes a function entry point. Used in ELF,
+ perhaps others someday. */
+#define BSF_FUNCTION (1 << 3)
+
+ /* Used by the linker. */
+#define BSF_KEEP (1 << 5)
+#define BSF_KEEP_G (1 << 6)
+
+ /* A weak global symbol, overridable without warnings by
+ a regular global symbol of the same name. */
+#define BSF_WEAK (1 << 7)
+
+ /* This symbol was created to point to a section, e.g. ELF's
+ STT_SECTION symbols. */
+#define BSF_SECTION_SYM (1 << 8)
+
+ /* The symbol used to be a common symbol, but now it is
+ allocated. */
+#define BSF_OLD_COMMON (1 << 9)
+
+ /* In some files the type of a symbol sometimes alters its
+ location in an output file - ie in coff a @code{ISFCN} symbol
+ which is also @code{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 (1 << 10)
+
+ /* Signal that the symbol is the label of constructor section. */
+#define BSF_CONSTRUCTOR (1 << 11)
+
+ /* 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 (1 << 12)
+
+ /* 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 (1 << 13)
+
+ /* BSF_FILE marks symbols that contain a file name. This is used
+ for ELF STT_FILE symbols. */
+#define BSF_FILE (1 << 14)
+
+ /* Symbol is from dynamic linking information. */
+#define BSF_DYNAMIC (1 << 15)
+
+ /* The symbol denotes a data object. Used in ELF, and perhaps
+ others someday. */
+#define BSF_OBJECT (1 << 16)
+
+ /* This symbol is a debugging symbol. The value is the offset
+ into the section of the data. BSF_DEBUGGING should be set
+ as well. */
+#define BSF_DEBUGGING_RELOC (1 << 17)
+
+ /* This symbol is thread local. Used in ELF. */
+#define BSF_THREAD_LOCAL (1 << 18)
+
+ /* This symbol represents a complex relocation expression,
+ with the expression tree serialized in the symbol name. */
+#define BSF_RELC (1 << 19)
+
+ /* This symbol represents a signed complex relocation expression,
+ with the expression tree serialized in the symbol name. */
+#define BSF_SRELC (1 << 20)
+
+ /* This symbol was created by bfd_get_synthetic_symtab. */
+#define BSF_SYNTHETIC (1 << 21)
+
+ /* This symbol is an indirect code object. Unrelated to BSF_INDIRECT.
+ The dynamic linker will compute the value of this symbol by
+ calling the function that it points to. BSF_FUNCTION must
+ also be also set. */
+#define BSF_GNU_INDIRECT_FUNCTION (1 << 22)
+ /* This symbol is a globally unique data object. The dynamic linker
+ will make sure that in the entire process there is just one symbol
+ with this name and type in use. BSF_OBJECT must also be set. */
+#define BSF_GNU_UNIQUE (1 << 23)
+
+ 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 bfd_section *section;
+
+ /* Back end special data. */
+ union
+ @{
+ void *p;
+ bfd_vma i;
+ @}
+ udata;
+@}
+asymbol;
+
+@end example
+
+@node symbol handling functions, , typedef asymbol, Symbols
+@subsection Symbol handling functions
+
+
+@findex bfd_get_symtab_upper_bound
+@subsubsection @code{bfd_get_symtab_upper_bound}
+@strong{Description}@*
+Return the number of bytes required to store a vector of pointers
+to @code{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.
+@example
+#define bfd_get_symtab_upper_bound(abfd) \
+ BFD_SEND (abfd, _bfd_get_symtab_upper_bound, (abfd))
+
+@end example
+
+@findex bfd_is_local_label
+@subsubsection @code{bfd_is_local_label}
+@strong{Synopsis}
+@example
+bfd_boolean bfd_is_local_label (bfd *abfd, asymbol *sym);
+@end example
+@strong{Description}@*
+Return TRUE if the given symbol @var{sym} in the BFD @var{abfd} is
+a compiler generated local label, else return FALSE.
+
+@findex bfd_is_local_label_name
+@subsubsection @code{bfd_is_local_label_name}
+@strong{Synopsis}
+@example
+bfd_boolean bfd_is_local_label_name (bfd *abfd, const char *name);
+@end example
+@strong{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.
+@example
+#define bfd_is_local_label_name(abfd, name) \
+ BFD_SEND (abfd, _bfd_is_local_label_name, (abfd, name))
+
+@end example
+
+@findex bfd_is_target_special_symbol
+@subsubsection @code{bfd_is_target_special_symbol}
+@strong{Synopsis}
+@example
+bfd_boolean bfd_is_target_special_symbol (bfd *abfd, asymbol *sym);
+@end example
+@strong{Description}@*
+Return TRUE iff a symbol @var{sym} in the BFD @var{abfd} is something
+special to the particular target represented by the BFD. Such symbols
+should normally not be mentioned to the user.
+@example
+#define bfd_is_target_special_symbol(abfd, sym) \
+ BFD_SEND (abfd, _bfd_is_target_special_symbol, (abfd, sym))
+
+@end example
+
+@findex bfd_canonicalize_symtab
+@subsubsection @code{bfd_canonicalize_symtab}
+@strong{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.
+@example
+#define bfd_canonicalize_symtab(abfd, location) \
+ BFD_SEND (abfd, _bfd_canonicalize_symtab, (abfd, location))
+
+@end example
+
+@findex bfd_set_symtab
+@subsubsection @code{bfd_set_symtab}
+@strong{Synopsis}
+@example
+bfd_boolean bfd_set_symtab
+ (bfd *abfd, asymbol **location, unsigned int count);
+@end example
+@strong{Description}@*
+Arrange that when the output BFD @var{abfd} is closed,
+the table @var{location} of @var{count} pointers to symbols
+will be written.
+
+@findex bfd_print_symbol_vandf
+@subsubsection @code{bfd_print_symbol_vandf}
+@strong{Synopsis}
+@example
+void bfd_print_symbol_vandf (bfd *abfd, void *file, asymbol *symbol);
+@end example
+@strong{Description}@*
+Print the value and flags of the @var{symbol} supplied to the
+stream @var{file}.
+
+@findex bfd_make_empty_symbol
+@subsubsection @code{bfd_make_empty_symbol}
+@strong{Description}@*
+Create a new @code{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 @code{asymbol}. Building your own
+@code{asymbol} and pointing to it will not create the private
+information, and will cause problems later on.
+@example
+#define bfd_make_empty_symbol(abfd) \
+ BFD_SEND (abfd, _bfd_make_empty_symbol, (abfd))
+
+@end example
+
+@findex _bfd_generic_make_empty_symbol
+@subsubsection @code{_bfd_generic_make_empty_symbol}
+@strong{Synopsis}
+@example
+asymbol *_bfd_generic_make_empty_symbol (bfd *);
+@end example
+@strong{Description}@*
+Create a new @code{asymbol} structure for the BFD @var{abfd}
+and return a pointer to it. Used by core file routines,
+binary back-end and anywhere else where no private info
+is needed.
+
+@findex bfd_make_debug_symbol
+@subsubsection @code{bfd_make_debug_symbol}
+@strong{Description}@*
+Create a new @code{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.
+@example
+#define bfd_make_debug_symbol(abfd,ptr,size) \
+ BFD_SEND (abfd, _bfd_make_debug_symbol, (abfd, ptr, size))
+
+@end example
+
+@findex bfd_decode_symclass
+@subsubsection @code{bfd_decode_symclass}
+@strong{Description}@*
+Return a character corresponding to the symbol
+class of @var{symbol}, or '?' for an unknown class.
+
+@strong{Synopsis}
+@example
+int bfd_decode_symclass (asymbol *symbol);
+@end example
+@findex bfd_is_undefined_symclass
+@subsubsection @code{bfd_is_undefined_symclass}
+@strong{Description}@*
+Returns non-zero if the class symbol returned by
+bfd_decode_symclass represents an undefined symbol.
+Returns zero otherwise.
+
+@strong{Synopsis}
+@example
+bfd_boolean bfd_is_undefined_symclass (int symclass);
+@end example
+@findex bfd_symbol_info
+@subsubsection @code{bfd_symbol_info}
+@strong{Description}@*
+Fill in the basic info about symbol that nm needs.
+Additional info may be added by the back-ends after
+calling this function.
+
+@strong{Synopsis}
+@example
+void bfd_symbol_info (asymbol *symbol, symbol_info *ret);
+@end example
+@findex bfd_copy_private_symbol_data
+@subsubsection @code{bfd_copy_private_symbol_data}
+@strong{Synopsis}
+@example
+bfd_boolean bfd_copy_private_symbol_data
+ (bfd *ibfd, asymbol *isym, bfd *obfd, asymbol *osym);
+@end example
+@strong{Description}@*
+Copy private symbol information from @var{isym} in the BFD
+@var{ibfd} to the symbol @var{osym} in the BFD @var{obfd}.
+Return @code{TRUE} on success, @code{FALSE} on error. Possible error
+returns are:
+
+@itemize @bullet
+
+@item
+@code{bfd_error_no_memory} -
+Not enough memory exists to create private data for @var{osec}.
+@end itemize
+@example
+#define bfd_copy_private_symbol_data(ibfd, isymbol, obfd, osymbol) \
+ BFD_SEND (obfd, _bfd_copy_private_symbol_data, \
+ (ibfd, isymbol, obfd, osymbol))
+
+@end example
+
diff --git a/bfd/doc/targets.texi b/bfd/doc/targets.texi
new file mode 100644
index 0000000..a0cd008
--- /dev/null
+++ b/bfd/doc/targets.texi
@@ -0,0 +1,614 @@
+@section Targets
+
+
+@strong{Description}@*
+Each port of BFD to a different machine requires 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 @code{bfd_openr}, its format and
+target are unknown. BFD uses various mechanisms to determine
+how to interpret the file. The operations performed are:
+
+@itemize @bullet
+
+@item
+Create a BFD by calling the internal routine
+@code{_bfd_new_bfd}, then call @code{bfd_find_target} with the
+target string supplied to @code{bfd_openr} and the new BFD pointer.
+
+@item
+If a null target string was provided to @code{bfd_find_target},
+look up the environment variable @code{GNUTARGET} and use
+that as the target string.
+
+@item
+If the target string is still @code{NULL}, or the target string is
+@code{default}, then use the first item in the target vector
+as the target type, and set @code{target_defaulted} in the BFD to
+cause @code{bfd_check_format} to loop through all the targets.
+@xref{bfd_target}. @xref{Formats}.
+
+@item
+Otherwise, inspect the elements in the target vector
+one by one, until a match on target name is found. When found,
+use it.
+
+@item
+Otherwise return the error @code{bfd_error_invalid_target} to
+@code{bfd_openr}.
+
+@item
+@code{bfd_openr} attempts to open the file using
+@code{bfd_open_file}, and returns the BFD.
+@end itemize
+Once the BFD has been opened and the target selected, the file
+format may be determined. This is done by calling
+@code{bfd_check_format} on the BFD with a suggested format.
+If @code{target_defaulted} has been set, each possible target
+type is tried to see if it recognizes the specified format.
+@code{bfd_check_format} returns @code{TRUE} when the caller guesses right.
+@menu
+* bfd_target::
+@end menu
+
+@node bfd_target, , Targets, Targets
+
+@subsection bfd_target
+
+
+@strong{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 @code{xvec}
+member.
+
+The macros below are used to dispatch to functions through the
+@code{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.
+@example
+#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
+@end example
+For operations which index on the BFD format:
+@example
+#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
+
+@end example
+This is the structure which defines the type of BFD this is. The
+@code{xvec} member of the struct @code{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!
+@example
+enum bfd_flavour
+@{
+ bfd_target_unknown_flavour,
+ bfd_target_aout_flavour,
+ bfd_target_coff_flavour,
+ bfd_target_ecoff_flavour,
+ bfd_target_xcoff_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_verilog_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,
+ bfd_target_mmo_flavour,
+ bfd_target_mach_o_flavour,
+ bfd_target_pef_flavour,
+ bfd_target_pef_xlib_flavour,
+ bfd_target_sym_flavour
+@};
+
+enum bfd_endian @{ BFD_ENDIAN_BIG, BFD_ENDIAN_LITTLE, BFD_ENDIAN_UNKNOWN @};
+
+/* Forward declaration. */
+typedef struct bfd_link_info _bfd_link_info;
+
+/* Forward declaration. */
+typedef struct flag_info flag_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 @code{BFD_NO_FLAGS}, @code{HAS_RELOC}, ...@code{D_PAGED}. */
+ flagword object_flags;
+
+ /* A mask of all the flags which a section may have set - from
+ the set @code{SEC_NO_FLAGS}, @code{SEC_ALLOC}, ...@code{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 char ar_max_namelen;
+
+ /* How well this target matches, used to select between various
+ possible targets when more than one target matches. */
+ unsigned char match_priority;
+
+ /* Entries for byte swapping for data. These are different from the
+ other entry points, since they don't take a BFD as the first argument.
+ Certain other handlers could do the same. */
+ bfd_uint64_t (*bfd_getx64) (const void *);
+ bfd_int64_t (*bfd_getx_signed_64) (const void *);
+ void (*bfd_putx64) (bfd_uint64_t, void *);
+ bfd_vma (*bfd_getx32) (const void *);
+ bfd_signed_vma (*bfd_getx_signed_32) (const void *);
+ void (*bfd_putx32) (bfd_vma, void *);
+ bfd_vma (*bfd_getx16) (const void *);
+ bfd_signed_vma (*bfd_getx_signed_16) (const void *);
+ void (*bfd_putx16) (bfd_vma, void *);
+
+ /* Byte swapping for the headers. */
+ bfd_uint64_t (*bfd_h_getx64) (const void *);
+ bfd_int64_t (*bfd_h_getx_signed_64) (const void *);
+ void (*bfd_h_putx64) (bfd_uint64_t, void *);
+ bfd_vma (*bfd_h_getx32) (const void *);
+ bfd_signed_vma (*bfd_h_getx_signed_32) (const void *);
+ void (*bfd_h_putx32) (bfd_vma, void *);
+ bfd_vma (*bfd_h_getx16) (const void *);
+ bfd_signed_vma (*bfd_h_getx_signed_16) (const void *);
+ void (*bfd_h_putx16) (bfd_vma, void *);
+
+ /* 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 @code{bfd_target *} or zero. */
+ const struct bfd_target *(*_bfd_check_format[bfd_type_end]) (bfd *);
+
+ /* Set the format of a file being written. */
+ bfd_boolean (*_bfd_set_format[bfd_type_end]) (bfd *);
+
+ /* Write cached information into a file being written, at @code{bfd_close}. */
+ bfd_boolean (*_bfd_write_contents[bfd_type_end]) (bfd *);
+
+@end example
+The general target vector. These vectors are initialized using the
+BFD_JUMP_TABLE macros.
+@example
+
+ /* Generic entry points. */
+#define BFD_JUMP_TABLE_GENERIC(NAME) \
+ NAME##_close_and_cleanup, \
+ NAME##_bfd_free_cached_info, \
+ NAME##_new_section_hook, \
+ NAME##_get_section_contents, \
+ NAME##_get_section_contents_in_window
+
+ /* Called when the BFD is being closed to do any necessary cleanup. */
+ bfd_boolean (*_close_and_cleanup) (bfd *);
+ /* Ask the BFD to free all cached information. */
+ bfd_boolean (*_bfd_free_cached_info) (bfd *);
+ /* Called when a new section is created. */
+ bfd_boolean (*_new_section_hook) (bfd *, sec_ptr);
+ /* Read the contents of a section. */
+ bfd_boolean (*_bfd_get_section_contents)
+ (bfd *, sec_ptr, void *, file_ptr, bfd_size_type);
+ bfd_boolean (*_bfd_get_section_contents_in_window)
+ (bfd *, sec_ptr, bfd_window *, file_ptr, bfd_size_type);
+
+ /* Entry points to copy private data. */
+#define BFD_JUMP_TABLE_COPY(NAME) \
+ NAME##_bfd_copy_private_bfd_data, \
+ NAME##_bfd_merge_private_bfd_data, \
+ _bfd_generic_init_private_section_data, \
+ NAME##_bfd_copy_private_section_data, \
+ NAME##_bfd_copy_private_symbol_data, \
+ NAME##_bfd_copy_private_header_data, \
+ NAME##_bfd_set_private_flags, \
+ NAME##_bfd_print_private_bfd_data
+
+ /* Called to copy BFD general private data from one object file
+ to another. */
+ bfd_boolean (*_bfd_copy_private_bfd_data) (bfd *, bfd *);
+ /* Called to merge BFD general private data from one object file
+ to a common output file when linking. */
+ bfd_boolean (*_bfd_merge_private_bfd_data) (bfd *, bfd *);
+ /* Called to initialize BFD private section data from one object file
+ to another. */
+#define bfd_init_private_section_data(ibfd, isec, obfd, osec, link_info) \
+ BFD_SEND (obfd, _bfd_init_private_section_data, (ibfd, isec, obfd, osec, link_info))
+ bfd_boolean (*_bfd_init_private_section_data)
+ (bfd *, sec_ptr, bfd *, sec_ptr, struct bfd_link_info *);
+ /* Called to copy BFD private section data from one object file
+ to another. */
+ bfd_boolean (*_bfd_copy_private_section_data)
+ (bfd *, sec_ptr, bfd *, sec_ptr);
+ /* Called to copy BFD private symbol data from one symbol
+ to another. */
+ bfd_boolean (*_bfd_copy_private_symbol_data)
+ (bfd *, asymbol *, bfd *, asymbol *);
+ /* Called to copy BFD private header data from one object file
+ to another. */
+ bfd_boolean (*_bfd_copy_private_header_data)
+ (bfd *, bfd *);
+ /* Called to set private backend flags. */
+ bfd_boolean (*_bfd_set_private_flags) (bfd *, flagword);
+
+ /* Called to print private BFD data. */
+ bfd_boolean (*_bfd_print_private_bfd_data) (bfd *, void *);
+
+ /* Core file entry points. */
+#define BFD_JUMP_TABLE_CORE(NAME) \
+ NAME##_core_file_failing_command, \
+ NAME##_core_file_failing_signal, \
+ NAME##_core_file_matches_executable_p, \
+ NAME##_core_file_pid
+
+ char * (*_core_file_failing_command) (bfd *);
+ int (*_core_file_failing_signal) (bfd *);
+ bfd_boolean (*_core_file_matches_executable_p) (bfd *, bfd *);
+ int (*_core_file_pid) (bfd *);
+
+ /* Archive entry points. */
+#define BFD_JUMP_TABLE_ARCHIVE(NAME) \
+ NAME##_slurp_armap, \
+ NAME##_slurp_extended_name_table, \
+ NAME##_construct_extended_name_table, \
+ NAME##_truncate_arname, \
+ NAME##_write_armap, \
+ NAME##_read_ar_hdr, \
+ NAME##_write_ar_hdr, \
+ NAME##_openr_next_archived_file, \
+ NAME##_get_elt_at_index, \
+ NAME##_generic_stat_arch_elt, \
+ NAME##_update_armap_timestamp
+
+ bfd_boolean (*_bfd_slurp_armap) (bfd *);
+ bfd_boolean (*_bfd_slurp_extended_name_table) (bfd *);
+ bfd_boolean (*_bfd_construct_extended_name_table)
+ (bfd *, char **, bfd_size_type *, const char **);
+ void (*_bfd_truncate_arname) (bfd *, const char *, char *);
+ bfd_boolean (*write_armap)
+ (bfd *, unsigned int, struct orl *, unsigned int, int);
+ void * (*_bfd_read_ar_hdr_fn) (bfd *);
+ bfd_boolean (*_bfd_write_ar_hdr_fn) (bfd *, bfd *);
+ bfd * (*openr_next_archived_file) (bfd *, bfd *);
+#define bfd_get_elt_at_index(b,i) BFD_SEND (b, _bfd_get_elt_at_index, (b,i))
+ bfd * (*_bfd_get_elt_at_index) (bfd *, symindex);
+ int (*_bfd_stat_arch_elt) (bfd *, struct stat *);
+ bfd_boolean (*_bfd_update_armap_timestamp) (bfd *);
+
+ /* Entry points used for symbols. */
+#define BFD_JUMP_TABLE_SYMBOLS(NAME) \
+ NAME##_get_symtab_upper_bound, \
+ NAME##_canonicalize_symtab, \
+ NAME##_make_empty_symbol, \
+ NAME##_print_symbol, \
+ NAME##_get_symbol_info, \
+ NAME##_bfd_is_local_label_name, \
+ NAME##_bfd_is_target_special_symbol, \
+ NAME##_get_lineno, \
+ NAME##_find_nearest_line, \
+ NAME##_find_line, \
+ NAME##_find_inliner_info, \
+ NAME##_bfd_make_debug_symbol, \
+ NAME##_read_minisymbols, \
+ NAME##_minisymbol_to_symbol
+
+ long (*_bfd_get_symtab_upper_bound) (bfd *);
+ long (*_bfd_canonicalize_symtab)
+ (bfd *, struct bfd_symbol **);
+ struct bfd_symbol *
+ (*_bfd_make_empty_symbol) (bfd *);
+ void (*_bfd_print_symbol)
+ (bfd *, void *, struct bfd_symbol *, 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)
+ (bfd *, struct bfd_symbol *, symbol_info *);
+#define bfd_get_symbol_info(b,p,e) BFD_SEND (b, _bfd_get_symbol_info, (b,p,e))
+ bfd_boolean (*_bfd_is_local_label_name) (bfd *, const char *);
+ bfd_boolean (*_bfd_is_target_special_symbol) (bfd *, asymbol *);
+ alent * (*_get_lineno) (bfd *, struct bfd_symbol *);
+ bfd_boolean (*_bfd_find_nearest_line)
+ (bfd *, struct bfd_symbol **, struct bfd_section *, bfd_vma,
+ const char **, const char **, unsigned int *, unsigned int *);
+ bfd_boolean (*_bfd_find_line)
+ (bfd *, struct bfd_symbol **, struct bfd_symbol *,
+ const char **, unsigned int *);
+ bfd_boolean (*_bfd_find_inliner_info)
+ (bfd *, const char **, const char **, unsigned int *);
+ /* 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)
+ (bfd *, void *, unsigned long size);
+#define bfd_read_minisymbols(b, d, m, s) \
+ BFD_SEND (b, _read_minisymbols, (b, d, m, s))
+ long (*_read_minisymbols)
+ (bfd *, bfd_boolean, void **, 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)
+ (bfd *, bfd_boolean, const void *, asymbol *);
+
+ /* Routines for relocs. */
+#define BFD_JUMP_TABLE_RELOCS(NAME) \
+ NAME##_get_reloc_upper_bound, \
+ NAME##_canonicalize_reloc, \
+ NAME##_bfd_reloc_type_lookup, \
+ NAME##_bfd_reloc_name_lookup
+
+ long (*_get_reloc_upper_bound) (bfd *, sec_ptr);
+ long (*_bfd_canonicalize_reloc)
+ (bfd *, sec_ptr, arelent **, struct bfd_symbol **);
+ /* See documentation on reloc types. */
+ reloc_howto_type *
+ (*reloc_type_lookup) (bfd *, bfd_reloc_code_real_type);
+ reloc_howto_type *
+ (*reloc_name_lookup) (bfd *, const char *);
+
+
+ /* Routines used when writing an object file. */
+#define BFD_JUMP_TABLE_WRITE(NAME) \
+ NAME##_set_arch_mach, \
+ NAME##_set_section_contents
+
+ bfd_boolean (*_bfd_set_arch_mach)
+ (bfd *, enum bfd_architecture, unsigned long);
+ bfd_boolean (*_bfd_set_section_contents)
+ (bfd *, sec_ptr, const void *, file_ptr, bfd_size_type);
+
+ /* Routines used by the linker. */
+#define BFD_JUMP_TABLE_LINK(NAME) \
+ NAME##_sizeof_headers, \
+ NAME##_bfd_get_relocated_section_contents, \
+ NAME##_bfd_relax_section, \
+ NAME##_bfd_link_hash_table_create, \
+ NAME##_bfd_link_add_symbols, \
+ NAME##_bfd_link_just_syms, \
+ NAME##_bfd_copy_link_hash_symbol_type, \
+ NAME##_bfd_final_link, \
+ NAME##_bfd_link_split_section, \
+ NAME##_bfd_gc_sections, \
+ NAME##_bfd_lookup_section_flags, \
+ NAME##_bfd_merge_sections, \
+ NAME##_bfd_is_group_section, \
+ NAME##_bfd_discard_group, \
+ NAME##_section_already_linked, \
+ NAME##_bfd_define_common_symbol
+
+ int (*_bfd_sizeof_headers) (bfd *, struct bfd_link_info *);
+ bfd_byte * (*_bfd_get_relocated_section_contents)
+ (bfd *, struct bfd_link_info *, struct bfd_link_order *,
+ bfd_byte *, bfd_boolean, struct bfd_symbol **);
+
+ bfd_boolean (*_bfd_relax_section)
+ (bfd *, struct bfd_section *, struct bfd_link_info *, bfd_boolean *);
+
+ /* 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) (bfd *);
+
+ /* Add symbols from this object file into the hash table. */
+ bfd_boolean (*_bfd_link_add_symbols) (bfd *, struct bfd_link_info *);
+
+ /* Indicate that we are only retrieving symbol values from this section. */
+ void (*_bfd_link_just_syms) (asection *, struct bfd_link_info *);
+
+ /* Copy the symbol type and other attributes for a linker script
+ assignment of one symbol to another. */
+#define bfd_copy_link_hash_symbol_type(b, t, f) \
+ BFD_SEND (b, _bfd_copy_link_hash_symbol_type, (b, t, f))
+ void (*_bfd_copy_link_hash_symbol_type)
+ (bfd *, struct bfd_link_hash_entry *, struct bfd_link_hash_entry *);
+
+ /* Do a link based on the link_order structures attached to each
+ section of the BFD. */
+ bfd_boolean (*_bfd_final_link) (bfd *, struct bfd_link_info *);
+
+ /* Should this section be split up into smaller pieces during linking. */
+ bfd_boolean (*_bfd_link_split_section) (bfd *, struct bfd_section *);
+
+ /* Remove sections that are not referenced from the output. */
+ bfd_boolean (*_bfd_gc_sections) (bfd *, struct bfd_link_info *);
+
+ /* Sets the bitmask of allowed and disallowed section flags. */
+ bfd_boolean (*_bfd_lookup_section_flags) (struct bfd_link_info *,
+ struct flag_info *,
+ asection *);
+
+ /* Attempt to merge SEC_MERGE sections. */
+ bfd_boolean (*_bfd_merge_sections) (bfd *, struct bfd_link_info *);
+
+ /* Is this section a member of a group? */
+ bfd_boolean (*_bfd_is_group_section) (bfd *, const struct bfd_section *);
+
+ /* Discard members of a group. */
+ bfd_boolean (*_bfd_discard_group) (bfd *, struct bfd_section *);
+
+ /* Check if SEC has been already linked during a reloceatable or
+ final link. */
+ bfd_boolean (*_section_already_linked) (bfd *, asection *,
+ struct bfd_link_info *);
+
+ /* Define a common symbol. */
+ bfd_boolean (*_bfd_define_common_symbol) (bfd *, struct bfd_link_info *,
+ struct bfd_link_hash_entry *);
+
+ /* Routines to handle dynamic symbols and relocs. */
+#define BFD_JUMP_TABLE_DYNAMIC(NAME) \
+ NAME##_get_dynamic_symtab_upper_bound, \
+ NAME##_canonicalize_dynamic_symtab, \
+ NAME##_get_synthetic_symtab, \
+ NAME##_get_dynamic_reloc_upper_bound, \
+ NAME##_canonicalize_dynamic_reloc
+
+ /* Get the amount of memory required to hold the dynamic symbols. */
+ long (*_bfd_get_dynamic_symtab_upper_bound) (bfd *);
+ /* Read in the dynamic symbols. */
+ long (*_bfd_canonicalize_dynamic_symtab)
+ (bfd *, struct bfd_symbol **);
+ /* Create synthetized symbols. */
+ long (*_bfd_get_synthetic_symtab)
+ (bfd *, long, struct bfd_symbol **, long, struct bfd_symbol **,
+ struct bfd_symbol **);
+ /* Get the amount of memory required to hold the dynamic relocs. */
+ long (*_bfd_get_dynamic_reloc_upper_bound) (bfd *);
+ /* Read in the dynamic relocs. */
+ long (*_bfd_canonicalize_dynamic_reloc)
+ (bfd *, arelent **, struct bfd_symbol **);
+
+@end example
+A pointer to an alternative bfd_target in case the current one is not
+satisfactory. This can happen when the target cpu supports both big
+and little endian code, and target chosen by the linker has the wrong
+endianness. The function open_output() in ld/ldlang.c uses this field
+to find an alternative output format that is suitable.
+@example
+ /* Opposite endian version of this target. */
+ const struct bfd_target * alternative_target;
+
+ /* Data for use by back-end routines, which isn't
+ generic enough to belong in this structure. */
+ const void *backend_data;
+
+@} bfd_target;
+
+@end example
+
+@findex bfd_set_default_target
+@subsubsection @code{bfd_set_default_target}
+@strong{Synopsis}
+@example
+bfd_boolean bfd_set_default_target (const char *name);
+@end example
+@strong{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.
+
+@findex bfd_find_target
+@subsubsection @code{bfd_find_target}
+@strong{Synopsis}
+@example
+const bfd_target *bfd_find_target (const char *target_name, bfd *abfd);
+@end example
+@strong{Description}@*
+Return a pointer to the transfer vector for the object target
+named @var{target_name}. If @var{target_name} is @code{NULL},
+choose the one in the environment variable @code{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 if @var{abfd} isn't @code{NULL}. This causes
+@code{bfd_check_format} to loop over all the targets to find the
+one that matches the file being read.
+
+@findex bfd_get_target_info
+@subsubsection @code{bfd_get_target_info}
+@strong{Synopsis}
+@example
+const bfd_target *bfd_get_target_info (const char *target_name,
+ bfd *abfd,
+ bfd_boolean *is_bigendian,
+ int *underscoring,
+ const char **def_target_arch);
+@end example
+@strong{Description}@*
+Return a pointer to the transfer vector for the object target
+named @var{target_name}. If @var{target_name} is @code{NULL},
+choose the one in the environment variable @code{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 if @var{abfd} isn't @code{NULL}. This causes
+@code{bfd_check_format} to loop over all the targets to find the
+one that matches the file being read.
+If @var{is_bigendian} is not @code{NULL}, then set this value to target's
+endian mode. True for big-endian, FALSE for little-endian or for
+invalid target.
+If @var{underscoring} is not @code{NULL}, then set this value to target's
+underscoring mode. Zero for none-underscoring, -1 for invalid target,
+else the value of target vector's symbol underscoring.
+If @var{def_target_arch} is not @code{NULL}, then set it to the architecture
+string specified by the target_name.
+
+@findex bfd_target_list
+@subsubsection @code{bfd_target_list}
+@strong{Synopsis}
+@example
+const char ** bfd_target_list (void);
+@end example
+@strong{Description}@*
+Return a freshly malloced NULL-terminated
+vector of the names of all the valid BFD targets. Do not
+modify the names.
+
+@findex bfd_seach_for_target
+@subsubsection @code{bfd_seach_for_target}
+@strong{Synopsis}
+@example
+const bfd_target *bfd_search_for_target
+ (int (*search_func) (const bfd_target *, void *),
+ void *);
+@end example
+@strong{Description}@*
+Return a pointer to the first transfer vector in the list of
+transfer vectors maintained by BFD that produces a non-zero
+result when passed to the function @var{search_func}. The
+parameter @var{data} is passed, unexamined, to the search
+function.
+
diff --git a/bfd/dwarf1.c b/bfd/dwarf1.c
new file mode 100644
index 0000000..6c292ef
--- /dev/null
+++ b/bfd/dwarf1.c
@@ -0,0 +1,563 @@
+/* DWARF 1 find nearest line (_bfd_dwarf1_find_nearest_line).
+ Copyright (C) 1998-2014 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 3 of the License, or (at
+ your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.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;
+
+ /* Pointer to the symbol table. */
+ asymbol** syms;
+
+ /* 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. */
+ bfd_byte *debug_section;
+
+ /* Pointer to the end of the .debug_info section memory buffer. */
+ bfd_byte *debug_section_end;
+
+ /* The buffer for the .line section. */
+ bfd_byte *line_section;
+
+ /* End of that buffer. */
+ bfd_byte *line_section_end;
+
+ /* The current or next unread die within the .debug section. */
+ bfd_byte *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. */
+ bfd_byte *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 (struct dwarf1_debug* stash)
+{
+ bfd_size_type amt = sizeof (struct dwarf1_unit);
+
+ struct dwarf1_unit* x = (struct dwarf1_unit *) bfd_zalloc (stash->abfd, amt);
+ if (x)
+ {
+ 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 (struct dwarf1_debug* stash, struct dwarf1_unit* aUnit)
+{
+ bfd_size_type amt = sizeof (struct dwarf1_func);
+
+ struct dwarf1_func* x = (struct dwarf1_func *) bfd_zalloc (stash->abfd, amt);
+ if (x)
+ {
+ 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 bfd_boolean
+parse_die (bfd * abfd,
+ struct die_info * aDieInfo,
+ bfd_byte * aDiePtr,
+ bfd_byte * aDiePtrEnd)
+{
+ bfd_byte *this_die = aDiePtr;
+ bfd_byte *xptr = this_die;
+
+ memset (aDieInfo, 0, sizeof (* aDieInfo));
+
+ /* First comes the length. */
+ aDieInfo->length = bfd_get_32 (abfd, (bfd_byte *) xptr);
+ xptr += 4;
+ if (aDieInfo->length == 0
+ || (this_die + aDieInfo->length) >= aDiePtrEnd)
+ return FALSE;
+ if (aDieInfo->length < 6)
+ {
+ /* Just padding bytes. */
+ aDieInfo->tag = TAG_padding;
+ return TRUE;
+ }
+
+ /* Then the tag. */
+ aDieInfo->tag = bfd_get_16 (abfd, (bfd_byte *) 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, (bfd_byte *) 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, (bfd_byte *) xptr);
+ else if (attr == AT_stmt_list)
+ {
+ aDieInfo->stmt_list_offset = bfd_get_32 (abfd, (bfd_byte *) 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, (bfd_byte *) xptr);
+ else if (attr == AT_high_pc)
+ aDieInfo->high_pc = bfd_get_32 (abfd, (bfd_byte *) xptr);
+ xptr += 4;
+ break;
+ case FORM_BLOCK2:
+ xptr += 2 + bfd_get_16 (abfd, (bfd_byte *) xptr);
+ break;
+ case FORM_BLOCK4:
+ xptr += 4 + bfd_get_32 (abfd, (bfd_byte *) xptr);
+ break;
+ case FORM_STRING:
+ if (attr == AT_name)
+ aDieInfo->name = (char *) xptr;
+ xptr += strlen ((char *) 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 bfd_boolean
+parse_line_table (struct dwarf1_debug* stash, struct dwarf1_unit* aUnit)
+{
+ bfd_byte *xptr;
+
+ /* Load the ".line" section from the bfd if we haven't already. */
+ if (stash->line_section == 0)
+ {
+ asection *msec;
+ bfd_size_type size;
+
+ msec = bfd_get_section_by_name (stash->abfd, ".line");
+ if (! msec)
+ return FALSE;
+
+ size = msec->rawsize ? msec->rawsize : msec->size;
+ stash->line_section
+ = bfd_simple_get_relocated_section_contents
+ (stash->abfd, msec, NULL, stash->syms);
+
+ if (! stash->line_section)
+ return FALSE;
+
+ stash->line_section_end = stash->line_section + size;
+ }
+
+ xptr = stash->line_section + aUnit->stmt_list_offset;
+ if (xptr < stash->line_section_end)
+ {
+ unsigned long eachLine;
+ bfd_byte *tblend;
+ unsigned long base;
+ bfd_size_type amt;
+
+ /* First comes the length. */
+ tblend = bfd_get_32 (stash->abfd, (bfd_byte *) xptr) + xptr;
+ xptr += 4;
+
+ /* Then the base address for each address in the table. */
+ base = bfd_get_32 (stash->abfd, (bfd_byte *) 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. */
+ amt = sizeof (struct linenumber) * aUnit->line_count;
+ aUnit->linenumber_table = (struct linenumber *) bfd_alloc (stash->abfd,
+ amt);
+ if (!aUnit->linenumber_table)
+ return FALSE;
+
+ for (eachLine = 0; eachLine < aUnit->line_count; eachLine++)
+ {
+ /* A line number. */
+ aUnit->linenumber_table[eachLine].linenumber
+ = bfd_get_32 (stash->abfd, (bfd_byte *) 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, (bfd_byte *) 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 bfd_boolean
+parse_functions_in_unit (struct dwarf1_debug* stash, struct dwarf1_unit* aUnit)
+{
+ bfd_byte *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,
+ stash->debug_section_end))
+ 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);
+ if (!aFunc)
+ return FALSE;
+
+ 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 bfd_boolean
+dwarf1_unit_find_nearest_line (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)
+ {
+ unsigned long 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. */
+
+bfd_boolean
+_bfd_dwarf1_find_nearest_line (bfd *abfd,
+ asymbol **symbols,
+ asection *section,
+ 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? */
+ unsigned long addr = (unsigned long)(offset + section->vma);
+
+ *filename_ptr = NULL;
+ *functionname_ptr = NULL;
+ *linenumber_ptr = 0;
+
+ if (! stash)
+ {
+ asection *msec;
+ bfd_size_type size = sizeof (struct dwarf1_debug);
+
+ stash = elf_tdata (abfd)->dwarf1_find_line_info
+ = (struct dwarf1_debug *) bfd_zalloc (abfd, size);
+
+ 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 = msec->rawsize ? msec->rawsize : msec->size;
+ stash->debug_section
+ = bfd_simple_get_relocated_section_contents (abfd, msec, NULL,
+ symbols);
+
+ if (! stash->debug_section)
+ return FALSE;
+
+ stash->debug_section_end = stash->debug_section + size;
+ stash->currentDie = stash->debug_section;
+ stash->abfd = abfd;
+ stash->syms = symbols;
+ }
+
+ /* 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,
+ stash->debug_section_end))
+ return FALSE;
+
+ if (aDieInfo.tag == TAG_compile_unit)
+ {
+ struct dwarf1_unit* aUnit
+ = alloc_dwarf1_unit (stash);
+ if (!aUnit)
+ return FALSE;
+
+ 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;
+}
diff --git a/bfd/dwarf2.c b/bfd/dwarf2.c
new file mode 100644
index 0000000..93236a6
--- /dev/null
+++ b/bfd/dwarf2.c
@@ -0,0 +1,3987 @@
+/* DWARF 2 support.
+ Copyright (C) 1994-2014 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 3 of the License, or (at
+ your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libiberty.h"
+#include "libbfd.h"
+#include "elf-bfd.h"
+#include "dwarf2.h"
+
+/* The data in the .debug_line statement prologue looks like this. */
+
+struct line_head
+{
+ bfd_vma total_length;
+ unsigned short version;
+ bfd_vma prologue_length;
+ unsigned char minimum_instruction_length;
+ unsigned char maximum_ops_per_insn;
+ 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;
+ bfd_uint64_t val;
+ bfd_int64_t sval;
+ }
+ u;
+};
+
+/* Blocks are a bunch of untyped bytes. */
+struct dwarf_block
+{
+ unsigned int size;
+ bfd_byte *data;
+};
+
+struct adjusted_section
+{
+ asection *section;
+ bfd_vma adj_vma;
+};
+
+struct dwarf2_debug
+{
+ /* A list of all previously read comp_units. */
+ struct comp_unit *all_comp_units;
+
+ /* Last comp unit in list above. */
+ struct comp_unit *last_comp_unit;
+
+ /* Names of the debug sections. */
+ const struct dwarf_debug_section *debug_sections;
+
+ /* 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. */
+ bfd_byte *info_ptr;
+
+ /* Pointer to the end of the .debug_info section memory buffer. */
+ bfd_byte *info_ptr_end;
+
+ /* Pointer to the bfd, section and address of the beginning of the
+ section. The bfd might be different than expected because of
+ gnu_debuglink sections. */
+ bfd *bfd_ptr;
+ asection *sec;
+ bfd_byte *sec_info_ptr;
+
+ /* Support for alternate debug info sections created by the DWZ utility:
+ This includes a pointer to an alternate bfd which contains *extra*,
+ possibly duplicate debug sections, and pointers to the loaded
+ .debug_str and .debug_info sections from this bfd. */
+ bfd * alt_bfd_ptr;
+ bfd_byte * alt_dwarf_str_buffer;
+ bfd_size_type alt_dwarf_str_size;
+ bfd_byte * alt_dwarf_info_buffer;
+ bfd_size_type alt_dwarf_info_size;
+
+ /* A pointer to the memory block allocated for info_ptr. Neither
+ info_ptr nor sec_info_ptr are guaranteed to stay pointing to the
+ beginning of the malloc block. This is used only to free the
+ memory later. */
+ bfd_byte *info_ptr_memory;
+
+ /* Pointer to the symbol table. */
+ asymbol **syms;
+
+ /* Pointer to the .debug_abbrev section loaded into memory. */
+ bfd_byte *dwarf_abbrev_buffer;
+
+ /* Length of the loaded .debug_abbrev section. */
+ bfd_size_type dwarf_abbrev_size;
+
+ /* Buffer for decode_line_info. */
+ bfd_byte *dwarf_line_buffer;
+
+ /* Length of the loaded .debug_line section. */
+ bfd_size_type dwarf_line_size;
+
+ /* Pointer to the .debug_str section loaded into memory. */
+ bfd_byte *dwarf_str_buffer;
+
+ /* Length of the loaded .debug_str section. */
+ bfd_size_type dwarf_str_size;
+
+ /* Pointer to the .debug_ranges section loaded into memory. */
+ bfd_byte *dwarf_ranges_buffer;
+
+ /* Length of the loaded .debug_ranges section. */
+ bfd_size_type dwarf_ranges_size;
+
+ /* If the most recent call to bfd_find_nearest_line was given an
+ address in an inlined function, preserve a pointer into the
+ calling chain for subsequent calls to bfd_find_inliner_info to
+ use. */
+ struct funcinfo *inliner_chain;
+
+ /* Section VMAs at the time the stash was built. */
+ bfd_vma *sec_vma;
+
+ /* Number of sections whose VMA we must adjust. */
+ int adjusted_section_count;
+
+ /* Array of sections with adjusted VMA. */
+ struct adjusted_section *adjusted_sections;
+
+ /* Number of times find_line is called. This is used in
+ the heuristic for enabling the info hash tables. */
+ int info_hash_count;
+
+#define STASH_INFO_HASH_TRIGGER 100
+
+ /* Hash table mapping symbol names to function infos. */
+ struct info_hash_table *funcinfo_hash_table;
+
+ /* Hash table mapping symbol names to variable infos. */
+ struct info_hash_table *varinfo_hash_table;
+
+ /* Head of comp_unit list in the last hash table update. */
+ struct comp_unit *hash_units_head;
+
+ /* Status of info hash. */
+ int info_hash_status;
+#define STASH_INFO_HASH_OFF 0
+#define STASH_INFO_HASH_ON 1
+#define STASH_INFO_HASH_DISABLED 2
+
+ /* True if we opened bfd_ptr. */
+ bfd_boolean close_on_cleanup;
+};
+
+struct arange
+{
+ struct arange *next;
+ bfd_vma low;
+ bfd_vma high;
+};
+
+/* 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;
+
+ /* Likewise, chain the compilation unit read after this one.
+ The comp units are stored in reversed reading order. */
+ struct comp_unit *prev_unit;
+
+ /* Keep the bfd convenient (for memory allocation). */
+ bfd *abfd;
+
+ /* The lowest and highest addresses contained in this compilation
+ unit as specified in the compilation unit header. */
+ struct arange arange;
+
+ /* 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;
+
+ /* Pointer to the current comp_unit so that we can find a given entry
+ by its reference. */
+ bfd_byte *info_ptr_unit;
+
+ /* Pointer to the start of the debug section, for DW_FORM_ref_addr. */
+ bfd_byte *sec_info_ptr;
+
+ /* The offset into .debug_line of the line number table. */
+ unsigned long line_offset;
+
+ /* Pointer to the first child die for the comp unit. */
+ bfd_byte *first_child_die_ptr;
+
+ /* The end of the comp unit. */
+ bfd_byte *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;
+
+ /* A list of the variables found in this comp. unit. */
+ struct varinfo *variable_table;
+
+ /* Pointer to dwarf2_debug structure. */
+ struct dwarf2_debug *stash;
+
+ /* DWARF format version for this unit - from unit header. */
+ int version;
+
+ /* Address size for this unit - from unit header. */
+ unsigned char addr_size;
+
+ /* Offset size for this unit - from unit header. */
+ unsigned char offset_size;
+
+ /* Base address for this unit - from DW_AT_low_pc attribute of
+ DW_TAG_compile_unit DIE */
+ bfd_vma base_address;
+
+ /* TRUE if symbols are cached in hash table for faster lookup by name. */
+ bfd_boolean cached;
+};
+
+/* 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;
+};
+
+/* Map of uncompressed DWARF debug section name to compressed one. It
+ is terminated by NULL uncompressed_name. */
+
+const struct dwarf_debug_section dwarf_debug_sections[] =
+{
+ { ".debug_abbrev", ".zdebug_abbrev" },
+ { ".debug_aranges", ".zdebug_aranges" },
+ { ".debug_frame", ".zdebug_frame" },
+ { ".debug_info", ".zdebug_info" },
+ { ".debug_info", ".zdebug_info" },
+ { ".debug_line", ".zdebug_line" },
+ { ".debug_loc", ".zdebug_loc" },
+ { ".debug_macinfo", ".zdebug_macinfo" },
+ { ".debug_macro", ".zdebug_macro" },
+ { ".debug_pubnames", ".zdebug_pubnames" },
+ { ".debug_pubtypes", ".zdebug_pubtypes" },
+ { ".debug_ranges", ".zdebug_ranges" },
+ { ".debug_static_func", ".zdebug_static_func" },
+ { ".debug_static_vars", ".zdebug_static_vars" },
+ { ".debug_str", ".zdebug_str", },
+ { ".debug_str", ".zdebug_str", },
+ { ".debug_types", ".zdebug_types" },
+ /* GNU DWARF 1 extensions */
+ { ".debug_sfnames", ".zdebug_sfnames" },
+ { ".debug_srcinfo", ".zebug_srcinfo" },
+ /* SGI/MIPS DWARF 2 extensions */
+ { ".debug_funcnames", ".zdebug_funcnames" },
+ { ".debug_typenames", ".zdebug_typenames" },
+ { ".debug_varnames", ".zdebug_varnames" },
+ { ".debug_weaknames", ".zdebug_weaknames" },
+ { NULL, NULL },
+};
+
+/* NB/ Numbers in this enum must match up with indicies
+ into the dwarf_debug_sections[] array above. */
+enum dwarf_debug_section_enum
+{
+ debug_abbrev = 0,
+ debug_aranges,
+ debug_frame,
+ debug_info,
+ debug_info_alt,
+ debug_line,
+ debug_loc,
+ debug_macinfo,
+ debug_macro,
+ debug_pubnames,
+ debug_pubtypes,
+ debug_ranges,
+ debug_static_func,
+ debug_static_vars,
+ debug_str,
+ debug_str_alt,
+ debug_types,
+ debug_sfnames,
+ debug_srcinfo,
+ debug_funcnames,
+ debug_typenames,
+ debug_varnames,
+ debug_weaknames
+};
+
+#ifndef ABBREV_HASH_SIZE
+#define ABBREV_HASH_SIZE 121
+#endif
+#ifndef ATTR_ALLOC_CHUNK
+#define ATTR_ALLOC_CHUNK 4
+#endif
+
+/* Variable and function hash tables. This is used to speed up look-up
+ in lookup_symbol_in_var_table() and lookup_symbol_in_function_table().
+ In order to share code between variable and function infos, we use
+ a list of untyped pointer for all variable/function info associated with
+ a symbol. We waste a bit of memory for list with one node but that
+ simplifies the code. */
+
+struct info_list_node
+{
+ struct info_list_node *next;
+ void *info;
+};
+
+/* Info hash entry. */
+struct info_hash_entry
+{
+ struct bfd_hash_entry root;
+ struct info_list_node *head;
+};
+
+struct info_hash_table
+{
+ struct bfd_hash_table base;
+};
+
+/* Function to create a new entry in info hash table. */
+
+static struct bfd_hash_entry *
+info_hash_table_newfunc (struct bfd_hash_entry *entry,
+ struct bfd_hash_table *table,
+ const char *string)
+{
+ struct info_hash_entry *ret = (struct info_hash_entry *) entry;
+
+ /* Allocate the structure if it has not already been allocated by a
+ derived class. */
+ if (ret == NULL)
+ {
+ ret = (struct info_hash_entry *) bfd_hash_allocate (table,
+ sizeof (* ret));
+ if (ret == NULL)
+ return NULL;
+ }
+
+ /* Call the allocation method of the base class. */
+ ret = ((struct info_hash_entry *)
+ bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string));
+
+ /* Initialize the local fields here. */
+ if (ret)
+ ret->head = NULL;
+
+ return (struct bfd_hash_entry *) ret;
+}
+
+/* Function to create a new info hash table. It returns a pointer to the
+ newly created table or NULL if there is any error. We need abfd
+ solely for memory allocation. */
+
+static struct info_hash_table *
+create_info_hash_table (bfd *abfd)
+{
+ struct info_hash_table *hash_table;
+
+ hash_table = ((struct info_hash_table *)
+ bfd_alloc (abfd, sizeof (struct info_hash_table)));
+ if (!hash_table)
+ return hash_table;
+
+ if (!bfd_hash_table_init (&hash_table->base, info_hash_table_newfunc,
+ sizeof (struct info_hash_entry)))
+ {
+ bfd_release (abfd, hash_table);
+ return NULL;
+ }
+
+ return hash_table;
+}
+
+/* Insert an info entry into an info hash table. We do not check of
+ duplicate entries. Also, the caller need to guarantee that the
+ right type of info in inserted as info is passed as a void* pointer.
+ This function returns true if there is no error. */
+
+static bfd_boolean
+insert_info_hash_table (struct info_hash_table *hash_table,
+ const char *key,
+ void *info,
+ bfd_boolean copy_p)
+{
+ struct info_hash_entry *entry;
+ struct info_list_node *node;
+
+ entry = (struct info_hash_entry*) bfd_hash_lookup (&hash_table->base,
+ key, TRUE, copy_p);
+ if (!entry)
+ return FALSE;
+
+ node = (struct info_list_node *) bfd_hash_allocate (&hash_table->base,
+ sizeof (*node));
+ if (!node)
+ return FALSE;
+
+ node->info = info;
+ node->next = entry->head;
+ entry->head = node;
+
+ return TRUE;
+}
+
+/* Look up an info entry list from an info hash table. Return NULL
+ if there is none. */
+
+static struct info_list_node *
+lookup_info_hash_table (struct info_hash_table *hash_table, const char *key)
+{
+ struct info_hash_entry *entry;
+
+ entry = (struct info_hash_entry*) bfd_hash_lookup (&hash_table->base, key,
+ FALSE, FALSE);
+ return entry ? entry->head : NULL;
+}
+
+/* Read a section into its appropriate place in the dwarf2_debug
+ struct (indicated by SECTION_BUFFER and SECTION_SIZE). If SYMS is
+ not NULL, use bfd_simple_get_relocated_section_contents to read the
+ section contents, otherwise use bfd_get_section_contents. Fail if
+ the located section does not contain at least OFFSET bytes. */
+
+static bfd_boolean
+read_section (bfd * abfd,
+ const struct dwarf_debug_section *sec,
+ asymbol ** syms,
+ bfd_uint64_t offset,
+ bfd_byte ** section_buffer,
+ bfd_size_type * section_size)
+{
+ asection *msec;
+ const char *section_name = sec->uncompressed_name;
+
+ /* The section may have already been read. */
+ if (*section_buffer == NULL)
+ {
+ msec = bfd_get_section_by_name (abfd, section_name);
+ if (! msec)
+ {
+ section_name = sec->compressed_name;
+ if (section_name != NULL)
+ msec = bfd_get_section_by_name (abfd, section_name);
+ }
+ if (! msec)
+ {
+ (*_bfd_error_handler) (_("Dwarf Error: Can't find %s section."),
+ sec->uncompressed_name);
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+
+ *section_size = msec->rawsize ? msec->rawsize : msec->size;
+ if (syms)
+ {
+ *section_buffer
+ = bfd_simple_get_relocated_section_contents (abfd, msec, NULL, syms);
+ if (! *section_buffer)
+ return FALSE;
+ }
+ else
+ {
+ *section_buffer = (bfd_byte *) bfd_malloc (*section_size);
+ if (! *section_buffer)
+ return FALSE;
+ if (! bfd_get_section_contents (abfd, msec, *section_buffer,
+ 0, *section_size))
+ return FALSE;
+ }
+ }
+
+ /* It is possible to get a bad value for the offset into the section
+ that the client wants. Validate it here to avoid trouble later. */
+ if (offset != 0 && offset >= *section_size)
+ {
+ (*_bfd_error_handler) (_("Dwarf Error: Offset (%lu)"
+ " greater than or equal to %s size (%lu)."),
+ (long) offset, section_name, *section_size);
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/* 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 (bfd *abfd ATTRIBUTE_UNUSED, bfd_byte *buf)
+{
+ return bfd_get_8 (abfd, buf);
+}
+
+static int
+read_1_signed_byte (bfd *abfd ATTRIBUTE_UNUSED, bfd_byte *buf)
+{
+ return bfd_get_signed_8 (abfd, buf);
+}
+
+static unsigned int
+read_2_bytes (bfd *abfd, bfd_byte *buf)
+{
+ return bfd_get_16 (abfd, buf);
+}
+
+static unsigned int
+read_4_bytes (bfd *abfd, bfd_byte *buf)
+{
+ return bfd_get_32 (abfd, buf);
+}
+
+static bfd_uint64_t
+read_8_bytes (bfd *abfd, bfd_byte *buf)
+{
+ return bfd_get_64 (abfd, buf);
+}
+
+static bfd_byte *
+read_n_bytes (bfd *abfd ATTRIBUTE_UNUSED,
+ bfd_byte *buf,
+ unsigned int size ATTRIBUTE_UNUSED)
+{
+ return buf;
+}
+
+static char *
+read_string (bfd *abfd ATTRIBUTE_UNUSED,
+ bfd_byte *buf,
+ unsigned int *bytes_read_ptr)
+{
+ /* Return a pointer to the embedded string. */
+ char *str = (char *) buf;
+
+ if (*str == '\0')
+ {
+ *bytes_read_ptr = 1;
+ return NULL;
+ }
+
+ *bytes_read_ptr = strlen (str) + 1;
+ return str;
+}
+
+/* END VERBATIM */
+
+static char *
+read_indirect_string (struct comp_unit * unit,
+ bfd_byte * buf,
+ unsigned int * bytes_read_ptr)
+{
+ bfd_uint64_t offset;
+ struct dwarf2_debug *stash = unit->stash;
+ char *str;
+
+ if (unit->offset_size == 4)
+ offset = read_4_bytes (unit->abfd, buf);
+ else
+ offset = read_8_bytes (unit->abfd, buf);
+
+ *bytes_read_ptr = unit->offset_size;
+
+ if (! read_section (unit->abfd, &stash->debug_sections[debug_str],
+ stash->syms, offset,
+ &stash->dwarf_str_buffer, &stash->dwarf_str_size))
+ return NULL;
+
+ str = (char *) stash->dwarf_str_buffer + offset;
+ if (*str == '\0')
+ return NULL;
+ return str;
+}
+
+/* Like read_indirect_string but uses a .debug_str located in
+ an alternate file pointed to by the .gnu_debugaltlink section.
+ Used to impement DW_FORM_GNU_strp_alt. */
+
+static char *
+read_alt_indirect_string (struct comp_unit * unit,
+ bfd_byte * buf,
+ unsigned int * bytes_read_ptr)
+{
+ bfd_uint64_t offset;
+ struct dwarf2_debug *stash = unit->stash;
+ char *str;
+
+ if (unit->offset_size == 4)
+ offset = read_4_bytes (unit->abfd, buf);
+ else
+ offset = read_8_bytes (unit->abfd, buf);
+
+ *bytes_read_ptr = unit->offset_size;
+
+ if (stash->alt_bfd_ptr == NULL)
+ {
+ bfd * debug_bfd;
+ char * debug_filename = bfd_follow_gnu_debugaltlink (unit->abfd, DEBUGDIR);
+
+ if (debug_filename == NULL)
+ return NULL;
+
+ if ((debug_bfd = bfd_openr (debug_filename, NULL)) == NULL
+ || ! bfd_check_format (debug_bfd, bfd_object))
+ {
+ if (debug_bfd)
+ bfd_close (debug_bfd);
+
+ /* FIXME: Should we report our failure to follow the debuglink ? */
+ free (debug_filename);
+ return NULL;
+ }
+ stash->alt_bfd_ptr = debug_bfd;
+ }
+
+ if (! read_section (unit->stash->alt_bfd_ptr,
+ stash->debug_sections + debug_str_alt,
+ NULL, /* FIXME: Do we need to load alternate symbols ? */
+ offset,
+ &stash->alt_dwarf_str_buffer,
+ &stash->alt_dwarf_str_size))
+ return NULL;
+
+ str = (char *) stash->alt_dwarf_str_buffer + offset;
+ if (*str == '\0')
+ return NULL;
+
+ return str;
+}
+
+/* Resolve an alternate reference from UNIT at OFFSET.
+ Returns a pointer into the loaded alternate CU upon success
+ or NULL upon failure. */
+
+static bfd_byte *
+read_alt_indirect_ref (struct comp_unit * unit,
+ bfd_uint64_t offset)
+{
+ struct dwarf2_debug *stash = unit->stash;
+
+ if (stash->alt_bfd_ptr == NULL)
+ {
+ bfd * debug_bfd;
+ char * debug_filename = bfd_follow_gnu_debugaltlink (unit->abfd, DEBUGDIR);
+
+ if (debug_filename == NULL)
+ return FALSE;
+
+ if ((debug_bfd = bfd_openr (debug_filename, NULL)) == NULL
+ || ! bfd_check_format (debug_bfd, bfd_object))
+ {
+ if (debug_bfd)
+ bfd_close (debug_bfd);
+
+ /* FIXME: Should we report our failure to follow the debuglink ? */
+ free (debug_filename);
+ return NULL;
+ }
+ stash->alt_bfd_ptr = debug_bfd;
+ }
+
+ if (! read_section (unit->stash->alt_bfd_ptr,
+ stash->debug_sections + debug_info_alt,
+ NULL, /* FIXME: Do we need to load alternate symbols ? */
+ offset,
+ &stash->alt_dwarf_info_buffer,
+ &stash->alt_dwarf_info_size))
+ return NULL;
+
+ return stash->alt_dwarf_info_buffer + offset;
+}
+
+static bfd_uint64_t
+read_address (struct comp_unit *unit, bfd_byte *buf)
+{
+ int signed_vma = 0;
+
+ if (bfd_get_flavour (unit->abfd) == bfd_target_elf_flavour)
+ signed_vma = get_elf_backend_data (unit->abfd)->sign_extend_vma;
+
+ if (signed_vma)
+ {
+ switch (unit->addr_size)
+ {
+ case 8:
+ return bfd_get_signed_64 (unit->abfd, buf);
+ case 4:
+ return bfd_get_signed_32 (unit->abfd, buf);
+ case 2:
+ return bfd_get_signed_16 (unit->abfd, buf);
+ default:
+ abort ();
+ }
+ }
+ else
+ {
+ switch (unit->addr_size)
+ {
+ case 8:
+ return bfd_get_64 (unit->abfd, buf);
+ case 4:
+ return bfd_get_32 (unit->abfd, buf);
+ case 2:
+ return bfd_get_16 (unit->abfd, buf);
+ default:
+ abort ();
+ }
+ }
+}
+
+/* Lookup an abbrev_info structure in the abbrev hash table. */
+
+static struct abbrev_info *
+lookup_abbrev (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 (bfd *abfd, bfd_uint64_t offset, struct dwarf2_debug *stash)
+{
+ struct abbrev_info **abbrevs;
+ bfd_byte *abbrev_ptr;
+ struct abbrev_info *cur_abbrev;
+ unsigned int abbrev_number, bytes_read, abbrev_name;
+ unsigned int abbrev_form, hash_number;
+ bfd_size_type amt;
+
+ if (! read_section (abfd, &stash->debug_sections[debug_abbrev],
+ stash->syms, offset,
+ &stash->dwarf_abbrev_buffer, &stash->dwarf_abbrev_size))
+ return NULL;
+
+ amt = sizeof (struct abbrev_info*) * ABBREV_HASH_SIZE;
+ abbrevs = (struct abbrev_info **) bfd_zalloc (abfd, amt);
+ if (abbrevs == NULL)
+ return NULL;
+
+ 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)
+ {
+ amt = sizeof (struct abbrev_info);
+ cur_abbrev = (struct abbrev_info *) bfd_zalloc (abfd, amt);
+ if (cur_abbrev == NULL)
+ return NULL;
+
+ /* Read in abbrev header. */
+ cur_abbrev->number = abbrev_number;
+ cur_abbrev->tag = (enum dwarf_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)
+ {
+ struct attr_abbrev *tmp;
+
+ amt = cur_abbrev->num_attrs + ATTR_ALLOC_CHUNK;
+ amt *= sizeof (struct attr_abbrev);
+ tmp = (struct attr_abbrev *) bfd_realloc (cur_abbrev->attrs, amt);
+ if (tmp == NULL)
+ {
+ size_t i;
+
+ for (i = 0; i < ABBREV_HASH_SIZE; i++)
+ {
+ struct abbrev_info *abbrev = abbrevs[i];
+
+ while (abbrev)
+ {
+ free (abbrev->attrs);
+ abbrev = abbrev->next;
+ }
+ }
+ return NULL;
+ }
+ cur_abbrev->attrs = tmp;
+ }
+
+ cur_abbrev->attrs[cur_abbrev->num_attrs].name
+ = (enum dwarf_attribute) abbrev_name;
+ cur_abbrev->attrs[cur_abbrev->num_attrs++].form
+ = (enum dwarf_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;
+}
+
+/* Returns true if the form is one which has a string value. */
+
+static inline bfd_boolean
+is_str_attr (enum dwarf_form form)
+{
+ return form == DW_FORM_string || form == DW_FORM_strp || form == DW_FORM_GNU_strp_alt;
+}
+
+/* Read an attribute value described by an attribute form. */
+
+static bfd_byte *
+read_attribute_value (struct attribute *attr,
+ unsigned form,
+ struct comp_unit *unit,
+ bfd_byte *info_ptr)
+{
+ bfd *abfd = unit->abfd;
+ unsigned int bytes_read;
+ struct dwarf_block *blk;
+ bfd_size_type amt;
+
+ attr->form = (enum dwarf_form) form;
+
+ switch (form)
+ {
+ case DW_FORM_ref_addr:
+ /* DW_FORM_ref_addr is an address in DWARF2, and an offset in
+ DWARF3. */
+ if (unit->version == 3 || unit->version == 4)
+ {
+ if (unit->offset_size == 4)
+ attr->u.val = read_4_bytes (unit->abfd, info_ptr);
+ else
+ attr->u.val = read_8_bytes (unit->abfd, info_ptr);
+ info_ptr += unit->offset_size;
+ break;
+ }
+ /* FALLTHROUGH */
+ case DW_FORM_addr:
+ attr->u.val = read_address (unit, info_ptr);
+ info_ptr += unit->addr_size;
+ break;
+ case DW_FORM_GNU_ref_alt:
+ case DW_FORM_sec_offset:
+ if (unit->offset_size == 4)
+ attr->u.val = read_4_bytes (unit->abfd, info_ptr);
+ else
+ attr->u.val = read_8_bytes (unit->abfd, info_ptr);
+ info_ptr += unit->offset_size;
+ break;
+ case DW_FORM_block2:
+ amt = sizeof (struct dwarf_block);
+ blk = (struct dwarf_block *) bfd_alloc (abfd, amt);
+ if (blk == NULL)
+ return NULL;
+ 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;
+ attr->u.blk = blk;
+ break;
+ case DW_FORM_block4:
+ amt = sizeof (struct dwarf_block);
+ blk = (struct dwarf_block *) bfd_alloc (abfd, amt);
+ if (blk == NULL)
+ return NULL;
+ 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;
+ attr->u.blk = blk;
+ break;
+ case DW_FORM_data2:
+ attr->u.val = read_2_bytes (abfd, info_ptr);
+ info_ptr += 2;
+ break;
+ case DW_FORM_data4:
+ attr->u.val = read_4_bytes (abfd, info_ptr);
+ info_ptr += 4;
+ break;
+ case DW_FORM_data8:
+ attr->u.val = read_8_bytes (abfd, info_ptr);
+ info_ptr += 8;
+ break;
+ case DW_FORM_string:
+ attr->u.str = read_string (abfd, info_ptr, &bytes_read);
+ info_ptr += bytes_read;
+ break;
+ case DW_FORM_strp:
+ attr->u.str = read_indirect_string (unit, info_ptr, &bytes_read);
+ info_ptr += bytes_read;
+ break;
+ case DW_FORM_GNU_strp_alt:
+ attr->u.str = read_alt_indirect_string (unit, info_ptr, &bytes_read);
+ info_ptr += bytes_read;
+ break;
+ case DW_FORM_exprloc:
+ case DW_FORM_block:
+ amt = sizeof (struct dwarf_block);
+ blk = (struct dwarf_block *) bfd_alloc (abfd, amt);
+ if (blk == NULL)
+ return NULL;
+ 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;
+ attr->u.blk = blk;
+ break;
+ case DW_FORM_block1:
+ amt = sizeof (struct dwarf_block);
+ blk = (struct dwarf_block *) bfd_alloc (abfd, amt);
+ if (blk == NULL)
+ return NULL;
+ 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;
+ attr->u.blk = blk;
+ break;
+ case DW_FORM_data1:
+ attr->u.val = read_1_byte (abfd, info_ptr);
+ info_ptr += 1;
+ break;
+ case DW_FORM_flag:
+ attr->u.val = read_1_byte (abfd, info_ptr);
+ info_ptr += 1;
+ break;
+ case DW_FORM_flag_present:
+ attr->u.val = 1;
+ break;
+ case DW_FORM_sdata:
+ attr->u.sval = read_signed_leb128 (abfd, info_ptr, &bytes_read);
+ info_ptr += bytes_read;
+ break;
+ case DW_FORM_udata:
+ attr->u.val = read_unsigned_leb128 (abfd, info_ptr, &bytes_read);
+ info_ptr += bytes_read;
+ break;
+ case DW_FORM_ref1:
+ attr->u.val = read_1_byte (abfd, info_ptr);
+ info_ptr += 1;
+ break;
+ case DW_FORM_ref2:
+ attr->u.val = read_2_bytes (abfd, info_ptr);
+ info_ptr += 2;
+ break;
+ case DW_FORM_ref4:
+ attr->u.val = read_4_bytes (abfd, info_ptr);
+ info_ptr += 4;
+ break;
+ case DW_FORM_ref8:
+ attr->u.val = read_8_bytes (abfd, info_ptr);
+ info_ptr += 8;
+ break;
+ case DW_FORM_ref_sig8:
+ attr->u.val = read_8_bytes (abfd, info_ptr);
+ info_ptr += 8;
+ break;
+ case DW_FORM_ref_udata:
+ attr->u.val = read_unsigned_leb128 (abfd, info_ptr, &bytes_read);
+ info_ptr += bytes_read;
+ break;
+ case DW_FORM_indirect:
+ form = read_unsigned_leb128 (abfd, info_ptr, &bytes_read);
+ info_ptr += bytes_read;
+ info_ptr = read_attribute_value (attr, form, unit, info_ptr);
+ break;
+ default:
+ (*_bfd_error_handler) (_("Dwarf Error: Invalid or unhandled FORM value: %#x."),
+ form);
+ bfd_set_error (bfd_error_bad_value);
+ return NULL;
+ }
+ return info_ptr;
+}
+
+/* Read an attribute described by an abbreviated attribute. */
+
+static bfd_byte *
+read_attribute (struct attribute *attr,
+ struct attr_abbrev *abbrev,
+ struct comp_unit *unit,
+ bfd_byte *info_ptr)
+{
+ attr->name = abbrev->name;
+ info_ptr = read_attribute_value (attr, abbrev->form, unit, info_ptr);
+ 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;
+ unsigned int discriminator;
+ unsigned char op_index;
+ unsigned char end_sequence; /* End of (sequential) code sequence. */
+};
+
+struct fileinfo
+{
+ char *name;
+ unsigned int dir;
+ unsigned int time;
+ unsigned int size;
+};
+
+struct line_sequence
+{
+ bfd_vma low_pc;
+ struct line_sequence* prev_sequence;
+ struct line_info* last_line; /* Largest VMA. */
+};
+
+struct line_info_table
+{
+ bfd* abfd;
+ unsigned int num_files;
+ unsigned int num_dirs;
+ unsigned int num_sequences;
+ char * comp_dir;
+ char ** dirs;
+ struct fileinfo* files;
+ struct line_sequence* sequences;
+ struct line_info* lcl_head; /* Local head; used in 'add_line_info'. */
+};
+
+/* Remember some information about each function. If the function is
+ inlined (DW_TAG_inlined_subroutine) it may have two additional
+ attributes, DW_AT_call_file and DW_AT_call_line, which specify the
+ source code location where this function was inlined. */
+
+struct funcinfo
+{
+ /* Pointer to previous function in list of all functions. */
+ struct funcinfo *prev_func;
+ /* Pointer to function one scope higher. */
+ struct funcinfo *caller_func;
+ /* Source location file name where caller_func inlines this func. */
+ char *caller_file;
+ /* Source location line number where caller_func inlines this func. */
+ int caller_line;
+ /* Source location file name. */
+ char *file;
+ /* Source location line number. */
+ int line;
+ int tag;
+ char *name;
+ struct arange arange;
+ /* Where the symbol is defined. */
+ asection *sec;
+};
+
+struct varinfo
+{
+ /* Pointer to previous variable in list of all variables */
+ struct varinfo *prev_var;
+ /* Source location file name */
+ char *file;
+ /* Source location line number */
+ int line;
+ int tag;
+ char *name;
+ bfd_vma addr;
+ /* Where the symbol is defined */
+ asection *sec;
+ /* Is this a stack variable? */
+ unsigned int stack: 1;
+};
+
+/* Return TRUE if NEW_LINE should sort after LINE. */
+
+static inline bfd_boolean
+new_line_sorts_after (struct line_info *new_line, struct line_info *line)
+{
+ return (new_line->address > line->address
+ || (new_line->address == line->address
+ && (new_line->op_index > line->op_index
+ || (new_line->op_index == line->op_index
+ && new_line->end_sequence < line->end_sequence))));
+}
+
+
+/* Adds a new entry to the line_info list in the line_info_table, ensuring
+ that the list is sorted. Note that the line_info list is sorted from
+ highest to lowest VMA (with possible duplicates); that is,
+ line_info->prev_line always accesses an equal or smaller VMA. */
+
+static bfd_boolean
+add_line_info (struct line_info_table *table,
+ bfd_vma address,
+ unsigned char op_index,
+ char *filename,
+ unsigned int line,
+ unsigned int column,
+ unsigned int discriminator,
+ int end_sequence)
+{
+ bfd_size_type amt = sizeof (struct line_info);
+ struct line_sequence* seq = table->sequences;
+ struct line_info* info = (struct line_info *) bfd_alloc (table->abfd, amt);
+
+ if (info == NULL)
+ return FALSE;
+
+ /* Set member data of 'info'. */
+ info->prev_line = NULL;
+ info->address = address;
+ info->op_index = op_index;
+ info->line = line;
+ info->column = column;
+ info->discriminator = discriminator;
+ info->end_sequence = end_sequence;
+
+ if (filename && filename[0])
+ {
+ info->filename = (char *) bfd_alloc (table->abfd, strlen (filename) + 1);
+ if (info->filename == NULL)
+ return FALSE;
+ strcpy (info->filename, filename);
+ }
+ else
+ info->filename = NULL;
+
+ /* Find the correct location for 'info'. Normally we will receive
+ new line_info data 1) in order and 2) with increasing VMAs.
+ However some compilers break the rules (cf. decode_line_info) and
+ so we include some heuristics for quickly finding the correct
+ location for 'info'. In particular, these heuristics optimize for
+ the common case in which the VMA sequence that we receive is a
+ list of locally sorted VMAs such as
+ p...z a...j (where a < j < p < z)
+
+ Note: table->lcl_head is used to head an *actual* or *possible*
+ sub-sequence within the list (such as a...j) that is not directly
+ headed by table->last_line
+
+ Note: we may receive duplicate entries from 'decode_line_info'. */
+
+ if (seq
+ && seq->last_line->address == address
+ && seq->last_line->op_index == op_index
+ && seq->last_line->end_sequence == end_sequence)
+ {
+ /* We only keep the last entry with the same address and end
+ sequence. See PR ld/4986. */
+ if (table->lcl_head == seq->last_line)
+ table->lcl_head = info;
+ info->prev_line = seq->last_line->prev_line;
+ seq->last_line = info;
+ }
+ else if (!seq || seq->last_line->end_sequence)
+ {
+ /* Start a new line sequence. */
+ amt = sizeof (struct line_sequence);
+ seq = (struct line_sequence *) bfd_malloc (amt);
+ if (seq == NULL)
+ return FALSE;
+ seq->low_pc = address;
+ seq->prev_sequence = table->sequences;
+ seq->last_line = info;
+ table->lcl_head = info;
+ table->sequences = seq;
+ table->num_sequences++;
+ }
+ else if (new_line_sorts_after (info, seq->last_line))
+ {
+ /* Normal case: add 'info' to the beginning of the current sequence. */
+ info->prev_line = seq->last_line;
+ seq->last_line = info;
+
+ /* lcl_head: initialize to head a *possible* sequence at the end. */
+ if (!table->lcl_head)
+ table->lcl_head = info;
+ }
+ else if (!new_line_sorts_after (info, table->lcl_head)
+ && (!table->lcl_head->prev_line
+ || new_line_sorts_after (info, table->lcl_head->prev_line)))
+ {
+ /* Abnormal but easy: lcl_head is the head of 'info'. */
+ info->prev_line = table->lcl_head->prev_line;
+ table->lcl_head->prev_line = info;
+ }
+ else
+ {
+ /* Abnormal and hard: Neither 'last_line' nor 'lcl_head'
+ are valid heads for 'info'. Reset 'lcl_head'. */
+ struct line_info* li2 = seq->last_line; /* Always non-NULL. */
+ struct line_info* li1 = li2->prev_line;
+
+ while (li1)
+ {
+ if (!new_line_sorts_after (info, li2)
+ && new_line_sorts_after (info, li1))
+ break;
+
+ li2 = li1; /* always non-NULL */
+ li1 = li1->prev_line;
+ }
+ table->lcl_head = li2;
+ info->prev_line = table->lcl_head->prev_line;
+ table->lcl_head->prev_line = info;
+ if (address < seq->low_pc)
+ seq->low_pc = address;
+ }
+ return TRUE;
+}
+
+/* Extract a fully qualified filename from a line info table.
+ The returned string has been malloc'ed and it is the caller's
+ responsibility to free it. */
+
+static char *
+concat_filename (struct line_info_table *table, unsigned int file)
+{
+ char *filename;
+
+ if (file - 1 >= table->num_files)
+ {
+ /* FILE == 0 means unknown. */
+ if (file)
+ (*_bfd_error_handler)
+ (_("Dwarf Error: mangled line number section (bad file number)."));
+ return strdup ("<unknown>");
+ }
+
+ filename = table->files[file - 1].name;
+
+ if (!IS_ABSOLUTE_PATH (filename))
+ {
+ char *dir_name = NULL;
+ char *subdir_name = NULL;
+ char *name;
+ size_t len;
+
+ if (table->files[file - 1].dir)
+ subdir_name = table->dirs[table->files[file - 1].dir - 1];
+
+ if (!subdir_name || !IS_ABSOLUTE_PATH (subdir_name))
+ dir_name = table->comp_dir;
+
+ if (!dir_name)
+ {
+ dir_name = subdir_name;
+ subdir_name = NULL;
+ }
+
+ if (!dir_name)
+ return strdup (filename);
+
+ len = strlen (dir_name) + strlen (filename) + 2;
+
+ if (subdir_name)
+ {
+ len += strlen (subdir_name) + 1;
+ name = (char *) bfd_malloc (len);
+ if (name)
+ sprintf (name, "%s/%s/%s", dir_name, subdir_name, filename);
+ }
+ else
+ {
+ name = (char *) bfd_malloc (len);
+ if (name)
+ sprintf (name, "%s/%s", dir_name, filename);
+ }
+
+ return name;
+ }
+
+ return strdup (filename);
+}
+
+static bfd_boolean
+arange_add (const struct comp_unit *unit, struct arange *first_arange,
+ bfd_vma low_pc, bfd_vma high_pc)
+{
+ struct arange *arange;
+
+ /* Ignore empty ranges. */
+ if (low_pc == high_pc)
+ return TRUE;
+
+ /* If the first arange is empty, use it. */
+ if (first_arange->high == 0)
+ {
+ first_arange->low = low_pc;
+ first_arange->high = high_pc;
+ return TRUE;
+ }
+
+ /* Next see if we can cheaply extend an existing range. */
+ arange = first_arange;
+ do
+ {
+ if (low_pc == arange->high)
+ {
+ arange->high = high_pc;
+ return TRUE;
+ }
+ if (high_pc == arange->low)
+ {
+ arange->low = low_pc;
+ return TRUE;
+ }
+ arange = arange->next;
+ }
+ while (arange);
+
+ /* Need to allocate a new arange and insert it into the arange list.
+ Order isn't significant, so just insert after the first arange. */
+ arange = (struct arange *) bfd_alloc (unit->abfd, sizeof (*arange));
+ if (arange == NULL)
+ return FALSE;
+ arange->low = low_pc;
+ arange->high = high_pc;
+ arange->next = first_arange->next;
+ first_arange->next = arange;
+ return TRUE;
+}
+
+/* Compare function for line sequences. */
+
+static int
+compare_sequences (const void* a, const void* b)
+{
+ const struct line_sequence* seq1 = a;
+ const struct line_sequence* seq2 = b;
+
+ /* Sort by low_pc as the primary key. */
+ if (seq1->low_pc < seq2->low_pc)
+ return -1;
+ if (seq1->low_pc > seq2->low_pc)
+ return 1;
+
+ /* If low_pc values are equal, sort in reverse order of
+ high_pc, so that the largest region comes first. */
+ if (seq1->last_line->address < seq2->last_line->address)
+ return 1;
+ if (seq1->last_line->address > seq2->last_line->address)
+ return -1;
+
+ if (seq1->last_line->op_index < seq2->last_line->op_index)
+ return 1;
+ if (seq1->last_line->op_index > seq2->last_line->op_index)
+ return -1;
+
+ return 0;
+}
+
+/* Sort the line sequences for quick lookup. */
+
+static bfd_boolean
+sort_line_sequences (struct line_info_table* table)
+{
+ bfd_size_type amt;
+ struct line_sequence* sequences;
+ struct line_sequence* seq;
+ unsigned int n = 0;
+ unsigned int num_sequences = table->num_sequences;
+ bfd_vma last_high_pc;
+
+ if (num_sequences == 0)
+ return TRUE;
+
+ /* Allocate space for an array of sequences. */
+ amt = sizeof (struct line_sequence) * num_sequences;
+ sequences = (struct line_sequence *) bfd_alloc (table->abfd, amt);
+ if (sequences == NULL)
+ return FALSE;
+
+ /* Copy the linked list into the array, freeing the original nodes. */
+ seq = table->sequences;
+ for (n = 0; n < num_sequences; n++)
+ {
+ struct line_sequence* last_seq = seq;
+
+ BFD_ASSERT (seq);
+ sequences[n].low_pc = seq->low_pc;
+ sequences[n].prev_sequence = NULL;
+ sequences[n].last_line = seq->last_line;
+ seq = seq->prev_sequence;
+ free (last_seq);
+ }
+ BFD_ASSERT (seq == NULL);
+
+ qsort (sequences, n, sizeof (struct line_sequence), compare_sequences);
+
+ /* Make the list binary-searchable by trimming overlapping entries
+ and removing nested entries. */
+ num_sequences = 1;
+ last_high_pc = sequences[0].last_line->address;
+ for (n = 1; n < table->num_sequences; n++)
+ {
+ if (sequences[n].low_pc < last_high_pc)
+ {
+ if (sequences[n].last_line->address <= last_high_pc)
+ /* Skip nested entries. */
+ continue;
+
+ /* Trim overlapping entries. */
+ sequences[n].low_pc = last_high_pc;
+ }
+ last_high_pc = sequences[n].last_line->address;
+ if (n > num_sequences)
+ {
+ /* Close up the gap. */
+ sequences[num_sequences].low_pc = sequences[n].low_pc;
+ sequences[num_sequences].last_line = sequences[n].last_line;
+ }
+ num_sequences++;
+ }
+
+ table->sequences = sequences;
+ table->num_sequences = num_sequences;
+ return TRUE;
+}
+
+/* Decode the line number information for UNIT. */
+
+static struct line_info_table*
+decode_line_info (struct comp_unit *unit, struct dwarf2_debug *stash)
+{
+ bfd *abfd = unit->abfd;
+ struct line_info_table* table;
+ bfd_byte *line_ptr;
+ bfd_byte *line_end;
+ struct line_head lh;
+ unsigned int i, bytes_read, offset_size;
+ char *cur_file, *cur_dir;
+ unsigned char op_code, extended_op, adj_opcode;
+ unsigned int exop_len;
+ bfd_size_type amt;
+
+ if (! read_section (abfd, &stash->debug_sections[debug_line],
+ stash->syms, unit->line_offset,
+ &stash->dwarf_line_buffer, &stash->dwarf_line_size))
+ return NULL;
+
+ amt = sizeof (struct line_info_table);
+ table = (struct line_info_table *) bfd_alloc (abfd, amt);
+ if (table == NULL)
+ return NULL;
+ table->abfd = abfd;
+ table->comp_dir = unit->comp_dir;
+
+ table->num_files = 0;
+ table->files = NULL;
+
+ table->num_dirs = 0;
+ table->dirs = NULL;
+
+ table->num_sequences = 0;
+ table->sequences = NULL;
+
+ table->lcl_head = NULL;
+
+ line_ptr = stash->dwarf_line_buffer + unit->line_offset;
+
+ /* Read in the prologue. */
+ lh.total_length = read_4_bytes (abfd, line_ptr);
+ line_ptr += 4;
+ offset_size = 4;
+ if (lh.total_length == 0xffffffff)
+ {
+ lh.total_length = read_8_bytes (abfd, line_ptr);
+ line_ptr += 8;
+ offset_size = 8;
+ }
+ else if (lh.total_length == 0 && unit->addr_size == 8)
+ {
+ /* Handle (non-standard) 64-bit DWARF2 formats. */
+ lh.total_length = read_4_bytes (abfd, line_ptr);
+ line_ptr += 4;
+ offset_size = 8;
+ }
+ line_end = line_ptr + lh.total_length;
+ lh.version = read_2_bytes (abfd, line_ptr);
+ if (lh.version < 2 || lh.version > 4)
+ {
+ (*_bfd_error_handler)
+ (_("Dwarf Error: Unhandled .debug_line version %d."), lh.version);
+ bfd_set_error (bfd_error_bad_value);
+ return NULL;
+ }
+ line_ptr += 2;
+ if (offset_size == 4)
+ lh.prologue_length = read_4_bytes (abfd, line_ptr);
+ else
+ lh.prologue_length = read_8_bytes (abfd, line_ptr);
+ line_ptr += offset_size;
+ lh.minimum_instruction_length = read_1_byte (abfd, line_ptr);
+ line_ptr += 1;
+ if (lh.version >= 4)
+ {
+ lh.maximum_ops_per_insn = read_1_byte (abfd, line_ptr);
+ line_ptr += 1;
+ }
+ else
+ lh.maximum_ops_per_insn = 1;
+ if (lh.maximum_ops_per_insn == 0)
+ {
+ (*_bfd_error_handler)
+ (_("Dwarf Error: Invalid maximum operations per instruction."));
+ bfd_set_error (bfd_error_bad_value);
+ return NULL;
+ }
+ 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;
+ amt = lh.opcode_base * sizeof (unsigned char);
+ lh.standard_opcode_lengths = (unsigned char *) bfd_alloc (abfd, amt);
+
+ 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)
+ {
+ char **tmp;
+
+ amt = table->num_dirs + DIR_ALLOC_CHUNK;
+ amt *= sizeof (char *);
+
+ tmp = (char **) bfd_realloc (table->dirs, amt);
+ if (tmp == NULL)
+ goto fail;
+ table->dirs = tmp;
+ }
+
+ 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)
+ {
+ struct fileinfo *tmp;
+
+ amt = table->num_files + FILE_ALLOC_CHUNK;
+ amt *= sizeof (struct fileinfo);
+
+ tmp = (struct fileinfo *) bfd_realloc (table->files, amt);
+ if (tmp == NULL)
+ goto fail;
+ table->files = tmp;
+ }
+
+ 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;
+ unsigned char op_index = 0;
+ char * filename = table->num_files ? concat_filename (table, 1) : NULL;
+ unsigned int line = 1;
+ unsigned int column = 0;
+ unsigned int discriminator = 0;
+ int is_stmt = lh.default_is_stmt;
+ int end_sequence = 0;
+ /* eraxxon@alumni.rice.edu: Against the DWARF2 specs, some
+ compilers generate address sequences that are wildly out of
+ order using DW_LNE_set_address (e.g. Intel C++ 6.0 compiler
+ for ia64-Linux). Thus, to determine the low and high
+ address, we must compare on every DW_LNS_copy, etc. */
+ bfd_vma low_pc = (bfd_vma) -1;
+ bfd_vma high_pc = 0;
+
+ /* Decode the table. */
+ while (! end_sequence)
+ {
+ op_code = read_1_byte (abfd, line_ptr);
+ line_ptr += 1;
+
+ if (op_code >= lh.opcode_base)
+ {
+ /* Special operand. */
+ adj_opcode = op_code - lh.opcode_base;
+ if (lh.maximum_ops_per_insn == 1)
+ address += (adj_opcode / lh.line_range
+ * lh.minimum_instruction_length);
+ else
+ {
+ address += ((op_index + adj_opcode / lh.line_range)
+ / lh.maximum_ops_per_insn
+ * lh.minimum_instruction_length);
+ op_index = ((op_index + adj_opcode / lh.line_range)
+ % lh.maximum_ops_per_insn);
+ }
+ line += lh.line_base + (adj_opcode % lh.line_range);
+ /* Append row to matrix using current values. */
+ if (!add_line_info (table, address, op_index, filename,
+ line, column, discriminator, 0))
+ goto line_fail;
+ discriminator = 0;
+ if (address < low_pc)
+ low_pc = address;
+ if (address > high_pc)
+ high_pc = address;
+ }
+ else switch (op_code)
+ {
+ case DW_LNS_extended_op:
+ exop_len = read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
+ line_ptr += bytes_read;
+ extended_op = read_1_byte (abfd, line_ptr);
+ line_ptr += 1;
+
+ switch (extended_op)
+ {
+ case DW_LNE_end_sequence:
+ end_sequence = 1;
+ if (!add_line_info (table, address, op_index, filename, line,
+ column, discriminator, end_sequence))
+ goto line_fail;
+ discriminator = 0;
+ if (address < low_pc)
+ low_pc = address;
+ if (address > high_pc)
+ high_pc = address;
+ if (!arange_add (unit, &unit->arange, low_pc, high_pc))
+ goto line_fail;
+ break;
+ case DW_LNE_set_address:
+ address = read_address (unit, line_ptr);
+ op_index = 0;
+ 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)
+ {
+ struct fileinfo *tmp;
+
+ amt = table->num_files + FILE_ALLOC_CHUNK;
+ amt *= sizeof (struct fileinfo);
+ tmp = (struct fileinfo *) bfd_realloc (table->files, amt);
+ if (tmp == NULL)
+ goto line_fail;
+ table->files = tmp;
+ }
+ 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;
+ case DW_LNE_set_discriminator:
+ discriminator =
+ read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
+ line_ptr += bytes_read;
+ break;
+ case DW_LNE_HP_source_file_correlation:
+ line_ptr += exop_len - 1;
+ break;
+ default:
+ (*_bfd_error_handler)
+ (_("Dwarf Error: mangled line number section."));
+ bfd_set_error (bfd_error_bad_value);
+ line_fail:
+ if (filename != NULL)
+ free (filename);
+ goto fail;
+ }
+ break;
+ case DW_LNS_copy:
+ if (!add_line_info (table, address, op_index,
+ filename, line, column, discriminator, 0))
+ goto line_fail;
+ discriminator = 0;
+ if (address < low_pc)
+ low_pc = address;
+ if (address > high_pc)
+ high_pc = address;
+ break;
+ case DW_LNS_advance_pc:
+ if (lh.maximum_ops_per_insn == 1)
+ address += (lh.minimum_instruction_length
+ * read_unsigned_leb128 (abfd, line_ptr,
+ &bytes_read));
+ else
+ {
+ bfd_vma adjust = read_unsigned_leb128 (abfd, line_ptr,
+ &bytes_read);
+ address = ((op_index + adjust) / lh.maximum_ops_per_insn
+ * lh.minimum_instruction_length);
+ op_index = (op_index + adjust) % lh.maximum_ops_per_insn;
+ }
+ 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;
+ if (filename)
+ free (filename);
+ 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:
+ break;
+ case DW_LNS_const_add_pc:
+ if (lh.maximum_ops_per_insn == 1)
+ address += (lh.minimum_instruction_length
+ * ((255 - lh.opcode_base) / lh.line_range));
+ else
+ {
+ bfd_vma adjust = ((255 - lh.opcode_base) / lh.line_range);
+ address += (lh.minimum_instruction_length
+ * ((op_index + adjust)
+ / lh.maximum_ops_per_insn));
+ op_index = (op_index + adjust) % lh.maximum_ops_per_insn;
+ }
+ break;
+ case DW_LNS_fixed_advance_pc:
+ address += read_2_bytes (abfd, line_ptr);
+ op_index = 0;
+ line_ptr += 2;
+ break;
+ default:
+ /* Unknown standard opcode, ignore it. */
+ for (i = 0; i < lh.standard_opcode_lengths[op_code]; i++)
+ {
+ (void) read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
+ line_ptr += bytes_read;
+ }
+ break;
+ }
+ }
+
+ if (filename)
+ free (filename);
+ }
+
+ if (sort_line_sequences (table))
+ return table;
+
+ fail:
+ if (table->sequences != NULL)
+ free (table->sequences);
+ if (table->files != NULL)
+ free (table->files);
+ if (table->dirs != NULL)
+ free (table->dirs);
+ return NULL;
+}
+
+/* If ADDR is within TABLE set the output parameters and return the
+ range of addresses covered by the entry used to fill them out.
+ Otherwise set * FILENAME_PTR to NULL and return 0.
+ The parameters FILENAME_PTR, LINENUMBER_PTR and DISCRIMINATOR_PTR
+ are pointers to the objects to be filled in. */
+
+static bfd_vma
+lookup_address_in_line_info_table (struct line_info_table *table,
+ bfd_vma addr,
+ const char **filename_ptr,
+ unsigned int *linenumber_ptr,
+ unsigned int *discriminator_ptr)
+{
+ struct line_sequence *seq = NULL;
+ struct line_info *each_line;
+ int low, high, mid;
+
+ /* Binary search the array of sequences. */
+ low = 0;
+ high = table->num_sequences;
+ while (low < high)
+ {
+ mid = (low + high) / 2;
+ seq = &table->sequences[mid];
+ if (addr < seq->low_pc)
+ high = mid;
+ else if (addr >= seq->last_line->address)
+ low = mid + 1;
+ else
+ break;
+ }
+
+ if (seq && addr >= seq->low_pc && addr < seq->last_line->address)
+ {
+ /* Note: seq->last_line should be a descendingly sorted list. */
+ for (each_line = seq->last_line;
+ each_line;
+ each_line = each_line->prev_line)
+ if (addr >= each_line->address)
+ break;
+
+ if (each_line
+ && !(each_line->end_sequence || each_line == seq->last_line))
+ {
+ *filename_ptr = each_line->filename;
+ *linenumber_ptr = each_line->line;
+ if (discriminator_ptr)
+ *discriminator_ptr = each_line->discriminator;
+ return seq->last_line->address - seq->low_pc;
+ }
+ }
+
+ *filename_ptr = NULL;
+ return 0;
+}
+
+/* Read in the .debug_ranges section for future reference. */
+
+static bfd_boolean
+read_debug_ranges (struct comp_unit *unit)
+{
+ struct dwarf2_debug *stash = unit->stash;
+ return read_section (unit->abfd, &stash->debug_sections[debug_ranges],
+ stash->syms, 0,
+ &stash->dwarf_ranges_buffer, &stash->dwarf_ranges_size);
+}
+
+/* Function table functions. */
+
+/* If ADDR is within UNIT's function tables, set FUNCTIONNAME_PTR, and return
+ TRUE. Note that we need to find the function that has the smallest range
+ that contains ADDR, to handle inlined functions without depending upon
+ them being ordered in TABLE by increasing range. */
+
+static bfd_boolean
+lookup_address_in_function_table (struct comp_unit *unit,
+ bfd_vma addr,
+ struct funcinfo **function_ptr,
+ const char **functionname_ptr)
+{
+ struct funcinfo* each_func;
+ struct funcinfo* best_fit = NULL;
+ bfd_vma best_fit_len = 0;
+ struct arange *arange;
+
+ for (each_func = unit->function_table;
+ each_func;
+ each_func = each_func->prev_func)
+ {
+ for (arange = &each_func->arange;
+ arange;
+ arange = arange->next)
+ {
+ if (addr >= arange->low && addr < arange->high)
+ {
+ if (!best_fit
+ || arange->high - arange->low < best_fit_len)
+ {
+ best_fit = each_func;
+ best_fit_len = arange->high - arange->low;
+ }
+ }
+ }
+ }
+
+ if (best_fit)
+ {
+ *functionname_ptr = best_fit->name;
+ *function_ptr = best_fit;
+ return TRUE;
+ }
+ else
+ {
+ return FALSE;
+ }
+}
+
+/* If SYM at ADDR is within function table of UNIT, set FILENAME_PTR
+ and LINENUMBER_PTR, and return TRUE. */
+
+static bfd_boolean
+lookup_symbol_in_function_table (struct comp_unit *unit,
+ asymbol *sym,
+ bfd_vma addr,
+ const char **filename_ptr,
+ unsigned int *linenumber_ptr)
+{
+ struct funcinfo* each_func;
+ struct funcinfo* best_fit = NULL;
+ bfd_vma best_fit_len = 0;
+ struct arange *arange;
+ const char *name = bfd_asymbol_name (sym);
+ asection *sec = bfd_get_section (sym);
+
+ for (each_func = unit->function_table;
+ each_func;
+ each_func = each_func->prev_func)
+ {
+ for (arange = &each_func->arange;
+ arange;
+ arange = arange->next)
+ {
+ if ((!each_func->sec || each_func->sec == sec)
+ && addr >= arange->low
+ && addr < arange->high
+ && each_func->name
+ && strcmp (name, each_func->name) == 0
+ && (!best_fit
+ || arange->high - arange->low < best_fit_len))
+ {
+ best_fit = each_func;
+ best_fit_len = arange->high - arange->low;
+ }
+ }
+ }
+
+ if (best_fit)
+ {
+ best_fit->sec = sec;
+ *filename_ptr = best_fit->file;
+ *linenumber_ptr = best_fit->line;
+ return TRUE;
+ }
+ else
+ return FALSE;
+}
+
+/* Variable table functions. */
+
+/* If SYM is within variable table of UNIT, set FILENAME_PTR and
+ LINENUMBER_PTR, and return TRUE. */
+
+static bfd_boolean
+lookup_symbol_in_variable_table (struct comp_unit *unit,
+ asymbol *sym,
+ bfd_vma addr,
+ const char **filename_ptr,
+ unsigned int *linenumber_ptr)
+{
+ const char *name = bfd_asymbol_name (sym);
+ asection *sec = bfd_get_section (sym);
+ struct varinfo* each;
+
+ for (each = unit->variable_table; each; each = each->prev_var)
+ if (each->stack == 0
+ && each->file != NULL
+ && each->name != NULL
+ && each->addr == addr
+ && (!each->sec || each->sec == sec)
+ && strcmp (name, each->name) == 0)
+ break;
+
+ if (each)
+ {
+ each->sec = sec;
+ *filename_ptr = each->file;
+ *linenumber_ptr = each->line;
+ return TRUE;
+ }
+ else
+ return FALSE;
+}
+
+static char *
+find_abstract_instance_name (struct comp_unit *unit,
+ struct attribute *attr_ptr)
+{
+ bfd *abfd = unit->abfd;
+ bfd_byte *info_ptr;
+ unsigned int abbrev_number, bytes_read, i;
+ struct abbrev_info *abbrev;
+ bfd_uint64_t die_ref = attr_ptr->u.val;
+ struct attribute attr;
+ char *name = NULL;
+
+ /* DW_FORM_ref_addr can reference an entry in a different CU. It
+ is an offset from the .debug_info section, not the current CU. */
+ if (attr_ptr->form == DW_FORM_ref_addr)
+ {
+ /* We only support DW_FORM_ref_addr within the same file, so
+ any relocations should be resolved already. */
+ if (!die_ref)
+ abort ();
+
+ info_ptr = unit->sec_info_ptr + die_ref;
+
+ /* Now find the CU containing this pointer. */
+ if (info_ptr >= unit->info_ptr_unit && info_ptr < unit->end_ptr)
+ ;
+ else
+ {
+ /* Check other CUs to see if they contain the abbrev. */
+ struct comp_unit * u;
+
+ for (u = unit->prev_unit; u != NULL; u = u->prev_unit)
+ if (info_ptr >= u->info_ptr_unit && info_ptr < u->end_ptr)
+ break;
+
+ if (u == NULL)
+ for (u = unit->next_unit; u != NULL; u = u->next_unit)
+ if (info_ptr >= u->info_ptr_unit && info_ptr < u->end_ptr)
+ break;
+
+ if (u)
+ unit = u;
+ /* else FIXME: What do we do now ? */
+ }
+ }
+ else if (attr_ptr->form == DW_FORM_GNU_ref_alt)
+ {
+ info_ptr = read_alt_indirect_ref (unit, die_ref);
+ if (info_ptr == NULL)
+ {
+ (*_bfd_error_handler)
+ (_("Dwarf Error: Unable to read alt ref %u."), die_ref);
+ bfd_set_error (bfd_error_bad_value);
+ return name;
+ }
+ /* FIXME: Do we need to locate the correct CU, in a similar
+ fashion to the code in the DW_FORM_ref_addr case above ? */
+ }
+ else
+ info_ptr = unit->info_ptr_unit + die_ref;
+
+ abbrev_number = read_unsigned_leb128 (abfd, info_ptr, &bytes_read);
+ info_ptr += bytes_read;
+
+ if (abbrev_number)
+ {
+ abbrev = lookup_abbrev (abbrev_number, unit->abbrevs);
+ if (! abbrev)
+ {
+ (*_bfd_error_handler)
+ (_("Dwarf Error: Could not find abbrev number %u."), abbrev_number);
+ bfd_set_error (bfd_error_bad_value);
+ }
+ else
+ {
+ for (i = 0; i < abbrev->num_attrs; ++i)
+ {
+ info_ptr = read_attribute (&attr, &abbrev->attrs[i], unit,
+ info_ptr);
+ if (info_ptr == NULL)
+ break;
+ switch (attr.name)
+ {
+ case DW_AT_name:
+ /* Prefer DW_AT_MIPS_linkage_name or DW_AT_linkage_name
+ over DW_AT_name. */
+ if (name == NULL && is_str_attr (attr.form))
+ name = attr.u.str;
+ break;
+ case DW_AT_specification:
+ name = find_abstract_instance_name (unit, &attr);
+ break;
+ case DW_AT_linkage_name:
+ case DW_AT_MIPS_linkage_name:
+ /* PR 16949: Corrupt debug info can place
+ non-string forms into these attributes. */
+ if (is_str_attr (attr.form))
+ name = attr.u.str;
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ }
+ return name;
+}
+
+static bfd_boolean
+read_rangelist (struct comp_unit *unit, struct arange *arange,
+ bfd_uint64_t offset)
+{
+ bfd_byte *ranges_ptr;
+ bfd_vma base_address = unit->base_address;
+
+ if (! unit->stash->dwarf_ranges_buffer)
+ {
+ if (! read_debug_ranges (unit))
+ return FALSE;
+ }
+ ranges_ptr = unit->stash->dwarf_ranges_buffer + offset;
+
+ for (;;)
+ {
+ bfd_vma low_pc;
+ bfd_vma high_pc;
+
+ low_pc = read_address (unit, ranges_ptr);
+ ranges_ptr += unit->addr_size;
+ high_pc = read_address (unit, ranges_ptr);
+ ranges_ptr += unit->addr_size;
+
+ if (low_pc == 0 && high_pc == 0)
+ break;
+ if (low_pc == -1UL && high_pc != -1UL)
+ base_address = high_pc;
+ else
+ {
+ if (!arange_add (unit, arange,
+ base_address + low_pc, base_address + high_pc))
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+/* DWARF2 Compilation unit functions. */
+
+/* Scan over each die in a comp. unit looking for functions to add
+ to the function table and variables to the variable table. */
+
+static bfd_boolean
+scan_unit_for_symbols (struct comp_unit *unit)
+{
+ bfd *abfd = unit->abfd;
+ bfd_byte *info_ptr = unit->first_child_die_ptr;
+ int nesting_level = 1;
+ struct funcinfo **nested_funcs;
+ int nested_funcs_size;
+
+ /* Maintain a stack of in-scope functions and inlined functions, which we
+ can use to set the caller_func field. */
+ nested_funcs_size = 32;
+ nested_funcs = (struct funcinfo **)
+ bfd_malloc (nested_funcs_size * sizeof (struct funcinfo *));
+ if (nested_funcs == NULL)
+ return FALSE;
+ nested_funcs[nesting_level] = 0;
+
+ while (nesting_level)
+ {
+ unsigned int abbrev_number, bytes_read, i;
+ struct abbrev_info *abbrev;
+ struct attribute attr;
+ struct funcinfo *func;
+ struct varinfo *var;
+ bfd_vma low_pc = 0;
+ bfd_vma high_pc = 0;
+ bfd_boolean high_pc_relative = FALSE;
+
+ 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 %u."),
+ abbrev_number);
+ bfd_set_error (bfd_error_bad_value);
+ goto fail;
+ }
+
+ var = NULL;
+ if (abbrev->tag == DW_TAG_subprogram
+ || abbrev->tag == DW_TAG_entry_point
+ || abbrev->tag == DW_TAG_inlined_subroutine)
+ {
+ bfd_size_type amt = sizeof (struct funcinfo);
+ func = (struct funcinfo *) bfd_zalloc (abfd, amt);
+ if (func == NULL)
+ goto fail;
+ func->tag = abbrev->tag;
+ func->prev_func = unit->function_table;
+ unit->function_table = func;
+ BFD_ASSERT (!unit->cached);
+
+ if (func->tag == DW_TAG_inlined_subroutine)
+ for (i = nesting_level - 1; i >= 1; i--)
+ if (nested_funcs[i])
+ {
+ func->caller_func = nested_funcs[i];
+ break;
+ }
+ nested_funcs[nesting_level] = func;
+ }
+ else
+ {
+ func = NULL;
+ if (abbrev->tag == DW_TAG_variable)
+ {
+ bfd_size_type amt = sizeof (struct varinfo);
+ var = (struct varinfo *) bfd_zalloc (abfd, amt);
+ if (var == NULL)
+ goto fail;
+ var->tag = abbrev->tag;
+ var->stack = 1;
+ var->prev_var = unit->variable_table;
+ unit->variable_table = var;
+ BFD_ASSERT (!unit->cached);
+ }
+
+ /* No inline function in scope at this nesting level. */
+ nested_funcs[nesting_level] = 0;
+ }
+
+ for (i = 0; i < abbrev->num_attrs; ++i)
+ {
+ info_ptr = read_attribute (&attr, &abbrev->attrs[i], unit, info_ptr);
+ if (info_ptr == NULL)
+ goto fail;
+
+ if (func)
+ {
+ switch (attr.name)
+ {
+ case DW_AT_call_file:
+ func->caller_file = concat_filename (unit->line_table,
+ attr.u.val);
+ break;
+
+ case DW_AT_call_line:
+ func->caller_line = attr.u.val;
+ break;
+
+ case DW_AT_abstract_origin:
+ case DW_AT_specification:
+ func->name = find_abstract_instance_name (unit, &attr);
+ break;
+
+ case DW_AT_name:
+ /* Prefer DW_AT_MIPS_linkage_name or DW_AT_linkage_name
+ over DW_AT_name. */
+ if (func->name == NULL && is_str_attr (attr.form))
+ func->name = attr.u.str;
+ break;
+
+ case DW_AT_linkage_name:
+ case DW_AT_MIPS_linkage_name:
+ /* PR 16949: Corrupt debug info can place
+ non-string forms into these attributes. */
+ if (is_str_attr (attr.form))
+ func->name = attr.u.str;
+ break;
+
+ case DW_AT_low_pc:
+ low_pc = attr.u.val;
+ break;
+
+ case DW_AT_high_pc:
+ high_pc = attr.u.val;
+ high_pc_relative = attr.form != DW_FORM_addr;
+ break;
+
+ case DW_AT_ranges:
+ if (!read_rangelist (unit, &func->arange, attr.u.val))
+ goto fail;
+ break;
+
+ case DW_AT_decl_file:
+ func->file = concat_filename (unit->line_table,
+ attr.u.val);
+ break;
+
+ case DW_AT_decl_line:
+ func->line = attr.u.val;
+ break;
+
+ default:
+ break;
+ }
+ }
+ else if (var)
+ {
+ switch (attr.name)
+ {
+ case DW_AT_name:
+ var->name = attr.u.str;
+ break;
+
+ case DW_AT_decl_file:
+ var->file = concat_filename (unit->line_table,
+ attr.u.val);
+ break;
+
+ case DW_AT_decl_line:
+ var->line = attr.u.val;
+ break;
+
+ case DW_AT_external:
+ if (attr.u.val != 0)
+ var->stack = 0;
+ break;
+
+ case DW_AT_location:
+ switch (attr.form)
+ {
+ case DW_FORM_block:
+ case DW_FORM_block1:
+ case DW_FORM_block2:
+ case DW_FORM_block4:
+ case DW_FORM_exprloc:
+ if (*attr.u.blk->data == DW_OP_addr)
+ {
+ var->stack = 0;
+
+ /* Verify that DW_OP_addr is the only opcode in the
+ location, in which case the block size will be 1
+ plus the address size. */
+ /* ??? For TLS variables, gcc can emit
+ DW_OP_addr <addr> DW_OP_GNU_push_tls_address
+ which we don't handle here yet. */
+ if (attr.u.blk->size == unit->addr_size + 1U)
+ var->addr = bfd_get (unit->addr_size * 8,
+ unit->abfd,
+ attr.u.blk->data + 1);
+ }
+ break;
+
+ default:
+ break;
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ }
+
+ if (high_pc_relative)
+ high_pc += low_pc;
+
+ if (func && high_pc != 0)
+ {
+ if (!arange_add (unit, &func->arange, low_pc, high_pc))
+ goto fail;
+ }
+
+ if (abbrev->has_children)
+ {
+ nesting_level++;
+
+ if (nesting_level >= nested_funcs_size)
+ {
+ struct funcinfo **tmp;
+
+ nested_funcs_size *= 2;
+ tmp = (struct funcinfo **)
+ bfd_realloc (nested_funcs,
+ nested_funcs_size * sizeof (struct funcinfo *));
+ if (tmp == NULL)
+ goto fail;
+ nested_funcs = tmp;
+ }
+ nested_funcs[nesting_level] = 0;
+ }
+ }
+
+ free (nested_funcs);
+ return TRUE;
+
+ fail:
+ free (nested_funcs);
+ return FALSE;
+}
+
+/* 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 precedes each compilation
+ unit header. END_PTR points one past the end of this comp unit.
+ OFFSET_SIZE is the size of DWARF2 offsets (either 4 or 8 bytes).
+
+ 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 (struct dwarf2_debug *stash,
+ bfd_vma unit_length,
+ bfd_byte *info_ptr_unit,
+ unsigned int offset_size)
+{
+ struct comp_unit* unit;
+ unsigned int version;
+ bfd_uint64_t abbrev_offset = 0;
+ unsigned int addr_size;
+ struct abbrev_info** abbrevs;
+ unsigned int abbrev_number, bytes_read, i;
+ struct abbrev_info *abbrev;
+ struct attribute attr;
+ bfd_byte *info_ptr = stash->info_ptr;
+ bfd_byte *end_ptr = info_ptr + unit_length;
+ bfd_size_type amt;
+ bfd_vma low_pc = 0;
+ bfd_vma high_pc = 0;
+ bfd *abfd = stash->bfd_ptr;
+ bfd_boolean high_pc_relative = FALSE;
+
+ version = read_2_bytes (abfd, info_ptr);
+ info_ptr += 2;
+ BFD_ASSERT (offset_size == 4 || offset_size == 8);
+ if (offset_size == 4)
+ abbrev_offset = read_4_bytes (abfd, info_ptr);
+ else
+ abbrev_offset = read_8_bytes (abfd, info_ptr);
+ info_ptr += offset_size;
+ addr_size = read_1_byte (abfd, info_ptr);
+ info_ptr += 1;
+
+ if (version != 2 && version != 3 && version != 4)
+ {
+ (*_bfd_error_handler)
+ (_("Dwarf Error: found dwarf version '%u', this reader"
+ " only handles version 2, 3 and 4 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,
+ (unsigned int) sizeof (bfd_vma));
+ bfd_set_error (bfd_error_bad_value);
+ return 0;
+ }
+
+ if (addr_size != 2 && addr_size != 4 && addr_size != 8)
+ {
+ (*_bfd_error_handler)
+ ("Dwarf Error: found address size '%u', this reader"
+ " can only handle address sizes '2', '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, stash);
+ 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: %u."),
+ 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 %u."),
+ abbrev_number);
+ bfd_set_error (bfd_error_bad_value);
+ return 0;
+ }
+
+ amt = sizeof (struct comp_unit);
+ unit = (struct comp_unit *) bfd_zalloc (abfd, amt);
+ if (unit == NULL)
+ return NULL;
+ unit->abfd = abfd;
+ unit->version = version;
+ unit->addr_size = addr_size;
+ unit->offset_size = offset_size;
+ unit->abbrevs = abbrevs;
+ unit->end_ptr = end_ptr;
+ unit->stash = stash;
+ unit->info_ptr_unit = info_ptr_unit;
+ unit->sec_info_ptr = stash->sec_info_ptr;
+
+ for (i = 0; i < abbrev->num_attrs; ++i)
+ {
+ info_ptr = read_attribute (&attr, &abbrev->attrs[i], unit, info_ptr);
+ if (info_ptr == NULL)
+ return NULL;
+
+ /* 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 = attr.u.val;
+ break;
+
+ case DW_AT_name:
+ unit->name = attr.u.str;
+ break;
+
+ case DW_AT_low_pc:
+ low_pc = attr.u.val;
+ /* If the compilation unit DIE has a DW_AT_low_pc attribute,
+ this is the base address to use when reading location
+ lists or range lists. */
+ if (abbrev->tag == DW_TAG_compile_unit)
+ unit->base_address = low_pc;
+ break;
+
+ case DW_AT_high_pc:
+ high_pc = attr.u.val;
+ high_pc_relative = attr.form != DW_FORM_addr;
+ break;
+
+ case DW_AT_ranges:
+ if (!read_rangelist (unit, &unit->arange, attr.u.val))
+ return NULL;
+ break;
+
+ case DW_AT_comp_dir:
+ {
+ char *comp_dir = attr.u.str;
+ if (comp_dir)
+ {
+ /* Irix 6.2 native cc prepends <machine>.: to the compilation
+ directory, get rid of it. */
+ char *cp = strchr (comp_dir, ':');
+
+ if (cp && cp != comp_dir && cp[-1] == '.' && cp[1] == '/')
+ comp_dir = cp + 1;
+ }
+ unit->comp_dir = comp_dir;
+ break;
+ }
+
+ default:
+ break;
+ }
+ }
+ if (high_pc_relative)
+ high_pc += low_pc;
+ if (high_pc != 0)
+ {
+ if (!arange_add (unit, &unit->arange, low_pc, high_pc))
+ return NULL;
+ }
+
+ unit->first_child_die_ptr = info_ptr;
+ return unit;
+}
+
+/* Return TRUE if UNIT may contain the address given by ADDR. When
+ there are functions written entirely with inline asm statements, the
+ range info in the compilation unit header may not be correct. We
+ need to consult the line info table to see if a compilation unit
+ really contains the given address. */
+
+static bfd_boolean
+comp_unit_contains_address (struct comp_unit *unit, bfd_vma addr)
+{
+ struct arange *arange;
+
+ if (unit->error)
+ return FALSE;
+
+ arange = &unit->arange;
+ do
+ {
+ if (addr >= arange->low && addr < arange->high)
+ return TRUE;
+ arange = arange->next;
+ }
+ while (arange);
+
+ return FALSE;
+}
+
+/* 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.
+
+ Returns the range of addresses covered by the entry that was used
+ to fill in *LINENUMBER_PTR or 0 if it was not filled in. */
+
+static bfd_vma
+comp_unit_find_nearest_line (struct comp_unit *unit,
+ bfd_vma addr,
+ const char **filename_ptr,
+ const char **functionname_ptr,
+ unsigned int *linenumber_ptr,
+ unsigned int *discriminator_ptr,
+ struct dwarf2_debug *stash)
+{
+ bfd_boolean func_p;
+ struct funcinfo *function;
+
+ if (unit->error)
+ return FALSE;
+
+ if (! unit->line_table)
+ {
+ if (! unit->stmtlist)
+ {
+ unit->error = 1;
+ return FALSE;
+ }
+
+ unit->line_table = decode_line_info (unit, stash);
+
+ if (! unit->line_table)
+ {
+ unit->error = 1;
+ return FALSE;
+ }
+
+ if (unit->first_child_die_ptr < unit->end_ptr
+ && ! scan_unit_for_symbols (unit))
+ {
+ unit->error = 1;
+ return FALSE;
+ }
+ }
+
+ function = NULL;
+ func_p = lookup_address_in_function_table (unit, addr,
+ &function, functionname_ptr);
+ if (func_p && (function->tag == DW_TAG_inlined_subroutine))
+ stash->inliner_chain = function;
+
+ return lookup_address_in_line_info_table (unit->line_table, addr,
+ filename_ptr,
+ linenumber_ptr,
+ discriminator_ptr);
+}
+
+/* Check to see if line info is already decoded in a comp_unit.
+ If not, decode it. Returns TRUE if no errors were encountered;
+ FALSE otherwise. */
+
+static bfd_boolean
+comp_unit_maybe_decode_line_info (struct comp_unit *unit,
+ struct dwarf2_debug *stash)
+{
+ if (unit->error)
+ return FALSE;
+
+ if (! unit->line_table)
+ {
+ if (! unit->stmtlist)
+ {
+ unit->error = 1;
+ return FALSE;
+ }
+
+ unit->line_table = decode_line_info (unit, stash);
+
+ if (! unit->line_table)
+ {
+ unit->error = 1;
+ return FALSE;
+ }
+
+ if (unit->first_child_die_ptr < unit->end_ptr
+ && ! scan_unit_for_symbols (unit))
+ {
+ unit->error = 1;
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+/* If UNIT contains SYM at ADDR, set the output parameters to the
+ values for the line containing SYM. The output parameters,
+ FILENAME_PTR, and LINENUMBER_PTR, are pointers to the objects to be
+ filled in.
+
+ Return TRUE if UNIT contains SYM, and no errors were encountered;
+ FALSE otherwise. */
+
+static bfd_boolean
+comp_unit_find_line (struct comp_unit *unit,
+ asymbol *sym,
+ bfd_vma addr,
+ const char **filename_ptr,
+ unsigned int *linenumber_ptr,
+ struct dwarf2_debug *stash)
+{
+ if (!comp_unit_maybe_decode_line_info (unit, stash))
+ return FALSE;
+
+ if (sym->flags & BSF_FUNCTION)
+ return lookup_symbol_in_function_table (unit, sym, addr,
+ filename_ptr,
+ linenumber_ptr);
+
+ return lookup_symbol_in_variable_table (unit, sym, addr,
+ filename_ptr,
+ linenumber_ptr);
+}
+
+static struct funcinfo *
+reverse_funcinfo_list (struct funcinfo *head)
+{
+ struct funcinfo *rhead;
+ struct funcinfo *temp;
+
+ for (rhead = NULL; head; head = temp)
+ {
+ temp = head->prev_func;
+ head->prev_func = rhead;
+ rhead = head;
+ }
+ return rhead;
+}
+
+static struct varinfo *
+reverse_varinfo_list (struct varinfo *head)
+{
+ struct varinfo *rhead;
+ struct varinfo *temp;
+
+ for (rhead = NULL; head; head = temp)
+ {
+ temp = head->prev_var;
+ head->prev_var = rhead;
+ rhead = head;
+ }
+ return rhead;
+}
+
+/* Extract all interesting funcinfos and varinfos of a compilation
+ unit into hash tables for faster lookup. Returns TRUE if no
+ errors were enountered; FALSE otherwise. */
+
+static bfd_boolean
+comp_unit_hash_info (struct dwarf2_debug *stash,
+ struct comp_unit *unit,
+ struct info_hash_table *funcinfo_hash_table,
+ struct info_hash_table *varinfo_hash_table)
+{
+ struct funcinfo* each_func;
+ struct varinfo* each_var;
+ bfd_boolean okay = TRUE;
+
+ BFD_ASSERT (stash->info_hash_status != STASH_INFO_HASH_DISABLED);
+
+ if (!comp_unit_maybe_decode_line_info (unit, stash))
+ return FALSE;
+
+ BFD_ASSERT (!unit->cached);
+
+ /* To preserve the original search order, we went to visit the function
+ infos in the reversed order of the list. However, making the list
+ bi-directional use quite a bit of extra memory. So we reverse
+ the list first, traverse the list in the now reversed order and
+ finally reverse the list again to get back the original order. */
+ unit->function_table = reverse_funcinfo_list (unit->function_table);
+ for (each_func = unit->function_table;
+ each_func && okay;
+ each_func = each_func->prev_func)
+ {
+ /* Skip nameless functions. */
+ if (each_func->name)
+ /* There is no need to copy name string into hash table as
+ name string is either in the dwarf string buffer or
+ info in the stash. */
+ okay = insert_info_hash_table (funcinfo_hash_table, each_func->name,
+ (void*) each_func, FALSE);
+ }
+ unit->function_table = reverse_funcinfo_list (unit->function_table);
+ if (!okay)
+ return FALSE;
+
+ /* We do the same for variable infos. */
+ unit->variable_table = reverse_varinfo_list (unit->variable_table);
+ for (each_var = unit->variable_table;
+ each_var && okay;
+ each_var = each_var->prev_var)
+ {
+ /* Skip stack vars and vars with no files or names. */
+ if (each_var->stack == 0
+ && each_var->file != NULL
+ && each_var->name != NULL)
+ /* There is no need to copy name string into hash table as
+ name string is either in the dwarf string buffer or
+ info in the stash. */
+ okay = insert_info_hash_table (varinfo_hash_table, each_var->name,
+ (void*) each_var, FALSE);
+ }
+
+ unit->variable_table = reverse_varinfo_list (unit->variable_table);
+ unit->cached = TRUE;
+ return okay;
+}
+
+/* Locate a section in a BFD containing debugging info. The search starts
+ from the section after AFTER_SEC, or from the first section in the BFD if
+ AFTER_SEC is NULL. The search works by examining the names of the
+ sections. There are three permissiable names. The first two are given
+ by DEBUG_SECTIONS[debug_info] (whose standard DWARF2 names are .debug_info
+ and .zdebug_info). The third is a prefix .gnu.linkonce.wi.
+ This is a variation on the .debug_info section which has a checksum
+ describing the contents appended onto the name. This allows the linker to
+ identify and discard duplicate debugging sections for different
+ compilation units. */
+#define GNU_LINKONCE_INFO ".gnu.linkonce.wi."
+
+static asection *
+find_debug_info (bfd *abfd, const struct dwarf_debug_section *debug_sections,
+ asection *after_sec)
+{
+ asection *msec;
+ const char *look;
+
+ if (after_sec == NULL)
+ {
+ look = debug_sections[debug_info].uncompressed_name;
+ msec = bfd_get_section_by_name (abfd, look);
+ if (msec != NULL)
+ return msec;
+
+ look = debug_sections[debug_info].compressed_name;
+ if (look != NULL)
+ {
+ msec = bfd_get_section_by_name (abfd, look);
+ if (msec != NULL)
+ return msec;
+ }
+
+ for (msec = abfd->sections; msec != NULL; msec = msec->next)
+ if (CONST_STRNEQ (msec->name, GNU_LINKONCE_INFO))
+ return msec;
+
+ return NULL;
+ }
+
+ for (msec = after_sec->next; msec != NULL; msec = msec->next)
+ {
+ look = debug_sections[debug_info].uncompressed_name;
+ if (strcmp (msec->name, look) == 0)
+ return msec;
+
+ look = debug_sections[debug_info].compressed_name;
+ if (look != NULL && strcmp (msec->name, look) == 0)
+ return msec;
+
+ if (CONST_STRNEQ (msec->name, GNU_LINKONCE_INFO))
+ return msec;
+ }
+
+ return NULL;
+}
+
+/* Transfer VMAs from object file to separate debug file. */
+
+static void
+set_debug_vma (bfd *orig_bfd, bfd *debug_bfd)
+{
+ asection *s, *d;
+
+ for (s = orig_bfd->sections, d = debug_bfd->sections;
+ s != NULL && d != NULL;
+ s = s->next, d = d->next)
+ {
+ if ((d->flags & SEC_DEBUGGING) != 0)
+ break;
+ /* ??? Assumes 1-1 correspondence between sections in the
+ two files. */
+ if (strcmp (s->name, d->name) == 0)
+ {
+ d->output_section = s->output_section;
+ d->output_offset = s->output_offset;
+ d->vma = s->vma;
+ }
+ }
+}
+
+/* Unset vmas for adjusted sections in STASH. */
+
+static void
+unset_sections (struct dwarf2_debug *stash)
+{
+ int i;
+ struct adjusted_section *p;
+
+ i = stash->adjusted_section_count;
+ p = stash->adjusted_sections;
+ for (; i > 0; i--, p++)
+ p->section->vma = 0;
+}
+
+/* Set VMAs for allocated and .debug_info sections in ORIG_BFD, a
+ relocatable object file. VMAs are normally all zero in relocatable
+ object files, so if we want to distinguish locations in sections by
+ address we need to set VMAs so the sections do not overlap. We
+ also set VMA on .debug_info so that when we have multiple
+ .debug_info sections (or the linkonce variant) they also do not
+ overlap. The multiple .debug_info sections make up a single
+ logical section. ??? We should probably do the same for other
+ debug sections. */
+
+static bfd_boolean
+place_sections (bfd *orig_bfd, struct dwarf2_debug *stash)
+{
+ bfd *abfd;
+ struct adjusted_section *p;
+ int i;
+ const char *debug_info_name;
+
+ if (stash->adjusted_section_count != 0)
+ {
+ i = stash->adjusted_section_count;
+ p = stash->adjusted_sections;
+ for (; i > 0; i--, p++)
+ p->section->vma = p->adj_vma;
+ return TRUE;
+ }
+
+ debug_info_name = stash->debug_sections[debug_info].uncompressed_name;
+ i = 0;
+ abfd = orig_bfd;
+ while (1)
+ {
+ asection *sect;
+
+ for (sect = abfd->sections; sect != NULL; sect = sect->next)
+ {
+ int is_debug_info;
+
+ if ((sect->output_section != NULL
+ && sect->output_section != sect
+ && (sect->flags & SEC_DEBUGGING) == 0)
+ || sect->vma != 0)
+ continue;
+
+ is_debug_info = (strcmp (sect->name, debug_info_name) == 0
+ || CONST_STRNEQ (sect->name, GNU_LINKONCE_INFO));
+
+ if (!((sect->flags & SEC_ALLOC) != 0 && abfd == orig_bfd)
+ && !is_debug_info)
+ continue;
+
+ i++;
+ }
+ if (abfd == stash->bfd_ptr)
+ break;
+ abfd = stash->bfd_ptr;
+ }
+
+ if (i <= 1)
+ stash->adjusted_section_count = -1;
+ else
+ {
+ bfd_vma last_vma = 0, last_dwarf = 0;
+ bfd_size_type amt = i * sizeof (struct adjusted_section);
+
+ p = (struct adjusted_section *) bfd_malloc (amt);
+ if (p == NULL)
+ return FALSE;
+
+ stash->adjusted_sections = p;
+ stash->adjusted_section_count = i;
+
+ abfd = orig_bfd;
+ while (1)
+ {
+ asection *sect;
+
+ for (sect = abfd->sections; sect != NULL; sect = sect->next)
+ {
+ bfd_size_type sz;
+ int is_debug_info;
+
+ if ((sect->output_section != NULL
+ && sect->output_section != sect
+ && (sect->flags & SEC_DEBUGGING) == 0)
+ || sect->vma != 0)
+ continue;
+
+ is_debug_info = (strcmp (sect->name, debug_info_name) == 0
+ || CONST_STRNEQ (sect->name, GNU_LINKONCE_INFO));
+
+ if (!((sect->flags & SEC_ALLOC) != 0 && abfd == orig_bfd)
+ && !is_debug_info)
+ continue;
+
+ sz = sect->rawsize ? sect->rawsize : sect->size;
+
+ if (is_debug_info)
+ {
+ BFD_ASSERT (sect->alignment_power == 0);
+ sect->vma = last_dwarf;
+ last_dwarf += sz;
+ }
+ else
+ {
+ /* Align the new address to the current section
+ alignment. */
+ last_vma = ((last_vma
+ + ~((bfd_vma) -1 << sect->alignment_power))
+ & ((bfd_vma) -1 << sect->alignment_power));
+ sect->vma = last_vma;
+ last_vma += sz;
+ }
+
+ p->section = sect;
+ p->adj_vma = sect->vma;
+ p++;
+ }
+ if (abfd == stash->bfd_ptr)
+ break;
+ abfd = stash->bfd_ptr;
+ }
+ }
+
+ if (orig_bfd != stash->bfd_ptr)
+ set_debug_vma (orig_bfd, stash->bfd_ptr);
+
+ return TRUE;
+}
+
+/* Look up a funcinfo by name using the given info hash table. If found,
+ also update the locations pointed to by filename_ptr and linenumber_ptr.
+
+ This function returns TRUE if a funcinfo that matches the given symbol
+ and address is found with any error; otherwise it returns FALSE. */
+
+static bfd_boolean
+info_hash_lookup_funcinfo (struct info_hash_table *hash_table,
+ asymbol *sym,
+ bfd_vma addr,
+ const char **filename_ptr,
+ unsigned int *linenumber_ptr)
+{
+ struct funcinfo* each_func;
+ struct funcinfo* best_fit = NULL;
+ bfd_vma best_fit_len = 0;
+ struct info_list_node *node;
+ struct arange *arange;
+ const char *name = bfd_asymbol_name (sym);
+ asection *sec = bfd_get_section (sym);
+
+ for (node = lookup_info_hash_table (hash_table, name);
+ node;
+ node = node->next)
+ {
+ each_func = (struct funcinfo *) node->info;
+ for (arange = &each_func->arange;
+ arange;
+ arange = arange->next)
+ {
+ if ((!each_func->sec || each_func->sec == sec)
+ && addr >= arange->low
+ && addr < arange->high
+ && (!best_fit
+ || arange->high - arange->low < best_fit_len))
+ {
+ best_fit = each_func;
+ best_fit_len = arange->high - arange->low;
+ }
+ }
+ }
+
+ if (best_fit)
+ {
+ best_fit->sec = sec;
+ *filename_ptr = best_fit->file;
+ *linenumber_ptr = best_fit->line;
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/* Look up a varinfo by name using the given info hash table. If found,
+ also update the locations pointed to by filename_ptr and linenumber_ptr.
+
+ This function returns TRUE if a varinfo that matches the given symbol
+ and address is found with any error; otherwise it returns FALSE. */
+
+static bfd_boolean
+info_hash_lookup_varinfo (struct info_hash_table *hash_table,
+ asymbol *sym,
+ bfd_vma addr,
+ const char **filename_ptr,
+ unsigned int *linenumber_ptr)
+{
+ const char *name = bfd_asymbol_name (sym);
+ asection *sec = bfd_get_section (sym);
+ struct varinfo* each;
+ struct info_list_node *node;
+
+ for (node = lookup_info_hash_table (hash_table, name);
+ node;
+ node = node->next)
+ {
+ each = (struct varinfo *) node->info;
+ if (each->addr == addr
+ && (!each->sec || each->sec == sec))
+ {
+ each->sec = sec;
+ *filename_ptr = each->file;
+ *linenumber_ptr = each->line;
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+/* Update the funcinfo and varinfo info hash tables if they are
+ not up to date. Returns TRUE if there is no error; otherwise
+ returns FALSE and disable the info hash tables. */
+
+static bfd_boolean
+stash_maybe_update_info_hash_tables (struct dwarf2_debug *stash)
+{
+ struct comp_unit *each;
+
+ /* Exit if hash tables are up-to-date. */
+ if (stash->all_comp_units == stash->hash_units_head)
+ return TRUE;
+
+ if (stash->hash_units_head)
+ each = stash->hash_units_head->prev_unit;
+ else
+ each = stash->last_comp_unit;
+
+ while (each)
+ {
+ if (!comp_unit_hash_info (stash, each, stash->funcinfo_hash_table,
+ stash->varinfo_hash_table))
+ {
+ stash->info_hash_status = STASH_INFO_HASH_DISABLED;
+ return FALSE;
+ }
+ each = each->prev_unit;
+ }
+
+ stash->hash_units_head = stash->all_comp_units;
+ return TRUE;
+}
+
+/* Check consistency of info hash tables. This is for debugging only. */
+
+static void ATTRIBUTE_UNUSED
+stash_verify_info_hash_table (struct dwarf2_debug *stash)
+{
+ struct comp_unit *each_unit;
+ struct funcinfo *each_func;
+ struct varinfo *each_var;
+ struct info_list_node *node;
+ bfd_boolean found;
+
+ for (each_unit = stash->all_comp_units;
+ each_unit;
+ each_unit = each_unit->next_unit)
+ {
+ for (each_func = each_unit->function_table;
+ each_func;
+ each_func = each_func->prev_func)
+ {
+ if (!each_func->name)
+ continue;
+ node = lookup_info_hash_table (stash->funcinfo_hash_table,
+ each_func->name);
+ BFD_ASSERT (node);
+ found = FALSE;
+ while (node && !found)
+ {
+ found = node->info == each_func;
+ node = node->next;
+ }
+ BFD_ASSERT (found);
+ }
+
+ for (each_var = each_unit->variable_table;
+ each_var;
+ each_var = each_var->prev_var)
+ {
+ if (!each_var->name || !each_var->file || each_var->stack)
+ continue;
+ node = lookup_info_hash_table (stash->varinfo_hash_table,
+ each_var->name);
+ BFD_ASSERT (node);
+ found = FALSE;
+ while (node && !found)
+ {
+ found = node->info == each_var;
+ node = node->next;
+ }
+ BFD_ASSERT (found);
+ }
+ }
+}
+
+/* Check to see if we want to enable the info hash tables, which consume
+ quite a bit of memory. Currently we only check the number times
+ bfd_dwarf2_find_line is called. In the future, we may also want to
+ take the number of symbols into account. */
+
+static void
+stash_maybe_enable_info_hash_tables (bfd *abfd, struct dwarf2_debug *stash)
+{
+ BFD_ASSERT (stash->info_hash_status == STASH_INFO_HASH_OFF);
+
+ if (stash->info_hash_count++ < STASH_INFO_HASH_TRIGGER)
+ return;
+
+ /* FIXME: Maybe we should check the reduce_memory_overheads
+ and optimize fields in the bfd_link_info structure ? */
+
+ /* Create hash tables. */
+ stash->funcinfo_hash_table = create_info_hash_table (abfd);
+ stash->varinfo_hash_table = create_info_hash_table (abfd);
+ if (!stash->funcinfo_hash_table || !stash->varinfo_hash_table)
+ {
+ /* Turn off info hashes if any allocation above fails. */
+ stash->info_hash_status = STASH_INFO_HASH_DISABLED;
+ return;
+ }
+ /* We need a forced update so that the info hash tables will
+ be created even though there is no compilation unit. That
+ happens if STASH_INFO_HASH_TRIGGER is 0. */
+ stash_maybe_update_info_hash_tables (stash);
+ stash->info_hash_status = STASH_INFO_HASH_ON;
+}
+
+/* Find the file and line associated with a symbol and address using the
+ info hash tables of a stash. If there is a match, the function returns
+ TRUE and update the locations pointed to by filename_ptr and linenumber_ptr;
+ otherwise it returns FALSE. */
+
+static bfd_boolean
+stash_find_line_fast (struct dwarf2_debug *stash,
+ asymbol *sym,
+ bfd_vma addr,
+ const char **filename_ptr,
+ unsigned int *linenumber_ptr)
+{
+ BFD_ASSERT (stash->info_hash_status == STASH_INFO_HASH_ON);
+
+ if (sym->flags & BSF_FUNCTION)
+ return info_hash_lookup_funcinfo (stash->funcinfo_hash_table, sym, addr,
+ filename_ptr, linenumber_ptr);
+ return info_hash_lookup_varinfo (stash->varinfo_hash_table, sym, addr,
+ filename_ptr, linenumber_ptr);
+}
+
+/* Save current section VMAs. */
+
+static bfd_boolean
+save_section_vma (const bfd *abfd, struct dwarf2_debug *stash)
+{
+ asection *s;
+ unsigned int i;
+
+ if (abfd->section_count == 0)
+ return TRUE;
+ stash->sec_vma = bfd_malloc (sizeof (*stash->sec_vma) * abfd->section_count);
+ if (stash->sec_vma == NULL)
+ return FALSE;
+ for (i = 0, s = abfd->sections; i < abfd->section_count; i++, s = s->next)
+ {
+ if (s->output_section != NULL)
+ stash->sec_vma[i] = s->output_section->vma + s->output_offset;
+ else
+ stash->sec_vma[i] = s->vma;
+ }
+ return TRUE;
+}
+
+/* Compare current section VMAs against those at the time the stash
+ was created. If find_nearest_line is used in linker warnings or
+ errors early in the link process, the debug info stash will be
+ invalid for later calls. This is because we relocate debug info
+ sections, so the stashed section contents depend on symbol values,
+ which in turn depend on section VMAs. */
+
+static bfd_boolean
+section_vma_same (const bfd *abfd, const struct dwarf2_debug *stash)
+{
+ asection *s;
+ unsigned int i;
+
+ for (i = 0, s = abfd->sections; i < abfd->section_count; i++, s = s->next)
+ {
+ bfd_vma vma;
+
+ if (s->output_section != NULL)
+ vma = s->output_section->vma + s->output_offset;
+ else
+ vma = s->vma;
+ if (vma != stash->sec_vma[i])
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/* Read debug information from DEBUG_BFD when DEBUG_BFD is specified.
+ If DEBUG_BFD is not specified, we read debug information from ABFD
+ or its gnu_debuglink. The results will be stored in PINFO.
+ The function returns TRUE iff debug information is ready. */
+
+bfd_boolean
+_bfd_dwarf2_slurp_debug_info (bfd *abfd, bfd *debug_bfd,
+ const struct dwarf_debug_section *debug_sections,
+ asymbol **symbols,
+ void **pinfo,
+ bfd_boolean do_place)
+{
+ bfd_size_type amt = sizeof (struct dwarf2_debug);
+ bfd_size_type total_size;
+ asection *msec;
+ struct dwarf2_debug *stash = (struct dwarf2_debug *) *pinfo;
+
+ if (stash != NULL)
+ {
+ if (section_vma_same (abfd, stash))
+ return TRUE;
+ _bfd_dwarf2_cleanup_debug_info (abfd, pinfo);
+ memset (stash, 0, amt);
+ }
+ else
+ {
+ stash = (struct dwarf2_debug *) bfd_zalloc (abfd, amt);
+ if (! stash)
+ return FALSE;
+ }
+ stash->debug_sections = debug_sections;
+ stash->syms = symbols;
+ if (!save_section_vma (abfd, stash))
+ return FALSE;
+
+ *pinfo = stash;
+
+ if (debug_bfd == NULL)
+ debug_bfd = abfd;
+
+ msec = find_debug_info (debug_bfd, debug_sections, NULL);
+ if (msec == NULL && abfd == debug_bfd)
+ {
+ char * debug_filename = bfd_follow_gnu_debuglink (abfd, DEBUGDIR);
+
+ if (debug_filename == NULL)
+ /* No dwarf2 info, and no gnu_debuglink to follow.
+ Note that at this point the stash has been allocated, but
+ contains zeros. This lets future calls to this function
+ fail more quickly. */
+ return FALSE;
+
+ if ((debug_bfd = bfd_openr (debug_filename, NULL)) == NULL
+ || ! bfd_check_format (debug_bfd, bfd_object)
+ || (msec = find_debug_info (debug_bfd,
+ debug_sections, NULL)) == NULL
+ || !bfd_generic_link_read_symbols (debug_bfd))
+ {
+ if (debug_bfd)
+ bfd_close (debug_bfd);
+ /* FIXME: Should we report our failure to follow the debuglink ? */
+ free (debug_filename);
+ return FALSE;
+ }
+
+ symbols = bfd_get_outsymbols (debug_bfd);
+ stash->syms = symbols;
+ stash->close_on_cleanup = TRUE;
+ }
+ stash->bfd_ptr = debug_bfd;
+
+ if (do_place
+ && !place_sections (abfd, stash))
+ return FALSE;
+
+ /* There can be more than one DWARF2 info section in a BFD these
+ days. First handle the easy case when there's only one. If
+ there's more than one, try case two: none of the sections is
+ compressed. In that case, read them all in and produce one
+ large stash. We do this in two passes - in the first pass we
+ just accumulate the section sizes, and in the second pass we
+ read in the section's contents. (The allows us to avoid
+ reallocing the data as we add sections to the stash.) If
+ some or all sections are compressed, then do things the slow
+ way, with a bunch of reallocs. */
+
+ if (! find_debug_info (debug_bfd, debug_sections, msec))
+ {
+ /* Case 1: only one info section. */
+ total_size = msec->size;
+ if (! read_section (debug_bfd, &stash->debug_sections[debug_info],
+ symbols, 0,
+ &stash->info_ptr_memory, &total_size))
+ return FALSE;
+ }
+ else
+ {
+ /* Case 2: multiple sections. */
+ for (total_size = 0;
+ msec;
+ msec = find_debug_info (debug_bfd, debug_sections, msec))
+ total_size += msec->size;
+
+ stash->info_ptr_memory = (bfd_byte *) bfd_malloc (total_size);
+ if (stash->info_ptr_memory == NULL)
+ return FALSE;
+
+ total_size = 0;
+ for (msec = find_debug_info (debug_bfd, debug_sections, NULL);
+ msec;
+ msec = find_debug_info (debug_bfd, debug_sections, msec))
+ {
+ bfd_size_type size;
+
+ size = msec->size;
+ if (size == 0)
+ continue;
+
+ if (!(bfd_simple_get_relocated_section_contents
+ (debug_bfd, msec, stash->info_ptr_memory + total_size,
+ symbols)))
+ return FALSE;
+
+ total_size += size;
+ }
+ }
+
+ stash->info_ptr = stash->info_ptr_memory;
+ stash->info_ptr_end = stash->info_ptr + total_size;
+ stash->sec = find_debug_info (debug_bfd, debug_sections, NULL);
+ stash->sec_info_ptr = stash->info_ptr;
+ return TRUE;
+}
+
+/* Find the source code location of SYMBOL. If SYMBOL is NULL
+ then find the nearest source code location corresponding to
+ the address SECTION + OFFSET.
+ Returns TRUE if the line is found without error and fills in
+ FILENAME_PTR and LINENUMBER_PTR. In the case where SYMBOL was
+ NULL the FUNCTIONNAME_PTR is also filled in.
+ SYMBOLS contains the symbol table for ABFD.
+ DEBUG_SECTIONS contains the name of the dwarf debug sections.
+ ADDR_SIZE is the number of bytes in the initial .debug_info length
+ field and in the abbreviation offset, or zero to indicate that the
+ default value should be used. */
+
+bfd_boolean
+_bfd_dwarf2_find_nearest_line (bfd *abfd,
+ asymbol **symbols,
+ asymbol *symbol,
+ asection *section,
+ bfd_vma offset,
+ const char **filename_ptr,
+ const char **functionname_ptr,
+ unsigned int *linenumber_ptr,
+ unsigned int *discriminator_ptr,
+ const struct dwarf_debug_section *debug_sections,
+ unsigned int addr_size,
+ void **pinfo)
+{
+ /* 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;
+ /* What address are we looking for? */
+ bfd_vma addr;
+ struct comp_unit* each;
+ bfd_boolean found = FALSE;
+ bfd_boolean do_line;
+
+ *filename_ptr = NULL;
+ if (functionname_ptr != NULL)
+ *functionname_ptr = NULL;
+ *linenumber_ptr = 0;
+ if (discriminator_ptr)
+ *discriminator_ptr = 0;
+
+ if (! _bfd_dwarf2_slurp_debug_info (abfd, NULL, debug_sections,
+ symbols, pinfo,
+ (abfd->flags & (EXEC_P | DYNAMIC)) == 0))
+ return FALSE;
+
+ stash = (struct dwarf2_debug *) *pinfo;
+
+ do_line = symbol != NULL;
+ if (do_line)
+ {
+ BFD_ASSERT (section == NULL && offset == 0 && functionname_ptr == NULL);
+ section = bfd_get_section (symbol);
+ addr = symbol->value;
+ }
+ else
+ {
+ BFD_ASSERT (section != NULL && functionname_ptr != NULL);
+ addr = offset;
+ }
+
+ if (section->output_section)
+ addr += section->output_section->vma + section->output_offset;
+ else
+ addr += section->vma;
+
+ /* 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;
+
+ stash->inliner_chain = NULL;
+
+ /* Check the previously read comp. units first. */
+ if (do_line)
+ {
+ /* The info hash tables use quite a bit of memory. We may not want to
+ always use them. We use some heuristics to decide if and when to
+ turn it on. */
+ if (stash->info_hash_status == STASH_INFO_HASH_OFF)
+ stash_maybe_enable_info_hash_tables (abfd, stash);
+
+ /* Keep info hash table up to date if they are available. Note that we
+ may disable the hash tables if there is any error duing update. */
+ if (stash->info_hash_status == STASH_INFO_HASH_ON)
+ stash_maybe_update_info_hash_tables (stash);
+
+ if (stash->info_hash_status == STASH_INFO_HASH_ON)
+ {
+ found = stash_find_line_fast (stash, symbol, addr, filename_ptr,
+ linenumber_ptr);
+ if (found)
+ goto done;
+ }
+ else
+ {
+ /* Check the previously read comp. units first. */
+ for (each = stash->all_comp_units; each; each = each->next_unit)
+ if ((symbol->flags & BSF_FUNCTION) == 0
+ || each->arange.high == 0
+ || comp_unit_contains_address (each, addr))
+ {
+ found = comp_unit_find_line (each, symbol, addr, filename_ptr,
+ linenumber_ptr, stash);
+ if (found)
+ goto done;
+ }
+ }
+ }
+ else
+ {
+ bfd_vma min_range = (bfd_vma) -1;
+ const char * local_filename = NULL;
+ const char * local_functionname = NULL;
+ unsigned int local_linenumber = 0;
+ unsigned int local_discriminator = 0;
+
+ for (each = stash->all_comp_units; each; each = each->next_unit)
+ {
+ bfd_vma range = (bfd_vma) -1;
+
+ found = ((each->arange.high == 0
+ || comp_unit_contains_address (each, addr))
+ && (range = comp_unit_find_nearest_line (each, addr,
+ & local_filename,
+ & local_functionname,
+ & local_linenumber,
+ & local_discriminator,
+ stash)) != 0);
+ if (found)
+ {
+ /* PRs 15935 15994: Bogus debug information may have provided us
+ with an erroneous match. We attempt to counter this by
+ selecting the match that has the smallest address range
+ associated with it. (We are assuming that corrupt debug info
+ will tend to result in extra large address ranges rather than
+ extra small ranges).
+
+ This does mean that we scan through all of the CUs associated
+ with the bfd each time this function is called. But this does
+ have the benefit of producing consistent results every time the
+ function is called. */
+ if (range <= min_range)
+ {
+ if (filename_ptr && local_filename)
+ * filename_ptr = local_filename;
+ if (functionname_ptr && local_functionname)
+ * functionname_ptr = local_functionname;
+ if (discriminator_ptr && local_discriminator)
+ * discriminator_ptr = local_discriminator;
+ if (local_linenumber)
+ * linenumber_ptr = local_linenumber;
+ min_range = range;
+ }
+ }
+ }
+
+ if (* linenumber_ptr)
+ {
+ found = TRUE;
+ goto done;
+ }
+ }
+
+ /* The DWARF2 spec says that the initial length field, and the
+ offset of the abbreviation table, should both be 4-byte values.
+ However, some compilers do things differently. */
+ if (addr_size == 0)
+ addr_size = 4;
+ BFD_ASSERT (addr_size == 4 || addr_size == 8);
+
+ /* Read each remaining comp. units checking each as they are read. */
+ while (stash->info_ptr < stash->info_ptr_end)
+ {
+ bfd_vma length;
+ unsigned int offset_size = addr_size;
+ bfd_byte *info_ptr_unit = stash->info_ptr;
+
+ length = read_4_bytes (stash->bfd_ptr, stash->info_ptr);
+ /* A 0xffffff length is the DWARF3 way of indicating
+ we use 64-bit offsets, instead of 32-bit offsets. */
+ if (length == 0xffffffff)
+ {
+ offset_size = 8;
+ length = read_8_bytes (stash->bfd_ptr, stash->info_ptr + 4);
+ stash->info_ptr += 12;
+ }
+ /* A zero length is the IRIX way of indicating 64-bit offsets,
+ mostly because the 64-bit length will generally fit in 32
+ bits, and the endianness helps. */
+ else if (length == 0)
+ {
+ offset_size = 8;
+ length = read_4_bytes (stash->bfd_ptr, stash->info_ptr + 4);
+ stash->info_ptr += 8;
+ }
+ /* In the absence of the hints above, we assume 32-bit DWARF2
+ offsets even for targets with 64-bit addresses, because:
+ a) most of the time these targets will not have generated
+ more than 2Gb of debug info and so will not need 64-bit
+ offsets,
+ and
+ b) if they do use 64-bit offsets but they are not using
+ the size hints that are tested for above then they are
+ not conforming to the DWARF3 standard anyway. */
+ else if (addr_size == 8)
+ {
+ offset_size = 4;
+ stash->info_ptr += 4;
+ }
+ else
+ stash->info_ptr += 4;
+
+ if (length > 0)
+ {
+ each = parse_comp_unit (stash, length, info_ptr_unit,
+ offset_size);
+ if (!each)
+ /* The dwarf information is damaged, don't trust it any
+ more. */
+ break;
+ stash->info_ptr += length;
+
+ if (stash->all_comp_units)
+ stash->all_comp_units->prev_unit = each;
+ else
+ stash->last_comp_unit = each;
+
+ each->next_unit = stash->all_comp_units;
+ stash->all_comp_units = each;
+
+ /* DW_AT_low_pc and DW_AT_high_pc are optional for
+ compilation units. If we don't have them (i.e.,
+ unit->high == 0), we need to consult the line info table
+ to see if a compilation unit contains the given
+ address. */
+ if (do_line)
+ found = (((symbol->flags & BSF_FUNCTION) == 0
+ || each->arange.high == 0
+ || comp_unit_contains_address (each, addr))
+ && comp_unit_find_line (each, symbol, addr,
+ filename_ptr,
+ linenumber_ptr,
+ stash));
+ else
+ found = ((each->arange.high == 0
+ || comp_unit_contains_address (each, addr))
+ && comp_unit_find_nearest_line (each, addr,
+ filename_ptr,
+ functionname_ptr,
+ linenumber_ptr,
+ discriminator_ptr,
+ stash) != 0);
+
+ if ((bfd_vma) (stash->info_ptr - stash->sec_info_ptr)
+ == stash->sec->size)
+ {
+ stash->sec = find_debug_info (stash->bfd_ptr, debug_sections,
+ stash->sec);
+ stash->sec_info_ptr = stash->info_ptr;
+ }
+
+ if (found)
+ goto done;
+ }
+ }
+
+ done:
+ if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0)
+ unset_sections (stash);
+
+ return found;
+}
+
+bfd_boolean
+_bfd_dwarf2_find_inliner_info (bfd *abfd ATTRIBUTE_UNUSED,
+ const char **filename_ptr,
+ const char **functionname_ptr,
+ unsigned int *linenumber_ptr,
+ void **pinfo)
+{
+ struct dwarf2_debug *stash;
+
+ stash = (struct dwarf2_debug *) *pinfo;
+ if (stash)
+ {
+ struct funcinfo *func = stash->inliner_chain;
+
+ if (func && func->caller_func)
+ {
+ *filename_ptr = func->caller_file;
+ *functionname_ptr = func->caller_func->name;
+ *linenumber_ptr = func->caller_line;
+ stash->inliner_chain = func->caller_func;
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+void
+_bfd_dwarf2_cleanup_debug_info (bfd *abfd, void **pinfo)
+{
+ struct dwarf2_debug *stash = (struct dwarf2_debug *) *pinfo;
+ struct comp_unit *each;
+
+ if (abfd == NULL || stash == NULL)
+ return;
+
+ for (each = stash->all_comp_units; each; each = each->next_unit)
+ {
+ struct abbrev_info **abbrevs = each->abbrevs;
+ struct funcinfo *function_table = each->function_table;
+ struct varinfo *variable_table = each->variable_table;
+ size_t i;
+
+ for (i = 0; i < ABBREV_HASH_SIZE; i++)
+ {
+ struct abbrev_info *abbrev = abbrevs[i];
+
+ while (abbrev)
+ {
+ free (abbrev->attrs);
+ abbrev = abbrev->next;
+ }
+ }
+
+ if (each->line_table)
+ {
+ free (each->line_table->dirs);
+ free (each->line_table->files);
+ }
+
+ while (function_table)
+ {
+ if (function_table->file)
+ {
+ free (function_table->file);
+ function_table->file = NULL;
+ }
+
+ if (function_table->caller_file)
+ {
+ free (function_table->caller_file);
+ function_table->caller_file = NULL;
+ }
+ function_table = function_table->prev_func;
+ }
+
+ while (variable_table)
+ {
+ if (variable_table->file)
+ {
+ free (variable_table->file);
+ variable_table->file = NULL;
+ }
+
+ variable_table = variable_table->prev_var;
+ }
+ }
+
+ if (stash->dwarf_abbrev_buffer)
+ free (stash->dwarf_abbrev_buffer);
+ if (stash->dwarf_line_buffer)
+ free (stash->dwarf_line_buffer);
+ if (stash->dwarf_str_buffer)
+ free (stash->dwarf_str_buffer);
+ if (stash->dwarf_ranges_buffer)
+ free (stash->dwarf_ranges_buffer);
+ if (stash->info_ptr_memory)
+ free (stash->info_ptr_memory);
+ if (stash->close_on_cleanup)
+ bfd_close (stash->bfd_ptr);
+ if (stash->alt_dwarf_str_buffer)
+ free (stash->alt_dwarf_str_buffer);
+ if (stash->alt_dwarf_info_buffer)
+ free (stash->alt_dwarf_info_buffer);
+ if (stash->sec_vma)
+ free (stash->sec_vma);
+ if (stash->adjusted_sections)
+ free (stash->adjusted_sections);
+ if (stash->alt_bfd_ptr)
+ bfd_close (stash->alt_bfd_ptr);
+}
diff --git a/bfd/ecoff.c b/bfd/ecoff.c
new file mode 100644
index 0000000..01f51e6
--- /dev/null
+++ b/bfd/ecoff.c
@@ -0,0 +1,4454 @@
+/* Generic ECOFF (Extended-COFF) routines.
+ Copyright (C) 1990-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "bfdlink.h"
+#include "libbfd.h"
+#include "aout/ar.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"
+#include "libiberty.h"
+
+#define streq(a, b) (strcmp ((a), (b)) == 0)
+#define strneq(a, b, n) (strncmp ((a), (b), (n)) == 0)
+
+
+/* This stuff is somewhat copied from coffcode.h. */
+static asection bfd_debug_section =
+{
+ /* name, id, index, next, prev, flags, user_set_vma, */
+ "*DEBUG*", 0, 0, NULL, NULL, 0, 0,
+ /* linker_mark, linker_has_input, gc_mark, compress_status, */
+ 0, 0, 1, 0,
+ /* segment_mark, sec_info_type, use_rela_p, */
+ 0, 0, 0,
+ /* sec_flg0, sec_flg1, sec_flg2, sec_flg3, sec_flg4, sec_flg5, */
+ 0, 0, 0, 0, 0, 0,
+ /* vma, lma, size, rawsize, compressed_size, relax, relax_count, */
+ 0, 0, 0, 0, 0, 0, 0,
+ /* output_offset, output_section, alignment_power, */
+ 0, NULL, 0,
+ /* relocation, orelocation, reloc_count, filepos, rel_filepos, */
+ NULL, NULL, 0, 0, 0,
+ /* line_filepos, userdata, contents, lineno, lineno_count, */
+ 0, NULL, NULL, NULL, 0,
+ /* entsize, kept_section, moving_line_filepos, */
+ 0, NULL, 0,
+ /* target_index, used_by_bfd, constructor_chain, owner, */
+ 0, NULL, NULL, NULL,
+ /* symbol, */
+ NULL,
+ /* symbol_ptr_ptr, */
+ NULL,
+ /* map_head, map_tail */
+ { NULL }, { NULL }
+};
+
+/* Create an ECOFF object. */
+
+bfd_boolean
+_bfd_ecoff_mkobject (bfd *abfd)
+{
+ bfd_size_type amt = sizeof (ecoff_data_type);
+
+ abfd->tdata.ecoff_obj_data = (struct ecoff_tdata *) bfd_zalloc (abfd, amt);
+ 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. */
+
+void *
+_bfd_ecoff_mkobject_hook (bfd *abfd, void * filehdr, void * 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))
+ return NULL;
+
+ ecoff = ecoff_data (abfd);
+ ecoff->gp_size = 8;
+ ecoff->sym_filepos = internal_f->f_symptr;
+
+ if (internal_a != 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 (void *) ecoff;
+}
+
+/* Initialize a new section. */
+
+bfd_boolean
+_bfd_ecoff_new_section_hook (bfd *abfd, asection *section)
+{
+ unsigned int i;
+ static struct
+ {
+ const char * name;
+ flagword flags;
+ }
+ section_flags [] =
+ {
+ { _TEXT, SEC_ALLOC | SEC_CODE | SEC_LOAD },
+ { _INIT, SEC_ALLOC | SEC_CODE | SEC_LOAD },
+ { _FINI, SEC_ALLOC | SEC_CODE | SEC_LOAD },
+ { _DATA, SEC_ALLOC | SEC_DATA | SEC_LOAD },
+ { _SDATA, SEC_ALLOC | SEC_DATA | SEC_LOAD },
+ { _RDATA, SEC_ALLOC | SEC_DATA | SEC_LOAD | SEC_READONLY},
+ { _LIT8, SEC_ALLOC | SEC_DATA | SEC_LOAD | SEC_READONLY},
+ { _LIT4, SEC_ALLOC | SEC_DATA | SEC_LOAD | SEC_READONLY},
+ { _RCONST, SEC_ALLOC | SEC_DATA | SEC_LOAD | SEC_READONLY},
+ { _PDATA, SEC_ALLOC | SEC_DATA | SEC_LOAD | SEC_READONLY},
+ { _BSS, SEC_ALLOC},
+ { _SBSS, SEC_ALLOC},
+ /* An Irix 4 shared libary. */
+ { _LIB, SEC_COFF_SHARED_LIBRARY}
+ };
+
+ section->alignment_power = 4;
+
+ for (i = 0; i < ARRAY_SIZE (section_flags); i++)
+ if (streq (section->name, section_flags[i].name))
+ {
+ section->flags |= section_flags[i].flags;
+ break;
+ }
+
+
+ /* 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 _bfd_generic_new_section_hook (abfd, section);
+}
+
+/* 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. */
+
+bfd_boolean
+_bfd_ecoff_set_arch_mach_hook (bfd *abfd, void * 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 = bfd_mach_mips3000;
+ break;
+
+ case MIPS_MAGIC_LITTLE2:
+ case MIPS_MAGIC_BIG2:
+ /* MIPS ISA level 2: the r6000. */
+ arch = bfd_arch_mips;
+ mach = bfd_mach_mips6000;
+ break;
+
+ case MIPS_MAGIC_LITTLE3:
+ case MIPS_MAGIC_BIG3:
+ /* MIPS ISA level 3: the r4000. */
+ arch = bfd_arch_mips;
+ mach = bfd_mach_mips4000;
+ 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);
+}
+
+bfd_boolean
+_bfd_ecoff_no_long_sections (bfd *abfd, int enable)
+{
+ (void) abfd;
+ (void) enable;
+ return FALSE;
+}
+
+/* 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 (bfd *abfd)
+{
+ int big, little;
+
+ switch (bfd_get_arch (abfd))
+ {
+ case bfd_arch_mips:
+ switch (bfd_get_mach (abfd))
+ {
+ default:
+ case 0:
+ case bfd_mach_mips3000:
+ big = MIPS_MAGIC_BIG;
+ little = MIPS_MAGIC_LITTLE;
+ break;
+
+ case bfd_mach_mips6000:
+ big = MIPS_MAGIC_BIG2;
+ little = MIPS_MAGIC_LITTLE2;
+ break;
+
+ case bfd_mach_mips4000:
+ 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 (const char *name, flagword flags)
+{
+ unsigned int i;
+ static struct
+ {
+ const char * name;
+ long flags;
+ }
+ styp_flags [] =
+ {
+ { _TEXT, STYP_TEXT },
+ { _DATA, STYP_DATA },
+ { _SDATA, STYP_SDATA },
+ { _RDATA, STYP_RDATA },
+ { _LITA, STYP_LITA },
+ { _LIT8, STYP_LIT8 },
+ { _LIT4, STYP_LIT4 },
+ { _BSS, STYP_BSS },
+ { _SBSS, STYP_SBSS },
+ { _INIT, STYP_ECOFF_INIT },
+ { _FINI, STYP_ECOFF_FINI },
+ { _PDATA, STYP_PDATA },
+ { _XDATA, STYP_XDATA },
+ { _LIB, STYP_ECOFF_LIB },
+ { _GOT, STYP_GOT },
+ { _HASH, STYP_HASH },
+ { _DYNAMIC, STYP_DYNAMIC },
+ { _LIBLIST, STYP_LIBLIST },
+ { _RELDYN, STYP_RELDYN },
+ { _CONFLIC, STYP_CONFLIC },
+ { _DYNSTR, STYP_DYNSTR },
+ { _DYNSYM, STYP_DYNSYM },
+ { _RCONST, STYP_RCONST }
+ };
+ long styp = 0;
+
+ for (i = 0; i < ARRAY_SIZE (styp_flags); i++)
+ if (streq (name, styp_flags[i].name))
+ {
+ styp = styp_flags[i].flags;
+ break;
+ }
+
+ if (styp == 0)
+ {
+ if (streq (name, _COMMENT))
+ {
+ styp = STYP_COMMENT;
+ flags &=~ SEC_NEVER_LOAD;
+ }
+ 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. */
+
+bfd_boolean
+_bfd_ecoff_styp_to_sec_flags (bfd *abfd ATTRIBUTE_UNUSED,
+ void * hdr,
+ const char *name ATTRIBUTE_UNUSED,
+ asection *section ATTRIBUTE_UNUSED,
+ flagword * flags_ptr)
+{
+ 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;
+
+ * flags_ptr = sec_flags;
+ return TRUE;
+}
+
+/* Read in the symbolic header for an ECOFF object file. */
+
+static bfd_boolean
+ecoff_slurp_symbolic_header (bfd *abfd)
+{
+ const struct ecoff_backend_data * const backend = ecoff_backend (abfd);
+ bfd_size_type external_hdr_size;
+ void * 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 = bfd_malloc (external_hdr_size);
+ if (raw == NULL)
+ goto error_return;
+
+ if (bfd_seek (abfd, ecoff_data (abfd)->sym_filepos, SEEK_SET) != 0
+ || bfd_bread (raw, external_hdr_size, 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. */
+
+bfd_boolean
+_bfd_ecoff_slurp_symbolic_info (bfd *abfd,
+ asection *ignore ATTRIBUTE_UNUSED,
+ 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;
+ void * 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_size_type amt;
+ file_ptr pos;
+
+ 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 != 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);
+ /* eraxxon@alumni.rice.edu: ioptMax refers to the size of the
+ optimization symtab, not the number of entries. */
+ UPDATE_RAW_END (cbOptOffset, ioptMax, sizeof (char));
+ 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 = bfd_alloc (abfd, raw_size);
+ if (raw == NULL)
+ return FALSE;
+
+ pos = ecoff_data (abfd)->sym_filepos;
+ pos += backend->debug_swap.external_hdr_size;
+ if (bfd_seek (abfd, pos, SEEK_SET) != 0
+ || bfd_bread (raw, raw_size, 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 = NULL; \
+ else \
+ debug->off2 = (type) ((char *) raw \
+ + (internal_symhdr->off1 \
+ - raw_base))
+
+ FIX (cbLineOffset, line, unsigned char *);
+ FIX (cbDnOffset, external_dnr, void *);
+ FIX (cbPdOffset, external_pdr, void *);
+ FIX (cbSymOffset, external_sym, void *);
+ FIX (cbOptOffset, external_opt, void *);
+ FIX (cbAuxOffset, external_aux, union aux_ext *);
+ FIX (cbSsOffset, ss, char *);
+ FIX (cbSsExtOffset, ssext, char *);
+ FIX (cbFdOffset, external_fdr, void *);
+ FIX (cbRfdOffset, external_rfd, void *);
+ FIX (cbExtOffset, external_ext, void *);
+#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. */
+ amt = internal_symhdr->ifdMax;
+ amt *= sizeof (struct fdr);
+ debug->fdr = (FDR *) bfd_alloc (abfd, amt);
+ 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, (void *) 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 (bfd *abfd)
+{
+ ecoff_symbol_type *new_symbol;
+ bfd_size_type amt = sizeof (ecoff_symbol_type);
+
+ new_symbol = (ecoff_symbol_type *) bfd_zalloc (abfd, amt);
+ if (new_symbol == NULL)
+ return NULL;
+ new_symbol->symbol.section = NULL;
+ new_symbol->fdr = NULL;
+ new_symbol->local = FALSE;
+ new_symbol->native = NULL;
+ new_symbol->symbol.the_bfd = abfd;
+ return &new_symbol->symbol;
+}
+
+/* Set the BFD flags and section for an ECOFF symbol. */
+
+static bfd_boolean
+ecoff_set_symbol_info (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;
+ }
+
+ if (ecoff_sym->st == stProc || ecoff_sym->st == stStaticProc)
+ asym->flags |= BSF_FUNCTION;
+
+ 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:
+ /* Mark the symbol as a constructor. */
+ asym->flags |= BSF_CONSTRUCTOR;
+ break;
+ }
+ }
+ return TRUE;
+}
+
+/* Read an ECOFF symbol table. */
+
+bfd_boolean
+_bfd_ecoff_slurp_symbol_table (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) (bfd *, void *, EXTR *)
+ = backend->debug_swap.swap_ext_in;
+ void (* const swap_sym_in) (bfd *, void *, 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, NULL,
+ &ecoff_data (abfd)->debug_info))
+ return FALSE;
+ if (bfd_get_symcount (abfd) == 0)
+ return TRUE;
+
+ internal_size = bfd_get_symcount (abfd);
+ internal_size *= 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, (void *) 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 = (void *) 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, (void *) 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 = (void *) 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 (bfd *abfd)
+{
+ if (! _bfd_ecoff_slurp_symbolic_info (abfd, 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_canonicalize_symtab (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))
+ 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++ = 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 (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,
+ ((unsigned long) indx
+ + debug_info->symbolic_header.iextMax));
+}
+
+/* Convert the type information to string format. */
+
+static char *
+ecoff_type_to_string (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. */
+
+void
+_bfd_ecoff_get_symbol_info (bfd *abfd ATTRIBUTE_UNUSED,
+ asymbol *symbol,
+ symbol_info *ret)
+{
+ bfd_symbol_info (symbol, ret);
+}
+
+/* Return whether this is a local label. */
+
+bfd_boolean
+_bfd_ecoff_bfd_is_local_label_name (bfd *abfd ATTRIBUTE_UNUSED,
+ const char *name)
+{
+ return name[0] == '$';
+}
+
+/* Print information about an ECOFF symbol. */
+
+void
+_bfd_ecoff_print_symbol (bfd *abfd,
+ void * 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 bfd_boolean
+ecoff_slurp_reloc_table (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 amt;
+ char *external_relocs;
+ arelent *rptr;
+ unsigned int i;
+
+ if (section->relocation != NULL
+ || section->reloc_count == 0
+ || (section->flags & SEC_CONSTRUCTOR) != 0)
+ return TRUE;
+
+ if (! _bfd_ecoff_slurp_symbol_table (abfd))
+ return FALSE;
+
+ amt = section->reloc_count;
+ amt *= sizeof (arelent);
+ internal_relocs = (arelent *) bfd_alloc (abfd, amt);
+
+ external_reloc_size = backend->external_reloc_size;
+ amt = external_reloc_size * section->reloc_count;
+ external_relocs = (char *) bfd_alloc (abfd, amt);
+ if (internal_relocs == NULL || external_relocs == NULL)
+ return FALSE;
+ if (bfd_seek (abfd, section->rel_filepos, SEEK_SET) != 0)
+ return FALSE;
+ if (bfd_bread (external_relocs, amt, abfd) != amt)
+ 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 == 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 (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))
+ return -1;
+
+ tblptr = section->relocation;
+
+ for (count = 0; count < section->reloc_count; count++)
+ *relptr++ = tblptr++;
+ }
+
+ *relptr = 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. */
+
+bfd_boolean
+_bfd_ecoff_find_nearest_line (bfd *abfd,
+ asymbol **symbols ATTRIBUTE_UNUSED,
+ asection *section,
+ bfd_vma offset,
+ const char **filename_ptr,
+ const char **functionname_ptr,
+ unsigned int *retline_ptr,
+ unsigned int *discriminator_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, NULL, debug_info)
+ || bfd_get_symcount (abfd) == 0)
+ return FALSE;
+
+ if (ecoff_data (abfd)->find_line_info == NULL)
+ {
+ bfd_size_type amt = sizeof (struct ecoff_find_line);
+
+ ecoff_data (abfd)->find_line_info =
+ (struct ecoff_find_line *) bfd_zalloc (abfd, amt);
+ if (ecoff_data (abfd)->find_line_info == NULL)
+ return FALSE;
+ }
+
+ if (discriminator_ptr)
+ *discriminator_ptr = 0;
+ 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. */
+
+bfd_boolean
+_bfd_ecoff_bfd_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
+{
+ struct ecoff_debug_info *iinfo = &ecoff_data (ibfd)->debug_info;
+ struct ecoff_debug_info *oinfo = &ecoff_data (obfd)->debug_info;
+ int i;
+ asymbol **sym_ptr_ptr;
+ size_t c;
+ bfd_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 == 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. */
+
+bfd_boolean
+_bfd_ecoff_set_arch_mach (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. */
+
+int
+_bfd_ecoff_sizeof_headers (bfd *abfd,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED)
+{
+ asection *current;
+ int c;
+ int ret;
+
+ c = 0;
+ for (current = abfd->sections;
+ current != NULL;
+ current = current->next)
+ ++c;
+
+ ret = (bfd_coff_filhsz (abfd)
+ + bfd_coff_aoutsz (abfd)
+ + c * bfd_coff_scnhsz (abfd));
+ return (int) BFD_ALIGN (ret, 16);
+}
+
+/* Get the contents of a section. */
+
+bfd_boolean
+_bfd_ecoff_get_section_contents (bfd *abfd,
+ asection *section,
+ void * 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 (const void * arg1, const void * 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 bfd_boolean
+ecoff_compute_section_file_positions (bfd *abfd)
+{
+ file_ptr sofar, file_sofar;
+ asection **sorted_hdrs;
+ asection *current;
+ unsigned int i;
+ file_ptr old_sofar;
+ bfd_boolean rdata_in_text;
+ bfd_boolean first_data, first_nonalloc;
+ const bfd_vma round = ecoff_backend (abfd)->round;
+ bfd_size_type amt;
+
+ sofar = _bfd_ecoff_sizeof_headers (abfd, NULL);
+ file_sofar = sofar;
+
+ /* Sort the sections by VMA. */
+ amt = abfd->section_count;
+ amt *= sizeof (asection *);
+ sorted_hdrs = (asection **) bfd_malloc (amt);
+ 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 (streq (current->name, _RDATA))
+ break;
+ if ((current->flags & SEC_CODE) == 0
+ && ! streq (current->name, _PDATA)
+ && ! streq (current->name, _RCONST))
+ {
+ 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 (streq (current->name, _PDATA))
+ current->line_filepos = current->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
+ || ! streq (current->name, _RDATA))
+ && ! streq (current->name, _PDATA)
+ && ! streq (current->name, _RCONST))
+ {
+ sofar = (sofar + round - 1) &~ (round - 1);
+ file_sofar = (file_sofar + round - 1) &~ (round - 1);
+ first_data = FALSE;
+ }
+ else if (streq (current->name, _LIB))
+ {
+ /* 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->size;
+ if ((current->flags & SEC_HAS_CONTENTS) != 0)
+ file_sofar += current->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->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 (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 != 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. */
+
+bfd_boolean
+_bfd_ecoff_set_section_contents (bfd *abfd,
+ asection *section,
+ const void * location,
+ file_ptr offset,
+ bfd_size_type count)
+{
+ file_ptr pos;
+
+ /* This must be done first, because bfd_set_section_contents is
+ going to set output_has_begun to TRUE. */
+ if (! abfd->output_has_begun
+ && ! 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 (streq (section->name, _LIB))
+ {
+ 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;
+
+ pos = section->filepos + offset;
+ if (bfd_seek (abfd, pos, SEEK_SET) != 0
+ || bfd_bwrite (location, 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 (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. */
+
+bfd_boolean
+bfd_ecoff_set_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. */
+
+bfd_boolean
+bfd_ecoff_set_regmasks (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 != NULL)
+ {
+ 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 bfd_boolean
+ecoff_get_extr (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 != 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 (asymbol *sym, bfd_size_type indx)
+{
+ ecoff_set_sym_index (sym, indx);
+}
+
+/* Write out an ECOFF file. */
+
+bfd_boolean
+_bfd_ecoff_write_object_contents (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) (bfd *, const arelent *, struct internal_reloc *)
+ = backend->adjust_reloc_out;
+ void (* const swap_reloc_out) (bfd *, const struct internal_reloc *, void *)
+ = 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;
+ bfd_boolean set_text_start;
+ bfd_size_type data_size;
+ bfd_vma data_start;
+ bfd_boolean set_data_start;
+ bfd_size_type bss_size;
+ void * buff = NULL;
+ void * 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 != NULL;
+ current = current->next)
+ {
+ current->target_index = count;
+ ++count;
+ }
+
+ if ((abfd->flags & D_PAGED) != 0)
+ text_size = _bfd_ecoff_sizeof_headers (abfd, NULL);
+ 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 = bfd_malloc (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 != 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 (streq (current->name, _LIB))
+ section.s_vaddr = 0;
+ else
+ section.s_vaddr = vma;
+
+ section.s_paddr = current->lma;
+ section.s_size = current->size;
+
+ /* 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 (! streq (current->name, _PDATA))
+ 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, (void *) &section, buff) == 0
+ || bfd_bwrite (buff, 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 += current->size;
+ 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 += current->size;
+ 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 += current->size;
+ 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, (void *) &internal_f, buff);
+ if (bfd_bwrite (buff, filhsz, abfd) != filhsz)
+ goto error_return;
+
+ bfd_coff_swap_aouthdr_out (abfd, (void *) &internal_a, buff);
+ if (bfd_bwrite (buff, 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,
+ ecoff_get_extr, ecoff_set_index))
+ goto error_return;
+
+ /* Write out the relocs. */
+ for (current = abfd->sections;
+ current != NULL;
+ current = current->next)
+ {
+ arelent **reloc_ptr_ptr;
+ arelent **reloc_end;
+ char *out_ptr;
+ bfd_size_type amt;
+
+ if (current->reloc_count == 0)
+ continue;
+
+ amt = current->reloc_count * external_reloc_size;
+ reloc_buff = bfd_alloc (abfd, amt);
+ 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 ((void *) &in, 0, sizeof in);
+
+ reloc = *reloc_ptr_ptr;
+ sym = *reloc->sym_ptr_ptr;
+
+ /* If the howto field has not been initialised then skip this reloc.
+ This assumes that an error message has been issued elsewhere. */
+ if (reloc->howto == NULL)
+ continue;
+
+ 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;
+ unsigned int j;
+ static struct
+ {
+ const char * name;
+ long r_symndx;
+ }
+ section_symndx [] =
+ {
+ { _TEXT, RELOC_SECTION_TEXT },
+ { _RDATA, RELOC_SECTION_RDATA },
+ { _DATA, RELOC_SECTION_DATA },
+ { _SDATA, RELOC_SECTION_SDATA },
+ { _SBSS, RELOC_SECTION_SBSS },
+ { _BSS, RELOC_SECTION_BSS },
+ { _INIT, RELOC_SECTION_INIT },
+ { _LIT8, RELOC_SECTION_LIT8 },
+ { _LIT4, RELOC_SECTION_LIT4 },
+ { _XDATA, RELOC_SECTION_XDATA },
+ { _PDATA, RELOC_SECTION_PDATA },
+ { _FINI, RELOC_SECTION_FINI },
+ { _LITA, RELOC_SECTION_LITA },
+ { "*ABS*", RELOC_SECTION_ABS },
+ { _RCONST, RELOC_SECTION_RCONST }
+ };
+
+ name = bfd_get_section_name (abfd, bfd_get_section (sym));
+
+ for (j = 0; j < ARRAY_SIZE (section_symndx); j++)
+ if (streq (name, section_symndx[j].name))
+ {
+ in.r_symndx = section_symndx[j].r_symndx;
+ break;
+ }
+
+ if (j == ARRAY_SIZE (section_symndx))
+ abort ();
+ in.r_extern = 0;
+ }
+
+ (*adjust_reloc_out) (abfd, reloc, &in);
+
+ (*swap_reloc_out) (abfd, &in, (void *) out_ptr);
+ }
+
+ if (bfd_seek (abfd, current->rel_filepos, SEEK_SET) != 0)
+ goto error_return;
+ amt = current->reloc_count * external_reloc_size;
+ if (bfd_bwrite (reloc_buff, amt, abfd) != amt)
+ 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))
+ 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_bread (&c, (bfd_size_type) 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_bwrite (&c, (bfd_size_type) 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 (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. */
+
+bfd_boolean
+_bfd_ecoff_slurp_armap (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;
+ carsym *symdef_ptr;
+ char *stringbase;
+ bfd_size_type amt;
+
+ /* Get the name of the first element. */
+ i = bfd_bread ((void *) nextname, (bfd_size_type) 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 (CONST_STRNEQ (nextname, "/ "))
+ return bfd_slurp_armap (abfd);
+
+ /* See if the first element is an armap. */
+ if (! strneq (nextname, ecoff_backend (abfd)->armap_start, ARMAP_START_LENGTH)
+ || 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)
+ || ! strneq (nextname + ARMAP_END_INDEX, ARMAP_END, sizeof ARMAP_END - 1))
+ {
+ 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 == NULL)
+ return FALSE;
+ parsed_size = mapdata->parsed_size;
+ free (mapdata);
+
+ raw_armap = (char *) bfd_alloc (abfd, parsed_size);
+ if (raw_armap == NULL)
+ return FALSE;
+
+ if (bfd_bread ((void *) raw_armap, parsed_size, abfd) != parsed_size)
+ {
+ if (bfd_get_error () != bfd_error_system_call)
+ bfd_set_error (bfd_error_malformed_archive);
+ bfd_release (abfd, (void *) raw_armap);
+ return FALSE;
+ }
+
+ ardata->tdata = (void *) raw_armap;
+
+ count = H_GET_32 (abfd, raw_armap);
+
+ ardata->symdef_count = 0;
+ ardata->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 = H_GET_32 (abfd, raw_ptr);
+ file_offset = H_GET_32 (abfd, (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 (H_GET_32 (abfd, (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 (H_GET_32 (abfd, (raw_ptr + 4)) != 0)
+ ++ardata->symdef_count;
+
+ amt = ardata->symdef_count;
+ amt *= sizeof (carsym);
+ symdef_ptr = (carsym *) bfd_alloc (abfd, amt);
+ if (!symdef_ptr)
+ return FALSE;
+
+ ardata->symdefs = symdef_ptr;
+
+ raw_ptr = raw_armap + 4;
+ for (i = 0; i < count; i++, raw_ptr += 8)
+ {
+ unsigned int name_offset, file_offset;
+
+ file_offset = H_GET_32 (abfd, (raw_ptr + 4));
+ if (file_offset == 0)
+ continue;
+ name_offset = H_GET_32 (abfd, raw_ptr);
+ symdef_ptr->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. */
+
+bfd_boolean
+_bfd_ecoff_write_armap (bfd *abfd,
+ unsigned int elength,
+ struct orl *map,
+ unsigned int orl_count,
+ int stridx)
+{
+ unsigned int hashsize, hashlog;
+ bfd_size_type 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 ((void *) &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);
+ _bfd_ar_spacepad (hdr.ar_date, sizeof (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';
+ /* Building gcc ends up extracting the armap as a file - twice. */
+ hdr.ar_mode[0] = '6';
+ hdr.ar_mode[1] = '4';
+ hdr.ar_mode[2] = '4';
+
+ _bfd_ar_spacepad (hdr.ar_size, sizeof (hdr.ar_size), "%-10ld", 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_bwrite ((void *) &hdr, (bfd_size_type) sizeof (struct ar_hdr), abfd)
+ != sizeof (struct ar_hdr))
+ return FALSE;
+
+ H_PUT_32 (abfd, hashsize, temp);
+ if (bfd_bwrite ((void *) temp, (bfd_size_type) 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 = 0;
+
+ /* Advance firstreal to the file position of this archive
+ element. */
+ if (map[i].u.abfd != last_elt)
+ {
+ do
+ {
+ firstreal += arelt_size (current) + sizeof (struct ar_hdr);
+ firstreal += firstreal % 2;
+ current = current->archive_next;
+ }
+ while (current != map[i].u.abfd);
+ }
+
+ last_elt = current;
+
+ hash = ecoff_armap_hash (*map[i].name, &rehash, hashsize, hashlog);
+ if (H_GET_32 (abfd, (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 (H_GET_32 (abfd, (hashtable + (srch * 8) + 4)) == 0)
+ break;
+
+ BFD_ASSERT (srch != hash);
+
+ hash = srch;
+ }
+
+ H_PUT_32 (abfd, map[i].namidx, (hashtable + hash * 8));
+ H_PUT_32 (abfd, firstreal, (hashtable + hash * 8 + 4));
+ }
+
+ if (bfd_bwrite ((void *) hashtable, symdefsize, abfd) != symdefsize)
+ return FALSE;
+
+ bfd_release (abfd, hashtable);
+
+ /* Now write the strings. */
+ H_PUT_32 (abfd, stringsize, temp);
+ if (bfd_bwrite ((void *) temp, (bfd_size_type) 4, abfd) != 4)
+ return FALSE;
+ for (i = 0; i < orl_count; i++)
+ {
+ bfd_size_type len;
+
+ len = strlen (*map[i].name) + 1;
+ if (bfd_bwrite ((void *) (*map[i].name), 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_bwrite ("", (bfd_size_type) 1, abfd) != 1)
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/* ECOFF linker code. */
+
+/* Routine to create an entry in an ECOFF link hash table. */
+
+static struct bfd_hash_entry *
+ecoff_link_hash_newfunc (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 == NULL)
+ ret = ((struct ecoff_link_hash_entry *)
+ bfd_hash_allocate (table, sizeof (struct ecoff_link_hash_entry)));
+ if (ret == 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 ((void *) &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 (bfd *abfd)
+{
+ struct ecoff_link_hash_table *ret;
+ bfd_size_type amt = sizeof (struct ecoff_link_hash_table);
+
+ ret = (struct ecoff_link_hash_table *) bfd_malloc (amt);
+ if (ret == NULL)
+ return NULL;
+ if (!_bfd_link_hash_table_init (&ret->root, abfd,
+ ecoff_link_hash_newfunc,
+ sizeof (struct ecoff_link_hash_entry)))
+ {
+ free (ret);
+ return 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)))
+
+/* 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))
+
+/* 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 bfd_boolean
+ecoff_link_add_externals (bfd *abfd,
+ struct bfd_link_info *info,
+ void * external_ext,
+ char *ssext)
+{
+ const struct ecoff_backend_data * const backend = ecoff_backend (abfd);
+ void (* const swap_ext_in) (bfd *, void *, EXTR *)
+ = backend->debug_swap.swap_ext_in;
+ bfd_size_type external_ext_size = backend->debug_swap.external_ext_size;
+ unsigned long ext_count;
+ struct bfd_link_hash_entry **sym_hash;
+ char *ext_ptr;
+ char *ext_end;
+ bfd_size_type amt;
+
+ ext_count = ecoff_data (abfd)->debug_info.symbolic_header.iextMax;
+
+ amt = ext_count;
+ amt *= sizeof (struct bfd_link_hash_entry *);
+ sym_hash = (struct bfd_link_hash_entry **) bfd_alloc (abfd, amt);
+ if (!sym_hash)
+ return FALSE;
+ ecoff_data (abfd)->sym_hashes = (struct ecoff_link_hash_entry **) 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;
+ bfd_boolean skip;
+ bfd_vma value;
+ asection *section;
+ const char *name;
+ struct ecoff_link_hash_entry *h;
+
+ *sym_hash = NULL;
+
+ (*swap_ext_in) (abfd, (void *) 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 == NULL)
+ continue;
+
+ name = ssext + esym.asym.iss;
+
+ if (! (_bfd_generic_link_add_one_symbol
+ (info, abfd, name,
+ (flagword) (esym.weakext ? BSF_WEAK : BSF_GLOBAL),
+ section, value, NULL, TRUE, TRUE, sym_hash)))
+ return FALSE;
+
+ h = (struct ecoff_link_hash_entry *) *sym_hash;
+
+ /* If we are building an ECOFF hash table, save the external
+ symbol information. */
+ if (bfd_get_flavour (info->output_bfd) == bfd_get_flavour (abfd))
+ {
+ if (h->abfd == 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
+ && streq (h->root.u.c.p->section->name, SCOMMON))
+ {
+ 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;
+}
+
+/* Add symbols from an ECOFF object file to the global linker hash
+ table. */
+
+static bfd_boolean
+ecoff_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info)
+{
+ HDRR *symhdr;
+ bfd_size_type external_ext_size;
+ void * external_ext = NULL;
+ bfd_size_type esize;
+ char *ssext = NULL;
+ bfd_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 = bfd_malloc (esize);
+ if (external_ext == NULL && esize != 0)
+ goto error_return;
+
+ if (bfd_seek (abfd, (file_ptr) symhdr->cbExtOffset, SEEK_SET) != 0
+ || bfd_bread (external_ext, esize, abfd) != esize)
+ goto error_return;
+
+ ssext = (char *) bfd_malloc ((bfd_size_type) symhdr->issExtMax);
+ if (ssext == NULL && symhdr->issExtMax != 0)
+ goto error_return;
+
+ if (bfd_seek (abfd, (file_ptr) symhdr->cbSsExtOffset, SEEK_SET) != 0
+ || (bfd_bread (ssext, (bfd_size_type) 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;
+}
+
+/* This is called if we used _bfd_generic_link_add_archive_symbols
+ because we were not dealing with an ECOFF archive. */
+
+static bfd_boolean
+ecoff_link_check_archive_element (bfd *abfd,
+ struct bfd_link_info *info,
+ struct bfd_link_hash_entry *h,
+ const char *name,
+ bfd_boolean *pneeded)
+{
+ *pneeded = FALSE;
+
+ /* Unlike the generic linker, we do not pull in elements because
+ of common symbols. */
+ if (h->type != bfd_link_hash_undefined)
+ return TRUE;
+
+ /* Include this element. */
+ if (!(*info->callbacks->add_archive_element) (info, abfd, name, &abfd))
+ return FALSE;
+ *pneeded = TRUE;
+
+ return ecoff_link_add_object_symbols (abfd, info);
+}
+
+/* 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 bfd_boolean
+ecoff_link_add_archive_symbols (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, 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 == NULL)
+ return (_bfd_generic_link_add_archive_symbols
+ (abfd, info, ecoff_link_check_archive_element));
+
+ armap_count = 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 != NULL)
+ {
+ struct bfd_link_hash_entry *h;
+ unsigned int hash, rehash = 0;
+ 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)->u.undef.next;
+ else
+ pundef = &(*pundef)->u.undef.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)->u.undef.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 = H_GET_32 (abfd, hashtable + (hash * 8) + 4);
+ if (file_offset == 0)
+ {
+ /* Nothing in this slot. */
+ pundef = &(*pundef)->u.undef.next;
+ continue;
+ }
+
+ name = stringbase + H_GET_32 (abfd, hashtable + (hash * 8));
+ if (name[0] != h->root.string[0]
+ || ! streq (name, h->root.string))
+ {
+ unsigned int srch;
+ bfd_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 = H_GET_32 (abfd, hashtable + (srch * 8) + 4);
+ if (file_offset == 0)
+ break;
+ name = stringbase + H_GET_32 (abfd, hashtable + (srch * 8));
+ if (name[0] == h->root.string[0]
+ && streq (name, h->root.string))
+ {
+ found = TRUE;
+ break;
+ }
+ }
+
+ if (! found)
+ {
+ pundef = &(*pundef)->u.undef.next;
+ continue;
+ }
+
+ hash = srch;
+ }
+
+ element = (*backend->get_elt_at_filepos) (abfd, (file_ptr) file_offset);
+ if (element == 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, &element))
+ return FALSE;
+ if (! ecoff_link_add_object_symbols (element, info))
+ return FALSE;
+
+ pundef = &(*pundef)->u.undef.next;
+ }
+
+ return TRUE;
+}
+
+/* Given an ECOFF BFD, add symbols to the global hash table as
+ appropriate. */
+
+bfd_boolean
+_bfd_ecoff_bfd_link_add_symbols (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;
+ }
+}
+
+
+/* ECOFF final link routines. */
+
+/* Structure used to pass information to ecoff_link_write_external. */
+
+struct extsym_info
+{
+ bfd *abfd;
+ struct bfd_link_info *info;
+};
+
+/* Accumulate the debugging information for an input BFD into the
+ output BFD. This must read in the symbolic information of the
+ input BFD. */
+
+static bfd_boolean
+ecoff_final_link_debug_accumulate (bfd *output_bfd,
+ bfd *input_bfd,
+ struct bfd_link_info *info,
+ void * 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;
+ bfd_boolean ret;
+
+#define READ(ptr, offset, count, size, type) \
+ if (symhdr->count == 0) \
+ debug->ptr = NULL; \
+ else \
+ { \
+ bfd_size_type amt = (bfd_size_type) size * symhdr->count; \
+ debug->ptr = (type) bfd_malloc (amt); \
+ if (debug->ptr == NULL) \
+ { \
+ ret = FALSE; \
+ goto return_something; \
+ } \
+ if (bfd_seek (input_bfd, (file_ptr) symhdr->offset, SEEK_SET) != 0 \
+ || bfd_bread (debug->ptr, amt, input_bfd) != amt) \
+ { \
+ 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, void *);
+ READ (external_pdr, cbPdOffset, ipdMax, swap->external_pdr_size, void *);
+ READ (external_sym, cbSymOffset, isymMax, swap->external_sym_size, void *);
+ READ (external_opt, cbOptOffset, ioptMax, swap->external_opt_size, void *);
+ 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, void *);
+ READ (external_rfd, cbRfdOffset, crfd, swap->external_rfd_size, void *);
+ }
+#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;
+}
+
+/* Relocate and write an ECOFF section into an ECOFF output file. */
+
+static bfd_boolean
+ecoff_indirect_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;
+ bfd_byte *contents = NULL;
+ bfd_size_type external_reloc_size;
+ bfd_size_type external_relocs_size;
+ void * external_relocs = NULL;
+
+ BFD_ASSERT ((output_section->flags & SEC_HAS_CONTENTS) != 0);
+
+ input_section = link_order->u.indirect.section;
+ input_bfd = input_section->owner;
+ if (input_section->size == 0)
+ return TRUE;
+
+ BFD_ASSERT (input_section->output_section == output_section);
+ BFD_ASSERT (input_section->output_offset == link_order->offset);
+ BFD_ASSERT (input_section->size == link_order->size);
+
+ /* Get the section contents. */
+ if (!bfd_malloc_and_get_section (input_bfd, input_section, &contents))
+ 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;
+
+ external_relocs = bfd_malloc (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_bread (external_relocs, 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,
+ contents,
+ input_section->output_offset,
+ input_section->size))
+ goto error_return;
+
+ /* If we are producing relocatable 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->relocatable)
+ {
+ file_ptr pos = (output_section->rel_filepos
+ + output_section->reloc_count * external_reloc_size);
+ if (bfd_seek (output_bfd, pos, SEEK_SET) != 0
+ || (bfd_bwrite (external_relocs, 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)
+ free (external_relocs);
+ return TRUE;
+
+ error_return:
+ if (contents != NULL)
+ free (contents);
+ if (external_relocs != 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 bfd_boolean
+ecoff_reloc_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;
+ bfd_boolean ok;
+ file_ptr pos;
+
+ 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 = 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;
+
+ size = bfd_get_reloc_size (rel.howto);
+ buf = (bfd_byte *) bfd_zmalloc (size);
+ if (buf == NULL)
+ return FALSE;
+ rstat = _bfd_relocate_contents (rel.howto, output_bfd,
+ (bfd_vma) 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, NULL,
+ (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, NULL,
+ NULL, (bfd_vma) 0)))
+ {
+ free (buf);
+ return FALSE;
+ }
+ break;
+ }
+ ok = bfd_set_section_contents (output_bfd, output_section, (void *) buf,
+ (file_ptr) link_order->offset, size);
+ free (buf);
+ if (! ok)
+ return FALSE;
+ }
+
+ rel.addend = 0;
+
+ /* Move the information into an 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 != NULL
+ && h->indx != -1)
+ in.r_symndx = h->indx;
+ else
+ {
+ if (! ((*info->callbacks->unattached_reloc)
+ (info, link_order->u.reloc.p->u.name, NULL,
+ NULL, (bfd_vma) 0)))
+ return FALSE;
+ in.r_symndx = 0;
+ }
+ in.r_extern = 1;
+ }
+ else
+ {
+ const char *name;
+ unsigned int i;
+ static struct
+ {
+ const char * name;
+ long r_symndx;
+ }
+ section_symndx [] =
+ {
+ { _TEXT, RELOC_SECTION_TEXT },
+ { _RDATA, RELOC_SECTION_RDATA },
+ { _DATA, RELOC_SECTION_DATA },
+ { _SDATA, RELOC_SECTION_SDATA },
+ { _SBSS, RELOC_SECTION_SBSS },
+ { _BSS, RELOC_SECTION_BSS },
+ { _INIT, RELOC_SECTION_INIT },
+ { _LIT8, RELOC_SECTION_LIT8 },
+ { _LIT4, RELOC_SECTION_LIT4 },
+ { _XDATA, RELOC_SECTION_XDATA },
+ { _PDATA, RELOC_SECTION_PDATA },
+ { _FINI, RELOC_SECTION_FINI },
+ { _LITA, RELOC_SECTION_LITA },
+ { "*ABS*", RELOC_SECTION_ABS },
+ { _RCONST, RELOC_SECTION_RCONST }
+ };
+
+ name = bfd_get_section_name (output_bfd, section);
+
+ for (i = 0; i < ARRAY_SIZE (section_symndx); i++)
+ if (streq (name, section_symndx[i].name))
+ {
+ in.r_symndx = section_symndx[i].r_symndx;
+ break;
+ }
+
+ if (i == ARRAY_SIZE (section_symndx))
+ 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 (external_reloc_size);
+ if (rbuf == NULL)
+ return FALSE;
+
+ (*ecoff_backend (output_bfd)->swap_reloc_out) (output_bfd, &in, (void *) rbuf);
+
+ pos = (output_section->rel_filepos
+ + output_section->reloc_count * external_reloc_size);
+ ok = (bfd_seek (output_bfd, pos, SEEK_SET) == 0
+ && (bfd_bwrite ((void *) rbuf, external_reloc_size, output_bfd)
+ == external_reloc_size));
+
+ if (ok)
+ ++output_section->reloc_count;
+
+ free (rbuf);
+
+ return ok;
+}
+
+/* Put out information for an external symbol. These come only from
+ the hash table. */
+
+static bfd_boolean
+ecoff_link_write_external (struct bfd_hash_entry *bh, void * data)
+{
+ struct ecoff_link_hash_entry *h = (struct ecoff_link_hash_entry *) bh;
+ struct extsym_info *einfo = (struct extsym_info *) data;
+ bfd *output_bfd = einfo->abfd;
+ bfd_boolean strip;
+
+ if (h->root.type == bfd_link_hash_warning)
+ {
+ h = (struct ecoff_link_hash_entry *) h->root.u.i.link;
+ if (h->root.type == bfd_link_hash_new)
+ return TRUE;
+ }
+
+ /* 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 == 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;
+ unsigned int i;
+ static struct
+ {
+ const char * name;
+ int sc;
+ }
+ section_storage_classes [] =
+ {
+ { _TEXT, scText },
+ { _DATA, scData },
+ { _SDATA, scSData },
+ { _RDATA, scRData },
+ { _BSS, scBss },
+ { _SBSS, scSBss },
+ { _INIT, scInit },
+ { _FINI, scFini },
+ { _PDATA, scPData },
+ { _XDATA, scXData },
+ { _RCONST, scRConst }
+ };
+
+ output_section = h->root.u.def.section->output_section;
+ name = bfd_section_name (output_section->owner, output_section);
+
+ for (i = 0; i < ARRAY_SIZE (section_storage_classes); i++)
+ if (streq (name, section_storage_classes[i].name))
+ {
+ h->esym.asym.sc = section_storage_classes[i].sc;
+ break;
+ }
+
+ if (i == ARRAY_SIZE (section_storage_classes))
+ 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_warning:
+ 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:
+ /* We ignore these symbols, since the indirected symbol is
+ already in the hash table. */
+ 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));
+}
+
+/* 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. */
+
+bfd_boolean
+_bfd_ecoff_bfd_final_link (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;
+ void * handle;
+ 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 == NULL)
+ return FALSE;
+
+ /* Accumulate the debugging symbols from each input BFD. */
+ for (input_bfd = info->input_bfds;
+ input_bfd != NULL;
+ input_bfd = input_bfd->link.next)
+ {
+ bfd_boolean ret;
+
+ if (bfd_get_flavour (input_bfd) == bfd_target_ecoff_flavour)
+ {
+ /* Arbitrarily 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;
+ bfd_hash_traverse (&info->hash->table, ecoff_link_write_external, &einfo);
+
+ if (info->relocatable)
+ {
+ /* 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 != NULL; o = o->next)
+ {
+ o->reloc_count = 0;
+ for (p = o->map_head.link_order;
+ p != 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->relocatable)
+ {
+ /* 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 != 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 != 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->relocatable)
+ {
+ bfd_vma lo;
+
+ /* Make up a value. */
+ lo = (bfd_vma) -1;
+ for (o = abfd->sections; o != NULL; o = o->next)
+ {
+ if (o->vma < lo
+ && (streq (o->name, _SBSS)
+ || streq (o->name, _SDATA)
+ || streq (o->name, _LIT4)
+ || streq (o->name, _LIT8)
+ || streq (o->name, _LITA)))
+ 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 != NULL; o = o->next)
+ {
+ for (p = o->map_head.link_order;
+ p != 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;
+}
diff --git a/bfd/ecofflink.c b/bfd/ecofflink.c
new file mode 100644
index 0000000..33cdffd
--- /dev/null
+++ b/bfd/ecofflink.c
@@ -0,0 +1,2477 @@
+/* Routines to link ECOFF debugging information.
+ Copyright (C) 1993-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.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"
+
+/* 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 (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 (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 (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 (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 bfd_boolean
+ecoff_add_bytes (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, (bfd_size_type) 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 (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. */
+ bfd_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. */
+ void * 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 bfd_boolean
+add_file_shuffle (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 bfd_boolean
+add_memory_shuffle (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 = 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. */
+
+void *
+bfd_ecoff_debug_init (bfd *output_bfd ATTRIBUTE_UNUSED,
+ struct ecoff_debug_info *output_debug,
+ const struct ecoff_debug_swap *output_swap ATTRIBUTE_UNUSED,
+ struct bfd_link_info *info)
+{
+ struct accumulate *ainfo;
+ bfd_size_type amt = sizeof (struct accumulate);
+
+ ainfo = (struct accumulate *) bfd_malloc (amt);
+ if (!ainfo)
+ return NULL;
+ if (!bfd_hash_table_init_n (&ainfo->fdr_hash.table, string_hash_newfunc,
+ sizeof (struct string_hash_entry), 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->relocatable)
+ {
+ if (!bfd_hash_table_init (&ainfo->str_hash.table, string_hash_newfunc,
+ sizeof (struct string_hash_entry)))
+ 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 ainfo;
+}
+
+/* Free the accumulated debugging information. */
+
+void
+bfd_ecoff_debug_free (void * handle,
+ bfd *output_bfd ATTRIBUTE_UNUSED,
+ struct ecoff_debug_info *output_debug ATTRIBUTE_UNUSED,
+ const struct ecoff_debug_swap *output_swap ATTRIBUTE_UNUSED,
+ struct bfd_link_info *info)
+{
+ struct accumulate *ainfo = (struct accumulate *) handle;
+
+ bfd_hash_table_free (&ainfo->fdr_hash.table);
+
+ if (! info->relocatable)
+ 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. */
+
+bfd_boolean
+bfd_ecoff_debug_accumulate (void * 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) (bfd *, void *, SYMR *)
+ = input_swap->swap_sym_in;
+ void (* const swap_rfd_in) (bfd *, void *, RFDT *)
+ = input_swap->swap_rfd_in;
+ void (* const swap_sym_out) (bfd *, const SYMR *, void *)
+ = output_swap->swap_sym_out;
+ void (* const swap_fdr_out) (bfd *, const FDR *, void *)
+ = output_swap->swap_fdr_out;
+ void (* const swap_rfd_out) (bfd *, const RFDT *, void *)
+ = 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;
+ bfd_size_type amt;
+
+ /* Use section_adjust to hold the value to add to a symbol in a
+ particular section. */
+ memset (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;
+
+ amt = input_symhdr->ifdMax;
+ amt *= sizeof (RFDT);
+ input_debug->ifdmap = (RFDT *) bfd_alloc (input_bfd, amt);
+
+ 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, 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 ((bfd_size_type) strlen (name) + 20);
+ if (lookup == NULL)
+ return FALSE;
+ sprintf (lookup, "%s %lx %lx", name, (unsigned long) fdr.csym,
+ (unsigned long) 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, 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, 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, rfd_in, &rfd);
+ BFD_ASSERT (rfd >= 0 && rfd < input_symhdr->ifdMax);
+ rfd = input_debug->ifdmap[rfd];
+ (*swap_rfd_out) (output_bfd, &rfd, 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_byte *sym_out;
+ bfd_byte *lraw_src;
+ bfd_byte *lraw_end;
+ bfd_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, fdr_ptr, &fdr);
+
+ /* 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, 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:
+ 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 relocatable link because it would
+ prevent us from easily merging different FDR's. */
+ if (! info->relocatable)
+ {
+ bfd_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)
+ {
+ file_ptr pos = input_symhdr->cbLineOffset + fdr.cbLineOffset;
+ if (!add_file_shuffle (ainfo, &ainfo->line, &ainfo->line_end,
+ input_bfd, pos, (unsigned long) 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)
+ {
+ file_ptr pos = (input_symhdr->cbAuxOffset
+ + fdr.iauxBase * sizeof (union aux_ext));
+ if (!add_file_shuffle (ainfo, &ainfo->aux, &ainfo->aux_end,
+ input_bfd, pos,
+ fdr.caux * sizeof (union aux_ext)))
+ return FALSE;
+ fdr.iauxBase = output_symhdr->iauxMax;
+ output_symhdr->iauxMax += fdr.caux;
+ }
+ if (! info->relocatable)
+ {
+
+ /* 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)
+ {
+ file_ptr pos = input_symhdr->cbSsOffset + fdr.issBase;
+ if (!add_file_shuffle (ainfo, &ainfo->ss, &ainfo->ss_end,
+ input_bfd, pos, (unsigned long) 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)
+ {
+ /* 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)
+ {
+ file_ptr pos = (input_symhdr->cbPdOffset
+ + fdr.ipdFirst * external_pdr_size);
+ unsigned long size = fdr.cpd * external_pdr_size;
+ if (!add_file_shuffle (ainfo, &ainfo->pdr, &ainfo->pdr_end,
+ input_bfd, pos, size))
+ return FALSE;
+ }
+ BFD_ASSERT (external_opt_size == input_swap->external_opt_size);
+ if (fdr.copt > 0)
+ {
+ file_ptr pos = (input_symhdr->cbOptOffset
+ + fdr.ioptBase * external_opt_size);
+ unsigned long size = fdr.copt * external_opt_size;
+ if (!add_file_shuffle (ainfo, &ainfo->opt, &ainfo->opt_end,
+ input_bfd, pos, 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, in, &pdr);
+ (*output_swap->swap_pdr_out) (output_bfd, &pdr, 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, in, &opt);
+ (*output_swap->swap_opt_out) (output_bfd, &opt, 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 (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->relocatable)
+ {
+ if (!add_memory_shuffle (ainfo, &ainfo->ss, &ainfo->ss_end,
+ (bfd_byte *) 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. */
+
+bfd_boolean
+bfd_ecoff_debug_accumulate_other (void * 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) (bfd *, const SYMR *, void *)
+ = 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;
+ void * external_fdr;
+
+ memset (&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,
+ input_bfd->filename);
+ 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, (bfd_size_type) 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;
+ void * external_sym;
+
+ if (((*sym_ptr)->flags & BSF_EXPORT) != 0)
+ continue;
+ memset (&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 = 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,
+ (bfd_byte *) external_sym,
+ (unsigned long) output_swap->external_sym_size);
+ ++fdr.csym;
+ ++output_symhdr->isymMax;
+ }
+
+ bfd_release (output_bfd, 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 = 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,
+ (bfd_byte *) external_fdr,
+ (unsigned long) 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. */
+
+bfd_boolean
+bfd_ecoff_debug_externals (bfd *abfd,
+ struct ecoff_debug_info *debug,
+ const struct ecoff_debug_swap *swap,
+ bfd_boolean relocatable,
+ bfd_boolean (*get_extr) (asymbol *, EXTR *),
+ void (*set_index) (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))
+ continue;
+
+ /* If we're producing an executable, move common symbols into
+ bss. */
+ if (! relocatable)
+ {
+ 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. */
+
+bfd_boolean
+bfd_ecoff_debug_one_external (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) (bfd *, const EXTR *, void *)
+ = 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))
+ return FALSE;
+ }
+ if ((size_t) ((char *) debug->external_ext_end
+ - (char *) debug->external_ext)
+ < (symhdr->iextMax + 1) * external_ext_size)
+ {
+ char *external_ext = (char *) debug->external_ext;
+ char *external_ext_end = (char *) debug->external_ext_end;
+ if (! ecoff_add_bytes ((char **) &external_ext,
+ (char **) &external_ext_end,
+ (symhdr->iextMax + 1) * (size_t) external_ext_size))
+ return FALSE;
+ debug->external_ext = external_ext;
+ debug->external_ext_end = external_ext_end;
+ }
+
+ 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. */
+
+static void
+ecoff_align_debug (bfd *abfd ATTRIBUTE_UNUSED,
+ 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 ((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 ((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 ((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 ((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 != NULL)
+ memset (((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 (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 bfd_boolean
+ecoff_write_symhdr (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 = (char *) bfd_malloc (swap->external_hdr_size);
+ if (buff == NULL && swap->external_hdr_size != 0)
+ goto error_return;
+
+ (*swap->swap_hdr_out) (abfd, symhdr, buff);
+ if (bfd_bwrite (buff, 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. */
+
+bfd_boolean
+bfd_ecoff_write_debug (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_bwrite (debug->ptr, (bfd_size_type) 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, (bfd_size_type) 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 bfd_boolean
+ecoff_write_shuffle (bfd *abfd,
+ const struct ecoff_debug_swap *swap,
+ struct shuffle *shuffle,
+ void * space)
+{
+ struct shuffle *l;
+ unsigned long total;
+
+ total = 0;
+ for (l = shuffle; l != (struct shuffle *) NULL; l = l->next)
+ {
+ if (! l->filep)
+ {
+ if (bfd_bwrite (l->u.memory, (bfd_size_type) l->size, abfd)
+ != l->size)
+ return FALSE;
+ }
+ else
+ {
+ if (bfd_seek (l->u.file.input_bfd, l->u.file.offset, SEEK_SET) != 0
+ || bfd_bread (space, (bfd_size_type) l->size,
+ l->u.file.input_bfd) != l->size
+ || bfd_bwrite (space, (bfd_size_type) 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_zmalloc ((bfd_size_type) i);
+ if (s == NULL && i != 0)
+ return FALSE;
+
+ if (bfd_bwrite (s, (bfd_size_type) i, abfd) != i)
+ {
+ free (s);
+ return FALSE;
+ }
+ free (s);
+ }
+
+ return TRUE;
+}
+
+/* Write out debugging information using accumulated linker
+ information. */
+
+bfd_boolean
+bfd_ecoff_write_accumulated_debug (void * 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;
+ void * space = NULL;
+ bfd_size_type amt;
+
+ if (! ecoff_write_symhdr (abfd, debug, swap, where))
+ goto error_return;
+
+ amt = ainfo->largest_file_shuffle;
+ space = bfd_malloc (amt);
+ 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->relocatable)
+ {
+ 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_bwrite (&null, (bfd_size_type) 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);
+ amt = len + 1;
+ if (bfd_bwrite (sh->root.string, amt, abfd) != amt)
+ 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_zmalloc ((bfd_size_type) i);
+ if (s == NULL && i != 0)
+ goto error_return;
+
+ if (bfd_bwrite (s, (bfd_size_type) 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. */
+ amt = debug->symbolic_header.issExtMax;
+ if (bfd_bwrite (debug->ssext, amt, abfd) != amt)
+ 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_zmalloc ((bfd_size_type) i);
+ if (s == NULL && i != 0)
+ goto error_return;
+
+ if (bfd_bwrite (s, (bfd_size_type) 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)));
+
+ amt = debug->symbolic_header.iextMax * swap->external_ext_size;
+ if (bfd_bwrite (debug->external_ext, amt, abfd) != amt)
+ 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 (const void * leftp, const void * 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 bfd_boolean
+mk_fdrtab (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;
+ bfd_boolean stabs;
+ long len;
+ bfd_size_type amt;
+
+ 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. */
+ amt = (bfd_size_type) len * sizeof (struct ecoff_fdrtab_entry);
+ line_info->fdrtab = (struct ecoff_fdrtab_entry*) bfd_zalloc (abfd, amt);
+ 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)
+ {
+ /* eraxxon: There are at least two problems with this computation:
+ 1) PDRs do *not* contain offsets but full vma's; and typically the
+ address of the first PDR is the address of the FDR, which will
+ make (most) of the results of the original computation 0!
+ 2) Once in a wacky while, the Compaq compiler generated PDR
+ addresses do not equal the FDR vma, but they (the PDR address)
+ are still vma's and not offsets. Cf. comments in
+ 'lookup_line'. */
+ /* 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;
+ }
+ 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 (line_info->fdrtab, (size_t) len,
+ sizeof (struct ecoff_fdrtab_entry), cmp_fdrtab_entry);
+
+ return TRUE;
+}
+
+/* Return index of first FDR that covers to OFFSET. */
+
+static long
+fdrtab_lookup (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;
+ }
+
+ /* eraxxon: at this point 'offset' is either lower than the lowest entry or
+ higher than the highest entry. In the former case high = low = mid = 0;
+ we want to return -1. In the latter case, low = high and mid = low - 1;
+ we want to return the index of the highest entry. Only in former case
+ will the following 'catch-all' test be true. */
+ ++mid;
+
+ /* Last entry is catch-all for all higher addresses. */
+ if (offset < tab[mid].base_addr)
+ return -1;
+
+ find_min:
+
+ /* eraxxon: There may be multiple FDRs in the table with the
+ same base_addr; make sure that we are at the first one. */
+ 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 bfd_boolean
+lookup_line (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;
+ bfd_boolean stabs;
+ FDR *fdr_ptr;
+ int i;
+
+ /* eraxxon: note that 'offset' is the full vma, not a section offset. */
+ 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... */
+
+ /* eraxxon: 'fdrtab_lookup' doesn't give what we want, at least for Compaq's
+ C++ compiler 6.2. Consider three FDRs with starting addresses of x, y,
+ and z, respectively, such that x < y < z. Assume further that
+ y < 'offset' < z. It is possible at times that the PDR for 'offset' is
+ associated with FDR x and *not* with FDR y. Erg!!
+
+ From a binary dump of my C++ test case 'moo' using Compaq's coffobjanl
+ (output format has been edited for our purposes):
+
+ FDR [2]: (main.C): First instruction: 0x12000207c <x>
+ PDR [5] for File [2]: LoopTest__Xv <0x1200020a0> (a)
+ PDR [7] for File [2]: foo__Xv <0x120002168>
+ FDR [1]: (-1): First instruction: 0x1200020e8 <y>
+ PDR [3] for File [1]: <0x120001ad0> (b)
+ FDR [6]: (-1): First instruction: 0x1200026f0 <z>
+
+ (a) In the case of PDR5, the vma is such that the first few instructions
+ of the procedure can be found. But since the size of this procedure is
+ 160b, the vma will soon cross into the 'address space' of FDR1 and no
+ debugging info will be found. How repugnant!
+
+ (b) It is also possible for a PDR to have a *lower* vma than its associated
+ FDR; see FDR1 and PDR3. Gross!
+
+ Since the FDRs that are causing so much havok (in this case) 1) do not
+ describe actual files (fdr.rss == -1), and 2) contain only compiler
+ generated routines, I thought a simple fix would be to exclude them from
+ the FDR table in 'mk_fdrtab'. But, besides not knowing for certain
+ whether this would be correct, it creates an additional problem. If we
+ happen to ask for source file info on a compiler generated (procedure)
+ symbol -- which is still in the symbol table -- the result can be
+ information from a real procedure! This is because compiler generated
+ procedures with vma's higher than the last FDR in the fdr table will be
+ associated with a PDR from this FDR, specifically the PDR with the
+ highest vma. This wasn't a problem before, because each procedure had a
+ PDR. (Yes, this problem could be eliminated if we kept the size of the
+ last PDR around, but things are already getting ugly).
+
+ Probably, a better solution would be to have a sorted PDR table. Each
+ PDR would have a pointer to its FDR so file information could still be
+ obtained. A FDR table could still be constructed if necessary -- since
+ it only contains pointers, not much extra memory would be used -- but
+ the PDR table would be searched to locate debugging info.
+
+ There is still at least one remaining issue. Sometimes a FDR can have a
+ bogus name, but contain PDRs that should belong to another FDR with a
+ real name. E.g:
+
+ FDR [3]: 0000000120001b50 (/home/.../Array.H~alt~deccxx_5E5A62AD)
+ PDR [a] for File [3]: 0000000120001b50
+ PDR [b] for File [3]: 0000000120001cf0
+ PDR [c] for File [3]: 0000000120001dc8
+ PDR [d] for File [3]: 0000000120001e40
+ PDR [e] for File [3]: 0000000120001eb8
+ PDR [f] for File [3]: 0000000120001f4c
+ FDR [4]: 0000000120001b50 (/home/.../Array.H)
+
+ Here, FDR4 has the correct name, but should (seemingly) contain PDRa-f.
+ The symbol table for PDR4 does contain symbols for PDRa-f, but so does
+ the symbol table for FDR3. However the former is different; perhaps this
+ can be detected easily. (I'm not sure at this point.) This problem only
+ seems to be associated with files with templates. I am assuming the idea
+ is that there is a 'fake' FDR (with PDRs) for each differently typed set
+ of templates that must be generated. Currently, FDR4 is completely
+ excluded from the FDR table in 'mk_fdrtab' because it contains no PDRs.
+
+ Since I don't have time to prepare a real fix for this right now, be
+ prepared for 'A Horrible Hack' to force the inspection of all non-stabs
+ FDRs. It's coming... */
+ 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_signed_vma best_dist = -1;
+ 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;
+
+ /* eraxxon: The Horrible Hack: Because of the problems above, set 'i'
+ to 0 so we look through all FDRs.
+
+ Because FDR's without any symbols are assumed to be non-stabs,
+ searching through all FDRs may cause the following code to try to
+ read stabs FDRs as ECOFF ones. However, I don't think this will
+ harm anything. */
+ i = 0;
+
+ /* 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
+ {
+ /* eraxxon: 'dist' and 'min_dist' can be negative now
+ because we iterate over every FDR rather than just ones
+ with a base address less than or equal to 'offset'. */
+ bfd_signed_vma dist = -1, min_dist = -1;
+ 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, 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, pdr_ptr, &pdr)))
+ {
+ if (offset >= (pdr.adr - 0x10 * pdr.prof))
+ {
+ dist = offset - (pdr.adr - 0x10 * pdr.prof);
+
+ /* eraxxon: 'dist' can be negative now. Note that
+ 'min_dist' can be negative if 'pdr_hold' below is NULL. */
+ if (!pdr_hold || (dist >= 0 && dist < min_dist))
+ {
+ min_dist = dist;
+ pdr_hold = pdr_ptr;
+ }
+ }
+ }
+
+ if (!best_pdr || (min_dist >= 0 && min_dist < best_dist))
+ {
+ best_dist = (bfd_vma) min_dist;
+ best_fdr = fdr_ptr;
+ best_pdr = pdr_hold;
+ }
+ /* Continue looping until base_addr of next entry is different. */
+ }
+ /* eraxxon: We want to iterate over all FDRs.
+ See previous comment about 'fdrtab_lookup'. */
+ while (++i < line_info->fdrtab_len);
+
+ 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, 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;
+ bfd_boolean past_line;
+ bfd_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 ((bfd_size_type) 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. */
+
+bfd_boolean
+_bfd_ecoff_locate_line (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 bfd_boolean
+ecoff_collect_shuffle (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_bread (buff, (bfd_size_type) 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. */
+
+bfd_boolean
+_bfd_ecoff_get_accumulated_pdr (void * handle,
+ bfd_byte *buff)
+{
+ struct accumulate *ainfo = (struct accumulate *) handle;
+
+ return ecoff_collect_shuffle (ainfo->pdr, buff);
+}
+
+/* Copy symbol information into a memory buffer. */
+
+bfd_boolean
+_bfd_ecoff_get_accumulated_sym (void * 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. */
+
+bfd_boolean
+_bfd_ecoff_get_accumulated_ss (void * 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, 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 0000000..e567fa9
--- /dev/null
+++ b/bfd/ecoffswap.h
@@ -0,0 +1,772 @@
+/* Generic ECOFF swapping routines, for BFD.
+ Copyright (C) 1992-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, 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, ECOFF_64,
+ ECOFF_SIGNED_32 or ECOFF_SIGNED_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 H_GET_32
+#define ECOFF_PUT_OFF H_PUT_32
+#endif
+#ifdef ECOFF_64
+#define ECOFF_GET_OFF H_GET_64
+#define ECOFF_PUT_OFF H_PUT_64
+#endif
+#ifdef ECOFF_SIGNED_32
+#define ECOFF_GET_OFF H_GET_S32
+#define ECOFF_PUT_OFF H_PUT_S32
+#endif
+#ifdef ECOFF_SIGNED_64
+#define ECOFF_GET_OFF H_GET_S64
+#define ECOFF_PUT_OFF H_PUT_S64
+#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
+ (int, const struct tir_ext *, TIR *);
+extern void _bfd_ecoff_swap_tir_out
+ (int, const TIR *, struct tir_ext *);
+extern void _bfd_ecoff_swap_rndx_in
+ (int, const struct rndx_ext *, RNDXR *);
+extern void _bfd_ecoff_swap_rndx_out
+ (int, const RNDXR *, struct rndx_ext *);
+
+/* Prototypes for functions defined in this file. */
+
+static void ecoff_swap_hdr_in (bfd *, void *, HDRR *);
+static void ecoff_swap_hdr_out (bfd *, const HDRR *, void *);
+static void ecoff_swap_fdr_in (bfd *, void *, FDR *);
+static void ecoff_swap_fdr_out (bfd *, const FDR *, void *);
+static void ecoff_swap_pdr_in (bfd *, void *, PDR *);
+static void ecoff_swap_pdr_out (bfd *, const PDR *, void *);
+static void ecoff_swap_sym_in (bfd *, void *, SYMR *);
+static void ecoff_swap_sym_out (bfd *, const SYMR *, void *);
+static void ecoff_swap_ext_in (bfd *, void *, EXTR *);
+static void ecoff_swap_ext_out (bfd *, const EXTR *, void *);
+static void ecoff_swap_rfd_in (bfd *, void *, RFDT *);
+static void ecoff_swap_rfd_out (bfd *, const RFDT *, void *);
+static void ecoff_swap_opt_in (bfd *, void *, OPTR *);
+static void ecoff_swap_opt_out (bfd *, const OPTR *, void *);
+static void ecoff_swap_dnr_in (bfd *, void *, DNR *);
+static void ecoff_swap_dnr_out (bfd *, const DNR *, void *);
+
+/* Swap in the symbolic header. */
+
+static void
+ecoff_swap_hdr_in (bfd *abfd, void * ext_copy, HDRR *intern)
+{
+ struct hdr_ext ext[1];
+
+ *ext = *(struct hdr_ext *) ext_copy;
+
+ intern->magic = H_GET_S16 (abfd, ext->h_magic);
+ intern->vstamp = H_GET_S16 (abfd, ext->h_vstamp);
+ intern->ilineMax = H_GET_32 (abfd, ext->h_ilineMax);
+ intern->cbLine = ECOFF_GET_OFF (abfd, ext->h_cbLine);
+ intern->cbLineOffset = ECOFF_GET_OFF (abfd, ext->h_cbLineOffset);
+ intern->idnMax = H_GET_32 (abfd, ext->h_idnMax);
+ intern->cbDnOffset = ECOFF_GET_OFF (abfd, ext->h_cbDnOffset);
+ intern->ipdMax = H_GET_32 (abfd, ext->h_ipdMax);
+ intern->cbPdOffset = ECOFF_GET_OFF (abfd, ext->h_cbPdOffset);
+ intern->isymMax = H_GET_32 (abfd, ext->h_isymMax);
+ intern->cbSymOffset = ECOFF_GET_OFF (abfd, ext->h_cbSymOffset);
+ intern->ioptMax = H_GET_32 (abfd, ext->h_ioptMax);
+ intern->cbOptOffset = ECOFF_GET_OFF (abfd, ext->h_cbOptOffset);
+ intern->iauxMax = H_GET_32 (abfd, ext->h_iauxMax);
+ intern->cbAuxOffset = ECOFF_GET_OFF (abfd, ext->h_cbAuxOffset);
+ intern->issMax = H_GET_32 (abfd, ext->h_issMax);
+ intern->cbSsOffset = ECOFF_GET_OFF (abfd, ext->h_cbSsOffset);
+ intern->issExtMax = H_GET_32 (abfd, ext->h_issExtMax);
+ intern->cbSsExtOffset = ECOFF_GET_OFF (abfd, ext->h_cbSsExtOffset);
+ intern->ifdMax = H_GET_32 (abfd, ext->h_ifdMax);
+ intern->cbFdOffset = ECOFF_GET_OFF (abfd, ext->h_cbFdOffset);
+ intern->crfd = H_GET_32 (abfd, ext->h_crfd);
+ intern->cbRfdOffset = ECOFF_GET_OFF (abfd, ext->h_cbRfdOffset);
+ intern->iextMax = H_GET_32 (abfd, ext->h_iextMax);
+ intern->cbExtOffset = ECOFF_GET_OFF (abfd, 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 (bfd *abfd, const HDRR *intern_copy, void * ext_ptr)
+{
+ struct hdr_ext *ext = (struct hdr_ext *) ext_ptr;
+ HDRR intern[1];
+
+ *intern = *intern_copy;
+
+ H_PUT_S16 (abfd, intern->magic, ext->h_magic);
+ H_PUT_S16 (abfd, intern->vstamp, ext->h_vstamp);
+ H_PUT_32 (abfd, intern->ilineMax, ext->h_ilineMax);
+ ECOFF_PUT_OFF (abfd, intern->cbLine, ext->h_cbLine);
+ ECOFF_PUT_OFF (abfd, intern->cbLineOffset, ext->h_cbLineOffset);
+ H_PUT_32 (abfd, intern->idnMax, ext->h_idnMax);
+ ECOFF_PUT_OFF (abfd, intern->cbDnOffset, ext->h_cbDnOffset);
+ H_PUT_32 (abfd, intern->ipdMax, ext->h_ipdMax);
+ ECOFF_PUT_OFF (abfd, intern->cbPdOffset, ext->h_cbPdOffset);
+ H_PUT_32 (abfd, intern->isymMax, ext->h_isymMax);
+ ECOFF_PUT_OFF (abfd, intern->cbSymOffset, ext->h_cbSymOffset);
+ H_PUT_32 (abfd, intern->ioptMax, ext->h_ioptMax);
+ ECOFF_PUT_OFF (abfd, intern->cbOptOffset, ext->h_cbOptOffset);
+ H_PUT_32 (abfd, intern->iauxMax, ext->h_iauxMax);
+ ECOFF_PUT_OFF (abfd, intern->cbAuxOffset, ext->h_cbAuxOffset);
+ H_PUT_32 (abfd, intern->issMax, ext->h_issMax);
+ ECOFF_PUT_OFF (abfd, intern->cbSsOffset, ext->h_cbSsOffset);
+ H_PUT_32 (abfd, intern->issExtMax, ext->h_issExtMax);
+ ECOFF_PUT_OFF (abfd, intern->cbSsExtOffset, ext->h_cbSsExtOffset);
+ H_PUT_32 (abfd, intern->ifdMax, ext->h_ifdMax);
+ ECOFF_PUT_OFF (abfd, intern->cbFdOffset, ext->h_cbFdOffset);
+ H_PUT_32 (abfd, intern->crfd, ext->h_crfd);
+ ECOFF_PUT_OFF (abfd, intern->cbRfdOffset, ext->h_cbRfdOffset);
+ H_PUT_32 (abfd, intern->iextMax, ext->h_iextMax);
+ ECOFF_PUT_OFF (abfd, intern->cbExtOffset, 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 (bfd *abfd, void * ext_copy, FDR *intern)
+{
+ struct fdr_ext ext[1];
+
+ *ext = *(struct fdr_ext *) ext_copy;
+
+ intern->adr = ECOFF_GET_OFF (abfd, ext->f_adr);
+ intern->rss = H_GET_32 (abfd, ext->f_rss);
+#if defined (ECOFF_64) || defined (ECOFF_SIGNED_64)
+ if (intern->rss == (signed long) 0xffffffff)
+ intern->rss = -1;
+#endif
+ intern->issBase = H_GET_32 (abfd, ext->f_issBase);
+ intern->cbSs = ECOFF_GET_OFF (abfd, ext->f_cbSs);
+ intern->isymBase = H_GET_32 (abfd, ext->f_isymBase);
+ intern->csym = H_GET_32 (abfd, ext->f_csym);
+ intern->ilineBase = H_GET_32 (abfd, ext->f_ilineBase);
+ intern->cline = H_GET_32 (abfd, ext->f_cline);
+ intern->ioptBase = H_GET_32 (abfd, ext->f_ioptBase);
+ intern->copt = H_GET_32 (abfd, ext->f_copt);
+#if defined (ECOFF_32) || defined (ECOFF_SIGNED_32)
+ intern->ipdFirst = H_GET_16 (abfd, ext->f_ipdFirst);
+ intern->cpd = H_GET_16 (abfd, ext->f_cpd);
+#endif
+#if defined (ECOFF_64) || defined (ECOFF_SIGNED_64)
+ intern->ipdFirst = H_GET_32 (abfd, ext->f_ipdFirst);
+ intern->cpd = H_GET_32 (abfd, ext->f_cpd);
+#endif
+ intern->iauxBase = H_GET_32 (abfd, ext->f_iauxBase);
+ intern->caux = H_GET_32 (abfd, ext->f_caux);
+ intern->rfdBase = H_GET_32 (abfd, ext->f_rfdBase);
+ intern->crfd = H_GET_32 (abfd, 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, ext->f_cbLineOffset);
+ intern->cbLine = ECOFF_GET_OFF (abfd, 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 (bfd *abfd, const FDR *intern_copy, void * ext_ptr)
+{
+ struct fdr_ext *ext = (struct fdr_ext *) ext_ptr;
+ FDR intern[1];
+
+ /* Make it reasonable to do in-place. */
+ *intern = *intern_copy;
+
+ ECOFF_PUT_OFF (abfd, intern->adr, ext->f_adr);
+ H_PUT_32 (abfd, intern->rss, ext->f_rss);
+ H_PUT_32 (abfd, intern->issBase, ext->f_issBase);
+ ECOFF_PUT_OFF (abfd, intern->cbSs, ext->f_cbSs);
+ H_PUT_32 (abfd, intern->isymBase, ext->f_isymBase);
+ H_PUT_32 (abfd, intern->csym, ext->f_csym);
+ H_PUT_32 (abfd, intern->ilineBase, ext->f_ilineBase);
+ H_PUT_32 (abfd, intern->cline, ext->f_cline);
+ H_PUT_32 (abfd, intern->ioptBase, ext->f_ioptBase);
+ H_PUT_32 (abfd, intern->copt, ext->f_copt);
+#if defined (ECOFF_32) || defined (ECOFF_SIGNED_32)
+ H_PUT_16 (abfd, intern->ipdFirst, ext->f_ipdFirst);
+ H_PUT_16 (abfd, intern->cpd, ext->f_cpd);
+#endif
+#if defined (ECOFF_64) || defined (ECOFF_SIGNED_64)
+ H_PUT_32 (abfd, intern->ipdFirst, ext->f_ipdFirst);
+ H_PUT_32 (abfd, intern->cpd, ext->f_cpd);
+#endif
+ H_PUT_32 (abfd, intern->iauxBase, ext->f_iauxBase);
+ H_PUT_32 (abfd, intern->caux, ext->f_caux);
+ H_PUT_32 (abfd, intern->rfdBase, ext->f_rfdBase);
+ H_PUT_32 (abfd, intern->crfd, 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, ext->f_cbLineOffset);
+ ECOFF_PUT_OFF (abfd, intern->cbLine, ext->f_cbLine);
+
+#ifdef TEST
+ if (memcmp ((char *) ext, (char *) intern, sizeof (*intern)) != 0)
+ abort ();
+#endif
+}
+
+/* Swap in the procedure descriptor record. */
+
+static void
+ecoff_swap_pdr_in (bfd *abfd, void * ext_copy, PDR *intern)
+{
+ struct pdr_ext ext[1];
+
+ *ext = *(struct pdr_ext *) ext_copy;
+
+ memset ((void *) intern, 0, sizeof (*intern));
+
+ intern->adr = ECOFF_GET_OFF (abfd, ext->p_adr);
+ intern->isym = H_GET_32 (abfd, ext->p_isym);
+ intern->iline = H_GET_32 (abfd, ext->p_iline);
+ intern->regmask = H_GET_32 (abfd, ext->p_regmask);
+ intern->regoffset = H_GET_S32 (abfd, ext->p_regoffset);
+ intern->iopt = H_GET_S32 (abfd, ext->p_iopt);
+ intern->fregmask = H_GET_32 (abfd, ext->p_fregmask);
+ intern->fregoffset = H_GET_S32 (abfd, ext->p_fregoffset);
+ intern->frameoffset = H_GET_S32 (abfd, ext->p_frameoffset);
+ intern->framereg = H_GET_16 (abfd, ext->p_framereg);
+ intern->pcreg = H_GET_16 (abfd, ext->p_pcreg);
+ intern->lnLow = H_GET_32 (abfd, ext->p_lnLow);
+ intern->lnHigh = H_GET_32 (abfd, ext->p_lnHigh);
+ intern->cbLineOffset = ECOFF_GET_OFF (abfd, ext->p_cbLineOffset);
+
+#if defined (ECOFF_64) || defined (ECOFF_SIGNED_64)
+ if (intern->isym == (signed long) 0xffffffff)
+ intern->isym = -1;
+ if (intern->iline == (signed long) 0xffffffff)
+ intern->iline = -1;
+
+ intern->gp_prologue = H_GET_8 (abfd, 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 = H_GET_8 (abfd, 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 (bfd *abfd, const PDR *intern_copy, void * ext_ptr)
+{
+ struct pdr_ext *ext = (struct pdr_ext *) ext_ptr;
+ PDR intern[1];
+
+ /* Make it reasonable to do in-place. */
+ *intern = *intern_copy;
+
+ ECOFF_PUT_OFF (abfd, intern->adr, ext->p_adr);
+ H_PUT_32 (abfd, intern->isym, ext->p_isym);
+ H_PUT_32 (abfd, intern->iline, ext->p_iline);
+ H_PUT_32 (abfd, intern->regmask, ext->p_regmask);
+ H_PUT_32 (abfd, intern->regoffset, ext->p_regoffset);
+ H_PUT_32 (abfd, intern->iopt, ext->p_iopt);
+ H_PUT_32 (abfd, intern->fregmask, ext->p_fregmask);
+ H_PUT_32 (abfd, intern->fregoffset, ext->p_fregoffset);
+ H_PUT_32 (abfd, intern->frameoffset, ext->p_frameoffset);
+ H_PUT_16 (abfd, intern->framereg, ext->p_framereg);
+ H_PUT_16 (abfd, intern->pcreg, ext->p_pcreg);
+ H_PUT_32 (abfd, intern->lnLow, ext->p_lnLow);
+ H_PUT_32 (abfd, intern->lnHigh, ext->p_lnHigh);
+ ECOFF_PUT_OFF (abfd, intern->cbLineOffset, ext->p_cbLineOffset);
+
+#if defined (ECOFF_64) || defined (ECOFF_SIGNED_64)
+ H_PUT_8 (abfd, intern->gp_prologue, 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);
+ }
+ H_PUT_8 (abfd, intern->localoff, ext->p_localoff);
+#endif
+
+#ifdef TEST
+ if (memcmp ((char *) ext, (char *) intern, sizeof (*intern)) != 0)
+ abort ();
+#endif
+}
+
+/* Swap in a symbol record. */
+
+static void
+ecoff_swap_sym_in (bfd *abfd, void * ext_copy, SYMR *intern)
+{
+ struct sym_ext ext[1];
+
+ *ext = *(struct sym_ext *) ext_copy;
+
+ intern->iss = H_GET_32 (abfd, ext->s_iss);
+ intern->value = ECOFF_GET_OFF (abfd, ext->s_value);
+
+#if defined (ECOFF_64) || defined (ECOFF_SIGNED_64)
+ if (intern->iss == (signed long) 0xffffffff)
+ intern->iss = -1;
+#endif
+
+ /* 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 (bfd *abfd, const SYMR *intern_copy, void * ext_ptr)
+{
+ struct sym_ext *ext = (struct sym_ext *) ext_ptr;
+ SYMR intern[1];
+
+ /* Make it reasonable to do in-place. */
+ *intern = *intern_copy;
+
+ H_PUT_32 (abfd, intern->iss, ext->s_iss);
+ ECOFF_PUT_OFF (abfd, intern->value, 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 (bfd *abfd, void * 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;
+
+#if defined (ECOFF_32) || defined (ECOFF_SIGNED_32)
+ intern->ifd = H_GET_S16 (abfd, ext->es_ifd);
+#endif
+#if defined (ECOFF_64) || defined (ECOFF_SIGNED_64)
+ intern->ifd = H_GET_S32 (abfd, 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 (bfd *abfd, const EXTR *intern_copy, void * ext_ptr)
+{
+ struct ext_ext *ext = (struct ext_ext *) ext_ptr;
+ EXTR intern[1];
+
+ /* Make it reasonable to do in-place. */
+ *intern = *intern_copy;
+
+ /* 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;
+#if defined (ECOFF_64) || defined (ECOFF_SIGNED_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;
+#if defined (ECOFF_64) || defined (ECOFF_SIGNED_64)
+ ext->es_bits2[1] = 0;
+ ext->es_bits2[2] = 0;
+#endif
+ }
+
+#if defined (ECOFF_32) || defined (ECOFF_SIGNED_32)
+ H_PUT_S16 (abfd, intern->ifd, ext->es_ifd);
+#endif
+#if defined (ECOFF_64) || defined (ECOFF_SIGNED_64)
+ H_PUT_S32 (abfd, intern->ifd, 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 (bfd *abfd, void * ext_ptr, RFDT *intern)
+{
+ struct rfd_ext *ext = (struct rfd_ext *) ext_ptr;
+
+ *intern = H_GET_32 (abfd, 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 (bfd *abfd, const RFDT *intern, void * ext_ptr)
+{
+ struct rfd_ext *ext = (struct rfd_ext *) ext_ptr;
+
+ H_PUT_32 (abfd, *intern, 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 (bfd *abfd, void * 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 = H_GET_32 (abfd, 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 (bfd *abfd, const OPTR *intern_copy, void * ext_ptr)
+{
+ struct opt_ext *ext = (struct opt_ext *) ext_ptr;
+ OPTR intern[1];
+
+ /* Make it reasonable to do in-place. */
+ *intern = *intern_copy;
+
+ 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);
+
+ H_PUT_32 (abfd, intern->value, 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 (bfd *abfd, void * ext_copy, DNR *intern)
+{
+ struct dnr_ext ext[1];
+
+ *ext = *(struct dnr_ext *) ext_copy;
+
+ intern->rfd = H_GET_32 (abfd, ext->d_rfd);
+ intern->index = H_GET_32 (abfd, 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 (bfd *abfd, const DNR *intern_copy, void * ext_ptr)
+{
+ struct dnr_ext *ext = (struct dnr_ext *) ext_ptr;
+ DNR intern[1];
+
+ /* Make it reasonable to do in-place. */
+ *intern = *intern_copy;
+
+ H_PUT_32 (abfd, intern->rfd, ext->d_rfd);
+ H_PUT_32 (abfd, intern->index, ext->d_index);
+
+#ifdef TEST
+ if (memcmp ((char *) ext, (char *) intern, sizeof (*intern)) != 0)
+ abort ();
+#endif
+}
diff --git a/bfd/elf-attrs.c b/bfd/elf-attrs.c
new file mode 100644
index 0000000..cd0cbca
--- /dev/null
+++ b/bfd/elf-attrs.c
@@ -0,0 +1,705 @@
+/* ELF attributes support (based on ARM EABI attributes).
+ Copyright (C) 2005-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libiberty.h"
+#include "libbfd.h"
+#include "elf-bfd.h"
+
+/* Return the number of bytes needed by I in uleb128 format. */
+static int
+uleb128_size (unsigned int i)
+{
+ int size;
+ size = 1;
+ while (i >= 0x80)
+ {
+ i >>= 7;
+ size++;
+ }
+ return size;
+}
+
+/* Return TRUE if the attribute has the default value (0/""). */
+static bfd_boolean
+is_default_attr (obj_attribute *attr)
+{
+ if (ATTR_TYPE_HAS_INT_VAL (attr->type) && attr->i != 0)
+ return FALSE;
+ if (ATTR_TYPE_HAS_STR_VAL (attr->type) && attr->s && *attr->s)
+ return FALSE;
+ if (ATTR_TYPE_HAS_NO_DEFAULT (attr->type))
+ return FALSE;
+
+ return TRUE;
+}
+
+/* Return the size of a single attribute. */
+static bfd_vma
+obj_attr_size (int tag, obj_attribute *attr)
+{
+ bfd_vma size;
+
+ if (is_default_attr (attr))
+ return 0;
+
+ size = uleb128_size (tag);
+ if (ATTR_TYPE_HAS_INT_VAL (attr->type))
+ size += uleb128_size (attr->i);
+ if (ATTR_TYPE_HAS_STR_VAL (attr->type))
+ size += strlen ((char *)attr->s) + 1;
+ return size;
+}
+
+/* Return the vendor name for a given object attributes section. */
+static const char *
+vendor_obj_attr_name (bfd *abfd, int vendor)
+{
+ return (vendor == OBJ_ATTR_PROC
+ ? get_elf_backend_data (abfd)->obj_attrs_vendor
+ : "gnu");
+}
+
+/* Return the size of the object attributes section for VENDOR
+ (OBJ_ATTR_PROC or OBJ_ATTR_GNU), or 0 if there are no attributes
+ for that vendor to record and the vendor is OBJ_ATTR_GNU. */
+static bfd_vma
+vendor_obj_attr_size (bfd *abfd, int vendor)
+{
+ bfd_vma size;
+ obj_attribute *attr;
+ obj_attribute_list *list;
+ int i;
+ const char *vendor_name = vendor_obj_attr_name (abfd, vendor);
+
+ if (!vendor_name)
+ return 0;
+
+ attr = elf_known_obj_attributes (abfd)[vendor];
+ size = 0;
+ for (i = LEAST_KNOWN_OBJ_ATTRIBUTE; i < NUM_KNOWN_OBJ_ATTRIBUTES; i++)
+ size += obj_attr_size (i, &attr[i]);
+
+ for (list = elf_other_obj_attributes (abfd)[vendor];
+ list;
+ list = list->next)
+ size += obj_attr_size (list->tag, &list->attr);
+
+ /* <size> <vendor_name> NUL 0x1 <size> */
+ return ((size || vendor == OBJ_ATTR_PROC)
+ ? size + 10 + strlen (vendor_name)
+ : 0);
+}
+
+/* Return the size of the object attributes section. */
+bfd_vma
+bfd_elf_obj_attr_size (bfd *abfd)
+{
+ bfd_vma size;
+
+ size = vendor_obj_attr_size (abfd, OBJ_ATTR_PROC);
+ size += vendor_obj_attr_size (abfd, OBJ_ATTR_GNU);
+
+ /* 'A' <sections for each vendor> */
+ return (size ? size + 1 : 0);
+}
+
+/* Write VAL in uleb128 format to P, returning a pointer to the
+ following byte. */
+static bfd_byte *
+write_uleb128 (bfd_byte *p, unsigned int val)
+{
+ bfd_byte c;
+ do
+ {
+ c = val & 0x7f;
+ val >>= 7;
+ if (val)
+ c |= 0x80;
+ *(p++) = c;
+ }
+ while (val);
+ return p;
+}
+
+/* Write attribute ATTR to butter P, and return a pointer to the following
+ byte. */
+static bfd_byte *
+write_obj_attribute (bfd_byte *p, int tag, obj_attribute *attr)
+{
+ /* Suppress default entries. */
+ if (is_default_attr (attr))
+ return p;
+
+ p = write_uleb128 (p, tag);
+ if (ATTR_TYPE_HAS_INT_VAL (attr->type))
+ p = write_uleb128 (p, attr->i);
+ if (ATTR_TYPE_HAS_STR_VAL (attr->type))
+ {
+ int len;
+
+ len = strlen (attr->s) + 1;
+ memcpy (p, attr->s, len);
+ p += len;
+ }
+
+ return p;
+}
+
+/* Write the contents of the object attributes section (length SIZE)
+ for VENDOR to CONTENTS. */
+static void
+vendor_set_obj_attr_contents (bfd *abfd, bfd_byte *contents, bfd_vma size,
+ int vendor)
+{
+ bfd_byte *p;
+ obj_attribute *attr;
+ obj_attribute_list *list;
+ int i;
+ const char *vendor_name = vendor_obj_attr_name (abfd, vendor);
+ size_t vendor_length = strlen (vendor_name) + 1;
+
+ p = contents;
+ bfd_put_32 (abfd, size, p);
+ p += 4;
+ memcpy (p, vendor_name, vendor_length);
+ p += vendor_length;
+ *(p++) = Tag_File;
+ bfd_put_32 (abfd, size - 4 - vendor_length, p);
+ p += 4;
+
+ attr = elf_known_obj_attributes (abfd)[vendor];
+ for (i = LEAST_KNOWN_OBJ_ATTRIBUTE; i < NUM_KNOWN_OBJ_ATTRIBUTES; i++)
+ {
+ int tag = i;
+ if (get_elf_backend_data (abfd)->obj_attrs_order)
+ tag = get_elf_backend_data (abfd)->obj_attrs_order (i);
+ p = write_obj_attribute (p, tag, &attr[tag]);
+ }
+
+ for (list = elf_other_obj_attributes (abfd)[vendor];
+ list;
+ list = list->next)
+ p = write_obj_attribute (p, list->tag, &list->attr);
+}
+
+/* Write the contents of the object attributes section to CONTENTS. */
+void
+bfd_elf_set_obj_attr_contents (bfd *abfd, bfd_byte *contents, bfd_vma size)
+{
+ bfd_byte *p;
+ int vendor;
+ bfd_vma my_size;
+
+ p = contents;
+ *(p++) = 'A';
+ my_size = 1;
+ for (vendor = OBJ_ATTR_FIRST; vendor <= OBJ_ATTR_LAST; vendor++)
+ {
+ bfd_vma vendor_size = vendor_obj_attr_size (abfd, vendor);
+ if (vendor_size)
+ vendor_set_obj_attr_contents (abfd, p, vendor_size, vendor);
+ p += vendor_size;
+ my_size += vendor_size;
+ }
+
+ if (size != my_size)
+ abort ();
+}
+
+/* Allocate/find an object attribute. */
+static obj_attribute *
+elf_new_obj_attr (bfd *abfd, int vendor, int tag)
+{
+ obj_attribute *attr;
+ obj_attribute_list *list;
+ obj_attribute_list *p;
+ obj_attribute_list **lastp;
+
+
+ if (tag < NUM_KNOWN_OBJ_ATTRIBUTES)
+ {
+ /* Known tags are preallocated. */
+ attr = &elf_known_obj_attributes (abfd)[vendor][tag];
+ }
+ else
+ {
+ /* Create a new tag. */
+ list = (obj_attribute_list *)
+ bfd_alloc (abfd, sizeof (obj_attribute_list));
+ memset (list, 0, sizeof (obj_attribute_list));
+ list->tag = tag;
+ /* Keep the tag list in order. */
+ lastp = &elf_other_obj_attributes (abfd)[vendor];
+ for (p = *lastp; p; p = p->next)
+ {
+ if (tag < p->tag)
+ break;
+ lastp = &p->next;
+ }
+ list->next = *lastp;
+ *lastp = list;
+ attr = &list->attr;
+ }
+
+ return attr;
+}
+
+/* Return the value of an integer object attribute. */
+int
+bfd_elf_get_obj_attr_int (bfd *abfd, int vendor, int tag)
+{
+ obj_attribute_list *p;
+
+ if (tag < NUM_KNOWN_OBJ_ATTRIBUTES)
+ {
+ /* Known tags are preallocated. */
+ return elf_known_obj_attributes (abfd)[vendor][tag].i;
+ }
+ else
+ {
+ for (p = elf_other_obj_attributes (abfd)[vendor];
+ p;
+ p = p->next)
+ {
+ if (tag == p->tag)
+ return p->attr.i;
+ if (tag < p->tag)
+ break;
+ }
+ return 0;
+ }
+}
+
+/* Add an integer object attribute. */
+void
+bfd_elf_add_obj_attr_int (bfd *abfd, int vendor, int tag, unsigned int i)
+{
+ obj_attribute *attr;
+
+ attr = elf_new_obj_attr (abfd, vendor, tag);
+ attr->type = _bfd_elf_obj_attrs_arg_type (abfd, vendor, tag);
+ attr->i = i;
+}
+
+/* Duplicate an object attribute string value. */
+char *
+_bfd_elf_attr_strdup (bfd *abfd, const char * s)
+{
+ char * p;
+ int len;
+
+ len = strlen (s) + 1;
+ p = (char *) bfd_alloc (abfd, len);
+ return (char *) memcpy (p, s, len);
+}
+
+/* Add a string object attribute. */
+void
+bfd_elf_add_obj_attr_string (bfd *abfd, int vendor, int tag, const char *s)
+{
+ obj_attribute *attr;
+
+ attr = elf_new_obj_attr (abfd, vendor, tag);
+ attr->type = _bfd_elf_obj_attrs_arg_type (abfd, vendor, tag);
+ attr->s = _bfd_elf_attr_strdup (abfd, s);
+}
+
+/* Add a int+string object attribute. */
+void
+bfd_elf_add_obj_attr_int_string (bfd *abfd, int vendor, int tag,
+ unsigned int i, const char *s)
+{
+ obj_attribute *attr;
+
+ attr = elf_new_obj_attr (abfd, vendor, tag);
+ attr->type = _bfd_elf_obj_attrs_arg_type (abfd, vendor, tag);
+ attr->i = i;
+ attr->s = _bfd_elf_attr_strdup (abfd, s);
+}
+
+/* Copy the object attributes from IBFD to OBFD. */
+void
+_bfd_elf_copy_obj_attributes (bfd *ibfd, bfd *obfd)
+{
+ obj_attribute *in_attr;
+ obj_attribute *out_attr;
+ obj_attribute_list *list;
+ int i;
+ int vendor;
+
+ if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
+ || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
+ return;
+
+ for (vendor = OBJ_ATTR_FIRST; vendor <= OBJ_ATTR_LAST; vendor++)
+ {
+ in_attr
+ = &elf_known_obj_attributes (ibfd)[vendor][LEAST_KNOWN_OBJ_ATTRIBUTE];
+ out_attr
+ = &elf_known_obj_attributes (obfd)[vendor][LEAST_KNOWN_OBJ_ATTRIBUTE];
+ for (i = LEAST_KNOWN_OBJ_ATTRIBUTE; i < NUM_KNOWN_OBJ_ATTRIBUTES; i++)
+ {
+ out_attr->type = in_attr->type;
+ out_attr->i = in_attr->i;
+ if (in_attr->s && *in_attr->s)
+ out_attr->s = _bfd_elf_attr_strdup (obfd, in_attr->s);
+ in_attr++;
+ out_attr++;
+ }
+
+ for (list = elf_other_obj_attributes (ibfd)[vendor];
+ list;
+ list = list->next)
+ {
+ in_attr = &list->attr;
+ switch (in_attr->type & (ATTR_TYPE_FLAG_INT_VAL | ATTR_TYPE_FLAG_STR_VAL))
+ {
+ case ATTR_TYPE_FLAG_INT_VAL:
+ bfd_elf_add_obj_attr_int (obfd, vendor, list->tag, in_attr->i);
+ break;
+ case ATTR_TYPE_FLAG_STR_VAL:
+ bfd_elf_add_obj_attr_string (obfd, vendor, list->tag,
+ in_attr->s);
+ break;
+ case ATTR_TYPE_FLAG_INT_VAL | ATTR_TYPE_FLAG_STR_VAL:
+ bfd_elf_add_obj_attr_int_string (obfd, vendor, list->tag,
+ in_attr->i, in_attr->s);
+ break;
+ default:
+ abort ();
+ }
+ }
+ }
+}
+
+/* Determine whether a GNU object attribute tag takes an integer, a
+ string or both. */
+static int
+gnu_obj_attrs_arg_type (int tag)
+{
+ /* Except for Tag_compatibility, for GNU attributes we follow the
+ same rule ARM ones > 32 follow: odd-numbered tags take strings
+ and even-numbered tags take integers. In addition, tag & 2 is
+ nonzero for architecture-independent tags and zero for
+ architecture-dependent ones. */
+ if (tag == Tag_compatibility)
+ return 3;
+ else
+ return (tag & 1) != 0 ? 2 : 1;
+}
+
+/* Determine what arguments an attribute tag takes. */
+int
+_bfd_elf_obj_attrs_arg_type (bfd *abfd, int vendor, int tag)
+{
+ switch (vendor)
+ {
+ case OBJ_ATTR_PROC:
+ return get_elf_backend_data (abfd)->obj_attrs_arg_type (tag);
+ break;
+ case OBJ_ATTR_GNU:
+ return gnu_obj_attrs_arg_type (tag);
+ break;
+ default:
+ abort ();
+ }
+}
+
+/* Parse an object attributes section. */
+void
+_bfd_elf_parse_attributes (bfd *abfd, Elf_Internal_Shdr * hdr)
+{
+ bfd_byte *contents;
+ bfd_byte *p;
+ bfd_vma len;
+ const char *std_sec;
+
+ contents = (bfd_byte *) bfd_malloc (hdr->sh_size);
+ if (!contents)
+ return;
+ if (!bfd_get_section_contents (abfd, hdr->bfd_section, contents, 0,
+ hdr->sh_size))
+ {
+ free (contents);
+ return;
+ }
+ p = contents;
+ std_sec = get_elf_backend_data (abfd)->obj_attrs_vendor;
+ if (*(p++) == 'A')
+ {
+ len = hdr->sh_size - 1;
+ while (len > 0)
+ {
+ unsigned namelen;
+ bfd_vma section_len;
+ int vendor;
+
+ section_len = bfd_get_32 (abfd, p);
+ p += 4;
+ if (section_len > len)
+ section_len = len;
+ len -= section_len;
+ section_len -= 4;
+ namelen = strnlen ((char *) p, section_len) + 1;
+ if (namelen == 0 || namelen >= section_len)
+ break;
+ section_len -= namelen;
+ if (std_sec && strcmp ((char *) p, std_sec) == 0)
+ vendor = OBJ_ATTR_PROC;
+ else if (strcmp ((char *) p, "gnu") == 0)
+ vendor = OBJ_ATTR_GNU;
+ else
+ {
+ /* Other vendor section. Ignore it. */
+ p += namelen + section_len;
+ continue;
+ }
+
+ p += namelen;
+ while (section_len > 0)
+ {
+ int tag;
+ unsigned int n;
+ unsigned int val;
+ bfd_vma subsection_len;
+ bfd_byte *end;
+
+ tag = read_unsigned_leb128 (abfd, p, &n);
+ p += n;
+ subsection_len = bfd_get_32 (abfd, p);
+ p += 4;
+ if (subsection_len > section_len)
+ subsection_len = section_len;
+ section_len -= subsection_len;
+ subsection_len -= n + 4;
+ end = p + subsection_len;
+ switch (tag)
+ {
+ case Tag_File:
+ while (p < end)
+ {
+ int type;
+
+ tag = read_unsigned_leb128 (abfd, p, &n);
+ p += n;
+ type = _bfd_elf_obj_attrs_arg_type (abfd, vendor, tag);
+ switch (type & (ATTR_TYPE_FLAG_INT_VAL | ATTR_TYPE_FLAG_STR_VAL))
+ {
+ case ATTR_TYPE_FLAG_INT_VAL | ATTR_TYPE_FLAG_STR_VAL:
+ val = read_unsigned_leb128 (abfd, p, &n);
+ p += n;
+ bfd_elf_add_obj_attr_int_string (abfd, vendor, tag,
+ val, (char *)p);
+ p += strlen ((char *)p) + 1;
+ break;
+ case ATTR_TYPE_FLAG_STR_VAL:
+ bfd_elf_add_obj_attr_string (abfd, vendor, tag,
+ (char *)p);
+ p += strlen ((char *)p) + 1;
+ break;
+ case ATTR_TYPE_FLAG_INT_VAL:
+ val = read_unsigned_leb128 (abfd, p, &n);
+ p += n;
+ bfd_elf_add_obj_attr_int (abfd, vendor, tag, val);
+ break;
+ default:
+ abort ();
+ }
+ }
+ break;
+ case Tag_Section:
+ case Tag_Symbol:
+ /* Don't have anywhere convenient to attach these.
+ Fall through for now. */
+ default:
+ /* Ignore things we don't kow about. */
+ p += subsection_len;
+ subsection_len = 0;
+ break;
+ }
+ }
+ }
+ }
+ free (contents);
+}
+
+/* Merge common object attributes from IBFD into OBFD. Raise an error
+ if there are conflicting attributes. Any processor-specific
+ attributes have already been merged. This must be called from the
+ bfd_elfNN_bfd_merge_private_bfd_data hook for each individual
+ target, along with any target-specific merging. Because there are
+ no common attributes other than Tag_compatibility at present, and
+ non-"gnu" Tag_compatibility is not expected in "gnu" sections, this
+ is not presently called for targets without their own
+ attributes. */
+
+bfd_boolean
+_bfd_elf_merge_object_attributes (bfd *ibfd, bfd *obfd)
+{
+ obj_attribute *in_attr;
+ obj_attribute *out_attr;
+ int vendor;
+
+ /* The only common attribute is currently Tag_compatibility,
+ accepted in both processor and "gnu" sections. */
+ for (vendor = OBJ_ATTR_FIRST; vendor <= OBJ_ATTR_LAST; vendor++)
+ {
+ /* Handle Tag_compatibility. The tags are only compatible if the flags
+ are identical and, if the flags are '1', the strings are identical.
+ If the flags are non-zero, then we can only use the string "gnu". */
+ in_attr = &elf_known_obj_attributes (ibfd)[vendor][Tag_compatibility];
+ out_attr = &elf_known_obj_attributes (obfd)[vendor][Tag_compatibility];
+
+ if (in_attr->i > 0 && strcmp (in_attr->s, "gnu") != 0)
+ {
+ _bfd_error_handler
+ (_("error: %B: Object has vendor-specific contents that "
+ "must be processed by the '%s' toolchain"),
+ ibfd, in_attr->s);
+ return FALSE;
+ }
+
+ if (in_attr->i != out_attr->i
+ || (in_attr->i != 0 && strcmp (in_attr->s, out_attr->s) != 0))
+ {
+ _bfd_error_handler (_("error: %B: Object tag '%d, %s' is "
+ "incompatible with tag '%d, %s'"),
+ ibfd,
+ in_attr->i, in_attr->s ? in_attr->s : "",
+ out_attr->i, out_attr->s ? out_attr->s : "");
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+/* Merge an unknown processor-specific attribute TAG, within the range
+ of known attributes, from IBFD into OBFD; return TRUE if the link
+ is OK, FALSE if it must fail. */
+
+bfd_boolean
+_bfd_elf_merge_unknown_attribute_low (bfd *ibfd, bfd *obfd, int tag)
+{
+ obj_attribute *in_attr;
+ obj_attribute *out_attr;
+ bfd *err_bfd = NULL;
+ bfd_boolean result = TRUE;
+
+ in_attr = elf_known_obj_attributes_proc (ibfd);
+ out_attr = elf_known_obj_attributes_proc (obfd);
+
+ if (out_attr[tag].i != 0 || out_attr[tag].s != NULL)
+ err_bfd = obfd;
+ else if (in_attr[tag].i != 0 || in_attr[tag].s != NULL)
+ err_bfd = ibfd;
+
+ if (err_bfd != NULL)
+ result
+ = get_elf_backend_data (err_bfd)->obj_attrs_handle_unknown (err_bfd, tag);
+
+ /* Only pass on attributes that match in both inputs. */
+ if (in_attr[tag].i != out_attr[tag].i
+ || (in_attr[tag].s == NULL) != (out_attr[tag].s == NULL)
+ || (in_attr[tag].s != NULL && out_attr[tag].s != NULL
+ && strcmp (in_attr[tag].s, out_attr[tag].s) != 0))
+ {
+ out_attr[tag].i = 0;
+ out_attr[tag].s = NULL;
+ }
+
+ return result;
+}
+
+/* Merge the lists of unknown processor-specific attributes, outside
+ the known range, from IBFD into OBFD; return TRUE if the link is
+ OK, FALSE if it must fail. */
+
+bfd_boolean
+_bfd_elf_merge_unknown_attribute_list (bfd *ibfd, bfd *obfd)
+{
+ obj_attribute_list *in_list;
+ obj_attribute_list *out_list;
+ obj_attribute_list **out_listp;
+ bfd_boolean result = TRUE;
+
+ in_list = elf_other_obj_attributes_proc (ibfd);
+ out_listp = &elf_other_obj_attributes_proc (obfd);
+ out_list = *out_listp;
+
+ for (; in_list || out_list; )
+ {
+ bfd *err_bfd = NULL;
+ int err_tag = 0;
+
+ /* The tags for each list are in numerical order. */
+ /* If the tags are equal, then merge. */
+ if (out_list && (!in_list || in_list->tag > out_list->tag))
+ {
+ /* This attribute only exists in obfd. We can't merge, and we don't
+ know what the tag means, so delete it. */
+ err_bfd = obfd;
+ err_tag = out_list->tag;
+ *out_listp = out_list->next;
+ out_list = *out_listp;
+ }
+ else if (in_list && (!out_list || in_list->tag < out_list->tag))
+ {
+ /* This attribute only exists in ibfd. We can't merge, and we don't
+ know what the tag means, so ignore it. */
+ err_bfd = ibfd;
+ err_tag = in_list->tag;
+ in_list = in_list->next;
+ }
+ else /* The tags are equal. */
+ {
+ /* As present, all attributes in the list are unknown, and
+ therefore can't be merged meaningfully. */
+ err_bfd = obfd;
+ err_tag = out_list->tag;
+
+ /* Only pass on attributes that match in both inputs. */
+ if (in_list->attr.i != out_list->attr.i
+ || (in_list->attr.s == NULL) != (out_list->attr.s == NULL)
+ || (in_list->attr.s && out_list->attr.s
+ && strcmp (in_list->attr.s, out_list->attr.s) != 0))
+ {
+ /* No match. Delete the attribute. */
+ *out_listp = out_list->next;
+ out_list = *out_listp;
+ }
+ else
+ {
+ /* Matched. Keep the attribute and move to the next. */
+ out_list = out_list->next;
+ in_list = in_list->next;
+ }
+ }
+
+ if (err_bfd)
+ result = result
+ && get_elf_backend_data (err_bfd)->obj_attrs_handle_unknown (err_bfd,
+ err_tag);
+ }
+
+ return result;
+}
diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h
new file mode 100644
index 0000000..72e7a66
--- /dev/null
+++ b/bfd/elf-bfd.h
@@ -0,0 +1,2531 @@
+/* BFD back-end data structures for ELF files.
+ Copyright (C) 1992-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#ifndef _LIBELF_H_
+#define _LIBELF_H_ 1
+
+#include "elf/common.h"
+#include "elf/external.h"
+#include "elf/internal.h"
+#include "bfdlink.h"
+
+/* The number of entries in a section is its size divided by the size
+ of a single entry. This is normally only applicable to reloc and
+ symbol table sections.
+ PR 9934: It is possible to have relocations that do not refer to
+ symbols, thus it is also possible to have a relocation section in
+ an object file, but no symbol table. */
+#define NUM_SHDR_ENTRIES(shdr) ((shdr)->sh_entsize > 0 ? (shdr)->sh_size / (shdr)->sh_entsize : 0)
+
+/* If size isn't specified as 64 or 32, NAME macro should fail. */
+#ifndef NAME
+#if ARCH_SIZE == 64
+#define NAME(x, y) x ## 64 ## _ ## y
+#endif
+#if ARCH_SIZE == 32
+#define NAME(x, y) x ## 32 ## _ ## y
+#endif
+#endif
+
+#ifndef NAME
+#define NAME(x, y) 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;
+ void *mips_extr;
+ void *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;
+
+struct elf_strtab_hash;
+struct got_entry;
+struct plt_entry;
+
+union gotplt_union
+ {
+ bfd_signed_vma refcount;
+ bfd_vma offset;
+ struct got_entry *glist;
+ struct plt_entry *plist;
+ };
+
+struct elf_link_virtual_table_entry
+ {
+ /* 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 size;
+ bfd_boolean *used;
+
+ /* Virtual table derivation info. */
+ struct elf_link_hash_entry *parent;
+ };
+
+/* 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 index as a dynamic symbol. Initialized to -1, and remains
+ -1 if this is not a dynamic symbol. */
+ /* ??? Note that this is consistently used as a synonym for tests
+ against whether we can perform various simplifying transformations
+ to the code. (E.g. changing a pc-relative jump to a PLT entry
+ into a pc-relative jump to the target function.) That test, which
+ is often relatively complex, and someplaces wrong or incomplete,
+ should really be replaced by a predicate in elflink.c.
+
+ End result: this field -1 does not indicate that the symbol is
+ not in the dynamic symbol table, but rather that the symbol is
+ not visible outside this DSO. */
+ long dynindx;
+
+ /* If this symbol requires an entry in the global offset table, the
+ processor specific backend uses this field to track usage and
+ final offset. Two schemes are supported: The first assumes that
+ a symbol may only have one GOT entry, and uses REFCOUNT until
+ size_dynamic_sections, at which point the contents of the .got is
+ fixed. Afterward, if OFFSET is -1, then the symbol does not
+ require a global offset table entry. The second scheme allows
+ multiple GOT entries per symbol, managed via a linked list
+ pointed to by GLIST. */
+ union gotplt_union got;
+
+ /* Same, but tracks a procedure linkage table entry. */
+ union gotplt_union plt;
+
+ /* Symbol size. */
+ bfd_size_type size;
+
+ /* Symbol type (STT_NOTYPE, STT_OBJECT, etc.). */
+ unsigned int type : 8;
+
+ /* Symbol st_other value, symbol visibility. */
+ unsigned int other : 8;
+
+ /* The symbol's st_target_internal value (see Elf_Internal_Sym). */
+ unsigned int target_internal : 8;
+
+ /* Symbol is referenced by a non-shared object (other than the object
+ in which it is defined). */
+ unsigned int ref_regular : 1;
+ /* Symbol is defined by a non-shared object. */
+ unsigned int def_regular : 1;
+ /* Symbol is referenced by a shared object. */
+ unsigned int ref_dynamic : 1;
+ /* Symbol is defined by a shared object. */
+ unsigned int def_dynamic : 1;
+ /* Symbol has a non-weak reference from a non-shared object (other than
+ the object in which it is defined). */
+ unsigned int ref_regular_nonweak : 1;
+ /* Dynamic symbol has been adjustd. */
+ unsigned int dynamic_adjusted : 1;
+ /* Symbol needs a copy reloc. */
+ unsigned int needs_copy : 1;
+ /* Symbol needs a procedure linkage table entry. */
+ unsigned int needs_plt : 1;
+ /* Symbol appears in a non-ELF input file. */
+ unsigned int non_elf : 1;
+ /* Symbol should be marked as hidden in the version information. */
+ unsigned int hidden : 1;
+ /* Symbol was forced to local scope due to a version script file. */
+ unsigned int forced_local : 1;
+ /* Symbol was forced to be dynamic due to a version script file. */
+ unsigned int dynamic : 1;
+ /* Symbol was marked during garbage collection. */
+ unsigned int mark : 1;
+ /* Symbol is referenced by a non-GOT/non-PLT relocation. This is
+ not currently set by all the backends. */
+ unsigned int non_got_ref : 1;
+ /* Symbol has a definition in a shared object.
+ FIXME: There is no real need for this field if def_dynamic is never
+ cleared and all places that test def_dynamic also test def_regular. */
+ unsigned int dynamic_def : 1;
+ /* Symbol has a non-weak reference from a shared object. */
+ unsigned int ref_dynamic_nonweak : 1;
+ /* Symbol is referenced with a relocation where C/C++ pointer equality
+ matters. */
+ unsigned int pointer_equality_needed : 1;
+ /* Symbol is a unique global symbol. */
+ unsigned int unique_global : 1;
+
+ /* String table index in .dynstr if this is a dynamic symbol. */
+ unsigned long dynstr_index;
+
+ union
+ {
+ /* 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;
+
+ /* Hash value of the name computed using the ELF hash function.
+ Used part way through size_dynamic_sections, after we've finished
+ with weakdefs. */
+ unsigned long elf_hash_value;
+ } u;
+
+ /* 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;
+
+ struct elf_link_virtual_table_entry *vtable;
+};
+
+/* Will references to this symbol always reference the symbol
+ in this object? */
+#define SYMBOL_REFERENCES_LOCAL(INFO, H) \
+ _bfd_elf_symbol_refs_local_p (H, INFO, 0)
+
+/* Will _calls_ to this symbol always call the version in this object? */
+#define SYMBOL_CALLS_LOCAL(INFO, H) \
+ _bfd_elf_symbol_refs_local_p (H, INFO, 1)
+
+/* Common symbols that are turned into definitions don't have the
+ DEF_REGULAR flag set, so they might appear to be undefined. */
+#define ELF_COMMON_DEF_P(H) \
+ (!(H)->def_regular \
+ && !(H)->def_dynamic \
+ && (H)->root.type == bfd_link_hash_defined)
+
+/* Records local symbols to be emitted in the dynamic symbol table. */
+
+struct elf_link_local_dynamic_entry
+{
+ struct elf_link_local_dynamic_entry *next;
+
+ /* The input bfd this symbol came from. */
+ bfd *input_bfd;
+
+ /* The index of the local symbol being copied. */
+ long input_indx;
+
+ /* The index in the outgoing dynamic symbol table. */
+ long dynindx;
+
+ /* A copy of the input symbol. */
+ Elf_Internal_Sym isym;
+};
+
+struct elf_link_loaded_list
+{
+ struct elf_link_loaded_list *next;
+ bfd *abfd;
+};
+
+/* Structures used by the eh_frame optimization code. */
+struct eh_cie_fde
+{
+ union {
+ struct {
+ /* If REMOVED == 1, this is the CIE that the FDE originally used.
+ The CIE belongs to the same .eh_frame input section as the FDE.
+
+ If REMOVED == 0, this is the CIE that we have chosen to use for
+ the output FDE. The CIE's REMOVED field is also 0, but the CIE
+ might belong to a different .eh_frame input section from the FDE.
+
+ May be NULL to signify that the FDE should be discarded. */
+ struct eh_cie_fde *cie_inf;
+ struct eh_cie_fde *next_for_section;
+ } fde;
+ struct {
+ /* CIEs have three states:
+
+ - REMOVED && !MERGED: Slated for removal because we haven't yet
+ proven that an FDE needs it. FULL_CIE, if nonnull, points to
+ more detailed information about the CIE.
+
+ - REMOVED && MERGED: We have merged this CIE with MERGED_WITH,
+ which may not belong to the same input section.
+
+ - !REMOVED: We have decided to keep this CIE. SEC is the
+ .eh_frame input section that contains the CIE. */
+ union {
+ struct cie *full_cie;
+ struct eh_cie_fde *merged_with;
+ asection *sec;
+ } u;
+
+ /* The offset of the personality data from the start of the CIE,
+ or 0 if the CIE doesn't have any. */
+ unsigned int personality_offset : 8;
+
+ /* True if we have marked relocations associated with this CIE. */
+ unsigned int gc_mark : 1;
+
+ /* True if we have decided to turn an absolute LSDA encoding into
+ a PC-relative one. */
+ unsigned int make_lsda_relative : 1;
+
+ /* True if we have decided to turn an absolute personality
+ encoding into a PC-relative one. */
+ unsigned int make_per_encoding_relative : 1;
+
+ /* True if the CIE contains personality data and if that
+ data uses a PC-relative encoding. Always true when
+ make_per_encoding_relative is. */
+ unsigned int per_encoding_relative : 1;
+
+ /* True if we need to add an 'R' (FDE encoding) entry to the
+ CIE's augmentation data. */
+ unsigned int add_fde_encoding : 1;
+
+ /* True if we have merged this CIE with another. */
+ unsigned int merged : 1;
+
+ /* Unused bits. */
+ unsigned int pad1 : 18;
+ } cie;
+ } u;
+ unsigned int reloc_index;
+ unsigned int size;
+ unsigned int offset;
+ unsigned int new_offset;
+ unsigned int fde_encoding : 8;
+ unsigned int lsda_encoding : 8;
+ unsigned int lsda_offset : 8;
+
+ /* True if this entry represents a CIE, false if it represents an FDE. */
+ unsigned int cie : 1;
+
+ /* True if this entry is currently marked for removal. */
+ unsigned int removed : 1;
+
+ /* True if we need to add a 'z' (augmentation size) entry to the CIE's
+ augmentation data, and an associated byte to each of the CIE's FDEs. */
+ unsigned int add_augmentation_size : 1;
+
+ /* True if we have decided to convert absolute FDE relocations into
+ relative ones. This applies to the first relocation in the FDE,
+ which is against the code that the FDE describes. */
+ unsigned int make_relative : 1;
+
+ /* Unused bits. */
+ unsigned int pad1 : 4;
+
+ unsigned int *set_loc;
+};
+
+struct eh_frame_sec_info
+{
+ unsigned int count;
+ struct cie *cies;
+ struct eh_cie_fde entry[1];
+};
+
+struct eh_frame_array_ent
+{
+ bfd_vma initial_loc;
+ bfd_size_type range;
+ bfd_vma fde;
+};
+
+struct htab;
+
+struct eh_frame_hdr_info
+{
+ struct htab *cies;
+ asection *hdr_sec;
+ unsigned int fde_count, array_count;
+ struct eh_frame_array_ent *array;
+ /* TRUE if .eh_frame_hdr should contain the sorted search table.
+ We build it if we successfully read all .eh_frame input sections
+ and recognize them. */
+ bfd_boolean table;
+};
+
+/* Enum used to identify target specific extensions to the elf_obj_tdata
+ and elf_link_hash_table structures. Note the enums deliberately start
+ from 1 so that we can detect an uninitialized field. The generic value
+ is last so that additions to this enum do not need to modify more than
+ one line. */
+enum elf_target_id
+{
+ AARCH64_ELF_DATA = 1,
+ ALPHA_ELF_DATA,
+ ARM_ELF_DATA,
+ AVR_ELF_DATA,
+ BFIN_ELF_DATA,
+ CRIS_ELF_DATA,
+ FRV_ELF_DATA,
+ HPPA32_ELF_DATA,
+ HPPA64_ELF_DATA,
+ I386_ELF_DATA,
+ IA64_ELF_DATA,
+ LM32_ELF_DATA,
+ M32R_ELF_DATA,
+ M68HC11_ELF_DATA,
+ M68K_ELF_DATA,
+ METAG_ELF_DATA,
+ MICROBLAZE_ELF_DATA,
+ MIPS_ELF_DATA,
+ MN10300_ELF_DATA,
+ NDS32_ELF_DATA,
+ NIOS2_ELF_DATA,
+ OR1K_ELF_DATA,
+ PPC32_ELF_DATA,
+ PPC64_ELF_DATA,
+ S390_ELF_DATA,
+ SH_ELF_DATA,
+ SPARC_ELF_DATA,
+ SPU_ELF_DATA,
+ TIC6X_ELF_DATA,
+ X86_64_ELF_DATA,
+ XTENSA_ELF_DATA,
+ XGATE_ELF_DATA,
+ TILEGX_ELF_DATA,
+ TILEPRO_ELF_DATA,
+ GENERIC_ELF_DATA
+};
+
+/* ELF linker hash table. */
+
+struct elf_link_hash_table
+{
+ struct bfd_link_hash_table root;
+
+ /* An identifier used to distinguish different target
+ specific extensions to this structure. */
+ enum elf_target_id hash_table_id;
+
+ /* Whether we have created the special dynamic sections required
+ when linking against or generating a shared object. */
+ bfd_boolean dynamic_sections_created;
+
+ /* True if this target has relocatable executables, so needs dynamic
+ section symbols. */
+ bfd_boolean is_relocatable_executable;
+
+ /* 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 value to use when initialising got.refcount/offset and
+ plt.refcount/offset in an elf_link_hash_entry. Set to zero when
+ the values are refcounts. Set to init_got_offset/init_plt_offset
+ in size_dynamic_sections when the values may be offsets. */
+ union gotplt_union init_got_refcount;
+ union gotplt_union init_plt_refcount;
+
+ /* The value to use for got.refcount/offset and plt.refcount/offset
+ when the values may be offsets. Normally (bfd_vma) -1. */
+ union gotplt_union init_got_offset;
+ union gotplt_union init_plt_offset;
+
+ /* 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 elf_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;
+
+ /* Sections in the output bfd that provides a section symbol
+ to be used by relocations emitted against local symbols.
+ Most targets will not use data_index_section. */
+ asection *text_index_section;
+ asection *data_index_section;
+
+ /* The _GLOBAL_OFFSET_TABLE_ symbol. */
+ struct elf_link_hash_entry *hgot;
+
+ /* The _PROCEDURE_LINKAGE_TABLE_ symbol. */
+ struct elf_link_hash_entry *hplt;
+
+ /* The _DYNAMIC symbol. */
+ struct elf_link_hash_entry *hdynamic;
+
+ /* A pointer to information used to merge SEC_MERGE sections. */
+ void *merge_info;
+
+ /* Used to link stabs in sections. */
+ struct stab_info stab_info;
+
+ /* Used by eh_frame code when editing .eh_frame. */
+ struct eh_frame_hdr_info eh_info;
+
+ /* A linked list of local symbols to be added to .dynsym. */
+ struct elf_link_local_dynamic_entry *dynlocal;
+
+ /* A linked list of DT_RPATH/DT_RUNPATH names found in dynamic
+ objects included in the link. */
+ struct bfd_link_needed_list *runpath;
+
+ /* Cached first output tls section and size of PT_TLS segment. */
+ asection *tls_sec;
+ bfd_size_type tls_size;
+
+ /* A linked list of BFD's loaded in the link. */
+ struct elf_link_loaded_list *loaded;
+
+ /* Short-cuts to get to dynamic linker sections. */
+ asection *sgot;
+ asection *sgotplt;
+ asection *srelgot;
+ asection *splt;
+ asection *srelplt;
+ asection *igotplt;
+ asection *iplt;
+ asection *irelplt;
+ asection *irelifunc;
+};
+
+/* 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, \
+ (bfd_boolean (*) (struct bfd_link_hash_entry *, void *)) (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))
+
+#define elf_hash_table_id(table) ((table) -> hash_table_id)
+
+/* Returns TRUE if the hash table is a struct elf_link_hash_table. */
+#define is_elf_hash_table(htab) \
+ (((struct bfd_link_hash_table *) (htab))->type == bfd_link_elf_hash_table)
+
+/* Used by bfd_sym_from_r_symndx to cache a small number of local
+ symbols. */
+#define LOCAL_SYM_CACHE_SIZE 32
+struct sym_cache
+{
+ bfd *abfd;
+ unsigned long indx[LOCAL_SYM_CACHE_SIZE];
+ Elf_Internal_Sym sym[LOCAL_SYM_CACHE_SIZE];
+};
+
+/* 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;
+
+ /* The size of entries in the .hash section. */
+ unsigned char sizeof_hash_entry;
+
+ /* The number of internal relocations to allocate per external
+ relocation entry. */
+ unsigned char int_rels_per_ext_rel;
+ /* We use some fixed size arrays. This should be large enough to
+ handle all back-ends. */
+#define MAX_INT_RELS_PER_EXT_REL 3
+
+ unsigned char arch_size, log_file_align;
+ unsigned char elfclass, ev_current;
+ int (*write_out_phdrs)
+ (bfd *, const Elf_Internal_Phdr *, unsigned int);
+ bfd_boolean
+ (*write_shdrs_and_ehdr) (bfd *);
+ bfd_boolean (*checksum_contents)
+ (bfd * , void (*) (const void *, size_t, void *), void *);
+ void (*write_relocs)
+ (bfd *, asection *, void *);
+ bfd_boolean (*swap_symbol_in)
+ (bfd *, const void *, const void *, Elf_Internal_Sym *);
+ void (*swap_symbol_out)
+ (bfd *, const Elf_Internal_Sym *, void *, void *);
+ bfd_boolean (*slurp_reloc_table)
+ (bfd *, asection *, asymbol **, bfd_boolean);
+ long (*slurp_symbol_table)
+ (bfd *, asymbol **, bfd_boolean);
+ void (*swap_dyn_in)
+ (bfd *, const void *, Elf_Internal_Dyn *);
+ void (*swap_dyn_out)
+ (bfd *, const Elf_Internal_Dyn *, void *);
+
+ /* This function is called to swap in a REL relocation. If an
+ external relocation corresponds to more than one internal
+ relocation, then all relocations are swapped in at once. */
+ void (*swap_reloc_in)
+ (bfd *, const bfd_byte *, Elf_Internal_Rela *);
+
+ /* This function is called to swap out a REL relocation. */
+ void (*swap_reloc_out)
+ (bfd *, const Elf_Internal_Rela *, bfd_byte *);
+
+ /* This function is called to swap in a RELA relocation. If an
+ external relocation corresponds to more than one internal
+ relocation, then all relocations are swapped in at once. */
+ void (*swap_reloca_in)
+ (bfd *, const bfd_byte *, Elf_Internal_Rela *);
+
+ /* This function is called to swap out a RELA relocation. */
+ void (*swap_reloca_out)
+ (bfd *, const Elf_Internal_Rela *, bfd_byte *);
+};
+
+#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)
+
+enum elf_reloc_type_class {
+ reloc_class_normal,
+ reloc_class_relative,
+ reloc_class_plt,
+ reloc_class_copy,
+ reloc_class_ifunc
+};
+
+struct elf_reloc_cookie
+{
+ Elf_Internal_Rela *rels, *rel, *relend;
+ Elf_Internal_Sym *locsyms;
+ bfd *abfd;
+ size_t locsymcount;
+ size_t extsymoff;
+ struct elf_link_hash_entry **sym_hashes;
+ int r_sym_shift;
+ bfd_boolean bad_symtab;
+};
+
+/* The level of IRIX compatibility we're striving for. */
+
+typedef enum {
+ ict_none,
+ ict_irix5,
+ ict_irix6
+} irix_compat_t;
+
+/* Mapping of ELF section names and types. */
+struct bfd_elf_special_section
+{
+ const char *prefix;
+ int prefix_length;
+ /* 0 means name must match PREFIX exactly.
+ -1 means name must start with PREFIX followed by an arbitrary string.
+ -2 means name must match PREFIX exactly or consist of PREFIX followed
+ by a dot then anything.
+ > 0 means name must start with the first PREFIX_LENGTH chars of
+ PREFIX and finish with the last SUFFIX_LENGTH chars of PREFIX. */
+ int suffix_length;
+ int type;
+ bfd_vma attr;
+};
+
+enum action_discarded
+ {
+ COMPLAIN = 1,
+ PRETEND = 2
+ };
+
+typedef asection * (*elf_gc_mark_hook_fn)
+ (asection *, struct bfd_link_info *, Elf_Internal_Rela *,
+ struct elf_link_hash_entry *, Elf_Internal_Sym *);
+
+struct elf_backend_data
+{
+ /* The architecture for this backend. */
+ enum bfd_architecture arch;
+
+ /* An identifier used to distinguish different target specific
+ extensions to elf_obj_tdata and elf_link_hash_table structures. */
+ enum elf_target_id target_id;
+
+ /* The ELF machine code (EM_xxxx) for this backend. */
+ int elf_machine_code;
+
+ /* EI_OSABI. */
+ int elf_osabi;
+
+ /* The maximum page size for this backend. */
+ bfd_vma maxpagesize;
+
+ /* The minimum page size for this backend. An input object will not be
+ considered page aligned unless its sections are correctly aligned for
+ pages at least this large. May be smaller than maxpagesize. */
+ bfd_vma minpagesize;
+
+ /* The common page size for this backend. */
+ bfd_vma commonpagesize;
+
+ /* The BFD flags applied to sections created for dynamic linking. */
+ flagword dynamic_sec_flags;
+
+ /* Architecture-specific data for this backend.
+ This is actually a pointer to some type like struct elf_ARCH_data. */
+ const void *arch_data;
+
+ /* A function to translate an ELF RELA relocation to a BFD arelent
+ structure. */
+ void (*elf_info_to_howto)
+ (bfd *, arelent *, Elf_Internal_Rela *);
+
+ /* A function to translate an ELF REL relocation to a BFD arelent
+ structure. */
+ void (*elf_info_to_howto_rel)
+ (bfd *, arelent *, Elf_Internal_Rela *);
+
+ /* 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. */
+ bfd_boolean (*elf_backend_sym_is_global)
+ (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. */
+ bfd_boolean (*elf_backend_object_p)
+ (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)
+ (bfd *, asymbol *);
+
+ /* A function to do additional symbol processing after reading the
+ entire ELF symbol table. */
+ bfd_boolean (*elf_backend_symbol_table_processing)
+ (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)
+ (Elf_Internal_Sym *, int);
+
+ /* A function to return the linker hash table entry of a symbol that
+ might be satisfied by an archive symbol. */
+ struct elf_link_hash_entry * (*elf_backend_archive_symbol_lookup)
+ (bfd *, struct bfd_link_info *, const char *);
+
+ /* Return true if local section symbols should have a non-null st_name.
+ NULL implies false. */
+ bfd_boolean (*elf_backend_name_local_section_symbols)
+ (bfd *);
+
+ /* 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. */
+ bfd_boolean (*elf_backend_section_processing)
+ (bfd *, Elf_Internal_Shdr *);
+
+ /* A function to handle unusual section types when creating BFD
+ sections from ELF sections. */
+ bfd_boolean (*elf_backend_section_from_shdr)
+ (bfd *, Elf_Internal_Shdr *, const char *, int);
+
+ /* A function to convert machine dependent ELF section header flags to
+ BFD internal section header flags. */
+ bfd_boolean (*elf_backend_section_flags)
+ (flagword *, const Elf_Internal_Shdr *);
+
+ /* A function that returns a struct containing ELF section flags and
+ type for the given BFD section. */
+ const struct bfd_elf_special_section * (*get_sec_type_attr)
+ (bfd *, asection *);
+
+ /* A function to handle unusual program segment types when creating BFD
+ sections from ELF program segments. */
+ bfd_boolean (*elf_backend_section_from_phdr)
+ (bfd *, Elf_Internal_Phdr *, int, const 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. */
+ bfd_boolean (*elf_backend_fake_sections)
+ (bfd *, Elf_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. */
+ bfd_boolean (*elf_backend_section_from_bfd_section)
+ (bfd *, 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. */
+ bfd_boolean (*elf_add_symbol_hook)
+ (bfd *abfd, struct bfd_link_info *info, 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.
+ On error, this function returns 0. 1 is returned when the symbol
+ should be output, 2 is returned when the symbol should be discarded. */
+ int (*elf_backend_link_output_symbol_hook)
+ (struct bfd_link_info *info, const char *, Elf_Internal_Sym *,
+ asection *, struct elf_link_hash_entry *);
+
+ /* 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. */
+ bfd_boolean (*elf_backend_create_dynamic_sections)
+ (bfd *abfd, struct bfd_link_info *info);
+
+ /* When creating a shared library, determine whether to omit the
+ dynamic symbol for the section. */
+ bfd_boolean (*elf_backend_omit_section_dynsym)
+ (bfd *output_bfd, struct bfd_link_info *info, asection *osec);
+
+ /* Return TRUE if relocations of targets are compatible to the extent
+ that CHECK_RELOCS will properly process them. PR 4424. */
+ bfd_boolean (*relocs_compatible) (const bfd_target *, const bfd_target *);
+
+ /* 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. */
+ bfd_boolean (*check_relocs)
+ (bfd *abfd, struct bfd_link_info *info, asection *o,
+ const Elf_Internal_Rela *relocs);
+
+ /* The CHECK_DIRECTIVES function is called once per input file by
+ the add_symbols phase of the ELF backend linker. The function
+ must inspect the bfd and create any additional symbols according
+ to any custom directives in the bfd. */
+ bfd_boolean (*check_directives)
+ (bfd *abfd, struct bfd_link_info *info);
+
+ /* The NOTICE_AS_NEEDED function is called as the linker is about to
+ handle an as-needed lib (ACT = notice_as_needed), and after the
+ linker has decided to keep the lib (ACT = notice_needed) or when
+ the lib is not needed (ACT = notice_not_needed). */
+ bfd_boolean (*notice_as_needed)
+ (bfd *abfd, struct bfd_link_info *info, enum notice_asneeded_action act);
+
+ /* 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. */
+ bfd_boolean (*elf_backend_adjust_dynamic_symbol)
+ (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. */
+ bfd_boolean (*elf_backend_always_size_sections)
+ (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. */
+ bfd_boolean (*elf_backend_size_dynamic_sections)
+ (bfd *output_bfd, struct bfd_link_info *info);
+
+ /* Set TEXT_INDEX_SECTION and DATA_INDEX_SECTION, the output sections
+ we keep to use as a base for relocs and symbols. */
+ void (*elf_backend_init_index_section)
+ (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
+ relocatable 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 relocatable 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.
+
+ Returns FALSE on error, TRUE on success, 2 if successful and
+ relocations should be written for this section. */
+ int (*elf_backend_relocate_section)
+ (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. */
+ bfd_boolean (*elf_backend_finish_dynamic_symbol)
+ (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. */
+ bfd_boolean (*elf_backend_finish_dynamic_sections)
+ (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)
+ (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)
+ (bfd *, 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)
+ (bfd *, struct bfd_link_info *);
+
+ /* This function is called to modify an existing segment map in a
+ backend specific fashion. */
+ bfd_boolean (*elf_backend_modify_segment_map)
+ (bfd *, struct bfd_link_info *);
+
+ /* This function is called to modify program headers just before
+ they are written. */
+ bfd_boolean (*elf_backend_modify_program_headers)
+ (bfd *, struct bfd_link_info *);
+
+ /* This function is called before section garbage collection to
+ mark entry symbol sections. */
+ void (*gc_keep)
+ (struct bfd_link_info *);
+
+ /* This function is called during section garbage collection to
+ mark sections that define global symbols. */
+ bfd_boolean (*gc_mark_dynamic_ref)
+ (struct elf_link_hash_entry *, void *);
+
+ /* This function is called during section gc to discover the section a
+ particular relocation refers to. */
+ elf_gc_mark_hook_fn gc_mark_hook;
+
+ /* This function, if defined, is called after the first gc marking pass
+ to allow the backend to mark additional sections. */
+ bfd_boolean (*gc_mark_extra_sections)
+ (struct bfd_link_info *, elf_gc_mark_hook_fn);
+
+ /* 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. */
+ bfd_boolean (*gc_sweep_hook)
+ (bfd *, struct bfd_link_info *, asection *, const Elf_Internal_Rela *);
+
+ /* This function, if defined, is called after the ELF headers have
+ been created. This allows for things like the OS and ABI versions
+ to be changed. */
+ void (*elf_backend_post_process_headers)
+ (bfd *, struct bfd_link_info *);
+
+ /* This function, if defined, prints a symbol to file and returns the
+ name of the symbol to be printed. It should return NULL to fall
+ back to default symbol printing. */
+ const char *(*elf_backend_print_symbol_all)
+ (bfd *, void *, asymbol *);
+
+ /* This function, if defined, is called after all local symbols and
+ global symbols converted to locals are emitted into the symtab
+ section. It allows the backend to emit special local symbols
+ not handled in the hash table. */
+ bfd_boolean (*elf_backend_output_arch_local_syms)
+ (bfd *, struct bfd_link_info *, void *,
+ bfd_boolean (*) (void *, const char *, Elf_Internal_Sym *, asection *,
+ struct elf_link_hash_entry *));
+
+ /* This function, if defined, is called after all symbols are emitted
+ into the symtab section. It allows the backend to emit special
+ global symbols not handled in the hash table. */
+ bfd_boolean (*elf_backend_output_arch_syms)
+ (bfd *, struct bfd_link_info *, void *,
+ bfd_boolean (*) (void *, const char *, Elf_Internal_Sym *, asection *,
+ struct elf_link_hash_entry *));
+
+ /* Copy any information related to dynamic linking from a pre-existing
+ symbol to a newly created symbol. Also called to copy flags and
+ other back-end info to a weakdef, in which case the symbol is not
+ newly created and plt/got refcounts and dynamic indices should not
+ be copied. */
+ void (*elf_backend_copy_indirect_symbol)
+ (struct bfd_link_info *, struct elf_link_hash_entry *,
+ struct elf_link_hash_entry *);
+
+ /* Modify any information related to dynamic linking such that the
+ symbol is not exported. */
+ void (*elf_backend_hide_symbol)
+ (struct bfd_link_info *, struct elf_link_hash_entry *, bfd_boolean);
+
+ /* A function to do additional symbol fixup, called by
+ _bfd_elf_fix_symbol_flags. */
+ bfd_boolean (*elf_backend_fixup_symbol)
+ (struct bfd_link_info *, struct elf_link_hash_entry *);
+
+ /* Merge the backend specific symbol attribute. */
+ void (*elf_backend_merge_symbol_attribute)
+ (struct elf_link_hash_entry *, const Elf_Internal_Sym *, bfd_boolean,
+ bfd_boolean);
+
+ /* This function, if defined, will return a string containing the
+ name of a target-specific dynamic tag. */
+ char *(*elf_backend_get_target_dtag)
+ (bfd_vma);
+
+ /* Decide whether an undefined symbol is special and can be ignored.
+ This is the case for OPTIONAL symbols on IRIX. */
+ bfd_boolean (*elf_backend_ignore_undef_symbol)
+ (struct elf_link_hash_entry *);
+
+ /* Emit relocations. Overrides default routine for emitting relocs,
+ except during a relocatable link, or if all relocs are being emitted. */
+ bfd_boolean (*elf_backend_emit_relocs)
+ (bfd *, asection *, Elf_Internal_Shdr *, Elf_Internal_Rela *,
+ struct elf_link_hash_entry **);
+
+ /* Count relocations. Not called for relocatable links
+ or if all relocs are being preserved in the output. */
+ unsigned int (*elf_backend_count_relocs)
+ (struct bfd_link_info *, asection *);
+
+ /* This function, if defined, is called when an NT_PRSTATUS note is found
+ in a core file. */
+ bfd_boolean (*elf_backend_grok_prstatus)
+ (bfd *, Elf_Internal_Note *);
+
+ /* This function, if defined, is called when an NT_PSINFO or NT_PRPSINFO
+ note is found in a core file. */
+ bfd_boolean (*elf_backend_grok_psinfo)
+ (bfd *, Elf_Internal_Note *);
+
+ /* This function, if defined, is called to write a note to a corefile. */
+ char *(*elf_backend_write_core_note)
+ (bfd *abfd, char *buf, int *bufsiz, int note_type, ...);
+
+ /* This function, if defined, is called to convert target-specific
+ section flag names into hex values. */
+ flagword (*elf_backend_lookup_section_flags_hook)
+ (char *);
+
+ /* This function returns class of a reloc type. */
+ enum elf_reloc_type_class (*elf_backend_reloc_type_class)
+ (const struct bfd_link_info *, const asection *, const Elf_Internal_Rela *);
+
+ /* This function, if defined, removes information about discarded functions
+ from other sections which mention them. */
+ bfd_boolean (*elf_backend_discard_info)
+ (bfd *, struct elf_reloc_cookie *, struct bfd_link_info *);
+
+ /* This function, if defined, signals that the function above has removed
+ the discarded relocations for this section. */
+ bfd_boolean (*elf_backend_ignore_discarded_relocs)
+ (asection *);
+
+ /* What to do when ld finds relocations against symbols defined in
+ discarded sections. */
+ unsigned int (*action_discarded)
+ (asection *);
+
+ /* This function returns the width of FDE pointers in bytes, or 0 if
+ that can't be determined for some reason. The default definition
+ goes by the bfd's EI_CLASS. */
+ unsigned int (*elf_backend_eh_frame_address_size)
+ (bfd *, asection *);
+
+ /* These functions tell elf-eh-frame whether to attempt to turn
+ absolute or lsda encodings into pc-relative ones. The default
+ definition enables these transformations. */
+ bfd_boolean (*elf_backend_can_make_relative_eh_frame)
+ (bfd *, struct bfd_link_info *, asection *);
+ bfd_boolean (*elf_backend_can_make_lsda_relative_eh_frame)
+ (bfd *, struct bfd_link_info *, asection *);
+
+ /* This function returns an encoding after computing the encoded
+ value (and storing it in ENCODED) for the given OFFSET into OSEC,
+ to be stored in at LOC_OFFSET into the LOC_SEC input section.
+ The default definition chooses a 32-bit PC-relative encoding. */
+ bfd_byte (*elf_backend_encode_eh_address)
+ (bfd *abfd, struct bfd_link_info *info,
+ asection *osec, bfd_vma offset,
+ asection *loc_sec, bfd_vma loc_offset,
+ bfd_vma *encoded);
+
+ /* This function, if defined, may write out the given section.
+ Returns TRUE if it did so and FALSE if the caller should. */
+ bfd_boolean (*elf_backend_write_section)
+ (bfd *, struct bfd_link_info *, asection *, bfd_byte *);
+
+ /* The level of IRIX compatibility we're striving for.
+ MIPS ELF specific function. */
+ irix_compat_t (*elf_backend_mips_irix_compat)
+ (bfd *);
+
+ reloc_howto_type *(*elf_backend_mips_rtype_to_howto)
+ (unsigned int, bfd_boolean);
+
+ /* 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;
+
+ /* This function implements `bfd_elf_bfd_from_remote_memory';
+ see elf.c, elfcode.h. */
+ bfd *(*elf_backend_bfd_from_remote_memory)
+ (bfd *templ, bfd_vma ehdr_vma, bfd_size_type size, bfd_vma *loadbasep,
+ int (*target_read_memory) (bfd_vma vma, bfd_byte *myaddr,
+ bfd_size_type len));
+
+ /* This function is used by `_bfd_elf_get_synthetic_symtab';
+ see elf.c. */
+ bfd_vma (*plt_sym_val) (bfd_vma, const asection *, const arelent *);
+
+ /* Is symbol defined in common section? */
+ bfd_boolean (*common_definition) (Elf_Internal_Sym *);
+
+ /* Return a common section index for section. */
+ unsigned int (*common_section_index) (asection *);
+
+ /* Return a common section for section. */
+ asection *(*common_section) (asection *);
+
+ /* Return TRUE if we can merge 2 definitions. */
+ bfd_boolean (*merge_symbol) (struct elf_link_hash_entry *,
+ const Elf_Internal_Sym *, asection **,
+ bfd_boolean, bfd_boolean,
+ bfd *, const asection *);
+
+ /* Return TRUE if symbol should be hashed in the `.gnu.hash' section. */
+ bfd_boolean (*elf_hash_symbol) (struct elf_link_hash_entry *);
+
+ /* Return TRUE if type is a function symbol type. */
+ bfd_boolean (*is_function_type) (unsigned int type);
+
+ /* If the ELF symbol SYM might be a function in SEC, return the
+ function size and set *CODE_OFF to the function's entry point,
+ otherwise return zero. */
+ bfd_size_type (*maybe_function_sym) (const asymbol *sym, asection *sec,
+ bfd_vma *code_off);
+
+ /* Used to handle bad SHF_LINK_ORDER input. */
+ bfd_error_handler_type link_order_error_handler;
+
+ /* Name of the PLT relocation section. */
+ const char *relplt_name;
+
+ /* Alternate EM_xxxx machine codes for this backend. */
+ int elf_machine_alt1;
+ int elf_machine_alt2;
+
+ const struct elf_size_info *s;
+
+ /* An array of target specific special sections. */
+ const struct bfd_elf_special_section *special_sections;
+
+ /* The size in bytes of the header for the GOT. This includes the
+ so-called reserved entries on some systems. */
+ bfd_vma got_header_size;
+
+ /* The size of the GOT entry for the symbol pointed to by H if non-NULL,
+ otherwise by the local symbol with index SYMNDX in IBFD. */
+ bfd_vma (*got_elt_size) (bfd *, struct bfd_link_info *,
+ struct elf_link_hash_entry *h,
+ bfd *ibfd, unsigned long symndx);
+
+ /* The vendor name to use for a processor-standard attributes section. */
+ const char *obj_attrs_vendor;
+
+ /* The section name to use for a processor-standard attributes section. */
+ const char *obj_attrs_section;
+
+ /* Return 1, 2 or 3 to indicate what type of arguments a
+ processor-specific tag takes. */
+ int (*obj_attrs_arg_type) (int);
+
+ /* The section type to use for an attributes section. */
+ unsigned int obj_attrs_section_type;
+
+ /* This function determines the order in which any attributes are
+ written. It must be defined for input in the range
+ LEAST_KNOWN_OBJ_ATTRIBUTE..NUM_KNOWN_OBJ_ATTRIBUTES-1 (this range
+ is used in order to make unity easy). The returned value is the
+ actual tag number to place in the input position. */
+ int (*obj_attrs_order) (int);
+
+ /* Handle merging unknown attributes; either warn and return TRUE,
+ or give an error and return FALSE. */
+ bfd_boolean (*obj_attrs_handle_unknown) (bfd *, int);
+
+ /* This is non-zero if static TLS segments require a special alignment. */
+ unsigned static_tls_alignment;
+
+ /* Alignment for the PT_GNU_STACK segment. */
+ unsigned stack_align;
+
+ /* 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. */
+ unsigned collect : 1;
+
+ /* 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. */
+ unsigned type_change_ok : 1;
+
+ /* Whether the backend may use REL relocations. (Some backends use
+ both REL and RELA relocations, and this flag is set for those
+ backends.) */
+ unsigned may_use_rel_p : 1;
+
+ /* Whether the backend may use RELA relocations. (Some backends use
+ both REL and RELA relocations, and this flag is set for those
+ backends.) */
+ unsigned may_use_rela_p : 1;
+
+ /* Whether the default relocation type is RELA. If a backend with
+ this flag set wants REL relocations for a particular section,
+ it must note that explicitly. Similarly, if this flag is clear,
+ and the backend wants RELA relocations for a particular
+ section. */
+ unsigned default_use_rela_p : 1;
+
+ /* True if PLT and copy relocations should be RELA by default. */
+ unsigned rela_plts_and_copies_p : 1;
+
+ /* Set if RELA relocations for a relocatable link can be handled by
+ generic code. Backends that set this flag need do nothing in the
+ backend relocate_section routine for relocatable linking. */
+ unsigned rela_normal : 1;
+
+ /* TRUE if addresses "naturally" sign extend. This is used when
+ swapping in from Elf32 when BFD64. */
+ unsigned sign_extend_vma : 1;
+
+ 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;
+ unsigned can_refcount : 1;
+ unsigned want_got_sym : 1;
+ unsigned want_dynbss : 1;
+
+ /* Targets which do not support physical addressing often require
+ that the p_paddr field in the section header to be set to zero.
+ This field indicates whether this behavior is required. */
+ unsigned want_p_paddr_set_to_zero : 1;
+
+ /* True if an object file lacking a .note.GNU-stack section
+ should be assumed to be requesting exec stack. At least one
+ other file in the link needs to have a .note.GNU-stack section
+ for a PT_GNU_STACK segment to be created. */
+ unsigned default_execstack : 1;
+
+ /* True if elf_section_data(sec)->this_hdr.contents is sec->rawsize
+ in length rather than sec->size in length, if sec->rawsize is
+ non-zero and smaller than sec->size. */
+ unsigned caches_rawsize : 1;
+};
+
+/* Information about reloc sections associated with a bfd_elf_section_data
+ structure. */
+struct bfd_elf_section_reloc_data
+{
+ /* The ELF header for the reloc section associated with this
+ section, if any. */
+ Elf_Internal_Shdr *hdr;
+ /* The number of relocations currently assigned to HDR. */
+ unsigned int count;
+ /* The ELF section number of the reloc section. Only used for an
+ output file. */
+ int idx;
+ /* Used by the backend linker to store the symbol hash table entries
+ associated with relocs against global symbols. */
+ struct elf_link_hash_entry **hashes;
+};
+
+/* 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;
+
+ /* INPUT_SECTION_FLAGS if specified in the linker script. */
+ struct flag_info *section_flag_info;
+
+ /* Information about the REL and RELA reloc sections associated
+ with this section, if any. */
+ struct bfd_elf_section_reloc_data rel, rela;
+
+ /* The ELF section number of this section. */
+ int this_idx;
+
+ /* Used by the backend linker when generating a shared library to
+ record the dynamic symbol index for a section symbol
+ corresponding to this section. A value of 0 means that there is
+ no dynamic symbol for this section. */
+ int dynindx;
+
+ /* A pointer to the linked-to section for SHF_LINK_ORDER. */
+ asection *linked_to;
+
+ /* 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;
+
+ /* A pointer to a linked list tracking dynamic relocs copied for
+ local symbols. */
+ void *local_dynrel;
+
+ /* A pointer to the bfd section used for dynamic relocs. */
+ asection *sreloc;
+
+ union {
+ /* Group name, if this section is a member of a group. */
+ const char *name;
+
+ /* Group signature sym, if this is the SHT_GROUP section. */
+ struct bfd_symbol *id;
+ } group;
+
+ /* For a member of a group, points to the SHT_GROUP section.
+ NULL for the SHT_GROUP section itself and non-group sections. */
+ asection *sec_group;
+
+ /* A linked list of member sections in the group. Circular when used by
+ the linker. For the SHT_GROUP section, points at first member. */
+ asection *next_in_group;
+
+ /* The FDEs associated with this section. The u.fde.next_in_section
+ field acts as a chain pointer. */
+ struct eh_cie_fde *fde_list;
+
+ /* A pointer used for various section optimizations. */
+ void *sec_info;
+};
+
+#define elf_section_data(sec) ((struct bfd_elf_section_data*)(sec)->used_by_bfd)
+#define elf_linked_to_section(sec) (elf_section_data(sec)->linked_to)
+#define elf_section_type(sec) (elf_section_data(sec)->this_hdr.sh_type)
+#define elf_section_flags(sec) (elf_section_data(sec)->this_hdr.sh_flags)
+#define elf_group_name(sec) (elf_section_data(sec)->group.name)
+#define elf_group_id(sec) (elf_section_data(sec)->group.id)
+#define elf_next_in_group(sec) (elf_section_data(sec)->next_in_group)
+#define elf_fde_list(sec) (elf_section_data(sec)->fde_list)
+#define elf_sec_group(sec) (elf_section_data(sec)->sec_group)
+
+#define xvec_get_elf_backend_data(xvec) \
+ ((const struct elf_backend_data *) (xvec)->backend_data)
+
+#define get_elf_backend_data(abfd) \
+ xvec_get_elf_backend_data ((abfd)->xvec)
+
+/* The least object attributes (within an attributes subsection) known
+ for any target. Some code assumes that the value 0 is not used and
+ the field for that attribute can instead be used as a marker to
+ indicate that attributes have been initialized. */
+#define LEAST_KNOWN_OBJ_ATTRIBUTE 2
+
+/* The maximum number of known object attributes for any target. */
+#define NUM_KNOWN_OBJ_ATTRIBUTES 71
+
+/* The value of an object attribute. The type indicates whether the attribute
+ holds and integer, a string, or both. It can also indicate that there can
+ be no default (i.e. all values must be written to file, even zero). */
+
+typedef struct obj_attribute
+{
+#define ATTR_TYPE_FLAG_INT_VAL (1 << 0)
+#define ATTR_TYPE_FLAG_STR_VAL (1 << 1)
+#define ATTR_TYPE_FLAG_NO_DEFAULT (1 << 2)
+
+#define ATTR_TYPE_HAS_INT_VAL(TYPE) ((TYPE) & ATTR_TYPE_FLAG_INT_VAL)
+#define ATTR_TYPE_HAS_STR_VAL(TYPE) ((TYPE) & ATTR_TYPE_FLAG_STR_VAL)
+#define ATTR_TYPE_HAS_NO_DEFAULT(TYPE) ((TYPE) & ATTR_TYPE_FLAG_NO_DEFAULT)
+
+ int type;
+ unsigned int i;
+ char *s;
+} obj_attribute;
+
+typedef struct obj_attribute_list
+{
+ struct obj_attribute_list *next;
+ int tag;
+ obj_attribute attr;
+} obj_attribute_list;
+
+/* Object attributes may either be defined by the processor ABI, index
+ OBJ_ATTR_PROC in the *_obj_attributes arrays, or be GNU-specific
+ (and possibly also processor-specific), index OBJ_ATTR_GNU. */
+#define OBJ_ATTR_PROC 0
+#define OBJ_ATTR_GNU 1
+#define OBJ_ATTR_FIRST OBJ_ATTR_PROC
+#define OBJ_ATTR_LAST OBJ_ATTR_GNU
+
+/* The following object attribute tags are taken as generic, for all
+ targets and for "gnu" where there is no target standard. */
+enum
+{
+ Tag_NULL = 0,
+ Tag_File = 1,
+ Tag_Section = 2,
+ Tag_Symbol = 3,
+ Tag_compatibility = 32
+};
+
+/* The following struct stores information about every SystemTap section
+ found in the object file. */
+struct sdt_note
+{
+ struct sdt_note *next;
+ bfd_size_type size;
+ bfd_byte data[1];
+};
+
+/* NT_GNU_BUILD_ID note type info for input BFDs. */
+struct elf_build_id
+{
+ size_t size;
+ bfd_byte data[1];
+};
+
+/* tdata information grabbed from an elf core file. */
+struct core_elf_obj_tdata
+{
+ int signal;
+ int pid;
+ int lwpid;
+ char* program;
+ char* command;
+};
+
+/* Extra tdata information held for output ELF BFDs. */
+struct output_elf_obj_tdata
+{
+ struct elf_segment_map *seg_map;
+ struct elf_strtab_hash *strtab_ptr;
+
+ /* STT_SECTION symbols for each section */
+ asymbol **section_syms;
+
+ /* Used to determine if PT_GNU_EH_FRAME segment header should be
+ created. */
+ asection *eh_frame_hdr;
+
+ /* NT_GNU_BUILD_ID note type info. */
+ struct
+ {
+ bfd_boolean (*after_write_object_contents) (bfd *);
+ const char *style;
+ asection *sec;
+ } build_id;
+
+ /* Records the result of `get_program_header_size'. */
+ bfd_size_type program_header_size;
+
+ /* Used when laying out sections. */
+ file_ptr next_file_pos;
+
+ int num_section_syms;
+ unsigned int shstrtab_section, strtab_section;
+
+ /* Segment flags for the PT_GNU_STACK segment. */
+ unsigned int stack_flags;
+
+ /* This is set to TRUE if the object was created by the backend
+ linker. */
+ bfd_boolean linker;
+
+ /* Used to determine if the e_flags field has been initialized */
+ bfd_boolean flags_init;
+};
+
+/* 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;
+ 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;
+ Elf_Internal_Shdr symtab_shndx_hdr;
+ bfd_vma gp; /* The gp value */
+ unsigned int gp_size; /* The gp size */
+ unsigned int num_elf_sections; /* elf_sect_ptr size */
+
+ /* 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;
+
+ /* Track usage and final offsets of GOT entries for local symbols.
+ This array is indexed by symbol index. Elements are used
+ identically to "got" in struct elf_link_hash_entry. */
+ union
+ {
+ bfd_signed_vma *refcounts;
+ bfd_vma *offsets;
+ struct got_entry **ents;
+ } local_got;
+
+ /* 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;
+
+ /* The linker emulation needs to know what audit libs
+ are used by a dynamic object. */
+ const char *dt_audit;
+
+ /* Used by find_nearest_line entry point. */
+ void *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. */
+ void *dwarf2_find_line_info;
+
+ /* Stash away info for yet another find line/function variant. */
+ void *elf_find_function_cache;
+
+ /* 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;
+
+ /* A pointer to the .eh_frame section. */
+ asection *eh_frame_section;
+
+ /* Symbol buffer. */
+ void *symbuf;
+
+ obj_attribute known_obj_attributes[2][NUM_KNOWN_OBJ_ATTRIBUTES];
+ obj_attribute_list *other_obj_attributes[2];
+
+ /* NT_GNU_BUILD_ID note type. */
+ struct elf_build_id *build_id;
+
+ /* Linked-list containing information about every Systemtap section
+ found in the object file. Each section corresponds to one entry
+ in the list. */
+ struct sdt_note *sdt_note_head;
+
+ Elf_Internal_Shdr **group_sect_ptr;
+ int num_group;
+
+ unsigned int symtab_section, symtab_shndx_section, dynsymtab_section;
+ unsigned int dynversym_section, dynverdef_section, dynverref_section;
+
+ /* An identifier used to distinguish different target
+ specific extensions to this structure. */
+ enum elf_target_id object_id;
+
+ /* Whether a dyanmic object was specified normally on the linker
+ command line, or was specified when --as-needed was in effect,
+ or was found via a DT_NEEDED entry. */
+ enum dynamic_lib_link_class dyn_lib_class;
+
+ /* 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. */
+ bfd_boolean bad_symtab;
+
+ /* True if the bfd contains symbols that have the STT_GNU_IFUNC
+ symbol type or STB_GNU_UNIQUE binding. Used to set the osabi
+ field in the ELF header structure. */
+ bfd_boolean has_gnu_symbols;
+
+ /* Information grabbed from an elf core file. */
+ struct core_elf_obj_tdata *core;
+
+ /* More information held for output ELF BFDs. */
+ struct output_elf_obj_tdata *o;
+};
+
+#define elf_tdata(bfd) ((bfd) -> tdata.elf_obj_data)
+
+#define elf_object_id(bfd) (elf_tdata(bfd) -> object_id)
+#define elf_program_header_size(bfd) (elf_tdata(bfd) -> o->program_header_size)
+#define elf_elfheader(bfd) (elf_tdata(bfd) -> elf_header)
+#define elf_elfsections(bfd) (elf_tdata(bfd) -> elf_sect_ptr)
+#define elf_numsections(bfd) (elf_tdata(bfd) -> num_elf_sections)
+#define elf_seg_map(bfd) (elf_tdata(bfd) -> o->seg_map)
+#define elf_next_file_pos(bfd) (elf_tdata(bfd) -> o->next_file_pos)
+#define elf_eh_frame_hdr(bfd) (elf_tdata(bfd) -> o->eh_frame_hdr)
+#define elf_linker(bfd) (elf_tdata(bfd) -> o->linker)
+#define elf_stack_flags(bfd) (elf_tdata(bfd) -> o->stack_flags)
+#define elf_shstrtab(bfd) (elf_tdata(bfd) -> o->strtab_ptr)
+#define elf_onesymtab(bfd) (elf_tdata(bfd) -> symtab_section)
+#define elf_symtab_shndx(bfd) (elf_tdata(bfd) -> symtab_shndx_section)
+#define elf_strtab_sec(bfd) (elf_tdata(bfd) -> o->strtab_section)
+#define elf_shstrtab_sec(bfd) (elf_tdata(bfd) -> o->shstrtab_section)
+#define elf_symtab_hdr(bfd) (elf_tdata(bfd) -> symtab_hdr)
+#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_eh_frame_section(bfd) \
+ (elf_tdata(bfd) -> eh_frame_section)
+#define elf_section_syms(bfd) (elf_tdata(bfd) -> o->section_syms)
+#define elf_num_section_syms(bfd) (elf_tdata(bfd) -> o->num_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_got_ents(bfd) (elf_tdata(bfd) -> local_got.ents)
+#define elf_dt_name(bfd) (elf_tdata(bfd) -> dt_name)
+#define elf_dt_audit(bfd) (elf_tdata(bfd) -> dt_audit)
+#define elf_dyn_lib_class(bfd) (elf_tdata(bfd) -> dyn_lib_class)
+#define elf_bad_symtab(bfd) (elf_tdata(bfd) -> bad_symtab)
+#define elf_flags_init(bfd) (elf_tdata(bfd) -> o->flags_init)
+#define elf_known_obj_attributes(bfd) (elf_tdata (bfd) -> known_obj_attributes)
+#define elf_other_obj_attributes(bfd) (elf_tdata (bfd) -> other_obj_attributes)
+#define elf_known_obj_attributes_proc(bfd) \
+ (elf_known_obj_attributes (bfd) [OBJ_ATTR_PROC])
+#define elf_other_obj_attributes_proc(bfd) \
+ (elf_other_obj_attributes (bfd) [OBJ_ATTR_PROC])
+
+extern void _bfd_elf_swap_verdef_in
+ (bfd *, const Elf_External_Verdef *, Elf_Internal_Verdef *);
+extern void _bfd_elf_swap_verdef_out
+ (bfd *, const Elf_Internal_Verdef *, Elf_External_Verdef *);
+extern void _bfd_elf_swap_verdaux_in
+ (bfd *, const Elf_External_Verdaux *, Elf_Internal_Verdaux *);
+extern void _bfd_elf_swap_verdaux_out
+ (bfd *, const Elf_Internal_Verdaux *, Elf_External_Verdaux *);
+extern void _bfd_elf_swap_verneed_in
+ (bfd *, const Elf_External_Verneed *, Elf_Internal_Verneed *);
+extern void _bfd_elf_swap_verneed_out
+ (bfd *, const Elf_Internal_Verneed *, Elf_External_Verneed *);
+extern void _bfd_elf_swap_vernaux_in
+ (bfd *, const Elf_External_Vernaux *, Elf_Internal_Vernaux *);
+extern void _bfd_elf_swap_vernaux_out
+ (bfd *, const Elf_Internal_Vernaux *, Elf_External_Vernaux *);
+extern void _bfd_elf_swap_versym_in
+ (bfd *, const Elf_External_Versym *, Elf_Internal_Versym *);
+extern void _bfd_elf_swap_versym_out
+ (bfd *, const Elf_Internal_Versym *, Elf_External_Versym *);
+
+extern unsigned int _bfd_elf_section_from_bfd_section
+ (bfd *, asection *);
+extern char *bfd_elf_string_from_elf_section
+ (bfd *, unsigned, unsigned);
+extern Elf_Internal_Sym *bfd_elf_get_elf_syms
+ (bfd *, Elf_Internal_Shdr *, size_t, size_t, Elf_Internal_Sym *, void *,
+ Elf_External_Sym_Shndx *);
+extern const char *bfd_elf_sym_name
+ (bfd *, Elf_Internal_Shdr *, Elf_Internal_Sym *, asection *);
+
+extern bfd_boolean _bfd_elf_copy_private_bfd_data
+ (bfd *, bfd *);
+extern bfd_boolean _bfd_elf_print_private_bfd_data
+ (bfd *, void *);
+extern void bfd_elf_print_symbol
+ (bfd *, void *, asymbol *, bfd_print_symbol_type);
+
+extern unsigned int _bfd_elf_eh_frame_address_size
+ (bfd *, asection *);
+extern bfd_byte _bfd_elf_encode_eh_address
+ (bfd *abfd, struct bfd_link_info *info, asection *osec, bfd_vma offset,
+ asection *loc_sec, bfd_vma loc_offset, bfd_vma *encoded);
+extern bfd_boolean _bfd_elf_can_make_relative
+ (bfd *input_bfd, struct bfd_link_info *info, asection *eh_frame_section);
+
+extern enum elf_reloc_type_class _bfd_elf_reloc_type_class
+ (const struct bfd_link_info *, const asection *,
+ const Elf_Internal_Rela *);
+extern bfd_vma _bfd_elf_rela_local_sym
+ (bfd *, Elf_Internal_Sym *, asection **, Elf_Internal_Rela *);
+extern bfd_vma _bfd_elf_rel_local_sym
+ (bfd *, Elf_Internal_Sym *, asection **, bfd_vma);
+extern bfd_vma _bfd_elf_section_offset
+ (bfd *, struct bfd_link_info *, asection *, bfd_vma);
+
+extern unsigned long bfd_elf_hash
+ (const char *);
+extern unsigned long bfd_elf_gnu_hash
+ (const char *);
+
+extern bfd_reloc_status_type bfd_elf_generic_reloc
+ (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
+extern bfd_boolean bfd_elf_allocate_object
+ (bfd *, size_t, enum elf_target_id);
+extern bfd_boolean bfd_elf_make_object
+ (bfd *);
+extern bfd_boolean bfd_elf_mkcorefile
+ (bfd *);
+extern bfd_boolean _bfd_elf_make_section_from_shdr
+ (bfd *, Elf_Internal_Shdr *, const char *, int);
+extern bfd_boolean _bfd_elf_make_section_from_phdr
+ (bfd *, Elf_Internal_Phdr *, int, const char *);
+extern struct bfd_hash_entry *_bfd_elf_link_hash_newfunc
+ (struct bfd_hash_entry *, struct bfd_hash_table *, const char *);
+extern struct bfd_link_hash_table *_bfd_elf_link_hash_table_create
+ (bfd *);
+extern void _bfd_elf_link_hash_table_free
+ (bfd *);
+extern void _bfd_elf_link_hash_copy_indirect
+ (struct bfd_link_info *, struct elf_link_hash_entry *,
+ struct elf_link_hash_entry *);
+extern void _bfd_elf_link_hash_hide_symbol
+ (struct bfd_link_info *, struct elf_link_hash_entry *, bfd_boolean);
+extern bfd_boolean _bfd_elf_link_hash_fixup_symbol
+ (struct bfd_link_info *, struct elf_link_hash_entry *);
+extern bfd_boolean _bfd_elf_link_hash_table_init
+ (struct elf_link_hash_table *, bfd *,
+ struct bfd_hash_entry *(*)
+ (struct bfd_hash_entry *, struct bfd_hash_table *, const char *),
+ unsigned int, enum elf_target_id);
+extern bfd_boolean _bfd_elf_slurp_version_tables
+ (bfd *, bfd_boolean);
+extern bfd_boolean _bfd_elf_merge_sections
+ (bfd *, struct bfd_link_info *);
+extern bfd_boolean _bfd_elf_match_sections_by_type
+ (bfd *, const asection *, bfd *, const asection *);
+extern bfd_boolean bfd_elf_is_group_section
+ (bfd *, const struct bfd_section *);
+extern bfd_boolean _bfd_elf_section_already_linked
+ (bfd *, asection *, struct bfd_link_info *);
+extern void bfd_elf_set_group_contents
+ (bfd *, asection *, void *);
+extern asection *_bfd_elf_check_kept_section
+ (asection *, struct bfd_link_info *);
+#define _bfd_elf_link_just_syms _bfd_generic_link_just_syms
+extern void _bfd_elf_copy_link_hash_symbol_type
+ (bfd *, struct bfd_link_hash_entry *, struct bfd_link_hash_entry *);
+extern bfd_boolean _bfd_elf_size_group_sections
+ (struct bfd_link_info *);
+extern bfd_boolean _bfd_elf_fixup_group_sections
+(bfd *, asection *);
+extern bfd_boolean _bfd_elf_copy_private_header_data
+ (bfd *, bfd *);
+extern bfd_boolean _bfd_elf_copy_private_symbol_data
+ (bfd *, asymbol *, bfd *, asymbol *);
+#define _bfd_generic_init_private_section_data \
+ _bfd_elf_init_private_section_data
+extern bfd_boolean _bfd_elf_init_private_section_data
+ (bfd *, asection *, bfd *, asection *, struct bfd_link_info *);
+extern bfd_boolean _bfd_elf_copy_private_section_data
+ (bfd *, asection *, bfd *, asection *);
+extern bfd_boolean _bfd_elf_write_object_contents
+ (bfd *);
+extern bfd_boolean _bfd_elf_write_corefile_contents
+ (bfd *);
+extern bfd_boolean _bfd_elf_set_section_contents
+ (bfd *, sec_ptr, const void *, file_ptr, bfd_size_type);
+extern long _bfd_elf_get_symtab_upper_bound
+ (bfd *);
+extern long _bfd_elf_canonicalize_symtab
+ (bfd *, asymbol **);
+extern long _bfd_elf_get_dynamic_symtab_upper_bound
+ (bfd *);
+extern long _bfd_elf_canonicalize_dynamic_symtab
+ (bfd *, asymbol **);
+extern long _bfd_elf_get_synthetic_symtab
+ (bfd *, long, asymbol **, long, asymbol **, asymbol **);
+extern long _bfd_elf_get_reloc_upper_bound
+ (bfd *, sec_ptr);
+extern long _bfd_elf_canonicalize_reloc
+ (bfd *, sec_ptr, arelent **, asymbol **);
+extern asection * _bfd_elf_get_dynamic_reloc_section
+ (bfd *, asection *, bfd_boolean);
+extern asection * _bfd_elf_make_dynamic_reloc_section
+ (asection *, bfd *, unsigned int, bfd *, bfd_boolean);
+extern long _bfd_elf_get_dynamic_reloc_upper_bound
+ (bfd *);
+extern long _bfd_elf_canonicalize_dynamic_reloc
+ (bfd *, arelent **, asymbol **);
+extern asymbol *_bfd_elf_make_empty_symbol
+ (bfd *);
+extern void _bfd_elf_get_symbol_info
+ (bfd *, asymbol *, symbol_info *);
+extern bfd_boolean _bfd_elf_is_local_label_name
+ (bfd *, const char *);
+extern alent *_bfd_elf_get_lineno
+ (bfd *, asymbol *);
+extern bfd_boolean _bfd_elf_set_arch_mach
+ (bfd *, enum bfd_architecture, unsigned long);
+extern bfd_boolean _bfd_elf_find_nearest_line
+ (bfd *, asymbol **, asection *, bfd_vma,
+ const char **, const char **, unsigned int *, unsigned int *);
+extern bfd_boolean _bfd_elf_find_line
+ (bfd *, asymbol **, asymbol *, const char **, unsigned int *);
+extern bfd_boolean _bfd_elf_find_inliner_info
+ (bfd *, 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
+ (bfd *, struct bfd_link_info *);
+extern bfd_boolean _bfd_elf_new_section_hook
+ (bfd *, asection *);
+extern const struct bfd_elf_special_section *_bfd_elf_get_special_section
+ (const char *, const struct bfd_elf_special_section *, unsigned int);
+extern const struct bfd_elf_special_section *_bfd_elf_get_sec_type_attr
+ (bfd *, asection *);
+
+/* If the target doesn't have reloc handling written yet: */
+extern void _bfd_elf_no_info_to_howto
+ (bfd *, arelent *, Elf_Internal_Rela *);
+
+extern bfd_boolean bfd_section_from_shdr
+ (bfd *, unsigned int shindex);
+extern bfd_boolean bfd_section_from_phdr
+ (bfd *, Elf_Internal_Phdr *, int);
+
+extern int _bfd_elf_symbol_from_bfd_symbol
+ (bfd *, asymbol **);
+
+extern Elf_Internal_Sym *bfd_sym_from_r_symndx
+ (struct sym_cache *, bfd *, unsigned long);
+extern asection *bfd_section_from_elf_index
+ (bfd *, unsigned int);
+extern struct bfd_strtab_hash *_bfd_elf_stringtab_init
+ (void);
+
+extern struct elf_strtab_hash * _bfd_elf_strtab_init
+ (void);
+extern void _bfd_elf_strtab_free
+ (struct elf_strtab_hash *);
+extern bfd_size_type _bfd_elf_strtab_add
+ (struct elf_strtab_hash *, const char *, bfd_boolean);
+extern void _bfd_elf_strtab_addref
+ (struct elf_strtab_hash *, bfd_size_type);
+extern void _bfd_elf_strtab_delref
+ (struct elf_strtab_hash *, bfd_size_type);
+extern unsigned int _bfd_elf_strtab_refcount
+ (struct elf_strtab_hash *, bfd_size_type);
+extern void _bfd_elf_strtab_clear_all_refs
+ (struct elf_strtab_hash *tab);
+extern void _bfd_elf_strtab_restore_size
+ (struct elf_strtab_hash *, bfd_size_type);
+extern bfd_size_type _bfd_elf_strtab_size
+ (struct elf_strtab_hash *);
+extern bfd_size_type _bfd_elf_strtab_offset
+ (struct elf_strtab_hash *, bfd_size_type);
+extern bfd_boolean _bfd_elf_strtab_emit
+ (bfd *, struct elf_strtab_hash *);
+extern void _bfd_elf_strtab_finalize
+ (struct elf_strtab_hash *);
+
+extern void _bfd_elf_parse_eh_frame
+ (bfd *, struct bfd_link_info *, asection *, struct elf_reloc_cookie *);
+extern bfd_boolean _bfd_elf_discard_section_eh_frame
+ (bfd *, struct bfd_link_info *, asection *,
+ bfd_boolean (*) (bfd_vma, void *), struct elf_reloc_cookie *);
+extern bfd_boolean _bfd_elf_discard_section_eh_frame_hdr
+ (bfd *, struct bfd_link_info *);
+extern bfd_vma _bfd_elf_eh_frame_section_offset
+ (bfd *, struct bfd_link_info *, asection *, bfd_vma);
+extern bfd_boolean _bfd_elf_write_section_eh_frame
+ (bfd *, struct bfd_link_info *, asection *, bfd_byte *);
+extern bfd_boolean _bfd_elf_write_section_eh_frame_hdr
+ (bfd *, struct bfd_link_info *);
+extern bfd_boolean _bfd_elf_eh_frame_present
+ (struct bfd_link_info *);
+extern bfd_boolean _bfd_elf_maybe_strip_eh_frame_hdr
+ (struct bfd_link_info *);
+
+extern bfd_boolean _bfd_elf_hash_symbol (struct elf_link_hash_entry *);
+
+extern long _bfd_elf_link_lookup_local_dynindx
+ (struct bfd_link_info *, bfd *, long);
+extern bfd_boolean _bfd_elf_compute_section_file_positions
+ (bfd *, struct bfd_link_info *);
+extern file_ptr _bfd_elf_assign_file_position_for_section
+ (Elf_Internal_Shdr *, file_ptr, bfd_boolean);
+
+extern bfd_boolean _bfd_elf_validate_reloc
+ (bfd *, arelent *);
+
+extern bfd_boolean _bfd_elf_link_create_dynamic_sections
+ (bfd *, struct bfd_link_info *);
+extern bfd_boolean _bfd_elf_link_omit_section_dynsym
+ (bfd *, struct bfd_link_info *, asection *);
+extern bfd_boolean _bfd_elf_create_dynamic_sections
+ (bfd *, struct bfd_link_info *);
+extern bfd_boolean _bfd_elf_create_got_section
+ (bfd *, struct bfd_link_info *);
+extern struct elf_link_hash_entry *_bfd_elf_define_linkage_sym
+ (bfd *, struct bfd_link_info *, asection *, const char *);
+extern void _bfd_elf_init_1_index_section
+ (bfd *, struct bfd_link_info *);
+extern void _bfd_elf_init_2_index_sections
+ (bfd *, struct bfd_link_info *);
+
+extern bfd_boolean _bfd_elfcore_make_pseudosection
+ (bfd *, char *, size_t, ufile_ptr);
+extern char *_bfd_elfcore_strndup
+ (bfd *, char *, size_t);
+
+extern Elf_Internal_Rela *_bfd_elf_link_read_relocs
+ (bfd *, asection *, void *, Elf_Internal_Rela *, bfd_boolean);
+
+extern bfd_boolean _bfd_elf_link_output_relocs
+ (bfd *, asection *, Elf_Internal_Shdr *, Elf_Internal_Rela *,
+ struct elf_link_hash_entry **);
+
+extern bfd_boolean _bfd_elf_adjust_dynamic_copy
+ (struct elf_link_hash_entry *, asection *);
+
+extern bfd_boolean _bfd_elf_dynamic_symbol_p
+ (struct elf_link_hash_entry *, struct bfd_link_info *, bfd_boolean);
+
+extern bfd_boolean _bfd_elf_symbol_refs_local_p
+ (struct elf_link_hash_entry *, struct bfd_link_info *, bfd_boolean);
+
+extern bfd_reloc_status_type bfd_elf_perform_complex_relocation
+ (bfd *, asection *, bfd_byte *, Elf_Internal_Rela *, bfd_vma);
+
+extern bfd_boolean _bfd_elf_setup_sections
+ (bfd *);
+
+extern void _bfd_elf_post_process_headers (bfd * , struct bfd_link_info *);
+
+extern const bfd_target *bfd_elf32_object_p
+ (bfd *);
+extern const bfd_target *bfd_elf32_core_file_p
+ (bfd *);
+extern char *bfd_elf32_core_file_failing_command
+ (bfd *);
+extern int bfd_elf32_core_file_failing_signal
+ (bfd *);
+extern bfd_boolean bfd_elf32_core_file_matches_executable_p
+ (bfd *, bfd *);
+extern int bfd_elf32_core_file_pid
+ (bfd *);
+
+extern bfd_boolean bfd_elf32_swap_symbol_in
+ (bfd *, const void *, const void *, Elf_Internal_Sym *);
+extern void bfd_elf32_swap_symbol_out
+ (bfd *, const Elf_Internal_Sym *, void *, void *);
+extern void bfd_elf32_swap_reloc_in
+ (bfd *, const bfd_byte *, Elf_Internal_Rela *);
+extern void bfd_elf32_swap_reloc_out
+ (bfd *, const Elf_Internal_Rela *, bfd_byte *);
+extern void bfd_elf32_swap_reloca_in
+ (bfd *, const bfd_byte *, Elf_Internal_Rela *);
+extern void bfd_elf32_swap_reloca_out
+ (bfd *, const Elf_Internal_Rela *, bfd_byte *);
+extern void bfd_elf32_swap_phdr_in
+ (bfd *, const Elf32_External_Phdr *, Elf_Internal_Phdr *);
+extern void bfd_elf32_swap_phdr_out
+ (bfd *, const Elf_Internal_Phdr *, Elf32_External_Phdr *);
+extern void bfd_elf32_swap_dyn_in
+ (bfd *, const void *, Elf_Internal_Dyn *);
+extern void bfd_elf32_swap_dyn_out
+ (bfd *, const Elf_Internal_Dyn *, void *);
+extern long bfd_elf32_slurp_symbol_table
+ (bfd *, asymbol **, bfd_boolean);
+extern bfd_boolean bfd_elf32_write_shdrs_and_ehdr
+ (bfd *);
+extern int bfd_elf32_write_out_phdrs
+ (bfd *, const Elf_Internal_Phdr *, unsigned int);
+extern bfd_boolean bfd_elf32_checksum_contents
+ (bfd * , void (*) (const void *, size_t, void *), void *);
+extern void bfd_elf32_write_relocs
+ (bfd *, asection *, void *);
+extern bfd_boolean bfd_elf32_slurp_reloc_table
+ (bfd *, asection *, asymbol **, bfd_boolean);
+
+extern const bfd_target *bfd_elf64_object_p
+ (bfd *);
+extern const bfd_target *bfd_elf64_core_file_p
+ (bfd *);
+extern char *bfd_elf64_core_file_failing_command
+ (bfd *);
+extern int bfd_elf64_core_file_failing_signal
+ (bfd *);
+extern bfd_boolean bfd_elf64_core_file_matches_executable_p
+ (bfd *, bfd *);
+extern int bfd_elf64_core_file_pid
+ (bfd *);
+
+extern bfd_boolean bfd_elf64_swap_symbol_in
+ (bfd *, const void *, const void *, Elf_Internal_Sym *);
+extern void bfd_elf64_swap_symbol_out
+ (bfd *, const Elf_Internal_Sym *, void *, void *);
+extern void bfd_elf64_swap_reloc_in
+ (bfd *, const bfd_byte *, Elf_Internal_Rela *);
+extern void bfd_elf64_swap_reloc_out
+ (bfd *, const Elf_Internal_Rela *, bfd_byte *);
+extern void bfd_elf64_swap_reloca_in
+ (bfd *, const bfd_byte *, Elf_Internal_Rela *);
+extern void bfd_elf64_swap_reloca_out
+ (bfd *, const Elf_Internal_Rela *, bfd_byte *);
+extern void bfd_elf64_swap_phdr_in
+ (bfd *, const Elf64_External_Phdr *, Elf_Internal_Phdr *);
+extern void bfd_elf64_swap_phdr_out
+ (bfd *, const Elf_Internal_Phdr *, Elf64_External_Phdr *);
+extern void bfd_elf64_swap_dyn_in
+ (bfd *, const void *, Elf_Internal_Dyn *);
+extern void bfd_elf64_swap_dyn_out
+ (bfd *, const Elf_Internal_Dyn *, void *);
+extern long bfd_elf64_slurp_symbol_table
+ (bfd *, asymbol **, bfd_boolean);
+extern bfd_boolean bfd_elf64_write_shdrs_and_ehdr
+ (bfd *);
+extern int bfd_elf64_write_out_phdrs
+ (bfd *, const Elf_Internal_Phdr *, unsigned int);
+extern bfd_boolean bfd_elf64_checksum_contents
+ (bfd * , void (*) (const void *, size_t, void *), void *);
+extern void bfd_elf64_write_relocs
+ (bfd *, asection *, void *);
+extern bfd_boolean bfd_elf64_slurp_reloc_table
+ (bfd *, asection *, asymbol **, bfd_boolean);
+
+extern bfd_boolean _bfd_elf_default_relocs_compatible
+ (const bfd_target *, const bfd_target *);
+
+extern bfd_boolean _bfd_elf_relocs_compatible
+ (const bfd_target *, const bfd_target *);
+extern bfd_boolean _bfd_elf_notice_as_needed
+ (bfd *, struct bfd_link_info *, enum notice_asneeded_action);
+
+extern struct elf_link_hash_entry *_bfd_elf_archive_symbol_lookup
+ (bfd *, struct bfd_link_info *, const char *);
+extern bfd_boolean bfd_elf_link_add_symbols
+ (bfd *, struct bfd_link_info *);
+extern bfd_boolean _bfd_elf_add_dynamic_entry
+ (struct bfd_link_info *, bfd_vma, bfd_vma);
+
+extern bfd_boolean bfd_elf_link_record_dynamic_symbol
+ (struct bfd_link_info *, struct elf_link_hash_entry *);
+
+extern int bfd_elf_link_record_local_dynamic_symbol
+ (struct bfd_link_info *, bfd *, long);
+
+extern bfd_boolean _bfd_elf_close_and_cleanup
+ (bfd *);
+
+extern bfd_boolean _bfd_elf_common_definition
+ (Elf_Internal_Sym *);
+
+extern unsigned int _bfd_elf_common_section_index
+ (asection *);
+
+extern asection *_bfd_elf_common_section
+ (asection *);
+
+extern bfd_vma _bfd_elf_default_got_elt_size
+(bfd *, struct bfd_link_info *, struct elf_link_hash_entry *, bfd *,
+ unsigned long);
+
+extern bfd_reloc_status_type _bfd_elf_rel_vtable_reloc_fn
+ (bfd *, arelent *, struct bfd_symbol *, void *,
+ asection *, bfd *, char **);
+
+extern bfd_boolean bfd_elf_final_link
+ (bfd *, struct bfd_link_info *);
+
+extern void _bfd_elf_gc_keep
+ (struct bfd_link_info *info);
+
+extern bfd_boolean bfd_elf_gc_mark_dynamic_ref_symbol
+ (struct elf_link_hash_entry *h, void *inf);
+
+extern bfd_boolean bfd_elf_gc_sections
+ (bfd *, struct bfd_link_info *);
+
+extern bfd_boolean bfd_elf_gc_record_vtinherit
+ (bfd *, asection *, struct elf_link_hash_entry *, bfd_vma);
+
+extern bfd_boolean bfd_elf_gc_record_vtentry
+ (bfd *, asection *, struct elf_link_hash_entry *, bfd_vma);
+
+extern asection *_bfd_elf_gc_mark_hook
+ (asection *, struct bfd_link_info *, Elf_Internal_Rela *,
+ struct elf_link_hash_entry *, Elf_Internal_Sym *);
+
+extern asection *_bfd_elf_gc_mark_rsec
+ (struct bfd_link_info *, asection *, elf_gc_mark_hook_fn,
+ struct elf_reloc_cookie *);
+
+extern bfd_boolean _bfd_elf_gc_mark_reloc
+ (struct bfd_link_info *, asection *, elf_gc_mark_hook_fn,
+ struct elf_reloc_cookie *);
+
+extern bfd_boolean _bfd_elf_gc_mark_fdes
+ (struct bfd_link_info *, asection *, asection *, elf_gc_mark_hook_fn,
+ struct elf_reloc_cookie *);
+
+extern bfd_boolean _bfd_elf_gc_mark
+ (struct bfd_link_info *, asection *, elf_gc_mark_hook_fn);
+
+extern bfd_boolean _bfd_elf_gc_mark_extra_sections
+ (struct bfd_link_info *, elf_gc_mark_hook_fn);
+
+extern bfd_boolean bfd_elf_gc_common_finalize_got_offsets
+ (bfd *, struct bfd_link_info *);
+
+extern bfd_boolean bfd_elf_gc_common_final_link
+ (bfd *, struct bfd_link_info *);
+
+extern bfd_boolean bfd_elf_reloc_symbol_deleted_p
+ (bfd_vma, void *);
+
+extern struct elf_segment_map * _bfd_elf_make_dynamic_segment
+ (bfd *, asection *);
+
+extern bfd_boolean _bfd_elf_map_sections_to_segments
+ (bfd *, struct bfd_link_info *);
+
+extern bfd_boolean _bfd_elf_is_function_type (unsigned int);
+
+extern bfd_size_type _bfd_elf_maybe_function_sym (const asymbol *, asection *,
+ bfd_vma *);
+
+extern int bfd_elf_get_default_section_type (flagword);
+
+extern bfd_boolean bfd_elf_lookup_section_flags
+ (struct bfd_link_info *, struct flag_info *, asection *);
+
+extern Elf_Internal_Phdr * _bfd_elf_find_segment_containing_section
+ (bfd * abfd, asection * section);
+
+/* Exported interface for writing elf corefile notes. */
+extern char *elfcore_write_note
+ (bfd *, char *, int *, const char *, int, const void *, int);
+extern char *elfcore_write_prpsinfo
+ (bfd *, char *, int *, const char *, const char *);
+extern char *elfcore_write_prstatus
+ (bfd *, char *, int *, long, int, const void *);
+extern char * elfcore_write_pstatus
+ (bfd *, char *, int *, long, int, const void *);
+extern char *elfcore_write_prfpreg
+ (bfd *, char *, int *, const void *, int);
+extern char *elfcore_write_prxfpreg
+ (bfd *, char *, int *, const void *, int);
+extern char *elfcore_write_xstatereg
+ (bfd *, char *, int *, const void *, int);
+extern char *elfcore_write_ppc_vmx
+ (bfd *, char *, int *, const void *, int);
+extern char *elfcore_write_ppc_vsx
+ (bfd *, char *, int *, const void *, int);
+extern char *elfcore_write_s390_timer
+ (bfd *, char *, int *, const void *, int);
+extern char *elfcore_write_s390_todcmp
+ (bfd *, char *, int *, const void *, int);
+extern char *elfcore_write_s390_todpreg
+ (bfd *, char *, int *, const void *, int);
+extern char *elfcore_write_s390_ctrs
+ (bfd *, char *, int *, const void *, int);
+extern char *elfcore_write_s390_prefix
+ (bfd *, char *, int *, const void *, int);
+extern char *elfcore_write_s390_last_break
+ (bfd *, char *, int *, const void *, int);
+extern char *elfcore_write_s390_system_call
+ (bfd *, char *, int *, const void *, int);
+extern char *elfcore_write_s390_tdb
+ (bfd *, char *, int *, const void *, int);
+extern char *elfcore_write_arm_vfp
+ (bfd *, char *, int *, const void *, int);
+extern char *elfcore_write_aarch_tls
+ (bfd *, char *, int *, const void *, int);
+extern char *elfcore_write_aarch_hw_break
+ (bfd *, char *, int *, const void *, int);
+extern char *elfcore_write_aarch_hw_watch
+ (bfd *, char *, int *, const void *, int);
+extern char *elfcore_write_lwpstatus
+ (bfd *, char *, int *, long, int, const void *);
+extern char *elfcore_write_register_note
+ (bfd *, char *, int *, const char *, const void *, int);
+
+/* Internal structure which holds information to be included in the
+ PRPSINFO section of Linux core files.
+
+ This is an "internal" structure in the sense that it should be used
+ to pass information to BFD (via the `elfcore_write_linux_prpsinfo'
+ function), so things like endianess shouldn't be an issue. This
+ structure will eventually be converted in one of the
+ `elf_external_linux_*' structures and written out to an output bfd
+ by one of the functions declared below. */
+
+struct elf_internal_linux_prpsinfo
+ {
+ char pr_state; /* Numeric process state. */
+ char pr_sname; /* Char for pr_state. */
+ char pr_zomb; /* Zombie. */
+ char pr_nice; /* Nice val. */
+ unsigned long pr_flag; /* Flags. */
+ unsigned int pr_uid;
+ unsigned int pr_gid;
+ int pr_pid, pr_ppid, pr_pgrp, pr_sid;
+ char pr_fname[16 + 1]; /* Filename of executable. */
+ char pr_psargs[80 + 1]; /* Initial part of arg list. */
+ };
+
+/* Linux/most 32-bit archs. */
+extern char *elfcore_write_linux_prpsinfo32
+ (bfd *, char *, int *, const struct elf_internal_linux_prpsinfo *);
+
+/* Linux/most 64-bit archs. */
+extern char *elfcore_write_linux_prpsinfo64
+ (bfd *, char *, int *, const struct elf_internal_linux_prpsinfo *);
+
+/* Linux/PPC32 uses different layout compared to most archs. */
+extern char *elfcore_write_ppc_linux_prpsinfo32
+ (bfd *, char *, int *, const struct elf_internal_linux_prpsinfo *);
+
+extern bfd *_bfd_elf32_bfd_from_remote_memory
+ (bfd *templ, bfd_vma ehdr_vma, bfd_size_type size, bfd_vma *loadbasep,
+ int (*target_read_memory) (bfd_vma, bfd_byte *, bfd_size_type));
+extern bfd *_bfd_elf64_bfd_from_remote_memory
+ (bfd *templ, bfd_vma ehdr_vma, bfd_size_type size, bfd_vma *loadbasep,
+ int (*target_read_memory) (bfd_vma, bfd_byte *, bfd_size_type));
+
+extern bfd_vma bfd_elf_obj_attr_size (bfd *);
+extern void bfd_elf_set_obj_attr_contents (bfd *, bfd_byte *, bfd_vma);
+extern int bfd_elf_get_obj_attr_int (bfd *, int, int);
+extern void bfd_elf_add_obj_attr_int (bfd *, int, int, unsigned int);
+#define bfd_elf_add_proc_attr_int(BFD, TAG, VALUE) \
+ bfd_elf_add_obj_attr_int ((BFD), OBJ_ATTR_PROC, (TAG), (VALUE))
+extern void bfd_elf_add_obj_attr_string (bfd *, int, int, const char *);
+#define bfd_elf_add_proc_attr_string(BFD, TAG, VALUE) \
+ bfd_elf_add_obj_attr_string ((BFD), OBJ_ATTR_PROC, (TAG), (VALUE))
+extern void bfd_elf_add_obj_attr_int_string (bfd *, int, int, unsigned int,
+ const char *);
+#define bfd_elf_add_proc_attr_int_string(BFD, TAG, INTVAL, STRVAL) \
+ bfd_elf_add_obj_attr_int_string ((BFD), OBJ_ATTR_PROC, (TAG), \
+ (INTVAL), (STRVAL))
+
+extern char *_bfd_elf_attr_strdup (bfd *, const char *);
+extern void _bfd_elf_copy_obj_attributes (bfd *, bfd *);
+extern int _bfd_elf_obj_attrs_arg_type (bfd *, int, int);
+extern void _bfd_elf_parse_attributes (bfd *, Elf_Internal_Shdr *);
+extern bfd_boolean _bfd_elf_merge_object_attributes (bfd *, bfd *);
+extern bfd_boolean _bfd_elf_merge_unknown_attribute_low (bfd *, bfd *, int);
+extern bfd_boolean _bfd_elf_merge_unknown_attribute_list (bfd *, bfd *);
+extern Elf_Internal_Shdr *_bfd_elf_single_rel_hdr (asection *sec);
+
+/* The linker may need to keep track of the number of relocs that it
+ decides to copy as dynamic relocs in check_relocs for each symbol.
+ This is so that it can later discard them if they are found to be
+ unnecessary. We can store the information in a field extending the
+ regular ELF linker hash table. */
+
+struct elf_dyn_relocs
+{
+ struct elf_dyn_relocs *next;
+
+ /* The input section of the reloc. */
+ asection *sec;
+
+ /* Total number of relocs copied for the input section. */
+ bfd_size_type count;
+
+ /* Number of pc-relative relocs copied for the input section. */
+ bfd_size_type pc_count;
+};
+
+extern bfd_boolean _bfd_elf_create_ifunc_sections
+ (bfd *, struct bfd_link_info *);
+extern bfd_boolean _bfd_elf_allocate_ifunc_dyn_relocs
+ (struct bfd_link_info *, struct elf_link_hash_entry *,
+ struct elf_dyn_relocs **, unsigned int, unsigned int, unsigned int);
+extern long _bfd_elf_ifunc_get_synthetic_symtab
+ (bfd *, long, asymbol **, long, asymbol **, asymbol **, asection *,
+ bfd_vma *(*) (bfd *, asymbol **, asection *, asection *));
+
+extern void elf_append_rela (bfd *, asection *, Elf_Internal_Rela *);
+extern void elf_append_rel (bfd *, asection *, Elf_Internal_Rela *);
+
+extern bfd_vma elf64_r_info (bfd_vma, bfd_vma);
+extern bfd_vma elf64_r_sym (bfd_vma);
+extern bfd_vma elf32_r_info (bfd_vma, bfd_vma);
+extern bfd_vma elf32_r_sym (bfd_vma);
+
+/* Large common section. */
+extern asection _bfd_elf_large_com_section;
+
+/* Hash for local symbol with the first section id, ID, in the input
+ file and the local symbol index, SYM. */
+#define ELF_LOCAL_SYMBOL_HASH(ID, SYM) \
+ (((((ID) & 0xff) << 24) | (((ID) & 0xff00) << 8)) \
+ ^ (SYM) ^ ((ID) >> 16))
+
+/* This is the condition under which finish_dynamic_symbol will be called.
+ If our finish_dynamic_symbol isn't called, we'll need to do something
+ about initializing any .plt and .got entries in relocate_section. */
+#define WILL_CALL_FINISH_DYNAMIC_SYMBOL(DYN, SHARED, H) \
+ ((DYN) \
+ && ((SHARED) || !(H)->forced_local) \
+ && ((H)->dynindx != -1 || (H)->forced_local))
+
+/* This macro is to avoid lots of duplicated code in the body
+ of xxx_relocate_section() in the various elfxx-xxxx.c files. */
+#define RELOC_FOR_GLOBAL_SYMBOL(info, input_bfd, input_section, rel, \
+ r_symndx, symtab_hdr, sym_hashes, \
+ h, sec, relocation, \
+ unresolved_reloc, warned, ignored) \
+ do \
+ { \
+ /* It seems this can happen with erroneous or unsupported \
+ input (mixing a.out and elf in an archive, for example.) */ \
+ if (sym_hashes == NULL) \
+ return FALSE; \
+ \
+ h = sym_hashes[r_symndx - symtab_hdr->sh_info]; \
+ \
+ if (info->wrap_hash != NULL \
+ && (input_section->flags & SEC_DEBUGGING) != 0) \
+ h = ((struct elf_link_hash_entry *) \
+ unwrap_hash_lookup (info, input_bfd, &h->root)); \
+ \
+ 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; \
+ \
+ warned = FALSE; \
+ ignored = FALSE; \
+ unresolved_reloc = FALSE; \
+ relocation = 0; \
+ if (h->root.type == bfd_link_hash_defined \
+ || h->root.type == bfd_link_hash_defweak) \
+ { \
+ sec = h->root.u.def.section; \
+ if (sec == NULL \
+ || sec->output_section == NULL) \
+ /* Set a flag that will be cleared later if we find a \
+ relocation value for this symbol. output_section \
+ is typically NULL for symbols satisfied by a shared \
+ library. */ \
+ unresolved_reloc = TRUE; \
+ else \
+ relocation = (h->root.u.def.value \
+ + sec->output_section->vma \
+ + sec->output_offset); \
+ } \
+ else if (h->root.type == bfd_link_hash_undefweak) \
+ ; \
+ else if (info->unresolved_syms_in_objects == RM_IGNORE \
+ && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT) \
+ ignored = TRUE; \
+ else if (!info->relocatable) \
+ { \
+ bfd_boolean err; \
+ err = (info->unresolved_syms_in_objects == RM_GENERATE_ERROR \
+ || ELF_ST_VISIBILITY (h->other) != STV_DEFAULT); \
+ if (!info->callbacks->undefined_symbol (info, \
+ h->root.root.string, \
+ input_bfd, \
+ input_section, \
+ rel->r_offset, err)) \
+ return FALSE; \
+ warned = TRUE; \
+ } \
+ (void) unresolved_reloc; \
+ (void) warned; \
+ (void) ignored; \
+ } \
+ while (0)
+
+/* This macro is to avoid lots of duplicated code in the body of the
+ loop over relocations in xxx_relocate_section() in the various
+ elfxx-xxxx.c files.
+
+ Handle relocations against symbols from removed linkonce sections,
+ or sections discarded by a linker script. When doing a relocatable
+ link, we remove such relocations. Otherwise, we just want the
+ section contents zeroed and avoid any special processing. */
+#define RELOC_AGAINST_DISCARDED_SECTION(info, input_bfd, input_section, \
+ rel, count, relend, \
+ howto, index, contents) \
+ { \
+ int i_; \
+ _bfd_clear_contents (howto, input_bfd, input_section, \
+ contents + rel[index].r_offset); \
+ \
+ if (info->relocatable \
+ && (input_section->flags & SEC_DEBUGGING)) \
+ { \
+ /* Only remove relocations in debug sections since other \
+ sections may require relocations. */ \
+ Elf_Internal_Shdr *rel_hdr; \
+ \
+ rel_hdr = _bfd_elf_single_rel_hdr (input_section->output_section); \
+ \
+ /* Avoid empty output section. */ \
+ if (rel_hdr->sh_size > rel_hdr->sh_entsize) \
+ { \
+ rel_hdr->sh_size -= rel_hdr->sh_entsize; \
+ rel_hdr = _bfd_elf_single_rel_hdr (input_section); \
+ rel_hdr->sh_size -= rel_hdr->sh_entsize; \
+ \
+ memmove (rel, rel + count, \
+ (relend - rel - count) * sizeof (*rel)); \
+ \
+ input_section->reloc_count--; \
+ relend -= count; \
+ rel--; \
+ continue; \
+ } \
+ } \
+ \
+ for (i_ = 0; i_ < count; i_++) \
+ { \
+ rel[i_].r_info = 0; \
+ rel[i_].r_addend = 0; \
+ } \
+ rel += count - 1; \
+ continue; \
+ }
+
+/* Will a symbol be bound to the definition within the shared
+ library, if any. A unique symbol can never be bound locally. */
+#define SYMBOLIC_BIND(INFO, H) \
+ (!(H)->unique_global \
+ && ((INFO)->symbolic || ((INFO)->dynamic && !(H)->dynamic)))
+
+#endif /* _LIBELF_H_ */
diff --git a/bfd/elf-eh-frame.c b/bfd/elf-eh-frame.c
new file mode 100644
index 0000000..002932d
--- /dev/null
+++ b/bfd/elf-eh-frame.c
@@ -0,0 +1,1920 @@
+/* .eh_frame section optimization.
+ Copyright (C) 2001-2014 Free Software Foundation, Inc.
+ Written by Jakub Jelinek <jakub@redhat.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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+#include "elf-bfd.h"
+#include "dwarf2.h"
+
+#define EH_FRAME_HDR_SIZE 8
+
+struct cie
+{
+ unsigned int length;
+ unsigned int hash;
+ unsigned char version;
+ unsigned char local_personality;
+ char augmentation[20];
+ bfd_vma code_align;
+ bfd_signed_vma data_align;
+ bfd_vma ra_column;
+ bfd_vma augmentation_size;
+ union {
+ struct elf_link_hash_entry *h;
+ struct {
+ unsigned int bfd_id;
+ unsigned int index;
+ } sym;
+ unsigned int reloc_index;
+ } personality;
+ struct eh_cie_fde *cie_inf;
+ unsigned char per_encoding;
+ unsigned char lsda_encoding;
+ unsigned char fde_encoding;
+ unsigned char initial_insn_length;
+ unsigned char can_make_lsda_relative;
+ unsigned char initial_instructions[50];
+};
+
+
+
+/* If *ITER hasn't reached END yet, read the next byte into *RESULT and
+ move onto the next byte. Return true on success. */
+
+static inline bfd_boolean
+read_byte (bfd_byte **iter, bfd_byte *end, unsigned char *result)
+{
+ if (*iter >= end)
+ return FALSE;
+ *result = *((*iter)++);
+ return TRUE;
+}
+
+/* Move *ITER over LENGTH bytes, or up to END, whichever is closer.
+ Return true it was possible to move LENGTH bytes. */
+
+static inline bfd_boolean
+skip_bytes (bfd_byte **iter, bfd_byte *end, bfd_size_type length)
+{
+ if ((bfd_size_type) (end - *iter) < length)
+ {
+ *iter = end;
+ return FALSE;
+ }
+ *iter += length;
+ return TRUE;
+}
+
+/* Move *ITER over an leb128, stopping at END. Return true if the end
+ of the leb128 was found. */
+
+static bfd_boolean
+skip_leb128 (bfd_byte **iter, bfd_byte *end)
+{
+ unsigned char byte;
+ do
+ if (!read_byte (iter, end, &byte))
+ return FALSE;
+ while (byte & 0x80);
+ return TRUE;
+}
+
+/* Like skip_leb128, but treat the leb128 as an unsigned value and
+ store it in *VALUE. */
+
+static bfd_boolean
+read_uleb128 (bfd_byte **iter, bfd_byte *end, bfd_vma *value)
+{
+ bfd_byte *start, *p;
+
+ start = *iter;
+ if (!skip_leb128 (iter, end))
+ return FALSE;
+
+ p = *iter;
+ *value = *--p;
+ while (p > start)
+ *value = (*value << 7) | (*--p & 0x7f);
+
+ return TRUE;
+}
+
+/* Like read_uleb128, but for signed values. */
+
+static bfd_boolean
+read_sleb128 (bfd_byte **iter, bfd_byte *end, bfd_signed_vma *value)
+{
+ bfd_byte *start, *p;
+
+ start = *iter;
+ if (!skip_leb128 (iter, end))
+ return FALSE;
+
+ p = *iter;
+ *value = ((*--p & 0x7f) ^ 0x40) - 0x40;
+ while (p > start)
+ *value = (*value << 7) | (*--p & 0x7f);
+
+ return TRUE;
+}
+
+/* Return 0 if either encoding is variable width, or not yet known to bfd. */
+
+static
+int get_DW_EH_PE_width (int encoding, int ptr_size)
+{
+ /* DW_EH_PE_ values of 0x60 and 0x70 weren't defined at the time .eh_frame
+ was added to bfd. */
+ if ((encoding & 0x60) == 0x60)
+ return 0;
+
+ switch (encoding & 7)
+ {
+ case DW_EH_PE_udata2: return 2;
+ case DW_EH_PE_udata4: return 4;
+ case DW_EH_PE_udata8: return 8;
+ case DW_EH_PE_absptr: return ptr_size;
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+#define get_DW_EH_PE_signed(encoding) (((encoding) & DW_EH_PE_signed) != 0)
+
+/* Read a width sized value from memory. */
+
+static bfd_vma
+read_value (bfd *abfd, bfd_byte *buf, int width, int is_signed)
+{
+ bfd_vma value;
+
+ switch (width)
+ {
+ case 2:
+ if (is_signed)
+ value = bfd_get_signed_16 (abfd, buf);
+ else
+ value = bfd_get_16 (abfd, buf);
+ break;
+ case 4:
+ if (is_signed)
+ value = bfd_get_signed_32 (abfd, buf);
+ else
+ value = bfd_get_32 (abfd, buf);
+ break;
+ case 8:
+ if (is_signed)
+ value = bfd_get_signed_64 (abfd, buf);
+ else
+ value = bfd_get_64 (abfd, buf);
+ break;
+ default:
+ BFD_FAIL ();
+ return 0;
+ }
+
+ return value;
+}
+
+/* Store a width sized value to memory. */
+
+static void
+write_value (bfd *abfd, bfd_byte *buf, bfd_vma value, int width)
+{
+ switch (width)
+ {
+ case 2: bfd_put_16 (abfd, value, buf); break;
+ case 4: bfd_put_32 (abfd, value, buf); break;
+ case 8: bfd_put_64 (abfd, value, buf); break;
+ default: BFD_FAIL ();
+ }
+}
+
+/* Return one if C1 and C2 CIEs can be merged. */
+
+static int
+cie_eq (const void *e1, const void *e2)
+{
+ const struct cie *c1 = (const struct cie *) e1;
+ const struct cie *c2 = (const struct cie *) e2;
+
+ if (c1->hash == c2->hash
+ && c1->length == c2->length
+ && c1->version == c2->version
+ && c1->local_personality == c2->local_personality
+ && strcmp (c1->augmentation, c2->augmentation) == 0
+ && strcmp (c1->augmentation, "eh") != 0
+ && c1->code_align == c2->code_align
+ && c1->data_align == c2->data_align
+ && c1->ra_column == c2->ra_column
+ && c1->augmentation_size == c2->augmentation_size
+ && memcmp (&c1->personality, &c2->personality,
+ sizeof (c1->personality)) == 0
+ && (c1->cie_inf->u.cie.u.sec->output_section
+ == c2->cie_inf->u.cie.u.sec->output_section)
+ && c1->per_encoding == c2->per_encoding
+ && c1->lsda_encoding == c2->lsda_encoding
+ && c1->fde_encoding == c2->fde_encoding
+ && c1->initial_insn_length == c2->initial_insn_length
+ && c1->initial_insn_length <= sizeof (c1->initial_instructions)
+ && memcmp (c1->initial_instructions,
+ c2->initial_instructions,
+ c1->initial_insn_length) == 0)
+ return 1;
+
+ return 0;
+}
+
+static hashval_t
+cie_hash (const void *e)
+{
+ const struct cie *c = (const struct cie *) e;
+ return c->hash;
+}
+
+static hashval_t
+cie_compute_hash (struct cie *c)
+{
+ hashval_t h = 0;
+ size_t len;
+ h = iterative_hash_object (c->length, h);
+ h = iterative_hash_object (c->version, h);
+ h = iterative_hash (c->augmentation, strlen (c->augmentation) + 1, h);
+ h = iterative_hash_object (c->code_align, h);
+ h = iterative_hash_object (c->data_align, h);
+ h = iterative_hash_object (c->ra_column, h);
+ h = iterative_hash_object (c->augmentation_size, h);
+ h = iterative_hash_object (c->personality, h);
+ h = iterative_hash_object (c->cie_inf->u.cie.u.sec->output_section, h);
+ h = iterative_hash_object (c->per_encoding, h);
+ h = iterative_hash_object (c->lsda_encoding, h);
+ h = iterative_hash_object (c->fde_encoding, h);
+ h = iterative_hash_object (c->initial_insn_length, h);
+ len = c->initial_insn_length;
+ if (len > sizeof (c->initial_instructions))
+ len = sizeof (c->initial_instructions);
+ h = iterative_hash (c->initial_instructions, len, h);
+ c->hash = h;
+ return h;
+}
+
+/* Return the number of extra bytes that we'll be inserting into
+ ENTRY's augmentation string. */
+
+static INLINE unsigned int
+extra_augmentation_string_bytes (struct eh_cie_fde *entry)
+{
+ unsigned int size = 0;
+ if (entry->cie)
+ {
+ if (entry->add_augmentation_size)
+ size++;
+ if (entry->u.cie.add_fde_encoding)
+ size++;
+ }
+ return size;
+}
+
+/* Likewise ENTRY's augmentation data. */
+
+static INLINE unsigned int
+extra_augmentation_data_bytes (struct eh_cie_fde *entry)
+{
+ unsigned int size = 0;
+ if (entry->add_augmentation_size)
+ size++;
+ if (entry->cie && entry->u.cie.add_fde_encoding)
+ size++;
+ return size;
+}
+
+/* Return the size that ENTRY will have in the output. ALIGNMENT is the
+ required alignment of ENTRY in bytes. */
+
+static unsigned int
+size_of_output_cie_fde (struct eh_cie_fde *entry, unsigned int alignment)
+{
+ if (entry->removed)
+ return 0;
+ if (entry->size == 4)
+ return 4;
+ return (entry->size
+ + extra_augmentation_string_bytes (entry)
+ + extra_augmentation_data_bytes (entry)
+ + alignment - 1) & -alignment;
+}
+
+/* Assume that the bytes between *ITER and END are CFA instructions.
+ Try to move *ITER past the first instruction and return true on
+ success. ENCODED_PTR_WIDTH gives the width of pointer entries. */
+
+static bfd_boolean
+skip_cfa_op (bfd_byte **iter, bfd_byte *end, unsigned int encoded_ptr_width)
+{
+ bfd_byte op;
+ bfd_vma length;
+
+ if (!read_byte (iter, end, &op))
+ return FALSE;
+
+ switch (op & 0xc0 ? op & 0xc0 : op)
+ {
+ case DW_CFA_nop:
+ case DW_CFA_advance_loc:
+ case DW_CFA_restore:
+ case DW_CFA_remember_state:
+ case DW_CFA_restore_state:
+ case DW_CFA_GNU_window_save:
+ /* No arguments. */
+ return TRUE;
+
+ case DW_CFA_offset:
+ case DW_CFA_restore_extended:
+ case DW_CFA_undefined:
+ case DW_CFA_same_value:
+ case DW_CFA_def_cfa_register:
+ case DW_CFA_def_cfa_offset:
+ case DW_CFA_def_cfa_offset_sf:
+ case DW_CFA_GNU_args_size:
+ /* One leb128 argument. */
+ return skip_leb128 (iter, end);
+
+ case DW_CFA_val_offset:
+ case DW_CFA_val_offset_sf:
+ case DW_CFA_offset_extended:
+ case DW_CFA_register:
+ case DW_CFA_def_cfa:
+ case DW_CFA_offset_extended_sf:
+ case DW_CFA_GNU_negative_offset_extended:
+ case DW_CFA_def_cfa_sf:
+ /* Two leb128 arguments. */
+ return (skip_leb128 (iter, end)
+ && skip_leb128 (iter, end));
+
+ case DW_CFA_def_cfa_expression:
+ /* A variable-length argument. */
+ return (read_uleb128 (iter, end, &length)
+ && skip_bytes (iter, end, length));
+
+ case DW_CFA_expression:
+ case DW_CFA_val_expression:
+ /* A leb128 followed by a variable-length argument. */
+ return (skip_leb128 (iter, end)
+ && read_uleb128 (iter, end, &length)
+ && skip_bytes (iter, end, length));
+
+ case DW_CFA_set_loc:
+ return skip_bytes (iter, end, encoded_ptr_width);
+
+ case DW_CFA_advance_loc1:
+ return skip_bytes (iter, end, 1);
+
+ case DW_CFA_advance_loc2:
+ return skip_bytes (iter, end, 2);
+
+ case DW_CFA_advance_loc4:
+ return skip_bytes (iter, end, 4);
+
+ case DW_CFA_MIPS_advance_loc8:
+ return skip_bytes (iter, end, 8);
+
+ default:
+ return FALSE;
+ }
+}
+
+/* Try to interpret the bytes between BUF and END as CFA instructions.
+ If every byte makes sense, return a pointer to the first DW_CFA_nop
+ padding byte, or END if there is no padding. Return null otherwise.
+ ENCODED_PTR_WIDTH is as for skip_cfa_op. */
+
+static bfd_byte *
+skip_non_nops (bfd_byte *buf, bfd_byte *end, unsigned int encoded_ptr_width,
+ unsigned int *set_loc_count)
+{
+ bfd_byte *last;
+
+ last = buf;
+ while (buf < end)
+ if (*buf == DW_CFA_nop)
+ buf++;
+ else
+ {
+ if (*buf == DW_CFA_set_loc)
+ ++*set_loc_count;
+ if (!skip_cfa_op (&buf, end, encoded_ptr_width))
+ return 0;
+ last = buf;
+ }
+ return last;
+}
+
+/* Convert absolute encoding ENCODING into PC-relative form.
+ SIZE is the size of a pointer. */
+
+static unsigned char
+make_pc_relative (unsigned char encoding, unsigned int ptr_size)
+{
+ if ((encoding & 0x7f) == DW_EH_PE_absptr)
+ switch (ptr_size)
+ {
+ case 2:
+ encoding |= DW_EH_PE_sdata2;
+ break;
+ case 4:
+ encoding |= DW_EH_PE_sdata4;
+ break;
+ case 8:
+ encoding |= DW_EH_PE_sdata8;
+ break;
+ }
+ return encoding | DW_EH_PE_pcrel;
+}
+
+/* Try to parse .eh_frame section SEC, which belongs to ABFD. Store the
+ information in the section's sec_info field on success. COOKIE
+ describes the relocations in SEC. */
+
+void
+_bfd_elf_parse_eh_frame (bfd *abfd, struct bfd_link_info *info,
+ asection *sec, struct elf_reloc_cookie *cookie)
+{
+#define REQUIRE(COND) \
+ do \
+ if (!(COND)) \
+ goto free_no_table; \
+ while (0)
+
+ bfd_byte *ehbuf = NULL, *buf, *end;
+ bfd_byte *last_fde;
+ struct eh_cie_fde *this_inf;
+ unsigned int hdr_length, hdr_id;
+ unsigned int cie_count;
+ struct cie *cie, *local_cies = NULL;
+ struct elf_link_hash_table *htab;
+ struct eh_frame_hdr_info *hdr_info;
+ struct eh_frame_sec_info *sec_info = NULL;
+ unsigned int ptr_size;
+ unsigned int num_cies;
+ unsigned int num_entries;
+ elf_gc_mark_hook_fn gc_mark_hook;
+
+ htab = elf_hash_table (info);
+ hdr_info = &htab->eh_info;
+
+ if (sec->size == 0
+ || sec->sec_info_type != SEC_INFO_TYPE_NONE)
+ {
+ /* This file does not contain .eh_frame information. */
+ return;
+ }
+
+ if (bfd_is_abs_section (sec->output_section))
+ {
+ /* At least one of the sections is being discarded from the
+ link, so we should just ignore them. */
+ return;
+ }
+
+ /* Read the frame unwind information from abfd. */
+
+ REQUIRE (bfd_malloc_and_get_section (abfd, sec, &ehbuf));
+
+ if (sec->size >= 4
+ && bfd_get_32 (abfd, ehbuf) == 0
+ && cookie->rel == cookie->relend)
+ {
+ /* Empty .eh_frame section. */
+ free (ehbuf);
+ return;
+ }
+
+ /* If .eh_frame section size doesn't fit into int, we cannot handle
+ it (it would need to use 64-bit .eh_frame format anyway). */
+ REQUIRE (sec->size == (unsigned int) sec->size);
+
+ ptr_size = (get_elf_backend_data (abfd)
+ ->elf_backend_eh_frame_address_size (abfd, sec));
+ REQUIRE (ptr_size != 0);
+
+ /* Go through the section contents and work out how many FDEs and
+ CIEs there are. */
+ buf = ehbuf;
+ end = ehbuf + sec->size;
+ num_cies = 0;
+ num_entries = 0;
+ while (buf != end)
+ {
+ num_entries++;
+
+ /* Read the length of the entry. */
+ REQUIRE (skip_bytes (&buf, end, 4));
+ hdr_length = bfd_get_32 (abfd, buf - 4);
+
+ /* 64-bit .eh_frame is not supported. */
+ REQUIRE (hdr_length != 0xffffffff);
+ if (hdr_length == 0)
+ break;
+
+ REQUIRE (skip_bytes (&buf, end, 4));
+ hdr_id = bfd_get_32 (abfd, buf - 4);
+ if (hdr_id == 0)
+ num_cies++;
+
+ REQUIRE (skip_bytes (&buf, end, hdr_length - 4));
+ }
+
+ sec_info = (struct eh_frame_sec_info *)
+ bfd_zmalloc (sizeof (struct eh_frame_sec_info)
+ + (num_entries - 1) * sizeof (struct eh_cie_fde));
+ REQUIRE (sec_info);
+
+ /* We need to have a "struct cie" for each CIE in this section. */
+ local_cies = (struct cie *) bfd_zmalloc (num_cies * sizeof (*local_cies));
+ REQUIRE (local_cies);
+
+ /* FIXME: octets_per_byte. */
+#define ENSURE_NO_RELOCS(buf) \
+ while (cookie->rel < cookie->relend \
+ && (cookie->rel->r_offset \
+ < (bfd_size_type) ((buf) - ehbuf))) \
+ { \
+ REQUIRE (cookie->rel->r_info == 0); \
+ cookie->rel++; \
+ }
+
+ /* FIXME: octets_per_byte. */
+#define SKIP_RELOCS(buf) \
+ while (cookie->rel < cookie->relend \
+ && (cookie->rel->r_offset \
+ < (bfd_size_type) ((buf) - ehbuf))) \
+ cookie->rel++
+
+ /* FIXME: octets_per_byte. */
+#define GET_RELOC(buf) \
+ ((cookie->rel < cookie->relend \
+ && (cookie->rel->r_offset \
+ == (bfd_size_type) ((buf) - ehbuf))) \
+ ? cookie->rel : NULL)
+
+ buf = ehbuf;
+ cie_count = 0;
+ gc_mark_hook = get_elf_backend_data (abfd)->gc_mark_hook;
+ while ((bfd_size_type) (buf - ehbuf) != sec->size)
+ {
+ char *aug;
+ bfd_byte *start, *insns, *insns_end;
+ bfd_size_type length;
+ unsigned int set_loc_count;
+
+ this_inf = sec_info->entry + sec_info->count;
+ last_fde = buf;
+
+ /* Read the length of the entry. */
+ REQUIRE (skip_bytes (&buf, ehbuf + sec->size, 4));
+ hdr_length = bfd_get_32 (abfd, buf - 4);
+
+ /* The CIE/FDE must be fully contained in this input section. */
+ REQUIRE ((bfd_size_type) (buf - ehbuf) + hdr_length <= sec->size);
+ end = buf + hdr_length;
+
+ this_inf->offset = last_fde - ehbuf;
+ this_inf->size = 4 + hdr_length;
+ this_inf->reloc_index = cookie->rel - cookie->rels;
+
+ if (hdr_length == 0)
+ {
+ /* A zero-length CIE should only be found at the end of
+ the section. */
+ REQUIRE ((bfd_size_type) (buf - ehbuf) == sec->size);
+ ENSURE_NO_RELOCS (buf);
+ sec_info->count++;
+ break;
+ }
+
+ REQUIRE (skip_bytes (&buf, end, 4));
+ hdr_id = bfd_get_32 (abfd, buf - 4);
+
+ if (hdr_id == 0)
+ {
+ unsigned int initial_insn_length;
+
+ /* CIE */
+ this_inf->cie = 1;
+
+ /* Point CIE to one of the section-local cie structures. */
+ cie = local_cies + cie_count++;
+
+ cie->cie_inf = this_inf;
+ cie->length = hdr_length;
+ start = buf;
+ REQUIRE (read_byte (&buf, end, &cie->version));
+
+ /* Cannot handle unknown versions. */
+ REQUIRE (cie->version == 1
+ || cie->version == 3
+ || cie->version == 4);
+ REQUIRE (strlen ((char *) buf) < sizeof (cie->augmentation));
+
+ strcpy (cie->augmentation, (char *) buf);
+ buf = (bfd_byte *) strchr ((char *) buf, '\0') + 1;
+ ENSURE_NO_RELOCS (buf);
+ if (buf[0] == 'e' && buf[1] == 'h')
+ {
+ /* GCC < 3.0 .eh_frame CIE */
+ /* We cannot merge "eh" CIEs because __EXCEPTION_TABLE__
+ is private to each CIE, so we don't need it for anything.
+ Just skip it. */
+ REQUIRE (skip_bytes (&buf, end, ptr_size));
+ SKIP_RELOCS (buf);
+ }
+ if (cie->version >= 4)
+ {
+ REQUIRE (buf + 1 < end);
+ REQUIRE (buf[0] == ptr_size);
+ REQUIRE (buf[1] == 0);
+ buf += 2;
+ }
+ REQUIRE (read_uleb128 (&buf, end, &cie->code_align));
+ REQUIRE (read_sleb128 (&buf, end, &cie->data_align));
+ if (cie->version == 1)
+ {
+ REQUIRE (buf < end);
+ cie->ra_column = *buf++;
+ }
+ else
+ REQUIRE (read_uleb128 (&buf, end, &cie->ra_column));
+ ENSURE_NO_RELOCS (buf);
+ cie->lsda_encoding = DW_EH_PE_omit;
+ cie->fde_encoding = DW_EH_PE_omit;
+ cie->per_encoding = DW_EH_PE_omit;
+ aug = cie->augmentation;
+ if (aug[0] != 'e' || aug[1] != 'h')
+ {
+ if (*aug == 'z')
+ {
+ aug++;
+ REQUIRE (read_uleb128 (&buf, end, &cie->augmentation_size));
+ ENSURE_NO_RELOCS (buf);
+ }
+
+ while (*aug != '\0')
+ switch (*aug++)
+ {
+ case 'L':
+ REQUIRE (read_byte (&buf, end, &cie->lsda_encoding));
+ ENSURE_NO_RELOCS (buf);
+ REQUIRE (get_DW_EH_PE_width (cie->lsda_encoding, ptr_size));
+ break;
+ case 'R':
+ REQUIRE (read_byte (&buf, end, &cie->fde_encoding));
+ ENSURE_NO_RELOCS (buf);
+ REQUIRE (get_DW_EH_PE_width (cie->fde_encoding, ptr_size));
+ break;
+ case 'S':
+ break;
+ case 'P':
+ {
+ int per_width;
+
+ REQUIRE (read_byte (&buf, end, &cie->per_encoding));
+ per_width = get_DW_EH_PE_width (cie->per_encoding,
+ ptr_size);
+ REQUIRE (per_width);
+ if ((cie->per_encoding & 0x70) == DW_EH_PE_aligned)
+ {
+ length = -(buf - ehbuf) & (per_width - 1);
+ REQUIRE (skip_bytes (&buf, end, length));
+ }
+ this_inf->u.cie.personality_offset = buf - start;
+ ENSURE_NO_RELOCS (buf);
+ /* Ensure we have a reloc here. */
+ REQUIRE (GET_RELOC (buf));
+ cie->personality.reloc_index
+ = cookie->rel - cookie->rels;
+ /* Cope with MIPS-style composite relocations. */
+ do
+ cookie->rel++;
+ while (GET_RELOC (buf) != NULL);
+ REQUIRE (skip_bytes (&buf, end, per_width));
+ }
+ break;
+ default:
+ /* Unrecognized augmentation. Better bail out. */
+ goto free_no_table;
+ }
+ }
+
+ /* For shared libraries, try to get rid of as many RELATIVE relocs
+ as possible. */
+ if (info->shared
+ && !info->relocatable
+ && (get_elf_backend_data (abfd)
+ ->elf_backend_can_make_relative_eh_frame
+ (abfd, info, sec)))
+ {
+ if ((cie->fde_encoding & 0x70) == DW_EH_PE_absptr)
+ this_inf->make_relative = 1;
+ /* If the CIE doesn't already have an 'R' entry, it's fairly
+ easy to add one, provided that there's no aligned data
+ after the augmentation string. */
+ else if (cie->fde_encoding == DW_EH_PE_omit
+ && (cie->per_encoding & 0x70) != DW_EH_PE_aligned)
+ {
+ if (*cie->augmentation == 0)
+ this_inf->add_augmentation_size = 1;
+ this_inf->u.cie.add_fde_encoding = 1;
+ this_inf->make_relative = 1;
+ }
+
+ if ((cie->lsda_encoding & 0x70) == DW_EH_PE_absptr)
+ cie->can_make_lsda_relative = 1;
+ }
+
+ /* If FDE encoding was not specified, it defaults to
+ DW_EH_absptr. */
+ if (cie->fde_encoding == DW_EH_PE_omit)
+ cie->fde_encoding = DW_EH_PE_absptr;
+
+ initial_insn_length = end - buf;
+ cie->initial_insn_length = initial_insn_length;
+ memcpy (cie->initial_instructions, buf,
+ initial_insn_length <= sizeof (cie->initial_instructions)
+ ? initial_insn_length : sizeof (cie->initial_instructions));
+ insns = buf;
+ buf += initial_insn_length;
+ ENSURE_NO_RELOCS (buf);
+
+ if (!info->relocatable)
+ {
+ /* Keep info for merging cies. */
+ this_inf->u.cie.u.full_cie = cie;
+ this_inf->u.cie.per_encoding_relative
+ = (cie->per_encoding & 0x70) == DW_EH_PE_pcrel;
+ }
+ }
+ else
+ {
+ /* Find the corresponding CIE. */
+ unsigned int cie_offset = this_inf->offset + 4 - hdr_id;
+ for (cie = local_cies; cie < local_cies + cie_count; cie++)
+ if (cie_offset == cie->cie_inf->offset)
+ break;
+
+ /* Ensure this FDE references one of the CIEs in this input
+ section. */
+ REQUIRE (cie != local_cies + cie_count);
+ this_inf->u.fde.cie_inf = cie->cie_inf;
+ this_inf->make_relative = cie->cie_inf->make_relative;
+ this_inf->add_augmentation_size
+ = cie->cie_inf->add_augmentation_size;
+
+ ENSURE_NO_RELOCS (buf);
+ if ((sec->flags & SEC_LINKER_CREATED) == 0 || cookie->rels != NULL)
+ {
+ asection *rsec;
+
+ REQUIRE (GET_RELOC (buf));
+
+ /* Chain together the FDEs for each section. */
+ rsec = _bfd_elf_gc_mark_rsec (info, sec, gc_mark_hook, cookie);
+ /* RSEC will be NULL if FDE was cleared out as it was belonging to
+ a discarded SHT_GROUP. */
+ if (rsec)
+ {
+ REQUIRE (rsec->owner == abfd);
+ this_inf->u.fde.next_for_section = elf_fde_list (rsec);
+ elf_fde_list (rsec) = this_inf;
+ }
+ }
+
+ /* Skip the initial location and address range. */
+ start = buf;
+ length = get_DW_EH_PE_width (cie->fde_encoding, ptr_size);
+ REQUIRE (skip_bytes (&buf, end, 2 * length));
+
+ SKIP_RELOCS (buf - length);
+ if (!GET_RELOC (buf - length)
+ && read_value (abfd, buf - length, length, FALSE) == 0)
+ {
+ (*info->callbacks->minfo)
+ (_("discarding zero address range FDE in %B(%A).\n"),
+ abfd, sec);
+ this_inf->u.fde.cie_inf = NULL;
+ }
+
+ /* Skip the augmentation size, if present. */
+ if (cie->augmentation[0] == 'z')
+ REQUIRE (read_uleb128 (&buf, end, &length));
+ else
+ length = 0;
+
+ /* Of the supported augmentation characters above, only 'L'
+ adds augmentation data to the FDE. This code would need to
+ be adjusted if any future augmentations do the same thing. */
+ if (cie->lsda_encoding != DW_EH_PE_omit)
+ {
+ SKIP_RELOCS (buf);
+ if (cie->can_make_lsda_relative && GET_RELOC (buf))
+ cie->cie_inf->u.cie.make_lsda_relative = 1;
+ this_inf->lsda_offset = buf - start;
+ /* If there's no 'z' augmentation, we don't know where the
+ CFA insns begin. Assume no padding. */
+ if (cie->augmentation[0] != 'z')
+ length = end - buf;
+ }
+
+ /* Skip over the augmentation data. */
+ REQUIRE (skip_bytes (&buf, end, length));
+ insns = buf;
+
+ buf = last_fde + 4 + hdr_length;
+
+ /* For NULL RSEC (cleared FDE belonging to a discarded section)
+ the relocations are commonly cleared. We do not sanity check if
+ all these relocations are cleared as (1) relocations to
+ .gcc_except_table will remain uncleared (they will get dropped
+ with the drop of this unused FDE) and (2) BFD already safely drops
+ relocations of any type to .eh_frame by
+ elf_section_ignore_discarded_relocs.
+ TODO: The .gcc_except_table entries should be also filtered as
+ .eh_frame entries; or GCC could rather use COMDAT for them. */
+ SKIP_RELOCS (buf);
+ }
+
+ /* Try to interpret the CFA instructions and find the first
+ padding nop. Shrink this_inf's size so that it doesn't
+ include the padding. */
+ length = get_DW_EH_PE_width (cie->fde_encoding, ptr_size);
+ set_loc_count = 0;
+ insns_end = skip_non_nops (insns, end, length, &set_loc_count);
+ /* If we don't understand the CFA instructions, we can't know
+ what needs to be adjusted there. */
+ if (insns_end == NULL
+ /* For the time being we don't support DW_CFA_set_loc in
+ CIE instructions. */
+ || (set_loc_count && this_inf->cie))
+ goto free_no_table;
+ this_inf->size -= end - insns_end;
+ if (insns_end != end && this_inf->cie)
+ {
+ cie->initial_insn_length -= end - insns_end;
+ cie->length -= end - insns_end;
+ }
+ if (set_loc_count
+ && ((cie->fde_encoding & 0x70) == DW_EH_PE_pcrel
+ || this_inf->make_relative))
+ {
+ unsigned int cnt;
+ bfd_byte *p;
+
+ this_inf->set_loc = (unsigned int *)
+ bfd_malloc ((set_loc_count + 1) * sizeof (unsigned int));
+ REQUIRE (this_inf->set_loc);
+ this_inf->set_loc[0] = set_loc_count;
+ p = insns;
+ cnt = 0;
+ while (p < end)
+ {
+ if (*p == DW_CFA_set_loc)
+ this_inf->set_loc[++cnt] = p + 1 - start;
+ REQUIRE (skip_cfa_op (&p, end, length));
+ }
+ }
+
+ this_inf->removed = 1;
+ this_inf->fde_encoding = cie->fde_encoding;
+ this_inf->lsda_encoding = cie->lsda_encoding;
+ sec_info->count++;
+ }
+ BFD_ASSERT (sec_info->count == num_entries);
+ BFD_ASSERT (cie_count == num_cies);
+
+ elf_section_data (sec)->sec_info = sec_info;
+ sec->sec_info_type = SEC_INFO_TYPE_EH_FRAME;
+ if (!info->relocatable)
+ {
+ /* Keep info for merging cies. */
+ sec_info->cies = local_cies;
+ local_cies = NULL;
+ }
+ goto success;
+
+ free_no_table:
+ (*info->callbacks->einfo)
+ (_("%P: error in %B(%A); no .eh_frame_hdr table will be created.\n"),
+ abfd, sec);
+ hdr_info->table = FALSE;
+ if (sec_info)
+ free (sec_info);
+ success:
+ if (ehbuf)
+ free (ehbuf);
+ if (local_cies)
+ free (local_cies);
+#undef REQUIRE
+}
+
+/* Mark all relocations against CIE or FDE ENT, which occurs in
+ .eh_frame section SEC. COOKIE describes the relocations in SEC;
+ its "rel" field can be changed freely. */
+
+static bfd_boolean
+mark_entry (struct bfd_link_info *info, asection *sec,
+ struct eh_cie_fde *ent, elf_gc_mark_hook_fn gc_mark_hook,
+ struct elf_reloc_cookie *cookie)
+{
+ /* FIXME: octets_per_byte. */
+ for (cookie->rel = cookie->rels + ent->reloc_index;
+ cookie->rel < cookie->relend
+ && cookie->rel->r_offset < ent->offset + ent->size;
+ cookie->rel++)
+ if (!_bfd_elf_gc_mark_reloc (info, sec, gc_mark_hook, cookie))
+ return FALSE;
+
+ return TRUE;
+}
+
+/* Mark all the relocations against FDEs that relate to code in input
+ section SEC. The FDEs belong to .eh_frame section EH_FRAME, whose
+ relocations are described by COOKIE. */
+
+bfd_boolean
+_bfd_elf_gc_mark_fdes (struct bfd_link_info *info, asection *sec,
+ asection *eh_frame, elf_gc_mark_hook_fn gc_mark_hook,
+ struct elf_reloc_cookie *cookie)
+{
+ struct eh_cie_fde *fde, *cie;
+
+ for (fde = elf_fde_list (sec); fde; fde = fde->u.fde.next_for_section)
+ {
+ if (!mark_entry (info, eh_frame, fde, gc_mark_hook, cookie))
+ return FALSE;
+
+ /* At this stage, all cie_inf fields point to local CIEs, so we
+ can use the same cookie to refer to them. */
+ cie = fde->u.fde.cie_inf;
+ if (cie != NULL && !cie->u.cie.gc_mark)
+ {
+ cie->u.cie.gc_mark = 1;
+ if (!mark_entry (info, eh_frame, cie, gc_mark_hook, cookie))
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+/* Input section SEC of ABFD is an .eh_frame section that contains the
+ CIE described by CIE_INF. Return a version of CIE_INF that is going
+ to be kept in the output, adding CIE_INF to the output if necessary.
+
+ HDR_INFO is the .eh_frame_hdr information and COOKIE describes the
+ relocations in REL. */
+
+static struct eh_cie_fde *
+find_merged_cie (bfd *abfd, struct bfd_link_info *info, asection *sec,
+ struct eh_frame_hdr_info *hdr_info,
+ struct elf_reloc_cookie *cookie,
+ struct eh_cie_fde *cie_inf)
+{
+ unsigned long r_symndx;
+ struct cie *cie, *new_cie;
+ Elf_Internal_Rela *rel;
+ void **loc;
+
+ /* Use CIE_INF if we have already decided to keep it. */
+ if (!cie_inf->removed)
+ return cie_inf;
+
+ /* If we have merged CIE_INF with another CIE, use that CIE instead. */
+ if (cie_inf->u.cie.merged)
+ return cie_inf->u.cie.u.merged_with;
+
+ cie = cie_inf->u.cie.u.full_cie;
+
+ /* Assume we will need to keep CIE_INF. */
+ cie_inf->removed = 0;
+ cie_inf->u.cie.u.sec = sec;
+
+ /* If we are not merging CIEs, use CIE_INF. */
+ if (cie == NULL)
+ return cie_inf;
+
+ if (cie->per_encoding != DW_EH_PE_omit)
+ {
+ bfd_boolean per_binds_local;
+
+ /* Work out the address of personality routine, or at least
+ enough info that we could calculate the address had we made a
+ final section layout. The symbol on the reloc is enough,
+ either the hash for a global, or (bfd id, index) pair for a
+ local. The assumption here is that no one uses addends on
+ the reloc. */
+ rel = cookie->rels + cie->personality.reloc_index;
+ memset (&cie->personality, 0, sizeof (cie->personality));
+#ifdef BFD64
+ if (elf_elfheader (abfd)->e_ident[EI_CLASS] == ELFCLASS64)
+ r_symndx = ELF64_R_SYM (rel->r_info);
+ else
+#endif
+ r_symndx = ELF32_R_SYM (rel->r_info);
+ if (r_symndx >= cookie->locsymcount
+ || ELF_ST_BIND (cookie->locsyms[r_symndx].st_info) != STB_LOCAL)
+ {
+ struct elf_link_hash_entry *h;
+
+ r_symndx -= cookie->extsymoff;
+ h = cookie->sym_hashes[r_symndx];
+
+ 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;
+
+ cie->personality.h = h;
+ per_binds_local = SYMBOL_REFERENCES_LOCAL (info, h);
+ }
+ else
+ {
+ Elf_Internal_Sym *sym;
+ asection *sym_sec;
+
+ sym = &cookie->locsyms[r_symndx];
+ sym_sec = bfd_section_from_elf_index (abfd, sym->st_shndx);
+ if (sym_sec == NULL)
+ return cie_inf;
+
+ if (sym_sec->kept_section != NULL)
+ sym_sec = sym_sec->kept_section;
+ if (sym_sec->output_section == NULL)
+ return cie_inf;
+
+ cie->local_personality = 1;
+ cie->personality.sym.bfd_id = abfd->id;
+ cie->personality.sym.index = r_symndx;
+ per_binds_local = TRUE;
+ }
+
+ if (per_binds_local
+ && info->shared
+ && !info->relocatable
+ && (cie->per_encoding & 0x70) == DW_EH_PE_absptr
+ && (get_elf_backend_data (abfd)
+ ->elf_backend_can_make_relative_eh_frame (abfd, info, sec)))
+ {
+ cie_inf->u.cie.make_per_encoding_relative = 1;
+ cie_inf->u.cie.per_encoding_relative = 1;
+ }
+ }
+
+ /* See if we can merge this CIE with an earlier one. */
+ cie_compute_hash (cie);
+ if (hdr_info->cies == NULL)
+ {
+ hdr_info->cies = htab_try_create (1, cie_hash, cie_eq, free);
+ if (hdr_info->cies == NULL)
+ return cie_inf;
+ }
+ loc = htab_find_slot_with_hash (hdr_info->cies, cie, cie->hash, INSERT);
+ if (loc == NULL)
+ return cie_inf;
+
+ new_cie = (struct cie *) *loc;
+ if (new_cie == NULL)
+ {
+ /* Keep CIE_INF and record it in the hash table. */
+ new_cie = (struct cie *) malloc (sizeof (struct cie));
+ if (new_cie == NULL)
+ return cie_inf;
+
+ memcpy (new_cie, cie, sizeof (struct cie));
+ *loc = new_cie;
+ }
+ else
+ {
+ /* Merge CIE_INF with NEW_CIE->CIE_INF. */
+ cie_inf->removed = 1;
+ cie_inf->u.cie.merged = 1;
+ cie_inf->u.cie.u.merged_with = new_cie->cie_inf;
+ if (cie_inf->u.cie.make_lsda_relative)
+ new_cie->cie_inf->u.cie.make_lsda_relative = 1;
+ }
+ return new_cie->cie_inf;
+}
+
+/* This function is called for each input file before the .eh_frame
+ section is relocated. It discards duplicate CIEs and FDEs for discarded
+ functions. The function returns TRUE iff any entries have been
+ deleted. */
+
+bfd_boolean
+_bfd_elf_discard_section_eh_frame
+ (bfd *abfd, struct bfd_link_info *info, asection *sec,
+ bfd_boolean (*reloc_symbol_deleted_p) (bfd_vma, void *),
+ struct elf_reloc_cookie *cookie)
+{
+ struct eh_cie_fde *ent;
+ struct eh_frame_sec_info *sec_info;
+ struct eh_frame_hdr_info *hdr_info;
+ unsigned int ptr_size, offset;
+
+ if (sec->sec_info_type != SEC_INFO_TYPE_EH_FRAME)
+ return FALSE;
+
+ sec_info = (struct eh_frame_sec_info *) elf_section_data (sec)->sec_info;
+ if (sec_info == NULL)
+ return FALSE;
+
+ ptr_size = (get_elf_backend_data (sec->owner)
+ ->elf_backend_eh_frame_address_size (sec->owner, sec));
+
+ hdr_info = &elf_hash_table (info)->eh_info;
+ for (ent = sec_info->entry; ent < sec_info->entry + sec_info->count; ++ent)
+ if (ent->size == 4)
+ /* There should only be one zero terminator, on the last input
+ file supplying .eh_frame (crtend.o). Remove any others. */
+ ent->removed = sec->map_head.s != NULL;
+ else if (!ent->cie && ent->u.fde.cie_inf != NULL)
+ {
+ bfd_boolean keep;
+ if ((sec->flags & SEC_LINKER_CREATED) != 0 && cookie->rels == NULL)
+ {
+ unsigned int width
+ = get_DW_EH_PE_width (ent->fde_encoding, ptr_size);
+ bfd_vma value
+ = read_value (abfd, sec->contents + ent->offset + 8 + width,
+ width, get_DW_EH_PE_signed (ent->fde_encoding));
+ keep = value != 0;
+ }
+ else
+ {
+ cookie->rel = cookie->rels + ent->reloc_index;
+ /* FIXME: octets_per_byte. */
+ BFD_ASSERT (cookie->rel < cookie->relend
+ && cookie->rel->r_offset == ent->offset + 8);
+ keep = !(*reloc_symbol_deleted_p) (ent->offset + 8, cookie);
+ }
+ if (keep)
+ {
+ if (info->shared
+ && (((ent->fde_encoding & 0x70) == DW_EH_PE_absptr
+ && ent->make_relative == 0)
+ || (ent->fde_encoding & 0x70) == DW_EH_PE_aligned))
+ {
+ /* If a shared library uses absolute pointers
+ which we cannot turn into PC relative,
+ don't create the binary search table,
+ since it is affected by runtime relocations. */
+ hdr_info->table = FALSE;
+ (*info->callbacks->einfo)
+ (_("%P: FDE encoding in %B(%A) prevents .eh_frame_hdr"
+ " table being created.\n"), abfd, sec);
+ }
+ ent->removed = 0;
+ hdr_info->fde_count++;
+ ent->u.fde.cie_inf = find_merged_cie (abfd, info, sec, hdr_info,
+ cookie, ent->u.fde.cie_inf);
+ }
+ }
+
+ if (sec_info->cies)
+ {
+ free (sec_info->cies);
+ sec_info->cies = NULL;
+ }
+
+ offset = 0;
+ for (ent = sec_info->entry; ent < sec_info->entry + sec_info->count; ++ent)
+ if (!ent->removed)
+ {
+ ent->new_offset = offset;
+ offset += size_of_output_cie_fde (ent, ptr_size);
+ }
+
+ sec->rawsize = sec->size;
+ sec->size = offset;
+ return offset != sec->rawsize;
+}
+
+/* This function is called for .eh_frame_hdr section after
+ _bfd_elf_discard_section_eh_frame has been called on all .eh_frame
+ input sections. It finalizes the size of .eh_frame_hdr section. */
+
+bfd_boolean
+_bfd_elf_discard_section_eh_frame_hdr (bfd *abfd, struct bfd_link_info *info)
+{
+ struct elf_link_hash_table *htab;
+ struct eh_frame_hdr_info *hdr_info;
+ asection *sec;
+
+ htab = elf_hash_table (info);
+ hdr_info = &htab->eh_info;
+
+ if (hdr_info->cies != NULL)
+ {
+ htab_delete (hdr_info->cies);
+ hdr_info->cies = NULL;
+ }
+
+ sec = hdr_info->hdr_sec;
+ if (sec == NULL)
+ return FALSE;
+
+ sec->size = EH_FRAME_HDR_SIZE;
+ if (hdr_info->table)
+ sec->size += 4 + hdr_info->fde_count * 8;
+
+ elf_eh_frame_hdr (abfd) = sec;
+ return TRUE;
+}
+
+/* Return true if there is at least one non-empty .eh_frame section in
+ input files. Can only be called after ld has mapped input to
+ output sections, and before sections are stripped. */
+bfd_boolean
+_bfd_elf_eh_frame_present (struct bfd_link_info *info)
+{
+ asection *eh = bfd_get_section_by_name (info->output_bfd, ".eh_frame");
+
+ if (eh == NULL)
+ return FALSE;
+
+ /* Count only sections which have at least a single CIE or FDE.
+ There cannot be any CIE or FDE <= 8 bytes. */
+ for (eh = eh->map_head.s; eh != NULL; eh = eh->map_head.s)
+ if (eh->size > 8)
+ return TRUE;
+
+ return FALSE;
+}
+
+/* This function is called from size_dynamic_sections.
+ It needs to decide whether .eh_frame_hdr should be output or not,
+ because when the dynamic symbol table has been sized it is too late
+ to strip sections. */
+
+bfd_boolean
+_bfd_elf_maybe_strip_eh_frame_hdr (struct bfd_link_info *info)
+{
+ struct elf_link_hash_table *htab;
+ struct eh_frame_hdr_info *hdr_info;
+
+ htab = elf_hash_table (info);
+ hdr_info = &htab->eh_info;
+ if (hdr_info->hdr_sec == NULL)
+ return TRUE;
+
+ if (bfd_is_abs_section (hdr_info->hdr_sec->output_section)
+ || !info->eh_frame_hdr
+ || !_bfd_elf_eh_frame_present (info))
+ {
+ hdr_info->hdr_sec->flags |= SEC_EXCLUDE;
+ hdr_info->hdr_sec = NULL;
+ return TRUE;
+ }
+
+ hdr_info->table = TRUE;
+ return TRUE;
+}
+
+/* Adjust an address in the .eh_frame section. Given OFFSET within
+ SEC, this returns the new offset in the adjusted .eh_frame section,
+ or -1 if the address refers to a CIE/FDE which has been removed
+ or to offset with dynamic relocation which is no longer needed. */
+
+bfd_vma
+_bfd_elf_eh_frame_section_offset (bfd *output_bfd ATTRIBUTE_UNUSED,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ asection *sec,
+ bfd_vma offset)
+{
+ struct eh_frame_sec_info *sec_info;
+ unsigned int lo, hi, mid;
+
+ if (sec->sec_info_type != SEC_INFO_TYPE_EH_FRAME)
+ return offset;
+ sec_info = (struct eh_frame_sec_info *) elf_section_data (sec)->sec_info;
+
+ if (offset >= sec->rawsize)
+ return offset - sec->rawsize + sec->size;
+
+ lo = 0;
+ hi = sec_info->count;
+ mid = 0;
+ while (lo < hi)
+ {
+ mid = (lo + hi) / 2;
+ if (offset < sec_info->entry[mid].offset)
+ hi = mid;
+ else if (offset
+ >= sec_info->entry[mid].offset + sec_info->entry[mid].size)
+ lo = mid + 1;
+ else
+ break;
+ }
+
+ BFD_ASSERT (lo < hi);
+
+ /* FDE or CIE was removed. */
+ if (sec_info->entry[mid].removed)
+ return (bfd_vma) -1;
+
+ /* If converting personality pointers to DW_EH_PE_pcrel, there will be
+ no need for run-time relocation against the personality field. */
+ if (sec_info->entry[mid].cie
+ && sec_info->entry[mid].u.cie.make_per_encoding_relative
+ && offset == (sec_info->entry[mid].offset + 8
+ + sec_info->entry[mid].u.cie.personality_offset))
+ return (bfd_vma) -2;
+
+ /* If converting to DW_EH_PE_pcrel, there will be no need for run-time
+ relocation against FDE's initial_location field. */
+ if (!sec_info->entry[mid].cie
+ && sec_info->entry[mid].make_relative
+ && offset == sec_info->entry[mid].offset + 8)
+ return (bfd_vma) -2;
+
+ /* If converting LSDA pointers to DW_EH_PE_pcrel, there will be no need
+ for run-time relocation against LSDA field. */
+ if (!sec_info->entry[mid].cie
+ && sec_info->entry[mid].u.fde.cie_inf->u.cie.make_lsda_relative
+ && offset == (sec_info->entry[mid].offset + 8
+ + sec_info->entry[mid].lsda_offset))
+ return (bfd_vma) -2;
+
+ /* If converting to DW_EH_PE_pcrel, there will be no need for run-time
+ relocation against DW_CFA_set_loc's arguments. */
+ if (sec_info->entry[mid].set_loc
+ && sec_info->entry[mid].make_relative
+ && (offset >= sec_info->entry[mid].offset + 8
+ + sec_info->entry[mid].set_loc[1]))
+ {
+ unsigned int cnt;
+
+ for (cnt = 1; cnt <= sec_info->entry[mid].set_loc[0]; cnt++)
+ if (offset == sec_info->entry[mid].offset + 8
+ + sec_info->entry[mid].set_loc[cnt])
+ return (bfd_vma) -2;
+ }
+
+ /* Any new augmentation bytes go before the first relocation. */
+ return (offset + sec_info->entry[mid].new_offset
+ - sec_info->entry[mid].offset
+ + extra_augmentation_string_bytes (sec_info->entry + mid)
+ + extra_augmentation_data_bytes (sec_info->entry + mid));
+}
+
+/* Write out .eh_frame section. This is called with the relocated
+ contents. */
+
+bfd_boolean
+_bfd_elf_write_section_eh_frame (bfd *abfd,
+ struct bfd_link_info *info,
+ asection *sec,
+ bfd_byte *contents)
+{
+ struct eh_frame_sec_info *sec_info;
+ struct elf_link_hash_table *htab;
+ struct eh_frame_hdr_info *hdr_info;
+ unsigned int ptr_size;
+ struct eh_cie_fde *ent;
+ bfd_size_type sec_size;
+
+ if (sec->sec_info_type != SEC_INFO_TYPE_EH_FRAME)
+ /* FIXME: octets_per_byte. */
+ return bfd_set_section_contents (abfd, sec->output_section, contents,
+ sec->output_offset, sec->size);
+
+ ptr_size = (get_elf_backend_data (abfd)
+ ->elf_backend_eh_frame_address_size (abfd, sec));
+ BFD_ASSERT (ptr_size != 0);
+
+ sec_info = (struct eh_frame_sec_info *) elf_section_data (sec)->sec_info;
+ htab = elf_hash_table (info);
+ hdr_info = &htab->eh_info;
+
+ if (hdr_info->table && hdr_info->array == NULL)
+ hdr_info->array = (struct eh_frame_array_ent *)
+ bfd_malloc (hdr_info->fde_count * sizeof(*hdr_info->array));
+ if (hdr_info->array == NULL)
+ hdr_info = NULL;
+
+ /* The new offsets can be bigger or smaller than the original offsets.
+ We therefore need to make two passes over the section: one backward
+ pass to move entries up and one forward pass to move entries down.
+ The two passes won't interfere with each other because entries are
+ not reordered */
+ for (ent = sec_info->entry + sec_info->count; ent-- != sec_info->entry;)
+ if (!ent->removed && ent->new_offset > ent->offset)
+ memmove (contents + ent->new_offset, contents + ent->offset, ent->size);
+
+ for (ent = sec_info->entry; ent < sec_info->entry + sec_info->count; ++ent)
+ if (!ent->removed && ent->new_offset < ent->offset)
+ memmove (contents + ent->new_offset, contents + ent->offset, ent->size);
+
+ for (ent = sec_info->entry; ent < sec_info->entry + sec_info->count; ++ent)
+ {
+ unsigned char *buf, *end;
+ unsigned int new_size;
+
+ if (ent->removed)
+ continue;
+
+ if (ent->size == 4)
+ {
+ /* Any terminating FDE must be at the end of the section. */
+ BFD_ASSERT (ent == sec_info->entry + sec_info->count - 1);
+ continue;
+ }
+
+ buf = contents + ent->new_offset;
+ end = buf + ent->size;
+ new_size = size_of_output_cie_fde (ent, ptr_size);
+
+ /* Update the size. It may be shrinked. */
+ bfd_put_32 (abfd, new_size - 4, buf);
+
+ /* Filling the extra bytes with DW_CFA_nops. */
+ if (new_size != ent->size)
+ memset (end, 0, new_size - ent->size);
+
+ if (ent->cie)
+ {
+ /* CIE */
+ if (ent->make_relative
+ || ent->u.cie.make_lsda_relative
+ || ent->u.cie.per_encoding_relative)
+ {
+ char *aug;
+ unsigned int action, extra_string, extra_data;
+ unsigned int per_width, per_encoding;
+
+ /* Need to find 'R' or 'L' augmentation's argument and modify
+ DW_EH_PE_* value. */
+ action = ((ent->make_relative ? 1 : 0)
+ | (ent->u.cie.make_lsda_relative ? 2 : 0)
+ | (ent->u.cie.per_encoding_relative ? 4 : 0));
+ extra_string = extra_augmentation_string_bytes (ent);
+ extra_data = extra_augmentation_data_bytes (ent);
+
+ /* Skip length, id and version. */
+ buf += 9;
+ aug = (char *) buf;
+ buf += strlen (aug) + 1;
+ skip_leb128 (&buf, end);
+ skip_leb128 (&buf, end);
+ skip_leb128 (&buf, end);
+ if (*aug == 'z')
+ {
+ /* The uleb128 will always be a single byte for the kind
+ of augmentation strings that we're prepared to handle. */
+ *buf++ += extra_data;
+ aug++;
+ }
+
+ /* Make room for the new augmentation string and data bytes. */
+ memmove (buf + extra_string + extra_data, buf, end - buf);
+ memmove (aug + extra_string, aug, buf - (bfd_byte *) aug);
+ buf += extra_string;
+ end += extra_string + extra_data;
+
+ if (ent->add_augmentation_size)
+ {
+ *aug++ = 'z';
+ *buf++ = extra_data - 1;
+ }
+ if (ent->u.cie.add_fde_encoding)
+ {
+ BFD_ASSERT (action & 1);
+ *aug++ = 'R';
+ *buf++ = make_pc_relative (DW_EH_PE_absptr, ptr_size);
+ action &= ~1;
+ }
+
+ while (action)
+ switch (*aug++)
+ {
+ case 'L':
+ if (action & 2)
+ {
+ BFD_ASSERT (*buf == ent->lsda_encoding);
+ *buf = make_pc_relative (*buf, ptr_size);
+ action &= ~2;
+ }
+ buf++;
+ break;
+ case 'P':
+ if (ent->u.cie.make_per_encoding_relative)
+ *buf = make_pc_relative (*buf, ptr_size);
+ per_encoding = *buf++;
+ per_width = get_DW_EH_PE_width (per_encoding, ptr_size);
+ BFD_ASSERT (per_width != 0);
+ BFD_ASSERT (((per_encoding & 0x70) == DW_EH_PE_pcrel)
+ == ent->u.cie.per_encoding_relative);
+ if ((per_encoding & 0x70) == DW_EH_PE_aligned)
+ buf = (contents
+ + ((buf - contents + per_width - 1)
+ & ~((bfd_size_type) per_width - 1)));
+ if (action & 4)
+ {
+ bfd_vma val;
+
+ val = read_value (abfd, buf, per_width,
+ get_DW_EH_PE_signed (per_encoding));
+ if (ent->u.cie.make_per_encoding_relative)
+ val -= (sec->output_section->vma
+ + sec->output_offset
+ + (buf - contents));
+ else
+ {
+ val += (bfd_vma) ent->offset - ent->new_offset;
+ val -= extra_string + extra_data;
+ }
+ write_value (abfd, buf, val, per_width);
+ action &= ~4;
+ }
+ buf += per_width;
+ break;
+ case 'R':
+ if (action & 1)
+ {
+ BFD_ASSERT (*buf == ent->fde_encoding);
+ *buf = make_pc_relative (*buf, ptr_size);
+ action &= ~1;
+ }
+ buf++;
+ break;
+ case 'S':
+ break;
+ default:
+ BFD_FAIL ();
+ }
+ }
+ }
+ else
+ {
+ /* FDE */
+ bfd_vma value, address;
+ unsigned int width;
+ bfd_byte *start;
+ struct eh_cie_fde *cie;
+
+ /* Skip length. */
+ cie = ent->u.fde.cie_inf;
+ buf += 4;
+ value = ((ent->new_offset + sec->output_offset + 4)
+ - (cie->new_offset + cie->u.cie.u.sec->output_offset));
+ bfd_put_32 (abfd, value, buf);
+ if (info->relocatable)
+ continue;
+ buf += 4;
+ width = get_DW_EH_PE_width (ent->fde_encoding, ptr_size);
+ value = read_value (abfd, buf, width,
+ get_DW_EH_PE_signed (ent->fde_encoding));
+ address = value;
+ if (value)
+ {
+ switch (ent->fde_encoding & 0x70)
+ {
+ case DW_EH_PE_textrel:
+ BFD_ASSERT (hdr_info == NULL);
+ break;
+ case DW_EH_PE_datarel:
+ {
+ switch (abfd->arch_info->arch)
+ {
+ case bfd_arch_ia64:
+ BFD_ASSERT (elf_gp (abfd) != 0);
+ address += elf_gp (abfd);
+ break;
+ default:
+ (*info->callbacks->einfo)
+ (_("%P: DW_EH_PE_datarel unspecified"
+ " for this architecture.\n"));
+ /* Fall thru */
+ case bfd_arch_frv:
+ case bfd_arch_i386:
+ BFD_ASSERT (htab->hgot != NULL
+ && ((htab->hgot->root.type
+ == bfd_link_hash_defined)
+ || (htab->hgot->root.type
+ == bfd_link_hash_defweak)));
+ address
+ += (htab->hgot->root.u.def.value
+ + htab->hgot->root.u.def.section->output_offset
+ + (htab->hgot->root.u.def.section->output_section
+ ->vma));
+ break;
+ }
+ }
+ break;
+ case DW_EH_PE_pcrel:
+ value += (bfd_vma) ent->offset - ent->new_offset;
+ address += (sec->output_section->vma
+ + sec->output_offset
+ + ent->offset + 8);
+ break;
+ }
+ if (ent->make_relative)
+ value -= (sec->output_section->vma
+ + sec->output_offset
+ + ent->new_offset + 8);
+ write_value (abfd, buf, value, width);
+ }
+
+ start = buf;
+
+ if (hdr_info)
+ {
+ /* The address calculation may overflow, giving us a
+ value greater than 4G on a 32-bit target when
+ dwarf_vma is 64-bit. */
+ if (sizeof (address) > 4 && ptr_size == 4)
+ address &= 0xffffffff;
+ hdr_info->array[hdr_info->array_count].initial_loc = address;
+ hdr_info->array[hdr_info->array_count].range
+ = read_value (abfd, buf + width, width, FALSE);
+ hdr_info->array[hdr_info->array_count++].fde
+ = (sec->output_section->vma
+ + sec->output_offset
+ + ent->new_offset);
+ }
+
+ if ((ent->lsda_encoding & 0x70) == DW_EH_PE_pcrel
+ || cie->u.cie.make_lsda_relative)
+ {
+ buf += ent->lsda_offset;
+ width = get_DW_EH_PE_width (ent->lsda_encoding, ptr_size);
+ value = read_value (abfd, buf, width,
+ get_DW_EH_PE_signed (ent->lsda_encoding));
+ if (value)
+ {
+ if ((ent->lsda_encoding & 0x70) == DW_EH_PE_pcrel)
+ value += (bfd_vma) ent->offset - ent->new_offset;
+ else if (cie->u.cie.make_lsda_relative)
+ value -= (sec->output_section->vma
+ + sec->output_offset
+ + ent->new_offset + 8 + ent->lsda_offset);
+ write_value (abfd, buf, value, width);
+ }
+ }
+ else if (ent->add_augmentation_size)
+ {
+ /* Skip the PC and length and insert a zero byte for the
+ augmentation size. */
+ buf += width * 2;
+ memmove (buf + 1, buf, end - buf);
+ *buf = 0;
+ }
+
+ if (ent->set_loc)
+ {
+ /* Adjust DW_CFA_set_loc. */
+ unsigned int cnt;
+ bfd_vma new_offset;
+
+ width = get_DW_EH_PE_width (ent->fde_encoding, ptr_size);
+ new_offset = ent->new_offset + 8
+ + extra_augmentation_string_bytes (ent)
+ + extra_augmentation_data_bytes (ent);
+
+ for (cnt = 1; cnt <= ent->set_loc[0]; cnt++)
+ {
+ buf = start + ent->set_loc[cnt];
+
+ value = read_value (abfd, buf, width,
+ get_DW_EH_PE_signed (ent->fde_encoding));
+ if (!value)
+ continue;
+
+ if ((ent->fde_encoding & 0x70) == DW_EH_PE_pcrel)
+ value += (bfd_vma) ent->offset + 8 - new_offset;
+ if (ent->make_relative)
+ value -= (sec->output_section->vma
+ + sec->output_offset
+ + new_offset + ent->set_loc[cnt]);
+ write_value (abfd, buf, value, width);
+ }
+ }
+ }
+ }
+
+ /* We don't align the section to its section alignment since the
+ runtime library only expects all CIE/FDE records aligned at
+ the pointer size. _bfd_elf_discard_section_eh_frame should
+ have padded CIE/FDE records to multiple of pointer size with
+ size_of_output_cie_fde. */
+ sec_size = sec->size;
+ if (sec_info->count != 0
+ && sec_info->entry[sec_info->count - 1].size == 4)
+ sec_size -= 4;
+ if ((sec_size % ptr_size) != 0)
+ abort ();
+
+ /* FIXME: octets_per_byte. */
+ return bfd_set_section_contents (abfd, sec->output_section,
+ contents, (file_ptr) sec->output_offset,
+ sec->size);
+}
+
+/* Helper function used to sort .eh_frame_hdr search table by increasing
+ VMA of FDE initial location. */
+
+static int
+vma_compare (const void *a, const void *b)
+{
+ const struct eh_frame_array_ent *p = (const struct eh_frame_array_ent *) a;
+ const struct eh_frame_array_ent *q = (const struct eh_frame_array_ent *) b;
+ if (p->initial_loc > q->initial_loc)
+ return 1;
+ if (p->initial_loc < q->initial_loc)
+ return -1;
+ if (p->range > q->range)
+ return 1;
+ if (p->range < q->range)
+ return -1;
+ return 0;
+}
+
+/* Write out .eh_frame_hdr section. This must be called after
+ _bfd_elf_write_section_eh_frame has been called on all input
+ .eh_frame sections.
+ .eh_frame_hdr format:
+ ubyte version (currently 1)
+ ubyte eh_frame_ptr_enc (DW_EH_PE_* encoding of pointer to start of
+ .eh_frame section)
+ ubyte fde_count_enc (DW_EH_PE_* encoding of total FDE count
+ number (or DW_EH_PE_omit if there is no
+ binary search table computed))
+ ubyte table_enc (DW_EH_PE_* encoding of binary search table,
+ or DW_EH_PE_omit if not present.
+ DW_EH_PE_datarel is using address of
+ .eh_frame_hdr section start as base)
+ [encoded] eh_frame_ptr (pointer to start of .eh_frame section)
+ optionally followed by:
+ [encoded] fde_count (total number of FDEs in .eh_frame section)
+ fde_count x [encoded] initial_loc, fde
+ (array of encoded pairs containing
+ FDE initial_location field and FDE address,
+ sorted by increasing initial_loc). */
+
+bfd_boolean
+_bfd_elf_write_section_eh_frame_hdr (bfd *abfd, struct bfd_link_info *info)
+{
+ struct elf_link_hash_table *htab;
+ struct eh_frame_hdr_info *hdr_info;
+ asection *sec;
+ bfd_boolean retval = TRUE;
+
+ htab = elf_hash_table (info);
+ hdr_info = &htab->eh_info;
+ sec = hdr_info->hdr_sec;
+
+ if (info->eh_frame_hdr && sec != NULL)
+ {
+ bfd_byte *contents;
+ asection *eh_frame_sec;
+ bfd_size_type size;
+ bfd_vma encoded_eh_frame;
+
+ size = EH_FRAME_HDR_SIZE;
+ if (hdr_info->array && hdr_info->array_count == hdr_info->fde_count)
+ size += 4 + hdr_info->fde_count * 8;
+ contents = (bfd_byte *) bfd_malloc (size);
+ if (contents == NULL)
+ return FALSE;
+
+ eh_frame_sec = bfd_get_section_by_name (abfd, ".eh_frame");
+ if (eh_frame_sec == NULL)
+ {
+ free (contents);
+ return FALSE;
+ }
+
+ memset (contents, 0, EH_FRAME_HDR_SIZE);
+ /* Version. */
+ contents[0] = 1;
+ /* .eh_frame offset. */
+ contents[1] = get_elf_backend_data (abfd)->elf_backend_encode_eh_address
+ (abfd, info, eh_frame_sec, 0, sec, 4, &encoded_eh_frame);
+
+ if (hdr_info->array && hdr_info->array_count == hdr_info->fde_count)
+ {
+ /* FDE count encoding. */
+ contents[2] = DW_EH_PE_udata4;
+ /* Search table encoding. */
+ contents[3] = DW_EH_PE_datarel | DW_EH_PE_sdata4;
+ }
+ else
+ {
+ contents[2] = DW_EH_PE_omit;
+ contents[3] = DW_EH_PE_omit;
+ }
+ bfd_put_32 (abfd, encoded_eh_frame, contents + 4);
+
+ if (contents[2] != DW_EH_PE_omit)
+ {
+ unsigned int i;
+
+ bfd_put_32 (abfd, hdr_info->fde_count, contents + EH_FRAME_HDR_SIZE);
+ qsort (hdr_info->array, hdr_info->fde_count,
+ sizeof (*hdr_info->array), vma_compare);
+ for (i = 0; i < hdr_info->fde_count; i++)
+ {
+ bfd_vma val;
+
+ val = hdr_info->array[i].initial_loc - sec->output_section->vma;
+ val = ((val & 0xffffffff) ^ 0x80000000) - 0x80000000;
+ if (elf_elfheader (abfd)->e_ident[EI_CLASS] == ELFCLASS64
+ && (hdr_info->array[i].initial_loc
+ != sec->output_section->vma + val))
+ (*info->callbacks->einfo)
+ (_("%X%P: .eh_frame_hdr table[%u] PC overflow.\n"), i);
+ bfd_put_32 (abfd, val, contents + EH_FRAME_HDR_SIZE + i * 8 + 4);
+
+ val = hdr_info->array[i].fde - sec->output_section->vma;
+ val = ((val & 0xffffffff) ^ 0x80000000) - 0x80000000;
+ if (elf_elfheader (abfd)->e_ident[EI_CLASS] == ELFCLASS64
+ && (hdr_info->array[i].fde
+ != sec->output_section->vma + val))
+ (*info->callbacks->einfo)
+ (_("%X%P: .eh_frame_hdr table[%u] FDE overflow.\n"), i);
+ bfd_put_32 (abfd, val, contents + EH_FRAME_HDR_SIZE + i * 8 + 8);
+
+ if (i != 0
+ && (hdr_info->array[i].initial_loc
+ < (hdr_info->array[i - 1].initial_loc
+ + hdr_info->array[i - 1].range)))
+ (*info->callbacks->einfo)
+ (_("%X%P: .eh_frame_hdr table[%u] FDE at %V overlaps "
+ "table[%u] FDE at %V.\n"),
+ i - 1, hdr_info->array[i - 1].fde,
+ i, hdr_info->array[i].fde);
+ }
+ }
+
+ /* FIXME: octets_per_byte. */
+ if (!bfd_set_section_contents (abfd, sec->output_section, contents,
+ (file_ptr) sec->output_offset,
+ sec->size))
+ retval = FALSE;
+ free (contents);
+ }
+ if (hdr_info->array != NULL)
+ free (hdr_info->array);
+ return retval;
+}
+
+/* Return the width of FDE addresses. This is the default implementation. */
+
+unsigned int
+_bfd_elf_eh_frame_address_size (bfd *abfd, asection *sec ATTRIBUTE_UNUSED)
+{
+ return elf_elfheader (abfd)->e_ident[EI_CLASS] == ELFCLASS64 ? 8 : 4;
+}
+
+/* Decide whether we can use a PC-relative encoding within the given
+ EH frame section. This is the default implementation. */
+
+bfd_boolean
+_bfd_elf_can_make_relative (bfd *input_bfd ATTRIBUTE_UNUSED,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ asection *eh_frame_section ATTRIBUTE_UNUSED)
+{
+ return TRUE;
+}
+
+/* Select an encoding for the given address. Preference is given to
+ PC-relative addressing modes. */
+
+bfd_byte
+_bfd_elf_encode_eh_address (bfd *abfd ATTRIBUTE_UNUSED,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ asection *osec, bfd_vma offset,
+ asection *loc_sec, bfd_vma loc_offset,
+ bfd_vma *encoded)
+{
+ *encoded = osec->vma + offset -
+ (loc_sec->output_section->vma + loc_sec->output_offset + loc_offset);
+ return DW_EH_PE_pcrel | DW_EH_PE_sdata4;
+}
diff --git a/bfd/elf-hppa.h b/bfd/elf-hppa.h
new file mode 100644
index 0000000..5ee7de8
--- /dev/null
+++ b/bfd/elf-hppa.h
@@ -0,0 +1,1219 @@
+/* Common code for PA ELF implementations.
+ Copyright (C) 1999-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#define ELF_HOWTO_TABLE_SIZE R_PARISC_UNIMPLEMENTED + 1
+
+/* This file is included by multiple PA ELF BFD backends with different
+ sizes.
+
+ Most of the routines are written to be size independent, but sometimes
+ external constraints require 32 or 64 bit specific code. We remap
+ the definitions/functions as necessary here. */
+#if ARCH_SIZE == 64
+#define ELF_R_TYPE(X) ELF64_R_TYPE(X)
+#define ELF_R_SYM(X) ELF64_R_SYM(X)
+#define elf_hppa_reloc_final_type elf64_hppa_reloc_final_type
+#define _bfd_elf_hppa_gen_reloc_type _bfd_elf64_hppa_gen_reloc_type
+#define elf_hppa_relocate_section elf64_hppa_relocate_section
+#define elf_hppa_final_link elf64_hppa_final_link
+#endif
+#if ARCH_SIZE == 32
+#define ELF_R_TYPE(X) ELF32_R_TYPE(X)
+#define ELF_R_SYM(X) ELF32_R_SYM(X)
+#define elf_hppa_reloc_final_type elf32_hppa_reloc_final_type
+#define _bfd_elf_hppa_gen_reloc_type _bfd_elf32_hppa_gen_reloc_type
+#define elf_hppa_relocate_section elf32_hppa_relocate_section
+#define elf_hppa_final_link elf32_hppa_final_link
+#endif
+
+/* 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,
+ bfd_elf_generic_reloc, "R_PARISC_NONE", FALSE, 0, 0, FALSE },
+
+ /* 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,
+ bfd_elf_generic_reloc, "R_PARISC_DIR32", FALSE, 0, 0xffffffff, FALSE },
+ { R_PARISC_DIR21L, 0, 2, 21, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_DIR21L", FALSE, 0, 0, FALSE },
+ { R_PARISC_DIR17R, 0, 2, 17, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_DIR17R", FALSE, 0, 0, FALSE },
+ { R_PARISC_DIR17F, 0, 2, 17, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_DIR17F", FALSE, 0, 0, FALSE },
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ { R_PARISC_DIR14R, 0, 2, 14, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_DIR14R", FALSE, 0, 0, FALSE },
+ { R_PARISC_DIR14F, 0, 2, 14, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_DIR14F", FALSE, 0, 0, FALSE },
+ /* 8 */
+ { R_PARISC_PCREL12F, 0, 2, 12, TRUE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_PCREL12F", FALSE, 0, 0, FALSE },
+ { R_PARISC_PCREL32, 0, 2, 32, TRUE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_PCREL32", FALSE, 0, 0, FALSE },
+ { R_PARISC_PCREL21L, 0, 2, 21, TRUE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_PCREL21L", FALSE, 0, 0, FALSE },
+ { R_PARISC_PCREL17R, 0, 2, 17, TRUE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_PCREL17R", FALSE, 0, 0, FALSE },
+ { R_PARISC_PCREL17F, 0, 2, 17, TRUE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_PCREL17F", FALSE, 0, 0, FALSE },
+ { R_PARISC_PCREL17C, 0, 2, 17, TRUE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_PCREL17C", FALSE, 0, 0, FALSE },
+ { R_PARISC_PCREL14R, 0, 2, 14, TRUE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_PCREL14R", FALSE, 0, 0, FALSE },
+ { R_PARISC_PCREL14F, 0, 2, 14, TRUE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_PCREL14F", FALSE, 0, 0, FALSE },
+ /* 16 */
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ { R_PARISC_DPREL21L, 0, 2, 21, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_DPREL21L", FALSE, 0, 0, FALSE },
+ { R_PARISC_DPREL14WR, 0, 2, 14, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_DPREL14WR", FALSE, 0, 0, FALSE },
+ { R_PARISC_DPREL14DR, 0, 2, 14, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_DPREL14DR", FALSE, 0, 0, FALSE },
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ { R_PARISC_DPREL14R, 0, 2, 14, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_DPREL14R", FALSE, 0, 0, FALSE },
+ { R_PARISC_DPREL14F, 0, 2, 14, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_DPREL14F", FALSE, 0, 0, FALSE },
+ /* 24 */
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ { R_PARISC_DLTREL21L, 0, 2, 21, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_DLTREL21L", FALSE, 0, 0, FALSE },
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ { R_PARISC_DLTREL14R, 0, 2, 14, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_DLTREL14R", FALSE, 0, 0, FALSE },
+ { R_PARISC_DLTREL14F, 0, 2, 14, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_DLTREL14F", FALSE, 0, 0, FALSE },
+ /* 32 */
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ { R_PARISC_DLTIND21L, 0, 2, 21, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_DLTIND21L", FALSE, 0, 0, FALSE },
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ { R_PARISC_DLTIND14R, 0, 2, 14, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_DLTIND14R", FALSE, 0, 0, FALSE },
+ { R_PARISC_DLTIND14F, 0, 2, 14, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_DLTIND14F", FALSE, 0, 0, FALSE },
+ /* 40 */
+ { R_PARISC_SETBASE, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_SETBASE", FALSE, 0, 0, FALSE },
+ { R_PARISC_SECREL32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_SECREL32", FALSE, 0, 0xffffffff, FALSE },
+ { R_PARISC_BASEREL21L, 0, 2, 21, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_BASEREL21L", FALSE, 0, 0, FALSE },
+ { R_PARISC_BASEREL17R, 0, 2, 17, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_BASEREL17R", FALSE, 0, 0, FALSE },
+ { R_PARISC_BASEREL17F, 0, 2, 17, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_BASEREL17F", FALSE, 0, 0, FALSE },
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ { R_PARISC_BASEREL14R, 0, 2, 14, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_BASEREL14R", FALSE, 0, 0, FALSE },
+ { R_PARISC_BASEREL14F, 0, 2, 14, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_BASEREL14F", FALSE, 0, 0, FALSE },
+ /* 48 */
+ { R_PARISC_SEGBASE, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_SEGBASE", FALSE, 0, 0, FALSE },
+ { R_PARISC_SEGREL32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_SEGREL32", FALSE, 0, 0, FALSE },
+ { R_PARISC_PLTOFF21L, 0, 2, 21, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_PLTOFF21L", FALSE, 0, 0, FALSE },
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ { R_PARISC_PLTOFF14R, 0, 2, 14, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_PLTOFF14R", FALSE, 0, 0, FALSE },
+ { R_PARISC_PLTOFF14F, 0, 2, 14, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_PLTOFF14F", FALSE, 0, 0, FALSE },
+ /* 56 */
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ { R_PARISC_LTOFF_FPTR32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_LTOFF_FPTR32", FALSE, 0, 0, FALSE },
+ { R_PARISC_LTOFF_FPTR21L, 0, 2, 21, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_LTOFF_FPTR21L", FALSE, 0, 0, FALSE },
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ { R_PARISC_LTOFF_FPTR14R, 0, 2, 14, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_LTOFF_FPTR14R", FALSE, 0, 0, FALSE },
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ /* 64 */
+ { R_PARISC_FPTR64, 0, 4, 64, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_FPTR64", FALSE, 0, 0, FALSE },
+ { R_PARISC_PLABEL32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_PLABEL32", FALSE, 0, 0, FALSE },
+ { R_PARISC_PLABEL21L, 0, 2, 21, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_PLABEL21L", FALSE, 0, 0, FALSE },
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ { R_PARISC_PLABEL14R, 0, 2, 14, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_PLABEL14R", FALSE, 0, 0, FALSE },
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ /* 72 */
+ { R_PARISC_PCREL64, 0, 4, 64, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_PCREL64", FALSE, 0, 0, FALSE },
+ { R_PARISC_PCREL22C, 0, 2, 22, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_PCREL22C", FALSE, 0, 0, FALSE },
+ { R_PARISC_PCREL22F, 0, 2, 22, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_PCREL22F", FALSE, 0, 0, FALSE },
+ { R_PARISC_PCREL14WR, 0, 2, 14, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_PCREL14WR", FALSE, 0, 0, FALSE },
+ { R_PARISC_PCREL14DR, 0, 2, 14, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_PCREL14DR", FALSE, 0, 0, FALSE },
+ { R_PARISC_PCREL16F, 0, 2, 16, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_PCREL16F", FALSE, 0, 0, FALSE },
+ { R_PARISC_PCREL16WF, 0, 2, 16, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_PCREL16WF", FALSE, 0, 0, FALSE },
+ { R_PARISC_PCREL16DF, 0, 2, 16, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_PCREL16DF", FALSE, 0, 0, FALSE },
+ /* 80 */
+ { R_PARISC_DIR64, 0, 4, 64, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_DIR64", FALSE, 0, 0, FALSE },
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ { R_PARISC_DIR14WR, 0, 2, 14, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_DIR14WR", FALSE, 0, 0, FALSE },
+ { R_PARISC_DIR14DR, 0, 2, 14, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_DIR14DR", FALSE, 0, 0, FALSE },
+ { R_PARISC_DIR16F, 0, 2, 16, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_DIR16F", FALSE, 0, 0, FALSE },
+ { R_PARISC_DIR16WF, 0, 2, 16, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_DIR16WF", FALSE, 0, 0, FALSE },
+ { R_PARISC_DIR16DF, 0, 2, 16, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_DIR16DF", FALSE, 0, 0, FALSE },
+ /* 88 */
+ { R_PARISC_GPREL64, 0, 4, 64, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_GPREL64", FALSE, 0, 0, FALSE },
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ { R_PARISC_DLTREL14WR, 0, 2, 14, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_DLTREL14WR", FALSE, 0, 0, FALSE },
+ { R_PARISC_DLTREL14DR, 0, 2, 14, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_DLTREL14DR", FALSE, 0, 0, FALSE },
+ { R_PARISC_GPREL16F, 0, 2, 16, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_GPREL16F", FALSE, 0, 0, FALSE },
+ { R_PARISC_GPREL16WF, 0, 2, 16, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_GPREL16WF", FALSE, 0, 0, FALSE },
+ { R_PARISC_GPREL16DF, 0, 2, 16, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_GPREL16DF", FALSE, 0, 0, FALSE },
+ /* 96 */
+ { R_PARISC_LTOFF64, 0, 4, 64, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_LTOFF64", FALSE, 0, 0, FALSE },
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ { R_PARISC_DLTIND14WR, 0, 2, 14, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_DLTIND14WR", FALSE, 0, 0, FALSE },
+ { R_PARISC_DLTIND14DR, 0, 2, 14, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_DLTIND14DR", FALSE, 0, 0, FALSE },
+ { R_PARISC_LTOFF16F, 0, 2, 16, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_LTOFF16F", FALSE, 0, 0, FALSE },
+ { R_PARISC_LTOFF16WF, 0, 2, 16, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_LTOFF16DF", FALSE, 0, 0, FALSE },
+ { R_PARISC_LTOFF16DF, 0, 2, 16, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_LTOFF16DF", FALSE, 0, 0, FALSE },
+ /* 104 */
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ { R_PARISC_BASEREL14WR, 0, 2, 14, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_BASEREL14WR", FALSE, 0, 0, FALSE },
+ { R_PARISC_BASEREL14DR, 0, 2, 14, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_BASEREL14DR", FALSE, 0, 0, FALSE },
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ /* 112 */
+ { R_PARISC_SEGREL64, 0, 4, 64, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_SEGREL64", FALSE, 0, 0, FALSE },
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ { R_PARISC_PLTOFF14WR, 0, 2, 14, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_PLTOFF14WR", FALSE, 0, 0, FALSE },
+ { R_PARISC_PLTOFF14DR, 0, 2, 14, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_PLTOFF14DR", FALSE, 0, 0, FALSE },
+ { R_PARISC_PLTOFF16F, 0, 2, 16, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_PLTOFF16F", FALSE, 0, 0, FALSE },
+ { R_PARISC_PLTOFF16WF, 0, 2, 16, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_PLTOFF16WF", FALSE, 0, 0, FALSE },
+ { R_PARISC_PLTOFF16DF, 0, 2, 16, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_PLTOFF16DF", FALSE, 0, 0, FALSE },
+ /* 120 */
+ { R_PARISC_LTOFF_FPTR64, 0, 4, 64, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ { R_PARISC_LTOFF_FPTR14WR, 0, 2, 14, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_LTOFF_FPTR14WR", FALSE, 0, 0, FALSE },
+ { R_PARISC_LTOFF_FPTR14DR, 0, 2, 14, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_LTOFF_FPTR14DR", FALSE, 0, 0, FALSE },
+ { R_PARISC_LTOFF_FPTR16F, 0, 2, 16, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_LTOFF_FPTR16F", FALSE, 0, 0, FALSE },
+ { R_PARISC_LTOFF_FPTR16WF, 0, 2, 16, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_LTOFF_FPTR16WF", FALSE, 0, 0, FALSE },
+ { R_PARISC_LTOFF_FPTR16DF, 0, 2, 16, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ /* 128 */
+ { R_PARISC_COPY, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_COPY", FALSE, 0, 0, FALSE },
+ { R_PARISC_IPLT, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_IPLT", FALSE, 0, 0, FALSE },
+ { R_PARISC_EPLT, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_EPLT", FALSE, 0, 0, FALSE },
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ /* 136 */
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_dont,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_dont,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ /* 144 */
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_dont,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_dont,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_dont,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ /* 152 */
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_dont,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ { R_PARISC_TPREL32, 0, 2, 32, FALSE, 0, complain_overflow_dont,
+ bfd_elf_generic_reloc, "R_PARISC_TPREL32", FALSE, 0, 0, FALSE },
+ { R_PARISC_TPREL21L, 0, 2, 21, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_TPREL21L", FALSE, 0, 0, FALSE },
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_dont,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_dont,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_dont,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ { R_PARISC_TPREL14R, 0, 2, 14, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_TPREL14R", FALSE, 0, 0, FALSE },
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_dont,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ /* 160 */
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_dont,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_dont,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ { R_PARISC_LTOFF_TP21L, 0, 2, 21, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_LTOFF_TP21L", FALSE, 0, 0, FALSE },
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_dont,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ { R_PARISC_LTOFF_TP14R, 0, 2, 14, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_LTOFF_TP14R", FALSE, 0, 0, FALSE },
+ { R_PARISC_LTOFF_TP14F, 0, 2, 14, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_LTOFF_TP14F", FALSE, 0, 0, FALSE },
+ /* 168 */
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_dont,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ /* 176 */
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_dont,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_dont,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ /* 184 */
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_dont,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_dont,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ /* 192 */
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_dont,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ /* 200 */
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_dont,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ /* 208 */
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_dont,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_dont,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ /* 216 */
+ { R_PARISC_TPREL64, 0, 4, 64, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_TPREL64", FALSE, 0, 0, FALSE },
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ { R_PARISC_TPREL14WR, 0, 2, 14, FALSE, 0, complain_overflow_dont,
+ bfd_elf_generic_reloc, "R_PARISC_TPREL14WR", FALSE, 0, 0, FALSE },
+ { R_PARISC_TPREL14DR, 0, 2, 14, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_TPREL14DR", FALSE, 0, 0, FALSE },
+ { R_PARISC_TPREL16F, 0, 2, 16, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_TPREL16F", FALSE, 0, 0, FALSE },
+ { R_PARISC_TPREL16WF, 0, 2, 16, FALSE, 0, complain_overflow_dont,
+ bfd_elf_generic_reloc, "R_PARISC_TPREL16WF", FALSE, 0, 0, FALSE },
+ { R_PARISC_TPREL16DF, 0, 2, 16, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_TPREL16DF", FALSE, 0, 0, FALSE },
+ /* 224 */
+ { R_PARISC_LTOFF_TP64, 0, 4, 64, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_LTOFF_TP64", FALSE, 0, 0, FALSE },
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ { R_PARISC_UNIMPLEMENTED, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", FALSE, 0, 0, FALSE },
+ { R_PARISC_LTOFF_TP14WR, 0, 2, 14, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_LTOFF_TP14WR", FALSE, 0, 0, FALSE },
+ { R_PARISC_LTOFF_TP14DR, 0, 2, 14, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_LTOFF_TP14DR", FALSE, 0, 0, FALSE },
+ { R_PARISC_LTOFF_TP16F, 0, 2, 16, FALSE, 0, complain_overflow_dont,
+ bfd_elf_generic_reloc, "R_PARISC_LTOFF_TP16F", FALSE, 0, 0, FALSE },
+ { R_PARISC_LTOFF_TP16WF, 0, 2, 16, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_LTOFF_TP16WF", FALSE, 0, 0, FALSE },
+ { R_PARISC_LTOFF_TP16DF, 0, 2, 16, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_LTOFF_TP16DF", FALSE, 0, 0, FALSE },
+ /* 232 */
+ { R_PARISC_GNU_VTENTRY, 0, 0, 0, FALSE, 0, complain_overflow_dont,
+ bfd_elf_generic_reloc, "R_PARISC_GNU_VTENTRY", FALSE, 0, 0, FALSE },
+ { R_PARISC_GNU_VTINHERIT, 0, 0, 0, FALSE, 0, complain_overflow_dont,
+ bfd_elf_generic_reloc, "R_PARISC_GNU_VTINHERIT", FALSE, 0, 0, FALSE },
+ { R_PARISC_TLS_GD21L, 0, 2, 21, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_TLS_GD21L", FALSE, 0, 0, FALSE },
+ { R_PARISC_TLS_GD14R, 0, 2, 14, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_TLS_GD14R", FALSE, 0, 0, FALSE },
+ { R_PARISC_TLS_GDCALL, 0, 0, 0, FALSE, 0, complain_overflow_dont,
+ bfd_elf_generic_reloc, "R_PARISC_TLS_GDCALL", FALSE, 0, 0, FALSE },
+ { R_PARISC_TLS_LDM21L, 0, 2, 21, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_TLS_LDM21L", FALSE, 0, 0, FALSE },
+ { R_PARISC_TLS_LDM14R, 0, 2, 14, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_TLS_LDM14R", FALSE, 0, 0, FALSE },
+ { R_PARISC_TLS_LDMCALL, 0, 0, 0, FALSE, 0, complain_overflow_dont,
+ bfd_elf_generic_reloc, "R_PARISC_TLS_LDMCALL", FALSE, 0, 0, FALSE },
+ /* 240 */
+ { R_PARISC_TLS_LDO21L, 0, 2, 21, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_TLS_LDO21L", FALSE, 0, 0, FALSE },
+ { R_PARISC_TLS_LDO14R, 0, 2, 14, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_TLS_LDO14R", FALSE, 0, 0, FALSE },
+ { R_PARISC_TLS_DTPMOD32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_TLS_DTPMOD32", FALSE, 0, 0, FALSE },
+ { R_PARISC_TLS_DTPMOD64, 0, 4, 64, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_TLS_DTPMOD64", FALSE, 0, 0, FALSE },
+ { R_PARISC_TLS_DTPOFF32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_TLS_DTPOFF32", FALSE, 0, 0, FALSE },
+ { R_PARISC_TLS_DTPOFF64, 0, 4, 64, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_PARISC_TLS_DTPOFF64", FALSE, 0, 0, FALSE },
+};
+
+#define OFFSET_14R_FROM_21L 4
+#define OFFSET_14F_FROM_21L 5
+
+/* Return the final relocation type for the given base type, instruction
+ format, and field selector. */
+
+elf_hppa_reloc_type
+elf_hppa_reloc_final_type (bfd *abfd,
+ elf_hppa_reloc_type base_type,
+ int format,
+ unsigned int field)
+{
+ elf_hppa_reloc_type 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)
+ {
+ /* We have been using generic relocation types. However, that may not
+ really make sense. Anyway, we need to support both R_PARISC_DIR64
+ and R_PARISC_DIR32 here. */
+ case R_PARISC_DIR32:
+ case R_PARISC_DIR64:
+ case R_HPPA_ABS_CALL:
+ switch (format)
+ {
+ case 14:
+ switch (field)
+ {
+ case e_fsel:
+ final_type = R_PARISC_DIR14F;
+ break;
+ case e_rsel:
+ case e_rrsel:
+ case e_rdsel:
+ final_type = R_PARISC_DIR14R;
+ break;
+ case e_rtsel:
+ final_type = R_PARISC_DLTIND14R;
+ break;
+ case e_rtpsel:
+ final_type = R_PARISC_LTOFF_FPTR14DR;
+ break;
+ case e_tsel:
+ final_type = R_PARISC_DLTIND14F;
+ break;
+ case e_rpsel:
+ final_type = R_PARISC_PLABEL14R;
+ break;
+ default:
+ return R_PARISC_NONE;
+ }
+ break;
+
+ case 17:
+ switch (field)
+ {
+ case e_fsel:
+ final_type = R_PARISC_DIR17F;
+ break;
+ case e_rsel:
+ case e_rrsel:
+ case e_rdsel:
+ final_type = R_PARISC_DIR17R;
+ break;
+ default:
+ return R_PARISC_NONE;
+ }
+ break;
+
+ case 21:
+ switch (field)
+ {
+ case e_lsel:
+ case e_lrsel:
+ case e_ldsel:
+ case e_nlsel:
+ case e_nlrsel:
+ final_type = R_PARISC_DIR21L;
+ break;
+ case e_ltsel:
+ final_type = R_PARISC_DLTIND21L;
+ break;
+ case e_ltpsel:
+ final_type = R_PARISC_LTOFF_FPTR21L;
+ break;
+ case e_lpsel:
+ final_type = R_PARISC_PLABEL21L;
+ break;
+ default:
+ return R_PARISC_NONE;
+ }
+ break;
+
+ case 32:
+ switch (field)
+ {
+ case e_fsel:
+ final_type = R_PARISC_DIR32;
+ /* When in 64bit mode, a 32bit relocation is supposed to
+ be a section relative relocation. Dwarf2 (for example)
+ uses 32bit section relative relocations. */
+ if (bfd_arch_bits_per_address (abfd) != 32)
+ final_type = R_PARISC_SECREL32;
+ break;
+ case e_psel:
+ final_type = R_PARISC_PLABEL32;
+ break;
+ default:
+ return R_PARISC_NONE;
+ }
+ break;
+
+ case 64:
+ switch (field)
+ {
+ case e_fsel:
+ final_type = R_PARISC_DIR64;
+ break;
+ case e_psel:
+ final_type = R_PARISC_FPTR64;
+ break;
+ default:
+ return R_PARISC_NONE;
+ }
+ break;
+
+ default:
+ return R_PARISC_NONE;
+ }
+ break;
+
+ case R_HPPA_GOTOFF:
+ switch (format)
+ {
+ case 14:
+ switch (field)
+ {
+ case e_rsel:
+ case e_rrsel:
+ case e_rdsel:
+ /* R_PARISC_DLTREL14R for elf64, R_PARISC_DPREL14R for elf32. */
+ final_type = base_type + OFFSET_14R_FROM_21L;
+ break;
+ case e_fsel:
+ /* R_PARISC_DLTREL14F for elf64, R_PARISC_DPREL14F for elf32. */
+ final_type = base_type + OFFSET_14F_FROM_21L;
+ break;
+ default:
+ return R_PARISC_NONE;
+ }
+ break;
+
+ case 21:
+ switch (field)
+ {
+ case e_lsel:
+ case e_lrsel:
+ case e_ldsel:
+ case e_nlsel:
+ case e_nlrsel:
+ /* R_PARISC_DLTREL21L for elf64, R_PARISC_DPREL21L for elf32. */
+ final_type = base_type;
+ break;
+ default:
+ return R_PARISC_NONE;
+ }
+ break;
+
+ case 64:
+ switch (field)
+ {
+ case e_fsel:
+ final_type = R_PARISC_GPREL64;
+ break;
+ default:
+ return R_PARISC_NONE;
+ }
+ break;
+
+ default:
+ return R_PARISC_NONE;
+ }
+ break;
+
+ case R_HPPA_PCREL_CALL:
+ switch (format)
+ {
+ case 12:
+ switch (field)
+ {
+ case e_fsel:
+ final_type = R_PARISC_PCREL12F;
+ break;
+ default:
+ return R_PARISC_NONE;
+ }
+ break;
+
+ case 14:
+ /* Contrary to appearances, these are not calls of any sort.
+ Rather, they are loads/stores with a pcrel reloc. */
+ switch (field)
+ {
+ case e_rsel:
+ case e_rrsel:
+ case e_rdsel:
+ final_type = R_PARISC_PCREL14R;
+ break;
+ case e_fsel:
+ if (bfd_get_mach (abfd) < 25)
+ final_type = R_PARISC_PCREL14F;
+ else
+ final_type = R_PARISC_PCREL16F;
+ break;
+ default:
+ return R_PARISC_NONE;
+ }
+ break;
+
+ case 17:
+ switch (field)
+ {
+ case e_rsel:
+ case e_rrsel:
+ case e_rdsel:
+ final_type = R_PARISC_PCREL17R;
+ break;
+ case e_fsel:
+ final_type = R_PARISC_PCREL17F;
+ break;
+ default:
+ return R_PARISC_NONE;
+ }
+ break;
+
+ case 21:
+ switch (field)
+ {
+ case e_lsel:
+ case e_lrsel:
+ case e_ldsel:
+ case e_nlsel:
+ case e_nlrsel:
+ final_type = R_PARISC_PCREL21L;
+ break;
+ default:
+ return R_PARISC_NONE;
+ }
+ break;
+
+ case 22:
+ switch (field)
+ {
+ case e_fsel:
+ final_type = R_PARISC_PCREL22F;
+ break;
+ default:
+ return R_PARISC_NONE;
+ }
+ break;
+
+ case 32:
+ switch (field)
+ {
+ case e_fsel:
+ final_type = R_PARISC_PCREL32;
+ break;
+ default:
+ return R_PARISC_NONE;
+ }
+ break;
+
+ case 64:
+ switch (field)
+ {
+ case e_fsel:
+ final_type = R_PARISC_PCREL64;
+ break;
+ default:
+ return R_PARISC_NONE;
+ }
+ break;
+
+ default:
+ return R_PARISC_NONE;
+ }
+ break;
+
+ case R_PARISC_TLS_GD21L:
+ switch (field)
+ {
+ case e_ltsel:
+ case e_lrsel:
+ final_type = R_PARISC_TLS_GD21L;
+ break;
+ case e_rtsel:
+ case e_rrsel:
+ final_type = R_PARISC_TLS_GD14R;
+ break;
+ default:
+ return R_PARISC_NONE;
+ }
+ break;
+
+ case R_PARISC_TLS_LDM21L:
+ switch (field)
+ {
+ case e_ltsel:
+ case e_lrsel:
+ final_type = R_PARISC_TLS_LDM21L;
+ break;
+ case e_rtsel:
+ case e_rrsel:
+ final_type = R_PARISC_TLS_LDM14R;
+ break;
+ default:
+ return R_PARISC_NONE;
+ }
+ break;
+
+ case R_PARISC_TLS_LDO21L:
+ switch (field)
+ {
+ case e_lrsel:
+ final_type = R_PARISC_TLS_LDO21L;
+ break;
+ case e_rrsel:
+ final_type = R_PARISC_TLS_LDO14R;
+ break;
+ default:
+ return R_PARISC_NONE;
+ }
+ break;
+
+ case R_PARISC_TLS_IE21L:
+ switch (field)
+ {
+ case e_ltsel:
+ case e_lrsel:
+ final_type = R_PARISC_TLS_IE21L;
+ break;
+ case e_rtsel:
+ case e_rrsel:
+ final_type = R_PARISC_TLS_IE14R;
+ break;
+ default:
+ return R_PARISC_NONE;
+ }
+ break;
+
+ case R_PARISC_TLS_LE21L:
+ switch (field)
+ {
+ case e_lrsel:
+ final_type = R_PARISC_TLS_LE21L;
+ break;
+ case e_rrsel:
+ final_type = R_PARISC_TLS_LE14R;
+ break;
+ default:
+ return R_PARISC_NONE;
+ }
+ break;
+
+ case R_PARISC_SEGREL32:
+ switch (format)
+ {
+ case 32:
+ switch (field)
+ {
+ case e_fsel:
+ final_type = R_PARISC_SEGREL32;
+ break;
+ default:
+ return R_PARISC_NONE;
+ }
+ break;
+
+ case 64:
+ switch (field)
+ {
+ case e_fsel:
+ final_type = R_PARISC_SEGREL64;
+ break;
+ default:
+ return R_PARISC_NONE;
+ }
+ break;
+
+ default:
+ return R_PARISC_NONE;
+ }
+ break;
+
+ case R_PARISC_GNU_VTENTRY:
+ case R_PARISC_GNU_VTINHERIT:
+ case R_PARISC_SEGBASE:
+ /* The defaults are fine for these cases. */
+ break;
+
+ default:
+ return R_PARISC_NONE;
+ }
+
+ return final_type;
+}
+
+/* Return one (or more) BFD relocations which implement the base
+ relocation with modifications based on format and field. */
+
+elf_hppa_reloc_type **
+_bfd_elf_hppa_gen_reloc_type (bfd *abfd,
+ elf_hppa_reloc_type base_type,
+ int format,
+ unsigned int field,
+ int ignore ATTRIBUTE_UNUSED,
+ asymbol *sym ATTRIBUTE_UNUSED)
+{
+ elf_hppa_reloc_type *finaltype;
+ elf_hppa_reloc_type **final_types;
+ bfd_size_type amt = sizeof (elf_hppa_reloc_type *) * 2;
+
+ /* Allocate slots for the BFD relocation. */
+ final_types = bfd_alloc (abfd, amt);
+ if (final_types == NULL)
+ return NULL;
+
+ /* Allocate space for the relocation itself. */
+ amt = sizeof (elf_hppa_reloc_type);
+ finaltype = bfd_alloc (abfd, amt);
+ if (finaltype == NULL)
+ return NULL;
+
+ /* Some reasonable defaults. */
+ final_types[0] = finaltype;
+ final_types[1] = NULL;
+
+ *finaltype = elf_hppa_reloc_final_type (abfd, base_type, format, field);
+
+ return final_types;
+}
+
+/* Translate from an elf into field into a howto relocation pointer. */
+
+static void
+elf_hppa_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED,
+ arelent *bfd_reloc,
+ Elf_Internal_Rela *elf_reloc)
+{
+ BFD_ASSERT (ELF_R_TYPE (elf_reloc->r_info)
+ < (unsigned int) R_PARISC_UNIMPLEMENTED);
+ bfd_reloc->howto = &elf_hppa_howto_table[ELF_R_TYPE (elf_reloc->r_info)];
+}
+
+/* Translate from an elf into field into a howto relocation pointer. */
+
+static void
+elf_hppa_info_to_howto_rel (bfd *abfd ATTRIBUTE_UNUSED,
+ arelent *bfd_reloc,
+ Elf_Internal_Rela *elf_reloc)
+{
+ BFD_ASSERT (ELF_R_TYPE (elf_reloc->r_info)
+ < (unsigned int) R_PARISC_UNIMPLEMENTED);
+ bfd_reloc->howto = &elf_hppa_howto_table[ELF_R_TYPE (elf_reloc->r_info)];
+}
+
+/* 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 (bfd *abfd ATTRIBUTE_UNUSED,
+ 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;
+}
+
+static reloc_howto_type *
+elf_hppa_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ const char *r_name)
+{
+ unsigned int i;
+
+ for (i = 0;
+ i < sizeof (elf_hppa_howto_table) / sizeof (elf_hppa_howto_table[0]);
+ i++)
+ if (elf_hppa_howto_table[i].name != NULL
+ && strcasecmp (elf_hppa_howto_table[i].name, r_name) == 0)
+ return &elf_hppa_howto_table[i];
+
+ return NULL;
+}
+
+/* Return TRUE if SYM represents a local label symbol. */
+
+static bfd_boolean
+elf_hppa_is_local_label_name (bfd *abfd ATTRIBUTE_UNUSED, const char *name)
+{
+ if (name[0] == 'L' && name[1] == '$')
+ return TRUE;
+ return _bfd_elf_is_local_label_name (abfd, name);
+}
+
+/* Set the correct type for an ELF section. We do this by the
+ section name, which is a hack, but ought to work. */
+
+static bfd_boolean
+elf_hppa_fake_sections (bfd *abfd, Elf_Internal_Shdr *hdr, asection *sec)
+{
+ const char *name;
+
+ name = bfd_get_section_name (abfd, sec);
+
+ if (strcmp (name, ".PARISC.unwind") == 0)
+ {
+ int indx;
+ asection *asec;
+
+#if ARCH_SIZE == 64
+ hdr->sh_type = SHT_LOPROC + 1;
+#else
+ hdr->sh_type = 1;
+#endif
+ /* ?!? How are unwinds supposed to work for symbols in arbitrary
+ sections? Or what if we have multiple .text sections in a single
+ .o file? HP really messed up on this one.
+
+ Ugh. We can not use elf_section_data (sec)->this_idx at this
+ point because it is not initialized yet.
+
+ So we (gasp) recompute it here. Hopefully nobody ever changes the
+ way sections are numbered in elf.c! */
+ for (asec = abfd->sections, indx = 1; asec; asec = asec->next, indx++)
+ {
+ if (asec->name && strcmp (asec->name, ".text") == 0)
+ {
+ hdr->sh_info = indx;
+ break;
+ }
+ }
+
+ /* I have no idea if this is really necessary or what it means. */
+ hdr->sh_entsize = 4;
+ }
+ return TRUE;
+}
+
+static void
+elf_hppa_final_write_processing (bfd *abfd,
+ bfd_boolean linker ATTRIBUTE_UNUSED)
+{
+ int mach = bfd_get_mach (abfd);
+
+ elf_elfheader (abfd)->e_flags &= ~(EF_PARISC_ARCH | EF_PARISC_TRAPNIL
+ | EF_PARISC_EXT | EF_PARISC_LSB
+ | EF_PARISC_WIDE | EF_PARISC_NO_KABP
+ | EF_PARISC_LAZYSWAP);
+
+ if (mach == 10)
+ elf_elfheader (abfd)->e_flags |= EFA_PARISC_1_0;
+ else if (mach == 11)
+ elf_elfheader (abfd)->e_flags |= EFA_PARISC_1_1;
+ else if (mach == 20)
+ elf_elfheader (abfd)->e_flags |= EFA_PARISC_2_0;
+ else if (mach == 25)
+ elf_elfheader (abfd)->e_flags |= (EF_PARISC_WIDE
+ | EFA_PARISC_2_0
+ /* The GNU tools have trapped without
+ option since 1993, so need to take
+ a step backwards with the ELF
+ based toolchains. */
+ | EF_PARISC_TRAPNIL);
+}
+
+/* Comparison function for qsort to sort unwind section during a
+ final link. */
+
+static int
+hppa_unwind_entry_compare (const void *a, const void *b)
+{
+ const bfd_byte *ap, *bp;
+ unsigned long av, bv;
+
+ ap = a;
+ av = (unsigned long) ap[0] << 24;
+ av |= (unsigned long) ap[1] << 16;
+ av |= (unsigned long) ap[2] << 8;
+ av |= (unsigned long) ap[3];
+
+ bp = b;
+ bv = (unsigned long) bp[0] << 24;
+ bv |= (unsigned long) bp[1] << 16;
+ bv |= (unsigned long) bp[2] << 8;
+ bv |= (unsigned long) bp[3];
+
+ return av < bv ? -1 : av > bv ? 1 : 0;
+}
+
+static bfd_boolean
+elf_hppa_sort_unwind (bfd *abfd)
+{
+ asection *s;
+
+ /* Magic section names, but this is much safer than having
+ relocate_section remember where SEGREL32 relocs occurred.
+ Consider what happens if someone inept creates a linker script
+ that puts unwind information in .text. */
+ s = bfd_get_section_by_name (abfd, ".PARISC.unwind");
+ if (s != NULL)
+ {
+ bfd_size_type size;
+ bfd_byte *contents;
+
+ if (!bfd_malloc_and_get_section (abfd, s, &contents))
+ return FALSE;
+
+ size = s->size;
+ qsort (contents, (size_t) (size / 16), 16, hppa_unwind_entry_compare);
+
+ if (! bfd_set_section_contents (abfd, s, contents, (file_ptr) 0, size))
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/* What to do when ld finds relocations against symbols defined in
+ discarded sections. */
+
+static unsigned int
+elf_hppa_action_discarded (asection *sec)
+{
+ if (strcmp (".PARISC.unwind", sec->name) == 0)
+ return 0;
+
+ return _bfd_elf_default_action_discarded (sec);
+}
diff --git a/bfd/elf-ifunc.c b/bfd/elf-ifunc.c
new file mode 100644
index 0000000..f5ab47f
--- /dev/null
+++ b/bfd/elf-ifunc.c
@@ -0,0 +1,400 @@
+/* ELF STT_GNU_IFUNC support.
+ Copyright (C) 2009-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "bfdlink.h"
+#include "libbfd.h"
+#define ARCH_SIZE 0
+#include "elf-bfd.h"
+#include "safe-ctype.h"
+#include "libiberty.h"
+#include "objalloc.h"
+
+/* Create sections needed by STT_GNU_IFUNC symbol. */
+
+bfd_boolean
+_bfd_elf_create_ifunc_sections (bfd *abfd, struct bfd_link_info *info)
+{
+ flagword flags, pltflags;
+ asection *s;
+ const struct elf_backend_data *bed = get_elf_backend_data (abfd);
+ struct elf_link_hash_table *htab = elf_hash_table (info);
+
+ if (htab->irelifunc != NULL || htab->iplt != NULL)
+ return TRUE;
+
+ flags = bed->dynamic_sec_flags;
+ pltflags = flags;
+ if (bed->plt_not_loaded)
+ /* We do not clear SEC_ALLOC here because we still want the OS to
+ allocate space for the section; it's just that there's nothing
+ to read in from the object file. */
+ pltflags &= ~ (SEC_CODE | SEC_LOAD | SEC_HAS_CONTENTS);
+ else
+ pltflags |= SEC_ALLOC | SEC_CODE | SEC_LOAD;
+ if (bed->plt_readonly)
+ pltflags |= SEC_READONLY;
+
+ if (info->shared)
+ {
+ /* We need to create .rel[a].ifunc for shared objects. */
+ const char *rel_sec = (bed->rela_plts_and_copies_p
+ ? ".rela.ifunc" : ".rel.ifunc");
+
+ s = bfd_make_section_with_flags (abfd, rel_sec,
+ flags | SEC_READONLY);
+ if (s == NULL
+ || ! bfd_set_section_alignment (abfd, s,
+ bed->s->log_file_align))
+ return FALSE;
+ htab->irelifunc = s;
+ }
+ else
+ {
+ /* We need to create .iplt, .rel[a].iplt, .igot and .igot.plt
+ for static executables. */
+ s = bfd_make_section_with_flags (abfd, ".iplt", pltflags);
+ if (s == NULL
+ || ! bfd_set_section_alignment (abfd, s, bed->plt_alignment))
+ return FALSE;
+ htab->iplt = s;
+
+ s = bfd_make_section_with_flags (abfd,
+ (bed->rela_plts_and_copies_p
+ ? ".rela.iplt" : ".rel.iplt"),
+ flags | SEC_READONLY);
+ if (s == NULL
+ || ! bfd_set_section_alignment (abfd, s,
+ bed->s->log_file_align))
+ return FALSE;
+ htab->irelplt = s;
+
+ /* We don't need the .igot section if we have the .igot.plt
+ section. */
+ if (bed->want_got_plt)
+ s = bfd_make_section_with_flags (abfd, ".igot.plt", flags);
+ else
+ s = bfd_make_section_with_flags (abfd, ".igot", flags);
+ if (s == NULL
+ || !bfd_set_section_alignment (abfd, s,
+ bed->s->log_file_align))
+ return FALSE;
+ htab->igotplt = s;
+ }
+
+ return TRUE;
+}
+
+/* Allocate space in .plt, .got and associated reloc sections for
+ dynamic relocs against a STT_GNU_IFUNC symbol definition. */
+
+bfd_boolean
+_bfd_elf_allocate_ifunc_dyn_relocs (struct bfd_link_info *info,
+ struct elf_link_hash_entry *h,
+ struct elf_dyn_relocs **head,
+ unsigned int plt_entry_size,
+ unsigned int plt_header_size,
+ unsigned int got_entry_size)
+{
+ asection *plt, *gotplt, *relplt;
+ struct elf_dyn_relocs *p;
+ unsigned int sizeof_reloc;
+ const struct elf_backend_data *bed;
+ struct elf_link_hash_table *htab;
+
+ /* When a shared library references a STT_GNU_IFUNC symbol defined
+ in executable, the address of the resolved function may be used.
+ But in non-shared executable, the address of its .plt slot may
+ be used. Pointer equality may not work correctly. PIE should
+ be used if pointer equality is required here. */
+ if (!info->shared
+ && (h->dynindx != -1
+ || info->export_dynamic)
+ && h->pointer_equality_needed)
+ {
+ info->callbacks->einfo
+ (_("%F%P: dynamic STT_GNU_IFUNC symbol `%s' with pointer "
+ "equality in `%B' can not be used when making an "
+ "executable; recompile with -fPIE and relink with -pie\n"),
+ h->root.root.string,
+ h->root.u.def.section->owner);
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+
+ htab = elf_hash_table (info);
+
+ /* When building shared library, we need to handle the case where it is
+ marked with regular reference, but not non-GOT reference since the
+ non-GOT reference bit may not be set here. */
+ if (info->shared && !h->non_got_ref && h->ref_regular)
+ for (p = *head; p != NULL; p = p->next)
+ if (p->count)
+ {
+ h->non_got_ref = 1;
+ goto keep;
+ }
+
+ /* Support garbage collection against STT_GNU_IFUNC symbols. */
+ if (h->plt.refcount <= 0 && h->got.refcount <= 0)
+ {
+ h->got = htab->init_got_offset;
+ h->plt = htab->init_plt_offset;
+ *head = NULL;
+ return TRUE;
+ }
+
+ /* Return and discard space for dynamic relocations against it if
+ it is never referenced in a non-shared object. */
+ if (!h->ref_regular)
+ {
+ if (h->plt.refcount > 0
+ || h->got.refcount > 0)
+ abort ();
+ h->got = htab->init_got_offset;
+ h->plt = htab->init_plt_offset;
+ *head = NULL;
+ return TRUE;
+ }
+
+keep:
+ bed = get_elf_backend_data (info->output_bfd);
+ if (bed->rela_plts_and_copies_p)
+ sizeof_reloc = bed->s->sizeof_rela;
+ else
+ sizeof_reloc = bed->s->sizeof_rel;
+
+ /* When building a static executable, use .iplt, .igot.plt and
+ .rel[a].iplt sections for STT_GNU_IFUNC symbols. */
+ if (htab->splt != NULL)
+ {
+ plt = htab->splt;
+ gotplt = htab->sgotplt;
+ relplt = htab->srelplt;
+
+ /* If this is the first .plt entry, make room for the special
+ first entry. */
+ if (plt->size == 0)
+ plt->size += plt_header_size;
+ }
+ else
+ {
+ plt = htab->iplt;
+ gotplt = htab->igotplt;
+ relplt = htab->irelplt;
+ }
+
+ /* Don't update value of STT_GNU_IFUNC symbol to PLT. We need
+ the original value for R_*_IRELATIVE. */
+ h->plt.offset = plt->size;
+
+ /* Make room for this entry in the .plt/.iplt section. */
+ plt->size += plt_entry_size;
+
+ /* We also need to make an entry in the .got.plt/.got.iplt section,
+ which will be placed in the .got section by the linker script. */
+ gotplt->size += got_entry_size;
+
+ /* We also need to make an entry in the .rel[a].plt/.rel[a].iplt
+ section. */
+ relplt->size += sizeof_reloc;
+ relplt->reloc_count++;
+
+ /* We need dynamic relocation for STT_GNU_IFUNC symbol only when
+ there is a non-GOT reference in a shared object. */
+ if (!info->shared
+ || !h->non_got_ref)
+ *head = NULL;
+
+ /* Finally, allocate space. */
+ p = *head;
+ if (p != NULL)
+ {
+ bfd_size_type count = 0;
+ do
+ {
+ count += p->count;
+ p = p->next;
+ }
+ while (p != NULL);
+ htab->irelifunc->size += count * sizeof_reloc;
+ }
+
+ /* For STT_GNU_IFUNC symbol, .got.plt has the real function address
+ and .got has the PLT entry adddress. We will load the GOT entry
+ with the PLT entry in finish_dynamic_symbol if it is used. For
+ branch, it uses .got.plt. For symbol value,
+ 1. Use .got.plt in a shared object if it is forced local or not
+ dynamic.
+ 2. Use .got.plt in a non-shared object if pointer equality isn't
+ needed.
+ 3. Use .got.plt in PIE.
+ 4. Use .got.plt if .got isn't used.
+ 5. Otherwise use .got so that it can be shared among different
+ objects at run-time.
+ We only need to relocate .got entry in shared object. */
+ if (h->got.refcount <= 0
+ || (info->shared
+ && (h->dynindx == -1
+ || h->forced_local))
+ || (!info->shared
+ && !h->pointer_equality_needed)
+ || (info->executable && info->shared)
+ || htab->sgot == NULL)
+ {
+ /* Use .got.plt. */
+ h->got.offset = (bfd_vma) -1;
+ }
+ else
+ {
+ h->got.offset = htab->sgot->size;
+ htab->sgot->size += got_entry_size;
+ if (info->shared)
+ htab->srelgot->size += sizeof_reloc;
+ }
+
+ return TRUE;
+}
+
+/* Similar to _bfd_elf_get_synthetic_symtab, optimized for unsorted PLT
+ entries. PLT is the PLT section. PLT_SYM_VAL is a function pointer
+ which returns an array of PLT entry symbol values. */
+
+long
+_bfd_elf_ifunc_get_synthetic_symtab
+ (bfd *abfd, long symcount ATTRIBUTE_UNUSED,
+ asymbol **syms ATTRIBUTE_UNUSED, long dynsymcount, asymbol **dynsyms,
+ asymbol **ret, asection *plt,
+ bfd_vma *(*get_plt_sym_val) (bfd *, asymbol **, asection *, asection *))
+{
+ const struct elf_backend_data *bed = get_elf_backend_data (abfd);
+ asection *relplt;
+ asymbol *s;
+ const char *relplt_name;
+ bfd_boolean (*slurp_relocs) (bfd *, asection *, asymbol **, bfd_boolean);
+ arelent *p;
+ long count, i, n;
+ size_t size;
+ Elf_Internal_Shdr *hdr;
+ char *names;
+ bfd_vma *plt_sym_val;
+
+ *ret = NULL;
+
+ if (plt == NULL)
+ return 0;
+
+ if ((abfd->flags & (DYNAMIC | EXEC_P)) == 0)
+ return 0;
+
+ if (dynsymcount <= 0)
+ return 0;
+
+ relplt_name = bed->relplt_name;
+ if (relplt_name == NULL)
+ relplt_name = bed->rela_plts_and_copies_p ? ".rela.plt" : ".rel.plt";
+ relplt = bfd_get_section_by_name (abfd, relplt_name);
+ if (relplt == NULL)
+ return 0;
+
+ hdr = &elf_section_data (relplt)->this_hdr;
+ if (hdr->sh_link != elf_dynsymtab (abfd)
+ || (hdr->sh_type != SHT_REL && hdr->sh_type != SHT_RELA))
+ return 0;
+
+ slurp_relocs = get_elf_backend_data (abfd)->s->slurp_reloc_table;
+ if (! (*slurp_relocs) (abfd, relplt, dynsyms, TRUE))
+ return -1;
+
+ count = relplt->size / hdr->sh_entsize;
+ size = count * sizeof (asymbol);
+ p = relplt->relocation;
+ for (i = 0; i < count; i++, p += bed->s->int_rels_per_ext_rel)
+ {
+ size += strlen ((*p->sym_ptr_ptr)->name) + sizeof ("@plt");
+ if (p->addend != 0)
+ {
+#ifdef BFD64
+ size += sizeof ("+0x") - 1 + 8 + 8 * (bed->s->elfclass == ELFCLASS64);
+#else
+ size += sizeof ("+0x") - 1 + 8;
+#endif
+ }
+ }
+
+ plt_sym_val = get_plt_sym_val (abfd, dynsyms, plt, relplt);
+ if (plt_sym_val == NULL)
+ return -1;
+
+ s = *ret = (asymbol *) bfd_malloc (size);
+ if (s == NULL)
+ {
+ free (plt_sym_val);
+ return -1;
+ }
+
+ names = (char *) (s + count);
+ p = relplt->relocation;
+ n = 0;
+ for (i = 0; i < count; i++, p += bed->s->int_rels_per_ext_rel)
+ {
+ size_t len;
+ bfd_vma addr;
+
+ addr = plt_sym_val[i];
+ if (addr == (bfd_vma) -1)
+ continue;
+
+ *s = **p->sym_ptr_ptr;
+ /* Undefined syms won't have BSF_LOCAL or BSF_GLOBAL set. Since
+ we are defining a symbol, ensure one of them is set. */
+ if ((s->flags & BSF_LOCAL) == 0)
+ s->flags |= BSF_GLOBAL;
+ s->flags |= BSF_SYNTHETIC;
+ s->section = plt;
+ s->value = addr - plt->vma;
+ s->name = names;
+ s->udata.p = NULL;
+ len = strlen ((*p->sym_ptr_ptr)->name);
+ memcpy (names, (*p->sym_ptr_ptr)->name, len);
+ names += len;
+ if (p->addend != 0)
+ {
+ char buf[30], *a;
+
+ memcpy (names, "+0x", sizeof ("+0x") - 1);
+ names += sizeof ("+0x") - 1;
+ bfd_sprintf_vma (abfd, buf, p->addend);
+ for (a = buf; *a == '0'; ++a)
+ ;
+ len = strlen (a);
+ memcpy (names, a, len);
+ names += len;
+ }
+ memcpy (names, "@plt", sizeof ("@plt"));
+ names += sizeof ("@plt");
+ ++s, ++n;
+ }
+
+ free (plt_sym_val);
+
+ return n;
+}
diff --git a/bfd/elf-linux-psinfo.h b/bfd/elf-linux-psinfo.h
new file mode 100644
index 0000000..5760cc7
--- /dev/null
+++ b/bfd/elf-linux-psinfo.h
@@ -0,0 +1,127 @@
+/* Definitions for PRPSINFO structures under ELF on GNU/Linux.
+ Copyright (C) 2013-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#ifndef ELF_LINUX_PSINFO_H
+#define ELF_LINUX_PSINFO_H
+
+/* The PRPSINFO structures defined below are used by most
+ architectures, although some of them define their own versions
+ (like e.g., PPC). */
+
+/* External 32-bit structure for PRPSINFO. This structure is
+ ABI-defined, thus we choose to use char arrays here in order to
+ avoid dealing with different types in different architectures.
+
+ This structure will ultimately be written in the corefile's note
+ section, as the PRPSINFO. */
+
+struct elf_external_linux_prpsinfo32
+ {
+ char pr_state; /* Numeric process state. */
+ char pr_sname; /* Char for pr_state. */
+ char pr_zomb; /* Zombie. */
+ char pr_nice; /* Nice val. */
+ char pr_flag[4]; /* Flags. */
+ char pr_uid[2];
+ char pr_gid[2];
+ char pr_pid[4];
+ char pr_ppid[4];
+ char pr_pgrp[4];
+ char pr_sid[4];
+ char pr_fname[16]; /* Filename of executable. */
+ char pr_psargs[80]; /* Initial part of arg list. */
+ };
+
+/* Helper macro to swap (properly handling endianess) things from the
+ `elf_internal_linux_prpsinfo' structure to the
+ `elf_external_linux_prpsinfo32' structure.
+
+ Note that FROM should be a pointer, and TO should be the explicit
+ type. */
+
+#define LINUX_PRPSINFO32_SWAP_FIELDS(abfd, from, to) \
+ do \
+ { \
+ H_PUT_8 (abfd, from->pr_state, &to.pr_state); \
+ H_PUT_8 (abfd, from->pr_sname, &to.pr_sname); \
+ H_PUT_8 (abfd, from->pr_zomb, &to.pr_zomb); \
+ H_PUT_8 (abfd, from->pr_nice, &to.pr_nice); \
+ H_PUT_32 (abfd, from->pr_flag, to.pr_flag); \
+ H_PUT_16 (abfd, from->pr_uid, to.pr_uid); \
+ H_PUT_16 (abfd, from->pr_gid, to.pr_gid); \
+ H_PUT_32 (abfd, from->pr_pid, to.pr_pid); \
+ H_PUT_32 (abfd, from->pr_ppid, to.pr_ppid); \
+ H_PUT_32 (abfd, from->pr_pgrp, to.pr_pgrp); \
+ H_PUT_32 (abfd, from->pr_sid, to.pr_sid); \
+ strncpy (to.pr_fname, from->pr_fname, sizeof (to.pr_fname)); \
+ strncpy (to.pr_psargs, from->pr_psargs, sizeof (to.pr_psargs)); \
+ } while (0)
+
+/* External 64-bit structure for PRPSINFO. This structure is
+ ABI-defined, thus we choose to use char arrays here in order to
+ avoid dealing with different types in different architectures.
+
+ This structure will ultimately be written in the corefile's note
+ section, as the PRPSINFO. */
+
+struct elf_external_linux_prpsinfo64
+ {
+ char pr_state; /* Numeric process state. */
+ char pr_sname; /* Char for pr_state. */
+ char pr_zomb; /* Zombie. */
+ char pr_nice; /* Nice val. */
+ char pr_flag[8]; /* Flags. */
+ char gap[4];
+ char pr_uid[4];
+ char pr_gid[4];
+ char pr_pid[4];
+ char pr_ppid[4];
+ char pr_pgrp[4];
+ char pr_sid[4];
+ char pr_fname[16]; /* Filename of executable. */
+ char pr_psargs[80]; /* Initial part of arg list. */
+ };
+
+/* Helper macro to swap (properly handling endianess) things from the
+ `elf_internal_linux_prpsinfo' structure to the
+ `elf_external_linux_prpsinfo64' structure.
+
+ Note that FROM should be a pointer, and TO should be the explicit
+ type. */
+
+#define LINUX_PRPSINFO64_SWAP_FIELDS(abfd, from, to) \
+ do \
+ { \
+ H_PUT_8 (abfd, from->pr_state, &to.pr_state); \
+ H_PUT_8 (abfd, from->pr_sname, &to.pr_sname); \
+ H_PUT_8 (abfd, from->pr_zomb, &to.pr_zomb); \
+ H_PUT_8 (abfd, from->pr_nice, &to.pr_nice); \
+ H_PUT_64 (abfd, from->pr_flag, to.pr_flag); \
+ H_PUT_32 (abfd, from->pr_uid, to.pr_uid); \
+ H_PUT_32 (abfd, from->pr_gid, to.pr_gid); \
+ H_PUT_32 (abfd, from->pr_pid, to.pr_pid); \
+ H_PUT_32 (abfd, from->pr_ppid, to.pr_ppid); \
+ H_PUT_32 (abfd, from->pr_pgrp, to.pr_pgrp); \
+ H_PUT_32 (abfd, from->pr_sid, to.pr_sid); \
+ strncpy (to.pr_fname, from->pr_fname, sizeof (to.pr_fname)); \
+ strncpy (to.pr_psargs, from->pr_psargs, sizeof (to.pr_psargs)); \
+ } while (0)
+
+#endif
diff --git a/bfd/elf-m10200.c b/bfd/elf-m10200.c
new file mode 100644
index 0000000..86872b7
--- /dev/null
+++ b/bfd/elf-m10200.c
@@ -0,0 +1,1394 @@
+/* Matsushita 10200 specific support for 32-bit ELF
+ Copyright (C) 1996-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+#include "elf-bfd.h"
+
+static bfd_boolean
+mn10200_elf_relax_delete_bytes (bfd *, asection *, bfd_vma, int);
+static bfd_boolean
+mn10200_elf_symbol_address_p (bfd *, asection *, Elf_Internal_Sym *, bfd_vma);
+
+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 (bfd *abfd ATTRIBUTE_UNUSED,
+ 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;
+}
+
+static reloc_howto_type *
+bfd_elf32_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ const char *r_name)
+{
+ unsigned int i;
+
+ for (i = 0;
+ i < (sizeof (elf_mn10200_howto_table)
+ / sizeof (elf_mn10200_howto_table[0]));
+ i++)
+ if (elf_mn10200_howto_table[i].name != NULL
+ && strcasecmp (elf_mn10200_howto_table[i].name, r_name) == 0)
+ return &elf_mn10200_howto_table[i];
+
+ return NULL;
+}
+
+/* Set the howto pointer for an MN10200 ELF reloc. */
+
+static void
+mn10200_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED,
+ arelent *cache_ptr,
+ Elf_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 (reloc_howto_type *howto,
+ bfd *input_bfd,
+ bfd *output_bfd ATTRIBUTE_UNUSED,
+ asection *input_section,
+ bfd_byte *contents,
+ bfd_vma offset,
+ bfd_vma value,
+ bfd_vma addend,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ asection *sym_sec ATTRIBUTE_UNUSED,
+ int is_local ATTRIBUTE_UNUSED)
+{
+ 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 bfd_boolean
+mn10200_elf_relocate_section (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;
+
+ h = NULL;
+ sym = NULL;
+ sec = NULL;
+ if (r_symndx < symtab_hdr->sh_info)
+ {
+ sym = local_syms + r_symndx;
+ sec = local_sections[r_symndx];
+ relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
+ }
+ else
+ {
+ bfd_boolean unresolved_reloc, warned, ignored;
+
+ RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
+ r_symndx, symtab_hdr, sym_hashes,
+ h, sec, relocation,
+ unresolved_reloc, warned, ignored);
+ }
+
+ if (sec != NULL && discarded_section (sec))
+ RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+ rel, 1, relend, howto, 0, contents);
+
+ if (info->relocatable)
+ continue;
+
+ 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, (h ? &h->root : NULL), 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, TRUE)))
+ 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;
+}
+
+/* Delete some bytes from a section while relaxing. */
+
+static bfd_boolean
+mn10200_elf_relax_delete_bytes (bfd *abfd, asection *sec,
+ bfd_vma addr, int count)
+{
+ Elf_Internal_Shdr *symtab_hdr;
+ unsigned int sec_shndx;
+ bfd_byte *contents;
+ Elf_Internal_Rela *irel, *irelend;
+ bfd_vma toaddr;
+ Elf_Internal_Sym *isym;
+ Elf_Internal_Sym *isymend;
+ struct elf_link_hash_entry **sym_hashes;
+ struct elf_link_hash_entry **end_hashes;
+ unsigned int symcount;
+
+ sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
+
+ contents = elf_section_data (sec)->this_hdr.contents;
+
+ toaddr = sec->size;
+
+ irel = elf_section_data (sec)->relocs;
+ irelend = irel + sec->reloc_count;
+
+ /* Actually delete the bytes. */
+ memmove (contents + addr, contents + addr + count,
+ (size_t) (toaddr - addr - count));
+ sec->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. */
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+ isym = (Elf_Internal_Sym *) symtab_hdr->contents;
+ for (isymend = isym + symtab_hdr->sh_info; isym < isymend; isym++)
+ {
+ if (isym->st_shndx == sec_shndx
+ && isym->st_value > addr
+ && isym->st_value < toaddr)
+ isym->st_value -= count;
+ }
+
+ /* Now adjust the global symbols defined in this section. */
+ symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
+ - symtab_hdr->sh_info);
+ sym_hashes = elf_sym_hashes (abfd);
+ end_hashes = sym_hashes + symcount;
+ for (; sym_hashes < end_hashes; sym_hashes++)
+ {
+ struct elf_link_hash_entry *sym_hash = *sym_hashes;
+ 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
+ && sym_hash->root.u.def.value < toaddr)
+ {
+ sym_hash->root.u.def.value -= count;
+ }
+ }
+
+ return TRUE;
+}
+
+/* This function handles relaxing for the mn10200.
+
+ There are quite a few relaxing opportunities 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 bfd_boolean
+mn10200_elf_relax_section (bfd *abfd,
+ asection *sec,
+ struct bfd_link_info *link_info,
+ bfd_boolean *again)
+{
+ Elf_Internal_Shdr *symtab_hdr;
+ Elf_Internal_Rela *internal_relocs;
+ Elf_Internal_Rela *irel, *irelend;
+ bfd_byte *contents = NULL;
+ Elf_Internal_Sym *isymbuf = NULL;
+
+ /* Assume nothing changes. */
+ *again = FALSE;
+
+ /* We don't have to do anything for a relocatable link, if
+ this section does not have relocs, or if this is not a
+ code section. */
+ if (link_info->relocatable
+ || (sec->flags & SEC_RELOC) == 0
+ || sec->reloc_count == 0
+ || (sec->flags & SEC_CODE) == 0)
+ return TRUE;
+
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+
+ /* Get a copy of the native relocations. */
+ internal_relocs = (_bfd_elf_link_read_relocs
+ (abfd, sec, NULL, (Elf_Internal_Rela *) NULL,
+ link_info->keep_memory));
+ if (internal_relocs == NULL)
+ goto error_return;
+
+ /* 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. */
+ if (!bfd_malloc_and_get_section (abfd, sec, &contents))
+ goto error_return;
+ }
+ }
+
+ /* Read this BFD's local symbols if we haven't done so already. */
+ if (isymbuf == NULL && symtab_hdr->sh_info != 0)
+ {
+ isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
+ if (isymbuf == NULL)
+ isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
+ symtab_hdr->sh_info, 0,
+ NULL, NULL, NULL);
+ if (isymbuf == NULL)
+ 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)
+ {
+ /* A local symbol. */
+ Elf_Internal_Sym *isym;
+ asection *sym_sec;
+
+ isym = isymbuf + ELF32_R_SYM (irel->r_info);
+ if (isym->st_shndx == SHN_UNDEF)
+ sym_sec = bfd_und_section_ptr;
+ 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;
+ else
+ 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;
+ elf_section_data (sec)->this_hdr.contents = contents;
+ symtab_hdr->contents = (unsigned char *) isymbuf;
+
+ /* 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;
+ elf_section_data (sec)->this_hdr.contents = contents;
+ symtab_hdr->contents = (unsigned char *) isymbuf;
+
+ /* 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->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, isymbuf,
+ irel->r_offset + 1))
+ continue;
+
+ /* Note that we've changed the relocs, section contents, etc. */
+ elf_section_data (sec)->relocs = internal_relocs;
+ elf_section_data (sec)->this_hdr.contents = contents;
+ symtab_hdr->contents = (unsigned char *) isymbuf;
+
+ /* 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 relocation contents, etc. */
+ elf_section_data (sec)->relocs = internal_relocs;
+ elf_section_data (sec)->this_hdr.contents = contents;
+ symtab_hdr->contents = (unsigned char *) isymbuf;
+
+ /* 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 relocation contents, etc. */
+ elf_section_data (sec)->relocs = internal_relocs;
+ elf_section_data (sec)->this_hdr.contents = contents;
+ symtab_hdr->contents = (unsigned char *) isymbuf;
+
+ 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 relocation contents, etc. */
+ elf_section_data (sec)->relocs = internal_relocs;
+ elf_section_data (sec)->this_hdr.contents = contents;
+ symtab_hdr->contents = (unsigned char *) isymbuf;
+
+ /* 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;
+ elf_section_data (sec)->this_hdr.contents = contents;
+ symtab_hdr->contents = (unsigned char *) isymbuf;
+
+ 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 (isymbuf != NULL
+ && symtab_hdr->contents != (unsigned char *) isymbuf)
+ {
+ if (! link_info->keep_memory)
+ free (isymbuf);
+ else
+ {
+ /* Cache the symbols for elf_link_input_bfd. */
+ symtab_hdr->contents = (unsigned char *) isymbuf;
+ }
+ }
+
+ if (contents != NULL
+ && elf_section_data (sec)->this_hdr.contents != contents)
+ {
+ if (! link_info->keep_memory)
+ free (contents);
+ else
+ {
+ /* Cache the section contents for elf_link_input_bfd. */
+ elf_section_data (sec)->this_hdr.contents = contents;
+ }
+ }
+
+ if (internal_relocs != NULL
+ && elf_section_data (sec)->relocs != internal_relocs)
+ free (internal_relocs);
+
+ return TRUE;
+
+ error_return:
+ if (isymbuf != NULL
+ && symtab_hdr->contents != (unsigned char *) isymbuf)
+ free (isymbuf);
+ if (contents != NULL
+ && elf_section_data (sec)->this_hdr.contents != contents)
+ free (contents);
+ if (internal_relocs != NULL
+ && elf_section_data (sec)->relocs != internal_relocs)
+ free (internal_relocs);
+
+ return FALSE;
+}
+
+/* Return TRUE if a symbol exists at the given address, else return
+ FALSE. */
+static bfd_boolean
+mn10200_elf_symbol_address_p (bfd *abfd,
+ asection *sec,
+ Elf_Internal_Sym *isym,
+ bfd_vma addr)
+{
+ Elf_Internal_Shdr *symtab_hdr;
+ unsigned int sec_shndx;
+ Elf_Internal_Sym *isymend;
+ struct elf_link_hash_entry **sym_hashes;
+ struct elf_link_hash_entry **end_hashes;
+ unsigned int symcount;
+
+ sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
+
+ /* Examine all the local symbols. */
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+ for (isymend = isym + symtab_hdr->sh_info; isym < isymend; isym++)
+ {
+ if (isym->st_shndx == sec_shndx
+ && isym->st_value == addr)
+ return TRUE;
+ }
+
+ symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
+ - symtab_hdr->sh_info);
+ sym_hashes = elf_sym_hashes (abfd);
+ end_hashes = sym_hashes + symcount;
+ for (; sym_hashes < end_hashes; sym_hashes++)
+ {
+ struct elf_link_hash_entry *sym_hash = *sym_hashes;
+ 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 (bfd *output_bfd,
+ struct bfd_link_info *link_info,
+ struct bfd_link_order *link_order,
+ bfd_byte *data,
+ bfd_boolean relocatable,
+ 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;
+ Elf_Internal_Sym *isymbuf = NULL;
+
+ /* We only need to handle the case of relaxing, or of having a
+ particular set of section contents, specially. */
+ if (relocatable
+ || elf_section_data (input_section)->this_hdr.contents == NULL)
+ return bfd_generic_get_relocated_section_contents (output_bfd, link_info,
+ link_order, data,
+ relocatable,
+ symbols);
+
+ symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
+
+ memcpy (data, elf_section_data (input_section)->this_hdr.contents,
+ (size_t) input_section->size);
+
+ if ((input_section->flags & SEC_RELOC) != 0
+ && input_section->reloc_count > 0)
+ {
+ Elf_Internal_Sym *isym;
+ Elf_Internal_Sym *isymend;
+ asection **secpp;
+ bfd_size_type amt;
+
+ internal_relocs = (_bfd_elf_link_read_relocs
+ (input_bfd, input_section, NULL,
+ (Elf_Internal_Rela *) NULL, FALSE));
+ if (internal_relocs == NULL)
+ goto error_return;
+
+ if (symtab_hdr->sh_info != 0)
+ {
+ isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
+ if (isymbuf == NULL)
+ isymbuf = bfd_elf_get_elf_syms (input_bfd, symtab_hdr,
+ symtab_hdr->sh_info, 0,
+ NULL, NULL, NULL);
+ if (isymbuf == NULL)
+ goto error_return;
+ }
+
+ amt = symtab_hdr->sh_info;
+ amt *= sizeof (asection *);
+ sections = (asection **) bfd_malloc (amt);
+ if (sections == NULL && amt != 0)
+ goto error_return;
+
+ isymend = isymbuf + symtab_hdr->sh_info;
+ for (isym = isymbuf, secpp = sections; isym < isymend; ++isym, ++secpp)
+ {
+ asection *isec;
+
+ if (isym->st_shndx == SHN_UNDEF)
+ isec = bfd_und_section_ptr;
+ 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
+ isec = bfd_section_from_elf_index (input_bfd, isym->st_shndx);
+
+ *secpp = isec;
+ }
+
+ if (! mn10200_elf_relocate_section (output_bfd, link_info, input_bfd,
+ input_section, data, internal_relocs,
+ isymbuf, sections))
+ goto error_return;
+
+ if (sections != NULL)
+ free (sections);
+ if (isymbuf != NULL
+ && symtab_hdr->contents != (unsigned char *) isymbuf)
+ free (isymbuf);
+ if (elf_section_data (input_section)->relocs != internal_relocs)
+ free (internal_relocs);
+ }
+
+ return data;
+
+ error_return:
+ if (sections != NULL)
+ free (sections);
+ if (isymbuf != NULL
+ && symtab_hdr->contents != (unsigned char *) isymbuf)
+ free (isymbuf);
+ if (internal_relocs != NULL
+ && elf_section_data (input_section)->relocs != internal_relocs)
+ free (internal_relocs);
+ return NULL;
+}
+
+#define TARGET_LITTLE_SYM mn10200_elf32_vec
+#define TARGET_LITTLE_NAME "elf32-mn10200"
+#define ELF_ARCH bfd_arch_mn10200
+#define ELF_MACHINE_CODE EM_MN10200
+#define ELF_MACHINE_ALT1 EM_CYGNUS_MN10200
+#define ELF_MAXPAGESIZE 0x1000
+
+#define elf_backend_rela_normal 1
+#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 0000000..f29025d
--- /dev/null
+++ b/bfd/elf-m10300.c
@@ -0,0 +1,5628 @@
+/* Matsushita 10300 specific support for 32-bit ELF
+ Copyright (C) 1996-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+#include "elf-bfd.h"
+#include "elf/mn10300.h"
+#include "libiberty.h"
+
+/* The mn10300 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. */
+
+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 function 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;
+
+ /* Calculated value. */
+ bfd_vma value;
+
+#define GOT_UNKNOWN 0
+#define GOT_NORMAL 1
+#define GOT_TLS_GD 2
+#define GOT_TLS_LD 3
+#define GOT_TLS_IE 4
+ /* Used to distinguish GOT entries for TLS types from normal GOT entries. */
+ unsigned char tls_type;
+};
+
+/* 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;
+ struct
+ {
+ bfd_signed_vma refcount;
+ bfd_vma offset;
+ char got_allocated;
+ char rel_emitted;
+ } tls_ldm_got;
+};
+
+#define elf_mn10300_hash_entry(ent) ((struct elf32_mn10300_link_hash_entry *)(ent))
+
+struct elf_mn10300_obj_tdata
+{
+ struct elf_obj_tdata root;
+
+ /* tls_type for each local got entry. */
+ char * local_got_tls_type;
+};
+
+#define elf_mn10300_tdata(abfd) \
+ ((struct elf_mn10300_obj_tdata *) (abfd)->tdata.any)
+
+#define elf_mn10300_local_got_tls_type(abfd) \
+ (elf_mn10300_tdata (abfd)->local_got_tls_type)
+
+#ifndef streq
+#define streq(a, b) (strcmp ((a),(b)) == 0)
+#endif
+
+/* For MN10300 linker hash table. */
+
+/* Get the MN10300 ELF linker hash table from a link_info structure. */
+
+#define elf32_mn10300_hash_table(p) \
+ (elf_hash_table_id ((struct elf_link_hash_table *) ((p)->hash)) \
+ == MN10300_ELF_DATA ? ((struct elf32_mn10300_link_hash_table *) ((p)->hash)) : NULL)
+
+#define elf32_mn10300_link_hash_traverse(table, func, info) \
+ (elf_link_hash_traverse \
+ (&(table)->root, \
+ (bfd_boolean (*) (struct elf_link_hash_entry *, void *)) (func), \
+ (info)))
+
+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),
+ HOWTO (R_MN10300_GOTPC32, /* 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, /* */
+ "R_MN10300_GOTPC32", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_MN10300_GOTPC16, /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* */
+ "R_MN10300_GOTPC16", /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_MN10300_GOTOFF32, /* 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, /* */
+ "R_MN10300_GOTOFF32", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_MN10300_GOTOFF24, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 24, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* */
+ "R_MN10300_GOTOFF24", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffff, /* src_mask */
+ 0xffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_MN10300_GOTOFF16, /* 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, /* */
+ "R_MN10300_GOTOFF16", /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_MN10300_PLT32, /* 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, /* */
+ "R_MN10300_PLT32", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_MN10300_PLT16, /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* */
+ "R_MN10300_PLT16", /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_MN10300_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, /* */
+ "R_MN10300_GOT32", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_MN10300_GOT24, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 24, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* */
+ "R_MN10300_GOT24", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_MN10300_GOT16, /* 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, /* */
+ "R_MN10300_GOT16", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_MN10300_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, /* */
+ "R_MN10300_COPY", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_MN10300_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, /* */
+ "R_MN10300_GLOB_DAT", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_MN10300_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, /* */
+ "R_MN10300_JMP_SLOT", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_MN10300_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, /* */
+ "R_MN10300_RELATIVE", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_MN10300_TLS_GD, /* 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, /* */
+ "R_MN10300_TLS_GD", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_MN10300_TLS_LD, /* 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, /* */
+ "R_MN10300_TLS_LD", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_MN10300_TLS_LDO, /* 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, /* */
+ "R_MN10300_TLS_LDO", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_MN10300_TLS_GOTIE, /* 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, /* */
+ "R_MN10300_TLS_GOTIE", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_MN10300_TLS_IE, /* 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, /* */
+ "R_MN10300_TLS_IE", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_MN10300_TLS_LE, /* 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, /* */
+ "R_MN10300_TLS_LE", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_MN10300_TLS_DTPMOD, /* 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, /* */
+ "R_MN10300_TLS_DTPMOD", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_MN10300_TLS_DTPOFF, /* 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, /* */
+ "R_MN10300_TLS_DTPOFF", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_MN10300_TLS_TPOFF, /* 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, /* */
+ "R_MN10300_TLS_TPOFF", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_MN10300_SYM_DIFF, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ NULL, /* special handler. */
+ "R_MN10300_SYM_DIFF", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_MN10300_ALIGN, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ NULL, /* special handler. */
+ "R_MN10300_ALIGN", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ FALSE) /* pcrel_offset */
+};
+
+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 },
+ { BFD_RELOC_32_GOT_PCREL, R_MN10300_GOTPC32 },
+ { BFD_RELOC_16_GOT_PCREL, R_MN10300_GOTPC16 },
+ { BFD_RELOC_32_GOTOFF, R_MN10300_GOTOFF32 },
+ { BFD_RELOC_MN10300_GOTOFF24, R_MN10300_GOTOFF24 },
+ { BFD_RELOC_16_GOTOFF, R_MN10300_GOTOFF16 },
+ { BFD_RELOC_32_PLT_PCREL, R_MN10300_PLT32 },
+ { BFD_RELOC_16_PLT_PCREL, R_MN10300_PLT16 },
+ { BFD_RELOC_MN10300_GOT32, R_MN10300_GOT32 },
+ { BFD_RELOC_MN10300_GOT24, R_MN10300_GOT24 },
+ { BFD_RELOC_MN10300_GOT16, R_MN10300_GOT16 },
+ { BFD_RELOC_MN10300_COPY, R_MN10300_COPY },
+ { BFD_RELOC_MN10300_GLOB_DAT, R_MN10300_GLOB_DAT },
+ { BFD_RELOC_MN10300_JMP_SLOT, R_MN10300_JMP_SLOT },
+ { BFD_RELOC_MN10300_RELATIVE, R_MN10300_RELATIVE },
+ { BFD_RELOC_MN10300_TLS_GD, R_MN10300_TLS_GD },
+ { BFD_RELOC_MN10300_TLS_LD, R_MN10300_TLS_LD },
+ { BFD_RELOC_MN10300_TLS_LDO, R_MN10300_TLS_LDO },
+ { BFD_RELOC_MN10300_TLS_GOTIE, R_MN10300_TLS_GOTIE },
+ { BFD_RELOC_MN10300_TLS_IE, R_MN10300_TLS_IE },
+ { BFD_RELOC_MN10300_TLS_LE, R_MN10300_TLS_LE },
+ { BFD_RELOC_MN10300_TLS_DTPMOD, R_MN10300_TLS_DTPMOD },
+ { BFD_RELOC_MN10300_TLS_DTPOFF, R_MN10300_TLS_DTPOFF },
+ { BFD_RELOC_MN10300_TLS_TPOFF, R_MN10300_TLS_TPOFF },
+ { BFD_RELOC_MN10300_SYM_DIFF, R_MN10300_SYM_DIFF },
+ { BFD_RELOC_MN10300_ALIGN, R_MN10300_ALIGN }
+};
+
+/* Create the GOT section. */
+
+static bfd_boolean
+_bfd_mn10300_elf_create_got_section (bfd * abfd,
+ struct bfd_link_info * info)
+{
+ flagword flags;
+ flagword pltflags;
+ asection * s;
+ struct elf_link_hash_entry * h;
+ const struct elf_backend_data * bed = get_elf_backend_data (abfd);
+ struct elf_link_hash_table *htab;
+ int ptralign;
+
+ /* This function may be called more than once. */
+ htab = elf_hash_table (info);
+ if (htab->sgot != NULL)
+ return TRUE;
+
+ switch (bed->s->arch_size)
+ {
+ case 32:
+ ptralign = 2;
+ break;
+
+ case 64:
+ ptralign = 3;
+ break;
+
+ default:
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+
+ 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_anyway_with_flags (abfd, ".plt", pltflags);
+ htab->splt = s;
+ if (s == NULL
+ || ! bfd_set_section_alignment (abfd, s, bed->plt_alignment))
+ return FALSE;
+
+ /* Define the symbol _PROCEDURE_LINKAGE_TABLE_ at the start of the
+ .plt section. */
+ if (bed->want_plt_sym)
+ {
+ h = _bfd_elf_define_linkage_sym (abfd, info, s,
+ "_PROCEDURE_LINKAGE_TABLE_");
+ htab->hplt = h;
+ if (h == NULL)
+ return FALSE;
+ }
+
+ s = bfd_make_section_anyway_with_flags (abfd, ".got", flags);
+ htab->sgot = s;
+ if (s == NULL
+ || ! bfd_set_section_alignment (abfd, s, ptralign))
+ return FALSE;
+
+ if (bed->want_got_plt)
+ {
+ s = bfd_make_section_anyway_with_flags (abfd, ".got.plt", flags);
+ htab->sgotplt = s;
+ if (s == NULL
+ || ! 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 = _bfd_elf_define_linkage_sym (abfd, info, s, "_GLOBAL_OFFSET_TABLE_");
+ htab->hgot = h;
+ if (h == NULL)
+ return FALSE;
+
+ /* The first bit of the global offset table is the header. */
+ s->size += bed->got_header_size;
+
+ return TRUE;
+}
+
+static reloc_howto_type *
+bfd_elf32_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ bfd_reloc_code_real_type code)
+{
+ unsigned int i;
+
+ for (i = ARRAY_SIZE (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;
+}
+
+static reloc_howto_type *
+bfd_elf32_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ const char *r_name)
+{
+ unsigned int i;
+
+ for (i = ARRAY_SIZE (elf_mn10300_howto_table); i--;)
+ if (elf_mn10300_howto_table[i].name != NULL
+ && strcasecmp (elf_mn10300_howto_table[i].name, r_name) == 0)
+ return elf_mn10300_howto_table + i;
+
+ return NULL;
+}
+
+/* Set the howto pointer for an MN10300 ELF reloc. */
+
+static void
+mn10300_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED,
+ arelent *cache_ptr,
+ Elf_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;
+}
+
+static int
+elf_mn10300_tls_transition (struct bfd_link_info * info,
+ int r_type,
+ struct elf_link_hash_entry * h,
+ asection * sec,
+ bfd_boolean counting)
+{
+ bfd_boolean is_local;
+
+ if (r_type == R_MN10300_TLS_GD
+ && h != NULL
+ && elf_mn10300_hash_entry (h)->tls_type == GOT_TLS_IE)
+ return R_MN10300_TLS_GOTIE;
+
+ if (info->shared)
+ return r_type;
+
+ if (! (sec->flags & SEC_CODE))
+ return r_type;
+
+ if (! counting && h != NULL && ! elf_hash_table (info)->dynamic_sections_created)
+ is_local = TRUE;
+ else
+ is_local = SYMBOL_CALLS_LOCAL (info, h);
+
+ /* For the main program, these are the transitions we do. */
+ switch (r_type)
+ {
+ case R_MN10300_TLS_GD: return is_local ? R_MN10300_TLS_LE : R_MN10300_TLS_GOTIE;
+ case R_MN10300_TLS_LD: return R_MN10300_NONE;
+ case R_MN10300_TLS_LDO: return R_MN10300_TLS_LE;
+ case R_MN10300_TLS_IE:
+ case R_MN10300_TLS_GOTIE: return is_local ? R_MN10300_TLS_LE : r_type;
+ }
+
+ return r_type;
+}
+
+/* Return the relocation value for @tpoff relocation
+ if STT_TLS virtual address is ADDRESS. */
+
+static bfd_vma
+dtpoff (struct bfd_link_info * info, bfd_vma address)
+{
+ struct elf_link_hash_table *htab = elf_hash_table (info);
+
+ /* If tls_sec is NULL, we should have signalled an error already. */
+ if (htab->tls_sec == NULL)
+ return 0;
+ return address - htab->tls_sec->vma;
+}
+
+/* Return the relocation value for @tpoff relocation
+ if STT_TLS virtual address is ADDRESS. */
+
+static bfd_vma
+tpoff (struct bfd_link_info * info, bfd_vma address)
+{
+ struct elf_link_hash_table *htab = elf_hash_table (info);
+
+ /* If tls_sec is NULL, we should have signalled an error already. */
+ if (htab->tls_sec == NULL)
+ return 0;
+ return address - (htab->tls_size + htab->tls_sec->vma);
+}
+
+/* Returns nonzero if there's a R_MN10300_PLT32 reloc that we now need
+ to skip, after this one. The actual value is the offset between
+ this reloc and the PLT reloc. */
+
+static int
+mn10300_do_tls_transition (bfd * input_bfd,
+ unsigned int r_type,
+ unsigned int tls_r_type,
+ bfd_byte * contents,
+ bfd_vma offset)
+{
+ bfd_byte *op = contents + offset;
+ int gotreg = 0;
+
+#define TLS_PAIR(r1,r2) ((r1) * R_MN10300_MAX + (r2))
+
+ /* This is common to all GD/LD transitions, so break it out. */
+ if (r_type == R_MN10300_TLS_GD
+ || r_type == R_MN10300_TLS_LD)
+ {
+ op -= 2;
+ /* mov imm,d0. */
+ BFD_ASSERT (bfd_get_8 (input_bfd, op) == 0xFC);
+ BFD_ASSERT (bfd_get_8 (input_bfd, op + 1) == 0xCC);
+ /* add aN,d0. */
+ BFD_ASSERT (bfd_get_8 (input_bfd, op + 6) == 0xF1);
+ gotreg = (bfd_get_8 (input_bfd, op + 7) & 0x0c) >> 2;
+ /* Call. */
+ BFD_ASSERT (bfd_get_8 (input_bfd, op + 8) == 0xDD);
+ }
+
+ switch (TLS_PAIR (r_type, tls_r_type))
+ {
+ case TLS_PAIR (R_MN10300_TLS_GD, R_MN10300_TLS_GOTIE):
+ {
+ /* Keep track of which register we put GOTptr in. */
+ /* mov (_x@indntpoff,a2),a0. */
+ memcpy (op, "\xFC\x20\x00\x00\x00\x00", 6);
+ op[1] |= gotreg;
+ /* add e2,a0. */
+ memcpy (op+6, "\xF9\x78\x28", 3);
+ /* or 0x00000000, d0 - six byte nop. */
+ memcpy (op+9, "\xFC\xE4\x00\x00\x00\x00", 6);
+ }
+ return 7;
+
+ case TLS_PAIR (R_MN10300_TLS_GD, R_MN10300_TLS_LE):
+ {
+ /* Register is *always* a0. */
+ /* mov _x@tpoff,a0. */
+ memcpy (op, "\xFC\xDC\x00\x00\x00\x00", 6);
+ /* add e2,a0. */
+ memcpy (op+6, "\xF9\x78\x28", 3);
+ /* or 0x00000000, d0 - six byte nop. */
+ memcpy (op+9, "\xFC\xE4\x00\x00\x00\x00", 6);
+ }
+ return 7;
+ case TLS_PAIR (R_MN10300_TLS_LD, R_MN10300_NONE):
+ {
+ /* Register is *always* a0. */
+ /* mov e2,a0. */
+ memcpy (op, "\xF5\x88", 2);
+ /* or 0x00000000, d0 - six byte nop. */
+ memcpy (op+2, "\xFC\xE4\x00\x00\x00\x00", 6);
+ /* or 0x00000000, e2 - seven byte nop. */
+ memcpy (op+8, "\xFE\x19\x22\x00\x00\x00\x00", 7);
+ }
+ return 7;
+
+ case TLS_PAIR (R_MN10300_TLS_LDO, R_MN10300_TLS_LE):
+ /* No changes needed, just the reloc change. */
+ return 0;
+
+ /* These are a little tricky, because we have to detect which
+ opcode is being used (they're different sizes, with the reloc
+ at different offsets within the opcode) and convert each
+ accordingly, copying the operands as needed. The conversions
+ we do are as follows (IE,GOTIE,LE):
+
+ 1111 1100 1010 01Dn [-- abs32 --] MOV (x@indntpoff),Dn
+ 1111 1100 0000 DnAm [-- abs32 --] MOV (x@gotntpoff,Am),Dn
+ 1111 1100 1100 11Dn [-- abs32 --] MOV x@tpoff,Dn
+
+ 1111 1100 1010 00An [-- abs32 --] MOV (x@indntpoff),An
+ 1111 1100 0010 AnAm [-- abs32 --] MOV (x@gotntpoff,Am),An
+ 1111 1100 1101 11An [-- abs32 --] MOV x@tpoff,An
+
+ 1111 1110 0000 1110 Rnnn Xxxx [-- abs32 --] MOV (x@indntpoff),Rn
+ 1111 1110 0000 1010 Rnnn Rmmm [-- abs32 --] MOV (x@indntpoff,Rm),Rn
+ 1111 1110 0000 1000 Rnnn Xxxx [-- abs32 --] MOV x@tpoff,Rn
+
+ Since the GOT pointer is always $a2, we assume the last
+ normally won't happen, but let's be paranoid and plan for the
+ day that GCC optimizes it somewhow. */
+
+ case TLS_PAIR (R_MN10300_TLS_IE, R_MN10300_TLS_LE):
+ if (op[-2] == 0xFC)
+ {
+ op -= 2;
+ if ((op[1] & 0xFC) == 0xA4) /* Dn */
+ {
+ op[1] &= 0x03; /* Leaves Dn. */
+ op[1] |= 0xCC;
+ }
+ else /* An */
+ {
+ op[1] &= 0x03; /* Leaves An. */
+ op[1] |= 0xDC;
+ }
+ }
+ else if (op[-3] == 0xFE)
+ op[-2] = 0x08;
+ else
+ abort ();
+ break;
+
+ case TLS_PAIR (R_MN10300_TLS_GOTIE, R_MN10300_TLS_LE):
+ if (op[-2] == 0xFC)
+ {
+ op -= 2;
+ if ((op[1] & 0xF0) == 0x00) /* Dn */
+ {
+ op[1] &= 0x0C; /* Leaves Dn. */
+ op[1] >>= 2;
+ op[1] |= 0xCC;
+ }
+ else /* An */
+ {
+ op[1] &= 0x0C; /* Leaves An. */
+ op[1] >>= 2;
+ op[1] |= 0xDC;
+ }
+ }
+ else if (op[-3] == 0xFE)
+ op[-2] = 0x08;
+ else
+ abort ();
+ break;
+
+ default:
+ (*_bfd_error_handler)
+ (_("%s: Unsupported transition from %s to %s"),
+ bfd_get_filename (input_bfd),
+ elf_mn10300_howto_table[r_type].name,
+ elf_mn10300_howto_table[tls_r_type].name);
+ break;
+ }
+#undef TLS_PAIR
+ return 0;
+}
+
+/* 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 bfd_boolean
+mn10300_elf_check_relocs (bfd *abfd,
+ struct bfd_link_info *info,
+ asection *sec,
+ const Elf_Internal_Rela *relocs)
+{
+ struct elf32_mn10300_link_hash_table * htab = elf32_mn10300_hash_table (info);
+ bfd_boolean sym_diff_reloc_seen;
+ Elf_Internal_Shdr *symtab_hdr;
+ Elf_Internal_Sym * isymbuf = NULL;
+ struct elf_link_hash_entry **sym_hashes;
+ const Elf_Internal_Rela *rel;
+ const Elf_Internal_Rela *rel_end;
+ bfd * dynobj;
+ bfd_vma * local_got_offsets;
+ asection * sgot;
+ asection * srelgot;
+ asection * sreloc;
+ bfd_boolean result = FALSE;
+
+ sgot = NULL;
+ srelgot = NULL;
+ sreloc = NULL;
+
+ if (info->relocatable)
+ return TRUE;
+
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+ isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
+ sym_hashes = elf_sym_hashes (abfd);
+
+ dynobj = elf_hash_table (info)->dynobj;
+ local_got_offsets = elf_local_got_offsets (abfd);
+ rel_end = relocs + sec->reloc_count;
+ sym_diff_reloc_seen = FALSE;
+
+ for (rel = relocs; rel < rel_end; rel++)
+ {
+ struct elf_link_hash_entry *h;
+ unsigned long r_symndx;
+ unsigned int r_type;
+ int tls_type = GOT_NORMAL;
+
+ 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];
+ 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;
+
+ /* PR15323, ref flags aren't set for references in the same
+ object. */
+ h->root.non_ir_ref = 1;
+ }
+
+ r_type = ELF32_R_TYPE (rel->r_info);
+ r_type = elf_mn10300_tls_transition (info, r_type, h, sec, TRUE);
+
+ /* Some relocs require a global offset table. */
+ if (dynobj == NULL)
+ {
+ switch (r_type)
+ {
+ case R_MN10300_GOT32:
+ case R_MN10300_GOT24:
+ case R_MN10300_GOT16:
+ case R_MN10300_GOTOFF32:
+ case R_MN10300_GOTOFF24:
+ case R_MN10300_GOTOFF16:
+ case R_MN10300_GOTPC32:
+ case R_MN10300_GOTPC16:
+ case R_MN10300_TLS_GD:
+ case R_MN10300_TLS_LD:
+ case R_MN10300_TLS_GOTIE:
+ case R_MN10300_TLS_IE:
+ elf_hash_table (info)->dynobj = dynobj = abfd;
+ if (! _bfd_mn10300_elf_create_got_section (dynobj, info))
+ goto fail;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ switch (r_type)
+ {
+ /* This relocation describes the C++ object vtable hierarchy.
+ Reconstruct it for later use during GC. */
+ case R_MN10300_GNU_VTINHERIT:
+ if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
+ goto fail;
+ break;
+
+ /* This relocation describes which C++ vtable entries are actually
+ used. Record for later use during GC. */
+ case R_MN10300_GNU_VTENTRY:
+ BFD_ASSERT (h != NULL);
+ if (h != NULL
+ && !bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
+ goto fail;
+ break;
+
+ case R_MN10300_TLS_LD:
+ htab->tls_ldm_got.refcount ++;
+ tls_type = GOT_TLS_LD;
+
+ if (htab->tls_ldm_got.got_allocated)
+ break;
+ goto create_got;
+
+ case R_MN10300_TLS_IE:
+ case R_MN10300_TLS_GOTIE:
+ if (info->shared)
+ info->flags |= DF_STATIC_TLS;
+ /* Fall through */
+
+ case R_MN10300_TLS_GD:
+ case R_MN10300_GOT32:
+ case R_MN10300_GOT24:
+ case R_MN10300_GOT16:
+ create_got:
+ /* This symbol requires a global offset table entry. */
+
+ switch (r_type)
+ {
+ case R_MN10300_TLS_IE:
+ case R_MN10300_TLS_GOTIE: tls_type = GOT_TLS_IE; break;
+ case R_MN10300_TLS_GD: tls_type = GOT_TLS_GD; break;
+ default: tls_type = GOT_NORMAL; break;
+ }
+
+ if (sgot == NULL)
+ {
+ sgot = htab->root.sgot;
+ BFD_ASSERT (sgot != NULL);
+ }
+
+ if (srelgot == NULL
+ && (h != NULL || info->shared))
+ {
+ srelgot = bfd_get_linker_section (dynobj, ".rela.got");
+ if (srelgot == NULL)
+ {
+ flagword flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS
+ | SEC_IN_MEMORY | SEC_LINKER_CREATED
+ | SEC_READONLY);
+ srelgot = bfd_make_section_anyway_with_flags (dynobj,
+ ".rela.got",
+ flags);
+ if (srelgot == NULL
+ || ! bfd_set_section_alignment (dynobj, srelgot, 2))
+ goto fail;
+ }
+ }
+
+ if (r_type == R_MN10300_TLS_LD)
+ {
+ htab->tls_ldm_got.offset = sgot->size;
+ htab->tls_ldm_got.got_allocated ++;
+ }
+ else if (h != NULL)
+ {
+ if (elf_mn10300_hash_entry (h)->tls_type != tls_type
+ && elf_mn10300_hash_entry (h)->tls_type != GOT_UNKNOWN)
+ {
+ if (tls_type == GOT_TLS_IE
+ && elf_mn10300_hash_entry (h)->tls_type == GOT_TLS_GD)
+ /* No change - this is ok. */;
+ else if (tls_type == GOT_TLS_GD
+ && elf_mn10300_hash_entry (h)->tls_type == GOT_TLS_IE)
+ /* Transition GD->IE. */
+ tls_type = GOT_TLS_IE;
+ else
+ (*_bfd_error_handler)
+ (_("%B: %s' accessed both as normal and thread local symbol"),
+ abfd, h ? h->root.root.string : "<local>");
+ }
+
+ elf_mn10300_hash_entry (h)->tls_type = tls_type;
+
+ if (h->got.offset != (bfd_vma) -1)
+ /* We have already allocated space in the .got. */
+ break;
+
+ h->got.offset = sgot->size;
+
+ if (ELF_ST_VISIBILITY (h->other) != STV_INTERNAL
+ /* Make sure this symbol is output as a dynamic symbol. */
+ && h->dynindx == -1)
+ {
+ if (! bfd_elf_link_record_dynamic_symbol (info, h))
+ goto fail;
+ }
+
+ srelgot->size += sizeof (Elf32_External_Rela);
+ if (r_type == R_MN10300_TLS_GD)
+ srelgot->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;
+ unsigned int i;
+
+ size = symtab_hdr->sh_info * (sizeof (bfd_vma) + sizeof (char));
+ local_got_offsets = bfd_alloc (abfd, size);
+
+ if (local_got_offsets == NULL)
+ goto fail;
+
+ elf_local_got_offsets (abfd) = local_got_offsets;
+ elf_mn10300_local_got_tls_type (abfd)
+ = (char *) (local_got_offsets + symtab_hdr->sh_info);
+
+ 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->size;
+
+ if (info->shared)
+ {
+ /* If we are generating a shared object, we need to
+ output a R_MN10300_RELATIVE reloc so that the dynamic
+ linker can adjust this GOT entry. */
+ srelgot->size += sizeof (Elf32_External_Rela);
+
+ if (r_type == R_MN10300_TLS_GD)
+ /* And a R_MN10300_TLS_DTPOFF reloc as well. */
+ srelgot->size += sizeof (Elf32_External_Rela);
+ }
+
+ elf_mn10300_local_got_tls_type (abfd) [r_symndx] = tls_type;
+ }
+
+ sgot->size += 4;
+ if (r_type == R_MN10300_TLS_GD
+ || r_type == R_MN10300_TLS_LD)
+ sgot->size += 4;
+
+ goto need_shared_relocs;
+
+ case R_MN10300_PLT32:
+ case R_MN10300_PLT16:
+ /* 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;
+
+ if (ELF_ST_VISIBILITY (h->other) == STV_INTERNAL
+ || ELF_ST_VISIBILITY (h->other) == STV_HIDDEN)
+ break;
+
+ h->needs_plt = 1;
+ break;
+
+ case R_MN10300_24:
+ case R_MN10300_16:
+ case R_MN10300_8:
+ case R_MN10300_PCREL32:
+ case R_MN10300_PCREL16:
+ case R_MN10300_PCREL8:
+ if (h != NULL)
+ h->non_got_ref = 1;
+ break;
+
+ case R_MN10300_SYM_DIFF:
+ sym_diff_reloc_seen = TRUE;
+ break;
+
+ case R_MN10300_32:
+ if (h != NULL)
+ h->non_got_ref = 1;
+
+ need_shared_relocs:
+ /* If we are creating a shared library, then we
+ need to copy the reloc into the shared library. */
+ if (info->shared
+ && (sec->flags & SEC_ALLOC) != 0
+ /* Do not generate a dynamic reloc for a
+ reloc associated with a SYM_DIFF operation. */
+ && ! sym_diff_reloc_seen)
+ {
+ asection * sym_section = NULL;
+
+ /* Find the section containing the
+ symbol involved in the relocation. */
+ if (h == NULL)
+ {
+ Elf_Internal_Sym * isym;
+
+ if (isymbuf == NULL)
+ isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
+ symtab_hdr->sh_info, 0,
+ NULL, NULL, NULL);
+ if (isymbuf)
+ {
+ isym = isymbuf + r_symndx;
+ /* All we care about is whether this local symbol is absolute. */
+ if (isym->st_shndx == SHN_ABS)
+ sym_section = bfd_abs_section_ptr;
+ }
+ }
+ else
+ {
+ if (h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak)
+ sym_section = h->root.u.def.section;
+ }
+
+ /* If the symbol is absolute then the relocation can
+ be resolved during linking and there is no need for
+ a dynamic reloc. */
+ if (sym_section != bfd_abs_section_ptr)
+ {
+ /* 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)
+ {
+ sreloc = _bfd_elf_make_dynamic_reloc_section
+ (sec, dynobj, 2, abfd, /*rela?*/ TRUE);
+ if (sreloc == NULL)
+ goto fail;
+ }
+
+ sreloc->size += sizeof (Elf32_External_Rela);
+ }
+ }
+
+ break;
+ }
+
+ if (ELF32_R_TYPE (rel->r_info) != R_MN10300_SYM_DIFF)
+ sym_diff_reloc_seen = FALSE;
+ }
+
+ result = TRUE;
+ fail:
+ if (isymbuf != NULL)
+ free (isymbuf);
+
+ return result;
+}
+
+/* Return the section that should be marked against GC for a given
+ relocation. */
+
+static asection *
+mn10300_elf_gc_mark_hook (asection *sec,
+ 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:
+ return NULL;
+ }
+
+ return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
+}
+
+/* Perform a relocation as part of a final link. */
+
+static bfd_reloc_status_type
+mn10300_elf_final_link_relocate (reloc_howto_type *howto,
+ bfd *input_bfd,
+ bfd *output_bfd ATTRIBUTE_UNUSED,
+ asection *input_section,
+ bfd_byte *contents,
+ bfd_vma offset,
+ bfd_vma value,
+ bfd_vma addend,
+ struct elf_link_hash_entry * h,
+ unsigned long symndx,
+ struct bfd_link_info *info,
+ asection *sym_sec ATTRIBUTE_UNUSED,
+ int is_local ATTRIBUTE_UNUSED)
+{
+ struct elf32_mn10300_link_hash_table * htab = elf32_mn10300_hash_table (info);
+ static asection * sym_diff_section;
+ static bfd_vma sym_diff_value;
+ bfd_boolean is_sym_diff_reloc;
+ unsigned long r_type = howto->type;
+ bfd_byte * hit_data = contents + offset;
+ bfd * dynobj;
+ asection * sgot;
+ asection * splt;
+ asection * sreloc;
+
+ dynobj = elf_hash_table (info)->dynobj;
+ sgot = NULL;
+ splt = NULL;
+ sreloc = NULL;
+
+ switch (r_type)
+ {
+ case R_MN10300_24:
+ case R_MN10300_16:
+ case R_MN10300_8:
+ case R_MN10300_PCREL8:
+ case R_MN10300_PCREL16:
+ case R_MN10300_PCREL32:
+ case R_MN10300_GOTOFF32:
+ case R_MN10300_GOTOFF24:
+ case R_MN10300_GOTOFF16:
+ if (info->shared
+ && (input_section->flags & SEC_ALLOC) != 0
+ && h != NULL
+ && ! SYMBOL_REFERENCES_LOCAL (info, h))
+ return bfd_reloc_dangerous;
+ case R_MN10300_GOT32:
+ /* Issue 2052223:
+ Taking the address of a protected function in a shared library
+ is illegal. Issue an error message here. */
+ if (info->shared
+ && (input_section->flags & SEC_ALLOC) != 0
+ && h != NULL
+ && ELF_ST_VISIBILITY (h->other) == STV_PROTECTED
+ && (h->type == STT_FUNC || h->type == STT_GNU_IFUNC)
+ && ! SYMBOL_REFERENCES_LOCAL (info, h))
+ return bfd_reloc_dangerous;
+ }
+
+ is_sym_diff_reloc = FALSE;
+ if (sym_diff_section != NULL)
+ {
+ BFD_ASSERT (sym_diff_section == input_section);
+
+ switch (r_type)
+ {
+ case R_MN10300_32:
+ case R_MN10300_24:
+ case R_MN10300_16:
+ case R_MN10300_8:
+ value -= sym_diff_value;
+ /* If we are computing a 32-bit value for the location lists
+ and the result is 0 then we add one to the value. A zero
+ value can result because of linker relaxation deleteing
+ prologue instructions and using a value of 1 (for the begin
+ and end offsets in the location list entry) results in a
+ nul entry which does not prevent the following entries from
+ being parsed. */
+ if (r_type == R_MN10300_32
+ && value == 0
+ && strcmp (input_section->name, ".debug_loc") == 0)
+ value = 1;
+ sym_diff_section = NULL;
+ is_sym_diff_reloc = TRUE;
+ break;
+
+ default:
+ sym_diff_section = NULL;
+ break;
+ }
+ }
+
+ switch (r_type)
+ {
+ case R_MN10300_SYM_DIFF:
+ BFD_ASSERT (addend == 0);
+ /* Cache the input section and value.
+ The offset is unreliable, since relaxation may
+ have reduced the following reloc's offset. */
+ sym_diff_section = input_section;
+ sym_diff_value = value;
+ return bfd_reloc_ok;
+
+ case R_MN10300_ALIGN:
+ case R_MN10300_NONE:
+ return bfd_reloc_ok;
+
+ case R_MN10300_32:
+ if (info->shared
+ /* Do not generate relocs when an R_MN10300_32 has been used
+ with an R_MN10300_SYM_DIFF to compute a difference of two
+ symbols. */
+ && is_sym_diff_reloc == FALSE
+ /* Also, do not generate a reloc when the symbol associated
+ with the R_MN10300_32 reloc is absolute - there is no
+ need for a run time computation in this case. */
+ && sym_sec != bfd_abs_section_ptr
+ /* If the section is not going to be allocated at load time
+ then there is no need to generate relocs for it. */
+ && (input_section->flags & SEC_ALLOC) != 0)
+ {
+ Elf_Internal_Rela outrel;
+ bfd_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)
+ {
+ sreloc = _bfd_elf_get_dynamic_reloc_section
+ (input_bfd, input_section, /*rela?*/ TRUE);
+ if (sreloc == NULL)
+ return FALSE;
+ }
+
+ skip = FALSE;
+
+ outrel.r_offset = _bfd_elf_section_offset (input_bfd, info,
+ input_section, offset);
+ if (outrel.r_offset == (bfd_vma) -1)
+ skip = TRUE;
+
+ outrel.r_offset += (input_section->output_section->vma
+ + input_section->output_offset);
+
+ if (skip)
+ {
+ memset (&outrel, 0, sizeof outrel);
+ relocate = FALSE;
+ }
+ else
+ {
+ /* h->dynindx may be -1 if this symbol was marked to
+ become local. */
+ if (h == NULL
+ || SYMBOL_REFERENCES_LOCAL (info, h))
+ {
+ relocate = TRUE;
+ outrel.r_info = ELF32_R_INFO (0, R_MN10300_RELATIVE);
+ outrel.r_addend = value + addend;
+ }
+ else
+ {
+ BFD_ASSERT (h->dynindx != -1);
+ relocate = FALSE;
+ outrel.r_info = ELF32_R_INFO (h->dynindx, R_MN10300_32);
+ outrel.r_addend = value + addend;
+ }
+ }
+
+ bfd_elf32_swap_reloca_out (output_bfd, &outrel,
+ (bfd_byte *) (((Elf32_External_Rela *) 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;
+ }
+ 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 > 0x7f || (long) value < -0x80)
+ 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 > 0x7fff || (long) value < -0x8000)
+ 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;
+
+ case R_MN10300_GOTPC32:
+ if (dynobj == NULL)
+ return bfd_reloc_dangerous;
+
+ /* Use global offset table as symbol value. */
+ value = htab->root.sgot->output_section->vma;
+ 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_GOTPC16:
+ if (dynobj == NULL)
+ return bfd_reloc_dangerous;
+
+ /* Use global offset table as symbol value. */
+ value = htab->root.sgot->output_section->vma;
+ value -= (input_section->output_section->vma
+ + input_section->output_offset);
+ value -= offset;
+ 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_GOTOFF32:
+ if (dynobj == NULL)
+ return bfd_reloc_dangerous;
+
+ value -= htab->root.sgot->output_section->vma;
+ value += addend;
+
+ bfd_put_32 (input_bfd, value, hit_data);
+ return bfd_reloc_ok;
+
+ case R_MN10300_GOTOFF24:
+ if (dynobj == NULL)
+ return bfd_reloc_dangerous;
+
+ value -= htab->root.sgot->output_section->vma;
+ value += addend;
+
+ if ((long) value > 0x7fffff || (long) value < -0x800000)
+ return bfd_reloc_overflow;
+
+ bfd_put_8 (input_bfd, value, 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_GOTOFF16:
+ if (dynobj == NULL)
+ return bfd_reloc_dangerous;
+
+ value -= htab->root.sgot->output_section->vma;
+ 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_PLT32:
+ if (h != NULL
+ && ELF_ST_VISIBILITY (h->other) != STV_INTERNAL
+ && ELF_ST_VISIBILITY (h->other) != STV_HIDDEN
+ && h->plt.offset != (bfd_vma) -1)
+ {
+ if (dynobj == NULL)
+ return bfd_reloc_dangerous;
+
+ splt = htab->root.splt;
+ value = (splt->output_section->vma
+ + splt->output_offset
+ + h->plt.offset) - value;
+ }
+
+ 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_PLT16:
+ if (h != NULL
+ && ELF_ST_VISIBILITY (h->other) != STV_INTERNAL
+ && ELF_ST_VISIBILITY (h->other) != STV_HIDDEN
+ && h->plt.offset != (bfd_vma) -1)
+ {
+ if (dynobj == NULL)
+ return bfd_reloc_dangerous;
+
+ splt = htab->root.splt;
+ value = (splt->output_section->vma
+ + splt->output_offset
+ + h->plt.offset) - value;
+ }
+
+ value -= (input_section->output_section->vma
+ + input_section->output_offset);
+ value -= offset;
+ 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_TLS_LDO:
+ value = dtpoff (info, value);
+ bfd_put_32 (input_bfd, value + addend, hit_data);
+ return bfd_reloc_ok;
+
+ case R_MN10300_TLS_LE:
+ value = tpoff (info, value);
+ bfd_put_32 (input_bfd, value + addend, hit_data);
+ return bfd_reloc_ok;
+
+ case R_MN10300_TLS_LD:
+ if (dynobj == NULL)
+ return bfd_reloc_dangerous;
+
+ sgot = htab->root.sgot;
+ BFD_ASSERT (sgot != NULL);
+ value = htab->tls_ldm_got.offset + sgot->output_offset;
+ bfd_put_32 (input_bfd, value, hit_data);
+
+ if (!htab->tls_ldm_got.rel_emitted)
+ {
+ asection * srelgot = bfd_get_linker_section (dynobj, ".rela.got");
+ Elf_Internal_Rela rel;
+
+ BFD_ASSERT (srelgot != NULL);
+ htab->tls_ldm_got.rel_emitted ++;
+ rel.r_offset = (sgot->output_section->vma
+ + sgot->output_offset
+ + htab->tls_ldm_got.offset);
+ bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents + htab->tls_ldm_got.offset);
+ bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents + htab->tls_ldm_got.offset+4);
+ rel.r_info = ELF32_R_INFO (0, R_MN10300_TLS_DTPMOD);
+ rel.r_addend = 0;
+ bfd_elf32_swap_reloca_out (output_bfd, & rel,
+ (bfd_byte *) ((Elf32_External_Rela *) srelgot->contents
+ + srelgot->reloc_count));
+ ++ srelgot->reloc_count;
+ }
+
+ return bfd_reloc_ok;
+
+ case R_MN10300_TLS_GOTIE:
+ value = tpoff (info, value);
+ /* Fall Through. */
+
+ case R_MN10300_TLS_GD:
+ case R_MN10300_TLS_IE:
+ case R_MN10300_GOT32:
+ case R_MN10300_GOT24:
+ case R_MN10300_GOT16:
+ if (dynobj == NULL)
+ return bfd_reloc_dangerous;
+
+ sgot = htab->root.sgot;
+ if (r_type == R_MN10300_TLS_GD)
+ value = dtpoff (info, value);
+
+ if (h != NULL)
+ {
+ bfd_vma off;
+
+ off = h->got.offset;
+ /* Offsets in the GOT are allocated in check_relocs
+ which is not called for shared libraries... */
+ if (off == (bfd_vma) -1)
+ off = 0;
+
+ if (sgot->contents != NULL
+ && (! elf_hash_table (info)->dynamic_sections_created
+ || SYMBOL_REFERENCES_LOCAL (info, h)))
+ /* 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.
+
+ 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. */
+ bfd_put_32 (output_bfd, value,
+ sgot->contents + off);
+
+ value = sgot->output_offset + off;
+ }
+ else
+ {
+ bfd_vma off;
+
+ off = elf_local_got_offsets (input_bfd)[symndx];
+
+ if (off & 1)
+ bfd_put_32 (output_bfd, value, sgot->contents + (off & ~ 1));
+ else
+ {
+ bfd_put_32 (output_bfd, value, sgot->contents + off);
+
+ if (info->shared)
+ {
+ asection * srelgot;
+ Elf_Internal_Rela outrel;
+
+ srelgot = bfd_get_linker_section (dynobj, ".rela.got");
+ BFD_ASSERT (srelgot != NULL);
+
+ outrel.r_offset = (sgot->output_section->vma
+ + sgot->output_offset
+ + off);
+ switch (r_type)
+ {
+ case R_MN10300_TLS_GD:
+ outrel.r_info = ELF32_R_INFO (0, R_MN10300_TLS_DTPOFF);
+ outrel.r_offset = (sgot->output_section->vma
+ + sgot->output_offset
+ + off + 4);
+ bfd_elf32_swap_reloca_out (output_bfd, & outrel,
+ (bfd_byte *) (((Elf32_External_Rela *)
+ srelgot->contents)
+ + srelgot->reloc_count));
+ ++ srelgot->reloc_count;
+ outrel.r_info = ELF32_R_INFO (0, R_MN10300_TLS_DTPMOD);
+ break;
+ case R_MN10300_TLS_GOTIE:
+ case R_MN10300_TLS_IE:
+ outrel.r_info = ELF32_R_INFO (0, R_MN10300_TLS_TPOFF);
+ break;
+ default:
+ outrel.r_info = ELF32_R_INFO (0, R_MN10300_RELATIVE);
+ break;
+ }
+
+ outrel.r_addend = value;
+ bfd_elf32_swap_reloca_out (output_bfd, &outrel,
+ (bfd_byte *) (((Elf32_External_Rela *)
+ srelgot->contents)
+ + srelgot->reloc_count));
+ ++ srelgot->reloc_count;
+ elf_local_got_offsets (input_bfd)[symndx] |= 1;
+ }
+
+ value = sgot->output_offset + (off & ~(bfd_vma) 1);
+ }
+ }
+
+ value += addend;
+
+ if (r_type == R_MN10300_TLS_IE)
+ {
+ value += sgot->output_section->vma;
+ bfd_put_32 (input_bfd, value, hit_data);
+ return bfd_reloc_ok;
+ }
+ else if (r_type == R_MN10300_TLS_GOTIE
+ || r_type == R_MN10300_TLS_GD
+ || r_type == R_MN10300_TLS_LD)
+ {
+ bfd_put_32 (input_bfd, value, hit_data);
+ return bfd_reloc_ok;
+ }
+ else if (r_type == R_MN10300_GOT32)
+ {
+ bfd_put_32 (input_bfd, value, hit_data);
+ return bfd_reloc_ok;
+ }
+ else if (r_type == R_MN10300_GOT24)
+ {
+ 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;
+ }
+ else if (r_type == R_MN10300_GOT16)
+ {
+ if ((long) value > 0x7fff || (long) value < -0x8000)
+ return bfd_reloc_overflow;
+
+ bfd_put_16 (input_bfd, value, hit_data);
+ return bfd_reloc_ok;
+ }
+ /* Fall through. */
+
+ default:
+ return bfd_reloc_notsupported;
+ }
+}
+
+/* Relocate an MN10300 ELF section. */
+
+static bfd_boolean
+mn10300_elf_relocate_section (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;
+ Elf_Internal_Rela * trel;
+
+ 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 elf32_mn10300_link_hash_entry *h;
+ bfd_vma relocation;
+ bfd_reloc_status_type r;
+ int tls_r_type;
+ bfd_boolean unresolved_reloc = FALSE;
+ bfd_boolean warned, ignored;
+ struct elf_link_hash_entry * hh;
+
+ relocation = 0;
+ 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;
+
+ h = NULL;
+ sym = NULL;
+ sec = NULL;
+ if (r_symndx < symtab_hdr->sh_info)
+ hh = NULL;
+ else
+ {
+ RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
+ r_symndx, symtab_hdr, sym_hashes,
+ hh, sec, relocation,
+ unresolved_reloc, warned, ignored);
+ }
+ h = elf_mn10300_hash_entry (hh);
+
+ tls_r_type = elf_mn10300_tls_transition (info, r_type, hh, input_section, 0);
+ if (tls_r_type != r_type)
+ {
+ bfd_boolean had_plt;
+
+ had_plt = mn10300_do_tls_transition (input_bfd, r_type, tls_r_type,
+ contents, rel->r_offset);
+ r_type = tls_r_type;
+ howto = elf_mn10300_howto_table + r_type;
+
+ if (had_plt)
+ for (trel = rel+1; trel < relend; trel++)
+ if ((ELF32_R_TYPE (trel->r_info) == R_MN10300_PLT32
+ || ELF32_R_TYPE (trel->r_info) == R_MN10300_PCREL32)
+ && rel->r_offset + had_plt == trel->r_offset)
+ trel->r_info = ELF32_R_INFO (0, R_MN10300_NONE);
+ }
+
+ if (r_symndx < symtab_hdr->sh_info)
+ {
+ sym = local_syms + r_symndx;
+ sec = local_sections[r_symndx];
+ relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
+ }
+ else
+ {
+ if ((h->root.root.type == bfd_link_hash_defined
+ || h->root.root.type == bfd_link_hash_defweak)
+ && ( r_type == R_MN10300_GOTPC32
+ || r_type == R_MN10300_GOTPC16
+ || (( r_type == R_MN10300_PLT32
+ || r_type == R_MN10300_PLT16)
+ && ELF_ST_VISIBILITY (h->root.other) != STV_INTERNAL
+ && ELF_ST_VISIBILITY (h->root.other) != STV_HIDDEN
+ && h->root.plt.offset != (bfd_vma) -1)
+ || (( r_type == R_MN10300_GOT32
+ || r_type == R_MN10300_GOT24
+ || r_type == R_MN10300_TLS_GD
+ || r_type == R_MN10300_TLS_LD
+ || r_type == R_MN10300_TLS_GOTIE
+ || r_type == R_MN10300_TLS_IE
+ || r_type == R_MN10300_GOT16)
+ && elf_hash_table (info)->dynamic_sections_created
+ && !SYMBOL_REFERENCES_LOCAL (info, hh))
+ || (r_type == R_MN10300_32
+ /* _32 relocs in executables force _COPY relocs,
+ such that the address of the symbol ends up
+ being local. */
+ && !info->executable
+ && !SYMBOL_REFERENCES_LOCAL (info, hh)
+ && ((input_section->flags & SEC_ALLOC) != 0
+ /* DWARF will emit R_MN10300_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
+ && h->root.def_dynamic)))))
+ /* 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 (!info->relocatable && unresolved_reloc
+ && _bfd_elf_section_offset (output_bfd, info, input_section,
+ rel->r_offset) != (bfd_vma) -1)
+
+ (*_bfd_error_handler)
+ (_("%B(%A+0x%lx): unresolvable %s relocation against symbol `%s'"),
+ input_bfd,
+ input_section,
+ (long) rel->r_offset,
+ howto->name,
+ h->root.root.root.string);
+ }
+
+ if (sec != NULL && discarded_section (sec))
+ RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+ rel, 1, relend, howto, 0, contents);
+
+ if (info->relocatable)
+ continue;
+
+ r = mn10300_elf_final_link_relocate (howto, input_bfd, output_bfd,
+ input_section,
+ contents, rel->r_offset,
+ relocation, rel->r_addend,
+ (struct elf_link_hash_entry *) h,
+ r_symndx,
+ info, sec, h == NULL);
+
+ if (r != bfd_reloc_ok)
+ {
+ const char *name;
+ const char *msg = NULL;
+
+ 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, (h ? &h->root.root : NULL), 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, TRUE)))
+ 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:
+ if (r_type == R_MN10300_PCREL32)
+ msg = _("error: inappropriate relocation type for shared"
+ " library (did you forget -fpic?)");
+ else if (r_type == R_MN10300_GOT32)
+ msg = _("%B: taking the address of protected function"
+ " '%s' cannot be done when making a shared library");
+ else
+ msg = _("internal error: suspicious relocation type used"
+ " in shared library");
+ goto common_error;
+
+ default:
+ msg = _("internal error: unknown error");
+ /* Fall through. */
+
+ common_error:
+ _bfd_error_handler (msg, input_bfd, name);
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+ }
+ }
+
+ return TRUE;
+}
+
+/* Finish initializing one hash table entry. */
+
+static bfd_boolean
+elf32_mn10300_finish_hash_table_entry (struct bfd_hash_entry *gen_entry,
+ void * in_args)
+{
+ struct elf32_mn10300_link_hash_entry *entry;
+ struct bfd_link_info *link_info = (struct bfd_link_info *) in_args;
+ 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 a symbol is available for
+ dynamic symbol resolution (overridable or overriding), avoid
+ custom calling conventions. */
+ if (entry->direct_calls == 0
+ || (entry->stack_size == 0 && entry->movm_args == 0)
+ || (elf_hash_table (link_info)->dynamic_sections_created
+ && ELF_ST_VISIBILITY (entry->root.other) != STV_INTERNAL
+ && ELF_ST_VISIBILITY (entry->root.other) != STV_HIDDEN))
+ {
+ /* 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)
+ {
+ if (entry->stack_size <= 128)
+ byte_count += 3;
+ else
+ byte_count += 4;
+ }
+
+ /* If using "call" will result in larger code, then turn all
+ the associated "call" instructions into "calls" instructions. */
+ if (byte_count < entry->direct_calls)
+ entry->flags |= MN10300_CONVERT_CALL_TO_CALLS;
+
+ /* This routine never fails. */
+ return TRUE;
+}
+
+/* Used to count hash table entries. */
+
+static bfd_boolean
+elf32_mn10300_count_hash_table_entries (struct bfd_hash_entry *gen_entry ATTRIBUTE_UNUSED,
+ void * in_args)
+{
+ int *count = (int *) in_args;
+
+ (*count) ++;
+ return TRUE;
+}
+
+/* Used to enumerate hash table entries into a linear array. */
+
+static bfd_boolean
+elf32_mn10300_list_hash_table_entries (struct bfd_hash_entry *gen_entry,
+ void * in_args)
+{
+ struct bfd_hash_entry ***ptr = (struct bfd_hash_entry ***) in_args;
+
+ **ptr = gen_entry;
+ (*ptr) ++;
+ return TRUE;
+}
+
+/* Used to sort the array created by the above. */
+
+static int
+sort_by_value (const void *va, const void *vb)
+{
+ struct elf32_mn10300_link_hash_entry *a
+ = *(struct elf32_mn10300_link_hash_entry **) va;
+ struct elf32_mn10300_link_hash_entry *b
+ = *(struct elf32_mn10300_link_hash_entry **) vb;
+
+ return a->value - b->value;
+}
+
+/* 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 (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 function'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;
+
+ if (bfd_get_mach (abfd) == bfd_mach_am33
+ || bfd_get_mach (abfd) == bfd_mach_am33_2)
+ {
+ /* "exother" space. e0, e1, mdrq, mcrh, mcrl, mcvf */
+ if (hash->movm_args & 0x1)
+ hash->movm_stack_size += 6 * 4;
+
+ /* exreg1 space. e4, e5, e6, e7 */
+ if (hash->movm_args & 0x2)
+ hash->movm_stack_size += 4 * 4;
+
+ /* exreg0 space. e2, e3 */
+ if (hash->movm_args & 0x4)
+ hash->movm_stack_size += 2 * 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;
+}
+
+/* Delete some bytes from a section while relaxing. */
+
+static bfd_boolean
+mn10300_elf_relax_delete_bytes (bfd *abfd,
+ asection *sec,
+ bfd_vma addr,
+ int count)
+{
+ Elf_Internal_Shdr *symtab_hdr;
+ unsigned int sec_shndx;
+ bfd_byte *contents;
+ Elf_Internal_Rela *irel, *irelend;
+ Elf_Internal_Rela *irelalign;
+ bfd_vma toaddr;
+ Elf_Internal_Sym *isym, *isymend;
+ struct elf_link_hash_entry **sym_hashes;
+ struct elf_link_hash_entry **end_hashes;
+ unsigned int symcount;
+
+ sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
+
+ contents = elf_section_data (sec)->this_hdr.contents;
+
+ irelalign = NULL;
+ toaddr = sec->size;
+
+ irel = elf_section_data (sec)->relocs;
+ irelend = irel + sec->reloc_count;
+
+ if (sec->reloc_count > 0)
+ {
+ /* If there is an align reloc at the end of the section ignore it.
+ GAS creates these relocs for reasons of its own, and they just
+ serve to keep the section artifically inflated. */
+ if (ELF32_R_TYPE ((irelend - 1)->r_info) == (int) R_MN10300_ALIGN)
+ --irelend;
+
+ /* The deletion must stop at the next ALIGN reloc for an aligment
+ power larger than, or not a multiple of, the number of bytes we
+ are deleting. */
+ for (; irel < irelend; irel++)
+ {
+ int alignment = 1 << irel->r_addend;
+
+ if (ELF32_R_TYPE (irel->r_info) == (int) R_MN10300_ALIGN
+ && irel->r_offset > addr
+ && irel->r_offset < toaddr
+ && (count < alignment
+ || alignment % count != 0))
+ {
+ irelalign = irel;
+ toaddr = irel->r_offset;
+ break;
+ }
+ }
+ }
+
+ /* Actually delete the bytes. */
+ memmove (contents + addr, contents + addr + count,
+ (size_t) (toaddr - addr - count));
+
+ /* Adjust the section's size if we are shrinking it, or else
+ pad the bytes between the end of the shrunken region and
+ the start of the next region with NOP codes. */
+ if (irelalign == NULL)
+ {
+ sec->size -= count;
+ /* Include symbols at the end of the section, but
+ not at the end of a sub-region of the section. */
+ toaddr ++;
+ }
+ else
+ {
+ int i;
+
+#define NOP_OPCODE 0xcb
+
+ for (i = 0; i < count; i ++)
+ bfd_put_8 (abfd, (bfd_vma) NOP_OPCODE, contents + toaddr - count + i);
+ }
+
+ /* 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)
+ || (ELF32_R_TYPE (irel->r_info) == (int) R_MN10300_ALIGN
+ && irel->r_offset == toaddr))
+ irel->r_offset -= count;
+ }
+
+ /* Adjust the local symbols in the section, reducing their value
+ by the number of bytes deleted. Note - symbols within the deleted
+ region are moved to the address of the start of the region, which
+ actually means that they will address the byte beyond the end of
+ the region once the deletion has been completed. */
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+ isym = (Elf_Internal_Sym *) symtab_hdr->contents;
+ for (isymend = isym + symtab_hdr->sh_info; isym < isymend; isym++)
+ {
+ if (isym->st_shndx == sec_shndx
+ && isym->st_value > addr
+ && isym->st_value < toaddr)
+ {
+ if (isym->st_value < addr + count)
+ isym->st_value = addr;
+ else
+ isym->st_value -= count;
+ }
+ /* Adjust the function symbol's size as well. */
+ else if (isym->st_shndx == sec_shndx
+ && ELF_ST_TYPE (isym->st_info) == STT_FUNC
+ && isym->st_value + isym->st_size > addr
+ && isym->st_value + isym->st_size < toaddr)
+ isym->st_size -= count;
+ }
+
+ /* Now adjust the global symbols defined in this section. */
+ symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
+ - symtab_hdr->sh_info);
+ sym_hashes = elf_sym_hashes (abfd);
+ end_hashes = sym_hashes + symcount;
+ for (; sym_hashes < end_hashes; sym_hashes++)
+ {
+ struct elf_link_hash_entry *sym_hash = *sym_hashes;
+
+ 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
+ && sym_hash->root.u.def.value < toaddr)
+ {
+ if (sym_hash->root.u.def.value < addr + count)
+ sym_hash->root.u.def.value = addr;
+ else
+ sym_hash->root.u.def.value -= count;
+ }
+ /* Adjust the function symbol's size as well. */
+ else if (sym_hash->root.type == bfd_link_hash_defined
+ && sym_hash->root.u.def.section == sec
+ && sym_hash->type == STT_FUNC
+ && sym_hash->root.u.def.value + sym_hash->size > addr
+ && sym_hash->root.u.def.value + sym_hash->size < toaddr)
+ sym_hash->size -= 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;
+
+ if ((int) irelalign->r_addend > 0)
+ {
+ /* This is the old address. */
+ alignto = BFD_ALIGN (toaddr, 1 << irelalign->r_addend);
+ /* This is where the align points to now. */
+ alignaddr = BFD_ALIGN (irelalign->r_offset,
+ 1 << irelalign->r_addend);
+ if (alignaddr < alignto)
+ /* Tail recursion. */
+ return mn10300_elf_relax_delete_bytes (abfd, sec, alignaddr,
+ (int) (alignto - alignaddr));
+ }
+ }
+
+ return TRUE;
+}
+
+/* Return TRUE if a symbol exists at the given address, else return
+ FALSE. */
+
+static bfd_boolean
+mn10300_elf_symbol_address_p (bfd *abfd,
+ asection *sec,
+ Elf_Internal_Sym *isym,
+ bfd_vma addr)
+{
+ Elf_Internal_Shdr *symtab_hdr;
+ unsigned int sec_shndx;
+ Elf_Internal_Sym *isymend;
+ struct elf_link_hash_entry **sym_hashes;
+ struct elf_link_hash_entry **end_hashes;
+ unsigned int symcount;
+
+ sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
+
+ /* Examine all the symbols. */
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+ for (isymend = isym + symtab_hdr->sh_info; isym < isymend; isym++)
+ if (isym->st_shndx == sec_shndx
+ && isym->st_value == addr)
+ return TRUE;
+
+ symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
+ - symtab_hdr->sh_info);
+ sym_hashes = elf_sym_hashes (abfd);
+ end_hashes = sym_hashes + symcount;
+ for (; sym_hashes < end_hashes; sym_hashes++)
+ {
+ struct elf_link_hash_entry *sym_hash = *sym_hashes;
+
+ 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 function handles relaxing for the mn10300.
+
+ There are quite a few relaxing opportunities 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 bfd_boolean
+mn10300_elf_relax_section (bfd *abfd,
+ asection *sec,
+ struct bfd_link_info *link_info,
+ bfd_boolean *again)
+{
+ Elf_Internal_Shdr *symtab_hdr;
+ Elf_Internal_Rela *internal_relocs = NULL;
+ Elf_Internal_Rela *irel, *irelend;
+ bfd_byte *contents = NULL;
+ Elf_Internal_Sym *isymbuf = NULL;
+ struct elf32_mn10300_link_hash_table *hash_table;
+ asection *section = sec;
+ bfd_vma align_gap_adjustment;
+
+ if (link_info->relocatable)
+ (*link_info->callbacks->einfo)
+ (_("%P%F: --relax and -r may not be used together\n"));
+
+ /* Assume nothing changes. */
+ *again = FALSE;
+
+ /* We need a pointer to the mn10300 specific hash table. */
+ hash_table = elf32_mn10300_hash_table (link_info);
+ if (hash_table == NULL)
+ return FALSE;
+
+ /* 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)
+ {
+ /* We're going to need all the symbols for each bfd. */
+ symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
+ if (symtab_hdr->sh_info != 0)
+ {
+ isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
+ if (isymbuf == NULL)
+ isymbuf = bfd_elf_get_elf_syms (input_bfd, symtab_hdr,
+ symtab_hdr->sh_info, 0,
+ NULL, NULL, NULL);
+ if (isymbuf == NULL)
+ 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;
+ asection *sym_sec = NULL;
+ const char *sym_name;
+ char *new_name;
+
+ /* If there's nothing to do in this section, skip it. */
+ if (! ((section->flags & SEC_RELOC) != 0
+ && section->reloc_count != 0))
+ continue;
+ if ((section->flags & SEC_ALLOC) == 0)
+ continue;
+
+ /* 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->size != 0)
+ {
+ /* Go get them off disk. */
+ if (!bfd_malloc_and_get_section (input_bfd, section,
+ &contents))
+ goto error_return;
+ }
+ else
+ 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_elf_link_read_relocs (input_bfd, section,
+ NULL, NULL,
+ link_info->keep_memory);
+ if (internal_relocs == NULL)
+ goto error_return;
+
+ /* 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_sec = NULL;
+
+ if (r_index < symtab_hdr->sh_info)
+ {
+ /* A local symbol. */
+ Elf_Internal_Sym *isym;
+ struct elf_link_hash_table *elftab;
+ bfd_size_type amt;
+
+ isym = isymbuf + r_index;
+ if (isym->st_shndx == SHN_UNDEF)
+ sym_sec = bfd_und_section_ptr;
+ 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;
+ else
+ sym_sec
+ = bfd_section_from_elf_index (input_bfd,
+ isym->st_shndx);
+
+ 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 (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. */
+ amt = strlen (sym_name) + 10;
+ new_name = bfd_malloc (amt);
+ if (new_name == NULL)
+ goto error_return;
+
+ sprintf (new_name, "%s_%08x", sym_name, sym_sec->id);
+ sym_name = new_name;
+
+ elftab = &hash_table->static_hash_table->root;
+ hash = ((struct elf32_mn10300_link_hash_entry *)
+ elf_link_hash_lookup (elftab, 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];
+ }
+
+ sym_name = hash->root.root.root.string;
+ if ((section->flags & SEC_CODE) != 0)
+ {
+ /* 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_PLT32
+ || r_type == R_MN10300_PLT16
+ || 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)
+ {
+ Elf_Internal_Sym *isym, *isymend;
+ unsigned int sec_shndx;
+ struct elf_link_hash_entry **hashes;
+ struct elf_link_hash_entry **end_hashes;
+ unsigned int symcount;
+
+ sec_shndx = _bfd_elf_section_from_bfd_section (input_bfd,
+ section);
+
+ symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
+ - symtab_hdr->sh_info);
+ hashes = elf_sym_hashes (input_bfd);
+ end_hashes = hashes + symcount;
+
+ /* Look at each function defined in this section and
+ update info for that function. */
+ isymend = isymbuf + symtab_hdr->sh_info;
+ for (isym = isymbuf; isym < isymend; isym++)
+ {
+ if (isym->st_shndx == sec_shndx
+ && ELF_ST_TYPE (isym->st_info) == STT_FUNC)
+ {
+ struct elf_link_hash_table *elftab;
+ bfd_size_type amt;
+ struct elf_link_hash_entry **lhashes = hashes;
+
+ /* Skip a local symbol if it aliases a
+ global one. */
+ for (; lhashes < end_hashes; lhashes++)
+ {
+ hash = (struct elf32_mn10300_link_hash_entry *) *lhashes;
+ if ((hash->root.root.type == bfd_link_hash_defined
+ || hash->root.root.type == bfd_link_hash_defweak)
+ && hash->root.root.u.def.section == section
+ && hash->root.type == STT_FUNC
+ && hash->root.root.u.def.value == isym->st_value)
+ break;
+ }
+ if (lhashes != end_hashes)
+ continue;
+
+ if (isym->st_shndx == SHN_UNDEF)
+ sym_sec = bfd_und_section_ptr;
+ 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;
+ else
+ sym_sec
+ = bfd_section_from_elf_index (input_bfd,
+ isym->st_shndx);
+
+ 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. */
+ amt = strlen (sym_name) + 10;
+ new_name = bfd_malloc (amt);
+ if (new_name == NULL)
+ goto error_return;
+
+ sprintf (new_name, "%s_%08x", sym_name, sym_sec->id);
+ sym_name = new_name;
+
+ elftab = &hash_table->static_hash_table->root;
+ hash = ((struct elf32_mn10300_link_hash_entry *)
+ elf_link_hash_lookup (elftab, sym_name,
+ TRUE, TRUE, FALSE));
+ free (new_name);
+ compute_function_info (input_bfd, hash,
+ isym->st_value, contents);
+ hash->value = isym->st_value;
+ }
+ }
+
+ for (; hashes < end_hashes; hashes++)
+ {
+ hash = (struct elf32_mn10300_link_hash_entry *) *hashes;
+ if ((hash->root.root.type == bfd_link_hash_defined
+ || hash->root.root.type == bfd_link_hash_defweak)
+ && hash->root.root.u.def.section == section
+ && hash->root.type == STT_FUNC)
+ compute_function_info (input_bfd, hash,
+ (hash)->root.root.u.def.value,
+ contents);
+ }
+ }
+
+ /* Cache or free any memory we allocated for the relocs. */
+ if (internal_relocs != NULL
+ && elf_section_data (section)->relocs != internal_relocs)
+ free (internal_relocs);
+ internal_relocs = NULL;
+
+ /* Cache or free any memory we allocated for the contents. */
+ if (contents != NULL
+ && elf_section_data (section)->this_hdr.contents != contents)
+ {
+ if (! link_info->keep_memory)
+ free (contents);
+ else
+ {
+ /* Cache the section contents for elf_link_input_bfd. */
+ elf_section_data (section)->this_hdr.contents = contents;
+ }
+ }
+ contents = NULL;
+ }
+
+ /* Cache or free any memory we allocated for the symbols. */
+ if (isymbuf != NULL
+ && symtab_hdr->contents != (unsigned char *) isymbuf)
+ {
+ if (! link_info->keep_memory)
+ free (isymbuf);
+ else
+ {
+ /* Cache the symbols for elf_link_input_bfd. */
+ symtab_hdr->contents = (unsigned char *) isymbuf;
+ }
+ }
+ isymbuf = 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,
+ link_info);
+ elf32_mn10300_link_hash_traverse (hash_table->static_hash_table,
+ elf32_mn10300_finish_hash_table_entry,
+ link_info);
+
+ {
+ /* This section of code collects all our local symbols, sorts
+ them by value, and looks for multiple symbols referring to
+ the same address. For those symbols, the flags are merged.
+ At this point, the only flag that can be set is
+ MN10300_CONVERT_CALL_TO_CALLS, so we simply OR the flags
+ together. */
+ int static_count = 0, i;
+ struct elf32_mn10300_link_hash_entry **entries;
+ struct elf32_mn10300_link_hash_entry **ptr;
+
+ elf32_mn10300_link_hash_traverse (hash_table->static_hash_table,
+ elf32_mn10300_count_hash_table_entries,
+ &static_count);
+
+ entries = bfd_malloc (static_count * sizeof (* ptr));
+
+ ptr = entries;
+ elf32_mn10300_link_hash_traverse (hash_table->static_hash_table,
+ elf32_mn10300_list_hash_table_entries,
+ & ptr);
+
+ qsort (entries, static_count, sizeof (entries[0]), sort_by_value);
+
+ for (i = 0; i < static_count - 1; i++)
+ if (entries[i]->value && entries[i]->value == entries[i+1]->value)
+ {
+ int v = entries[i]->flags;
+ int j;
+
+ for (j = i + 1; j < static_count && entries[j]->value == entries[i]->value; j++)
+ v |= entries[j]->flags;
+
+ for (j = i; j < static_count && entries[j]->value == entries[i]->value; j++)
+ entries[j]->flags = v;
+
+ i = j - 1;
+ }
+ }
+
+ /* 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)
+ {
+ /* We're going to need all the local symbols for each bfd. */
+ symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
+ if (symtab_hdr->sh_info != 0)
+ {
+ isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
+ if (isymbuf == NULL)
+ isymbuf = bfd_elf_get_elf_syms (input_bfd, symtab_hdr,
+ symtab_hdr->sh_info, 0,
+ NULL, NULL, NULL);
+ if (isymbuf == NULL)
+ goto error_return;
+ }
+
+ /* Walk over each section in this bfd. */
+ for (section = input_bfd->sections;
+ section != NULL;
+ section = section->next)
+ {
+ unsigned int sec_shndx;
+ Elf_Internal_Sym *isym, *isymend;
+ struct elf_link_hash_entry **hashes;
+ struct elf_link_hash_entry **end_hashes;
+ unsigned int symcount;
+
+ /* Skip non-code sections and empty sections. */
+ if ((section->flags & SEC_CODE) == 0 || section->size == 0)
+ continue;
+
+ if (section->reloc_count != 0)
+ {
+ /* Get a copy of the native relocations. */
+ internal_relocs = _bfd_elf_link_read_relocs (input_bfd, section,
+ NULL, NULL,
+ link_info->keep_memory);
+ if (internal_relocs == NULL)
+ goto error_return;
+ }
+
+ /* 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. */
+ if (!bfd_malloc_and_get_section (input_bfd, section,
+ &contents))
+ goto error_return;
+ }
+
+ sec_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. */
+ isymend = isymbuf + symtab_hdr->sh_info;
+ for (isym = isymbuf; isym < isymend; isym++)
+ {
+ struct elf32_mn10300_link_hash_entry *sym_hash;
+ asection *sym_sec = NULL;
+ const char *sym_name;
+ char *new_name;
+ struct elf_link_hash_table *elftab;
+ bfd_size_type amt;
+
+ if (isym->st_shndx != sec_shndx)
+ continue;
+
+ if (isym->st_shndx == SHN_UNDEF)
+ sym_sec = bfd_und_section_ptr;
+ 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;
+ else
+ sym_sec
+ = bfd_section_from_elf_index (input_bfd, isym->st_shndx);
+
+ 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. */
+ amt = strlen (sym_name) + 10;
+ new_name = bfd_malloc (amt);
+ if (new_name == NULL)
+ goto error_return;
+ sprintf (new_name, "%s_%08x", sym_name, sym_sec->id);
+ sym_name = new_name;
+
+ elftab = & hash_table->static_hash_table->root;
+ sym_hash = (struct elf32_mn10300_link_hash_entry *)
+ elf_link_hash_lookup (elftab, 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;
+ elf_section_data (section)->this_hdr.contents = contents;
+ symtab_hdr->contents = (unsigned char *) isymbuf;
+
+ /* Count how many bytes we're going to delete. */
+ if (sym_hash->movm_args)
+ bytes += 2;
+
+ if (sym_hash->stack_size > 0)
+ {
+ if (sym_hash->stack_size <= 128)
+ bytes += 3;
+ else
+ 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. */
+ symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
+ - symtab_hdr->sh_info);
+ hashes = elf_sym_hashes (input_bfd);
+ end_hashes = hashes + symcount;
+ for (; hashes < end_hashes; hashes++)
+ {
+ struct elf32_mn10300_link_hash_entry *sym_hash;
+
+ sym_hash = (struct elf32_mn10300_link_hash_entry *) *hashes;
+ 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 == section
+ && ! (sym_hash->flags & MN10300_CONVERT_CALL_TO_CALLS)
+ && ! (sym_hash->flags & MN10300_DELETED_PROLOGUE_BYTES))
+ {
+ int bytes = 0;
+ bfd_vma symval;
+ struct elf_link_hash_entry **hh;
+
+ /* Note that we've changed things. */
+ elf_section_data (section)->relocs = internal_relocs;
+ elf_section_data (section)->this_hdr.contents = contents;
+ symtab_hdr->contents = (unsigned char *) isymbuf;
+
+ /* Count how many bytes we're going to delete. */
+ if (sym_hash->movm_args)
+ bytes += 2;
+
+ if (sym_hash->stack_size > 0)
+ {
+ if (sym_hash->stack_size <= 128)
+ bytes += 3;
+ else
+ bytes += 4;
+ }
+
+ /* Note that we've deleted prologue bytes for this
+ function. */
+ sym_hash->flags |= MN10300_DELETED_PROLOGUE_BYTES;
+
+ /* Actually delete the bytes. */
+ symval = sym_hash->root.root.u.def.value;
+ if (!mn10300_elf_relax_delete_bytes (input_bfd,
+ section,
+ symval,
+ bytes))
+ goto error_return;
+
+ /* There may be other C++ functions symbols with the same
+ address. If so then mark these as having had their
+ prologue bytes deleted as well. */
+ for (hh = elf_sym_hashes (input_bfd); hh < end_hashes; hh++)
+ {
+ struct elf32_mn10300_link_hash_entry *h;
+
+ h = (struct elf32_mn10300_link_hash_entry *) * hh;
+
+ if (h != sym_hash
+ && (h->root.root.type == bfd_link_hash_defined
+ || h->root.root.type == bfd_link_hash_defweak)
+ && h->root.root.u.def.section == section
+ && ! (h->flags & MN10300_CONVERT_CALL_TO_CALLS)
+ && h->root.root.u.def.value == symval
+ && h->root.type == STT_FUNC)
+ h->flags |= MN10300_DELETED_PROLOGUE_BYTES;
+ }
+
+ /* 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 (internal_relocs != NULL
+ && elf_section_data (section)->relocs != internal_relocs)
+ free (internal_relocs);
+ internal_relocs = NULL;
+
+ /* Cache or free any memory we allocated for the contents. */
+ if (contents != NULL
+ && elf_section_data (section)->this_hdr.contents != contents)
+ {
+ if (! link_info->keep_memory)
+ free (contents);
+ else
+ /* Cache the section contents for elf_link_input_bfd. */
+ elf_section_data (section)->this_hdr.contents = contents;
+ }
+ contents = NULL;
+ }
+
+ /* Cache or free any memory we allocated for the symbols. */
+ if (isymbuf != NULL
+ && symtab_hdr->contents != (unsigned char *) isymbuf)
+ {
+ if (! link_info->keep_memory)
+ free (isymbuf);
+ else
+ /* Cache the symbols for elf_link_input_bfd. */
+ symtab_hdr->contents = (unsigned char *) isymbuf;
+ }
+ isymbuf = NULL;
+ }
+ }
+
+ /* (Re)initialize for the basic instruction shortening/relaxing pass. */
+ contents = NULL;
+ internal_relocs = NULL;
+ isymbuf = NULL;
+ /* For error_return. */
+ section = sec;
+
+ /* We don't have to do anything for a relocatable link, if
+ this section does not have relocs, or if this is not a
+ code section. */
+ if (link_info->relocatable
+ || (sec->flags & SEC_RELOC) == 0
+ || sec->reloc_count == 0
+ || (sec->flags & SEC_CODE) == 0)
+ return TRUE;
+
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+
+ /* Get a copy of the native relocations. */
+ internal_relocs = _bfd_elf_link_read_relocs (abfd, sec, NULL, NULL,
+ link_info->keep_memory);
+ if (internal_relocs == NULL)
+ goto error_return;
+
+ /* Scan for worst case alignment gap changes. Note that this logic
+ is not ideal; what we should do is run this scan for every
+ opcode/address range and adjust accordingly, but that's
+ expensive. Worst case is that for an alignment of N bytes, we
+ move by 2*N-N-1 bytes, assuming we have aligns of 1, 2, 4, 8, etc
+ all before it. Plus, this still doesn't cover cross-section
+ jumps with section alignment. */
+ irelend = internal_relocs + sec->reloc_count;
+ align_gap_adjustment = 0;
+ for (irel = internal_relocs; irel < irelend; irel++)
+ {
+ if (ELF32_R_TYPE (irel->r_info) == (int) R_MN10300_ALIGN)
+ {
+ bfd_vma adj = 1 << irel->r_addend;
+ bfd_vma aend = irel->r_offset;
+
+ aend = BFD_ALIGN (aend, 1 << irel->r_addend);
+ adj = 2 * adj - adj - 1;
+
+ /* Record the biggest adjustmnet. Skip any alignment at the
+ end of our section. */
+ if (align_gap_adjustment < adj
+ && aend < sec->output_section->vma + sec->output_offset + sec->size)
+ align_gap_adjustment = adj;
+ }
+ }
+
+ /* Walk through them looking for relaxing opportunities. */
+ irelend = internal_relocs + sec->reloc_count;
+ for (irel = internal_relocs; irel < irelend; irel++)
+ {
+ bfd_vma symval;
+ bfd_signed_vma jump_offset;
+ asection *sym_sec = NULL;
+ 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. */
+ if (!bfd_malloc_and_get_section (abfd, sec, &contents))
+ goto error_return;
+ }
+ }
+
+ /* Read this BFD's symbols if we haven't done so already. */
+ if (isymbuf == NULL && symtab_hdr->sh_info != 0)
+ {
+ isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
+ if (isymbuf == NULL)
+ isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
+ symtab_hdr->sh_info, 0,
+ NULL, NULL, NULL);
+ if (isymbuf == NULL)
+ 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;
+ const char *sym_name;
+ char *new_name;
+
+ /* A local symbol. */
+ isym = isymbuf + ELF32_R_SYM (irel->r_info);
+ if (isym->st_shndx == SHN_UNDEF)
+ sym_sec = bfd_und_section_ptr;
+ 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;
+ else
+ sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
+
+ sym_name = bfd_elf_string_from_elf_section (abfd,
+ symtab_hdr->sh_link,
+ isym->st_name);
+
+ if ((sym_sec->flags & SEC_MERGE)
+ && sym_sec->sec_info_type == SEC_INFO_TYPE_MERGE)
+ {
+ symval = isym->st_value;
+
+ /* GAS may reduce relocations against symbols in SEC_MERGE
+ sections to a relocation against the section symbol when
+ the original addend was zero. When the reloc is against
+ a section symbol we should include the addend in the
+ offset passed to _bfd_merged_section_offset, since the
+ location of interest is the original symbol. On the
+ other hand, an access to "sym+addend" where "sym" is not
+ a section symbol should not include the addend; Such an
+ access is presumed to be an offset from "sym"; The
+ location of interest is just "sym". */
+ if (ELF_ST_TYPE (isym->st_info) == STT_SECTION)
+ symval += irel->r_addend;
+
+ symval = _bfd_merged_section_offset (abfd, & sym_sec,
+ elf_section_data (sym_sec)->sec_info,
+ symval);
+
+ if (ELF_ST_TYPE (isym->st_info) != STT_SECTION)
+ symval += irel->r_addend;
+
+ symval += sym_sec->output_section->vma
+ + sym_sec->output_offset - irel->r_addend;
+ }
+ else
+ symval = (isym->st_value
+ + sym_sec->output_section->vma
+ + sym_sec->output_offset);
+
+ /* Tack on an ID so we can uniquely identify this
+ local symbol in the global hash table. */
+ new_name = bfd_malloc ((bfd_size_type) strlen (sym_name) + 10);
+ if (new_name == NULL)
+ goto error_return;
+ sprintf (new_name, "%s_%08x", sym_name, sym_sec->id);
+ 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;
+
+ /* Check for a reference to a discarded symbol and ignore it. */
+ if (h->root.root.u.def.section->output_section == NULL)
+ continue;
+
+ sym_sec = h->root.root.u.def.section->output_section;
+
+ 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
+ || ELF32_R_TYPE (irel->r_info) == (int) R_MN10300_PLT32)
+ {
+ bfd_vma value = symval;
+
+ if (ELF32_R_TYPE (irel->r_info) == (int) R_MN10300_PLT32
+ && h != NULL
+ && ELF_ST_VISIBILITY (h->root.other) != STV_INTERNAL
+ && ELF_ST_VISIBILITY (h->root.other) != STV_HIDDEN
+ && h->root.plt.offset != (bfd_vma) -1)
+ {
+ asection * splt;
+
+ splt = hash_table->root.splt;
+ value = ((splt->output_section->vma
+ + splt->output_offset
+ + h->root.plt.offset)
+ - (sec->output_section->vma
+ + sec->output_offset
+ + irel->r_offset));
+ }
+
+ /* 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;
+ elf_section_data (sec)->this_hdr.contents = contents;
+ symtab_hdr->contents = (unsigned char *) isymbuf;
+
+ /* 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 it's in the same section. */
+ if (sec->output_section == sym_sec->output_section)
+ jump_offset = 0x8001;
+ else
+ jump_offset = 0x7fff;
+
+ /* Account for jumps across alignment boundaries using
+ align_gap_adjustment. */
+ if ((bfd_signed_vma) value < jump_offset - (bfd_signed_vma) align_gap_adjustment
+ && ((bfd_signed_vma) value > -0x8000 + (bfd_signed_vma) align_gap_adjustment))
+ {
+ 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;
+ elf_section_data (sec)->this_hdr.contents = contents;
+ symtab_hdr->contents = (unsigned char *) isymbuf;
+
+ /* 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),
+ (ELF32_R_TYPE (irel->r_info)
+ == (int) R_MN10300_PLT32)
+ ? R_MN10300_PLT16 :
+ 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;
+ elf_section_data (sec)->this_hdr.contents = contents;
+ symtab_hdr->contents = (unsigned char *) isymbuf;
+
+ /* 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;
+ elf_section_data (sec)->this_hdr.contents = contents;
+ symtab_hdr->contents = (unsigned char *) isymbuf;
+
+ /* 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->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, isymbuf,
+ irel->r_offset + 1))
+ continue;
+
+ /* Note that we've changed the relocs, section contents, etc. */
+ elf_section_data (sec)->relocs = internal_relocs;
+ elf_section_data (sec)->this_hdr.contents = contents;
+ symtab_hdr->contents = (unsigned char *) isymbuf;
+
+ /* 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 24 immediate, displacement or absolute address
+ into a 8 immediate, displacement or absolute address. */
+ if (ELF32_R_TYPE (irel->r_info) == (int) R_MN10300_24)
+ {
+ bfd_vma value = symval;
+ value += irel->r_addend;
+
+ /* See if the value will fit in 8 bits. */
+ if ((long) value < 0x7f && (long) value > -0x80)
+ {
+ unsigned char code;
+
+ /* AM33 insns which have 24 operands are 6 bytes long and
+ will have 0xfd as the first byte. */
+
+ /* Get the first opcode. */
+ code = bfd_get_8 (abfd, contents + irel->r_offset - 3);
+
+ if (code == 0xfd)
+ {
+ /* Get the second opcode. */
+ code = bfd_get_8 (abfd, contents + irel->r_offset - 2);
+
+ /* We can not relax 0x6b, 0x7b, 0x8b, 0x9b as no 24bit
+ equivalent instructions exists. */
+ if (code != 0x6b && code != 0x7b
+ && code != 0x8b && code != 0x9b
+ && ((code & 0x0f) == 0x09 || (code & 0x0f) == 0x08
+ || (code & 0x0f) == 0x0a || (code & 0x0f) == 0x0b
+ || (code & 0x0f) == 0x0e))
+ {
+ /* 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 8bit value. This is currently over
+ conservative. */
+ if ((value & 0x80) == 0)
+ {
+ /* Note that we've changed the relocation contents,
+ etc. */
+ elf_section_data (sec)->relocs = internal_relocs;
+ elf_section_data (sec)->this_hdr.contents = contents;
+ symtab_hdr->contents = (unsigned char *) isymbuf;
+
+ /* Fix the opcode. */
+ bfd_put_8 (abfd, 0xfb, contents + irel->r_offset - 3);
+ 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_8);
+
+ /* 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;
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ /* 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
+ || ELF32_R_TYPE (irel->r_info) == (int) R_MN10300_GOT32
+ || ELF32_R_TYPE (irel->r_info) == (int) R_MN10300_GOTOFF32)
+ {
+ bfd_vma value = symval;
+
+ if (ELF32_R_TYPE (irel->r_info) != (int) R_MN10300_32)
+ {
+ asection * sgot;
+
+ sgot = hash_table->root.sgot;
+ if (ELF32_R_TYPE (irel->r_info) == (int) R_MN10300_GOT32)
+ {
+ value = sgot->output_offset;
+
+ if (h)
+ value += h->root.got.offset;
+ else
+ value += (elf_local_got_offsets
+ (abfd)[ELF32_R_SYM (irel->r_info)]);
+ }
+ else if (ELF32_R_TYPE (irel->r_info) == (int) R_MN10300_GOTOFF32)
+ value -= sgot->output_section->vma;
+ else if (ELF32_R_TYPE (irel->r_info) == (int) R_MN10300_GOTPC32)
+ value = (sgot->output_section->vma
+ - (sec->output_section->vma
+ + sec->output_offset
+ + irel->r_offset));
+ else
+ abort ();
+ }
+
+ value += irel->r_addend;
+
+ /* See if the value will fit in 24 bits.
+ We allow any 16bit match here. We prune those we can't
+ handle below. */
+ if ((long) value < 0x7fffff && (long) value > -0x800000)
+ {
+ unsigned char code;
+
+ /* AM33 insns which have 32bit operands are 7 bytes long and
+ will have 0xfe as the first byte. */
+
+ /* Get the first opcode. */
+ code = bfd_get_8 (abfd, contents + irel->r_offset - 3);
+
+ if (code == 0xfe)
+ {
+ /* Get the second opcode. */
+ code = bfd_get_8 (abfd, contents + irel->r_offset - 2);
+
+ /* All the am33 32 -> 24 relaxing possibilities. */
+ /* We can not relax 0x6b, 0x7b, 0x8b, 0x9b as no 24bit
+ equivalent instructions exists. */
+ if (code != 0x6b && code != 0x7b
+ && code != 0x8b && code != 0x9b
+ && (ELF32_R_TYPE (irel->r_info)
+ != (int) R_MN10300_GOTPC32)
+ && ((code & 0x0f) == 0x09 || (code & 0x0f) == 0x08
+ || (code & 0x0f) == 0x0a || (code & 0x0f) == 0x0b
+ || (code & 0x0f) == 0x0e))
+ {
+ /* 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. This is currently over
+ conservative. */
+ if ((value & 0x8000) == 0)
+ {
+ /* Note that we've changed the relocation contents,
+ etc. */
+ elf_section_data (sec)->relocs = internal_relocs;
+ elf_section_data (sec)->this_hdr.contents = contents;
+ symtab_hdr->contents = (unsigned char *) isymbuf;
+
+ /* Fix the opcode. */
+ bfd_put_8 (abfd, 0xfd, contents + irel->r_offset - 3);
+ 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),
+ (ELF32_R_TYPE (irel->r_info)
+ == (int) R_MN10300_GOTOFF32)
+ ? R_MN10300_GOTOFF24
+ : (ELF32_R_TYPE (irel->r_info)
+ == (int) R_MN10300_GOT32)
+ ? R_MN10300_GOT24 :
+ R_MN10300_24);
+
+ /* 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;
+ break;
+ }
+ }
+ }
+ }
+
+ /* 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;
+ elf_section_data (sec)->this_hdr.contents = contents;
+ symtab_hdr->contents = (unsigned char *) isymbuf;
+
+ /* 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),
+ (ELF32_R_TYPE (irel->r_info)
+ == (int) R_MN10300_GOTOFF32)
+ ? R_MN10300_GOTOFF16
+ : (ELF32_R_TYPE (irel->r_info)
+ == (int) R_MN10300_GOT32)
+ ? R_MN10300_GOT16
+ : (ELF32_R_TYPE (irel->r_info)
+ == (int) R_MN10300_GOTPC32)
+ ? R_MN10300_GOTPC16 :
+ 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;
+ elf_section_data (sec)->this_hdr.contents = contents;
+ symtab_hdr->contents = (unsigned char *) isymbuf;
+
+ 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),
+ (ELF32_R_TYPE (irel->r_info)
+ == (int) R_MN10300_GOTOFF32)
+ ? R_MN10300_GOTOFF16
+ : (ELF32_R_TYPE (irel->r_info)
+ == (int) R_MN10300_GOT32)
+ ? R_MN10300_GOT16
+ : (ELF32_R_TYPE (irel->r_info)
+ == (int) R_MN10300_GOTPC32)
+ ? R_MN10300_GOTPC16 :
+ 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:
+ /* sp-based offsets are zero-extended. */
+ if (code >= 0x90 && code <= 0x93
+ && (long) value < 0)
+ continue;
+
+ /* Note that we've changed the relocation contents, etc. */
+ elf_section_data (sec)->relocs = internal_relocs;
+ elf_section_data (sec)->this_hdr.contents = contents;
+ symtab_hdr->contents = (unsigned char *) isymbuf;
+
+ /* 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),
+ (ELF32_R_TYPE (irel->r_info)
+ == (int) R_MN10300_GOTOFF32)
+ ? R_MN10300_GOTOFF16
+ : (ELF32_R_TYPE (irel->r_info)
+ == (int) R_MN10300_GOT32)
+ ? R_MN10300_GOT16
+ : (ELF32_R_TYPE (irel->r_info)
+ == (int) R_MN10300_GOTPC32)
+ ? R_MN10300_GOTPC16 :
+ 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;
+
+ /* "mov imm16, an" zero-extends the immediate. */
+ if ((code & 0xfc) == 0xdc
+ && (long) value < 0)
+ continue;
+
+ /* Note that we've changed the relocation contents, etc. */
+ elf_section_data (sec)->relocs = internal_relocs;
+ elf_section_data (sec)->this_hdr.contents = contents;
+ symtab_hdr->contents = (unsigned char *) isymbuf;
+
+ 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),
+ (ELF32_R_TYPE (irel->r_info)
+ == (int) R_MN10300_GOTOFF32)
+ ? R_MN10300_GOTOFF16
+ : (ELF32_R_TYPE (irel->r_info)
+ == (int) R_MN10300_GOT32)
+ ? R_MN10300_GOT16
+ : (ELF32_R_TYPE (irel->r_info)
+ == (int) R_MN10300_GOTPC32)
+ ? R_MN10300_GOTPC16 :
+ 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 (d16,sp),an
+ mov (d32,sp),dn -> mov (d16,sp),dn
+ movbu (d32,sp),dn -> movbu (d16,sp),dn
+ movhu (d32,sp),dn -> movhu (d16,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 imm16,dn
+ or imm32,dn -> or imm16,dn
+ xor imm32,dn -> xor imm16,dn
+ btst imm32,dn -> btst imm16,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:
+ /* cmp imm16, an zero-extends the immediate. */
+ if (code == 0xdc
+ && (long) value < 0)
+ continue;
+
+ /* So do sp-based offsets. */
+ if (code >= 0xb0 && code <= 0xb3
+ && (long) value < 0)
+ continue;
+
+ /* Note that we've changed the relocation contents, etc. */
+ elf_section_data (sec)->relocs = internal_relocs;
+ elf_section_data (sec)->this_hdr.contents = contents;
+ symtab_hdr->contents = (unsigned char *) isymbuf;
+
+ /* 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),
+ (ELF32_R_TYPE (irel->r_info)
+ == (int) R_MN10300_GOTOFF32)
+ ? R_MN10300_GOTOFF16
+ : (ELF32_R_TYPE (irel->r_info)
+ == (int) R_MN10300_GOT32)
+ ? R_MN10300_GOT16
+ : (ELF32_R_TYPE (irel->r_info)
+ == (int) R_MN10300_GOTPC32)
+ ? R_MN10300_GOTPC16 :
+ 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;
+ elf_section_data (sec)->this_hdr.contents = contents;
+ symtab_hdr->contents = (unsigned char *) isymbuf;
+
+ /* 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),
+ (ELF32_R_TYPE (irel->r_info)
+ == (int) R_MN10300_GOT32)
+ ? R_MN10300_GOT16
+ : (ELF32_R_TYPE (irel->r_info)
+ == (int) R_MN10300_GOTOFF32)
+ ? R_MN10300_GOTOFF16
+ : (ELF32_R_TYPE (irel->r_info)
+ == (int) R_MN10300_GOTPC32)
+ ? R_MN10300_GOTPC16 :
+ 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 (isymbuf != NULL
+ && symtab_hdr->contents != (unsigned char *) isymbuf)
+ {
+ if (! link_info->keep_memory)
+ free (isymbuf);
+ else
+ {
+ /* Cache the symbols for elf_link_input_bfd. */
+ symtab_hdr->contents = (unsigned char *) isymbuf;
+ }
+ }
+
+ if (contents != NULL
+ && elf_section_data (sec)->this_hdr.contents != contents)
+ {
+ if (! link_info->keep_memory)
+ free (contents);
+ else
+ {
+ /* Cache the section contents for elf_link_input_bfd. */
+ elf_section_data (sec)->this_hdr.contents = contents;
+ }
+ }
+
+ if (internal_relocs != NULL
+ && elf_section_data (sec)->relocs != internal_relocs)
+ free (internal_relocs);
+
+ return TRUE;
+
+ error_return:
+ if (isymbuf != NULL
+ && symtab_hdr->contents != (unsigned char *) isymbuf)
+ free (isymbuf);
+ if (contents != NULL
+ && elf_section_data (section)->this_hdr.contents != contents)
+ free (contents);
+ if (internal_relocs != NULL
+ && elf_section_data (section)->relocs != internal_relocs)
+ free (internal_relocs);
+
+ 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 (bfd *output_bfd,
+ struct bfd_link_info *link_info,
+ struct bfd_link_order *link_order,
+ bfd_byte *data,
+ bfd_boolean relocatable,
+ 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;
+ Elf_Internal_Sym *isymbuf = NULL;
+
+ /* We only need to handle the case of relaxing, or of having a
+ particular set of section contents, specially. */
+ if (relocatable
+ || elf_section_data (input_section)->this_hdr.contents == NULL)
+ return bfd_generic_get_relocated_section_contents (output_bfd, link_info,
+ link_order, data,
+ relocatable,
+ symbols);
+
+ symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
+
+ memcpy (data, elf_section_data (input_section)->this_hdr.contents,
+ (size_t) input_section->size);
+
+ if ((input_section->flags & SEC_RELOC) != 0
+ && input_section->reloc_count > 0)
+ {
+ asection **secpp;
+ Elf_Internal_Sym *isym, *isymend;
+ bfd_size_type amt;
+
+ internal_relocs = _bfd_elf_link_read_relocs (input_bfd, input_section,
+ NULL, NULL, FALSE);
+ if (internal_relocs == NULL)
+ goto error_return;
+
+ if (symtab_hdr->sh_info != 0)
+ {
+ isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
+ if (isymbuf == NULL)
+ isymbuf = bfd_elf_get_elf_syms (input_bfd, symtab_hdr,
+ symtab_hdr->sh_info, 0,
+ NULL, NULL, NULL);
+ if (isymbuf == NULL)
+ goto error_return;
+ }
+
+ amt = symtab_hdr->sh_info;
+ amt *= sizeof (asection *);
+ sections = bfd_malloc (amt);
+ if (sections == NULL && amt != 0)
+ goto error_return;
+
+ isymend = isymbuf + symtab_hdr->sh_info;
+ for (isym = isymbuf, secpp = sections; isym < isymend; ++isym, ++secpp)
+ {
+ asection *isec;
+
+ if (isym->st_shndx == SHN_UNDEF)
+ isec = bfd_und_section_ptr;
+ 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
+ isec = bfd_section_from_elf_index (input_bfd, isym->st_shndx);
+
+ *secpp = isec;
+ }
+
+ if (! mn10300_elf_relocate_section (output_bfd, link_info, input_bfd,
+ input_section, data, internal_relocs,
+ isymbuf, sections))
+ goto error_return;
+
+ if (sections != NULL)
+ free (sections);
+ if (isymbuf != NULL && symtab_hdr->contents != (unsigned char *) isymbuf)
+ free (isymbuf);
+ if (internal_relocs != elf_section_data (input_section)->relocs)
+ free (internal_relocs);
+ }
+
+ return data;
+
+ error_return:
+ if (sections != NULL)
+ free (sections);
+ if (isymbuf != NULL && symtab_hdr->contents != (unsigned char *) isymbuf)
+ free (isymbuf);
+ if (internal_relocs != NULL
+ && internal_relocs != elf_section_data (input_section)->relocs)
+ free (internal_relocs);
+ 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 (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 == NULL)
+ ret = (struct elf32_mn10300_link_hash_entry *)
+ bfd_hash_allocate (table, sizeof (* ret));
+ if (ret == 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 != NULL)
+ {
+ ret->direct_calls = 0;
+ ret->stack_size = 0;
+ ret->movm_args = 0;
+ ret->movm_stack_size = 0;
+ ret->flags = 0;
+ ret->value = 0;
+ ret->tls_type = GOT_UNKNOWN;
+ }
+
+ return (struct bfd_hash_entry *) ret;
+}
+
+static void
+_bfd_mn10300_copy_indirect_symbol (struct bfd_link_info * info,
+ struct elf_link_hash_entry * dir,
+ struct elf_link_hash_entry * ind)
+{
+ struct elf32_mn10300_link_hash_entry * edir;
+ struct elf32_mn10300_link_hash_entry * eind;
+
+ edir = elf_mn10300_hash_entry (dir);
+ eind = elf_mn10300_hash_entry (ind);
+
+ if (ind->root.type == bfd_link_hash_indirect
+ && dir->got.refcount <= 0)
+ {
+ edir->tls_type = eind->tls_type;
+ eind->tls_type = GOT_UNKNOWN;
+ }
+ edir->direct_calls = eind->direct_calls;
+ edir->stack_size = eind->stack_size;
+ edir->movm_args = eind->movm_args;
+ edir->movm_stack_size = eind->movm_stack_size;
+ edir->flags = eind->flags;
+
+ _bfd_elf_link_hash_copy_indirect (info, dir, ind);
+}
+
+/* Destroy an mn10300 ELF linker hash table. */
+
+static void
+elf32_mn10300_link_hash_table_free (bfd *obfd)
+{
+ struct elf32_mn10300_link_hash_table *ret
+ = (struct elf32_mn10300_link_hash_table *) obfd->link.hash;
+
+ obfd->link.hash = &ret->static_hash_table->root.root;
+ _bfd_elf_link_hash_table_free (obfd);
+ obfd->is_linker_output = TRUE;
+ obfd->link.hash = &ret->root.root;
+ _bfd_elf_link_hash_table_free (obfd);
+}
+
+/* Create an mn10300 ELF linker hash table. */
+
+static struct bfd_link_hash_table *
+elf32_mn10300_link_hash_table_create (bfd *abfd)
+{
+ struct elf32_mn10300_link_hash_table *ret;
+ bfd_size_type amt = sizeof (* ret);
+
+ ret = bfd_zmalloc (amt);
+ if (ret == NULL)
+ return NULL;
+
+ amt = sizeof (struct elf_link_hash_table);
+ ret->static_hash_table = bfd_zmalloc (amt);
+ if (ret->static_hash_table == NULL)
+ {
+ free (ret);
+ return NULL;
+ }
+
+ if (!_bfd_elf_link_hash_table_init (&ret->static_hash_table->root, abfd,
+ elf32_mn10300_link_hash_newfunc,
+ sizeof (struct elf32_mn10300_link_hash_entry),
+ MN10300_ELF_DATA))
+ {
+ free (ret->static_hash_table);
+ free (ret);
+ return NULL;
+ }
+
+ abfd->is_linker_output = FALSE;
+ abfd->link.hash = NULL;
+ if (!_bfd_elf_link_hash_table_init (&ret->root, abfd,
+ elf32_mn10300_link_hash_newfunc,
+ sizeof (struct elf32_mn10300_link_hash_entry),
+ MN10300_ELF_DATA))
+ {
+ abfd->is_linker_output = TRUE;
+ abfd->link.hash = &ret->static_hash_table->root.root;
+ _bfd_elf_link_hash_table_free (abfd);
+ free (ret);
+ return NULL;
+ }
+ ret->root.root.hash_table_free = elf32_mn10300_link_hash_table_free;
+
+ ret->tls_ldm_got.offset = -1;
+
+ return & ret->root.root;
+}
+
+static unsigned long
+elf_mn10300_mach (flagword flags)
+{
+ switch (flags & EF_MN10300_MACH)
+ {
+ case E_MN10300_MACH_MN10300:
+ default:
+ return bfd_mach_mn10300;
+
+ case E_MN10300_MACH_AM33:
+ return bfd_mach_am33;
+
+ case E_MN10300_MACH_AM33_2:
+ return bfd_mach_am33_2;
+ }
+}
+
+/* The final processing done just before writing out a MN10300 ELF object
+ file. This gets the MN10300 architecture right based on the machine
+ number. */
+
+static void
+_bfd_mn10300_elf_final_write_processing (bfd *abfd,
+ bfd_boolean linker ATTRIBUTE_UNUSED)
+{
+ unsigned long val;
+
+ switch (bfd_get_mach (abfd))
+ {
+ default:
+ case bfd_mach_mn10300:
+ val = E_MN10300_MACH_MN10300;
+ break;
+
+ case bfd_mach_am33:
+ val = E_MN10300_MACH_AM33;
+ break;
+
+ case bfd_mach_am33_2:
+ val = E_MN10300_MACH_AM33_2;
+ break;
+ }
+
+ elf_elfheader (abfd)->e_flags &= ~ (EF_MN10300_MACH);
+ elf_elfheader (abfd)->e_flags |= val;
+}
+
+static bfd_boolean
+_bfd_mn10300_elf_object_p (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. */
+
+static bfd_boolean
+_bfd_mn10300_elf_merge_private_bfd_data (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 PLT0_ENTRY_SIZE 15
+#define PLT_ENTRY_SIZE 20
+#define PIC_PLT_ENTRY_SIZE 24
+
+static const bfd_byte elf_mn10300_plt0_entry[PLT0_ENTRY_SIZE] =
+{
+ 0xfc, 0xa0, 0, 0, 0, 0, /* mov (.got+8),a0 */
+ 0xfe, 0xe, 0x10, 0, 0, 0, 0, /* mov (.got+4),r1 */
+ 0xf0, 0xf4, /* jmp (a0) */
+};
+
+static const bfd_byte elf_mn10300_plt_entry[PLT_ENTRY_SIZE] =
+{
+ 0xfc, 0xa0, 0, 0, 0, 0, /* mov (nameN@GOT + .got),a0 */
+ 0xf0, 0xf4, /* jmp (a0) */
+ 0xfe, 8, 0, 0, 0, 0, 0, /* mov reloc-table-address,r0 */
+ 0xdc, 0, 0, 0, 0, /* jmp .plt0 */
+};
+
+static const bfd_byte elf_mn10300_pic_plt_entry[PIC_PLT_ENTRY_SIZE] =
+{
+ 0xfc, 0x22, 0, 0, 0, 0, /* mov (nameN@GOT,a2),a0 */
+ 0xf0, 0xf4, /* jmp (a0) */
+ 0xfe, 8, 0, 0, 0, 0, 0, /* mov reloc-table-address,r0 */
+ 0xf8, 0x22, 8, /* mov (8,a2),a0 */
+ 0xfb, 0xa, 0x1a, 4, /* mov (4,a2),r1 */
+ 0xf0, 0xf4, /* jmp (a0) */
+};
+
+/* Return size of the first PLT entry. */
+#define elf_mn10300_sizeof_plt0(info) \
+ (info->shared ? PIC_PLT_ENTRY_SIZE : PLT0_ENTRY_SIZE)
+
+/* Return size of a PLT entry. */
+#define elf_mn10300_sizeof_plt(info) \
+ (info->shared ? PIC_PLT_ENTRY_SIZE : PLT_ENTRY_SIZE)
+
+/* Return offset of the PLT0 address in an absolute PLT entry. */
+#define elf_mn10300_plt_plt0_offset(info) 16
+
+/* Return offset of the linker in PLT0 entry. */
+#define elf_mn10300_plt0_linker_offset(info) 2
+
+/* Return offset of the GOT id in PLT0 entry. */
+#define elf_mn10300_plt0_gotid_offset(info) 9
+
+/* Return offset of the temporary in PLT entry. */
+#define elf_mn10300_plt_temp_offset(info) 8
+
+/* Return offset of the symbol in PLT entry. */
+#define elf_mn10300_plt_symbol_offset(info) 2
+
+/* Return offset of the relocation in PLT entry. */
+#define elf_mn10300_plt_reloc_offset(info) 11
+
+/* The name of the dynamic interpreter. This is put in the .interp
+ section. */
+
+#define ELF_DYNAMIC_INTERPRETER "/lib/ld.so.1"
+
+/* Create dynamic sections when linking against a dynamic object. */
+
+static bfd_boolean
+_bfd_mn10300_elf_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
+{
+ flagword flags;
+ asection * s;
+ const struct elf_backend_data * bed = get_elf_backend_data (abfd);
+ struct elf32_mn10300_link_hash_table *htab = elf32_mn10300_hash_table (info);
+ int ptralign = 0;
+
+ switch (bed->s->arch_size)
+ {
+ case 32:
+ ptralign = 2;
+ break;
+
+ case 64:
+ ptralign = 3;
+ break;
+
+ default:
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+
+ /* 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);
+
+ s = bfd_make_section_anyway_with_flags (abfd,
+ (bed->default_use_rela_p
+ ? ".rela.plt" : ".rel.plt"),
+ flags | SEC_READONLY);
+ htab->root.srelplt = s;
+ if (s == NULL
+ || ! bfd_set_section_alignment (abfd, s, ptralign))
+ return FALSE;
+
+ if (! _bfd_mn10300_elf_create_got_section (abfd, info))
+ return FALSE;
+
+ if (bed->want_dynbss)
+ {
+ /* 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_anyway_with_flags (abfd, ".dynbss",
+ SEC_ALLOC | SEC_LINKER_CREATED);
+ if (s == NULL)
+ 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_anyway_with_flags (abfd,
+ (bed->default_use_rela_p
+ ? ".rela.bss" : ".rel.bss"),
+ flags | SEC_READONLY);
+ if (s == NULL
+ || ! bfd_set_section_alignment (abfd, s, ptralign))
+ 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 bfd_boolean
+_bfd_mn10300_elf_adjust_dynamic_symbol (struct bfd_link_info * info,
+ struct elf_link_hash_entry * h)
+{
+ struct elf32_mn10300_link_hash_table *htab = elf32_mn10300_hash_table (info);
+ bfd * dynobj;
+ asection * s;
+
+ dynobj = htab->root.dynobj;
+
+ /* Make sure we know what is going on here. */
+ BFD_ASSERT (dynobj != NULL
+ && (h->needs_plt
+ || h->u.weakdef != NULL
+ || (h->def_dynamic
+ && h->ref_regular
+ && !h->def_regular)));
+
+ /* 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->needs_plt)
+ {
+ if (! info->shared
+ && !h->def_dynamic
+ && !h->ref_dynamic)
+ {
+ /* This case can occur if we saw a PLT 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 REL32
+ reloc instead. */
+ BFD_ASSERT (h->needs_plt);
+ return TRUE;
+ }
+
+ /* Make sure this symbol is output as a dynamic symbol. */
+ if (h->dynindx == -1)
+ {
+ if (! bfd_elf_link_record_dynamic_symbol (info, h))
+ return FALSE;
+ }
+
+ s = htab->root.splt;
+ BFD_ASSERT (s != NULL);
+
+ /* If this is the first .plt entry, make room for the special
+ first entry. */
+ if (s->size == 0)
+ s->size += elf_mn10300_sizeof_plt0 (info);
+
+ /* 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->def_regular)
+ {
+ h->root.u.def.section = s;
+ h->root.u.def.value = s->size;
+ }
+
+ h->plt.offset = s->size;
+
+ /* Make room for this entry. */
+ s->size += elf_mn10300_sizeof_plt (info);
+
+ /* 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 = htab->root.sgotplt;
+ BFD_ASSERT (s != NULL);
+ s->size += 4;
+
+ /* We also need to make an entry in the .rela.plt section. */
+ s = bfd_get_linker_section (dynobj, ".rela.plt");
+ BFD_ASSERT (s != NULL);
+ s->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->u.weakdef != NULL)
+ {
+ BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
+ || h->u.weakdef->root.type == bfd_link_hash_defweak);
+ h->root.u.def.section = h->u.weakdef->root.u.def.section;
+ h->root.u.def.value = h->u.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;
+
+ /* If there are no references to this symbol that do not use the
+ GOT, we don't need to generate a copy reloc. */
+ if (!h->non_got_ref)
+ 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_linker_section (dynobj, ".dynbss");
+ BFD_ASSERT (s != NULL);
+
+ /* We must generate a R_MN10300_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 && h->size != 0)
+ {
+ asection * srel;
+
+ srel = bfd_get_linker_section (dynobj, ".rela.bss");
+ BFD_ASSERT (srel != NULL);
+ srel->size += sizeof (Elf32_External_Rela);
+ h->needs_copy = 1;
+ }
+
+ return _bfd_elf_adjust_dynamic_copy (h, s);
+}
+
+/* Set the sizes of the dynamic sections. */
+
+static bfd_boolean
+_bfd_mn10300_elf_size_dynamic_sections (bfd * output_bfd,
+ struct bfd_link_info * info)
+{
+ struct elf32_mn10300_link_hash_table *htab = elf32_mn10300_hash_table (info);
+ bfd * dynobj;
+ asection * s;
+ bfd_boolean plt;
+ bfd_boolean relocs;
+ bfd_boolean reltext;
+
+ dynobj = htab->root.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->executable)
+ {
+ s = bfd_get_linker_section (dynobj, ".interp");
+ BFD_ASSERT (s != NULL);
+ s->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 = htab->root.sgot;
+ if (s != NULL)
+ s->size = 0;
+ }
+
+ if (htab->tls_ldm_got.refcount > 0)
+ {
+ s = bfd_get_linker_section (dynobj, ".rela.got");
+ BFD_ASSERT (s != NULL);
+ s->size += sizeof (Elf32_External_Rela);
+ }
+
+ /* 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;
+
+ 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);
+
+ if (streq (name, ".plt"))
+ {
+ /* Remember whether there is a PLT. */
+ plt = s->size != 0;
+ }
+ else if (CONST_STRNEQ (name, ".rela"))
+ {
+ if (s->size != 0)
+ {
+ asection * target;
+
+ /* Remember whether there are any reloc sections other
+ than .rela.plt. */
+ if (! streq (name, ".rela.plt"))
+ {
+ 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 .rela.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 + 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 (! CONST_STRNEQ (name, ".got")
+ && ! streq (name, ".dynbss"))
+ /* It's not one of our sections, so don't allocate space. */
+ continue;
+
+ if (s->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. */
+ s->flags |= SEC_EXCLUDE;
+ continue;
+ }
+
+ if ((s->flags & SEC_HAS_CONTENTS) == 0)
+ continue;
+
+ /* Allocate memory for the section contents. We use bfd_zalloc
+ here in case unused entries are not reclaimed before the
+ section's contents are written out. This should not happen,
+ but this way if it does, we get a R_MN10300_NONE reloc
+ instead of garbage. */
+ s->contents = bfd_zalloc (dynobj, s->size);
+ if (s->contents == NULL)
+ return FALSE;
+ }
+
+ if (elf_hash_table (info)->dynamic_sections_created)
+ {
+ /* Add some entries to the .dynamic section. We fill in the
+ values later, in _bfd_mn10300_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_elf_add_dynamic_entry (info, DT_DEBUG, 0))
+ return FALSE;
+ }
+
+ if (plt)
+ {
+ if (!_bfd_elf_add_dynamic_entry (info, DT_PLTGOT, 0)
+ || !_bfd_elf_add_dynamic_entry (info, DT_PLTRELSZ, 0)
+ || !_bfd_elf_add_dynamic_entry (info, DT_PLTREL, DT_RELA)
+ || !_bfd_elf_add_dynamic_entry (info, DT_JMPREL, 0))
+ return FALSE;
+ }
+
+ if (relocs)
+ {
+ if (!_bfd_elf_add_dynamic_entry (info, DT_RELA, 0)
+ || !_bfd_elf_add_dynamic_entry (info, DT_RELASZ, 0)
+ || !_bfd_elf_add_dynamic_entry (info, DT_RELAENT,
+ sizeof (Elf32_External_Rela)))
+ return FALSE;
+ }
+
+ if (reltext)
+ {
+ if (!_bfd_elf_add_dynamic_entry (info, DT_TEXTREL, 0))
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+/* Finish up dynamic symbol handling. We set the contents of various
+ dynamic sections here. */
+
+static bfd_boolean
+_bfd_mn10300_elf_finish_dynamic_symbol (bfd * output_bfd,
+ struct bfd_link_info * info,
+ struct elf_link_hash_entry * h,
+ Elf_Internal_Sym * sym)
+{
+ struct elf32_mn10300_link_hash_table *htab = elf32_mn10300_hash_table (info);
+ bfd * dynobj;
+
+ dynobj = htab->root.dynobj;
+
+ if (h->plt.offset != (bfd_vma) -1)
+ {
+ asection * splt;
+ asection * sgot;
+ asection * srel;
+ bfd_vma plt_index;
+ bfd_vma got_offset;
+ Elf_Internal_Rela rel;
+
+ /* This symbol has an entry in the procedure linkage table. Set
+ it up. */
+
+ BFD_ASSERT (h->dynindx != -1);
+
+ splt = htab->root.splt;
+ sgot = htab->root.sgotplt;
+ srel = bfd_get_linker_section (dynobj, ".rela.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 - elf_mn10300_sizeof_plt0 (info))
+ / elf_mn10300_sizeof_plt (info));
+
+ /* 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_mn10300_plt_entry,
+ elf_mn10300_sizeof_plt (info));
+ bfd_put_32 (output_bfd,
+ (sgot->output_section->vma
+ + sgot->output_offset
+ + got_offset),
+ (splt->contents + h->plt.offset
+ + elf_mn10300_plt_symbol_offset (info)));
+
+ bfd_put_32 (output_bfd,
+ (1 - h->plt.offset - elf_mn10300_plt_plt0_offset (info)),
+ (splt->contents + h->plt.offset
+ + elf_mn10300_plt_plt0_offset (info)));
+ }
+ else
+ {
+ memcpy (splt->contents + h->plt.offset, elf_mn10300_pic_plt_entry,
+ elf_mn10300_sizeof_plt (info));
+
+ bfd_put_32 (output_bfd, got_offset,
+ (splt->contents + h->plt.offset
+ + elf_mn10300_plt_symbol_offset (info)));
+ }
+
+ bfd_put_32 (output_bfd, plt_index * sizeof (Elf32_External_Rela),
+ (splt->contents + h->plt.offset
+ + elf_mn10300_plt_reloc_offset (info)));
+
+ /* Fill in the entry in the global offset table. */
+ bfd_put_32 (output_bfd,
+ (splt->output_section->vma
+ + splt->output_offset
+ + h->plt.offset
+ + elf_mn10300_plt_temp_offset (info)),
+ sgot->contents + got_offset);
+
+ /* Fill in the entry in the .rela.plt section. */
+ rel.r_offset = (sgot->output_section->vma
+ + sgot->output_offset
+ + got_offset);
+ rel.r_info = ELF32_R_INFO (h->dynindx, R_MN10300_JMP_SLOT);
+ rel.r_addend = 0;
+ bfd_elf32_swap_reloca_out (output_bfd, &rel,
+ (bfd_byte *) ((Elf32_External_Rela *) srel->contents
+ + plt_index));
+
+ if (!h->def_regular)
+ /* 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_Rela rel;
+
+ /* This symbol has an entry in the global offset table. Set it up. */
+ sgot = htab->root.sgot;
+ srel = bfd_get_linker_section (dynobj, ".rela.got");
+ BFD_ASSERT (sgot != NULL && srel != NULL);
+
+ rel.r_offset = (sgot->output_section->vma
+ + sgot->output_offset
+ + (h->got.offset & ~1));
+
+ switch (elf_mn10300_hash_entry (h)->tls_type)
+ {
+ case GOT_TLS_GD:
+ bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents + h->got.offset);
+ bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents + h->got.offset + 4);
+ rel.r_info = ELF32_R_INFO (h->dynindx, R_MN10300_TLS_DTPMOD);
+ rel.r_addend = 0;
+ bfd_elf32_swap_reloca_out (output_bfd, & rel,
+ (bfd_byte *) ((Elf32_External_Rela *) srel->contents
+ + srel->reloc_count));
+ ++ srel->reloc_count;
+ rel.r_info = ELF32_R_INFO (h->dynindx, R_MN10300_TLS_DTPOFF);
+ rel.r_offset += 4;
+ rel.r_addend = 0;
+ break;
+
+ case GOT_TLS_IE:
+ /* We originally stored the addend in the GOT, but at this
+ point, we want to move it to the reloc instead as that's
+ where the dynamic linker wants it. */
+ rel.r_addend = bfd_get_32 (output_bfd, sgot->contents + h->got.offset);
+ bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents + h->got.offset);
+ if (h->dynindx == -1)
+ rel.r_info = ELF32_R_INFO (0, R_MN10300_TLS_TPOFF);
+ else
+ rel.r_info = ELF32_R_INFO (h->dynindx, R_MN10300_TLS_TPOFF);
+ break;
+
+ default:
+ /* 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->def_regular)
+ {
+ rel.r_info = ELF32_R_INFO (0, R_MN10300_RELATIVE);
+ rel.r_addend = (h->root.u.def.value
+ + h->root.u.def.section->output_section->vma
+ + h->root.u.def.section->output_offset);
+ }
+ else
+ {
+ bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents + h->got.offset);
+ rel.r_info = ELF32_R_INFO (h->dynindx, R_MN10300_GLOB_DAT);
+ rel.r_addend = 0;
+ }
+ }
+
+ if (ELF32_R_TYPE (rel.r_info) != R_MN10300_NONE)
+ {
+ bfd_elf32_swap_reloca_out (output_bfd, &rel,
+ (bfd_byte *) ((Elf32_External_Rela *) srel->contents
+ + srel->reloc_count));
+ ++ srel->reloc_count;
+ }
+ }
+
+ if (h->needs_copy)
+ {
+ asection * s;
+ Elf_Internal_Rela 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_linker_section (dynobj, ".rela.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_MN10300_COPY);
+ rel.r_addend = 0;
+ bfd_elf32_swap_reloca_out (output_bfd, & rel,
+ (bfd_byte *) ((Elf32_External_Rela *) s->contents
+ + s->reloc_count));
+ ++ s->reloc_count;
+ }
+
+ /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute. */
+ if (h == elf_hash_table (info)->hdynamic
+ || h == elf_hash_table (info)->hgot)
+ sym->st_shndx = SHN_ABS;
+
+ return TRUE;
+}
+
+/* Finish up the dynamic sections. */
+
+static bfd_boolean
+_bfd_mn10300_elf_finish_dynamic_sections (bfd * output_bfd,
+ struct bfd_link_info * info)
+{
+ bfd * dynobj;
+ asection * sgot;
+ asection * sdyn;
+ struct elf32_mn10300_link_hash_table *htab = elf32_mn10300_hash_table (info);
+
+ dynobj = htab->root.dynobj;
+ sgot = htab->root.sgotplt;
+ BFD_ASSERT (sgot != NULL);
+ sdyn = bfd_get_linker_section (dynobj, ".dynamic");
+
+ if (elf_hash_table (info)->dynamic_sections_created)
+ {
+ asection * splt;
+ Elf32_External_Dyn * dyncon;
+ Elf32_External_Dyn * dynconend;
+
+ BFD_ASSERT (sdyn != NULL);
+
+ dyncon = (Elf32_External_Dyn *) sdyn->contents;
+ dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->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);
+ dyn.d_un.d_val = s->size;
+ bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
+ break;
+
+ case DT_RELASZ:
+ /* My reading of the SVR4 ABI indicates that the
+ procedure linkage table relocs (DT_JMPREL) should be
+ included in the overall relocs (DT_RELA). This is
+ what Solaris does. However, UnixWare can not handle
+ that case. 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)
+ dyn.d_un.d_val -= s->size;
+ bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
+ break;
+ }
+ }
+
+ /* Fill in the first entry in the procedure linkage table. */
+ splt = htab->root.splt;
+ if (splt && splt->size > 0)
+ {
+ if (info->shared)
+ {
+ memcpy (splt->contents, elf_mn10300_pic_plt_entry,
+ elf_mn10300_sizeof_plt (info));
+ }
+ else
+ {
+ memcpy (splt->contents, elf_mn10300_plt0_entry, PLT0_ENTRY_SIZE);
+ bfd_put_32 (output_bfd,
+ sgot->output_section->vma + sgot->output_offset + 4,
+ splt->contents + elf_mn10300_plt0_gotid_offset (info));
+ bfd_put_32 (output_bfd,
+ sgot->output_section->vma + sgot->output_offset + 8,
+ splt->contents + elf_mn10300_plt0_linker_offset (info));
+ }
+
+ /* 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;
+
+ /* UnixWare sets the entsize of .plt to 4, but this is incorrect
+ as it means that the size of the PLT0 section (15 bytes) is not
+ a multiple of the sh_entsize. Some ELF tools flag this as an
+ error. We could pad PLT0 to 16 bytes, but that would introduce
+ compatibilty issues with previous toolchains, so instead we
+ just set the entry size to 1. */
+ elf_section_data (splt->output_section)->this_hdr.sh_entsize = 1;
+ }
+ }
+
+ /* Fill in the first three entries in the global offset table. */
+ if (sgot->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;
+}
+
+/* Classify relocation types, such that combreloc can sort them
+ properly. */
+
+static enum elf_reloc_type_class
+_bfd_mn10300_elf_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ const asection *rel_sec ATTRIBUTE_UNUSED,
+ const Elf_Internal_Rela *rela)
+{
+ switch ((int) ELF32_R_TYPE (rela->r_info))
+ {
+ case R_MN10300_RELATIVE: return reloc_class_relative;
+ case R_MN10300_JMP_SLOT: return reloc_class_plt;
+ case R_MN10300_COPY: return reloc_class_copy;
+ default: return reloc_class_normal;
+ }
+}
+
+/* Allocate space for an MN10300 extension to the bfd elf data structure. */
+
+static bfd_boolean
+mn10300_elf_mkobject (bfd *abfd)
+{
+ return bfd_elf_allocate_object (abfd, sizeof (struct elf_mn10300_obj_tdata),
+ MN10300_ELF_DATA);
+}
+
+#define bfd_elf32_mkobject mn10300_elf_mkobject
+
+#ifndef ELF_ARCH
+#define TARGET_LITTLE_SYM mn10300_elf32_vec
+#define TARGET_LITTLE_NAME "elf32-mn10300"
+#define ELF_ARCH bfd_arch_mn10300
+#define ELF_TARGET_ID MN10300_ELF_DATA
+#define ELF_MACHINE_CODE EM_MN10300
+#define ELF_MACHINE_ALT1 EM_CYGNUS_MN10300
+#define ELF_MAXPAGESIZE 0x1000
+#endif
+
+#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_rela_normal 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
+
+#ifndef elf_symbol_leading_char
+#define elf_symbol_leading_char '_'
+#endif
+
+/* 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
+
+#define elf_backend_can_gc_sections 1
+#define elf_backend_create_dynamic_sections \
+ _bfd_mn10300_elf_create_dynamic_sections
+#define elf_backend_adjust_dynamic_symbol \
+ _bfd_mn10300_elf_adjust_dynamic_symbol
+#define elf_backend_size_dynamic_sections \
+ _bfd_mn10300_elf_size_dynamic_sections
+#define elf_backend_omit_section_dynsym \
+ ((bfd_boolean (*) (bfd *, struct bfd_link_info *, asection *)) bfd_true)
+#define elf_backend_finish_dynamic_symbol \
+ _bfd_mn10300_elf_finish_dynamic_symbol
+#define elf_backend_finish_dynamic_sections \
+ _bfd_mn10300_elf_finish_dynamic_sections
+#define elf_backend_copy_indirect_symbol \
+ _bfd_mn10300_copy_indirect_symbol
+#define elf_backend_reloc_type_class \
+ _bfd_mn10300_elf_reloc_type_class
+
+#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
+
+#include "elf32-target.h"
diff --git a/bfd/elf-nacl.c b/bfd/elf-nacl.c
new file mode 100644
index 0000000..b6c9dc2
--- /dev/null
+++ b/bfd/elf-nacl.c
@@ -0,0 +1,355 @@
+/* Native Client support for ELF
+ Copyright (C) 2012-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public 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 "bfd.h"
+#include "libbfd.h"
+#include "elf-bfd.h"
+#include "elf-nacl.h"
+#include "elf/common.h"
+#include "elf/internal.h"
+
+static bfd_boolean
+segment_executable (struct elf_segment_map *seg)
+{
+ if (seg->p_flags_valid)
+ return (seg->p_flags & PF_X) != 0;
+ else
+ {
+ /* The p_flags value has not been computed yet,
+ so we have to look through the sections. */
+ unsigned int i;
+ for (i = 0; i < seg->count; ++i)
+ if (seg->sections[i]->flags & SEC_CODE)
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/* Determine if this segment is eligible to receive the file and program
+ headers. It must be read-only and non-executable.
+ Its first section must start far enough past the page boundary to
+ allow space for the headers. */
+static bfd_boolean
+segment_eligible_for_headers (struct elf_segment_map *seg,
+ bfd_vma minpagesize, bfd_vma sizeof_headers)
+{
+ unsigned int i;
+ if (seg->count == 0 || seg->sections[0]->lma % minpagesize < sizeof_headers)
+ return FALSE;
+ for (i = 0; i < seg->count; ++i)
+ {
+ if ((seg->sections[i]->flags & (SEC_CODE|SEC_READONLY)) != SEC_READONLY)
+ return FALSE;
+ }
+ return TRUE;
+}
+
+
+/* We permute the segment_map to get BFD to do the file layout we want:
+ The first non-executable PT_LOAD segment appears first in the file
+ and contains the ELF file header and phdrs. */
+bfd_boolean
+nacl_modify_segment_map (bfd *abfd, struct bfd_link_info *info)
+{
+ const struct elf_backend_data *const bed = get_elf_backend_data (abfd);
+ struct elf_segment_map **m = &elf_seg_map (abfd);
+ struct elf_segment_map **first_load = NULL;
+ struct elf_segment_map **last_load = NULL;
+ bfd_boolean moved_headers = FALSE;
+ int sizeof_headers;
+
+ if (info != NULL && info->user_phdrs)
+ /* The linker script used PHDRS explicitly, so don't change what the
+ user asked for. */
+ return TRUE;
+
+ if (info != NULL)
+ /* We're doing linking, so evalute SIZEOF_HEADERS as in a linker script. */
+ sizeof_headers = bfd_sizeof_headers (abfd, info);
+ else
+ {
+ /* We're not doing linking, so this is objcopy or suchlike.
+ We just need to collect the size of the existing headers. */
+ struct elf_segment_map *seg;
+ sizeof_headers = bed->s->sizeof_ehdr;
+ for (seg = *m; seg != NULL; seg = seg->next)
+ sizeof_headers += bed->s->sizeof_phdr;
+ }
+
+ while (*m != NULL)
+ {
+ struct elf_segment_map *seg = *m;
+
+ if (seg->p_type == PT_LOAD)
+ {
+ bfd_boolean executable = segment_executable (seg);
+
+ if (executable
+ && seg->count > 0
+ && seg->sections[0]->vma % bed->minpagesize == 0)
+ {
+ asection *lastsec = seg->sections[seg->count - 1];
+ bfd_vma end = lastsec->vma + lastsec->size;
+ if (end % bed->minpagesize != 0)
+ {
+ /* This is an executable segment that starts on a page
+ boundary but does not end on a page boundary. Fill
+ it out to a whole page with code fill (the tail of
+ the segment will not be within any section). Thus
+ the entire code segment can be mapped from the file
+ as whole pages and that mapping will contain only
+ valid instructions.
+
+ To accomplish this, we must fake out the code in
+ assign_file_positions_for_load_sections (elf.c) so
+ that it advances past the rest of the final page,
+ rather than trying to put the next (unaligned, or
+ unallocated) section. We do this by appending a
+ dummy section record to this element in the segment
+ map. No such output section ever actually exists,
+ but this gets the layout logic to advance the file
+ positions past this partial page. Since we are
+ lying to BFD like this, nothing will ever know to
+ write the section contents. So we do that by hand
+ after the fact, in nacl_final_write_processing, below. */
+
+ struct elf_segment_map *newseg;
+ asection *sec;
+ struct bfd_elf_section_data *secdata;
+
+ BFD_ASSERT (!seg->p_size_valid);
+
+ secdata = bfd_zalloc (abfd, sizeof *secdata);
+ if (secdata == NULL)
+ return FALSE;
+
+ sec = bfd_zalloc (abfd, sizeof *sec);
+ if (sec == NULL)
+ return FALSE;
+
+ /* Fill in only the fields that actually affect the logic
+ in assign_file_positions_for_load_sections. */
+ sec->vma = end;
+ sec->lma = lastsec->lma + lastsec->size;
+ sec->size = bed->minpagesize - (end % bed->minpagesize);
+ sec->flags = (SEC_ALLOC | SEC_LOAD
+ | SEC_READONLY | SEC_CODE | SEC_LINKER_CREATED);
+ sec->used_by_bfd = secdata;
+
+ secdata->this_hdr.sh_type = SHT_PROGBITS;
+ secdata->this_hdr.sh_flags = SHF_ALLOC | SHF_EXECINSTR;
+ secdata->this_hdr.sh_addr = sec->vma;
+ secdata->this_hdr.sh_size = sec->size;
+
+ newseg = bfd_alloc (abfd,
+ sizeof *newseg + ((seg->count + 1)
+ * sizeof (asection *)));
+ if (newseg == NULL)
+ return FALSE;
+ memcpy (newseg, seg,
+ sizeof *newseg + (seg->count * sizeof (asection *)));
+ newseg->sections[newseg->count++] = sec;
+ *m = seg = newseg;
+ }
+ }
+
+ /* First, we're just finding the earliest PT_LOAD.
+ By the normal rules, this will be the lowest-addressed one.
+ We only have anything interesting to do if it's executable. */
+ last_load = m;
+ if (first_load == NULL)
+ {
+ if (!executable)
+ goto next;
+ first_load = m;
+ }
+ /* Now that we've noted the first PT_LOAD, we're looking for
+ the first non-executable PT_LOAD with a nonempty p_filesz. */
+ else if (!moved_headers
+ && segment_eligible_for_headers (seg, bed->minpagesize,
+ sizeof_headers))
+ {
+ /* This is the one we were looking for!
+
+ First, clear the flags on previous segments that
+ say they include the file header and phdrs. */
+ struct elf_segment_map *prevseg;
+ for (prevseg = *first_load;
+ prevseg != seg;
+ prevseg = prevseg->next)
+ if (prevseg->p_type == PT_LOAD)
+ {
+ prevseg->includes_filehdr = 0;
+ prevseg->includes_phdrs = 0;
+ }
+
+ /* This segment will include those headers instead. */
+ seg->includes_filehdr = 1;
+ seg->includes_phdrs = 1;
+
+ moved_headers = TRUE;
+ }
+ }
+
+ next:
+ m = &seg->next;
+ }
+
+ if (first_load != last_load && moved_headers)
+ {
+ /* Now swap the first and last PT_LOAD segments'
+ positions in segment_map. */
+ struct elf_segment_map *first = *first_load;
+ struct elf_segment_map *last = *last_load;
+ *first_load = first->next;
+ first->next = last->next;
+ last->next = first;
+ }
+
+ return TRUE;
+}
+
+/* After nacl_modify_segment_map has done its work, the file layout has
+ been done as we wanted. But the PT_LOAD phdrs are no longer in the
+ proper order for the ELF rule that they must appear in ascending address
+ order. So find the two segments we swapped before, and swap them back. */
+bfd_boolean
+nacl_modify_program_headers (bfd *abfd, struct bfd_link_info *info)
+{
+ struct elf_segment_map **m = &elf_seg_map (abfd);
+ Elf_Internal_Phdr *phdr = elf_tdata (abfd)->phdr;
+ Elf_Internal_Phdr *p = phdr;
+
+ if (info != NULL && info->user_phdrs)
+ /* The linker script used PHDRS explicitly, so don't change what the
+ user asked for. */
+ return TRUE;
+
+ /* Find the PT_LOAD that contains the headers (should be the first). */
+ while (*m != NULL)
+ {
+ if ((*m)->p_type == PT_LOAD && (*m)->includes_filehdr)
+ break;
+
+ m = &(*m)->next;
+ ++p;
+ }
+
+ if (*m != NULL)
+ {
+ struct elf_segment_map **first_load_seg = m;
+ Elf_Internal_Phdr *first_load_phdr = p;
+ struct elf_segment_map **next_load_seg = NULL;
+ Elf_Internal_Phdr *next_load_phdr = NULL;
+
+ /* Now move past that first one and find the PT_LOAD that should be
+ before it by address order. */
+
+ m = &(*m)->next;
+ ++p;
+
+ while (*m != NULL)
+ {
+ if (p->p_type == PT_LOAD && p->p_vaddr < first_load_phdr->p_vaddr)
+ {
+ next_load_seg = m;
+ next_load_phdr = p;
+ break;
+ }
+
+ m = &(*m)->next;
+ ++p;
+ }
+
+ /* Swap their positions in the segment_map back to how they used to be.
+ The phdrs have already been set up by now, so we have to slide up
+ the earlier ones to insert the one that should be first. */
+ if (next_load_seg != NULL)
+ {
+ Elf_Internal_Phdr move_phdr;
+ struct elf_segment_map *first_seg = *first_load_seg;
+ struct elf_segment_map *next_seg = *next_load_seg;
+ struct elf_segment_map *first_next = first_seg->next;
+ struct elf_segment_map *next_next = next_seg->next;
+
+ if (next_load_seg == &first_seg->next)
+ {
+ *first_load_seg = next_seg;
+ next_seg->next = first_seg;
+ first_seg->next = next_next;
+ }
+ else
+ {
+ *first_load_seg = first_next;
+ *next_load_seg = next_next;
+
+ first_seg->next = *next_load_seg;
+ *next_load_seg = first_seg;
+
+ next_seg->next = *first_load_seg;
+ *first_load_seg = next_seg;
+ }
+
+ move_phdr = *next_load_phdr;
+ memmove (first_load_phdr + 1, first_load_phdr,
+ (next_load_phdr - first_load_phdr) * sizeof move_phdr);
+ *first_load_phdr = move_phdr;
+ }
+ }
+
+ return TRUE;
+}
+
+void
+nacl_final_write_processing (bfd *abfd, bfd_boolean linker ATTRIBUTE_UNUSED)
+{
+ struct elf_segment_map *seg;
+ for (seg = elf_seg_map (abfd); seg != NULL; seg = seg->next)
+ if (seg->p_type == PT_LOAD
+ && seg->count > 1
+ && seg->sections[seg->count - 1]->owner == NULL)
+ {
+ /* This is a fake section added in nacl_modify_segment_map, above.
+ It's not a real BFD section, so nothing wrote its contents.
+ Now write out its contents. */
+
+ asection *sec = seg->sections[seg->count - 1];
+ char *fill;
+
+ BFD_ASSERT (sec->flags & SEC_LINKER_CREATED);
+ BFD_ASSERT (sec->flags & SEC_CODE);
+ BFD_ASSERT (sec->size > 0);
+
+ fill = abfd->arch_info->fill (sec->size, bfd_big_endian (abfd), TRUE);
+
+ if (fill == NULL
+ || bfd_seek (abfd, sec->filepos, SEEK_SET) != 0
+ || bfd_bwrite (fill, sec->size, abfd) != sec->size)
+ {
+ /* We don't have a proper way to report an error here. So
+ instead fudge things so that elf_write_shdrs_and_ehdr will
+ fail. */
+ elf_elfheader (abfd)->e_shoff = (file_ptr) -1;
+ }
+
+ free (fill);
+ }
+}
diff --git a/bfd/elf-nacl.h b/bfd/elf-nacl.h
new file mode 100644
index 0000000..ec3f449
--- /dev/null
+++ b/bfd/elf-nacl.h
@@ -0,0 +1,25 @@
+/* Native Client support for ELF
+ Copyright (C) 2012-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public 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"
+
+bfd_boolean nacl_modify_segment_map (bfd *, struct bfd_link_info *);
+bfd_boolean nacl_modify_program_headers (bfd *, struct bfd_link_info *);
+void nacl_final_write_processing (bfd *, bfd_boolean linker);
diff --git a/bfd/elf-s390-common.c b/bfd/elf-s390-common.c
new file mode 100644
index 0000000..c74883c
--- /dev/null
+++ b/bfd/elf-s390-common.c
@@ -0,0 +1,244 @@
+/* IBM S/390-specific support for ELF 32 and 64 bit functions
+ Copyright (C) 2000-2014 Free Software Foundation, Inc.
+ Contributed by Andreas Krebbel.
+
+ This file is part of BFD, the Binary File Descriptor library.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
+ 02110-1301, USA. */
+
+
+/* Return TRUE if H is an IFUNC symbol. Simply checking for the
+ symbol type might not be enough since it might get changed to
+ STT_FUNC for pointer equality reasons. */
+static inline bfd_boolean
+s390_is_ifunc_symbol_p (struct elf_link_hash_entry *h)
+{
+ struct elf_s390_link_hash_entry *eh = (struct elf_s390_link_hash_entry*)h;
+ return h->type == STT_GNU_IFUNC || eh->ifunc_resolver_address != 0;
+}
+
+/* Create sections needed by STT_GNU_IFUNC symbol. */
+
+static bfd_boolean
+s390_elf_create_ifunc_sections (bfd *abfd, struct bfd_link_info *info)
+{
+ flagword flags;
+ asection *s;
+ const struct elf_backend_data *bed = get_elf_backend_data (abfd);
+ struct elf_link_hash_table *htab = elf_hash_table (info);
+
+ if (htab->iplt != NULL)
+ return TRUE;
+
+ flags = bed->dynamic_sec_flags;
+
+ if (info->shared)
+ {
+ s = bfd_make_section_with_flags (abfd, ".rela.ifunc",
+ flags | SEC_READONLY);
+ if (s == NULL
+ || ! bfd_set_section_alignment (abfd, s,
+ bed->s->log_file_align))
+ return FALSE;
+ htab->irelifunc = s;
+ }
+
+ /* Create .iplt, .rel[a].iplt, and .igot.plt. */
+ s = bfd_make_section_with_flags (abfd, ".iplt",
+ flags | SEC_CODE | SEC_READONLY);
+ if (s == NULL
+ || ! bfd_set_section_alignment (abfd, s, bed->plt_alignment))
+ return FALSE;
+ htab->iplt = s;
+
+ s = bfd_make_section_with_flags (abfd, ".rela.iplt", flags | SEC_READONLY);
+ if (s == NULL
+ || ! bfd_set_section_alignment (abfd, s,
+ bed->s->log_file_align))
+ return FALSE;
+ htab->irelplt = s;
+
+ s = bfd_make_section_with_flags (abfd, ".igot.plt", flags);
+ if (s == NULL
+ || !bfd_set_section_alignment (abfd, s,
+ bed->s->log_file_align))
+ return FALSE;
+ htab->igotplt = s;
+
+ return TRUE;
+}
+
+
+/* Allocate space in .plt, .got and associated reloc sections for
+ dynamic relocs against a STT_GNU_IFUNC symbol definition. */
+
+static bfd_boolean
+s390_elf_allocate_ifunc_dyn_relocs (struct bfd_link_info *info,
+ struct elf_link_hash_entry *h,
+ struct elf_dyn_relocs **head)
+{
+ struct elf_dyn_relocs *p;
+ struct elf_link_hash_table *htab;
+ struct elf_s390_link_hash_entry *eh = (struct elf_s390_link_hash_entry*)h;
+
+ htab = elf_hash_table (info);
+ eh->ifunc_resolver_address = h->root.u.def.value;
+ eh->ifunc_resolver_section = h->root.u.def.section;
+
+ /* Support garbage collection against STT_GNU_IFUNC symbols. */
+ if (h->plt.refcount <= 0 && h->got.refcount <= 0)
+ {
+ /* When building shared library, we need to handle the case
+ where it is marked with regular reference, but not non-GOT
+ reference. It may happen if we didn't see STT_GNU_IFUNC
+ symbol at the time when checking relocations. */
+ if (info->shared
+ && !h->non_got_ref
+ && h->ref_regular)
+ for (p = *head; p != NULL; p = p->next)
+ if (p->count)
+ {
+ h->non_got_ref = 1;
+ goto keep;
+ }
+
+ h->got = htab->init_got_offset;
+ h->plt = htab->init_plt_offset;
+ *head = NULL;
+ return TRUE;
+ }
+
+ /* Return and discard space for dynamic relocations against it if
+ it is never referenced in a non-shared object. */
+ if (!h->ref_regular)
+ {
+ if (h->plt.refcount > 0
+ || h->got.refcount > 0)
+ abort ();
+ h->got = htab->init_got_offset;
+ h->plt = htab->init_plt_offset;
+ *head = NULL;
+ return TRUE;
+ }
+
+keep:
+ /* Without checking h->plt.refcount here we allocate a PLT slot.
+ When setting plt.refcount in check_relocs it might not have been
+ known that this will be an IFUNC symol. */
+ h->plt.offset = htab->iplt->size;
+ h->needs_plt = 1;
+ htab->iplt->size += PLT_ENTRY_SIZE;
+ htab->igotplt->size += GOT_ENTRY_SIZE;
+ htab->irelplt->size += RELA_ENTRY_SIZE;
+ htab->irelplt->reloc_count++;
+
+ /* In order to make pointer equality work with IFUNC symbols defined
+ in a non-PIE executable and referenced in a shared lib, we turn
+ the symbol into a STT_FUNC symbol and make the symbol value to
+ point to the IPLT slot. That way the referencing shared lib will
+ always get the PLT slot address when resolving the respective
+ R_390_GLOB_DAT/R_390_64 relocs on that symbol. */
+ if (info->executable && !info->shared && h->def_regular && h->ref_dynamic)
+ {
+ h->root.u.def.section = htab->iplt;
+ h->root.u.def.value = h->plt.offset;
+ h->size = PLT_ENTRY_SIZE;
+ h->type = STT_FUNC;
+ }
+
+ /* We need dynamic relocation for STT_GNU_IFUNC symbol only when
+ there is a non-GOT reference in a shared object. */
+ if (!info->shared || !h->non_got_ref)
+ *head = NULL;
+
+ /* Finally, allocate space. */
+ p = *head;
+ if (p != NULL)
+ {
+ bfd_size_type count = 0;
+ do
+ {
+ count += p->count;
+ p = p->next;
+ }
+ while (p != NULL);
+ htab->irelifunc->size += count * RELA_ENTRY_SIZE;
+ }
+
+ /* Decide whether the got.iplt slot can be used. This has to be
+ avoided if the values in the GOT slots could differ for pointer
+ equality reasons. */
+ if (h->got.refcount <= 0
+ || (info->shared
+ && (h->dynindx == -1 || h->forced_local))
+ || (info->executable && info->shared)
+ || htab->sgot == NULL)
+ {
+ /* Use .got.iplt. */
+ h->got.offset = (bfd_vma) -1;
+ }
+ else
+ {
+ h->got.offset = htab->sgot->size;
+ htab->sgot->size += GOT_ENTRY_SIZE;
+ if (info->shared)
+ htab->srelgot->size += RELA_ENTRY_SIZE;
+ }
+
+ return TRUE;
+}
+
+static bfd_boolean
+elf_s390_allocate_local_syminfo (bfd *abfd, Elf_Internal_Shdr *symtab_hdr)
+{
+ bfd_size_type size;
+
+ size = symtab_hdr->sh_info;
+ size *= (sizeof (bfd_signed_vma) /* local got */
+ + sizeof (struct plt_entry) /* local plt */
+ + sizeof(char)); /* local tls type */
+ elf_local_got_refcounts (abfd) = ((bfd_signed_vma *)
+ bfd_zalloc (abfd, size));
+ if (elf_local_got_refcounts (abfd) == NULL)
+ return FALSE;
+ elf_s390_local_plt (abfd)
+ = (struct plt_entry*)(elf_local_got_refcounts (abfd)
+ + symtab_hdr->sh_info);
+ elf_s390_local_got_tls_type (abfd)
+ = (char *) (elf_s390_local_plt (abfd) + symtab_hdr->sh_info);
+
+ return TRUE;
+}
+
+/* Pick ELFOSABI_GNU if IFUNC symbols are used. */
+
+static bfd_boolean
+elf_s390_add_symbol_hook (bfd *abfd,
+ struct bfd_link_info *info,
+ Elf_Internal_Sym *sym,
+ const char **namep ATTRIBUTE_UNUSED,
+ flagword *flagsp ATTRIBUTE_UNUSED,
+ asection **secp ATTRIBUTE_UNUSED,
+ bfd_vma *valp ATTRIBUTE_UNUSED)
+{
+ if ((ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC
+ || ELF_ST_BIND (sym->st_info) == STB_GNU_UNIQUE)
+ && (abfd->flags & DYNAMIC) == 0
+ && bfd_get_flavour (info->output_bfd) == bfd_target_elf_flavour)
+ elf_tdata (info->output_bfd)->has_gnu_symbols = TRUE;
+
+ return TRUE;
+}
diff --git a/bfd/elf-strtab.c b/bfd/elf-strtab.c
new file mode 100644
index 0000000..c016c8b
--- /dev/null
+++ b/bfd/elf-strtab.c
@@ -0,0 +1,420 @@
+/* ELF strtab with GC and suffix merging support.
+ Copyright (C) 2001-2014 Free Software Foundation, Inc.
+ Written by Jakub Jelinek <jakub@redhat.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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+#include "elf-bfd.h"
+#include "hashtab.h"
+#include "libiberty.h"
+
+/* An entry in the strtab hash table. */
+
+struct elf_strtab_hash_entry
+{
+ struct bfd_hash_entry root;
+ /* Length of this entry. This includes the zero terminator. */
+ int len;
+ unsigned int refcount;
+ union {
+ /* Index within the merged section. */
+ bfd_size_type index;
+ /* Entry this is a suffix of (if len < 0). */
+ struct elf_strtab_hash_entry *suffix;
+ } u;
+};
+
+/* The strtab hash table. */
+
+struct elf_strtab_hash
+{
+ struct bfd_hash_table table;
+ /* Next available index. */
+ bfd_size_type size;
+ /* Number of array entries alloced. */
+ bfd_size_type alloced;
+ /* Final strtab size. */
+ bfd_size_type sec_size;
+ /* Array of pointers to strtab entries. */
+ struct elf_strtab_hash_entry **array;
+};
+
+/* Routine to create an entry in a section merge hashtab. */
+
+static struct bfd_hash_entry *
+elf_strtab_hash_newfunc (struct bfd_hash_entry *entry,
+ struct bfd_hash_table *table,
+ const char *string)
+{
+ /* Allocate the structure if it has not already been allocated by a
+ subclass. */
+ if (entry == NULL)
+ entry = (struct bfd_hash_entry *)
+ bfd_hash_allocate (table, sizeof (struct elf_strtab_hash_entry));
+ if (entry == NULL)
+ return NULL;
+
+ /* Call the allocation method of the superclass. */
+ entry = bfd_hash_newfunc (entry, table, string);
+
+ if (entry)
+ {
+ /* Initialize the local fields. */
+ struct elf_strtab_hash_entry *ret;
+
+ ret = (struct elf_strtab_hash_entry *) entry;
+ ret->u.index = -1;
+ ret->refcount = 0;
+ ret->len = 0;
+ }
+
+ return entry;
+}
+
+/* Create a new hash table. */
+
+struct elf_strtab_hash *
+_bfd_elf_strtab_init (void)
+{
+ struct elf_strtab_hash *table;
+ bfd_size_type amt = sizeof (struct elf_strtab_hash);
+
+ table = (struct elf_strtab_hash *) bfd_malloc (amt);
+ if (table == NULL)
+ return NULL;
+
+ if (!bfd_hash_table_init (&table->table, elf_strtab_hash_newfunc,
+ sizeof (struct elf_strtab_hash_entry)))
+ {
+ free (table);
+ return NULL;
+ }
+
+ table->sec_size = 0;
+ table->size = 1;
+ table->alloced = 64;
+ amt = sizeof (struct elf_strtab_hasn_entry *);
+ table->array = (struct elf_strtab_hash_entry **)
+ bfd_malloc (table->alloced * amt);
+ if (table->array == NULL)
+ {
+ free (table);
+ return NULL;
+ }
+
+ table->array[0] = NULL;
+
+ return table;
+}
+
+/* Free a strtab. */
+
+void
+_bfd_elf_strtab_free (struct elf_strtab_hash *tab)
+{
+ bfd_hash_table_free (&tab->table);
+ free (tab->array);
+ free (tab);
+}
+
+/* Get the index of an entity in a hash table, adding it if it is not
+ already present. */
+
+bfd_size_type
+_bfd_elf_strtab_add (struct elf_strtab_hash *tab,
+ const char *str,
+ bfd_boolean copy)
+{
+ register struct elf_strtab_hash_entry *entry;
+
+ /* We handle this specially, since we don't want to do refcounting
+ on it. */
+ if (*str == '\0')
+ return 0;
+
+ BFD_ASSERT (tab->sec_size == 0);
+ entry = (struct elf_strtab_hash_entry *)
+ bfd_hash_lookup (&tab->table, str, TRUE, copy);
+
+ if (entry == NULL)
+ return (bfd_size_type) -1;
+
+ entry->refcount++;
+ if (entry->len == 0)
+ {
+ entry->len = strlen (str) + 1;
+ /* 2G strings lose. */
+ BFD_ASSERT (entry->len > 0);
+ if (tab->size == tab->alloced)
+ {
+ bfd_size_type amt = sizeof (struct elf_strtab_hash_entry *);
+ tab->alloced *= 2;
+ tab->array = (struct elf_strtab_hash_entry **)
+ bfd_realloc_or_free (tab->array, tab->alloced * amt);
+ if (tab->array == NULL)
+ return (bfd_size_type) -1;
+ }
+
+ entry->u.index = tab->size++;
+ tab->array[entry->u.index] = entry;
+ }
+ return entry->u.index;
+}
+
+void
+_bfd_elf_strtab_addref (struct elf_strtab_hash *tab, bfd_size_type idx)
+{
+ if (idx == 0 || idx == (bfd_size_type) -1)
+ return;
+ BFD_ASSERT (tab->sec_size == 0);
+ BFD_ASSERT (idx < tab->size);
+ ++tab->array[idx]->refcount;
+}
+
+void
+_bfd_elf_strtab_delref (struct elf_strtab_hash *tab, bfd_size_type idx)
+{
+ if (idx == 0 || idx == (bfd_size_type) -1)
+ return;
+ BFD_ASSERT (tab->sec_size == 0);
+ BFD_ASSERT (idx < tab->size);
+ BFD_ASSERT (tab->array[idx]->refcount > 0);
+ --tab->array[idx]->refcount;
+}
+
+unsigned int
+_bfd_elf_strtab_refcount (struct elf_strtab_hash *tab, bfd_size_type idx)
+{
+ return tab->array[idx]->refcount;
+}
+
+void
+_bfd_elf_strtab_clear_all_refs (struct elf_strtab_hash *tab)
+{
+ bfd_size_type idx;
+
+ for (idx = 1; idx < tab->size; idx++)
+ tab->array[idx]->refcount = 0;
+}
+
+/* Downsizes strtab. Entries from IDX up to the current size are
+ removed from the array. */
+void
+_bfd_elf_strtab_restore_size (struct elf_strtab_hash *tab, bfd_size_type idx)
+{
+ bfd_size_type curr_size = tab->size;
+
+ BFD_ASSERT (tab->sec_size == 0);
+ BFD_ASSERT (idx <= curr_size);
+ tab->size = idx;
+ for (; idx < curr_size; ++idx)
+ {
+ /* We don't remove entries from the hash table, just set their
+ REFCOUNT to zero. Setting LEN zero will result in the size
+ growing if the entry is added again. See _bfd_elf_strtab_add. */
+ tab->array[idx]->refcount = 0;
+ tab->array[idx]->len = 0;
+ }
+}
+
+bfd_size_type
+_bfd_elf_strtab_size (struct elf_strtab_hash *tab)
+{
+ return tab->sec_size ? tab->sec_size : tab->size;
+}
+
+bfd_size_type
+_bfd_elf_strtab_offset (struct elf_strtab_hash *tab, bfd_size_type idx)
+{
+ struct elf_strtab_hash_entry *entry;
+
+ if (idx == 0)
+ return 0;
+ BFD_ASSERT (idx < tab->size);
+ BFD_ASSERT (tab->sec_size);
+ entry = tab->array[idx];
+ BFD_ASSERT (entry->refcount > 0);
+ entry->refcount--;
+ return tab->array[idx]->u.index;
+}
+
+bfd_boolean
+_bfd_elf_strtab_emit (register bfd *abfd, struct elf_strtab_hash *tab)
+{
+ bfd_size_type off = 1, i;
+
+ if (bfd_bwrite ("", 1, abfd) != 1)
+ return FALSE;
+
+ for (i = 1; i < tab->size; ++i)
+ {
+ register const char *str;
+ register unsigned int len;
+
+ BFD_ASSERT (tab->array[i]->refcount == 0);
+ len = tab->array[i]->len;
+ if ((int) len < 0)
+ continue;
+
+ str = tab->array[i]->root.string;
+ if (bfd_bwrite (str, len, abfd) != len)
+ return FALSE;
+
+ off += len;
+ }
+
+ BFD_ASSERT (off == tab->sec_size);
+ return TRUE;
+}
+
+/* Compare two elf_strtab_hash_entry structures. Called via qsort. */
+
+static int
+strrevcmp (const void *a, const void *b)
+{
+ struct elf_strtab_hash_entry *A = *(struct elf_strtab_hash_entry **) a;
+ struct elf_strtab_hash_entry *B = *(struct elf_strtab_hash_entry **) b;
+ unsigned int lenA = A->len;
+ unsigned int lenB = B->len;
+ const unsigned char *s = (const unsigned char *) A->root.string + lenA - 1;
+ const unsigned char *t = (const unsigned char *) B->root.string + lenB - 1;
+ int l = lenA < lenB ? lenA : lenB;
+
+ while (l)
+ {
+ if (*s != *t)
+ return (int) *s - (int) *t;
+ s--;
+ t--;
+ l--;
+ }
+ return lenA - lenB;
+}
+
+static inline int
+is_suffix (const struct elf_strtab_hash_entry *A,
+ const struct elf_strtab_hash_entry *B)
+{
+ if (A->len <= B->len)
+ /* B cannot be a suffix of A unless A is equal to B, which is guaranteed
+ not to be equal by the hash table. */
+ return 0;
+
+ return memcmp (A->root.string + (A->len - B->len),
+ B->root.string, B->len - 1) == 0;
+}
+
+/* This function assigns final string table offsets for used strings,
+ merging strings matching suffixes of longer strings if possible. */
+
+void
+_bfd_elf_strtab_finalize (struct elf_strtab_hash *tab)
+{
+ struct elf_strtab_hash_entry **array, **a, *e;
+ bfd_size_type size, amt;
+
+ /* GCC 2.91.66 (egcs-1.1.2) on i386 miscompiles this function when i is
+ a 64-bit bfd_size_type: a 64-bit target or --enable-64-bit-bfd.
+ Besides, indexing with a long long wouldn't give anything but extra
+ cycles. */
+ size_t i;
+
+ /* Sort the strings by suffix and length. */
+ amt = tab->size * sizeof (struct elf_strtab_hash_entry *);
+ array = (struct elf_strtab_hash_entry **) bfd_malloc (amt);
+ if (array == NULL)
+ goto alloc_failure;
+
+ for (i = 1, a = array; i < tab->size; ++i)
+ {
+ e = tab->array[i];
+ if (e->refcount)
+ {
+ *a++ = e;
+ /* Adjust the length to not include the zero terminator. */
+ e->len -= 1;
+ }
+ else
+ e->len = 0;
+ }
+
+ size = a - array;
+ if (size != 0)
+ {
+ qsort (array, size, sizeof (struct elf_strtab_hash_entry *), strrevcmp);
+
+ /* Loop over the sorted array and merge suffixes. Start from the
+ end because we want eg.
+
+ s1 -> "d"
+ s2 -> "bcd"
+ s3 -> "abcd"
+
+ to end up as
+
+ s3 -> "abcd"
+ s2 _____^
+ s1 _______^
+
+ ie. we don't want s1 pointing into the old s2. */
+ e = *--a;
+ e->len += 1;
+ while (--a >= array)
+ {
+ struct elf_strtab_hash_entry *cmp = *a;
+
+ cmp->len += 1;
+ if (is_suffix (e, cmp))
+ {
+ cmp->u.suffix = e;
+ cmp->len = -cmp->len;
+ }
+ else
+ e = cmp;
+ }
+ }
+
+alloc_failure:
+ if (array)
+ free (array);
+
+ /* Assign positions to the strings we want to keep. */
+ size = 1;
+ for (i = 1; i < tab->size; ++i)
+ {
+ e = tab->array[i];
+ if (e->refcount && e->len > 0)
+ {
+ e->u.index = size;
+ size += e->len;
+ }
+ }
+
+ tab->sec_size = size;
+
+ /* Adjust the rest. */
+ for (i = 1; i < tab->size; ++i)
+ {
+ e = tab->array[i];
+ if (e->refcount && e->len < 0)
+ e->u.index = e->u.suffix->u.index + (e->u.suffix->len + e->len);
+ }
+}
diff --git a/bfd/elf-vxworks.c b/bfd/elf-vxworks.c
new file mode 100644
index 0000000..77dfd02
--- /dev/null
+++ b/bfd/elf-vxworks.c
@@ -0,0 +1,301 @@
+/* VxWorks support for ELF
+ Copyright (C) 2005-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public 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 provides routines used by all VxWorks targets. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+#include "elf-bfd.h"
+#include "elf-vxworks.h"
+#include "elf/vxworks.h"
+
+/* Return true if symbol NAME, as defined by ABFD, is one of the special
+ __GOTT_BASE__ or __GOTT_INDEX__ symbols. */
+
+static bfd_boolean
+elf_vxworks_gott_symbol_p (bfd *abfd, const char *name)
+{
+ char leading;
+
+ leading = bfd_get_symbol_leading_char (abfd);
+ if (leading)
+ {
+ if (*name != leading)
+ return FALSE;
+ name++;
+ }
+ return (strcmp (name, "__GOTT_BASE__") == 0
+ || strcmp (name, "__GOTT_INDEX__") == 0);
+}
+
+/* Tweak magic VxWorks symbols as they are loaded. */
+bfd_boolean
+elf_vxworks_add_symbol_hook (bfd *abfd,
+ struct bfd_link_info *info,
+ Elf_Internal_Sym *sym,
+ const char **namep,
+ flagword *flagsp,
+ asection **secp ATTRIBUTE_UNUSED,
+ bfd_vma *valp ATTRIBUTE_UNUSED)
+{
+ /* Ideally these "magic" symbols would be exported by libc.so.1
+ which would be found via a DT_NEEDED tag, and then handled
+ specially by the linker at runtime. Except shared libraries
+ don't even link to libc.so.1 by default...
+ If the symbol is imported from, or will be put in a shared library,
+ give the symbol weak binding to get the desired samantics.
+ This transformation will be undone in
+ elf_i386_vxworks_link_output_symbol_hook. */
+ if ((info->shared || abfd->flags & DYNAMIC)
+ && elf_vxworks_gott_symbol_p (abfd, *namep))
+ {
+ sym->st_info = ELF_ST_INFO (STB_WEAK, ELF_ST_TYPE (sym->st_info));
+ *flagsp |= BSF_WEAK;
+ }
+
+ return TRUE;
+}
+
+/* Perform VxWorks-specific handling of the create_dynamic_sections hook.
+ When creating an executable, set *SRELPLT2_OUT to the .rel(a).plt.unloaded
+ section. */
+
+bfd_boolean
+elf_vxworks_create_dynamic_sections (bfd *dynobj, struct bfd_link_info *info,
+ asection **srelplt2_out)
+{
+ struct elf_link_hash_table *htab;
+ const struct elf_backend_data *bed;
+ asection *s;
+
+ htab = elf_hash_table (info);
+ bed = get_elf_backend_data (dynobj);
+
+ if (!info->shared)
+ {
+ s = bfd_make_section_anyway_with_flags (dynobj,
+ bed->default_use_rela_p
+ ? ".rela.plt.unloaded"
+ : ".rel.plt.unloaded",
+ SEC_HAS_CONTENTS | SEC_IN_MEMORY
+ | SEC_READONLY
+ | SEC_LINKER_CREATED);
+ if (s == NULL
+ || !bfd_set_section_alignment (dynobj, s, bed->s->log_file_align))
+ return FALSE;
+
+ *srelplt2_out = s;
+ }
+
+ /* Mark the GOT and PLT symbols as having relocations; they might
+ not, but we won't know for sure until we build the GOT in
+ finish_dynamic_symbol. Also make sure that the GOT symbol
+ is entered into the dynamic symbol table; the loader uses it
+ to initialize __GOTT_BASE__[__GOTT_INDEX__]. */
+ if (htab->hgot)
+ {
+ htab->hgot->indx = -2;
+ htab->hgot->other &= ~ELF_ST_VISIBILITY (-1);
+ htab->hgot->forced_local = 0;
+ if (!bfd_elf_link_record_dynamic_symbol (info, htab->hgot))
+ return FALSE;
+ }
+ if (htab->hplt)
+ {
+ htab->hplt->indx = -2;
+ htab->hplt->type = STT_FUNC;
+ }
+
+ return TRUE;
+}
+
+/* Tweak magic VxWorks symbols as they are written to the output file. */
+int
+elf_vxworks_link_output_symbol_hook (struct bfd_link_info *info
+ ATTRIBUTE_UNUSED,
+ const char *name,
+ Elf_Internal_Sym *sym,
+ asection *input_sec ATTRIBUTE_UNUSED,
+ struct elf_link_hash_entry *h)
+{
+ /* Reverse the effects of the hack in elf_vxworks_add_symbol_hook. */
+ if (h
+ && h->root.type == bfd_link_hash_undefweak
+ && elf_vxworks_gott_symbol_p (h->root.u.undef.abfd, name))
+ sym->st_info = ELF_ST_INFO (STB_GLOBAL, ELF_ST_TYPE (sym->st_info));
+
+ return 1;
+}
+
+/* Copy relocations into the output file. Fixes up relocations against PLT
+ entries, then calls the generic routine. */
+
+bfd_boolean
+elf_vxworks_emit_relocs (bfd *output_bfd,
+ asection *input_section,
+ Elf_Internal_Shdr *input_rel_hdr,
+ Elf_Internal_Rela *internal_relocs,
+ struct elf_link_hash_entry **rel_hash)
+{
+ const struct elf_backend_data *bed;
+ int j;
+
+ bed = get_elf_backend_data (output_bfd);
+
+ if (output_bfd->flags & (DYNAMIC|EXEC_P))
+ {
+ Elf_Internal_Rela *irela;
+ Elf_Internal_Rela *irelaend;
+ struct elf_link_hash_entry **hash_ptr;
+
+ for (irela = internal_relocs,
+ irelaend = irela + (NUM_SHDR_ENTRIES (input_rel_hdr)
+ * bed->s->int_rels_per_ext_rel),
+ hash_ptr = rel_hash;
+ irela < irelaend;
+ irela += bed->s->int_rels_per_ext_rel,
+ hash_ptr++)
+ {
+ if (*hash_ptr
+ && (*hash_ptr)->def_dynamic
+ && !(*hash_ptr)->def_regular
+ && ((*hash_ptr)->root.type == bfd_link_hash_defined
+ || (*hash_ptr)->root.type == bfd_link_hash_defweak)
+ && (*hash_ptr)->root.u.def.section->output_section != NULL)
+ {
+ /* This is a relocation from an executable or shared
+ library against a symbol in a different shared
+ library. We are creating a definition in the output
+ file but it does not come from any of our normal (.o)
+ files. ie. a PLT stub. Normally this would be a
+ relocation against against SHN_UNDEF with the VMA of
+ the PLT stub. This upsets the VxWorks loader.
+ Convert it to a section-relative relocation. This
+ gets some other symbols (for instance .dynbss), but
+ is conservatively correct. */
+ for (j = 0; j < bed->s->int_rels_per_ext_rel; j++)
+ {
+ asection *sec = (*hash_ptr)->root.u.def.section;
+ int this_idx = sec->output_section->target_index;
+
+ irela[j].r_info
+ = ELF32_R_INFO (this_idx, ELF32_R_TYPE (irela[j].r_info));
+ irela[j].r_addend += (*hash_ptr)->root.u.def.value;
+ irela[j].r_addend += sec->output_offset;
+ }
+ /* Stop the generic routine adjusting this entry. */
+ *hash_ptr = NULL;
+ }
+ }
+ }
+ return _bfd_elf_link_output_relocs (output_bfd, input_section,
+ input_rel_hdr, internal_relocs,
+ rel_hash);
+}
+
+
+/* Set the sh_link and sh_info fields on the static plt relocation secton. */
+
+void
+elf_vxworks_final_write_processing (bfd *abfd,
+ bfd_boolean linker ATTRIBUTE_UNUSED)
+{
+ asection * sec;
+ struct bfd_elf_section_data *d;
+
+ sec = bfd_get_section_by_name (abfd, ".rel.plt.unloaded");
+ if (!sec)
+ sec = bfd_get_section_by_name (abfd, ".rela.plt.unloaded");
+ if (!sec)
+ return;
+ d = elf_section_data (sec);
+ d->this_hdr.sh_link = elf_onesymtab (abfd);
+ sec = bfd_get_section_by_name (abfd, ".plt");
+ if (sec)
+ d->this_hdr.sh_info = elf_section_data (sec)->this_idx;
+}
+
+/* Add the dynamic entries required by VxWorks. These point to the
+ tls sections. */
+
+bfd_boolean
+elf_vxworks_add_dynamic_entries (bfd *output_bfd, struct bfd_link_info *info)
+{
+ if (bfd_get_section_by_name (output_bfd, ".tls_data"))
+ {
+ if (!_bfd_elf_add_dynamic_entry (info, DT_VX_WRS_TLS_DATA_START, 0)
+ || !_bfd_elf_add_dynamic_entry (info, DT_VX_WRS_TLS_DATA_SIZE, 0)
+ || !_bfd_elf_add_dynamic_entry (info, DT_VX_WRS_TLS_DATA_ALIGN, 0))
+ return FALSE;
+ }
+ if (bfd_get_section_by_name (output_bfd, ".tls_vars"))
+ {
+ if (!_bfd_elf_add_dynamic_entry (info, DT_VX_WRS_TLS_VARS_START, 0)
+ || !_bfd_elf_add_dynamic_entry (info, DT_VX_WRS_TLS_VARS_SIZE, 0))
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/* If *DYN is one of the VxWorks-specific dynamic entries, then fill
+ in the value now and return TRUE. Otherwise return FALSE. */
+
+bfd_boolean
+elf_vxworks_finish_dynamic_entry (bfd *output_bfd, Elf_Internal_Dyn *dyn)
+{
+ asection *sec;
+
+ switch (dyn->d_tag)
+ {
+ default:
+ return FALSE;
+
+ case DT_VX_WRS_TLS_DATA_START:
+ sec = bfd_get_section_by_name (output_bfd, ".tls_data");
+ dyn->d_un.d_ptr = sec->vma;
+ break;
+
+ case DT_VX_WRS_TLS_DATA_SIZE:
+ sec = bfd_get_section_by_name (output_bfd, ".tls_data");
+ dyn->d_un.d_val = sec->size;
+ break;
+
+ case DT_VX_WRS_TLS_DATA_ALIGN:
+ sec = bfd_get_section_by_name (output_bfd, ".tls_data");
+ dyn->d_un.d_val
+ = (bfd_size_type)1 << bfd_get_section_alignment (output_bfd,
+ sec);
+ break;
+
+ case DT_VX_WRS_TLS_VARS_START:
+ sec = bfd_get_section_by_name (output_bfd, ".tls_vars");
+ dyn->d_un.d_ptr = sec->vma;
+ break;
+
+ case DT_VX_WRS_TLS_VARS_SIZE:
+ sec = bfd_get_section_by_name (output_bfd, ".tls_vars");
+ dyn->d_un.d_val = sec->size;
+ break;
+ }
+ return TRUE;
+}
+
+
diff --git a/bfd/elf-vxworks.h b/bfd/elf-vxworks.h
new file mode 100644
index 0000000..fa57a27
--- /dev/null
+++ b/bfd/elf-vxworks.h
@@ -0,0 +1,38 @@
+/* VxWorks support for ELF
+ Copyright (C) 2005-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public 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/common.h"
+#include "elf/internal.h"
+
+bfd_boolean elf_vxworks_add_symbol_hook
+ (bfd *, struct bfd_link_info *, Elf_Internal_Sym *, const char **,
+ flagword *, asection **, bfd_vma *);
+bfd_boolean elf_vxworks_link_output_symbol_hook
+ (struct bfd_link_info *, const char *name, Elf_Internal_Sym *,
+ asection *, struct elf_link_hash_entry *);
+bfd_boolean elf_vxworks_emit_relocs
+ (bfd *, asection *, Elf_Internal_Shdr *, Elf_Internal_Rela *,
+ struct elf_link_hash_entry **);
+void elf_vxworks_final_write_processing (bfd *, bfd_boolean);
+bfd_boolean elf_vxworks_create_dynamic_sections
+ (bfd *, struct bfd_link_info *, asection **);
+bfd_boolean elf_vxworks_add_dynamic_entries (bfd *, struct bfd_link_info *);
+bfd_boolean elf_vxworks_finish_dynamic_entry (bfd *, Elf_Internal_Dyn *);
+
diff --git a/bfd/elf.c b/bfd/elf.c
new file mode 100644
index 0000000..8b207ad
--- /dev/null
+++ b/bfd/elf.c
@@ -0,0 +1,10171 @@
+/* ELF executable support for BFD.
+
+ Copyright (C) 1993-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, 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. */
+
+/* For sparc64-cross-sparc32. */
+#define _SYSCALL32
+#include "sysdep.h"
+#include "bfd.h"
+#include "bfdlink.h"
+#include "libbfd.h"
+#define ARCH_SIZE 0
+#include "elf-bfd.h"
+#include "libiberty.h"
+#include "safe-ctype.h"
+#include "elf-linux-psinfo.h"
+
+#ifdef CORE_HEADER
+#include CORE_HEADER
+#endif
+
+static int elf_sort_sections (const void *, const void *);
+static bfd_boolean assign_file_positions_except_relocs (bfd *, struct bfd_link_info *);
+static bfd_boolean prep_headers (bfd *);
+static bfd_boolean swap_out_syms (bfd *, struct bfd_strtab_hash **, int) ;
+static bfd_boolean elf_read_notes (bfd *, file_ptr, bfd_size_type) ;
+static bfd_boolean elf_parse_notes (bfd *abfd, char *buf, size_t size,
+ file_ptr offset);
+
+/* 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 (bfd *abfd,
+ const Elf_External_Verdef *src,
+ Elf_Internal_Verdef *dst)
+{
+ dst->vd_version = H_GET_16 (abfd, src->vd_version);
+ dst->vd_flags = H_GET_16 (abfd, src->vd_flags);
+ dst->vd_ndx = H_GET_16 (abfd, src->vd_ndx);
+ dst->vd_cnt = H_GET_16 (abfd, src->vd_cnt);
+ dst->vd_hash = H_GET_32 (abfd, src->vd_hash);
+ dst->vd_aux = H_GET_32 (abfd, src->vd_aux);
+ dst->vd_next = H_GET_32 (abfd, src->vd_next);
+}
+
+/* Swap out a Verdef structure. */
+
+void
+_bfd_elf_swap_verdef_out (bfd *abfd,
+ const Elf_Internal_Verdef *src,
+ Elf_External_Verdef *dst)
+{
+ H_PUT_16 (abfd, src->vd_version, dst->vd_version);
+ H_PUT_16 (abfd, src->vd_flags, dst->vd_flags);
+ H_PUT_16 (abfd, src->vd_ndx, dst->vd_ndx);
+ H_PUT_16 (abfd, src->vd_cnt, dst->vd_cnt);
+ H_PUT_32 (abfd, src->vd_hash, dst->vd_hash);
+ H_PUT_32 (abfd, src->vd_aux, dst->vd_aux);
+ H_PUT_32 (abfd, src->vd_next, dst->vd_next);
+}
+
+/* Swap in a Verdaux structure. */
+
+void
+_bfd_elf_swap_verdaux_in (bfd *abfd,
+ const Elf_External_Verdaux *src,
+ Elf_Internal_Verdaux *dst)
+{
+ dst->vda_name = H_GET_32 (abfd, src->vda_name);
+ dst->vda_next = H_GET_32 (abfd, src->vda_next);
+}
+
+/* Swap out a Verdaux structure. */
+
+void
+_bfd_elf_swap_verdaux_out (bfd *abfd,
+ const Elf_Internal_Verdaux *src,
+ Elf_External_Verdaux *dst)
+{
+ H_PUT_32 (abfd, src->vda_name, dst->vda_name);
+ H_PUT_32 (abfd, src->vda_next, dst->vda_next);
+}
+
+/* Swap in a Verneed structure. */
+
+void
+_bfd_elf_swap_verneed_in (bfd *abfd,
+ const Elf_External_Verneed *src,
+ Elf_Internal_Verneed *dst)
+{
+ dst->vn_version = H_GET_16 (abfd, src->vn_version);
+ dst->vn_cnt = H_GET_16 (abfd, src->vn_cnt);
+ dst->vn_file = H_GET_32 (abfd, src->vn_file);
+ dst->vn_aux = H_GET_32 (abfd, src->vn_aux);
+ dst->vn_next = H_GET_32 (abfd, src->vn_next);
+}
+
+/* Swap out a Verneed structure. */
+
+void
+_bfd_elf_swap_verneed_out (bfd *abfd,
+ const Elf_Internal_Verneed *src,
+ Elf_External_Verneed *dst)
+{
+ H_PUT_16 (abfd, src->vn_version, dst->vn_version);
+ H_PUT_16 (abfd, src->vn_cnt, dst->vn_cnt);
+ H_PUT_32 (abfd, src->vn_file, dst->vn_file);
+ H_PUT_32 (abfd, src->vn_aux, dst->vn_aux);
+ H_PUT_32 (abfd, src->vn_next, dst->vn_next);
+}
+
+/* Swap in a Vernaux structure. */
+
+void
+_bfd_elf_swap_vernaux_in (bfd *abfd,
+ const Elf_External_Vernaux *src,
+ Elf_Internal_Vernaux *dst)
+{
+ dst->vna_hash = H_GET_32 (abfd, src->vna_hash);
+ dst->vna_flags = H_GET_16 (abfd, src->vna_flags);
+ dst->vna_other = H_GET_16 (abfd, src->vna_other);
+ dst->vna_name = H_GET_32 (abfd, src->vna_name);
+ dst->vna_next = H_GET_32 (abfd, src->vna_next);
+}
+
+/* Swap out a Vernaux structure. */
+
+void
+_bfd_elf_swap_vernaux_out (bfd *abfd,
+ const Elf_Internal_Vernaux *src,
+ Elf_External_Vernaux *dst)
+{
+ H_PUT_32 (abfd, src->vna_hash, dst->vna_hash);
+ H_PUT_16 (abfd, src->vna_flags, dst->vna_flags);
+ H_PUT_16 (abfd, src->vna_other, dst->vna_other);
+ H_PUT_32 (abfd, src->vna_name, dst->vna_name);
+ H_PUT_32 (abfd, src->vna_next, dst->vna_next);
+}
+
+/* Swap in a Versym structure. */
+
+void
+_bfd_elf_swap_versym_in (bfd *abfd,
+ const Elf_External_Versym *src,
+ Elf_Internal_Versym *dst)
+{
+ dst->vs_vers = H_GET_16 (abfd, src->vs_vers);
+}
+
+/* Swap out a Versym structure. */
+
+void
+_bfd_elf_swap_versym_out (bfd *abfd,
+ const Elf_Internal_Versym *src,
+ Elf_External_Versym *dst)
+{
+ 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 (const char *namearg)
+{
+ const unsigned char *name = (const unsigned char *) namearg;
+ 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 & 0xffffffff;
+}
+
+/* DT_GNU_HASH hash function. Do not change this function; you will
+ cause invalid hash tables to be generated. */
+
+unsigned long
+bfd_elf_gnu_hash (const char *namearg)
+{
+ const unsigned char *name = (const unsigned char *) namearg;
+ unsigned long h = 5381;
+ unsigned char ch;
+
+ while ((ch = *name++) != '\0')
+ h = (h << 5) + h + ch;
+ return h & 0xffffffff;
+}
+
+/* Create a tdata field OBJECT_SIZE bytes in length, zeroed out and with
+ the object_id field of an elf_obj_tdata field set to OBJECT_ID. */
+bfd_boolean
+bfd_elf_allocate_object (bfd *abfd,
+ size_t object_size,
+ enum elf_target_id object_id)
+{
+ BFD_ASSERT (object_size >= sizeof (struct elf_obj_tdata));
+ abfd->tdata.any = bfd_zalloc (abfd, object_size);
+ if (abfd->tdata.any == NULL)
+ return FALSE;
+
+ elf_object_id (abfd) = object_id;
+ if (abfd->direction != read_direction)
+ {
+ struct output_elf_obj_tdata *o = bfd_zalloc (abfd, sizeof *o);
+ if (o == NULL)
+ return FALSE;
+ elf_tdata (abfd)->o = o;
+ elf_program_header_size (abfd) = (bfd_size_type) -1;
+ }
+ return TRUE;
+}
+
+
+bfd_boolean
+bfd_elf_make_object (bfd *abfd)
+{
+ const struct elf_backend_data *bed = get_elf_backend_data (abfd);
+ return bfd_elf_allocate_object (abfd, sizeof (struct elf_obj_tdata),
+ bed->target_id);
+}
+
+bfd_boolean
+bfd_elf_mkcorefile (bfd *abfd)
+{
+ /* I think this can be done just like an object file. */
+ if (!abfd->xvec->_bfd_set_format[(int) bfd_object] (abfd))
+ return FALSE;
+ elf_tdata (abfd)->core = bfd_zalloc (abfd, sizeof (*elf_tdata (abfd)->core));
+ return elf_tdata (abfd)->core != NULL;
+}
+
+static char *
+bfd_elf_get_str_section (bfd *abfd, unsigned int shindex)
+{
+ Elf_Internal_Shdr **i_shdrp;
+ bfd_byte *shstrtab = NULL;
+ file_ptr offset;
+ bfd_size_type shstrtabsize;
+
+ i_shdrp = elf_elfsections (abfd);
+ if (i_shdrp == 0
+ || shindex >= elf_numsections (abfd)
+ || i_shdrp[shindex] == 0)
+ return NULL;
+
+ shstrtab = 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;
+
+ /* Allocate and clear an extra byte at the end, to prevent crashes
+ in case the string table is not terminated. */
+ if (shstrtabsize + 1 <= 1
+ || (shstrtab = (bfd_byte *) bfd_alloc (abfd, shstrtabsize + 1)) == NULL
+ || bfd_seek (abfd, offset, SEEK_SET) != 0)
+ shstrtab = NULL;
+ else if (bfd_bread (shstrtab, shstrtabsize, abfd) != shstrtabsize)
+ {
+ if (bfd_get_error () != bfd_error_system_call)
+ bfd_set_error (bfd_error_file_truncated);
+ shstrtab = NULL;
+ /* Once we've failed to read it, make sure we don't keep
+ trying. Otherwise, we'll keep allocating space for
+ the string table over and over. */
+ i_shdrp[shindex]->sh_size = 0;
+ }
+ else
+ shstrtab[shstrtabsize] = '\0';
+ i_shdrp[shindex]->contents = shstrtab;
+ }
+ return (char *) shstrtab;
+}
+
+char *
+bfd_elf_string_from_elf_section (bfd *abfd,
+ unsigned int shindex,
+ unsigned int strindex)
+{
+ Elf_Internal_Shdr *hdr;
+
+ if (strindex == 0)
+ return "";
+
+ if (elf_elfsections (abfd) == NULL || shindex >= elf_numsections (abfd))
+ return NULL;
+
+ hdr = elf_elfsections (abfd)[shindex];
+
+ if (hdr->contents == NULL
+ && bfd_elf_get_str_section (abfd, shindex) == NULL)
+ return NULL;
+
+ if (strindex >= hdr->sh_size)
+ {
+ unsigned int shstrndx = elf_elfheader(abfd)->e_shstrndx;
+ (*_bfd_error_handler)
+ (_("%B: invalid string offset %u >= %lu for section `%s'"),
+ abfd, strindex, (unsigned long) hdr->sh_size,
+ (shindex == shstrndx && strindex == hdr->sh_name
+ ? ".shstrtab"
+ : bfd_elf_string_from_elf_section (abfd, shstrndx, hdr->sh_name)));
+ return NULL;
+ }
+
+ return ((char *) hdr->contents) + strindex;
+}
+
+/* Read and convert symbols to internal format.
+ SYMCOUNT specifies the number of symbols to read, starting from
+ symbol SYMOFFSET. If any of INTSYM_BUF, EXTSYM_BUF or EXTSHNDX_BUF
+ are non-NULL, they are used to store the internal symbols, external
+ symbols, and symbol section index extensions, respectively.
+ Returns a pointer to the internal symbol buffer (malloced if necessary)
+ or NULL if there were no symbols or some kind of problem. */
+
+Elf_Internal_Sym *
+bfd_elf_get_elf_syms (bfd *ibfd,
+ Elf_Internal_Shdr *symtab_hdr,
+ size_t symcount,
+ size_t symoffset,
+ Elf_Internal_Sym *intsym_buf,
+ void *extsym_buf,
+ Elf_External_Sym_Shndx *extshndx_buf)
+{
+ Elf_Internal_Shdr *shndx_hdr;
+ void *alloc_ext;
+ const bfd_byte *esym;
+ Elf_External_Sym_Shndx *alloc_extshndx;
+ Elf_External_Sym_Shndx *shndx;
+ Elf_Internal_Sym *alloc_intsym;
+ Elf_Internal_Sym *isym;
+ Elf_Internal_Sym *isymend;
+ const struct elf_backend_data *bed;
+ size_t extsym_size;
+ bfd_size_type amt;
+ file_ptr pos;
+
+ if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour)
+ abort ();
+
+ if (symcount == 0)
+ return intsym_buf;
+
+ /* Normal syms might have section extension entries. */
+ shndx_hdr = NULL;
+ if (symtab_hdr == &elf_tdata (ibfd)->symtab_hdr)
+ shndx_hdr = &elf_tdata (ibfd)->symtab_shndx_hdr;
+
+ /* Read the symbols. */
+ alloc_ext = NULL;
+ alloc_extshndx = NULL;
+ alloc_intsym = NULL;
+ bed = get_elf_backend_data (ibfd);
+ extsym_size = bed->s->sizeof_sym;
+ amt = symcount * extsym_size;
+ pos = symtab_hdr->sh_offset + symoffset * extsym_size;
+ if (extsym_buf == NULL)
+ {
+ alloc_ext = bfd_malloc2 (symcount, extsym_size);
+ extsym_buf = alloc_ext;
+ }
+ if (extsym_buf == NULL
+ || bfd_seek (ibfd, pos, SEEK_SET) != 0
+ || bfd_bread (extsym_buf, amt, ibfd) != amt)
+ {
+ intsym_buf = NULL;
+ goto out;
+ }
+
+ if (shndx_hdr == NULL || shndx_hdr->sh_size == 0)
+ extshndx_buf = NULL;
+ else
+ {
+ amt = symcount * sizeof (Elf_External_Sym_Shndx);
+ pos = shndx_hdr->sh_offset + symoffset * sizeof (Elf_External_Sym_Shndx);
+ if (extshndx_buf == NULL)
+ {
+ alloc_extshndx = (Elf_External_Sym_Shndx *)
+ bfd_malloc2 (symcount, sizeof (Elf_External_Sym_Shndx));
+ extshndx_buf = alloc_extshndx;
+ }
+ if (extshndx_buf == NULL
+ || bfd_seek (ibfd, pos, SEEK_SET) != 0
+ || bfd_bread (extshndx_buf, amt, ibfd) != amt)
+ {
+ intsym_buf = NULL;
+ goto out;
+ }
+ }
+
+ if (intsym_buf == NULL)
+ {
+ alloc_intsym = (Elf_Internal_Sym *)
+ bfd_malloc2 (symcount, sizeof (Elf_Internal_Sym));
+ intsym_buf = alloc_intsym;
+ if (intsym_buf == NULL)
+ goto out;
+ }
+
+ /* Convert the symbols to internal form. */
+ isymend = intsym_buf + symcount;
+ for (esym = (const bfd_byte *) extsym_buf, isym = intsym_buf,
+ shndx = extshndx_buf;
+ isym < isymend;
+ esym += extsym_size, isym++, shndx = shndx != NULL ? shndx + 1 : NULL)
+ if (!(*bed->s->swap_symbol_in) (ibfd, esym, shndx, isym))
+ {
+ symoffset += (esym - (bfd_byte *) extsym_buf) / extsym_size;
+ (*_bfd_error_handler) (_("%B symbol number %lu references "
+ "nonexistent SHT_SYMTAB_SHNDX section"),
+ ibfd, (unsigned long) symoffset);
+ if (alloc_intsym != NULL)
+ free (alloc_intsym);
+ intsym_buf = NULL;
+ goto out;
+ }
+
+ out:
+ if (alloc_ext != NULL)
+ free (alloc_ext);
+ if (alloc_extshndx != NULL)
+ free (alloc_extshndx);
+
+ return intsym_buf;
+}
+
+/* Look up a symbol name. */
+const char *
+bfd_elf_sym_name (bfd *abfd,
+ Elf_Internal_Shdr *symtab_hdr,
+ Elf_Internal_Sym *isym,
+ asection *sym_sec)
+{
+ const char *name;
+ unsigned int iname = isym->st_name;
+ unsigned int shindex = symtab_hdr->sh_link;
+
+ if (iname == 0 && ELF_ST_TYPE (isym->st_info) == STT_SECTION
+ /* Check for a bogus st_shndx to avoid crashing. */
+ && isym->st_shndx < elf_numsections (abfd))
+ {
+ iname = elf_elfsections (abfd)[isym->st_shndx]->sh_name;
+ shindex = elf_elfheader (abfd)->e_shstrndx;
+ }
+
+ name = bfd_elf_string_from_elf_section (abfd, shindex, iname);
+ if (name == NULL)
+ name = "(null)";
+ else if (sym_sec && *name == '\0')
+ name = bfd_section_name (abfd, sym_sec);
+
+ return name;
+}
+
+/* Elf_Internal_Shdr->contents is an array of these for SHT_GROUP
+ sections. The first element is the flags, the rest are section
+ pointers. */
+
+typedef union elf_internal_group {
+ Elf_Internal_Shdr *shdr;
+ unsigned int flags;
+} Elf_Internal_Group;
+
+/* Return the name of the group signature symbol. Why isn't the
+ signature just a string? */
+
+static const char *
+group_signature (bfd *abfd, Elf_Internal_Shdr *ghdr)
+{
+ Elf_Internal_Shdr *hdr;
+ unsigned char esym[sizeof (Elf64_External_Sym)];
+ Elf_External_Sym_Shndx eshndx;
+ Elf_Internal_Sym isym;
+
+ /* First we need to ensure the symbol table is available. Make sure
+ that it is a symbol table section. */
+ if (ghdr->sh_link >= elf_numsections (abfd))
+ return NULL;
+ hdr = elf_elfsections (abfd) [ghdr->sh_link];
+ if (hdr->sh_type != SHT_SYMTAB
+ || ! bfd_section_from_shdr (abfd, ghdr->sh_link))
+ return NULL;
+
+ /* Go read the symbol. */
+ hdr = &elf_tdata (abfd)->symtab_hdr;
+ if (bfd_elf_get_elf_syms (abfd, hdr, 1, ghdr->sh_info,
+ &isym, esym, &eshndx) == NULL)
+ return NULL;
+
+ return bfd_elf_sym_name (abfd, hdr, &isym, NULL);
+}
+
+/* Set next_in_group list pointer, and group name for NEWSECT. */
+
+static bfd_boolean
+setup_group (bfd *abfd, Elf_Internal_Shdr *hdr, asection *newsect)
+{
+ unsigned int num_group = elf_tdata (abfd)->num_group;
+
+ /* If num_group is zero, read in all SHT_GROUP sections. The count
+ is set to -1 if there are no SHT_GROUP sections. */
+ if (num_group == 0)
+ {
+ unsigned int i, shnum;
+
+ /* First count the number of groups. If we have a SHT_GROUP
+ section with just a flag word (ie. sh_size is 4), ignore it. */
+ shnum = elf_numsections (abfd);
+ num_group = 0;
+
+#define IS_VALID_GROUP_SECTION_HEADER(shdr, minsize) \
+ ( (shdr)->sh_type == SHT_GROUP \
+ && (shdr)->sh_size >= minsize \
+ && (shdr)->sh_entsize == GRP_ENTRY_SIZE \
+ && ((shdr)->sh_size % GRP_ENTRY_SIZE) == 0)
+
+ for (i = 0; i < shnum; i++)
+ {
+ Elf_Internal_Shdr *shdr = elf_elfsections (abfd)[i];
+
+ if (IS_VALID_GROUP_SECTION_HEADER (shdr, 2 * GRP_ENTRY_SIZE))
+ num_group += 1;
+ }
+
+ if (num_group == 0)
+ {
+ num_group = (unsigned) -1;
+ elf_tdata (abfd)->num_group = num_group;
+ }
+ else
+ {
+ /* We keep a list of elf section headers for group sections,
+ so we can find them quickly. */
+ bfd_size_type amt;
+
+ elf_tdata (abfd)->num_group = num_group;
+ elf_tdata (abfd)->group_sect_ptr = (Elf_Internal_Shdr **)
+ bfd_alloc2 (abfd, num_group, sizeof (Elf_Internal_Shdr *));
+ if (elf_tdata (abfd)->group_sect_ptr == NULL)
+ return FALSE;
+
+ num_group = 0;
+ for (i = 0; i < shnum; i++)
+ {
+ Elf_Internal_Shdr *shdr = elf_elfsections (abfd)[i];
+
+ if (IS_VALID_GROUP_SECTION_HEADER (shdr, 2 * GRP_ENTRY_SIZE))
+ {
+ unsigned char *src;
+ Elf_Internal_Group *dest;
+
+ /* Add to list of sections. */
+ elf_tdata (abfd)->group_sect_ptr[num_group] = shdr;
+ num_group += 1;
+
+ /* Read the raw contents. */
+ BFD_ASSERT (sizeof (*dest) >= 4);
+ amt = shdr->sh_size * sizeof (*dest) / 4;
+ shdr->contents = (unsigned char *)
+ bfd_alloc2 (abfd, shdr->sh_size, sizeof (*dest) / 4);
+ /* PR binutils/4110: Handle corrupt group headers. */
+ if (shdr->contents == NULL)
+ {
+ _bfd_error_handler
+ (_("%B: corrupt size field in group section header: 0x%lx"), abfd, shdr->sh_size);
+ bfd_set_error (bfd_error_bad_value);
+ -- num_group;
+ continue;
+ }
+
+ memset (shdr->contents, 0, amt);
+
+ if (bfd_seek (abfd, shdr->sh_offset, SEEK_SET) != 0
+ || (bfd_bread (shdr->contents, shdr->sh_size, abfd)
+ != shdr->sh_size))
+ {
+ _bfd_error_handler
+ (_("%B: invalid size field in group section header: 0x%lx"), abfd, shdr->sh_size);
+ bfd_set_error (bfd_error_bad_value);
+ -- num_group;
+ /* PR 17510: If the group contents are even partially
+ corrupt, do not allow any of the contents to be used. */
+ memset (shdr->contents, 0, amt);
+ continue;
+ }
+
+ /* Translate raw contents, a flag word followed by an
+ array of elf section indices all in target byte order,
+ to the flag word followed by an array of elf section
+ pointers. */
+ src = shdr->contents + shdr->sh_size;
+ dest = (Elf_Internal_Group *) (shdr->contents + amt);
+ while (1)
+ {
+ unsigned int idx;
+
+ src -= 4;
+ --dest;
+ idx = H_GET_32 (abfd, src);
+ if (src == shdr->contents)
+ {
+ dest->flags = idx;
+ if (shdr->bfd_section != NULL && (idx & GRP_COMDAT))
+ shdr->bfd_section->flags
+ |= SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD;
+ break;
+ }
+ if (idx >= shnum)
+ {
+ ((*_bfd_error_handler)
+ (_("%B: invalid SHT_GROUP entry"), abfd));
+ idx = 0;
+ }
+ dest->shdr = elf_elfsections (abfd)[idx];
+ }
+ }
+ }
+
+ /* PR 17510: Corrupt binaries might contain invalid groups. */
+ if (num_group != (unsigned) elf_tdata (abfd)->num_group)
+ {
+ elf_tdata (abfd)->num_group = num_group;
+
+ /* If all groups are invalid then fail. */
+ if (num_group == 0)
+ {
+ elf_tdata (abfd)->group_sect_ptr = NULL;
+ elf_tdata (abfd)->num_group = num_group = -1;
+ (*_bfd_error_handler) (_("%B: no valid group sections found"), abfd);
+ bfd_set_error (bfd_error_bad_value);
+ }
+ }
+ }
+ }
+
+ if (num_group != (unsigned) -1)
+ {
+ unsigned int i;
+
+ for (i = 0; i < num_group; i++)
+ {
+ Elf_Internal_Shdr *shdr = elf_tdata (abfd)->group_sect_ptr[i];
+ Elf_Internal_Group *idx = (Elf_Internal_Group *) shdr->contents;
+ unsigned int n_elt = shdr->sh_size / 4;
+
+ /* Look through this group's sections to see if current
+ section is a member. */
+ while (--n_elt != 0)
+ if ((++idx)->shdr == hdr)
+ {
+ asection *s = NULL;
+
+ /* We are a member of this group. Go looking through
+ other members to see if any others are linked via
+ next_in_group. */
+ idx = (Elf_Internal_Group *) shdr->contents;
+ n_elt = shdr->sh_size / 4;
+ while (--n_elt != 0)
+ if ((s = (++idx)->shdr->bfd_section) != NULL
+ && elf_next_in_group (s) != NULL)
+ break;
+ if (n_elt != 0)
+ {
+ /* Snarf the group name from other member, and
+ insert current section in circular list. */
+ elf_group_name (newsect) = elf_group_name (s);
+ elf_next_in_group (newsect) = elf_next_in_group (s);
+ elf_next_in_group (s) = newsect;
+ }
+ else
+ {
+ const char *gname;
+
+ gname = group_signature (abfd, shdr);
+ if (gname == NULL)
+ return FALSE;
+ elf_group_name (newsect) = gname;
+
+ /* Start a circular list with one element. */
+ elf_next_in_group (newsect) = newsect;
+ }
+
+ /* If the group section has been created, point to the
+ new member. */
+ if (shdr->bfd_section != NULL)
+ elf_next_in_group (shdr->bfd_section) = newsect;
+
+ i = num_group - 1;
+ break;
+ }
+ }
+ }
+
+ if (elf_group_name (newsect) == NULL)
+ {
+ (*_bfd_error_handler) (_("%B: no group info for section %A"),
+ abfd, newsect);
+ return FALSE;
+ }
+ return TRUE;
+}
+
+bfd_boolean
+_bfd_elf_setup_sections (bfd *abfd)
+{
+ unsigned int i;
+ unsigned int num_group = elf_tdata (abfd)->num_group;
+ bfd_boolean result = TRUE;
+ asection *s;
+
+ /* Process SHF_LINK_ORDER. */
+ for (s = abfd->sections; s != NULL; s = s->next)
+ {
+ Elf_Internal_Shdr *this_hdr = &elf_section_data (s)->this_hdr;
+ if ((this_hdr->sh_flags & SHF_LINK_ORDER) != 0)
+ {
+ unsigned int elfsec = this_hdr->sh_link;
+ /* FIXME: The old Intel compiler and old strip/objcopy may
+ not set the sh_link or sh_info fields. Hence we could
+ get the situation where elfsec is 0. */
+ if (elfsec == 0)
+ {
+ const struct elf_backend_data *bed = get_elf_backend_data (abfd);
+ if (bed->link_order_error_handler)
+ bed->link_order_error_handler
+ (_("%B: warning: sh_link not set for section `%A'"),
+ abfd, s);
+ }
+ else
+ {
+ asection *linksec = NULL;
+
+ if (elfsec < elf_numsections (abfd))
+ {
+ this_hdr = elf_elfsections (abfd)[elfsec];
+ linksec = this_hdr->bfd_section;
+ }
+
+ /* PR 1991, 2008:
+ Some strip/objcopy may leave an incorrect value in
+ sh_link. We don't want to proceed. */
+ if (linksec == NULL)
+ {
+ (*_bfd_error_handler)
+ (_("%B: sh_link [%d] in section `%A' is incorrect"),
+ s->owner, s, elfsec);
+ result = FALSE;
+ }
+
+ elf_linked_to_section (s) = linksec;
+ }
+ }
+ }
+
+ /* Process section groups. */
+ if (num_group == (unsigned) -1)
+ return result;
+
+ for (i = 0; i < num_group; i++)
+ {
+ Elf_Internal_Shdr *shdr = elf_tdata (abfd)->group_sect_ptr[i];
+ Elf_Internal_Group *idx = (Elf_Internal_Group *) shdr->contents;
+ unsigned int n_elt = shdr->sh_size / 4;
+
+ while (--n_elt != 0)
+ if ((++idx)->shdr->bfd_section)
+ elf_sec_group (idx->shdr->bfd_section) = shdr->bfd_section;
+ else if (idx->shdr->sh_type == SHT_RELA
+ || idx->shdr->sh_type == SHT_REL)
+ /* We won't include relocation sections in section groups in
+ output object files. We adjust the group section size here
+ so that relocatable link will work correctly when
+ relocation sections are in section group in input object
+ files. */
+ shdr->bfd_section->size -= 4;
+ else
+ {
+ /* There are some unknown sections in the group. */
+ (*_bfd_error_handler)
+ (_("%B: unknown [%d] section `%s' in group [%s]"),
+ abfd,
+ (unsigned int) idx->shdr->sh_type,
+ bfd_elf_string_from_elf_section (abfd,
+ (elf_elfheader (abfd)
+ ->e_shstrndx),
+ idx->shdr->sh_name),
+ shdr->bfd_section->name);
+ result = FALSE;
+ }
+ }
+ return result;
+}
+
+bfd_boolean
+bfd_elf_is_group_section (bfd *abfd ATTRIBUTE_UNUSED, const asection *sec)
+{
+ return elf_next_in_group (sec) != NULL;
+}
+
+/* Make a BFD section from an ELF section. We store a pointer to the
+ BFD section in the bfd_section field of the header. */
+
+bfd_boolean
+_bfd_elf_make_section_from_shdr (bfd *abfd,
+ Elf_Internal_Shdr *hdr,
+ const char *name,
+ int shindex)
+{
+ asection *newsect;
+ flagword flags;
+ const struct elf_backend_data *bed;
+
+ if (hdr->bfd_section != NULL)
+ return TRUE;
+
+ newsect = bfd_make_section_anyway (abfd, name);
+ if (newsect == NULL)
+ return FALSE;
+
+ hdr->bfd_section = newsect;
+ elf_section_data (newsect)->this_hdr = *hdr;
+ elf_section_data (newsect)->this_idx = shindex;
+
+ /* Always use the real type/flags. */
+ elf_section_type (newsect) = hdr->sh_type;
+ elf_section_flags (newsect) = hdr->sh_flags;
+
+ 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_type == SHT_GROUP)
+ flags |= SEC_GROUP | SEC_EXCLUDE;
+ 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;
+ if ((hdr->sh_flags & SHF_MERGE) != 0)
+ {
+ flags |= SEC_MERGE;
+ newsect->entsize = hdr->sh_entsize;
+ if ((hdr->sh_flags & SHF_STRINGS) != 0)
+ flags |= SEC_STRINGS;
+ }
+ if (hdr->sh_flags & SHF_GROUP)
+ if (!setup_group (abfd, hdr, newsect))
+ return FALSE;
+ if ((hdr->sh_flags & SHF_TLS) != 0)
+ flags |= SEC_THREAD_LOCAL;
+ if ((hdr->sh_flags & SHF_EXCLUDE) != 0)
+ flags |= SEC_EXCLUDE;
+
+ if ((flags & SEC_ALLOC) == 0)
+ {
+ /* The debugging sections appear to be recognized only by name,
+ not any sort of flag. Their SEC_ALLOC bits are cleared. */
+ if (name [0] == '.')
+ {
+ const char *p;
+ int n;
+ if (name[1] == 'd')
+ p = ".debug", n = 6;
+ else if (name[1] == 'g' && name[2] == 'n')
+ p = ".gnu.linkonce.wi.", n = 17;
+ else if (name[1] == 'g' && name[2] == 'd')
+ p = ".gdb_index", n = 11; /* yes we really do mean 11. */
+ else if (name[1] == 'l')
+ p = ".line", n = 5;
+ else if (name[1] == 's')
+ p = ".stab", n = 5;
+ else if (name[1] == 'z')
+ p = ".zdebug", n = 7;
+ else
+ p = NULL, n = 0;
+ if (p != NULL && strncmp (name, p, n) == 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 (CONST_STRNEQ (name, ".gnu.linkonce")
+ && elf_next_in_group (newsect) == NULL)
+ flags |= SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD;
+
+ bed = get_elf_backend_data (abfd);
+ if (bed->elf_backend_section_flags)
+ if (! bed->elf_backend_section_flags (&flags, hdr))
+ return FALSE;
+
+ if (! bfd_set_section_flags (abfd, newsect, flags))
+ return FALSE;
+
+ /* We do not parse the PT_NOTE segments as we are interested even in the
+ separate debug info files which may have the segments offsets corrupted.
+ PT_NOTEs from the core files are currently not parsed using BFD. */
+ if (hdr->sh_type == SHT_NOTE)
+ {
+ bfd_byte *contents;
+
+ if (!bfd_malloc_and_get_section (abfd, newsect, &contents))
+ return FALSE;
+
+ elf_parse_notes (abfd, (char *) contents, hdr->sh_size, -1);
+ free (contents);
+ }
+
+ if ((flags & SEC_ALLOC) != 0)
+ {
+ Elf_Internal_Phdr *phdr;
+ unsigned int i, nload;
+
+ /* Some ELF linkers produce binaries with all the program header
+ p_paddr fields zero. If we have such a binary with more than
+ one PT_LOAD header, then leave the section lma equal to vma
+ so that we don't create sections with overlapping lma. */
+ phdr = elf_tdata (abfd)->phdr;
+ for (nload = 0, i = 0; i < elf_elfheader (abfd)->e_phnum; i++, phdr++)
+ if (phdr->p_paddr != 0)
+ break;
+ else if (phdr->p_type == PT_LOAD && phdr->p_memsz != 0)
+ ++nload;
+ if (i >= elf_elfheader (abfd)->e_phnum && nload > 1)
+ return TRUE;
+
+ phdr = elf_tdata (abfd)->phdr;
+ for (i = 0; i < elf_elfheader (abfd)->e_phnum; i++, phdr++)
+ {
+ if (((phdr->p_type == PT_LOAD
+ && (hdr->sh_flags & SHF_TLS) == 0)
+ || phdr->p_type == PT_TLS)
+ && ELF_SECTION_IN_SEGMENT (hdr, phdr))
+ {
+ if ((flags & SEC_LOAD) == 0)
+ newsect->lma = (phdr->p_paddr
+ + hdr->sh_addr - phdr->p_vaddr);
+ else
+ /* We used to use the same adjustment for SEC_LOAD
+ sections, but that doesn't work if the segment
+ is packed with code from multiple VMAs.
+ Instead we calculate the section LMA based on
+ the segment LMA. It is assumed that the
+ segment will contain sections with contiguous
+ LMAs, even if the VMAs are not. */
+ newsect->lma = (phdr->p_paddr
+ + hdr->sh_offset - phdr->p_offset);
+
+ /* With contiguous segments, we can't tell from file
+ offsets whether a section with zero size should
+ be placed at the end of one segment or the
+ beginning of the next. Decide based on vaddr. */
+ if (hdr->sh_addr >= phdr->p_vaddr
+ && (hdr->sh_addr + hdr->sh_size
+ <= phdr->p_vaddr + phdr->p_memsz))
+ break;
+ }
+ }
+ }
+
+ /* Compress/decompress DWARF debug sections with names: .debug_* and
+ .zdebug_*, after the section flags is set. */
+ if ((flags & SEC_DEBUGGING)
+ && ((name[1] == 'd' && name[6] == '_')
+ || (name[1] == 'z' && name[7] == '_')))
+ {
+ enum { nothing, compress, decompress } action = nothing;
+ char *new_name;
+
+ if (bfd_is_section_compressed (abfd, newsect))
+ {
+ /* Compressed section. Check if we should decompress. */
+ if ((abfd->flags & BFD_DECOMPRESS))
+ action = decompress;
+ }
+ else
+ {
+ /* Normal section. Check if we should compress. */
+ if ((abfd->flags & BFD_COMPRESS) && newsect->size != 0)
+ action = compress;
+ }
+
+ new_name = NULL;
+ switch (action)
+ {
+ case nothing:
+ break;
+ case compress:
+ if (!bfd_init_section_compress_status (abfd, newsect))
+ {
+ (*_bfd_error_handler)
+ (_("%B: unable to initialize compress status for section %s"),
+ abfd, name);
+ return FALSE;
+ }
+ if (name[1] != 'z')
+ {
+ unsigned int len = strlen (name);
+
+ new_name = bfd_alloc (abfd, len + 2);
+ if (new_name == NULL)
+ return FALSE;
+ new_name[0] = '.';
+ new_name[1] = 'z';
+ memcpy (new_name + 2, name + 1, len);
+ }
+ break;
+ case decompress:
+ if (!bfd_init_section_decompress_status (abfd, newsect))
+ {
+ (*_bfd_error_handler)
+ (_("%B: unable to initialize decompress status for section %s"),
+ abfd, name);
+ return FALSE;
+ }
+ if (name[1] == 'z')
+ {
+ unsigned int len = strlen (name);
+
+ new_name = bfd_alloc (abfd, len);
+ if (new_name == NULL)
+ return FALSE;
+ new_name[0] = '.';
+ memcpy (new_name + 1, name + 2, len - 1);
+ }
+ break;
+ }
+ if (new_name != NULL)
+ bfd_rename_section (abfd, newsect, new_name);
+ }
+
+ return TRUE;
+}
+
+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 relocatable
+ 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
+ relocatable output against an external symbol. */
+
+bfd_reloc_status_type
+bfd_elf_generic_reloc (bfd *abfd ATTRIBUTE_UNUSED,
+ arelent *reloc_entry,
+ asymbol *symbol,
+ void *data ATTRIBUTE_UNUSED,
+ asection *input_section,
+ bfd *output_bfd,
+ char **error_message ATTRIBUTE_UNUSED)
+{
+ if (output_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;
+}
+
+/* Copy the program header and other data from one object module to
+ another. */
+
+bfd_boolean
+_bfd_elf_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
+{
+ if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
+ || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
+ return TRUE;
+
+ if (!elf_flags_init (obfd))
+ {
+ elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags;
+ elf_flags_init (obfd) = TRUE;
+ }
+
+ elf_gp (obfd) = elf_gp (ibfd);
+
+ /* Also copy the EI_OSABI field. */
+ elf_elfheader (obfd)->e_ident[EI_OSABI] =
+ elf_elfheader (ibfd)->e_ident[EI_OSABI];
+
+ /* Copy object attributes. */
+ _bfd_elf_copy_obj_attributes (ibfd, obfd);
+ return TRUE;
+}
+
+static const char *
+get_segment_type (unsigned int p_type)
+{
+ const char *pt;
+ switch (p_type)
+ {
+ case PT_NULL: pt = "NULL"; break;
+ case PT_LOAD: pt = "LOAD"; break;
+ case PT_DYNAMIC: pt = "DYNAMIC"; break;
+ case PT_INTERP: pt = "INTERP"; break;
+ case PT_NOTE: pt = "NOTE"; break;
+ case PT_SHLIB: pt = "SHLIB"; break;
+ case PT_PHDR: pt = "PHDR"; break;
+ case PT_TLS: pt = "TLS"; break;
+ case PT_GNU_EH_FRAME: pt = "EH_FRAME"; break;
+ case PT_GNU_STACK: pt = "STACK"; break;
+ case PT_GNU_RELRO: pt = "RELRO"; break;
+ default: pt = NULL; break;
+ }
+ return pt;
+}
+
+/* Print out the program headers. */
+
+bfd_boolean
+_bfd_elf_print_private_bfd_data (bfd *abfd, void *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 *pt = get_segment_type (p->p_type);
+ char buf[20];
+
+ if (pt == NULL)
+ {
+ sprintf (buf, "0x%lx", p->p_type);
+ pt = buf;
+ }
+ fprintf (f, "%8s off 0x", pt);
+ bfd_fprintf_vma (abfd, f, p->p_offset);
+ fprintf (f, " vaddr 0x");
+ bfd_fprintf_vma (abfd, f, p->p_vaddr);
+ fprintf (f, " paddr 0x");
+ bfd_fprintf_vma (abfd, f, p->p_paddr);
+ fprintf (f, " align 2**%u\n", bfd_log2 (p->p_align));
+ fprintf (f, " filesz 0x");
+ bfd_fprintf_vma (abfd, f, p->p_filesz);
+ fprintf (f, " memsz 0x");
+ bfd_fprintf_vma (abfd, 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 &~ (unsigned) (PF_R | PF_W | PF_X)) != 0)
+ fprintf (f, " %lx", p->p_flags &~ (unsigned) (PF_R | PF_W | PF_X));
+ fprintf (f, "\n");
+ }
+ }
+
+ s = bfd_get_section_by_name (abfd, ".dynamic");
+ if (s != NULL)
+ {
+ unsigned int elfsec;
+ unsigned long shlink;
+ bfd_byte *extdyn, *extdynend;
+ size_t extdynsize;
+ void (*swap_dyn_in) (bfd *, const void *, Elf_Internal_Dyn *);
+
+ fprintf (f, _("\nDynamic Section:\n"));
+
+ if (!bfd_malloc_and_get_section (abfd, s, &dynbuf))
+ goto error_return;
+
+ elfsec = _bfd_elf_section_from_bfd_section (abfd, s);
+ if (elfsec == SHN_BAD)
+ goto error_return;
+ shlink = 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->size;
+ for (; extdyn < extdynend; extdyn += extdynsize)
+ {
+ Elf_Internal_Dyn dyn;
+ const char *name = "";
+ char ab[20];
+ bfd_boolean stringp;
+ const struct elf_backend_data *bed = get_elf_backend_data (abfd);
+
+ (*swap_dyn_in) (abfd, extdyn, &dyn);
+
+ if (dyn.d_tag == DT_NULL)
+ break;
+
+ stringp = FALSE;
+ switch (dyn.d_tag)
+ {
+ default:
+ if (bed->elf_backend_get_target_dtag)
+ name = (*bed->elf_backend_get_target_dtag) (dyn.d_tag);
+
+ if (!strcmp (name, ""))
+ {
+ 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_BIND_NOW: name = "BIND_NOW"; break;
+ case DT_INIT_ARRAY: name = "INIT_ARRAY"; break;
+ case DT_FINI_ARRAY: name = "FINI_ARRAY"; break;
+ case DT_INIT_ARRAYSZ: name = "INIT_ARRAYSZ"; break;
+ case DT_FINI_ARRAYSZ: name = "FINI_ARRAYSZ"; break;
+ case DT_RUNPATH: name = "RUNPATH"; stringp = TRUE; break;
+ case DT_FLAGS: name = "FLAGS"; break;
+ case DT_PREINIT_ARRAY: name = "PREINIT_ARRAY"; break;
+ case DT_PREINIT_ARRAYSZ: name = "PREINIT_ARRAYSZ"; break;
+ case DT_CHECKSUM: name = "CHECKSUM"; break;
+ case DT_PLTPADSZ: name = "PLTPADSZ"; break;
+ case DT_MOVEENT: name = "MOVEENT"; break;
+ case DT_MOVESZ: name = "MOVESZ"; break;
+ case DT_FEATURE: name = "FEATURE"; break;
+ case DT_POSFLAG_1: name = "POSFLAG_1"; break;
+ case DT_SYMINSZ: name = "SYMINSZ"; break;
+ case DT_SYMINENT: name = "SYMINENT"; break;
+ case DT_CONFIG: name = "CONFIG"; stringp = TRUE; break;
+ case DT_DEPAUDIT: name = "DEPAUDIT"; stringp = TRUE; break;
+ case DT_AUDIT: name = "AUDIT"; stringp = TRUE; break;
+ case DT_PLTPAD: name = "PLTPAD"; break;
+ case DT_MOVETAB: name = "MOVETAB"; break;
+ case DT_SYMINFO: name = "SYMINFO"; break;
+ case DT_RELACOUNT: name = "RELACOUNT"; break;
+ case DT_RELCOUNT: name = "RELCOUNT"; break;
+ case DT_FLAGS_1: name = "FLAGS_1"; 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;
+ case DT_AUXILIARY: name = "AUXILIARY"; stringp = TRUE; break;
+ case DT_USED: name = "USED"; break;
+ case DT_FILTER: name = "FILTER"; stringp = TRUE; break;
+ case DT_GNU_HASH: name = "GNU_HASH"; break;
+ }
+
+ fprintf (f, " %-20s ", name);
+ if (! stringp)
+ {
+ fprintf (f, "0x");
+ bfd_fprintf_vma (abfd, f, dyn.d_un.d_val);
+ }
+ else
+ {
+ const char *string;
+ unsigned int tagv = dyn.d_un.d_val;
+
+ string = bfd_elf_string_from_elf_section (abfd, shlink, tagv);
+ 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, FALSE))
+ 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 ? t->vd_nodename : "<corrupt>");
+ if (t->vd_auxptr != NULL && 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 ? a->vda_nodename : "<corrupt>");
+ 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 ? t->vn_filename : "<corrupt>");
+ 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 ? a->vna_nodename : "<corrupt>");
+ }
+ }
+
+ return TRUE;
+
+ error_return:
+ if (dynbuf != NULL)
+ free (dynbuf);
+ return FALSE;
+}
+
+/* Display ELF-specific fields of a symbol. */
+
+void
+bfd_elf_print_symbol (bfd *abfd,
+ void *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 ");
+ bfd_fprintf_vma (abfd, file, symbol->value);
+ fprintf (file, " %lx", (unsigned long) symbol->flags);
+ break;
+ case bfd_print_symbol_all:
+ {
+ const char *section_name;
+ const char *name = NULL;
+ const struct elf_backend_data *bed;
+ unsigned char st_other;
+ bfd_vma val;
+
+ section_name = symbol->section ? symbol->section->name : "(*none*)";
+
+ bed = get_elf_backend_data (abfd);
+ if (bed->elf_backend_print_symbol_all)
+ name = (*bed->elf_backend_print_symbol_all) (abfd, filep, symbol);
+
+ if (name == NULL)
+ {
+ name = symbol->name;
+ bfd_print_symbol_vandf (abfd, 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. */
+ if (symbol->section && bfd_is_com_section (symbol->section))
+ val = ((elf_symbol_type *) symbol)->internal_elf_sym.st_value;
+ else
+ val = ((elf_symbol_type *) symbol)->internal_elf_sym.st_size;
+ bfd_fprintf_vma (abfd, file, val);
+
+ /* If we have version information, print it. */
+ if (elf_dynversym (abfd) != 0
+ && (elf_dynverdef (abfd) != 0
+ || elf_dynverref (abfd) != 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. */
+ st_other = ((elf_symbol_type *) symbol)->internal_elf_sym.st_other;
+
+ switch (st_other)
+ {
+ case 0: break;
+ case STV_INTERNAL: fprintf (file, " .internal"); break;
+ case STV_HIDDEN: fprintf (file, " .hidden"); break;
+ case STV_PROTECTED: fprintf (file, " .protected"); break;
+ default:
+ /* Some other non-defined flags are also present, so print
+ everything hex. */
+ fprintf (file, " 0x%02x", (unsigned int) st_other);
+ }
+
+ fprintf (file, " %s", name);
+ }
+ break;
+ }
+}
+
+/* Allocate an ELF string table--force the first byte to be zero. */
+
+struct bfd_strtab_hash *
+_bfd_elf_stringtab_init (void)
+{
+ 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. */
+
+bfd_boolean
+bfd_section_from_shdr (bfd *abfd, unsigned int shindex)
+{
+ Elf_Internal_Shdr *hdr;
+ Elf_Internal_Ehdr *ehdr;
+ const struct elf_backend_data *bed;
+ const char *name;
+ bfd_boolean ret = TRUE;
+ static bfd_boolean * sections_being_created = NULL;
+ static bfd * sections_being_created_abfd = NULL;
+ static unsigned int nesting = 0;
+
+ if (shindex >= elf_numsections (abfd))
+ return FALSE;
+
+ if (++ nesting > 3)
+ {
+ /* PR17512: A corrupt ELF binary might contain a recursive group of
+ sections, each the string indicies pointing to the next in the
+ loop. Detect this here, by refusing to load a section that we are
+ already in the process of loading. We only trigger this test if
+ we have nested at least three sections deep as normal ELF binaries
+ can expect to recurse at least once.
+
+ FIXME: It would be better if this array was attached to the bfd,
+ rather than being held in a static pointer. */
+
+ if (sections_being_created_abfd != abfd)
+ sections_being_created = NULL;
+ if (sections_being_created == NULL)
+ {
+ /* FIXME: It would be more efficient to attach this array to the bfd somehow. */
+ sections_being_created = (bfd_boolean *)
+ bfd_zalloc (abfd, elf_numsections (abfd) * sizeof (bfd_boolean));
+ sections_being_created_abfd = abfd;
+ }
+ if (sections_being_created [shindex])
+ {
+ (*_bfd_error_handler)
+ (_("%B: warning: loop in section dependencies detected"), abfd);
+ return FALSE;
+ }
+ sections_being_created [shindex] = TRUE;
+ }
+
+ hdr = elf_elfsections (abfd)[shindex];
+ ehdr = elf_elfheader (abfd);
+ name = bfd_elf_string_from_elf_section (abfd, ehdr->e_shstrndx,
+ hdr->sh_name);
+ if (name == NULL)
+ goto fail;
+
+ bed = get_elf_backend_data (abfd);
+ switch (hdr->sh_type)
+ {
+ case SHT_NULL:
+ /* Inactive section. Throw it away. */
+ goto success;
+
+ case SHT_PROGBITS: /* Normal section with contents. */
+ case SHT_NOBITS: /* .bss section. */
+ case SHT_HASH: /* .hash section. */
+ case SHT_NOTE: /* .note section. */
+ case SHT_INIT_ARRAY: /* .init_array section. */
+ case SHT_FINI_ARRAY: /* .fini_array section. */
+ case SHT_PREINIT_ARRAY: /* .preinit_array section. */
+ case SHT_GNU_LIBLIST: /* .gnu.liblist section. */
+ case SHT_GNU_HASH: /* .gnu.hash section. */
+ ret = _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex);
+ goto success;
+
+ case SHT_DYNAMIC: /* Dynamic linking information. */
+ if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex))
+ goto fail;
+
+ if (hdr->sh_link > elf_numsections (abfd))
+ {
+ /* PR 10478: Accept Solaris binaries with a sh_link
+ field set to SHN_BEFORE or SHN_AFTER. */
+ switch (bfd_get_arch (abfd))
+ {
+ case bfd_arch_i386:
+ case bfd_arch_sparc:
+ if (hdr->sh_link == (SHN_LORESERVE & 0xffff) /* SHN_BEFORE */
+ || hdr->sh_link == ((SHN_LORESERVE + 1) & 0xffff) /* SHN_AFTER */)
+ break;
+ /* Otherwise fall through. */
+ default:
+ goto fail;
+ }
+ }
+ else if (elf_elfsections (abfd)[hdr->sh_link] == NULL)
+ goto fail;
+ else if (elf_elfsections (abfd)[hdr->sh_link]->sh_type != SHT_STRTAB)
+ {
+ Elf_Internal_Shdr *dynsymhdr;
+
+ /* The shared libraries distributed with hpux11 have a bogus
+ sh_link field for the ".dynamic" section. Find the
+ string table for the ".dynsym" section instead. */
+ if (elf_dynsymtab (abfd) != 0)
+ {
+ dynsymhdr = elf_elfsections (abfd)[elf_dynsymtab (abfd)];
+ hdr->sh_link = dynsymhdr->sh_link;
+ }
+ else
+ {
+ unsigned int i, num_sec;
+
+ num_sec = elf_numsections (abfd);
+ for (i = 1; i < num_sec; i++)
+ {
+ dynsymhdr = elf_elfsections (abfd)[i];
+ if (dynsymhdr->sh_type == SHT_DYNSYM)
+ {
+ hdr->sh_link = dynsymhdr->sh_link;
+ break;
+ }
+ }
+ }
+ }
+ goto success;
+
+ case SHT_SYMTAB: /* A symbol table. */
+ if (elf_onesymtab (abfd) == shindex)
+ goto success;
+
+ if (hdr->sh_entsize != bed->s->sizeof_sym)
+ goto fail;
+
+ if (hdr->sh_info * hdr->sh_entsize > hdr->sh_size)
+ {
+ if (hdr->sh_size != 0)
+ goto fail;
+ /* Some assemblers erroneously set sh_info to one with a
+ zero sh_size. ld sees this as a global symbol count
+ of (unsigned) -1. Fix it here. */
+ hdr->sh_info = 0;
+ goto success;
+ }
+
+ 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 relocatable 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,
+ shindex))
+ goto fail;
+
+ /* Go looking for SHT_SYMTAB_SHNDX too, since if there is one we
+ can't read symbols without that section loaded as well. It
+ is most likely specified by the next section header. */
+ if (elf_elfsections (abfd)[elf_symtab_shndx (abfd)]->sh_link != shindex)
+ {
+ unsigned int i, num_sec;
+
+ num_sec = elf_numsections (abfd);
+ for (i = shindex + 1; i < num_sec; i++)
+ {
+ Elf_Internal_Shdr *hdr2 = elf_elfsections (abfd)[i];
+ if (hdr2->sh_type == SHT_SYMTAB_SHNDX
+ && hdr2->sh_link == shindex)
+ break;
+ }
+ if (i == num_sec)
+ for (i = 1; i < shindex; i++)
+ {
+ Elf_Internal_Shdr *hdr2 = elf_elfsections (abfd)[i];
+ if (hdr2->sh_type == SHT_SYMTAB_SHNDX
+ && hdr2->sh_link == shindex)
+ break;
+ }
+ if (i != shindex)
+ ret = bfd_section_from_shdr (abfd, i);
+ }
+ goto success;
+
+ case SHT_DYNSYM: /* A dynamic symbol table. */
+ if (elf_dynsymtab (abfd) == shindex)
+ goto success;
+
+ if (hdr->sh_entsize != bed->s->sizeof_sym)
+ goto fail;
+
+ if (hdr->sh_info * hdr->sh_entsize > hdr->sh_size)
+ {
+ if (hdr->sh_size != 0)
+ goto fail;
+
+ /* Some linkers erroneously set sh_info to one with a
+ zero sh_size. ld sees this as a global symbol count
+ of (unsigned) -1. Fix it here. */
+ hdr->sh_info = 0;
+ goto success;
+ }
+
+ 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. */
+ ret = _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex);
+ goto success;
+
+ case SHT_SYMTAB_SHNDX: /* Symbol section indices when >64k sections. */
+ if (elf_symtab_shndx (abfd) == shindex)
+ goto success;
+
+ BFD_ASSERT (elf_symtab_shndx (abfd) == 0);
+ elf_symtab_shndx (abfd) = shindex;
+ elf_tdata (abfd)->symtab_shndx_hdr = *hdr;
+ elf_elfsections (abfd)[shindex] = &elf_tdata (abfd)->symtab_shndx_hdr;
+ goto success;
+
+ case SHT_STRTAB: /* A string table. */
+ if (hdr->bfd_section != NULL)
+ goto success;
+
+ if (ehdr->e_shstrndx == shindex)
+ {
+ elf_tdata (abfd)->shstrtab_hdr = *hdr;
+ elf_elfsections (abfd)[shindex] = &elf_tdata (abfd)->shstrtab_hdr;
+ goto success;
+ }
+
+ if (elf_elfsections (abfd)[elf_onesymtab (abfd)]->sh_link == shindex)
+ {
+ symtab_strtab:
+ elf_tdata (abfd)->strtab_hdr = *hdr;
+ elf_elfsections (abfd)[shindex] = &elf_tdata (abfd)->strtab_hdr;
+ goto success;
+ }
+
+ if (elf_elfsections (abfd)[elf_dynsymtab (abfd)]->sh_link == shindex)
+ {
+ dynsymtab_strtab:
+ elf_tdata (abfd)->dynstrtab_hdr = *hdr;
+ hdr = &elf_tdata (abfd)->dynstrtab_hdr;
+ elf_elfsections (abfd)[shindex] = hdr;
+ /* We also treat this as a regular section, so that objcopy
+ can handle it. */
+ ret = _bfd_elf_make_section_from_shdr (abfd, hdr, name,
+ shindex);
+ goto success;
+ }
+
+ /* If the string table isn't one of the above, then treat it as a
+ regular section. We need to scan all the headers to be sure,
+ just in case this strtab section appeared before the above. */
+ if (elf_onesymtab (abfd) == 0 || elf_dynsymtab (abfd) == 0)
+ {
+ unsigned int i, num_sec;
+
+ num_sec = elf_numsections (abfd);
+ for (i = 1; i < num_sec; i++)
+ {
+ Elf_Internal_Shdr *hdr2 = elf_elfsections (abfd)[i];
+ if (hdr2->sh_link == shindex)
+ {
+ /* Prevent endless recursion on broken objects. */
+ if (i == shindex)
+ goto fail;
+ if (! bfd_section_from_shdr (abfd, i))
+ goto fail;
+ if (elf_onesymtab (abfd) == i)
+ goto symtab_strtab;
+ if (elf_dynsymtab (abfd) == i)
+ goto dynsymtab_strtab;
+ }
+ }
+ }
+ ret = _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex);
+ goto success;
+
+ case SHT_REL:
+ case SHT_RELA:
+ /* *These* do a lot of work -- but build no sections! */
+ {
+ asection *target_sect;
+ Elf_Internal_Shdr *hdr2, **p_hdr;
+ unsigned int num_sec = elf_numsections (abfd);
+ struct bfd_elf_section_data *esdt;
+ bfd_size_type amt;
+
+ if (hdr->sh_entsize
+ != (bfd_size_type) (hdr->sh_type == SHT_REL
+ ? bed->s->sizeof_rel : bed->s->sizeof_rela))
+ goto fail;
+
+ /* Check for a bogus link to avoid crashing. */
+ if (hdr->sh_link >= num_sec)
+ {
+ ((*_bfd_error_handler)
+ (_("%B: invalid link %lu for reloc section %s (index %u)"),
+ abfd, hdr->sh_link, name, shindex));
+ ret = _bfd_elf_make_section_from_shdr (abfd, hdr, name,
+ shindex);
+ goto success;
+ }
+
+ /* 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.
+
+ Don't do it on executable nor shared library. */
+ if ((abfd->flags & (DYNAMIC | EXEC_P)) == 0
+ && elf_elfsections (abfd)[hdr->sh_link]->sh_type != SHT_SYMTAB
+ && elf_elfsections (abfd)[hdr->sh_link]->sh_type != SHT_DYNSYM)
+ {
+ unsigned int scan;
+ int found;
+
+ found = 0;
+ for (scan = 1; scan < num_sec; 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
+ || elf_elfsections (abfd)[hdr->sh_link]->sh_type == SHT_DYNSYM)
+ && ! bfd_section_from_shdr (abfd, hdr->sh_link))
+ goto fail;
+
+ /* 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. We also
+ can't use it as a reloc section if it points to the null
+ section, an invalid section, another reloc section, or its
+ sh_link points to the null section. */
+ if (hdr->sh_link != elf_onesymtab (abfd)
+ || hdr->sh_link == SHN_UNDEF
+ || hdr->sh_info == SHN_UNDEF
+ || hdr->sh_info >= num_sec
+ || elf_elfsections (abfd)[hdr->sh_info]->sh_type == SHT_REL
+ || elf_elfsections (abfd)[hdr->sh_info]->sh_type == SHT_RELA)
+ {
+ ret = _bfd_elf_make_section_from_shdr (abfd, hdr, name,
+ shindex);
+ goto success;
+ }
+
+ if (! bfd_section_from_shdr (abfd, hdr->sh_info))
+ goto fail;
+
+ target_sect = bfd_section_from_elf_index (abfd, hdr->sh_info);
+ if (target_sect == NULL)
+ goto fail;
+
+ esdt = elf_section_data (target_sect);
+ if (hdr->sh_type == SHT_RELA)
+ p_hdr = &esdt->rela.hdr;
+ else
+ p_hdr = &esdt->rel.hdr;
+
+ BFD_ASSERT (*p_hdr == NULL);
+ amt = sizeof (*hdr2);
+ hdr2 = (Elf_Internal_Shdr *) bfd_alloc (abfd, amt);
+ if (hdr2 == NULL)
+ goto fail;
+ *hdr2 = *hdr;
+ *p_hdr = hdr2;
+ elf_elfsections (abfd)[shindex] = hdr2;
+ target_sect->reloc_count += NUM_SHDR_ENTRIES (hdr);
+ target_sect->flags |= SEC_RELOC;
+ target_sect->relocation = NULL;
+ target_sect->rel_filepos = hdr->sh_offset;
+ /* In the section to which the relocations apply, mark whether
+ its relocations are of the REL or RELA variety. */
+ if (hdr->sh_size != 0)
+ {
+ if (hdr->sh_type == SHT_RELA)
+ target_sect->use_rela_p = 1;
+ }
+ abfd->flags |= HAS_RELOC;
+ goto success;
+ }
+
+ case SHT_GNU_verdef:
+ elf_dynverdef (abfd) = shindex;
+ elf_tdata (abfd)->dynverdef_hdr = *hdr;
+ ret = _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex);
+ goto success;
+
+ case SHT_GNU_versym:
+ if (hdr->sh_entsize != sizeof (Elf_External_Versym))
+ goto fail;
+
+ elf_dynversym (abfd) = shindex;
+ elf_tdata (abfd)->dynversym_hdr = *hdr;
+ ret = _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex);
+ goto success;
+
+ case SHT_GNU_verneed:
+ elf_dynverref (abfd) = shindex;
+ elf_tdata (abfd)->dynverref_hdr = *hdr;
+ ret = _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex);
+ goto success;
+
+ case SHT_SHLIB:
+ goto success;
+
+ case SHT_GROUP:
+ if (! IS_VALID_GROUP_SECTION_HEADER (hdr, GRP_ENTRY_SIZE))
+ goto fail;
+
+ if (!_bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex))
+ goto fail;
+
+ if (hdr->contents != NULL)
+ {
+ Elf_Internal_Group *idx = (Elf_Internal_Group *) hdr->contents;
+ unsigned int n_elt = hdr->sh_size / GRP_ENTRY_SIZE;
+ asection *s;
+
+ if (idx->flags & GRP_COMDAT)
+ hdr->bfd_section->flags
+ |= SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD;
+
+ /* We try to keep the same section order as it comes in. */
+ idx += n_elt;
+ while (--n_elt != 0)
+ {
+ --idx;
+
+ if (idx->shdr != NULL
+ && (s = idx->shdr->bfd_section) != NULL
+ && elf_next_in_group (s) != NULL)
+ {
+ elf_next_in_group (hdr->bfd_section) = s;
+ break;
+ }
+ }
+ }
+ goto success;
+
+ default:
+ /* Possibly an attributes section. */
+ if (hdr->sh_type == SHT_GNU_ATTRIBUTES
+ || hdr->sh_type == bed->obj_attrs_section_type)
+ {
+ if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex))
+ goto fail;
+ _bfd_elf_parse_attributes (abfd, hdr);
+ goto success;
+ }
+
+ /* Check for any processor-specific section types. */
+ if (bed->elf_backend_section_from_shdr (abfd, hdr, name, shindex))
+ goto success;
+
+ if (hdr->sh_type >= SHT_LOUSER && hdr->sh_type <= SHT_HIUSER)
+ {
+ if ((hdr->sh_flags & SHF_ALLOC) != 0)
+ /* FIXME: How to properly handle allocated section reserved
+ for applications? */
+ (*_bfd_error_handler)
+ (_("%B: don't know how to handle allocated, application "
+ "specific section `%s' [0x%8x]"),
+ abfd, name, hdr->sh_type);
+ else
+ {
+ /* Allow sections reserved for applications. */
+ ret = _bfd_elf_make_section_from_shdr (abfd, hdr, name,
+ shindex);
+ goto success;
+ }
+ }
+ else if (hdr->sh_type >= SHT_LOPROC
+ && hdr->sh_type <= SHT_HIPROC)
+ /* FIXME: We should handle this section. */
+ (*_bfd_error_handler)
+ (_("%B: don't know how to handle processor specific section "
+ "`%s' [0x%8x]"),
+ abfd, name, hdr->sh_type);
+ else if (hdr->sh_type >= SHT_LOOS && hdr->sh_type <= SHT_HIOS)
+ {
+ /* Unrecognised OS-specific sections. */
+ if ((hdr->sh_flags & SHF_OS_NONCONFORMING) != 0)
+ /* SHF_OS_NONCONFORMING indicates that special knowledge is
+ required to correctly process the section and the file should
+ be rejected with an error message. */
+ (*_bfd_error_handler)
+ (_("%B: don't know how to handle OS specific section "
+ "`%s' [0x%8x]"),
+ abfd, name, hdr->sh_type);
+ else
+ {
+ /* Otherwise it should be processed. */
+ ret = _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex);
+ goto success;
+ }
+ }
+ else
+ /* FIXME: We should handle this section. */
+ (*_bfd_error_handler)
+ (_("%B: don't know how to handle section `%s' [0x%8x]"),
+ abfd, name, hdr->sh_type);
+
+ goto fail;
+ }
+
+ fail:
+ ret = FALSE;
+ success:
+ if (sections_being_created && sections_being_created_abfd == abfd)
+ sections_being_created [shindex] = FALSE;
+ if (-- nesting == 0)
+ {
+ sections_being_created = NULL;
+ sections_being_created_abfd = abfd;
+ }
+ return ret;
+}
+
+/* Return the local symbol specified by ABFD, R_SYMNDX. */
+
+Elf_Internal_Sym *
+bfd_sym_from_r_symndx (struct sym_cache *cache,
+ bfd *abfd,
+ unsigned long r_symndx)
+{
+ unsigned int ent = r_symndx % LOCAL_SYM_CACHE_SIZE;
+
+ if (cache->abfd != abfd || cache->indx[ent] != r_symndx)
+ {
+ Elf_Internal_Shdr *symtab_hdr;
+ unsigned char esym[sizeof (Elf64_External_Sym)];
+ Elf_External_Sym_Shndx eshndx;
+
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+ if (bfd_elf_get_elf_syms (abfd, symtab_hdr, 1, r_symndx,
+ &cache->sym[ent], esym, &eshndx) == NULL)
+ return NULL;
+
+ if (cache->abfd != abfd)
+ {
+ memset (cache->indx, -1, sizeof (cache->indx));
+ cache->abfd = abfd;
+ }
+ cache->indx[ent] = r_symndx;
+ }
+
+ return &cache->sym[ent];
+}
+
+/* Given an ELF section number, retrieve the corresponding BFD
+ section. */
+
+asection *
+bfd_section_from_elf_index (bfd *abfd, unsigned int sec_index)
+{
+ if (sec_index >= elf_numsections (abfd))
+ return NULL;
+ return elf_elfsections (abfd)[sec_index]->bfd_section;
+}
+
+static const struct bfd_elf_special_section special_sections_b[] =
+{
+ { STRING_COMMA_LEN (".bss"), -2, SHT_NOBITS, SHF_ALLOC + SHF_WRITE },
+ { NULL, 0, 0, 0, 0 }
+};
+
+static const struct bfd_elf_special_section special_sections_c[] =
+{
+ { STRING_COMMA_LEN (".comment"), 0, SHT_PROGBITS, 0 },
+ { NULL, 0, 0, 0, 0 }
+};
+
+static const struct bfd_elf_special_section special_sections_d[] =
+{
+ { STRING_COMMA_LEN (".data"), -2, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE },
+ { STRING_COMMA_LEN (".data1"), 0, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE },
+ /* There are more DWARF sections than these, but they needn't be added here
+ unless you have to cope with broken compilers that don't emit section
+ attributes or you want to help the user writing assembler. */
+ { STRING_COMMA_LEN (".debug"), 0, SHT_PROGBITS, 0 },
+ { STRING_COMMA_LEN (".debug_line"), 0, SHT_PROGBITS, 0 },
+ { STRING_COMMA_LEN (".debug_info"), 0, SHT_PROGBITS, 0 },
+ { STRING_COMMA_LEN (".debug_abbrev"), 0, SHT_PROGBITS, 0 },
+ { STRING_COMMA_LEN (".debug_aranges"), 0, SHT_PROGBITS, 0 },
+ { STRING_COMMA_LEN (".dynamic"), 0, SHT_DYNAMIC, SHF_ALLOC },
+ { STRING_COMMA_LEN (".dynstr"), 0, SHT_STRTAB, SHF_ALLOC },
+ { STRING_COMMA_LEN (".dynsym"), 0, SHT_DYNSYM, SHF_ALLOC },
+ { NULL, 0, 0, 0, 0 }
+};
+
+static const struct bfd_elf_special_section special_sections_f[] =
+{
+ { STRING_COMMA_LEN (".fini"), 0, SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR },
+ { STRING_COMMA_LEN (".fini_array"), 0, SHT_FINI_ARRAY, SHF_ALLOC + SHF_WRITE },
+ { NULL, 0, 0, 0, 0 }
+};
+
+static const struct bfd_elf_special_section special_sections_g[] =
+{
+ { STRING_COMMA_LEN (".gnu.linkonce.b"), -2, SHT_NOBITS, SHF_ALLOC + SHF_WRITE },
+ { STRING_COMMA_LEN (".gnu.lto_"), -1, SHT_PROGBITS, SHF_EXCLUDE },
+ { STRING_COMMA_LEN (".got"), 0, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE },
+ { STRING_COMMA_LEN (".gnu.version"), 0, SHT_GNU_versym, 0 },
+ { STRING_COMMA_LEN (".gnu.version_d"), 0, SHT_GNU_verdef, 0 },
+ { STRING_COMMA_LEN (".gnu.version_r"), 0, SHT_GNU_verneed, 0 },
+ { STRING_COMMA_LEN (".gnu.liblist"), 0, SHT_GNU_LIBLIST, SHF_ALLOC },
+ { STRING_COMMA_LEN (".gnu.conflict"), 0, SHT_RELA, SHF_ALLOC },
+ { STRING_COMMA_LEN (".gnu.hash"), 0, SHT_GNU_HASH, SHF_ALLOC },
+ { NULL, 0, 0, 0, 0 }
+};
+
+static const struct bfd_elf_special_section special_sections_h[] =
+{
+ { STRING_COMMA_LEN (".hash"), 0, SHT_HASH, SHF_ALLOC },
+ { NULL, 0, 0, 0, 0 }
+};
+
+static const struct bfd_elf_special_section special_sections_i[] =
+{
+ { STRING_COMMA_LEN (".init"), 0, SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR },
+ { STRING_COMMA_LEN (".init_array"), 0, SHT_INIT_ARRAY, SHF_ALLOC + SHF_WRITE },
+ { STRING_COMMA_LEN (".interp"), 0, SHT_PROGBITS, 0 },
+ { NULL, 0, 0, 0, 0 }
+};
+
+static const struct bfd_elf_special_section special_sections_l[] =
+{
+ { STRING_COMMA_LEN (".line"), 0, SHT_PROGBITS, 0 },
+ { NULL, 0, 0, 0, 0 }
+};
+
+static const struct bfd_elf_special_section special_sections_n[] =
+{
+ { STRING_COMMA_LEN (".note.GNU-stack"), 0, SHT_PROGBITS, 0 },
+ { STRING_COMMA_LEN (".note"), -1, SHT_NOTE, 0 },
+ { NULL, 0, 0, 0, 0 }
+};
+
+static const struct bfd_elf_special_section special_sections_p[] =
+{
+ { STRING_COMMA_LEN (".preinit_array"), 0, SHT_PREINIT_ARRAY, SHF_ALLOC + SHF_WRITE },
+ { STRING_COMMA_LEN (".plt"), 0, SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR },
+ { NULL, 0, 0, 0, 0 }
+};
+
+static const struct bfd_elf_special_section special_sections_r[] =
+{
+ { STRING_COMMA_LEN (".rodata"), -2, SHT_PROGBITS, SHF_ALLOC },
+ { STRING_COMMA_LEN (".rodata1"), 0, SHT_PROGBITS, SHF_ALLOC },
+ { STRING_COMMA_LEN (".rela"), -1, SHT_RELA, 0 },
+ { STRING_COMMA_LEN (".rel"), -1, SHT_REL, 0 },
+ { NULL, 0, 0, 0, 0 }
+};
+
+static const struct bfd_elf_special_section special_sections_s[] =
+{
+ { STRING_COMMA_LEN (".shstrtab"), 0, SHT_STRTAB, 0 },
+ { STRING_COMMA_LEN (".strtab"), 0, SHT_STRTAB, 0 },
+ { STRING_COMMA_LEN (".symtab"), 0, SHT_SYMTAB, 0 },
+ /* See struct bfd_elf_special_section declaration for the semantics of
+ this special case where .prefix_length != strlen (.prefix). */
+ { ".stabstr", 5, 3, SHT_STRTAB, 0 },
+ { NULL, 0, 0, 0, 0 }
+};
+
+static const struct bfd_elf_special_section special_sections_t[] =
+{
+ { STRING_COMMA_LEN (".text"), -2, SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR },
+ { STRING_COMMA_LEN (".tbss"), -2, SHT_NOBITS, SHF_ALLOC + SHF_WRITE + SHF_TLS },
+ { STRING_COMMA_LEN (".tdata"), -2, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE + SHF_TLS },
+ { NULL, 0, 0, 0, 0 }
+};
+
+static const struct bfd_elf_special_section special_sections_z[] =
+{
+ { STRING_COMMA_LEN (".zdebug_line"), 0, SHT_PROGBITS, 0 },
+ { STRING_COMMA_LEN (".zdebug_info"), 0, SHT_PROGBITS, 0 },
+ { STRING_COMMA_LEN (".zdebug_abbrev"), 0, SHT_PROGBITS, 0 },
+ { STRING_COMMA_LEN (".zdebug_aranges"), 0, SHT_PROGBITS, 0 },
+ { NULL, 0, 0, 0, 0 }
+};
+
+static const struct bfd_elf_special_section * const special_sections[] =
+{
+ special_sections_b, /* 'b' */
+ special_sections_c, /* 'c' */
+ special_sections_d, /* 'd' */
+ NULL, /* 'e' */
+ special_sections_f, /* 'f' */
+ special_sections_g, /* 'g' */
+ special_sections_h, /* 'h' */
+ special_sections_i, /* 'i' */
+ NULL, /* 'j' */
+ NULL, /* 'k' */
+ special_sections_l, /* 'l' */
+ NULL, /* 'm' */
+ special_sections_n, /* 'n' */
+ NULL, /* 'o' */
+ special_sections_p, /* 'p' */
+ NULL, /* 'q' */
+ special_sections_r, /* 'r' */
+ special_sections_s, /* 's' */
+ special_sections_t, /* 't' */
+ NULL, /* 'u' */
+ NULL, /* 'v' */
+ NULL, /* 'w' */
+ NULL, /* 'x' */
+ NULL, /* 'y' */
+ special_sections_z /* 'z' */
+};
+
+const struct bfd_elf_special_section *
+_bfd_elf_get_special_section (const char *name,
+ const struct bfd_elf_special_section *spec,
+ unsigned int rela)
+{
+ int i;
+ int len;
+
+ len = strlen (name);
+
+ for (i = 0; spec[i].prefix != NULL; i++)
+ {
+ int suffix_len;
+ int prefix_len = spec[i].prefix_length;
+
+ if (len < prefix_len)
+ continue;
+ if (memcmp (name, spec[i].prefix, prefix_len) != 0)
+ continue;
+
+ suffix_len = spec[i].suffix_length;
+ if (suffix_len <= 0)
+ {
+ if (name[prefix_len] != 0)
+ {
+ if (suffix_len == 0)
+ continue;
+ if (name[prefix_len] != '.'
+ && (suffix_len == -2
+ || (rela && spec[i].type == SHT_REL)))
+ continue;
+ }
+ }
+ else
+ {
+ if (len < prefix_len + suffix_len)
+ continue;
+ if (memcmp (name + len - suffix_len,
+ spec[i].prefix + prefix_len,
+ suffix_len) != 0)
+ continue;
+ }
+ return &spec[i];
+ }
+
+ return NULL;
+}
+
+const struct bfd_elf_special_section *
+_bfd_elf_get_sec_type_attr (bfd *abfd, asection *sec)
+{
+ int i;
+ const struct bfd_elf_special_section *spec;
+ const struct elf_backend_data *bed;
+
+ /* See if this is one of the special sections. */
+ if (sec->name == NULL)
+ return NULL;
+
+ bed = get_elf_backend_data (abfd);
+ spec = bed->special_sections;
+ if (spec)
+ {
+ spec = _bfd_elf_get_special_section (sec->name,
+ bed->special_sections,
+ sec->use_rela_p);
+ if (spec != NULL)
+ return spec;
+ }
+
+ if (sec->name[0] != '.')
+ return NULL;
+
+ i = sec->name[1] - 'b';
+ if (i < 0 || i > 'z' - 'b')
+ return NULL;
+
+ spec = special_sections[i];
+
+ if (spec == NULL)
+ return NULL;
+
+ return _bfd_elf_get_special_section (sec->name, spec, sec->use_rela_p);
+}
+
+bfd_boolean
+_bfd_elf_new_section_hook (bfd *abfd, asection *sec)
+{
+ struct bfd_elf_section_data *sdata;
+ const struct elf_backend_data *bed;
+ const struct bfd_elf_special_section *ssect;
+
+ sdata = (struct bfd_elf_section_data *) sec->used_by_bfd;
+ if (sdata == NULL)
+ {
+ sdata = (struct bfd_elf_section_data *) bfd_zalloc (abfd,
+ sizeof (*sdata));
+ if (sdata == NULL)
+ return FALSE;
+ sec->used_by_bfd = sdata;
+ }
+
+ /* Indicate whether or not this section should use RELA relocations. */
+ bed = get_elf_backend_data (abfd);
+ sec->use_rela_p = bed->default_use_rela_p;
+
+ /* When we read a file, we don't need to set ELF section type and
+ flags. They will be overridden in _bfd_elf_make_section_from_shdr
+ anyway. We will set ELF section type and flags for all linker
+ created sections. If user specifies BFD section flags, we will
+ set ELF section type and flags based on BFD section flags in
+ elf_fake_sections. Special handling for .init_array/.fini_array
+ output sections since they may contain .ctors/.dtors input
+ sections. We don't want _bfd_elf_init_private_section_data to
+ copy ELF section type from .ctors/.dtors input sections. */
+ if (abfd->direction != read_direction
+ || (sec->flags & SEC_LINKER_CREATED) != 0)
+ {
+ ssect = (*bed->get_sec_type_attr) (abfd, sec);
+ if (ssect != NULL
+ && (!sec->flags
+ || (sec->flags & SEC_LINKER_CREATED) != 0
+ || ssect->type == SHT_INIT_ARRAY
+ || ssect->type == SHT_FINI_ARRAY))
+ {
+ elf_section_type (sec) = ssect->type;
+ elf_section_flags (sec) = ssect->attr;
+ }
+ }
+
+ return _bfd_generic_new_section_hook (abfd, sec);
+}
+
+/* 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 its initialized and uninitialized parts.
+
+ */
+
+bfd_boolean
+_bfd_elf_make_section_from_phdr (bfd *abfd,
+ Elf_Internal_Phdr *hdr,
+ int hdr_index,
+ const char *type_name)
+{
+ asection *newsect;
+ char *name;
+ char namebuf[64];
+ size_t len;
+ int split;
+
+ split = ((hdr->p_memsz > 0)
+ && (hdr->p_filesz > 0)
+ && (hdr->p_memsz > hdr->p_filesz));
+
+ if (hdr->p_filesz > 0)
+ {
+ sprintf (namebuf, "%s%d%s", type_name, hdr_index, split ? "a" : "");
+ len = strlen (namebuf) + 1;
+ name = (char *) bfd_alloc (abfd, len);
+ if (!name)
+ return FALSE;
+ memcpy (name, namebuf, len);
+ newsect = bfd_make_section (abfd, name);
+ if (newsect == NULL)
+ return FALSE;
+ newsect->vma = hdr->p_vaddr;
+ newsect->lma = hdr->p_paddr;
+ newsect->size = hdr->p_filesz;
+ newsect->filepos = hdr->p_offset;
+ newsect->flags |= SEC_HAS_CONTENTS;
+ newsect->alignment_power = bfd_log2 (hdr->p_align);
+ 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 (hdr->p_memsz > hdr->p_filesz)
+ {
+ bfd_vma align;
+
+ sprintf (namebuf, "%s%d%s", type_name, hdr_index, split ? "b" : "");
+ len = strlen (namebuf) + 1;
+ name = (char *) bfd_alloc (abfd, len);
+ if (!name)
+ return FALSE;
+ memcpy (name, namebuf, len);
+ 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->size = hdr->p_memsz - hdr->p_filesz;
+ newsect->filepos = hdr->p_offset + hdr->p_filesz;
+ align = newsect->vma & -newsect->vma;
+ if (align == 0 || align > hdr->p_align)
+ align = hdr->p_align;
+ newsect->alignment_power = bfd_log2 (align);
+ if (hdr->p_type == PT_LOAD)
+ {
+ /* Hack for gdb. Segments that have not been modified do
+ not have their contents written to a core file, on the
+ assumption that a debugger can find the contents in the
+ executable. We flag this case by setting the fake
+ section size to zero. Note that "real" bss sections will
+ always have their contents dumped to the core file. */
+ if (bfd_get_format (abfd) == bfd_core)
+ newsect->size = 0;
+ 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;
+}
+
+bfd_boolean
+bfd_section_from_phdr (bfd *abfd, Elf_Internal_Phdr *hdr, int hdr_index)
+{
+ const struct elf_backend_data *bed;
+
+ switch (hdr->p_type)
+ {
+ case PT_NULL:
+ return _bfd_elf_make_section_from_phdr (abfd, hdr, hdr_index, "null");
+
+ case PT_LOAD:
+ return _bfd_elf_make_section_from_phdr (abfd, hdr, hdr_index, "load");
+
+ case PT_DYNAMIC:
+ return _bfd_elf_make_section_from_phdr (abfd, hdr, hdr_index, "dynamic");
+
+ case PT_INTERP:
+ return _bfd_elf_make_section_from_phdr (abfd, hdr, hdr_index, "interp");
+
+ case PT_NOTE:
+ if (! _bfd_elf_make_section_from_phdr (abfd, hdr, hdr_index, "note"))
+ return FALSE;
+ if (! elf_read_notes (abfd, hdr->p_offset, hdr->p_filesz))
+ return FALSE;
+ return TRUE;
+
+ case PT_SHLIB:
+ return _bfd_elf_make_section_from_phdr (abfd, hdr, hdr_index, "shlib");
+
+ case PT_PHDR:
+ return _bfd_elf_make_section_from_phdr (abfd, hdr, hdr_index, "phdr");
+
+ case PT_GNU_EH_FRAME:
+ return _bfd_elf_make_section_from_phdr (abfd, hdr, hdr_index,
+ "eh_frame_hdr");
+
+ case PT_GNU_STACK:
+ return _bfd_elf_make_section_from_phdr (abfd, hdr, hdr_index, "stack");
+
+ case PT_GNU_RELRO:
+ return _bfd_elf_make_section_from_phdr (abfd, hdr, hdr_index, "relro");
+
+ default:
+ /* Check for any processor-specific program segment types. */
+ bed = get_elf_backend_data (abfd);
+ return bed->elf_backend_section_from_phdr (abfd, hdr, hdr_index, "proc");
+ }
+}
+
+/* Return the REL_HDR for SEC, assuming there is only a single one, either
+ REL or RELA. */
+
+Elf_Internal_Shdr *
+_bfd_elf_single_rel_hdr (asection *sec)
+{
+ if (elf_section_data (sec)->rel.hdr)
+ {
+ BFD_ASSERT (elf_section_data (sec)->rela.hdr == NULL);
+ return elf_section_data (sec)->rel.hdr;
+ }
+ else
+ return elf_section_data (sec)->rela.hdr;
+}
+
+/* Allocate and initialize a section-header for a new reloc section,
+ containing relocations against ASECT. It is stored in RELDATA. If
+ USE_RELA_P is TRUE, we use RELA relocations; otherwise, we use REL
+ relocations. */
+
+static bfd_boolean
+_bfd_elf_init_reloc_shdr (bfd *abfd,
+ struct bfd_elf_section_reloc_data *reldata,
+ asection *asect,
+ bfd_boolean use_rela_p)
+{
+ Elf_Internal_Shdr *rel_hdr;
+ char *name;
+ const struct elf_backend_data *bed = get_elf_backend_data (abfd);
+ bfd_size_type amt;
+
+ amt = sizeof (Elf_Internal_Shdr);
+ BFD_ASSERT (reldata->hdr == NULL);
+ rel_hdr = bfd_zalloc (abfd, amt);
+ reldata->hdr = rel_hdr;
+
+ amt = sizeof ".rela" + strlen (asect->name);
+ name = (char *) bfd_alloc (abfd, amt);
+ if (name == NULL)
+ return FALSE;
+ sprintf (name, "%s%s", use_rela_p ? ".rela" : ".rel", asect->name);
+ rel_hdr->sh_name =
+ (unsigned int) _bfd_elf_strtab_add (elf_shstrtab (abfd), name,
+ FALSE);
+ if (rel_hdr->sh_name == (unsigned int) -1)
+ return FALSE;
+ rel_hdr->sh_type = use_rela_p ? SHT_RELA : SHT_REL;
+ rel_hdr->sh_entsize = (use_rela_p
+ ? bed->s->sizeof_rela
+ : bed->s->sizeof_rel);
+ rel_hdr->sh_addralign = (bfd_vma) 1 << bed->s->log_file_align;
+ rel_hdr->sh_flags = 0;
+ rel_hdr->sh_addr = 0;
+ rel_hdr->sh_size = 0;
+ rel_hdr->sh_offset = 0;
+
+ return TRUE;
+}
+
+/* Return the default section type based on the passed in section flags. */
+
+int
+bfd_elf_get_default_section_type (flagword flags)
+{
+ if ((flags & SEC_ALLOC) != 0
+ && (flags & (SEC_LOAD | SEC_HAS_CONTENTS)) == 0)
+ return SHT_NOBITS;
+ return SHT_PROGBITS;
+}
+
+struct fake_section_arg
+{
+ struct bfd_link_info *link_info;
+ bfd_boolean failed;
+};
+
+/* Set up an ELF internal section header for a section. */
+
+static void
+elf_fake_sections (bfd *abfd, asection *asect, void *fsarg)
+{
+ struct fake_section_arg *arg = (struct fake_section_arg *)fsarg;
+ const struct elf_backend_data *bed = get_elf_backend_data (abfd);
+ struct bfd_elf_section_data *esd = elf_section_data (asect);
+ Elf_Internal_Shdr *this_hdr;
+ unsigned int sh_type;
+
+ if (arg->failed)
+ {
+ /* We already failed; just get out of the bfd_map_over_sections
+ loop. */
+ return;
+ }
+
+ this_hdr = &esd->this_hdr;
+
+ this_hdr->sh_name = (unsigned int) _bfd_elf_strtab_add (elf_shstrtab (abfd),
+ asect->name, FALSE);
+ if (this_hdr->sh_name == (unsigned int) -1)
+ {
+ arg->failed = TRUE;
+ return;
+ }
+
+ /* Don't clear sh_flags. Assembler may set additional bits. */
+
+ 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->size;
+ this_hdr->sh_link = 0;
+ this_hdr->sh_addralign = (bfd_vma) 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;
+
+ /* If the section type is unspecified, we set it based on
+ asect->flags. */
+ if ((asect->flags & SEC_GROUP) != 0)
+ sh_type = SHT_GROUP;
+ else
+ sh_type = bfd_elf_get_default_section_type (asect->flags);
+
+ if (this_hdr->sh_type == SHT_NULL)
+ this_hdr->sh_type = sh_type;
+ else if (this_hdr->sh_type == SHT_NOBITS
+ && sh_type == SHT_PROGBITS
+ && (asect->flags & SEC_ALLOC) != 0)
+ {
+ /* Warn if we are changing a NOBITS section to PROGBITS, but
+ allow the link to proceed. This can happen when users link
+ non-bss input sections to bss output sections, or emit data
+ to a bss output section via a linker script. */
+ (*_bfd_error_handler)
+ (_("warning: section `%A' type changed to PROGBITS"), asect);
+ this_hdr->sh_type = sh_type;
+ }
+
+ switch (this_hdr->sh_type)
+ {
+ default:
+ break;
+
+ case SHT_STRTAB:
+ case SHT_INIT_ARRAY:
+ case SHT_FINI_ARRAY:
+ case SHT_PREINIT_ARRAY:
+ case SHT_NOTE:
+ case SHT_NOBITS:
+ case SHT_PROGBITS:
+ break;
+
+ case SHT_HASH:
+ this_hdr->sh_entsize = bed->s->sizeof_hash_entry;
+ break;
+
+ case SHT_DYNSYM:
+ this_hdr->sh_entsize = bed->s->sizeof_sym;
+ break;
+
+ case SHT_DYNAMIC:
+ this_hdr->sh_entsize = bed->s->sizeof_dyn;
+ break;
+
+ case SHT_RELA:
+ if (get_elf_backend_data (abfd)->may_use_rela_p)
+ this_hdr->sh_entsize = bed->s->sizeof_rela;
+ break;
+
+ case SHT_REL:
+ if (get_elf_backend_data (abfd)->may_use_rel_p)
+ this_hdr->sh_entsize = bed->s->sizeof_rel;
+ break;
+
+ case SHT_GNU_versym:
+ this_hdr->sh_entsize = sizeof (Elf_External_Versym);
+ break;
+
+ case 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);
+ break;
+
+ case 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);
+ break;
+
+ case SHT_GROUP:
+ this_hdr->sh_entsize = GRP_ENTRY_SIZE;
+ break;
+
+ case SHT_GNU_HASH:
+ this_hdr->sh_entsize = bed->s->arch_size == 64 ? 0 : 4;
+ break;
+ }
+
+ 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;
+ if ((asect->flags & SEC_MERGE) != 0)
+ {
+ this_hdr->sh_flags |= SHF_MERGE;
+ this_hdr->sh_entsize = asect->entsize;
+ if ((asect->flags & SEC_STRINGS) != 0)
+ this_hdr->sh_flags |= SHF_STRINGS;
+ }
+ if ((asect->flags & SEC_GROUP) == 0 && elf_group_name (asect) != NULL)
+ this_hdr->sh_flags |= SHF_GROUP;
+ if ((asect->flags & SEC_THREAD_LOCAL) != 0)
+ {
+ this_hdr->sh_flags |= SHF_TLS;
+ if (asect->size == 0
+ && (asect->flags & SEC_HAS_CONTENTS) == 0)
+ {
+ struct bfd_link_order *o = asect->map_tail.link_order;
+
+ this_hdr->sh_size = 0;
+ if (o != NULL)
+ {
+ this_hdr->sh_size = o->offset + o->size;
+ if (this_hdr->sh_size != 0)
+ this_hdr->sh_type = SHT_NOBITS;
+ }
+ }
+ }
+ if ((asect->flags & (SEC_GROUP | SEC_EXCLUDE)) == SEC_EXCLUDE)
+ this_hdr->sh_flags |= SHF_EXCLUDE;
+
+ /* If the section has relocs, set up a section header for the
+ SHT_REL[A] section. If two relocation sections are required for
+ this section, it is up to the processor-specific back-end to
+ create the other. */
+ if ((asect->flags & SEC_RELOC) != 0)
+ {
+ /* When doing a relocatable link, create both REL and RELA sections if
+ needed. */
+ if (arg->link_info
+ /* Do the normal setup if we wouldn't create any sections here. */
+ && esd->rel.count + esd->rela.count > 0
+ && (arg->link_info->relocatable || arg->link_info->emitrelocations))
+ {
+ if (esd->rel.count && esd->rel.hdr == NULL
+ && !_bfd_elf_init_reloc_shdr (abfd, &esd->rel, asect, FALSE))
+ {
+ arg->failed = TRUE;
+ return;
+ }
+ if (esd->rela.count && esd->rela.hdr == NULL
+ && !_bfd_elf_init_reloc_shdr (abfd, &esd->rela, asect, TRUE))
+ {
+ arg->failed = TRUE;
+ return;
+ }
+ }
+ else if (!_bfd_elf_init_reloc_shdr (abfd,
+ (asect->use_rela_p
+ ? &esd->rela : &esd->rel),
+ asect,
+ asect->use_rela_p))
+ arg->failed = TRUE;
+ }
+
+ /* Check for processor-specific section types. */
+ sh_type = this_hdr->sh_type;
+ if (bed->elf_backend_fake_sections
+ && !(*bed->elf_backend_fake_sections) (abfd, this_hdr, asect))
+ arg->failed = TRUE;
+
+ if (sh_type == SHT_NOBITS && asect->size != 0)
+ {
+ /* Don't change the header type from NOBITS if we are being
+ called for objcopy --only-keep-debug. */
+ this_hdr->sh_type = sh_type;
+ }
+}
+
+/* Fill in the contents of a SHT_GROUP section. Called from
+ _bfd_elf_compute_section_file_positions for gas, objcopy, and
+ when ELF targets use the generic linker, ld. Called for ld -r
+ from bfd_elf_final_link. */
+
+void
+bfd_elf_set_group_contents (bfd *abfd, asection *sec, void *failedptrarg)
+{
+ bfd_boolean *failedptr = (bfd_boolean *) failedptrarg;
+ asection *elt, *first;
+ unsigned char *loc;
+ bfd_boolean gas;
+
+ /* Ignore linker created group section. See elfNN_ia64_object_p in
+ elfxx-ia64.c. */
+ if (((sec->flags & (SEC_GROUP | SEC_LINKER_CREATED)) != SEC_GROUP)
+ || *failedptr)
+ return;
+
+ if (elf_section_data (sec)->this_hdr.sh_info == 0)
+ {
+ unsigned long symindx = 0;
+
+ /* elf_group_id will have been set up by objcopy and the
+ generic linker. */
+ if (elf_group_id (sec) != NULL)
+ symindx = elf_group_id (sec)->udata.i;
+
+ if (symindx == 0)
+ {
+ /* If called from the assembler, swap_out_syms will have set up
+ elf_section_syms. */
+ BFD_ASSERT (elf_section_syms (abfd) != NULL);
+ symindx = elf_section_syms (abfd)[sec->index]->udata.i;
+ }
+ elf_section_data (sec)->this_hdr.sh_info = symindx;
+ }
+ else if (elf_section_data (sec)->this_hdr.sh_info == (unsigned int) -2)
+ {
+ /* The ELF backend linker sets sh_info to -2 when the group
+ signature symbol is global, and thus the index can't be
+ set until all local symbols are output. */
+ asection *igroup = elf_sec_group (elf_next_in_group (sec));
+ struct bfd_elf_section_data *sec_data = elf_section_data (igroup);
+ unsigned long symndx = sec_data->this_hdr.sh_info;
+ unsigned long extsymoff = 0;
+ struct elf_link_hash_entry *h;
+
+ if (!elf_bad_symtab (igroup->owner))
+ {
+ Elf_Internal_Shdr *symtab_hdr;
+
+ symtab_hdr = &elf_tdata (igroup->owner)->symtab_hdr;
+ extsymoff = symtab_hdr->sh_info;
+ }
+ h = elf_sym_hashes (igroup->owner)[symndx - extsymoff];
+ 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;
+
+ elf_section_data (sec)->this_hdr.sh_info = h->indx;
+ }
+
+ /* The contents won't be allocated for "ld -r" or objcopy. */
+ gas = TRUE;
+ if (sec->contents == NULL)
+ {
+ gas = FALSE;
+ sec->contents = (unsigned char *) bfd_alloc (abfd, sec->size);
+
+ /* Arrange for the section to be written out. */
+ elf_section_data (sec)->this_hdr.contents = sec->contents;
+ if (sec->contents == NULL)
+ {
+ *failedptr = TRUE;
+ return;
+ }
+ }
+
+ loc = sec->contents + sec->size;
+
+ /* Get the pointer to the first section in the group that gas
+ squirreled away here. objcopy arranges for this to be set to the
+ start of the input section group. */
+ first = elt = elf_next_in_group (sec);
+
+ /* First element is a flag word. Rest of section is elf section
+ indices for all the sections of the group. Write them backwards
+ just to keep the group in the same order as given in .section
+ directives, not that it matters. */
+ while (elt != NULL)
+ {
+ asection *s;
+
+ s = elt;
+ if (!gas)
+ s = s->output_section;
+ if (s != NULL
+ && !bfd_is_abs_section (s))
+ {
+ unsigned int idx = elf_section_data (s)->this_idx;
+
+ loc -= 4;
+ H_PUT_32 (abfd, idx, loc);
+ }
+ elt = elf_next_in_group (elt);
+ if (elt == first)
+ break;
+ }
+
+ if ((loc -= 4) != sec->contents)
+ abort ();
+
+ H_PUT_32 (abfd, sec->flags & SEC_LINK_ONCE ? GRP_COMDAT : 0, loc);
+}
+
+/* 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 bfd_boolean
+assign_section_numbers (bfd *abfd, struct bfd_link_info *link_info)
+{
+ struct elf_obj_tdata *t = elf_tdata (abfd);
+ asection *sec;
+ unsigned int section_number, secn;
+ Elf_Internal_Shdr **i_shdrp;
+ struct bfd_elf_section_data *d;
+ bfd_boolean need_symtab;
+
+ section_number = 1;
+
+ _bfd_elf_strtab_clear_all_refs (elf_shstrtab (abfd));
+
+ /* SHT_GROUP sections are in relocatable files only. */
+ if (link_info == NULL || link_info->relocatable)
+ {
+ /* Put SHT_GROUP sections first. */
+ for (sec = abfd->sections; sec != NULL; sec = sec->next)
+ {
+ d = elf_section_data (sec);
+
+ if (d->this_hdr.sh_type == SHT_GROUP)
+ {
+ if (sec->flags & SEC_LINKER_CREATED)
+ {
+ /* Remove the linker created SHT_GROUP sections. */
+ bfd_section_list_remove (abfd, sec);
+ abfd->section_count--;
+ }
+ else
+ d->this_idx = section_number++;
+ }
+ }
+ }
+
+ for (sec = abfd->sections; sec; sec = sec->next)
+ {
+ d = elf_section_data (sec);
+
+ if (d->this_hdr.sh_type != SHT_GROUP)
+ d->this_idx = section_number++;
+ _bfd_elf_strtab_addref (elf_shstrtab (abfd), d->this_hdr.sh_name);
+ if (d->rel.hdr)
+ {
+ d->rel.idx = section_number++;
+ _bfd_elf_strtab_addref (elf_shstrtab (abfd), d->rel.hdr->sh_name);
+ }
+ else
+ d->rel.idx = 0;
+
+ if (d->rela.hdr)
+ {
+ d->rela.idx = section_number++;
+ _bfd_elf_strtab_addref (elf_shstrtab (abfd), d->rela.hdr->sh_name);
+ }
+ else
+ d->rela.idx = 0;
+ }
+
+ elf_shstrtab_sec (abfd) = section_number++;
+ _bfd_elf_strtab_addref (elf_shstrtab (abfd), t->shstrtab_hdr.sh_name);
+ elf_elfheader (abfd)->e_shstrndx = elf_shstrtab_sec (abfd);
+
+ need_symtab = (bfd_get_symcount (abfd) > 0
+ || (link_info == NULL
+ && ((abfd->flags & (EXEC_P | DYNAMIC | HAS_RELOC))
+ == HAS_RELOC)));
+ if (need_symtab)
+ {
+ elf_onesymtab (abfd) = section_number++;
+ _bfd_elf_strtab_addref (elf_shstrtab (abfd), t->symtab_hdr.sh_name);
+ if (section_number > ((SHN_LORESERVE - 2) & 0xFFFF))
+ {
+ elf_symtab_shndx (abfd) = section_number++;
+ t->symtab_shndx_hdr.sh_name
+ = (unsigned int) _bfd_elf_strtab_add (elf_shstrtab (abfd),
+ ".symtab_shndx", FALSE);
+ if (t->symtab_shndx_hdr.sh_name == (unsigned int) -1)
+ return FALSE;
+ }
+ elf_strtab_sec (abfd) = section_number++;
+ _bfd_elf_strtab_addref (elf_shstrtab (abfd), t->strtab_hdr.sh_name);
+ }
+
+ if (section_number >= SHN_LORESERVE)
+ {
+ _bfd_error_handler (_("%B: too many sections: %u"),
+ abfd, section_number);
+ return FALSE;
+ }
+
+ _bfd_elf_strtab_finalize (elf_shstrtab (abfd));
+ t->shstrtab_hdr.sh_size = _bfd_elf_strtab_size (elf_shstrtab (abfd));
+
+ elf_numsections (abfd) = 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_zalloc2 (abfd, section_number,
+ sizeof (Elf_Internal_Shdr *));
+ if (i_shdrp == NULL)
+ return FALSE;
+
+ i_shdrp[0] = (Elf_Internal_Shdr *) bfd_zalloc (abfd,
+ sizeof (Elf_Internal_Shdr));
+ if (i_shdrp[0] == NULL)
+ {
+ bfd_release (abfd, i_shdrp);
+ return FALSE;
+ }
+
+ elf_elfsections (abfd) = i_shdrp;
+
+ i_shdrp[elf_shstrtab_sec (abfd)] = &t->shstrtab_hdr;
+ if (need_symtab)
+ {
+ i_shdrp[elf_onesymtab (abfd)] = &t->symtab_hdr;
+ if (elf_numsections (abfd) > (SHN_LORESERVE & 0xFFFF))
+ {
+ i_shdrp[elf_symtab_shndx (abfd)] = &t->symtab_shndx_hdr;
+ t->symtab_shndx_hdr.sh_link = elf_onesymtab (abfd);
+ }
+ i_shdrp[elf_strtab_sec (abfd)] = &t->strtab_hdr;
+ t->symtab_hdr.sh_link = elf_strtab_sec (abfd);
+ }
+
+ for (sec = abfd->sections; sec; sec = sec->next)
+ {
+ asection *s;
+ const char *name;
+
+ d = elf_section_data (sec);
+
+ i_shdrp[d->this_idx] = &d->this_hdr;
+ if (d->rel.idx != 0)
+ i_shdrp[d->rel.idx] = d->rel.hdr;
+ if (d->rela.idx != 0)
+ i_shdrp[d->rela.idx] = d->rela.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 = elf_onesymtab (abfd);
+ d->rel.hdr->sh_info = d->this_idx;
+ d->rel.hdr->sh_flags |= SHF_INFO_LINK;
+ }
+ if (d->rela.idx != 0)
+ {
+ d->rela.hdr->sh_link = elf_onesymtab (abfd);
+ d->rela.hdr->sh_info = d->this_idx;
+ d->rela.hdr->sh_flags |= SHF_INFO_LINK;
+ }
+
+ /* We need to set up sh_link for SHF_LINK_ORDER. */
+ if ((d->this_hdr.sh_flags & SHF_LINK_ORDER) != 0)
+ {
+ s = elf_linked_to_section (sec);
+ if (s)
+ {
+ /* elf_linked_to_section points to the input section. */
+ if (link_info != NULL)
+ {
+ /* Check discarded linkonce section. */
+ if (discarded_section (s))
+ {
+ asection *kept;
+ (*_bfd_error_handler)
+ (_("%B: sh_link of section `%A' points to discarded section `%A' of `%B'"),
+ abfd, d->this_hdr.bfd_section,
+ s, s->owner);
+ /* Point to the kept section if it has the same
+ size as the discarded one. */
+ kept = _bfd_elf_check_kept_section (s, link_info);
+ if (kept == NULL)
+ {
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+ s = kept;
+ }
+
+ s = s->output_section;
+ BFD_ASSERT (s != NULL);
+ }
+ else
+ {
+ /* Handle objcopy. */
+ if (s->output_section == NULL)
+ {
+ (*_bfd_error_handler)
+ (_("%B: sh_link of section `%A' points to removed section `%A' of `%B'"),
+ abfd, d->this_hdr.bfd_section, s, s->owner);
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+ s = s->output_section;
+ }
+ d->this_hdr.sh_link = elf_section_data (s)->this_idx;
+ }
+ else
+ {
+ /* PR 290:
+ The Intel C compiler generates SHT_IA_64_UNWIND with
+ SHF_LINK_ORDER. But it doesn't set the sh_link or
+ sh_info fields. Hence we could get the situation
+ where s is NULL. */
+ const struct elf_backend_data *bed
+ = get_elf_backend_data (abfd);
+ if (bed->link_order_error_handler)
+ bed->link_order_error_handler
+ (_("%B: warning: sh_link not set for section `%A'"),
+ abfd, sec);
+ }
+ }
+
+ 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;
+ d->this_hdr.sh_flags |= SHF_INFO_LINK;
+ }
+ 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 (CONST_STRNEQ (sec->name, ".stab")
+ && 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;
+ memcpy (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. */
+ if (elf_section_data (s)->this_hdr.sh_entsize == 0)
+ elf_section_data (s)->this_hdr.sh_entsize
+ = 4 + 2 * bfd_get_arch_size (abfd) / 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_GNU_LIBLIST:
+ /* sh_link is the section header index of the prelink library
+ list used for the dynamic entries, or the symbol table, or
+ the version strings. */
+ s = bfd_get_section_by_name (abfd, (sec->flags & SEC_ALLOC)
+ ? ".dynstr" : ".gnu.libstr");
+ if (s != NULL)
+ d->this_hdr.sh_link = elf_section_data (s)->this_idx;
+ break;
+
+ case SHT_HASH:
+ case SHT_GNU_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;
+
+ case SHT_GROUP:
+ d->this_hdr.sh_link = elf_onesymtab (abfd);
+ }
+ }
+
+ for (secn = 1; secn < section_number; ++secn)
+ if (i_shdrp[secn] == NULL)
+ i_shdrp[secn] = i_shdrp[0];
+ else
+ i_shdrp[secn]->sh_name = _bfd_elf_strtab_offset (elf_shstrtab (abfd),
+ i_shdrp[secn]->sh_name);
+ return TRUE;
+}
+
+static bfd_boolean
+sym_is_global (bfd *abfd, asymbol *sym)
+{
+ /* If the backend has a special mapping, use it. */
+ const struct elf_backend_data *bed = get_elf_backend_data (abfd);
+ if (bed->elf_backend_sym_is_global)
+ return (*bed->elf_backend_sym_is_global) (abfd, sym);
+
+ return ((sym->flags & (BSF_GLOBAL | BSF_WEAK | BSF_GNU_UNIQUE)) != 0
+ || bfd_is_und_section (bfd_get_section (sym))
+ || bfd_is_com_section (bfd_get_section (sym)));
+}
+
+/* Don't output section symbols for sections that are not going to be
+ output, that are duplicates or there is no BFD section. */
+
+static bfd_boolean
+ignore_section_sym (bfd *abfd, asymbol *sym)
+{
+ elf_symbol_type *type_ptr;
+
+ if ((sym->flags & BSF_SECTION_SYM) == 0)
+ return FALSE;
+
+ type_ptr = elf_symbol_from (abfd, sym);
+ return ((type_ptr != NULL
+ && type_ptr->internal_elf_sym.st_shndx != 0
+ && bfd_is_abs_section (sym->section))
+ || !(sym->section->owner == abfd
+ || (sym->section->output_section->owner == abfd
+ && sym->section->output_offset == 0)
+ || bfd_is_abs_section (sym->section)));
+}
+
+/* Map symbol from it's internal number to the external number, moving
+ all local symbols to be at the head of the list. */
+
+static bfd_boolean
+elf_map_symbols (bfd *abfd, unsigned int *pnum_locals)
+{
+ unsigned int symcount = bfd_get_symcount (abfd);
+ asymbol **syms = bfd_get_outsymbols (abfd);
+ asymbol **sect_syms;
+ unsigned int num_locals = 0;
+ unsigned int num_globals = 0;
+ unsigned int num_locals2 = 0;
+ unsigned int num_globals2 = 0;
+ int max_index = 0;
+ unsigned int idx;
+ asection *asect;
+ asymbol **new_syms;
+
+#ifdef DEBUG
+ fprintf (stderr, "elf_map_symbols\n");
+ fflush (stderr);
+#endif
+
+ for (asect = abfd->sections; asect; asect = asect->next)
+ {
+ if (max_index < asect->index)
+ max_index = asect->index;
+ }
+
+ max_index++;
+ sect_syms = (asymbol **) bfd_zalloc2 (abfd, max_index, sizeof (asymbol *));
+ if (sect_syms == NULL)
+ return FALSE;
+ elf_section_syms (abfd) = sect_syms;
+ elf_num_section_syms (abfd) = max_index;
+
+ /* Init sect_syms entries for any section symbols we have already
+ decided to output. */
+ for (idx = 0; idx < symcount; idx++)
+ {
+ asymbol *sym = syms[idx];
+
+ if ((sym->flags & BSF_SECTION_SYM) != 0
+ && sym->value == 0
+ && !ignore_section_sym (abfd, sym)
+ && !bfd_is_abs_section (sym->section))
+ {
+ asection *sec = sym->section;
+
+ if (sec->owner != abfd)
+ sec = sec->output_section;
+
+ sect_syms[sec->index] = syms[idx];
+ }
+ }
+
+ /* Classify all of the symbols. */
+ for (idx = 0; idx < symcount; idx++)
+ {
+ if (sym_is_global (abfd, syms[idx]))
+ num_globals++;
+ else if (!ignore_section_sym (abfd, syms[idx]))
+ num_locals++;
+ }
+
+ /* We will be adding a section symbol for each normal BFD section. Most
+ sections will already have a section symbol in outsymbols, but
+ eg. SHT_GROUP sections will not, and we need the section symbol mapped
+ at least in that case. */
+ for (asect = abfd->sections; asect; asect = asect->next)
+ {
+ if (sect_syms[asect->index] == NULL)
+ {
+ if (!sym_is_global (abfd, asect->symbol))
+ num_locals++;
+ else
+ num_globals++;
+ }
+ }
+
+ /* Now sort the symbols so the local symbols are first. */
+ new_syms = (asymbol **) bfd_alloc2 (abfd, num_locals + num_globals,
+ sizeof (asymbol *));
+
+ if (new_syms == NULL)
+ return FALSE;
+
+ for (idx = 0; idx < symcount; idx++)
+ {
+ asymbol *sym = syms[idx];
+ unsigned int i;
+
+ if (sym_is_global (abfd, sym))
+ i = num_locals + num_globals2++;
+ else if (!ignore_section_sym (abfd, sym))
+ i = num_locals2++;
+ else
+ continue;
+ new_syms[i] = sym;
+ sym->udata.i = i + 1;
+ }
+ for (asect = abfd->sections; asect; asect = asect->next)
+ {
+ if (sect_syms[asect->index] == NULL)
+ {
+ asymbol *sym = asect->symbol;
+ unsigned int i;
+
+ sect_syms[asect->index] = 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);
+
+ *pnum_locals = num_locals;
+ return TRUE;
+}
+
+/* Align to the maximum file alignment that could be required for any
+ ELF data structure. */
+
+static inline file_ptr
+align_file_position (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. */
+
+file_ptr
+_bfd_elf_assign_file_position_for_section (Elf_Internal_Shdr *i_shdrp,
+ file_ptr offset,
+ bfd_boolean align)
+{
+ if (align && i_shdrp->sh_addralign > 1)
+ offset = BFD_ALIGN (offset, i_shdrp->sh_addralign);
+ 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. */
+
+bfd_boolean
+_bfd_elf_compute_section_file_positions (bfd *abfd,
+ struct bfd_link_info *link_info)
+{
+ const struct elf_backend_data *bed = get_elf_backend_data (abfd);
+ struct fake_section_arg fsargs;
+ bfd_boolean failed;
+ struct bfd_strtab_hash *strtab = NULL;
+ Elf_Internal_Shdr *shstrtab_hdr;
+ bfd_boolean need_symtab;
+
+ 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;
+
+ /* Post process the headers if necessary. */
+ (*bed->elf_backend_post_process_headers) (abfd, link_info);
+
+ fsargs.failed = FALSE;
+ fsargs.link_info = link_info;
+ bfd_map_over_sections (abfd, elf_fake_sections, &fsargs);
+ if (fsargs.failed)
+ return FALSE;
+
+ if (!assign_section_numbers (abfd, link_info))
+ return FALSE;
+
+ /* The backend linker builds symbol table information itself. */
+ need_symtab = (link_info == NULL
+ && (bfd_get_symcount (abfd) > 0
+ || ((abfd->flags & (EXEC_P | DYNAMIC | HAS_RELOC))
+ == HAS_RELOC)));
+ if (need_symtab)
+ {
+ /* 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;
+ }
+
+ failed = FALSE;
+ if (link_info == NULL)
+ {
+ bfd_map_over_sections (abfd, bfd_elf_set_group_contents, &failed);
+ if (failed)
+ 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_elf_strtab_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, link_info))
+ return FALSE;
+
+ if (need_symtab)
+ {
+ file_ptr off;
+ Elf_Internal_Shdr *hdr;
+
+ off = elf_next_file_pos (abfd);
+
+ hdr = &elf_tdata (abfd)->symtab_hdr;
+ off = _bfd_elf_assign_file_position_for_section (hdr, off, TRUE);
+
+ hdr = &elf_tdata (abfd)->symtab_shndx_hdr;
+ if (hdr->sh_size != 0)
+ 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_next_file_pos (abfd) = 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;
+}
+
+/* Make an initial estimate of the size of the program header. If we
+ get the number wrong here, we'll redo section placement. */
+
+static bfd_size_type
+get_program_header_size (bfd *abfd, struct bfd_link_info *info)
+{
+ size_t segs;
+ asection *s;
+ const struct elf_backend_data *bed;
+
+ /* 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;
+ }
+
+ if (info != NULL && info->relro)
+ {
+ /* We need a PT_GNU_RELRO segment. */
+ ++segs;
+ }
+
+ if (elf_eh_frame_hdr (abfd))
+ {
+ /* We need a PT_GNU_EH_FRAME segment. */
+ ++segs;
+ }
+
+ if (elf_stack_flags (abfd))
+ {
+ /* We need a PT_GNU_STACK segment. */
+ ++segs;
+ }
+
+ for (s = abfd->sections; s != NULL; s = s->next)
+ {
+ if ((s->flags & SEC_LOAD) != 0
+ && CONST_STRNEQ (s->name, ".note"))
+ {
+ /* We need a PT_NOTE segment. */
+ ++segs;
+ /* Try to create just one PT_NOTE segment
+ for all adjacent loadable .note* sections.
+ gABI requires that within a PT_NOTE segment
+ (and also inside of each SHT_NOTE section)
+ each note is padded to a multiple of 4 size,
+ so we check whether the sections are correctly
+ aligned. */
+ if (s->alignment_power == 2)
+ while (s->next != NULL
+ && s->next->alignment_power == 2
+ && (s->next->flags & SEC_LOAD) != 0
+ && CONST_STRNEQ (s->next->name, ".note"))
+ s = s->next;
+ }
+ }
+
+ for (s = abfd->sections; s != NULL; s = s->next)
+ {
+ if (s->flags & SEC_THREAD_LOCAL)
+ {
+ /* We need a PT_TLS segment. */
+ ++segs;
+ break;
+ }
+ }
+
+ /* Let the backend count up any program headers it might need. */
+ bed = get_elf_backend_data (abfd);
+ if (bed->elf_backend_additional_program_headers)
+ {
+ int a;
+
+ a = (*bed->elf_backend_additional_program_headers) (abfd, info);
+ if (a == -1)
+ abort ();
+ segs += a;
+ }
+
+ return segs * bed->s->sizeof_phdr;
+}
+
+/* Find the segment that contains the output_section of section. */
+
+Elf_Internal_Phdr *
+_bfd_elf_find_segment_containing_section (bfd * abfd, asection * section)
+{
+ struct elf_segment_map *m;
+ Elf_Internal_Phdr *p;
+
+ for (m = elf_seg_map (abfd), p = elf_tdata (abfd)->phdr;
+ m != NULL;
+ m = m->next, p++)
+ {
+ int i;
+
+ for (i = m->count - 1; i >= 0; i--)
+ if (m->sections[i] == section)
+ return p;
+ }
+
+ return NULL;
+}
+
+/* Create a mapping from a set of sections to a program segment. */
+
+static struct elf_segment_map *
+make_mapping (bfd *abfd,
+ asection **sections,
+ unsigned int from,
+ unsigned int to,
+ bfd_boolean phdr)
+{
+ struct elf_segment_map *m;
+ unsigned int i;
+ asection **hdrpp;
+ bfd_size_type amt;
+
+ amt = sizeof (struct elf_segment_map);
+ amt += (to - from - 1) * sizeof (asection *);
+ m = (struct elf_segment_map *) bfd_zalloc (abfd, amt);
+ 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;
+}
+
+/* Create the PT_DYNAMIC segment, which includes DYNSEC. Returns NULL
+ on failure. */
+
+struct elf_segment_map *
+_bfd_elf_make_dynamic_segment (bfd *abfd, asection *dynsec)
+{
+ struct elf_segment_map *m;
+
+ m = (struct elf_segment_map *) bfd_zalloc (abfd,
+ sizeof (struct elf_segment_map));
+ if (m == NULL)
+ return NULL;
+ m->next = NULL;
+ m->p_type = PT_DYNAMIC;
+ m->count = 1;
+ m->sections[0] = dynsec;
+
+ return m;
+}
+
+/* Possibly add or remove segments from the segment map. */
+
+static bfd_boolean
+elf_modify_segment_map (bfd *abfd,
+ struct bfd_link_info *info,
+ bfd_boolean remove_empty_load)
+{
+ struct elf_segment_map **m;
+ const struct elf_backend_data *bed;
+
+ /* The placement algorithm assumes that non allocated sections are
+ not in PT_LOAD segments. We ensure this here by removing such
+ sections from the segment map. We also remove excluded
+ sections. Finally, any PT_LOAD segment without sections is
+ removed. */
+ m = &elf_seg_map (abfd);
+ while (*m)
+ {
+ unsigned int i, new_count;
+
+ for (new_count = 0, i = 0; i < (*m)->count; i++)
+ {
+ if (((*m)->sections[i]->flags & SEC_EXCLUDE) == 0
+ && (((*m)->sections[i]->flags & SEC_ALLOC) != 0
+ || (*m)->p_type != PT_LOAD))
+ {
+ (*m)->sections[new_count] = (*m)->sections[i];
+ new_count++;
+ }
+ }
+ (*m)->count = new_count;
+
+ if (remove_empty_load && (*m)->p_type == PT_LOAD && (*m)->count == 0)
+ *m = (*m)->next;
+ else
+ m = &(*m)->next;
+ }
+
+ bed = get_elf_backend_data (abfd);
+ if (bed->elf_backend_modify_segment_map != NULL)
+ {
+ if (!(*bed->elf_backend_modify_segment_map) (abfd, info))
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/* Set up a mapping from BFD sections to program segments. */
+
+bfd_boolean
+_bfd_elf_map_sections_to_segments (bfd *abfd, struct bfd_link_info *info)
+{
+ unsigned int count;
+ struct elf_segment_map *m;
+ asection **sections = NULL;
+ const struct elf_backend_data *bed = get_elf_backend_data (abfd);
+ bfd_boolean no_user_phdrs;
+
+ no_user_phdrs = elf_seg_map (abfd) == NULL;
+
+ if (info != NULL)
+ info->user_phdrs = !no_user_phdrs;
+
+ if (no_user_phdrs && bfd_count_sections (abfd) != 0)
+ {
+ asection *s;
+ unsigned int i;
+ struct elf_segment_map *mfirst;
+ struct elf_segment_map **pm;
+ asection *last_hdr;
+ bfd_vma last_size;
+ unsigned int phdr_index;
+ bfd_vma maxpagesize;
+ asection **hdrpp;
+ bfd_boolean phdr_in_segment = TRUE;
+ bfd_boolean writable;
+ int tls_count = 0;
+ asection *first_tls = NULL;
+ asection *dynsec, *eh_frame_hdr;
+ bfd_size_type amt;
+ bfd_vma addr_mask, wrap_to = 0;
+
+ /* Select the allocated sections, and sort them. */
+
+ sections = (asection **) bfd_malloc2 (bfd_count_sections (abfd),
+ sizeof (asection *));
+ if (sections == NULL)
+ goto error_return;
+
+ /* Calculate top address, avoiding undefined behaviour of shift
+ left operator when shift count is equal to size of type
+ being shifted. */
+ addr_mask = ((bfd_vma) 1 << (bfd_arch_bits_per_address (abfd) - 1)) - 1;
+ addr_mask = (addr_mask << 1) + 1;
+
+ i = 0;
+ for (s = abfd->sections; s != NULL; s = s->next)
+ {
+ if ((s->flags & SEC_ALLOC) != 0)
+ {
+ sections[i] = s;
+ ++i;
+ /* A wrapping section potentially clashes with header. */
+ if (((s->lma + s->size) & addr_mask) < (s->lma & addr_mask))
+ wrap_to = (s->lma + s->size) & addr_mask;
+ }
+ }
+ 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)
+ {
+ amt = sizeof (struct elf_segment_map);
+ m = (struct elf_segment_map *) bfd_zalloc (abfd, amt);
+ 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;
+
+ amt = sizeof (struct elf_segment_map);
+ m = (struct elf_segment_map *) bfd_zalloc (abfd, amt);
+ 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;
+ last_size = 0;
+ phdr_index = 0;
+ maxpagesize = bed->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 = elf_program_header_size (abfd);
+
+ if (phdr_size == (bfd_size_type) -1)
+ phdr_size = get_program_header_size (abfd, info);
+ phdr_size += bed->s->sizeof_ehdr;
+ if ((abfd->flags & D_PAGED) == 0
+ || (sections[0]->lma & addr_mask) < phdr_size
+ || ((sections[0]->lma & addr_mask) % maxpagesize
+ < phdr_size % maxpagesize)
+ || (sections[0]->lma & addr_mask & -maxpagesize) < wrap_to)
+ phdr_in_segment = FALSE;
+ }
+
+ for (i = 0, hdrpp = sections; i < count; i++, hdrpp++)
+ {
+ asection *hdr;
+ bfd_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 (hdr->lma < last_hdr->lma + last_size
+ || last_hdr->lma + last_size < last_hdr->lma)
+ {
+ /* If this section has a load address that makes it overlap
+ the previous section, then we need a new segment. */
+ new_segment = TRUE;
+ }
+ /* In the next test we have to be careful when last_hdr->lma is close
+ to the end of the address space. If the aligned address wraps
+ around to the start of the address space, then there are no more
+ pages left in memory and it is OK to assume that the current
+ section can be included in the current segment. */
+ else if ((BFD_ALIGN (last_hdr->lma + last_size, maxpagesize) + maxpagesize
+ > last_hdr->lma)
+ && (BFD_ALIGN (last_hdr->lma + last_size, maxpagesize) + maxpagesize
+ <= hdr->lma))
+ {
+ /* 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 | SEC_THREAD_LOCAL)) == 0
+ && (hdr->flags & (SEC_LOAD | SEC_THREAD_LOCAL)) != 0)
+ {
+ /* We don't want to put a loadable section after a
+ nonloadable section in the same segment.
+ Consider .tbss sections as loadable for this purpose. */
+ 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
+ && (((last_hdr->lma + last_size - 1) & -maxpagesize)
+ != (hdr->lma & -maxpagesize)))
+ {
+ /* 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;
+ }
+
+ /* Allow interested parties a chance to override our decision. */
+ if (last_hdr != NULL
+ && info != NULL
+ && info->callbacks->override_segment_assignment != NULL)
+ new_segment
+ = info->callbacks->override_segment_assignment (info, abfd, hdr,
+ last_hdr,
+ new_segment);
+
+ if (! new_segment)
+ {
+ if ((hdr->flags & SEC_READONLY) == 0)
+ writable = TRUE;
+ last_hdr = hdr;
+ /* .tbss sections effectively have zero size. */
+ if ((hdr->flags & (SEC_THREAD_LOCAL | SEC_LOAD))
+ != SEC_THREAD_LOCAL)
+ last_size = hdr->size;
+ else
+ last_size = 0;
+ 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;
+ /* .tbss sections effectively have zero size. */
+ if ((hdr->flags & (SEC_THREAD_LOCAL | SEC_LOAD)) != SEC_THREAD_LOCAL)
+ last_size = hdr->size;
+ else
+ last_size = 0;
+ phdr_index = i;
+ phdr_in_segment = FALSE;
+ }
+
+ /* Create a final PT_LOAD program segment, but not if it's just
+ for .tbss. */
+ if (last_hdr != NULL
+ && (i - phdr_index != 1
+ || ((last_hdr->flags & (SEC_THREAD_LOCAL | SEC_LOAD))
+ != SEC_THREAD_LOCAL)))
+ {
+ 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 = _bfd_elf_make_dynamic_segment (abfd, dynsec);
+ if (m == NULL)
+ goto error_return;
+ *pm = m;
+ pm = &m->next;
+ }
+
+ /* For each batch of consecutive loadable .note sections,
+ 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
+ && CONST_STRNEQ (s->name, ".note"))
+ {
+ asection *s2;
+
+ count = 1;
+ amt = sizeof (struct elf_segment_map);
+ if (s->alignment_power == 2)
+ for (s2 = s; s2->next != NULL; s2 = s2->next)
+ {
+ if (s2->next->alignment_power == 2
+ && (s2->next->flags & SEC_LOAD) != 0
+ && CONST_STRNEQ (s2->next->name, ".note")
+ && align_power (s2->lma + s2->size, 2)
+ == s2->next->lma)
+ count++;
+ else
+ break;
+ }
+ amt += (count - 1) * sizeof (asection *);
+ m = (struct elf_segment_map *) bfd_zalloc (abfd, amt);
+ if (m == NULL)
+ goto error_return;
+ m->next = NULL;
+ m->p_type = PT_NOTE;
+ m->count = count;
+ while (count > 1)
+ {
+ m->sections[m->count - count--] = s;
+ BFD_ASSERT ((s->flags & SEC_THREAD_LOCAL) == 0);
+ s = s->next;
+ }
+ m->sections[m->count - 1] = s;
+ BFD_ASSERT ((s->flags & SEC_THREAD_LOCAL) == 0);
+ *pm = m;
+ pm = &m->next;
+ }
+ if (s->flags & SEC_THREAD_LOCAL)
+ {
+ if (! tls_count)
+ first_tls = s;
+ tls_count++;
+ }
+ }
+
+ /* If there are any SHF_TLS output sections, add PT_TLS segment. */
+ if (tls_count > 0)
+ {
+ amt = sizeof (struct elf_segment_map);
+ amt += (tls_count - 1) * sizeof (asection *);
+ m = (struct elf_segment_map *) bfd_zalloc (abfd, amt);
+ if (m == NULL)
+ goto error_return;
+ m->next = NULL;
+ m->p_type = PT_TLS;
+ m->count = tls_count;
+ /* Mandated PF_R. */
+ m->p_flags = PF_R;
+ m->p_flags_valid = 1;
+ s = first_tls;
+ for (i = 0; i < (unsigned int) tls_count; ++i)
+ {
+ if ((s->flags & SEC_THREAD_LOCAL) == 0)
+ {
+ _bfd_error_handler
+ (_("%B: TLS sections are not adjacent:"), abfd);
+ s = first_tls;
+ i = 0;
+ while (i < (unsigned int) tls_count)
+ {
+ if ((s->flags & SEC_THREAD_LOCAL) != 0)
+ {
+ _bfd_error_handler (_(" TLS: %A"), s);
+ i++;
+ }
+ else
+ _bfd_error_handler (_(" non-TLS: %A"), s);
+ s = s->next;
+ }
+ bfd_set_error (bfd_error_bad_value);
+ goto error_return;
+ }
+ m->sections[i] = s;
+ s = s->next;
+ }
+
+ *pm = m;
+ pm = &m->next;
+ }
+
+ /* If there is a .eh_frame_hdr section, throw in a PT_GNU_EH_FRAME
+ segment. */
+ eh_frame_hdr = elf_eh_frame_hdr (abfd);
+ if (eh_frame_hdr != NULL
+ && (eh_frame_hdr->output_section->flags & SEC_LOAD) != 0)
+ {
+ amt = sizeof (struct elf_segment_map);
+ m = (struct elf_segment_map *) bfd_zalloc (abfd, amt);
+ if (m == NULL)
+ goto error_return;
+ m->next = NULL;
+ m->p_type = PT_GNU_EH_FRAME;
+ m->count = 1;
+ m->sections[0] = eh_frame_hdr->output_section;
+
+ *pm = m;
+ pm = &m->next;
+ }
+
+ if (elf_stack_flags (abfd))
+ {
+ amt = sizeof (struct elf_segment_map);
+ m = (struct elf_segment_map *) bfd_zalloc (abfd, amt);
+ if (m == NULL)
+ goto error_return;
+ m->next = NULL;
+ m->p_type = PT_GNU_STACK;
+ m->p_flags = elf_stack_flags (abfd);
+ m->p_align = bed->stack_align;
+ m->p_flags_valid = 1;
+ m->p_align_valid = m->p_align != 0;
+ if (info->stacksize > 0)
+ {
+ m->p_size = info->stacksize;
+ m->p_size_valid = 1;
+ }
+
+ *pm = m;
+ pm = &m->next;
+ }
+
+ if (info != NULL && info->relro)
+ {
+ for (m = mfirst; m != NULL; m = m->next)
+ {
+ if (m->p_type == PT_LOAD
+ && m->count != 0
+ && m->sections[0]->vma >= info->relro_start
+ && m->sections[0]->vma < info->relro_end)
+ {
+ i = m->count;
+ while (--i != (unsigned) -1)
+ if ((m->sections[i]->flags & (SEC_LOAD | SEC_HAS_CONTENTS))
+ == (SEC_LOAD | SEC_HAS_CONTENTS))
+ break;
+
+ if (i != (unsigned) -1)
+ break;
+ }
+ }
+
+ /* Make a PT_GNU_RELRO segment only when it isn't empty. */
+ if (m != NULL)
+ {
+ amt = sizeof (struct elf_segment_map);
+ m = (struct elf_segment_map *) bfd_zalloc (abfd, amt);
+ if (m == NULL)
+ goto error_return;
+ m->next = NULL;
+ m->p_type = PT_GNU_RELRO;
+ m->p_flags = PF_R;
+ m->p_flags_valid = 1;
+
+ *pm = m;
+ pm = &m->next;
+ }
+ }
+
+ free (sections);
+ elf_seg_map (abfd) = mfirst;
+ }
+
+ if (!elf_modify_segment_map (abfd, info, no_user_phdrs))
+ return FALSE;
+
+ for (count = 0, m = elf_seg_map (abfd); m != NULL; m = m->next)
+ ++count;
+ elf_program_header_size (abfd) = count * bed->s->sizeof_phdr;
+
+ return TRUE;
+
+ error_return:
+ if (sections != NULL)
+ free (sections);
+ return FALSE;
+}
+
+/* Sort sections by address. */
+
+static int
+elf_sort_sections (const void *arg1, const void *arg2)
+{
+ const asection *sec1 = *(const asection **) arg1;
+ const asection *sec2 = *(const asection **) arg2;
+ bfd_size_type size1, size2;
+
+ /* 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 | SEC_THREAD_LOCAL)) == 0)
+
+ if (TOEND (sec1))
+ {
+ if (TOEND (sec2))
+ {
+ /* If the indicies are the same, do not return 0
+ here, but continue to try the next comparison. */
+ if (sec1->target_index - sec2->target_index != 0)
+ return sec1->target_index - sec2->target_index;
+ }
+ else
+ return 1;
+ }
+ else if (TOEND (sec2))
+ return -1;
+
+#undef TOEND
+
+ /* Sort by size, to put zero sized sections
+ before others at the same address. */
+
+ size1 = (sec1->flags & SEC_LOAD) ? sec1->size : 0;
+ size2 = (sec2->flags & SEC_LOAD) ? sec2->size : 0;
+
+ if (size1 < size2)
+ return -1;
+ if (size1 > size2)
+ return 1;
+
+ return sec1->target_index - sec2->target_index;
+}
+
+/* Ian Lance Taylor writes:
+
+ We shouldn't be using % with a negative signed number. That's just
+ not good. We have to make sure either that the number is not
+ negative, or that the number has an unsigned type. When the types
+ are all the same size they wind up as unsigned. When file_ptr is a
+ larger signed type, the arithmetic winds up as signed long long,
+ which is wrong.
+
+ What we're trying to say here is something like ``increase OFF by
+ the least amount that will cause it to be equal to the VMA modulo
+ the page size.'' */
+/* In other words, something like:
+
+ vma_offset = m->sections[0]->vma % bed->maxpagesize;
+ off_offset = off % bed->maxpagesize;
+ if (vma_offset < off_offset)
+ adjustment = vma_offset + bed->maxpagesize - off_offset;
+ else
+ adjustment = vma_offset - off_offset;
+
+ which can can be collapsed into the expression below. */
+
+static file_ptr
+vma_page_aligned_bias (bfd_vma vma, ufile_ptr off, bfd_vma maxpagesize)
+{
+ /* PR binutils/16199: Handle an alignment of zero. */
+ if (maxpagesize == 0)
+ maxpagesize = 1;
+ return ((vma - off) % maxpagesize);
+}
+
+static void
+print_segment_map (const struct elf_segment_map *m)
+{
+ unsigned int j;
+ const char *pt = get_segment_type (m->p_type);
+ char buf[32];
+
+ if (pt == NULL)
+ {
+ if (m->p_type >= PT_LOPROC && m->p_type <= PT_HIPROC)
+ sprintf (buf, "LOPROC+%7.7x",
+ (unsigned int) (m->p_type - PT_LOPROC));
+ else if (m->p_type >= PT_LOOS && m->p_type <= PT_HIOS)
+ sprintf (buf, "LOOS+%7.7x",
+ (unsigned int) (m->p_type - PT_LOOS));
+ else
+ snprintf (buf, sizeof (buf), "%8.8x",
+ (unsigned int) m->p_type);
+ pt = buf;
+ }
+ fflush (stdout);
+ fprintf (stderr, "%s:", pt);
+ for (j = 0; j < m->count; j++)
+ fprintf (stderr, " %s", m->sections [j]->name);
+ putc ('\n',stderr);
+ fflush (stderr);
+}
+
+static bfd_boolean
+write_zeros (bfd *abfd, file_ptr pos, bfd_size_type len)
+{
+ void *buf;
+ bfd_boolean ret;
+
+ if (bfd_seek (abfd, pos, SEEK_SET) != 0)
+ return FALSE;
+ buf = bfd_zmalloc (len);
+ if (buf == NULL)
+ return FALSE;
+ ret = bfd_bwrite (buf, len, abfd) == len;
+ free (buf);
+ return ret;
+}
+
+/* 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. */
+
+static bfd_boolean
+assign_file_positions_for_load_sections (bfd *abfd,
+ struct bfd_link_info *link_info)
+{
+ const struct elf_backend_data *bed = get_elf_backend_data (abfd);
+ struct elf_segment_map *m;
+ Elf_Internal_Phdr *phdrs;
+ Elf_Internal_Phdr *p;
+ file_ptr off;
+ bfd_size_type maxpagesize;
+ unsigned int alloc;
+ unsigned int i, j;
+ bfd_vma header_pad = 0;
+
+ if (link_info == NULL
+ && !_bfd_elf_map_sections_to_segments (abfd, link_info))
+ return FALSE;
+
+ alloc = 0;
+ for (m = elf_seg_map (abfd); m != NULL; m = m->next)
+ {
+ ++alloc;
+ if (m->header_size)
+ header_pad = m->header_size;
+ }
+
+ if (alloc)
+ {
+ elf_elfheader (abfd)->e_phoff = bed->s->sizeof_ehdr;
+ elf_elfheader (abfd)->e_phentsize = bed->s->sizeof_phdr;
+ }
+ else
+ {
+ /* PR binutils/12467. */
+ elf_elfheader (abfd)->e_phoff = 0;
+ elf_elfheader (abfd)->e_phentsize = 0;
+ }
+
+ elf_elfheader (abfd)->e_phnum = alloc;
+
+ if (elf_program_header_size (abfd) == (bfd_size_type) -1)
+ elf_program_header_size (abfd) = alloc * bed->s->sizeof_phdr;
+ else
+ BFD_ASSERT (elf_program_header_size (abfd)
+ >= alloc * bed->s->sizeof_phdr);
+
+ if (alloc == 0)
+ {
+ elf_next_file_pos (abfd) = bed->s->sizeof_ehdr;
+ return TRUE;
+ }
+
+ /* We're writing the size in elf_program_header_size (abfd),
+ see assign_file_positions_except_relocs, so make sure we have
+ that amount allocated, with trailing space cleared.
+ The variable alloc contains the computed need, while
+ elf_program_header_size (abfd) contains the size used for the
+ layout.
+ See ld/emultempl/elf-generic.em:gld${EMULATION_NAME}_map_segments
+ where the layout is forced to according to a larger size in the
+ last iterations for the testcase ld-elf/header. */
+ BFD_ASSERT (elf_program_header_size (abfd) % bed->s->sizeof_phdr
+ == 0);
+ phdrs = (Elf_Internal_Phdr *)
+ bfd_zalloc2 (abfd,
+ (elf_program_header_size (abfd) / bed->s->sizeof_phdr),
+ sizeof (Elf_Internal_Phdr));
+ elf_tdata (abfd)->phdr = phdrs;
+ if (phdrs == NULL)
+ return FALSE;
+
+ maxpagesize = 1;
+ if ((abfd->flags & D_PAGED) != 0)
+ maxpagesize = bed->maxpagesize;
+
+ off = bed->s->sizeof_ehdr;
+ off += alloc * bed->s->sizeof_phdr;
+ if (header_pad < (bfd_vma) off)
+ header_pad = 0;
+ else
+ header_pad -= off;
+ off += header_pad;
+
+ for (m = elf_seg_map (abfd), p = phdrs, j = 0;
+ m != NULL;
+ m = m->next, p++, j++)
+ {
+ asection **secpp;
+ bfd_vma off_adjust;
+ bfd_boolean no_contents;
+
+ /* If elf_segment_map is not from map_sections_to_segments, the
+ sections may not be correctly ordered. NOTE: sorting should
+ not be done to the PT_NOTE section of a corefile, which may
+ contain several pseudo-sections artificially created by bfd.
+ Sorting these pseudo-sections breaks things badly. */
+ if (m->count > 1
+ && !(elf_elfheader (abfd)->e_type == ET_CORE
+ && m->p_type == PT_NOTE))
+ qsort (m->sections, (size_t) m->count, sizeof (asection *),
+ elf_sort_sections);
+
+ /* An ELF segment (described by Elf_Internal_Phdr) may contain a
+ number of sections with contents contributing to both p_filesz
+ and p_memsz, followed by a number of sections with no contents
+ that just contribute to p_memsz. In this loop, OFF tracks next
+ available file offset for PT_LOAD and PT_NOTE segments. */
+ p->p_type = m->p_type;
+ p->p_flags = m->p_flags;
+
+ if (m->count == 0)
+ p->p_vaddr = 0;
+ else
+ p->p_vaddr = m->sections[0]->vma - m->p_vaddr_offset;
+
+ 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 - m->p_vaddr_offset;
+
+ if (p->p_type == PT_LOAD
+ && (abfd->flags & D_PAGED) != 0)
+ {
+ /* p_align in demand paged PT_LOAD segments effectively stores
+ the maximum page size. When copying an executable with
+ objcopy, we set m->p_align from the input file. Use this
+ value for maxpagesize rather than bed->maxpagesize, which
+ may be different. Note that we use maxpagesize for PT_TLS
+ segment alignment later in this function, so we are relying
+ on at least one PT_LOAD segment appearing before a PT_TLS
+ segment. */
+ if (m->p_align_valid)
+ maxpagesize = m->p_align;
+
+ p->p_align = maxpagesize;
+ }
+ else if (m->p_align_valid)
+ p->p_align = m->p_align;
+ else if (m->count == 0)
+ p->p_align = 1 << bed->s->log_file_align;
+ else
+ p->p_align = 0;
+
+ no_contents = FALSE;
+ off_adjust = 0;
+ if (p->p_type == PT_LOAD
+ && m->count > 0)
+ {
+ bfd_size_type align;
+ unsigned int align_power = 0;
+
+ if (m->p_align_valid)
+ align = p->p_align;
+ else
+ {
+ for (i = 0, secpp = m->sections; i < m->count; i++, secpp++)
+ {
+ unsigned int secalign;
+
+ secalign = bfd_get_section_alignment (abfd, *secpp);
+ if (secalign > align_power)
+ align_power = secalign;
+ }
+ align = (bfd_size_type) 1 << align_power;
+ if (align < maxpagesize)
+ align = maxpagesize;
+ }
+
+ for (i = 0; i < m->count; i++)
+ if ((m->sections[i]->flags & (SEC_LOAD | SEC_HAS_CONTENTS)) == 0)
+ /* If we aren't making room for this section, then
+ it must be SHT_NOBITS regardless of what we've
+ set via struct bfd_elf_special_section. */
+ elf_section_type (m->sections[i]) = SHT_NOBITS;
+
+ /* Find out whether this segment contains any loadable
+ sections. */
+ no_contents = TRUE;
+ for (i = 0; i < m->count; i++)
+ if (elf_section_type (m->sections[i]) != SHT_NOBITS)
+ {
+ no_contents = FALSE;
+ break;
+ }
+
+ off_adjust = vma_page_aligned_bias (p->p_vaddr, off, align);
+ off += off_adjust;
+ if (no_contents)
+ {
+ /* We shouldn't need to align the segment on disk since
+ the segment doesn't need file space, but the gABI
+ arguably requires the alignment and glibc ld.so
+ checks it. So to comply with the alignment
+ requirement but not waste file space, we adjust
+ p_offset for just this segment. (OFF_ADJUST is
+ subtracted from OFF later.) This may put p_offset
+ past the end of file, but that shouldn't matter. */
+ }
+ else
+ off_adjust = 0;
+ }
+ /* Make sure the .dynamic section is the first section in the
+ PT_DYNAMIC segment. */
+ else if (p->p_type == PT_DYNAMIC
+ && m->count > 1
+ && strcmp (m->sections[0]->name, ".dynamic") != 0)
+ {
+ _bfd_error_handler
+ (_("%B: The first section in the PT_DYNAMIC segment is not the .dynamic section"),
+ abfd);
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+ /* Set the note section type to SHT_NOTE. */
+ else if (p->p_type == PT_NOTE)
+ for (i = 0; i < m->count; i++)
+ elf_section_type (m->sections[i]) = SHT_NOTE;
+
+ 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_filesz = bed->s->sizeof_ehdr;
+ p->p_memsz = bed->s->sizeof_ehdr;
+ if (m->count > 0)
+ {
+ if (p->p_vaddr < (bfd_vma) off)
+ {
+ (*_bfd_error_handler)
+ (_("%B: Not enough room for program headers, try linking with -N"),
+ abfd);
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+
+ p->p_vaddr -= off;
+ if (!m->p_paddr_valid)
+ p->p_paddr -= off;
+ }
+ }
+
+ if (m->includes_phdrs)
+ {
+ if (!m->p_flags_valid)
+ p->p_flags |= PF_R;
+
+ if (!m->includes_filehdr)
+ {
+ p->p_offset = bed->s->sizeof_ehdr;
+
+ if (m->count > 0)
+ {
+ p->p_vaddr -= off - p->p_offset;
+ if (!m->p_paddr_valid)
+ p->p_paddr -= off - p->p_offset;
+ }
+ }
+
+ p->p_filesz += alloc * bed->s->sizeof_phdr;
+ p->p_memsz += alloc * bed->s->sizeof_phdr;
+ if (m->count)
+ {
+ p->p_filesz += header_pad;
+ p->p_memsz += header_pad;
+ }
+ }
+
+ 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);
+ if (!no_contents)
+ p->p_filesz += adjust;
+ p->p_memsz += adjust;
+ }
+ }
+
+ /* Set up p_filesz, p_memsz, p_align and p_flags from the section
+ maps. Set filepos for sections in PT_LOAD segments, and in
+ core files, for sections in PT_NOTE segments.
+ assign_file_positions_for_non_load_sections will set filepos
+ for other sections and update p_filesz for other segments. */
+ for (i = 0, secpp = m->sections; i < m->count; i++, secpp++)
+ {
+ asection *sec;
+ bfd_size_type align;
+ Elf_Internal_Shdr *this_hdr;
+
+ sec = *secpp;
+ this_hdr = &elf_section_data (sec)->this_hdr;
+ align = (bfd_size_type) 1 << bfd_get_section_alignment (abfd, sec);
+
+ if ((p->p_type == PT_LOAD
+ || p->p_type == PT_TLS)
+ && (this_hdr->sh_type != SHT_NOBITS
+ || ((this_hdr->sh_flags & SHF_ALLOC) != 0
+ && ((this_hdr->sh_flags & SHF_TLS) == 0
+ || p->p_type == PT_TLS))))
+ {
+ bfd_vma p_start = p->p_paddr;
+ bfd_vma p_end = p_start + p->p_memsz;
+ bfd_vma s_start = sec->lma;
+ bfd_vma adjust = s_start - p_end;
+
+ if (adjust != 0
+ && (s_start < p_end
+ || p_end < p_start))
+ {
+ (*_bfd_error_handler)
+ (_("%B: section %A lma %#lx adjusted to %#lx"), abfd, sec,
+ (unsigned long) s_start, (unsigned long) p_end);
+ adjust = 0;
+ sec->lma = p_end;
+ }
+ p->p_memsz += adjust;
+
+ if (this_hdr->sh_type != SHT_NOBITS)
+ {
+ if (p->p_filesz + adjust < p->p_memsz)
+ {
+ /* We have a PROGBITS section following NOBITS ones.
+ Allocate file space for the NOBITS section(s) and
+ zero it. */
+ adjust = p->p_memsz - p->p_filesz;
+ if (!write_zeros (abfd, off, adjust))
+ return FALSE;
+ }
+ off += adjust;
+ p->p_filesz += adjust;
+ }
+ }
+
+ if (p->p_type == PT_NOTE && bfd_get_format (abfd) == bfd_core)
+ {
+ /* The section at i == 0 is the one that actually contains
+ everything. */
+ if (i == 0)
+ {
+ this_hdr->sh_offset = sec->filepos = off;
+ off += this_hdr->sh_size;
+ p->p_filesz = this_hdr->sh_size;
+ p->p_memsz = 0;
+ p->p_align = 1;
+ }
+ else
+ {
+ /* The rest are fake sections that shouldn't be written. */
+ sec->filepos = 0;
+ sec->size = 0;
+ sec->flags = 0;
+ continue;
+ }
+ }
+ else
+ {
+ if (p->p_type == PT_LOAD)
+ {
+ this_hdr->sh_offset = sec->filepos = off;
+ if (this_hdr->sh_type != SHT_NOBITS)
+ off += this_hdr->sh_size;
+ }
+ else if (this_hdr->sh_type == SHT_NOBITS
+ && (this_hdr->sh_flags & SHF_TLS) != 0
+ && this_hdr->sh_offset == 0)
+ {
+ /* This is a .tbss section that didn't get a PT_LOAD.
+ (See _bfd_elf_map_sections_to_segments "Create a
+ final PT_LOAD".) Set sh_offset to the value it
+ would have if we had created a zero p_filesz and
+ p_memsz PT_LOAD header for the section. This
+ also makes the PT_TLS header have the same
+ p_offset value. */
+ bfd_vma adjust = vma_page_aligned_bias (this_hdr->sh_addr,
+ off, align);
+ this_hdr->sh_offset = sec->filepos = off + adjust;
+ }
+
+ if (this_hdr->sh_type != SHT_NOBITS)
+ {
+ p->p_filesz += this_hdr->sh_size;
+ /* A load section without SHF_ALLOC is something like
+ a note section in a PT_NOTE segment. These take
+ file space but are not loaded into memory. */
+ if ((this_hdr->sh_flags & SHF_ALLOC) != 0)
+ p->p_memsz += this_hdr->sh_size;
+ }
+ else if ((this_hdr->sh_flags & SHF_ALLOC) != 0)
+ {
+ if (p->p_type == PT_TLS)
+ p->p_memsz += this_hdr->sh_size;
+
+ /* .tbss is special. It doesn't contribute to p_memsz of
+ normal segments. */
+ else if ((this_hdr->sh_flags & SHF_TLS) == 0)
+ p->p_memsz += this_hdr->sh_size;
+ }
+
+ if (align > p->p_align
+ && !m->p_align_valid
+ && (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 ((this_hdr->sh_flags & SHF_EXECINSTR) != 0)
+ p->p_flags |= PF_X;
+ if ((this_hdr->sh_flags & SHF_WRITE) != 0)
+ p->p_flags |= PF_W;
+ }
+ }
+
+ off -= off_adjust;
+
+ /* Check that all sections are in a PT_LOAD segment.
+ Don't check funky gdb generated core files. */
+ if (p->p_type == PT_LOAD && bfd_get_format (abfd) != bfd_core)
+ {
+ bfd_boolean check_vma = TRUE;
+
+ for (i = 1; i < m->count; i++)
+ if (m->sections[i]->vma == m->sections[i - 1]->vma
+ && ELF_SECTION_SIZE (&(elf_section_data (m->sections[i])
+ ->this_hdr), p) != 0
+ && ELF_SECTION_SIZE (&(elf_section_data (m->sections[i - 1])
+ ->this_hdr), p) != 0)
+ {
+ /* Looks like we have overlays packed into the segment. */
+ check_vma = FALSE;
+ break;
+ }
+
+ for (i = 0; i < m->count; i++)
+ {
+ Elf_Internal_Shdr *this_hdr;
+ asection *sec;
+
+ sec = m->sections[i];
+ this_hdr = &(elf_section_data(sec)->this_hdr);
+ if (!ELF_SECTION_IN_SEGMENT_1 (this_hdr, p, check_vma, 0)
+ && !ELF_TBSS_SPECIAL (this_hdr, p))
+ {
+ (*_bfd_error_handler)
+ (_("%B: section `%A' can't be allocated in segment %d"),
+ abfd, sec, j);
+ print_segment_map (m);
+ }
+ }
+ }
+ }
+
+ elf_next_file_pos (abfd) = off;
+ return TRUE;
+}
+
+/* Assign file positions for the other sections. */
+
+static bfd_boolean
+assign_file_positions_for_non_load_sections (bfd *abfd,
+ struct bfd_link_info *link_info)
+{
+ const struct elf_backend_data *bed = get_elf_backend_data (abfd);
+ Elf_Internal_Shdr **i_shdrpp;
+ Elf_Internal_Shdr **hdrpp;
+ Elf_Internal_Phdr *phdrs;
+ Elf_Internal_Phdr *p;
+ struct elf_segment_map *m;
+ struct elf_segment_map *hdrs_segment;
+ bfd_vma filehdr_vaddr, filehdr_paddr;
+ bfd_vma phdrs_vaddr, phdrs_paddr;
+ file_ptr off;
+ unsigned int num_sec;
+ unsigned int i;
+ unsigned int count;
+
+ i_shdrpp = elf_elfsections (abfd);
+ num_sec = elf_numsections (abfd);
+ off = elf_next_file_pos (abfd);
+ for (i = 1, hdrpp = i_shdrpp + 1; i < num_sec; i++, hdrpp++)
+ {
+ Elf_Internal_Shdr *hdr;
+
+ hdr = *hdrpp;
+ if (hdr->bfd_section != NULL
+ && (hdr->bfd_section->filepos != 0
+ || (hdr->sh_type == SHT_NOBITS
+ && hdr->contents == NULL)))
+ BFD_ASSERT (hdr->sh_offset == hdr->bfd_section->filepos);
+ else if ((hdr->sh_flags & SHF_ALLOC) != 0)
+ {
+ if (hdr->sh_size != 0)
+ (*_bfd_error_handler)
+ (_("%B: warning: allocated section `%s' not in segment"),
+ abfd,
+ (hdr->bfd_section == NULL
+ ? "*unknown*"
+ : hdr->bfd_section->name));
+ /* We don't need to page align empty sections. */
+ if ((abfd->flags & D_PAGED) != 0 && hdr->sh_size != 0)
+ off += vma_page_aligned_bias (hdr->sh_addr, off,
+ bed->maxpagesize);
+ else
+ off += vma_page_aligned_bias (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->bfd_section == NULL)
+ || hdr == i_shdrpp[elf_onesymtab (abfd)]
+ || hdr == i_shdrpp[elf_symtab_shndx (abfd)]
+ || hdr == i_shdrpp[elf_strtab_sec (abfd)])
+ hdr->sh_offset = -1;
+ else
+ off = _bfd_elf_assign_file_position_for_section (hdr, off, TRUE);
+ }
+
+ /* Now that we have set the section file positions, we can set up
+ the file positions for the non PT_LOAD segments. */
+ count = 0;
+ filehdr_vaddr = 0;
+ filehdr_paddr = 0;
+ phdrs_vaddr = bed->maxpagesize + bed->s->sizeof_ehdr;
+ phdrs_paddr = 0;
+ hdrs_segment = NULL;
+ phdrs = elf_tdata (abfd)->phdr;
+ for (m = elf_seg_map (abfd), p = phdrs; m != NULL; m = m->next, p++)
+ {
+ ++count;
+ if (p->p_type != PT_LOAD)
+ continue;
+
+ if (m->includes_filehdr)
+ {
+ filehdr_vaddr = p->p_vaddr;
+ filehdr_paddr = p->p_paddr;
+ }
+ if (m->includes_phdrs)
+ {
+ phdrs_vaddr = p->p_vaddr;
+ phdrs_paddr = p->p_paddr;
+ if (m->includes_filehdr)
+ {
+ hdrs_segment = m;
+ phdrs_vaddr += bed->s->sizeof_ehdr;
+ phdrs_paddr += bed->s->sizeof_ehdr;
+ }
+ }
+ }
+
+ if (hdrs_segment != NULL && link_info != NULL)
+ {
+ /* There is a segment that contains both the file headers and the
+ program headers, so provide a symbol __ehdr_start pointing there.
+ A program can use this to examine itself robustly. */
+
+ struct elf_link_hash_entry *hash
+ = elf_link_hash_lookup (elf_hash_table (link_info), "__ehdr_start",
+ FALSE, FALSE, TRUE);
+ /* If the symbol was referenced and not defined, define it. */
+ if (hash != NULL
+ && (hash->root.type == bfd_link_hash_new
+ || hash->root.type == bfd_link_hash_undefined
+ || hash->root.type == bfd_link_hash_undefweak
+ || hash->root.type == bfd_link_hash_common))
+ {
+ asection *s = NULL;
+ if (hdrs_segment->count != 0)
+ /* The segment contains sections, so use the first one. */
+ s = hdrs_segment->sections[0];
+ else
+ /* Use the first (i.e. lowest-addressed) section in any segment. */
+ for (m = elf_seg_map (abfd); m != NULL; m = m->next)
+ if (m->count != 0)
+ {
+ s = m->sections[0];
+ break;
+ }
+
+ if (s != NULL)
+ {
+ hash->root.u.def.value = filehdr_vaddr - s->vma;
+ hash->root.u.def.section = s;
+ }
+ else
+ {
+ hash->root.u.def.value = filehdr_vaddr;
+ hash->root.u.def.section = bfd_abs_section_ptr;
+ }
+
+ hash->root.type = bfd_link_hash_defined;
+ hash->def_regular = 1;
+ hash->non_elf = 0;
+ }
+ }
+
+ for (m = elf_seg_map (abfd), p = phdrs; m != NULL; m = m->next, p++)
+ {
+ if (p->p_type == PT_GNU_RELRO)
+ {
+ const Elf_Internal_Phdr *lp;
+ struct elf_segment_map *lm;
+
+ if (link_info != NULL)
+ {
+ /* During linking the range of the RELRO segment is passed
+ in link_info. */
+ for (lm = elf_seg_map (abfd), lp = phdrs;
+ lm != NULL;
+ lm = lm->next, lp++)
+ {
+ if (lp->p_type == PT_LOAD
+ && lp->p_vaddr < link_info->relro_end
+ && lm->count != 0
+ && lm->sections[0]->vma >= link_info->relro_start)
+ break;
+ }
+
+ BFD_ASSERT (lm != NULL);
+ }
+ else
+ {
+ /* Otherwise we are copying an executable or shared
+ library, but we need to use the same linker logic. */
+ for (lp = phdrs; lp < phdrs + count; ++lp)
+ {
+ if (lp->p_type == PT_LOAD
+ && lp->p_paddr == p->p_paddr)
+ break;
+ }
+ }
+
+ if (lp < phdrs + count)
+ {
+ p->p_vaddr = lp->p_vaddr;
+ p->p_paddr = lp->p_paddr;
+ p->p_offset = lp->p_offset;
+ if (link_info != NULL)
+ p->p_filesz = link_info->relro_end - lp->p_vaddr;
+ else if (m->p_size_valid)
+ p->p_filesz = m->p_size;
+ else
+ abort ();
+ p->p_memsz = p->p_filesz;
+ /* Preserve the alignment and flags if they are valid. The
+ gold linker generates RW/4 for the PT_GNU_RELRO section.
+ It is better for objcopy/strip to honor these attributes
+ otherwise gdb will choke when using separate debug files.
+ */
+ if (!m->p_align_valid)
+ p->p_align = 1;
+ if (!m->p_flags_valid)
+ p->p_flags = (lp->p_flags & ~PF_W);
+ }
+ else
+ {
+ memset (p, 0, sizeof *p);
+ p->p_type = PT_NULL;
+ }
+ }
+ else if (p->p_type == PT_GNU_STACK)
+ {
+ if (m->p_size_valid)
+ p->p_memsz = m->p_size;
+ }
+ else if (m->count != 0)
+ {
+ if (p->p_type != PT_LOAD
+ && (p->p_type != PT_NOTE
+ || bfd_get_format (abfd) != bfd_core))
+ {
+ BFD_ASSERT (!m->includes_filehdr && !m->includes_phdrs);
+
+ p->p_filesz = 0;
+ p->p_offset = m->sections[0]->filepos;
+ for (i = m->count; i-- != 0;)
+ {
+ asection *sect = m->sections[i];
+ Elf_Internal_Shdr *hdr = &elf_section_data (sect)->this_hdr;
+ if (hdr->sh_type != SHT_NOBITS)
+ {
+ p->p_filesz = (sect->filepos - m->sections[0]->filepos
+ + hdr->sh_size);
+ break;
+ }
+ }
+ }
+ }
+ else 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;
+ }
+ }
+
+ elf_next_file_pos (abfd) = off;
+
+ return TRUE;
+}
+
+/* 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.
+
+ Reloc sections come in two flavours: Those processed specially as
+ "side-channel" data attached to a section to which they apply, and
+ those that bfd doesn't process as relocations. The latter sort are
+ stored in a normal bfd section by bfd_section_from_shdr. We don't
+ consider the former sort here, unless they form part of the loadable
+ image. Reloc sections not assigned here will be handled later by
+ assign_file_positions_for_relocs.
+
+ We also don't set the positions of the .symtab and .strtab here. */
+
+static bfd_boolean
+assign_file_positions_except_relocs (bfd *abfd,
+ struct bfd_link_info *link_info)
+{
+ struct elf_obj_tdata *tdata = elf_tdata (abfd);
+ Elf_Internal_Ehdr *i_ehdrp = elf_elfheader (abfd);
+ const 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 ** const i_shdrpp = elf_elfsections (abfd);
+ unsigned int num_sec = elf_numsections (abfd);
+ Elf_Internal_Shdr **hdrpp;
+ unsigned int i;
+ file_ptr off;
+
+ /* 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 < num_sec; i++, hdrpp++)
+ {
+ Elf_Internal_Shdr *hdr;
+
+ hdr = *hdrpp;
+ if (((hdr->sh_type == SHT_REL || hdr->sh_type == SHT_RELA)
+ && hdr->bfd_section == NULL)
+ || i == elf_onesymtab (abfd)
+ || i == elf_symtab_shndx (abfd)
+ || i == elf_strtab_sec (abfd))
+ {
+ hdr->sh_offset = -1;
+ }
+ else
+ off = _bfd_elf_assign_file_position_for_section (hdr, off, TRUE);
+ }
+
+ elf_next_file_pos (abfd) = off;
+ }
+ else
+ {
+ unsigned int alloc;
+
+ /* Assign file positions for the loaded sections based on the
+ assignment of sections to segments. */
+ if (!assign_file_positions_for_load_sections (abfd, link_info))
+ return FALSE;
+
+ /* And for non-load sections. */
+ if (!assign_file_positions_for_non_load_sections (abfd, link_info))
+ return FALSE;
+
+ if (bed->elf_backend_modify_program_headers != NULL)
+ {
+ if (!(*bed->elf_backend_modify_program_headers) (abfd, link_info))
+ return FALSE;
+ }
+
+ /* Set e_type in ELF header to ET_EXEC for -pie -Ttext-segment=. */
+ if (link_info != NULL
+ && link_info->executable
+ && link_info->shared)
+ {
+ unsigned int num_segments = elf_elfheader (abfd)->e_phnum;
+ Elf_Internal_Phdr *segment = elf_tdata (abfd)->phdr;
+ Elf_Internal_Phdr *end_segment = &segment[num_segments];
+
+ /* Find the lowest p_vaddr in PT_LOAD segments. */
+ bfd_vma p_vaddr = (bfd_vma) -1;
+ for (; segment < end_segment; segment++)
+ if (segment->p_type == PT_LOAD && p_vaddr > segment->p_vaddr)
+ p_vaddr = segment->p_vaddr;
+
+ /* Set e_type to ET_EXEC if the lowest p_vaddr in PT_LOAD
+ segments is non-zero. */
+ if (p_vaddr)
+ i_ehdrp->e_type = ET_EXEC;
+ }
+
+ /* Write out the program headers. */
+ alloc = elf_program_header_size (abfd) / bed->s->sizeof_phdr;
+ if (bfd_seek (abfd, (bfd_signed_vma) bed->s->sizeof_ehdr, SEEK_SET) != 0
+ || bed->s->write_out_phdrs (abfd, tdata->phdr, alloc) != 0)
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static bfd_boolean
+prep_headers (bfd *abfd)
+{
+ Elf_Internal_Ehdr *i_ehdrp; /* Elf file header, internal form. */
+ struct elf_strtab_hash *shstrtab;
+ const struct elf_backend_data *bed = get_elf_backend_data (abfd);
+
+ i_ehdrp = elf_elfheader (abfd);
+
+ shstrtab = _bfd_elf_strtab_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;
+
+ 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;
+
+ /* There used to be a long list of cases here, each one setting
+ e_machine to the same EM_* macro #defined as ELF_MACHINE_CODE
+ in the corresponding bfd definition. To avoid duplication,
+ the switch was removed. Machines that need special handling
+ can generally do it in elf_backend_final_write_processing(),
+ unless they need the information earlier than the final write.
+ Such need can generally be supplied by replacing the tests for
+ e_machine with the conditions used to determine it. */
+ default:
+ i_ehdrp->e_machine = bed->elf_machine_code;
+ }
+
+ 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. */
+ ;
+ else
+ {
+ i_ehdrp->e_phentsize = 0;
+ i_ehdrp->e_phoff = 0;
+ }
+
+ elf_tdata (abfd)->symtab_hdr.sh_name =
+ (unsigned int) _bfd_elf_strtab_add (shstrtab, ".symtab", FALSE);
+ elf_tdata (abfd)->strtab_hdr.sh_name =
+ (unsigned int) _bfd_elf_strtab_add (shstrtab, ".strtab", FALSE);
+ elf_tdata (abfd)->shstrtab_hdr.sh_name =
+ (unsigned int) _bfd_elf_strtab_add (shstrtab, ".shstrtab", FALSE);
+ if (elf_tdata (abfd)->symtab_hdr.sh_name == (unsigned int) -1
+ || elf_tdata (abfd)->strtab_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, and the file position of section headers. */
+
+static void
+_bfd_elf_assign_file_positions_for_relocs (bfd *abfd)
+{
+ file_ptr off;
+ unsigned int i, num_sec;
+ Elf_Internal_Shdr **shdrpp;
+ Elf_Internal_Ehdr *i_ehdrp;
+ const struct elf_backend_data *bed;
+
+ off = elf_next_file_pos (abfd);
+
+ num_sec = elf_numsections (abfd);
+ for (i = 1, shdrpp = elf_elfsections (abfd) + 1; i < num_sec; 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);
+ }
+
+/* Place the section headers. */
+ i_ehdrp = elf_elfheader (abfd);
+ bed = get_elf_backend_data (abfd);
+ off = align_file_position (off, 1 << bed->s->log_file_align);
+ i_ehdrp->e_shoff = off;
+ off += i_ehdrp->e_shnum * i_ehdrp->e_shentsize;
+ elf_next_file_pos (abfd) = off;
+}
+
+bfd_boolean
+_bfd_elf_write_object_contents (bfd *abfd)
+{
+ const struct elf_backend_data *bed = get_elf_backend_data (abfd);
+ Elf_Internal_Shdr **i_shdrp;
+ bfd_boolean failed;
+ unsigned int count, num_sec;
+ struct elf_obj_tdata *t;
+
+ if (! abfd->output_has_begun
+ && ! _bfd_elf_compute_section_file_positions (abfd, NULL))
+ return FALSE;
+
+ i_shdrp = elf_elfsections (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... */
+ num_sec = elf_numsections (abfd);
+ for (count = 1; count < num_sec; count++)
+ {
+ if (bed->elf_backend_section_processing)
+ (*bed->elf_backend_section_processing) (abfd, i_shdrp[count]);
+ if (i_shdrp[count]->contents)
+ {
+ bfd_size_type amt = i_shdrp[count]->sh_size;
+
+ if (bfd_seek (abfd, i_shdrp[count]->sh_offset, SEEK_SET) != 0
+ || bfd_bwrite (i_shdrp[count]->contents, amt, abfd) != amt)
+ return FALSE;
+ }
+ }
+
+ /* Write out the section header names. */
+ t = elf_tdata (abfd);
+ if (elf_shstrtab (abfd) != NULL
+ && (bfd_seek (abfd, t->shstrtab_hdr.sh_offset, SEEK_SET) != 0
+ || !_bfd_elf_strtab_emit (abfd, elf_shstrtab (abfd))))
+ return FALSE;
+
+ if (bed->elf_backend_final_write_processing)
+ (*bed->elf_backend_final_write_processing) (abfd, elf_linker (abfd));
+
+ if (!bed->s->write_shdrs_and_ehdr (abfd))
+ return FALSE;
+
+ /* This is last since write_shdrs_and_ehdr can touch i_shdrp[0]. */
+ if (t->o->build_id.after_write_object_contents != NULL)
+ return (*t->o->build_id.after_write_object_contents) (abfd);
+
+ return TRUE;
+}
+
+bfd_boolean
+_bfd_elf_write_corefile_contents (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. */
+
+unsigned int
+_bfd_elf_section_from_bfd_section (bfd *abfd, struct bfd_section *asect)
+{
+ const struct elf_backend_data *bed;
+ unsigned int sec_index;
+
+ if (elf_section_data (asect) != NULL
+ && elf_section_data (asect)->this_idx != 0)
+ return elf_section_data (asect)->this_idx;
+
+ if (bfd_is_abs_section (asect))
+ sec_index = SHN_ABS;
+ else if (bfd_is_com_section (asect))
+ sec_index = SHN_COMMON;
+ else if (bfd_is_und_section (asect))
+ sec_index = SHN_UNDEF;
+ else
+ sec_index = SHN_BAD;
+
+ bed = get_elf_backend_data (abfd);
+ if (bed->elf_backend_section_from_bfd_section)
+ {
+ int retval = sec_index;
+
+ if ((*bed->elf_backend_section_from_bfd_section) (abfd, asect, &retval))
+ return retval;
+ }
+
+ if (sec_index == SHN_BAD)
+ bfd_set_error (bfd_error_nonrepresentable_section);
+
+ return sec_index;
+}
+
+/* Given a BFD symbol, return the index in the ELF symbol table, or -1
+ on error. */
+
+int
+_bfd_elf_symbol_from_bfd_symbol (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)
+ {
+ asection *sec;
+ int indx;
+
+ sec = asym_ptr->section;
+ if (sec->owner != abfd && sec->output_section != NULL)
+ sec = sec->output_section;
+ if (sec->owner == abfd
+ && (indx = sec->index) < elf_num_section_syms (abfd)
+ && elf_section_syms (abfd)[indx] != NULL)
+ 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)
+ (_("%B: symbol `%s' required but not present"),
+ 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\n",
+ (long) asym_ptr, asym_ptr->name, idx, (long) flags);
+ fflush (stderr);
+ }
+#endif
+
+ return idx;
+}
+
+/* Rewrite program header information. */
+
+static bfd_boolean
+rewrite_elf_program_header (bfd *ibfd, bfd *obfd)
+{
+ Elf_Internal_Ehdr *iehdr;
+ struct elf_segment_map *map;
+ struct elf_segment_map *map_first;
+ struct elf_segment_map **pointer_to_map;
+ Elf_Internal_Phdr *segment;
+ asection *section;
+ unsigned int i;
+ unsigned int num_segments;
+ bfd_boolean phdr_included = FALSE;
+ bfd_boolean p_paddr_valid;
+ bfd_vma maxpagesize;
+ struct elf_segment_map *phdr_adjust_seg = NULL;
+ unsigned int phdr_adjust_num = 0;
+ const struct elf_backend_data *bed;
+
+ bed = get_elf_backend_data (ibfd);
+ iehdr = elf_elfheader (ibfd);
+
+ map_first = NULL;
+ pointer_to_map = &map_first;
+
+ num_segments = elf_elfheader (ibfd)->e_phnum;
+ maxpagesize = get_elf_backend_data (obfd)->maxpagesize;
+
+ /* Returns the end address of the segment + 1. */
+#define SEGMENT_END(segment, start) \
+ (start + (segment->p_memsz > segment->p_filesz \
+ ? segment->p_memsz : segment->p_filesz))
+
+#define SECTION_SIZE(section, segment) \
+ (((section->flags & (SEC_HAS_CONTENTS | SEC_THREAD_LOCAL)) \
+ != SEC_THREAD_LOCAL || segment->p_type == PT_TLS) \
+ ? section->size : 0)
+
+ /* Returns TRUE if the given section is contained within
+ the given segment. VMA addresses are compared. */
+#define IS_CONTAINED_BY_VMA(section, segment) \
+ (section->vma >= segment->p_vaddr \
+ && (section->vma + SECTION_SIZE (section, segment) \
+ <= (SEGMENT_END (segment, segment->p_vaddr))))
+
+ /* Returns TRUE if the given section is contained within
+ the given segment. LMA addresses are compared. */
+#define IS_CONTAINED_BY_LMA(section, segment, base) \
+ (section->lma >= base \
+ && (section->lma + SECTION_SIZE (section, segment) \
+ <= SEGMENT_END (segment, base)))
+
+ /* Handle PT_NOTE segment. */
+#define IS_NOTE(p, s) \
+ (p->p_type == PT_NOTE \
+ && elf_section_type (s) == SHT_NOTE \
+ && (bfd_vma) s->filepos >= p->p_offset \
+ && ((bfd_vma) s->filepos + s->size \
+ <= p->p_offset + p->p_filesz))
+
+ /* Special case: corefile "NOTE" section containing regs, prpsinfo
+ etc. */
+#define IS_COREFILE_NOTE(p, s) \
+ (IS_NOTE (p, s) \
+ && bfd_get_format (ibfd) == bfd_core \
+ && s->vma == 0 \
+ && s->lma == 0)
+
+ /* 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_paddr == 0 \
+ && p->p_memsz == 0 \
+ && p->p_filesz > 0 \
+ && (s->flags & SEC_HAS_CONTENTS) != 0 \
+ && s->size > 0 \
+ && (bfd_vma) s->filepos >= p->p_offset \
+ && ((bfd_vma) s->filepos + s->size \
+ <= p->p_offset + p->p_filesz))
+
+ /* Decide if the given section should be included in the given segment.
+ A section will be included if:
+ 1. It is within the address space of the segment -- we use the LMA
+ if that is set for the segment and the VMA otherwise,
+ 2. It is an allocated section or a NOTE section in a PT_NOTE
+ segment.
+ 3. There is an output section associated with it,
+ 4. The section has not already been allocated to a previous segment.
+ 5. PT_GNU_STACK segments do not include any sections.
+ 6. PT_TLS segment includes only SHF_TLS sections.
+ 7. SHF_TLS sections are only in PT_TLS or PT_LOAD segments.
+ 8. PT_DYNAMIC should not contain empty sections at the beginning
+ (with the possible exception of .dynamic). */
+#define IS_SECTION_IN_INPUT_SEGMENT(section, segment, bed) \
+ ((((segment->p_paddr \
+ ? IS_CONTAINED_BY_LMA (section, segment, segment->p_paddr) \
+ : IS_CONTAINED_BY_VMA (section, segment)) \
+ && (section->flags & SEC_ALLOC) != 0) \
+ || IS_NOTE (segment, section)) \
+ && segment->p_type != PT_GNU_STACK \
+ && (segment->p_type != PT_TLS \
+ || (section->flags & SEC_THREAD_LOCAL)) \
+ && (segment->p_type == PT_LOAD \
+ || segment->p_type == PT_TLS \
+ || (section->flags & SEC_THREAD_LOCAL) == 0) \
+ && (segment->p_type != PT_DYNAMIC \
+ || SECTION_SIZE (section, segment) > 0 \
+ || (segment->p_paddr \
+ ? segment->p_paddr != section->lma \
+ : segment->p_vaddr != section->vma) \
+ || (strcmp (bfd_get_section_name (ibfd, section), ".dynamic") \
+ == 0)) \
+ && !section->segment_mark)
+
+/* If the output section of a section in the input segment is NULL,
+ it is removed from the corresponding output segment. */
+#define INCLUDE_SECTION_IN_SEGMENT(section, segment, bed) \
+ (IS_SECTION_IN_INPUT_SEGMENT (section, segment, bed) \
+ && section->output_section != NULL)
+
+ /* Returns TRUE iff seg1 starts after the end of seg2. */
+#define SEGMENT_AFTER_SEGMENT(seg1, seg2, field) \
+ (seg1->field >= SEGMENT_END (seg2, seg2->field))
+
+ /* Returns TRUE iff seg1 and seg2 overlap. Segments overlap iff both
+ their VMA address ranges and their LMA address ranges overlap.
+ It is possible to have overlapping VMA ranges without overlapping LMA
+ ranges. RedBoot images for example can have both .data and .bss mapped
+ to the same VMA range, but with the .data section mapped to a different
+ LMA. */
+#define SEGMENT_OVERLAPS(seg1, seg2) \
+ ( !(SEGMENT_AFTER_SEGMENT (seg1, seg2, p_vaddr) \
+ || SEGMENT_AFTER_SEGMENT (seg2, seg1, p_vaddr)) \
+ && !(SEGMENT_AFTER_SEGMENT (seg1, seg2, p_paddr) \
+ || SEGMENT_AFTER_SEGMENT (seg2, seg1, p_paddr)))
+
+ /* Initialise the segment mark field. */
+ for (section = ibfd->sections; section != NULL; section = section->next)
+ section->segment_mark = FALSE;
+
+ /* 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
+ don't set the p_paddr_valid fields. */
+ p_paddr_valid = FALSE;
+ for (i = 0, segment = elf_tdata (ibfd)->phdr;
+ i < num_segments;
+ i++, segment++)
+ if (segment->p_paddr != 0)
+ {
+ p_paddr_valid = TRUE;
+ break;
+ }
+
+ /* Scan through the segments specified in the program header
+ of the input BFD. For this first scan we look for overlaps
+ in the loadable segments. These can be created by weird
+ parameters to objcopy. Also, fix some solaris weirdness. */
+ for (i = 0, segment = elf_tdata (ibfd)->phdr;
+ i < num_segments;
+ i++, segment++)
+ {
+ unsigned int j;
+ Elf_Internal_Phdr *segment2;
+
+ if (segment->p_type == PT_INTERP)
+ for (section = ibfd->sections; section; section = section->next)
+ if (IS_SOLARIS_PT_INTERP (segment, section))
+ {
+ /* Mininal change so that the normal section to segment
+ assignment code will work. */
+ segment->p_vaddr = section->vma;
+ break;
+ }
+
+ if (segment->p_type != PT_LOAD)
+ {
+ /* Remove PT_GNU_RELRO segment. */
+ if (segment->p_type == PT_GNU_RELRO)
+ segment->p_type = PT_NULL;
+ continue;
+ }
+
+ /* Determine if this segment overlaps any previous segments. */
+ for (j = 0, segment2 = elf_tdata (ibfd)->phdr; j < i; j++, segment2++)
+ {
+ bfd_signed_vma extra_length;
+
+ if (segment2->p_type != PT_LOAD
+ || !SEGMENT_OVERLAPS (segment, segment2))
+ continue;
+
+ /* Merge the two segments together. */
+ if (segment2->p_vaddr < segment->p_vaddr)
+ {
+ /* Extend SEGMENT2 to include SEGMENT and then delete
+ SEGMENT. */
+ extra_length = (SEGMENT_END (segment, segment->p_vaddr)
+ - SEGMENT_END (segment2, segment2->p_vaddr));
+
+ if (extra_length > 0)
+ {
+ segment2->p_memsz += extra_length;
+ segment2->p_filesz += extra_length;
+ }
+
+ segment->p_type = PT_NULL;
+
+ /* Since we have deleted P we must restart the outer loop. */
+ i = 0;
+ segment = elf_tdata (ibfd)->phdr;
+ break;
+ }
+ else
+ {
+ /* Extend SEGMENT to include SEGMENT2 and then delete
+ SEGMENT2. */
+ extra_length = (SEGMENT_END (segment2, segment2->p_vaddr)
+ - SEGMENT_END (segment, segment->p_vaddr));
+
+ if (extra_length > 0)
+ {
+ segment->p_memsz += extra_length;
+ segment->p_filesz += extra_length;
+ }
+
+ segment2->p_type = PT_NULL;
+ }
+ }
+ }
+
+ /* The second scan attempts to assign sections to segments. */
+ for (i = 0, segment = elf_tdata (ibfd)->phdr;
+ i < num_segments;
+ i++, segment++)
+ {
+ unsigned int section_count;
+ asection **sections;
+ asection *output_section;
+ unsigned int isec;
+ bfd_vma matching_lma;
+ bfd_vma suggested_lma;
+ unsigned int j;
+ bfd_size_type amt;
+ asection *first_section;
+ bfd_boolean first_matching_lma;
+ bfd_boolean first_suggested_lma;
+
+ if (segment->p_type == PT_NULL)
+ continue;
+
+ first_section = NULL;
+ /* Compute how many sections might be placed into this segment. */
+ for (section = ibfd->sections, section_count = 0;
+ section != NULL;
+ section = section->next)
+ {
+ /* Find the first section in the input segment, which may be
+ removed from the corresponding output segment. */
+ if (IS_SECTION_IN_INPUT_SEGMENT (section, segment, bed))
+ {
+ if (first_section == NULL)
+ first_section = section;
+ if (section->output_section != NULL)
+ ++section_count;
+ }
+ }
+
+ /* Allocate a segment map big enough to contain
+ all of the sections we have selected. */
+ amt = sizeof (struct elf_segment_map);
+ amt += ((bfd_size_type) section_count - 1) * sizeof (asection *);
+ map = (struct elf_segment_map *) bfd_zalloc (obfd, amt);
+ if (map == NULL)
+ return FALSE;
+
+ /* Initialise the fields of the segment map. Default to
+ using the physical address of the segment in the input BFD. */
+ map->next = NULL;
+ map->p_type = segment->p_type;
+ map->p_flags = segment->p_flags;
+ map->p_flags_valid = 1;
+
+ /* If the first section in the input segment is removed, there is
+ no need to preserve segment physical address in the corresponding
+ output segment. */
+ if (!first_section || first_section->output_section != NULL)
+ {
+ map->p_paddr = segment->p_paddr;
+ map->p_paddr_valid = p_paddr_valid;
+ }
+
+ /* Determine if this segment contains the ELF file header
+ and if it contains the program headers themselves. */
+ map->includes_filehdr = (segment->p_offset == 0
+ && segment->p_filesz >= iehdr->e_ehsize);
+ map->includes_phdrs = 0;
+
+ if (!phdr_included || segment->p_type != PT_LOAD)
+ {
+ map->includes_phdrs =
+ (segment->p_offset <= (bfd_vma) iehdr->e_phoff
+ && (segment->p_offset + segment->p_filesz
+ >= ((bfd_vma) iehdr->e_phoff
+ + iehdr->e_phnum * iehdr->e_phentsize)));
+
+ if (segment->p_type == PT_LOAD && map->includes_phdrs)
+ phdr_included = TRUE;
+ }
+
+ if (section_count == 0)
+ {
+ /* Special segments, such as the PT_PHDR segment, may contain
+ no sections, but ordinary, loadable segments should contain
+ something. They are allowed by the ELF spec however, so only
+ a warning is produced. */
+ if (segment->p_type == PT_LOAD)
+ (*_bfd_error_handler) (_("%B: warning: Empty loadable segment"
+ " detected, is this intentional ?\n"),
+ ibfd);
+
+ map->count = 0;
+ *pointer_to_map = map;
+ pointer_to_map = &map->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 by 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_malloc2 (section_count, sizeof (asection *));
+ 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 = 0;
+ suggested_lma = 0;
+ first_matching_lma = TRUE;
+ first_suggested_lma = TRUE;
+
+ for (section = ibfd->sections;
+ section != NULL;
+ section = section->next)
+ if (section == first_section)
+ break;
+
+ for (j = 0; section != NULL; section = section->next)
+ {
+ if (INCLUDE_SECTION_IN_SEGMENT (section, segment, bed))
+ {
+ output_section = section->output_section;
+
+ sections[j++] = section;
+
+ /* The Solaris native linker always sets p_paddr to 0.
+ We try to catch that case here, and set it to the
+ correct value. Note - some backends require that
+ p_paddr be left as zero. */
+ if (!p_paddr_valid
+ && segment->p_vaddr != 0
+ && !bed->want_p_paddr_set_to_zero
+ && isec == 0
+ && output_section->lma != 0
+ && output_section->vma == (segment->p_vaddr
+ + (map->includes_filehdr
+ ? iehdr->e_ehsize
+ : 0)
+ + (map->includes_phdrs
+ ? (iehdr->e_phnum
+ * iehdr->e_phentsize)
+ : 0)))
+ map->p_paddr = segment->p_vaddr;
+
+ /* Match up the physical address of the segment with the
+ LMA address of the output section. */
+ if (IS_CONTAINED_BY_LMA (output_section, segment, map->p_paddr)
+ || IS_COREFILE_NOTE (segment, section)
+ || (bed->want_p_paddr_set_to_zero
+ && IS_CONTAINED_BY_VMA (output_section, segment)))
+ {
+ if (first_matching_lma || output_section->lma < matching_lma)
+ {
+ matching_lma = output_section->lma;
+ first_matching_lma = FALSE;
+ }
+
+ /* We assume that if the section fits within the segment
+ then it does not overlap any other section within that
+ segment. */
+ map->sections[isec++] = output_section;
+ }
+ else if (first_suggested_lma)
+ {
+ suggested_lma = output_section->lma;
+ first_suggested_lma = FALSE;
+ }
+
+ if (j == section_count)
+ break;
+ }
+ }
+
+ BFD_ASSERT (j == section_count);
+
+ /* Step Two: Adjust the physical address of the current segment,
+ if necessary. */
+ if (isec == section_count)
+ {
+ /* 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. */
+ map->count = section_count;
+ *pointer_to_map = map;
+ pointer_to_map = &map->next;
+
+ if (p_paddr_valid
+ && !bed->want_p_paddr_set_to_zero
+ && matching_lma != map->p_paddr
+ && !map->includes_filehdr
+ && !map->includes_phdrs)
+ /* There is some padding before the first section in the
+ segment. So, we must account for that in the output
+ segment's vma. */
+ map->p_vaddr_offset = matching_lma - map->p_paddr;
+
+ free (sections);
+ continue;
+ }
+ else
+ {
+ if (!first_matching_lma)
+ {
+ /* 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. */
+ map->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. */
+ map->p_paddr = suggested_lma;
+ }
+
+ /* Offset the segment physical address from the lma
+ to allow for space taken up by elf headers. */
+ if (map->includes_filehdr)
+ {
+ if (map->p_paddr >= iehdr->e_ehsize)
+ map->p_paddr -= iehdr->e_ehsize;
+ else
+ {
+ map->includes_filehdr = FALSE;
+ map->includes_phdrs = FALSE;
+ }
+ }
+
+ if (map->includes_phdrs)
+ {
+ if (map->p_paddr >= iehdr->e_phnum * iehdr->e_phentsize)
+ {
+ map->p_paddr -= iehdr->e_phnum * iehdr->e_phentsize;
+
+ /* iehdr->e_phnum is just an estimate of the number
+ of program headers that we will need. Make a note
+ here of the number we used and the segment we chose
+ to hold these headers, so that we can adjust the
+ offset when we know the correct value. */
+ phdr_adjust_num = iehdr->e_phnum;
+ phdr_adjust_seg = map;
+ }
+ else
+ map->includes_phdrs = FALSE;
+ }
+ }
+
+ /* Step Three: Loop over the sections again, this time assigning
+ those that fit to the current segment and removing 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
+ {
+ map->count = 0;
+ suggested_lma = 0;
+ first_suggested_lma = TRUE;
+
+ /* Fill the current segment with sections that fit. */
+ for (j = 0; j < section_count; j++)
+ {
+ section = sections[j];
+
+ if (section == NULL)
+ continue;
+
+ output_section = section->output_section;
+
+ BFD_ASSERT (output_section != NULL);
+
+ if (IS_CONTAINED_BY_LMA (output_section, segment, map->p_paddr)
+ || IS_COREFILE_NOTE (segment, section))
+ {
+ if (map->count == 0)
+ {
+ /* If the first section in a segment does not start at
+ the beginning of the segment, then something is
+ wrong. */
+ if (output_section->lma
+ != (map->p_paddr
+ + (map->includes_filehdr ? iehdr->e_ehsize : 0)
+ + (map->includes_phdrs
+ ? iehdr->e_phnum * iehdr->e_phentsize
+ : 0)))
+ abort ();
+ }
+ else
+ {
+ asection *prev_sec;
+
+ prev_sec = map->sections[map->count - 1];
+
+ /* 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->size,
+ maxpagesize)
+ < BFD_ALIGN (output_section->lma, maxpagesize))
+ || (prev_sec->lma + prev_sec->size
+ > output_section->lma))
+ {
+ if (first_suggested_lma)
+ {
+ suggested_lma = output_section->lma;
+ first_suggested_lma = FALSE;
+ }
+
+ continue;
+ }
+ }
+
+ map->sections[map->count++] = output_section;
+ ++isec;
+ sections[j] = NULL;
+ section->segment_mark = TRUE;
+ }
+ else if (first_suggested_lma)
+ {
+ suggested_lma = output_section->lma;
+ first_suggested_lma = FALSE;
+ }
+ }
+
+ BFD_ASSERT (map->count > 0);
+
+ /* Add the current segment to the list of built segments. */
+ *pointer_to_map = map;
+ pointer_to_map = &map->next;
+
+ if (isec < section_count)
+ {
+ /* We still have not allocated all of the sections to
+ segments. Create a new segment here, initialise it
+ and carry on looping. */
+ amt = sizeof (struct elf_segment_map);
+ amt += ((bfd_size_type) section_count - 1) * sizeof (asection *);
+ map = (struct elf_segment_map *) bfd_zalloc (obfd, amt);
+ if (map == NULL)
+ {
+ free (sections);
+ 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. */
+ map->next = NULL;
+ map->p_type = segment->p_type;
+ map->p_flags = segment->p_flags;
+ map->p_flags_valid = 1;
+ map->p_paddr = suggested_lma;
+ map->p_paddr_valid = p_paddr_valid;
+ map->includes_filehdr = 0;
+ map->includes_phdrs = 0;
+ }
+ }
+ while (isec < section_count);
+
+ free (sections);
+ }
+
+ elf_seg_map (obfd) = map_first;
+
+ /* If we had to estimate the number of program headers that were
+ going to be needed, then check our estimate now and adjust
+ the offset if necessary. */
+ if (phdr_adjust_seg != NULL)
+ {
+ unsigned int count;
+
+ for (count = 0, map = map_first; map != NULL; map = map->next)
+ count++;
+
+ if (count > phdr_adjust_num)
+ phdr_adjust_seg->p_paddr
+ -= (count - phdr_adjust_num) * iehdr->e_phentsize;
+ }
+
+#undef SEGMENT_END
+#undef SECTION_SIZE
+#undef IS_CONTAINED_BY_VMA
+#undef IS_CONTAINED_BY_LMA
+#undef IS_NOTE
+#undef IS_COREFILE_NOTE
+#undef IS_SOLARIS_PT_INTERP
+#undef IS_SECTION_IN_INPUT_SEGMENT
+#undef INCLUDE_SECTION_IN_SEGMENT
+#undef SEGMENT_AFTER_SEGMENT
+#undef SEGMENT_OVERLAPS
+ return TRUE;
+}
+
+/* Copy ELF program header information. */
+
+static bfd_boolean
+copy_elf_program_header (bfd *ibfd, bfd *obfd)
+{
+ Elf_Internal_Ehdr *iehdr;
+ struct elf_segment_map *map;
+ struct elf_segment_map *map_first;
+ struct elf_segment_map **pointer_to_map;
+ Elf_Internal_Phdr *segment;
+ unsigned int i;
+ unsigned int num_segments;
+ bfd_boolean phdr_included = FALSE;
+ bfd_boolean p_paddr_valid;
+
+ iehdr = elf_elfheader (ibfd);
+
+ map_first = NULL;
+ pointer_to_map = &map_first;
+
+ /* If all the segment p_paddr fields are zero, don't set
+ map->p_paddr_valid. */
+ p_paddr_valid = FALSE;
+ num_segments = elf_elfheader (ibfd)->e_phnum;
+ for (i = 0, segment = elf_tdata (ibfd)->phdr;
+ i < num_segments;
+ i++, segment++)
+ if (segment->p_paddr != 0)
+ {
+ p_paddr_valid = TRUE;
+ break;
+ }
+
+ for (i = 0, segment = elf_tdata (ibfd)->phdr;
+ i < num_segments;
+ i++, segment++)
+ {
+ asection *section;
+ unsigned int section_count;
+ bfd_size_type amt;
+ Elf_Internal_Shdr *this_hdr;
+ asection *first_section = NULL;
+ asection *lowest_section;
+
+ /* Compute how many sections are in this segment. */
+ for (section = ibfd->sections, section_count = 0;
+ section != NULL;
+ section = section->next)
+ {
+ this_hdr = &(elf_section_data(section)->this_hdr);
+ if (ELF_SECTION_IN_SEGMENT (this_hdr, segment))
+ {
+ if (first_section == NULL)
+ first_section = section;
+ section_count++;
+ }
+ }
+
+ /* Allocate a segment map big enough to contain
+ all of the sections we have selected. */
+ amt = sizeof (struct elf_segment_map);
+ if (section_count != 0)
+ amt += ((bfd_size_type) section_count - 1) * sizeof (asection *);
+ map = (struct elf_segment_map *) bfd_zalloc (obfd, amt);
+ if (map == NULL)
+ return FALSE;
+
+ /* Initialize the fields of the output segment map with the
+ input segment. */
+ map->next = NULL;
+ map->p_type = segment->p_type;
+ map->p_flags = segment->p_flags;
+ map->p_flags_valid = 1;
+ map->p_paddr = segment->p_paddr;
+ map->p_paddr_valid = p_paddr_valid;
+ map->p_align = segment->p_align;
+ map->p_align_valid = 1;
+ map->p_vaddr_offset = 0;
+
+ if (map->p_type == PT_GNU_RELRO
+ || map->p_type == PT_GNU_STACK)
+ {
+ /* The PT_GNU_RELRO segment may contain the first a few
+ bytes in the .got.plt section even if the whole .got.plt
+ section isn't in the PT_GNU_RELRO segment. We won't
+ change the size of the PT_GNU_RELRO segment.
+ Similarly, PT_GNU_STACK size is significant on uclinux
+ systems. */
+ map->p_size = segment->p_memsz;
+ map->p_size_valid = 1;
+ }
+
+ /* Determine if this segment contains the ELF file header
+ and if it contains the program headers themselves. */
+ map->includes_filehdr = (segment->p_offset == 0
+ && segment->p_filesz >= iehdr->e_ehsize);
+
+ map->includes_phdrs = 0;
+ if (! phdr_included || segment->p_type != PT_LOAD)
+ {
+ map->includes_phdrs =
+ (segment->p_offset <= (bfd_vma) iehdr->e_phoff
+ && (segment->p_offset + segment->p_filesz
+ >= ((bfd_vma) iehdr->e_phoff
+ + iehdr->e_phnum * iehdr->e_phentsize)));
+
+ if (segment->p_type == PT_LOAD && map->includes_phdrs)
+ phdr_included = TRUE;
+ }
+
+ lowest_section = NULL;
+ if (section_count != 0)
+ {
+ unsigned int isec = 0;
+
+ for (section = first_section;
+ section != NULL;
+ section = section->next)
+ {
+ this_hdr = &(elf_section_data(section)->this_hdr);
+ if (ELF_SECTION_IN_SEGMENT (this_hdr, segment))
+ {
+ map->sections[isec++] = section->output_section;
+ if ((section->flags & SEC_ALLOC) != 0)
+ {
+ bfd_vma seg_off;
+
+ if (lowest_section == NULL
+ || section->lma < lowest_section->lma)
+ lowest_section = section;
+
+ /* Section lmas are set up from PT_LOAD header
+ p_paddr in _bfd_elf_make_section_from_shdr.
+ If this header has a p_paddr that disagrees
+ with the section lma, flag the p_paddr as
+ invalid. */
+ if ((section->flags & SEC_LOAD) != 0)
+ seg_off = this_hdr->sh_offset - segment->p_offset;
+ else
+ seg_off = this_hdr->sh_addr - segment->p_vaddr;
+ if (section->lma - segment->p_paddr != seg_off)
+ map->p_paddr_valid = FALSE;
+ }
+ if (isec == section_count)
+ break;
+ }
+ }
+ }
+
+ if (map->includes_filehdr && lowest_section != NULL)
+ /* We need to keep the space used by the headers fixed. */
+ map->header_size = lowest_section->vma - segment->p_vaddr;
+
+ if (!map->includes_phdrs
+ && !map->includes_filehdr
+ && map->p_paddr_valid)
+ /* There is some other padding before the first section. */
+ map->p_vaddr_offset = ((lowest_section ? lowest_section->lma : 0)
+ - segment->p_paddr);
+
+ map->count = section_count;
+ *pointer_to_map = map;
+ pointer_to_map = &map->next;
+ }
+
+ elf_seg_map (obfd) = map_first;
+ return TRUE;
+}
+
+/* Copy private BFD data. This copies or rewrites ELF program header
+ information. */
+
+static bfd_boolean
+copy_private_bfd_data (bfd *ibfd, bfd *obfd)
+{
+ 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;
+
+ if (ibfd->xvec == obfd->xvec)
+ {
+ /* Check to see if any sections in the input BFD
+ covered by ELF program header have changed. */
+ Elf_Internal_Phdr *segment;
+ asection *section, *osec;
+ unsigned int i, num_segments;
+ Elf_Internal_Shdr *this_hdr;
+ const struct elf_backend_data *bed;
+
+ bed = get_elf_backend_data (ibfd);
+
+ /* Regenerate the segment map if p_paddr is set to 0. */
+ if (bed->want_p_paddr_set_to_zero)
+ goto rewrite;
+
+ /* Initialize the segment mark field. */
+ for (section = obfd->sections; section != NULL;
+ section = section->next)
+ section->segment_mark = FALSE;
+
+ num_segments = elf_elfheader (ibfd)->e_phnum;
+ for (i = 0, segment = elf_tdata (ibfd)->phdr;
+ i < num_segments;
+ i++, segment++)
+ {
+ /* PR binutils/3535. The Solaris linker always sets the p_paddr
+ and p_memsz fields of special segments (DYNAMIC, INTERP) to 0
+ which severly confuses things, so always regenerate the segment
+ map in this case. */
+ if (segment->p_paddr == 0
+ && segment->p_memsz == 0
+ && (segment->p_type == PT_INTERP || segment->p_type == PT_DYNAMIC))
+ goto rewrite;
+
+ for (section = ibfd->sections;
+ section != NULL; section = section->next)
+ {
+ /* We mark the output section so that we know it comes
+ from the input BFD. */
+ osec = section->output_section;
+ if (osec)
+ osec->segment_mark = TRUE;
+
+ /* Check if this section is covered by the segment. */
+ this_hdr = &(elf_section_data(section)->this_hdr);
+ if (ELF_SECTION_IN_SEGMENT (this_hdr, segment))
+ {
+ /* FIXME: Check if its output section is changed or
+ removed. What else do we need to check? */
+ if (osec == NULL
+ || section->flags != osec->flags
+ || section->lma != osec->lma
+ || section->vma != osec->vma
+ || section->size != osec->size
+ || section->rawsize != osec->rawsize
+ || section->alignment_power != osec->alignment_power)
+ goto rewrite;
+ }
+ }
+ }
+
+ /* Check to see if any output section do not come from the
+ input BFD. */
+ for (section = obfd->sections; section != NULL;
+ section = section->next)
+ {
+ if (section->segment_mark == FALSE)
+ goto rewrite;
+ else
+ section->segment_mark = FALSE;
+ }
+
+ return copy_elf_program_header (ibfd, obfd);
+ }
+
+rewrite:
+ if (ibfd->xvec == obfd->xvec)
+ {
+ /* When rewriting program header, set the output maxpagesize to
+ the maximum alignment of input PT_LOAD segments. */
+ Elf_Internal_Phdr *segment;
+ unsigned int i;
+ unsigned int num_segments = elf_elfheader (ibfd)->e_phnum;
+ bfd_vma maxpagesize = 0;
+
+ for (i = 0, segment = elf_tdata (ibfd)->phdr;
+ i < num_segments;
+ i++, segment++)
+ if (segment->p_type == PT_LOAD
+ && maxpagesize < segment->p_align)
+ maxpagesize = segment->p_align;
+
+ if (maxpagesize != get_elf_backend_data (obfd)->maxpagesize)
+ bfd_emul_set_maxpagesize (bfd_get_target (obfd), maxpagesize);
+ }
+
+ return rewrite_elf_program_header (ibfd, obfd);
+}
+
+/* Initialize private output section information from input section. */
+
+bfd_boolean
+_bfd_elf_init_private_section_data (bfd *ibfd,
+ asection *isec,
+ bfd *obfd,
+ asection *osec,
+ struct bfd_link_info *link_info)
+
+{
+ Elf_Internal_Shdr *ihdr, *ohdr;
+ bfd_boolean final_link = link_info != NULL && !link_info->relocatable;
+
+ if (ibfd->xvec->flavour != bfd_target_elf_flavour
+ || obfd->xvec->flavour != bfd_target_elf_flavour)
+ return TRUE;
+
+ BFD_ASSERT (elf_section_data (osec) != NULL);
+
+ /* For objcopy and relocatable link, don't copy the output ELF
+ section type from input if the output BFD section flags have been
+ set to something different. For a final link allow some flags
+ that the linker clears to differ. */
+ if (elf_section_type (osec) == SHT_NULL
+ && (osec->flags == isec->flags
+ || (final_link
+ && ((osec->flags ^ isec->flags)
+ & ~(SEC_LINK_ONCE | SEC_LINK_DUPLICATES | SEC_RELOC)) == 0)))
+ elf_section_type (osec) = elf_section_type (isec);
+
+ /* FIXME: Is this correct for all OS/PROC specific flags? */
+ elf_section_flags (osec) |= (elf_section_flags (isec)
+ & (SHF_MASKOS | SHF_MASKPROC));
+
+ /* Set things up for objcopy and relocatable link. The output
+ SHT_GROUP section will have its elf_next_in_group pointing back
+ to the input group members. Ignore linker created group section.
+ See elfNN_ia64_object_p in elfxx-ia64.c. */
+ if (!final_link)
+ {
+ if (elf_sec_group (isec) == NULL
+ || (elf_sec_group (isec)->flags & SEC_LINKER_CREATED) == 0)
+ {
+ if (elf_section_flags (isec) & SHF_GROUP)
+ elf_section_flags (osec) |= SHF_GROUP;
+ elf_next_in_group (osec) = elf_next_in_group (isec);
+ elf_section_data (osec)->group = elf_section_data (isec)->group;
+ }
+ }
+
+ ihdr = &elf_section_data (isec)->this_hdr;
+
+ /* We need to handle elf_linked_to_section for SHF_LINK_ORDER. We
+ don't use the output section of the linked-to section since it
+ may be NULL at this point. */
+ if ((ihdr->sh_flags & SHF_LINK_ORDER) != 0)
+ {
+ ohdr = &elf_section_data (osec)->this_hdr;
+ ohdr->sh_flags |= SHF_LINK_ORDER;
+ elf_linked_to_section (osec) = elf_linked_to_section (isec);
+ }
+
+ osec->use_rela_p = isec->use_rela_p;
+
+ return TRUE;
+}
+
+/* Copy private section information. This copies over the entsize
+ field, and sometimes the info field. */
+
+bfd_boolean
+_bfd_elf_copy_private_section_data (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;
+
+ 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 _bfd_elf_init_private_section_data (ibfd, isec, obfd, osec,
+ NULL);
+}
+
+/* Look at all the SHT_GROUP sections in IBFD, making any adjustments
+ necessary if we are removing either the SHT_GROUP section or any of
+ the group member sections. DISCARDED is the value that a section's
+ output_section has if the section will be discarded, NULL when this
+ function is called from objcopy, bfd_abs_section_ptr when called
+ from the linker. */
+
+bfd_boolean
+_bfd_elf_fixup_group_sections (bfd *ibfd, asection *discarded)
+{
+ asection *isec;
+
+ for (isec = ibfd->sections; isec != NULL; isec = isec->next)
+ if (elf_section_type (isec) == SHT_GROUP)
+ {
+ asection *first = elf_next_in_group (isec);
+ asection *s = first;
+ bfd_size_type removed = 0;
+
+ while (s != NULL)
+ {
+ /* If this member section is being output but the
+ SHT_GROUP section is not, then clear the group info
+ set up by _bfd_elf_copy_private_section_data. */
+ if (s->output_section != discarded
+ && isec->output_section == discarded)
+ {
+ elf_section_flags (s->output_section) &= ~SHF_GROUP;
+ elf_group_name (s->output_section) = NULL;
+ }
+ /* Conversely, if the member section is not being output
+ but the SHT_GROUP section is, then adjust its size. */
+ else if (s->output_section == discarded
+ && isec->output_section != discarded)
+ removed += 4;
+ s = elf_next_in_group (s);
+ if (s == first)
+ break;
+ }
+ if (removed != 0)
+ {
+ if (discarded != NULL)
+ {
+ /* If we've been called for ld -r, then we need to
+ adjust the input section size. This function may
+ be called multiple times, so save the original
+ size. */
+ if (isec->rawsize == 0)
+ isec->rawsize = isec->size;
+ isec->size = isec->rawsize - removed;
+ }
+ else
+ {
+ /* Adjust the output section size when called from
+ objcopy. */
+ isec->output_section->size -= removed;
+ }
+ }
+ }
+
+ return TRUE;
+}
+
+/* Copy private header information. */
+
+bfd_boolean
+_bfd_elf_copy_private_header_data (bfd *ibfd, bfd *obfd)
+{
+ if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
+ || bfd_get_flavour (obfd) != 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_seg_map (obfd) == NULL && elf_tdata (ibfd)->phdr != NULL)
+ {
+ if (! copy_private_bfd_data (ibfd, obfd))
+ return FALSE;
+ }
+
+ return _bfd_elf_fixup_group_sections (ibfd, NULL);
+}
+
+/* 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_HIOS + 1)
+#define MAP_DYNSYMTAB (SHN_HIOS + 2)
+#define MAP_STRTAB (SHN_HIOS + 3)
+#define MAP_SHSTRTAB (SHN_HIOS + 4)
+#define MAP_SYM_SHNDX (SHN_HIOS + 5)
+
+bfd_boolean
+_bfd_elf_copy_private_symbol_data (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
+ && isym->internal_elf_sym.st_shndx != 0
+ && 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_strtab_sec (ibfd))
+ shndx = MAP_STRTAB;
+ else if (shndx == elf_shstrtab_sec (ibfd))
+ shndx = MAP_SHSTRTAB;
+ else if (shndx == elf_symtab_shndx (ibfd))
+ shndx = MAP_SYM_SHNDX;
+ osym->internal_elf_sym.st_shndx = shndx;
+ }
+
+ return TRUE;
+}
+
+/* Swap out the symbols. */
+
+static bfd_boolean
+swap_out_syms (bfd *abfd,
+ struct bfd_strtab_hash **sttp,
+ int relocatable_p)
+{
+ const struct elf_backend_data *bed;
+ int symcount;
+ asymbol **syms;
+ struct bfd_strtab_hash *stt;
+ Elf_Internal_Shdr *symtab_hdr;
+ Elf_Internal_Shdr *symtab_shndx_hdr;
+ Elf_Internal_Shdr *symstrtab_hdr;
+ bfd_byte *outbound_syms;
+ bfd_byte *outbound_shndx;
+ int idx;
+ unsigned int num_locals;
+ bfd_size_type amt;
+ bfd_boolean name_local_sections;
+
+ if (!elf_map_symbols (abfd, &num_locals))
+ return FALSE;
+
+ /* Dump out the symtabs. */
+ stt = _bfd_elf_stringtab_init ();
+ if (stt == NULL)
+ return FALSE;
+
+ bed = get_elf_backend_data (abfd);
+ symcount = bfd_get_symcount (abfd);
+ 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 = num_locals + 1;
+ symtab_hdr->sh_addralign = (bfd_vma) 1 << bed->s->log_file_align;
+
+ symstrtab_hdr = &elf_tdata (abfd)->strtab_hdr;
+ symstrtab_hdr->sh_type = SHT_STRTAB;
+
+ outbound_syms = (bfd_byte *) bfd_alloc2 (abfd, 1 + symcount,
+ bed->s->sizeof_sym);
+ if (outbound_syms == NULL)
+ {
+ _bfd_stringtab_free (stt);
+ return FALSE;
+ }
+ symtab_hdr->contents = outbound_syms;
+
+ outbound_shndx = NULL;
+ symtab_shndx_hdr = &elf_tdata (abfd)->symtab_shndx_hdr;
+ if (symtab_shndx_hdr->sh_name != 0)
+ {
+ amt = (bfd_size_type) (1 + symcount) * sizeof (Elf_External_Sym_Shndx);
+ outbound_shndx = (bfd_byte *)
+ bfd_zalloc2 (abfd, 1 + symcount, sizeof (Elf_External_Sym_Shndx));
+ if (outbound_shndx == NULL)
+ {
+ _bfd_stringtab_free (stt);
+ return FALSE;
+ }
+
+ symtab_shndx_hdr->contents = outbound_shndx;
+ symtab_shndx_hdr->sh_type = SHT_SYMTAB_SHNDX;
+ symtab_shndx_hdr->sh_size = amt;
+ symtab_shndx_hdr->sh_addralign = sizeof (Elf_External_Sym_Shndx);
+ symtab_shndx_hdr->sh_entsize = sizeof (Elf_External_Sym_Shndx);
+ }
+
+ /* 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;
+ sym.st_target_internal = 0;
+ bed->s->swap_symbol_out (abfd, &sym, outbound_syms, outbound_shndx);
+ outbound_syms += bed->s->sizeof_sym;
+ if (outbound_shndx != NULL)
+ outbound_shndx += sizeof (Elf_External_Sym_Shndx);
+ }
+
+ name_local_sections
+ = (bed->elf_backend_name_local_section_symbols
+ && bed->elf_backend_name_local_section_symbols (abfd));
+
+ syms = bfd_get_outsymbols (abfd);
+ 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 (!name_local_sections
+ && (flags & (BSF_SECTION_SYM | BSF_GLOBAL)) == BSF_SECTION_SYM)
+ {
+ /* Local section symbols have no name. */
+ 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)
+ {
+ _bfd_stringtab_free (stt);
+ 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;
+ unsigned 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_strtab_sec (abfd);
+ break;
+ case MAP_SHSTRTAB:
+ shndx = elf_shstrtab_sec (abfd);
+ break;
+ case MAP_SYM_SHNDX:
+ shndx = elf_symtab_shndx (abfd);
+ break;
+ default:
+ shndx = SHN_ABS;
+ break;
+ }
+ }
+ else
+ {
+ shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
+
+ if (shndx == SHN_BAD)
+ {
+ 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);
+ if (sec2 == NULL)
+ {
+ _bfd_error_handler (_("\
+Unable to find equivalent output section for symbol '%s' from section '%s'"),
+ syms[idx]->name ? syms[idx]->name : "<Local sym>",
+ sec->name);
+ bfd_set_error (bfd_error_invalid_operation);
+ _bfd_stringtab_free (stt);
+ return FALSE;
+ }
+
+ shndx = _bfd_elf_section_from_bfd_section (abfd, sec2);
+ BFD_ASSERT (shndx != SHN_BAD);
+ }
+ }
+
+ sym.st_shndx = shndx;
+ }
+
+ if ((flags & BSF_THREAD_LOCAL) != 0)
+ type = STT_TLS;
+ else if ((flags & BSF_GNU_INDIRECT_FUNCTION) != 0)
+ type = STT_GNU_IFUNC;
+ else if ((flags & BSF_FUNCTION) != 0)
+ type = STT_FUNC;
+ else if ((flags & BSF_OBJECT) != 0)
+ type = STT_OBJECT;
+ else if ((flags & BSF_RELC) != 0)
+ type = STT_RELC;
+ else if ((flags & BSF_SRELC) != 0)
+ type = STT_SRELC;
+ else
+ type = STT_NOTYPE;
+
+ if (syms[idx]->section->flags & SEC_THREAD_LOCAL)
+ type = STT_TLS;
+
+ /* Processor-specific types. */
+ if (type_ptr != NULL
+ && bed->elf_backend_get_symbol_type)
+ type = ((*bed->elf_backend_get_symbol_type)
+ (&type_ptr->internal_elf_sym, type));
+
+ if (flags & BSF_SECTION_SYM)
+ {
+ if (flags & BSF_GLOBAL)
+ sym.st_info = ELF_ST_INFO (STB_GLOBAL, STT_SECTION);
+ else
+ sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_SECTION);
+ }
+ else if (bfd_is_com_section (syms[idx]->section))
+ {
+#ifdef USE_STT_COMMON
+ if (type == STT_OBJECT)
+ sym.st_info = ELF_ST_INFO (STB_GLOBAL, STT_COMMON);
+ else
+#endif
+ 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_GNU_UNIQUE)
+ bind = STB_GNU_UNIQUE;
+ 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;
+ sym.st_target_internal
+ = type_ptr->internal_elf_sym.st_target_internal;
+ }
+ else
+ {
+ sym.st_other = 0;
+ sym.st_target_internal = 0;
+ }
+
+ bed->s->swap_symbol_out (abfd, &sym, outbound_syms, outbound_shndx);
+ outbound_syms += bed->s->sizeof_sym;
+ if (outbound_shndx != NULL)
+ outbound_shndx += sizeof (Elf_External_Sym_Shndx);
+ }
+
+ *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 (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) * (sizeof (asymbol *));
+ if (symcount > 0)
+ symtab_size -= sizeof (asymbol *);
+
+ return symtab_size;
+}
+
+long
+_bfd_elf_get_dynamic_symtab_upper_bound (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) * (sizeof (asymbol *));
+ if (symcount > 0)
+ symtab_size -= sizeof (asymbol *);
+
+ return symtab_size;
+}
+
+long
+_bfd_elf_get_reloc_upper_bound (bfd *abfd ATTRIBUTE_UNUSED,
+ sec_ptr asect)
+{
+ return (asect->reloc_count + 1) * sizeof (arelent *);
+}
+
+/* Canonicalize the relocs. */
+
+long
+_bfd_elf_canonicalize_reloc (bfd *abfd,
+ sec_ptr section,
+ arelent **relptr,
+ asymbol **symbols)
+{
+ arelent *tblptr;
+ unsigned int i;
+ const struct elf_backend_data *bed = get_elf_backend_data (abfd);
+
+ if (! bed->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_canonicalize_symtab (bfd *abfd, asymbol **allocation)
+{
+ const struct elf_backend_data *bed = get_elf_backend_data (abfd);
+ long symcount = bed->s->slurp_symbol_table (abfd, allocation, FALSE);
+
+ if (symcount >= 0)
+ bfd_get_symcount (abfd) = symcount;
+ return symcount;
+}
+
+long
+_bfd_elf_canonicalize_dynamic_symtab (bfd *abfd,
+ asymbol **allocation)
+{
+ const struct elf_backend_data *bed = get_elf_backend_data (abfd);
+ long symcount = bed->s->slurp_symbol_table (abfd, allocation, TRUE);
+
+ if (symcount >= 0)
+ bfd_get_dynamic_symcount (abfd) = symcount;
+ return symcount;
+}
+
+/* Return the size required for the dynamic reloc entries. Any loadable
+ 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 (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->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 loadable 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 (bfd *abfd,
+ arelent **storage,
+ asymbol **syms)
+{
+ bfd_boolean (*slurp_relocs) (bfd *, asection *, asymbol **, bfd_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->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. */
+
+bfd_boolean
+_bfd_elf_slurp_version_tables (bfd *abfd, bfd_boolean default_imported_symver)
+{
+ bfd_byte *contents = NULL;
+ unsigned int freeidx = 0;
+
+ if (elf_dynverref (abfd) != 0)
+ {
+ Elf_Internal_Shdr *hdr;
+ Elf_External_Verneed *everneed;
+ Elf_Internal_Verneed *iverneed;
+ unsigned int i;
+ bfd_byte *contents_end;
+
+ hdr = &elf_tdata (abfd)->dynverref_hdr;
+
+ if (hdr->sh_info)
+ elf_tdata (abfd)->verref = (Elf_Internal_Verneed *)
+ bfd_zalloc2 (abfd, hdr->sh_info, sizeof (Elf_Internal_Verneed));
+ else
+ elf_tdata (abfd)->verref = NULL;
+
+ 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)
+ {
+error_return_verref:
+ elf_tdata (abfd)->verref = NULL;
+ elf_tdata (abfd)->cverrefs = 0;
+ goto error_return;
+ }
+ if (bfd_seek (abfd, hdr->sh_offset, SEEK_SET) != 0
+ || bfd_bread (contents, hdr->sh_size, abfd) != hdr->sh_size)
+ goto error_return_verref;
+
+ if (hdr->sh_info && hdr->sh_size < sizeof (Elf_External_Verneed))
+ goto error_return_verref;
+
+ BFD_ASSERT (sizeof (Elf_External_Verneed)
+ == sizeof (Elf_External_Vernaux));
+ contents_end = contents + hdr->sh_size - sizeof (Elf_External_Verneed);
+ 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_verref;
+
+ if (iverneed->vn_cnt == 0)
+ iverneed->vn_auxptr = NULL;
+ else
+ {
+ iverneed->vn_auxptr = (struct elf_internal_vernaux *)
+ bfd_alloc2 (abfd, iverneed->vn_cnt,
+ sizeof (Elf_Internal_Vernaux));
+ if (iverneed->vn_auxptr == NULL)
+ goto error_return_verref;
+ }
+
+ if (iverneed->vn_aux
+ > (size_t) (contents_end - (bfd_byte *) everneed))
+ goto error_return_verref;
+
+ 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_verref;
+
+ if (j + 1 < iverneed->vn_cnt)
+ ivernaux->vna_nextptr = ivernaux + 1;
+ else
+ ivernaux->vna_nextptr = NULL;
+
+ if (ivernaux->vna_next
+ > (size_t) (contents_end - (bfd_byte *) evernaux))
+ goto error_return_verref;
+
+ evernaux = ((Elf_External_Vernaux *)
+ ((bfd_byte *) evernaux + ivernaux->vna_next));
+
+ if (ivernaux->vna_other > freeidx)
+ freeidx = ivernaux->vna_other;
+ }
+
+ if (i + 1 < hdr->sh_info)
+ iverneed->vn_nextref = iverneed + 1;
+ else
+ iverneed->vn_nextref = NULL;
+
+ if (iverneed->vn_next
+ > (size_t) (contents_end - (bfd_byte *) everneed))
+ goto error_return_verref;
+
+ everneed = ((Elf_External_Verneed *)
+ ((bfd_byte *) everneed + iverneed->vn_next));
+ }
+
+ free (contents);
+ contents = NULL;
+ }
+
+ if (elf_dynverdef (abfd) != 0)
+ {
+ Elf_Internal_Shdr *hdr;
+ Elf_External_Verdef *everdef;
+ Elf_Internal_Verdef *iverdef;
+ Elf_Internal_Verdef *iverdefarr;
+ Elf_Internal_Verdef iverdefmem;
+ unsigned int i;
+ unsigned int maxidx;
+ bfd_byte *contents_end_def, *contents_end_aux;
+
+ hdr = &elf_tdata (abfd)->dynverdef_hdr;
+
+ 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_bread (contents, hdr->sh_size, abfd) != hdr->sh_size)
+ goto error_return;
+
+ if (hdr->sh_info && hdr->sh_size < sizeof (Elf_External_Verdef))
+ goto error_return;
+
+ BFD_ASSERT (sizeof (Elf_External_Verdef)
+ >= sizeof (Elf_External_Verdaux));
+ contents_end_def = contents + hdr->sh_size
+ - sizeof (Elf_External_Verdef);
+ contents_end_aux = contents + hdr->sh_size
+ - sizeof (Elf_External_Verdaux);
+
+ /* We know the number of entries in the section but not the maximum
+ index. Therefore we have to run through all entries and find
+ the maximum. */
+ everdef = (Elf_External_Verdef *) contents;
+ maxidx = 0;
+ for (i = 0; i < hdr->sh_info; ++i)
+ {
+ _bfd_elf_swap_verdef_in (abfd, everdef, &iverdefmem);
+
+ if ((iverdefmem.vd_ndx & ((unsigned) VERSYM_VERSION)) > maxidx)
+ maxidx = iverdefmem.vd_ndx & ((unsigned) VERSYM_VERSION);
+
+ if (iverdefmem.vd_next
+ > (size_t) (contents_end_def - (bfd_byte *) everdef))
+ goto error_return;
+
+ everdef = ((Elf_External_Verdef *)
+ ((bfd_byte *) everdef + iverdefmem.vd_next));
+ }
+
+ if (default_imported_symver)
+ {
+ if (freeidx > maxidx)
+ maxidx = ++freeidx;
+ else
+ freeidx = ++maxidx;
+ }
+ if (maxidx)
+ elf_tdata (abfd)->verdef = (Elf_Internal_Verdef *)
+ bfd_zalloc2 (abfd, maxidx, sizeof (Elf_Internal_Verdef));
+ else
+ elf_tdata (abfd)->verdef = NULL;
+
+ if (elf_tdata (abfd)->verdef == NULL)
+ goto error_return;
+
+ elf_tdata (abfd)->cverdefs = maxidx;
+
+ everdef = (Elf_External_Verdef *) contents;
+ iverdefarr = elf_tdata (abfd)->verdef;
+ for (i = 0; i < hdr->sh_info; i++)
+ {
+ Elf_External_Verdaux *everdaux;
+ Elf_Internal_Verdaux *iverdaux;
+ unsigned int j;
+
+ _bfd_elf_swap_verdef_in (abfd, everdef, &iverdefmem);
+
+ if ((iverdefmem.vd_ndx & VERSYM_VERSION) == 0)
+ {
+error_return_verdef:
+ elf_tdata (abfd)->verdef = NULL;
+ elf_tdata (abfd)->cverdefs = 0;
+ goto error_return;
+ }
+
+ iverdef = &iverdefarr[(iverdefmem.vd_ndx & VERSYM_VERSION) - 1];
+ memcpy (iverdef, &iverdefmem, sizeof (Elf_Internal_Verdef));
+
+ iverdef->vd_bfd = abfd;
+
+ if (iverdef->vd_cnt == 0)
+ iverdef->vd_auxptr = NULL;
+ else
+ {
+ iverdef->vd_auxptr = (struct elf_internal_verdaux *)
+ bfd_alloc2 (abfd, iverdef->vd_cnt,
+ sizeof (Elf_Internal_Verdaux));
+ if (iverdef->vd_auxptr == NULL)
+ goto error_return_verdef;
+ }
+
+ if (iverdef->vd_aux
+ > (size_t) (contents_end_aux - (bfd_byte *) everdef))
+ goto error_return_verdef;
+
+ 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_verdef;
+
+ if (j + 1 < iverdef->vd_cnt)
+ iverdaux->vda_nextptr = iverdaux + 1;
+ else
+ iverdaux->vda_nextptr = NULL;
+
+ if (iverdaux->vda_next
+ > (size_t) (contents_end_aux - (bfd_byte *) everdaux))
+ goto error_return_verdef;
+
+ everdaux = ((Elf_External_Verdaux *)
+ ((bfd_byte *) everdaux + iverdaux->vda_next));
+ }
+
+ if (iverdef->vd_cnt)
+ iverdef->vd_nodename = iverdef->vd_auxptr->vda_nodename;
+
+ if ((size_t) (iverdef - iverdefarr) + 1 < maxidx)
+ iverdef->vd_nextdef = iverdef + 1;
+ else
+ iverdef->vd_nextdef = NULL;
+
+ everdef = ((Elf_External_Verdef *)
+ ((bfd_byte *) everdef + iverdef->vd_next));
+ }
+
+ free (contents);
+ contents = NULL;
+ }
+ else if (default_imported_symver)
+ {
+ if (freeidx < 3)
+ freeidx = 3;
+ else
+ freeidx++;
+
+ elf_tdata (abfd)->verdef = (Elf_Internal_Verdef *)
+ bfd_zalloc2 (abfd, freeidx, sizeof (Elf_Internal_Verdef));
+ if (elf_tdata (abfd)->verdef == NULL)
+ goto error_return;
+
+ elf_tdata (abfd)->cverdefs = freeidx;
+ }
+
+ /* Create a default version based on the soname. */
+ if (default_imported_symver)
+ {
+ Elf_Internal_Verdef *iverdef;
+ Elf_Internal_Verdaux *iverdaux;
+
+ iverdef = &elf_tdata (abfd)->verdef[freeidx - 1];
+
+ iverdef->vd_version = VER_DEF_CURRENT;
+ iverdef->vd_flags = 0;
+ iverdef->vd_ndx = freeidx;
+ iverdef->vd_cnt = 1;
+
+ iverdef->vd_bfd = abfd;
+
+ iverdef->vd_nodename = bfd_elf_get_dt_soname (abfd);
+ if (iverdef->vd_nodename == NULL)
+ goto error_return_verdef;
+ iverdef->vd_nextdef = NULL;
+ iverdef->vd_auxptr = (struct elf_internal_verdaux *)
+ bfd_alloc (abfd, sizeof (Elf_Internal_Verdaux));
+ if (iverdef->vd_auxptr == NULL)
+ goto error_return_verdef;
+
+ iverdaux = iverdef->vd_auxptr;
+ iverdaux->vda_nodename = iverdef->vd_nodename;
+ iverdaux->vda_nextptr = NULL;
+ }
+
+ return TRUE;
+
+ error_return:
+ if (contents != NULL)
+ free (contents);
+ return FALSE;
+}
+
+asymbol *
+_bfd_elf_make_empty_symbol (bfd *abfd)
+{
+ elf_symbol_type *newsym;
+
+ newsym = (elf_symbol_type *) bfd_zalloc (abfd, sizeof * newsym);
+ if (!newsym)
+ return NULL;
+ newsym->symbol.the_bfd = abfd;
+ return &newsym->symbol;
+}
+
+void
+_bfd_elf_get_symbol_info (bfd *abfd ATTRIBUTE_UNUSED,
+ 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. */
+
+bfd_boolean
+_bfd_elf_is_local_label_name (bfd *abfd ATTRIBUTE_UNUSED,
+ 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 (bfd *abfd ATTRIBUTE_UNUSED,
+ asymbol *symbol ATTRIBUTE_UNUSED)
+{
+ abort ();
+ return NULL;
+}
+
+bfd_boolean
+_bfd_elf_set_arch_mach (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 function to a particular section and offset,
+ for error reporting. */
+
+static bfd_boolean
+elf_find_function (bfd *abfd,
+ asymbol **symbols,
+ asection *section,
+ bfd_vma offset,
+ const char **filename_ptr,
+ const char **functionname_ptr)
+{
+ struct elf_find_function_cache
+ {
+ asection *last_section;
+ asymbol *func;
+ const char *filename;
+ bfd_size_type func_size;
+ } *cache;
+
+ if (symbols == NULL)
+ return FALSE;
+
+ cache = elf_tdata (abfd)->elf_find_function_cache;
+ if (cache == NULL)
+ {
+ cache = bfd_zalloc (abfd, sizeof (*cache));
+ elf_tdata (abfd)->elf_find_function_cache = cache;
+ if (cache == NULL)
+ return FALSE;
+ }
+ if (cache->last_section != section
+ || cache->func == NULL
+ || offset < cache->func->value
+ || offset >= cache->func->value + cache->func_size)
+ {
+ asymbol *file;
+ bfd_vma low_func;
+ asymbol **p;
+ /* ??? Given multiple file symbols, it is impossible to reliably
+ choose the right file name for global symbols. File symbols are
+ local symbols, and thus all file symbols must sort before any
+ global symbols. The ELF spec may be interpreted to say that a
+ file symbol must sort before other local symbols, but currently
+ ld -r doesn't do this. So, for ld -r output, it is possible to
+ make a better choice of file name for local symbols by ignoring
+ file symbols appearing after a given local symbol. */
+ enum { nothing_seen, symbol_seen, file_after_symbol_seen } state;
+ const struct elf_backend_data *bed = get_elf_backend_data (abfd);
+
+ file = NULL;
+ low_func = 0;
+ state = nothing_seen;
+ cache->filename = NULL;
+ cache->func = NULL;
+ cache->func_size = 0;
+ cache->last_section = section;
+
+ for (p = symbols; *p != NULL; p++)
+ {
+ asymbol *sym = *p;
+ bfd_vma code_off;
+ bfd_size_type size;
+
+ if ((sym->flags & BSF_FILE) != 0)
+ {
+ file = sym;
+ if (state == symbol_seen)
+ state = file_after_symbol_seen;
+ continue;
+ }
+
+ size = bed->maybe_function_sym (sym, section, &code_off);
+ if (size != 0
+ && code_off <= offset
+ && (code_off > low_func
+ || (code_off == low_func
+ && size > cache->func_size)))
+ {
+ cache->func = sym;
+ cache->func_size = size;
+ cache->filename = NULL;
+ low_func = code_off;
+ if (file != NULL
+ && ((sym->flags & BSF_LOCAL) != 0
+ || state != file_after_symbol_seen))
+ cache->filename = bfd_asymbol_name (file);
+ }
+ if (state == nothing_seen)
+ state = symbol_seen;
+ }
+ }
+
+ if (cache->func == NULL)
+ return FALSE;
+
+ if (filename_ptr)
+ *filename_ptr = cache->filename;
+ if (functionname_ptr)
+ *functionname_ptr = bfd_asymbol_name (cache->func);
+
+ return TRUE;
+}
+
+/* Find the nearest line to a particular section and offset,
+ for error reporting. */
+
+bfd_boolean
+_bfd_elf_find_nearest_line (bfd *abfd,
+ asymbol **symbols,
+ asection *section,
+ bfd_vma offset,
+ const char **filename_ptr,
+ const char **functionname_ptr,
+ unsigned int *line_ptr,
+ unsigned int *discriminator_ptr)
+{
+ bfd_boolean found;
+
+ if (_bfd_dwarf2_find_nearest_line (abfd, symbols, NULL, section, offset,
+ filename_ptr, functionname_ptr,
+ line_ptr, discriminator_ptr,
+ dwarf_debug_sections, 0,
+ &elf_tdata (abfd)->dwarf2_find_line_info))
+ {
+ if (!*functionname_ptr)
+ elf_find_function (abfd, symbols, section, offset,
+ *filename_ptr ? NULL : filename_ptr,
+ functionname_ptr);
+
+ return TRUE;
+ }
+
+ if (_bfd_dwarf1_find_nearest_line (abfd, symbols, section, offset,
+ filename_ptr, functionname_ptr, line_ptr))
+ {
+ if (!*functionname_ptr)
+ elf_find_function (abfd, symbols, section, offset,
+ *filename_ptr ? NULL : filename_ptr,
+ functionname_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 && (*functionname_ptr || *line_ptr))
+ return TRUE;
+
+ if (symbols == NULL)
+ return FALSE;
+
+ if (! elf_find_function (abfd, symbols, section, offset,
+ filename_ptr, functionname_ptr))
+ return FALSE;
+
+ *line_ptr = 0;
+ return TRUE;
+}
+
+/* Find the line for a symbol. */
+
+bfd_boolean
+_bfd_elf_find_line (bfd *abfd, asymbol **symbols, asymbol *symbol,
+ const char **filename_ptr, unsigned int *line_ptr)
+{
+ return _bfd_dwarf2_find_nearest_line (abfd, symbols, symbol, NULL, 0,
+ filename_ptr, NULL, line_ptr, NULL,
+ dwarf_debug_sections, 0,
+ &elf_tdata (abfd)->dwarf2_find_line_info);
+}
+
+/* After a call to bfd_find_nearest_line, successive calls to
+ bfd_find_inliner_info can be used to get source information about
+ each level of function inlining that terminated at the address
+ passed to bfd_find_nearest_line. Currently this is only supported
+ for DWARF2 with appropriate DWARF3 extensions. */
+
+bfd_boolean
+_bfd_elf_find_inliner_info (bfd *abfd,
+ const char **filename_ptr,
+ const char **functionname_ptr,
+ unsigned int *line_ptr)
+{
+ bfd_boolean found;
+ found = _bfd_dwarf2_find_inliner_info (abfd, filename_ptr,
+ functionname_ptr, line_ptr,
+ & elf_tdata (abfd)->dwarf2_find_line_info);
+ return found;
+}
+
+int
+_bfd_elf_sizeof_headers (bfd *abfd, struct bfd_link_info *info)
+{
+ const struct elf_backend_data *bed = get_elf_backend_data (abfd);
+ int ret = bed->s->sizeof_ehdr;
+
+ if (!info->relocatable)
+ {
+ bfd_size_type phdr_size = elf_program_header_size (abfd);
+
+ if (phdr_size == (bfd_size_type) -1)
+ {
+ struct elf_segment_map *m;
+
+ phdr_size = 0;
+ for (m = elf_seg_map (abfd); m != NULL; m = m->next)
+ phdr_size += bed->s->sizeof_phdr;
+
+ if (phdr_size == 0)
+ phdr_size = get_program_header_size (abfd, info);
+ }
+
+ elf_program_header_size (abfd) = phdr_size;
+ ret += phdr_size;
+ }
+
+ return ret;
+}
+
+bfd_boolean
+_bfd_elf_set_section_contents (bfd *abfd,
+ sec_ptr section,
+ const void *location,
+ file_ptr offset,
+ bfd_size_type count)
+{
+ Elf_Internal_Shdr *hdr;
+ file_ptr pos;
+
+ if (! abfd->output_has_begun
+ && ! _bfd_elf_compute_section_file_positions (abfd, NULL))
+ return FALSE;
+
+ hdr = &elf_section_data (section)->this_hdr;
+ pos = hdr->sh_offset + offset;
+ if (bfd_seek (abfd, pos, SEEK_SET) != 0
+ || bfd_bwrite (location, count, abfd) != count)
+ return FALSE;
+
+ return TRUE;
+}
+
+void
+_bfd_elf_no_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED,
+ arelent *cache_ptr ATTRIBUTE_UNUSED,
+ Elf_Internal_Rela *dst ATTRIBUTE_UNUSED)
+{
+ abort ();
+}
+
+/* Try to convert a non-ELF reloc into an ELF one. */
+
+bfd_boolean
+_bfd_elf_validate_reloc (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)
+ (_("%B: unsupported relocation type %s"),
+ abfd, areloc->howto->name);
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+}
+
+bfd_boolean
+_bfd_elf_close_and_cleanup (bfd *abfd)
+{
+ struct elf_obj_tdata *tdata = elf_tdata (abfd);
+ if (bfd_get_format (abfd) == bfd_object && tdata != NULL)
+ {
+ if (elf_tdata (abfd)->o != NULL && elf_shstrtab (abfd) != NULL)
+ _bfd_elf_strtab_free (elf_shstrtab (abfd));
+ _bfd_dwarf2_cleanup_debug_info (abfd, &tdata->dwarf2_find_line_info);
+ }
+
+ 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
+ (bfd *abfd ATTRIBUTE_UNUSED, arelent *re ATTRIBUTE_UNUSED,
+ struct bfd_symbol *symbol ATTRIBUTE_UNUSED,
+ void *data ATTRIBUTE_UNUSED, asection *is ATTRIBUTE_UNUSED,
+ bfd *obfd ATTRIBUTE_UNUSED, char **errmsg ATTRIBUTE_UNUSED)
+{
+ 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
+/* Needed for new procfs interface on sparc-solaris. */
+# define _STRUCTURED_PROC 1
+# include <sys/procfs.h>
+#endif
+
+/* Return a PID that identifies a "thread" for threaded cores, or the
+ PID of the main process for non-threaded cores. */
+
+static int
+elfcore_make_pid (bfd *abfd)
+{
+ int pid;
+
+ pid = elf_tdata (abfd)->core->lwpid;
+ if (pid == 0)
+ pid = elf_tdata (abfd)->core->pid;
+
+ return 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 bfd_boolean
+elfcore_maybe_make_sect (bfd *abfd, char *name, asection *sect)
+{
+ asection *sect2;
+
+ if (bfd_get_section_by_name (abfd, name) != NULL)
+ return TRUE;
+
+ sect2 = bfd_make_section_with_flags (abfd, name, sect->flags);
+ if (sect2 == NULL)
+ return FALSE;
+
+ sect2->size = sect->size;
+ sect2->filepos = sect->filepos;
+ sect2->alignment_power = sect->alignment_power;
+ return TRUE;
+}
+
+/* Create a pseudosection containing SIZE bytes at FILEPOS. This
+ actually creates up to two pseudosections:
+ - For the single-threaded case, a section named NAME, unless
+ such a section already exists.
+ - For the multi-threaded case, a section named "NAME/PID", where
+ PID is elfcore_make_pid (abfd).
+ Both pseudosections have identical contents. */
+bfd_boolean
+_bfd_elfcore_make_pseudosection (bfd *abfd,
+ char *name,
+ size_t size,
+ ufile_ptr filepos)
+{
+ char buf[100];
+ char *threaded_name;
+ size_t len;
+ asection *sect;
+
+ /* Build the section name. */
+
+ sprintf (buf, "%s/%d", name, elfcore_make_pid (abfd));
+ len = strlen (buf) + 1;
+ threaded_name = (char *) bfd_alloc (abfd, len);
+ if (threaded_name == NULL)
+ return FALSE;
+ memcpy (threaded_name, buf, len);
+
+ sect = bfd_make_section_anyway_with_flags (abfd, threaded_name,
+ SEC_HAS_CONTENTS);
+ if (sect == NULL)
+ return FALSE;
+ sect->size = size;
+ sect->filepos = filepos;
+ sect->alignment_power = 2;
+
+ return elfcore_maybe_make_sect (abfd, name, sect);
+}
+
+/* prstatus_t exists on:
+ solaris 2.5+
+ linux 2.[01] + glibc
+ unixware 4.2
+*/
+
+#if defined (HAVE_PRSTATUS_T)
+
+static bfd_boolean
+elfcore_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
+{
+ size_t size;
+ int offset;
+
+ if (note->descsz == sizeof (prstatus_t))
+ {
+ prstatus_t prstat;
+
+ size = sizeof (prstat.pr_reg);
+ offset = offsetof (prstatus_t, pr_reg);
+ memcpy (&prstat, note->descdata, sizeof (prstat));
+
+ /* Do not overwrite the core signal if it
+ has already been set by another thread. */
+ if (elf_tdata (abfd)->core->signal == 0)
+ elf_tdata (abfd)->core->signal = prstat.pr_cursig;
+ if (elf_tdata (abfd)->core->pid == 0)
+ elf_tdata (abfd)->core->pid = prstat.pr_pid;
+
+ /* pr_who exists on:
+ solaris 2.5+
+ 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;
+#else
+ elf_tdata (abfd)->core->lwpid = prstat.pr_pid;
+#endif
+ }
+#if defined (HAVE_PRSTATUS32_T)
+ else if (note->descsz == sizeof (prstatus32_t))
+ {
+ /* 64-bit host, 32-bit corefile */
+ prstatus32_t prstat;
+
+ size = sizeof (prstat.pr_reg);
+ offset = offsetof (prstatus32_t, pr_reg);
+ memcpy (&prstat, note->descdata, sizeof (prstat));
+
+ /* Do not overwrite the core signal if it
+ has already been set by another thread. */
+ if (elf_tdata (abfd)->core->signal == 0)
+ elf_tdata (abfd)->core->signal = prstat.pr_cursig;
+ if (elf_tdata (abfd)->core->pid == 0)
+ elf_tdata (abfd)->core->pid = prstat.pr_pid;
+
+ /* pr_who exists on:
+ solaris 2.5+
+ unixware 4.2
+ pr_who doesn't exist on:
+ linux 2.[01]
+ */
+#if defined (HAVE_PRSTATUS32_T_PR_WHO)
+ elf_tdata (abfd)->core->lwpid = prstat.pr_who;
+#else
+ elf_tdata (abfd)->core->lwpid = prstat.pr_pid;
+#endif
+ }
+#endif /* HAVE_PRSTATUS32_T */
+ else
+ {
+ /* Fail - we don't know how to handle any other
+ note size (ie. data object type). */
+ return TRUE;
+ }
+
+ /* Make a ".reg/999" section and a ".reg" section. */
+ return _bfd_elfcore_make_pseudosection (abfd, ".reg",
+ size, note->descpos + offset);
+}
+#endif /* defined (HAVE_PRSTATUS_T) */
+
+/* Create a pseudosection containing the exact contents of NOTE. */
+static bfd_boolean
+elfcore_make_note_pseudosection (bfd *abfd,
+ char *name,
+ Elf_Internal_Note *note)
+{
+ return _bfd_elfcore_make_pseudosection (abfd, name,
+ note->descsz, note->descpos);
+}
+
+/* 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 bfd_boolean
+elfcore_grok_prfpreg (bfd *abfd, Elf_Internal_Note *note)
+{
+ return elfcore_make_note_pseudosection (abfd, ".reg2", note);
+}
+
+/* Linux dumps the Intel SSE regs in a note named "LINUX" with a note
+ type of NT_PRXFPREG. Just include the whole note's contents
+ literally. */
+
+static bfd_boolean
+elfcore_grok_prxfpreg (bfd *abfd, Elf_Internal_Note *note)
+{
+ return elfcore_make_note_pseudosection (abfd, ".reg-xfp", note);
+}
+
+/* Linux dumps the Intel XSAVE extended state in a note named "LINUX"
+ with a note type of NT_X86_XSTATE. Just include the whole note's
+ contents literally. */
+
+static bfd_boolean
+elfcore_grok_xstatereg (bfd *abfd, Elf_Internal_Note *note)
+{
+ return elfcore_make_note_pseudosection (abfd, ".reg-xstate", note);
+}
+
+static bfd_boolean
+elfcore_grok_ppc_vmx (bfd *abfd, Elf_Internal_Note *note)
+{
+ return elfcore_make_note_pseudosection (abfd, ".reg-ppc-vmx", note);
+}
+
+static bfd_boolean
+elfcore_grok_ppc_vsx (bfd *abfd, Elf_Internal_Note *note)
+{
+ return elfcore_make_note_pseudosection (abfd, ".reg-ppc-vsx", note);
+}
+
+static bfd_boolean
+elfcore_grok_s390_high_gprs (bfd *abfd, Elf_Internal_Note *note)
+{
+ return elfcore_make_note_pseudosection (abfd, ".reg-s390-high-gprs", note);
+}
+
+static bfd_boolean
+elfcore_grok_s390_timer (bfd *abfd, Elf_Internal_Note *note)
+{
+ return elfcore_make_note_pseudosection (abfd, ".reg-s390-timer", note);
+}
+
+static bfd_boolean
+elfcore_grok_s390_todcmp (bfd *abfd, Elf_Internal_Note *note)
+{
+ return elfcore_make_note_pseudosection (abfd, ".reg-s390-todcmp", note);
+}
+
+static bfd_boolean
+elfcore_grok_s390_todpreg (bfd *abfd, Elf_Internal_Note *note)
+{
+ return elfcore_make_note_pseudosection (abfd, ".reg-s390-todpreg", note);
+}
+
+static bfd_boolean
+elfcore_grok_s390_ctrs (bfd *abfd, Elf_Internal_Note *note)
+{
+ return elfcore_make_note_pseudosection (abfd, ".reg-s390-ctrs", note);
+}
+
+static bfd_boolean
+elfcore_grok_s390_prefix (bfd *abfd, Elf_Internal_Note *note)
+{
+ return elfcore_make_note_pseudosection (abfd, ".reg-s390-prefix", note);
+}
+
+static bfd_boolean
+elfcore_grok_s390_last_break (bfd *abfd, Elf_Internal_Note *note)
+{
+ return elfcore_make_note_pseudosection (abfd, ".reg-s390-last-break", note);
+}
+
+static bfd_boolean
+elfcore_grok_s390_system_call (bfd *abfd, Elf_Internal_Note *note)
+{
+ return elfcore_make_note_pseudosection (abfd, ".reg-s390-system-call", note);
+}
+
+static bfd_boolean
+elfcore_grok_s390_tdb (bfd *abfd, Elf_Internal_Note *note)
+{
+ return elfcore_make_note_pseudosection (abfd, ".reg-s390-tdb", note);
+}
+
+static bfd_boolean
+elfcore_grok_arm_vfp (bfd *abfd, Elf_Internal_Note *note)
+{
+ return elfcore_make_note_pseudosection (abfd, ".reg-arm-vfp", note);
+}
+
+static bfd_boolean
+elfcore_grok_aarch_tls (bfd *abfd, Elf_Internal_Note *note)
+{
+ return elfcore_make_note_pseudosection (abfd, ".reg-aarch-tls", note);
+}
+
+static bfd_boolean
+elfcore_grok_aarch_hw_break (bfd *abfd, Elf_Internal_Note *note)
+{
+ return elfcore_make_note_pseudosection (abfd, ".reg-aarch-hw-break", note);
+}
+
+static bfd_boolean
+elfcore_grok_aarch_hw_watch (bfd *abfd, Elf_Internal_Note *note)
+{
+ return elfcore_make_note_pseudosection (abfd, ".reg-aarch-hw-watch", note);
+}
+
+#if defined (HAVE_PRPSINFO_T)
+typedef prpsinfo_t elfcore_psinfo_t;
+#if defined (HAVE_PRPSINFO32_T) /* Sparc64 cross Sparc32 */
+typedef prpsinfo32_t elfcore_psinfo32_t;
+#endif
+#endif
+
+#if defined (HAVE_PSINFO_T)
+typedef psinfo_t elfcore_psinfo_t;
+#if defined (HAVE_PSINFO32_T) /* Sparc64 cross Sparc32 */
+typedef psinfo32_t elfcore_psinfo32_t;
+#endif
+#endif
+
+/* 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'. */
+
+char *
+_bfd_elfcore_strndup (bfd *abfd, char *start, size_t max)
+{
+ char *dups;
+ char *end = (char *) memchr (start, '\0', max);
+ size_t len;
+
+ if (end == NULL)
+ len = max;
+ else
+ len = end - start;
+
+ dups = (char *) bfd_alloc (abfd, len + 1);
+ if (dups == NULL)
+ return NULL;
+
+ memcpy (dups, start, len);
+ dups[len] = '\0';
+
+ return dups;
+}
+
+#if defined (HAVE_PRPSINFO_T) || defined (HAVE_PSINFO_T)
+static bfd_boolean
+elfcore_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
+{
+ if (note->descsz == sizeof (elfcore_psinfo_t))
+ {
+ elfcore_psinfo_t psinfo;
+
+ memcpy (&psinfo, note->descdata, sizeof (psinfo));
+
+#if defined (HAVE_PSINFO_T_PR_PID) || defined (HAVE_PRPSINFO_T_PR_PID)
+ elf_tdata (abfd)->core->pid = psinfo.pr_pid;
+#endif
+ elf_tdata (abfd)->core->program
+ = _bfd_elfcore_strndup (abfd, psinfo.pr_fname,
+ sizeof (psinfo.pr_fname));
+
+ elf_tdata (abfd)->core->command
+ = _bfd_elfcore_strndup (abfd, psinfo.pr_psargs,
+ sizeof (psinfo.pr_psargs));
+ }
+#if defined (HAVE_PRPSINFO32_T) || defined (HAVE_PSINFO32_T)
+ else if (note->descsz == sizeof (elfcore_psinfo32_t))
+ {
+ /* 64-bit host, 32-bit corefile */
+ elfcore_psinfo32_t psinfo;
+
+ memcpy (&psinfo, note->descdata, sizeof (psinfo));
+
+#if defined (HAVE_PSINFO32_T_PR_PID) || defined (HAVE_PRPSINFO32_T_PR_PID)
+ elf_tdata (abfd)->core->pid = psinfo.pr_pid;
+#endif
+ elf_tdata (abfd)->core->program
+ = _bfd_elfcore_strndup (abfd, psinfo.pr_fname,
+ sizeof (psinfo.pr_fname));
+
+ elf_tdata (abfd)->core->command
+ = _bfd_elfcore_strndup (abfd, psinfo.pr_psargs,
+ sizeof (psinfo.pr_psargs));
+ }
+#endif
+
+ else
+ {
+ /* Fail - we don't know how to handle any other
+ note size (ie. data object type). */
+ return TRUE;
+ }
+
+ /* 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 bfd_boolean
+elfcore_grok_pstatus (bfd *abfd, Elf_Internal_Note *note)
+{
+ if (note->descsz == sizeof (pstatus_t)
+#if defined (HAVE_PXSTATUS_T)
+ || note->descsz == sizeof (pxstatus_t)
+#endif
+ )
+ {
+ pstatus_t pstat;
+
+ memcpy (&pstat, note->descdata, sizeof (pstat));
+
+ elf_tdata (abfd)->core->pid = pstat.pr_pid;
+ }
+#if defined (HAVE_PSTATUS32_T)
+ else if (note->descsz == sizeof (pstatus32_t))
+ {
+ /* 64-bit host, 32-bit corefile */
+ pstatus32_t pstat;
+
+ memcpy (&pstat, note->descdata, sizeof (pstat));
+
+ elf_tdata (abfd)->core->pid = pstat.pr_pid;
+ }
+#endif
+ /* 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 bfd_boolean
+elfcore_grok_lwpstatus (bfd *abfd, Elf_Internal_Note *note)
+{
+ lwpstatus_t lwpstat;
+ char buf[100];
+ char *name;
+ size_t len;
+ asection *sect;
+
+ if (note->descsz != sizeof (lwpstat)
+#if defined (HAVE_LWPXSTATUS_T)
+ && note->descsz != sizeof (lwpxstatus_t)
+#endif
+ )
+ return TRUE;
+
+ memcpy (&lwpstat, note->descdata, sizeof (lwpstat));
+
+ elf_tdata (abfd)->core->lwpid = lwpstat.pr_lwpid;
+ /* Do not overwrite the core signal if it has already been set by
+ another thread. */
+ if (elf_tdata (abfd)->core->signal == 0)
+ elf_tdata (abfd)->core->signal = lwpstat.pr_cursig;
+
+ /* Make a ".reg/999" section. */
+
+ sprintf (buf, ".reg/%d", elfcore_make_pid (abfd));
+ len = strlen (buf) + 1;
+ name = bfd_alloc (abfd, len);
+ if (name == NULL)
+ return FALSE;
+ memcpy (name, buf, len);
+
+ sect = bfd_make_section_anyway_with_flags (abfd, name, SEC_HAS_CONTENTS);
+ if (sect == NULL)
+ return FALSE;
+
+#if defined (HAVE_LWPSTATUS_T_PR_CONTEXT)
+ sect->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->size = sizeof (lwpstat.pr_reg);
+ sect->filepos = note->descpos + offsetof (lwpstatus_t, pr_reg);
+#endif
+
+ 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));
+ len = strlen (buf) + 1;
+ name = bfd_alloc (abfd, len);
+ if (name == NULL)
+ return FALSE;
+ memcpy (name, buf, len);
+
+ sect = bfd_make_section_anyway_with_flags (abfd, name, SEC_HAS_CONTENTS);
+ if (sect == NULL)
+ return FALSE;
+
+#if defined (HAVE_LWPSTATUS_T_PR_CONTEXT)
+ sect->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->size = sizeof (lwpstat.pr_fpreg);
+ sect->filepos = note->descpos + offsetof (lwpstatus_t, pr_fpreg);
+#endif
+
+ sect->alignment_power = 2;
+
+ return elfcore_maybe_make_sect (abfd, ".reg2", sect);
+}
+#endif /* defined (HAVE_LWPSTATUS_T) */
+
+static bfd_boolean
+elfcore_grok_win32pstatus (bfd *abfd, Elf_Internal_Note *note)
+{
+ char buf[30];
+ char *name;
+ size_t len;
+ asection *sect;
+ int type;
+ int is_active_thread;
+ bfd_vma base_addr;
+
+ if (note->descsz < 728)
+ return TRUE;
+
+ if (! CONST_STRNEQ (note->namedata, "win32"))
+ return TRUE;
+
+ type = bfd_get_32 (abfd, note->descdata);
+
+ switch (type)
+ {
+ case 1 /* NOTE_INFO_PROCESS */:
+ /* FIXME: need to add ->core->command. */
+ /* process_info.pid */
+ elf_tdata (abfd)->core->pid = bfd_get_32 (abfd, note->descdata + 8);
+ /* process_info.signal */
+ elf_tdata (abfd)->core->signal = bfd_get_32 (abfd, note->descdata + 12);
+ break;
+
+ case 2 /* NOTE_INFO_THREAD */:
+ /* Make a ".reg/999" section. */
+ /* thread_info.tid */
+ sprintf (buf, ".reg/%ld", (long) bfd_get_32 (abfd, note->descdata + 8));
+
+ len = strlen (buf) + 1;
+ name = (char *) bfd_alloc (abfd, len);
+ if (name == NULL)
+ return FALSE;
+
+ memcpy (name, buf, len);
+
+ sect = bfd_make_section_anyway_with_flags (abfd, name, SEC_HAS_CONTENTS);
+ if (sect == NULL)
+ return FALSE;
+
+ /* sizeof (thread_info.thread_context) */
+ sect->size = 716;
+ /* offsetof (thread_info.thread_context) */
+ sect->filepos = note->descpos + 12;
+ sect->alignment_power = 2;
+
+ /* thread_info.is_active_thread */
+ is_active_thread = bfd_get_32 (abfd, note->descdata + 8);
+
+ if (is_active_thread)
+ if (! elfcore_maybe_make_sect (abfd, ".reg", sect))
+ return FALSE;
+ break;
+
+ case 3 /* NOTE_INFO_MODULE */:
+ /* Make a ".module/xxxxxxxx" section. */
+ /* module_info.base_address */
+ base_addr = bfd_get_32 (abfd, note->descdata + 4);
+ sprintf (buf, ".module/%08lx", (unsigned long) base_addr);
+
+ len = strlen (buf) + 1;
+ name = (char *) bfd_alloc (abfd, len);
+ if (name == NULL)
+ return FALSE;
+
+ memcpy (name, buf, len);
+
+ sect = bfd_make_section_anyway_with_flags (abfd, name, SEC_HAS_CONTENTS);
+
+ if (sect == NULL)
+ return FALSE;
+
+ sect->size = note->descsz;
+ sect->filepos = note->descpos;
+ sect->alignment_power = 2;
+ break;
+
+ default:
+ return TRUE;
+ }
+
+ return TRUE;
+}
+
+static bfd_boolean
+elfcore_grok_note (bfd *abfd, Elf_Internal_Note *note)
+{
+ const struct elf_backend_data *bed = get_elf_backend_data (abfd);
+
+ switch (note->type)
+ {
+ default:
+ return TRUE;
+
+ case NT_PRSTATUS:
+ if (bed->elf_backend_grok_prstatus)
+ if ((*bed->elf_backend_grok_prstatus) (abfd, note))
+ return TRUE;
+#if defined (HAVE_PRSTATUS_T)
+ return elfcore_grok_prstatus (abfd, note);
+#else
+ return TRUE;
+#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);
+
+ case NT_WIN32PSTATUS:
+ return elfcore_grok_win32pstatus (abfd, note);
+
+ case NT_PRXFPREG: /* Linux SSE extension */
+ if (note->namesz == 6
+ && strcmp (note->namedata, "LINUX") == 0)
+ return elfcore_grok_prxfpreg (abfd, note);
+ else
+ return TRUE;
+
+ case NT_X86_XSTATE: /* Linux XSAVE extension */
+ if (note->namesz == 6
+ && strcmp (note->namedata, "LINUX") == 0)
+ return elfcore_grok_xstatereg (abfd, note);
+ else
+ return TRUE;
+
+ case NT_PPC_VMX:
+ if (note->namesz == 6
+ && strcmp (note->namedata, "LINUX") == 0)
+ return elfcore_grok_ppc_vmx (abfd, note);
+ else
+ return TRUE;
+
+ case NT_PPC_VSX:
+ if (note->namesz == 6
+ && strcmp (note->namedata, "LINUX") == 0)
+ return elfcore_grok_ppc_vsx (abfd, note);
+ else
+ return TRUE;
+
+ case NT_S390_HIGH_GPRS:
+ if (note->namesz == 6
+ && strcmp (note->namedata, "LINUX") == 0)
+ return elfcore_grok_s390_high_gprs (abfd, note);
+ else
+ return TRUE;
+
+ case NT_S390_TIMER:
+ if (note->namesz == 6
+ && strcmp (note->namedata, "LINUX") == 0)
+ return elfcore_grok_s390_timer (abfd, note);
+ else
+ return TRUE;
+
+ case NT_S390_TODCMP:
+ if (note->namesz == 6
+ && strcmp (note->namedata, "LINUX") == 0)
+ return elfcore_grok_s390_todcmp (abfd, note);
+ else
+ return TRUE;
+
+ case NT_S390_TODPREG:
+ if (note->namesz == 6
+ && strcmp (note->namedata, "LINUX") == 0)
+ return elfcore_grok_s390_todpreg (abfd, note);
+ else
+ return TRUE;
+
+ case NT_S390_CTRS:
+ if (note->namesz == 6
+ && strcmp (note->namedata, "LINUX") == 0)
+ return elfcore_grok_s390_ctrs (abfd, note);
+ else
+ return TRUE;
+
+ case NT_S390_PREFIX:
+ if (note->namesz == 6
+ && strcmp (note->namedata, "LINUX") == 0)
+ return elfcore_grok_s390_prefix (abfd, note);
+ else
+ return TRUE;
+
+ case NT_S390_LAST_BREAK:
+ if (note->namesz == 6
+ && strcmp (note->namedata, "LINUX") == 0)
+ return elfcore_grok_s390_last_break (abfd, note);
+ else
+ return TRUE;
+
+ case NT_S390_SYSTEM_CALL:
+ if (note->namesz == 6
+ && strcmp (note->namedata, "LINUX") == 0)
+ return elfcore_grok_s390_system_call (abfd, note);
+ else
+ return TRUE;
+
+ case NT_S390_TDB:
+ if (note->namesz == 6
+ && strcmp (note->namedata, "LINUX") == 0)
+ return elfcore_grok_s390_tdb (abfd, note);
+ else
+ return TRUE;
+
+ case NT_ARM_VFP:
+ if (note->namesz == 6
+ && strcmp (note->namedata, "LINUX") == 0)
+ return elfcore_grok_arm_vfp (abfd, note);
+ else
+ return TRUE;
+
+ case NT_ARM_TLS:
+ if (note->namesz == 6
+ && strcmp (note->namedata, "LINUX") == 0)
+ return elfcore_grok_aarch_tls (abfd, note);
+ else
+ return TRUE;
+
+ case NT_ARM_HW_BREAK:
+ if (note->namesz == 6
+ && strcmp (note->namedata, "LINUX") == 0)
+ return elfcore_grok_aarch_hw_break (abfd, note);
+ else
+ return TRUE;
+
+ case NT_ARM_HW_WATCH:
+ if (note->namesz == 6
+ && strcmp (note->namedata, "LINUX") == 0)
+ return elfcore_grok_aarch_hw_watch (abfd, note);
+ else
+ return TRUE;
+
+ case NT_PRPSINFO:
+ case NT_PSINFO:
+ if (bed->elf_backend_grok_psinfo)
+ if ((*bed->elf_backend_grok_psinfo) (abfd, note))
+ return TRUE;
+#if defined (HAVE_PRPSINFO_T) || defined (HAVE_PSINFO_T)
+ return elfcore_grok_psinfo (abfd, note);
+#else
+ return TRUE;
+#endif
+
+ case NT_AUXV:
+ {
+ asection *sect = bfd_make_section_anyway_with_flags (abfd, ".auxv",
+ SEC_HAS_CONTENTS);
+
+ if (sect == NULL)
+ return FALSE;
+ sect->size = note->descsz;
+ sect->filepos = note->descpos;
+ sect->alignment_power = 1 + bfd_get_arch_size (abfd) / 32;
+
+ return TRUE;
+ }
+
+ case NT_FILE:
+ return elfcore_make_note_pseudosection (abfd, ".note.linuxcore.file",
+ note);
+
+ case NT_SIGINFO:
+ return elfcore_make_note_pseudosection (abfd, ".note.linuxcore.siginfo",
+ note);
+ }
+}
+
+static bfd_boolean
+elfobj_grok_gnu_build_id (bfd *abfd, Elf_Internal_Note *note)
+{
+ struct elf_obj_tdata *t;
+
+ if (note->descsz == 0)
+ return FALSE;
+
+ t = elf_tdata (abfd);
+ t->build_id = bfd_alloc (abfd, sizeof (*t->build_id) - 1 + note->descsz);
+ if (t->build_id == NULL)
+ return FALSE;
+
+ t->build_id->size = note->descsz;
+ memcpy (t->build_id->data, note->descdata, note->descsz);
+
+ return TRUE;
+}
+
+static bfd_boolean
+elfobj_grok_gnu_note (bfd *abfd, Elf_Internal_Note *note)
+{
+ switch (note->type)
+ {
+ default:
+ return TRUE;
+
+ case NT_GNU_BUILD_ID:
+ return elfobj_grok_gnu_build_id (abfd, note);
+ }
+}
+
+static bfd_boolean
+elfobj_grok_stapsdt_note_1 (bfd *abfd, Elf_Internal_Note *note)
+{
+ struct sdt_note *cur =
+ (struct sdt_note *) bfd_alloc (abfd, sizeof (struct sdt_note)
+ + note->descsz);
+
+ cur->next = (struct sdt_note *) (elf_tdata (abfd))->sdt_note_head;
+ cur->size = (bfd_size_type) note->descsz;
+ memcpy (cur->data, note->descdata, note->descsz);
+
+ elf_tdata (abfd)->sdt_note_head = cur;
+
+ return TRUE;
+}
+
+static bfd_boolean
+elfobj_grok_stapsdt_note (bfd *abfd, Elf_Internal_Note *note)
+{
+ switch (note->type)
+ {
+ case NT_STAPSDT:
+ return elfobj_grok_stapsdt_note_1 (abfd, note);
+
+ default:
+ return TRUE;
+ }
+}
+
+static bfd_boolean
+elfcore_netbsd_get_lwpid (Elf_Internal_Note *note, int *lwpidp)
+{
+ char *cp;
+
+ cp = strchr (note->namedata, '@');
+ if (cp != NULL)
+ {
+ *lwpidp = atoi(cp + 1);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static bfd_boolean
+elfcore_grok_netbsd_procinfo (bfd *abfd, Elf_Internal_Note *note)
+{
+ /* Signal number at offset 0x08. */
+ elf_tdata (abfd)->core->signal
+ = bfd_h_get_32 (abfd, (bfd_byte *) note->descdata + 0x08);
+
+ /* Process ID at offset 0x50. */
+ elf_tdata (abfd)->core->pid
+ = bfd_h_get_32 (abfd, (bfd_byte *) note->descdata + 0x50);
+
+ /* Command name at 0x7c (max 32 bytes, including nul). */
+ elf_tdata (abfd)->core->command
+ = _bfd_elfcore_strndup (abfd, note->descdata + 0x7c, 31);
+
+ return elfcore_make_note_pseudosection (abfd, ".note.netbsdcore.procinfo",
+ note);
+}
+
+static bfd_boolean
+elfcore_grok_netbsd_note (bfd *abfd, Elf_Internal_Note *note)
+{
+ int lwp;
+
+ if (elfcore_netbsd_get_lwpid (note, &lwp))
+ elf_tdata (abfd)->core->lwpid = lwp;
+
+ if (note->type == NT_NETBSDCORE_PROCINFO)
+ {
+ /* NetBSD-specific core "procinfo". Note that we expect to
+ find this note before any of the others, which is fine,
+ since the kernel writes this note out first when it
+ creates a core file. */
+
+ return elfcore_grok_netbsd_procinfo (abfd, note);
+ }
+
+ /* As of Jan 2002 there are no other machine-independent notes
+ defined for NetBSD core files. If the note type is less
+ than the start of the machine-dependent note types, we don't
+ understand it. */
+
+ if (note->type < NT_NETBSDCORE_FIRSTMACH)
+ return TRUE;
+
+
+ switch (bfd_get_arch (abfd))
+ {
+ /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0 and
+ PT_GETFPREGS == mach+2. */
+
+ case bfd_arch_alpha:
+ case bfd_arch_sparc:
+ switch (note->type)
+ {
+ case NT_NETBSDCORE_FIRSTMACH+0:
+ return elfcore_make_note_pseudosection (abfd, ".reg", note);
+
+ case NT_NETBSDCORE_FIRSTMACH+2:
+ return elfcore_make_note_pseudosection (abfd, ".reg2", note);
+
+ default:
+ return TRUE;
+ }
+
+ /* On all other arch's, PT_GETREGS == mach+1 and
+ PT_GETFPREGS == mach+3. */
+
+ default:
+ switch (note->type)
+ {
+ case NT_NETBSDCORE_FIRSTMACH+1:
+ return elfcore_make_note_pseudosection (abfd, ".reg", note);
+
+ case NT_NETBSDCORE_FIRSTMACH+3:
+ return elfcore_make_note_pseudosection (abfd, ".reg2", note);
+
+ default:
+ return TRUE;
+ }
+ }
+ /* NOTREACHED */
+}
+
+static bfd_boolean
+elfcore_grok_openbsd_procinfo (bfd *abfd, Elf_Internal_Note *note)
+{
+ /* Signal number at offset 0x08. */
+ elf_tdata (abfd)->core->signal
+ = bfd_h_get_32 (abfd, (bfd_byte *) note->descdata + 0x08);
+
+ /* Process ID at offset 0x20. */
+ elf_tdata (abfd)->core->pid
+ = bfd_h_get_32 (abfd, (bfd_byte *) note->descdata + 0x20);
+
+ /* Command name at 0x48 (max 32 bytes, including nul). */
+ elf_tdata (abfd)->core->command
+ = _bfd_elfcore_strndup (abfd, note->descdata + 0x48, 31);
+
+ return TRUE;
+}
+
+static bfd_boolean
+elfcore_grok_openbsd_note (bfd *abfd, Elf_Internal_Note *note)
+{
+ if (note->type == NT_OPENBSD_PROCINFO)
+ return elfcore_grok_openbsd_procinfo (abfd, note);
+
+ if (note->type == NT_OPENBSD_REGS)
+ return elfcore_make_note_pseudosection (abfd, ".reg", note);
+
+ if (note->type == NT_OPENBSD_FPREGS)
+ return elfcore_make_note_pseudosection (abfd, ".reg2", note);
+
+ if (note->type == NT_OPENBSD_XFPREGS)
+ return elfcore_make_note_pseudosection (abfd, ".reg-xfp", note);
+
+ if (note->type == NT_OPENBSD_AUXV)
+ {
+ asection *sect = bfd_make_section_anyway_with_flags (abfd, ".auxv",
+ SEC_HAS_CONTENTS);
+
+ if (sect == NULL)
+ return FALSE;
+ sect->size = note->descsz;
+ sect->filepos = note->descpos;
+ sect->alignment_power = 1 + bfd_get_arch_size (abfd) / 32;
+
+ return TRUE;
+ }
+
+ if (note->type == NT_OPENBSD_WCOOKIE)
+ {
+ asection *sect = bfd_make_section_anyway_with_flags (abfd, ".wcookie",
+ SEC_HAS_CONTENTS);
+
+ if (sect == NULL)
+ return FALSE;
+ sect->size = note->descsz;
+ sect->filepos = note->descpos;
+ sect->alignment_power = 1 + bfd_get_arch_size (abfd) / 32;
+
+ return TRUE;
+ }
+
+ return TRUE;
+}
+
+static bfd_boolean
+elfcore_grok_nto_status (bfd *abfd, Elf_Internal_Note *note, long *tid)
+{
+ void *ddata = note->descdata;
+ char buf[100];
+ char *name;
+ asection *sect;
+ short sig;
+ unsigned flags;
+
+ /* nto_procfs_status 'pid' field is at offset 0. */
+ elf_tdata (abfd)->core->pid = bfd_get_32 (abfd, (bfd_byte *) ddata);
+
+ /* nto_procfs_status 'tid' field is at offset 4. Pass it back. */
+ *tid = bfd_get_32 (abfd, (bfd_byte *) ddata + 4);
+
+ /* nto_procfs_status 'flags' field is at offset 8. */
+ flags = bfd_get_32 (abfd, (bfd_byte *) ddata + 8);
+
+ /* nto_procfs_status 'what' field is at offset 14. */
+ if ((sig = bfd_get_16 (abfd, (bfd_byte *) ddata + 14)) > 0)
+ {
+ elf_tdata (abfd)->core->signal = sig;
+ elf_tdata (abfd)->core->lwpid = *tid;
+ }
+
+ /* _DEBUG_FLAG_CURTID (current thread) is 0x80. Some cores
+ do not come from signals so we make sure we set the current
+ thread just in case. */
+ if (flags & 0x00000080)
+ elf_tdata (abfd)->core->lwpid = *tid;
+
+ /* Make a ".qnx_core_status/%d" section. */
+ sprintf (buf, ".qnx_core_status/%ld", *tid);
+
+ name = (char *) bfd_alloc (abfd, strlen (buf) + 1);
+ if (name == NULL)
+ return FALSE;
+ strcpy (name, buf);
+
+ sect = bfd_make_section_anyway_with_flags (abfd, name, SEC_HAS_CONTENTS);
+ if (sect == NULL)
+ return FALSE;
+
+ sect->size = note->descsz;
+ sect->filepos = note->descpos;
+ sect->alignment_power = 2;
+
+ return (elfcore_maybe_make_sect (abfd, ".qnx_core_status", sect));
+}
+
+static bfd_boolean
+elfcore_grok_nto_regs (bfd *abfd,
+ Elf_Internal_Note *note,
+ long tid,
+ char *base)
+{
+ char buf[100];
+ char *name;
+ asection *sect;
+
+ /* Make a "(base)/%d" section. */
+ sprintf (buf, "%s/%ld", base, tid);
+
+ name = (char *) bfd_alloc (abfd, strlen (buf) + 1);
+ if (name == NULL)
+ return FALSE;
+ strcpy (name, buf);
+
+ sect = bfd_make_section_anyway_with_flags (abfd, name, SEC_HAS_CONTENTS);
+ if (sect == NULL)
+ return FALSE;
+
+ sect->size = note->descsz;
+ sect->filepos = note->descpos;
+ sect->alignment_power = 2;
+
+ /* This is the current thread. */
+ if (elf_tdata (abfd)->core->lwpid == tid)
+ return elfcore_maybe_make_sect (abfd, base, sect);
+
+ return TRUE;
+}
+
+#define BFD_QNT_CORE_INFO 7
+#define BFD_QNT_CORE_STATUS 8
+#define BFD_QNT_CORE_GREG 9
+#define BFD_QNT_CORE_FPREG 10
+
+static bfd_boolean
+elfcore_grok_nto_note (bfd *abfd, Elf_Internal_Note *note)
+{
+ /* Every GREG section has a STATUS section before it. Store the
+ tid from the previous call to pass down to the next gregs
+ function. */
+ static long tid = 1;
+
+ switch (note->type)
+ {
+ case BFD_QNT_CORE_INFO:
+ return elfcore_make_note_pseudosection (abfd, ".qnx_core_info", note);
+ case BFD_QNT_CORE_STATUS:
+ return elfcore_grok_nto_status (abfd, note, &tid);
+ case BFD_QNT_CORE_GREG:
+ return elfcore_grok_nto_regs (abfd, note, tid, ".reg");
+ case BFD_QNT_CORE_FPREG:
+ return elfcore_grok_nto_regs (abfd, note, tid, ".reg2");
+ default:
+ return TRUE;
+ }
+}
+
+static bfd_boolean
+elfcore_grok_spu_note (bfd *abfd, Elf_Internal_Note *note)
+{
+ char *name;
+ asection *sect;
+ size_t len;
+
+ /* Use note name as section name. */
+ len = note->namesz;
+ name = (char *) bfd_alloc (abfd, len);
+ if (name == NULL)
+ return FALSE;
+ memcpy (name, note->namedata, len);
+ name[len - 1] = '\0';
+
+ sect = bfd_make_section_anyway_with_flags (abfd, name, SEC_HAS_CONTENTS);
+ if (sect == NULL)
+ return FALSE;
+
+ sect->size = note->descsz;
+ sect->filepos = note->descpos;
+ sect->alignment_power = 1;
+
+ return TRUE;
+}
+
+/* Function: elfcore_write_note
+
+ Inputs:
+ buffer to hold note, and current size of buffer
+ name of note
+ type of note
+ data for note
+ size of data for note
+
+ Writes note to end of buffer. ELF64 notes are written exactly as
+ for ELF32, despite the current (as of 2006) ELF gabi specifying
+ that they ought to have 8-byte namesz and descsz field, and have
+ 8-byte alignment. Other writers, eg. Linux kernel, do the same.
+
+ Return:
+ Pointer to realloc'd buffer, *BUFSIZ updated. */
+
+char *
+elfcore_write_note (bfd *abfd,
+ char *buf,
+ int *bufsiz,
+ const char *name,
+ int type,
+ const void *input,
+ int size)
+{
+ Elf_External_Note *xnp;
+ size_t namesz;
+ size_t newspace;
+ char *dest;
+
+ namesz = 0;
+ if (name != NULL)
+ namesz = strlen (name) + 1;
+
+ newspace = 12 + ((namesz + 3) & -4) + ((size + 3) & -4);
+
+ buf = (char *) realloc (buf, *bufsiz + newspace);
+ if (buf == NULL)
+ return buf;
+ dest = buf + *bufsiz;
+ *bufsiz += newspace;
+ xnp = (Elf_External_Note *) dest;
+ H_PUT_32 (abfd, namesz, xnp->namesz);
+ H_PUT_32 (abfd, size, xnp->descsz);
+ H_PUT_32 (abfd, type, xnp->type);
+ dest = xnp->name;
+ if (name != NULL)
+ {
+ memcpy (dest, name, namesz);
+ dest += namesz;
+ while (namesz & 3)
+ {
+ *dest++ = '\0';
+ ++namesz;
+ }
+ }
+ memcpy (dest, input, size);
+ dest += size;
+ while (size & 3)
+ {
+ *dest++ = '\0';
+ ++size;
+ }
+ return buf;
+}
+
+char *
+elfcore_write_prpsinfo (bfd *abfd,
+ char *buf,
+ int *bufsiz,
+ const char *fname,
+ const char *psargs)
+{
+ const struct elf_backend_data *bed = get_elf_backend_data (abfd);
+
+ if (bed->elf_backend_write_core_note != NULL)
+ {
+ char *ret;
+ ret = (*bed->elf_backend_write_core_note) (abfd, buf, bufsiz,
+ NT_PRPSINFO, fname, psargs);
+ if (ret != NULL)
+ return ret;
+ }
+
+#if defined (HAVE_PRPSINFO_T) || defined (HAVE_PSINFO_T)
+#if defined (HAVE_PRPSINFO32_T) || defined (HAVE_PSINFO32_T)
+ if (bed->s->elfclass == ELFCLASS32)
+ {
+#if defined (HAVE_PSINFO32_T)
+ psinfo32_t data;
+ int note_type = NT_PSINFO;
+#else
+ prpsinfo32_t data;
+ int note_type = NT_PRPSINFO;
+#endif
+
+ memset (&data, 0, sizeof (data));
+ strncpy (data.pr_fname, fname, sizeof (data.pr_fname));
+ strncpy (data.pr_psargs, psargs, sizeof (data.pr_psargs));
+ return elfcore_write_note (abfd, buf, bufsiz,
+ "CORE", note_type, &data, sizeof (data));
+ }
+ else
+#endif
+ {
+#if defined (HAVE_PSINFO_T)
+ psinfo_t data;
+ int note_type = NT_PSINFO;
+#else
+ prpsinfo_t data;
+ int note_type = NT_PRPSINFO;
+#endif
+
+ memset (&data, 0, sizeof (data));
+ strncpy (data.pr_fname, fname, sizeof (data.pr_fname));
+ strncpy (data.pr_psargs, psargs, sizeof (data.pr_psargs));
+ return elfcore_write_note (abfd, buf, bufsiz,
+ "CORE", note_type, &data, sizeof (data));
+ }
+#endif /* PSINFO_T or PRPSINFO_T */
+
+ free (buf);
+ return NULL;
+}
+
+char *
+elfcore_write_linux_prpsinfo32
+ (bfd *abfd, char *buf, int *bufsiz,
+ const struct elf_internal_linux_prpsinfo *prpsinfo)
+{
+ struct elf_external_linux_prpsinfo32 data;
+
+ memset (&data, 0, sizeof (data));
+ LINUX_PRPSINFO32_SWAP_FIELDS (abfd, prpsinfo, data);
+
+ return elfcore_write_note (abfd, buf, bufsiz, "CORE", NT_PRPSINFO,
+ &data, sizeof (data));
+}
+
+char *
+elfcore_write_linux_prpsinfo64
+ (bfd *abfd, char *buf, int *bufsiz,
+ const struct elf_internal_linux_prpsinfo *prpsinfo)
+{
+ struct elf_external_linux_prpsinfo64 data;
+
+ memset (&data, 0, sizeof (data));
+ LINUX_PRPSINFO64_SWAP_FIELDS (abfd, prpsinfo, data);
+
+ return elfcore_write_note (abfd, buf, bufsiz,
+ "CORE", NT_PRPSINFO, &data, sizeof (data));
+}
+
+char *
+elfcore_write_prstatus (bfd *abfd,
+ char *buf,
+ int *bufsiz,
+ long pid,
+ int cursig,
+ const void *gregs)
+{
+ const struct elf_backend_data *bed = get_elf_backend_data (abfd);
+
+ if (bed->elf_backend_write_core_note != NULL)
+ {
+ char *ret;
+ ret = (*bed->elf_backend_write_core_note) (abfd, buf, bufsiz,
+ NT_PRSTATUS,
+ pid, cursig, gregs);
+ if (ret != NULL)
+ return ret;
+ }
+
+#if defined (HAVE_PRSTATUS_T)
+#if defined (HAVE_PRSTATUS32_T)
+ if (bed->s->elfclass == ELFCLASS32)
+ {
+ prstatus32_t prstat;
+
+ memset (&prstat, 0, sizeof (prstat));
+ prstat.pr_pid = pid;
+ prstat.pr_cursig = cursig;
+ memcpy (&prstat.pr_reg, gregs, sizeof (prstat.pr_reg));
+ return elfcore_write_note (abfd, buf, bufsiz, "CORE",
+ NT_PRSTATUS, &prstat, sizeof (prstat));
+ }
+ else
+#endif
+ {
+ prstatus_t prstat;
+
+ memset (&prstat, 0, sizeof (prstat));
+ prstat.pr_pid = pid;
+ prstat.pr_cursig = cursig;
+ memcpy (&prstat.pr_reg, gregs, sizeof (prstat.pr_reg));
+ return elfcore_write_note (abfd, buf, bufsiz, "CORE",
+ NT_PRSTATUS, &prstat, sizeof (prstat));
+ }
+#endif /* HAVE_PRSTATUS_T */
+
+ free (buf);
+ return NULL;
+}
+
+#if defined (HAVE_LWPSTATUS_T)
+char *
+elfcore_write_lwpstatus (bfd *abfd,
+ char *buf,
+ int *bufsiz,
+ long pid,
+ int cursig,
+ const void *gregs)
+{
+ lwpstatus_t lwpstat;
+ const char *note_name = "CORE";
+
+ memset (&lwpstat, 0, sizeof (lwpstat));
+ lwpstat.pr_lwpid = pid >> 16;
+ lwpstat.pr_cursig = cursig;
+#if defined (HAVE_LWPSTATUS_T_PR_REG)
+ memcpy (&lwpstat.pr_reg, gregs, sizeof (lwpstat.pr_reg));
+#elif defined (HAVE_LWPSTATUS_T_PR_CONTEXT)
+#if !defined(gregs)
+ memcpy (lwpstat.pr_context.uc_mcontext.gregs,
+ gregs, sizeof (lwpstat.pr_context.uc_mcontext.gregs));
+#else
+ memcpy (lwpstat.pr_context.uc_mcontext.__gregs,
+ gregs, sizeof (lwpstat.pr_context.uc_mcontext.__gregs));
+#endif
+#endif
+ return elfcore_write_note (abfd, buf, bufsiz, note_name,
+ NT_LWPSTATUS, &lwpstat, sizeof (lwpstat));
+}
+#endif /* HAVE_LWPSTATUS_T */
+
+#if defined (HAVE_PSTATUS_T)
+char *
+elfcore_write_pstatus (bfd *abfd,
+ char *buf,
+ int *bufsiz,
+ long pid,
+ int cursig ATTRIBUTE_UNUSED,
+ const void *gregs ATTRIBUTE_UNUSED)
+{
+ const char *note_name = "CORE";
+#if defined (HAVE_PSTATUS32_T)
+ const struct elf_backend_data *bed = get_elf_backend_data (abfd);
+
+ if (bed->s->elfclass == ELFCLASS32)
+ {
+ pstatus32_t pstat;
+
+ memset (&pstat, 0, sizeof (pstat));
+ pstat.pr_pid = pid & 0xffff;
+ buf = elfcore_write_note (abfd, buf, bufsiz, note_name,
+ NT_PSTATUS, &pstat, sizeof (pstat));
+ return buf;
+ }
+ else
+#endif
+ {
+ pstatus_t pstat;
+
+ memset (&pstat, 0, sizeof (pstat));
+ pstat.pr_pid = pid & 0xffff;
+ buf = elfcore_write_note (abfd, buf, bufsiz, note_name,
+ NT_PSTATUS, &pstat, sizeof (pstat));
+ return buf;
+ }
+}
+#endif /* HAVE_PSTATUS_T */
+
+char *
+elfcore_write_prfpreg (bfd *abfd,
+ char *buf,
+ int *bufsiz,
+ const void *fpregs,
+ int size)
+{
+ const char *note_name = "CORE";
+ return elfcore_write_note (abfd, buf, bufsiz,
+ note_name, NT_FPREGSET, fpregs, size);
+}
+
+char *
+elfcore_write_prxfpreg (bfd *abfd,
+ char *buf,
+ int *bufsiz,
+ const void *xfpregs,
+ int size)
+{
+ char *note_name = "LINUX";
+ return elfcore_write_note (abfd, buf, bufsiz,
+ note_name, NT_PRXFPREG, xfpregs, size);
+}
+
+char *
+elfcore_write_xstatereg (bfd *abfd, char *buf, int *bufsiz,
+ const void *xfpregs, int size)
+{
+ char *note_name = "LINUX";
+ return elfcore_write_note (abfd, buf, bufsiz,
+ note_name, NT_X86_XSTATE, xfpregs, size);
+}
+
+char *
+elfcore_write_ppc_vmx (bfd *abfd,
+ char *buf,
+ int *bufsiz,
+ const void *ppc_vmx,
+ int size)
+{
+ char *note_name = "LINUX";
+ return elfcore_write_note (abfd, buf, bufsiz,
+ note_name, NT_PPC_VMX, ppc_vmx, size);
+}
+
+char *
+elfcore_write_ppc_vsx (bfd *abfd,
+ char *buf,
+ int *bufsiz,
+ const void *ppc_vsx,
+ int size)
+{
+ char *note_name = "LINUX";
+ return elfcore_write_note (abfd, buf, bufsiz,
+ note_name, NT_PPC_VSX, ppc_vsx, size);
+}
+
+static char *
+elfcore_write_s390_high_gprs (bfd *abfd,
+ char *buf,
+ int *bufsiz,
+ const void *s390_high_gprs,
+ int size)
+{
+ char *note_name = "LINUX";
+ return elfcore_write_note (abfd, buf, bufsiz,
+ note_name, NT_S390_HIGH_GPRS,
+ s390_high_gprs, size);
+}
+
+char *
+elfcore_write_s390_timer (bfd *abfd,
+ char *buf,
+ int *bufsiz,
+ const void *s390_timer,
+ int size)
+{
+ char *note_name = "LINUX";
+ return elfcore_write_note (abfd, buf, bufsiz,
+ note_name, NT_S390_TIMER, s390_timer, size);
+}
+
+char *
+elfcore_write_s390_todcmp (bfd *abfd,
+ char *buf,
+ int *bufsiz,
+ const void *s390_todcmp,
+ int size)
+{
+ char *note_name = "LINUX";
+ return elfcore_write_note (abfd, buf, bufsiz,
+ note_name, NT_S390_TODCMP, s390_todcmp, size);
+}
+
+char *
+elfcore_write_s390_todpreg (bfd *abfd,
+ char *buf,
+ int *bufsiz,
+ const void *s390_todpreg,
+ int size)
+{
+ char *note_name = "LINUX";
+ return elfcore_write_note (abfd, buf, bufsiz,
+ note_name, NT_S390_TODPREG, s390_todpreg, size);
+}
+
+char *
+elfcore_write_s390_ctrs (bfd *abfd,
+ char *buf,
+ int *bufsiz,
+ const void *s390_ctrs,
+ int size)
+{
+ char *note_name = "LINUX";
+ return elfcore_write_note (abfd, buf, bufsiz,
+ note_name, NT_S390_CTRS, s390_ctrs, size);
+}
+
+char *
+elfcore_write_s390_prefix (bfd *abfd,
+ char *buf,
+ int *bufsiz,
+ const void *s390_prefix,
+ int size)
+{
+ char *note_name = "LINUX";
+ return elfcore_write_note (abfd, buf, bufsiz,
+ note_name, NT_S390_PREFIX, s390_prefix, size);
+}
+
+char *
+elfcore_write_s390_last_break (bfd *abfd,
+ char *buf,
+ int *bufsiz,
+ const void *s390_last_break,
+ int size)
+{
+ char *note_name = "LINUX";
+ return elfcore_write_note (abfd, buf, bufsiz,
+ note_name, NT_S390_LAST_BREAK,
+ s390_last_break, size);
+}
+
+char *
+elfcore_write_s390_system_call (bfd *abfd,
+ char *buf,
+ int *bufsiz,
+ const void *s390_system_call,
+ int size)
+{
+ char *note_name = "LINUX";
+ return elfcore_write_note (abfd, buf, bufsiz,
+ note_name, NT_S390_SYSTEM_CALL,
+ s390_system_call, size);
+}
+
+char *
+elfcore_write_s390_tdb (bfd *abfd,
+ char *buf,
+ int *bufsiz,
+ const void *s390_tdb,
+ int size)
+{
+ char *note_name = "LINUX";
+ return elfcore_write_note (abfd, buf, bufsiz,
+ note_name, NT_S390_TDB, s390_tdb, size);
+}
+
+char *
+elfcore_write_arm_vfp (bfd *abfd,
+ char *buf,
+ int *bufsiz,
+ const void *arm_vfp,
+ int size)
+{
+ char *note_name = "LINUX";
+ return elfcore_write_note (abfd, buf, bufsiz,
+ note_name, NT_ARM_VFP, arm_vfp, size);
+}
+
+char *
+elfcore_write_aarch_tls (bfd *abfd,
+ char *buf,
+ int *bufsiz,
+ const void *aarch_tls,
+ int size)
+{
+ char *note_name = "LINUX";
+ return elfcore_write_note (abfd, buf, bufsiz,
+ note_name, NT_ARM_TLS, aarch_tls, size);
+}
+
+char *
+elfcore_write_aarch_hw_break (bfd *abfd,
+ char *buf,
+ int *bufsiz,
+ const void *aarch_hw_break,
+ int size)
+{
+ char *note_name = "LINUX";
+ return elfcore_write_note (abfd, buf, bufsiz,
+ note_name, NT_ARM_HW_BREAK, aarch_hw_break, size);
+}
+
+char *
+elfcore_write_aarch_hw_watch (bfd *abfd,
+ char *buf,
+ int *bufsiz,
+ const void *aarch_hw_watch,
+ int size)
+{
+ char *note_name = "LINUX";
+ return elfcore_write_note (abfd, buf, bufsiz,
+ note_name, NT_ARM_HW_WATCH, aarch_hw_watch, size);
+}
+
+char *
+elfcore_write_register_note (bfd *abfd,
+ char *buf,
+ int *bufsiz,
+ const char *section,
+ const void *data,
+ int size)
+{
+ if (strcmp (section, ".reg2") == 0)
+ return elfcore_write_prfpreg (abfd, buf, bufsiz, data, size);
+ if (strcmp (section, ".reg-xfp") == 0)
+ return elfcore_write_prxfpreg (abfd, buf, bufsiz, data, size);
+ if (strcmp (section, ".reg-xstate") == 0)
+ return elfcore_write_xstatereg (abfd, buf, bufsiz, data, size);
+ if (strcmp (section, ".reg-ppc-vmx") == 0)
+ return elfcore_write_ppc_vmx (abfd, buf, bufsiz, data, size);
+ if (strcmp (section, ".reg-ppc-vsx") == 0)
+ return elfcore_write_ppc_vsx (abfd, buf, bufsiz, data, size);
+ if (strcmp (section, ".reg-s390-high-gprs") == 0)
+ return elfcore_write_s390_high_gprs (abfd, buf, bufsiz, data, size);
+ if (strcmp (section, ".reg-s390-timer") == 0)
+ return elfcore_write_s390_timer (abfd, buf, bufsiz, data, size);
+ if (strcmp (section, ".reg-s390-todcmp") == 0)
+ return elfcore_write_s390_todcmp (abfd, buf, bufsiz, data, size);
+ if (strcmp (section, ".reg-s390-todpreg") == 0)
+ return elfcore_write_s390_todpreg (abfd, buf, bufsiz, data, size);
+ if (strcmp (section, ".reg-s390-ctrs") == 0)
+ return elfcore_write_s390_ctrs (abfd, buf, bufsiz, data, size);
+ if (strcmp (section, ".reg-s390-prefix") == 0)
+ return elfcore_write_s390_prefix (abfd, buf, bufsiz, data, size);
+ if (strcmp (section, ".reg-s390-last-break") == 0)
+ return elfcore_write_s390_last_break (abfd, buf, bufsiz, data, size);
+ if (strcmp (section, ".reg-s390-system-call") == 0)
+ return elfcore_write_s390_system_call (abfd, buf, bufsiz, data, size);
+ if (strcmp (section, ".reg-s390-tdb") == 0)
+ return elfcore_write_s390_tdb (abfd, buf, bufsiz, data, size);
+ if (strcmp (section, ".reg-arm-vfp") == 0)
+ return elfcore_write_arm_vfp (abfd, buf, bufsiz, data, size);
+ if (strcmp (section, ".reg-aarch-tls") == 0)
+ return elfcore_write_aarch_tls (abfd, buf, bufsiz, data, size);
+ if (strcmp (section, ".reg-aarch-hw-break") == 0)
+ return elfcore_write_aarch_hw_break (abfd, buf, bufsiz, data, size);
+ if (strcmp (section, ".reg-aarch-hw-watch") == 0)
+ return elfcore_write_aarch_hw_watch (abfd, buf, bufsiz, data, size);
+ return NULL;
+}
+
+static bfd_boolean
+elf_parse_notes (bfd *abfd, char *buf, size_t size, file_ptr offset)
+{
+ char *p;
+
+ p = buf;
+ while (p < buf + size)
+ {
+ /* FIXME: bad alignment assumption. */
+ Elf_External_Note *xnp = (Elf_External_Note *) p;
+ Elf_Internal_Note in;
+
+ if (offsetof (Elf_External_Note, name) > buf - p + size)
+ return FALSE;
+
+ in.type = H_GET_32 (abfd, xnp->type);
+
+ in.namesz = H_GET_32 (abfd, xnp->namesz);
+ in.namedata = xnp->name;
+ if (in.namesz > buf - in.namedata + size)
+ return FALSE;
+
+ in.descsz = H_GET_32 (abfd, xnp->descsz);
+ in.descdata = in.namedata + BFD_ALIGN (in.namesz, 4);
+ in.descpos = offset + (in.descdata - buf);
+ if (in.descsz != 0
+ && (in.descdata >= buf + size
+ || in.descsz > buf - in.descdata + size))
+ return FALSE;
+
+ switch (bfd_get_format (abfd))
+ {
+ default:
+ return TRUE;
+
+ case bfd_core:
+ if (CONST_STRNEQ (in.namedata, "NetBSD-CORE"))
+ {
+ if (! elfcore_grok_netbsd_note (abfd, &in))
+ return FALSE;
+ }
+ else if (CONST_STRNEQ (in.namedata, "OpenBSD"))
+ {
+ if (! elfcore_grok_openbsd_note (abfd, &in))
+ return FALSE;
+ }
+ else if (CONST_STRNEQ (in.namedata, "QNX"))
+ {
+ if (! elfcore_grok_nto_note (abfd, &in))
+ return FALSE;
+ }
+ else if (CONST_STRNEQ (in.namedata, "SPU/"))
+ {
+ if (! elfcore_grok_spu_note (abfd, &in))
+ return FALSE;
+ }
+ else
+ {
+ if (! elfcore_grok_note (abfd, &in))
+ return FALSE;
+ }
+ break;
+
+ case bfd_object:
+ if (in.namesz == sizeof "GNU" && strcmp (in.namedata, "GNU") == 0)
+ {
+ if (! elfobj_grok_gnu_note (abfd, &in))
+ return FALSE;
+ }
+ else if (in.namesz == sizeof "stapsdt"
+ && strcmp (in.namedata, "stapsdt") == 0)
+ {
+ if (! elfobj_grok_stapsdt_note (abfd, &in))
+ return FALSE;
+ }
+ break;
+ }
+
+ p = in.descdata + BFD_ALIGN (in.descsz, 4);
+ }
+
+ return TRUE;
+}
+
+static bfd_boolean
+elf_read_notes (bfd *abfd, file_ptr offset, bfd_size_type size)
+{
+ char *buf;
+
+ if (size <= 0)
+ return TRUE;
+
+ if (bfd_seek (abfd, offset, SEEK_SET) != 0)
+ return FALSE;
+
+ buf = (char *) bfd_malloc (size);
+ if (buf == NULL)
+ return FALSE;
+
+ if (bfd_bread (buf, size, abfd) != size
+ || !elf_parse_notes (abfd, buf, size, offset))
+ {
+ free (buf);
+ return FALSE;
+ }
+
+ free (buf);
+ return TRUE;
+}
+
+/* Providing external access to the ELF program header table. */
+
+/* Return an upper bound on the number of bytes required to store a
+ copy of ABFD's program header table entries. Return -1 if an error
+ occurs; bfd_get_error will return an appropriate code. */
+
+long
+bfd_get_elf_phdr_upper_bound (bfd *abfd)
+{
+ if (abfd->xvec->flavour != bfd_target_elf_flavour)
+ {
+ bfd_set_error (bfd_error_wrong_format);
+ return -1;
+ }
+
+ return elf_elfheader (abfd)->e_phnum * sizeof (Elf_Internal_Phdr);
+}
+
+/* Copy ABFD's program header table entries to *PHDRS. The entries
+ will be stored as an array of Elf_Internal_Phdr structures, as
+ defined in include/elf/internal.h. To find out how large the
+ buffer needs to be, call bfd_get_elf_phdr_upper_bound.
+
+ Return the number of program header table entries read, or -1 if an
+ error occurs; bfd_get_error will return an appropriate code. */
+
+int
+bfd_get_elf_phdrs (bfd *abfd, void *phdrs)
+{
+ int num_phdrs;
+
+ if (abfd->xvec->flavour != bfd_target_elf_flavour)
+ {
+ bfd_set_error (bfd_error_wrong_format);
+ return -1;
+ }
+
+ num_phdrs = elf_elfheader (abfd)->e_phnum;
+ memcpy (phdrs, elf_tdata (abfd)->phdr,
+ num_phdrs * sizeof (Elf_Internal_Phdr));
+
+ return num_phdrs;
+}
+
+enum elf_reloc_type_class
+_bfd_elf_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ const asection *rel_sec ATTRIBUTE_UNUSED,
+ const Elf_Internal_Rela *rela ATTRIBUTE_UNUSED)
+{
+ return reloc_class_normal;
+}
+
+/* For RELA architectures, return the relocation value for a
+ relocation against a local symbol. */
+
+bfd_vma
+_bfd_elf_rela_local_sym (bfd *abfd,
+ Elf_Internal_Sym *sym,
+ asection **psec,
+ Elf_Internal_Rela *rel)
+{
+ asection *sec = *psec;
+ bfd_vma relocation;
+
+ relocation = (sec->output_section->vma
+ + sec->output_offset
+ + sym->st_value);
+ if ((sec->flags & SEC_MERGE)
+ && ELF_ST_TYPE (sym->st_info) == STT_SECTION
+ && sec->sec_info_type == SEC_INFO_TYPE_MERGE)
+ {
+ rel->r_addend =
+ _bfd_merged_section_offset (abfd, psec,
+ elf_section_data (sec)->sec_info,
+ sym->st_value + rel->r_addend);
+ if (sec != *psec)
+ {
+ /* If we have changed the section, and our original section is
+ marked with SEC_EXCLUDE, it means that the original
+ SEC_MERGE section has been completely subsumed in some
+ other SEC_MERGE section. In this case, we need to leave
+ some info around for --emit-relocs. */
+ if ((sec->flags & SEC_EXCLUDE) != 0)
+ sec->kept_section = *psec;
+ sec = *psec;
+ }
+ rel->r_addend -= relocation;
+ rel->r_addend += sec->output_section->vma + sec->output_offset;
+ }
+ return relocation;
+}
+
+bfd_vma
+_bfd_elf_rel_local_sym (bfd *abfd,
+ Elf_Internal_Sym *sym,
+ asection **psec,
+ bfd_vma addend)
+{
+ asection *sec = *psec;
+
+ if (sec->sec_info_type != SEC_INFO_TYPE_MERGE)
+ return sym->st_value + addend;
+
+ return _bfd_merged_section_offset (abfd, psec,
+ elf_section_data (sec)->sec_info,
+ sym->st_value + addend);
+}
+
+bfd_vma
+_bfd_elf_section_offset (bfd *abfd,
+ struct bfd_link_info *info,
+ asection *sec,
+ bfd_vma offset)
+{
+ switch (sec->sec_info_type)
+ {
+ case SEC_INFO_TYPE_STABS:
+ return _bfd_stab_section_offset (sec, elf_section_data (sec)->sec_info,
+ offset);
+ case SEC_INFO_TYPE_EH_FRAME:
+ return _bfd_elf_eh_frame_section_offset (abfd, info, sec, offset);
+ default:
+ if ((sec->flags & SEC_ELF_REVERSE_COPY) != 0)
+ {
+ const struct elf_backend_data *bed = get_elf_backend_data (abfd);
+ bfd_size_type address_size = bed->s->arch_size / 8;
+ offset = sec->size - offset - address_size;
+ }
+ return offset;
+ }
+}
+
+/* Create a new BFD as if by bfd_openr. Rather than opening a file,
+ reconstruct an ELF file by reading the segments out of remote memory
+ based on the ELF file header at EHDR_VMA and the ELF program headers it
+ points to. If not null, *LOADBASEP is filled in with the difference
+ between the VMAs from which the segments were read, and the VMAs the
+ file headers (and hence BFD's idea of each section's VMA) put them at.
+
+ The function TARGET_READ_MEMORY is called to copy LEN bytes from the
+ remote memory at target address VMA into the local buffer at MYADDR; it
+ should return zero on success or an `errno' code on failure. TEMPL must
+ be a BFD for an ELF target with the word size and byte order found in
+ the remote memory. */
+
+bfd *
+bfd_elf_bfd_from_remote_memory
+ (bfd *templ,
+ bfd_vma ehdr_vma,
+ bfd_size_type size,
+ bfd_vma *loadbasep,
+ int (*target_read_memory) (bfd_vma, bfd_byte *, bfd_size_type))
+{
+ return (*get_elf_backend_data (templ)->elf_backend_bfd_from_remote_memory)
+ (templ, ehdr_vma, size, loadbasep, target_read_memory);
+}
+
+long
+_bfd_elf_get_synthetic_symtab (bfd *abfd,
+ long symcount ATTRIBUTE_UNUSED,
+ asymbol **syms ATTRIBUTE_UNUSED,
+ long dynsymcount,
+ asymbol **dynsyms,
+ asymbol **ret)
+{
+ const struct elf_backend_data *bed = get_elf_backend_data (abfd);
+ asection *relplt;
+ asymbol *s;
+ const char *relplt_name;
+ bfd_boolean (*slurp_relocs) (bfd *, asection *, asymbol **, bfd_boolean);
+ arelent *p;
+ long count, i, n;
+ size_t size;
+ Elf_Internal_Shdr *hdr;
+ char *names;
+ asection *plt;
+
+ *ret = NULL;
+
+ if ((abfd->flags & (DYNAMIC | EXEC_P)) == 0)
+ return 0;
+
+ if (dynsymcount <= 0)
+ return 0;
+
+ if (!bed->plt_sym_val)
+ return 0;
+
+ relplt_name = bed->relplt_name;
+ if (relplt_name == NULL)
+ relplt_name = bed->rela_plts_and_copies_p ? ".rela.plt" : ".rel.plt";
+ relplt = bfd_get_section_by_name (abfd, relplt_name);
+ if (relplt == NULL)
+ return 0;
+
+ hdr = &elf_section_data (relplt)->this_hdr;
+ if (hdr->sh_link != elf_dynsymtab (abfd)
+ || (hdr->sh_type != SHT_REL && hdr->sh_type != SHT_RELA))
+ return 0;
+
+ plt = bfd_get_section_by_name (abfd, ".plt");
+ if (plt == NULL)
+ return 0;
+
+ slurp_relocs = get_elf_backend_data (abfd)->s->slurp_reloc_table;
+ if (! (*slurp_relocs) (abfd, relplt, dynsyms, TRUE))
+ return -1;
+
+ count = relplt->size / hdr->sh_entsize;
+ size = count * sizeof (asymbol);
+ p = relplt->relocation;
+ for (i = 0; i < count; i++, p += bed->s->int_rels_per_ext_rel)
+ {
+ size += strlen ((*p->sym_ptr_ptr)->name) + sizeof ("@plt");
+ if (p->addend != 0)
+ {
+#ifdef BFD64
+ size += sizeof ("+0x") - 1 + 8 + 8 * (bed->s->elfclass == ELFCLASS64);
+#else
+ size += sizeof ("+0x") - 1 + 8;
+#endif
+ }
+ }
+
+ s = *ret = (asymbol *) bfd_malloc (size);
+ if (s == NULL)
+ return -1;
+
+ names = (char *) (s + count);
+ p = relplt->relocation;
+ n = 0;
+ for (i = 0; i < count; i++, p += bed->s->int_rels_per_ext_rel)
+ {
+ size_t len;
+ bfd_vma addr;
+
+ addr = bed->plt_sym_val (i, plt, p);
+ if (addr == (bfd_vma) -1)
+ continue;
+
+ *s = **p->sym_ptr_ptr;
+ /* Undefined syms won't have BSF_LOCAL or BSF_GLOBAL set. Since
+ we are defining a symbol, ensure one of them is set. */
+ if ((s->flags & BSF_LOCAL) == 0)
+ s->flags |= BSF_GLOBAL;
+ s->flags |= BSF_SYNTHETIC;
+ s->section = plt;
+ s->value = addr - plt->vma;
+ s->name = names;
+ s->udata.p = NULL;
+ len = strlen ((*p->sym_ptr_ptr)->name);
+ memcpy (names, (*p->sym_ptr_ptr)->name, len);
+ names += len;
+ if (p->addend != 0)
+ {
+ char buf[30], *a;
+
+ memcpy (names, "+0x", sizeof ("+0x") - 1);
+ names += sizeof ("+0x") - 1;
+ bfd_sprintf_vma (abfd, buf, p->addend);
+ for (a = buf; *a == '0'; ++a)
+ ;
+ len = strlen (a);
+ memcpy (names, a, len);
+ names += len;
+ }
+ memcpy (names, "@plt", sizeof ("@plt"));
+ names += sizeof ("@plt");
+ ++s, ++n;
+ }
+
+ return n;
+}
+
+/* It is only used by x86-64 so far. */
+asection _bfd_elf_large_com_section
+ = BFD_FAKE_SECTION (_bfd_elf_large_com_section,
+ SEC_IS_COMMON, NULL, "LARGE_COMMON", 0);
+
+void
+_bfd_elf_post_process_headers (bfd * abfd,
+ struct bfd_link_info * link_info ATTRIBUTE_UNUSED)
+{
+ Elf_Internal_Ehdr * i_ehdrp; /* ELF file header, internal form. */
+
+ i_ehdrp = elf_elfheader (abfd);
+
+ i_ehdrp->e_ident[EI_OSABI] = get_elf_backend_data (abfd)->elf_osabi;
+
+ /* To make things simpler for the loader on Linux systems we set the
+ osabi field to ELFOSABI_GNU if the binary contains symbols of
+ the STT_GNU_IFUNC type or STB_GNU_UNIQUE binding. */
+ if (i_ehdrp->e_ident[EI_OSABI] == ELFOSABI_NONE
+ && elf_tdata (abfd)->has_gnu_symbols)
+ i_ehdrp->e_ident[EI_OSABI] = ELFOSABI_GNU;
+}
+
+
+/* Return TRUE for ELF symbol types that represent functions.
+ This is the default version of this function, which is sufficient for
+ most targets. It returns true if TYPE is STT_FUNC or STT_GNU_IFUNC. */
+
+bfd_boolean
+_bfd_elf_is_function_type (unsigned int type)
+{
+ return (type == STT_FUNC
+ || type == STT_GNU_IFUNC);
+}
+
+/* If the ELF symbol SYM might be a function in SEC, return the
+ function size and set *CODE_OFF to the function's entry point,
+ otherwise return zero. */
+
+bfd_size_type
+_bfd_elf_maybe_function_sym (const asymbol *sym, asection *sec,
+ bfd_vma *code_off)
+{
+ bfd_size_type size;
+
+ if ((sym->flags & (BSF_SECTION_SYM | BSF_FILE | BSF_OBJECT
+ | BSF_THREAD_LOCAL | BSF_RELC | BSF_SRELC)) != 0
+ || sym->section != sec)
+ return 0;
+
+ *code_off = sym->value;
+ size = 0;
+ if (!(sym->flags & BSF_SYNTHETIC))
+ size = ((elf_symbol_type *) sym)->internal_elf_sym.st_size;
+ if (size == 0)
+ size = 1;
+ return size;
+}
diff --git a/bfd/elf32-am33lin.c b/bfd/elf32-am33lin.c
new file mode 100644
index 0000000..c28308d
--- /dev/null
+++ b/bfd/elf32-am33lin.c
@@ -0,0 +1,105 @@
+/* Matsushita AM33/2.0 support for 32-bit GNU/Linux ELF
+ Copyright (C) 2003-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "elf-bfd.h"
+#include "elf/mn10300.h"
+
+#define elf_symbol_leading_char 0
+
+#define TARGET_LITTLE_SYM am33_elf32_linux_vec
+#define TARGET_LITTLE_NAME "elf32-am33lin"
+#define ELF_ARCH bfd_arch_mn10300
+#define ELF_MACHINE_CODE EM_MN10300
+#define ELF_MACHINE_ALT1 EM_CYGNUS_MN10300
+#define ELF_MAXPAGESIZE 0x1000
+
+/* Rename global functions. */
+#define _bfd_mn10300_elf_merge_private_bfd_data _bfd_am33_elf_merge_private_bfd_data
+#define _bfd_mn10300_elf_object_p _bfd_am33_elf_object_p
+#define _bfd_mn10300_elf_final_write_processing _bfd_am33_elf_final_write_processing
+
+/* Support for core dump NOTE sections. */
+static bfd_boolean
+elf32_am33lin_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
+{
+ int offset;
+ unsigned int size;
+
+ switch (note->descsz)
+ {
+ default:
+ return FALSE;
+
+ case 184:
+ case 188: /* Linux/am33 */
+ /* pr_cursig */
+ elf_tdata (abfd)->core->signal = bfd_get_16 (abfd, note->descdata + 12);
+
+ /* pr_pid */
+ elf_tdata (abfd)->core->lwpid = bfd_get_32 (abfd, note->descdata + 24);
+
+ /* pr_reg */
+ offset = 72;
+ size = 112;
+
+ break;
+ }
+
+ /* Make a ".reg/999" section. */
+ return _bfd_elfcore_make_pseudosection (abfd, ".reg", size,
+ note->descpos + offset);
+}
+
+static bfd_boolean
+elf32_am33lin_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
+{
+ switch (note->descsz)
+ {
+ default:
+ return FALSE;
+
+ case 124: /* Linux/am33 elf_prpsinfo */
+ elf_tdata (abfd)->core->program
+ = _bfd_elfcore_strndup (abfd, note->descdata + 28, 16);
+ elf_tdata (abfd)->core->command
+ = _bfd_elfcore_strndup (abfd, note->descdata + 44, 80);
+ }
+
+ /* 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;
+}
+
+#define elf_backend_grok_prstatus elf32_am33lin_grok_prstatus
+#define elf_backend_grok_psinfo elf32_am33lin_grok_psinfo
+
+#include "elf-m10300.c"
diff --git a/bfd/elf32-arc.c b/bfd/elf32-arc.c
new file mode 100644
index 0000000..e528e66
--- /dev/null
+++ b/bfd/elf32-arc.c
@@ -0,0 +1,252 @@
+/* ARC-specific support for 32-bit ELF
+ Copyright (C) 1994-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+#include "elf-bfd.h"
+#include "elf/arc.h"
+#include "libiberty.h"
+
+/* 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 1
+
+static bfd_reloc_status_type
+arc_elf_b22_pcrel (bfd * abfd,
+ arelent * reloc_entry,
+ asymbol * symbol,
+ void * data,
+ asection * input_section,
+ bfd * output_bfd,
+ char ** error_message)
+{
+ /* If linking, back up the final symbol address by the address of the
+ reloc. This cannot be accomplished by setting the pcrel_offset
+ field to TRUE, as bfd_install_relocation will detect this and refuse
+ to install the offset in the first place, but bfd_perform_relocation
+ will still insist on removing it. */
+ if (output_bfd == NULL)
+ reloc_entry->addend -= reloc_entry->address;
+
+ /* Fall through to the default elf reloc handler. */
+ return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
+ input_section, output_bfd, error_message);
+}
+
+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. */
+ TRUE, /* 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. */
+ TRUE, /* 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. */
+ TRUE, /* 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. */
+ arc_elf_b22_pcrel, /* Special_function. */
+ "R_ARC_B22_PCREL", /* Name. */
+ TRUE, /* Partial_inplace. */
+ 0x07ffff80, /* Src_mask. */
+ 0x07ffff80, /* Dst_mask. */
+ FALSE), /* 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 (bfd *abfd ATTRIBUTE_UNUSED,
+ bfd_reloc_code_real_type code)
+{
+ unsigned int i;
+
+ for (i = ARRAY_SIZE (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;
+}
+
+static reloc_howto_type *
+bfd_elf32_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ const char *r_name)
+{
+ unsigned int i;
+
+ for (i = 0;
+ i < sizeof (elf_arc_howto_table) / sizeof (elf_arc_howto_table[0]);
+ i++)
+ if (elf_arc_howto_table[i].name != NULL
+ && strcasecmp (elf_arc_howto_table[i].name, r_name) == 0)
+ return &elf_arc_howto_table[i];
+
+ return NULL;
+}
+
+/* Set the howto pointer for an ARC ELF reloc. */
+
+static void
+arc_info_to_howto_rel (bfd *abfd ATTRIBUTE_UNUSED,
+ arelent *cache_ptr,
+ Elf_Internal_Rela *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 bfd_boolean
+arc_elf_object_p (bfd *abfd)
+{
+ unsigned int mach = bfd_mach_arc_6;
+
+ if (elf_elfheader(abfd)->e_machine == EM_ARC)
+ {
+ unsigned long arch = elf_elfheader (abfd)->e_flags & EF_ARC_MACH;
+
+ switch (arch)
+ {
+ case E_ARC_MACH_ARC5:
+ mach = bfd_mach_arc_5;
+ break;
+ default:
+ case E_ARC_MACH_ARC6:
+ mach = bfd_mach_arc_6;
+ break;
+ case E_ARC_MACH_ARC7:
+ mach = bfd_mach_arc_7;
+ break;
+ case E_ARC_MACH_ARC8:
+ mach = bfd_mach_arc_8;
+ break;
+ }
+ }
+ return bfd_default_set_arch_mach (abfd, bfd_arch_arc, mach);
+}
+
+/* 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 (bfd *abfd,
+ bfd_boolean linker ATTRIBUTE_UNUSED)
+{
+ unsigned long val;
+
+ switch (bfd_get_mach (abfd))
+ {
+ case bfd_mach_arc_5:
+ val = E_ARC_MACH_ARC5;
+ break;
+ default:
+ case bfd_mach_arc_6:
+ val = E_ARC_MACH_ARC6;
+ break;
+ case bfd_mach_arc_7:
+ val = E_ARC_MACH_ARC7;
+ break;
+ case bfd_mach_arc_8:
+ val = E_ARC_MACH_ARC8;
+ break;
+ }
+ elf_elfheader (abfd)->e_flags &=~ EF_ARC_MACH;
+ elf_elfheader (abfd)->e_flags |= val;
+}
+
+#define TARGET_LITTLE_SYM arc_elf32_le_vec
+#define TARGET_LITTLE_NAME "elf32-littlearc"
+#define TARGET_BIG_SYM arc_elf32_be_vec
+#define TARGET_BIG_NAME "elf32-bigarc"
+#define ELF_ARCH bfd_arch_arc
+#define ELF_MACHINE_CODE EM_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.c b/bfd/elf32-arm.c
new file mode 100644
index 0000000..996889d
--- /dev/null
+++ b/bfd/elf32-arm.c
@@ -0,0 +1,16758 @@
+/* 32-bit ELF support for ARM
+ Copyright (C) 1998-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include <limits.h>
+
+#include "bfd.h"
+#include "bfd_stdint.h"
+#include "libiberty.h"
+#include "libbfd.h"
+#include "elf-bfd.h"
+#include "elf-nacl.h"
+#include "elf-vxworks.h"
+#include "elf/arm.h"
+
+/* Return the relocation section associated with NAME. HTAB is the
+ bfd's elf32_arm_link_hash_entry. */
+#define RELOC_SECTION(HTAB, NAME) \
+ ((HTAB)->use_rel ? ".rel" NAME : ".rela" NAME)
+
+/* Return size of a relocation entry. HTAB is the bfd's
+ elf32_arm_link_hash_entry. */
+#define RELOC_SIZE(HTAB) \
+ ((HTAB)->use_rel \
+ ? sizeof (Elf32_External_Rel) \
+ : sizeof (Elf32_External_Rela))
+
+/* Return function to swap relocations in. HTAB is the bfd's
+ elf32_arm_link_hash_entry. */
+#define SWAP_RELOC_IN(HTAB) \
+ ((HTAB)->use_rel \
+ ? bfd_elf32_swap_reloc_in \
+ : bfd_elf32_swap_reloca_in)
+
+/* Return function to swap relocations out. HTAB is the bfd's
+ elf32_arm_link_hash_entry. */
+#define SWAP_RELOC_OUT(HTAB) \
+ ((HTAB)->use_rel \
+ ? bfd_elf32_swap_reloc_out \
+ : bfd_elf32_swap_reloca_out)
+
+#define elf_info_to_howto 0
+#define elf_info_to_howto_rel elf32_arm_info_to_howto
+
+#define ARM_ELF_ABI_VERSION 0
+#define ARM_ELF_OS_ABI_VERSION ELFOSABI_ARM
+
+/* The Adjusted Place, as defined by AAELF. */
+#define Pa(X) ((X) & 0xfffffffc)
+
+static bfd_boolean elf32_arm_write_section (bfd *output_bfd,
+ struct bfd_link_info *link_info,
+ asection *sec,
+ bfd_byte *contents);
+
+/* Note: code such as elf32_arm_reloc_type_lookup expect to use e.g.
+ R_ARM_PC24 as an index into this, and find the R_ARM_PC24 HOWTO
+ in that slot. */
+
+static reloc_howto_type elf32_arm_howto_table_1[] =
+{
+ /* 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 - R_ARM_LDR_PC_G0 in AAELF */
+ HOWTO (R_ARM_LDR_PC_G0, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_ARM_LDR_PC_G0", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ TRUE), /* 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 */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* 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 */
+ 0x00000fff, /* src_mask */
+ 0x00000fff, /* 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 */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* 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 */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_ARM_THM_CALL, /* type */
+ 1, /* 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_THM_CALL", /* name */
+ FALSE, /* partial_inplace */
+ 0x07ff2fff, /* src_mask */
+ 0x07ff2fff, /* 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_BREL_ADJ, /* type */
+ 1, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_ARM_BREL_ADJ", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_ARM_TLS_DESC, /* 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_TLS_DESC", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* 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 */
+
+ /* BLX instruction for the ARM. */
+ HOWTO (R_ARM_XPC25, /* 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_XPC25", /* name */
+ FALSE, /* partial_inplace */
+ 0x00ffffff, /* src_mask */
+ 0x00ffffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* BLX instruction for the Thumb. */
+ HOWTO (R_ARM_THM_XPC22, /* 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_THM_XPC22", /* name */
+ FALSE, /* partial_inplace */
+ 0x07ff2fff, /* src_mask */
+ 0x07ff2fff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* Dynamic TLS relocations. */
+
+ HOWTO (R_ARM_TLS_DTPMOD32, /* 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_TLS_DTPMOD32", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_ARM_TLS_DTPOFF32, /* 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_TLS_DTPOFF32", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_ARM_TLS_TPOFF32, /* 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_TLS_TPOFF32", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* 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_GOTOFF32, /* 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_GOTOFF32", /* 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) */
+ 24, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_ARM_PLT32", /* name */
+ FALSE, /* partial_inplace */
+ 0x00ffffff, /* src_mask */
+ 0x00ffffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_ARM_CALL, /* 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_CALL", /* name */
+ FALSE, /* partial_inplace */
+ 0x00ffffff, /* src_mask */
+ 0x00ffffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_ARM_JUMP24, /* 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_JUMP24", /* name */
+ FALSE, /* partial_inplace */
+ 0x00ffffff, /* src_mask */
+ 0x00ffffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_ARM_THM_JUMP24, /* type */
+ 1, /* 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_THM_JUMP24", /* name */
+ FALSE, /* partial_inplace */
+ 0x07ff2fff, /* src_mask */
+ 0x07ff2fff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_ARM_BASE_ABS, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_ARM_BASE_ABS", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_ARM_ALU_PCREL7_0, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 12, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_ARM_ALU_PCREL_7_0", /* name */
+ FALSE, /* partial_inplace */
+ 0x00000fff, /* src_mask */
+ 0x00000fff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_ARM_ALU_PCREL15_8, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 12, /* bitsize */
+ TRUE, /* pc_relative */
+ 8, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_ARM_ALU_PCREL_15_8",/* name */
+ FALSE, /* partial_inplace */
+ 0x00000fff, /* src_mask */
+ 0x00000fff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_ARM_ALU_PCREL23_15, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 12, /* bitsize */
+ TRUE, /* pc_relative */
+ 16, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_ARM_ALU_PCREL_23_15",/* name */
+ FALSE, /* partial_inplace */
+ 0x00000fff, /* src_mask */
+ 0x00000fff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_ARM_LDR_SBREL_11_0, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 12, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_ARM_LDR_SBREL_11_0",/* name */
+ FALSE, /* partial_inplace */
+ 0x00000fff, /* src_mask */
+ 0x00000fff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_ARM_ALU_SBREL_19_12, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 8, /* bitsize */
+ FALSE, /* pc_relative */
+ 12, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_ARM_ALU_SBREL_19_12",/* name */
+ FALSE, /* partial_inplace */
+ 0x000ff000, /* src_mask */
+ 0x000ff000, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_ARM_ALU_SBREL_27_20, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 8, /* bitsize */
+ FALSE, /* pc_relative */
+ 20, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_ARM_ALU_SBREL_27_20",/* name */
+ FALSE, /* partial_inplace */
+ 0x0ff00000, /* src_mask */
+ 0x0ff00000, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_ARM_TARGET1, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_ARM_TARGET1", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_ARM_ROSEGREL32, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_ARM_ROSEGREL32", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_ARM_V4BX, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_ARM_V4BX", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_ARM_TARGET2, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_ARM_TARGET2", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_ARM_PREL31, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 31, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_ARM_PREL31", /* name */
+ FALSE, /* partial_inplace */
+ 0x7fffffff, /* src_mask */
+ 0x7fffffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_ARM_MOVW_ABS_NC, /* 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_ARM_MOVW_ABS_NC", /* name */
+ FALSE, /* partial_inplace */
+ 0x000f0fff, /* src_mask */
+ 0x000f0fff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_ARM_MOVT_ABS, /* 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_ARM_MOVT_ABS", /* name */
+ FALSE, /* partial_inplace */
+ 0x000f0fff, /* src_mask */
+ 0x000f0fff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_ARM_MOVW_PREL_NC, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_ARM_MOVW_PREL_NC", /* name */
+ FALSE, /* partial_inplace */
+ 0x000f0fff, /* src_mask */
+ 0x000f0fff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_ARM_MOVT_PREL, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_ARM_MOVT_PREL", /* name */
+ FALSE, /* partial_inplace */
+ 0x000f0fff, /* src_mask */
+ 0x000f0fff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_ARM_THM_MOVW_ABS_NC, /* 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_ARM_THM_MOVW_ABS_NC",/* name */
+ FALSE, /* partial_inplace */
+ 0x040f70ff, /* src_mask */
+ 0x040f70ff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_ARM_THM_MOVT_ABS, /* 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_ARM_THM_MOVT_ABS", /* name */
+ FALSE, /* partial_inplace */
+ 0x040f70ff, /* src_mask */
+ 0x040f70ff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_ARM_THM_MOVW_PREL_NC,/* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_ARM_THM_MOVW_PREL_NC",/* name */
+ FALSE, /* partial_inplace */
+ 0x040f70ff, /* src_mask */
+ 0x040f70ff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_ARM_THM_MOVT_PREL, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_ARM_THM_MOVT_PREL", /* name */
+ FALSE, /* partial_inplace */
+ 0x040f70ff, /* src_mask */
+ 0x040f70ff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_ARM_THM_JUMP19, /* type */
+ 1, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 19, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_ARM_THM_JUMP19", /* name */
+ FALSE, /* partial_inplace */
+ 0x043f2fff, /* src_mask */
+ 0x043f2fff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_ARM_THM_JUMP6, /* type */
+ 1, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 6, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_unsigned,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_ARM_THM_JUMP6", /* name */
+ FALSE, /* partial_inplace */
+ 0x02f8, /* src_mask */
+ 0x02f8, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* These are declared as 13-bit signed relocations because we can
+ address -4095 .. 4095(base) by altering ADDW to SUBW or vice
+ versa. */
+ HOWTO (R_ARM_THM_ALU_PREL_11_0,/* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 13, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_ARM_THM_ALU_PREL_11_0",/* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_ARM_THM_PC12, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 13, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_ARM_THM_PC12", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_ARM_ABS32_NOI, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_ARM_ABS32_NOI", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_ARM_REL32_NOI, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_ARM_REL32_NOI", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Group relocations. */
+
+ HOWTO (R_ARM_ALU_PC_G0_NC, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_ARM_ALU_PC_G0_NC", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_ARM_ALU_PC_G0, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_ARM_ALU_PC_G0", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_ARM_ALU_PC_G1_NC, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_ARM_ALU_PC_G1_NC", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_ARM_ALU_PC_G1, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_ARM_ALU_PC_G1", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_ARM_ALU_PC_G2, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_ARM_ALU_PC_G2", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_ARM_LDR_PC_G1, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_ARM_LDR_PC_G1", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_ARM_LDR_PC_G2, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_ARM_LDR_PC_G2", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_ARM_LDRS_PC_G0, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_ARM_LDRS_PC_G0", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_ARM_LDRS_PC_G1, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_ARM_LDRS_PC_G1", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_ARM_LDRS_PC_G2, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_ARM_LDRS_PC_G2", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_ARM_LDC_PC_G0, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_ARM_LDC_PC_G0", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_ARM_LDC_PC_G1, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_ARM_LDC_PC_G1", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_ARM_LDC_PC_G2, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_ARM_LDC_PC_G2", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_ARM_ALU_SB_G0_NC, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_ARM_ALU_SB_G0_NC", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_ARM_ALU_SB_G0, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_ARM_ALU_SB_G0", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_ARM_ALU_SB_G1_NC, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_ARM_ALU_SB_G1_NC", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_ARM_ALU_SB_G1, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_ARM_ALU_SB_G1", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_ARM_ALU_SB_G2, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_ARM_ALU_SB_G2", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_ARM_LDR_SB_G0, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_ARM_LDR_SB_G0", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_ARM_LDR_SB_G1, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_ARM_LDR_SB_G1", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_ARM_LDR_SB_G2, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_ARM_LDR_SB_G2", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_ARM_LDRS_SB_G0, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_ARM_LDRS_SB_G0", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_ARM_LDRS_SB_G1, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_ARM_LDRS_SB_G1", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_ARM_LDRS_SB_G2, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_ARM_LDRS_SB_G2", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_ARM_LDC_SB_G0, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_ARM_LDC_SB_G0", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_ARM_LDC_SB_G1, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_ARM_LDC_SB_G1", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_ARM_LDC_SB_G2, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_ARM_LDC_SB_G2", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* End of group relocations. */
+
+ HOWTO (R_ARM_MOVW_BREL_NC, /* 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_ARM_MOVW_BREL_NC", /* name */
+ FALSE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_ARM_MOVT_BREL, /* 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_ARM_MOVT_BREL", /* name */
+ FALSE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_ARM_MOVW_BREL, /* 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_ARM_MOVW_BREL", /* name */
+ FALSE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_ARM_THM_MOVW_BREL_NC,/* 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_ARM_THM_MOVW_BREL_NC",/* name */
+ FALSE, /* partial_inplace */
+ 0x040f70ff, /* src_mask */
+ 0x040f70ff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_ARM_THM_MOVT_BREL, /* 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_ARM_THM_MOVT_BREL", /* name */
+ FALSE, /* partial_inplace */
+ 0x040f70ff, /* src_mask */
+ 0x040f70ff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_ARM_THM_MOVW_BREL, /* 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_ARM_THM_MOVW_BREL", /* name */
+ FALSE, /* partial_inplace */
+ 0x040f70ff, /* src_mask */
+ 0x040f70ff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_ARM_TLS_GOTDESC, /* 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 */
+ "R_ARM_TLS_GOTDESC", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_ARM_TLS_CALL, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 24, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_ARM_TLS_CALL", /* name */
+ FALSE, /* partial_inplace */
+ 0x00ffffff, /* src_mask */
+ 0x00ffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_ARM_TLS_DESCSEQ, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 0, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_ARM_TLS_DESCSEQ", /* name */
+ FALSE, /* partial_inplace */
+ 0x00000000, /* src_mask */
+ 0x00000000, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_ARM_THM_TLS_CALL, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 24, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_ARM_THM_TLS_CALL", /* name */
+ FALSE, /* partial_inplace */
+ 0x07ff07ff, /* src_mask */
+ 0x07ff07ff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_ARM_PLT32_ABS, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_ARM_PLT32_ABS", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_ARM_GOT_ABS, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_ARM_GOT_ABS", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_ARM_GOT_PREL, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_ARM_GOT_PREL", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_ARM_GOT_BREL12, /* 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_GOT_BREL12", /* name */
+ FALSE, /* partial_inplace */
+ 0x00000fff, /* src_mask */
+ 0x00000fff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_ARM_GOTOFF12, /* 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_GOTOFF12", /* name */
+ FALSE, /* partial_inplace */
+ 0x00000fff, /* src_mask */
+ 0x00000fff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ EMPTY_HOWTO (R_ARM_GOTRELAX), /* reserved for future GOT-load optimizations */
+
+ /* 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 */
+
+ /* 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 */
+
+ HOWTO (R_ARM_THM_JUMP11, /* 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_JUMP11", /* name */
+ FALSE, /* partial_inplace */
+ 0x000007ff, /* src_mask */
+ 0x000007ff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_ARM_THM_JUMP8, /* 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_JUMP8", /* name */
+ FALSE, /* partial_inplace */
+ 0x000000ff, /* src_mask */
+ 0x000000ff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* TLS relocations */
+ HOWTO (R_ARM_TLS_GD32, /* 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 */
+ "R_ARM_TLS_GD32", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_ARM_TLS_LDM32, /* 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_TLS_LDM32", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_ARM_TLS_LDO32, /* 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_TLS_LDO32", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_ARM_TLS_IE32, /* 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 */
+ "R_ARM_TLS_IE32", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_ARM_TLS_LE32, /* 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_TLS_LE32", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_ARM_TLS_LDO12, /* 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_TLS_LDO12", /* name */
+ FALSE, /* partial_inplace */
+ 0x00000fff, /* src_mask */
+ 0x00000fff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_ARM_TLS_LE12, /* 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_TLS_LE12", /* name */
+ FALSE, /* partial_inplace */
+ 0x00000fff, /* src_mask */
+ 0x00000fff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_ARM_TLS_IE12GP, /* 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_TLS_IE12GP", /* name */
+ FALSE, /* partial_inplace */
+ 0x00000fff, /* src_mask */
+ 0x00000fff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* 112-127 private relocations. */
+ EMPTY_HOWTO (112),
+ EMPTY_HOWTO (113),
+ EMPTY_HOWTO (114),
+ EMPTY_HOWTO (115),
+ EMPTY_HOWTO (116),
+ EMPTY_HOWTO (117),
+ EMPTY_HOWTO (118),
+ EMPTY_HOWTO (119),
+ EMPTY_HOWTO (120),
+ EMPTY_HOWTO (121),
+ EMPTY_HOWTO (122),
+ EMPTY_HOWTO (123),
+ EMPTY_HOWTO (124),
+ EMPTY_HOWTO (125),
+ EMPTY_HOWTO (126),
+ EMPTY_HOWTO (127),
+
+ /* R_ARM_ME_TOO, obsolete. */
+ EMPTY_HOWTO (128),
+
+ HOWTO (R_ARM_THM_TLS_DESCSEQ, /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 0, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_ARM_THM_TLS_DESCSEQ",/* name */
+ FALSE, /* partial_inplace */
+ 0x00000000, /* src_mask */
+ 0x00000000, /* dst_mask */
+ FALSE), /* pcrel_offset */
+};
+
+/* 160 onwards: */
+static reloc_howto_type elf32_arm_howto_table_2[1] =
+{
+ HOWTO (R_ARM_IRELATIVE, /* 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_IRELATIVE", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE) /* pcrel_offset */
+};
+
+/* 249-255 extended, currently unused, relocations: */
+static reloc_howto_type elf32_arm_howto_table_3[4] =
+{
+ 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 reloc_howto_type *
+elf32_arm_howto_from_type (unsigned int r_type)
+{
+ if (r_type < ARRAY_SIZE (elf32_arm_howto_table_1))
+ return &elf32_arm_howto_table_1[r_type];
+
+ if (r_type == R_ARM_IRELATIVE)
+ return &elf32_arm_howto_table_2[r_type - R_ARM_IRELATIVE];
+
+ if (r_type >= R_ARM_RREL32
+ && r_type < R_ARM_RREL32 + ARRAY_SIZE (elf32_arm_howto_table_3))
+ return &elf32_arm_howto_table_3[r_type - R_ARM_RREL32];
+
+ return NULL;
+}
+
+static void
+elf32_arm_info_to_howto (bfd * abfd ATTRIBUTE_UNUSED, arelent * bfd_reloc,
+ Elf_Internal_Rela * elf_reloc)
+{
+ unsigned int r_type;
+
+ r_type = ELF32_R_TYPE (elf_reloc->r_info);
+ bfd_reloc->howto = elf32_arm_howto_from_type (r_type);
+}
+
+struct elf32_arm_reloc_map
+ {
+ bfd_reloc_code_real_type bfd_reloc_val;
+ unsigned char elf_reloc_val;
+ };
+
+/* All entries in this list must also be present in elf32_arm_howto_table. */
+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_ARM_PCREL_CALL, R_ARM_CALL},
+ {BFD_RELOC_ARM_PCREL_JUMP, R_ARM_JUMP24},
+ {BFD_RELOC_ARM_PCREL_BLX, R_ARM_XPC25},
+ {BFD_RELOC_THUMB_PCREL_BLX, R_ARM_THM_XPC22},
+ {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_BRANCH25, R_ARM_THM_JUMP24},
+ {BFD_RELOC_THUMB_PCREL_BRANCH23, R_ARM_THM_CALL},
+ {BFD_RELOC_THUMB_PCREL_BRANCH12, R_ARM_THM_JUMP11},
+ {BFD_RELOC_THUMB_PCREL_BRANCH20, R_ARM_THM_JUMP19},
+ {BFD_RELOC_THUMB_PCREL_BRANCH9, R_ARM_THM_JUMP8},
+ {BFD_RELOC_THUMB_PCREL_BRANCH7, R_ARM_THM_JUMP6},
+ {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_GOTOFF32},
+ {BFD_RELOC_ARM_GOTPC, R_ARM_GOTPC},
+ {BFD_RELOC_ARM_GOT_PREL, R_ARM_GOT_PREL},
+ {BFD_RELOC_ARM_GOT32, R_ARM_GOT32},
+ {BFD_RELOC_ARM_PLT32, R_ARM_PLT32},
+ {BFD_RELOC_ARM_TARGET1, R_ARM_TARGET1},
+ {BFD_RELOC_ARM_ROSEGREL32, R_ARM_ROSEGREL32},
+ {BFD_RELOC_ARM_SBREL32, R_ARM_SBREL32},
+ {BFD_RELOC_ARM_PREL31, R_ARM_PREL31},
+ {BFD_RELOC_ARM_TARGET2, R_ARM_TARGET2},
+ {BFD_RELOC_ARM_PLT32, R_ARM_PLT32},
+ {BFD_RELOC_ARM_TLS_GOTDESC, R_ARM_TLS_GOTDESC},
+ {BFD_RELOC_ARM_TLS_CALL, R_ARM_TLS_CALL},
+ {BFD_RELOC_ARM_THM_TLS_CALL, R_ARM_THM_TLS_CALL},
+ {BFD_RELOC_ARM_TLS_DESCSEQ, R_ARM_TLS_DESCSEQ},
+ {BFD_RELOC_ARM_THM_TLS_DESCSEQ, R_ARM_THM_TLS_DESCSEQ},
+ {BFD_RELOC_ARM_TLS_DESC, R_ARM_TLS_DESC},
+ {BFD_RELOC_ARM_TLS_GD32, R_ARM_TLS_GD32},
+ {BFD_RELOC_ARM_TLS_LDO32, R_ARM_TLS_LDO32},
+ {BFD_RELOC_ARM_TLS_LDM32, R_ARM_TLS_LDM32},
+ {BFD_RELOC_ARM_TLS_DTPMOD32, R_ARM_TLS_DTPMOD32},
+ {BFD_RELOC_ARM_TLS_DTPOFF32, R_ARM_TLS_DTPOFF32},
+ {BFD_RELOC_ARM_TLS_TPOFF32, R_ARM_TLS_TPOFF32},
+ {BFD_RELOC_ARM_TLS_IE32, R_ARM_TLS_IE32},
+ {BFD_RELOC_ARM_TLS_LE32, R_ARM_TLS_LE32},
+ {BFD_RELOC_ARM_IRELATIVE, R_ARM_IRELATIVE},
+ {BFD_RELOC_VTABLE_INHERIT, R_ARM_GNU_VTINHERIT},
+ {BFD_RELOC_VTABLE_ENTRY, R_ARM_GNU_VTENTRY},
+ {BFD_RELOC_ARM_MOVW, R_ARM_MOVW_ABS_NC},
+ {BFD_RELOC_ARM_MOVT, R_ARM_MOVT_ABS},
+ {BFD_RELOC_ARM_MOVW_PCREL, R_ARM_MOVW_PREL_NC},
+ {BFD_RELOC_ARM_MOVT_PCREL, R_ARM_MOVT_PREL},
+ {BFD_RELOC_ARM_THUMB_MOVW, R_ARM_THM_MOVW_ABS_NC},
+ {BFD_RELOC_ARM_THUMB_MOVT, R_ARM_THM_MOVT_ABS},
+ {BFD_RELOC_ARM_THUMB_MOVW_PCREL, R_ARM_THM_MOVW_PREL_NC},
+ {BFD_RELOC_ARM_THUMB_MOVT_PCREL, R_ARM_THM_MOVT_PREL},
+ {BFD_RELOC_ARM_ALU_PC_G0_NC, R_ARM_ALU_PC_G0_NC},
+ {BFD_RELOC_ARM_ALU_PC_G0, R_ARM_ALU_PC_G0},
+ {BFD_RELOC_ARM_ALU_PC_G1_NC, R_ARM_ALU_PC_G1_NC},
+ {BFD_RELOC_ARM_ALU_PC_G1, R_ARM_ALU_PC_G1},
+ {BFD_RELOC_ARM_ALU_PC_G2, R_ARM_ALU_PC_G2},
+ {BFD_RELOC_ARM_LDR_PC_G0, R_ARM_LDR_PC_G0},
+ {BFD_RELOC_ARM_LDR_PC_G1, R_ARM_LDR_PC_G1},
+ {BFD_RELOC_ARM_LDR_PC_G2, R_ARM_LDR_PC_G2},
+ {BFD_RELOC_ARM_LDRS_PC_G0, R_ARM_LDRS_PC_G0},
+ {BFD_RELOC_ARM_LDRS_PC_G1, R_ARM_LDRS_PC_G1},
+ {BFD_RELOC_ARM_LDRS_PC_G2, R_ARM_LDRS_PC_G2},
+ {BFD_RELOC_ARM_LDC_PC_G0, R_ARM_LDC_PC_G0},
+ {BFD_RELOC_ARM_LDC_PC_G1, R_ARM_LDC_PC_G1},
+ {BFD_RELOC_ARM_LDC_PC_G2, R_ARM_LDC_PC_G2},
+ {BFD_RELOC_ARM_ALU_SB_G0_NC, R_ARM_ALU_SB_G0_NC},
+ {BFD_RELOC_ARM_ALU_SB_G0, R_ARM_ALU_SB_G0},
+ {BFD_RELOC_ARM_ALU_SB_G1_NC, R_ARM_ALU_SB_G1_NC},
+ {BFD_RELOC_ARM_ALU_SB_G1, R_ARM_ALU_SB_G1},
+ {BFD_RELOC_ARM_ALU_SB_G2, R_ARM_ALU_SB_G2},
+ {BFD_RELOC_ARM_LDR_SB_G0, R_ARM_LDR_SB_G0},
+ {BFD_RELOC_ARM_LDR_SB_G1, R_ARM_LDR_SB_G1},
+ {BFD_RELOC_ARM_LDR_SB_G2, R_ARM_LDR_SB_G2},
+ {BFD_RELOC_ARM_LDRS_SB_G0, R_ARM_LDRS_SB_G0},
+ {BFD_RELOC_ARM_LDRS_SB_G1, R_ARM_LDRS_SB_G1},
+ {BFD_RELOC_ARM_LDRS_SB_G2, R_ARM_LDRS_SB_G2},
+ {BFD_RELOC_ARM_LDC_SB_G0, R_ARM_LDC_SB_G0},
+ {BFD_RELOC_ARM_LDC_SB_G1, R_ARM_LDC_SB_G1},
+ {BFD_RELOC_ARM_LDC_SB_G2, R_ARM_LDC_SB_G2},
+ {BFD_RELOC_ARM_V4BX, R_ARM_V4BX}
+ };
+
+static reloc_howto_type *
+elf32_arm_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ bfd_reloc_code_real_type code)
+{
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE (elf32_arm_reloc_map); i ++)
+ if (elf32_arm_reloc_map[i].bfd_reloc_val == code)
+ return elf32_arm_howto_from_type (elf32_arm_reloc_map[i].elf_reloc_val);
+
+ return NULL;
+}
+
+static reloc_howto_type *
+elf32_arm_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ const char *r_name)
+{
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE (elf32_arm_howto_table_1); i++)
+ if (elf32_arm_howto_table_1[i].name != NULL
+ && strcasecmp (elf32_arm_howto_table_1[i].name, r_name) == 0)
+ return &elf32_arm_howto_table_1[i];
+
+ for (i = 0; i < ARRAY_SIZE (elf32_arm_howto_table_2); i++)
+ if (elf32_arm_howto_table_2[i].name != NULL
+ && strcasecmp (elf32_arm_howto_table_2[i].name, r_name) == 0)
+ return &elf32_arm_howto_table_2[i];
+
+ for (i = 0; i < ARRAY_SIZE (elf32_arm_howto_table_3); i++)
+ if (elf32_arm_howto_table_3[i].name != NULL
+ && strcasecmp (elf32_arm_howto_table_3[i].name, r_name) == 0)
+ return &elf32_arm_howto_table_3[i];
+
+ return NULL;
+}
+
+/* Support for core dump NOTE sections. */
+
+static bfd_boolean
+elf32_arm_nabi_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
+{
+ int offset;
+ size_t size;
+
+ switch (note->descsz)
+ {
+ default:
+ return FALSE;
+
+ case 148: /* Linux/ARM 32-bit. */
+ /* pr_cursig */
+ elf_tdata (abfd)->core->signal = bfd_get_16 (abfd, note->descdata + 12);
+
+ /* pr_pid */
+ elf_tdata (abfd)->core->lwpid = bfd_get_32 (abfd, note->descdata + 24);
+
+ /* pr_reg */
+ offset = 72;
+ size = 72;
+
+ break;
+ }
+
+ /* Make a ".reg/999" section. */
+ return _bfd_elfcore_make_pseudosection (abfd, ".reg",
+ size, note->descpos + offset);
+}
+
+static bfd_boolean
+elf32_arm_nabi_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
+{
+ switch (note->descsz)
+ {
+ default:
+ return FALSE;
+
+ case 124: /* Linux/ARM elf_prpsinfo. */
+ elf_tdata (abfd)->core->pid
+ = bfd_get_32 (abfd, note->descdata + 12);
+ elf_tdata (abfd)->core->program
+ = _bfd_elfcore_strndup (abfd, note->descdata + 28, 16);
+ elf_tdata (abfd)->core->command
+ = _bfd_elfcore_strndup (abfd, note->descdata + 44, 80);
+ }
+
+ /* 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;
+}
+
+static char *
+elf32_arm_nabi_write_core_note (bfd *abfd, char *buf, int *bufsiz,
+ int note_type, ...)
+{
+ switch (note_type)
+ {
+ default:
+ return NULL;
+
+ case NT_PRPSINFO:
+ {
+ char data[124];
+ va_list ap;
+
+ va_start (ap, note_type);
+ memset (data, 0, sizeof (data));
+ strncpy (data + 28, va_arg (ap, const char *), 16);
+ strncpy (data + 44, va_arg (ap, const char *), 80);
+ va_end (ap);
+
+ return elfcore_write_note (abfd, buf, bufsiz,
+ "CORE", note_type, data, sizeof (data));
+ }
+
+ case NT_PRSTATUS:
+ {
+ char data[148];
+ va_list ap;
+ long pid;
+ int cursig;
+ const void *greg;
+
+ va_start (ap, note_type);
+ memset (data, 0, sizeof (data));
+ pid = va_arg (ap, long);
+ bfd_put_32 (abfd, pid, data + 24);
+ cursig = va_arg (ap, int);
+ bfd_put_16 (abfd, cursig, data + 12);
+ greg = va_arg (ap, const void *);
+ memcpy (data + 72, greg, 72);
+ va_end (ap);
+
+ return elfcore_write_note (abfd, buf, bufsiz,
+ "CORE", note_type, data, sizeof (data));
+ }
+ }
+}
+
+#define TARGET_LITTLE_SYM arm_elf32_le_vec
+#define TARGET_LITTLE_NAME "elf32-littlearm"
+#define TARGET_BIG_SYM arm_elf32_be_vec
+#define TARGET_BIG_NAME "elf32-bigarm"
+
+#define elf_backend_grok_prstatus elf32_arm_nabi_grok_prstatus
+#define elf_backend_grok_psinfo elf32_arm_nabi_grok_psinfo
+#define elf_backend_write_core_note elf32_arm_nabi_write_core_note
+
+typedef unsigned long int insn32;
+typedef unsigned short int insn16;
+
+/* In lieu of proper flags, assume all EABIv4 or later objects are
+ interworkable. */
+#define INTERWORK_FLAG(abfd) \
+ (EF_ARM_EABI_VERSION (elf_elfheader (abfd)->e_flags) >= EF_ARM_EABI_VER4 \
+ || (elf_elfheader (abfd)->e_flags & EF_ARM_INTERWORK) \
+ || ((abfd)->flags & BFD_LINKER_CREATED))
+
+/* 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"
+
+#define VFP11_ERRATUM_VENEER_SECTION_NAME ".vfp11_veneer"
+#define VFP11_ERRATUM_VENEER_ENTRY_NAME "__vfp11_veneer_%x"
+
+#define ARM_BX_GLUE_SECTION_NAME ".v4_bx"
+#define ARM_BX_GLUE_ENTRY_NAME "__bx_r%d"
+
+#define STUB_ENTRY_NAME "__%s_veneer"
+
+/* The name of the dynamic interpreter. This is put in the .interp
+ section. */
+#define ELF_DYNAMIC_INTERPRETER "/usr/lib/ld.so.1"
+
+static const unsigned long tls_trampoline [] =
+{
+ 0xe08e0000, /* add r0, lr, r0 */
+ 0xe5901004, /* ldr r1, [r0,#4] */
+ 0xe12fff11, /* bx r1 */
+};
+
+static const unsigned long dl_tlsdesc_lazy_trampoline [] =
+{
+ 0xe52d2004, /* push {r2} */
+ 0xe59f200c, /* ldr r2, [pc, #3f - . - 8] */
+ 0xe59f100c, /* ldr r1, [pc, #4f - . - 8] */
+ 0xe79f2002, /* 1: ldr r2, [pc, r2] */
+ 0xe081100f, /* 2: add r1, pc */
+ 0xe12fff12, /* bx r2 */
+ 0x00000014, /* 3: .word _GLOBAL_OFFSET_TABLE_ - 1b - 8
+ + dl_tlsdesc_lazy_resolver(GOT) */
+ 0x00000018, /* 4: .word _GLOBAL_OFFSET_TABLE_ - 2b - 8 */
+};
+
+#ifdef FOUR_WORD_PLT
+
+/* 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 calls the dynamic
+ linker first. */
+static const bfd_vma elf32_arm_plt0_entry [] =
+{
+ 0xe52de004, /* str lr, [sp, #-4]! */
+ 0xe59fe010, /* ldr lr, [pc, #16] */
+ 0xe08fe00e, /* add lr, pc, lr */
+ 0xe5bef008, /* ldr pc, [lr, #8]! */
+};
+
+/* Subsequent entries in a procedure linkage table look like
+ this. */
+static const bfd_vma elf32_arm_plt_entry [] =
+{
+ 0xe28fc600, /* add ip, pc, #NN */
+ 0xe28cca00, /* add ip, ip, #NN */
+ 0xe5bcf000, /* ldr pc, [ip, #NN]! */
+ 0x00000000, /* unused */
+};
+
+#else /* not FOUR_WORD_PLT */
+
+/* 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 calls the dynamic
+ linker first. */
+static const bfd_vma elf32_arm_plt0_entry [] =
+{
+ 0xe52de004, /* str lr, [sp, #-4]! */
+ 0xe59fe004, /* ldr lr, [pc, #4] */
+ 0xe08fe00e, /* add lr, pc, lr */
+ 0xe5bef008, /* ldr pc, [lr, #8]! */
+ 0x00000000, /* &GOT[0] - . */
+};
+
+/* By default subsequent entries in a procedure linkage table look like
+ this. Offsets that don't fit into 28 bits will cause link error. */
+static const bfd_vma elf32_arm_plt_entry_short [] =
+{
+ 0xe28fc600, /* add ip, pc, #0xNN00000 */
+ 0xe28cca00, /* add ip, ip, #0xNN000 */
+ 0xe5bcf000, /* ldr pc, [ip, #0xNNN]! */
+};
+
+/* When explicitly asked, we'll use this "long" entry format
+ which can cope with arbitrary displacements. */
+static const bfd_vma elf32_arm_plt_entry_long [] =
+{
+ 0xe28fc200, /* add ip, pc, #0xN0000000 */
+ 0xe28cc600, /* add ip, ip, #0xNN00000 */
+ 0xe28cca00, /* add ip, ip, #0xNN000 */
+ 0xe5bcf000, /* ldr pc, [ip, #0xNNN]! */
+};
+
+static bfd_boolean elf32_arm_use_long_plt_entry = FALSE;
+
+#endif /* not FOUR_WORD_PLT */
+
+/* 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 calls the dynamic linker first. */
+static const bfd_vma elf32_thumb2_plt0_entry [] =
+{
+ /* NOTE: As this is a mixture of 16-bit and 32-bit instructions,
+ an instruction maybe encoded to one or two array elements. */
+ 0xf8dfb500, /* push {lr} */
+ 0x44fee008, /* ldr.w lr, [pc, #8] */
+ /* add lr, pc */
+ 0xff08f85e, /* ldr.w pc, [lr, #8]! */
+ 0x00000000, /* &GOT[0] - . */
+};
+
+/* Subsequent entries in a procedure linkage table for thumb only target
+ look like this. */
+static const bfd_vma elf32_thumb2_plt_entry [] =
+{
+ /* NOTE: As this is a mixture of 16-bit and 32-bit instructions,
+ an instruction maybe encoded to one or two array elements. */
+ 0x0c00f240, /* movw ip, #0xNNNN */
+ 0x0c00f2c0, /* movt ip, #0xNNNN */
+ 0xf8dc44fc, /* add ip, pc */
+ 0xbf00f000 /* ldr.w pc, [ip] */
+ /* nop */
+};
+
+/* The format of the first entry in the procedure linkage table
+ for a VxWorks executable. */
+static const bfd_vma elf32_arm_vxworks_exec_plt0_entry[] =
+{
+ 0xe52dc008, /* str ip,[sp,#-8]! */
+ 0xe59fc000, /* ldr ip,[pc] */
+ 0xe59cf008, /* ldr pc,[ip,#8] */
+ 0x00000000, /* .long _GLOBAL_OFFSET_TABLE_ */
+};
+
+/* The format of subsequent entries in a VxWorks executable. */
+static const bfd_vma elf32_arm_vxworks_exec_plt_entry[] =
+{
+ 0xe59fc000, /* ldr ip,[pc] */
+ 0xe59cf000, /* ldr pc,[ip] */
+ 0x00000000, /* .long @got */
+ 0xe59fc000, /* ldr ip,[pc] */
+ 0xea000000, /* b _PLT */
+ 0x00000000, /* .long @pltindex*sizeof(Elf32_Rela) */
+};
+
+/* The format of entries in a VxWorks shared library. */
+static const bfd_vma elf32_arm_vxworks_shared_plt_entry[] =
+{
+ 0xe59fc000, /* ldr ip,[pc] */
+ 0xe79cf009, /* ldr pc,[ip,r9] */
+ 0x00000000, /* .long @got */
+ 0xe59fc000, /* ldr ip,[pc] */
+ 0xe599f008, /* ldr pc,[r9,#8] */
+ 0x00000000, /* .long @pltindex*sizeof(Elf32_Rela) */
+};
+
+/* An initial stub used if the PLT entry is referenced from Thumb code. */
+#define PLT_THUMB_STUB_SIZE 4
+static const bfd_vma elf32_arm_plt_thumb_stub [] =
+{
+ 0x4778, /* bx pc */
+ 0x46c0 /* nop */
+};
+
+/* The entries in a PLT when using a DLL-based target with multiple
+ address spaces. */
+static const bfd_vma elf32_arm_symbian_plt_entry [] =
+{
+ 0xe51ff004, /* ldr pc, [pc, #-4] */
+ 0x00000000, /* dcd R_ARM_GLOB_DAT(X) */
+};
+
+/* 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 calls the dynamic
+ linker first. */
+static const bfd_vma elf32_arm_nacl_plt0_entry [] =
+{
+ /* First bundle: */
+ 0xe300c000, /* movw ip, #:lower16:&GOT[2]-.+8 */
+ 0xe340c000, /* movt ip, #:upper16:&GOT[2]-.+8 */
+ 0xe08cc00f, /* add ip, ip, pc */
+ 0xe52dc008, /* str ip, [sp, #-8]! */
+ /* Second bundle: */
+ 0xe3ccc103, /* bic ip, ip, #0xc0000000 */
+ 0xe59cc000, /* ldr ip, [ip] */
+ 0xe3ccc13f, /* bic ip, ip, #0xc000000f */
+ 0xe12fff1c, /* bx ip */
+ /* Third bundle: */
+ 0xe320f000, /* nop */
+ 0xe320f000, /* nop */
+ 0xe320f000, /* nop */
+ /* .Lplt_tail: */
+ 0xe50dc004, /* str ip, [sp, #-4] */
+ /* Fourth bundle: */
+ 0xe3ccc103, /* bic ip, ip, #0xc0000000 */
+ 0xe59cc000, /* ldr ip, [ip] */
+ 0xe3ccc13f, /* bic ip, ip, #0xc000000f */
+ 0xe12fff1c, /* bx ip */
+};
+#define ARM_NACL_PLT_TAIL_OFFSET (11 * 4)
+
+/* Subsequent entries in a procedure linkage table look like this. */
+static const bfd_vma elf32_arm_nacl_plt_entry [] =
+{
+ 0xe300c000, /* movw ip, #:lower16:&GOT[n]-.+8 */
+ 0xe340c000, /* movt ip, #:upper16:&GOT[n]-.+8 */
+ 0xe08cc00f, /* add ip, ip, pc */
+ 0xea000000, /* b .Lplt_tail */
+};
+
+#define ARM_MAX_FWD_BRANCH_OFFSET ((((1 << 23) - 1) << 2) + 8)
+#define ARM_MAX_BWD_BRANCH_OFFSET ((-((1 << 23) << 2)) + 8)
+#define THM_MAX_FWD_BRANCH_OFFSET ((1 << 22) -2 + 4)
+#define THM_MAX_BWD_BRANCH_OFFSET (-(1 << 22) + 4)
+#define THM2_MAX_FWD_BRANCH_OFFSET (((1 << 24) - 2) + 4)
+#define THM2_MAX_BWD_BRANCH_OFFSET (-(1 << 24) + 4)
+#define THM2_MAX_FWD_COND_BRANCH_OFFSET (((1 << 20) -2) + 4)
+#define THM2_MAX_BWD_COND_BRANCH_OFFSET (-(1 << 20) + 4)
+
+enum stub_insn_type
+{
+ THUMB16_TYPE = 1,
+ THUMB32_TYPE,
+ ARM_TYPE,
+ DATA_TYPE
+};
+
+#define THUMB16_INSN(X) {(X), THUMB16_TYPE, R_ARM_NONE, 0}
+/* A bit of a hack. A Thumb conditional branch, in which the proper condition
+ is inserted in arm_build_one_stub(). */
+#define THUMB16_BCOND_INSN(X) {(X), THUMB16_TYPE, R_ARM_NONE, 1}
+#define THUMB32_INSN(X) {(X), THUMB32_TYPE, R_ARM_NONE, 0}
+#define THUMB32_B_INSN(X, Z) {(X), THUMB32_TYPE, R_ARM_THM_JUMP24, (Z)}
+#define ARM_INSN(X) {(X), ARM_TYPE, R_ARM_NONE, 0}
+#define ARM_REL_INSN(X, Z) {(X), ARM_TYPE, R_ARM_JUMP24, (Z)}
+#define DATA_WORD(X,Y,Z) {(X), DATA_TYPE, (Y), (Z)}
+
+typedef struct
+{
+ bfd_vma data;
+ enum stub_insn_type type;
+ unsigned int r_type;
+ int reloc_addend;
+} insn_sequence;
+
+/* Arm/Thumb -> Arm/Thumb long branch stub. On V5T and above, use blx
+ to reach the stub if necessary. */
+static const insn_sequence elf32_arm_stub_long_branch_any_any[] =
+{
+ ARM_INSN (0xe51ff004), /* ldr pc, [pc, #-4] */
+ DATA_WORD (0, R_ARM_ABS32, 0), /* dcd R_ARM_ABS32(X) */
+};
+
+/* V4T Arm -> Thumb long branch stub. Used on V4T where blx is not
+ available. */
+static const insn_sequence elf32_arm_stub_long_branch_v4t_arm_thumb[] =
+{
+ ARM_INSN (0xe59fc000), /* ldr ip, [pc, #0] */
+ ARM_INSN (0xe12fff1c), /* bx ip */
+ DATA_WORD (0, R_ARM_ABS32, 0), /* dcd R_ARM_ABS32(X) */
+};
+
+/* Thumb -> Thumb long branch stub. Used on M-profile architectures. */
+static const insn_sequence elf32_arm_stub_long_branch_thumb_only[] =
+{
+ THUMB16_INSN (0xb401), /* push {r0} */
+ THUMB16_INSN (0x4802), /* ldr r0, [pc, #8] */
+ THUMB16_INSN (0x4684), /* mov ip, r0 */
+ THUMB16_INSN (0xbc01), /* pop {r0} */
+ THUMB16_INSN (0x4760), /* bx ip */
+ THUMB16_INSN (0xbf00), /* nop */
+ DATA_WORD (0, R_ARM_ABS32, 0), /* dcd R_ARM_ABS32(X) */
+};
+
+/* V4T Thumb -> Thumb long branch stub. Using the stack is not
+ allowed. */
+static const insn_sequence elf32_arm_stub_long_branch_v4t_thumb_thumb[] =
+{
+ THUMB16_INSN (0x4778), /* bx pc */
+ THUMB16_INSN (0x46c0), /* nop */
+ ARM_INSN (0xe59fc000), /* ldr ip, [pc, #0] */
+ ARM_INSN (0xe12fff1c), /* bx ip */
+ DATA_WORD (0, R_ARM_ABS32, 0), /* dcd R_ARM_ABS32(X) */
+};
+
+/* V4T Thumb -> ARM long branch stub. Used on V4T where blx is not
+ available. */
+static const insn_sequence elf32_arm_stub_long_branch_v4t_thumb_arm[] =
+{
+ THUMB16_INSN (0x4778), /* bx pc */
+ THUMB16_INSN (0x46c0), /* nop */
+ ARM_INSN (0xe51ff004), /* ldr pc, [pc, #-4] */
+ DATA_WORD (0, R_ARM_ABS32, 0), /* dcd R_ARM_ABS32(X) */
+};
+
+/* V4T Thumb -> ARM short branch stub. Shorter variant of the above
+ one, when the destination is close enough. */
+static const insn_sequence elf32_arm_stub_short_branch_v4t_thumb_arm[] =
+{
+ THUMB16_INSN (0x4778), /* bx pc */
+ THUMB16_INSN (0x46c0), /* nop */
+ ARM_REL_INSN (0xea000000, -8), /* b (X-8) */
+};
+
+/* ARM/Thumb -> ARM long branch stub, PIC. On V5T and above, use
+ blx to reach the stub if necessary. */
+static const insn_sequence elf32_arm_stub_long_branch_any_arm_pic[] =
+{
+ ARM_INSN (0xe59fc000), /* ldr ip, [pc] */
+ ARM_INSN (0xe08ff00c), /* add pc, pc, ip */
+ DATA_WORD (0, R_ARM_REL32, -4), /* dcd R_ARM_REL32(X-4) */
+};
+
+/* ARM/Thumb -> Thumb long branch stub, PIC. On V5T and above, use
+ blx to reach the stub if necessary. We can not add into pc;
+ it is not guaranteed to mode switch (different in ARMv6 and
+ ARMv7). */
+static const insn_sequence elf32_arm_stub_long_branch_any_thumb_pic[] =
+{
+ ARM_INSN (0xe59fc004), /* ldr ip, [pc, #4] */
+ ARM_INSN (0xe08fc00c), /* add ip, pc, ip */
+ ARM_INSN (0xe12fff1c), /* bx ip */
+ DATA_WORD (0, R_ARM_REL32, 0), /* dcd R_ARM_REL32(X) */
+};
+
+/* V4T ARM -> ARM long branch stub, PIC. */
+static const insn_sequence elf32_arm_stub_long_branch_v4t_arm_thumb_pic[] =
+{
+ ARM_INSN (0xe59fc004), /* ldr ip, [pc, #4] */
+ ARM_INSN (0xe08fc00c), /* add ip, pc, ip */
+ ARM_INSN (0xe12fff1c), /* bx ip */
+ DATA_WORD (0, R_ARM_REL32, 0), /* dcd R_ARM_REL32(X) */
+};
+
+/* V4T Thumb -> ARM long branch stub, PIC. */
+static const insn_sequence elf32_arm_stub_long_branch_v4t_thumb_arm_pic[] =
+{
+ THUMB16_INSN (0x4778), /* bx pc */
+ THUMB16_INSN (0x46c0), /* nop */
+ ARM_INSN (0xe59fc000), /* ldr ip, [pc, #0] */
+ ARM_INSN (0xe08cf00f), /* add pc, ip, pc */
+ DATA_WORD (0, R_ARM_REL32, -4), /* dcd R_ARM_REL32(X) */
+};
+
+/* Thumb -> Thumb long branch stub, PIC. Used on M-profile
+ architectures. */
+static const insn_sequence elf32_arm_stub_long_branch_thumb_only_pic[] =
+{
+ THUMB16_INSN (0xb401), /* push {r0} */
+ THUMB16_INSN (0x4802), /* ldr r0, [pc, #8] */
+ THUMB16_INSN (0x46fc), /* mov ip, pc */
+ THUMB16_INSN (0x4484), /* add ip, r0 */
+ THUMB16_INSN (0xbc01), /* pop {r0} */
+ THUMB16_INSN (0x4760), /* bx ip */
+ DATA_WORD (0, R_ARM_REL32, 4), /* dcd R_ARM_REL32(X) */
+};
+
+/* V4T Thumb -> Thumb long branch stub, PIC. Using the stack is not
+ allowed. */
+static const insn_sequence elf32_arm_stub_long_branch_v4t_thumb_thumb_pic[] =
+{
+ THUMB16_INSN (0x4778), /* bx pc */
+ THUMB16_INSN (0x46c0), /* nop */
+ ARM_INSN (0xe59fc004), /* ldr ip, [pc, #4] */
+ ARM_INSN (0xe08fc00c), /* add ip, pc, ip */
+ ARM_INSN (0xe12fff1c), /* bx ip */
+ DATA_WORD (0, R_ARM_REL32, 0), /* dcd R_ARM_REL32(X) */
+};
+
+/* Thumb2/ARM -> TLS trampoline. Lowest common denominator, which is a
+ long PIC stub. We can use r1 as a scratch -- and cannot use ip. */
+static const insn_sequence elf32_arm_stub_long_branch_any_tls_pic[] =
+{
+ ARM_INSN (0xe59f1000), /* ldr r1, [pc] */
+ ARM_INSN (0xe08ff001), /* add pc, pc, r1 */
+ DATA_WORD (0, R_ARM_REL32, -4), /* dcd R_ARM_REL32(X-4) */
+};
+
+/* V4T Thumb -> TLS trampoline. lowest common denominator, which is a
+ long PIC stub. We can use r1 as a scratch -- and cannot use ip. */
+static const insn_sequence elf32_arm_stub_long_branch_v4t_thumb_tls_pic[] =
+{
+ THUMB16_INSN (0x4778), /* bx pc */
+ THUMB16_INSN (0x46c0), /* nop */
+ ARM_INSN (0xe59f1000), /* ldr r1, [pc, #0] */
+ ARM_INSN (0xe081f00f), /* add pc, r1, pc */
+ DATA_WORD (0, R_ARM_REL32, -4), /* dcd R_ARM_REL32(X) */
+};
+
+/* NaCl ARM -> ARM long branch stub. */
+static const insn_sequence elf32_arm_stub_long_branch_arm_nacl[] =
+{
+ ARM_INSN (0xe59fc00c), /* ldr ip, [pc, #12] */
+ ARM_INSN (0xe3ccc13f), /* bic ip, ip, #0xc000000f */
+ ARM_INSN (0xe12fff1c), /* bx ip */
+ ARM_INSN (0xe320f000), /* nop */
+ ARM_INSN (0xe125be70), /* bkpt 0x5be0 */
+ DATA_WORD (0, R_ARM_ABS32, 0), /* dcd R_ARM_ABS32(X) */
+ DATA_WORD (0, R_ARM_NONE, 0), /* .word 0 */
+ DATA_WORD (0, R_ARM_NONE, 0), /* .word 0 */
+};
+
+/* NaCl ARM -> ARM long branch stub, PIC. */
+static const insn_sequence elf32_arm_stub_long_branch_arm_nacl_pic[] =
+{
+ ARM_INSN (0xe59fc00c), /* ldr ip, [pc, #12] */
+ ARM_INSN (0xe08cc00f), /* add ip, ip, pc */
+ ARM_INSN (0xe3ccc13f), /* bic ip, ip, #0xc000000f */
+ ARM_INSN (0xe12fff1c), /* bx ip */
+ ARM_INSN (0xe125be70), /* bkpt 0x5be0 */
+ DATA_WORD (0, R_ARM_REL32, 8), /* dcd R_ARM_REL32(X+8) */
+ DATA_WORD (0, R_ARM_NONE, 0), /* .word 0 */
+ DATA_WORD (0, R_ARM_NONE, 0), /* .word 0 */
+};
+
+
+/* Cortex-A8 erratum-workaround stubs. */
+
+/* Stub used for conditional branches (which may be beyond +/-1MB away, so we
+ can't use a conditional branch to reach this stub). */
+
+static const insn_sequence elf32_arm_stub_a8_veneer_b_cond[] =
+{
+ THUMB16_BCOND_INSN (0xd001), /* b<cond>.n true. */
+ THUMB32_B_INSN (0xf000b800, -4), /* b.w insn_after_original_branch. */
+ THUMB32_B_INSN (0xf000b800, -4) /* true: b.w original_branch_dest. */
+};
+
+/* Stub used for b.w and bl.w instructions. */
+
+static const insn_sequence elf32_arm_stub_a8_veneer_b[] =
+{
+ THUMB32_B_INSN (0xf000b800, -4) /* b.w original_branch_dest. */
+};
+
+static const insn_sequence elf32_arm_stub_a8_veneer_bl[] =
+{
+ THUMB32_B_INSN (0xf000b800, -4) /* b.w original_branch_dest. */
+};
+
+/* Stub used for Thumb-2 blx.w instructions. We modified the original blx.w
+ instruction (which switches to ARM mode) to point to this stub. Jump to the
+ real destination using an ARM-mode branch. */
+
+static const insn_sequence elf32_arm_stub_a8_veneer_blx[] =
+{
+ ARM_REL_INSN (0xea000000, -8) /* b original_branch_dest. */
+};
+
+/* For each section group there can be a specially created linker section
+ to hold the stubs for that group. The name of the stub section is based
+ upon the name of another section within that group with the suffix below
+ applied.
+
+ PR 13049: STUB_SUFFIX used to be ".stub", but this allowed the user to
+ create what appeared to be a linker stub section when it actually
+ contained user code/data. For example, consider this fragment:
+
+ const char * stubborn_problems[] = { "np" };
+
+ If this is compiled with "-fPIC -fdata-sections" then gcc produces a
+ section called:
+
+ .data.rel.local.stubborn_problems
+
+ This then causes problems in arm32_arm_build_stubs() as it triggers:
+
+ // Ignore non-stub sections.
+ if (!strstr (stub_sec->name, STUB_SUFFIX))
+ continue;
+
+ And so the section would be ignored instead of being processed. Hence
+ the change in definition of STUB_SUFFIX to a name that cannot be a valid
+ C identifier. */
+#define STUB_SUFFIX ".__stub"
+
+/* One entry per long/short branch stub defined above. */
+#define DEF_STUBS \
+ DEF_STUB(long_branch_any_any) \
+ DEF_STUB(long_branch_v4t_arm_thumb) \
+ DEF_STUB(long_branch_thumb_only) \
+ DEF_STUB(long_branch_v4t_thumb_thumb) \
+ DEF_STUB(long_branch_v4t_thumb_arm) \
+ DEF_STUB(short_branch_v4t_thumb_arm) \
+ DEF_STUB(long_branch_any_arm_pic) \
+ DEF_STUB(long_branch_any_thumb_pic) \
+ DEF_STUB(long_branch_v4t_thumb_thumb_pic) \
+ DEF_STUB(long_branch_v4t_arm_thumb_pic) \
+ DEF_STUB(long_branch_v4t_thumb_arm_pic) \
+ DEF_STUB(long_branch_thumb_only_pic) \
+ DEF_STUB(long_branch_any_tls_pic) \
+ DEF_STUB(long_branch_v4t_thumb_tls_pic) \
+ DEF_STUB(long_branch_arm_nacl) \
+ DEF_STUB(long_branch_arm_nacl_pic) \
+ DEF_STUB(a8_veneer_b_cond) \
+ DEF_STUB(a8_veneer_b) \
+ DEF_STUB(a8_veneer_bl) \
+ DEF_STUB(a8_veneer_blx)
+
+#define DEF_STUB(x) arm_stub_##x,
+enum elf32_arm_stub_type
+{
+ arm_stub_none,
+ DEF_STUBS
+ /* Note the first a8_veneer type. */
+ arm_stub_a8_veneer_lwm = arm_stub_a8_veneer_b_cond
+};
+#undef DEF_STUB
+
+typedef struct
+{
+ const insn_sequence* template_sequence;
+ int template_size;
+} stub_def;
+
+#define DEF_STUB(x) {elf32_arm_stub_##x, ARRAY_SIZE(elf32_arm_stub_##x)},
+static const stub_def stub_definitions[] =
+{
+ {NULL, 0},
+ DEF_STUBS
+};
+
+struct elf32_arm_stub_hash_entry
+{
+ /* Base hash table entry structure. */
+ struct bfd_hash_entry root;
+
+ /* The stub section. */
+ asection *stub_sec;
+
+ /* Offset within stub_sec of the beginning of this stub. */
+ bfd_vma stub_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). */
+ bfd_vma target_value;
+ asection *target_section;
+
+ /* Offset to apply to relocation referencing target_value. */
+ bfd_vma target_addend;
+
+ /* The instruction which caused this stub to be generated (only valid for
+ Cortex-A8 erratum workaround stubs at present). */
+ unsigned long orig_insn;
+
+ /* The stub type. */
+ enum elf32_arm_stub_type stub_type;
+ /* Its encoding size in bytes. */
+ int stub_size;
+ /* Its template. */
+ const insn_sequence *stub_template;
+ /* The size of the template (number of entries). */
+ int stub_template_size;
+
+ /* The symbol table entry, if any, that this was derived from. */
+ struct elf32_arm_link_hash_entry *h;
+
+ /* Type of branch. */
+ enum arm_st_branch_type branch_type;
+
+ /* Where this stub is being called from, or, in the case of combined
+ stub sections, the first input section in the group. */
+ asection *id_sec;
+
+ /* The name for the local symbol at the start of this stub. The
+ stub name in the hash table has to be unique; this does not, so
+ it can be friendlier. */
+ char *output_name;
+};
+
+/* Used to build a map of a section. This is required for mixed-endian
+ code/data. */
+
+typedef struct elf32_elf_section_map
+{
+ bfd_vma vma;
+ char type;
+}
+elf32_arm_section_map;
+
+/* Information about a VFP11 erratum veneer, or a branch to such a veneer. */
+
+typedef enum
+{
+ VFP11_ERRATUM_BRANCH_TO_ARM_VENEER,
+ VFP11_ERRATUM_BRANCH_TO_THUMB_VENEER,
+ VFP11_ERRATUM_ARM_VENEER,
+ VFP11_ERRATUM_THUMB_VENEER
+}
+elf32_vfp11_erratum_type;
+
+typedef struct elf32_vfp11_erratum_list
+{
+ struct elf32_vfp11_erratum_list *next;
+ bfd_vma vma;
+ union
+ {
+ struct
+ {
+ struct elf32_vfp11_erratum_list *veneer;
+ unsigned int vfp_insn;
+ } b;
+ struct
+ {
+ struct elf32_vfp11_erratum_list *branch;
+ unsigned int id;
+ } v;
+ } u;
+ elf32_vfp11_erratum_type type;
+}
+elf32_vfp11_erratum_list;
+
+typedef enum
+{
+ DELETE_EXIDX_ENTRY,
+ INSERT_EXIDX_CANTUNWIND_AT_END
+}
+arm_unwind_edit_type;
+
+/* A (sorted) list of edits to apply to an unwind table. */
+typedef struct arm_unwind_table_edit
+{
+ arm_unwind_edit_type type;
+ /* Note: we sometimes want to insert an unwind entry corresponding to a
+ section different from the one we're currently writing out, so record the
+ (text) section this edit relates to here. */
+ asection *linked_section;
+ unsigned int index;
+ struct arm_unwind_table_edit *next;
+}
+arm_unwind_table_edit;
+
+typedef struct _arm_elf_section_data
+{
+ /* Information about mapping symbols. */
+ struct bfd_elf_section_data elf;
+ unsigned int mapcount;
+ unsigned int mapsize;
+ elf32_arm_section_map *map;
+ /* Information about CPU errata. */
+ unsigned int erratumcount;
+ elf32_vfp11_erratum_list *erratumlist;
+ /* Information about unwind tables. */
+ union
+ {
+ /* Unwind info attached to a text section. */
+ struct
+ {
+ asection *arm_exidx_sec;
+ } text;
+
+ /* Unwind info attached to an .ARM.exidx section. */
+ struct
+ {
+ arm_unwind_table_edit *unwind_edit_list;
+ arm_unwind_table_edit *unwind_edit_tail;
+ } exidx;
+ } u;
+}
+_arm_elf_section_data;
+
+#define elf32_arm_section_data(sec) \
+ ((_arm_elf_section_data *) elf_section_data (sec))
+
+/* A fix which might be required for Cortex-A8 Thumb-2 branch/TLB erratum.
+ These fixes are subject to a relaxation procedure (in elf32_arm_size_stubs),
+ so may be created multiple times: we use an array of these entries whilst
+ relaxing which we can refresh easily, then create stubs for each potentially
+ erratum-triggering instruction once we've settled on a solution. */
+
+struct a8_erratum_fix
+{
+ bfd *input_bfd;
+ asection *section;
+ bfd_vma offset;
+ bfd_vma addend;
+ unsigned long orig_insn;
+ char *stub_name;
+ enum elf32_arm_stub_type stub_type;
+ enum arm_st_branch_type branch_type;
+};
+
+/* A table of relocs applied to branches which might trigger Cortex-A8
+ erratum. */
+
+struct a8_erratum_reloc
+{
+ bfd_vma from;
+ bfd_vma destination;
+ struct elf32_arm_link_hash_entry *hash;
+ const char *sym_name;
+ unsigned int r_type;
+ enum arm_st_branch_type branch_type;
+ bfd_boolean non_a8_stub;
+};
+
+/* The size of the thread control block. */
+#define TCB_SIZE 8
+
+/* ARM-specific information about a PLT entry, over and above the usual
+ gotplt_union. */
+struct arm_plt_info
+{
+ /* We reference count Thumb references to a PLT entry separately,
+ so that we can emit the Thumb trampoline only if needed. */
+ bfd_signed_vma thumb_refcount;
+
+ /* Some references from Thumb code may be eliminated by BL->BLX
+ conversion, so record them separately. */
+ bfd_signed_vma maybe_thumb_refcount;
+
+ /* How many of the recorded PLT accesses were from non-call relocations.
+ This information is useful when deciding whether anything takes the
+ address of an STT_GNU_IFUNC PLT. A value of 0 means that all
+ non-call references to the function should resolve directly to the
+ real runtime target. */
+ unsigned int noncall_refcount;
+
+ /* Since PLT entries have variable size if the Thumb prologue is
+ used, we need to record the index into .got.plt instead of
+ recomputing it from the PLT offset. */
+ bfd_signed_vma got_offset;
+};
+
+/* Information about an .iplt entry for a local STT_GNU_IFUNC symbol. */
+struct arm_local_iplt_info
+{
+ /* The information that is usually found in the generic ELF part of
+ the hash table entry. */
+ union gotplt_union root;
+
+ /* The information that is usually found in the ARM-specific part of
+ the hash table entry. */
+ struct arm_plt_info arm;
+
+ /* A list of all potential dynamic relocations against this symbol. */
+ struct elf_dyn_relocs *dyn_relocs;
+};
+
+struct elf_arm_obj_tdata
+{
+ struct elf_obj_tdata root;
+
+ /* tls_type for each local got entry. */
+ char *local_got_tls_type;
+
+ /* GOTPLT entries for TLS descriptors. */
+ bfd_vma *local_tlsdesc_gotent;
+
+ /* Information for local symbols that need entries in .iplt. */
+ struct arm_local_iplt_info **local_iplt;
+
+ /* Zero to warn when linking objects with incompatible enum sizes. */
+ int no_enum_size_warning;
+
+ /* Zero to warn when linking objects with incompatible wchar_t sizes. */
+ int no_wchar_size_warning;
+};
+
+#define elf_arm_tdata(bfd) \
+ ((struct elf_arm_obj_tdata *) (bfd)->tdata.any)
+
+#define elf32_arm_local_got_tls_type(bfd) \
+ (elf_arm_tdata (bfd)->local_got_tls_type)
+
+#define elf32_arm_local_tlsdesc_gotent(bfd) \
+ (elf_arm_tdata (bfd)->local_tlsdesc_gotent)
+
+#define elf32_arm_local_iplt(bfd) \
+ (elf_arm_tdata (bfd)->local_iplt)
+
+#define is_arm_elf(bfd) \
+ (bfd_get_flavour (bfd) == bfd_target_elf_flavour \
+ && elf_tdata (bfd) != NULL \
+ && elf_object_id (bfd) == ARM_ELF_DATA)
+
+static bfd_boolean
+elf32_arm_mkobject (bfd *abfd)
+{
+ return bfd_elf_allocate_object (abfd, sizeof (struct elf_arm_obj_tdata),
+ ARM_ELF_DATA);
+}
+
+#define elf32_arm_hash_entry(ent) ((struct elf32_arm_link_hash_entry *)(ent))
+
+/* Arm ELF linker hash entry. */
+struct elf32_arm_link_hash_entry
+{
+ struct elf_link_hash_entry root;
+
+ /* Track dynamic relocs copied for this symbol. */
+ struct elf_dyn_relocs *dyn_relocs;
+
+ /* ARM-specific PLT information. */
+ struct arm_plt_info plt;
+
+#define GOT_UNKNOWN 0
+#define GOT_NORMAL 1
+#define GOT_TLS_GD 2
+#define GOT_TLS_IE 4
+#define GOT_TLS_GDESC 8
+#define GOT_TLS_GD_ANY_P(type) ((type & GOT_TLS_GD) || (type & GOT_TLS_GDESC))
+ unsigned int tls_type : 8;
+
+ /* True if the symbol's PLT entry is in .iplt rather than .plt. */
+ unsigned int is_iplt : 1;
+
+ unsigned int unused : 23;
+
+ /* Offset of the GOTPLT entry reserved for the TLS descriptor,
+ starting at the end of the jump table. */
+ bfd_vma tlsdesc_got;
+
+ /* The symbol marking the real symbol location for exported thumb
+ symbols with Arm stubs. */
+ struct elf_link_hash_entry *export_glue;
+
+ /* A pointer to the most recently used stub hash entry against this
+ symbol. */
+ struct elf32_arm_stub_hash_entry *stub_cache;
+};
+
+/* Traverse an arm ELF linker hash table. */
+#define elf32_arm_link_hash_traverse(table, func, info) \
+ (elf_link_hash_traverse \
+ (&(table)->root, \
+ (bfd_boolean (*) (struct elf_link_hash_entry *, void *)) (func), \
+ (info)))
+
+/* Get the ARM elf linker hash table from a link_info structure. */
+#define elf32_arm_hash_table(info) \
+ (elf_hash_table_id ((struct elf_link_hash_table *) ((info)->hash)) \
+ == ARM_ELF_DATA ? ((struct elf32_arm_link_hash_table *) ((info)->hash)) : NULL)
+
+#define arm_stub_hash_lookup(table, string, create, copy) \
+ ((struct elf32_arm_stub_hash_entry *) \
+ bfd_hash_lookup ((table), (string), (create), (copy)))
+
+/* Array to keep track of which stub sections have been created, and
+ information on stub grouping. */
+struct map_stub
+{
+ /* This is the section to which stubs in the group will be
+ attached. */
+ asection *link_sec;
+ /* The stub section. */
+ asection *stub_sec;
+};
+
+#define elf32_arm_compute_jump_table_size(htab) \
+ ((htab)->next_tls_desc_index * 4)
+
+/* 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 containing the Thumb-to-ARM glue. */
+ bfd_size_type thumb_glue_size;
+
+ /* The size in bytes of the section containing the ARM-to-Thumb glue. */
+ bfd_size_type arm_glue_size;
+
+ /* The size in bytes of section containing the ARMv4 BX veneers. */
+ bfd_size_type bx_glue_size;
+
+ /* Offsets of ARMv4 BX veneers. Bit1 set if present, and Bit0 set when
+ veneer has been populated. */
+ bfd_vma bx_glue_offset[15];
+
+ /* The size in bytes of the section containing glue for VFP11 erratum
+ veneers. */
+ bfd_size_type vfp11_erratum_glue_size;
+
+ /* A table of fix locations for Cortex-A8 Thumb-2 branch/TLB erratum. This
+ holds Cortex-A8 erratum fix locations between elf32_arm_size_stubs() and
+ elf32_arm_write_section(). */
+ struct a8_erratum_fix *a8_erratum_fixes;
+ unsigned int num_a8_erratum_fixes;
+
+ /* An arbitrary input BFD chosen to hold the glue sections. */
+ bfd * bfd_of_glue_owner;
+
+ /* Nonzero to output a BE8 image. */
+ int byteswap_code;
+
+ /* Zero if R_ARM_TARGET1 means R_ARM_ABS32.
+ Nonzero if R_ARM_TARGET1 means R_ARM_REL32. */
+ int target1_is_rel;
+
+ /* The relocation to use for R_ARM_TARGET2 relocations. */
+ int target2_reloc;
+
+ /* 0 = Ignore R_ARM_V4BX.
+ 1 = Convert BX to MOV PC.
+ 2 = Generate v4 interworing stubs. */
+ int fix_v4bx;
+
+ /* Whether we should fix the Cortex-A8 Thumb-2 branch/TLB erratum. */
+ int fix_cortex_a8;
+
+ /* Whether we should fix the ARM1176 BLX immediate issue. */
+ int fix_arm1176;
+
+ /* Nonzero if the ARM/Thumb BLX instructions are available for use. */
+ int use_blx;
+
+ /* What sort of code sequences we should look for which may trigger the
+ VFP11 denorm erratum. */
+ bfd_arm_vfp11_fix vfp11_fix;
+
+ /* Global counter for the number of fixes we have emitted. */
+ int num_vfp11_fixes;
+
+ /* Nonzero to force PIC branch veneers. */
+ int pic_veneer;
+
+ /* The number of bytes in the initial entry in the PLT. */
+ bfd_size_type plt_header_size;
+
+ /* The number of bytes in the subsequent PLT etries. */
+ bfd_size_type plt_entry_size;
+
+ /* True if the target system is VxWorks. */
+ int vxworks_p;
+
+ /* True if the target system is Symbian OS. */
+ int symbian_p;
+
+ /* True if the target system is Native Client. */
+ int nacl_p;
+
+ /* True if the target uses REL relocations. */
+ int use_rel;
+
+ /* The index of the next unused R_ARM_TLS_DESC slot in .rel.plt. */
+ bfd_vma next_tls_desc_index;
+
+ /* How many R_ARM_TLS_DESC relocations were generated so far. */
+ bfd_vma num_tls_desc;
+
+ /* Short-cuts to get to dynamic linker sections. */
+ asection *sdynbss;
+ asection *srelbss;
+
+ /* The (unloaded but important) VxWorks .rela.plt.unloaded section. */
+ asection *srelplt2;
+
+ /* The offset into splt of the PLT entry for the TLS descriptor
+ resolver. Special values are 0, if not necessary (or not found
+ to be necessary yet), and -1 if needed but not determined
+ yet. */
+ bfd_vma dt_tlsdesc_plt;
+
+ /* The offset into sgot of the GOT entry used by the PLT entry
+ above. */
+ bfd_vma dt_tlsdesc_got;
+
+ /* Offset in .plt section of tls_arm_trampoline. */
+ bfd_vma tls_trampoline;
+
+ /* Data for R_ARM_TLS_LDM32 relocations. */
+ union
+ {
+ bfd_signed_vma refcount;
+ bfd_vma offset;
+ } tls_ldm_got;
+
+ /* Small local sym cache. */
+ struct sym_cache sym_cache;
+
+ /* For convenience in allocate_dynrelocs. */
+ bfd * obfd;
+
+ /* The amount of space used by the reserved portion of the sgotplt
+ section, plus whatever space is used by the jump slots. */
+ bfd_vma sgotplt_jump_table_size;
+
+ /* The stub hash table. */
+ struct bfd_hash_table stub_hash_table;
+
+ /* Linker stub bfd. */
+ bfd *stub_bfd;
+
+ /* Linker call-backs. */
+ asection * (*add_stub_section) (const char *, asection *, unsigned int);
+ void (*layout_sections_again) (void);
+
+ /* Array to keep track of which stub sections have been created, and
+ information on stub grouping. */
+ struct map_stub *stub_group;
+
+ /* Number of elements in stub_group. */
+ int top_id;
+
+ /* Assorted information used by elf32_arm_size_stubs. */
+ unsigned int bfd_count;
+ int top_index;
+ asection **input_list;
+};
+
+/* Create an entry in an ARM ELF linker hash table. */
+
+static struct bfd_hash_entry *
+elf32_arm_link_hash_newfunc (struct bfd_hash_entry * entry,
+ struct bfd_hash_table * table,
+ const char * string)
+{
+ struct elf32_arm_link_hash_entry * ret =
+ (struct elf32_arm_link_hash_entry *) entry;
+
+ /* Allocate the structure if it has not already been allocated by a
+ subclass. */
+ if (ret == NULL)
+ ret = (struct elf32_arm_link_hash_entry *)
+ bfd_hash_allocate (table, sizeof (struct elf32_arm_link_hash_entry));
+ if (ret == NULL)
+ return (struct bfd_hash_entry *) ret;
+
+ /* Call the allocation method of the superclass. */
+ ret = ((struct elf32_arm_link_hash_entry *)
+ _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry *) ret,
+ table, string));
+ if (ret != NULL)
+ {
+ ret->dyn_relocs = NULL;
+ ret->tls_type = GOT_UNKNOWN;
+ ret->tlsdesc_got = (bfd_vma) -1;
+ ret->plt.thumb_refcount = 0;
+ ret->plt.maybe_thumb_refcount = 0;
+ ret->plt.noncall_refcount = 0;
+ ret->plt.got_offset = -1;
+ ret->is_iplt = FALSE;
+ ret->export_glue = NULL;
+
+ ret->stub_cache = NULL;
+ }
+
+ return (struct bfd_hash_entry *) ret;
+}
+
+/* Ensure that we have allocated bookkeeping structures for ABFD's local
+ symbols. */
+
+static bfd_boolean
+elf32_arm_allocate_local_sym_info (bfd *abfd)
+{
+ if (elf_local_got_refcounts (abfd) == NULL)
+ {
+ bfd_size_type num_syms;
+ bfd_size_type size;
+ char *data;
+
+ num_syms = elf_tdata (abfd)->symtab_hdr.sh_info;
+ size = num_syms * (sizeof (bfd_signed_vma)
+ + sizeof (struct arm_local_iplt_info *)
+ + sizeof (bfd_vma)
+ + sizeof (char));
+ data = bfd_zalloc (abfd, size);
+ if (data == NULL)
+ return FALSE;
+
+ elf_local_got_refcounts (abfd) = (bfd_signed_vma *) data;
+ data += num_syms * sizeof (bfd_signed_vma);
+
+ elf32_arm_local_iplt (abfd) = (struct arm_local_iplt_info **) data;
+ data += num_syms * sizeof (struct arm_local_iplt_info *);
+
+ elf32_arm_local_tlsdesc_gotent (abfd) = (bfd_vma *) data;
+ data += num_syms * sizeof (bfd_vma);
+
+ elf32_arm_local_got_tls_type (abfd) = data;
+ }
+ return TRUE;
+}
+
+/* Return the .iplt information for local symbol R_SYMNDX, which belongs
+ to input bfd ABFD. Create the information if it doesn't already exist.
+ Return null if an allocation fails. */
+
+static struct arm_local_iplt_info *
+elf32_arm_create_local_iplt (bfd *abfd, unsigned long r_symndx)
+{
+ struct arm_local_iplt_info **ptr;
+
+ if (!elf32_arm_allocate_local_sym_info (abfd))
+ return NULL;
+
+ BFD_ASSERT (r_symndx < elf_tdata (abfd)->symtab_hdr.sh_info);
+ ptr = &elf32_arm_local_iplt (abfd)[r_symndx];
+ if (*ptr == NULL)
+ *ptr = bfd_zalloc (abfd, sizeof (**ptr));
+ return *ptr;
+}
+
+/* Try to obtain PLT information for the symbol with index R_SYMNDX
+ in ABFD's symbol table. If the symbol is global, H points to its
+ hash table entry, otherwise H is null.
+
+ Return true if the symbol does have PLT information. When returning
+ true, point *ROOT_PLT at the target-independent reference count/offset
+ union and *ARM_PLT at the ARM-specific information. */
+
+static bfd_boolean
+elf32_arm_get_plt_info (bfd *abfd, struct elf32_arm_link_hash_entry *h,
+ unsigned long r_symndx, union gotplt_union **root_plt,
+ struct arm_plt_info **arm_plt)
+{
+ struct arm_local_iplt_info *local_iplt;
+
+ if (h != NULL)
+ {
+ *root_plt = &h->root.plt;
+ *arm_plt = &h->plt;
+ return TRUE;
+ }
+
+ if (elf32_arm_local_iplt (abfd) == NULL)
+ return FALSE;
+
+ local_iplt = elf32_arm_local_iplt (abfd)[r_symndx];
+ if (local_iplt == NULL)
+ return FALSE;
+
+ *root_plt = &local_iplt->root;
+ *arm_plt = &local_iplt->arm;
+ return TRUE;
+}
+
+/* Return true if the PLT described by ARM_PLT requires a Thumb stub
+ before it. */
+
+static bfd_boolean
+elf32_arm_plt_needs_thumb_stub_p (struct bfd_link_info *info,
+ struct arm_plt_info *arm_plt)
+{
+ struct elf32_arm_link_hash_table *htab;
+
+ htab = elf32_arm_hash_table (info);
+ return (arm_plt->thumb_refcount != 0
+ || (!htab->use_blx && arm_plt->maybe_thumb_refcount != 0));
+}
+
+/* Return a pointer to the head of the dynamic reloc list that should
+ be used for local symbol ISYM, which is symbol number R_SYMNDX in
+ ABFD's symbol table. Return null if an error occurs. */
+
+static struct elf_dyn_relocs **
+elf32_arm_get_local_dynreloc_list (bfd *abfd, unsigned long r_symndx,
+ Elf_Internal_Sym *isym)
+{
+ if (ELF32_ST_TYPE (isym->st_info) == STT_GNU_IFUNC)
+ {
+ struct arm_local_iplt_info *local_iplt;
+
+ local_iplt = elf32_arm_create_local_iplt (abfd, r_symndx);
+ if (local_iplt == NULL)
+ return NULL;
+ return &local_iplt->dyn_relocs;
+ }
+ else
+ {
+ /* Track dynamic relocs needed for local syms too.
+ We really need local syms available to do this
+ easily. Oh well. */
+ asection *s;
+ void *vpp;
+
+ s = bfd_section_from_elf_index (abfd, isym->st_shndx);
+ if (s == NULL)
+ abort ();
+
+ vpp = &elf_section_data (s)->local_dynrel;
+ return (struct elf_dyn_relocs **) vpp;
+ }
+}
+
+/* Initialize an entry in the stub hash table. */
+
+static struct bfd_hash_entry *
+stub_hash_newfunc (struct bfd_hash_entry *entry,
+ struct bfd_hash_table *table,
+ const char *string)
+{
+ /* Allocate the structure if it has not already been allocated by a
+ subclass. */
+ if (entry == NULL)
+ {
+ entry = (struct bfd_hash_entry *)
+ bfd_hash_allocate (table, sizeof (struct elf32_arm_stub_hash_entry));
+ if (entry == NULL)
+ return entry;
+ }
+
+ /* Call the allocation method of the superclass. */
+ entry = bfd_hash_newfunc (entry, table, string);
+ if (entry != NULL)
+ {
+ struct elf32_arm_stub_hash_entry *eh;
+
+ /* Initialize the local fields. */
+ eh = (struct elf32_arm_stub_hash_entry *) entry;
+ eh->stub_sec = NULL;
+ eh->stub_offset = 0;
+ eh->target_value = 0;
+ eh->target_section = NULL;
+ eh->target_addend = 0;
+ eh->orig_insn = 0;
+ eh->stub_type = arm_stub_none;
+ eh->stub_size = 0;
+ eh->stub_template = NULL;
+ eh->stub_template_size = 0;
+ eh->h = NULL;
+ eh->id_sec = NULL;
+ eh->output_name = NULL;
+ }
+
+ return entry;
+}
+
+/* Create .got, .gotplt, and .rel(a).got sections in DYNOBJ, and set up
+ shortcuts to them in our hash table. */
+
+static bfd_boolean
+create_got_section (bfd *dynobj, struct bfd_link_info *info)
+{
+ struct elf32_arm_link_hash_table *htab;
+
+ htab = elf32_arm_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ /* BPABI objects never have a GOT, or associated sections. */
+ if (htab->symbian_p)
+ return TRUE;
+
+ if (! _bfd_elf_create_got_section (dynobj, info))
+ return FALSE;
+
+ return TRUE;
+}
+
+/* Create the .iplt, .rel(a).iplt and .igot.plt sections. */
+
+static bfd_boolean
+create_ifunc_sections (struct bfd_link_info *info)
+{
+ struct elf32_arm_link_hash_table *htab;
+ const struct elf_backend_data *bed;
+ bfd *dynobj;
+ asection *s;
+ flagword flags;
+
+ htab = elf32_arm_hash_table (info);
+ dynobj = htab->root.dynobj;
+ bed = get_elf_backend_data (dynobj);
+ flags = bed->dynamic_sec_flags;
+
+ if (htab->root.iplt == NULL)
+ {
+ s = bfd_make_section_anyway_with_flags (dynobj, ".iplt",
+ flags | SEC_READONLY | SEC_CODE);
+ if (s == NULL
+ || !bfd_set_section_alignment (dynobj, s, bed->plt_alignment))
+ return FALSE;
+ htab->root.iplt = s;
+ }
+
+ if (htab->root.irelplt == NULL)
+ {
+ s = bfd_make_section_anyway_with_flags (dynobj,
+ RELOC_SECTION (htab, ".iplt"),
+ flags | SEC_READONLY);
+ if (s == NULL
+ || !bfd_set_section_alignment (dynobj, s, bed->s->log_file_align))
+ return FALSE;
+ htab->root.irelplt = s;
+ }
+
+ if (htab->root.igotplt == NULL)
+ {
+ s = bfd_make_section_anyway_with_flags (dynobj, ".igot.plt", flags);
+ if (s == NULL
+ || !bfd_set_section_alignment (dynobj, s, bed->s->log_file_align))
+ return FALSE;
+ htab->root.igotplt = s;
+ }
+ return TRUE;
+}
+
+/* Determine if we're dealing with a Thumb only architecture. */
+
+static bfd_boolean
+using_thumb_only (struct elf32_arm_link_hash_table *globals)
+{
+ int arch = bfd_elf_get_obj_attr_int (globals->obfd, OBJ_ATTR_PROC,
+ Tag_CPU_arch);
+ int profile;
+
+ if (arch == TAG_CPU_ARCH_V6_M || arch == TAG_CPU_ARCH_V6S_M)
+ return TRUE;
+
+ if (arch != TAG_CPU_ARCH_V7 && arch != TAG_CPU_ARCH_V7E_M)
+ return FALSE;
+
+ profile = bfd_elf_get_obj_attr_int (globals->obfd, OBJ_ATTR_PROC,
+ Tag_CPU_arch_profile);
+
+ return profile == 'M';
+}
+
+/* Determine if we're dealing with a Thumb-2 object. */
+
+static bfd_boolean
+using_thumb2 (struct elf32_arm_link_hash_table *globals)
+{
+ int arch = bfd_elf_get_obj_attr_int (globals->obfd, OBJ_ATTR_PROC,
+ Tag_CPU_arch);
+ return arch == TAG_CPU_ARCH_V6T2 || arch >= TAG_CPU_ARCH_V7;
+}
+
+/* Create .plt, .rel(a).plt, .got, .got.plt, .rel(a).got, .dynbss, and
+ .rel(a).bss sections in DYNOBJ, and set up shortcuts to them in our
+ hash table. */
+
+static bfd_boolean
+elf32_arm_create_dynamic_sections (bfd *dynobj, struct bfd_link_info *info)
+{
+ struct elf32_arm_link_hash_table *htab;
+
+ htab = elf32_arm_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ if (!htab->root.sgot && !create_got_section (dynobj, info))
+ return FALSE;
+
+ if (!_bfd_elf_create_dynamic_sections (dynobj, info))
+ return FALSE;
+
+ htab->sdynbss = bfd_get_linker_section (dynobj, ".dynbss");
+ if (!info->shared)
+ htab->srelbss = bfd_get_linker_section (dynobj,
+ RELOC_SECTION (htab, ".bss"));
+
+ if (htab->vxworks_p)
+ {
+ if (!elf_vxworks_create_dynamic_sections (dynobj, info, &htab->srelplt2))
+ return FALSE;
+
+ if (info->shared)
+ {
+ htab->plt_header_size = 0;
+ htab->plt_entry_size
+ = 4 * ARRAY_SIZE (elf32_arm_vxworks_shared_plt_entry);
+ }
+ else
+ {
+ htab->plt_header_size
+ = 4 * ARRAY_SIZE (elf32_arm_vxworks_exec_plt0_entry);
+ htab->plt_entry_size
+ = 4 * ARRAY_SIZE (elf32_arm_vxworks_exec_plt_entry);
+ }
+ }
+ else
+ {
+ /* PR ld/16017
+ Test for thumb only architectures. Note - we cannot just call
+ using_thumb_only() as the attributes in the output bfd have not been
+ initialised at this point, so instead we use the input bfd. */
+ bfd * saved_obfd = htab->obfd;
+
+ htab->obfd = dynobj;
+ if (using_thumb_only (htab))
+ {
+ htab->plt_header_size = 4 * ARRAY_SIZE (elf32_thumb2_plt0_entry);
+ htab->plt_entry_size = 4 * ARRAY_SIZE (elf32_thumb2_plt_entry);
+ }
+ htab->obfd = saved_obfd;
+ }
+
+ if (!htab->root.splt
+ || !htab->root.srelplt
+ || !htab->sdynbss
+ || (!info->shared && !htab->srelbss))
+ abort ();
+
+ return TRUE;
+}
+
+/* Copy the extra info we tack onto an elf_link_hash_entry. */
+
+static void
+elf32_arm_copy_indirect_symbol (struct bfd_link_info *info,
+ struct elf_link_hash_entry *dir,
+ struct elf_link_hash_entry *ind)
+{
+ struct elf32_arm_link_hash_entry *edir, *eind;
+
+ edir = (struct elf32_arm_link_hash_entry *) dir;
+ eind = (struct elf32_arm_link_hash_entry *) ind;
+
+ if (eind->dyn_relocs != NULL)
+ {
+ if (edir->dyn_relocs != NULL)
+ {
+ struct elf_dyn_relocs **pp;
+ struct elf_dyn_relocs *p;
+
+ /* Add reloc counts against the indirect sym to the direct sym
+ list. Merge any entries against the same section. */
+ for (pp = &eind->dyn_relocs; (p = *pp) != NULL; )
+ {
+ struct elf_dyn_relocs *q;
+
+ for (q = edir->dyn_relocs; q != NULL; q = q->next)
+ if (q->sec == p->sec)
+ {
+ q->pc_count += p->pc_count;
+ q->count += p->count;
+ *pp = p->next;
+ break;
+ }
+ if (q == NULL)
+ pp = &p->next;
+ }
+ *pp = edir->dyn_relocs;
+ }
+
+ edir->dyn_relocs = eind->dyn_relocs;
+ eind->dyn_relocs = NULL;
+ }
+
+ if (ind->root.type == bfd_link_hash_indirect)
+ {
+ /* Copy over PLT info. */
+ edir->plt.thumb_refcount += eind->plt.thumb_refcount;
+ eind->plt.thumb_refcount = 0;
+ edir->plt.maybe_thumb_refcount += eind->plt.maybe_thumb_refcount;
+ eind->plt.maybe_thumb_refcount = 0;
+ edir->plt.noncall_refcount += eind->plt.noncall_refcount;
+ eind->plt.noncall_refcount = 0;
+
+ /* We should only allocate a function to .iplt once the final
+ symbol information is known. */
+ BFD_ASSERT (!eind->is_iplt);
+
+ if (dir->got.refcount <= 0)
+ {
+ edir->tls_type = eind->tls_type;
+ eind->tls_type = GOT_UNKNOWN;
+ }
+ }
+
+ _bfd_elf_link_hash_copy_indirect (info, dir, ind);
+}
+
+/* Destroy an ARM elf linker hash table. */
+
+static void
+elf32_arm_link_hash_table_free (bfd *obfd)
+{
+ struct elf32_arm_link_hash_table *ret
+ = (struct elf32_arm_link_hash_table *) obfd->link.hash;
+
+ bfd_hash_table_free (&ret->stub_hash_table);
+ _bfd_elf_link_hash_table_free (obfd);
+}
+
+/* Create an ARM elf linker hash table. */
+
+static struct bfd_link_hash_table *
+elf32_arm_link_hash_table_create (bfd *abfd)
+{
+ struct elf32_arm_link_hash_table *ret;
+ bfd_size_type amt = sizeof (struct elf32_arm_link_hash_table);
+
+ ret = (struct elf32_arm_link_hash_table *) bfd_zmalloc (amt);
+ if (ret == NULL)
+ return NULL;
+
+ if (!_bfd_elf_link_hash_table_init (& ret->root, abfd,
+ elf32_arm_link_hash_newfunc,
+ sizeof (struct elf32_arm_link_hash_entry),
+ ARM_ELF_DATA))
+ {
+ free (ret);
+ return NULL;
+ }
+
+ ret->vfp11_fix = BFD_ARM_VFP11_FIX_NONE;
+#ifdef FOUR_WORD_PLT
+ ret->plt_header_size = 16;
+ ret->plt_entry_size = 16;
+#else
+ ret->plt_header_size = 20;
+ ret->plt_entry_size = elf32_arm_use_long_plt_entry ? 16 : 12;
+#endif
+ ret->use_rel = 1;
+ ret->obfd = abfd;
+
+ if (!bfd_hash_table_init (&ret->stub_hash_table, stub_hash_newfunc,
+ sizeof (struct elf32_arm_stub_hash_entry)))
+ {
+ _bfd_elf_link_hash_table_free (abfd);
+ return NULL;
+ }
+ ret->root.root.hash_table_free = elf32_arm_link_hash_table_free;
+
+ return &ret->root.root;
+}
+
+/* Determine what kind of NOPs are available. */
+
+static bfd_boolean
+arch_has_arm_nop (struct elf32_arm_link_hash_table *globals)
+{
+ const int arch = bfd_elf_get_obj_attr_int (globals->obfd, OBJ_ATTR_PROC,
+ Tag_CPU_arch);
+ return arch == TAG_CPU_ARCH_V6T2
+ || arch == TAG_CPU_ARCH_V6K
+ || arch == TAG_CPU_ARCH_V7
+ || arch == TAG_CPU_ARCH_V7E_M;
+}
+
+static bfd_boolean
+arch_has_thumb2_nop (struct elf32_arm_link_hash_table *globals)
+{
+ const int arch = bfd_elf_get_obj_attr_int (globals->obfd, OBJ_ATTR_PROC,
+ Tag_CPU_arch);
+ return (arch == TAG_CPU_ARCH_V6T2 || arch == TAG_CPU_ARCH_V7
+ || arch == TAG_CPU_ARCH_V7E_M);
+}
+
+static bfd_boolean
+arm_stub_is_thumb (enum elf32_arm_stub_type stub_type)
+{
+ switch (stub_type)
+ {
+ case arm_stub_long_branch_thumb_only:
+ case arm_stub_long_branch_v4t_thumb_arm:
+ case arm_stub_short_branch_v4t_thumb_arm:
+ case arm_stub_long_branch_v4t_thumb_arm_pic:
+ case arm_stub_long_branch_v4t_thumb_tls_pic:
+ case arm_stub_long_branch_thumb_only_pic:
+ return TRUE;
+ case arm_stub_none:
+ BFD_FAIL ();
+ return FALSE;
+ break;
+ default:
+ return FALSE;
+ }
+}
+
+/* Determine the type of stub needed, if any, for a call. */
+
+static enum elf32_arm_stub_type
+arm_type_of_stub (struct bfd_link_info *info,
+ asection *input_sec,
+ const Elf_Internal_Rela *rel,
+ unsigned char st_type,
+ enum arm_st_branch_type *actual_branch_type,
+ struct elf32_arm_link_hash_entry *hash,
+ bfd_vma destination,
+ asection *sym_sec,
+ bfd *input_bfd,
+ const char *name)
+{
+ bfd_vma location;
+ bfd_signed_vma branch_offset;
+ unsigned int r_type;
+ struct elf32_arm_link_hash_table * globals;
+ int thumb2;
+ int thumb_only;
+ enum elf32_arm_stub_type stub_type = arm_stub_none;
+ int use_plt = 0;
+ enum arm_st_branch_type branch_type = *actual_branch_type;
+ union gotplt_union *root_plt;
+ struct arm_plt_info *arm_plt;
+
+ if (branch_type == ST_BRANCH_LONG)
+ return stub_type;
+
+ globals = elf32_arm_hash_table (info);
+ if (globals == NULL)
+ return stub_type;
+
+ thumb_only = using_thumb_only (globals);
+
+ thumb2 = using_thumb2 (globals);
+
+ /* Determine where the call point is. */
+ location = (input_sec->output_offset
+ + input_sec->output_section->vma
+ + rel->r_offset);
+
+ r_type = ELF32_R_TYPE (rel->r_info);
+
+ /* ST_BRANCH_TO_ARM is nonsense to thumb-only targets when we
+ are considering a function call relocation. */
+ if (thumb_only && (r_type == R_ARM_THM_CALL || r_type == R_ARM_THM_JUMP24
+ || r_type == R_ARM_THM_JUMP19)
+ && branch_type == ST_BRANCH_TO_ARM)
+ branch_type = ST_BRANCH_TO_THUMB;
+
+ /* For TLS call relocs, it is the caller's responsibility to provide
+ the address of the appropriate trampoline. */
+ if (r_type != R_ARM_TLS_CALL
+ && r_type != R_ARM_THM_TLS_CALL
+ && elf32_arm_get_plt_info (input_bfd, hash, ELF32_R_SYM (rel->r_info),
+ &root_plt, &arm_plt)
+ && root_plt->offset != (bfd_vma) -1)
+ {
+ asection *splt;
+
+ if (hash == NULL || hash->is_iplt)
+ splt = globals->root.iplt;
+ else
+ splt = globals->root.splt;
+ if (splt != NULL)
+ {
+ use_plt = 1;
+
+ /* Note when dealing with PLT entries: the main PLT stub is in
+ ARM mode, so if the branch is in Thumb mode, another
+ Thumb->ARM stub will be inserted later just before the ARM
+ PLT stub. We don't take this extra distance into account
+ here, because if a long branch stub is needed, we'll add a
+ Thumb->Arm one and branch directly to the ARM PLT entry
+ because it avoids spreading offset corrections in several
+ places. */
+
+ destination = (splt->output_section->vma
+ + splt->output_offset
+ + root_plt->offset);
+ st_type = STT_FUNC;
+ branch_type = ST_BRANCH_TO_ARM;
+ }
+ }
+ /* Calls to STT_GNU_IFUNC symbols should go through a PLT. */
+ BFD_ASSERT (st_type != STT_GNU_IFUNC);
+
+ branch_offset = (bfd_signed_vma)(destination - location);
+
+ if (r_type == R_ARM_THM_CALL || r_type == R_ARM_THM_JUMP24
+ || r_type == R_ARM_THM_TLS_CALL || r_type == R_ARM_THM_JUMP19)
+ {
+ /* Handle cases where:
+ - this call goes too far (different Thumb/Thumb2 max
+ distance)
+ - it's a Thumb->Arm call and blx is not available, or it's a
+ Thumb->Arm branch (not bl). A stub is needed in this case,
+ but only if this call is not through a PLT entry. Indeed,
+ PLT stubs handle mode switching already.
+ */
+ if ((!thumb2
+ && (branch_offset > THM_MAX_FWD_BRANCH_OFFSET
+ || (branch_offset < THM_MAX_BWD_BRANCH_OFFSET)))
+ || (thumb2
+ && (branch_offset > THM2_MAX_FWD_BRANCH_OFFSET
+ || (branch_offset < THM2_MAX_BWD_BRANCH_OFFSET)))
+ || (thumb2
+ && (branch_offset > THM2_MAX_FWD_COND_BRANCH_OFFSET
+ || (branch_offset < THM2_MAX_BWD_COND_BRANCH_OFFSET))
+ && (r_type == R_ARM_THM_JUMP19))
+ || (branch_type == ST_BRANCH_TO_ARM
+ && (((r_type == R_ARM_THM_CALL
+ || r_type == R_ARM_THM_TLS_CALL) && !globals->use_blx)
+ || (r_type == R_ARM_THM_JUMP24)
+ || (r_type == R_ARM_THM_JUMP19))
+ && !use_plt))
+ {
+ if (branch_type == ST_BRANCH_TO_THUMB)
+ {
+ /* Thumb to thumb. */
+ if (!thumb_only)
+ {
+ stub_type = (info->shared | globals->pic_veneer)
+ /* PIC stubs. */
+ ? ((globals->use_blx
+ && (r_type == R_ARM_THM_CALL))
+ /* V5T and above. Stub starts with ARM code, so
+ we must be able to switch mode before
+ reaching it, which is only possible for 'bl'
+ (ie R_ARM_THM_CALL relocation). */
+ ? arm_stub_long_branch_any_thumb_pic
+ /* On V4T, use Thumb code only. */
+ : arm_stub_long_branch_v4t_thumb_thumb_pic)
+
+ /* non-PIC stubs. */
+ : ((globals->use_blx
+ && (r_type == R_ARM_THM_CALL))
+ /* V5T and above. */
+ ? arm_stub_long_branch_any_any
+ /* V4T. */
+ : arm_stub_long_branch_v4t_thumb_thumb);
+ }
+ else
+ {
+ stub_type = (info->shared | globals->pic_veneer)
+ /* PIC stub. */
+ ? arm_stub_long_branch_thumb_only_pic
+ /* non-PIC stub. */
+ : arm_stub_long_branch_thumb_only;
+ }
+ }
+ else
+ {
+ /* Thumb to arm. */
+ if (sym_sec != NULL
+ && sym_sec->owner != NULL
+ && !INTERWORK_FLAG (sym_sec->owner))
+ {
+ (*_bfd_error_handler)
+ (_("%B(%s): warning: interworking not enabled.\n"
+ " first occurrence: %B: Thumb call to ARM"),
+ sym_sec->owner, input_bfd, name);
+ }
+
+ stub_type =
+ (info->shared | globals->pic_veneer)
+ /* PIC stubs. */
+ ? (r_type == R_ARM_THM_TLS_CALL
+ /* TLS PIC stubs. */
+ ? (globals->use_blx ? arm_stub_long_branch_any_tls_pic
+ : arm_stub_long_branch_v4t_thumb_tls_pic)
+ : ((globals->use_blx && r_type == R_ARM_THM_CALL)
+ /* V5T PIC and above. */
+ ? arm_stub_long_branch_any_arm_pic
+ /* V4T PIC stub. */
+ : arm_stub_long_branch_v4t_thumb_arm_pic))
+
+ /* non-PIC stubs. */
+ : ((globals->use_blx && r_type == R_ARM_THM_CALL)
+ /* V5T and above. */
+ ? arm_stub_long_branch_any_any
+ /* V4T. */
+ : arm_stub_long_branch_v4t_thumb_arm);
+
+ /* Handle v4t short branches. */
+ if ((stub_type == arm_stub_long_branch_v4t_thumb_arm)
+ && (branch_offset <= THM_MAX_FWD_BRANCH_OFFSET)
+ && (branch_offset >= THM_MAX_BWD_BRANCH_OFFSET))
+ stub_type = arm_stub_short_branch_v4t_thumb_arm;
+ }
+ }
+ }
+ else if (r_type == R_ARM_CALL
+ || r_type == R_ARM_JUMP24
+ || r_type == R_ARM_PLT32
+ || r_type == R_ARM_TLS_CALL)
+ {
+ if (branch_type == ST_BRANCH_TO_THUMB)
+ {
+ /* Arm to thumb. */
+
+ if (sym_sec != NULL
+ && sym_sec->owner != NULL
+ && !INTERWORK_FLAG (sym_sec->owner))
+ {
+ (*_bfd_error_handler)
+ (_("%B(%s): warning: interworking not enabled.\n"
+ " first occurrence: %B: ARM call to Thumb"),
+ sym_sec->owner, input_bfd, name);
+ }
+
+ /* We have an extra 2-bytes reach because of
+ the mode change (bit 24 (H) of BLX encoding). */
+ if (branch_offset > (ARM_MAX_FWD_BRANCH_OFFSET + 2)
+ || (branch_offset < ARM_MAX_BWD_BRANCH_OFFSET)
+ || (r_type == R_ARM_CALL && !globals->use_blx)
+ || (r_type == R_ARM_JUMP24)
+ || (r_type == R_ARM_PLT32))
+ {
+ stub_type = (info->shared | globals->pic_veneer)
+ /* PIC stubs. */
+ ? ((globals->use_blx)
+ /* V5T and above. */
+ ? arm_stub_long_branch_any_thumb_pic
+ /* V4T stub. */
+ : arm_stub_long_branch_v4t_arm_thumb_pic)
+
+ /* non-PIC stubs. */
+ : ((globals->use_blx)
+ /* V5T and above. */
+ ? arm_stub_long_branch_any_any
+ /* V4T. */
+ : arm_stub_long_branch_v4t_arm_thumb);
+ }
+ }
+ else
+ {
+ /* Arm to arm. */
+ if (branch_offset > ARM_MAX_FWD_BRANCH_OFFSET
+ || (branch_offset < ARM_MAX_BWD_BRANCH_OFFSET))
+ {
+ stub_type =
+ (info->shared | globals->pic_veneer)
+ /* PIC stubs. */
+ ? (r_type == R_ARM_TLS_CALL
+ /* TLS PIC Stub. */
+ ? arm_stub_long_branch_any_tls_pic
+ : (globals->nacl_p
+ ? arm_stub_long_branch_arm_nacl_pic
+ : arm_stub_long_branch_any_arm_pic))
+ /* non-PIC stubs. */
+ : (globals->nacl_p
+ ? arm_stub_long_branch_arm_nacl
+ : arm_stub_long_branch_any_any);
+ }
+ }
+ }
+
+ /* If a stub is needed, record the actual destination type. */
+ if (stub_type != arm_stub_none)
+ *actual_branch_type = branch_type;
+
+ return stub_type;
+}
+
+/* Build a name for an entry in the stub hash table. */
+
+static char *
+elf32_arm_stub_name (const asection *input_section,
+ const asection *sym_sec,
+ const struct elf32_arm_link_hash_entry *hash,
+ const Elf_Internal_Rela *rel,
+ enum elf32_arm_stub_type stub_type)
+{
+ char *stub_name;
+ bfd_size_type len;
+
+ if (hash)
+ {
+ len = 8 + 1 + strlen (hash->root.root.root.string) + 1 + 8 + 1 + 2 + 1;
+ stub_name = (char *) bfd_malloc (len);
+ if (stub_name != NULL)
+ sprintf (stub_name, "%08x_%s+%x_%d",
+ input_section->id & 0xffffffff,
+ hash->root.root.root.string,
+ (int) rel->r_addend & 0xffffffff,
+ (int) stub_type);
+ }
+ else
+ {
+ len = 8 + 1 + 8 + 1 + 8 + 1 + 8 + 1 + 2 + 1;
+ stub_name = (char *) bfd_malloc (len);
+ if (stub_name != NULL)
+ sprintf (stub_name, "%08x_%x:%x+%x_%d",
+ input_section->id & 0xffffffff,
+ sym_sec->id & 0xffffffff,
+ ELF32_R_TYPE (rel->r_info) == R_ARM_TLS_CALL
+ || ELF32_R_TYPE (rel->r_info) == R_ARM_THM_TLS_CALL
+ ? 0 : (int) ELF32_R_SYM (rel->r_info) & 0xffffffff,
+ (int) rel->r_addend & 0xffffffff,
+ (int) stub_type);
+ }
+
+ return stub_name;
+}
+
+/* Look up an entry in the stub hash. Stub entries are cached because
+ creating the stub name takes a bit of time. */
+
+static struct elf32_arm_stub_hash_entry *
+elf32_arm_get_stub_entry (const asection *input_section,
+ const asection *sym_sec,
+ struct elf_link_hash_entry *hash,
+ const Elf_Internal_Rela *rel,
+ struct elf32_arm_link_hash_table *htab,
+ enum elf32_arm_stub_type stub_type)
+{
+ struct elf32_arm_stub_hash_entry *stub_entry;
+ struct elf32_arm_link_hash_entry *h = (struct elf32_arm_link_hash_entry *) hash;
+ const asection *id_sec;
+
+ if ((input_section->flags & SEC_CODE) == 0)
+ return NULL;
+
+ /* If this input section is part of a group of sections sharing one
+ stub section, then use the id of the first section in the group.
+ Stub names need to include a section id, as there may well be
+ more than one stub used to reach say, printf, and we need to
+ distinguish between them. */
+ id_sec = htab->stub_group[input_section->id].link_sec;
+
+ if (h != NULL && h->stub_cache != NULL
+ && h->stub_cache->h == h
+ && h->stub_cache->id_sec == id_sec
+ && h->stub_cache->stub_type == stub_type)
+ {
+ stub_entry = h->stub_cache;
+ }
+ else
+ {
+ char *stub_name;
+
+ stub_name = elf32_arm_stub_name (id_sec, sym_sec, h, rel, stub_type);
+ if (stub_name == NULL)
+ return NULL;
+
+ stub_entry = arm_stub_hash_lookup (&htab->stub_hash_table,
+ stub_name, FALSE, FALSE);
+ if (h != NULL)
+ h->stub_cache = stub_entry;
+
+ free (stub_name);
+ }
+
+ return stub_entry;
+}
+
+/* Find or create a stub section. Returns a pointer to the stub section, and
+ the section to which the stub section will be attached (in *LINK_SEC_P).
+ LINK_SEC_P may be NULL. */
+
+static asection *
+elf32_arm_create_or_find_stub_sec (asection **link_sec_p, asection *section,
+ struct elf32_arm_link_hash_table *htab)
+{
+ asection *link_sec;
+ asection *stub_sec;
+
+ link_sec = htab->stub_group[section->id].link_sec;
+ BFD_ASSERT (link_sec != NULL);
+ stub_sec = htab->stub_group[section->id].stub_sec;
+
+ if (stub_sec == NULL)
+ {
+ stub_sec = htab->stub_group[link_sec->id].stub_sec;
+ if (stub_sec == NULL)
+ {
+ size_t namelen;
+ bfd_size_type len;
+ char *s_name;
+
+ namelen = strlen (link_sec->name);
+ len = namelen + sizeof (STUB_SUFFIX);
+ s_name = (char *) bfd_alloc (htab->stub_bfd, len);
+ if (s_name == NULL)
+ return NULL;
+
+ memcpy (s_name, link_sec->name, namelen);
+ memcpy (s_name + namelen, STUB_SUFFIX, sizeof (STUB_SUFFIX));
+ stub_sec = (*htab->add_stub_section) (s_name, link_sec,
+ htab->nacl_p ? 4 : 3);
+ if (stub_sec == NULL)
+ return NULL;
+ htab->stub_group[link_sec->id].stub_sec = stub_sec;
+ }
+ htab->stub_group[section->id].stub_sec = stub_sec;
+ }
+
+ if (link_sec_p)
+ *link_sec_p = link_sec;
+
+ return stub_sec;
+}
+
+/* Add a new stub entry to the stub hash. Not all fields of the new
+ stub entry are initialised. */
+
+static struct elf32_arm_stub_hash_entry *
+elf32_arm_add_stub (const char *stub_name,
+ asection *section,
+ struct elf32_arm_link_hash_table *htab)
+{
+ asection *link_sec;
+ asection *stub_sec;
+ struct elf32_arm_stub_hash_entry *stub_entry;
+
+ stub_sec = elf32_arm_create_or_find_stub_sec (&link_sec, section, htab);
+ if (stub_sec == NULL)
+ return NULL;
+
+ /* Enter this entry into the linker stub hash table. */
+ stub_entry = arm_stub_hash_lookup (&htab->stub_hash_table, stub_name,
+ TRUE, FALSE);
+ if (stub_entry == NULL)
+ {
+ (*_bfd_error_handler) (_("%s: cannot create stub entry %s"),
+ section->owner,
+ stub_name);
+ return NULL;
+ }
+
+ stub_entry->stub_sec = stub_sec;
+ stub_entry->stub_offset = 0;
+ stub_entry->id_sec = link_sec;
+
+ return stub_entry;
+}
+
+/* Store an Arm insn into an output section not processed by
+ elf32_arm_write_section. */
+
+static void
+put_arm_insn (struct elf32_arm_link_hash_table * htab,
+ bfd * output_bfd, bfd_vma val, void * ptr)
+{
+ if (htab->byteswap_code != bfd_little_endian (output_bfd))
+ bfd_putl32 (val, ptr);
+ else
+ bfd_putb32 (val, ptr);
+}
+
+/* Store a 16-bit Thumb insn into an output section not processed by
+ elf32_arm_write_section. */
+
+static void
+put_thumb_insn (struct elf32_arm_link_hash_table * htab,
+ bfd * output_bfd, bfd_vma val, void * ptr)
+{
+ if (htab->byteswap_code != bfd_little_endian (output_bfd))
+ bfd_putl16 (val, ptr);
+ else
+ bfd_putb16 (val, ptr);
+}
+
+/* If it's possible to change R_TYPE to a more efficient access
+ model, return the new reloc type. */
+
+static unsigned
+elf32_arm_tls_transition (struct bfd_link_info *info, int r_type,
+ struct elf_link_hash_entry *h)
+{
+ int is_local = (h == NULL);
+
+ if (info->shared || (h && h->root.type == bfd_link_hash_undefweak))
+ return r_type;
+
+ /* We do not support relaxations for Old TLS models. */
+ switch (r_type)
+ {
+ case R_ARM_TLS_GOTDESC:
+ case R_ARM_TLS_CALL:
+ case R_ARM_THM_TLS_CALL:
+ case R_ARM_TLS_DESCSEQ:
+ case R_ARM_THM_TLS_DESCSEQ:
+ return is_local ? R_ARM_TLS_LE32 : R_ARM_TLS_IE32;
+ }
+
+ return r_type;
+}
+
+static bfd_reloc_status_type elf32_arm_final_link_relocate
+ (reloc_howto_type *, bfd *, bfd *, asection *, bfd_byte *,
+ Elf_Internal_Rela *, bfd_vma, struct bfd_link_info *, asection *,
+ const char *, unsigned char, enum arm_st_branch_type,
+ struct elf_link_hash_entry *, bfd_boolean *, char **);
+
+static unsigned int
+arm_stub_required_alignment (enum elf32_arm_stub_type stub_type)
+{
+ switch (stub_type)
+ {
+ case arm_stub_a8_veneer_b_cond:
+ case arm_stub_a8_veneer_b:
+ case arm_stub_a8_veneer_bl:
+ return 2;
+
+ case arm_stub_long_branch_any_any:
+ case arm_stub_long_branch_v4t_arm_thumb:
+ case arm_stub_long_branch_thumb_only:
+ case arm_stub_long_branch_v4t_thumb_thumb:
+ case arm_stub_long_branch_v4t_thumb_arm:
+ case arm_stub_short_branch_v4t_thumb_arm:
+ case arm_stub_long_branch_any_arm_pic:
+ case arm_stub_long_branch_any_thumb_pic:
+ case arm_stub_long_branch_v4t_thumb_thumb_pic:
+ case arm_stub_long_branch_v4t_arm_thumb_pic:
+ case arm_stub_long_branch_v4t_thumb_arm_pic:
+ case arm_stub_long_branch_thumb_only_pic:
+ case arm_stub_long_branch_any_tls_pic:
+ case arm_stub_long_branch_v4t_thumb_tls_pic:
+ case arm_stub_a8_veneer_blx:
+ return 4;
+
+ case arm_stub_long_branch_arm_nacl:
+ case arm_stub_long_branch_arm_nacl_pic:
+ return 16;
+
+ default:
+ abort (); /* Should be unreachable. */
+ }
+}
+
+static bfd_boolean
+arm_build_one_stub (struct bfd_hash_entry *gen_entry,
+ void * in_arg)
+{
+#define MAXRELOCS 3
+ struct elf32_arm_stub_hash_entry *stub_entry;
+ struct elf32_arm_link_hash_table *globals;
+ struct bfd_link_info *info;
+ asection *stub_sec;
+ bfd *stub_bfd;
+ bfd_byte *loc;
+ bfd_vma sym_value;
+ int template_size;
+ int size;
+ const insn_sequence *template_sequence;
+ int i;
+ int stub_reloc_idx[MAXRELOCS] = {-1, -1};
+ int stub_reloc_offset[MAXRELOCS] = {0, 0};
+ int nrelocs = 0;
+
+ /* Massage our args to the form they really have. */
+ stub_entry = (struct elf32_arm_stub_hash_entry *) gen_entry;
+ info = (struct bfd_link_info *) in_arg;
+
+ globals = elf32_arm_hash_table (info);
+ if (globals == NULL)
+ return FALSE;
+
+ stub_sec = stub_entry->stub_sec;
+
+ if ((globals->fix_cortex_a8 < 0)
+ != (arm_stub_required_alignment (stub_entry->stub_type) == 2))
+ /* We have to do less-strictly-aligned fixes last. */
+ return TRUE;
+
+ /* Make a note of the offset within the stubs for this entry. */
+ stub_entry->stub_offset = stub_sec->size;
+ loc = stub_sec->contents + stub_entry->stub_offset;
+
+ stub_bfd = stub_sec->owner;
+
+ /* This is the address of the stub destination. */
+ sym_value = (stub_entry->target_value
+ + stub_entry->target_section->output_offset
+ + stub_entry->target_section->output_section->vma);
+
+ template_sequence = stub_entry->stub_template;
+ template_size = stub_entry->stub_template_size;
+
+ size = 0;
+ for (i = 0; i < template_size; i++)
+ {
+ switch (template_sequence[i].type)
+ {
+ case THUMB16_TYPE:
+ {
+ bfd_vma data = (bfd_vma) template_sequence[i].data;
+ if (template_sequence[i].reloc_addend != 0)
+ {
+ /* We've borrowed the reloc_addend field to mean we should
+ insert a condition code into this (Thumb-1 branch)
+ instruction. See THUMB16_BCOND_INSN. */
+ BFD_ASSERT ((data & 0xff00) == 0xd000);
+ data |= ((stub_entry->orig_insn >> 22) & 0xf) << 8;
+ }
+ bfd_put_16 (stub_bfd, data, loc + size);
+ size += 2;
+ }
+ break;
+
+ case THUMB32_TYPE:
+ bfd_put_16 (stub_bfd,
+ (template_sequence[i].data >> 16) & 0xffff,
+ loc + size);
+ bfd_put_16 (stub_bfd, template_sequence[i].data & 0xffff,
+ loc + size + 2);
+ if (template_sequence[i].r_type != R_ARM_NONE)
+ {
+ stub_reloc_idx[nrelocs] = i;
+ stub_reloc_offset[nrelocs++] = size;
+ }
+ size += 4;
+ break;
+
+ case ARM_TYPE:
+ bfd_put_32 (stub_bfd, template_sequence[i].data,
+ loc + size);
+ /* Handle cases where the target is encoded within the
+ instruction. */
+ if (template_sequence[i].r_type == R_ARM_JUMP24)
+ {
+ stub_reloc_idx[nrelocs] = i;
+ stub_reloc_offset[nrelocs++] = size;
+ }
+ size += 4;
+ break;
+
+ case DATA_TYPE:
+ bfd_put_32 (stub_bfd, template_sequence[i].data, loc + size);
+ stub_reloc_idx[nrelocs] = i;
+ stub_reloc_offset[nrelocs++] = size;
+ size += 4;
+ break;
+
+ default:
+ BFD_FAIL ();
+ return FALSE;
+ }
+ }
+
+ stub_sec->size += size;
+
+ /* Stub size has already been computed in arm_size_one_stub. Check
+ consistency. */
+ BFD_ASSERT (size == stub_entry->stub_size);
+
+ /* Destination is Thumb. Force bit 0 to 1 to reflect this. */
+ if (stub_entry->branch_type == ST_BRANCH_TO_THUMB)
+ sym_value |= 1;
+
+ /* Assume there is at least one and at most MAXRELOCS entries to relocate
+ in each stub. */
+ BFD_ASSERT (nrelocs != 0 && nrelocs <= MAXRELOCS);
+
+ for (i = 0; i < nrelocs; i++)
+ if (template_sequence[stub_reloc_idx[i]].r_type == R_ARM_THM_JUMP24
+ || template_sequence[stub_reloc_idx[i]].r_type == R_ARM_THM_JUMP19
+ || template_sequence[stub_reloc_idx[i]].r_type == R_ARM_THM_CALL
+ || template_sequence[stub_reloc_idx[i]].r_type == R_ARM_THM_XPC22)
+ {
+ Elf_Internal_Rela rel;
+ bfd_boolean unresolved_reloc;
+ char *error_message;
+ enum arm_st_branch_type branch_type
+ = (template_sequence[stub_reloc_idx[i]].r_type != R_ARM_THM_XPC22
+ ? ST_BRANCH_TO_THUMB : ST_BRANCH_TO_ARM);
+ bfd_vma points_to = sym_value + stub_entry->target_addend;
+
+ rel.r_offset = stub_entry->stub_offset + stub_reloc_offset[i];
+ rel.r_info = ELF32_R_INFO (0,
+ template_sequence[stub_reloc_idx[i]].r_type);
+ rel.r_addend = template_sequence[stub_reloc_idx[i]].reloc_addend;
+
+ if (stub_entry->stub_type == arm_stub_a8_veneer_b_cond && i == 0)
+ /* The first relocation in the elf32_arm_stub_a8_veneer_b_cond[]
+ template should refer back to the instruction after the original
+ branch. */
+ points_to = sym_value;
+
+ /* There may be unintended consequences if this is not true. */
+ BFD_ASSERT (stub_entry->h == NULL);
+
+ /* Note: _bfd_final_link_relocate doesn't handle these relocations
+ properly. We should probably use this function unconditionally,
+ rather than only for certain relocations listed in the enclosing
+ conditional, for the sake of consistency. */
+ elf32_arm_final_link_relocate (elf32_arm_howto_from_type
+ (template_sequence[stub_reloc_idx[i]].r_type),
+ stub_bfd, info->output_bfd, stub_sec, stub_sec->contents, &rel,
+ points_to, info, stub_entry->target_section, "", STT_FUNC,
+ branch_type, (struct elf_link_hash_entry *) stub_entry->h,
+ &unresolved_reloc, &error_message);
+ }
+ else
+ {
+ Elf_Internal_Rela rel;
+ bfd_boolean unresolved_reloc;
+ char *error_message;
+ bfd_vma points_to = sym_value + stub_entry->target_addend
+ + template_sequence[stub_reloc_idx[i]].reloc_addend;
+
+ rel.r_offset = stub_entry->stub_offset + stub_reloc_offset[i];
+ rel.r_info = ELF32_R_INFO (0,
+ template_sequence[stub_reloc_idx[i]].r_type);
+ rel.r_addend = 0;
+
+ elf32_arm_final_link_relocate (elf32_arm_howto_from_type
+ (template_sequence[stub_reloc_idx[i]].r_type),
+ stub_bfd, info->output_bfd, stub_sec, stub_sec->contents, &rel,
+ points_to, info, stub_entry->target_section, "", STT_FUNC,
+ stub_entry->branch_type,
+ (struct elf_link_hash_entry *) stub_entry->h, &unresolved_reloc,
+ &error_message);
+ }
+
+ return TRUE;
+#undef MAXRELOCS
+}
+
+/* Calculate the template, template size and instruction size for a stub.
+ Return value is the instruction size. */
+
+static unsigned int
+find_stub_size_and_template (enum elf32_arm_stub_type stub_type,
+ const insn_sequence **stub_template,
+ int *stub_template_size)
+{
+ const insn_sequence *template_sequence = NULL;
+ int template_size = 0, i;
+ unsigned int size;
+
+ template_sequence = stub_definitions[stub_type].template_sequence;
+ if (stub_template)
+ *stub_template = template_sequence;
+
+ template_size = stub_definitions[stub_type].template_size;
+ if (stub_template_size)
+ *stub_template_size = template_size;
+
+ size = 0;
+ for (i = 0; i < template_size; i++)
+ {
+ switch (template_sequence[i].type)
+ {
+ case THUMB16_TYPE:
+ size += 2;
+ break;
+
+ case ARM_TYPE:
+ case THUMB32_TYPE:
+ case DATA_TYPE:
+ size += 4;
+ break;
+
+ default:
+ BFD_FAIL ();
+ return 0;
+ }
+ }
+
+ return size;
+}
+
+/* As above, but don't actually build the stub. Just bump offset so
+ we know stub section sizes. */
+
+static bfd_boolean
+arm_size_one_stub (struct bfd_hash_entry *gen_entry,
+ void *in_arg ATTRIBUTE_UNUSED)
+{
+ struct elf32_arm_stub_hash_entry *stub_entry;
+ const insn_sequence *template_sequence;
+ int template_size, size;
+
+ /* Massage our args to the form they really have. */
+ stub_entry = (struct elf32_arm_stub_hash_entry *) gen_entry;
+
+ BFD_ASSERT((stub_entry->stub_type > arm_stub_none)
+ && stub_entry->stub_type < ARRAY_SIZE(stub_definitions));
+
+ size = find_stub_size_and_template (stub_entry->stub_type, &template_sequence,
+ &template_size);
+
+ stub_entry->stub_size = size;
+ stub_entry->stub_template = template_sequence;
+ stub_entry->stub_template_size = template_size;
+
+ size = (size + 7) & ~7;
+ stub_entry->stub_sec->size += size;
+
+ return TRUE;
+}
+
+/* External entry points for sizing and building linker stubs. */
+
+/* Set up various things so that we can make a list of input sections
+ for each output section included in the link. Returns -1 on error,
+ 0 when no stubs will be needed, and 1 on success. */
+
+int
+elf32_arm_setup_section_lists (bfd *output_bfd,
+ struct bfd_link_info *info)
+{
+ bfd *input_bfd;
+ unsigned int bfd_count;
+ int top_id, top_index;
+ asection *section;
+ asection **input_list, **list;
+ bfd_size_type amt;
+ struct elf32_arm_link_hash_table *htab = elf32_arm_hash_table (info);
+
+ if (htab == NULL)
+ return 0;
+ if (! is_elf_hash_table (htab))
+ return 0;
+
+ /* Count the number of input BFDs and find the top input section id. */
+ for (input_bfd = info->input_bfds, bfd_count = 0, top_id = 0;
+ input_bfd != NULL;
+ input_bfd = input_bfd->link.next)
+ {
+ bfd_count += 1;
+ for (section = input_bfd->sections;
+ section != NULL;
+ section = section->next)
+ {
+ if (top_id < section->id)
+ top_id = section->id;
+ }
+ }
+ htab->bfd_count = bfd_count;
+
+ amt = sizeof (struct map_stub) * (top_id + 1);
+ htab->stub_group = (struct map_stub *) bfd_zmalloc (amt);
+ if (htab->stub_group == NULL)
+ return -1;
+ htab->top_id = top_id;
+
+ /* We can't use output_bfd->section_count here to find the top output
+ section index as some sections may have been removed, and
+ _bfd_strip_section_from_output doesn't renumber the indices. */
+ for (section = output_bfd->sections, top_index = 0;
+ section != NULL;
+ section = section->next)
+ {
+ if (top_index < section->index)
+ top_index = section->index;
+ }
+
+ htab->top_index = top_index;
+ amt = sizeof (asection *) * (top_index + 1);
+ input_list = (asection **) bfd_malloc (amt);
+ htab->input_list = input_list;
+ if (input_list == NULL)
+ return -1;
+
+ /* For sections we aren't interested in, mark their entries with a
+ value we can check later. */
+ list = input_list + top_index;
+ do
+ *list = bfd_abs_section_ptr;
+ while (list-- != input_list);
+
+ for (section = output_bfd->sections;
+ section != NULL;
+ section = section->next)
+ {
+ if ((section->flags & SEC_CODE) != 0)
+ input_list[section->index] = NULL;
+ }
+
+ return 1;
+}
+
+/* The linker repeatedly calls this function for each input section,
+ in the order that input sections are linked into output sections.
+ Build lists of input sections to determine groupings between which
+ we may insert linker stubs. */
+
+void
+elf32_arm_next_input_section (struct bfd_link_info *info,
+ asection *isec)
+{
+ struct elf32_arm_link_hash_table *htab = elf32_arm_hash_table (info);
+
+ if (htab == NULL)
+ return;
+
+ if (isec->output_section->index <= htab->top_index)
+ {
+ asection **list = htab->input_list + isec->output_section->index;
+
+ if (*list != bfd_abs_section_ptr && (isec->flags & SEC_CODE) != 0)
+ {
+ /* Steal the link_sec pointer for our list. */
+#define PREV_SEC(sec) (htab->stub_group[(sec)->id].link_sec)
+ /* This happens to make the list in reverse order,
+ which we reverse later. */
+ PREV_SEC (isec) = *list;
+ *list = isec;
+ }
+ }
+}
+
+/* See whether we can group stub sections together. Grouping stub
+ sections may result in fewer stubs. More importantly, we need to
+ put all .init* and .fini* stubs at the end of the .init or
+ .fini output sections respectively, because glibc splits the
+ _init and _fini functions into multiple parts. Putting a stub in
+ the middle of a function is not a good idea. */
+
+static void
+group_sections (struct elf32_arm_link_hash_table *htab,
+ bfd_size_type stub_group_size,
+ bfd_boolean stubs_always_after_branch)
+{
+ asection **list = htab->input_list;
+
+ do
+ {
+ asection *tail = *list;
+ asection *head;
+
+ if (tail == bfd_abs_section_ptr)
+ continue;
+
+ /* Reverse the list: we must avoid placing stubs at the
+ beginning of the section because the beginning of the text
+ section may be required for an interrupt vector in bare metal
+ code. */
+#define NEXT_SEC PREV_SEC
+ head = NULL;
+ while (tail != NULL)
+ {
+ /* Pop from tail. */
+ asection *item = tail;
+ tail = PREV_SEC (item);
+
+ /* Push on head. */
+ NEXT_SEC (item) = head;
+ head = item;
+ }
+
+ while (head != NULL)
+ {
+ asection *curr;
+ asection *next;
+ bfd_vma stub_group_start = head->output_offset;
+ bfd_vma end_of_next;
+
+ curr = head;
+ while (NEXT_SEC (curr) != NULL)
+ {
+ next = NEXT_SEC (curr);
+ end_of_next = next->output_offset + next->size;
+ if (end_of_next - stub_group_start >= stub_group_size)
+ /* End of NEXT is too far from start, so stop. */
+ break;
+ /* Add NEXT to the group. */
+ curr = next;
+ }
+
+ /* OK, the size from the start to the start of CURR is less
+ than stub_group_size and thus can be handled by one stub
+ section. (Or the head section is itself larger than
+ stub_group_size, in which case we may be toast.)
+ We should really be keeping track of the total size of
+ stubs added here, as stubs contribute to the final output
+ section size. */
+ do
+ {
+ next = NEXT_SEC (head);
+ /* Set up this stub group. */
+ htab->stub_group[head->id].link_sec = curr;
+ }
+ while (head != curr && (head = next) != NULL);
+
+ /* But wait, there's more! Input sections up to stub_group_size
+ bytes after the stub section can be handled by it too. */
+ if (!stubs_always_after_branch)
+ {
+ stub_group_start = curr->output_offset + curr->size;
+
+ while (next != NULL)
+ {
+ end_of_next = next->output_offset + next->size;
+ if (end_of_next - stub_group_start >= stub_group_size)
+ /* End of NEXT is too far from stubs, so stop. */
+ break;
+ /* Add NEXT to the stub group. */
+ head = next;
+ next = NEXT_SEC (head);
+ htab->stub_group[head->id].link_sec = curr;
+ }
+ }
+ head = next;
+ }
+ }
+ while (list++ != htab->input_list + htab->top_index);
+
+ free (htab->input_list);
+#undef PREV_SEC
+#undef NEXT_SEC
+}
+
+/* Comparison function for sorting/searching relocations relating to Cortex-A8
+ erratum fix. */
+
+static int
+a8_reloc_compare (const void *a, const void *b)
+{
+ const struct a8_erratum_reloc *ra = (const struct a8_erratum_reloc *) a;
+ const struct a8_erratum_reloc *rb = (const struct a8_erratum_reloc *) b;
+
+ if (ra->from < rb->from)
+ return -1;
+ else if (ra->from > rb->from)
+ return 1;
+ else
+ return 0;
+}
+
+static struct elf_link_hash_entry *find_thumb_glue (struct bfd_link_info *,
+ const char *, char **);
+
+/* Helper function to scan code for sequences which might trigger the Cortex-A8
+ branch/TLB erratum. Fill in the table described by A8_FIXES_P,
+ NUM_A8_FIXES_P, A8_FIX_TABLE_SIZE_P. Returns true if an error occurs, false
+ otherwise. */
+
+static bfd_boolean
+cortex_a8_erratum_scan (bfd *input_bfd,
+ struct bfd_link_info *info,
+ struct a8_erratum_fix **a8_fixes_p,
+ unsigned int *num_a8_fixes_p,
+ unsigned int *a8_fix_table_size_p,
+ struct a8_erratum_reloc *a8_relocs,
+ unsigned int num_a8_relocs,
+ unsigned prev_num_a8_fixes,
+ bfd_boolean *stub_changed_p)
+{
+ asection *section;
+ struct elf32_arm_link_hash_table *htab = elf32_arm_hash_table (info);
+ struct a8_erratum_fix *a8_fixes = *a8_fixes_p;
+ unsigned int num_a8_fixes = *num_a8_fixes_p;
+ unsigned int a8_fix_table_size = *a8_fix_table_size_p;
+
+ if (htab == NULL)
+ return FALSE;
+
+ for (section = input_bfd->sections;
+ section != NULL;
+ section = section->next)
+ {
+ bfd_byte *contents = NULL;
+ struct _arm_elf_section_data *sec_data;
+ unsigned int span;
+ bfd_vma base_vma;
+
+ if (elf_section_type (section) != SHT_PROGBITS
+ || (elf_section_flags (section) & SHF_EXECINSTR) == 0
+ || (section->flags & SEC_EXCLUDE) != 0
+ || (section->sec_info_type == SEC_INFO_TYPE_JUST_SYMS)
+ || (section->output_section == bfd_abs_section_ptr))
+ continue;
+
+ base_vma = section->output_section->vma + section->output_offset;
+
+ if (elf_section_data (section)->this_hdr.contents != NULL)
+ contents = elf_section_data (section)->this_hdr.contents;
+ else if (! bfd_malloc_and_get_section (input_bfd, section, &contents))
+ return TRUE;
+
+ sec_data = elf32_arm_section_data (section);
+
+ for (span = 0; span < sec_data->mapcount; span++)
+ {
+ unsigned int span_start = sec_data->map[span].vma;
+ unsigned int span_end = (span == sec_data->mapcount - 1)
+ ? section->size : sec_data->map[span + 1].vma;
+ unsigned int i;
+ char span_type = sec_data->map[span].type;
+ bfd_boolean last_was_32bit = FALSE, last_was_branch = FALSE;
+
+ if (span_type != 't')
+ continue;
+
+ /* Span is entirely within a single 4KB region: skip scanning. */
+ if (((base_vma + span_start) & ~0xfff)
+ == ((base_vma + span_end) & ~0xfff))
+ continue;
+
+ /* Scan for 32-bit Thumb-2 branches which span two 4K regions, where:
+
+ * The opcode is BLX.W, BL.W, B.W, Bcc.W
+ * The branch target is in the same 4KB region as the
+ first half of the branch.
+ * The instruction before the branch is a 32-bit
+ length non-branch instruction. */
+ for (i = span_start; i < span_end;)
+ {
+ unsigned int insn = bfd_getl16 (&contents[i]);
+ bfd_boolean insn_32bit = FALSE, is_blx = FALSE, is_b = FALSE;
+ bfd_boolean is_bl = FALSE, is_bcc = FALSE, is_32bit_branch;
+
+ if ((insn & 0xe000) == 0xe000 && (insn & 0x1800) != 0x0000)
+ insn_32bit = TRUE;
+
+ if (insn_32bit)
+ {
+ /* Load the rest of the insn (in manual-friendly order). */
+ insn = (insn << 16) | bfd_getl16 (&contents[i + 2]);
+
+ /* Encoding T4: B<c>.W. */
+ is_b = (insn & 0xf800d000) == 0xf0009000;
+ /* Encoding T1: BL<c>.W. */
+ is_bl = (insn & 0xf800d000) == 0xf000d000;
+ /* Encoding T2: BLX<c>.W. */
+ is_blx = (insn & 0xf800d000) == 0xf000c000;
+ /* Encoding T3: B<c>.W (not permitted in IT block). */
+ is_bcc = (insn & 0xf800d000) == 0xf0008000
+ && (insn & 0x07f00000) != 0x03800000;
+ }
+
+ is_32bit_branch = is_b || is_bl || is_blx || is_bcc;
+
+ if (((base_vma + i) & 0xfff) == 0xffe
+ && insn_32bit
+ && is_32bit_branch
+ && last_was_32bit
+ && ! last_was_branch)
+ {
+ bfd_signed_vma offset = 0;
+ bfd_boolean force_target_arm = FALSE;
+ bfd_boolean force_target_thumb = FALSE;
+ bfd_vma target;
+ enum elf32_arm_stub_type stub_type = arm_stub_none;
+ struct a8_erratum_reloc key, *found;
+ bfd_boolean use_plt = FALSE;
+
+ key.from = base_vma + i;
+ found = (struct a8_erratum_reloc *)
+ bsearch (&key, a8_relocs, num_a8_relocs,
+ sizeof (struct a8_erratum_reloc),
+ &a8_reloc_compare);
+
+ if (found)
+ {
+ char *error_message = NULL;
+ struct elf_link_hash_entry *entry;
+
+ /* We don't care about the error returned from this
+ function, only if there is glue or not. */
+ entry = find_thumb_glue (info, found->sym_name,
+ &error_message);
+
+ if (entry)
+ found->non_a8_stub = TRUE;
+
+ /* Keep a simpler condition, for the sake of clarity. */
+ if (htab->root.splt != NULL && found->hash != NULL
+ && found->hash->root.plt.offset != (bfd_vma) -1)
+ use_plt = TRUE;
+
+ if (found->r_type == R_ARM_THM_CALL)
+ {
+ if (found->branch_type == ST_BRANCH_TO_ARM
+ || use_plt)
+ force_target_arm = TRUE;
+ else
+ force_target_thumb = TRUE;
+ }
+ }
+
+ /* Check if we have an offending branch instruction. */
+
+ if (found && found->non_a8_stub)
+ /* We've already made a stub for this instruction, e.g.
+ it's a long branch or a Thumb->ARM stub. Assume that
+ stub will suffice to work around the A8 erratum (see
+ setting of always_after_branch above). */
+ ;
+ else if (is_bcc)
+ {
+ offset = (insn & 0x7ff) << 1;
+ offset |= (insn & 0x3f0000) >> 4;
+ offset |= (insn & 0x2000) ? 0x40000 : 0;
+ offset |= (insn & 0x800) ? 0x80000 : 0;
+ offset |= (insn & 0x4000000) ? 0x100000 : 0;
+ if (offset & 0x100000)
+ offset |= ~ ((bfd_signed_vma) 0xfffff);
+ stub_type = arm_stub_a8_veneer_b_cond;
+ }
+ else if (is_b || is_bl || is_blx)
+ {
+ int s = (insn & 0x4000000) != 0;
+ int j1 = (insn & 0x2000) != 0;
+ int j2 = (insn & 0x800) != 0;
+ int i1 = !(j1 ^ s);
+ int i2 = !(j2 ^ s);
+
+ offset = (insn & 0x7ff) << 1;
+ offset |= (insn & 0x3ff0000) >> 4;
+ offset |= i2 << 22;
+ offset |= i1 << 23;
+ offset |= s << 24;
+ if (offset & 0x1000000)
+ offset |= ~ ((bfd_signed_vma) 0xffffff);
+
+ if (is_blx)
+ offset &= ~ ((bfd_signed_vma) 3);
+
+ stub_type = is_blx ? arm_stub_a8_veneer_blx :
+ is_bl ? arm_stub_a8_veneer_bl : arm_stub_a8_veneer_b;
+ }
+
+ if (stub_type != arm_stub_none)
+ {
+ bfd_vma pc_for_insn = base_vma + i + 4;
+
+ /* The original instruction is a BL, but the target is
+ an ARM instruction. If we were not making a stub,
+ the BL would have been converted to a BLX. Use the
+ BLX stub instead in that case. */
+ if (htab->use_blx && force_target_arm
+ && stub_type == arm_stub_a8_veneer_bl)
+ {
+ stub_type = arm_stub_a8_veneer_blx;
+ is_blx = TRUE;
+ is_bl = FALSE;
+ }
+ /* Conversely, if the original instruction was
+ BLX but the target is Thumb mode, use the BL
+ stub. */
+ else if (force_target_thumb
+ && stub_type == arm_stub_a8_veneer_blx)
+ {
+ stub_type = arm_stub_a8_veneer_bl;
+ is_blx = FALSE;
+ is_bl = TRUE;
+ }
+
+ if (is_blx)
+ pc_for_insn &= ~ ((bfd_vma) 3);
+
+ /* If we found a relocation, use the proper destination,
+ not the offset in the (unrelocated) instruction.
+ Note this is always done if we switched the stub type
+ above. */
+ if (found)
+ offset =
+ (bfd_signed_vma) (found->destination - pc_for_insn);
+
+ /* If the stub will use a Thumb-mode branch to a
+ PLT target, redirect it to the preceding Thumb
+ entry point. */
+ if (stub_type != arm_stub_a8_veneer_blx && use_plt)
+ offset -= PLT_THUMB_STUB_SIZE;
+
+ target = pc_for_insn + offset;
+
+ /* The BLX stub is ARM-mode code. Adjust the offset to
+ take the different PC value (+8 instead of +4) into
+ account. */
+ if (stub_type == arm_stub_a8_veneer_blx)
+ offset += 4;
+
+ if (((base_vma + i) & ~0xfff) == (target & ~0xfff))
+ {
+ char *stub_name = NULL;
+
+ if (num_a8_fixes == a8_fix_table_size)
+ {
+ a8_fix_table_size *= 2;
+ a8_fixes = (struct a8_erratum_fix *)
+ bfd_realloc (a8_fixes,
+ sizeof (struct a8_erratum_fix)
+ * a8_fix_table_size);
+ }
+
+ if (num_a8_fixes < prev_num_a8_fixes)
+ {
+ /* If we're doing a subsequent scan,
+ check if we've found the same fix as
+ before, and try and reuse the stub
+ name. */
+ stub_name = a8_fixes[num_a8_fixes].stub_name;
+ if ((a8_fixes[num_a8_fixes].section != section)
+ || (a8_fixes[num_a8_fixes].offset != i))
+ {
+ free (stub_name);
+ stub_name = NULL;
+ *stub_changed_p = TRUE;
+ }
+ }
+
+ if (!stub_name)
+ {
+ stub_name = (char *) bfd_malloc (8 + 1 + 8 + 1);
+ if (stub_name != NULL)
+ sprintf (stub_name, "%x:%x", section->id, i);
+ }
+
+ a8_fixes[num_a8_fixes].input_bfd = input_bfd;
+ a8_fixes[num_a8_fixes].section = section;
+ a8_fixes[num_a8_fixes].offset = i;
+ a8_fixes[num_a8_fixes].addend = offset;
+ a8_fixes[num_a8_fixes].orig_insn = insn;
+ a8_fixes[num_a8_fixes].stub_name = stub_name;
+ a8_fixes[num_a8_fixes].stub_type = stub_type;
+ a8_fixes[num_a8_fixes].branch_type =
+ is_blx ? ST_BRANCH_TO_ARM : ST_BRANCH_TO_THUMB;
+
+ num_a8_fixes++;
+ }
+ }
+ }
+
+ i += insn_32bit ? 4 : 2;
+ last_was_32bit = insn_32bit;
+ last_was_branch = is_32bit_branch;
+ }
+ }
+
+ if (elf_section_data (section)->this_hdr.contents == NULL)
+ free (contents);
+ }
+
+ *a8_fixes_p = a8_fixes;
+ *num_a8_fixes_p = num_a8_fixes;
+ *a8_fix_table_size_p = a8_fix_table_size;
+
+ return FALSE;
+}
+
+/* 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. */
+
+bfd_boolean
+elf32_arm_size_stubs (bfd *output_bfd,
+ bfd *stub_bfd,
+ struct bfd_link_info *info,
+ bfd_signed_vma group_size,
+ asection * (*add_stub_section) (const char *, asection *,
+ unsigned int),
+ void (*layout_sections_again) (void))
+{
+ bfd_size_type stub_group_size;
+ bfd_boolean stubs_always_after_branch;
+ struct elf32_arm_link_hash_table *htab = elf32_arm_hash_table (info);
+ struct a8_erratum_fix *a8_fixes = NULL;
+ unsigned int num_a8_fixes = 0, a8_fix_table_size = 10;
+ struct a8_erratum_reloc *a8_relocs = NULL;
+ unsigned int num_a8_relocs = 0, a8_reloc_table_size = 10, i;
+
+ if (htab == NULL)
+ return FALSE;
+
+ if (htab->fix_cortex_a8)
+ {
+ a8_fixes = (struct a8_erratum_fix *)
+ bfd_zmalloc (sizeof (struct a8_erratum_fix) * a8_fix_table_size);
+ a8_relocs = (struct a8_erratum_reloc *)
+ bfd_zmalloc (sizeof (struct a8_erratum_reloc) * a8_reloc_table_size);
+ }
+
+ /* Propagate mach to stub bfd, because it may not have been
+ finalized when we created stub_bfd. */
+ bfd_set_arch_mach (stub_bfd, bfd_get_arch (output_bfd),
+ bfd_get_mach (output_bfd));
+
+ /* Stash our params away. */
+ htab->stub_bfd = stub_bfd;
+ htab->add_stub_section = add_stub_section;
+ htab->layout_sections_again = layout_sections_again;
+ stubs_always_after_branch = group_size < 0;
+
+ /* The Cortex-A8 erratum fix depends on stubs not being in the same 4K page
+ as the first half of a 32-bit branch straddling two 4K pages. This is a
+ crude way of enforcing that. */
+ if (htab->fix_cortex_a8)
+ stubs_always_after_branch = 1;
+
+ if (group_size < 0)
+ stub_group_size = -group_size;
+ else
+ stub_group_size = group_size;
+
+ if (stub_group_size == 1)
+ {
+ /* Default values. */
+ /* Thumb branch range is +-4MB has to be used as the default
+ maximum size (a given section can contain both ARM and Thumb
+ code, so the worst case has to be taken into account).
+
+ This value is 24K less than that, which allows for 2025
+ 12-byte stubs. If we exceed that, then we will fail to link.
+ The user will have to relink with an explicit group size
+ option. */
+ stub_group_size = 4170000;
+ }
+
+ group_sections (htab, stub_group_size, stubs_always_after_branch);
+
+ /* If we're applying the cortex A8 fix, we need to determine the
+ program header size now, because we cannot change it later --
+ that could alter section placements. Notice the A8 erratum fix
+ ends up requiring the section addresses to remain unchanged
+ modulo the page size. That's something we cannot represent
+ inside BFD, and we don't want to force the section alignment to
+ be the page size. */
+ if (htab->fix_cortex_a8)
+ (*htab->layout_sections_again) ();
+
+ while (1)
+ {
+ bfd *input_bfd;
+ unsigned int bfd_indx;
+ asection *stub_sec;
+ bfd_boolean stub_changed = FALSE;
+ unsigned prev_num_a8_fixes = num_a8_fixes;
+
+ num_a8_fixes = 0;
+ for (input_bfd = info->input_bfds, bfd_indx = 0;
+ input_bfd != NULL;
+ input_bfd = input_bfd->link.next, bfd_indx++)
+ {
+ Elf_Internal_Shdr *symtab_hdr;
+ asection *section;
+ Elf_Internal_Sym *local_syms = NULL;
+
+ if (!is_arm_elf (input_bfd))
+ continue;
+
+ num_a8_relocs = 0;
+
+ /* We'll need the symbol table in a second. */
+ symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
+ if (symtab_hdr->sh_info == 0)
+ continue;
+
+ /* Walk over each section attached to the input bfd. */
+ for (section = input_bfd->sections;
+ section != NULL;
+ section = section->next)
+ {
+ Elf_Internal_Rela *internal_relocs, *irelaend, *irela;
+
+ /* If there aren't any relocs, then there's nothing more
+ to do. */
+ if ((section->flags & SEC_RELOC) == 0
+ || section->reloc_count == 0
+ || (section->flags & SEC_CODE) == 0)
+ continue;
+
+ /* If this section is a link-once section that will be
+ discarded, then don't create any stubs. */
+ if (section->output_section == NULL
+ || section->output_section->owner != output_bfd)
+ continue;
+
+ /* Get the relocs. */
+ internal_relocs
+ = _bfd_elf_link_read_relocs (input_bfd, section, NULL,
+ NULL, info->keep_memory);
+ if (internal_relocs == NULL)
+ goto error_ret_free_local;
+
+ /* Now examine each relocation. */
+ irela = internal_relocs;
+ irelaend = irela + section->reloc_count;
+ for (; irela < irelaend; irela++)
+ {
+ unsigned int r_type, r_indx;
+ enum elf32_arm_stub_type stub_type;
+ struct elf32_arm_stub_hash_entry *stub_entry;
+ asection *sym_sec;
+ bfd_vma sym_value;
+ bfd_vma destination;
+ struct elf32_arm_link_hash_entry *hash;
+ const char *sym_name;
+ char *stub_name;
+ const asection *id_sec;
+ unsigned char st_type;
+ enum arm_st_branch_type branch_type;
+ bfd_boolean created_stub = FALSE;
+
+ r_type = ELF32_R_TYPE (irela->r_info);
+ r_indx = ELF32_R_SYM (irela->r_info);
+
+ if (r_type >= (unsigned int) R_ARM_max)
+ {
+ bfd_set_error (bfd_error_bad_value);
+ error_ret_free_internal:
+ if (elf_section_data (section)->relocs == NULL)
+ free (internal_relocs);
+ goto error_ret_free_local;
+ }
+
+ hash = NULL;
+ if (r_indx >= symtab_hdr->sh_info)
+ hash = elf32_arm_hash_entry
+ (elf_sym_hashes (input_bfd)
+ [r_indx - symtab_hdr->sh_info]);
+
+ /* Only look for stubs on branch instructions, or
+ non-relaxed TLSCALL */
+ if ((r_type != (unsigned int) R_ARM_CALL)
+ && (r_type != (unsigned int) R_ARM_THM_CALL)
+ && (r_type != (unsigned int) R_ARM_JUMP24)
+ && (r_type != (unsigned int) R_ARM_THM_JUMP19)
+ && (r_type != (unsigned int) R_ARM_THM_XPC22)
+ && (r_type != (unsigned int) R_ARM_THM_JUMP24)
+ && (r_type != (unsigned int) R_ARM_PLT32)
+ && !((r_type == (unsigned int) R_ARM_TLS_CALL
+ || r_type == (unsigned int) R_ARM_THM_TLS_CALL)
+ && r_type == elf32_arm_tls_transition
+ (info, r_type, &hash->root)
+ && ((hash ? hash->tls_type
+ : (elf32_arm_local_got_tls_type
+ (input_bfd)[r_indx]))
+ & GOT_TLS_GDESC) != 0))
+ continue;
+
+ /* Now determine the call target, its name, value,
+ section. */
+ sym_sec = NULL;
+ sym_value = 0;
+ destination = 0;
+ sym_name = NULL;
+
+ if (r_type == (unsigned int) R_ARM_TLS_CALL
+ || r_type == (unsigned int) R_ARM_THM_TLS_CALL)
+ {
+ /* A non-relaxed TLS call. The target is the
+ plt-resident trampoline and nothing to do
+ with the symbol. */
+ BFD_ASSERT (htab->tls_trampoline > 0);
+ sym_sec = htab->root.splt;
+ sym_value = htab->tls_trampoline;
+ hash = 0;
+ st_type = STT_FUNC;
+ branch_type = ST_BRANCH_TO_ARM;
+ }
+ else if (!hash)
+ {
+ /* It's a local symbol. */
+ Elf_Internal_Sym *sym;
+
+ if (local_syms == NULL)
+ {
+ local_syms
+ = (Elf_Internal_Sym *) symtab_hdr->contents;
+ if (local_syms == NULL)
+ local_syms
+ = bfd_elf_get_elf_syms (input_bfd, symtab_hdr,
+ symtab_hdr->sh_info, 0,
+ NULL, NULL, NULL);
+ if (local_syms == NULL)
+ goto error_ret_free_internal;
+ }
+
+ sym = local_syms + r_indx;
+ if (sym->st_shndx == SHN_UNDEF)
+ sym_sec = bfd_und_section_ptr;
+ else if (sym->st_shndx == SHN_ABS)
+ sym_sec = bfd_abs_section_ptr;
+ else if (sym->st_shndx == SHN_COMMON)
+ sym_sec = bfd_com_section_ptr;
+ else
+ sym_sec =
+ bfd_section_from_elf_index (input_bfd, sym->st_shndx);
+
+ if (!sym_sec)
+ /* This is an undefined symbol. It can never
+ be resolved. */
+ continue;
+
+ if (ELF_ST_TYPE (sym->st_info) != STT_SECTION)
+ sym_value = sym->st_value;
+ destination = (sym_value + irela->r_addend
+ + sym_sec->output_offset
+ + sym_sec->output_section->vma);
+ st_type = ELF_ST_TYPE (sym->st_info);
+ branch_type = ARM_SYM_BRANCH_TYPE (sym);
+ sym_name
+ = bfd_elf_string_from_elf_section (input_bfd,
+ symtab_hdr->sh_link,
+ sym->st_name);
+ }
+ else
+ {
+ /* It's an external symbol. */
+ while (hash->root.root.type == bfd_link_hash_indirect
+ || hash->root.root.type == bfd_link_hash_warning)
+ hash = ((struct elf32_arm_link_hash_entry *)
+ hash->root.root.u.i.link);
+
+ if (hash->root.root.type == bfd_link_hash_defined
+ || hash->root.root.type == bfd_link_hash_defweak)
+ {
+ sym_sec = hash->root.root.u.def.section;
+ sym_value = hash->root.root.u.def.value;
+
+ struct elf32_arm_link_hash_table *globals =
+ elf32_arm_hash_table (info);
+
+ /* For a destination in a shared library,
+ use the PLT stub as target address to
+ decide whether a branch stub is
+ needed. */
+ if (globals != NULL
+ && globals->root.splt != NULL
+ && hash != NULL
+ && hash->root.plt.offset != (bfd_vma) -1)
+ {
+ sym_sec = globals->root.splt;
+ sym_value = hash->root.plt.offset;
+ if (sym_sec->output_section != NULL)
+ destination = (sym_value
+ + sym_sec->output_offset
+ + sym_sec->output_section->vma);
+ }
+ else if (sym_sec->output_section != NULL)
+ destination = (sym_value + irela->r_addend
+ + sym_sec->output_offset
+ + sym_sec->output_section->vma);
+ }
+ else if ((hash->root.root.type == bfd_link_hash_undefined)
+ || (hash->root.root.type == bfd_link_hash_undefweak))
+ {
+ /* For a shared library, use the PLT stub as
+ target address to decide whether a long
+ branch stub is needed.
+ For absolute code, they cannot be handled. */
+ struct elf32_arm_link_hash_table *globals =
+ elf32_arm_hash_table (info);
+
+ if (globals != NULL
+ && globals->root.splt != NULL
+ && hash != NULL
+ && hash->root.plt.offset != (bfd_vma) -1)
+ {
+ sym_sec = globals->root.splt;
+ sym_value = hash->root.plt.offset;
+ if (sym_sec->output_section != NULL)
+ destination = (sym_value
+ + sym_sec->output_offset
+ + sym_sec->output_section->vma);
+ }
+ else
+ continue;
+ }
+ else
+ {
+ bfd_set_error (bfd_error_bad_value);
+ goto error_ret_free_internal;
+ }
+ st_type = hash->root.type;
+ branch_type = hash->root.target_internal;
+ sym_name = hash->root.root.root.string;
+ }
+
+ do
+ {
+ /* Determine what (if any) linker stub is needed. */
+ stub_type = arm_type_of_stub (info, section, irela,
+ st_type, &branch_type,
+ hash, destination, sym_sec,
+ input_bfd, sym_name);
+ if (stub_type == arm_stub_none)
+ break;
+
+ /* Support for grouping stub sections. */
+ id_sec = htab->stub_group[section->id].link_sec;
+
+ /* Get the name of this stub. */
+ stub_name = elf32_arm_stub_name (id_sec, sym_sec, hash,
+ irela, stub_type);
+ if (!stub_name)
+ goto error_ret_free_internal;
+
+ /* We've either created a stub for this reloc already,
+ or we are about to. */
+ created_stub = TRUE;
+
+ stub_entry = arm_stub_hash_lookup
+ (&htab->stub_hash_table, stub_name,
+ FALSE, FALSE);
+ if (stub_entry != NULL)
+ {
+ /* The proper stub has already been created. */
+ free (stub_name);
+ stub_entry->target_value = sym_value;
+ break;
+ }
+
+ stub_entry = elf32_arm_add_stub (stub_name, section,
+ htab);
+ if (stub_entry == NULL)
+ {
+ free (stub_name);
+ goto error_ret_free_internal;
+ }
+
+ stub_entry->target_value = sym_value;
+ stub_entry->target_section = sym_sec;
+ stub_entry->stub_type = stub_type;
+ stub_entry->h = hash;
+ stub_entry->branch_type = branch_type;
+
+ if (sym_name == NULL)
+ sym_name = "unnamed";
+ stub_entry->output_name = (char *)
+ bfd_alloc (htab->stub_bfd,
+ sizeof (THUMB2ARM_GLUE_ENTRY_NAME)
+ + strlen (sym_name));
+ if (stub_entry->output_name == NULL)
+ {
+ free (stub_name);
+ goto error_ret_free_internal;
+ }
+
+ /* For historical reasons, use the existing names for
+ ARM-to-Thumb and Thumb-to-ARM stubs. */
+ if ((r_type == (unsigned int) R_ARM_THM_CALL
+ || r_type == (unsigned int) R_ARM_THM_JUMP24
+ || r_type == (unsigned int) R_ARM_THM_JUMP19)
+ && branch_type == ST_BRANCH_TO_ARM)
+ sprintf (stub_entry->output_name,
+ THUMB2ARM_GLUE_ENTRY_NAME, sym_name);
+ else if ((r_type == (unsigned int) R_ARM_CALL
+ || r_type == (unsigned int) R_ARM_JUMP24)
+ && branch_type == ST_BRANCH_TO_THUMB)
+ sprintf (stub_entry->output_name,
+ ARM2THUMB_GLUE_ENTRY_NAME, sym_name);
+ else
+ sprintf (stub_entry->output_name, STUB_ENTRY_NAME,
+ sym_name);
+
+ stub_changed = TRUE;
+ }
+ while (0);
+
+ /* Look for relocations which might trigger Cortex-A8
+ erratum. */
+ if (htab->fix_cortex_a8
+ && (r_type == (unsigned int) R_ARM_THM_JUMP24
+ || r_type == (unsigned int) R_ARM_THM_JUMP19
+ || r_type == (unsigned int) R_ARM_THM_CALL
+ || r_type == (unsigned int) R_ARM_THM_XPC22))
+ {
+ bfd_vma from = section->output_section->vma
+ + section->output_offset
+ + irela->r_offset;
+
+ if ((from & 0xfff) == 0xffe)
+ {
+ /* Found a candidate. Note we haven't checked the
+ destination is within 4K here: if we do so (and
+ don't create an entry in a8_relocs) we can't tell
+ that a branch should have been relocated when
+ scanning later. */
+ if (num_a8_relocs == a8_reloc_table_size)
+ {
+ a8_reloc_table_size *= 2;
+ a8_relocs = (struct a8_erratum_reloc *)
+ bfd_realloc (a8_relocs,
+ sizeof (struct a8_erratum_reloc)
+ * a8_reloc_table_size);
+ }
+
+ a8_relocs[num_a8_relocs].from = from;
+ a8_relocs[num_a8_relocs].destination = destination;
+ a8_relocs[num_a8_relocs].r_type = r_type;
+ a8_relocs[num_a8_relocs].branch_type = branch_type;
+ a8_relocs[num_a8_relocs].sym_name = sym_name;
+ a8_relocs[num_a8_relocs].non_a8_stub = created_stub;
+ a8_relocs[num_a8_relocs].hash = hash;
+
+ num_a8_relocs++;
+ }
+ }
+ }
+
+ /* We're done with the internal relocs, free them. */
+ if (elf_section_data (section)->relocs == NULL)
+ free (internal_relocs);
+ }
+
+ if (htab->fix_cortex_a8)
+ {
+ /* Sort relocs which might apply to Cortex-A8 erratum. */
+ qsort (a8_relocs, num_a8_relocs,
+ sizeof (struct a8_erratum_reloc),
+ &a8_reloc_compare);
+
+ /* Scan for branches which might trigger Cortex-A8 erratum. */
+ if (cortex_a8_erratum_scan (input_bfd, info, &a8_fixes,
+ &num_a8_fixes, &a8_fix_table_size,
+ a8_relocs, num_a8_relocs,
+ prev_num_a8_fixes, &stub_changed)
+ != 0)
+ goto error_ret_free_local;
+ }
+ }
+
+ if (prev_num_a8_fixes != num_a8_fixes)
+ stub_changed = TRUE;
+
+ if (!stub_changed)
+ break;
+
+ /* OK, we've added some stubs. Find out the new size of the
+ stub sections. */
+ for (stub_sec = htab->stub_bfd->sections;
+ stub_sec != NULL;
+ stub_sec = stub_sec->next)
+ {
+ /* Ignore non-stub sections. */
+ if (!strstr (stub_sec->name, STUB_SUFFIX))
+ continue;
+
+ stub_sec->size = 0;
+ }
+
+ bfd_hash_traverse (&htab->stub_hash_table, arm_size_one_stub, htab);
+
+ /* Add Cortex-A8 erratum veneers to stub section sizes too. */
+ if (htab->fix_cortex_a8)
+ for (i = 0; i < num_a8_fixes; i++)
+ {
+ stub_sec = elf32_arm_create_or_find_stub_sec (NULL,
+ a8_fixes[i].section, htab);
+
+ if (stub_sec == NULL)
+ goto error_ret_free_local;
+
+ stub_sec->size
+ += find_stub_size_and_template (a8_fixes[i].stub_type, NULL,
+ NULL);
+ }
+
+
+ /* Ask the linker to do its stuff. */
+ (*htab->layout_sections_again) ();
+ }
+
+ /* Add stubs for Cortex-A8 erratum fixes now. */
+ if (htab->fix_cortex_a8)
+ {
+ for (i = 0; i < num_a8_fixes; i++)
+ {
+ struct elf32_arm_stub_hash_entry *stub_entry;
+ char *stub_name = a8_fixes[i].stub_name;
+ asection *section = a8_fixes[i].section;
+ unsigned int section_id = a8_fixes[i].section->id;
+ asection *link_sec = htab->stub_group[section_id].link_sec;
+ asection *stub_sec = htab->stub_group[section_id].stub_sec;
+ const insn_sequence *template_sequence;
+ int template_size, size = 0;
+
+ stub_entry = arm_stub_hash_lookup (&htab->stub_hash_table, stub_name,
+ TRUE, FALSE);
+ if (stub_entry == NULL)
+ {
+ (*_bfd_error_handler) (_("%s: cannot create stub entry %s"),
+ section->owner,
+ stub_name);
+ return FALSE;
+ }
+
+ stub_entry->stub_sec = stub_sec;
+ stub_entry->stub_offset = 0;
+ stub_entry->id_sec = link_sec;
+ stub_entry->stub_type = a8_fixes[i].stub_type;
+ stub_entry->target_section = a8_fixes[i].section;
+ stub_entry->target_value = a8_fixes[i].offset;
+ stub_entry->target_addend = a8_fixes[i].addend;
+ stub_entry->orig_insn = a8_fixes[i].orig_insn;
+ stub_entry->branch_type = a8_fixes[i].branch_type;
+
+ size = find_stub_size_and_template (a8_fixes[i].stub_type,
+ &template_sequence,
+ &template_size);
+
+ stub_entry->stub_size = size;
+ stub_entry->stub_template = template_sequence;
+ stub_entry->stub_template_size = template_size;
+ }
+
+ /* Stash the Cortex-A8 erratum fix array for use later in
+ elf32_arm_write_section(). */
+ htab->a8_erratum_fixes = a8_fixes;
+ htab->num_a8_erratum_fixes = num_a8_fixes;
+ }
+ else
+ {
+ htab->a8_erratum_fixes = NULL;
+ htab->num_a8_erratum_fixes = 0;
+ }
+ return TRUE;
+
+ error_ret_free_local:
+ return FALSE;
+}
+
+/* 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. We also set up the .plt entries for statically linked PIC
+ functions here. This function is called via arm_elf_finish in the
+ linker. */
+
+bfd_boolean
+elf32_arm_build_stubs (struct bfd_link_info *info)
+{
+ asection *stub_sec;
+ struct bfd_hash_table *table;
+ struct elf32_arm_link_hash_table *htab;
+
+ htab = elf32_arm_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ for (stub_sec = htab->stub_bfd->sections;
+ stub_sec != NULL;
+ stub_sec = stub_sec->next)
+ {
+ bfd_size_type size;
+
+ /* Ignore non-stub sections. */
+ if (!strstr (stub_sec->name, STUB_SUFFIX))
+ continue;
+
+ /* Allocate memory to hold the linker stubs. */
+ size = stub_sec->size;
+ stub_sec->contents = (unsigned char *) bfd_zalloc (htab->stub_bfd, size);
+ if (stub_sec->contents == NULL && size != 0)
+ return FALSE;
+ stub_sec->size = 0;
+ }
+
+ /* Build the stubs as directed by the stub hash table. */
+ table = &htab->stub_hash_table;
+ bfd_hash_traverse (table, arm_build_one_stub, info);
+ if (htab->fix_cortex_a8)
+ {
+ /* Place the cortex a8 stubs last. */
+ htab->fix_cortex_a8 = -1;
+ bfd_hash_traverse (table, arm_build_one_stub, info);
+ }
+
+ return TRUE;
+}
+
+/* Locate the Thumb encoded calling stub for NAME. */
+
+static struct elf_link_hash_entry *
+find_thumb_glue (struct bfd_link_info *link_info,
+ const char *name,
+ char **error_message)
+{
+ 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);
+ if (hash_table == NULL)
+ return NULL;
+
+ tmp_name = (char *) bfd_malloc ((bfd_size_type) 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
+ && asprintf (error_message, _("unable to find THUMB glue '%s' for '%s'"),
+ tmp_name, name) == -1)
+ *error_message = (char *) bfd_errmsg (bfd_error_system_call);
+
+ free (tmp_name);
+
+ return hash;
+}
+
+/* Locate the ARM encoded calling stub for NAME. */
+
+static struct elf_link_hash_entry *
+find_arm_glue (struct bfd_link_info *link_info,
+ const char *name,
+ char **error_message)
+{
+ 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);
+ if (hash_table == NULL)
+ return NULL;
+
+ tmp_name = (char *) bfd_malloc ((bfd_size_type) 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
+ && asprintf (error_message, _("unable to find ARM glue '%s' for '%s'"),
+ tmp_name, name) == -1)
+ *error_message = (char *) bfd_errmsg (bfd_error_system_call);
+
+ free (tmp_name);
+
+ return myh;
+}
+
+/* ARM->Thumb glue (static images):
+
+ .arm
+ __func_from_arm:
+ ldr r12, __func_addr
+ bx r12
+ __func_addr:
+ .word func @ behave as if you saw a ARM_32 reloc.
+
+ (v5t static images)
+ .arm
+ __func_from_arm:
+ ldr pc, __func_addr
+ __func_addr:
+ .word func @ behave as if you saw a ARM_32 reloc.
+
+ (relocatable images)
+ .arm
+ __func_from_arm:
+ ldr r12, __func_offset
+ add r12, r12, pc
+ bx r12
+ __func_offset:
+ .word func - . */
+
+#define ARM2THUMB_STATIC_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 ARM2THUMB_V5_STATIC_GLUE_SIZE 8
+static const insn32 a2t1v5_ldr_insn = 0xe51ff004;
+static const insn32 a2t2v5_func_addr_insn = 0x00000001;
+
+#define ARM2THUMB_PIC_GLUE_SIZE 16
+static const insn32 a2t1p_ldr_insn = 0xe59fc004;
+static const insn32 a2t2p_add_pc_insn = 0xe08cc00f;
+static const insn32 a2t3p_bx_r12_insn = 0xe12fff1c;
+
+/* 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
+ b func bx r6
+ .arm
+ ;; 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;
+
+#define VFP11_ERRATUM_VENEER_SIZE 8
+
+#define ARM_BX_VENEER_SIZE 12
+static const insn32 armbx1_tst_insn = 0xe3100001;
+static const insn32 armbx2_moveq_insn = 0x01a0f000;
+static const insn32 armbx3_bx_insn = 0xe12fff10;
+
+#ifndef ELFARM_NABI_C_INCLUDED
+static void
+arm_allocate_glue_section_space (bfd * abfd, bfd_size_type size, const char * name)
+{
+ asection * s;
+ bfd_byte * contents;
+
+ if (size == 0)
+ {
+ /* Do not include empty glue sections in the output. */
+ if (abfd != NULL)
+ {
+ s = bfd_get_linker_section (abfd, name);
+ if (s != NULL)
+ s->flags |= SEC_EXCLUDE;
+ }
+ return;
+ }
+
+ BFD_ASSERT (abfd != NULL);
+
+ s = bfd_get_linker_section (abfd, name);
+ BFD_ASSERT (s != NULL);
+
+ contents = (bfd_byte *) bfd_alloc (abfd, size);
+
+ BFD_ASSERT (s->size == size);
+ s->contents = contents;
+}
+
+bfd_boolean
+bfd_elf32_arm_allocate_interworking_sections (struct bfd_link_info * info)
+{
+ struct elf32_arm_link_hash_table * globals;
+
+ globals = elf32_arm_hash_table (info);
+ BFD_ASSERT (globals != NULL);
+
+ arm_allocate_glue_section_space (globals->bfd_of_glue_owner,
+ globals->arm_glue_size,
+ ARM2THUMB_GLUE_SECTION_NAME);
+
+ arm_allocate_glue_section_space (globals->bfd_of_glue_owner,
+ globals->thumb_glue_size,
+ THUMB2ARM_GLUE_SECTION_NAME);
+
+ arm_allocate_glue_section_space (globals->bfd_of_glue_owner,
+ globals->vfp11_erratum_glue_size,
+ VFP11_ERRATUM_VENEER_SECTION_NAME);
+
+ arm_allocate_glue_section_space (globals->bfd_of_glue_owner,
+ globals->bx_glue_size,
+ ARM_BX_GLUE_SECTION_NAME);
+
+ return TRUE;
+}
+
+/* Allocate space and symbols for calling a Thumb function from Arm mode.
+ returns the symbol identifying the stub. */
+
+static struct elf_link_hash_entry *
+record_arm_to_thumb_glue (struct bfd_link_info * link_info,
+ struct elf_link_hash_entry * h)
+{
+ const char * name = h->root.root.string;
+ asection * s;
+ char * tmp_name;
+ struct elf_link_hash_entry * myh;
+ struct bfd_link_hash_entry * bh;
+ struct elf32_arm_link_hash_table * globals;
+ bfd_vma val;
+ bfd_size_type size;
+
+ globals = elf32_arm_hash_table (link_info);
+ BFD_ASSERT (globals != NULL);
+ BFD_ASSERT (globals->bfd_of_glue_owner != NULL);
+
+ s = bfd_get_linker_section
+ (globals->bfd_of_glue_owner, ARM2THUMB_GLUE_SECTION_NAME);
+
+ BFD_ASSERT (s != NULL);
+
+ tmp_name = (char *) bfd_malloc ((bfd_size_type) 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)
+ {
+ /* We've already seen this guy. */
+ free (tmp_name);
+ return myh;
+ }
+
+ /* 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. The +1 on the value marks that the stub has not been
+ output yet - not that it is a Thumb function. */
+ bh = NULL;
+ val = globals->arm_glue_size + 1;
+ _bfd_generic_link_add_one_symbol (link_info, globals->bfd_of_glue_owner,
+ tmp_name, BSF_GLOBAL, s, val,
+ NULL, TRUE, FALSE, &bh);
+
+ myh = (struct elf_link_hash_entry *) bh;
+ myh->type = ELF_ST_INFO (STB_LOCAL, STT_FUNC);
+ myh->forced_local = 1;
+
+ free (tmp_name);
+
+ if (link_info->shared || globals->root.is_relocatable_executable
+ || globals->pic_veneer)
+ size = ARM2THUMB_PIC_GLUE_SIZE;
+ else if (globals->use_blx)
+ size = ARM2THUMB_V5_STATIC_GLUE_SIZE;
+ else
+ size = ARM2THUMB_STATIC_GLUE_SIZE;
+
+ s->size += size;
+ globals->arm_glue_size += size;
+
+ return myh;
+}
+
+/* Allocate space for ARMv4 BX veneers. */
+
+static void
+record_arm_bx_glue (struct bfd_link_info * link_info, int reg)
+{
+ asection * s;
+ struct elf32_arm_link_hash_table *globals;
+ char *tmp_name;
+ struct elf_link_hash_entry *myh;
+ struct bfd_link_hash_entry *bh;
+ bfd_vma val;
+
+ /* BX PC does not need a veneer. */
+ if (reg == 15)
+ return;
+
+ globals = elf32_arm_hash_table (link_info);
+ BFD_ASSERT (globals != NULL);
+ BFD_ASSERT (globals->bfd_of_glue_owner != NULL);
+
+ /* Check if this veneer has already been allocated. */
+ if (globals->bx_glue_offset[reg])
+ return;
+
+ s = bfd_get_linker_section
+ (globals->bfd_of_glue_owner, ARM_BX_GLUE_SECTION_NAME);
+
+ BFD_ASSERT (s != NULL);
+
+ /* Add symbol for veneer. */
+ tmp_name = (char *)
+ bfd_malloc ((bfd_size_type) strlen (ARM_BX_GLUE_ENTRY_NAME) + 1);
+
+ BFD_ASSERT (tmp_name);
+
+ sprintf (tmp_name, ARM_BX_GLUE_ENTRY_NAME, reg);
+
+ myh = elf_link_hash_lookup
+ (&(globals)->root, tmp_name, FALSE, FALSE, FALSE);
+
+ BFD_ASSERT (myh == NULL);
+
+ bh = NULL;
+ val = globals->bx_glue_size;
+ _bfd_generic_link_add_one_symbol (link_info, globals->bfd_of_glue_owner,
+ tmp_name, BSF_FUNCTION | BSF_LOCAL, s, val,
+ NULL, TRUE, FALSE, &bh);
+
+ myh = (struct elf_link_hash_entry *) bh;
+ myh->type = ELF_ST_INFO (STB_LOCAL, STT_FUNC);
+ myh->forced_local = 1;
+
+ s->size += ARM_BX_VENEER_SIZE;
+ globals->bx_glue_offset[reg] = globals->bx_glue_size | 2;
+ globals->bx_glue_size += ARM_BX_VENEER_SIZE;
+}
+
+
+/* Add an entry to the code/data map for section SEC. */
+
+static void
+elf32_arm_section_map_add (asection *sec, char type, bfd_vma vma)
+{
+ struct _arm_elf_section_data *sec_data = elf32_arm_section_data (sec);
+ unsigned int newidx;
+
+ if (sec_data->map == NULL)
+ {
+ sec_data->map = (elf32_arm_section_map *)
+ bfd_malloc (sizeof (elf32_arm_section_map));
+ sec_data->mapcount = 0;
+ sec_data->mapsize = 1;
+ }
+
+ newidx = sec_data->mapcount++;
+
+ if (sec_data->mapcount > sec_data->mapsize)
+ {
+ sec_data->mapsize *= 2;
+ sec_data->map = (elf32_arm_section_map *)
+ bfd_realloc_or_free (sec_data->map, sec_data->mapsize
+ * sizeof (elf32_arm_section_map));
+ }
+
+ if (sec_data->map)
+ {
+ sec_data->map[newidx].vma = vma;
+ sec_data->map[newidx].type = type;
+ }
+}
+
+
+/* Record information about a VFP11 denorm-erratum veneer. Only ARM-mode
+ veneers are handled for now. */
+
+static bfd_vma
+record_vfp11_erratum_veneer (struct bfd_link_info *link_info,
+ elf32_vfp11_erratum_list *branch,
+ bfd *branch_bfd,
+ asection *branch_sec,
+ unsigned int offset)
+{
+ asection *s;
+ struct elf32_arm_link_hash_table *hash_table;
+ char *tmp_name;
+ struct elf_link_hash_entry *myh;
+ struct bfd_link_hash_entry *bh;
+ bfd_vma val;
+ struct _arm_elf_section_data *sec_data;
+ elf32_vfp11_erratum_list *newerr;
+
+ 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_linker_section
+ (hash_table->bfd_of_glue_owner, VFP11_ERRATUM_VENEER_SECTION_NAME);
+
+ sec_data = elf32_arm_section_data (s);
+
+ BFD_ASSERT (s != NULL);
+
+ tmp_name = (char *) bfd_malloc ((bfd_size_type) strlen
+ (VFP11_ERRATUM_VENEER_ENTRY_NAME) + 10);
+
+ BFD_ASSERT (tmp_name);
+
+ sprintf (tmp_name, VFP11_ERRATUM_VENEER_ENTRY_NAME,
+ hash_table->num_vfp11_fixes);
+
+ myh = elf_link_hash_lookup
+ (&(hash_table)->root, tmp_name, FALSE, FALSE, FALSE);
+
+ BFD_ASSERT (myh == NULL);
+
+ bh = NULL;
+ val = hash_table->vfp11_erratum_glue_size;
+ _bfd_generic_link_add_one_symbol (link_info, hash_table->bfd_of_glue_owner,
+ tmp_name, BSF_FUNCTION | BSF_LOCAL, s, val,
+ NULL, TRUE, FALSE, &bh);
+
+ myh = (struct elf_link_hash_entry *) bh;
+ myh->type = ELF_ST_INFO (STB_LOCAL, STT_FUNC);
+ myh->forced_local = 1;
+
+ /* Link veneer back to calling location. */
+ sec_data->erratumcount += 1;
+ newerr = (elf32_vfp11_erratum_list *)
+ bfd_zmalloc (sizeof (elf32_vfp11_erratum_list));
+
+ newerr->type = VFP11_ERRATUM_ARM_VENEER;
+ newerr->vma = -1;
+ newerr->u.v.branch = branch;
+ newerr->u.v.id = hash_table->num_vfp11_fixes;
+ branch->u.b.veneer = newerr;
+
+ newerr->next = sec_data->erratumlist;
+ sec_data->erratumlist = newerr;
+
+ /* A symbol for the return from the veneer. */
+ sprintf (tmp_name, VFP11_ERRATUM_VENEER_ENTRY_NAME "_r",
+ hash_table->num_vfp11_fixes);
+
+ myh = elf_link_hash_lookup
+ (&(hash_table)->root, tmp_name, FALSE, FALSE, FALSE);
+
+ if (myh != NULL)
+ abort ();
+
+ bh = NULL;
+ val = offset + 4;
+ _bfd_generic_link_add_one_symbol (link_info, branch_bfd, tmp_name, BSF_LOCAL,
+ branch_sec, val, NULL, TRUE, FALSE, &bh);
+
+ myh = (struct elf_link_hash_entry *) bh;
+ myh->type = ELF_ST_INFO (STB_LOCAL, STT_FUNC);
+ myh->forced_local = 1;
+
+ free (tmp_name);
+
+ /* Generate a mapping symbol for the veneer section, and explicitly add an
+ entry for that symbol to the code/data map for the section. */
+ if (hash_table->vfp11_erratum_glue_size == 0)
+ {
+ bh = NULL;
+ /* FIXME: Creates an ARM symbol. Thumb mode will need attention if it
+ ever requires this erratum fix. */
+ _bfd_generic_link_add_one_symbol (link_info,
+ hash_table->bfd_of_glue_owner, "$a",
+ BSF_LOCAL, s, 0, NULL,
+ TRUE, FALSE, &bh);
+
+ myh = (struct elf_link_hash_entry *) bh;
+ myh->type = ELF_ST_INFO (STB_LOCAL, STT_NOTYPE);
+ myh->forced_local = 1;
+
+ /* The elf32_arm_init_maps function only cares about symbols from input
+ BFDs. We must make a note of this generated mapping symbol
+ ourselves so that code byteswapping works properly in
+ elf32_arm_write_section. */
+ elf32_arm_section_map_add (s, 'a', 0);
+ }
+
+ s->size += VFP11_ERRATUM_VENEER_SIZE;
+ hash_table->vfp11_erratum_glue_size += VFP11_ERRATUM_VENEER_SIZE;
+ hash_table->num_vfp11_fixes++;
+
+ /* The offset of the veneer. */
+ return val;
+}
+
+#define ARM_GLUE_SECTION_FLAGS \
+ (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_CODE \
+ | SEC_READONLY | SEC_LINKER_CREATED)
+
+/* Create a fake section for use by the ARM backend of the linker. */
+
+static bfd_boolean
+arm_make_glue_section (bfd * abfd, const char * name)
+{
+ asection * sec;
+
+ sec = bfd_get_linker_section (abfd, name);
+ if (sec != NULL)
+ /* Already made. */
+ return TRUE;
+
+ sec = bfd_make_section_anyway_with_flags (abfd, name, ARM_GLUE_SECTION_FLAGS);
+
+ if (sec == NULL
+ || !bfd_set_section_alignment (abfd, sec, 2))
+ return FALSE;
+
+ /* Set the gc mark to prevent the section from being removed by garbage
+ collection, despite the fact that no relocs refer to this section. */
+ sec->gc_mark = 1;
+
+ return TRUE;
+}
+
+/* Set size of .plt entries. This function is called from the
+ linker scripts in ld/emultempl/{armelf}.em. */
+
+void
+bfd_elf32_arm_use_long_plt (void)
+{
+ elf32_arm_use_long_plt_entry = TRUE;
+}
+
+/* Add the glue sections to ABFD. This function is called from the
+ linker scripts in ld/emultempl/{armelf}.em. */
+
+bfd_boolean
+bfd_elf32_arm_add_glue_sections_to_bfd (bfd *abfd,
+ struct bfd_link_info *info)
+{
+ /* If we are only performing a partial
+ link do not bother adding the glue. */
+ if (info->relocatable)
+ return TRUE;
+
+ return arm_make_glue_section (abfd, ARM2THUMB_GLUE_SECTION_NAME)
+ && arm_make_glue_section (abfd, THUMB2ARM_GLUE_SECTION_NAME)
+ && arm_make_glue_section (abfd, VFP11_ERRATUM_VENEER_SECTION_NAME)
+ && arm_make_glue_section (abfd, ARM_BX_GLUE_SECTION_NAME);
+}
+
+/* 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. */
+
+bfd_boolean
+bfd_elf32_arm_get_bfd_for_interworking (bfd *abfd, struct bfd_link_info *info)
+{
+ struct elf32_arm_link_hash_table *globals;
+
+ /* If we are only performing a partial link
+ do not bother getting a bfd to hold the glue. */
+ if (info->relocatable)
+ return TRUE;
+
+ /* Make sure we don't attach the glue sections to a dynamic object. */
+ BFD_ASSERT (!(abfd->flags & DYNAMIC));
+
+ globals = elf32_arm_hash_table (info);
+ BFD_ASSERT (globals != NULL);
+
+ if (globals->bfd_of_glue_owner != NULL)
+ return TRUE;
+
+ /* Save the bfd for later use. */
+ globals->bfd_of_glue_owner = abfd;
+
+ return TRUE;
+}
+
+static void
+check_use_blx (struct elf32_arm_link_hash_table *globals)
+{
+ int cpu_arch;
+
+ cpu_arch = bfd_elf_get_obj_attr_int (globals->obfd, OBJ_ATTR_PROC,
+ Tag_CPU_arch);
+
+ if (globals->fix_arm1176)
+ {
+ if (cpu_arch == TAG_CPU_ARCH_V6T2 || cpu_arch > TAG_CPU_ARCH_V6K)
+ globals->use_blx = 1;
+ }
+ else
+ {
+ if (cpu_arch > TAG_CPU_ARCH_V4T)
+ globals->use_blx = 1;
+ }
+}
+
+bfd_boolean
+bfd_elf32_arm_process_before_allocation (bfd *abfd,
+ struct bfd_link_info *link_info)
+{
+ Elf_Internal_Shdr *symtab_hdr;
+ Elf_Internal_Rela *internal_relocs = NULL;
+ Elf_Internal_Rela *irel, *irelend;
+ bfd_byte *contents = 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->relocatable)
+ 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);
+
+ check_use_blx (globals);
+
+ if (globals->byteswap_code && !bfd_big_endian (abfd))
+ {
+ _bfd_error_handler (_("%B: BE8 images only valid in big-endian mode."),
+ abfd);
+ return FALSE;
+ }
+
+ /* PR 5398: If we have not decided to include any loadable sections in
+ the output then we will not have a glue owner bfd. This is OK, it
+ just means that there is nothing else for us to do here. */
+ if (globals->bfd_of_glue_owner == NULL)
+ return TRUE;
+
+ /* 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;
+
+ if ((sec->flags & SEC_EXCLUDE) != 0)
+ continue;
+
+ symtab_hdr = & elf_symtab_hdr (abfd);
+
+ /* Load the relocs. */
+ internal_relocs
+ = _bfd_elf_link_read_relocs (abfd, sec, NULL, NULL, FALSE);
+
+ if (internal_relocs == NULL)
+ goto error_return;
+
+ irelend = internal_relocs + sec->reloc_count;
+ for (irel = internal_relocs; irel < irelend; irel++)
+ {
+ long r_type;
+ unsigned long r_index;
+
+ 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_V4BX || globals->fix_v4bx < 2))
+ 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. */
+ if (! bfd_malloc_and_get_section (abfd, sec, &contents))
+ goto error_return;
+ }
+ }
+
+ if (r_type == R_ARM_V4BX)
+ {
+ int reg;
+
+ reg = bfd_get_32 (abfd, contents + irel->r_offset) & 0xf;
+ record_arm_bx_glue (link_info, reg);
+ continue;
+ }
+
+ /* 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;
+
+ /* If the call will go through a PLT entry then we do not need
+ glue. */
+ if (globals->root.splt != NULL && h->plt.offset != (bfd_vma) -1)
+ 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 (h->target_internal == ST_BRANCH_TO_THUMB)
+ record_arm_to_thumb_glue (link_info, h);
+ break;
+
+ default:
+ abort ();
+ }
+ }
+
+ if (contents != NULL
+ && elf_section_data (sec)->this_hdr.contents != contents)
+ free (contents);
+ contents = NULL;
+
+ if (internal_relocs != NULL
+ && elf_section_data (sec)->relocs != internal_relocs)
+ free (internal_relocs);
+ internal_relocs = NULL;
+ }
+
+ return TRUE;
+
+error_return:
+ if (contents != NULL
+ && elf_section_data (sec)->this_hdr.contents != contents)
+ free (contents);
+ if (internal_relocs != NULL
+ && elf_section_data (sec)->relocs != internal_relocs)
+ free (internal_relocs);
+
+ return FALSE;
+}
+#endif
+
+
+/* Initialise maps of ARM/Thumb/data for input BFDs. */
+
+void
+bfd_elf32_arm_init_maps (bfd *abfd)
+{
+ Elf_Internal_Sym *isymbuf;
+ Elf_Internal_Shdr *hdr;
+ unsigned int i, localsyms;
+
+ /* PR 7093: Make sure that we are dealing with an arm elf binary. */
+ if (! is_arm_elf (abfd))
+ return;
+
+ if ((abfd->flags & DYNAMIC) != 0)
+ return;
+
+ hdr = & elf_symtab_hdr (abfd);
+ localsyms = hdr->sh_info;
+
+ /* Obtain a buffer full of symbols for this BFD. The hdr->sh_info field
+ should contain the number of local symbols, which should come before any
+ global symbols. Mapping symbols are always local. */
+ isymbuf = bfd_elf_get_elf_syms (abfd, hdr, localsyms, 0, NULL, NULL,
+ NULL);
+
+ /* No internal symbols read? Skip this BFD. */
+ if (isymbuf == NULL)
+ return;
+
+ for (i = 0; i < localsyms; i++)
+ {
+ Elf_Internal_Sym *isym = &isymbuf[i];
+ asection *sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
+ const char *name;
+
+ if (sec != NULL
+ && ELF_ST_BIND (isym->st_info) == STB_LOCAL)
+ {
+ name = bfd_elf_string_from_elf_section (abfd,
+ hdr->sh_link, isym->st_name);
+
+ if (bfd_is_arm_special_symbol_name (name,
+ BFD_ARM_SPECIAL_SYM_TYPE_MAP))
+ elf32_arm_section_map_add (sec, name[1], isym->st_value);
+ }
+ }
+}
+
+
+/* Auto-select enabling of Cortex-A8 erratum fix if the user didn't explicitly
+ say what they wanted. */
+
+void
+bfd_elf32_arm_set_cortex_a8_fix (bfd *obfd, struct bfd_link_info *link_info)
+{
+ struct elf32_arm_link_hash_table *globals = elf32_arm_hash_table (link_info);
+ obj_attribute *out_attr = elf_known_obj_attributes_proc (obfd);
+
+ if (globals == NULL)
+ return;
+
+ if (globals->fix_cortex_a8 == -1)
+ {
+ /* Turn on Cortex-A8 erratum workaround for ARMv7-A. */
+ if (out_attr[Tag_CPU_arch].i == TAG_CPU_ARCH_V7
+ && (out_attr[Tag_CPU_arch_profile].i == 'A'
+ || out_attr[Tag_CPU_arch_profile].i == 0))
+ globals->fix_cortex_a8 = 1;
+ else
+ globals->fix_cortex_a8 = 0;
+ }
+}
+
+
+void
+bfd_elf32_arm_set_vfp11_fix (bfd *obfd, struct bfd_link_info *link_info)
+{
+ struct elf32_arm_link_hash_table *globals = elf32_arm_hash_table (link_info);
+ obj_attribute *out_attr = elf_known_obj_attributes_proc (obfd);
+
+ if (globals == NULL)
+ return;
+ /* We assume that ARMv7+ does not need the VFP11 denorm erratum fix. */
+ if (out_attr[Tag_CPU_arch].i >= TAG_CPU_ARCH_V7)
+ {
+ switch (globals->vfp11_fix)
+ {
+ case BFD_ARM_VFP11_FIX_DEFAULT:
+ case BFD_ARM_VFP11_FIX_NONE:
+ globals->vfp11_fix = BFD_ARM_VFP11_FIX_NONE;
+ break;
+
+ default:
+ /* Give a warning, but do as the user requests anyway. */
+ (*_bfd_error_handler) (_("%B: warning: selected VFP11 erratum "
+ "workaround is not necessary for target architecture"), obfd);
+ }
+ }
+ else if (globals->vfp11_fix == BFD_ARM_VFP11_FIX_DEFAULT)
+ /* For earlier architectures, we might need the workaround, but do not
+ enable it by default. If users is running with broken hardware, they
+ must enable the erratum fix explicitly. */
+ globals->vfp11_fix = BFD_ARM_VFP11_FIX_NONE;
+}
+
+
+enum bfd_arm_vfp11_pipe
+{
+ VFP11_FMAC,
+ VFP11_LS,
+ VFP11_DS,
+ VFP11_BAD
+};
+
+/* Return a VFP register number. This is encoded as RX:X for single-precision
+ registers, or X:RX for double-precision registers, where RX is the group of
+ four bits in the instruction encoding and X is the single extension bit.
+ RX and X fields are specified using their lowest (starting) bit. The return
+ value is:
+
+ 0...31: single-precision registers s0...s31
+ 32...63: double-precision registers d0...d31.
+
+ Although X should be zero for VFP11 (encoding d0...d15 only), we might
+ encounter VFP3 instructions, so we allow the full range for DP registers. */
+
+static unsigned int
+bfd_arm_vfp11_regno (unsigned int insn, bfd_boolean is_double, unsigned int rx,
+ unsigned int x)
+{
+ if (is_double)
+ return (((insn >> rx) & 0xf) | (((insn >> x) & 1) << 4)) + 32;
+ else
+ return (((insn >> rx) & 0xf) << 1) | ((insn >> x) & 1);
+}
+
+/* Set bits in *WMASK according to a register number REG as encoded by
+ bfd_arm_vfp11_regno(). Ignore d16-d31. */
+
+static void
+bfd_arm_vfp11_write_mask (unsigned int *wmask, unsigned int reg)
+{
+ if (reg < 32)
+ *wmask |= 1 << reg;
+ else if (reg < 48)
+ *wmask |= 3 << ((reg - 32) * 2);
+}
+
+/* Return TRUE if WMASK overwrites anything in REGS. */
+
+static bfd_boolean
+bfd_arm_vfp11_antidependency (unsigned int wmask, int *regs, int numregs)
+{
+ int i;
+
+ for (i = 0; i < numregs; i++)
+ {
+ unsigned int reg = regs[i];
+
+ if (reg < 32 && (wmask & (1 << reg)) != 0)
+ return TRUE;
+
+ reg -= 32;
+
+ if (reg >= 16)
+ continue;
+
+ if ((wmask & (3 << (reg * 2))) != 0)
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/* In this function, we're interested in two things: finding input registers
+ for VFP data-processing instructions, and finding the set of registers which
+ arbitrary VFP instructions may write to. We use a 32-bit unsigned int to
+ hold the written set, so FLDM etc. are easy to deal with (we're only
+ interested in 32 SP registers or 16 dp registers, due to the VFP version
+ implemented by the chip in question). DP registers are marked by setting
+ both SP registers in the write mask). */
+
+static enum bfd_arm_vfp11_pipe
+bfd_arm_vfp11_insn_decode (unsigned int insn, unsigned int *destmask, int *regs,
+ int *numregs)
+{
+ enum bfd_arm_vfp11_pipe vpipe = VFP11_BAD;
+ bfd_boolean is_double = ((insn & 0xf00) == 0xb00) ? 1 : 0;
+
+ if ((insn & 0x0f000e10) == 0x0e000a00) /* A data-processing insn. */
+ {
+ unsigned int pqrs;
+ unsigned int fd = bfd_arm_vfp11_regno (insn, is_double, 12, 22);
+ unsigned int fm = bfd_arm_vfp11_regno (insn, is_double, 0, 5);
+
+ pqrs = ((insn & 0x00800000) >> 20)
+ | ((insn & 0x00300000) >> 19)
+ | ((insn & 0x00000040) >> 6);
+
+ switch (pqrs)
+ {
+ case 0: /* fmac[sd]. */
+ case 1: /* fnmac[sd]. */
+ case 2: /* fmsc[sd]. */
+ case 3: /* fnmsc[sd]. */
+ vpipe = VFP11_FMAC;
+ bfd_arm_vfp11_write_mask (destmask, fd);
+ regs[0] = fd;
+ regs[1] = bfd_arm_vfp11_regno (insn, is_double, 16, 7); /* Fn. */
+ regs[2] = fm;
+ *numregs = 3;
+ break;
+
+ case 4: /* fmul[sd]. */
+ case 5: /* fnmul[sd]. */
+ case 6: /* fadd[sd]. */
+ case 7: /* fsub[sd]. */
+ vpipe = VFP11_FMAC;
+ goto vfp_binop;
+
+ case 8: /* fdiv[sd]. */
+ vpipe = VFP11_DS;
+ vfp_binop:
+ bfd_arm_vfp11_write_mask (destmask, fd);
+ regs[0] = bfd_arm_vfp11_regno (insn, is_double, 16, 7); /* Fn. */
+ regs[1] = fm;
+ *numregs = 2;
+ break;
+
+ case 15: /* extended opcode. */
+ {
+ unsigned int extn = ((insn >> 15) & 0x1e)
+ | ((insn >> 7) & 1);
+
+ switch (extn)
+ {
+ case 0: /* fcpy[sd]. */
+ case 1: /* fabs[sd]. */
+ case 2: /* fneg[sd]. */
+ case 8: /* fcmp[sd]. */
+ case 9: /* fcmpe[sd]. */
+ case 10: /* fcmpz[sd]. */
+ case 11: /* fcmpez[sd]. */
+ case 16: /* fuito[sd]. */
+ case 17: /* fsito[sd]. */
+ case 24: /* ftoui[sd]. */
+ case 25: /* ftouiz[sd]. */
+ case 26: /* ftosi[sd]. */
+ case 27: /* ftosiz[sd]. */
+ /* These instructions will not bounce due to underflow. */
+ *numregs = 0;
+ vpipe = VFP11_FMAC;
+ break;
+
+ case 3: /* fsqrt[sd]. */
+ /* fsqrt cannot underflow, but it can (perhaps) overwrite
+ registers to cause the erratum in previous instructions. */
+ bfd_arm_vfp11_write_mask (destmask, fd);
+ vpipe = VFP11_DS;
+ break;
+
+ case 15: /* fcvt{ds,sd}. */
+ {
+ int rnum = 0;
+
+ bfd_arm_vfp11_write_mask (destmask, fd);
+
+ /* Only FCVTSD can underflow. */
+ if ((insn & 0x100) != 0)
+ regs[rnum++] = fm;
+
+ *numregs = rnum;
+
+ vpipe = VFP11_FMAC;
+ }
+ break;
+
+ default:
+ return VFP11_BAD;
+ }
+ }
+ break;
+
+ default:
+ return VFP11_BAD;
+ }
+ }
+ /* Two-register transfer. */
+ else if ((insn & 0x0fe00ed0) == 0x0c400a10)
+ {
+ unsigned int fm = bfd_arm_vfp11_regno (insn, is_double, 0, 5);
+
+ if ((insn & 0x100000) == 0)
+ {
+ if (is_double)
+ bfd_arm_vfp11_write_mask (destmask, fm);
+ else
+ {
+ bfd_arm_vfp11_write_mask (destmask, fm);
+ bfd_arm_vfp11_write_mask (destmask, fm + 1);
+ }
+ }
+
+ vpipe = VFP11_LS;
+ }
+ else if ((insn & 0x0e100e00) == 0x0c100a00) /* A load insn. */
+ {
+ int fd = bfd_arm_vfp11_regno (insn, is_double, 12, 22);
+ unsigned int puw = ((insn >> 21) & 0x1) | (((insn >> 23) & 3) << 1);
+
+ switch (puw)
+ {
+ case 0: /* Two-reg transfer. We should catch these above. */
+ abort ();
+
+ case 2: /* fldm[sdx]. */
+ case 3:
+ case 5:
+ {
+ unsigned int i, offset = insn & 0xff;
+
+ if (is_double)
+ offset >>= 1;
+
+ for (i = fd; i < fd + offset; i++)
+ bfd_arm_vfp11_write_mask (destmask, i);
+ }
+ break;
+
+ case 4: /* fld[sd]. */
+ case 6:
+ bfd_arm_vfp11_write_mask (destmask, fd);
+ break;
+
+ default:
+ return VFP11_BAD;
+ }
+
+ vpipe = VFP11_LS;
+ }
+ /* Single-register transfer. Note L==0. */
+ else if ((insn & 0x0f100e10) == 0x0e000a10)
+ {
+ unsigned int opcode = (insn >> 21) & 7;
+ unsigned int fn = bfd_arm_vfp11_regno (insn, is_double, 16, 7);
+
+ switch (opcode)
+ {
+ case 0: /* fmsr/fmdlr. */
+ case 1: /* fmdhr. */
+ /* Mark fmdhr and fmdlr as writing to the whole of the DP
+ destination register. I don't know if this is exactly right,
+ but it is the conservative choice. */
+ bfd_arm_vfp11_write_mask (destmask, fn);
+ break;
+
+ case 7: /* fmxr. */
+ break;
+ }
+
+ vpipe = VFP11_LS;
+ }
+
+ return vpipe;
+}
+
+
+static int elf32_arm_compare_mapping (const void * a, const void * b);
+
+
+/* Look for potentially-troublesome code sequences which might trigger the
+ VFP11 denormal/antidependency erratum. See, e.g., the ARM1136 errata sheet
+ (available from ARM) for details of the erratum. A short version is
+ described in ld.texinfo. */
+
+bfd_boolean
+bfd_elf32_arm_vfp11_erratum_scan (bfd *abfd, struct bfd_link_info *link_info)
+{
+ asection *sec;
+ bfd_byte *contents = NULL;
+ int state = 0;
+ int regs[3], numregs = 0;
+ struct elf32_arm_link_hash_table *globals = elf32_arm_hash_table (link_info);
+ int use_vector = (globals->vfp11_fix == BFD_ARM_VFP11_FIX_VECTOR);
+
+ if (globals == NULL)
+ return FALSE;
+
+ /* We use a simple FSM to match troublesome VFP11 instruction sequences.
+ The states transition as follows:
+
+ 0 -> 1 (vector) or 0 -> 2 (scalar)
+ A VFP FMAC-pipeline instruction has been seen. Fill
+ regs[0]..regs[numregs-1] with its input operands. Remember this
+ instruction in 'first_fmac'.
+
+ 1 -> 2
+ Any instruction, except for a VFP instruction which overwrites
+ regs[*].
+
+ 1 -> 3 [ -> 0 ] or
+ 2 -> 3 [ -> 0 ]
+ A VFP instruction has been seen which overwrites any of regs[*].
+ We must make a veneer! Reset state to 0 before examining next
+ instruction.
+
+ 2 -> 0
+ If we fail to match anything in state 2, reset to state 0 and reset
+ the instruction pointer to the instruction after 'first_fmac'.
+
+ If the VFP11 vector mode is in use, there must be at least two unrelated
+ instructions between anti-dependent VFP11 instructions to properly avoid
+ triggering the erratum, hence the use of the extra state 1. */
+
+ /* If we are only performing a partial link do not bother
+ to construct any glue. */
+ if (link_info->relocatable)
+ return TRUE;
+
+ /* Skip if this bfd does not correspond to an ELF image. */
+ if (! is_arm_elf (abfd))
+ return TRUE;
+
+ /* We should have chosen a fix type by the time we get here. */
+ BFD_ASSERT (globals->vfp11_fix != BFD_ARM_VFP11_FIX_DEFAULT);
+
+ if (globals->vfp11_fix == BFD_ARM_VFP11_FIX_NONE)
+ return TRUE;
+
+ /* Skip this BFD if it corresponds to an executable or dynamic object. */
+ if ((abfd->flags & (EXEC_P | DYNAMIC)) != 0)
+ return TRUE;
+
+ for (sec = abfd->sections; sec != NULL; sec = sec->next)
+ {
+ unsigned int i, span, first_fmac = 0, veneer_of_insn = 0;
+ struct _arm_elf_section_data *sec_data;
+
+ /* If we don't have executable progbits, we're not interested in this
+ section. Also skip if section is to be excluded. */
+ if (elf_section_type (sec) != SHT_PROGBITS
+ || (elf_section_flags (sec) & SHF_EXECINSTR) == 0
+ || (sec->flags & SEC_EXCLUDE) != 0
+ || sec->sec_info_type == SEC_INFO_TYPE_JUST_SYMS
+ || sec->output_section == bfd_abs_section_ptr
+ || strcmp (sec->name, VFP11_ERRATUM_VENEER_SECTION_NAME) == 0)
+ continue;
+
+ sec_data = elf32_arm_section_data (sec);
+
+ if (sec_data->mapcount == 0)
+ continue;
+
+ if (elf_section_data (sec)->this_hdr.contents != NULL)
+ contents = elf_section_data (sec)->this_hdr.contents;
+ else if (! bfd_malloc_and_get_section (abfd, sec, &contents))
+ goto error_return;
+
+ qsort (sec_data->map, sec_data->mapcount, sizeof (elf32_arm_section_map),
+ elf32_arm_compare_mapping);
+
+ for (span = 0; span < sec_data->mapcount; span++)
+ {
+ unsigned int span_start = sec_data->map[span].vma;
+ unsigned int span_end = (span == sec_data->mapcount - 1)
+ ? sec->size : sec_data->map[span + 1].vma;
+ char span_type = sec_data->map[span].type;
+
+ /* FIXME: Only ARM mode is supported at present. We may need to
+ support Thumb-2 mode also at some point. */
+ if (span_type != 'a')
+ continue;
+
+ for (i = span_start; i < span_end;)
+ {
+ unsigned int next_i = i + 4;
+ unsigned int insn = bfd_big_endian (abfd)
+ ? (contents[i] << 24)
+ | (contents[i + 1] << 16)
+ | (contents[i + 2] << 8)
+ | contents[i + 3]
+ : (contents[i + 3] << 24)
+ | (contents[i + 2] << 16)
+ | (contents[i + 1] << 8)
+ | contents[i];
+ unsigned int writemask = 0;
+ enum bfd_arm_vfp11_pipe vpipe;
+
+ switch (state)
+ {
+ case 0:
+ vpipe = bfd_arm_vfp11_insn_decode (insn, &writemask, regs,
+ &numregs);
+ /* I'm assuming the VFP11 erratum can trigger with denorm
+ operands on either the FMAC or the DS pipeline. This might
+ lead to slightly overenthusiastic veneer insertion. */
+ if (vpipe == VFP11_FMAC || vpipe == VFP11_DS)
+ {
+ state = use_vector ? 1 : 2;
+ first_fmac = i;
+ veneer_of_insn = insn;
+ }
+ break;
+
+ case 1:
+ {
+ int other_regs[3], other_numregs;
+ vpipe = bfd_arm_vfp11_insn_decode (insn, &writemask,
+ other_regs,
+ &other_numregs);
+ if (vpipe != VFP11_BAD
+ && bfd_arm_vfp11_antidependency (writemask, regs,
+ numregs))
+ state = 3;
+ else
+ state = 2;
+ }
+ break;
+
+ case 2:
+ {
+ int other_regs[3], other_numregs;
+ vpipe = bfd_arm_vfp11_insn_decode (insn, &writemask,
+ other_regs,
+ &other_numregs);
+ if (vpipe != VFP11_BAD
+ && bfd_arm_vfp11_antidependency (writemask, regs,
+ numregs))
+ state = 3;
+ else
+ {
+ state = 0;
+ next_i = first_fmac + 4;
+ }
+ }
+ break;
+
+ case 3:
+ abort (); /* Should be unreachable. */
+ }
+
+ if (state == 3)
+ {
+ elf32_vfp11_erratum_list *newerr =(elf32_vfp11_erratum_list *)
+ bfd_zmalloc (sizeof (elf32_vfp11_erratum_list));
+
+ elf32_arm_section_data (sec)->erratumcount += 1;
+
+ newerr->u.b.vfp_insn = veneer_of_insn;
+
+ switch (span_type)
+ {
+ case 'a':
+ newerr->type = VFP11_ERRATUM_BRANCH_TO_ARM_VENEER;
+ break;
+
+ default:
+ abort ();
+ }
+
+ record_vfp11_erratum_veneer (link_info, newerr, abfd, sec,
+ first_fmac);
+
+ newerr->vma = -1;
+
+ newerr->next = sec_data->erratumlist;
+ sec_data->erratumlist = newerr;
+
+ state = 0;
+ }
+
+ i = next_i;
+ }
+ }
+
+ if (contents != NULL
+ && elf_section_data (sec)->this_hdr.contents != contents)
+ free (contents);
+ contents = NULL;
+ }
+
+ return TRUE;
+
+error_return:
+ if (contents != NULL
+ && elf_section_data (sec)->this_hdr.contents != contents)
+ free (contents);
+
+ return FALSE;
+}
+
+/* Find virtual-memory addresses for VFP11 erratum veneers and return locations
+ after sections have been laid out, using specially-named symbols. */
+
+void
+bfd_elf32_arm_vfp11_fix_veneer_locations (bfd *abfd,
+ struct bfd_link_info *link_info)
+{
+ asection *sec;
+ struct elf32_arm_link_hash_table *globals;
+ char *tmp_name;
+
+ if (link_info->relocatable)
+ return;
+
+ /* Skip if this bfd does not correspond to an ELF image. */
+ if (! is_arm_elf (abfd))
+ return;
+
+ globals = elf32_arm_hash_table (link_info);
+ if (globals == NULL)
+ return;
+
+ tmp_name = (char *) bfd_malloc ((bfd_size_type) strlen
+ (VFP11_ERRATUM_VENEER_ENTRY_NAME) + 10);
+
+ for (sec = abfd->sections; sec != NULL; sec = sec->next)
+ {
+ struct _arm_elf_section_data *sec_data = elf32_arm_section_data (sec);
+ elf32_vfp11_erratum_list *errnode = sec_data->erratumlist;
+
+ for (; errnode != NULL; errnode = errnode->next)
+ {
+ struct elf_link_hash_entry *myh;
+ bfd_vma vma;
+
+ switch (errnode->type)
+ {
+ case VFP11_ERRATUM_BRANCH_TO_ARM_VENEER:
+ case VFP11_ERRATUM_BRANCH_TO_THUMB_VENEER:
+ /* Find veneer symbol. */
+ sprintf (tmp_name, VFP11_ERRATUM_VENEER_ENTRY_NAME,
+ errnode->u.b.veneer->u.v.id);
+
+ myh = elf_link_hash_lookup
+ (&(globals)->root, tmp_name, FALSE, FALSE, TRUE);
+
+ if (myh == NULL)
+ (*_bfd_error_handler) (_("%B: unable to find VFP11 veneer "
+ "`%s'"), abfd, tmp_name);
+
+ vma = myh->root.u.def.section->output_section->vma
+ + myh->root.u.def.section->output_offset
+ + myh->root.u.def.value;
+
+ errnode->u.b.veneer->vma = vma;
+ break;
+
+ case VFP11_ERRATUM_ARM_VENEER:
+ case VFP11_ERRATUM_THUMB_VENEER:
+ /* Find return location. */
+ sprintf (tmp_name, VFP11_ERRATUM_VENEER_ENTRY_NAME "_r",
+ errnode->u.v.id);
+
+ myh = elf_link_hash_lookup
+ (&(globals)->root, tmp_name, FALSE, FALSE, TRUE);
+
+ if (myh == NULL)
+ (*_bfd_error_handler) (_("%B: unable to find VFP11 veneer "
+ "`%s'"), abfd, tmp_name);
+
+ vma = myh->root.u.def.section->output_section->vma
+ + myh->root.u.def.section->output_offset
+ + myh->root.u.def.value;
+
+ errnode->u.v.branch->vma = vma;
+ break;
+
+ default:
+ abort ();
+ }
+ }
+ }
+
+ free (tmp_name);
+}
+
+
+/* Set target relocation values needed during linking. */
+
+void
+bfd_elf32_arm_set_target_relocs (struct bfd *output_bfd,
+ struct bfd_link_info *link_info,
+ int target1_is_rel,
+ char * target2_type,
+ int fix_v4bx,
+ int use_blx,
+ bfd_arm_vfp11_fix vfp11_fix,
+ int no_enum_warn, int no_wchar_warn,
+ int pic_veneer, int fix_cortex_a8,
+ int fix_arm1176)
+{
+ struct elf32_arm_link_hash_table *globals;
+
+ globals = elf32_arm_hash_table (link_info);
+ if (globals == NULL)
+ return;
+
+ globals->target1_is_rel = target1_is_rel;
+ if (strcmp (target2_type, "rel") == 0)
+ globals->target2_reloc = R_ARM_REL32;
+ else if (strcmp (target2_type, "abs") == 0)
+ globals->target2_reloc = R_ARM_ABS32;
+ else if (strcmp (target2_type, "got-rel") == 0)
+ globals->target2_reloc = R_ARM_GOT_PREL;
+ else
+ {
+ _bfd_error_handler (_("Invalid TARGET2 relocation type '%s'."),
+ target2_type);
+ }
+ globals->fix_v4bx = fix_v4bx;
+ globals->use_blx |= use_blx;
+ globals->vfp11_fix = vfp11_fix;
+ globals->pic_veneer = pic_veneer;
+ globals->fix_cortex_a8 = fix_cortex_a8;
+ globals->fix_arm1176 = fix_arm1176;
+
+ BFD_ASSERT (is_arm_elf (output_bfd));
+ elf_arm_tdata (output_bfd)->no_enum_size_warning = no_enum_warn;
+ elf_arm_tdata (output_bfd)->no_wchar_size_warning = no_wchar_warn;
+}
+
+/* Replace the target offset of a Thumb bl or b.w instruction. */
+
+static void
+insert_thumb_branch (bfd *abfd, long int offset, bfd_byte *insn)
+{
+ bfd_vma upper;
+ bfd_vma lower;
+ int reloc_sign;
+
+ BFD_ASSERT ((offset & 1) == 0);
+
+ upper = bfd_get_16 (abfd, insn);
+ lower = bfd_get_16 (abfd, insn + 2);
+ reloc_sign = (offset < 0) ? 1 : 0;
+ upper = (upper & ~(bfd_vma) 0x7ff)
+ | ((offset >> 12) & 0x3ff)
+ | (reloc_sign << 10);
+ lower = (lower & ~(bfd_vma) 0x2fff)
+ | (((!((offset >> 23) & 1)) ^ reloc_sign) << 13)
+ | (((!((offset >> 22) & 1)) ^ reloc_sign) << 11)
+ | ((offset >> 1) & 0x7ff);
+ bfd_put_16 (abfd, upper, insn);
+ bfd_put_16 (abfd, lower, insn + 2);
+}
+
+/* Thumb code calling an ARM function. */
+
+static int
+elf32_thumb_to_arm_stub (struct bfd_link_info * info,
+ const char * name,
+ bfd * input_bfd,
+ bfd * output_bfd,
+ asection * input_section,
+ bfd_byte * hit_data,
+ asection * sym_sec,
+ bfd_vma offset,
+ bfd_signed_vma addend,
+ bfd_vma val,
+ char **error_message)
+{
+ asection * s = 0;
+ bfd_vma my_offset;
+ long int ret_offset;
+ struct elf_link_hash_entry * myh;
+ struct elf32_arm_link_hash_table * globals;
+
+ myh = find_thumb_glue (info, name, error_message);
+ 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_linker_section (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)
+ (_("%B(%s): warning: interworking not enabled.\n"
+ " first occurrence: %B: Thumb call to ARM"),
+ sym_sec->owner, input_bfd, name);
+
+ return FALSE;
+ }
+
+ --my_offset;
+ myh->root.u.def.value = my_offset;
+
+ put_thumb_insn (globals, output_bfd, (bfd_vma) t2a1_bx_pc_insn,
+ s->contents + my_offset);
+
+ put_thumb_insn (globals, output_bfd, (bfd_vma) t2a2_noop_insn,
+ s->contents + my_offset + 2);
+
+ ret_offset =
+ /* Address of destination of the stub. */
+ ((bfd_signed_vma) val)
+ - ((bfd_signed_vma)
+ /* Offset from the start of the current section
+ to the start of the stubs. */
+ (s->output_offset
+ /* Offset of the start of this stub from the start of the stubs. */
+ + my_offset
+ /* Address of the start of the current section. */
+ + s->output_section->vma)
+ /* The branch instruction is 4 bytes into the stub. */
+ + 4
+ /* ARM branches work from the pc of the instruction + 8. */
+ + 8);
+
+ put_arm_insn (globals, output_bfd,
+ (bfd_vma) 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 =
+ /* Address of where the stub is located. */
+ (s->output_section->vma + s->output_offset + my_offset)
+ /* Address of where the BL is located. */
+ - (input_section->output_section->vma + input_section->output_offset
+ + offset)
+ /* Addend in the relocation. */
+ - addend
+ /* Biassing for PC-relative addressing. */
+ - 8;
+
+ insert_thumb_branch (input_bfd, ret_offset, hit_data - input_section->vma);
+
+ return TRUE;
+}
+
+/* Populate an Arm to Thumb stub. Returns the stub symbol. */
+
+static struct elf_link_hash_entry *
+elf32_arm_create_thumb_stub (struct bfd_link_info * info,
+ const char * name,
+ bfd * input_bfd,
+ bfd * output_bfd,
+ asection * sym_sec,
+ bfd_vma val,
+ asection * s,
+ char ** error_message)
+{
+ bfd_vma my_offset;
+ long int ret_offset;
+ struct elf_link_hash_entry * myh;
+ struct elf32_arm_link_hash_table * globals;
+
+ myh = find_arm_glue (info, name, error_message);
+ if (myh == NULL)
+ return NULL;
+
+ 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;
+
+ if ((my_offset & 0x01) == 0x01)
+ {
+ if (sym_sec != NULL
+ && sym_sec->owner != NULL
+ && !INTERWORK_FLAG (sym_sec->owner))
+ {
+ (*_bfd_error_handler)
+ (_("%B(%s): warning: interworking not enabled.\n"
+ " first occurrence: %B: arm call to thumb"),
+ sym_sec->owner, input_bfd, name);
+ }
+
+ --my_offset;
+ myh->root.u.def.value = my_offset;
+
+ if (info->shared || globals->root.is_relocatable_executable
+ || globals->pic_veneer)
+ {
+ /* For relocatable objects we can't use absolute addresses,
+ so construct the address from a relative offset. */
+ /* TODO: If the offset is small it's probably worth
+ constructing the address with adds. */
+ put_arm_insn (globals, output_bfd, (bfd_vma) a2t1p_ldr_insn,
+ s->contents + my_offset);
+ put_arm_insn (globals, output_bfd, (bfd_vma) a2t2p_add_pc_insn,
+ s->contents + my_offset + 4);
+ put_arm_insn (globals, output_bfd, (bfd_vma) a2t3p_bx_r12_insn,
+ s->contents + my_offset + 8);
+ /* Adjust the offset by 4 for the position of the add,
+ and 8 for the pipeline offset. */
+ ret_offset = (val - (s->output_offset
+ + s->output_section->vma
+ + my_offset + 12))
+ | 1;
+ bfd_put_32 (output_bfd, ret_offset,
+ s->contents + my_offset + 12);
+ }
+ else if (globals->use_blx)
+ {
+ put_arm_insn (globals, output_bfd, (bfd_vma) a2t1v5_ldr_insn,
+ s->contents + my_offset);
+
+ /* It's a thumb address. Add the low order bit. */
+ bfd_put_32 (output_bfd, val | a2t2v5_func_addr_insn,
+ s->contents + my_offset + 4);
+ }
+ else
+ {
+ put_arm_insn (globals, output_bfd, (bfd_vma) a2t1_ldr_insn,
+ s->contents + my_offset);
+
+ put_arm_insn (globals, output_bfd, (bfd_vma) 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);
+
+ my_offset += 12;
+ }
+ }
+
+ BFD_ASSERT (my_offset <= globals->arm_glue_size);
+
+ return myh;
+}
+
+/* Arm code calling a Thumb function. */
+
+static int
+elf32_arm_to_thumb_stub (struct bfd_link_info * info,
+ const char * name,
+ bfd * input_bfd,
+ bfd * output_bfd,
+ asection * input_section,
+ bfd_byte * hit_data,
+ asection * sym_sec,
+ bfd_vma offset,
+ bfd_signed_vma addend,
+ bfd_vma val,
+ char **error_message)
+{
+ unsigned long int tmp;
+ bfd_vma my_offset;
+ asection * s;
+ long int ret_offset;
+ struct elf_link_hash_entry * myh;
+ struct elf32_arm_link_hash_table * globals;
+
+ globals = elf32_arm_hash_table (info);
+ BFD_ASSERT (globals != NULL);
+ BFD_ASSERT (globals->bfd_of_glue_owner != NULL);
+
+ s = bfd_get_linker_section (globals->bfd_of_glue_owner,
+ ARM2THUMB_GLUE_SECTION_NAME);
+ BFD_ASSERT (s != NULL);
+ BFD_ASSERT (s->contents != NULL);
+ BFD_ASSERT (s->output_section != NULL);
+
+ myh = elf32_arm_create_thumb_stub (info, name, input_bfd, output_bfd,
+ sym_sec, val, s, error_message);
+ if (!myh)
+ return FALSE;
+
+ my_offset = myh->root.u.def.value;
+ 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, (bfd_vma) tmp, hit_data - input_section->vma);
+
+ return TRUE;
+}
+
+/* Populate Arm stub for an exported Thumb function. */
+
+static bfd_boolean
+elf32_arm_to_thumb_export_stub (struct elf_link_hash_entry *h, void * inf)
+{
+ struct bfd_link_info * info = (struct bfd_link_info *) inf;
+ asection * s;
+ struct elf_link_hash_entry * myh;
+ struct elf32_arm_link_hash_entry *eh;
+ struct elf32_arm_link_hash_table * globals;
+ asection *sec;
+ bfd_vma val;
+ char *error_message;
+
+ eh = elf32_arm_hash_entry (h);
+ /* Allocate stubs for exported Thumb functions on v4t. */
+ if (eh->export_glue == NULL)
+ return TRUE;
+
+ globals = elf32_arm_hash_table (info);
+ BFD_ASSERT (globals != NULL);
+ BFD_ASSERT (globals->bfd_of_glue_owner != NULL);
+
+ s = bfd_get_linker_section (globals->bfd_of_glue_owner,
+ ARM2THUMB_GLUE_SECTION_NAME);
+ BFD_ASSERT (s != NULL);
+ BFD_ASSERT (s->contents != NULL);
+ BFD_ASSERT (s->output_section != NULL);
+
+ sec = eh->export_glue->root.u.def.section;
+
+ BFD_ASSERT (sec->output_section != NULL);
+
+ val = eh->export_glue->root.u.def.value + sec->output_offset
+ + sec->output_section->vma;
+
+ myh = elf32_arm_create_thumb_stub (info, h->root.root.string,
+ h->root.u.def.section->owner,
+ globals->obfd, sec, val, s,
+ &error_message);
+ BFD_ASSERT (myh);
+ return TRUE;
+}
+
+/* Populate ARMv4 BX veneers. Returns the absolute adress of the veneer. */
+
+static bfd_vma
+elf32_arm_bx_glue (struct bfd_link_info * info, int reg)
+{
+ bfd_byte *p;
+ bfd_vma glue_addr;
+ asection *s;
+ struct elf32_arm_link_hash_table *globals;
+
+ globals = elf32_arm_hash_table (info);
+ BFD_ASSERT (globals != NULL);
+ BFD_ASSERT (globals->bfd_of_glue_owner != NULL);
+
+ s = bfd_get_linker_section (globals->bfd_of_glue_owner,
+ ARM_BX_GLUE_SECTION_NAME);
+ BFD_ASSERT (s != NULL);
+ BFD_ASSERT (s->contents != NULL);
+ BFD_ASSERT (s->output_section != NULL);
+
+ BFD_ASSERT (globals->bx_glue_offset[reg] & 2);
+
+ glue_addr = globals->bx_glue_offset[reg] & ~(bfd_vma)3;
+
+ if ((globals->bx_glue_offset[reg] & 1) == 0)
+ {
+ p = s->contents + glue_addr;
+ bfd_put_32 (globals->obfd, armbx1_tst_insn + (reg << 16), p);
+ bfd_put_32 (globals->obfd, armbx2_moveq_insn + reg, p + 4);
+ bfd_put_32 (globals->obfd, armbx3_bx_insn + reg, p + 8);
+ globals->bx_glue_offset[reg] |= 1;
+ }
+
+ return glue_addr + s->output_section->vma + s->output_offset;
+}
+
+/* Generate Arm stubs for exported Thumb symbols. */
+static void
+elf32_arm_begin_write_processing (bfd *abfd ATTRIBUTE_UNUSED,
+ struct bfd_link_info *link_info)
+{
+ struct elf32_arm_link_hash_table * globals;
+
+ if (link_info == NULL)
+ /* Ignore this if we are not called by the ELF backend linker. */
+ return;
+
+ globals = elf32_arm_hash_table (link_info);
+ if (globals == NULL)
+ return;
+
+ /* If blx is available then exported Thumb symbols are OK and there is
+ nothing to do. */
+ if (globals->use_blx)
+ return;
+
+ elf_link_hash_traverse (&globals->root, elf32_arm_to_thumb_export_stub,
+ link_info);
+}
+
+/* Reserve space for COUNT dynamic relocations in relocation selection
+ SRELOC. */
+
+static void
+elf32_arm_allocate_dynrelocs (struct bfd_link_info *info, asection *sreloc,
+ bfd_size_type count)
+{
+ struct elf32_arm_link_hash_table *htab;
+
+ htab = elf32_arm_hash_table (info);
+ BFD_ASSERT (htab->root.dynamic_sections_created);
+ if (sreloc == NULL)
+ abort ();
+ sreloc->size += RELOC_SIZE (htab) * count;
+}
+
+/* Reserve space for COUNT R_ARM_IRELATIVE relocations. If the link is
+ dynamic, the relocations should go in SRELOC, otherwise they should
+ go in the special .rel.iplt section. */
+
+static void
+elf32_arm_allocate_irelocs (struct bfd_link_info *info, asection *sreloc,
+ bfd_size_type count)
+{
+ struct elf32_arm_link_hash_table *htab;
+
+ htab = elf32_arm_hash_table (info);
+ if (!htab->root.dynamic_sections_created)
+ htab->root.irelplt->size += RELOC_SIZE (htab) * count;
+ else
+ {
+ BFD_ASSERT (sreloc != NULL);
+ sreloc->size += RELOC_SIZE (htab) * count;
+ }
+}
+
+/* Add relocation REL to the end of relocation section SRELOC. */
+
+static void
+elf32_arm_add_dynreloc (bfd *output_bfd, struct bfd_link_info *info,
+ asection *sreloc, Elf_Internal_Rela *rel)
+{
+ bfd_byte *loc;
+ struct elf32_arm_link_hash_table *htab;
+
+ htab = elf32_arm_hash_table (info);
+ if (!htab->root.dynamic_sections_created
+ && ELF32_R_TYPE (rel->r_info) == R_ARM_IRELATIVE)
+ sreloc = htab->root.irelplt;
+ if (sreloc == NULL)
+ abort ();
+ loc = sreloc->contents;
+ loc += sreloc->reloc_count++ * RELOC_SIZE (htab);
+ if (sreloc->reloc_count * RELOC_SIZE (htab) > sreloc->size)
+ abort ();
+ SWAP_RELOC_OUT (htab) (output_bfd, rel, loc);
+}
+
+/* Allocate room for a PLT entry described by ROOT_PLT and ARM_PLT.
+ IS_IPLT_ENTRY says whether the entry belongs to .iplt rather than
+ to .plt. */
+
+static void
+elf32_arm_allocate_plt_entry (struct bfd_link_info *info,
+ bfd_boolean is_iplt_entry,
+ union gotplt_union *root_plt,
+ struct arm_plt_info *arm_plt)
+{
+ struct elf32_arm_link_hash_table *htab;
+ asection *splt;
+ asection *sgotplt;
+
+ htab = elf32_arm_hash_table (info);
+
+ if (is_iplt_entry)
+ {
+ splt = htab->root.iplt;
+ sgotplt = htab->root.igotplt;
+
+ /* NaCl uses a special first entry in .iplt too. */
+ if (htab->nacl_p && splt->size == 0)
+ splt->size += htab->plt_header_size;
+
+ /* Allocate room for an R_ARM_IRELATIVE relocation in .rel.iplt. */
+ elf32_arm_allocate_irelocs (info, htab->root.irelplt, 1);
+ }
+ else
+ {
+ splt = htab->root.splt;
+ sgotplt = htab->root.sgotplt;
+
+ /* Allocate room for an R_JUMP_SLOT relocation in .rel.plt. */
+ elf32_arm_allocate_dynrelocs (info, htab->root.srelplt, 1);
+
+ /* If this is the first .plt entry, make room for the special
+ first entry. */
+ if (splt->size == 0)
+ splt->size += htab->plt_header_size;
+
+ htab->next_tls_desc_index++;
+ }
+
+ /* Allocate the PLT entry itself, including any leading Thumb stub. */
+ if (elf32_arm_plt_needs_thumb_stub_p (info, arm_plt))
+ splt->size += PLT_THUMB_STUB_SIZE;
+ root_plt->offset = splt->size;
+ splt->size += htab->plt_entry_size;
+
+ if (!htab->symbian_p)
+ {
+ /* We also need to make an entry in the .got.plt section, which
+ will be placed in the .got section by the linker script. */
+ if (is_iplt_entry)
+ arm_plt->got_offset = sgotplt->size;
+ else
+ arm_plt->got_offset = sgotplt->size - 8 * htab->num_tls_desc;
+ sgotplt->size += 4;
+ }
+}
+
+static bfd_vma
+arm_movw_immediate (bfd_vma value)
+{
+ return (value & 0x00000fff) | ((value & 0x0000f000) << 4);
+}
+
+static bfd_vma
+arm_movt_immediate (bfd_vma value)
+{
+ return ((value & 0x0fff0000) >> 16) | ((value & 0xf0000000) >> 12);
+}
+
+/* Fill in a PLT entry and its associated GOT slot. If DYNINDX == -1,
+ the entry lives in .iplt and resolves to (*SYM_VALUE)().
+ Otherwise, DYNINDX is the index of the symbol in the dynamic
+ symbol table and SYM_VALUE is undefined.
+
+ ROOT_PLT points to the offset of the PLT entry from the start of its
+ section (.iplt or .plt). ARM_PLT points to the symbol's ARM-specific
+ bookkeeping information.
+
+ Returns FALSE if there was a problem. */
+
+static bfd_boolean
+elf32_arm_populate_plt_entry (bfd *output_bfd, struct bfd_link_info *info,
+ union gotplt_union *root_plt,
+ struct arm_plt_info *arm_plt,
+ int dynindx, bfd_vma sym_value)
+{
+ struct elf32_arm_link_hash_table *htab;
+ asection *sgot;
+ asection *splt;
+ asection *srel;
+ bfd_byte *loc;
+ bfd_vma plt_index;
+ Elf_Internal_Rela rel;
+ bfd_vma plt_header_size;
+ bfd_vma got_header_size;
+
+ htab = elf32_arm_hash_table (info);
+
+ /* Pick the appropriate sections and sizes. */
+ if (dynindx == -1)
+ {
+ splt = htab->root.iplt;
+ sgot = htab->root.igotplt;
+ srel = htab->root.irelplt;
+
+ /* There are no reserved entries in .igot.plt, and no special
+ first entry in .iplt. */
+ got_header_size = 0;
+ plt_header_size = 0;
+ }
+ else
+ {
+ splt = htab->root.splt;
+ sgot = htab->root.sgotplt;
+ srel = htab->root.srelplt;
+
+ got_header_size = get_elf_backend_data (output_bfd)->got_header_size;
+ plt_header_size = htab->plt_header_size;
+ }
+ BFD_ASSERT (splt != NULL && srel != NULL);
+
+ /* Fill in the entry in the procedure linkage table. */
+ if (htab->symbian_p)
+ {
+ BFD_ASSERT (dynindx >= 0);
+ put_arm_insn (htab, output_bfd,
+ elf32_arm_symbian_plt_entry[0],
+ splt->contents + root_plt->offset);
+ bfd_put_32 (output_bfd,
+ elf32_arm_symbian_plt_entry[1],
+ splt->contents + root_plt->offset + 4);
+
+ /* Fill in the entry in the .rel.plt section. */
+ rel.r_offset = (splt->output_section->vma
+ + splt->output_offset
+ + root_plt->offset + 4);
+ rel.r_info = ELF32_R_INFO (dynindx, R_ARM_GLOB_DAT);
+
+ /* 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 = ((root_plt->offset - plt_header_size)
+ / htab->plt_entry_size);
+ }
+ else
+ {
+ bfd_vma got_offset, got_address, plt_address;
+ bfd_vma got_displacement, initial_got_entry;
+ bfd_byte * ptr;
+
+ BFD_ASSERT (sgot != NULL);
+
+ /* Get the offset into the .(i)got.plt table of the entry that
+ corresponds to this function. */
+ got_offset = (arm_plt->got_offset & -2);
+
+ /* 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.
+ After the reserved .got.plt entries, all symbols appear in
+ the same order as in .plt. */
+ plt_index = (got_offset - got_header_size) / 4;
+
+ /* Calculate the address of the GOT entry. */
+ got_address = (sgot->output_section->vma
+ + sgot->output_offset
+ + got_offset);
+
+ /* ...and the address of the PLT entry. */
+ plt_address = (splt->output_section->vma
+ + splt->output_offset
+ + root_plt->offset);
+
+ ptr = splt->contents + root_plt->offset;
+ if (htab->vxworks_p && info->shared)
+ {
+ unsigned int i;
+ bfd_vma val;
+
+ for (i = 0; i != htab->plt_entry_size / 4; i++, ptr += 4)
+ {
+ val = elf32_arm_vxworks_shared_plt_entry[i];
+ if (i == 2)
+ val |= got_address - sgot->output_section->vma;
+ if (i == 5)
+ val |= plt_index * RELOC_SIZE (htab);
+ if (i == 2 || i == 5)
+ bfd_put_32 (output_bfd, val, ptr);
+ else
+ put_arm_insn (htab, output_bfd, val, ptr);
+ }
+ }
+ else if (htab->vxworks_p)
+ {
+ unsigned int i;
+ bfd_vma val;
+
+ for (i = 0; i != htab->plt_entry_size / 4; i++, ptr += 4)
+ {
+ val = elf32_arm_vxworks_exec_plt_entry[i];
+ if (i == 2)
+ val |= got_address;
+ if (i == 4)
+ val |= 0xffffff & -((root_plt->offset + i * 4 + 8) >> 2);
+ if (i == 5)
+ val |= plt_index * RELOC_SIZE (htab);
+ if (i == 2 || i == 5)
+ bfd_put_32 (output_bfd, val, ptr);
+ else
+ put_arm_insn (htab, output_bfd, val, ptr);
+ }
+
+ loc = (htab->srelplt2->contents
+ + (plt_index * 2 + 1) * RELOC_SIZE (htab));
+
+ /* Create the .rela.plt.unloaded R_ARM_ABS32 relocation
+ referencing the GOT for this PLT entry. */
+ rel.r_offset = plt_address + 8;
+ rel.r_info = ELF32_R_INFO (htab->root.hgot->indx, R_ARM_ABS32);
+ rel.r_addend = got_offset;
+ SWAP_RELOC_OUT (htab) (output_bfd, &rel, loc);
+ loc += RELOC_SIZE (htab);
+
+ /* Create the R_ARM_ABS32 relocation referencing the
+ beginning of the PLT for this GOT entry. */
+ rel.r_offset = got_address;
+ rel.r_info = ELF32_R_INFO (htab->root.hplt->indx, R_ARM_ABS32);
+ rel.r_addend = 0;
+ SWAP_RELOC_OUT (htab) (output_bfd, &rel, loc);
+ }
+ else if (htab->nacl_p)
+ {
+ /* Calculate the displacement between the PLT slot and the
+ common tail that's part of the special initial PLT slot. */
+ int32_t tail_displacement
+ = ((splt->output_section->vma + splt->output_offset
+ + ARM_NACL_PLT_TAIL_OFFSET)
+ - (plt_address + htab->plt_entry_size + 4));
+ BFD_ASSERT ((tail_displacement & 3) == 0);
+ tail_displacement >>= 2;
+
+ BFD_ASSERT ((tail_displacement & 0xff000000) == 0
+ || (-tail_displacement & 0xff000000) == 0);
+
+ /* Calculate the displacement between the PLT slot and the entry
+ in the GOT. The offset accounts for the value produced by
+ adding to pc in the penultimate instruction of the PLT stub. */
+ got_displacement = (got_address
+ - (plt_address + htab->plt_entry_size));
+
+ /* NaCl does not support interworking at all. */
+ BFD_ASSERT (!elf32_arm_plt_needs_thumb_stub_p (info, arm_plt));
+
+ put_arm_insn (htab, output_bfd,
+ elf32_arm_nacl_plt_entry[0]
+ | arm_movw_immediate (got_displacement),
+ ptr + 0);
+ put_arm_insn (htab, output_bfd,
+ elf32_arm_nacl_plt_entry[1]
+ | arm_movt_immediate (got_displacement),
+ ptr + 4);
+ put_arm_insn (htab, output_bfd,
+ elf32_arm_nacl_plt_entry[2],
+ ptr + 8);
+ put_arm_insn (htab, output_bfd,
+ elf32_arm_nacl_plt_entry[3]
+ | (tail_displacement & 0x00ffffff),
+ ptr + 12);
+ }
+ else if (using_thumb_only (htab))
+ {
+ /* PR ld/16017: Generate thumb only PLT entries. */
+ if (!using_thumb2 (htab))
+ {
+ /* FIXME: We ought to be able to generate thumb-1 PLT
+ instructions... */
+ _bfd_error_handler (_("%B: Warning: thumb-1 mode PLT generation not currently supported"),
+ output_bfd);
+ return FALSE;
+ }
+
+ /* Calculate the displacement between the PLT slot and the entry in
+ the GOT. The 12-byte offset accounts for the value produced by
+ adding to pc in the 3rd instruction of the PLT stub. */
+ got_displacement = got_address - (plt_address + 12);
+
+ /* As we are using 32 bit instructions we have to use 'put_arm_insn'
+ instead of 'put_thumb_insn'. */
+ put_arm_insn (htab, output_bfd,
+ elf32_thumb2_plt_entry[0]
+ | ((got_displacement & 0x000000ff) << 16)
+ | ((got_displacement & 0x00000700) << 20)
+ | ((got_displacement & 0x00000800) >> 1)
+ | ((got_displacement & 0x0000f000) >> 12),
+ ptr + 0);
+ put_arm_insn (htab, output_bfd,
+ elf32_thumb2_plt_entry[1]
+ | ((got_displacement & 0x00ff0000) )
+ | ((got_displacement & 0x07000000) << 4)
+ | ((got_displacement & 0x08000000) >> 17)
+ | ((got_displacement & 0xf0000000) >> 28),
+ ptr + 4);
+ put_arm_insn (htab, output_bfd,
+ elf32_thumb2_plt_entry[2],
+ ptr + 8);
+ put_arm_insn (htab, output_bfd,
+ elf32_thumb2_plt_entry[3],
+ ptr + 12);
+ }
+ else
+ {
+ /* Calculate the displacement between the PLT slot and the
+ entry in the GOT. The eight-byte offset accounts for the
+ value produced by adding to pc in the first instruction
+ of the PLT stub. */
+ got_displacement = got_address - (plt_address + 8);
+
+ if (elf32_arm_plt_needs_thumb_stub_p (info, arm_plt))
+ {
+ put_thumb_insn (htab, output_bfd,
+ elf32_arm_plt_thumb_stub[0], ptr - 4);
+ put_thumb_insn (htab, output_bfd,
+ elf32_arm_plt_thumb_stub[1], ptr - 2);
+ }
+
+ if (!elf32_arm_use_long_plt_entry)
+ {
+ BFD_ASSERT ((got_displacement & 0xf0000000) == 0);
+
+ put_arm_insn (htab, output_bfd,
+ elf32_arm_plt_entry_short[0]
+ | ((got_displacement & 0x0ff00000) >> 20),
+ ptr + 0);
+ put_arm_insn (htab, output_bfd,
+ elf32_arm_plt_entry_short[1]
+ | ((got_displacement & 0x000ff000) >> 12),
+ ptr+ 4);
+ put_arm_insn (htab, output_bfd,
+ elf32_arm_plt_entry_short[2]
+ | (got_displacement & 0x00000fff),
+ ptr + 8);
+#ifdef FOUR_WORD_PLT
+ bfd_put_32 (output_bfd, elf32_arm_plt_entry_short[3], ptr + 12);
+#endif
+ }
+ else
+ {
+ put_arm_insn (htab, output_bfd,
+ elf32_arm_plt_entry_long[0]
+ | ((got_displacement & 0xf0000000) >> 28),
+ ptr + 0);
+ put_arm_insn (htab, output_bfd,
+ elf32_arm_plt_entry_long[1]
+ | ((got_displacement & 0x0ff00000) >> 20),
+ ptr + 4);
+ put_arm_insn (htab, output_bfd,
+ elf32_arm_plt_entry_long[2]
+ | ((got_displacement & 0x000ff000) >> 12),
+ ptr+ 8);
+ put_arm_insn (htab, output_bfd,
+ elf32_arm_plt_entry_long[3]
+ | (got_displacement & 0x00000fff),
+ ptr + 12);
+ }
+ }
+
+ /* Fill in the entry in the .rel(a).(i)plt section. */
+ rel.r_offset = got_address;
+ rel.r_addend = 0;
+ if (dynindx == -1)
+ {
+ /* .igot.plt entries use IRELATIVE relocations against SYM_VALUE.
+ The dynamic linker or static executable then calls SYM_VALUE
+ to determine the correct run-time value of the .igot.plt entry. */
+ rel.r_info = ELF32_R_INFO (0, R_ARM_IRELATIVE);
+ initial_got_entry = sym_value;
+ }
+ else
+ {
+ rel.r_info = ELF32_R_INFO (dynindx, R_ARM_JUMP_SLOT);
+ initial_got_entry = (splt->output_section->vma
+ + splt->output_offset);
+ }
+
+ /* Fill in the entry in the global offset table. */
+ bfd_put_32 (output_bfd, initial_got_entry,
+ sgot->contents + got_offset);
+ }
+
+ if (dynindx == -1)
+ elf32_arm_add_dynreloc (output_bfd, info, srel, &rel);
+ else
+ {
+ loc = srel->contents + plt_index * RELOC_SIZE (htab);
+ SWAP_RELOC_OUT (htab) (output_bfd, &rel, loc);
+ }
+
+ return TRUE;
+}
+
+/* Some relocations map to different relocations depending on the
+ target. Return the real relocation. */
+
+static int
+arm_real_reloc_type (struct elf32_arm_link_hash_table * globals,
+ int r_type)
+{
+ switch (r_type)
+ {
+ case R_ARM_TARGET1:
+ if (globals->target1_is_rel)
+ return R_ARM_REL32;
+ else
+ return R_ARM_ABS32;
+
+ case R_ARM_TARGET2:
+ return globals->target2_reloc;
+
+ default:
+ return r_type;
+ }
+}
+
+/* Return the base VMA address which should be subtracted from real addresses
+ when resolving @dtpoff relocation.
+ This is PT_TLS segment p_vaddr. */
+
+static bfd_vma
+dtpoff_base (struct bfd_link_info *info)
+{
+ /* If tls_sec is NULL, we should have signalled an error already. */
+ if (elf_hash_table (info)->tls_sec == NULL)
+ return 0;
+ return elf_hash_table (info)->tls_sec->vma;
+}
+
+/* Return the relocation value for @tpoff relocation
+ if STT_TLS virtual address is ADDRESS. */
+
+static bfd_vma
+tpoff (struct bfd_link_info *info, bfd_vma address)
+{
+ struct elf_link_hash_table *htab = elf_hash_table (info);
+ bfd_vma base;
+
+ /* If tls_sec is NULL, we should have signalled an error already. */
+ if (htab->tls_sec == NULL)
+ return 0;
+ base = align_power ((bfd_vma) TCB_SIZE, htab->tls_sec->alignment_power);
+ return address - htab->tls_sec->vma + base;
+}
+
+/* Perform an R_ARM_ABS12 relocation on the field pointed to by DATA.
+ VALUE is the relocation value. */
+
+static bfd_reloc_status_type
+elf32_arm_abs12_reloc (bfd *abfd, void *data, bfd_vma value)
+{
+ if (value > 0xfff)
+ return bfd_reloc_overflow;
+
+ value |= bfd_get_32 (abfd, data) & 0xfffff000;
+ bfd_put_32 (abfd, value, data);
+ return bfd_reloc_ok;
+}
+
+/* Handle TLS relaxations. Relaxing is possible for symbols that use
+ R_ARM_GOTDESC, R_ARM_{,THM_}TLS_CALL or
+ R_ARM_{,THM_}TLS_DESCSEQ relocations, during a static link.
+
+ Return bfd_reloc_ok if we're done, bfd_reloc_continue if the caller
+ is to then call final_link_relocate. Return other values in the
+ case of error.
+
+ FIXME:When --emit-relocs is in effect, we'll emit relocs describing
+ the pre-relaxed code. It would be nice if the relocs were updated
+ to match the optimization. */
+
+static bfd_reloc_status_type
+elf32_arm_tls_relax (struct elf32_arm_link_hash_table *globals,
+ bfd *input_bfd, asection *input_sec, bfd_byte *contents,
+ Elf_Internal_Rela *rel, unsigned long is_local)
+{
+ unsigned long insn;
+
+ switch (ELF32_R_TYPE (rel->r_info))
+ {
+ default:
+ return bfd_reloc_notsupported;
+
+ case R_ARM_TLS_GOTDESC:
+ if (is_local)
+ insn = 0;
+ else
+ {
+ insn = bfd_get_32 (input_bfd, contents + rel->r_offset);
+ if (insn & 1)
+ insn -= 5; /* THUMB */
+ else
+ insn -= 8; /* ARM */
+ }
+ bfd_put_32 (input_bfd, insn, contents + rel->r_offset);
+ return bfd_reloc_continue;
+
+ case R_ARM_THM_TLS_DESCSEQ:
+ /* Thumb insn. */
+ insn = bfd_get_16 (input_bfd, contents + rel->r_offset);
+ if ((insn & 0xff78) == 0x4478) /* add rx, pc */
+ {
+ if (is_local)
+ /* nop */
+ bfd_put_16 (input_bfd, 0x46c0, contents + rel->r_offset);
+ }
+ else if ((insn & 0xffc0) == 0x6840) /* ldr rx,[ry,#4] */
+ {
+ if (is_local)
+ /* nop */
+ bfd_put_16 (input_bfd, 0x46c0, contents + rel->r_offset);
+ else
+ /* ldr rx,[ry] */
+ bfd_put_16 (input_bfd, insn & 0xf83f, contents + rel->r_offset);
+ }
+ else if ((insn & 0xff87) == 0x4780) /* blx rx */
+ {
+ if (is_local)
+ /* nop */
+ bfd_put_16 (input_bfd, 0x46c0, contents + rel->r_offset);
+ else
+ /* mov r0, rx */
+ bfd_put_16 (input_bfd, 0x4600 | (insn & 0x78),
+ contents + rel->r_offset);
+ }
+ else
+ {
+ if ((insn & 0xf000) == 0xf000 || (insn & 0xf800) == 0xe800)
+ /* It's a 32 bit instruction, fetch the rest of it for
+ error generation. */
+ insn = (insn << 16)
+ | bfd_get_16 (input_bfd, contents + rel->r_offset + 2);
+ (*_bfd_error_handler)
+ (_("%B(%A+0x%lx):unexpected Thumb instruction '0x%x' in TLS trampoline"),
+ input_bfd, input_sec, (unsigned long)rel->r_offset, insn);
+ return bfd_reloc_notsupported;
+ }
+ break;
+
+ case R_ARM_TLS_DESCSEQ:
+ /* arm insn. */
+ insn = bfd_get_32 (input_bfd, contents + rel->r_offset);
+ if ((insn & 0xffff0ff0) == 0xe08f0000) /* add rx,pc,ry */
+ {
+ if (is_local)
+ /* mov rx, ry */
+ bfd_put_32 (input_bfd, 0xe1a00000 | (insn & 0xffff),
+ contents + rel->r_offset);
+ }
+ else if ((insn & 0xfff00fff) == 0xe5900004) /* ldr rx,[ry,#4]*/
+ {
+ if (is_local)
+ /* nop */
+ bfd_put_32 (input_bfd, 0xe1a00000, contents + rel->r_offset);
+ else
+ /* ldr rx,[ry] */
+ bfd_put_32 (input_bfd, insn & 0xfffff000,
+ contents + rel->r_offset);
+ }
+ else if ((insn & 0xfffffff0) == 0xe12fff30) /* blx rx */
+ {
+ if (is_local)
+ /* nop */
+ bfd_put_32 (input_bfd, 0xe1a00000, contents + rel->r_offset);
+ else
+ /* mov r0, rx */
+ bfd_put_32 (input_bfd, 0xe1a00000 | (insn & 0xf),
+ contents + rel->r_offset);
+ }
+ else
+ {
+ (*_bfd_error_handler)
+ (_("%B(%A+0x%lx):unexpected ARM instruction '0x%x' in TLS trampoline"),
+ input_bfd, input_sec, (unsigned long)rel->r_offset, insn);
+ return bfd_reloc_notsupported;
+ }
+ break;
+
+ case R_ARM_TLS_CALL:
+ /* GD->IE relaxation, turn the instruction into 'nop' or
+ 'ldr r0, [pc,r0]' */
+ insn = is_local ? 0xe1a00000 : 0xe79f0000;
+ bfd_put_32 (input_bfd, insn, contents + rel->r_offset);
+ break;
+
+ case R_ARM_THM_TLS_CALL:
+ /* GD->IE relaxation. */
+ if (!is_local)
+ /* add r0,pc; ldr r0, [r0] */
+ insn = 0x44786800;
+ else if (arch_has_thumb2_nop (globals))
+ /* nop.w */
+ insn = 0xf3af8000;
+ else
+ /* nop; nop */
+ insn = 0xbf00bf00;
+
+ bfd_put_16 (input_bfd, insn >> 16, contents + rel->r_offset);
+ bfd_put_16 (input_bfd, insn & 0xffff, contents + rel->r_offset + 2);
+ break;
+ }
+ return bfd_reloc_ok;
+}
+
+/* For a given value of n, calculate the value of G_n as required to
+ deal with group relocations. We return it in the form of an
+ encoded constant-and-rotation, together with the final residual. If n is
+ specified as less than zero, then final_residual is filled with the
+ input value and no further action is performed. */
+
+static bfd_vma
+calculate_group_reloc_mask (bfd_vma value, int n, bfd_vma *final_residual)
+{
+ int current_n;
+ bfd_vma g_n;
+ bfd_vma encoded_g_n = 0;
+ bfd_vma residual = value; /* Also known as Y_n. */
+
+ for (current_n = 0; current_n <= n; current_n++)
+ {
+ int shift;
+
+ /* Calculate which part of the value to mask. */
+ if (residual == 0)
+ shift = 0;
+ else
+ {
+ int msb;
+
+ /* Determine the most significant bit in the residual and
+ align the resulting value to a 2-bit boundary. */
+ for (msb = 30; msb >= 0; msb -= 2)
+ if (residual & (3 << msb))
+ break;
+
+ /* The desired shift is now (msb - 6), or zero, whichever
+ is the greater. */
+ shift = msb - 6;
+ if (shift < 0)
+ shift = 0;
+ }
+
+ /* Calculate g_n in 32-bit as well as encoded constant+rotation form. */
+ g_n = residual & (0xff << shift);
+ encoded_g_n = (g_n >> shift)
+ | ((g_n <= 0xff ? 0 : (32 - shift) / 2) << 8);
+
+ /* Calculate the residual for the next time around. */
+ residual &= ~g_n;
+ }
+
+ *final_residual = residual;
+
+ return encoded_g_n;
+}
+
+/* Given an ARM instruction, determine whether it is an ADD or a SUB.
+ Returns 1 if it is an ADD, -1 if it is a SUB, and 0 otherwise. */
+
+static int
+identify_add_or_sub (bfd_vma insn)
+{
+ int opcode = insn & 0x1e00000;
+
+ if (opcode == 1 << 23) /* ADD */
+ return 1;
+
+ if (opcode == 1 << 22) /* SUB */
+ return -1;
+
+ return 0;
+}
+
+/* Perform a relocation as part of a final link. */
+
+static bfd_reloc_status_type
+elf32_arm_final_link_relocate (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 st_type,
+ enum arm_st_branch_type branch_type,
+ struct elf_link_hash_entry * h,
+ bfd_boolean * unresolved_reloc_p,
+ char ** error_message)
+{
+ unsigned long r_type = howto->type;
+ unsigned long r_symndx;
+ bfd_byte * hit_data = contents + rel->r_offset;
+ bfd_vma * local_got_offsets;
+ bfd_vma * local_tlsdesc_gotents;
+ asection * sgot;
+ asection * splt;
+ asection * sreloc = NULL;
+ asection * srelgot;
+ bfd_vma addend;
+ bfd_signed_vma signed_addend;
+ unsigned char dynreloc_st_type;
+ bfd_vma dynreloc_value;
+ struct elf32_arm_link_hash_table * globals;
+ struct elf32_arm_link_hash_entry *eh;
+ union gotplt_union *root_plt;
+ struct arm_plt_info *arm_plt;
+ bfd_vma plt_offset;
+ bfd_vma gotplt_offset;
+ bfd_boolean has_iplt_entry;
+
+ globals = elf32_arm_hash_table (info);
+ if (globals == NULL)
+ return bfd_reloc_notsupported;
+
+ BFD_ASSERT (is_arm_elf (input_bfd));
+
+ /* Some relocation types map to different relocations depending on the
+ target. We pick the right one here. */
+ r_type = arm_real_reloc_type (globals, r_type);
+
+ /* It is possible to have linker relaxations on some TLS access
+ models. Update our information here. */
+ r_type = elf32_arm_tls_transition (info, r_type, h);
+
+ if (r_type != howto->type)
+ howto = elf32_arm_howto_from_type (r_type);
+
+ /* If the start address has been set, then set the EF_ARM_HASENTRY
+ flag. Setting this more than once is redundant, but the cost is
+ not too high, and it keeps the code simple.
+
+ The test is done here, rather than somewhere else, because the
+ start address is only set just before the final link commences.
+
+ Note - if the user deliberately sets a start address of 0, the
+ flag will not be set. */
+ if (bfd_get_start_address (output_bfd) != 0)
+ elf_elfheader (output_bfd)->e_flags |= EF_ARM_HASENTRY;
+
+ eh = (struct elf32_arm_link_hash_entry *) h;
+ sgot = globals->root.sgot;
+ local_got_offsets = elf_local_got_offsets (input_bfd);
+ local_tlsdesc_gotents = elf32_arm_local_tlsdesc_gotent (input_bfd);
+
+ if (globals->root.dynamic_sections_created)
+ srelgot = globals->root.srelgot;
+ else
+ srelgot = NULL;
+
+ r_symndx = ELF32_R_SYM (rel->r_info);
+
+ if (globals->use_rel)
+ {
+ addend = bfd_get_32 (input_bfd, hit_data) & howto->src_mask;
+
+ if (addend & ((howto->src_mask + 1) >> 1))
+ {
+ signed_addend = -1;
+ signed_addend &= ~ howto->src_mask;
+ signed_addend |= addend;
+ }
+ else
+ signed_addend = addend;
+ }
+ else
+ addend = signed_addend = rel->r_addend;
+
+ /* ST_BRANCH_TO_ARM is nonsense to thumb-only targets when we
+ are resolving a function call relocation. */
+ if (using_thumb_only (globals)
+ && (r_type == R_ARM_THM_CALL
+ || r_type == R_ARM_THM_JUMP24)
+ && branch_type == ST_BRANCH_TO_ARM)
+ branch_type = ST_BRANCH_TO_THUMB;
+
+ /* Record the symbol information that should be used in dynamic
+ relocations. */
+ dynreloc_st_type = st_type;
+ dynreloc_value = value;
+ if (branch_type == ST_BRANCH_TO_THUMB)
+ dynreloc_value |= 1;
+
+ /* Find out whether the symbol has a PLT. Set ST_VALUE, BRANCH_TYPE and
+ VALUE appropriately for relocations that we resolve at link time. */
+ has_iplt_entry = FALSE;
+ if (elf32_arm_get_plt_info (input_bfd, eh, r_symndx, &root_plt, &arm_plt)
+ && root_plt->offset != (bfd_vma) -1)
+ {
+ plt_offset = root_plt->offset;
+ gotplt_offset = arm_plt->got_offset;
+
+ if (h == NULL || eh->is_iplt)
+ {
+ has_iplt_entry = TRUE;
+ splt = globals->root.iplt;
+
+ /* Populate .iplt entries here, because not all of them will
+ be seen by finish_dynamic_symbol. The lower bit is set if
+ we have already populated the entry. */
+ if (plt_offset & 1)
+ plt_offset--;
+ else
+ {
+ if (elf32_arm_populate_plt_entry (output_bfd, info, root_plt, arm_plt,
+ -1, dynreloc_value))
+ root_plt->offset |= 1;
+ else
+ return bfd_reloc_notsupported;
+ }
+
+ /* Static relocations always resolve to the .iplt entry. */
+ st_type = STT_FUNC;
+ value = (splt->output_section->vma
+ + splt->output_offset
+ + plt_offset);
+ branch_type = ST_BRANCH_TO_ARM;
+
+ /* If there are non-call relocations that resolve to the .iplt
+ entry, then all dynamic ones must too. */
+ if (arm_plt->noncall_refcount != 0)
+ {
+ dynreloc_st_type = st_type;
+ dynreloc_value = value;
+ }
+ }
+ else
+ /* We populate the .plt entry in finish_dynamic_symbol. */
+ splt = globals->root.splt;
+ }
+ else
+ {
+ splt = NULL;
+ plt_offset = (bfd_vma) -1;
+ gotplt_offset = (bfd_vma) -1;
+ }
+
+ switch (r_type)
+ {
+ case R_ARM_NONE:
+ /* We don't need to find a value for this symbol. It's just a
+ marker. */
+ *unresolved_reloc_p = FALSE;
+ return bfd_reloc_ok;
+
+ case R_ARM_ABS12:
+ if (!globals->vxworks_p)
+ return elf32_arm_abs12_reloc (input_bfd, hit_data, value + addend);
+
+ case R_ARM_PC24:
+ case R_ARM_ABS32:
+ case R_ARM_ABS32_NOI:
+ case R_ARM_REL32:
+ case R_ARM_REL32_NOI:
+ case R_ARM_CALL:
+ case R_ARM_JUMP24:
+ case R_ARM_XPC25:
+ case R_ARM_PREL31:
+ case R_ARM_PLT32:
+ /* Handle relocations which should use the PLT entry. ABS32/REL32
+ will use the symbol's value, which may point to a PLT entry, but we
+ don't need to handle that here. If we created a PLT entry, all
+ branches in this object should go to it, except if the PLT is too
+ far away, in which case a long branch stub should be inserted. */
+ if ((r_type != R_ARM_ABS32 && r_type != R_ARM_REL32
+ && r_type != R_ARM_ABS32_NOI && r_type != R_ARM_REL32_NOI
+ && r_type != R_ARM_CALL
+ && r_type != R_ARM_JUMP24
+ && r_type != R_ARM_PLT32)
+ && plt_offset != (bfd_vma) -1)
+ {
+ /* If we've created a .plt section, and assigned a PLT entry
+ to this function, it must either be a STT_GNU_IFUNC reference
+ or not be known to bind locally. In other cases, we should
+ have cleared the PLT entry by now. */
+ BFD_ASSERT (has_iplt_entry || !SYMBOL_CALLS_LOCAL (info, h));
+
+ value = (splt->output_section->vma
+ + splt->output_offset
+ + plt_offset);
+ *unresolved_reloc_p = FALSE;
+ return _bfd_final_link_relocate (howto, input_bfd, input_section,
+ contents, rel->r_offset, value,
+ rel->r_addend);
+ }
+
+ /* When generating a shared object or relocatable executable, these
+ relocations are copied into the output file to be resolved at
+ run time. */
+ if ((info->shared || globals->root.is_relocatable_executable)
+ && (input_section->flags & SEC_ALLOC)
+ && !(globals->vxworks_p
+ && strcmp (input_section->output_section->name,
+ ".tls_vars") == 0)
+ && ((r_type != R_ARM_REL32 && r_type != R_ARM_REL32_NOI)
+ || !SYMBOL_CALLS_LOCAL (info, h))
+ && !(input_bfd == globals->stub_bfd
+ && strstr (input_section->name, STUB_SUFFIX))
+ && (h == NULL
+ || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
+ || h->root.type != bfd_link_hash_undefweak)
+ && r_type != R_ARM_PC24
+ && r_type != R_ARM_CALL
+ && r_type != R_ARM_JUMP24
+ && r_type != R_ARM_PREL31
+ && r_type != R_ARM_PLT32)
+ {
+ Elf_Internal_Rela outrel;
+ bfd_boolean skip, relocate;
+
+ *unresolved_reloc_p = FALSE;
+
+ if (sreloc == NULL && globals->root.dynamic_sections_created)
+ {
+ sreloc = _bfd_elf_get_dynamic_reloc_section (input_bfd, input_section,
+ ! globals->use_rel);
+
+ if (sreloc == NULL)
+ return bfd_reloc_notsupported;
+ }
+
+ skip = FALSE;
+ relocate = FALSE;
+
+ outrel.r_addend = addend;
+ outrel.r_offset =
+ _bfd_elf_section_offset (output_bfd, info, input_section,
+ rel->r_offset);
+ if (outrel.r_offset == (bfd_vma) -1)
+ skip = TRUE;
+ else if (outrel.r_offset == (bfd_vma) -2)
+ skip = TRUE, relocate = TRUE;
+ outrel.r_offset += (input_section->output_section->vma
+ + input_section->output_offset);
+
+ if (skip)
+ memset (&outrel, 0, sizeof outrel);
+ else if (h != NULL
+ && h->dynindx != -1
+ && (!info->shared
+ || !info->symbolic
+ || !h->def_regular))
+ outrel.r_info = ELF32_R_INFO (h->dynindx, r_type);
+ else
+ {
+ int symbol;
+
+ /* This symbol is local, or marked to become local. */
+ BFD_ASSERT (r_type == R_ARM_ABS32 || r_type == R_ARM_ABS32_NOI);
+ if (globals->symbian_p)
+ {
+ asection *osec;
+
+ /* On Symbian OS, the data segment and text segement
+ can be relocated independently. Therefore, we
+ must indicate the segment to which this
+ relocation is relative. The BPABI allows us to
+ use any symbol in the right segment; we just use
+ the section symbol as it is convenient. (We
+ cannot use the symbol given by "h" directly as it
+ will not appear in the dynamic symbol table.)
+
+ Note that the dynamic linker ignores the section
+ symbol value, so we don't subtract osec->vma
+ from the emitted reloc addend. */
+ if (sym_sec)
+ osec = sym_sec->output_section;
+ else
+ osec = input_section->output_section;
+ symbol = elf_section_data (osec)->dynindx;
+ if (symbol == 0)
+ {
+ struct elf_link_hash_table *htab = elf_hash_table (info);
+
+ if ((osec->flags & SEC_READONLY) == 0
+ && htab->data_index_section != NULL)
+ osec = htab->data_index_section;
+ else
+ osec = htab->text_index_section;
+ symbol = elf_section_data (osec)->dynindx;
+ }
+ BFD_ASSERT (symbol != 0);
+ }
+ else
+ /* On SVR4-ish systems, the dynamic loader cannot
+ relocate the text and data segments independently,
+ so the symbol does not matter. */
+ symbol = 0;
+ if (dynreloc_st_type == STT_GNU_IFUNC)
+ /* We have an STT_GNU_IFUNC symbol that doesn't resolve
+ to the .iplt entry. Instead, every non-call reference
+ must use an R_ARM_IRELATIVE relocation to obtain the
+ correct run-time address. */
+ outrel.r_info = ELF32_R_INFO (symbol, R_ARM_IRELATIVE);
+ else
+ outrel.r_info = ELF32_R_INFO (symbol, R_ARM_RELATIVE);
+ if (globals->use_rel)
+ relocate = TRUE;
+ else
+ outrel.r_addend += dynreloc_value;
+ }
+
+ elf32_arm_add_dynreloc (output_bfd, info, sreloc, &outrel);
+
+ /* 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,
+ dynreloc_value, (bfd_vma) 0);
+ }
+ else switch (r_type)
+ {
+ case R_ARM_ABS12:
+ return elf32_arm_abs12_reloc (input_bfd, hit_data, value + addend);
+
+ case R_ARM_XPC25: /* Arm BLX instruction. */
+ case R_ARM_CALL:
+ case R_ARM_JUMP24:
+ case R_ARM_PC24: /* Arm B/BL instruction. */
+ case R_ARM_PLT32:
+ {
+ struct elf32_arm_stub_hash_entry *stub_entry = NULL;
+
+ if (r_type == R_ARM_XPC25)
+ {
+ /* Check for Arm calling Arm function. */
+ /* FIXME: Should we translate the instruction into a BL
+ instruction instead ? */
+ if (branch_type != ST_BRANCH_TO_THUMB)
+ (*_bfd_error_handler)
+ (_("\%B: Warning: Arm BLX instruction targets Arm function '%s'."),
+ input_bfd,
+ h ? h->root.root.string : "(local)");
+ }
+ else if (r_type == R_ARM_PC24)
+ {
+ /* Check for Arm calling Thumb function. */
+ if (branch_type == ST_BRANCH_TO_THUMB)
+ {
+ if (elf32_arm_to_thumb_stub (info, sym_name, input_bfd,
+ output_bfd, input_section,
+ hit_data, sym_sec, rel->r_offset,
+ signed_addend, value,
+ error_message))
+ return bfd_reloc_ok;
+ else
+ return bfd_reloc_dangerous;
+ }
+ }
+
+ /* Check if a stub has to be inserted because the
+ destination is too far or we are changing mode. */
+ if ( r_type == R_ARM_CALL
+ || r_type == R_ARM_JUMP24
+ || r_type == R_ARM_PLT32)
+ {
+ enum elf32_arm_stub_type stub_type = arm_stub_none;
+ struct elf32_arm_link_hash_entry *hash;
+
+ hash = (struct elf32_arm_link_hash_entry *) h;
+ stub_type = arm_type_of_stub (info, input_section, rel,
+ st_type, &branch_type,
+ hash, value, sym_sec,
+ input_bfd, sym_name);
+
+ if (stub_type != arm_stub_none)
+ {
+ /* The target is out of reach, so redirect the
+ branch to the local stub for this function. */
+ stub_entry = elf32_arm_get_stub_entry (input_section,
+ sym_sec, h,
+ rel, globals,
+ stub_type);
+ {
+ if (stub_entry != NULL)
+ value = (stub_entry->stub_offset
+ + stub_entry->stub_sec->output_offset
+ + stub_entry->stub_sec->output_section->vma);
+
+ if (plt_offset != (bfd_vma) -1)
+ *unresolved_reloc_p = FALSE;
+ }
+ }
+ else
+ {
+ /* If the call goes through a PLT entry, make sure to
+ check distance to the right destination address. */
+ if (plt_offset != (bfd_vma) -1)
+ {
+ value = (splt->output_section->vma
+ + splt->output_offset
+ + plt_offset);
+ *unresolved_reloc_p = FALSE;
+ /* The PLT entry is in ARM mode, regardless of the
+ target function. */
+ branch_type = ST_BRANCH_TO_ARM;
+ }
+ }
+ }
+
+ /* The ARM ELF ABI says that this reloc is computed as: S - P + A
+ where:
+ S is the address of the symbol in the relocation.
+ P is address of the instruction being relocated.
+ A is the addend (extracted from the instruction) in bytes.
+
+ S is held in 'value'.
+ P is the base address of the section containing the
+ instruction plus the offset of the reloc into that
+ section, ie:
+ (input_section->output_section->vma +
+ input_section->output_offset +
+ rel->r_offset).
+ A is the addend, converted into bytes, ie:
+ (signed_addend * 4)
+
+ Note: None of these operations have knowledge of the pipeline
+ size of the processor, thus it is up to the assembler to
+ encode this information into the addend. */
+ value -= (input_section->output_section->vma
+ + input_section->output_offset);
+ value -= rel->r_offset;
+ if (globals->use_rel)
+ value += (signed_addend << howto->size);
+ else
+ /* RELA addends do not have to be adjusted by howto->size. */
+ value += signed_addend;
+
+ signed_addend = value;
+ signed_addend >>= howto->rightshift;
+
+ /* A branch to an undefined weak symbol is turned into a jump to
+ the next instruction unless a PLT entry will be created.
+ Do the same for local undefined symbols (but not for STN_UNDEF).
+ The jump to the next instruction is optimized as a NOP depending
+ on the architecture. */
+ if (h ? (h->root.type == bfd_link_hash_undefweak
+ && plt_offset == (bfd_vma) -1)
+ : r_symndx != STN_UNDEF && bfd_is_und_section (sym_sec))
+ {
+ value = (bfd_get_32 (input_bfd, hit_data) & 0xf0000000);
+
+ if (arch_has_arm_nop (globals))
+ value |= 0x0320f000;
+ else
+ value |= 0x01a00000; /* Using pre-UAL nop: mov r0, r0. */
+ }
+ else
+ {
+ /* Perform a signed range check. */
+ if ( signed_addend > ((bfd_signed_vma) (howto->dst_mask >> 1))
+ || signed_addend < - ((bfd_signed_vma) ((howto->dst_mask + 1) >> 1)))
+ return bfd_reloc_overflow;
+
+ addend = (value & 2);
+
+ value = (signed_addend & howto->dst_mask)
+ | (bfd_get_32 (input_bfd, hit_data) & (~ howto->dst_mask));
+
+ if (r_type == R_ARM_CALL)
+ {
+ /* Set the H bit in the BLX instruction. */
+ if (branch_type == ST_BRANCH_TO_THUMB)
+ {
+ if (addend)
+ value |= (1 << 24);
+ else
+ value &= ~(bfd_vma)(1 << 24);
+ }
+
+ /* Select the correct instruction (BL or BLX). */
+ /* Only if we are not handling a BL to a stub. In this
+ case, mode switching is performed by the stub. */
+ if (branch_type == ST_BRANCH_TO_THUMB && !stub_entry)
+ value |= (1 << 28);
+ else if (stub_entry || branch_type != ST_BRANCH_UNKNOWN)
+ {
+ value &= ~(bfd_vma)(1 << 28);
+ value |= (1 << 24);
+ }
+ }
+ }
+ }
+ break;
+
+ case R_ARM_ABS32:
+ value += addend;
+ if (branch_type == ST_BRANCH_TO_THUMB)
+ value |= 1;
+ break;
+
+ case R_ARM_ABS32_NOI:
+ value += addend;
+ break;
+
+ case R_ARM_REL32:
+ value += addend;
+ if (branch_type == ST_BRANCH_TO_THUMB)
+ value |= 1;
+ value -= (input_section->output_section->vma
+ + input_section->output_offset + rel->r_offset);
+ break;
+
+ case R_ARM_REL32_NOI:
+ value += addend;
+ value -= (input_section->output_section->vma
+ + input_section->output_offset + rel->r_offset);
+ break;
+
+ case R_ARM_PREL31:
+ value -= (input_section->output_section->vma
+ + input_section->output_offset + rel->r_offset);
+ value += signed_addend;
+ if (! h || h->root.type != bfd_link_hash_undefweak)
+ {
+ /* Check for overflow. */
+ if ((value ^ (value >> 1)) & (1 << 30))
+ return bfd_reloc_overflow;
+ }
+ value &= 0x7fffffff;
+ value |= (bfd_get_32 (input_bfd, hit_data) & 0x80000000);
+ if (branch_type == ST_BRANCH_TO_THUMB)
+ value |= 1;
+ break;
+ }
+
+ bfd_put_32 (input_bfd, value, hit_data);
+ return bfd_reloc_ok;
+
+ case R_ARM_ABS8:
+ /* PR 16202: Refectch the addend using the correct size. */
+ if (globals->use_rel)
+ addend = bfd_get_8 (input_bfd, hit_data);
+ value += addend;
+
+ /* There is no way to tell whether the user intended to use a signed or
+ unsigned addend. When checking for overflow we accept either,
+ as specified by the AAELF. */
+ if ((long) value > 0xff || (long) value < -0x80)
+ return bfd_reloc_overflow;
+
+ bfd_put_8 (input_bfd, value, hit_data);
+ return bfd_reloc_ok;
+
+ case R_ARM_ABS16:
+ /* PR 16202: Refectch the addend using the correct size. */
+ if (globals->use_rel)
+ addend = bfd_get_16 (input_bfd, hit_data);
+ value += addend;
+
+ /* See comment for R_ARM_ABS8. */
+ if ((long) value > 0xffff || (long) value < -0x8000)
+ return bfd_reloc_overflow;
+
+ bfd_put_16 (input_bfd, value, hit_data);
+ return bfd_reloc_ok;
+
+ case R_ARM_THM_ABS5:
+ /* Support ldr and str instructions for the thumb. */
+ if (globals->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;
+ }
+ 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_ALU_PREL_11_0:
+ /* Corresponds to: addw.w reg, pc, #offset (and similarly for subw). */
+ {
+ bfd_vma insn;
+ bfd_signed_vma relocation;
+
+ insn = (bfd_get_16 (input_bfd, hit_data) << 16)
+ | bfd_get_16 (input_bfd, hit_data + 2);
+
+ if (globals->use_rel)
+ {
+ signed_addend = (insn & 0xff) | ((insn & 0x7000) >> 4)
+ | ((insn & (1 << 26)) >> 15);
+ if (insn & 0xf00000)
+ signed_addend = -signed_addend;
+ }
+
+ relocation = value + signed_addend;
+ relocation -= Pa (input_section->output_section->vma
+ + input_section->output_offset
+ + rel->r_offset);
+
+ value = abs (relocation);
+
+ if (value >= 0x1000)
+ return bfd_reloc_overflow;
+
+ insn = (insn & 0xfb0f8f00) | (value & 0xff)
+ | ((value & 0x700) << 4)
+ | ((value & 0x800) << 15);
+ if (relocation < 0)
+ insn |= 0xa00000;
+
+ bfd_put_16 (input_bfd, insn >> 16, hit_data);
+ bfd_put_16 (input_bfd, insn & 0xffff, hit_data + 2);
+
+ return bfd_reloc_ok;
+ }
+
+ case R_ARM_THM_PC8:
+ /* PR 10073: This reloc is not generated by the GNU toolchain,
+ but it is supported for compatibility with third party libraries
+ generated by other compilers, specifically the ARM/IAR. */
+ {
+ bfd_vma insn;
+ bfd_signed_vma relocation;
+
+ insn = bfd_get_16 (input_bfd, hit_data);
+
+ if (globals->use_rel)
+ addend = ((((insn & 0x00ff) << 2) + 4) & 0x3ff) -4;
+
+ relocation = value + addend;
+ relocation -= Pa (input_section->output_section->vma
+ + input_section->output_offset
+ + rel->r_offset);
+
+ value = abs (relocation);
+
+ /* We do not check for overflow of this reloc. Although strictly
+ speaking this is incorrect, it appears to be necessary in order
+ to work with IAR generated relocs. Since GCC and GAS do not
+ generate R_ARM_THM_PC8 relocs, the lack of a check should not be
+ a problem for them. */
+ value &= 0x3fc;
+
+ insn = (insn & 0xff00) | (value >> 2);
+
+ bfd_put_16 (input_bfd, insn, hit_data);
+
+ return bfd_reloc_ok;
+ }
+
+ case R_ARM_THM_PC12:
+ /* Corresponds to: ldr.w reg, [pc, #offset]. */
+ {
+ bfd_vma insn;
+ bfd_signed_vma relocation;
+
+ insn = (bfd_get_16 (input_bfd, hit_data) << 16)
+ | bfd_get_16 (input_bfd, hit_data + 2);
+
+ if (globals->use_rel)
+ {
+ signed_addend = insn & 0xfff;
+ if (!(insn & (1 << 23)))
+ signed_addend = -signed_addend;
+ }
+
+ relocation = value + signed_addend;
+ relocation -= Pa (input_section->output_section->vma
+ + input_section->output_offset
+ + rel->r_offset);
+
+ value = abs (relocation);
+
+ if (value >= 0x1000)
+ return bfd_reloc_overflow;
+
+ insn = (insn & 0xff7ff000) | value;
+ if (relocation >= 0)
+ insn |= (1 << 23);
+
+ bfd_put_16 (input_bfd, insn >> 16, hit_data);
+ bfd_put_16 (input_bfd, insn & 0xffff, hit_data + 2);
+
+ return bfd_reloc_ok;
+ }
+
+ case R_ARM_THM_XPC22:
+ case R_ARM_THM_CALL:
+ case R_ARM_THM_JUMP24:
+ /* Thumb BL (branch long instruction). */
+ {
+ bfd_vma relocation;
+ bfd_vma reloc_sign;
+ bfd_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_signed_vma reloc_signed_max;
+ bfd_signed_vma reloc_signed_min;
+ bfd_vma check;
+ bfd_signed_vma signed_check;
+ int bitsize;
+ const int thumb2 = using_thumb2 (globals);
+
+ /* A branch to an undefined weak symbol is turned into a jump to
+ the next instruction unless a PLT entry will be created.
+ The jump to the next instruction is optimized as a NOP.W for
+ Thumb-2 enabled architectures. */
+ if (h && h->root.type == bfd_link_hash_undefweak
+ && plt_offset == (bfd_vma) -1)
+ {
+ if (arch_has_thumb2_nop (globals))
+ {
+ bfd_put_16 (input_bfd, 0xf3af, hit_data);
+ bfd_put_16 (input_bfd, 0x8000, hit_data + 2);
+ }
+ else
+ {
+ bfd_put_16 (input_bfd, 0xe000, hit_data);
+ bfd_put_16 (input_bfd, 0xbf00, hit_data + 2);
+ }
+ return bfd_reloc_ok;
+ }
+
+ /* Fetch the addend. We use the Thumb-2 encoding (backwards compatible
+ with Thumb-1) involving the J1 and J2 bits. */
+ if (globals->use_rel)
+ {
+ bfd_vma s = (upper_insn & (1 << 10)) >> 10;
+ bfd_vma upper = upper_insn & 0x3ff;
+ bfd_vma lower = lower_insn & 0x7ff;
+ bfd_vma j1 = (lower_insn & (1 << 13)) >> 13;
+ bfd_vma j2 = (lower_insn & (1 << 11)) >> 11;
+ bfd_vma i1 = j1 ^ s ? 0 : 1;
+ bfd_vma i2 = j2 ^ s ? 0 : 1;
+
+ addend = (i1 << 23) | (i2 << 22) | (upper << 12) | (lower << 1);
+ /* Sign extend. */
+ addend = (addend | ((s ? 0 : 1) << 24)) - (1 << 24);
+
+ signed_addend = addend;
+ }
+
+ if (r_type == R_ARM_THM_XPC22)
+ {
+ /* Check for Thumb to Thumb call. */
+ /* FIXME: Should we translate the instruction into a BL
+ instruction instead ? */
+ if (branch_type == ST_BRANCH_TO_THUMB)
+ (*_bfd_error_handler)
+ (_("%B: Warning: Thumb BLX instruction targets thumb function '%s'."),
+ input_bfd,
+ h ? h->root.root.string : "(local)");
+ }
+ else
+ {
+ /* If it is not a call to Thumb, assume call to Arm.
+ If it is a call relative to a section name, then it is not a
+ function call at all, but rather a long jump. Calls through
+ the PLT do not require stubs. */
+ if (branch_type == ST_BRANCH_TO_ARM && plt_offset == (bfd_vma) -1)
+ {
+ if (globals->use_blx && r_type == R_ARM_THM_CALL)
+ {
+ /* Convert BL to BLX. */
+ lower_insn = (lower_insn & ~0x1000) | 0x0800;
+ }
+ else if (( r_type != R_ARM_THM_CALL)
+ && (r_type != R_ARM_THM_JUMP24))
+ {
+ if (elf32_thumb_to_arm_stub
+ (info, sym_name, input_bfd, output_bfd, input_section,
+ hit_data, sym_sec, rel->r_offset, signed_addend, value,
+ error_message))
+ return bfd_reloc_ok;
+ else
+ return bfd_reloc_dangerous;
+ }
+ }
+ else if (branch_type == ST_BRANCH_TO_THUMB
+ && globals->use_blx
+ && r_type == R_ARM_THM_CALL)
+ {
+ /* Make sure this is a BL. */
+ lower_insn |= 0x1800;
+ }
+ }
+
+ enum elf32_arm_stub_type stub_type = arm_stub_none;
+ if (r_type == R_ARM_THM_CALL || r_type == R_ARM_THM_JUMP24)
+ {
+ /* Check if a stub has to be inserted because the destination
+ is too far. */
+ struct elf32_arm_stub_hash_entry *stub_entry;
+ struct elf32_arm_link_hash_entry *hash;
+
+ hash = (struct elf32_arm_link_hash_entry *) h;
+
+ stub_type = arm_type_of_stub (info, input_section, rel,
+ st_type, &branch_type,
+ hash, value, sym_sec,
+ input_bfd, sym_name);
+
+ if (stub_type != arm_stub_none)
+ {
+ /* The target is out of reach or we are changing modes, so
+ redirect the branch to the local stub for this
+ function. */
+ stub_entry = elf32_arm_get_stub_entry (input_section,
+ sym_sec, h,
+ rel, globals,
+ stub_type);
+ if (stub_entry != NULL)
+ {
+ value = (stub_entry->stub_offset
+ + stub_entry->stub_sec->output_offset
+ + stub_entry->stub_sec->output_section->vma);
+
+ if (plt_offset != (bfd_vma) -1)
+ *unresolved_reloc_p = FALSE;
+ }
+
+ /* If this call becomes a call to Arm, force BLX. */
+ if (globals->use_blx && (r_type == R_ARM_THM_CALL))
+ {
+ if ((stub_entry
+ && !arm_stub_is_thumb (stub_entry->stub_type))
+ || branch_type != ST_BRANCH_TO_THUMB)
+ lower_insn = (lower_insn & ~0x1000) | 0x0800;
+ }
+ }
+ }
+
+ /* Handle calls via the PLT. */
+ if (stub_type == arm_stub_none && plt_offset != (bfd_vma) -1)
+ {
+ value = (splt->output_section->vma
+ + splt->output_offset
+ + plt_offset);
+
+ if (globals->use_blx
+ && r_type == R_ARM_THM_CALL
+ && ! using_thumb_only (globals))
+ {
+ /* If the Thumb BLX instruction is available, convert
+ the BL to a BLX instruction to call the ARM-mode
+ PLT entry. */
+ lower_insn = (lower_insn & ~0x1000) | 0x0800;
+ branch_type = ST_BRANCH_TO_ARM;
+ }
+ else
+ {
+ if (! using_thumb_only (globals))
+ /* Target the Thumb stub before the ARM PLT entry. */
+ value -= PLT_THUMB_STUB_SIZE;
+ branch_type = ST_BRANCH_TO_THUMB;
+ }
+ *unresolved_reloc_p = FALSE;
+ }
+
+ relocation = value + signed_addend;
+
+ relocation -= (input_section->output_section->vma
+ + input_section->output_offset
+ + 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);
+
+ /* Calculate the permissable maximum and minimum values for
+ this relocation according to whether we're relocating for
+ Thumb-2 or not. */
+ bitsize = howto->bitsize;
+ if (!thumb2)
+ bitsize -= 2;
+ reloc_signed_max = (1 << (bitsize - 1)) - 1;
+ reloc_signed_min = ~reloc_signed_max;
+
+ /* Assumes two's complement. */
+ if (signed_check > reloc_signed_max || signed_check < reloc_signed_min)
+ overflow = TRUE;
+
+ if ((lower_insn & 0x5000) == 0x4000)
+ /* For a BLX instruction, make sure that the relocation is rounded up
+ to a word boundary. This follows the semantics of the instruction
+ which specifies that bit 1 of the target address will come from bit
+ 1 of the base address. */
+ relocation = (relocation + 2) & ~ 3;
+
+ /* Put RELOCATION back into the insn. Assumes two's complement.
+ We use the Thumb-2 encoding, which is safe even if dealing with
+ a Thumb-1 instruction by virtue of our overflow check above. */
+ reloc_sign = (signed_check < 0) ? 1 : 0;
+ upper_insn = (upper_insn & ~(bfd_vma) 0x7ff)
+ | ((relocation >> 12) & 0x3ff)
+ | (reloc_sign << 10);
+ lower_insn = (lower_insn & ~(bfd_vma) 0x2fff)
+ | (((!((relocation >> 23) & 1)) ^ reloc_sign) << 13)
+ | (((!((relocation >> 22) & 1)) ^ reloc_sign) << 11)
+ | ((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_THM_JUMP19:
+ /* Thumb32 conditional branch instruction. */
+ {
+ bfd_vma relocation;
+ bfd_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_signed_vma reloc_signed_max = 0xffffe;
+ bfd_signed_vma reloc_signed_min = -0x100000;
+ bfd_signed_vma signed_check;
+ enum elf32_arm_stub_type stub_type = arm_stub_none;
+ struct elf32_arm_stub_hash_entry *stub_entry;
+ struct elf32_arm_link_hash_entry *hash;
+
+ /* Need to refetch the addend, reconstruct the top three bits,
+ and squish the two 11 bit pieces together. */
+ if (globals->use_rel)
+ {
+ bfd_vma S = (upper_insn & 0x0400) >> 10;
+ bfd_vma upper = (upper_insn & 0x003f);
+ bfd_vma J1 = (lower_insn & 0x2000) >> 13;
+ bfd_vma J2 = (lower_insn & 0x0800) >> 11;
+ bfd_vma lower = (lower_insn & 0x07ff);
+
+ upper |= J1 << 6;
+ upper |= J2 << 7;
+ upper |= (!S) << 8;
+ upper -= 0x0100; /* Sign extend. */
+
+ addend = (upper << 12) | (lower << 1);
+ signed_addend = addend;
+ }
+
+ /* Handle calls via the PLT. */
+ if (plt_offset != (bfd_vma) -1)
+ {
+ value = (splt->output_section->vma
+ + splt->output_offset
+ + plt_offset);
+ /* Target the Thumb stub before the ARM PLT entry. */
+ value -= PLT_THUMB_STUB_SIZE;
+ *unresolved_reloc_p = FALSE;
+ }
+
+ hash = (struct elf32_arm_link_hash_entry *)h;
+
+ stub_type = arm_type_of_stub (info, input_section, rel,
+ st_type, &branch_type,
+ hash, value, sym_sec,
+ input_bfd, sym_name);
+ if (stub_type != arm_stub_none)
+ {
+ stub_entry = elf32_arm_get_stub_entry (input_section,
+ sym_sec, h,
+ rel, globals,
+ stub_type);
+ if (stub_entry != NULL)
+ {
+ value = (stub_entry->stub_offset
+ + stub_entry->stub_sec->output_offset
+ + stub_entry->stub_sec->output_section->vma);
+ }
+ }
+
+ relocation = value + signed_addend;
+ relocation -= (input_section->output_section->vma
+ + input_section->output_offset
+ + rel->r_offset);
+ signed_check = (bfd_signed_vma) relocation;
+
+ if (signed_check > reloc_signed_max || signed_check < reloc_signed_min)
+ overflow = TRUE;
+
+ /* Put RELOCATION back into the insn. */
+ {
+ bfd_vma S = (relocation & 0x00100000) >> 20;
+ bfd_vma J2 = (relocation & 0x00080000) >> 19;
+ bfd_vma J1 = (relocation & 0x00040000) >> 18;
+ bfd_vma hi = (relocation & 0x0003f000) >> 12;
+ bfd_vma lo = (relocation & 0x00000ffe) >> 1;
+
+ upper_insn = (upper_insn & 0xfbc0) | (S << 10) | hi;
+ lower_insn = (lower_insn & 0xd000) | (J1 << 13) | (J2 << 11) | lo;
+ }
+
+ /* 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);
+ }
+
+ case R_ARM_THM_JUMP11:
+ case R_ARM_THM_JUMP8:
+ case R_ARM_THM_JUMP6:
+ /* Thumb B (branch) instruction). */
+ {
+ bfd_signed_vma relocation;
+ bfd_signed_vma reloc_signed_max = (1 << (howto->bitsize - 1)) - 1;
+ bfd_signed_vma reloc_signed_min = ~ reloc_signed_max;
+ bfd_signed_vma signed_check;
+
+ /* CZB cannot jump backward. */
+ if (r_type == R_ARM_THM_JUMP6)
+ reloc_signed_min = 0;
+
+ if (globals->use_rel)
+ {
+ /* Need to refetch addend. */
+ addend = bfd_get_16 (input_bfd, hit_data) & howto->src_mask;
+ if (addend & ((howto->src_mask + 1) >> 1))
+ {
+ signed_addend = -1;
+ signed_addend &= ~ howto->src_mask;
+ signed_addend |= addend;
+ }
+ else
+ signed_addend = addend;
+ /* The value in the insn has been right shifted. We need to
+ undo this, so that we can perform the address calculation
+ in terms of bytes. */
+ signed_addend <<= howto->rightshift;
+ }
+ relocation = value + signed_addend;
+
+ relocation -= (input_section->output_section->vma
+ + input_section->output_offset
+ + rel->r_offset);
+
+ relocation >>= howto->rightshift;
+ signed_check = relocation;
+
+ if (r_type == R_ARM_THM_JUMP6)
+ relocation = ((relocation & 0x0020) << 4) | ((relocation & 0x001f) << 3);
+ else
+ relocation &= howto->dst_mask;
+ relocation |= (bfd_get_16 (input_bfd, hit_data) & (~ howto->dst_mask));
+
+ bfd_put_16 (input_bfd, relocation, hit_data);
+
+ /* Assumes two's complement. */
+ if (signed_check > reloc_signed_max || signed_check < reloc_signed_min)
+ return bfd_reloc_overflow;
+
+ return bfd_reloc_ok;
+ }
+
+ case R_ARM_ALU_PCREL7_0:
+ case R_ARM_ALU_PCREL15_8:
+ case R_ARM_ALU_PCREL23_15:
+ {
+ bfd_vma insn;
+ bfd_vma relocation;
+
+ insn = bfd_get_32 (input_bfd, hit_data);
+ if (globals->use_rel)
+ {
+ /* Extract the addend. */
+ addend = (insn & 0xff) << ((insn & 0xf00) >> 7);
+ signed_addend = addend;
+ }
+ relocation = value + signed_addend;
+
+ relocation -= (input_section->output_section->vma
+ + input_section->output_offset
+ + rel->r_offset);
+ insn = (insn & ~0xfff)
+ | ((howto->bitpos << 7) & 0xf00)
+ | ((relocation >> howto->bitpos) & 0xff);
+ bfd_put_32 (input_bfd, value, hit_data);
+ }
+ return bfd_reloc_ok;
+
+ case R_ARM_GNU_VTINHERIT:
+ case R_ARM_GNU_VTENTRY:
+ return bfd_reloc_ok;
+
+ case R_ARM_GOTOFF32:
+ /* Relocation is relative to the start of the
+ global offset table. */
+
+ BFD_ASSERT (sgot != NULL);
+ if (sgot == NULL)
+ return bfd_reloc_notsupported;
+
+ /* If we are addressing a Thumb function, we need to adjust the
+ address by one, so that attempts to call the function pointer will
+ correctly interpret it as Thumb code. */
+ if (branch_type == ST_BRANCH_TO_THUMB)
+ value += 1;
+
+ /* 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,
+ rel->r_addend);
+
+ case R_ARM_GOTPC:
+ /* Use global offset table as symbol value. */
+ BFD_ASSERT (sgot != NULL);
+
+ if (sgot == NULL)
+ return bfd_reloc_notsupported;
+
+ *unresolved_reloc_p = FALSE;
+ value = sgot->output_section->vma;
+ return _bfd_final_link_relocate (howto, input_bfd, input_section,
+ contents, rel->r_offset, value,
+ rel->r_addend);
+
+ case R_ARM_GOT32:
+ case R_ARM_GOT_PREL:
+ /* Relocation is to the entry for this symbol in the
+ global offset table. */
+ if (sgot == NULL)
+ return bfd_reloc_notsupported;
+
+ if (dynreloc_st_type == STT_GNU_IFUNC
+ && plt_offset != (bfd_vma) -1
+ && (h == NULL || SYMBOL_REFERENCES_LOCAL (info, h)))
+ {
+ /* We have a relocation against a locally-binding STT_GNU_IFUNC
+ symbol, and the relocation resolves directly to the runtime
+ target rather than to the .iplt entry. This means that any
+ .got entry would be the same value as the .igot.plt entry,
+ so there's no point creating both. */
+ sgot = globals->root.igotplt;
+ value = sgot->output_offset + gotplt_offset;
+ }
+ else if (h != NULL)
+ {
+ bfd_vma off;
+
+ off = h->got.offset;
+ BFD_ASSERT (off != (bfd_vma) -1);
+ if ((off & 1) != 0)
+ {
+ /* We have already processsed one GOT relocation against
+ this symbol. */
+ off &= ~1;
+ if (globals->root.dynamic_sections_created
+ && !SYMBOL_REFERENCES_LOCAL (info, h))
+ *unresolved_reloc_p = FALSE;
+ }
+ else
+ {
+ Elf_Internal_Rela outrel;
+
+ if (h->dynindx != -1 && !SYMBOL_REFERENCES_LOCAL (info, h))
+ {
+ /* If the symbol doesn't resolve locally in a static
+ object, we have an undefined reference. If the
+ symbol doesn't resolve locally in a dynamic object,
+ it should be resolved by the dynamic linker. */
+ if (globals->root.dynamic_sections_created)
+ {
+ outrel.r_info = ELF32_R_INFO (h->dynindx, R_ARM_GLOB_DAT);
+ *unresolved_reloc_p = FALSE;
+ }
+ else
+ outrel.r_info = 0;
+ outrel.r_addend = 0;
+ }
+ else
+ {
+ if (dynreloc_st_type == STT_GNU_IFUNC)
+ outrel.r_info = ELF32_R_INFO (0, R_ARM_IRELATIVE);
+ else if (info->shared &&
+ (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
+ || h->root.type != bfd_link_hash_undefweak))
+ outrel.r_info = ELF32_R_INFO (0, R_ARM_RELATIVE);
+ else
+ outrel.r_info = 0;
+ outrel.r_addend = dynreloc_value;
+ }
+
+ /* The GOT entry is initialized to zero by default.
+ See if we should install a different value. */
+ if (outrel.r_addend != 0
+ && (outrel.r_info == 0 || globals->use_rel))
+ {
+ bfd_put_32 (output_bfd, outrel.r_addend,
+ sgot->contents + off);
+ outrel.r_addend = 0;
+ }
+
+ if (outrel.r_info != 0)
+ {
+ outrel.r_offset = (sgot->output_section->vma
+ + sgot->output_offset
+ + off);
+ elf32_arm_add_dynreloc (output_bfd, info, srelgot, &outrel);
+ }
+ 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
+ {
+ if (globals->use_rel)
+ bfd_put_32 (output_bfd, dynreloc_value, sgot->contents + off);
+
+ if (info->shared || dynreloc_st_type == STT_GNU_IFUNC)
+ {
+ Elf_Internal_Rela outrel;
+
+ outrel.r_addend = addend + dynreloc_value;
+ outrel.r_offset = (sgot->output_section->vma
+ + sgot->output_offset
+ + off);
+ if (dynreloc_st_type == STT_GNU_IFUNC)
+ outrel.r_info = ELF32_R_INFO (0, R_ARM_IRELATIVE);
+ else
+ outrel.r_info = ELF32_R_INFO (0, R_ARM_RELATIVE);
+ elf32_arm_add_dynreloc (output_bfd, info, srelgot, &outrel);
+ }
+
+ local_got_offsets[r_symndx] |= 1;
+ }
+
+ value = sgot->output_offset + off;
+ }
+ if (r_type != R_ARM_GOT32)
+ value += sgot->output_section->vma;
+
+ return _bfd_final_link_relocate (howto, input_bfd, input_section,
+ contents, rel->r_offset, value,
+ rel->r_addend);
+
+ case R_ARM_TLS_LDO32:
+ value = value - dtpoff_base (info);
+
+ return _bfd_final_link_relocate (howto, input_bfd, input_section,
+ contents, rel->r_offset, value,
+ rel->r_addend);
+
+ case R_ARM_TLS_LDM32:
+ {
+ bfd_vma off;
+
+ if (sgot == NULL)
+ abort ();
+
+ off = globals->tls_ldm_got.offset;
+
+ if ((off & 1) != 0)
+ off &= ~1;
+ else
+ {
+ /* If we don't know the module number, create a relocation
+ for it. */
+ if (info->shared)
+ {
+ Elf_Internal_Rela outrel;
+
+ if (srelgot == NULL)
+ abort ();
+
+ outrel.r_addend = 0;
+ outrel.r_offset = (sgot->output_section->vma
+ + sgot->output_offset + off);
+ outrel.r_info = ELF32_R_INFO (0, R_ARM_TLS_DTPMOD32);
+
+ if (globals->use_rel)
+ bfd_put_32 (output_bfd, outrel.r_addend,
+ sgot->contents + off);
+
+ elf32_arm_add_dynreloc (output_bfd, info, srelgot, &outrel);
+ }
+ else
+ bfd_put_32 (output_bfd, 1, sgot->contents + off);
+
+ globals->tls_ldm_got.offset |= 1;
+ }
+
+ value = sgot->output_section->vma + sgot->output_offset + off
+ - (input_section->output_section->vma + input_section->output_offset + rel->r_offset);
+
+ return _bfd_final_link_relocate (howto, input_bfd, input_section,
+ contents, rel->r_offset, value,
+ rel->r_addend);
+ }
+
+ case R_ARM_TLS_CALL:
+ case R_ARM_THM_TLS_CALL:
+ case R_ARM_TLS_GD32:
+ case R_ARM_TLS_IE32:
+ case R_ARM_TLS_GOTDESC:
+ case R_ARM_TLS_DESCSEQ:
+ case R_ARM_THM_TLS_DESCSEQ:
+ {
+ bfd_vma off, offplt;
+ int indx = 0;
+ char tls_type;
+
+ BFD_ASSERT (sgot != NULL);
+
+ if (h != NULL)
+ {
+ bfd_boolean dyn;
+ dyn = globals->root.dynamic_sections_created;
+ if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h)
+ && (!info->shared
+ || !SYMBOL_REFERENCES_LOCAL (info, h)))
+ {
+ *unresolved_reloc_p = FALSE;
+ indx = h->dynindx;
+ }
+ off = h->got.offset;
+ offplt = elf32_arm_hash_entry (h)->tlsdesc_got;
+ tls_type = ((struct elf32_arm_link_hash_entry *) h)->tls_type;
+ }
+ else
+ {
+ BFD_ASSERT (local_got_offsets != NULL);
+ off = local_got_offsets[r_symndx];
+ offplt = local_tlsdesc_gotents[r_symndx];
+ tls_type = elf32_arm_local_got_tls_type (input_bfd)[r_symndx];
+ }
+
+ /* Linker relaxations happens from one of the
+ R_ARM_{GOTDESC,CALL,DESCSEQ} relocations to IE or LE. */
+ if (ELF32_R_TYPE(rel->r_info) != r_type)
+ tls_type = GOT_TLS_IE;
+
+ BFD_ASSERT (tls_type != GOT_UNKNOWN);
+
+ if ((off & 1) != 0)
+ off &= ~1;
+ else
+ {
+ bfd_boolean need_relocs = FALSE;
+ Elf_Internal_Rela outrel;
+ int cur_off = off;
+
+ /* The GOT entries have not been initialized yet. Do it
+ now, and emit any relocations. If both an IE GOT and a
+ GD GOT are necessary, we emit the GD first. */
+
+ if ((info->shared || indx != 0)
+ && (h == NULL
+ || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
+ || h->root.type != bfd_link_hash_undefweak))
+ {
+ need_relocs = TRUE;
+ BFD_ASSERT (srelgot != NULL);
+ }
+
+ if (tls_type & GOT_TLS_GDESC)
+ {
+ bfd_byte *loc;
+
+ /* We should have relaxed, unless this is an undefined
+ weak symbol. */
+ BFD_ASSERT ((h && (h->root.type == bfd_link_hash_undefweak))
+ || info->shared);
+ BFD_ASSERT (globals->sgotplt_jump_table_size + offplt + 8
+ <= globals->root.sgotplt->size);
+
+ outrel.r_addend = 0;
+ outrel.r_offset = (globals->root.sgotplt->output_section->vma
+ + globals->root.sgotplt->output_offset
+ + offplt
+ + globals->sgotplt_jump_table_size);
+
+ outrel.r_info = ELF32_R_INFO (indx, R_ARM_TLS_DESC);
+ sreloc = globals->root.srelplt;
+ loc = sreloc->contents;
+ loc += globals->next_tls_desc_index++ * RELOC_SIZE (globals);
+ BFD_ASSERT (loc + RELOC_SIZE (globals)
+ <= sreloc->contents + sreloc->size);
+
+ SWAP_RELOC_OUT (globals) (output_bfd, &outrel, loc);
+
+ /* For globals, the first word in the relocation gets
+ the relocation index and the top bit set, or zero,
+ if we're binding now. For locals, it gets the
+ symbol's offset in the tls section. */
+ bfd_put_32 (output_bfd,
+ !h ? value - elf_hash_table (info)->tls_sec->vma
+ : info->flags & DF_BIND_NOW ? 0
+ : 0x80000000 | ELF32_R_SYM (outrel.r_info),
+ globals->root.sgotplt->contents + offplt
+ + globals->sgotplt_jump_table_size);
+
+ /* Second word in the relocation is always zero. */
+ bfd_put_32 (output_bfd, 0,
+ globals->root.sgotplt->contents + offplt
+ + globals->sgotplt_jump_table_size + 4);
+ }
+ if (tls_type & GOT_TLS_GD)
+ {
+ if (need_relocs)
+ {
+ outrel.r_addend = 0;
+ outrel.r_offset = (sgot->output_section->vma
+ + sgot->output_offset
+ + cur_off);
+ outrel.r_info = ELF32_R_INFO (indx, R_ARM_TLS_DTPMOD32);
+
+ if (globals->use_rel)
+ bfd_put_32 (output_bfd, outrel.r_addend,
+ sgot->contents + cur_off);
+
+ elf32_arm_add_dynreloc (output_bfd, info, srelgot, &outrel);
+
+ if (indx == 0)
+ bfd_put_32 (output_bfd, value - dtpoff_base (info),
+ sgot->contents + cur_off + 4);
+ else
+ {
+ outrel.r_addend = 0;
+ outrel.r_info = ELF32_R_INFO (indx,
+ R_ARM_TLS_DTPOFF32);
+ outrel.r_offset += 4;
+
+ if (globals->use_rel)
+ bfd_put_32 (output_bfd, outrel.r_addend,
+ sgot->contents + cur_off + 4);
+
+ elf32_arm_add_dynreloc (output_bfd, info,
+ srelgot, &outrel);
+ }
+ }
+ else
+ {
+ /* If we are not emitting relocations for a
+ general dynamic reference, then we must be in a
+ static link or an executable link with the
+ symbol binding locally. Mark it as belonging
+ to module 1, the executable. */
+ bfd_put_32 (output_bfd, 1,
+ sgot->contents + cur_off);
+ bfd_put_32 (output_bfd, value - dtpoff_base (info),
+ sgot->contents + cur_off + 4);
+ }
+
+ cur_off += 8;
+ }
+
+ if (tls_type & GOT_TLS_IE)
+ {
+ if (need_relocs)
+ {
+ if (indx == 0)
+ outrel.r_addend = value - dtpoff_base (info);
+ else
+ outrel.r_addend = 0;
+ outrel.r_offset = (sgot->output_section->vma
+ + sgot->output_offset
+ + cur_off);
+ outrel.r_info = ELF32_R_INFO (indx, R_ARM_TLS_TPOFF32);
+
+ if (globals->use_rel)
+ bfd_put_32 (output_bfd, outrel.r_addend,
+ sgot->contents + cur_off);
+
+ elf32_arm_add_dynreloc (output_bfd, info, srelgot, &outrel);
+ }
+ else
+ bfd_put_32 (output_bfd, tpoff (info, value),
+ sgot->contents + cur_off);
+ cur_off += 4;
+ }
+
+ if (h != NULL)
+ h->got.offset |= 1;
+ else
+ local_got_offsets[r_symndx] |= 1;
+ }
+
+ if ((tls_type & GOT_TLS_GD) && r_type != R_ARM_TLS_GD32)
+ off += 8;
+ else if (tls_type & GOT_TLS_GDESC)
+ off = offplt;
+
+ if (ELF32_R_TYPE(rel->r_info) == R_ARM_TLS_CALL
+ || ELF32_R_TYPE(rel->r_info) == R_ARM_THM_TLS_CALL)
+ {
+ bfd_signed_vma offset;
+ /* TLS stubs are arm mode. The original symbol is a
+ data object, so branch_type is bogus. */
+ branch_type = ST_BRANCH_TO_ARM;
+ enum elf32_arm_stub_type stub_type
+ = arm_type_of_stub (info, input_section, rel,
+ st_type, &branch_type,
+ (struct elf32_arm_link_hash_entry *)h,
+ globals->tls_trampoline, globals->root.splt,
+ input_bfd, sym_name);
+
+ if (stub_type != arm_stub_none)
+ {
+ struct elf32_arm_stub_hash_entry *stub_entry
+ = elf32_arm_get_stub_entry
+ (input_section, globals->root.splt, 0, rel,
+ globals, stub_type);
+ offset = (stub_entry->stub_offset
+ + stub_entry->stub_sec->output_offset
+ + stub_entry->stub_sec->output_section->vma);
+ }
+ else
+ offset = (globals->root.splt->output_section->vma
+ + globals->root.splt->output_offset
+ + globals->tls_trampoline);
+
+ if (ELF32_R_TYPE(rel->r_info) == R_ARM_TLS_CALL)
+ {
+ unsigned long inst;
+
+ offset -= (input_section->output_section->vma
+ + input_section->output_offset
+ + rel->r_offset + 8);
+
+ inst = offset >> 2;
+ inst &= 0x00ffffff;
+ value = inst | (globals->use_blx ? 0xfa000000 : 0xeb000000);
+ }
+ else
+ {
+ /* Thumb blx encodes the offset in a complicated
+ fashion. */
+ unsigned upper_insn, lower_insn;
+ unsigned neg;
+
+ offset -= (input_section->output_section->vma
+ + input_section->output_offset
+ + rel->r_offset + 4);
+
+ if (stub_type != arm_stub_none
+ && arm_stub_is_thumb (stub_type))
+ {
+ lower_insn = 0xd000;
+ }
+ else
+ {
+ lower_insn = 0xc000;
+ /* Round up the offset to a word boundary. */
+ offset = (offset + 2) & ~2;
+ }
+
+ neg = offset < 0;
+ upper_insn = (0xf000
+ | ((offset >> 12) & 0x3ff)
+ | (neg << 10));
+ lower_insn |= (((!((offset >> 23) & 1)) ^ neg) << 13)
+ | (((!((offset >> 22) & 1)) ^ neg) << 11)
+ | ((offset >> 1) & 0x7ff);
+ bfd_put_16 (input_bfd, upper_insn, hit_data);
+ bfd_put_16 (input_bfd, lower_insn, hit_data + 2);
+ return bfd_reloc_ok;
+ }
+ }
+ /* These relocations needs special care, as besides the fact
+ they point somewhere in .gotplt, the addend must be
+ adjusted accordingly depending on the type of instruction
+ we refer to. */
+ else if ((r_type == R_ARM_TLS_GOTDESC) && (tls_type & GOT_TLS_GDESC))
+ {
+ unsigned long data, insn;
+ unsigned thumb;
+
+ data = bfd_get_32 (input_bfd, hit_data);
+ thumb = data & 1;
+ data &= ~1u;
+
+ if (thumb)
+ {
+ insn = bfd_get_16 (input_bfd, contents + rel->r_offset - data);
+ if ((insn & 0xf000) == 0xf000 || (insn & 0xf800) == 0xe800)
+ insn = (insn << 16)
+ | bfd_get_16 (input_bfd,
+ contents + rel->r_offset - data + 2);
+ if ((insn & 0xf800c000) == 0xf000c000)
+ /* bl/blx */
+ value = -6;
+ else if ((insn & 0xffffff00) == 0x4400)
+ /* add */
+ value = -5;
+ else
+ {
+ (*_bfd_error_handler)
+ (_("%B(%A+0x%lx):unexpected Thumb instruction '0x%x' referenced by TLS_GOTDESC"),
+ input_bfd, input_section,
+ (unsigned long)rel->r_offset, insn);
+ return bfd_reloc_notsupported;
+ }
+ }
+ else
+ {
+ insn = bfd_get_32 (input_bfd, contents + rel->r_offset - data);
+
+ switch (insn >> 24)
+ {
+ case 0xeb: /* bl */
+ case 0xfa: /* blx */
+ value = -4;
+ break;
+
+ case 0xe0: /* add */
+ value = -8;
+ break;
+
+ default:
+ (*_bfd_error_handler)
+ (_("%B(%A+0x%lx):unexpected ARM instruction '0x%x' referenced by TLS_GOTDESC"),
+ input_bfd, input_section,
+ (unsigned long)rel->r_offset, insn);
+ return bfd_reloc_notsupported;
+ }
+ }
+
+ value += ((globals->root.sgotplt->output_section->vma
+ + globals->root.sgotplt->output_offset + off)
+ - (input_section->output_section->vma
+ + input_section->output_offset
+ + rel->r_offset)
+ + globals->sgotplt_jump_table_size);
+ }
+ else
+ value = ((globals->root.sgot->output_section->vma
+ + globals->root.sgot->output_offset + off)
+ - (input_section->output_section->vma
+ + input_section->output_offset + rel->r_offset));
+
+ return _bfd_final_link_relocate (howto, input_bfd, input_section,
+ contents, rel->r_offset, value,
+ rel->r_addend);
+ }
+
+ case R_ARM_TLS_LE32:
+ if (info->shared && !info->pie)
+ {
+ (*_bfd_error_handler)
+ (_("%B(%A+0x%lx): R_ARM_TLS_LE32 relocation not permitted in shared object"),
+ input_bfd, input_section,
+ (long) rel->r_offset, howto->name);
+ return bfd_reloc_notsupported;
+ }
+ else
+ value = tpoff (info, value);
+
+ return _bfd_final_link_relocate (howto, input_bfd, input_section,
+ contents, rel->r_offset, value,
+ rel->r_addend);
+
+ case R_ARM_V4BX:
+ if (globals->fix_v4bx)
+ {
+ bfd_vma insn = bfd_get_32 (input_bfd, hit_data);
+
+ /* Ensure that we have a BX instruction. */
+ BFD_ASSERT ((insn & 0x0ffffff0) == 0x012fff10);
+
+ if (globals->fix_v4bx == 2 && (insn & 0xf) != 0xf)
+ {
+ /* Branch to veneer. */
+ bfd_vma glue_addr;
+ glue_addr = elf32_arm_bx_glue (info, insn & 0xf);
+ glue_addr -= input_section->output_section->vma
+ + input_section->output_offset
+ + rel->r_offset + 8;
+ insn = (insn & 0xf0000000) | 0x0a000000
+ | ((glue_addr >> 2) & 0x00ffffff);
+ }
+ else
+ {
+ /* Preserve Rm (lowest four bits) and the condition code
+ (highest four bits). Other bits encode MOV PC,Rm. */
+ insn = (insn & 0xf000000f) | 0x01a0f000;
+ }
+
+ bfd_put_32 (input_bfd, insn, hit_data);
+ }
+ return bfd_reloc_ok;
+
+ case R_ARM_MOVW_ABS_NC:
+ case R_ARM_MOVT_ABS:
+ case R_ARM_MOVW_PREL_NC:
+ case R_ARM_MOVT_PREL:
+ /* Until we properly support segment-base-relative addressing then
+ we assume the segment base to be zero, as for the group relocations.
+ Thus R_ARM_MOVW_BREL_NC has the same semantics as R_ARM_MOVW_ABS_NC
+ and R_ARM_MOVT_BREL has the same semantics as R_ARM_MOVT_ABS. */
+ case R_ARM_MOVW_BREL_NC:
+ case R_ARM_MOVW_BREL:
+ case R_ARM_MOVT_BREL:
+ {
+ bfd_vma insn = bfd_get_32 (input_bfd, hit_data);
+
+ if (globals->use_rel)
+ {
+ addend = ((insn >> 4) & 0xf000) | (insn & 0xfff);
+ signed_addend = (addend ^ 0x8000) - 0x8000;
+ }
+
+ value += signed_addend;
+
+ if (r_type == R_ARM_MOVW_PREL_NC || r_type == R_ARM_MOVT_PREL)
+ value -= (input_section->output_section->vma
+ + input_section->output_offset + rel->r_offset);
+
+ if (r_type == R_ARM_MOVW_BREL && value >= 0x10000)
+ return bfd_reloc_overflow;
+
+ if (branch_type == ST_BRANCH_TO_THUMB)
+ value |= 1;
+
+ if (r_type == R_ARM_MOVT_ABS || r_type == R_ARM_MOVT_PREL
+ || r_type == R_ARM_MOVT_BREL)
+ value >>= 16;
+
+ insn &= 0xfff0f000;
+ insn |= value & 0xfff;
+ insn |= (value & 0xf000) << 4;
+ bfd_put_32 (input_bfd, insn, hit_data);
+ }
+ return bfd_reloc_ok;
+
+ case R_ARM_THM_MOVW_ABS_NC:
+ case R_ARM_THM_MOVT_ABS:
+ case R_ARM_THM_MOVW_PREL_NC:
+ case R_ARM_THM_MOVT_PREL:
+ /* Until we properly support segment-base-relative addressing then
+ we assume the segment base to be zero, as for the above relocations.
+ Thus R_ARM_THM_MOVW_BREL_NC has the same semantics as
+ R_ARM_THM_MOVW_ABS_NC and R_ARM_THM_MOVT_BREL has the same semantics
+ as R_ARM_THM_MOVT_ABS. */
+ case R_ARM_THM_MOVW_BREL_NC:
+ case R_ARM_THM_MOVW_BREL:
+ case R_ARM_THM_MOVT_BREL:
+ {
+ bfd_vma insn;
+
+ insn = bfd_get_16 (input_bfd, hit_data) << 16;
+ insn |= bfd_get_16 (input_bfd, hit_data + 2);
+
+ if (globals->use_rel)
+ {
+ addend = ((insn >> 4) & 0xf000)
+ | ((insn >> 15) & 0x0800)
+ | ((insn >> 4) & 0x0700)
+ | (insn & 0x00ff);
+ signed_addend = (addend ^ 0x8000) - 0x8000;
+ }
+
+ value += signed_addend;
+
+ if (r_type == R_ARM_THM_MOVW_PREL_NC || r_type == R_ARM_THM_MOVT_PREL)
+ value -= (input_section->output_section->vma
+ + input_section->output_offset + rel->r_offset);
+
+ if (r_type == R_ARM_THM_MOVW_BREL && value >= 0x10000)
+ return bfd_reloc_overflow;
+
+ if (branch_type == ST_BRANCH_TO_THUMB)
+ value |= 1;
+
+ if (r_type == R_ARM_THM_MOVT_ABS || r_type == R_ARM_THM_MOVT_PREL
+ || r_type == R_ARM_THM_MOVT_BREL)
+ value >>= 16;
+
+ insn &= 0xfbf08f00;
+ insn |= (value & 0xf000) << 4;
+ insn |= (value & 0x0800) << 15;
+ insn |= (value & 0x0700) << 4;
+ insn |= (value & 0x00ff);
+
+ bfd_put_16 (input_bfd, insn >> 16, hit_data);
+ bfd_put_16 (input_bfd, insn & 0xffff, hit_data + 2);
+ }
+ return bfd_reloc_ok;
+
+ case R_ARM_ALU_PC_G0_NC:
+ case R_ARM_ALU_PC_G1_NC:
+ case R_ARM_ALU_PC_G0:
+ case R_ARM_ALU_PC_G1:
+ case R_ARM_ALU_PC_G2:
+ case R_ARM_ALU_SB_G0_NC:
+ case R_ARM_ALU_SB_G1_NC:
+ case R_ARM_ALU_SB_G0:
+ case R_ARM_ALU_SB_G1:
+ case R_ARM_ALU_SB_G2:
+ {
+ bfd_vma insn = bfd_get_32 (input_bfd, hit_data);
+ bfd_vma pc = input_section->output_section->vma
+ + input_section->output_offset + rel->r_offset;
+ /* sb is the origin of the *segment* containing the symbol. */
+ bfd_vma sb = sym_sec ? sym_sec->output_section->vma : 0;
+ bfd_vma residual;
+ bfd_vma g_n;
+ bfd_signed_vma signed_value;
+ int group = 0;
+
+ /* Determine which group of bits to select. */
+ switch (r_type)
+ {
+ case R_ARM_ALU_PC_G0_NC:
+ case R_ARM_ALU_PC_G0:
+ case R_ARM_ALU_SB_G0_NC:
+ case R_ARM_ALU_SB_G0:
+ group = 0;
+ break;
+
+ case R_ARM_ALU_PC_G1_NC:
+ case R_ARM_ALU_PC_G1:
+ case R_ARM_ALU_SB_G1_NC:
+ case R_ARM_ALU_SB_G1:
+ group = 1;
+ break;
+
+ case R_ARM_ALU_PC_G2:
+ case R_ARM_ALU_SB_G2:
+ group = 2;
+ break;
+
+ default:
+ abort ();
+ }
+
+ /* If REL, extract the addend from the insn. If RELA, it will
+ have already been fetched for us. */
+ if (globals->use_rel)
+ {
+ int negative;
+ bfd_vma constant = insn & 0xff;
+ bfd_vma rotation = (insn & 0xf00) >> 8;
+
+ if (rotation == 0)
+ signed_addend = constant;
+ else
+ {
+ /* Compensate for the fact that in the instruction, the
+ rotation is stored in multiples of 2 bits. */
+ rotation *= 2;
+
+ /* Rotate "constant" right by "rotation" bits. */
+ signed_addend = (constant >> rotation) |
+ (constant << (8 * sizeof (bfd_vma) - rotation));
+ }
+
+ /* Determine if the instruction is an ADD or a SUB.
+ (For REL, this determines the sign of the addend.) */
+ negative = identify_add_or_sub (insn);
+ if (negative == 0)
+ {
+ (*_bfd_error_handler)
+ (_("%B(%A+0x%lx): Only ADD or SUB instructions are allowed for ALU group relocations"),
+ input_bfd, input_section,
+ (long) rel->r_offset, howto->name);
+ return bfd_reloc_overflow;
+ }
+
+ signed_addend *= negative;
+ }
+
+ /* Compute the value (X) to go in the place. */
+ if (r_type == R_ARM_ALU_PC_G0_NC
+ || r_type == R_ARM_ALU_PC_G1_NC
+ || r_type == R_ARM_ALU_PC_G0
+ || r_type == R_ARM_ALU_PC_G1
+ || r_type == R_ARM_ALU_PC_G2)
+ /* PC relative. */
+ signed_value = value - pc + signed_addend;
+ else
+ /* Section base relative. */
+ signed_value = value - sb + signed_addend;
+
+ /* If the target symbol is a Thumb function, then set the
+ Thumb bit in the address. */
+ if (branch_type == ST_BRANCH_TO_THUMB)
+ signed_value |= 1;
+
+ /* Calculate the value of the relevant G_n, in encoded
+ constant-with-rotation format. */
+ g_n = calculate_group_reloc_mask (abs (signed_value), group,
+ &residual);
+
+ /* Check for overflow if required. */
+ if ((r_type == R_ARM_ALU_PC_G0
+ || r_type == R_ARM_ALU_PC_G1
+ || r_type == R_ARM_ALU_PC_G2
+ || r_type == R_ARM_ALU_SB_G0
+ || r_type == R_ARM_ALU_SB_G1
+ || r_type == R_ARM_ALU_SB_G2) && residual != 0)
+ {
+ (*_bfd_error_handler)
+ (_("%B(%A+0x%lx): Overflow whilst splitting 0x%lx for group relocation %s"),
+ input_bfd, input_section,
+ (long) rel->r_offset, abs (signed_value), howto->name);
+ return bfd_reloc_overflow;
+ }
+
+ /* Mask out the value and the ADD/SUB part of the opcode; take care
+ not to destroy the S bit. */
+ insn &= 0xff1ff000;
+
+ /* Set the opcode according to whether the value to go in the
+ place is negative. */
+ if (signed_value < 0)
+ insn |= 1 << 22;
+ else
+ insn |= 1 << 23;
+
+ /* Encode the offset. */
+ insn |= g_n;
+
+ bfd_put_32 (input_bfd, insn, hit_data);
+ }
+ return bfd_reloc_ok;
+
+ case R_ARM_LDR_PC_G0:
+ case R_ARM_LDR_PC_G1:
+ case R_ARM_LDR_PC_G2:
+ case R_ARM_LDR_SB_G0:
+ case R_ARM_LDR_SB_G1:
+ case R_ARM_LDR_SB_G2:
+ {
+ bfd_vma insn = bfd_get_32 (input_bfd, hit_data);
+ bfd_vma pc = input_section->output_section->vma
+ + input_section->output_offset + rel->r_offset;
+ /* sb is the origin of the *segment* containing the symbol. */
+ bfd_vma sb = sym_sec ? sym_sec->output_section->vma : 0;
+ bfd_vma residual;
+ bfd_signed_vma signed_value;
+ int group = 0;
+
+ /* Determine which groups of bits to calculate. */
+ switch (r_type)
+ {
+ case R_ARM_LDR_PC_G0:
+ case R_ARM_LDR_SB_G0:
+ group = 0;
+ break;
+
+ case R_ARM_LDR_PC_G1:
+ case R_ARM_LDR_SB_G1:
+ group = 1;
+ break;
+
+ case R_ARM_LDR_PC_G2:
+ case R_ARM_LDR_SB_G2:
+ group = 2;
+ break;
+
+ default:
+ abort ();
+ }
+
+ /* If REL, extract the addend from the insn. If RELA, it will
+ have already been fetched for us. */
+ if (globals->use_rel)
+ {
+ int negative = (insn & (1 << 23)) ? 1 : -1;
+ signed_addend = negative * (insn & 0xfff);
+ }
+
+ /* Compute the value (X) to go in the place. */
+ if (r_type == R_ARM_LDR_PC_G0
+ || r_type == R_ARM_LDR_PC_G1
+ || r_type == R_ARM_LDR_PC_G2)
+ /* PC relative. */
+ signed_value = value - pc + signed_addend;
+ else
+ /* Section base relative. */
+ signed_value = value - sb + signed_addend;
+
+ /* Calculate the value of the relevant G_{n-1} to obtain
+ the residual at that stage. */
+ calculate_group_reloc_mask (abs (signed_value), group - 1, &residual);
+
+ /* Check for overflow. */
+ if (residual >= 0x1000)
+ {
+ (*_bfd_error_handler)
+ (_("%B(%A+0x%lx): Overflow whilst splitting 0x%lx for group relocation %s"),
+ input_bfd, input_section,
+ (long) rel->r_offset, abs (signed_value), howto->name);
+ return bfd_reloc_overflow;
+ }
+
+ /* Mask out the value and U bit. */
+ insn &= 0xff7ff000;
+
+ /* Set the U bit if the value to go in the place is non-negative. */
+ if (signed_value >= 0)
+ insn |= 1 << 23;
+
+ /* Encode the offset. */
+ insn |= residual;
+
+ bfd_put_32 (input_bfd, insn, hit_data);
+ }
+ return bfd_reloc_ok;
+
+ case R_ARM_LDRS_PC_G0:
+ case R_ARM_LDRS_PC_G1:
+ case R_ARM_LDRS_PC_G2:
+ case R_ARM_LDRS_SB_G0:
+ case R_ARM_LDRS_SB_G1:
+ case R_ARM_LDRS_SB_G2:
+ {
+ bfd_vma insn = bfd_get_32 (input_bfd, hit_data);
+ bfd_vma pc = input_section->output_section->vma
+ + input_section->output_offset + rel->r_offset;
+ /* sb is the origin of the *segment* containing the symbol. */
+ bfd_vma sb = sym_sec ? sym_sec->output_section->vma : 0;
+ bfd_vma residual;
+ bfd_signed_vma signed_value;
+ int group = 0;
+
+ /* Determine which groups of bits to calculate. */
+ switch (r_type)
+ {
+ case R_ARM_LDRS_PC_G0:
+ case R_ARM_LDRS_SB_G0:
+ group = 0;
+ break;
+
+ case R_ARM_LDRS_PC_G1:
+ case R_ARM_LDRS_SB_G1:
+ group = 1;
+ break;
+
+ case R_ARM_LDRS_PC_G2:
+ case R_ARM_LDRS_SB_G2:
+ group = 2;
+ break;
+
+ default:
+ abort ();
+ }
+
+ /* If REL, extract the addend from the insn. If RELA, it will
+ have already been fetched for us. */
+ if (globals->use_rel)
+ {
+ int negative = (insn & (1 << 23)) ? 1 : -1;
+ signed_addend = negative * (((insn & 0xf00) >> 4) + (insn & 0xf));
+ }
+
+ /* Compute the value (X) to go in the place. */
+ if (r_type == R_ARM_LDRS_PC_G0
+ || r_type == R_ARM_LDRS_PC_G1
+ || r_type == R_ARM_LDRS_PC_G2)
+ /* PC relative. */
+ signed_value = value - pc + signed_addend;
+ else
+ /* Section base relative. */
+ signed_value = value - sb + signed_addend;
+
+ /* Calculate the value of the relevant G_{n-1} to obtain
+ the residual at that stage. */
+ calculate_group_reloc_mask (abs (signed_value), group - 1, &residual);
+
+ /* Check for overflow. */
+ if (residual >= 0x100)
+ {
+ (*_bfd_error_handler)
+ (_("%B(%A+0x%lx): Overflow whilst splitting 0x%lx for group relocation %s"),
+ input_bfd, input_section,
+ (long) rel->r_offset, abs (signed_value), howto->name);
+ return bfd_reloc_overflow;
+ }
+
+ /* Mask out the value and U bit. */
+ insn &= 0xff7ff0f0;
+
+ /* Set the U bit if the value to go in the place is non-negative. */
+ if (signed_value >= 0)
+ insn |= 1 << 23;
+
+ /* Encode the offset. */
+ insn |= ((residual & 0xf0) << 4) | (residual & 0xf);
+
+ bfd_put_32 (input_bfd, insn, hit_data);
+ }
+ return bfd_reloc_ok;
+
+ case R_ARM_LDC_PC_G0:
+ case R_ARM_LDC_PC_G1:
+ case R_ARM_LDC_PC_G2:
+ case R_ARM_LDC_SB_G0:
+ case R_ARM_LDC_SB_G1:
+ case R_ARM_LDC_SB_G2:
+ {
+ bfd_vma insn = bfd_get_32 (input_bfd, hit_data);
+ bfd_vma pc = input_section->output_section->vma
+ + input_section->output_offset + rel->r_offset;
+ /* sb is the origin of the *segment* containing the symbol. */
+ bfd_vma sb = sym_sec ? sym_sec->output_section->vma : 0;
+ bfd_vma residual;
+ bfd_signed_vma signed_value;
+ int group = 0;
+
+ /* Determine which groups of bits to calculate. */
+ switch (r_type)
+ {
+ case R_ARM_LDC_PC_G0:
+ case R_ARM_LDC_SB_G0:
+ group = 0;
+ break;
+
+ case R_ARM_LDC_PC_G1:
+ case R_ARM_LDC_SB_G1:
+ group = 1;
+ break;
+
+ case R_ARM_LDC_PC_G2:
+ case R_ARM_LDC_SB_G2:
+ group = 2;
+ break;
+
+ default:
+ abort ();
+ }
+
+ /* If REL, extract the addend from the insn. If RELA, it will
+ have already been fetched for us. */
+ if (globals->use_rel)
+ {
+ int negative = (insn & (1 << 23)) ? 1 : -1;
+ signed_addend = negative * ((insn & 0xff) << 2);
+ }
+
+ /* Compute the value (X) to go in the place. */
+ if (r_type == R_ARM_LDC_PC_G0
+ || r_type == R_ARM_LDC_PC_G1
+ || r_type == R_ARM_LDC_PC_G2)
+ /* PC relative. */
+ signed_value = value - pc + signed_addend;
+ else
+ /* Section base relative. */
+ signed_value = value - sb + signed_addend;
+
+ /* Calculate the value of the relevant G_{n-1} to obtain
+ the residual at that stage. */
+ calculate_group_reloc_mask (abs (signed_value), group - 1, &residual);
+
+ /* Check for overflow. (The absolute value to go in the place must be
+ divisible by four and, after having been divided by four, must
+ fit in eight bits.) */
+ if ((residual & 0x3) != 0 || residual >= 0x400)
+ {
+ (*_bfd_error_handler)
+ (_("%B(%A+0x%lx): Overflow whilst splitting 0x%lx for group relocation %s"),
+ input_bfd, input_section,
+ (long) rel->r_offset, abs (signed_value), howto->name);
+ return bfd_reloc_overflow;
+ }
+
+ /* Mask out the value and U bit. */
+ insn &= 0xff7fff00;
+
+ /* Set the U bit if the value to go in the place is non-negative. */
+ if (signed_value >= 0)
+ insn |= 1 << 23;
+
+ /* Encode the offset. */
+ insn |= residual >> 2;
+
+ bfd_put_32 (input_bfd, insn, hit_data);
+ }
+ return bfd_reloc_ok;
+
+ default:
+ return bfd_reloc_notsupported;
+ }
+}
+
+/* Add INCREMENT to the reloc (of type HOWTO) at ADDRESS. */
+static void
+arm_add_to_rel (bfd * abfd,
+ bfd_byte * address,
+ reloc_howto_type * howto,
+ bfd_signed_vma increment)
+{
+ bfd_signed_vma addend;
+
+ if (howto->type == R_ARM_THM_CALL
+ || howto->type == R_ARM_THM_JUMP24)
+ {
+ int upper_insn, lower_insn;
+ int upper, lower;
+
+ upper_insn = bfd_get_16 (abfd, address);
+ lower_insn = bfd_get_16 (abfd, address + 2);
+ upper = upper_insn & 0x7ff;
+ lower = lower_insn & 0x7ff;
+
+ addend = (upper << 12) | (lower << 1);
+ addend += increment;
+ addend >>= 1;
+
+ upper_insn = (upper_insn & 0xf800) | ((addend >> 11) & 0x7ff);
+ lower_insn = (lower_insn & 0xf800) | (addend & 0x7ff);
+
+ bfd_put_16 (abfd, (bfd_vma) upper_insn, address);
+ bfd_put_16 (abfd, (bfd_vma) lower_insn, address + 2);
+ }
+ else
+ {
+ bfd_vma contents;
+
+ contents = bfd_get_32 (abfd, address);
+
+ /* Get the (signed) value from the instruction. */
+ addend = contents & howto->src_mask;
+ if (addend & ((howto->src_mask + 1) >> 1))
+ {
+ bfd_signed_vma mask;
+
+ mask = -1;
+ mask &= ~ howto->src_mask;
+ addend |= mask;
+ }
+
+ /* Add in the increment, (which is a byte value). */
+ switch (howto->type)
+ {
+ default:
+ addend += increment;
+ break;
+
+ case R_ARM_PC24:
+ case R_ARM_PLT32:
+ case R_ARM_CALL:
+ case R_ARM_JUMP24:
+ addend <<= howto->size;
+ addend += increment;
+
+ /* Should we check for overflow here ? */
+
+ /* Drop any undesired bits. */
+ addend >>= howto->rightshift;
+ break;
+ }
+
+ contents = (contents & ~ howto->dst_mask) | (addend & howto->dst_mask);
+
+ bfd_put_32 (abfd, contents, address);
+ }
+}
+
+#define IS_ARM_TLS_RELOC(R_TYPE) \
+ ((R_TYPE) == R_ARM_TLS_GD32 \
+ || (R_TYPE) == R_ARM_TLS_LDO32 \
+ || (R_TYPE) == R_ARM_TLS_LDM32 \
+ || (R_TYPE) == R_ARM_TLS_DTPOFF32 \
+ || (R_TYPE) == R_ARM_TLS_DTPMOD32 \
+ || (R_TYPE) == R_ARM_TLS_TPOFF32 \
+ || (R_TYPE) == R_ARM_TLS_LE32 \
+ || (R_TYPE) == R_ARM_TLS_IE32 \
+ || IS_ARM_TLS_GNU_RELOC (R_TYPE))
+
+/* Specific set of relocations for the gnu tls dialect. */
+#define IS_ARM_TLS_GNU_RELOC(R_TYPE) \
+ ((R_TYPE) == R_ARM_TLS_GOTDESC \
+ || (R_TYPE) == R_ARM_TLS_CALL \
+ || (R_TYPE) == R_ARM_THM_TLS_CALL \
+ || (R_TYPE) == R_ARM_TLS_DESCSEQ \
+ || (R_TYPE) == R_ARM_THM_TLS_DESCSEQ)
+
+/* Relocate an ARM ELF section. */
+
+static bfd_boolean
+elf32_arm_relocate_section (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;
+ struct elf32_arm_link_hash_table * globals;
+
+ globals = elf32_arm_hash_table (info);
+ if (globals == NULL)
+ return FALSE;
+
+ symtab_hdr = & elf_symtab_hdr (input_bfd);
+ 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;
+ arelent bfd_reloc;
+ char sym_type;
+ bfd_boolean unresolved_reloc = FALSE;
+ char *error_message = NULL;
+
+ r_symndx = ELF32_R_SYM (rel->r_info);
+ r_type = ELF32_R_TYPE (rel->r_info);
+ r_type = arm_real_reloc_type (globals, r_type);
+
+ if ( r_type == R_ARM_GNU_VTENTRY
+ || r_type == R_ARM_GNU_VTINHERIT)
+ continue;
+
+ bfd_reloc.howto = elf32_arm_howto_from_type (r_type);
+ howto = bfd_reloc.howto;
+
+ h = NULL;
+ sym = NULL;
+ sec = NULL;
+
+ if (r_symndx < symtab_hdr->sh_info)
+ {
+ sym = local_syms + r_symndx;
+ sym_type = ELF32_ST_TYPE (sym->st_info);
+ sec = local_sections[r_symndx];
+
+ /* An object file might have a reference to a local
+ undefined symbol. This is a daft object file, but we
+ should at least do something about it. V4BX & NONE
+ relocations do not use the symbol and are explicitly
+ allowed to use the undefined symbol, so allow those.
+ Likewise for relocations against STN_UNDEF. */
+ if (r_type != R_ARM_V4BX
+ && r_type != R_ARM_NONE
+ && r_symndx != STN_UNDEF
+ && bfd_is_und_section (sec)
+ && ELF_ST_BIND (sym->st_info) != STB_WEAK)
+ {
+ if (!info->callbacks->undefined_symbol
+ (info, bfd_elf_string_from_elf_section
+ (input_bfd, symtab_hdr->sh_link, sym->st_name),
+ input_bfd, input_section,
+ rel->r_offset, TRUE))
+ return FALSE;
+ }
+
+ if (globals->use_rel)
+ {
+ relocation = (sec->output_section->vma
+ + sec->output_offset
+ + sym->st_value);
+ if (!info->relocatable
+ && (sec->flags & SEC_MERGE)
+ && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
+ {
+ asection *msec;
+ bfd_vma addend, value;
+
+ switch (r_type)
+ {
+ case R_ARM_MOVW_ABS_NC:
+ case R_ARM_MOVT_ABS:
+ value = bfd_get_32 (input_bfd, contents + rel->r_offset);
+ addend = ((value & 0xf0000) >> 4) | (value & 0xfff);
+ addend = (addend ^ 0x8000) - 0x8000;
+ break;
+
+ case R_ARM_THM_MOVW_ABS_NC:
+ case R_ARM_THM_MOVT_ABS:
+ value = bfd_get_16 (input_bfd, contents + rel->r_offset)
+ << 16;
+ value |= bfd_get_16 (input_bfd,
+ contents + rel->r_offset + 2);
+ addend = ((value & 0xf7000) >> 4) | (value & 0xff)
+ | ((value & 0x04000000) >> 15);
+ addend = (addend ^ 0x8000) - 0x8000;
+ break;
+
+ default:
+ if (howto->rightshift
+ || (howto->src_mask & (howto->src_mask + 1)))
+ {
+ (*_bfd_error_handler)
+ (_("%B(%A+0x%lx): %s relocation against SEC_MERGE section"),
+ input_bfd, input_section,
+ (long) rel->r_offset, howto->name);
+ return FALSE;
+ }
+
+ value = bfd_get_32 (input_bfd, contents + rel->r_offset);
+
+ /* Get the (signed) value from the instruction. */
+ addend = value & howto->src_mask;
+ if (addend & ((howto->src_mask + 1) >> 1))
+ {
+ bfd_signed_vma mask;
+
+ mask = -1;
+ mask &= ~ howto->src_mask;
+ addend |= mask;
+ }
+ break;
+ }
+
+ msec = sec;
+ addend =
+ _bfd_elf_rel_local_sym (output_bfd, sym, &msec, addend)
+ - relocation;
+ addend += msec->output_section->vma + msec->output_offset;
+
+ /* Cases here must match those in the preceding
+ switch statement. */
+ switch (r_type)
+ {
+ case R_ARM_MOVW_ABS_NC:
+ case R_ARM_MOVT_ABS:
+ value = (value & 0xfff0f000) | ((addend & 0xf000) << 4)
+ | (addend & 0xfff);
+ bfd_put_32 (input_bfd, value, contents + rel->r_offset);
+ break;
+
+ case R_ARM_THM_MOVW_ABS_NC:
+ case R_ARM_THM_MOVT_ABS:
+ value = (value & 0xfbf08f00) | ((addend & 0xf700) << 4)
+ | (addend & 0xff) | ((addend & 0x0800) << 15);
+ bfd_put_16 (input_bfd, value >> 16,
+ contents + rel->r_offset);
+ bfd_put_16 (input_bfd, value,
+ contents + rel->r_offset + 2);
+ break;
+
+ default:
+ value = (value & ~ howto->dst_mask)
+ | (addend & howto->dst_mask);
+ bfd_put_32 (input_bfd, value, contents + rel->r_offset);
+ break;
+ }
+ }
+ }
+ else
+ relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
+ }
+ else
+ {
+ bfd_boolean warned, ignored;
+
+ RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
+ r_symndx, symtab_hdr, sym_hashes,
+ h, sec, relocation,
+ unresolved_reloc, warned, ignored);
+
+ sym_type = h->type;
+ }
+
+ if (sec != NULL && discarded_section (sec))
+ RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+ rel, 1, relend, howto, 0, contents);
+
+ if (info->relocatable)
+ {
+ /* This is a relocatable 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 (sym != NULL && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
+ {
+ if (globals->use_rel)
+ arm_add_to_rel (input_bfd, contents + rel->r_offset,
+ howto, (bfd_signed_vma) sec->output_offset);
+ else
+ rel->r_addend += sec->output_offset;
+ }
+ continue;
+ }
+
+ 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 (r_symndx != STN_UNDEF
+ && r_type != R_ARM_NONE
+ && (h == NULL
+ || h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak)
+ && IS_ARM_TLS_RELOC (r_type) != (sym_type == STT_TLS))
+ {
+ (*_bfd_error_handler)
+ ((sym_type == STT_TLS
+ ? _("%B(%A+0x%lx): %s used with TLS symbol %s")
+ : _("%B(%A+0x%lx): %s used with non-TLS symbol %s")),
+ input_bfd,
+ input_section,
+ (long) rel->r_offset,
+ howto->name,
+ name);
+ }
+
+ /* We call elf32_arm_final_link_relocate unless we're completely
+ done, i.e., the relaxation produced the final output we want,
+ and we won't let anybody mess with it. Also, we have to do
+ addend adjustments in case of a R_ARM_TLS_GOTDESC relocation
+ both in relaxed and non-relaxed cases. */
+ if ((elf32_arm_tls_transition (info, r_type, h) != (unsigned)r_type)
+ || (IS_ARM_TLS_GNU_RELOC (r_type)
+ && !((h ? elf32_arm_hash_entry (h)->tls_type :
+ elf32_arm_local_got_tls_type (input_bfd)[r_symndx])
+ & GOT_TLS_GDESC)))
+ {
+ r = elf32_arm_tls_relax (globals, input_bfd, input_section,
+ contents, rel, h == NULL);
+ /* This may have been marked unresolved because it came from
+ a shared library. But we've just dealt with that. */
+ unresolved_reloc = 0;
+ }
+ else
+ r = bfd_reloc_continue;
+
+ if (r == bfd_reloc_continue)
+ r = elf32_arm_final_link_relocate (howto, input_bfd, output_bfd,
+ input_section, contents, rel,
+ relocation, info, sec, name, sym_type,
+ (h ? h->target_internal
+ : ARM_SYM_BRANCH_TYPE (sym)), h,
+ &unresolved_reloc, &error_message);
+
+ /* Dynamic relocs are not propagated for SEC_DEBUGGING sections
+ because such sections are not SEC_ALLOC and thus ld.so will
+ not process them. */
+ if (unresolved_reloc
+ && !((input_section->flags & SEC_DEBUGGING) != 0
+ && h->def_dynamic)
+ && _bfd_elf_section_offset (output_bfd, info, input_section,
+ rel->r_offset) != (bfd_vma) -1)
+ {
+ (*_bfd_error_handler)
+ (_("%B(%A+0x%lx): unresolvable %s relocation against symbol `%s'"),
+ input_bfd,
+ input_section,
+ (long) rel->r_offset,
+ howto->name,
+ h->root.root.string);
+ return FALSE;
+ }
+
+ if (r != bfd_reloc_ok)
+ {
+ switch (r)
+ {
+ case bfd_reloc_overflow:
+ /* If the overflowing reloc was to an undefined symbol,
+ we have already printed one error message and there
+ is no point complaining again. */
+ if ((! h ||
+ h->root.type != bfd_link_hash_undefined)
+ && (!((*info->callbacks->reloc_overflow)
+ (info, (h ? &h->root : NULL), 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, TRUE)))
+ return FALSE;
+ break;
+
+ case bfd_reloc_outofrange:
+ error_message = _("out of range");
+ goto common_error;
+
+ case bfd_reloc_notsupported:
+ error_message = _("unsupported relocation");
+ goto common_error;
+
+ case bfd_reloc_dangerous:
+ /* error_message should already be set. */
+ goto common_error;
+
+ default:
+ error_message = _("unknown error");
+ /* Fall through. */
+
+ common_error:
+ BFD_ASSERT (error_message != NULL);
+ if (!((*info->callbacks->reloc_dangerous)
+ (info, error_message, input_bfd, input_section,
+ rel->r_offset)))
+ return FALSE;
+ break;
+ }
+ }
+ }
+
+ return TRUE;
+}
+
+/* Add a new unwind edit to the list described by HEAD, TAIL. If TINDEX is zero,
+ adds the edit to the start of the list. (The list must be built in order of
+ ascending TINDEX: the function's callers are primarily responsible for
+ maintaining that condition). */
+
+static void
+add_unwind_table_edit (arm_unwind_table_edit **head,
+ arm_unwind_table_edit **tail,
+ arm_unwind_edit_type type,
+ asection *linked_section,
+ unsigned int tindex)
+{
+ arm_unwind_table_edit *new_edit = (arm_unwind_table_edit *)
+ xmalloc (sizeof (arm_unwind_table_edit));
+
+ new_edit->type = type;
+ new_edit->linked_section = linked_section;
+ new_edit->index = tindex;
+
+ if (tindex > 0)
+ {
+ new_edit->next = NULL;
+
+ if (*tail)
+ (*tail)->next = new_edit;
+
+ (*tail) = new_edit;
+
+ if (!*head)
+ (*head) = new_edit;
+ }
+ else
+ {
+ new_edit->next = *head;
+
+ if (!*tail)
+ *tail = new_edit;
+
+ *head = new_edit;
+ }
+}
+
+static _arm_elf_section_data *get_arm_elf_section_data (asection *);
+
+/* Increase the size of EXIDX_SEC by ADJUST bytes. ADJUST mau be negative. */
+static void
+adjust_exidx_size(asection *exidx_sec, int adjust)
+{
+ asection *out_sec;
+
+ if (!exidx_sec->rawsize)
+ exidx_sec->rawsize = exidx_sec->size;
+
+ bfd_set_section_size (exidx_sec->owner, exidx_sec, exidx_sec->size + adjust);
+ out_sec = exidx_sec->output_section;
+ /* Adjust size of output section. */
+ bfd_set_section_size (out_sec->owner, out_sec, out_sec->size +adjust);
+}
+
+/* Insert an EXIDX_CANTUNWIND marker at the end of a section. */
+static void
+insert_cantunwind_after(asection *text_sec, asection *exidx_sec)
+{
+ struct _arm_elf_section_data *exidx_arm_data;
+
+ exidx_arm_data = get_arm_elf_section_data (exidx_sec);
+ add_unwind_table_edit (
+ &exidx_arm_data->u.exidx.unwind_edit_list,
+ &exidx_arm_data->u.exidx.unwind_edit_tail,
+ INSERT_EXIDX_CANTUNWIND_AT_END, text_sec, UINT_MAX);
+
+ adjust_exidx_size(exidx_sec, 8);
+}
+
+/* Scan .ARM.exidx tables, and create a list describing edits which should be
+ made to those tables, such that:
+
+ 1. Regions without unwind data are marked with EXIDX_CANTUNWIND entries.
+ 2. Duplicate entries are merged together (EXIDX_CANTUNWIND, or unwind
+ codes which have been inlined into the index).
+
+ If MERGE_EXIDX_ENTRIES is false, duplicate entries are not merged.
+
+ The edits are applied when the tables are written
+ (in elf32_arm_write_section). */
+
+bfd_boolean
+elf32_arm_fix_exidx_coverage (asection **text_section_order,
+ unsigned int num_text_sections,
+ struct bfd_link_info *info,
+ bfd_boolean merge_exidx_entries)
+{
+ bfd *inp;
+ unsigned int last_second_word = 0, i;
+ asection *last_exidx_sec = NULL;
+ asection *last_text_sec = NULL;
+ int last_unwind_type = -1;
+
+ /* Walk over all EXIDX sections, and create backlinks from the corrsponding
+ text sections. */
+ for (inp = info->input_bfds; inp != NULL; inp = inp->link.next)
+ {
+ asection *sec;
+
+ for (sec = inp->sections; sec != NULL; sec = sec->next)
+ {
+ struct bfd_elf_section_data *elf_sec = elf_section_data (sec);
+ Elf_Internal_Shdr *hdr = &elf_sec->this_hdr;
+
+ if (!hdr || hdr->sh_type != SHT_ARM_EXIDX)
+ continue;
+
+ if (elf_sec->linked_to)
+ {
+ Elf_Internal_Shdr *linked_hdr
+ = &elf_section_data (elf_sec->linked_to)->this_hdr;
+ struct _arm_elf_section_data *linked_sec_arm_data
+ = get_arm_elf_section_data (linked_hdr->bfd_section);
+
+ if (linked_sec_arm_data == NULL)
+ continue;
+
+ /* Link this .ARM.exidx section back from the text section it
+ describes. */
+ linked_sec_arm_data->u.text.arm_exidx_sec = sec;
+ }
+ }
+ }
+
+ /* Walk all text sections in order of increasing VMA. Eilminate duplicate
+ index table entries (EXIDX_CANTUNWIND and inlined unwind opcodes),
+ and add EXIDX_CANTUNWIND entries for sections with no unwind table data. */
+
+ for (i = 0; i < num_text_sections; i++)
+ {
+ asection *sec = text_section_order[i];
+ asection *exidx_sec;
+ struct _arm_elf_section_data *arm_data = get_arm_elf_section_data (sec);
+ struct _arm_elf_section_data *exidx_arm_data;
+ bfd_byte *contents = NULL;
+ int deleted_exidx_bytes = 0;
+ bfd_vma j;
+ arm_unwind_table_edit *unwind_edit_head = NULL;
+ arm_unwind_table_edit *unwind_edit_tail = NULL;
+ Elf_Internal_Shdr *hdr;
+ bfd *ibfd;
+
+ if (arm_data == NULL)
+ continue;
+
+ exidx_sec = arm_data->u.text.arm_exidx_sec;
+ if (exidx_sec == NULL)
+ {
+ /* Section has no unwind data. */
+ if (last_unwind_type == 0 || !last_exidx_sec)
+ continue;
+
+ /* Ignore zero sized sections. */
+ if (sec->size == 0)
+ continue;
+
+ insert_cantunwind_after(last_text_sec, last_exidx_sec);
+ last_unwind_type = 0;
+ continue;
+ }
+
+ /* Skip /DISCARD/ sections. */
+ if (bfd_is_abs_section (exidx_sec->output_section))
+ continue;
+
+ hdr = &elf_section_data (exidx_sec)->this_hdr;
+ if (hdr->sh_type != SHT_ARM_EXIDX)
+ continue;
+
+ exidx_arm_data = get_arm_elf_section_data (exidx_sec);
+ if (exidx_arm_data == NULL)
+ continue;
+
+ ibfd = exidx_sec->owner;
+
+ if (hdr->contents != NULL)
+ contents = hdr->contents;
+ else if (! bfd_malloc_and_get_section (ibfd, exidx_sec, &contents))
+ /* An error? */
+ continue;
+
+ for (j = 0; j < hdr->sh_size; j += 8)
+ {
+ unsigned int second_word = bfd_get_32 (ibfd, contents + j + 4);
+ int unwind_type;
+ int elide = 0;
+
+ /* An EXIDX_CANTUNWIND entry. */
+ if (second_word == 1)
+ {
+ if (last_unwind_type == 0)
+ elide = 1;
+ unwind_type = 0;
+ }
+ /* Inlined unwinding data. Merge if equal to previous. */
+ else if ((second_word & 0x80000000) != 0)
+ {
+ if (merge_exidx_entries
+ && last_second_word == second_word && last_unwind_type == 1)
+ elide = 1;
+ unwind_type = 1;
+ last_second_word = second_word;
+ }
+ /* Normal table entry. In theory we could merge these too,
+ but duplicate entries are likely to be much less common. */
+ else
+ unwind_type = 2;
+
+ if (elide)
+ {
+ add_unwind_table_edit (&unwind_edit_head, &unwind_edit_tail,
+ DELETE_EXIDX_ENTRY, NULL, j / 8);
+
+ deleted_exidx_bytes += 8;
+ }
+
+ last_unwind_type = unwind_type;
+ }
+
+ /* Free contents if we allocated it ourselves. */
+ if (contents != hdr->contents)
+ free (contents);
+
+ /* Record edits to be applied later (in elf32_arm_write_section). */
+ exidx_arm_data->u.exidx.unwind_edit_list = unwind_edit_head;
+ exidx_arm_data->u.exidx.unwind_edit_tail = unwind_edit_tail;
+
+ if (deleted_exidx_bytes > 0)
+ adjust_exidx_size(exidx_sec, -deleted_exidx_bytes);
+
+ last_exidx_sec = exidx_sec;
+ last_text_sec = sec;
+ }
+
+ /* Add terminating CANTUNWIND entry. */
+ if (last_exidx_sec && last_unwind_type != 0)
+ insert_cantunwind_after(last_text_sec, last_exidx_sec);
+
+ return TRUE;
+}
+
+static bfd_boolean
+elf32_arm_output_glue_section (struct bfd_link_info *info, bfd *obfd,
+ bfd *ibfd, const char *name)
+{
+ asection *sec, *osec;
+
+ sec = bfd_get_linker_section (ibfd, name);
+ if (sec == NULL || (sec->flags & SEC_EXCLUDE) != 0)
+ return TRUE;
+
+ osec = sec->output_section;
+ if (elf32_arm_write_section (obfd, info, sec, sec->contents))
+ return TRUE;
+
+ if (! bfd_set_section_contents (obfd, osec, sec->contents,
+ sec->output_offset, sec->size))
+ return FALSE;
+
+ return TRUE;
+}
+
+static bfd_boolean
+elf32_arm_final_link (bfd *abfd, struct bfd_link_info *info)
+{
+ struct elf32_arm_link_hash_table *globals = elf32_arm_hash_table (info);
+ asection *sec, *osec;
+
+ if (globals == NULL)
+ return FALSE;
+
+ /* Invoke the regular ELF backend linker to do all the work. */
+ if (!bfd_elf_final_link (abfd, info))
+ return FALSE;
+
+ /* Process stub sections (eg BE8 encoding, ...). */
+ struct elf32_arm_link_hash_table *htab = elf32_arm_hash_table (info);
+ int i;
+ for (i=0; i<htab->top_id; i++)
+ {
+ sec = htab->stub_group[i].stub_sec;
+ /* Only process it once, in its link_sec slot. */
+ if (sec && i == htab->stub_group[i].link_sec->id)
+ {
+ osec = sec->output_section;
+ elf32_arm_write_section (abfd, info, sec, sec->contents);
+ if (! bfd_set_section_contents (abfd, osec, sec->contents,
+ sec->output_offset, sec->size))
+ return FALSE;
+ }
+ }
+
+ /* Write out any glue sections now that we have created all the
+ stubs. */
+ if (globals->bfd_of_glue_owner != NULL)
+ {
+ if (! elf32_arm_output_glue_section (info, abfd,
+ globals->bfd_of_glue_owner,
+ ARM2THUMB_GLUE_SECTION_NAME))
+ return FALSE;
+
+ if (! elf32_arm_output_glue_section (info, abfd,
+ globals->bfd_of_glue_owner,
+ THUMB2ARM_GLUE_SECTION_NAME))
+ return FALSE;
+
+ if (! elf32_arm_output_glue_section (info, abfd,
+ globals->bfd_of_glue_owner,
+ VFP11_ERRATUM_VENEER_SECTION_NAME))
+ return FALSE;
+
+ if (! elf32_arm_output_glue_section (info, abfd,
+ globals->bfd_of_glue_owner,
+ ARM_BX_GLUE_SECTION_NAME))
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/* Return a best guess for the machine number based on the attributes. */
+
+static unsigned int
+bfd_arm_get_mach_from_attributes (bfd * abfd)
+{
+ int arch = bfd_elf_get_obj_attr_int (abfd, OBJ_ATTR_PROC, Tag_CPU_arch);
+
+ switch (arch)
+ {
+ case TAG_CPU_ARCH_V4: return bfd_mach_arm_4;
+ case TAG_CPU_ARCH_V4T: return bfd_mach_arm_4T;
+ case TAG_CPU_ARCH_V5T: return bfd_mach_arm_5T;
+
+ case TAG_CPU_ARCH_V5TE:
+ {
+ char * name;
+
+ BFD_ASSERT (Tag_CPU_name < NUM_KNOWN_OBJ_ATTRIBUTES);
+ name = elf_known_obj_attributes (abfd) [OBJ_ATTR_PROC][Tag_CPU_name].s;
+
+ if (name)
+ {
+ if (strcmp (name, "IWMMXT2") == 0)
+ return bfd_mach_arm_iWMMXt2;
+
+ if (strcmp (name, "IWMMXT") == 0)
+ return bfd_mach_arm_iWMMXt;
+
+ if (strcmp (name, "XSCALE") == 0)
+ {
+ int wmmx;
+
+ BFD_ASSERT (Tag_WMMX_arch < NUM_KNOWN_OBJ_ATTRIBUTES);
+ wmmx = elf_known_obj_attributes (abfd) [OBJ_ATTR_PROC][Tag_WMMX_arch].i;
+ switch (wmmx)
+ {
+ case 1: return bfd_mach_arm_iWMMXt;
+ case 2: return bfd_mach_arm_iWMMXt2;
+ default: return bfd_mach_arm_XScale;
+ }
+ }
+ }
+
+ return bfd_mach_arm_5TE;
+ }
+
+ default:
+ return bfd_mach_arm_unknown;
+ }
+}
+
+/* Set the right machine number. */
+
+static bfd_boolean
+elf32_arm_object_p (bfd *abfd)
+{
+ unsigned int mach;
+
+ mach = bfd_arm_get_mach_from_notes (abfd, ARM_NOTE_SECTION);
+
+ if (mach == bfd_mach_arm_unknown)
+ {
+ if (elf_elfheader (abfd)->e_flags & EF_ARM_MAVERICK_FLOAT)
+ mach = bfd_mach_arm_ep9312;
+ else
+ mach = bfd_arm_get_mach_from_attributes (abfd);
+ }
+
+ bfd_default_set_arch_mach (abfd, bfd_arch_arm, mach);
+ return TRUE;
+}
+
+/* Function to keep ARM specific flags in the ELF header. */
+
+static bfd_boolean
+elf32_arm_set_private_flags (bfd *abfd, flagword flags)
+{
+ if (elf_flags_init (abfd)
+ && elf_elfheader (abfd)->e_flags != flags)
+ {
+ if (EF_ARM_EABI_VERSION (flags) == EF_ARM_EABI_UNKNOWN)
+ {
+ if (flags & EF_ARM_INTERWORK)
+ (*_bfd_error_handler)
+ (_("Warning: Not setting interworking flag of %B since it has already been specified as non-interworking"),
+ abfd);
+ else
+ _bfd_error_handler
+ (_("Warning: Clearing the interworking flag of %B due to outside request"),
+ 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 bfd_boolean
+elf32_arm_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
+{
+ flagword in_flags;
+ flagword out_flags;
+
+ if (! is_arm_elf (ibfd) || ! is_arm_elf (obfd))
+ return TRUE;
+
+ in_flags = elf_elfheader (ibfd)->e_flags;
+ out_flags = elf_elfheader (obfd)->e_flags;
+
+ if (elf_flags_init (obfd)
+ && EF_ARM_EABI_VERSION (out_flags) == EF_ARM_EABI_UNKNOWN
+ && in_flags != out_flags)
+ {
+ /* Cannot mix APCS26 and APCS32 code. */
+ if ((in_flags & EF_ARM_APCS_26) != (out_flags & EF_ARM_APCS_26))
+ return FALSE;
+
+ /* Cannot mix float APCS and non-float APCS code. */
+ if ((in_flags & EF_ARM_APCS_FLOAT) != (out_flags & EF_ARM_APCS_FLOAT))
+ return FALSE;
+
+ /* If the src and dest have different interworking flags
+ then turn off the interworking bit. */
+ if ((in_flags & EF_ARM_INTERWORK) != (out_flags & EF_ARM_INTERWORK))
+ {
+ if (out_flags & EF_ARM_INTERWORK)
+ _bfd_error_handler
+ (_("Warning: Clearing the interworking flag of %B because non-interworking code in %B has been linked with it"),
+ obfd, ibfd);
+
+ in_flags &= ~EF_ARM_INTERWORK;
+ }
+
+ /* Likewise for PIC, though don't warn for this case. */
+ if ((in_flags & EF_ARM_PIC) != (out_flags & EF_ARM_PIC))
+ in_flags &= ~EF_ARM_PIC;
+ }
+
+ elf_elfheader (obfd)->e_flags = in_flags;
+ elf_flags_init (obfd) = TRUE;
+
+ return _bfd_elf_copy_private_bfd_data (ibfd, obfd);
+}
+
+/* Values for Tag_ABI_PCS_R9_use. */
+enum
+{
+ AEABI_R9_V6,
+ AEABI_R9_SB,
+ AEABI_R9_TLS,
+ AEABI_R9_unused
+};
+
+/* Values for Tag_ABI_PCS_RW_data. */
+enum
+{
+ AEABI_PCS_RW_data_absolute,
+ AEABI_PCS_RW_data_PCrel,
+ AEABI_PCS_RW_data_SBrel,
+ AEABI_PCS_RW_data_unused
+};
+
+/* Values for Tag_ABI_enum_size. */
+enum
+{
+ AEABI_enum_unused,
+ AEABI_enum_short,
+ AEABI_enum_wide,
+ AEABI_enum_forced_wide
+};
+
+/* Determine whether an object attribute tag takes an integer, a
+ string or both. */
+
+static int
+elf32_arm_obj_attrs_arg_type (int tag)
+{
+ if (tag == Tag_compatibility)
+ return ATTR_TYPE_FLAG_INT_VAL | ATTR_TYPE_FLAG_STR_VAL;
+ else if (tag == Tag_nodefaults)
+ return ATTR_TYPE_FLAG_INT_VAL | ATTR_TYPE_FLAG_NO_DEFAULT;
+ else if (tag == Tag_CPU_raw_name || tag == Tag_CPU_name)
+ return ATTR_TYPE_FLAG_STR_VAL;
+ else if (tag < 32)
+ return ATTR_TYPE_FLAG_INT_VAL;
+ else
+ return (tag & 1) != 0 ? ATTR_TYPE_FLAG_STR_VAL : ATTR_TYPE_FLAG_INT_VAL;
+}
+
+/* The ABI defines that Tag_conformance should be emitted first, and that
+ Tag_nodefaults should be second (if either is defined). This sets those
+ two positions, and bumps up the position of all the remaining tags to
+ compensate. */
+static int
+elf32_arm_obj_attrs_order (int num)
+{
+ if (num == LEAST_KNOWN_OBJ_ATTRIBUTE)
+ return Tag_conformance;
+ if (num == LEAST_KNOWN_OBJ_ATTRIBUTE + 1)
+ return Tag_nodefaults;
+ if ((num - 2) < Tag_nodefaults)
+ return num - 2;
+ if ((num - 1) < Tag_conformance)
+ return num - 1;
+ return num;
+}
+
+/* Attribute numbers >=64 (mod 128) can be safely ignored. */
+static bfd_boolean
+elf32_arm_obj_attrs_handle_unknown (bfd *abfd, int tag)
+{
+ if ((tag & 127) < 64)
+ {
+ _bfd_error_handler
+ (_("%B: Unknown mandatory EABI object attribute %d"),
+ abfd, tag);
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+ else
+ {
+ _bfd_error_handler
+ (_("Warning: %B: Unknown EABI object attribute %d"),
+ abfd, tag);
+ return TRUE;
+ }
+}
+
+/* Read the architecture from the Tag_also_compatible_with attribute, if any.
+ Returns -1 if no architecture could be read. */
+
+static int
+get_secondary_compatible_arch (bfd *abfd)
+{
+ obj_attribute *attr =
+ &elf_known_obj_attributes_proc (abfd)[Tag_also_compatible_with];
+
+ /* Note: the tag and its argument below are uleb128 values, though
+ currently-defined values fit in one byte for each. */
+ if (attr->s
+ && attr->s[0] == Tag_CPU_arch
+ && (attr->s[1] & 128) != 128
+ && attr->s[2] == 0)
+ return attr->s[1];
+
+ /* This tag is "safely ignorable", so don't complain if it looks funny. */
+ return -1;
+}
+
+/* Set, or unset, the architecture of the Tag_also_compatible_with attribute.
+ The tag is removed if ARCH is -1. */
+
+static void
+set_secondary_compatible_arch (bfd *abfd, int arch)
+{
+ obj_attribute *attr =
+ &elf_known_obj_attributes_proc (abfd)[Tag_also_compatible_with];
+
+ if (arch == -1)
+ {
+ attr->s = NULL;
+ return;
+ }
+
+ /* Note: the tag and its argument below are uleb128 values, though
+ currently-defined values fit in one byte for each. */
+ if (!attr->s)
+ attr->s = (char *) bfd_alloc (abfd, 3);
+ attr->s[0] = Tag_CPU_arch;
+ attr->s[1] = arch;
+ attr->s[2] = '\0';
+}
+
+/* Combine two values for Tag_CPU_arch, taking secondary compatibility tags
+ into account. */
+
+static int
+tag_cpu_arch_combine (bfd *ibfd, int oldtag, int *secondary_compat_out,
+ int newtag, int secondary_compat)
+{
+#define T(X) TAG_CPU_ARCH_##X
+ int tagl, tagh, result;
+ const int v6t2[] =
+ {
+ T(V6T2), /* PRE_V4. */
+ T(V6T2), /* V4. */
+ T(V6T2), /* V4T. */
+ T(V6T2), /* V5T. */
+ T(V6T2), /* V5TE. */
+ T(V6T2), /* V5TEJ. */
+ T(V6T2), /* V6. */
+ T(V7), /* V6KZ. */
+ T(V6T2) /* V6T2. */
+ };
+ const int v6k[] =
+ {
+ T(V6K), /* PRE_V4. */
+ T(V6K), /* V4. */
+ T(V6K), /* V4T. */
+ T(V6K), /* V5T. */
+ T(V6K), /* V5TE. */
+ T(V6K), /* V5TEJ. */
+ T(V6K), /* V6. */
+ T(V6KZ), /* V6KZ. */
+ T(V7), /* V6T2. */
+ T(V6K) /* V6K. */
+ };
+ const int v7[] =
+ {
+ T(V7), /* PRE_V4. */
+ T(V7), /* V4. */
+ T(V7), /* V4T. */
+ T(V7), /* V5T. */
+ T(V7), /* V5TE. */
+ T(V7), /* V5TEJ. */
+ T(V7), /* V6. */
+ T(V7), /* V6KZ. */
+ T(V7), /* V6T2. */
+ T(V7), /* V6K. */
+ T(V7) /* V7. */
+ };
+ const int v6_m[] =
+ {
+ -1, /* PRE_V4. */
+ -1, /* V4. */
+ T(V6K), /* V4T. */
+ T(V6K), /* V5T. */
+ T(V6K), /* V5TE. */
+ T(V6K), /* V5TEJ. */
+ T(V6K), /* V6. */
+ T(V6KZ), /* V6KZ. */
+ T(V7), /* V6T2. */
+ T(V6K), /* V6K. */
+ T(V7), /* V7. */
+ T(V6_M) /* V6_M. */
+ };
+ const int v6s_m[] =
+ {
+ -1, /* PRE_V4. */
+ -1, /* V4. */
+ T(V6K), /* V4T. */
+ T(V6K), /* V5T. */
+ T(V6K), /* V5TE. */
+ T(V6K), /* V5TEJ. */
+ T(V6K), /* V6. */
+ T(V6KZ), /* V6KZ. */
+ T(V7), /* V6T2. */
+ T(V6K), /* V6K. */
+ T(V7), /* V7. */
+ T(V6S_M), /* V6_M. */
+ T(V6S_M) /* V6S_M. */
+ };
+ const int v7e_m[] =
+ {
+ -1, /* PRE_V4. */
+ -1, /* V4. */
+ T(V7E_M), /* V4T. */
+ T(V7E_M), /* V5T. */
+ T(V7E_M), /* V5TE. */
+ T(V7E_M), /* V5TEJ. */
+ T(V7E_M), /* V6. */
+ T(V7E_M), /* V6KZ. */
+ T(V7E_M), /* V6T2. */
+ T(V7E_M), /* V6K. */
+ T(V7E_M), /* V7. */
+ T(V7E_M), /* V6_M. */
+ T(V7E_M), /* V6S_M. */
+ T(V7E_M) /* V7E_M. */
+ };
+ const int v8[] =
+ {
+ T(V8), /* PRE_V4. */
+ T(V8), /* V4. */
+ T(V8), /* V4T. */
+ T(V8), /* V5T. */
+ T(V8), /* V5TE. */
+ T(V8), /* V5TEJ. */
+ T(V8), /* V6. */
+ T(V8), /* V6KZ. */
+ T(V8), /* V6T2. */
+ T(V8), /* V6K. */
+ T(V8), /* V7. */
+ T(V8), /* V6_M. */
+ T(V8), /* V6S_M. */
+ T(V8), /* V7E_M. */
+ T(V8) /* V8. */
+ };
+ const int v4t_plus_v6_m[] =
+ {
+ -1, /* PRE_V4. */
+ -1, /* V4. */
+ T(V4T), /* V4T. */
+ T(V5T), /* V5T. */
+ T(V5TE), /* V5TE. */
+ T(V5TEJ), /* V5TEJ. */
+ T(V6), /* V6. */
+ T(V6KZ), /* V6KZ. */
+ T(V6T2), /* V6T2. */
+ T(V6K), /* V6K. */
+ T(V7), /* V7. */
+ T(V6_M), /* V6_M. */
+ T(V6S_M), /* V6S_M. */
+ T(V7E_M), /* V7E_M. */
+ T(V8), /* V8. */
+ T(V4T_PLUS_V6_M) /* V4T plus V6_M. */
+ };
+ const int *comb[] =
+ {
+ v6t2,
+ v6k,
+ v7,
+ v6_m,
+ v6s_m,
+ v7e_m,
+ v8,
+ /* Pseudo-architecture. */
+ v4t_plus_v6_m
+ };
+
+ /* Check we've not got a higher architecture than we know about. */
+
+ if (oldtag > MAX_TAG_CPU_ARCH || newtag > MAX_TAG_CPU_ARCH)
+ {
+ _bfd_error_handler (_("error: %B: Unknown CPU architecture"), ibfd);
+ return -1;
+ }
+
+ /* Override old tag if we have a Tag_also_compatible_with on the output. */
+
+ if ((oldtag == T(V6_M) && *secondary_compat_out == T(V4T))
+ || (oldtag == T(V4T) && *secondary_compat_out == T(V6_M)))
+ oldtag = T(V4T_PLUS_V6_M);
+
+ /* And override the new tag if we have a Tag_also_compatible_with on the
+ input. */
+
+ if ((newtag == T(V6_M) && secondary_compat == T(V4T))
+ || (newtag == T(V4T) && secondary_compat == T(V6_M)))
+ newtag = T(V4T_PLUS_V6_M);
+
+ tagl = (oldtag < newtag) ? oldtag : newtag;
+ result = tagh = (oldtag > newtag) ? oldtag : newtag;
+
+ /* Architectures before V6KZ add features monotonically. */
+ if (tagh <= TAG_CPU_ARCH_V6KZ)
+ return result;
+
+ result = comb[tagh - T(V6T2)][tagl];
+
+ /* Use Tag_CPU_arch == V4T and Tag_also_compatible_with (Tag_CPU_arch V6_M)
+ as the canonical version. */
+ if (result == T(V4T_PLUS_V6_M))
+ {
+ result = T(V4T);
+ *secondary_compat_out = T(V6_M);
+ }
+ else
+ *secondary_compat_out = -1;
+
+ if (result == -1)
+ {
+ _bfd_error_handler (_("error: %B: Conflicting CPU architectures %d/%d"),
+ ibfd, oldtag, newtag);
+ return -1;
+ }
+
+ return result;
+#undef T
+}
+
+/* Query attributes object to see if integer divide instructions may be
+ present in an object. */
+static bfd_boolean
+elf32_arm_attributes_accept_div (const obj_attribute *attr)
+{
+ int arch = attr[Tag_CPU_arch].i;
+ int profile = attr[Tag_CPU_arch_profile].i;
+
+ switch (attr[Tag_DIV_use].i)
+ {
+ case 0:
+ /* Integer divide allowed if instruction contained in archetecture. */
+ if (arch == TAG_CPU_ARCH_V7 && (profile == 'R' || profile == 'M'))
+ return TRUE;
+ else if (arch >= TAG_CPU_ARCH_V7E_M)
+ return TRUE;
+ else
+ return FALSE;
+
+ case 1:
+ /* Integer divide explicitly prohibited. */
+ return FALSE;
+
+ default:
+ /* Unrecognised case - treat as allowing divide everywhere. */
+ case 2:
+ /* Integer divide allowed in ARM state. */
+ return TRUE;
+ }
+}
+
+/* Query attributes object to see if integer divide instructions are
+ forbidden to be in the object. This is not the inverse of
+ elf32_arm_attributes_accept_div. */
+static bfd_boolean
+elf32_arm_attributes_forbid_div (const obj_attribute *attr)
+{
+ return attr[Tag_DIV_use].i == 1;
+}
+
+/* Merge EABI object attributes from IBFD into OBFD. Raise an error if there
+ are conflicting attributes. */
+
+static bfd_boolean
+elf32_arm_merge_eabi_attributes (bfd *ibfd, bfd *obfd)
+{
+ obj_attribute *in_attr;
+ obj_attribute *out_attr;
+ /* Some tags have 0 = don't care, 1 = strong requirement,
+ 2 = weak requirement. */
+ static const int order_021[3] = {0, 2, 1};
+ int i;
+ bfd_boolean result = TRUE;
+
+ /* Skip the linker stubs file. This preserves previous behavior
+ of accepting unknown attributes in the first input file - but
+ is that a bug? */
+ if (ibfd->flags & BFD_LINKER_CREATED)
+ return TRUE;
+
+ if (!elf_known_obj_attributes_proc (obfd)[0].i)
+ {
+ /* This is the first object. Copy the attributes. */
+ _bfd_elf_copy_obj_attributes (ibfd, obfd);
+
+ out_attr = elf_known_obj_attributes_proc (obfd);
+
+ /* Use the Tag_null value to indicate the attributes have been
+ initialized. */
+ out_attr[0].i = 1;
+
+ /* We do not output objects with Tag_MPextension_use_legacy - we move
+ the attribute's value to Tag_MPextension_use. */
+ if (out_attr[Tag_MPextension_use_legacy].i != 0)
+ {
+ if (out_attr[Tag_MPextension_use].i != 0
+ && out_attr[Tag_MPextension_use_legacy].i
+ != out_attr[Tag_MPextension_use].i)
+ {
+ _bfd_error_handler
+ (_("Error: %B has both the current and legacy "
+ "Tag_MPextension_use attributes"), ibfd);
+ result = FALSE;
+ }
+
+ out_attr[Tag_MPextension_use] =
+ out_attr[Tag_MPextension_use_legacy];
+ out_attr[Tag_MPextension_use_legacy].type = 0;
+ out_attr[Tag_MPextension_use_legacy].i = 0;
+ }
+
+ return result;
+ }
+
+ in_attr = elf_known_obj_attributes_proc (ibfd);
+ out_attr = elf_known_obj_attributes_proc (obfd);
+ /* This needs to happen before Tag_ABI_FP_number_model is merged. */
+ if (in_attr[Tag_ABI_VFP_args].i != out_attr[Tag_ABI_VFP_args].i)
+ {
+ /* Ignore mismatches if the object doesn't use floating point. */
+ if (out_attr[Tag_ABI_FP_number_model].i == 0)
+ out_attr[Tag_ABI_VFP_args].i = in_attr[Tag_ABI_VFP_args].i;
+ else if (in_attr[Tag_ABI_FP_number_model].i != 0)
+ {
+ _bfd_error_handler
+ (_("error: %B uses VFP register arguments, %B does not"),
+ in_attr[Tag_ABI_VFP_args].i ? ibfd : obfd,
+ in_attr[Tag_ABI_VFP_args].i ? obfd : ibfd);
+ result = FALSE;
+ }
+ }
+
+ for (i = LEAST_KNOWN_OBJ_ATTRIBUTE; i < NUM_KNOWN_OBJ_ATTRIBUTES; i++)
+ {
+ /* Merge this attribute with existing attributes. */
+ switch (i)
+ {
+ case Tag_CPU_raw_name:
+ case Tag_CPU_name:
+ /* These are merged after Tag_CPU_arch. */
+ break;
+
+ case Tag_ABI_optimization_goals:
+ case Tag_ABI_FP_optimization_goals:
+ /* Use the first value seen. */
+ break;
+
+ case Tag_CPU_arch:
+ {
+ int secondary_compat = -1, secondary_compat_out = -1;
+ unsigned int saved_out_attr = out_attr[i].i;
+ int arch_attr;
+ static const char *name_table[] =
+ {
+ /* These aren't real CPU names, but we can't guess
+ that from the architecture version alone. */
+ "Pre v4",
+ "ARM v4",
+ "ARM v4T",
+ "ARM v5T",
+ "ARM v5TE",
+ "ARM v5TEJ",
+ "ARM v6",
+ "ARM v6KZ",
+ "ARM v6T2",
+ "ARM v6K",
+ "ARM v7",
+ "ARM v6-M",
+ "ARM v6S-M",
+ "ARM v8"
+ };
+
+ /* Merge Tag_CPU_arch and Tag_also_compatible_with. */
+ secondary_compat = get_secondary_compatible_arch (ibfd);
+ secondary_compat_out = get_secondary_compatible_arch (obfd);
+ arch_attr = tag_cpu_arch_combine (ibfd, out_attr[i].i,
+ &secondary_compat_out,
+ in_attr[i].i,
+ secondary_compat);
+
+ /* Return with error if failed to merge. */
+ if (arch_attr == -1)
+ return FALSE;
+
+ out_attr[i].i = arch_attr;
+
+ set_secondary_compatible_arch (obfd, secondary_compat_out);
+
+ /* Merge Tag_CPU_name and Tag_CPU_raw_name. */
+ if (out_attr[i].i == saved_out_attr)
+ ; /* Leave the names alone. */
+ else if (out_attr[i].i == in_attr[i].i)
+ {
+ /* The output architecture has been changed to match the
+ input architecture. Use the input names. */
+ out_attr[Tag_CPU_name].s = in_attr[Tag_CPU_name].s
+ ? _bfd_elf_attr_strdup (obfd, in_attr[Tag_CPU_name].s)
+ : NULL;
+ out_attr[Tag_CPU_raw_name].s = in_attr[Tag_CPU_raw_name].s
+ ? _bfd_elf_attr_strdup (obfd, in_attr[Tag_CPU_raw_name].s)
+ : NULL;
+ }
+ else
+ {
+ out_attr[Tag_CPU_name].s = NULL;
+ out_attr[Tag_CPU_raw_name].s = NULL;
+ }
+
+ /* If we still don't have a value for Tag_CPU_name,
+ make one up now. Tag_CPU_raw_name remains blank. */
+ if (out_attr[Tag_CPU_name].s == NULL
+ && out_attr[i].i < ARRAY_SIZE (name_table))
+ out_attr[Tag_CPU_name].s =
+ _bfd_elf_attr_strdup (obfd, name_table[out_attr[i].i]);
+ }
+ break;
+
+ case Tag_ARM_ISA_use:
+ case Tag_THUMB_ISA_use:
+ case Tag_WMMX_arch:
+ case Tag_Advanced_SIMD_arch:
+ /* ??? Do Advanced_SIMD (NEON) and WMMX conflict? */
+ case Tag_ABI_FP_rounding:
+ case Tag_ABI_FP_exceptions:
+ case Tag_ABI_FP_user_exceptions:
+ case Tag_ABI_FP_number_model:
+ case Tag_FP_HP_extension:
+ case Tag_CPU_unaligned_access:
+ case Tag_T2EE_use:
+ case Tag_MPextension_use:
+ /* Use the largest value specified. */
+ if (in_attr[i].i > out_attr[i].i)
+ out_attr[i].i = in_attr[i].i;
+ break;
+
+ case Tag_ABI_align_preserved:
+ case Tag_ABI_PCS_RO_data:
+ /* Use the smallest value specified. */
+ if (in_attr[i].i < out_attr[i].i)
+ out_attr[i].i = in_attr[i].i;
+ break;
+
+ case Tag_ABI_align_needed:
+ if ((in_attr[i].i > 0 || out_attr[i].i > 0)
+ && (in_attr[Tag_ABI_align_preserved].i == 0
+ || out_attr[Tag_ABI_align_preserved].i == 0))
+ {
+ /* This error message should be enabled once all non-conformant
+ binaries in the toolchain have had the attributes set
+ properly.
+ _bfd_error_handler
+ (_("error: %B: 8-byte data alignment conflicts with %B"),
+ obfd, ibfd);
+ result = FALSE; */
+ }
+ /* Fall through. */
+ case Tag_ABI_FP_denormal:
+ case Tag_ABI_PCS_GOT_use:
+ /* Use the "greatest" from the sequence 0, 2, 1, or the largest
+ value if greater than 2 (for future-proofing). */
+ if ((in_attr[i].i > 2 && in_attr[i].i > out_attr[i].i)
+ || (in_attr[i].i <= 2 && out_attr[i].i <= 2
+ && order_021[in_attr[i].i] > order_021[out_attr[i].i]))
+ out_attr[i].i = in_attr[i].i;
+ break;
+
+ case Tag_Virtualization_use:
+ /* The virtualization tag effectively stores two bits of
+ information: the intended use of TrustZone (in bit 0), and the
+ intended use of Virtualization (in bit 1). */
+ if (out_attr[i].i == 0)
+ out_attr[i].i = in_attr[i].i;
+ else if (in_attr[i].i != 0
+ && in_attr[i].i != out_attr[i].i)
+ {
+ if (in_attr[i].i <= 3 && out_attr[i].i <= 3)
+ out_attr[i].i = 3;
+ else
+ {
+ _bfd_error_handler
+ (_("error: %B: unable to merge virtualization attributes "
+ "with %B"),
+ obfd, ibfd);
+ result = FALSE;
+ }
+ }
+ break;
+
+ case Tag_CPU_arch_profile:
+ if (out_attr[i].i != in_attr[i].i)
+ {
+ /* 0 will merge with anything.
+ 'A' and 'S' merge to 'A'.
+ 'R' and 'S' merge to 'R'.
+ 'M' and 'A|R|S' is an error. */
+ if (out_attr[i].i == 0
+ || (out_attr[i].i == 'S'
+ && (in_attr[i].i == 'A' || in_attr[i].i == 'R')))
+ out_attr[i].i = in_attr[i].i;
+ else if (in_attr[i].i == 0
+ || (in_attr[i].i == 'S'
+ && (out_attr[i].i == 'A' || out_attr[i].i == 'R')))
+ ; /* Do nothing. */
+ else
+ {
+ _bfd_error_handler
+ (_("error: %B: Conflicting architecture profiles %c/%c"),
+ ibfd,
+ in_attr[i].i ? in_attr[i].i : '0',
+ out_attr[i].i ? out_attr[i].i : '0');
+ result = FALSE;
+ }
+ }
+ break;
+ case Tag_FP_arch:
+ {
+ /* Tag_ABI_HardFP_use is handled along with Tag_FP_arch since
+ the meaning of Tag_ABI_HardFP_use depends on Tag_FP_arch
+ when it's 0. It might mean absence of FP hardware if
+ Tag_FP_arch is zero, otherwise it is effectively SP + DP. */
+
+#define VFP_VERSION_COUNT 8
+ static const struct
+ {
+ int ver;
+ int regs;
+ } vfp_versions[VFP_VERSION_COUNT] =
+ {
+ {0, 0},
+ {1, 16},
+ {2, 16},
+ {3, 32},
+ {3, 16},
+ {4, 32},
+ {4, 16},
+ {8, 32}
+ };
+ int ver;
+ int regs;
+ int newval;
+
+ /* If the output has no requirement about FP hardware,
+ follow the requirement of the input. */
+ if (out_attr[i].i == 0)
+ {
+ BFD_ASSERT (out_attr[Tag_ABI_HardFP_use].i == 0);
+ out_attr[i].i = in_attr[i].i;
+ out_attr[Tag_ABI_HardFP_use].i
+ = in_attr[Tag_ABI_HardFP_use].i;
+ break;
+ }
+ /* If the input has no requirement about FP hardware, do
+ nothing. */
+ else if (in_attr[i].i == 0)
+ {
+ BFD_ASSERT (in_attr[Tag_ABI_HardFP_use].i == 0);
+ break;
+ }
+
+ /* Both the input and the output have nonzero Tag_FP_arch.
+ So Tag_ABI_HardFP_use is (SP & DP) when it's zero. */
+
+ /* If both the input and the output have zero Tag_ABI_HardFP_use,
+ do nothing. */
+ if (in_attr[Tag_ABI_HardFP_use].i == 0
+ && out_attr[Tag_ABI_HardFP_use].i == 0)
+ ;
+ /* If the input and the output have different Tag_ABI_HardFP_use,
+ the combination of them is 3 (SP & DP). */
+ else if (in_attr[Tag_ABI_HardFP_use].i
+ != out_attr[Tag_ABI_HardFP_use].i)
+ out_attr[Tag_ABI_HardFP_use].i = 3;
+
+ /* Now we can handle Tag_FP_arch. */
+
+ /* Values of VFP_VERSION_COUNT or more aren't defined, so just
+ pick the biggest. */
+ if (in_attr[i].i >= VFP_VERSION_COUNT
+ && in_attr[i].i > out_attr[i].i)
+ {
+ out_attr[i] = in_attr[i];
+ break;
+ }
+ /* The output uses the superset of input features
+ (ISA version) and registers. */
+ ver = vfp_versions[in_attr[i].i].ver;
+ if (ver < vfp_versions[out_attr[i].i].ver)
+ ver = vfp_versions[out_attr[i].i].ver;
+ regs = vfp_versions[in_attr[i].i].regs;
+ if (regs < vfp_versions[out_attr[i].i].regs)
+ regs = vfp_versions[out_attr[i].i].regs;
+ /* This assumes all possible supersets are also a valid
+ options. */
+ for (newval = VFP_VERSION_COUNT - 1; newval > 0; newval--)
+ {
+ if (regs == vfp_versions[newval].regs
+ && ver == vfp_versions[newval].ver)
+ break;
+ }
+ out_attr[i].i = newval;
+ }
+ break;
+ case Tag_PCS_config:
+ if (out_attr[i].i == 0)
+ out_attr[i].i = in_attr[i].i;
+ else if (in_attr[i].i != 0 && out_attr[i].i != in_attr[i].i)
+ {
+ /* It's sometimes ok to mix different configs, so this is only
+ a warning. */
+ _bfd_error_handler
+ (_("Warning: %B: Conflicting platform configuration"), ibfd);
+ }
+ break;
+ case Tag_ABI_PCS_R9_use:
+ if (in_attr[i].i != out_attr[i].i
+ && out_attr[i].i != AEABI_R9_unused
+ && in_attr[i].i != AEABI_R9_unused)
+ {
+ _bfd_error_handler
+ (_("error: %B: Conflicting use of R9"), ibfd);
+ result = FALSE;
+ }
+ if (out_attr[i].i == AEABI_R9_unused)
+ out_attr[i].i = in_attr[i].i;
+ break;
+ case Tag_ABI_PCS_RW_data:
+ if (in_attr[i].i == AEABI_PCS_RW_data_SBrel
+ && out_attr[Tag_ABI_PCS_R9_use].i != AEABI_R9_SB
+ && out_attr[Tag_ABI_PCS_R9_use].i != AEABI_R9_unused)
+ {
+ _bfd_error_handler
+ (_("error: %B: SB relative addressing conflicts with use of R9"),
+ ibfd);
+ result = FALSE;
+ }
+ /* Use the smallest value specified. */
+ if (in_attr[i].i < out_attr[i].i)
+ out_attr[i].i = in_attr[i].i;
+ break;
+ case Tag_ABI_PCS_wchar_t:
+ if (out_attr[i].i && in_attr[i].i && out_attr[i].i != in_attr[i].i
+ && !elf_arm_tdata (obfd)->no_wchar_size_warning)
+ {
+ _bfd_error_handler
+ (_("warning: %B uses %u-byte wchar_t yet the output is to use %u-byte wchar_t; use of wchar_t values across objects may fail"),
+ ibfd, in_attr[i].i, out_attr[i].i);
+ }
+ else if (in_attr[i].i && !out_attr[i].i)
+ out_attr[i].i = in_attr[i].i;
+ break;
+ case Tag_ABI_enum_size:
+ if (in_attr[i].i != AEABI_enum_unused)
+ {
+ if (out_attr[i].i == AEABI_enum_unused
+ || out_attr[i].i == AEABI_enum_forced_wide)
+ {
+ /* The existing object is compatible with anything.
+ Use whatever requirements the new object has. */
+ out_attr[i].i = in_attr[i].i;
+ }
+ else if (in_attr[i].i != AEABI_enum_forced_wide
+ && out_attr[i].i != in_attr[i].i
+ && !elf_arm_tdata (obfd)->no_enum_size_warning)
+ {
+ static const char *aeabi_enum_names[] =
+ { "", "variable-size", "32-bit", "" };
+ const char *in_name =
+ in_attr[i].i < ARRAY_SIZE(aeabi_enum_names)
+ ? aeabi_enum_names[in_attr[i].i]
+ : "<unknown>";
+ const char *out_name =
+ out_attr[i].i < ARRAY_SIZE(aeabi_enum_names)
+ ? aeabi_enum_names[out_attr[i].i]
+ : "<unknown>";
+ _bfd_error_handler
+ (_("warning: %B uses %s enums yet the output is to use %s enums; use of enum values across objects may fail"),
+ ibfd, in_name, out_name);
+ }
+ }
+ break;
+ case Tag_ABI_VFP_args:
+ /* Aready done. */
+ break;
+ case Tag_ABI_WMMX_args:
+ if (in_attr[i].i != out_attr[i].i)
+ {
+ _bfd_error_handler
+ (_("error: %B uses iWMMXt register arguments, %B does not"),
+ ibfd, obfd);
+ result = FALSE;
+ }
+ break;
+ case Tag_compatibility:
+ /* Merged in target-independent code. */
+ break;
+ case Tag_ABI_HardFP_use:
+ /* This is handled along with Tag_FP_arch. */
+ break;
+ case Tag_ABI_FP_16bit_format:
+ if (in_attr[i].i != 0 && out_attr[i].i != 0)
+ {
+ if (in_attr[i].i != out_attr[i].i)
+ {
+ _bfd_error_handler
+ (_("error: fp16 format mismatch between %B and %B"),
+ ibfd, obfd);
+ result = FALSE;
+ }
+ }
+ if (in_attr[i].i != 0)
+ out_attr[i].i = in_attr[i].i;
+ break;
+
+ case Tag_DIV_use:
+ /* A value of zero on input means that the divide instruction may
+ be used if available in the base architecture as specified via
+ Tag_CPU_arch and Tag_CPU_arch_profile. A value of 1 means that
+ the user did not want divide instructions. A value of 2
+ explicitly means that divide instructions were allowed in ARM
+ and Thumb state. */
+ if (in_attr[i].i == out_attr[i].i)
+ /* Do nothing. */ ;
+ else if (elf32_arm_attributes_forbid_div (in_attr)
+ && !elf32_arm_attributes_accept_div (out_attr))
+ out_attr[i].i = 1;
+ else if (elf32_arm_attributes_forbid_div (out_attr)
+ && elf32_arm_attributes_accept_div (in_attr))
+ out_attr[i].i = in_attr[i].i;
+ else if (in_attr[i].i == 2)
+ out_attr[i].i = in_attr[i].i;
+ break;
+
+ case Tag_MPextension_use_legacy:
+ /* We don't output objects with Tag_MPextension_use_legacy - we
+ move the value to Tag_MPextension_use. */
+ if (in_attr[i].i != 0 && in_attr[Tag_MPextension_use].i != 0)
+ {
+ if (in_attr[Tag_MPextension_use].i != in_attr[i].i)
+ {
+ _bfd_error_handler
+ (_("%B has has both the current and legacy "
+ "Tag_MPextension_use attributes"),
+ ibfd);
+ result = FALSE;
+ }
+ }
+
+ if (in_attr[i].i > out_attr[Tag_MPextension_use].i)
+ out_attr[Tag_MPextension_use] = in_attr[i];
+
+ break;
+
+ case Tag_nodefaults:
+ /* This tag is set if it exists, but the value is unused (and is
+ typically zero). We don't actually need to do anything here -
+ the merge happens automatically when the type flags are merged
+ below. */
+ break;
+ case Tag_also_compatible_with:
+ /* Already done in Tag_CPU_arch. */
+ break;
+ case Tag_conformance:
+ /* Keep the attribute if it matches. Throw it away otherwise.
+ No attribute means no claim to conform. */
+ if (!in_attr[i].s || !out_attr[i].s
+ || strcmp (in_attr[i].s, out_attr[i].s) != 0)
+ out_attr[i].s = NULL;
+ break;
+
+ default:
+ result
+ = result && _bfd_elf_merge_unknown_attribute_low (ibfd, obfd, i);
+ }
+
+ /* If out_attr was copied from in_attr then it won't have a type yet. */
+ if (in_attr[i].type && !out_attr[i].type)
+ out_attr[i].type = in_attr[i].type;
+ }
+
+ /* Merge Tag_compatibility attributes and any common GNU ones. */
+ if (!_bfd_elf_merge_object_attributes (ibfd, obfd))
+ return FALSE;
+
+ /* Check for any attributes not known on ARM. */
+ result &= _bfd_elf_merge_unknown_attribute_list (ibfd, obfd);
+
+ return result;
+}
+
+
+/* Return TRUE if the two EABI versions are incompatible. */
+
+static bfd_boolean
+elf32_arm_versions_compatible (unsigned iver, unsigned over)
+{
+ /* v4 and v5 are the same spec before and after it was released,
+ so allow mixing them. */
+ if ((iver == EF_ARM_EABI_VER4 && over == EF_ARM_EABI_VER5)
+ || (iver == EF_ARM_EABI_VER5 && over == EF_ARM_EABI_VER4))
+ return TRUE;
+
+ return (iver == over);
+}
+
+/* Merge backend specific data from an object file to the output
+ object file when linking. */
+
+static bfd_boolean
+elf32_arm_merge_private_bfd_data (bfd * ibfd, bfd * obfd);
+
+/* Display the flags field. */
+
+static bfd_boolean
+elf32_arm_print_private_bfd_data (bfd *abfd, void * ptr)
+{
+ FILE * file = (FILE *) ptr;
+ unsigned long flags;
+
+ BFD_ASSERT (abfd != NULL && ptr != NULL);
+
+ /* Print normal ELF private data. */
+ _bfd_elf_print_private_bfd_data (abfd, ptr);
+
+ flags = elf_elfheader (abfd)->e_flags;
+ /* 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);
+
+ switch (EF_ARM_EABI_VERSION (flags))
+ {
+ case EF_ARM_EABI_UNKNOWN:
+ /* The following flag bits are GNU extensions and not part of the
+ official ARM ELF extended ABI. Hence they are only decoded if
+ the EABI version is not set. */
+ if (flags & EF_ARM_INTERWORK)
+ fprintf (file, _(" [interworking enabled]"));
+
+ if (flags & EF_ARM_APCS_26)
+ fprintf (file, " [APCS-26]");
+ else
+ fprintf (file, " [APCS-32]");
+
+ if (flags & EF_ARM_VFP_FLOAT)
+ fprintf (file, _(" [VFP float format]"));
+ else if (flags & EF_ARM_MAVERICK_FLOAT)
+ fprintf (file, _(" [Maverick float format]"));
+ else
+ fprintf (file, _(" [FPA float format]"));
+
+ if (flags & EF_ARM_APCS_FLOAT)
+ fprintf (file, _(" [floats passed in float registers]"));
+
+ if (flags & EF_ARM_PIC)
+ fprintf (file, _(" [position independent]"));
+
+ if (flags & EF_ARM_NEW_ABI)
+ fprintf (file, _(" [new ABI]"));
+
+ if (flags & EF_ARM_OLD_ABI)
+ fprintf (file, _(" [old ABI]"));
+
+ if (flags & EF_ARM_SOFT_FLOAT)
+ fprintf (file, _(" [software FP]"));
+
+ flags &= ~(EF_ARM_INTERWORK | EF_ARM_APCS_26 | EF_ARM_APCS_FLOAT
+ | EF_ARM_PIC | EF_ARM_NEW_ABI | EF_ARM_OLD_ABI
+ | EF_ARM_SOFT_FLOAT | EF_ARM_VFP_FLOAT
+ | EF_ARM_MAVERICK_FLOAT);
+ break;
+
+ case EF_ARM_EABI_VER1:
+ fprintf (file, _(" [Version1 EABI]"));
+
+ if (flags & EF_ARM_SYMSARESORTED)
+ fprintf (file, _(" [sorted symbol table]"));
+ else
+ fprintf (file, _(" [unsorted symbol table]"));
+
+ flags &= ~ EF_ARM_SYMSARESORTED;
+ break;
+
+ case EF_ARM_EABI_VER2:
+ fprintf (file, _(" [Version2 EABI]"));
+
+ if (flags & EF_ARM_SYMSARESORTED)
+ fprintf (file, _(" [sorted symbol table]"));
+ else
+ fprintf (file, _(" [unsorted symbol table]"));
+
+ if (flags & EF_ARM_DYNSYMSUSESEGIDX)
+ fprintf (file, _(" [dynamic symbols use segment index]"));
+
+ if (flags & EF_ARM_MAPSYMSFIRST)
+ fprintf (file, _(" [mapping symbols precede others]"));
+
+ flags &= ~(EF_ARM_SYMSARESORTED | EF_ARM_DYNSYMSUSESEGIDX
+ | EF_ARM_MAPSYMSFIRST);
+ break;
+
+ case EF_ARM_EABI_VER3:
+ fprintf (file, _(" [Version3 EABI]"));
+ break;
+
+ case EF_ARM_EABI_VER4:
+ fprintf (file, _(" [Version4 EABI]"));
+ goto eabi;
+
+ case EF_ARM_EABI_VER5:
+ fprintf (file, _(" [Version5 EABI]"));
+
+ if (flags & EF_ARM_ABI_FLOAT_SOFT)
+ fprintf (file, _(" [soft-float ABI]"));
+
+ if (flags & EF_ARM_ABI_FLOAT_HARD)
+ fprintf (file, _(" [hard-float ABI]"));
+
+ flags &= ~(EF_ARM_ABI_FLOAT_SOFT | EF_ARM_ABI_FLOAT_HARD);
+
+ eabi:
+ if (flags & EF_ARM_BE8)
+ fprintf (file, _(" [BE8]"));
+
+ if (flags & EF_ARM_LE8)
+ fprintf (file, _(" [LE8]"));
+
+ flags &= ~(EF_ARM_LE8 | EF_ARM_BE8);
+ break;
+
+ default:
+ fprintf (file, _(" <EABI version unrecognised>"));
+ break;
+ }
+
+ flags &= ~ EF_ARM_EABIMASK;
+
+ if (flags & EF_ARM_RELEXEC)
+ fprintf (file, _(" [relocatable executable]"));
+
+ if (flags & EF_ARM_HASENTRY)
+ fprintf (file, _(" [has entry point]"));
+
+ flags &= ~ (EF_ARM_RELEXEC | EF_ARM_HASENTRY);
+
+ if (flags)
+ fprintf (file, _("<Unrecognised flag bits set>"));
+
+ fputc ('\n', file);
+
+ return TRUE;
+}
+
+static int
+elf32_arm_get_symbol_type (Elf_Internal_Sym * elf_sym, int type)
+{
+ switch (ELF_ST_TYPE (elf_sym->st_info))
+ {
+ case STT_ARM_TFUNC:
+ return ELF_ST_TYPE (elf_sym->st_info);
+
+ case STT_ARM_16BIT:
+ /* If the symbol is not an object, return the STT_ARM_16BIT flag.
+ This allows us to distinguish between data used by Thumb instructions
+ and non-data (which is probably code) inside Thumb regions of an
+ executable. */
+ if (type != STT_OBJECT && type != STT_TLS)
+ return ELF_ST_TYPE (elf_sym->st_info);
+ break;
+
+ default:
+ break;
+ }
+
+ return type;
+}
+
+static asection *
+elf32_arm_gc_mark_hook (asection *sec,
+ 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:
+ return NULL;
+ }
+
+ return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
+}
+
+/* Update the got entry reference counts for the section being removed. */
+
+static bfd_boolean
+elf32_arm_gc_sweep_hook (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;
+ struct elf32_arm_link_hash_table * globals;
+
+ if (info->relocatable)
+ return TRUE;
+
+ globals = elf32_arm_hash_table (info);
+ if (globals == NULL)
+ return FALSE;
+
+ elf_section_data (sec)->local_dynrel = NULL;
+
+ symtab_hdr = & elf_symtab_hdr (abfd);
+ sym_hashes = elf_sym_hashes (abfd);
+ local_got_refcounts = elf_local_got_refcounts (abfd);
+
+ check_use_blx (globals);
+
+ relend = relocs + sec->reloc_count;
+ for (rel = relocs; rel < relend; rel++)
+ {
+ unsigned long r_symndx;
+ struct elf_link_hash_entry *h = NULL;
+ struct elf32_arm_link_hash_entry *eh;
+ int r_type;
+ bfd_boolean call_reloc_p;
+ bfd_boolean may_become_dynamic_p;
+ bfd_boolean may_need_local_target_p;
+ union gotplt_union *root_plt;
+ struct arm_plt_info *arm_plt;
+
+ r_symndx = ELF32_R_SYM (rel->r_info);
+ if (r_symndx >= symtab_hdr->sh_info)
+ {
+ 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;
+ }
+ eh = (struct elf32_arm_link_hash_entry *) h;
+
+ call_reloc_p = FALSE;
+ may_become_dynamic_p = FALSE;
+ may_need_local_target_p = FALSE;
+
+ r_type = ELF32_R_TYPE (rel->r_info);
+ r_type = arm_real_reloc_type (globals, r_type);
+ switch (r_type)
+ {
+ case R_ARM_GOT32:
+ case R_ARM_GOT_PREL:
+ case R_ARM_TLS_GD32:
+ case R_ARM_TLS_IE32:
+ if (h != NULL)
+ {
+ if (h->got.refcount > 0)
+ h->got.refcount -= 1;
+ }
+ else if (local_got_refcounts != NULL)
+ {
+ if (local_got_refcounts[r_symndx] > 0)
+ local_got_refcounts[r_symndx] -= 1;
+ }
+ break;
+
+ case R_ARM_TLS_LDM32:
+ globals->tls_ldm_got.refcount -= 1;
+ break;
+
+ case R_ARM_PC24:
+ case R_ARM_PLT32:
+ case R_ARM_CALL:
+ case R_ARM_JUMP24:
+ case R_ARM_PREL31:
+ case R_ARM_THM_CALL:
+ case R_ARM_THM_JUMP24:
+ case R_ARM_THM_JUMP19:
+ call_reloc_p = TRUE;
+ may_need_local_target_p = TRUE;
+ break;
+
+ case R_ARM_ABS12:
+ if (!globals->vxworks_p)
+ {
+ may_need_local_target_p = TRUE;
+ break;
+ }
+ /* Fall through. */
+ case R_ARM_ABS32:
+ case R_ARM_ABS32_NOI:
+ case R_ARM_REL32:
+ case R_ARM_REL32_NOI:
+ case R_ARM_MOVW_ABS_NC:
+ case R_ARM_MOVT_ABS:
+ case R_ARM_MOVW_PREL_NC:
+ case R_ARM_MOVT_PREL:
+ case R_ARM_THM_MOVW_ABS_NC:
+ case R_ARM_THM_MOVT_ABS:
+ case R_ARM_THM_MOVW_PREL_NC:
+ case R_ARM_THM_MOVT_PREL:
+ /* Should the interworking branches be here also? */
+ if ((info->shared || globals->root.is_relocatable_executable)
+ && (sec->flags & SEC_ALLOC) != 0)
+ {
+ if (h == NULL
+ && elf32_arm_howto_from_type (r_type)->pc_relative)
+ {
+ call_reloc_p = TRUE;
+ may_need_local_target_p = TRUE;
+ }
+ else
+ may_become_dynamic_p = TRUE;
+ }
+ else
+ may_need_local_target_p = TRUE;
+ break;
+
+ default:
+ break;
+ }
+
+ if (may_need_local_target_p
+ && elf32_arm_get_plt_info (abfd, eh, r_symndx, &root_plt, &arm_plt))
+ {
+ /* If PLT refcount book-keeping is wrong and too low, we'll
+ see a zero value (going to -1) for the root PLT reference
+ count. */
+ if (root_plt->refcount >= 0)
+ {
+ BFD_ASSERT (root_plt->refcount != 0);
+ root_plt->refcount -= 1;
+ }
+ else
+ /* A value of -1 means the symbol has become local, forced
+ or seeing a hidden definition. Any other negative value
+ is an error. */
+ BFD_ASSERT (root_plt->refcount == -1);
+
+ if (!call_reloc_p)
+ arm_plt->noncall_refcount--;
+
+ if (r_type == R_ARM_THM_CALL)
+ arm_plt->maybe_thumb_refcount--;
+
+ if (r_type == R_ARM_THM_JUMP24
+ || r_type == R_ARM_THM_JUMP19)
+ arm_plt->thumb_refcount--;
+ }
+
+ if (may_become_dynamic_p)
+ {
+ struct elf_dyn_relocs **pp;
+ struct elf_dyn_relocs *p;
+
+ if (h != NULL)
+ pp = &(eh->dyn_relocs);
+ else
+ {
+ Elf_Internal_Sym *isym;
+
+ isym = bfd_sym_from_r_symndx (&globals->sym_cache,
+ abfd, r_symndx);
+ if (isym == NULL)
+ return FALSE;
+ pp = elf32_arm_get_local_dynreloc_list (abfd, r_symndx, isym);
+ if (pp == NULL)
+ return FALSE;
+ }
+ for (; (p = *pp) != NULL; pp = &p->next)
+ if (p->sec == sec)
+ {
+ /* Everything must go for SEC. */
+ *pp = p->next;
+ break;
+ }
+ }
+ }
+
+ return TRUE;
+}
+
+/* Look through the relocs for a section during the first phase. */
+
+static bfd_boolean
+elf32_arm_check_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;
+ const Elf_Internal_Rela *rel;
+ const Elf_Internal_Rela *rel_end;
+ bfd *dynobj;
+ asection *sreloc;
+ struct elf32_arm_link_hash_table *htab;
+ bfd_boolean call_reloc_p;
+ bfd_boolean may_become_dynamic_p;
+ bfd_boolean may_need_local_target_p;
+ unsigned long nsyms;
+
+ if (info->relocatable)
+ return TRUE;
+
+ BFD_ASSERT (is_arm_elf (abfd));
+
+ htab = elf32_arm_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ sreloc = NULL;
+
+ /* Create dynamic sections for relocatable executables so that we can
+ copy relocations. */
+ if (htab->root.is_relocatable_executable
+ && ! htab->root.dynamic_sections_created)
+ {
+ if (! _bfd_elf_link_create_dynamic_sections (abfd, info))
+ return FALSE;
+ }
+
+ if (htab->root.dynobj == NULL)
+ htab->root.dynobj = abfd;
+ if (!create_ifunc_sections (info))
+ return FALSE;
+
+ dynobj = htab->root.dynobj;
+
+ symtab_hdr = & elf_symtab_hdr (abfd);
+ sym_hashes = elf_sym_hashes (abfd);
+ nsyms = NUM_SHDR_ENTRIES (symtab_hdr);
+
+ rel_end = relocs + sec->reloc_count;
+ for (rel = relocs; rel < rel_end; rel++)
+ {
+ Elf_Internal_Sym *isym;
+ struct elf_link_hash_entry *h;
+ struct elf32_arm_link_hash_entry *eh;
+ unsigned long r_symndx;
+ int r_type;
+
+ r_symndx = ELF32_R_SYM (rel->r_info);
+ r_type = ELF32_R_TYPE (rel->r_info);
+ r_type = arm_real_reloc_type (htab, r_type);
+
+ if (r_symndx >= nsyms
+ /* PR 9934: It is possible to have relocations that do not
+ refer to symbols, thus it is also possible to have an
+ object file containing relocations but no symbol table. */
+ && (r_symndx > STN_UNDEF || nsyms > 0))
+ {
+ (*_bfd_error_handler) (_("%B: bad symbol index: %d"), abfd,
+ r_symndx);
+ return FALSE;
+ }
+
+ h = NULL;
+ isym = NULL;
+ if (nsyms > 0)
+ {
+ if (r_symndx < symtab_hdr->sh_info)
+ {
+ /* A local symbol. */
+ isym = bfd_sym_from_r_symndx (&htab->sym_cache,
+ abfd, r_symndx);
+ if (isym == NULL)
+ return FALSE;
+ }
+ 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;
+
+ /* PR15323, ref flags aren't set for references in the
+ same object. */
+ h->root.non_ir_ref = 1;
+ }
+ }
+
+ eh = (struct elf32_arm_link_hash_entry *) h;
+
+ call_reloc_p = FALSE;
+ may_become_dynamic_p = FALSE;
+ may_need_local_target_p = FALSE;
+
+ /* Could be done earlier, if h were already available. */
+ r_type = elf32_arm_tls_transition (info, r_type, h);
+ switch (r_type)
+ {
+ case R_ARM_GOT32:
+ case R_ARM_GOT_PREL:
+ case R_ARM_TLS_GD32:
+ case R_ARM_TLS_IE32:
+ case R_ARM_TLS_GOTDESC:
+ case R_ARM_TLS_DESCSEQ:
+ case R_ARM_THM_TLS_DESCSEQ:
+ case R_ARM_TLS_CALL:
+ case R_ARM_THM_TLS_CALL:
+ /* This symbol requires a global offset table entry. */
+ {
+ int tls_type, old_tls_type;
+
+ switch (r_type)
+ {
+ case R_ARM_TLS_GD32: tls_type = GOT_TLS_GD; break;
+
+ case R_ARM_TLS_IE32: tls_type = GOT_TLS_IE; break;
+
+ case R_ARM_TLS_GOTDESC:
+ case R_ARM_TLS_CALL: case R_ARM_THM_TLS_CALL:
+ case R_ARM_TLS_DESCSEQ: case R_ARM_THM_TLS_DESCSEQ:
+ tls_type = GOT_TLS_GDESC; break;
+
+ default: tls_type = GOT_NORMAL; break;
+ }
+
+ if (!info->executable && (tls_type & GOT_TLS_IE))
+ info->flags |= DF_STATIC_TLS;
+
+ if (h != NULL)
+ {
+ h->got.refcount++;
+ old_tls_type = elf32_arm_hash_entry (h)->tls_type;
+ }
+ else
+ {
+ /* This is a global offset table entry for a local symbol. */
+ if (!elf32_arm_allocate_local_sym_info (abfd))
+ return FALSE;
+ elf_local_got_refcounts (abfd)[r_symndx] += 1;
+ old_tls_type = elf32_arm_local_got_tls_type (abfd) [r_symndx];
+ }
+
+ /* If a variable is accessed with both tls methods, two
+ slots may be created. */
+ if (GOT_TLS_GD_ANY_P (old_tls_type)
+ && GOT_TLS_GD_ANY_P (tls_type))
+ tls_type |= old_tls_type;
+
+ /* We will already have issued an error message if there
+ is a TLS/non-TLS mismatch, based on the symbol
+ type. So just combine any TLS types needed. */
+ if (old_tls_type != GOT_UNKNOWN && old_tls_type != GOT_NORMAL
+ && tls_type != GOT_NORMAL)
+ tls_type |= old_tls_type;
+
+ /* If the symbol is accessed in both IE and GDESC
+ method, we're able to relax. Turn off the GDESC flag,
+ without messing up with any other kind of tls types
+ that may be involved. */
+ if ((tls_type & GOT_TLS_IE) && (tls_type & GOT_TLS_GDESC))
+ tls_type &= ~GOT_TLS_GDESC;
+
+ if (old_tls_type != tls_type)
+ {
+ if (h != NULL)
+ elf32_arm_hash_entry (h)->tls_type = tls_type;
+ else
+ elf32_arm_local_got_tls_type (abfd) [r_symndx] = tls_type;
+ }
+ }
+ /* Fall through. */
+
+ case R_ARM_TLS_LDM32:
+ if (r_type == R_ARM_TLS_LDM32)
+ htab->tls_ldm_got.refcount++;
+ /* Fall through. */
+
+ case R_ARM_GOTOFF32:
+ case R_ARM_GOTPC:
+ if (htab->root.sgot == NULL
+ && !create_got_section (htab->root.dynobj, info))
+ return FALSE;
+ break;
+
+ case R_ARM_PC24:
+ case R_ARM_PLT32:
+ case R_ARM_CALL:
+ case R_ARM_JUMP24:
+ case R_ARM_PREL31:
+ case R_ARM_THM_CALL:
+ case R_ARM_THM_JUMP24:
+ case R_ARM_THM_JUMP19:
+ call_reloc_p = TRUE;
+ may_need_local_target_p = TRUE;
+ break;
+
+ case R_ARM_ABS12:
+ /* VxWorks uses dynamic R_ARM_ABS12 relocations for
+ ldr __GOTT_INDEX__ offsets. */
+ if (!htab->vxworks_p)
+ {
+ may_need_local_target_p = TRUE;
+ break;
+ }
+ /* Fall through. */
+
+ case R_ARM_MOVW_ABS_NC:
+ case R_ARM_MOVT_ABS:
+ case R_ARM_THM_MOVW_ABS_NC:
+ case R_ARM_THM_MOVT_ABS:
+ if (info->shared)
+ {
+ (*_bfd_error_handler)
+ (_("%B: relocation %s against `%s' can not be used when making a shared object; recompile with -fPIC"),
+ abfd, elf32_arm_howto_table_1[r_type].name,
+ (h) ? h->root.root.string : "a local symbol");
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+
+ /* Fall through. */
+ case R_ARM_ABS32:
+ case R_ARM_ABS32_NOI:
+ if (h != NULL && info->executable)
+ {
+ h->pointer_equality_needed = 1;
+ }
+ /* Fall through. */
+ case R_ARM_REL32:
+ case R_ARM_REL32_NOI:
+ case R_ARM_MOVW_PREL_NC:
+ case R_ARM_MOVT_PREL:
+ case R_ARM_THM_MOVW_PREL_NC:
+ case R_ARM_THM_MOVT_PREL:
+
+ /* Should the interworking branches be listed here? */
+ if ((info->shared || htab->root.is_relocatable_executable)
+ && (sec->flags & SEC_ALLOC) != 0)
+ {
+ if (h == NULL
+ && elf32_arm_howto_from_type (r_type)->pc_relative)
+ {
+ /* In shared libraries and relocatable executables,
+ we treat local relative references as calls;
+ see the related SYMBOL_CALLS_LOCAL code in
+ allocate_dynrelocs. */
+ call_reloc_p = TRUE;
+ may_need_local_target_p = TRUE;
+ }
+ else
+ /* We are creating a shared library or relocatable
+ executable, and this is a reloc against a global symbol,
+ or a non-PC-relative reloc against a local symbol.
+ We may need to copy the reloc into the output. */
+ may_become_dynamic_p = TRUE;
+ }
+ else
+ may_need_local_target_p = TRUE;
+ break;
+
+ /* This relocation describes the C++ object vtable hierarchy.
+ Reconstruct it for later use during GC. */
+ case R_ARM_GNU_VTINHERIT:
+ if (!bfd_elf_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:
+ BFD_ASSERT (h != NULL);
+ if (h != NULL
+ && !bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_offset))
+ return FALSE;
+ break;
+ }
+
+ if (h != NULL)
+ {
+ if (call_reloc_p)
+ /* We may need a .plt entry if the function this reloc
+ refers to is in a different object, regardless of the
+ symbol's type. We can't tell for sure yet, because
+ something later might force the symbol local. */
+ h->needs_plt = 1;
+ else if (may_need_local_target_p)
+ /* If this reloc is in a read-only section, we might
+ need a copy reloc. We can't check reliably at this
+ stage whether the section is read-only, as input
+ sections have not yet been mapped to output sections.
+ Tentatively set the flag for now, and correct in
+ adjust_dynamic_symbol. */
+ h->non_got_ref = 1;
+ }
+
+ if (may_need_local_target_p
+ && (h != NULL || ELF32_ST_TYPE (isym->st_info) == STT_GNU_IFUNC))
+ {
+ union gotplt_union *root_plt;
+ struct arm_plt_info *arm_plt;
+ struct arm_local_iplt_info *local_iplt;
+
+ if (h != NULL)
+ {
+ root_plt = &h->plt;
+ arm_plt = &eh->plt;
+ }
+ else
+ {
+ local_iplt = elf32_arm_create_local_iplt (abfd, r_symndx);
+ if (local_iplt == NULL)
+ return FALSE;
+ root_plt = &local_iplt->root;
+ arm_plt = &local_iplt->arm;
+ }
+
+ /* If the symbol is a function that doesn't bind locally,
+ this relocation will need a PLT entry. */
+ if (root_plt->refcount != -1)
+ root_plt->refcount += 1;
+
+ if (!call_reloc_p)
+ arm_plt->noncall_refcount++;
+
+ /* It's too early to use htab->use_blx here, so we have to
+ record possible blx references separately from
+ relocs that definitely need a thumb stub. */
+
+ if (r_type == R_ARM_THM_CALL)
+ arm_plt->maybe_thumb_refcount += 1;
+
+ if (r_type == R_ARM_THM_JUMP24
+ || r_type == R_ARM_THM_JUMP19)
+ arm_plt->thumb_refcount += 1;
+ }
+
+ if (may_become_dynamic_p)
+ {
+ struct elf_dyn_relocs *p, **head;
+
+ /* Create a reloc section in dynobj. */
+ if (sreloc == NULL)
+ {
+ sreloc = _bfd_elf_make_dynamic_reloc_section
+ (sec, dynobj, 2, abfd, ! htab->use_rel);
+
+ if (sreloc == NULL)
+ return FALSE;
+
+ /* BPABI objects never have dynamic relocations mapped. */
+ if (htab->symbian_p)
+ {
+ flagword flags;
+
+ flags = bfd_get_section_flags (dynobj, sreloc);
+ flags &= ~(SEC_LOAD | SEC_ALLOC);
+ bfd_set_section_flags (dynobj, sreloc, flags);
+ }
+ }
+
+ /* If this is a global symbol, count the number of
+ relocations we need for this symbol. */
+ if (h != NULL)
+ head = &((struct elf32_arm_link_hash_entry *) h)->dyn_relocs;
+ else
+ {
+ head = elf32_arm_get_local_dynreloc_list (abfd, r_symndx, isym);
+ if (head == NULL)
+ return FALSE;
+ }
+
+ p = *head;
+ if (p == NULL || p->sec != sec)
+ {
+ bfd_size_type amt = sizeof *p;
+
+ p = (struct elf_dyn_relocs *) bfd_alloc (htab->root.dynobj, amt);
+ if (p == NULL)
+ return FALSE;
+ p->next = *head;
+ *head = p;
+ p->sec = sec;
+ p->count = 0;
+ p->pc_count = 0;
+ }
+
+ if (elf32_arm_howto_from_type (r_type)->pc_relative)
+ p->pc_count += 1;
+ p->count += 1;
+ }
+ }
+
+ return TRUE;
+}
+
+/* Unwinding tables are not referenced directly. This pass marks them as
+ required if the corresponding code section is marked. */
+
+static bfd_boolean
+elf32_arm_gc_mark_extra_sections (struct bfd_link_info *info,
+ elf_gc_mark_hook_fn gc_mark_hook)
+{
+ bfd *sub;
+ Elf_Internal_Shdr **elf_shdrp;
+ bfd_boolean again;
+
+ _bfd_elf_gc_mark_extra_sections (info, gc_mark_hook);
+
+ /* Marking EH data may cause additional code sections to be marked,
+ requiring multiple passes. */
+ again = TRUE;
+ while (again)
+ {
+ again = FALSE;
+ for (sub = info->input_bfds; sub != NULL; sub = sub->link.next)
+ {
+ asection *o;
+
+ if (! is_arm_elf (sub))
+ continue;
+
+ elf_shdrp = elf_elfsections (sub);
+ for (o = sub->sections; o != NULL; o = o->next)
+ {
+ Elf_Internal_Shdr *hdr;
+
+ hdr = &elf_section_data (o)->this_hdr;
+ if (hdr->sh_type == SHT_ARM_EXIDX
+ && hdr->sh_link
+ && hdr->sh_link < elf_numsections (sub)
+ && !o->gc_mark
+ && elf_shdrp[hdr->sh_link]->bfd_section->gc_mark)
+ {
+ again = TRUE;
+ if (!_bfd_elf_gc_mark (info, o, gc_mark_hook))
+ return FALSE;
+ }
+ }
+ }
+ }
+
+ return TRUE;
+}
+
+/* Treat mapping symbols as special target symbols. */
+
+static bfd_boolean
+elf32_arm_is_target_special_symbol (bfd * abfd ATTRIBUTE_UNUSED, asymbol * sym)
+{
+ return bfd_is_arm_special_symbol_name (sym->name,
+ BFD_ARM_SPECIAL_SYM_TYPE_ANY);
+}
+
+/* This is a copy of elf_find_function() from elf.c except that
+ ARM mapping symbols are ignored when looking for function names
+ and STT_ARM_TFUNC is considered to a function type. */
+
+static bfd_boolean
+arm_elf_find_function (bfd * abfd ATTRIBUTE_UNUSED,
+ asymbol ** symbols,
+ asection * section,
+ bfd_vma offset,
+ const char ** filename_ptr,
+ const char ** functionname_ptr)
+{
+ const char * filename = NULL;
+ asymbol * func = NULL;
+ bfd_vma low_func = 0;
+ asymbol ** p;
+
+ for (p = symbols; *p != NULL; p++)
+ {
+ elf_symbol_type *q;
+
+ q = (elf_symbol_type *) *p;
+
+ switch (ELF_ST_TYPE (q->internal_elf_sym.st_info))
+ {
+ default:
+ break;
+ case STT_FILE:
+ filename = bfd_asymbol_name (&q->symbol);
+ break;
+ case STT_FUNC:
+ case STT_ARM_TFUNC:
+ case STT_NOTYPE:
+ /* Skip mapping symbols. */
+ if ((q->symbol.flags & BSF_LOCAL)
+ && bfd_is_arm_special_symbol_name (q->symbol.name,
+ BFD_ARM_SPECIAL_SYM_TYPE_ANY))
+ continue;
+ /* Fall through. */
+ if (bfd_get_section (&q->symbol) == section
+ && q->symbol.value >= low_func
+ && q->symbol.value <= offset)
+ {
+ func = (asymbol *) q;
+ low_func = q->symbol.value;
+ }
+ break;
+ }
+ }
+
+ if (func == NULL)
+ return FALSE;
+
+ if (filename_ptr)
+ *filename_ptr = filename;
+ if (functionname_ptr)
+ *functionname_ptr = bfd_asymbol_name (func);
+
+ 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 uses arm_elf_find_function. */
+
+static bfd_boolean
+elf32_arm_find_nearest_line (bfd * abfd,
+ asymbol ** symbols,
+ asection * section,
+ bfd_vma offset,
+ const char ** filename_ptr,
+ const char ** functionname_ptr,
+ unsigned int * line_ptr,
+ unsigned int * discriminator_ptr)
+{
+ bfd_boolean found = FALSE;
+
+ if (_bfd_dwarf2_find_nearest_line (abfd, symbols, NULL, section, offset,
+ filename_ptr, functionname_ptr,
+ line_ptr, discriminator_ptr,
+ dwarf_debug_sections, 0,
+ & elf_tdata (abfd)->dwarf2_find_line_info))
+ {
+ if (!*functionname_ptr)
+ arm_elf_find_function (abfd, symbols, section, offset,
+ *filename_ptr ? NULL : filename_ptr,
+ functionname_ptr);
+
+ return TRUE;
+ }
+
+ /* Skip _bfd_dwarf1_find_nearest_line since no known ARM toolchain
+ uses DWARF1. */
+
+ 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 && (*functionname_ptr || *line_ptr))
+ return TRUE;
+
+ if (symbols == NULL)
+ return FALSE;
+
+ if (! arm_elf_find_function (abfd, symbols, section, offset,
+ filename_ptr, functionname_ptr))
+ return FALSE;
+
+ *line_ptr = 0;
+ return TRUE;
+}
+
+static bfd_boolean
+elf32_arm_find_inliner_info (bfd * abfd,
+ const char ** filename_ptr,
+ const char ** functionname_ptr,
+ unsigned int * line_ptr)
+{
+ bfd_boolean found;
+ found = _bfd_dwarf2_find_inliner_info (abfd, filename_ptr,
+ functionname_ptr, line_ptr,
+ & elf_tdata (abfd)->dwarf2_find_line_info);
+ return found;
+}
+
+/* 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 bfd_boolean
+elf32_arm_adjust_dynamic_symbol (struct bfd_link_info * info,
+ struct elf_link_hash_entry * h)
+{
+ bfd * dynobj;
+ asection * s;
+ struct elf32_arm_link_hash_entry * eh;
+ struct elf32_arm_link_hash_table *globals;
+
+ globals = elf32_arm_hash_table (info);
+ if (globals == NULL)
+ return FALSE;
+
+ dynobj = elf_hash_table (info)->dynobj;
+
+ /* Make sure we know what is going on here. */
+ BFD_ASSERT (dynobj != NULL
+ && (h->needs_plt
+ || h->type == STT_GNU_IFUNC
+ || h->u.weakdef != NULL
+ || (h->def_dynamic
+ && h->ref_regular
+ && !h->def_regular)));
+
+ eh = (struct elf32_arm_link_hash_entry *) h;
+
+ /* 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->type == STT_GNU_IFUNC || h->needs_plt)
+ {
+ /* Calls to STT_GNU_IFUNC symbols always use a PLT, even if the
+ symbol binds locally. */
+ if (h->plt.refcount <= 0
+ || (h->type != STT_GNU_IFUNC
+ && (SYMBOL_CALLS_LOCAL (info, h)
+ || (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
+ && h->root.type == bfd_link_hash_undefweak))))
+ {
+ /* 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, or if all references were garbage collected. In
+ such a case, we don't actually need to build a procedure
+ linkage table, and we can just do a PC24 reloc instead. */
+ h->plt.offset = (bfd_vma) -1;
+ eh->plt.thumb_refcount = 0;
+ eh->plt.maybe_thumb_refcount = 0;
+ eh->plt.noncall_refcount = 0;
+ h->needs_plt = 0;
+ }
+
+ return TRUE;
+ }
+ else
+ {
+ /* It's possible that we incorrectly decided a .plt reloc was
+ needed for an R_ARM_PC24 or similar reloc to a non-function sym
+ in check_relocs. We can't decide accurately between function
+ and non-function syms in check-relocs; Objects loaded later in
+ the link may change h->type. So fix it now. */
+ h->plt.offset = (bfd_vma) -1;
+ eh->plt.thumb_refcount = 0;
+ eh->plt.maybe_thumb_refcount = 0;
+ eh->plt.noncall_refcount = 0;
+ }
+
+ /* 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->u.weakdef != NULL)
+ {
+ BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
+ || h->u.weakdef->root.type == bfd_link_hash_defweak);
+ h->root.u.def.section = h->u.weakdef->root.u.def.section;
+ h->root.u.def.value = h->u.weakdef->root.u.def.value;
+ return TRUE;
+ }
+
+ /* If there are no non-GOT references, we do not need a copy
+ relocation. */
+ if (!h->non_got_ref)
+ 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. Relocatable executables
+ can reference data in shared objects directly, so we don't need to
+ do anything here. */
+ if (info->shared || globals->root.is_relocatable_executable)
+ 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_linker_section (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(a).bss section we are going to use. */
+ if ((h->root.u.def.section->flags & SEC_ALLOC) != 0 && h->size != 0)
+ {
+ asection *srel;
+
+ srel = bfd_get_linker_section (dynobj, RELOC_SECTION (globals, ".bss"));
+ elf32_arm_allocate_dynrelocs (info, srel, 1);
+ h->needs_copy = 1;
+ }
+
+ return _bfd_elf_adjust_dynamic_copy (h, s);
+}
+
+/* Allocate space in .plt, .got and associated reloc sections for
+ dynamic relocs. */
+
+static bfd_boolean
+allocate_dynrelocs_for_symbol (struct elf_link_hash_entry *h, void * inf)
+{
+ struct bfd_link_info *info;
+ struct elf32_arm_link_hash_table *htab;
+ struct elf32_arm_link_hash_entry *eh;
+ struct elf_dyn_relocs *p;
+
+ if (h->root.type == bfd_link_hash_indirect)
+ return TRUE;
+
+ eh = (struct elf32_arm_link_hash_entry *) h;
+
+ info = (struct bfd_link_info *) inf;
+ htab = elf32_arm_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ if ((htab->root.dynamic_sections_created || h->type == STT_GNU_IFUNC)
+ && h->plt.refcount > 0)
+ {
+ /* Make sure this symbol is output as a dynamic symbol.
+ Undefined weak syms won't yet be marked as dynamic. */
+ if (h->dynindx == -1
+ && !h->forced_local)
+ {
+ if (! bfd_elf_link_record_dynamic_symbol (info, h))
+ return FALSE;
+ }
+
+ /* If the call in the PLT entry binds locally, the associated
+ GOT entry should use an R_ARM_IRELATIVE relocation instead of
+ the usual R_ARM_JUMP_SLOT. Put it in the .iplt section rather
+ than the .plt section. */
+ if (h->type == STT_GNU_IFUNC && SYMBOL_CALLS_LOCAL (info, h))
+ {
+ eh->is_iplt = 1;
+ if (eh->plt.noncall_refcount == 0
+ && SYMBOL_REFERENCES_LOCAL (info, h))
+ /* All non-call references can be resolved directly.
+ This means that they can (and in some cases, must)
+ resolve directly to the run-time target, rather than
+ to the PLT. That in turns means that any .got entry
+ would be equal to the .igot.plt entry, so there's
+ no point having both. */
+ h->got.refcount = 0;
+ }
+
+ if (info->shared
+ || eh->is_iplt
+ || WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, 0, h))
+ {
+ elf32_arm_allocate_plt_entry (info, eh->is_iplt, &h->plt, &eh->plt);
+
+ /* 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->def_regular)
+ {
+ h->root.u.def.section = htab->root.splt;
+ h->root.u.def.value = h->plt.offset;
+
+ /* Make sure the function is not marked as Thumb, in case
+ it is the target of an ABS32 relocation, which will
+ point to the PLT entry. */
+ h->target_internal = ST_BRANCH_TO_ARM;
+ }
+
+ /* VxWorks executables have a second set of relocations for
+ each PLT entry. They go in a separate relocation section,
+ which is processed by the kernel loader. */
+ if (htab->vxworks_p && !info->shared)
+ {
+ /* There is a relocation for the initial PLT entry:
+ an R_ARM_32 relocation for _GLOBAL_OFFSET_TABLE_. */
+ if (h->plt.offset == htab->plt_header_size)
+ elf32_arm_allocate_dynrelocs (info, htab->srelplt2, 1);
+
+ /* There are two extra relocations for each subsequent
+ PLT entry: an R_ARM_32 relocation for the GOT entry,
+ and an R_ARM_32 relocation for the PLT entry. */
+ elf32_arm_allocate_dynrelocs (info, htab->srelplt2, 2);
+ }
+ }
+ else
+ {
+ h->plt.offset = (bfd_vma) -1;
+ h->needs_plt = 0;
+ }
+ }
+ else
+ {
+ h->plt.offset = (bfd_vma) -1;
+ h->needs_plt = 0;
+ }
+
+ eh = (struct elf32_arm_link_hash_entry *) h;
+ eh->tlsdesc_got = (bfd_vma) -1;
+
+ if (h->got.refcount > 0)
+ {
+ asection *s;
+ bfd_boolean dyn;
+ int tls_type = elf32_arm_hash_entry (h)->tls_type;
+ int indx;
+
+ /* Make sure this symbol is output as a dynamic symbol.
+ Undefined weak syms won't yet be marked as dynamic. */
+ if (h->dynindx == -1
+ && !h->forced_local)
+ {
+ if (! bfd_elf_link_record_dynamic_symbol (info, h))
+ return FALSE;
+ }
+
+ if (!htab->symbian_p)
+ {
+ s = htab->root.sgot;
+ h->got.offset = s->size;
+
+ if (tls_type == GOT_UNKNOWN)
+ abort ();
+
+ if (tls_type == GOT_NORMAL)
+ /* Non-TLS symbols need one GOT slot. */
+ s->size += 4;
+ else
+ {
+ if (tls_type & GOT_TLS_GDESC)
+ {
+ /* R_ARM_TLS_DESC needs 2 GOT slots. */
+ eh->tlsdesc_got
+ = (htab->root.sgotplt->size
+ - elf32_arm_compute_jump_table_size (htab));
+ htab->root.sgotplt->size += 8;
+ h->got.offset = (bfd_vma) -2;
+ /* plt.got_offset needs to know there's a TLS_DESC
+ reloc in the middle of .got.plt. */
+ htab->num_tls_desc++;
+ }
+
+ if (tls_type & GOT_TLS_GD)
+ {
+ /* R_ARM_TLS_GD32 needs 2 consecutive GOT slots. If
+ the symbol is both GD and GDESC, got.offset may
+ have been overwritten. */
+ h->got.offset = s->size;
+ s->size += 8;
+ }
+
+ if (tls_type & GOT_TLS_IE)
+ /* R_ARM_TLS_IE32 needs one GOT slot. */
+ s->size += 4;
+ }
+
+ dyn = htab->root.dynamic_sections_created;
+
+ indx = 0;
+ if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h)
+ && (!info->shared
+ || !SYMBOL_REFERENCES_LOCAL (info, h)))
+ indx = h->dynindx;
+
+ if (tls_type != GOT_NORMAL
+ && (info->shared || indx != 0)
+ && (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
+ || h->root.type != bfd_link_hash_undefweak))
+ {
+ if (tls_type & GOT_TLS_IE)
+ elf32_arm_allocate_dynrelocs (info, htab->root.srelgot, 1);
+
+ if (tls_type & GOT_TLS_GD)
+ elf32_arm_allocate_dynrelocs (info, htab->root.srelgot, 1);
+
+ if (tls_type & GOT_TLS_GDESC)
+ {
+ elf32_arm_allocate_dynrelocs (info, htab->root.srelplt, 1);
+ /* GDESC needs a trampoline to jump to. */
+ htab->tls_trampoline = -1;
+ }
+
+ /* Only GD needs it. GDESC just emits one relocation per
+ 2 entries. */
+ if ((tls_type & GOT_TLS_GD) && indx != 0)
+ elf32_arm_allocate_dynrelocs (info, htab->root.srelgot, 1);
+ }
+ else if (indx != -1 && !SYMBOL_REFERENCES_LOCAL (info, h))
+ {
+ if (htab->root.dynamic_sections_created)
+ /* Reserve room for the GOT entry's R_ARM_GLOB_DAT relocation. */
+ elf32_arm_allocate_dynrelocs (info, htab->root.srelgot, 1);
+ }
+ else if (h->type == STT_GNU_IFUNC
+ && eh->plt.noncall_refcount == 0)
+ /* No non-call references resolve the STT_GNU_IFUNC's PLT entry;
+ they all resolve dynamically instead. Reserve room for the
+ GOT entry's R_ARM_IRELATIVE relocation. */
+ elf32_arm_allocate_irelocs (info, htab->root.srelgot, 1);
+ else if (info->shared && (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
+ || h->root.type != bfd_link_hash_undefweak))
+ /* Reserve room for the GOT entry's R_ARM_RELATIVE relocation. */
+ elf32_arm_allocate_dynrelocs (info, htab->root.srelgot, 1);
+ }
+ }
+ else
+ h->got.offset = (bfd_vma) -1;
+
+ /* Allocate stubs for exported Thumb functions on v4t. */
+ if (!htab->use_blx && h->dynindx != -1
+ && h->def_regular
+ && h->target_internal == ST_BRANCH_TO_THUMB
+ && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)
+ {
+ struct elf_link_hash_entry * th;
+ struct bfd_link_hash_entry * bh;
+ struct elf_link_hash_entry * myh;
+ char name[1024];
+ asection *s;
+ bh = NULL;
+ /* Create a new symbol to regist the real location of the function. */
+ s = h->root.u.def.section;
+ sprintf (name, "__real_%s", h->root.root.string);
+ _bfd_generic_link_add_one_symbol (info, s->owner,
+ name, BSF_GLOBAL, s,
+ h->root.u.def.value,
+ NULL, TRUE, FALSE, &bh);
+
+ myh = (struct elf_link_hash_entry *) bh;
+ myh->type = ELF_ST_INFO (STB_LOCAL, STT_FUNC);
+ myh->forced_local = 1;
+ myh->target_internal = ST_BRANCH_TO_THUMB;
+ eh->export_glue = myh;
+ th = record_arm_to_thumb_glue (info, h);
+ /* Point the symbol at the stub. */
+ h->type = ELF_ST_INFO (ELF_ST_BIND (h->type), STT_FUNC);
+ h->target_internal = ST_BRANCH_TO_ARM;
+ h->root.u.def.section = th->root.u.def.section;
+ h->root.u.def.value = th->root.u.def.value & ~1;
+ }
+
+ if (eh->dyn_relocs == NULL)
+ return TRUE;
+
+ /* In the shared -Bsymbolic case, discard space allocated for
+ dynamic pc-relative relocs against symbols which turn out to be
+ defined in regular objects. For the normal shared case, discard
+ space for pc-relative relocs that have become local due to symbol
+ visibility changes. */
+
+ if (info->shared || htab->root.is_relocatable_executable)
+ {
+ /* Relocs that use pc_count are PC-relative forms, which will appear
+ on something like ".long foo - ." or "movw REG, foo - .". We want
+ calls to protected symbols to resolve directly to the function
+ rather than going via the plt. If people want function pointer
+ comparisons to work as expected then they should avoid writing
+ assembly like ".long foo - .". */
+ if (SYMBOL_CALLS_LOCAL (info, h))
+ {
+ struct elf_dyn_relocs **pp;
+
+ for (pp = &eh->dyn_relocs; (p = *pp) != NULL; )
+ {
+ p->count -= p->pc_count;
+ p->pc_count = 0;
+ if (p->count == 0)
+ *pp = p->next;
+ else
+ pp = &p->next;
+ }
+ }
+
+ if (htab->vxworks_p)
+ {
+ struct elf_dyn_relocs **pp;
+
+ for (pp = &eh->dyn_relocs; (p = *pp) != NULL; )
+ {
+ if (strcmp (p->sec->output_section->name, ".tls_vars") == 0)
+ *pp = p->next;
+ else
+ pp = &p->next;
+ }
+ }
+
+ /* Also discard relocs on undefined weak syms with non-default
+ visibility. */
+ if (eh->dyn_relocs != NULL
+ && h->root.type == bfd_link_hash_undefweak)
+ {
+ if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
+ eh->dyn_relocs = NULL;
+
+ /* Make sure undefined weak symbols are output as a dynamic
+ symbol in PIEs. */
+ else if (h->dynindx == -1
+ && !h->forced_local)
+ {
+ if (! bfd_elf_link_record_dynamic_symbol (info, h))
+ return FALSE;
+ }
+ }
+
+ else if (htab->root.is_relocatable_executable && h->dynindx == -1
+ && h->root.type == bfd_link_hash_new)
+ {
+ /* Output absolute symbols so that we can create relocations
+ against them. For normal symbols we output a relocation
+ against the section that contains them. */
+ if (! bfd_elf_link_record_dynamic_symbol (info, h))
+ return FALSE;
+ }
+
+ }
+ else
+ {
+ /* For the non-shared case, discard space for relocs against
+ symbols which turn out to need copy relocs or are not
+ dynamic. */
+
+ if (!h->non_got_ref
+ && ((h->def_dynamic
+ && !h->def_regular)
+ || (htab->root.dynamic_sections_created
+ && (h->root.type == bfd_link_hash_undefweak
+ || h->root.type == bfd_link_hash_undefined))))
+ {
+ /* Make sure this symbol is output as a dynamic symbol.
+ Undefined weak syms won't yet be marked as dynamic. */
+ if (h->dynindx == -1
+ && !h->forced_local)
+ {
+ if (! bfd_elf_link_record_dynamic_symbol (info, h))
+ return FALSE;
+ }
+
+ /* If that succeeded, we know we'll be keeping all the
+ relocs. */
+ if (h->dynindx != -1)
+ goto keep;
+ }
+
+ eh->dyn_relocs = NULL;
+
+ keep: ;
+ }
+
+ /* Finally, allocate space. */
+ for (p = eh->dyn_relocs; p != NULL; p = p->next)
+ {
+ asection *sreloc = elf_section_data (p->sec)->sreloc;
+ if (h->type == STT_GNU_IFUNC
+ && eh->plt.noncall_refcount == 0
+ && SYMBOL_REFERENCES_LOCAL (info, h))
+ elf32_arm_allocate_irelocs (info, sreloc, p->count);
+ else
+ elf32_arm_allocate_dynrelocs (info, sreloc, p->count);
+ }
+
+ return TRUE;
+}
+
+/* Find any dynamic relocs that apply to read-only sections. */
+
+static bfd_boolean
+elf32_arm_readonly_dynrelocs (struct elf_link_hash_entry * h, void * inf)
+{
+ struct elf32_arm_link_hash_entry * eh;
+ struct elf_dyn_relocs * p;
+
+ eh = (struct elf32_arm_link_hash_entry *) h;
+ for (p = eh->dyn_relocs; p != NULL; p = p->next)
+ {
+ asection *s = p->sec;
+
+ if (s != NULL && (s->flags & SEC_READONLY) != 0)
+ {
+ struct bfd_link_info *info = (struct bfd_link_info *) inf;
+
+ info->flags |= DF_TEXTREL;
+
+ /* Not an error, just cut short the traversal. */
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+void
+bfd_elf32_arm_set_byteswap_code (struct bfd_link_info *info,
+ int byteswap_code)
+{
+ struct elf32_arm_link_hash_table *globals;
+
+ globals = elf32_arm_hash_table (info);
+ if (globals == NULL)
+ return;
+
+ globals->byteswap_code = byteswap_code;
+}
+
+/* Set the sizes of the dynamic sections. */
+
+static bfd_boolean
+elf32_arm_size_dynamic_sections (bfd * output_bfd ATTRIBUTE_UNUSED,
+ struct bfd_link_info * info)
+{
+ bfd * dynobj;
+ asection * s;
+ bfd_boolean plt;
+ bfd_boolean relocs;
+ bfd *ibfd;
+ struct elf32_arm_link_hash_table *htab;
+
+ htab = elf32_arm_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ dynobj = elf_hash_table (info)->dynobj;
+ BFD_ASSERT (dynobj != NULL);
+ check_use_blx (htab);
+
+ if (elf_hash_table (info)->dynamic_sections_created)
+ {
+ /* Set the contents of the .interp section to the interpreter. */
+ if (info->executable)
+ {
+ s = bfd_get_linker_section (dynobj, ".interp");
+ BFD_ASSERT (s != NULL);
+ s->size = sizeof ELF_DYNAMIC_INTERPRETER;
+ s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
+ }
+ }
+
+ /* Set up .got offsets for local syms, and space for local dynamic
+ relocs. */
+ for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next)
+ {
+ bfd_signed_vma *local_got;
+ bfd_signed_vma *end_local_got;
+ struct arm_local_iplt_info **local_iplt_ptr, *local_iplt;
+ char *local_tls_type;
+ bfd_vma *local_tlsdesc_gotent;
+ bfd_size_type locsymcount;
+ Elf_Internal_Shdr *symtab_hdr;
+ asection *srel;
+ bfd_boolean is_vxworks = htab->vxworks_p;
+ unsigned int symndx;
+
+ if (! is_arm_elf (ibfd))
+ continue;
+
+ for (s = ibfd->sections; s != NULL; s = s->next)
+ {
+ struct elf_dyn_relocs *p;
+
+ for (p = (struct elf_dyn_relocs *)
+ elf_section_data (s)->local_dynrel; p != NULL; p = p->next)
+ {
+ if (!bfd_is_abs_section (p->sec)
+ && bfd_is_abs_section (p->sec->output_section))
+ {
+ /* Input section has been discarded, either because
+ it is a copy of a linkonce section or due to
+ linker script /DISCARD/, so we'll be discarding
+ the relocs too. */
+ }
+ else if (is_vxworks
+ && strcmp (p->sec->output_section->name,
+ ".tls_vars") == 0)
+ {
+ /* Relocations in vxworks .tls_vars sections are
+ handled specially by the loader. */
+ }
+ else if (p->count != 0)
+ {
+ srel = elf_section_data (p->sec)->sreloc;
+ elf32_arm_allocate_dynrelocs (info, srel, p->count);
+ if ((p->sec->output_section->flags & SEC_READONLY) != 0)
+ info->flags |= DF_TEXTREL;
+ }
+ }
+ }
+
+ local_got = elf_local_got_refcounts (ibfd);
+ if (!local_got)
+ continue;
+
+ symtab_hdr = & elf_symtab_hdr (ibfd);
+ locsymcount = symtab_hdr->sh_info;
+ end_local_got = local_got + locsymcount;
+ local_iplt_ptr = elf32_arm_local_iplt (ibfd);
+ local_tls_type = elf32_arm_local_got_tls_type (ibfd);
+ local_tlsdesc_gotent = elf32_arm_local_tlsdesc_gotent (ibfd);
+ symndx = 0;
+ s = htab->root.sgot;
+ srel = htab->root.srelgot;
+ for (; local_got < end_local_got;
+ ++local_got, ++local_iplt_ptr, ++local_tls_type,
+ ++local_tlsdesc_gotent, ++symndx)
+ {
+ *local_tlsdesc_gotent = (bfd_vma) -1;
+ local_iplt = *local_iplt_ptr;
+ if (local_iplt != NULL)
+ {
+ struct elf_dyn_relocs *p;
+
+ if (local_iplt->root.refcount > 0)
+ {
+ elf32_arm_allocate_plt_entry (info, TRUE,
+ &local_iplt->root,
+ &local_iplt->arm);
+ if (local_iplt->arm.noncall_refcount == 0)
+ /* All references to the PLT are calls, so all
+ non-call references can resolve directly to the
+ run-time target. This means that the .got entry
+ would be the same as the .igot.plt entry, so there's
+ no point creating both. */
+ *local_got = 0;
+ }
+ else
+ {
+ BFD_ASSERT (local_iplt->arm.noncall_refcount == 0);
+ local_iplt->root.offset = (bfd_vma) -1;
+ }
+
+ for (p = local_iplt->dyn_relocs; p != NULL; p = p->next)
+ {
+ asection *psrel;
+
+ psrel = elf_section_data (p->sec)->sreloc;
+ if (local_iplt->arm.noncall_refcount == 0)
+ elf32_arm_allocate_irelocs (info, psrel, p->count);
+ else
+ elf32_arm_allocate_dynrelocs (info, psrel, p->count);
+ }
+ }
+ if (*local_got > 0)
+ {
+ Elf_Internal_Sym *isym;
+
+ *local_got = s->size;
+ if (*local_tls_type & GOT_TLS_GD)
+ /* TLS_GD relocs need an 8-byte structure in the GOT. */
+ s->size += 8;
+ if (*local_tls_type & GOT_TLS_GDESC)
+ {
+ *local_tlsdesc_gotent = htab->root.sgotplt->size
+ - elf32_arm_compute_jump_table_size (htab);
+ htab->root.sgotplt->size += 8;
+ *local_got = (bfd_vma) -2;
+ /* plt.got_offset needs to know there's a TLS_DESC
+ reloc in the middle of .got.plt. */
+ htab->num_tls_desc++;
+ }
+ if (*local_tls_type & GOT_TLS_IE)
+ s->size += 4;
+
+ if (*local_tls_type & GOT_NORMAL)
+ {
+ /* If the symbol is both GD and GDESC, *local_got
+ may have been overwritten. */
+ *local_got = s->size;
+ s->size += 4;
+ }
+
+ isym = bfd_sym_from_r_symndx (&htab->sym_cache, ibfd, symndx);
+ if (isym == NULL)
+ return FALSE;
+
+ /* If all references to an STT_GNU_IFUNC PLT are calls,
+ then all non-call references, including this GOT entry,
+ resolve directly to the run-time target. */
+ if (ELF32_ST_TYPE (isym->st_info) == STT_GNU_IFUNC
+ && (local_iplt == NULL
+ || local_iplt->arm.noncall_refcount == 0))
+ elf32_arm_allocate_irelocs (info, srel, 1);
+ else if (info->shared || output_bfd->flags & DYNAMIC)
+ {
+ if ((info->shared && !(*local_tls_type & GOT_TLS_GDESC))
+ || *local_tls_type & GOT_TLS_GD)
+ elf32_arm_allocate_dynrelocs (info, srel, 1);
+
+ if (info->shared && *local_tls_type & GOT_TLS_GDESC)
+ {
+ elf32_arm_allocate_dynrelocs (info,
+ htab->root.srelplt, 1);
+ htab->tls_trampoline = -1;
+ }
+ }
+ }
+ else
+ *local_got = (bfd_vma) -1;
+ }
+ }
+
+ if (htab->tls_ldm_got.refcount > 0)
+ {
+ /* Allocate two GOT entries and one dynamic relocation (if necessary)
+ for R_ARM_TLS_LDM32 relocations. */
+ htab->tls_ldm_got.offset = htab->root.sgot->size;
+ htab->root.sgot->size += 8;
+ if (info->shared)
+ elf32_arm_allocate_dynrelocs (info, htab->root.srelgot, 1);
+ }
+ else
+ htab->tls_ldm_got.offset = -1;
+
+ /* Allocate global sym .plt and .got entries, and space for global
+ sym dynamic relocs. */
+ elf_link_hash_traverse (& htab->root, allocate_dynrelocs_for_symbol, info);
+
+ /* Here we rummage through the found bfds to collect glue information. */
+ for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next)
+ {
+ if (! is_arm_elf (ibfd))
+ continue;
+
+ /* Initialise mapping tables for code/data. */
+ bfd_elf32_arm_init_maps (ibfd);
+
+ if (!bfd_elf32_arm_process_before_allocation (ibfd, info)
+ || !bfd_elf32_arm_vfp11_erratum_scan (ibfd, info))
+ /* xgettext:c-format */
+ _bfd_error_handler (_("Errors encountered processing file %s"),
+ ibfd->filename);
+ }
+
+ /* Allocate space for the glue sections now that we've sized them. */
+ bfd_elf32_arm_allocate_interworking_sections (info);
+
+ /* For every jump slot reserved in the sgotplt, reloc_count is
+ incremented. However, when we reserve space for TLS descriptors,
+ it's not incremented, so in order to compute the space reserved
+ for them, it suffices to multiply the reloc count by the jump
+ slot size. */
+ if (htab->root.srelplt)
+ htab->sgotplt_jump_table_size = elf32_arm_compute_jump_table_size(htab);
+
+ if (htab->tls_trampoline)
+ {
+ if (htab->root.splt->size == 0)
+ htab->root.splt->size += htab->plt_header_size;
+
+ htab->tls_trampoline = htab->root.splt->size;
+ htab->root.splt->size += htab->plt_entry_size;
+
+ /* If we're not using lazy TLS relocations, don't generate the
+ PLT and GOT entries they require. */
+ if (!(info->flags & DF_BIND_NOW))
+ {
+ htab->dt_tlsdesc_got = htab->root.sgot->size;
+ htab->root.sgot->size += 4;
+
+ htab->dt_tlsdesc_plt = htab->root.splt->size;
+ htab->root.splt->size += 4 * ARRAY_SIZE (dl_tlsdesc_lazy_trampoline);
+ }
+ }
+
+ /* 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;
+ for (s = dynobj->sections; s != NULL; s = s->next)
+ {
+ const char * name;
+
+ 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);
+
+ if (s == htab->root.splt)
+ {
+ /* Remember whether there is a PLT. */
+ plt = s->size != 0;
+ }
+ else if (CONST_STRNEQ (name, ".rel"))
+ {
+ if (s->size != 0)
+ {
+ /* Remember whether there are any reloc sections other
+ than .rel(a).plt and .rela.plt.unloaded. */
+ if (s != htab->root.srelplt && s != htab->srelplt2)
+ relocs = 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 (s != htab->root.sgot
+ && s != htab->root.sgotplt
+ && s != htab->root.iplt
+ && s != htab->root.igotplt
+ && s != htab->sdynbss)
+ {
+ /* It's not one of our sections, so don't allocate space. */
+ continue;
+ }
+
+ if (s->size == 0)
+ {
+ /* If we don't need this section, strip it from the
+ output file. This is mostly to handle .rel(a).bss and
+ .rel(a).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. */
+ s->flags |= SEC_EXCLUDE;
+ continue;
+ }
+
+ if ((s->flags & SEC_HAS_CONTENTS) == 0)
+ continue;
+
+ /* Allocate memory for the section contents. */
+ s->contents = (unsigned char *) bfd_zalloc (dynobj, s->size);
+ if (s->contents == NULL)
+ 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. */
+#define add_dynamic_entry(TAG, VAL) \
+ _bfd_elf_add_dynamic_entry (info, TAG, VAL)
+
+ if (info->executable)
+ {
+ if (!add_dynamic_entry (DT_DEBUG, 0))
+ return FALSE;
+ }
+
+ if (plt)
+ {
+ if ( !add_dynamic_entry (DT_PLTGOT, 0)
+ || !add_dynamic_entry (DT_PLTRELSZ, 0)
+ || !add_dynamic_entry (DT_PLTREL,
+ htab->use_rel ? DT_REL : DT_RELA)
+ || !add_dynamic_entry (DT_JMPREL, 0))
+ return FALSE;
+
+ if (htab->dt_tlsdesc_plt &&
+ (!add_dynamic_entry (DT_TLSDESC_PLT,0)
+ || !add_dynamic_entry (DT_TLSDESC_GOT,0)))
+ return FALSE;
+ }
+
+ if (relocs)
+ {
+ if (htab->use_rel)
+ {
+ if (!add_dynamic_entry (DT_REL, 0)
+ || !add_dynamic_entry (DT_RELSZ, 0)
+ || !add_dynamic_entry (DT_RELENT, RELOC_SIZE (htab)))
+ return FALSE;
+ }
+ else
+ {
+ if (!add_dynamic_entry (DT_RELA, 0)
+ || !add_dynamic_entry (DT_RELASZ, 0)
+ || !add_dynamic_entry (DT_RELAENT, RELOC_SIZE (htab)))
+ return FALSE;
+ }
+ }
+
+ /* If any dynamic relocs apply to a read-only section,
+ then we need a DT_TEXTREL entry. */
+ if ((info->flags & DF_TEXTREL) == 0)
+ elf_link_hash_traverse (& htab->root, elf32_arm_readonly_dynrelocs,
+ info);
+
+ if ((info->flags & DF_TEXTREL) != 0)
+ {
+ if (!add_dynamic_entry (DT_TEXTREL, 0))
+ return FALSE;
+ }
+ if (htab->vxworks_p
+ && !elf_vxworks_add_dynamic_entries (output_bfd, info))
+ return FALSE;
+ }
+#undef add_dynamic_entry
+
+ return TRUE;
+}
+
+/* Size sections even though they're not dynamic. We use it to setup
+ _TLS_MODULE_BASE_, if needed. */
+
+static bfd_boolean
+elf32_arm_always_size_sections (bfd *output_bfd,
+ struct bfd_link_info *info)
+{
+ asection *tls_sec;
+
+ if (info->relocatable)
+ return TRUE;
+
+ tls_sec = elf_hash_table (info)->tls_sec;
+
+ if (tls_sec)
+ {
+ struct elf_link_hash_entry *tlsbase;
+
+ tlsbase = elf_link_hash_lookup
+ (elf_hash_table (info), "_TLS_MODULE_BASE_", TRUE, TRUE, FALSE);
+
+ if (tlsbase)
+ {
+ struct bfd_link_hash_entry *bh = NULL;
+ const struct elf_backend_data *bed
+ = get_elf_backend_data (output_bfd);
+
+ if (!(_bfd_generic_link_add_one_symbol
+ (info, output_bfd, "_TLS_MODULE_BASE_", BSF_LOCAL,
+ tls_sec, 0, NULL, FALSE,
+ bed->collect, &bh)))
+ return FALSE;
+
+ tlsbase->type = STT_TLS;
+ tlsbase = (struct elf_link_hash_entry *)bh;
+ tlsbase->def_regular = 1;
+ tlsbase->other = STV_HIDDEN;
+ (*bed->elf_backend_hide_symbol) (info, tlsbase, TRUE);
+ }
+ }
+ return TRUE;
+}
+
+/* Finish up dynamic symbol handling. We set the contents of various
+ dynamic sections here. */
+
+static bfd_boolean
+elf32_arm_finish_dynamic_symbol (bfd * output_bfd,
+ struct bfd_link_info * info,
+ struct elf_link_hash_entry * h,
+ Elf_Internal_Sym * sym)
+{
+ struct elf32_arm_link_hash_table *htab;
+ struct elf32_arm_link_hash_entry *eh;
+
+ htab = elf32_arm_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ eh = (struct elf32_arm_link_hash_entry *) h;
+
+ if (h->plt.offset != (bfd_vma) -1)
+ {
+ if (!eh->is_iplt)
+ {
+ BFD_ASSERT (h->dynindx != -1);
+ if (! elf32_arm_populate_plt_entry (output_bfd, info, &h->plt, &eh->plt,
+ h->dynindx, 0))
+ return FALSE;
+ }
+
+ if (!h->def_regular)
+ {
+ /* Mark the symbol as undefined, rather than as defined in
+ the .plt section. Leave the value alone. */
+ sym->st_shndx = SHN_UNDEF;
+ /* If the symbol is weak, we do need to clear the value.
+ Otherwise, the PLT entry would provide a definition for
+ the symbol even if the symbol wasn't defined anywhere,
+ and so the symbol would never be NULL. */
+ if (!h->ref_regular_nonweak || !h->pointer_equality_needed)
+ sym->st_value = 0;
+ }
+ else if (eh->is_iplt && eh->plt.noncall_refcount != 0)
+ {
+ /* At least one non-call relocation references this .iplt entry,
+ so the .iplt entry is the function's canonical address. */
+ sym->st_info = ELF_ST_INFO (ELF_ST_BIND (sym->st_info), STT_FUNC);
+ sym->st_target_internal = ST_BRANCH_TO_ARM;
+ sym->st_shndx = (_bfd_elf_section_from_bfd_section
+ (output_bfd, htab->root.iplt->output_section));
+ sym->st_value = (h->plt.offset
+ + htab->root.iplt->output_section->vma
+ + htab->root.iplt->output_offset);
+ }
+ }
+
+ if (h->needs_copy)
+ {
+ asection * s;
+ Elf_Internal_Rela 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 = htab->srelbss;
+ BFD_ASSERT (s != NULL);
+
+ rel.r_addend = 0;
+ 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);
+ elf32_arm_add_dynreloc (output_bfd, info, s, &rel);
+ }
+
+ /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute. On VxWorks,
+ the _GLOBAL_OFFSET_TABLE_ symbol is not absolute: it is relative
+ to the ".got" section. */
+ if (h == htab->root.hdynamic
+ || (!htab->vxworks_p && h == htab->root.hgot))
+ sym->st_shndx = SHN_ABS;
+
+ return TRUE;
+}
+
+static void
+arm_put_trampoline (struct elf32_arm_link_hash_table *htab, bfd *output_bfd,
+ void *contents,
+ const unsigned long *template, unsigned count)
+{
+ unsigned ix;
+
+ for (ix = 0; ix != count; ix++)
+ {
+ unsigned long insn = template[ix];
+
+ /* Emit mov pc,rx if bx is not permitted. */
+ if (htab->fix_v4bx == 1 && (insn & 0x0ffffff0) == 0x012fff10)
+ insn = (insn & 0xf000000f) | 0x01a0f000;
+ put_arm_insn (htab, output_bfd, insn, (char *)contents + ix*4);
+ }
+}
+
+/* Install the special first PLT entry for elf32-arm-nacl. Unlike
+ other variants, NaCl needs this entry in a static executable's
+ .iplt too. When we're handling that case, GOT_DISPLACEMENT is
+ zero. For .iplt really only the last bundle is useful, and .iplt
+ could have a shorter first entry, with each individual PLT entry's
+ relative branch calculated differently so it targets the last
+ bundle instead of the instruction before it (labelled .Lplt_tail
+ above). But it's simpler to keep the size and layout of PLT0
+ consistent with the dynamic case, at the cost of some dead code at
+ the start of .iplt and the one dead store to the stack at the start
+ of .Lplt_tail. */
+static void
+arm_nacl_put_plt0 (struct elf32_arm_link_hash_table *htab, bfd *output_bfd,
+ asection *plt, bfd_vma got_displacement)
+{
+ unsigned int i;
+
+ put_arm_insn (htab, output_bfd,
+ elf32_arm_nacl_plt0_entry[0]
+ | arm_movw_immediate (got_displacement),
+ plt->contents + 0);
+ put_arm_insn (htab, output_bfd,
+ elf32_arm_nacl_plt0_entry[1]
+ | arm_movt_immediate (got_displacement),
+ plt->contents + 4);
+
+ for (i = 2; i < ARRAY_SIZE (elf32_arm_nacl_plt0_entry); ++i)
+ put_arm_insn (htab, output_bfd,
+ elf32_arm_nacl_plt0_entry[i],
+ plt->contents + (i * 4));
+}
+
+/* Finish up the dynamic sections. */
+
+static bfd_boolean
+elf32_arm_finish_dynamic_sections (bfd * output_bfd, struct bfd_link_info * info)
+{
+ bfd * dynobj;
+ asection * sgot;
+ asection * sdyn;
+ struct elf32_arm_link_hash_table *htab;
+
+ htab = elf32_arm_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ dynobj = elf_hash_table (info)->dynobj;
+
+ sgot = htab->root.sgotplt;
+ /* A broken linker script might have discarded the dynamic sections.
+ Catch this here so that we do not seg-fault later on. */
+ if (sgot != NULL && bfd_is_abs_section (sgot->output_section))
+ return FALSE;
+ sdyn = bfd_get_linker_section (dynobj, ".dynamic");
+
+ if (elf_hash_table (info)->dynamic_sections_created)
+ {
+ asection *splt;
+ Elf32_External_Dyn *dyncon, *dynconend;
+
+ splt = htab->root.splt;
+ BFD_ASSERT (splt != NULL && sdyn != NULL);
+ BFD_ASSERT (htab->symbian_p || sgot != NULL);
+
+ dyncon = (Elf32_External_Dyn *) sdyn->contents;
+ dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->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)
+ {
+ unsigned int type;
+
+ default:
+ if (htab->vxworks_p
+ && elf_vxworks_finish_dynamic_entry (output_bfd, &dyn))
+ bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
+ break;
+
+ case DT_HASH:
+ name = ".hash";
+ goto get_vma_if_bpabi;
+ case DT_STRTAB:
+ name = ".dynstr";
+ goto get_vma_if_bpabi;
+ case DT_SYMTAB:
+ name = ".dynsym";
+ goto get_vma_if_bpabi;
+ case DT_VERSYM:
+ name = ".gnu.version";
+ goto get_vma_if_bpabi;
+ case DT_VERDEF:
+ name = ".gnu.version_d";
+ goto get_vma_if_bpabi;
+ case DT_VERNEED:
+ name = ".gnu.version_r";
+ goto get_vma_if_bpabi;
+
+ case DT_PLTGOT:
+ name = ".got";
+ goto get_vma;
+ case DT_JMPREL:
+ name = RELOC_SECTION (htab, ".plt");
+ get_vma:
+ s = bfd_get_section_by_name (output_bfd, name);
+ if (s == NULL)
+ {
+ /* PR ld/14397: Issue an error message if a required section is missing. */
+ (*_bfd_error_handler)
+ (_("error: required section '%s' not found in the linker script"), name);
+ bfd_set_error (bfd_error_invalid_operation);
+ return FALSE;
+ }
+ if (!htab->symbian_p)
+ dyn.d_un.d_ptr = s->vma;
+ else
+ /* In the BPABI, tags in the PT_DYNAMIC section point
+ at the file offset, not the memory address, for the
+ convenience of the post linker. */
+ dyn.d_un.d_ptr = s->filepos;
+ bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
+ break;
+
+ get_vma_if_bpabi:
+ if (htab->symbian_p)
+ goto get_vma;
+ break;
+
+ case DT_PLTRELSZ:
+ s = htab->root.srelplt;
+ BFD_ASSERT (s != NULL);
+ dyn.d_un.d_val = s->size;
+ bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
+ break;
+
+ case DT_RELSZ:
+ case DT_RELASZ:
+ if (!htab->symbian_p)
+ {
+ /* 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(a).plt to follow all
+ other relocation sections, we don't have to worry
+ about changing the DT_REL entry. */
+ s = htab->root.srelplt;
+ if (s != NULL)
+ dyn.d_un.d_val -= s->size;
+ bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
+ break;
+ }
+ /* Fall through. */
+
+ case DT_REL:
+ case DT_RELA:
+ /* In the BPABI, the DT_REL tag must point at the file
+ offset, not the VMA, of the first relocation
+ section. So, we use code similar to that in
+ elflink.c, but do not check for SHF_ALLOC on the
+ relcoation section, since relocations sections are
+ never allocated under the BPABI. The comments above
+ about Unixware notwithstanding, we include all of the
+ relocations here. */
+ if (htab->symbian_p)
+ {
+ unsigned int i;
+ type = ((dyn.d_tag == DT_REL || dyn.d_tag == DT_RELSZ)
+ ? SHT_REL : SHT_RELA);
+ dyn.d_un.d_val = 0;
+ for (i = 1; i < elf_numsections (output_bfd); i++)
+ {
+ Elf_Internal_Shdr *hdr
+ = elf_elfsections (output_bfd)[i];
+ if (hdr->sh_type == type)
+ {
+ if (dyn.d_tag == DT_RELSZ
+ || dyn.d_tag == DT_RELASZ)
+ dyn.d_un.d_val += hdr->sh_size;
+ else if ((ufile_ptr) hdr->sh_offset
+ <= dyn.d_un.d_val - 1)
+ dyn.d_un.d_val = hdr->sh_offset;
+ }
+ }
+ bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
+ }
+ break;
+
+ case DT_TLSDESC_PLT:
+ s = htab->root.splt;
+ dyn.d_un.d_ptr = (s->output_section->vma + s->output_offset
+ + htab->dt_tlsdesc_plt);
+ bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
+ break;
+
+ case DT_TLSDESC_GOT:
+ s = htab->root.sgot;
+ dyn.d_un.d_ptr = (s->output_section->vma + s->output_offset
+ + htab->dt_tlsdesc_got);
+ bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
+ break;
+
+ /* Set the bottom bit of DT_INIT/FINI if the
+ corresponding function is Thumb. */
+ case DT_INIT:
+ name = info->init_function;
+ goto get_sym;
+ case DT_FINI:
+ name = info->fini_function;
+ get_sym:
+ /* If it wasn't set by elf_bfd_final_link
+ then there is nothing to adjust. */
+ if (dyn.d_un.d_val != 0)
+ {
+ struct elf_link_hash_entry * eh;
+
+ eh = elf_link_hash_lookup (elf_hash_table (info), name,
+ FALSE, FALSE, TRUE);
+ if (eh != NULL && eh->target_internal == ST_BRANCH_TO_THUMB)
+ {
+ dyn.d_un.d_val |= 1;
+ bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
+ }
+ }
+ break;
+ }
+ }
+
+ /* Fill in the first entry in the procedure linkage table. */
+ if (splt->size > 0 && htab->plt_header_size)
+ {
+ const bfd_vma *plt0_entry;
+ bfd_vma got_address, plt_address, got_displacement;
+
+ /* Calculate the addresses of the GOT and PLT. */
+ got_address = sgot->output_section->vma + sgot->output_offset;
+ plt_address = splt->output_section->vma + splt->output_offset;
+
+ if (htab->vxworks_p)
+ {
+ /* The VxWorks GOT is relocated by the dynamic linker.
+ Therefore, we must emit relocations rather than simply
+ computing the values now. */
+ Elf_Internal_Rela rel;
+
+ plt0_entry = elf32_arm_vxworks_exec_plt0_entry;
+ put_arm_insn (htab, output_bfd, plt0_entry[0],
+ splt->contents + 0);
+ put_arm_insn (htab, output_bfd, plt0_entry[1],
+ splt->contents + 4);
+ put_arm_insn (htab, output_bfd, plt0_entry[2],
+ splt->contents + 8);
+ bfd_put_32 (output_bfd, got_address, splt->contents + 12);
+
+ /* Generate a relocation for _GLOBAL_OFFSET_TABLE_. */
+ rel.r_offset = plt_address + 12;
+ rel.r_info = ELF32_R_INFO (htab->root.hgot->indx, R_ARM_ABS32);
+ rel.r_addend = 0;
+ SWAP_RELOC_OUT (htab) (output_bfd, &rel,
+ htab->srelplt2->contents);
+ }
+ else if (htab->nacl_p)
+ arm_nacl_put_plt0 (htab, output_bfd, splt,
+ got_address + 8 - (plt_address + 16));
+ else if (using_thumb_only (htab))
+ {
+ got_displacement = got_address - (plt_address + 12);
+
+ plt0_entry = elf32_thumb2_plt0_entry;
+ put_arm_insn (htab, output_bfd, plt0_entry[0],
+ splt->contents + 0);
+ put_arm_insn (htab, output_bfd, plt0_entry[1],
+ splt->contents + 4);
+ put_arm_insn (htab, output_bfd, plt0_entry[2],
+ splt->contents + 8);
+
+ bfd_put_32 (output_bfd, got_displacement, splt->contents + 12);
+ }
+ else
+ {
+ got_displacement = got_address - (plt_address + 16);
+
+ plt0_entry = elf32_arm_plt0_entry;
+ put_arm_insn (htab, output_bfd, plt0_entry[0],
+ splt->contents + 0);
+ put_arm_insn (htab, output_bfd, plt0_entry[1],
+ splt->contents + 4);
+ put_arm_insn (htab, output_bfd, plt0_entry[2],
+ splt->contents + 8);
+ put_arm_insn (htab, output_bfd, plt0_entry[3],
+ splt->contents + 12);
+
+#ifdef FOUR_WORD_PLT
+ /* The displacement value goes in the otherwise-unused
+ last word of the second entry. */
+ bfd_put_32 (output_bfd, got_displacement, splt->contents + 28);
+#else
+ bfd_put_32 (output_bfd, got_displacement, splt->contents + 16);
+#endif
+ }
+ }
+
+ /* UnixWare sets the entsize of .plt to 4, although that doesn't
+ really seem like the right value. */
+ if (splt->output_section->owner == output_bfd)
+ elf_section_data (splt->output_section)->this_hdr.sh_entsize = 4;
+
+ if (htab->dt_tlsdesc_plt)
+ {
+ bfd_vma got_address
+ = sgot->output_section->vma + sgot->output_offset;
+ bfd_vma gotplt_address = (htab->root.sgot->output_section->vma
+ + htab->root.sgot->output_offset);
+ bfd_vma plt_address
+ = splt->output_section->vma + splt->output_offset;
+
+ arm_put_trampoline (htab, output_bfd,
+ splt->contents + htab->dt_tlsdesc_plt,
+ dl_tlsdesc_lazy_trampoline, 6);
+
+ bfd_put_32 (output_bfd,
+ gotplt_address + htab->dt_tlsdesc_got
+ - (plt_address + htab->dt_tlsdesc_plt)
+ - dl_tlsdesc_lazy_trampoline[6],
+ splt->contents + htab->dt_tlsdesc_plt + 24);
+ bfd_put_32 (output_bfd,
+ got_address - (plt_address + htab->dt_tlsdesc_plt)
+ - dl_tlsdesc_lazy_trampoline[7],
+ splt->contents + htab->dt_tlsdesc_plt + 24 + 4);
+ }
+
+ if (htab->tls_trampoline)
+ {
+ arm_put_trampoline (htab, output_bfd,
+ splt->contents + htab->tls_trampoline,
+ tls_trampoline, 3);
+#ifdef FOUR_WORD_PLT
+ bfd_put_32 (output_bfd, 0x00000000,
+ splt->contents + htab->tls_trampoline + 12);
+#endif
+ }
+
+ if (htab->vxworks_p && !info->shared && htab->root.splt->size > 0)
+ {
+ /* Correct the .rel(a).plt.unloaded relocations. They will have
+ incorrect symbol indexes. */
+ int num_plts;
+ unsigned char *p;
+
+ num_plts = ((htab->root.splt->size - htab->plt_header_size)
+ / htab->plt_entry_size);
+ p = htab->srelplt2->contents + RELOC_SIZE (htab);
+
+ for (; num_plts; num_plts--)
+ {
+ Elf_Internal_Rela rel;
+
+ SWAP_RELOC_IN (htab) (output_bfd, p, &rel);
+ rel.r_info = ELF32_R_INFO (htab->root.hgot->indx, R_ARM_ABS32);
+ SWAP_RELOC_OUT (htab) (output_bfd, &rel, p);
+ p += RELOC_SIZE (htab);
+
+ SWAP_RELOC_IN (htab) (output_bfd, p, &rel);
+ rel.r_info = ELF32_R_INFO (htab->root.hplt->indx, R_ARM_ABS32);
+ SWAP_RELOC_OUT (htab) (output_bfd, &rel, p);
+ p += RELOC_SIZE (htab);
+ }
+ }
+ }
+
+ if (htab->nacl_p && htab->root.iplt != NULL && htab->root.iplt->size > 0)
+ /* NaCl uses a special first entry in .iplt too. */
+ arm_nacl_put_plt0 (htab, output_bfd, htab->root.iplt, 0);
+
+ /* Fill in the first three entries in the global offset table. */
+ if (sgot)
+ {
+ if (sgot->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;
+}
+
+static void
+elf32_arm_post_process_headers (bfd * abfd, struct bfd_link_info * link_info ATTRIBUTE_UNUSED)
+{
+ Elf_Internal_Ehdr * i_ehdrp; /* ELF file header, internal form. */
+ struct elf32_arm_link_hash_table *globals;
+
+ i_ehdrp = elf_elfheader (abfd);
+
+ if (EF_ARM_EABI_VERSION (i_ehdrp->e_flags) == EF_ARM_EABI_UNKNOWN)
+ i_ehdrp->e_ident[EI_OSABI] = ELFOSABI_ARM;
+ else
+ _bfd_elf_post_process_headers (abfd, link_info);
+ i_ehdrp->e_ident[EI_ABIVERSION] = ARM_ELF_ABI_VERSION;
+
+ if (link_info)
+ {
+ globals = elf32_arm_hash_table (link_info);
+ if (globals != NULL && globals->byteswap_code)
+ i_ehdrp->e_flags |= EF_ARM_BE8;
+ }
+
+ if (EF_ARM_EABI_VERSION (i_ehdrp->e_flags) == EF_ARM_EABI_VER5
+ && ((i_ehdrp->e_type == ET_DYN) || (i_ehdrp->e_type == ET_EXEC)))
+ {
+ int abi = bfd_elf_get_obj_attr_int (abfd, OBJ_ATTR_PROC, Tag_ABI_VFP_args);
+ if (abi)
+ i_ehdrp->e_flags |= EF_ARM_ABI_FLOAT_HARD;
+ else
+ i_ehdrp->e_flags |= EF_ARM_ABI_FLOAT_SOFT;
+ }
+}
+
+static enum elf_reloc_type_class
+elf32_arm_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ const asection *rel_sec ATTRIBUTE_UNUSED,
+ const Elf_Internal_Rela *rela)
+{
+ switch ((int) ELF32_R_TYPE (rela->r_info))
+ {
+ case R_ARM_RELATIVE:
+ return reloc_class_relative;
+ case R_ARM_JUMP_SLOT:
+ return reloc_class_plt;
+ case R_ARM_COPY:
+ return reloc_class_copy;
+ default:
+ return reloc_class_normal;
+ }
+}
+
+static void
+elf32_arm_final_write_processing (bfd *abfd, bfd_boolean linker ATTRIBUTE_UNUSED)
+{
+ bfd_arm_update_notes (abfd, ARM_NOTE_SECTION);
+}
+
+/* Return TRUE if this is an unwinding table entry. */
+
+static bfd_boolean
+is_arm_elf_unwind_section_name (bfd * abfd ATTRIBUTE_UNUSED, const char * name)
+{
+ return (CONST_STRNEQ (name, ELF_STRING_ARM_unwind)
+ || CONST_STRNEQ (name, ELF_STRING_ARM_unwind_once));
+}
+
+
+/* Set the type and flags for an ARM section. We do this by
+ the section name, which is a hack, but ought to work. */
+
+static bfd_boolean
+elf32_arm_fake_sections (bfd * abfd, Elf_Internal_Shdr * hdr, asection * sec)
+{
+ const char * name;
+
+ name = bfd_get_section_name (abfd, sec);
+
+ if (is_arm_elf_unwind_section_name (abfd, name))
+ {
+ hdr->sh_type = SHT_ARM_EXIDX;
+ hdr->sh_flags |= SHF_LINK_ORDER;
+ }
+ return TRUE;
+}
+
+/* Handle an ARM specific section when reading an object file. This is
+ called when bfd_section_from_shdr finds a section with an unknown
+ type. */
+
+static bfd_boolean
+elf32_arm_section_from_shdr (bfd *abfd,
+ Elf_Internal_Shdr * hdr,
+ const char *name,
+ int shindex)
+{
+ /* 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
+ names for all the ARM specific sections, so we will probably get
+ away with this. */
+ switch (hdr->sh_type)
+ {
+ case SHT_ARM_EXIDX:
+ case SHT_ARM_PREEMPTMAP:
+ case SHT_ARM_ATTRIBUTES:
+ break;
+
+ default:
+ return FALSE;
+ }
+
+ if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex))
+ return FALSE;
+
+ return TRUE;
+}
+
+static _arm_elf_section_data *
+get_arm_elf_section_data (asection * sec)
+{
+ if (sec && sec->owner && is_arm_elf (sec->owner))
+ return elf32_arm_section_data (sec);
+ else
+ return NULL;
+}
+
+typedef struct
+{
+ void *flaginfo;
+ struct bfd_link_info *info;
+ asection *sec;
+ int sec_shndx;
+ int (*func) (void *, const char *, Elf_Internal_Sym *,
+ asection *, struct elf_link_hash_entry *);
+} output_arch_syminfo;
+
+enum map_symbol_type
+{
+ ARM_MAP_ARM,
+ ARM_MAP_THUMB,
+ ARM_MAP_DATA
+};
+
+
+/* Output a single mapping symbol. */
+
+static bfd_boolean
+elf32_arm_output_map_sym (output_arch_syminfo *osi,
+ enum map_symbol_type type,
+ bfd_vma offset)
+{
+ static const char *names[3] = {"$a", "$t", "$d"};
+ Elf_Internal_Sym sym;
+
+ sym.st_value = osi->sec->output_section->vma
+ + osi->sec->output_offset
+ + offset;
+ sym.st_size = 0;
+ sym.st_other = 0;
+ sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_NOTYPE);
+ sym.st_shndx = osi->sec_shndx;
+ sym.st_target_internal = 0;
+ elf32_arm_section_map_add (osi->sec, names[type][1], offset);
+ return osi->func (osi->flaginfo, names[type], &sym, osi->sec, NULL) == 1;
+}
+
+/* Output mapping symbols for the PLT entry described by ROOT_PLT and ARM_PLT.
+ IS_IPLT_ENTRY_P says whether the PLT is in .iplt rather than .plt. */
+
+static bfd_boolean
+elf32_arm_output_plt_map_1 (output_arch_syminfo *osi,
+ bfd_boolean is_iplt_entry_p,
+ union gotplt_union *root_plt,
+ struct arm_plt_info *arm_plt)
+{
+ struct elf32_arm_link_hash_table *htab;
+ bfd_vma addr, plt_header_size;
+
+ if (root_plt->offset == (bfd_vma) -1)
+ return TRUE;
+
+ htab = elf32_arm_hash_table (osi->info);
+ if (htab == NULL)
+ return FALSE;
+
+ if (is_iplt_entry_p)
+ {
+ osi->sec = htab->root.iplt;
+ plt_header_size = 0;
+ }
+ else
+ {
+ osi->sec = htab->root.splt;
+ plt_header_size = htab->plt_header_size;
+ }
+ osi->sec_shndx = (_bfd_elf_section_from_bfd_section
+ (osi->info->output_bfd, osi->sec->output_section));
+
+ addr = root_plt->offset & -2;
+ if (htab->symbian_p)
+ {
+ if (!elf32_arm_output_map_sym (osi, ARM_MAP_ARM, addr))
+ return FALSE;
+ if (!elf32_arm_output_map_sym (osi, ARM_MAP_DATA, addr + 4))
+ return FALSE;
+ }
+ else if (htab->vxworks_p)
+ {
+ if (!elf32_arm_output_map_sym (osi, ARM_MAP_ARM, addr))
+ return FALSE;
+ if (!elf32_arm_output_map_sym (osi, ARM_MAP_DATA, addr + 8))
+ return FALSE;
+ if (!elf32_arm_output_map_sym (osi, ARM_MAP_ARM, addr + 12))
+ return FALSE;
+ if (!elf32_arm_output_map_sym (osi, ARM_MAP_DATA, addr + 20))
+ return FALSE;
+ }
+ else if (htab->nacl_p)
+ {
+ if (!elf32_arm_output_map_sym (osi, ARM_MAP_ARM, addr))
+ return FALSE;
+ }
+ else if (using_thumb_only (htab))
+ {
+ if (!elf32_arm_output_map_sym (osi, ARM_MAP_THUMB, addr))
+ return FALSE;
+ }
+ else
+ {
+ bfd_boolean thumb_stub_p;
+
+ thumb_stub_p = elf32_arm_plt_needs_thumb_stub_p (osi->info, arm_plt);
+ if (thumb_stub_p)
+ {
+ if (!elf32_arm_output_map_sym (osi, ARM_MAP_THUMB, addr - 4))
+ return FALSE;
+ }
+#ifdef FOUR_WORD_PLT
+ if (!elf32_arm_output_map_sym (osi, ARM_MAP_ARM, addr))
+ return FALSE;
+ if (!elf32_arm_output_map_sym (osi, ARM_MAP_DATA, addr + 12))
+ return FALSE;
+#else
+ /* A three-word PLT with no Thumb thunk contains only Arm code,
+ so only need to output a mapping symbol for the first PLT entry and
+ entries with thumb thunks. */
+ if (thumb_stub_p || addr == plt_header_size)
+ {
+ if (!elf32_arm_output_map_sym (osi, ARM_MAP_ARM, addr))
+ return FALSE;
+ }
+#endif
+ }
+
+ return TRUE;
+}
+
+/* Output mapping symbols for PLT entries associated with H. */
+
+static bfd_boolean
+elf32_arm_output_plt_map (struct elf_link_hash_entry *h, void *inf)
+{
+ output_arch_syminfo *osi = (output_arch_syminfo *) inf;
+ struct elf32_arm_link_hash_entry *eh;
+
+ if (h->root.type == bfd_link_hash_indirect)
+ return TRUE;
+
+ if (h->root.type == bfd_link_hash_warning)
+ /* When warning symbols are created, they **replace** the "real"
+ entry in the hash table, thus we never get to see the real
+ symbol in a hash traversal. So look at it now. */
+ h = (struct elf_link_hash_entry *) h->root.u.i.link;
+
+ eh = (struct elf32_arm_link_hash_entry *) h;
+ return elf32_arm_output_plt_map_1 (osi, SYMBOL_CALLS_LOCAL (osi->info, h),
+ &h->plt, &eh->plt);
+}
+
+/* Output a single local symbol for a generated stub. */
+
+static bfd_boolean
+elf32_arm_output_stub_sym (output_arch_syminfo *osi, const char *name,
+ bfd_vma offset, bfd_vma size)
+{
+ Elf_Internal_Sym sym;
+
+ sym.st_value = osi->sec->output_section->vma
+ + osi->sec->output_offset
+ + offset;
+ sym.st_size = size;
+ sym.st_other = 0;
+ sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_FUNC);
+ sym.st_shndx = osi->sec_shndx;
+ sym.st_target_internal = 0;
+ return osi->func (osi->flaginfo, name, &sym, osi->sec, NULL) == 1;
+}
+
+static bfd_boolean
+arm_map_one_stub (struct bfd_hash_entry * gen_entry,
+ void * in_arg)
+{
+ struct elf32_arm_stub_hash_entry *stub_entry;
+ asection *stub_sec;
+ bfd_vma addr;
+ char *stub_name;
+ output_arch_syminfo *osi;
+ const insn_sequence *template_sequence;
+ enum stub_insn_type prev_type;
+ int size;
+ int i;
+ enum map_symbol_type sym_type;
+
+ /* Massage our args to the form they really have. */
+ stub_entry = (struct elf32_arm_stub_hash_entry *) gen_entry;
+ osi = (output_arch_syminfo *) in_arg;
+
+ stub_sec = stub_entry->stub_sec;
+
+ /* Ensure this stub is attached to the current section being
+ processed. */
+ if (stub_sec != osi->sec)
+ return TRUE;
+
+ addr = (bfd_vma) stub_entry->stub_offset;
+ stub_name = stub_entry->output_name;
+
+ template_sequence = stub_entry->stub_template;
+ switch (template_sequence[0].type)
+ {
+ case ARM_TYPE:
+ if (!elf32_arm_output_stub_sym (osi, stub_name, addr, stub_entry->stub_size))
+ return FALSE;
+ break;
+ case THUMB16_TYPE:
+ case THUMB32_TYPE:
+ if (!elf32_arm_output_stub_sym (osi, stub_name, addr | 1,
+ stub_entry->stub_size))
+ return FALSE;
+ break;
+ default:
+ BFD_FAIL ();
+ return 0;
+ }
+
+ prev_type = DATA_TYPE;
+ size = 0;
+ for (i = 0; i < stub_entry->stub_template_size; i++)
+ {
+ switch (template_sequence[i].type)
+ {
+ case ARM_TYPE:
+ sym_type = ARM_MAP_ARM;
+ break;
+
+ case THUMB16_TYPE:
+ case THUMB32_TYPE:
+ sym_type = ARM_MAP_THUMB;
+ break;
+
+ case DATA_TYPE:
+ sym_type = ARM_MAP_DATA;
+ break;
+
+ default:
+ BFD_FAIL ();
+ return FALSE;
+ }
+
+ if (template_sequence[i].type != prev_type)
+ {
+ prev_type = template_sequence[i].type;
+ if (!elf32_arm_output_map_sym (osi, sym_type, addr + size))
+ return FALSE;
+ }
+
+ switch (template_sequence[i].type)
+ {
+ case ARM_TYPE:
+ case THUMB32_TYPE:
+ size += 4;
+ break;
+
+ case THUMB16_TYPE:
+ size += 2;
+ break;
+
+ case DATA_TYPE:
+ size += 4;
+ break;
+
+ default:
+ BFD_FAIL ();
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+/* Output mapping symbols for linker generated sections,
+ and for those data-only sections that do not have a
+ $d. */
+
+static bfd_boolean
+elf32_arm_output_arch_local_syms (bfd *output_bfd,
+ struct bfd_link_info *info,
+ void *flaginfo,
+ int (*func) (void *, const char *,
+ Elf_Internal_Sym *,
+ asection *,
+ struct elf_link_hash_entry *))
+{
+ output_arch_syminfo osi;
+ struct elf32_arm_link_hash_table *htab;
+ bfd_vma offset;
+ bfd_size_type size;
+ bfd *input_bfd;
+
+ htab = elf32_arm_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ check_use_blx (htab);
+
+ osi.flaginfo = flaginfo;
+ osi.info = info;
+ osi.func = func;
+
+ /* Add a $d mapping symbol to data-only sections that
+ don't have any mapping symbol. This may result in (harmless) redundant
+ mapping symbols. */
+ for (input_bfd = info->input_bfds;
+ input_bfd != NULL;
+ input_bfd = input_bfd->link.next)
+ {
+ if ((input_bfd->flags & (BFD_LINKER_CREATED | HAS_SYMS)) == HAS_SYMS)
+ for (osi.sec = input_bfd->sections;
+ osi.sec != NULL;
+ osi.sec = osi.sec->next)
+ {
+ if (osi.sec->output_section != NULL
+ && ((osi.sec->output_section->flags & (SEC_ALLOC | SEC_CODE))
+ != 0)
+ && (osi.sec->flags & (SEC_HAS_CONTENTS | SEC_LINKER_CREATED))
+ == SEC_HAS_CONTENTS
+ && get_arm_elf_section_data (osi.sec) != NULL
+ && get_arm_elf_section_data (osi.sec)->mapcount == 0
+ && osi.sec->size > 0
+ && (osi.sec->flags & SEC_EXCLUDE) == 0)
+ {
+ osi.sec_shndx = _bfd_elf_section_from_bfd_section
+ (output_bfd, osi.sec->output_section);
+ if (osi.sec_shndx != (int)SHN_BAD)
+ elf32_arm_output_map_sym (&osi, ARM_MAP_DATA, 0);
+ }
+ }
+ }
+
+ /* ARM->Thumb glue. */
+ if (htab->arm_glue_size > 0)
+ {
+ osi.sec = bfd_get_linker_section (htab->bfd_of_glue_owner,
+ ARM2THUMB_GLUE_SECTION_NAME);
+
+ osi.sec_shndx = _bfd_elf_section_from_bfd_section
+ (output_bfd, osi.sec->output_section);
+ if (info->shared || htab->root.is_relocatable_executable
+ || htab->pic_veneer)
+ size = ARM2THUMB_PIC_GLUE_SIZE;
+ else if (htab->use_blx)
+ size = ARM2THUMB_V5_STATIC_GLUE_SIZE;
+ else
+ size = ARM2THUMB_STATIC_GLUE_SIZE;
+
+ for (offset = 0; offset < htab->arm_glue_size; offset += size)
+ {
+ elf32_arm_output_map_sym (&osi, ARM_MAP_ARM, offset);
+ elf32_arm_output_map_sym (&osi, ARM_MAP_DATA, offset + size - 4);
+ }
+ }
+
+ /* Thumb->ARM glue. */
+ if (htab->thumb_glue_size > 0)
+ {
+ osi.sec = bfd_get_linker_section (htab->bfd_of_glue_owner,
+ THUMB2ARM_GLUE_SECTION_NAME);
+
+ osi.sec_shndx = _bfd_elf_section_from_bfd_section
+ (output_bfd, osi.sec->output_section);
+ size = THUMB2ARM_GLUE_SIZE;
+
+ for (offset = 0; offset < htab->thumb_glue_size; offset += size)
+ {
+ elf32_arm_output_map_sym (&osi, ARM_MAP_THUMB, offset);
+ elf32_arm_output_map_sym (&osi, ARM_MAP_ARM, offset + 4);
+ }
+ }
+
+ /* ARMv4 BX veneers. */
+ if (htab->bx_glue_size > 0)
+ {
+ osi.sec = bfd_get_linker_section (htab->bfd_of_glue_owner,
+ ARM_BX_GLUE_SECTION_NAME);
+
+ osi.sec_shndx = _bfd_elf_section_from_bfd_section
+ (output_bfd, osi.sec->output_section);
+
+ elf32_arm_output_map_sym (&osi, ARM_MAP_ARM, 0);
+ }
+
+ /* Long calls stubs. */
+ if (htab->stub_bfd && htab->stub_bfd->sections)
+ {
+ asection* stub_sec;
+
+ for (stub_sec = htab->stub_bfd->sections;
+ stub_sec != NULL;
+ stub_sec = stub_sec->next)
+ {
+ /* Ignore non-stub sections. */
+ if (!strstr (stub_sec->name, STUB_SUFFIX))
+ continue;
+
+ osi.sec = stub_sec;
+
+ osi.sec_shndx = _bfd_elf_section_from_bfd_section
+ (output_bfd, osi.sec->output_section);
+
+ bfd_hash_traverse (&htab->stub_hash_table, arm_map_one_stub, &osi);
+ }
+ }
+
+ /* Finally, output mapping symbols for the PLT. */
+ if (htab->root.splt && htab->root.splt->size > 0)
+ {
+ osi.sec = htab->root.splt;
+ osi.sec_shndx = (_bfd_elf_section_from_bfd_section
+ (output_bfd, osi.sec->output_section));
+
+ /* Output mapping symbols for the plt header. SymbianOS does not have a
+ plt header. */
+ if (htab->vxworks_p)
+ {
+ /* VxWorks shared libraries have no PLT header. */
+ if (!info->shared)
+ {
+ if (!elf32_arm_output_map_sym (&osi, ARM_MAP_ARM, 0))
+ return FALSE;
+ if (!elf32_arm_output_map_sym (&osi, ARM_MAP_DATA, 12))
+ return FALSE;
+ }
+ }
+ else if (htab->nacl_p)
+ {
+ if (!elf32_arm_output_map_sym (&osi, ARM_MAP_ARM, 0))
+ return FALSE;
+ }
+ else if (using_thumb_only (htab))
+ {
+ if (!elf32_arm_output_map_sym (&osi, ARM_MAP_THUMB, 0))
+ return FALSE;
+ if (!elf32_arm_output_map_sym (&osi, ARM_MAP_DATA, 12))
+ return FALSE;
+ if (!elf32_arm_output_map_sym (&osi, ARM_MAP_THUMB, 16))
+ return FALSE;
+ }
+ else if (!htab->symbian_p)
+ {
+ if (!elf32_arm_output_map_sym (&osi, ARM_MAP_ARM, 0))
+ return FALSE;
+#ifndef FOUR_WORD_PLT
+ if (!elf32_arm_output_map_sym (&osi, ARM_MAP_DATA, 16))
+ return FALSE;
+#endif
+ }
+ }
+ if (htab->nacl_p && htab->root.iplt && htab->root.iplt->size > 0)
+ {
+ /* NaCl uses a special first entry in .iplt too. */
+ osi.sec = htab->root.iplt;
+ osi.sec_shndx = (_bfd_elf_section_from_bfd_section
+ (output_bfd, osi.sec->output_section));
+ if (!elf32_arm_output_map_sym (&osi, ARM_MAP_ARM, 0))
+ return FALSE;
+ }
+ if ((htab->root.splt && htab->root.splt->size > 0)
+ || (htab->root.iplt && htab->root.iplt->size > 0))
+ {
+ elf_link_hash_traverse (&htab->root, elf32_arm_output_plt_map, &osi);
+ for (input_bfd = info->input_bfds;
+ input_bfd != NULL;
+ input_bfd = input_bfd->link.next)
+ {
+ struct arm_local_iplt_info **local_iplt;
+ unsigned int i, num_syms;
+
+ local_iplt = elf32_arm_local_iplt (input_bfd);
+ if (local_iplt != NULL)
+ {
+ num_syms = elf_symtab_hdr (input_bfd).sh_info;
+ for (i = 0; i < num_syms; i++)
+ if (local_iplt[i] != NULL
+ && !elf32_arm_output_plt_map_1 (&osi, TRUE,
+ &local_iplt[i]->root,
+ &local_iplt[i]->arm))
+ return FALSE;
+ }
+ }
+ }
+ if (htab->dt_tlsdesc_plt != 0)
+ {
+ /* Mapping symbols for the lazy tls trampoline. */
+ if (!elf32_arm_output_map_sym (&osi, ARM_MAP_ARM, htab->dt_tlsdesc_plt))
+ return FALSE;
+
+ if (!elf32_arm_output_map_sym (&osi, ARM_MAP_DATA,
+ htab->dt_tlsdesc_plt + 24))
+ return FALSE;
+ }
+ if (htab->tls_trampoline != 0)
+ {
+ /* Mapping symbols for the tls trampoline. */
+ if (!elf32_arm_output_map_sym (&osi, ARM_MAP_ARM, htab->tls_trampoline))
+ return FALSE;
+#ifdef FOUR_WORD_PLT
+ if (!elf32_arm_output_map_sym (&osi, ARM_MAP_DATA,
+ htab->tls_trampoline + 12))
+ return FALSE;
+#endif
+ }
+
+ return TRUE;
+}
+
+/* Allocate target specific section data. */
+
+static bfd_boolean
+elf32_arm_new_section_hook (bfd *abfd, asection *sec)
+{
+ if (!sec->used_by_bfd)
+ {
+ _arm_elf_section_data *sdata;
+ bfd_size_type amt = sizeof (*sdata);
+
+ sdata = (_arm_elf_section_data *) bfd_zalloc (abfd, amt);
+ if (sdata == NULL)
+ return FALSE;
+ sec->used_by_bfd = sdata;
+ }
+
+ return _bfd_elf_new_section_hook (abfd, sec);
+}
+
+
+/* Used to order a list of mapping symbols by address. */
+
+static int
+elf32_arm_compare_mapping (const void * a, const void * b)
+{
+ const elf32_arm_section_map *amap = (const elf32_arm_section_map *) a;
+ const elf32_arm_section_map *bmap = (const elf32_arm_section_map *) b;
+
+ if (amap->vma > bmap->vma)
+ return 1;
+ else if (amap->vma < bmap->vma)
+ return -1;
+ else if (amap->type > bmap->type)
+ /* Ensure results do not depend on the host qsort for objects with
+ multiple mapping symbols at the same address by sorting on type
+ after vma. */
+ return 1;
+ else if (amap->type < bmap->type)
+ return -1;
+ else
+ return 0;
+}
+
+/* Add OFFSET to lower 31 bits of ADDR, leaving other bits unmodified. */
+
+static unsigned long
+offset_prel31 (unsigned long addr, bfd_vma offset)
+{
+ return (addr & ~0x7ffffffful) | ((addr + offset) & 0x7ffffffful);
+}
+
+/* Copy an .ARM.exidx table entry, adding OFFSET to (applied) PREL31
+ relocations. */
+
+static void
+copy_exidx_entry (bfd *output_bfd, bfd_byte *to, bfd_byte *from, bfd_vma offset)
+{
+ unsigned long first_word = bfd_get_32 (output_bfd, from);
+ unsigned long second_word = bfd_get_32 (output_bfd, from + 4);
+
+ /* High bit of first word is supposed to be zero. */
+ if ((first_word & 0x80000000ul) == 0)
+ first_word = offset_prel31 (first_word, offset);
+
+ /* If the high bit of the first word is clear, and the bit pattern is not 0x1
+ (EXIDX_CANTUNWIND), this is an offset to an .ARM.extab entry. */
+ if ((second_word != 0x1) && ((second_word & 0x80000000ul) == 0))
+ second_word = offset_prel31 (second_word, offset);
+
+ bfd_put_32 (output_bfd, first_word, to);
+ bfd_put_32 (output_bfd, second_word, to + 4);
+}
+
+/* Data for make_branch_to_a8_stub(). */
+
+struct a8_branch_to_stub_data
+{
+ asection *writing_section;
+ bfd_byte *contents;
+};
+
+
+/* Helper to insert branches to Cortex-A8 erratum stubs in the right
+ places for a particular section. */
+
+static bfd_boolean
+make_branch_to_a8_stub (struct bfd_hash_entry *gen_entry,
+ void *in_arg)
+{
+ struct elf32_arm_stub_hash_entry *stub_entry;
+ struct a8_branch_to_stub_data *data;
+ bfd_byte *contents;
+ unsigned long branch_insn;
+ bfd_vma veneered_insn_loc, veneer_entry_loc;
+ bfd_signed_vma branch_offset;
+ bfd *abfd;
+ unsigned int target;
+
+ stub_entry = (struct elf32_arm_stub_hash_entry *) gen_entry;
+ data = (struct a8_branch_to_stub_data *) in_arg;
+
+ if (stub_entry->target_section != data->writing_section
+ || stub_entry->stub_type < arm_stub_a8_veneer_lwm)
+ return TRUE;
+
+ contents = data->contents;
+
+ veneered_insn_loc = stub_entry->target_section->output_section->vma
+ + stub_entry->target_section->output_offset
+ + stub_entry->target_value;
+
+ veneer_entry_loc = stub_entry->stub_sec->output_section->vma
+ + stub_entry->stub_sec->output_offset
+ + stub_entry->stub_offset;
+
+ if (stub_entry->stub_type == arm_stub_a8_veneer_blx)
+ veneered_insn_loc &= ~3u;
+
+ branch_offset = veneer_entry_loc - veneered_insn_loc - 4;
+
+ abfd = stub_entry->target_section->owner;
+ target = stub_entry->target_value;
+
+ /* We attempt to avoid this condition by setting stubs_always_after_branch
+ in elf32_arm_size_stubs if we've enabled the Cortex-A8 erratum workaround.
+ This check is just to be on the safe side... */
+ if ((veneered_insn_loc & ~0xfff) == (veneer_entry_loc & ~0xfff))
+ {
+ (*_bfd_error_handler) (_("%B: error: Cortex-A8 erratum stub is "
+ "allocated in unsafe location"), abfd);
+ return FALSE;
+ }
+
+ switch (stub_entry->stub_type)
+ {
+ case arm_stub_a8_veneer_b:
+ case arm_stub_a8_veneer_b_cond:
+ branch_insn = 0xf0009000;
+ goto jump24;
+
+ case arm_stub_a8_veneer_blx:
+ branch_insn = 0xf000e800;
+ goto jump24;
+
+ case arm_stub_a8_veneer_bl:
+ {
+ unsigned int i1, j1, i2, j2, s;
+
+ branch_insn = 0xf000d000;
+
+ jump24:
+ if (branch_offset < -16777216 || branch_offset > 16777214)
+ {
+ /* There's not much we can do apart from complain if this
+ happens. */
+ (*_bfd_error_handler) (_("%B: error: Cortex-A8 erratum stub out "
+ "of range (input file too large)"), abfd);
+ return FALSE;
+ }
+
+ /* i1 = not(j1 eor s), so:
+ not i1 = j1 eor s
+ j1 = (not i1) eor s. */
+
+ branch_insn |= (branch_offset >> 1) & 0x7ff;
+ branch_insn |= ((branch_offset >> 12) & 0x3ff) << 16;
+ i2 = (branch_offset >> 22) & 1;
+ i1 = (branch_offset >> 23) & 1;
+ s = (branch_offset >> 24) & 1;
+ j1 = (!i1) ^ s;
+ j2 = (!i2) ^ s;
+ branch_insn |= j2 << 11;
+ branch_insn |= j1 << 13;
+ branch_insn |= s << 26;
+ }
+ break;
+
+ default:
+ BFD_FAIL ();
+ return FALSE;
+ }
+
+ bfd_put_16 (abfd, (branch_insn >> 16) & 0xffff, &contents[target]);
+ bfd_put_16 (abfd, branch_insn & 0xffff, &contents[target + 2]);
+
+ return TRUE;
+}
+
+/* Do code byteswapping. Return FALSE afterwards so that the section is
+ written out as normal. */
+
+static bfd_boolean
+elf32_arm_write_section (bfd *output_bfd,
+ struct bfd_link_info *link_info,
+ asection *sec,
+ bfd_byte *contents)
+{
+ unsigned int mapcount, errcount;
+ _arm_elf_section_data *arm_data;
+ struct elf32_arm_link_hash_table *globals = elf32_arm_hash_table (link_info);
+ elf32_arm_section_map *map;
+ elf32_vfp11_erratum_list *errnode;
+ bfd_vma ptr;
+ bfd_vma end;
+ bfd_vma offset = sec->output_section->vma + sec->output_offset;
+ bfd_byte tmp;
+ unsigned int i;
+
+ if (globals == NULL)
+ return FALSE;
+
+ /* If this section has not been allocated an _arm_elf_section_data
+ structure then we cannot record anything. */
+ arm_data = get_arm_elf_section_data (sec);
+ if (arm_data == NULL)
+ return FALSE;
+
+ mapcount = arm_data->mapcount;
+ map = arm_data->map;
+ errcount = arm_data->erratumcount;
+
+ if (errcount != 0)
+ {
+ unsigned int endianflip = bfd_big_endian (output_bfd) ? 3 : 0;
+
+ for (errnode = arm_data->erratumlist; errnode != 0;
+ errnode = errnode->next)
+ {
+ bfd_vma target = errnode->vma - offset;
+
+ switch (errnode->type)
+ {
+ case VFP11_ERRATUM_BRANCH_TO_ARM_VENEER:
+ {
+ bfd_vma branch_to_veneer;
+ /* Original condition code of instruction, plus bit mask for
+ ARM B instruction. */
+ unsigned int insn = (errnode->u.b.vfp_insn & 0xf0000000)
+ | 0x0a000000;
+
+ /* The instruction is before the label. */
+ target -= 4;
+
+ /* Above offset included in -4 below. */
+ branch_to_veneer = errnode->u.b.veneer->vma
+ - errnode->vma - 4;
+
+ if ((signed) branch_to_veneer < -(1 << 25)
+ || (signed) branch_to_veneer >= (1 << 25))
+ (*_bfd_error_handler) (_("%B: error: VFP11 veneer out of "
+ "range"), output_bfd);
+
+ insn |= (branch_to_veneer >> 2) & 0xffffff;
+ contents[endianflip ^ target] = insn & 0xff;
+ contents[endianflip ^ (target + 1)] = (insn >> 8) & 0xff;
+ contents[endianflip ^ (target + 2)] = (insn >> 16) & 0xff;
+ contents[endianflip ^ (target + 3)] = (insn >> 24) & 0xff;
+ }
+ break;
+
+ case VFP11_ERRATUM_ARM_VENEER:
+ {
+ bfd_vma branch_from_veneer;
+ unsigned int insn;
+
+ /* Take size of veneer into account. */
+ branch_from_veneer = errnode->u.v.branch->vma
+ - errnode->vma - 12;
+
+ if ((signed) branch_from_veneer < -(1 << 25)
+ || (signed) branch_from_veneer >= (1 << 25))
+ (*_bfd_error_handler) (_("%B: error: VFP11 veneer out of "
+ "range"), output_bfd);
+
+ /* Original instruction. */
+ insn = errnode->u.v.branch->u.b.vfp_insn;
+ contents[endianflip ^ target] = insn & 0xff;
+ contents[endianflip ^ (target + 1)] = (insn >> 8) & 0xff;
+ contents[endianflip ^ (target + 2)] = (insn >> 16) & 0xff;
+ contents[endianflip ^ (target + 3)] = (insn >> 24) & 0xff;
+
+ /* Branch back to insn after original insn. */
+ insn = 0xea000000 | ((branch_from_veneer >> 2) & 0xffffff);
+ contents[endianflip ^ (target + 4)] = insn & 0xff;
+ contents[endianflip ^ (target + 5)] = (insn >> 8) & 0xff;
+ contents[endianflip ^ (target + 6)] = (insn >> 16) & 0xff;
+ contents[endianflip ^ (target + 7)] = (insn >> 24) & 0xff;
+ }
+ break;
+
+ default:
+ abort ();
+ }
+ }
+ }
+
+ if (arm_data->elf.this_hdr.sh_type == SHT_ARM_EXIDX)
+ {
+ arm_unwind_table_edit *edit_node
+ = arm_data->u.exidx.unwind_edit_list;
+ /* Now, sec->size is the size of the section we will write. The original
+ size (before we merged duplicate entries and inserted EXIDX_CANTUNWIND
+ markers) was sec->rawsize. (This isn't the case if we perform no
+ edits, then rawsize will be zero and we should use size). */
+ bfd_byte *edited_contents = (bfd_byte *) bfd_malloc (sec->size);
+ unsigned int input_size = sec->rawsize ? sec->rawsize : sec->size;
+ unsigned int in_index, out_index;
+ bfd_vma add_to_offsets = 0;
+
+ for (in_index = 0, out_index = 0; in_index * 8 < input_size || edit_node;)
+ {
+ if (edit_node)
+ {
+ unsigned int edit_index = edit_node->index;
+
+ if (in_index < edit_index && in_index * 8 < input_size)
+ {
+ copy_exidx_entry (output_bfd, edited_contents + out_index * 8,
+ contents + in_index * 8, add_to_offsets);
+ out_index++;
+ in_index++;
+ }
+ else if (in_index == edit_index
+ || (in_index * 8 >= input_size
+ && edit_index == UINT_MAX))
+ {
+ switch (edit_node->type)
+ {
+ case DELETE_EXIDX_ENTRY:
+ in_index++;
+ add_to_offsets += 8;
+ break;
+
+ case INSERT_EXIDX_CANTUNWIND_AT_END:
+ {
+ asection *text_sec = edit_node->linked_section;
+ bfd_vma text_offset = text_sec->output_section->vma
+ + text_sec->output_offset
+ + text_sec->size;
+ bfd_vma exidx_offset = offset + out_index * 8;
+ unsigned long prel31_offset;
+
+ /* Note: this is meant to be equivalent to an
+ R_ARM_PREL31 relocation. These synthetic
+ EXIDX_CANTUNWIND markers are not relocated by the
+ usual BFD method. */
+ prel31_offset = (text_offset - exidx_offset)
+ & 0x7ffffffful;
+
+ /* First address we can't unwind. */
+ bfd_put_32 (output_bfd, prel31_offset,
+ &edited_contents[out_index * 8]);
+
+ /* Code for EXIDX_CANTUNWIND. */
+ bfd_put_32 (output_bfd, 0x1,
+ &edited_contents[out_index * 8 + 4]);
+
+ out_index++;
+ add_to_offsets -= 8;
+ }
+ break;
+ }
+
+ edit_node = edit_node->next;
+ }
+ }
+ else
+ {
+ /* No more edits, copy remaining entries verbatim. */
+ copy_exidx_entry (output_bfd, edited_contents + out_index * 8,
+ contents + in_index * 8, add_to_offsets);
+ out_index++;
+ in_index++;
+ }
+ }
+
+ if (!(sec->flags & SEC_EXCLUDE) && !(sec->flags & SEC_NEVER_LOAD))
+ bfd_set_section_contents (output_bfd, sec->output_section,
+ edited_contents,
+ (file_ptr) sec->output_offset, sec->size);
+
+ return TRUE;
+ }
+
+ /* Fix code to point to Cortex-A8 erratum stubs. */
+ if (globals->fix_cortex_a8)
+ {
+ struct a8_branch_to_stub_data data;
+
+ data.writing_section = sec;
+ data.contents = contents;
+
+ bfd_hash_traverse (&globals->stub_hash_table, make_branch_to_a8_stub,
+ &data);
+ }
+
+ if (mapcount == 0)
+ return FALSE;
+
+ if (globals->byteswap_code)
+ {
+ qsort (map, mapcount, sizeof (* map), elf32_arm_compare_mapping);
+
+ ptr = map[0].vma;
+ for (i = 0; i < mapcount; i++)
+ {
+ if (i == mapcount - 1)
+ end = sec->size;
+ else
+ end = map[i + 1].vma;
+
+ switch (map[i].type)
+ {
+ case 'a':
+ /* Byte swap code words. */
+ while (ptr + 3 < end)
+ {
+ tmp = contents[ptr];
+ contents[ptr] = contents[ptr + 3];
+ contents[ptr + 3] = tmp;
+ tmp = contents[ptr + 1];
+ contents[ptr + 1] = contents[ptr + 2];
+ contents[ptr + 2] = tmp;
+ ptr += 4;
+ }
+ break;
+
+ case 't':
+ /* Byte swap code halfwords. */
+ while (ptr + 1 < end)
+ {
+ tmp = contents[ptr];
+ contents[ptr] = contents[ptr + 1];
+ contents[ptr + 1] = tmp;
+ ptr += 2;
+ }
+ break;
+
+ case 'd':
+ /* Leave data alone. */
+ break;
+ }
+ ptr = end;
+ }
+ }
+
+ free (map);
+ arm_data->mapcount = -1;
+ arm_data->mapsize = 0;
+ arm_data->map = NULL;
+
+ return FALSE;
+}
+
+/* Mangle thumb function symbols as we read them in. */
+
+static bfd_boolean
+elf32_arm_swap_symbol_in (bfd * abfd,
+ const void *psrc,
+ const void *pshn,
+ Elf_Internal_Sym *dst)
+{
+ if (!bfd_elf32_swap_symbol_in (abfd, psrc, pshn, dst))
+ return FALSE;
+
+ /* New EABI objects mark thumb function symbols by setting the low bit of
+ the address. */
+ if (ELF_ST_TYPE (dst->st_info) == STT_FUNC
+ || ELF_ST_TYPE (dst->st_info) == STT_GNU_IFUNC)
+ {
+ if (dst->st_value & 1)
+ {
+ dst->st_value &= ~(bfd_vma) 1;
+ dst->st_target_internal = ST_BRANCH_TO_THUMB;
+ }
+ else
+ dst->st_target_internal = ST_BRANCH_TO_ARM;
+ }
+ else if (ELF_ST_TYPE (dst->st_info) == STT_ARM_TFUNC)
+ {
+ dst->st_info = ELF_ST_INFO (ELF_ST_BIND (dst->st_info), STT_FUNC);
+ dst->st_target_internal = ST_BRANCH_TO_THUMB;
+ }
+ else if (ELF_ST_TYPE (dst->st_info) == STT_SECTION)
+ dst->st_target_internal = ST_BRANCH_LONG;
+ else
+ dst->st_target_internal = ST_BRANCH_UNKNOWN;
+
+ return TRUE;
+}
+
+
+/* Mangle thumb function symbols as we write them out. */
+
+static void
+elf32_arm_swap_symbol_out (bfd *abfd,
+ const Elf_Internal_Sym *src,
+ void *cdst,
+ void *shndx)
+{
+ Elf_Internal_Sym newsym;
+
+ /* We convert STT_ARM_TFUNC symbols into STT_FUNC with the low bit
+ of the address set, as per the new EABI. We do this unconditionally
+ because objcopy does not set the elf header flags until after
+ it writes out the symbol table. */
+ if (src->st_target_internal == ST_BRANCH_TO_THUMB)
+ {
+ newsym = *src;
+ if (ELF_ST_TYPE (src->st_info) != STT_GNU_IFUNC)
+ newsym.st_info = ELF_ST_INFO (ELF_ST_BIND (src->st_info), STT_FUNC);
+ if (newsym.st_shndx != SHN_UNDEF)
+ {
+ /* Do this only for defined symbols. At link type, the static
+ linker will simulate the work of dynamic linker of resolving
+ symbols and will carry over the thumbness of found symbols to
+ the output symbol table. It's not clear how it happens, but
+ the thumbness of undefined symbols can well be different at
+ runtime, and writing '1' for them will be confusing for users
+ and possibly for dynamic linker itself.
+ */
+ newsym.st_value |= 1;
+ }
+
+ src = &newsym;
+ }
+ bfd_elf32_swap_symbol_out (abfd, src, cdst, shndx);
+}
+
+/* Add the PT_ARM_EXIDX program header. */
+
+static bfd_boolean
+elf32_arm_modify_segment_map (bfd *abfd,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED)
+{
+ struct elf_segment_map *m;
+ asection *sec;
+
+ sec = bfd_get_section_by_name (abfd, ".ARM.exidx");
+ if (sec != NULL && (sec->flags & SEC_LOAD) != 0)
+ {
+ /* If there is already a PT_ARM_EXIDX header, then we do not
+ want to add another one. This situation arises when running
+ "strip"; the input binary already has the header. */
+ m = elf_seg_map (abfd);
+ while (m && m->p_type != PT_ARM_EXIDX)
+ m = m->next;
+ if (!m)
+ {
+ m = (struct elf_segment_map *)
+ bfd_zalloc (abfd, sizeof (struct elf_segment_map));
+ if (m == NULL)
+ return FALSE;
+ m->p_type = PT_ARM_EXIDX;
+ m->count = 1;
+ m->sections[0] = sec;
+
+ m->next = elf_seg_map (abfd);
+ elf_seg_map (abfd) = m;
+ }
+ }
+
+ return TRUE;
+}
+
+/* We may add a PT_ARM_EXIDX program header. */
+
+static int
+elf32_arm_additional_program_headers (bfd *abfd,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED)
+{
+ asection *sec;
+
+ sec = bfd_get_section_by_name (abfd, ".ARM.exidx");
+ if (sec != NULL && (sec->flags & SEC_LOAD) != 0)
+ return 1;
+ else
+ return 0;
+}
+
+/* Hook called by the linker routine which adds symbols from an object
+ file. */
+
+static bfd_boolean
+elf32_arm_add_symbol_hook (bfd *abfd, struct bfd_link_info *info,
+ Elf_Internal_Sym *sym, const char **namep,
+ flagword *flagsp, asection **secp, bfd_vma *valp)
+{
+ if ((ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC
+ || ELF_ST_BIND (sym->st_info) == STB_GNU_UNIQUE)
+ && (abfd->flags & DYNAMIC) == 0
+ && bfd_get_flavour (info->output_bfd) == bfd_target_elf_flavour)
+ elf_tdata (info->output_bfd)->has_gnu_symbols = TRUE;
+
+ if (elf32_arm_hash_table (info) == NULL)
+ return FALSE;
+
+ if (elf32_arm_hash_table (info)->vxworks_p
+ && !elf_vxworks_add_symbol_hook (abfd, info, sym, namep,
+ flagsp, secp, valp))
+ return FALSE;
+
+ return TRUE;
+}
+
+/* We use this to override swap_symbol_in and swap_symbol_out. */
+const struct elf_size_info elf32_arm_size_info =
+{
+ sizeof (Elf32_External_Ehdr),
+ sizeof (Elf32_External_Phdr),
+ sizeof (Elf32_External_Shdr),
+ sizeof (Elf32_External_Rel),
+ sizeof (Elf32_External_Rela),
+ sizeof (Elf32_External_Sym),
+ sizeof (Elf32_External_Dyn),
+ sizeof (Elf_External_Note),
+ 4,
+ 1,
+ 32, 2,
+ ELFCLASS32, EV_CURRENT,
+ bfd_elf32_write_out_phdrs,
+ bfd_elf32_write_shdrs_and_ehdr,
+ bfd_elf32_checksum_contents,
+ bfd_elf32_write_relocs,
+ elf32_arm_swap_symbol_in,
+ elf32_arm_swap_symbol_out,
+ bfd_elf32_slurp_reloc_table,
+ bfd_elf32_slurp_symbol_table,
+ bfd_elf32_swap_dyn_in,
+ bfd_elf32_swap_dyn_out,
+ bfd_elf32_swap_reloc_in,
+ bfd_elf32_swap_reloc_out,
+ bfd_elf32_swap_reloca_in,
+ bfd_elf32_swap_reloca_out
+};
+
+/* Return size of plt0 entry starting at ADDR
+ or (bfd_vma) -1 if size can not be determined. */
+
+static bfd_vma
+elf32_arm_plt0_size (const bfd *abfd, const bfd_byte *addr)
+{
+ bfd_vma first_word;
+ bfd_vma plt0_size;
+
+ first_word = H_GET_32 (abfd, addr);
+
+ if (first_word == elf32_arm_plt0_entry[0])
+ plt0_size = 4 * ARRAY_SIZE (elf32_arm_plt0_entry);
+ else if (first_word == elf32_thumb2_plt0_entry[0])
+ plt0_size = 4 * ARRAY_SIZE (elf32_thumb2_plt0_entry);
+ else
+ /* We don't yet handle this PLT format. */
+ return (bfd_vma) -1;
+
+ return plt0_size;
+}
+
+/* Return size of plt entry starting at offset OFFSET
+ of plt section located at address START
+ or (bfd_vma) -1 if size can not be determined. */
+
+static bfd_vma
+elf32_arm_plt_size (const bfd *abfd, const bfd_byte *start, bfd_vma offset)
+{
+ bfd_vma first_insn;
+ bfd_vma plt_size = 0;
+ const bfd_byte *addr = start + offset;
+
+ /* PLT entry size if fixed on Thumb-only platforms. */
+ if (H_GET_32(abfd, start) == elf32_thumb2_plt0_entry[0])
+ return 4 * ARRAY_SIZE (elf32_thumb2_plt_entry);
+
+ /* Respect Thumb stub if necessary. */
+ if (H_GET_16(abfd, addr) == elf32_arm_plt_thumb_stub[0])
+ {
+ plt_size += 2 * ARRAY_SIZE(elf32_arm_plt_thumb_stub);
+ }
+
+ /* Strip immediate from first add. */
+ first_insn = H_GET_32(abfd, addr + plt_size) & 0xffffff00;
+
+#ifdef FOUR_WORD_PLT
+ if (first_insn == elf32_arm_plt_entry[0])
+ plt_size += 4 * ARRAY_SIZE (elf32_arm_plt_entry);
+#else
+ if (first_insn == elf32_arm_plt_entry_long[0])
+ plt_size += 4 * ARRAY_SIZE (elf32_arm_plt_entry_long);
+ else if (first_insn == elf32_arm_plt_entry_short[0])
+ plt_size += 4 * ARRAY_SIZE (elf32_arm_plt_entry_short);
+#endif
+ else
+ /* We don't yet handle this PLT format. */
+ return (bfd_vma) -1;
+
+ return plt_size;
+}
+
+/* Implementation is shamelessly borrowed from _bfd_elf_get_synthetic_symtab. */
+
+static long
+elf32_arm_get_synthetic_symtab (bfd *abfd,
+ long symcount ATTRIBUTE_UNUSED,
+ asymbol **syms ATTRIBUTE_UNUSED,
+ long dynsymcount,
+ asymbol **dynsyms,
+ asymbol **ret)
+{
+ asection *relplt;
+ asymbol *s;
+ arelent *p;
+ long count, i, n;
+ size_t size;
+ Elf_Internal_Shdr *hdr;
+ char *names;
+ asection *plt;
+ bfd_vma offset;
+ bfd_byte *data;
+
+ *ret = NULL;
+
+ if ((abfd->flags & (DYNAMIC | EXEC_P)) == 0)
+ return 0;
+
+ if (dynsymcount <= 0)
+ return 0;
+
+ relplt = bfd_get_section_by_name (abfd, ".rel.plt");
+ if (relplt == NULL)
+ return 0;
+
+ hdr = &elf_section_data (relplt)->this_hdr;
+ if (hdr->sh_link != elf_dynsymtab (abfd)
+ || (hdr->sh_type != SHT_REL && hdr->sh_type != SHT_RELA))
+ return 0;
+
+ plt = bfd_get_section_by_name (abfd, ".plt");
+ if (plt == NULL)
+ return 0;
+
+ if (!elf32_arm_size_info.slurp_reloc_table (abfd, relplt, dynsyms, TRUE))
+ return -1;
+
+ data = plt->contents;
+ if (data == NULL)
+ {
+ if (!bfd_get_full_section_contents(abfd, (asection *) plt, &data) || data == NULL)
+ return -1;
+ bfd_cache_section_contents((asection *) plt, data);
+ }
+
+ count = relplt->size / hdr->sh_entsize;
+ size = count * sizeof (asymbol);
+ p = relplt->relocation;
+ for (i = 0; i < count; i++, p += elf32_arm_size_info.int_rels_per_ext_rel)
+ {
+ size += strlen ((*p->sym_ptr_ptr)->name) + sizeof ("@plt");
+ if (p->addend != 0)
+ size += sizeof ("+0x") - 1 + 8;
+ }
+
+ s = *ret = (asymbol *) bfd_malloc (size);
+ if (s == NULL)
+ return -1;
+
+ offset = elf32_arm_plt0_size (abfd, data);
+ if (offset == (bfd_vma) -1)
+ return -1;
+
+ names = (char *) (s + count);
+ p = relplt->relocation;
+ n = 0;
+ for (i = 0; i < count; i++, p += elf32_arm_size_info.int_rels_per_ext_rel)
+ {
+ size_t len;
+
+ bfd_vma plt_size = elf32_arm_plt_size (abfd, data, offset);
+ if (plt_size == (bfd_vma) -1)
+ break;
+
+ *s = **p->sym_ptr_ptr;
+ /* Undefined syms won't have BSF_LOCAL or BSF_GLOBAL set. Since
+ we are defining a symbol, ensure one of them is set. */
+ if ((s->flags & BSF_LOCAL) == 0)
+ s->flags |= BSF_GLOBAL;
+ s->flags |= BSF_SYNTHETIC;
+ s->section = plt;
+ s->value = offset;
+ s->name = names;
+ s->udata.p = NULL;
+ len = strlen ((*p->sym_ptr_ptr)->name);
+ memcpy (names, (*p->sym_ptr_ptr)->name, len);
+ names += len;
+ if (p->addend != 0)
+ {
+ char buf[30], *a;
+
+ memcpy (names, "+0x", sizeof ("+0x") - 1);
+ names += sizeof ("+0x") - 1;
+ bfd_sprintf_vma (abfd, buf, p->addend);
+ for (a = buf; *a == '0'; ++a)
+ ;
+ len = strlen (a);
+ memcpy (names, a, len);
+ names += len;
+ }
+ memcpy (names, "@plt", sizeof ("@plt"));
+ names += sizeof ("@plt");
+ ++s, ++n;
+ offset += plt_size;
+ }
+
+ return n;
+}
+
+#define ELF_ARCH bfd_arch_arm
+#define ELF_TARGET_ID ARM_ELF_DATA
+#define ELF_MACHINE_CODE EM_ARM
+#ifdef __QNXTARGET__
+#define ELF_MAXPAGESIZE 0x1000
+#else
+#define ELF_MAXPAGESIZE 0x10000
+#endif
+#define ELF_MINPAGESIZE 0x1000
+#define ELF_COMMONPAGESIZE 0x1000
+
+#define bfd_elf32_mkobject elf32_arm_mkobject
+
+#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_bfd_reloc_name_lookup elf32_arm_reloc_name_lookup
+#define bfd_elf32_find_nearest_line elf32_arm_find_nearest_line
+#define bfd_elf32_find_inliner_info elf32_arm_find_inliner_info
+#define bfd_elf32_new_section_hook elf32_arm_new_section_hook
+#define bfd_elf32_bfd_is_target_special_symbol elf32_arm_is_target_special_symbol
+#define bfd_elf32_bfd_final_link elf32_arm_final_link
+#define bfd_elf32_get_synthetic_symtab elf32_arm_get_synthetic_symtab
+
+#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_mark_extra_sections elf32_arm_gc_mark_extra_sections
+#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_write_section elf32_arm_write_section
+#define elf_backend_adjust_dynamic_symbol elf32_arm_adjust_dynamic_symbol
+#define elf_backend_create_dynamic_sections elf32_arm_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_always_size_sections elf32_arm_always_size_sections
+#define elf_backend_init_index_section _bfd_elf_init_2_index_sections
+#define elf_backend_post_process_headers elf32_arm_post_process_headers
+#define elf_backend_reloc_type_class elf32_arm_reloc_type_class
+#define elf_backend_object_p elf32_arm_object_p
+#define elf_backend_fake_sections elf32_arm_fake_sections
+#define elf_backend_section_from_shdr elf32_arm_section_from_shdr
+#define elf_backend_final_write_processing elf32_arm_final_write_processing
+#define elf_backend_copy_indirect_symbol elf32_arm_copy_indirect_symbol
+#define elf_backend_size_info elf32_arm_size_info
+#define elf_backend_modify_segment_map elf32_arm_modify_segment_map
+#define elf_backend_additional_program_headers elf32_arm_additional_program_headers
+#define elf_backend_output_arch_local_syms elf32_arm_output_arch_local_syms
+#define elf_backend_begin_write_processing elf32_arm_begin_write_processing
+#define elf_backend_add_symbol_hook elf32_arm_add_symbol_hook
+
+#define elf_backend_can_refcount 1
+#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
+#define elf_backend_may_use_rel_p 1
+#define elf_backend_may_use_rela_p 0
+#define elf_backend_default_use_rela_p 0
+
+#define elf_backend_got_header_size 12
+
+#undef elf_backend_obj_attrs_vendor
+#define elf_backend_obj_attrs_vendor "aeabi"
+#undef elf_backend_obj_attrs_section
+#define elf_backend_obj_attrs_section ".ARM.attributes"
+#undef elf_backend_obj_attrs_arg_type
+#define elf_backend_obj_attrs_arg_type elf32_arm_obj_attrs_arg_type
+#undef elf_backend_obj_attrs_section_type
+#define elf_backend_obj_attrs_section_type SHT_ARM_ATTRIBUTES
+#define elf_backend_obj_attrs_order elf32_arm_obj_attrs_order
+#define elf_backend_obj_attrs_handle_unknown elf32_arm_obj_attrs_handle_unknown
+
+#include "elf32-target.h"
+
+/* Native Client targets. */
+
+#undef TARGET_LITTLE_SYM
+#define TARGET_LITTLE_SYM arm_elf32_nacl_le_vec
+#undef TARGET_LITTLE_NAME
+#define TARGET_LITTLE_NAME "elf32-littlearm-nacl"
+#undef TARGET_BIG_SYM
+#define TARGET_BIG_SYM arm_elf32_nacl_be_vec
+#undef TARGET_BIG_NAME
+#define TARGET_BIG_NAME "elf32-bigarm-nacl"
+
+/* Like elf32_arm_link_hash_table_create -- but overrides
+ appropriately for NaCl. */
+
+static struct bfd_link_hash_table *
+elf32_arm_nacl_link_hash_table_create (bfd *abfd)
+{
+ struct bfd_link_hash_table *ret;
+
+ ret = elf32_arm_link_hash_table_create (abfd);
+ if (ret)
+ {
+ struct elf32_arm_link_hash_table *htab
+ = (struct elf32_arm_link_hash_table *) ret;
+
+ htab->nacl_p = 1;
+
+ htab->plt_header_size = 4 * ARRAY_SIZE (elf32_arm_nacl_plt0_entry);
+ htab->plt_entry_size = 4 * ARRAY_SIZE (elf32_arm_nacl_plt_entry);
+ }
+ return ret;
+}
+
+/* Since NaCl doesn't use the ARM-specific unwind format, we don't
+ really need to use elf32_arm_modify_segment_map. But we do it
+ anyway just to reduce gratuitous differences with the stock ARM backend. */
+
+static bfd_boolean
+elf32_arm_nacl_modify_segment_map (bfd *abfd, struct bfd_link_info *info)
+{
+ return (elf32_arm_modify_segment_map (abfd, info)
+ && nacl_modify_segment_map (abfd, info));
+}
+
+static void
+elf32_arm_nacl_final_write_processing (bfd *abfd, bfd_boolean linker)
+{
+ elf32_arm_final_write_processing (abfd, linker);
+ nacl_final_write_processing (abfd, linker);
+}
+
+static bfd_vma
+elf32_arm_nacl_plt_sym_val (bfd_vma i, const asection *plt,
+ const arelent *rel ATTRIBUTE_UNUSED)
+{
+ return plt->vma
+ + 4 * (ARRAY_SIZE (elf32_arm_nacl_plt0_entry) +
+ i * ARRAY_SIZE (elf32_arm_nacl_plt_entry));
+}
+
+#undef elf32_bed
+#define elf32_bed elf32_arm_nacl_bed
+#undef bfd_elf32_bfd_link_hash_table_create
+#define bfd_elf32_bfd_link_hash_table_create \
+ elf32_arm_nacl_link_hash_table_create
+#undef elf_backend_plt_alignment
+#define elf_backend_plt_alignment 4
+#undef elf_backend_modify_segment_map
+#define elf_backend_modify_segment_map elf32_arm_nacl_modify_segment_map
+#undef elf_backend_modify_program_headers
+#define elf_backend_modify_program_headers nacl_modify_program_headers
+#undef elf_backend_final_write_processing
+#define elf_backend_final_write_processing elf32_arm_nacl_final_write_processing
+#undef bfd_elf32_get_synthetic_symtab
+#undef elf_backend_plt_sym_val
+#define elf_backend_plt_sym_val elf32_arm_nacl_plt_sym_val
+
+#undef ELF_MINPAGESIZE
+#undef ELF_COMMONPAGESIZE
+
+
+#include "elf32-target.h"
+
+/* Reset to defaults. */
+#undef elf_backend_plt_alignment
+#undef elf_backend_modify_segment_map
+#define elf_backend_modify_segment_map elf32_arm_modify_segment_map
+#undef elf_backend_modify_program_headers
+#undef elf_backend_final_write_processing
+#define elf_backend_final_write_processing elf32_arm_final_write_processing
+#undef ELF_MINPAGESIZE
+#define ELF_MINPAGESIZE 0x1000
+#undef ELF_COMMONPAGESIZE
+#define ELF_COMMONPAGESIZE 0x1000
+
+
+/* VxWorks Targets. */
+
+#undef TARGET_LITTLE_SYM
+#define TARGET_LITTLE_SYM arm_elf32_vxworks_le_vec
+#undef TARGET_LITTLE_NAME
+#define TARGET_LITTLE_NAME "elf32-littlearm-vxworks"
+#undef TARGET_BIG_SYM
+#define TARGET_BIG_SYM arm_elf32_vxworks_be_vec
+#undef TARGET_BIG_NAME
+#define TARGET_BIG_NAME "elf32-bigarm-vxworks"
+
+/* Like elf32_arm_link_hash_table_create -- but overrides
+ appropriately for VxWorks. */
+
+static struct bfd_link_hash_table *
+elf32_arm_vxworks_link_hash_table_create (bfd *abfd)
+{
+ struct bfd_link_hash_table *ret;
+
+ ret = elf32_arm_link_hash_table_create (abfd);
+ if (ret)
+ {
+ struct elf32_arm_link_hash_table *htab
+ = (struct elf32_arm_link_hash_table *) ret;
+ htab->use_rel = 0;
+ htab->vxworks_p = 1;
+ }
+ return ret;
+}
+
+static void
+elf32_arm_vxworks_final_write_processing (bfd *abfd, bfd_boolean linker)
+{
+ elf32_arm_final_write_processing (abfd, linker);
+ elf_vxworks_final_write_processing (abfd, linker);
+}
+
+#undef elf32_bed
+#define elf32_bed elf32_arm_vxworks_bed
+
+#undef bfd_elf32_bfd_link_hash_table_create
+#define bfd_elf32_bfd_link_hash_table_create elf32_arm_vxworks_link_hash_table_create
+#undef elf_backend_final_write_processing
+#define elf_backend_final_write_processing elf32_arm_vxworks_final_write_processing
+#undef elf_backend_emit_relocs
+#define elf_backend_emit_relocs elf_vxworks_emit_relocs
+
+#undef elf_backend_may_use_rel_p
+#define elf_backend_may_use_rel_p 0
+#undef elf_backend_may_use_rela_p
+#define elf_backend_may_use_rela_p 1
+#undef elf_backend_default_use_rela_p
+#define elf_backend_default_use_rela_p 1
+#undef elf_backend_want_plt_sym
+#define elf_backend_want_plt_sym 1
+#undef ELF_MAXPAGESIZE
+#define ELF_MAXPAGESIZE 0x1000
+
+#include "elf32-target.h"
+
+
+/* Merge backend specific data from an object file to the output
+ object file when linking. */
+
+static bfd_boolean
+elf32_arm_merge_private_bfd_data (bfd * ibfd, bfd * obfd)
+{
+ flagword out_flags;
+ flagword in_flags;
+ bfd_boolean flags_compatible = TRUE;
+ asection *sec;
+
+ /* Check if we have the same endianness. */
+ if (! _bfd_generic_verify_endian_match (ibfd, obfd))
+ return FALSE;
+
+ if (! is_arm_elf (ibfd) || ! is_arm_elf (obfd))
+ return TRUE;
+
+ if (!elf32_arm_merge_eabi_attributes (ibfd, obfd))
+ 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;
+
+ /* In theory there is no reason why we couldn't handle this. However
+ in practice it isn't even close to working and there is no real
+ reason to want it. */
+ if (EF_ARM_EABI_VERSION (in_flags) >= EF_ARM_EABI_VER4
+ && !(ibfd->flags & DYNAMIC)
+ && (in_flags & EF_ARM_BE8))
+ {
+ _bfd_error_handler (_("error: %B is already in final BE8 format"),
+ ibfd);
+ return FALSE;
+ }
+
+ if (!elf_flags_init (obfd))
+ {
+ /* If the input is the default architecture and had the default
+ flags 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
+ uninitialised values, which surprise surprise, correspond
+ to the default values. */
+ if (bfd_get_arch_info (ibfd)->the_default
+ && elf_elfheader (ibfd)->e_flags == 0)
+ 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;
+ }
+
+ /* Determine what should happen if the input ARM architecture
+ does not match the output ARM architecture. */
+ if (! bfd_arm_merge_machines (ibfd, obfd))
+ return FALSE;
+
+ /* Identical flags must be compatible. */
+ if (in_flags == out_flags)
+ return TRUE;
+
+ /* Check to see if the input BFD actually contains any sections. If
+ not, its flags may not have been initialised either, but it
+ cannot actually cause any incompatiblity. Do not short-circuit
+ dynamic objects; their section list may be emptied by
+ elf_link_add_object_symbols.
+
+ Also check to see if there are no code sections in the input.
+ In this case there is no need to check for code specific flags.
+ XXX - do we need to worry about floating-point format compatability
+ in data sections ? */
+ if (!(ibfd->flags & DYNAMIC))
+ {
+ bfd_boolean null_input_bfd = TRUE;
+ bfd_boolean only_data_sections = TRUE;
+
+ for (sec = ibfd->sections; sec != NULL; sec = sec->next)
+ {
+ /* Ignore synthetic glue sections. */
+ if (strcmp (sec->name, ".glue_7")
+ && strcmp (sec->name, ".glue_7t"))
+ {
+ if ((bfd_get_section_flags (ibfd, sec)
+ & (SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS))
+ == (SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS))
+ only_data_sections = FALSE;
+
+ null_input_bfd = FALSE;
+ break;
+ }
+ }
+
+ if (null_input_bfd || only_data_sections)
+ return TRUE;
+ }
+
+ /* Complain about various flag mismatches. */
+ if (!elf32_arm_versions_compatible (EF_ARM_EABI_VERSION (in_flags),
+ EF_ARM_EABI_VERSION (out_flags)))
+ {
+ _bfd_error_handler
+ (_("error: Source object %B has EABI version %d, but target %B has EABI version %d"),
+ ibfd, obfd,
+ (in_flags & EF_ARM_EABIMASK) >> 24,
+ (out_flags & EF_ARM_EABIMASK) >> 24);
+ return FALSE;
+ }
+
+ /* Not sure what needs to be checked for EABI versions >= 1. */
+ /* VxWorks libraries do not use these flags. */
+ if (get_elf_backend_data (obfd) != &elf32_arm_vxworks_bed
+ && get_elf_backend_data (ibfd) != &elf32_arm_vxworks_bed
+ && EF_ARM_EABI_VERSION (in_flags) == EF_ARM_EABI_UNKNOWN)
+ {
+ if ((in_flags & EF_ARM_APCS_26) != (out_flags & EF_ARM_APCS_26))
+ {
+ _bfd_error_handler
+ (_("error: %B is compiled for APCS-%d, whereas target %B uses APCS-%d"),
+ ibfd, obfd,
+ in_flags & EF_ARM_APCS_26 ? 26 : 32,
+ out_flags & EF_ARM_APCS_26 ? 26 : 32);
+ flags_compatible = FALSE;
+ }
+
+ if ((in_flags & EF_ARM_APCS_FLOAT) != (out_flags & EF_ARM_APCS_FLOAT))
+ {
+ if (in_flags & EF_ARM_APCS_FLOAT)
+ _bfd_error_handler
+ (_("error: %B passes floats in float registers, whereas %B passes them in integer registers"),
+ ibfd, obfd);
+ else
+ _bfd_error_handler
+ (_("error: %B passes floats in integer registers, whereas %B passes them in float registers"),
+ ibfd, obfd);
+
+ flags_compatible = FALSE;
+ }
+
+ if ((in_flags & EF_ARM_VFP_FLOAT) != (out_flags & EF_ARM_VFP_FLOAT))
+ {
+ if (in_flags & EF_ARM_VFP_FLOAT)
+ _bfd_error_handler
+ (_("error: %B uses VFP instructions, whereas %B does not"),
+ ibfd, obfd);
+ else
+ _bfd_error_handler
+ (_("error: %B uses FPA instructions, whereas %B does not"),
+ ibfd, obfd);
+
+ flags_compatible = FALSE;
+ }
+
+ if ((in_flags & EF_ARM_MAVERICK_FLOAT) != (out_flags & EF_ARM_MAVERICK_FLOAT))
+ {
+ if (in_flags & EF_ARM_MAVERICK_FLOAT)
+ _bfd_error_handler
+ (_("error: %B uses Maverick instructions, whereas %B does not"),
+ ibfd, obfd);
+ else
+ _bfd_error_handler
+ (_("error: %B does not use Maverick instructions, whereas %B does"),
+ ibfd, obfd);
+
+ flags_compatible = FALSE;
+ }
+
+#ifdef EF_ARM_SOFT_FLOAT
+ if ((in_flags & EF_ARM_SOFT_FLOAT) != (out_flags & EF_ARM_SOFT_FLOAT))
+ {
+ /* We can allow interworking between code that is VFP format
+ layout, and uses either soft float or integer regs for
+ passing floating point arguments and results. We already
+ know that the APCS_FLOAT flags match; similarly for VFP
+ flags. */
+ if ((in_flags & EF_ARM_APCS_FLOAT) != 0
+ || (in_flags & EF_ARM_VFP_FLOAT) == 0)
+ {
+ if (in_flags & EF_ARM_SOFT_FLOAT)
+ _bfd_error_handler
+ (_("error: %B uses software FP, whereas %B uses hardware FP"),
+ ibfd, obfd);
+ else
+ _bfd_error_handler
+ (_("error: %B uses hardware FP, whereas %B uses software FP"),
+ ibfd, obfd);
+
+ flags_compatible = FALSE;
+ }
+ }
+#endif
+
+ /* Interworking mismatch is only a warning. */
+ if ((in_flags & EF_ARM_INTERWORK) != (out_flags & EF_ARM_INTERWORK))
+ {
+ if (in_flags & EF_ARM_INTERWORK)
+ {
+ _bfd_error_handler
+ (_("Warning: %B supports interworking, whereas %B does not"),
+ ibfd, obfd);
+ }
+ else
+ {
+ _bfd_error_handler
+ (_("Warning: %B does not support interworking, whereas %B does"),
+ ibfd, obfd);
+ }
+ }
+ }
+
+ return flags_compatible;
+}
+
+
+/* Symbian OS Targets. */
+
+#undef TARGET_LITTLE_SYM
+#define TARGET_LITTLE_SYM arm_elf32_symbian_le_vec
+#undef TARGET_LITTLE_NAME
+#define TARGET_LITTLE_NAME "elf32-littlearm-symbian"
+#undef TARGET_BIG_SYM
+#define TARGET_BIG_SYM arm_elf32_symbian_be_vec
+#undef TARGET_BIG_NAME
+#define TARGET_BIG_NAME "elf32-bigarm-symbian"
+
+/* Like elf32_arm_link_hash_table_create -- but overrides
+ appropriately for Symbian OS. */
+
+static struct bfd_link_hash_table *
+elf32_arm_symbian_link_hash_table_create (bfd *abfd)
+{
+ struct bfd_link_hash_table *ret;
+
+ ret = elf32_arm_link_hash_table_create (abfd);
+ if (ret)
+ {
+ struct elf32_arm_link_hash_table *htab
+ = (struct elf32_arm_link_hash_table *)ret;
+ /* There is no PLT header for Symbian OS. */
+ htab->plt_header_size = 0;
+ /* The PLT entries are each one instruction and one word. */
+ htab->plt_entry_size = 4 * ARRAY_SIZE (elf32_arm_symbian_plt_entry);
+ htab->symbian_p = 1;
+ /* Symbian uses armv5t or above, so use_blx is always true. */
+ htab->use_blx = 1;
+ htab->root.is_relocatable_executable = 1;
+ }
+ return ret;
+}
+
+static const struct bfd_elf_special_section
+elf32_arm_symbian_special_sections[] =
+{
+ /* In a BPABI executable, the dynamic linking sections do not go in
+ the loadable read-only segment. The post-linker may wish to
+ refer to these sections, but they are not part of the final
+ program image. */
+ { STRING_COMMA_LEN (".dynamic"), 0, SHT_DYNAMIC, 0 },
+ { STRING_COMMA_LEN (".dynstr"), 0, SHT_STRTAB, 0 },
+ { STRING_COMMA_LEN (".dynsym"), 0, SHT_DYNSYM, 0 },
+ { STRING_COMMA_LEN (".got"), 0, SHT_PROGBITS, 0 },
+ { STRING_COMMA_LEN (".hash"), 0, SHT_HASH, 0 },
+ /* These sections do not need to be writable as the SymbianOS
+ postlinker will arrange things so that no dynamic relocation is
+ required. */
+ { STRING_COMMA_LEN (".init_array"), 0, SHT_INIT_ARRAY, SHF_ALLOC },
+ { STRING_COMMA_LEN (".fini_array"), 0, SHT_FINI_ARRAY, SHF_ALLOC },
+ { STRING_COMMA_LEN (".preinit_array"), 0, SHT_PREINIT_ARRAY, SHF_ALLOC },
+ { NULL, 0, 0, 0, 0 }
+};
+
+static void
+elf32_arm_symbian_begin_write_processing (bfd *abfd,
+ struct bfd_link_info *link_info)
+{
+ /* BPABI objects are never loaded directly by an OS kernel; they are
+ processed by a postlinker first, into an OS-specific format. If
+ the D_PAGED bit is set on the file, BFD will align segments on
+ page boundaries, so that an OS can directly map the file. With
+ BPABI objects, that just results in wasted space. In addition,
+ because we clear the D_PAGED bit, map_sections_to_segments will
+ recognize that the program headers should not be mapped into any
+ loadable segment. */
+ abfd->flags &= ~D_PAGED;
+ elf32_arm_begin_write_processing (abfd, link_info);
+}
+
+static bfd_boolean
+elf32_arm_symbian_modify_segment_map (bfd *abfd,
+ struct bfd_link_info *info)
+{
+ struct elf_segment_map *m;
+ asection *dynsec;
+
+ /* BPABI shared libraries and executables should have a PT_DYNAMIC
+ segment. However, because the .dynamic section is not marked
+ with SEC_LOAD, the generic ELF code will not create such a
+ segment. */
+ dynsec = bfd_get_section_by_name (abfd, ".dynamic");
+ if (dynsec)
+ {
+ for (m = elf_seg_map (abfd); m != NULL; m = m->next)
+ if (m->p_type == PT_DYNAMIC)
+ break;
+
+ if (m == NULL)
+ {
+ m = _bfd_elf_make_dynamic_segment (abfd, dynsec);
+ m->next = elf_seg_map (abfd);
+ elf_seg_map (abfd) = m;
+ }
+ }
+
+ /* Also call the generic arm routine. */
+ return elf32_arm_modify_segment_map (abfd, info);
+}
+
+/* Return address for Ith PLT stub in section PLT, for relocation REL
+ or (bfd_vma) -1 if it should not be included. */
+
+static bfd_vma
+elf32_arm_symbian_plt_sym_val (bfd_vma i, const asection *plt,
+ const arelent *rel ATTRIBUTE_UNUSED)
+{
+ return plt->vma + 4 * ARRAY_SIZE (elf32_arm_symbian_plt_entry) * i;
+}
+
+
+#undef elf32_bed
+#define elf32_bed elf32_arm_symbian_bed
+
+/* The dynamic sections are not allocated on SymbianOS; the postlinker
+ will process them and then discard them. */
+#undef ELF_DYNAMIC_SEC_FLAGS
+#define ELF_DYNAMIC_SEC_FLAGS \
+ (SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_LINKER_CREATED)
+
+#undef elf_backend_emit_relocs
+
+#undef bfd_elf32_bfd_link_hash_table_create
+#define bfd_elf32_bfd_link_hash_table_create elf32_arm_symbian_link_hash_table_create
+#undef elf_backend_special_sections
+#define elf_backend_special_sections elf32_arm_symbian_special_sections
+#undef elf_backend_begin_write_processing
+#define elf_backend_begin_write_processing elf32_arm_symbian_begin_write_processing
+#undef elf_backend_final_write_processing
+#define elf_backend_final_write_processing elf32_arm_final_write_processing
+
+#undef elf_backend_modify_segment_map
+#define elf_backend_modify_segment_map elf32_arm_symbian_modify_segment_map
+
+/* There is no .got section for BPABI objects, and hence no header. */
+#undef elf_backend_got_header_size
+#define elf_backend_got_header_size 0
+
+/* Similarly, there is no .got.plt section. */
+#undef elf_backend_want_got_plt
+#define elf_backend_want_got_plt 0
+
+#undef elf_backend_plt_sym_val
+#define elf_backend_plt_sym_val elf32_arm_symbian_plt_sym_val
+
+#undef elf_backend_may_use_rel_p
+#define elf_backend_may_use_rel_p 1
+#undef elf_backend_may_use_rela_p
+#define elf_backend_may_use_rela_p 0
+#undef elf_backend_default_use_rela_p
+#define elf_backend_default_use_rela_p 0
+#undef elf_backend_want_plt_sym
+#define elf_backend_want_plt_sym 0
+#undef ELF_MAXPAGESIZE
+#define ELF_MAXPAGESIZE 0x8000
+
+#include "elf32-target.h"
diff --git a/bfd/elf32-avr.c b/bfd/elf32-avr.c
new file mode 100644
index 0000000..54d67bf
--- /dev/null
+++ b/bfd/elf32-avr.c
@@ -0,0 +1,3348 @@
+/* AVR-specific support for 32-bit ELF
+ Copyright (C) 1999-2014 Free Software Foundation, Inc.
+ Contributed by Denis Chertykov <denisc@overta.ru>
+
+ This file is part of BFD, the Binary File Descriptor library.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor,
+ Boston, MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+#include "elf-bfd.h"
+#include "elf/avr.h"
+#include "elf32-avr.h"
+
+/* Enable debugging printout at stdout with this variable. */
+static bfd_boolean debug_relax = FALSE;
+
+/* Enable debugging printout at stdout with this variable. */
+static bfd_boolean debug_stubs = FALSE;
+
+static bfd_reloc_status_type
+bfd_elf_avr_diff_reloc (bfd *, arelent *, asymbol *, void *,
+ asection *, bfd *, char **);
+
+/* Hash table initialization and handling. Code is taken from the hppa port
+ and adapted to the needs of AVR. */
+
+/* We use two hash tables to hold information for linking avr objects.
+
+ The first is the elf32_avr_link_hash_table which is derived from the
+ stanard ELF linker hash table. We use this as a place to attach the other
+ hash table and some 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 on the linker
+ stubs. */
+
+struct elf32_avr_stub_hash_entry
+{
+ /* Base hash table entry structure. */
+ struct bfd_hash_entry bh_root;
+
+ /* Offset within stub_sec of the beginning of this stub. */
+ bfd_vma stub_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). */
+ bfd_vma target_value;
+
+ /* This way we could mark stubs to be no longer necessary. */
+ bfd_boolean is_actually_needed;
+};
+
+struct elf32_avr_link_hash_table
+{
+ /* The main hash table. */
+ struct elf_link_hash_table etab;
+
+ /* The stub hash table. */
+ struct bfd_hash_table bstab;
+
+ bfd_boolean no_stubs;
+
+ /* Linker stub bfd. */
+ bfd *stub_bfd;
+
+ /* The stub section. */
+ asection *stub_sec;
+
+ /* Usually 0, unless we are generating code for a bootloader. Will
+ be initialized by elf32_avr_size_stubs to the vma offset of the
+ output section associated with the stub section. */
+ bfd_vma vector_base;
+
+ /* Assorted information used by elf32_avr_size_stubs. */
+ unsigned int bfd_count;
+ int top_index;
+ asection ** input_list;
+ Elf_Internal_Sym ** all_local_syms;
+
+ /* Tables for mapping vma beyond the 128k boundary to the address of the
+ corresponding stub. (AMT)
+ "amt_max_entry_cnt" reflects the number of entries that memory is allocated
+ for in the "amt_stub_offsets" and "amt_destination_addr" arrays.
+ "amt_entry_cnt" informs how many of these entries actually contain
+ useful data. */
+ unsigned int amt_entry_cnt;
+ unsigned int amt_max_entry_cnt;
+ bfd_vma * amt_stub_offsets;
+ bfd_vma * amt_destination_addr;
+};
+
+/* Various hash macros and functions. */
+#define avr_link_hash_table(p) \
+ /* PR 3874: Check that we have an AVR style hash table before using it. */\
+ (elf_hash_table_id ((struct elf_link_hash_table *) ((p)->hash)) \
+ == AVR_ELF_DATA ? ((struct elf32_avr_link_hash_table *) ((p)->hash)) : NULL)
+
+#define avr_stub_hash_entry(ent) \
+ ((struct elf32_avr_stub_hash_entry *)(ent))
+
+#define avr_stub_hash_lookup(table, string, create, copy) \
+ ((struct elf32_avr_stub_hash_entry *) \
+ bfd_hash_lookup ((table), (string), (create), (copy)))
+
+static reloc_howto_type elf_avr_howto_table[] =
+{
+ HOWTO (R_AVR_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_AVR_NONE", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_AVR_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_AVR_32", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A 7 bit PC relative relocation. */
+ HOWTO (R_AVR_7_PCREL, /* type */
+ 1, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 7, /* bitsize */
+ TRUE, /* pc_relative */
+ 3, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_AVR_7_PCREL", /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* A 13 bit PC relative relocation. */
+ HOWTO (R_AVR_13_PCREL, /* type */
+ 1, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 13, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_AVR_13_PCREL", /* name */
+ FALSE, /* partial_inplace */
+ 0xfff, /* src_mask */
+ 0xfff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* A 16 bit absolute relocation. */
+ HOWTO (R_AVR_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_AVR_16", /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A 16 bit absolute relocation for command address
+ Will be changed when linker stubs are needed. */
+ HOWTO (R_AVR_16_PM, /* type */
+ 1, /* 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_AVR_16_PM", /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ /* A low 8 bit absolute relocation of 16 bit address.
+ For LDI command. */
+ HOWTO (R_AVR_LO8_LDI, /* type */
+ 0, /* rightshift */
+ 1, /* 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_AVR_LO8_LDI", /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ /* A high 8 bit absolute relocation of 16 bit address.
+ For LDI command. */
+ HOWTO (R_AVR_HI8_LDI, /* type */
+ 8, /* rightshift */
+ 1, /* 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_AVR_HI8_LDI", /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ /* A high 6 bit absolute relocation of 22 bit address.
+ For LDI command. As well second most significant 8 bit value of
+ a 32 bit link-time constant. */
+ HOWTO (R_AVR_HH8_LDI, /* type */
+ 16, /* rightshift */
+ 1, /* 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_AVR_HH8_LDI", /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ /* A negative low 8 bit absolute relocation of 16 bit address.
+ For LDI command. */
+ HOWTO (R_AVR_LO8_LDI_NEG, /* type */
+ 0, /* rightshift */
+ 1, /* 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_AVR_LO8_LDI_NEG", /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ /* A negative high 8 bit absolute relocation of 16 bit address.
+ For LDI command. */
+ HOWTO (R_AVR_HI8_LDI_NEG, /* type */
+ 8, /* rightshift */
+ 1, /* 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_AVR_HI8_LDI_NEG", /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ /* A negative high 6 bit absolute relocation of 22 bit address.
+ For LDI command. */
+ HOWTO (R_AVR_HH8_LDI_NEG, /* type */
+ 16, /* rightshift */
+ 1, /* 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_AVR_HH8_LDI_NEG", /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ /* A low 8 bit absolute relocation of 24 bit program memory address.
+ For LDI command. Will not be changed when linker stubs are needed. */
+ HOWTO (R_AVR_LO8_LDI_PM, /* type */
+ 1, /* rightshift */
+ 1, /* 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_AVR_LO8_LDI_PM", /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ /* A low 8 bit absolute relocation of 24 bit program memory address.
+ For LDI command. Will not be changed when linker stubs are needed. */
+ HOWTO (R_AVR_HI8_LDI_PM, /* type */
+ 9, /* rightshift */
+ 1, /* 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_AVR_HI8_LDI_PM", /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ /* A low 8 bit absolute relocation of 24 bit program memory address.
+ For LDI command. Will not be changed when linker stubs are needed. */
+ HOWTO (R_AVR_HH8_LDI_PM, /* type */
+ 17, /* rightshift */
+ 1, /* 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_AVR_HH8_LDI_PM", /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ /* A low 8 bit absolute relocation of 24 bit program memory address.
+ For LDI command. Will not be changed when linker stubs are needed. */
+ HOWTO (R_AVR_LO8_LDI_PM_NEG, /* type */
+ 1, /* rightshift */
+ 1, /* 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_AVR_LO8_LDI_PM_NEG", /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ /* A low 8 bit absolute relocation of 24 bit program memory address.
+ For LDI command. Will not be changed when linker stubs are needed. */
+ HOWTO (R_AVR_HI8_LDI_PM_NEG, /* type */
+ 9, /* rightshift */
+ 1, /* 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_AVR_HI8_LDI_PM_NEG", /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ /* A low 8 bit absolute relocation of 24 bit program memory address.
+ For LDI command. Will not be changed when linker stubs are needed. */
+ HOWTO (R_AVR_HH8_LDI_PM_NEG, /* type */
+ 17, /* rightshift */
+ 1, /* 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_AVR_HH8_LDI_PM_NEG", /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ /* Relocation for CALL command in ATmega. */
+ HOWTO (R_AVR_CALL, /* type */
+ 1, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 23, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_AVR_CALL", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ /* A 16 bit absolute relocation of 16 bit address.
+ For LDI command. */
+ HOWTO (R_AVR_LDI, /* 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_AVR_LDI", /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ /* A 6 bit absolute relocation of 6 bit offset.
+ For ldd/sdd command. */
+ HOWTO (R_AVR_6, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 6, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_AVR_6", /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ /* A 6 bit absolute relocation of 6 bit offset.
+ For sbiw/adiw command. */
+ HOWTO (R_AVR_6_ADIW, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 6, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_AVR_6_ADIW", /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ /* Most significant 8 bit value of a 32 bit link-time constant. */
+ HOWTO (R_AVR_MS8_LDI, /* type */
+ 24, /* rightshift */
+ 1, /* 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_AVR_MS8_LDI", /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ /* Negative most significant 8 bit value of a 32 bit link-time constant. */
+ HOWTO (R_AVR_MS8_LDI_NEG, /* type */
+ 24, /* rightshift */
+ 1, /* 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_AVR_MS8_LDI_NEG", /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ /* A low 8 bit absolute relocation of 24 bit program memory address.
+ For LDI command. Will be changed when linker stubs are needed. */
+ HOWTO (R_AVR_LO8_LDI_GS, /* type */
+ 1, /* rightshift */
+ 1, /* 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_AVR_LO8_LDI_GS", /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ /* A low 8 bit absolute relocation of 24 bit program memory address.
+ For LDI command. Will be changed when linker stubs are needed. */
+ HOWTO (R_AVR_HI8_LDI_GS, /* type */
+ 9, /* rightshift */
+ 1, /* 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_AVR_HI8_LDI_GS", /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ /* 8 bit offset. */
+ HOWTO (R_AVR_8, /* 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_AVR_8", /* name */
+ FALSE, /* partial_inplace */
+ 0x000000ff, /* src_mask */
+ 0x000000ff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ /* lo8-part to use in .byte lo8(sym). */
+ HOWTO (R_AVR_8_LO8, /* 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_AVR_8_LO8", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffff, /* src_mask */
+ 0xffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ /* hi8-part to use in .byte hi8(sym). */
+ HOWTO (R_AVR_8_HI8, /* type */
+ 8, /* 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_AVR_8_HI8", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffff, /* src_mask */
+ 0xffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ /* hlo8-part to use in .byte hlo8(sym). */
+ HOWTO (R_AVR_8_HLO8, /* type */
+ 16, /* 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_AVR_8_HLO8", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffff, /* src_mask */
+ 0xffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ HOWTO (R_AVR_DIFF8, /* 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_avr_diff_reloc, /* special_function */
+ "R_AVR_DIFF8", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ HOWTO (R_AVR_DIFF16, /* 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_avr_diff_reloc,/* special_function */
+ "R_AVR_DIFF16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ HOWTO (R_AVR_DIFF32, /* 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_avr_diff_reloc,/* special_function */
+ "R_AVR_DIFF32", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ /* 7 bit immediate for LDS/STS in Tiny core. */
+ HOWTO (R_AVR_LDS_STS_16, /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 7, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_AVR_LDS_STS_16", /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_AVR_PORT6, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 6, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_AVR_PORT6", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffff, /* src_mask */
+ 0xffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ HOWTO (R_AVR_PORT5, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 5, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_AVR_PORT5", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffff, /* src_mask */
+ 0xffffff, /* dst_mask */
+ FALSE) /* pcrel_offset */
+};
+
+/* Map BFD reloc types to AVR ELF reloc types. */
+
+struct avr_reloc_map
+{
+ bfd_reloc_code_real_type bfd_reloc_val;
+ unsigned int elf_reloc_val;
+};
+
+static const struct avr_reloc_map avr_reloc_map[] =
+{
+ { BFD_RELOC_NONE, R_AVR_NONE },
+ { BFD_RELOC_32, R_AVR_32 },
+ { BFD_RELOC_AVR_7_PCREL, R_AVR_7_PCREL },
+ { BFD_RELOC_AVR_13_PCREL, R_AVR_13_PCREL },
+ { BFD_RELOC_16, R_AVR_16 },
+ { BFD_RELOC_AVR_16_PM, R_AVR_16_PM },
+ { BFD_RELOC_AVR_LO8_LDI, R_AVR_LO8_LDI},
+ { BFD_RELOC_AVR_HI8_LDI, R_AVR_HI8_LDI },
+ { BFD_RELOC_AVR_HH8_LDI, R_AVR_HH8_LDI },
+ { BFD_RELOC_AVR_MS8_LDI, R_AVR_MS8_LDI },
+ { BFD_RELOC_AVR_LO8_LDI_NEG, R_AVR_LO8_LDI_NEG },
+ { BFD_RELOC_AVR_HI8_LDI_NEG, R_AVR_HI8_LDI_NEG },
+ { BFD_RELOC_AVR_HH8_LDI_NEG, R_AVR_HH8_LDI_NEG },
+ { BFD_RELOC_AVR_MS8_LDI_NEG, R_AVR_MS8_LDI_NEG },
+ { BFD_RELOC_AVR_LO8_LDI_PM, R_AVR_LO8_LDI_PM },
+ { BFD_RELOC_AVR_LO8_LDI_GS, R_AVR_LO8_LDI_GS },
+ { BFD_RELOC_AVR_HI8_LDI_PM, R_AVR_HI8_LDI_PM },
+ { BFD_RELOC_AVR_HI8_LDI_GS, R_AVR_HI8_LDI_GS },
+ { BFD_RELOC_AVR_HH8_LDI_PM, R_AVR_HH8_LDI_PM },
+ { BFD_RELOC_AVR_LO8_LDI_PM_NEG, R_AVR_LO8_LDI_PM_NEG },
+ { BFD_RELOC_AVR_HI8_LDI_PM_NEG, R_AVR_HI8_LDI_PM_NEG },
+ { BFD_RELOC_AVR_HH8_LDI_PM_NEG, R_AVR_HH8_LDI_PM_NEG },
+ { BFD_RELOC_AVR_CALL, R_AVR_CALL },
+ { BFD_RELOC_AVR_LDI, R_AVR_LDI },
+ { BFD_RELOC_AVR_6, R_AVR_6 },
+ { BFD_RELOC_AVR_6_ADIW, R_AVR_6_ADIW },
+ { BFD_RELOC_8, R_AVR_8 },
+ { BFD_RELOC_AVR_8_LO, R_AVR_8_LO8 },
+ { BFD_RELOC_AVR_8_HI, R_AVR_8_HI8 },
+ { BFD_RELOC_AVR_8_HLO, R_AVR_8_HLO8 },
+ { BFD_RELOC_AVR_DIFF8, R_AVR_DIFF8 },
+ { BFD_RELOC_AVR_DIFF16, R_AVR_DIFF16 },
+ { BFD_RELOC_AVR_DIFF32, R_AVR_DIFF32 },
+ { BFD_RELOC_AVR_LDS_STS_16, R_AVR_LDS_STS_16},
+ { BFD_RELOC_AVR_PORT6, R_AVR_PORT6},
+ { BFD_RELOC_AVR_PORT5, R_AVR_PORT5}
+};
+
+/* Meant to be filled one day with the wrap around address for the
+ specific device. I.e. should get the value 0x4000 for 16k devices,
+ 0x8000 for 32k devices and so on.
+
+ We initialize it here with a value of 0x1000000 resulting in
+ that we will never suggest a wrap-around jump during relaxation.
+ The logic of the source code later on assumes that in
+ avr_pc_wrap_around one single bit is set. */
+static bfd_vma avr_pc_wrap_around = 0x10000000;
+
+/* If this variable holds a value different from zero, the linker relaxation
+ machine will try to optimize call/ret sequences by a single jump
+ instruction. This option could be switched off by a linker switch. */
+static int avr_replace_call_ret_sequences = 1;
+
+/* Initialize an entry in the stub hash table. */
+
+static struct bfd_hash_entry *
+stub_hash_newfunc (struct bfd_hash_entry *entry,
+ struct bfd_hash_table *table,
+ const char *string)
+{
+ /* Allocate the structure if it has not already been allocated by a
+ subclass. */
+ if (entry == NULL)
+ {
+ entry = bfd_hash_allocate (table,
+ sizeof (struct elf32_avr_stub_hash_entry));
+ if (entry == NULL)
+ return entry;
+ }
+
+ /* Call the allocation method of the superclass. */
+ entry = bfd_hash_newfunc (entry, table, string);
+ if (entry != NULL)
+ {
+ struct elf32_avr_stub_hash_entry *hsh;
+
+ /* Initialize the local fields. */
+ hsh = avr_stub_hash_entry (entry);
+ hsh->stub_offset = 0;
+ hsh->target_value = 0;
+ }
+
+ return entry;
+}
+
+/* This function is just a straight passthrough to the real
+ function in linker.c. Its prupose is so that its address
+ can be compared inside the avr_link_hash_table macro. */
+
+static struct bfd_hash_entry *
+elf32_avr_link_hash_newfunc (struct bfd_hash_entry * entry,
+ struct bfd_hash_table * table,
+ const char * string)
+{
+ return _bfd_elf_link_hash_newfunc (entry, table, string);
+}
+
+/* Free the derived linker hash table. */
+
+static void
+elf32_avr_link_hash_table_free (bfd *obfd)
+{
+ struct elf32_avr_link_hash_table *htab
+ = (struct elf32_avr_link_hash_table *) obfd->link.hash;
+
+ /* Free the address mapping table. */
+ if (htab->amt_stub_offsets != NULL)
+ free (htab->amt_stub_offsets);
+ if (htab->amt_destination_addr != NULL)
+ free (htab->amt_destination_addr);
+
+ bfd_hash_table_free (&htab->bstab);
+ _bfd_elf_link_hash_table_free (obfd);
+}
+
+/* Create the derived linker hash table. The AVR ELF port uses the derived
+ hash table to keep information specific to the AVR ELF linker (without
+ using static variables). */
+
+static struct bfd_link_hash_table *
+elf32_avr_link_hash_table_create (bfd *abfd)
+{
+ struct elf32_avr_link_hash_table *htab;
+ bfd_size_type amt = sizeof (*htab);
+
+ htab = bfd_zmalloc (amt);
+ if (htab == NULL)
+ return NULL;
+
+ if (!_bfd_elf_link_hash_table_init (&htab->etab, abfd,
+ elf32_avr_link_hash_newfunc,
+ sizeof (struct elf_link_hash_entry),
+ AVR_ELF_DATA))
+ {
+ free (htab);
+ return NULL;
+ }
+
+ /* Init the stub hash table too. */
+ if (!bfd_hash_table_init (&htab->bstab, stub_hash_newfunc,
+ sizeof (struct elf32_avr_stub_hash_entry)))
+ {
+ _bfd_elf_link_hash_table_free (abfd);
+ return NULL;
+ }
+ htab->etab.root.hash_table_free = elf32_avr_link_hash_table_free;
+
+ return &htab->etab.root;
+}
+
+/* Calculates the effective distance of a pc relative jump/call. */
+
+static int
+avr_relative_distance_considering_wrap_around (unsigned int distance)
+{
+ unsigned int wrap_around_mask = avr_pc_wrap_around - 1;
+ int dist_with_wrap_around = distance & wrap_around_mask;
+
+ if (dist_with_wrap_around > ((int) (avr_pc_wrap_around >> 1)))
+ dist_with_wrap_around -= avr_pc_wrap_around;
+
+ return dist_with_wrap_around;
+}
+
+
+static reloc_howto_type *
+bfd_elf32_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ bfd_reloc_code_real_type code)
+{
+ unsigned int i;
+
+ for (i = 0;
+ i < sizeof (avr_reloc_map) / sizeof (struct avr_reloc_map);
+ i++)
+ if (avr_reloc_map[i].bfd_reloc_val == code)
+ return &elf_avr_howto_table[avr_reloc_map[i].elf_reloc_val];
+
+ return NULL;
+}
+
+static reloc_howto_type *
+bfd_elf32_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ const char *r_name)
+{
+ unsigned int i;
+
+ for (i = 0;
+ i < sizeof (elf_avr_howto_table) / sizeof (elf_avr_howto_table[0]);
+ i++)
+ if (elf_avr_howto_table[i].name != NULL
+ && strcasecmp (elf_avr_howto_table[i].name, r_name) == 0)
+ return &elf_avr_howto_table[i];
+
+ return NULL;
+}
+
+/* Set the howto pointer for an AVR ELF reloc. */
+
+static void
+avr_info_to_howto_rela (bfd *abfd ATTRIBUTE_UNUSED,
+ arelent *cache_ptr,
+ Elf_Internal_Rela *dst)
+{
+ unsigned int r_type;
+
+ r_type = ELF32_R_TYPE (dst->r_info);
+ BFD_ASSERT (r_type < (unsigned int) R_AVR_max);
+ cache_ptr->howto = &elf_avr_howto_table[r_type];
+}
+
+static bfd_boolean
+avr_stub_is_required_for_16_bit_reloc (bfd_vma relocation)
+{
+ return (relocation >= 0x020000);
+}
+
+/* Returns the address of the corresponding stub if there is one.
+ Returns otherwise an address above 0x020000. This function
+ could also be used, if there is no knowledge on the section where
+ the destination is found. */
+
+static bfd_vma
+avr_get_stub_addr (bfd_vma srel,
+ struct elf32_avr_link_hash_table *htab)
+{
+ unsigned int sindex;
+ bfd_vma stub_sec_addr =
+ (htab->stub_sec->output_section->vma +
+ htab->stub_sec->output_offset);
+
+ for (sindex = 0; sindex < htab->amt_max_entry_cnt; sindex ++)
+ if (htab->amt_destination_addr[sindex] == srel)
+ return htab->amt_stub_offsets[sindex] + stub_sec_addr;
+
+ /* Return an address that could not be reached by 16 bit relocs. */
+ return 0x020000;
+}
+
+/* Perform a diff relocation. Nothing to do, as the difference value is already
+ written into the section's contents. */
+
+static bfd_reloc_status_type
+bfd_elf_avr_diff_reloc (bfd *abfd ATTRIBUTE_UNUSED,
+ arelent *reloc_entry ATTRIBUTE_UNUSED,
+ asymbol *symbol ATTRIBUTE_UNUSED,
+ void *data ATTRIBUTE_UNUSED,
+ asection *input_section ATTRIBUTE_UNUSED,
+ bfd *output_bfd ATTRIBUTE_UNUSED,
+ char **error_message ATTRIBUTE_UNUSED)
+{
+ return bfd_reloc_ok;
+}
+
+
+/* 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
+avr_final_link_relocate (reloc_howto_type * howto,
+ bfd * input_bfd,
+ asection * input_section,
+ bfd_byte * contents,
+ Elf_Internal_Rela * rel,
+ bfd_vma relocation,
+ struct elf32_avr_link_hash_table * htab)
+{
+ bfd_reloc_status_type r = bfd_reloc_ok;
+ bfd_vma x;
+ bfd_signed_vma srel;
+ bfd_signed_vma reloc_addr;
+ bfd_boolean use_stubs = FALSE;
+ /* Usually is 0, unless we are generating code for a bootloader. */
+ bfd_signed_vma base_addr = htab->vector_base;
+
+ /* Absolute addr of the reloc in the final excecutable. */
+ reloc_addr = rel->r_offset + input_section->output_section->vma
+ + input_section->output_offset;
+
+ switch (howto->type)
+ {
+ case R_AVR_7_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 << 7) - 1) || (srel < - (1 << 7)))
+ return bfd_reloc_overflow;
+ x = bfd_get_16 (input_bfd, contents);
+ x = (x & 0xfc07) | (((srel >> 1) << 3) & 0x3f8);
+ bfd_put_16 (input_bfd, x, contents);
+ break;
+
+ case R_AVR_13_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;
+
+ srel = avr_relative_distance_considering_wrap_around (srel);
+
+ /* AVR addresses commands as words. */
+ srel >>= 1;
+
+ /* Check for overflow. */
+ if (srel < -2048 || srel > 2047)
+ {
+ /* Relative distance is too large. */
+
+ /* Always apply WRAPAROUND for avr2, avr25, and avr4. */
+ switch (bfd_get_mach (input_bfd))
+ {
+ case bfd_mach_avr2:
+ case bfd_mach_avr25:
+ case bfd_mach_avr4:
+ break;
+
+ default:
+ return bfd_reloc_overflow;
+ }
+ }
+
+ x = bfd_get_16 (input_bfd, contents);
+ x = (x & 0xf000) | (srel & 0xfff);
+ bfd_put_16 (input_bfd, x, contents);
+ break;
+
+ case R_AVR_LO8_LDI:
+ contents += rel->r_offset;
+ srel = (bfd_signed_vma) relocation + rel->r_addend;
+ x = bfd_get_16 (input_bfd, contents);
+ x = (x & 0xf0f0) | (srel & 0xf) | ((srel << 4) & 0xf00);
+ bfd_put_16 (input_bfd, x, contents);
+ break;
+
+ case R_AVR_LDI:
+ contents += rel->r_offset;
+ srel = (bfd_signed_vma) relocation + rel->r_addend;
+ if (((srel > 0) && (srel & 0xffff) > 255)
+ || ((srel < 0) && ((-srel) & 0xffff) > 128))
+ /* Remove offset for data/eeprom section. */
+ return bfd_reloc_overflow;
+
+ x = bfd_get_16 (input_bfd, contents);
+ x = (x & 0xf0f0) | (srel & 0xf) | ((srel << 4) & 0xf00);
+ bfd_put_16 (input_bfd, x, contents);
+ break;
+
+ case R_AVR_6:
+ contents += rel->r_offset;
+ srel = (bfd_signed_vma) relocation + rel->r_addend;
+ if (((srel & 0xffff) > 63) || (srel < 0))
+ /* Remove offset for data/eeprom section. */
+ return bfd_reloc_overflow;
+ x = bfd_get_16 (input_bfd, contents);
+ x = (x & 0xd3f8) | ((srel & 7) | ((srel & (3 << 3)) << 7)
+ | ((srel & (1 << 5)) << 8));
+ bfd_put_16 (input_bfd, x, contents);
+ break;
+
+ case R_AVR_6_ADIW:
+ contents += rel->r_offset;
+ srel = (bfd_signed_vma) relocation + rel->r_addend;
+ if (((srel & 0xffff) > 63) || (srel < 0))
+ /* Remove offset for data/eeprom section. */
+ return bfd_reloc_overflow;
+ x = bfd_get_16 (input_bfd, contents);
+ x = (x & 0xff30) | (srel & 0xf) | ((srel & 0x30) << 2);
+ bfd_put_16 (input_bfd, x, contents);
+ break;
+
+ case R_AVR_HI8_LDI:
+ contents += rel->r_offset;
+ srel = (bfd_signed_vma) relocation + rel->r_addend;
+ srel = (srel >> 8) & 0xff;
+ x = bfd_get_16 (input_bfd, contents);
+ x = (x & 0xf0f0) | (srel & 0xf) | ((srel << 4) & 0xf00);
+ bfd_put_16 (input_bfd, x, contents);
+ break;
+
+ case R_AVR_HH8_LDI:
+ contents += rel->r_offset;
+ srel = (bfd_signed_vma) relocation + rel->r_addend;
+ srel = (srel >> 16) & 0xff;
+ x = bfd_get_16 (input_bfd, contents);
+ x = (x & 0xf0f0) | (srel & 0xf) | ((srel << 4) & 0xf00);
+ bfd_put_16 (input_bfd, x, contents);
+ break;
+
+ case R_AVR_MS8_LDI:
+ contents += rel->r_offset;
+ srel = (bfd_signed_vma) relocation + rel->r_addend;
+ srel = (srel >> 24) & 0xff;
+ x = bfd_get_16 (input_bfd, contents);
+ x = (x & 0xf0f0) | (srel & 0xf) | ((srel << 4) & 0xf00);
+ bfd_put_16 (input_bfd, x, contents);
+ break;
+
+ case R_AVR_LO8_LDI_NEG:
+ contents += rel->r_offset;
+ srel = (bfd_signed_vma) relocation + rel->r_addend;
+ srel = -srel;
+ x = bfd_get_16 (input_bfd, contents);
+ x = (x & 0xf0f0) | (srel & 0xf) | ((srel << 4) & 0xf00);
+ bfd_put_16 (input_bfd, x, contents);
+ break;
+
+ case R_AVR_HI8_LDI_NEG:
+ contents += rel->r_offset;
+ srel = (bfd_signed_vma) relocation + rel->r_addend;
+ srel = -srel;
+ srel = (srel >> 8) & 0xff;
+ x = bfd_get_16 (input_bfd, contents);
+ x = (x & 0xf0f0) | (srel & 0xf) | ((srel << 4) & 0xf00);
+ bfd_put_16 (input_bfd, x, contents);
+ break;
+
+ case R_AVR_HH8_LDI_NEG:
+ contents += rel->r_offset;
+ srel = (bfd_signed_vma) relocation + rel->r_addend;
+ srel = -srel;
+ srel = (srel >> 16) & 0xff;
+ x = bfd_get_16 (input_bfd, contents);
+ x = (x & 0xf0f0) | (srel & 0xf) | ((srel << 4) & 0xf00);
+ bfd_put_16 (input_bfd, x, contents);
+ break;
+
+ case R_AVR_MS8_LDI_NEG:
+ contents += rel->r_offset;
+ srel = (bfd_signed_vma) relocation + rel->r_addend;
+ srel = -srel;
+ srel = (srel >> 24) & 0xff;
+ x = bfd_get_16 (input_bfd, contents);
+ x = (x & 0xf0f0) | (srel & 0xf) | ((srel << 4) & 0xf00);
+ bfd_put_16 (input_bfd, x, contents);
+ break;
+
+ case R_AVR_LO8_LDI_GS:
+ use_stubs = (!htab->no_stubs);
+ /* Fall through. */
+ case R_AVR_LO8_LDI_PM:
+ contents += rel->r_offset;
+ srel = (bfd_signed_vma) relocation + rel->r_addend;
+
+ if (use_stubs
+ && avr_stub_is_required_for_16_bit_reloc (srel - base_addr))
+ {
+ bfd_vma old_srel = srel;
+
+ /* We need to use the address of the stub instead. */
+ srel = avr_get_stub_addr (srel, htab);
+ if (debug_stubs)
+ printf ("LD: Using jump stub (at 0x%x) with destination 0x%x for "
+ "reloc at address 0x%x.\n",
+ (unsigned int) srel,
+ (unsigned int) old_srel,
+ (unsigned int) reloc_addr);
+
+ if (avr_stub_is_required_for_16_bit_reloc (srel - base_addr))
+ return bfd_reloc_outofrange;
+ }
+
+ if (srel & 1)
+ return bfd_reloc_outofrange;
+ srel = srel >> 1;
+ x = bfd_get_16 (input_bfd, contents);
+ x = (x & 0xf0f0) | (srel & 0xf) | ((srel << 4) & 0xf00);
+ bfd_put_16 (input_bfd, x, contents);
+ break;
+
+ case R_AVR_HI8_LDI_GS:
+ use_stubs = (!htab->no_stubs);
+ /* Fall through. */
+ case R_AVR_HI8_LDI_PM:
+ contents += rel->r_offset;
+ srel = (bfd_signed_vma) relocation + rel->r_addend;
+
+ if (use_stubs
+ && avr_stub_is_required_for_16_bit_reloc (srel - base_addr))
+ {
+ bfd_vma old_srel = srel;
+
+ /* We need to use the address of the stub instead. */
+ srel = avr_get_stub_addr (srel, htab);
+ if (debug_stubs)
+ printf ("LD: Using jump stub (at 0x%x) with destination 0x%x for "
+ "reloc at address 0x%x.\n",
+ (unsigned int) srel,
+ (unsigned int) old_srel,
+ (unsigned int) reloc_addr);
+
+ if (avr_stub_is_required_for_16_bit_reloc (srel - base_addr))
+ return bfd_reloc_outofrange;
+ }
+
+ if (srel & 1)
+ return bfd_reloc_outofrange;
+ srel = srel >> 1;
+ srel = (srel >> 8) & 0xff;
+ x = bfd_get_16 (input_bfd, contents);
+ x = (x & 0xf0f0) | (srel & 0xf) | ((srel << 4) & 0xf00);
+ bfd_put_16 (input_bfd, x, contents);
+ break;
+
+ case R_AVR_HH8_LDI_PM:
+ contents += rel->r_offset;
+ srel = (bfd_signed_vma) relocation + rel->r_addend;
+ if (srel & 1)
+ return bfd_reloc_outofrange;
+ srel = srel >> 1;
+ srel = (srel >> 16) & 0xff;
+ x = bfd_get_16 (input_bfd, contents);
+ x = (x & 0xf0f0) | (srel & 0xf) | ((srel << 4) & 0xf00);
+ bfd_put_16 (input_bfd, x, contents);
+ break;
+
+ case R_AVR_LO8_LDI_PM_NEG:
+ contents += rel->r_offset;
+ srel = (bfd_signed_vma) relocation + rel->r_addend;
+ srel = -srel;
+ if (srel & 1)
+ return bfd_reloc_outofrange;
+ srel = srel >> 1;
+ x = bfd_get_16 (input_bfd, contents);
+ x = (x & 0xf0f0) | (srel & 0xf) | ((srel << 4) & 0xf00);
+ bfd_put_16 (input_bfd, x, contents);
+ break;
+
+ case R_AVR_HI8_LDI_PM_NEG:
+ contents += rel->r_offset;
+ srel = (bfd_signed_vma) relocation + rel->r_addend;
+ srel = -srel;
+ if (srel & 1)
+ return bfd_reloc_outofrange;
+ srel = srel >> 1;
+ srel = (srel >> 8) & 0xff;
+ x = bfd_get_16 (input_bfd, contents);
+ x = (x & 0xf0f0) | (srel & 0xf) | ((srel << 4) & 0xf00);
+ bfd_put_16 (input_bfd, x, contents);
+ break;
+
+ case R_AVR_HH8_LDI_PM_NEG:
+ contents += rel->r_offset;
+ srel = (bfd_signed_vma) relocation + rel->r_addend;
+ srel = -srel;
+ if (srel & 1)
+ return bfd_reloc_outofrange;
+ srel = srel >> 1;
+ srel = (srel >> 16) & 0xff;
+ x = bfd_get_16 (input_bfd, contents);
+ x = (x & 0xf0f0) | (srel & 0xf) | ((srel << 4) & 0xf00);
+ bfd_put_16 (input_bfd, x, contents);
+ break;
+
+ case R_AVR_CALL:
+ contents += rel->r_offset;
+ srel = (bfd_signed_vma) relocation + rel->r_addend;
+ if (srel & 1)
+ return bfd_reloc_outofrange;
+ srel = srel >> 1;
+ x = bfd_get_16 (input_bfd, contents);
+ x |= ((srel & 0x10000) | ((srel << 3) & 0x1f00000)) >> 16;
+ bfd_put_16 (input_bfd, x, contents);
+ bfd_put_16 (input_bfd, (bfd_vma) srel & 0xffff, contents+2);
+ break;
+
+ case R_AVR_16_PM:
+ use_stubs = (!htab->no_stubs);
+ contents += rel->r_offset;
+ srel = (bfd_signed_vma) relocation + rel->r_addend;
+
+ if (use_stubs
+ && avr_stub_is_required_for_16_bit_reloc (srel - base_addr))
+ {
+ bfd_vma old_srel = srel;
+
+ /* We need to use the address of the stub instead. */
+ srel = avr_get_stub_addr (srel,htab);
+ if (debug_stubs)
+ printf ("LD: Using jump stub (at 0x%x) with destination 0x%x for "
+ "reloc at address 0x%x.\n",
+ (unsigned int) srel,
+ (unsigned int) old_srel,
+ (unsigned int) reloc_addr);
+
+ if (avr_stub_is_required_for_16_bit_reloc (srel - base_addr))
+ return bfd_reloc_outofrange;
+ }
+
+ if (srel & 1)
+ return bfd_reloc_outofrange;
+ srel = srel >> 1;
+ bfd_put_16 (input_bfd, (bfd_vma) srel &0x00ffff, contents);
+ break;
+
+ case R_AVR_DIFF8:
+ case R_AVR_DIFF16:
+ case R_AVR_DIFF32:
+ /* Nothing to do here, as contents already contains the diff value. */
+ r = bfd_reloc_ok;
+ break;
+
+ case R_AVR_LDS_STS_16:
+ contents += rel->r_offset;
+ srel = (bfd_signed_vma) relocation + rel->r_addend;
+ if ((srel & 0xFFFF) < 0x40 || (srel & 0xFFFF) > 0xbf)
+ return bfd_reloc_outofrange;
+ srel = srel & 0x7f;
+ x = bfd_get_16 (input_bfd, contents);
+ x |= (srel & 0x0f) | ((srel & 0x30) << 5) | ((srel & 0x40) << 2);
+ bfd_put_16 (input_bfd, x, contents);
+ break;
+
+ case R_AVR_PORT6:
+ contents += rel->r_offset;
+ srel = (bfd_signed_vma) relocation + rel->r_addend;
+ if ((srel & 0xffff) > 0x3f)
+ return bfd_reloc_outofrange;
+ x = bfd_get_16 (input_bfd, contents);
+ x = (x & 0xf9f0) | ((srel & 0x30) << 5) | (srel & 0x0f);
+ bfd_put_16 (input_bfd, x, contents);
+ break;
+
+ case R_AVR_PORT5:
+ contents += rel->r_offset;
+ srel = (bfd_signed_vma) relocation + rel->r_addend;
+ if ((srel & 0xffff) > 0x1f)
+ return bfd_reloc_outofrange;
+ x = bfd_get_16 (input_bfd, contents);
+ x = (x & 0xff07) | ((srel & 0x1f) << 3);
+ 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 AVR ELF section. */
+
+static bfd_boolean
+elf32_avr_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
+ 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;
+ struct elf32_avr_link_hash_table * htab = avr_link_hash_table (info);
+
+ if (htab == NULL)
+ return FALSE;
+
+ 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;
+ int r_type;
+
+ r_type = ELF32_R_TYPE (rel->r_info);
+ r_symndx = ELF32_R_SYM (rel->r_info);
+ howto = elf_avr_howto_table + r_type;
+ h = NULL;
+ sym = NULL;
+ sec = NULL;
+
+ if (r_symndx < symtab_hdr->sh_info)
+ {
+ sym = local_syms + r_symndx;
+ sec = local_sections [r_symndx];
+ relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
+
+ 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;
+ }
+ else
+ {
+ bfd_boolean unresolved_reloc, warned, ignored;
+
+ RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
+ r_symndx, symtab_hdr, sym_hashes,
+ h, sec, relocation,
+ unresolved_reloc, warned, ignored);
+
+ name = h->root.root.string;
+ }
+
+ if (sec != NULL && discarded_section (sec))
+ RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+ rel, 1, relend, howto, 0, contents);
+
+ if (info->relocatable)
+ continue;
+
+ r = avr_final_link_relocate (howto, input_bfd, input_section,
+ contents, rel, relocation, htab);
+
+ if (r != bfd_reloc_ok)
+ {
+ const char * msg = (const char *) NULL;
+
+ switch (r)
+ {
+ case bfd_reloc_overflow:
+ r = info->callbacks->reloc_overflow
+ (info, (h ? &h->root : NULL),
+ 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, TRUE);
+ 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;
+}
+
+/* The final processing done just before writing out a AVR ELF object
+ file. This gets the AVR architecture right based on the machine
+ number. */
+
+static void
+bfd_elf_avr_final_write_processing (bfd *abfd,
+ bfd_boolean linker ATTRIBUTE_UNUSED)
+{
+ unsigned long val;
+
+ switch (bfd_get_mach (abfd))
+ {
+ default:
+ case bfd_mach_avr2:
+ val = E_AVR_MACH_AVR2;
+ break;
+
+ case bfd_mach_avr1:
+ val = E_AVR_MACH_AVR1;
+ break;
+
+ case bfd_mach_avr25:
+ val = E_AVR_MACH_AVR25;
+ break;
+
+ case bfd_mach_avr3:
+ val = E_AVR_MACH_AVR3;
+ break;
+
+ case bfd_mach_avr31:
+ val = E_AVR_MACH_AVR31;
+ break;
+
+ case bfd_mach_avr35:
+ val = E_AVR_MACH_AVR35;
+ break;
+
+ case bfd_mach_avr4:
+ val = E_AVR_MACH_AVR4;
+ break;
+
+ case bfd_mach_avr5:
+ val = E_AVR_MACH_AVR5;
+ break;
+
+ case bfd_mach_avr51:
+ val = E_AVR_MACH_AVR51;
+ break;
+
+ case bfd_mach_avr6:
+ val = E_AVR_MACH_AVR6;
+ break;
+
+ case bfd_mach_avrxmega1:
+ val = E_AVR_MACH_XMEGA1;
+ break;
+
+ case bfd_mach_avrxmega2:
+ val = E_AVR_MACH_XMEGA2;
+ break;
+
+ case bfd_mach_avrxmega3:
+ val = E_AVR_MACH_XMEGA3;
+ break;
+
+ case bfd_mach_avrxmega4:
+ val = E_AVR_MACH_XMEGA4;
+ break;
+
+ case bfd_mach_avrxmega5:
+ val = E_AVR_MACH_XMEGA5;
+ break;
+
+ case bfd_mach_avrxmega6:
+ val = E_AVR_MACH_XMEGA6;
+ break;
+
+ case bfd_mach_avrxmega7:
+ val = E_AVR_MACH_XMEGA7;
+ break;
+
+ case bfd_mach_avrtiny:
+ val = E_AVR_MACH_AVRTINY;
+ break;
+ }
+
+ elf_elfheader (abfd)->e_machine = EM_AVR;
+ elf_elfheader (abfd)->e_flags &= ~ EF_AVR_MACH;
+ elf_elfheader (abfd)->e_flags |= val;
+ elf_elfheader (abfd)->e_flags |= EF_AVR_LINKRELAX_PREPARED;
+}
+
+/* Set the right machine number. */
+
+static bfd_boolean
+elf32_avr_object_p (bfd *abfd)
+{
+ unsigned int e_set = bfd_mach_avr2;
+
+ if (elf_elfheader (abfd)->e_machine == EM_AVR
+ || elf_elfheader (abfd)->e_machine == EM_AVR_OLD)
+ {
+ int e_mach = elf_elfheader (abfd)->e_flags & EF_AVR_MACH;
+
+ switch (e_mach)
+ {
+ default:
+ case E_AVR_MACH_AVR2:
+ e_set = bfd_mach_avr2;
+ break;
+
+ case E_AVR_MACH_AVR1:
+ e_set = bfd_mach_avr1;
+ break;
+
+ case E_AVR_MACH_AVR25:
+ e_set = bfd_mach_avr25;
+ break;
+
+ case E_AVR_MACH_AVR3:
+ e_set = bfd_mach_avr3;
+ break;
+
+ case E_AVR_MACH_AVR31:
+ e_set = bfd_mach_avr31;
+ break;
+
+ case E_AVR_MACH_AVR35:
+ e_set = bfd_mach_avr35;
+ break;
+
+ case E_AVR_MACH_AVR4:
+ e_set = bfd_mach_avr4;
+ break;
+
+ case E_AVR_MACH_AVR5:
+ e_set = bfd_mach_avr5;
+ break;
+
+ case E_AVR_MACH_AVR51:
+ e_set = bfd_mach_avr51;
+ break;
+
+ case E_AVR_MACH_AVR6:
+ e_set = bfd_mach_avr6;
+ break;
+
+ case E_AVR_MACH_XMEGA1:
+ e_set = bfd_mach_avrxmega1;
+ break;
+
+ case E_AVR_MACH_XMEGA2:
+ e_set = bfd_mach_avrxmega2;
+ break;
+
+ case E_AVR_MACH_XMEGA3:
+ e_set = bfd_mach_avrxmega3;
+ break;
+
+ case E_AVR_MACH_XMEGA4:
+ e_set = bfd_mach_avrxmega4;
+ break;
+
+ case E_AVR_MACH_XMEGA5:
+ e_set = bfd_mach_avrxmega5;
+ break;
+
+ case E_AVR_MACH_XMEGA6:
+ e_set = bfd_mach_avrxmega6;
+ break;
+
+ case E_AVR_MACH_XMEGA7:
+ e_set = bfd_mach_avrxmega7;
+ break;
+
+ case E_AVR_MACH_AVRTINY:
+ e_set = bfd_mach_avrtiny;
+ break;
+ }
+ }
+ return bfd_default_set_arch_mach (abfd, bfd_arch_avr,
+ e_set);
+}
+
+/* Returns whether the relocation type passed is a diff reloc. */
+
+static bfd_boolean
+elf32_avr_is_diff_reloc (Elf_Internal_Rela *irel)
+{
+ return (ELF32_R_TYPE (irel->r_info) == R_AVR_DIFF8
+ ||ELF32_R_TYPE (irel->r_info) == R_AVR_DIFF16
+ || ELF32_R_TYPE (irel->r_info) == R_AVR_DIFF32);
+}
+
+/* Reduce the diff value written in the section by count if the shrinked
+ insn address happens to fall between the two symbols for which this
+ diff reloc was emitted. */
+
+static void
+elf32_avr_adjust_diff_reloc_value (bfd *abfd,
+ struct bfd_section *isec,
+ Elf_Internal_Rela *irel,
+ bfd_vma symval,
+ bfd_vma shrinked_insn_address,
+ int count)
+{
+ unsigned char *reloc_contents = NULL;
+ unsigned char *isec_contents = elf_section_data (isec)->this_hdr.contents;
+ if (isec_contents == NULL)
+ {
+ if (! bfd_malloc_and_get_section (abfd, isec, &isec_contents))
+ return;
+
+ elf_section_data (isec)->this_hdr.contents = isec_contents;
+ }
+
+ reloc_contents = isec_contents + irel->r_offset;
+
+ /* Read value written in object file. */
+ bfd_vma x = 0;
+ switch (ELF32_R_TYPE (irel->r_info))
+ {
+ case R_AVR_DIFF8:
+ {
+ x = *reloc_contents;
+ break;
+ }
+ case R_AVR_DIFF16:
+ {
+ x = bfd_get_16 (abfd, reloc_contents);
+ break;
+ }
+ case R_AVR_DIFF32:
+ {
+ x = bfd_get_32 (abfd, reloc_contents);
+ break;
+ }
+ default:
+ {
+ BFD_FAIL();
+ }
+ }
+
+ /* For a diff reloc sym1 - sym2 the diff at assembly time (x) is written
+ into the object file at the reloc offset. sym2's logical value is
+ symval (<start_of_section>) + reloc addend. Compute the start and end
+ addresses and check if the shrinked insn falls between sym1 and sym2. */
+
+ bfd_vma end_address = symval + irel->r_addend;
+ bfd_vma start_address = end_address - x;
+
+ /* Reduce the diff value by count bytes and write it back into section
+ contents. */
+
+ if (shrinked_insn_address >= start_address
+ && shrinked_insn_address <= end_address)
+ {
+ switch (ELF32_R_TYPE (irel->r_info))
+ {
+ case R_AVR_DIFF8:
+ {
+ *reloc_contents = (x - count);
+ break;
+ }
+ case R_AVR_DIFF16:
+ {
+ bfd_put_16 (abfd, (x - count) & 0xFFFF, reloc_contents);
+ break;
+ }
+ case R_AVR_DIFF32:
+ {
+ bfd_put_32 (abfd, (x - count) & 0xFFFFFFFF, reloc_contents);
+ break;
+ }
+ default:
+ {
+ BFD_FAIL();
+ }
+ }
+
+ }
+}
+
+/* Delete some bytes from a section while changing the size of an instruction.
+ The parameter "addr" denotes the section-relative offset pointing just
+ behind the shrinked instruction. "addr+count" point at the first
+ byte just behind the original unshrinked instruction. */
+
+static bfd_boolean
+elf32_avr_relax_delete_bytes (bfd *abfd,
+ asection *sec,
+ bfd_vma addr,
+ int count)
+{
+ Elf_Internal_Shdr *symtab_hdr;
+ unsigned int sec_shndx;
+ bfd_byte *contents;
+ Elf_Internal_Rela *irel, *irelend;
+ Elf_Internal_Sym *isym;
+ Elf_Internal_Sym *isymbuf = NULL;
+ bfd_vma toaddr;
+ struct elf_link_hash_entry **sym_hashes;
+ struct elf_link_hash_entry **end_hashes;
+ unsigned int symcount;
+
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+ sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
+ contents = elf_section_data (sec)->this_hdr.contents;
+
+ toaddr = sec->size;
+
+ irel = elf_section_data (sec)->relocs;
+ irelend = irel + sec->reloc_count;
+
+ /* Actually delete the bytes. */
+ if (toaddr - addr - count > 0)
+ memmove (contents + addr, contents + addr + count,
+ (size_t) (toaddr - addr - count));
+ sec->size -= count;
+
+ /* Adjust all the reloc addresses. */
+ for (irel = elf_section_data (sec)->relocs; irel < irelend; irel++)
+ {
+ bfd_vma old_reloc_address;
+
+ old_reloc_address = (sec->output_section->vma
+ + sec->output_offset + irel->r_offset);
+
+ /* Get the new reloc address. */
+ if ((irel->r_offset > addr
+ && irel->r_offset < toaddr))
+ {
+ if (debug_relax)
+ printf ("Relocation at address 0x%x needs to be moved.\n"
+ "Old section offset: 0x%x, New section offset: 0x%x \n",
+ (unsigned int) old_reloc_address,
+ (unsigned int) irel->r_offset,
+ (unsigned int) ((irel->r_offset) - count));
+
+ irel->r_offset -= count;
+ }
+
+ }
+
+ /* The reloc's own addresses are now ok. However, we need to readjust
+ the reloc's addend, i.e. the reloc's value if two conditions are met:
+ 1.) the reloc is relative to a symbol in this section that
+ is located in front of the shrinked instruction
+ 2.) symbol plus addend end up behind the shrinked instruction.
+
+ The most common case where this happens are relocs relative to
+ the section-start symbol.
+
+ This step needs to be done for all of the sections of the bfd. */
+
+ {
+ struct bfd_section *isec;
+
+ for (isec = abfd->sections; isec; isec = isec->next)
+ {
+ bfd_vma symval;
+ bfd_vma shrinked_insn_address;
+
+ if (isec->reloc_count == 0)
+ continue;
+
+ shrinked_insn_address = (sec->output_section->vma
+ + sec->output_offset + addr - count);
+
+ irel = elf_section_data (isec)->relocs;
+ /* PR 12161: Read in the relocs for this section if necessary. */
+ if (irel == NULL)
+ irel = _bfd_elf_link_read_relocs (abfd, isec, NULL, NULL, TRUE);
+
+ for (irelend = irel + isec->reloc_count;
+ irel < irelend;
+ irel++)
+ {
+ /* Read this BFD's local symbols if we haven't done
+ so already. */
+ if (isymbuf == NULL && symtab_hdr->sh_info != 0)
+ {
+ isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
+ if (isymbuf == NULL)
+ isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
+ symtab_hdr->sh_info, 0,
+ NULL, NULL, NULL);
+ if (isymbuf == NULL)
+ return FALSE;
+ }
+
+ /* Get the value of the symbol referred to by the reloc. */
+ if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
+ {
+ /* A local symbol. */
+ asection *sym_sec;
+
+ isym = isymbuf + ELF32_R_SYM (irel->r_info);
+ sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
+ symval = isym->st_value;
+ /* If the reloc is absolute, it will not have
+ a symbol or section associated with it. */
+ if (sym_sec == sec)
+ {
+ symval += sym_sec->output_section->vma
+ + sym_sec->output_offset;
+
+ if (debug_relax)
+ printf ("Checking if the relocation's "
+ "addend needs corrections.\n"
+ "Address of anchor symbol: 0x%x \n"
+ "Address of relocation target: 0x%x \n"
+ "Address of relaxed insn: 0x%x \n",
+ (unsigned int) symval,
+ (unsigned int) (symval + irel->r_addend),
+ (unsigned int) shrinked_insn_address);
+
+ if (symval <= shrinked_insn_address
+ && (symval + irel->r_addend) > shrinked_insn_address)
+ {
+ if (elf32_avr_is_diff_reloc (irel))
+ {
+ elf32_avr_adjust_diff_reloc_value (abfd, isec, irel,
+ symval,
+ shrinked_insn_address,
+ count);
+ }
+
+ irel->r_addend -= count;
+
+ if (debug_relax)
+ printf ("Relocation's addend needed to be fixed \n");
+ }
+ }
+ /* else...Reference symbol is absolute. No adjustment needed. */
+ }
+ /* else...Reference symbol is extern. No need for adjusting
+ the addend. */
+ }
+ }
+ }
+
+ /* Adjust the local symbols defined in this section. */
+ isym = (Elf_Internal_Sym *) symtab_hdr->contents;
+ /* Fix PR 9841, there may be no local symbols. */
+ if (isym != NULL)
+ {
+ Elf_Internal_Sym *isymend;
+
+ isymend = isym + symtab_hdr->sh_info;
+ for (; isym < isymend; isym++)
+ {
+ if (isym->st_shndx == sec_shndx
+ && isym->st_value > addr
+ && isym->st_value < toaddr)
+ isym->st_value -= count;
+ }
+ }
+
+ /* Now adjust the global symbols defined in this section. */
+ symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
+ - symtab_hdr->sh_info);
+ sym_hashes = elf_sym_hashes (abfd);
+ end_hashes = sym_hashes + symcount;
+ for (; sym_hashes < end_hashes; sym_hashes++)
+ {
+ struct elf_link_hash_entry *sym_hash = *sym_hashes;
+ 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
+ && sym_hash->root.u.def.value < toaddr)
+ {
+ sym_hash->root.u.def.value -= count;
+ }
+ }
+
+ return TRUE;
+}
+
+/* This function handles relaxing for the avr.
+ Many important relaxing opportunities within functions are already
+ realized by the compiler itself.
+ Here we try to replace call (4 bytes) -> rcall (2 bytes)
+ and jump -> rjmp (safes also 2 bytes).
+ As well we now optimize seqences of
+ - call/rcall function
+ - ret
+ to yield
+ - jmp/rjmp function
+ - ret
+ . In case that within a sequence
+ - jmp/rjmp label
+ - ret
+ the ret could no longer be reached it is optimized away. In order
+ to check if the ret is no longer needed, it is checked that the ret's address
+ is not the target of a branch or jump within the same section, it is checked
+ that there is no skip instruction before the jmp/rjmp and that there
+ is no local or global label place at the address of the ret.
+
+ We refrain from relaxing within sections ".vectors" and
+ ".jumptables" in order to maintain the position of the instructions.
+ There, however, we substitute jmp/call by a sequence rjmp,nop/rcall,nop
+ if possible. (In future one could possibly use the space of the nop
+ for the first instruction of the irq service function.
+
+ The .jumptables sections is meant to be used for a future tablejump variant
+ for the devices with 3-byte program counter where the table itself
+ contains 4-byte jump instructions whose relative offset must not
+ be changed. */
+
+static bfd_boolean
+elf32_avr_relax_section (bfd *abfd,
+ asection *sec,
+ struct bfd_link_info *link_info,
+ bfd_boolean *again)
+{
+ Elf_Internal_Shdr *symtab_hdr;
+ Elf_Internal_Rela *internal_relocs;
+ Elf_Internal_Rela *irel, *irelend;
+ bfd_byte *contents = NULL;
+ Elf_Internal_Sym *isymbuf = NULL;
+ struct elf32_avr_link_hash_table *htab;
+
+ /* If 'shrinkable' is FALSE, do not shrink by deleting bytes while
+ relaxing. Such shrinking can cause issues for the sections such
+ as .vectors and .jumptables. Instead the unused bytes should be
+ filled with nop instructions. */
+ bfd_boolean shrinkable = TRUE;
+
+ if (!strcmp (sec->name,".vectors")
+ || !strcmp (sec->name,".jumptables"))
+ shrinkable = FALSE;
+
+ if (link_info->relocatable)
+ (*link_info->callbacks->einfo)
+ (_("%P%F: --relax and -r may not be used together\n"));
+
+ htab = avr_link_hash_table (link_info);
+ if (htab == NULL)
+ return FALSE;
+
+ /* Assume nothing changes. */
+ *again = FALSE;
+
+ if ((!htab->no_stubs) && (sec == htab->stub_sec))
+ {
+ /* We are just relaxing the stub section.
+ Let's calculate the size needed again. */
+ bfd_size_type last_estimated_stub_section_size = htab->stub_sec->size;
+
+ if (debug_relax)
+ printf ("Relaxing the stub section. Size prior to this pass: %i\n",
+ (int) last_estimated_stub_section_size);
+
+ elf32_avr_size_stubs (htab->stub_sec->output_section->owner,
+ link_info, FALSE);
+
+ /* Check if the number of trampolines changed. */
+ if (last_estimated_stub_section_size != htab->stub_sec->size)
+ *again = TRUE;
+
+ if (debug_relax)
+ printf ("Size of stub section after this pass: %i\n",
+ (int) htab->stub_sec->size);
+
+ return TRUE;
+ }
+
+ /* We don't have to do anything for a relocatable link, if
+ this section does not have relocs, or if this is not a
+ code section. */
+ if (link_info->relocatable
+ || (sec->flags & SEC_RELOC) == 0
+ || sec->reloc_count == 0
+ || (sec->flags & SEC_CODE) == 0)
+ return TRUE;
+
+ /* Check if the object file to relax uses internal symbols so that we
+ could fix up the relocations. */
+ if (!(elf_elfheader (abfd)->e_flags & EF_AVR_LINKRELAX_PREPARED))
+ return TRUE;
+
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+
+ /* Get a copy of the native relocations. */
+ internal_relocs = (_bfd_elf_link_read_relocs
+ (abfd, sec, NULL, NULL, link_info->keep_memory));
+ if (internal_relocs == NULL)
+ goto error_return;
+
+ /* Walk through the relocs looking for relaxing opportunities. */
+ irelend = internal_relocs + sec->reloc_count;
+ for (irel = internal_relocs; irel < irelend; irel++)
+ {
+ bfd_vma symval;
+
+ if ( ELF32_R_TYPE (irel->r_info) != R_AVR_13_PCREL
+ && ELF32_R_TYPE (irel->r_info) != R_AVR_7_PCREL
+ && ELF32_R_TYPE (irel->r_info) != R_AVR_CALL)
+ 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. */
+ if (! bfd_malloc_and_get_section (abfd, sec, &contents))
+ goto error_return;
+ }
+ }
+
+ /* Read this BFD's local symbols if we haven't done so already. */
+ if (isymbuf == NULL && symtab_hdr->sh_info != 0)
+ {
+ isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
+ if (isymbuf == NULL)
+ isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
+ symtab_hdr->sh_info, 0,
+ NULL, NULL, NULL);
+ if (isymbuf == NULL)
+ 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)
+ {
+ /* A local symbol. */
+ Elf_Internal_Sym *isym;
+ asection *sym_sec;
+
+ isym = isymbuf + ELF32_R_SYM (irel->r_info);
+ sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
+ symval = isym->st_value;
+ /* If the reloc is absolute, it will not have
+ a symbol or section associated with it. */
+ if (sym_sec)
+ symval += 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. */
+ switch (ELF32_R_TYPE (irel->r_info))
+ {
+ /* Try to turn a 22-bit absolute call/jump into an 13-bit
+ pc-relative rcall/rjmp. */
+ case R_AVR_CALL:
+ {
+ bfd_vma value = symval + irel->r_addend;
+ bfd_vma dot, gap;
+ int distance_short_enough = 0;
+
+ /* Get the address of this instruction. */
+ dot = (sec->output_section->vma
+ + sec->output_offset + irel->r_offset);
+
+ /* Compute the distance from this insn to the branch target. */
+ gap = value - dot;
+
+ /* Check if the gap falls in the range that can be accommodated
+ in 13bits signed (It is 12bits when encoded, as we deal with
+ word addressing). */
+ if (!shrinkable && ((int) gap >= -4096 && (int) gap <= 4095))
+ distance_short_enough = 1;
+ /* If shrinkable, then we can check for a range of distance which
+ is two bytes farther on both the directions because the call
+ or jump target will be closer by two bytes after the
+ relaxation. */
+ else if (shrinkable && ((int) gap >= -4094 && (int) gap <= 4097))
+ distance_short_enough = 1;
+
+ /* Here we handle the wrap-around case. E.g. for a 16k device
+ we could use a rjmp to jump from address 0x100 to 0x3d00!
+ In order to make this work properly, we need to fill the
+ vaiable avr_pc_wrap_around with the appropriate value.
+ I.e. 0x4000 for a 16k device. */
+ {
+ /* Shrinking the code size makes the gaps larger in the
+ case of wrap-arounds. So we use a heuristical safety
+ margin to avoid that during relax the distance gets
+ again too large for the short jumps. Let's assume
+ a typical code-size reduction due to relax for a
+ 16k device of 600 bytes. So let's use twice the
+ typical value as safety margin. */
+ int rgap;
+ int safety_margin;
+
+ int assumed_shrink = 600;
+ if (avr_pc_wrap_around > 0x4000)
+ assumed_shrink = 900;
+
+ safety_margin = 2 * assumed_shrink;
+
+ rgap = avr_relative_distance_considering_wrap_around (gap);
+
+ if (rgap >= (-4092 + safety_margin)
+ && rgap <= (4094 - safety_margin))
+ distance_short_enough = 1;
+ }
+
+ if (distance_short_enough)
+ {
+ unsigned char code_msb;
+ unsigned char code_lsb;
+
+ if (debug_relax)
+ printf ("shrinking jump/call instruction at address 0x%x"
+ " in section %s\n\n",
+ (int) dot, sec->name);
+
+ /* Note that we've changed the relocs, section contents,
+ etc. */
+ elf_section_data (sec)->relocs = internal_relocs;
+ elf_section_data (sec)->this_hdr.contents = contents;
+ symtab_hdr->contents = (unsigned char *) isymbuf;
+
+ /* Get the instruction code for relaxing. */
+ code_lsb = bfd_get_8 (abfd, contents + irel->r_offset);
+ code_msb = bfd_get_8 (abfd, contents + irel->r_offset + 1);
+
+ /* Mask out the relocation bits. */
+ code_msb &= 0x94;
+ code_lsb &= 0x0E;
+ if (code_msb == 0x94 && code_lsb == 0x0E)
+ {
+ /* we are changing call -> rcall . */
+ bfd_put_8 (abfd, 0x00, contents + irel->r_offset);
+ bfd_put_8 (abfd, 0xD0, contents + irel->r_offset + 1);
+ }
+ else if (code_msb == 0x94 && code_lsb == 0x0C)
+ {
+ /* we are changeing jump -> rjmp. */
+ bfd_put_8 (abfd, 0x00, contents + irel->r_offset);
+ bfd_put_8 (abfd, 0xC0, contents + irel->r_offset + 1);
+ }
+ else
+ abort ();
+
+ /* Fix the relocation's type. */
+ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
+ R_AVR_13_PCREL);
+
+ /* We should not modify the ordering if 'shrinkable' is
+ FALSE. */
+ if (!shrinkable)
+ {
+ /* Let's insert a nop. */
+ bfd_put_8 (abfd, 0x00, contents + irel->r_offset + 2);
+ bfd_put_8 (abfd, 0x00, contents + irel->r_offset + 3);
+ }
+ else
+ {
+ /* Delete two bytes of data. */
+ if (!elf32_avr_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;
+ }
+ }
+ }
+
+ default:
+ {
+ unsigned char code_msb;
+ unsigned char code_lsb;
+ bfd_vma dot;
+
+ code_msb = bfd_get_8 (abfd, contents + irel->r_offset + 1);
+ code_lsb = bfd_get_8 (abfd, contents + irel->r_offset + 0);
+
+ /* Get the address of this instruction. */
+ dot = (sec->output_section->vma
+ + sec->output_offset + irel->r_offset);
+
+ /* Here we look for rcall/ret or call/ret sequences that could be
+ safely replaced by rjmp/ret or jmp/ret. */
+ if (((code_msb & 0xf0) == 0xd0)
+ && avr_replace_call_ret_sequences)
+ {
+ /* This insn is a rcall. */
+ unsigned char next_insn_msb = 0;
+ unsigned char next_insn_lsb = 0;
+
+ if (irel->r_offset + 3 < sec->size)
+ {
+ next_insn_msb =
+ bfd_get_8 (abfd, contents + irel->r_offset + 3);
+ next_insn_lsb =
+ bfd_get_8 (abfd, contents + irel->r_offset + 2);
+ }
+
+ if ((0x95 == next_insn_msb) && (0x08 == next_insn_lsb))
+ {
+ /* The next insn is a ret. We now convert the rcall insn
+ into a rjmp instruction. */
+ code_msb &= 0xef;
+ bfd_put_8 (abfd, code_msb, contents + irel->r_offset + 1);
+ if (debug_relax)
+ printf ("converted rcall/ret sequence at address 0x%x"
+ " into rjmp/ret sequence. Section is %s\n\n",
+ (int) dot, sec->name);
+ *again = TRUE;
+ break;
+ }
+ }
+ else if ((0x94 == (code_msb & 0xfe))
+ && (0x0e == (code_lsb & 0x0e))
+ && avr_replace_call_ret_sequences)
+ {
+ /* This insn is a call. */
+ unsigned char next_insn_msb = 0;
+ unsigned char next_insn_lsb = 0;
+
+ if (irel->r_offset + 5 < sec->size)
+ {
+ next_insn_msb =
+ bfd_get_8 (abfd, contents + irel->r_offset + 5);
+ next_insn_lsb =
+ bfd_get_8 (abfd, contents + irel->r_offset + 4);
+ }
+
+ if ((0x95 == next_insn_msb) && (0x08 == next_insn_lsb))
+ {
+ /* The next insn is a ret. We now convert the call insn
+ into a jmp instruction. */
+
+ code_lsb &= 0xfd;
+ bfd_put_8 (abfd, code_lsb, contents + irel->r_offset);
+ if (debug_relax)
+ printf ("converted call/ret sequence at address 0x%x"
+ " into jmp/ret sequence. Section is %s\n\n",
+ (int) dot, sec->name);
+ *again = TRUE;
+ break;
+ }
+ }
+ else if ((0xc0 == (code_msb & 0xf0))
+ || ((0x94 == (code_msb & 0xfe))
+ && (0x0c == (code_lsb & 0x0e))))
+ {
+ /* This insn is a rjmp or a jmp. */
+ unsigned char next_insn_msb = 0;
+ unsigned char next_insn_lsb = 0;
+ int insn_size;
+
+ if (0xc0 == (code_msb & 0xf0))
+ insn_size = 2; /* rjmp insn */
+ else
+ insn_size = 4; /* jmp insn */
+
+ if (irel->r_offset + insn_size + 1 < sec->size)
+ {
+ next_insn_msb =
+ bfd_get_8 (abfd, contents + irel->r_offset
+ + insn_size + 1);
+ next_insn_lsb =
+ bfd_get_8 (abfd, contents + irel->r_offset
+ + insn_size);
+ }
+
+ if ((0x95 == next_insn_msb) && (0x08 == next_insn_lsb))
+ {
+ /* The next insn is a ret. We possibly could delete
+ this ret. First we need to check for preceding
+ sbis/sbic/sbrs or cpse "skip" instructions. */
+
+ int there_is_preceding_non_skip_insn = 1;
+ bfd_vma address_of_ret;
+
+ address_of_ret = dot + insn_size;
+
+ if (debug_relax && (insn_size == 2))
+ printf ("found rjmp / ret sequence at address 0x%x\n",
+ (int) dot);
+ if (debug_relax && (insn_size == 4))
+ printf ("found jmp / ret sequence at address 0x%x\n",
+ (int) dot);
+
+ /* We have to make sure that there is a preceding insn. */
+ if (irel->r_offset >= 2)
+ {
+ unsigned char preceding_msb;
+ unsigned char preceding_lsb;
+
+ preceding_msb =
+ bfd_get_8 (abfd, contents + irel->r_offset - 1);
+ preceding_lsb =
+ bfd_get_8 (abfd, contents + irel->r_offset - 2);
+
+ /* sbic. */
+ if (0x99 == preceding_msb)
+ there_is_preceding_non_skip_insn = 0;
+
+ /* sbis. */
+ if (0x9b == preceding_msb)
+ there_is_preceding_non_skip_insn = 0;
+
+ /* sbrc */
+ if ((0xfc == (preceding_msb & 0xfe)
+ && (0x00 == (preceding_lsb & 0x08))))
+ there_is_preceding_non_skip_insn = 0;
+
+ /* sbrs */
+ if ((0xfe == (preceding_msb & 0xfe)
+ && (0x00 == (preceding_lsb & 0x08))))
+ there_is_preceding_non_skip_insn = 0;
+
+ /* cpse */
+ if (0x10 == (preceding_msb & 0xfc))
+ there_is_preceding_non_skip_insn = 0;
+
+ if (there_is_preceding_non_skip_insn == 0)
+ if (debug_relax)
+ printf ("preceding skip insn prevents deletion of"
+ " ret insn at Addy 0x%x in section %s\n",
+ (int) dot + 2, sec->name);
+ }
+ else
+ {
+ /* There is no previous instruction. */
+ there_is_preceding_non_skip_insn = 0;
+ }
+
+ if (there_is_preceding_non_skip_insn)
+ {
+ /* We now only have to make sure that there is no
+ local label defined at the address of the ret
+ instruction and that there is no local relocation
+ in this section pointing to the ret. */
+
+ int deleting_ret_is_safe = 1;
+ unsigned int section_offset_of_ret_insn =
+ irel->r_offset + insn_size;
+ Elf_Internal_Sym *isym, *isymend;
+ unsigned int sec_shndx;
+ struct bfd_section *isec;
+
+ sec_shndx =
+ _bfd_elf_section_from_bfd_section (abfd, sec);
+
+ /* Check for local symbols. */
+ isym = (Elf_Internal_Sym *) symtab_hdr->contents;
+ isymend = isym + symtab_hdr->sh_info;
+ /* PR 6019: There may not be any local symbols. */
+ for (; isym != NULL && isym < isymend; isym++)
+ {
+ if (isym->st_value == section_offset_of_ret_insn
+ && isym->st_shndx == sec_shndx)
+ {
+ deleting_ret_is_safe = 0;
+ if (debug_relax)
+ printf ("local label prevents deletion of ret "
+ "insn at address 0x%x\n",
+ (int) dot + insn_size);
+ }
+ }
+
+ /* Now check for global symbols. */
+ {
+ int symcount;
+ struct elf_link_hash_entry **sym_hashes;
+ struct elf_link_hash_entry **end_hashes;
+
+ symcount = (symtab_hdr->sh_size
+ / sizeof (Elf32_External_Sym)
+ - symtab_hdr->sh_info);
+ sym_hashes = elf_sym_hashes (abfd);
+ end_hashes = sym_hashes + symcount;
+ for (; sym_hashes < end_hashes; sym_hashes++)
+ {
+ struct elf_link_hash_entry *sym_hash =
+ *sym_hashes;
+ 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 == section_offset_of_ret_insn)
+ {
+ deleting_ret_is_safe = 0;
+ if (debug_relax)
+ printf ("global label prevents deletion of "
+ "ret insn at address 0x%x\n",
+ (int) dot + insn_size);
+ }
+ }
+ }
+
+ /* Now we check for relocations pointing to ret. */
+ for (isec = abfd->sections; isec && deleting_ret_is_safe; isec = isec->next)
+ {
+ Elf_Internal_Rela *rel;
+ Elf_Internal_Rela *relend;
+
+ rel = elf_section_data (isec)->relocs;
+ if (rel == NULL)
+ rel = _bfd_elf_link_read_relocs (abfd, isec, NULL, NULL, TRUE);
+
+ relend = rel + isec->reloc_count;
+
+ for (; rel && rel < relend; rel++)
+ {
+ bfd_vma reloc_target = 0;
+
+ /* Read this BFD's local symbols if we haven't
+ done so already. */
+ if (isymbuf == NULL && symtab_hdr->sh_info != 0)
+ {
+ isymbuf = (Elf_Internal_Sym *)
+ symtab_hdr->contents;
+ if (isymbuf == NULL)
+ isymbuf = bfd_elf_get_elf_syms
+ (abfd,
+ symtab_hdr,
+ symtab_hdr->sh_info, 0,
+ NULL, NULL, NULL);
+ if (isymbuf == NULL)
+ break;
+ }
+
+ /* Get the value of the symbol referred to
+ by the reloc. */
+ if (ELF32_R_SYM (rel->r_info)
+ < symtab_hdr->sh_info)
+ {
+ /* A local symbol. */
+ asection *sym_sec;
+
+ isym = isymbuf
+ + ELF32_R_SYM (rel->r_info);
+ sym_sec = bfd_section_from_elf_index
+ (abfd, isym->st_shndx);
+ symval = isym->st_value;
+
+ /* If the reloc is absolute, it will not
+ have a symbol or section associated
+ with it. */
+
+ if (sym_sec)
+ {
+ symval +=
+ sym_sec->output_section->vma
+ + sym_sec->output_offset;
+ reloc_target = symval + rel->r_addend;
+ }
+ else
+ {
+ reloc_target = symval + rel->r_addend;
+ /* Reference symbol is absolute. */
+ }
+ }
+ /* else ... reference symbol is extern. */
+
+ if (address_of_ret == reloc_target)
+ {
+ deleting_ret_is_safe = 0;
+ if (debug_relax)
+ printf ("ret from "
+ "rjmp/jmp ret sequence at address"
+ " 0x%x could not be deleted. ret"
+ " is target of a relocation.\n",
+ (int) address_of_ret);
+ break;
+ }
+ }
+ }
+
+ if (deleting_ret_is_safe)
+ {
+ if (debug_relax)
+ printf ("unreachable ret instruction "
+ "at address 0x%x deleted.\n",
+ (int) dot + insn_size);
+
+ /* Delete two bytes of data. */
+ if (!elf32_avr_relax_delete_bytes (abfd, sec,
+ irel->r_offset + insn_size, 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;
+ }
+ }
+ }
+ }
+ break;
+ }
+ }
+ }
+
+ if (contents != NULL
+ && elf_section_data (sec)->this_hdr.contents != contents)
+ {
+ if (! link_info->keep_memory)
+ free (contents);
+ else
+ {
+ /* Cache the section contents for elf_link_input_bfd. */
+ elf_section_data (sec)->this_hdr.contents = contents;
+ }
+ }
+
+ if (internal_relocs != NULL
+ && elf_section_data (sec)->relocs != internal_relocs)
+ free (internal_relocs);
+
+ return TRUE;
+
+ error_return:
+ if (isymbuf != NULL
+ && symtab_hdr->contents != (unsigned char *) isymbuf)
+ free (isymbuf);
+ if (contents != NULL
+ && elf_section_data (sec)->this_hdr.contents != contents)
+ free (contents);
+ if (internal_relocs != NULL
+ && elf_section_data (sec)->relocs != internal_relocs)
+ free (internal_relocs);
+
+ return FALSE;
+}
+
+/* This is a version of bfd_generic_get_relocated_section_contents
+ which uses elf32_avr_relocate_section.
+
+ For avr it's essentially a cut and paste taken from the H8300 port.
+ The author of the relaxation support patch for avr had absolutely no
+ clue what is happening here but found out that this part of the code
+ seems to be important. */
+
+static bfd_byte *
+elf32_avr_get_relocated_section_contents (bfd *output_bfd,
+ struct bfd_link_info *link_info,
+ struct bfd_link_order *link_order,
+ bfd_byte *data,
+ bfd_boolean relocatable,
+ 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;
+ Elf_Internal_Sym *isymbuf = NULL;
+
+ /* We only need to handle the case of relaxing, or of having a
+ particular set of section contents, specially. */
+ if (relocatable
+ || elf_section_data (input_section)->this_hdr.contents == NULL)
+ return bfd_generic_get_relocated_section_contents (output_bfd, link_info,
+ link_order, data,
+ relocatable,
+ symbols);
+ symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
+
+ memcpy (data, elf_section_data (input_section)->this_hdr.contents,
+ (size_t) input_section->size);
+
+ if ((input_section->flags & SEC_RELOC) != 0
+ && input_section->reloc_count > 0)
+ {
+ asection **secpp;
+ Elf_Internal_Sym *isym, *isymend;
+ bfd_size_type amt;
+
+ internal_relocs = (_bfd_elf_link_read_relocs
+ (input_bfd, input_section, NULL, NULL, FALSE));
+ if (internal_relocs == NULL)
+ goto error_return;
+
+ if (symtab_hdr->sh_info != 0)
+ {
+ isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
+ if (isymbuf == NULL)
+ isymbuf = bfd_elf_get_elf_syms (input_bfd, symtab_hdr,
+ symtab_hdr->sh_info, 0,
+ NULL, NULL, NULL);
+ if (isymbuf == NULL)
+ goto error_return;
+ }
+
+ amt = symtab_hdr->sh_info;
+ amt *= sizeof (asection *);
+ sections = bfd_malloc (amt);
+ if (sections == NULL && amt != 0)
+ goto error_return;
+
+ isymend = isymbuf + symtab_hdr->sh_info;
+ for (isym = isymbuf, secpp = sections; isym < isymend; ++isym, ++secpp)
+ {
+ asection *isec;
+
+ if (isym->st_shndx == SHN_UNDEF)
+ isec = bfd_und_section_ptr;
+ 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
+ isec = bfd_section_from_elf_index (input_bfd, isym->st_shndx);
+
+ *secpp = isec;
+ }
+
+ if (! elf32_avr_relocate_section (output_bfd, link_info, input_bfd,
+ input_section, data, internal_relocs,
+ isymbuf, sections))
+ goto error_return;
+
+ if (sections != NULL)
+ free (sections);
+ if (isymbuf != NULL
+ && symtab_hdr->contents != (unsigned char *) isymbuf)
+ free (isymbuf);
+ if (elf_section_data (input_section)->relocs != internal_relocs)
+ free (internal_relocs);
+ }
+
+ return data;
+
+ error_return:
+ if (sections != NULL)
+ free (sections);
+ if (isymbuf != NULL
+ && symtab_hdr->contents != (unsigned char *) isymbuf)
+ free (isymbuf);
+ if (internal_relocs != NULL
+ && elf_section_data (input_section)->relocs != internal_relocs)
+ free (internal_relocs);
+ return NULL;
+}
+
+
+/* Determines the hash entry name for a particular reloc. It consists of
+ the identifier of the symbol section and the added reloc addend and
+ symbol offset relative to the section the symbol is attached to. */
+
+static char *
+avr_stub_name (const asection *symbol_section,
+ const bfd_vma symbol_offset,
+ const Elf_Internal_Rela *rela)
+{
+ char *stub_name;
+ bfd_size_type len;
+
+ len = 8 + 1 + 8 + 1 + 1;
+ stub_name = bfd_malloc (len);
+
+ sprintf (stub_name, "%08x+%08x",
+ symbol_section->id & 0xffffffff,
+ (unsigned int) ((rela->r_addend & 0xffffffff) + symbol_offset));
+
+ return stub_name;
+}
+
+
+/* Add a new stub entry to the stub hash. Not all fields of the new
+ stub entry are initialised. */
+
+static struct elf32_avr_stub_hash_entry *
+avr_add_stub (const char *stub_name,
+ struct elf32_avr_link_hash_table *htab)
+{
+ struct elf32_avr_stub_hash_entry *hsh;
+
+ /* Enter this entry into the linker stub hash table. */
+ hsh = avr_stub_hash_lookup (&htab->bstab, stub_name, TRUE, FALSE);
+
+ if (hsh == NULL)
+ {
+ (*_bfd_error_handler) (_("%B: cannot create stub entry %s"),
+ NULL, stub_name);
+ return NULL;
+ }
+
+ hsh->stub_offset = 0;
+ return hsh;
+}
+
+/* We assume that there is already space allocated for the stub section
+ contents and that before building the stubs the section size is
+ initialized to 0. We assume that within the stub hash table entry,
+ the absolute position of the jmp target has been written in the
+ target_value field. We write here the offset of the generated jmp insn
+ relative to the trampoline section start to the stub_offset entry in
+ the stub hash table entry. */
+
+static bfd_boolean
+avr_build_one_stub (struct bfd_hash_entry *bh, void *in_arg)
+{
+ struct elf32_avr_stub_hash_entry *hsh;
+ struct bfd_link_info *info;
+ struct elf32_avr_link_hash_table *htab;
+ bfd *stub_bfd;
+ bfd_byte *loc;
+ bfd_vma target;
+ bfd_vma starget;
+
+ /* Basic opcode */
+ bfd_vma jmp_insn = 0x0000940c;
+
+ /* Massage our args to the form they really have. */
+ hsh = avr_stub_hash_entry (bh);
+
+ if (!hsh->is_actually_needed)
+ return TRUE;
+
+ info = (struct bfd_link_info *) in_arg;
+
+ htab = avr_link_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ target = hsh->target_value;
+
+ /* Make a note of the offset within the stubs for this entry. */
+ hsh->stub_offset = htab->stub_sec->size;
+ loc = htab->stub_sec->contents + hsh->stub_offset;
+
+ stub_bfd = htab->stub_sec->owner;
+
+ if (debug_stubs)
+ printf ("Building one Stub. Address: 0x%x, Offset: 0x%x\n",
+ (unsigned int) target,
+ (unsigned int) hsh->stub_offset);
+
+ /* We now have to add the information on the jump target to the bare
+ opcode bits already set in jmp_insn. */
+
+ /* Check for the alignment of the address. */
+ if (target & 1)
+ return FALSE;
+
+ starget = target >> 1;
+ jmp_insn |= ((starget & 0x10000) | ((starget << 3) & 0x1f00000)) >> 16;
+ bfd_put_16 (stub_bfd, jmp_insn, loc);
+ bfd_put_16 (stub_bfd, (bfd_vma) starget & 0xffff, loc + 2);
+
+ htab->stub_sec->size += 4;
+
+ /* Now add the entries in the address mapping table if there is still
+ space left. */
+ {
+ unsigned int nr;
+
+ nr = htab->amt_entry_cnt + 1;
+ if (nr <= htab->amt_max_entry_cnt)
+ {
+ htab->amt_entry_cnt = nr;
+
+ htab->amt_stub_offsets[nr - 1] = hsh->stub_offset;
+ htab->amt_destination_addr[nr - 1] = target;
+ }
+ }
+
+ return TRUE;
+}
+
+static bfd_boolean
+avr_mark_stub_not_to_be_necessary (struct bfd_hash_entry *bh,
+ void *in_arg ATTRIBUTE_UNUSED)
+{
+ struct elf32_avr_stub_hash_entry *hsh;
+
+ hsh = avr_stub_hash_entry (bh);
+ hsh->is_actually_needed = FALSE;
+
+ return TRUE;
+}
+
+static bfd_boolean
+avr_size_one_stub (struct bfd_hash_entry *bh, void *in_arg)
+{
+ struct elf32_avr_stub_hash_entry *hsh;
+ struct elf32_avr_link_hash_table *htab;
+ int size;
+
+ /* Massage our args to the form they really have. */
+ hsh = avr_stub_hash_entry (bh);
+ htab = in_arg;
+
+ if (hsh->is_actually_needed)
+ size = 4;
+ else
+ size = 0;
+
+ htab->stub_sec->size += size;
+ return TRUE;
+}
+
+void
+elf32_avr_setup_params (struct bfd_link_info *info,
+ bfd *avr_stub_bfd,
+ asection *avr_stub_section,
+ bfd_boolean no_stubs,
+ bfd_boolean deb_stubs,
+ bfd_boolean deb_relax,
+ bfd_vma pc_wrap_around,
+ bfd_boolean call_ret_replacement)
+{
+ struct elf32_avr_link_hash_table *htab = avr_link_hash_table (info);
+
+ if (htab == NULL)
+ return;
+ htab->stub_sec = avr_stub_section;
+ htab->stub_bfd = avr_stub_bfd;
+ htab->no_stubs = no_stubs;
+
+ debug_relax = deb_relax;
+ debug_stubs = deb_stubs;
+ avr_pc_wrap_around = pc_wrap_around;
+ avr_replace_call_ret_sequences = call_ret_replacement;
+}
+
+
+/* Set up various things so that we can make a list of input sections
+ for each output section included in the link. Returns -1 on error,
+ 0 when no stubs will be needed, and 1 on success. It also sets
+ information on the stubs bfd and the stub section in the info
+ struct. */
+
+int
+elf32_avr_setup_section_lists (bfd *output_bfd,
+ struct bfd_link_info *info)
+{
+ bfd *input_bfd;
+ unsigned int bfd_count;
+ int top_id, top_index;
+ asection *section;
+ asection **input_list, **list;
+ bfd_size_type amt;
+ struct elf32_avr_link_hash_table *htab = avr_link_hash_table (info);
+
+ if (htab == NULL || htab->no_stubs)
+ return 0;
+
+ /* Count the number of input BFDs and find the top input section id. */
+ for (input_bfd = info->input_bfds, bfd_count = 0, top_id = 0;
+ input_bfd != NULL;
+ input_bfd = input_bfd->link.next)
+ {
+ bfd_count += 1;
+ for (section = input_bfd->sections;
+ section != NULL;
+ section = section->next)
+ if (top_id < section->id)
+ top_id = section->id;
+ }
+
+ htab->bfd_count = bfd_count;
+
+ /* We can't use output_bfd->section_count here to find the top output
+ section index as some sections may have been removed, and
+ strip_excluded_output_sections doesn't renumber the indices. */
+ for (section = output_bfd->sections, top_index = 0;
+ section != NULL;
+ section = section->next)
+ if (top_index < section->index)
+ top_index = section->index;
+
+ htab->top_index = top_index;
+ amt = sizeof (asection *) * (top_index + 1);
+ input_list = bfd_malloc (amt);
+ htab->input_list = input_list;
+ if (input_list == NULL)
+ return -1;
+
+ /* For sections we aren't interested in, mark their entries with a
+ value we can check later. */
+ list = input_list + top_index;
+ do
+ *list = bfd_abs_section_ptr;
+ while (list-- != input_list);
+
+ for (section = output_bfd->sections;
+ section != NULL;
+ section = section->next)
+ if ((section->flags & SEC_CODE) != 0)
+ input_list[section->index] = NULL;
+
+ return 1;
+}
+
+
+/* Read in all local syms for all input bfds, and create hash entries
+ for export stubs if we are building a multi-subspace shared lib.
+ Returns -1 on error, 0 otherwise. */
+
+static int
+get_local_syms (bfd *input_bfd, struct bfd_link_info *info)
+{
+ unsigned int bfd_indx;
+ Elf_Internal_Sym *local_syms, **all_local_syms;
+ struct elf32_avr_link_hash_table *htab = avr_link_hash_table (info);
+ bfd_size_type amt;
+
+ if (htab == NULL)
+ return -1;
+
+ /* 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. */
+ amt = sizeof (Elf_Internal_Sym *) * htab->bfd_count;
+ all_local_syms = bfd_zmalloc (amt);
+ htab->all_local_syms = all_local_syms;
+ if (all_local_syms == NULL)
+ return -1;
+
+ /* Walk over all the input BFDs, swapping in local symbols.
+ If we are creating a shared library, create hash entries for the
+ export stubs. */
+ for (bfd_indx = 0;
+ input_bfd != NULL;
+ input_bfd = input_bfd->link.next, bfd_indx++)
+ {
+ Elf_Internal_Shdr *symtab_hdr;
+
+ /* 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. */
+ local_syms = (Elf_Internal_Sym *) symtab_hdr->contents;
+ if (local_syms == NULL)
+ {
+ local_syms = bfd_elf_get_elf_syms (input_bfd, symtab_hdr,
+ symtab_hdr->sh_info, 0,
+ NULL, NULL, NULL);
+ /* Cache them for elf_link_input_bfd. */
+ symtab_hdr->contents = (unsigned char *) local_syms;
+ }
+ if (local_syms == NULL)
+ return -1;
+
+ all_local_syms[bfd_indx] = local_syms;
+ }
+
+ return 0;
+}
+
+#define ADD_DUMMY_STUBS_FOR_DEBUGGING 0
+
+bfd_boolean
+elf32_avr_size_stubs (bfd *output_bfd,
+ struct bfd_link_info *info,
+ bfd_boolean is_prealloc_run)
+{
+ struct elf32_avr_link_hash_table *htab;
+ int stub_changed = 0;
+
+ htab = avr_link_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ /* At this point we initialize htab->vector_base
+ To the start of the text output section. */
+ htab->vector_base = htab->stub_sec->output_section->vma;
+
+ if (get_local_syms (info->input_bfds, info))
+ {
+ if (htab->all_local_syms)
+ goto error_ret_free_local;
+ return FALSE;
+ }
+
+ if (ADD_DUMMY_STUBS_FOR_DEBUGGING)
+ {
+ struct elf32_avr_stub_hash_entry *test;
+
+ test = avr_add_stub ("Hugo",htab);
+ test->target_value = 0x123456;
+ test->stub_offset = 13;
+
+ test = avr_add_stub ("Hugo2",htab);
+ test->target_value = 0x84210;
+ test->stub_offset = 14;
+ }
+
+ while (1)
+ {
+ bfd *input_bfd;
+ unsigned int bfd_indx;
+
+ /* We will have to re-generate the stub hash table each time anything
+ in memory has changed. */
+
+ bfd_hash_traverse (&htab->bstab, avr_mark_stub_not_to_be_necessary, htab);
+ for (input_bfd = info->input_bfds, bfd_indx = 0;
+ input_bfd != NULL;
+ input_bfd = input_bfd->link.next, bfd_indx++)
+ {
+ Elf_Internal_Shdr *symtab_hdr;
+ asection *section;
+ Elf_Internal_Sym *local_syms;
+
+ /* 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 = htab->all_local_syms[bfd_indx];
+
+ /* Walk over each section attached to the input bfd. */
+ for (section = input_bfd->sections;
+ section != NULL;
+ section = section->next)
+ {
+ Elf_Internal_Rela *internal_relocs, *irelaend, *irela;
+
+ /* If there aren't any relocs, then there's nothing more
+ to do. */
+ if ((section->flags & SEC_RELOC) == 0
+ || section->reloc_count == 0)
+ continue;
+
+ /* If this section is a link-once section that will be
+ discarded, then don't create any stubs. */
+ if (section->output_section == NULL
+ || section->output_section->owner != output_bfd)
+ continue;
+
+ /* Get the relocs. */
+ internal_relocs
+ = _bfd_elf_link_read_relocs (input_bfd, section, NULL, NULL,
+ info->keep_memory);
+ if (internal_relocs == NULL)
+ goto error_ret_free_local;
+
+ /* Now examine each relocation. */
+ irela = internal_relocs;
+ irelaend = irela + section->reloc_count;
+ for (; irela < irelaend; irela++)
+ {
+ unsigned int r_type, r_indx;
+ struct elf32_avr_stub_hash_entry *hsh;
+ asection *sym_sec;
+ bfd_vma sym_value;
+ bfd_vma destination;
+ struct elf_link_hash_entry *hh;
+ char *stub_name;
+
+ r_type = ELF32_R_TYPE (irela->r_info);
+ r_indx = ELF32_R_SYM (irela->r_info);
+
+ /* Only look for 16 bit GS relocs. No other reloc will need a
+ stub. */
+ if (!((r_type == R_AVR_16_PM)
+ || (r_type == R_AVR_LO8_LDI_GS)
+ || (r_type == R_AVR_HI8_LDI_GS)))
+ continue;
+
+ /* Now determine the call target, its name, value,
+ section. */
+ sym_sec = NULL;
+ sym_value = 0;
+ destination = 0;
+ hh = NULL;
+ if (r_indx < symtab_hdr->sh_info)
+ {
+ /* It's a local symbol. */
+ Elf_Internal_Sym *sym;
+ Elf_Internal_Shdr *hdr;
+ unsigned int shndx;
+
+ sym = local_syms + r_indx;
+ if (ELF_ST_TYPE (sym->st_info) != STT_SECTION)
+ sym_value = sym->st_value;
+ shndx = sym->st_shndx;
+ if (shndx < elf_numsections (input_bfd))
+ {
+ hdr = elf_elfsections (input_bfd)[shndx];
+ sym_sec = hdr->bfd_section;
+ destination = (sym_value + irela->r_addend
+ + sym_sec->output_offset
+ + sym_sec->output_section->vma);
+ }
+ }
+ else
+ {
+ /* It's an external symbol. */
+ int e_indx;
+
+ e_indx = r_indx - symtab_hdr->sh_info;
+ hh = elf_sym_hashes (input_bfd)[e_indx];
+
+ while (hh->root.type == bfd_link_hash_indirect
+ || hh->root.type == bfd_link_hash_warning)
+ hh = (struct elf_link_hash_entry *)
+ (hh->root.u.i.link);
+
+ if (hh->root.type == bfd_link_hash_defined
+ || hh->root.type == bfd_link_hash_defweak)
+ {
+ sym_sec = hh->root.u.def.section;
+ sym_value = hh->root.u.def.value;
+ if (sym_sec->output_section != NULL)
+ destination = (sym_value + irela->r_addend
+ + sym_sec->output_offset
+ + sym_sec->output_section->vma);
+ }
+ else if (hh->root.type == bfd_link_hash_undefweak)
+ {
+ if (! info->shared)
+ continue;
+ }
+ else if (hh->root.type == bfd_link_hash_undefined)
+ {
+ if (! (info->unresolved_syms_in_objects == RM_IGNORE
+ && (ELF_ST_VISIBILITY (hh->other)
+ == STV_DEFAULT)))
+ continue;
+ }
+ else
+ {
+ bfd_set_error (bfd_error_bad_value);
+
+ error_ret_free_internal:
+ if (elf_section_data (section)->relocs == NULL)
+ free (internal_relocs);
+ goto error_ret_free_local;
+ }
+ }
+
+ if (! avr_stub_is_required_for_16_bit_reloc
+ (destination - htab->vector_base))
+ {
+ if (!is_prealloc_run)
+ /* We are having a reloc that does't need a stub. */
+ continue;
+
+ /* We don't right now know if a stub will be needed.
+ Let's rather be on the safe side. */
+ }
+
+ /* Get the name of this stub. */
+ stub_name = avr_stub_name (sym_sec, sym_value, irela);
+
+ if (!stub_name)
+ goto error_ret_free_internal;
+
+
+ hsh = avr_stub_hash_lookup (&htab->bstab,
+ stub_name,
+ FALSE, FALSE);
+ if (hsh != NULL)
+ {
+ /* The proper stub has already been created. Mark it
+ to be used and write the possibly changed destination
+ value. */
+ hsh->is_actually_needed = TRUE;
+ hsh->target_value = destination;
+ free (stub_name);
+ continue;
+ }
+
+ hsh = avr_add_stub (stub_name, htab);
+ if (hsh == NULL)
+ {
+ free (stub_name);
+ goto error_ret_free_internal;
+ }
+
+ hsh->is_actually_needed = TRUE;
+ hsh->target_value = destination;
+
+ if (debug_stubs)
+ printf ("Adding stub with destination 0x%x to the"
+ " hash table.\n", (unsigned int) destination);
+ if (debug_stubs)
+ printf ("(Pre-Alloc run: %i)\n", is_prealloc_run);
+
+ stub_changed = TRUE;
+ }
+
+ /* We're done with the internal relocs, free them. */
+ if (elf_section_data (section)->relocs == NULL)
+ free (internal_relocs);
+ }
+ }
+
+ /* Re-Calculate the number of needed stubs. */
+ htab->stub_sec->size = 0;
+ bfd_hash_traverse (&htab->bstab, avr_size_one_stub, htab);
+
+ if (!stub_changed)
+ break;
+
+ stub_changed = FALSE;
+ }
+
+ free (htab->all_local_syms);
+ return TRUE;
+
+ error_ret_free_local:
+ free (htab->all_local_syms);
+ return FALSE;
+}
+
+
+/* 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. We also set up the .plt entries for statically linked PIC
+ functions here. This function is called via hppaelf_finish in the
+ linker. */
+
+bfd_boolean
+elf32_avr_build_stubs (struct bfd_link_info *info)
+{
+ asection *stub_sec;
+ struct bfd_hash_table *table;
+ struct elf32_avr_link_hash_table *htab;
+ bfd_size_type total_size = 0;
+
+ htab = avr_link_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ /* In case that there were several stub sections: */
+ for (stub_sec = htab->stub_bfd->sections;
+ stub_sec != NULL;
+ stub_sec = stub_sec->next)
+ {
+ bfd_size_type size;
+
+ /* Allocate memory to hold the linker stubs. */
+ size = stub_sec->size;
+ total_size += size;
+
+ stub_sec->contents = bfd_zalloc (htab->stub_bfd, size);
+ if (stub_sec->contents == NULL && size != 0)
+ return FALSE;
+ stub_sec->size = 0;
+ }
+
+ /* Allocate memory for the adress mapping table. */
+ htab->amt_entry_cnt = 0;
+ htab->amt_max_entry_cnt = total_size / 4;
+ htab->amt_stub_offsets = bfd_malloc (sizeof (bfd_vma)
+ * htab->amt_max_entry_cnt);
+ htab->amt_destination_addr = bfd_malloc (sizeof (bfd_vma)
+ * htab->amt_max_entry_cnt );
+
+ if (debug_stubs)
+ printf ("Allocating %i entries in the AMT\n", htab->amt_max_entry_cnt);
+
+ /* Build the stubs as directed by the stub hash table. */
+ table = &htab->bstab;
+ bfd_hash_traverse (table, avr_build_one_stub, info);
+
+ if (debug_stubs)
+ printf ("Final Stub section Size: %i\n", (int) htab->stub_sec->size);
+
+ return TRUE;
+}
+
+#define ELF_ARCH bfd_arch_avr
+#define ELF_TARGET_ID AVR_ELF_DATA
+#define ELF_MACHINE_CODE EM_AVR
+#define ELF_MACHINE_ALT1 EM_AVR_OLD
+#define ELF_MAXPAGESIZE 1
+
+#define TARGET_LITTLE_SYM avr_elf32_vec
+#define TARGET_LITTLE_NAME "elf32-avr"
+
+#define bfd_elf32_bfd_link_hash_table_create elf32_avr_link_hash_table_create
+
+#define elf_info_to_howto avr_info_to_howto_rela
+#define elf_info_to_howto_rel NULL
+#define elf_backend_relocate_section elf32_avr_relocate_section
+#define elf_backend_can_gc_sections 1
+#define elf_backend_rela_normal 1
+#define elf_backend_final_write_processing \
+ bfd_elf_avr_final_write_processing
+#define elf_backend_object_p elf32_avr_object_p
+
+#define bfd_elf32_bfd_relax_section elf32_avr_relax_section
+#define bfd_elf32_bfd_get_relocated_section_contents \
+ elf32_avr_get_relocated_section_contents
+
+#include "elf32-target.h"
diff --git a/bfd/elf32-avr.h b/bfd/elf32-avr.h
new file mode 100644
index 0000000..8c33868
--- /dev/null
+++ b/bfd/elf32-avr.h
@@ -0,0 +1,38 @@
+/* AVR-specific support for 32-bit ELF.
+ Copyright (C) 2006-2014 Free Software Foundation, Inc.
+
+ Written by Bjoern Haase <bjoern.m.haase@web.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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor,
+ Boston, MA 02110-1301, USA. */
+
+
+/* These four functions will be called from the ld back-end. */
+
+extern void
+elf32_avr_setup_params (struct bfd_link_info *, bfd *, asection *,
+ bfd_boolean, bfd_boolean, bfd_boolean,
+ bfd_vma, bfd_boolean);
+
+extern int
+elf32_avr_setup_section_lists (bfd *, struct bfd_link_info *);
+
+extern bfd_boolean
+elf32_avr_size_stubs (bfd *, struct bfd_link_info *, bfd_boolean);
+
+extern bfd_boolean
+elf32_avr_build_stubs (struct bfd_link_info *);
diff --git a/bfd/elf32-bfin.c b/bfd/elf32-bfin.c
new file mode 100644
index 0000000..692875b
--- /dev/null
+++ b/bfd/elf32-bfin.c
@@ -0,0 +1,5753 @@
+/* ADI Blackfin BFD support for 32-bit ELF.
+ Copyright (C) 2005-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+#include "elf-bfd.h"
+#include "elf/bfin.h"
+#include "dwarf2.h"
+#include "hashtab.h"
+
+/* FUNCTION : bfin_pltpc_reloc
+ ABSTRACT : TODO : figure out how to handle pltpc relocs. */
+static bfd_reloc_status_type
+bfin_pltpc_reloc (
+ bfd *abfd ATTRIBUTE_UNUSED,
+ arelent *reloc_entry ATTRIBUTE_UNUSED,
+ asymbol *symbol ATTRIBUTE_UNUSED,
+ void * data ATTRIBUTE_UNUSED,
+ asection *input_section ATTRIBUTE_UNUSED,
+ bfd *output_bfd ATTRIBUTE_UNUSED,
+ char **error_message ATTRIBUTE_UNUSED)
+{
+ bfd_reloc_status_type flag = bfd_reloc_ok;
+ return flag;
+}
+
+
+static bfd_reloc_status_type
+bfin_pcrel24_reloc (bfd *abfd,
+ arelent *reloc_entry,
+ asymbol *symbol,
+ void * data,
+ asection *input_section,
+ bfd *output_bfd,
+ char **error_message ATTRIBUTE_UNUSED)
+{
+ bfd_vma relocation;
+ bfd_size_type addr = reloc_entry->address;
+ bfd_vma output_base = 0;
+ reloc_howto_type *howto = reloc_entry->howto;
+ asection *output_section;
+ bfd_boolean relocatable = (output_bfd != NULL);
+
+ if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
+ return bfd_reloc_outofrange;
+
+ if (bfd_is_und_section (symbol->section)
+ && (symbol->flags & BSF_WEAK) == 0
+ && !relocatable)
+ return bfd_reloc_undefined;
+
+ if (bfd_is_com_section (symbol->section))
+ relocation = 0;
+ else
+ relocation = symbol->value;
+
+ output_section = symbol->section->output_section;
+
+ if (relocatable)
+ output_base = 0;
+ else
+ output_base = output_section->vma;
+
+ if (!relocatable || !strcmp (symbol->name, symbol->section->name))
+ relocation += output_base + symbol->section->output_offset;
+
+ if (!relocatable && !strcmp (symbol->name, symbol->section->name))
+ relocation += reloc_entry->addend;
+
+ relocation -= input_section->output_section->vma + input_section->output_offset;
+ relocation -= reloc_entry->address;
+
+ if (howto->complain_on_overflow != complain_overflow_dont)
+ {
+ bfd_reloc_status_type status;
+ status = bfd_check_overflow (howto->complain_on_overflow,
+ howto->bitsize,
+ howto->rightshift,
+ bfd_arch_bits_per_address(abfd),
+ relocation);
+ if (status != bfd_reloc_ok)
+ return status;
+ }
+
+ /* if rightshift is 1 and the number odd, return error. */
+ if (howto->rightshift && (relocation & 0x01))
+ {
+ (*_bfd_error_handler) (_("relocation should be even number"));
+ return bfd_reloc_overflow;
+ }
+
+ relocation >>= (bfd_vma) howto->rightshift;
+ /* Shift everything up to where it's going to be used. */
+
+ relocation <<= (bfd_vma) howto->bitpos;
+
+ if (relocatable)
+ {
+ reloc_entry->address += input_section->output_offset;
+ reloc_entry->addend += symbol->section->output_offset;
+ }
+
+ {
+ short x;
+
+ /* We are getting reloc_entry->address 2 byte off from
+ the start of instruction. Assuming absolute postion
+ of the reloc data. But, following code had been written assuming
+ reloc address is starting at begining of instruction.
+ To compensate that I have increased the value of
+ relocation by 1 (effectively 2) and used the addr -2 instead of addr. */
+
+ relocation += 1;
+ x = bfd_get_16 (abfd, (bfd_byte *) data + addr - 2);
+ x = (x & 0xff00) | ((relocation >> 16) & 0xff);
+ bfd_put_16 (abfd, x, (unsigned char *) data + addr - 2);
+
+ x = bfd_get_16 (abfd, (bfd_byte *) data + addr);
+ x = relocation & 0xFFFF;
+ bfd_put_16 (abfd, x, (unsigned char *) data + addr );
+ }
+ return bfd_reloc_ok;
+}
+
+static bfd_reloc_status_type
+bfin_imm16_reloc (bfd *abfd,
+ arelent *reloc_entry,
+ asymbol *symbol,
+ void * data,
+ asection *input_section,
+ bfd *output_bfd,
+ char **error_message ATTRIBUTE_UNUSED)
+{
+ bfd_vma relocation, x;
+ bfd_size_type reloc_addr = reloc_entry->address;
+ bfd_vma output_base = 0;
+ reloc_howto_type *howto = reloc_entry->howto;
+ asection *output_section;
+ bfd_boolean relocatable = (output_bfd != NULL);
+
+ /* Is the address of the relocation really within the section? */
+ if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
+ return bfd_reloc_outofrange;
+
+ if (bfd_is_und_section (symbol->section)
+ && (symbol->flags & BSF_WEAK) == 0
+ && !relocatable)
+ return bfd_reloc_undefined;
+
+ output_section = symbol->section->output_section;
+ relocation = symbol->value;
+
+ /* Convert input-section-relative symbol value to absolute. */
+ if (relocatable)
+ output_base = 0;
+ else
+ output_base = output_section->vma;
+
+ if (!relocatable || !strcmp (symbol->name, symbol->section->name))
+ relocation += output_base + symbol->section->output_offset;
+
+ /* Add in supplied addend. */
+ relocation += reloc_entry->addend;
+
+ if (relocatable)
+ {
+ reloc_entry->address += input_section->output_offset;
+ reloc_entry->addend += symbol->section->output_offset;
+ }
+ else
+ {
+ reloc_entry->addend = 0;
+ }
+
+ if (howto->complain_on_overflow != complain_overflow_dont)
+ {
+ bfd_reloc_status_type flag;
+ flag = bfd_check_overflow (howto->complain_on_overflow,
+ howto->bitsize,
+ howto->rightshift,
+ bfd_arch_bits_per_address(abfd),
+ relocation);
+ if (flag != bfd_reloc_ok)
+ return flag;
+ }
+
+ /* Here the variable relocation holds the final address of the
+ symbol we are relocating against, plus any addend. */
+
+ relocation >>= (bfd_vma) howto->rightshift;
+ x = relocation;
+ bfd_put_16 (abfd, x, (unsigned char *) data + reloc_addr);
+ return bfd_reloc_ok;
+}
+
+
+static bfd_reloc_status_type
+bfin_byte4_reloc (bfd *abfd,
+ arelent *reloc_entry,
+ asymbol *symbol,
+ void * data,
+ asection *input_section,
+ bfd *output_bfd,
+ char **error_message ATTRIBUTE_UNUSED)
+{
+ bfd_vma relocation, x;
+ bfd_size_type addr = reloc_entry->address;
+ bfd_vma output_base = 0;
+ asection *output_section;
+ bfd_boolean relocatable = (output_bfd != NULL);
+
+ /* Is the address of the relocation really within the section? */
+ if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
+ return bfd_reloc_outofrange;
+
+ if (bfd_is_und_section (symbol->section)
+ && (symbol->flags & BSF_WEAK) == 0
+ && !relocatable)
+ return bfd_reloc_undefined;
+
+ output_section = symbol->section->output_section;
+ relocation = symbol->value;
+ /* Convert input-section-relative symbol value to absolute. */
+ if (relocatable)
+ output_base = 0;
+ else
+ output_base = output_section->vma;
+
+ if ((symbol->name
+ && symbol->section->name
+ && !strcmp (symbol->name, symbol->section->name))
+ || !relocatable)
+ {
+ relocation += output_base + symbol->section->output_offset;
+ }
+
+ relocation += reloc_entry->addend;
+
+ if (relocatable)
+ {
+ /* This output will be relocatable ... like ld -r. */
+ reloc_entry->address += input_section->output_offset;
+ reloc_entry->addend += symbol->section->output_offset;
+ }
+ else
+ {
+ reloc_entry->addend = 0;
+ }
+
+ /* Here the variable relocation holds the final address of the
+ symbol we are relocating against, plus any addend. */
+ x = relocation & 0xFFFF0000;
+ x >>=16;
+ bfd_put_16 (abfd, x, (unsigned char *) data + addr + 2);
+
+ x = relocation & 0x0000FFFF;
+ bfd_put_16 (abfd, x, (unsigned char *) data + addr);
+ return bfd_reloc_ok;
+}
+
+/* bfin_bfd_reloc handles the blackfin arithmetic relocations.
+ Use this instead of bfd_perform_relocation. */
+static bfd_reloc_status_type
+bfin_bfd_reloc (bfd *abfd,
+ arelent *reloc_entry,
+ asymbol *symbol,
+ void * data,
+ asection *input_section,
+ bfd *output_bfd,
+ char **error_message ATTRIBUTE_UNUSED)
+{
+ bfd_vma relocation;
+ bfd_size_type addr = reloc_entry->address;
+ bfd_vma output_base = 0;
+ reloc_howto_type *howto = reloc_entry->howto;
+ asection *output_section;
+ bfd_boolean relocatable = (output_bfd != NULL);
+
+ /* Is the address of the relocation really within the section? */
+ if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
+ return bfd_reloc_outofrange;
+
+ if (bfd_is_und_section (symbol->section)
+ && (symbol->flags & BSF_WEAK) == 0
+ && !relocatable)
+ return bfd_reloc_undefined;
+
+ /* Get symbol value. (Common symbols are special.) */
+ if (bfd_is_com_section (symbol->section))
+ relocation = 0;
+ else
+ relocation = symbol->value;
+
+ output_section = symbol->section->output_section;
+
+ /* Convert input-section-relative symbol value to absolute. */
+ if (relocatable)
+ output_base = 0;
+ else
+ output_base = output_section->vma;
+
+ if (!relocatable || !strcmp (symbol->name, symbol->section->name))
+ relocation += output_base + symbol->section->output_offset;
+
+ if (!relocatable && !strcmp (symbol->name, symbol->section->name))
+ {
+ /* 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 (relocatable)
+ {
+ reloc_entry->address += input_section->output_offset;
+ reloc_entry->addend += symbol->section->output_offset;
+ }
+
+ if (howto->complain_on_overflow != complain_overflow_dont)
+ {
+ bfd_reloc_status_type status;
+
+ status = bfd_check_overflow (howto->complain_on_overflow,
+ howto->bitsize,
+ howto->rightshift,
+ bfd_arch_bits_per_address(abfd),
+ relocation);
+ if (status != bfd_reloc_ok)
+ return status;
+ }
+
+ /* If rightshift is 1 and the number odd, return error. */
+ if (howto->rightshift && (relocation & 0x01))
+ {
+ (*_bfd_error_handler) (_("relocation should be even number"));
+ return bfd_reloc_overflow;
+ }
+
+ relocation >>= (bfd_vma) howto->rightshift;
+
+ /* Shift everything up to where it's going to be used. */
+
+ relocation <<= (bfd_vma) howto->bitpos;
+
+#define DOIT(x) \
+ x = ( (x & ~howto->dst_mask) | (relocation & howto->dst_mask))
+
+ /* handle 8 and 16 bit relocations here. */
+ 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:
+ {
+ unsigned short x = bfd_get_16 (abfd, (bfd_byte *) data + addr);
+ DOIT (x);
+ bfd_put_16 (abfd, (bfd_vma) x, (unsigned char *) data + addr);
+ }
+ break;
+
+ default:
+ return bfd_reloc_other;
+ }
+
+ return bfd_reloc_ok;
+}
+
+/* HOWTO Table for blackfin.
+ Blackfin relocations are fairly complicated.
+ Some of the salient features are
+ a. Even numbered offsets. A number of (not all) relocations are
+ even numbered. This means that the rightmost bit is not stored.
+ Needs to right shift by 1 and check to see if value is not odd
+ b. A relocation can be an expression. An expression takes on
+ a variety of relocations arranged in a stack.
+ As a result, we cannot use the standard generic function as special
+ function. We will have our own, which is very similar to the standard
+ generic function except that it understands how to get the value from
+ the relocation stack. . */
+
+#define BFIN_RELOC_MIN 0
+#define BFIN_RELOC_MAX 0x21
+#define BFIN_GNUEXT_RELOC_MIN 0x40
+#define BFIN_GNUEXT_RELOC_MAX 0x43
+#define BFIN_ARELOC_MIN 0xE0
+#define BFIN_ARELOC_MAX 0xF3
+
+static reloc_howto_type bfin_howto_table [] =
+{
+ /* This reloc does nothing. . */
+ HOWTO (R_BFIN_UNUSED0, /* 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_BFIN_UNUSED0", /* name. */
+ FALSE, /* partial_inplace. */
+ 0, /* src_mask. */
+ 0, /* dst_mask. */
+ FALSE), /* pcrel_offset. */
+
+ HOWTO (R_BFIN_PCREL5M2, /* type. */
+ 1, /* rightshift. */
+ 1, /* size (0 = byte, 1 = short, 2 = long).. */
+ 4, /* bitsize. */
+ TRUE, /* pc_relative. */
+ 0, /* bitpos. */
+ complain_overflow_unsigned, /* complain_on_overflow. */
+ bfin_bfd_reloc, /* special_function. */
+ "R_BFIN_PCREL5M2", /* name. */
+ FALSE, /* partial_inplace. */
+ 0, /* src_mask. */
+ 0x0000000F, /* dst_mask. */
+ FALSE), /* pcrel_offset. */
+
+ HOWTO (R_BFIN_UNUSED1, /* 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_BFIN_UNUSED1", /* name. */
+ FALSE, /* partial_inplace. */
+ 0, /* src_mask. */
+ 0, /* dst_mask. */
+ FALSE), /* pcrel_offset. */
+
+ HOWTO (R_BFIN_PCREL10, /* type. */
+ 1, /* rightshift. */
+ 1, /* size (0 = byte, 1 = short, 2 = long). */
+ 10, /* bitsize. */
+ TRUE, /* pc_relative. */
+ 0, /* bitpos. */
+ complain_overflow_signed, /* complain_on_overflow. */
+ bfin_bfd_reloc, /* special_function. */
+ "R_BFIN_PCREL10", /* name. */
+ FALSE, /* partial_inplace. */
+ 0, /* src_mask. */
+ 0x000003FF, /* dst_mask. */
+ TRUE), /* pcrel_offset. */
+
+ HOWTO (R_BFIN_PCREL12_JUMP, /* type. */
+ 1, /* rightshift. */
+ /* the offset is actually 13 bit
+ aligned on a word boundary so
+ only 12 bits have to be used.
+ Right shift the rightmost bit.. */
+ 1, /* size (0 = byte, 1 = short, 2 = long). */
+ 12, /* bitsize. */
+ TRUE, /* pc_relative. */
+ 0, /* bitpos. */
+ complain_overflow_signed, /* complain_on_overflow. */
+ bfin_bfd_reloc, /* special_function. */
+ "R_BFIN_PCREL12_JUMP", /* name. */
+ FALSE, /* partial_inplace. */
+ 0, /* src_mask. */
+ 0x0FFF, /* dst_mask. */
+ TRUE), /* pcrel_offset. */
+
+ HOWTO (R_BFIN_RIMM16, /* type. */
+ 0, /* rightshift. */
+ 1, /* size (0 = byte, 1 = short, 2 = long). */
+ 16, /* bitsize. */
+ FALSE, /* pc_relative. */
+ 0, /* bitpos. */
+ complain_overflow_signed, /* complain_on_overflow. */
+ bfin_imm16_reloc, /* special_function. */
+ "R_BFIN_RIMM16", /* name. */
+ FALSE, /* partial_inplace. */
+ 0, /* src_mask. */
+ 0x0000FFFF, /* dst_mask. */
+ TRUE), /* pcrel_offset. */
+
+ HOWTO (R_BFIN_LUIMM16, /* type. */
+ 0, /* rightshift. */
+ 1, /* size (0 = byte, 1 = short, 2 = long). */
+ 16, /* bitsize. */
+ FALSE, /* pc_relative. */
+ 0, /* bitpos. */
+ complain_overflow_dont, /* complain_on_overflow. */
+ bfin_imm16_reloc, /* special_function. */
+ "R_BFIN_LUIMM16", /* name. */
+ FALSE, /* partial_inplace. */
+ 0, /* src_mask. */
+ 0x0000FFFF, /* dst_mask. */
+ TRUE), /* pcrel_offset. */
+
+ HOWTO (R_BFIN_HUIMM16, /* type. */
+ 16, /* rightshift. */
+ 1, /* size (0 = byte, 1 = short, 2 = long). */
+ 16, /* bitsize. */
+ FALSE, /* pc_relative. */
+ 0, /* bitpos. */
+ complain_overflow_unsigned, /* complain_on_overflow. */
+ bfin_imm16_reloc, /* special_function. */
+ "R_BFIN_HUIMM16", /* name. */
+ FALSE, /* partial_inplace. */
+ 0, /* src_mask. */
+ 0x0000FFFF, /* dst_mask. */
+ TRUE), /* pcrel_offset. */
+
+ HOWTO (R_BFIN_PCREL12_JUMP_S, /* type. */
+ 1, /* rightshift. */
+ 1, /* size (0 = byte, 1 = short, 2 = long). */
+ 12, /* bitsize. */
+ TRUE, /* pc_relative. */
+ 0, /* bitpos. */
+ complain_overflow_signed, /* complain_on_overflow. */
+ bfin_bfd_reloc, /* special_function. */
+ "R_BFIN_PCREL12_JUMP_S", /* name. */
+ FALSE, /* partial_inplace. */
+ 0, /* src_mask. */
+ 0x00000FFF, /* dst_mask. */
+ TRUE), /* pcrel_offset. */
+
+ HOWTO (R_BFIN_PCREL24_JUMP_X, /* type. */
+ 1, /* rightshift. */
+ 2, /* size (0 = byte, 1 = short, 2 = long). */
+ 24, /* bitsize. */
+ TRUE, /* pc_relative. */
+ 0, /* bitpos. */
+ complain_overflow_signed, /* complain_on_overflow. */
+ bfin_pcrel24_reloc, /* special_function. */
+ "R_BFIN_PCREL24_JUMP_X", /* name. */
+ FALSE, /* partial_inplace. */
+ 0, /* src_mask. */
+ 0x00FFFFFF, /* dst_mask. */
+ TRUE), /* pcrel_offset. */
+
+ HOWTO (R_BFIN_PCREL24, /* type. */
+ 1, /* rightshift. */
+ 2, /* size (0 = byte, 1 = short, 2 = long). */
+ 24, /* bitsize. */
+ TRUE, /* pc_relative. */
+ 0, /* bitpos. */
+ complain_overflow_signed, /* complain_on_overflow. */
+ bfin_pcrel24_reloc, /* special_function. */
+ "R_BFIN_PCREL24", /* name. */
+ FALSE, /* partial_inplace. */
+ 0, /* src_mask. */
+ 0x00FFFFFF, /* dst_mask. */
+ TRUE), /* pcrel_offset. */
+
+ HOWTO (R_BFIN_UNUSEDB, /* type. */
+ 0, /* rightshift. */
+ 2, /* size (0 = byte, 1 = short, 2 = long). */
+ 32, /* bitsize. */
+ FALSE, /* pc_relative. */
+ 0, /* bitpos. */
+ complain_overflow_dont, /* complain_on_overflow. */
+ bfd_elf_generic_reloc, /* special_function. */
+ "R_BFIN_UNUSEDB", /* name. */
+ FALSE, /* partial_inplace. */
+ 0, /* src_mask. */
+ 0, /* dst_mask. */
+ FALSE), /* pcrel_offset. */
+
+ HOWTO (R_BFIN_UNUSEDC, /* type. */
+ 0, /* rightshift. */
+ 2, /* size (0 = byte, 1 = short, 2 = long). */
+ 32, /* bitsize. */
+ FALSE, /* pc_relative. */
+ 0, /* bitpos. */
+ complain_overflow_dont, /* complain_on_overflow. */
+ bfd_elf_generic_reloc, /* special_function. */
+ "R_BFIN_UNUSEDC", /* name. */
+ FALSE, /* partial_inplace. */
+ 0, /* src_mask. */
+ 0, /* dst_mask. */
+ FALSE), /* pcrel_offset. */
+
+ HOWTO (R_BFIN_PCREL24_JUMP_L, /* type. */
+ 1, /* rightshift. */
+ 2, /* size (0 = byte, 1 = short, 2 = long). */
+ 24, /* bitsize. */
+ TRUE, /* pc_relative. */
+ 0, /* bitpos. */
+ complain_overflow_signed, /* complain_on_overflow. */
+ bfin_pcrel24_reloc, /* special_function. */
+ "R_BFIN_PCREL24_JUMP_L", /* name. */
+ FALSE, /* partial_inplace. */
+ 0, /* src_mask. */
+ 0x00FFFFFF, /* dst_mask. */
+ TRUE), /* pcrel_offset. */
+
+ HOWTO (R_BFIN_PCREL24_CALL_X, /* type. */
+ 1, /* rightshift. */
+ 2, /* size (0 = byte, 1 = short, 2 = long). */
+ 24, /* bitsize. */
+ TRUE, /* pc_relative. */
+ 0, /* bitpos. */
+ complain_overflow_signed, /* complain_on_overflow. */
+ bfin_pcrel24_reloc, /* special_function. */
+ "R_BFIN_PCREL24_CALL_X", /* name. */
+ FALSE, /* partial_inplace. */
+ 0, /* src_mask. */
+ 0x00FFFFFF, /* dst_mask. */
+ TRUE), /* pcrel_offset. */
+
+ HOWTO (R_BFIN_VAR_EQ_SYMB, /* type. */
+ 0, /* rightshift. */
+ 2, /* size (0 = byte, 1 = short, 2 = long). */
+ 32, /* bitsize. */
+ FALSE, /* pc_relative. */
+ 0, /* bitpos. */
+ complain_overflow_bitfield, /* complain_on_overflow. */
+ bfin_bfd_reloc, /* special_function. */
+ "R_BFIN_VAR_EQ_SYMB", /* name. */
+ FALSE, /* partial_inplace. */
+ 0, /* src_mask. */
+ 0, /* dst_mask. */
+ FALSE), /* pcrel_offset. */
+
+ HOWTO (R_BFIN_BYTE_DATA, /* type. */
+ 0, /* rightshift. */
+ 0, /* size (0 = byte, 1 = short, 2 = long). */
+ 8, /* bitsize. */
+ FALSE, /* pc_relative. */
+ 0, /* bitpos. */
+ complain_overflow_unsigned, /* complain_on_overflow. */
+ bfin_bfd_reloc, /* special_function. */
+ "R_BFIN_BYTE_DATA", /* name. */
+ FALSE, /* partial_inplace. */
+ 0, /* src_mask. */
+ 0xFF, /* dst_mask. */
+ TRUE), /* pcrel_offset. */
+
+ HOWTO (R_BFIN_BYTE2_DATA, /* type. */
+ 0, /* rightshift. */
+ 1, /* size (0 = byte, 1 = short, 2 = long). */
+ 16, /* bitsize. */
+ FALSE, /* pc_relative. */
+ 0, /* bitpos. */
+ complain_overflow_signed, /* complain_on_overflow. */
+ bfin_bfd_reloc, /* special_function. */
+ "R_BFIN_BYTE2_DATA", /* name. */
+ FALSE, /* partial_inplace. */
+ 0, /* src_mask. */
+ 0xFFFF, /* dst_mask. */
+ TRUE), /* pcrel_offset. */
+
+ HOWTO (R_BFIN_BYTE4_DATA, /* type. */
+ 0, /* rightshift. */
+ 2, /* size (0 = byte, 1 = short, 2 = long). */
+ 32, /* bitsize. */
+ FALSE, /* pc_relative. */
+ 0, /* bitpos. */
+ complain_overflow_unsigned, /* complain_on_overflow. */
+ bfin_byte4_reloc, /* special_function. */
+ "R_BFIN_BYTE4_DATA", /* name. */
+ FALSE, /* partial_inplace. */
+ 0, /* src_mask. */
+ 0xFFFFFFFF, /* dst_mask. */
+ TRUE), /* pcrel_offset. */
+
+ HOWTO (R_BFIN_PCREL11, /* type. */
+ 1, /* rightshift. */
+ 1, /* size (0 = byte, 1 = short, 2 = long). */
+ 10, /* bitsize. */
+ TRUE, /* pc_relative. */
+ 0, /* bitpos. */
+ complain_overflow_unsigned, /* complain_on_overflow. */
+ bfin_bfd_reloc, /* special_function. */
+ "R_BFIN_PCREL11", /* name. */
+ FALSE, /* partial_inplace. */
+ 0, /* src_mask. */
+ 0x000003FF, /* dst_mask. */
+ FALSE), /* pcrel_offset. */
+
+
+ /* A 18-bit signed operand with the GOT offset for the address of
+ the symbol. */
+ HOWTO (R_BFIN_GOT17M4, /* type */
+ 2, /* 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_BFIN_GOT17M4", /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* The upper 16 bits of the GOT offset for the address of the
+ symbol. */
+ HOWTO (R_BFIN_GOTHI, /* 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_BFIN_GOTHI", /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* The lower 16 bits of the GOT offset for the address of the
+ symbol. */
+ HOWTO (R_BFIN_GOTLO, /* 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_BFIN_GOTLO", /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* The 32-bit address of the canonical descriptor of a function. */
+ HOWTO (R_BFIN_FUNCDESC, /* 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_BFIN_FUNCDESC", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A 12-bit signed operand with the GOT offset for the address of
+ canonical descriptor of a function. */
+ HOWTO (R_BFIN_FUNCDESC_GOT17M4, /* type */
+ 2, /* 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_BFIN_FUNCDESC_GOT17M4", /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* The upper 16 bits of the GOT offset for the address of the
+ canonical descriptor of a function. */
+ HOWTO (R_BFIN_FUNCDESC_GOTHI, /* 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_BFIN_FUNCDESC_GOTHI", /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* The lower 16 bits of the GOT offset for the address of the
+ canonical descriptor of a function. */
+ HOWTO (R_BFIN_FUNCDESC_GOTLO, /* 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_BFIN_FUNCDESC_GOTLO", /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* The 32-bit address of the canonical descriptor of a function. */
+ HOWTO (R_BFIN_FUNCDESC_VALUE, /* type */
+ 0, /* rightshift */
+ 2, /* 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_BFIN_FUNCDESC_VALUE", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A 12-bit signed operand with the GOT offset for the address of
+ canonical descriptor of a function. */
+ HOWTO (R_BFIN_FUNCDESC_GOTOFF17M4, /* type */
+ 2, /* 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_BFIN_FUNCDESC_GOTOFF17M4", /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* The upper 16 bits of the GOT offset for the address of the
+ canonical descriptor of a function. */
+ HOWTO (R_BFIN_FUNCDESC_GOTOFFHI, /* 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_BFIN_FUNCDESC_GOTOFFHI", /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* The lower 16 bits of the GOT offset for the address of the
+ canonical descriptor of a function. */
+ HOWTO (R_BFIN_FUNCDESC_GOTOFFLO, /* 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_BFIN_FUNCDESC_GOTOFFLO", /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A 12-bit signed operand with the GOT offset for the address of
+ the symbol. */
+ HOWTO (R_BFIN_GOTOFF17M4, /* type */
+ 2, /* 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_BFIN_GOTOFF17M4", /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* The upper 16 bits of the GOT offset for the address of the
+ symbol. */
+ HOWTO (R_BFIN_GOTOFFHI, /* 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_BFIN_GOTOFFHI", /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* The lower 16 bits of the GOT offset for the address of the
+ symbol. */
+ HOWTO (R_BFIN_GOTOFFLO, /* 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_BFIN_GOTOFFLO", /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+};
+
+static reloc_howto_type bfin_gnuext_howto_table [] =
+{
+ HOWTO (R_BFIN_PLTPC, /* type. */
+ 0, /* rightshift. */
+ 1, /* size (0 = byte, 1 = short, 2 = long). */
+ 16, /* bitsize. */
+ FALSE, /* pc_relative. */
+ 0, /* bitpos. */
+ complain_overflow_bitfield, /* complain_on_overflow. */
+ bfin_pltpc_reloc, /* special_function. */
+ "R_BFIN_PLTPC", /* name. */
+ FALSE, /* partial_inplace. */
+ 0xffff, /* src_mask. */
+ 0xffff, /* dst_mask. */
+ FALSE), /* pcrel_offset. */
+
+ HOWTO (R_BFIN_GOT, /* 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_BFIN_GOT", /* name. */
+ FALSE, /* partial_inplace. */
+ 0x7fff, /* src_mask. */
+ 0x7fff, /* dst_mask. */
+ FALSE), /* pcrel_offset. */
+
+/* GNU extension to record C++ vtable hierarchy. */
+ HOWTO (R_BFIN_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_BFIN_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_BFIN_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_BFIN_GNU_VTENTRY", /* name. */
+ FALSE, /* partial_inplace. */
+ 0, /* src_mask. */
+ 0, /* dst_mask. */
+ FALSE) /* pcrel_offset. */
+};
+
+struct bfin_reloc_map
+{
+ bfd_reloc_code_real_type bfd_reloc_val;
+ unsigned int bfin_reloc_val;
+};
+
+static const struct bfin_reloc_map bfin_reloc_map [] =
+{
+ { BFD_RELOC_NONE, R_BFIN_UNUSED0 },
+ { BFD_RELOC_BFIN_5_PCREL, R_BFIN_PCREL5M2 },
+ { BFD_RELOC_NONE, R_BFIN_UNUSED1 },
+ { BFD_RELOC_BFIN_10_PCREL, R_BFIN_PCREL10 },
+ { BFD_RELOC_BFIN_12_PCREL_JUMP, R_BFIN_PCREL12_JUMP },
+ { BFD_RELOC_BFIN_16_IMM, R_BFIN_RIMM16 },
+ { BFD_RELOC_BFIN_16_LOW, R_BFIN_LUIMM16 },
+ { BFD_RELOC_BFIN_16_HIGH, R_BFIN_HUIMM16 },
+ { BFD_RELOC_BFIN_12_PCREL_JUMP_S, R_BFIN_PCREL12_JUMP_S },
+ { BFD_RELOC_24_PCREL, R_BFIN_PCREL24 },
+ { BFD_RELOC_24_PCREL, R_BFIN_PCREL24 },
+ { BFD_RELOC_BFIN_24_PCREL_JUMP_L, R_BFIN_PCREL24_JUMP_L },
+ { BFD_RELOC_NONE, R_BFIN_UNUSEDB },
+ { BFD_RELOC_NONE, R_BFIN_UNUSEDC },
+ { BFD_RELOC_BFIN_24_PCREL_CALL_X, R_BFIN_PCREL24_CALL_X },
+ { BFD_RELOC_8, R_BFIN_BYTE_DATA },
+ { BFD_RELOC_16, R_BFIN_BYTE2_DATA },
+ { BFD_RELOC_32, R_BFIN_BYTE4_DATA },
+ { BFD_RELOC_BFIN_11_PCREL, R_BFIN_PCREL11 },
+ { BFD_RELOC_BFIN_GOT, R_BFIN_GOT },
+ { BFD_RELOC_BFIN_PLTPC, R_BFIN_PLTPC },
+
+ { BFD_RELOC_BFIN_GOT17M4, R_BFIN_GOT17M4 },
+ { BFD_RELOC_BFIN_GOTHI, R_BFIN_GOTHI },
+ { BFD_RELOC_BFIN_GOTLO, R_BFIN_GOTLO },
+ { BFD_RELOC_BFIN_FUNCDESC, R_BFIN_FUNCDESC },
+ { BFD_RELOC_BFIN_FUNCDESC_GOT17M4, R_BFIN_FUNCDESC_GOT17M4 },
+ { BFD_RELOC_BFIN_FUNCDESC_GOTHI, R_BFIN_FUNCDESC_GOTHI },
+ { BFD_RELOC_BFIN_FUNCDESC_GOTLO, R_BFIN_FUNCDESC_GOTLO },
+ { BFD_RELOC_BFIN_FUNCDESC_VALUE, R_BFIN_FUNCDESC_VALUE },
+ { BFD_RELOC_BFIN_FUNCDESC_GOTOFF17M4, R_BFIN_FUNCDESC_GOTOFF17M4 },
+ { BFD_RELOC_BFIN_FUNCDESC_GOTOFFHI, R_BFIN_FUNCDESC_GOTOFFHI },
+ { BFD_RELOC_BFIN_FUNCDESC_GOTOFFLO, R_BFIN_FUNCDESC_GOTOFFLO },
+ { BFD_RELOC_BFIN_GOTOFF17M4, R_BFIN_GOTOFF17M4 },
+ { BFD_RELOC_BFIN_GOTOFFHI, R_BFIN_GOTOFFHI },
+ { BFD_RELOC_BFIN_GOTOFFLO, R_BFIN_GOTOFFLO },
+
+ { BFD_RELOC_VTABLE_INHERIT, R_BFIN_GNU_VTINHERIT },
+ { BFD_RELOC_VTABLE_ENTRY, R_BFIN_GNU_VTENTRY },
+};
+
+
+static void
+bfin_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED,
+ arelent *cache_ptr,
+ Elf_Internal_Rela *dst)
+{
+ unsigned int r_type;
+
+ r_type = ELF32_R_TYPE (dst->r_info);
+
+ if (r_type <= BFIN_RELOC_MAX)
+ cache_ptr->howto = &bfin_howto_table [r_type];
+
+ else if (r_type >= BFIN_GNUEXT_RELOC_MIN && r_type <= BFIN_GNUEXT_RELOC_MAX)
+ cache_ptr->howto = &bfin_gnuext_howto_table [r_type - BFIN_GNUEXT_RELOC_MIN];
+
+ else
+ cache_ptr->howto = (reloc_howto_type *) NULL;
+}
+
+/* Given a BFD reloc type, return the howto. */
+static reloc_howto_type *
+bfin_bfd_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED,
+ bfd_reloc_code_real_type code)
+{
+ unsigned int i;
+ unsigned int r_type = BFIN_RELOC_MIN;
+
+ for (i = sizeof (bfin_reloc_map) / sizeof (bfin_reloc_map[0]); --i;)
+ if (bfin_reloc_map[i].bfd_reloc_val == code)
+ r_type = bfin_reloc_map[i].bfin_reloc_val;
+
+ if (r_type <= BFIN_RELOC_MAX && r_type > BFIN_RELOC_MIN)
+ return &bfin_howto_table [r_type];
+
+ else if (r_type >= BFIN_GNUEXT_RELOC_MIN && r_type <= BFIN_GNUEXT_RELOC_MAX)
+ return &bfin_gnuext_howto_table [r_type - BFIN_GNUEXT_RELOC_MIN];
+
+ return (reloc_howto_type *) NULL;
+}
+
+static reloc_howto_type *
+bfin_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ const char *r_name)
+{
+ unsigned int i;
+
+ for (i = 0;
+ i < (sizeof (bfin_howto_table)
+ / sizeof (bfin_howto_table[0]));
+ i++)
+ if (bfin_howto_table[i].name != NULL
+ && strcasecmp (bfin_howto_table[i].name, r_name) == 0)
+ return &bfin_howto_table[i];
+
+ for (i = 0;
+ i < (sizeof (bfin_gnuext_howto_table)
+ / sizeof (bfin_gnuext_howto_table[0]));
+ i++)
+ if (bfin_gnuext_howto_table[i].name != NULL
+ && strcasecmp (bfin_gnuext_howto_table[i].name, r_name) == 0)
+ return &bfin_gnuext_howto_table[i];
+
+ return NULL;
+}
+
+/* Given a bfin relocation type, return the howto. */
+static reloc_howto_type *
+bfin_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED,
+ unsigned int r_type)
+{
+ if (r_type <= BFIN_RELOC_MAX)
+ return &bfin_howto_table [r_type];
+
+ else if (r_type >= BFIN_GNUEXT_RELOC_MIN && r_type <= BFIN_GNUEXT_RELOC_MAX)
+ return &bfin_gnuext_howto_table [r_type - BFIN_GNUEXT_RELOC_MIN];
+
+ return (reloc_howto_type *) NULL;
+}
+
+/* Set by ld emulation if --code-in-l1. */
+bfd_boolean elf32_bfin_code_in_l1 = 0;
+
+/* Set by ld emulation if --data-in-l1. */
+bfd_boolean elf32_bfin_data_in_l1 = 0;
+
+static void
+elf32_bfin_final_write_processing (bfd *abfd,
+ bfd_boolean linker ATTRIBUTE_UNUSED)
+{
+ if (elf32_bfin_code_in_l1)
+ elf_elfheader (abfd)->e_flags |= EF_BFIN_CODE_IN_L1;
+ if (elf32_bfin_data_in_l1)
+ elf_elfheader (abfd)->e_flags |= EF_BFIN_DATA_IN_L1;
+}
+
+/* Return TRUE if the name is a local label.
+ bfin local labels begin with L$. */
+static bfd_boolean
+bfin_is_local_label_name (bfd *abfd, const char *label)
+{
+ if (label[0] == 'L' && label[1] == '$' )
+ return TRUE;
+
+ return _bfd_elf_is_local_label_name (abfd, label);
+}
+
+/* Look through the relocs for a section during the first phase, and
+ allocate space in the global offset table or procedure linkage
+ table. */
+
+static bfd_boolean
+bfin_check_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;
+
+ if (info->relocatable)
+ 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;
+
+ 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];
+
+ /* PR15323, ref flags aren't set for references in the same
+ object. */
+ h->root.non_ir_ref = 1;
+ }
+
+ switch (ELF32_R_TYPE (rel->r_info))
+ {
+ /* This relocation describes the C++ object vtable hierarchy.
+ Reconstruct it for later use during GC. */
+ case R_BFIN_GNU_VTINHERIT:
+ if (!bfd_elf_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_BFIN_GNU_VTENTRY:
+ BFD_ASSERT (h != NULL);
+ if (h != NULL
+ && !bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
+ return FALSE;
+ break;
+
+ case R_BFIN_GOT:
+ if (h != NULL
+ && strcmp (h->root.root.string, "__GLOBAL_OFFSET_TABLE_") == 0)
+ break;
+ /* Fall through. */
+
+ 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_linker_section (dynobj, ".got");
+ BFD_ASSERT (sgot != NULL);
+ }
+
+ if (srelgot == NULL && (h != NULL || info->shared))
+ {
+ srelgot = bfd_get_linker_section (dynobj, ".rela.got");
+ if (srelgot == NULL)
+ {
+ flagword flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS
+ | SEC_IN_MEMORY | SEC_LINKER_CREATED
+ | SEC_READONLY);
+ srelgot = bfd_make_section_anyway_with_flags (dynobj,
+ ".rela.got",
+ flags);
+ if (srelgot == NULL
+ || !bfd_set_section_alignment (dynobj, srelgot, 2))
+ return FALSE;
+ }
+ }
+
+ if (h != NULL)
+ {
+ if (h->got.refcount == 0)
+ {
+ /* Make sure this symbol is output as a dynamic symbol. */
+ if (h->dynindx == -1 && !h->forced_local)
+ {
+ if (!bfd_elf_link_record_dynamic_symbol (info, h))
+ return FALSE;
+ }
+
+ /* Allocate space in the .got section. */
+ sgot->size += 4;
+ /* Allocate relocation space. */
+ srelgot->size += sizeof (Elf32_External_Rela);
+ }
+ h->got.refcount++;
+ }
+ else
+ {
+ /* This is a global offset table entry for a local symbol. */
+ if (local_got_refcounts == NULL)
+ {
+ bfd_size_type size;
+
+ size = symtab_hdr->sh_info;
+ size *= sizeof (bfd_signed_vma);
+ local_got_refcounts = ((bfd_signed_vma *)
+ bfd_zalloc (abfd, size));
+ if (local_got_refcounts == NULL)
+ return FALSE;
+ elf_local_got_refcounts (abfd) = local_got_refcounts;
+ }
+ if (local_got_refcounts[r_symndx] == 0)
+ {
+ sgot->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->size += sizeof (Elf32_External_Rela);
+ }
+ }
+ local_got_refcounts[r_symndx]++;
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ return TRUE;
+}
+
+static enum elf_reloc_type_class
+elf32_bfin_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ const asection *rel_sec ATTRIBUTE_UNUSED,
+ const Elf_Internal_Rela * rela)
+{
+ switch ((int) ELF32_R_TYPE (rela->r_info))
+ {
+ default:
+ return reloc_class_normal;
+ }
+}
+
+static bfd_reloc_status_type
+bfin_final_link_relocate (Elf_Internal_Rela *rel, reloc_howto_type *howto,
+ bfd *input_bfd, asection *input_section,
+ bfd_byte *contents, bfd_vma address,
+ bfd_vma value, bfd_vma addend)
+{
+ int r_type = ELF32_R_TYPE (rel->r_info);
+
+ if (r_type == R_BFIN_PCREL24 || r_type == R_BFIN_PCREL24_JUMP_L)
+ {
+ bfd_reloc_status_type r = bfd_reloc_ok;
+ bfd_vma x;
+
+ if (address > bfd_get_section_limit (input_bfd, input_section))
+ return bfd_reloc_outofrange;
+
+ value += addend;
+
+ /* Perform usual pc-relative correction. */
+ value -= input_section->output_section->vma + input_section->output_offset;
+ value -= address;
+
+ /* We are getting reloc_entry->address 2 byte off from
+ the start of instruction. Assuming absolute postion
+ of the reloc data. But, following code had been written assuming
+ reloc address is starting at begining of instruction.
+ To compensate that I have increased the value of
+ relocation by 1 (effectively 2) and used the addr -2 instead of addr. */
+
+ value += 2;
+ address -= 2;
+
+ if ((value & 0xFF000000) != 0
+ && (value & 0xFF000000) != 0xFF000000)
+ r = bfd_reloc_overflow;
+
+ value >>= 1;
+
+ x = bfd_get_16 (input_bfd, contents + address);
+ x = (x & 0xff00) | ((value >> 16) & 0xff);
+ bfd_put_16 (input_bfd, x, contents + address);
+
+ x = bfd_get_16 (input_bfd, contents + address + 2);
+ x = value & 0xFFFF;
+ bfd_put_16 (input_bfd, x, contents + address + 2);
+ return r;
+ }
+
+ return _bfd_final_link_relocate (howto, input_bfd, input_section, contents,
+ rel->r_offset, value, addend);
+
+}
+
+static bfd_boolean
+bfin_relocate_section (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;
+ Elf_Internal_Rela *rel;
+ Elf_Internal_Rela *relend;
+ int i = 0;
+
+ 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;
+
+ rel = relocs;
+ relend = relocs + input_section->reloc_count;
+ for (; rel < relend; rel++, i++)
+ {
+ 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 = 0;
+ bfd_boolean unresolved_reloc;
+ bfd_reloc_status_type r;
+ bfd_vma address;
+
+ r_type = ELF32_R_TYPE (rel->r_info);
+ if (r_type < 0 || r_type >= 243)
+ {
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+
+ if (r_type == R_BFIN_GNU_VTENTRY
+ || r_type == R_BFIN_GNU_VTINHERIT)
+ continue;
+
+ howto = bfin_reloc_type_lookup (input_bfd, r_type);
+ if (howto == NULL)
+ {
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+ r_symndx = ELF32_R_SYM (rel->r_info);
+
+ h = NULL;
+ sym = NULL;
+ sec = NULL;
+ unresolved_reloc = FALSE;
+
+ if (r_symndx < symtab_hdr->sh_info)
+ {
+ sym = local_syms + r_symndx;
+ sec = local_sections[r_symndx];
+ relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
+ }
+ else
+ {
+ bfd_boolean warned, ignored;
+
+ RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
+ r_symndx, symtab_hdr, sym_hashes,
+ h, sec, relocation,
+ unresolved_reloc, warned, ignored);
+ }
+
+ if (sec != NULL && discarded_section (sec))
+ RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+ rel, 1, relend, howto, 0, contents);
+
+ if (info->relocatable)
+ continue;
+
+ address = rel->r_offset;
+
+ /* Then, process normally. */
+ switch (r_type)
+ {
+ case R_BFIN_GNU_VTINHERIT:
+ case R_BFIN_GNU_VTENTRY:
+ return bfd_reloc_ok;
+
+ case R_BFIN_GOT:
+ /* 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)
+ goto do_default;
+ /* Fall through. */
+ /* Relocation is the offset of the entry for this symbol in
+ the global offset table. */
+
+ {
+ bfd_vma off;
+
+ if (dynobj == NULL)
+ {
+ /* Create the .got section. */
+ elf_hash_table (info)->dynobj = dynobj = output_bfd;
+ if (!_bfd_elf_create_got_section (dynobj, info))
+ return FALSE;
+ }
+
+ if (sgot == NULL)
+ {
+ sgot = bfd_get_linker_section (dynobj, ".got");
+ BFD_ASSERT (sgot != NULL);
+ }
+
+ if (h != NULL)
+ {
+ bfd_boolean dyn;
+
+ off = h->got.offset;
+ BFD_ASSERT (off != (bfd_vma) - 1);
+ dyn = elf_hash_table (info)->dynamic_sections_created;
+
+ if (!WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h)
+ || (info->shared
+ && (info->symbolic
+ || h->dynindx == -1
+ || h->forced_local)
+ && h->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
+ unresolved_reloc = FALSE;
+ }
+ else
+ {
+ 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 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 *s;
+ Elf_Internal_Rela outrel;
+ bfd_byte *loc;
+
+ s = bfd_get_linker_section (dynobj, ".rela.got");
+ BFD_ASSERT (s != NULL);
+
+ outrel.r_offset = (sgot->output_section->vma
+ + sgot->output_offset + off);
+ outrel.r_info =
+ ELF32_R_INFO (0, R_BFIN_PCREL24);
+ outrel.r_addend = relocation;
+ loc = s->contents;
+ loc +=
+ s->reloc_count++ * sizeof (Elf32_External_Rela);
+ bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
+ }
+
+ local_got_offsets[r_symndx] |= 1;
+ }
+ }
+
+ relocation = sgot->output_offset + off;
+ rel->r_addend = 0;
+ /* bfin : preg = [preg + 17bitdiv4offset] relocation is div by 4. */
+ relocation /= 4;
+ }
+ goto do_default;
+
+ default:
+ do_default:
+ r = bfin_final_link_relocate (rel, howto, input_bfd, input_section,
+ contents, address,
+ relocation, rel->r_addend);
+
+ break;
+ }
+
+ /* Dynamic relocs are not propagated for SEC_DEBUGGING sections
+ because such sections are not SEC_ALLOC and thus ld.so will
+ not process them. */
+ if (unresolved_reloc
+ && !((input_section->flags & SEC_DEBUGGING) != 0 && h->def_dynamic)
+ && _bfd_elf_section_offset (output_bfd, info, input_section,
+ rel->r_offset) != (bfd_vma) -1)
+ {
+ (*_bfd_error_handler)
+ (_("%B(%A+0x%lx): unresolvable relocation against symbol `%s'"),
+ input_bfd,
+ input_section, (long) rel->r_offset, h->root.root.string);
+ return FALSE;
+ }
+
+ if (r != bfd_reloc_ok)
+ {
+ 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 (r == bfd_reloc_overflow)
+ {
+ if (!(info->callbacks->reloc_overflow
+ (info, (h ? &h->root : NULL), name, howto->name,
+ (bfd_vma) 0, input_bfd, input_section, rel->r_offset)))
+ return FALSE;
+ }
+ else
+ {
+ (*_bfd_error_handler)
+ (_("%B(%A+0x%lx): reloc against `%s': error %d"),
+ input_bfd, input_section,
+ (long) rel->r_offset, name, (int) r);
+ return FALSE;
+ }
+ }
+ }
+
+ return TRUE;
+}
+
+static asection *
+bfin_gc_mark_hook (asection * sec,
+ 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_BFIN_GNU_VTINHERIT:
+ case R_BFIN_GNU_VTENTRY:
+ return NULL;
+ }
+
+ return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
+}
+
+/* Update the got entry reference counts for the section being removed. */
+
+static bfd_boolean
+bfin_gc_sweep_hook (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;
+ bfd *dynobj;
+ asection *sgot;
+ asection *srelgot;
+
+ dynobj = elf_hash_table (info)->dynobj;
+ if (dynobj == NULL)
+ return TRUE;
+
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+ sym_hashes = elf_sym_hashes (abfd);
+ local_got_refcounts = elf_local_got_refcounts (abfd);
+
+ sgot = bfd_get_linker_section (dynobj, ".got");
+ srelgot = bfd_get_linker_section (dynobj, ".rela.got");
+
+ relend = relocs + sec->reloc_count;
+ for (rel = relocs; rel < relend; rel++)
+ {
+ unsigned long r_symndx;
+ struct elf_link_hash_entry *h;
+
+ switch (ELF32_R_TYPE (rel->r_info))
+ {
+ case R_BFIN_GOT:
+ 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->size -= 4;
+ srelgot->size -= sizeof (Elf32_External_Rela);
+ }
+ }
+ }
+ else if (local_got_refcounts != NULL)
+ {
+ 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->size -= 4;
+ if (info->shared)
+ srelgot->size -= sizeof (Elf32_External_Rela);
+ }
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ return TRUE;
+}
+
+extern const bfd_target bfin_elf32_fdpic_vec;
+#define IS_FDPIC(bfd) ((bfd)->xvec == &bfin_elf32_fdpic_vec)
+
+/* An extension of the elf hash table data structure,
+ containing some additional Blackfin-specific data. */
+struct bfinfdpic_elf_link_hash_table
+{
+ struct elf_link_hash_table elf;
+
+ /* A pointer to the .got section. */
+ asection *sgot;
+ /* A pointer to the .rel.got section. */
+ asection *sgotrel;
+ /* A pointer to the .rofixup section. */
+ asection *sgotfixup;
+ /* A pointer to the .plt section. */
+ asection *splt;
+ /* A pointer to the .rel.plt section. */
+ asection *spltrel;
+ /* GOT base offset. */
+ bfd_vma got0;
+ /* Location of the first non-lazy PLT entry, i.e., the number of
+ bytes taken by lazy PLT entries. */
+ bfd_vma plt0;
+ /* A hash table holding information about which symbols were
+ referenced with which PIC-related relocations. */
+ struct htab *relocs_info;
+ /* Summary reloc information collected by
+ _bfinfdpic_count_got_plt_entries. */
+ struct _bfinfdpic_dynamic_got_info *g;
+};
+
+/* Get the Blackfin ELF linker hash table from a link_info structure. */
+
+#define bfinfdpic_hash_table(info) \
+ (elf_hash_table_id ((struct elf_link_hash_table *) ((info)->hash)) \
+ == BFIN_ELF_DATA ? ((struct bfinfdpic_elf_link_hash_table *) ((info)->hash)) : NULL)
+
+#define bfinfdpic_got_section(info) \
+ (bfinfdpic_hash_table (info)->sgot)
+#define bfinfdpic_gotrel_section(info) \
+ (bfinfdpic_hash_table (info)->sgotrel)
+#define bfinfdpic_gotfixup_section(info) \
+ (bfinfdpic_hash_table (info)->sgotfixup)
+#define bfinfdpic_plt_section(info) \
+ (bfinfdpic_hash_table (info)->splt)
+#define bfinfdpic_pltrel_section(info) \
+ (bfinfdpic_hash_table (info)->spltrel)
+#define bfinfdpic_relocs_info(info) \
+ (bfinfdpic_hash_table (info)->relocs_info)
+#define bfinfdpic_got_initial_offset(info) \
+ (bfinfdpic_hash_table (info)->got0)
+#define bfinfdpic_plt_initial_offset(info) \
+ (bfinfdpic_hash_table (info)->plt0)
+#define bfinfdpic_dynamic_got_plt_info(info) \
+ (bfinfdpic_hash_table (info)->g)
+
+/* The name of the dynamic interpreter. This is put in the .interp
+ section. */
+
+#define ELF_DYNAMIC_INTERPRETER "/lib/ld.so.1"
+
+#define DEFAULT_STACK_SIZE 0x20000
+
+/* This structure is used to collect the number of entries present in
+ each addressable range of the got. */
+struct _bfinfdpic_dynamic_got_info
+{
+ /* Several bits of information about the current link. */
+ struct bfd_link_info *info;
+ /* Total size needed for GOT entries within the 18- or 32-bit
+ ranges. */
+ bfd_vma got17m4, gothilo;
+ /* Total size needed for function descriptor entries within the 18-
+ or 32-bit ranges. */
+ bfd_vma fd17m4, fdhilo;
+ /* Total size needed function descriptor entries referenced in PLT
+ entries, that would be profitable to place in offsets close to
+ the PIC register. */
+ bfd_vma fdplt;
+ /* Total size needed by lazy PLT entries. */
+ bfd_vma lzplt;
+ /* Number of relocations carried over from input object files. */
+ unsigned long relocs;
+ /* Number of fixups introduced by relocations in input object files. */
+ unsigned long fixups;
+};
+
+/* Create a Blackfin ELF linker hash table. */
+
+static struct bfd_link_hash_table *
+bfinfdpic_elf_link_hash_table_create (bfd *abfd)
+{
+ struct bfinfdpic_elf_link_hash_table *ret;
+ bfd_size_type amt = sizeof (struct bfinfdpic_elf_link_hash_table);
+
+ ret = bfd_zmalloc (amt);
+ if (ret == NULL)
+ return NULL;
+
+ if (!_bfd_elf_link_hash_table_init (&ret->elf, abfd,
+ _bfd_elf_link_hash_newfunc,
+ sizeof (struct elf_link_hash_entry),
+ BFIN_ELF_DATA))
+ {
+ free (ret);
+ return NULL;
+ }
+
+ return &ret->elf.root;
+}
+
+/* Decide whether a reference to a symbol can be resolved locally or
+ not. If the symbol is protected, we want the local address, but
+ its function descriptor must be assigned by the dynamic linker. */
+#define BFINFDPIC_SYM_LOCAL(INFO, H) \
+ (_bfd_elf_symbol_refs_local_p ((H), (INFO), 1) \
+ || ! elf_hash_table (INFO)->dynamic_sections_created)
+#define BFINFDPIC_FUNCDESC_LOCAL(INFO, H) \
+ ((H)->dynindx == -1 || ! elf_hash_table (INFO)->dynamic_sections_created)
+
+/* This structure collects information on what kind of GOT, PLT or
+ function descriptors are required by relocations that reference a
+ certain symbol. */
+struct bfinfdpic_relocs_info
+{
+ /* The index of the symbol, as stored in the relocation r_info, if
+ we have a local symbol; -1 otherwise. */
+ long symndx;
+ union
+ {
+ /* The input bfd in which the symbol is defined, if it's a local
+ symbol. */
+ bfd *abfd;
+ /* If symndx == -1, the hash table entry corresponding to a global
+ symbol (even if it turns out to bind locally, in which case it
+ should ideally be replaced with section's symndx + addend). */
+ struct elf_link_hash_entry *h;
+ } d;
+ /* The addend of the relocation that references the symbol. */
+ bfd_vma addend;
+
+ /* The fields above are used to identify an entry. The fields below
+ contain information on how an entry is used and, later on, which
+ locations it was assigned. */
+ /* The following 2 fields record whether the symbol+addend above was
+ ever referenced with a GOT relocation. The 17M4 suffix indicates a
+ GOT17M4 relocation; hilo is used for GOTLO/GOTHI pairs. */
+ unsigned got17m4;
+ unsigned gothilo;
+ /* Whether a FUNCDESC relocation references symbol+addend. */
+ unsigned fd;
+ /* Whether a FUNCDESC_GOT relocation references symbol+addend. */
+ unsigned fdgot17m4;
+ unsigned fdgothilo;
+ /* Whether a FUNCDESC_GOTOFF relocation references symbol+addend. */
+ unsigned fdgoff17m4;
+ unsigned fdgoffhilo;
+ /* Whether symbol+addend is referenced with GOTOFF17M4, GOTOFFLO or
+ GOTOFFHI relocations. The addend doesn't really matter, since we
+ envision that this will only be used to check whether the symbol
+ is mapped to the same segment as the got. */
+ unsigned gotoff;
+ /* Whether symbol+addend is referenced by a LABEL24 relocation. */
+ unsigned call;
+ /* Whether symbol+addend is referenced by a 32 or FUNCDESC_VALUE
+ relocation. */
+ unsigned sym;
+ /* Whether we need a PLT entry for a symbol. Should be implied by
+ something like:
+ (call && symndx == -1 && ! BFINFDPIC_SYM_LOCAL (info, d.h)) */
+ unsigned plt:1;
+ /* Whether a function descriptor should be created in this link unit
+ for symbol+addend. Should be implied by something like:
+ (plt || fdgotoff17m4 || fdgotofflohi
+ || ((fd || fdgot17m4 || fdgothilo)
+ && (symndx != -1 || BFINFDPIC_FUNCDESC_LOCAL (info, d.h)))) */
+ unsigned privfd:1;
+ /* Whether a lazy PLT entry is needed for this symbol+addend.
+ Should be implied by something like:
+ (privfd && symndx == -1 && ! BFINFDPIC_SYM_LOCAL (info, d.h)
+ && ! (info->flags & DF_BIND_NOW)) */
+ unsigned lazyplt:1;
+ /* Whether we've already emitted GOT relocations and PLT entries as
+ needed for this symbol. */
+ unsigned done:1;
+
+ /* The number of R_BFIN_BYTE4_DATA, R_BFIN_FUNCDESC and R_BFIN_FUNCDESC_VALUE
+ relocations referencing the symbol. */
+ unsigned relocs32, relocsfd, relocsfdv;
+
+ /* The number of .rofixups entries and dynamic relocations allocated
+ for this symbol, minus any that might have already been used. */
+ unsigned fixups, dynrelocs;
+
+ /* The offsets of the GOT entries assigned to symbol+addend, to the
+ function descriptor's address, and to a function descriptor,
+ respectively. Should be zero if unassigned. The offsets are
+ counted from the value that will be assigned to the PIC register,
+ not from the beginning of the .got section. */
+ bfd_signed_vma got_entry, fdgot_entry, fd_entry;
+ /* The offsets of the PLT entries assigned to symbol+addend,
+ non-lazy and lazy, respectively. If unassigned, should be
+ (bfd_vma)-1. */
+ bfd_vma plt_entry, lzplt_entry;
+};
+
+/* Compute a hash with the key fields of an bfinfdpic_relocs_info entry. */
+static hashval_t
+bfinfdpic_relocs_info_hash (const void *entry_)
+{
+ const struct bfinfdpic_relocs_info *entry = entry_;
+
+ return (entry->symndx == -1
+ ? (long) entry->d.h->root.root.hash
+ : entry->symndx + (long) entry->d.abfd->id * 257) + entry->addend;
+}
+
+/* Test whether the key fields of two bfinfdpic_relocs_info entries are
+ identical. */
+static int
+bfinfdpic_relocs_info_eq (const void *entry1, const void *entry2)
+{
+ const struct bfinfdpic_relocs_info *e1 = entry1;
+ const struct bfinfdpic_relocs_info *e2 = entry2;
+
+ return e1->symndx == e2->symndx && e1->addend == e2->addend
+ && (e1->symndx == -1 ? e1->d.h == e2->d.h : e1->d.abfd == e2->d.abfd);
+}
+
+/* Find or create an entry in a hash table HT that matches the key
+ fields of the given ENTRY. If it's not found, memory for a new
+ entry is allocated in ABFD's obstack. */
+static struct bfinfdpic_relocs_info *
+bfinfdpic_relocs_info_find (struct htab *ht,
+ bfd *abfd,
+ const struct bfinfdpic_relocs_info *entry,
+ enum insert_option insert)
+{
+ struct bfinfdpic_relocs_info **loc;
+
+ if (!ht)
+ return NULL;
+
+ loc = (struct bfinfdpic_relocs_info **) htab_find_slot (ht, entry, insert);
+
+ if (! loc)
+ return NULL;
+
+ if (*loc)
+ return *loc;
+
+ *loc = bfd_zalloc (abfd, sizeof (**loc));
+
+ if (! *loc)
+ return *loc;
+
+ (*loc)->symndx = entry->symndx;
+ (*loc)->d = entry->d;
+ (*loc)->addend = entry->addend;
+ (*loc)->plt_entry = (bfd_vma)-1;
+ (*loc)->lzplt_entry = (bfd_vma)-1;
+
+ return *loc;
+}
+
+/* Obtain the address of the entry in HT associated with H's symbol +
+ addend, creating a new entry if none existed. ABFD is only used
+ for memory allocation purposes. */
+inline static struct bfinfdpic_relocs_info *
+bfinfdpic_relocs_info_for_global (struct htab *ht,
+ bfd *abfd,
+ struct elf_link_hash_entry *h,
+ bfd_vma addend,
+ enum insert_option insert)
+{
+ struct bfinfdpic_relocs_info entry;
+
+ entry.symndx = -1;
+ entry.d.h = h;
+ entry.addend = addend;
+
+ return bfinfdpic_relocs_info_find (ht, abfd, &entry, insert);
+}
+
+/* Obtain the address of the entry in HT associated with the SYMNDXth
+ local symbol of the input bfd ABFD, plus the addend, creating a new
+ entry if none existed. */
+inline static struct bfinfdpic_relocs_info *
+bfinfdpic_relocs_info_for_local (struct htab *ht,
+ bfd *abfd,
+ long symndx,
+ bfd_vma addend,
+ enum insert_option insert)
+{
+ struct bfinfdpic_relocs_info entry;
+
+ entry.symndx = symndx;
+ entry.d.abfd = abfd;
+ entry.addend = addend;
+
+ return bfinfdpic_relocs_info_find (ht, abfd, &entry, insert);
+}
+
+/* Merge fields set by check_relocs() of two entries that end up being
+ mapped to the same (presumably global) symbol. */
+
+inline static void
+bfinfdpic_pic_merge_early_relocs_info (struct bfinfdpic_relocs_info *e2,
+ struct bfinfdpic_relocs_info const *e1)
+{
+ e2->got17m4 |= e1->got17m4;
+ e2->gothilo |= e1->gothilo;
+ e2->fd |= e1->fd;
+ e2->fdgot17m4 |= e1->fdgot17m4;
+ e2->fdgothilo |= e1->fdgothilo;
+ e2->fdgoff17m4 |= e1->fdgoff17m4;
+ e2->fdgoffhilo |= e1->fdgoffhilo;
+ e2->gotoff |= e1->gotoff;
+ e2->call |= e1->call;
+ e2->sym |= e1->sym;
+}
+
+/* Every block of 65535 lazy PLT entries shares a single call to the
+ resolver, inserted in the 32768th lazy PLT entry (i.e., entry #
+ 32767, counting from 0). All other lazy PLT entries branch to it
+ in a single instruction. */
+
+#define LZPLT_RESOLVER_EXTRA 10
+#define LZPLT_NORMAL_SIZE 6
+#define LZPLT_ENTRIES 1362
+
+#define BFINFDPIC_LZPLT_BLOCK_SIZE ((bfd_vma) LZPLT_NORMAL_SIZE * LZPLT_ENTRIES + LZPLT_RESOLVER_EXTRA)
+#define BFINFDPIC_LZPLT_RESOLV_LOC (LZPLT_NORMAL_SIZE * LZPLT_ENTRIES / 2)
+
+/* Add a dynamic relocation to the SRELOC section. */
+
+inline static bfd_vma
+_bfinfdpic_add_dyn_reloc (bfd *output_bfd, asection *sreloc, bfd_vma offset,
+ int reloc_type, long dynindx, bfd_vma addend,
+ struct bfinfdpic_relocs_info *entry)
+{
+ Elf_Internal_Rela outrel;
+ bfd_vma reloc_offset;
+
+ outrel.r_offset = offset;
+ outrel.r_info = ELF32_R_INFO (dynindx, reloc_type);
+ outrel.r_addend = addend;
+
+ reloc_offset = sreloc->reloc_count * sizeof (Elf32_External_Rel);
+ BFD_ASSERT (reloc_offset < sreloc->size);
+ bfd_elf32_swap_reloc_out (output_bfd, &outrel,
+ sreloc->contents + reloc_offset);
+ sreloc->reloc_count++;
+
+ /* If the entry's index is zero, this relocation was probably to a
+ linkonce section that got discarded. We reserved a dynamic
+ relocation, but it was for another entry than the one we got at
+ the time of emitting the relocation. Unfortunately there's no
+ simple way for us to catch this situation, since the relocation
+ is cleared right before calling relocate_section, at which point
+ we no longer know what the relocation used to point to. */
+ if (entry->symndx)
+ {
+ BFD_ASSERT (entry->dynrelocs > 0);
+ entry->dynrelocs--;
+ }
+
+ return reloc_offset;
+}
+
+/* Add a fixup to the ROFIXUP section. */
+
+static bfd_vma
+_bfinfdpic_add_rofixup (bfd *output_bfd, asection *rofixup, bfd_vma offset,
+ struct bfinfdpic_relocs_info *entry)
+{
+ bfd_vma fixup_offset;
+
+ if (rofixup->flags & SEC_EXCLUDE)
+ return -1;
+
+ fixup_offset = rofixup->reloc_count * 4;
+ if (rofixup->contents)
+ {
+ BFD_ASSERT (fixup_offset < rofixup->size);
+ bfd_put_32 (output_bfd, offset, rofixup->contents + fixup_offset);
+ }
+ rofixup->reloc_count++;
+
+ if (entry && entry->symndx)
+ {
+ /* See discussion about symndx == 0 in _bfinfdpic_add_dyn_reloc
+ above. */
+ BFD_ASSERT (entry->fixups > 0);
+ entry->fixups--;
+ }
+
+ return fixup_offset;
+}
+
+/* Find the segment number in which OSEC, and output section, is
+ located. */
+
+static unsigned
+_bfinfdpic_osec_to_segment (bfd *output_bfd, asection *osec)
+{
+ Elf_Internal_Phdr *p = _bfd_elf_find_segment_containing_section (output_bfd, osec);
+
+ return (p != NULL) ? p - elf_tdata (output_bfd)->phdr : -1;
+}
+
+inline static bfd_boolean
+_bfinfdpic_osec_readonly_p (bfd *output_bfd, asection *osec)
+{
+ unsigned seg = _bfinfdpic_osec_to_segment (output_bfd, osec);
+
+ return ! (elf_tdata (output_bfd)->phdr[seg].p_flags & PF_W);
+}
+
+/* Generate relocations for GOT entries, function descriptors, and
+ code for PLT and lazy PLT entries. */
+
+inline static bfd_boolean
+_bfinfdpic_emit_got_relocs_plt_entries (struct bfinfdpic_relocs_info *entry,
+ bfd *output_bfd,
+ struct bfd_link_info *info,
+ asection *sec,
+ Elf_Internal_Sym *sym,
+ bfd_vma addend)
+{
+ bfd_vma fd_lazy_rel_offset = (bfd_vma) -1;
+ int dynindx = -1;
+
+ if (entry->done)
+ return TRUE;
+ entry->done = 1;
+
+ if (entry->got_entry || entry->fdgot_entry || entry->fd_entry)
+ {
+ /* If the symbol is dynamic, consider it for dynamic
+ relocations, otherwise decay to section + offset. */
+ if (entry->symndx == -1 && entry->d.h->dynindx != -1)
+ dynindx = entry->d.h->dynindx;
+ else
+ {
+ if (sec
+ && sec->output_section
+ && ! bfd_is_abs_section (sec->output_section)
+ && ! bfd_is_und_section (sec->output_section))
+ dynindx = elf_section_data (sec->output_section)->dynindx;
+ else
+ dynindx = 0;
+ }
+ }
+
+ /* Generate relocation for GOT entry pointing to the symbol. */
+ if (entry->got_entry)
+ {
+ int idx = dynindx;
+ bfd_vma ad = addend;
+
+ /* If the symbol is dynamic but binds locally, use
+ section+offset. */
+ if (sec && (entry->symndx != -1
+ || BFINFDPIC_SYM_LOCAL (info, entry->d.h)))
+ {
+ if (entry->symndx == -1)
+ ad += entry->d.h->root.u.def.value;
+ else
+ ad += sym->st_value;
+ ad += sec->output_offset;
+ if (sec->output_section && elf_section_data (sec->output_section))
+ idx = elf_section_data (sec->output_section)->dynindx;
+ else
+ idx = 0;
+ }
+
+ /* If we're linking an executable at a fixed address, we can
+ omit the dynamic relocation as long as the symbol is local to
+ this module. */
+ if (info->executable && !info->pie
+ && (entry->symndx != -1
+ || BFINFDPIC_SYM_LOCAL (info, entry->d.h)))
+ {
+ if (sec)
+ ad += sec->output_section->vma;
+ if (entry->symndx != -1
+ || entry->d.h->root.type != bfd_link_hash_undefweak)
+ _bfinfdpic_add_rofixup (output_bfd,
+ bfinfdpic_gotfixup_section (info),
+ bfinfdpic_got_section (info)->output_section
+ ->vma
+ + bfinfdpic_got_section (info)->output_offset
+ + bfinfdpic_got_initial_offset (info)
+ + entry->got_entry, entry);
+ }
+ else
+ _bfinfdpic_add_dyn_reloc (output_bfd, bfinfdpic_gotrel_section (info),
+ _bfd_elf_section_offset
+ (output_bfd, info,
+ bfinfdpic_got_section (info),
+ bfinfdpic_got_initial_offset (info)
+ + entry->got_entry)
+ + bfinfdpic_got_section (info)
+ ->output_section->vma
+ + bfinfdpic_got_section (info)->output_offset,
+ R_BFIN_BYTE4_DATA, idx, ad, entry);
+
+ bfd_put_32 (output_bfd, ad,
+ bfinfdpic_got_section (info)->contents
+ + bfinfdpic_got_initial_offset (info)
+ + entry->got_entry);
+ }
+
+ /* Generate relocation for GOT entry pointing to a canonical
+ function descriptor. */
+ if (entry->fdgot_entry)
+ {
+ int reloc, idx;
+ bfd_vma ad = 0;
+
+ if (! (entry->symndx == -1
+ && entry->d.h->root.type == bfd_link_hash_undefweak
+ && BFINFDPIC_SYM_LOCAL (info, entry->d.h)))
+ {
+ /* If the symbol is dynamic and there may be dynamic symbol
+ resolution because we are, or are linked with, a shared
+ library, emit a FUNCDESC relocation such that the dynamic
+ linker will allocate the function descriptor. If the
+ symbol needs a non-local function descriptor but binds
+ locally (e.g., its visibility is protected, emit a
+ dynamic relocation decayed to section+offset. */
+ if (entry->symndx == -1
+ && ! BFINFDPIC_FUNCDESC_LOCAL (info, entry->d.h)
+ && BFINFDPIC_SYM_LOCAL (info, entry->d.h)
+ && !(info->executable && !info->pie))
+ {
+ reloc = R_BFIN_FUNCDESC;
+ idx = elf_section_data (entry->d.h->root.u.def.section
+ ->output_section)->dynindx;
+ ad = entry->d.h->root.u.def.section->output_offset
+ + entry->d.h->root.u.def.value;
+ }
+ else if (entry->symndx == -1
+ && ! BFINFDPIC_FUNCDESC_LOCAL (info, entry->d.h))
+ {
+ reloc = R_BFIN_FUNCDESC;
+ idx = dynindx;
+ ad = addend;
+ if (ad)
+ return FALSE;
+ }
+ else
+ {
+ /* Otherwise, we know we have a private function descriptor,
+ so reference it directly. */
+ if (elf_hash_table (info)->dynamic_sections_created)
+ BFD_ASSERT (entry->privfd);
+ reloc = R_BFIN_BYTE4_DATA;
+ idx = elf_section_data (bfinfdpic_got_section (info)
+ ->output_section)->dynindx;
+ ad = bfinfdpic_got_section (info)->output_offset
+ + bfinfdpic_got_initial_offset (info) + entry->fd_entry;
+ }
+
+ /* If there is room for dynamic symbol resolution, emit the
+ dynamic relocation. However, if we're linking an
+ executable at a fixed location, we won't have emitted a
+ dynamic symbol entry for the got section, so idx will be
+ zero, which means we can and should compute the address
+ of the private descriptor ourselves. */
+ if (info->executable && !info->pie
+ && (entry->symndx != -1
+ || BFINFDPIC_FUNCDESC_LOCAL (info, entry->d.h)))
+ {
+ ad += bfinfdpic_got_section (info)->output_section->vma;
+ _bfinfdpic_add_rofixup (output_bfd,
+ bfinfdpic_gotfixup_section (info),
+ bfinfdpic_got_section (info)
+ ->output_section->vma
+ + bfinfdpic_got_section (info)
+ ->output_offset
+ + bfinfdpic_got_initial_offset (info)
+ + entry->fdgot_entry, entry);
+ }
+ else
+ _bfinfdpic_add_dyn_reloc (output_bfd,
+ bfinfdpic_gotrel_section (info),
+ _bfd_elf_section_offset
+ (output_bfd, info,
+ bfinfdpic_got_section (info),
+ bfinfdpic_got_initial_offset (info)
+ + entry->fdgot_entry)
+ + bfinfdpic_got_section (info)
+ ->output_section->vma
+ + bfinfdpic_got_section (info)
+ ->output_offset,
+ reloc, idx, ad, entry);
+ }
+
+ bfd_put_32 (output_bfd, ad,
+ bfinfdpic_got_section (info)->contents
+ + bfinfdpic_got_initial_offset (info)
+ + entry->fdgot_entry);
+ }
+
+ /* Generate relocation to fill in a private function descriptor in
+ the GOT. */
+ if (entry->fd_entry)
+ {
+ int idx = dynindx;
+ bfd_vma ad = addend;
+ bfd_vma ofst;
+ long lowword, highword;
+
+ /* If the symbol is dynamic but binds locally, use
+ section+offset. */
+ if (sec && (entry->symndx != -1
+ || BFINFDPIC_SYM_LOCAL (info, entry->d.h)))
+ {
+ if (entry->symndx == -1)
+ ad += entry->d.h->root.u.def.value;
+ else
+ ad += sym->st_value;
+ ad += sec->output_offset;
+ if (sec->output_section && elf_section_data (sec->output_section))
+ idx = elf_section_data (sec->output_section)->dynindx;
+ else
+ idx = 0;
+ }
+
+ /* If we're linking an executable at a fixed address, we can
+ omit the dynamic relocation as long as the symbol is local to
+ this module. */
+ if (info->executable && !info->pie
+ && (entry->symndx != -1 || BFINFDPIC_SYM_LOCAL (info, entry->d.h)))
+ {
+ if (sec)
+ ad += sec->output_section->vma;
+ ofst = 0;
+ if (entry->symndx != -1
+ || entry->d.h->root.type != bfd_link_hash_undefweak)
+ {
+ _bfinfdpic_add_rofixup (output_bfd,
+ bfinfdpic_gotfixup_section (info),
+ bfinfdpic_got_section (info)
+ ->output_section->vma
+ + bfinfdpic_got_section (info)
+ ->output_offset
+ + bfinfdpic_got_initial_offset (info)
+ + entry->fd_entry, entry);
+ _bfinfdpic_add_rofixup (output_bfd,
+ bfinfdpic_gotfixup_section (info),
+ bfinfdpic_got_section (info)
+ ->output_section->vma
+ + bfinfdpic_got_section (info)
+ ->output_offset
+ + bfinfdpic_got_initial_offset (info)
+ + entry->fd_entry + 4, entry);
+ }
+ }
+ else
+ {
+ ofst
+ = _bfinfdpic_add_dyn_reloc (output_bfd,
+ entry->lazyplt
+ ? bfinfdpic_pltrel_section (info)
+ : bfinfdpic_gotrel_section (info),
+ _bfd_elf_section_offset
+ (output_bfd, info,
+ bfinfdpic_got_section (info),
+ bfinfdpic_got_initial_offset (info)
+ + entry->fd_entry)
+ + bfinfdpic_got_section (info)
+ ->output_section->vma
+ + bfinfdpic_got_section (info)
+ ->output_offset,
+ R_BFIN_FUNCDESC_VALUE, idx, ad, entry);
+ }
+
+ /* If we've omitted the dynamic relocation, just emit the fixed
+ addresses of the symbol and of the local GOT base offset. */
+ if (info->executable && !info->pie && sec && sec->output_section)
+ {
+ lowword = ad;
+ highword = bfinfdpic_got_section (info)->output_section->vma
+ + bfinfdpic_got_section (info)->output_offset
+ + bfinfdpic_got_initial_offset (info);
+ }
+ else if (entry->lazyplt)
+ {
+ if (ad)
+ return FALSE;
+
+ fd_lazy_rel_offset = ofst;
+
+ /* A function descriptor used for lazy or local resolving is
+ initialized such that its high word contains the output
+ section index in which the PLT entries are located, and
+ the low word contains the address of the lazy PLT entry
+ entry point, that must be within the memory region
+ assigned to that section. */
+ lowword = entry->lzplt_entry + 4
+ + bfinfdpic_plt_section (info)->output_offset
+ + bfinfdpic_plt_section (info)->output_section->vma;
+ highword = _bfinfdpic_osec_to_segment
+ (output_bfd, bfinfdpic_plt_section (info)->output_section);
+ }
+ else
+ {
+ /* A function descriptor for a local function gets the index
+ of the section. For a non-local function, it's
+ disregarded. */
+ lowword = ad;
+ if (sec == NULL
+ || (entry->symndx == -1 && entry->d.h->dynindx != -1
+ && entry->d.h->dynindx == idx))
+ highword = 0;
+ else
+ highword = _bfinfdpic_osec_to_segment
+ (output_bfd, sec->output_section);
+ }
+
+ bfd_put_32 (output_bfd, lowword,
+ bfinfdpic_got_section (info)->contents
+ + bfinfdpic_got_initial_offset (info)
+ + entry->fd_entry);
+ bfd_put_32 (output_bfd, highword,
+ bfinfdpic_got_section (info)->contents
+ + bfinfdpic_got_initial_offset (info)
+ + entry->fd_entry + 4);
+ }
+
+ /* Generate code for the PLT entry. */
+ if (entry->plt_entry != (bfd_vma) -1)
+ {
+ bfd_byte *plt_code = bfinfdpic_plt_section (info)->contents
+ + entry->plt_entry;
+
+ BFD_ASSERT (entry->fd_entry);
+
+ /* Figure out what kind of PLT entry we need, depending on the
+ location of the function descriptor within the GOT. */
+ if (entry->fd_entry >= -(1 << (18 - 1))
+ && entry->fd_entry + 4 < (1 << (18 - 1)))
+ {
+ /* P1 = [P3 + fd_entry]; P3 = [P3 + fd_entry + 4] */
+ bfd_put_32 (output_bfd,
+ 0xe519 | ((entry->fd_entry << 14) & 0xFFFF0000),
+ plt_code);
+ bfd_put_32 (output_bfd,
+ 0xe51b | (((entry->fd_entry + 4) << 14) & 0xFFFF0000),
+ plt_code + 4);
+ plt_code += 8;
+ }
+ else
+ {
+ /* P1.L = fd_entry; P1.H = fd_entry;
+ P3 = P3 + P1;
+ P1 = [P3];
+ P3 = [P3 + 4]; */
+ bfd_put_32 (output_bfd,
+ 0xe109 | (entry->fd_entry << 16),
+ plt_code);
+ bfd_put_32 (output_bfd,
+ 0xe149 | (entry->fd_entry & 0xFFFF0000),
+ plt_code + 4);
+ bfd_put_16 (output_bfd, 0x5ad9, plt_code + 8);
+ bfd_put_16 (output_bfd, 0x9159, plt_code + 10);
+ bfd_put_16 (output_bfd, 0xac5b, plt_code + 12);
+ plt_code += 14;
+ }
+ /* JUMP (P1) */
+ bfd_put_16 (output_bfd, 0x0051, plt_code);
+ }
+
+ /* Generate code for the lazy PLT entry. */
+ if (entry->lzplt_entry != (bfd_vma) -1)
+ {
+ bfd_byte *lzplt_code = bfinfdpic_plt_section (info)->contents
+ + entry->lzplt_entry;
+ bfd_vma resolverStub_addr;
+
+ bfd_put_32 (output_bfd, fd_lazy_rel_offset, lzplt_code);
+ lzplt_code += 4;
+
+ resolverStub_addr = entry->lzplt_entry / BFINFDPIC_LZPLT_BLOCK_SIZE
+ * BFINFDPIC_LZPLT_BLOCK_SIZE + BFINFDPIC_LZPLT_RESOLV_LOC;
+ if (resolverStub_addr >= bfinfdpic_plt_initial_offset (info))
+ resolverStub_addr = bfinfdpic_plt_initial_offset (info) - LZPLT_NORMAL_SIZE - LZPLT_RESOLVER_EXTRA;
+
+ if (entry->lzplt_entry == resolverStub_addr)
+ {
+ /* This is a lazy PLT entry that includes a resolver call.
+ P2 = [P3];
+ R3 = [P3 + 4];
+ JUMP (P2); */
+ bfd_put_32 (output_bfd,
+ 0xa05b915a,
+ lzplt_code);
+ bfd_put_16 (output_bfd, 0x0052, lzplt_code + 4);
+ }
+ else
+ {
+ /* JUMP.S resolverStub */
+ bfd_put_16 (output_bfd,
+ 0x2000
+ | (((resolverStub_addr - entry->lzplt_entry)
+ / 2) & (((bfd_vma)1 << 12) - 1)),
+ lzplt_code);
+ }
+ }
+
+ return TRUE;
+}
+
+/* Relocate an Blackfin ELF section.
+
+ 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 relocatable
+ 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 relocatable 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 bfd_boolean
+bfinfdpic_relocate_section (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;
+ unsigned isec_segment, got_segment, plt_segment,
+ check_segment[2];
+ int silence_segment_error = !(info->shared || info->pie);
+
+ symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
+ sym_hashes = elf_sym_hashes (input_bfd);
+ relend = relocs + input_section->reloc_count;
+
+ isec_segment = _bfinfdpic_osec_to_segment (output_bfd,
+ input_section->output_section);
+ if (IS_FDPIC (output_bfd) && bfinfdpic_got_section (info))
+ got_segment = _bfinfdpic_osec_to_segment (output_bfd,
+ bfinfdpic_got_section (info)
+ ->output_section);
+ else
+ got_segment = -1;
+ if (IS_FDPIC (output_bfd) && elf_hash_table (info)->dynamic_sections_created)
+ plt_segment = _bfinfdpic_osec_to_segment (output_bfd,
+ bfinfdpic_plt_section (info)
+ ->output_section);
+ else
+ plt_segment = -1;
+
+ 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;
+ asection *osec;
+ struct bfinfdpic_relocs_info *picrel;
+ bfd_vma orig_addend = rel->r_addend;
+
+ r_type = ELF32_R_TYPE (rel->r_info);
+
+ if (r_type == R_BFIN_GNU_VTINHERIT
+ || r_type == R_BFIN_GNU_VTENTRY)
+ continue;
+
+ r_symndx = ELF32_R_SYM (rel->r_info);
+ howto = bfin_reloc_type_lookup (input_bfd, r_type);
+ if (howto == NULL)
+ {
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+
+ h = NULL;
+ sym = NULL;
+ sec = NULL;
+
+ if (r_symndx < symtab_hdr->sh_info)
+ {
+ sym = local_syms + r_symndx;
+ osec = sec = local_sections [r_symndx];
+ relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
+
+ 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;
+ }
+ else
+ {
+ bfd_boolean warned, ignored;
+ bfd_boolean unresolved_reloc;
+
+ RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
+ r_symndx, symtab_hdr, sym_hashes,
+ h, sec, relocation,
+ unresolved_reloc, warned, ignored);
+ osec = sec;
+ }
+
+ if (sec != NULL && discarded_section (sec))
+ RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+ rel, 1, relend, howto, 0, contents);
+
+ if (info->relocatable)
+ continue;
+
+ if (h != NULL
+ && (h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak)
+ && !BFINFDPIC_SYM_LOCAL (info, h))
+ {
+ osec = sec = NULL;
+ relocation = 0;
+ }
+
+ switch (r_type)
+ {
+ case R_BFIN_PCREL24:
+ case R_BFIN_PCREL24_JUMP_L:
+ case R_BFIN_BYTE4_DATA:
+ if (! IS_FDPIC (output_bfd))
+ goto non_fdpic;
+
+ case R_BFIN_GOT17M4:
+ case R_BFIN_GOTHI:
+ case R_BFIN_GOTLO:
+ case R_BFIN_FUNCDESC_GOT17M4:
+ case R_BFIN_FUNCDESC_GOTHI:
+ case R_BFIN_FUNCDESC_GOTLO:
+ case R_BFIN_GOTOFF17M4:
+ case R_BFIN_GOTOFFHI:
+ case R_BFIN_GOTOFFLO:
+ case R_BFIN_FUNCDESC_GOTOFF17M4:
+ case R_BFIN_FUNCDESC_GOTOFFHI:
+ case R_BFIN_FUNCDESC_GOTOFFLO:
+ case R_BFIN_FUNCDESC:
+ case R_BFIN_FUNCDESC_VALUE:
+ if (h != NULL)
+ picrel = bfinfdpic_relocs_info_for_global (bfinfdpic_relocs_info
+ (info), input_bfd, h,
+ orig_addend, INSERT);
+ else
+ /* In order to find the entry we created before, we must
+ use the original addend, not the one that may have been
+ modified by _bfd_elf_rela_local_sym(). */
+ picrel = bfinfdpic_relocs_info_for_local (bfinfdpic_relocs_info
+ (info), input_bfd, r_symndx,
+ orig_addend, INSERT);
+ if (! picrel)
+ return FALSE;
+
+ if (!_bfinfdpic_emit_got_relocs_plt_entries (picrel, output_bfd, info,
+ osec, sym,
+ rel->r_addend))
+ {
+ (*_bfd_error_handler)
+ (_("%B: relocation at `%A+0x%x' references symbol `%s' with nonzero addend"),
+ input_bfd, input_section, rel->r_offset, name);
+ return FALSE;
+
+ }
+
+ break;
+
+ default:
+ non_fdpic:
+ picrel = NULL;
+ if (h && ! BFINFDPIC_SYM_LOCAL (info, h)
+ && _bfd_elf_section_offset (output_bfd, info, input_section,
+ rel->r_offset) != (bfd_vma) -1)
+ {
+ info->callbacks->warning
+ (info, _("relocation references symbol not defined in the module"),
+ name, input_bfd, input_section, rel->r_offset);
+ return FALSE;
+ }
+ break;
+ }
+
+ switch (r_type)
+ {
+ case R_BFIN_PCREL24:
+ case R_BFIN_PCREL24_JUMP_L:
+ check_segment[0] = isec_segment;
+ if (! IS_FDPIC (output_bfd))
+ check_segment[1] = isec_segment;
+ else if (picrel->plt)
+ {
+ relocation = bfinfdpic_plt_section (info)->output_section->vma
+ + bfinfdpic_plt_section (info)->output_offset
+ + picrel->plt_entry;
+ check_segment[1] = plt_segment;
+ }
+ /* We don't want to warn on calls to undefined weak symbols,
+ as calls to them must be protected by non-NULL tests
+ anyway, and unprotected calls would invoke undefined
+ behavior. */
+ else if (picrel->symndx == -1
+ && picrel->d.h->root.type == bfd_link_hash_undefweak)
+ check_segment[1] = check_segment[0];
+ else
+ check_segment[1] = sec
+ ? _bfinfdpic_osec_to_segment (output_bfd, sec->output_section)
+ : (unsigned)-1;
+ break;
+
+ case R_BFIN_GOT17M4:
+ case R_BFIN_GOTHI:
+ case R_BFIN_GOTLO:
+ relocation = picrel->got_entry;
+ check_segment[0] = check_segment[1] = got_segment;
+ break;
+
+ case R_BFIN_FUNCDESC_GOT17M4:
+ case R_BFIN_FUNCDESC_GOTHI:
+ case R_BFIN_FUNCDESC_GOTLO:
+ relocation = picrel->fdgot_entry;
+ check_segment[0] = check_segment[1] = got_segment;
+ break;
+
+ case R_BFIN_GOTOFFHI:
+ case R_BFIN_GOTOFF17M4:
+ case R_BFIN_GOTOFFLO:
+ relocation -= bfinfdpic_got_section (info)->output_section->vma
+ + bfinfdpic_got_section (info)->output_offset
+ + bfinfdpic_got_initial_offset (info);
+ check_segment[0] = got_segment;
+ check_segment[1] = sec
+ ? _bfinfdpic_osec_to_segment (output_bfd, sec->output_section)
+ : (unsigned)-1;
+ break;
+
+ case R_BFIN_FUNCDESC_GOTOFF17M4:
+ case R_BFIN_FUNCDESC_GOTOFFHI:
+ case R_BFIN_FUNCDESC_GOTOFFLO:
+ relocation = picrel->fd_entry;
+ check_segment[0] = check_segment[1] = got_segment;
+ break;
+
+ case R_BFIN_FUNCDESC:
+ {
+ int dynindx;
+ bfd_vma addend = rel->r_addend;
+
+ if (! (h && h->root.type == bfd_link_hash_undefweak
+ && BFINFDPIC_SYM_LOCAL (info, h)))
+ {
+ /* If the symbol is dynamic and there may be dynamic
+ symbol resolution because we are or are linked with a
+ shared library, emit a FUNCDESC relocation such that
+ the dynamic linker will allocate the function
+ descriptor. If the symbol needs a non-local function
+ descriptor but binds locally (e.g., its visibility is
+ protected, emit a dynamic relocation decayed to
+ section+offset. */
+ if (h && ! BFINFDPIC_FUNCDESC_LOCAL (info, h)
+ && BFINFDPIC_SYM_LOCAL (info, h)
+ && !(info->executable && !info->pie))
+ {
+ dynindx = elf_section_data (h->root.u.def.section
+ ->output_section)->dynindx;
+ addend += h->root.u.def.section->output_offset
+ + h->root.u.def.value;
+ }
+ else if (h && ! BFINFDPIC_FUNCDESC_LOCAL (info, h))
+ {
+ if (addend)
+ {
+ info->callbacks->warning
+ (info, _("R_BFIN_FUNCDESC references dynamic symbol with nonzero addend"),
+ name, input_bfd, input_section, rel->r_offset);
+ return FALSE;
+ }
+ dynindx = h->dynindx;
+ }
+ else
+ {
+ /* Otherwise, we know we have a private function
+ descriptor, so reference it directly. */
+ BFD_ASSERT (picrel->privfd);
+ r_type = R_BFIN_BYTE4_DATA;
+ dynindx = elf_section_data (bfinfdpic_got_section (info)
+ ->output_section)->dynindx;
+ addend = bfinfdpic_got_section (info)->output_offset
+ + bfinfdpic_got_initial_offset (info)
+ + picrel->fd_entry;
+ }
+
+ /* If there is room for dynamic symbol resolution, emit
+ the dynamic relocation. However, if we're linking an
+ executable at a fixed location, we won't have emitted a
+ dynamic symbol entry for the got section, so idx will
+ be zero, which means we can and should compute the
+ address of the private descriptor ourselves. */
+ if (info->executable && !info->pie
+ && (!h || BFINFDPIC_FUNCDESC_LOCAL (info, h)))
+ {
+ bfd_vma offset;
+
+ addend += bfinfdpic_got_section (info)->output_section->vma;
+ if ((bfd_get_section_flags (output_bfd,
+ input_section->output_section)
+ & (SEC_ALLOC | SEC_LOAD)) == (SEC_ALLOC | SEC_LOAD))
+ {
+ if (_bfinfdpic_osec_readonly_p (output_bfd,
+ input_section
+ ->output_section))
+ {
+ info->callbacks->warning
+ (info,
+ _("cannot emit fixups in read-only section"),
+ name, input_bfd, input_section, rel->r_offset);
+ return FALSE;
+ }
+
+ offset = _bfd_elf_section_offset
+ (output_bfd, info,
+ input_section, rel->r_offset);
+
+ if (offset != (bfd_vma)-1)
+ _bfinfdpic_add_rofixup (output_bfd,
+ bfinfdpic_gotfixup_section
+ (info),
+ offset + input_section
+ ->output_section->vma
+ + input_section->output_offset,
+ picrel);
+ }
+ }
+ else if ((bfd_get_section_flags (output_bfd,
+ input_section->output_section)
+ & (SEC_ALLOC | SEC_LOAD)) == (SEC_ALLOC | SEC_LOAD))
+ {
+ bfd_vma offset;
+
+ if (_bfinfdpic_osec_readonly_p (output_bfd,
+ input_section
+ ->output_section))
+ {
+ info->callbacks->warning
+ (info,
+ _("cannot emit dynamic relocations in read-only section"),
+ name, input_bfd, input_section, rel->r_offset);
+ return FALSE;
+ }
+ offset = _bfd_elf_section_offset (output_bfd, info,
+ input_section, rel->r_offset);
+
+ if (offset != (bfd_vma)-1)
+ _bfinfdpic_add_dyn_reloc (output_bfd,
+ bfinfdpic_gotrel_section (info),
+ offset + input_section
+ ->output_section->vma
+ + input_section->output_offset,
+ r_type,
+ dynindx, addend, picrel);
+ }
+ else
+ addend += bfinfdpic_got_section (info)->output_section->vma;
+ }
+
+ /* We want the addend in-place because dynamic
+ relocations are REL. Setting relocation to it should
+ arrange for it to be installed. */
+ relocation = addend - rel->r_addend;
+ }
+ check_segment[0] = check_segment[1] = got_segment;
+ break;
+
+ case R_BFIN_BYTE4_DATA:
+ if (! IS_FDPIC (output_bfd))
+ {
+ check_segment[0] = check_segment[1] = -1;
+ break;
+ }
+ /* Fall through. */
+ case R_BFIN_FUNCDESC_VALUE:
+ {
+ int dynindx;
+ bfd_vma addend = rel->r_addend;
+ bfd_vma offset;
+ offset = _bfd_elf_section_offset (output_bfd, info,
+ input_section, rel->r_offset);
+
+ /* If the symbol is dynamic but binds locally, use
+ section+offset. */
+ if (h && ! BFINFDPIC_SYM_LOCAL (info, h))
+ {
+ if (addend && r_type == R_BFIN_FUNCDESC_VALUE)
+ {
+ info->callbacks->warning
+ (info, _("R_BFIN_FUNCDESC_VALUE references dynamic symbol with nonzero addend"),
+ name, input_bfd, input_section, rel->r_offset);
+ return FALSE;
+ }
+ dynindx = h->dynindx;
+ }
+ else
+ {
+ if (h)
+ addend += h->root.u.def.value;
+ else
+ addend += sym->st_value;
+ if (osec)
+ addend += osec->output_offset;
+ if (osec && osec->output_section
+ && ! bfd_is_abs_section (osec->output_section)
+ && ! bfd_is_und_section (osec->output_section))
+ dynindx = elf_section_data (osec->output_section)->dynindx;
+ else
+ dynindx = 0;
+ }
+
+ /* If we're linking an executable at a fixed address, we
+ can omit the dynamic relocation as long as the symbol
+ is defined in the current link unit (which is implied
+ by its output section not being NULL). */
+ if (info->executable && !info->pie
+ && (!h || BFINFDPIC_SYM_LOCAL (info, h)))
+ {
+ if (osec)
+ addend += osec->output_section->vma;
+ if (IS_FDPIC (input_bfd)
+ && (bfd_get_section_flags (output_bfd,
+ input_section->output_section)
+ & (SEC_ALLOC | SEC_LOAD)) == (SEC_ALLOC | SEC_LOAD))
+ {
+ if (_bfinfdpic_osec_readonly_p (output_bfd,
+ input_section
+ ->output_section))
+ {
+ info->callbacks->warning
+ (info,
+ _("cannot emit fixups in read-only section"),
+ name, input_bfd, input_section, rel->r_offset);
+ return FALSE;
+ }
+ if (!h || h->root.type != bfd_link_hash_undefweak)
+ {
+ if (offset != (bfd_vma)-1)
+ {
+ _bfinfdpic_add_rofixup (output_bfd,
+ bfinfdpic_gotfixup_section
+ (info),
+ offset + input_section
+ ->output_section->vma
+ + input_section->output_offset,
+ picrel);
+
+ if (r_type == R_BFIN_FUNCDESC_VALUE)
+ _bfinfdpic_add_rofixup
+ (output_bfd,
+ bfinfdpic_gotfixup_section (info),
+ offset + input_section->output_section->vma
+ + input_section->output_offset + 4, picrel);
+ }
+ }
+ }
+ }
+ else
+ {
+ if ((bfd_get_section_flags (output_bfd,
+ input_section->output_section)
+ & (SEC_ALLOC | SEC_LOAD)) == (SEC_ALLOC | SEC_LOAD))
+ {
+ if (_bfinfdpic_osec_readonly_p (output_bfd,
+ input_section
+ ->output_section))
+ {
+ info->callbacks->warning
+ (info,
+ _("cannot emit dynamic relocations in read-only section"),
+ name, input_bfd, input_section, rel->r_offset);
+ return FALSE;
+ }
+
+ if (offset != (bfd_vma)-1)
+ _bfinfdpic_add_dyn_reloc (output_bfd,
+ bfinfdpic_gotrel_section (info),
+ offset
+ + input_section->output_section->vma
+ + input_section->output_offset,
+ r_type, dynindx, addend, picrel);
+ }
+ else if (osec)
+ addend += osec->output_section->vma;
+ /* We want the addend in-place because dynamic
+ relocations are REL. Setting relocation to it
+ should arrange for it to be installed. */
+ relocation = addend - rel->r_addend;
+ }
+
+ if (r_type == R_BFIN_FUNCDESC_VALUE)
+ {
+ /* If we've omitted the dynamic relocation, just emit
+ the fixed addresses of the symbol and of the local
+ GOT base offset. */
+ if (info->executable && !info->pie
+ && (!h || BFINFDPIC_SYM_LOCAL (info, h)))
+ bfd_put_32 (output_bfd,
+ bfinfdpic_got_section (info)->output_section->vma
+ + bfinfdpic_got_section (info)->output_offset
+ + bfinfdpic_got_initial_offset (info),
+ contents + rel->r_offset + 4);
+ else
+ /* A function descriptor used for lazy or local
+ resolving is initialized such that its high word
+ contains the output section index in which the
+ PLT entries are located, and the low word
+ contains the offset of the lazy PLT entry entry
+ point into that section. */
+ bfd_put_32 (output_bfd,
+ h && ! BFINFDPIC_SYM_LOCAL (info, h)
+ ? 0
+ : _bfinfdpic_osec_to_segment (output_bfd,
+ sec
+ ->output_section),
+ contents + rel->r_offset + 4);
+ }
+ }
+ check_segment[0] = check_segment[1] = got_segment;
+ break;
+
+ default:
+ check_segment[0] = isec_segment;
+ check_segment[1] = sec
+ ? _bfinfdpic_osec_to_segment (output_bfd, sec->output_section)
+ : (unsigned)-1;
+ break;
+ }
+
+ if (check_segment[0] != check_segment[1] && IS_FDPIC (output_bfd))
+ {
+#if 1 /* If you take this out, remove the #error from fdpic-static-6.d
+ in the ld testsuite. */
+ /* This helps catch problems in GCC while we can't do more
+ than static linking. The idea is to test whether the
+ input file basename is crt0.o only once. */
+ if (silence_segment_error == 1)
+ silence_segment_error =
+ (strlen (input_bfd->filename) == 6
+ && filename_cmp (input_bfd->filename, "crt0.o") == 0)
+ || (strlen (input_bfd->filename) > 6
+ && filename_cmp (input_bfd->filename
+ + strlen (input_bfd->filename) - 7,
+ "/crt0.o") == 0)
+ ? -1 : 0;
+#endif
+ if (!silence_segment_error
+ /* We don't want duplicate errors for undefined
+ symbols. */
+ && !(picrel && picrel->symndx == -1
+ && picrel->d.h->root.type == bfd_link_hash_undefined))
+ info->callbacks->warning
+ (info,
+ (info->shared || info->pie)
+ ? _("relocations between different segments are not supported")
+ : _("warning: relocation references a different segment"),
+ name, input_bfd, input_section, rel->r_offset);
+ if (!silence_segment_error && (info->shared || info->pie))
+ return FALSE;
+ elf_elfheader (output_bfd)->e_flags |= EF_BFIN_PIC;
+ }
+
+ switch (r_type)
+ {
+ case R_BFIN_GOTOFFHI:
+ /* We need the addend to be applied before we shift the
+ value right. */
+ relocation += rel->r_addend;
+ /* Fall through. */
+ case R_BFIN_GOTHI:
+ case R_BFIN_FUNCDESC_GOTHI:
+ case R_BFIN_FUNCDESC_GOTOFFHI:
+ relocation >>= 16;
+ /* Fall through. */
+
+ case R_BFIN_GOTLO:
+ case R_BFIN_FUNCDESC_GOTLO:
+ case R_BFIN_GOTOFFLO:
+ case R_BFIN_FUNCDESC_GOTOFFLO:
+ relocation &= 0xffff;
+ break;
+
+ default:
+ break;
+ }
+
+ switch (r_type)
+ {
+ case R_BFIN_PCREL24:
+ case R_BFIN_PCREL24_JUMP_L:
+ if (! IS_FDPIC (output_bfd) || ! picrel->plt)
+ break;
+ /* Fall through. */
+
+ /* When referencing a GOT entry, a function descriptor or a
+ PLT, we don't want the addend to apply to the reference,
+ but rather to the referenced symbol. The actual entry
+ will have already been created taking the addend into
+ account, so cancel it out here. */
+ case R_BFIN_GOT17M4:
+ case R_BFIN_GOTHI:
+ case R_BFIN_GOTLO:
+ case R_BFIN_FUNCDESC_GOT17M4:
+ case R_BFIN_FUNCDESC_GOTHI:
+ case R_BFIN_FUNCDESC_GOTLO:
+ case R_BFIN_FUNCDESC_GOTOFF17M4:
+ case R_BFIN_FUNCDESC_GOTOFFHI:
+ case R_BFIN_FUNCDESC_GOTOFFLO:
+ /* Note that we only want GOTOFFHI, not GOTOFFLO or GOTOFF17M4
+ here, since we do want to apply the addend to the others.
+ Note that we've applied the addend to GOTOFFHI before we
+ shifted it right. */
+ case R_BFIN_GOTOFFHI:
+ relocation -= rel->r_addend;
+ break;
+
+ default:
+ break;
+ }
+
+ r = bfin_final_link_relocate (rel, howto, input_bfd, input_section,
+ contents, rel->r_offset,
+ relocation, rel->r_addend);
+
+ if (r != bfd_reloc_ok)
+ {
+ const char * msg = (const char *) NULL;
+
+ switch (r)
+ {
+ case bfd_reloc_overflow:
+ r = info->callbacks->reloc_overflow
+ (info, (h ? &h->root : NULL), 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, TRUE);
+ 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;
+}
+
+/* Update the relocation information for the relocations of the section
+ being removed. */
+
+static bfd_boolean
+bfinfdpic_gc_sweep_hook (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;
+ struct bfinfdpic_relocs_info *picrel;
+
+ BFD_ASSERT (IS_FDPIC (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];
+
+ if (h != NULL)
+ picrel = bfinfdpic_relocs_info_for_global (bfinfdpic_relocs_info (info),
+ abfd, h,
+ rel->r_addend, NO_INSERT);
+ else
+ picrel = bfinfdpic_relocs_info_for_local (bfinfdpic_relocs_info
+ (info), abfd, r_symndx,
+ rel->r_addend, NO_INSERT);
+
+ if (!picrel)
+ return TRUE;
+
+ switch (ELF32_R_TYPE (rel->r_info))
+ {
+ case R_BFIN_PCREL24:
+ case R_BFIN_PCREL24_JUMP_L:
+ picrel->call--;
+ break;
+
+ case R_BFIN_FUNCDESC_VALUE:
+ picrel->relocsfdv--;
+ if (bfd_get_section_flags (abfd, sec) & SEC_ALLOC)
+ picrel->relocs32++;
+ /* Fall through. */
+
+ case R_BFIN_BYTE4_DATA:
+ picrel->sym--;
+ if (bfd_get_section_flags (abfd, sec) & SEC_ALLOC)
+ picrel->relocs32--;
+ break;
+
+ case R_BFIN_GOT17M4:
+ picrel->got17m4--;
+ break;
+
+ case R_BFIN_GOTHI:
+ case R_BFIN_GOTLO:
+ picrel->gothilo--;
+ break;
+
+ case R_BFIN_FUNCDESC_GOT17M4:
+ picrel->fdgot17m4--;
+ break;
+
+ case R_BFIN_FUNCDESC_GOTHI:
+ case R_BFIN_FUNCDESC_GOTLO:
+ picrel->fdgothilo--;
+ break;
+
+ case R_BFIN_GOTOFF17M4:
+ case R_BFIN_GOTOFFHI:
+ case R_BFIN_GOTOFFLO:
+ picrel->gotoff--;
+ break;
+
+ case R_BFIN_FUNCDESC_GOTOFF17M4:
+ picrel->fdgoff17m4--;
+ break;
+
+ case R_BFIN_FUNCDESC_GOTOFFHI:
+ case R_BFIN_FUNCDESC_GOTOFFLO:
+ picrel->fdgoffhilo--;
+ break;
+
+ case R_BFIN_FUNCDESC:
+ picrel->fd--;
+ picrel->relocsfd--;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ return TRUE;
+}
+
+/* We need dynamic symbols for every section, since segments can
+ relocate independently. */
+static bfd_boolean
+_bfinfdpic_link_omit_section_dynsym (bfd *output_bfd ATTRIBUTE_UNUSED,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ asection *p)
+{
+ switch (elf_section_data (p)->this_hdr.sh_type)
+ {
+ case SHT_PROGBITS:
+ case SHT_NOBITS:
+ /* If sh_type is yet undecided, assume it could be
+ SHT_PROGBITS/SHT_NOBITS. */
+ case SHT_NULL:
+ return FALSE;
+
+ /* There shouldn't be section relative relocations
+ against any other section. */
+ default:
+ return TRUE;
+ }
+}
+
+/* Create a .got section, as well as its additional info field. This
+ is almost entirely copied from
+ elflink.c:_bfd_elf_create_got_section(). */
+
+static bfd_boolean
+_bfin_create_got_section (bfd *abfd, struct bfd_link_info *info)
+{
+ flagword flags, pltflags;
+ asection *s;
+ struct elf_link_hash_entry *h;
+ const struct elf_backend_data *bed = get_elf_backend_data (abfd);
+ int ptralign;
+
+ /* This function may be called more than once. */
+ s = bfd_get_linker_section (abfd, ".got");
+ if (s != NULL)
+ return TRUE;
+
+ /* Machine specific: although pointers are 32-bits wide, we want the
+ GOT to be aligned to a 64-bit boundary, such that function
+ descriptors in it can be accessed with 64-bit loads and
+ stores. */
+ ptralign = 3;
+
+ flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
+ | SEC_LINKER_CREATED);
+ pltflags = flags;
+
+ s = bfd_make_section_anyway_with_flags (abfd, ".got", flags);
+ if (s == NULL
+ || !bfd_set_section_alignment (abfd, s, ptralign))
+ return FALSE;
+
+ if (bed->want_got_plt)
+ {
+ s = bfd_make_section_anyway_with_flags (abfd, ".got.plt", flags);
+ if (s == NULL
+ || !bfd_set_section_alignment (abfd, s, ptralign))
+ return FALSE;
+ }
+
+ if (bed->want_got_sym)
+ {
+ /* 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 = _bfd_elf_define_linkage_sym (abfd, info, s, "__GLOBAL_OFFSET_TABLE_");
+ elf_hash_table (info)->hgot = h;
+ if (h == NULL)
+ return FALSE;
+
+ /* Machine-specific: we want the symbol for executables as
+ well. */
+ if (! bfd_elf_link_record_dynamic_symbol (info, h))
+ return FALSE;
+ }
+
+ /* The first bit of the global offset table is the header. */
+ s->size += bed->got_header_size;
+
+ /* This is the machine-specific part. Create and initialize section
+ data for the got. */
+ if (IS_FDPIC (abfd))
+ {
+ bfinfdpic_got_section (info) = s;
+ bfinfdpic_relocs_info (info) = htab_try_create (1,
+ bfinfdpic_relocs_info_hash,
+ bfinfdpic_relocs_info_eq,
+ (htab_del) NULL);
+ if (! bfinfdpic_relocs_info (info))
+ return FALSE;
+
+ s = bfd_make_section_anyway_with_flags (abfd, ".rel.got",
+ (flags | SEC_READONLY));
+ if (s == NULL
+ || ! bfd_set_section_alignment (abfd, s, 2))
+ return FALSE;
+
+ bfinfdpic_gotrel_section (info) = s;
+
+ /* Machine-specific. */
+ s = bfd_make_section_anyway_with_flags (abfd, ".rofixup",
+ (flags | SEC_READONLY));
+ if (s == NULL
+ || ! bfd_set_section_alignment (abfd, s, 2))
+ return FALSE;
+
+ bfinfdpic_gotfixup_section (info) = s;
+ }
+
+ pltflags |= SEC_CODE;
+ if (bed->plt_not_loaded)
+ pltflags &= ~ (SEC_CODE | SEC_LOAD | SEC_HAS_CONTENTS);
+ if (bed->plt_readonly)
+ pltflags |= SEC_READONLY;
+
+ s = bfd_make_section_anyway_with_flags (abfd, ".plt", pltflags);
+ if (s == NULL
+ || ! bfd_set_section_alignment (abfd, s, bed->plt_alignment))
+ return FALSE;
+ /* Blackfin-specific: remember it. */
+ bfinfdpic_plt_section (info) = s;
+
+ if (bed->want_plt_sym)
+ {
+ /* Define the symbol _PROCEDURE_LINKAGE_TABLE_ at the start of the
+ .plt section. */
+ struct bfd_link_hash_entry *bh = NULL;
+
+ if (! (_bfd_generic_link_add_one_symbol
+ (info, abfd, "__PROCEDURE_LINKAGE_TABLE_", BSF_GLOBAL, s, 0, NULL,
+ FALSE, get_elf_backend_data (abfd)->collect, &bh)))
+ return FALSE;
+ h = (struct elf_link_hash_entry *) bh;
+ h->def_regular = 1;
+ h->type = STT_OBJECT;
+
+ if (! info->executable
+ && ! bfd_elf_link_record_dynamic_symbol (info, h))
+ return FALSE;
+ }
+
+ /* Blackfin-specific: we want rel relocations for the plt. */
+ s = bfd_make_section_anyway_with_flags (abfd, ".rel.plt",
+ flags | SEC_READONLY);
+ if (s == NULL
+ || ! bfd_set_section_alignment (abfd, s, bed->s->log_file_align))
+ return FALSE;
+ /* Blackfin-specific: remember it. */
+ bfinfdpic_pltrel_section (info) = s;
+
+ return TRUE;
+}
+
+/* Make sure the got and plt sections exist, and that our pointers in
+ the link hash table point to them. */
+
+static bfd_boolean
+elf32_bfinfdpic_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
+{
+ /* This is mostly copied from
+ elflink.c:_bfd_elf_create_dynamic_sections(). */
+ flagword flags;
+ asection *s;
+ const struct elf_backend_data *bed = get_elf_backend_data (abfd);
+
+ flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
+ | SEC_LINKER_CREATED);
+
+ /* We need to create .plt, .rel[a].plt, .got, .got.plt, .dynbss, and
+ .rel[a].bss sections. */
+
+ /* Blackfin-specific: we want to create the GOT in the Blackfin way. */
+ if (! _bfin_create_got_section (abfd, info))
+ return FALSE;
+
+ /* Blackfin-specific: make sure we created everything we wanted. */
+ BFD_ASSERT (bfinfdpic_got_section (info) && bfinfdpic_gotrel_section (info)
+ /* && bfinfdpic_gotfixup_section (info) */
+ && bfinfdpic_plt_section (info)
+ && bfinfdpic_pltrel_section (info));
+
+ if (bed->want_dynbss)
+ {
+ /* 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_anyway_with_flags (abfd, ".dynbss",
+ SEC_ALLOC | SEC_LINKER_CREATED);
+ if (s == NULL)
+ 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_anyway_with_flags (abfd,
+ ".rela.bss",
+ flags | SEC_READONLY);
+ if (s == NULL
+ || ! bfd_set_section_alignment (abfd, s, bed->s->log_file_align))
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+/* Compute the total GOT size required by each symbol in each range.
+ Symbols may require up to 4 words in the GOT: an entry pointing to
+ the symbol, an entry pointing to its function descriptor, and a
+ private function descriptors taking two words. */
+
+static void
+_bfinfdpic_count_nontls_entries (struct bfinfdpic_relocs_info *entry,
+ struct _bfinfdpic_dynamic_got_info *dinfo)
+{
+ /* Allocate space for a GOT entry pointing to the symbol. */
+ if (entry->got17m4)
+ dinfo->got17m4 += 4;
+ else if (entry->gothilo)
+ dinfo->gothilo += 4;
+ else
+ entry->relocs32--;
+ entry->relocs32++;
+
+ /* Allocate space for a GOT entry pointing to the function
+ descriptor. */
+ if (entry->fdgot17m4)
+ dinfo->got17m4 += 4;
+ else if (entry->fdgothilo)
+ dinfo->gothilo += 4;
+ else
+ entry->relocsfd--;
+ entry->relocsfd++;
+
+ /* Decide whether we need a PLT entry, a function descriptor in the
+ GOT, and a lazy PLT entry for this symbol. */
+ entry->plt = entry->call
+ && entry->symndx == -1 && ! BFINFDPIC_SYM_LOCAL (dinfo->info, entry->d.h)
+ && elf_hash_table (dinfo->info)->dynamic_sections_created;
+ entry->privfd = entry->plt
+ || entry->fdgoff17m4 || entry->fdgoffhilo
+ || ((entry->fd || entry->fdgot17m4 || entry->fdgothilo)
+ && (entry->symndx != -1
+ || BFINFDPIC_FUNCDESC_LOCAL (dinfo->info, entry->d.h)));
+ entry->lazyplt = entry->privfd
+ && entry->symndx == -1 && ! BFINFDPIC_SYM_LOCAL (dinfo->info, entry->d.h)
+ && ! (dinfo->info->flags & DF_BIND_NOW)
+ && elf_hash_table (dinfo->info)->dynamic_sections_created;
+
+ /* Allocate space for a function descriptor. */
+ if (entry->fdgoff17m4)
+ dinfo->fd17m4 += 8;
+ else if (entry->privfd && entry->plt)
+ dinfo->fdplt += 8;
+ else if (entry->privfd)
+ dinfo->fdhilo += 8;
+ else
+ entry->relocsfdv--;
+ entry->relocsfdv++;
+
+ if (entry->lazyplt)
+ dinfo->lzplt += LZPLT_NORMAL_SIZE;
+}
+
+/* Compute the number of dynamic relocations and fixups that a symbol
+ requires, and add (or subtract) from the grand and per-symbol
+ totals. */
+
+static void
+_bfinfdpic_count_relocs_fixups (struct bfinfdpic_relocs_info *entry,
+ struct _bfinfdpic_dynamic_got_info *dinfo,
+ bfd_boolean subtract)
+{
+ bfd_vma relocs = 0, fixups = 0;
+
+ if (!dinfo->info->executable || dinfo->info->pie)
+ relocs = entry->relocs32 + entry->relocsfd + entry->relocsfdv;
+ else
+ {
+ if (entry->symndx != -1 || BFINFDPIC_SYM_LOCAL (dinfo->info, entry->d.h))
+ {
+ if (entry->symndx != -1
+ || entry->d.h->root.type != bfd_link_hash_undefweak)
+ fixups += entry->relocs32 + 2 * entry->relocsfdv;
+ }
+ else
+ relocs += entry->relocs32 + entry->relocsfdv;
+
+ if (entry->symndx != -1
+ || BFINFDPIC_FUNCDESC_LOCAL (dinfo->info, entry->d.h))
+ {
+ if (entry->symndx != -1
+ || entry->d.h->root.type != bfd_link_hash_undefweak)
+ fixups += entry->relocsfd;
+ }
+ else
+ relocs += entry->relocsfd;
+ }
+
+ if (subtract)
+ {
+ relocs = - relocs;
+ fixups = - fixups;
+ }
+
+ entry->dynrelocs += relocs;
+ entry->fixups += fixups;
+ dinfo->relocs += relocs;
+ dinfo->fixups += fixups;
+}
+
+/* Compute the total GOT and PLT size required by each symbol in each range. *
+ Symbols may require up to 4 words in the GOT: an entry pointing to
+ the symbol, an entry pointing to its function descriptor, and a
+ private function descriptors taking two words. */
+
+static int
+_bfinfdpic_count_got_plt_entries (void **entryp, void *dinfo_)
+{
+ struct bfinfdpic_relocs_info *entry = *entryp;
+ struct _bfinfdpic_dynamic_got_info *dinfo = dinfo_;
+
+ _bfinfdpic_count_nontls_entries (entry, dinfo);
+
+ _bfinfdpic_count_relocs_fixups (entry, dinfo, FALSE);
+
+ return 1;
+}
+
+/* This structure is used to assign offsets to got entries, function
+ descriptors, plt entries and lazy plt entries. */
+
+struct _bfinfdpic_dynamic_got_plt_info
+{
+ /* Summary information collected with _bfinfdpic_count_got_plt_entries. */
+ struct _bfinfdpic_dynamic_got_info g;
+
+ /* For each addressable range, we record a MAX (positive) and MIN
+ (negative) value. CUR is used to assign got entries, and it's
+ incremented from an initial positive value to MAX, then from MIN
+ to FDCUR (unless FDCUR wraps around first). FDCUR is used to
+ assign function descriptors, and it's decreased from an initial
+ non-positive value to MIN, then from MAX down to CUR (unless CUR
+ wraps around first). All of MIN, MAX, CUR and FDCUR always point
+ to even words. ODD, if non-zero, indicates an odd word to be
+ used for the next got entry, otherwise CUR is used and
+ incremented by a pair of words, wrapping around when it reaches
+ MAX. FDCUR is decremented (and wrapped) before the next function
+ descriptor is chosen. FDPLT indicates the number of remaining
+ slots that can be used for function descriptors used only by PLT
+ entries. */
+ struct _bfinfdpic_dynamic_got_alloc_data
+ {
+ bfd_signed_vma max, cur, odd, fdcur, min;
+ bfd_vma fdplt;
+ } got17m4, gothilo;
+};
+
+/* Determine the positive and negative ranges to be used by each
+ offset range in the GOT. FDCUR and CUR, that must be aligned to a
+ double-word boundary, are the minimum (negative) and maximum
+ (positive) GOT offsets already used by previous ranges, except for
+ an ODD entry that may have been left behind. GOT and FD indicate
+ the size of GOT entries and function descriptors that must be
+ placed within the range from -WRAP to WRAP. If there's room left,
+ up to FDPLT bytes should be reserved for additional function
+ descriptors. */
+
+inline static bfd_signed_vma
+_bfinfdpic_compute_got_alloc_data (struct _bfinfdpic_dynamic_got_alloc_data *gad,
+ bfd_signed_vma fdcur,
+ bfd_signed_vma odd,
+ bfd_signed_vma cur,
+ bfd_vma got,
+ bfd_vma fd,
+ bfd_vma fdplt,
+ bfd_vma wrap)
+{
+ bfd_signed_vma wrapmin = -wrap;
+
+ /* Start at the given initial points. */
+ gad->fdcur = fdcur;
+ gad->cur = cur;
+
+ /* If we had an incoming odd word and we have any got entries that
+ are going to use it, consume it, otherwise leave gad->odd at
+ zero. We might force gad->odd to zero and return the incoming
+ odd such that it is used by the next range, but then GOT entries
+ might appear to be out of order and we wouldn't be able to
+ shorten the GOT by one word if it turns out to end with an
+ unpaired GOT entry. */
+ if (odd && got)
+ {
+ gad->odd = odd;
+ got -= 4;
+ odd = 0;
+ }
+ else
+ gad->odd = 0;
+
+ /* If we're left with an unpaired GOT entry, compute its location
+ such that we can return it. Otherwise, if got doesn't require an
+ odd number of words here, either odd was already zero in the
+ block above, or it was set to zero because got was non-zero, or
+ got was already zero. In the latter case, we want the value of
+ odd to carry over to the return statement, so we don't want to
+ reset odd unless the condition below is true. */
+ if (got & 4)
+ {
+ odd = cur + got;
+ got += 4;
+ }
+
+ /* Compute the tentative boundaries of this range. */
+ gad->max = cur + got;
+ gad->min = fdcur - fd;
+ gad->fdplt = 0;
+
+ /* If function descriptors took too much space, wrap some of them
+ around. */
+ if (gad->min < wrapmin)
+ {
+ gad->max += wrapmin - gad->min;
+ gad->min = wrapmin;
+ }
+ /* If there is space left and we have function descriptors
+ referenced in PLT entries that could take advantage of shorter
+ offsets, place them here. */
+ else if (fdplt && gad->min > wrapmin)
+ {
+ bfd_vma fds;
+ if ((bfd_vma) (gad->min - wrapmin) < fdplt)
+ fds = gad->min - wrapmin;
+ else
+ fds = fdplt;
+
+ fdplt -= fds;
+ gad->min -= fds;
+ gad->fdplt += fds;
+ }
+
+ /* If GOT entries took too much space, wrap some of them around.
+ This may well cause gad->min to become lower than wrapmin. This
+ will cause a relocation overflow later on, so we don't have to
+ report it here . */
+ if ((bfd_vma) gad->max > wrap)
+ {
+ gad->min -= gad->max - wrap;
+ gad->max = wrap;
+ }
+ /* If there is more space left, try to place some more function
+ descriptors for PLT entries. */
+ else if (fdplt && (bfd_vma) gad->max < wrap)
+ {
+ bfd_vma fds;
+ if ((bfd_vma) (wrap - gad->max) < fdplt)
+ fds = wrap - gad->max;
+ else
+ fds = fdplt;
+
+ fdplt -= fds;
+ gad->max += fds;
+ gad->fdplt += fds;
+ }
+
+ /* If odd was initially computed as an offset past the wrap point,
+ wrap it around. */
+ if (odd > gad->max)
+ odd = gad->min + odd - gad->max;
+
+ /* _bfinfdpic_get_got_entry() below will always wrap gad->cur if needed
+ before returning, so do it here too. This guarantees that,
+ should cur and fdcur meet at the wrap point, they'll both be
+ equal to min. */
+ if (gad->cur == gad->max)
+ gad->cur = gad->min;
+
+ return odd;
+}
+
+/* Compute the location of the next GOT entry, given the allocation
+ data for a range. */
+
+inline static bfd_signed_vma
+_bfinfdpic_get_got_entry (struct _bfinfdpic_dynamic_got_alloc_data *gad)
+{
+ bfd_signed_vma ret;
+
+ if (gad->odd)
+ {
+ /* If there was an odd word left behind, use it. */
+ ret = gad->odd;
+ gad->odd = 0;
+ }
+ else
+ {
+ /* Otherwise, use the word pointed to by cur, reserve the next
+ as an odd word, and skip to the next pair of words, possibly
+ wrapping around. */
+ ret = gad->cur;
+ gad->odd = gad->cur + 4;
+ gad->cur += 8;
+ if (gad->cur == gad->max)
+ gad->cur = gad->min;
+ }
+
+ return ret;
+}
+
+/* Compute the location of the next function descriptor entry in the
+ GOT, given the allocation data for a range. */
+
+inline static bfd_signed_vma
+_bfinfdpic_get_fd_entry (struct _bfinfdpic_dynamic_got_alloc_data *gad)
+{
+ /* If we're at the bottom, wrap around, and only then allocate the
+ next pair of words. */
+ if (gad->fdcur == gad->min)
+ gad->fdcur = gad->max;
+ return gad->fdcur -= 8;
+}
+
+/* Assign GOT offsets for every GOT entry and function descriptor.
+ Doing everything in a single pass is tricky. */
+
+static int
+_bfinfdpic_assign_got_entries (void **entryp, void *info_)
+{
+ struct bfinfdpic_relocs_info *entry = *entryp;
+ struct _bfinfdpic_dynamic_got_plt_info *dinfo = info_;
+
+ if (entry->got17m4)
+ entry->got_entry = _bfinfdpic_get_got_entry (&dinfo->got17m4);
+ else if (entry->gothilo)
+ entry->got_entry = _bfinfdpic_get_got_entry (&dinfo->gothilo);
+
+ if (entry->fdgot17m4)
+ entry->fdgot_entry = _bfinfdpic_get_got_entry (&dinfo->got17m4);
+ else if (entry->fdgothilo)
+ entry->fdgot_entry = _bfinfdpic_get_got_entry (&dinfo->gothilo);
+
+ if (entry->fdgoff17m4)
+ entry->fd_entry = _bfinfdpic_get_fd_entry (&dinfo->got17m4);
+ else if (entry->plt && dinfo->got17m4.fdplt)
+ {
+ dinfo->got17m4.fdplt -= 8;
+ entry->fd_entry = _bfinfdpic_get_fd_entry (&dinfo->got17m4);
+ }
+ else if (entry->plt)
+ {
+ dinfo->gothilo.fdplt -= 8;
+ entry->fd_entry = _bfinfdpic_get_fd_entry (&dinfo->gothilo);
+ }
+ else if (entry->privfd)
+ entry->fd_entry = _bfinfdpic_get_fd_entry (&dinfo->gothilo);
+
+ return 1;
+}
+
+/* Assign GOT offsets to private function descriptors used by PLT
+ entries (or referenced by 32-bit offsets), as well as PLT entries
+ and lazy PLT entries. */
+
+static int
+_bfinfdpic_assign_plt_entries (void **entryp, void *info_)
+{
+ struct bfinfdpic_relocs_info *entry = *entryp;
+ struct _bfinfdpic_dynamic_got_plt_info *dinfo = info_;
+
+ /* If this symbol requires a local function descriptor, allocate
+ one. */
+ if (entry->privfd && entry->fd_entry == 0)
+ {
+ if (dinfo->got17m4.fdplt)
+ {
+ entry->fd_entry = _bfinfdpic_get_fd_entry (&dinfo->got17m4);
+ dinfo->got17m4.fdplt -= 8;
+ }
+ else
+ {
+ BFD_ASSERT (dinfo->gothilo.fdplt);
+ entry->fd_entry = _bfinfdpic_get_fd_entry (&dinfo->gothilo);
+ dinfo->gothilo.fdplt -= 8;
+ }
+ }
+
+ if (entry->plt)
+ {
+ int size;
+
+ /* We use the section's raw size to mark the location of the
+ next PLT entry. */
+ entry->plt_entry = bfinfdpic_plt_section (dinfo->g.info)->size;
+
+ /* Figure out the length of this PLT entry based on the
+ addressing mode we need to reach the function descriptor. */
+ BFD_ASSERT (entry->fd_entry);
+ if (entry->fd_entry >= -(1 << (18 - 1))
+ && entry->fd_entry + 4 < (1 << (18 - 1)))
+ size = 10;
+ else
+ size = 16;
+
+ bfinfdpic_plt_section (dinfo->g.info)->size += size;
+ }
+
+ if (entry->lazyplt)
+ {
+ entry->lzplt_entry = dinfo->g.lzplt;
+ dinfo->g.lzplt += LZPLT_NORMAL_SIZE;
+ /* If this entry is the one that gets the resolver stub, account
+ for the additional instruction. */
+ if (entry->lzplt_entry % BFINFDPIC_LZPLT_BLOCK_SIZE
+ == BFINFDPIC_LZPLT_RESOLV_LOC)
+ dinfo->g.lzplt += LZPLT_RESOLVER_EXTRA;
+ }
+
+ return 1;
+}
+
+/* Cancel out any effects of calling _bfinfdpic_assign_got_entries and
+ _bfinfdpic_assign_plt_entries. */
+
+static int
+_bfinfdpic_reset_got_plt_entries (void **entryp, void *ignore ATTRIBUTE_UNUSED)
+{
+ struct bfinfdpic_relocs_info *entry = *entryp;
+
+ entry->got_entry = 0;
+ entry->fdgot_entry = 0;
+ entry->fd_entry = 0;
+ entry->plt_entry = (bfd_vma)-1;
+ entry->lzplt_entry = (bfd_vma)-1;
+
+ return 1;
+}
+
+/* Follow indirect and warning hash entries so that each got entry
+ points to the final symbol definition. P must point to a pointer
+ to the hash table we're traversing. Since this traversal may
+ modify the hash table, we set this pointer to NULL to indicate
+ we've made a potentially-destructive change to the hash table, so
+ the traversal must be restarted. */
+static int
+_bfinfdpic_resolve_final_relocs_info (void **entryp, void *p)
+{
+ struct bfinfdpic_relocs_info *entry = *entryp;
+ htab_t *htab = p;
+
+ if (entry->symndx == -1)
+ {
+ struct elf_link_hash_entry *h = entry->d.h;
+ struct bfinfdpic_relocs_info *oentry;
+
+ 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 (entry->d.h == h)
+ return 1;
+
+ oentry = bfinfdpic_relocs_info_for_global (*htab, 0, h, entry->addend,
+ NO_INSERT);
+
+ if (oentry)
+ {
+ /* Merge the two entries. */
+ bfinfdpic_pic_merge_early_relocs_info (oentry, entry);
+ htab_clear_slot (*htab, entryp);
+ return 1;
+ }
+
+ entry->d.h = h;
+
+ /* If we can't find this entry with the new bfd hash, re-insert
+ it, and get the traversal restarted. */
+ if (! htab_find (*htab, entry))
+ {
+ htab_clear_slot (*htab, entryp);
+ entryp = htab_find_slot (*htab, entry, INSERT);
+ if (! *entryp)
+ *entryp = entry;
+ /* Abort the traversal, since the whole table may have
+ moved, and leave it up to the parent to restart the
+ process. */
+ *(htab_t *)p = NULL;
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
+/* Compute the total size of the GOT, the PLT, the dynamic relocations
+ section and the rofixup section. Assign locations for GOT and PLT
+ entries. */
+
+static bfd_boolean
+_bfinfdpic_size_got_plt (bfd *output_bfd,
+ struct _bfinfdpic_dynamic_got_plt_info *gpinfop)
+{
+ bfd_signed_vma odd;
+ bfd_vma limit;
+ struct bfd_link_info *info = gpinfop->g.info;
+ bfd *dynobj = elf_hash_table (info)->dynobj;
+
+ memcpy (bfinfdpic_dynamic_got_plt_info (info), &gpinfop->g,
+ sizeof (gpinfop->g));
+
+ odd = 12;
+ /* Compute the total size taken by entries in the 18-bit range,
+ to tell how many PLT function descriptors we can bring into it
+ without causing it to overflow. */
+ limit = odd + gpinfop->g.got17m4 + gpinfop->g.fd17m4;
+ if (limit < (bfd_vma)1 << 18)
+ limit = ((bfd_vma)1 << 18) - limit;
+ else
+ limit = 0;
+ if (gpinfop->g.fdplt < limit)
+ limit = gpinfop->g.fdplt;
+
+ /* Determine the ranges of GOT offsets that we can use for each
+ range of addressing modes. */
+ odd = _bfinfdpic_compute_got_alloc_data (&gpinfop->got17m4,
+ 0,
+ odd,
+ 16,
+ gpinfop->g.got17m4,
+ gpinfop->g.fd17m4,
+ limit,
+ (bfd_vma)1 << (18-1));
+ odd = _bfinfdpic_compute_got_alloc_data (&gpinfop->gothilo,
+ gpinfop->got17m4.min,
+ odd,
+ gpinfop->got17m4.max,
+ gpinfop->g.gothilo,
+ gpinfop->g.fdhilo,
+ gpinfop->g.fdplt - gpinfop->got17m4.fdplt,
+ (bfd_vma)1 << (32-1));
+
+ /* Now assign (most) GOT offsets. */
+ htab_traverse (bfinfdpic_relocs_info (info), _bfinfdpic_assign_got_entries,
+ gpinfop);
+
+ bfinfdpic_got_section (info)->size = gpinfop->gothilo.max
+ - gpinfop->gothilo.min
+ /* If an odd word is the last word of the GOT, we don't need this
+ word to be part of the GOT. */
+ - (odd + 4 == gpinfop->gothilo.max ? 4 : 0);
+ if (bfinfdpic_got_section (info)->size == 0)
+ bfinfdpic_got_section (info)->flags |= SEC_EXCLUDE;
+ else if (bfinfdpic_got_section (info)->size == 12
+ && ! elf_hash_table (info)->dynamic_sections_created)
+ {
+ bfinfdpic_got_section (info)->flags |= SEC_EXCLUDE;
+ bfinfdpic_got_section (info)->size = 0;
+ }
+ else
+ {
+ bfinfdpic_got_section (info)->contents =
+ (bfd_byte *) bfd_zalloc (dynobj,
+ bfinfdpic_got_section (info)->size);
+ if (bfinfdpic_got_section (info)->contents == NULL)
+ return FALSE;
+ }
+
+ if (elf_hash_table (info)->dynamic_sections_created)
+ /* Subtract the number of lzplt entries, since those will generate
+ relocations in the pltrel section. */
+ bfinfdpic_gotrel_section (info)->size =
+ (gpinfop->g.relocs - gpinfop->g.lzplt / LZPLT_NORMAL_SIZE)
+ * get_elf_backend_data (output_bfd)->s->sizeof_rel;
+ else
+ BFD_ASSERT (gpinfop->g.relocs == 0);
+ if (bfinfdpic_gotrel_section (info)->size == 0)
+ bfinfdpic_gotrel_section (info)->flags |= SEC_EXCLUDE;
+ else
+ {
+ bfinfdpic_gotrel_section (info)->contents =
+ (bfd_byte *) bfd_zalloc (dynobj,
+ bfinfdpic_gotrel_section (info)->size);
+ if (bfinfdpic_gotrel_section (info)->contents == NULL)
+ return FALSE;
+ }
+
+ bfinfdpic_gotfixup_section (info)->size = (gpinfop->g.fixups + 1) * 4;
+ if (bfinfdpic_gotfixup_section (info)->size == 0)
+ bfinfdpic_gotfixup_section (info)->flags |= SEC_EXCLUDE;
+ else
+ {
+ bfinfdpic_gotfixup_section (info)->contents =
+ (bfd_byte *) bfd_zalloc (dynobj,
+ bfinfdpic_gotfixup_section (info)->size);
+ if (bfinfdpic_gotfixup_section (info)->contents == NULL)
+ return FALSE;
+ }
+
+ if (elf_hash_table (info)->dynamic_sections_created)
+ bfinfdpic_pltrel_section (info)->size =
+ gpinfop->g.lzplt / LZPLT_NORMAL_SIZE * get_elf_backend_data (output_bfd)->s->sizeof_rel;
+ if (bfinfdpic_pltrel_section (info)->size == 0)
+ bfinfdpic_pltrel_section (info)->flags |= SEC_EXCLUDE;
+ else
+ {
+ bfinfdpic_pltrel_section (info)->contents =
+ (bfd_byte *) bfd_zalloc (dynobj,
+ bfinfdpic_pltrel_section (info)->size);
+ if (bfinfdpic_pltrel_section (info)->contents == NULL)
+ return FALSE;
+ }
+
+ /* Add 4 bytes for every block of at most 65535 lazy PLT entries,
+ such that there's room for the additional instruction needed to
+ call the resolver. Since _bfinfdpic_assign_got_entries didn't
+ account for them, our block size is 4 bytes smaller than the real
+ block size. */
+ if (elf_hash_table (info)->dynamic_sections_created)
+ {
+ bfinfdpic_plt_section (info)->size = gpinfop->g.lzplt
+ + ((gpinfop->g.lzplt + (BFINFDPIC_LZPLT_BLOCK_SIZE - 4) - LZPLT_NORMAL_SIZE)
+ / (BFINFDPIC_LZPLT_BLOCK_SIZE - 4) * LZPLT_RESOLVER_EXTRA);
+ }
+
+ /* Reset it, such that _bfinfdpic_assign_plt_entries() can use it to
+ actually assign lazy PLT entries addresses. */
+ gpinfop->g.lzplt = 0;
+
+ /* Save information that we're going to need to generate GOT and PLT
+ entries. */
+ bfinfdpic_got_initial_offset (info) = -gpinfop->gothilo.min;
+
+ if (get_elf_backend_data (output_bfd)->want_got_sym)
+ elf_hash_table (info)->hgot->root.u.def.value
+ = bfinfdpic_got_initial_offset (info);
+
+ if (elf_hash_table (info)->dynamic_sections_created)
+ bfinfdpic_plt_initial_offset (info) =
+ bfinfdpic_plt_section (info)->size;
+
+ htab_traverse (bfinfdpic_relocs_info (info), _bfinfdpic_assign_plt_entries,
+ gpinfop);
+
+ /* Allocate the PLT section contents only after
+ _bfinfdpic_assign_plt_entries has a chance to add the size of the
+ non-lazy PLT entries. */
+ if (bfinfdpic_plt_section (info)->size == 0)
+ bfinfdpic_plt_section (info)->flags |= SEC_EXCLUDE;
+ else
+ {
+ bfinfdpic_plt_section (info)->contents =
+ (bfd_byte *) bfd_zalloc (dynobj,
+ bfinfdpic_plt_section (info)->size);
+ if (bfinfdpic_plt_section (info)->contents == NULL)
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/* Set the sizes of the dynamic sections. */
+
+static bfd_boolean
+elf32_bfinfdpic_size_dynamic_sections (bfd *output_bfd,
+ struct bfd_link_info *info)
+{
+ struct elf_link_hash_table *htab;
+ bfd *dynobj;
+ asection *s;
+ struct _bfinfdpic_dynamic_got_plt_info gpinfo;
+
+ htab = elf_hash_table (info);
+ dynobj = htab->dynobj;
+ BFD_ASSERT (dynobj != NULL);
+
+ if (htab->dynamic_sections_created)
+ {
+ /* Set the contents of the .interp section to the interpreter. */
+ if (info->executable)
+ {
+ s = bfd_get_linker_section (dynobj, ".interp");
+ BFD_ASSERT (s != NULL);
+ s->size = sizeof ELF_DYNAMIC_INTERPRETER;
+ s->contents = (bfd_byte *) ELF_DYNAMIC_INTERPRETER;
+ }
+ }
+
+ memset (&gpinfo, 0, sizeof (gpinfo));
+ gpinfo.g.info = info;
+
+ for (;;)
+ {
+ htab_t relocs = bfinfdpic_relocs_info (info);
+
+ htab_traverse (relocs, _bfinfdpic_resolve_final_relocs_info, &relocs);
+
+ if (relocs == bfinfdpic_relocs_info (info))
+ break;
+ }
+
+ htab_traverse (bfinfdpic_relocs_info (info), _bfinfdpic_count_got_plt_entries,
+ &gpinfo.g);
+
+ /* Allocate space to save the summary information, we're going to
+ use it if we're doing relaxations. */
+ bfinfdpic_dynamic_got_plt_info (info) = bfd_alloc (dynobj, sizeof (gpinfo.g));
+
+ if (!_bfinfdpic_size_got_plt (output_bfd, &gpinfo))
+ return FALSE;
+
+ if (elf_hash_table (info)->dynamic_sections_created)
+ {
+ if (bfinfdpic_got_section (info)->size)
+ if (!_bfd_elf_add_dynamic_entry (info, DT_PLTGOT, 0))
+ return FALSE;
+
+ if (bfinfdpic_pltrel_section (info)->size)
+ if (!_bfd_elf_add_dynamic_entry (info, DT_PLTRELSZ, 0)
+ || !_bfd_elf_add_dynamic_entry (info, DT_PLTREL, DT_REL)
+ || !_bfd_elf_add_dynamic_entry (info, DT_JMPREL, 0))
+ return FALSE;
+
+ if (bfinfdpic_gotrel_section (info)->size)
+ if (!_bfd_elf_add_dynamic_entry (info, DT_REL, 0)
+ || !_bfd_elf_add_dynamic_entry (info, DT_RELSZ, 0)
+ || !_bfd_elf_add_dynamic_entry (info, DT_RELENT,
+ sizeof (Elf32_External_Rel)))
+ return FALSE;
+ }
+
+ s = bfd_get_linker_section (dynobj, ".dynbss");
+ if (s && s->size == 0)
+ s->flags |= SEC_EXCLUDE;
+
+ s = bfd_get_linker_section (dynobj, ".rela.bss");
+ if (s && s->size == 0)
+ s->flags |= SEC_EXCLUDE;
+
+ return TRUE;
+}
+
+static bfd_boolean
+elf32_bfinfdpic_always_size_sections (bfd *output_bfd,
+ struct bfd_link_info *info)
+{
+ if (!info->relocatable
+ && !bfd_elf_stack_segment_size (output_bfd, info,
+ "__stacksize", DEFAULT_STACK_SIZE))
+ return FALSE;
+
+ return TRUE;
+}
+
+/* Check whether any of the relocations was optimized away, and
+ subtract it from the relocation or fixup count. */
+static bfd_boolean
+_bfinfdpic_check_discarded_relocs (bfd *abfd, asection *sec,
+ struct bfd_link_info *info,
+ bfd_boolean *changed)
+{
+ Elf_Internal_Shdr *symtab_hdr;
+ struct elf_link_hash_entry **sym_hashes, **sym_hashes_end;
+ Elf_Internal_Rela *rel, *erel;
+
+ if ((sec->flags & SEC_RELOC) == 0
+ || sec->reloc_count == 0)
+ 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 = elf_section_data (sec)->relocs;
+
+ /* Now examine each relocation. */
+ for (erel = rel + sec->reloc_count; rel < erel; rel++)
+ {
+ struct elf_link_hash_entry *h;
+ unsigned long r_symndx;
+ struct bfinfdpic_relocs_info *picrel;
+ struct _bfinfdpic_dynamic_got_info *dinfo;
+
+ if (ELF32_R_TYPE (rel->r_info) != R_BFIN_BYTE4_DATA
+ && ELF32_R_TYPE (rel->r_info) != R_BFIN_FUNCDESC)
+ continue;
+
+ if (_bfd_elf_section_offset (sec->output_section->owner,
+ info, sec, rel->r_offset)
+ != (bfd_vma)-1)
+ continue;
+
+ 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];
+ 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 != NULL)
+ picrel = bfinfdpic_relocs_info_for_global (bfinfdpic_relocs_info (info),
+ abfd, h,
+ rel->r_addend, NO_INSERT);
+ else
+ picrel = bfinfdpic_relocs_info_for_local (bfinfdpic_relocs_info (info),
+ abfd, r_symndx,
+ rel->r_addend, NO_INSERT);
+
+ if (! picrel)
+ return FALSE;
+
+ *changed = TRUE;
+ dinfo = bfinfdpic_dynamic_got_plt_info (info);
+
+ _bfinfdpic_count_relocs_fixups (picrel, dinfo, TRUE);
+ if (ELF32_R_TYPE (rel->r_info) == R_BFIN_BYTE4_DATA)
+ picrel->relocs32--;
+ else /* we know (ELF32_R_TYPE (rel->r_info) == R_BFIN_FUNCDESC) */
+ picrel->relocsfd--;
+ _bfinfdpic_count_relocs_fixups (picrel, dinfo, FALSE);
+ }
+
+ return TRUE;
+}
+
+static bfd_boolean
+bfinfdpic_elf_discard_info (bfd *ibfd,
+ struct elf_reloc_cookie *cookie ATTRIBUTE_UNUSED,
+ struct bfd_link_info *info)
+{
+ bfd_boolean changed = FALSE;
+ asection *s;
+ bfd *obfd = NULL;
+
+ /* Account for relaxation of .eh_frame section. */
+ for (s = ibfd->sections; s; s = s->next)
+ if (s->sec_info_type == SEC_INFO_TYPE_EH_FRAME)
+ {
+ if (!_bfinfdpic_check_discarded_relocs (ibfd, s, info, &changed))
+ return FALSE;
+ obfd = s->output_section->owner;
+ }
+
+ if (changed)
+ {
+ struct _bfinfdpic_dynamic_got_plt_info gpinfo;
+
+ memset (&gpinfo, 0, sizeof (gpinfo));
+ memcpy (&gpinfo.g, bfinfdpic_dynamic_got_plt_info (info),
+ sizeof (gpinfo.g));
+
+ /* Clear GOT and PLT assignments. */
+ htab_traverse (bfinfdpic_relocs_info (info),
+ _bfinfdpic_reset_got_plt_entries,
+ NULL);
+
+ if (!_bfinfdpic_size_got_plt (obfd, &gpinfo))
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static bfd_boolean
+elf32_bfinfdpic_finish_dynamic_sections (bfd *output_bfd,
+ struct bfd_link_info *info)
+{
+ bfd *dynobj;
+ asection *sdyn;
+
+ dynobj = elf_hash_table (info)->dynobj;
+
+ if (bfinfdpic_got_section (info))
+ {
+ BFD_ASSERT (bfinfdpic_gotrel_section (info)->size
+ == (bfinfdpic_gotrel_section (info)->reloc_count
+ * sizeof (Elf32_External_Rel)));
+
+ if (bfinfdpic_gotfixup_section (info))
+ {
+ struct elf_link_hash_entry *hgot = elf_hash_table (info)->hgot;
+ bfd_vma got_value = hgot->root.u.def.value
+ + hgot->root.u.def.section->output_section->vma
+ + hgot->root.u.def.section->output_offset;
+
+ _bfinfdpic_add_rofixup (output_bfd, bfinfdpic_gotfixup_section (info),
+ got_value, 0);
+
+ if (bfinfdpic_gotfixup_section (info)->size
+ != (bfinfdpic_gotfixup_section (info)->reloc_count * 4))
+ {
+ (*_bfd_error_handler)
+ ("LINKER BUG: .rofixup section size mismatch");
+ return FALSE;
+ }
+ }
+ }
+ if (elf_hash_table (info)->dynamic_sections_created)
+ {
+ BFD_ASSERT (bfinfdpic_pltrel_section (info)->size
+ == (bfinfdpic_pltrel_section (info)->reloc_count
+ * sizeof (Elf32_External_Rel)));
+ }
+
+ sdyn = bfd_get_linker_section (dynobj, ".dynamic");
+
+ if (elf_hash_table (info)->dynamic_sections_created)
+ {
+ Elf32_External_Dyn * dyncon;
+ Elf32_External_Dyn * dynconend;
+
+ BFD_ASSERT (sdyn != NULL);
+
+ dyncon = (Elf32_External_Dyn *) sdyn->contents;
+ dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->size);
+
+ for (; dyncon < dynconend; dyncon++)
+ {
+ Elf_Internal_Dyn dyn;
+
+ bfd_elf32_swap_dyn_in (dynobj, dyncon, &dyn);
+
+ switch (dyn.d_tag)
+ {
+ default:
+ break;
+
+ case DT_PLTGOT:
+ dyn.d_un.d_ptr = bfinfdpic_got_section (info)->output_section->vma
+ + bfinfdpic_got_section (info)->output_offset
+ + bfinfdpic_got_initial_offset (info);
+ bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
+ break;
+
+ case DT_JMPREL:
+ dyn.d_un.d_ptr = bfinfdpic_pltrel_section (info)
+ ->output_section->vma
+ + bfinfdpic_pltrel_section (info)->output_offset;
+ bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
+ break;
+
+ case DT_PLTRELSZ:
+ dyn.d_un.d_val = bfinfdpic_pltrel_section (info)->size;
+ bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
+ break;
+ }
+ }
+ }
+
+ return TRUE;
+}
+
+/* Adjust a symbol defined by a dynamic object and referenced by a
+ regular object. */
+
+static bfd_boolean
+elf32_bfinfdpic_adjust_dynamic_symbol (struct bfd_link_info *info,
+ struct elf_link_hash_entry *h)
+{
+ bfd * dynobj;
+
+ dynobj = elf_hash_table (info)->dynobj;
+
+ /* Make sure we know what is going on here. */
+ BFD_ASSERT (dynobj != NULL
+ && (h->u.weakdef != NULL
+ || (h->def_dynamic
+ && h->ref_regular
+ && !h->def_regular)));
+
+ /* 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->u.weakdef != NULL)
+ {
+ BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
+ || h->u.weakdef->root.type == bfd_link_hash_defweak);
+ h->root.u.def.section = h->u.weakdef->root.u.def.section;
+ h->root.u.def.value = h->u.weakdef->root.u.def.value;
+ }
+
+ return TRUE;
+}
+
+/* Perform any actions needed for dynamic symbols. */
+
+static bfd_boolean
+elf32_bfinfdpic_finish_dynamic_symbol
+(bfd *output_bfd ATTRIBUTE_UNUSED,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ struct elf_link_hash_entry *h ATTRIBUTE_UNUSED,
+ Elf_Internal_Sym *sym ATTRIBUTE_UNUSED)
+{
+ return TRUE;
+}
+
+/* Decide whether to attempt to turn absptr or lsda encodings in
+ shared libraries into pcrel within the given input section. */
+
+static bfd_boolean
+bfinfdpic_elf_use_relative_eh_frame
+(bfd *input_bfd ATTRIBUTE_UNUSED,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ asection *eh_frame_section ATTRIBUTE_UNUSED)
+{
+ /* We can't use PC-relative encodings in FDPIC binaries, in general. */
+ return FALSE;
+}
+
+/* Adjust the contents of an eh_frame_hdr section before they're output. */
+
+static bfd_byte
+bfinfdpic_elf_encode_eh_address (bfd *abfd,
+ struct bfd_link_info *info,
+ asection *osec, bfd_vma offset,
+ asection *loc_sec, bfd_vma loc_offset,
+ bfd_vma *encoded)
+{
+ struct elf_link_hash_entry *h;
+
+ h = elf_hash_table (info)->hgot;
+ BFD_ASSERT (h && h->root.type == bfd_link_hash_defined);
+
+ if (! h || (_bfinfdpic_osec_to_segment (abfd, osec)
+ == _bfinfdpic_osec_to_segment (abfd, loc_sec->output_section)))
+ return _bfd_elf_encode_eh_address (abfd, info, osec, offset,
+ loc_sec, loc_offset, encoded);
+
+ BFD_ASSERT (_bfinfdpic_osec_to_segment (abfd, osec)
+ == (_bfinfdpic_osec_to_segment
+ (abfd, h->root.u.def.section->output_section)));
+
+ *encoded = osec->vma + offset
+ - (h->root.u.def.value
+ + h->root.u.def.section->output_section->vma
+ + h->root.u.def.section->output_offset);
+
+ return DW_EH_PE_datarel | DW_EH_PE_sdata4;
+}
+
+
+
+/* Look through the relocs for a section during the first phase.
+
+ Besides handling virtual table relocs for gc, we have to deal with
+ all sorts of PIC-related relocations. We describe below the
+ general plan on how to handle such relocations, even though we only
+ collect information at this point, storing them in hash tables for
+ perusal of later passes.
+
+ 32 relocations are propagated to the linker output when creating
+ position-independent output. LO16 and HI16 relocations are not
+ supposed to be encountered in this case.
+
+ LABEL16 should always be resolvable by the linker, since it's only
+ used by branches.
+
+ LABEL24, on the other hand, is used by calls. If it turns out that
+ the target of a call is a dynamic symbol, a PLT entry must be
+ created for it, which triggers the creation of a private function
+ descriptor and, unless lazy binding is disabled, a lazy PLT entry.
+
+ GPREL relocations require the referenced symbol to be in the same
+ segment as _gp, but this can only be checked later.
+
+ All GOT, GOTOFF and FUNCDESC relocations require a .got section to
+ exist. LABEL24 might as well, since it may require a PLT entry,
+ that will require a got.
+
+ Non-FUNCDESC GOT relocations require a GOT entry to be created
+ regardless of whether the symbol is dynamic. However, since a
+ global symbol that turns out to not be exported may have the same
+ address of a non-dynamic symbol, we don't assign GOT entries at
+ this point, such that we can share them in this case. A relocation
+ for the GOT entry always has to be created, be it to offset a
+ private symbol by the section load address, be it to get the symbol
+ resolved dynamically.
+
+ FUNCDESC GOT relocations require a GOT entry to be created, and
+ handled as if a FUNCDESC relocation was applied to the GOT entry in
+ an object file.
+
+ FUNCDESC relocations referencing a symbol that turns out to NOT be
+ dynamic cause a private function descriptor to be created. The
+ FUNCDESC relocation then decays to a 32 relocation that points at
+ the private descriptor. If the symbol is dynamic, the FUNCDESC
+ relocation is propagated to the linker output, such that the
+ dynamic linker creates the canonical descriptor, pointing to the
+ dynamically-resolved definition of the function.
+
+ Non-FUNCDESC GOTOFF relocations must always refer to non-dynamic
+ symbols that are assigned to the same segment as the GOT, but we
+ can only check this later, after we know the complete set of
+ symbols defined and/or exported.
+
+ FUNCDESC GOTOFF relocations require a function descriptor to be
+ created and, unless lazy binding is disabled or the symbol is not
+ dynamic, a lazy PLT entry. Since we can't tell at this point
+ whether a symbol is going to be dynamic, we have to decide later
+ whether to create a lazy PLT entry or bind the descriptor directly
+ to the private function.
+
+ FUNCDESC_VALUE relocations are not supposed to be present in object
+ files, but they may very well be simply propagated to the linker
+ output, since they have no side effect.
+
+
+ A function descriptor always requires a FUNCDESC_VALUE relocation.
+ Whether it's in .plt.rel or not depends on whether lazy binding is
+ enabled and on whether the referenced symbol is dynamic.
+
+ The existence of a lazy PLT requires the resolverStub lazy PLT
+ entry to be present.
+
+
+ As for assignment of GOT, PLT and lazy PLT entries, and private
+ descriptors, we might do them all sequentially, but we can do
+ better than that. For example, we can place GOT entries and
+ private function descriptors referenced using 12-bit operands
+ closer to the PIC register value, such that these relocations don't
+ overflow. Those that are only referenced with LO16 relocations
+ could come next, but we may as well place PLT-required function
+ descriptors in the 12-bit range to make them shorter. Symbols
+ referenced with LO16/HI16 may come next, but we may place
+ additional function descriptors in the 16-bit range if we can
+ reliably tell that we've already placed entries that are ever
+ referenced with only LO16. PLT entries are therefore generated as
+ small as possible, while not introducing relocation overflows in
+ GOT or FUNCDESC_GOTOFF relocations. Lazy PLT entries could be
+ generated before or after PLT entries, but not intermingled with
+ them, such that we can have more lazy PLT entries in range for a
+ branch to the resolverStub. The resolverStub should be emitted at
+ the most distant location from the first lazy PLT entry such that
+ it's still in range for a branch, or closer, if there isn't a need
+ for so many lazy PLT entries. Additional lazy PLT entries may be
+ emitted after the resolverStub, as long as branches are still in
+ range. If the branch goes out of range, longer lazy PLT entries
+ are emitted.
+
+ We could further optimize PLT and lazy PLT entries by giving them
+ priority in assignment to closer-to-gr17 locations depending on the
+ number of occurrences of references to them (assuming a function
+ that's called more often is more important for performance, so its
+ PLT entry should be faster), or taking hints from the compiler.
+ Given infinite time and money... :-) */
+
+static bfd_boolean
+bfinfdpic_check_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;
+ const Elf_Internal_Rela *rel;
+ const Elf_Internal_Rela *rel_end;
+ bfd *dynobj;
+ struct bfinfdpic_relocs_info *picrel;
+
+ if (info->relocatable)
+ return TRUE;
+
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+ sym_hashes = elf_sym_hashes (abfd);
+
+ dynobj = elf_hash_table (info)->dynobj;
+ 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))
+ {
+ case R_BFIN_GOT17M4:
+ case R_BFIN_GOTHI:
+ case R_BFIN_GOTLO:
+ case R_BFIN_FUNCDESC_GOT17M4:
+ case R_BFIN_FUNCDESC_GOTHI:
+ case R_BFIN_FUNCDESC_GOTLO:
+ case R_BFIN_GOTOFF17M4:
+ case R_BFIN_GOTOFFHI:
+ case R_BFIN_GOTOFFLO:
+ case R_BFIN_FUNCDESC_GOTOFF17M4:
+ case R_BFIN_FUNCDESC_GOTOFFHI:
+ case R_BFIN_FUNCDESC_GOTOFFLO:
+ case R_BFIN_FUNCDESC:
+ case R_BFIN_FUNCDESC_VALUE:
+ if (! IS_FDPIC (abfd))
+ goto bad_reloc;
+ /* Fall through. */
+ case R_BFIN_PCREL24:
+ case R_BFIN_PCREL24_JUMP_L:
+ case R_BFIN_BYTE4_DATA:
+ if (IS_FDPIC (abfd) && ! dynobj)
+ {
+ elf_hash_table (info)->dynobj = dynobj = abfd;
+ if (! _bfin_create_got_section (abfd, info))
+ return FALSE;
+ }
+ if (! IS_FDPIC (abfd))
+ {
+ picrel = NULL;
+ break;
+ }
+ if (h != NULL)
+ {
+ if (h->dynindx == -1)
+ switch (ELF_ST_VISIBILITY (h->other))
+ {
+ case STV_INTERNAL:
+ case STV_HIDDEN:
+ break;
+ default:
+ bfd_elf_link_record_dynamic_symbol (info, h);
+ break;
+ }
+ picrel
+ = bfinfdpic_relocs_info_for_global (bfinfdpic_relocs_info (info),
+ abfd, h,
+ rel->r_addend, INSERT);
+ }
+ else
+ picrel = bfinfdpic_relocs_info_for_local (bfinfdpic_relocs_info
+ (info), abfd, r_symndx,
+ rel->r_addend, INSERT);
+ if (! picrel)
+ return FALSE;
+ break;
+
+ default:
+ picrel = NULL;
+ break;
+ }
+
+ switch (ELF32_R_TYPE (rel->r_info))
+ {
+ case R_BFIN_PCREL24:
+ case R_BFIN_PCREL24_JUMP_L:
+ if (IS_FDPIC (abfd))
+ picrel->call++;
+ break;
+
+ case R_BFIN_FUNCDESC_VALUE:
+ picrel->relocsfdv++;
+ if (bfd_get_section_flags (abfd, sec) & SEC_ALLOC)
+ picrel->relocs32--;
+ /* Fall through. */
+
+ case R_BFIN_BYTE4_DATA:
+ if (! IS_FDPIC (abfd))
+ break;
+
+ picrel->sym++;
+ if (bfd_get_section_flags (abfd, sec) & SEC_ALLOC)
+ picrel->relocs32++;
+ break;
+
+ case R_BFIN_GOT17M4:
+ picrel->got17m4++;
+ break;
+
+ case R_BFIN_GOTHI:
+ case R_BFIN_GOTLO:
+ picrel->gothilo++;
+ break;
+
+ case R_BFIN_FUNCDESC_GOT17M4:
+ picrel->fdgot17m4++;
+ break;
+
+ case R_BFIN_FUNCDESC_GOTHI:
+ case R_BFIN_FUNCDESC_GOTLO:
+ picrel->fdgothilo++;
+ break;
+
+ case R_BFIN_GOTOFF17M4:
+ case R_BFIN_GOTOFFHI:
+ case R_BFIN_GOTOFFLO:
+ picrel->gotoff++;
+ break;
+
+ case R_BFIN_FUNCDESC_GOTOFF17M4:
+ picrel->fdgoff17m4++;
+ break;
+
+ case R_BFIN_FUNCDESC_GOTOFFHI:
+ case R_BFIN_FUNCDESC_GOTOFFLO:
+ picrel->fdgoffhilo++;
+ break;
+
+ case R_BFIN_FUNCDESC:
+ picrel->fd++;
+ picrel->relocsfd++;
+ break;
+
+ /* This relocation describes the C++ object vtable hierarchy.
+ Reconstruct it for later use during GC. */
+ case R_BFIN_GNU_VTINHERIT:
+ if (!bfd_elf_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_BFIN_GNU_VTENTRY:
+ BFD_ASSERT (h != NULL);
+ if (h != NULL
+ && !bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
+ return FALSE;
+ break;
+
+ case R_BFIN_HUIMM16:
+ case R_BFIN_LUIMM16:
+ case R_BFIN_PCREL12_JUMP_S:
+ case R_BFIN_PCREL10:
+ break;
+
+ default:
+ bad_reloc:
+ (*_bfd_error_handler)
+ (_("%B: unsupported relocation type %i"),
+ abfd, ELF32_R_TYPE (rel->r_info));
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+/* Set the right machine number for a Blackfin ELF file. */
+
+static bfd_boolean
+elf32_bfin_object_p (bfd *abfd)
+{
+ bfd_default_set_arch_mach (abfd, bfd_arch_bfin, 0);
+ return (((elf_elfheader (abfd)->e_flags & EF_BFIN_FDPIC) != 0)
+ == (IS_FDPIC (abfd)));
+}
+
+static bfd_boolean
+elf32_bfin_set_private_flags (bfd * abfd, flagword flags)
+{
+ elf_elfheader (abfd)->e_flags = flags;
+ elf_flags_init (abfd) = TRUE;
+ return TRUE;
+}
+
+/* Display the flags field. */
+static bfd_boolean
+elf32_bfin_print_private_bfd_data (bfd * abfd, void * ptr)
+{
+ FILE *file = (FILE *) ptr;
+ flagword flags;
+
+ BFD_ASSERT (abfd != NULL && ptr != NULL);
+
+ /* Print normal ELF private data. */
+ _bfd_elf_print_private_bfd_data (abfd, ptr);
+
+ flags = elf_elfheader (abfd)->e_flags;
+
+ /* xgettext:c-format */
+ fprintf (file, _("private flags = %lx:"), elf_elfheader (abfd)->e_flags);
+
+ if (flags & EF_BFIN_PIC)
+ fprintf (file, " -fpic");
+
+ if (flags & EF_BFIN_FDPIC)
+ fprintf (file, " -mfdpic");
+
+ fputc ('\n', file);
+
+ return TRUE;
+}
+
+/* Merge backend specific data from an object file to the output
+ object file when linking. */
+
+static bfd_boolean
+elf32_bfin_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
+{
+ flagword old_flags, new_flags;
+ bfd_boolean error = FALSE;
+
+ new_flags = elf_elfheader (ibfd)->e_flags;
+ old_flags = elf_elfheader (obfd)->e_flags;
+
+ if (new_flags & EF_BFIN_FDPIC)
+ new_flags &= ~EF_BFIN_PIC;
+
+#ifndef DEBUG
+ if (0)
+#endif
+ (*_bfd_error_handler) ("old_flags = 0x%.8lx, new_flags = 0x%.8lx, init = %s, filename = %s",
+ old_flags, new_flags, elf_flags_init (obfd) ? "yes" : "no",
+ bfd_get_filename (ibfd));
+
+ if (!elf_flags_init (obfd)) /* First call, no flags set. */
+ {
+ elf_flags_init (obfd) = TRUE;
+ elf_elfheader (obfd)->e_flags = new_flags;
+ }
+
+ if (((new_flags & EF_BFIN_FDPIC) == 0) != (! IS_FDPIC (obfd)))
+ {
+ error = TRUE;
+ if (IS_FDPIC (obfd))
+ (*_bfd_error_handler)
+ (_("%s: cannot link non-fdpic object file into fdpic executable"),
+ bfd_get_filename (ibfd));
+ else
+ (*_bfd_error_handler)
+ (_("%s: cannot link fdpic object file into non-fdpic executable"),
+ bfd_get_filename (ibfd));
+ }
+
+ if (error)
+ bfd_set_error (bfd_error_bad_value);
+
+ return !error;
+}
+
+/* bfin ELF linker hash entry. */
+
+struct bfin_link_hash_entry
+{
+ struct elf_link_hash_entry root;
+
+ /* Number of PC relative relocs copied for this symbol. */
+ struct bfin_pcrel_relocs_copied *pcrel_relocs_copied;
+};
+
+/* bfin ELF linker hash table. */
+
+struct bfin_link_hash_table
+{
+ struct elf_link_hash_table root;
+
+ /* Small local sym cache. */
+ struct sym_cache sym_cache;
+};
+
+#define bfin_hash_entry(ent) ((struct bfin_link_hash_entry *) (ent))
+
+static struct bfd_hash_entry *
+bfin_link_hash_newfunc (struct bfd_hash_entry *entry,
+ struct bfd_hash_table *table, const char *string)
+{
+ struct bfd_hash_entry *ret = entry;
+
+ /* Allocate the structure if it has not already been allocated by a
+ subclass. */
+ if (ret == NULL)
+ ret = bfd_hash_allocate (table, sizeof (struct bfin_link_hash_entry));
+ if (ret == NULL)
+ return ret;
+
+ /* Call the allocation method of the superclass. */
+ ret = _bfd_elf_link_hash_newfunc (ret, table, string);
+ if (ret != NULL)
+ bfin_hash_entry (ret)->pcrel_relocs_copied = NULL;
+
+ return ret;
+}
+
+/* Create an bfin ELF linker hash table. */
+
+static struct bfd_link_hash_table *
+bfin_link_hash_table_create (bfd * abfd)
+{
+ struct bfin_link_hash_table *ret;
+ bfd_size_type amt = sizeof (struct bfin_link_hash_table);
+
+ ret = bfd_zmalloc (amt);
+ if (ret == NULL)
+ return NULL;
+
+ if (!_bfd_elf_link_hash_table_init (&ret->root, abfd,
+ bfin_link_hash_newfunc,
+ sizeof (struct elf_link_hash_entry),
+ BFIN_ELF_DATA))
+ {
+ free (ret);
+ return NULL;
+ }
+
+ ret->sym_cache.abfd = NULL;
+
+ return &ret->root.root;
+}
+
+/* The size in bytes of an entry in the procedure linkage table. */
+
+/* Finish up the dynamic sections. */
+
+static bfd_boolean
+bfin_finish_dynamic_sections (bfd * output_bfd ATTRIBUTE_UNUSED,
+ struct bfd_link_info *info)
+{
+ bfd *dynobj;
+ asection *sdyn;
+
+ dynobj = elf_hash_table (info)->dynobj;
+
+ sdyn = bfd_get_linker_section (dynobj, ".dynamic");
+
+ if (elf_hash_table (info)->dynamic_sections_created)
+ {
+ Elf32_External_Dyn *dyncon, *dynconend;
+
+ BFD_ASSERT (sdyn != NULL);
+
+ dyncon = (Elf32_External_Dyn *) sdyn->contents;
+ dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->size);
+ for (; dyncon < dynconend; dyncon++)
+ {
+ Elf_Internal_Dyn dyn;
+
+ bfd_elf32_swap_dyn_in (dynobj, dyncon, &dyn);
+
+ }
+
+ }
+ return TRUE;
+}
+
+/* Finish up dynamic symbol handling. We set the contents of various
+ dynamic sections here. */
+
+static bfd_boolean
+bfin_finish_dynamic_symbol (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->got.offset != (bfd_vma) - 1)
+ {
+ asection *sgot;
+ asection *srela;
+ Elf_Internal_Rela rela;
+ bfd_byte *loc;
+
+ /* This symbol has an entry in the global offset table.
+ Set it up. */
+
+ sgot = bfd_get_linker_section (dynobj, ".got");
+ srela = bfd_get_linker_section (dynobj, ".rela.got");
+ BFD_ASSERT (sgot != NULL && srela != NULL);
+
+ rela.r_offset = (sgot->output_section->vma
+ + sgot->output_offset
+ + (h->got.offset & ~(bfd_vma) 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->forced_local) && h->def_regular)
+ {
+ (*_bfd_error_handler) (_("*** check this relocation %s"),
+ __FUNCTION__);
+ rela.r_info = ELF32_R_INFO (0, R_BFIN_PCREL24);
+ rela.r_addend = bfd_get_signed_32 (output_bfd,
+ (sgot->contents
+ +
+ (h->got.
+ offset & ~(bfd_vma) 1)));
+ }
+ else
+ {
+ bfd_put_32 (output_bfd, (bfd_vma) 0,
+ sgot->contents + (h->got.offset & ~(bfd_vma) 1));
+ rela.r_info = ELF32_R_INFO (h->dynindx, R_BFIN_GOT);
+ rela.r_addend = 0;
+ }
+
+ loc = srela->contents;
+ loc += srela->reloc_count++ * sizeof (Elf32_External_Rela);
+ bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
+ }
+
+ if (h->needs_copy)
+ {
+ BFD_ASSERT (0);
+ }
+ /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute. */
+ if (strcmp (h->root.root.string, "__DYNAMIC") == 0
+ || h == elf_hash_table (info)->hgot)
+ sym->st_shndx = SHN_ABS;
+
+ 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 bfd_boolean
+bfin_adjust_dynamic_symbol (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->needs_plt
+ || h->u.weakdef != NULL
+ || (h->def_dynamic && h->ref_regular && !h->def_regular)));
+
+ /* 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->needs_plt)
+ {
+ BFD_ASSERT(0);
+ }
+
+ /* 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->u.weakdef != NULL)
+ {
+ BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
+ || h->u.weakdef->root.type == bfd_link_hash_defweak);
+ h->root.u.def.section = h->u.weakdef->root.u.def.section;
+ h->root.u.def.value = h->u.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_linker_section (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_linker_section (dynobj, ".rela.bss");
+ BFD_ASSERT (srel != NULL);
+ srel->size += sizeof (Elf32_External_Rela);
+ h->needs_copy = 1;
+ }
+
+ /* 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->size = BFD_ALIGN (s->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->size;
+
+ /* Increment the section size to make room for the symbol. */
+ s->size += h->size;
+
+ return TRUE;
+}
+
+/* The bfin 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 bfin_pcrel_relocs_copied
+{
+ /* Next section. */
+ struct bfin_pcrel_relocs_copied *next;
+ /* A section in dynobj. */
+ asection *section;
+ /* Number of relocs copied in this section. */
+ bfd_size_type count;
+};
+
+/* This function is called via elf_link_hash_traverse if we are
+ creating a shared object. In the -Bsymbolic case it discards the
+ space allocated to copy PC relative relocs against symbols which
+ are defined in regular objects. For the normal shared case, it
+ discards space for pc-relative relocs that have become local due to
+ symbol visibility changes. We allocated space for them in the
+ check_relocs routine, but we won't fill them in in the
+ relocate_section routine.
+
+ We also check whether any of the remaining relocations apply
+ against a readonly section, and set the DF_TEXTREL flag in this
+ case. */
+
+static bfd_boolean
+bfin_discard_copies (struct elf_link_hash_entry *h, void * inf)
+{
+ struct bfd_link_info *info = (struct bfd_link_info *) inf;
+ struct bfin_pcrel_relocs_copied *s;
+
+ if (!h->def_regular || (!info->symbolic && !h->forced_local))
+ {
+ if ((info->flags & DF_TEXTREL) == 0)
+ {
+ /* Look for relocations against read-only sections. */
+ for (s = bfin_hash_entry (h)->pcrel_relocs_copied;
+ s != NULL; s = s->next)
+ if ((s->section->flags & SEC_READONLY) != 0)
+ {
+ info->flags |= DF_TEXTREL;
+ break;
+ }
+ }
+
+ return TRUE;
+ }
+
+ for (s = bfin_hash_entry (h)->pcrel_relocs_copied;
+ s != NULL; s = s->next)
+ s->section->size -= s->count * sizeof (Elf32_External_Rela);
+
+ return TRUE;
+}
+
+static bfd_boolean
+bfin_size_dynamic_sections (bfd * output_bfd ATTRIBUTE_UNUSED,
+ struct bfd_link_info *info)
+{
+ bfd *dynobj;
+ asection *s;
+ bfd_boolean relocs;
+
+ 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->executable)
+ {
+ s = bfd_get_linker_section (dynobj, ".interp");
+ BFD_ASSERT (s != NULL);
+ s->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_linker_section (dynobj, ".rela.got");
+ if (s != NULL)
+ s->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.
+ For the normal shared case we discard the PC relative relocs
+ against symbols that have become local due to visibility changes.
+ 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)
+ elf_link_hash_traverse (elf_hash_table (info),
+ bfin_discard_copies, info);
+
+ /* The check_relocs and adjust_dynamic_symbol entry points have
+ determined the sizes of the various dynamic sections. Allocate
+ memory for them. */
+ relocs = FALSE;
+ for (s = dynobj->sections; s != NULL; s = s->next)
+ {
+ const char *name;
+ bfd_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 (CONST_STRNEQ (name, ".rela"))
+ {
+ if (s->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
+ {
+ relocs = 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 (! CONST_STRNEQ (name, ".got"))
+ {
+ /* It's not one of our sections, so don't allocate space. */
+ continue;
+ }
+
+ if (strip)
+ {
+ s->flags |= SEC_EXCLUDE;
+ continue;
+ }
+
+ /* Allocate memory for the section contents. */
+ /* FIXME: This should be a call to bfd_alloc not bfd_zalloc.
+ Unused entries should be reclaimed before the section's contents
+ are written out, but at the moment this does not happen. Thus in
+ order to prevent writing out garbage, we initialise the section's
+ contents to zero. */
+ s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->size);
+ if (s->contents == NULL && s->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 bfin_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. */
+#define add_dynamic_entry(TAG, VAL) \
+ _bfd_elf_add_dynamic_entry (info, TAG, VAL)
+
+ if (!info->shared)
+ {
+ if (!add_dynamic_entry (DT_DEBUG, 0))
+ return FALSE;
+ }
+
+
+ if (relocs)
+ {
+ if (!add_dynamic_entry (DT_RELA, 0)
+ || !add_dynamic_entry (DT_RELASZ, 0)
+ || !add_dynamic_entry (DT_RELAENT,
+ sizeof (Elf32_External_Rela)))
+ return FALSE;
+ }
+
+ if ((info->flags & DF_TEXTREL) != 0)
+ {
+ if (!add_dynamic_entry (DT_TEXTREL, 0))
+ return FALSE;
+ }
+ }
+#undef add_dynamic_entry
+
+ return TRUE;
+}
+
+/* Given a .data section and a .emreloc in-memory section, store
+ relocation information into the .emreloc 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. */
+
+bfd_boolean
+bfd_bfin_elf32_create_embedded_relocs (bfd *abfd,
+ struct bfd_link_info *info,
+ asection *datasec,
+ asection *relsec,
+ char **errmsg)
+{
+ Elf_Internal_Shdr *symtab_hdr;
+ Elf_Internal_Sym *isymbuf = NULL;
+ Elf_Internal_Rela *internal_relocs = NULL;
+ Elf_Internal_Rela *irel, *irelend;
+ bfd_byte *p;
+ bfd_size_type amt;
+
+ BFD_ASSERT (! info->relocatable);
+
+ *errmsg = NULL;
+
+ if (datasec->reloc_count == 0)
+ return TRUE;
+
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+
+ /* Get a copy of the native relocations. */
+ internal_relocs = (_bfd_elf_link_read_relocs
+ (abfd, datasec, NULL, (Elf_Internal_Rela *) NULL,
+ info->keep_memory));
+ if (internal_relocs == NULL)
+ goto error_return;
+
+ amt = (bfd_size_type) datasec->reloc_count * 12;
+ relsec->contents = (bfd_byte *) bfd_alloc (abfd, amt);
+ if (relsec->contents == NULL)
+ goto error_return;
+
+ p = relsec->contents;
+
+ irelend = internal_relocs + datasec->reloc_count;
+ for (irel = internal_relocs; irel < irelend; irel++, p += 12)
+ {
+ asection *targetsec;
+
+ /* We are going to write a four byte longword into the runtime
+ reloc section. The longword will be the address in the data
+ section which must be relocated. It is followed by the name
+ of the target section NUL-padded or truncated to 8
+ characters. */
+
+ /* We can only relocate absolute longword relocs at run time. */
+ if (ELF32_R_TYPE (irel->r_info) != (int) R_BFIN_BYTE4_DATA)
+ {
+ *errmsg = _("unsupported reloc type");
+ bfd_set_error (bfd_error_bad_value);
+ goto error_return;
+ }
+
+ /* Get the target section referred to by the reloc. */
+ if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
+ {
+ /* A local symbol. */
+ Elf_Internal_Sym *isym;
+
+ /* Read this BFD's local symbols if we haven't done so already. */
+ if (isymbuf == NULL)
+ {
+ isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
+ if (isymbuf == NULL)
+ isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
+ symtab_hdr->sh_info, 0,
+ NULL, NULL, NULL);
+ if (isymbuf == NULL)
+ goto error_return;
+ }
+
+ isym = isymbuf + ELF32_R_SYM (irel->r_info);
+ targetsec = bfd_section_from_elf_index (abfd, isym->st_shndx);
+ }
+ 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)
+ targetsec = h->root.u.def.section;
+ else
+ targetsec = NULL;
+ }
+
+ bfd_put_32 (abfd, irel->r_offset + datasec->output_offset, p);
+ memset (p + 4, 0, 8);
+ if (targetsec != NULL)
+ strncpy ((char *) p + 4, targetsec->output_section->name, 8);
+ }
+
+ if (isymbuf != NULL && symtab_hdr->contents != (unsigned char *) isymbuf)
+ free (isymbuf);
+ if (internal_relocs != NULL
+ && elf_section_data (datasec)->relocs != internal_relocs)
+ free (internal_relocs);
+ return TRUE;
+
+error_return:
+ if (isymbuf != NULL && symtab_hdr->contents != (unsigned char *) isymbuf)
+ free (isymbuf);
+ if (internal_relocs != NULL
+ && elf_section_data (datasec)->relocs != internal_relocs)
+ free (internal_relocs);
+ return FALSE;
+}
+
+struct bfd_elf_special_section const elf32_bfin_special_sections[] =
+{
+ { ".l1.text", 8, -2, SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR },
+ { ".l1.data", 8, -2, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE },
+ { NULL, 0, 0, 0, 0 }
+};
+
+
+#define TARGET_LITTLE_SYM bfin_elf32_vec
+#define TARGET_LITTLE_NAME "elf32-bfin"
+#define ELF_ARCH bfd_arch_bfin
+#define ELF_TARGET_ID BFIN_ELF_DATA
+#define ELF_MACHINE_CODE EM_BLACKFIN
+#define ELF_MAXPAGESIZE 0x1000
+#define elf_symbol_leading_char '_'
+
+#define bfd_elf32_bfd_reloc_type_lookup bfin_bfd_reloc_type_lookup
+#define bfd_elf32_bfd_reloc_name_lookup \
+ bfin_bfd_reloc_name_lookup
+#define elf_info_to_howto bfin_info_to_howto
+#define elf_info_to_howto_rel 0
+#define elf_backend_object_p elf32_bfin_object_p
+
+#define bfd_elf32_bfd_is_local_label_name \
+ bfin_is_local_label_name
+#define bfin_hash_table(p) \
+ ((struct bfin_link_hash_table *) (p)->hash)
+
+
+
+#define elf_backend_create_dynamic_sections \
+ _bfd_elf_create_dynamic_sections
+#define bfd_elf32_bfd_link_hash_table_create \
+ bfin_link_hash_table_create
+#define bfd_elf32_bfd_final_link bfd_elf_gc_common_final_link
+
+#define elf_backend_check_relocs bfin_check_relocs
+#define elf_backend_adjust_dynamic_symbol \
+ bfin_adjust_dynamic_symbol
+#define elf_backend_size_dynamic_sections \
+ bfin_size_dynamic_sections
+#define elf_backend_relocate_section bfin_relocate_section
+#define elf_backend_finish_dynamic_symbol \
+ bfin_finish_dynamic_symbol
+#define elf_backend_finish_dynamic_sections \
+ bfin_finish_dynamic_sections
+#define elf_backend_gc_mark_hook bfin_gc_mark_hook
+#define elf_backend_gc_sweep_hook bfin_gc_sweep_hook
+#define bfd_elf32_bfd_merge_private_bfd_data \
+ elf32_bfin_merge_private_bfd_data
+#define bfd_elf32_bfd_set_private_flags \
+ elf32_bfin_set_private_flags
+#define bfd_elf32_bfd_print_private_bfd_data \
+ elf32_bfin_print_private_bfd_data
+#define elf_backend_final_write_processing \
+ elf32_bfin_final_write_processing
+#define elf_backend_reloc_type_class elf32_bfin_reloc_type_class
+#define elf_backend_stack_align 8
+#define elf_backend_can_gc_sections 1
+#define elf_backend_special_sections elf32_bfin_special_sections
+#define elf_backend_can_refcount 1
+#define elf_backend_want_got_plt 0
+#define elf_backend_plt_readonly 1
+#define elf_backend_want_plt_sym 0
+#define elf_backend_got_header_size 12
+#define elf_backend_rela_normal 1
+
+#include "elf32-target.h"
+
+#undef TARGET_LITTLE_SYM
+#define TARGET_LITTLE_SYM bfin_elf32_fdpic_vec
+#undef TARGET_LITTLE_NAME
+#define TARGET_LITTLE_NAME "elf32-bfinfdpic"
+#undef elf32_bed
+#define elf32_bed elf32_bfinfdpic_bed
+
+#undef elf_backend_gc_sweep_hook
+#define elf_backend_gc_sweep_hook bfinfdpic_gc_sweep_hook
+
+#undef elf_backend_got_header_size
+#define elf_backend_got_header_size 0
+
+#undef elf_backend_relocate_section
+#define elf_backend_relocate_section bfinfdpic_relocate_section
+#undef elf_backend_check_relocs
+#define elf_backend_check_relocs bfinfdpic_check_relocs
+
+#undef bfd_elf32_bfd_link_hash_table_create
+#define bfd_elf32_bfd_link_hash_table_create \
+ bfinfdpic_elf_link_hash_table_create
+#undef elf_backend_always_size_sections
+#define elf_backend_always_size_sections \
+ elf32_bfinfdpic_always_size_sections
+
+#undef elf_backend_create_dynamic_sections
+#define elf_backend_create_dynamic_sections \
+ elf32_bfinfdpic_create_dynamic_sections
+#undef elf_backend_adjust_dynamic_symbol
+#define elf_backend_adjust_dynamic_symbol \
+ elf32_bfinfdpic_adjust_dynamic_symbol
+#undef elf_backend_size_dynamic_sections
+#define elf_backend_size_dynamic_sections \
+ elf32_bfinfdpic_size_dynamic_sections
+#undef elf_backend_finish_dynamic_symbol
+#define elf_backend_finish_dynamic_symbol \
+ elf32_bfinfdpic_finish_dynamic_symbol
+#undef elf_backend_finish_dynamic_sections
+#define elf_backend_finish_dynamic_sections \
+ elf32_bfinfdpic_finish_dynamic_sections
+
+#undef elf_backend_discard_info
+#define elf_backend_discard_info \
+ bfinfdpic_elf_discard_info
+#undef elf_backend_can_make_relative_eh_frame
+#define elf_backend_can_make_relative_eh_frame \
+ bfinfdpic_elf_use_relative_eh_frame
+#undef elf_backend_can_make_lsda_relative_eh_frame
+#define elf_backend_can_make_lsda_relative_eh_frame \
+ bfinfdpic_elf_use_relative_eh_frame
+#undef elf_backend_encode_eh_address
+#define elf_backend_encode_eh_address \
+ bfinfdpic_elf_encode_eh_address
+
+#undef elf_backend_may_use_rel_p
+#define elf_backend_may_use_rel_p 1
+#undef elf_backend_may_use_rela_p
+#define elf_backend_may_use_rela_p 1
+/* We use REL for dynamic relocations only. */
+#undef elf_backend_default_use_rela_p
+#define elf_backend_default_use_rela_p 1
+
+#undef elf_backend_omit_section_dynsym
+#define elf_backend_omit_section_dynsym _bfinfdpic_link_omit_section_dynsym
+
+#include "elf32-target.h"
diff --git a/bfd/elf32-cr16.c b/bfd/elf32-cr16.c
new file mode 100644
index 0000000..f16f1c6
--- /dev/null
+++ b/bfd/elf32-cr16.c
@@ -0,0 +1,2992 @@
+/* BFD back-end for National Semiconductor's CR16 ELF
+ Copyright (C) 2007-2014 Free Software Foundation, Inc.
+ Written by M R Swami Reddy.
+
+ This file is part of BFD, the Binary File Descriptor library.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "bfdlink.h"
+#include "libbfd.h"
+#include "libiberty.h"
+#include "elf-bfd.h"
+#include "elf/cr16.h"
+
+/* The cr16 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. */
+
+struct elf32_cr16_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 function 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;
+
+/* Used to mark functions which have had redundant parts of their
+ prologue deleted. */
+#define CR16_DELETED_PROLOGUE_BYTES 0x1
+ unsigned char flags;
+
+ /* Calculated value. */
+ bfd_vma value;
+};
+
+/* cr16_reloc_map array maps BFD relocation enum into a CRGAS relocation type. */
+
+struct cr16_reloc_map
+{
+ bfd_reloc_code_real_type bfd_reloc_enum; /* BFD relocation enum. */
+ unsigned short cr16_reloc_type; /* CR16 relocation type. */
+};
+
+static const struct cr16_reloc_map cr16_reloc_map[R_CR16_MAX] =
+{
+ {BFD_RELOC_NONE, R_CR16_NONE},
+ {BFD_RELOC_CR16_NUM8, R_CR16_NUM8},
+ {BFD_RELOC_CR16_NUM16, R_CR16_NUM16},
+ {BFD_RELOC_CR16_NUM32, R_CR16_NUM32},
+ {BFD_RELOC_CR16_NUM32a, R_CR16_NUM32a},
+ {BFD_RELOC_CR16_REGREL4, R_CR16_REGREL4},
+ {BFD_RELOC_CR16_REGREL4a, R_CR16_REGREL4a},
+ {BFD_RELOC_CR16_REGREL14, R_CR16_REGREL14},
+ {BFD_RELOC_CR16_REGREL14a, R_CR16_REGREL14a},
+ {BFD_RELOC_CR16_REGREL16, R_CR16_REGREL16},
+ {BFD_RELOC_CR16_REGREL20, R_CR16_REGREL20},
+ {BFD_RELOC_CR16_REGREL20a, R_CR16_REGREL20a},
+ {BFD_RELOC_CR16_ABS20, R_CR16_ABS20},
+ {BFD_RELOC_CR16_ABS24, R_CR16_ABS24},
+ {BFD_RELOC_CR16_IMM4, R_CR16_IMM4},
+ {BFD_RELOC_CR16_IMM8, R_CR16_IMM8},
+ {BFD_RELOC_CR16_IMM16, R_CR16_IMM16},
+ {BFD_RELOC_CR16_IMM20, R_CR16_IMM20},
+ {BFD_RELOC_CR16_IMM24, R_CR16_IMM24},
+ {BFD_RELOC_CR16_IMM32, R_CR16_IMM32},
+ {BFD_RELOC_CR16_IMM32a, R_CR16_IMM32a},
+ {BFD_RELOC_CR16_DISP4, R_CR16_DISP4},
+ {BFD_RELOC_CR16_DISP8, R_CR16_DISP8},
+ {BFD_RELOC_CR16_DISP16, R_CR16_DISP16},
+ {BFD_RELOC_CR16_DISP24, R_CR16_DISP24},
+ {BFD_RELOC_CR16_DISP24a, R_CR16_DISP24a},
+ {BFD_RELOC_CR16_SWITCH8, R_CR16_SWITCH8},
+ {BFD_RELOC_CR16_SWITCH16, R_CR16_SWITCH16},
+ {BFD_RELOC_CR16_SWITCH32, R_CR16_SWITCH32},
+ {BFD_RELOC_CR16_GOT_REGREL20, R_CR16_GOT_REGREL20},
+ {BFD_RELOC_CR16_GOTC_REGREL20, R_CR16_GOTC_REGREL20},
+ {BFD_RELOC_CR16_GLOB_DAT, R_CR16_GLOB_DAT}
+};
+
+static reloc_howto_type cr16_elf_howto_table[] =
+{
+ HOWTO (R_CR16_NONE, /* type */
+ 0, /* rightshift */
+ 2, /* size */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_CR16_NONE", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_CR16_NUM8, /* type */
+ 0, /* rightshift */
+ 0, /* size */
+ 8, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_CR16_NUM8", /* name */
+ FALSE, /* partial_inplace */
+ 0x0, /* src_mask */
+ 0xff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_CR16_NUM16, /* type */
+ 0, /* rightshift */
+ 1, /* size */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_CR16_NUM16", /* name */
+ FALSE, /* partial_inplace */
+ 0x0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_CR16_NUM32, /* type */
+ 0, /* rightshift */
+ 2, /* size */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_CR16_NUM32", /* name */
+ FALSE, /* partial_inplace */
+ 0x0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_CR16_NUM32a, /* type */
+ 1, /* rightshift */
+ 2, /* size */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_CR16_NUM32a", /* name */
+ FALSE, /* partial_inplace */
+ 0x0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_CR16_REGREL4, /* type */
+ 0, /* rightshift */
+ 0, /* size */
+ 4, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_CR16_REGREL4", /* name */
+ FALSE, /* partial_inplace */
+ 0x0, /* src_mask */
+ 0xf, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_CR16_REGREL4a, /* type */
+ 0, /* rightshift */
+ 0, /* size */
+ 4, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_CR16_REGREL4a", /* name */
+ FALSE, /* partial_inplace */
+ 0x0, /* src_mask */
+ 0xf, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_CR16_REGREL14, /* type */
+ 0, /* rightshift */
+ 1, /* size */
+ 14, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_CR16_REGREL14", /* name */
+ FALSE, /* partial_inplace */
+ 0x0, /* src_mask */
+ 0x3fff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_CR16_REGREL14a, /* type */
+ 0, /* rightshift */
+ 1, /* size */
+ 14, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_CR16_REGREL14a", /* name */
+ FALSE, /* partial_inplace */
+ 0x0, /* src_mask */
+ 0x3fff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_CR16_REGREL16, /* type */
+ 0, /* rightshift */
+ 1, /* size */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_CR16_REGREL16", /* name */
+ FALSE, /* partial_inplace */
+ 0x0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_CR16_REGREL20, /* type */
+ 0, /* rightshift */
+ 2, /* size */
+ 20, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_CR16_REGREL20", /* name */
+ FALSE, /* partial_inplace */
+ 0x0, /* src_mask */
+ 0xfffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_CR16_REGREL20a, /* type */
+ 0, /* rightshift */
+ 2, /* size */
+ 20, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_CR16_REGREL20a", /* name */
+ FALSE, /* partial_inplace */
+ 0x0, /* src_mask */
+ 0xfffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_CR16_ABS20, /* type */
+ 0, /* rightshift */
+ 2, /* size */
+ 20, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_CR16_ABS20", /* name */
+ FALSE, /* partial_inplace */
+ 0x0, /* src_mask */
+ 0xfffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_CR16_ABS24, /* type */
+ 0, /* rightshift */
+ 2, /* size */
+ 24, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_CR16_ABS24", /* name */
+ FALSE, /* partial_inplace */
+ 0x0, /* src_mask */
+ 0xffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_CR16_IMM4, /* type */
+ 0, /* rightshift */
+ 0, /* size */
+ 4, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_CR16_IMM4", /* name */
+ FALSE, /* partial_inplace */
+ 0x0, /* src_mask */
+ 0xf, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_CR16_IMM8, /* type */
+ 0, /* rightshift */
+ 0, /* size */
+ 8, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_CR16_IMM8", /* name */
+ FALSE, /* partial_inplace */
+ 0x0, /* src_mask */
+ 0xff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_CR16_IMM16, /* type */
+ 0, /* rightshift */
+ 1, /* size */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_CR16_IMM16", /* name */
+ FALSE, /* partial_inplace */
+ 0x0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_CR16_IMM20, /* type */
+ 0, /* rightshift */
+ 2, /* size */
+ 20, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_CR16_IMM20", /* name */
+ FALSE, /* partial_inplace */
+ 0x0, /* src_mask */
+ 0xfffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_CR16_IMM24, /* type */
+ 0, /* rightshift */
+ 2, /* size */
+ 24, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_CR16_IMM24", /* name */
+ FALSE, /* partial_inplace */
+ 0x0, /* src_mask */
+ 0xffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_CR16_IMM32, /* type */
+ 0, /* rightshift */
+ 2, /* size */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_CR16_IMM32", /* name */
+ FALSE, /* partial_inplace */
+ 0x0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_CR16_IMM32a, /* type */
+ 1, /* rightshift */
+ 2, /* size */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_CR16_IMM32a", /* name */
+ FALSE, /* partial_inplace */
+ 0x0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_CR16_DISP4, /* type */
+ 1, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 4, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_unsigned, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_CR16_DISP4", /* name */
+ FALSE, /* partial_inplace */
+ 0x0, /* src_mask */
+ 0xf, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_CR16_DISP8, /* type */
+ 1, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 8, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_unsigned, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_CR16_DISP8", /* name */
+ FALSE, /* partial_inplace */
+ 0x0, /* src_mask */
+ 0x1ff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_CR16_DISP16, /* type */
+ 0, /* rightshift REVIITS: To sync with WinIDEA*/
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_unsigned, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_CR16_DISP16", /* name */
+ FALSE, /* partial_inplace */
+ 0x0, /* src_mask */
+ 0x1ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ /* REVISIT: DISP24 should be left-shift by 2 as per ISA doc
+ but its not done, to sync with WinIDEA and CR16 4.1 tools */
+ HOWTO (R_CR16_DISP24, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 24, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_unsigned, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_CR16_DISP24", /* name */
+ FALSE, /* partial_inplace */
+ 0x0, /* src_mask */
+ 0x1ffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_CR16_DISP24a, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 24, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_unsigned, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_CR16_DISP24a", /* name */
+ FALSE, /* partial_inplace */
+ 0x0, /* src_mask */
+ 0xffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* An 8 bit switch table entry. This is generated for an expression
+ such as ``.byte L1 - L2''. The offset holds the difference
+ between the reloc address and L2. */
+ HOWTO (R_CR16_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 */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_CR16_SWITCH8", /* name */
+ FALSE, /* partial_inplace */
+ 0x0, /* src_mask */
+ 0xff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* 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_CR16_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 */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_CR16_SWITCH16", /* name */
+ FALSE, /* partial_inplace */
+ 0x0, /* src_mask */
+ 0xffff, /* 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_CR16_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 */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_CR16_SWITCH32", /* name */
+ FALSE, /* partial_inplace */
+ 0x0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_CR16_GOT_REGREL20, /* type */
+ 0, /* rightshift */
+ 2, /* size */
+ 20, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_CR16_GOT_REGREL20", /* name */
+ TRUE, /* partial_inplace */
+ 0x0, /* src_mask */
+ 0xfffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_CR16_GOTC_REGREL20, /* type */
+ 0, /* rightshift */
+ 2, /* size */
+ 20, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_CR16_GOTC_REGREL20", /* name */
+ TRUE, /* partial_inplace */
+ 0x0, /* src_mask */
+ 0xfffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_CR16_GLOB_DAT, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_unsigned, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_CR16_GLOB_DAT", /* name */
+ FALSE, /* partial_inplace */
+ 0x0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ TRUE) /* pcrel_offset */
+};
+
+
+/* Create the GOT section. */
+
+static bfd_boolean
+_bfd_cr16_elf_create_got_section (bfd * abfd, struct bfd_link_info * info)
+{
+ flagword flags;
+ asection * s;
+ struct elf_link_hash_entry * h;
+ const struct elf_backend_data * bed = get_elf_backend_data (abfd);
+ int ptralign;
+
+ /* This function may be called more than once. */
+ if (bfd_get_linker_section (abfd, ".got") != NULL)
+ return TRUE;
+
+ switch (bed->s->arch_size)
+ {
+ case 16:
+ ptralign = 1;
+ break;
+
+ case 32:
+ ptralign = 2;
+ break;
+
+ default:
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+
+ flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
+ | SEC_LINKER_CREATED);
+
+ s = bfd_make_section_anyway_with_flags (abfd, ".got", flags);
+ if (s == NULL
+ || ! bfd_set_section_alignment (abfd, s, ptralign))
+ return FALSE;
+
+ if (bed->want_got_plt)
+ {
+ s = bfd_make_section_anyway_with_flags (abfd, ".got.plt", flags);
+ if (s == NULL
+ || ! 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 = _bfd_elf_define_linkage_sym (abfd, info, s, "_GLOBAL_OFFSET_TABLE_");
+ elf_hash_table (info)->hgot = h;
+ if (h == NULL)
+ return FALSE;
+
+ /* The first bit of the global offset table is the header. */
+ s->size += bed->got_header_size;
+
+ return TRUE;
+}
+
+
+/* Retrieve a howto ptr using a BFD reloc_code. */
+
+static reloc_howto_type *
+elf_cr16_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ bfd_reloc_code_real_type code)
+{
+ unsigned int i;
+
+ for (i = 0; i < R_CR16_MAX; i++)
+ if (code == cr16_reloc_map[i].bfd_reloc_enum)
+ return &cr16_elf_howto_table[cr16_reloc_map[i].cr16_reloc_type];
+
+ _bfd_error_handler ("Unsupported CR16 relocation type: 0x%x\n", code);
+ return NULL;
+}
+
+static reloc_howto_type *
+elf_cr16_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ const char *r_name)
+{
+ unsigned int i;
+
+ for (i = 0; ARRAY_SIZE (cr16_elf_howto_table); i++)
+ if (cr16_elf_howto_table[i].name != NULL
+ && strcasecmp (cr16_elf_howto_table[i].name, r_name) == 0)
+ return cr16_elf_howto_table + i;
+
+ return NULL;
+}
+
+/* Retrieve a howto ptr using an internal relocation entry. */
+
+static void
+elf_cr16_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED, arelent *cache_ptr,
+ Elf_Internal_Rela *dst)
+{
+ unsigned int r_type = ELF32_R_TYPE (dst->r_info);
+
+ BFD_ASSERT (r_type < (unsigned int) R_CR16_MAX);
+ cache_ptr->howto = cr16_elf_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 bfd_boolean
+cr16_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, asection *sec,
+ const Elf_Internal_Rela *relocs)
+{
+ Elf_Internal_Shdr *symtab_hdr;
+ Elf_Internal_Sym * isymbuf = NULL;
+ struct elf_link_hash_entry **sym_hashes, **sym_hashes_end;
+ const Elf_Internal_Rela *rel;
+ const Elf_Internal_Rela *rel_end;
+ bfd * dynobj;
+ bfd_vma * local_got_offsets;
+ asection * sgot;
+ asection * srelgot;
+
+ sgot = NULL;
+ srelgot = NULL;
+ bfd_boolean result = FALSE;
+
+ if (info->relocatable)
+ 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;
+
+ dynobj = elf_hash_table (info)->dynobj;
+ local_got_offsets = elf_local_got_offsets (abfd);
+ 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];
+ 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;
+
+ /* PR15323, ref flags aren't set for references in the same
+ object. */
+ h->root.non_ir_ref = 1;
+ }
+
+ /* Some relocs require a global offset table. */
+ if (dynobj == NULL)
+ {
+ switch (ELF32_R_TYPE (rel->r_info))
+ {
+ case R_CR16_GOT_REGREL20:
+ case R_CR16_GOTC_REGREL20:
+ elf_hash_table (info)->dynobj = dynobj = abfd;
+ if (! _bfd_cr16_elf_create_got_section (dynobj, info))
+ goto fail;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ switch (ELF32_R_TYPE (rel->r_info))
+ {
+ case R_CR16_GOT_REGREL20:
+ case R_CR16_GOTC_REGREL20:
+ /* This symbol requires a global offset table entry. */
+
+ if (sgot == NULL)
+ {
+ sgot = bfd_get_linker_section (dynobj, ".got");
+ BFD_ASSERT (sgot != NULL);
+ }
+
+ if (srelgot == NULL
+ && (h != NULL || info->executable))
+ {
+ srelgot = bfd_get_linker_section (dynobj, ".rela.got");
+ if (srelgot == NULL)
+ {
+ flagword flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS
+ | SEC_IN_MEMORY | SEC_LINKER_CREATED
+ | SEC_READONLY);
+ srelgot = bfd_make_section_anyway_with_flags (dynobj,
+ ".rela.got",
+ flags);
+ if (srelgot == NULL
+ || ! bfd_set_section_alignment (dynobj, srelgot, 2))
+ goto fail;
+ }
+ }
+
+ if (h != NULL)
+ {
+ if (h->got.offset != (bfd_vma) -1)
+ /* We have already allocated space in the .got. */
+ break;
+
+ h->got.offset = sgot->size;
+
+ /* Make sure this symbol is output as a dynamic symbol. */
+ if (h->dynindx == -1)
+ {
+ if (! bfd_elf_link_record_dynamic_symbol (info, h))
+ goto fail;
+ }
+
+ srelgot->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;
+ 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)
+ goto fail;
+
+ 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->size;
+
+ if (info->executable)
+ /* If we are generating a shared object, we need to
+ output a R_CR16_RELATIVE reloc so that the dynamic
+ linker can adjust this GOT entry. */
+ srelgot->size += sizeof (Elf32_External_Rela);
+ }
+
+ sgot->size += 4;
+ break;
+
+ }
+ }
+
+ result = TRUE;
+ fail:
+ if (isymbuf != NULL)
+ free (isymbuf);
+
+ return result;
+}
+
+/* Perform a relocation as part of a final link. */
+
+static bfd_reloc_status_type
+cr16_elf_final_link_relocate (reloc_howto_type *howto,
+ bfd *input_bfd,
+ bfd *output_bfd ATTRIBUTE_UNUSED,
+ asection *input_section,
+ bfd_byte *contents,
+ bfd_vma offset,
+ bfd_vma Rvalue,
+ bfd_vma addend,
+ struct elf_link_hash_entry * h,
+ unsigned long symndx ATTRIBUTE_UNUSED,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ asection *sec ATTRIBUTE_UNUSED,
+ int is_local ATTRIBUTE_UNUSED)
+{
+ unsigned short r_type = howto->type;
+ bfd_byte *hit_data = contents + offset;
+ bfd_vma reloc_bits, check, Rvalue1;
+ bfd * dynobj;
+
+ dynobj = elf_hash_table (info)->dynobj;
+
+ switch (r_type)
+ {
+ case R_CR16_IMM4:
+ case R_CR16_IMM20:
+ case R_CR16_ABS20:
+ break;
+
+ case R_CR16_IMM8:
+ case R_CR16_IMM16:
+ case R_CR16_IMM32:
+ case R_CR16_IMM32a:
+ case R_CR16_REGREL4:
+ case R_CR16_REGREL4a:
+ case R_CR16_REGREL14:
+ case R_CR16_REGREL14a:
+ case R_CR16_REGREL16:
+ case R_CR16_REGREL20:
+ case R_CR16_REGREL20a:
+ case R_CR16_GOT_REGREL20:
+ case R_CR16_GOTC_REGREL20:
+ case R_CR16_ABS24:
+ case R_CR16_DISP16:
+ case R_CR16_DISP24:
+ /* 'hit_data' is relative to the start of the instruction, not the
+ relocation offset. Advance it to account for the exact offset. */
+ hit_data += 2;
+ break;
+
+ case R_CR16_NONE:
+ return bfd_reloc_ok;
+ break;
+
+ case R_CR16_DISP4:
+ if (is_local)
+ Rvalue += -1;
+ break;
+
+ case R_CR16_DISP8:
+ case R_CR16_DISP24a:
+ if (is_local)
+ Rvalue -= -1;
+ break;
+
+ case R_CR16_SWITCH8:
+ case R_CR16_SWITCH16:
+ case R_CR16_SWITCH32:
+ /* We only care about the addend, where the difference between
+ expressions is kept. */
+ Rvalue = 0;
+
+ default:
+ break;
+ }
+
+ if (howto->pc_relative)
+ {
+ /* Subtract the address of the section containing the location. */
+ Rvalue -= (input_section->output_section->vma
+ + input_section->output_offset);
+ /* Subtract the position of the location within the section. */
+ Rvalue -= offset;
+ }
+
+ /* Add in supplied addend. */
+ Rvalue += addend;
+
+ /* Complain if the bitfield overflows, whether it is considered
+ as signed or unsigned. */
+ check = Rvalue >> howto->rightshift;
+
+ /* Assumes two's complement. This expression avoids
+ overflow if howto->bitsize is the number of bits in
+ bfd_vma. */
+ reloc_bits = (((1 << (howto->bitsize - 1)) - 1) << 1) | 1;
+
+ /* For GOT and GOTC relocs no boundary checks applied. */
+ if (!((r_type == R_CR16_GOT_REGREL20)
+ || (r_type == R_CR16_GOTC_REGREL20)))
+ {
+ if (((bfd_vma) check & ~reloc_bits) != 0
+ && (((bfd_vma) check & ~reloc_bits)
+ != (-(bfd_vma) 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 && (bfd_signed_vma) Rvalue < 0)
+ {
+ check |= ((bfd_vma) - 1
+ & ~((bfd_vma) - 1
+ >> howto->rightshift));
+
+ if (((bfd_vma) check & ~reloc_bits)
+ != (-(bfd_vma) 1 & ~reloc_bits))
+ return bfd_reloc_overflow;
+ }
+ else
+ return bfd_reloc_overflow;
+ }
+
+ /* Drop unwanted bits from the value we are relocating to. */
+ Rvalue >>= (bfd_vma) howto->rightshift;
+
+ /* Apply dst_mask to select only relocatable part of the insn. */
+ Rvalue &= howto->dst_mask;
+ }
+
+ switch (howto->size)
+ {
+ case 0:
+ if (r_type == R_CR16_DISP8)
+ {
+ Rvalue1 = bfd_get_16 (input_bfd, hit_data);
+ Rvalue = ((Rvalue1 & 0xf000) | ((Rvalue << 4) & 0xf00)
+ | (Rvalue1 & 0x00f0) | (Rvalue & 0xf));
+ bfd_put_16 (input_bfd, Rvalue, hit_data);
+ }
+ else if (r_type == R_CR16_IMM4)
+ {
+ Rvalue1 = bfd_get_16 (input_bfd, hit_data);
+ Rvalue = (((Rvalue1 & 0xff) << 8) | ((Rvalue << 4) & 0xf0)
+ | ((Rvalue1 & 0x0f00) >> 8));
+ bfd_put_16 (input_bfd, Rvalue, hit_data);
+ }
+ else if (r_type == R_CR16_DISP4)
+ {
+ Rvalue1 = bfd_get_16 (input_bfd, hit_data);
+ Rvalue = (Rvalue1 | ((Rvalue & 0xf) << 4));
+ bfd_put_16 (input_bfd, Rvalue, hit_data);
+ }
+ else
+ {
+ bfd_put_8 (input_bfd, (unsigned char) Rvalue, hit_data);
+ }
+ break;
+
+ case 1:
+ if (r_type == R_CR16_DISP16)
+ {
+ Rvalue |= (bfd_get_16 (input_bfd, hit_data));
+ Rvalue = ((Rvalue & 0xfffe) | ((Rvalue >> 16) & 0x1));
+ }
+ if (r_type == R_CR16_IMM16)
+ {
+ Rvalue1 = bfd_get_16 (input_bfd, hit_data);
+
+ /* Add or subtract the offset value. */
+ if (Rvalue1 & 0x8000)
+ Rvalue -= (~Rvalue1 + 1) & 0xffff;
+ else
+ Rvalue += Rvalue1;
+
+ /* Check for range. */
+ if ((long) Rvalue > 0xffff || (long) Rvalue < 0x0)
+ return bfd_reloc_overflow;
+ }
+
+ bfd_put_16 (input_bfd, Rvalue, hit_data);
+ break;
+
+ case 2:
+ if ((r_type == R_CR16_ABS20) || (r_type == R_CR16_IMM20))
+ {
+ Rvalue1 = (bfd_get_16 (input_bfd, hit_data + 2)
+ | (((bfd_get_16 (input_bfd, hit_data) & 0xf) <<16)));
+
+ /* Add or subtract the offset value. */
+ if (Rvalue1 & 0x80000)
+ Rvalue -= (~Rvalue1 + 1) & 0xfffff;
+ else
+ Rvalue += Rvalue1;
+
+ /* Check for range. */
+ if ((long) Rvalue > 0xfffff || (long) Rvalue < 0x0)
+ return bfd_reloc_overflow;
+
+ bfd_put_16 (input_bfd, ((bfd_get_16 (input_bfd, hit_data) & 0xfff0)
+ | ((Rvalue >> 16) & 0xf)), hit_data);
+ bfd_put_16 (input_bfd, (Rvalue) & 0xffff, hit_data + 2);
+ }
+ else if (r_type == R_CR16_GOT_REGREL20)
+ {
+ asection * sgot = bfd_get_linker_section (dynobj, ".got");
+
+ if (h != NULL)
+ {
+ bfd_vma off;
+
+ off = h->got.offset;
+ BFD_ASSERT (off != (bfd_vma) -1);
+
+ if (! elf_hash_table (info)->dynamic_sections_created
+ || SYMBOL_REFERENCES_LOCAL (info, h))
+ /* 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.
+ 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. */
+ bfd_put_32 (output_bfd, Rvalue, sgot->contents + off);
+
+ Rvalue = sgot->output_offset + off;
+ }
+ else
+ {
+ bfd_vma off;
+
+ off = elf_local_got_offsets (input_bfd)[symndx];
+ bfd_put_32 (output_bfd,Rvalue, sgot->contents + off);
+
+ Rvalue = sgot->output_offset + off;
+ }
+
+ Rvalue += addend;
+
+ /* REVISIT: if ((long) Rvalue > 0xffffff ||
+ (long) Rvalue < -0x800000). */
+ if ((long) Rvalue > 0xffffff || (long) Rvalue < 0)
+ return bfd_reloc_overflow;
+
+
+ bfd_put_16 (input_bfd, (bfd_get_16 (input_bfd, hit_data))
+ | (((Rvalue >> 16) & 0xf) << 8), hit_data);
+ bfd_put_16 (input_bfd, (Rvalue) & 0xffff, hit_data + 2);
+
+ }
+ else if (r_type == R_CR16_GOTC_REGREL20)
+ {
+ asection * sgot;
+ sgot = bfd_get_linker_section (dynobj, ".got");
+
+ if (h != NULL)
+ {
+ bfd_vma off;
+
+ off = h->got.offset;
+ BFD_ASSERT (off != (bfd_vma) -1);
+
+ Rvalue >>=1; /* For code symbols. */
+
+ if (! elf_hash_table (info)->dynamic_sections_created
+ || SYMBOL_REFERENCES_LOCAL (info, h))
+ /* 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.
+ 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. */
+ bfd_put_32 (output_bfd, Rvalue, sgot->contents + off);
+
+ Rvalue = sgot->output_offset + off;
+ }
+ else
+ {
+ bfd_vma off;
+
+ off = elf_local_got_offsets (input_bfd)[symndx];
+ Rvalue >>= 1;
+ bfd_put_32 (output_bfd,Rvalue, sgot->contents + off);
+ Rvalue = sgot->output_offset + off;
+ }
+
+ Rvalue += addend;
+
+ /* Check if any value in DISP. */
+ Rvalue1 =((bfd_get_32 (input_bfd, hit_data) >>16)
+ | (((bfd_get_32 (input_bfd, hit_data) & 0xfff) >> 8) <<16));
+
+ /* Add or subtract the offset value. */
+ if (Rvalue1 & 0x80000)
+ Rvalue -= (~Rvalue1 + 1) & 0xfffff;
+ else
+ Rvalue += Rvalue1;
+
+ /* Check for range. */
+ /* REVISIT: if ((long) Rvalue > 0xffffff
+ || (long) Rvalue < -0x800000). */
+ if ((long) Rvalue > 0xffffff || (long) Rvalue < 0)
+ return bfd_reloc_overflow;
+
+ bfd_put_16 (input_bfd, (bfd_get_16 (input_bfd, hit_data))
+ | (((Rvalue >> 16) & 0xf) << 8), hit_data);
+ bfd_put_16 (input_bfd, (Rvalue) & 0xffff, hit_data + 2);
+ }
+ else
+ {
+ if (r_type == R_CR16_ABS24)
+ {
+ Rvalue1 = ((bfd_get_32 (input_bfd, hit_data) >> 16)
+ | (((bfd_get_32 (input_bfd, hit_data) & 0xfff) >> 8) <<16)
+ | (((bfd_get_32 (input_bfd, hit_data) & 0xf) <<20)));
+
+ /* Add or subtract the offset value. */
+ if (Rvalue1 & 0x800000)
+ Rvalue -= (~Rvalue1 + 1) & 0xffffff;
+ else
+ Rvalue += Rvalue1;
+
+ /* Check for Range. */
+ if ((long) Rvalue > 0xffffff || (long) Rvalue < 0x0)
+ return bfd_reloc_overflow;
+
+ Rvalue = ((((Rvalue >> 20) & 0xf) | (((Rvalue >> 16) & 0xf)<<8)
+ | (bfd_get_32 (input_bfd, hit_data) & 0xf0f0))
+ | ((Rvalue & 0xffff) << 16));
+ }
+ else if (r_type == R_CR16_DISP24)
+ {
+ Rvalue = ((((Rvalue >> 20)& 0xf) | (((Rvalue >>16) & 0xf)<<8)
+ | (bfd_get_16 (input_bfd, hit_data)))
+ | (((Rvalue & 0xfffe) | ((Rvalue >> 24) & 0x1)) << 16));
+ }
+ else if ((r_type == R_CR16_IMM32) || (r_type == R_CR16_IMM32a))
+ {
+ Rvalue1 =((((bfd_get_32 (input_bfd, hit_data)) >> 16) &0xffff)
+ | (((bfd_get_32 (input_bfd, hit_data)) &0xffff)) << 16);
+
+ /* Add or subtract the offset value. */
+ if (Rvalue1 & 0x80000000)
+ Rvalue -= (~Rvalue1 + 1) & 0xffffffff;
+ else
+ Rvalue += Rvalue1;
+
+ /* Check for range. */
+ if (Rvalue > 0xffffffff || (long) Rvalue < 0x0)
+ return bfd_reloc_overflow;
+
+ Rvalue = (((Rvalue >> 16)& 0xffff) | (Rvalue & 0xffff) << 16);
+ }
+ else if (r_type == R_CR16_DISP24a)
+ {
+ Rvalue = (((Rvalue & 0xfffffe) | (Rvalue >> 23)));
+ Rvalue = ((Rvalue >> 16) & 0xff) | ((Rvalue & 0xffff) << 16)
+ | (bfd_get_32 (input_bfd, hit_data));
+ }
+ else if ((r_type == R_CR16_REGREL20)
+ || (r_type == R_CR16_REGREL20a))
+ {
+ Rvalue1 = ((bfd_get_32 (input_bfd, hit_data) >> 16)
+ | (((bfd_get_32 (input_bfd, hit_data) & 0xfff) >> 8) <<16));
+ /* Add or subtract the offset value. */
+ if (Rvalue1 & 0x80000)
+ Rvalue -= (~Rvalue1 + 1) & 0xfffff;
+ else
+ Rvalue += Rvalue1;
+
+ /* Check for range. */
+ if ((long) Rvalue > 0xfffff || (long) Rvalue < 0x0)
+ return bfd_reloc_overflow;
+
+ Rvalue = (((((Rvalue >> 20)& 0xf) | (((Rvalue >>16) & 0xf)<<8)
+ | ((Rvalue & 0xffff) << 16)))
+ | (bfd_get_32 (input_bfd, hit_data) & 0xf0ff));
+
+ }
+ else if (r_type == R_CR16_NUM32)
+ {
+ Rvalue1 = (bfd_get_32 (input_bfd, hit_data));
+
+ /* Add or subtract the offset value */
+ if (Rvalue1 & 0x80000000)
+ Rvalue -= (~Rvalue1 + 1) & 0xffffffff;
+ else
+ Rvalue += Rvalue1;
+
+ /* Check for Ranga */
+ if (Rvalue > 0xffffffff)
+ return bfd_reloc_overflow;
+ }
+
+ bfd_put_32 (input_bfd, Rvalue, hit_data);
+ }
+ break;
+
+ default:
+ return bfd_reloc_notsupported;
+ }
+
+ return bfd_reloc_ok;
+}
+
+/* Delete some bytes from a section while relaxing. */
+
+static bfd_boolean
+elf32_cr16_relax_delete_bytes (struct bfd_link_info *link_info, bfd *abfd,
+ asection *sec, bfd_vma addr, int count)
+{
+ Elf_Internal_Shdr *symtab_hdr;
+ unsigned int sec_shndx;
+ bfd_byte *contents;
+ Elf_Internal_Rela *irel, *irelend;
+ bfd_vma toaddr;
+ Elf_Internal_Sym *isym;
+ Elf_Internal_Sym *isymend;
+ struct elf_link_hash_entry **sym_hashes;
+ struct elf_link_hash_entry **end_hashes;
+ struct elf_link_hash_entry **start_hashes;
+ unsigned int symcount;
+
+ sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
+
+ contents = elf_section_data (sec)->this_hdr.contents;
+
+ toaddr = sec->size;
+
+ irel = elf_section_data (sec)->relocs;
+ irelend = irel + sec->reloc_count;
+
+ /* Actually delete the bytes. */
+ memmove (contents + addr, contents + addr + count,
+ (size_t) (toaddr - addr - count));
+ sec->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. */
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+ isym = (Elf_Internal_Sym *) symtab_hdr->contents;
+ for (isymend = isym + symtab_hdr->sh_info; isym < isymend; isym++)
+ {
+ if (isym->st_shndx == sec_shndx
+ && isym->st_value > addr
+ && isym->st_value < toaddr)
+ {
+ /* Adjust the addend of SWITCH relocations in this section,
+ which reference this local symbol. */
+#if 0
+ for (irel = elf_section_data (sec)->relocs; irel < irelend; irel++)
+ {
+ unsigned long r_symndx;
+ Elf_Internal_Sym *rsym;
+ bfd_vma addsym, subsym;
+
+ /* Skip if not a SWITCH relocation. */
+ if (ELF32_R_TYPE (irel->r_info) != (int) R_CR16_SWITCH8
+ && ELF32_R_TYPE (irel->r_info) != (int) R_CR16_SWITCH16
+ && ELF32_R_TYPE (irel->r_info) != (int) R_CR16_SWITCH32)
+ continue;
+
+ r_symndx = ELF32_R_SYM (irel->r_info);
+ rsym = (Elf_Internal_Sym *) symtab_hdr->contents + r_symndx;
+
+ /* Skip if not the local adjusted symbol. */
+ if (rsym != isym)
+ continue;
+
+ addsym = isym->st_value;
+ subsym = addsym - irel->r_addend;
+
+ /* Fix the addend only when -->> (addsym > addr >= subsym). */
+ if (subsym <= addr)
+ irel->r_addend -= count;
+ else
+ continue;
+ }
+#endif
+
+ isym->st_value -= count;
+ }
+ }
+
+ /* Now adjust the global symbols defined in this section. */
+ symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
+ - symtab_hdr->sh_info);
+ sym_hashes = start_hashes = elf_sym_hashes (abfd);
+ end_hashes = sym_hashes + symcount;
+
+ for (; sym_hashes < end_hashes; sym_hashes++)
+ {
+ struct elf_link_hash_entry *sym_hash = *sym_hashes;
+
+ /* The '--wrap SYMBOL' option is causing a pain when the object file,
+ containing the definition of __wrap_SYMBOL, includes a direct
+ call to SYMBOL as well. Since both __wrap_SYMBOL and SYMBOL reference
+ the same symbol (which is __wrap_SYMBOL), but still exist as two
+ different symbols in 'sym_hashes', we don't want to adjust
+ the global symbol __wrap_SYMBOL twice.
+ This check is only relevant when symbols are being wrapped. */
+ if (link_info->wrap_hash != NULL)
+ {
+ struct elf_link_hash_entry **cur_sym_hashes;
+
+ /* Loop only over the symbols whom been already checked. */
+ for (cur_sym_hashes = start_hashes; cur_sym_hashes < sym_hashes;
+ cur_sym_hashes++)
+ /* If the current symbol is identical to 'sym_hash', that means
+ the symbol was already adjusted (or at least checked). */
+ if (*cur_sym_hashes == sym_hash)
+ break;
+
+ /* Don't adjust the symbol again. */
+ if (cur_sym_hashes < sym_hashes)
+ continue;
+ }
+
+ 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
+ && sym_hash->root.u.def.value < toaddr)
+ sym_hash->root.u.def.value -= count;
+ }
+
+ return TRUE;
+}
+
+/* Relocate a CR16 ELF section. */
+
+static bfd_boolean
+elf32_cr16_relocate_section (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 = cr16_elf_howto_table + (r_type);
+
+ h = NULL;
+ sym = NULL;
+ sec = NULL;
+ if (r_symndx < symtab_hdr->sh_info)
+ {
+ sym = local_syms + r_symndx;
+ sec = local_sections[r_symndx];
+ relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
+ }
+ else
+ {
+ bfd_boolean unresolved_reloc, warned, ignored;
+
+ RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
+ r_symndx, symtab_hdr, sym_hashes,
+ h, sec, relocation,
+ unresolved_reloc, warned, ignored);
+ }
+
+ if (sec != NULL && discarded_section (sec))
+ RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+ rel, 1, relend, howto, 0, contents);
+
+ if (info->relocatable)
+ continue;
+
+ r = cr16_elf_final_link_relocate (howto, input_bfd, output_bfd,
+ input_section,
+ contents, rel->r_offset,
+ relocation, rel->r_addend,
+ (struct elf_link_hash_entry *) h,
+ r_symndx,
+ info, sec, h == NULL);
+
+ if (r != bfd_reloc_ok)
+ {
+ const char *name;
+ const char *msg = NULL;
+
+ 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, (h ? &h->root : NULL), 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, TRUE)))
+ 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 is a version of bfd_generic_get_relocated_section_contents
+ which uses elf32_cr16_relocate_section. */
+
+static bfd_byte *
+elf32_cr16_get_relocated_section_contents (bfd *output_bfd,
+ struct bfd_link_info *link_info,
+ struct bfd_link_order *link_order,
+ bfd_byte *data,
+ bfd_boolean relocatable,
+ 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;
+ Elf_Internal_Sym *isymbuf = NULL;
+
+ /* We only need to handle the case of relaxing, or of having a
+ particular set of section contents, specially. */
+ if (relocatable
+ || elf_section_data (input_section)->this_hdr.contents == NULL)
+ return bfd_generic_get_relocated_section_contents (output_bfd, link_info,
+ link_order, data,
+ relocatable,
+ symbols);
+
+ symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
+
+ memcpy (data, elf_section_data (input_section)->this_hdr.contents,
+ (size_t) input_section->size);
+
+ if ((input_section->flags & SEC_RELOC) != 0
+ && input_section->reloc_count > 0)
+ {
+ Elf_Internal_Sym *isym;
+ Elf_Internal_Sym *isymend;
+ asection **secpp;
+ bfd_size_type amt;
+
+ internal_relocs = _bfd_elf_link_read_relocs (input_bfd, input_section,
+ NULL, NULL, FALSE);
+ if (internal_relocs == NULL)
+ goto error_return;
+
+ if (symtab_hdr->sh_info != 0)
+ {
+ isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
+ if (isymbuf == NULL)
+ isymbuf = bfd_elf_get_elf_syms (input_bfd, symtab_hdr,
+ symtab_hdr->sh_info, 0,
+ NULL, NULL, NULL);
+ if (isymbuf == NULL)
+ goto error_return;
+ }
+
+ amt = symtab_hdr->sh_info;
+ amt *= sizeof (asection *);
+ sections = bfd_malloc (amt);
+ if (sections == NULL && amt != 0)
+ goto error_return;
+
+ isymend = isymbuf + symtab_hdr->sh_info;
+ for (isym = isymbuf, secpp = sections; isym < isymend; ++isym, ++secpp)
+ {
+ asection *isec;
+
+ if (isym->st_shndx == SHN_UNDEF)
+ isec = bfd_und_section_ptr;
+ 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
+ isec = bfd_section_from_elf_index (input_bfd, isym->st_shndx);
+
+ *secpp = isec;
+ }
+
+ if (! elf32_cr16_relocate_section (output_bfd, link_info, input_bfd,
+ input_section, data, internal_relocs,
+ isymbuf, sections))
+ goto error_return;
+
+ if (sections != NULL)
+ free (sections);
+ if (isymbuf != NULL
+ && symtab_hdr->contents != (unsigned char *) isymbuf)
+ free (isymbuf);
+ if (elf_section_data (input_section)->relocs != internal_relocs)
+ free (internal_relocs);
+ }
+
+ return data;
+
+ error_return:
+ if (sections != NULL)
+ free (sections);
+ if (isymbuf != NULL
+ && symtab_hdr->contents != (unsigned char *) isymbuf)
+ free (isymbuf);
+ if (internal_relocs != NULL
+ && elf_section_data (input_section)->relocs != internal_relocs)
+ free (internal_relocs);
+ return NULL;
+}
+
+/* Assorted hash table functions. */
+
+/* Initialize an entry in the link hash table. */
+
+/* Create an entry in an CR16 ELF linker hash table. */
+
+static struct bfd_hash_entry *
+elf32_cr16_link_hash_newfunc (struct bfd_hash_entry *entry,
+ struct bfd_hash_table *table,
+ const char *string)
+{
+ struct elf32_cr16_link_hash_entry *ret =
+ (struct elf32_cr16_link_hash_entry *) entry;
+
+ /* Allocate the structure if it has not already been allocated by a
+ subclass. */
+ if (ret == (struct elf32_cr16_link_hash_entry *) NULL)
+ ret = ((struct elf32_cr16_link_hash_entry *)
+ bfd_hash_allocate (table,
+ sizeof (struct elf32_cr16_link_hash_entry)));
+ if (ret == (struct elf32_cr16_link_hash_entry *) NULL)
+ return (struct bfd_hash_entry *) ret;
+
+ /* Call the allocation method of the superclass. */
+ ret = ((struct elf32_cr16_link_hash_entry *)
+ _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry *) ret,
+ table, string));
+ if (ret != (struct elf32_cr16_link_hash_entry *) NULL)
+ {
+ ret->direct_calls = 0;
+ ret->stack_size = 0;
+ ret->movm_args = 0;
+ ret->movm_stack_size = 0;
+ ret->flags = 0;
+ ret->value = 0;
+ }
+
+ return (struct bfd_hash_entry *) ret;
+}
+
+/* Create an cr16 ELF linker hash table. */
+
+static struct bfd_link_hash_table *
+elf32_cr16_link_hash_table_create (bfd *abfd)
+{
+ struct elf_link_hash_table *ret;
+ bfd_size_type amt = sizeof (struct elf_link_hash_table);
+
+ ret = (struct elf_link_hash_table *) bfd_zmalloc (amt);
+ if (ret == (struct elf_link_hash_table *) NULL)
+ return NULL;
+
+ if (!_bfd_elf_link_hash_table_init (ret, abfd,
+ elf32_cr16_link_hash_newfunc,
+ sizeof (struct elf32_cr16_link_hash_entry),
+ GENERIC_ELF_DATA))
+ {
+ free (ret);
+ return NULL;
+ }
+
+ return &ret->root;
+}
+
+static unsigned long
+elf_cr16_mach (flagword flags)
+{
+ switch (flags)
+ {
+ case EM_CR16:
+ default:
+ return bfd_mach_cr16;
+ }
+}
+
+/* The final processing done just before writing out a CR16 ELF object
+ file. This gets the CR16 architecture right based on the machine
+ number. */
+
+static void
+_bfd_cr16_elf_final_write_processing (bfd *abfd,
+ bfd_boolean linker ATTRIBUTE_UNUSED)
+{
+ unsigned long val;
+ switch (bfd_get_mach (abfd))
+ {
+ default:
+ case bfd_mach_cr16:
+ val = EM_CR16;
+ break;
+ }
+
+
+ elf_elfheader (abfd)->e_flags |= val;
+}
+
+
+static bfd_boolean
+_bfd_cr16_elf_object_p (bfd *abfd)
+{
+ bfd_default_set_arch_mach (abfd, bfd_arch_cr16,
+ elf_cr16_mach (elf_elfheader (abfd)->e_flags));
+ return TRUE;
+}
+
+/* Merge backend specific data from an object file to the output
+ object file when linking. */
+
+static bfd_boolean
+_bfd_cr16_elf_merge_private_bfd_data (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;
+}
+
+
+/* This function handles relaxing for the CR16.
+
+ There's quite a few relaxing opportunites available on the CR16:
+
+ * bcond:24 -> bcond:16 1 byte
+ * bcond:16 -> bcond:8 1 byte
+ * arithmetic imm32 -> arithmetic imm20 12 bits
+ * arithmetic imm20/imm16 -> arithmetic imm4 12/16 bits
+
+ Symbol- and reloc-reading infrastructure copied from elf-m10200.c. */
+
+static bfd_boolean
+elf32_cr16_relax_section (bfd *abfd, asection *sec,
+ struct bfd_link_info *link_info, bfd_boolean *again)
+{
+ Elf_Internal_Shdr *symtab_hdr;
+ Elf_Internal_Rela *internal_relocs;
+ Elf_Internal_Rela *irel, *irelend;
+ bfd_byte *contents = NULL;
+ Elf_Internal_Sym *isymbuf = NULL;
+
+ /* Assume nothing changes. */
+ *again = FALSE;
+
+ /* We don't have to do anything for a relocatable link, if
+ this section does not have relocs, or if this is not a
+ code section. */
+ if (link_info->relocatable
+ || (sec->flags & SEC_RELOC) == 0
+ || sec->reloc_count == 0
+ || (sec->flags & SEC_CODE) == 0)
+ return TRUE;
+
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+
+ /* Get a copy of the native relocations. */
+ internal_relocs = _bfd_elf_link_read_relocs (abfd, sec, NULL, NULL,
+ link_info->keep_memory);
+ if (internal_relocs == NULL)
+ goto error_return;
+
+ /* 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_CR16_DISP16
+ && ELF32_R_TYPE (irel->r_info) != (int) R_CR16_DISP24
+ && ELF32_R_TYPE (irel->r_info) != (int) R_CR16_IMM32
+ && ELF32_R_TYPE (irel->r_info) != (int) R_CR16_IMM20
+ && ELF32_R_TYPE (irel->r_info) != (int) R_CR16_IMM16)
+ 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;
+ /* Go get them off disk. */
+ else if (!bfd_malloc_and_get_section (abfd, sec, &contents))
+ goto error_return;
+ }
+
+ /* Read this BFD's local symbols if we haven't done so already. */
+ if (isymbuf == NULL && symtab_hdr->sh_info != 0)
+ {
+ isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
+ if (isymbuf == NULL)
+ isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
+ symtab_hdr->sh_info, 0,
+ NULL, NULL, NULL);
+ if (isymbuf == NULL)
+ 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)
+ {
+ /* A local symbol. */
+ Elf_Internal_Sym *isym;
+ asection *sym_sec;
+
+ isym = isymbuf + ELF32_R_SYM (irel->r_info);
+ if (isym->st_shndx == SHN_UNDEF)
+ sym_sec = bfd_und_section_ptr;
+ 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;
+ else
+ 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 24 branch/call into a 16bit relative
+ branch/call. */
+ if (ELF32_R_TYPE (irel->r_info) == (int) R_CR16_DISP24)
+ {
+ bfd_vma value = symval;
+
+ /* 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
+ 0xfffe + 2 as the target will be two bytes closer if we are
+ able to relax. */
+ if ((long) value < 0x10000 && (long) value > -0x10002)
+ {
+ unsigned int code;
+
+ /* Get the opcode. */
+ code = (unsigned int) bfd_get_32 (abfd, contents + irel->r_offset);
+
+ /* Verify it's a 'bcond' and fix the opcode. */
+ if ((code & 0xffff) == 0x0010)
+ bfd_put_16 (abfd, 0x1800 | ((0xf & (code >> 20)) << 4), contents + irel->r_offset);
+ else
+ continue;
+
+ /* Note that we've changed the relocs, section contents, etc. */
+ elf_section_data (sec)->relocs = internal_relocs;
+ elf_section_data (sec)->this_hdr.contents = contents;
+ symtab_hdr->contents = (unsigned char *) isymbuf;
+
+ /* Fix the relocation's type. */
+ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
+ R_CR16_DISP16);
+
+ /* Delete two bytes of data. */
+ if (!elf32_cr16_relax_delete_bytes (link_info, 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;
+ }
+ }
+
+ /* Try to turn a 16bit pc-relative branch into an
+ 8bit pc-relative branch. */
+ if (ELF32_R_TYPE (irel->r_info) == (int) R_CR16_DISP16)
+ {
+ bfd_vma value = symval;
+
+ /* 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
+ 0xfc + 2 as the target will be two bytes closer if we are
+ able to relax. */
+ /*if ((long) value < 0x1fa && (long) value > -0x100) REVISIT:range */
+ if ((long) value < 0xfa && (long) value > -0x100)
+ {
+ unsigned short code;
+
+ /* Get the opcode. */
+ code = (unsigned short) bfd_get_16 (abfd, contents + irel->r_offset);
+
+ /* Verify it's a 'bcond' and fix the opcode. */
+ if ((code & 0xff0f) == 0x1800)
+ bfd_put_16 (abfd, (code & 0xf0f0), contents + irel->r_offset);
+ else
+ continue;
+
+ /* Note that we've changed the relocs, section contents, etc. */
+ elf_section_data (sec)->relocs = internal_relocs;
+ elf_section_data (sec)->this_hdr.contents = contents;
+ symtab_hdr->contents = (unsigned char *) isymbuf;
+
+ /* Fix the relocation's type. */
+ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
+ R_CR16_DISP8);
+
+ /* Delete two bytes of data. */
+ if (!elf32_cr16_relax_delete_bytes (link_info, 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;
+ }
+ }
+
+ /* Try to turn a 32-bit IMM address into a 20/16-bit IMM address */
+ if (ELF32_R_TYPE (irel->r_info) == (int) R_CR16_IMM32)
+ {
+ bfd_vma value = symval;
+ unsigned short is_add_mov = 0;
+ bfd_vma value1 = 0;
+
+ /* Get the existing value from the mcode */
+ value1 = ((bfd_get_32 (abfd, contents + irel->r_offset + 2) >> 16)
+ |(((bfd_get_32 (abfd, contents + irel->r_offset + 2) & 0xffff) << 16)));
+
+ /* See if the value will fit in 20 bits. */
+ if ((long) (value + value1) < 0xfffff && (long) (value + value1) > 0)
+ {
+ unsigned short code;
+
+ /* Get the opcode. */
+ code = (unsigned short) bfd_get_16 (abfd, contents + irel->r_offset);
+
+ /* Verify it's a 'arithmetic ADDD or MOVD instruction'.
+ For ADDD and MOVD only, convert to IMM32 -> IMM20. */
+
+ if (((code & 0xfff0) == 0x0070) || ((code & 0xfff0) == 0x0020))
+ is_add_mov = 1;
+
+ if (is_add_mov)
+ {
+ /* Note that we've changed the relocs, section contents,
+ etc. */
+ elf_section_data (sec)->relocs = internal_relocs;
+ elf_section_data (sec)->this_hdr.contents = contents;
+ symtab_hdr->contents = (unsigned char *) isymbuf;
+
+ /* Fix the opcode. */
+ if ((code & 0xfff0) == 0x0070) /* For movd. */
+ bfd_put_8 (abfd, 0x05, contents + irel->r_offset + 1);
+ else /* code == 0x0020 for addd. */
+ bfd_put_8 (abfd, 0x04, contents + irel->r_offset + 1);
+
+ bfd_put_8 (abfd, (code & 0xf) << 4, contents + irel->r_offset);
+
+ /* If existing value is nagavive adjust approriately
+ place the 16-20bits (ie 4 bit) in new opcode,
+ as the 0xffffxxxx, the higher 2 byte values removed. */
+ if (value1 & 0x80000000)
+ bfd_put_8 (abfd, (0x0f | (bfd_get_8(abfd, contents + irel->r_offset))), contents + irel->r_offset);
+ else
+ bfd_put_8 (abfd, (((value1 >> 16)&0xf) | (bfd_get_8(abfd, contents + irel->r_offset))), contents + irel->r_offset);
+
+ /* Fix the relocation's type. */
+ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
+ R_CR16_IMM20);
+
+ /* Delete two bytes of data. */
+ if (!elf32_cr16_relax_delete_bytes (link_info, 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;
+ }
+ }
+
+ /* See if the value will fit in 16 bits. */
+ if ((!is_add_mov)
+ && ((long)(value + value1) < 0x7fff && (long)(value + value1) > 0))
+ {
+ unsigned short code;
+
+ /* Get the opcode. */
+ code = (unsigned short) bfd_get_16 (abfd, contents + irel->r_offset);
+
+ /* Note that we've changed the relocs, section contents, etc. */
+ elf_section_data (sec)->relocs = internal_relocs;
+ elf_section_data (sec)->this_hdr.contents = contents;
+ symtab_hdr->contents = (unsigned char *) isymbuf;
+
+ /* Fix the opcode. */
+ if ((code & 0xf0) == 0x70) /* For movd. */
+ bfd_put_8 (abfd, 0x54, contents + irel->r_offset + 1);
+ else if ((code & 0xf0) == 0x20) /* For addd. */
+ bfd_put_8 (abfd, 0x60, contents + irel->r_offset + 1);
+ else if ((code & 0xf0) == 0x90) /* For cmpd. */
+ bfd_put_8 (abfd, 0x56, contents + irel->r_offset + 1);
+ else
+ continue;
+
+ bfd_put_8 (abfd, 0xb0 | (code & 0xf), contents + irel->r_offset);
+
+ /* If existing value is nagavive adjust approriately
+ place the 12-16bits (ie 4 bit) in new opcode,
+ as the 0xfffffxxx, the higher 2 byte values removed. */
+ if (value1 & 0x80000000)
+ bfd_put_8 (abfd, (0x0f | (bfd_get_8(abfd, contents + irel->r_offset))), contents + irel->r_offset);
+ else
+ bfd_put_16 (abfd, value1, contents + irel->r_offset + 2);
+
+
+ /* Fix the relocation's type. */
+ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
+ R_CR16_IMM16);
+
+ /* Delete two bytes of data. */
+ if (!elf32_cr16_relax_delete_bytes (link_info, 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;
+ }
+ }
+
+#if 0
+ /* Try to turn a 16bit immediate address into a 4bit
+ immediate address. */
+ if ((ELF32_R_TYPE (irel->r_info) == (int) R_CR16_IMM20)
+ || (ELF32_R_TYPE (irel->r_info) == (int) R_CR16_IMM16))
+ {
+ bfd_vma value = symval;
+ bfd_vma value1 = 0;
+
+ /* Get the existing value from the mcode */
+ value1 = ((bfd_get_16 (abfd, contents + irel->r_offset + 2) & 0xffff));
+
+ if (ELF32_R_TYPE (irel->r_info) == (int) R_CR16_IMM20)
+ {
+ value1 |= ((bfd_get_16 (abfd, contents + irel->r_offset + 1) & 0xf000) << 0x4);
+ }
+
+ /* See if the value will fit in 4 bits. */
+ if ((((long) (value + value1)) < 0xf)
+ && (((long) (value + value1)) > 0))
+ {
+ unsigned short code;
+
+ /* Get the opcode. */
+ code = (unsigned short) bfd_get_16 (abfd, contents + irel->r_offset);
+
+ /* Note that we've changed the relocs, section contents, etc. */
+ elf_section_data (sec)->relocs = internal_relocs;
+ elf_section_data (sec)->this_hdr.contents = contents;
+ symtab_hdr->contents = (unsigned char *) isymbuf;
+
+ /* Fix the opcode. */
+ if (((code & 0x0f00) == 0x0400) || ((code & 0x0f00) == 0x0500))
+ {
+ if ((code & 0x0f00) == 0x0400) /* For movd imm20. */
+ bfd_put_8 (abfd, 0x60, contents + irel->r_offset);
+ else /* For addd imm20. */
+ bfd_put_8 (abfd, 0x54, contents + irel->r_offset);
+ bfd_put_8 (abfd, (code & 0xf0) >> 4, contents + irel->r_offset + 1);
+ }
+ else
+ {
+ if ((code & 0xfff0) == 0x56b0) /* For cmpd imm16. */
+ bfd_put_8 (abfd, 0x56, contents + irel->r_offset);
+ else if ((code & 0xfff0) == 0x54b0) /* For movd imm16. */
+ bfd_put_8 (abfd, 0x54, contents + irel->r_offset);
+ else if ((code & 0xfff0) == 0x58b0) /* For movb imm16. */
+ bfd_put_8 (abfd, 0x58, contents + irel->r_offset);
+ else if ((code & 0xfff0) == 0x5Ab0) /* For movw imm16. */
+ bfd_put_8 (abfd, 0x5A, contents + irel->r_offset);
+ else if ((code & 0xfff0) == 0x60b0) /* For addd imm16. */
+ bfd_put_8 (abfd, 0x60, contents + irel->r_offset);
+ else if ((code & 0xfff0) == 0x30b0) /* For addb imm16. */
+ bfd_put_8 (abfd, 0x30, contents + irel->r_offset);
+ else if ((code & 0xfff0) == 0x2Cb0) /* For addub imm16. */
+ bfd_put_8 (abfd, 0x2C, contents + irel->r_offset);
+ else if ((code & 0xfff0) == 0x32b0) /* For adduw imm16. */
+ bfd_put_8 (abfd, 0x32, contents + irel->r_offset);
+ else if ((code & 0xfff0) == 0x38b0) /* For subb imm16. */
+ bfd_put_8 (abfd, 0x38, contents + irel->r_offset);
+ else if ((code & 0xfff0) == 0x3Cb0) /* For subcb imm16. */
+ bfd_put_8 (abfd, 0x3C, contents + irel->r_offset);
+ else if ((code & 0xfff0) == 0x3Fb0) /* For subcw imm16. */
+ bfd_put_8 (abfd, 0x3F, contents + irel->r_offset);
+ else if ((code & 0xfff0) == 0x3Ab0) /* For subw imm16. */
+ bfd_put_8 (abfd, 0x3A, contents + irel->r_offset);
+ else if ((code & 0xfff0) == 0x50b0) /* For cmpb imm16. */
+ bfd_put_8 (abfd, 0x50, contents + irel->r_offset);
+ else if ((code & 0xfff0) == 0x52b0) /* For cmpw imm16. */
+ bfd_put_8 (abfd, 0x52, contents + irel->r_offset);
+ else
+ continue;
+
+ bfd_put_8 (abfd, (code & 0xf), contents + irel->r_offset + 1);
+ }
+
+ /* Fix the relocation's type. */
+ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
+ R_CR16_IMM4);
+
+ /* Delete two bytes of data. */
+ if (!elf32_cr16_relax_delete_bytes (link_info, 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;
+ }
+ }
+#endif
+ }
+
+ if (isymbuf != NULL
+ && symtab_hdr->contents != (unsigned char *) isymbuf)
+ {
+ if (! link_info->keep_memory)
+ free (isymbuf);
+ else
+ /* Cache the symbols for elf_link_input_bfd. */
+ symtab_hdr->contents = (unsigned char *) isymbuf;
+ }
+
+ if (contents != NULL
+ && elf_section_data (sec)->this_hdr.contents != contents)
+ {
+ if (! link_info->keep_memory)
+ free (contents);
+ else
+ /* Cache the section contents for elf_link_input_bfd. */
+ elf_section_data (sec)->this_hdr.contents = contents;
+
+ }
+
+ if (internal_relocs != NULL
+ && elf_section_data (sec)->relocs != internal_relocs)
+ free (internal_relocs);
+
+ return TRUE;
+
+ error_return:
+ if (isymbuf != NULL
+ && symtab_hdr->contents != (unsigned char *) isymbuf)
+ free (isymbuf);
+ if (contents != NULL
+ && elf_section_data (sec)->this_hdr.contents != contents)
+ free (contents);
+ if (internal_relocs != NULL
+ && elf_section_data (sec)->relocs != internal_relocs)
+ free (internal_relocs);
+
+ return FALSE;
+}
+
+static asection *
+elf32_cr16_gc_mark_hook (asection *sec,
+ struct bfd_link_info *info,
+ Elf_Internal_Rela *rel,
+ struct elf_link_hash_entry *h,
+ Elf_Internal_Sym *sym)
+{
+ return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
+}
+
+/* Update the got entry reference counts for the section being removed. */
+
+static bfd_boolean
+elf32_cr16_gc_sweep_hook (bfd *abfd ATTRIBUTE_UNUSED,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ asection *sec ATTRIBUTE_UNUSED,
+ const Elf_Internal_Rela *relocs ATTRIBUTE_UNUSED)
+{
+ /* We don't support garbage collection of GOT and PLT relocs yet. */
+ return TRUE;
+}
+
+/* Create dynamic sections when linking against a dynamic object. */
+
+static bfd_boolean
+_bfd_cr16_elf_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
+{
+ flagword flags;
+ asection * s;
+ const struct elf_backend_data * bed = get_elf_backend_data (abfd);
+ int ptralign = 0;
+
+ switch (bed->s->arch_size)
+ {
+ case 16:
+ ptralign = 1;
+ break;
+
+ case 32:
+ ptralign = 2;
+ break;
+
+ default:
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+
+ /* 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);
+
+ s = bfd_make_section_anyway_with_flags (abfd,
+ (bed->default_use_rela_p
+ ? ".rela.plt" : ".rel.plt"),
+ flags | SEC_READONLY);
+ if (s == NULL
+ || ! bfd_set_section_alignment (abfd, s, ptralign))
+ return FALSE;
+
+ if (! _bfd_cr16_elf_create_got_section (abfd, info))
+ return FALSE;
+
+ if (bed->want_dynbss)
+ {
+ /* 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_anyway_with_flags (abfd, ".dynbss",
+ SEC_ALLOC | SEC_LINKER_CREATED);
+ if (s == NULL)
+ 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->executable)
+ {
+ s = bfd_make_section_anyway_with_flags (abfd,
+ (bed->default_use_rela_p
+ ? ".rela.bss" : ".rel.bss"),
+ flags | SEC_READONLY);
+ if (s == NULL
+ || ! bfd_set_section_alignment (abfd, s, ptralign))
+ 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 bfd_boolean
+_bfd_cr16_elf_adjust_dynamic_symbol (struct bfd_link_info * info,
+ struct elf_link_hash_entry * h)
+{
+ bfd * dynobj;
+ asection * s;
+
+ dynobj = elf_hash_table (info)->dynobj;
+
+ /* Make sure we know what is going on here. */
+ BFD_ASSERT (dynobj != NULL
+ && (h->needs_plt
+ || h->u.weakdef != NULL
+ || (h->def_dynamic
+ && h->ref_regular
+ && !h->def_regular)));
+
+ /* 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->needs_plt)
+ {
+ if (! info->executable
+ && !h->def_dynamic
+ && !h->ref_dynamic)
+ {
+ /* This case can occur if we saw a PLT 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 REL32
+ reloc instead. */
+ BFD_ASSERT (h->needs_plt);
+ return TRUE;
+ }
+
+ /* Make sure this symbol is output as a dynamic symbol. */
+ if (h->dynindx == -1)
+ {
+ if (! bfd_elf_link_record_dynamic_symbol (info, h))
+ return FALSE;
+ }
+
+ /* 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_linker_section (dynobj, ".got.plt");
+ BFD_ASSERT (s != NULL);
+ s->size += 4;
+
+ /* We also need to make an entry in the .rela.plt section. */
+
+ s = bfd_get_linker_section (dynobj, ".rela.plt");
+ BFD_ASSERT (s != NULL);
+ s->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->u.weakdef != NULL)
+ {
+ BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
+ || h->u.weakdef->root.type == bfd_link_hash_defweak);
+ h->root.u.def.section = h->u.weakdef->root.u.def.section;
+ h->root.u.def.value = h->u.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->executable)
+ return TRUE;
+
+ /* If there are no references to this symbol that do not use the
+ GOT, we don't need to generate a copy reloc. */
+ if (!h->non_got_ref)
+ 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_linker_section (dynobj, ".dynbss");
+ BFD_ASSERT (s != NULL);
+
+ /* We must generate a R_CR16_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 && h->size != 0)
+ {
+ asection * srel;
+
+ srel = bfd_get_linker_section (dynobj, ".rela.bss");
+ BFD_ASSERT (srel != NULL);
+ srel->size += sizeof (Elf32_External_Rela);
+ h->needs_copy = 1;
+ }
+
+ return _bfd_elf_adjust_dynamic_copy (h, s);
+}
+
+/* Set the sizes of the dynamic sections. */
+
+static bfd_boolean
+_bfd_cr16_elf_size_dynamic_sections (bfd * output_bfd,
+ struct bfd_link_info * info)
+{
+ bfd * dynobj;
+ asection * s;
+ bfd_boolean plt;
+ bfd_boolean relocs;
+ bfd_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->executable)
+ {
+#if 0
+ s = bfd_get_linker_section (dynobj, ".interp");
+ BFD_ASSERT (s != NULL);
+ s->size = sizeof ELF_DYNAMIC_INTERPRETER;
+ s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
+#endif
+ }
+ }
+ 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_linker_section (dynobj, ".rela.got");
+ if (s != NULL)
+ s->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;
+
+ 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);
+
+ if (strcmp (name, ".plt") == 0)
+ {
+ /* Remember whether there is a PLT. */
+ plt = s->size != 0;
+ }
+ else if (CONST_STRNEQ (name, ".rela"))
+ {
+ if (s->size != 0)
+ {
+ 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. The entries in the .rela.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 + 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 (! CONST_STRNEQ (name, ".got")
+ && strcmp (name, ".dynbss") != 0)
+ /* It's not one of our sections, so don't allocate space. */
+ continue;
+
+ if (s->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. */
+ s->flags |= SEC_EXCLUDE;
+ continue;
+ }
+
+ if ((s->flags & SEC_HAS_CONTENTS) == 0)
+ continue;
+
+ /* Allocate memory for the section contents. We use bfd_zalloc
+ here in case unused entries are not reclaimed before the
+ section's contents are written out. This should not happen,
+ but this way if it does, we get a R_CR16_NONE reloc
+ instead of garbage. */
+ s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->size);
+ if (s->contents == NULL)
+ return FALSE;
+ }
+
+ if (elf_hash_table (info)->dynamic_sections_created)
+ {
+ /* Add some entries to the .dynamic section. We fill in the
+ values later, in _bfd_cr16_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->executable)
+ {
+ if (!_bfd_elf_add_dynamic_entry (info, DT_DEBUG, 0))
+ return FALSE;
+ }
+
+ if (plt)
+ {
+ if (!_bfd_elf_add_dynamic_entry (info, DT_PLTGOT, 0)
+ || !_bfd_elf_add_dynamic_entry (info, DT_PLTRELSZ, 0)
+ || !_bfd_elf_add_dynamic_entry (info, DT_PLTREL, DT_RELA)
+ || !_bfd_elf_add_dynamic_entry (info, DT_JMPREL, 0))
+ return FALSE;
+ }
+
+ if (relocs)
+ {
+ if (!_bfd_elf_add_dynamic_entry (info, DT_RELA, 0)
+ || !_bfd_elf_add_dynamic_entry (info, DT_RELASZ, 0)
+ || !_bfd_elf_add_dynamic_entry (info, DT_RELAENT,
+ sizeof (Elf32_External_Rela)))
+ return FALSE;
+ }
+
+ if (reltext)
+ {
+ if (!_bfd_elf_add_dynamic_entry (info, DT_TEXTREL, 0))
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+/* Finish up dynamic symbol handling. We set the contents of various
+ dynamic sections here. */
+
+static bfd_boolean
+_bfd_cr16_elf_finish_dynamic_symbol (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->got.offset != (bfd_vma) -1)
+ {
+ asection * sgot;
+ asection * srel;
+ Elf_Internal_Rela rel;
+
+ /* This symbol has an entry in the global offset table. Set it up. */
+
+ sgot = bfd_get_linker_section (dynobj, ".got");
+ srel = bfd_get_linker_section (dynobj, ".rela.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->executable
+ && (info->symbolic || h->dynindx == -1)
+ && h->def_regular)
+ {
+ rel.r_info = ELF32_R_INFO (0, R_CR16_GOT_REGREL20);
+ rel.r_addend = (h->root.u.def.value
+ + h->root.u.def.section->output_section->vma
+ + h->root.u.def.section->output_offset);
+ }
+ else
+ {
+ bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents + h->got.offset);
+ rel.r_info = ELF32_R_INFO (h->dynindx, R_CR16_GOT_REGREL20);
+ rel.r_addend = 0;
+ }
+
+ bfd_elf32_swap_reloca_out (output_bfd, &rel,
+ (bfd_byte *) ((Elf32_External_Rela *) srel->contents
+ + srel->reloc_count));
+ ++ srel->reloc_count;
+ }
+
+ if (h->needs_copy)
+ {
+ asection * s;
+ Elf_Internal_Rela 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_linker_section (dynobj, ".rela.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_CR16_GOT_REGREL20);
+ rel.r_addend = 0;
+ bfd_elf32_swap_reloca_out (output_bfd, &rel,
+ (bfd_byte *) ((Elf32_External_Rela *) s->contents
+ + s->reloc_count));
+ ++ s->reloc_count;
+ }
+
+ /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute. */
+ if (h == elf_hash_table (info)->hdynamic
+ || h == elf_hash_table (info)->hgot)
+ sym->st_shndx = SHN_ABS;
+
+ return TRUE;
+}
+
+/* Finish up the dynamic sections. */
+
+static bfd_boolean
+_bfd_cr16_elf_finish_dynamic_sections (bfd * output_bfd,
+ struct bfd_link_info * info)
+{
+ bfd * dynobj;
+ asection * sgot;
+ asection * sdyn;
+
+ dynobj = elf_hash_table (info)->dynobj;
+
+ sgot = bfd_get_linker_section (dynobj, ".got.plt");
+ BFD_ASSERT (sgot != NULL);
+ sdyn = bfd_get_linker_section (dynobj, ".dynamic");
+
+ if (elf_hash_table (info)->dynamic_sections_created)
+ {
+ Elf32_External_Dyn * dyncon;
+ Elf32_External_Dyn * dynconend;
+
+ BFD_ASSERT (sdyn != NULL);
+
+ dyncon = (Elf32_External_Dyn *) sdyn->contents;
+ dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->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);
+ dyn.d_un.d_val = s->size;
+ bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
+ break;
+
+ case DT_RELASZ:
+ /* My reading of the SVR4 ABI indicates that the
+ procedure linkage table relocs (DT_JMPREL) should be
+ included in the overall relocs (DT_RELA). This is
+ what Solaris does. However, UnixWare can not handle
+ that case. 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)
+ dyn.d_un.d_val -= s->size;
+ bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
+ break;
+ }
+ }
+
+ }
+
+ /* Fill in the first three entries in the global offset table. */
+ if (sgot->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;
+
+ return TRUE;
+}
+
+/* Given a .data.rel section and a .emreloc in-memory section, store
+ relocation information into the .emreloc 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. */
+
+bfd_boolean
+bfd_cr16_elf32_create_embedded_relocs (bfd *abfd,
+ struct bfd_link_info *info,
+ asection *datasec,
+ asection *relsec,
+ char **errmsg)
+{
+ Elf_Internal_Shdr *symtab_hdr;
+ Elf_Internal_Sym *isymbuf = NULL;
+ Elf_Internal_Rela *internal_relocs = NULL;
+ Elf_Internal_Rela *irel, *irelend;
+ bfd_byte *p;
+ bfd_size_type amt;
+
+ BFD_ASSERT (! info->relocatable);
+
+ *errmsg = NULL;
+
+ if (datasec->reloc_count == 0)
+ return TRUE;
+
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+
+ /* Get a copy of the native relocations. */
+ internal_relocs = (_bfd_elf_link_read_relocs
+ (abfd, datasec, NULL, NULL, info->keep_memory));
+ if (internal_relocs == NULL)
+ goto error_return;
+
+ amt = (bfd_size_type) datasec->reloc_count * 8;
+ relsec->contents = (bfd_byte *) bfd_alloc (abfd, amt);
+ if (relsec->contents == NULL)
+ goto error_return;
+
+ p = relsec->contents;
+
+ irelend = internal_relocs + datasec->reloc_count;
+ for (irel = internal_relocs; irel < irelend; irel++, p += 8)
+ {
+ asection *targetsec;
+
+ /* We are going to write a four byte longword into the runtime
+ reloc section. The longword will be the address in the data
+ section which must be relocated. It is followed by the name
+ of the target section NUL-padded or truncated to 8
+ characters. */
+
+ /* We can only relocate absolute longword relocs at run time. */
+ if (!((ELF32_R_TYPE (irel->r_info) == (int) R_CR16_NUM32a)
+ || (ELF32_R_TYPE (irel->r_info) == (int) R_CR16_NUM32)))
+ {
+ *errmsg = _("unsupported reloc type");
+ bfd_set_error (bfd_error_bad_value);
+ goto error_return;
+ }
+
+ /* Get the target section referred to by the reloc. */
+ if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
+ {
+ /* A local symbol. */
+ Elf_Internal_Sym *isym;
+
+ /* Read this BFD's local symbols if we haven't done so already. */
+ if (isymbuf == NULL)
+ {
+ isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
+ if (isymbuf == NULL)
+ isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
+ symtab_hdr->sh_info, 0,
+ NULL, NULL, NULL);
+ if (isymbuf == NULL)
+ goto error_return;
+ }
+
+ isym = isymbuf + ELF32_R_SYM (irel->r_info);
+ targetsec = bfd_section_from_elf_index (abfd, isym->st_shndx);
+ }
+ 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)
+ targetsec = h->root.u.def.section;
+ else
+ targetsec = NULL;
+ }
+
+ bfd_put_32 (abfd, irel->r_offset + datasec->output_offset, p);
+ memset (p + 4, 0, 4);
+ if ((ELF32_R_TYPE (irel->r_info) == (int) R_CR16_NUM32a)
+ && (targetsec != NULL) )
+ strncpy ((char *) p + 4, targetsec->output_section->name, 4);
+ }
+
+ if (isymbuf != NULL && symtab_hdr->contents != (unsigned char *) isymbuf)
+ free (isymbuf);
+ if (internal_relocs != NULL
+ && elf_section_data (datasec)->relocs != internal_relocs)
+ free (internal_relocs);
+ return TRUE;
+
+error_return:
+ if (isymbuf != NULL && symtab_hdr->contents != (unsigned char *) isymbuf)
+ free (isymbuf);
+ if (internal_relocs != NULL
+ && elf_section_data (datasec)->relocs != internal_relocs)
+ free (internal_relocs);
+ return FALSE;
+}
+
+
+/* Classify relocation types, such that combreloc can sort them
+ properly. */
+
+static enum elf_reloc_type_class
+_bfd_cr16_elf_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ const asection *rel_sec ATTRIBUTE_UNUSED,
+ const Elf_Internal_Rela *rela)
+{
+ switch ((int) ELF32_R_TYPE (rela->r_info))
+ {
+ case R_CR16_GOT_REGREL20:
+ case R_CR16_GOTC_REGREL20:
+ return reloc_class_relative;
+ default:
+ return reloc_class_normal;
+ }
+}
+
+/* Definitions for setting CR16 target vector. */
+#define TARGET_LITTLE_SYM cr16_elf32_vec
+#define TARGET_LITTLE_NAME "elf32-cr16"
+#define ELF_ARCH bfd_arch_cr16
+#define ELF_MACHINE_CODE EM_CR16
+#define ELF_MACHINE_ALT1 EM_CR16_OLD
+#define ELF_MAXPAGESIZE 0x1
+#define elf_symbol_leading_char '_'
+
+#define bfd_elf32_bfd_reloc_type_lookup elf_cr16_reloc_type_lookup
+#define bfd_elf32_bfd_reloc_name_lookup elf_cr16_reloc_name_lookup
+#define elf_info_to_howto elf_cr16_info_to_howto
+#define elf_info_to_howto_rel 0
+#define elf_backend_relocate_section elf32_cr16_relocate_section
+#define bfd_elf32_bfd_relax_section elf32_cr16_relax_section
+#define bfd_elf32_bfd_get_relocated_section_contents \
+ elf32_cr16_get_relocated_section_contents
+#define elf_backend_gc_mark_hook elf32_cr16_gc_mark_hook
+#define elf_backend_gc_sweep_hook elf32_cr16_gc_sweep_hook
+#define elf_backend_can_gc_sections 1
+#define elf_backend_rela_normal 1
+#define elf_backend_check_relocs cr16_elf_check_relocs
+/* So we can set bits in e_flags. */
+#define elf_backend_final_write_processing \
+ _bfd_cr16_elf_final_write_processing
+#define elf_backend_object_p _bfd_cr16_elf_object_p
+
+#define bfd_elf32_bfd_merge_private_bfd_data \
+ _bfd_cr16_elf_merge_private_bfd_data
+
+
+#define bfd_elf32_bfd_link_hash_table_create \
+ elf32_cr16_link_hash_table_create
+
+#define elf_backend_create_dynamic_sections \
+ _bfd_cr16_elf_create_dynamic_sections
+#define elf_backend_adjust_dynamic_symbol \
+ _bfd_cr16_elf_adjust_dynamic_symbol
+#define elf_backend_size_dynamic_sections \
+ _bfd_cr16_elf_size_dynamic_sections
+#define elf_backend_omit_section_dynsym \
+ ((bfd_boolean (*) (bfd *, struct bfd_link_info *, asection *)) bfd_true)
+#define elf_backend_finish_dynamic_symbol \
+ _bfd_cr16_elf_finish_dynamic_symbol
+#define elf_backend_finish_dynamic_sections \
+ _bfd_cr16_elf_finish_dynamic_sections
+
+#define elf_backend_reloc_type_class _bfd_cr16_elf_reloc_type_class
+
+
+#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
+
+#include "elf32-target.h"
diff --git a/bfd/elf32-cr16c.c b/bfd/elf32-cr16c.c
new file mode 100644
index 0000000..cf4503c
--- /dev/null
+++ b/bfd/elf32-cr16c.c
@@ -0,0 +1,961 @@
+/* BFD back-end for National Semiconductor's CR16C ELF
+ Copyright (C) 2004-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+#include "bfdlink.h"
+#include "elf/cr16c.h"
+#include "elf-bfd.h"
+
+
+#define USE_REL 1 /* CR16C uses REL relocations instead of RELA. */
+
+/* The following definition is based on EMPTY_HOWTO macro,
+ but also initiates the "name" field in HOWTO struct. */
+#define ONLY_NAME_HOWTO(C) \
+ HOWTO ((C), 0, 0, 0, FALSE, 0, complain_overflow_dont, NULL, \
+ STRINGX(C), FALSE, 0, 0, FALSE)
+
+/* reloc_map_index array maps CRASM relocation type into a BFD
+ relocation enum. The array's indices are synchronized with
+ RINDEX_16C_* indices, created in include/elf/cr16c.h.
+ The array is used in:
+ 1. elf32-cr16c.c : elf_cr16c_reloc_type_lookup().
+ 2. asreloc.c : find_reloc_type(). */
+
+RELOC_MAP reloc_map_index[RINDEX_16C_MAX] =
+{
+ {R_16C_NUM08, BFD_RELOC_16C_NUM08},
+ {R_16C_NUM08_C, BFD_RELOC_16C_NUM08_C},
+ {R_16C_NUM16, BFD_RELOC_16C_NUM16},
+ {R_16C_NUM16_C, BFD_RELOC_16C_NUM16_C},
+ {R_16C_NUM32, BFD_RELOC_16C_NUM32},
+ {R_16C_NUM32_C, BFD_RELOC_16C_NUM32_C},
+ {R_16C_DISP04, BFD_RELOC_16C_DISP04},
+ {R_16C_DISP04_C, BFD_RELOC_16C_DISP04_C},
+ {R_16C_DISP08, BFD_RELOC_16C_DISP08},
+ {R_16C_DISP08_C, BFD_RELOC_16C_DISP08_C},
+ {R_16C_DISP16, BFD_RELOC_16C_DISP16},
+ {R_16C_DISP16_C, BFD_RELOC_16C_DISP16_C},
+ {R_16C_DISP24, BFD_RELOC_16C_DISP24},
+ {R_16C_DISP24_C, BFD_RELOC_16C_DISP24_C},
+ {R_16C_DISP24a, BFD_RELOC_16C_DISP24a},
+ {R_16C_DISP24a_C, BFD_RELOC_16C_DISP24a_C},
+ {R_16C_REG04, BFD_RELOC_16C_REG04},
+ {R_16C_REG04_C, BFD_RELOC_16C_REG04_C},
+ {R_16C_REG04a, BFD_RELOC_16C_REG04a},
+ {R_16C_REG04a_C, BFD_RELOC_16C_REG04a_C},
+ {R_16C_REG14, BFD_RELOC_16C_REG14},
+ {R_16C_REG14_C, BFD_RELOC_16C_REG14_C},
+ {R_16C_REG16, BFD_RELOC_16C_REG16},
+ {R_16C_REG16_C, BFD_RELOC_16C_REG16_C},
+ {R_16C_REG20, BFD_RELOC_16C_REG20},
+ {R_16C_REG20_C, BFD_RELOC_16C_REG20_C},
+ {R_16C_ABS20, BFD_RELOC_16C_ABS20},
+ {R_16C_ABS20_C, BFD_RELOC_16C_ABS20_C},
+ {R_16C_ABS24, BFD_RELOC_16C_ABS24},
+ {R_16C_ABS24_C, BFD_RELOC_16C_ABS24_C},
+ {R_16C_IMM04, BFD_RELOC_16C_IMM04},
+ {R_16C_IMM04_C, BFD_RELOC_16C_IMM04_C},
+ {R_16C_IMM16, BFD_RELOC_16C_IMM16},
+ {R_16C_IMM16_C, BFD_RELOC_16C_IMM16_C},
+ {R_16C_IMM20, BFD_RELOC_16C_IMM20},
+ {R_16C_IMM20_C, BFD_RELOC_16C_IMM20_C},
+ {R_16C_IMM24, BFD_RELOC_16C_IMM24},
+ {R_16C_IMM24_C, BFD_RELOC_16C_IMM24_C},
+ {R_16C_IMM32, BFD_RELOC_16C_IMM32},
+ {R_16C_IMM32_C, BFD_RELOC_16C_IMM32_C}
+};
+
+static reloc_howto_type elf_howto_table[] =
+{
+ /* 00 */ ONLY_NAME_HOWTO (RINDEX_16C_NUM08),
+ /* 01 */ ONLY_NAME_HOWTO (RINDEX_16C_NUM08_C),
+ /* 02 */ ONLY_NAME_HOWTO (RINDEX_16C_NUM16),
+ /* 03 */ ONLY_NAME_HOWTO (RINDEX_16C_NUM16_C),
+ /* 04 */ ONLY_NAME_HOWTO (RINDEX_16C_NUM32),
+ /* 05 */ ONLY_NAME_HOWTO (RINDEX_16C_NUM32_C),
+ /* 06 */ ONLY_NAME_HOWTO (RINDEX_16C_DISP04),
+ /* 07 */ ONLY_NAME_HOWTO (RINDEX_16C_DISP04_C),
+ /* 08 */ ONLY_NAME_HOWTO (RINDEX_16C_DISP08),
+ /* 09 */ ONLY_NAME_HOWTO (RINDEX_16C_DISP08_C),
+ /* 10 */ ONLY_NAME_HOWTO (RINDEX_16C_DISP16),
+ /* 11 */ ONLY_NAME_HOWTO (RINDEX_16C_DISP16_C),
+ /* 12 */ ONLY_NAME_HOWTO (RINDEX_16C_DISP24),
+ /* 13 */ ONLY_NAME_HOWTO (RINDEX_16C_DISP24_C),
+ /* 14 */ ONLY_NAME_HOWTO (RINDEX_16C_DISP24a),
+ /* 15 */ ONLY_NAME_HOWTO (RINDEX_16C_DISP24a_C),
+ /* 16 */ ONLY_NAME_HOWTO (RINDEX_16C_REG04),
+ /* 17 */ ONLY_NAME_HOWTO (RINDEX_16C_REG04_C),
+ /* 18 */ ONLY_NAME_HOWTO (RINDEX_16C_REG04a),
+ /* 19 */ ONLY_NAME_HOWTO (RINDEX_16C_REG04a_C),
+ /* 20 */ ONLY_NAME_HOWTO (RINDEX_16C_REG14),
+ /* 21 */ ONLY_NAME_HOWTO (RINDEX_16C_REG14_C),
+ /* 22 */ ONLY_NAME_HOWTO (RINDEX_16C_REG16),
+ /* 23 */ ONLY_NAME_HOWTO (RINDEX_16C_REG16_C),
+ /* 24 */ ONLY_NAME_HOWTO (RINDEX_16C_REG20),
+ /* 25 */ ONLY_NAME_HOWTO (RINDEX_16C_REG20_C),
+ /* 26 */ ONLY_NAME_HOWTO (RINDEX_16C_ABS20),
+ /* 27 */ ONLY_NAME_HOWTO (RINDEX_16C_ABS20_C),
+ /* 28 */ ONLY_NAME_HOWTO (RINDEX_16C_ABS24),
+ /* 29 */ ONLY_NAME_HOWTO (RINDEX_16C_ABS24_C),
+ /* 30 */ ONLY_NAME_HOWTO (RINDEX_16C_IMM04),
+ /* 31 */ ONLY_NAME_HOWTO (RINDEX_16C_IMM04_C),
+ /* 32 */ ONLY_NAME_HOWTO (RINDEX_16C_IMM16),
+ /* 33 */ ONLY_NAME_HOWTO (RINDEX_16C_IMM16_C),
+ /* 34 */ ONLY_NAME_HOWTO (RINDEX_16C_IMM20),
+ /* 35 */ ONLY_NAME_HOWTO (RINDEX_16C_IMM20_C),
+ /* 36 */ ONLY_NAME_HOWTO (RINDEX_16C_IMM24),
+ /* 37 */ ONLY_NAME_HOWTO (RINDEX_16C_IMM24_C),
+ /* 38 */ ONLY_NAME_HOWTO (RINDEX_16C_IMM32),
+ /* 39 */ ONLY_NAME_HOWTO (RINDEX_16C_IMM32_C)
+};
+
+
+/* Code to turn a code_type into a howto ptr, uses the above howto table. */
+
+static reloc_howto_type *
+elf_cr16c_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ bfd_reloc_code_real_type code)
+{
+ unsigned int i;
+
+ for (i = 0; i < RINDEX_16C_MAX; i++)
+ {
+ if (code == reloc_map_index[i].bfd_reloc_enum)
+ {
+ /* printf ("CR16C Relocation Type is - %x\n", code); */
+ return & elf_howto_table[i];
+ }
+ }
+
+ /* printf ("This relocation Type is not supported - %x\n", code); */
+ return 0;
+}
+
+static reloc_howto_type *
+elf_cr16c_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ const char *r_name)
+{
+ unsigned int i;
+
+ for (i = 0; i < sizeof (elf_howto_table) / sizeof (elf_howto_table[0]); i++)
+ if (elf_howto_table[i].name != NULL
+ && strcasecmp (elf_howto_table[i].name, r_name) == 0)
+ return &elf_howto_table[i];
+
+ return NULL;
+}
+
+static void
+elf_cr16c_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED,
+ arelent *cache_ptr ATTRIBUTE_UNUSED,
+ Elf_Internal_Rela *dst ATTRIBUTE_UNUSED)
+{
+ abort ();
+}
+
+static void
+elf_cr16c_info_to_howto_rel (bfd *abfd ATTRIBUTE_UNUSED,
+ arelent *cache_ptr,
+ Elf_Internal_Rela *dst)
+{
+ unsigned int r_type = ELF32_R_TYPE (dst->r_info);
+
+ BFD_ASSERT (r_type < (unsigned int) RINDEX_16C_MAX);
+ cache_ptr->howto = &elf_howto_table[r_type];
+}
+
+/* Perform a relocation as part of a final link. */
+
+static bfd_reloc_status_type
+cr16c_elf_final_link_relocate (reloc_howto_type *howto,
+ bfd *abfd,
+ bfd *output_bfd ATTRIBUTE_UNUSED,
+ asection *input_section,
+ bfd_byte *data,
+ bfd_vma octets,
+ bfd_vma Rvalue,
+ bfd_vma addend ATTRIBUTE_UNUSED,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ asection *sym_sec ATTRIBUTE_UNUSED,
+ int is_local ATTRIBUTE_UNUSED)
+{
+ long value;
+ short sword; /* Extracted from the hole and put back. */
+ unsigned long format, addr_type, code_factor;
+ unsigned short size;
+ unsigned short r_type;
+
+ unsigned long disp20_opcod;
+ char neg = 0;
+ char neg2pos = 0;
+
+ long left_val = 0;
+ long plus_factor = 0; /* To be added to the hole. */
+
+#define MIN_BYTE ((int) 0xFFFFFF80)
+#define MIN_WORD ((int) 0xFFFF8000)
+#define MAX_UWORD ((unsigned) 0x0000FFFF)
+#define MAX_UBYTE ((unsigned) 0x000000FF)
+
+ r_type = reloc_map_index[howto->type].cr_reloc_type;
+ format = r_type & R_FORMAT;
+ size = r_type & R_SIZESP;
+ addr_type = r_type & R_ADDRTYPE;
+ code_factor = ((addr_type == R_CODE_ADDR) ? 1 : 0);
+
+ switch (format)
+ {
+ case R_NUMBER:
+ switch (size)
+ {
+ case R_S_16C_08: /* One byte. */
+ value = bfd_get_8 (abfd, (char *) data + octets);
+ break;
+ case R_S_16C_16: /* Two bytes. */
+ sword = bfd_get_16 (abfd, (bfd_byte *) data + octets);
+ value = sword;
+ break;
+ case R_S_16C_32: /* Four bytes. */
+ value = bfd_get_32 (abfd, (bfd_byte *) data + octets);
+ break;
+ default:
+ return bfd_reloc_notsupported;
+ }
+ break;
+
+ case R_16C_DISPL:
+ switch (size)
+ {
+ case R_S_16C_04: /* word1(4-7). */
+ value = bfd_get_8 (abfd, (char *) data + octets);
+ left_val = value & 0xF;
+ value = (value & 0xF0) >> 4;
+ value++;
+ value <<= 1;
+ break;
+ case R_S_16C_08: /* word1(0-3,8-11). */
+ sword = bfd_get_16 (abfd, (char *) data + octets);
+ value = sword & 0x000F;
+ value |= ((sword & 0x0F00) >> 4);
+ left_val = sword & 0xF0F0;
+ value <<= 1;
+ if (value & 0x100)
+ value |= 0xFFFFFF00;
+ break;
+ case R_S_16C_16: /* word2. */
+ sword = bfd_get_16 (abfd, (bfd_byte *) data + octets);
+ value = sword;
+ value = ((value & 0xFFFE) >> 1) | ((value & 0x1) << 15);
+ value <<= 1;
+ if (value & 0x10000)
+ value |= 0xFFFF0000;
+ break;
+ case R_S_16C_24_a: /* word1(0-7),word2. */
+ value = bfd_get_32 (abfd, (bfd_byte *) data + octets);
+ left_val = value & 0x0000FF00;
+ value = ((value & 0xFFFE0000) >> 17) |
+ ((value & 0x00010000) << 7) | ((value & 0x000000FF) << 15);
+ value <<= 1;
+ if (value & 0x1000000)
+ value |= 0xFE000000;
+ break;
+ case R_S_16C_24: /* word2(0-3,8-11),word3. */
+ value = bfd_get_32 (abfd, (bfd_byte *) data + octets);
+ left_val = value & 0x0000F0F0;
+ value = ((value >> 16) & 0x0000FFFF) |
+ ((value & 0x00000F00) << 8) | ((value & 0x0000000F) << 20);
+
+ value = ((value & 0x00FFFFFE) >> 1) | ((value & 0x00000001) << 23);
+
+ value <<= 1;
+ if (value & 0x1000000)
+ value |= 0xFE000000;
+ break;
+ default:
+ return bfd_reloc_notsupported;
+ }
+ break;
+
+ case R_16C_REGREL:
+ switch (size)
+ {
+ case R_S_16C_04: /* word1(12-15) not scaled. */
+ value = bfd_get_8 (abfd, (char *) data + octets);
+ left_val = value & 0xF0;
+ value = value & 0xF;
+ break;
+ case R_S_16C_04_a: /* word1(12-15) scaled by 2. */
+ value = bfd_get_8 (abfd, (char *) data + octets);
+ left_val = value & 0xF0;
+ value = value & 0xF;
+ value <<= 1;
+ break;
+ case R_S_16C_14: /* word1(4-5),word2(0-3,8-15). */
+ value = bfd_get_32 (abfd, (bfd_byte *) data + octets);
+ left_val = value & 0x00F0FFCF;
+ value = ((value & 0xc0000000) >> 24) |
+ ((value & 0x3F000000) >> 16) |
+ ((value & 0x000F0000) >> 16) | (value & 0x00000030);
+ break;
+ case R_S_16C_16: /* word2. */
+ sword = bfd_get_16 (abfd, (bfd_byte *) data + octets);
+ value = sword;
+ break;
+ case R_S_16C_20: /* word2(8-11),word3. */
+ value = bfd_get_32 (abfd, (bfd_byte *) data + octets);
+ left_val = value & 0xF0;
+ value = (value & 0xF) << 16;
+ sword = bfd_get_16 (abfd, (bfd_byte *) data + octets + 1);
+ value = value | (unsigned short) sword;
+ disp20_opcod = bfd_get_32 (abfd, (bfd_byte *) data + octets - 3);
+ disp20_opcod |= 0x0FFF0000;
+ if ((disp20_opcod == 0x4FFF0018) || /* loadb -disp20(reg) */
+ (disp20_opcod == 0x5FFF0018) || /* loadb -disp20(rp) */
+ (disp20_opcod == 0x8FFF0018) || /* loadd -disp20(reg) */
+ (disp20_opcod == 0x9FFF0018) || /* loadd -disp20(rp) */
+ (disp20_opcod == 0xCFFF0018) || /* loadw -disp20(reg) */
+ (disp20_opcod == 0xDFFF0018) || /* loadw -disp20(rp) */
+ (disp20_opcod == 0x4FFF0019) || /* storb -disp20(reg) */
+ (disp20_opcod == 0x5FFF0019) || /* storb -disp20(rp) */
+ (disp20_opcod == 0x8FFF0019) || /* stord -disp20(reg) */
+ (disp20_opcod == 0x9FFF0019) || /* stord -disp20(rp) */
+ (disp20_opcod == 0xCFFF0019) || /* storw -disp20(reg) */
+ (disp20_opcod == 0xDFFF0019))
+ { /* storw -disp20(rp). */
+ neg = 1;
+ value |= 0xFFF00000;
+ }
+
+ break;
+ default:
+ return bfd_reloc_notsupported;
+ }
+ break;
+
+ case R_16C_ABS:
+ switch (size)
+ {
+ case R_S_16C_20: /* word1(0-3),word2. */
+ value = bfd_get_32 (abfd, (bfd_byte *) data + octets);
+ left_val = value & 0x0000FFF0;
+ value = ((value & 0xFFFF0000) >> 16) |
+ ((value & 0x0000000F) << 16);
+ break;
+ case R_S_16C_24: /* word2(0-3,8-11),word3. */
+ value = bfd_get_32 (abfd, (bfd_byte *) data + octets);
+ left_val = value & 0x0000F0F0;
+ value = ((value & 0xFFFF0000) >> 16) |
+ ((value & 0x00000F00) << 8) | ((value & 0x0000000F) << 20);
+ break;
+ default:
+ return bfd_reloc_notsupported;
+ }
+ break;
+
+ case R_16C_IMMED:
+ switch (size)
+ {
+ case R_S_16C_04: /* word1/2(4-7). */
+ value = bfd_get_8 (abfd, (char *) data + octets);
+ left_val = value & 0xF;
+ value = (value & 0xF0) >> 4;
+ break;
+ case R_S_16C_16: /* word2. */
+ sword = bfd_get_16 (abfd, (bfd_byte *) data + octets);
+ value = sword;
+ break;
+ case R_S_16C_20: /* word1(0-3),word2. */
+ value = bfd_get_32 (abfd, (bfd_byte *) data + octets);
+ left_val = value & 0x0000FFF0;
+ value = ((value & 0xFFFF0000) >> 16) |
+ ((value & 0x0000000F) << 16);
+ break;
+ case R_S_16C_32: /* word2, word3. */
+ value = bfd_get_32 (abfd, (bfd_byte *) data + octets);
+ value = ((value & 0x0000FFFF) << 16) |
+ ((value & 0xFFFF0000) >> 16);
+ break;
+ default:
+ return bfd_reloc_notsupported;
+ }
+ break;
+ default:
+ return bfd_reloc_notsupported;
+ }
+
+ switch ((r_type & R_RELTO) >> 4)
+ {
+
+ case 0: /* R_ABS. */
+ plus_factor = Rvalue;
+ break;
+ case 1: /* R_PCREL. */
+ plus_factor = Rvalue -
+ (input_section->output_section->vma + input_section->output_offset);
+ break;
+ default:
+ return bfd_reloc_notsupported;
+ }
+
+ if (neg)
+ {
+ if (plus_factor >= -value)
+ neg2pos = 1;
+ /* We need to change load/stor with negative
+ displ opcode to positive disp opcode (CR16C). */
+ }
+
+ value = value + (plus_factor >> code_factor);
+
+ switch (format)
+ {
+ case R_NUMBER:
+ switch (size)
+ {
+ case R_S_16C_08: /* One byte. */
+ if (value > (int) MAX_UBYTE || value < MIN_BYTE)
+ return bfd_reloc_overflow;
+ value &= 0xFF;
+ bfd_put_8 (abfd, (bfd_vma) value, (unsigned char *) data + octets);
+ break;
+
+ case R_S_16C_16: /* Two bytes. */
+ if (value > (int) MAX_UWORD || value < MIN_WORD)
+ return bfd_reloc_overflow;
+ value &= 0xFFFF;
+ sword = value;
+ bfd_put_16 (abfd, (bfd_vma) sword,
+ (unsigned char *) data + octets);
+ break;
+
+ case R_S_16C_32: /* Four bytes. */
+ value &= 0xFFFFFFFF;
+ bfd_put_32 (abfd, (bfd_vma) value, (bfd_byte *) data + octets);
+ break;
+
+ default:
+ return bfd_reloc_notsupported;
+ }
+ break;
+
+ case R_16C_DISPL:
+ switch (size)
+ {
+ case R_S_16C_04: /* word1(4-7). */
+ if ((value - 32) > 32 || value < 2)
+ return bfd_reloc_overflow;
+ value >>= 1;
+ value--;
+ value &= 0xF;
+ value <<= 4;
+ value |= left_val;
+ bfd_put_8 (abfd, (bfd_vma) value, (unsigned char *) data + octets);
+ break;
+
+ case R_S_16C_08: /* word1(0-3,8-11). */
+ if (value > 255 || value < -256 || value == 0x80)
+ return bfd_reloc_overflow;
+ value &= 0x1FF;
+ value >>= 1;
+ sword = value & 0x000F;
+ sword |= (value & 0x00F0) << 4;
+ sword |= left_val;
+ bfd_put_16 (abfd, (bfd_vma) sword,
+ (unsigned char *) data + octets);
+ break;
+
+ case R_S_16C_16: /* word2. */
+ if (value > 65535 || value < -65536)
+ return bfd_reloc_overflow;
+ value >>= 1;
+ value &= 0xFFFF;
+ value = ((value & 0x8000) >> 15) | ((value & 0x7FFF) << 1);
+ sword = value;
+ bfd_put_16 (abfd, (bfd_vma) sword,
+ (unsigned char *) data + octets);
+ break;
+
+ case R_S_16C_24_a: /* word1(0-7),word2. */
+ if (value > 16777215 || value < -16777216)
+ return bfd_reloc_overflow;
+ value &= 0x1FFFFFF;
+ value >>= 1;
+ value = ((value & 0x00007FFF) << 17) |
+ ((value & 0x00800000) >> 7) | ((value & 0x007F8000) >> 15);
+ value |= left_val;
+ bfd_put_32 (abfd, (bfd_vma) value, (bfd_byte *) data + octets);
+ break;
+
+ case R_S_16C_24: /* word2(0-3,8-11),word3. */
+ if (value > 16777215 || value < -16777216)
+ return bfd_reloc_overflow;
+ value &= 0x1FFFFFF;
+ value >>= 1;
+
+ value = ((value & 0x007FFFFF) << 1) | ((value & 0x00800000) >> 23);
+
+ value = ((value & 0x0000FFFF) << 16) |
+ ((value & 0x000F0000) >> 8) | ((value & 0x00F00000) >> 20);
+ value |= left_val;
+ bfd_put_32 (abfd, (bfd_vma) value, (bfd_byte *) data + octets);
+ break;
+
+ default:
+ return bfd_reloc_notsupported;
+ }
+ break;
+
+ case R_16C_REGREL:
+ switch (size)
+ {
+ case R_S_16C_04: /* word1(12-15) not scaled. */
+ if (value > 13 || value < 0)
+ return bfd_reloc_overflow;
+ value &= 0xF;
+ value |= left_val;
+ bfd_put_8 (abfd, (bfd_vma) value, (unsigned char *) data + octets);
+ break;
+
+ case R_S_16C_04_a: /* word1(12-15) not scaled. */
+ if (value > 26 || value < 0)
+ return bfd_reloc_overflow;
+ value &= 0x1F;
+ value >>= 1;
+ value |= left_val;
+ bfd_put_8 (abfd, (bfd_vma) value, (unsigned char *) data + octets);
+ break;
+
+ case R_S_16C_14: /* word1(4-5),word2(0-3,8-15). */
+ if (value < 0 || value > 16383)
+ return bfd_reloc_overflow;
+ value &= 0x3FFF;
+ value = ((value & 0x000000c0) << 24) |
+ ((value & 0x00003F00) << 16) |
+ ((value & 0x0000000F) << 16) | (value & 0x00000030);
+ value |= left_val;
+ bfd_put_32 (abfd, (bfd_vma) value, (bfd_byte *) data + octets);
+ break;
+
+ case R_S_16C_16: /* word2. */
+ if (value > 65535 || value < 0)
+ return bfd_reloc_overflow;
+ value &= 0xFFFF;
+ sword = value;
+ bfd_put_16 (abfd, (bfd_vma) sword,
+ (unsigned char *) data + octets);
+ break;
+
+ case R_S_16C_20: /* word2(8-11),word3. */
+ /* if (value > 1048575 || value < 0) RELOC_ERROR(1); */
+ value &= 0xFFFFF;
+ sword = value & 0x0000FFFF;
+ value = (value & 0x000F0000) >> 16;
+ value |= left_val;
+ bfd_put_8 (abfd, (bfd_vma) value, (unsigned char *) data + octets);
+ bfd_put_16 (abfd, (bfd_vma) sword,
+ (unsigned char *) data + octets + 1);
+ if (neg2pos)
+ {
+ /* Change load/stor negative displ opcode
+ to load/stor positive displ opcode. */
+ value = bfd_get_8 (abfd, (char *) data + octets - 3);
+ value &= 0xF7;
+ value |= 0x2;
+ bfd_put_8 (abfd, (bfd_vma) value,
+ (unsigned char *) data + octets - 3);
+ }
+ break;
+
+ default:
+ return bfd_reloc_notsupported;
+ }
+ break;
+
+ case R_16C_ABS:
+ switch (size)
+ {
+ case R_S_16C_20: /* word1(0-3),word2. */
+ if (value > 1048575 || value < 0)
+ return bfd_reloc_overflow;
+ value &= 0xFFFFF;
+ value = ((value & 0x0000FFFF) << 16) |
+ ((value & 0x000F0000) >> 16);
+ value |= left_val;
+ bfd_put_32 (abfd, (bfd_vma) value, (bfd_byte *) data + octets);
+ break;
+
+ case R_S_16C_24: /* word2(0-3,8-11),word3. */
+ /* if (value > 16777215 || value < 0) RELOC_ERROR(1); */
+ value &= 0xFFFFFF;
+ value = ((value & 0x0000FFFF) << 16) |
+ ((value & 0x000F0000) >> 8) | ((value & 0x00F00000) >> 20);
+ value |= left_val;
+ bfd_put_32 (abfd, (bfd_vma) value, (bfd_byte *) data + octets);
+ break;
+
+ default:
+ return bfd_reloc_notsupported;
+ }
+ break;
+
+ case R_16C_IMMED:
+ switch (size)
+ {
+ case R_S_16C_04: /* word1/2(4-7). */
+ if (value > 15 || value < -1)
+ return bfd_reloc_overflow;
+ value &= 0xF;
+ value <<= 4;
+ value |= left_val;
+ bfd_put_8 (abfd, (bfd_vma) value, (unsigned char *) data + octets);
+ break;
+
+ case R_S_16C_16: /* word2. */
+ if (value > 32767 || value < -32768)
+ return bfd_reloc_overflow;
+ value &= 0xFFFF;
+ sword = value;
+ bfd_put_16 (abfd, (bfd_vma) sword,
+ (unsigned char *) data + octets);
+ break;
+
+ case R_S_16C_20: /* word1(0-3),word2. */
+ if (value > 1048575 || value < 0)
+ return bfd_reloc_overflow;
+ value &= 0xFFFFF;
+ value = ((value & 0x0000FFFF) << 16) |
+ ((value & 0x000F0000) >> 16);
+ value |= left_val;
+ bfd_put_32 (abfd, (bfd_vma) value, (bfd_byte *) data + octets);
+ break;
+
+ case R_S_16C_32: /* word2, word3. */
+ value &= 0xFFFFFFFF;
+ value = ((value & 0x0000FFFF) << 16) |
+ ((value & 0xFFFF0000) >> 16);
+ bfd_put_32 (abfd, (bfd_vma) value, (bfd_byte *) data + octets);
+ break;
+
+ default:
+ return bfd_reloc_notsupported;
+ }
+ break;
+ default:
+ return bfd_reloc_notsupported;
+ }
+
+ return bfd_reloc_ok;
+}
+
+/* Relocate a CR16C ELF section. */
+
+static bfd_boolean
+elf32_cr16c_relocate_section (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_howto_table + r_type;
+
+ h = NULL;
+ sym = NULL;
+ sec = NULL;
+ if (r_symndx < symtab_hdr->sh_info)
+ {
+ sym = local_syms + r_symndx;
+ sec = local_sections[r_symndx];
+ relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
+ }
+ else
+ {
+ bfd_boolean unresolved_reloc, warned, ignored;
+
+ RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
+ r_symndx, symtab_hdr, sym_hashes,
+ h, sec, relocation,
+ unresolved_reloc, warned, ignored);
+ }
+
+ if (sec != NULL && discarded_section (sec))
+ RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+ rel, 1, relend, howto, 0, contents);
+
+ if (info->relocatable)
+ {
+ /* This is a relocatable 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 (sym != NULL && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
+ rel->r_addend += sec->output_offset;
+ continue;
+ }
+
+ r = cr16c_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, (h ? &h->root : NULL), 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, TRUE)))
+ 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;
+}
+
+/* CR16C ELF uses three common sections:
+ One is for default common symbols (placed in usual common section).
+ Second is for near common symbols (placed in "ncommon" section).
+ Third is for far common symbols (placed in "fcommon" section).
+ The following implementation is based on elf32-mips architecture */
+
+static asection cr16c_elf_fcom_section;
+static asymbol cr16c_elf_fcom_symbol;
+static asymbol * cr16c_elf_fcom_symbol_ptr;
+static asection cr16c_elf_ncom_section;
+static asymbol cr16c_elf_ncom_symbol;
+static asymbol * cr16c_elf_ncom_symbol_ptr;
+
+/* Given a BFD section, try to locate the
+ corresponding ELF section index. */
+
+static bfd_boolean
+elf32_cr16c_section_from_bfd_section (bfd *abfd ATTRIBUTE_UNUSED,
+ asection *sec,
+ int *retval)
+{
+ if (strcmp (bfd_get_section_name (abfd, sec), ".fcommon") == 0)
+ *retval = SHN_CR16C_FCOMMON;
+ else if (strcmp (bfd_get_section_name (abfd, sec), ".ncommon") == 0)
+ *retval = SHN_CR16C_NCOMMON;
+ else
+ return FALSE;
+
+ return TRUE;
+}
+
+/* Handle the special CR16C section numbers that a symbol may use. */
+
+static void
+elf32_cr16c_symbol_processing (bfd *abfd ATTRIBUTE_UNUSED,
+ asymbol *asym)
+{
+ elf_symbol_type *elfsym = (elf_symbol_type *) asym;
+ unsigned int indx;
+
+ indx = elfsym->internal_elf_sym.st_shndx;
+
+ switch (indx)
+ {
+ case SHN_CR16C_FCOMMON:
+ if (cr16c_elf_fcom_section.name == NULL)
+ {
+ /* Initialize the far common section. */
+ cr16c_elf_fcom_section.name = ".fcommon";
+ cr16c_elf_fcom_section.flags = SEC_IS_COMMON | SEC_ALLOC;
+ cr16c_elf_fcom_section.output_section = &cr16c_elf_fcom_section;
+ cr16c_elf_fcom_section.symbol = &cr16c_elf_fcom_symbol;
+ cr16c_elf_fcom_section.symbol_ptr_ptr = &cr16c_elf_fcom_symbol_ptr;
+ cr16c_elf_fcom_symbol.name = ".fcommon";
+ cr16c_elf_fcom_symbol.flags = BSF_SECTION_SYM;
+ cr16c_elf_fcom_symbol.section = &cr16c_elf_fcom_section;
+ cr16c_elf_fcom_symbol_ptr = &cr16c_elf_fcom_symbol;
+ }
+ asym->section = &cr16c_elf_fcom_section;
+ asym->value = elfsym->internal_elf_sym.st_size;
+ break;
+ case SHN_CR16C_NCOMMON:
+ if (cr16c_elf_ncom_section.name == NULL)
+ {
+ /* Initialize the far common section. */
+ cr16c_elf_ncom_section.name = ".ncommon";
+ cr16c_elf_ncom_section.flags = SEC_IS_COMMON | SEC_ALLOC;
+ cr16c_elf_ncom_section.output_section = &cr16c_elf_ncom_section;
+ cr16c_elf_ncom_section.symbol = &cr16c_elf_ncom_symbol;
+ cr16c_elf_ncom_section.symbol_ptr_ptr = &cr16c_elf_ncom_symbol_ptr;
+ cr16c_elf_ncom_symbol.name = ".ncommon";
+ cr16c_elf_ncom_symbol.flags = BSF_SECTION_SYM;
+ cr16c_elf_ncom_symbol.section = &cr16c_elf_ncom_section;
+ cr16c_elf_ncom_symbol_ptr = &cr16c_elf_ncom_symbol;
+ }
+ asym->section = &cr16c_elf_ncom_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 cr16c section numbers here. */
+
+static bfd_boolean
+elf32_cr16c_add_symbol_hook (bfd *abfd,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ Elf_Internal_Sym *sym,
+ const char **namep ATTRIBUTE_UNUSED,
+ flagword *flagsp ATTRIBUTE_UNUSED,
+ asection **secp,
+ bfd_vma *valp)
+{
+ unsigned int indx = sym->st_shndx;
+
+ switch (indx)
+ {
+ case SHN_CR16C_FCOMMON:
+ *secp = bfd_make_section_old_way (abfd, ".fcommon");
+ (*secp)->flags |= SEC_IS_COMMON;
+ *valp = sym->st_size;
+ break;
+ case SHN_CR16C_NCOMMON:
+ *secp = bfd_make_section_old_way (abfd, ".ncommon");
+ (*secp)->flags |= SEC_IS_COMMON;
+ *valp = sym->st_size;
+ break;
+ }
+
+ return TRUE;
+}
+
+static int
+elf32_cr16c_link_output_symbol_hook (struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ const char *name ATTRIBUTE_UNUSED,
+ Elf_Internal_Sym *sym,
+ asection *input_sec,
+ struct elf_link_hash_entry *h ATTRIBUTE_UNUSED)
+{
+ /* 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, ".fcommon") == 0)
+ sym->st_shndx = SHN_CR16C_FCOMMON;
+ else if (strcmp (input_sec->name, ".ncommon") == 0)
+ sym->st_shndx = SHN_CR16C_NCOMMON;
+ }
+
+ return 1;
+}
+
+/* Definitions for setting CR16C target vector. */
+#define TARGET_LITTLE_SYM cr16c_elf32_vec
+#define TARGET_LITTLE_NAME "elf32-cr16c"
+#define ELF_ARCH bfd_arch_cr16c
+#define ELF_MACHINE_CODE EM_CR
+#define ELF_MAXPAGESIZE 0x1
+#define elf_symbol_leading_char '_'
+
+#define bfd_elf32_bfd_reloc_type_lookup elf_cr16c_reloc_type_lookup
+#define bfd_elf32_bfd_reloc_name_lookup elf_cr16c_reloc_name_lookup
+#define elf_info_to_howto elf_cr16c_info_to_howto
+#define elf_info_to_howto_rel elf_cr16c_info_to_howto_rel
+#define elf_backend_relocate_section elf32_cr16c_relocate_section
+#define elf_backend_symbol_processing elf32_cr16c_symbol_processing
+#define elf_backend_section_from_bfd_section elf32_cr16c_section_from_bfd_section
+#define elf_backend_add_symbol_hook elf32_cr16c_add_symbol_hook
+#define elf_backend_link_output_symbol_hook elf32_cr16c_link_output_symbol_hook
+
+#define elf_backend_can_gc_sections 1
+
+#include "elf32-target.h"
diff --git a/bfd/elf32-cris.c b/bfd/elf32-cris.c
new file mode 100644
index 0000000..9b2b956
--- /dev/null
+++ b/bfd/elf32-cris.c
@@ -0,0 +1,4412 @@
+/* CRIS-specific support for 32-bit ELF.
+ Copyright (C) 2000-2014 Free Software Foundation, Inc.
+ Contributed by Axis Communications AB.
+ Written by Hans-Peter Nilsson, based on elf32-fr30.c
+ PIC and shlib bits based primarily on elf32-m68k.c and elf32-i386.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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+#include "elf-bfd.h"
+#include "elf/cris.h"
+#include <limits.h>
+
+bfd_reloc_status_type
+cris_elf_pcrel_reloc (bfd *, arelent *, asymbol *, void *,
+ asection *, bfd *, char **);
+static bfd_boolean
+cris_elf_set_mach_from_flags (bfd *, unsigned long);
+
+/* Forward declarations. */
+static reloc_howto_type cris_elf_howto_table [] =
+{
+ /* This reloc does nothing. */
+ HOWTO (R_CRIS_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_CRIS_NONE", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* An 8 bit absolute relocation. */
+ HOWTO (R_CRIS_8, /* 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_CRIS_8", /* name */
+ FALSE, /* partial_inplace */
+ 0x0000, /* src_mask */
+ 0x00ff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A 16 bit absolute relocation. */
+ HOWTO (R_CRIS_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_CRIS_16", /* name */
+ FALSE, /* partial_inplace */
+ 0x00000000, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A 32 bit absolute relocation. */
+ HOWTO (R_CRIS_32, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ /* We don't want overflow complaints for 64-bit vma builds
+ for e.g. sym+0x40000000 (or actually sym-0xc0000000 in
+ 32-bit ELF) where sym=0xc0001234.
+ Don't do this for the PIC relocs, as we don't expect to
+ see them with large offsets. */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_CRIS_32", /* name */
+ FALSE, /* partial_inplace */
+ 0x00000000, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* An 8 bit PC-relative relocation. */
+ HOWTO (R_CRIS_8_PCREL, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 8, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ cris_elf_pcrel_reloc, /* special_function */
+ "R_CRIS_8_PCREL", /* name */
+ FALSE, /* partial_inplace */
+ 0x0000, /* src_mask */
+ 0x00ff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* A 16 bit PC-relative relocation. */
+ HOWTO (R_CRIS_16_PCREL, /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ cris_elf_pcrel_reloc, /* special_function */
+ "R_CRIS_16_PCREL", /* name */
+ FALSE, /* partial_inplace */
+ 0x00000000, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* A 32 bit PC-relative relocation. */
+ HOWTO (R_CRIS_32_PCREL, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ cris_elf_pcrel_reloc, /* special_function */
+ "R_CRIS_32_PCREL", /* name */
+ FALSE, /* partial_inplace */
+ 0x00000000, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* GNU extension to record C++ vtable hierarchy. */
+ HOWTO (R_CRIS_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_CRIS_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_CRIS_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_CRIS_GNU_VTENTRY", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ FALSE), /* 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_CRIS_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_CRIS_COPY", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Like R_CRIS_32, but used when setting global offset table entries. */
+ HOWTO (R_CRIS_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_CRIS_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_CRIS_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_CRIS_JUMP_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_CRIS_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_CRIS_RELATIVE", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Like R_CRIS_32, but referring to the GOT table entry for the symbol. */
+ HOWTO (R_CRIS_16_GOT, /* 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_CRIS_16_GOT", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_CRIS_32_GOT, /* 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_CRIS_32_GOT", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Like R_CRIS_32_GOT, but referring to (and requesting a) PLT part of
+ the GOT table for the symbol. */
+ HOWTO (R_CRIS_16_GOTPLT, /* 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_CRIS_16_GOTPLT", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_CRIS_32_GOTPLT, /* 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_CRIS_32_GOTPLT", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A 32-bit offset from GOT to (local const) symbol: no GOT entry should
+ be necessary. */
+ HOWTO (R_CRIS_32_GOTREL, /* 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_CRIS_32_GOTREL", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A 32-bit offset from GOT to entry for this symbol in PLT and request
+ to create PLT entry for symbol. */
+ HOWTO (R_CRIS_32_PLT_GOTREL, /* 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_CRIS_32_PLT_GOTREL", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A 32-bit offset from PC (location after the relocation) + addend to
+ entry for this symbol in PLT and request to create PLT entry for
+ symbol. */
+ HOWTO (R_CRIS_32_PLT_PCREL, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ cris_elf_pcrel_reloc, /* special_function */
+ "R_CRIS_32_PLT_PCREL", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* We don't handle these in any special manner and cross-format
+ linking is not supported; just recognize them enough to pass them
+ around. FIXME: do the same for most PIC relocs and add sanity
+ tests to actually refuse gracefully to handle these and PIC
+ relocs for cross-format linking. */
+#define TLSHOWTO32(name) \
+ HOWTO (name, 0, 2, 32, FALSE, 0, complain_overflow_bitfield, \
+ bfd_elf_generic_reloc, #name, FALSE, 0, 0xffffffff, FALSE)
+#define TLSHOWTO16X(name, X) \
+ HOWTO (name, 0, 1, 16, FALSE, 0, complain_overflow_ ## X, \
+ bfd_elf_generic_reloc, #name, FALSE, 0, 0xffff, FALSE)
+#define TLSHOWTO16(name) TLSHOWTO16X(name, unsigned)
+#define TLSHOWTO16S(name) TLSHOWTO16X(name, signed)
+
+ TLSHOWTO32 (R_CRIS_32_GOT_GD),
+ TLSHOWTO16 (R_CRIS_16_GOT_GD),
+ TLSHOWTO32 (R_CRIS_32_GD),
+ TLSHOWTO32 (R_CRIS_DTP),
+ TLSHOWTO32 (R_CRIS_32_DTPREL),
+ TLSHOWTO16S (R_CRIS_16_DTPREL),
+ TLSHOWTO32 (R_CRIS_32_GOT_TPREL),
+ TLSHOWTO16S (R_CRIS_16_GOT_TPREL),
+ TLSHOWTO32 (R_CRIS_32_TPREL),
+ TLSHOWTO16S (R_CRIS_16_TPREL),
+ TLSHOWTO32 (R_CRIS_DTPMOD),
+ TLSHOWTO32 (R_CRIS_32_IE)
+};
+
+/* Map BFD reloc types to CRIS ELF reloc types. */
+
+struct cris_reloc_map
+{
+ bfd_reloc_code_real_type bfd_reloc_val;
+ unsigned int cris_reloc_val;
+};
+
+static const struct cris_reloc_map cris_reloc_map [] =
+{
+ { BFD_RELOC_NONE, R_CRIS_NONE },
+ { BFD_RELOC_8, R_CRIS_8 },
+ { BFD_RELOC_16, R_CRIS_16 },
+ { BFD_RELOC_32, R_CRIS_32 },
+ { BFD_RELOC_8_PCREL, R_CRIS_8_PCREL },
+ { BFD_RELOC_16_PCREL, R_CRIS_16_PCREL },
+ { BFD_RELOC_32_PCREL, R_CRIS_32_PCREL },
+ { BFD_RELOC_VTABLE_INHERIT, R_CRIS_GNU_VTINHERIT },
+ { BFD_RELOC_VTABLE_ENTRY, R_CRIS_GNU_VTENTRY },
+ { BFD_RELOC_CRIS_COPY, R_CRIS_COPY },
+ { BFD_RELOC_CRIS_GLOB_DAT, R_CRIS_GLOB_DAT },
+ { BFD_RELOC_CRIS_JUMP_SLOT, R_CRIS_JUMP_SLOT },
+ { BFD_RELOC_CRIS_RELATIVE, R_CRIS_RELATIVE },
+ { BFD_RELOC_CRIS_16_GOT, R_CRIS_16_GOT },
+ { BFD_RELOC_CRIS_32_GOT, R_CRIS_32_GOT },
+ { BFD_RELOC_CRIS_16_GOTPLT, R_CRIS_16_GOTPLT },
+ { BFD_RELOC_CRIS_32_GOTPLT, R_CRIS_32_GOTPLT },
+ { BFD_RELOC_CRIS_32_GOTREL, R_CRIS_32_GOTREL },
+ { BFD_RELOC_CRIS_32_PLT_GOTREL, R_CRIS_32_PLT_GOTREL },
+ { BFD_RELOC_CRIS_32_PLT_PCREL, R_CRIS_32_PLT_PCREL },
+ { BFD_RELOC_CRIS_32_GOT_GD, R_CRIS_32_GOT_GD },
+ { BFD_RELOC_CRIS_16_GOT_GD, R_CRIS_16_GOT_GD },
+ { BFD_RELOC_CRIS_32_GD, R_CRIS_32_GD },
+ { BFD_RELOC_CRIS_DTP, R_CRIS_DTP },
+ { BFD_RELOC_CRIS_32_DTPREL, R_CRIS_32_DTPREL },
+ { BFD_RELOC_CRIS_16_DTPREL, R_CRIS_16_DTPREL },
+ { BFD_RELOC_CRIS_32_GOT_TPREL, R_CRIS_32_GOT_TPREL },
+ { BFD_RELOC_CRIS_16_GOT_TPREL, R_CRIS_16_GOT_TPREL },
+ { BFD_RELOC_CRIS_32_TPREL, R_CRIS_32_TPREL },
+ { BFD_RELOC_CRIS_16_TPREL, R_CRIS_16_TPREL },
+ { BFD_RELOC_CRIS_DTPMOD, R_CRIS_DTPMOD },
+ { BFD_RELOC_CRIS_32_IE, R_CRIS_32_IE }
+};
+
+static reloc_howto_type *
+cris_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED,
+ bfd_reloc_code_real_type code)
+{
+ unsigned int i;
+
+ for (i = 0; i < sizeof (cris_reloc_map) / sizeof (cris_reloc_map[0]); i++)
+ if (cris_reloc_map [i].bfd_reloc_val == code)
+ return & cris_elf_howto_table [cris_reloc_map[i].cris_reloc_val];
+
+ return NULL;
+}
+
+static reloc_howto_type *
+cris_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, const char *r_name)
+{
+ unsigned int i;
+
+ for (i = 0;
+ i < sizeof (cris_elf_howto_table) / sizeof (cris_elf_howto_table[0]);
+ i++)
+ if (cris_elf_howto_table[i].name != NULL
+ && strcasecmp (cris_elf_howto_table[i].name, r_name) == 0)
+ return &cris_elf_howto_table[i];
+
+ return NULL;
+}
+
+/* Set the howto pointer for an CRIS ELF reloc. */
+
+static void
+cris_info_to_howto_rela (bfd * abfd ATTRIBUTE_UNUSED,
+ arelent * cache_ptr,
+ Elf_Internal_Rela * dst)
+{
+ enum elf_cris_reloc_type r_type;
+
+ r_type = ELF32_R_TYPE (dst->r_info);
+ BFD_ASSERT (r_type < (unsigned int) R_CRIS_max);
+ cache_ptr->howto = & cris_elf_howto_table [r_type];
+}
+
+bfd_reloc_status_type
+cris_elf_pcrel_reloc (bfd *abfd ATTRIBUTE_UNUSED,
+ arelent *reloc_entry,
+ asymbol *symbol,
+ void * data ATTRIBUTE_UNUSED,
+ asection *input_section,
+ bfd *output_bfd,
+ char **error_message ATTRIBUTE_UNUSED)
+{
+ /* By default (using only bfd_elf_generic_reloc when linking to
+ non-ELF formats) PC-relative relocs are relative to the beginning
+ of the reloc. CRIS PC-relative relocs are relative to the position
+ *after* the reloc because that's what pre-CRISv32 PC points to
+ after reading an insn field with that reloc. (For CRISv32, PC is
+ actually relative to the start of the insn, but we keep the old
+ definition.) Still, we use as much generic machinery as we can.
+
+ Only adjust when doing a final link. */
+ if (output_bfd == (bfd *) NULL)
+ reloc_entry->addend -= 1 << reloc_entry->howto->size;
+
+ return
+ bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
+ input_section, output_bfd, error_message);
+}
+
+/* Support for core dump NOTE sections.
+ The slightly unintuitive code layout is an attempt to keep at least
+ some similarities with other ports, hoping to simplify general
+ changes, while still keeping Linux/CRIS and Linux/CRISv32 code apart. */
+
+static bfd_boolean
+cris_elf_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
+{
+ int offset;
+ size_t size;
+
+ if (bfd_get_mach (abfd) == bfd_mach_cris_v32)
+ switch (note->descsz)
+ {
+ default:
+ return FALSE;
+
+ case 202: /* Linux/CRISv32 */
+ /* pr_cursig */
+ elf_tdata (abfd)->core->signal = bfd_get_16 (abfd, note->descdata + 12);
+
+ /* pr_pid */
+ elf_tdata (abfd)->core->lwpid = bfd_get_32 (abfd, note->descdata + 22);
+
+ /* pr_reg */
+ offset = 70;
+ size = 128;
+
+ break;
+ }
+ else
+ switch (note->descsz)
+ {
+ default:
+ return FALSE;
+
+ case 214: /* Linux/CRIS */
+ /* pr_cursig */
+ elf_tdata (abfd)->core->signal = bfd_get_16 (abfd, note->descdata + 12);
+
+ /* pr_pid */
+ elf_tdata (abfd)->core->lwpid = bfd_get_32 (abfd, note->descdata + 22);
+
+ /* pr_reg */
+ offset = 70;
+ size = 140;
+
+ break;
+ }
+
+ /* Make a ".reg/999" section. */
+ return _bfd_elfcore_make_pseudosection (abfd, ".reg",
+ size, note->descpos + offset);
+}
+
+static bfd_boolean
+cris_elf_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
+{
+ if (bfd_get_mach (abfd) == bfd_mach_cris_v32)
+ switch (note->descsz)
+ {
+ default:
+ return FALSE;
+
+ case 124: /* Linux/CRISv32 elf_prpsinfo */
+ elf_tdata (abfd)->core->program
+ = _bfd_elfcore_strndup (abfd, note->descdata + 28, 16);
+ elf_tdata (abfd)->core->command
+ = _bfd_elfcore_strndup (abfd, note->descdata + 44, 80);
+ }
+ else
+ switch (note->descsz)
+ {
+ default:
+ return FALSE;
+
+ case 124: /* Linux/CRIS elf_prpsinfo */
+ elf_tdata (abfd)->core->program
+ = _bfd_elfcore_strndup (abfd, note->descdata + 28, 16);
+ elf_tdata (abfd)->core->command
+ = _bfd_elfcore_strndup (abfd, note->descdata + 44, 80);
+ }
+
+ /* 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;
+}
+
+/* The name of the dynamic interpreter. This is put in the .interp
+ section. */
+
+#define ELF_DYNAMIC_INTERPRETER "/lib/ld.so.1"
+
+/* The size in bytes of an entry in the procedure linkage table. */
+
+#define PLT_ENTRY_SIZE 20
+#define PLT_ENTRY_SIZE_V32 26
+
+/* The first entry in an absolute procedure linkage table looks like this. */
+
+static const bfd_byte elf_cris_plt0_entry[PLT_ENTRY_SIZE] =
+{
+ 0xfc, 0xe1,
+ 0x7e, 0x7e, /* push mof. */
+ 0x7f, 0x0d, /* (dip [pc+]) */
+ 0, 0, 0, 0, /* Replaced with address of .got + 4. */
+ 0x30, 0x7a, /* move [...],mof */
+ 0x7f, 0x0d, /* (dip [pc+]) */
+ 0, 0, 0, 0, /* Replaced with address of .got + 8. */
+ 0x30, 0x09 /* jump [...] */
+};
+
+static const bfd_byte elf_cris_plt0_entry_v32[PLT_ENTRY_SIZE_V32] =
+{
+ 0x84, 0xe2, /* subq 4,$sp */
+ 0x6f, 0xfe, /* move.d 0,$acr */
+ 0, 0, 0, 0, /* Replaced by address of .got + 4. */
+ 0x7e, 0x7a, /* move $mof,[$sp] */
+ 0x3f, 0x7a, /* move [$acr],$mof */
+ 0x04, 0xf2, /* addq 4,acr */
+ 0x6f, 0xfa, /* move.d [$acr],$acr */
+ 0xbf, 0x09, /* jump $acr */
+ 0xb0, 0x05, /* nop */
+ 0, 0 /* Pad out to 26 bytes. */
+};
+
+/* Subsequent entries in an absolute procedure linkage table look like
+ this. */
+
+static const bfd_byte elf_cris_plt_entry[PLT_ENTRY_SIZE] =
+{
+ 0x7f, 0x0d, /* (dip [pc+]) */
+ 0, 0, 0, 0, /* Replaced with address of this symbol in .got. */
+ 0x30, 0x09, /* jump [...] */
+ 0x3f, 0x7e, /* move [pc+],mof */
+ 0, 0, 0, 0, /* Replaced with offset into relocation table. */
+ 0x2f, 0xfe, /* add.d [pc+],pc */
+ 0xec, 0xff,
+ 0xff, 0xff /* Replaced with offset to start of .plt. */
+};
+
+static const bfd_byte elf_cris_plt_entry_v32[PLT_ENTRY_SIZE_V32] =
+{
+ 0x6f, 0xfe, /* move.d 0,$acr */
+ 0, 0, 0, 0, /* Replaced with address of this symbol in .got. */
+ 0x6f, 0xfa, /* move.d [$acr],$acr */
+ 0xbf, 0x09, /* jump $acr */
+ 0xb0, 0x05, /* nop */
+ 0x3f, 0x7e, /* move 0,mof */
+ 0, 0, 0, 0, /* Replaced with offset into relocation table. */
+ 0xbf, 0x0e, /* ba start_of_plt0_entry */
+ 0, 0, 0, 0, /* Replaced with offset to plt0 entry. */
+ 0xb0, 0x05 /* nop */
+};
+
+/* The first entry in a PIC procedure linkage table looks like this. */
+
+static const bfd_byte elf_cris_pic_plt0_entry[PLT_ENTRY_SIZE] =
+{
+ 0xfc, 0xe1, 0x7e, 0x7e, /* push mof */
+ 0x04, 0x01, 0x30, 0x7a, /* move [r0+4],mof */
+ 0x08, 0x01, 0x30, 0x09, /* jump [r0+8] */
+ 0, 0, 0, 0, 0, 0, 0, 0, /* Pad out to 20 bytes. */
+};
+
+static const bfd_byte elf_cris_pic_plt0_entry_v32[PLT_ENTRY_SIZE_V32] =
+{
+ 0x84, 0xe2, /* subq 4,$sp */
+ 0x04, 0x01, /* addoq 4,$r0,$acr */
+ 0x7e, 0x7a, /* move $mof,[$sp] */
+ 0x3f, 0x7a, /* move [$acr],$mof */
+ 0x04, 0xf2, /* addq 4,$acr */
+ 0x6f, 0xfa, /* move.d [$acr],$acr */
+ 0xbf, 0x09, /* jump $acr */
+ 0xb0, 0x05, /* nop */
+ 0, 0, /* Pad out to 26 bytes. */
+ 0, 0, 0, 0,
+ 0, 0, 0, 0
+};
+
+/* Subsequent entries in a PIC procedure linkage table look like this. */
+
+static const bfd_byte elf_cris_pic_plt_entry[PLT_ENTRY_SIZE] =
+{
+ 0x6f, 0x0d, /* (bdap [pc+].d,r0) */
+ 0, 0, 0, 0, /* Replaced with offset of this symbol in .got. */
+ 0x30, 0x09, /* jump [...] */
+ 0x3f, 0x7e, /* move [pc+],mof */
+ 0, 0, 0, 0, /* Replaced with offset into relocation table. */
+ 0x2f, 0xfe, /* add.d [pc+],pc */
+ 0xec, 0xff, /* Replaced with offset to start of .plt. */
+ 0xff, 0xff
+};
+
+static const bfd_byte elf_cris_pic_plt_entry_v32[PLT_ENTRY_SIZE_V32] =
+{
+ 0x6f, 0x0d, /* addo.d 0,$r0,$acr */
+ 0, 0, 0, 0, /* Replaced with offset of this symbol in .got. */
+ 0x6f, 0xfa, /* move.d [$acr],$acr */
+ 0xbf, 0x09, /* jump $acr */
+ 0xb0, 0x05, /* nop */
+ 0x3f, 0x7e, /* move relocoffs,$mof */
+ 0, 0, 0, 0, /* Replaced with offset into relocation table. */
+ 0xbf, 0x0e, /* ba start_of_plt */
+ 0, 0, 0, 0, /* Replaced with offset to start of .plt. */
+ 0xb0, 0x05 /* nop */
+};
+
+/* We copy elf32-m68k.c and elf32-i386.c for the basic linker hash bits
+ (and most other PIC/shlib stuff). Check that we don't drift away
+ without reason.
+
+ The CRIS linker, like the m68k and i386 linkers (and probably the rest
+ too) 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_cris_pcrel_relocs_copied
+{
+ /* Next section. */
+ struct elf_cris_pcrel_relocs_copied *next;
+
+ /* A section in dynobj. */
+ asection *section;
+
+ /* Number of relocs copied in this section. */
+ bfd_size_type count;
+
+ /* Example of reloc being copied, for message. */
+ enum elf_cris_reloc_type r_type;
+};
+
+/* CRIS ELF linker hash entry. */
+
+struct elf_cris_link_hash_entry
+{
+ struct elf_link_hash_entry root;
+
+ /* Number of PC relative relocs copied for this symbol. */
+ struct elf_cris_pcrel_relocs_copied *pcrel_relocs_copied;
+
+ /* The GOTPLT references are CRIS-specific; the goal is to avoid having
+ both a general GOT and a PLT-specific GOT entry for the same symbol,
+ when it is referenced both as a function and as a function pointer.
+
+ Number of GOTPLT references for a function. */
+ bfd_signed_vma gotplt_refcount;
+
+ /* Actual GOTPLT index for this symbol, if applicable, or zero if not
+ (zero is never used as an index). FIXME: We should be able to fold
+ this with gotplt_refcount in a union, like the got and plt unions in
+ elf_link_hash_entry. */
+ bfd_size_type gotplt_offset;
+
+ /* The root.got.refcount is the sum of the regular reference counts
+ (this) and those members below. We have to keep a separate count
+ to track when we've found the first (or last) reference to a
+ regular got entry. The offset is in root.got.offset. */
+ bfd_signed_vma reg_got_refcount;
+
+ /* Similar to the above, the number of reloc references to this
+ symbols that need a R_CRIS_32_TPREL slot. The offset is in
+ root.got.offset, because this and .dtp_refcount can't validly
+ happen when there's also a regular GOT entry; that's invalid
+ input for which an error is emitted. */
+ bfd_signed_vma tprel_refcount;
+
+ /* Similar to the above, the number of reloc references to this
+ symbols that need a R_CRIS_DTP slot. The offset is in
+ root.got.offset; plus 4 if .tprel_refcount > 0. */
+ bfd_signed_vma dtp_refcount;
+};
+
+static bfd_boolean
+elf_cris_discard_excess_dso_dynamics (struct elf_cris_link_hash_entry *,
+ void * );
+static bfd_boolean
+elf_cris_discard_excess_program_dynamics (struct elf_cris_link_hash_entry *,
+ void *);
+
+/* The local_got_refcounts and local_got_offsets are a multiple of
+ LSNUM in size, namely LGOT_ALLOC_NELTS_FOR(LSNUM) (plus one for the
+ refcount for GOT itself, see code), with the summary / group offset
+ for local symbols located at offset N, reference counts for
+ ordinary (address) relocs at offset N + LSNUM, for R_CRIS_DTP
+ relocs at offset N + 2*LSNUM, and for R_CRIS_32_TPREL relocs at N +
+ 3*LSNUM. */
+
+#define LGOT_REG_NDX(x) ((x) + symtab_hdr->sh_info)
+#define LGOT_DTP_NDX(x) ((x) + 2 * symtab_hdr->sh_info)
+#define LGOT_TPREL_NDX(x) ((x) + 3 * symtab_hdr->sh_info)
+#define LGOT_ALLOC_NELTS_FOR(x) ((x) * 4)
+
+/* CRIS ELF linker hash table. */
+
+struct elf_cris_link_hash_table
+{
+ struct elf_link_hash_table root;
+
+ /* We can't use the PLT offset and calculate to get the GOTPLT offset,
+ since we try and avoid creating GOTPLT:s when there's already a GOT.
+ Instead, we keep and update the next available index here. */
+ bfd_size_type next_gotplt_entry;
+
+ /* The number of R_CRIS_32_DTPREL and R_CRIS_16_DTPREL that have
+ been seen for any input; if != 0, then the constant-offset
+ R_CRIS_DTPMOD is needed for this DSO/executable. This turns
+ negative at relocation, so that we don't need an extra flag for
+ when the reloc is output. */
+ bfd_signed_vma dtpmod_refcount;
+};
+
+/* Traverse a CRIS ELF linker hash table. */
+
+#define elf_cris_link_hash_traverse(table, func, info) \
+ (elf_link_hash_traverse \
+ (&(table)->root, \
+ (bfd_boolean (*) (struct elf_link_hash_entry *, void *)) (func), \
+ (info)))
+
+/* Get the CRIS ELF linker hash table from a link_info structure. */
+
+#define elf_cris_hash_table(p) \
+ (elf_hash_table_id ((struct elf_link_hash_table *) ((p)->hash)) \
+ == CRIS_ELF_DATA ? ((struct elf_cris_link_hash_table *) ((p)->hash)) : NULL)
+
+/* Get the CRIS ELF linker hash entry from a regular hash entry (the
+ "parent class"). The .root reference is just a simple type
+ check on the argument. */
+
+#define elf_cris_hash_entry(p) \
+ ((struct elf_cris_link_hash_entry *) (&(p)->root))
+
+/* Create an entry in a CRIS ELF linker hash table. */
+
+static struct bfd_hash_entry *
+elf_cris_link_hash_newfunc (struct bfd_hash_entry *entry,
+ struct bfd_hash_table *table,
+ const char *string)
+{
+ struct elf_cris_link_hash_entry *ret =
+ (struct elf_cris_link_hash_entry *) entry;
+
+ /* Allocate the structure if it has not already been allocated by a
+ subclass. */
+ if (ret == (struct elf_cris_link_hash_entry *) NULL)
+ ret = ((struct elf_cris_link_hash_entry *)
+ bfd_hash_allocate (table,
+ sizeof (struct elf_cris_link_hash_entry)));
+ if (ret == (struct elf_cris_link_hash_entry *) NULL)
+ return (struct bfd_hash_entry *) ret;
+
+ /* Call the allocation method of the superclass. */
+ ret = ((struct elf_cris_link_hash_entry *)
+ _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry *) ret,
+ table, string));
+ if (ret != (struct elf_cris_link_hash_entry *) NULL)
+ {
+ ret->pcrel_relocs_copied = NULL;
+ ret->gotplt_refcount = 0;
+ ret->gotplt_offset = 0;
+ ret->dtp_refcount = 0;
+ ret->tprel_refcount = 0;
+ ret->reg_got_refcount = 0;
+ }
+
+ return (struct bfd_hash_entry *) ret;
+}
+
+/* Create a CRIS ELF linker hash table. */
+
+static struct bfd_link_hash_table *
+elf_cris_link_hash_table_create (bfd *abfd)
+{
+ struct elf_cris_link_hash_table *ret;
+ bfd_size_type amt = sizeof (struct elf_cris_link_hash_table);
+
+ ret = ((struct elf_cris_link_hash_table *) bfd_zmalloc (amt));
+ if (ret == (struct elf_cris_link_hash_table *) NULL)
+ return NULL;
+
+ if (!_bfd_elf_link_hash_table_init (&ret->root, abfd,
+ elf_cris_link_hash_newfunc,
+ sizeof (struct elf_cris_link_hash_entry),
+ CRIS_ELF_DATA))
+ {
+ free (ret);
+ return NULL;
+ }
+
+ /* Initialize to skip over the first three entries in the gotplt; they
+ are used for run-time symbol evaluation. */
+ ret->next_gotplt_entry = 12;
+
+ return &ret->root.root;
+}
+
+/* Perform a single relocation. By default we use the standard BFD
+ routines, with a few tweaks. */
+
+static bfd_reloc_status_type
+cris_final_link_relocate (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;
+ enum elf_cris_reloc_type r_type = ELF32_R_TYPE (rel->r_info);
+
+ /* PC-relative relocations are relative to the position *after*
+ the reloc. Note that for R_CRIS_8_PCREL the adjustment is
+ not a single byte, since PC must be 16-bit-aligned. */
+ switch (r_type)
+ {
+ /* Check that the 16-bit GOT relocs are positive. */
+ case R_CRIS_16_GOTPLT:
+ case R_CRIS_16_GOT:
+ if ((bfd_signed_vma) relocation < 0)
+ return bfd_reloc_overflow;
+ break;
+
+ case R_CRIS_32_PLT_PCREL:
+ case R_CRIS_32_PCREL:
+ relocation -= 2;
+ /* Fall through. */
+ case R_CRIS_8_PCREL:
+ case R_CRIS_16_PCREL:
+ relocation -= 2;
+ break;
+
+ default:
+ break;
+ }
+
+ r = _bfd_final_link_relocate (howto, input_bfd, input_section,
+ contents, rel->r_offset,
+ relocation, rel->r_addend);
+ return r;
+}
+
+
+/* The number of errors left before we stop outputting reloc-specific
+ explanatory messages. By coincidence, this works nicely together
+ with the default number of messages you'll get from LD about
+ "relocation truncated to fit" messages before you get an
+ "additional relocation overflows omitted from the output". */
+static int additional_relocation_error_msg_count = 10;
+
+/* Relocate an CRIS ELF section. See elf32-fr30.c, from where this was
+ copied, for further comments. */
+
+static bfd_boolean
+cris_elf_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
+ 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)
+{
+ struct elf_cris_link_hash_table * htab;
+ 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;
+ asection *srelgot;
+
+ htab = elf_cris_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ dynobj = elf_hash_table (info)->dynobj;
+ local_got_offsets = elf_local_got_offsets (input_bfd);
+ symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
+ sym_hashes = elf_sym_hashes (input_bfd);
+ relend = relocs + input_section->reloc_count;
+
+ sgot = NULL;
+ splt = NULL;
+ sreloc = NULL;
+ srelgot = NULL;
+
+ if (dynobj != NULL)
+ {
+ splt = bfd_get_linker_section (dynobj, ".plt");
+ sgot = bfd_get_linker_section (dynobj, ".got");
+ }
+
+ 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 *symname = NULL;
+ enum elf_cris_reloc_type r_type;
+
+ r_type = ELF32_R_TYPE (rel->r_info);
+
+ if ( r_type == R_CRIS_GNU_VTINHERIT
+ || r_type == R_CRIS_GNU_VTENTRY)
+ continue;
+
+ r_symndx = ELF32_R_SYM (rel->r_info);
+ howto = cris_elf_howto_table + r_type;
+ h = NULL;
+ sym = NULL;
+ sec = NULL;
+
+ if (r_symndx < symtab_hdr->sh_info)
+ {
+ sym = local_syms + r_symndx;
+ sec = local_sections [r_symndx];
+ relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
+
+ symname = (bfd_elf_string_from_elf_section
+ (input_bfd, symtab_hdr->sh_link, sym->st_name));
+ if (symname == NULL)
+ symname = bfd_section_name (input_bfd, sec);
+ }
+ else
+ {
+ bfd_boolean warned, ignored;
+ bfd_boolean unresolved_reloc;
+
+ RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
+ r_symndx, symtab_hdr, sym_hashes,
+ h, sec, relocation,
+ unresolved_reloc, warned, ignored);
+
+ symname = h->root.root.string;
+
+ if (unresolved_reloc
+ /* Perhaps we should detect the cases that
+ sec->output_section is expected to be NULL like i386 and
+ m68k, but apparently (and according to elfxx-ia64.c) all
+ valid cases are where the symbol is defined in a shared
+ object which we link dynamically against. This includes
+ PLT relocs for which we've created a PLT entry and other
+ relocs for which we're prepared to create dynamic
+ relocations.
+
+ For now, new situations cause us to just err when
+ sec->output_offset is NULL but the object with the symbol
+ is *not* dynamically linked against. Thus this will
+ automatically remind us so we can see if there are other
+ valid cases we need to revisit. */
+ && (sec->owner->flags & DYNAMIC) != 0)
+ relocation = 0;
+
+ else if (h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak)
+ {
+ /* Here follow the cases where the relocation value must
+ be zero (or when further handling is simplified when
+ zero). I can't claim to understand the various
+ conditions and they weren't described in the files
+ where I copied them from (elf32-m68k.c and
+ elf32-i386.c), but let's mention examples of where
+ they happen. FIXME: Perhaps define and use a
+ dynamic_symbol_p function like ia64.
+
+ - When creating a shared library, we can have an
+ ordinary relocation for a symbol defined in a shared
+ library (perhaps the one we create). We then make
+ the relocation value zero, as the value seen now will
+ be added into the relocation addend in this shared
+ library, but must be handled only at dynamic-link
+ time. FIXME: Not sure this example covers the
+ h->elf_link_hash_flags test, though it's there in
+ other targets. */
+ if (info->shared
+ && ((! info->symbolic && h->dynindx != -1)
+ || !h->def_regular)
+ && (input_section->flags & SEC_ALLOC) != 0
+ && (r_type == R_CRIS_8
+ || r_type == R_CRIS_16
+ || r_type == R_CRIS_32
+ || r_type == R_CRIS_8_PCREL
+ || r_type == R_CRIS_16_PCREL
+ || r_type == R_CRIS_32_PCREL))
+ relocation = 0;
+ else if (!info->relocatable && unresolved_reloc
+ && (_bfd_elf_section_offset (output_bfd, info,
+ input_section,
+ rel->r_offset)
+ != (bfd_vma) -1))
+ {
+ _bfd_error_handler
+ (_("%B, section %A: unresolvable relocation %s against symbol `%s'"),
+ input_bfd,
+ input_section,
+ cris_elf_howto_table[r_type].name,
+ symname);
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+ }
+ }
+
+ if (sec != NULL && discarded_section (sec))
+ RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+ rel, 1, relend, howto, 0, contents);
+
+ if (info->relocatable)
+ continue;
+
+ switch (r_type)
+ {
+ case R_CRIS_16_GOTPLT:
+ case R_CRIS_32_GOTPLT:
+ /* This is like the case for R_CRIS_32_GOT and R_CRIS_16_GOT,
+ but we require a PLT, and the PLT handling will take care of
+ filling in the PLT-specific GOT entry. For the GOT offset,
+ calculate it as we do when filling it in for the .got.plt
+ section. If we don't have a PLT, punt to GOT handling. */
+ if (h != NULL
+ && ((struct elf_cris_link_hash_entry *) h)->gotplt_offset != 0)
+ {
+ asection *sgotplt
+ = bfd_get_linker_section (dynobj, ".got.plt");
+ bfd_vma got_offset;
+
+ BFD_ASSERT (h->dynindx != -1);
+ BFD_ASSERT (sgotplt != NULL);
+
+ got_offset
+ = ((struct elf_cris_link_hash_entry *) h)->gotplt_offset;
+
+ relocation = got_offset;
+ break;
+ }
+
+ /* We didn't make a PLT entry for this symbol. Maybe everything is
+ folded into the GOT. Other than folding, this happens when
+ statically linking PIC code, or when using -Bsymbolic. Check
+ that we instead have a GOT entry as done for us by
+ elf_cris_adjust_dynamic_symbol, and drop through into the
+ ordinary GOT cases. This must not happen for the
+ executable, because any reference it does to a function
+ that is satisfied by a DSO must generate a PLT. We assume
+ these call-specific relocs don't address non-functions. */
+ if (h != NULL
+ && (h->got.offset == (bfd_vma) -1
+ || (!info->shared
+ && !(h->def_regular
+ || (!h->def_dynamic
+ && h->root.type == bfd_link_hash_undefweak)))))
+ {
+ (*_bfd_error_handler)
+ ((h->got.offset == (bfd_vma) -1)
+ ? _("%B, section %A: No PLT nor GOT for relocation %s"
+ " against symbol `%s'")
+ : _("%B, section %A: No PLT for relocation %s"
+ " against symbol `%s'"),
+ input_bfd,
+ input_section,
+ cris_elf_howto_table[r_type].name,
+ (symname != NULL && symname[0] != '\0'
+ ? symname : _("[whose name is lost]")));
+
+ /* FIXME: Perhaps blaming input is not the right thing to
+ do; this is probably an internal error. But it is true
+ that we didn't like that particular input. */
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+ /* Fall through. */
+
+ /* The size of the actual relocation is not used here; we only
+ fill in the GOT table here. */
+ case R_CRIS_16_GOT:
+ case R_CRIS_32_GOT:
+ {
+ bfd_vma off;
+
+ /* Note that despite using RELA relocations, the .got contents
+ is always filled in with the link-relative relocation
+ value; the addend. */
+
+ if (h != NULL)
+ {
+ off = h->got.offset;
+ BFD_ASSERT (off != (bfd_vma) -1);
+
+ if (!elf_hash_table (info)->dynamic_sections_created
+ || (! info->shared
+ && (h->def_regular
+ || h->type == STT_FUNC
+ || h->needs_plt))
+ || (info->shared
+ && (info->symbolic || h->dynindx == -1)
+ && h->def_regular))
+ {
+ /* This wasn't checked above for ! info->shared, but
+ must hold there if we get here; the symbol must
+ be defined in the regular program or be undefweak
+ or be a function or otherwise need a PLT. */
+ BFD_ASSERT (!elf_hash_table (info)->dynamic_sections_created
+ || info->shared
+ || h->def_regular
+ || h->type == STT_FUNC
+ || h->needs_plt
+ || h->root.type == bfd_link_hash_undefweak);
+
+ /* This is actually a static link, or it is a
+ -Bsymbolic link and the symbol is defined locally,
+ or is undefweak, or the symbol was forced to be
+ local because of a version file, or we're not
+ creating a dynamic object. 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.
+
+ If this GOT entry should be runtime-initialized, we
+ will 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)
+ {
+ Elf_Internal_Rela outrel;
+ bfd_byte *loc;
+
+ if (srelgot == NULL)
+ srelgot
+ = bfd_get_linker_section (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_CRIS_RELATIVE);
+ outrel.r_addend = relocation;
+ loc = srelgot->contents;
+ loc += srelgot->reloc_count++ * sizeof (Elf32_External_Rela);
+ bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
+ }
+
+ local_got_offsets[r_symndx] |= 1;
+ }
+ }
+
+ relocation = sgot->output_offset + off;
+ if (rel->r_addend != 0)
+ {
+ /* We can't do anything for a relocation which is against
+ a symbol *plus offset*. GOT holds relocations for
+ symbols. Make this an error; the compiler isn't
+ allowed to pass us these kinds of things. */
+ if (h == NULL)
+ (*_bfd_error_handler)
+ (_("%B, section %A: relocation %s with non-zero addend %d"
+ " against local symbol"),
+ input_bfd,
+ input_section,
+ cris_elf_howto_table[r_type].name,
+ rel->r_addend);
+ else
+ (*_bfd_error_handler)
+ (_("%B, section %A: relocation %s with non-zero addend %d"
+ " against symbol `%s'"),
+ input_bfd,
+ input_section,
+ cris_elf_howto_table[r_type].name,
+ rel->r_addend,
+ symname[0] != '\0' ? symname : _("[whose name is lost]"));
+
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+ }
+ break;
+
+ case R_CRIS_32_GOTREL:
+ /* This relocation must only be performed against local symbols.
+ It's also ok when we link a program and the symbol is either
+ defined in an ordinary (non-DSO) object or is undefined weak. */
+ if (h != NULL
+ && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
+ && !(!info->shared
+ && (h->def_regular
+ || (!h->def_dynamic
+ && h->root.type == bfd_link_hash_undefweak))))
+ {
+ (*_bfd_error_handler)
+ (_("%B, section %A: relocation %s is"
+ " not allowed for global symbol: `%s'"),
+ input_bfd,
+ input_section,
+ cris_elf_howto_table[r_type].name,
+ symname);
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+
+ /* This can happen if we get a link error with the input ELF
+ variant mismatching the output variant. Emit an error so
+ it's noticed if it happens elsewhere. */
+ if (sgot == NULL)
+ {
+ (*_bfd_error_handler)
+ (_("%B, section %A: relocation %s with no GOT created"),
+ input_bfd,
+ input_section,
+ cris_elf_howto_table[r_type].name);
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+
+ /* This relocation is like a PC-relative one, except the
+ reference point is the location of GOT. Note that
+ sgot->output_offset is not involved in this calculation. We
+ always want the start of entire .got section, not the
+ position after the reserved header. */
+ relocation -= sgot->output_section->vma;
+ break;
+
+ case R_CRIS_32_PLT_PCREL:
+ /* Relocation is to the entry for this symbol in the
+ procedure linkage table. */
+
+ /* Resolve a PLT_PCREL reloc against a local symbol directly,
+ without using the procedure linkage table. */
+ if (h == NULL || ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
+ break;
+
+ 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;
+
+ case R_CRIS_32_PLT_GOTREL:
+ /* Like R_CRIS_32_PLT_PCREL, but the reference point is the
+ start of the .got section. See also comment at
+ R_CRIS_32_GOT. */
+ relocation -= sgot->output_section->vma;
+
+ /* Resolve a PLT_GOTREL reloc against a local symbol directly,
+ without using the procedure linkage table. */
+ if (h == NULL || ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
+ break;
+
+ 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
+ - sgot->output_section->vma);
+ break;
+
+ case R_CRIS_8_PCREL:
+ case R_CRIS_16_PCREL:
+ case R_CRIS_32_PCREL:
+ /* If the symbol was local, we need no shlib-specific handling. */
+ if (h == NULL || ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
+ || h->dynindx == -1)
+ break;
+
+ /* Fall through. */
+ case R_CRIS_8:
+ case R_CRIS_16:
+ case R_CRIS_32:
+ if (info->shared
+ && r_symndx != STN_UNDEF
+ && (input_section->flags & SEC_ALLOC) != 0
+ && ((r_type != R_CRIS_8_PCREL
+ && r_type != R_CRIS_16_PCREL
+ && r_type != R_CRIS_32_PCREL)
+ || (!info->symbolic
+ || (h != NULL && !h->def_regular))))
+ {
+ Elf_Internal_Rela outrel;
+ bfd_byte *loc;
+ bfd_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)
+ {
+ sreloc = _bfd_elf_get_dynamic_reloc_section
+ (dynobj, input_section, /*rela?*/ TRUE);
+ /* The section should have been created in cris_elf_check_relocs,
+ but that function will not be called for objects which fail in
+ cris_elf_merge_private_bfd_data. */
+ if (sreloc == NULL)
+ {
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+ }
+
+ skip = FALSE;
+ relocate = FALSE;
+
+ outrel.r_offset =
+ _bfd_elf_section_offset (output_bfd, info, input_section,
+ rel->r_offset);
+ if (outrel.r_offset == (bfd_vma) -1)
+ skip = TRUE;
+ else if (outrel.r_offset == (bfd_vma) -2
+ /* For now, undefined weak symbols with non-default
+ visibility (yielding 0), like exception info for
+ discarded sections, will get a R_CRIS_NONE
+ relocation rather than no relocation, because we
+ notice too late that the symbol doesn't need a
+ relocation. */
+ || (h != NULL
+ && h->root.type == bfd_link_hash_undefweak
+ && ELF_ST_VISIBILITY (h->other) != STV_DEFAULT))
+ skip = TRUE, relocate = TRUE;
+ 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->def_regular))
+ {
+ BFD_ASSERT (h->dynindx != -1);
+ outrel.r_info = ELF32_R_INFO (h->dynindx, r_type);
+ outrel.r_addend = relocation + rel->r_addend;
+ }
+ else
+ {
+ outrel.r_addend = relocation + rel->r_addend;
+
+ if (r_type == R_CRIS_32)
+ {
+ relocate = TRUE;
+ outrel.r_info = ELF32_R_INFO (0, R_CRIS_RELATIVE);
+ }
+ else
+ {
+ long indx;
+
+ if (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;
+
+ /* We are turning this relocation into one
+ against a section symbol. It would be
+ proper to subtract the symbol's value,
+ osec->vma, from the emitted reloc addend,
+ but ld.so expects buggy relocs. */
+ osec = sec->output_section;
+ indx = elf_section_data (osec)->dynindx;
+ if (indx == 0)
+ {
+ osec = htab->root.text_index_section;
+ indx = elf_section_data (osec)->dynindx;
+ }
+ BFD_ASSERT (indx != 0);
+ }
+
+ outrel.r_info = ELF32_R_INFO (indx, r_type);
+ }
+ }
+
+ loc = sreloc->contents;
+ loc += sreloc->reloc_count++ * sizeof (Elf32_External_Rela);
+ bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
+
+ /* This reloc will be computed at runtime, so there's no
+ need to do anything now, except for R_CRIS_32 relocations
+ that have been turned into R_CRIS_RELATIVE. */
+ if (!relocate)
+ continue;
+ }
+
+ break;
+
+ case R_CRIS_16_DTPREL:
+ case R_CRIS_32_DTPREL:
+ /* This relocation must only be performed against local
+ symbols, or to sections that are not loadable. It's also
+ ok when we link a program and the symbol is defined in an
+ ordinary (non-DSO) object (if it's undefined there, we've
+ already seen an error). */
+ if (h != NULL
+ && (input_section->flags & SEC_ALLOC) != 0
+ && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
+ && (info->shared
+ || (!h->def_regular
+ && h->root.type != bfd_link_hash_undefined)))
+ {
+ (*_bfd_error_handler)
+ ((h->root.type == bfd_link_hash_undefined)
+ /* We shouldn't get here for GCC-emitted code. */
+ ? _("%B, section %A: relocation %s has an undefined"
+ " reference to `%s', perhaps a declaration mixup?")
+ : ("%B, section %A: relocation %s is"
+ " not allowed for `%s', a global symbol with default"
+ " visibility, perhaps a declaration mixup?"),
+ input_bfd,
+ input_section,
+ cris_elf_howto_table[r_type].name,
+ symname != NULL && symname[0] != '\0'
+ ? symname : _("[whose name is lost]"));
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+
+ BFD_ASSERT ((input_section->flags & SEC_ALLOC) == 0
+ || htab->dtpmod_refcount != 0);
+
+ /* Fill in a R_CRIS_DTPMOD reloc at offset 3 if we haven't
+ already done so. Note that we do this in .got.plt, not
+ in .got, as .got.plt contains the first part, still the
+ reloc is against .got, because the linker script directs
+ (is required to direct) them both into .got. */
+ if (htab->dtpmod_refcount > 0
+ && (input_section->flags & SEC_ALLOC) != 0)
+ {
+ asection *sgotplt = bfd_get_linker_section (dynobj, ".got.plt");
+ BFD_ASSERT (sgotplt != NULL);
+
+ if (info->shared)
+ {
+ Elf_Internal_Rela outrel;
+ bfd_byte *loc;
+
+ if (srelgot == NULL)
+ srelgot = bfd_get_linker_section (dynobj, ".rela.got");
+ BFD_ASSERT (srelgot != NULL);
+ loc = srelgot->contents;
+ loc += srelgot->reloc_count++ * sizeof (Elf32_External_Rela);
+
+ bfd_put_32 (output_bfd, (bfd_vma) 0, sgotplt->contents + 12);
+ bfd_put_32 (output_bfd, (bfd_vma) 0, sgotplt->contents + 16);
+ outrel.r_offset = (sgotplt->output_section->vma
+ + sgotplt->output_offset
+ + 12);
+ outrel.r_info = ELF32_R_INFO (0, R_CRIS_DTPMOD);
+ outrel.r_addend = 0;
+ bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
+ }
+ else
+ {
+ /* For an executable, the GOT entry contents is known. */
+ bfd_put_32 (output_bfd, (bfd_vma) 1, sgotplt->contents + 12);
+ bfd_put_32 (output_bfd, (bfd_vma) 0, sgotplt->contents + 16);
+ }
+
+ /* Reverse the sign to mark that we've emitted the
+ required GOT entry. */
+ htab->dtpmod_refcount = - htab->dtpmod_refcount;
+ }
+
+ /* The relocation is the offset from the start of the module
+ TLS block to the (local) symbol. */
+ relocation -= elf_hash_table (info)->tls_sec == NULL
+ ? 0 : elf_hash_table (info)->tls_sec->vma;
+ break;
+
+ case R_CRIS_32_GD:
+ if (info->shared)
+ {
+ bfd_set_error (bfd_error_invalid_operation);
+
+ /* We've already informed in cris_elf_check_relocs that
+ this is an error. */
+ return FALSE;
+ }
+ /* Fall through. */
+
+ case R_CRIS_16_GOT_GD:
+ case R_CRIS_32_GOT_GD:
+ if (rel->r_addend != 0)
+ {
+ /* We can't do anything for a relocation which is against a
+ symbol *plus offset*. The GOT holds relocations for
+ symbols. Make this an error; the compiler isn't allowed
+ to pass us these kinds of things. */
+ (*_bfd_error_handler)
+ (_("%B, section %A: relocation %s with non-zero addend %d"
+ " against symbol `%s'"),
+ input_bfd,
+ input_section,
+ cris_elf_howto_table[r_type].name,
+ rel->r_addend,
+ symname[0] != '\0' ? symname : _("[whose name is lost]"));
+
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+
+ if (!info->shared
+ && (h == NULL || h->def_regular || ELF_COMMON_DEF_P (h)))
+ {
+ /* Known contents of the GOT. */
+ bfd_vma off;
+
+ /* The symbol is defined in the program, so just write
+ (1, known_tpoffset) into the GOT. */
+ relocation -= elf_hash_table (info)->tls_sec->vma;
+
+ if (h != NULL)
+ {
+ off = elf_cris_hash_entry (h)->tprel_refcount > 0
+ ? h->got.offset + 4 : h->got.offset;
+ }
+ else
+ {
+ off = local_got_offsets[r_symndx];
+ if (local_got_offsets[LGOT_TPREL_NDX (r_symndx)])
+ off += 4;
+ }
+
+ /* We use bit 1 of the offset as a flag for GOT entry with
+ the R_CRIS_DTP reloc, setting it when we've emitted the
+ GOT entry and reloc. Bit 0 is used for R_CRIS_32_TPREL
+ relocs. */
+ if ((off & 2) == 0)
+ {
+ off &= ~3;
+
+ if (h != NULL)
+ h->got.offset |= 2;
+ else
+ local_got_offsets[r_symndx] |= 2;
+
+ bfd_put_32 (output_bfd, 1, sgot->contents + off);
+ bfd_put_32 (output_bfd, relocation, sgot->contents + off + 4);
+ }
+ else
+ off &= ~3;
+
+ relocation = sgot->output_offset + off
+ + (r_type == R_CRIS_32_GD ? sgot->output_section->vma : 0);
+ }
+ else
+ {
+ /* Not all parts of the GOT entry are known; emit a real
+ relocation. */
+ bfd_vma off;
+
+ if (h != NULL)
+ off = elf_cris_hash_entry (h)->tprel_refcount > 0
+ ? h->got.offset + 4 : h->got.offset;
+ else
+ {
+ off = local_got_offsets[r_symndx];
+ if (local_got_offsets[LGOT_TPREL_NDX (r_symndx)])
+ off += 4;
+ }
+
+ /* See above re bit 1 and bit 0 usage. */
+ if ((off & 2) == 0)
+ {
+ Elf_Internal_Rela outrel;
+ bfd_byte *loc;
+
+ off &= ~3;
+
+ if (h != NULL)
+ h->got.offset |= 2;
+ else
+ local_got_offsets[r_symndx] |= 2;
+
+ /* Clear the target contents of the GOT (just as a
+ gesture; it's already cleared on allocation): this
+ relocation is not like the other dynrelocs. */
+ bfd_put_32 (output_bfd, 0, sgot->contents + off);
+ bfd_put_32 (output_bfd, 0, sgot->contents + off + 4);
+
+ if (srelgot == NULL)
+ srelgot = bfd_get_linker_section (dynobj, ".rela.got");
+ BFD_ASSERT (srelgot != NULL);
+
+ if (h != NULL && h->dynindx != -1)
+ {
+ outrel.r_info = ELF32_R_INFO (h->dynindx, R_CRIS_DTP);
+ relocation = 0;
+ }
+ else
+ {
+ outrel.r_info = ELF32_R_INFO (0, R_CRIS_DTP);
+
+ /* NULL if we had an error. */
+ relocation -= elf_hash_table (info)->tls_sec == NULL
+ ? 0 : elf_hash_table (info)->tls_sec->vma;
+ }
+
+ outrel.r_offset = (sgot->output_section->vma
+ + sgot->output_offset
+ + off);
+ outrel.r_addend = relocation;
+ loc = srelgot->contents;
+ loc += srelgot->reloc_count++ * sizeof (Elf32_External_Rela);
+
+ /* NULL if we had an error. */
+ if (srelgot->contents != NULL)
+ bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
+ }
+ else
+ off &= ~3;
+
+ relocation = sgot->output_offset + off
+ + (r_type == R_CRIS_32_GD ? sgot->output_section->vma : 0);
+ }
+
+ /* The GOT-relative offset to the GOT entry is the
+ relocation, or for R_CRIS_32_GD, the actual address of
+ the GOT entry. */
+ break;
+
+ case R_CRIS_32_IE:
+ if (info->shared)
+ {
+ bfd_set_error (bfd_error_invalid_operation);
+
+ /* We've already informed in cris_elf_check_relocs that
+ this is an error. */
+ return FALSE;
+ }
+ /* Fall through. */
+
+ case R_CRIS_32_GOT_TPREL:
+ case R_CRIS_16_GOT_TPREL:
+ if (rel->r_addend != 0)
+ {
+ /* We can't do anything for a relocation which is
+ against a symbol *plus offset*. GOT holds
+ relocations for symbols. Make this an error; the
+ compiler isn't allowed to pass us these kinds of
+ things. */
+ (*_bfd_error_handler)
+ (_("%B, section %A: relocation %s with non-zero addend %d"
+ " against symbol `%s'"),
+ input_bfd,
+ input_section,
+ cris_elf_howto_table[r_type].name,
+ rel->r_addend,
+ symname[0] != '\0' ? symname : _("[whose name is lost]"));
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+
+ if (!info->shared
+ && (h == NULL || h->def_regular || ELF_COMMON_DEF_P (h)))
+ {
+ /* Known contents of the GOT. */
+ bfd_vma off;
+
+ /* The symbol is defined in the program, so just write
+ the -prog_tls_size+known_tpoffset into the GOT. */
+ relocation -= elf_hash_table (info)->tls_sec->vma;
+ relocation -= elf_hash_table (info)->tls_size;
+
+ if (h != NULL)
+ off = h->got.offset;
+ else
+ off = local_got_offsets[r_symndx];
+
+ /* Bit 0 is used to mark whether we've emitted the required
+ entry (and if needed R_CRIS_32_TPREL reloc). Bit 1
+ is used similarly for R_CRIS_DTP, see above. */
+ if ((off & 1) == 0)
+ {
+ off &= ~3;
+
+ if (h != NULL)
+ h->got.offset |= 1;
+ else
+ local_got_offsets[r_symndx] |= 1;
+
+ bfd_put_32 (output_bfd, relocation, sgot->contents + off);
+ }
+ else
+ off &= ~3;
+
+ relocation = sgot->output_offset + off
+ + (r_type == R_CRIS_32_IE ? sgot->output_section->vma : 0);
+ }
+ else
+ {
+ /* Emit a real relocation. */
+ bfd_vma off;
+
+ if (h != NULL)
+ off = h->got.offset;
+ else
+ off = local_got_offsets[r_symndx];
+
+ /* See above re usage of bit 0 and 1. */
+ if ((off & 1) == 0)
+ {
+ Elf_Internal_Rela outrel;
+ bfd_byte *loc;
+
+ off &= ~3;
+
+ if (h != NULL)
+ h->got.offset |= 1;
+ else
+ local_got_offsets[r_symndx] |= 1;
+
+ if (srelgot == NULL)
+ srelgot = bfd_get_linker_section (dynobj, ".rela.got");
+ BFD_ASSERT (srelgot != NULL);
+
+ if (h != NULL && h->dynindx != -1)
+ {
+ outrel.r_info = ELF32_R_INFO (h->dynindx, R_CRIS_32_TPREL);
+ relocation = 0;
+ }
+ else
+ {
+ outrel.r_info = ELF32_R_INFO (0, R_CRIS_32_TPREL);
+
+ /* NULL if we had an error. */
+ relocation -= elf_hash_table (info)->tls_sec == NULL
+ ? 0 : elf_hash_table (info)->tls_sec->vma;
+ }
+
+ /* Just "define" the initial contents in some
+ semi-logical way. */
+ bfd_put_32 (output_bfd, relocation, sgot->contents + off);
+
+ outrel.r_offset = (sgot->output_section->vma
+ + sgot->output_offset
+ + off);
+ outrel.r_addend = relocation;
+ loc = srelgot->contents;
+ loc += srelgot->reloc_count++ * sizeof (Elf32_External_Rela);
+ /* NULL if we had an error. */
+ if (srelgot->contents != NULL)
+ bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
+ }
+ else
+ off &= ~3;
+
+ relocation = sgot->output_offset + off
+ + (r_type == R_CRIS_32_IE ? sgot->output_section->vma : 0);
+ }
+
+ /* The GOT-relative offset to the GOT entry is the relocation,
+ or for R_CRIS_32_GD, the actual address of the GOT entry. */
+ break;
+
+ case R_CRIS_16_TPREL:
+ case R_CRIS_32_TPREL:
+ /* This relocation must only be performed against symbols
+ defined in an ordinary (non-DSO) object. */
+ if (info->shared)
+ {
+ bfd_set_error (bfd_error_invalid_operation);
+
+ /* We've already informed in cris_elf_check_relocs that
+ this is an error. */
+ return FALSE;
+ }
+
+ if (h != NULL
+ && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
+ && !(h->def_regular || ELF_COMMON_DEF_P (h))
+ /* If it's undefined, then an error message has already
+ been emitted. */
+ && h->root.type != bfd_link_hash_undefined)
+ {
+ (*_bfd_error_handler)
+ (_("%B, section %A: relocation %s is"
+ " not allowed for symbol: `%s'"
+ " which is defined outside the program,"
+ " perhaps a declaration mixup?"),
+ input_bfd,
+ input_section,
+ cris_elf_howto_table[r_type].name,
+ symname);
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+
+ /* NULL if we had an error. */
+ relocation -= elf_hash_table (info)->tls_sec == NULL
+ ? 0
+ : (elf_hash_table (info)->tls_sec->vma
+ + elf_hash_table (info)->tls_size);
+
+ /* The TLS-relative offset is the relocation. */
+ break;
+
+ default:
+ BFD_FAIL ();
+ return FALSE;
+ }
+
+ r = cris_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, (h ? &h->root : NULL), symname, howto->name,
+ (bfd_vma) 0, input_bfd, input_section, rel->r_offset);
+ if (additional_relocation_error_msg_count > 0)
+ {
+ additional_relocation_error_msg_count--;
+ switch (r_type)
+ {
+ case R_CRIS_16_GOTPLT:
+ case R_CRIS_16_GOT:
+
+ /* Not just TLS is involved here, so we make
+ generation and message depend on -fPIC/-fpic
+ only. */
+ case R_CRIS_16_GOT_TPREL:
+ case R_CRIS_16_GOT_GD:
+ (*_bfd_error_handler)
+ (_("(too many global variables for -fpic:"
+ " recompile with -fPIC)"));
+ break;
+
+ case R_CRIS_16_TPREL:
+ case R_CRIS_16_DTPREL:
+ (*_bfd_error_handler)
+ (_("(thread-local data too big for -fpic or"
+ " -msmall-tls: recompile with -fPIC or"
+ " -mno-small-tls)"));
+ break;
+
+ /* No known cause for overflow for other relocs. */
+ default:
+ break;
+ }
+ }
+ break;
+
+ case bfd_reloc_undefined:
+ r = info->callbacks->undefined_symbol
+ (info, symname, input_bfd, input_section, rel->r_offset,
+ TRUE);
+ 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, symname, input_bfd, input_section, rel->r_offset);
+
+ if (! r)
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+/* Finish up dynamic symbol handling. We set the contents of various
+ dynamic sections here. */
+
+static bfd_boolean
+elf_cris_finish_dynamic_symbol (bfd *output_bfd,
+ struct bfd_link_info *info,
+ struct elf_link_hash_entry *h,
+ Elf_Internal_Sym *sym)
+{
+ struct elf_cris_link_hash_table * htab;
+ bfd *dynobj;
+
+ /* Where in the plt entry to put values. */
+ int plt_off1 = 2, plt_off2 = 10, plt_off3 = 16;
+
+ /* What offset to add to the distance to the first PLT entry for the
+ value at plt_off3. */
+ int plt_off3_value_bias = 4;
+
+ /* Where in the PLT entry the call-dynlink-stub is (happens to be same
+ for PIC and non-PIC for v32 and pre-v32). */
+ int plt_stub_offset = 8;
+ int plt_entry_size = PLT_ENTRY_SIZE;
+ const bfd_byte *plt_entry = elf_cris_plt_entry;
+ const bfd_byte *plt_pic_entry = elf_cris_pic_plt_entry;
+
+ htab = elf_cris_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ /* Adjust the various PLT entry offsets. */
+ if (bfd_get_mach (output_bfd) == bfd_mach_cris_v32)
+ {
+ plt_off2 = 14;
+ plt_off3 = 20;
+ plt_off3_value_bias = -2;
+ plt_stub_offset = 12;
+ plt_entry_size = PLT_ENTRY_SIZE_V32;
+ plt_entry = elf_cris_plt_entry_v32;
+ plt_pic_entry = elf_cris_pic_plt_entry_v32;
+ }
+
+ dynobj = elf_hash_table (info)->dynobj;
+
+ if (h->plt.offset != (bfd_vma) -1)
+ {
+ asection *splt;
+ asection *sgotplt;
+ asection *srela;
+ bfd_vma got_base;
+
+ bfd_vma gotplt_offset
+ = elf_cris_hash_entry (h)->gotplt_offset;
+ Elf_Internal_Rela rela;
+ bfd_byte *loc;
+ bfd_boolean has_gotplt = gotplt_offset != 0;
+
+ /* Get the index in the .rela.plt relocations for the .got.plt
+ entry that corresponds to this symbol.
+ We have to count backwards here, and the result is only valid
+ as an index into .rela.plt. We also have to undo the effect
+ of the R_CRIS_DTPMOD entry at .got index 3 (offset 12 into
+ .got.plt) for which gotplt_offset is adjusted, because while
+ that entry goes into .got.plt, its relocation goes into
+ .rela.got, not .rela.plt. (It's not PLT-specific; not to be
+ processed as part of the runtime lazy .rela.plt relocation).
+ FIXME: There be literal constants here... */
+ bfd_vma rela_plt_index
+ = (htab->dtpmod_refcount != 0
+ ? gotplt_offset/4 - 2 - 3 : gotplt_offset/4 - 3);
+
+ /* Get the offset into the .got table of the entry that corresponds
+ to this function. Note that we embed knowledge that "incoming"
+ .got goes after .got.plt in the output without padding (pointer
+ aligned). However, that knowledge is present in several other
+ places too. */
+ bfd_vma got_offset
+ = (has_gotplt
+ ? gotplt_offset
+ : h->got.offset + htab->next_gotplt_entry);
+
+ /* This symbol has an entry in the procedure linkage table. Set it
+ up. */
+
+ BFD_ASSERT (h->dynindx != -1);
+
+ splt = bfd_get_linker_section (dynobj, ".plt");
+ sgotplt = bfd_get_linker_section (dynobj, ".got.plt");
+ srela = bfd_get_linker_section (dynobj, ".rela.plt");
+ BFD_ASSERT (splt != NULL && sgotplt != NULL
+ && (! has_gotplt || srela != NULL));
+
+ got_base = sgotplt->output_section->vma + sgotplt->output_offset;
+
+ /* Fill in the entry in the procedure linkage table. */
+ if (! info->shared)
+ {
+ memcpy (splt->contents + h->plt.offset, plt_entry,
+ plt_entry_size);
+
+ /* We need to enter the absolute address of the GOT entry here. */
+ bfd_put_32 (output_bfd, got_base + got_offset,
+ splt->contents + h->plt.offset + plt_off1);
+ }
+ else
+ {
+ memcpy (splt->contents + h->plt.offset, plt_pic_entry,
+ plt_entry_size);
+ bfd_put_32 (output_bfd, got_offset,
+ splt->contents + h->plt.offset + plt_off1);
+ }
+
+ /* Fill in the plt entry and make a relocation, if this is a "real"
+ PLT entry. */
+ if (has_gotplt)
+ {
+ /* Fill in the offset to the reloc table. */
+ bfd_put_32 (output_bfd,
+ rela_plt_index * sizeof (Elf32_External_Rela),
+ splt->contents + h->plt.offset + plt_off2);
+
+ /* Fill in the offset to the first PLT entry, where to "jump". */
+ bfd_put_32 (output_bfd,
+ - (h->plt.offset + plt_off3 + plt_off3_value_bias),
+ splt->contents + h->plt.offset + plt_off3);
+
+ /* Fill in the entry in the global offset table with the address of
+ the relocating stub. */
+ bfd_put_32 (output_bfd,
+ (splt->output_section->vma
+ + splt->output_offset
+ + h->plt.offset
+ + plt_stub_offset),
+ sgotplt->contents + got_offset);
+
+ /* Fill in the entry in the .rela.plt section. */
+ rela.r_offset = (sgotplt->output_section->vma
+ + sgotplt->output_offset
+ + got_offset);
+ rela.r_info = ELF32_R_INFO (h->dynindx, R_CRIS_JUMP_SLOT);
+ rela.r_addend = 0;
+ loc = srela->contents + rela_plt_index * sizeof (Elf32_External_Rela);
+ bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
+ }
+
+ if (!h->def_regular)
+ {
+ /* Mark the symbol as undefined, rather than as defined in
+ the .plt section. Leave the value alone. */
+ sym->st_shndx = SHN_UNDEF;
+
+ /* FIXME: From elf32-sparc.c 2001-02-19 (1.18). I still don't
+ know whether resetting the value is significant; if it really
+ is, rather than a quirk or bug in the sparc port, then I
+ believe we'd see this elsewhere. */
+ /* If the symbol is weak, we do need to clear the value.
+ Otherwise, the PLT entry would provide a definition for
+ the symbol even if the symbol wasn't defined anywhere,
+ and so the symbol would never be NULL. */
+ if (!h->ref_regular_nonweak)
+ sym->st_value = 0;
+ }
+ }
+
+ /* For an ordinary program, we emit .got relocs only for symbols that
+ are in the dynamic-symbols table and are either defined by the
+ program or are undefined weak symbols, or are function symbols
+ where we do not output a PLT: the PLT reloc was output above and all
+ references to the function symbol are redirected to the PLT. */
+ if (h->got.offset != (bfd_vma) -1
+ && (elf_cris_hash_entry (h)->reg_got_refcount > 0)
+ && (info->shared
+ || (h->dynindx != -1
+ && h->plt.offset == (bfd_vma) -1
+ && !h->def_regular
+ && h->root.type != bfd_link_hash_undefweak)))
+ {
+ asection *sgot;
+ asection *srela;
+ Elf_Internal_Rela rela;
+ bfd_byte *loc;
+ bfd_byte *where;
+
+ /* This symbol has an entry in the global offset table. Set it up. */
+
+ sgot = bfd_get_linker_section (dynobj, ".got");
+ srela = bfd_get_linker_section (dynobj, ".rela.got");
+ BFD_ASSERT (sgot != NULL && srela != NULL);
+
+ rela.r_offset = (sgot->output_section->vma
+ + sgot->output_offset
+ + (h->got.offset &~ (bfd_vma) 1));
+
+ /* If this is a static link, or it is a -Bsymbolic link and the
+ symbol is defined locally or was forced to be local because
+ of a version file, 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. */
+ where = sgot->contents + (h->got.offset &~ (bfd_vma) 1);
+ if (! elf_hash_table (info)->dynamic_sections_created
+ || (info->shared
+ && (info->symbolic || h->dynindx == -1)
+ && h->def_regular))
+ {
+ rela.r_info = ELF32_R_INFO (0, R_CRIS_RELATIVE);
+ rela.r_addend = bfd_get_signed_32 (output_bfd, where);
+ }
+ else
+ {
+ bfd_put_32 (output_bfd, (bfd_vma) 0, where);
+ rela.r_info = ELF32_R_INFO (h->dynindx, R_CRIS_GLOB_DAT);
+ rela.r_addend = 0;
+ }
+
+ loc = srela->contents;
+ loc += srela->reloc_count++ * sizeof (Elf32_External_Rela);
+ bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
+ }
+
+ if (h->needs_copy)
+ {
+ asection *s;
+ Elf_Internal_Rela rela;
+ bfd_byte *loc;
+
+ /* 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_linker_section (dynobj, ".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_CRIS_COPY);
+ rela.r_addend = 0;
+ loc = s->contents + s->reloc_count++ * sizeof (Elf32_External_Rela);
+ bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
+ }
+
+ /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute. */
+ if (h == elf_hash_table (info)->hdynamic
+ || h == elf_hash_table (info)->hgot)
+ sym->st_shndx = SHN_ABS;
+
+ return TRUE;
+}
+
+/* Finish up the dynamic sections. Do *not* emit relocs here, as their
+ offsets were changed, as part of -z combreloc handling, from those we
+ computed. */
+
+static bfd_boolean
+elf_cris_finish_dynamic_sections (bfd *output_bfd,
+ struct bfd_link_info *info)
+{
+ bfd *dynobj;
+ asection *sgot;
+ asection *sdyn;
+
+ dynobj = elf_hash_table (info)->dynobj;
+
+ sgot = bfd_get_linker_section (dynobj, ".got.plt");
+ BFD_ASSERT (sgot != NULL);
+ sdyn = bfd_get_linker_section (dynobj, ".dynamic");
+
+ if (elf_hash_table (info)->dynamic_sections_created)
+ {
+ asection *splt;
+ Elf32_External_Dyn *dyncon, *dynconend;
+
+ splt = bfd_get_linker_section (dynobj, ".plt");
+ BFD_ASSERT (splt != NULL && sdyn != NULL);
+
+ dyncon = (Elf32_External_Dyn *) sdyn->contents;
+ dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->size);
+ for (; dyncon < dynconend; dyncon++)
+ {
+ Elf_Internal_Dyn dyn;
+ asection *s;
+
+ bfd_elf32_swap_dyn_in (dynobj, dyncon, &dyn);
+
+ switch (dyn.d_tag)
+ {
+ default:
+ break;
+
+ case DT_PLTGOT:
+ s = bfd_get_section_by_name (output_bfd, ".got");
+ BFD_ASSERT (s != NULL);
+ dyn.d_un.d_ptr = s->vma;
+ bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
+ break;
+
+ case DT_JMPREL:
+ /* Yes, we *can* have a .plt and no .plt.rela, for instance
+ if all symbols are found in the .got (not .got.plt). */
+ s = bfd_get_section_by_name (output_bfd, ".rela.plt");
+ dyn.d_un.d_ptr = s != NULL ? s->vma : 0;
+ bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
+ break;
+
+ case DT_PLTRELSZ:
+ s = bfd_get_section_by_name (output_bfd, ".rela.plt");
+ if (s == NULL)
+ dyn.d_un.d_val = 0;
+ else
+ dyn.d_un.d_val = s->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)
+ dyn.d_un.d_val -= s->size;
+ bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
+ break;
+ }
+ }
+
+ /* Fill in the first entry in the procedure linkage table. */
+ if (splt->size > 0)
+ {
+ if (bfd_get_mach (output_bfd) == bfd_mach_cris_v32)
+ {
+ if (info->shared)
+ memcpy (splt->contents, elf_cris_pic_plt0_entry_v32,
+ PLT_ENTRY_SIZE_V32);
+ else
+ {
+ memcpy (splt->contents, elf_cris_plt0_entry_v32,
+ PLT_ENTRY_SIZE_V32);
+ bfd_put_32 (output_bfd,
+ sgot->output_section->vma
+ + sgot->output_offset + 4,
+ splt->contents + 4);
+
+ elf_section_data (splt->output_section)->this_hdr.sh_entsize
+ = PLT_ENTRY_SIZE_V32;
+ }
+ }
+ else
+ {
+ if (info->shared)
+ memcpy (splt->contents, elf_cris_pic_plt0_entry,
+ PLT_ENTRY_SIZE);
+ else
+ {
+ memcpy (splt->contents, elf_cris_plt0_entry,
+ PLT_ENTRY_SIZE);
+ bfd_put_32 (output_bfd,
+ sgot->output_section->vma
+ + sgot->output_offset + 4,
+ splt->contents + 6);
+ bfd_put_32 (output_bfd,
+ sgot->output_section->vma
+ + sgot->output_offset + 8,
+ splt->contents + 14);
+
+ 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->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;
+}
+
+/* Return the section that should be marked against GC for a given
+ relocation. */
+
+static asection *
+cris_elf_gc_mark_hook (asection *sec,
+ struct bfd_link_info *info,
+ Elf_Internal_Rela *rel,
+ struct elf_link_hash_entry *h,
+ Elf_Internal_Sym *sym)
+{
+ enum elf_cris_reloc_type r_type = ELF32_R_TYPE (rel->r_info);
+ if (h != NULL)
+ switch (r_type)
+ {
+ case R_CRIS_GNU_VTINHERIT:
+ case R_CRIS_GNU_VTENTRY:
+ return NULL;
+
+ default:
+ break;
+ }
+
+ return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
+}
+
+/* Update the got entry reference counts for the section being removed. */
+
+static bfd_boolean
+cris_elf_gc_sweep_hook (bfd *abfd,
+ struct bfd_link_info *info,
+ asection *sec,
+ const Elf_Internal_Rela *relocs)
+{
+ struct elf_cris_link_hash_table * htab;
+ Elf_Internal_Shdr *symtab_hdr;
+ struct elf_link_hash_entry **sym_hashes;
+ bfd_signed_vma *local_got_refcounts;
+ const Elf_Internal_Rela *rel, *relend;
+ bfd *dynobj;
+ asection *sgot;
+ asection *srelgot;
+
+ if (info->relocatable)
+ return TRUE;
+
+ dynobj = elf_hash_table (info)->dynobj;
+ if (dynobj == NULL)
+ return TRUE;
+
+ htab = elf_cris_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+ sym_hashes = elf_sym_hashes (abfd);
+ local_got_refcounts = elf_local_got_refcounts (abfd);
+
+ sgot = bfd_get_linker_section (dynobj, ".got");
+ srelgot = bfd_get_linker_section (dynobj, ".rela.got");
+
+ relend = relocs + sec->reloc_count;
+ for (rel = relocs; rel < relend; rel++)
+ {
+ unsigned long r_symndx;
+ struct elf_link_hash_entry *h = NULL;
+ bfd_signed_vma got_element_size = 4;
+ bfd_signed_vma *specific_refcount = NULL;
+ enum elf_cris_reloc_type r_type;
+
+ r_symndx = ELF32_R_SYM (rel->r_info);
+ if (r_symndx >= symtab_hdr->sh_info)
+ {
+ 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;
+ }
+
+ r_type = ELF32_R_TYPE (rel->r_info);
+ switch (r_type)
+ {
+ case R_CRIS_32_GOT:
+ case R_CRIS_16_GOT:
+ case R_CRIS_16_GOTPLT:
+ case R_CRIS_32_GOTPLT:
+ specific_refcount = h != NULL
+ ? &((struct elf_cris_link_hash_entry *) h)->reg_got_refcount
+ : &local_got_refcounts[LGOT_REG_NDX (r_symndx)];
+ break;
+
+ case R_CRIS_32_GD:
+ case R_CRIS_32_GOT_GD:
+ case R_CRIS_16_GOT_GD:
+ got_element_size = 8;
+ specific_refcount = h != NULL
+ ? &((struct elf_cris_link_hash_entry *) h)->dtp_refcount
+ : &local_got_refcounts[LGOT_DTP_NDX (r_symndx)];
+ break;
+
+ case R_CRIS_32_IE:
+ case R_CRIS_16_GOT_TPREL:
+ case R_CRIS_32_GOT_TPREL:
+ specific_refcount = h != NULL
+ ? &((struct elf_cris_link_hash_entry *) h)->tprel_refcount
+ : &local_got_refcounts[LGOT_TPREL_NDX (r_symndx)];
+ break;
+
+ default:
+ break;
+ }
+
+ switch (r_type)
+ {
+ case R_CRIS_32_IE:
+ case R_CRIS_32_GD:
+ case R_CRIS_16_GOT_TPREL:
+ case R_CRIS_32_GOT_TPREL:
+ case R_CRIS_32_GOT_GD:
+ case R_CRIS_16_GOT_GD:
+ case R_CRIS_16_GOT:
+ case R_CRIS_32_GOT:
+ if (h != NULL)
+ {
+ /* If the counters are 0 when we got here, we've
+ miscounted somehow somewhere, an internal error. */
+ BFD_ASSERT (h->got.refcount > 0);
+ --h->got.refcount;
+
+ BFD_ASSERT (*specific_refcount > 0);
+ --*specific_refcount;
+ if (*specific_refcount == 0)
+ {
+ /* We don't need the .got entry any more. */
+ sgot->size -= got_element_size;
+ srelgot->size -= sizeof (Elf32_External_Rela);
+ }
+ break;
+ }
+
+ local_got_reloc:
+ if (local_got_refcounts != NULL)
+ {
+ /* If the counters are 0 when we got here, we've
+ miscounted somehow somewhere, an internal error. */
+ BFD_ASSERT (local_got_refcounts[r_symndx] > 0);
+ --local_got_refcounts[r_symndx];
+
+ BFD_ASSERT (*specific_refcount > 0);
+ --*specific_refcount;
+ if (*specific_refcount == 0)
+ {
+ /* We don't need the .got entry any more. */
+ sgot->size -= got_element_size;
+ if (info->shared)
+ srelgot->size -= sizeof (Elf32_External_Rela);
+ }
+ }
+ break;
+
+ case R_CRIS_16_GOTPLT:
+ case R_CRIS_32_GOTPLT:
+ /* For local symbols, treat these like GOT relocs. */
+ if (h == NULL)
+ goto local_got_reloc;
+ else
+ /* For global symbols, adjust the reloc-specific refcount. */
+ elf_cris_hash_entry (h)->gotplt_refcount--;
+ /* Fall through. */
+
+ case R_CRIS_32_PLT_GOTREL:
+ /* FIXME: We don't garbage-collect away the .got section. */
+ if (local_got_refcounts != NULL)
+ local_got_refcounts[-1]--;
+ /* Fall through. */
+
+ case R_CRIS_8:
+ case R_CRIS_16:
+ case R_CRIS_32:
+ case R_CRIS_8_PCREL:
+ case R_CRIS_16_PCREL:
+ case R_CRIS_32_PCREL:
+ case R_CRIS_32_PLT_PCREL:
+ /* Negate the increment we did in cris_elf_check_relocs. */
+ if (h != NULL)
+ {
+ if (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
+ && h->plt.refcount > 0)
+ --h->plt.refcount;
+ }
+ break;
+
+ case R_CRIS_32_DTPREL:
+ /* This'd be a .dtpreld entry in e.g. debug info. */
+ if ((sec->flags & SEC_ALLOC) == 0)
+ break;
+ /* Fall through. */
+ case R_CRIS_16_DTPREL:
+ htab->dtpmod_refcount--;
+ if (htab->dtpmod_refcount == 0)
+ htab->next_gotplt_entry -= 8;
+ BFD_ASSERT (local_got_refcounts != NULL);
+ local_got_refcounts[-1]--;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ return TRUE;
+}
+
+/* The elf_backend_plt_sym_val hook function. */
+
+static bfd_vma
+cris_elf_plt_sym_val (bfd_vma i ATTRIBUTE_UNUSED, const asection *plt,
+ const arelent *rel)
+{
+ bfd_size_type plt_entry_size;
+ bfd_size_type pltoffs;
+ bfd *abfd = plt->owner;
+
+ /* Same for CRIS and CRIS v32; see elf_cris_(|pic_)plt_entry(|_v32)[]. */
+ bfd_size_type plt_entry_got_offset = 2;
+ bfd_size_type plt_sec_size;
+ bfd_size_type got_vma_for_dyn;
+ asection *got;
+
+ /* FIXME: the .got section should be readily available also when
+ we're not linking. */
+ if ((got = bfd_get_section_by_name (abfd, ".got")) == NULL)
+ return (bfd_vma) -1;
+
+ plt_sec_size = bfd_section_size (plt->owner, plt);
+ plt_entry_size
+ = (bfd_get_mach (abfd) == bfd_mach_cris_v32
+ ? PLT_ENTRY_SIZE_V32 : PLT_ENTRY_SIZE);
+
+ /* Data in PLT is GOT-relative for DYN, but absolute for EXE. */
+ got_vma_for_dyn = (abfd->flags & EXEC_P) ? 0 : got->vma;
+
+ /* Because we can have merged GOT entries; a single .got entry for
+ both GOT and the PLT part of the GOT (.got.plt), the index of the
+ reloc in .rela.plt is not the same as the index in the PLT.
+ Instead, we have to hunt down the GOT offset in the PLT that
+ corresponds to that of this reloc. Unfortunately, we will only
+ be called for the .rela.plt relocs, so we'll miss synthetic
+ symbols for .plt entries with merged GOT entries. (FIXME:
+ fixable by providing our own bfd_elf32_get_synthetic_symtab.
+ Doesn't seem worthwile at time of this writing.) FIXME: we've
+ gone from O(1) to O(N) (N number of PLT entries) for finding each
+ PLT address. Shouldn't matter in practice though. */
+
+ for (pltoffs = plt_entry_size;
+ pltoffs < plt_sec_size;
+ pltoffs += plt_entry_size)
+ {
+ bfd_size_type got_offset;
+ bfd_byte gotoffs_raw[4];
+
+ if (!bfd_get_section_contents (abfd, (asection *) plt, gotoffs_raw,
+ pltoffs + plt_entry_got_offset,
+ sizeof (gotoffs_raw)))
+ return (bfd_vma) -1;
+
+ got_offset = bfd_get_32 (abfd, gotoffs_raw);
+ if (got_offset + got_vma_for_dyn == rel->address)
+ return plt->vma + pltoffs;
+ }
+
+ /* While it's tempting to BFD_ASSERT that we shouldn't get here,
+ that'd not be graceful behavior for invalid input. */
+ return (bfd_vma) -1;
+}
+
+/* Make sure we emit a GOT entry if the symbol was supposed to have a PLT
+ entry but we found we will not create any. Called when we find we will
+ not have any PLT for this symbol, by for example
+ elf_cris_adjust_dynamic_symbol when we're doing a proper dynamic link,
+ or elf_cris_size_dynamic_sections if no dynamic sections will be
+ created (we're only linking static objects). */
+
+static bfd_boolean
+elf_cris_adjust_gotplt_to_got (struct elf_cris_link_hash_entry *h, void * p)
+{
+ struct bfd_link_info *info = (struct bfd_link_info *) p;
+
+ /* A GOTPLT reloc, when activated, is supposed to be included into
+ the PLT refcount. */
+ BFD_ASSERT (h->gotplt_refcount == 0
+ || h->gotplt_refcount <= h->root.plt.refcount);
+
+ /* If nobody wanted a GOTPLT with this symbol, we're done. */
+ if (h->gotplt_refcount <= 0)
+ return TRUE;
+
+ if (h->reg_got_refcount > 0)
+ {
+ /* There's a GOT entry for this symbol. Just adjust the refcounts.
+ Probably not necessary at this stage, but keeping them accurate
+ helps avoiding surprises later. */
+ h->root.got.refcount += h->gotplt_refcount;
+ h->reg_got_refcount += h->gotplt_refcount;
+ h->gotplt_refcount = 0;
+ }
+ else
+ {
+ /* No GOT entry for this symbol. We need to create one. */
+ bfd *dynobj = elf_hash_table (info)->dynobj;
+ asection *sgot;
+ asection *srelgot;
+
+ BFD_ASSERT (dynobj != NULL);
+ sgot = bfd_get_linker_section (dynobj, ".got");
+ srelgot = bfd_get_linker_section (dynobj, ".rela.got");
+
+ /* Put accurate refcounts there. */
+ h->root.got.refcount += h->gotplt_refcount;
+ h->reg_got_refcount = h->gotplt_refcount;
+
+ h->gotplt_refcount = 0;
+
+ /* We always have a .got and a .rela.got section if there were
+ GOTPLT relocs in input. */
+ BFD_ASSERT (sgot != NULL && srelgot != NULL);
+
+ /* Allocate space in the .got section. */
+ sgot->size += 4;
+
+ /* Allocate relocation space. */
+ srelgot->size += sizeof (Elf32_External_Rela);
+ }
+
+ return TRUE;
+}
+
+/* Try to fold PLT entries with GOT entries. There are two cases when we
+ want to do this:
+
+ - When all PLT references are GOTPLT references, and there are GOT
+ references, and this is not the executable. We don't have to
+ generate a PLT at all.
+
+ - When there are both (ordinary) PLT references and GOT references,
+ and this isn't the executable.
+ We want to make the PLT reference use the ordinary GOT entry rather
+ than R_CRIS_JUMP_SLOT, a run-time dynamically resolved GOTPLT entry,
+ since the GOT entry will have to be resolved at startup anyway.
+
+ Though the latter case is handled when room for the PLT is allocated,
+ not here.
+
+ By folding into the GOT, we may need a round-trip to a PLT in the
+ executable for calls, a loss in performance. Still, losing a
+ reloc is a win in size and at least in start-up time.
+
+ Note that this function is called before symbols are forced local by
+ version scripts. The differing cases are handled by
+ elf_cris_hide_symbol. */
+
+static bfd_boolean
+elf_cris_try_fold_plt_to_got (struct elf_cris_link_hash_entry *h, void * p)
+{
+ struct bfd_link_info *info = (struct bfd_link_info *) p;
+
+ /* If there are no GOT references for this symbol, we can't fold any
+ other reference so there's nothing to do. Likewise if there are no
+ PLT references; GOTPLT references included. */
+ if (h->root.got.refcount <= 0 || h->root.plt.refcount <= 0)
+ return TRUE;
+
+ /* GOTPLT relocs are supposed to be included into the PLT refcount. */
+ BFD_ASSERT (h->gotplt_refcount <= h->root.plt.refcount);
+
+ if (h->gotplt_refcount == h->root.plt.refcount)
+ {
+ /* The only PLT references are GOTPLT references, and there are GOT
+ references. Convert PLT to GOT references. */
+ if (! elf_cris_adjust_gotplt_to_got (h, info))
+ return FALSE;
+
+ /* Clear the PLT references, so no PLT will be created. */
+ h->root.plt.offset = (bfd_vma) -1;
+ }
+
+ return TRUE;
+}
+
+/* Our own version of hide_symbol, so that we can adjust a GOTPLT reloc
+ to use a GOT entry (and create one) rather than requiring a GOTPLT
+ entry. */
+
+static void
+elf_cris_hide_symbol (struct bfd_link_info *info,
+ struct elf_link_hash_entry *h,
+ bfd_boolean force_local)
+{
+ elf_cris_adjust_gotplt_to_got ((struct elf_cris_link_hash_entry *) h, info);
+
+ _bfd_elf_link_hash_hide_symbol (info, h, force_local);
+}
+
+/* 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 bfd_boolean
+elf_cris_adjust_dynamic_symbol (struct bfd_link_info *info,
+ struct elf_link_hash_entry *h)
+{
+ struct elf_cris_link_hash_table * htab;
+ bfd *dynobj;
+ asection *s;
+ bfd_size_type plt_entry_size;
+
+ htab = elf_cris_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ dynobj = elf_hash_table (info)->dynobj;
+
+ /* Make sure we know what is going on here. */
+ BFD_ASSERT (dynobj != NULL
+ && (h->needs_plt
+ || h->u.weakdef != NULL
+ || (h->def_dynamic
+ && h->ref_regular
+ && !h->def_regular)));
+
+ plt_entry_size
+ = (bfd_get_mach (dynobj) == bfd_mach_cris_v32
+ ? PLT_ENTRY_SIZE_V32 : PLT_ENTRY_SIZE);
+
+ /* 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->needs_plt)
+ {
+ /* If we link a program (not a DSO), we'll get rid of unnecessary
+ PLT entries; we point to the actual symbols -- even for pic
+ relocs, because a program built with -fpic should have the same
+ result as one built without -fpic, specifically considering weak
+ symbols.
+ FIXME: m68k and i386 differ here, for unclear reasons. */
+ if (! info->shared
+ && !h->def_dynamic)
+ {
+ /* This case can occur if we saw a PLT reloc in an input file,
+ but the symbol was not defined by a dynamic object. In such
+ a case, we don't actually need to build a procedure linkage
+ table, and we can just do an absolute or PC reloc instead, or
+ change a .got.plt index to a .got index for GOTPLT relocs. */
+ BFD_ASSERT (h->needs_plt);
+ h->needs_plt = 0;
+ h->plt.offset = (bfd_vma) -1;
+ return
+ elf_cris_adjust_gotplt_to_got ((struct
+ elf_cris_link_hash_entry *) h,
+ info);
+ }
+
+ /* If we had a R_CRIS_GLOB_DAT that didn't have to point to a PLT;
+ where a pointer-equivalent symbol was unimportant (i.e. more
+ like R_CRIS_JUMP_SLOT after symbol evaluation) we could get rid
+ of the PLT. We can't for the executable, because the GOT
+ entries will point to the PLT there (and be constant). */
+ if (info->shared
+ && !elf_cris_try_fold_plt_to_got ((struct elf_cris_link_hash_entry*)
+ h, info))
+ return FALSE;
+
+ /* GC or folding may have rendered this entry unused. */
+ if (h->plt.refcount <= 0)
+ {
+ h->needs_plt = 0;
+ h->plt.offset = (bfd_vma) -1;
+ return TRUE;
+ }
+
+ /* Make sure this symbol is output as a dynamic symbol. */
+ if (h->dynindx == -1)
+ {
+ if (! bfd_elf_link_record_dynamic_symbol (info, h))
+ return FALSE;
+ }
+
+ s = bfd_get_linker_section (dynobj, ".plt");
+ BFD_ASSERT (s != NULL);
+
+ /* If this is the first .plt entry, make room for the special
+ first entry. */
+ if (s->size == 0)
+ s->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. */
+ if (!info->shared
+ && !h->def_regular)
+ {
+ h->root.u.def.section = s;
+ h->root.u.def.value = s->size;
+ }
+
+ /* If there's already a GOT entry, use that, not a .got.plt. A
+ GOT field still has a reference count when we get here; it's
+ not yet changed to an offset. We can't do this for an
+ executable, because then the reloc associated with the PLT
+ would get a non-PLT reloc pointing to the PLT. FIXME: Move
+ this to elf_cris_try_fold_plt_to_got. */
+ if (info->shared && h->got.refcount > 0)
+ {
+ h->got.refcount += h->plt.refcount;
+
+ /* Mark the PLT offset to use the GOT entry by setting the low
+ bit in the plt offset; it is always a multiple of
+ plt_entry_size (which is at least a multiple of 2). */
+ BFD_ASSERT ((s->size % plt_entry_size) == 0);
+
+ /* Change the PLT refcount to an offset. */
+ h->plt.offset = s->size;
+
+ /* By not setting gotplt_offset (i.e. it remains at 0), we signal
+ that the got entry should be used instead. */
+ BFD_ASSERT (((struct elf_cris_link_hash_entry *)
+ h)->gotplt_offset == 0);
+
+ /* Make room for this entry. */
+ s->size += plt_entry_size;
+
+ return TRUE;
+ }
+
+ /* No GOT reference for this symbol; prepare for an ordinary PLT. */
+ h->plt.offset = s->size;
+
+ /* Make room for this entry. */
+ s->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. */
+ ((struct elf_cris_link_hash_entry *) h)->gotplt_offset
+ = htab->next_gotplt_entry;
+ htab->next_gotplt_entry += 4;
+
+ s = bfd_get_linker_section (dynobj, ".got.plt");
+ BFD_ASSERT (s != NULL);
+ s->size += 4;
+
+ /* We also need to make an entry in the .rela.plt section. */
+
+ s = bfd_get_linker_section (dynobj, ".rela.plt");
+ BFD_ASSERT (s != NULL);
+ s->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->u.weakdef != NULL)
+ {
+ BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
+ || h->u.weakdef->root.type == bfd_link_hash_defweak);
+ h->root.u.def.section = h->u.weakdef->root.u.def.section;
+ h->root.u.def.value = h->u.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;
+
+ /* If there are no references to this symbol that do not use the
+ GOT, we don't need to generate a copy reloc. */
+ if (!h->non_got_ref)
+ 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_linker_section (dynobj, ".dynbss");
+ BFD_ASSERT (s != NULL);
+
+ /* We must generate a R_CRIS_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 && h->size != 0)
+ {
+ asection *srel;
+
+ srel = bfd_get_linker_section (dynobj, ".rela.bss");
+ BFD_ASSERT (srel != NULL);
+ srel->size += sizeof (Elf32_External_Rela);
+ h->needs_copy = 1;
+ }
+
+ return _bfd_elf_adjust_dynamic_copy (h, s);
+}
+
+/* Adjust our "subclass" elements for an indirect symbol. */
+
+static void
+elf_cris_copy_indirect_symbol (struct bfd_link_info *info,
+ struct elf_link_hash_entry *dir,
+ struct elf_link_hash_entry *ind)
+{
+ struct elf_cris_link_hash_entry *edir, *eind;
+
+ edir = (struct elf_cris_link_hash_entry *) dir;
+ eind = (struct elf_cris_link_hash_entry *) ind;
+
+ /* Only indirect symbols are replaced; we're not interested in
+ updating any of EIND's fields for other symbols. */
+ if (eind->root.root.type != bfd_link_hash_indirect)
+ {
+ /* Still, we need to copy flags for e.g. weak definitions. */
+ _bfd_elf_link_hash_copy_indirect (info, dir, ind);
+ return;
+ }
+
+ BFD_ASSERT (edir->gotplt_offset == 0 || eind->gotplt_offset == 0);
+
+#define XMOVOPZ(F, OP, Z) edir->F OP eind->F; eind->F = Z
+#define XMOVE(F) XMOVOPZ (F, +=, 0)
+ if (eind->pcrel_relocs_copied != NULL)
+ {
+ if (edir->pcrel_relocs_copied != NULL)
+ {
+ struct elf_cris_pcrel_relocs_copied **pp;
+ struct elf_cris_pcrel_relocs_copied *p;
+
+ /* Add reloc counts against the indirect sym to the direct sym
+ list. Merge any entries against the same section. */
+ for (pp = &eind->pcrel_relocs_copied; *pp != NULL;)
+ {
+ struct elf_cris_pcrel_relocs_copied *q;
+ p = *pp;
+ for (q = edir->pcrel_relocs_copied; q != NULL; q = q->next)
+ if (q->section == p->section)
+ {
+ q->count += p->count;
+ *pp = p->next;
+ break;
+ }
+ if (q == NULL)
+ pp = &p->next;
+ }
+ *pp = edir->pcrel_relocs_copied;
+ }
+ XMOVOPZ (pcrel_relocs_copied, =, NULL);
+ }
+ XMOVE (gotplt_refcount);
+ XMOVE (gotplt_offset);
+ XMOVE (reg_got_refcount);
+ XMOVE (tprel_refcount);
+ XMOVE (dtp_refcount);
+#undef XMOVE
+#undef XMOVOPZ
+
+ _bfd_elf_link_hash_copy_indirect (info, dir, ind);
+}
+
+/* Look through the relocs for a section during the first phase. */
+
+static bfd_boolean
+cris_elf_check_relocs (bfd *abfd,
+ struct bfd_link_info *info,
+ asection *sec,
+ const Elf_Internal_Rela *relocs)
+{
+ struct elf_cris_link_hash_table * htab;
+ 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->relocatable)
+ return TRUE;
+
+ htab = elf_cris_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ 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++)
+ {
+ struct elf_link_hash_entry *h;
+ unsigned long r_symndx;
+ enum elf_cris_reloc_type r_type;
+ bfd_signed_vma got_element_size = 4;
+ unsigned long r_symndx_lgot = INT_MAX;
+
+ r_symndx = ELF32_R_SYM (rel->r_info);
+ if (r_symndx < symtab_hdr->sh_info)
+ {
+ h = NULL;
+ r_symndx_lgot = LGOT_REG_NDX (r_symndx);
+ }
+ 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;
+
+ /* PR15323, ref flags aren't set for references in the same
+ object. */
+ h->root.non_ir_ref = 1;
+ }
+
+ r_type = ELF32_R_TYPE (rel->r_info);
+
+ /* Some relocs require linker-created sections; we need to hang them
+ on the first input bfd we found that contained dynamic relocs. */
+ switch (r_type)
+ {
+ case R_CRIS_32_DTPREL:
+ if ((sec->flags & SEC_ALLOC) == 0)
+ /* This'd be a .dtpreld entry in e.g. debug info. We have
+ several different switch statements below, but none of
+ that is needed; we need no preparations for resolving
+ R_CRIS_32_DTPREL into a non-allocated section (debug
+ info), so let's just move on to the next
+ relocation. */
+ continue;
+ /* Fall through. */
+ case R_CRIS_16_DTPREL:
+ /* The first .got.plt entry is right after the R_CRIS_DTPMOD
+ entry at index 3. */
+ if (htab->dtpmod_refcount == 0)
+ htab->next_gotplt_entry += 8;
+
+ htab->dtpmod_refcount++;
+ /* Fall through. */
+
+ case R_CRIS_32_IE:
+ case R_CRIS_32_GD:
+ case R_CRIS_16_GOT_GD:
+ case R_CRIS_32_GOT_GD:
+ case R_CRIS_32_GOT_TPREL:
+ case R_CRIS_16_GOT_TPREL:
+ case R_CRIS_16_GOT:
+ case R_CRIS_32_GOT:
+ case R_CRIS_32_GOTREL:
+ case R_CRIS_32_PLT_GOTREL:
+ case R_CRIS_32_PLT_PCREL:
+ case R_CRIS_16_GOTPLT:
+ case R_CRIS_32_GOTPLT:
+ if (dynobj == NULL)
+ {
+ elf_hash_table (info)->dynobj = dynobj = abfd;
+
+ /* We could handle this if we can get a handle on the
+ output bfd in elf_cris_adjust_dynamic_symbol. Failing
+ that, we must insist on dynobj being a specific mach. */
+ if (bfd_get_mach (dynobj) == bfd_mach_cris_v10_v32)
+ {
+ (*_bfd_error_handler)
+ (_("%B, section %A:\n v10/v32 compatible object %s"
+ " must not contain a PIC relocation"),
+ abfd, sec);
+ return FALSE;
+ }
+ }
+
+ if (sgot == NULL)
+ {
+ /* We may have a dynobj but no .got section, if machine-
+ independent parts of the linker found a reason to create
+ a dynobj. We want to create the .got section now, so we
+ can assume it's always present whenever there's a dynobj.
+ It's ok to call this function more than once. */
+ if (!_bfd_elf_create_got_section (dynobj, info))
+ return FALSE;
+
+ sgot = bfd_get_linker_section (dynobj, ".got");
+ }
+
+ if (local_got_refcounts == NULL)
+ {
+ bfd_size_type amt;
+
+ /* We use index local_got_refcounts[-1] to count all
+ GOT-relative relocations that do not have explicit
+ GOT entries. */
+ amt = LGOT_ALLOC_NELTS_FOR (symtab_hdr->sh_info) + 1;
+ amt *= sizeof (bfd_signed_vma);
+ local_got_refcounts = ((bfd_signed_vma *) bfd_zalloc (abfd, amt));
+ if (local_got_refcounts == NULL)
+ return FALSE;
+
+ local_got_refcounts++;
+ elf_local_got_refcounts (abfd) = local_got_refcounts;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ /* Some relocs require a global offset table (but perhaps not a
+ specific GOT entry). */
+ switch (r_type)
+ {
+ case R_CRIS_16_DTPREL:
+ case R_CRIS_32_DTPREL:
+ /* Not requesting .got.rela for an executable: the contents
+ of the first entry is constant there. For a shared
+ library, we need .got.rela for the R_CRIS_DTPMOD
+ relocation at index 3. */
+ if (!info->shared)
+ break;
+ /* Fall through. */
+
+ case R_CRIS_32_IE:
+ case R_CRIS_32_GD:
+ case R_CRIS_16_GOT_GD:
+ case R_CRIS_32_GOT_GD:
+ case R_CRIS_32_GOT_TPREL:
+ case R_CRIS_16_GOT_TPREL:
+ /* Fall through. */
+
+ /* For R_CRIS_16_GOTPLT and R_CRIS_32_GOTPLT, we need a GOT
+ entry only for local symbols. Unfortunately, we don't know
+ until later on if there's a version script that forces the
+ symbol local. We must have the .rela.got section in place
+ before we know if the symbol looks global now, so we need
+ to treat the reloc just like for R_CRIS_16_GOT and
+ R_CRIS_32_GOT. */
+ case R_CRIS_16_GOTPLT:
+ case R_CRIS_32_GOTPLT:
+ case R_CRIS_16_GOT:
+ case R_CRIS_32_GOT:
+ if (srelgot == NULL
+ && (h != NULL || info->shared))
+ {
+ srelgot = bfd_get_linker_section (dynobj, ".rela.got");
+ if (srelgot == NULL)
+ {
+ flagword flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS
+ | SEC_IN_MEMORY | SEC_LINKER_CREATED
+ | SEC_READONLY);
+ srelgot = bfd_make_section_anyway_with_flags (dynobj,
+ ".rela.got",
+ flags);
+ if (srelgot == NULL
+ || !bfd_set_section_alignment (dynobj, srelgot, 2))
+ return FALSE;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ /* Warn and error for invalid input. */
+ switch (r_type)
+ {
+ case R_CRIS_32_IE:
+ case R_CRIS_32_TPREL:
+ case R_CRIS_16_TPREL:
+ case R_CRIS_32_GD:
+ if (info->shared)
+ {
+ (*_bfd_error_handler)
+ (_("%B, section %A:\n relocation %s not valid"
+ " in a shared object;"
+ " typically an option mixup, recompile with -fPIC"),
+ abfd,
+ sec,
+ cris_elf_howto_table[r_type].name);
+ /* Don't return FALSE here; we want messages for all of
+ these and the error behavior is ungraceful
+ anyway. */
+ }
+ default:
+ break;
+ }
+
+ switch (r_type)
+ {
+ case R_CRIS_32_GD:
+ case R_CRIS_16_GOT_GD:
+ case R_CRIS_32_GOT_GD:
+ /* These are requests for tls_index entries, run-time R_CRIS_DTP. */
+ got_element_size = 8;
+ r_symndx_lgot = LGOT_DTP_NDX (r_symndx);
+ break;
+
+ case R_CRIS_16_DTPREL:
+ case R_CRIS_32_DTPREL:
+ /* These two just request for the constant-index
+ module-local tls_index-sized GOT entry, which we add
+ elsewhere. */
+ break;
+
+ case R_CRIS_32_IE:
+ case R_CRIS_32_GOT_TPREL:
+ case R_CRIS_16_GOT_TPREL:
+ r_symndx_lgot = LGOT_TPREL_NDX (r_symndx);
+
+ /* Those relocs also require that a DSO is of type
+ Initial Exec. Like other targets, we don't reset this
+ flag even if the relocs are GC:ed away. */
+ if (info->shared)
+ info->flags |= DF_STATIC_TLS;
+ break;
+
+ /* Let's list the other assembler-generated TLS-relocs too,
+ just to show that they're not forgotten. */
+ case R_CRIS_16_TPREL:
+ case R_CRIS_32_TPREL:
+ default:
+ break;
+ }
+
+ switch (r_type)
+ {
+ case R_CRIS_16_GOTPLT:
+ case R_CRIS_32_GOTPLT:
+ /* Mark that we need a GOT entry if the PLT entry (and its GOT
+ entry) is eliminated. We can only do this for a non-local
+ symbol. */
+ if (h != NULL)
+ {
+ elf_cris_hash_entry (h)->gotplt_refcount++;
+ goto handle_gotplt_reloc;
+ }
+ /* If h is NULL then this is a local symbol, and we must make a
+ GOT entry for it, so handle it like a GOT reloc. */
+ /* Fall through. */
+
+ case R_CRIS_32_IE:
+ case R_CRIS_32_GD:
+ case R_CRIS_16_GOT_GD:
+ case R_CRIS_32_GOT_GD:
+ case R_CRIS_32_GOT_TPREL:
+ case R_CRIS_16_GOT_TPREL:
+ case R_CRIS_16_GOT:
+ case R_CRIS_32_GOT:
+ /* This symbol requires a global offset table entry. */
+ if (h != NULL)
+ {
+ if (h->got.refcount == 0)
+ {
+ /* Make sure this symbol is output as a dynamic symbol. */
+ if (h->dynindx == -1)
+ {
+ if (!bfd_elf_link_record_dynamic_symbol (info, h))
+ return FALSE;
+ }
+ }
+
+ /* Update the sum of reloc counts for this symbol. */
+ h->got.refcount++;
+
+ switch (r_type)
+ {
+ case R_CRIS_16_GOT:
+ case R_CRIS_32_GOT:
+ if (elf_cris_hash_entry (h)->reg_got_refcount == 0)
+ {
+ /* Allocate space in the .got section. */
+ sgot->size += got_element_size;
+ /* Allocate relocation space. */
+ srelgot->size += sizeof (Elf32_External_Rela);
+ }
+ elf_cris_hash_entry (h)->reg_got_refcount++;
+ break;
+
+ case R_CRIS_32_GD:
+ case R_CRIS_16_GOT_GD:
+ case R_CRIS_32_GOT_GD:
+ if (elf_cris_hash_entry (h)->dtp_refcount == 0)
+ {
+ /* Allocate space in the .got section. */
+ sgot->size += got_element_size;
+ /* Allocate relocation space. */
+ srelgot->size += sizeof (Elf32_External_Rela);
+ }
+ elf_cris_hash_entry (h)->dtp_refcount++;
+ break;
+
+ case R_CRIS_32_IE:
+ case R_CRIS_32_GOT_TPREL:
+ case R_CRIS_16_GOT_TPREL:
+ if (elf_cris_hash_entry (h)->tprel_refcount == 0)
+ {
+ /* Allocate space in the .got section. */
+ sgot->size += got_element_size;
+ /* Allocate relocation space. */
+ srelgot->size += sizeof (Elf32_External_Rela);
+ }
+ elf_cris_hash_entry (h)->tprel_refcount++;
+ break;
+
+ default:
+ BFD_FAIL ();
+ break;
+ }
+ }
+ else
+ {
+ /* This is a global offset table entry for a local symbol. */
+ if (local_got_refcounts[r_symndx_lgot] == 0)
+ {
+ sgot->size += got_element_size;
+ if (info->shared)
+ {
+ /* If we are generating a shared object, we need
+ to output a R_CRIS_RELATIVE reloc so that the
+ dynamic linker can adjust this GOT entry.
+ Similarly for non-regular got entries. */
+ srelgot->size += sizeof (Elf32_External_Rela);
+ }
+ }
+ /* Update the reloc-specific count. */
+ local_got_refcounts[r_symndx_lgot]++;
+
+ /* This one is the sum of all the others. */
+ local_got_refcounts[r_symndx]++;
+ }
+ break;
+
+ case R_CRIS_16_DTPREL:
+ case R_CRIS_32_DTPREL:
+ case R_CRIS_32_GOTREL:
+ /* This reference requires a global offset table.
+ FIXME: The actual refcount isn't used currently; the .got
+ section can't be removed if there were any references in the
+ input. */
+ local_got_refcounts[-1]++;
+ break;
+
+ handle_gotplt_reloc:
+
+ case R_CRIS_32_PLT_GOTREL:
+ /* This reference requires a global offset table. */
+ local_got_refcounts[-1]++;
+ /* Fall through. */
+
+ case R_CRIS_32_PLT_PCREL:
+ /* 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. */
+
+ /* Beware: if we'd check for visibility of the symbol here
+ (and not marking the need for a PLT when non-visible), we'd
+ get into trouble with keeping handling consistent with
+ regards to relocs found before definition and GOTPLT
+ handling. Eliminable PLT entries will be dealt with later
+ anyway. */
+ if (h == NULL)
+ continue;
+
+ h->needs_plt = 1;
+ h->plt.refcount++;
+ break;
+
+ case R_CRIS_8:
+ case R_CRIS_16:
+ case R_CRIS_32:
+ /* Let's help debug shared library creation. Any of these
+ relocs *can* be used in shared libs, but pages containing
+ them cannot be shared, so they're not appropriate for
+ common use. Don't warn for sections we don't care about,
+ such as debug sections or non-constant sections. We
+ can't help tables of (global) function pointers, for
+ example, though they must be emitted in a (writable) data
+ section to avoid having impure text sections. */
+ if (info->shared
+ && (sec->flags & SEC_ALLOC) != 0
+ && (sec->flags & SEC_READONLY) != 0)
+ {
+ /* FIXME: How do we make this optionally a warning only? */
+ (*_bfd_error_handler)
+ (_("%B, section %A:\n relocation %s should not"
+ " be used in a shared object; recompile with -fPIC"),
+ abfd,
+ sec,
+ cris_elf_howto_table[r_type].name);
+ }
+
+ /* We don't need to handle relocs into sections not going into
+ the "real" output. */
+ if ((sec->flags & SEC_ALLOC) == 0)
+ break;
+
+ if (h != NULL)
+ {
+ h->non_got_ref = 1;
+
+ /* Make sure a plt entry is created for this symbol if it
+ turns out to be a function defined by a dynamic object. */
+ if (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)
+ h->plt.refcount++;
+ }
+
+ /* 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). In case of a weak
+ definition, DEF_REGULAR may be cleared later by a strong
+ definition in a shared library. We account for that
+ possibility below by storing information in the relocs_copied
+ field of the hash table entry. A similar situation occurs
+ when creating shared libraries and symbol visibility changes
+ render the symbol local. */
+
+ /* No need to do anything if we're not creating a shared object. */
+ if (! info->shared)
+ break;
+
+ /* We may need to create a reloc section in the dynobj and made room
+ for this reloc. */
+ if (sreloc == NULL)
+ {
+ sreloc = _bfd_elf_make_dynamic_reloc_section
+ (sec, dynobj, 2, abfd, /*rela?*/ TRUE);
+
+ if (sreloc == NULL)
+ return FALSE;
+ }
+
+ if (sec->flags & SEC_READONLY)
+ info->flags |= DF_TEXTREL;
+
+ sreloc->size += sizeof (Elf32_External_Rela);
+ break;
+
+ case R_CRIS_8_PCREL:
+ case R_CRIS_16_PCREL:
+ case R_CRIS_32_PCREL:
+ if (h != NULL)
+ {
+ h->non_got_ref = 1;
+
+ /* Make sure a plt entry is created for this symbol if it
+ turns out to be a function defined by a dynamic object. */
+ if (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)
+ h->plt.refcount++;
+ }
+
+ /* 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). In case of a weak
+ definition, DEF_REGULAR may be cleared later by a strong
+ definition in a shared library. We account for that
+ possibility below by storing information in the relocs_copied
+ field of the hash table entry. A similar situation occurs
+ when creating shared libraries and symbol visibility changes
+ render the symbol local. */
+
+ /* No need to do anything if we're not creating a shared object. */
+ if (! info->shared)
+ break;
+
+ /* We don't need to handle relocs into sections not going into
+ the "real" output. */
+ if ((sec->flags & SEC_ALLOC) == 0)
+ break;
+
+ /* If the symbol is local, then we know already we can
+ eliminate the reloc. */
+ if (h == NULL || ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
+ break;
+
+ /* If this is with -Bsymbolic and the symbol isn't weak, and
+ is defined by an ordinary object (the ones we include in
+ this shared library) then we can also eliminate the
+ reloc. See comment above for more eliminable cases which
+ we can't identify at this time. */
+ if (info->symbolic
+ && h->root.type != bfd_link_hash_defweak
+ && h->def_regular)
+ break;
+
+ /* We may need to create a reloc section in the dynobj and made room
+ for this reloc. */
+ if (sreloc == NULL)
+ {
+ sreloc = _bfd_elf_make_dynamic_reloc_section
+ (sec, dynobj, 2, abfd, /*rela?*/ TRUE);
+
+ if (sreloc == NULL)
+ return FALSE;
+ }
+
+ sreloc->size += sizeof (Elf32_External_Rela);
+
+ /* 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.
+ We know that h is really a pointer to an
+ elf_cris_link_hash_entry. */
+ {
+ struct elf_cris_link_hash_entry *eh;
+ struct elf_cris_pcrel_relocs_copied *p;
+
+ eh = elf_cris_hash_entry (h);
+
+ for (p = eh->pcrel_relocs_copied; p != NULL; p = p->next)
+ if (p->section == sec)
+ break;
+
+ if (p == NULL)
+ {
+ p = ((struct elf_cris_pcrel_relocs_copied *)
+ bfd_alloc (dynobj, (bfd_size_type) sizeof *p));
+ if (p == NULL)
+ return FALSE;
+ p->next = eh->pcrel_relocs_copied;
+ eh->pcrel_relocs_copied = p;
+ p->section = sec;
+ p->count = 0;
+ p->r_type = r_type;
+ }
+
+ ++p->count;
+ }
+ break;
+
+ /* This relocation describes the C++ object vtable hierarchy.
+ Reconstruct it for later use during GC. */
+ case R_CRIS_GNU_VTINHERIT:
+ if (!bfd_elf_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_CRIS_GNU_VTENTRY:
+ BFD_ASSERT (h != NULL);
+ if (h != NULL
+ && !bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
+ return FALSE;
+ break;
+
+ case R_CRIS_16_TPREL:
+ case R_CRIS_32_TPREL:
+ /* Already warned above, when necessary. */
+ break;
+
+ default:
+ /* Other relocs do not appear here. */
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+/* Set the sizes of the dynamic sections. */
+
+static bfd_boolean
+elf_cris_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
+ struct bfd_link_info *info)
+{
+ struct elf_cris_link_hash_table * htab;
+ bfd *dynobj;
+ asection *s;
+ bfd_boolean plt;
+ bfd_boolean relocs;
+
+ htab = elf_cris_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ 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->executable)
+ {
+ s = bfd_get_linker_section (dynobj, ".interp");
+ BFD_ASSERT (s != NULL);
+ s->size = sizeof ELF_DYNAMIC_INTERPRETER;
+ s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
+ }
+ }
+ else
+ {
+ /* Adjust all expected GOTPLT uses to use a GOT entry instead. */
+ elf_cris_link_hash_traverse (htab, elf_cris_adjust_gotplt_to_got,
+ info);
+
+ /* 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_linker_section (dynobj, ".rela.got");
+ if (s != NULL)
+ s->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. We also discard space
+ for relocs that have become for local symbols due to symbol
+ visibility changes. For programs, we discard space for relocs for
+ symbols not referenced by any dynamic object. */
+ if (info->shared)
+ elf_cris_link_hash_traverse (htab,
+ elf_cris_discard_excess_dso_dynamics,
+ info);
+ else
+ elf_cris_link_hash_traverse (htab,
+ elf_cris_discard_excess_program_dynamics,
+ info);
+
+ /* 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;
+ for (s = dynobj->sections; s != NULL; s = s->next)
+ {
+ const char *name;
+
+ 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);
+
+ if (strcmp (name, ".plt") == 0)
+ {
+ /* Remember whether there is a PLT. */
+ plt = s->size != 0;
+ }
+ else if (strcmp (name, ".got.plt") == 0)
+ {
+ /* The .got.plt contains the .got header as well as the
+ actual .got.plt contents. The .got header may contain a
+ R_CRIS_DTPMOD entry at index 3. */
+ s->size += htab->dtpmod_refcount != 0
+ ? 8 : 0;
+ }
+ else if (CONST_STRNEQ (name, ".rela"))
+ {
+ if (strcmp (name, ".rela.got") == 0
+ && htab->dtpmod_refcount != 0
+ && info->shared)
+ s->size += sizeof (Elf32_External_Rela);
+
+ if (s->size != 0)
+ {
+ /* Remember whether there are any reloc sections other
+ than .rela.plt. */
+ if (strcmp (name, ".rela.plt") != 0)
+ relocs = 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 (! CONST_STRNEQ (name, ".got")
+ && strcmp (name, ".dynbss") != 0)
+ {
+ /* It's not one of our sections, so don't allocate space. */
+ continue;
+ }
+
+ if (s->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. */
+ s->flags |= SEC_EXCLUDE;
+ continue;
+ }
+
+ if ((s->flags & SEC_HAS_CONTENTS) == 0)
+ continue;
+
+ /* Allocate memory for the section contents. We use bfd_zalloc here
+ in case unused entries are not reclaimed before the section's
+ contents are written out. This should not happen, but this way
+ if it does, we will not write out garbage. For reloc sections,
+ this will make entries have the type R_CRIS_NONE. */
+ s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->size);
+ if (s->contents == NULL)
+ 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_cris_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. */
+#define add_dynamic_entry(TAG, VAL) \
+ _bfd_elf_add_dynamic_entry (info, TAG, VAL)
+
+ if (!info->shared)
+ {
+ if (!add_dynamic_entry (DT_DEBUG, 0))
+ return FALSE;
+ }
+
+ if (plt)
+ {
+ if (!add_dynamic_entry (DT_PLTGOT, 0)
+ || !add_dynamic_entry (DT_PLTRELSZ, 0)
+ || !add_dynamic_entry (DT_PLTREL, DT_RELA)
+ || !add_dynamic_entry (DT_JMPREL, 0))
+ return FALSE;
+ }
+
+ if (relocs)
+ {
+ if (!add_dynamic_entry (DT_RELA, 0)
+ || !add_dynamic_entry (DT_RELASZ, 0)
+ || !add_dynamic_entry (DT_RELAENT, sizeof (Elf32_External_Rela)))
+ return FALSE;
+ }
+
+ if ((info->flags & DF_TEXTREL) != 0)
+ {
+ if (!add_dynamic_entry (DT_TEXTREL, 0))
+ return FALSE;
+ info->flags |= DF_TEXTREL;
+ }
+ }
+#undef add_dynamic_entry
+
+ return TRUE;
+}
+
+/* This function is called via elf_cris_link_hash_traverse if we are
+ creating a shared object. In the -Bsymbolic case, it discards the
+ space allocated to copy PC relative relocs against symbols which
+ are defined in regular objects. For the normal non-symbolic case,
+ we also discard space for relocs that have become local due to
+ symbol visibility changes. We allocated space for them in the
+ check_relocs routine, but we won't fill them in in the
+ relocate_section routine. */
+
+static bfd_boolean
+elf_cris_discard_excess_dso_dynamics (struct elf_cris_link_hash_entry *h,
+ void * inf)
+{
+ struct elf_cris_pcrel_relocs_copied *s;
+ struct bfd_link_info *info = (struct bfd_link_info *) inf;
+
+ /* If a symbol has been forced local or we have found a regular
+ definition for the symbolic link case, then we won't be needing
+ any relocs. */
+ if (h->root.def_regular
+ && (h->root.forced_local
+ || info->symbolic))
+ {
+ for (s = h->pcrel_relocs_copied; s != NULL; s = s->next)
+ {
+ asection *sreloc
+ = _bfd_elf_get_dynamic_reloc_section (elf_hash_table (info)
+ ->dynobj,
+ s->section,
+ /*rela?*/ TRUE);
+ sreloc->size -= s->count * sizeof (Elf32_External_Rela);
+ }
+ return TRUE;
+ }
+
+ /* If we have accounted for PC-relative relocs for read-only
+ sections, now is the time to warn for them. We can't do it in
+ cris_elf_check_relocs, because we don't know the status of all
+ symbols at that time (and it's common to force symbols local
+ late). */
+
+ for (s = h->pcrel_relocs_copied; s != NULL; s = s->next)
+ if ((s->section->flags & SEC_READONLY) != 0)
+ {
+ /* FIXME: How do we make this optionally a warning only? */
+ (*_bfd_error_handler)
+ (_("%B, section `%A', to symbol `%s':\n"
+ " relocation %s should not be used"
+ " in a shared object; recompile with -fPIC"),
+ s->section->owner,
+ s->section,
+ h->root.root.root.string,
+ cris_elf_howto_table[s->r_type].name);
+
+ info->flags |= DF_TEXTREL;
+ }
+
+ return TRUE;
+}
+
+/* This function is called via elf_cris_link_hash_traverse if we are *not*
+ creating a shared object. We discard space for relocs for symbols put
+ in the .got, but which we found we do not have to resolve at run-time. */
+
+static bfd_boolean
+elf_cris_discard_excess_program_dynamics (struct elf_cris_link_hash_entry *h,
+ void * inf)
+{
+ struct bfd_link_info *info = (struct bfd_link_info *) inf;
+
+ /* If we're not creating a shared library and have a symbol which is
+ referred to by .got references, but the symbol is defined locally,
+ (or rather, not defined by a DSO) then lose the reloc for the .got
+ (don't allocate room for it). Likewise for relocs for something
+ for which we create a PLT. */
+ if (!h->root.def_dynamic
+ || h->root.plt.refcount > 0)
+ {
+ if (h->reg_got_refcount > 0
+ /* The size of this section is only valid and in sync with the
+ various reference counts if we do dynamic; don't decrement it
+ otherwise. */
+ && elf_hash_table (info)->dynamic_sections_created)
+ {
+ bfd *dynobj = elf_hash_table (info)->dynobj;
+ asection *srelgot;
+
+ BFD_ASSERT (dynobj != NULL);
+
+ srelgot = bfd_get_linker_section (dynobj, ".rela.got");
+
+ BFD_ASSERT (srelgot != NULL);
+
+ srelgot->size -= sizeof (Elf32_External_Rela);
+ }
+
+ /* If the locally-defined symbol isn't used by a DSO, then we don't
+ have to export it as a dynamic symbol. This was already done for
+ functions; doing this for all symbols would presumably not
+ introduce new problems. Of course we don't do this if we're
+ exporting all dynamic symbols. */
+ if (! info->export_dynamic
+ && h->root.dynindx != -1
+ && !h->root.def_dynamic
+ && !h->root.ref_dynamic)
+ {
+ h->root.dynindx = -1;
+ _bfd_elf_strtab_delref (elf_hash_table (info)->dynstr,
+ h->root.dynstr_index);
+ }
+ }
+
+ return TRUE;
+}
+
+/* Reject a file depending on presence and expectation of prefixed
+ underscores on symbols. */
+
+static bfd_boolean
+cris_elf_object_p (bfd *abfd)
+{
+ if (! cris_elf_set_mach_from_flags (abfd, elf_elfheader (abfd)->e_flags))
+ return FALSE;
+
+ if ((elf_elfheader (abfd)->e_flags & EF_CRIS_UNDERSCORE))
+ return (bfd_get_symbol_leading_char (abfd) == '_');
+ else
+ return (bfd_get_symbol_leading_char (abfd) == 0);
+}
+
+/* Mark presence or absence of leading underscore. Set machine type
+ flags from mach type. */
+
+static void
+cris_elf_final_write_processing (bfd *abfd,
+ bfd_boolean linker ATTRIBUTE_UNUSED)
+{
+ unsigned long e_flags = elf_elfheader (abfd)->e_flags;
+
+ e_flags &= ~EF_CRIS_UNDERSCORE;
+ if (bfd_get_symbol_leading_char (abfd) == '_')
+ e_flags |= EF_CRIS_UNDERSCORE;
+
+ switch (bfd_get_mach (abfd))
+ {
+ case bfd_mach_cris_v0_v10:
+ e_flags |= EF_CRIS_VARIANT_ANY_V0_V10;
+ break;
+
+ case bfd_mach_cris_v10_v32:
+ e_flags |= EF_CRIS_VARIANT_COMMON_V10_V32;
+ break;
+
+ case bfd_mach_cris_v32:
+ e_flags |= EF_CRIS_VARIANT_V32;
+ break;
+
+ default:
+ _bfd_abort (__FILE__, __LINE__,
+ _("Unexpected machine number"));
+ }
+
+ elf_elfheader (abfd)->e_flags = e_flags;
+}
+
+/* Set the mach type from e_flags value. */
+
+static bfd_boolean
+cris_elf_set_mach_from_flags (bfd *abfd,
+ unsigned long flags)
+{
+ switch (flags & EF_CRIS_VARIANT_MASK)
+ {
+ case EF_CRIS_VARIANT_ANY_V0_V10:
+ bfd_default_set_arch_mach (abfd, bfd_arch_cris, bfd_mach_cris_v0_v10);
+ break;
+
+ case EF_CRIS_VARIANT_V32:
+ bfd_default_set_arch_mach (abfd, bfd_arch_cris, bfd_mach_cris_v32);
+ break;
+
+ case EF_CRIS_VARIANT_COMMON_V10_V32:
+ bfd_default_set_arch_mach (abfd, bfd_arch_cris, bfd_mach_cris_v10_v32);
+ break;
+
+ default:
+ /* Since we don't recognize them, we obviously can't support them
+ with this code; we'd have to require that all future handling
+ would be optional. */
+ bfd_set_error (bfd_error_wrong_format);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/* Display the flags field. */
+
+static bfd_boolean
+cris_elf_print_private_bfd_data (bfd *abfd, void * 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);
+
+ if (elf_elfheader (abfd)->e_flags & EF_CRIS_UNDERSCORE)
+ fprintf (file, _(" [symbols have a _ prefix]"));
+ if ((elf_elfheader (abfd)->e_flags & EF_CRIS_VARIANT_MASK)
+ == EF_CRIS_VARIANT_COMMON_V10_V32)
+ fprintf (file, _(" [v10 and v32]"));
+ if ((elf_elfheader (abfd)->e_flags & EF_CRIS_VARIANT_MASK)
+ == EF_CRIS_VARIANT_V32)
+ fprintf (file, _(" [v32]"));
+
+ fputc ('\n', file);
+ return TRUE;
+}
+
+/* Don't mix files with and without a leading underscore. */
+
+static bfd_boolean
+cris_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
+{
+ int imach, omach;
+
+ if (! _bfd_generic_verify_endian_match (ibfd, obfd))
+ return FALSE;
+
+ if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
+ || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
+ return TRUE;
+
+ imach = bfd_get_mach (ibfd);
+
+ if (! elf_flags_init (obfd))
+ {
+ /* This happens when ld starts out with a 'blank' output file. */
+ elf_flags_init (obfd) = TRUE;
+
+ /* We ignore the linker-set mach, and instead set it according to
+ the first input file. This would also happen if we could
+ somehow filter out the OUTPUT_ARCH () setting from elf.sc.
+ This allows us to keep the same linker config across
+ cris(v0..v10) and crisv32. The drawback is that we can't force
+ the output type, which might be a sane thing to do for a
+ v10+v32 compatibility object. */
+ if (! bfd_set_arch_mach (obfd, bfd_arch_cris, imach))
+ return FALSE;
+ }
+
+ if (bfd_get_symbol_leading_char (ibfd)
+ != bfd_get_symbol_leading_char (obfd))
+ {
+ (*_bfd_error_handler)
+ (bfd_get_symbol_leading_char (ibfd) == '_'
+ ? _("%B: uses _-prefixed symbols, but writing file with non-prefixed symbols")
+ : _("%B: uses non-prefixed symbols, but writing file with _-prefixed symbols"),
+ ibfd);
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+
+ omach = bfd_get_mach (obfd);
+
+ if (imach != omach)
+ {
+ /* We can get an incompatible combination only if either is
+ bfd_mach_cris_v32, and the other one isn't compatible. */
+ if ((imach == bfd_mach_cris_v32
+ && omach != bfd_mach_cris_v10_v32)
+ || (omach == bfd_mach_cris_v32
+ && imach != bfd_mach_cris_v10_v32))
+ {
+ (*_bfd_error_handler)
+ ((imach == bfd_mach_cris_v32)
+ ? _("%B contains CRIS v32 code, incompatible"
+ " with previous objects")
+ : _("%B contains non-CRIS-v32 code, incompatible"
+ " with previous objects"),
+ ibfd);
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+
+ /* We don't have to check the case where the input is compatible
+ with v10 and v32, because the output is already known to be set
+ to the other (compatible) mach. */
+ if (omach == bfd_mach_cris_v10_v32
+ && ! bfd_set_arch_mach (obfd, bfd_arch_cris, imach))
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/* Do side-effects of e_flags copying to obfd. */
+
+static bfd_boolean
+cris_elf_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
+{
+ /* Call the base function. */
+ if (!_bfd_elf_copy_private_bfd_data (ibfd, obfd))
+ return FALSE;
+
+ /* If output is big-endian for some obscure reason, stop here. */
+ if (_bfd_generic_verify_endian_match (ibfd, obfd) == FALSE)
+ return FALSE;
+
+ if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
+ || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
+ return TRUE;
+
+ /* Do what we really came here for. */
+ return bfd_set_arch_mach (obfd, bfd_arch_cris, bfd_get_mach (ibfd));
+}
+
+static enum elf_reloc_type_class
+elf_cris_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ const asection *rel_sec ATTRIBUTE_UNUSED,
+ const Elf_Internal_Rela *rela)
+{
+ enum elf_cris_reloc_type r_type = ELF32_R_TYPE (rela->r_info);
+ switch (r_type)
+ {
+ case R_CRIS_RELATIVE:
+ return reloc_class_relative;
+ case R_CRIS_JUMP_SLOT:
+ return reloc_class_plt;
+ case R_CRIS_COPY:
+ return reloc_class_copy;
+ default:
+ return reloc_class_normal;
+ }
+}
+
+/* The elf_backend_got_elt_size worker. For one symbol, we can have up to
+ two GOT entries from three types with two different sizes. We handle
+ it as a single entry, so we can use the regular offset-calculation
+ machinery. */
+
+static bfd_vma
+elf_cris_got_elt_size (bfd *abfd ATTRIBUTE_UNUSED,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ struct elf_link_hash_entry *hr,
+ bfd *ibfd,
+ unsigned long symndx)
+{
+ struct elf_link_hash_entry *h = (struct elf_link_hash_entry *) hr;
+ bfd_vma eltsiz = 0;
+
+ /* We may have one regular GOT entry or up to two TLS GOT
+ entries. */
+ if (h == NULL)
+ {
+ Elf_Internal_Shdr *symtab_hdr = &elf_tdata (ibfd)->symtab_hdr;
+ bfd_signed_vma *local_got_refcounts = elf_local_got_refcounts (ibfd);
+
+ BFD_ASSERT (local_got_refcounts != NULL);
+
+ if (local_got_refcounts[LGOT_REG_NDX (symndx)] > 0)
+ {
+ /* We can't have a variable referred to both as a regular
+ variable and through TLS relocs. */
+ BFD_ASSERT (local_got_refcounts[LGOT_DTP_NDX (symndx)] == 0
+ && local_got_refcounts[LGOT_TPREL_NDX (symndx)] == 0);
+ return 4;
+ }
+
+ if (local_got_refcounts[LGOT_DTP_NDX (symndx)] > 0)
+ eltsiz += 8;
+
+ if (local_got_refcounts[LGOT_TPREL_NDX (symndx)] > 0)
+ eltsiz += 4;
+ }
+ else
+ {
+ struct elf_cris_link_hash_entry *hh = elf_cris_hash_entry (h);
+ if (hh->reg_got_refcount > 0)
+ {
+ /* The actual error-on-input is emitted elsewhere. */
+ BFD_ASSERT (hh->dtp_refcount == 0 && hh->tprel_refcount == 0);
+ return 4;
+ }
+
+ if (hh->dtp_refcount > 0)
+ eltsiz += 8;
+
+ if (hh->tprel_refcount > 0)
+ eltsiz += 4;
+ }
+
+ /* We're only called when h->got.refcount is non-zero, so we must
+ have a non-zero size. */
+ BFD_ASSERT (eltsiz != 0);
+ return eltsiz;
+}
+
+#define ELF_ARCH bfd_arch_cris
+#define ELF_TARGET_ID CRIS_ELF_DATA
+#define ELF_MACHINE_CODE EM_CRIS
+#define ELF_MAXPAGESIZE 0x2000
+
+#define TARGET_LITTLE_SYM cris_elf32_vec
+#define TARGET_LITTLE_NAME "elf32-cris"
+#define elf_symbol_leading_char 0
+
+#define elf_info_to_howto_rel NULL
+#define elf_info_to_howto cris_info_to_howto_rela
+#define elf_backend_relocate_section cris_elf_relocate_section
+#define elf_backend_gc_mark_hook cris_elf_gc_mark_hook
+#define elf_backend_gc_sweep_hook cris_elf_gc_sweep_hook
+#define elf_backend_plt_sym_val cris_elf_plt_sym_val
+#define elf_backend_check_relocs cris_elf_check_relocs
+#define elf_backend_grok_prstatus cris_elf_grok_prstatus
+#define elf_backend_grok_psinfo cris_elf_grok_psinfo
+
+#define elf_backend_can_gc_sections 1
+#define elf_backend_can_refcount 1
+
+#define elf_backend_object_p cris_elf_object_p
+#define elf_backend_final_write_processing \
+ cris_elf_final_write_processing
+#define bfd_elf32_bfd_print_private_bfd_data \
+ cris_elf_print_private_bfd_data
+#define bfd_elf32_bfd_merge_private_bfd_data \
+ cris_elf_merge_private_bfd_data
+#define bfd_elf32_bfd_copy_private_bfd_data \
+ cris_elf_copy_private_bfd_data
+
+#define bfd_elf32_bfd_reloc_type_lookup cris_reloc_type_lookup
+#define bfd_elf32_bfd_reloc_name_lookup cris_reloc_name_lookup
+
+#define bfd_elf32_bfd_link_hash_table_create \
+ elf_cris_link_hash_table_create
+#define elf_backend_adjust_dynamic_symbol \
+ elf_cris_adjust_dynamic_symbol
+#define elf_backend_copy_indirect_symbol \
+ elf_cris_copy_indirect_symbol
+#define elf_backend_size_dynamic_sections \
+ elf_cris_size_dynamic_sections
+#define elf_backend_init_index_section _bfd_elf_init_1_index_section
+#define elf_backend_finish_dynamic_symbol \
+ elf_cris_finish_dynamic_symbol
+#define elf_backend_finish_dynamic_sections \
+ elf_cris_finish_dynamic_sections
+#define elf_backend_create_dynamic_sections \
+ _bfd_elf_create_dynamic_sections
+#define bfd_elf32_bfd_final_link \
+ bfd_elf_gc_common_final_link
+#define elf_backend_hide_symbol elf_cris_hide_symbol
+#define elf_backend_reloc_type_class elf_cris_reloc_type_class
+
+#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_got_elt_size elf_cris_got_elt_size
+
+/* Later, we my want to optimize RELA entries into REL entries for dynamic
+ linking and libraries (if it's a win of any significance). Until then,
+ take the easy route. */
+#define elf_backend_may_use_rel_p 0
+#define elf_backend_may_use_rela_p 1
+#define elf_backend_rela_normal 1
+
+#include "elf32-target.h"
+
+#undef TARGET_LITTLE_SYM
+#undef TARGET_LITTLE_NAME
+#undef elf_symbol_leading_char
+
+#define TARGET_LITTLE_SYM cris_elf32_us_vec
+#define TARGET_LITTLE_NAME "elf32-us-cris"
+#define elf_symbol_leading_char '_'
+#undef elf32_bed
+#define elf32_bed elf32_us_cris_bed
+
+#include "elf32-target.h"
diff --git a/bfd/elf32-crx.c b/bfd/elf32-crx.c
new file mode 100644
index 0000000..f2925f5
--- /dev/null
+++ b/bfd/elf32-crx.c
@@ -0,0 +1,1330 @@
+/* BFD back-end for National Semiconductor's CRX ELF
+ Copyright (C) 2004-2014 Free Software Foundation, Inc.
+ Written by Tomer Levi, NSC, Israel.
+
+ This file is part of BFD, the Binary File Descriptor library.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "bfdlink.h"
+#include "libbfd.h"
+#include "elf-bfd.h"
+#include "elf/crx.h"
+
+static reloc_howto_type *elf_crx_reloc_type_lookup
+ (bfd *, bfd_reloc_code_real_type);
+static void elf_crx_info_to_howto
+ (bfd *, arelent *, Elf_Internal_Rela *);
+static bfd_boolean elf32_crx_relax_delete_bytes
+ (struct bfd_link_info *, bfd *, asection *, bfd_vma, int);
+static bfd_reloc_status_type crx_elf_final_link_relocate
+ (reloc_howto_type *, bfd *, bfd *, asection *,
+ bfd_byte *, bfd_vma, bfd_vma, bfd_vma,
+ struct bfd_link_info *, asection *, int);
+static bfd_boolean elf32_crx_relocate_section
+ (bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
+ Elf_Internal_Rela *, Elf_Internal_Sym *, asection **);
+static bfd_boolean elf32_crx_relax_section
+ (bfd *, asection *, struct bfd_link_info *, bfd_boolean *);
+static bfd_byte * elf32_crx_get_relocated_section_contents
+ (bfd *, struct bfd_link_info *, struct bfd_link_order *,
+ bfd_byte *, bfd_boolean, asymbol **);
+
+/* crx_reloc_map array maps BFD relocation enum into a CRGAS relocation type. */
+
+struct crx_reloc_map
+{
+ bfd_reloc_code_real_type bfd_reloc_enum; /* BFD relocation enum. */
+ unsigned short crx_reloc_type; /* CRX relocation type. */
+};
+
+static const struct crx_reloc_map crx_reloc_map[R_CRX_MAX] =
+{
+ {BFD_RELOC_NONE, R_CRX_NONE},
+ {BFD_RELOC_CRX_REL4, R_CRX_REL4},
+ {BFD_RELOC_CRX_REL8, R_CRX_REL8},
+ {BFD_RELOC_CRX_REL8_CMP, R_CRX_REL8_CMP},
+ {BFD_RELOC_CRX_REL16, R_CRX_REL16},
+ {BFD_RELOC_CRX_REL24, R_CRX_REL24},
+ {BFD_RELOC_CRX_REL32, R_CRX_REL32},
+ {BFD_RELOC_CRX_REGREL12, R_CRX_REGREL12},
+ {BFD_RELOC_CRX_REGREL22, R_CRX_REGREL22},
+ {BFD_RELOC_CRX_REGREL28, R_CRX_REGREL28},
+ {BFD_RELOC_CRX_REGREL32, R_CRX_REGREL32},
+ {BFD_RELOC_CRX_ABS16, R_CRX_ABS16},
+ {BFD_RELOC_CRX_ABS32, R_CRX_ABS32},
+ {BFD_RELOC_CRX_NUM8, R_CRX_NUM8},
+ {BFD_RELOC_CRX_NUM16, R_CRX_NUM16},
+ {BFD_RELOC_CRX_NUM32, R_CRX_NUM32},
+ {BFD_RELOC_CRX_IMM16, R_CRX_IMM16},
+ {BFD_RELOC_CRX_IMM32, R_CRX_IMM32},
+ {BFD_RELOC_CRX_SWITCH8, R_CRX_SWITCH8},
+ {BFD_RELOC_CRX_SWITCH16, R_CRX_SWITCH16},
+ {BFD_RELOC_CRX_SWITCH32, R_CRX_SWITCH32}
+};
+
+static reloc_howto_type crx_elf_howto_table[] =
+{
+ HOWTO (R_CRX_NONE, /* type */
+ 0, /* rightshift */
+ 2, /* size */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_CRX_NONE", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_CRX_REL4, /* type */
+ 1, /* rightshift */
+ 0, /* size */
+ 4, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_CRX_REL4", /* name */
+ FALSE, /* partial_inplace */
+ 0x0, /* src_mask */
+ 0xf, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_CRX_REL8, /* type */
+ 1, /* rightshift */
+ 0, /* size */
+ 8, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_CRX_REL8", /* name */
+ FALSE, /* partial_inplace */
+ 0x0, /* src_mask */
+ 0xff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_CRX_REL8_CMP, /* type */
+ 1, /* rightshift */
+ 0, /* size */
+ 8, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_CRX_REL8_CMP", /* name */
+ FALSE, /* partial_inplace */
+ 0x0, /* src_mask */
+ 0xff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_CRX_REL16, /* type */
+ 1, /* rightshift */
+ 1, /* size */
+ 16, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_CRX_REL16", /* name */
+ FALSE, /* partial_inplace */
+ 0x0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_CRX_REL24, /* type */
+ 1, /* rightshift */
+ 2, /* size */
+ 24, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_CRX_REL24", /* name */
+ FALSE, /* partial_inplace */
+ 0x0, /* src_mask */
+ 0xffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_CRX_REL32, /* type */
+ 1, /* rightshift */
+ 2, /* size */
+ 32, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_CRX_REL32", /* name */
+ FALSE, /* partial_inplace */
+ 0x0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_CRX_REGREL12, /* type */
+ 0, /* rightshift */
+ 1, /* size */
+ 12, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_CRX_REGREL12", /* name */
+ FALSE, /* partial_inplace */
+ 0x0, /* src_mask */
+ 0xfff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_CRX_REGREL22, /* type */
+ 0, /* rightshift */
+ 2, /* size */
+ 22, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_CRX_REGREL22", /* name */
+ FALSE, /* partial_inplace */
+ 0x0, /* src_mask */
+ 0x3fffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_CRX_REGREL28, /* type */
+ 0, /* rightshift */
+ 2, /* size */
+ 28, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_CRX_REGREL28", /* name */
+ FALSE, /* partial_inplace */
+ 0x0, /* src_mask */
+ 0xfffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_CRX_REGREL32, /* type */
+ 0, /* rightshift */
+ 2, /* size */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_CRX_REGREL32", /* name */
+ FALSE, /* partial_inplace */
+ 0x0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_CRX_ABS16, /* type */
+ 0, /* rightshift */
+ 1, /* size */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_CRX_ABS16", /* name */
+ FALSE, /* partial_inplace */
+ 0x0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_CRX_ABS32, /* type */
+ 0, /* rightshift */
+ 2, /* size */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_CRX_ABS32", /* name */
+ FALSE, /* partial_inplace */
+ 0x0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_CRX_NUM8, /* type */
+ 0, /* rightshift */
+ 0, /* size */
+ 8, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_CRX_NUM8", /* name */
+ FALSE, /* partial_inplace */
+ 0x0, /* src_mask */
+ 0xff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_CRX_NUM16, /* type */
+ 0, /* rightshift */
+ 1, /* size */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_CRX_NUM16", /* name */
+ FALSE, /* partial_inplace */
+ 0x0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_CRX_NUM32, /* type */
+ 0, /* rightshift */
+ 2, /* size */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_CRX_NUM32", /* name */
+ FALSE, /* partial_inplace */
+ 0x0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_CRX_IMM16, /* type */
+ 0, /* rightshift */
+ 1, /* size */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_CRX_IMM16", /* name */
+ FALSE, /* partial_inplace */
+ 0x0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_CRX_IMM32, /* type */
+ 0, /* rightshift */
+ 2, /* size */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_CRX_IMM32", /* name */
+ FALSE, /* partial_inplace */
+ 0x0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* An 8 bit switch table entry. This is generated for an expression
+ such as ``.byte L1 - L2''. The offset holds the difference
+ between the reloc address and L2. */
+ HOWTO (R_CRX_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 */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_CRX_SWITCH8", /* name */
+ FALSE, /* partial_inplace */
+ 0x0, /* src_mask */
+ 0xff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* 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_CRX_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 */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_CRX_SWITCH16", /* name */
+ FALSE, /* partial_inplace */
+ 0x0, /* src_mask */
+ 0xffff, /* 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_CRX_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 */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_CRX_SWITCH32", /* name */
+ FALSE, /* partial_inplace */
+ 0x0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ TRUE) /* pcrel_offset */
+};
+
+/* Retrieve a howto ptr using a BFD reloc_code. */
+
+static reloc_howto_type *
+elf_crx_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ bfd_reloc_code_real_type code)
+{
+ unsigned int i;
+
+ for (i = 0; i < R_CRX_MAX; i++)
+ if (code == crx_reloc_map[i].bfd_reloc_enum)
+ return &crx_elf_howto_table[crx_reloc_map[i].crx_reloc_type];
+
+ printf ("This relocation Type is not supported -0x%x\n", code);
+ return 0;
+}
+
+static reloc_howto_type *
+elf_crx_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ const char *r_name)
+{
+ unsigned int i;
+
+ for (i = 0;
+ i < sizeof (crx_elf_howto_table) / sizeof (crx_elf_howto_table[0]);
+ i++)
+ if (crx_elf_howto_table[i].name != NULL
+ && strcasecmp (crx_elf_howto_table[i].name, r_name) == 0)
+ return &crx_elf_howto_table[i];
+
+ return NULL;
+}
+
+/* Retrieve a howto ptr using an internal relocation entry. */
+
+static void
+elf_crx_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED, arelent *cache_ptr,
+ Elf_Internal_Rela *dst)
+{
+ unsigned int r_type = ELF32_R_TYPE (dst->r_info);
+ BFD_ASSERT (r_type < (unsigned int) R_CRX_MAX);
+ cache_ptr->howto = &crx_elf_howto_table[r_type];
+}
+
+/* Perform a relocation as part of a final link. */
+
+static bfd_reloc_status_type
+crx_elf_final_link_relocate (reloc_howto_type *howto, bfd *input_bfd,
+ bfd *output_bfd ATTRIBUTE_UNUSED,
+ asection *input_section, bfd_byte *contents,
+ bfd_vma offset, bfd_vma Rvalue, bfd_vma addend,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ asection *sec ATTRIBUTE_UNUSED,
+ int is_local ATTRIBUTE_UNUSED)
+{
+ unsigned short r_type = howto->type;
+ bfd_byte *hit_data = contents + offset;
+ bfd_vma reloc_bits, check;
+
+ switch (r_type)
+ {
+ case R_CRX_IMM16:
+ case R_CRX_IMM32:
+ case R_CRX_ABS16:
+ case R_CRX_ABS32:
+ case R_CRX_REL8_CMP:
+ case R_CRX_REL16:
+ case R_CRX_REL24:
+ case R_CRX_REL32:
+ case R_CRX_REGREL12:
+ case R_CRX_REGREL22:
+ case R_CRX_REGREL28:
+ case R_CRX_REGREL32:
+ /* 'hit_data' is relative to the start of the instruction, not the
+ relocation offset. Advance it to account for the exact offset. */
+ hit_data += 2;
+ break;
+
+ case R_CRX_REL4:
+ /* This relocation type is used only in 'Branch if Equal to 0'
+ instructions and requires special handling. */
+ Rvalue -= 1;
+ break;
+
+ case R_CRX_NONE:
+ return bfd_reloc_ok;
+ break;
+
+ case R_CRX_SWITCH8:
+ case R_CRX_SWITCH16:
+ case R_CRX_SWITCH32:
+ /* We only care about the addend, where the difference between
+ expressions is kept. */
+ Rvalue = 0;
+
+ default:
+ break;
+ }
+
+ if (howto->pc_relative)
+ {
+ /* Subtract the address of the section containing the location. */
+ Rvalue -= (input_section->output_section->vma
+ + input_section->output_offset);
+ /* Subtract the position of the location within the section. */
+ Rvalue -= offset;
+ }
+
+ /* Add in supplied addend. */
+ Rvalue += addend;
+
+ /* Complain if the bitfield overflows, whether it is considered
+ as signed or unsigned. */
+ check = Rvalue >> howto->rightshift;
+
+ /* Assumes two's complement. This expression avoids
+ overflow if howto->bitsize is the number of bits in
+ bfd_vma. */
+ reloc_bits = (((1 << (howto->bitsize - 1)) - 1) << 1) | 1;
+
+ if (((bfd_vma) check & ~reloc_bits) != 0
+ && (((bfd_vma) check & ~reloc_bits)
+ != (-(bfd_vma) 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 && (bfd_signed_vma) Rvalue < 0)
+ {
+ check |= ((bfd_vma) - 1
+ & ~((bfd_vma) - 1
+ >> howto->rightshift));
+ if (((bfd_vma) check & ~reloc_bits)
+ != (-(bfd_vma) 1 & ~reloc_bits))
+ return bfd_reloc_overflow;
+ }
+ else
+ return bfd_reloc_overflow;
+ }
+
+ /* Drop unwanted bits from the value we are relocating to. */
+ Rvalue >>= (bfd_vma) howto->rightshift;
+
+ /* Apply dst_mask to select only relocatable part of the insn. */
+ Rvalue &= howto->dst_mask;
+
+ switch (howto->size)
+ {
+ case 0:
+ if (r_type == R_CRX_REL4)
+ {
+ Rvalue <<= 4;
+ Rvalue |= (bfd_get_8 (input_bfd, hit_data) & 0x0f);
+ }
+
+ bfd_put_8 (input_bfd, (unsigned char) Rvalue, hit_data);
+ break;
+
+ case 1:
+ if (r_type == R_CRX_REGREL12)
+ Rvalue |= (bfd_get_16 (input_bfd, hit_data) & 0xf000);
+
+ bfd_put_16 (input_bfd, Rvalue, hit_data);
+ break;
+
+ case 2:
+ if (r_type == R_CRX_REL24
+ || r_type == R_CRX_REGREL22
+ || r_type == R_CRX_REGREL28)
+ Rvalue |= (((bfd_get_16 (input_bfd, hit_data) << 16) |
+ bfd_get_16 (input_bfd, hit_data + 2)) & ~howto->dst_mask);
+
+ if (r_type == R_CRX_NUM32 || r_type == R_CRX_SWITCH32)
+ /* Relocation on DATA is purely little-endian, that is, for a
+ multi-byte datum, the lowest address in memory contains the
+ little end of the datum, that is, the least significant byte.
+ Therefore we use BFD's byte Putting functions. */
+ bfd_put_32 (input_bfd, Rvalue, hit_data);
+ else
+ /* Relocation on INSTRUCTIONS is different : Instructions are
+ word-addressable, that is, each word itself is arranged according
+ to little-endian convention, whereas the words are arranged with
+ respect to one another in BIG ENDIAN fashion.
+ When there is an immediate value that spans a word boundary, it is
+ split in a big-endian way with respect to the words. */
+ {
+ bfd_put_16 (input_bfd, (Rvalue >> 16) & 0xffff, hit_data);
+ bfd_put_16 (input_bfd, Rvalue & 0xffff, hit_data + 2);
+ }
+ break;
+
+ default:
+ return bfd_reloc_notsupported;
+ }
+
+ return bfd_reloc_ok;
+}
+
+/* Delete some bytes from a section while relaxing. */
+
+static bfd_boolean
+elf32_crx_relax_delete_bytes (struct bfd_link_info *link_info, bfd *abfd,
+ asection *sec, bfd_vma addr, int count)
+{
+ Elf_Internal_Shdr *symtab_hdr;
+ unsigned int sec_shndx;
+ bfd_byte *contents;
+ Elf_Internal_Rela *irel, *irelend;
+ bfd_vma toaddr;
+ Elf_Internal_Sym *isym;
+ Elf_Internal_Sym *isymend;
+ struct elf_link_hash_entry **sym_hashes;
+ struct elf_link_hash_entry **end_hashes;
+ struct elf_link_hash_entry **start_hashes;
+ unsigned int symcount;
+
+ sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
+
+ contents = elf_section_data (sec)->this_hdr.contents;
+
+ toaddr = sec->size;
+
+ irel = elf_section_data (sec)->relocs;
+ irelend = irel + sec->reloc_count;
+
+ /* Actually delete the bytes. */
+ memmove (contents + addr, contents + addr + count,
+ (size_t) (toaddr - addr - count));
+ sec->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. */
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+ isym = (Elf_Internal_Sym *) symtab_hdr->contents;
+ for (isymend = isym + symtab_hdr->sh_info; isym < isymend; isym++)
+ {
+ if (isym->st_shndx == sec_shndx
+ && isym->st_value > addr
+ && isym->st_value < toaddr)
+ {
+ /* Adjust the addend of SWITCH relocations in this section,
+ which reference this local symbol. */
+ for (irel = elf_section_data (sec)->relocs; irel < irelend; irel++)
+ {
+ unsigned long r_symndx;
+ Elf_Internal_Sym *rsym;
+ bfd_vma addsym, subsym;
+
+ /* Skip if not a SWITCH relocation. */
+ if (ELF32_R_TYPE (irel->r_info) != (int) R_CRX_SWITCH8
+ && ELF32_R_TYPE (irel->r_info) != (int) R_CRX_SWITCH16
+ && ELF32_R_TYPE (irel->r_info) != (int) R_CRX_SWITCH32)
+ continue;
+
+ r_symndx = ELF32_R_SYM (irel->r_info);
+ rsym = (Elf_Internal_Sym *) symtab_hdr->contents + r_symndx;
+
+ /* Skip if not the local adjusted symbol. */
+ if (rsym != isym)
+ continue;
+
+ addsym = isym->st_value;
+ subsym = addsym - irel->r_addend;
+
+ /* Fix the addend only when -->> (addsym > addr >= subsym). */
+ if (subsym <= addr)
+ irel->r_addend -= count;
+ else
+ continue;
+ }
+
+ isym->st_value -= count;
+ }
+ }
+
+ /* Now adjust the global symbols defined in this section. */
+ symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
+ - symtab_hdr->sh_info);
+ sym_hashes = start_hashes = elf_sym_hashes (abfd);
+ end_hashes = sym_hashes + symcount;
+
+ for (; sym_hashes < end_hashes; sym_hashes++)
+ {
+ struct elf_link_hash_entry *sym_hash = *sym_hashes;
+
+ /* The '--wrap SYMBOL' option is causing a pain when the object file,
+ containing the definition of __wrap_SYMBOL, includes a direct
+ call to SYMBOL as well. Since both __wrap_SYMBOL and SYMBOL reference
+ the same symbol (which is __wrap_SYMBOL), but still exist as two
+ different symbols in 'sym_hashes', we don't want to adjust
+ the global symbol __wrap_SYMBOL twice.
+ This check is only relevant when symbols are being wrapped. */
+ if (link_info->wrap_hash != NULL)
+ {
+ struct elf_link_hash_entry **cur_sym_hashes;
+
+ /* Loop only over the symbols whom been already checked. */
+ for (cur_sym_hashes = start_hashes; cur_sym_hashes < sym_hashes;
+ cur_sym_hashes++)
+ {
+ /* If the current symbol is identical to 'sym_hash', that means
+ the symbol was already adjusted (or at least checked). */
+ if (*cur_sym_hashes == sym_hash)
+ break;
+ }
+ /* Don't adjust the symbol again. */
+ if (cur_sym_hashes < sym_hashes)
+ continue;
+ }
+
+ 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
+ && 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 elf32_crx_relocate_section. */
+
+static bfd_byte *
+elf32_crx_get_relocated_section_contents (bfd *output_bfd,
+ struct bfd_link_info *link_info,
+ struct bfd_link_order *link_order,
+ bfd_byte *data,
+ bfd_boolean relocatable,
+ 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;
+ Elf_Internal_Sym *isymbuf = NULL;
+
+ /* We only need to handle the case of relaxing, or of having a
+ particular set of section contents, specially. */
+ if (relocatable
+ || elf_section_data (input_section)->this_hdr.contents == NULL)
+ return bfd_generic_get_relocated_section_contents (output_bfd, link_info,
+ link_order, data,
+ relocatable,
+ symbols);
+
+ symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
+
+ memcpy (data, elf_section_data (input_section)->this_hdr.contents,
+ (size_t) input_section->size);
+
+ if ((input_section->flags & SEC_RELOC) != 0
+ && input_section->reloc_count > 0)
+ {
+ Elf_Internal_Sym *isym;
+ Elf_Internal_Sym *isymend;
+ asection **secpp;
+ bfd_size_type amt;
+
+ internal_relocs = (_bfd_elf_link_read_relocs
+ (input_bfd, input_section, NULL,
+ (Elf_Internal_Rela *) NULL, FALSE));
+ if (internal_relocs == NULL)
+ goto error_return;
+
+ if (symtab_hdr->sh_info != 0)
+ {
+ isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
+ if (isymbuf == NULL)
+ isymbuf = bfd_elf_get_elf_syms (input_bfd, symtab_hdr,
+ symtab_hdr->sh_info, 0,
+ NULL, NULL, NULL);
+ if (isymbuf == NULL)
+ goto error_return;
+ }
+
+ amt = symtab_hdr->sh_info;
+ amt *= sizeof (asection *);
+ sections = bfd_malloc (amt);
+ if (sections == NULL && amt != 0)
+ goto error_return;
+
+ isymend = isymbuf + symtab_hdr->sh_info;
+ for (isym = isymbuf, secpp = sections; isym < isymend; ++isym, ++secpp)
+ {
+ asection *isec;
+
+ if (isym->st_shndx == SHN_UNDEF)
+ isec = bfd_und_section_ptr;
+ 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
+ isec = bfd_section_from_elf_index (input_bfd, isym->st_shndx);
+
+ *secpp = isec;
+ }
+
+ if (! elf32_crx_relocate_section (output_bfd, link_info, input_bfd,
+ input_section, data, internal_relocs,
+ isymbuf, sections))
+ goto error_return;
+
+ if (sections != NULL)
+ free (sections);
+ if (isymbuf != NULL
+ && symtab_hdr->contents != (unsigned char *) isymbuf)
+ free (isymbuf);
+ if (elf_section_data (input_section)->relocs != internal_relocs)
+ free (internal_relocs);
+ }
+
+ return data;
+
+ error_return:
+ if (sections != NULL)
+ free (sections);
+ if (isymbuf != NULL
+ && symtab_hdr->contents != (unsigned char *) isymbuf)
+ free (isymbuf);
+ if (internal_relocs != NULL
+ && elf_section_data (input_section)->relocs != internal_relocs)
+ free (internal_relocs);
+ return NULL;
+}
+
+/* Relocate a CRX ELF section. */
+
+static bfd_boolean
+elf32_crx_relocate_section (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 = crx_elf_howto_table + (r_type);
+
+ h = NULL;
+ sym = NULL;
+ sec = NULL;
+ if (r_symndx < symtab_hdr->sh_info)
+ {
+ sym = local_syms + r_symndx;
+ sec = local_sections[r_symndx];
+ relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
+ }
+ else
+ {
+ bfd_boolean unresolved_reloc, warned, ignored;
+
+ RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
+ r_symndx, symtab_hdr, sym_hashes,
+ h, sec, relocation,
+ unresolved_reloc, warned, ignored);
+ }
+
+ if (sec != NULL && discarded_section (sec))
+ RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+ rel, 1, relend, howto, 0, contents);
+
+ if (info->relocatable)
+ continue;
+
+ r = crx_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, (h ? &h->root : NULL), 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, TRUE)))
+ 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 CRX.
+
+ There's quite a few relaxing opportunites available on the CRX:
+
+ * bal/bcond:32 -> bal/bcond:16 2 bytes
+ * bcond:16 -> bcond:8 2 bytes
+ * cmpbcond:24 -> cmpbcond:8 2 bytes
+ * arithmetic imm32 -> arithmetic imm16 2 bytes
+
+ Symbol- and reloc-reading infrastructure copied from elf-m10200.c. */
+
+static bfd_boolean
+elf32_crx_relax_section (bfd *abfd, asection *sec,
+ struct bfd_link_info *link_info, bfd_boolean *again)
+{
+ Elf_Internal_Shdr *symtab_hdr;
+ Elf_Internal_Rela *internal_relocs;
+ Elf_Internal_Rela *irel, *irelend;
+ bfd_byte *contents = NULL;
+ Elf_Internal_Sym *isymbuf = NULL;
+
+ /* Assume nothing changes. */
+ *again = FALSE;
+
+ /* We don't have to do anything for a relocatable link, if
+ this section does not have relocs, or if this is not a
+ code section. */
+ if (link_info->relocatable
+ || (sec->flags & SEC_RELOC) == 0
+ || sec->reloc_count == 0
+ || (sec->flags & SEC_CODE) == 0)
+ return TRUE;
+
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+
+ /* Get a copy of the native relocations. */
+ internal_relocs = (_bfd_elf_link_read_relocs
+ (abfd, sec, NULL, (Elf_Internal_Rela *) NULL,
+ link_info->keep_memory));
+ if (internal_relocs == NULL)
+ goto error_return;
+
+ /* 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_CRX_REL32
+ && ELF32_R_TYPE (irel->r_info) != (int) R_CRX_REL16
+ && ELF32_R_TYPE (irel->r_info) != (int) R_CRX_REL24
+ && ELF32_R_TYPE (irel->r_info) != (int) R_CRX_IMM32)
+ 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;
+ /* Go get them off disk. */
+ else if (!bfd_malloc_and_get_section (abfd, sec, &contents))
+ goto error_return;
+ }
+
+ /* Read this BFD's local symbols if we haven't done so already. */
+ if (isymbuf == NULL && symtab_hdr->sh_info != 0)
+ {
+ isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
+ if (isymbuf == NULL)
+ isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
+ symtab_hdr->sh_info, 0,
+ NULL, NULL, NULL);
+ if (isymbuf == NULL)
+ 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)
+ {
+ /* A local symbol. */
+ Elf_Internal_Sym *isym;
+ asection *sym_sec;
+
+ isym = isymbuf + ELF32_R_SYM (irel->r_info);
+ if (isym->st_shndx == SHN_UNDEF)
+ sym_sec = bfd_und_section_ptr;
+ 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;
+ else
+ 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 32bit pc-relative branch/call into
+ a 16bit pc-relative branch/call. */
+ if (ELF32_R_TYPE (irel->r_info) == (int) R_CRX_REL32)
+ {
+ bfd_vma value = symval;
+
+ /* 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
+ 0xfffe + 2 as the target will be two bytes closer if we are
+ able to relax. */
+ if ((long) value < 0x10000 && (long) value > -0x10002)
+ {
+ unsigned short code;
+
+ /* Get the opcode. */
+ code = (unsigned short) bfd_get_16 (abfd, contents + irel->r_offset);
+
+ /* Verify it's a 'bal'/'bcond' and fix the opcode. */
+ if ((code & 0xfff0) == 0x3170)
+ bfd_put_8 (abfd, 0x30, contents + irel->r_offset + 1);
+ else if ((code & 0xf0ff) == 0x707f)
+ bfd_put_8 (abfd, 0x7e, contents + irel->r_offset);
+ else
+ continue;
+
+ /* Note that we've changed the relocs, section contents, etc. */
+ elf_section_data (sec)->relocs = internal_relocs;
+ elf_section_data (sec)->this_hdr.contents = contents;
+ symtab_hdr->contents = (unsigned char *) isymbuf;
+
+ /* Fix the relocation's type. */
+ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
+ R_CRX_REL16);
+
+ /* Delete two bytes of data. */
+ if (!elf32_crx_relax_delete_bytes (link_info, 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;
+ }
+ }
+
+ /* Try to turn a 16bit pc-relative branch into an
+ 8bit pc-relative branch. */
+ if (ELF32_R_TYPE (irel->r_info) == (int) R_CRX_REL16)
+ {
+ bfd_vma value = symval;
+
+ /* 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
+ 0xfc + 2 as the target will be two bytes closer if we are
+ able to relax. */
+ if ((long) value < 0xfe && (long) value > -0x100)
+ {
+ unsigned short code;
+
+ /* Get the opcode. */
+ code = (unsigned short) bfd_get_16 (abfd, contents + irel->r_offset);
+
+ /* Verify it's a 'bcond' opcode. */
+ if ((code & 0xf0ff) != 0x707e)
+ continue;
+
+ /* Note that we've changed the relocs, section contents, etc. */
+ elf_section_data (sec)->relocs = internal_relocs;
+ elf_section_data (sec)->this_hdr.contents = contents;
+ symtab_hdr->contents = (unsigned char *) isymbuf;
+
+ /* Fix the relocation's type. */
+ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
+ R_CRX_REL8);
+
+ /* Delete two bytes of data. */
+ if (!elf32_crx_relax_delete_bytes (link_info, 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;
+ }
+ }
+
+ /* Try to turn a 24bit pc-relative cmp&branch into
+ an 8bit pc-relative cmp&branch. */
+ if (ELF32_R_TYPE (irel->r_info) == (int) R_CRX_REL24)
+ {
+ bfd_vma value = symval;
+
+ /* 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
+ 0x7e + 2 as the target will be two bytes closer if we are
+ able to relax. */
+ if ((long) value < 0x100 && (long) value > -0x100)
+ {
+ unsigned short code;
+
+ /* Get the opcode. */
+ code = (unsigned short) bfd_get_16 (abfd, contents + irel->r_offset);
+
+ /* Verify it's a 'cmp&branch' opcode. */
+ if ((code & 0xfff0) != 0x3180 && (code & 0xfff0) != 0x3190
+ && (code & 0xfff0) != 0x31a0 && (code & 0xfff0) != 0x31c0
+ && (code & 0xfff0) != 0x31d0 && (code & 0xfff0) != 0x31e0
+ /* Or a Co-processor branch ('bcop'). */
+ && (code & 0xfff0) != 0x3010 && (code & 0xfff0) != 0x3110)
+ continue;
+
+ /* Note that we've changed the relocs, section contents, etc. */
+ elf_section_data (sec)->relocs = internal_relocs;
+ elf_section_data (sec)->this_hdr.contents = contents;
+ symtab_hdr->contents = (unsigned char *) isymbuf;
+
+ /* Fix the opcode. */
+ bfd_put_8 (abfd, 0x30, contents + irel->r_offset + 1);
+
+ /* Fix the relocation's type. */
+ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
+ R_CRX_REL8_CMP);
+
+ /* Delete two bytes of data. */
+ if (!elf32_crx_relax_delete_bytes (link_info, abfd, sec,
+ irel->r_offset + 4, 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 address into
+ a 16bit immediate address. */
+ if (ELF32_R_TYPE (irel->r_info) == (int) R_CRX_IMM32)
+ {
+ bfd_vma value = symval;
+
+ /* See if the value will fit in 16 bits. */
+ if ((long) value < 0x7fff && (long) value > -0x8000)
+ {
+ unsigned short code;
+
+ /* Get the opcode. */
+ code = (unsigned short) bfd_get_16 (abfd, contents + irel->r_offset);
+
+ /* Verify it's a 'arithmetic double'. */
+ if ((code & 0xf0f0) != 0x20f0)
+ continue;
+
+ /* Note that we've changed the relocs, section contents, etc. */
+ elf_section_data (sec)->relocs = internal_relocs;
+ elf_section_data (sec)->this_hdr.contents = contents;
+ symtab_hdr->contents = (unsigned char *) isymbuf;
+
+ /* Fix the opcode. */
+ bfd_put_8 (abfd, (code & 0xff) - 0x10, contents + irel->r_offset);
+
+ /* Fix the relocation's type. */
+ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
+ R_CRX_IMM16);
+
+ /* Delete two bytes of data. */
+ if (!elf32_crx_relax_delete_bytes (link_info, 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;
+ }
+ }
+ }
+
+ if (isymbuf != NULL
+ && symtab_hdr->contents != (unsigned char *) isymbuf)
+ {
+ if (! link_info->keep_memory)
+ free (isymbuf);
+ else
+ {
+ /* Cache the symbols for elf_link_input_bfd. */
+ symtab_hdr->contents = (unsigned char *) isymbuf;
+ }
+ }
+
+ if (contents != NULL
+ && elf_section_data (sec)->this_hdr.contents != contents)
+ {
+ if (! link_info->keep_memory)
+ free (contents);
+ else
+ {
+ /* Cache the section contents for elf_link_input_bfd. */
+ elf_section_data (sec)->this_hdr.contents = contents;
+ }
+ }
+
+ if (internal_relocs != NULL
+ && elf_section_data (sec)->relocs != internal_relocs)
+ free (internal_relocs);
+
+ return TRUE;
+
+ error_return:
+ if (isymbuf != NULL
+ && symtab_hdr->contents != (unsigned char *) isymbuf)
+ free (isymbuf);
+ if (contents != NULL
+ && elf_section_data (sec)->this_hdr.contents != contents)
+ free (contents);
+ if (internal_relocs != NULL
+ && elf_section_data (sec)->relocs != internal_relocs)
+ free (internal_relocs);
+
+ return FALSE;
+}
+
+/* Definitions for setting CRX target vector. */
+#define TARGET_LITTLE_SYM crx_elf32_vec
+#define TARGET_LITTLE_NAME "elf32-crx"
+#define ELF_ARCH bfd_arch_crx
+#define ELF_MACHINE_CODE EM_CRX
+#define ELF_MAXPAGESIZE 0x1
+#define elf_symbol_leading_char '_'
+
+#define bfd_elf32_bfd_reloc_type_lookup elf_crx_reloc_type_lookup
+#define bfd_elf32_bfd_reloc_name_lookup \
+ elf_crx_reloc_name_lookup
+#define elf_info_to_howto elf_crx_info_to_howto
+#define elf_info_to_howto_rel 0
+#define elf_backend_relocate_section elf32_crx_relocate_section
+#define bfd_elf32_bfd_relax_section elf32_crx_relax_section
+#define bfd_elf32_bfd_get_relocated_section_contents \
+ elf32_crx_get_relocated_section_contents
+#define elf_backend_can_gc_sections 1
+#define elf_backend_rela_normal 1
+
+#include "elf32-target.h"
diff --git a/bfd/elf32-d10v.c b/bfd/elf32-d10v.c
new file mode 100644
index 0000000..f45e2db
--- /dev/null
+++ b/bfd/elf32-d10v.c
@@ -0,0 +1,556 @@
+/* D10V-specific support for 32-bit ELF
+ Copyright (C) 1996-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+#include "elf-bfd.h"
+#include "elf/d10v.h"
+
+/* Use REL instead of RELA to save space. */
+#define USE_REL 1
+
+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_dont,/* 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). */
+ 8, /* Bitsize. */
+ TRUE, /* PC_relative. */
+ 0, /* Bitpos. */
+ complain_overflow_signed, /* 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). */
+ 8, /* Bitsize. */
+ TRUE, /* PC_relative. */
+ 15, /* Bitpos. */
+ complain_overflow_signed, /* 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). */
+ 16, /* 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). */
+ 16, /* 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_dont,/* 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 (bfd *abfd ATTRIBUTE_UNUSED,
+ 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;
+}
+
+static reloc_howto_type *
+bfd_elf32_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ const char *r_name)
+{
+ unsigned int i;
+
+ for (i = 0;
+ i < sizeof (elf_d10v_howto_table) / sizeof (elf_d10v_howto_table[0]);
+ i++)
+ if (elf_d10v_howto_table[i].name != NULL
+ && strcasecmp (elf_d10v_howto_table[i].name, r_name) == 0)
+ return &elf_d10v_howto_table[i];
+
+ return NULL;
+}
+
+/* Set the howto pointer for an D10V ELF reloc. */
+
+static void
+d10v_info_to_howto_rel (bfd *abfd ATTRIBUTE_UNUSED,
+ arelent *cache_ptr,
+ Elf_Internal_Rela *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 (asection *sec,
+ 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:
+ return NULL;
+ }
+
+ return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
+}
+
+/* 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 bfd_boolean
+elf32_d10v_check_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;
+ const Elf_Internal_Rela *rel;
+ const Elf_Internal_Rela *rel_end;
+
+ if (info->relocatable)
+ return TRUE;
+
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+ sym_hashes = elf_sym_hashes (abfd);
+
+ 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];
+ 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;
+
+ /* PR15323, ref flags aren't set for references in the same
+ object. */
+ h->root.non_ir_ref = 1;
+ }
+
+ 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_elf_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:
+ BFD_ASSERT (h != NULL);
+ if (h != NULL
+ && !bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_offset))
+ return FALSE;
+ break;
+ }
+ }
+
+ return TRUE;
+}
+
+static bfd_vma
+extract_rel_addend (bfd *abfd,
+ bfd_byte *where,
+ reloc_howto_type *howto)
+{
+ bfd_vma insn, val;
+
+ switch (howto->size)
+ {
+ case 0:
+ insn = bfd_get_8 (abfd, where);
+ break;
+ case 1:
+ insn = bfd_get_16 (abfd, where);
+ break;
+ case 2:
+ insn = bfd_get_32 (abfd, where);
+ break;
+ default:
+ abort ();
+ }
+
+ val = (insn & howto->dst_mask) >> howto->bitpos << howto->rightshift;
+ /* We should really be testing for signed addends here, but we don't
+ have that info directly in the howto. */
+ if (howto->pc_relative)
+ {
+ bfd_vma sign;
+ sign = howto->dst_mask & (~howto->dst_mask >> 1 | ~(-(bfd_vma) 1 >> 1));
+ sign = sign >> howto->bitpos << howto->rightshift;
+ val = (val ^ sign) - sign;
+ }
+ return val;
+}
+
+static void
+insert_rel_addend (bfd *abfd,
+ bfd_byte *where,
+ reloc_howto_type *howto,
+ bfd_vma addend)
+{
+ bfd_vma insn;
+
+ addend = (addend >> howto->rightshift << howto->bitpos) & howto->dst_mask;
+ insn = ~howto->dst_mask;
+ switch (howto->size)
+ {
+ case 0:
+ insn &= bfd_get_8 (abfd, where);
+ insn |= addend;
+ bfd_put_8 (abfd, insn, where);
+ break;
+ case 1:
+ insn &= bfd_get_16 (abfd, where);
+ insn |= addend;
+ bfd_put_16 (abfd, insn, where);
+ break;
+ case 2:
+ insn &= bfd_get_32 (abfd, where);
+ insn |= addend;
+ bfd_put_32 (abfd, insn, where);
+ break;
+ default:
+ abort ();
+ }
+}
+
+/* Relocate a D10V ELF section. */
+
+static bfd_boolean
+elf32_d10v_relocate_section (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;
+ 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 (ELF_ST_TYPE (sym->st_info) == STT_SECTION
+ && ((sec->flags & SEC_MERGE) != 0
+ || (info->relocatable
+ && sec->output_offset != 0)))
+ {
+ bfd_vma addend;
+ bfd_byte *where = contents + rel->r_offset;
+
+ addend = extract_rel_addend (input_bfd, where, howto);
+
+ if (info->relocatable)
+ addend += sec->output_offset;
+ else
+ {
+ asection *msec = sec;
+ addend = _bfd_elf_rel_local_sym (output_bfd, sym, &msec,
+ addend);
+ addend -= relocation;
+ addend += msec->output_section->vma + msec->output_offset;
+ }
+ insert_rel_addend (input_bfd, where, howto, addend);
+ }
+ }
+ else
+ {
+ bfd_boolean unresolved_reloc, warned, ignored;
+
+ RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
+ r_symndx, symtab_hdr, sym_hashes,
+ h, sec, relocation,
+ unresolved_reloc, warned, ignored);
+ }
+
+ if (sec != NULL && discarded_section (sec))
+ RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+ rel, 1, relend, howto, 0, contents);
+
+ if (info->relocatable)
+ continue;
+
+ 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, (bfd_vma) 0);
+
+ if (r != bfd_reloc_ok)
+ {
+ const char * msg = (const char *) 0;
+
+ switch (r)
+ {
+ case bfd_reloc_overflow:
+ if (!((*info->callbacks->reloc_overflow)
+ (info, (h ? &h->root : NULL), 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, TRUE)))
+ 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_D10V
+#define ELF_MACHINE_ALT1 EM_CYGNUS_D10V
+#define ELF_MAXPAGESIZE 0x1000
+
+#define TARGET_BIG_SYM d10v_elf32_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_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 0000000..211a673
--- /dev/null
+++ b/bfd/elf32-d30v.c
@@ -0,0 +1,550 @@
+/* D30V-specific support for 32-bit ELF
+ Copyright (C) 1997-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+#include "elf-bfd.h"
+#include "elf/d30v.h"
+
+#define MAX32 ((bfd_signed_vma) 0x7fffffff)
+#define MIN32 (- MAX32 - 1)
+
+static bfd_reloc_status_type
+bfd_elf_d30v_reloc (bfd *abfd,
+ arelent *reloc_entry,
+ asymbol *symbol,
+ void * data,
+ asection *input_section,
+ bfd *output_bfd,
+ char **error_message)
+{
+ bfd_signed_vma 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;
+
+ if (output_bfd != NULL)
+ {
+ /* Partial linking -- do nothing. */
+ reloc_entry->address += input_section->output_offset;
+ return bfd_reloc_ok;
+ }
+
+ 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 == NULL)
+ flag = bfd_reloc_undefined;
+
+ /* Is the address of the relocation really within the section? */
+ if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
+ return bfd_reloc_outofrange;
+
+ /* Work out which section the relocation is targeted 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. */
+ 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)
+ {
+ tmp_addr = input_section->output_section->vma
+ + input_section->output_offset
+ + reloc_entry->address;
+ relocation -= tmp_addr;
+ }
+
+ 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 && howto->bitsize == 32)
+ {
+ /* The D30V has a PC that doesn't wrap and PC-relative jumps are
+ signed, so a PC-relative jump can't be more than +/- 2^31 bytes.
+ If one exceeds this, change it to an absolute jump. */
+ if (relocation > MAX32 || 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 (bfd *abfd,
+ arelent *reloc_entry,
+ asymbol *symbol,
+ void * 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;
+
+ if (output_bfd != NULL)
+ {
+ /* Partial linking -- do nothing. */
+ reloc_entry->address += input_section->output_offset;
+ return bfd_reloc_ok;
+ }
+
+ 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 == NULL)
+ flag = bfd_reloc_undefined;
+
+ /* Is the address of the relocation really within the section? */
+ if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
+ return bfd_reloc_outofrange;
+
+ /* Work out which section the relocation is targeted 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. */
+ 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)
+ {
+ relocation -= (input_section->output_section->vma
+ + input_section->output_offset);
+ if (howto->pcrel_offset)
+ relocation -= reloc_entry->address;
+ }
+
+ 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;
+}
+
+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. */
+
+};
+
+/* 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 (bfd *abfd ATTRIBUTE_UNUSED,
+ 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;
+}
+
+static reloc_howto_type *
+bfd_elf32_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ const char *r_name)
+{
+ unsigned int i;
+
+ for (i = 0;
+ i < sizeof (elf_d30v_howto_table) / sizeof (elf_d30v_howto_table[0]);
+ i++)
+ if (elf_d30v_howto_table[i].name != NULL
+ && strcasecmp (elf_d30v_howto_table[i].name, r_name) == 0)
+ return &elf_d30v_howto_table[i];
+
+ return NULL;
+}
+
+/* Set the howto pointer for an D30V ELF reloc (type REL). */
+
+static void
+d30v_info_to_howto_rel (bfd *abfd ATTRIBUTE_UNUSED,
+ arelent *cache_ptr,
+ Elf_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];
+}
+
+/* Set the howto pointer for an D30V ELF reloc (type RELA). */
+
+static void
+d30v_info_to_howto_rela (bfd *abfd ATTRIBUTE_UNUSED,
+ arelent *cache_ptr,
+ Elf_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_D30V
+#define ELF_MACHINE_ALT1 EM_CYGNUS_D30V
+#define ELF_MAXPAGESIZE 0x1000
+
+#define TARGET_BIG_SYM d30v_elf32_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-dlx.c b/bfd/elf32-dlx.c
new file mode 100644
index 0000000..91441aa
--- /dev/null
+++ b/bfd/elf32-dlx.c
@@ -0,0 +1,580 @@
+/* DLX specific support for 32-bit ELF
+ Copyright (C) 2002-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+#include "elf-bfd.h"
+#include "elf/dlx.h"
+
+#define USE_REL 1
+
+#define bfd_elf32_bfd_reloc_type_lookup elf32_dlx_reloc_type_lookup
+#define bfd_elf32_bfd_reloc_name_lookup elf32_dlx_reloc_name_lookup
+#define elf_info_to_howto elf32_dlx_info_to_howto
+#define elf_info_to_howto_rel elf32_dlx_info_to_howto_rel
+#define elf_backend_check_relocs elf32_dlx_check_relocs
+
+/* The gas default behavior is not to preform the %hi modifier so that the
+ GNU assembler can have the lower 16 bits offset placed in the insn, BUT
+ we do like the gas to indicate it is %hi reloc type so when we in the link
+ loader phase we can have the corrected hi16 vale replace the buggous lo16
+ value that was placed there by gas. */
+
+static int skip_dlx_elf_hi16_reloc = 0;
+
+extern int set_dlx_skip_hi16_flag (int);
+
+int
+set_dlx_skip_hi16_flag (int flag)
+{
+ skip_dlx_elf_hi16_reloc = flag;
+ return flag;
+}
+
+static bfd_reloc_status_type
+_bfd_dlx_elf_hi16_reloc (bfd *abfd,
+ arelent *reloc_entry,
+ asymbol *symbol,
+ void * data,
+ asection *input_section,
+ bfd *output_bfd,
+ char **error_message)
+{
+ bfd_reloc_status_type ret;
+ bfd_vma relocation;
+
+ /* If the skip flag is set then we simply do the generic relocating, this
+ is more of a hack for dlx gas/gld, so we do not need to do the %hi/%lo
+ fixup like mips gld did. */
+ if (skip_dlx_elf_hi16_reloc)
+ return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
+ input_section, output_bfd, 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;
+ }
+
+ ret = bfd_reloc_ok;
+
+ if (bfd_is_und_section (symbol->section)
+ && output_bfd == (bfd *) NULL)
+ ret = bfd_reloc_undefined;
+
+ relocation = (bfd_is_com_section (symbol->section)) ? 0 : symbol->value;
+ relocation += symbol->section->output_section->vma;
+ relocation += symbol->section->output_offset;
+ relocation += reloc_entry->addend;
+ relocation += bfd_get_16 (abfd, (bfd_byte *)data + reloc_entry->address);
+
+ if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
+ return bfd_reloc_outofrange;
+
+ bfd_put_16 (abfd, (short)((relocation >> 16) & 0xFFFF),
+ (bfd_byte *)data + reloc_entry->address);
+
+ return ret;
+}
+
+/* ELF relocs are against symbols. If we are producing relocatable
+ 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
+ relocatable output against an external symbol. */
+
+static bfd_reloc_status_type
+elf32_dlx_relocate16 (bfd *abfd,
+ arelent *reloc_entry,
+ asymbol *symbol,
+ void * data,
+ asection *input_section,
+ bfd *output_bfd,
+ char **error_message ATTRIBUTE_UNUSED)
+{
+ unsigned long insn, vallo, allignment;
+ int val;
+
+ /* HACK: I think this first condition is necessary when producing
+ relocatable output. After the end of HACK, the code is identical
+ to bfd_elf_generic_reloc(). I would _guess_ the first change
+ belongs there rather than here. martindo 1998-10-23. */
+
+ if (skip_dlx_elf_hi16_reloc)
+ return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
+ input_section, output_bfd, error_message);
+
+ /* Check undefined section and undefined symbols. */
+ if (bfd_is_und_section (symbol->section)
+ && output_bfd == (bfd *) NULL)
+ return bfd_reloc_undefined;
+
+ /* Can not support a long jump to sections other then .text. */
+ if (strcmp (input_section->name, symbol->section->output_section->name) != 0)
+ {
+ (*_bfd_error_handler) (_("BFD Link Error: branch (PC rel16) to section (%s) not supported"),
+ symbol->section->output_section->name);
+ return bfd_reloc_undefined;
+ }
+
+ insn = bfd_get_32 (abfd, (bfd_byte *)data + reloc_entry->address);
+ allignment = 1 << (input_section->output_section->alignment_power - 1);
+ vallo = insn & 0x0000FFFF;
+
+ if (vallo & 0x8000)
+ vallo = ~(vallo | 0xFFFF0000) + 1;
+
+ /* vallo points to the vma of next instruction. */
+ vallo += (((unsigned long)(input_section->output_section->vma +
+ input_section->output_offset) +
+ allignment) & ~allignment);
+
+ /* val is the displacement (PC relative to next instruction). */
+ val = (symbol->section->output_offset +
+ symbol->section->output_section->vma +
+ symbol->value) - vallo;
+
+ if (abs ((int) val) > 0x00007FFF)
+ return bfd_reloc_outofrange;
+
+ insn = (insn & 0xFFFF0000) | (val & 0x0000FFFF);
+
+ bfd_put_32 (abfd, insn,
+ (bfd_byte *) data + reloc_entry->address);
+
+ return bfd_reloc_ok;
+}
+
+static bfd_reloc_status_type
+elf32_dlx_relocate26 (bfd *abfd,
+ arelent *reloc_entry,
+ asymbol *symbol,
+ void * data,
+ asection *input_section,
+ bfd *output_bfd,
+ char **error_message ATTRIBUTE_UNUSED)
+{
+ unsigned long insn, vallo, allignment;
+ int val;
+
+ /* HACK: I think this first condition is necessary when producing
+ relocatable output. After the end of HACK, the code is identical
+ to bfd_elf_generic_reloc(). I would _guess_ the first change
+ belongs there rather than here. martindo 1998-10-23. */
+
+ if (skip_dlx_elf_hi16_reloc)
+ return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
+ input_section, output_bfd, error_message);
+
+ /* Check undefined section and undefined symbols. */
+ if (bfd_is_und_section (symbol->section)
+ && output_bfd == (bfd *) NULL)
+ return bfd_reloc_undefined;
+
+ /* Can not support a long jump to sections other then .text */
+ if (strcmp (input_section->name, symbol->section->output_section->name) != 0)
+ {
+ (*_bfd_error_handler) (_("BFD Link Error: jump (PC rel26) to section (%s) not supported"),
+ symbol->section->output_section->name);
+ return bfd_reloc_undefined;
+ }
+
+ insn = bfd_get_32 (abfd, (bfd_byte *)data + reloc_entry->address);
+ allignment = 1 << (input_section->output_section->alignment_power - 1);
+ vallo = insn & 0x03FFFFFF;
+
+ if (vallo & 0x03000000)
+ vallo = ~(vallo | 0xFC000000) + 1;
+
+ /* vallo is the vma for the next instruction. */
+ vallo += (((unsigned long) (input_section->output_section->vma +
+ input_section->output_offset) +
+ allignment) & ~allignment);
+
+ /* val is the displacement (PC relative to next instruction). */
+ val = (symbol->section->output_offset +
+ symbol->section->output_section->vma + symbol->value)
+ - vallo;
+
+ if (abs ((int) val) > 0x01FFFFFF)
+ return bfd_reloc_outofrange;
+
+ insn = (insn & 0xFC000000) | (val & 0x03FFFFFF);
+ bfd_put_32 (abfd, insn,
+ (bfd_byte *) data + reloc_entry->address);
+
+ return bfd_reloc_ok;
+}
+
+static reloc_howto_type dlx_elf_howto_table[]=
+{
+ /* No relocation. */
+ HOWTO (R_DLX_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_DLX_NONE", /* Name. */
+ FALSE, /* Partial_inplace. */
+ 0, /* Src_mask. */
+ 0, /* Dst_mask. */
+ FALSE), /* PCrel_offset. */
+
+ /* 8 bit relocation. */
+ HOWTO (R_DLX_RELOC_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_DLX_RELOC_8", /* Name. */
+ TRUE, /* Partial_inplace. */
+ 0xff, /* Src_mask. */
+ 0xff, /* Dst_mask. */
+ FALSE), /* PCrel_offset. */
+
+ /* 16 bit relocation. */
+ HOWTO (R_DLX_RELOC_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_DLX_RELOC_16", /* Name. */
+ TRUE, /* Partial_inplace. */
+ 0xffff, /* Src_mask. */
+ 0xffff, /* Dst_mask. */
+ FALSE), /* PCrel_offset. */
+
+ /* 32 bit relocation. */
+ HOWTO (R_DLX_RELOC_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. */
+ bfd_elf_generic_reloc, /* Special_function. */
+ "R_DLX_RELOC_32", /* Name. */
+ TRUE, /* Partial_inplace. */
+ 0xffffffff, /* Src_mask. */
+ 0xffffffff, /* Dst_mask. */
+ FALSE), /* PCrel_offset. */
+
+ /* GNU extension to record C++ vtable hierarchy. */
+ HOWTO (R_DLX_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_DLX_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_DLX_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_DLX_GNU_VTENTRY", /* Name. */
+ FALSE, /* Partial_inplace. */
+ 0, /* Src_mask. */
+ 0, /* Dst_mask. */
+ FALSE) /* PCrel_offset. */
+};
+
+/* 16 bit offset for pc-relative branches. */
+static reloc_howto_type elf_dlx_gnu_rel16_s2 =
+ HOWTO (R_DLX_RELOC_16_PCREL, /* Type. */
+ 0, /* Rightshift. */
+ 1, /* Size (0 = byte, 1 = short, 2 = long). */
+ 16, /* Bitsize. */
+ TRUE, /* PC_relative. */
+ 0, /* Bitpos. */
+ complain_overflow_signed, /* Complain_on_overflow. */
+ elf32_dlx_relocate16, /* Special_function. */
+ "R_DLX_RELOC_16_PCREL",/* Name. */
+ TRUE, /* Partial_inplace. */
+ 0xffff, /* Src_mask. */
+ 0xffff, /* Dst_mask. */
+ TRUE); /* PCrel_offset. */
+
+/* 26 bit offset for pc-relative branches. */
+static reloc_howto_type elf_dlx_gnu_rel26_s2 =
+ HOWTO (R_DLX_RELOC_26_PCREL, /* Type. */
+ 0, /* Rightshift. */
+ 2, /* Size (0 = byte, 1 = short, 2 = long). */
+ 26, /* Bitsize. */
+ TRUE, /* PC_relative. */
+ 0, /* Bitpos. */
+ complain_overflow_dont,/* Complain_on_overflow. */
+ elf32_dlx_relocate26, /* Special_function. */
+ "R_DLX_RELOC_26_PCREL",/* Name. */
+ TRUE, /* Partial_inplace. */
+ 0xffff, /* Src_mask. */
+ 0xffff, /* Dst_mask. */
+ TRUE); /* PCrel_offset. */
+
+/* High 16 bits of symbol value. */
+static reloc_howto_type elf_dlx_reloc_16_hi =
+ HOWTO (R_DLX_RELOC_16_HI, /* Type. */
+ 16, /* Rightshift. */
+ 2, /* Size (0 = byte, 1 = short, 2 = long). */
+ 32, /* Bitsize. */
+ FALSE, /* PC_relative. */
+ 0, /* Bitpos. */
+ complain_overflow_dont,/* Complain_on_overflow. */
+ _bfd_dlx_elf_hi16_reloc,/* Special_function. */
+ "R_DLX_RELOC_16_HI", /* Name. */
+ TRUE, /* Partial_inplace. */
+ 0xFFFF, /* Src_mask. */
+ 0xffff, /* Dst_mask. */
+ FALSE); /* PCrel_offset. */
+
+ /* Low 16 bits of symbol value. */
+static reloc_howto_type elf_dlx_reloc_16_lo =
+ HOWTO (R_DLX_RELOC_16_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_DLX_RELOC_16_LO", /* Name. */
+ TRUE, /* Partial_inplace. */
+ 0xffff, /* Src_mask. */
+ 0xffff, /* Dst_mask. */
+ FALSE); /* PCrel_offset. */
+
+/* A mapping from BFD reloc types to DLX ELF reloc types.
+ Stolen from elf32-mips.c.
+
+ More about this table - for dlx elf relocation we do not really
+ need this table, if we have a rtype defined in this table will
+ caused tc_gen_relocate confused and die on us, but if we remove
+ this table it will caused more problem, so for now simple solution
+ is to remove those entries which may cause problem. */
+struct elf_reloc_map
+{
+ bfd_reloc_code_real_type bfd_reloc_val;
+ enum elf_dlx_reloc_type elf_reloc_val;
+};
+
+static const struct elf_reloc_map dlx_reloc_map[] =
+{
+ { BFD_RELOC_NONE, R_DLX_NONE },
+ { BFD_RELOC_16, R_DLX_RELOC_16 },
+ { BFD_RELOC_32, R_DLX_RELOC_32 },
+ { BFD_RELOC_DLX_HI16_S, R_DLX_RELOC_16_HI },
+ { BFD_RELOC_DLX_LO16, R_DLX_RELOC_16_LO },
+ { BFD_RELOC_VTABLE_INHERIT, R_DLX_GNU_VTINHERIT },
+ { BFD_RELOC_VTABLE_ENTRY, R_DLX_GNU_VTENTRY }
+};
+
+/* 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 bfd_boolean
+elf32_dlx_check_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;
+ const Elf_Internal_Rela *rel;
+ const Elf_Internal_Rela *rel_end;
+
+ if (info->relocatable)
+ return TRUE;
+
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+ sym_hashes = elf_sym_hashes (abfd);
+
+ 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];
+ 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;
+
+ /* PR15323, ref flags aren't set for references in the same
+ object. */
+ h->root.non_ir_ref = 1;
+ }
+
+ switch (ELF32_R_TYPE (rel->r_info))
+ {
+ /* This relocation describes the C++ object vtable hierarchy.
+ Reconstruct it for later use during GC. */
+ case R_DLX_GNU_VTINHERIT:
+ if (!bfd_elf_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_DLX_GNU_VTENTRY:
+ BFD_ASSERT (h != NULL);
+ if (h != NULL
+ && !bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
+ return FALSE;
+ break;
+ }
+ }
+
+ return TRUE;
+}
+
+/* Given a BFD reloc type, return a howto structure. */
+
+static reloc_howto_type *
+elf32_dlx_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ bfd_reloc_code_real_type code)
+{
+ unsigned int i;
+
+ for (i = 0; i < sizeof (dlx_reloc_map) / sizeof (struct elf_reloc_map); i++)
+ if (dlx_reloc_map[i].bfd_reloc_val == code)
+ return &dlx_elf_howto_table[(int) dlx_reloc_map[i].elf_reloc_val];
+
+ switch (code)
+ {
+ default:
+ bfd_set_error (bfd_error_bad_value);
+ return NULL;
+ case BFD_RELOC_16_PCREL_S2:
+ return &elf_dlx_gnu_rel16_s2;
+ case BFD_RELOC_DLX_JMP26:
+ return &elf_dlx_gnu_rel26_s2;
+ case BFD_RELOC_HI16_S:
+ return &elf_dlx_reloc_16_hi;
+ case BFD_RELOC_LO16:
+ return &elf_dlx_reloc_16_lo;
+ }
+}
+
+static reloc_howto_type *
+elf32_dlx_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ const char *r_name)
+{
+ unsigned int i;
+
+ for (i = 0;
+ i < sizeof (dlx_elf_howto_table) / sizeof (dlx_elf_howto_table[0]);
+ i++)
+ if (dlx_elf_howto_table[i].name != NULL
+ && strcasecmp (dlx_elf_howto_table[i].name, r_name) == 0)
+ return &dlx_elf_howto_table[i];
+
+ if (strcasecmp (elf_dlx_gnu_rel16_s2.name, r_name) == 0)
+ return &elf_dlx_gnu_rel16_s2;
+ if (strcasecmp (elf_dlx_gnu_rel26_s2.name, r_name) == 0)
+ return &elf_dlx_gnu_rel26_s2;
+ if (strcasecmp (elf_dlx_reloc_16_hi.name, r_name) == 0)
+ return &elf_dlx_reloc_16_hi;
+ if (strcasecmp (elf_dlx_reloc_16_lo.name, r_name) == 0)
+ return &elf_dlx_reloc_16_lo;
+
+ return NULL;
+}
+
+static reloc_howto_type *
+dlx_rtype_to_howto (unsigned int r_type)
+{
+ switch (r_type)
+ {
+ case R_DLX_RELOC_16_PCREL:
+ return & elf_dlx_gnu_rel16_s2;
+ case R_DLX_RELOC_26_PCREL:
+ return & elf_dlx_gnu_rel26_s2;
+ case R_DLX_RELOC_16_HI:
+ return & elf_dlx_reloc_16_hi;
+ case R_DLX_RELOC_16_LO:
+ return & elf_dlx_reloc_16_lo;
+ default:
+ BFD_ASSERT (r_type < (unsigned int) R_DLX_max);
+ return & dlx_elf_howto_table[r_type];
+ }
+}
+
+static void
+elf32_dlx_info_to_howto (bfd * abfd ATTRIBUTE_UNUSED,
+ arelent * cache_ptr ATTRIBUTE_UNUSED,
+ Elf_Internal_Rela * dst ATTRIBUTE_UNUSED)
+{
+ abort ();
+}
+
+static void
+elf32_dlx_info_to_howto_rel (bfd *abfd ATTRIBUTE_UNUSED,
+ arelent *cache_ptr,
+ Elf_Internal_Rela *dst)
+{
+ unsigned int r_type;
+
+ r_type = ELF32_R_TYPE (dst->r_info);
+ cache_ptr->howto = dlx_rtype_to_howto (r_type);
+ return;
+}
+
+#define TARGET_BIG_SYM dlx_elf32_be_vec
+#define TARGET_BIG_NAME "elf32-dlx"
+#define ELF_ARCH bfd_arch_dlx
+#define ELF_MACHINE_CODE EM_DLX
+#define ELF_MAXPAGESIZE 1 /* FIXME: This number is wrong, It should be the page size in bytes. */
+
+#include "elf32-target.h"
diff --git a/bfd/elf32-epiphany.c b/bfd/elf32-epiphany.c
new file mode 100644
index 0000000..8d95cc9
--- /dev/null
+++ b/bfd/elf32-epiphany.c
@@ -0,0 +1,608 @@
+/* Adapteva epiphany specific support for 32-bit ELF
+ Copyright (C) 2000-2014 Free Software Foundation, Inc.
+ Contributed by Embecosm on behalf of Adapteva, 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+#include "elf-bfd.h"
+#include "elf/epiphany.h"
+#include "libiberty.h"
+
+/* Struct used to pass miscellaneous paramaters which
+ helps to avoid overly long parameter lists. */
+struct misc
+{
+ Elf_Internal_Shdr * symtab_hdr;
+ Elf_Internal_Rela * irelbase;
+ bfd_byte * contents;
+ Elf_Internal_Sym * isymbuf;
+};
+
+struct epiphany_opcode
+{
+ unsigned short opcode;
+ unsigned short mask;
+};
+
+static bfd_boolean epiphany_relaxed = FALSE;
+
+/* Relocation tables. */
+static reloc_howto_type epiphany_elf_howto_table [] =
+{
+#define AHOW(t,rs,s,bs,pr,bp,co,name,sm,dm) \
+ HOWTO(t, /* type */ \
+ rs, /* rightshift */ \
+ s, /* size (0 = byte, 1 = short, 2 = long) */ \
+ bs, /* bitsize */ \
+ pr, /* pc_relative */ \
+ bp, /* bitpos */ \
+ co, /* complain_on_overflow */ \
+ bfd_elf_generic_reloc,/* special_function */ \
+ name, /* name */ \
+ FALSE, /* partial_inplace */ \
+ sm, /* src_mask */ \
+ dm, /* dst_mask */ \
+ pr) /* pcrel_offset */
+
+ /* This reloc does nothing. */
+ AHOW (R_EPIPHANY_NONE, 0, 0,32, FALSE, 0, complain_overflow_dont, "R_EPIPHANY_NONE", 0, 0),
+
+ /* 8 bit absolute (not likely) */
+ AHOW (R_EPIPHANY_8, 0, 0, 8, FALSE, 0, complain_overflow_bitfield, "R_EPIPHANY_8", 0x000000ff, 0x000000ff),
+ /* 16 bit absolute */
+ AHOW (R_EPIPHANY_16, 0, 1,16, FALSE, 0, complain_overflow_bitfield, "R_EPIPHANY_16", 0x0000ffff, 0x00ff1fe0),
+ /* A 32 bit absolute relocation. */
+ AHOW (R_EPIPHANY_32, 0, 2,32, FALSE, 0, complain_overflow_dont, "R_EPIPHANY_32", 0xffffffff, 0xffffffff),
+
+ /* 8 bit relative relocation */
+ HOWTO ( R_EPIPHANY_8_PCREL, 0, 0, 8, TRUE, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_EPIPHANY_8_PCREL", FALSE, 0x000000ff, 0x000000ff, FALSE),
+ /* 16 bit relative relocation */
+ HOWTO ( R_EPIPHANY_16_PCREL, 0, 1, 16, TRUE, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_EPIPHANY_8_PCREL", FALSE, 0x000000ff, 0x000000ff, FALSE),
+ /* 32 bit relative relocation */
+ HOWTO ( R_EPIPHANY_32_PCREL, 0, 2, 32, TRUE, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_EPIPHANY_8_PCREL", FALSE, 0x000000ff, 0x000000ff, FALSE),
+
+ /* 8 bit pc-relative relocation */
+ AHOW (R_EPIPHANY_SIMM8, 1, 0, 8, TRUE, 8, complain_overflow_signed, "R_EPIPHANY_SIMM8", 0x000000ff, 0x0000ff00),
+ /* 24 bit pc-relative relocation */
+ AHOW (R_EPIPHANY_SIMM24, 1, 2,24, TRUE, 8, complain_overflow_signed, "R_EPIPHANY_SIMM24", 0x00ffffff, 0xffffff00),
+
+ /* %HIGH(EA) */
+ AHOW (R_EPIPHANY_HIGH, 0, 2,16, FALSE, 0, complain_overflow_dont, "R_EPIPHANY_HIGH", 0x0ff01fe0, 0x0ff01fe0),
+
+ /* %LOW(EA) */
+ AHOW (R_EPIPHANY_LOW, 0, 2,16, FALSE, 0, complain_overflow_dont, "R_EPIPHANY_LOW", 0x0ff01fe0, 0x0ff01fe0),
+
+ /* simm11 */
+ AHOW (R_EPIPHANY_SIMM11, 0, 2,11, FALSE, 0, complain_overflow_bitfield, "R_EPIPHANY_SIMM11", 0x00ff0380, 0x00ff0380),
+ /* imm12 - sign-magnitude */
+ AHOW (R_EPIPHANY_IMM11, 0, 2,11, FALSE, 0, complain_overflow_bitfield, "R_EPIPHANY_IMM12", 0x00ff0380, 0x00ff0380),
+ /* imm8 */
+ AHOW (R_EPIPHANY_IMM8, 0, 1, 8, FALSE, 8, complain_overflow_signed, "R_EPIPHANY_IMM8", 0x0000ff00, 0x0000ff00)
+
+
+};
+#undef AHOW
+
+/* Map BFD reloc types to EPIPHANY ELF reloc types. */
+
+static reloc_howto_type *
+epiphany_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED,
+ bfd_reloc_code_real_type code)
+{
+ /* Note that the epiphany_elf_howto_table is indxed by the R_
+ constants. Thus, the order that the howto records appear in the
+ table *must* match the order of the relocation types defined in
+ include/elf/epiphany.h. */
+
+ switch (code)
+ {
+ case BFD_RELOC_NONE:
+ return &epiphany_elf_howto_table[ (int) R_EPIPHANY_NONE];
+
+ case BFD_RELOC_EPIPHANY_SIMM8:
+ return &epiphany_elf_howto_table[ (int) R_EPIPHANY_SIMM8];
+ case BFD_RELOC_EPIPHANY_SIMM24:
+ return &epiphany_elf_howto_table[ (int) R_EPIPHANY_SIMM24];
+
+ case BFD_RELOC_8_PCREL:
+ return &epiphany_elf_howto_table[ (int) R_EPIPHANY_8_PCREL];
+ case BFD_RELOC_16_PCREL:
+ return &epiphany_elf_howto_table[ (int) R_EPIPHANY_16_PCREL];
+ case BFD_RELOC_32_PCREL:
+ return &epiphany_elf_howto_table[ (int) R_EPIPHANY_32_PCREL];
+
+ case BFD_RELOC_8:
+ return &epiphany_elf_howto_table[ (int) R_EPIPHANY_8];
+ case BFD_RELOC_16:
+ return &epiphany_elf_howto_table[ (int) R_EPIPHANY_16];
+ case BFD_RELOC_32:
+ return &epiphany_elf_howto_table[ (int) R_EPIPHANY_32];
+
+ case BFD_RELOC_EPIPHANY_HIGH:
+ return & epiphany_elf_howto_table[ (int) R_EPIPHANY_HIGH];
+ case BFD_RELOC_EPIPHANY_LOW:
+ return & epiphany_elf_howto_table[ (int) R_EPIPHANY_LOW];
+
+ case BFD_RELOC_EPIPHANY_SIMM11:
+ return & epiphany_elf_howto_table[ (int) R_EPIPHANY_SIMM11];
+ case BFD_RELOC_EPIPHANY_IMM11:
+ return & epiphany_elf_howto_table[ (int) R_EPIPHANY_IMM11];
+
+ case BFD_RELOC_EPIPHANY_IMM8:
+ return & epiphany_elf_howto_table[ (int) R_EPIPHANY_IMM8];
+
+ default:
+ /* Pacify gcc -Wall. */
+ return NULL;
+ }
+ return NULL;
+}
+
+static reloc_howto_type *
+epiphany_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, const char *r_name)
+{
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE (epiphany_elf_howto_table); i++)
+ if (epiphany_elf_howto_table[i].name != NULL
+ && strcasecmp (epiphany_elf_howto_table[i].name, r_name) == 0)
+ return &epiphany_elf_howto_table[i];
+
+ return NULL;
+}
+
+#define PAGENO(ABSADDR) ((ABSADDR) & 0xFFFFC000)
+#define BASEADDR(SEC) ((SEC)->output_section->vma + (SEC)->output_offset)
+
+/* This function handles relaxing for the epiphany.
+ Dummy placeholder for future optimizations. */
+
+static bfd_boolean
+epiphany_elf_relax_section (bfd *abfd, asection *sec,
+ struct bfd_link_info *link_info,
+ bfd_boolean *again)
+{
+ Elf_Internal_Shdr *symtab_hdr;
+ Elf_Internal_Rela *internal_relocs;
+ bfd_byte *contents = NULL;
+ Elf_Internal_Sym *isymbuf = NULL;
+ static asection * first_section = NULL;
+ static unsigned long search_addr;
+ static unsigned long page_start = 0;
+ static unsigned long page_end = 0;
+ static unsigned int pass = 0;
+ static bfd_boolean new_pass = FALSE;
+ static bfd_boolean changed = FALSE;
+ struct misc misc ATTRIBUTE_UNUSED;
+ asection *stab;
+
+ /* Assume nothing changes. */
+ *again = FALSE;
+
+ if (first_section == NULL)
+ {
+ epiphany_relaxed = TRUE;
+ first_section = sec;
+ }
+
+ if (first_section == sec)
+ {
+ pass++;
+ new_pass = TRUE;
+ }
+
+ /* We don't have to do anything for a relocatable link,
+ if this section does not have relocs, or if this is
+ not a code section. */
+ if (link_info->relocatable
+ || (sec->flags & SEC_RELOC) == 0
+ || sec->reloc_count == 0
+ || (sec->flags & SEC_CODE) == 0)
+ return TRUE;
+
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+
+ internal_relocs = _bfd_elf_link_read_relocs (abfd, sec, NULL, NULL,
+ link_info->keep_memory);
+ if (internal_relocs == NULL)
+ goto error_return;
+
+ /* Make sure the stac.rela stuff gets read in. */
+ stab = bfd_get_section_by_name (abfd, ".stab");
+
+ if (stab)
+ {
+ /* So stab does exits. */
+ Elf_Internal_Rela * irelbase ATTRIBUTE_UNUSED;
+
+ irelbase = _bfd_elf_link_read_relocs (abfd, stab, NULL, NULL,
+ link_info->keep_memory);
+ }
+
+ /* Get section contents cached copy if it exists. */
+ 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. */
+ if (!bfd_malloc_and_get_section (abfd, sec, &contents))
+ goto error_return;
+ }
+ }
+
+ /* Read this BFD's symbols cached copy if it exists. */
+ if (isymbuf == NULL && symtab_hdr->sh_info != 0)
+ {
+ isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
+ if (isymbuf == NULL)
+ isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
+ symtab_hdr->sh_info, 0,
+ NULL, NULL, NULL);
+ if (isymbuf == NULL)
+ goto error_return;
+ }
+
+ misc.symtab_hdr = symtab_hdr;
+ misc.isymbuf = isymbuf;
+ misc.irelbase = internal_relocs;
+ misc.contents = contents;
+
+ /* This is where all the relaxation actually get done. */
+ if ((pass == 1) || (new_pass && !changed))
+ {
+ /* On the first pass we simply search for the lowest page that
+ we havn't relaxed yet. Note that the pass count is reset
+ each time a page is complete in order to move on to the next page.
+ If we can't find any more pages then we are finished. */
+ if (new_pass)
+ {
+ pass = 1;
+ new_pass = FALSE;
+ changed = TRUE; /* Pre-initialize to break out of pass 1. */
+ search_addr = 0xFFFFFFFF;
+ }
+
+ if ((BASEADDR (sec) + sec->size < search_addr)
+ && (BASEADDR (sec) + sec->size > page_end))
+ {
+ if (BASEADDR (sec) <= page_end)
+ search_addr = page_end + 1;
+ else
+ search_addr = BASEADDR (sec);
+
+ /* Found a page => more work to do. */
+ *again = TRUE;
+ }
+ }
+ else
+ {
+ if (new_pass)
+ {
+ new_pass = FALSE;
+ changed = FALSE;
+ page_start = PAGENO (search_addr);
+ page_end = page_start | 0x00003FFF;
+ }
+
+ /* Only process sections in range. */
+ if ((BASEADDR (sec) + sec->size >= page_start)
+ && (BASEADDR (sec) <= page_end))
+ {
+#if 0
+ if (!epiphany_elf_relax_section_page (abfd, sec, &changed, &misc,
+ page_start, page_end))
+#endif
+ return FALSE;
+ }
+ *again = TRUE;
+ }
+
+ /* Perform some house keeping after relaxing the section. */
+
+ if (isymbuf != NULL
+ && symtab_hdr->contents != (unsigned char *) isymbuf)
+ {
+ if (! link_info->keep_memory)
+ free (isymbuf);
+ else
+ symtab_hdr->contents = (unsigned char *) isymbuf;
+ }
+
+ if (contents != NULL
+ && elf_section_data (sec)->this_hdr.contents != contents)
+ {
+ if (! link_info->keep_memory)
+ free (contents);
+ else
+ {
+ /* Cache the section contents for elf_link_input_bfd. */
+ elf_section_data (sec)->this_hdr.contents = contents;
+ }
+ }
+
+ if (internal_relocs != NULL
+ && elf_section_data (sec)->relocs != internal_relocs)
+ free (internal_relocs);
+
+ return TRUE;
+
+ error_return:
+ if (isymbuf != NULL
+ && symtab_hdr->contents != (unsigned char *) isymbuf)
+ free (isymbuf);
+ if (contents != NULL
+ && elf_section_data (sec)->this_hdr.contents != contents)
+ free (contents);
+ if (internal_relocs != NULL
+ && elf_section_data (sec)->relocs != internal_relocs)
+ free (internal_relocs);
+ return FALSE;
+}
+
+/* Set the howto pointer for a EPIPHANY ELF reloc. */
+
+static void
+epiphany_info_to_howto_rela (bfd * abfd ATTRIBUTE_UNUSED,
+ arelent * cache_ptr,
+ Elf_Internal_Rela * dst)
+{
+ unsigned int r_type;
+
+ r_type = ELF32_R_TYPE (dst->r_info);
+ cache_ptr->howto = & epiphany_elf_howto_table [r_type];
+}
+
+/* Perform a single relocation.
+ By default we use the standard BFD routines. */
+
+static bfd_reloc_status_type
+epiphany_final_link_relocate (reloc_howto_type * howto,
+ bfd * input_bfd,
+ asection * input_section,
+ bfd_byte * contents,
+ Elf_Internal_Rela * rel,
+ bfd_vma relocation)
+{
+ switch (howto->type)
+ {
+ /* Handle 16 bit immediates. */
+ case R_EPIPHANY_HIGH:
+ relocation += rel->r_addend;
+ relocation >>= 16;
+ goto common;
+
+ case R_EPIPHANY_LOW:
+ relocation += rel->r_addend;
+ common:
+ relocation = ((relocation & 0xff00L) << 12)
+ | ((relocation & 0x00ffL) << 5);
+ /* Sanity check the address. */
+ if (rel->r_offset > bfd_get_section_limit (input_bfd, input_section))
+ return bfd_reloc_outofrange;
+
+ return _bfd_relocate_contents (howto, input_bfd, relocation,
+ contents + rel->r_offset);
+
+ case R_EPIPHANY_SIMM11:
+ relocation += rel->r_addend;
+ /* Check signed overflow. */
+ if ((int)relocation > 1023 || (int)relocation < -1024)
+ return bfd_reloc_outofrange;
+ goto disp11;
+
+ case R_EPIPHANY_IMM11:
+ relocation += rel->r_addend;
+ if ((unsigned int) relocation > 0x7ff)
+ return bfd_reloc_outofrange;
+ disp11:
+ relocation = ((relocation & 7) << 5)
+ || ((relocation & 0x7f8 ) << 13);
+ return _bfd_relocate_contents (howto, input_bfd, relocation,
+ contents + rel->r_offset);
+
+ /* Pass others through. */
+ default:
+ break;
+ }
+
+ /* Only install relocation if above tests did not disqualify it. */
+ return _bfd_final_link_relocate (howto, input_bfd, input_section,
+ contents, rel->r_offset,
+ relocation, rel->r_addend);
+}
+
+/* Relocate an EPIPHANY ELF section.
+
+ 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 relocatable
+ 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 relocatable 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 bfd_boolean
+epiphany_elf_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
+ 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 ATTRIBUTE_UNUSED;
+
+ r_type = ELF32_R_TYPE (rel->r_info);
+ r_symndx = ELF32_R_SYM (rel->r_info);
+ howto = epiphany_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 = BASEADDR (sec) + 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;
+ }
+ else
+ {
+ bfd_boolean warned ATTRIBUTE_UNUSED;
+ bfd_boolean unresolved_reloc ATTRIBUTE_UNUSED;
+ bfd_boolean ignored ATTRIBUTE_UNUSED;
+
+ RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
+ r_symndx, symtab_hdr, sym_hashes,
+ h, sec, relocation,
+ unresolved_reloc, warned, ignored);
+
+ name = h->root.root.string;
+ }
+
+ if (sec != NULL && discarded_section (sec))
+ RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+ rel, 1, relend, howto, 0, contents);
+
+ if (info->relocatable)
+ continue;
+
+ /* Finally, the sole EPIPHANY-specific part. */
+ r = epiphany_final_link_relocate (howto, input_bfd, input_section,
+ contents, rel, relocation);
+
+ if (r != bfd_reloc_ok)
+ {
+ const char * msg = NULL;
+
+ switch (r)
+ {
+ case bfd_reloc_overflow:
+ r = info->callbacks->reloc_overflow
+ (info, (h ? &h->root : NULL), 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, TRUE);
+ break;
+
+ case bfd_reloc_outofrange:
+ msg = _("internal error: out of range error");
+ break;
+
+ /* This is how epiphany_final_link_relocate tells us of a
+ non-kosher reference between insn & data address spaces. */
+ case bfd_reloc_notsupported:
+ if (sym != NULL) /* Only if it's not an unresolved symbol. */
+ msg = _("unsupported relocation between data/insn address spaces");
+ 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;
+}
+
+/* We only have a little-endian target. */
+#define TARGET_LITTLE_SYM epiphany_elf32_vec
+#define TARGET_LITTLE_NAME "elf32-epiphany"
+
+#define ELF_ARCH bfd_arch_epiphany
+#define ELF_MACHINE_CODE EM_ADAPTEVA_EPIPHANY
+
+#define ELF_MAXPAGESIZE 0x8000 /* No pages on the EPIPHANY. */
+
+#define elf_info_to_howto_rel NULL
+#define elf_info_to_howto epiphany_info_to_howto_rela
+
+#define elf_backend_can_gc_sections 1
+#define elf_backend_rela_normal 1
+#define elf_backend_relocate_section epiphany_elf_relocate_section
+
+#define elf_symbol_leading_char '_'
+#define bfd_elf32_bfd_reloc_type_lookup epiphany_reloc_type_lookup
+#define bfd_elf32_bfd_reloc_name_lookup epiphany_reloc_name_lookup
+#define bfd_elf32_bfd_relax_section epiphany_elf_relax_section
+
+#include "elf32-target.h"
diff --git a/bfd/elf32-fr30.c b/bfd/elf32-fr30.c
new file mode 100644
index 0000000..022a0a9
--- /dev/null
+++ b/bfd/elf32-fr30.c
@@ -0,0 +1,721 @@
+/* FR30-specific support for 32-bit ELF.
+ Copyright (C) 1998-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+#include "elf-bfd.h"
+#include "elf/fr30.h"
+
+/* Forward declarations. */
+static bfd_reloc_status_type
+fr30_elf_i20_reloc (bfd *, arelent *, asymbol *, void * data,
+ asection *, bfd *, char **error_message);
+static bfd_reloc_status_type
+fr30_elf_i32_reloc (bfd *, arelent *, asymbol *, void *,
+ asection *, bfd *, char **);
+
+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 */
+ FALSE, /* 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 */
+ FALSE, /* 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 */
+ FALSE, /* 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 */
+ FALSE, /* 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 */
+ FALSE, /* 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 */
+ FALSE, /* 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 */
+ FALSE, /* 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 */
+ FALSE, /* 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 (bfd *abfd,
+ arelent *reloc_entry,
+ asymbol *symbol,
+ void * data,
+ asection *input_section,
+ bfd *output_bfd,
+ char **error_message ATTRIBUTE_UNUSED)
+{
+ 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 > (((bfd_vma) 1 << 20) - 1))
+ return bfd_reloc_overflow;
+
+ x = bfd_get_32 (abfd, (char *) data + reloc_entry->address);
+ x = (x & 0xff0f0000) | (relocation & 0x0000ffff) | ((relocation & 0x000f0000) << 4);
+ bfd_put_32 (abfd, (bfd_vma) x, (char *) 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 (bfd *abfd,
+ arelent *reloc_entry,
+ asymbol *symbol,
+ void * data,
+ asection *input_section,
+ bfd *output_bfd,
+ char **error_message ATTRIBUTE_UNUSED)
+{
+ 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, (char *) 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 (bfd *abfd ATTRIBUTE_UNUSED,
+ 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;
+}
+
+static reloc_howto_type *
+fr30_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, const char *r_name)
+{
+ unsigned int i;
+
+ for (i = 0;
+ i < sizeof (fr30_elf_howto_table) / sizeof (fr30_elf_howto_table[0]);
+ i++)
+ if (fr30_elf_howto_table[i].name != NULL
+ && strcasecmp (fr30_elf_howto_table[i].name, r_name) == 0)
+ return &fr30_elf_howto_table[i];
+
+ return NULL;
+}
+
+/* Set the howto pointer for an FR30 ELF reloc. */
+
+static void
+fr30_info_to_howto_rela (bfd *abfd ATTRIBUTE_UNUSED,
+ arelent *cache_ptr,
+ Elf_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 (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.
+
+ 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 relocatable
+ 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 relocatable 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 bfd_boolean
+fr30_elf_relocate_section (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;
+ 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);
+
+ 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 = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
+
+ 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;
+ }
+ else
+ {
+ bfd_boolean unresolved_reloc, warned, ignored;
+
+ RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
+ r_symndx, symtab_hdr, sym_hashes,
+ h, sec, relocation,
+ unresolved_reloc, warned, ignored);
+
+ name = h->root.root.string;
+ }
+
+ if (sec != NULL && discarded_section (sec))
+ RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+ rel, 1, relend, howto, 0, contents);
+
+ if (info->relocatable)
+ continue;
+
+ 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, (h ? &h->root : NULL), 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,
+ TRUE);
+ 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 (asection *sec,
+ 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:
+ return NULL;
+ }
+
+ return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
+}
+
+/* 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 bfd_boolean
+fr30_elf_check_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;
+ const Elf_Internal_Rela *rel;
+ const Elf_Internal_Rela *rel_end;
+
+ if (info->relocatable)
+ return TRUE;
+
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+ sym_hashes = elf_sym_hashes (abfd);
+
+ 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];
+ 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;
+
+ /* PR15323, ref flags aren't set for references in the same
+ object. */
+ h->root.non_ir_ref = 1;
+ }
+
+ 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_elf_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:
+ BFD_ASSERT (h != NULL);
+ if (h != NULL
+ && !bfd_elf_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_FR30
+#define ELF_MACHINE_ALT1 EM_CYGNUS_FR30
+#define ELF_MAXPAGESIZE 0x1000
+
+#define TARGET_BIG_SYM fr30_elf32_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_check_relocs fr30_elf_check_relocs
+
+#define elf_backend_can_gc_sections 1
+#define elf_backend_rela_normal 1
+
+#define bfd_elf32_bfd_reloc_type_lookup fr30_reloc_type_lookup
+#define bfd_elf32_bfd_reloc_name_lookup fr30_reloc_name_lookup
+
+#include "elf32-target.h"
diff --git a/bfd/elf32-frv.c b/bfd/elf32-frv.c
new file mode 100644
index 0000000..46f299b
--- /dev/null
+++ b/bfd/elf32-frv.c
@@ -0,0 +1,6878 @@
+/* FRV-specific support for 32-bit ELF.
+ Copyright (C) 2002-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+#include "elf-bfd.h"
+#include "elf/frv.h"
+#include "dwarf2.h"
+#include "hashtab.h"
+
+/* Forward declarations. */
+
+
+static reloc_howto_type elf32_frv_howto_table [] =
+{
+ /* This reloc does nothing. */
+ HOWTO (R_FRV_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_FRV_NONE", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A 32 bit absolute relocation. */
+ HOWTO (R_FRV_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_FRV_32", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A 16 bit pc-relative relocation. */
+ HOWTO (R_FRV_LABEL16, /* 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_FRV_LABEL16", /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* A 24-bit pc-relative relocation. */
+ HOWTO (R_FRV_LABEL24, /* 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_FRV_LABEL24", /* name */
+ FALSE, /* partial_inplace */
+ 0x7e03ffff, /* src_mask */
+ 0x7e03ffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_FRV_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_FRV_LO16", /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_FRV_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_FRV_HI16", /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_FRV_GPREL12, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 12, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_FRV_GPREL12", /* name */
+ FALSE, /* partial_inplace */
+ 0xfff, /* src_mask */
+ 0xfff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_FRV_GPRELU12, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 12, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_FRV_GPRELU12", /* name */
+ FALSE, /* partial_inplace */
+ 0xfff, /* src_mask */
+ 0x3f03f, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_FRV_GPREL32, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_FRV_GPREL32", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_FRV_GPRELHI, /* 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_FRV_GPRELHI", /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_FRV_GPRELLO, /* 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_FRV_GPRELLO", /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A 12-bit signed operand with the GOT offset for the address of
+ the symbol. */
+ HOWTO (R_FRV_GOT12, /* type */
+ 0, /* 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_FRV_GOT12", /* name */
+ FALSE, /* partial_inplace */
+ 0xfff, /* src_mask */
+ 0xfff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* The upper 16 bits of the GOT offset for the address of the
+ symbol. */
+ HOWTO (R_FRV_GOTHI, /* 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_FRV_GOTHI", /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* The lower 16 bits of the GOT offset for the address of the
+ symbol. */
+ HOWTO (R_FRV_GOTLO, /* 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_FRV_GOTLO", /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* The 32-bit address of the canonical descriptor of a function. */
+ HOWTO (R_FRV_FUNCDESC, /* 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_FRV_FUNCDESC", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A 12-bit signed operand with the GOT offset for the address of
+ canonical descriptor of a function. */
+ HOWTO (R_FRV_FUNCDESC_GOT12, /* type */
+ 0, /* 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_FRV_FUNCDESC_GOT12", /* name */
+ FALSE, /* partial_inplace */
+ 0xfff, /* src_mask */
+ 0xfff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* The upper 16 bits of the GOT offset for the address of the
+ canonical descriptor of a function. */
+ HOWTO (R_FRV_FUNCDESC_GOTHI, /* 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_FRV_FUNCDESC_GOTHI", /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* The lower 16 bits of the GOT offset for the address of the
+ canonical descriptor of a function. */
+ HOWTO (R_FRV_FUNCDESC_GOTLO, /* 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_FRV_FUNCDESC_GOTLO", /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* The 64-bit descriptor of a function. */
+ HOWTO (R_FRV_FUNCDESC_VALUE, /* type */
+ 0, /* rightshift */
+ 2, /* 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_FRV_FUNCDESC_VALUE", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A 12-bit signed operand with the GOT offset for the address of
+ canonical descriptor of a function. */
+ HOWTO (R_FRV_FUNCDESC_GOTOFF12, /* type */
+ 0, /* 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_FRV_FUNCDESC_GOTOFF12", /* name */
+ FALSE, /* partial_inplace */
+ 0xfff, /* src_mask */
+ 0xfff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* The upper 16 bits of the GOT offset for the address of the
+ canonical descriptor of a function. */
+ HOWTO (R_FRV_FUNCDESC_GOTOFFHI, /* 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_FRV_FUNCDESC_GOTOFFHI", /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* The lower 16 bits of the GOT offset for the address of the
+ canonical descriptor of a function. */
+ HOWTO (R_FRV_FUNCDESC_GOTOFFLO, /* 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_FRV_FUNCDESC_GOTOFFLO", /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A 12-bit signed operand with the GOT offset for the address of
+ the symbol. */
+ HOWTO (R_FRV_GOTOFF12, /* type */
+ 0, /* 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_FRV_GOTOFF12", /* name */
+ FALSE, /* partial_inplace */
+ 0xfff, /* src_mask */
+ 0xfff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* The upper 16 bits of the GOT offset for the address of the
+ symbol. */
+ HOWTO (R_FRV_GOTOFFHI, /* 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_FRV_GOTOFFHI", /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* The lower 16 bits of the GOT offset for the address of the
+ symbol. */
+ HOWTO (R_FRV_GOTOFFLO, /* 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_FRV_GOTOFFLO", /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A 24-bit pc-relative relocation referencing the TLS PLT entry for
+ a thread-local symbol. If the symbol number is 0, it refers to
+ the module. */
+ HOWTO (R_FRV_GETTLSOFF, /* 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_FRV_GETTLSOFF", /* name */
+ FALSE, /* partial_inplace */
+ 0x7e03ffff, /* src_mask */
+ 0x7e03ffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* A 64-bit TLS descriptor for a symbol. This relocation is only
+ valid as a REL, dynamic relocation. */
+ HOWTO (R_FRV_TLSDESC_VALUE, /* type */
+ 0, /* rightshift */
+ 2, /* 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_FRV_TLSDESC_VALUE", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A 12-bit signed operand with the GOT offset for the TLS
+ descriptor of the symbol. */
+ HOWTO (R_FRV_GOTTLSDESC12, /* type */
+ 0, /* 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_FRV_GOTTLSDESC12", /* name */
+ FALSE, /* partial_inplace */
+ 0xfff, /* src_mask */
+ 0xfff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* The upper 16 bits of the GOT offset for the TLS descriptor of the
+ symbol. */
+ HOWTO (R_FRV_GOTTLSDESCHI, /* 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_FRV_GOTTLSDESCHI", /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* The lower 16 bits of the GOT offset for the TLS descriptor of the
+ symbol. */
+ HOWTO (R_FRV_GOTTLSDESCLO, /* 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_FRV_GOTTLSDESCLO", /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A 12-bit signed operand with the offset from the module base
+ address to the thread-local symbol address. */
+ HOWTO (R_FRV_TLSMOFF12, /* type */
+ 0, /* 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_FRV_TLSMOFF12", /* name */
+ FALSE, /* partial_inplace */
+ 0xfff, /* src_mask */
+ 0xfff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* The upper 16 bits of the offset from the module base address to
+ the thread-local symbol address. */
+ HOWTO (R_FRV_TLSMOFFHI, /* 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_FRV_TLSMOFFHI", /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* The lower 16 bits of the offset from the module base address to
+ the thread-local symbol address. */
+ HOWTO (R_FRV_TLSMOFFLO, /* 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_FRV_TLSMOFFLO", /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A 12-bit signed operand with the GOT offset for the TLSOFF entry
+ for a symbol. */
+ HOWTO (R_FRV_GOTTLSOFF12, /* type */
+ 0, /* 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_FRV_GOTTLSOFF12", /* name */
+ FALSE, /* partial_inplace */
+ 0xfff, /* src_mask */
+ 0xfff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* The upper 16 bits of the GOT offset for the TLSOFF entry for a
+ symbol. */
+ HOWTO (R_FRV_GOTTLSOFFHI, /* 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_FRV_GOTTLSOFFHI", /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* The lower 16 bits of the GOT offset for the TLSOFF entry for a
+ symbol. */
+ HOWTO (R_FRV_GOTTLSOFFLO, /* 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_FRV_GOTTLSOFFLO", /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* The 32-bit offset from the thread pointer (not the module base
+ address) to a thread-local symbol. */
+ HOWTO (R_FRV_TLSOFF, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_FRV_TLSOFF", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* An annotation for linker relaxation, that denotes the
+ symbol+addend whose TLS descriptor is referenced by the sum of
+ the two input registers of an ldd instruction. */
+ HOWTO (R_FRV_TLSDESC_RELAX, /* 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_generic_reloc, /* special_function */
+ "R_FRV_TLSDESC_RELAX", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* An annotation for linker relaxation, that denotes the
+ symbol+addend whose TLS resolver entry point is given by the sum
+ of the two register operands of an calll instruction. */
+ HOWTO (R_FRV_GETTLSOFF_RELAX, /* 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_generic_reloc, /* special_function */
+ "R_FRV_GETTLSOFF_RELAX", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* An annotation for linker relaxation, that denotes the
+ symbol+addend whose TLS offset GOT entry is given by the sum of
+ the two input registers of an ld instruction. */
+ HOWTO (R_FRV_TLSOFF_RELAX, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 0, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_FRV_TLSOFF_RELAX", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A 32-bit offset from the module base address to
+ the thread-local symbol address. */
+ HOWTO (R_FRV_TLSMOFF, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_FRV_TLSMOFF", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+};
+
+/* GNU extension to record C++ vtable hierarchy. */
+static reloc_howto_type elf32_frv_vtinherit_howto =
+ HOWTO (R_FRV_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_FRV_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_frv_vtentry_howto =
+ HOWTO (R_FRV_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_FRV_GNU_VTENTRY", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ FALSE); /* pcrel_offset */
+
+/* The following 3 relocations are REL. The only difference to the
+ entries in the table above are that partial_inplace is TRUE. */
+static reloc_howto_type elf32_frv_rel_32_howto =
+ HOWTO (R_FRV_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_FRV_32", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE); /* pcrel_offset */
+
+static reloc_howto_type elf32_frv_rel_funcdesc_howto =
+ HOWTO (R_FRV_FUNCDESC, /* 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_FRV_FUNCDESC", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE); /* pcrel_offset */
+
+static reloc_howto_type elf32_frv_rel_funcdesc_value_howto =
+ HOWTO (R_FRV_FUNCDESC_VALUE, /* type */
+ 0, /* rightshift */
+ 2, /* 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_FRV_FUNCDESC_VALUE", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE); /* pcrel_offset */
+
+static reloc_howto_type elf32_frv_rel_tlsdesc_value_howto =
+ /* A 64-bit TLS descriptor for a symbol. The first word resolves to
+ an entry point, and the second resolves to a special argument.
+ If the symbol turns out to be in static TLS, the entry point is a
+ return instruction, and the special argument is the TLS offset
+ for the symbol. If it's in dynamic TLS, the entry point is a TLS
+ offset resolver, and the special argument is a pointer to a data
+ structure allocated by the dynamic loader, containing the GOT
+ address for the offset resolver, the module id, the offset within
+ the module, and anything else the TLS offset resolver might need
+ to determine the TLS offset for the symbol in the running
+ thread. */
+ HOWTO (R_FRV_TLSDESC_VALUE, /* type */
+ 0, /* rightshift */
+ 2, /* 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_FRV_TLSDESC_VALUE", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE); /* pcrel_offset */
+
+static reloc_howto_type elf32_frv_rel_tlsoff_howto =
+ /* The 32-bit offset from the thread pointer (not the module base
+ address) to a thread-local symbol. */
+ HOWTO (R_FRV_TLSOFF, /* 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_FRV_TLSOFF", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE); /* pcrel_offset */
+
+
+
+extern const bfd_target frv_elf32_fdpic_vec;
+#define IS_FDPIC(bfd) ((bfd)->xvec == &frv_elf32_fdpic_vec)
+
+/* An extension of the elf hash table data structure, containing some
+ additional FRV-specific data. */
+struct frvfdpic_elf_link_hash_table
+{
+ struct elf_link_hash_table elf;
+
+ /* A pointer to the .got section. */
+ asection *sgot;
+ /* A pointer to the .rel.got section. */
+ asection *sgotrel;
+ /* A pointer to the .rofixup section. */
+ asection *sgotfixup;
+ /* A pointer to the .plt section. */
+ asection *splt;
+ /* A pointer to the .rel.plt section. */
+ asection *spltrel;
+ /* GOT base offset. */
+ bfd_vma got0;
+ /* Location of the first non-lazy PLT entry, i.e., the number of
+ bytes taken by lazy PLT entries. If locally-bound TLS
+ descriptors require a ret instruction, it will be placed at this
+ offset. */
+ bfd_vma plt0;
+ /* A hash table holding information about which symbols were
+ referenced with which PIC-related relocations. */
+ struct htab *relocs_info;
+ /* Summary reloc information collected by
+ _frvfdpic_count_got_plt_entries. */
+ struct _frvfdpic_dynamic_got_info *g;
+};
+
+/* Get the FRV ELF linker hash table from a link_info structure. */
+
+#define frvfdpic_hash_table(p) \
+ (elf_hash_table_id ((struct elf_link_hash_table *) ((p)->hash)) \
+ == FRV_ELF_DATA ? ((struct frvfdpic_elf_link_hash_table *) ((p)->hash)) : NULL)
+
+#define frvfdpic_got_section(info) \
+ (frvfdpic_hash_table (info)->sgot)
+#define frvfdpic_gotrel_section(info) \
+ (frvfdpic_hash_table (info)->sgotrel)
+#define frvfdpic_gotfixup_section(info) \
+ (frvfdpic_hash_table (info)->sgotfixup)
+#define frvfdpic_plt_section(info) \
+ (frvfdpic_hash_table (info)->splt)
+#define frvfdpic_pltrel_section(info) \
+ (frvfdpic_hash_table (info)->spltrel)
+#define frvfdpic_relocs_info(info) \
+ (frvfdpic_hash_table (info)->relocs_info)
+#define frvfdpic_got_initial_offset(info) \
+ (frvfdpic_hash_table (info)->got0)
+#define frvfdpic_plt_initial_offset(info) \
+ (frvfdpic_hash_table (info)->plt0)
+#define frvfdpic_dynamic_got_plt_info(info) \
+ (frvfdpic_hash_table (info)->g)
+
+/* Currently it's the same, but if some day we have a reason to change
+ it, we'd better be using a different macro.
+
+ FIXME: if there's any TLS PLT entry that uses local-exec or
+ initial-exec models, we could use the ret at the end of any of them
+ instead of adding one more. */
+#define frvfdpic_plt_tls_ret_offset(info) \
+ (frvfdpic_plt_initial_offset (info))
+
+/* The name of the dynamic interpreter. This is put in the .interp
+ section. */
+
+#define ELF_DYNAMIC_INTERPRETER "/lib/ld.so.1"
+
+#define DEFAULT_STACK_SIZE 0x20000
+
+/* This structure is used to collect the number of entries present in
+ each addressable range of the got. */
+struct _frvfdpic_dynamic_got_info
+{
+ /* Several bits of information about the current link. */
+ struct bfd_link_info *info;
+ /* Total GOT size needed for GOT entries within the 12-, 16- or 32-bit
+ ranges. */
+ bfd_vma got12, gotlos, gothilo;
+ /* Total GOT size needed for function descriptor entries within the 12-,
+ 16- or 32-bit ranges. */
+ bfd_vma fd12, fdlos, fdhilo;
+ /* Total GOT size needed by function descriptor entries referenced
+ in PLT entries, that would be profitable to place in offsets
+ close to the PIC register. */
+ bfd_vma fdplt;
+ /* Total PLT size needed by lazy PLT entries. */
+ bfd_vma lzplt;
+ /* Total GOT size needed for TLS descriptor entries within the 12-,
+ 16- or 32-bit ranges. */
+ bfd_vma tlsd12, tlsdlos, tlsdhilo;
+ /* Total GOT size needed by TLS descriptors referenced in PLT
+ entries, that would be profitable to place in offers close to the
+ PIC register. */
+ bfd_vma tlsdplt;
+ /* Total PLT size needed by TLS lazy PLT entries. */
+ bfd_vma tlslzplt;
+ /* Number of relocations carried over from input object files. */
+ unsigned long relocs;
+ /* Number of fixups introduced by relocations in input object files. */
+ unsigned long fixups;
+ /* The number of fixups that reference the ret instruction added to
+ the PLT for locally-resolved TLS descriptors. */
+ unsigned long tls_ret_refs;
+};
+
+/* This structure is used to assign offsets to got entries, function
+ descriptors, plt entries and lazy plt entries. */
+
+struct _frvfdpic_dynamic_got_plt_info
+{
+ /* Summary information collected with _frvfdpic_count_got_plt_entries. */
+ struct _frvfdpic_dynamic_got_info g;
+
+ /* For each addressable range, we record a MAX (positive) and MIN
+ (negative) value. CUR is used to assign got entries, and it's
+ incremented from an initial positive value to MAX, then from MIN
+ to FDCUR (unless FDCUR wraps around first). FDCUR is used to
+ assign function descriptors, and it's decreased from an initial
+ non-positive value to MIN, then from MAX down to CUR (unless CUR
+ wraps around first). All of MIN, MAX, CUR and FDCUR always point
+ to even words. ODD, if non-zero, indicates an odd word to be
+ used for the next got entry, otherwise CUR is used and
+ incremented by a pair of words, wrapping around when it reaches
+ MAX. FDCUR is decremented (and wrapped) before the next function
+ descriptor is chosen. FDPLT indicates the number of remaining
+ slots that can be used for function descriptors used only by PLT
+ entries.
+
+ TMAX, TMIN and TCUR are used to assign TLS descriptors. TCUR
+ starts as MAX, and grows up to TMAX, then wraps around to TMIN
+ and grows up to MIN. TLSDPLT indicates the number of remaining
+ slots that can be used for TLS descriptors used only by TLS PLT
+ entries. */
+ struct _frvfdpic_dynamic_got_alloc_data
+ {
+ bfd_signed_vma max, cur, odd, fdcur, min;
+ bfd_signed_vma tmax, tcur, tmin;
+ bfd_vma fdplt, tlsdplt;
+ } got12, gotlos, gothilo;
+};
+
+/* Create an FRV ELF linker hash table. */
+
+static struct bfd_link_hash_table *
+frvfdpic_elf_link_hash_table_create (bfd *abfd)
+{
+ struct frvfdpic_elf_link_hash_table *ret;
+ bfd_size_type amt = sizeof (struct frvfdpic_elf_link_hash_table);
+
+ ret = bfd_zmalloc (amt);
+ if (ret == NULL)
+ return NULL;
+
+ if (!_bfd_elf_link_hash_table_init (&ret->elf, abfd,
+ _bfd_elf_link_hash_newfunc,
+ sizeof (struct elf_link_hash_entry),
+ FRV_ELF_DATA))
+ {
+ free (ret);
+ return NULL;
+ }
+
+ return &ret->elf.root;
+}
+
+/* Decide whether a reference to a symbol can be resolved locally or
+ not. If the symbol is protected, we want the local address, but
+ its function descriptor must be assigned by the dynamic linker. */
+#define FRVFDPIC_SYM_LOCAL(INFO, H) \
+ (_bfd_elf_symbol_refs_local_p ((H), (INFO), 1) \
+ || ! elf_hash_table (INFO)->dynamic_sections_created)
+#define FRVFDPIC_FUNCDESC_LOCAL(INFO, H) \
+ ((H)->dynindx == -1 || ! elf_hash_table (INFO)->dynamic_sections_created)
+
+/* This structure collects information on what kind of GOT, PLT or
+ function descriptors are required by relocations that reference a
+ certain symbol. */
+struct frvfdpic_relocs_info
+{
+ /* The index of the symbol, as stored in the relocation r_info, if
+ we have a local symbol; -1 otherwise. */
+ long symndx;
+ union
+ {
+ /* The input bfd in which the symbol is defined, if it's a local
+ symbol. */
+ bfd *abfd;
+ /* If symndx == -1, the hash table entry corresponding to a global
+ symbol (even if it turns out to bind locally, in which case it
+ should ideally be replaced with section's symndx + addend). */
+ struct elf_link_hash_entry *h;
+ } d;
+ /* The addend of the relocation that references the symbol. */
+ bfd_vma addend;
+
+ /* The fields above are used to identify an entry. The fields below
+ contain information on how an entry is used and, later on, which
+ locations it was assigned. */
+ /* The following 3 fields record whether the symbol+addend above was
+ ever referenced with a GOT relocation. The 12 suffix indicates a
+ GOT12 relocation; los is used for GOTLO relocations that are not
+ matched by a GOTHI relocation; hilo is used for GOTLO/GOTHI
+ pairs. */
+ unsigned got12:1;
+ unsigned gotlos:1;
+ unsigned gothilo:1;
+ /* Whether a FUNCDESC relocation references symbol+addend. */
+ unsigned fd:1;
+ /* Whether a FUNCDESC_GOT relocation references symbol+addend. */
+ unsigned fdgot12:1;
+ unsigned fdgotlos:1;
+ unsigned fdgothilo:1;
+ /* Whether a FUNCDESC_GOTOFF relocation references symbol+addend. */
+ unsigned fdgoff12:1;
+ unsigned fdgofflos:1;
+ unsigned fdgoffhilo:1;
+ /* Whether a GETTLSOFF relocation references symbol+addend. */
+ unsigned tlsplt:1;
+ /* FIXME: we should probably add tlspltdesc, tlspltoff and
+ tlspltimm, to tell what kind of TLS PLT entry we're generating.
+ We might instead just pre-compute flags telling whether the
+ object is suitable for local exec, initial exec or general
+ dynamic addressing, and use that all over the place. We could
+ also try to do a better job of merging TLSOFF and TLSDESC entries
+ in main executables, but perhaps we can get rid of TLSDESC
+ entirely in them instead. */
+ /* Whether a GOTTLSDESC relocation references symbol+addend. */
+ unsigned tlsdesc12:1;
+ unsigned tlsdesclos:1;
+ unsigned tlsdeschilo:1;
+ /* Whether a GOTTLSOFF relocation references symbol+addend. */
+ unsigned tlsoff12:1;
+ unsigned tlsofflos:1;
+ unsigned tlsoffhilo:1;
+ /* Whether symbol+addend is referenced with GOTOFF12, GOTOFFLO or
+ GOTOFFHI relocations. The addend doesn't really matter, since we
+ envision that this will only be used to check whether the symbol
+ is mapped to the same segment as the got. */
+ unsigned gotoff:1;
+ /* Whether symbol+addend is referenced by a LABEL24 relocation. */
+ unsigned call:1;
+ /* Whether symbol+addend is referenced by a 32 or FUNCDESC_VALUE
+ relocation. */
+ unsigned sym:1;
+ /* Whether we need a PLT entry for a symbol. Should be implied by
+ something like:
+ (call && symndx == -1 && ! FRVFDPIC_SYM_LOCAL (info, d.h)) */
+ unsigned plt:1;
+ /* Whether a function descriptor should be created in this link unit
+ for symbol+addend. Should be implied by something like:
+ (plt || fdgotoff12 || fdgotofflos || fdgotofflohi
+ || ((fd || fdgot12 || fdgotlos || fdgothilo)
+ && (symndx != -1 || FRVFDPIC_FUNCDESC_LOCAL (info, d.h)))) */
+ unsigned privfd:1;
+ /* Whether a lazy PLT entry is needed for this symbol+addend.
+ Should be implied by something like:
+ (privfd && symndx == -1 && ! FRVFDPIC_SYM_LOCAL (info, d.h)
+ && ! (info->flags & DF_BIND_NOW)) */
+ unsigned lazyplt:1;
+ /* Whether we've already emitted GOT relocations and PLT entries as
+ needed for this symbol. */
+ unsigned done:1;
+
+ /* The number of R_FRV_32, R_FRV_FUNCDESC, R_FRV_FUNCDESC_VALUE and
+ R_FRV_TLSDESC_VALUE, R_FRV_TLSOFF relocations referencing
+ symbol+addend. */
+ unsigned relocs32, relocsfd, relocsfdv, relocstlsd, relocstlsoff;
+
+ /* The number of .rofixups entries and dynamic relocations allocated
+ for this symbol, minus any that might have already been used. */
+ unsigned fixups, dynrelocs;
+
+ /* The offsets of the GOT entries assigned to symbol+addend, to the
+ function descriptor's address, and to a function descriptor,
+ respectively. Should be zero if unassigned. The offsets are
+ counted from the value that will be assigned to the PIC register,
+ not from the beginning of the .got section. */
+ bfd_signed_vma got_entry, fdgot_entry, fd_entry;
+ /* The offsets of the PLT entries assigned to symbol+addend,
+ non-lazy and lazy, respectively. If unassigned, should be
+ (bfd_vma)-1. */
+ bfd_vma plt_entry, lzplt_entry;
+ /* The offsets of the GOT entries for TLS offset and TLS descriptor. */
+ bfd_signed_vma tlsoff_entry, tlsdesc_entry;
+ /* The offset of the TLS offset PLT entry. */
+ bfd_vma tlsplt_entry;
+};
+
+/* Compute a hash with the key fields of an frvfdpic_relocs_info entry. */
+static hashval_t
+frvfdpic_relocs_info_hash (const void *entry_)
+{
+ const struct frvfdpic_relocs_info *entry = entry_;
+
+ return (entry->symndx == -1
+ ? (long) entry->d.h->root.root.hash
+ : entry->symndx + (long) entry->d.abfd->id * 257) + entry->addend;
+}
+
+/* Test whether the key fields of two frvfdpic_relocs_info entries are
+ identical. */
+static int
+frvfdpic_relocs_info_eq (const void *entry1, const void *entry2)
+{
+ const struct frvfdpic_relocs_info *e1 = entry1;
+ const struct frvfdpic_relocs_info *e2 = entry2;
+
+ return e1->symndx == e2->symndx && e1->addend == e2->addend
+ && (e1->symndx == -1 ? e1->d.h == e2->d.h : e1->d.abfd == e2->d.abfd);
+}
+
+/* Find or create an entry in a hash table HT that matches the key
+ fields of the given ENTRY. If it's not found, memory for a new
+ entry is allocated in ABFD's obstack. */
+static struct frvfdpic_relocs_info *
+frvfdpic_relocs_info_find (struct htab *ht,
+ bfd *abfd,
+ const struct frvfdpic_relocs_info *entry,
+ enum insert_option insert)
+{
+ struct frvfdpic_relocs_info **loc =
+ (struct frvfdpic_relocs_info **) htab_find_slot (ht, entry, insert);
+
+ if (! loc)
+ return NULL;
+
+ if (*loc)
+ return *loc;
+
+ *loc = bfd_zalloc (abfd, sizeof (**loc));
+
+ if (! *loc)
+ return *loc;
+
+ (*loc)->symndx = entry->symndx;
+ (*loc)->d = entry->d;
+ (*loc)->addend = entry->addend;
+ (*loc)->plt_entry = (bfd_vma)-1;
+ (*loc)->lzplt_entry = (bfd_vma)-1;
+ (*loc)->tlsplt_entry = (bfd_vma)-1;
+
+ return *loc;
+}
+
+/* Obtain the address of the entry in HT associated with H's symbol +
+ addend, creating a new entry if none existed. ABFD is only used
+ for memory allocation purposes. */
+inline static struct frvfdpic_relocs_info *
+frvfdpic_relocs_info_for_global (struct htab *ht,
+ bfd *abfd,
+ struct elf_link_hash_entry *h,
+ bfd_vma addend,
+ enum insert_option insert)
+{
+ struct frvfdpic_relocs_info entry;
+
+ entry.symndx = -1;
+ entry.d.h = h;
+ entry.addend = addend;
+
+ return frvfdpic_relocs_info_find (ht, abfd, &entry, insert);
+}
+
+/* Obtain the address of the entry in HT associated with the SYMNDXth
+ local symbol of the input bfd ABFD, plus the addend, creating a new
+ entry if none existed. */
+inline static struct frvfdpic_relocs_info *
+frvfdpic_relocs_info_for_local (struct htab *ht,
+ bfd *abfd,
+ long symndx,
+ bfd_vma addend,
+ enum insert_option insert)
+{
+ struct frvfdpic_relocs_info entry;
+
+ entry.symndx = symndx;
+ entry.d.abfd = abfd;
+ entry.addend = addend;
+
+ return frvfdpic_relocs_info_find (ht, abfd, &entry, insert);
+}
+
+/* Merge fields set by check_relocs() of two entries that end up being
+ mapped to the same (presumably global) symbol. */
+
+inline static void
+frvfdpic_pic_merge_early_relocs_info (struct frvfdpic_relocs_info *e2,
+ struct frvfdpic_relocs_info const *e1)
+{
+ e2->got12 |= e1->got12;
+ e2->gotlos |= e1->gotlos;
+ e2->gothilo |= e1->gothilo;
+ e2->fd |= e1->fd;
+ e2->fdgot12 |= e1->fdgot12;
+ e2->fdgotlos |= e1->fdgotlos;
+ e2->fdgothilo |= e1->fdgothilo;
+ e2->fdgoff12 |= e1->fdgoff12;
+ e2->fdgofflos |= e1->fdgofflos;
+ e2->fdgoffhilo |= e1->fdgoffhilo;
+ e2->tlsplt |= e1->tlsplt;
+ e2->tlsdesc12 |= e1->tlsdesc12;
+ e2->tlsdesclos |= e1->tlsdesclos;
+ e2->tlsdeschilo |= e1->tlsdeschilo;
+ e2->tlsoff12 |= e1->tlsoff12;
+ e2->tlsofflos |= e1->tlsofflos;
+ e2->tlsoffhilo |= e1->tlsoffhilo;
+ e2->gotoff |= e1->gotoff;
+ e2->call |= e1->call;
+ e2->sym |= e1->sym;
+}
+
+/* Every block of 65535 lazy PLT entries shares a single call to the
+ resolver, inserted in the 32768th lazy PLT entry (i.e., entry #
+ 32767, counting from 0). All other lazy PLT entries branch to it
+ in a single instruction. */
+
+#define FRVFDPIC_LZPLT_BLOCK_SIZE ((bfd_vma) 8 * 65535 + 4)
+#define FRVFDPIC_LZPLT_RESOLV_LOC (8 * 32767)
+
+/* Add a dynamic relocation to the SRELOC section. */
+
+inline static bfd_vma
+_frvfdpic_add_dyn_reloc (bfd *output_bfd, asection *sreloc, bfd_vma offset,
+ int reloc_type, long dynindx, bfd_vma addend,
+ struct frvfdpic_relocs_info *entry)
+{
+ Elf_Internal_Rela outrel;
+ bfd_vma reloc_offset;
+
+ outrel.r_offset = offset;
+ outrel.r_info = ELF32_R_INFO (dynindx, reloc_type);
+ outrel.r_addend = addend;
+
+ reloc_offset = sreloc->reloc_count * sizeof (Elf32_External_Rel);
+ BFD_ASSERT (reloc_offset < sreloc->size);
+ bfd_elf32_swap_reloc_out (output_bfd, &outrel,
+ sreloc->contents + reloc_offset);
+ sreloc->reloc_count++;
+
+ /* If the entry's index is zero, this relocation was probably to a
+ linkonce section that got discarded. We reserved a dynamic
+ relocation, but it was for another entry than the one we got at
+ the time of emitting the relocation. Unfortunately there's no
+ simple way for us to catch this situation, since the relocation
+ is cleared right before calling relocate_section, at which point
+ we no longer know what the relocation used to point to. */
+ if (entry->symndx)
+ {
+ BFD_ASSERT (entry->dynrelocs > 0);
+ entry->dynrelocs--;
+ }
+
+ return reloc_offset;
+}
+
+/* Add a fixup to the ROFIXUP section. */
+
+static bfd_vma
+_frvfdpic_add_rofixup (bfd *output_bfd, asection *rofixup, bfd_vma offset,
+ struct frvfdpic_relocs_info *entry)
+{
+ bfd_vma fixup_offset;
+
+ if (rofixup->flags & SEC_EXCLUDE)
+ return -1;
+
+ fixup_offset = rofixup->reloc_count * 4;
+ if (rofixup->contents)
+ {
+ BFD_ASSERT (fixup_offset < rofixup->size);
+ bfd_put_32 (output_bfd, offset, rofixup->contents + fixup_offset);
+ }
+ rofixup->reloc_count++;
+
+ if (entry && entry->symndx)
+ {
+ /* See discussion about symndx == 0 in _frvfdpic_add_dyn_reloc
+ above. */
+ BFD_ASSERT (entry->fixups > 0);
+ entry->fixups--;
+ }
+
+ return fixup_offset;
+}
+
+/* Find the segment number in which OSEC, and output section, is
+ located. */
+
+static unsigned
+_frvfdpic_osec_to_segment (bfd *output_bfd, asection *osec)
+{
+ Elf_Internal_Phdr *p = _bfd_elf_find_segment_containing_section (output_bfd, osec);
+
+ return (p != NULL) ? p - elf_tdata (output_bfd)->phdr : -1;
+}
+
+inline static bfd_boolean
+_frvfdpic_osec_readonly_p (bfd *output_bfd, asection *osec)
+{
+ unsigned seg = _frvfdpic_osec_to_segment (output_bfd, osec);
+
+ return ! (elf_tdata (output_bfd)->phdr[seg].p_flags & PF_W);
+}
+
+#define FRVFDPIC_TLS_BIAS (2048 - 16)
+
+/* Return the base VMA address which should be subtracted from real addresses
+ when resolving TLSMOFF relocation.
+ This is PT_TLS segment p_vaddr, plus the 2048-16 bias. */
+
+static bfd_vma
+tls_biased_base (struct bfd_link_info *info)
+{
+ /* If tls_sec is NULL, we should have signalled an error already. */
+ if (elf_hash_table (info)->tls_sec == NULL)
+ return FRVFDPIC_TLS_BIAS;
+ return elf_hash_table (info)->tls_sec->vma + FRVFDPIC_TLS_BIAS;
+}
+
+/* Generate relocations for GOT entries, function descriptors, and
+ code for PLT and lazy PLT entries. */
+
+inline static bfd_boolean
+_frvfdpic_emit_got_relocs_plt_entries (struct frvfdpic_relocs_info *entry,
+ bfd *output_bfd,
+ struct bfd_link_info *info,
+ asection *sec,
+ Elf_Internal_Sym *sym,
+ bfd_vma addend)
+
+{
+ bfd_vma fd_lazy_rel_offset = (bfd_vma)-1;
+ int dynindx = -1;
+
+ if (entry->done)
+ return TRUE;
+ entry->done = 1;
+
+ if (entry->got_entry || entry->fdgot_entry || entry->fd_entry
+ || entry->tlsoff_entry || entry->tlsdesc_entry)
+ {
+ /* If the symbol is dynamic, consider it for dynamic
+ relocations, otherwise decay to section + offset. */
+ if (entry->symndx == -1 && entry->d.h->dynindx != -1)
+ dynindx = entry->d.h->dynindx;
+ else
+ {
+ if (sec
+ && sec->output_section
+ && ! bfd_is_abs_section (sec->output_section)
+ && ! bfd_is_und_section (sec->output_section))
+ dynindx = elf_section_data (sec->output_section)->dynindx;
+ else
+ dynindx = 0;
+ }
+ }
+
+ /* Generate relocation for GOT entry pointing to the symbol. */
+ if (entry->got_entry)
+ {
+ int idx = dynindx;
+ bfd_vma ad = addend;
+
+ /* If the symbol is dynamic but binds locally, use
+ section+offset. */
+ if (sec && (entry->symndx != -1
+ || FRVFDPIC_SYM_LOCAL (info, entry->d.h)))
+ {
+ if (entry->symndx == -1)
+ ad += entry->d.h->root.u.def.value;
+ else
+ ad += sym->st_value;
+ ad += sec->output_offset;
+ if (sec->output_section && elf_section_data (sec->output_section))
+ idx = elf_section_data (sec->output_section)->dynindx;
+ else
+ idx = 0;
+ }
+
+ /* If we're linking an executable at a fixed address, we can
+ omit the dynamic relocation as long as the symbol is local to
+ this module. */
+ if (info->executable && !info->pie
+ && (entry->symndx != -1
+ || FRVFDPIC_SYM_LOCAL (info, entry->d.h)))
+ {
+ if (sec)
+ ad += sec->output_section->vma;
+ if (entry->symndx != -1
+ || entry->d.h->root.type != bfd_link_hash_undefweak)
+ _frvfdpic_add_rofixup (output_bfd,
+ frvfdpic_gotfixup_section (info),
+ frvfdpic_got_section (info)->output_section
+ ->vma
+ + frvfdpic_got_section (info)->output_offset
+ + frvfdpic_got_initial_offset (info)
+ + entry->got_entry, entry);
+ }
+ else
+ _frvfdpic_add_dyn_reloc (output_bfd, frvfdpic_gotrel_section (info),
+ _bfd_elf_section_offset
+ (output_bfd, info,
+ frvfdpic_got_section (info),
+ frvfdpic_got_initial_offset (info)
+ + entry->got_entry)
+ + frvfdpic_got_section (info)
+ ->output_section->vma
+ + frvfdpic_got_section (info)->output_offset,
+ R_FRV_32, idx, ad, entry);
+
+ bfd_put_32 (output_bfd, ad,
+ frvfdpic_got_section (info)->contents
+ + frvfdpic_got_initial_offset (info)
+ + entry->got_entry);
+ }
+
+ /* Generate relocation for GOT entry pointing to a canonical
+ function descriptor. */
+ if (entry->fdgot_entry)
+ {
+ int reloc, idx;
+ bfd_vma ad = 0;
+
+ if (! (entry->symndx == -1
+ && entry->d.h->root.type == bfd_link_hash_undefweak
+ && FRVFDPIC_SYM_LOCAL (info, entry->d.h)))
+ {
+ /* If the symbol is dynamic and there may be dynamic symbol
+ resolution because we are, or are linked with, a shared
+ library, emit a FUNCDESC relocation such that the dynamic
+ linker will allocate the function descriptor. If the
+ symbol needs a non-local function descriptor but binds
+ locally (e.g., its visibility is protected, emit a
+ dynamic relocation decayed to section+offset. */
+ if (entry->symndx == -1
+ && ! FRVFDPIC_FUNCDESC_LOCAL (info, entry->d.h)
+ && FRVFDPIC_SYM_LOCAL (info, entry->d.h)
+ && !(info->executable && !info->pie))
+ {
+ reloc = R_FRV_FUNCDESC;
+ idx = elf_section_data (entry->d.h->root.u.def.section
+ ->output_section)->dynindx;
+ ad = entry->d.h->root.u.def.section->output_offset
+ + entry->d.h->root.u.def.value;
+ }
+ else if (entry->symndx == -1
+ && ! FRVFDPIC_FUNCDESC_LOCAL (info, entry->d.h))
+ {
+ reloc = R_FRV_FUNCDESC;
+ idx = dynindx;
+ ad = addend;
+ if (ad)
+ {
+ (*info->callbacks->reloc_dangerous)
+ (info, _("relocation requires zero addend"),
+ elf_hash_table (info)->dynobj,
+ frvfdpic_got_section (info),
+ entry->fdgot_entry);
+ return FALSE;
+ }
+ }
+ else
+ {
+ /* Otherwise, we know we have a private function descriptor,
+ so reference it directly. */
+ if (elf_hash_table (info)->dynamic_sections_created)
+ BFD_ASSERT (entry->privfd);
+ reloc = R_FRV_32;
+ idx = elf_section_data (frvfdpic_got_section (info)
+ ->output_section)->dynindx;
+ ad = frvfdpic_got_section (info)->output_offset
+ + frvfdpic_got_initial_offset (info) + entry->fd_entry;
+ }
+
+ /* If there is room for dynamic symbol resolution, emit the
+ dynamic relocation. However, if we're linking an
+ executable at a fixed location, we won't have emitted a
+ dynamic symbol entry for the got section, so idx will be
+ zero, which means we can and should compute the address
+ of the private descriptor ourselves. */
+ if (info->executable && !info->pie
+ && (entry->symndx != -1
+ || FRVFDPIC_FUNCDESC_LOCAL (info, entry->d.h)))
+ {
+ ad += frvfdpic_got_section (info)->output_section->vma;
+ _frvfdpic_add_rofixup (output_bfd,
+ frvfdpic_gotfixup_section (info),
+ frvfdpic_got_section (info)
+ ->output_section->vma
+ + frvfdpic_got_section (info)
+ ->output_offset
+ + frvfdpic_got_initial_offset (info)
+ + entry->fdgot_entry, entry);
+ }
+ else
+ _frvfdpic_add_dyn_reloc (output_bfd,
+ frvfdpic_gotrel_section (info),
+ _bfd_elf_section_offset
+ (output_bfd, info,
+ frvfdpic_got_section (info),
+ frvfdpic_got_initial_offset (info)
+ + entry->fdgot_entry)
+ + frvfdpic_got_section (info)
+ ->output_section->vma
+ + frvfdpic_got_section (info)
+ ->output_offset,
+ reloc, idx, ad, entry);
+ }
+
+ bfd_put_32 (output_bfd, ad,
+ frvfdpic_got_section (info)->contents
+ + frvfdpic_got_initial_offset (info)
+ + entry->fdgot_entry);
+ }
+
+ /* Generate relocation to fill in a private function descriptor in
+ the GOT. */
+ if (entry->fd_entry)
+ {
+ int idx = dynindx;
+ bfd_vma ad = addend;
+ bfd_vma ofst;
+ long lowword, highword;
+
+ /* If the symbol is dynamic but binds locally, use
+ section+offset. */
+ if (sec && (entry->symndx != -1
+ || FRVFDPIC_SYM_LOCAL (info, entry->d.h)))
+ {
+ if (entry->symndx == -1)
+ ad += entry->d.h->root.u.def.value;
+ else
+ ad += sym->st_value;
+ ad += sec->output_offset;
+ if (sec->output_section && elf_section_data (sec->output_section))
+ idx = elf_section_data (sec->output_section)->dynindx;
+ else
+ idx = 0;
+ }
+
+ /* If we're linking an executable at a fixed address, we can
+ omit the dynamic relocation as long as the symbol is local to
+ this module. */
+ if (info->executable && !info->pie
+ && (entry->symndx != -1 || FRVFDPIC_SYM_LOCAL (info, entry->d.h)))
+ {
+ if (sec)
+ ad += sec->output_section->vma;
+ ofst = 0;
+ if (entry->symndx != -1
+ || entry->d.h->root.type != bfd_link_hash_undefweak)
+ {
+ _frvfdpic_add_rofixup (output_bfd,
+ frvfdpic_gotfixup_section (info),
+ frvfdpic_got_section (info)
+ ->output_section->vma
+ + frvfdpic_got_section (info)
+ ->output_offset
+ + frvfdpic_got_initial_offset (info)
+ + entry->fd_entry, entry);
+ _frvfdpic_add_rofixup (output_bfd,
+ frvfdpic_gotfixup_section (info),
+ frvfdpic_got_section (info)
+ ->output_section->vma
+ + frvfdpic_got_section (info)
+ ->output_offset
+ + frvfdpic_got_initial_offset (info)
+ + entry->fd_entry + 4, entry);
+ }
+ }
+ else
+ {
+ ofst =
+ _frvfdpic_add_dyn_reloc (output_bfd,
+ entry->lazyplt
+ ? frvfdpic_pltrel_section (info)
+ : frvfdpic_gotrel_section (info),
+ _bfd_elf_section_offset
+ (output_bfd, info,
+ frvfdpic_got_section (info),
+ frvfdpic_got_initial_offset (info)
+ + entry->fd_entry)
+ + frvfdpic_got_section (info)
+ ->output_section->vma
+ + frvfdpic_got_section (info)
+ ->output_offset,
+ R_FRV_FUNCDESC_VALUE, idx, ad, entry);
+ }
+
+ /* If we've omitted the dynamic relocation, just emit the fixed
+ addresses of the symbol and of the local GOT base offset. */
+ if (info->executable && !info->pie && sec && sec->output_section)
+ {
+ lowword = ad;
+ highword = frvfdpic_got_section (info)->output_section->vma
+ + frvfdpic_got_section (info)->output_offset
+ + frvfdpic_got_initial_offset (info);
+ }
+ else if (entry->lazyplt)
+ {
+ if (ad)
+ {
+ (*info->callbacks->reloc_dangerous)
+ (info, _("relocation requires zero addend"),
+ elf_hash_table (info)->dynobj,
+ frvfdpic_got_section (info),
+ entry->fd_entry);
+ return FALSE;
+ }
+
+ fd_lazy_rel_offset = ofst;
+
+ /* A function descriptor used for lazy or local resolving is
+ initialized such that its high word contains the output
+ section index in which the PLT entries are located, and
+ the low word contains the address of the lazy PLT entry
+ entry point, that must be within the memory region
+ assigned to that section. */
+ lowword = entry->lzplt_entry + 4
+ + frvfdpic_plt_section (info)->output_offset
+ + frvfdpic_plt_section (info)->output_section->vma;
+ highword = _frvfdpic_osec_to_segment
+ (output_bfd, frvfdpic_plt_section (info)->output_section);
+ }
+ else
+ {
+ /* A function descriptor for a local function gets the index
+ of the section. For a non-local function, it's
+ disregarded. */
+ lowword = ad;
+ if (sec == NULL
+ || (entry->symndx == -1 && entry->d.h->dynindx != -1
+ && entry->d.h->dynindx == idx))
+ highword = 0;
+ else
+ highword = _frvfdpic_osec_to_segment
+ (output_bfd, sec->output_section);
+ }
+
+ bfd_put_32 (output_bfd, lowword,
+ frvfdpic_got_section (info)->contents
+ + frvfdpic_got_initial_offset (info)
+ + entry->fd_entry);
+ bfd_put_32 (output_bfd, highword,
+ frvfdpic_got_section (info)->contents
+ + frvfdpic_got_initial_offset (info)
+ + entry->fd_entry + 4);
+ }
+
+ /* Generate code for the PLT entry. */
+ if (entry->plt_entry != (bfd_vma) -1)
+ {
+ bfd_byte *plt_code = frvfdpic_plt_section (info)->contents
+ + entry->plt_entry;
+
+ BFD_ASSERT (entry->fd_entry);
+
+ /* Figure out what kind of PLT entry we need, depending on the
+ location of the function descriptor within the GOT. */
+ if (entry->fd_entry >= -(1 << (12 - 1))
+ && entry->fd_entry < (1 << (12 - 1)))
+ {
+ /* lddi @(gr15, fd_entry), gr14 */
+ bfd_put_32 (output_bfd,
+ 0x9cccf000 | (entry->fd_entry & ((1 << 12) - 1)),
+ plt_code);
+ plt_code += 4;
+ }
+ else
+ {
+ if (entry->fd_entry >= -(1 << (16 - 1))
+ && entry->fd_entry < (1 << (16 - 1)))
+ {
+ /* setlos lo(fd_entry), gr14 */
+ bfd_put_32 (output_bfd,
+ 0x9cfc0000
+ | (entry->fd_entry & (((bfd_vma)1 << 16) - 1)),
+ plt_code);
+ plt_code += 4;
+ }
+ else
+ {
+ /* sethi.p hi(fd_entry), gr14
+ setlo lo(fd_entry), gr14 */
+ bfd_put_32 (output_bfd,
+ 0x1cf80000
+ | ((entry->fd_entry >> 16)
+ & (((bfd_vma)1 << 16) - 1)),
+ plt_code);
+ plt_code += 4;
+ bfd_put_32 (output_bfd,
+ 0x9cf40000
+ | (entry->fd_entry & (((bfd_vma)1 << 16) - 1)),
+ plt_code);
+ plt_code += 4;
+ }
+ /* ldd @(gr14,gr15),gr14 */
+ bfd_put_32 (output_bfd, 0x9c08e14f, plt_code);
+ plt_code += 4;
+ }
+ /* jmpl @(gr14,gr0) */
+ bfd_put_32 (output_bfd, 0x8030e000, plt_code);
+ }
+
+ /* Generate code for the lazy PLT entry. */
+ if (entry->lzplt_entry != (bfd_vma) -1)
+ {
+ bfd_byte *lzplt_code = frvfdpic_plt_section (info)->contents
+ + entry->lzplt_entry;
+ bfd_vma resolverStub_addr;
+
+ bfd_put_32 (output_bfd, fd_lazy_rel_offset, lzplt_code);
+ lzplt_code += 4;
+
+ resolverStub_addr = entry->lzplt_entry / FRVFDPIC_LZPLT_BLOCK_SIZE
+ * FRVFDPIC_LZPLT_BLOCK_SIZE + FRVFDPIC_LZPLT_RESOLV_LOC;
+ if (resolverStub_addr >= frvfdpic_plt_initial_offset (info))
+ resolverStub_addr = frvfdpic_plt_initial_offset (info) - 12;
+
+ if (entry->lzplt_entry == resolverStub_addr)
+ {
+ /* This is a lazy PLT entry that includes a resolver call. */
+ /* ldd @(gr15,gr0), gr4
+ jmpl @(gr4,gr0) */
+ bfd_put_32 (output_bfd, 0x8808f140, lzplt_code);
+ bfd_put_32 (output_bfd, 0x80304000, lzplt_code + 4);
+ }
+ else
+ {
+ /* bra resolverStub */
+ bfd_put_32 (output_bfd,
+ 0xc01a0000
+ | (((resolverStub_addr - entry->lzplt_entry)
+ / 4) & (((bfd_vma)1 << 16) - 1)),
+ lzplt_code);
+ }
+ }
+
+ /* Generate relocation for GOT entry holding the TLS offset. */
+ if (entry->tlsoff_entry)
+ {
+ int idx = dynindx;
+ bfd_vma ad = addend;
+
+ if (entry->symndx != -1
+ || FRVFDPIC_SYM_LOCAL (info, entry->d.h))
+ {
+ /* If the symbol is dynamic but binds locally, use
+ section+offset. */
+ if (sec)
+ {
+ if (entry->symndx == -1)
+ ad += entry->d.h->root.u.def.value;
+ else
+ ad += sym->st_value;
+ ad += sec->output_offset;
+ if (sec->output_section
+ && elf_section_data (sec->output_section))
+ idx = elf_section_data (sec->output_section)->dynindx;
+ else
+ idx = 0;
+ }
+ }
+
+ /* *ABS*+addend is special for TLS relocations, use only the
+ addend. */
+ if (info->executable
+ && idx == 0
+ && (bfd_is_abs_section (sec)
+ || bfd_is_und_section (sec)))
+ ;
+ /* If we're linking an executable, we can entirely omit the
+ dynamic relocation if the symbol is local to this module. */
+ else if (info->executable
+ && (entry->symndx != -1
+ || FRVFDPIC_SYM_LOCAL (info, entry->d.h)))
+ {
+ if (sec)
+ ad += sec->output_section->vma - tls_biased_base (info);
+ }
+ else
+ {
+ if (idx == 0
+ && (bfd_is_abs_section (sec)
+ || bfd_is_und_section (sec)))
+ {
+ if (! elf_hash_table (info)->tls_sec)
+ {
+ (*info->callbacks->undefined_symbol)
+ (info, "TLS section", elf_hash_table (info)->dynobj,
+ frvfdpic_got_section (info), entry->tlsoff_entry, TRUE);
+ return FALSE;
+ }
+ idx = elf_section_data (elf_hash_table (info)->tls_sec)->dynindx;
+ ad += FRVFDPIC_TLS_BIAS;
+ }
+ _frvfdpic_add_dyn_reloc (output_bfd, frvfdpic_gotrel_section (info),
+ _bfd_elf_section_offset
+ (output_bfd, info,
+ frvfdpic_got_section (info),
+ frvfdpic_got_initial_offset (info)
+ + entry->tlsoff_entry)
+ + frvfdpic_got_section (info)
+ ->output_section->vma
+ + frvfdpic_got_section (info)
+ ->output_offset,
+ R_FRV_TLSOFF, idx, ad, entry);
+ }
+
+ bfd_put_32 (output_bfd, ad,
+ frvfdpic_got_section (info)->contents
+ + frvfdpic_got_initial_offset (info)
+ + entry->tlsoff_entry);
+ }
+
+ if (entry->tlsdesc_entry)
+ {
+ int idx = dynindx;
+ bfd_vma ad = addend;
+
+ /* If the symbol is dynamic but binds locally, use
+ section+offset. */
+ if (sec && (entry->symndx != -1
+ || FRVFDPIC_SYM_LOCAL (info, entry->d.h)))
+ {
+ if (entry->symndx == -1)
+ ad += entry->d.h->root.u.def.value;
+ else
+ ad += sym->st_value;
+ ad += sec->output_offset;
+ if (sec->output_section && elf_section_data (sec->output_section))
+ idx = elf_section_data (sec->output_section)->dynindx;
+ else
+ idx = 0;
+ }
+
+ /* If we didn't set up a TLS offset entry, but we're linking an
+ executable and the symbol binds locally, we can use the
+ module offset in the TLS descriptor in relaxations. */
+ if (info->executable && ! entry->tlsoff_entry)
+ entry->tlsoff_entry = entry->tlsdesc_entry + 4;
+
+ if (info->executable && !info->pie
+ && ((idx == 0
+ && (bfd_is_abs_section (sec)
+ || bfd_is_und_section (sec)))
+ || entry->symndx != -1
+ || FRVFDPIC_SYM_LOCAL (info, entry->d.h)))
+ {
+ /* *ABS*+addend is special for TLS relocations, use only the
+ addend for the TLS offset, and take the module id as
+ 0. */
+ if (idx == 0
+ && (bfd_is_abs_section (sec)
+ || bfd_is_und_section (sec)))
+ ;
+ /* For other TLS symbols that bind locally, add the section
+ TLS offset to the addend. */
+ else if (sec)
+ ad += sec->output_section->vma - tls_biased_base (info);
+
+ bfd_put_32 (output_bfd,
+ frvfdpic_plt_section (info)->output_section->vma
+ + frvfdpic_plt_section (info)->output_offset
+ + frvfdpic_plt_tls_ret_offset (info),
+ frvfdpic_got_section (info)->contents
+ + frvfdpic_got_initial_offset (info)
+ + entry->tlsdesc_entry);
+
+ _frvfdpic_add_rofixup (output_bfd,
+ frvfdpic_gotfixup_section (info),
+ frvfdpic_got_section (info)
+ ->output_section->vma
+ + frvfdpic_got_section (info)
+ ->output_offset
+ + frvfdpic_got_initial_offset (info)
+ + entry->tlsdesc_entry, entry);
+
+ BFD_ASSERT (frvfdpic_dynamic_got_plt_info (info)->tls_ret_refs);
+
+ /* We've used one of the reserved fixups, so discount it so
+ that we can check at the end that we've used them
+ all. */
+ frvfdpic_dynamic_got_plt_info (info)->tls_ret_refs--;
+
+ /* While at that, make sure the ret instruction makes to the
+ right location in the PLT. We could do it only when we
+ got to 0, but since the check at the end will only print
+ a warning, make sure we have the ret in place in case the
+ warning is missed. */
+ bfd_put_32 (output_bfd, 0xc03a4000,
+ frvfdpic_plt_section (info)->contents
+ + frvfdpic_plt_tls_ret_offset (info));
+ }
+ else
+ {
+ if (idx == 0
+ && (bfd_is_abs_section (sec)
+ || bfd_is_und_section (sec)))
+ {
+ if (! elf_hash_table (info)->tls_sec)
+ {
+ (*info->callbacks->undefined_symbol)
+ (info, "TLS section", elf_hash_table (info)->dynobj,
+ frvfdpic_got_section (info), entry->tlsdesc_entry, TRUE);
+ return FALSE;
+ }
+ idx = elf_section_data (elf_hash_table (info)->tls_sec)->dynindx;
+ ad += FRVFDPIC_TLS_BIAS;
+ }
+
+ _frvfdpic_add_dyn_reloc (output_bfd, frvfdpic_gotrel_section (info),
+ _bfd_elf_section_offset
+ (output_bfd, info,
+ frvfdpic_got_section (info),
+ frvfdpic_got_initial_offset (info)
+ + entry->tlsdesc_entry)
+ + frvfdpic_got_section (info)
+ ->output_section->vma
+ + frvfdpic_got_section (info)
+ ->output_offset,
+ R_FRV_TLSDESC_VALUE, idx, ad, entry);
+
+ bfd_put_32 (output_bfd, 0,
+ frvfdpic_got_section (info)->contents
+ + frvfdpic_got_initial_offset (info)
+ + entry->tlsdesc_entry);
+ }
+
+ bfd_put_32 (output_bfd, ad,
+ frvfdpic_got_section (info)->contents
+ + frvfdpic_got_initial_offset (info)
+ + entry->tlsdesc_entry + 4);
+ }
+
+ /* Generate code for the get-TLS-offset PLT entry. */
+ if (entry->tlsplt_entry != (bfd_vma) -1)
+ {
+ bfd_byte *plt_code = frvfdpic_plt_section (info)->contents
+ + entry->tlsplt_entry;
+
+ if (info->executable
+ && (entry->symndx != -1
+ || FRVFDPIC_SYM_LOCAL (info, entry->d.h)))
+ {
+ int idx = dynindx;
+ bfd_vma ad = addend;
+
+ /* sec may be NULL when referencing an undefweak symbol
+ while linking a static executable. */
+ if (!sec)
+ {
+ BFD_ASSERT (entry->symndx == -1
+ && entry->d.h->root.type == bfd_link_hash_undefweak);
+ }
+ else
+ {
+ if (entry->symndx == -1)
+ ad += entry->d.h->root.u.def.value;
+ else
+ ad += sym->st_value;
+ ad += sec->output_offset;
+ if (sec->output_section
+ && elf_section_data (sec->output_section))
+ idx = elf_section_data (sec->output_section)->dynindx;
+ else
+ idx = 0;
+ }
+
+ /* *ABS*+addend is special for TLS relocations, use only the
+ addend for the TLS offset, and take the module id as
+ 0. */
+ if (idx == 0
+ && (bfd_is_abs_section (sec)
+ || bfd_is_und_section (sec)))
+ ;
+ /* For other TLS symbols that bind locally, add the section
+ TLS offset to the addend. */
+ else if (sec)
+ ad += sec->output_section->vma - tls_biased_base (info);
+
+ if ((bfd_signed_vma)ad >= -(1 << (16 - 1))
+ && (bfd_signed_vma)ad < (1 << (16 - 1)))
+ {
+ /* setlos lo(ad), gr9 */
+ bfd_put_32 (output_bfd,
+ 0x92fc0000
+ | (ad
+ & (((bfd_vma)1 << 16) - 1)),
+ plt_code);
+ plt_code += 4;
+ }
+ else
+ {
+ /* sethi.p hi(ad), gr9
+ setlo lo(ad), gr9 */
+ bfd_put_32 (output_bfd,
+ 0x12f80000
+ | ((ad >> 16)
+ & (((bfd_vma)1 << 16) - 1)),
+ plt_code);
+ plt_code += 4;
+ bfd_put_32 (output_bfd,
+ 0x92f40000
+ | (ad
+ & (((bfd_vma)1 << 16) - 1)),
+ plt_code);
+ plt_code += 4;
+ }
+ /* ret */
+ bfd_put_32 (output_bfd, 0xc03a4000, plt_code);
+ }
+ else if (entry->tlsoff_entry)
+ {
+ /* Figure out what kind of PLT entry we need, depending on the
+ location of the TLS descriptor within the GOT. */
+ if (entry->tlsoff_entry >= -(1 << (12 - 1))
+ && entry->tlsoff_entry < (1 << (12 - 1)))
+ {
+ /* ldi @(gr15, tlsoff_entry), gr9 */
+ bfd_put_32 (output_bfd,
+ 0x92c8f000 | (entry->tlsoff_entry
+ & ((1 << 12) - 1)),
+ plt_code);
+ plt_code += 4;
+ }
+ else
+ {
+ if (entry->tlsoff_entry >= -(1 << (16 - 1))
+ && entry->tlsoff_entry < (1 << (16 - 1)))
+ {
+ /* setlos lo(tlsoff_entry), gr8 */
+ bfd_put_32 (output_bfd,
+ 0x90fc0000
+ | (entry->tlsoff_entry
+ & (((bfd_vma)1 << 16) - 1)),
+ plt_code);
+ plt_code += 4;
+ }
+ else
+ {
+ /* sethi.p hi(tlsoff_entry), gr8
+ setlo lo(tlsoff_entry), gr8 */
+ bfd_put_32 (output_bfd,
+ 0x10f80000
+ | ((entry->tlsoff_entry >> 16)
+ & (((bfd_vma)1 << 16) - 1)),
+ plt_code);
+ plt_code += 4;
+ bfd_put_32 (output_bfd,
+ 0x90f40000
+ | (entry->tlsoff_entry
+ & (((bfd_vma)1 << 16) - 1)),
+ plt_code);
+ plt_code += 4;
+ }
+ /* ld @(gr15,gr8),gr9 */
+ bfd_put_32 (output_bfd, 0x9008f108, plt_code);
+ plt_code += 4;
+ }
+ /* ret */
+ bfd_put_32 (output_bfd, 0xc03a4000, plt_code);
+ }
+ else
+ {
+ BFD_ASSERT (entry->tlsdesc_entry);
+
+ /* Figure out what kind of PLT entry we need, depending on the
+ location of the TLS descriptor within the GOT. */
+ if (entry->tlsdesc_entry >= -(1 << (12 - 1))
+ && entry->tlsdesc_entry < (1 << (12 - 1)))
+ {
+ /* lddi @(gr15, tlsdesc_entry), gr8 */
+ bfd_put_32 (output_bfd,
+ 0x90ccf000 | (entry->tlsdesc_entry
+ & ((1 << 12) - 1)),
+ plt_code);
+ plt_code += 4;
+ }
+ else
+ {
+ if (entry->tlsdesc_entry >= -(1 << (16 - 1))
+ && entry->tlsdesc_entry < (1 << (16 - 1)))
+ {
+ /* setlos lo(tlsdesc_entry), gr8 */
+ bfd_put_32 (output_bfd,
+ 0x90fc0000
+ | (entry->tlsdesc_entry
+ & (((bfd_vma)1 << 16) - 1)),
+ plt_code);
+ plt_code += 4;
+ }
+ else
+ {
+ /* sethi.p hi(tlsdesc_entry), gr8
+ setlo lo(tlsdesc_entry), gr8 */
+ bfd_put_32 (output_bfd,
+ 0x10f80000
+ | ((entry->tlsdesc_entry >> 16)
+ & (((bfd_vma)1 << 16) - 1)),
+ plt_code);
+ plt_code += 4;
+ bfd_put_32 (output_bfd,
+ 0x90f40000
+ | (entry->tlsdesc_entry
+ & (((bfd_vma)1 << 16) - 1)),
+ plt_code);
+ plt_code += 4;
+ }
+ /* ldd @(gr15,gr8),gr8 */
+ bfd_put_32 (output_bfd, 0x9008f148, plt_code);
+ plt_code += 4;
+ }
+ /* jmpl @(gr8,gr0) */
+ bfd_put_32 (output_bfd, 0x80308000, plt_code);
+ }
+ }
+
+ return TRUE;
+}
+
+/* Handle an FRV small data reloc. */
+
+static bfd_reloc_status_type
+elf32_frv_relocate_gprel12 (struct bfd_link_info *info,
+ bfd *input_bfd,
+ asection *input_section,
+ Elf_Internal_Rela *relocation,
+ bfd_byte *contents,
+ bfd_vma value)
+{
+ bfd_vma insn;
+ bfd_vma gp;
+ struct bfd_link_hash_entry *h;
+
+ h = bfd_link_hash_lookup (info->hash, "_gp", FALSE, FALSE, TRUE);
+
+ gp = (h->u.def.value
+ + h->u.def.section->output_section->vma
+ + h->u.def.section->output_offset);
+
+ value -= input_section->output_section->vma;
+ value -= (gp - input_section->output_section->vma);
+
+ insn = bfd_get_32 (input_bfd, contents + relocation->r_offset);
+
+ value += relocation->r_addend;
+
+ if ((long) value > 0x7ff || (long) value < -0x800)
+ return bfd_reloc_overflow;
+
+ bfd_put_32 (input_bfd,
+ (insn & 0xfffff000) | (value & 0xfff),
+ contents + relocation->r_offset);
+
+ return bfd_reloc_ok;
+}
+
+/* Handle an FRV small data reloc. for the u12 field. */
+
+static bfd_reloc_status_type
+elf32_frv_relocate_gprelu12 (struct bfd_link_info *info,
+ bfd *input_bfd,
+ asection *input_section,
+ Elf_Internal_Rela *relocation,
+ bfd_byte *contents,
+ bfd_vma value)
+{
+ bfd_vma insn;
+ bfd_vma gp;
+ struct bfd_link_hash_entry *h;
+ bfd_vma mask;
+
+ h = bfd_link_hash_lookup (info->hash, "_gp", FALSE, FALSE, TRUE);
+
+ gp = (h->u.def.value
+ + h->u.def.section->output_section->vma
+ + h->u.def.section->output_offset);
+
+ value -= input_section->output_section->vma;
+ value -= (gp - input_section->output_section->vma);
+
+ insn = bfd_get_32 (input_bfd, contents + relocation->r_offset);
+
+ value += relocation->r_addend;
+
+ if ((long) value > 0x7ff || (long) value < -0x800)
+ return bfd_reloc_overflow;
+
+ /* The high 6 bits go into bits 17-12. The low 6 bits go into bits 5-0. */
+ mask = 0x3f03f;
+ insn = (insn & ~mask) | ((value & 0xfc0) << 12) | (value & 0x3f);
+
+ bfd_put_32 (input_bfd, insn, contents + relocation->r_offset);
+
+ return bfd_reloc_ok;
+}
+
+/* Handle an FRV ELF HI16 reloc. */
+
+static bfd_reloc_status_type
+elf32_frv_relocate_hi16 (bfd *input_bfd,
+ Elf_Internal_Rela *relhi,
+ bfd_byte *contents,
+ bfd_vma value)
+{
+ bfd_vma insn;
+
+ insn = bfd_get_32 (input_bfd, contents + relhi->r_offset);
+
+ value += relhi->r_addend;
+ value = ((value >> 16) & 0xffff);
+
+ insn = (insn & 0xffff0000) | value;
+
+ if ((long) value > 0xffff || (long) value < -0x10000)
+ return bfd_reloc_overflow;
+
+ bfd_put_32 (input_bfd, insn, contents + relhi->r_offset);
+ return bfd_reloc_ok;
+
+}
+static bfd_reloc_status_type
+elf32_frv_relocate_lo16 (bfd *input_bfd,
+ Elf_Internal_Rela *rello,
+ bfd_byte *contents,
+ bfd_vma value)
+{
+ bfd_vma insn;
+
+ insn = bfd_get_32 (input_bfd, contents + rello->r_offset);
+
+ value += rello->r_addend;
+ value = value & 0xffff;
+
+ insn = (insn & 0xffff0000) | value;
+
+ if ((long) value > 0xffff || (long) value < -0x10000)
+ return bfd_reloc_overflow;
+
+ bfd_put_32 (input_bfd, insn, contents + rello->r_offset);
+ return bfd_reloc_ok;
+}
+
+/* Perform the relocation for the CALL label24 instruction. */
+
+static bfd_reloc_status_type
+elf32_frv_relocate_label24 (bfd *input_bfd,
+ asection *input_section,
+ Elf_Internal_Rela *rello,
+ bfd_byte *contents,
+ bfd_vma value)
+{
+ bfd_vma insn;
+ bfd_vma label6;
+ bfd_vma label18;
+
+ /* The format for the call instruction is:
+
+ 0 000000 0001111 000000000000000000
+ label6 opcode label18
+
+ The branch calculation is: pc + (4*label24)
+ where label24 is the concatenation of label6 and label18. */
+
+ /* Grab the instruction. */
+ insn = bfd_get_32 (input_bfd, contents + rello->r_offset);
+
+ value -= input_section->output_section->vma + input_section->output_offset;
+ value -= rello->r_offset;
+ value += rello->r_addend;
+
+ value = value >> 2;
+
+ label6 = value & 0xfc0000;
+ label6 = label6 << 7;
+
+ label18 = value & 0x3ffff;
+
+ insn = insn & 0x803c0000;
+ insn = insn | label6;
+ insn = insn | label18;
+
+ bfd_put_32 (input_bfd, insn, contents + rello->r_offset);
+
+ return bfd_reloc_ok;
+}
+
+static bfd_reloc_status_type
+elf32_frv_relocate_gprelhi (struct bfd_link_info *info,
+ bfd *input_bfd,
+ asection *input_section,
+ Elf_Internal_Rela *relocation,
+ bfd_byte *contents,
+ bfd_vma value)
+{
+ bfd_vma insn;
+ bfd_vma gp;
+ struct bfd_link_hash_entry *h;
+
+ h = bfd_link_hash_lookup (info->hash, "_gp", FALSE, FALSE, TRUE);
+
+ gp = (h->u.def.value
+ + h->u.def.section->output_section->vma
+ + h->u.def.section->output_offset);
+
+ value -= input_section->output_section->vma;
+ value -= (gp - input_section->output_section->vma);
+ value += relocation->r_addend;
+ value = ((value >> 16) & 0xffff);
+
+ if ((long) value > 0xffff || (long) value < -0x10000)
+ return bfd_reloc_overflow;
+
+ insn = bfd_get_32 (input_bfd, contents + relocation->r_offset);
+ insn = (insn & 0xffff0000) | value;
+
+ bfd_put_32 (input_bfd, insn, contents + relocation->r_offset);
+ return bfd_reloc_ok;
+}
+
+static bfd_reloc_status_type
+elf32_frv_relocate_gprello (struct bfd_link_info *info,
+ bfd *input_bfd,
+ asection *input_section,
+ Elf_Internal_Rela *relocation,
+ bfd_byte *contents,
+ bfd_vma value)
+{
+ bfd_vma insn;
+ bfd_vma gp;
+ struct bfd_link_hash_entry *h;
+
+ h = bfd_link_hash_lookup (info->hash, "_gp", FALSE, FALSE, TRUE);
+
+ gp = (h->u.def.value
+ + h->u.def.section->output_section->vma
+ + h->u.def.section->output_offset);
+
+ value -= input_section->output_section->vma;
+ value -= (gp - input_section->output_section->vma);
+ value += relocation->r_addend;
+ value = value & 0xffff;
+
+ if ((long) value > 0xffff || (long) value < -0x10000)
+ return bfd_reloc_overflow;
+
+ insn = bfd_get_32 (input_bfd, contents + relocation->r_offset);
+ insn = (insn & 0xffff0000) | value;
+
+ bfd_put_32 (input_bfd, insn, contents + relocation->r_offset);
+
+ return bfd_reloc_ok;
+}
+
+static reloc_howto_type *
+frv_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ bfd_reloc_code_real_type code)
+{
+ switch (code)
+ {
+ default:
+ break;
+
+ case BFD_RELOC_NONE:
+ return &elf32_frv_howto_table[ (int) R_FRV_NONE];
+
+ case BFD_RELOC_32:
+ if (elf_elfheader (abfd)->e_type == ET_EXEC
+ || elf_elfheader (abfd)->e_type == ET_DYN)
+ return &elf32_frv_rel_32_howto;
+ /* Fall through. */
+ case BFD_RELOC_CTOR:
+ return &elf32_frv_howto_table[ (int) R_FRV_32];
+
+ case BFD_RELOC_FRV_LABEL16:
+ return &elf32_frv_howto_table[ (int) R_FRV_LABEL16];
+
+ case BFD_RELOC_FRV_LABEL24:
+ return &elf32_frv_howto_table[ (int) R_FRV_LABEL24];
+
+ case BFD_RELOC_FRV_LO16:
+ return &elf32_frv_howto_table[ (int) R_FRV_LO16];
+
+ case BFD_RELOC_FRV_HI16:
+ return &elf32_frv_howto_table[ (int) R_FRV_HI16];
+
+ case BFD_RELOC_FRV_GPREL12:
+ return &elf32_frv_howto_table[ (int) R_FRV_GPREL12];
+
+ case BFD_RELOC_FRV_GPRELU12:
+ return &elf32_frv_howto_table[ (int) R_FRV_GPRELU12];
+
+ case BFD_RELOC_FRV_GPREL32:
+ return &elf32_frv_howto_table[ (int) R_FRV_GPREL32];
+
+ case BFD_RELOC_FRV_GPRELHI:
+ return &elf32_frv_howto_table[ (int) R_FRV_GPRELHI];
+
+ case BFD_RELOC_FRV_GPRELLO:
+ return &elf32_frv_howto_table[ (int) R_FRV_GPRELLO];
+
+ case BFD_RELOC_FRV_GOT12:
+ return &elf32_frv_howto_table[ (int) R_FRV_GOT12];
+
+ case BFD_RELOC_FRV_GOTHI:
+ return &elf32_frv_howto_table[ (int) R_FRV_GOTHI];
+
+ case BFD_RELOC_FRV_GOTLO:
+ return &elf32_frv_howto_table[ (int) R_FRV_GOTLO];
+
+ case BFD_RELOC_FRV_FUNCDESC:
+ if (elf_elfheader (abfd)->e_type == ET_EXEC
+ || elf_elfheader (abfd)->e_type == ET_DYN)
+ return &elf32_frv_rel_funcdesc_howto;
+ return &elf32_frv_howto_table[ (int) R_FRV_FUNCDESC];
+
+ case BFD_RELOC_FRV_FUNCDESC_GOT12:
+ return &elf32_frv_howto_table[ (int) R_FRV_FUNCDESC_GOT12];
+
+ case BFD_RELOC_FRV_FUNCDESC_GOTHI:
+ return &elf32_frv_howto_table[ (int) R_FRV_FUNCDESC_GOTHI];
+
+ case BFD_RELOC_FRV_FUNCDESC_GOTLO:
+ return &elf32_frv_howto_table[ (int) R_FRV_FUNCDESC_GOTLO];
+
+ case BFD_RELOC_FRV_FUNCDESC_VALUE:
+ if (elf_elfheader (abfd)->e_type == ET_EXEC
+ || elf_elfheader (abfd)->e_type == ET_DYN)
+ return &elf32_frv_rel_funcdesc_value_howto;
+ return &elf32_frv_howto_table[ (int) R_FRV_FUNCDESC_VALUE];
+
+ case BFD_RELOC_FRV_FUNCDESC_GOTOFF12:
+ return &elf32_frv_howto_table[ (int) R_FRV_FUNCDESC_GOTOFF12];
+
+ case BFD_RELOC_FRV_FUNCDESC_GOTOFFHI:
+ return &elf32_frv_howto_table[ (int) R_FRV_FUNCDESC_GOTOFFHI];
+
+ case BFD_RELOC_FRV_FUNCDESC_GOTOFFLO:
+ return &elf32_frv_howto_table[ (int) R_FRV_FUNCDESC_GOTOFFLO];
+
+ case BFD_RELOC_FRV_GOTOFF12:
+ return &elf32_frv_howto_table[ (int) R_FRV_GOTOFF12];
+
+ case BFD_RELOC_FRV_GOTOFFHI:
+ return &elf32_frv_howto_table[ (int) R_FRV_GOTOFFHI];
+
+ case BFD_RELOC_FRV_GOTOFFLO:
+ return &elf32_frv_howto_table[ (int) R_FRV_GOTOFFLO];
+
+ case BFD_RELOC_FRV_GETTLSOFF:
+ return &elf32_frv_howto_table[ (int) R_FRV_GETTLSOFF];
+
+ case BFD_RELOC_FRV_TLSDESC_VALUE:
+ if (elf_elfheader (abfd)->e_type == ET_EXEC
+ || elf_elfheader (abfd)->e_type == ET_DYN)
+ return &elf32_frv_rel_tlsdesc_value_howto;
+ return &elf32_frv_howto_table[ (int) R_FRV_TLSDESC_VALUE];
+
+ case BFD_RELOC_FRV_GOTTLSDESC12:
+ return &elf32_frv_howto_table[ (int) R_FRV_GOTTLSDESC12];
+
+ case BFD_RELOC_FRV_GOTTLSDESCHI:
+ return &elf32_frv_howto_table[ (int) R_FRV_GOTTLSDESCHI];
+
+ case BFD_RELOC_FRV_GOTTLSDESCLO:
+ return &elf32_frv_howto_table[ (int) R_FRV_GOTTLSDESCLO];
+
+ case BFD_RELOC_FRV_TLSMOFF12:
+ return &elf32_frv_howto_table[ (int) R_FRV_TLSMOFF12];
+
+ case BFD_RELOC_FRV_TLSMOFFHI:
+ return &elf32_frv_howto_table[ (int) R_FRV_TLSMOFFHI];
+
+ case BFD_RELOC_FRV_TLSMOFFLO:
+ return &elf32_frv_howto_table[ (int) R_FRV_TLSMOFFLO];
+
+ case BFD_RELOC_FRV_GOTTLSOFF12:
+ return &elf32_frv_howto_table[ (int) R_FRV_GOTTLSOFF12];
+
+ case BFD_RELOC_FRV_GOTTLSOFFHI:
+ return &elf32_frv_howto_table[ (int) R_FRV_GOTTLSOFFHI];
+
+ case BFD_RELOC_FRV_GOTTLSOFFLO:
+ return &elf32_frv_howto_table[ (int) R_FRV_GOTTLSOFFLO];
+
+ case BFD_RELOC_FRV_TLSOFF:
+ if (elf_elfheader (abfd)->e_type == ET_EXEC
+ || elf_elfheader (abfd)->e_type == ET_DYN)
+ return &elf32_frv_rel_tlsoff_howto;
+ return &elf32_frv_howto_table[ (int) R_FRV_TLSOFF];
+
+ case BFD_RELOC_FRV_TLSDESC_RELAX:
+ return &elf32_frv_howto_table[ (int) R_FRV_TLSDESC_RELAX];
+
+ case BFD_RELOC_FRV_GETTLSOFF_RELAX:
+ return &elf32_frv_howto_table[ (int) R_FRV_GETTLSOFF_RELAX];
+
+ case BFD_RELOC_FRV_TLSOFF_RELAX:
+ return &elf32_frv_howto_table[ (int) R_FRV_TLSOFF_RELAX];
+
+ case BFD_RELOC_FRV_TLSMOFF:
+ return &elf32_frv_howto_table[ (int) R_FRV_TLSMOFF];
+
+ case BFD_RELOC_VTABLE_INHERIT:
+ return &elf32_frv_vtinherit_howto;
+
+ case BFD_RELOC_VTABLE_ENTRY:
+ return &elf32_frv_vtentry_howto;
+ }
+
+ return NULL;
+}
+
+static reloc_howto_type *
+frv_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, const char *r_name)
+{
+ unsigned int i;
+
+ for (i = 0;
+ i < sizeof (elf32_frv_howto_table) / sizeof (elf32_frv_howto_table[0]);
+ i++)
+ if (elf32_frv_howto_table[i].name != NULL
+ && strcasecmp (elf32_frv_howto_table[i].name, r_name) == 0)
+ return &elf32_frv_howto_table[i];
+
+ if (strcasecmp (elf32_frv_vtinherit_howto.name, r_name) == 0)
+ return &elf32_frv_vtinherit_howto;
+ if (strcasecmp (elf32_frv_vtentry_howto.name, r_name) == 0)
+ return &elf32_frv_vtentry_howto;
+
+ return NULL;
+}
+
+/* Set the howto pointer for an FRV ELF reloc. */
+
+static void
+frv_info_to_howto_rela (bfd *abfd ATTRIBUTE_UNUSED,
+ arelent *cache_ptr,
+ Elf_Internal_Rela *dst)
+{
+ unsigned int r_type;
+
+ r_type = ELF32_R_TYPE (dst->r_info);
+ switch (r_type)
+ {
+ case R_FRV_GNU_VTINHERIT:
+ cache_ptr->howto = &elf32_frv_vtinherit_howto;
+ break;
+
+ case R_FRV_GNU_VTENTRY:
+ cache_ptr->howto = &elf32_frv_vtentry_howto;
+ break;
+
+ default:
+ cache_ptr->howto = & elf32_frv_howto_table [r_type];
+ break;
+ }
+}
+
+/* Set the howto pointer for an FRV ELF REL reloc. */
+static void
+frvfdpic_info_to_howto_rel (bfd *abfd ATTRIBUTE_UNUSED,
+ arelent *cache_ptr, Elf_Internal_Rela *dst)
+{
+ unsigned int r_type;
+
+ r_type = ELF32_R_TYPE (dst->r_info);
+ switch (r_type)
+ {
+ case R_FRV_32:
+ cache_ptr->howto = &elf32_frv_rel_32_howto;
+ break;
+
+ case R_FRV_FUNCDESC:
+ cache_ptr->howto = &elf32_frv_rel_funcdesc_howto;
+ break;
+
+ case R_FRV_FUNCDESC_VALUE:
+ cache_ptr->howto = &elf32_frv_rel_funcdesc_value_howto;
+ break;
+
+ case R_FRV_TLSDESC_VALUE:
+ cache_ptr->howto = &elf32_frv_rel_tlsdesc_value_howto;
+ break;
+
+ case R_FRV_TLSOFF:
+ cache_ptr->howto = &elf32_frv_rel_tlsoff_howto;
+ break;
+
+ default:
+ cache_ptr->howto = NULL;
+ break;
+ }
+}
+
+/* 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
+frv_final_link_relocate (reloc_howto_type *howto,
+ bfd *input_bfd,
+ asection *input_section,
+ bfd_byte *contents,
+ Elf_Internal_Rela *rel,
+ bfd_vma relocation)
+{
+ return _bfd_final_link_relocate (howto, input_bfd, input_section,
+ contents, rel->r_offset, relocation,
+ rel->r_addend);
+}
+
+
+/* Relocate an FRV ELF section.
+
+ 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 relocatable
+ 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 relocatable 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 bfd_boolean
+elf32_frv_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
+ 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;
+ unsigned isec_segment, got_segment, plt_segment, gprel_segment, tls_segment,
+ check_segment[2];
+ int silence_segment_error = !(info->shared || info->pie);
+ unsigned long insn;
+
+ symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
+ sym_hashes = elf_sym_hashes (input_bfd);
+ relend = relocs + input_section->reloc_count;
+
+ isec_segment = _frvfdpic_osec_to_segment (output_bfd,
+ input_section->output_section);
+ if (IS_FDPIC (output_bfd) && frvfdpic_got_section (info))
+ got_segment = _frvfdpic_osec_to_segment (output_bfd,
+ frvfdpic_got_section (info)
+ ->output_section);
+ else
+ got_segment = -1;
+ if (IS_FDPIC (output_bfd) && frvfdpic_gotfixup_section (info))
+ gprel_segment = _frvfdpic_osec_to_segment (output_bfd,
+ frvfdpic_gotfixup_section (info)
+ ->output_section);
+ else
+ gprel_segment = -1;
+ if (IS_FDPIC (output_bfd) && frvfdpic_plt_section (info))
+ plt_segment = _frvfdpic_osec_to_segment (output_bfd,
+ frvfdpic_plt_section (info)
+ ->output_section);
+ else
+ plt_segment = -1;
+ if (elf_hash_table (info)->tls_sec)
+ tls_segment = _frvfdpic_osec_to_segment (output_bfd,
+ elf_hash_table (info)->tls_sec);
+ else
+ tls_segment = -1;
+
+ 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;
+ int r_type;
+ asection *osec;
+ struct frvfdpic_relocs_info *picrel;
+ bfd_vma orig_addend = rel->r_addend;
+
+ r_type = ELF32_R_TYPE (rel->r_info);
+
+ if ( r_type == R_FRV_GNU_VTINHERIT
+ || r_type == R_FRV_GNU_VTENTRY)
+ continue;
+
+ r_symndx = ELF32_R_SYM (rel->r_info);
+ howto = elf32_frv_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;
+ osec = sec = local_sections [r_symndx];
+ relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
+
+ name = bfd_elf_string_from_elf_section
+ (input_bfd, symtab_hdr->sh_link, sym->st_name);
+ if (name == NULL || name[0] == 0)
+ name = bfd_section_name (input_bfd, sec);
+ }
+ else
+ {
+ bfd_boolean warned, ignored;
+ bfd_boolean unresolved_reloc;
+
+ RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
+ r_symndx, symtab_hdr, sym_hashes,
+ h, sec, relocation,
+ unresolved_reloc, warned, ignored);
+ osec = sec;
+ name = h->root.root.string;
+ }
+
+ if (sec != NULL && discarded_section (sec))
+ RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+ rel, 1, relend, howto, 0, contents);
+
+ if (info->relocatable)
+ continue;
+
+ if (r_type != R_FRV_TLSMOFF
+ && h != NULL
+ && (h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak)
+ && !FRVFDPIC_SYM_LOCAL (info, h))
+ {
+ osec = sec = NULL;
+ relocation = 0;
+ }
+
+ switch (r_type)
+ {
+ case R_FRV_LABEL24:
+ case R_FRV_32:
+ if (! IS_FDPIC (output_bfd))
+ goto non_fdpic;
+
+ case R_FRV_GOT12:
+ case R_FRV_GOTHI:
+ case R_FRV_GOTLO:
+ case R_FRV_FUNCDESC_GOT12:
+ case R_FRV_FUNCDESC_GOTHI:
+ case R_FRV_FUNCDESC_GOTLO:
+ case R_FRV_GOTOFF12:
+ case R_FRV_GOTOFFHI:
+ case R_FRV_GOTOFFLO:
+ case R_FRV_FUNCDESC_GOTOFF12:
+ case R_FRV_FUNCDESC_GOTOFFHI:
+ case R_FRV_FUNCDESC_GOTOFFLO:
+ case R_FRV_FUNCDESC:
+ case R_FRV_FUNCDESC_VALUE:
+ case R_FRV_GETTLSOFF:
+ case R_FRV_TLSDESC_VALUE:
+ case R_FRV_GOTTLSDESC12:
+ case R_FRV_GOTTLSDESCHI:
+ case R_FRV_GOTTLSDESCLO:
+ case R_FRV_TLSMOFF12:
+ case R_FRV_TLSMOFFHI:
+ case R_FRV_TLSMOFFLO:
+ case R_FRV_GOTTLSOFF12:
+ case R_FRV_GOTTLSOFFHI:
+ case R_FRV_GOTTLSOFFLO:
+ case R_FRV_TLSOFF:
+ case R_FRV_TLSDESC_RELAX:
+ case R_FRV_GETTLSOFF_RELAX:
+ case R_FRV_TLSOFF_RELAX:
+ case R_FRV_TLSMOFF:
+ if (h != NULL)
+ picrel = frvfdpic_relocs_info_for_global (frvfdpic_relocs_info
+ (info), input_bfd, h,
+ orig_addend, INSERT);
+ else
+ /* In order to find the entry we created before, we must
+ use the original addend, not the one that may have been
+ modified by _bfd_elf_rela_local_sym(). */
+ picrel = frvfdpic_relocs_info_for_local (frvfdpic_relocs_info
+ (info), input_bfd, r_symndx,
+ orig_addend, INSERT);
+ if (! picrel)
+ return FALSE;
+
+ if (!_frvfdpic_emit_got_relocs_plt_entries (picrel, output_bfd, info,
+ osec, sym,
+ rel->r_addend))
+ {
+ info->callbacks->einfo
+ (_("%H: relocation to `%s+%v'"
+ " may have caused the error above\n"),
+ input_bfd, input_section, rel->r_offset, name, rel->r_addend);
+ return FALSE;
+ }
+
+ break;
+
+ default:
+ non_fdpic:
+ picrel = NULL;
+ if (h
+ && ! FRVFDPIC_SYM_LOCAL (info, h)
+ && _bfd_elf_section_offset (output_bfd, info, input_section,
+ rel->r_offset) != (bfd_vma) -1)
+ {
+ info->callbacks->einfo
+ (_("%H: relocation references symbol"
+ " not defined in the module\n"),
+ input_bfd, input_section, rel->r_offset);
+ return FALSE;
+ }
+ break;
+ }
+
+ switch (r_type)
+ {
+ case R_FRV_GETTLSOFF:
+ case R_FRV_TLSDESC_VALUE:
+ case R_FRV_GOTTLSDESC12:
+ case R_FRV_GOTTLSDESCHI:
+ case R_FRV_GOTTLSDESCLO:
+ case R_FRV_TLSMOFF12:
+ case R_FRV_TLSMOFFHI:
+ case R_FRV_TLSMOFFLO:
+ case R_FRV_GOTTLSOFF12:
+ case R_FRV_GOTTLSOFFHI:
+ case R_FRV_GOTTLSOFFLO:
+ case R_FRV_TLSOFF:
+ case R_FRV_TLSDESC_RELAX:
+ case R_FRV_GETTLSOFF_RELAX:
+ case R_FRV_TLSOFF_RELAX:
+ case R_FRV_TLSMOFF:
+ if (sec && (bfd_is_abs_section (sec) || bfd_is_und_section (sec)))
+ relocation += tls_biased_base (info);
+ break;
+
+ default:
+ break;
+ }
+
+ /* Try to apply TLS relaxations. */
+ if (1)
+ switch (r_type)
+ {
+
+#define LOCAL_EXEC_P(info, picrel) \
+ ((info)->executable \
+ && (picrel->symndx != -1 || FRVFDPIC_SYM_LOCAL ((info), (picrel)->d.h)))
+#define INITIAL_EXEC_P(info, picrel) \
+ (((info)->executable || (info)->flags & DF_STATIC_TLS) \
+ && (picrel)->tlsoff_entry)
+
+#define IN_RANGE_FOR_OFST12_P(value) \
+ ((bfd_vma)((value) + 2048) < (bfd_vma)4096)
+#define IN_RANGE_FOR_SETLOS_P(value) \
+ ((bfd_vma)((value) + 32768) < (bfd_vma)65536)
+#define TLSMOFF_IN_RANGE_FOR_SETLOS_P(value, info) \
+ (IN_RANGE_FOR_SETLOS_P ((value) - tls_biased_base (info)))
+
+#define RELAX_GETTLSOFF_LOCAL_EXEC_P(info, picrel, value) \
+ (LOCAL_EXEC_P ((info), (picrel)) \
+ && TLSMOFF_IN_RANGE_FOR_SETLOS_P((value), (info)))
+#define RELAX_GETTLSOFF_INITIAL_EXEC_P(info, picrel) \
+ (INITIAL_EXEC_P ((info), (picrel)) \
+ && IN_RANGE_FOR_OFST12_P ((picrel)->tlsoff_entry))
+
+#define RELAX_TLSDESC_LOCAL_EXEC_P(info, picrel, value) \
+ (LOCAL_EXEC_P ((info), (picrel)))
+#define RELAX_TLSDESC_INITIAL_EXEC_P(info, picrel) \
+ (INITIAL_EXEC_P ((info), (picrel)))
+
+#define RELAX_GOTTLSOFF_LOCAL_EXEC_P(info, picrel, value) \
+ (LOCAL_EXEC_P ((info), (picrel)) \
+ && TLSMOFF_IN_RANGE_FOR_SETLOS_P((value), (info)))
+
+ case R_FRV_GETTLSOFF:
+ insn = bfd_get_32 (input_bfd, contents + rel->r_offset);
+
+ /* Is this a call instruction? */
+ if ((insn & (unsigned long)0x01fc0000) != 0x003c0000)
+ {
+ info->callbacks->einfo
+ (_("%H: R_FRV_GETTLSOFF not applied to a call instruction\n"),
+ input_bfd, input_section, rel->r_offset);
+ return FALSE;
+ }
+
+ if (RELAX_GETTLSOFF_LOCAL_EXEC_P (info, picrel,
+ relocation + rel->r_addend))
+ {
+ /* Replace the call instruction (except the packing bit)
+ with setlos #tlsmofflo(symbol+offset), gr9. */
+ insn &= (unsigned long)0x80000000;
+ insn |= (unsigned long)0x12fc0000;
+ bfd_put_32 (input_bfd, insn, contents + rel->r_offset);
+
+ r_type = R_FRV_TLSMOFFLO;
+ howto = elf32_frv_howto_table + r_type;
+ rel->r_info = ELF32_R_INFO (r_symndx, r_type);
+ }
+
+ else if (RELAX_GETTLSOFF_INITIAL_EXEC_P (info, picrel))
+ {
+ /* Replace the call instruction (except the packing bit)
+ with ldi @(gr15, #gottlsoff12(symbol+addend)), gr9. */
+ insn &= (unsigned long)0x80000000;
+ insn |= (unsigned long)0x12c8f000;
+ bfd_put_32 (input_bfd, insn, contents + rel->r_offset);
+
+ r_type = R_FRV_GOTTLSOFF12;
+ howto = elf32_frv_howto_table + r_type;
+ rel->r_info = ELF32_R_INFO (r_symndx, r_type);
+ }
+
+ break;
+
+ case R_FRV_GOTTLSDESC12:
+ insn = bfd_get_32 (input_bfd, contents + rel->r_offset);
+
+ /* Is this an lddi instruction? */
+ if ((insn & (unsigned long)0x01fc0000) != 0x00cc0000)
+ {
+ info->callbacks->einfo
+ (_("%H: R_FRV_GOTTLSDESC12"
+ " not applied to an lddi instruction\n"),
+ input_bfd, input_section, rel->r_offset);
+ return FALSE;
+ }
+
+ if (RELAX_TLSDESC_LOCAL_EXEC_P (info, picrel,
+ relocation + rel->r_addend)
+ && TLSMOFF_IN_RANGE_FOR_SETLOS_P (relocation + rel->r_addend,
+ info))
+ {
+ /* Replace lddi @(grB, #gottlsdesc12(symbol+offset), grC
+ with setlos #tlsmofflo(symbol+offset), gr<C+1>.
+ Preserve the packing bit. */
+ insn = (insn & (unsigned long)0x80000000)
+ | ((insn + (unsigned long)0x02000000)
+ & (unsigned long)0x7e000000);
+ insn |= (unsigned long)0x00fc0000;
+ bfd_put_32 (input_bfd, insn, contents + rel->r_offset);
+
+ r_type = R_FRV_TLSMOFFLO;
+ howto = elf32_frv_howto_table + r_type;
+ rel->r_info = ELF32_R_INFO (r_symndx, r_type);
+ }
+
+ else if (RELAX_TLSDESC_LOCAL_EXEC_P (info, picrel,
+ relocation + rel->r_addend))
+ {
+ /* Replace lddi @(grB, #gottlsdesc12(symbol+offset), grC
+ with sethi #tlsmoffhi(symbol+offset), gr<C+1>.
+ Preserve the packing bit. */
+ insn = (insn & (unsigned long)0x80000000)
+ | ((insn + (unsigned long)0x02000000)
+ & (unsigned long)0x7e000000);
+ insn |= (unsigned long)0x00f80000;
+ bfd_put_32 (input_bfd, insn, contents + rel->r_offset);
+
+ r_type = R_FRV_TLSMOFFHI;
+ howto = elf32_frv_howto_table + r_type;
+ rel->r_info = ELF32_R_INFO (r_symndx, r_type);
+ }
+
+ else if (RELAX_TLSDESC_INITIAL_EXEC_P (info, picrel))
+ {
+ /* Replace lddi @(grB, #gottlsdesc12(symbol+offset), grC
+ with ldi @(grB, #gottlsoff12(symbol+offset),
+ gr<C+1>. Preserve the packing bit. If gottlsoff12
+ overflows, we'll error out, but that's sort-of ok,
+ since we'd started with gottlsdesc12, that's actually
+ more demanding. Compiling with -fPIE instead of
+ -fpie would fix it; linking with --relax should fix
+ it as well. */
+ insn = (insn & (unsigned long)0x80cbf000)
+ | ((insn + (unsigned long)0x02000000)
+ & (unsigned long)0x7e000000);
+ bfd_put_32 (input_bfd, insn, contents + rel->r_offset);
+
+ r_type = R_FRV_GOTTLSOFF12;
+ howto = elf32_frv_howto_table + r_type;
+ rel->r_info = ELF32_R_INFO (r_symndx, r_type);
+ }
+
+ break;
+
+ case R_FRV_GOTTLSDESCHI:
+ insn = bfd_get_32 (input_bfd, contents + rel->r_offset);
+
+ /* Is this a sethi instruction? */
+ if ((insn & (unsigned long)0x01ff0000) != 0x00f80000)
+ {
+ info->callbacks->einfo
+ (_("%H: R_FRV_GOTTLSDESCHI"
+ " not applied to a sethi instruction\n"),
+ input_bfd, input_section, rel->r_offset);
+ return FALSE;
+ }
+
+ if (RELAX_TLSDESC_LOCAL_EXEC_P (info, picrel,
+ relocation + rel->r_addend)
+ || (RELAX_TLSDESC_INITIAL_EXEC_P (info, picrel)
+ && IN_RANGE_FOR_SETLOS_P (picrel->tlsoff_entry)))
+ {
+ /* Replace sethi with a nop. Preserve the packing bit. */
+ insn &= (unsigned long)0x80000000;
+ insn |= (unsigned long)0x00880000;
+ bfd_put_32 (input_bfd, insn, contents + rel->r_offset);
+
+ /* Nothing to relocate. */
+ continue;
+ }
+
+ else if (RELAX_TLSDESC_INITIAL_EXEC_P (info, picrel))
+ {
+ /* Simply decay GOTTLSDESC to GOTTLSOFF. */
+ r_type = R_FRV_GOTTLSOFFHI;
+ howto = elf32_frv_howto_table + r_type;
+ rel->r_info = ELF32_R_INFO (r_symndx, r_type);
+ }
+
+ break;
+
+ case R_FRV_GOTTLSDESCLO:
+ insn = bfd_get_32 (input_bfd, contents + rel->r_offset);
+
+ /* Is this a setlo or setlos instruction? */
+ if ((insn & (unsigned long)0x01f70000) != 0x00f40000)
+ {
+ info->callbacks->einfo
+ (_("%H: R_FRV_GOTTLSDESCLO"
+ " not applied to a setlo or setlos instruction\n"),
+ input_bfd, input_section, rel->r_offset);
+ return FALSE;
+ }
+
+ if (RELAX_TLSDESC_LOCAL_EXEC_P (info, picrel,
+ relocation + rel->r_addend)
+ || (RELAX_TLSDESC_INITIAL_EXEC_P (info, picrel)
+ && IN_RANGE_FOR_OFST12_P (picrel->tlsoff_entry)))
+ {
+ /* Replace setlo/setlos with a nop. Preserve the
+ packing bit. */
+ insn &= (unsigned long)0x80000000;
+ insn |= (unsigned long)0x00880000;
+ bfd_put_32 (input_bfd, insn, contents + rel->r_offset);
+
+ /* Nothing to relocate. */
+ continue;
+ }
+
+ else if (RELAX_TLSDESC_INITIAL_EXEC_P (info, picrel))
+ {
+ /* If the corresponding sethi (if it exists) decayed
+ to a nop, make sure this becomes (or already is) a
+ setlos, not setlo. */
+ if (IN_RANGE_FOR_SETLOS_P (picrel->tlsoff_entry))
+ {
+ insn |= (unsigned long)0x00080000;
+ bfd_put_32 (input_bfd, insn, contents + rel->r_offset);
+ }
+
+ /* Simply decay GOTTLSDESC to GOTTLSOFF. */
+ r_type = R_FRV_GOTTLSOFFLO;
+ howto = elf32_frv_howto_table + r_type;
+ rel->r_info = ELF32_R_INFO (r_symndx, r_type);
+ }
+
+ break;
+
+ case R_FRV_TLSDESC_RELAX:
+ insn = bfd_get_32 (input_bfd, contents + rel->r_offset);
+
+ /* Is this an ldd instruction? */
+ if ((insn & (unsigned long)0x01fc0fc0) != 0x00080140)
+ {
+ info->callbacks->einfo
+ (_("%H: R_FRV_TLSDESC_RELAX"
+ " not applied to an ldd instruction\n"),
+ input_bfd, input_section, rel->r_offset);
+ return FALSE;
+ }
+
+ if (RELAX_TLSDESC_LOCAL_EXEC_P (info, picrel,
+ relocation + rel->r_addend)
+ && TLSMOFF_IN_RANGE_FOR_SETLOS_P (relocation + rel->r_addend,
+ info))
+ {
+ /* Replace ldd #tlsdesc(symbol+offset)@(grB, grA), grC
+ with setlos #tlsmofflo(symbol+offset), gr<C+1>.
+ Preserve the packing bit. */
+ insn = (insn & (unsigned long)0x80000000)
+ | ((insn + (unsigned long)0x02000000)
+ & (unsigned long)0x7e000000);
+ insn |= (unsigned long)0x00fc0000;
+ bfd_put_32 (input_bfd, insn, contents + rel->r_offset);
+
+ r_type = R_FRV_TLSMOFFLO;
+ howto = elf32_frv_howto_table + r_type;
+ rel->r_info = ELF32_R_INFO (r_symndx, r_type);
+ }
+
+ else if (RELAX_TLSDESC_LOCAL_EXEC_P (info, picrel,
+ relocation + rel->r_addend))
+ {
+ /* Replace ldd #tlsdesc(symbol+offset)@(grB, grA), grC
+ with sethi #tlsmoffhi(symbol+offset), gr<C+1>.
+ Preserve the packing bit. */
+ insn = (insn & (unsigned long)0x80000000)
+ | ((insn + (unsigned long)0x02000000)
+ & (unsigned long)0x7e000000);
+ insn |= (unsigned long)0x00f80000;
+ bfd_put_32 (input_bfd, insn, contents + rel->r_offset);
+
+ r_type = R_FRV_TLSMOFFHI;
+ howto = elf32_frv_howto_table + r_type;
+ rel->r_info = ELF32_R_INFO (r_symndx, r_type);
+ }
+
+ else if (RELAX_TLSDESC_INITIAL_EXEC_P (info, picrel)
+ && IN_RANGE_FOR_OFST12_P (picrel->tlsoff_entry))
+ {
+ /* Replace ldd #tlsdesc(symbol+offset)@(grB, grA), grC
+ with ldi @(grB, #gottlsoff12(symbol+offset), gr<C+1>.
+ Preserve the packing bit. */
+ insn = (insn & (unsigned long)0x8003f000)
+ | (unsigned long)0x00c80000
+ | ((insn + (unsigned long)0x02000000)
+ & (unsigned long)0x7e000000);
+ bfd_put_32 (input_bfd, insn, contents + rel->r_offset);
+
+ r_type = R_FRV_GOTTLSOFF12;
+ howto = elf32_frv_howto_table + r_type;
+ rel->r_info = ELF32_R_INFO (r_symndx, r_type);
+ }
+
+ else if (RELAX_TLSDESC_INITIAL_EXEC_P (info, picrel))
+ {
+ /* Replace ldd #tlsdesc(symbol+offset)@(grB, grA), grC
+ with ld #tlsoff(symbol+offset)@(grB, grA), gr<C+1>.
+ Preserve the packing bit. */
+ insn = (insn & (unsigned long)0x81ffffbf)
+ | ((insn + (unsigned long)0x02000000)
+ & (unsigned long)0x7e000000);
+ bfd_put_32 (input_bfd, insn, contents + rel->r_offset);
+
+ /* #tlsoff(symbol+offset) is just a relaxation
+ annotation, so there's nothing left to
+ relocate. */
+ continue;
+ }
+
+ break;
+
+ case R_FRV_GETTLSOFF_RELAX:
+ insn = bfd_get_32 (input_bfd, contents + rel->r_offset);
+
+ /* Is this a calll or callil instruction? */
+ if ((insn & (unsigned long)0x7ff80fc0) != 0x02300000)
+ {
+ info->callbacks->einfo
+ (_("%H: R_FRV_GETTLSOFF_RELAX"
+ " not applied to a calll instruction\n"),
+ input_bfd, input_section, rel->r_offset);
+ return FALSE;
+ }
+
+ if (RELAX_TLSDESC_LOCAL_EXEC_P (info, picrel,
+ relocation + rel->r_addend)
+ && TLSMOFF_IN_RANGE_FOR_SETLOS_P (relocation + rel->r_addend,
+ info))
+ {
+ /* Replace calll with a nop. Preserve the packing bit. */
+ insn &= (unsigned long)0x80000000;
+ insn |= (unsigned long)0x00880000;
+ bfd_put_32 (input_bfd, insn, contents + rel->r_offset);
+
+ /* Nothing to relocate. */
+ continue;
+ }
+
+ else if (RELAX_TLSDESC_LOCAL_EXEC_P (info, picrel,
+ relocation + rel->r_addend))
+ {
+ /* Replace calll with setlo #tlsmofflo(symbol+offset), gr9.
+ Preserve the packing bit. */
+ insn &= (unsigned long)0x80000000;
+ insn |= (unsigned long)0x12f40000;
+ bfd_put_32 (input_bfd, insn, contents + rel->r_offset);
+
+ r_type = R_FRV_TLSMOFFLO;
+ howto = elf32_frv_howto_table + r_type;
+ rel->r_info = ELF32_R_INFO (r_symndx, r_type);
+ }
+
+ else if (RELAX_TLSDESC_INITIAL_EXEC_P (info, picrel))
+ {
+ /* Replace calll with a nop. Preserve the packing bit. */
+ insn &= (unsigned long)0x80000000;
+ insn |= (unsigned long)0x00880000;
+ bfd_put_32 (input_bfd, insn, contents + rel->r_offset);
+
+ /* Nothing to relocate. */
+ continue;
+ }
+
+ break;
+
+ case R_FRV_GOTTLSOFF12:
+ insn = bfd_get_32 (input_bfd, contents + rel->r_offset);
+
+ /* Is this an ldi instruction? */
+ if ((insn & (unsigned long)0x01fc0000) != 0x00c80000)
+ {
+ info->callbacks->einfo
+ (_("%H: R_FRV_GOTTLSOFF12"
+ " not applied to an ldi instruction\n"),
+ input_bfd, input_section, rel->r_offset);
+ return FALSE;
+ }
+
+ if (RELAX_GOTTLSOFF_LOCAL_EXEC_P (info, picrel,
+ relocation + rel->r_addend))
+ {
+ /* Replace ldi @(grB, #gottlsoff12(symbol+offset), grC
+ with setlos #tlsmofflo(symbol+offset), grC.
+ Preserve the packing bit. */
+ insn &= (unsigned long)0xfe000000;
+ insn |= (unsigned long)0x00fc0000;
+ bfd_put_32 (input_bfd, insn, contents + rel->r_offset);
+
+ r_type = R_FRV_TLSMOFFLO;
+ howto = elf32_frv_howto_table + r_type;
+ rel->r_info = ELF32_R_INFO (r_symndx, r_type);
+ }
+
+ break;
+
+ case R_FRV_GOTTLSOFFHI:
+ insn = bfd_get_32 (input_bfd, contents + rel->r_offset);
+
+ /* Is this a sethi instruction? */
+ if ((insn & (unsigned long)0x01ff0000) != 0x00f80000)
+ {
+ info->callbacks->einfo
+ (_("%H: R_FRV_GOTTLSOFFHI"
+ " not applied to a sethi instruction\n"),
+ input_bfd, input_section, rel->r_offset);
+ return FALSE;
+ }
+
+ if (RELAX_GOTTLSOFF_LOCAL_EXEC_P (info, picrel,
+ relocation + rel->r_addend)
+ || (RELAX_TLSDESC_INITIAL_EXEC_P (info, picrel)
+ && IN_RANGE_FOR_OFST12_P (picrel->tlsoff_entry)))
+ {
+ /* Replace sethi with a nop. Preserve the packing bit. */
+ insn &= (unsigned long)0x80000000;
+ insn |= (unsigned long)0x00880000;
+ bfd_put_32 (input_bfd, insn, contents + rel->r_offset);
+
+ /* Nothing to relocate. */
+ continue;
+ }
+
+ break;
+
+ case R_FRV_GOTTLSOFFLO:
+ insn = bfd_get_32 (input_bfd, contents + rel->r_offset);
+
+ /* Is this a setlo or setlos instruction? */
+ if ((insn & (unsigned long)0x01f70000) != 0x00f40000)
+ {
+ info->callbacks->einfo
+ (_("%H: R_FRV_GOTTLSOFFLO"
+ " not applied to a setlo or setlos instruction\n"),
+ input_bfd, input_section, rel->r_offset);
+ return FALSE;
+ }
+
+ if (RELAX_GOTTLSOFF_LOCAL_EXEC_P (info, picrel,
+ relocation + rel->r_addend)
+ || (RELAX_TLSDESC_INITIAL_EXEC_P (info, picrel)
+ && IN_RANGE_FOR_OFST12_P (picrel->tlsoff_entry)))
+ {
+ /* Replace setlo/setlos with a nop. Preserve the
+ packing bit. */
+ insn &= (unsigned long)0x80000000;
+ insn |= (unsigned long)0x00880000;
+ bfd_put_32 (input_bfd, insn, contents + rel->r_offset);
+
+ /* Nothing to relocate. */
+ continue;
+ }
+
+ break;
+
+ case R_FRV_TLSOFF_RELAX:
+ insn = bfd_get_32 (input_bfd, contents + rel->r_offset);
+
+ /* Is this an ld instruction? */
+ if ((insn & (unsigned long)0x01fc0fc0) != 0x00080100)
+ {
+ info->callbacks->einfo
+ (_("%H: R_FRV_TLSOFF_RELAX"
+ " not applied to an ld instruction\n"),
+ input_bfd, input_section, rel->r_offset);
+ return FALSE;
+ }
+
+ if (RELAX_GOTTLSOFF_LOCAL_EXEC_P (info, picrel,
+ relocation + rel->r_addend))
+ {
+ /* Replace ld #gottlsoff(symbol+offset)@(grB, grA), grC
+ with setlos #tlsmofflo(symbol+offset), grC.
+ Preserve the packing bit. */
+ insn &= (unsigned long)0xfe000000;
+ insn |= (unsigned long)0x00fc0000;
+ bfd_put_32 (input_bfd, insn, contents + rel->r_offset);
+
+ r_type = R_FRV_TLSMOFFLO;
+ howto = elf32_frv_howto_table + r_type;
+ rel->r_info = ELF32_R_INFO (r_symndx, r_type);
+ }
+
+ else if (RELAX_TLSDESC_INITIAL_EXEC_P (info, picrel)
+ && IN_RANGE_FOR_OFST12_P (picrel->tlsoff_entry))
+ {
+ /* Replace ld #tlsoff(symbol+offset)@(grB, grA), grC
+ with ldi @(grB, #gottlsoff12(symbol+offset), grC.
+ Preserve the packing bit. */
+ insn = (insn & (unsigned long)0xfe03f000)
+ | (unsigned long)0x00c80000;
+ bfd_put_32 (input_bfd, insn, contents + rel->r_offset);
+
+ r_type = R_FRV_GOTTLSOFF12;
+ howto = elf32_frv_howto_table + r_type;
+ rel->r_info = ELF32_R_INFO (r_symndx, r_type);
+ }
+
+ break;
+
+ case R_FRV_TLSMOFFHI:
+ insn = bfd_get_32 (input_bfd, contents + rel->r_offset);
+
+ /* Is this a sethi instruction? */
+ if ((insn & (unsigned long)0x01ff0000) != 0x00f80000)
+ {
+ info->callbacks->einfo
+ (_("%H: R_FRV_TLSMOFFHI"
+ " not applied to a sethi instruction\n"),
+ input_bfd, input_section, rel->r_offset);
+ return FALSE;
+ }
+
+ if (TLSMOFF_IN_RANGE_FOR_SETLOS_P (relocation + rel->r_addend,
+ info))
+ {
+ /* Replace sethi with a nop. Preserve the packing bit. */
+ insn &= (unsigned long)0x80000000;
+ insn |= (unsigned long)0x00880000;
+ bfd_put_32 (input_bfd, insn, contents + rel->r_offset);
+
+ /* Nothing to relocate. */
+ continue;
+ }
+
+ break;
+
+ case R_FRV_TLSMOFFLO:
+ insn = bfd_get_32 (input_bfd, contents + rel->r_offset);
+
+ /* Is this a setlo or setlos instruction? */
+ if ((insn & (unsigned long)0x01f70000) != 0x00f40000)
+ {
+ info->callbacks->einfo
+ (_("R_FRV_TLSMOFFLO"
+ " not applied to a setlo or setlos instruction\n"),
+ input_bfd, input_section, rel->r_offset);
+ return FALSE;
+ }
+
+ if (TLSMOFF_IN_RANGE_FOR_SETLOS_P (relocation + rel->r_addend,
+ info))
+ /* If the corresponding sethi (if it exists) decayed
+ to a nop, make sure this becomes (or already is) a
+ setlos, not setlo. */
+ {
+ insn |= (unsigned long)0x00080000;
+ bfd_put_32 (input_bfd, insn, contents + rel->r_offset);
+ }
+
+ break;
+
+ /*
+ There's nothing to relax in these:
+ R_FRV_TLSDESC_VALUE
+ R_FRV_TLSOFF
+ R_FRV_TLSMOFF12
+ R_FRV_TLSMOFFHI
+ R_FRV_TLSMOFFLO
+ R_FRV_TLSMOFF
+ */
+
+ default:
+ break;
+ }
+
+ switch (r_type)
+ {
+ case R_FRV_LABEL24:
+ check_segment[0] = isec_segment;
+ if (! IS_FDPIC (output_bfd))
+ check_segment[1] = isec_segment;
+ else if (picrel->plt)
+ {
+ relocation = frvfdpic_plt_section (info)->output_section->vma
+ + frvfdpic_plt_section (info)->output_offset
+ + picrel->plt_entry;
+ check_segment[1] = plt_segment;
+ }
+ /* We don't want to warn on calls to undefined weak symbols,
+ as calls to them must be protected by non-NULL tests
+ anyway, and unprotected calls would invoke undefined
+ behavior. */
+ else if (picrel->symndx == -1
+ && picrel->d.h->root.type == bfd_link_hash_undefweak)
+ check_segment[1] = check_segment[0];
+ else
+ check_segment[1] = sec
+ ? _frvfdpic_osec_to_segment (output_bfd, sec->output_section)
+ : (unsigned)-1;
+ break;
+
+ case R_FRV_GOT12:
+ case R_FRV_GOTHI:
+ case R_FRV_GOTLO:
+ relocation = picrel->got_entry;
+ check_segment[0] = check_segment[1] = got_segment;
+ break;
+
+ case R_FRV_FUNCDESC_GOT12:
+ case R_FRV_FUNCDESC_GOTHI:
+ case R_FRV_FUNCDESC_GOTLO:
+ relocation = picrel->fdgot_entry;
+ check_segment[0] = check_segment[1] = got_segment;
+ break;
+
+ case R_FRV_GOTOFFHI:
+ case R_FRV_GOTOFF12:
+ case R_FRV_GOTOFFLO:
+ relocation -= frvfdpic_got_section (info)->output_section->vma
+ + frvfdpic_got_section (info)->output_offset
+ + frvfdpic_got_initial_offset (info);
+ check_segment[0] = got_segment;
+ check_segment[1] = sec
+ ? _frvfdpic_osec_to_segment (output_bfd, sec->output_section)
+ : (unsigned)-1;
+ break;
+
+ case R_FRV_FUNCDESC_GOTOFF12:
+ case R_FRV_FUNCDESC_GOTOFFHI:
+ case R_FRV_FUNCDESC_GOTOFFLO:
+ relocation = picrel->fd_entry;
+ check_segment[0] = check_segment[1] = got_segment;
+ break;
+
+ case R_FRV_FUNCDESC:
+ {
+ int dynindx;
+ bfd_vma addend = rel->r_addend;
+
+ if (! (h && h->root.type == bfd_link_hash_undefweak
+ && FRVFDPIC_SYM_LOCAL (info, h)))
+ {
+ /* If the symbol is dynamic and there may be dynamic
+ symbol resolution because we are or are linked with a
+ shared library, emit a FUNCDESC relocation such that
+ the dynamic linker will allocate the function
+ descriptor. If the symbol needs a non-local function
+ descriptor but binds locally (e.g., its visibility is
+ protected, emit a dynamic relocation decayed to
+ section+offset. */
+ if (h && ! FRVFDPIC_FUNCDESC_LOCAL (info, h)
+ && FRVFDPIC_SYM_LOCAL (info, h)
+ && !(info->executable && !info->pie))
+ {
+ dynindx = elf_section_data (h->root.u.def.section
+ ->output_section)->dynindx;
+ addend += h->root.u.def.section->output_offset
+ + h->root.u.def.value;
+ }
+ else if (h && ! FRVFDPIC_FUNCDESC_LOCAL (info, h))
+ {
+ if (addend)
+ {
+ info->callbacks->einfo
+ (_("%H: R_FRV_FUNCDESC references dynamic symbol"
+ " with nonzero addend\n"),
+ input_bfd, input_section, rel->r_offset);
+ return FALSE;
+ }
+ dynindx = h->dynindx;
+ }
+ else
+ {
+ /* Otherwise, we know we have a private function
+ descriptor, so reference it directly. */
+ BFD_ASSERT (picrel->privfd);
+ r_type = R_FRV_32;
+ dynindx = elf_section_data (frvfdpic_got_section (info)
+ ->output_section)->dynindx;
+ addend = frvfdpic_got_section (info)->output_offset
+ + frvfdpic_got_initial_offset (info)
+ + picrel->fd_entry;
+ }
+
+ /* If there is room for dynamic symbol resolution, emit
+ the dynamic relocation. However, if we're linking an
+ executable at a fixed location, we won't have emitted a
+ dynamic symbol entry for the got section, so idx will
+ be zero, which means we can and should compute the
+ address of the private descriptor ourselves. */
+ if (info->executable && !info->pie
+ && (!h || FRVFDPIC_FUNCDESC_LOCAL (info, h)))
+ {
+ addend += frvfdpic_got_section (info)->output_section->vma;
+ if ((bfd_get_section_flags (output_bfd,
+ input_section->output_section)
+ & (SEC_ALLOC | SEC_LOAD)) == (SEC_ALLOC | SEC_LOAD))
+ {
+ bfd_vma offset;
+
+ if (_frvfdpic_osec_readonly_p (output_bfd,
+ input_section
+ ->output_section))
+ {
+ info->callbacks->einfo
+ (_("%H: cannot emit fixups"
+ " in read-only section\n"),
+ input_bfd, input_section, rel->r_offset);
+ return FALSE;
+ }
+
+ offset = _bfd_elf_section_offset
+ (output_bfd, info,
+ input_section, rel->r_offset);
+
+ if (offset != (bfd_vma)-1)
+ _frvfdpic_add_rofixup (output_bfd,
+ frvfdpic_gotfixup_section
+ (info),
+ offset + input_section
+ ->output_section->vma
+ + input_section->output_offset,
+ picrel);
+ }
+ }
+ else if ((bfd_get_section_flags (output_bfd,
+ input_section->output_section)
+ & (SEC_ALLOC | SEC_LOAD)) == (SEC_ALLOC | SEC_LOAD))
+ {
+ bfd_vma offset;
+
+ if (_frvfdpic_osec_readonly_p (output_bfd,
+ input_section
+ ->output_section))
+ {
+ info->callbacks->einfo
+ (_("%H: cannot emit dynamic relocations"
+ " in read-only section\n"),
+ input_bfd, input_section, rel->r_offset);
+ return FALSE;
+ }
+
+ offset = _bfd_elf_section_offset
+ (output_bfd, info,
+ input_section, rel->r_offset);
+
+ if (offset != (bfd_vma)-1)
+ _frvfdpic_add_dyn_reloc (output_bfd,
+ frvfdpic_gotrel_section (info),
+ offset + input_section
+ ->output_section->vma
+ + input_section->output_offset,
+ r_type, dynindx, addend, picrel);
+ }
+ else
+ addend += frvfdpic_got_section (info)->output_section->vma;
+ }
+
+ /* We want the addend in-place because dynamic
+ relocations are REL. Setting relocation to it should
+ arrange for it to be installed. */
+ relocation = addend - rel->r_addend;
+ }
+ check_segment[0] = check_segment[1] = got_segment;
+ break;
+
+ case R_FRV_32:
+ if (! IS_FDPIC (output_bfd))
+ {
+ check_segment[0] = check_segment[1] = -1;
+ break;
+ }
+ /* Fall through. */
+ case R_FRV_FUNCDESC_VALUE:
+ {
+ int dynindx;
+ bfd_vma addend = rel->r_addend;
+
+ /* If the symbol is dynamic but binds locally, use
+ section+offset. */
+ if (h && ! FRVFDPIC_SYM_LOCAL (info, h))
+ {
+ if (addend && r_type == R_FRV_FUNCDESC_VALUE)
+ {
+ info->callbacks->einfo
+ (_("%H: R_FRV_FUNCDESC_VALUE"
+ " references dynamic symbol with nonzero addend\n"),
+ input_bfd, input_section, rel->r_offset);
+ return FALSE;
+ }
+ dynindx = h->dynindx;
+ }
+ else
+ {
+ if (h)
+ addend += h->root.u.def.value;
+ else
+ addend += sym->st_value;
+ if (osec)
+ addend += osec->output_offset;
+ if (osec && osec->output_section
+ && ! bfd_is_abs_section (osec->output_section)
+ && ! bfd_is_und_section (osec->output_section))
+ dynindx = elf_section_data (osec->output_section)->dynindx;
+ else
+ dynindx = 0;
+ }
+
+ /* If we're linking an executable at a fixed address, we
+ can omit the dynamic relocation as long as the symbol
+ is defined in the current link unit (which is implied
+ by its output section not being NULL). */
+ if (info->executable && !info->pie
+ && (!h || FRVFDPIC_SYM_LOCAL (info, h)))
+ {
+ if (osec)
+ addend += osec->output_section->vma;
+ if (IS_FDPIC (input_bfd)
+ && (bfd_get_section_flags (output_bfd,
+ input_section->output_section)
+ & (SEC_ALLOC | SEC_LOAD)) == (SEC_ALLOC | SEC_LOAD))
+ {
+ if (_frvfdpic_osec_readonly_p (output_bfd,
+ input_section
+ ->output_section))
+ {
+ info->callbacks->einfo
+ (_("%H: cannot emit fixups in read-only section\n"),
+ input_bfd, input_section, rel->r_offset);
+ return FALSE;
+ }
+ if (!h || h->root.type != bfd_link_hash_undefweak)
+ {
+ bfd_vma offset = _bfd_elf_section_offset
+ (output_bfd, info,
+ input_section, rel->r_offset);
+
+ if (offset != (bfd_vma)-1)
+ {
+ _frvfdpic_add_rofixup (output_bfd,
+ frvfdpic_gotfixup_section
+ (info),
+ offset + input_section
+ ->output_section->vma
+ + input_section->output_offset,
+ picrel);
+ if (r_type == R_FRV_FUNCDESC_VALUE)
+ _frvfdpic_add_rofixup
+ (output_bfd,
+ frvfdpic_gotfixup_section (info),
+ offset
+ + input_section->output_section->vma
+ + input_section->output_offset + 4, picrel);
+ }
+ }
+ }
+ }
+ else
+ {
+ if ((bfd_get_section_flags (output_bfd,
+ input_section->output_section)
+ & (SEC_ALLOC | SEC_LOAD)) == (SEC_ALLOC | SEC_LOAD))
+ {
+ bfd_vma offset;
+
+ if (_frvfdpic_osec_readonly_p (output_bfd,
+ input_section
+ ->output_section))
+ {
+ info->callbacks->einfo
+ (_("%H: cannot emit dynamic relocations"
+ " in read-only section\n"),
+ input_bfd, input_section, rel->r_offset);
+ return FALSE;
+ }
+
+ offset = _bfd_elf_section_offset
+ (output_bfd, info,
+ input_section, rel->r_offset);
+
+ if (offset != (bfd_vma)-1)
+ _frvfdpic_add_dyn_reloc (output_bfd,
+ frvfdpic_gotrel_section (info),
+ offset + input_section
+ ->output_section->vma
+ + input_section->output_offset,
+ r_type, dynindx, addend, picrel);
+ }
+ else if (osec)
+ addend += osec->output_section->vma;
+ /* We want the addend in-place because dynamic
+ relocations are REL. Setting relocation to it
+ should arrange for it to be installed. */
+ relocation = addend - rel->r_addend;
+ }
+
+ if (r_type == R_FRV_FUNCDESC_VALUE)
+ {
+ /* If we've omitted the dynamic relocation, just emit
+ the fixed addresses of the symbol and of the local
+ GOT base offset. */
+ if (info->executable && !info->pie
+ && (!h || FRVFDPIC_SYM_LOCAL (info, h)))
+ bfd_put_32 (output_bfd,
+ frvfdpic_got_section (info)->output_section->vma
+ + frvfdpic_got_section (info)->output_offset
+ + frvfdpic_got_initial_offset (info),
+ contents + rel->r_offset + 4);
+ else
+ /* A function descriptor used for lazy or local
+ resolving is initialized such that its high word
+ contains the output section index in which the
+ PLT entries are located, and the low word
+ contains the offset of the lazy PLT entry entry
+ point into that section. */
+ bfd_put_32 (output_bfd,
+ h && ! FRVFDPIC_SYM_LOCAL (info, h)
+ ? 0
+ : _frvfdpic_osec_to_segment (output_bfd,
+ sec
+ ->output_section),
+ contents + rel->r_offset + 4);
+ }
+ }
+ check_segment[0] = check_segment[1] = got_segment;
+ break;
+
+ case R_FRV_GPREL12:
+ case R_FRV_GPRELU12:
+ case R_FRV_GPREL32:
+ case R_FRV_GPRELHI:
+ case R_FRV_GPRELLO:
+ check_segment[0] = gprel_segment;
+ check_segment[1] = sec
+ ? _frvfdpic_osec_to_segment (output_bfd, sec->output_section)
+ : (unsigned)-1;
+ break;
+
+ case R_FRV_GETTLSOFF:
+ relocation = frvfdpic_plt_section (info)->output_section->vma
+ + frvfdpic_plt_section (info)->output_offset
+ + picrel->tlsplt_entry;
+ BFD_ASSERT (picrel->tlsplt_entry != (bfd_vma)-1
+ && picrel->tlsdesc_entry);
+ check_segment[0] = isec_segment;
+ check_segment[1] = plt_segment;
+ break;
+
+ case R_FRV_GOTTLSDESC12:
+ case R_FRV_GOTTLSDESCHI:
+ case R_FRV_GOTTLSDESCLO:
+ BFD_ASSERT (picrel->tlsdesc_entry);
+ relocation = picrel->tlsdesc_entry;
+ check_segment[0] = tls_segment;
+ check_segment[1] = sec
+ && ! bfd_is_abs_section (sec)
+ && ! bfd_is_und_section (sec)
+ ? _frvfdpic_osec_to_segment (output_bfd, sec->output_section)
+ : tls_segment;
+ break;
+
+ case R_FRV_TLSMOFF12:
+ case R_FRV_TLSMOFFHI:
+ case R_FRV_TLSMOFFLO:
+ case R_FRV_TLSMOFF:
+ check_segment[0] = tls_segment;
+ if (! sec)
+ check_segment[1] = -1;
+ else if (bfd_is_abs_section (sec)
+ || bfd_is_und_section (sec))
+ {
+ relocation = 0;
+ check_segment[1] = tls_segment;
+ }
+ else if (sec->output_section)
+ {
+ relocation -= tls_biased_base (info);
+ check_segment[1] =
+ _frvfdpic_osec_to_segment (output_bfd, sec->output_section);
+ }
+ else
+ check_segment[1] = -1;
+ break;
+
+ case R_FRV_GOTTLSOFF12:
+ case R_FRV_GOTTLSOFFHI:
+ case R_FRV_GOTTLSOFFLO:
+ BFD_ASSERT (picrel->tlsoff_entry);
+ relocation = picrel->tlsoff_entry;
+ check_segment[0] = tls_segment;
+ check_segment[1] = sec
+ && ! bfd_is_abs_section (sec)
+ && ! bfd_is_und_section (sec)
+ ? _frvfdpic_osec_to_segment (output_bfd, sec->output_section)
+ : tls_segment;
+ break;
+
+ case R_FRV_TLSDESC_VALUE:
+ case R_FRV_TLSOFF:
+ /* These shouldn't be present in input object files. */
+ check_segment[0] = check_segment[1] = isec_segment;
+ break;
+
+ case R_FRV_TLSDESC_RELAX:
+ case R_FRV_GETTLSOFF_RELAX:
+ case R_FRV_TLSOFF_RELAX:
+ /* These are just annotations for relaxation, nothing to do
+ here. */
+ continue;
+
+ default:
+ check_segment[0] = isec_segment;
+ check_segment[1] = sec
+ ? _frvfdpic_osec_to_segment (output_bfd, sec->output_section)
+ : (unsigned)-1;
+ break;
+ }
+
+ if (check_segment[0] != check_segment[1] && IS_FDPIC (output_bfd))
+ {
+ /* If you take this out, remove the #error from fdpic-static-6.d
+ in the ld testsuite. */
+ /* This helps catch problems in GCC while we can't do more
+ than static linking. The idea is to test whether the
+ input file basename is crt0.o only once. */
+ if (silence_segment_error == 1)
+ silence_segment_error =
+ (strlen (input_bfd->filename) == 6
+ && filename_cmp (input_bfd->filename, "crt0.o") == 0)
+ || (strlen (input_bfd->filename) > 6
+ && filename_cmp (input_bfd->filename
+ + strlen (input_bfd->filename) - 7,
+ "/crt0.o") == 0)
+ ? -1 : 0;
+ if (!silence_segment_error
+ /* We don't want duplicate errors for undefined
+ symbols. */
+ && !(picrel && picrel->symndx == -1
+ && picrel->d.h->root.type == bfd_link_hash_undefined))
+ {
+ info->callbacks->einfo
+ (_("%H: reloc against `%s' references a different segment\n"),
+ input_bfd, input_section, rel->r_offset, name);
+ }
+ if (!silence_segment_error && (info->shared || info->pie))
+ return FALSE;
+ elf_elfheader (output_bfd)->e_flags |= EF_FRV_PIC;
+ }
+
+ switch (r_type)
+ {
+ case R_FRV_GOTOFFHI:
+ case R_FRV_TLSMOFFHI:
+ /* We need the addend to be applied before we shift the
+ value right. */
+ relocation += rel->r_addend;
+ /* Fall through. */
+ case R_FRV_GOTHI:
+ case R_FRV_FUNCDESC_GOTHI:
+ case R_FRV_FUNCDESC_GOTOFFHI:
+ case R_FRV_GOTTLSOFFHI:
+ case R_FRV_GOTTLSDESCHI:
+ relocation >>= 16;
+ /* Fall through. */
+
+ case R_FRV_GOTLO:
+ case R_FRV_FUNCDESC_GOTLO:
+ case R_FRV_GOTOFFLO:
+ case R_FRV_FUNCDESC_GOTOFFLO:
+ case R_FRV_GOTTLSOFFLO:
+ case R_FRV_GOTTLSDESCLO:
+ case R_FRV_TLSMOFFLO:
+ relocation &= 0xffff;
+ break;
+
+ default:
+ break;
+ }
+
+ switch (r_type)
+ {
+ case R_FRV_LABEL24:
+ if (! IS_FDPIC (output_bfd) || ! picrel->plt)
+ break;
+ /* Fall through. */
+
+ /* When referencing a GOT entry, a function descriptor or a
+ PLT, we don't want the addend to apply to the reference,
+ but rather to the referenced symbol. The actual entry
+ will have already been created taking the addend into
+ account, so cancel it out here. */
+ case R_FRV_GOT12:
+ case R_FRV_GOTHI:
+ case R_FRV_GOTLO:
+ case R_FRV_FUNCDESC_GOT12:
+ case R_FRV_FUNCDESC_GOTHI:
+ case R_FRV_FUNCDESC_GOTLO:
+ case R_FRV_FUNCDESC_GOTOFF12:
+ case R_FRV_FUNCDESC_GOTOFFHI:
+ case R_FRV_FUNCDESC_GOTOFFLO:
+ case R_FRV_GETTLSOFF:
+ case R_FRV_GOTTLSDESC12:
+ case R_FRV_GOTTLSDESCHI:
+ case R_FRV_GOTTLSDESCLO:
+ case R_FRV_GOTTLSOFF12:
+ case R_FRV_GOTTLSOFFHI:
+ case R_FRV_GOTTLSOFFLO:
+ /* Note that we only want GOTOFFHI, not GOTOFFLO or GOTOFF12
+ here, since we do want to apply the addend to the others.
+ Note that we've applied the addend to GOTOFFHI before we
+ shifted it right. */
+ case R_FRV_GOTOFFHI:
+ case R_FRV_TLSMOFFHI:
+ relocation -= rel->r_addend;
+ break;
+
+ default:
+ break;
+ }
+
+ if (r_type == R_FRV_HI16)
+ r = elf32_frv_relocate_hi16 (input_bfd, rel, contents, relocation);
+
+ else if (r_type == R_FRV_LO16)
+ r = elf32_frv_relocate_lo16 (input_bfd, rel, contents, relocation);
+
+ else if (r_type == R_FRV_LABEL24 || r_type == R_FRV_GETTLSOFF)
+ r = elf32_frv_relocate_label24 (input_bfd, input_section, rel,
+ contents, relocation);
+
+ else if (r_type == R_FRV_GPREL12)
+ r = elf32_frv_relocate_gprel12 (info, input_bfd, input_section, rel,
+ contents, relocation);
+
+ else if (r_type == R_FRV_GPRELU12)
+ r = elf32_frv_relocate_gprelu12 (info, input_bfd, input_section, rel,
+ contents, relocation);
+
+ else if (r_type == R_FRV_GPRELLO)
+ r = elf32_frv_relocate_gprello (info, input_bfd, input_section, rel,
+ contents, relocation);
+
+ else if (r_type == R_FRV_GPRELHI)
+ r = elf32_frv_relocate_gprelhi (info, input_bfd, input_section, rel,
+ contents, relocation);
+
+ else if (r_type == R_FRV_TLSOFF
+ || r_type == R_FRV_TLSDESC_VALUE)
+ r = bfd_reloc_notsupported;
+
+ else
+ r = frv_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, (h ? &h->root : NULL), 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, TRUE);
+ 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)
+ {
+ info->callbacks->einfo
+ (_("%H: reloc against `%s': %s\n"),
+ input_bfd, input_section, rel->r_offset, name, msg);
+ return FALSE;
+ }
+
+ if (! r)
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+/* Return the section that should be marked against GC for a given
+ relocation. */
+
+static asection *
+elf32_frv_gc_mark_hook (asection *sec,
+ 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_FRV_GNU_VTINHERIT:
+ case R_FRV_GNU_VTENTRY:
+ return NULL;
+ }
+
+ return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
+}
+
+/* Hook called by the linker routine which adds symbols from an object
+ file. We use it to put .comm items in .scomm, and not .comm. */
+
+static bfd_boolean
+elf32_frv_add_symbol_hook (bfd *abfd,
+ struct bfd_link_info *info,
+ Elf_Internal_Sym *sym,
+ const char **namep ATTRIBUTE_UNUSED,
+ flagword *flagsp ATTRIBUTE_UNUSED,
+ asection **secp,
+ bfd_vma *valp)
+{
+ if (sym->st_shndx == SHN_COMMON
+ && !info->relocatable
+ && (int)sym->st_size <= (int)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_with_flags (abfd, ".scommon",
+ (SEC_ALLOC
+ | SEC_IS_COMMON
+ | SEC_LINKER_CREATED));
+ if (scomm == NULL)
+ return FALSE;
+ }
+
+ *secp = scomm;
+ *valp = sym->st_size;
+ }
+
+ return TRUE;
+}
+
+/* We need dynamic symbols for every section, since segments can
+ relocate independently. */
+static bfd_boolean
+_frvfdpic_link_omit_section_dynsym (bfd *output_bfd ATTRIBUTE_UNUSED,
+ struct bfd_link_info *info
+ ATTRIBUTE_UNUSED,
+ asection *p ATTRIBUTE_UNUSED)
+{
+ switch (elf_section_data (p)->this_hdr.sh_type)
+ {
+ case SHT_PROGBITS:
+ case SHT_NOBITS:
+ /* If sh_type is yet undecided, assume it could be
+ SHT_PROGBITS/SHT_NOBITS. */
+ case SHT_NULL:
+ return FALSE;
+
+ /* There shouldn't be section relative relocations
+ against any other section. */
+ default:
+ return TRUE;
+ }
+}
+
+/* Create a .got section, as well as its additional info field. This
+ is almost entirely copied from
+ elflink.c:_bfd_elf_create_got_section(). */
+
+static bfd_boolean
+_frv_create_got_section (bfd *abfd, struct bfd_link_info *info)
+{
+ flagword flags, pltflags;
+ asection *s;
+ struct elf_link_hash_entry *h;
+ struct bfd_link_hash_entry *bh;
+ const struct elf_backend_data *bed = get_elf_backend_data (abfd);
+ int ptralign;
+ int offset;
+
+ /* This function may be called more than once. */
+ s = bfd_get_linker_section (abfd, ".got");
+ if (s != NULL)
+ return TRUE;
+
+ /* Machine specific: although pointers are 32-bits wide, we want the
+ GOT to be aligned to a 64-bit boundary, such that function
+ descriptors in it can be accessed with 64-bit loads and
+ stores. */
+ ptralign = 3;
+
+ flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
+ | SEC_LINKER_CREATED);
+ pltflags = flags;
+
+ s = bfd_make_section_anyway_with_flags (abfd, ".got", flags);
+ if (s == NULL
+ || !bfd_set_section_alignment (abfd, s, ptralign))
+ return FALSE;
+
+ if (bed->want_got_plt)
+ {
+ s = bfd_make_section_anyway_with_flags (abfd, ".got.plt", flags);
+ if (s == NULL
+ || !bfd_set_section_alignment (abfd, s, ptralign))
+ return FALSE;
+ }
+
+ if (bed->want_got_sym)
+ {
+ /* 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 = _bfd_elf_define_linkage_sym (abfd, info, s, "_GLOBAL_OFFSET_TABLE_");
+ elf_hash_table (info)->hgot = h;
+ if (h == NULL)
+ return FALSE;
+
+ /* Machine-specific: we want the symbol for executables as
+ well. */
+ if (! bfd_elf_link_record_dynamic_symbol (info, h))
+ return FALSE;
+ }
+
+ /* The first bit of the global offset table is the header. */
+ s->size += bed->got_header_size;
+
+ /* This is the machine-specific part. Create and initialize section
+ data for the got. */
+ if (IS_FDPIC (abfd))
+ {
+ frvfdpic_got_section (info) = s;
+ frvfdpic_relocs_info (info) = htab_try_create (1,
+ frvfdpic_relocs_info_hash,
+ frvfdpic_relocs_info_eq,
+ (htab_del) NULL);
+ if (! frvfdpic_relocs_info (info))
+ return FALSE;
+
+ s = bfd_make_section_anyway_with_flags (abfd, ".rel.got",
+ (flags | SEC_READONLY));
+ if (s == NULL
+ || ! bfd_set_section_alignment (abfd, s, 2))
+ return FALSE;
+
+ frvfdpic_gotrel_section (info) = s;
+
+ /* Machine-specific. */
+ s = bfd_make_section_anyway_with_flags (abfd, ".rofixup",
+ (flags | SEC_READONLY));
+ if (s == NULL
+ || ! bfd_set_section_alignment (abfd, s, 2))
+ return FALSE;
+
+ frvfdpic_gotfixup_section (info) = s;
+ offset = -2048;
+ flags = BSF_GLOBAL;
+ }
+ else
+ {
+ offset = 2048;
+ flags = BSF_GLOBAL | BSF_WEAK;
+ }
+
+ /* Define _gp in .rofixup, for FDPIC, or .got otherwise. If it
+ turns out that we're linking with a different linker script, the
+ linker script will override it. */
+ bh = NULL;
+ if (!(_bfd_generic_link_add_one_symbol
+ (info, abfd, "_gp", flags, s, offset, (const char *) NULL, FALSE,
+ bed->collect, &bh)))
+ return FALSE;
+ h = (struct elf_link_hash_entry *) bh;
+ h->def_regular = 1;
+ h->type = STT_OBJECT;
+ /* h->other = STV_HIDDEN; */ /* Should we? */
+
+ /* Machine-specific: we want the symbol for executables as well. */
+ if (IS_FDPIC (abfd) && ! bfd_elf_link_record_dynamic_symbol (info, h))
+ return FALSE;
+
+ if (!IS_FDPIC (abfd))
+ return TRUE;
+
+ /* FDPIC supports Thread Local Storage, and this may require a
+ procedure linkage table for TLS PLT entries. */
+
+ /* This is mostly copied from
+ elflink.c:_bfd_elf_create_dynamic_sections(). */
+
+ flags = pltflags;
+ pltflags |= SEC_CODE;
+ if (bed->plt_not_loaded)
+ pltflags &= ~ (SEC_CODE | SEC_LOAD | SEC_HAS_CONTENTS);
+ if (bed->plt_readonly)
+ pltflags |= SEC_READONLY;
+
+ s = bfd_make_section_anyway_with_flags (abfd, ".plt", pltflags);
+ if (s == NULL
+ || ! bfd_set_section_alignment (abfd, s, bed->plt_alignment))
+ return FALSE;
+ /* FRV-specific: remember it. */
+ frvfdpic_plt_section (info) = s;
+
+ /* Define the symbol _PROCEDURE_LINKAGE_TABLE_ at the start of the
+ .plt section. */
+ if (bed->want_plt_sym)
+ {
+ h = _bfd_elf_define_linkage_sym (abfd, info, s,
+ "_PROCEDURE_LINKAGE_TABLE_");
+ elf_hash_table (info)->hplt = h;
+ if (h == NULL)
+ return FALSE;
+ }
+
+ /* FRV-specific: we want rel relocations for the plt. */
+ s = bfd_make_section_anyway_with_flags (abfd, ".rel.plt",
+ flags | SEC_READONLY);
+ if (s == NULL
+ || ! bfd_set_section_alignment (abfd, s, bed->s->log_file_align))
+ return FALSE;
+ /* FRV-specific: remember it. */
+ frvfdpic_pltrel_section (info) = s;
+
+ return TRUE;
+}
+
+/* Make sure the got and plt sections exist, and that our pointers in
+ the link hash table point to them. */
+
+static bfd_boolean
+elf32_frvfdpic_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
+{
+ /* This is mostly copied from
+ elflink.c:_bfd_elf_create_dynamic_sections(). */
+ flagword flags;
+ asection *s;
+ const struct elf_backend_data *bed = get_elf_backend_data (abfd);
+
+ flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
+ | SEC_LINKER_CREATED);
+
+ /* We need to create .plt, .rel[a].plt, .got, .got.plt, .dynbss, and
+ .rel[a].bss sections. */
+
+ /* FRV-specific: we want to create the GOT and the PLT in the FRV
+ way. */
+ if (! _frv_create_got_section (abfd, info))
+ return FALSE;
+
+ /* FRV-specific: make sure we created everything we wanted. */
+ BFD_ASSERT (frvfdpic_got_section (info) && frvfdpic_gotrel_section (info)
+ && frvfdpic_gotfixup_section (info)
+ && frvfdpic_plt_section (info)
+ && frvfdpic_pltrel_section (info));
+
+ if (bed->want_dynbss)
+ {
+ /* 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_anyway_with_flags (abfd, ".dynbss",
+ SEC_ALLOC | SEC_LINKER_CREATED);
+ if (s == NULL)
+ 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_anyway_with_flags (abfd,
+ (bed->default_use_rela_p
+ ? ".rela.bss" : ".rel.bss"),
+ flags | SEC_READONLY);
+ if (s == NULL
+ || ! bfd_set_section_alignment (abfd, s, bed->s->log_file_align))
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+/* Compute the total GOT and PLT size required by each symbol in each
+ range. Symbols may require up to 4 words in the GOT: an entry
+ pointing to the symbol, an entry pointing to its function
+ descriptor, and a private function descriptors taking two
+ words. */
+
+static void
+_frvfdpic_count_nontls_entries (struct frvfdpic_relocs_info *entry,
+ struct _frvfdpic_dynamic_got_info *dinfo)
+{
+ /* Allocate space for a GOT entry pointing to the symbol. */
+ if (entry->got12)
+ dinfo->got12 += 4;
+ else if (entry->gotlos)
+ dinfo->gotlos += 4;
+ else if (entry->gothilo)
+ dinfo->gothilo += 4;
+ else
+ entry->relocs32--;
+ entry->relocs32++;
+
+ /* Allocate space for a GOT entry pointing to the function
+ descriptor. */
+ if (entry->fdgot12)
+ dinfo->got12 += 4;
+ else if (entry->fdgotlos)
+ dinfo->gotlos += 4;
+ else if (entry->fdgothilo)
+ dinfo->gothilo += 4;
+ else
+ entry->relocsfd--;
+ entry->relocsfd++;
+
+ /* Decide whether we need a PLT entry, a function descriptor in the
+ GOT, and a lazy PLT entry for this symbol. */
+ entry->plt = entry->call
+ && entry->symndx == -1 && ! FRVFDPIC_SYM_LOCAL (dinfo->info, entry->d.h)
+ && elf_hash_table (dinfo->info)->dynamic_sections_created;
+ entry->privfd = entry->plt
+ || entry->fdgoff12 || entry->fdgofflos || entry->fdgoffhilo
+ || ((entry->fd || entry->fdgot12 || entry->fdgotlos || entry->fdgothilo)
+ && (entry->symndx != -1
+ || FRVFDPIC_FUNCDESC_LOCAL (dinfo->info, entry->d.h)));
+ entry->lazyplt = entry->privfd
+ && entry->symndx == -1 && ! FRVFDPIC_SYM_LOCAL (dinfo->info, entry->d.h)
+ && ! (dinfo->info->flags & DF_BIND_NOW)
+ && elf_hash_table (dinfo->info)->dynamic_sections_created;
+
+ /* Allocate space for a function descriptor. */
+ if (entry->fdgoff12)
+ dinfo->fd12 += 8;
+ else if (entry->fdgofflos)
+ dinfo->fdlos += 8;
+ else if (entry->privfd && entry->plt)
+ dinfo->fdplt += 8;
+ else if (entry->privfd)
+ dinfo->fdhilo += 8;
+ else
+ entry->relocsfdv--;
+ entry->relocsfdv++;
+
+ if (entry->lazyplt)
+ dinfo->lzplt += 8;
+}
+
+/* Compute the total GOT size required by each TLS symbol in each
+ range. Symbols may require up to 5 words in the GOT: an entry
+ holding the TLS offset for the symbol, and an entry with a full TLS
+ descriptor taking 4 words. */
+
+static void
+_frvfdpic_count_tls_entries (struct frvfdpic_relocs_info *entry,
+ struct _frvfdpic_dynamic_got_info *dinfo,
+ bfd_boolean subtract)
+{
+ const int l = subtract ? -1 : 1;
+
+ /* Allocate space for a GOT entry with the TLS offset of the
+ symbol. */
+ if (entry->tlsoff12)
+ dinfo->got12 += 4 * l;
+ else if (entry->tlsofflos)
+ dinfo->gotlos += 4 * l;
+ else if (entry->tlsoffhilo)
+ dinfo->gothilo += 4 * l;
+ else
+ entry->relocstlsoff -= l;
+ entry->relocstlsoff += l;
+
+ /* If there's any TLSOFF relocation, mark the output file as not
+ suitable for dlopening. This mark will remain even if we relax
+ all such relocations, but this is not a problem, since we'll only
+ do so for executables, and we definitely don't want anyone
+ dlopening executables. */
+ if (entry->relocstlsoff)
+ dinfo->info->flags |= DF_STATIC_TLS;
+
+ /* Allocate space for a TLS descriptor. */
+ if (entry->tlsdesc12)
+ dinfo->tlsd12 += 8 * l;
+ else if (entry->tlsdesclos)
+ dinfo->tlsdlos += 8 * l;
+ else if (entry->tlsplt)
+ dinfo->tlsdplt += 8 * l;
+ else if (entry->tlsdeschilo)
+ dinfo->tlsdhilo += 8 * l;
+ else
+ entry->relocstlsd -= l;
+ entry->relocstlsd += l;
+}
+
+/* Compute the number of dynamic relocations and fixups that a symbol
+ requires, and add (or subtract) from the grand and per-symbol
+ totals. */
+
+static void
+_frvfdpic_count_relocs_fixups (struct frvfdpic_relocs_info *entry,
+ struct _frvfdpic_dynamic_got_info *dinfo,
+ bfd_boolean subtract)
+{
+ bfd_vma relocs = 0, fixups = 0, tlsrets = 0;
+
+ if (!dinfo->info->executable || dinfo->info->pie)
+ {
+ relocs = entry->relocs32 + entry->relocsfd + entry->relocsfdv
+ + entry->relocstlsd;
+
+ /* In the executable, TLS relocations to symbols that bind
+ locally (including those that resolve to global TLS offsets)
+ are resolved immediately, without any need for fixups or
+ dynamic relocations. In shared libraries, however, we must
+ emit dynamic relocations even for local symbols, because we
+ don't know the module id the library is going to get at
+ run-time, nor its TLS base offset. */
+ if (!dinfo->info->executable
+ || (entry->symndx == -1
+ && ! FRVFDPIC_SYM_LOCAL (dinfo->info, entry->d.h)))
+ relocs += entry->relocstlsoff;
+ }
+ else
+ {
+ if (entry->symndx != -1 || FRVFDPIC_SYM_LOCAL (dinfo->info, entry->d.h))
+ {
+ if (entry->symndx != -1
+ || entry->d.h->root.type != bfd_link_hash_undefweak)
+ fixups += entry->relocs32 + 2 * entry->relocsfdv;
+ fixups += entry->relocstlsd;
+ tlsrets += entry->relocstlsd;
+ }
+ else
+ {
+ relocs += entry->relocs32 + entry->relocsfdv
+ + entry->relocstlsoff + entry->relocstlsd;
+ }
+
+ if (entry->symndx != -1
+ || FRVFDPIC_FUNCDESC_LOCAL (dinfo->info, entry->d.h))
+ {
+ if (entry->symndx != -1
+ || entry->d.h->root.type != bfd_link_hash_undefweak)
+ fixups += entry->relocsfd;
+ }
+ else
+ relocs += entry->relocsfd;
+ }
+
+ if (subtract)
+ {
+ relocs = - relocs;
+ fixups = - fixups;
+ tlsrets = - tlsrets;
+ }
+
+ entry->dynrelocs += relocs;
+ entry->fixups += fixups;
+ dinfo->relocs += relocs;
+ dinfo->fixups += fixups;
+ dinfo->tls_ret_refs += tlsrets;
+}
+
+/* Look for opportunities to relax TLS relocations. We can assume
+ we're linking the main executable or a static-tls library, since
+ otherwise we wouldn't have got here. When relaxing, we have to
+ first undo any previous accounting of TLS uses of fixups, dynamic
+ relocations, GOT and PLT entries. */
+
+static void
+_frvfdpic_relax_tls_entries (struct frvfdpic_relocs_info *entry,
+ struct _frvfdpic_dynamic_got_info *dinfo,
+ bfd_boolean relaxing)
+{
+ bfd_boolean changed = ! relaxing;
+
+ BFD_ASSERT (dinfo->info->executable
+ || (dinfo->info->flags & DF_STATIC_TLS));
+
+ if (entry->tlsdesc12 || entry->tlsdesclos || entry->tlsdeschilo)
+ {
+ if (! changed)
+ {
+ _frvfdpic_count_relocs_fixups (entry, dinfo, TRUE);
+ _frvfdpic_count_tls_entries (entry, dinfo, TRUE);
+ changed = TRUE;
+ }
+
+ /* When linking an executable, we can always decay GOTTLSDESC to
+ TLSMOFF, if the symbol is local, or GOTTLSOFF, otherwise.
+ When linking a static-tls shared library, using TLSMOFF is
+ not an option, but we can still use GOTTLSOFF. When decaying
+ to GOTTLSOFF, we must keep the GOT entry in range. We know
+ it has to fit because we'll be trading the 4 words of hte TLS
+ descriptor for a single word in the same range. */
+ if (! dinfo->info->executable
+ || (entry->symndx == -1
+ && ! FRVFDPIC_SYM_LOCAL (dinfo->info, entry->d.h)))
+ {
+ entry->tlsoff12 |= entry->tlsdesc12;
+ entry->tlsofflos |= entry->tlsdesclos;
+ entry->tlsoffhilo |= entry->tlsdeschilo;
+ }
+
+ entry->tlsdesc12 = entry->tlsdesclos = entry->tlsdeschilo = 0;
+ }
+
+ /* We can only decay TLSOFFs or call #gettlsoff to TLSMOFF in the
+ main executable. We have to check whether the symbol's TLSOFF is
+ in range for a setlos. For symbols with a hash entry, we can
+ determine exactly what to do; for others locals, we don't have
+ addresses handy, so we use the size of the TLS section as an
+ approximation. If we get it wrong, we'll retain a GOT entry
+ holding the TLS offset (without dynamic relocations or fixups),
+ but we'll still optimize away the loads from it. Since TLS sizes
+ are generally very small, it's probably not worth attempting to
+ do better than this. */
+ if ((entry->tlsplt
+ || entry->tlsoff12 || entry->tlsofflos || entry->tlsoffhilo)
+ && dinfo->info->executable && relaxing
+ && ((entry->symndx == -1
+ && FRVFDPIC_SYM_LOCAL (dinfo->info, entry->d.h)
+ /* The above may hold for an undefweak TLS symbol, so make
+ sure we don't have this case before accessing def.value
+ and def.section. */
+ && (entry->d.h->root.type == bfd_link_hash_undefweak
+ || (bfd_vma)(entry->d.h->root.u.def.value
+ + (entry->d.h->root.u.def.section
+ ->output_section->vma)
+ + entry->d.h->root.u.def.section->output_offset
+ + entry->addend
+ - tls_biased_base (dinfo->info)
+ + 32768) < (bfd_vma)65536))
+ || (entry->symndx != -1
+ && (elf_hash_table (dinfo->info)->tls_sec->size
+ + abs (entry->addend) < 32768 + FRVFDPIC_TLS_BIAS))))
+ {
+ if (! changed)
+ {
+ _frvfdpic_count_relocs_fixups (entry, dinfo, TRUE);
+ _frvfdpic_count_tls_entries (entry, dinfo, TRUE);
+ changed = TRUE;
+ }
+
+ entry->tlsplt =
+ entry->tlsoff12 = entry->tlsofflos = entry->tlsoffhilo = 0;
+ }
+
+ /* We can decay `call #gettlsoff' to a ldi #tlsoff if we already
+ have a #gottlsoff12 relocation for this entry, or if we can fit
+ one more in the 12-bit (and 16-bit) ranges. */
+ if (entry->tlsplt
+ && (entry->tlsoff12
+ || (relaxing
+ && dinfo->got12 + dinfo->fd12 + dinfo->tlsd12 <= 4096 - 12 - 4
+ && (dinfo->got12 + dinfo->fd12 + dinfo->tlsd12
+ + dinfo->gotlos + dinfo->fdlos + dinfo->tlsdlos
+ <= 65536 - 12 - 4))))
+ {
+ if (! changed)
+ {
+ _frvfdpic_count_relocs_fixups (entry, dinfo, TRUE);
+ _frvfdpic_count_tls_entries (entry, dinfo, TRUE);
+ changed = TRUE;
+ }
+
+ entry->tlsoff12 = 1;
+ entry->tlsplt = 0;
+ }
+
+ if (changed)
+ {
+ _frvfdpic_count_tls_entries (entry, dinfo, FALSE);
+ _frvfdpic_count_relocs_fixups (entry, dinfo, FALSE);
+ }
+
+ return;
+}
+
+/* Compute the total GOT and PLT size required by each symbol in each range. *
+ Symbols may require up to 4 words in the GOT: an entry pointing to
+ the symbol, an entry pointing to its function descriptor, and a
+ private function descriptors taking two words. */
+
+static int
+_frvfdpic_count_got_plt_entries (void **entryp, void *dinfo_)
+{
+ struct frvfdpic_relocs_info *entry = *entryp;
+ struct _frvfdpic_dynamic_got_info *dinfo = dinfo_;
+
+ _frvfdpic_count_nontls_entries (entry, dinfo);
+
+ if (dinfo->info->executable || (dinfo->info->flags & DF_STATIC_TLS))
+ _frvfdpic_relax_tls_entries (entry, dinfo, FALSE);
+ else
+ {
+ _frvfdpic_count_tls_entries (entry, dinfo, FALSE);
+ _frvfdpic_count_relocs_fixups (entry, dinfo, FALSE);
+ }
+
+ return 1;
+}
+
+/* Determine the positive and negative ranges to be used by each
+ offset range in the GOT. FDCUR and CUR, that must be aligned to a
+ double-word boundary, are the minimum (negative) and maximum
+ (positive) GOT offsets already used by previous ranges, except for
+ an ODD entry that may have been left behind. GOT and FD indicate
+ the size of GOT entries and function descriptors that must be
+ placed within the range from -WRAP to WRAP. If there's room left,
+ up to FDPLT bytes should be reserved for additional function
+ descriptors. */
+
+inline static bfd_signed_vma
+_frvfdpic_compute_got_alloc_data (struct _frvfdpic_dynamic_got_alloc_data *gad,
+ bfd_signed_vma fdcur,
+ bfd_signed_vma odd,
+ bfd_signed_vma cur,
+ bfd_vma got,
+ bfd_vma fd,
+ bfd_vma fdplt,
+ bfd_vma tlsd,
+ bfd_vma tlsdplt,
+ bfd_vma wrap)
+{
+ bfd_signed_vma wrapmin = -wrap;
+ const bfd_vma tdescsz = 8;
+
+ /* Start at the given initial points. */
+ gad->fdcur = fdcur;
+ gad->cur = cur;
+
+ /* If we had an incoming odd word and we have any got entries that
+ are going to use it, consume it, otherwise leave gad->odd at
+ zero. We might force gad->odd to zero and return the incoming
+ odd such that it is used by the next range, but then GOT entries
+ might appear to be out of order and we wouldn't be able to
+ shorten the GOT by one word if it turns out to end with an
+ unpaired GOT entry. */
+ if (odd && got)
+ {
+ gad->odd = odd;
+ got -= 4;
+ odd = 0;
+ }
+ else
+ gad->odd = 0;
+
+ /* If we're left with an unpaired GOT entry, compute its location
+ such that we can return it. Otherwise, if got doesn't require an
+ odd number of words here, either odd was already zero in the
+ block above, or it was set to zero because got was non-zero, or
+ got was already zero. In the latter case, we want the value of
+ odd to carry over to the return statement, so we don't want to
+ reset odd unless the condition below is true. */
+ if (got & 4)
+ {
+ odd = cur + got;
+ got += 4;
+ }
+
+ /* Compute the tentative boundaries of this range. */
+ gad->max = cur + got;
+ gad->min = fdcur - fd;
+ gad->fdplt = 0;
+
+ /* If function descriptors took too much space, wrap some of them
+ around. */
+ if (gad->min < wrapmin)
+ {
+ gad->max += wrapmin - gad->min;
+ gad->tmin = gad->min = wrapmin;
+ }
+
+ /* If GOT entries took too much space, wrap some of them around.
+ This may well cause gad->min to become lower than wrapmin. This
+ will cause a relocation overflow later on, so we don't have to
+ report it here . */
+ if ((bfd_vma) gad->max > wrap)
+ {
+ gad->min -= gad->max - wrap;
+ gad->max = wrap;
+ }
+
+ /* Add TLS descriptors. */
+ gad->tmax = gad->max + tlsd;
+ gad->tmin = gad->min;
+ gad->tlsdplt = 0;
+
+ /* If TLS descriptors took too much space, wrap an integral number
+ of them around. */
+ if ((bfd_vma) gad->tmax > wrap)
+ {
+ bfd_vma wrapsize = gad->tmax - wrap;
+
+ wrapsize += tdescsz / 2;
+ wrapsize &= ~ tdescsz / 2;
+
+ gad->tmin -= wrapsize;
+ gad->tmax -= wrapsize;
+ }
+
+ /* If there is space left and we have function descriptors
+ referenced in PLT entries that could take advantage of shorter
+ offsets, place them now. */
+ if (fdplt && gad->tmin > wrapmin)
+ {
+ bfd_vma fds;
+
+ if ((bfd_vma) (gad->tmin - wrapmin) < fdplt)
+ fds = gad->tmin - wrapmin;
+ else
+ fds = fdplt;
+
+ fdplt -= fds;
+ gad->min -= fds;
+ gad->tmin -= fds;
+ gad->fdplt += fds;
+ }
+
+ /* If there is more space left, try to place some more function
+ descriptors for PLT entries. */
+ if (fdplt && (bfd_vma) gad->tmax < wrap)
+ {
+ bfd_vma fds;
+
+ if ((bfd_vma) (wrap - gad->tmax) < fdplt)
+ fds = wrap - gad->tmax;
+ else
+ fds = fdplt;
+
+ fdplt -= fds;
+ gad->max += fds;
+ gad->tmax += fds;
+ gad->fdplt += fds;
+ }
+
+ /* If there is space left and we have TLS descriptors referenced in
+ PLT entries that could take advantage of shorter offsets, place
+ them now. */
+ if (tlsdplt && gad->tmin > wrapmin)
+ {
+ bfd_vma tlsds;
+
+ if ((bfd_vma) (gad->tmin - wrapmin) < tlsdplt)
+ tlsds = (gad->tmin - wrapmin) & ~ (tdescsz / 2);
+ else
+ tlsds = tlsdplt;
+
+ tlsdplt -= tlsds;
+ gad->tmin -= tlsds;
+ gad->tlsdplt += tlsds;
+ }
+
+ /* If there is more space left, try to place some more TLS
+ descriptors for PLT entries. Although we could try to fit an
+ additional TLS descriptor with half of it just before before the
+ wrap point and another right past the wrap point, this might
+ cause us to run out of space for the next region, so don't do
+ it. */
+ if (tlsdplt && (bfd_vma) gad->tmax < wrap - tdescsz / 2)
+ {
+ bfd_vma tlsds;
+
+ if ((bfd_vma) (wrap - gad->tmax) < tlsdplt)
+ tlsds = (wrap - gad->tmax) & ~ (tdescsz / 2);
+ else
+ tlsds = tlsdplt;
+
+ tlsdplt -= tlsds;
+ gad->tmax += tlsds;
+ gad->tlsdplt += tlsds;
+ }
+
+ /* If odd was initially computed as an offset past the wrap point,
+ wrap it around. */
+ if (odd > gad->max)
+ odd = gad->min + odd - gad->max;
+
+ /* _frvfdpic_get_got_entry() below will always wrap gad->cur if needed
+ before returning, so do it here too. This guarantees that,
+ should cur and fdcur meet at the wrap point, they'll both be
+ equal to min. */
+ if (gad->cur == gad->max)
+ gad->cur = gad->min;
+
+ /* Ditto for _frvfdpic_get_tlsdesc_entry(). */
+ gad->tcur = gad->max;
+ if (gad->tcur == gad->tmax)
+ gad->tcur = gad->tmin;
+
+ return odd;
+}
+
+/* Compute the location of the next GOT entry, given the allocation
+ data for a range. */
+
+inline static bfd_signed_vma
+_frvfdpic_get_got_entry (struct _frvfdpic_dynamic_got_alloc_data *gad)
+{
+ bfd_signed_vma ret;
+
+ if (gad->odd)
+ {
+ /* If there was an odd word left behind, use it. */
+ ret = gad->odd;
+ gad->odd = 0;
+ }
+ else
+ {
+ /* Otherwise, use the word pointed to by cur, reserve the next
+ as an odd word, and skip to the next pair of words, possibly
+ wrapping around. */
+ ret = gad->cur;
+ gad->odd = gad->cur + 4;
+ gad->cur += 8;
+ if (gad->cur == gad->max)
+ gad->cur = gad->min;
+ }
+
+ return ret;
+}
+
+/* Compute the location of the next function descriptor entry in the
+ GOT, given the allocation data for a range. */
+
+inline static bfd_signed_vma
+_frvfdpic_get_fd_entry (struct _frvfdpic_dynamic_got_alloc_data *gad)
+{
+ /* If we're at the bottom, wrap around, and only then allocate the
+ next pair of words. */
+ if (gad->fdcur == gad->min)
+ gad->fdcur = gad->max;
+ return gad->fdcur -= 8;
+}
+
+/* Compute the location of the next TLS descriptor entry in the GOT,
+ given the allocation data for a range. */
+inline static bfd_signed_vma
+_frvfdpic_get_tlsdesc_entry (struct _frvfdpic_dynamic_got_alloc_data *gad)
+{
+ bfd_signed_vma ret;
+
+ ret = gad->tcur;
+
+ gad->tcur += 8;
+
+ /* If we're at the top of the region, wrap around to the bottom. */
+ if (gad->tcur == gad->tmax)
+ gad->tcur = gad->tmin;
+
+ return ret;
+}
+
+/* Assign GOT offsets for every GOT entry and function descriptor.
+ Doing everything in a single pass is tricky. */
+
+static int
+_frvfdpic_assign_got_entries (void **entryp, void *info_)
+{
+ struct frvfdpic_relocs_info *entry = *entryp;
+ struct _frvfdpic_dynamic_got_plt_info *dinfo = info_;
+
+ if (entry->got12)
+ entry->got_entry = _frvfdpic_get_got_entry (&dinfo->got12);
+ else if (entry->gotlos)
+ entry->got_entry = _frvfdpic_get_got_entry (&dinfo->gotlos);
+ else if (entry->gothilo)
+ entry->got_entry = _frvfdpic_get_got_entry (&dinfo->gothilo);
+
+ if (entry->fdgot12)
+ entry->fdgot_entry = _frvfdpic_get_got_entry (&dinfo->got12);
+ else if (entry->fdgotlos)
+ entry->fdgot_entry = _frvfdpic_get_got_entry (&dinfo->gotlos);
+ else if (entry->fdgothilo)
+ entry->fdgot_entry = _frvfdpic_get_got_entry (&dinfo->gothilo);
+
+ if (entry->fdgoff12)
+ entry->fd_entry = _frvfdpic_get_fd_entry (&dinfo->got12);
+ else if (entry->plt && dinfo->got12.fdplt)
+ {
+ dinfo->got12.fdplt -= 8;
+ entry->fd_entry = _frvfdpic_get_fd_entry (&dinfo->got12);
+ }
+ else if (entry->fdgofflos)
+ entry->fd_entry = _frvfdpic_get_fd_entry (&dinfo->gotlos);
+ else if (entry->plt && dinfo->gotlos.fdplt)
+ {
+ dinfo->gotlos.fdplt -= 8;
+ entry->fd_entry = _frvfdpic_get_fd_entry (&dinfo->gotlos);
+ }
+ else if (entry->plt)
+ {
+ dinfo->gothilo.fdplt -= 8;
+ entry->fd_entry = _frvfdpic_get_fd_entry (&dinfo->gothilo);
+ }
+ else if (entry->privfd)
+ entry->fd_entry = _frvfdpic_get_fd_entry (&dinfo->gothilo);
+
+ if (entry->tlsoff12)
+ entry->tlsoff_entry = _frvfdpic_get_got_entry (&dinfo->got12);
+ else if (entry->tlsofflos)
+ entry->tlsoff_entry = _frvfdpic_get_got_entry (&dinfo->gotlos);
+ else if (entry->tlsoffhilo)
+ entry->tlsoff_entry = _frvfdpic_get_got_entry (&dinfo->gothilo);
+
+ if (entry->tlsdesc12)
+ entry->tlsdesc_entry = _frvfdpic_get_tlsdesc_entry (&dinfo->got12);
+ else if (entry->tlsplt && dinfo->got12.tlsdplt)
+ {
+ dinfo->got12.tlsdplt -= 8;
+ entry->tlsdesc_entry = _frvfdpic_get_tlsdesc_entry (&dinfo->got12);
+ }
+ else if (entry->tlsdesclos)
+ entry->tlsdesc_entry = _frvfdpic_get_tlsdesc_entry (&dinfo->gotlos);
+ else if (entry->tlsplt && dinfo->gotlos.tlsdplt)
+ {
+ dinfo->gotlos.tlsdplt -= 8;
+ entry->tlsdesc_entry = _frvfdpic_get_tlsdesc_entry (&dinfo->gotlos);
+ }
+ else if (entry->tlsplt)
+ {
+ dinfo->gothilo.tlsdplt -= 8;
+ entry->tlsdesc_entry = _frvfdpic_get_tlsdesc_entry (&dinfo->gothilo);
+ }
+ else if (entry->tlsdeschilo)
+ entry->tlsdesc_entry = _frvfdpic_get_tlsdesc_entry (&dinfo->gothilo);
+
+ return 1;
+}
+
+/* Assign GOT offsets to private function descriptors used by PLT
+ entries (or referenced by 32-bit offsets), as well as PLT entries
+ and lazy PLT entries. */
+
+static int
+_frvfdpic_assign_plt_entries (void **entryp, void *info_)
+{
+ struct frvfdpic_relocs_info *entry = *entryp;
+ struct _frvfdpic_dynamic_got_plt_info *dinfo = info_;
+
+ if (entry->privfd)
+ BFD_ASSERT (entry->fd_entry);
+
+ if (entry->plt)
+ {
+ int size;
+
+ /* We use the section's raw size to mark the location of the
+ next PLT entry. */
+ entry->plt_entry = frvfdpic_plt_section (dinfo->g.info)->size;
+
+ /* Figure out the length of this PLT entry based on the
+ addressing mode we need to reach the function descriptor. */
+ BFD_ASSERT (entry->fd_entry);
+ if (entry->fd_entry >= -(1 << (12 - 1))
+ && entry->fd_entry < (1 << (12 - 1)))
+ size = 8;
+ else if (entry->fd_entry >= -(1 << (16 - 1))
+ && entry->fd_entry < (1 << (16 - 1)))
+ size = 12;
+ else
+ size = 16;
+
+ frvfdpic_plt_section (dinfo->g.info)->size += size;
+ }
+
+ if (entry->lazyplt)
+ {
+ entry->lzplt_entry = dinfo->g.lzplt;
+ dinfo->g.lzplt += 8;
+ /* If this entry is the one that gets the resolver stub, account
+ for the additional instruction. */
+ if (entry->lzplt_entry % FRVFDPIC_LZPLT_BLOCK_SIZE
+ == FRVFDPIC_LZPLT_RESOLV_LOC)
+ dinfo->g.lzplt += 4;
+ }
+
+ if (entry->tlsplt)
+ {
+ int size;
+
+ entry->tlsplt_entry
+ = frvfdpic_plt_section (dinfo->g.info)->size;
+
+ if (dinfo->g.info->executable
+ && (entry->symndx != -1
+ || FRVFDPIC_SYM_LOCAL (dinfo->g.info, entry->d.h)))
+ {
+ if ((bfd_signed_vma)entry->addend >= -(1 << (16 - 1))
+ /* FIXME: here we use the size of the TLS section
+ as an upper bound for the value of the TLS
+ symbol, because we may not know the exact value
+ yet. If we get it wrong, we'll just waste a
+ word in the PLT, and we should never get even
+ close to 32 KiB of TLS anyway. */
+ && elf_hash_table (dinfo->g.info)->tls_sec
+ && (elf_hash_table (dinfo->g.info)->tls_sec->size
+ + (bfd_signed_vma)(entry->addend) <= (1 << (16 - 1))))
+ size = 8;
+ else
+ size = 12;
+ }
+ else if (entry->tlsoff_entry)
+ {
+ if (entry->tlsoff_entry >= -(1 << (12 - 1))
+ && entry->tlsoff_entry < (1 << (12 - 1)))
+ size = 8;
+ else if (entry->tlsoff_entry >= -(1 << (16 - 1))
+ && entry->tlsoff_entry < (1 << (16 - 1)))
+ size = 12;
+ else
+ size = 16;
+ }
+ else
+ {
+ BFD_ASSERT (entry->tlsdesc_entry);
+
+ if (entry->tlsdesc_entry >= -(1 << (12 - 1))
+ && entry->tlsdesc_entry < (1 << (12 - 1)))
+ size = 8;
+ else if (entry->tlsdesc_entry >= -(1 << (16 - 1))
+ && entry->tlsdesc_entry < (1 << (16 - 1)))
+ size = 12;
+ else
+ size = 16;
+ }
+
+ frvfdpic_plt_section (dinfo->g.info)->size += size;
+ }
+
+ return 1;
+}
+
+/* Cancel out any effects of calling _frvfdpic_assign_got_entries and
+ _frvfdpic_assign_plt_entries. */
+
+static int
+_frvfdpic_reset_got_plt_entries (void **entryp, void *ignore ATTRIBUTE_UNUSED)
+{
+ struct frvfdpic_relocs_info *entry = *entryp;
+
+ entry->got_entry = 0;
+ entry->fdgot_entry = 0;
+ entry->fd_entry = 0;
+ entry->plt_entry = (bfd_vma)-1;
+ entry->lzplt_entry = (bfd_vma)-1;
+ entry->tlsoff_entry = 0;
+ entry->tlsdesc_entry = 0;
+ entry->tlsplt_entry = (bfd_vma)-1;
+
+ return 1;
+}
+
+/* Follow indirect and warning hash entries so that each got entry
+ points to the final symbol definition. P must point to a pointer
+ to the hash table we're traversing. Since this traversal may
+ modify the hash table, we set this pointer to NULL to indicate
+ we've made a potentially-destructive change to the hash table, so
+ the traversal must be restarted. */
+static int
+_frvfdpic_resolve_final_relocs_info (void **entryp, void *p)
+{
+ struct frvfdpic_relocs_info *entry = *entryp;
+ htab_t *htab = p;
+
+ if (entry->symndx == -1)
+ {
+ struct elf_link_hash_entry *h = entry->d.h;
+ struct frvfdpic_relocs_info *oentry;
+
+ 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 (entry->d.h == h)
+ return 1;
+
+ oentry = frvfdpic_relocs_info_for_global (*htab, 0, h, entry->addend,
+ NO_INSERT);
+
+ if (oentry)
+ {
+ /* Merge the two entries. */
+ frvfdpic_pic_merge_early_relocs_info (oentry, entry);
+ htab_clear_slot (*htab, entryp);
+ return 1;
+ }
+
+ entry->d.h = h;
+
+ /* If we can't find this entry with the new bfd hash, re-insert
+ it, and get the traversal restarted. */
+ if (! htab_find (*htab, entry))
+ {
+ htab_clear_slot (*htab, entryp);
+ entryp = htab_find_slot (*htab, entry, INSERT);
+ if (! *entryp)
+ *entryp = entry;
+ /* Abort the traversal, since the whole table may have
+ moved, and leave it up to the parent to restart the
+ process. */
+ *(htab_t *)p = NULL;
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
+/* Compute the total size of the GOT, the PLT, the dynamic relocations
+ section and the rofixup section. Assign locations for GOT and PLT
+ entries. */
+
+static bfd_boolean
+_frvfdpic_size_got_plt (bfd *output_bfd,
+ struct _frvfdpic_dynamic_got_plt_info *gpinfop)
+{
+ bfd_signed_vma odd;
+ bfd_vma limit, tlslimit;
+ struct bfd_link_info *info = gpinfop->g.info;
+ bfd *dynobj = elf_hash_table (info)->dynobj;
+
+ memcpy (frvfdpic_dynamic_got_plt_info (info), &gpinfop->g,
+ sizeof (gpinfop->g));
+
+ odd = 12;
+ /* Compute the total size taken by entries in the 12-bit and 16-bit
+ ranges, to tell how many PLT function descriptors we can bring
+ into the 12-bit range without causing the 16-bit range to
+ overflow. */
+ limit = odd + gpinfop->g.got12 + gpinfop->g.gotlos
+ + gpinfop->g.fd12 + gpinfop->g.fdlos
+ + gpinfop->g.tlsd12 + gpinfop->g.tlsdlos;
+ if (limit < (bfd_vma)1 << 16)
+ limit = ((bfd_vma)1 << 16) - limit;
+ else
+ limit = 0;
+ if (gpinfop->g.fdplt < limit)
+ {
+ tlslimit = (limit - gpinfop->g.fdplt) & ~ (bfd_vma) 8;
+ limit = gpinfop->g.fdplt;
+ }
+ else
+ tlslimit = 0;
+ if (gpinfop->g.tlsdplt < tlslimit)
+ tlslimit = gpinfop->g.tlsdplt;
+
+ /* Determine the ranges of GOT offsets that we can use for each
+ range of addressing modes. */
+ odd = _frvfdpic_compute_got_alloc_data (&gpinfop->got12,
+ 0,
+ odd,
+ 16,
+ gpinfop->g.got12,
+ gpinfop->g.fd12,
+ limit,
+ gpinfop->g.tlsd12,
+ tlslimit,
+ (bfd_vma)1 << (12-1));
+ odd = _frvfdpic_compute_got_alloc_data (&gpinfop->gotlos,
+ gpinfop->got12.tmin,
+ odd,
+ gpinfop->got12.tmax,
+ gpinfop->g.gotlos,
+ gpinfop->g.fdlos,
+ gpinfop->g.fdplt
+ - gpinfop->got12.fdplt,
+ gpinfop->g.tlsdlos,
+ gpinfop->g.tlsdplt
+ - gpinfop->got12.tlsdplt,
+ (bfd_vma)1 << (16-1));
+ odd = _frvfdpic_compute_got_alloc_data (&gpinfop->gothilo,
+ gpinfop->gotlos.tmin,
+ odd,
+ gpinfop->gotlos.tmax,
+ gpinfop->g.gothilo,
+ gpinfop->g.fdhilo,
+ gpinfop->g.fdplt
+ - gpinfop->got12.fdplt
+ - gpinfop->gotlos.fdplt,
+ gpinfop->g.tlsdhilo,
+ gpinfop->g.tlsdplt
+ - gpinfop->got12.tlsdplt
+ - gpinfop->gotlos.tlsdplt,
+ (bfd_vma)1 << (32-1));
+
+ /* Now assign (most) GOT offsets. */
+ htab_traverse (frvfdpic_relocs_info (info), _frvfdpic_assign_got_entries,
+ gpinfop);
+
+ frvfdpic_got_section (info)->size = gpinfop->gothilo.tmax
+ - gpinfop->gothilo.tmin
+ /* If an odd word is the last word of the GOT, we don't need this
+ word to be part of the GOT. */
+ - (odd + 4 == gpinfop->gothilo.tmax ? 4 : 0);
+ if (frvfdpic_got_section (info)->size == 0)
+ frvfdpic_got_section (info)->flags |= SEC_EXCLUDE;
+ else if (frvfdpic_got_section (info)->size == 12
+ && ! elf_hash_table (info)->dynamic_sections_created)
+ {
+ frvfdpic_got_section (info)->flags |= SEC_EXCLUDE;
+ frvfdpic_got_section (info)->size = 0;
+ }
+ /* This will be non-NULL during relaxation. The assumption is that
+ the size of one of these sections will never grow, only shrink,
+ so we can use the larger buffer we allocated before. */
+ else if (frvfdpic_got_section (info)->contents == NULL)
+ {
+ frvfdpic_got_section (info)->contents =
+ (bfd_byte *) bfd_zalloc (dynobj,
+ frvfdpic_got_section (info)->size);
+ if (frvfdpic_got_section (info)->contents == NULL)
+ return FALSE;
+ }
+
+ if (frvfdpic_gotrel_section (info))
+ /* Subtract the number of lzplt entries, since those will generate
+ relocations in the pltrel section. */
+ frvfdpic_gotrel_section (info)->size =
+ (gpinfop->g.relocs - gpinfop->g.lzplt / 8)
+ * get_elf_backend_data (output_bfd)->s->sizeof_rel;
+ else
+ BFD_ASSERT (gpinfop->g.relocs == 0);
+ if (frvfdpic_gotrel_section (info)->size == 0)
+ frvfdpic_gotrel_section (info)->flags |= SEC_EXCLUDE;
+ else if (frvfdpic_gotrel_section (info)->contents == NULL)
+ {
+ frvfdpic_gotrel_section (info)->contents =
+ (bfd_byte *) bfd_zalloc (dynobj,
+ frvfdpic_gotrel_section (info)->size);
+ if (frvfdpic_gotrel_section (info)->contents == NULL)
+ return FALSE;
+ }
+
+ frvfdpic_gotfixup_section (info)->size = (gpinfop->g.fixups + 1) * 4;
+ if (frvfdpic_gotfixup_section (info)->size == 0)
+ frvfdpic_gotfixup_section (info)->flags |= SEC_EXCLUDE;
+ else if (frvfdpic_gotfixup_section (info)->contents == NULL)
+ {
+ frvfdpic_gotfixup_section (info)->contents =
+ (bfd_byte *) bfd_zalloc (dynobj,
+ frvfdpic_gotfixup_section (info)->size);
+ if (frvfdpic_gotfixup_section (info)->contents == NULL)
+ return FALSE;
+ }
+
+ if (frvfdpic_pltrel_section (info))
+ {
+ frvfdpic_pltrel_section (info)->size =
+ gpinfop->g.lzplt / 8
+ * get_elf_backend_data (output_bfd)->s->sizeof_rel;
+ if (frvfdpic_pltrel_section (info)->size == 0)
+ frvfdpic_pltrel_section (info)->flags |= SEC_EXCLUDE;
+ else if (frvfdpic_pltrel_section (info)->contents == NULL)
+ {
+ frvfdpic_pltrel_section (info)->contents =
+ (bfd_byte *) bfd_zalloc (dynobj,
+ frvfdpic_pltrel_section (info)->size);
+ if (frvfdpic_pltrel_section (info)->contents == NULL)
+ return FALSE;
+ }
+ }
+
+ /* Add 4 bytes for every block of at most 65535 lazy PLT entries,
+ such that there's room for the additional instruction needed to
+ call the resolver. Since _frvfdpic_assign_got_entries didn't
+ account for them, our block size is 4 bytes smaller than the real
+ block size. */
+ if (frvfdpic_plt_section (info))
+ {
+ frvfdpic_plt_section (info)->size = gpinfop->g.lzplt
+ + ((gpinfop->g.lzplt + (FRVFDPIC_LZPLT_BLOCK_SIZE - 4) - 8)
+ / (FRVFDPIC_LZPLT_BLOCK_SIZE - 4) * 4);
+ }
+
+ /* Reset it, such that _frvfdpic_assign_plt_entries() can use it to
+ actually assign lazy PLT entries addresses. */
+ gpinfop->g.lzplt = 0;
+
+ /* Save information that we're going to need to generate GOT and PLT
+ entries. */
+ frvfdpic_got_initial_offset (info) = -gpinfop->gothilo.tmin;
+
+ if (get_elf_backend_data (output_bfd)->want_got_sym)
+ elf_hash_table (info)->hgot->root.u.def.value
+ = frvfdpic_got_initial_offset (info);
+
+ if (frvfdpic_plt_section (info))
+ frvfdpic_plt_initial_offset (info) =
+ frvfdpic_plt_section (info)->size;
+
+ /* Allocate a ret statement at plt_initial_offset, to be used by
+ locally-resolved TLS descriptors. */
+ if (gpinfop->g.tls_ret_refs)
+ frvfdpic_plt_section (info)->size += 4;
+
+ htab_traverse (frvfdpic_relocs_info (info), _frvfdpic_assign_plt_entries,
+ gpinfop);
+
+ /* Allocate the PLT section contents only after
+ _frvfdpic_assign_plt_entries has a chance to add the size of the
+ non-lazy PLT entries. */
+ if (frvfdpic_plt_section (info))
+ {
+ if (frvfdpic_plt_section (info)->size == 0)
+ frvfdpic_plt_section (info)->flags |= SEC_EXCLUDE;
+ else if (frvfdpic_plt_section (info)->contents == NULL)
+ {
+ frvfdpic_plt_section (info)->contents =
+ (bfd_byte *) bfd_zalloc (dynobj,
+ frvfdpic_plt_section (info)->size);
+ if (frvfdpic_plt_section (info)->contents == NULL)
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+/* Set the sizes of the dynamic sections. */
+
+static bfd_boolean
+elf32_frvfdpic_size_dynamic_sections (bfd *output_bfd,
+ struct bfd_link_info *info)
+{
+ bfd *dynobj;
+ asection *s;
+ struct _frvfdpic_dynamic_got_plt_info gpinfo;
+
+ 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->executable)
+ {
+ s = bfd_get_linker_section (dynobj, ".interp");
+ BFD_ASSERT (s != NULL);
+ s->size = sizeof ELF_DYNAMIC_INTERPRETER;
+ s->contents = (bfd_byte *) ELF_DYNAMIC_INTERPRETER;
+ }
+ }
+
+ memset (&gpinfo, 0, sizeof (gpinfo));
+ gpinfo.g.info = info;
+
+ for (;;)
+ {
+ htab_t relocs = frvfdpic_relocs_info (info);
+
+ htab_traverse (relocs, _frvfdpic_resolve_final_relocs_info, &relocs);
+
+ if (relocs == frvfdpic_relocs_info (info))
+ break;
+ }
+
+ htab_traverse (frvfdpic_relocs_info (info), _frvfdpic_count_got_plt_entries,
+ &gpinfo.g);
+
+ /* Allocate space to save the summary information, we're going to
+ use it if we're doing relaxations. */
+ frvfdpic_dynamic_got_plt_info (info) = bfd_alloc (dynobj, sizeof (gpinfo.g));
+
+ if (!_frvfdpic_size_got_plt (output_bfd, &gpinfo))
+ return FALSE;
+
+ if (elf_hash_table (info)->dynamic_sections_created)
+ {
+ if (frvfdpic_got_section (info)->size)
+ if (!_bfd_elf_add_dynamic_entry (info, DT_PLTGOT, 0))
+ return FALSE;
+
+ if (frvfdpic_pltrel_section (info)->size)
+ if (!_bfd_elf_add_dynamic_entry (info, DT_PLTRELSZ, 0)
+ || !_bfd_elf_add_dynamic_entry (info, DT_PLTREL, DT_REL)
+ || !_bfd_elf_add_dynamic_entry (info, DT_JMPREL, 0))
+ return FALSE;
+
+ if (frvfdpic_gotrel_section (info)->size)
+ if (!_bfd_elf_add_dynamic_entry (info, DT_REL, 0)
+ || !_bfd_elf_add_dynamic_entry (info, DT_RELSZ, 0)
+ || !_bfd_elf_add_dynamic_entry (info, DT_RELENT,
+ sizeof (Elf32_External_Rel)))
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static bfd_boolean
+elf32_frvfdpic_always_size_sections (bfd *output_bfd,
+ struct bfd_link_info *info)
+{
+ if (!info->relocatable
+ && !bfd_elf_stack_segment_size (output_bfd, info,
+ "__stacksize", DEFAULT_STACK_SIZE))
+ return FALSE;
+
+ return TRUE;
+}
+
+/* Check whether any of the relocations was optimized away, and
+ subtract it from the relocation or fixup count. */
+static bfd_boolean
+_frvfdpic_check_discarded_relocs (bfd *abfd, asection *sec,
+ struct bfd_link_info *info,
+
+ bfd_boolean *changed)
+{
+ Elf_Internal_Shdr *symtab_hdr;
+ struct elf_link_hash_entry **sym_hashes;
+ Elf_Internal_Rela *rel, *erel;
+
+ if ((sec->flags & SEC_RELOC) == 0
+ || sec->reloc_count == 0)
+ return TRUE;
+
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+ sym_hashes = elf_sym_hashes (abfd);
+
+ rel = elf_section_data (sec)->relocs;
+
+ /* Now examine each relocation. */
+ for (erel = rel + sec->reloc_count; rel < erel; rel++)
+ {
+ struct elf_link_hash_entry *h;
+ unsigned long r_symndx;
+ struct frvfdpic_relocs_info *picrel;
+ struct _frvfdpic_dynamic_got_info *dinfo;
+
+ if (ELF32_R_TYPE (rel->r_info) != R_FRV_32
+ && ELF32_R_TYPE (rel->r_info) != R_FRV_FUNCDESC)
+ continue;
+
+ if (_bfd_elf_section_offset (sec->output_section->owner,
+ info, sec, rel->r_offset)
+ != (bfd_vma)-1)
+ continue;
+
+ 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];
+ 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 != NULL)
+ picrel = frvfdpic_relocs_info_for_global (frvfdpic_relocs_info (info),
+ abfd, h,
+ rel->r_addend, NO_INSERT);
+ else
+ picrel = frvfdpic_relocs_info_for_local (frvfdpic_relocs_info (info),
+ abfd, r_symndx,
+ rel->r_addend, NO_INSERT);
+
+ if (! picrel)
+ return FALSE;
+
+ *changed = TRUE;
+ dinfo = frvfdpic_dynamic_got_plt_info (info);
+
+ _frvfdpic_count_relocs_fixups (picrel, dinfo, TRUE);
+ if (ELF32_R_TYPE (rel->r_info) == R_FRV_32)
+ picrel->relocs32--;
+ else /* we know (ELF32_R_TYPE (rel->r_info) == R_FRV_FUNCDESC) */
+ picrel->relocsfd--;
+ _frvfdpic_count_relocs_fixups (picrel, dinfo, FALSE);
+ }
+
+ return TRUE;
+}
+
+static bfd_boolean
+frvfdpic_elf_discard_info (bfd *ibfd,
+ struct elf_reloc_cookie *cookie ATTRIBUTE_UNUSED,
+ struct bfd_link_info *info)
+{
+ bfd_boolean changed = FALSE;
+ asection *s;
+ bfd *obfd = NULL;
+
+ /* Account for relaxation of .eh_frame section. */
+ for (s = ibfd->sections; s; s = s->next)
+ if (s->sec_info_type == SEC_INFO_TYPE_EH_FRAME)
+ {
+ if (!_frvfdpic_check_discarded_relocs (ibfd, s, info, &changed))
+ return FALSE;
+ obfd = s->output_section->owner;
+ }
+
+ if (changed)
+ {
+ struct _frvfdpic_dynamic_got_plt_info gpinfo;
+
+ memset (&gpinfo, 0, sizeof (gpinfo));
+ memcpy (&gpinfo.g, frvfdpic_dynamic_got_plt_info (info),
+ sizeof (gpinfo.g));
+
+ /* Clear GOT and PLT assignments. */
+ htab_traverse (frvfdpic_relocs_info (info),
+ _frvfdpic_reset_got_plt_entries,
+ NULL);
+
+ if (!_frvfdpic_size_got_plt (obfd, &gpinfo))
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/* Look for opportunities to relax TLS relocations. We can assume
+ we're linking the main executable or a static-tls library, since
+ otherwise we wouldn't have got here. */
+
+static int
+_frvfdpic_relax_got_plt_entries (void **entryp, void *dinfo_)
+{
+ struct frvfdpic_relocs_info *entry = *entryp;
+ struct _frvfdpic_dynamic_got_info *dinfo = dinfo_;
+
+ _frvfdpic_relax_tls_entries (entry, dinfo, TRUE);
+
+ return 1;
+}
+
+static bfd_boolean
+elf32_frvfdpic_relax_section (bfd *abfd ATTRIBUTE_UNUSED, asection *sec,
+ struct bfd_link_info *info, bfd_boolean *again)
+{
+ struct _frvfdpic_dynamic_got_plt_info gpinfo;
+
+ if (info->relocatable)
+ (*info->callbacks->einfo)
+ (_("%P%F: --relax and -r may not be used together\n"));
+
+ /* If we return early, we didn't change anything. */
+ *again = FALSE;
+
+ /* We'll do our thing when requested to relax the GOT section. */
+ if (sec != frvfdpic_got_section (info))
+ return TRUE;
+
+ /* We can only relax when linking the main executable or a library
+ that can't be dlopened. */
+ if (! info->executable && ! (info->flags & DF_STATIC_TLS))
+ return TRUE;
+
+ /* If there isn't a TLS section for this binary, we can't do
+ anything about its TLS relocations (it probably doesn't have
+ any. */
+ if (elf_hash_table (info)->tls_sec == NULL)
+ return TRUE;
+
+ memset (&gpinfo, 0, sizeof (gpinfo));
+ memcpy (&gpinfo.g, frvfdpic_dynamic_got_plt_info (info), sizeof (gpinfo.g));
+
+ /* Now look for opportunities to relax, adjusting the GOT usage
+ as needed. */
+ htab_traverse (frvfdpic_relocs_info (info),
+ _frvfdpic_relax_got_plt_entries,
+ &gpinfo.g);
+
+ /* If we changed anything, reset and re-assign GOT and PLT entries. */
+ if (memcmp (frvfdpic_dynamic_got_plt_info (info),
+ &gpinfo.g, sizeof (gpinfo.g)) != 0)
+ {
+ /* Clear GOT and PLT assignments. */
+ htab_traverse (frvfdpic_relocs_info (info),
+ _frvfdpic_reset_got_plt_entries,
+ NULL);
+
+ /* The owner of the TLS section is the output bfd. There should
+ be a better way to get to it. */
+ if (!_frvfdpic_size_got_plt (elf_hash_table (info)->tls_sec->owner,
+ &gpinfo))
+ return FALSE;
+
+ /* Repeat until we don't make any further changes. We could fail to
+ introduce changes in a round if, for example, the 12-bit range is
+ full, but we later release some space by getting rid of TLS
+ descriptors in it. We have to repeat the whole process because
+ we might have changed the size of a section processed before this
+ one. */
+ *again = TRUE;
+ }
+
+ return TRUE;
+}
+
+/* Fill in code and data in dynamic sections. */
+
+static bfd_boolean
+elf32_frv_finish_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED)
+{
+ /* Nothing to be done for non-FDPIC. */
+ return TRUE;
+}
+
+static bfd_boolean
+elf32_frvfdpic_finish_dynamic_sections (bfd *output_bfd,
+ struct bfd_link_info *info)
+{
+ bfd *dynobj;
+ asection *sdyn;
+
+ dynobj = elf_hash_table (info)->dynobj;
+
+ if (frvfdpic_dynamic_got_plt_info (info))
+ {
+ BFD_ASSERT (frvfdpic_dynamic_got_plt_info (info)->tls_ret_refs == 0);
+ }
+ if (frvfdpic_got_section (info))
+ {
+ BFD_ASSERT (frvfdpic_gotrel_section (info)->size
+ == (frvfdpic_gotrel_section (info)->reloc_count
+ * sizeof (Elf32_External_Rel)));
+
+ if (frvfdpic_gotfixup_section (info))
+ {
+ struct elf_link_hash_entry *hgot = elf_hash_table (info)->hgot;
+ bfd_vma got_value = hgot->root.u.def.value
+ + hgot->root.u.def.section->output_section->vma
+ + hgot->root.u.def.section->output_offset;
+ struct bfd_link_hash_entry *hend;
+
+ _frvfdpic_add_rofixup (output_bfd, frvfdpic_gotfixup_section (info),
+ got_value, 0);
+
+ if (frvfdpic_gotfixup_section (info)->size
+ != (frvfdpic_gotfixup_section (info)->reloc_count * 4))
+ {
+ error:
+ info->callbacks->einfo
+ ("LINKER BUG: .rofixup section size mismatch\n");
+ return FALSE;
+ }
+
+ hend = bfd_link_hash_lookup (info->hash, "__ROFIXUP_END__",
+ FALSE, FALSE, TRUE);
+ if (hend
+ && (hend->type == bfd_link_hash_defined
+ || hend->type == bfd_link_hash_defweak)
+ && hend->u.def.section->output_section != NULL)
+ {
+ bfd_vma value =
+ frvfdpic_gotfixup_section (info)->output_section->vma
+ + frvfdpic_gotfixup_section (info)->output_offset
+ + frvfdpic_gotfixup_section (info)->size
+ - hend->u.def.section->output_section->vma
+ - hend->u.def.section->output_offset;
+ BFD_ASSERT (hend->u.def.value == value);
+ if (hend->u.def.value != value)
+ goto error;
+ }
+ }
+ }
+ if (frvfdpic_pltrel_section (info))
+ {
+ BFD_ASSERT (frvfdpic_pltrel_section (info)->size
+ == (frvfdpic_pltrel_section (info)->reloc_count
+ * sizeof (Elf32_External_Rel)));
+ }
+
+
+ if (elf_hash_table (info)->dynamic_sections_created)
+ {
+ Elf32_External_Dyn * dyncon;
+ Elf32_External_Dyn * dynconend;
+
+ sdyn = bfd_get_linker_section (dynobj, ".dynamic");
+
+ BFD_ASSERT (sdyn != NULL);
+
+ dyncon = (Elf32_External_Dyn *) sdyn->contents;
+ dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->size);
+
+ for (; dyncon < dynconend; dyncon++)
+ {
+ Elf_Internal_Dyn dyn;
+
+ bfd_elf32_swap_dyn_in (dynobj, dyncon, &dyn);
+
+ switch (dyn.d_tag)
+ {
+ default:
+ break;
+
+ case DT_PLTGOT:
+ dyn.d_un.d_ptr = frvfdpic_got_section (info)->output_section->vma
+ + frvfdpic_got_section (info)->output_offset
+ + frvfdpic_got_initial_offset (info);
+ bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
+ break;
+
+ case DT_JMPREL:
+ dyn.d_un.d_ptr = frvfdpic_pltrel_section (info)
+ ->output_section->vma
+ + frvfdpic_pltrel_section (info)->output_offset;
+ bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
+ break;
+
+ case DT_PLTRELSZ:
+ dyn.d_un.d_val = frvfdpic_pltrel_section (info)->size;
+ bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
+ break;
+ }
+ }
+ }
+
+ return TRUE;
+}
+
+/* Adjust a symbol defined by a dynamic object and referenced by a
+ regular object. */
+
+static bfd_boolean
+elf32_frvfdpic_adjust_dynamic_symbol
+(struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ struct elf_link_hash_entry *h ATTRIBUTE_UNUSED)
+{
+ bfd * dynobj;
+
+ dynobj = elf_hash_table (info)->dynobj;
+
+ /* Make sure we know what is going on here. */
+ BFD_ASSERT (dynobj != NULL
+ && (h->u.weakdef != NULL
+ || (h->def_dynamic
+ && h->ref_regular
+ && !h->def_regular)));
+
+ /* 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->u.weakdef != NULL)
+ {
+ BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
+ || h->u.weakdef->root.type == bfd_link_hash_defweak);
+ h->root.u.def.section = h->u.weakdef->root.u.def.section;
+ h->root.u.def.value = h->u.weakdef->root.u.def.value;
+ }
+
+ return TRUE;
+}
+
+/* Perform any actions needed for dynamic symbols. */
+
+static bfd_boolean
+elf32_frvfdpic_finish_dynamic_symbol
+(bfd *output_bfd ATTRIBUTE_UNUSED,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ struct elf_link_hash_entry *h ATTRIBUTE_UNUSED,
+ Elf_Internal_Sym *sym ATTRIBUTE_UNUSED)
+{
+ return TRUE;
+}
+
+/* Decide whether to attempt to turn absptr or lsda encodings in
+ shared libraries into pcrel within the given input section. */
+
+static bfd_boolean
+frvfdpic_elf_use_relative_eh_frame
+(bfd *input_bfd ATTRIBUTE_UNUSED,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ asection *eh_frame_section ATTRIBUTE_UNUSED)
+{
+ /* We can't use PC-relative encodings in FDPIC binaries, in general. */
+ return FALSE;
+}
+
+/* Adjust the contents of an eh_frame_hdr section before they're output. */
+
+static bfd_byte
+frvfdpic_elf_encode_eh_address (bfd *abfd,
+ struct bfd_link_info *info,
+ asection *osec, bfd_vma offset,
+ asection *loc_sec, bfd_vma loc_offset,
+ bfd_vma *encoded)
+{
+ struct elf_link_hash_entry *h;
+
+ h = elf_hash_table (info)->hgot;
+ BFD_ASSERT (h && h->root.type == bfd_link_hash_defined);
+
+ if (! h || (_frvfdpic_osec_to_segment (abfd, osec)
+ == _frvfdpic_osec_to_segment (abfd, loc_sec->output_section)))
+ return _bfd_elf_encode_eh_address (abfd, info, osec, offset,
+ loc_sec, loc_offset, encoded);
+
+ BFD_ASSERT (_frvfdpic_osec_to_segment (abfd, osec)
+ == (_frvfdpic_osec_to_segment
+ (abfd, h->root.u.def.section->output_section)));
+
+ *encoded = osec->vma + offset
+ - (h->root.u.def.value
+ + h->root.u.def.section->output_section->vma
+ + h->root.u.def.section->output_offset);
+
+ return DW_EH_PE_datarel | DW_EH_PE_sdata4;
+}
+
+/* Look through the relocs for a section during the first phase.
+
+ Besides handling virtual table relocs for gc, we have to deal with
+ all sorts of PIC-related relocations. We describe below the
+ general plan on how to handle such relocations, even though we only
+ collect information at this point, storing them in hash tables for
+ perusal of later passes.
+
+ 32 relocations are propagated to the linker output when creating
+ position-independent output. LO16 and HI16 relocations are not
+ supposed to be encountered in this case.
+
+ LABEL16 should always be resolvable by the linker, since it's only
+ used by branches.
+
+ LABEL24, on the other hand, is used by calls. If it turns out that
+ the target of a call is a dynamic symbol, a PLT entry must be
+ created for it, which triggers the creation of a private function
+ descriptor and, unless lazy binding is disabled, a lazy PLT entry.
+
+ GPREL relocations require the referenced symbol to be in the same
+ segment as _gp, but this can only be checked later.
+
+ All GOT, GOTOFF and FUNCDESC relocations require a .got section to
+ exist. LABEL24 might as well, since it may require a PLT entry,
+ that will require a got.
+
+ Non-FUNCDESC GOT relocations require a GOT entry to be created
+ regardless of whether the symbol is dynamic. However, since a
+ global symbol that turns out to not be exported may have the same
+ address of a non-dynamic symbol, we don't assign GOT entries at
+ this point, such that we can share them in this case. A relocation
+ for the GOT entry always has to be created, be it to offset a
+ private symbol by the section load address, be it to get the symbol
+ resolved dynamically.
+
+ FUNCDESC GOT relocations require a GOT entry to be created, and
+ handled as if a FUNCDESC relocation was applied to the GOT entry in
+ an object file.
+
+ FUNCDESC relocations referencing a symbol that turns out to NOT be
+ dynamic cause a private function descriptor to be created. The
+ FUNCDESC relocation then decays to a 32 relocation that points at
+ the private descriptor. If the symbol is dynamic, the FUNCDESC
+ relocation is propagated to the linker output, such that the
+ dynamic linker creates the canonical descriptor, pointing to the
+ dynamically-resolved definition of the function.
+
+ Non-FUNCDESC GOTOFF relocations must always refer to non-dynamic
+ symbols that are assigned to the same segment as the GOT, but we
+ can only check this later, after we know the complete set of
+ symbols defined and/or exported.
+
+ FUNCDESC GOTOFF relocations require a function descriptor to be
+ created and, unless lazy binding is disabled or the symbol is not
+ dynamic, a lazy PLT entry. Since we can't tell at this point
+ whether a symbol is going to be dynamic, we have to decide later
+ whether to create a lazy PLT entry or bind the descriptor directly
+ to the private function.
+
+ FUNCDESC_VALUE relocations are not supposed to be present in object
+ files, but they may very well be simply propagated to the linker
+ output, since they have no side effect.
+
+
+ A function descriptor always requires a FUNCDESC_VALUE relocation.
+ Whether it's in .plt.rel or not depends on whether lazy binding is
+ enabled and on whether the referenced symbol is dynamic.
+
+ The existence of a lazy PLT requires the resolverStub lazy PLT
+ entry to be present.
+
+
+ As for assignment of GOT, PLT and lazy PLT entries, and private
+ descriptors, we might do them all sequentially, but we can do
+ better than that. For example, we can place GOT entries and
+ private function descriptors referenced using 12-bit operands
+ closer to the PIC register value, such that these relocations don't
+ overflow. Those that are only referenced with LO16 relocations
+ could come next, but we may as well place PLT-required function
+ descriptors in the 12-bit range to make them shorter. Symbols
+ referenced with LO16/HI16 may come next, but we may place
+ additional function descriptors in the 16-bit range if we can
+ reliably tell that we've already placed entries that are ever
+ referenced with only LO16. PLT entries are therefore generated as
+ small as possible, while not introducing relocation overflows in
+ GOT or FUNCDESC_GOTOFF relocations. Lazy PLT entries could be
+ generated before or after PLT entries, but not intermingled with
+ them, such that we can have more lazy PLT entries in range for a
+ branch to the resolverStub. The resolverStub should be emitted at
+ the most distant location from the first lazy PLT entry such that
+ it's still in range for a branch, or closer, if there isn't a need
+ for so many lazy PLT entries. Additional lazy PLT entries may be
+ emitted after the resolverStub, as long as branches are still in
+ range. If the branch goes out of range, longer lazy PLT entries
+ are emitted.
+
+ We could further optimize PLT and lazy PLT entries by giving them
+ priority in assignment to closer-to-gr17 locations depending on the
+ number of occurrences of references to them (assuming a function
+ that's called more often is more important for performance, so its
+ PLT entry should be faster), or taking hints from the compiler.
+ Given infinite time and money... :-) */
+
+static bfd_boolean
+elf32_frv_check_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;
+ const Elf_Internal_Rela *rel;
+ const Elf_Internal_Rela *rel_end;
+ bfd *dynobj;
+ struct frvfdpic_relocs_info *picrel;
+
+ if (info->relocatable)
+ return TRUE;
+
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+ sym_hashes = elf_sym_hashes (abfd);
+
+ dynobj = elf_hash_table (info)->dynobj;
+ 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];
+ 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;
+
+ /* PR15323, ref flags aren't set for references in the same
+ object. */
+ h->root.non_ir_ref = 1;
+ }
+
+ switch (ELF32_R_TYPE (rel->r_info))
+ {
+ case R_FRV_GETTLSOFF:
+ case R_FRV_TLSDESC_VALUE:
+ case R_FRV_GOTTLSDESC12:
+ case R_FRV_GOTTLSDESCHI:
+ case R_FRV_GOTTLSDESCLO:
+ case R_FRV_GOTTLSOFF12:
+ case R_FRV_GOTTLSOFFHI:
+ case R_FRV_GOTTLSOFFLO:
+ case R_FRV_TLSOFF:
+ case R_FRV_GOT12:
+ case R_FRV_GOTHI:
+ case R_FRV_GOTLO:
+ case R_FRV_FUNCDESC_GOT12:
+ case R_FRV_FUNCDESC_GOTHI:
+ case R_FRV_FUNCDESC_GOTLO:
+ case R_FRV_GOTOFF12:
+ case R_FRV_GOTOFFHI:
+ case R_FRV_GOTOFFLO:
+ case R_FRV_FUNCDESC_GOTOFF12:
+ case R_FRV_FUNCDESC_GOTOFFHI:
+ case R_FRV_FUNCDESC_GOTOFFLO:
+ case R_FRV_FUNCDESC:
+ case R_FRV_FUNCDESC_VALUE:
+ case R_FRV_TLSMOFF12:
+ case R_FRV_TLSMOFFHI:
+ case R_FRV_TLSMOFFLO:
+ case R_FRV_TLSMOFF:
+ if (! IS_FDPIC (abfd))
+ goto bad_reloc;
+ /* Fall through. */
+ case R_FRV_GPREL12:
+ case R_FRV_GPRELU12:
+ case R_FRV_GPRELHI:
+ case R_FRV_GPRELLO:
+ case R_FRV_LABEL24:
+ case R_FRV_32:
+ if (! dynobj)
+ {
+ elf_hash_table (info)->dynobj = dynobj = abfd;
+ if (! _frv_create_got_section (abfd, info))
+ return FALSE;
+ }
+ if (! IS_FDPIC (abfd))
+ {
+ picrel = NULL;
+ break;
+ }
+ if (h != NULL)
+ {
+ if (h->dynindx == -1)
+ switch (ELF_ST_VISIBILITY (h->other))
+ {
+ case STV_INTERNAL:
+ case STV_HIDDEN:
+ break;
+ default:
+ bfd_elf_link_record_dynamic_symbol (info, h);
+ break;
+ }
+ picrel
+ = frvfdpic_relocs_info_for_global (frvfdpic_relocs_info (info),
+ abfd, h,
+ rel->r_addend, INSERT);
+ }
+ else
+ picrel = frvfdpic_relocs_info_for_local (frvfdpic_relocs_info
+ (info), abfd, r_symndx,
+ rel->r_addend, INSERT);
+ if (! picrel)
+ return FALSE;
+ break;
+
+ default:
+ picrel = NULL;
+ break;
+ }
+
+ switch (ELF32_R_TYPE (rel->r_info))
+ {
+ case R_FRV_LABEL24:
+ if (IS_FDPIC (abfd))
+ picrel->call = 1;
+ break;
+
+ case R_FRV_FUNCDESC_VALUE:
+ picrel->relocsfdv++;
+ if (bfd_get_section_flags (abfd, sec) & SEC_ALLOC)
+ picrel->relocs32--;
+ /* Fall through. */
+
+ case R_FRV_32:
+ if (! IS_FDPIC (abfd))
+ break;
+
+ picrel->sym = 1;
+ if (bfd_get_section_flags (abfd, sec) & SEC_ALLOC)
+ picrel->relocs32++;
+ break;
+
+ case R_FRV_GOT12:
+ picrel->got12 = 1;
+ break;
+
+ case R_FRV_GOTHI:
+ case R_FRV_GOTLO:
+ picrel->gothilo = 1;
+ break;
+
+ case R_FRV_FUNCDESC_GOT12:
+ picrel->fdgot12 = 1;
+ break;
+
+ case R_FRV_FUNCDESC_GOTHI:
+ case R_FRV_FUNCDESC_GOTLO:
+ picrel->fdgothilo = 1;
+ break;
+
+ case R_FRV_GOTOFF12:
+ case R_FRV_GOTOFFHI:
+ case R_FRV_GOTOFFLO:
+ picrel->gotoff = 1;
+ break;
+
+ case R_FRV_FUNCDESC_GOTOFF12:
+ picrel->fdgoff12 = 1;
+ break;
+
+ case R_FRV_FUNCDESC_GOTOFFHI:
+ case R_FRV_FUNCDESC_GOTOFFLO:
+ picrel->fdgoffhilo = 1;
+ break;
+
+ case R_FRV_FUNCDESC:
+ picrel->fd = 1;
+ picrel->relocsfd++;
+ break;
+
+ case R_FRV_GETTLSOFF:
+ picrel->tlsplt = 1;
+ break;
+
+ case R_FRV_TLSDESC_VALUE:
+ picrel->relocstlsd++;
+ goto bad_reloc;
+
+ case R_FRV_GOTTLSDESC12:
+ picrel->tlsdesc12 = 1;
+ break;
+
+ case R_FRV_GOTTLSDESCHI:
+ case R_FRV_GOTTLSDESCLO:
+ picrel->tlsdeschilo = 1;
+ break;
+
+ case R_FRV_TLSMOFF12:
+ case R_FRV_TLSMOFFHI:
+ case R_FRV_TLSMOFFLO:
+ case R_FRV_TLSMOFF:
+ break;
+
+ case R_FRV_GOTTLSOFF12:
+ picrel->tlsoff12 = 1;
+ info->flags |= DF_STATIC_TLS;
+ break;
+
+ case R_FRV_GOTTLSOFFHI:
+ case R_FRV_GOTTLSOFFLO:
+ picrel->tlsoffhilo = 1;
+ info->flags |= DF_STATIC_TLS;
+ break;
+
+ case R_FRV_TLSOFF:
+ picrel->relocstlsoff++;
+ info->flags |= DF_STATIC_TLS;
+ goto bad_reloc;
+
+ /* This relocation describes the C++ object vtable hierarchy.
+ Reconstruct it for later use during GC. */
+ case R_FRV_GNU_VTINHERIT:
+ if (!bfd_elf_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_FRV_GNU_VTENTRY:
+ BFD_ASSERT (h != NULL);
+ if (h != NULL
+ && !bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
+ return FALSE;
+ break;
+
+ case R_FRV_LABEL16:
+ case R_FRV_LO16:
+ case R_FRV_HI16:
+ case R_FRV_GPREL12:
+ case R_FRV_GPRELU12:
+ case R_FRV_GPREL32:
+ case R_FRV_GPRELHI:
+ case R_FRV_GPRELLO:
+ case R_FRV_TLSDESC_RELAX:
+ case R_FRV_GETTLSOFF_RELAX:
+ case R_FRV_TLSOFF_RELAX:
+ break;
+
+ default:
+ bad_reloc:
+ info->callbacks->einfo
+ (_("%B: unsupported relocation type %i\n"),
+ abfd, ELF32_R_TYPE (rel->r_info));
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+
+/* Return the machine subcode from the ELF e_flags header. */
+
+static int
+elf32_frv_machine (bfd *abfd)
+{
+ switch (elf_elfheader (abfd)->e_flags & EF_FRV_CPU_MASK)
+ {
+ default: break;
+ case EF_FRV_CPU_FR550: return bfd_mach_fr550;
+ case EF_FRV_CPU_FR500: return bfd_mach_fr500;
+ case EF_FRV_CPU_FR450: return bfd_mach_fr450;
+ case EF_FRV_CPU_FR405: return bfd_mach_fr400;
+ case EF_FRV_CPU_FR400: return bfd_mach_fr400;
+ case EF_FRV_CPU_FR300: return bfd_mach_fr300;
+ case EF_FRV_CPU_SIMPLE: return bfd_mach_frvsimple;
+ case EF_FRV_CPU_TOMCAT: return bfd_mach_frvtomcat;
+ }
+
+ return bfd_mach_frv;
+}
+
+/* Set the right machine number for a FRV ELF file. */
+
+static bfd_boolean
+elf32_frv_object_p (bfd *abfd)
+{
+ bfd_default_set_arch_mach (abfd, bfd_arch_frv, elf32_frv_machine (abfd));
+ return (((elf_elfheader (abfd)->e_flags & EF_FRV_FDPIC) != 0)
+ == (IS_FDPIC (abfd)));
+}
+
+/* Function to set the ELF flag bits. */
+
+static bfd_boolean
+frv_elf_set_private_flags (bfd *abfd, flagword flags)
+{
+ elf_elfheader (abfd)->e_flags = flags;
+ elf_flags_init (abfd) = TRUE;
+ return TRUE;
+}
+
+/* Return true if the architecture described by elf header flag
+ EXTENSION is an extension of the architecture described by BASE. */
+
+static bfd_boolean
+frv_elf_arch_extension_p (flagword base, flagword extension)
+{
+ if (base == extension)
+ return TRUE;
+
+ /* CPU_GENERIC code can be merged with code for a specific
+ architecture, in which case the result is marked as being
+ for the specific architecture. Everything is therefore
+ an extension of CPU_GENERIC. */
+ if (base == EF_FRV_CPU_GENERIC)
+ return TRUE;
+
+ if (extension == EF_FRV_CPU_FR450)
+ if (base == EF_FRV_CPU_FR400 || base == EF_FRV_CPU_FR405)
+ return TRUE;
+
+ if (extension == EF_FRV_CPU_FR405)
+ if (base == EF_FRV_CPU_FR400)
+ return TRUE;
+
+ return FALSE;
+}
+
+/* Merge backend specific data from an object file to the output
+ object file when linking. */
+
+static bfd_boolean
+frv_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
+{
+ flagword old_flags, old_partial;
+ flagword new_flags, new_partial;
+ bfd_boolean error = FALSE;
+ char new_opt[80];
+ char old_opt[80];
+
+ new_opt[0] = old_opt[0] = '\0';
+ new_flags = elf_elfheader (ibfd)->e_flags;
+ old_flags = elf_elfheader (obfd)->e_flags;
+
+ if (new_flags & EF_FRV_FDPIC)
+ new_flags &= ~EF_FRV_PIC;
+
+#ifdef DEBUG
+ (*_bfd_error_handler) ("old_flags = 0x%.8lx, new_flags = 0x%.8lx, init = %s, filename = %s",
+ old_flags, new_flags, elf_flags_init (obfd) ? "yes" : "no",
+ bfd_get_filename (ibfd));
+#endif
+
+ if (!elf_flags_init (obfd)) /* First call, no flags set. */
+ {
+ elf_flags_init (obfd) = TRUE;
+ old_flags = new_flags;
+ }
+
+ else if (new_flags == old_flags) /* Compatible flags are ok. */
+ ;
+
+ else /* Possibly incompatible flags. */
+ {
+ /* Warn if different # of gprs are used. Note, 0 means nothing is
+ said about the size of gprs. */
+ new_partial = (new_flags & EF_FRV_GPR_MASK);
+ old_partial = (old_flags & EF_FRV_GPR_MASK);
+ if (new_partial == old_partial)
+ ;
+
+ else if (new_partial == 0)
+ ;
+
+ else if (old_partial == 0)
+ old_flags |= new_partial;
+
+ else
+ {
+ switch (new_partial)
+ {
+ default: strcat (new_opt, " -mgpr-??"); break;
+ case EF_FRV_GPR_32: strcat (new_opt, " -mgpr-32"); break;
+ case EF_FRV_GPR_64: strcat (new_opt, " -mgpr-64"); break;
+ }
+
+ switch (old_partial)
+ {
+ default: strcat (old_opt, " -mgpr-??"); break;
+ case EF_FRV_GPR_32: strcat (old_opt, " -mgpr-32"); break;
+ case EF_FRV_GPR_64: strcat (old_opt, " -mgpr-64"); break;
+ }
+ }
+
+ /* Warn if different # of fprs are used. Note, 0 means nothing is
+ said about the size of fprs. */
+ new_partial = (new_flags & EF_FRV_FPR_MASK);
+ old_partial = (old_flags & EF_FRV_FPR_MASK);
+ if (new_partial == old_partial)
+ ;
+
+ else if (new_partial == 0)
+ ;
+
+ else if (old_partial == 0)
+ old_flags |= new_partial;
+
+ else
+ {
+ switch (new_partial)
+ {
+ default: strcat (new_opt, " -mfpr-?"); break;
+ case EF_FRV_FPR_32: strcat (new_opt, " -mfpr-32"); break;
+ case EF_FRV_FPR_64: strcat (new_opt, " -mfpr-64"); break;
+ case EF_FRV_FPR_NONE: strcat (new_opt, " -msoft-float"); break;
+ }
+
+ switch (old_partial)
+ {
+ default: strcat (old_opt, " -mfpr-?"); break;
+ case EF_FRV_FPR_32: strcat (old_opt, " -mfpr-32"); break;
+ case EF_FRV_FPR_64: strcat (old_opt, " -mfpr-64"); break;
+ case EF_FRV_FPR_NONE: strcat (old_opt, " -msoft-float"); break;
+ }
+ }
+
+ /* Warn if different dword support was used. Note, 0 means nothing is
+ said about the dword support. */
+ new_partial = (new_flags & EF_FRV_DWORD_MASK);
+ old_partial = (old_flags & EF_FRV_DWORD_MASK);
+ if (new_partial == old_partial)
+ ;
+
+ else if (new_partial == 0)
+ ;
+
+ else if (old_partial == 0)
+ old_flags |= new_partial;
+
+ else
+ {
+ switch (new_partial)
+ {
+ default: strcat (new_opt, " -mdword-?"); break;
+ case EF_FRV_DWORD_YES: strcat (new_opt, " -mdword"); break;
+ case EF_FRV_DWORD_NO: strcat (new_opt, " -mno-dword"); break;
+ }
+
+ switch (old_partial)
+ {
+ default: strcat (old_opt, " -mdword-?"); break;
+ case EF_FRV_DWORD_YES: strcat (old_opt, " -mdword"); break;
+ case EF_FRV_DWORD_NO: strcat (old_opt, " -mno-dword"); break;
+ }
+ }
+
+ /* Or in flags that accumulate (ie, if one module uses it, mark that the
+ feature is used. */
+ old_flags |= new_flags & (EF_FRV_DOUBLE
+ | EF_FRV_MEDIA
+ | EF_FRV_MULADD
+ | EF_FRV_NON_PIC_RELOCS);
+
+ /* If any module was compiled without -G0, clear the G0 bit. */
+ old_flags = ((old_flags & ~ EF_FRV_G0)
+ | (old_flags & new_flags & EF_FRV_G0));
+
+ /* If any module was compiled without -mnopack, clear the mnopack bit. */
+ old_flags = ((old_flags & ~ EF_FRV_NOPACK)
+ | (old_flags & new_flags & EF_FRV_NOPACK));
+
+ /* We don't have to do anything if the pic flags are the same, or the new
+ module(s) were compiled with -mlibrary-pic. */
+ new_partial = (new_flags & EF_FRV_PIC_FLAGS);
+ old_partial = (old_flags & EF_FRV_PIC_FLAGS);
+ if ((new_partial == old_partial) || ((new_partial & EF_FRV_LIBPIC) != 0))
+ ;
+
+ /* If the old module(s) were compiled with -mlibrary-pic, copy in the pic
+ flags if any from the new module. */
+ else if ((old_partial & EF_FRV_LIBPIC) != 0)
+ old_flags = (old_flags & ~ EF_FRV_PIC_FLAGS) | new_partial;
+
+ /* If we have mixtures of -fpic and -fPIC, or in both bits. */
+ else if (new_partial != 0 && old_partial != 0)
+ old_flags |= new_partial;
+
+ /* One module was compiled for pic and the other was not, see if we have
+ had any relocations that are not pic-safe. */
+ else
+ {
+ if ((old_flags & EF_FRV_NON_PIC_RELOCS) == 0)
+ old_flags |= new_partial;
+ else
+ {
+ old_flags &= ~ EF_FRV_PIC_FLAGS;
+#ifndef FRV_NO_PIC_ERROR
+ error = TRUE;
+ (*_bfd_error_handler)
+ (_("%s: compiled with %s and linked with modules that use non-pic relocations"),
+ bfd_get_filename (ibfd),
+ (new_flags & EF_FRV_BIGPIC) ? "-fPIC" : "-fpic");
+#endif
+ }
+ }
+
+ /* Warn if different cpu is used (allow a specific cpu to override
+ the generic cpu). */
+ new_partial = (new_flags & EF_FRV_CPU_MASK);
+ old_partial = (old_flags & EF_FRV_CPU_MASK);
+ if (frv_elf_arch_extension_p (new_partial, old_partial))
+ ;
+
+ else if (frv_elf_arch_extension_p (old_partial, new_partial))
+ old_flags = (old_flags & ~EF_FRV_CPU_MASK) | new_partial;
+
+ else
+ {
+ switch (new_partial)
+ {
+ default: strcat (new_opt, " -mcpu=?"); break;
+ case EF_FRV_CPU_GENERIC: strcat (new_opt, " -mcpu=frv"); break;
+ case EF_FRV_CPU_SIMPLE: strcat (new_opt, " -mcpu=simple"); break;
+ case EF_FRV_CPU_FR550: strcat (new_opt, " -mcpu=fr550"); break;
+ case EF_FRV_CPU_FR500: strcat (new_opt, " -mcpu=fr500"); break;
+ case EF_FRV_CPU_FR450: strcat (new_opt, " -mcpu=fr450"); break;
+ case EF_FRV_CPU_FR405: strcat (new_opt, " -mcpu=fr405"); break;
+ case EF_FRV_CPU_FR400: strcat (new_opt, " -mcpu=fr400"); break;
+ case EF_FRV_CPU_FR300: strcat (new_opt, " -mcpu=fr300"); break;
+ case EF_FRV_CPU_TOMCAT: strcat (new_opt, " -mcpu=tomcat"); break;
+ }
+
+ switch (old_partial)
+ {
+ default: strcat (old_opt, " -mcpu=?"); break;
+ case EF_FRV_CPU_GENERIC: strcat (old_opt, " -mcpu=frv"); break;
+ case EF_FRV_CPU_SIMPLE: strcat (old_opt, " -mcpu=simple"); break;
+ case EF_FRV_CPU_FR550: strcat (old_opt, " -mcpu=fr550"); break;
+ case EF_FRV_CPU_FR500: strcat (old_opt, " -mcpu=fr500"); break;
+ case EF_FRV_CPU_FR450: strcat (old_opt, " -mcpu=fr450"); break;
+ case EF_FRV_CPU_FR405: strcat (old_opt, " -mcpu=fr405"); break;
+ case EF_FRV_CPU_FR400: strcat (old_opt, " -mcpu=fr400"); break;
+ case EF_FRV_CPU_FR300: strcat (old_opt, " -mcpu=fr300"); break;
+ case EF_FRV_CPU_TOMCAT: strcat (old_opt, " -mcpu=tomcat"); break;
+ }
+ }
+
+ /* Print out any mismatches from above. */
+ if (new_opt[0])
+ {
+ error = TRUE;
+ (*_bfd_error_handler)
+ (_("%s: compiled with %s and linked with modules compiled with %s"),
+ bfd_get_filename (ibfd), new_opt, old_opt);
+ }
+
+ /* Warn about any other mismatches */
+ new_partial = (new_flags & ~ EF_FRV_ALL_FLAGS);
+ old_partial = (old_flags & ~ EF_FRV_ALL_FLAGS);
+ if (new_partial != old_partial)
+ {
+ old_flags |= new_partial;
+ error = TRUE;
+ (*_bfd_error_handler)
+ (_("%s: uses different unknown e_flags (0x%lx) fields than previous modules (0x%lx)"),
+ bfd_get_filename (ibfd), (long)new_partial, (long)old_partial);
+ }
+ }
+
+ /* If the cpu is -mcpu=simple, then set the -mnopack bit. */
+ if ((old_flags & EF_FRV_CPU_MASK) == EF_FRV_CPU_SIMPLE)
+ old_flags |= EF_FRV_NOPACK;
+
+ /* Update the old flags now with changes made above. */
+ old_partial = elf_elfheader (obfd)->e_flags & EF_FRV_CPU_MASK;
+ elf_elfheader (obfd)->e_flags = old_flags;
+ if (old_partial != (old_flags & EF_FRV_CPU_MASK))
+ bfd_default_set_arch_mach (obfd, bfd_arch_frv, elf32_frv_machine (obfd));
+
+ if (((new_flags & EF_FRV_FDPIC) == 0)
+ != (! IS_FDPIC (ibfd)))
+ {
+ error = TRUE;
+ if (IS_FDPIC (obfd))
+ (*_bfd_error_handler)
+ (_("%s: cannot link non-fdpic object file into fdpic executable"),
+ bfd_get_filename (ibfd));
+ else
+ (*_bfd_error_handler)
+ (_("%s: cannot link fdpic object file into non-fdpic executable"),
+ bfd_get_filename (ibfd));
+ }
+
+ if (error)
+ bfd_set_error (bfd_error_bad_value);
+
+ return !error;
+}
+
+
+static bfd_boolean
+frv_elf_print_private_bfd_data (bfd *abfd, void * ptr)
+{
+ FILE *file = (FILE *) ptr;
+ flagword flags;
+
+ BFD_ASSERT (abfd != NULL && ptr != NULL);
+
+ /* Print normal ELF private data. */
+ _bfd_elf_print_private_bfd_data (abfd, ptr);
+
+ flags = elf_elfheader (abfd)->e_flags;
+ fprintf (file, _("private flags = 0x%lx:"), (unsigned long) flags);
+
+ switch (flags & EF_FRV_CPU_MASK)
+ {
+ default: break;
+ case EF_FRV_CPU_SIMPLE: fprintf (file, " -mcpu=simple"); break;
+ case EF_FRV_CPU_FR550: fprintf (file, " -mcpu=fr550"); break;
+ case EF_FRV_CPU_FR500: fprintf (file, " -mcpu=fr500"); break;
+ case EF_FRV_CPU_FR450: fprintf (file, " -mcpu=fr450"); break;
+ case EF_FRV_CPU_FR405: fprintf (file, " -mcpu=fr405"); break;
+ case EF_FRV_CPU_FR400: fprintf (file, " -mcpu=fr400"); break;
+ case EF_FRV_CPU_FR300: fprintf (file, " -mcpu=fr300"); break;
+ case EF_FRV_CPU_TOMCAT: fprintf (file, " -mcpu=tomcat"); break;
+ }
+
+ switch (flags & EF_FRV_GPR_MASK)
+ {
+ default: break;
+ case EF_FRV_GPR_32: fprintf (file, " -mgpr-32"); break;
+ case EF_FRV_GPR_64: fprintf (file, " -mgpr-64"); break;
+ }
+
+ switch (flags & EF_FRV_FPR_MASK)
+ {
+ default: break;
+ case EF_FRV_FPR_32: fprintf (file, " -mfpr-32"); break;
+ case EF_FRV_FPR_64: fprintf (file, " -mfpr-64"); break;
+ case EF_FRV_FPR_NONE: fprintf (file, " -msoft-float"); break;
+ }
+
+ switch (flags & EF_FRV_DWORD_MASK)
+ {
+ default: break;
+ case EF_FRV_DWORD_YES: fprintf (file, " -mdword"); break;
+ case EF_FRV_DWORD_NO: fprintf (file, " -mno-dword"); break;
+ }
+
+ if (flags & EF_FRV_DOUBLE)
+ fprintf (file, " -mdouble");
+
+ if (flags & EF_FRV_MEDIA)
+ fprintf (file, " -mmedia");
+
+ if (flags & EF_FRV_MULADD)
+ fprintf (file, " -mmuladd");
+
+ if (flags & EF_FRV_PIC)
+ fprintf (file, " -fpic");
+
+ if (flags & EF_FRV_BIGPIC)
+ fprintf (file, " -fPIC");
+
+ if (flags & EF_FRV_LIBPIC)
+ fprintf (file, " -mlibrary-pic");
+
+ if (flags & EF_FRV_FDPIC)
+ fprintf (file, " -mfdpic");
+
+ if (flags & EF_FRV_NON_PIC_RELOCS)
+ fprintf (file, " non-pic relocations");
+
+ if (flags & EF_FRV_G0)
+ fprintf (file, " -G0");
+
+ fputc ('\n', file);
+ return TRUE;
+}
+
+
+/* Support for core dump NOTE sections. */
+
+static bfd_boolean
+elf32_frv_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
+{
+ int offset;
+ unsigned int raw_size;
+
+ switch (note->descsz)
+ {
+ default:
+ return FALSE;
+
+ /* The Linux/FRV elf_prstatus struct is 268 bytes long. The other
+ hardcoded offsets and sizes listed below (and contained within
+ this lexical block) refer to fields in the target's elf_prstatus
+ struct. */
+ case 268:
+ /* `pr_cursig' is at offset 12. */
+ elf_tdata (abfd)->core->signal = bfd_get_16 (abfd, note->descdata + 12);
+
+ /* `pr_pid' is at offset 24. */
+ elf_tdata (abfd)->core->lwpid = bfd_get_32 (abfd, note->descdata + 24);
+
+ /* `pr_reg' is at offset 72. */
+ offset = 72;
+
+ /* Most grok_prstatus implementations set `raw_size' to the size
+ of the pr_reg field. For Linux/FRV, we set `raw_size' to be
+ the size of `pr_reg' plus the size of `pr_exec_fdpic_loadmap'
+ and `pr_interp_fdpic_loadmap', both of which (by design)
+ immediately follow `pr_reg'. This will allow these fields to
+ be viewed by GDB as registers.
+
+ `pr_reg' is 184 bytes long. `pr_exec_fdpic_loadmap' and
+ `pr_interp_fdpic_loadmap' are 4 bytes each. */
+ raw_size = 184 + 4 + 4;
+
+ break;
+ }
+
+ /* Make a ".reg/999" section. */
+ return _bfd_elfcore_make_pseudosection (abfd, ".reg", raw_size,
+ note->descpos + offset);
+}
+
+static bfd_boolean
+elf32_frv_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
+{
+ switch (note->descsz)
+ {
+ default:
+ return FALSE;
+
+ /* The Linux/FRV elf_prpsinfo struct is 124 bytes long. */
+ case 124:
+
+ /* `pr_fname' is found at offset 28 and is 16 bytes long. */
+ elf_tdata (abfd)->core->program
+ = _bfd_elfcore_strndup (abfd, note->descdata + 28, 16);
+
+ /* `pr_psargs' is found at offset 44 and is 80 bytes long. */
+ elf_tdata (abfd)->core->command
+ = _bfd_elfcore_strndup (abfd, note->descdata + 44, 80);
+ }
+
+ /* 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;
+}
+#define ELF_ARCH bfd_arch_frv
+#define ELF_TARGET_ID FRV_ELF_DATA
+#define ELF_MACHINE_CODE EM_CYGNUS_FRV
+#define ELF_MAXPAGESIZE 0x1000
+
+#define TARGET_BIG_SYM frv_elf32_vec
+#define TARGET_BIG_NAME "elf32-frv"
+
+#define elf_info_to_howto frv_info_to_howto_rela
+#define elf_backend_relocate_section elf32_frv_relocate_section
+#define elf_backend_gc_mark_hook elf32_frv_gc_mark_hook
+#define elf_backend_check_relocs elf32_frv_check_relocs
+#define elf_backend_object_p elf32_frv_object_p
+#define elf_backend_add_symbol_hook elf32_frv_add_symbol_hook
+
+#define elf_backend_stack_align 8
+#define elf_backend_can_gc_sections 1
+#define elf_backend_rela_normal 1
+
+#define bfd_elf32_bfd_reloc_type_lookup frv_reloc_type_lookup
+#define bfd_elf32_bfd_reloc_name_lookup frv_reloc_name_lookup
+#define bfd_elf32_bfd_set_private_flags frv_elf_set_private_flags
+#define bfd_elf32_bfd_merge_private_bfd_data frv_elf_merge_private_bfd_data
+#define bfd_elf32_bfd_print_private_bfd_data frv_elf_print_private_bfd_data
+
+#define elf_backend_want_got_sym 1
+#define elf_backend_got_header_size 0
+#define elf_backend_want_got_plt 0
+#define elf_backend_plt_readonly 1
+#define elf_backend_want_plt_sym 0
+#define elf_backend_plt_header_size 0
+
+#define elf_backend_finish_dynamic_sections \
+ elf32_frv_finish_dynamic_sections
+
+#define elf_backend_grok_prstatus elf32_frv_grok_prstatus
+#define elf_backend_grok_psinfo elf32_frv_grok_psinfo
+
+#include "elf32-target.h"
+
+#undef ELF_MAXPAGESIZE
+#define ELF_MAXPAGESIZE 0x4000
+
+#undef TARGET_BIG_SYM
+#define TARGET_BIG_SYM frv_elf32_fdpic_vec
+#undef TARGET_BIG_NAME
+#define TARGET_BIG_NAME "elf32-frvfdpic"
+#undef elf32_bed
+#define elf32_bed elf32_frvfdpic_bed
+
+#undef elf_info_to_howto_rel
+#define elf_info_to_howto_rel frvfdpic_info_to_howto_rel
+
+#undef bfd_elf32_bfd_link_hash_table_create
+#define bfd_elf32_bfd_link_hash_table_create \
+ frvfdpic_elf_link_hash_table_create
+#undef elf_backend_always_size_sections
+#define elf_backend_always_size_sections \
+ elf32_frvfdpic_always_size_sections
+
+#undef elf_backend_create_dynamic_sections
+#define elf_backend_create_dynamic_sections \
+ elf32_frvfdpic_create_dynamic_sections
+#undef elf_backend_adjust_dynamic_symbol
+#define elf_backend_adjust_dynamic_symbol \
+ elf32_frvfdpic_adjust_dynamic_symbol
+#undef elf_backend_size_dynamic_sections
+#define elf_backend_size_dynamic_sections \
+ elf32_frvfdpic_size_dynamic_sections
+#undef bfd_elf32_bfd_relax_section
+#define bfd_elf32_bfd_relax_section \
+ elf32_frvfdpic_relax_section
+#undef elf_backend_finish_dynamic_symbol
+#define elf_backend_finish_dynamic_symbol \
+ elf32_frvfdpic_finish_dynamic_symbol
+#undef elf_backend_finish_dynamic_sections
+#define elf_backend_finish_dynamic_sections \
+ elf32_frvfdpic_finish_dynamic_sections
+
+#undef elf_backend_discard_info
+#define elf_backend_discard_info \
+ frvfdpic_elf_discard_info
+#undef elf_backend_can_make_relative_eh_frame
+#define elf_backend_can_make_relative_eh_frame \
+ frvfdpic_elf_use_relative_eh_frame
+#undef elf_backend_can_make_lsda_relative_eh_frame
+#define elf_backend_can_make_lsda_relative_eh_frame \
+ frvfdpic_elf_use_relative_eh_frame
+#undef elf_backend_encode_eh_address
+#define elf_backend_encode_eh_address \
+ frvfdpic_elf_encode_eh_address
+
+#undef elf_backend_may_use_rel_p
+#define elf_backend_may_use_rel_p 1
+#undef elf_backend_may_use_rela_p
+#define elf_backend_may_use_rela_p 1
+/* We use REL for dynamic relocations only. */
+#undef elf_backend_default_use_rela_p
+#define elf_backend_default_use_rela_p 1
+
+#undef elf_backend_omit_section_dynsym
+#define elf_backend_omit_section_dynsym _frvfdpic_link_omit_section_dynsym
+
+#include "elf32-target.h"
diff --git a/bfd/elf32-gen.c b/bfd/elf32-gen.c
new file mode 100644
index 0000000..412fefd
--- /dev/null
+++ b/bfd/elf32-gen.c
@@ -0,0 +1,102 @@
+/* Generic support for 32-bit ELF
+ Copyright (C) 1993-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.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 (bfd *abfd ATTRIBUTE_UNUSED,
+ arelent *bfd_reloc,
+ Elf_Internal_Rela *elf_reloc ATTRIBUTE_UNUSED)
+{
+ bfd_reloc->howto = &dummy;
+}
+
+static void
+elf_generic_info_to_howto_rel (bfd *abfd ATTRIBUTE_UNUSED,
+ arelent *bfd_reloc,
+ Elf_Internal_Rela *elf_reloc ATTRIBUTE_UNUSED)
+{
+ bfd_reloc->howto = &dummy;
+}
+
+static void
+check_for_relocs (bfd * abfd, asection * o, void * failed)
+{
+ if ((o->flags & SEC_RELOC) != 0)
+ {
+ Elf_Internal_Ehdr *ehdrp;
+
+ ehdrp = elf_elfheader (abfd);
+ _bfd_error_handler (_("%B: Relocations in generic ELF (EM: %d)"),
+ abfd, ehdrp->e_machine);
+
+ bfd_set_error (bfd_error_wrong_format);
+ * (bfd_boolean *) failed = TRUE;
+ }
+}
+
+static bfd_boolean
+elf32_generic_link_add_symbols (bfd *abfd, struct bfd_link_info *info)
+{
+ bfd_boolean failed = FALSE;
+
+ /* Check if there are any relocations. */
+ bfd_map_over_sections (abfd, check_for_relocs, & failed);
+
+ if (failed)
+ return FALSE;
+ return bfd_elf_link_add_symbols (abfd, info);
+}
+
+#define TARGET_LITTLE_SYM elf32_le_vec
+#define TARGET_LITTLE_NAME "elf32-little"
+#define TARGET_BIG_SYM elf32_be_vec
+#define TARGET_BIG_NAME "elf32-big"
+#define ELF_ARCH bfd_arch_unknown
+#define ELF_MACHINE_CODE EM_NONE
+#define ELF_MAXPAGESIZE 0x1
+#define bfd_elf32_bfd_reloc_type_lookup bfd_default_reloc_type_lookup
+#define bfd_elf32_bfd_reloc_name_lookup _bfd_norelocs_bfd_reloc_name_lookup
+#define bfd_elf32_bfd_link_add_symbols elf32_generic_link_add_symbols
+#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-h8300.c b/bfd/elf32-h8300.c
new file mode 100644
index 0000000..e9eae94
--- /dev/null
+++ b/bfd/elf32-h8300.c
@@ -0,0 +1,1746 @@
+/* BFD back-end for Renesas H8/300 ELF binaries.
+ Copyright (C) 1993-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+#include "elf-bfd.h"
+#include "elf/h8.h"
+
+static reloc_howto_type *elf32_h8_reloc_type_lookup
+ (bfd *abfd, bfd_reloc_code_real_type code);
+static void elf32_h8_info_to_howto
+ (bfd *, arelent *, Elf_Internal_Rela *);
+static void elf32_h8_info_to_howto_rel
+ (bfd *, arelent *, Elf_Internal_Rela *);
+static unsigned long elf32_h8_mach (flagword);
+static void elf32_h8_final_write_processing (bfd *, bfd_boolean);
+static bfd_boolean elf32_h8_object_p (bfd *);
+static bfd_boolean elf32_h8_merge_private_bfd_data (bfd *, bfd *);
+static bfd_boolean elf32_h8_relax_section
+ (bfd *, asection *, struct bfd_link_info *, bfd_boolean *);
+static bfd_boolean elf32_h8_relax_delete_bytes
+ (bfd *, asection *, bfd_vma, int);
+static bfd_boolean elf32_h8_symbol_address_p (bfd *, asection *, bfd_vma);
+static bfd_byte *elf32_h8_get_relocated_section_contents
+ (bfd *, struct bfd_link_info *, struct bfd_link_order *,
+ bfd_byte *, bfd_boolean, asymbol **);
+static bfd_reloc_status_type elf32_h8_final_link_relocate
+ (unsigned long, bfd *, bfd *, asection *,
+ bfd_byte *, bfd_vma, bfd_vma, bfd_vma,
+ struct bfd_link_info *, asection *, int);
+static bfd_boolean elf32_h8_relocate_section
+ (bfd *, struct bfd_link_info *, bfd *, asection *,
+ bfd_byte *, Elf_Internal_Rela *,
+ Elf_Internal_Sym *, asection **);
+static bfd_reloc_status_type special
+ (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
+
+/* This does not include any relocation information, but should be
+ good enough for GDB or objdump to read the file. */
+
+static reloc_howto_type h8_elf_howto_table[] =
+{
+#define R_H8_NONE_X 0
+ HOWTO (R_H8_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 */
+ special, /* special_function */
+ "R_H8_NONE", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ FALSE), /* pcrel_offset */
+#define R_H8_DIR32_X (R_H8_NONE_X + 1)
+ HOWTO (R_H8_DIR32, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ special, /* special_function */
+ "R_H8_DIR32", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+#define R_H8_DIR16_X (R_H8_DIR32_X + 1)
+ HOWTO (R_H8_DIR16, /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ special, /* special_function */
+ "R_H8_DIR16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+#define R_H8_DIR8_X (R_H8_DIR16_X + 1)
+ HOWTO (R_H8_DIR8, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 8, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ special, /* special_function */
+ "R_H8_DIR8", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x000000ff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+#define R_H8_DIR16A8_X (R_H8_DIR8_X + 1)
+ HOWTO (R_H8_DIR16A8, /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ special, /* special_function */
+ "R_H8_DIR16A8", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+#define R_H8_DIR16R8_X (R_H8_DIR16A8_X + 1)
+ HOWTO (R_H8_DIR16R8, /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ special, /* special_function */
+ "R_H8_DIR16R8", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+#define R_H8_DIR24A8_X (R_H8_DIR16R8_X + 1)
+ HOWTO (R_H8_DIR24A8, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 24, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ special, /* special_function */
+ "R_H8_DIR24A8", /* name */
+ TRUE, /* partial_inplace */
+ 0xff000000, /* src_mask */
+ 0x00ffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+#define R_H8_DIR24R8_X (R_H8_DIR24A8_X + 1)
+ HOWTO (R_H8_DIR24R8, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 24, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ special, /* special_function */
+ "R_H8_DIR24R8", /* name */
+ TRUE, /* partial_inplace */
+ 0xff000000, /* src_mask */
+ 0x00ffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+#define R_H8_DIR32A16_X (R_H8_DIR24R8_X + 1)
+ HOWTO (R_H8_DIR32A16, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ special, /* special_function */
+ "R_H8_DIR32A16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+#define R_H8_DISP32A16_X (R_H8_DIR32A16_X + 1)
+ HOWTO (R_H8_DISP32A16, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ special, /* special_function */
+ "R_H8_DISP32A16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+#define R_H8_PCREL16_X (R_H8_DISP32A16_X + 1)
+ HOWTO (R_H8_PCREL16, /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed,/* complain_on_overflow */
+ special, /* special_function */
+ "R_H8_PCREL16", /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+#define R_H8_PCREL8_X (R_H8_PCREL16_X + 1)
+ HOWTO (R_H8_PCREL8, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 8, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed,/* complain_on_overflow */
+ special, /* special_function */
+ "R_H8_PCREL8", /* name */
+ FALSE, /* partial_inplace */
+ 0xff, /* src_mask */
+ 0xff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+};
+
+/* This structure is used to map BFD reloc codes to H8 ELF relocs. */
+
+struct elf_reloc_map {
+ bfd_reloc_code_real_type bfd_reloc_val;
+ unsigned char howto_index;
+};
+
+/* An array mapping BFD reloc codes to H8 ELF relocs. */
+
+static const struct elf_reloc_map h8_reloc_map[] = {
+ { BFD_RELOC_NONE, R_H8_NONE_X },
+ { BFD_RELOC_32, R_H8_DIR32_X },
+ { BFD_RELOC_16, R_H8_DIR16_X },
+ { BFD_RELOC_8, R_H8_DIR8_X },
+ { BFD_RELOC_H8_DIR16A8, R_H8_DIR16A8_X },
+ { BFD_RELOC_H8_DIR16R8, R_H8_DIR16R8_X },
+ { BFD_RELOC_H8_DIR24A8, R_H8_DIR24A8_X },
+ { BFD_RELOC_H8_DIR24R8, R_H8_DIR24R8_X },
+ { BFD_RELOC_H8_DIR32A16, R_H8_DIR32A16_X },
+ { BFD_RELOC_H8_DISP32A16, R_H8_DISP32A16_X },
+ { BFD_RELOC_16_PCREL, R_H8_PCREL16_X },
+ { BFD_RELOC_8_PCREL, R_H8_PCREL8_X },
+};
+
+
+static reloc_howto_type *
+elf32_h8_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ bfd_reloc_code_real_type code)
+{
+ unsigned int i;
+
+ for (i = 0; i < sizeof (h8_reloc_map) / sizeof (struct elf_reloc_map); i++)
+ {
+ if (h8_reloc_map[i].bfd_reloc_val == code)
+ return &h8_elf_howto_table[(int) h8_reloc_map[i].howto_index];
+ }
+ return NULL;
+}
+
+static reloc_howto_type *
+elf32_h8_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ const char *r_name)
+{
+ unsigned int i;
+
+ for (i = 0;
+ i < sizeof (h8_elf_howto_table) / sizeof (h8_elf_howto_table[0]);
+ i++)
+ if (h8_elf_howto_table[i].name != NULL
+ && strcasecmp (h8_elf_howto_table[i].name, r_name) == 0)
+ return &h8_elf_howto_table[i];
+
+ return NULL;
+}
+
+static void
+elf32_h8_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED, arelent *bfd_reloc,
+ Elf_Internal_Rela *elf_reloc)
+{
+ unsigned int r;
+ unsigned int i;
+
+ r = ELF32_R_TYPE (elf_reloc->r_info);
+ for (i = 0; i < sizeof (h8_elf_howto_table) / sizeof (reloc_howto_type); i++)
+ if (h8_elf_howto_table[i].type == r)
+ {
+ bfd_reloc->howto = &h8_elf_howto_table[i];
+ return;
+ }
+ abort ();
+}
+
+static void
+elf32_h8_info_to_howto_rel (bfd *abfd ATTRIBUTE_UNUSED, arelent *bfd_reloc,
+ Elf_Internal_Rela *elf_reloc ATTRIBUTE_UNUSED)
+{
+ unsigned int r;
+
+ abort ();
+ r = ELF32_R_TYPE (elf_reloc->r_info);
+ bfd_reloc->howto = &h8_elf_howto_table[r];
+}
+
+/* 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
+ we support relaxing on the H8/300 series chips. */
+static bfd_reloc_status_type
+special (bfd *abfd ATTRIBUTE_UNUSED,
+ arelent *reloc_entry ATTRIBUTE_UNUSED,
+ asymbol *symbol ATTRIBUTE_UNUSED,
+ void * data ATTRIBUTE_UNUSED,
+ asection *input_section ATTRIBUTE_UNUSED,
+ bfd *output_bfd,
+ char **error_message ATTRIBUTE_UNUSED)
+{
+ if (output_bfd == (bfd *) NULL)
+ return bfd_reloc_continue;
+
+ /* Adjust the reloc address to that in the output section. */
+ reloc_entry->address += input_section->output_offset;
+ return bfd_reloc_ok;
+}
+
+/* Perform a relocation as part of a final link. */
+static bfd_reloc_status_type
+elf32_h8_final_link_relocate (unsigned long r_type, bfd *input_bfd,
+ bfd *output_bfd ATTRIBUTE_UNUSED,
+ asection *input_section ATTRIBUTE_UNUSED,
+ bfd_byte *contents, bfd_vma offset,
+ bfd_vma value, bfd_vma addend,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ asection *sym_sec ATTRIBUTE_UNUSED,
+ int is_local ATTRIBUTE_UNUSED)
+{
+ bfd_byte *hit_data = contents + offset;
+
+ switch (r_type)
+ {
+ case R_H8_NONE:
+ return bfd_reloc_ok;
+
+ case R_H8_DIR32:
+ case R_H8_DIR32A16:
+ case R_H8_DISP32A16:
+ case R_H8_DIR24A8:
+ value += addend;
+ bfd_put_32 (input_bfd, value, hit_data);
+ return bfd_reloc_ok;
+
+ case R_H8_DIR16:
+ case R_H8_DIR16A8:
+ case R_H8_DIR16R8:
+ value += addend;
+ bfd_put_16 (input_bfd, value, hit_data);
+ return bfd_reloc_ok;
+
+ /* AKA R_RELBYTE */
+ case R_H8_DIR8:
+ value += addend;
+
+ bfd_put_8 (input_bfd, value, hit_data);
+ return bfd_reloc_ok;
+
+ case R_H8_DIR24R8:
+ value += addend;
+
+ /* HIT_DATA is the address for the first byte for the relocated
+ value. Subtract 1 so that we can manipulate the data in 32-bit
+ hunks. */
+ hit_data--;
+
+ /* Clear out the top byte in value. */
+ value &= 0xffffff;
+
+ /* Retrieve the type byte for value from the section contents. */
+ value |= (bfd_get_32 (input_bfd, hit_data) & 0xff000000);
+
+ /* Now scribble it out in one 32-bit hunk. */
+ bfd_put_32 (input_bfd, value, hit_data);
+ return bfd_reloc_ok;
+
+ case R_H8_PCREL16:
+ value -= (input_section->output_section->vma
+ + input_section->output_offset);
+ value -= offset;
+ value += addend;
+
+ /* The value is relative to the start of the instruction,
+ not the relocation offset. Subtract 2 to account for
+ this minor issue. */
+ value -= 2;
+
+ bfd_put_16 (input_bfd, value, hit_data);
+ return bfd_reloc_ok;
+
+ case R_H8_PCREL8:
+ value -= (input_section->output_section->vma
+ + input_section->output_offset);
+ value -= offset;
+ value += addend;
+
+ /* The value is relative to the start of the instruction,
+ not the relocation offset. Subtract 1 to account for
+ this minor issue. */
+ value -= 1;
+
+ bfd_put_8 (input_bfd, value, hit_data);
+ return bfd_reloc_ok;
+
+ default:
+ return bfd_reloc_notsupported;
+ }
+}
+
+/* Relocate an H8 ELF section. */
+static bfd_boolean
+elf32_h8_relocate_section (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++)
+ {
+ unsigned int r_type;
+ unsigned long r_symndx;
+ Elf_Internal_Sym *sym;
+ asection *sec;
+ struct elf_link_hash_entry *h;
+ bfd_vma relocation;
+ bfd_reloc_status_type r;
+ arelent bfd_reloc;
+ reloc_howto_type *howto;
+
+ elf32_h8_info_to_howto (input_bfd, &bfd_reloc, rel);
+ howto = bfd_reloc.howto;
+
+ r_symndx = ELF32_R_SYM (rel->r_info);
+ r_type = 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 = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
+ }
+ else
+ {
+ bfd_boolean unresolved_reloc, warned, ignored;
+
+ RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
+ r_symndx, symtab_hdr, sym_hashes,
+ h, sec, relocation,
+ unresolved_reloc, warned, ignored);
+ }
+
+ if (sec != NULL && discarded_section (sec))
+ RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+ rel, 1, relend, howto, 0, contents);
+
+ if (info->relocatable)
+ continue;
+
+ r = elf32_h8_final_link_relocate (r_type, 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, (h ? &h->root : NULL), 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, TRUE)))
+ 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;
+}
+
+/* Object files encode the specific H8 model they were compiled
+ for in the ELF flags field.
+
+ Examine that field and return the proper BFD machine type for
+ the object file. */
+static unsigned long
+elf32_h8_mach (flagword flags)
+{
+ switch (flags & EF_H8_MACH)
+ {
+ case E_H8_MACH_H8300:
+ default:
+ return bfd_mach_h8300;
+
+ case E_H8_MACH_H8300H:
+ return bfd_mach_h8300h;
+
+ case E_H8_MACH_H8300S:
+ return bfd_mach_h8300s;
+
+ case E_H8_MACH_H8300HN:
+ return bfd_mach_h8300hn;
+
+ case E_H8_MACH_H8300SN:
+ return bfd_mach_h8300sn;
+
+ case E_H8_MACH_H8300SX:
+ return bfd_mach_h8300sx;
+
+ case E_H8_MACH_H8300SXN:
+ return bfd_mach_h8300sxn;
+ }
+}
+
+/* The final processing done just before writing out a H8 ELF object
+ file. We use this opportunity to encode the BFD machine type
+ into the flags field in the object file. */
+
+static void
+elf32_h8_final_write_processing (bfd *abfd,
+ bfd_boolean linker ATTRIBUTE_UNUSED)
+{
+ unsigned long val;
+
+ switch (bfd_get_mach (abfd))
+ {
+ default:
+ case bfd_mach_h8300:
+ val = E_H8_MACH_H8300;
+ break;
+
+ case bfd_mach_h8300h:
+ val = E_H8_MACH_H8300H;
+ break;
+
+ case bfd_mach_h8300s:
+ val = E_H8_MACH_H8300S;
+ break;
+
+ case bfd_mach_h8300hn:
+ val = E_H8_MACH_H8300HN;
+ break;
+
+ case bfd_mach_h8300sn:
+ val = E_H8_MACH_H8300SN;
+ break;
+
+ case bfd_mach_h8300sx:
+ val = E_H8_MACH_H8300SX;
+ break;
+
+ case bfd_mach_h8300sxn:
+ val = E_H8_MACH_H8300SXN;
+ break;
+ }
+
+ elf_elfheader (abfd)->e_flags &= ~ (EF_H8_MACH);
+ elf_elfheader (abfd)->e_flags |= val;
+}
+
+/* Return nonzero if ABFD represents a valid H8 ELF object file; also
+ record the encoded machine type found in the ELF flags. */
+
+static bfd_boolean
+elf32_h8_object_p (bfd *abfd)
+{
+ bfd_default_set_arch_mach (abfd, bfd_arch_h8300,
+ elf32_h8_mach (elf_elfheader (abfd)->e_flags));
+ return TRUE;
+}
+
+/* Merge backend specific data from an object file to the output
+ object file when linking. The only data we need to copy at this
+ time is the architecture/machine information. */
+
+static bfd_boolean
+elf32_h8_merge_private_bfd_data (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;
+}
+
+/* This function handles relaxing for the H8..
+
+ There are a few relaxing opportunities available on the H8:
+
+ jmp/jsr:24 -> bra/bsr:8 2 bytes
+ The jmp may be completely eliminated if the previous insn is a
+ conditional branch to the insn after the jump. In that case
+ we invert the branch and delete the jump and save 4 bytes.
+
+ bCC:16 -> bCC:8 2 bytes
+ bsr:16 -> bsr:8 2 bytes
+
+ bset:16 -> bset:8 2 bytes
+ bset:24/32 -> bset:8 4 bytes
+ (also applicable to other bit manipulation instructions)
+
+ mov.b:16 -> mov.b:8 2 bytes
+ mov.b:24/32 -> mov.b:8 4 bytes
+
+ bset:24/32 -> bset:16 2 bytes
+ (also applicable to other bit manipulation instructions)
+
+ mov.[bwl]:24/32 -> mov.[bwl]:16 2 bytes
+
+ mov.[bwl] @(displ:24/32+ERx) -> mov.[bwl] @(displ:16+ERx) 4 bytes. */
+
+static bfd_boolean
+elf32_h8_relax_section (bfd *abfd, asection *sec,
+ struct bfd_link_info *link_info, bfd_boolean *again)
+{
+ Elf_Internal_Shdr *symtab_hdr;
+ Elf_Internal_Rela *internal_relocs;
+ Elf_Internal_Rela *irel, *irelend;
+ bfd_byte *contents = NULL;
+ Elf_Internal_Sym *isymbuf = NULL;
+ static asection *last_input_section = NULL;
+ static Elf_Internal_Rela *last_reloc = NULL;
+
+ /* Assume nothing changes. */
+ *again = FALSE;
+
+ /* We don't have to do anything for a relocatable link, if
+ this section does not have relocs, or if this is not a
+ code section. */
+ if (link_info->relocatable
+ || (sec->flags & SEC_RELOC) == 0
+ || sec->reloc_count == 0
+ || (sec->flags & SEC_CODE) == 0)
+ return TRUE;
+
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+
+ /* Get a copy of the native relocations. */
+ internal_relocs = (_bfd_elf_link_read_relocs
+ (abfd, sec, NULL, (Elf_Internal_Rela *) NULL,
+ link_info->keep_memory));
+ if (internal_relocs == NULL)
+ goto error_return;
+
+ if (sec != last_input_section)
+ last_reloc = NULL;
+
+ last_input_section = sec;
+
+ /* Walk through the relocs looking for relaxing opportunities. */
+ irelend = internal_relocs + sec->reloc_count;
+ for (irel = internal_relocs; irel < irelend; irel++)
+ {
+ bfd_vma symval;
+
+ {
+ arelent bfd_reloc;
+
+ elf32_h8_info_to_howto (abfd, &bfd_reloc, irel);
+ }
+ /* Keep track of the previous reloc so that we can delete
+ some long jumps created by the compiler. */
+ if (irel != internal_relocs)
+ last_reloc = irel - 1;
+
+ switch(ELF32_R_TYPE (irel->r_info))
+ {
+ case R_H8_DIR24R8:
+ case R_H8_PCREL16:
+ case R_H8_DIR16A8:
+ case R_H8_DIR24A8:
+ case R_H8_DIR32A16:
+ case R_H8_DISP32A16:
+ break;
+ default:
+ 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. */
+ if (!bfd_malloc_and_get_section (abfd, sec, &contents))
+ goto error_return;
+ }
+ }
+
+ /* Read this BFD's local symbols if we haven't done so already. */
+ if (isymbuf == NULL && symtab_hdr->sh_info != 0)
+ {
+ isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
+ if (isymbuf == NULL)
+ isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
+ symtab_hdr->sh_info, 0,
+ NULL, NULL, NULL);
+ if (isymbuf == NULL)
+ 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)
+ {
+ /* A local symbol. */
+ Elf_Internal_Sym *isym;
+ asection *sym_sec;
+
+ isym = isymbuf + ELF32_R_SYM (irel->r_info);
+ sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
+ symval = isym->st_value;
+ /* If the reloc is absolute, it will not have
+ a symbol or section associated with it. */
+ if (sym_sec)
+ symval += 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. */
+ switch (ELF32_R_TYPE (irel->r_info))
+ {
+ /* Try to turn a 24-bit absolute branch/call into an 8-bit
+ pc-relative branch/call. */
+ case R_H8_DIR24R8:
+ {
+ bfd_vma value = symval + irel->r_addend;
+ bfd_vma dot, gap;
+
+ /* Get the address of this instruction. */
+ dot = (sec->output_section->vma
+ + sec->output_offset + irel->r_offset - 1);
+
+ /* Compute the distance from this insn to the branch target. */
+ gap = value - dot;
+
+ /* If the distance is within -126..+130 inclusive, then we can
+ relax this jump. +130 is valid since the target will move
+ two bytes closer if we do relax this branch. */
+ if ((int) gap >= -126 && (int) gap <= 130)
+ {
+ unsigned char code;
+
+ /* Note that we've changed the relocs, section contents,
+ etc. */
+ elf_section_data (sec)->relocs = internal_relocs;
+ elf_section_data (sec)->this_hdr.contents = contents;
+ symtab_hdr->contents = (unsigned char *) isymbuf;
+
+ /* Get the instruction code being relaxed. */
+ code = bfd_get_8 (abfd, contents + irel->r_offset - 1);
+
+ /* If the previous instruction conditionally jumped around
+ this instruction, we may be able to reverse the condition
+ and redirect the previous instruction to the target of
+ this instruction.
+
+ Such sequences are used by the compiler to deal with
+ long conditional branches.
+
+ Only perform this optimisation for jumps (code 0x5a) not
+ subroutine calls, as otherwise it could transform:
+
+ mov.w r0,r0
+ beq .L1
+ jsr @_bar
+ .L1: rts
+ _bar: rts
+ into:
+ mov.w r0,r0
+ bne _bar
+ rts
+ _bar: rts
+
+ which changes the call (jsr) into a branch (bne). */
+ if (code == 0x5a /* jmp24. */
+ && (int) gap <= 130
+ && (int) gap >= -128
+ && last_reloc
+ && ELF32_R_TYPE (last_reloc->r_info) == R_H8_PCREL8
+ && ELF32_R_SYM (last_reloc->r_info) < symtab_hdr->sh_info)
+ {
+ bfd_vma last_value;
+ asection *last_sym_sec;
+ Elf_Internal_Sym *last_sym;
+
+ /* We will need to examine the symbol used by the
+ previous relocation. */
+
+ last_sym = isymbuf + ELF32_R_SYM (last_reloc->r_info);
+ last_sym_sec
+ = bfd_section_from_elf_index (abfd, last_sym->st_shndx);
+ last_value = (last_sym->st_value
+ + last_sym_sec->output_section->vma
+ + last_sym_sec->output_offset);
+
+ /* Verify that the previous relocation was for a
+ branch around this instruction and that no symbol
+ exists at the current location. */
+ if (last_value == dot + 4
+ && last_reloc->r_offset + 2 == irel->r_offset
+ && ! elf32_h8_symbol_address_p (abfd, sec, dot))
+ {
+ /* We can eliminate this jump. Twiddle the
+ previous relocation as necessary. */
+ irel->r_info
+ = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
+ ELF32_R_TYPE (R_H8_NONE));
+
+ last_reloc->r_info
+ = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
+ ELF32_R_TYPE (R_H8_PCREL8));
+ last_reloc->r_addend = irel->r_addend;
+
+ code = bfd_get_8 (abfd,
+ contents + last_reloc->r_offset - 1);
+ code ^= 1;
+ bfd_put_8 (abfd,
+ code,
+ contents + last_reloc->r_offset - 1);
+
+ /* Delete four bytes of data. */
+ if (!elf32_h8_relax_delete_bytes (abfd, sec,
+ irel->r_offset - 1,
+ 4))
+ goto error_return;
+
+ *again = TRUE;
+ break;
+ }
+ }
+
+ if (code == 0x5e)
+ /* This is jsr24 */
+ bfd_put_8 (abfd, 0x55, contents + irel->r_offset - 1); /* bsr8. */
+ else if (code == 0x5a)
+ /* This is jmp24 */
+ bfd_put_8 (abfd, 0x40, contents + irel->r_offset - 1); /* bra8. */
+ else
+ abort ();
+
+ /* Fix the relocation's type. */
+ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
+ R_H8_PCREL8);
+
+ /* Delete two bytes of data. */
+ if (!elf32_h8_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;
+ }
+
+ /* Try to turn a 16-bit pc-relative branch into a 8-bit pc-relative
+ branch. */
+ case R_H8_PCREL16:
+ {
+ bfd_vma value = symval + irel->r_addend;
+ bfd_vma dot;
+ bfd_vma gap;
+
+ /* Get the address of this instruction. */
+ dot = (sec->output_section->vma
+ + sec->output_offset
+ + irel->r_offset - 2);
+
+ gap = value - dot;
+
+ /* If the distance is within -126..+130 inclusive, then we can
+ relax this jump. +130 is valid since the target will move
+ two bytes closer if we do relax this branch. */
+ if ((int) gap >= -126 && (int) gap <= 130)
+ {
+ unsigned char code;
+
+ /* Note that we've changed the relocs, section contents,
+ etc. */
+ elf_section_data (sec)->relocs = internal_relocs;
+ elf_section_data (sec)->this_hdr.contents = contents;
+ symtab_hdr->contents = (unsigned char *) isymbuf;
+
+ /* Get the opcode. */
+ code = bfd_get_8 (abfd, contents + irel->r_offset - 2);
+
+ if (code == 0x58)
+ {
+ /* bCC:16 -> bCC:8 */
+ /* Get the second byte of the original insn, which
+ contains the condition code. */
+ code = bfd_get_8 (abfd, contents + irel->r_offset - 1);
+
+ /* Compute the first byte of the relaxed
+ instruction. The original sequence 0x58 0xX0
+ is relaxed to 0x4X, where X represents the
+ condition code. */
+ code &= 0xf0;
+ code >>= 4;
+ code |= 0x40;
+ bfd_put_8 (abfd, code, contents + irel->r_offset - 2); /* bCC:8. */
+ }
+ else if (code == 0x5c) /* bsr16. */
+ /* This is bsr. */
+ bfd_put_8 (abfd, 0x55, contents + irel->r_offset - 2); /* bsr8. */
+ else
+ /* Might be MOVSD. */
+ break;
+
+ /* Fix the relocation's type. */
+ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
+ R_H8_PCREL8);
+ irel->r_offset--;
+
+ /* Delete two bytes of data. */
+ if (!elf32_h8_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;
+ }
+
+ /* This is a 16-bit absolute address in one of the following
+ instructions:
+
+ "band", "bclr", "biand", "bild", "bior", "bist", "bixor",
+ "bld", "bnot", "bor", "bset", "bst", "btst", "bxor", and
+ "mov.b"
+
+ We may relax this into an 8-bit absolute address if it's in
+ the right range. */
+ case R_H8_DIR16A8:
+ {
+ bfd_vma value;
+
+ value = bfd_h8300_pad_address (abfd, symval + irel->r_addend);
+ if (value >= 0xffffff00u)
+ {
+ unsigned char code;
+ unsigned char temp_code;
+
+ /* Note that we've changed the relocs, section contents,
+ etc. */
+ elf_section_data (sec)->relocs = internal_relocs;
+ elf_section_data (sec)->this_hdr.contents = contents;
+ symtab_hdr->contents = (unsigned char *) isymbuf;
+
+ /* Get the opcode. */
+ code = bfd_get_8 (abfd, contents + irel->r_offset - 2);
+
+ /* All instructions with R_H8_DIR16A8 start with
+ 0x6a. */
+ if (code != 0x6a)
+ abort ();
+
+ temp_code = code = bfd_get_8 (abfd, contents + irel->r_offset - 1);
+ /* If this is a mov.b instruction, clear the lower
+ nibble, which contains the source/destination
+ register number. */
+ if ((temp_code & 0x10) != 0x10)
+ temp_code &= 0xf0;
+
+ switch (temp_code)
+ {
+ case 0x00:
+ /* This is mov.b @aa:16,Rd. */
+ bfd_put_8 (abfd, (code & 0xf) | 0x20,
+ contents + irel->r_offset - 2);
+ break;
+ case 0x80:
+ /* This is mov.b Rs,@aa:16. */
+ bfd_put_8 (abfd, (code & 0xf) | 0x30,
+ contents + irel->r_offset - 2);
+ break;
+ case 0x18:
+ /* This is a bit-maniputation instruction that
+ stores one bit into memory, one of "bclr",
+ "bist", "bnot", "bset", and "bst". */
+ bfd_put_8 (abfd, 0x7f, contents + irel->r_offset - 2);
+ break;
+ case 0x10:
+ /* This is a bit-maniputation instruction that
+ loads one bit from memory, one of "band",
+ "biand", "bild", "bior", "bixor", "bld", "bor",
+ "btst", and "bxor". */
+ bfd_put_8 (abfd, 0x7e, contents + irel->r_offset - 2);
+ break;
+ default:
+ abort ();
+ }
+
+ /* Fix the relocation's type. */
+ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
+ R_H8_DIR8);
+
+ /* Move the relocation. */
+ irel->r_offset--;
+
+ /* Delete two bytes of data. */
+ if (!elf32_h8_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;
+ }
+
+ /* This is a 24-bit absolute address in one of the following
+ instructions:
+
+ "band", "bclr", "biand", "bild", "bior", "bist", "bixor",
+ "bld", "bnot", "bor", "bset", "bst", "btst", "bxor", and
+ "mov.b"
+
+ We may relax this into an 8-bit absolute address if it's in
+ the right range. */
+ case R_H8_DIR24A8:
+ {
+ bfd_vma value;
+
+ value = bfd_h8300_pad_address (abfd, symval + irel->r_addend);
+ if (value >= 0xffffff00u)
+ {
+ unsigned char code;
+ unsigned char temp_code;
+
+ /* Note that we've changed the relocs, section contents,
+ etc. */
+ elf_section_data (sec)->relocs = internal_relocs;
+ elf_section_data (sec)->this_hdr.contents = contents;
+ symtab_hdr->contents = (unsigned char *) isymbuf;
+
+ /* Get the opcode. */
+ code = bfd_get_8 (abfd, contents + irel->r_offset - 2);
+
+ /* All instructions with R_H8_DIR24A8 start with
+ 0x6a. */
+ if (code != 0x6a)
+ abort ();
+
+ temp_code = code = bfd_get_8 (abfd, contents + irel->r_offset - 1);
+
+ /* If this is a mov.b instruction, clear the lower
+ nibble, which contains the source/destination
+ register number. */
+ if ((temp_code & 0x30) != 0x30)
+ temp_code &= 0xf0;
+
+ switch (temp_code)
+ {
+ case 0x20:
+ /* This is mov.b @aa:24/32,Rd. */
+ bfd_put_8 (abfd, (code & 0xf) | 0x20,
+ contents + irel->r_offset - 2);
+ break;
+ case 0xa0:
+ /* This is mov.b Rs,@aa:24/32. */
+ bfd_put_8 (abfd, (code & 0xf) | 0x30,
+ contents + irel->r_offset - 2);
+ break;
+ case 0x38:
+ /* This is a bit-maniputation instruction that
+ stores one bit into memory, one of "bclr",
+ "bist", "bnot", "bset", and "bst". */
+ bfd_put_8 (abfd, 0x7f, contents + irel->r_offset - 2);
+ break;
+ case 0x30:
+ /* This is a bit-maniputation instruction that
+ loads one bit from memory, one of "band",
+ "biand", "bild", "bior", "bixor", "bld", "bor",
+ "btst", and "bxor". */
+ bfd_put_8 (abfd, 0x7e, contents + irel->r_offset - 2);
+ break;
+ default:
+ abort();
+ }
+
+ /* Fix the relocation's type. */
+ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
+ R_H8_DIR8);
+ irel->r_offset--;
+
+ /* Delete four bytes of data. */
+ if (!elf32_h8_relax_delete_bytes (abfd, sec,
+ irel->r_offset + 1, 4))
+ 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;
+ }
+ }
+
+ /* Fall through. */
+
+ /* This is a 24-/32-bit absolute address in one of the
+ following instructions:
+
+ "band", "bclr", "biand", "bild", "bior", "bist",
+ "bixor", "bld", "bnot", "bor", "bset", "bst", "btst",
+ "bxor", "ldc.w", "stc.w" and "mov.[bwl]"
+
+ We may relax this into an 16-bit absolute address if it's
+ in the right range. */
+ case R_H8_DIR32A16:
+ {
+ bfd_vma value;
+
+ value = bfd_h8300_pad_address (abfd, symval + irel->r_addend);
+ if (value <= 0x7fff || value >= 0xffff8000u)
+ {
+ unsigned char code;
+ unsigned char op0, op1, op2, op3;
+ unsigned char *op_ptr;
+
+ /* Note that we've changed the relocs, section contents,
+ etc. */
+ elf_section_data (sec)->relocs = internal_relocs;
+ elf_section_data (sec)->this_hdr.contents = contents;
+ symtab_hdr->contents = (unsigned char *) isymbuf;
+
+ if (irel->r_offset >= 4)
+ {
+ /* Check for 4-byte MOVA relaxation (SH-specific). */
+ int second_reloc = 0;
+
+ op_ptr = contents + irel->r_offset - 4;
+
+ if (last_reloc)
+ {
+ arelent bfd_reloc;
+ reloc_howto_type *h;
+ bfd_vma last_reloc_size;
+
+ elf32_h8_info_to_howto (abfd, &bfd_reloc, last_reloc);
+ h = bfd_reloc.howto;
+ last_reloc_size = 1 << h->size;
+ if (last_reloc->r_offset + last_reloc_size
+ == irel->r_offset)
+ {
+ op_ptr -= last_reloc_size;
+ second_reloc = 1;
+ }
+ }
+
+ if (irel + 1 < irelend)
+ {
+ Elf_Internal_Rela *next_reloc = irel + 1;
+ arelent bfd_reloc;
+ reloc_howto_type *h;
+ bfd_vma next_reloc_size;
+
+ elf32_h8_info_to_howto (abfd, &bfd_reloc, next_reloc);
+ h = bfd_reloc.howto;
+ next_reloc_size = 1 << h->size;
+ if (next_reloc->r_offset + next_reloc_size
+ == irel->r_offset)
+ {
+ op_ptr -= next_reloc_size;
+ second_reloc = 1;
+ }
+ }
+
+ op0 = bfd_get_8 (abfd, op_ptr + 0);
+ op1 = bfd_get_8 (abfd, op_ptr + 1);
+ op2 = bfd_get_8 (abfd, op_ptr + 2);
+ op3 = bfd_get_8 (abfd, op_ptr + 3);
+
+ if (op0 == 0x01
+ && (op1 & 0xdf) == 0x5f
+ && (op2 & 0x40) == 0x40
+ && (op3 & 0x80) == 0x80)
+ {
+ if ((op2 & 0x08) == 0)
+ second_reloc = 1;
+
+ if (second_reloc)
+ {
+ op3 &= ~0x08;
+ bfd_put_8 (abfd, op3, op_ptr + 3);
+ }
+ else
+ {
+ op2 &= ~0x08;
+ bfd_put_8 (abfd, op2, op_ptr + 2);
+ }
+ goto r_h8_dir32a16_common;
+ }
+ }
+
+ /* Now check for short version of MOVA. (SH-specific) */
+ op_ptr = contents + irel->r_offset - 2;
+ op0 = bfd_get_8 (abfd, op_ptr + 0);
+ op1 = bfd_get_8 (abfd, op_ptr + 1);
+
+ if (op0 == 0x7a
+ && (op1 & 0x88) == 0x80)
+ {
+ op1 |= 0x08;
+ bfd_put_8 (abfd, op1, op_ptr + 1);
+ goto r_h8_dir32a16_common;
+ }
+
+ /* Get the opcode. */
+ code = bfd_get_8 (abfd, contents + irel->r_offset - 1);
+
+ /* Fix the opcode. For all the instructions that
+ belong to this relaxation, we simply need to turn
+ off bit 0x20 in the previous byte. */
+ code &= ~0x20;
+
+ bfd_put_8 (abfd, code, contents + irel->r_offset - 1);
+
+ r_h8_dir32a16_common:
+ /* Fix the relocation's type. */
+ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
+ R_H8_DIR16);
+
+ /* Delete two bytes of data. */
+ if (!elf32_h8_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; /* case R_H8_DIR32A16 */
+ }
+
+ case R_H8_DISP32A16:
+ /* mov.[bwl] @(displ:24/32+ERx) -> mov.[bwl] @(displ:16+ERx) 4 bytes
+ It is assured that instruction uses at least 4 bytes opcode before
+ reloc entry addressing mode "register indirect with displacement"
+ relaxing options (all saving 4 bytes):
+ 0x78 0sss0000 0x6A 0010dddd disp:32 mov.b @(d:32,ERs),Rd ->
+ 0x6E 0sssdddd disp:16 mov.b @(d:16,ERs),Rd
+ 0x78 0sss0000 0x6B 0010dddd disp:32 mov.w @(d:32,ERs),Rd ->
+ 0x6F 0sssdddd disp:16 mov.w @(d:16,ERs),Rd
+ 0x01 0x00 0x78 0sss0000 0x6B 00100ddd disp:32 mov.l @(d:32,ERs),ERd ->
+ 0x01 0x00 0x6F 0sss0ddd disp:16 mov.l @(d:16,ERs),ERd
+
+ 0x78 0ddd0000 0x6A 1010ssss disp:32 mov.b Rs,@(d:32,ERd) ->
+ 0x6E 1dddssss disp:16 mov.b Rs,@(d:16,ERd)
+ 0x78 0ddd0000 0x6B 1010ssss disp:32 mov.w Rs,@(d:32,ERd) ->
+ 0x6F 1dddssss disp:16 mov.w Rs,@(d:16,ERd)
+ 0x01 0x00 0x78 xddd0000 0x6B 10100sss disp:32 mov.l ERs,@(d:32,ERd) ->
+ 0x01 0x00 0x6F 1ddd0sss disp:16 mov.l ERs,@(d:16,ERd)
+ mov.l prefix 0x01 0x00 can be left as is and mov.l handled same
+ as mov.w/ */
+ {
+ bfd_vma value;
+
+ value = bfd_h8300_pad_address (abfd, symval + irel->r_addend);
+ if (value <= 0x7fff || value >= 0xffff8000u)
+ {
+ unsigned char op0, op1, op2, op3, op0n, op1n;
+ int relax = 0;
+
+ /* Note that we've changed the relocs, section contents,
+ etc. */
+ elf_section_data (sec)->relocs = internal_relocs;
+ elf_section_data (sec)->this_hdr.contents = contents;
+ symtab_hdr->contents = (unsigned char *) isymbuf;
+
+ if (irel->r_offset >= 4)
+ {
+ op0 = bfd_get_8 (abfd, contents + irel->r_offset - 4);
+ op1 = bfd_get_8 (abfd, contents + irel->r_offset - 3);
+ op2 = bfd_get_8 (abfd, contents + irel->r_offset - 2);
+ op3 = bfd_get_8 (abfd, contents + irel->r_offset - 1);
+
+ if (op0 == 0x78)
+ {
+ switch(op2)
+ {
+ case 0x6A:
+ if ((op1 & 0x8F) == 0x00 && (op3 & 0x70) == 0x20)
+ {
+ /* mov.b. */
+ op0n = 0x6E;
+ relax = 1;
+ }
+ break;
+ case 0x6B:
+ if ((op1 & 0x0F) == 0x00 && (op3 & 0x70) == 0x20)
+ {
+ /* mov.w/l. */
+ op0n = 0x6F;
+ relax = 1;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ if (relax)
+ {
+ op1n = (op3 & 0x8F) | (op1 & 0x70);
+ bfd_put_8 (abfd, op0n, contents + irel->r_offset - 4);
+ bfd_put_8 (abfd, op1n, contents + irel->r_offset - 3);
+
+ /* Fix the relocation's type. */
+ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info), R_H8_DIR16);
+ irel->r_offset -= 2;
+
+ /* Delete four bytes of data. */
+ if (!elf32_h8_relax_delete_bytes (abfd, sec, irel->r_offset + 2, 4))
+ 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;
+
+ default:
+ break;
+ }
+ }
+
+ if (isymbuf != NULL
+ && symtab_hdr->contents != (unsigned char *) isymbuf)
+ {
+ if (! link_info->keep_memory)
+ free (isymbuf);
+ else
+ symtab_hdr->contents = (unsigned char *) isymbuf;
+ }
+
+ if (contents != NULL
+ && elf_section_data (sec)->this_hdr.contents != contents)
+ {
+ if (! link_info->keep_memory)
+ free (contents);
+ else
+ {
+ /* Cache the section contents for elf_link_input_bfd. */
+ elf_section_data (sec)->this_hdr.contents = contents;
+ }
+ }
+
+ if (internal_relocs != NULL
+ && elf_section_data (sec)->relocs != internal_relocs)
+ free (internal_relocs);
+
+ return TRUE;
+
+ error_return:
+ if (isymbuf != NULL
+ && symtab_hdr->contents != (unsigned char *) isymbuf)
+ free (isymbuf);
+ if (contents != NULL
+ && elf_section_data (sec)->this_hdr.contents != contents)
+ free (contents);
+ if (internal_relocs != NULL
+ && elf_section_data (sec)->relocs != internal_relocs)
+ free (internal_relocs);
+ return FALSE;
+}
+
+/* Delete some bytes from a section while relaxing. */
+
+static bfd_boolean
+elf32_h8_relax_delete_bytes (bfd *abfd, asection *sec, bfd_vma addr, int count)
+{
+ Elf_Internal_Shdr *symtab_hdr;
+ unsigned int sec_shndx;
+ bfd_byte *contents;
+ Elf_Internal_Rela *irel, *irelend;
+ Elf_Internal_Sym *isym;
+ Elf_Internal_Sym *isymend;
+ bfd_vma toaddr;
+ struct elf_link_hash_entry **sym_hashes;
+ struct elf_link_hash_entry **end_hashes;
+ unsigned int symcount;
+
+ sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
+
+ contents = elf_section_data (sec)->this_hdr.contents;
+
+ toaddr = sec->size;
+
+ irel = elf_section_data (sec)->relocs;
+ irelend = irel + sec->reloc_count;
+
+ /* Actually delete the bytes. */
+ memmove (contents + addr, contents + addr + count,
+ (size_t) (toaddr - addr - count));
+ sec->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. */
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+ isym = (Elf_Internal_Sym *) symtab_hdr->contents;
+ isymend = isym + symtab_hdr->sh_info;
+ for (; isym < isymend; isym++)
+ {
+ if (isym->st_shndx == sec_shndx
+ && isym->st_value > addr
+ && isym->st_value <= toaddr)
+ isym->st_value -= count;
+ }
+
+ /* Now adjust the global symbols defined in this section. */
+ symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
+ - symtab_hdr->sh_info);
+ sym_hashes = elf_sym_hashes (abfd);
+ end_hashes = sym_hashes + symcount;
+ for (; sym_hashes < end_hashes; sym_hashes++)
+ {
+ struct elf_link_hash_entry *sym_hash = *sym_hashes;
+
+ 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
+ && 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 bfd_boolean
+elf32_h8_symbol_address_p (bfd *abfd, asection *sec, bfd_vma addr)
+{
+ Elf_Internal_Shdr *symtab_hdr;
+ unsigned int sec_shndx;
+ Elf_Internal_Sym *isym;
+ Elf_Internal_Sym *isymend;
+ struct elf_link_hash_entry **sym_hashes;
+ struct elf_link_hash_entry **end_hashes;
+ unsigned int symcount;
+
+ sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
+
+ /* Examine all the symbols. */
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+ isym = (Elf_Internal_Sym *) symtab_hdr->contents;
+ isymend = isym + symtab_hdr->sh_info;
+ for (; isym < isymend; isym++)
+ {
+ if (isym->st_shndx == sec_shndx
+ && isym->st_value == addr)
+ return TRUE;
+ }
+
+ symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
+ - symtab_hdr->sh_info);
+ sym_hashes = elf_sym_hashes (abfd);
+ end_hashes = sym_hashes + symcount;
+ for (; sym_hashes < end_hashes; sym_hashes++)
+ {
+ struct elf_link_hash_entry *sym_hash = *sym_hashes;
+ 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 elf32_h8_relocate_section. */
+
+static bfd_byte *
+elf32_h8_get_relocated_section_contents (bfd *output_bfd,
+ struct bfd_link_info *link_info,
+ struct bfd_link_order *link_order,
+ bfd_byte *data,
+ bfd_boolean relocatable,
+ 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;
+ Elf_Internal_Sym *isymbuf = NULL;
+
+ /* We only need to handle the case of relaxing, or of having a
+ particular set of section contents, specially. */
+ if (relocatable
+ || elf_section_data (input_section)->this_hdr.contents == NULL)
+ return bfd_generic_get_relocated_section_contents (output_bfd, link_info,
+ link_order, data,
+ relocatable,
+ symbols);
+
+ symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
+
+ memcpy (data, elf_section_data (input_section)->this_hdr.contents,
+ (size_t) input_section->size);
+
+ if ((input_section->flags & SEC_RELOC) != 0
+ && input_section->reloc_count > 0)
+ {
+ asection **secpp;
+ Elf_Internal_Sym *isym, *isymend;
+ bfd_size_type amt;
+
+ internal_relocs = (_bfd_elf_link_read_relocs
+ (input_bfd, input_section, NULL,
+ (Elf_Internal_Rela *) NULL, FALSE));
+ if (internal_relocs == NULL)
+ goto error_return;
+
+ if (symtab_hdr->sh_info != 0)
+ {
+ isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
+ if (isymbuf == NULL)
+ isymbuf = bfd_elf_get_elf_syms (input_bfd, symtab_hdr,
+ symtab_hdr->sh_info, 0,
+ NULL, NULL, NULL);
+ if (isymbuf == NULL)
+ goto error_return;
+ }
+
+ amt = symtab_hdr->sh_info;
+ amt *= sizeof (asection *);
+ sections = (asection **) bfd_malloc (amt);
+ if (sections == NULL && amt != 0)
+ goto error_return;
+
+ isymend = isymbuf + symtab_hdr->sh_info;
+ for (isym = isymbuf, secpp = sections; isym < isymend; ++isym, ++secpp)
+ {
+ asection *isec;
+
+ if (isym->st_shndx == SHN_UNDEF)
+ isec = bfd_und_section_ptr;
+ 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
+ isec = bfd_section_from_elf_index (input_bfd, isym->st_shndx);
+
+ *secpp = isec;
+ }
+
+ if (! elf32_h8_relocate_section (output_bfd, link_info, input_bfd,
+ input_section, data, internal_relocs,
+ isymbuf, sections))
+ goto error_return;
+
+ if (sections != NULL)
+ free (sections);
+ if (isymbuf != NULL
+ && symtab_hdr->contents != (unsigned char *) isymbuf)
+ free (isymbuf);
+ if (elf_section_data (input_section)->relocs != internal_relocs)
+ free (internal_relocs);
+ }
+
+ return data;
+
+ error_return:
+ if (sections != NULL)
+ free (sections);
+ if (isymbuf != NULL
+ && symtab_hdr->contents != (unsigned char *) isymbuf)
+ free (isymbuf);
+ if (internal_relocs != NULL
+ && elf_section_data (input_section)->relocs != internal_relocs)
+ free (internal_relocs);
+ return NULL;
+}
+
+
+#define TARGET_BIG_SYM h8300_elf32_vec
+#define TARGET_BIG_NAME "elf32-h8300"
+#define ELF_ARCH bfd_arch_h8300
+#define ELF_MACHINE_CODE EM_H8_300
+#define ELF_MAXPAGESIZE 0x1
+#define bfd_elf32_bfd_reloc_type_lookup elf32_h8_reloc_type_lookup
+#define bfd_elf32_bfd_reloc_name_lookup elf32_h8_reloc_name_lookup
+#define elf_info_to_howto elf32_h8_info_to_howto
+#define elf_info_to_howto_rel elf32_h8_info_to_howto_rel
+
+/* So we can set/examine bits in e_flags to get the specific
+ H8 architecture in use. */
+#define elf_backend_final_write_processing \
+ elf32_h8_final_write_processing
+#define elf_backend_object_p \
+ elf32_h8_object_p
+#define bfd_elf32_bfd_merge_private_bfd_data \
+ elf32_h8_merge_private_bfd_data
+
+/* ??? when elf_backend_relocate_section is not defined, elf32-target.h
+ defaults to using _bfd_generic_link_hash_table_create, but
+ bfd_elf_size_dynamic_sections uses
+ dynobj = elf_hash_table (info)->dynobj;
+ and thus requires an elf hash table. */
+#define bfd_elf32_bfd_link_hash_table_create _bfd_elf_link_hash_table_create
+
+/* Use an H8 specific linker, not the ELF generic linker. */
+#define elf_backend_relocate_section elf32_h8_relocate_section
+#define elf_backend_rela_normal 1
+#define elf_backend_can_gc_sections 1
+
+/* And relaxing stuff. */
+#define bfd_elf32_bfd_relax_section elf32_h8_relax_section
+#define bfd_elf32_bfd_get_relocated_section_contents \
+ elf32_h8_get_relocated_section_contents
+
+#define elf_symbol_leading_char '_'
+
+#include "elf32-target.h"
diff --git a/bfd/elf32-hppa.c b/bfd/elf32-hppa.c
new file mode 100644
index 0000000..0588ebb
--- /dev/null
+++ b/bfd/elf32-hppa.c
@@ -0,0 +1,4693 @@
+/* BFD back-end for HP PA-RISC ELF files.
+ Copyright (C) 1990-2014 Free Software Foundation, Inc.
+
+ Original code by
+ Center for Software Science
+ Department of Computer Science
+ University of Utah
+ Largely rewritten by Alan Modra <alan@linuxcare.com.au>
+ Naming cleanup by Carlos O'Donell <carlos@systemhalted.org>
+ TLS support written by Randolph Chung <tausq@debian.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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+#include "elf-bfd.h"
+#include "elf/hppa.h"
+#include "libhppa.h"
+#include "elf32-hppa.h"
+#define ARCH_SIZE 32
+#include "elf32-hppa.h"
+#include "elf-hppa.h"
+
+/* In order to gain some understanding of code in this file without
+ knowing all the intricate details of the linker, note the
+ following:
+
+ Functions named elf32_hppa_* are called by external routines, other
+ functions are only called locally. elf32_hppa_* functions appear
+ in this file more or less in the order in which they are called
+ from external routines. eg. elf32_hppa_check_relocs is called
+ early in the link process, elf32_hppa_finish_dynamic_sections is
+ one of the last functions. */
+
+/* We use two 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.
+
+ There are a number of different stubs generated by the linker.
+
+ Long branch stub:
+ : ldil LR'X,%r1
+ : be,n RR'X(%sr4,%r1)
+
+ PIC long branch stub:
+ : b,l .+8,%r1
+ : addil LR'X - ($PIC_pcrel$0 - 4),%r1
+ : be,n RR'X - ($PIC_pcrel$0 - 8)(%sr4,%r1)
+
+ Import stub to call shared library routine from normal object file
+ (single sub-space version)
+ : addil LR'lt_ptr+ltoff,%dp ; get procedure entry point
+ : ldw RR'lt_ptr+ltoff(%r1),%r21
+ : bv %r0(%r21)
+ : ldw RR'lt_ptr+ltoff+4(%r1),%r19 ; get new dlt value.
+
+ Import stub to call shared library routine from shared library
+ (single sub-space version)
+ : addil LR'ltoff,%r19 ; get procedure entry point
+ : ldw RR'ltoff(%r1),%r21
+ : bv %r0(%r21)
+ : ldw RR'ltoff+4(%r1),%r19 ; get new dlt value.
+
+ Import stub to call shared library routine from normal object file
+ (multiple sub-space support)
+ : addil LR'lt_ptr+ltoff,%dp ; get procedure entry point
+ : ldw RR'lt_ptr+ltoff(%r1),%r21
+ : ldw RR'lt_ptr+ltoff+4(%r1),%r19 ; get new dlt value.
+ : ldsid (%r21),%r1
+ : mtsp %r1,%sr0
+ : be 0(%sr0,%r21) ; branch to target
+ : stw %rp,-24(%sp) ; save rp
+
+ Import stub to call shared library routine from shared library
+ (multiple sub-space support)
+ : addil LR'ltoff,%r19 ; get procedure entry point
+ : ldw RR'ltoff(%r1),%r21
+ : ldw RR'ltoff+4(%r1),%r19 ; get new dlt value.
+ : ldsid (%r21),%r1
+ : mtsp %r1,%sr0
+ : be 0(%sr0,%r21) ; branch to target
+ : stw %rp,-24(%sp) ; save rp
+
+ Export stub to return from shared lib routine (multiple sub-space support)
+ One of these is created for each exported procedure in a shared
+ library (and stored in the shared lib). Shared lib routines are
+ called via the first instruction in the export stub so that we can
+ do an inter-space return. Not required for single sub-space.
+ : bl,n X,%rp ; trap the return
+ : nop
+ : ldw -24(%sp),%rp ; restore the original rp
+ : ldsid (%rp),%r1
+ : mtsp %r1,%sr0
+ : be,n 0(%sr0,%rp) ; inter-space return. */
+
+
+/* Variable names follow a coding style.
+ Please follow this (Apps Hungarian) style:
+
+ Structure/Variable Prefix
+ elf_link_hash_table "etab"
+ elf_link_hash_entry "eh"
+
+ elf32_hppa_link_hash_table "htab"
+ elf32_hppa_link_hash_entry "hh"
+
+ bfd_hash_table "btab"
+ bfd_hash_entry "bh"
+
+ bfd_hash_table containing stubs "bstab"
+ elf32_hppa_stub_hash_entry "hsh"
+
+ elf32_hppa_dyn_reloc_entry "hdh"
+
+ Always remember to use GNU Coding Style. */
+
+#define PLT_ENTRY_SIZE 8
+#define GOT_ENTRY_SIZE 4
+#define ELF_DYNAMIC_INTERPRETER "/lib/ld.so.1"
+
+static const bfd_byte plt_stub[] =
+{
+ 0x0e, 0x80, 0x10, 0x96, /* 1: ldw 0(%r20),%r22 */
+ 0xea, 0xc0, 0xc0, 0x00, /* bv %r0(%r22) */
+ 0x0e, 0x88, 0x10, 0x95, /* ldw 4(%r20),%r21 */
+#define PLT_STUB_ENTRY (3*4)
+ 0xea, 0x9f, 0x1f, 0xdd, /* b,l 1b,%r20 */
+ 0xd6, 0x80, 0x1c, 0x1e, /* depi 0,31,2,%r20 */
+ 0x00, 0xc0, 0xff, 0xee, /* 9: .word fixup_func */
+ 0xde, 0xad, 0xbe, 0xef /* .word fixup_ltp */
+};
+
+/* Section name for stubs is the associated section name plus this
+ string. */
+#define STUB_SUFFIX ".stub"
+
+/* We don't need to copy certain PC- or GP-relative dynamic relocs
+ into a shared object's dynamic section. All the relocs of the
+ limited class we are interested in, are absolute. */
+#ifndef RELATIVE_DYNRELOCS
+#define RELATIVE_DYNRELOCS 0
+#define IS_ABSOLUTE_RELOC(r_type) 1
+#endif
+
+/* If ELIMINATE_COPY_RELOCS is non-zero, the linker will try to avoid
+ copying dynamic variables from a shared lib into an app's dynbss
+ section, and instead use a dynamic relocation to point into the
+ shared lib. */
+#define ELIMINATE_COPY_RELOCS 1
+
+enum elf32_hppa_stub_type
+{
+ hppa_stub_long_branch,
+ hppa_stub_long_branch_shared,
+ hppa_stub_import,
+ hppa_stub_import_shared,
+ hppa_stub_export,
+ hppa_stub_none
+};
+
+struct elf32_hppa_stub_hash_entry
+{
+ /* Base hash table entry structure. */
+ struct bfd_hash_entry bh_root;
+
+ /* The stub section. */
+ asection *stub_sec;
+
+ /* Offset within stub_sec of the beginning of this stub. */
+ bfd_vma stub_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. */
+ bfd_vma target_value;
+ asection *target_section;
+
+ enum elf32_hppa_stub_type stub_type;
+
+ /* The symbol table entry, if any, that this was derived from. */
+ struct elf32_hppa_link_hash_entry *hh;
+
+ /* Where this stub is being called from, or, in the case of combined
+ stub sections, the first input section in the group. */
+ asection *id_sec;
+};
+
+struct elf32_hppa_link_hash_entry
+{
+ struct elf_link_hash_entry eh;
+
+ /* A pointer to the most recently used stub hash entry against this
+ symbol. */
+ struct elf32_hppa_stub_hash_entry *hsh_cache;
+
+ /* Used to count relocations for delayed sizing of relocation
+ sections. */
+ struct elf32_hppa_dyn_reloc_entry
+ {
+ /* Next relocation in the chain. */
+ struct elf32_hppa_dyn_reloc_entry *hdh_next;
+
+ /* The input section of the reloc. */
+ asection *sec;
+
+ /* Number of relocs copied in this section. */
+ bfd_size_type count;
+
+#if RELATIVE_DYNRELOCS
+ /* Number of relative relocs copied for the input section. */
+ bfd_size_type relative_count;
+#endif
+ } *dyn_relocs;
+
+ enum
+ {
+ GOT_UNKNOWN = 0, GOT_NORMAL = 1, GOT_TLS_GD = 2, GOT_TLS_LDM = 4, GOT_TLS_IE = 8
+ } tls_type;
+
+ /* Set if this symbol is used by a plabel reloc. */
+ unsigned int plabel:1;
+};
+
+struct elf32_hppa_link_hash_table
+{
+ /* The main hash table. */
+ struct elf_link_hash_table etab;
+
+ /* The stub hash table. */
+ struct bfd_hash_table bstab;
+
+ /* Linker stub bfd. */
+ bfd *stub_bfd;
+
+ /* Linker call-backs. */
+ asection * (*add_stub_section) (const char *, asection *);
+ void (*layout_sections_again) (void);
+
+ /* Array to keep track of which stub sections have been created, and
+ information on stub grouping. */
+ struct map_stub
+ {
+ /* This is the section to which stubs in the group will be
+ attached. */
+ asection *link_sec;
+ /* The stub section. */
+ asection *stub_sec;
+ } *stub_group;
+
+ /* Assorted information used by elf32_hppa_size_stubs. */
+ unsigned int bfd_count;
+ int top_index;
+ asection **input_list;
+ Elf_Internal_Sym **all_local_syms;
+
+ /* Short-cuts to get to dynamic linker sections. */
+ asection *sgot;
+ asection *srelgot;
+ asection *splt;
+ asection *srelplt;
+ asection *sdynbss;
+ asection *srelbss;
+
+ /* Used during a final link to store the base of the text and data
+ segments so that we can perform SEGREL relocations. */
+ bfd_vma text_segment_base;
+ bfd_vma data_segment_base;
+
+ /* Whether we support multiple sub-spaces for shared libs. */
+ unsigned int multi_subspace:1;
+
+ /* Flags set when various size branches are detected. Used to
+ select suitable defaults for the stub group size. */
+ unsigned int has_12bit_branch:1;
+ unsigned int has_17bit_branch:1;
+ unsigned int has_22bit_branch:1;
+
+ /* Set if we need a .plt stub to support lazy dynamic linking. */
+ unsigned int need_plt_stub:1;
+
+ /* Small local sym cache. */
+ struct sym_cache sym_cache;
+
+ /* Data for LDM relocations. */
+ union
+ {
+ bfd_signed_vma refcount;
+ bfd_vma offset;
+ } tls_ldm_got;
+};
+
+/* Various hash macros and functions. */
+#define hppa_link_hash_table(p) \
+ (elf_hash_table_id ((struct elf_link_hash_table *) ((p)->hash)) \
+ == HPPA32_ELF_DATA ? ((struct elf32_hppa_link_hash_table *) ((p)->hash)) : NULL)
+
+#define hppa_elf_hash_entry(ent) \
+ ((struct elf32_hppa_link_hash_entry *)(ent))
+
+#define hppa_stub_hash_entry(ent) \
+ ((struct elf32_hppa_stub_hash_entry *)(ent))
+
+#define hppa_stub_hash_lookup(table, string, create, copy) \
+ ((struct elf32_hppa_stub_hash_entry *) \
+ bfd_hash_lookup ((table), (string), (create), (copy)))
+
+#define hppa_elf_local_got_tls_type(abfd) \
+ ((char *)(elf_local_got_offsets (abfd) + (elf_tdata (abfd)->symtab_hdr.sh_info * 2)))
+
+#define hh_name(hh) \
+ (hh ? hh->eh.root.root.string : "<undef>")
+
+#define eh_name(eh) \
+ (eh ? eh->root.root.string : "<undef>")
+
+/* Assorted hash table functions. */
+
+/* Initialize an entry in the stub hash table. */
+
+static struct bfd_hash_entry *
+stub_hash_newfunc (struct bfd_hash_entry *entry,
+ struct bfd_hash_table *table,
+ const char *string)
+{
+ /* Allocate the structure if it has not already been allocated by a
+ subclass. */
+ if (entry == NULL)
+ {
+ entry = bfd_hash_allocate (table,
+ sizeof (struct elf32_hppa_stub_hash_entry));
+ if (entry == NULL)
+ return entry;
+ }
+
+ /* Call the allocation method of the superclass. */
+ entry = bfd_hash_newfunc (entry, table, string);
+ if (entry != NULL)
+ {
+ struct elf32_hppa_stub_hash_entry *hsh;
+
+ /* Initialize the local fields. */
+ hsh = hppa_stub_hash_entry (entry);
+ hsh->stub_sec = NULL;
+ hsh->stub_offset = 0;
+ hsh->target_value = 0;
+ hsh->target_section = NULL;
+ hsh->stub_type = hppa_stub_long_branch;
+ hsh->hh = NULL;
+ hsh->id_sec = NULL;
+ }
+
+ return entry;
+}
+
+/* Initialize an entry in the link hash table. */
+
+static struct bfd_hash_entry *
+hppa_link_hash_newfunc (struct bfd_hash_entry *entry,
+ struct bfd_hash_table *table,
+ const char *string)
+{
+ /* Allocate the structure if it has not already been allocated by a
+ subclass. */
+ if (entry == NULL)
+ {
+ entry = bfd_hash_allocate (table,
+ sizeof (struct elf32_hppa_link_hash_entry));
+ if (entry == NULL)
+ return entry;
+ }
+
+ /* Call the allocation method of the superclass. */
+ entry = _bfd_elf_link_hash_newfunc (entry, table, string);
+ if (entry != NULL)
+ {
+ struct elf32_hppa_link_hash_entry *hh;
+
+ /* Initialize the local fields. */
+ hh = hppa_elf_hash_entry (entry);
+ hh->hsh_cache = NULL;
+ hh->dyn_relocs = NULL;
+ hh->plabel = 0;
+ hh->tls_type = GOT_UNKNOWN;
+ }
+
+ return entry;
+}
+
+/* Free the derived linker hash table. */
+
+static void
+elf32_hppa_link_hash_table_free (bfd *obfd)
+{
+ struct elf32_hppa_link_hash_table *htab
+ = (struct elf32_hppa_link_hash_table *) obfd->link.hash;
+
+ bfd_hash_table_free (&htab->bstab);
+ _bfd_elf_link_hash_table_free (obfd);
+}
+
+/* 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 (bfd *abfd)
+{
+ struct elf32_hppa_link_hash_table *htab;
+ bfd_size_type amt = sizeof (*htab);
+
+ htab = bfd_zmalloc (amt);
+ if (htab == NULL)
+ return NULL;
+
+ if (!_bfd_elf_link_hash_table_init (&htab->etab, abfd, hppa_link_hash_newfunc,
+ sizeof (struct elf32_hppa_link_hash_entry),
+ HPPA32_ELF_DATA))
+ {
+ free (htab);
+ return NULL;
+ }
+
+ /* Init the stub hash table too. */
+ if (!bfd_hash_table_init (&htab->bstab, stub_hash_newfunc,
+ sizeof (struct elf32_hppa_stub_hash_entry)))
+ {
+ _bfd_elf_link_hash_table_free (abfd);
+ return NULL;
+ }
+ htab->etab.root.hash_table_free = elf32_hppa_link_hash_table_free;
+
+ htab->text_segment_base = (bfd_vma) -1;
+ htab->data_segment_base = (bfd_vma) -1;
+ return &htab->etab.root;
+}
+
+/* Build a name for an entry in the stub hash table. */
+
+static char *
+hppa_stub_name (const asection *input_section,
+ const asection *sym_sec,
+ const struct elf32_hppa_link_hash_entry *hh,
+ const Elf_Internal_Rela *rela)
+{
+ char *stub_name;
+ bfd_size_type len;
+
+ if (hh)
+ {
+ len = 8 + 1 + strlen (hh_name (hh)) + 1 + 8 + 1;
+ stub_name = bfd_malloc (len);
+ if (stub_name != NULL)
+ sprintf (stub_name, "%08x_%s+%x",
+ input_section->id & 0xffffffff,
+ hh_name (hh),
+ (int) rela->r_addend & 0xffffffff);
+ }
+ else
+ {
+ len = 8 + 1 + 8 + 1 + 8 + 1 + 8 + 1;
+ stub_name = bfd_malloc (len);
+ if (stub_name != NULL)
+ sprintf (stub_name, "%08x_%x:%x+%x",
+ input_section->id & 0xffffffff,
+ sym_sec->id & 0xffffffff,
+ (int) ELF32_R_SYM (rela->r_info) & 0xffffffff,
+ (int) rela->r_addend & 0xffffffff);
+ }
+ return stub_name;
+}
+
+/* Look up an entry in the stub hash. Stub entries are cached because
+ creating the stub name takes a bit of time. */
+
+static struct elf32_hppa_stub_hash_entry *
+hppa_get_stub_entry (const asection *input_section,
+ const asection *sym_sec,
+ struct elf32_hppa_link_hash_entry *hh,
+ const Elf_Internal_Rela *rela,
+ struct elf32_hppa_link_hash_table *htab)
+{
+ struct elf32_hppa_stub_hash_entry *hsh_entry;
+ const asection *id_sec;
+
+ /* If this input section is part of a group of sections sharing one
+ stub section, then use the id of the first section in the group.
+ Stub names need to include a section id, as there may well be
+ more than one stub used to reach say, printf, and we need to
+ distinguish between them. */
+ id_sec = htab->stub_group[input_section->id].link_sec;
+
+ if (hh != NULL && hh->hsh_cache != NULL
+ && hh->hsh_cache->hh == hh
+ && hh->hsh_cache->id_sec == id_sec)
+ {
+ hsh_entry = hh->hsh_cache;
+ }
+ else
+ {
+ char *stub_name;
+
+ stub_name = hppa_stub_name (id_sec, sym_sec, hh, rela);
+ if (stub_name == NULL)
+ return NULL;
+
+ hsh_entry = hppa_stub_hash_lookup (&htab->bstab,
+ stub_name, FALSE, FALSE);
+ if (hh != NULL)
+ hh->hsh_cache = hsh_entry;
+
+ free (stub_name);
+ }
+
+ return hsh_entry;
+}
+
+/* Add a new stub entry to the stub hash. Not all fields of the new
+ stub entry are initialised. */
+
+static struct elf32_hppa_stub_hash_entry *
+hppa_add_stub (const char *stub_name,
+ asection *section,
+ struct elf32_hppa_link_hash_table *htab)
+{
+ asection *link_sec;
+ asection *stub_sec;
+ struct elf32_hppa_stub_hash_entry *hsh;
+
+ link_sec = htab->stub_group[section->id].link_sec;
+ stub_sec = htab->stub_group[section->id].stub_sec;
+ if (stub_sec == NULL)
+ {
+ stub_sec = htab->stub_group[link_sec->id].stub_sec;
+ if (stub_sec == NULL)
+ {
+ size_t namelen;
+ bfd_size_type len;
+ char *s_name;
+
+ namelen = strlen (link_sec->name);
+ len = namelen + sizeof (STUB_SUFFIX);
+ s_name = bfd_alloc (htab->stub_bfd, len);
+ if (s_name == NULL)
+ return NULL;
+
+ memcpy (s_name, link_sec->name, namelen);
+ memcpy (s_name + namelen, STUB_SUFFIX, sizeof (STUB_SUFFIX));
+ stub_sec = (*htab->add_stub_section) (s_name, link_sec);
+ if (stub_sec == NULL)
+ return NULL;
+ htab->stub_group[link_sec->id].stub_sec = stub_sec;
+ }
+ htab->stub_group[section->id].stub_sec = stub_sec;
+ }
+
+ /* Enter this entry into the linker stub hash table. */
+ hsh = hppa_stub_hash_lookup (&htab->bstab, stub_name,
+ TRUE, FALSE);
+ if (hsh == NULL)
+ {
+ (*_bfd_error_handler) (_("%B: cannot create stub entry %s"),
+ section->owner,
+ stub_name);
+ return NULL;
+ }
+
+ hsh->stub_sec = stub_sec;
+ hsh->stub_offset = 0;
+ hsh->id_sec = link_sec;
+ return hsh;
+}
+
+/* Determine the type of stub needed, if any, for a call. */
+
+static enum elf32_hppa_stub_type
+hppa_type_of_stub (asection *input_sec,
+ const Elf_Internal_Rela *rela,
+ struct elf32_hppa_link_hash_entry *hh,
+ bfd_vma destination,
+ struct bfd_link_info *info)
+{
+ bfd_vma location;
+ bfd_vma branch_offset;
+ bfd_vma max_branch_offset;
+ unsigned int r_type;
+
+ if (hh != NULL
+ && hh->eh.plt.offset != (bfd_vma) -1
+ && hh->eh.dynindx != -1
+ && !hh->plabel
+ && (info->shared
+ || !hh->eh.def_regular
+ || hh->eh.root.type == bfd_link_hash_defweak))
+ {
+ /* We need an import stub. Decide between hppa_stub_import
+ and hppa_stub_import_shared later. */
+ return hppa_stub_import;
+ }
+
+ /* Determine where the call point is. */
+ location = (input_sec->output_offset
+ + input_sec->output_section->vma
+ + rela->r_offset);
+
+ branch_offset = destination - location - 8;
+ r_type = ELF32_R_TYPE (rela->r_info);
+
+ /* Determine if a long branch stub is needed. parisc branch offsets
+ are relative to the second instruction past the branch, ie. +8
+ bytes on from the branch instruction location. The offset is
+ signed and counts in units of 4 bytes. */
+ if (r_type == (unsigned int) R_PARISC_PCREL17F)
+ max_branch_offset = (1 << (17 - 1)) << 2;
+
+ else if (r_type == (unsigned int) R_PARISC_PCREL12F)
+ max_branch_offset = (1 << (12 - 1)) << 2;
+
+ else /* R_PARISC_PCREL22F. */
+ max_branch_offset = (1 << (22 - 1)) << 2;
+
+ if (branch_offset + max_branch_offset >= 2*max_branch_offset)
+ return hppa_stub_long_branch;
+
+ return hppa_stub_none;
+}
+
+/* Build one linker stub as defined by the stub hash table entry GEN_ENTRY.
+ IN_ARG contains the link info pointer. */
+
+#define LDIL_R1 0x20200000 /* ldil LR'XXX,%r1 */
+#define BE_SR4_R1 0xe0202002 /* be,n RR'XXX(%sr4,%r1) */
+
+#define BL_R1 0xe8200000 /* b,l .+8,%r1 */
+#define ADDIL_R1 0x28200000 /* addil LR'XXX,%r1,%r1 */
+#define DEPI_R1 0xd4201c1e /* depi 0,31,2,%r1 */
+
+#define ADDIL_DP 0x2b600000 /* addil LR'XXX,%dp,%r1 */
+#define LDW_R1_R21 0x48350000 /* ldw RR'XXX(%sr0,%r1),%r21 */
+#define BV_R0_R21 0xeaa0c000 /* bv %r0(%r21) */
+#define LDW_R1_R19 0x48330000 /* ldw RR'XXX(%sr0,%r1),%r19 */
+
+#define ADDIL_R19 0x2a600000 /* addil LR'XXX,%r19,%r1 */
+#define LDW_R1_DP 0x483b0000 /* ldw RR'XXX(%sr0,%r1),%dp */
+
+#define LDSID_R21_R1 0x02a010a1 /* ldsid (%sr0,%r21),%r1 */
+#define MTSP_R1 0x00011820 /* mtsp %r1,%sr0 */
+#define BE_SR0_R21 0xe2a00000 /* be 0(%sr0,%r21) */
+#define STW_RP 0x6bc23fd1 /* stw %rp,-24(%sr0,%sp) */
+
+#define BL22_RP 0xe800a002 /* b,l,n XXX,%rp */
+#define BL_RP 0xe8400002 /* b,l,n XXX,%rp */
+#define NOP 0x08000240 /* nop */
+#define LDW_RP 0x4bc23fd1 /* ldw -24(%sr0,%sp),%rp */
+#define LDSID_RP_R1 0x004010a1 /* ldsid (%sr0,%rp),%r1 */
+#define BE_SR0_RP 0xe0400002 /* be,n 0(%sr0,%rp) */
+
+#ifndef R19_STUBS
+#define R19_STUBS 1
+#endif
+
+#if R19_STUBS
+#define LDW_R1_DLT LDW_R1_R19
+#else
+#define LDW_R1_DLT LDW_R1_DP
+#endif
+
+static bfd_boolean
+hppa_build_one_stub (struct bfd_hash_entry *bh, void *in_arg)
+{
+ struct elf32_hppa_stub_hash_entry *hsh;
+ struct bfd_link_info *info;
+ struct elf32_hppa_link_hash_table *htab;
+ asection *stub_sec;
+ bfd *stub_bfd;
+ bfd_byte *loc;
+ bfd_vma sym_value;
+ bfd_vma insn;
+ bfd_vma off;
+ int val;
+ int size;
+
+ /* Massage our args to the form they really have. */
+ hsh = hppa_stub_hash_entry (bh);
+ info = (struct bfd_link_info *)in_arg;
+
+ htab = hppa_link_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ stub_sec = hsh->stub_sec;
+
+ /* Make a note of the offset within the stubs for this entry. */
+ hsh->stub_offset = stub_sec->size;
+ loc = stub_sec->contents + hsh->stub_offset;
+
+ stub_bfd = stub_sec->owner;
+
+ switch (hsh->stub_type)
+ {
+ case hppa_stub_long_branch:
+ /* Create the long branch. 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.
+ The "be" has its delay slot nullified. */
+ sym_value = (hsh->target_value
+ + hsh->target_section->output_offset
+ + hsh->target_section->output_section->vma);
+
+ val = hppa_field_adjust (sym_value, 0, e_lrsel);
+ insn = hppa_rebuild_insn ((int) LDIL_R1, val, 21);
+ bfd_put_32 (stub_bfd, insn, loc);
+
+ val = hppa_field_adjust (sym_value, 0, e_rrsel) >> 2;
+ insn = hppa_rebuild_insn ((int) BE_SR4_R1, val, 17);
+ bfd_put_32 (stub_bfd, insn, loc + 4);
+
+ size = 8;
+ break;
+
+ case hppa_stub_long_branch_shared:
+ /* Branches are relative. This is where we are going to. */
+ sym_value = (hsh->target_value
+ + hsh->target_section->output_offset
+ + hsh->target_section->output_section->vma);
+
+ /* And this is where we are coming from, more or less. */
+ sym_value -= (hsh->stub_offset
+ + stub_sec->output_offset
+ + stub_sec->output_section->vma);
+
+ bfd_put_32 (stub_bfd, (bfd_vma) BL_R1, loc);
+ val = hppa_field_adjust (sym_value, (bfd_signed_vma) -8, e_lrsel);
+ insn = hppa_rebuild_insn ((int) ADDIL_R1, val, 21);
+ bfd_put_32 (stub_bfd, insn, loc + 4);
+
+ val = hppa_field_adjust (sym_value, (bfd_signed_vma) -8, e_rrsel) >> 2;
+ insn = hppa_rebuild_insn ((int) BE_SR4_R1, val, 17);
+ bfd_put_32 (stub_bfd, insn, loc + 8);
+ size = 12;
+ break;
+
+ case hppa_stub_import:
+ case hppa_stub_import_shared:
+ off = hsh->hh->eh.plt.offset;
+ if (off >= (bfd_vma) -2)
+ abort ();
+
+ off &= ~ (bfd_vma) 1;
+ sym_value = (off
+ + htab->splt->output_offset
+ + htab->splt->output_section->vma
+ - elf_gp (htab->splt->output_section->owner));
+
+ insn = ADDIL_DP;
+#if R19_STUBS
+ if (hsh->stub_type == hppa_stub_import_shared)
+ insn = ADDIL_R19;
+#endif
+ val = hppa_field_adjust (sym_value, 0, e_lrsel),
+ insn = hppa_rebuild_insn ((int) insn, val, 21);
+ bfd_put_32 (stub_bfd, insn, loc);
+
+ /* It is critical to use lrsel/rrsel here because we are using
+ two different offsets (+0 and +4) from sym_value. If we use
+ lsel/rsel then with unfortunate sym_values we will round
+ sym_value+4 up to the next 2k block leading to a mis-match
+ between the lsel and rsel value. */
+ val = hppa_field_adjust (sym_value, 0, e_rrsel);
+ insn = hppa_rebuild_insn ((int) LDW_R1_R21, val, 14);
+ bfd_put_32 (stub_bfd, insn, loc + 4);
+
+ if (htab->multi_subspace)
+ {
+ val = hppa_field_adjust (sym_value, (bfd_signed_vma) 4, e_rrsel);
+ insn = hppa_rebuild_insn ((int) LDW_R1_DLT, val, 14);
+ bfd_put_32 (stub_bfd, insn, loc + 8);
+
+ bfd_put_32 (stub_bfd, (bfd_vma) LDSID_R21_R1, loc + 12);
+ bfd_put_32 (stub_bfd, (bfd_vma) MTSP_R1, loc + 16);
+ bfd_put_32 (stub_bfd, (bfd_vma) BE_SR0_R21, loc + 20);
+ bfd_put_32 (stub_bfd, (bfd_vma) STW_RP, loc + 24);
+
+ size = 28;
+ }
+ else
+ {
+ bfd_put_32 (stub_bfd, (bfd_vma) BV_R0_R21, loc + 8);
+ val = hppa_field_adjust (sym_value, (bfd_signed_vma) 4, e_rrsel);
+ insn = hppa_rebuild_insn ((int) LDW_R1_DLT, val, 14);
+ bfd_put_32 (stub_bfd, insn, loc + 12);
+
+ size = 16;
+ }
+
+ break;
+
+ case hppa_stub_export:
+ /* Branches are relative. This is where we are going to. */
+ sym_value = (hsh->target_value
+ + hsh->target_section->output_offset
+ + hsh->target_section->output_section->vma);
+
+ /* And this is where we are coming from. */
+ sym_value -= (hsh->stub_offset
+ + stub_sec->output_offset
+ + stub_sec->output_section->vma);
+
+ if (sym_value - 8 + (1 << (17 + 1)) >= (1 << (17 + 2))
+ && (!htab->has_22bit_branch
+ || sym_value - 8 + (1 << (22 + 1)) >= (1 << (22 + 2))))
+ {
+ (*_bfd_error_handler)
+ (_("%B(%A+0x%lx): cannot reach %s, recompile with -ffunction-sections"),
+ hsh->target_section->owner,
+ stub_sec,
+ (long) hsh->stub_offset,
+ hsh->bh_root.string);
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+
+ val = hppa_field_adjust (sym_value, (bfd_signed_vma) -8, e_fsel) >> 2;
+ if (!htab->has_22bit_branch)
+ insn = hppa_rebuild_insn ((int) BL_RP, val, 17);
+ else
+ insn = hppa_rebuild_insn ((int) BL22_RP, val, 22);
+ bfd_put_32 (stub_bfd, insn, loc);
+
+ bfd_put_32 (stub_bfd, (bfd_vma) NOP, loc + 4);
+ bfd_put_32 (stub_bfd, (bfd_vma) LDW_RP, loc + 8);
+ bfd_put_32 (stub_bfd, (bfd_vma) LDSID_RP_R1, loc + 12);
+ bfd_put_32 (stub_bfd, (bfd_vma) MTSP_R1, loc + 16);
+ bfd_put_32 (stub_bfd, (bfd_vma) BE_SR0_RP, loc + 20);
+
+ /* Point the function symbol at the stub. */
+ hsh->hh->eh.root.u.def.section = stub_sec;
+ hsh->hh->eh.root.u.def.value = stub_sec->size;
+
+ size = 24;
+ break;
+
+ default:
+ BFD_FAIL ();
+ return FALSE;
+ }
+
+ stub_sec->size += size;
+ return TRUE;
+}
+
+#undef LDIL_R1
+#undef BE_SR4_R1
+#undef BL_R1
+#undef ADDIL_R1
+#undef DEPI_R1
+#undef LDW_R1_R21
+#undef LDW_R1_DLT
+#undef LDW_R1_R19
+#undef ADDIL_R19
+#undef LDW_R1_DP
+#undef LDSID_R21_R1
+#undef MTSP_R1
+#undef BE_SR0_R21
+#undef STW_RP
+#undef BV_R0_R21
+#undef BL_RP
+#undef NOP
+#undef LDW_RP
+#undef LDSID_RP_R1
+#undef BE_SR0_RP
+
+/* As above, but don't actually build the stub. Just bump offset so
+ we know stub section sizes. */
+
+static bfd_boolean
+hppa_size_one_stub (struct bfd_hash_entry *bh, void *in_arg)
+{
+ struct elf32_hppa_stub_hash_entry *hsh;
+ struct elf32_hppa_link_hash_table *htab;
+ int size;
+
+ /* Massage our args to the form they really have. */
+ hsh = hppa_stub_hash_entry (bh);
+ htab = in_arg;
+
+ if (hsh->stub_type == hppa_stub_long_branch)
+ size = 8;
+ else if (hsh->stub_type == hppa_stub_long_branch_shared)
+ size = 12;
+ else if (hsh->stub_type == hppa_stub_export)
+ size = 24;
+ else /* hppa_stub_import or hppa_stub_import_shared. */
+ {
+ if (htab->multi_subspace)
+ size = 28;
+ else
+ size = 16;
+ }
+
+ hsh->stub_sec->size += size;
+ return TRUE;
+}
+
+/* Return nonzero if ABFD represents an HPPA ELF32 file.
+ Additionally we set the default architecture and machine. */
+
+static bfd_boolean
+elf32_hppa_object_p (bfd *abfd)
+{
+ Elf_Internal_Ehdr * i_ehdrp;
+ unsigned int flags;
+
+ i_ehdrp = elf_elfheader (abfd);
+ if (strcmp (bfd_get_target (abfd), "elf32-hppa-linux") == 0)
+ {
+ /* GCC on hppa-linux produces binaries with OSABI=GNU,
+ but the kernel produces corefiles with OSABI=SysV. */
+ if (i_ehdrp->e_ident[EI_OSABI] != ELFOSABI_GNU &&
+ i_ehdrp->e_ident[EI_OSABI] != ELFOSABI_NONE) /* aka SYSV */
+ return FALSE;
+ }
+ else if (strcmp (bfd_get_target (abfd), "elf32-hppa-netbsd") == 0)
+ {
+ /* GCC on hppa-netbsd produces binaries with OSABI=NetBSD,
+ but the kernel produces corefiles with OSABI=SysV. */
+ if (i_ehdrp->e_ident[EI_OSABI] != ELFOSABI_NETBSD &&
+ i_ehdrp->e_ident[EI_OSABI] != ELFOSABI_NONE) /* aka SYSV */
+ return FALSE;
+ }
+ else
+ {
+ if (i_ehdrp->e_ident[EI_OSABI] != ELFOSABI_HPUX)
+ return FALSE;
+ }
+
+ flags = i_ehdrp->e_flags;
+ switch (flags & (EF_PARISC_ARCH | EF_PARISC_WIDE))
+ {
+ case EFA_PARISC_1_0:
+ return bfd_default_set_arch_mach (abfd, bfd_arch_hppa, 10);
+ case EFA_PARISC_1_1:
+ return bfd_default_set_arch_mach (abfd, bfd_arch_hppa, 11);
+ case EFA_PARISC_2_0:
+ return bfd_default_set_arch_mach (abfd, bfd_arch_hppa, 20);
+ case EFA_PARISC_2_0 | EF_PARISC_WIDE:
+ return bfd_default_set_arch_mach (abfd, bfd_arch_hppa, 25);
+ }
+ return TRUE;
+}
+
+/* Create the .plt and .got sections, and set up our hash table
+ short-cuts to various dynamic sections. */
+
+static bfd_boolean
+elf32_hppa_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
+{
+ struct elf32_hppa_link_hash_table *htab;
+ struct elf_link_hash_entry *eh;
+
+ /* Don't try to create the .plt and .got twice. */
+ htab = hppa_link_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+ if (htab->splt != NULL)
+ return TRUE;
+
+ /* Call the generic code to do most of the work. */
+ if (! _bfd_elf_create_dynamic_sections (abfd, info))
+ return FALSE;
+
+ htab->splt = bfd_get_linker_section (abfd, ".plt");
+ htab->srelplt = bfd_get_linker_section (abfd, ".rela.plt");
+
+ htab->sgot = bfd_get_linker_section (abfd, ".got");
+ htab->srelgot = bfd_get_linker_section (abfd, ".rela.got");
+
+ htab->sdynbss = bfd_get_linker_section (abfd, ".dynbss");
+ htab->srelbss = bfd_get_linker_section (abfd, ".rela.bss");
+
+ /* hppa-linux needs _GLOBAL_OFFSET_TABLE_ to be visible from the main
+ application, because __canonicalize_funcptr_for_compare needs it. */
+ eh = elf_hash_table (info)->hgot;
+ eh->forced_local = 0;
+ eh->other = STV_DEFAULT;
+ return bfd_elf_link_record_dynamic_symbol (info, eh);
+}
+
+/* Copy the extra info we tack onto an elf_link_hash_entry. */
+
+static void
+elf32_hppa_copy_indirect_symbol (struct bfd_link_info *info,
+ struct elf_link_hash_entry *eh_dir,
+ struct elf_link_hash_entry *eh_ind)
+{
+ struct elf32_hppa_link_hash_entry *hh_dir, *hh_ind;
+
+ hh_dir = hppa_elf_hash_entry (eh_dir);
+ hh_ind = hppa_elf_hash_entry (eh_ind);
+
+ if (hh_ind->dyn_relocs != NULL)
+ {
+ if (hh_dir->dyn_relocs != NULL)
+ {
+ struct elf32_hppa_dyn_reloc_entry **hdh_pp;
+ struct elf32_hppa_dyn_reloc_entry *hdh_p;
+
+ /* Add reloc counts against the indirect sym to the direct sym
+ list. Merge any entries against the same section. */
+ for (hdh_pp = &hh_ind->dyn_relocs; (hdh_p = *hdh_pp) != NULL; )
+ {
+ struct elf32_hppa_dyn_reloc_entry *hdh_q;
+
+ for (hdh_q = hh_dir->dyn_relocs;
+ hdh_q != NULL;
+ hdh_q = hdh_q->hdh_next)
+ if (hdh_q->sec == hdh_p->sec)
+ {
+#if RELATIVE_DYNRELOCS
+ hdh_q->relative_count += hdh_p->relative_count;
+#endif
+ hdh_q->count += hdh_p->count;
+ *hdh_pp = hdh_p->hdh_next;
+ break;
+ }
+ if (hdh_q == NULL)
+ hdh_pp = &hdh_p->hdh_next;
+ }
+ *hdh_pp = hh_dir->dyn_relocs;
+ }
+
+ hh_dir->dyn_relocs = hh_ind->dyn_relocs;
+ hh_ind->dyn_relocs = NULL;
+ }
+
+ if (ELIMINATE_COPY_RELOCS
+ && eh_ind->root.type != bfd_link_hash_indirect
+ && eh_dir->dynamic_adjusted)
+ {
+ /* If called to transfer flags for a weakdef during processing
+ of elf_adjust_dynamic_symbol, don't copy non_got_ref.
+ We clear it ourselves for ELIMINATE_COPY_RELOCS. */
+ eh_dir->ref_dynamic |= eh_ind->ref_dynamic;
+ eh_dir->ref_regular |= eh_ind->ref_regular;
+ eh_dir->ref_regular_nonweak |= eh_ind->ref_regular_nonweak;
+ eh_dir->needs_plt |= eh_ind->needs_plt;
+ }
+ else
+ {
+ if (eh_ind->root.type == bfd_link_hash_indirect
+ && eh_dir->got.refcount <= 0)
+ {
+ hh_dir->tls_type = hh_ind->tls_type;
+ hh_ind->tls_type = GOT_UNKNOWN;
+ }
+
+ _bfd_elf_link_hash_copy_indirect (info, eh_dir, eh_ind);
+ }
+}
+
+static int
+elf32_hppa_optimized_tls_reloc (struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ int r_type, int is_local ATTRIBUTE_UNUSED)
+{
+ /* For now we don't support linker optimizations. */
+ return r_type;
+}
+
+/* Return a pointer to the local GOT, PLT and TLS reference counts
+ for ABFD. Returns NULL if the storage allocation fails. */
+
+static bfd_signed_vma *
+hppa32_elf_local_refcounts (bfd *abfd)
+{
+ Elf_Internal_Shdr *symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+ bfd_signed_vma *local_refcounts;
+
+ local_refcounts = elf_local_got_refcounts (abfd);
+ if (local_refcounts == NULL)
+ {
+ bfd_size_type size;
+
+ /* Allocate space for local GOT and PLT reference
+ counts. Done this way to save polluting elf_obj_tdata
+ with another target specific pointer. */
+ size = symtab_hdr->sh_info;
+ size *= 2 * sizeof (bfd_signed_vma);
+ /* Add in space to store the local GOT TLS types. */
+ size += symtab_hdr->sh_info;
+ local_refcounts = bfd_zalloc (abfd, size);
+ if (local_refcounts == NULL)
+ return NULL;
+ elf_local_got_refcounts (abfd) = local_refcounts;
+ memset (hppa_elf_local_got_tls_type (abfd), GOT_UNKNOWN,
+ symtab_hdr->sh_info);
+ }
+ return local_refcounts;
+}
+
+
+/* Look through the relocs for a section during the first phase, and
+ calculate needed space in the global offset table, procedure linkage
+ table, and dynamic reloc sections. At this point we haven't
+ necessarily read all the input files. */
+
+static bfd_boolean
+elf32_hppa_check_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 **eh_syms;
+ const Elf_Internal_Rela *rela;
+ const Elf_Internal_Rela *rela_end;
+ struct elf32_hppa_link_hash_table *htab;
+ asection *sreloc;
+ int tls_type = GOT_UNKNOWN, old_tls_type = GOT_UNKNOWN;
+
+ if (info->relocatable)
+ return TRUE;
+
+ htab = hppa_link_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+ eh_syms = elf_sym_hashes (abfd);
+ sreloc = NULL;
+
+ rela_end = relocs + sec->reloc_count;
+ for (rela = relocs; rela < rela_end; rela++)
+ {
+ enum {
+ NEED_GOT = 1,
+ NEED_PLT = 2,
+ NEED_DYNREL = 4,
+ PLT_PLABEL = 8
+ };
+
+ unsigned int r_symndx, r_type;
+ struct elf32_hppa_link_hash_entry *hh;
+ int need_entry = 0;
+
+ r_symndx = ELF32_R_SYM (rela->r_info);
+
+ if (r_symndx < symtab_hdr->sh_info)
+ hh = NULL;
+ else
+ {
+ hh = hppa_elf_hash_entry (eh_syms[r_symndx - symtab_hdr->sh_info]);
+ while (hh->eh.root.type == bfd_link_hash_indirect
+ || hh->eh.root.type == bfd_link_hash_warning)
+ hh = hppa_elf_hash_entry (hh->eh.root.u.i.link);
+
+ /* PR15323, ref flags aren't set for references in the same
+ object. */
+ hh->eh.root.non_ir_ref = 1;
+ }
+
+ r_type = ELF32_R_TYPE (rela->r_info);
+ r_type = elf32_hppa_optimized_tls_reloc (info, r_type, hh == NULL);
+
+ switch (r_type)
+ {
+ case R_PARISC_DLTIND14F:
+ case R_PARISC_DLTIND14R:
+ case R_PARISC_DLTIND21L:
+ /* This symbol requires a global offset table entry. */
+ need_entry = NEED_GOT;
+ break;
+
+ case R_PARISC_PLABEL14R: /* "Official" procedure labels. */
+ case R_PARISC_PLABEL21L:
+ case R_PARISC_PLABEL32:
+ /* If the addend is non-zero, we break badly. */
+ if (rela->r_addend != 0)
+ abort ();
+
+ /* If we are creating a shared library, then we need to
+ create a PLT entry for all PLABELs, because PLABELs with
+ local symbols may be passed via a pointer to another
+ object. Additionally, output a dynamic relocation
+ pointing to the PLT entry.
+
+ For executables, the original 32-bit ABI allowed two
+ different styles of PLABELs (function pointers): For
+ global functions, the PLABEL word points into the .plt
+ two bytes past a (function address, gp) pair, and for
+ local functions the PLABEL points directly at the
+ function. The magic +2 for the first type allows us to
+ differentiate between the two. As you can imagine, this
+ is a real pain when it comes to generating code to call
+ functions indirectly or to compare function pointers.
+ We avoid the mess by always pointing a PLABEL into the
+ .plt, even for local functions. */
+ need_entry = PLT_PLABEL | NEED_PLT | NEED_DYNREL;
+ break;
+
+ case R_PARISC_PCREL12F:
+ htab->has_12bit_branch = 1;
+ goto branch_common;
+
+ case R_PARISC_PCREL17C:
+ case R_PARISC_PCREL17F:
+ htab->has_17bit_branch = 1;
+ goto branch_common;
+
+ case R_PARISC_PCREL22F:
+ htab->has_22bit_branch = 1;
+ branch_common:
+ /* Function calls might need to go through the .plt, and
+ might require long branch stubs. */
+ if (hh == NULL)
+ {
+ /* We know local syms won't need a .plt entry, and if
+ they need a long branch stub we can't guarantee that
+ we can reach the stub. So just flag an error later
+ if we're doing a shared link and find we need a long
+ branch stub. */
+ continue;
+ }
+ else
+ {
+ /* Global symbols will need a .plt entry if they remain
+ global, and in most cases won't need a long branch
+ stub. Unfortunately, we have to cater for the case
+ where a symbol is forced local by versioning, or due
+ to symbolic linking, and we lose the .plt entry. */
+ need_entry = NEED_PLT;
+ if (hh->eh.type == STT_PARISC_MILLI)
+ need_entry = 0;
+ }
+ break;
+
+ case R_PARISC_SEGBASE: /* Used to set segment base. */
+ case R_PARISC_SEGREL32: /* Relative reloc, used for unwind. */
+ case R_PARISC_PCREL14F: /* PC relative load/store. */
+ case R_PARISC_PCREL14R:
+ case R_PARISC_PCREL17R: /* External branches. */
+ case R_PARISC_PCREL21L: /* As above, and for load/store too. */
+ case R_PARISC_PCREL32:
+ /* We don't need to propagate the relocation if linking a
+ shared object since these are section relative. */
+ continue;
+
+ case R_PARISC_DPREL14F: /* Used for gp rel data load/store. */
+ case R_PARISC_DPREL14R:
+ case R_PARISC_DPREL21L:
+ if (info->shared)
+ {
+ (*_bfd_error_handler)
+ (_("%B: relocation %s can not be used when making a shared object; recompile with -fPIC"),
+ abfd,
+ elf_hppa_howto_table[r_type].name);
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+ /* Fall through. */
+
+ case R_PARISC_DIR17F: /* Used for external branches. */
+ case R_PARISC_DIR17R:
+ case R_PARISC_DIR14F: /* Used for load/store from absolute locn. */
+ case R_PARISC_DIR14R:
+ case R_PARISC_DIR21L: /* As above, and for ext branches too. */
+ case R_PARISC_DIR32: /* .word relocs. */
+ /* We may want to output a dynamic relocation later. */
+ need_entry = NEED_DYNREL;
+ break;
+
+ /* This relocation describes the C++ object vtable hierarchy.
+ Reconstruct it for later use during GC. */
+ case R_PARISC_GNU_VTINHERIT:
+ if (!bfd_elf_gc_record_vtinherit (abfd, sec, &hh->eh, rela->r_offset))
+ return FALSE;
+ continue;
+
+ /* This relocation describes which C++ vtable entries are actually
+ used. Record for later use during GC. */
+ case R_PARISC_GNU_VTENTRY:
+ BFD_ASSERT (hh != NULL);
+ if (hh != NULL
+ && !bfd_elf_gc_record_vtentry (abfd, sec, &hh->eh, rela->r_addend))
+ return FALSE;
+ continue;
+
+ case R_PARISC_TLS_GD21L:
+ case R_PARISC_TLS_GD14R:
+ case R_PARISC_TLS_LDM21L:
+ case R_PARISC_TLS_LDM14R:
+ need_entry = NEED_GOT;
+ break;
+
+ case R_PARISC_TLS_IE21L:
+ case R_PARISC_TLS_IE14R:
+ if (info->shared)
+ info->flags |= DF_STATIC_TLS;
+ need_entry = NEED_GOT;
+ break;
+
+ default:
+ continue;
+ }
+
+ /* Now carry out our orders. */
+ if (need_entry & NEED_GOT)
+ {
+ switch (r_type)
+ {
+ default:
+ tls_type = GOT_NORMAL;
+ break;
+ case R_PARISC_TLS_GD21L:
+ case R_PARISC_TLS_GD14R:
+ tls_type |= GOT_TLS_GD;
+ break;
+ case R_PARISC_TLS_LDM21L:
+ case R_PARISC_TLS_LDM14R:
+ tls_type |= GOT_TLS_LDM;
+ break;
+ case R_PARISC_TLS_IE21L:
+ case R_PARISC_TLS_IE14R:
+ tls_type |= GOT_TLS_IE;
+ break;
+ }
+
+ /* Allocate space for a GOT entry, as well as a dynamic
+ relocation for this entry. */
+ if (htab->sgot == NULL)
+ {
+ if (htab->etab.dynobj == NULL)
+ htab->etab.dynobj = abfd;
+ if (!elf32_hppa_create_dynamic_sections (htab->etab.dynobj, info))
+ return FALSE;
+ }
+
+ if (r_type == R_PARISC_TLS_LDM21L
+ || r_type == R_PARISC_TLS_LDM14R)
+ htab->tls_ldm_got.refcount += 1;
+ else
+ {
+ if (hh != NULL)
+ {
+ hh->eh.got.refcount += 1;
+ old_tls_type = hh->tls_type;
+ }
+ else
+ {
+ bfd_signed_vma *local_got_refcounts;
+
+ /* This is a global offset table entry for a local symbol. */
+ local_got_refcounts = hppa32_elf_local_refcounts (abfd);
+ if (local_got_refcounts == NULL)
+ return FALSE;
+ local_got_refcounts[r_symndx] += 1;
+
+ old_tls_type = hppa_elf_local_got_tls_type (abfd) [r_symndx];
+ }
+
+ tls_type |= old_tls_type;
+
+ if (old_tls_type != tls_type)
+ {
+ if (hh != NULL)
+ hh->tls_type = tls_type;
+ else
+ hppa_elf_local_got_tls_type (abfd) [r_symndx] = tls_type;
+ }
+
+ }
+ }
+
+ if (need_entry & NEED_PLT)
+ {
+ /* If we are creating a shared library, and this is a reloc
+ against a weak symbol or a global symbol in a dynamic
+ object, then we will be creating an import stub and a
+ .plt entry for the symbol. Similarly, on a normal link
+ to symbols defined in a dynamic object we'll need the
+ import stub and a .plt entry. We don't know yet whether
+ the symbol is defined or not, so make an entry anyway and
+ clean up later in adjust_dynamic_symbol. */
+ if ((sec->flags & SEC_ALLOC) != 0)
+ {
+ if (hh != NULL)
+ {
+ hh->eh.needs_plt = 1;
+ hh->eh.plt.refcount += 1;
+
+ /* If this .plt entry is for a plabel, mark it so
+ that adjust_dynamic_symbol will keep the entry
+ even if it appears to be local. */
+ if (need_entry & PLT_PLABEL)
+ hh->plabel = 1;
+ }
+ else if (need_entry & PLT_PLABEL)
+ {
+ bfd_signed_vma *local_got_refcounts;
+ bfd_signed_vma *local_plt_refcounts;
+
+ local_got_refcounts = hppa32_elf_local_refcounts (abfd);
+ if (local_got_refcounts == NULL)
+ return FALSE;
+ local_plt_refcounts = (local_got_refcounts
+ + symtab_hdr->sh_info);
+ local_plt_refcounts[r_symndx] += 1;
+ }
+ }
+ }
+
+ if (need_entry & NEED_DYNREL)
+ {
+ /* Flag this symbol as having a non-got, non-plt reference
+ so that we generate copy relocs if it turns out to be
+ dynamic. */
+ if (hh != NULL && !info->shared)
+ hh->eh.non_got_ref = 1;
+
+ /* If we are creating a shared library then we need to copy
+ the reloc into the shared library. However, if we are
+ linking with -Bsymbolic, we need only copy absolute
+ relocs or relocs against symbols that are not defined in
+ an object we are including in the link. PC- or DP- or
+ DLT-relative relocs against any local sym or global sym
+ with DEF_REGULAR set, can be discarded. 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 dyn_relocs field of the
+ hash table entry.
+
+ A similar situation to the -Bsymbolic case occurs when
+ creating shared libraries and symbol visibility changes
+ render the symbol local.
+
+ As it turns out, all the relocs we will be creating here
+ are absolute, so we cannot remove them on -Bsymbolic
+ links or visibility changes anyway. A STUB_REL reloc
+ is absolute too, as in that case it is the reloc in the
+ stub we will be creating, rather than copying the PCREL
+ reloc in the branch.
+
+ If on the other hand, we are creating an executable, we
+ may need to keep relocations for symbols satisfied by a
+ dynamic library if we manage to avoid copy relocs for the
+ symbol. */
+ if ((info->shared
+ && (sec->flags & SEC_ALLOC) != 0
+ && (IS_ABSOLUTE_RELOC (r_type)
+ || (hh != NULL
+ && (!info->symbolic
+ || hh->eh.root.type == bfd_link_hash_defweak
+ || !hh->eh.def_regular))))
+ || (ELIMINATE_COPY_RELOCS
+ && !info->shared
+ && (sec->flags & SEC_ALLOC) != 0
+ && hh != NULL
+ && (hh->eh.root.type == bfd_link_hash_defweak
+ || !hh->eh.def_regular)))
+ {
+ struct elf32_hppa_dyn_reloc_entry *hdh_p;
+ struct elf32_hppa_dyn_reloc_entry **hdh_head;
+
+ /* Create a reloc section in dynobj and make room for
+ this reloc. */
+ if (sreloc == NULL)
+ {
+ if (htab->etab.dynobj == NULL)
+ htab->etab.dynobj = abfd;
+
+ sreloc = _bfd_elf_make_dynamic_reloc_section
+ (sec, htab->etab.dynobj, 2, abfd, /*rela?*/ TRUE);
+
+ if (sreloc == NULL)
+ {
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+ }
+
+ /* If this is a global symbol, we count the number of
+ relocations we need for this symbol. */
+ if (hh != NULL)
+ {
+ hdh_head = &hh->dyn_relocs;
+ }
+ else
+ {
+ /* Track dynamic relocs needed for local syms too.
+ We really need local syms available to do this
+ easily. Oh well. */
+ asection *sr;
+ void *vpp;
+ Elf_Internal_Sym *isym;
+
+ isym = bfd_sym_from_r_symndx (&htab->sym_cache,
+ abfd, r_symndx);
+ if (isym == NULL)
+ return FALSE;
+
+ sr = bfd_section_from_elf_index (abfd, isym->st_shndx);
+ if (sr == NULL)
+ sr = sec;
+
+ vpp = &elf_section_data (sr)->local_dynrel;
+ hdh_head = (struct elf32_hppa_dyn_reloc_entry **) vpp;
+ }
+
+ hdh_p = *hdh_head;
+ if (hdh_p == NULL || hdh_p->sec != sec)
+ {
+ hdh_p = bfd_alloc (htab->etab.dynobj, sizeof *hdh_p);
+ if (hdh_p == NULL)
+ return FALSE;
+ hdh_p->hdh_next = *hdh_head;
+ *hdh_head = hdh_p;
+ hdh_p->sec = sec;
+ hdh_p->count = 0;
+#if RELATIVE_DYNRELOCS
+ hdh_p->relative_count = 0;
+#endif
+ }
+
+ hdh_p->count += 1;
+#if RELATIVE_DYNRELOCS
+ if (!IS_ABSOLUTE_RELOC (rtype))
+ hdh_p->relative_count += 1;
+#endif
+ }
+ }
+ }
+
+ return TRUE;
+}
+
+/* Return the section that should be marked against garbage collection
+ for a given relocation. */
+
+static asection *
+elf32_hppa_gc_mark_hook (asection *sec,
+ struct bfd_link_info *info,
+ Elf_Internal_Rela *rela,
+ struct elf_link_hash_entry *hh,
+ Elf_Internal_Sym *sym)
+{
+ if (hh != NULL)
+ switch ((unsigned int) ELF32_R_TYPE (rela->r_info))
+ {
+ case R_PARISC_GNU_VTINHERIT:
+ case R_PARISC_GNU_VTENTRY:
+ return NULL;
+ }
+
+ return _bfd_elf_gc_mark_hook (sec, info, rela, hh, sym);
+}
+
+/* Update the got and plt entry reference counts for the section being
+ removed. */
+
+static bfd_boolean
+elf32_hppa_gc_sweep_hook (bfd *abfd,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ asection *sec,
+ const Elf_Internal_Rela *relocs)
+{
+ Elf_Internal_Shdr *symtab_hdr;
+ struct elf_link_hash_entry **eh_syms;
+ bfd_signed_vma *local_got_refcounts;
+ bfd_signed_vma *local_plt_refcounts;
+ const Elf_Internal_Rela *rela, *relend;
+ struct elf32_hppa_link_hash_table *htab;
+
+ if (info->relocatable)
+ return TRUE;
+
+ htab = hppa_link_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ elf_section_data (sec)->local_dynrel = NULL;
+
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+ eh_syms = elf_sym_hashes (abfd);
+ local_got_refcounts = elf_local_got_refcounts (abfd);
+ local_plt_refcounts = local_got_refcounts;
+ if (local_plt_refcounts != NULL)
+ local_plt_refcounts += symtab_hdr->sh_info;
+
+ relend = relocs + sec->reloc_count;
+ for (rela = relocs; rela < relend; rela++)
+ {
+ unsigned long r_symndx;
+ unsigned int r_type;
+ struct elf_link_hash_entry *eh = NULL;
+
+ r_symndx = ELF32_R_SYM (rela->r_info);
+ if (r_symndx >= symtab_hdr->sh_info)
+ {
+ struct elf32_hppa_link_hash_entry *hh;
+ struct elf32_hppa_dyn_reloc_entry **hdh_pp;
+ struct elf32_hppa_dyn_reloc_entry *hdh_p;
+
+ eh = eh_syms[r_symndx - symtab_hdr->sh_info];
+ while (eh->root.type == bfd_link_hash_indirect
+ || eh->root.type == bfd_link_hash_warning)
+ eh = (struct elf_link_hash_entry *) eh->root.u.i.link;
+ hh = hppa_elf_hash_entry (eh);
+
+ for (hdh_pp = &hh->dyn_relocs; (hdh_p = *hdh_pp) != NULL; hdh_pp = &hdh_p->hdh_next)
+ if (hdh_p->sec == sec)
+ {
+ /* Everything must go for SEC. */
+ *hdh_pp = hdh_p->hdh_next;
+ break;
+ }
+ }
+
+ r_type = ELF32_R_TYPE (rela->r_info);
+ r_type = elf32_hppa_optimized_tls_reloc (info, r_type, eh != NULL);
+
+ switch (r_type)
+ {
+ case R_PARISC_DLTIND14F:
+ case R_PARISC_DLTIND14R:
+ case R_PARISC_DLTIND21L:
+ case R_PARISC_TLS_GD21L:
+ case R_PARISC_TLS_GD14R:
+ case R_PARISC_TLS_IE21L:
+ case R_PARISC_TLS_IE14R:
+ if (eh != NULL)
+ {
+ if (eh->got.refcount > 0)
+ eh->got.refcount -= 1;
+ }
+ else if (local_got_refcounts != NULL)
+ {
+ if (local_got_refcounts[r_symndx] > 0)
+ local_got_refcounts[r_symndx] -= 1;
+ }
+ break;
+
+ case R_PARISC_TLS_LDM21L:
+ case R_PARISC_TLS_LDM14R:
+ htab->tls_ldm_got.refcount -= 1;
+ break;
+
+ case R_PARISC_PCREL12F:
+ case R_PARISC_PCREL17C:
+ case R_PARISC_PCREL17F:
+ case R_PARISC_PCREL22F:
+ if (eh != NULL)
+ {
+ if (eh->plt.refcount > 0)
+ eh->plt.refcount -= 1;
+ }
+ break;
+
+ case R_PARISC_PLABEL14R:
+ case R_PARISC_PLABEL21L:
+ case R_PARISC_PLABEL32:
+ if (eh != NULL)
+ {
+ if (eh->plt.refcount > 0)
+ eh->plt.refcount -= 1;
+ }
+ else if (local_plt_refcounts != NULL)
+ {
+ if (local_plt_refcounts[r_symndx] > 0)
+ local_plt_refcounts[r_symndx] -= 1;
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ return TRUE;
+}
+
+/* Support for core dump NOTE sections. */
+
+static bfd_boolean
+elf32_hppa_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
+{
+ int offset;
+ size_t size;
+
+ switch (note->descsz)
+ {
+ default:
+ return FALSE;
+
+ case 396: /* Linux/hppa */
+ /* pr_cursig */
+ elf_tdata (abfd)->core->signal = bfd_get_16 (abfd, note->descdata + 12);
+
+ /* pr_pid */
+ elf_tdata (abfd)->core->lwpid = bfd_get_32 (abfd, note->descdata + 24);
+
+ /* pr_reg */
+ offset = 72;
+ size = 320;
+
+ break;
+ }
+
+ /* Make a ".reg/999" section. */
+ return _bfd_elfcore_make_pseudosection (abfd, ".reg",
+ size, note->descpos + offset);
+}
+
+static bfd_boolean
+elf32_hppa_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
+{
+ switch (note->descsz)
+ {
+ default:
+ return FALSE;
+
+ case 124: /* Linux/hppa elf_prpsinfo. */
+ elf_tdata (abfd)->core->program
+ = _bfd_elfcore_strndup (abfd, note->descdata + 28, 16);
+ elf_tdata (abfd)->core->command
+ = _bfd_elfcore_strndup (abfd, note->descdata + 44, 80);
+ }
+
+ /* 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;
+}
+
+/* Our own version of hide_symbol, so that we can keep plt entries for
+ plabels. */
+
+static void
+elf32_hppa_hide_symbol (struct bfd_link_info *info,
+ struct elf_link_hash_entry *eh,
+ bfd_boolean force_local)
+{
+ if (force_local)
+ {
+ eh->forced_local = 1;
+ if (eh->dynindx != -1)
+ {
+ eh->dynindx = -1;
+ _bfd_elf_strtab_delref (elf_hash_table (info)->dynstr,
+ eh->dynstr_index);
+ }
+
+ /* PR 16082: Remove version information from hidden symbol. */
+ eh->verinfo.verdef = NULL;
+ eh->verinfo.vertree = NULL;
+ }
+
+ /* STT_GNU_IFUNC symbol must go through PLT. */
+ if (! hppa_elf_hash_entry (eh)->plabel
+ && eh->type != STT_GNU_IFUNC)
+ {
+ eh->needs_plt = 0;
+ eh->plt = elf_hash_table (info)->init_plt_offset;
+ }
+}
+
+/* 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 bfd_boolean
+elf32_hppa_adjust_dynamic_symbol (struct bfd_link_info *info,
+ struct elf_link_hash_entry *eh)
+{
+ struct elf32_hppa_link_hash_table *htab;
+ asection *sec;
+
+ /* If this is a function, put it in the procedure linkage table. We
+ will fill in the contents of the procedure linkage table later. */
+ if (eh->type == STT_FUNC
+ || eh->needs_plt)
+ {
+ /* If the symbol is used by a plabel, we must allocate a PLT slot.
+ The refcounts are not reliable when it has been hidden since
+ hide_symbol can be called before the plabel flag is set. */
+ if (hppa_elf_hash_entry (eh)->plabel
+ && eh->plt.refcount <= 0)
+ eh->plt.refcount = 1;
+
+ if (eh->plt.refcount <= 0
+ || (eh->def_regular
+ && eh->root.type != bfd_link_hash_defweak
+ && ! hppa_elf_hash_entry (eh)->plabel
+ && (!info->shared || info->symbolic)))
+ {
+ /* The .plt entry is not needed when:
+ a) Garbage collection has removed all references to the
+ symbol, or
+ b) We know for certain the symbol is defined in this
+ object, and it's not a weak definition, nor is the symbol
+ used by a plabel relocation. Either this object is the
+ application or we are doing a shared symbolic link. */
+
+ eh->plt.offset = (bfd_vma) -1;
+ eh->needs_plt = 0;
+ }
+
+ return TRUE;
+ }
+ else
+ eh->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 (eh->u.weakdef != NULL)
+ {
+ if (eh->u.weakdef->root.type != bfd_link_hash_defined
+ && eh->u.weakdef->root.type != bfd_link_hash_defweak)
+ abort ();
+ eh->root.u.def.section = eh->u.weakdef->root.u.def.section;
+ eh->root.u.def.value = eh->u.weakdef->root.u.def.value;
+ if (ELIMINATE_COPY_RELOCS)
+ eh->non_got_ref = eh->u.weakdef->non_got_ref;
+ 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;
+
+ /* If there are no references to this symbol that do not use the
+ GOT, we don't need to generate a copy reloc. */
+ if (!eh->non_got_ref)
+ return TRUE;
+
+ if (ELIMINATE_COPY_RELOCS)
+ {
+ struct elf32_hppa_link_hash_entry *hh;
+ struct elf32_hppa_dyn_reloc_entry *hdh_p;
+
+ hh = hppa_elf_hash_entry (eh);
+ for (hdh_p = hh->dyn_relocs; hdh_p != NULL; hdh_p = hdh_p->hdh_next)
+ {
+ sec = hdh_p->sec->output_section;
+ if (sec != NULL && (sec->flags & SEC_READONLY) != 0)
+ break;
+ }
+
+ /* If we didn't find any dynamic relocs in read-only sections, then
+ we'll be keeping the dynamic relocs and avoiding the copy reloc. */
+ if (hdh_p == NULL)
+ {
+ eh->non_got_ref = 0;
+ 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. */
+
+ htab = hppa_link_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ /* We must generate a COPY reloc to tell the dynamic linker to
+ copy the initial value out of the dynamic object and into the
+ runtime process image. */
+ if ((eh->root.u.def.section->flags & SEC_ALLOC) != 0 && eh->size != 0)
+ {
+ htab->srelbss->size += sizeof (Elf32_External_Rela);
+ eh->needs_copy = 1;
+ }
+
+ sec = htab->sdynbss;
+
+ return _bfd_elf_adjust_dynamic_copy (eh, sec);
+}
+
+/* Allocate space in the .plt for entries that won't have relocations.
+ ie. plabel entries. */
+
+static bfd_boolean
+allocate_plt_static (struct elf_link_hash_entry *eh, void *inf)
+{
+ struct bfd_link_info *info;
+ struct elf32_hppa_link_hash_table *htab;
+ struct elf32_hppa_link_hash_entry *hh;
+ asection *sec;
+
+ if (eh->root.type == bfd_link_hash_indirect)
+ return TRUE;
+
+ info = (struct bfd_link_info *) inf;
+ hh = hppa_elf_hash_entry (eh);
+ htab = hppa_link_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ if (htab->etab.dynamic_sections_created
+ && eh->plt.refcount > 0)
+ {
+ /* Make sure this symbol is output as a dynamic symbol.
+ Undefined weak syms won't yet be marked as dynamic. */
+ if (eh->dynindx == -1
+ && !eh->forced_local
+ && eh->type != STT_PARISC_MILLI)
+ {
+ if (! bfd_elf_link_record_dynamic_symbol (info, eh))
+ return FALSE;
+ }
+
+ if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, info->shared, eh))
+ {
+ /* Allocate these later. From this point on, h->plabel
+ means that the plt entry is only used by a plabel.
+ We'll be using a normal plt entry for this symbol, so
+ clear the plabel indicator. */
+
+ hh->plabel = 0;
+ }
+ else if (hh->plabel)
+ {
+ /* Make an entry in the .plt section for plabel references
+ that won't have a .plt entry for other reasons. */
+ sec = htab->splt;
+ eh->plt.offset = sec->size;
+ sec->size += PLT_ENTRY_SIZE;
+ }
+ else
+ {
+ /* No .plt entry needed. */
+ eh->plt.offset = (bfd_vma) -1;
+ eh->needs_plt = 0;
+ }
+ }
+ else
+ {
+ eh->plt.offset = (bfd_vma) -1;
+ eh->needs_plt = 0;
+ }
+
+ return TRUE;
+}
+
+/* Allocate space in .plt, .got and associated reloc sections for
+ global syms. */
+
+static bfd_boolean
+allocate_dynrelocs (struct elf_link_hash_entry *eh, void *inf)
+{
+ struct bfd_link_info *info;
+ struct elf32_hppa_link_hash_table *htab;
+ asection *sec;
+ struct elf32_hppa_link_hash_entry *hh;
+ struct elf32_hppa_dyn_reloc_entry *hdh_p;
+
+ if (eh->root.type == bfd_link_hash_indirect)
+ return TRUE;
+
+ info = inf;
+ htab = hppa_link_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ hh = hppa_elf_hash_entry (eh);
+
+ if (htab->etab.dynamic_sections_created
+ && eh->plt.offset != (bfd_vma) -1
+ && !hh->plabel
+ && eh->plt.refcount > 0)
+ {
+ /* Make an entry in the .plt section. */
+ sec = htab->splt;
+ eh->plt.offset = sec->size;
+ sec->size += PLT_ENTRY_SIZE;
+
+ /* We also need to make an entry in the .rela.plt section. */
+ htab->srelplt->size += sizeof (Elf32_External_Rela);
+ htab->need_plt_stub = 1;
+ }
+
+ if (eh->got.refcount > 0)
+ {
+ /* Make sure this symbol is output as a dynamic symbol.
+ Undefined weak syms won't yet be marked as dynamic. */
+ if (eh->dynindx == -1
+ && !eh->forced_local
+ && eh->type != STT_PARISC_MILLI)
+ {
+ if (! bfd_elf_link_record_dynamic_symbol (info, eh))
+ return FALSE;
+ }
+
+ sec = htab->sgot;
+ eh->got.offset = sec->size;
+ sec->size += GOT_ENTRY_SIZE;
+ /* R_PARISC_TLS_GD* needs two GOT entries */
+ if ((hh->tls_type & (GOT_TLS_GD | GOT_TLS_IE)) == (GOT_TLS_GD | GOT_TLS_IE))
+ sec->size += GOT_ENTRY_SIZE * 2;
+ else if ((hh->tls_type & GOT_TLS_GD) == GOT_TLS_GD)
+ sec->size += GOT_ENTRY_SIZE;
+ if (htab->etab.dynamic_sections_created
+ && (info->shared
+ || (eh->dynindx != -1
+ && !eh->forced_local)))
+ {
+ htab->srelgot->size += sizeof (Elf32_External_Rela);
+ if ((hh->tls_type & (GOT_TLS_GD | GOT_TLS_IE)) == (GOT_TLS_GD | GOT_TLS_IE))
+ htab->srelgot->size += 2 * sizeof (Elf32_External_Rela);
+ else if ((hh->tls_type & GOT_TLS_GD) == GOT_TLS_GD)
+ htab->srelgot->size += sizeof (Elf32_External_Rela);
+ }
+ }
+ else
+ eh->got.offset = (bfd_vma) -1;
+
+ if (hh->dyn_relocs == NULL)
+ return TRUE;
+
+ /* If this is a -Bsymbolic shared link, then we need to discard all
+ space allocated for dynamic pc-relative relocs against symbols
+ defined in a regular object. For the normal shared case, discard
+ space for relocs that have become local due to symbol visibility
+ changes. */
+ if (info->shared)
+ {
+#if RELATIVE_DYNRELOCS
+ if (SYMBOL_CALLS_LOCAL (info, eh))
+ {
+ struct elf32_hppa_dyn_reloc_entry **hdh_pp;
+
+ for (hdh_pp = &hh->dyn_relocs; (hdh_p = *hdh_pp) != NULL; )
+ {
+ hdh_p->count -= hdh_p->relative_count;
+ hdh_p->relative_count = 0;
+ if (hdh_p->count == 0)
+ *hdh_pp = hdh_p->hdh_next;
+ else
+ hdh_pp = &hdh_p->hdh_next;
+ }
+ }
+#endif
+
+ /* Also discard relocs on undefined weak syms with non-default
+ visibility. */
+ if (hh->dyn_relocs != NULL
+ && eh->root.type == bfd_link_hash_undefweak)
+ {
+ if (ELF_ST_VISIBILITY (eh->other) != STV_DEFAULT)
+ hh->dyn_relocs = NULL;
+
+ /* Make sure undefined weak symbols are output as a dynamic
+ symbol in PIEs. */
+ else if (eh->dynindx == -1
+ && !eh->forced_local)
+ {
+ if (! bfd_elf_link_record_dynamic_symbol (info, eh))
+ return FALSE;
+ }
+ }
+ }
+ else
+ {
+ /* For the non-shared case, discard space for relocs against
+ symbols which turn out to need copy relocs or are not
+ dynamic. */
+
+ if (!eh->non_got_ref
+ && ((ELIMINATE_COPY_RELOCS
+ && eh->def_dynamic
+ && !eh->def_regular)
+ || (htab->etab.dynamic_sections_created
+ && (eh->root.type == bfd_link_hash_undefweak
+ || eh->root.type == bfd_link_hash_undefined))))
+ {
+ /* Make sure this symbol is output as a dynamic symbol.
+ Undefined weak syms won't yet be marked as dynamic. */
+ if (eh->dynindx == -1
+ && !eh->forced_local
+ && eh->type != STT_PARISC_MILLI)
+ {
+ if (! bfd_elf_link_record_dynamic_symbol (info, eh))
+ return FALSE;
+ }
+
+ /* If that succeeded, we know we'll be keeping all the
+ relocs. */
+ if (eh->dynindx != -1)
+ goto keep;
+ }
+
+ hh->dyn_relocs = NULL;
+ return TRUE;
+
+ keep: ;
+ }
+
+ /* Finally, allocate space. */
+ for (hdh_p = hh->dyn_relocs; hdh_p != NULL; hdh_p = hdh_p->hdh_next)
+ {
+ asection *sreloc = elf_section_data (hdh_p->sec)->sreloc;
+ sreloc->size += hdh_p->count * sizeof (Elf32_External_Rela);
+ }
+
+ return TRUE;
+}
+
+/* This function is called via elf_link_hash_traverse to force
+ millicode symbols local so they do not end up as globals in the
+ dynamic symbol table. We ought to be able to do this in
+ adjust_dynamic_symbol, but our adjust_dynamic_symbol is not called
+ for all dynamic symbols. Arguably, this is a bug in
+ elf_adjust_dynamic_symbol. */
+
+static bfd_boolean
+clobber_millicode_symbols (struct elf_link_hash_entry *eh,
+ struct bfd_link_info *info)
+{
+ if (eh->type == STT_PARISC_MILLI
+ && !eh->forced_local)
+ {
+ elf32_hppa_hide_symbol (info, eh, TRUE);
+ }
+ return TRUE;
+}
+
+/* Find any dynamic relocs that apply to read-only sections. */
+
+static bfd_boolean
+readonly_dynrelocs (struct elf_link_hash_entry *eh, void *inf)
+{
+ struct elf32_hppa_link_hash_entry *hh;
+ struct elf32_hppa_dyn_reloc_entry *hdh_p;
+
+ hh = hppa_elf_hash_entry (eh);
+ for (hdh_p = hh->dyn_relocs; hdh_p != NULL; hdh_p = hdh_p->hdh_next)
+ {
+ asection *sec = hdh_p->sec->output_section;
+
+ if (sec != NULL && (sec->flags & SEC_READONLY) != 0)
+ {
+ struct bfd_link_info *info = inf;
+
+ info->flags |= DF_TEXTREL;
+
+ /* Not an error, just cut short the traversal. */
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+/* Set the sizes of the dynamic sections. */
+
+static bfd_boolean
+elf32_hppa_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
+ struct bfd_link_info *info)
+{
+ struct elf32_hppa_link_hash_table *htab;
+ bfd *dynobj;
+ bfd *ibfd;
+ asection *sec;
+ bfd_boolean relocs;
+
+ htab = hppa_link_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ dynobj = htab->etab.dynobj;
+ if (dynobj == NULL)
+ abort ();
+
+ if (htab->etab.dynamic_sections_created)
+ {
+ /* Set the contents of the .interp section to the interpreter. */
+ if (info->executable)
+ {
+ sec = bfd_get_linker_section (dynobj, ".interp");
+ if (sec == NULL)
+ abort ();
+ sec->size = sizeof ELF_DYNAMIC_INTERPRETER;
+ sec->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
+ }
+
+ /* Force millicode symbols local. */
+ elf_link_hash_traverse (&htab->etab,
+ clobber_millicode_symbols,
+ info);
+ }
+
+ /* Set up .got and .plt offsets for local syms, and space for local
+ dynamic relocs. */
+ for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next)
+ {
+ bfd_signed_vma *local_got;
+ bfd_signed_vma *end_local_got;
+ bfd_signed_vma *local_plt;
+ bfd_signed_vma *end_local_plt;
+ bfd_size_type locsymcount;
+ Elf_Internal_Shdr *symtab_hdr;
+ asection *srel;
+ char *local_tls_type;
+
+ if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour)
+ continue;
+
+ for (sec = ibfd->sections; sec != NULL; sec = sec->next)
+ {
+ struct elf32_hppa_dyn_reloc_entry *hdh_p;
+
+ for (hdh_p = ((struct elf32_hppa_dyn_reloc_entry *)
+ elf_section_data (sec)->local_dynrel);
+ hdh_p != NULL;
+ hdh_p = hdh_p->hdh_next)
+ {
+ if (!bfd_is_abs_section (hdh_p->sec)
+ && bfd_is_abs_section (hdh_p->sec->output_section))
+ {
+ /* Input section has been discarded, either because
+ it is a copy of a linkonce section or due to
+ linker script /DISCARD/, so we'll be discarding
+ the relocs too. */
+ }
+ else if (hdh_p->count != 0)
+ {
+ srel = elf_section_data (hdh_p->sec)->sreloc;
+ srel->size += hdh_p->count * sizeof (Elf32_External_Rela);
+ if ((hdh_p->sec->output_section->flags & SEC_READONLY) != 0)
+ info->flags |= DF_TEXTREL;
+ }
+ }
+ }
+
+ local_got = elf_local_got_refcounts (ibfd);
+ if (!local_got)
+ continue;
+
+ symtab_hdr = &elf_tdata (ibfd)->symtab_hdr;
+ locsymcount = symtab_hdr->sh_info;
+ end_local_got = local_got + locsymcount;
+ local_tls_type = hppa_elf_local_got_tls_type (ibfd);
+ sec = htab->sgot;
+ srel = htab->srelgot;
+ for (; local_got < end_local_got; ++local_got)
+ {
+ if (*local_got > 0)
+ {
+ *local_got = sec->size;
+ sec->size += GOT_ENTRY_SIZE;
+ if ((*local_tls_type & (GOT_TLS_GD | GOT_TLS_IE)) == (GOT_TLS_GD | GOT_TLS_IE))
+ sec->size += 2 * GOT_ENTRY_SIZE;
+ else if ((*local_tls_type & GOT_TLS_GD) == GOT_TLS_GD)
+ sec->size += GOT_ENTRY_SIZE;
+ if (info->shared)
+ {
+ srel->size += sizeof (Elf32_External_Rela);
+ if ((*local_tls_type & (GOT_TLS_GD | GOT_TLS_IE)) == (GOT_TLS_GD | GOT_TLS_IE))
+ srel->size += 2 * sizeof (Elf32_External_Rela);
+ else if ((*local_tls_type & GOT_TLS_GD) == GOT_TLS_GD)
+ srel->size += sizeof (Elf32_External_Rela);
+ }
+ }
+ else
+ *local_got = (bfd_vma) -1;
+
+ ++local_tls_type;
+ }
+
+ local_plt = end_local_got;
+ end_local_plt = local_plt + locsymcount;
+ if (! htab->etab.dynamic_sections_created)
+ {
+ /* Won't be used, but be safe. */
+ for (; local_plt < end_local_plt; ++local_plt)
+ *local_plt = (bfd_vma) -1;
+ }
+ else
+ {
+ sec = htab->splt;
+ srel = htab->srelplt;
+ for (; local_plt < end_local_plt; ++local_plt)
+ {
+ if (*local_plt > 0)
+ {
+ *local_plt = sec->size;
+ sec->size += PLT_ENTRY_SIZE;
+ if (info->shared)
+ srel->size += sizeof (Elf32_External_Rela);
+ }
+ else
+ *local_plt = (bfd_vma) -1;
+ }
+ }
+ }
+
+ if (htab->tls_ldm_got.refcount > 0)
+ {
+ /* Allocate 2 got entries and 1 dynamic reloc for
+ R_PARISC_TLS_DTPMOD32 relocs. */
+ htab->tls_ldm_got.offset = htab->sgot->size;
+ htab->sgot->size += (GOT_ENTRY_SIZE * 2);
+ htab->srelgot->size += sizeof (Elf32_External_Rela);
+ }
+ else
+ htab->tls_ldm_got.offset = -1;
+
+ /* Do all the .plt entries without relocs first. The dynamic linker
+ uses the last .plt reloc to find the end of the .plt (and hence
+ the start of the .got) for lazy linking. */
+ elf_link_hash_traverse (&htab->etab, allocate_plt_static, info);
+
+ /* Allocate global sym .plt and .got entries, and space for global
+ sym dynamic relocs. */
+ elf_link_hash_traverse (&htab->etab, allocate_dynrelocs, info);
+
+ /* The check_relocs and adjust_dynamic_symbol entry points have
+ determined the sizes of the various dynamic sections. Allocate
+ memory for them. */
+ relocs = FALSE;
+ for (sec = dynobj->sections; sec != NULL; sec = sec->next)
+ {
+ if ((sec->flags & SEC_LINKER_CREATED) == 0)
+ continue;
+
+ if (sec == htab->splt)
+ {
+ if (htab->need_plt_stub)
+ {
+ /* Make space for the plt stub at the end of the .plt
+ section. We want this stub right at the end, up
+ against the .got section. */
+ int gotalign = bfd_section_alignment (dynobj, htab->sgot);
+ int pltalign = bfd_section_alignment (dynobj, sec);
+ bfd_size_type mask;
+
+ if (gotalign > pltalign)
+ (void) bfd_set_section_alignment (dynobj, sec, gotalign);
+ mask = ((bfd_size_type) 1 << gotalign) - 1;
+ sec->size = (sec->size + sizeof (plt_stub) + mask) & ~mask;
+ }
+ }
+ else if (sec == htab->sgot
+ || sec == htab->sdynbss)
+ ;
+ else if (CONST_STRNEQ (bfd_get_section_name (dynobj, sec), ".rela"))
+ {
+ if (sec->size != 0)
+ {
+ /* Remember whether there are any reloc sections other
+ than .rela.plt. */
+ if (sec != htab->srelplt)
+ relocs = TRUE;
+
+ /* We use the reloc_count field as a counter if we need
+ to copy relocs into the output file. */
+ sec->reloc_count = 0;
+ }
+ }
+ else
+ {
+ /* It's not one of our sections, so don't allocate space. */
+ continue;
+ }
+
+ if (sec->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. */
+ sec->flags |= SEC_EXCLUDE;
+ continue;
+ }
+
+ if ((sec->flags & SEC_HAS_CONTENTS) == 0)
+ continue;
+
+ /* Allocate memory for the section contents. Zero it, because
+ we may not fill in all the reloc sections. */
+ sec->contents = bfd_zalloc (dynobj, sec->size);
+ if (sec->contents == NULL)
+ return FALSE;
+ }
+
+ if (htab->etab.dynamic_sections_created)
+ {
+ /* Like IA-64 and HPPA64, always create a DT_PLTGOT. It
+ actually has nothing to do with the PLT, it is how we
+ communicate the LTP value of a load module to the dynamic
+ linker. */
+#define add_dynamic_entry(TAG, VAL) \
+ _bfd_elf_add_dynamic_entry (info, TAG, VAL)
+
+ if (!add_dynamic_entry (DT_PLTGOT, 0))
+ return FALSE;
+
+ /* Add some entries to the .dynamic section. We fill in the
+ values later, in elf32_hppa_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->executable)
+ {
+ if (!add_dynamic_entry (DT_DEBUG, 0))
+ return FALSE;
+ }
+
+ if (htab->srelplt->size != 0)
+ {
+ if (!add_dynamic_entry (DT_PLTRELSZ, 0)
+ || !add_dynamic_entry (DT_PLTREL, DT_RELA)
+ || !add_dynamic_entry (DT_JMPREL, 0))
+ return FALSE;
+ }
+
+ if (relocs)
+ {
+ if (!add_dynamic_entry (DT_RELA, 0)
+ || !add_dynamic_entry (DT_RELASZ, 0)
+ || !add_dynamic_entry (DT_RELAENT, sizeof (Elf32_External_Rela)))
+ return FALSE;
+
+ /* If any dynamic relocs apply to a read-only section,
+ then we need a DT_TEXTREL entry. */
+ if ((info->flags & DF_TEXTREL) == 0)
+ elf_link_hash_traverse (&htab->etab, readonly_dynrelocs, info);
+
+ if ((info->flags & DF_TEXTREL) != 0)
+ {
+ if (!add_dynamic_entry (DT_TEXTREL, 0))
+ return FALSE;
+ }
+ }
+ }
+#undef add_dynamic_entry
+
+ return TRUE;
+}
+
+/* External entry points for sizing and building linker stubs. */
+
+/* Set up various things so that we can make a list of input sections
+ for each output section included in the link. Returns -1 on error,
+ 0 when no stubs will be needed, and 1 on success. */
+
+int
+elf32_hppa_setup_section_lists (bfd *output_bfd, struct bfd_link_info *info)
+{
+ bfd *input_bfd;
+ unsigned int bfd_count;
+ int top_id, top_index;
+ asection *section;
+ asection **input_list, **list;
+ bfd_size_type amt;
+ struct elf32_hppa_link_hash_table *htab = hppa_link_hash_table (info);
+
+ if (htab == NULL)
+ return -1;
+
+ /* Count the number of input BFDs and find the top input section id. */
+ for (input_bfd = info->input_bfds, bfd_count = 0, top_id = 0;
+ input_bfd != NULL;
+ input_bfd = input_bfd->link.next)
+ {
+ bfd_count += 1;
+ for (section = input_bfd->sections;
+ section != NULL;
+ section = section->next)
+ {
+ if (top_id < section->id)
+ top_id = section->id;
+ }
+ }
+ htab->bfd_count = bfd_count;
+
+ amt = sizeof (struct map_stub) * (top_id + 1);
+ htab->stub_group = bfd_zmalloc (amt);
+ if (htab->stub_group == NULL)
+ return -1;
+
+ /* We can't use output_bfd->section_count here to find the top output
+ section index as some sections may have been removed, and
+ strip_excluded_output_sections doesn't renumber the indices. */
+ for (section = output_bfd->sections, top_index = 0;
+ section != NULL;
+ section = section->next)
+ {
+ if (top_index < section->index)
+ top_index = section->index;
+ }
+
+ htab->top_index = top_index;
+ amt = sizeof (asection *) * (top_index + 1);
+ input_list = bfd_malloc (amt);
+ htab->input_list = input_list;
+ if (input_list == NULL)
+ return -1;
+
+ /* For sections we aren't interested in, mark their entries with a
+ value we can check later. */
+ list = input_list + top_index;
+ do
+ *list = bfd_abs_section_ptr;
+ while (list-- != input_list);
+
+ for (section = output_bfd->sections;
+ section != NULL;
+ section = section->next)
+ {
+ if ((section->flags & SEC_CODE) != 0)
+ input_list[section->index] = NULL;
+ }
+
+ return 1;
+}
+
+/* The linker repeatedly calls this function for each input section,
+ in the order that input sections are linked into output sections.
+ Build lists of input sections to determine groupings between which
+ we may insert linker stubs. */
+
+void
+elf32_hppa_next_input_section (struct bfd_link_info *info, asection *isec)
+{
+ struct elf32_hppa_link_hash_table *htab = hppa_link_hash_table (info);
+
+ if (htab == NULL)
+ return;
+
+ if (isec->output_section->index <= htab->top_index)
+ {
+ asection **list = htab->input_list + isec->output_section->index;
+ if (*list != bfd_abs_section_ptr)
+ {
+ /* Steal the link_sec pointer for our list. */
+#define PREV_SEC(sec) (htab->stub_group[(sec)->id].link_sec)
+ /* This happens to make the list in reverse order,
+ which is what we want. */
+ PREV_SEC (isec) = *list;
+ *list = isec;
+ }
+ }
+}
+
+/* See whether we can group stub sections together. Grouping stub
+ sections may result in fewer stubs. More importantly, we need to
+ put all .init* and .fini* stubs at the beginning of the .init or
+ .fini output sections respectively, because glibc splits the
+ _init and _fini functions into multiple parts. Putting a stub in
+ the middle of a function is not a good idea. */
+
+static void
+group_sections (struct elf32_hppa_link_hash_table *htab,
+ bfd_size_type stub_group_size,
+ bfd_boolean stubs_always_before_branch)
+{
+ asection **list = htab->input_list + htab->top_index;
+ do
+ {
+ asection *tail = *list;
+ if (tail == bfd_abs_section_ptr)
+ continue;
+ while (tail != NULL)
+ {
+ asection *curr;
+ asection *prev;
+ bfd_size_type total;
+ bfd_boolean big_sec;
+
+ curr = tail;
+ total = tail->size;
+ big_sec = total >= stub_group_size;
+
+ while ((prev = PREV_SEC (curr)) != NULL
+ && ((total += curr->output_offset - prev->output_offset)
+ < stub_group_size))
+ curr = prev;
+
+ /* OK, the size from the start of CURR to the end is less
+ than 240000 bytes and thus can be handled by one stub
+ section. (or the tail section is itself larger than
+ 240000 bytes, in which case we may be toast.)
+ We should really be keeping track of the total size of
+ stubs added here, as stubs contribute to the final output
+ section size. That's a little tricky, and this way will
+ only break if stubs added total more than 22144 bytes, or
+ 2768 long branch stubs. It seems unlikely for more than
+ 2768 different functions to be called, especially from
+ code only 240000 bytes long. This limit used to be
+ 250000, but c++ code tends to generate lots of little
+ functions, and sometimes violated the assumption. */
+ do
+ {
+ prev = PREV_SEC (tail);
+ /* Set up this stub group. */
+ htab->stub_group[tail->id].link_sec = curr;
+ }
+ while (tail != curr && (tail = prev) != NULL);
+
+ /* But wait, there's more! Input sections up to 240000
+ bytes before the stub section can be handled by it too.
+ Don't do this if we have a really large section after the
+ stubs, as adding more stubs increases the chance that
+ branches may not reach into the stub section. */
+ if (!stubs_always_before_branch && !big_sec)
+ {
+ total = 0;
+ while (prev != NULL
+ && ((total += tail->output_offset - prev->output_offset)
+ < stub_group_size))
+ {
+ tail = prev;
+ prev = PREV_SEC (tail);
+ htab->stub_group[tail->id].link_sec = curr;
+ }
+ }
+ tail = prev;
+ }
+ }
+ while (list-- != htab->input_list);
+ free (htab->input_list);
+#undef PREV_SEC
+}
+
+/* Read in all local syms for all input bfds, and create hash entries
+ for export stubs if we are building a multi-subspace shared lib.
+ Returns -1 on error, 1 if export stubs created, 0 otherwise. */
+
+static int
+get_local_syms (bfd *output_bfd, bfd *input_bfd, struct bfd_link_info *info)
+{
+ unsigned int bfd_indx;
+ Elf_Internal_Sym *local_syms, **all_local_syms;
+ int stub_changed = 0;
+ struct elf32_hppa_link_hash_table *htab = hppa_link_hash_table (info);
+
+ if (htab == NULL)
+ return -1;
+
+ /* 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. */
+ bfd_size_type amt = sizeof (Elf_Internal_Sym *) * htab->bfd_count;
+ all_local_syms = bfd_zmalloc (amt);
+ htab->all_local_syms = all_local_syms;
+ if (all_local_syms == NULL)
+ return -1;
+
+ /* Walk over all the input BFDs, swapping in local symbols.
+ If we are creating a shared library, create hash entries for the
+ export stubs. */
+ for (bfd_indx = 0;
+ input_bfd != NULL;
+ input_bfd = input_bfd->link.next, bfd_indx++)
+ {
+ Elf_Internal_Shdr *symtab_hdr;
+
+ /* 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. */
+ local_syms = (Elf_Internal_Sym *) symtab_hdr->contents;
+ if (local_syms == NULL)
+ {
+ local_syms = bfd_elf_get_elf_syms (input_bfd, symtab_hdr,
+ symtab_hdr->sh_info, 0,
+ NULL, NULL, NULL);
+ /* Cache them for elf_link_input_bfd. */
+ symtab_hdr->contents = (unsigned char *) local_syms;
+ }
+ if (local_syms == NULL)
+ return -1;
+
+ all_local_syms[bfd_indx] = local_syms;
+
+ if (info->shared && htab->multi_subspace)
+ {
+ struct elf_link_hash_entry **eh_syms;
+ struct elf_link_hash_entry **eh_symend;
+ unsigned int symcount;
+
+ symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
+ - symtab_hdr->sh_info);
+ eh_syms = (struct elf_link_hash_entry **) elf_sym_hashes (input_bfd);
+ eh_symend = (struct elf_link_hash_entry **) (eh_syms + symcount);
+
+ /* Look through the global syms for functions; We need to
+ build export stubs for all globally visible functions. */
+ for (; eh_syms < eh_symend; eh_syms++)
+ {
+ struct elf32_hppa_link_hash_entry *hh;
+
+ hh = hppa_elf_hash_entry (*eh_syms);
+
+ while (hh->eh.root.type == bfd_link_hash_indirect
+ || hh->eh.root.type == bfd_link_hash_warning)
+ hh = hppa_elf_hash_entry (hh->eh.root.u.i.link);
+
+ /* At this point in the link, undefined syms have been
+ resolved, so we need to check that the symbol was
+ defined in this BFD. */
+ if ((hh->eh.root.type == bfd_link_hash_defined
+ || hh->eh.root.type == bfd_link_hash_defweak)
+ && hh->eh.type == STT_FUNC
+ && hh->eh.root.u.def.section->output_section != NULL
+ && (hh->eh.root.u.def.section->output_section->owner
+ == output_bfd)
+ && hh->eh.root.u.def.section->owner == input_bfd
+ && hh->eh.def_regular
+ && !hh->eh.forced_local
+ && ELF_ST_VISIBILITY (hh->eh.other) == STV_DEFAULT)
+ {
+ asection *sec;
+ const char *stub_name;
+ struct elf32_hppa_stub_hash_entry *hsh;
+
+ sec = hh->eh.root.u.def.section;
+ stub_name = hh_name (hh);
+ hsh = hppa_stub_hash_lookup (&htab->bstab,
+ stub_name,
+ FALSE, FALSE);
+ if (hsh == NULL)
+ {
+ hsh = hppa_add_stub (stub_name, sec, htab);
+ if (!hsh)
+ return -1;
+
+ hsh->target_value = hh->eh.root.u.def.value;
+ hsh->target_section = hh->eh.root.u.def.section;
+ hsh->stub_type = hppa_stub_export;
+ hsh->hh = hh;
+ stub_changed = 1;
+ }
+ else
+ {
+ (*_bfd_error_handler) (_("%B: duplicate export stub %s"),
+ input_bfd,
+ stub_name);
+ }
+ }
+ }
+ }
+ }
+
+ return stub_changed;
+}
+
+/* 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. */
+
+bfd_boolean
+elf32_hppa_size_stubs
+ (bfd *output_bfd, bfd *stub_bfd, struct bfd_link_info *info,
+ bfd_boolean multi_subspace, bfd_signed_vma group_size,
+ asection * (*add_stub_section) (const char *, asection *),
+ void (*layout_sections_again) (void))
+{
+ bfd_size_type stub_group_size;
+ bfd_boolean stubs_always_before_branch;
+ bfd_boolean stub_changed;
+ struct elf32_hppa_link_hash_table *htab = hppa_link_hash_table (info);
+
+ if (htab == NULL)
+ return FALSE;
+
+ /* Stash our params away. */
+ htab->stub_bfd = stub_bfd;
+ htab->multi_subspace = multi_subspace;
+ htab->add_stub_section = add_stub_section;
+ htab->layout_sections_again = layout_sections_again;
+ stubs_always_before_branch = group_size < 0;
+ if (group_size < 0)
+ stub_group_size = -group_size;
+ else
+ stub_group_size = group_size;
+ if (stub_group_size == 1)
+ {
+ /* Default values. */
+ if (stubs_always_before_branch)
+ {
+ stub_group_size = 7680000;
+ if (htab->has_17bit_branch || htab->multi_subspace)
+ stub_group_size = 240000;
+ if (htab->has_12bit_branch)
+ stub_group_size = 7500;
+ }
+ else
+ {
+ stub_group_size = 6971392;
+ if (htab->has_17bit_branch || htab->multi_subspace)
+ stub_group_size = 217856;
+ if (htab->has_12bit_branch)
+ stub_group_size = 6808;
+ }
+ }
+
+ group_sections (htab, stub_group_size, stubs_always_before_branch);
+
+ switch (get_local_syms (output_bfd, info->input_bfds, info))
+ {
+ default:
+ if (htab->all_local_syms)
+ goto error_ret_free_local;
+ return FALSE;
+
+ case 0:
+ stub_changed = FALSE;
+ break;
+
+ case 1:
+ stub_changed = TRUE;
+ break;
+ }
+
+ while (1)
+ {
+ bfd *input_bfd;
+ unsigned int bfd_indx;
+ asection *stub_sec;
+
+ for (input_bfd = info->input_bfds, bfd_indx = 0;
+ input_bfd != NULL;
+ input_bfd = input_bfd->link.next, bfd_indx++)
+ {
+ Elf_Internal_Shdr *symtab_hdr;
+ asection *section;
+ Elf_Internal_Sym *local_syms;
+
+ /* 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 = htab->all_local_syms[bfd_indx];
+
+ /* Walk over each section attached to the input bfd. */
+ for (section = input_bfd->sections;
+ section != NULL;
+ section = section->next)
+ {
+ Elf_Internal_Rela *internal_relocs, *irelaend, *irela;
+
+ /* If there aren't any relocs, then there's nothing more
+ to do. */
+ if ((section->flags & SEC_RELOC) == 0
+ || section->reloc_count == 0)
+ continue;
+
+ /* If this section is a link-once section that will be
+ discarded, then don't create any stubs. */
+ if (section->output_section == NULL
+ || section->output_section->owner != output_bfd)
+ continue;
+
+ /* Get the relocs. */
+ internal_relocs
+ = _bfd_elf_link_read_relocs (input_bfd, section, NULL, NULL,
+ info->keep_memory);
+ if (internal_relocs == NULL)
+ goto error_ret_free_local;
+
+ /* Now examine each relocation. */
+ irela = internal_relocs;
+ irelaend = irela + section->reloc_count;
+ for (; irela < irelaend; irela++)
+ {
+ unsigned int r_type, r_indx;
+ enum elf32_hppa_stub_type stub_type;
+ struct elf32_hppa_stub_hash_entry *hsh;
+ asection *sym_sec;
+ bfd_vma sym_value;
+ bfd_vma destination;
+ struct elf32_hppa_link_hash_entry *hh;
+ char *stub_name;
+ const asection *id_sec;
+
+ r_type = ELF32_R_TYPE (irela->r_info);
+ r_indx = ELF32_R_SYM (irela->r_info);
+
+ if (r_type >= (unsigned int) R_PARISC_UNIMPLEMENTED)
+ {
+ bfd_set_error (bfd_error_bad_value);
+ error_ret_free_internal:
+ if (elf_section_data (section)->relocs == NULL)
+ free (internal_relocs);
+ goto error_ret_free_local;
+ }
+
+ /* Only look for stubs on call instructions. */
+ if (r_type != (unsigned int) R_PARISC_PCREL12F
+ && r_type != (unsigned int) R_PARISC_PCREL17F
+ && r_type != (unsigned int) R_PARISC_PCREL22F)
+ continue;
+
+ /* Now determine the call target, its name, value,
+ section. */
+ sym_sec = NULL;
+ sym_value = 0;
+ destination = 0;
+ hh = NULL;
+ if (r_indx < symtab_hdr->sh_info)
+ {
+ /* It's a local symbol. */
+ Elf_Internal_Sym *sym;
+ Elf_Internal_Shdr *hdr;
+ unsigned int shndx;
+
+ sym = local_syms + r_indx;
+ if (ELF_ST_TYPE (sym->st_info) != STT_SECTION)
+ sym_value = sym->st_value;
+ shndx = sym->st_shndx;
+ if (shndx < elf_numsections (input_bfd))
+ {
+ hdr = elf_elfsections (input_bfd)[shndx];
+ sym_sec = hdr->bfd_section;
+ destination = (sym_value + irela->r_addend
+ + sym_sec->output_offset
+ + sym_sec->output_section->vma);
+ }
+ }
+ else
+ {
+ /* It's an external symbol. */
+ int e_indx;
+
+ e_indx = r_indx - symtab_hdr->sh_info;
+ hh = hppa_elf_hash_entry (elf_sym_hashes (input_bfd)[e_indx]);
+
+ while (hh->eh.root.type == bfd_link_hash_indirect
+ || hh->eh.root.type == bfd_link_hash_warning)
+ hh = hppa_elf_hash_entry (hh->eh.root.u.i.link);
+
+ if (hh->eh.root.type == bfd_link_hash_defined
+ || hh->eh.root.type == bfd_link_hash_defweak)
+ {
+ sym_sec = hh->eh.root.u.def.section;
+ sym_value = hh->eh.root.u.def.value;
+ if (sym_sec->output_section != NULL)
+ destination = (sym_value + irela->r_addend
+ + sym_sec->output_offset
+ + sym_sec->output_section->vma);
+ }
+ else if (hh->eh.root.type == bfd_link_hash_undefweak)
+ {
+ if (! info->shared)
+ continue;
+ }
+ else if (hh->eh.root.type == bfd_link_hash_undefined)
+ {
+ if (! (info->unresolved_syms_in_objects == RM_IGNORE
+ && (ELF_ST_VISIBILITY (hh->eh.other)
+ == STV_DEFAULT)
+ && hh->eh.type != STT_PARISC_MILLI))
+ continue;
+ }
+ else
+ {
+ bfd_set_error (bfd_error_bad_value);
+ goto error_ret_free_internal;
+ }
+ }
+
+ /* Determine what (if any) linker stub is needed. */
+ stub_type = hppa_type_of_stub (section, irela, hh,
+ destination, info);
+ if (stub_type == hppa_stub_none)
+ continue;
+
+ /* Support for grouping stub sections. */
+ id_sec = htab->stub_group[section->id].link_sec;
+
+ /* Get the name of this stub. */
+ stub_name = hppa_stub_name (id_sec, sym_sec, hh, irela);
+ if (!stub_name)
+ goto error_ret_free_internal;
+
+ hsh = hppa_stub_hash_lookup (&htab->bstab,
+ stub_name,
+ FALSE, FALSE);
+ if (hsh != NULL)
+ {
+ /* The proper stub has already been created. */
+ free (stub_name);
+ continue;
+ }
+
+ hsh = hppa_add_stub (stub_name, section, htab);
+ if (hsh == NULL)
+ {
+ free (stub_name);
+ goto error_ret_free_internal;
+ }
+
+ hsh->target_value = sym_value;
+ hsh->target_section = sym_sec;
+ hsh->stub_type = stub_type;
+ if (info->shared)
+ {
+ if (stub_type == hppa_stub_import)
+ hsh->stub_type = hppa_stub_import_shared;
+ else if (stub_type == hppa_stub_long_branch)
+ hsh->stub_type = hppa_stub_long_branch_shared;
+ }
+ hsh->hh = hh;
+ stub_changed = TRUE;
+ }
+
+ /* We're done with the internal relocs, free them. */
+ if (elf_section_data (section)->relocs == NULL)
+ free (internal_relocs);
+ }
+ }
+
+ if (!stub_changed)
+ break;
+
+ /* OK, we've added some stubs. Find out the new size of the
+ stub sections. */
+ for (stub_sec = htab->stub_bfd->sections;
+ stub_sec != NULL;
+ stub_sec = stub_sec->next)
+ stub_sec->size = 0;
+
+ bfd_hash_traverse (&htab->bstab, hppa_size_one_stub, htab);
+
+ /* Ask the linker to do its stuff. */
+ (*htab->layout_sections_again) ();
+ stub_changed = FALSE;
+ }
+
+ free (htab->all_local_syms);
+ return TRUE;
+
+ error_ret_free_local:
+ free (htab->all_local_syms);
+ return FALSE;
+}
+
+/* For a final link, this function is called after we have sized the
+ stubs to provide a value for __gp. */
+
+bfd_boolean
+elf32_hppa_set_gp (bfd *abfd, struct bfd_link_info *info)
+{
+ struct bfd_link_hash_entry *h;
+ asection *sec = NULL;
+ bfd_vma gp_val = 0;
+ struct elf32_hppa_link_hash_table *htab;
+
+ htab = hppa_link_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ h = bfd_link_hash_lookup (&htab->etab.root, "$global$", FALSE, FALSE, FALSE);
+
+ if (h != NULL
+ && (h->type == bfd_link_hash_defined
+ || h->type == bfd_link_hash_defweak))
+ {
+ gp_val = h->u.def.value;
+ sec = h->u.def.section;
+ }
+ else
+ {
+ asection *splt = bfd_get_section_by_name (abfd, ".plt");
+ asection *sgot = bfd_get_section_by_name (abfd, ".got");
+
+ /* Choose to point our LTP at, in this order, one of .plt, .got,
+ or .data, if these sections exist. In the case of choosing
+ .plt try to make the LTP ideal for addressing anywhere in the
+ .plt or .got with a 14 bit signed offset. Typically, the end
+ of the .plt is the start of the .got, so choose .plt + 0x2000
+ if either the .plt or .got is larger than 0x2000. If both
+ the .plt and .got are smaller than 0x2000, choose the end of
+ the .plt section. */
+ sec = strcmp (bfd_get_target (abfd), "elf32-hppa-netbsd") == 0
+ ? NULL : splt;
+ if (sec != NULL)
+ {
+ gp_val = sec->size;
+ if (gp_val > 0x2000 || (sgot && sgot->size > 0x2000))
+ {
+ gp_val = 0x2000;
+ }
+ }
+ else
+ {
+ sec = sgot;
+ if (sec != NULL)
+ {
+ if (strcmp (bfd_get_target (abfd), "elf32-hppa-netbsd") != 0)
+ {
+ /* We know we don't have a .plt. If .got is large,
+ offset our LTP. */
+ if (sec->size > 0x2000)
+ gp_val = 0x2000;
+ }
+ }
+ else
+ {
+ /* No .plt or .got. Who cares what the LTP is? */
+ sec = bfd_get_section_by_name (abfd, ".data");
+ }
+ }
+
+ if (h != NULL)
+ {
+ h->type = bfd_link_hash_defined;
+ h->u.def.value = gp_val;
+ if (sec != NULL)
+ h->u.def.section = sec;
+ else
+ h->u.def.section = bfd_abs_section_ptr;
+ }
+ }
+
+ if (sec != NULL && sec->output_section != NULL)
+ gp_val += sec->output_section->vma + sec->output_offset;
+
+ elf_gp (abfd) = gp_val;
+ return TRUE;
+}
+
+/* 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. We also set up the .plt entries for statically linked PIC
+ functions here. This function is called via hppaelf_finish in the
+ linker. */
+
+bfd_boolean
+elf32_hppa_build_stubs (struct bfd_link_info *info)
+{
+ asection *stub_sec;
+ struct bfd_hash_table *table;
+ struct elf32_hppa_link_hash_table *htab;
+
+ htab = hppa_link_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ for (stub_sec = htab->stub_bfd->sections;
+ stub_sec != NULL;
+ stub_sec = stub_sec->next)
+ {
+ bfd_size_type size;
+
+ /* Allocate memory to hold the linker stubs. */
+ size = stub_sec->size;
+ stub_sec->contents = bfd_zalloc (htab->stub_bfd, size);
+ if (stub_sec->contents == NULL && size != 0)
+ return FALSE;
+ stub_sec->size = 0;
+ }
+
+ /* Build the stubs as directed by the stub hash table. */
+ table = &htab->bstab;
+ bfd_hash_traverse (table, hppa_build_one_stub, info);
+
+ return TRUE;
+}
+
+/* Return the base vma address which should be subtracted from the real
+ address when resolving a dtpoff relocation.
+ This is PT_TLS segment p_vaddr. */
+
+static bfd_vma
+dtpoff_base (struct bfd_link_info *info)
+{
+ /* If tls_sec is NULL, we should have signalled an error already. */
+ if (elf_hash_table (info)->tls_sec == NULL)
+ return 0;
+ return elf_hash_table (info)->tls_sec->vma;
+}
+
+/* Return the relocation value for R_PARISC_TLS_TPOFF*.. */
+
+static bfd_vma
+tpoff (struct bfd_link_info *info, bfd_vma address)
+{
+ struct elf_link_hash_table *htab = elf_hash_table (info);
+
+ /* If tls_sec is NULL, we should have signalled an error already. */
+ if (htab->tls_sec == NULL)
+ return 0;
+ /* hppa TLS ABI is variant I and static TLS block start just after
+ tcbhead structure which has 2 pointer fields. */
+ return (address - htab->tls_sec->vma
+ + align_power ((bfd_vma) 8, htab->tls_sec->alignment_power));
+}
+
+/* Perform a final link. */
+
+static bfd_boolean
+elf32_hppa_final_link (bfd *abfd, struct bfd_link_info *info)
+{
+ /* Invoke the regular ELF linker to do all the work. */
+ if (!bfd_elf_final_link (abfd, info))
+ return FALSE;
+
+ /* If we're producing a final executable, sort the contents of the
+ unwind section. */
+ if (info->relocatable)
+ return TRUE;
+
+ return elf_hppa_sort_unwind (abfd);
+}
+
+/* Record the lowest address for the data and text segments. */
+
+static void
+hppa_record_segment_addr (bfd *abfd, asection *section, void *data)
+{
+ struct elf32_hppa_link_hash_table *htab;
+
+ htab = (struct elf32_hppa_link_hash_table*) data;
+ if (htab == NULL)
+ return;
+
+ if ((section->flags & (SEC_ALLOC | SEC_LOAD)) == (SEC_ALLOC | SEC_LOAD))
+ {
+ bfd_vma value;
+ Elf_Internal_Phdr *p;
+
+ p = _bfd_elf_find_segment_containing_section (abfd, section->output_section);
+ BFD_ASSERT (p != NULL);
+ value = p->p_vaddr;
+
+ if ((section->flags & SEC_READONLY) != 0)
+ {
+ if (value < htab->text_segment_base)
+ htab->text_segment_base = value;
+ }
+ else
+ {
+ if (value < htab->data_segment_base)
+ htab->data_segment_base = value;
+ }
+ }
+}
+
+/* Perform a relocation as part of a final link. */
+
+static bfd_reloc_status_type
+final_link_relocate (asection *input_section,
+ bfd_byte *contents,
+ const Elf_Internal_Rela *rela,
+ bfd_vma value,
+ struct elf32_hppa_link_hash_table *htab,
+ asection *sym_sec,
+ struct elf32_hppa_link_hash_entry *hh,
+ struct bfd_link_info *info)
+{
+ int insn;
+ unsigned int r_type = ELF32_R_TYPE (rela->r_info);
+ unsigned int orig_r_type = r_type;
+ reloc_howto_type *howto = elf_hppa_howto_table + r_type;
+ int r_format = howto->bitsize;
+ enum hppa_reloc_field_selector_type_alt r_field;
+ bfd *input_bfd = input_section->owner;
+ bfd_vma offset = rela->r_offset;
+ bfd_vma max_branch_offset = 0;
+ bfd_byte *hit_data = contents + offset;
+ bfd_signed_vma addend = rela->r_addend;
+ bfd_vma location;
+ struct elf32_hppa_stub_hash_entry *hsh = NULL;
+ int val;
+
+ if (r_type == R_PARISC_NONE)
+ return bfd_reloc_ok;
+
+ insn = bfd_get_32 (input_bfd, hit_data);
+
+ /* Find out where we are and where we're going. */
+ location = (offset +
+ input_section->output_offset +
+ input_section->output_section->vma);
+
+ /* If we are not building a shared library, convert DLTIND relocs to
+ DPREL relocs. */
+ if (!info->shared)
+ {
+ switch (r_type)
+ {
+ case R_PARISC_DLTIND21L:
+ case R_PARISC_TLS_GD21L:
+ case R_PARISC_TLS_LDM21L:
+ case R_PARISC_TLS_IE21L:
+ r_type = R_PARISC_DPREL21L;
+ break;
+
+ case R_PARISC_DLTIND14R:
+ case R_PARISC_TLS_GD14R:
+ case R_PARISC_TLS_LDM14R:
+ case R_PARISC_TLS_IE14R:
+ r_type = R_PARISC_DPREL14R;
+ break;
+
+ case R_PARISC_DLTIND14F:
+ r_type = R_PARISC_DPREL14F;
+ break;
+ }
+ }
+
+ switch (r_type)
+ {
+ case R_PARISC_PCREL12F:
+ case R_PARISC_PCREL17F:
+ case R_PARISC_PCREL22F:
+ /* If this call should go via the plt, find the import stub in
+ the stub hash. */
+ if (sym_sec == NULL
+ || sym_sec->output_section == NULL
+ || (hh != NULL
+ && hh->eh.plt.offset != (bfd_vma) -1
+ && hh->eh.dynindx != -1
+ && !hh->plabel
+ && (info->shared
+ || !hh->eh.def_regular
+ || hh->eh.root.type == bfd_link_hash_defweak)))
+ {
+ hsh = hppa_get_stub_entry (input_section, sym_sec,
+ hh, rela, htab);
+ if (hsh != NULL)
+ {
+ value = (hsh->stub_offset
+ + hsh->stub_sec->output_offset
+ + hsh->stub_sec->output_section->vma);
+ addend = 0;
+ }
+ else if (sym_sec == NULL && hh != NULL
+ && hh->eh.root.type == bfd_link_hash_undefweak)
+ {
+ /* It's OK if undefined weak. Calls to undefined weak
+ symbols behave as if the "called" function
+ immediately returns. We can thus call to a weak
+ function without first checking whether the function
+ is defined. */
+ value = location;
+ addend = 8;
+ }
+ else
+ return bfd_reloc_undefined;
+ }
+ /* Fall thru. */
+
+ case R_PARISC_PCREL21L:
+ case R_PARISC_PCREL17C:
+ case R_PARISC_PCREL17R:
+ case R_PARISC_PCREL14R:
+ case R_PARISC_PCREL14F:
+ case R_PARISC_PCREL32:
+ /* Make it a pc relative offset. */
+ value -= location;
+ addend -= 8;
+ break;
+
+ case R_PARISC_DPREL21L:
+ case R_PARISC_DPREL14R:
+ case R_PARISC_DPREL14F:
+ /* Convert instructions that use the linkage table pointer (r19) to
+ instructions that use the global data pointer (dp). This is the
+ most efficient way of using PIC code in an incomplete executable,
+ but the user must follow the standard runtime conventions for
+ accessing data for this to work. */
+ if (orig_r_type != r_type)
+ {
+ if (r_type == R_PARISC_DPREL21L)
+ {
+ /* GCC sometimes uses a register other than r19 for the
+ operation, so we must convert any addil instruction
+ that uses this relocation. */
+ if ((insn & 0xfc000000) == ((int) OP_ADDIL << 26))
+ insn = ADDIL_DP;
+ else
+ /* We must have a ldil instruction. It's too hard to find
+ and convert the associated add instruction, so issue an
+ error. */
+ (*_bfd_error_handler)
+ (_("%B(%A+0x%lx): %s fixup for insn 0x%x is not supported in a non-shared link"),
+ input_bfd,
+ input_section,
+ (long) offset,
+ howto->name,
+ insn);
+ }
+ else if (r_type == R_PARISC_DPREL14F)
+ {
+ /* This must be a format 1 load/store. Change the base
+ register to dp. */
+ insn = (insn & 0xfc1ffff) | (27 << 21);
+ }
+ }
+
+ /* For all the DP relative relocations, we need to examine the symbol's
+ section. If it has no section or 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. This situation commonly
+ arises for undefined weak symbols and when a variable's "constness"
+ is declared differently from the way the variable is defined. For
+ instance: "extern int foo" with foo defined as "const int foo". */
+ if (sym_sec == NULL || (sym_sec->flags & SEC_CODE) != 0)
+ {
+ if ((insn & ((0x3f << 26) | (0x1f << 21)))
+ == (((int) OP_ADDIL << 26) | (27 << 21)))
+ {
+ insn &= ~ (0x1f << 21);
+ }
+ /* Now try to make things easy for the dynamic linker. */
+
+ break;
+ }
+ /* Fall thru. */
+
+ case R_PARISC_DLTIND21L:
+ case R_PARISC_DLTIND14R:
+ case R_PARISC_DLTIND14F:
+ case R_PARISC_TLS_GD21L:
+ case R_PARISC_TLS_LDM21L:
+ case R_PARISC_TLS_IE21L:
+ case R_PARISC_TLS_GD14R:
+ case R_PARISC_TLS_LDM14R:
+ case R_PARISC_TLS_IE14R:
+ value -= elf_gp (input_section->output_section->owner);
+ break;
+
+ case R_PARISC_SEGREL32:
+ if ((sym_sec->flags & SEC_CODE) != 0)
+ value -= htab->text_segment_base;
+ else
+ value -= htab->data_segment_base;
+ break;
+
+ default:
+ break;
+ }
+
+ switch (r_type)
+ {
+ case R_PARISC_DIR32:
+ case R_PARISC_DIR14F:
+ case R_PARISC_DIR17F:
+ case R_PARISC_PCREL17C:
+ case R_PARISC_PCREL14F:
+ case R_PARISC_PCREL32:
+ case R_PARISC_DPREL14F:
+ case R_PARISC_PLABEL32:
+ case R_PARISC_DLTIND14F:
+ case R_PARISC_SEGBASE:
+ case R_PARISC_SEGREL32:
+ case R_PARISC_TLS_DTPMOD32:
+ case R_PARISC_TLS_DTPOFF32:
+ case R_PARISC_TLS_TPREL32:
+ r_field = e_fsel;
+ break;
+
+ case R_PARISC_DLTIND21L:
+ case R_PARISC_PCREL21L:
+ case R_PARISC_PLABEL21L:
+ r_field = e_lsel;
+ break;
+
+ case R_PARISC_DIR21L:
+ case R_PARISC_DPREL21L:
+ case R_PARISC_TLS_GD21L:
+ case R_PARISC_TLS_LDM21L:
+ case R_PARISC_TLS_LDO21L:
+ case R_PARISC_TLS_IE21L:
+ case R_PARISC_TLS_LE21L:
+ r_field = e_lrsel;
+ break;
+
+ case R_PARISC_PCREL17R:
+ case R_PARISC_PCREL14R:
+ case R_PARISC_PLABEL14R:
+ case R_PARISC_DLTIND14R:
+ r_field = e_rsel;
+ break;
+
+ case R_PARISC_DIR17R:
+ case R_PARISC_DIR14R:
+ case R_PARISC_DPREL14R:
+ case R_PARISC_TLS_GD14R:
+ case R_PARISC_TLS_LDM14R:
+ case R_PARISC_TLS_LDO14R:
+ case R_PARISC_TLS_IE14R:
+ case R_PARISC_TLS_LE14R:
+ r_field = e_rrsel;
+ break;
+
+ case R_PARISC_PCREL12F:
+ case R_PARISC_PCREL17F:
+ case R_PARISC_PCREL22F:
+ r_field = e_fsel;
+
+ if (r_type == (unsigned int) R_PARISC_PCREL17F)
+ {
+ max_branch_offset = (1 << (17-1)) << 2;
+ }
+ else if (r_type == (unsigned int) R_PARISC_PCREL12F)
+ {
+ max_branch_offset = (1 << (12-1)) << 2;
+ }
+ else
+ {
+ max_branch_offset = (1 << (22-1)) << 2;
+ }
+
+ /* sym_sec is NULL on undefined weak syms or when shared on
+ undefined syms. We've already checked for a stub for the
+ shared undefined case. */
+ if (sym_sec == NULL)
+ break;
+
+ /* If the branch is out of reach, then redirect the
+ call to the local stub for this function. */
+ if (value + addend + max_branch_offset >= 2*max_branch_offset)
+ {
+ hsh = hppa_get_stub_entry (input_section, sym_sec,
+ hh, rela, htab);
+ if (hsh == NULL)
+ return bfd_reloc_undefined;
+
+ /* Munge up the value and addend so that we call the stub
+ rather than the procedure directly. */
+ value = (hsh->stub_offset
+ + hsh->stub_sec->output_offset
+ + hsh->stub_sec->output_section->vma
+ - location);
+ addend = -8;
+ }
+ break;
+
+ /* Something we don't know how to handle. */
+ default:
+ return bfd_reloc_notsupported;
+ }
+
+ /* Make sure we can reach the stub. */
+ if (max_branch_offset != 0
+ && value + addend + max_branch_offset >= 2*max_branch_offset)
+ {
+ (*_bfd_error_handler)
+ (_("%B(%A+0x%lx): cannot reach %s, recompile with -ffunction-sections"),
+ input_bfd,
+ input_section,
+ (long) offset,
+ hsh->bh_root.string);
+ bfd_set_error (bfd_error_bad_value);
+ return bfd_reloc_notsupported;
+ }
+
+ val = hppa_field_adjust (value, addend, r_field);
+
+ switch (r_type)
+ {
+ case R_PARISC_PCREL12F:
+ case R_PARISC_PCREL17C:
+ case R_PARISC_PCREL17F:
+ case R_PARISC_PCREL17R:
+ case R_PARISC_PCREL22F:
+ case R_PARISC_DIR17F:
+ case R_PARISC_DIR17R:
+ /* This is a branch. Divide the offset by four.
+ Note that we need to decide whether it's a branch or
+ otherwise by inspecting the reloc. Inspecting insn won't
+ work as insn might be from a .word directive. */
+ val >>= 2;
+ break;
+
+ default:
+ break;
+ }
+
+ insn = hppa_rebuild_insn (insn, val, r_format);
+
+ /* Update the instruction word. */
+ bfd_put_32 (input_bfd, (bfd_vma) insn, hit_data);
+ return bfd_reloc_ok;
+}
+
+/* Relocate an HPPA ELF section. */
+
+static bfd_boolean
+elf32_hppa_relocate_section (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_vma *local_got_offsets;
+ struct elf32_hppa_link_hash_table *htab;
+ Elf_Internal_Shdr *symtab_hdr;
+ Elf_Internal_Rela *rela;
+ Elf_Internal_Rela *relend;
+
+ symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
+
+ htab = hppa_link_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ local_got_offsets = elf_local_got_offsets (input_bfd);
+
+ rela = relocs;
+ relend = relocs + input_section->reloc_count;
+ for (; rela < relend; rela++)
+ {
+ unsigned int r_type;
+ reloc_howto_type *howto;
+ unsigned int r_symndx;
+ struct elf32_hppa_link_hash_entry *hh;
+ Elf_Internal_Sym *sym;
+ asection *sym_sec;
+ bfd_vma relocation;
+ bfd_reloc_status_type rstatus;
+ const char *sym_name;
+ bfd_boolean plabel;
+ bfd_boolean warned_undef;
+
+ r_type = ELF32_R_TYPE (rela->r_info);
+ if (r_type >= (unsigned int) R_PARISC_UNIMPLEMENTED)
+ {
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+ if (r_type == (unsigned int) R_PARISC_GNU_VTENTRY
+ || r_type == (unsigned int) R_PARISC_GNU_VTINHERIT)
+ continue;
+
+ r_symndx = ELF32_R_SYM (rela->r_info);
+ hh = NULL;
+ sym = NULL;
+ sym_sec = NULL;
+ warned_undef = FALSE;
+ if (r_symndx < symtab_hdr->sh_info)
+ {
+ /* This is a local symbol, h defaults to NULL. */
+ sym = local_syms + r_symndx;
+ sym_sec = local_sections[r_symndx];
+ relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sym_sec, rela);
+ }
+ else
+ {
+ struct elf_link_hash_entry *eh;
+ bfd_boolean unresolved_reloc, ignored;
+ struct elf_link_hash_entry **sym_hashes = elf_sym_hashes (input_bfd);
+
+ RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rela,
+ r_symndx, symtab_hdr, sym_hashes,
+ eh, sym_sec, relocation,
+ unresolved_reloc, warned_undef,
+ ignored);
+
+ if (!info->relocatable
+ && relocation == 0
+ && eh->root.type != bfd_link_hash_defined
+ && eh->root.type != bfd_link_hash_defweak
+ && eh->root.type != bfd_link_hash_undefweak)
+ {
+ if (info->unresolved_syms_in_objects == RM_IGNORE
+ && ELF_ST_VISIBILITY (eh->other) == STV_DEFAULT
+ && eh->type == STT_PARISC_MILLI)
+ {
+ if (! info->callbacks->undefined_symbol
+ (info, eh_name (eh), input_bfd,
+ input_section, rela->r_offset, FALSE))
+ return FALSE;
+ warned_undef = TRUE;
+ }
+ }
+ hh = hppa_elf_hash_entry (eh);
+ }
+
+ if (sym_sec != NULL && discarded_section (sym_sec))
+ RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+ rela, 1, relend,
+ elf_hppa_howto_table + r_type, 0,
+ contents);
+
+ if (info->relocatable)
+ continue;
+
+ /* Do any required modifications to the relocation value, and
+ determine what types of dynamic info we need to output, if
+ any. */
+ plabel = 0;
+ switch (r_type)
+ {
+ case R_PARISC_DLTIND14F:
+ case R_PARISC_DLTIND14R:
+ case R_PARISC_DLTIND21L:
+ {
+ bfd_vma off;
+ bfd_boolean do_got = 0;
+
+ /* Relocation is to the entry for this symbol in the
+ global offset table. */
+ if (hh != NULL)
+ {
+ bfd_boolean dyn;
+
+ off = hh->eh.got.offset;
+ dyn = htab->etab.dynamic_sections_created;
+ if (! WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared,
+ &hh->eh))
+ {
+ /* If we aren't going to call finish_dynamic_symbol,
+ then we need to handle initialisation of the .got
+ entry and create needed relocs here. Since the
+ offset must always be a multiple of 4, we use the
+ least significant bit to record whether we have
+ initialised it already. */
+ if ((off & 1) != 0)
+ off &= ~1;
+ else
+ {
+ hh->eh.got.offset |= 1;
+ do_got = 1;
+ }
+ }
+ }
+ else
+ {
+ /* Local symbol case. */
+ if (local_got_offsets == NULL)
+ abort ();
+
+ 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
+ {
+ local_got_offsets[r_symndx] |= 1;
+ do_got = 1;
+ }
+ }
+
+ if (do_got)
+ {
+ if (info->shared)
+ {
+ /* Output a dynamic relocation for this GOT entry.
+ In this case it is relative to the base of the
+ object because the symbol index is zero. */
+ Elf_Internal_Rela outrel;
+ bfd_byte *loc;
+ asection *sec = htab->srelgot;
+
+ outrel.r_offset = (off
+ + htab->sgot->output_offset
+ + htab->sgot->output_section->vma);
+ outrel.r_info = ELF32_R_INFO (0, R_PARISC_DIR32);
+ outrel.r_addend = relocation;
+ loc = sec->contents;
+ loc += sec->reloc_count++ * sizeof (Elf32_External_Rela);
+ bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
+ }
+ else
+ bfd_put_32 (output_bfd, relocation,
+ htab->sgot->contents + off);
+ }
+
+ if (off >= (bfd_vma) -2)
+ abort ();
+
+ /* Add the base of the GOT to the relocation value. */
+ relocation = (off
+ + htab->sgot->output_offset
+ + htab->sgot->output_section->vma);
+ }
+ break;
+
+ case R_PARISC_SEGREL32:
+ /* If this is the first SEGREL relocation, then initialize
+ the segment base values. */
+ if (htab->text_segment_base == (bfd_vma) -1)
+ bfd_map_over_sections (output_bfd, hppa_record_segment_addr, htab);
+ break;
+
+ case R_PARISC_PLABEL14R:
+ case R_PARISC_PLABEL21L:
+ case R_PARISC_PLABEL32:
+ if (htab->etab.dynamic_sections_created)
+ {
+ bfd_vma off;
+ bfd_boolean do_plt = 0;
+ /* If we have a global symbol with a PLT slot, then
+ redirect this relocation to it. */
+ if (hh != NULL)
+ {
+ off = hh->eh.plt.offset;
+ if (! WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, info->shared,
+ &hh->eh))
+ {
+ /* In a non-shared link, adjust_dynamic_symbols
+ isn't called for symbols forced local. We
+ need to write out the plt entry here. */
+ if ((off & 1) != 0)
+ off &= ~1;
+ else
+ {
+ hh->eh.plt.offset |= 1;
+ do_plt = 1;
+ }
+ }
+ }
+ else
+ {
+ bfd_vma *local_plt_offsets;
+
+ if (local_got_offsets == NULL)
+ abort ();
+
+ local_plt_offsets = local_got_offsets + symtab_hdr->sh_info;
+ off = local_plt_offsets[r_symndx];
+
+ /* As for the local .got entry case, we use the last
+ bit to record whether we've already initialised
+ this local .plt entry. */
+ if ((off & 1) != 0)
+ off &= ~1;
+ else
+ {
+ local_plt_offsets[r_symndx] |= 1;
+ do_plt = 1;
+ }
+ }
+
+ if (do_plt)
+ {
+ if (info->shared)
+ {
+ /* Output a dynamic IPLT relocation for this
+ PLT entry. */
+ Elf_Internal_Rela outrel;
+ bfd_byte *loc;
+ asection *s = htab->srelplt;
+
+ outrel.r_offset = (off
+ + htab->splt->output_offset
+ + htab->splt->output_section->vma);
+ outrel.r_info = ELF32_R_INFO (0, R_PARISC_IPLT);
+ outrel.r_addend = relocation;
+ loc = s->contents;
+ loc += s->reloc_count++ * sizeof (Elf32_External_Rela);
+ bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
+ }
+ else
+ {
+ bfd_put_32 (output_bfd,
+ relocation,
+ htab->splt->contents + off);
+ bfd_put_32 (output_bfd,
+ elf_gp (htab->splt->output_section->owner),
+ htab->splt->contents + off + 4);
+ }
+ }
+
+ if (off >= (bfd_vma) -2)
+ abort ();
+
+ /* PLABELs contain function pointers. Relocation is to
+ the entry for the function in the .plt. The magic +2
+ offset signals to $$dyncall that the function pointer
+ is in the .plt and thus has a gp pointer too.
+ Exception: Undefined PLABELs should have a value of
+ zero. */
+ if (hh == NULL
+ || (hh->eh.root.type != bfd_link_hash_undefweak
+ && hh->eh.root.type != bfd_link_hash_undefined))
+ {
+ relocation = (off
+ + htab->splt->output_offset
+ + htab->splt->output_section->vma
+ + 2);
+ }
+ plabel = 1;
+ }
+ /* Fall through and possibly emit a dynamic relocation. */
+
+ case R_PARISC_DIR17F:
+ case R_PARISC_DIR17R:
+ case R_PARISC_DIR14F:
+ case R_PARISC_DIR14R:
+ case R_PARISC_DIR21L:
+ case R_PARISC_DPREL14F:
+ case R_PARISC_DPREL14R:
+ case R_PARISC_DPREL21L:
+ case R_PARISC_DIR32:
+ if ((input_section->flags & SEC_ALLOC) == 0)
+ break;
+
+ /* The reloc types handled here and this conditional
+ expression must match the code in ..check_relocs and
+ allocate_dynrelocs. ie. We need exactly the same condition
+ as in ..check_relocs, with some extra conditions (dynindx
+ test in this case) to cater for relocs removed by
+ allocate_dynrelocs. If you squint, the non-shared test
+ here does indeed match the one in ..check_relocs, the
+ difference being that here we test DEF_DYNAMIC as well as
+ !DEF_REGULAR. All common syms end up with !DEF_REGULAR,
+ which is why we can't use just that test here.
+ Conversely, DEF_DYNAMIC can't be used in check_relocs as
+ there all files have not been loaded. */
+ if ((info->shared
+ && (hh == NULL
+ || ELF_ST_VISIBILITY (hh->eh.other) == STV_DEFAULT
+ || hh->eh.root.type != bfd_link_hash_undefweak)
+ && (IS_ABSOLUTE_RELOC (r_type)
+ || !SYMBOL_CALLS_LOCAL (info, &hh->eh)))
+ || (!info->shared
+ && hh != NULL
+ && hh->eh.dynindx != -1
+ && !hh->eh.non_got_ref
+ && ((ELIMINATE_COPY_RELOCS
+ && hh->eh.def_dynamic
+ && !hh->eh.def_regular)
+ || hh->eh.root.type == bfd_link_hash_undefweak
+ || hh->eh.root.type == bfd_link_hash_undefined)))
+ {
+ Elf_Internal_Rela outrel;
+ bfd_boolean skip;
+ asection *sreloc;
+ bfd_byte *loc;
+
+ /* When generating a shared object, these relocations
+ are copied into the output file to be resolved at run
+ time. */
+
+ outrel.r_addend = rela->r_addend;
+ outrel.r_offset =
+ _bfd_elf_section_offset (output_bfd, info, input_section,
+ rela->r_offset);
+ skip = (outrel.r_offset == (bfd_vma) -1
+ || outrel.r_offset == (bfd_vma) -2);
+ outrel.r_offset += (input_section->output_offset
+ + input_section->output_section->vma);
+
+ if (skip)
+ {
+ memset (&outrel, 0, sizeof (outrel));
+ }
+ else if (hh != NULL
+ && hh->eh.dynindx != -1
+ && (plabel
+ || !IS_ABSOLUTE_RELOC (r_type)
+ || !info->shared
+ || !info->symbolic
+ || !hh->eh.def_regular))
+ {
+ outrel.r_info = ELF32_R_INFO (hh->eh.dynindx, r_type);
+ }
+ else /* It's a local symbol, or one marked to become local. */
+ {
+ int indx = 0;
+
+ /* Add the absolute offset of the symbol. */
+ outrel.r_addend += relocation;
+
+ /* Global plabels need to be processed by the
+ dynamic linker so that functions have at most one
+ fptr. For this reason, we need to differentiate
+ between global and local plabels, which we do by
+ providing the function symbol for a global plabel
+ reloc, and no symbol for local plabels. */
+ if (! plabel
+ && sym_sec != NULL
+ && sym_sec->output_section != NULL
+ && ! bfd_is_abs_section (sym_sec))
+ {
+ asection *osec;
+
+ osec = sym_sec->output_section;
+ indx = elf_section_data (osec)->dynindx;
+ if (indx == 0)
+ {
+ osec = htab->etab.text_index_section;
+ indx = elf_section_data (osec)->dynindx;
+ }
+ BFD_ASSERT (indx != 0);
+
+ /* We are turning this relocation into one
+ against a section symbol, so subtract out the
+ output section's address but not the offset
+ of the input section in the output section. */
+ outrel.r_addend -= osec->vma;
+ }
+
+ outrel.r_info = ELF32_R_INFO (indx, r_type);
+ }
+ sreloc = elf_section_data (input_section)->sreloc;
+ if (sreloc == NULL)
+ abort ();
+
+ loc = sreloc->contents;
+ loc += sreloc->reloc_count++ * sizeof (Elf32_External_Rela);
+ bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
+ }
+ break;
+
+ case R_PARISC_TLS_LDM21L:
+ case R_PARISC_TLS_LDM14R:
+ {
+ bfd_vma off;
+
+ off = htab->tls_ldm_got.offset;
+ if (off & 1)
+ off &= ~1;
+ else
+ {
+ Elf_Internal_Rela outrel;
+ bfd_byte *loc;
+
+ outrel.r_offset = (off
+ + htab->sgot->output_section->vma
+ + htab->sgot->output_offset);
+ outrel.r_addend = 0;
+ outrel.r_info = ELF32_R_INFO (0, R_PARISC_TLS_DTPMOD32);
+ loc = htab->srelgot->contents;
+ loc += htab->srelgot->reloc_count++ * sizeof (Elf32_External_Rela);
+
+ bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
+ htab->tls_ldm_got.offset |= 1;
+ }
+
+ /* Add the base of the GOT to the relocation value. */
+ relocation = (off
+ + htab->sgot->output_offset
+ + htab->sgot->output_section->vma);
+
+ break;
+ }
+
+ case R_PARISC_TLS_LDO21L:
+ case R_PARISC_TLS_LDO14R:
+ relocation -= dtpoff_base (info);
+ break;
+
+ case R_PARISC_TLS_GD21L:
+ case R_PARISC_TLS_GD14R:
+ case R_PARISC_TLS_IE21L:
+ case R_PARISC_TLS_IE14R:
+ {
+ bfd_vma off;
+ int indx;
+ char tls_type;
+
+ indx = 0;
+ if (hh != NULL)
+ {
+ bfd_boolean dyn;
+ dyn = htab->etab.dynamic_sections_created;
+
+ if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, &hh->eh)
+ && (!info->shared
+ || !SYMBOL_REFERENCES_LOCAL (info, &hh->eh)))
+ {
+ indx = hh->eh.dynindx;
+ }
+ off = hh->eh.got.offset;
+ tls_type = hh->tls_type;
+ }
+ else
+ {
+ off = local_got_offsets[r_symndx];
+ tls_type = hppa_elf_local_got_tls_type (input_bfd)[r_symndx];
+ }
+
+ if (tls_type == GOT_UNKNOWN)
+ abort ();
+
+ if ((off & 1) != 0)
+ off &= ~1;
+ else
+ {
+ bfd_boolean need_relocs = FALSE;
+ Elf_Internal_Rela outrel;
+ bfd_byte *loc = NULL;
+ int cur_off = off;
+
+ /* The GOT entries have not been initialized yet. Do it
+ now, and emit any relocations. If both an IE GOT and a
+ GD GOT are necessary, we emit the GD first. */
+
+ if ((info->shared || indx != 0)
+ && (hh == NULL
+ || ELF_ST_VISIBILITY (hh->eh.other) == STV_DEFAULT
+ || hh->eh.root.type != bfd_link_hash_undefweak))
+ {
+ need_relocs = TRUE;
+ loc = htab->srelgot->contents;
+ /* FIXME (CAO): Should this be reloc_count++ ? */
+ loc += htab->srelgot->reloc_count * sizeof (Elf32_External_Rela);
+ }
+
+ if (tls_type & GOT_TLS_GD)
+ {
+ if (need_relocs)
+ {
+ outrel.r_offset = (cur_off
+ + htab->sgot->output_section->vma
+ + htab->sgot->output_offset);
+ outrel.r_info = ELF32_R_INFO (indx,R_PARISC_TLS_DTPMOD32);
+ outrel.r_addend = 0;
+ bfd_put_32 (output_bfd, 0, htab->sgot->contents + cur_off);
+ bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
+ htab->srelgot->reloc_count++;
+ loc += sizeof (Elf32_External_Rela);
+
+ if (indx == 0)
+ bfd_put_32 (output_bfd, relocation - dtpoff_base (info),
+ htab->sgot->contents + cur_off + 4);
+ else
+ {
+ bfd_put_32 (output_bfd, 0,
+ htab->sgot->contents + cur_off + 4);
+ outrel.r_info = ELF32_R_INFO (indx, R_PARISC_TLS_DTPOFF32);
+ outrel.r_offset += 4;
+ bfd_elf32_swap_reloca_out (output_bfd, &outrel,loc);
+ htab->srelgot->reloc_count++;
+ loc += sizeof (Elf32_External_Rela);
+ }
+ }
+ else
+ {
+ /* If we are not emitting relocations for a
+ general dynamic reference, then we must be in a
+ static link or an executable link with the
+ symbol binding locally. Mark it as belonging
+ to module 1, the executable. */
+ bfd_put_32 (output_bfd, 1,
+ htab->sgot->contents + cur_off);
+ bfd_put_32 (output_bfd, relocation - dtpoff_base (info),
+ htab->sgot->contents + cur_off + 4);
+ }
+
+
+ cur_off += 8;
+ }
+
+ if (tls_type & GOT_TLS_IE)
+ {
+ if (need_relocs)
+ {
+ outrel.r_offset = (cur_off
+ + htab->sgot->output_section->vma
+ + htab->sgot->output_offset);
+ outrel.r_info = ELF32_R_INFO (indx, R_PARISC_TLS_TPREL32);
+
+ if (indx == 0)
+ outrel.r_addend = relocation - dtpoff_base (info);
+ else
+ outrel.r_addend = 0;
+
+ bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
+ htab->srelgot->reloc_count++;
+ loc += sizeof (Elf32_External_Rela);
+ }
+ else
+ bfd_put_32 (output_bfd, tpoff (info, relocation),
+ htab->sgot->contents + cur_off);
+
+ cur_off += 4;
+ }
+
+ if (hh != NULL)
+ hh->eh.got.offset |= 1;
+ else
+ local_got_offsets[r_symndx] |= 1;
+ }
+
+ if ((tls_type & GOT_TLS_GD)
+ && r_type != R_PARISC_TLS_GD21L
+ && r_type != R_PARISC_TLS_GD14R)
+ off += 2 * GOT_ENTRY_SIZE;
+
+ /* Add the base of the GOT to the relocation value. */
+ relocation = (off
+ + htab->sgot->output_offset
+ + htab->sgot->output_section->vma);
+
+ break;
+ }
+
+ case R_PARISC_TLS_LE21L:
+ case R_PARISC_TLS_LE14R:
+ {
+ relocation = tpoff (info, relocation);
+ break;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ rstatus = final_link_relocate (input_section, contents, rela, relocation,
+ htab, sym_sec, hh, info);
+
+ if (rstatus == bfd_reloc_ok)
+ continue;
+
+ if (hh != NULL)
+ sym_name = hh_name (hh);
+ 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);
+ }
+
+ howto = elf_hppa_howto_table + r_type;
+
+ if (rstatus == bfd_reloc_undefined || rstatus == bfd_reloc_notsupported)
+ {
+ if (rstatus == bfd_reloc_notsupported || !warned_undef)
+ {
+ (*_bfd_error_handler)
+ (_("%B(%A+0x%lx): cannot handle %s for %s"),
+ input_bfd,
+ input_section,
+ (long) rela->r_offset,
+ howto->name,
+ sym_name);
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+ }
+ else
+ {
+ if (!((*info->callbacks->reloc_overflow)
+ (info, (hh ? &hh->eh.root : NULL), sym_name, howto->name,
+ (bfd_vma) 0, input_bfd, input_section, rela->r_offset)))
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+/* Finish up dynamic symbol handling. We set the contents of various
+ dynamic sections here. */
+
+static bfd_boolean
+elf32_hppa_finish_dynamic_symbol (bfd *output_bfd,
+ struct bfd_link_info *info,
+ struct elf_link_hash_entry *eh,
+ Elf_Internal_Sym *sym)
+{
+ struct elf32_hppa_link_hash_table *htab;
+ Elf_Internal_Rela rela;
+ bfd_byte *loc;
+
+ htab = hppa_link_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ if (eh->plt.offset != (bfd_vma) -1)
+ {
+ bfd_vma value;
+
+ if (eh->plt.offset & 1)
+ abort ();
+
+ /* This symbol has an entry in the procedure linkage table. Set
+ it up.
+
+ The format of a plt entry is
+ <funcaddr>
+ <__gp>
+ */
+ value = 0;
+ if (eh->root.type == bfd_link_hash_defined
+ || eh->root.type == bfd_link_hash_defweak)
+ {
+ value = eh->root.u.def.value;
+ if (eh->root.u.def.section->output_section != NULL)
+ value += (eh->root.u.def.section->output_offset
+ + eh->root.u.def.section->output_section->vma);
+ }
+
+ /* Create a dynamic IPLT relocation for this entry. */
+ rela.r_offset = (eh->plt.offset
+ + htab->splt->output_offset
+ + htab->splt->output_section->vma);
+ if (eh->dynindx != -1)
+ {
+ rela.r_info = ELF32_R_INFO (eh->dynindx, R_PARISC_IPLT);
+ rela.r_addend = 0;
+ }
+ else
+ {
+ /* This symbol has been marked to become local, and is
+ used by a plabel so must be kept in the .plt. */
+ rela.r_info = ELF32_R_INFO (0, R_PARISC_IPLT);
+ rela.r_addend = value;
+ }
+
+ loc = htab->srelplt->contents;
+ loc += htab->srelplt->reloc_count++ * sizeof (Elf32_External_Rela);
+ bfd_elf32_swap_reloca_out (htab->splt->output_section->owner, &rela, loc);
+
+ if (!eh->def_regular)
+ {
+ /* Mark the symbol as undefined, rather than as defined in
+ the .plt section. Leave the value alone. */
+ sym->st_shndx = SHN_UNDEF;
+ }
+ }
+
+ if (eh->got.offset != (bfd_vma) -1
+ && (hppa_elf_hash_entry (eh)->tls_type & GOT_TLS_GD) == 0
+ && (hppa_elf_hash_entry (eh)->tls_type & GOT_TLS_IE) == 0)
+ {
+ /* This symbol has an entry in the global offset table. Set it
+ up. */
+
+ rela.r_offset = ((eh->got.offset &~ (bfd_vma) 1)
+ + htab->sgot->output_offset
+ + htab->sgot->output_section->vma);
+
+ /* If this is a -Bsymbolic link and the symbol is defined
+ locally or was forced to be local because of a version file,
+ 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 || eh->dynindx == -1)
+ && eh->def_regular)
+ {
+ rela.r_info = ELF32_R_INFO (0, R_PARISC_DIR32);
+ rela.r_addend = (eh->root.u.def.value
+ + eh->root.u.def.section->output_offset
+ + eh->root.u.def.section->output_section->vma);
+ }
+ else
+ {
+ if ((eh->got.offset & 1) != 0)
+ abort ();
+
+ bfd_put_32 (output_bfd, 0, htab->sgot->contents + (eh->got.offset & ~1));
+ rela.r_info = ELF32_R_INFO (eh->dynindx, R_PARISC_DIR32);
+ rela.r_addend = 0;
+ }
+
+ loc = htab->srelgot->contents;
+ loc += htab->srelgot->reloc_count++ * sizeof (Elf32_External_Rela);
+ bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
+ }
+
+ if (eh->needs_copy)
+ {
+ asection *sec;
+
+ /* This symbol needs a copy reloc. Set it up. */
+
+ if (! (eh->dynindx != -1
+ && (eh->root.type == bfd_link_hash_defined
+ || eh->root.type == bfd_link_hash_defweak)))
+ abort ();
+
+ sec = htab->srelbss;
+
+ rela.r_offset = (eh->root.u.def.value
+ + eh->root.u.def.section->output_offset
+ + eh->root.u.def.section->output_section->vma);
+ rela.r_addend = 0;
+ rela.r_info = ELF32_R_INFO (eh->dynindx, R_PARISC_COPY);
+ loc = sec->contents + sec->reloc_count++ * sizeof (Elf32_External_Rela);
+ bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
+ }
+
+ /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute. */
+ if (eh == htab->etab.hdynamic || eh == htab->etab.hgot)
+ {
+ sym->st_shndx = SHN_ABS;
+ }
+
+ return TRUE;
+}
+
+/* Used to decide how to sort relocs in an optimal manner for the
+ dynamic linker, before writing them out. */
+
+static enum elf_reloc_type_class
+elf32_hppa_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ const asection *rel_sec ATTRIBUTE_UNUSED,
+ const Elf_Internal_Rela *rela)
+{
+ /* Handle TLS relocs first; we don't want them to be marked
+ relative by the "if (ELF32_R_SYM (rela->r_info) == STN_UNDEF)"
+ check below. */
+ switch ((int) ELF32_R_TYPE (rela->r_info))
+ {
+ case R_PARISC_TLS_DTPMOD32:
+ case R_PARISC_TLS_DTPOFF32:
+ case R_PARISC_TLS_TPREL32:
+ return reloc_class_normal;
+ }
+
+ if (ELF32_R_SYM (rela->r_info) == STN_UNDEF)
+ return reloc_class_relative;
+
+ switch ((int) ELF32_R_TYPE (rela->r_info))
+ {
+ case R_PARISC_IPLT:
+ return reloc_class_plt;
+ case R_PARISC_COPY:
+ return reloc_class_copy;
+ default:
+ return reloc_class_normal;
+ }
+}
+
+/* Finish up the dynamic sections. */
+
+static bfd_boolean
+elf32_hppa_finish_dynamic_sections (bfd *output_bfd,
+ struct bfd_link_info *info)
+{
+ bfd *dynobj;
+ struct elf32_hppa_link_hash_table *htab;
+ asection *sdyn;
+ asection * sgot;
+
+ htab = hppa_link_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ dynobj = htab->etab.dynobj;
+
+ sgot = htab->sgot;
+ /* A broken linker script might have discarded the dynamic sections.
+ Catch this here so that we do not seg-fault later on. */
+ if (sgot != NULL && bfd_is_abs_section (sgot->output_section))
+ return FALSE;
+
+ sdyn = bfd_get_linker_section (dynobj, ".dynamic");
+
+ if (htab->etab.dynamic_sections_created)
+ {
+ Elf32_External_Dyn *dyncon, *dynconend;
+
+ if (sdyn == NULL)
+ abort ();
+
+ dyncon = (Elf32_External_Dyn *) sdyn->contents;
+ dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->size);
+ for (; dyncon < dynconend; dyncon++)
+ {
+ Elf_Internal_Dyn dyn;
+ asection *s;
+
+ bfd_elf32_swap_dyn_in (dynobj, dyncon, &dyn);
+
+ switch (dyn.d_tag)
+ {
+ default:
+ continue;
+
+ case DT_PLTGOT:
+ /* Use PLTGOT to set the GOT register. */
+ dyn.d_un.d_ptr = elf_gp (output_bfd);
+ break;
+
+ case DT_JMPREL:
+ s = htab->srelplt;
+ dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
+ break;
+
+ case DT_PLTRELSZ:
+ s = htab->srelplt;
+ dyn.d_un.d_val = s->size;
+ break;
+
+ case DT_RELASZ:
+ /* Don't count procedure linkage table relocs in the
+ overall reloc count. */
+ s = htab->srelplt;
+ if (s == NULL)
+ continue;
+ dyn.d_un.d_val -= s->size;
+ break;
+
+ case DT_RELA:
+ /* We may not be using the standard ELF linker script.
+ If .rela.plt is the first .rela section, we adjust
+ DT_RELA to not include it. */
+ s = htab->srelplt;
+ if (s == NULL)
+ continue;
+ if (dyn.d_un.d_ptr != s->output_section->vma + s->output_offset)
+ continue;
+ dyn.d_un.d_ptr += s->size;
+ break;
+ }
+
+ bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
+ }
+ }
+
+ if (sgot != NULL && sgot->size != 0)
+ {
+ /* Fill in the first entry in the global offset table.
+ We use it to point to our dynamic section, if we have one. */
+ bfd_put_32 (output_bfd,
+ sdyn ? sdyn->output_section->vma + sdyn->output_offset : 0,
+ sgot->contents);
+
+ /* The second entry is reserved for use by the dynamic linker. */
+ memset (sgot->contents + GOT_ENTRY_SIZE, 0, GOT_ENTRY_SIZE);
+
+ /* Set .got entry size. */
+ elf_section_data (sgot->output_section)
+ ->this_hdr.sh_entsize = GOT_ENTRY_SIZE;
+ }
+
+ if (htab->splt != NULL && htab->splt->size != 0)
+ {
+ /* Set plt entry size. */
+ elf_section_data (htab->splt->output_section)
+ ->this_hdr.sh_entsize = PLT_ENTRY_SIZE;
+
+ if (htab->need_plt_stub)
+ {
+ /* Set up the .plt stub. */
+ memcpy (htab->splt->contents
+ + htab->splt->size - sizeof (plt_stub),
+ plt_stub, sizeof (plt_stub));
+
+ if ((htab->splt->output_offset
+ + htab->splt->output_section->vma
+ + htab->splt->size)
+ != (sgot->output_offset
+ + sgot->output_section->vma))
+ {
+ (*_bfd_error_handler)
+ (_(".got section not immediately after .plt section"));
+ return FALSE;
+ }
+ }
+ }
+
+ return TRUE;
+}
+
+/* Called when writing out an object file to decide the type of a
+ symbol. */
+static int
+elf32_hppa_elf_get_symbol_type (Elf_Internal_Sym *elf_sym, int type)
+{
+ if (ELF_ST_TYPE (elf_sym->st_info) == STT_PARISC_MILLI)
+ return STT_PARISC_MILLI;
+ else
+ return type;
+}
+
+/* Misc BFD support code. */
+#define bfd_elf32_bfd_is_local_label_name elf_hppa_is_local_label_name
+#define bfd_elf32_bfd_reloc_type_lookup elf_hppa_reloc_type_lookup
+#define bfd_elf32_bfd_reloc_name_lookup elf_hppa_reloc_name_lookup
+#define elf_info_to_howto elf_hppa_info_to_howto
+#define elf_info_to_howto_rel elf_hppa_info_to_howto_rel
+
+/* Stuff for the BFD linker. */
+#define bfd_elf32_bfd_final_link elf32_hppa_final_link
+#define bfd_elf32_bfd_link_hash_table_create elf32_hppa_link_hash_table_create
+#define elf_backend_adjust_dynamic_symbol elf32_hppa_adjust_dynamic_symbol
+#define elf_backend_copy_indirect_symbol elf32_hppa_copy_indirect_symbol
+#define elf_backend_check_relocs elf32_hppa_check_relocs
+#define elf_backend_create_dynamic_sections elf32_hppa_create_dynamic_sections
+#define elf_backend_fake_sections elf_hppa_fake_sections
+#define elf_backend_relocate_section elf32_hppa_relocate_section
+#define elf_backend_hide_symbol elf32_hppa_hide_symbol
+#define elf_backend_finish_dynamic_symbol elf32_hppa_finish_dynamic_symbol
+#define elf_backend_finish_dynamic_sections elf32_hppa_finish_dynamic_sections
+#define elf_backend_size_dynamic_sections elf32_hppa_size_dynamic_sections
+#define elf_backend_init_index_section _bfd_elf_init_1_index_section
+#define elf_backend_gc_mark_hook elf32_hppa_gc_mark_hook
+#define elf_backend_gc_sweep_hook elf32_hppa_gc_sweep_hook
+#define elf_backend_grok_prstatus elf32_hppa_grok_prstatus
+#define elf_backend_grok_psinfo elf32_hppa_grok_psinfo
+#define elf_backend_object_p elf32_hppa_object_p
+#define elf_backend_final_write_processing elf_hppa_final_write_processing
+#define elf_backend_get_symbol_type elf32_hppa_elf_get_symbol_type
+#define elf_backend_reloc_type_class elf32_hppa_reloc_type_class
+#define elf_backend_action_discarded elf_hppa_action_discarded
+
+#define elf_backend_can_gc_sections 1
+#define elf_backend_can_refcount 1
+#define elf_backend_plt_alignment 2
+#define elf_backend_want_got_plt 0
+#define elf_backend_plt_readonly 0
+#define elf_backend_want_plt_sym 0
+#define elf_backend_got_header_size 8
+#define elf_backend_rela_normal 1
+
+#define TARGET_BIG_SYM hppa_elf32_vec
+#define TARGET_BIG_NAME "elf32-hppa"
+#define ELF_ARCH bfd_arch_hppa
+#define ELF_TARGET_ID HPPA32_ELF_DATA
+#define ELF_MACHINE_CODE EM_PARISC
+#define ELF_MAXPAGESIZE 0x1000
+#define ELF_OSABI ELFOSABI_HPUX
+#define elf32_bed elf32_hppa_hpux_bed
+
+#include "elf32-target.h"
+
+#undef TARGET_BIG_SYM
+#define TARGET_BIG_SYM hppa_elf32_linux_vec
+#undef TARGET_BIG_NAME
+#define TARGET_BIG_NAME "elf32-hppa-linux"
+#undef ELF_OSABI
+#define ELF_OSABI ELFOSABI_GNU
+#undef elf32_bed
+#define elf32_bed elf32_hppa_linux_bed
+
+#include "elf32-target.h"
+
+#undef TARGET_BIG_SYM
+#define TARGET_BIG_SYM hppa_elf32_nbsd_vec
+#undef TARGET_BIG_NAME
+#define TARGET_BIG_NAME "elf32-hppa-netbsd"
+#undef ELF_OSABI
+#define ELF_OSABI ELFOSABI_NETBSD
+#undef elf32_bed
+#define elf32_bed elf32_hppa_netbsd_bed
+
+#include "elf32-target.h"
diff --git a/bfd/elf32-hppa.h b/bfd/elf32-hppa.h
new file mode 100644
index 0000000..1b3c5ef
--- /dev/null
+++ b/bfd/elf32-hppa.h
@@ -0,0 +1,77 @@
+/* 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-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#ifndef _ELF32_HPPA_H
+#define _ELF32_HPPA_H
+
+#include "elf-bfd.h"
+#include "libhppa.h"
+#include "elf/hppa.h"
+
+int elf32_hppa_setup_section_lists
+ (bfd *, struct bfd_link_info *);
+
+void elf32_hppa_next_input_section
+ (struct bfd_link_info *, asection *);
+
+bfd_boolean elf32_hppa_size_stubs
+ (bfd *, bfd *, struct bfd_link_info *, bfd_boolean, bfd_signed_vma,
+ asection * (*) (const char *, asection *), void (*) (void));
+
+bfd_boolean elf32_hppa_set_gp
+ (bfd *, struct bfd_link_info *);
+
+bfd_boolean elf32_hppa_build_stubs
+ (struct bfd_link_info *);
+
+elf_hppa_reloc_type elf32_hppa_reloc_final_type
+ (bfd *, elf_hppa_reloc_type, int, unsigned int);
+
+extern elf_hppa_reloc_type ** _bfd_elf32_hppa_gen_reloc_type
+ (bfd *, elf_hppa_reloc_type, int, unsigned int, int, asymbol *);
+
+/* 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
+
+#endif /* _ELF32_HPPA_H */
diff --git a/bfd/elf32-i370.c b/bfd/elf32-i370.c
new file mode 100644
index 0000000..c9ed6e0
--- /dev/null
+++ b/bfd/elf32-i370.c
@@ -0,0 +1,1408 @@
+/* i370-specific support for 32-bit ELF
+ Copyright (C) 1994-2014 Free Software Foundation, Inc.
+ Written by Ian Lance Taylor, Cygnus Support.
+ Hacked by Linas Vepstas for i370 linas@linas.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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+/* This file is based on a preliminary PowerPC ELF ABI.
+ But its been hacked on for the IBM 360/370 architectures.
+ Basically, the 31bit relocation works, and just about everything
+ else is a wild card. In particular, don't expect shared libs or
+ dynamic loading to work ... its never been tested. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "bfdlink.h"
+#include "libbfd.h"
+#include "elf-bfd.h"
+#include "elf/i370.h"
+
+static reloc_howto_type *i370_elf_howto_table[ (int)R_I370_max ];
+
+static reloc_howto_type i370_elf_howto_raw[] =
+{
+ /* This reloc does nothing. */
+ HOWTO (R_I370_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_I370_NONE", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A standard 31 bit relocation. */
+ HOWTO (R_I370_ADDR31, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 31, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_I370_ADDR31", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x7fffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A standard 32 bit relocation. */
+ HOWTO (R_I370_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_I370_ADDR32", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A standard 16 bit relocation. */
+ HOWTO (R_I370_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_I370_ADDR16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* 31-bit PC relative. */
+ HOWTO (R_I370_REL31, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 31, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_I370_REL31", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x7fffffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* 32-bit PC relative. */
+ HOWTO (R_I370_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_I370_REL32", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* A standard 12 bit relocation. */
+ HOWTO (R_I370_ADDR12, /* type */
+ 0, /* rightshift */
+ 1, /* 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_I370_ADDR12", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xfff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* 12-bit PC relative. */
+ HOWTO (R_I370_REL12, /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 12, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_I370_REL12", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xfff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* A standard 8 bit relocation. */
+ HOWTO (R_I370_ADDR8, /* 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_I370_ADDR8", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* 8-bit PC relative. */
+ HOWTO (R_I370_REL8, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 8, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_I370_REL8", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xff, /* 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_I370_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_I370_COPY", /* 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_I370_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_I370_RELATIVE", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+};
+
+/* Initialize the i370_elf_howto_table, so that linear accesses can be done. */
+
+static void
+i370_elf_howto_init (void)
+{
+ unsigned int i, type;
+
+ for (i = 0; i < sizeof (i370_elf_howto_raw) / sizeof (i370_elf_howto_raw[0]); i++)
+ {
+ type = i370_elf_howto_raw[i].type;
+ BFD_ASSERT (type < sizeof (i370_elf_howto_table) / sizeof (i370_elf_howto_table[0]));
+ i370_elf_howto_table[type] = &i370_elf_howto_raw[i];
+ }
+}
+
+static reloc_howto_type *
+i370_elf_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ bfd_reloc_code_real_type code)
+{
+ enum i370_reloc_type i370_reloc = R_I370_NONE;
+
+ if (!i370_elf_howto_table[ R_I370_ADDR31 ])
+ /* Initialize howto table if needed. */
+ i370_elf_howto_init ();
+
+ switch ((int) code)
+ {
+ default:
+ return NULL;
+
+ case BFD_RELOC_NONE: i370_reloc = R_I370_NONE; break;
+ case BFD_RELOC_32: i370_reloc = R_I370_ADDR31; break;
+ case BFD_RELOC_16: i370_reloc = R_I370_ADDR16; break;
+ case BFD_RELOC_32_PCREL: i370_reloc = R_I370_REL31; break;
+ case BFD_RELOC_CTOR: i370_reloc = R_I370_ADDR31; break;
+ case BFD_RELOC_I370_D12: i370_reloc = R_I370_ADDR12; break;
+ }
+
+ return i370_elf_howto_table[ (int)i370_reloc ];
+};
+
+static reloc_howto_type *
+i370_elf_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ const char *r_name)
+{
+ unsigned int i;
+
+ for (i = 0;
+ i < sizeof (i370_elf_howto_raw) / sizeof (i370_elf_howto_raw[0]);
+ i++)
+ if (i370_elf_howto_raw[i].name != NULL
+ && strcasecmp (i370_elf_howto_raw[i].name, r_name) == 0)
+ return &i370_elf_howto_raw[i];
+
+ return NULL;
+}
+
+/* The name of the dynamic interpreter. This is put in the .interp
+ section. */
+
+#define ELF_DYNAMIC_INTERPRETER "/lib/ld.so"
+
+/* Set the howto pointer for an i370 ELF reloc. */
+
+static void
+i370_elf_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED,
+ arelent *cache_ptr,
+ Elf_Internal_Rela *dst)
+{
+ if (!i370_elf_howto_table[ R_I370_ADDR31 ])
+ /* Initialize howto table. */
+ i370_elf_howto_init ();
+
+ BFD_ASSERT (ELF32_R_TYPE (dst->r_info) < (unsigned int) R_I370_max);
+ cache_ptr->howto = i370_elf_howto_table[ELF32_R_TYPE (dst->r_info)];
+}
+
+/* Hack alert -- the following several routines look generic to me ...
+ why are we bothering with them ? */
+/* Function to set whether a module needs the -mrelocatable bit set. */
+
+static bfd_boolean
+i370_elf_set_private_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;
+}
+
+/* Merge backend specific data from an object file to the output
+ object file when linking. */
+
+static bfd_boolean
+i370_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
+{
+ flagword old_flags;
+ flagword new_flags;
+
+ 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. */
+ {
+ (*_bfd_error_handler)
+ ("%B: uses different e_flags (0x%lx) fields than previous modules (0x%lx)",
+ ibfd, (long) new_flags, (long) old_flags);
+
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/* Handle an i370 specific section when reading an object file. This
+ is called when elfcode.h finds a section with an unknown type. */
+/* XXX hack alert bogus This routine is mostly all junk and almost
+ certainly does the wrong thing. Its here simply because it does
+ just enough to allow glibc-2.1 ld.so to compile & link. */
+
+static bfd_boolean
+i370_elf_section_from_shdr (bfd *abfd,
+ Elf_Internal_Shdr *hdr,
+ const char *name,
+ int shindex)
+{
+ asection *newsect;
+ flagword flags;
+
+ if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex))
+ return FALSE;
+
+ newsect = hdr->bfd_section;
+ flags = bfd_get_section_flags (abfd, newsect);
+ 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. */
+/* XXX hack alert bogus This routine is mostly all junk and almost
+ certainly does the wrong thing. Its here simply because it does
+ just enough to allow glibc-2.1 ld.so to compile & link. */
+
+static bfd_boolean
+i370_elf_fake_sections (bfd *abfd ATTRIBUTE_UNUSED,
+ Elf_Internal_Shdr *shdr,
+ asection *asect)
+{
+ if ((asect->flags & (SEC_GROUP | SEC_EXCLUDE)) == SEC_EXCLUDE)
+ shdr->sh_flags |= SHF_EXCLUDE;
+
+ if ((asect->flags & SEC_SORT_ENTRIES) != 0)
+ shdr->sh_type = SHT_ORDERED;
+
+ 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). */
+/* XXX hack alert bogus This routine is mostly all junk and almost
+ certainly does the wrong thing. Its here simply because it does
+ just enough to allow glibc-2.1 ld.so to compile & link. */
+
+static bfd_boolean
+i370_elf_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
+{
+ 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_anyway_with_flags (abfd, ".dynsbss",
+ SEC_ALLOC | SEC_LINKER_CREATED);
+ if (s == NULL)
+ return FALSE;
+
+ if (! info->shared)
+ {
+ s = bfd_make_section_anyway_with_flags (abfd, ".rela.sbss",
+ flags | SEC_READONLY);
+ if (s == NULL
+ || ! bfd_set_section_alignment (abfd, s, 2))
+ return FALSE;
+ }
+
+ /* XXX beats me, seem to need a rela.text ... */
+ s = bfd_make_section_anyway_with_flags (abfd, ".rela.text",
+ flags | SEC_READONLY);
+ if (s == NULL
+ || ! 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. */
+/* XXX hack alert bogus This routine is mostly all junk and almost
+ certainly does the wrong thing. Its here simply because it does
+ just enough to allow glibc-2.1 ld.so to compile & link. */
+
+static bfd_boolean
+i370_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
+ struct elf_link_hash_entry *h)
+{
+ bfd *dynobj = elf_hash_table (info)->dynobj;
+ asection *s;
+
+#ifdef DEBUG
+ fprintf (stderr, "i370_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->needs_plt
+ || h->u.weakdef != NULL
+ || (h->def_dynamic
+ && h->ref_regular
+ && !h->def_regular)));
+
+ s = bfd_get_linker_section (dynobj, ".rela.text");
+ BFD_ASSERT (s != NULL);
+ s->size += sizeof (Elf32_External_Rela);
+
+ /* 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->u.weakdef != NULL)
+ {
+ BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
+ || h->u.weakdef->root.type == bfd_link_hash_defweak);
+ h->root.u.def.section = h->u.weakdef->root.u.def.section;
+ h->root.u.def.value = h->u.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_linker_section (dynobj, ".dynsbss");
+ else
+ s = bfd_get_linker_section (dynobj, ".dynbss");
+ BFD_ASSERT (s != NULL);
+
+ /* We must generate a R_I370_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 && h->size != 0)
+ {
+ asection *srel;
+
+ if (h->size <= elf_gp_size (dynobj))
+ srel = bfd_get_linker_section (dynobj, ".rela.sbss");
+ else
+ srel = bfd_get_linker_section (dynobj, ".rela.bss");
+ BFD_ASSERT (srel != NULL);
+ srel->size += sizeof (Elf32_External_Rela);
+ h->needs_copy = 1;
+ }
+
+ return _bfd_elf_adjust_dynamic_copy (h, s);
+}
+
+/* Increment the index of a dynamic symbol by a given amount. Called
+ via elf_link_hash_traverse. */
+/* XXX hack alert bogus This routine is mostly all junk and almost
+ certainly does the wrong thing. Its here simply because it does
+ just enough to allow glibc-2.1 ld.so to compile & link. */
+
+static bfd_boolean
+i370_elf_adjust_dynindx (struct elf_link_hash_entry *h, void * cparg)
+{
+ int *cp = (int *) cparg;
+
+#ifdef DEBUG
+ fprintf (stderr,
+ "i370_elf_adjust_dynindx called, h->dynindx = %ld, *cp = %d\n",
+ h->dynindx, *cp);
+#endif
+
+ if (h->dynindx != -1)
+ h->dynindx += *cp;
+
+ return TRUE;
+}
+
+/* Set the sizes of the dynamic sections. */
+/* XXX hack alert bogus This routine is mostly all junk and almost
+ certainly does the wrong thing. Its here simply because it does
+ just enough to allow glibc-2.1 ld.so to compile & link. */
+
+static bfd_boolean
+i370_elf_size_dynamic_sections (bfd *output_bfd,
+ struct bfd_link_info *info)
+{
+ bfd *dynobj;
+ asection *s;
+ bfd_boolean plt;
+ bfd_boolean relocs;
+ bfd_boolean reltext;
+
+#ifdef DEBUG
+ fprintf (stderr, "i370_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->executable)
+ {
+ s = bfd_get_linker_section (dynobj, ".interp");
+ BFD_ASSERT (s != NULL);
+ s->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",
+ NULL };
+ char **p;
+
+ for (p = rela_sections; *p != NULL; p++)
+ {
+ s = bfd_get_linker_section (dynobj, *p);
+ if (s != NULL)
+ s->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;
+
+ 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);
+
+ if (strcmp (name, ".plt") == 0)
+ {
+ /* Remember whether there is a PLT. */
+ plt = s->size != 0;
+ }
+ else if (CONST_STRNEQ (name, ".rela"))
+ {
+ if (s->size != 0)
+ {
+ 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
+ && strcmp (name, ".dynbss") != 0
+ && strcmp (name, ".dynsbss") != 0)
+ {
+ /* It's not one of our sections, so don't allocate space. */
+ continue;
+ }
+
+ if (s->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. */
+ s->flags |= SEC_EXCLUDE;
+ continue;
+ }
+
+ if ((s->flags & SEC_HAS_CONTENTS) == 0)
+ continue;
+
+ /* Allocate memory for the section contents. */
+ s->contents = bfd_zalloc (dynobj, s->size);
+ if (s->contents == NULL)
+ return FALSE;
+ }
+
+ if (elf_hash_table (info)->dynamic_sections_created)
+ {
+ /* Add some entries to the .dynamic section. We fill in the
+ values later, in i370_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. */
+#define add_dynamic_entry(TAG, VAL) \
+ _bfd_elf_add_dynamic_entry (info, TAG, VAL)
+
+ if (!info->shared)
+ {
+ if (!add_dynamic_entry (DT_DEBUG, 0))
+ return FALSE;
+ }
+
+ if (plt)
+ {
+ if (!add_dynamic_entry (DT_PLTGOT, 0)
+ || !add_dynamic_entry (DT_PLTRELSZ, 0)
+ || !add_dynamic_entry (DT_PLTREL, DT_RELA)
+ || !add_dynamic_entry (DT_JMPREL, 0))
+ return FALSE;
+ }
+
+ if (relocs)
+ {
+ if (!add_dynamic_entry (DT_RELA, 0)
+ || !add_dynamic_entry (DT_RELASZ, 0)
+ || !add_dynamic_entry (DT_RELAENT, sizeof (Elf32_External_Rela)))
+ return FALSE;
+ }
+
+ if (reltext)
+ {
+ if (!add_dynamic_entry (DT_TEXTREL, 0))
+ return FALSE;
+ info->flags |= DF_TEXTREL;
+ }
+ }
+#undef add_dynamic_entry
+
+ /* 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 targeted 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),
+ i370_elf_adjust_dynindx, & 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. */
+/* XXX hack alert bogus This routine is mostly all junk and almost
+ certainly does the wrong thing. Its here simply because it does
+ just enough to allow glibc-2.1 ld.so to compile & link. */
+
+static bfd_boolean
+i370_elf_check_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;
+ const Elf_Internal_Rela *rel;
+ const Elf_Internal_Rela *rel_end;
+ asection *sreloc;
+
+ if (info->relocatable)
+ return TRUE;
+
+#ifdef DEBUG
+ _bfd_error_handler ("i370_elf_check_relocs called for section %A in %B",
+ sec, 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];
+ 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;
+
+ /* PR15323, ref flags aren't set for references in the same
+ object. */
+ h->root.non_ir_ref = 1;
+ }
+
+ if (info->shared)
+ {
+#ifdef DEBUG
+ fprintf (stderr,
+ "i370_elf_check_relocs needs to create relocation for %s\n",
+ (h && h->root.root.string)
+ ? h->root.root.string : "<unknown>");
+#endif
+ if (sreloc == NULL)
+ {
+ sreloc = _bfd_elf_make_dynamic_reloc_section
+ (sec, dynobj, 2, abfd, /*rela?*/ TRUE);
+
+ if (sreloc == NULL)
+ return FALSE;
+ }
+
+ sreloc->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. */
+ }
+ }
+
+ return TRUE;
+}
+
+/* Finish up the dynamic sections. */
+/* XXX hack alert bogus This routine is mostly all junk and almost
+ certainly does the wrong thing. Its here simply because it does
+ just enough to allow glibc-2.1 ld.so to compile & link. */
+
+static bfd_boolean
+i370_elf_finish_dynamic_sections (bfd *output_bfd,
+ struct bfd_link_info *info)
+{
+ asection *sdyn;
+ bfd *dynobj = elf_hash_table (info)->dynobj;
+ asection *sgot = bfd_get_linker_section (dynobj, ".got");
+
+#ifdef DEBUG
+ fprintf (stderr, "i370_elf_finish_dynamic_sections called\n");
+#endif
+
+ sdyn = bfd_get_linker_section (dynobj, ".dynamic");
+
+ if (elf_hash_table (info)->dynamic_sections_created)
+ {
+ asection *splt;
+ Elf32_External_Dyn *dyncon, *dynconend;
+
+ splt = bfd_get_linker_section (dynobj, ".plt");
+ BFD_ASSERT (splt != NULL && sdyn != NULL);
+
+ dyncon = (Elf32_External_Dyn *) sdyn->contents;
+ dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->size);
+ for (; dyncon < dynconend; dyncon++)
+ {
+ Elf_Internal_Dyn dyn;
+ const char *name;
+ bfd_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
+ dyn.d_un.d_val = s->size;
+ }
+ bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
+ }
+ }
+ }
+
+ if (sgot && sgot->size != 0)
+ {
+ unsigned char *contents = sgot->contents;
+
+ if (sdyn == NULL)
+ bfd_put_32 (output_bfd, (bfd_vma) 0, contents);
+ else
+ bfd_put_32 (output_bfd,
+ sdyn->output_section->vma + sdyn->output_offset,
+ contents);
+
+ 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_linker_section (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;
+ sym.st_target_internal = 0;
+
+ for (s = output_bfd->sections; s != NULL; s = s->next)
+ {
+ int indx, dindx;
+ Elf32_External_Sym *esym;
+
+ 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;
+
+ esym = (Elf32_External_Sym *) sdynsym->contents + dindx;
+ bfd_elf32_swap_symbol_out (output_bfd, &sym, esym, NULL);
+ }
+ }
+
+ /* 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
+ relocatable 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 relocatable 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 bfd_boolean
+i370_elf_relocate_section (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;
+ asection *sreloc = NULL;
+ bfd_boolean ret = TRUE;
+
+#ifdef DEBUG
+ _bfd_error_handler ("i370_elf_relocate_section called for %B section %A, %ld relocations%s",
+ input_bfd, input_section,
+ (long) input_section->reloc_count,
+ (info->relocatable) ? " (relocatable)" : "");
+#endif
+
+ if (!i370_elf_howto_table[ R_I370_ADDR31 ])
+ /* Initialize howto table if needed. */
+ i370_elf_howto_init ();
+
+ for (; rel < relend; rel++)
+ {
+ enum i370_reloc_type r_type = (enum i370_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 = NULL;
+ asection *sec = NULL;
+ struct elf_link_hash_entry * h = NULL;
+ const char *sym_name = NULL;
+ reloc_howto_type *howto;
+ unsigned long r_symndx;
+ bfd_vma relocation;
+
+ /* Unknown relocation handling. */
+ if ((unsigned) r_type >= (unsigned) R_I370_max
+ || !i370_elf_howto_table[(int)r_type])
+ {
+ (*_bfd_error_handler) ("%B: unknown relocation type %d",
+ input_bfd,
+ (int) r_type);
+
+ bfd_set_error (bfd_error_bad_value);
+ ret = FALSE;
+ continue;
+ }
+
+ howto = i370_elf_howto_table[(int) r_type];
+ r_symndx = ELF32_R_SYM (rel->r_info);
+ relocation = 0;
+
+ if (r_symndx < symtab_hdr->sh_info)
+ {
+ sym = local_syms + r_symndx;
+ sec = local_sections[r_symndx];
+ sym_name = "<local symbol>";
+
+ relocation = _bfd_elf_rela_local_sym (output_bfd, sym, & sec, rel);
+ addend = rel->r_addend;
+ }
+ else
+ {
+ h = sym_hashes[r_symndx - symtab_hdr->sh_info];
+
+ if (info->wrap_hash != NULL
+ && (input_section->flags & SEC_DEBUGGING) != 0)
+ h = ((struct elf_link_hash_entry *)
+ unwrap_hash_lookup (info, input_bfd, &h->root));
+
+ 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 (info->shared
+ && ((! info->symbolic && h->dynindx != -1)
+ || !h->def_regular)
+ && (input_section->flags & SEC_ALLOC) != 0
+ && (r_type == R_I370_ADDR31
+ || r_type == R_I370_COPY
+ || r_type == R_I370_ADDR16
+ || r_type == R_I370_RELATIVE))
+ /* In these cases, we don't need the relocation
+ value. We check specially because in some
+ obscure cases sec->output_section will be NULL. */
+ ;
+ else
+ relocation = (h->root.u.def.value
+ + sec->output_section->vma
+ + sec->output_offset);
+ }
+ else if (h->root.type == bfd_link_hash_undefweak)
+ ;
+ else if (info->unresolved_syms_in_objects == RM_IGNORE
+ && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)
+ ;
+ else if (!info->relocatable)
+ {
+ if ((*info->callbacks->undefined_symbol)
+ (info, h->root.root.string, input_bfd,
+ input_section, rel->r_offset,
+ (info->unresolved_syms_in_objects == RM_GENERATE_ERROR
+ || ELF_ST_VISIBILITY (h->other))))
+ {
+ ret = FALSE;
+ continue;
+ }
+ }
+ }
+
+ if (sec != NULL && discarded_section (sec))
+ RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+ rel, 1, relend, howto, 0, contents);
+
+ if (info->relocatable)
+ continue;
+
+ switch ((int) r_type)
+ {
+ default:
+ (*_bfd_error_handler)
+ ("%B: unknown relocation type %d for symbol %s",
+ input_bfd, (int) r_type, sym_name);
+
+ bfd_set_error (bfd_error_bad_value);
+ ret = FALSE;
+ continue;
+
+ case (int) R_I370_NONE:
+ continue;
+
+ /* Relocations that may need to be propagated if this is a shared
+ object. */
+ case (int) R_I370_REL31:
+ /* 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_I370_ADDR31:
+ case (int) R_I370_ADDR16:
+ if (info->shared
+ && r_symndx != STN_UNDEF)
+ {
+ Elf_Internal_Rela outrel;
+ bfd_byte *loc;
+ int skip;
+
+#ifdef DEBUG
+ fprintf (stderr,
+ "i370_elf_relocate_section needs 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)
+ {
+ sreloc = _bfd_elf_get_dynamic_reloc_section
+ (input_bfd, input_section, /*rela?*/ TRUE);
+ if (sreloc == NULL)
+ return FALSE;
+ }
+
+ skip = 0;
+
+ outrel.r_offset =
+ _bfd_elf_section_offset (output_bfd, info, input_section,
+ rel->r_offset);
+ if (outrel.r_offset == (bfd_vma) -1
+ || outrel.r_offset == (bfd_vma) -2)
+ skip = (int) outrel.r_offset;
+ 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->def_regular))
+ {
+ 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_I370_ADDR31)
+ {
+ outrel.r_info = ELF32_R_INFO (0, R_I370_RELATIVE);
+ outrel.r_addend = relocation + rel->r_addend;
+ }
+ else
+ {
+ long indx;
+
+ if (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;
+
+ /* We are turning this relocation into one
+ against a section symbol. It would be
+ proper to subtract the symbol's value,
+ osec->vma, from the emitted reloc addend,
+ but ld.so expects buggy relocs. */
+ osec = sec->output_section;
+ indx = elf_section_data (osec)->dynindx;
+ if (indx == 0)
+ {
+ struct elf_link_hash_table *htab;
+ htab = elf_hash_table (info);
+ osec = htab->text_index_section;
+ indx = elf_section_data (osec)->dynindx;
+ }
+ BFD_ASSERT (indx != 0);
+#ifdef DEBUG
+ if (indx <= 0)
+ {
+ printf ("indx=%ld 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;
+ }
+ }
+
+ loc = sreloc->contents;
+ loc += sreloc->reloc_count++ * sizeof (Elf32_External_Rela);
+ bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
+
+ /* 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 == -1
+ || (input_section->flags & SEC_ALLOC) != 0
+ || ELF32_R_TYPE (outrel.r_info) != R_I370_RELATIVE)
+ continue;
+ }
+ break;
+
+ case (int) R_I370_COPY:
+ case (int) R_I370_RELATIVE:
+ (*_bfd_error_handler)
+ ("%B: Relocation %s is not yet supported for symbol %s.",
+ input_bfd,
+ i370_elf_howto_table[(int) r_type]->name,
+ sym_name);
+
+ bfd_set_error (bfd_error_invalid_operation);
+ ret = FALSE;
+ 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 = NULL;
+ 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,
+ (h ? &h->root : NULL),
+ name,
+ howto->name,
+ (bfd_vma) 0,
+ input_bfd,
+ input_section,
+ offset);
+ }
+ break;
+ }
+ }
+ }
+
+#ifdef DEBUG
+ fprintf (stderr, "\n");
+#endif
+
+ return ret;
+}
+
+#define TARGET_BIG_SYM i370_elf32_vec
+#define TARGET_BIG_NAME "elf32-i370"
+#define ELF_ARCH bfd_arch_i370
+#define ELF_MACHINE_CODE EM_S370
+#ifdef EM_I370_OLD
+#define ELF_MACHINE_ALT1 EM_I370_OLD
+#endif
+#define ELF_MAXPAGESIZE 0x1000
+#define ELF_OSABI ELFOSABI_GNU
+
+#define elf_info_to_howto i370_elf_info_to_howto
+
+#define elf_backend_plt_not_loaded 1
+#define elf_backend_rela_normal 1
+
+#define bfd_elf32_bfd_reloc_type_lookup i370_elf_reloc_type_lookup
+#define bfd_elf32_bfd_reloc_name_lookup i370_elf_reloc_name_lookup
+#define bfd_elf32_bfd_set_private_flags i370_elf_set_private_flags
+#define bfd_elf32_bfd_merge_private_bfd_data i370_elf_merge_private_bfd_data
+#define elf_backend_relocate_section i370_elf_relocate_section
+
+/* Dynamic loader support is mostly broken; just enough here to be able to
+ link glibc's ld.so without errors. */
+#define elf_backend_create_dynamic_sections i370_elf_create_dynamic_sections
+#define elf_backend_size_dynamic_sections i370_elf_size_dynamic_sections
+#define elf_backend_init_index_section _bfd_elf_init_1_index_section
+#define elf_backend_finish_dynamic_sections i370_elf_finish_dynamic_sections
+#define elf_backend_fake_sections i370_elf_fake_sections
+#define elf_backend_section_from_shdr i370_elf_section_from_shdr
+#define elf_backend_adjust_dynamic_symbol i370_elf_adjust_dynamic_symbol
+#define elf_backend_check_relocs i370_elf_check_relocs
+
+static int
+i370_noop (void)
+{
+ return 1;
+}
+
+#define elf_backend_finish_dynamic_symbol \
+ (bfd_boolean (*) \
+ (bfd *, struct bfd_link_info *, struct elf_link_hash_entry *, \
+ Elf_Internal_Sym *)) i370_noop
+
+#include "elf32-target.h"
diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c
new file mode 100644
index 0000000..f9b9428
--- /dev/null
+++ b/bfd/elf32-i386.c
@@ -0,0 +1,5441 @@
+/* Intel 80386/80486-specific support for 32-bit ELF
+ Copyright (C) 1993-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "bfdlink.h"
+#include "libbfd.h"
+#include "elf-bfd.h"
+#include "elf-nacl.h"
+#include "elf-vxworks.h"
+#include "bfd_stdint.h"
+#include "objalloc.h"
+#include "hashtab.h"
+#include "dwarf2.h"
+
+/* 386 uses REL relocations instead of RELA. */
+#define USE_REL 1
+
+#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),
+
+ /* We have a gap in the reloc numbers here.
+ R_386_standard counts the number up to this point, and
+ R_386_ext_offset is the value to subtract from a reloc type of
+ R_386_16 thru R_386_PC8 to form an index into this table. */
+#define R_386_standard (R_386_GOTPC + 1)
+#define R_386_ext_offset (R_386_TLS_TPOFF - R_386_standard)
+
+ /* These relocs are a GNU extension. */
+ HOWTO(R_386_TLS_TPOFF, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_386_TLS_TPOFF",
+ TRUE, 0xffffffff, 0xffffffff, FALSE),
+ HOWTO(R_386_TLS_IE, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_386_TLS_IE",
+ TRUE, 0xffffffff, 0xffffffff, FALSE),
+ HOWTO(R_386_TLS_GOTIE, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_386_TLS_GOTIE",
+ TRUE, 0xffffffff, 0xffffffff, FALSE),
+ HOWTO(R_386_TLS_LE, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_386_TLS_LE",
+ TRUE, 0xffffffff, 0xffffffff, FALSE),
+ HOWTO(R_386_TLS_GD, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_386_TLS_GD",
+ TRUE, 0xffffffff, 0xffffffff, FALSE),
+ HOWTO(R_386_TLS_LDM, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_386_TLS_LDM",
+ TRUE, 0xffffffff, 0xffffffff, FALSE),
+ 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_signed,
+ bfd_elf_generic_reloc, "R_386_PC8",
+ TRUE, 0xff, 0xff, TRUE),
+
+#define R_386_ext (R_386_PC8 + 1 - R_386_ext_offset)
+#define R_386_tls_offset (R_386_TLS_LDO_32 - R_386_ext)
+ /* These are common with Solaris TLS implementation. */
+ HOWTO(R_386_TLS_LDO_32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_386_TLS_LDO_32",
+ TRUE, 0xffffffff, 0xffffffff, FALSE),
+ HOWTO(R_386_TLS_IE_32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_386_TLS_IE_32",
+ TRUE, 0xffffffff, 0xffffffff, FALSE),
+ HOWTO(R_386_TLS_LE_32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_386_TLS_LE_32",
+ TRUE, 0xffffffff, 0xffffffff, FALSE),
+ HOWTO(R_386_TLS_DTPMOD32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_386_TLS_DTPMOD32",
+ TRUE, 0xffffffff, 0xffffffff, FALSE),
+ HOWTO(R_386_TLS_DTPOFF32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_386_TLS_DTPOFF32",
+ TRUE, 0xffffffff, 0xffffffff, FALSE),
+ HOWTO(R_386_TLS_TPOFF32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_386_TLS_TPOFF32",
+ TRUE, 0xffffffff, 0xffffffff, FALSE),
+ HOWTO(R_386_SIZE32, 0, 2, 32, FALSE, 0, complain_overflow_unsigned,
+ bfd_elf_generic_reloc, "R_386_SIZE32",
+ TRUE, 0xffffffff, 0xffffffff, FALSE),
+ HOWTO(R_386_TLS_GOTDESC, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_386_TLS_GOTDESC",
+ TRUE, 0xffffffff, 0xffffffff, FALSE),
+ HOWTO(R_386_TLS_DESC_CALL, 0, 0, 0, FALSE, 0, complain_overflow_dont,
+ bfd_elf_generic_reloc, "R_386_TLS_DESC_CALL",
+ FALSE, 0, 0, FALSE),
+ HOWTO(R_386_TLS_DESC, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_386_TLS_DESC",
+ TRUE, 0xffffffff, 0xffffffff, FALSE),
+ HOWTO(R_386_IRELATIVE, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_386_IRELATIVE",
+ TRUE, 0xffffffff, 0xffffffff, FALSE),
+
+ /* Another gap. */
+#define R_386_irelative (R_386_IRELATIVE + 1 - R_386_tls_offset)
+#define R_386_vt_offset (R_386_GNU_VTINHERIT - R_386_irelative)
+
+/* GNU extension to record C++ vtable hierarchy. */
+ 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), /* pcrel_offset */
+
+/* GNU extension to record C++ vtable member usage. */
+ 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) /* pcrel_offset */
+
+#define R_386_vt (R_386_GNU_VTENTRY + 1 - R_386_vt_offset)
+
+};
+
+#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 (bfd *abfd ATTRIBUTE_UNUSED,
+ bfd_reloc_code_real_type code)
+{
+ switch (code)
+ {
+ case BFD_RELOC_NONE:
+ TRACE ("BFD_RELOC_NONE");
+ return &elf_howto_table[R_386_NONE];
+
+ case BFD_RELOC_32:
+ TRACE ("BFD_RELOC_32");
+ return &elf_howto_table[R_386_32];
+
+ case BFD_RELOC_CTOR:
+ TRACE ("BFD_RELOC_CTOR");
+ return &elf_howto_table[R_386_32];
+
+ case BFD_RELOC_32_PCREL:
+ TRACE ("BFD_RELOC_PC32");
+ return &elf_howto_table[R_386_PC32];
+
+ case BFD_RELOC_386_GOT32:
+ TRACE ("BFD_RELOC_386_GOT32");
+ return &elf_howto_table[R_386_GOT32];
+
+ case BFD_RELOC_386_PLT32:
+ TRACE ("BFD_RELOC_386_PLT32");
+ return &elf_howto_table[R_386_PLT32];
+
+ case BFD_RELOC_386_COPY:
+ TRACE ("BFD_RELOC_386_COPY");
+ return &elf_howto_table[R_386_COPY];
+
+ case BFD_RELOC_386_GLOB_DAT:
+ TRACE ("BFD_RELOC_386_GLOB_DAT");
+ return &elf_howto_table[R_386_GLOB_DAT];
+
+ case BFD_RELOC_386_JUMP_SLOT:
+ TRACE ("BFD_RELOC_386_JUMP_SLOT");
+ return &elf_howto_table[R_386_JUMP_SLOT];
+
+ case BFD_RELOC_386_RELATIVE:
+ TRACE ("BFD_RELOC_386_RELATIVE");
+ return &elf_howto_table[R_386_RELATIVE];
+
+ case BFD_RELOC_386_GOTOFF:
+ TRACE ("BFD_RELOC_386_GOTOFF");
+ return &elf_howto_table[R_386_GOTOFF];
+
+ case BFD_RELOC_386_GOTPC:
+ TRACE ("BFD_RELOC_386_GOTPC");
+ return &elf_howto_table[R_386_GOTPC];
+
+ /* These relocs are a GNU extension. */
+ case BFD_RELOC_386_TLS_TPOFF:
+ TRACE ("BFD_RELOC_386_TLS_TPOFF");
+ return &elf_howto_table[R_386_TLS_TPOFF - R_386_ext_offset];
+
+ case BFD_RELOC_386_TLS_IE:
+ TRACE ("BFD_RELOC_386_TLS_IE");
+ return &elf_howto_table[R_386_TLS_IE - R_386_ext_offset];
+
+ case BFD_RELOC_386_TLS_GOTIE:
+ TRACE ("BFD_RELOC_386_TLS_GOTIE");
+ return &elf_howto_table[R_386_TLS_GOTIE - R_386_ext_offset];
+
+ case BFD_RELOC_386_TLS_LE:
+ TRACE ("BFD_RELOC_386_TLS_LE");
+ return &elf_howto_table[R_386_TLS_LE - R_386_ext_offset];
+
+ case BFD_RELOC_386_TLS_GD:
+ TRACE ("BFD_RELOC_386_TLS_GD");
+ return &elf_howto_table[R_386_TLS_GD - R_386_ext_offset];
+
+ case BFD_RELOC_386_TLS_LDM:
+ TRACE ("BFD_RELOC_386_TLS_LDM");
+ return &elf_howto_table[R_386_TLS_LDM - R_386_ext_offset];
+
+ case BFD_RELOC_16:
+ TRACE ("BFD_RELOC_16");
+ return &elf_howto_table[R_386_16 - R_386_ext_offset];
+
+ case BFD_RELOC_16_PCREL:
+ TRACE ("BFD_RELOC_16_PCREL");
+ return &elf_howto_table[R_386_PC16 - R_386_ext_offset];
+
+ case BFD_RELOC_8:
+ TRACE ("BFD_RELOC_8");
+ return &elf_howto_table[R_386_8 - R_386_ext_offset];
+
+ case BFD_RELOC_8_PCREL:
+ TRACE ("BFD_RELOC_8_PCREL");
+ return &elf_howto_table[R_386_PC8 - R_386_ext_offset];
+
+ /* Common with Sun TLS implementation. */
+ case BFD_RELOC_386_TLS_LDO_32:
+ TRACE ("BFD_RELOC_386_TLS_LDO_32");
+ return &elf_howto_table[R_386_TLS_LDO_32 - R_386_tls_offset];
+
+ case BFD_RELOC_386_TLS_IE_32:
+ TRACE ("BFD_RELOC_386_TLS_IE_32");
+ return &elf_howto_table[R_386_TLS_IE_32 - R_386_tls_offset];
+
+ case BFD_RELOC_386_TLS_LE_32:
+ TRACE ("BFD_RELOC_386_TLS_LE_32");
+ return &elf_howto_table[R_386_TLS_LE_32 - R_386_tls_offset];
+
+ case BFD_RELOC_386_TLS_DTPMOD32:
+ TRACE ("BFD_RELOC_386_TLS_DTPMOD32");
+ return &elf_howto_table[R_386_TLS_DTPMOD32 - R_386_tls_offset];
+
+ case BFD_RELOC_386_TLS_DTPOFF32:
+ TRACE ("BFD_RELOC_386_TLS_DTPOFF32");
+ return &elf_howto_table[R_386_TLS_DTPOFF32 - R_386_tls_offset];
+
+ case BFD_RELOC_386_TLS_TPOFF32:
+ TRACE ("BFD_RELOC_386_TLS_TPOFF32");
+ return &elf_howto_table[R_386_TLS_TPOFF32 - R_386_tls_offset];
+
+ case BFD_RELOC_SIZE32:
+ TRACE ("BFD_RELOC_SIZE32");
+ return &elf_howto_table[R_386_SIZE32 - R_386_tls_offset];
+
+ case BFD_RELOC_386_TLS_GOTDESC:
+ TRACE ("BFD_RELOC_386_TLS_GOTDESC");
+ return &elf_howto_table[R_386_TLS_GOTDESC - R_386_tls_offset];
+
+ case BFD_RELOC_386_TLS_DESC_CALL:
+ TRACE ("BFD_RELOC_386_TLS_DESC_CALL");
+ return &elf_howto_table[R_386_TLS_DESC_CALL - R_386_tls_offset];
+
+ case BFD_RELOC_386_TLS_DESC:
+ TRACE ("BFD_RELOC_386_TLS_DESC");
+ return &elf_howto_table[R_386_TLS_DESC - R_386_tls_offset];
+
+ case BFD_RELOC_386_IRELATIVE:
+ TRACE ("BFD_RELOC_386_IRELATIVE");
+ return &elf_howto_table[R_386_IRELATIVE - R_386_tls_offset];
+
+ case BFD_RELOC_VTABLE_INHERIT:
+ TRACE ("BFD_RELOC_VTABLE_INHERIT");
+ return &elf_howto_table[R_386_GNU_VTINHERIT - R_386_vt_offset];
+
+ case BFD_RELOC_VTABLE_ENTRY:
+ TRACE ("BFD_RELOC_VTABLE_ENTRY");
+ return &elf_howto_table[R_386_GNU_VTENTRY - R_386_vt_offset];
+
+ default:
+ break;
+ }
+
+ TRACE ("Unknown");
+ return 0;
+}
+
+static reloc_howto_type *
+elf_i386_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ const char *r_name)
+{
+ unsigned int i;
+
+ for (i = 0; i < sizeof (elf_howto_table) / sizeof (elf_howto_table[0]); i++)
+ if (elf_howto_table[i].name != NULL
+ && strcasecmp (elf_howto_table[i].name, r_name) == 0)
+ return &elf_howto_table[i];
+
+ return NULL;
+}
+
+static reloc_howto_type *
+elf_i386_rtype_to_howto (bfd *abfd, unsigned r_type)
+{
+ unsigned int indx;
+
+ if ((indx = r_type) >= R_386_standard
+ && ((indx = r_type - R_386_ext_offset) - R_386_standard
+ >= R_386_ext - R_386_standard)
+ && ((indx = r_type - R_386_tls_offset) - R_386_ext
+ >= R_386_irelative - R_386_ext)
+ && ((indx = r_type - R_386_vt_offset) - R_386_irelative
+ >= R_386_vt - R_386_irelative))
+ {
+ (*_bfd_error_handler) (_("%B: invalid relocation type %d"),
+ abfd, (int) r_type);
+ indx = R_386_NONE;
+ }
+ BFD_ASSERT (elf_howto_table [indx].type == r_type);
+ return &elf_howto_table[indx];
+}
+
+static void
+elf_i386_info_to_howto_rel (bfd *abfd ATTRIBUTE_UNUSED,
+ arelent *cache_ptr,
+ Elf_Internal_Rela *dst)
+{
+ unsigned int r_type = ELF32_R_TYPE (dst->r_info);
+ cache_ptr->howto = elf_i386_rtype_to_howto (abfd, r_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 bfd_boolean
+elf_i386_is_local_label_name (bfd *abfd, const char *name)
+{
+ if (name[0] == '.' && name[1] == 'X')
+ return TRUE;
+
+ return _bfd_elf_is_local_label_name (abfd, name);
+}
+
+/* Support for core dump NOTE sections. */
+
+static bfd_boolean
+elf_i386_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
+{
+ int offset;
+ size_t size;
+
+ if (note->namesz == 8 && strcmp (note->namedata, "FreeBSD") == 0)
+ {
+ int pr_version = bfd_get_32 (abfd, note->descdata);
+
+ if (pr_version != 1)
+ return FALSE;
+
+ /* pr_cursig */
+ elf_tdata (abfd)->core->signal = bfd_get_32 (abfd, note->descdata + 20);
+
+ /* pr_pid */
+ elf_tdata (abfd)->core->lwpid = bfd_get_32 (abfd, note->descdata + 24);
+
+ /* pr_reg */
+ offset = 28;
+ size = bfd_get_32 (abfd, note->descdata + 8);
+ }
+ else
+ {
+ switch (note->descsz)
+ {
+ default:
+ return FALSE;
+
+ case 144: /* Linux/i386 */
+ /* pr_cursig */
+ elf_tdata (abfd)->core->signal = bfd_get_16 (abfd, note->descdata + 12);
+
+ /* pr_pid */
+ elf_tdata (abfd)->core->lwpid = bfd_get_32 (abfd, note->descdata + 24);
+
+ /* pr_reg */
+ offset = 72;
+ size = 68;
+
+ break;
+ }
+ }
+
+ /* Make a ".reg/999" section. */
+ return _bfd_elfcore_make_pseudosection (abfd, ".reg",
+ size, note->descpos + offset);
+}
+
+static bfd_boolean
+elf_i386_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
+{
+ if (note->namesz == 8 && strcmp (note->namedata, "FreeBSD") == 0)
+ {
+ int pr_version = bfd_get_32 (abfd, note->descdata);
+
+ if (pr_version != 1)
+ return FALSE;
+
+ elf_tdata (abfd)->core->program
+ = _bfd_elfcore_strndup (abfd, note->descdata + 8, 17);
+ elf_tdata (abfd)->core->command
+ = _bfd_elfcore_strndup (abfd, note->descdata + 25, 81);
+ }
+ else
+ {
+ switch (note->descsz)
+ {
+ default:
+ return FALSE;
+
+ case 124: /* Linux/i386 elf_prpsinfo. */
+ elf_tdata (abfd)->core->pid
+ = bfd_get_32 (abfd, note->descdata + 12);
+ elf_tdata (abfd)->core->program
+ = _bfd_elfcore_strndup (abfd, note->descdata + 28, 16);
+ elf_tdata (abfd)->core->command
+ = _bfd_elfcore_strndup (abfd, note->descdata + 44, 80);
+ }
+ }
+
+ /* 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;
+}
+
+/* Functions for the i386 ELF linker.
+
+ In order to gain some understanding of code in this file without
+ knowing all the intricate details of the linker, note the
+ following:
+
+ Functions named elf_i386_* are called by external routines, other
+ functions are only called locally. elf_i386_* functions appear
+ in this file more or less in the order in which they are called
+ from external routines. eg. elf_i386_check_relocs is called
+ early in the link process, elf_i386_finish_dynamic_sections is
+ one of the last functions. */
+
+
+/* The name of the dynamic interpreter. This is put in the .interp
+ section. */
+
+#define ELF_DYNAMIC_INTERPRETER "/usr/lib/libc.so.1"
+
+/* If ELIMINATE_COPY_RELOCS is non-zero, the linker will try to avoid
+ copying dynamic variables from a shared lib into an app's dynbss
+ section, and instead use a dynamic relocation to point into the
+ shared lib. */
+#define ELIMINATE_COPY_RELOCS 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.
+ Will be padded to PLT_ENTRY_SIZE with htab->plt0_pad_byte. */
+
+static const bfd_byte elf_i386_plt0_entry[12] =
+{
+ 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. */
+};
+
+/* 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.
+ Will be padded to PLT_ENTRY_SIZE with htab->plt0_pad_byte. */
+
+static const bfd_byte elf_i386_pic_plt0_entry[12] =
+{
+ 0xff, 0xb3, 4, 0, 0, 0, /* pushl 4(%ebx) */
+ 0xff, 0xa3, 8, 0, 0, 0 /* jmp *8(%ebx) */
+};
+
+/* 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. */
+};
+
+/* .eh_frame covering the .plt section. */
+
+static const bfd_byte elf_i386_eh_frame_plt[] =
+{
+#define PLT_CIE_LENGTH 20
+#define PLT_FDE_LENGTH 36
+#define PLT_FDE_START_OFFSET 4 + PLT_CIE_LENGTH + 8
+#define PLT_FDE_LEN_OFFSET 4 + PLT_CIE_LENGTH + 12
+ PLT_CIE_LENGTH, 0, 0, 0, /* CIE length */
+ 0, 0, 0, 0, /* CIE ID */
+ 1, /* CIE version */
+ 'z', 'R', 0, /* Augmentation string */
+ 1, /* Code alignment factor */
+ 0x7c, /* Data alignment factor */
+ 8, /* Return address column */
+ 1, /* Augmentation size */
+ DW_EH_PE_pcrel | DW_EH_PE_sdata4, /* FDE encoding */
+ DW_CFA_def_cfa, 4, 4, /* DW_CFA_def_cfa: r4 (esp) ofs 4 */
+ DW_CFA_offset + 8, 1, /* DW_CFA_offset: r8 (eip) at cfa-4 */
+ DW_CFA_nop, DW_CFA_nop,
+
+ PLT_FDE_LENGTH, 0, 0, 0, /* FDE length */
+ PLT_CIE_LENGTH + 8, 0, 0, 0, /* CIE pointer */
+ 0, 0, 0, 0, /* R_386_PC32 .plt goes here */
+ 0, 0, 0, 0, /* .plt size goes here */
+ 0, /* Augmentation size */
+ DW_CFA_def_cfa_offset, 8, /* DW_CFA_def_cfa_offset: 8 */
+ DW_CFA_advance_loc + 6, /* DW_CFA_advance_loc: 6 to __PLT__+6 */
+ DW_CFA_def_cfa_offset, 12, /* DW_CFA_def_cfa_offset: 12 */
+ DW_CFA_advance_loc + 10, /* DW_CFA_advance_loc: 10 to __PLT__+16 */
+ DW_CFA_def_cfa_expression, /* DW_CFA_def_cfa_expression */
+ 11, /* Block length */
+ DW_OP_breg4, 4, /* DW_OP_breg4 (esp): 4 */
+ DW_OP_breg8, 0, /* DW_OP_breg8 (eip): 0 */
+ DW_OP_lit15, DW_OP_and, DW_OP_lit11, DW_OP_ge,
+ DW_OP_lit2, DW_OP_shl, DW_OP_plus,
+ DW_CFA_nop, DW_CFA_nop, DW_CFA_nop, DW_CFA_nop
+};
+
+struct elf_i386_plt_layout
+{
+ /* The first entry in an absolute procedure linkage table looks like this. */
+ const bfd_byte *plt0_entry;
+ unsigned int plt0_entry_size;
+
+ /* Offsets into plt0_entry that are to be replaced with GOT[1] and GOT[2]. */
+ unsigned int plt0_got1_offset;
+ unsigned int plt0_got2_offset;
+
+ /* Later entries in an absolute procedure linkage table look like this. */
+ const bfd_byte *plt_entry;
+ unsigned int plt_entry_size;
+
+ /* Offsets into plt_entry that are to be replaced with... */
+ unsigned int plt_got_offset; /* ... address of this symbol in .got. */
+ unsigned int plt_reloc_offset; /* ... offset into relocation table. */
+ unsigned int plt_plt_offset; /* ... offset to start of .plt. */
+
+ /* Offset into plt_entry where the initial value of the GOT entry points. */
+ unsigned int plt_lazy_offset;
+
+ /* The first entry in a PIC procedure linkage table looks like this. */
+ const bfd_byte *pic_plt0_entry;
+
+ /* Subsequent entries in a PIC procedure linkage table look like this. */
+ const bfd_byte *pic_plt_entry;
+
+ /* .eh_frame covering the .plt section. */
+ const bfd_byte *eh_frame_plt;
+ unsigned int eh_frame_plt_size;
+};
+
+#define GET_PLT_ENTRY_SIZE(abfd) \
+ get_elf_i386_backend_data (abfd)->plt->plt_entry_size
+
+/* These are the standard parameters. */
+static const struct elf_i386_plt_layout elf_i386_plt =
+ {
+ elf_i386_plt0_entry, /* plt0_entry */
+ sizeof (elf_i386_plt0_entry), /* plt0_entry_size */
+ 2, /* plt0_got1_offset */
+ 8, /* plt0_got2_offset */
+ elf_i386_plt_entry, /* plt_entry */
+ PLT_ENTRY_SIZE, /* plt_entry_size */
+ 2, /* plt_got_offset */
+ 7, /* plt_reloc_offset */
+ 12, /* plt_plt_offset */
+ 6, /* plt_lazy_offset */
+ elf_i386_pic_plt0_entry, /* pic_plt0_entry */
+ elf_i386_pic_plt_entry, /* pic_plt_entry */
+ elf_i386_eh_frame_plt, /* eh_frame_plt */
+ sizeof (elf_i386_eh_frame_plt), /* eh_frame_plt_size */
+ };
+
+
+/* On VxWorks, the .rel.plt.unloaded section has absolute relocations
+ for the PLTResolve stub and then for each PLT entry. */
+#define PLTRESOLVE_RELOCS_SHLIB 0
+#define PLTRESOLVE_RELOCS 2
+#define PLT_NON_JUMP_SLOT_RELOCS 2
+
+/* Architecture-specific backend data for i386. */
+
+struct elf_i386_backend_data
+{
+ /* Parameters describing PLT generation. */
+ const struct elf_i386_plt_layout *plt;
+
+ /* Value used to fill the unused bytes of the first PLT entry. */
+ bfd_byte plt0_pad_byte;
+
+ /* True if the target system is VxWorks. */
+ int is_vxworks;
+};
+
+#define get_elf_i386_backend_data(abfd) \
+ ((const struct elf_i386_backend_data *) \
+ get_elf_backend_data (abfd)->arch_data)
+
+/* These are the standard parameters. */
+static const struct elf_i386_backend_data elf_i386_arch_bed =
+ {
+ &elf_i386_plt, /* plt */
+ 0, /* plt0_pad_byte */
+ 0, /* is_vxworks */
+ };
+
+#define elf_backend_arch_data &elf_i386_arch_bed
+
+/* i386 ELF linker hash entry. */
+
+struct elf_i386_link_hash_entry
+{
+ struct elf_link_hash_entry elf;
+
+ /* Track dynamic relocs copied for this symbol. */
+ struct elf_dyn_relocs *dyn_relocs;
+
+#define GOT_UNKNOWN 0
+#define GOT_NORMAL 1
+#define GOT_TLS_GD 2
+#define GOT_TLS_IE 4
+#define GOT_TLS_IE_POS 5
+#define GOT_TLS_IE_NEG 6
+#define GOT_TLS_IE_BOTH 7
+#define GOT_TLS_GDESC 8
+#define GOT_TLS_GD_BOTH_P(type) \
+ ((type) == (GOT_TLS_GD | GOT_TLS_GDESC))
+#define GOT_TLS_GD_P(type) \
+ ((type) == GOT_TLS_GD || GOT_TLS_GD_BOTH_P (type))
+#define GOT_TLS_GDESC_P(type) \
+ ((type) == GOT_TLS_GDESC || GOT_TLS_GD_BOTH_P (type))
+#define GOT_TLS_GD_ANY_P(type) \
+ (GOT_TLS_GD_P (type) || GOT_TLS_GDESC_P (type))
+ unsigned char tls_type;
+
+ /* Offset of the GOTPLT entry reserved for the TLS descriptor,
+ starting at the end of the jump table. */
+ bfd_vma tlsdesc_got;
+};
+
+#define elf_i386_hash_entry(ent) ((struct elf_i386_link_hash_entry *)(ent))
+
+struct elf_i386_obj_tdata
+{
+ struct elf_obj_tdata root;
+
+ /* tls_type for each local got entry. */
+ char *local_got_tls_type;
+
+ /* GOTPLT entries for TLS descriptors. */
+ bfd_vma *local_tlsdesc_gotent;
+};
+
+#define elf_i386_tdata(abfd) \
+ ((struct elf_i386_obj_tdata *) (abfd)->tdata.any)
+
+#define elf_i386_local_got_tls_type(abfd) \
+ (elf_i386_tdata (abfd)->local_got_tls_type)
+
+#define elf_i386_local_tlsdesc_gotent(abfd) \
+ (elf_i386_tdata (abfd)->local_tlsdesc_gotent)
+
+#define is_i386_elf(bfd) \
+ (bfd_get_flavour (bfd) == bfd_target_elf_flavour \
+ && elf_tdata (bfd) != NULL \
+ && elf_object_id (bfd) == I386_ELF_DATA)
+
+static bfd_boolean
+elf_i386_mkobject (bfd *abfd)
+{
+ return bfd_elf_allocate_object (abfd, sizeof (struct elf_i386_obj_tdata),
+ I386_ELF_DATA);
+}
+
+/* i386 ELF linker hash table. */
+
+struct elf_i386_link_hash_table
+{
+ struct elf_link_hash_table elf;
+
+ /* Short-cuts to get to dynamic linker sections. */
+ asection *sdynbss;
+ asection *srelbss;
+ asection *plt_eh_frame;
+
+ union
+ {
+ bfd_signed_vma refcount;
+ bfd_vma offset;
+ } tls_ldm_got;
+
+ /* The amount of space used by the reserved portion of the sgotplt
+ section, plus whatever space is used by the jump slots. */
+ bfd_vma sgotplt_jump_table_size;
+
+ /* Small local sym cache. */
+ struct sym_cache sym_cache;
+
+ /* _TLS_MODULE_BASE_ symbol. */
+ struct bfd_link_hash_entry *tls_module_base;
+
+ /* Used by local STT_GNU_IFUNC symbols. */
+ htab_t loc_hash_table;
+ void * loc_hash_memory;
+
+ /* The (unloaded but important) .rel.plt.unloaded section on VxWorks. */
+ asection *srelplt2;
+
+ /* The index of the next unused R_386_TLS_DESC slot in .rel.plt. */
+ bfd_vma next_tls_desc_index;
+
+ /* The index of the next unused R_386_JUMP_SLOT slot in .rel.plt. */
+ bfd_vma next_jump_slot_index;
+
+ /* The index of the next unused R_386_IRELATIVE slot in .rel.plt. */
+ bfd_vma next_irelative_index;
+};
+
+/* Get the i386 ELF linker hash table from a link_info structure. */
+
+#define elf_i386_hash_table(p) \
+ (elf_hash_table_id ((struct elf_link_hash_table *) ((p)->hash)) \
+ == I386_ELF_DATA ? ((struct elf_i386_link_hash_table *) ((p)->hash)) : NULL)
+
+#define elf_i386_compute_jump_table_size(htab) \
+ ((htab)->elf.srelplt->reloc_count * 4)
+
+/* Create an entry in an i386 ELF linker hash table. */
+
+static struct bfd_hash_entry *
+elf_i386_link_hash_newfunc (struct bfd_hash_entry *entry,
+ struct bfd_hash_table *table,
+ const char *string)
+{
+ /* Allocate the structure if it has not already been allocated by a
+ subclass. */
+ if (entry == NULL)
+ {
+ entry = (struct bfd_hash_entry *)
+ bfd_hash_allocate (table, sizeof (struct elf_i386_link_hash_entry));
+ if (entry == NULL)
+ return entry;
+ }
+
+ /* Call the allocation method of the superclass. */
+ entry = _bfd_elf_link_hash_newfunc (entry, table, string);
+ if (entry != NULL)
+ {
+ struct elf_i386_link_hash_entry *eh;
+
+ eh = (struct elf_i386_link_hash_entry *) entry;
+ eh->dyn_relocs = NULL;
+ eh->tls_type = GOT_UNKNOWN;
+ eh->tlsdesc_got = (bfd_vma) -1;
+ }
+
+ return entry;
+}
+
+/* Compute a hash of a local hash entry. We use elf_link_hash_entry
+ for local symbol so that we can handle local STT_GNU_IFUNC symbols
+ as global symbol. We reuse indx and dynstr_index for local symbol
+ hash since they aren't used by global symbols in this backend. */
+
+static hashval_t
+elf_i386_local_htab_hash (const void *ptr)
+{
+ struct elf_link_hash_entry *h
+ = (struct elf_link_hash_entry *) ptr;
+ return ELF_LOCAL_SYMBOL_HASH (h->indx, h->dynstr_index);
+}
+
+/* Compare local hash entries. */
+
+static int
+elf_i386_local_htab_eq (const void *ptr1, const void *ptr2)
+{
+ struct elf_link_hash_entry *h1
+ = (struct elf_link_hash_entry *) ptr1;
+ struct elf_link_hash_entry *h2
+ = (struct elf_link_hash_entry *) ptr2;
+
+ return h1->indx == h2->indx && h1->dynstr_index == h2->dynstr_index;
+}
+
+/* Find and/or create a hash entry for local symbol. */
+
+static struct elf_link_hash_entry *
+elf_i386_get_local_sym_hash (struct elf_i386_link_hash_table *htab,
+ bfd *abfd, const Elf_Internal_Rela *rel,
+ bfd_boolean create)
+{
+ struct elf_i386_link_hash_entry e, *ret;
+ asection *sec = abfd->sections;
+ hashval_t h = ELF_LOCAL_SYMBOL_HASH (sec->id,
+ ELF32_R_SYM (rel->r_info));
+ void **slot;
+
+ e.elf.indx = sec->id;
+ e.elf.dynstr_index = ELF32_R_SYM (rel->r_info);
+ slot = htab_find_slot_with_hash (htab->loc_hash_table, &e, h,
+ create ? INSERT : NO_INSERT);
+
+ if (!slot)
+ return NULL;
+
+ if (*slot)
+ {
+ ret = (struct elf_i386_link_hash_entry *) *slot;
+ return &ret->elf;
+ }
+
+ ret = (struct elf_i386_link_hash_entry *)
+ objalloc_alloc ((struct objalloc *) htab->loc_hash_memory,
+ sizeof (struct elf_i386_link_hash_entry));
+ if (ret)
+ {
+ memset (ret, 0, sizeof (*ret));
+ ret->elf.indx = sec->id;
+ ret->elf.dynstr_index = ELF32_R_SYM (rel->r_info);
+ ret->elf.dynindx = -1;
+ *slot = ret;
+ }
+ return &ret->elf;
+}
+
+/* Destroy an i386 ELF linker hash table. */
+
+static void
+elf_i386_link_hash_table_free (bfd *obfd)
+{
+ struct elf_i386_link_hash_table *htab
+ = (struct elf_i386_link_hash_table *) obfd->link.hash;
+
+ if (htab->loc_hash_table)
+ htab_delete (htab->loc_hash_table);
+ if (htab->loc_hash_memory)
+ objalloc_free ((struct objalloc *) htab->loc_hash_memory);
+ _bfd_elf_link_hash_table_free (obfd);
+}
+
+/* Create an i386 ELF linker hash table. */
+
+static struct bfd_link_hash_table *
+elf_i386_link_hash_table_create (bfd *abfd)
+{
+ struct elf_i386_link_hash_table *ret;
+ bfd_size_type amt = sizeof (struct elf_i386_link_hash_table);
+
+ ret = (struct elf_i386_link_hash_table *) bfd_zmalloc (amt);
+ if (ret == NULL)
+ return NULL;
+
+ if (!_bfd_elf_link_hash_table_init (&ret->elf, abfd,
+ elf_i386_link_hash_newfunc,
+ sizeof (struct elf_i386_link_hash_entry),
+ I386_ELF_DATA))
+ {
+ free (ret);
+ return NULL;
+ }
+
+ ret->loc_hash_table = htab_try_create (1024,
+ elf_i386_local_htab_hash,
+ elf_i386_local_htab_eq,
+ NULL);
+ ret->loc_hash_memory = objalloc_create ();
+ if (!ret->loc_hash_table || !ret->loc_hash_memory)
+ {
+ elf_i386_link_hash_table_free (abfd);
+ return NULL;
+ }
+ ret->elf.root.hash_table_free = elf_i386_link_hash_table_free;
+
+ return &ret->elf.root;
+}
+
+/* Create .plt, .rel.plt, .got, .got.plt, .rel.got, .dynbss, and
+ .rel.bss sections in DYNOBJ, and set up shortcuts to them in our
+ hash table. */
+
+static bfd_boolean
+elf_i386_create_dynamic_sections (bfd *dynobj, struct bfd_link_info *info)
+{
+ struct elf_i386_link_hash_table *htab;
+
+ if (!_bfd_elf_create_dynamic_sections (dynobj, info))
+ return FALSE;
+
+ htab = elf_i386_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ htab->sdynbss = bfd_get_linker_section (dynobj, ".dynbss");
+ if (!info->shared)
+ htab->srelbss = bfd_get_linker_section (dynobj, ".rel.bss");
+
+ if (!htab->sdynbss
+ || (!info->shared && !htab->srelbss))
+ abort ();
+
+ if (get_elf_i386_backend_data (dynobj)->is_vxworks
+ && !elf_vxworks_create_dynamic_sections (dynobj, info,
+ &htab->srelplt2))
+ return FALSE;
+
+ if (!info->no_ld_generated_unwind_info
+ && htab->plt_eh_frame == NULL
+ && htab->elf.splt != NULL)
+ {
+ flagword flags = (SEC_ALLOC | SEC_LOAD | SEC_READONLY
+ | SEC_HAS_CONTENTS | SEC_IN_MEMORY
+ | SEC_LINKER_CREATED);
+ htab->plt_eh_frame
+ = bfd_make_section_anyway_with_flags (dynobj, ".eh_frame", flags);
+ if (htab->plt_eh_frame == NULL
+ || !bfd_set_section_alignment (dynobj, htab->plt_eh_frame, 2))
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/* Copy the extra info we tack onto an elf_link_hash_entry. */
+
+static void
+elf_i386_copy_indirect_symbol (struct bfd_link_info *info,
+ struct elf_link_hash_entry *dir,
+ struct elf_link_hash_entry *ind)
+{
+ struct elf_i386_link_hash_entry *edir, *eind;
+
+ edir = (struct elf_i386_link_hash_entry *) dir;
+ eind = (struct elf_i386_link_hash_entry *) ind;
+
+ if (eind->dyn_relocs != NULL)
+ {
+ if (edir->dyn_relocs != NULL)
+ {
+ struct elf_dyn_relocs **pp;
+ struct elf_dyn_relocs *p;
+
+ /* Add reloc counts against the indirect sym to the direct sym
+ list. Merge any entries against the same section. */
+ for (pp = &eind->dyn_relocs; (p = *pp) != NULL; )
+ {
+ struct elf_dyn_relocs *q;
+
+ for (q = edir->dyn_relocs; q != NULL; q = q->next)
+ if (q->sec == p->sec)
+ {
+ q->pc_count += p->pc_count;
+ q->count += p->count;
+ *pp = p->next;
+ break;
+ }
+ if (q == NULL)
+ pp = &p->next;
+ }
+ *pp = edir->dyn_relocs;
+ }
+
+ edir->dyn_relocs = eind->dyn_relocs;
+ eind->dyn_relocs = NULL;
+ }
+
+ if (ind->root.type == bfd_link_hash_indirect
+ && dir->got.refcount <= 0)
+ {
+ edir->tls_type = eind->tls_type;
+ eind->tls_type = GOT_UNKNOWN;
+ }
+
+ if (ELIMINATE_COPY_RELOCS
+ && ind->root.type != bfd_link_hash_indirect
+ && dir->dynamic_adjusted)
+ {
+ /* If called to transfer flags for a weakdef during processing
+ of elf_adjust_dynamic_symbol, don't copy non_got_ref.
+ We clear it ourselves for ELIMINATE_COPY_RELOCS. */
+ dir->ref_dynamic |= ind->ref_dynamic;
+ dir->ref_regular |= ind->ref_regular;
+ dir->ref_regular_nonweak |= ind->ref_regular_nonweak;
+ dir->needs_plt |= ind->needs_plt;
+ dir->pointer_equality_needed |= ind->pointer_equality_needed;
+ }
+ else
+ _bfd_elf_link_hash_copy_indirect (info, dir, ind);
+}
+
+/* Return TRUE if the TLS access code sequence support transition
+ from R_TYPE. */
+
+static bfd_boolean
+elf_i386_check_tls_transition (bfd *abfd, asection *sec,
+ bfd_byte *contents,
+ Elf_Internal_Shdr *symtab_hdr,
+ struct elf_link_hash_entry **sym_hashes,
+ unsigned int r_type,
+ const Elf_Internal_Rela *rel,
+ const Elf_Internal_Rela *relend)
+{
+ unsigned int val, type;
+ unsigned long r_symndx;
+ struct elf_link_hash_entry *h;
+ bfd_vma offset;
+
+ /* 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
+ {
+ /* FIXME: How to better handle error condition? */
+ if (!bfd_malloc_and_get_section (abfd, sec, &contents))
+ return FALSE;
+
+ /* Cache the section contents for elf_link_input_bfd. */
+ elf_section_data (sec)->this_hdr.contents = contents;
+ }
+ }
+
+ offset = rel->r_offset;
+ switch (r_type)
+ {
+ case R_386_TLS_GD:
+ case R_386_TLS_LDM:
+ if (offset < 2 || (rel + 1) >= relend)
+ return FALSE;
+
+ type = bfd_get_8 (abfd, contents + offset - 2);
+ if (r_type == R_386_TLS_GD)
+ {
+ /* Check transition from GD access model. Only
+ leal foo@tlsgd(,%reg,1), %eax; call ___tls_get_addr
+ leal foo@tlsgd(%reg), %eax; call ___tls_get_addr; nop
+ can transit to different access model. */
+ if ((offset + 10) > sec->size ||
+ (type != 0x8d && type != 0x04))
+ return FALSE;
+
+ val = bfd_get_8 (abfd, contents + offset - 1);
+ if (type == 0x04)
+ {
+ /* leal foo@tlsgd(,%reg,1), %eax; call ___tls_get_addr */
+ if (offset < 3)
+ return FALSE;
+
+ if (bfd_get_8 (abfd, contents + offset - 3) != 0x8d)
+ return FALSE;
+
+ if ((val & 0xc7) != 0x05 || val == (4 << 3))
+ return FALSE;
+ }
+ else
+ {
+ /* leal foo@tlsgd(%reg), %eax; call ___tls_get_addr; nop */
+ if ((val & 0xf8) != 0x80 || (val & 7) == 4)
+ return FALSE;
+
+ if (bfd_get_8 (abfd, contents + offset + 9) != 0x90)
+ return FALSE;
+ }
+ }
+ else
+ {
+ /* Check transition from LD access model. Only
+ leal foo@tlsgd(%reg), %eax; call ___tls_get_addr
+ can transit to different access model. */
+ if (type != 0x8d || (offset + 9) > sec->size)
+ return FALSE;
+
+ val = bfd_get_8 (abfd, contents + offset - 1);
+ if ((val & 0xf8) != 0x80 || (val & 7) == 4)
+ return FALSE;
+ }
+
+ if (bfd_get_8 (abfd, contents + offset + 4) != 0xe8)
+ return FALSE;
+
+ r_symndx = ELF32_R_SYM (rel[1].r_info);
+ if (r_symndx < symtab_hdr->sh_info)
+ return FALSE;
+
+ h = sym_hashes[r_symndx - symtab_hdr->sh_info];
+ /* Use strncmp to check ___tls_get_addr since ___tls_get_addr
+ may be versioned. */
+ return (h != NULL
+ && h->root.root.string != NULL
+ && (ELF32_R_TYPE (rel[1].r_info) == R_386_PC32
+ || ELF32_R_TYPE (rel[1].r_info) == R_386_PLT32)
+ && (strncmp (h->root.root.string, "___tls_get_addr",
+ 15) == 0));
+
+ case R_386_TLS_IE:
+ /* Check transition from IE access model:
+ movl foo@indntpoff(%rip), %eax
+ movl foo@indntpoff(%rip), %reg
+ addl foo@indntpoff(%rip), %reg
+ */
+
+ if (offset < 1 || (offset + 4) > sec->size)
+ return FALSE;
+
+ /* Check "movl foo@tpoff(%rip), %eax" first. */
+ val = bfd_get_8 (abfd, contents + offset - 1);
+ if (val == 0xa1)
+ return TRUE;
+
+ if (offset < 2)
+ return FALSE;
+
+ /* Check movl|addl foo@tpoff(%rip), %reg. */
+ type = bfd_get_8 (abfd, contents + offset - 2);
+ return ((type == 0x8b || type == 0x03)
+ && (val & 0xc7) == 0x05);
+
+ case R_386_TLS_GOTIE:
+ case R_386_TLS_IE_32:
+ /* Check transition from {IE_32,GOTIE} access model:
+ subl foo@{tpoff,gontoff}(%reg1), %reg2
+ movl foo@{tpoff,gontoff}(%reg1), %reg2
+ addl foo@{tpoff,gontoff}(%reg1), %reg2
+ */
+
+ if (offset < 2 || (offset + 4) > sec->size)
+ return FALSE;
+
+ val = bfd_get_8 (abfd, contents + offset - 1);
+ if ((val & 0xc0) != 0x80 || (val & 7) == 4)
+ return FALSE;
+
+ type = bfd_get_8 (abfd, contents + offset - 2);
+ return type == 0x8b || type == 0x2b || type == 0x03;
+
+ case R_386_TLS_GOTDESC:
+ /* Check transition from GDesc access model:
+ leal x@tlsdesc(%ebx), %eax
+
+ Make sure it's a leal adding ebx to a 32-bit offset
+ into any register, although it's probably almost always
+ going to be eax. */
+
+ if (offset < 2 || (offset + 4) > sec->size)
+ return FALSE;
+
+ if (bfd_get_8 (abfd, contents + offset - 2) != 0x8d)
+ return FALSE;
+
+ val = bfd_get_8 (abfd, contents + offset - 1);
+ return (val & 0xc7) == 0x83;
+
+ case R_386_TLS_DESC_CALL:
+ /* Check transition from GDesc access model:
+ call *x@tlsdesc(%rax)
+ */
+ if (offset + 2 <= sec->size)
+ {
+ /* Make sure that it's a call *x@tlsdesc(%rax). */
+ static const unsigned char call[] = { 0xff, 0x10 };
+ return memcmp (contents + offset, call, 2) == 0;
+ }
+
+ return FALSE;
+
+ default:
+ abort ();
+ }
+}
+
+/* Return TRUE if the TLS access transition is OK or no transition
+ will be performed. Update R_TYPE if there is a transition. */
+
+static bfd_boolean
+elf_i386_tls_transition (struct bfd_link_info *info, bfd *abfd,
+ asection *sec, bfd_byte *contents,
+ Elf_Internal_Shdr *symtab_hdr,
+ struct elf_link_hash_entry **sym_hashes,
+ unsigned int *r_type, int tls_type,
+ const Elf_Internal_Rela *rel,
+ const Elf_Internal_Rela *relend,
+ struct elf_link_hash_entry *h,
+ unsigned long r_symndx)
+{
+ unsigned int from_type = *r_type;
+ unsigned int to_type = from_type;
+ bfd_boolean check = TRUE;
+
+ /* Skip TLS transition for functions. */
+ if (h != NULL
+ && (h->type == STT_FUNC
+ || h->type == STT_GNU_IFUNC))
+ return TRUE;
+
+ switch (from_type)
+ {
+ case R_386_TLS_GD:
+ case R_386_TLS_GOTDESC:
+ case R_386_TLS_DESC_CALL:
+ case R_386_TLS_IE_32:
+ case R_386_TLS_IE:
+ case R_386_TLS_GOTIE:
+ if (info->executable)
+ {
+ if (h == NULL)
+ to_type = R_386_TLS_LE_32;
+ else if (from_type != R_386_TLS_IE
+ && from_type != R_386_TLS_GOTIE)
+ to_type = R_386_TLS_IE_32;
+ }
+
+ /* When we are called from elf_i386_relocate_section, CONTENTS
+ isn't NULL and there may be additional transitions based on
+ TLS_TYPE. */
+ if (contents != NULL)
+ {
+ unsigned int new_to_type = to_type;
+
+ if (info->executable
+ && h != NULL
+ && h->dynindx == -1
+ && (tls_type & GOT_TLS_IE))
+ new_to_type = R_386_TLS_LE_32;
+
+ if (to_type == R_386_TLS_GD
+ || to_type == R_386_TLS_GOTDESC
+ || to_type == R_386_TLS_DESC_CALL)
+ {
+ if (tls_type == GOT_TLS_IE_POS)
+ new_to_type = R_386_TLS_GOTIE;
+ else if (tls_type & GOT_TLS_IE)
+ new_to_type = R_386_TLS_IE_32;
+ }
+
+ /* We checked the transition before when we were called from
+ elf_i386_check_relocs. We only want to check the new
+ transition which hasn't been checked before. */
+ check = new_to_type != to_type && from_type == to_type;
+ to_type = new_to_type;
+ }
+
+ break;
+
+ case R_386_TLS_LDM:
+ if (info->executable)
+ to_type = R_386_TLS_LE_32;
+ break;
+
+ default:
+ return TRUE;
+ }
+
+ /* Return TRUE if there is no transition. */
+ if (from_type == to_type)
+ return TRUE;
+
+ /* Check if the transition can be performed. */
+ if (check
+ && ! elf_i386_check_tls_transition (abfd, sec, contents,
+ symtab_hdr, sym_hashes,
+ from_type, rel, relend))
+ {
+ reloc_howto_type *from, *to;
+ const char *name;
+
+ from = elf_i386_rtype_to_howto (abfd, from_type);
+ to = elf_i386_rtype_to_howto (abfd, to_type);
+
+ if (h)
+ name = h->root.root.string;
+ else
+ {
+ struct elf_i386_link_hash_table *htab;
+
+ htab = elf_i386_hash_table (info);
+ if (htab == NULL)
+ name = "*unknown*";
+ else
+ {
+ Elf_Internal_Sym *isym;
+
+ isym = bfd_sym_from_r_symndx (&htab->sym_cache,
+ abfd, r_symndx);
+ name = bfd_elf_sym_name (abfd, symtab_hdr, isym, NULL);
+ }
+ }
+
+ (*_bfd_error_handler)
+ (_("%B: TLS transition from %s to %s against `%s' at 0x%lx "
+ "in section `%A' failed"),
+ abfd, sec, from->name, to->name, name,
+ (unsigned long) rel->r_offset);
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+
+ *r_type = to_type;
+ return TRUE;
+}
+
+/* Look through the relocs for a section during the first phase, and
+ calculate needed space in the global offset table, procedure linkage
+ table, and dynamic reloc sections. */
+
+static bfd_boolean
+elf_i386_check_relocs (bfd *abfd,
+ struct bfd_link_info *info,
+ asection *sec,
+ const Elf_Internal_Rela *relocs)
+{
+ struct elf_i386_link_hash_table *htab;
+ 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;
+
+ if (info->relocatable)
+ return TRUE;
+
+ BFD_ASSERT (is_i386_elf (abfd));
+
+ htab = elf_i386_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ symtab_hdr = &elf_symtab_hdr (abfd);
+ sym_hashes = elf_sym_hashes (abfd);
+
+ sreloc = NULL;
+
+ rel_end = relocs + sec->reloc_count;
+ for (rel = relocs; rel < rel_end; rel++)
+ {
+ unsigned int r_type;
+ unsigned long r_symndx;
+ struct elf_link_hash_entry *h;
+ Elf_Internal_Sym *isym;
+ const char *name;
+ bfd_boolean size_reloc;
+
+ r_symndx = ELF32_R_SYM (rel->r_info);
+ r_type = ELF32_R_TYPE (rel->r_info);
+
+ if (r_symndx >= NUM_SHDR_ENTRIES (symtab_hdr))
+ {
+ (*_bfd_error_handler) (_("%B: bad symbol index: %d"),
+ abfd,
+ r_symndx);
+ return FALSE;
+ }
+
+ if (r_symndx < symtab_hdr->sh_info)
+ {
+ /* A local symbol. */
+ isym = bfd_sym_from_r_symndx (&htab->sym_cache,
+ abfd, r_symndx);
+ if (isym == NULL)
+ return FALSE;
+
+ /* Check relocation against local STT_GNU_IFUNC symbol. */
+ if (ELF32_ST_TYPE (isym->st_info) == STT_GNU_IFUNC)
+ {
+ h = elf_i386_get_local_sym_hash (htab, abfd, rel, TRUE);
+ if (h == NULL)
+ return FALSE;
+
+ /* Fake a STT_GNU_IFUNC symbol. */
+ h->type = STT_GNU_IFUNC;
+ h->def_regular = 1;
+ h->ref_regular = 1;
+ h->forced_local = 1;
+ h->root.type = bfd_link_hash_defined;
+ }
+ else
+ h = NULL;
+ }
+ else
+ {
+ isym = NULL;
+ 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 != NULL)
+ {
+ /* Create the ifunc sections for static executables. If we
+ never see an indirect function symbol nor we are building
+ a static executable, those sections will be empty and
+ won't appear in output. */
+ switch (r_type)
+ {
+ default:
+ break;
+
+ case R_386_32:
+ case R_386_PC32:
+ case R_386_PLT32:
+ case R_386_GOT32:
+ case R_386_GOTOFF:
+ if (htab->elf.dynobj == NULL)
+ htab->elf.dynobj = abfd;
+ if (!_bfd_elf_create_ifunc_sections (htab->elf.dynobj, info))
+ return FALSE;
+ break;
+ }
+
+ /* It is referenced by a non-shared object. */
+ h->ref_regular = 1;
+ h->root.non_ir_ref = 1;
+ }
+
+ if (! elf_i386_tls_transition (info, abfd, sec, NULL,
+ symtab_hdr, sym_hashes,
+ &r_type, GOT_UNKNOWN,
+ rel, rel_end, h, r_symndx))
+ return FALSE;
+
+ switch (r_type)
+ {
+ case R_386_TLS_LDM:
+ htab->tls_ldm_got.refcount += 1;
+ goto create_got;
+
+ 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->needs_plt = 1;
+ h->plt.refcount += 1;
+ break;
+
+ case R_386_SIZE32:
+ size_reloc = TRUE;
+ goto do_size;
+
+ case R_386_TLS_IE_32:
+ case R_386_TLS_IE:
+ case R_386_TLS_GOTIE:
+ if (!info->executable)
+ info->flags |= DF_STATIC_TLS;
+ /* Fall through */
+
+ case R_386_GOT32:
+ case R_386_TLS_GD:
+ case R_386_TLS_GOTDESC:
+ case R_386_TLS_DESC_CALL:
+ /* This symbol requires a global offset table entry. */
+ {
+ int tls_type, old_tls_type;
+
+ switch (r_type)
+ {
+ default:
+ case R_386_GOT32: tls_type = GOT_NORMAL; break;
+ case R_386_TLS_GD: tls_type = GOT_TLS_GD; break;
+ case R_386_TLS_GOTDESC:
+ case R_386_TLS_DESC_CALL:
+ tls_type = GOT_TLS_GDESC; break;
+ case R_386_TLS_IE_32:
+ if (ELF32_R_TYPE (rel->r_info) == r_type)
+ tls_type = GOT_TLS_IE_NEG;
+ else
+ /* If this is a GD->IE transition, we may use either of
+ R_386_TLS_TPOFF and R_386_TLS_TPOFF32. */
+ tls_type = GOT_TLS_IE;
+ break;
+ case R_386_TLS_IE:
+ case R_386_TLS_GOTIE:
+ tls_type = GOT_TLS_IE_POS; break;
+ }
+
+ if (h != NULL)
+ {
+ h->got.refcount += 1;
+ old_tls_type = elf_i386_hash_entry(h)->tls_type;
+ }
+ else
+ {
+ bfd_signed_vma *local_got_refcounts;
+
+ /* This is a global offset table entry for a local symbol. */
+ local_got_refcounts = elf_local_got_refcounts (abfd);
+ if (local_got_refcounts == NULL)
+ {
+ bfd_size_type size;
+
+ size = symtab_hdr->sh_info;
+ size *= (sizeof (bfd_signed_vma)
+ + sizeof (bfd_vma) + sizeof(char));
+ local_got_refcounts = (bfd_signed_vma *)
+ bfd_zalloc (abfd, size);
+ if (local_got_refcounts == NULL)
+ return FALSE;
+ elf_local_got_refcounts (abfd) = local_got_refcounts;
+ elf_i386_local_tlsdesc_gotent (abfd)
+ = (bfd_vma *) (local_got_refcounts + symtab_hdr->sh_info);
+ elf_i386_local_got_tls_type (abfd)
+ = (char *) (local_got_refcounts + 2 * symtab_hdr->sh_info);
+ }
+ local_got_refcounts[r_symndx] += 1;
+ old_tls_type = elf_i386_local_got_tls_type (abfd) [r_symndx];
+ }
+
+ if ((old_tls_type & GOT_TLS_IE) && (tls_type & GOT_TLS_IE))
+ tls_type |= old_tls_type;
+ /* If a TLS symbol is accessed using IE at least once,
+ there is no point to use dynamic model for it. */
+ else if (old_tls_type != tls_type && old_tls_type != GOT_UNKNOWN
+ && (! GOT_TLS_GD_ANY_P (old_tls_type)
+ || (tls_type & GOT_TLS_IE) == 0))
+ {
+ if ((old_tls_type & GOT_TLS_IE) && GOT_TLS_GD_ANY_P (tls_type))
+ tls_type = old_tls_type;
+ else if (GOT_TLS_GD_ANY_P (old_tls_type)
+ && GOT_TLS_GD_ANY_P (tls_type))
+ tls_type |= old_tls_type;
+ else
+ {
+ if (h)
+ name = h->root.root.string;
+ else
+ name = bfd_elf_sym_name (abfd, symtab_hdr, isym,
+ NULL);
+ (*_bfd_error_handler)
+ (_("%B: `%s' accessed both as normal and "
+ "thread local symbol"),
+ abfd, name);
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+ }
+
+ if (old_tls_type != tls_type)
+ {
+ if (h != NULL)
+ elf_i386_hash_entry (h)->tls_type = tls_type;
+ else
+ elf_i386_local_got_tls_type (abfd) [r_symndx] = tls_type;
+ }
+ }
+ /* Fall through */
+
+ case R_386_GOTOFF:
+ case R_386_GOTPC:
+ create_got:
+ if (htab->elf.sgot == NULL)
+ {
+ if (htab->elf.dynobj == NULL)
+ htab->elf.dynobj = abfd;
+ if (!_bfd_elf_create_got_section (htab->elf.dynobj, info))
+ return FALSE;
+ }
+ if (r_type != R_386_TLS_IE)
+ break;
+ /* Fall through */
+
+ case R_386_TLS_LE_32:
+ case R_386_TLS_LE:
+ if (info->executable)
+ break;
+ info->flags |= DF_STATIC_TLS;
+ /* Fall through */
+
+ case R_386_32:
+ case R_386_PC32:
+ if (h != NULL && info->executable)
+ {
+ /* If this reloc is in a read-only section, we might
+ need a copy reloc. We can't check reliably at this
+ stage whether the section is read-only, as input
+ sections have not yet been mapped to output sections.
+ Tentatively set the flag for now, and correct in
+ adjust_dynamic_symbol. */
+ h->non_got_ref = 1;
+
+ /* We may need a .plt entry if the function this reloc
+ refers to is in a shared lib. */
+ h->plt.refcount += 1;
+ if (r_type != R_386_PC32)
+ h->pointer_equality_needed = 1;
+ }
+
+ size_reloc = FALSE;
+do_size:
+ /* 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). In case of a weak definition,
+ DEF_REGULAR may be cleared later by a strong definition in
+ a shared library. We account for that possibility below by
+ storing information in the relocs_copied field of the hash
+ table entry. A similar situation occurs when creating
+ shared libraries and symbol visibility changes render the
+ symbol local.
+
+ If on the other hand, we are creating an executable, we
+ may need to keep relocations for symbols satisfied by a
+ dynamic library if we manage to avoid copy relocs for the
+ symbol. */
+ if ((info->shared
+ && (sec->flags & SEC_ALLOC) != 0
+ && (r_type != R_386_PC32
+ || (h != NULL
+ && (! SYMBOLIC_BIND (info, h)
+ || h->root.type == bfd_link_hash_defweak
+ || !h->def_regular))))
+ || (ELIMINATE_COPY_RELOCS
+ && !info->shared
+ && (sec->flags & SEC_ALLOC) != 0
+ && h != NULL
+ && (h->root.type == bfd_link_hash_defweak
+ || !h->def_regular)))
+ {
+ struct elf_dyn_relocs *p;
+ struct elf_dyn_relocs **head;
+
+ /* We must copy these reloc types into the output file.
+ Create a reloc section in dynobj and make room for
+ this reloc. */
+ if (sreloc == NULL)
+ {
+ if (htab->elf.dynobj == NULL)
+ htab->elf.dynobj = abfd;
+
+ sreloc = _bfd_elf_make_dynamic_reloc_section
+ (sec, htab->elf.dynobj, 2, abfd, /*rela?*/ FALSE);
+
+ if (sreloc == NULL)
+ return FALSE;
+ }
+
+ /* If this is a global symbol, we count the number of
+ relocations we need for this symbol. */
+ if (h != NULL)
+ {
+ head = &((struct elf_i386_link_hash_entry *) h)->dyn_relocs;
+ }
+ else
+ {
+ /* Track dynamic relocs needed for local syms too.
+ We really need local syms available to do this
+ easily. Oh well. */
+ void **vpp;
+ asection *s;
+
+ isym = bfd_sym_from_r_symndx (&htab->sym_cache,
+ abfd, r_symndx);
+ if (isym == NULL)
+ return FALSE;
+
+ s = bfd_section_from_elf_index (abfd, isym->st_shndx);
+ if (s == NULL)
+ s = sec;
+
+ vpp = &elf_section_data (s)->local_dynrel;
+ head = (struct elf_dyn_relocs **)vpp;
+ }
+
+ p = *head;
+ if (p == NULL || p->sec != sec)
+ {
+ bfd_size_type amt = sizeof *p;
+ p = (struct elf_dyn_relocs *) bfd_alloc (htab->elf.dynobj,
+ amt);
+ if (p == NULL)
+ return FALSE;
+ p->next = *head;
+ *head = p;
+ p->sec = sec;
+ p->count = 0;
+ p->pc_count = 0;
+ }
+
+ p->count += 1;
+ /* Count size relocation as PC-relative relocation. */
+ if (r_type == R_386_PC32 || size_reloc)
+ p->pc_count += 1;
+ }
+ break;
+
+ /* This relocation describes the C++ object vtable hierarchy.
+ Reconstruct it for later use during GC. */
+ case R_386_GNU_VTINHERIT:
+ if (!bfd_elf_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:
+ BFD_ASSERT (h != NULL);
+ if (h != NULL
+ && !bfd_elf_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 (asection *sec,
+ 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:
+ return NULL;
+ }
+
+ return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
+}
+
+/* Update the got entry reference counts for the section being removed. */
+
+static bfd_boolean
+elf_i386_gc_sweep_hook (bfd *abfd,
+ struct bfd_link_info *info,
+ asection *sec,
+ const Elf_Internal_Rela *relocs)
+{
+ struct elf_i386_link_hash_table *htab;
+ Elf_Internal_Shdr *symtab_hdr;
+ struct elf_link_hash_entry **sym_hashes;
+ bfd_signed_vma *local_got_refcounts;
+ const Elf_Internal_Rela *rel, *relend;
+
+ if (info->relocatable)
+ return TRUE;
+
+ htab = elf_i386_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ elf_section_data (sec)->local_dynrel = NULL;
+
+ symtab_hdr = &elf_symtab_hdr (abfd);
+ 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++)
+ {
+ unsigned long r_symndx;
+ unsigned int r_type;
+ struct elf_link_hash_entry *h = NULL;
+
+ r_symndx = ELF32_R_SYM (rel->r_info);
+ if (r_symndx >= symtab_hdr->sh_info)
+ {
+ 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;
+ }
+ else
+ {
+ /* A local symbol. */
+ Elf_Internal_Sym *isym;
+
+ isym = bfd_sym_from_r_symndx (&htab->sym_cache,
+ abfd, r_symndx);
+
+ /* Check relocation against local STT_GNU_IFUNC symbol. */
+ if (isym != NULL
+ && ELF32_ST_TYPE (isym->st_info) == STT_GNU_IFUNC)
+ {
+ h = elf_i386_get_local_sym_hash (htab, abfd, rel, FALSE);
+ if (h == NULL)
+ abort ();
+ }
+ }
+
+ if (h)
+ {
+ struct elf_i386_link_hash_entry *eh;
+ struct elf_dyn_relocs **pp;
+ struct elf_dyn_relocs *p;
+
+ eh = (struct elf_i386_link_hash_entry *) h;
+ for (pp = &eh->dyn_relocs; (p = *pp) != NULL; pp = &p->next)
+ if (p->sec == sec)
+ {
+ /* Everything must go for SEC. */
+ *pp = p->next;
+ break;
+ }
+ }
+
+ r_type = ELF32_R_TYPE (rel->r_info);
+ if (! elf_i386_tls_transition (info, abfd, sec, NULL,
+ symtab_hdr, sym_hashes,
+ &r_type, GOT_UNKNOWN,
+ rel, relend, h, r_symndx))
+ return FALSE;
+
+ switch (r_type)
+ {
+ case R_386_TLS_LDM:
+ if (htab->tls_ldm_got.refcount > 0)
+ htab->tls_ldm_got.refcount -= 1;
+ break;
+
+ case R_386_TLS_GD:
+ case R_386_TLS_GOTDESC:
+ case R_386_TLS_DESC_CALL:
+ case R_386_TLS_IE_32:
+ case R_386_TLS_IE:
+ case R_386_TLS_GOTIE:
+ case R_386_GOT32:
+ if (h != NULL)
+ {
+ if (h->got.refcount > 0)
+ h->got.refcount -= 1;
+ if (h->type == STT_GNU_IFUNC)
+ {
+ if (h->plt.refcount > 0)
+ h->plt.refcount -= 1;
+ }
+ }
+ else if (local_got_refcounts != NULL)
+ {
+ if (local_got_refcounts[r_symndx] > 0)
+ local_got_refcounts[r_symndx] -= 1;
+ }
+ break;
+
+ case R_386_32:
+ case R_386_PC32:
+ case R_386_SIZE32:
+ if (info->shared
+ && (h == NULL || h->type != STT_GNU_IFUNC))
+ break;
+ /* Fall through */
+
+ case R_386_PLT32:
+ if (h != NULL)
+ {
+ if (h->plt.refcount > 0)
+ h->plt.refcount -= 1;
+ }
+ break;
+
+ case R_386_GOTOFF:
+ if (h != NULL && h->type == STT_GNU_IFUNC)
+ {
+ if (h->got.refcount > 0)
+ h->got.refcount -= 1;
+ if (h->plt.refcount > 0)
+ h->plt.refcount -= 1;
+ }
+ 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 bfd_boolean
+elf_i386_adjust_dynamic_symbol (struct bfd_link_info *info,
+ struct elf_link_hash_entry *h)
+{
+ struct elf_i386_link_hash_table *htab;
+ asection *s;
+ struct elf_i386_link_hash_entry *eh;
+ struct elf_dyn_relocs *p;
+
+ /* STT_GNU_IFUNC symbol must go through PLT. */
+ if (h->type == STT_GNU_IFUNC)
+ {
+ /* All local STT_GNU_IFUNC references must be treate as local
+ calls via local PLT. */
+ if (h->ref_regular
+ && SYMBOL_CALLS_LOCAL (info, h))
+ {
+ bfd_size_type pc_count = 0, count = 0;
+ struct elf_dyn_relocs **pp;
+
+ eh = (struct elf_i386_link_hash_entry *) h;
+ for (pp = &eh->dyn_relocs; (p = *pp) != NULL; )
+ {
+ pc_count += p->pc_count;
+ p->count -= p->pc_count;
+ p->pc_count = 0;
+ count += p->count;
+ if (p->count == 0)
+ *pp = p->next;
+ else
+ pp = &p->next;
+ }
+
+ if (pc_count || count)
+ {
+ h->needs_plt = 1;
+ h->non_got_ref = 1;
+ if (h->plt.refcount <= 0)
+ h->plt.refcount = 1;
+ else
+ h->plt.refcount += 1;
+ }
+ }
+
+ if (h->plt.refcount <= 0)
+ {
+ h->plt.offset = (bfd_vma) -1;
+ h->needs_plt = 0;
+ }
+ return TRUE;
+ }
+
+ /* 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->needs_plt)
+ {
+ if (h->plt.refcount <= 0
+ || SYMBOL_CALLS_LOCAL (info, h)
+ || (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
+ && h->root.type == bfd_link_hash_undefweak))
+ {
+ /* 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, or if all references were garbage collected. In
+ such a case, we don't actually need to build a procedure
+ linkage table, and we can just do a PC32 reloc instead. */
+ h->plt.offset = (bfd_vma) -1;
+ h->needs_plt = 0;
+ }
+
+ return TRUE;
+ }
+ else
+ /* It's possible that we incorrectly decided a .plt reloc was
+ needed for an R_386_PC32 reloc to a non-function sym in
+ check_relocs. We can't decide accurately between function and
+ non-function syms in check-relocs; Objects loaded later in
+ the link may change h->type. So fix it now. */
+ 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->u.weakdef != NULL)
+ {
+ BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
+ || h->u.weakdef->root.type == bfd_link_hash_defweak);
+ h->root.u.def.section = h->u.weakdef->root.u.def.section;
+ h->root.u.def.value = h->u.weakdef->root.u.def.value;
+ if (ELIMINATE_COPY_RELOCS || info->nocopyreloc)
+ h->non_got_ref = h->u.weakdef->non_got_ref;
+ 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;
+
+ /* If there are no references to this symbol that do not use the
+ GOT, we don't need to generate a copy reloc. */
+ if (!h->non_got_ref)
+ return TRUE;
+
+ /* If -z nocopyreloc was given, we won't generate them either. */
+ if (info->nocopyreloc)
+ {
+ h->non_got_ref = 0;
+ return TRUE;
+ }
+
+ htab = elf_i386_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ /* If there aren't any dynamic relocs in read-only sections, then
+ we can keep the dynamic relocs and avoid the copy reloc. This
+ doesn't work on VxWorks, where we can not have dynamic relocations
+ (other than copy and jump slot relocations) in an executable. */
+ if (ELIMINATE_COPY_RELOCS
+ && !get_elf_i386_backend_data (info->output_bfd)->is_vxworks)
+ {
+ eh = (struct elf_i386_link_hash_entry *) h;
+ for (p = eh->dyn_relocs; p != NULL; p = p->next)
+ {
+ s = p->sec->output_section;
+ if (s != NULL && (s->flags & SEC_READONLY) != 0)
+ break;
+ }
+
+ if (p == NULL)
+ {
+ h->non_got_ref = 0;
+ 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. */
+
+ /* 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. */
+ if ((h->root.u.def.section->flags & SEC_ALLOC) != 0 && h->size != 0)
+ {
+ htab->srelbss->size += sizeof (Elf32_External_Rel);
+ h->needs_copy = 1;
+ }
+
+ s = htab->sdynbss;
+
+ return _bfd_elf_adjust_dynamic_copy (h, s);
+}
+
+/* Allocate space in .plt, .got and associated reloc sections for
+ dynamic relocs. */
+
+static bfd_boolean
+elf_i386_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
+{
+ struct bfd_link_info *info;
+ struct elf_i386_link_hash_table *htab;
+ struct elf_i386_link_hash_entry *eh;
+ struct elf_dyn_relocs *p;
+ unsigned plt_entry_size;
+
+ if (h->root.type == bfd_link_hash_indirect)
+ return TRUE;
+
+ eh = (struct elf_i386_link_hash_entry *) h;
+
+ info = (struct bfd_link_info *) inf;
+ htab = elf_i386_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ plt_entry_size = GET_PLT_ENTRY_SIZE (info->output_bfd);
+
+ /* Since STT_GNU_IFUNC symbol must go through PLT, we handle it
+ here if it is defined and referenced in a non-shared object. */
+ if (h->type == STT_GNU_IFUNC
+ && h->def_regular)
+ return _bfd_elf_allocate_ifunc_dyn_relocs (info, h, &eh->dyn_relocs,
+ plt_entry_size,
+ plt_entry_size, 4);
+ else if (htab->elf.dynamic_sections_created
+ && h->plt.refcount > 0)
+ {
+ /* Make sure this symbol is output as a dynamic symbol.
+ Undefined weak syms won't yet be marked as dynamic. */
+ if (h->dynindx == -1
+ && !h->forced_local)
+ {
+ if (! bfd_elf_link_record_dynamic_symbol (info, h))
+ return FALSE;
+ }
+
+ if (info->shared
+ || WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, 0, h))
+ {
+ asection *s = htab->elf.splt;
+
+ /* If this is the first .plt entry, make room for the special
+ first entry. */
+ if (s->size == 0)
+ s->size = plt_entry_size;
+
+ h->plt.offset = s->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->def_regular)
+ {
+ h->root.u.def.section = s;
+ h->root.u.def.value = h->plt.offset;
+ }
+
+ /* Make room for this entry. */
+ s->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. */
+ htab->elf.sgotplt->size += 4;
+
+ /* We also need to make an entry in the .rel.plt section. */
+ htab->elf.srelplt->size += sizeof (Elf32_External_Rel);
+ htab->elf.srelplt->reloc_count++;
+
+ if (get_elf_i386_backend_data (info->output_bfd)->is_vxworks
+ && !info->shared)
+ {
+ /* VxWorks has a second set of relocations for each PLT entry
+ in executables. They go in a separate relocation section,
+ which is processed by the kernel loader. */
+
+ /* There are two relocations for the initial PLT entry: an
+ R_386_32 relocation for _GLOBAL_OFFSET_TABLE_ + 4 and an
+ R_386_32 relocation for _GLOBAL_OFFSET_TABLE_ + 8. */
+
+ if (h->plt.offset == plt_entry_size)
+ htab->srelplt2->size += (sizeof (Elf32_External_Rel) * 2);
+
+ /* There are two extra relocations for each subsequent PLT entry:
+ an R_386_32 relocation for the GOT entry, and an R_386_32
+ relocation for the PLT entry. */
+
+ htab->srelplt2->size += (sizeof (Elf32_External_Rel) * 2);
+ }
+ }
+ else
+ {
+ h->plt.offset = (bfd_vma) -1;
+ h->needs_plt = 0;
+ }
+ }
+ else
+ {
+ h->plt.offset = (bfd_vma) -1;
+ h->needs_plt = 0;
+ }
+
+ eh->tlsdesc_got = (bfd_vma) -1;
+
+ /* If R_386_TLS_{IE_32,IE,GOTIE} symbol is now local to the binary,
+ make it a R_386_TLS_LE_32 requiring no TLS entry. */
+ if (h->got.refcount > 0
+ && info->executable
+ && h->dynindx == -1
+ && (elf_i386_hash_entry(h)->tls_type & GOT_TLS_IE))
+ h->got.offset = (bfd_vma) -1;
+ else if (h->got.refcount > 0)
+ {
+ asection *s;
+ bfd_boolean dyn;
+ int tls_type = elf_i386_hash_entry(h)->tls_type;
+
+ /* Make sure this symbol is output as a dynamic symbol.
+ Undefined weak syms won't yet be marked as dynamic. */
+ if (h->dynindx == -1
+ && !h->forced_local)
+ {
+ if (! bfd_elf_link_record_dynamic_symbol (info, h))
+ return FALSE;
+ }
+
+ s = htab->elf.sgot;
+ if (GOT_TLS_GDESC_P (tls_type))
+ {
+ eh->tlsdesc_got = htab->elf.sgotplt->size
+ - elf_i386_compute_jump_table_size (htab);
+ htab->elf.sgotplt->size += 8;
+ h->got.offset = (bfd_vma) -2;
+ }
+ if (! GOT_TLS_GDESC_P (tls_type)
+ || GOT_TLS_GD_P (tls_type))
+ {
+ h->got.offset = s->size;
+ s->size += 4;
+ /* R_386_TLS_GD needs 2 consecutive GOT slots. */
+ if (GOT_TLS_GD_P (tls_type) || tls_type == GOT_TLS_IE_BOTH)
+ s->size += 4;
+ }
+ dyn = htab->elf.dynamic_sections_created;
+ /* R_386_TLS_IE_32 needs one dynamic relocation,
+ R_386_TLS_IE resp. R_386_TLS_GOTIE needs one dynamic relocation,
+ (but if both R_386_TLS_IE_32 and R_386_TLS_IE is present, we
+ need two), R_386_TLS_GD needs one if local symbol and two if
+ global. */
+ if (tls_type == GOT_TLS_IE_BOTH)
+ htab->elf.srelgot->size += 2 * sizeof (Elf32_External_Rel);
+ else if ((GOT_TLS_GD_P (tls_type) && h->dynindx == -1)
+ || (tls_type & GOT_TLS_IE))
+ htab->elf.srelgot->size += sizeof (Elf32_External_Rel);
+ else if (GOT_TLS_GD_P (tls_type))
+ htab->elf.srelgot->size += 2 * sizeof (Elf32_External_Rel);
+ else if (! GOT_TLS_GDESC_P (tls_type)
+ && (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
+ || h->root.type != bfd_link_hash_undefweak)
+ && (info->shared
+ || WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, 0, h)))
+ htab->elf.srelgot->size += sizeof (Elf32_External_Rel);
+ if (GOT_TLS_GDESC_P (tls_type))
+ htab->elf.srelplt->size += sizeof (Elf32_External_Rel);
+ }
+ else
+ h->got.offset = (bfd_vma) -1;
+
+ if (eh->dyn_relocs == NULL)
+ return TRUE;
+
+ /* In the shared -Bsymbolic case, discard space allocated for
+ dynamic pc-relative relocs against symbols which turn out to be
+ defined in regular objects. For the normal shared case, discard
+ space for pc-relative relocs that have become local due to symbol
+ visibility changes. */
+
+ if (info->shared)
+ {
+ /* The only reloc that uses pc_count is R_386_PC32, which will
+ appear on a call or on something like ".long foo - .". We
+ want calls to protected symbols to resolve directly to the
+ function rather than going via the plt. If people want
+ function pointer comparisons to work as expected then they
+ should avoid writing assembly like ".long foo - .". */
+ if (SYMBOL_CALLS_LOCAL (info, h))
+ {
+ struct elf_dyn_relocs **pp;
+
+ for (pp = &eh->dyn_relocs; (p = *pp) != NULL; )
+ {
+ p->count -= p->pc_count;
+ p->pc_count = 0;
+ if (p->count == 0)
+ *pp = p->next;
+ else
+ pp = &p->next;
+ }
+ }
+
+ if (get_elf_i386_backend_data (info->output_bfd)->is_vxworks)
+ {
+ struct elf_dyn_relocs **pp;
+ for (pp = &eh->dyn_relocs; (p = *pp) != NULL; )
+ {
+ if (strcmp (p->sec->output_section->name, ".tls_vars") == 0)
+ *pp = p->next;
+ else
+ pp = &p->next;
+ }
+ }
+
+ /* Also discard relocs on undefined weak syms with non-default
+ visibility. */
+ if (eh->dyn_relocs != NULL
+ && h->root.type == bfd_link_hash_undefweak)
+ {
+ if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
+ eh->dyn_relocs = NULL;
+
+ /* Make sure undefined weak symbols are output as a dynamic
+ symbol in PIEs. */
+ else if (h->dynindx == -1
+ && !h->forced_local)
+ {
+ if (! bfd_elf_link_record_dynamic_symbol (info, h))
+ return FALSE;
+ }
+ }
+ }
+ else if (ELIMINATE_COPY_RELOCS)
+ {
+ /* For the non-shared case, discard space for relocs against
+ symbols which turn out to need copy relocs or are not
+ dynamic. */
+
+ if (!h->non_got_ref
+ && ((h->def_dynamic
+ && !h->def_regular)
+ || (htab->elf.dynamic_sections_created
+ && (h->root.type == bfd_link_hash_undefweak
+ || h->root.type == bfd_link_hash_undefined))))
+ {
+ /* Make sure this symbol is output as a dynamic symbol.
+ Undefined weak syms won't yet be marked as dynamic. */
+ if (h->dynindx == -1
+ && !h->forced_local)
+ {
+ if (! bfd_elf_link_record_dynamic_symbol (info, h))
+ return FALSE;
+ }
+
+ /* If that succeeded, we know we'll be keeping all the
+ relocs. */
+ if (h->dynindx != -1)
+ goto keep;
+ }
+
+ eh->dyn_relocs = NULL;
+
+ keep: ;
+ }
+
+ /* Finally, allocate space. */
+ for (p = eh->dyn_relocs; p != NULL; p = p->next)
+ {
+ asection *sreloc;
+
+ sreloc = elf_section_data (p->sec)->sreloc;
+
+ BFD_ASSERT (sreloc != NULL);
+ sreloc->size += p->count * sizeof (Elf32_External_Rel);
+ }
+
+ return TRUE;
+}
+
+/* Allocate space in .plt, .got and associated reloc sections for
+ local dynamic relocs. */
+
+static bfd_boolean
+elf_i386_allocate_local_dynrelocs (void **slot, void *inf)
+{
+ struct elf_link_hash_entry *h
+ = (struct elf_link_hash_entry *) *slot;
+
+ if (h->type != STT_GNU_IFUNC
+ || !h->def_regular
+ || !h->ref_regular
+ || !h->forced_local
+ || h->root.type != bfd_link_hash_defined)
+ abort ();
+
+ return elf_i386_allocate_dynrelocs (h, inf);
+}
+
+/* Find any dynamic relocs that apply to read-only sections. */
+
+static bfd_boolean
+elf_i386_readonly_dynrelocs (struct elf_link_hash_entry *h, void *inf)
+{
+ struct elf_i386_link_hash_entry *eh;
+ struct elf_dyn_relocs *p;
+
+ /* Skip local IFUNC symbols. */
+ if (h->forced_local && h->type == STT_GNU_IFUNC)
+ return TRUE;
+
+ eh = (struct elf_i386_link_hash_entry *) h;
+ for (p = eh->dyn_relocs; p != NULL; p = p->next)
+ {
+ asection *s = p->sec->output_section;
+
+ if (s != NULL && (s->flags & SEC_READONLY) != 0)
+ {
+ struct bfd_link_info *info = (struct bfd_link_info *) inf;
+
+ info->flags |= DF_TEXTREL;
+
+ if (info->warn_shared_textrel && info->shared)
+ info->callbacks->einfo (_("%P: %B: warning: relocation against `%s' in readonly section `%A'.\n"),
+ p->sec->owner, h->root.root.string,
+ p->sec);
+
+ /* Not an error, just cut short the traversal. */
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+/* Convert
+ mov foo@GOT(%reg), %reg
+ to
+ lea foo@GOTOFF(%reg), %reg
+ with the local symbol, foo. */
+
+static bfd_boolean
+elf_i386_convert_mov_to_lea (bfd *abfd, asection *sec,
+ struct bfd_link_info *link_info)
+{
+ Elf_Internal_Shdr *symtab_hdr;
+ Elf_Internal_Rela *internal_relocs;
+ Elf_Internal_Rela *irel, *irelend;
+ bfd_byte *contents;
+ struct elf_i386_link_hash_table *htab;
+ bfd_boolean changed_contents;
+ bfd_boolean changed_relocs;
+ bfd_signed_vma *local_got_refcounts;
+
+ /* Don't even try to convert non-ELF outputs. */
+ if (!is_elf_hash_table (link_info->hash))
+ return FALSE;
+
+ /* Nothing to do if there are no codes, no relocations or no output. */
+ if ((sec->flags & (SEC_CODE | SEC_RELOC)) != (SEC_CODE | SEC_RELOC)
+ || sec->reloc_count == 0
+ || bfd_is_abs_section (sec->output_section))
+ return TRUE;
+
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+
+ /* Load the relocations for this section. */
+ internal_relocs = (_bfd_elf_link_read_relocs
+ (abfd, sec, NULL, (Elf_Internal_Rela *) NULL,
+ link_info->keep_memory));
+ if (internal_relocs == NULL)
+ return FALSE;
+
+ htab = elf_i386_hash_table (link_info);
+ changed_contents = FALSE;
+ changed_relocs = FALSE;
+ local_got_refcounts = elf_local_got_refcounts (abfd);
+
+ /* Get the section contents. */
+ if (elf_section_data (sec)->this_hdr.contents != NULL)
+ contents = elf_section_data (sec)->this_hdr.contents;
+ else
+ {
+ if (!bfd_malloc_and_get_section (abfd, sec, &contents))
+ goto error_return;
+ }
+
+ irelend = internal_relocs + sec->reloc_count;
+ for (irel = internal_relocs; irel < irelend; irel++)
+ {
+ unsigned int r_type = ELF32_R_TYPE (irel->r_info);
+ unsigned int r_symndx = ELF32_R_SYM (irel->r_info);
+ unsigned int indx;
+ struct elf_link_hash_entry *h;
+
+ if (r_type != R_386_GOT32)
+ continue;
+
+ /* Get the symbol referred to by the reloc. */
+ if (r_symndx < symtab_hdr->sh_info)
+ {
+ Elf_Internal_Sym *isym;
+
+ isym = bfd_sym_from_r_symndx (&htab->sym_cache,
+ abfd, r_symndx);
+
+ /* STT_GNU_IFUNC must keep R_386_GOT32 relocation. */
+ if (ELF_ST_TYPE (isym->st_info) != STT_GNU_IFUNC
+ && bfd_get_8 (input_bfd,
+ contents + irel->r_offset - 2) == 0x8b)
+ {
+ bfd_put_8 (output_bfd, 0x8d,
+ contents + irel->r_offset - 2);
+ irel->r_info = ELF32_R_INFO (r_symndx, R_386_GOTOFF);
+ if (local_got_refcounts != NULL
+ && local_got_refcounts[r_symndx] > 0)
+ local_got_refcounts[r_symndx] -= 1;
+ changed_contents = TRUE;
+ changed_relocs = TRUE;
+ }
+ continue;
+ }
+
+ indx = r_symndx - symtab_hdr->sh_info;
+ h = elf_sym_hashes (abfd)[indx];
+ BFD_ASSERT (h != NULL);
+
+ 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;
+
+ /* STT_GNU_IFUNC must keep R_386_GOT32 relocation. We also avoid
+ optimizing _DYNAMIC since ld.so may use its link-time address. */
+ if (h->def_regular
+ && h->type != STT_GNU_IFUNC
+ && h != htab->elf.hdynamic
+ && SYMBOL_REFERENCES_LOCAL (link_info, h)
+ && bfd_get_8 (input_bfd,
+ contents + irel->r_offset - 2) == 0x8b)
+ {
+ bfd_put_8 (output_bfd, 0x8d,
+ contents + irel->r_offset - 2);
+ irel->r_info = ELF32_R_INFO (r_symndx, R_386_GOTOFF);
+ if (h->got.refcount > 0)
+ h->got.refcount -= 1;
+ changed_contents = TRUE;
+ changed_relocs = TRUE;
+ }
+ }
+
+ if (contents != NULL
+ && elf_section_data (sec)->this_hdr.contents != contents)
+ {
+ if (!changed_contents && !link_info->keep_memory)
+ free (contents);
+ else
+ {
+ /* Cache the section contents for elf_link_input_bfd. */
+ elf_section_data (sec)->this_hdr.contents = contents;
+ }
+ }
+
+ if (elf_section_data (sec)->relocs != internal_relocs)
+ {
+ if (!changed_relocs)
+ free (internal_relocs);
+ else
+ elf_section_data (sec)->relocs = internal_relocs;
+ }
+
+ return TRUE;
+
+ error_return:
+ if (contents != NULL
+ && elf_section_data (sec)->this_hdr.contents != contents)
+ free (contents);
+ if (internal_relocs != NULL
+ && elf_section_data (sec)->relocs != internal_relocs)
+ free (internal_relocs);
+ return FALSE;
+}
+
+/* Set the sizes of the dynamic sections. */
+
+static bfd_boolean
+elf_i386_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
+{
+ struct elf_i386_link_hash_table *htab;
+ bfd *dynobj;
+ asection *s;
+ bfd_boolean relocs;
+ bfd *ibfd;
+
+ htab = elf_i386_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+ dynobj = htab->elf.dynobj;
+ if (dynobj == NULL)
+ abort ();
+
+ if (htab->elf.dynamic_sections_created)
+ {
+ /* Set the contents of the .interp section to the interpreter. */
+ if (info->executable)
+ {
+ s = bfd_get_linker_section (dynobj, ".interp");
+ if (s == NULL)
+ abort ();
+ s->size = sizeof ELF_DYNAMIC_INTERPRETER;
+ s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
+ }
+ }
+
+ /* Set up .got offsets for local syms, and space for local dynamic
+ relocs. */
+ for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next)
+ {
+ bfd_signed_vma *local_got;
+ bfd_signed_vma *end_local_got;
+ char *local_tls_type;
+ bfd_vma *local_tlsdesc_gotent;
+ bfd_size_type locsymcount;
+ Elf_Internal_Shdr *symtab_hdr;
+ asection *srel;
+
+ if (! is_i386_elf (ibfd))
+ continue;
+
+ for (s = ibfd->sections; s != NULL; s = s->next)
+ {
+ struct elf_dyn_relocs *p;
+
+ if (!elf_i386_convert_mov_to_lea (ibfd, s, info))
+ return FALSE;
+
+ for (p = ((struct elf_dyn_relocs *)
+ elf_section_data (s)->local_dynrel);
+ p != NULL;
+ p = p->next)
+ {
+ if (!bfd_is_abs_section (p->sec)
+ && bfd_is_abs_section (p->sec->output_section))
+ {
+ /* Input section has been discarded, either because
+ it is a copy of a linkonce section or due to
+ linker script /DISCARD/, so we'll be discarding
+ the relocs too. */
+ }
+ else if (get_elf_i386_backend_data (output_bfd)->is_vxworks
+ && strcmp (p->sec->output_section->name,
+ ".tls_vars") == 0)
+ {
+ /* Relocations in vxworks .tls_vars sections are
+ handled specially by the loader. */
+ }
+ else if (p->count != 0)
+ {
+ srel = elf_section_data (p->sec)->sreloc;
+ srel->size += p->count * sizeof (Elf32_External_Rel);
+ if ((p->sec->output_section->flags & SEC_READONLY) != 0
+ && (info->flags & DF_TEXTREL) == 0)
+ {
+ info->flags |= DF_TEXTREL;
+ if (info->warn_shared_textrel && info->shared)
+ info->callbacks->einfo (_("%P: %B: warning: relocation in readonly section `%A'.\n"),
+ p->sec->owner, p->sec);
+ }
+ }
+ }
+ }
+
+ local_got = elf_local_got_refcounts (ibfd);
+ if (!local_got)
+ continue;
+
+ symtab_hdr = &elf_symtab_hdr (ibfd);
+ locsymcount = symtab_hdr->sh_info;
+ end_local_got = local_got + locsymcount;
+ local_tls_type = elf_i386_local_got_tls_type (ibfd);
+ local_tlsdesc_gotent = elf_i386_local_tlsdesc_gotent (ibfd);
+ s = htab->elf.sgot;
+ srel = htab->elf.srelgot;
+ for (; local_got < end_local_got;
+ ++local_got, ++local_tls_type, ++local_tlsdesc_gotent)
+ {
+ *local_tlsdesc_gotent = (bfd_vma) -1;
+ if (*local_got > 0)
+ {
+ if (GOT_TLS_GDESC_P (*local_tls_type))
+ {
+ *local_tlsdesc_gotent = htab->elf.sgotplt->size
+ - elf_i386_compute_jump_table_size (htab);
+ htab->elf.sgotplt->size += 8;
+ *local_got = (bfd_vma) -2;
+ }
+ if (! GOT_TLS_GDESC_P (*local_tls_type)
+ || GOT_TLS_GD_P (*local_tls_type))
+ {
+ *local_got = s->size;
+ s->size += 4;
+ if (GOT_TLS_GD_P (*local_tls_type)
+ || *local_tls_type == GOT_TLS_IE_BOTH)
+ s->size += 4;
+ }
+ if (info->shared
+ || GOT_TLS_GD_ANY_P (*local_tls_type)
+ || (*local_tls_type & GOT_TLS_IE))
+ {
+ if (*local_tls_type == GOT_TLS_IE_BOTH)
+ srel->size += 2 * sizeof (Elf32_External_Rel);
+ else if (GOT_TLS_GD_P (*local_tls_type)
+ || ! GOT_TLS_GDESC_P (*local_tls_type))
+ srel->size += sizeof (Elf32_External_Rel);
+ if (GOT_TLS_GDESC_P (*local_tls_type))
+ htab->elf.srelplt->size += sizeof (Elf32_External_Rel);
+ }
+ }
+ else
+ *local_got = (bfd_vma) -1;
+ }
+ }
+
+ if (htab->tls_ldm_got.refcount > 0)
+ {
+ /* Allocate 2 got entries and 1 dynamic reloc for R_386_TLS_LDM
+ relocs. */
+ htab->tls_ldm_got.offset = htab->elf.sgot->size;
+ htab->elf.sgot->size += 8;
+ htab->elf.srelgot->size += sizeof (Elf32_External_Rel);
+ }
+ else
+ htab->tls_ldm_got.offset = -1;
+
+ /* Allocate global sym .plt and .got entries, and space for global
+ sym dynamic relocs. */
+ elf_link_hash_traverse (&htab->elf, elf_i386_allocate_dynrelocs, info);
+
+ /* Allocate .plt and .got entries, and space for local symbols. */
+ htab_traverse (htab->loc_hash_table,
+ elf_i386_allocate_local_dynrelocs,
+ info);
+
+ /* For every jump slot reserved in the sgotplt, reloc_count is
+ incremented. However, when we reserve space for TLS descriptors,
+ it's not incremented, so in order to compute the space reserved
+ for them, it suffices to multiply the reloc count by the jump
+ slot size.
+
+ PR ld/13302: We start next_irelative_index at the end of .rela.plt
+ so that R_386_IRELATIVE entries come last. */
+ if (htab->elf.srelplt)
+ {
+ htab->next_tls_desc_index = htab->elf.srelplt->reloc_count;
+ htab->sgotplt_jump_table_size = htab->next_tls_desc_index * 4;
+ htab->next_irelative_index = htab->elf.srelplt->reloc_count - 1;
+ }
+ else if (htab->elf.irelplt)
+ htab->next_irelative_index = htab->elf.irelplt->reloc_count - 1;
+
+
+ if (htab->elf.sgotplt)
+ {
+ /* Don't allocate .got.plt section if there are no GOT nor PLT
+ entries and there is no reference to _GLOBAL_OFFSET_TABLE_. */
+ if ((htab->elf.hgot == NULL
+ || !htab->elf.hgot->ref_regular_nonweak)
+ && (htab->elf.sgotplt->size
+ == get_elf_backend_data (output_bfd)->got_header_size)
+ && (htab->elf.splt == NULL
+ || htab->elf.splt->size == 0)
+ && (htab->elf.sgot == NULL
+ || htab->elf.sgot->size == 0)
+ && (htab->elf.iplt == NULL
+ || htab->elf.iplt->size == 0)
+ && (htab->elf.igotplt == NULL
+ || htab->elf.igotplt->size == 0))
+ htab->elf.sgotplt->size = 0;
+ }
+
+
+ if (htab->plt_eh_frame != NULL
+ && htab->elf.splt != NULL
+ && htab->elf.splt->size != 0
+ && !bfd_is_abs_section (htab->elf.splt->output_section)
+ && _bfd_elf_eh_frame_present (info))
+ htab->plt_eh_frame->size = sizeof (elf_i386_eh_frame_plt);
+
+ /* We now have determined the sizes of the various dynamic sections.
+ Allocate memory for them. */
+ relocs = FALSE;
+ for (s = dynobj->sections; s != NULL; s = s->next)
+ {
+ bfd_boolean strip_section = TRUE;
+
+ if ((s->flags & SEC_LINKER_CREATED) == 0)
+ continue;
+
+ if (s == htab->elf.splt
+ || s == htab->elf.sgot)
+ {
+ /* Strip this section if we don't need it; see the
+ comment below. */
+ /* We'd like to strip these sections if they aren't needed, but if
+ we've exported dynamic symbols from them we must leave them.
+ It's too late to tell BFD to get rid of the symbols. */
+
+ if (htab->elf.hplt != NULL)
+ strip_section = FALSE;
+ }
+ else if (s == htab->elf.sgotplt
+ || s == htab->elf.iplt
+ || s == htab->elf.igotplt
+ || s == htab->plt_eh_frame
+ || s == htab->sdynbss)
+ {
+ /* Strip these too. */
+ }
+ else if (CONST_STRNEQ (bfd_get_section_name (dynobj, s), ".rel"))
+ {
+ if (s->size != 0
+ && s != htab->elf.srelplt
+ && s != htab->srelplt2)
+ relocs = 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
+ {
+ /* It's not one of our sections, so don't allocate space. */
+ continue;
+ }
+
+ if (s->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. */
+ if (strip_section)
+ s->flags |= SEC_EXCLUDE;
+ continue;
+ }
+
+ if ((s->flags & SEC_HAS_CONTENTS) == 0)
+ continue;
+
+ /* Allocate memory for the section contents. We use bfd_zalloc
+ here in case unused entries are not reclaimed before the
+ section's contents are written out. This should not happen,
+ but this way if it does, we get a R_386_NONE reloc instead
+ of garbage. */
+ s->contents = (unsigned char *) bfd_zalloc (dynobj, s->size);
+ if (s->contents == NULL)
+ return FALSE;
+ }
+
+ if (htab->plt_eh_frame != NULL
+ && htab->plt_eh_frame->contents != NULL)
+ {
+ memcpy (htab->plt_eh_frame->contents, elf_i386_eh_frame_plt,
+ sizeof (elf_i386_eh_frame_plt));
+ bfd_put_32 (dynobj, htab->elf.splt->size,
+ htab->plt_eh_frame->contents + PLT_FDE_LEN_OFFSET);
+ }
+
+ if (htab->elf.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. */
+#define add_dynamic_entry(TAG, VAL) \
+ _bfd_elf_add_dynamic_entry (info, TAG, VAL)
+
+ if (info->executable)
+ {
+ if (!add_dynamic_entry (DT_DEBUG, 0))
+ return FALSE;
+ }
+
+ if (htab->elf.splt->size != 0)
+ {
+ if (!add_dynamic_entry (DT_PLTGOT, 0)
+ || !add_dynamic_entry (DT_PLTRELSZ, 0)
+ || !add_dynamic_entry (DT_PLTREL, DT_REL)
+ || !add_dynamic_entry (DT_JMPREL, 0))
+ return FALSE;
+ }
+
+ if (relocs)
+ {
+ if (!add_dynamic_entry (DT_REL, 0)
+ || !add_dynamic_entry (DT_RELSZ, 0)
+ || !add_dynamic_entry (DT_RELENT, sizeof (Elf32_External_Rel)))
+ return FALSE;
+
+ /* If any dynamic relocs apply to a read-only section,
+ then we need a DT_TEXTREL entry. */
+ if ((info->flags & DF_TEXTREL) == 0)
+ elf_link_hash_traverse (&htab->elf,
+ elf_i386_readonly_dynrelocs, info);
+
+ if ((info->flags & DF_TEXTREL) != 0)
+ {
+ if (!add_dynamic_entry (DT_TEXTREL, 0))
+ return FALSE;
+ }
+ }
+ if (get_elf_i386_backend_data (output_bfd)->is_vxworks
+ && !elf_vxworks_add_dynamic_entries (output_bfd, info))
+ return FALSE;
+ }
+#undef add_dynamic_entry
+
+ return TRUE;
+}
+
+static bfd_boolean
+elf_i386_always_size_sections (bfd *output_bfd,
+ struct bfd_link_info *info)
+{
+ asection *tls_sec = elf_hash_table (info)->tls_sec;
+
+ if (tls_sec)
+ {
+ struct elf_link_hash_entry *tlsbase;
+
+ tlsbase = elf_link_hash_lookup (elf_hash_table (info),
+ "_TLS_MODULE_BASE_",
+ FALSE, FALSE, FALSE);
+
+ if (tlsbase && tlsbase->type == STT_TLS)
+ {
+ struct elf_i386_link_hash_table *htab;
+ struct bfd_link_hash_entry *bh = NULL;
+ const struct elf_backend_data *bed
+ = get_elf_backend_data (output_bfd);
+
+ htab = elf_i386_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ if (!(_bfd_generic_link_add_one_symbol
+ (info, output_bfd, "_TLS_MODULE_BASE_", BSF_LOCAL,
+ tls_sec, 0, NULL, FALSE,
+ bed->collect, &bh)))
+ return FALSE;
+
+ htab->tls_module_base = bh;
+
+ tlsbase = (struct elf_link_hash_entry *)bh;
+ tlsbase->def_regular = 1;
+ tlsbase->other = STV_HIDDEN;
+ (*bed->elf_backend_hide_symbol) (info, tlsbase, TRUE);
+ }
+ }
+
+ return TRUE;
+}
+
+/* Set the correct type for an x86 ELF section. We do this by the
+ section name, which is a hack, but ought to work. */
+
+static bfd_boolean
+elf_i386_fake_sections (bfd *abfd ATTRIBUTE_UNUSED,
+ Elf_Internal_Shdr *hdr,
+ asection *sec)
+{
+ const char *name;
+
+ name = bfd_get_section_name (abfd, sec);
+
+ /* This is an ugly, but unfortunately necessary hack that is
+ needed when producing EFI binaries on x86. It tells
+ elf.c:elf_fake_sections() not to consider ".reloc" as a section
+ containing ELF relocation info. We need this hack in order to
+ be able to generate ELF binaries that can be translated into
+ EFI applications (which are essentially COFF objects). Those
+ files contain a COFF ".reloc" section inside an ELFNN object,
+ which would normally cause BFD to segfault because it would
+ attempt to interpret this section as containing relocation
+ entries for section "oc". With this hack enabled, ".reloc"
+ will be treated as a normal data section, which will avoid the
+ segfault. However, you won't be able to create an ELFNN binary
+ with a section named "oc" that needs relocations, but that's
+ the kind of ugly side-effects you get when detecting section
+ types based on their names... In practice, this limitation is
+ unlikely to bite. */
+ if (strcmp (name, ".reloc") == 0)
+ hdr->sh_type = SHT_PROGBITS;
+
+ return TRUE;
+}
+
+/* _TLS_MODULE_BASE_ needs to be treated especially when linking
+ executables. Rather than setting it to the beginning of the TLS
+ section, we have to set it to the end. This function may be called
+ multiple times, it is idempotent. */
+
+static void
+elf_i386_set_tls_module_base (struct bfd_link_info *info)
+{
+ struct elf_i386_link_hash_table *htab;
+ struct bfd_link_hash_entry *base;
+
+ if (!info->executable)
+ return;
+
+ htab = elf_i386_hash_table (info);
+ if (htab == NULL)
+ return;
+
+ base = htab->tls_module_base;
+ if (base == NULL)
+ return;
+
+ base->u.def.value = htab->elf.tls_size;
+}
+
+/* Return the base VMA address which should be subtracted from real addresses
+ when resolving @dtpoff relocation.
+ This is PT_TLS segment p_vaddr. */
+
+static bfd_vma
+elf_i386_dtpoff_base (struct bfd_link_info *info)
+{
+ /* If tls_sec is NULL, we should have signalled an error already. */
+ if (elf_hash_table (info)->tls_sec == NULL)
+ return 0;
+ return elf_hash_table (info)->tls_sec->vma;
+}
+
+/* Return the relocation value for @tpoff relocation
+ if STT_TLS virtual address is ADDRESS. */
+
+static bfd_vma
+elf_i386_tpoff (struct bfd_link_info *info, bfd_vma address)
+{
+ struct elf_link_hash_table *htab = elf_hash_table (info);
+ const struct elf_backend_data *bed = get_elf_backend_data (info->output_bfd);
+ bfd_vma static_tls_size;
+
+ /* If tls_sec is NULL, we should have signalled an error already. */
+ if (htab->tls_sec == NULL)
+ return 0;
+
+ /* Consider special static TLS alignment requirements. */
+ static_tls_size = BFD_ALIGN (htab->tls_size, bed->static_tls_alignment);
+ return static_tls_size + htab->tls_sec->vma - address;
+}
+
+/* Relocate an i386 ELF section. */
+
+static bfd_boolean
+elf_i386_relocate_section (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)
+{
+ struct elf_i386_link_hash_table *htab;
+ Elf_Internal_Shdr *symtab_hdr;
+ struct elf_link_hash_entry **sym_hashes;
+ bfd_vma *local_got_offsets;
+ bfd_vma *local_tlsdesc_gotents;
+ Elf_Internal_Rela *rel;
+ Elf_Internal_Rela *relend;
+ bfd_boolean is_vxworks_tls;
+ unsigned plt_entry_size;
+
+ BFD_ASSERT (is_i386_elf (input_bfd));
+
+ htab = elf_i386_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+ symtab_hdr = &elf_symtab_hdr (input_bfd);
+ sym_hashes = elf_sym_hashes (input_bfd);
+ local_got_offsets = elf_local_got_offsets (input_bfd);
+ local_tlsdesc_gotents = elf_i386_local_tlsdesc_gotent (input_bfd);
+ /* We have to handle relocations in vxworks .tls_vars sections
+ specially, because the dynamic loader is 'weird'. */
+ is_vxworks_tls = (get_elf_i386_backend_data (output_bfd)->is_vxworks
+ && info->shared
+ && !strcmp (input_section->output_section->name,
+ ".tls_vars"));
+
+ elf_i386_set_tls_module_base (info);
+
+ plt_entry_size = GET_PLT_ENTRY_SIZE (output_bfd);
+
+ rel = relocs;
+ relend = relocs + input_section->reloc_count;
+ for (; rel < relend; rel++)
+ {
+ unsigned 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 off, offplt;
+ bfd_vma relocation;
+ bfd_boolean unresolved_reloc;
+ bfd_reloc_status_type r;
+ unsigned int indx;
+ int tls_type;
+ bfd_vma st_size;
+
+ r_type = ELF32_R_TYPE (rel->r_info);
+ if (r_type == R_386_GNU_VTINHERIT
+ || r_type == R_386_GNU_VTENTRY)
+ continue;
+
+ if ((indx = r_type) >= R_386_standard
+ && ((indx = r_type - R_386_ext_offset) - R_386_standard
+ >= R_386_ext - R_386_standard)
+ && ((indx = r_type - R_386_tls_offset) - R_386_ext
+ >= R_386_irelative - R_386_ext))
+ {
+ (*_bfd_error_handler)
+ (_("%B: unrecognized relocation (0x%x) in section `%A'"),
+ input_bfd, input_section, r_type);
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+ howto = elf_howto_table + indx;
+
+ r_symndx = ELF32_R_SYM (rel->r_info);
+ h = NULL;
+ sym = NULL;
+ sec = NULL;
+ unresolved_reloc = FALSE;
+ 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);
+ st_size = sym->st_size;
+
+ if (ELF_ST_TYPE (sym->st_info) == STT_SECTION
+ && ((sec->flags & SEC_MERGE) != 0
+ || (info->relocatable
+ && sec->output_offset != 0)))
+ {
+ bfd_vma addend;
+ bfd_byte *where = contents + rel->r_offset;
+
+ switch (howto->size)
+ {
+ case 0:
+ addend = bfd_get_8 (input_bfd, where);
+ if (howto->pc_relative)
+ {
+ addend = (addend ^ 0x80) - 0x80;
+ addend += 1;
+ }
+ break;
+ case 1:
+ addend = bfd_get_16 (input_bfd, where);
+ if (howto->pc_relative)
+ {
+ addend = (addend ^ 0x8000) - 0x8000;
+ addend += 2;
+ }
+ break;
+ case 2:
+ addend = bfd_get_32 (input_bfd, where);
+ if (howto->pc_relative)
+ {
+ addend = (addend ^ 0x80000000) - 0x80000000;
+ addend += 4;
+ }
+ break;
+ default:
+ abort ();
+ }
+
+ if (info->relocatable)
+ addend += sec->output_offset;
+ else
+ {
+ asection *msec = sec;
+ addend = _bfd_elf_rel_local_sym (output_bfd, sym, &msec,
+ addend);
+ addend -= relocation;
+ addend += msec->output_section->vma + msec->output_offset;
+ }
+
+ switch (howto->size)
+ {
+ case 0:
+ /* FIXME: overflow checks. */
+ if (howto->pc_relative)
+ addend -= 1;
+ bfd_put_8 (input_bfd, addend, where);
+ break;
+ case 1:
+ if (howto->pc_relative)
+ addend -= 2;
+ bfd_put_16 (input_bfd, addend, where);
+ break;
+ case 2:
+ if (howto->pc_relative)
+ addend -= 4;
+ bfd_put_32 (input_bfd, addend, where);
+ break;
+ }
+ }
+ else if (!info->relocatable
+ && ELF32_ST_TYPE (sym->st_info) == STT_GNU_IFUNC)
+ {
+ /* Relocate against local STT_GNU_IFUNC symbol. */
+ h = elf_i386_get_local_sym_hash (htab, input_bfd, rel,
+ FALSE);
+ if (h == NULL)
+ abort ();
+
+ /* Set STT_GNU_IFUNC symbol value. */
+ h->root.u.def.value = sym->st_value;
+ h->root.u.def.section = sec;
+ }
+ }
+ else
+ {
+ bfd_boolean warned ATTRIBUTE_UNUSED;
+ bfd_boolean ignored ATTRIBUTE_UNUSED;
+
+ RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
+ r_symndx, symtab_hdr, sym_hashes,
+ h, sec, relocation,
+ unresolved_reloc, warned, ignored);
+ st_size = h->size;
+ }
+
+ if (sec != NULL && discarded_section (sec))
+ RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+ rel, 1, relend, howto, 0, contents);
+
+ if (info->relocatable)
+ continue;
+
+ /* Since STT_GNU_IFUNC symbol must go through PLT, we handle
+ it here if it is defined in a non-shared object. */
+ if (h != NULL
+ && h->type == STT_GNU_IFUNC
+ && h->def_regular)
+ {
+ asection *plt, *gotplt, *base_got;
+ bfd_vma plt_index;
+ const char *name;
+
+ if ((input_section->flags & SEC_ALLOC) == 0
+ || h->plt.offset == (bfd_vma) -1)
+ abort ();
+
+ /* STT_GNU_IFUNC symbol must go through PLT. */
+ if (htab->elf.splt != NULL)
+ {
+ plt = htab->elf.splt;
+ gotplt = htab->elf.sgotplt;
+ }
+ else
+ {
+ plt = htab->elf.iplt;
+ gotplt = htab->elf.igotplt;
+ }
+
+ relocation = (plt->output_section->vma
+ + plt->output_offset + h->plt.offset);
+
+ switch (r_type)
+ {
+ default:
+ if (h->root.root.string)
+ name = h->root.root.string;
+ else
+ name = bfd_elf_sym_name (input_bfd, symtab_hdr, sym,
+ NULL);
+ (*_bfd_error_handler)
+ (_("%B: relocation %s against STT_GNU_IFUNC "
+ "symbol `%s' isn't handled by %s"), input_bfd,
+ elf_howto_table[r_type].name,
+ name, __FUNCTION__);
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+
+ case R_386_32:
+ /* Generate dynamic relcoation only when there is a
+ non-GOT reference in a shared object. */
+ if (info->shared && h->non_got_ref)
+ {
+ Elf_Internal_Rela outrel;
+ asection *sreloc;
+ bfd_vma offset;
+
+ /* Need a dynamic relocation to get the real function
+ adddress. */
+ offset = _bfd_elf_section_offset (output_bfd,
+ info,
+ input_section,
+ rel->r_offset);
+ if (offset == (bfd_vma) -1
+ || offset == (bfd_vma) -2)
+ abort ();
+
+ outrel.r_offset = (input_section->output_section->vma
+ + input_section->output_offset
+ + offset);
+
+ if (h->dynindx == -1
+ || h->forced_local
+ || info->executable)
+ {
+ /* This symbol is resolved locally. */
+ outrel.r_info = ELF32_R_INFO (0, R_386_IRELATIVE);
+ bfd_put_32 (output_bfd,
+ (h->root.u.def.value
+ + h->root.u.def.section->output_section->vma
+ + h->root.u.def.section->output_offset),
+ contents + offset);
+ }
+ else
+ outrel.r_info = ELF32_R_INFO (h->dynindx, r_type);
+
+ sreloc = htab->elf.irelifunc;
+ elf_append_rel (output_bfd, sreloc, &outrel);
+
+ /* 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. For an
+ internal symbol, we have updated addend. */
+ continue;
+ }
+ /* FALLTHROUGH */
+ case R_386_PC32:
+ case R_386_PLT32:
+ goto do_relocation;
+
+ case R_386_GOT32:
+ base_got = htab->elf.sgot;
+ off = h->got.offset;
+
+ if (base_got == NULL)
+ abort ();
+
+ if (off == (bfd_vma) -1)
+ {
+ /* We can't use h->got.offset here to save state, or
+ even just remember the offset, as finish_dynamic_symbol
+ would use that as offset into .got. */
+
+ if (htab->elf.splt != NULL)
+ {
+ plt_index = h->plt.offset / plt_entry_size - 1;
+ off = (plt_index + 3) * 4;
+ base_got = htab->elf.sgotplt;
+ }
+ else
+ {
+ plt_index = h->plt.offset / plt_entry_size;
+ off = plt_index * 4;
+ base_got = htab->elf.igotplt;
+ }
+
+ if (h->dynindx == -1
+ || h->forced_local
+ || info->symbolic)
+ {
+ /* This references the local defitionion. 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_32 (output_bfd, relocation,
+ base_got->contents + off);
+ h->got.offset |= 1;
+ }
+ }
+
+ relocation = off;
+
+ /* Adjust for static executables. */
+ if (htab->elf.splt == NULL)
+ relocation += gotplt->output_offset;
+ }
+ else
+ {
+ relocation = (base_got->output_section->vma
+ + base_got->output_offset + off
+ - gotplt->output_section->vma
+ - gotplt->output_offset);
+ /* Adjust for static executables. */
+ if (htab->elf.splt == NULL)
+ relocation += gotplt->output_offset;
+ }
+
+ goto do_relocation;
+
+ case R_386_GOTOFF:
+ relocation -= (gotplt->output_section->vma
+ + gotplt->output_offset);
+ goto do_relocation;
+ }
+ }
+
+ switch (r_type)
+ {
+ case R_386_GOT32:
+ /* Relocation is to the entry for this symbol in the global
+ offset table. */
+ if (htab->elf.sgot == NULL)
+ abort ();
+
+ if (h != NULL)
+ {
+ bfd_boolean dyn;
+
+ off = h->got.offset;
+ dyn = htab->elf.dynamic_sections_created;
+ if (! WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h)
+ || (info->shared
+ && SYMBOL_REFERENCES_LOCAL (info, h))
+ || (ELF_ST_VISIBILITY (h->other)
+ && h->root.type == bfd_link_hash_undefweak))
+ {
+ /* 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,
+ htab->elf.sgot->contents + off);
+ h->got.offset |= 1;
+ }
+ }
+ else
+ unresolved_reloc = FALSE;
+ }
+ else
+ {
+ if (local_got_offsets == NULL)
+ abort ();
+
+ 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,
+ htab->elf.sgot->contents + off);
+
+ if (info->shared)
+ {
+ asection *s;
+ Elf_Internal_Rela outrel;
+
+ s = htab->elf.srelgot;
+ if (s == NULL)
+ abort ();
+
+ outrel.r_offset = (htab->elf.sgot->output_section->vma
+ + htab->elf.sgot->output_offset
+ + off);
+ outrel.r_info = ELF32_R_INFO (0, R_386_RELATIVE);
+ elf_append_rel (output_bfd, s, &outrel);
+ }
+
+ local_got_offsets[r_symndx] |= 1;
+ }
+ }
+
+ if (off >= (bfd_vma) -2)
+ abort ();
+
+ relocation = htab->elf.sgot->output_section->vma
+ + htab->elf.sgot->output_offset + off
+ - htab->elf.sgotplt->output_section->vma
+ - htab->elf.sgotplt->output_offset;
+ break;
+
+ case R_386_GOTOFF:
+ /* Relocation is relative to the start of the global offset
+ table. */
+
+ /* Check to make sure it isn't a protected function symbol
+ for shared library since it may not be local when used
+ as function address. We also need to make sure that a
+ symbol is defined locally. */
+ if (info->shared && h)
+ {
+ if (!h->def_regular)
+ {
+ const char *v;
+
+ switch (ELF_ST_VISIBILITY (h->other))
+ {
+ case STV_HIDDEN:
+ v = _("hidden symbol");
+ break;
+ case STV_INTERNAL:
+ v = _("internal symbol");
+ break;
+ case STV_PROTECTED:
+ v = _("protected symbol");
+ break;
+ default:
+ v = _("symbol");
+ break;
+ }
+
+ (*_bfd_error_handler)
+ (_("%B: relocation R_386_GOTOFF against undefined %s `%s' can not be used when making a shared object"),
+ input_bfd, v, h->root.root.string);
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+ else if (!info->executable
+ && !SYMBOLIC_BIND (info, h)
+ && h->type == STT_FUNC
+ && ELF_ST_VISIBILITY (h->other) == STV_PROTECTED)
+ {
+ (*_bfd_error_handler)
+ (_("%B: relocation R_386_GOTOFF against protected function `%s' can not be used when making a shared object"),
+ input_bfd, h->root.root.string);
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+ }
+
+ /* Note that sgot is not involved in this
+ calculation. We always want the start of .got.plt. If we
+ defined _GLOBAL_OFFSET_TABLE_ in a different way, as is
+ permitted by the ABI, we might have to change this
+ calculation. */
+ relocation -= htab->elf.sgotplt->output_section->vma
+ + htab->elf.sgotplt->output_offset;
+ break;
+
+ case R_386_GOTPC:
+ /* Use global offset table as symbol value. */
+ relocation = htab->elf.sgotplt->output_section->vma
+ + htab->elf.sgotplt->output_offset;
+ unresolved_reloc = FALSE;
+ break;
+
+ case R_386_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)
+ break;
+
+ if (h->plt.offset == (bfd_vma) -1
+ || htab->elf.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 = (htab->elf.splt->output_section->vma
+ + htab->elf.splt->output_offset
+ + h->plt.offset);
+ unresolved_reloc = FALSE;
+ break;
+
+ case R_386_SIZE32:
+ /* Set to symbol size. */
+ relocation = st_size;
+ /* Fall through. */
+
+ case R_386_32:
+ case R_386_PC32:
+ if ((input_section->flags & SEC_ALLOC) == 0
+ || is_vxworks_tls)
+ break;
+
+ if ((info->shared
+ && (h == NULL
+ || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
+ || h->root.type != bfd_link_hash_undefweak)
+ && ((r_type != R_386_PC32 && r_type != R_386_SIZE32)
+ || !SYMBOL_CALLS_LOCAL (info, h)))
+ || (ELIMINATE_COPY_RELOCS
+ && !info->shared
+ && h != NULL
+ && h->dynindx != -1
+ && !h->non_got_ref
+ && ((h->def_dynamic
+ && !h->def_regular)
+ || h->root.type == bfd_link_hash_undefweak
+ || h->root.type == bfd_link_hash_undefined)))
+ {
+ Elf_Internal_Rela outrel;
+ bfd_boolean skip, relocate;
+ asection *sreloc;
+
+ /* When generating a shared object, these relocations
+ are copied into the output file to be resolved at run
+ time. */
+
+ skip = FALSE;
+ relocate = FALSE;
+
+ outrel.r_offset =
+ _bfd_elf_section_offset (output_bfd, info, input_section,
+ rel->r_offset);
+ if (outrel.r_offset == (bfd_vma) -1)
+ skip = TRUE;
+ else if (outrel.r_offset == (bfd_vma) -2)
+ skip = TRUE, relocate = TRUE;
+ outrel.r_offset += (input_section->output_section->vma
+ + input_section->output_offset);
+
+ if (skip)
+ memset (&outrel, 0, sizeof outrel);
+ else if (h != NULL
+ && h->dynindx != -1
+ && (r_type == R_386_PC32
+ || !info->shared
+ || !SYMBOLIC_BIND (info, h)
+ || !h->def_regular))
+ outrel.r_info = ELF32_R_INFO (h->dynindx, r_type);
+ else
+ {
+ /* This symbol is local, or marked to become local. */
+ relocate = TRUE;
+ outrel.r_info = ELF32_R_INFO (0, R_386_RELATIVE);
+ }
+
+ sreloc = elf_section_data (input_section)->sreloc;
+
+ if (sreloc == NULL || sreloc->contents == NULL)
+ {
+ r = bfd_reloc_notsupported;
+ goto check_relocation_error;
+ }
+
+ elf_append_rel (output_bfd, sreloc, &outrel);
+
+ /* 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;
+
+ case R_386_TLS_IE:
+ if (!info->executable)
+ {
+ Elf_Internal_Rela outrel;
+ asection *sreloc;
+
+ outrel.r_offset = rel->r_offset
+ + input_section->output_section->vma
+ + input_section->output_offset;
+ outrel.r_info = ELF32_R_INFO (0, R_386_RELATIVE);
+ sreloc = elf_section_data (input_section)->sreloc;
+ if (sreloc == NULL)
+ abort ();
+ elf_append_rel (output_bfd, sreloc, &outrel);
+ }
+ /* Fall through */
+
+ case R_386_TLS_GD:
+ case R_386_TLS_GOTDESC:
+ case R_386_TLS_DESC_CALL:
+ case R_386_TLS_IE_32:
+ case R_386_TLS_GOTIE:
+ tls_type = GOT_UNKNOWN;
+ if (h == NULL && local_got_offsets)
+ tls_type = elf_i386_local_got_tls_type (input_bfd) [r_symndx];
+ else if (h != NULL)
+ tls_type = elf_i386_hash_entry(h)->tls_type;
+ if (tls_type == GOT_TLS_IE)
+ tls_type = GOT_TLS_IE_NEG;
+
+ if (! elf_i386_tls_transition (info, input_bfd,
+ input_section, contents,
+ symtab_hdr, sym_hashes,
+ &r_type, tls_type, rel,
+ relend, h, r_symndx))
+ return FALSE;
+
+ if (r_type == R_386_TLS_LE_32)
+ {
+ BFD_ASSERT (! unresolved_reloc);
+ if (ELF32_R_TYPE (rel->r_info) == R_386_TLS_GD)
+ {
+ unsigned int type;
+ bfd_vma roff;
+
+ /* GD->LE transition. */
+ type = bfd_get_8 (input_bfd, contents + rel->r_offset - 2);
+ if (type == 0x04)
+ {
+ /* leal foo(,%reg,1), %eax; call ___tls_get_addr
+ Change it into:
+ movl %gs:0, %eax; subl $foo@tpoff, %eax
+ (6 byte form of subl). */
+ memcpy (contents + rel->r_offset - 3,
+ "\x65\xa1\0\0\0\0\x81\xe8\0\0\0", 12);
+ roff = rel->r_offset + 5;
+ }
+ else
+ {
+ /* leal foo(%reg), %eax; call ___tls_get_addr; nop
+ Change it into:
+ movl %gs:0, %eax; subl $foo@tpoff, %eax
+ (6 byte form of subl). */
+ memcpy (contents + rel->r_offset - 2,
+ "\x65\xa1\0\0\0\0\x81\xe8\0\0\0", 12);
+ roff = rel->r_offset + 6;
+ }
+ bfd_put_32 (output_bfd, elf_i386_tpoff (info, relocation),
+ contents + roff);
+ /* Skip R_386_PC32/R_386_PLT32. */
+ rel++;
+ continue;
+ }
+ else if (ELF32_R_TYPE (rel->r_info) == R_386_TLS_GOTDESC)
+ {
+ /* GDesc -> LE transition.
+ It's originally something like:
+ leal x@tlsdesc(%ebx), %eax
+
+ leal x@ntpoff, %eax
+
+ Registers other than %eax may be set up here. */
+
+ unsigned int val;
+ bfd_vma roff;
+
+ roff = rel->r_offset;
+ val = bfd_get_8 (input_bfd, contents + roff - 1);
+
+ /* Now modify the instruction as appropriate. */
+ /* aoliva FIXME: remove the above and xor the byte
+ below with 0x86. */
+ bfd_put_8 (output_bfd, val ^ 0x86,
+ contents + roff - 1);
+ bfd_put_32 (output_bfd, -elf_i386_tpoff (info, relocation),
+ contents + roff);
+ continue;
+ }
+ else if (ELF32_R_TYPE (rel->r_info) == R_386_TLS_DESC_CALL)
+ {
+ /* GDesc -> LE transition.
+ It's originally:
+ call *(%eax)
+ Turn it into:
+ xchg %ax,%ax */
+
+ bfd_vma roff;
+
+ roff = rel->r_offset;
+ bfd_put_8 (output_bfd, 0x66, contents + roff);
+ bfd_put_8 (output_bfd, 0x90, contents + roff + 1);
+ continue;
+ }
+ else if (ELF32_R_TYPE (rel->r_info) == R_386_TLS_IE)
+ {
+ unsigned int val;
+
+ /* IE->LE transition:
+ Originally it can be one of:
+ movl foo, %eax
+ movl foo, %reg
+ addl foo, %reg
+ We change it into:
+ movl $foo, %eax
+ movl $foo, %reg
+ addl $foo, %reg. */
+ val = bfd_get_8 (input_bfd, contents + rel->r_offset - 1);
+ if (val == 0xa1)
+ {
+ /* movl foo, %eax. */
+ bfd_put_8 (output_bfd, 0xb8,
+ contents + rel->r_offset - 1);
+ }
+ else
+ {
+ unsigned int type;
+
+ type = bfd_get_8 (input_bfd,
+ contents + rel->r_offset - 2);
+ switch (type)
+ {
+ case 0x8b:
+ /* movl */
+ bfd_put_8 (output_bfd, 0xc7,
+ contents + rel->r_offset - 2);
+ bfd_put_8 (output_bfd,
+ 0xc0 | ((val >> 3) & 7),
+ contents + rel->r_offset - 1);
+ break;
+ case 0x03:
+ /* addl */
+ bfd_put_8 (output_bfd, 0x81,
+ contents + rel->r_offset - 2);
+ bfd_put_8 (output_bfd,
+ 0xc0 | ((val >> 3) & 7),
+ contents + rel->r_offset - 1);
+ break;
+ default:
+ BFD_FAIL ();
+ break;
+ }
+ }
+ bfd_put_32 (output_bfd, -elf_i386_tpoff (info, relocation),
+ contents + rel->r_offset);
+ continue;
+ }
+ else
+ {
+ unsigned int val, type;
+
+ /* {IE_32,GOTIE}->LE transition:
+ Originally it can be one of:
+ subl foo(%reg1), %reg2
+ movl foo(%reg1), %reg2
+ addl foo(%reg1), %reg2
+ We change it into:
+ subl $foo, %reg2
+ movl $foo, %reg2 (6 byte form)
+ addl $foo, %reg2. */
+ type = bfd_get_8 (input_bfd, contents + rel->r_offset - 2);
+ val = bfd_get_8 (input_bfd, contents + rel->r_offset - 1);
+ if (type == 0x8b)
+ {
+ /* movl */
+ bfd_put_8 (output_bfd, 0xc7,
+ contents + rel->r_offset - 2);
+ bfd_put_8 (output_bfd, 0xc0 | ((val >> 3) & 7),
+ contents + rel->r_offset - 1);
+ }
+ else if (type == 0x2b)
+ {
+ /* subl */
+ bfd_put_8 (output_bfd, 0x81,
+ contents + rel->r_offset - 2);
+ bfd_put_8 (output_bfd, 0xe8 | ((val >> 3) & 7),
+ contents + rel->r_offset - 1);
+ }
+ else if (type == 0x03)
+ {
+ /* addl */
+ bfd_put_8 (output_bfd, 0x81,
+ contents + rel->r_offset - 2);
+ bfd_put_8 (output_bfd, 0xc0 | ((val >> 3) & 7),
+ contents + rel->r_offset - 1);
+ }
+ else
+ BFD_FAIL ();
+ if (ELF32_R_TYPE (rel->r_info) == R_386_TLS_GOTIE)
+ bfd_put_32 (output_bfd, -elf_i386_tpoff (info, relocation),
+ contents + rel->r_offset);
+ else
+ bfd_put_32 (output_bfd, elf_i386_tpoff (info, relocation),
+ contents + rel->r_offset);
+ continue;
+ }
+ }
+
+ if (htab->elf.sgot == NULL)
+ abort ();
+
+ if (h != NULL)
+ {
+ off = h->got.offset;
+ offplt = elf_i386_hash_entry (h)->tlsdesc_got;
+ }
+ else
+ {
+ if (local_got_offsets == NULL)
+ abort ();
+
+ off = local_got_offsets[r_symndx];
+ offplt = local_tlsdesc_gotents[r_symndx];
+ }
+
+ if ((off & 1) != 0)
+ off &= ~1;
+ else
+ {
+ Elf_Internal_Rela outrel;
+ int dr_type;
+ asection *sreloc;
+
+ if (htab->elf.srelgot == NULL)
+ abort ();
+
+ indx = h && h->dynindx != -1 ? h->dynindx : 0;
+
+ if (GOT_TLS_GDESC_P (tls_type))
+ {
+ bfd_byte *loc;
+ outrel.r_info = ELF32_R_INFO (indx, R_386_TLS_DESC);
+ BFD_ASSERT (htab->sgotplt_jump_table_size + offplt + 8
+ <= htab->elf.sgotplt->size);
+ outrel.r_offset = (htab->elf.sgotplt->output_section->vma
+ + htab->elf.sgotplt->output_offset
+ + offplt
+ + htab->sgotplt_jump_table_size);
+ sreloc = htab->elf.srelplt;
+ loc = sreloc->contents;
+ loc += (htab->next_tls_desc_index++
+ * sizeof (Elf32_External_Rel));
+ BFD_ASSERT (loc + sizeof (Elf32_External_Rel)
+ <= sreloc->contents + sreloc->size);
+ bfd_elf32_swap_reloc_out (output_bfd, &outrel, loc);
+ if (indx == 0)
+ {
+ BFD_ASSERT (! unresolved_reloc);
+ bfd_put_32 (output_bfd,
+ relocation - elf_i386_dtpoff_base (info),
+ htab->elf.sgotplt->contents + offplt
+ + htab->sgotplt_jump_table_size + 4);
+ }
+ else
+ {
+ bfd_put_32 (output_bfd, 0,
+ htab->elf.sgotplt->contents + offplt
+ + htab->sgotplt_jump_table_size + 4);
+ }
+ }
+
+ sreloc = htab->elf.srelgot;
+
+ outrel.r_offset = (htab->elf.sgot->output_section->vma
+ + htab->elf.sgot->output_offset + off);
+
+ if (GOT_TLS_GD_P (tls_type))
+ dr_type = R_386_TLS_DTPMOD32;
+ else if (GOT_TLS_GDESC_P (tls_type))
+ goto dr_done;
+ else if (tls_type == GOT_TLS_IE_POS)
+ dr_type = R_386_TLS_TPOFF;
+ else
+ dr_type = R_386_TLS_TPOFF32;
+
+ if (dr_type == R_386_TLS_TPOFF && indx == 0)
+ bfd_put_32 (output_bfd,
+ relocation - elf_i386_dtpoff_base (info),
+ htab->elf.sgot->contents + off);
+ else if (dr_type == R_386_TLS_TPOFF32 && indx == 0)
+ bfd_put_32 (output_bfd,
+ elf_i386_dtpoff_base (info) - relocation,
+ htab->elf.sgot->contents + off);
+ else if (dr_type != R_386_TLS_DESC)
+ bfd_put_32 (output_bfd, 0,
+ htab->elf.sgot->contents + off);
+ outrel.r_info = ELF32_R_INFO (indx, dr_type);
+
+ elf_append_rel (output_bfd, sreloc, &outrel);
+
+ if (GOT_TLS_GD_P (tls_type))
+ {
+ if (indx == 0)
+ {
+ BFD_ASSERT (! unresolved_reloc);
+ bfd_put_32 (output_bfd,
+ relocation - elf_i386_dtpoff_base (info),
+ htab->elf.sgot->contents + off + 4);
+ }
+ else
+ {
+ bfd_put_32 (output_bfd, 0,
+ htab->elf.sgot->contents + off + 4);
+ outrel.r_info = ELF32_R_INFO (indx,
+ R_386_TLS_DTPOFF32);
+ outrel.r_offset += 4;
+ elf_append_rel (output_bfd, sreloc, &outrel);
+ }
+ }
+ else if (tls_type == GOT_TLS_IE_BOTH)
+ {
+ bfd_put_32 (output_bfd,
+ (indx == 0
+ ? relocation - elf_i386_dtpoff_base (info)
+ : 0),
+ htab->elf.sgot->contents + off + 4);
+ outrel.r_info = ELF32_R_INFO (indx, R_386_TLS_TPOFF);
+ outrel.r_offset += 4;
+ elf_append_rel (output_bfd, sreloc, &outrel);
+ }
+
+ dr_done:
+ if (h != NULL)
+ h->got.offset |= 1;
+ else
+ local_got_offsets[r_symndx] |= 1;
+ }
+
+ if (off >= (bfd_vma) -2
+ && ! GOT_TLS_GDESC_P (tls_type))
+ abort ();
+ if (r_type == R_386_TLS_GOTDESC
+ || r_type == R_386_TLS_DESC_CALL)
+ {
+ relocation = htab->sgotplt_jump_table_size + offplt;
+ unresolved_reloc = FALSE;
+ }
+ else if (r_type == ELF32_R_TYPE (rel->r_info))
+ {
+ bfd_vma g_o_t = htab->elf.sgotplt->output_section->vma
+ + htab->elf.sgotplt->output_offset;
+ relocation = htab->elf.sgot->output_section->vma
+ + htab->elf.sgot->output_offset + off - g_o_t;
+ if ((r_type == R_386_TLS_IE || r_type == R_386_TLS_GOTIE)
+ && tls_type == GOT_TLS_IE_BOTH)
+ relocation += 4;
+ if (r_type == R_386_TLS_IE)
+ relocation += g_o_t;
+ unresolved_reloc = FALSE;
+ }
+ else if (ELF32_R_TYPE (rel->r_info) == R_386_TLS_GD)
+ {
+ unsigned int val, type;
+ bfd_vma roff;
+
+ /* GD->IE transition. */
+ type = bfd_get_8 (input_bfd, contents + rel->r_offset - 2);
+ val = bfd_get_8 (input_bfd, contents + rel->r_offset - 1);
+ if (type == 0x04)
+ {
+ /* leal foo(,%reg,1), %eax; call ___tls_get_addr
+ Change it into:
+ movl %gs:0, %eax; subl $foo@gottpoff(%reg), %eax. */
+ val >>= 3;
+ roff = rel->r_offset - 3;
+ }
+ else
+ {
+ /* leal foo(%reg), %eax; call ___tls_get_addr; nop
+ Change it into:
+ movl %gs:0, %eax; subl $foo@gottpoff(%reg), %eax. */
+ roff = rel->r_offset - 2;
+ }
+ memcpy (contents + roff,
+ "\x65\xa1\0\0\0\0\x2b\x80\0\0\0", 12);
+ contents[roff + 7] = 0x80 | (val & 7);
+ /* If foo is used only with foo@gotntpoff(%reg) and
+ foo@indntpoff, but not with foo@gottpoff(%reg), change
+ subl $foo@gottpoff(%reg), %eax
+ into:
+ addl $foo@gotntpoff(%reg), %eax. */
+ if (tls_type == GOT_TLS_IE_POS)
+ contents[roff + 6] = 0x03;
+ bfd_put_32 (output_bfd,
+ htab->elf.sgot->output_section->vma
+ + htab->elf.sgot->output_offset + off
+ - htab->elf.sgotplt->output_section->vma
+ - htab->elf.sgotplt->output_offset,
+ contents + roff + 8);
+ /* Skip R_386_PLT32. */
+ rel++;
+ continue;
+ }
+ else if (ELF32_R_TYPE (rel->r_info) == R_386_TLS_GOTDESC)
+ {
+ /* GDesc -> IE transition.
+ It's originally something like:
+ leal x@tlsdesc(%ebx), %eax
+
+ Change it to:
+ movl x@gotntpoff(%ebx), %eax # before xchg %ax,%ax
+ or:
+ movl x@gottpoff(%ebx), %eax # before negl %eax
+
+ Registers other than %eax may be set up here. */
+
+ bfd_vma roff;
+
+ /* First, make sure it's a leal adding ebx to a 32-bit
+ offset into any register, although it's probably
+ almost always going to be eax. */
+ roff = rel->r_offset;
+
+ /* Now modify the instruction as appropriate. */
+ /* To turn a leal into a movl in the form we use it, it
+ suffices to change the first byte from 0x8d to 0x8b.
+ aoliva FIXME: should we decide to keep the leal, all
+ we have to do is remove the statement below, and
+ adjust the relaxation of R_386_TLS_DESC_CALL. */
+ bfd_put_8 (output_bfd, 0x8b, contents + roff - 2);
+
+ if (tls_type == GOT_TLS_IE_BOTH)
+ off += 4;
+
+ bfd_put_32 (output_bfd,
+ htab->elf.sgot->output_section->vma
+ + htab->elf.sgot->output_offset + off
+ - htab->elf.sgotplt->output_section->vma
+ - htab->elf.sgotplt->output_offset,
+ contents + roff);
+ continue;
+ }
+ else if (ELF32_R_TYPE (rel->r_info) == R_386_TLS_DESC_CALL)
+ {
+ /* GDesc -> IE transition.
+ It's originally:
+ call *(%eax)
+
+ Change it to:
+ xchg %ax,%ax
+ or
+ negl %eax
+ depending on how we transformed the TLS_GOTDESC above.
+ */
+
+ bfd_vma roff;
+
+ roff = rel->r_offset;
+
+ /* Now modify the instruction as appropriate. */
+ if (tls_type != GOT_TLS_IE_NEG)
+ {
+ /* xchg %ax,%ax */
+ bfd_put_8 (output_bfd, 0x66, contents + roff);
+ bfd_put_8 (output_bfd, 0x90, contents + roff + 1);
+ }
+ else
+ {
+ /* negl %eax */
+ bfd_put_8 (output_bfd, 0xf7, contents + roff);
+ bfd_put_8 (output_bfd, 0xd8, contents + roff + 1);
+ }
+
+ continue;
+ }
+ else
+ BFD_ASSERT (FALSE);
+ break;
+
+ case R_386_TLS_LDM:
+ if (! elf_i386_tls_transition (info, input_bfd,
+ input_section, contents,
+ symtab_hdr, sym_hashes,
+ &r_type, GOT_UNKNOWN, rel,
+ relend, h, r_symndx))
+ return FALSE;
+
+ if (r_type != R_386_TLS_LDM)
+ {
+ /* LD->LE transition:
+ leal foo(%reg), %eax; call ___tls_get_addr.
+ We change it into:
+ movl %gs:0, %eax; nop; leal 0(%esi,1), %esi. */
+ BFD_ASSERT (r_type == R_386_TLS_LE_32);
+ memcpy (contents + rel->r_offset - 2,
+ "\x65\xa1\0\0\0\0\x90\x8d\x74\x26", 11);
+ /* Skip R_386_PC32/R_386_PLT32. */
+ rel++;
+ continue;
+ }
+
+ if (htab->elf.sgot == NULL)
+ abort ();
+
+ off = htab->tls_ldm_got.offset;
+ if (off & 1)
+ off &= ~1;
+ else
+ {
+ Elf_Internal_Rela outrel;
+
+ if (htab->elf.srelgot == NULL)
+ abort ();
+
+ outrel.r_offset = (htab->elf.sgot->output_section->vma
+ + htab->elf.sgot->output_offset + off);
+
+ bfd_put_32 (output_bfd, 0,
+ htab->elf.sgot->contents + off);
+ bfd_put_32 (output_bfd, 0,
+ htab->elf.sgot->contents + off + 4);
+ outrel.r_info = ELF32_R_INFO (0, R_386_TLS_DTPMOD32);
+ elf_append_rel (output_bfd, htab->elf.srelgot, &outrel);
+ htab->tls_ldm_got.offset |= 1;
+ }
+ relocation = htab->elf.sgot->output_section->vma
+ + htab->elf.sgot->output_offset + off
+ - htab->elf.sgotplt->output_section->vma
+ - htab->elf.sgotplt->output_offset;
+ unresolved_reloc = FALSE;
+ break;
+
+ case R_386_TLS_LDO_32:
+ if (!info->executable || (input_section->flags & SEC_CODE) == 0)
+ relocation -= elf_i386_dtpoff_base (info);
+ else
+ /* When converting LDO to LE, we must negate. */
+ relocation = -elf_i386_tpoff (info, relocation);
+ break;
+
+ case R_386_TLS_LE_32:
+ case R_386_TLS_LE:
+ if (!info->executable)
+ {
+ Elf_Internal_Rela outrel;
+ asection *sreloc;
+
+ outrel.r_offset = rel->r_offset
+ + input_section->output_section->vma
+ + input_section->output_offset;
+ if (h != NULL && h->dynindx != -1)
+ indx = h->dynindx;
+ else
+ indx = 0;
+ if (r_type == R_386_TLS_LE_32)
+ outrel.r_info = ELF32_R_INFO (indx, R_386_TLS_TPOFF32);
+ else
+ outrel.r_info = ELF32_R_INFO (indx, R_386_TLS_TPOFF);
+ sreloc = elf_section_data (input_section)->sreloc;
+ if (sreloc == NULL)
+ abort ();
+ elf_append_rel (output_bfd, sreloc, &outrel);
+ if (indx)
+ continue;
+ else if (r_type == R_386_TLS_LE_32)
+ relocation = elf_i386_dtpoff_base (info) - relocation;
+ else
+ relocation -= elf_i386_dtpoff_base (info);
+ }
+ else if (r_type == R_386_TLS_LE_32)
+ relocation = elf_i386_tpoff (info, relocation);
+ else
+ relocation = -elf_i386_tpoff (info, relocation);
+ break;
+
+ default:
+ break;
+ }
+
+ /* Dynamic relocs are not propagated for SEC_DEBUGGING sections
+ because such sections are not SEC_ALLOC and thus ld.so will
+ not process them. */
+ if (unresolved_reloc
+ && !((input_section->flags & SEC_DEBUGGING) != 0
+ && h->def_dynamic)
+ && _bfd_elf_section_offset (output_bfd, info, input_section,
+ rel->r_offset) != (bfd_vma) -1)
+ {
+ (*_bfd_error_handler)
+ (_("%B(%A+0x%lx): unresolvable %s relocation against symbol `%s'"),
+ input_bfd,
+ input_section,
+ (long) rel->r_offset,
+ howto->name,
+ h->root.root.string);
+ return FALSE;
+ }
+
+do_relocation:
+ r = _bfd_final_link_relocate (howto, input_bfd, input_section,
+ contents, rel->r_offset,
+ relocation, 0);
+
+check_relocation_error:
+ if (r != bfd_reloc_ok)
+ {
+ 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 (r == bfd_reloc_overflow)
+ {
+ if (! ((*info->callbacks->reloc_overflow)
+ (info, (h ? &h->root : NULL), name, howto->name,
+ (bfd_vma) 0, input_bfd, input_section,
+ rel->r_offset)))
+ return FALSE;
+ }
+ else
+ {
+ (*_bfd_error_handler)
+ (_("%B(%A+0x%lx): reloc against `%s': error %d"),
+ input_bfd, input_section,
+ (long) rel->r_offset, name, (int) r);
+ return FALSE;
+ }
+ }
+ }
+
+ return TRUE;
+}
+
+/* Finish up dynamic symbol handling. We set the contents of various
+ dynamic sections here. */
+
+static bfd_boolean
+elf_i386_finish_dynamic_symbol (bfd *output_bfd,
+ struct bfd_link_info *info,
+ struct elf_link_hash_entry *h,
+ Elf_Internal_Sym *sym)
+{
+ struct elf_i386_link_hash_table *htab;
+ unsigned plt_entry_size;
+ const struct elf_i386_backend_data *abed;
+
+ htab = elf_i386_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ abed = get_elf_i386_backend_data (output_bfd);
+ plt_entry_size = GET_PLT_ENTRY_SIZE (output_bfd);
+
+ if (h->plt.offset != (bfd_vma) -1)
+ {
+ bfd_vma plt_index;
+ bfd_vma got_offset;
+ Elf_Internal_Rela rel;
+ bfd_byte *loc;
+ asection *plt, *gotplt, *relplt;
+
+ /* When building a static executable, use .iplt, .igot.plt and
+ .rel.iplt sections for STT_GNU_IFUNC symbols. */
+ if (htab->elf.splt != NULL)
+ {
+ plt = htab->elf.splt;
+ gotplt = htab->elf.sgotplt;
+ relplt = htab->elf.srelplt;
+ }
+ else
+ {
+ plt = htab->elf.iplt;
+ gotplt = htab->elf.igotplt;
+ relplt = htab->elf.irelplt;
+ }
+
+ /* This symbol has an entry in the procedure linkage table. Set
+ it up. */
+
+ if ((h->dynindx == -1
+ && !((h->forced_local || info->executable)
+ && h->def_regular
+ && h->type == STT_GNU_IFUNC))
+ || plt == NULL
+ || gotplt == NULL
+ || relplt == NULL)
+ abort ();
+
+ /* 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.
+
+ 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.
+
+ For static executables, we don't reserve anything. */
+
+ if (plt == htab->elf.splt)
+ {
+ got_offset = h->plt.offset / plt_entry_size - 1;
+ got_offset = (got_offset + 3) * 4;
+ }
+ else
+ {
+ got_offset = h->plt.offset / plt_entry_size;
+ got_offset = got_offset * 4;
+ }
+
+ /* Fill in the entry in the procedure linkage table. */
+ if (! info->shared)
+ {
+ memcpy (plt->contents + h->plt.offset, abed->plt->plt_entry,
+ abed->plt->plt_entry_size);
+ bfd_put_32 (output_bfd,
+ (gotplt->output_section->vma
+ + gotplt->output_offset
+ + got_offset),
+ plt->contents + h->plt.offset
+ + abed->plt->plt_got_offset);
+
+ if (abed->is_vxworks)
+ {
+ int s, k, reloc_index;
+
+ /* Create the R_386_32 relocation referencing the GOT
+ for this PLT entry. */
+
+ /* S: Current slot number (zero-based). */
+ s = ((h->plt.offset - abed->plt->plt_entry_size)
+ / abed->plt->plt_entry_size);
+ /* K: Number of relocations for PLTResolve. */
+ if (info->shared)
+ k = PLTRESOLVE_RELOCS_SHLIB;
+ else
+ k = PLTRESOLVE_RELOCS;
+ /* Skip the PLTresolve relocations, and the relocations for
+ the other PLT slots. */
+ reloc_index = k + s * PLT_NON_JUMP_SLOT_RELOCS;
+ loc = (htab->srelplt2->contents + reloc_index
+ * sizeof (Elf32_External_Rel));
+
+ rel.r_offset = (htab->elf.splt->output_section->vma
+ + htab->elf.splt->output_offset
+ + h->plt.offset + 2),
+ rel.r_info = ELF32_R_INFO (htab->elf.hgot->indx, R_386_32);
+ bfd_elf32_swap_reloc_out (output_bfd, &rel, loc);
+
+ /* Create the R_386_32 relocation referencing the beginning of
+ the PLT for this GOT entry. */
+ rel.r_offset = (htab->elf.sgotplt->output_section->vma
+ + htab->elf.sgotplt->output_offset
+ + got_offset);
+ rel.r_info = ELF32_R_INFO (htab->elf.hplt->indx, R_386_32);
+ bfd_elf32_swap_reloc_out (output_bfd, &rel,
+ loc + sizeof (Elf32_External_Rel));
+ }
+ }
+ else
+ {
+ memcpy (plt->contents + h->plt.offset, abed->plt->pic_plt_entry,
+ abed->plt->plt_entry_size);
+ bfd_put_32 (output_bfd, got_offset,
+ plt->contents + h->plt.offset
+ + abed->plt->plt_got_offset);
+ }
+
+ /* Fill in the entry in the global offset table. */
+ bfd_put_32 (output_bfd,
+ (plt->output_section->vma
+ + plt->output_offset
+ + h->plt.offset
+ + abed->plt->plt_lazy_offset),
+ gotplt->contents + got_offset);
+
+ /* Fill in the entry in the .rel.plt section. */
+ rel.r_offset = (gotplt->output_section->vma
+ + gotplt->output_offset
+ + got_offset);
+ if (h->dynindx == -1
+ || ((info->executable
+ || ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
+ && h->def_regular
+ && h->type == STT_GNU_IFUNC))
+ {
+ /* If an STT_GNU_IFUNC symbol is locally defined, generate
+ R_386_IRELATIVE instead of R_386_JUMP_SLOT. Store addend
+ in the .got.plt section. */
+ bfd_put_32 (output_bfd,
+ (h->root.u.def.value
+ + h->root.u.def.section->output_section->vma
+ + h->root.u.def.section->output_offset),
+ gotplt->contents + got_offset);
+ rel.r_info = ELF32_R_INFO (0, R_386_IRELATIVE);
+ /* R_386_IRELATIVE comes last. */
+ plt_index = htab->next_irelative_index--;
+ }
+ else
+ {
+ rel.r_info = ELF32_R_INFO (h->dynindx, R_386_JUMP_SLOT);
+ plt_index = htab->next_jump_slot_index++;
+ }
+ loc = relplt->contents + plt_index * sizeof (Elf32_External_Rel);
+ bfd_elf32_swap_reloc_out (output_bfd, &rel, loc);
+
+ /* Don't fill PLT entry for static executables. */
+ if (plt == htab->elf.splt)
+ {
+ bfd_put_32 (output_bfd, plt_index * sizeof (Elf32_External_Rel),
+ plt->contents + h->plt.offset
+ + abed->plt->plt_reloc_offset);
+ bfd_put_32 (output_bfd, - (h->plt.offset
+ + abed->plt->plt_plt_offset + 4),
+ plt->contents + h->plt.offset
+ + abed->plt->plt_plt_offset);
+ }
+
+ if (!h->def_regular)
+ {
+ /* Mark the symbol as undefined, rather than as defined in
+ the .plt section. Leave the value if there were any
+ relocations where pointer equality matters (this is a clue
+ for the dynamic linker, to make function pointer
+ comparisons work between an application and shared
+ library), otherwise set it to zero. If a function is only
+ called from a binary, there is no need to slow down
+ shared libraries because of that. */
+ sym->st_shndx = SHN_UNDEF;
+ if (!h->pointer_equality_needed)
+ sym->st_value = 0;
+ }
+ }
+
+ if (h->got.offset != (bfd_vma) -1
+ && ! GOT_TLS_GD_ANY_P (elf_i386_hash_entry(h)->tls_type)
+ && (elf_i386_hash_entry(h)->tls_type & GOT_TLS_IE) == 0)
+ {
+ Elf_Internal_Rela rel;
+
+ /* This symbol has an entry in the global offset table. Set it
+ up. */
+
+ if (htab->elf.sgot == NULL || htab->elf.srelgot == NULL)
+ abort ();
+
+ rel.r_offset = (htab->elf.sgot->output_section->vma
+ + htab->elf.sgot->output_offset
+ + (h->got.offset & ~(bfd_vma) 1));
+
+ /* If this is a static link, or it is a -Bsymbolic link and the
+ symbol is defined locally or was forced to be local because
+ of a version file, 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 (h->def_regular
+ && h->type == STT_GNU_IFUNC)
+ {
+ if (info->shared)
+ {
+ /* Generate R_386_GLOB_DAT. */
+ goto do_glob_dat;
+ }
+ else
+ {
+ asection *plt;
+
+ if (!h->pointer_equality_needed)
+ abort ();
+
+ /* For non-shared object, we can't use .got.plt, which
+ contains the real function addres if we need pointer
+ equality. We load the GOT entry with the PLT entry. */
+ plt = htab->elf.splt ? htab->elf.splt : htab->elf.iplt;
+ bfd_put_32 (output_bfd,
+ (plt->output_section->vma
+ + plt->output_offset + h->plt.offset),
+ htab->elf.sgot->contents + h->got.offset);
+ return TRUE;
+ }
+ }
+ else if (info->shared
+ && SYMBOL_REFERENCES_LOCAL (info, h))
+ {
+ BFD_ASSERT((h->got.offset & 1) != 0);
+ rel.r_info = ELF32_R_INFO (0, R_386_RELATIVE);
+ }
+ else
+ {
+ BFD_ASSERT((h->got.offset & 1) == 0);
+do_glob_dat:
+ bfd_put_32 (output_bfd, (bfd_vma) 0,
+ htab->elf.sgot->contents + h->got.offset);
+ rel.r_info = ELF32_R_INFO (h->dynindx, R_386_GLOB_DAT);
+ }
+
+ elf_append_rel (output_bfd, htab->elf.srelgot, &rel);
+ }
+
+ if (h->needs_copy)
+ {
+ Elf_Internal_Rela rel;
+
+ /* This symbol needs a copy reloc. Set it up. */
+
+ if (h->dynindx == -1
+ || (h->root.type != bfd_link_hash_defined
+ && h->root.type != bfd_link_hash_defweak)
+ || htab->srelbss == NULL)
+ abort ();
+
+ 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);
+ elf_append_rel (output_bfd, htab->srelbss, &rel);
+ }
+
+ return TRUE;
+}
+
+/* Finish up local dynamic symbol handling. We set the contents of
+ various dynamic sections here. */
+
+static bfd_boolean
+elf_i386_finish_local_dynamic_symbol (void **slot, void *inf)
+{
+ struct elf_link_hash_entry *h
+ = (struct elf_link_hash_entry *) *slot;
+ struct bfd_link_info *info
+ = (struct bfd_link_info *) inf;
+
+ return elf_i386_finish_dynamic_symbol (info->output_bfd, info,
+ h, NULL);
+}
+
+/* Used to decide how to sort relocs in an optimal manner for the
+ dynamic linker, before writing them out. */
+
+static enum elf_reloc_type_class
+elf_i386_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ const asection *rel_sec ATTRIBUTE_UNUSED,
+ const Elf_Internal_Rela *rela)
+{
+ switch (ELF32_R_TYPE (rela->r_info))
+ {
+ case R_386_RELATIVE:
+ return reloc_class_relative;
+ case R_386_JUMP_SLOT:
+ return reloc_class_plt;
+ case R_386_COPY:
+ return reloc_class_copy;
+ default:
+ return reloc_class_normal;
+ }
+}
+
+/* Finish up the dynamic sections. */
+
+static bfd_boolean
+elf_i386_finish_dynamic_sections (bfd *output_bfd,
+ struct bfd_link_info *info)
+{
+ struct elf_i386_link_hash_table *htab;
+ bfd *dynobj;
+ asection *sdyn;
+ const struct elf_i386_backend_data *abed;
+
+ htab = elf_i386_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ dynobj = htab->elf.dynobj;
+ sdyn = bfd_get_linker_section (dynobj, ".dynamic");
+ abed = get_elf_i386_backend_data (output_bfd);
+
+ if (htab->elf.dynamic_sections_created)
+ {
+ Elf32_External_Dyn *dyncon, *dynconend;
+
+ if (sdyn == NULL || htab->elf.sgot == NULL)
+ abort ();
+
+ dyncon = (Elf32_External_Dyn *) sdyn->contents;
+ dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->size);
+ for (; dyncon < dynconend; dyncon++)
+ {
+ Elf_Internal_Dyn dyn;
+ asection *s;
+
+ bfd_elf32_swap_dyn_in (dynobj, dyncon, &dyn);
+
+ switch (dyn.d_tag)
+ {
+ default:
+ if (abed->is_vxworks
+ && elf_vxworks_finish_dynamic_entry (output_bfd, &dyn))
+ break;
+ continue;
+
+ case DT_PLTGOT:
+ s = htab->elf.sgotplt;
+ dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
+ break;
+
+ case DT_JMPREL:
+ s = htab->elf.srelplt;
+ dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
+ break;
+
+ case DT_PLTRELSZ:
+ s = htab->elf.srelplt;
+ dyn.d_un.d_val = s->size;
+ 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. */
+ s = htab->elf.srelplt;
+ if (s == NULL)
+ continue;
+ dyn.d_un.d_val -= s->size;
+ break;
+
+ case DT_REL:
+ /* We may not be using the standard ELF linker script.
+ If .rel.plt is the first .rel section, we adjust
+ DT_REL to not include it. */
+ s = htab->elf.srelplt;
+ if (s == NULL)
+ continue;
+ if (dyn.d_un.d_ptr != s->output_section->vma + s->output_offset)
+ continue;
+ dyn.d_un.d_ptr += s->size;
+ break;
+ }
+
+ bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
+ }
+
+ /* Fill in the first entry in the procedure linkage table. */
+ if (htab->elf.splt && htab->elf.splt->size > 0)
+ {
+ if (info->shared)
+ {
+ memcpy (htab->elf.splt->contents, abed->plt->pic_plt0_entry,
+ abed->plt->plt0_entry_size);
+ memset (htab->elf.splt->contents + abed->plt->plt0_entry_size,
+ abed->plt0_pad_byte,
+ abed->plt->plt_entry_size - abed->plt->plt0_entry_size);
+ }
+ else
+ {
+ memcpy (htab->elf.splt->contents, abed->plt->plt0_entry,
+ abed->plt->plt0_entry_size);
+ memset (htab->elf.splt->contents + abed->plt->plt0_entry_size,
+ abed->plt0_pad_byte,
+ abed->plt->plt_entry_size - abed->plt->plt0_entry_size);
+ bfd_put_32 (output_bfd,
+ (htab->elf.sgotplt->output_section->vma
+ + htab->elf.sgotplt->output_offset
+ + 4),
+ htab->elf.splt->contents
+ + abed->plt->plt0_got1_offset);
+ bfd_put_32 (output_bfd,
+ (htab->elf.sgotplt->output_section->vma
+ + htab->elf.sgotplt->output_offset
+ + 8),
+ htab->elf.splt->contents
+ + abed->plt->plt0_got2_offset);
+
+ if (abed->is_vxworks)
+ {
+ Elf_Internal_Rela rel;
+
+ /* Generate a relocation for _GLOBAL_OFFSET_TABLE_ + 4.
+ On IA32 we use REL relocations so the addend goes in
+ the PLT directly. */
+ rel.r_offset = (htab->elf.splt->output_section->vma
+ + htab->elf.splt->output_offset
+ + abed->plt->plt0_got1_offset);
+ rel.r_info = ELF32_R_INFO (htab->elf.hgot->indx, R_386_32);
+ bfd_elf32_swap_reloc_out (output_bfd, &rel,
+ htab->srelplt2->contents);
+ /* Generate a relocation for _GLOBAL_OFFSET_TABLE_ + 8. */
+ rel.r_offset = (htab->elf.splt->output_section->vma
+ + htab->elf.splt->output_offset
+ + abed->plt->plt0_got2_offset);
+ rel.r_info = ELF32_R_INFO (htab->elf.hgot->indx, R_386_32);
+ bfd_elf32_swap_reloc_out (output_bfd, &rel,
+ htab->srelplt2->contents +
+ sizeof (Elf32_External_Rel));
+ }
+ }
+
+ /* UnixWare sets the entsize of .plt to 4, although that doesn't
+ really seem like the right value. */
+ elf_section_data (htab->elf.splt->output_section)
+ ->this_hdr.sh_entsize = 4;
+
+ /* Correct the .rel.plt.unloaded relocations. */
+ if (abed->is_vxworks && !info->shared)
+ {
+ int num_plts = (htab->elf.splt->size
+ / abed->plt->plt_entry_size) - 1;
+ unsigned char *p;
+
+ p = htab->srelplt2->contents;
+ if (info->shared)
+ p += PLTRESOLVE_RELOCS_SHLIB * sizeof (Elf32_External_Rel);
+ else
+ p += PLTRESOLVE_RELOCS * sizeof (Elf32_External_Rel);
+
+ for (; num_plts; num_plts--)
+ {
+ Elf_Internal_Rela rel;
+ bfd_elf32_swap_reloc_in (output_bfd, p, &rel);
+ rel.r_info = ELF32_R_INFO (htab->elf.hgot->indx, R_386_32);
+ bfd_elf32_swap_reloc_out (output_bfd, &rel, p);
+ p += sizeof (Elf32_External_Rel);
+
+ bfd_elf32_swap_reloc_in (output_bfd, p, &rel);
+ rel.r_info = ELF32_R_INFO (htab->elf.hplt->indx, R_386_32);
+ bfd_elf32_swap_reloc_out (output_bfd, &rel, p);
+ p += sizeof (Elf32_External_Rel);
+ }
+ }
+ }
+ }
+
+ if (htab->elf.sgotplt)
+ {
+ if (bfd_is_abs_section (htab->elf.sgotplt->output_section))
+ {
+ (*_bfd_error_handler)
+ (_("discarded output section: `%A'"), htab->elf.sgotplt);
+ return FALSE;
+ }
+
+ /* Fill in the first three entries in the global offset table. */
+ if (htab->elf.sgotplt->size > 0)
+ {
+ bfd_put_32 (output_bfd,
+ (sdyn == NULL ? 0
+ : sdyn->output_section->vma + sdyn->output_offset),
+ htab->elf.sgotplt->contents);
+ bfd_put_32 (output_bfd, 0, htab->elf.sgotplt->contents + 4);
+ bfd_put_32 (output_bfd, 0, htab->elf.sgotplt->contents + 8);
+ }
+
+ elf_section_data (htab->elf.sgotplt->output_section)->this_hdr.sh_entsize = 4;
+ }
+
+ /* Adjust .eh_frame for .plt section. */
+ if (htab->plt_eh_frame != NULL
+ && htab->plt_eh_frame->contents != NULL)
+ {
+ if (htab->elf.splt != NULL
+ && htab->elf.splt->size != 0
+ && (htab->elf.splt->flags & SEC_EXCLUDE) == 0
+ && htab->elf.splt->output_section != NULL
+ && htab->plt_eh_frame->output_section != NULL)
+ {
+ bfd_vma plt_start = htab->elf.splt->output_section->vma;
+ bfd_vma eh_frame_start = htab->plt_eh_frame->output_section->vma
+ + htab->plt_eh_frame->output_offset
+ + PLT_FDE_START_OFFSET;
+ bfd_put_signed_32 (dynobj, plt_start - eh_frame_start,
+ htab->plt_eh_frame->contents
+ + PLT_FDE_START_OFFSET);
+ }
+ if (htab->plt_eh_frame->sec_info_type
+ == SEC_INFO_TYPE_EH_FRAME)
+ {
+ if (! _bfd_elf_write_section_eh_frame (output_bfd, info,
+ htab->plt_eh_frame,
+ htab->plt_eh_frame->contents))
+ return FALSE;
+ }
+ }
+
+ if (htab->elf.sgot && htab->elf.sgot->size > 0)
+ elf_section_data (htab->elf.sgot->output_section)->this_hdr.sh_entsize = 4;
+
+ /* Fill PLT and GOT entries for local STT_GNU_IFUNC symbols. */
+ htab_traverse (htab->loc_hash_table,
+ elf_i386_finish_local_dynamic_symbol,
+ info);
+
+ return TRUE;
+}
+
+/* Return an array of PLT entry symbol values. */
+
+static bfd_vma *
+elf_i386_get_plt_sym_val (bfd *abfd, asymbol **dynsyms, asection *plt,
+ asection *relplt)
+{
+ bfd_boolean (*slurp_relocs) (bfd *, asection *, asymbol **, bfd_boolean);
+ arelent *p;
+ long count, i;
+ bfd_vma *plt_sym_val;
+ bfd_vma plt_offset;
+ bfd_byte *plt_contents;
+ const struct elf_i386_backend_data *bed
+ = get_elf_i386_backend_data (abfd);
+ Elf_Internal_Shdr *hdr;
+
+ /* Get the .plt section contents. */
+ plt_contents = (bfd_byte *) bfd_malloc (plt->size);
+ if (plt_contents == NULL)
+ return NULL;
+ if (!bfd_get_section_contents (abfd, (asection *) plt,
+ plt_contents, 0, plt->size))
+ {
+bad_return:
+ free (plt_contents);
+ return NULL;
+ }
+
+ slurp_relocs = get_elf_backend_data (abfd)->s->slurp_reloc_table;
+ if (! (*slurp_relocs) (abfd, relplt, dynsyms, TRUE))
+ goto bad_return;
+
+ hdr = &elf_section_data (relplt)->this_hdr;
+ count = relplt->size / hdr->sh_entsize;
+
+ plt_sym_val = (bfd_vma *) bfd_malloc (sizeof (bfd_vma) * count);
+ if (plt_sym_val == NULL)
+ goto bad_return;
+
+ for (i = 0; i < count; i++, p++)
+ plt_sym_val[i] = -1;
+
+ plt_offset = bed->plt->plt_entry_size;
+ p = relplt->relocation;
+ for (i = 0; i < count; i++, p++)
+ {
+ long reloc_index;
+
+ if (p->howto->type != R_386_JUMP_SLOT
+ && p->howto->type != R_386_IRELATIVE)
+ continue;
+
+ reloc_index = H_GET_32 (abfd, (plt_contents + plt_offset
+ + bed->plt->plt_reloc_offset));
+ reloc_index /= sizeof (Elf32_External_Rel);
+ if (reloc_index >= count)
+ abort ();
+ plt_sym_val[reloc_index] = plt->vma + plt_offset;
+ plt_offset += bed->plt->plt_entry_size;
+ }
+
+ free (plt_contents);
+
+ return plt_sym_val;
+}
+
+/* Similar to _bfd_elf_get_synthetic_symtab. */
+
+static long
+elf_i386_get_synthetic_symtab (bfd *abfd,
+ long symcount,
+ asymbol **syms,
+ long dynsymcount,
+ asymbol **dynsyms,
+ asymbol **ret)
+{
+ asection *plt = bfd_get_section_by_name (abfd, ".plt");
+ return _bfd_elf_ifunc_get_synthetic_symtab (abfd, symcount, syms,
+ dynsymcount, dynsyms, ret,
+ plt,
+ elf_i386_get_plt_sym_val);
+}
+
+/* Return TRUE if symbol should be hashed in the `.gnu.hash' section. */
+
+static bfd_boolean
+elf_i386_hash_symbol (struct elf_link_hash_entry *h)
+{
+ if (h->plt.offset != (bfd_vma) -1
+ && !h->def_regular
+ && !h->pointer_equality_needed)
+ return FALSE;
+
+ return _bfd_elf_hash_symbol (h);
+}
+
+/* Hook called by the linker routine which adds symbols from an object
+ file. */
+
+static bfd_boolean
+elf_i386_add_symbol_hook (bfd * abfd,
+ struct bfd_link_info * info,
+ Elf_Internal_Sym * sym,
+ const char ** namep ATTRIBUTE_UNUSED,
+ flagword * flagsp ATTRIBUTE_UNUSED,
+ asection ** secp ATTRIBUTE_UNUSED,
+ bfd_vma * valp ATTRIBUTE_UNUSED)
+{
+ if ((ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC
+ || ELF_ST_BIND (sym->st_info) == STB_GNU_UNIQUE)
+ && (abfd->flags & DYNAMIC) == 0
+ && bfd_get_flavour (info->output_bfd) == bfd_target_elf_flavour)
+ elf_tdata (info->output_bfd)->has_gnu_symbols = TRUE;
+
+ return TRUE;
+}
+
+#define TARGET_LITTLE_SYM i386_elf32_vec
+#define TARGET_LITTLE_NAME "elf32-i386"
+#define ELF_ARCH bfd_arch_i386
+#define ELF_TARGET_ID I386_ELF_DATA
+#define ELF_MACHINE_CODE EM_386
+#define ELF_MAXPAGESIZE 0x1000
+
+#define elf_backend_can_gc_sections 1
+#define elf_backend_can_refcount 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_alignment 4
+
+/* Support RELA for objdump of prelink objects. */
+#define elf_info_to_howto elf_i386_info_to_howto_rel
+#define elf_info_to_howto_rel elf_i386_info_to_howto_rel
+
+#define bfd_elf32_mkobject elf_i386_mkobject
+
+#define bfd_elf32_bfd_is_local_label_name elf_i386_is_local_label_name
+#define bfd_elf32_bfd_link_hash_table_create elf_i386_link_hash_table_create
+#define bfd_elf32_bfd_reloc_type_lookup elf_i386_reloc_type_lookup
+#define bfd_elf32_bfd_reloc_name_lookup elf_i386_reloc_name_lookup
+#define bfd_elf32_get_synthetic_symtab elf_i386_get_synthetic_symtab
+
+#define elf_backend_adjust_dynamic_symbol elf_i386_adjust_dynamic_symbol
+#define elf_backend_relocs_compatible _bfd_elf_relocs_compatible
+#define elf_backend_check_relocs elf_i386_check_relocs
+#define elf_backend_copy_indirect_symbol elf_i386_copy_indirect_symbol
+#define elf_backend_create_dynamic_sections elf_i386_create_dynamic_sections
+#define elf_backend_fake_sections elf_i386_fake_sections
+#define elf_backend_finish_dynamic_sections elf_i386_finish_dynamic_sections
+#define elf_backend_finish_dynamic_symbol elf_i386_finish_dynamic_symbol
+#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_grok_prstatus elf_i386_grok_prstatus
+#define elf_backend_grok_psinfo elf_i386_grok_psinfo
+#define elf_backend_reloc_type_class elf_i386_reloc_type_class
+#define elf_backend_relocate_section elf_i386_relocate_section
+#define elf_backend_size_dynamic_sections elf_i386_size_dynamic_sections
+#define elf_backend_always_size_sections elf_i386_always_size_sections
+#define elf_backend_omit_section_dynsym \
+ ((bfd_boolean (*) (bfd *, struct bfd_link_info *, asection *)) bfd_true)
+#define elf_backend_hash_symbol elf_i386_hash_symbol
+#define elf_backend_add_symbol_hook elf_i386_add_symbol_hook
+
+#include "elf32-target.h"
+
+/* FreeBSD support. */
+
+#undef TARGET_LITTLE_SYM
+#define TARGET_LITTLE_SYM i386_elf32_fbsd_vec
+#undef TARGET_LITTLE_NAME
+#define TARGET_LITTLE_NAME "elf32-i386-freebsd"
+#undef ELF_OSABI
+#define ELF_OSABI ELFOSABI_FREEBSD
+
+/* The kernel recognizes executables as valid only if they carry a
+ "FreeBSD" label in the ELF header. So we put this label on all
+ executables and (for simplicity) also all other object files. */
+
+static void
+elf_i386_fbsd_post_process_headers (bfd *abfd, struct bfd_link_info *info)
+{
+ _bfd_elf_post_process_headers (abfd, info);
+
+#ifdef OLD_FREEBSD_ABI_LABEL
+ {
+ /* The ABI label supported by FreeBSD <= 4.0 is quite nonstandard. */
+ Elf_Internal_Ehdr *i_ehdrp = elf_elfheader (abfd);
+ memcpy (&i_ehdrp->e_ident[EI_ABIVERSION], "FreeBSD", 8);
+ }
+#endif
+}
+
+#undef elf_backend_post_process_headers
+#define elf_backend_post_process_headers elf_i386_fbsd_post_process_headers
+#undef elf32_bed
+#define elf32_bed elf32_i386_fbsd_bed
+
+#undef elf_backend_add_symbol_hook
+
+#include "elf32-target.h"
+
+/* Solaris 2. */
+
+#undef TARGET_LITTLE_SYM
+#define TARGET_LITTLE_SYM i386_elf32_sol2_vec
+#undef TARGET_LITTLE_NAME
+#define TARGET_LITTLE_NAME "elf32-i386-sol2"
+
+/* Restore default: we cannot use ELFOSABI_SOLARIS, otherwise ELFOSABI_NONE
+ objects won't be recognized. */
+#undef ELF_OSABI
+
+#undef elf32_bed
+#define elf32_bed elf32_i386_sol2_bed
+
+/* The 32-bit static TLS arena size is rounded to the nearest 8-byte
+ boundary. */
+#undef elf_backend_static_tls_alignment
+#define elf_backend_static_tls_alignment 8
+
+/* The Solaris 2 ABI requires a plt symbol on all platforms.
+
+ Cf. Linker and Libraries Guide, Ch. 2, Link-Editor, Generating the Output
+ File, p.63. */
+#undef elf_backend_want_plt_sym
+#define elf_backend_want_plt_sym 1
+
+#include "elf32-target.h"
+
+/* Native Client support. */
+
+#undef TARGET_LITTLE_SYM
+#define TARGET_LITTLE_SYM i386_elf32_nacl_vec
+#undef TARGET_LITTLE_NAME
+#define TARGET_LITTLE_NAME "elf32-i386-nacl"
+#undef elf32_bed
+#define elf32_bed elf32_i386_nacl_bed
+
+#undef ELF_MAXPAGESIZE
+#define ELF_MAXPAGESIZE 0x10000
+
+/* Restore defaults. */
+#undef ELF_OSABI
+#undef elf_backend_want_plt_sym
+#define elf_backend_want_plt_sym 0
+#undef elf_backend_post_process_headers
+#undef elf_backend_static_tls_alignment
+
+/* NaCl uses substantially different PLT entries for the same effects. */
+
+#undef elf_backend_plt_alignment
+#define elf_backend_plt_alignment 5
+#define NACL_PLT_ENTRY_SIZE 64
+#define NACLMASK 0xe0 /* 32-byte alignment mask. */
+
+static const bfd_byte elf_i386_nacl_plt0_entry[] =
+ {
+ 0xff, 0x35, /* pushl contents of address */
+ 0, 0, 0, 0, /* replaced with address of .got + 4. */
+ 0x8b, 0x0d, /* movl contents of address, %ecx */
+ 0, 0, 0, 0, /* replaced with address of .got + 8. */
+ 0x83, 0xe1, NACLMASK, /* andl $NACLMASK, %ecx */
+ 0xff, 0xe1 /* jmp *%ecx */
+ };
+
+static const bfd_byte elf_i386_nacl_plt_entry[NACL_PLT_ENTRY_SIZE] =
+ {
+ 0x8b, 0x0d, /* movl contents of address, %ecx */
+ 0, 0, 0, 0, /* replaced with GOT slot address. */
+ 0x83, 0xe1, NACLMASK, /* andl $NACLMASK, %ecx */
+ 0xff, 0xe1, /* jmp *%ecx */
+
+ /* Pad to the next 32-byte boundary with nop instructions. */
+ 0x90,
+ 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
+ 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
+
+ /* Lazy GOT entries point here (32-byte aligned). */
+ 0x68, /* pushl immediate */
+ 0, 0, 0, 0, /* replaced with reloc offset. */
+ 0xe9, /* jmp relative */
+ 0, 0, 0, 0, /* replaced with offset to .plt. */
+
+ /* Pad to the next 32-byte boundary with nop instructions. */
+ 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
+ 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
+ 0x90, 0x90
+ };
+
+static const bfd_byte
+elf_i386_nacl_pic_plt0_entry[sizeof (elf_i386_nacl_plt0_entry)] =
+ {
+ 0xff, 0x73, 0x04, /* pushl 4(%ebx) */
+ 0x8b, 0x4b, 0x08, /* mov 0x8(%ebx), %ecx */
+ 0x83, 0xe1, 0xe0, /* and $NACLMASK, %ecx */
+ 0xff, 0xe1, /* jmp *%ecx */
+
+ /* This is expected to be the same size as elf_i386_nacl_plt0_entry,
+ so pad to that size with nop instructions. */
+ 0x90, 0x90, 0x90, 0x90, 0x90, 0x90
+ };
+
+static const bfd_byte elf_i386_nacl_pic_plt_entry[NACL_PLT_ENTRY_SIZE] =
+ {
+ 0x8b, 0x8b, /* movl offset(%ebx), %ecx */
+ 0, 0, 0, 0, /* replaced with offset of this symbol in .got. */
+ 0x83, 0xe1, 0xe0, /* andl $NACLMASK, %ecx */
+ 0xff, 0xe1, /* jmp *%ecx */
+
+ /* Pad to the next 32-byte boundary with nop instructions. */
+ 0x90,
+ 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
+ 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
+
+ /* Lazy GOT entries point here (32-byte aligned). */
+ 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. */
+
+ /* Pad to the next 32-byte boundary with nop instructions. */
+ 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
+ 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
+ 0x90, 0x90
+ };
+
+static const bfd_byte elf_i386_nacl_eh_frame_plt[] =
+ {
+#if (PLT_CIE_LENGTH != 20 \
+ || PLT_FDE_LENGTH != 36 \
+ || PLT_FDE_START_OFFSET != 4 + PLT_CIE_LENGTH + 8 \
+ || PLT_FDE_LEN_OFFSET != 4 + PLT_CIE_LENGTH + 12)
+# error "Need elf_i386_backend_data parameters for eh_frame_plt offsets!"
+#endif
+ PLT_CIE_LENGTH, 0, 0, 0, /* CIE length */
+ 0, 0, 0, 0, /* CIE ID */
+ 1, /* CIE version */
+ 'z', 'R', 0, /* Augmentation string */
+ 1, /* Code alignment factor */
+ 0x7c, /* Data alignment factor: -4 */
+ 8, /* Return address column */
+ 1, /* Augmentation size */
+ DW_EH_PE_pcrel | DW_EH_PE_sdata4, /* FDE encoding */
+ DW_CFA_def_cfa, 4, 4, /* DW_CFA_def_cfa: r4 (esp) ofs 4 */
+ DW_CFA_offset + 8, 1, /* DW_CFA_offset: r8 (eip) at cfa-4 */
+ DW_CFA_nop, DW_CFA_nop,
+
+ PLT_FDE_LENGTH, 0, 0, 0, /* FDE length */
+ PLT_CIE_LENGTH + 8, 0, 0, 0, /* CIE pointer */
+ 0, 0, 0, 0, /* R_386_PC32 .plt goes here */
+ 0, 0, 0, 0, /* .plt size goes here */
+ 0, /* Augmentation size */
+ DW_CFA_def_cfa_offset, 8, /* DW_CFA_def_cfa_offset: 8 */
+ DW_CFA_advance_loc + 6, /* DW_CFA_advance_loc: 6 to __PLT__+6 */
+ DW_CFA_def_cfa_offset, 12, /* DW_CFA_def_cfa_offset: 12 */
+ DW_CFA_advance_loc + 58, /* DW_CFA_advance_loc: 58 to __PLT__+64 */
+ DW_CFA_def_cfa_expression, /* DW_CFA_def_cfa_expression */
+ 13, /* Block length */
+ DW_OP_breg4, 4, /* DW_OP_breg4 (esp): 4 */
+ DW_OP_breg8, 0, /* DW_OP_breg8 (eip): 0 */
+ DW_OP_const1u, 63, DW_OP_and, DW_OP_const1u, 37, DW_OP_ge,
+ DW_OP_lit2, DW_OP_shl, DW_OP_plus,
+ DW_CFA_nop, DW_CFA_nop
+ };
+
+static const struct elf_i386_plt_layout elf_i386_nacl_plt =
+ {
+ elf_i386_nacl_plt0_entry, /* plt0_entry */
+ sizeof (elf_i386_nacl_plt0_entry), /* plt0_entry_size */
+ 2, /* plt0_got1_offset */
+ 8, /* plt0_got2_offset */
+ elf_i386_nacl_plt_entry, /* plt_entry */
+ NACL_PLT_ENTRY_SIZE, /* plt_entry_size */
+ 2, /* plt_got_offset */
+ 33, /* plt_reloc_offset */
+ 38, /* plt_plt_offset */
+ 32, /* plt_lazy_offset */
+ elf_i386_nacl_pic_plt0_entry, /* pic_plt0_entry */
+ elf_i386_nacl_pic_plt_entry, /* pic_plt_entry */
+ elf_i386_nacl_eh_frame_plt, /* eh_frame_plt */
+ sizeof (elf_i386_nacl_eh_frame_plt),/* eh_frame_plt_size */
+ };
+
+static const struct elf_i386_backend_data elf_i386_nacl_arch_bed =
+ {
+ &elf_i386_nacl_plt, /* plt */
+ 0x90, /* plt0_pad_byte: nop insn */
+ 0, /* is_vxworks */
+ };
+
+static bfd_boolean
+elf32_i386_nacl_elf_object_p (bfd *abfd)
+{
+ /* Set the right machine number for a NaCl i386 ELF32 file. */
+ bfd_default_set_arch_mach (abfd, bfd_arch_i386, bfd_mach_i386_i386_nacl);
+ return TRUE;
+}
+
+#undef elf_backend_arch_data
+#define elf_backend_arch_data &elf_i386_nacl_arch_bed
+
+#undef elf_backend_object_p
+#define elf_backend_object_p elf32_i386_nacl_elf_object_p
+#undef elf_backend_modify_segment_map
+#define elf_backend_modify_segment_map nacl_modify_segment_map
+#undef elf_backend_modify_program_headers
+#define elf_backend_modify_program_headers nacl_modify_program_headers
+#undef elf_backend_final_write_processing
+#define elf_backend_final_write_processing nacl_final_write_processing
+
+#include "elf32-target.h"
+
+/* Restore defaults. */
+#undef elf_backend_object_p
+#undef elf_backend_modify_segment_map
+#undef elf_backend_modify_program_headers
+#undef elf_backend_final_write_processing
+
+/* VxWorks support. */
+
+#undef TARGET_LITTLE_SYM
+#define TARGET_LITTLE_SYM i386_elf32_vxworks_vec
+#undef TARGET_LITTLE_NAME
+#define TARGET_LITTLE_NAME "elf32-i386-vxworks"
+#undef ELF_OSABI
+#undef elf_backend_plt_alignment
+#define elf_backend_plt_alignment 4
+
+static const struct elf_i386_backend_data elf_i386_vxworks_arch_bed =
+ {
+ &elf_i386_plt, /* plt */
+ 0x90, /* plt0_pad_byte */
+ 1, /* is_vxworks */
+ };
+
+#undef elf_backend_arch_data
+#define elf_backend_arch_data &elf_i386_vxworks_arch_bed
+
+#undef elf_backend_relocs_compatible
+#undef elf_backend_add_symbol_hook
+#define elf_backend_add_symbol_hook \
+ elf_vxworks_add_symbol_hook
+#undef elf_backend_link_output_symbol_hook
+#define elf_backend_link_output_symbol_hook \
+ elf_vxworks_link_output_symbol_hook
+#undef elf_backend_emit_relocs
+#define elf_backend_emit_relocs elf_vxworks_emit_relocs
+#undef elf_backend_final_write_processing
+#define elf_backend_final_write_processing \
+ elf_vxworks_final_write_processing
+#undef elf_backend_static_tls_alignment
+
+/* On VxWorks, we emit relocations against _PROCEDURE_LINKAGE_TABLE_, so
+ define it. */
+#undef elf_backend_want_plt_sym
+#define elf_backend_want_plt_sym 1
+
+#undef elf32_bed
+#define elf32_bed elf32_i386_vxworks_bed
+
+#include "elf32-target.h"
diff --git a/bfd/elf32-i860.c b/bfd/elf32-i860.c
new file mode 100644
index 0000000..de900c1
--- /dev/null
+++ b/bfd/elf32-i860.c
@@ -0,0 +1,1268 @@
+/* Intel i860 specific support for 32-bit ELF.
+ Copyright (C) 1993-2014 Free Software Foundation, Inc.
+
+ Full i860 support contributed by Jason Eckhardt <jle@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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+#include "elf-bfd.h"
+#include "elf/i860.h"
+
+/* special_function for R_860_PC26 relocation. */
+static bfd_reloc_status_type
+i860_howto_pc26_reloc (bfd *abfd ATTRIBUTE_UNUSED,
+ arelent *reloc_entry,
+ asymbol *symbol,
+ void *data ATTRIBUTE_UNUSED,
+ asection *input_section,
+ bfd *output_bfd,
+ char **error_message ATTRIBUTE_UNUSED)
+{
+ bfd_vma insn;
+ bfd_vma relocation;
+ bfd_byte *addr;
+
+ if (output_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;
+ }
+
+ /* Used elf32-mips.c as an example. */
+ if (bfd_is_und_section (symbol->section)
+ && output_bfd == (bfd *) NULL)
+ return 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 > bfd_get_section_limit (abfd, input_section))
+ return bfd_reloc_outofrange;
+
+ /* Adjust for PC-relative relocation. */
+ relocation -= (input_section->output_section->vma
+ + input_section->output_offset
+ + reloc_entry->address
+ + 4);
+
+ /* Check for target out of range. */
+ if ((bfd_signed_vma)relocation > (0x3ffffff << 2)
+ || (bfd_signed_vma)relocation < (-0x4000000 << 2))
+ return bfd_reloc_outofrange;
+
+ addr = (bfd_byte *) data + reloc_entry->address;
+ insn = bfd_get_32 (abfd, addr);
+
+ relocation >>= reloc_entry->howto->rightshift;
+ insn = (insn & ~reloc_entry->howto->dst_mask)
+ | (relocation & reloc_entry->howto->dst_mask);
+
+ bfd_put_32 (abfd, (bfd_vma) insn, addr);
+
+ return bfd_reloc_ok;
+}
+
+/* special_function for R_860_PC16 relocation. */
+static bfd_reloc_status_type
+i860_howto_pc16_reloc (bfd *abfd,
+ arelent *reloc_entry,
+ asymbol *symbol,
+ void *data,
+ asection *input_section,
+ bfd *output_bfd,
+ char **error_message ATTRIBUTE_UNUSED)
+{
+ bfd_vma insn;
+ bfd_vma relocation;
+ bfd_byte *addr;
+
+ if (output_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;
+ }
+
+ /* Used elf32-mips.c as an example. */
+ if (bfd_is_und_section (symbol->section)
+ && output_bfd == (bfd *) NULL)
+ return 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 > bfd_get_section_limit (abfd, input_section))
+ return bfd_reloc_outofrange;
+
+ /* Adjust for PC-relative relocation. */
+ relocation -= (input_section->output_section->vma
+ + input_section->output_offset
+ + reloc_entry->address
+ + 4);
+
+ /* Check for target out of range. */
+ if ((bfd_signed_vma)relocation > (0x7fff << 2)
+ || (bfd_signed_vma)relocation < (-0x8000 << 2))
+ return bfd_reloc_outofrange;
+
+ addr = (bfd_byte *) data + reloc_entry->address;
+ insn = bfd_get_32 (abfd, addr);
+
+ relocation >>= reloc_entry->howto->rightshift;
+ relocation = (((relocation & 0xf800) << 5) | (relocation & 0x7ff))
+ & reloc_entry->howto->dst_mask;
+ insn = (insn & ~reloc_entry->howto->dst_mask) | relocation;
+
+ bfd_put_32 (abfd, (bfd_vma) insn, addr);
+
+ return bfd_reloc_ok;
+}
+
+/* special_function for R_860_HIGHADJ relocation. */
+static bfd_reloc_status_type
+i860_howto_highadj_reloc (bfd *abfd,
+ arelent *reloc_entry,
+ asymbol *symbol,
+ void *data,
+ asection *input_section,
+ bfd *output_bfd,
+ char **error_message ATTRIBUTE_UNUSED)
+{
+ bfd_vma insn;
+ bfd_vma relocation;
+ bfd_byte *addr;
+
+ if (output_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;
+ }
+
+ /* Used elf32-mips.c as an example. */
+ if (bfd_is_und_section (symbol->section)
+ && output_bfd == (bfd *) NULL)
+ return 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;
+ relocation += 0x8000;
+
+ if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
+ return bfd_reloc_outofrange;
+
+ addr = (bfd_byte *) data + reloc_entry->address;
+ insn = bfd_get_32 (abfd, addr);
+
+ relocation = ((relocation >> 16) & 0xffff);
+
+ insn = (insn & 0xffff0000) | relocation;
+
+ bfd_put_32 (abfd, (bfd_vma) insn, addr);
+
+ return bfd_reloc_ok;
+}
+
+/* special_function for R_860_SPLITn relocations. */
+static bfd_reloc_status_type
+i860_howto_splitn_reloc (bfd *abfd,
+ arelent *reloc_entry,
+ asymbol *symbol,
+ void *data,
+ asection *input_section,
+ bfd *output_bfd,
+ char **error_message ATTRIBUTE_UNUSED)
+{
+ bfd_vma insn;
+ bfd_vma relocation;
+ bfd_byte *addr;
+
+ if (output_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;
+ }
+
+ /* Used elf32-mips.c as an example. */
+ if (bfd_is_und_section (symbol->section)
+ && output_bfd == (bfd *) NULL)
+ return 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 > bfd_get_section_limit (abfd, input_section))
+ return bfd_reloc_outofrange;
+
+ addr = (bfd_byte *) data + reloc_entry->address;
+ insn = bfd_get_32 (abfd, addr);
+
+ relocation = (((relocation & 0xf800) << 5) | (relocation & 0x7ff))
+ & reloc_entry->howto->dst_mask;
+ insn = (insn & ~reloc_entry->howto->dst_mask) | relocation;
+
+ bfd_put_32 (abfd, (bfd_vma) insn, addr);
+
+ return bfd_reloc_ok;
+}
+
+/* This howto table is preliminary. */
+static reloc_howto_type elf32_i860_howto_table [] =
+{
+ /* This relocation does nothing. */
+ HOWTO (R_860_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_860_NONE", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A 32-bit absolute relocation. */
+ HOWTO (R_860_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_860_32", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_860_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_860_COPY", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_860_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_860_GLOB_DAT", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_860_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_860_JUMP_SLOT", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_860_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_860_RELATIVE", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A 26-bit PC-relative relocation. */
+ HOWTO (R_860_PC26, /* type */
+ 2, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 26, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ i860_howto_pc26_reloc, /* special_function */
+ "R_860_PC26", /* name */
+ FALSE, /* partial_inplace */
+ 0x3ffffff, /* src_mask */
+ 0x3ffffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_860_PLT26, /* type */
+ 0, /* 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_860_PLT26", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* A 16-bit PC-relative relocation. */
+ HOWTO (R_860_PC16, /* type */
+ 2, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ i860_howto_pc16_reloc, /* special_function */
+ "R_860_PC16", /* name */
+ FALSE, /* partial_inplace */
+ 0x1f07ff, /* src_mask */
+ 0x1f07ff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_860_LOW0, /* 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_860_LOW0", /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_860_SPLIT0, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ i860_howto_splitn_reloc, /* special_function */
+ "R_860_SPLIT0", /* name */
+ FALSE, /* partial_inplace */
+ 0x1f07ff, /* src_mask */
+ 0x1f07ff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_860_LOW1, /* 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_860_LOW1", /* name */
+ FALSE, /* partial_inplace */
+ 0xfffe, /* src_mask */
+ 0xfffe, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_860_SPLIT1, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ i860_howto_splitn_reloc, /* special_function */
+ "R_860_SPLIT1", /* name */
+ FALSE, /* partial_inplace */
+ 0x1f07fe, /* src_mask */
+ 0x1f07fe, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_860_LOW2, /* 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_860_LOW2", /* name */
+ FALSE, /* partial_inplace */
+ 0xfffc, /* src_mask */
+ 0xfffc, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_860_SPLIT2, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ i860_howto_splitn_reloc, /* special_function */
+ "R_860_SPLIT2", /* name */
+ FALSE, /* partial_inplace */
+ 0x1f07fc, /* src_mask */
+ 0x1f07fc, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_860_LOW3, /* 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_860_LOW3", /* name */
+ FALSE, /* partial_inplace */
+ 0xfff8, /* src_mask */
+ 0xfff8, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_860_LOGOT0, /* 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_860_LOGOT0", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_860_SPGOT0, /* 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_860_SPGOT0", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_860_LOGOT1, /* 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_860_LOGOT1", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_860_SPGOT1, /* 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_860_SPGOT1", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_860_LOGOTOFF0, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_860_LOGOTOFF0", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_860_SPGOTOFF0, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_860_SPGOTOFF0", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_860_LOGOTOFF1, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_860_LOGOTOFF1", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_860_SPGOTOFF1, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_860_SPGOTOFF1", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_860_LOGOTOFF2, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_860_LOGOTOFF2", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_860_LOGOTOFF3, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_860_LOGOTOFF3", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_860_LOPC, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_860_LOPC", /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_860_HIGHADJ, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ i860_howto_highadj_reloc, /* special_function */
+ "R_860_HIGHADJ", /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_860_HAGOT, /* 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_860_HAGOT", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_860_HAGOTOFF, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_860_HAGOTOFF", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_860_HAPC, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_860_HAPC", /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_860_HIGH, /* type */
+ 16, /* 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_860_HIGH", /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_860_HIGOT, /* 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_860_HIGOT", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_860_HIGOTOFF, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_860_HIGOTOFF", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+};
+
+static unsigned char elf_code_to_howto_index[R_860_max + 1];
+
+static reloc_howto_type *
+lookup_howto (unsigned int rtype)
+{
+ static int initialized = 0;
+ int i;
+ int howto_tbl_size = (int) (sizeof (elf32_i860_howto_table)
+ / sizeof (elf32_i860_howto_table[0]));
+
+ if (! initialized)
+ {
+ initialized = 1;
+ memset (elf_code_to_howto_index, 0xff,
+ sizeof (elf_code_to_howto_index));
+ for (i = 0; i < howto_tbl_size; i++)
+ elf_code_to_howto_index[elf32_i860_howto_table[i].type] = i;
+ }
+
+ BFD_ASSERT (rtype <= R_860_max);
+ i = elf_code_to_howto_index[rtype];
+ if (i >= howto_tbl_size)
+ return 0;
+ return elf32_i860_howto_table + i;
+}
+
+/* Given a BFD reloc, return the matching HOWTO structure. */
+static reloc_howto_type *
+elf32_i860_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ bfd_reloc_code_real_type code)
+{
+ unsigned int rtype;
+
+ switch (code)
+ {
+ case BFD_RELOC_NONE:
+ rtype = R_860_NONE;
+ break;
+ case BFD_RELOC_32:
+ rtype = R_860_32;
+ break;
+ case BFD_RELOC_860_COPY:
+ rtype = R_860_COPY;
+ break;
+ case BFD_RELOC_860_GLOB_DAT:
+ rtype = R_860_GLOB_DAT;
+ break;
+ case BFD_RELOC_860_JUMP_SLOT:
+ rtype = R_860_JUMP_SLOT;
+ break;
+ case BFD_RELOC_860_RELATIVE:
+ rtype = R_860_RELATIVE;
+ break;
+ case BFD_RELOC_860_PC26:
+ rtype = R_860_PC26;
+ break;
+ case BFD_RELOC_860_PLT26:
+ rtype = R_860_PLT26;
+ break;
+ case BFD_RELOC_860_PC16:
+ rtype = R_860_PC16;
+ break;
+ case BFD_RELOC_860_LOW0:
+ rtype = R_860_LOW0;
+ break;
+ case BFD_RELOC_860_SPLIT0:
+ rtype = R_860_SPLIT0;
+ break;
+ case BFD_RELOC_860_LOW1:
+ rtype = R_860_LOW1;
+ break;
+ case BFD_RELOC_860_SPLIT1:
+ rtype = R_860_SPLIT1;
+ break;
+ case BFD_RELOC_860_LOW2:
+ rtype = R_860_LOW2;
+ break;
+ case BFD_RELOC_860_SPLIT2:
+ rtype = R_860_SPLIT2;
+ break;
+ case BFD_RELOC_860_LOW3:
+ rtype = R_860_LOW3;
+ break;
+ case BFD_RELOC_860_LOGOT0:
+ rtype = R_860_LOGOT0;
+ break;
+ case BFD_RELOC_860_SPGOT0:
+ rtype = R_860_SPGOT0;
+ break;
+ case BFD_RELOC_860_LOGOT1:
+ rtype = R_860_LOGOT1;
+ break;
+ case BFD_RELOC_860_SPGOT1:
+ rtype = R_860_SPGOT1;
+ break;
+ case BFD_RELOC_860_LOGOTOFF0:
+ rtype = R_860_LOGOTOFF0;
+ break;
+ case BFD_RELOC_860_SPGOTOFF0:
+ rtype = R_860_SPGOTOFF0;
+ break;
+ case BFD_RELOC_860_LOGOTOFF1:
+ rtype = R_860_LOGOTOFF1;
+ break;
+ case BFD_RELOC_860_SPGOTOFF1:
+ rtype = R_860_SPGOTOFF1;
+ break;
+ case BFD_RELOC_860_LOGOTOFF2:
+ rtype = R_860_LOGOTOFF2;
+ break;
+ case BFD_RELOC_860_LOGOTOFF3:
+ rtype = R_860_LOGOTOFF3;
+ break;
+ case BFD_RELOC_860_LOPC:
+ rtype = R_860_LOPC;
+ break;
+ case BFD_RELOC_860_HIGHADJ:
+ rtype = R_860_HIGHADJ;
+ break;
+ case BFD_RELOC_860_HAGOT:
+ rtype = R_860_HAGOT;
+ break;
+ case BFD_RELOC_860_HAGOTOFF:
+ rtype = R_860_HAGOTOFF;
+ break;
+ case BFD_RELOC_860_HAPC:
+ rtype = R_860_HAPC;
+ break;
+ case BFD_RELOC_860_HIGH:
+ rtype = R_860_HIGH;
+ break;
+ case BFD_RELOC_860_HIGOT:
+ rtype = R_860_HIGOT;
+ break;
+ case BFD_RELOC_860_HIGOTOFF:
+ rtype = R_860_HIGOTOFF;
+ break;
+ default:
+ rtype = 0;
+ break;
+ }
+ return lookup_howto (rtype);
+}
+
+static reloc_howto_type *
+elf32_i860_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ const char *r_name)
+{
+ unsigned int i;
+
+ for (i = 0;
+ i < (sizeof (elf32_i860_howto_table)
+ / sizeof (elf32_i860_howto_table[0]));
+ i++)
+ if (elf32_i860_howto_table[i].name != NULL
+ && strcasecmp (elf32_i860_howto_table[i].name, r_name) == 0)
+ return &elf32_i860_howto_table[i];
+
+ return NULL;
+}
+
+/* Given a ELF reloc, return the matching HOWTO structure. */
+static void
+elf32_i860_info_to_howto_rela (bfd *abfd ATTRIBUTE_UNUSED,
+ arelent *bfd_reloc,
+ Elf_Internal_Rela *elf_reloc)
+{
+ bfd_reloc->howto
+ = lookup_howto ((unsigned) ELF32_R_TYPE (elf_reloc->r_info));
+}
+
+/* Specialized relocation handler for R_860_SPLITn. These relocations
+ involves a 16-bit field that is split into two contiguous parts. */
+static bfd_reloc_status_type
+elf32_i860_relocate_splitn (bfd *input_bfd,
+ Elf_Internal_Rela *rello,
+ bfd_byte *contents,
+ bfd_vma value)
+{
+ bfd_vma insn;
+ reloc_howto_type *howto;
+ howto = lookup_howto ((unsigned) ELF32_R_TYPE (rello->r_info));
+ insn = bfd_get_32 (input_bfd, contents + rello->r_offset);
+
+ /* Relocate. */
+ value += rello->r_addend;
+
+ /* Separate the fields and insert. */
+ value = (((value & 0xf800) << 5) | (value & 0x7ff)) & howto->dst_mask;
+ insn = (insn & ~howto->dst_mask) | value;
+
+ bfd_put_32 (input_bfd, insn, contents + rello->r_offset);
+ return bfd_reloc_ok;
+}
+
+/* Specialized relocation handler for R_860_PC16. This relocation
+ involves a 16-bit, PC-relative field that is split into two contiguous
+ parts. */
+static bfd_reloc_status_type
+elf32_i860_relocate_pc16 (bfd *input_bfd,
+ asection *input_section,
+ Elf_Internal_Rela *rello,
+ bfd_byte *contents,
+ bfd_vma value)
+{
+ bfd_vma insn;
+ reloc_howto_type *howto;
+ howto = lookup_howto ((unsigned) ELF32_R_TYPE (rello->r_info));
+ insn = bfd_get_32 (input_bfd, contents + rello->r_offset);
+
+ /* Adjust for PC-relative relocation. */
+ value -= (input_section->output_section->vma
+ + input_section->output_offset);
+ value -= rello->r_offset;
+
+ /* Relocate. */
+ value += rello->r_addend;
+
+ /* Adjust the value by 4, then separate the fields and insert. */
+ value = (value - 4) >> howto->rightshift;
+ value = (((value & 0xf800) << 5) | (value & 0x7ff)) & howto->dst_mask;
+ insn = (insn & ~howto->dst_mask) | value;
+
+ bfd_put_32 (input_bfd, insn, contents + rello->r_offset);
+ return bfd_reloc_ok;
+
+}
+
+/* Specialized relocation handler for R_860_PC26. This relocation
+ involves a 26-bit, PC-relative field which must be adjusted by 4. */
+static bfd_reloc_status_type
+elf32_i860_relocate_pc26 (bfd *input_bfd,
+ asection *input_section,
+ Elf_Internal_Rela *rello,
+ bfd_byte *contents,
+ bfd_vma value)
+{
+ bfd_vma insn;
+ reloc_howto_type *howto;
+ howto = lookup_howto ((unsigned) ELF32_R_TYPE (rello->r_info));
+ insn = bfd_get_32 (input_bfd, contents + rello->r_offset);
+
+ /* Adjust for PC-relative relocation. */
+ value -= (input_section->output_section->vma
+ + input_section->output_offset);
+ value -= rello->r_offset;
+
+ /* Relocate. */
+ value += rello->r_addend;
+
+ /* Adjust value by 4 and insert the field. */
+ value = ((value - 4) >> howto->rightshift) & howto->dst_mask;
+ insn = (insn & ~howto->dst_mask) | value;
+
+ bfd_put_32 (input_bfd, insn, contents + rello->r_offset);
+ return bfd_reloc_ok;
+
+}
+
+/* Specialized relocation handler for R_860_HIGHADJ. */
+static bfd_reloc_status_type
+elf32_i860_relocate_highadj (bfd *input_bfd,
+ Elf_Internal_Rela *rel,
+ bfd_byte *contents,
+ bfd_vma value)
+{
+ bfd_vma insn;
+
+ insn = bfd_get_32 (input_bfd, contents + rel->r_offset);
+
+ value += rel->r_addend;
+ value += 0x8000;
+ value = ((value >> 16) & 0xffff);
+
+ insn = (insn & 0xffff0000) | value;
+
+ bfd_put_32 (input_bfd, insn, contents + rel->r_offset);
+ return bfd_reloc_ok;
+}
+
+/* Perform a single relocation. By default we use the standard BFD
+ routines. However, we handle some specially. */
+static bfd_reloc_status_type
+i860_final_link_relocate (reloc_howto_type *howto,
+ bfd *input_bfd,
+ asection *input_section,
+ bfd_byte *contents,
+ Elf_Internal_Rela *rel,
+ bfd_vma relocation)
+{
+ return _bfd_final_link_relocate (howto, input_bfd, input_section,
+ contents, rel->r_offset, relocation,
+ rel->r_addend);
+}
+
+/* Relocate an i860 ELF section.
+
+ This is boiler-plate code copied from fr30.
+
+ 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 relocatable
+ 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 relocatable 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 bfd_boolean
+elf32_i860_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
+ 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);
+ r_symndx = ELF32_R_SYM (rel->r_info);
+
+ howto = lookup_howto ((unsigned) 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 = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
+
+ 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;
+ }
+ else
+ {
+ bfd_boolean unresolved_reloc, warned, ignored;
+
+ RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
+ r_symndx, symtab_hdr, sym_hashes,
+ h, sec, relocation,
+ unresolved_reloc, warned, ignored);
+ }
+
+ if (sec != NULL && discarded_section (sec))
+ RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+ rel, 1, relend, howto, 0, contents);
+
+ if (info->relocatable)
+ continue;
+
+ switch (r_type)
+ {
+ default:
+ r = i860_final_link_relocate (howto, input_bfd, input_section,
+ contents, rel, relocation);
+ break;
+
+ case R_860_HIGHADJ:
+ r = elf32_i860_relocate_highadj (input_bfd, rel, contents,
+ relocation);
+ break;
+
+ case R_860_PC16:
+ r = elf32_i860_relocate_pc16 (input_bfd, input_section, rel,
+ contents, relocation);
+ break;
+
+ case R_860_PC26:
+ r = elf32_i860_relocate_pc26 (input_bfd, input_section, rel,
+ contents, relocation);
+ break;
+
+ case R_860_SPLIT0:
+ case R_860_SPLIT1:
+ case R_860_SPLIT2:
+ r = elf32_i860_relocate_splitn (input_bfd, rel, contents,
+ relocation);
+ break;
+
+ /* We do not yet handle GOT/PLT/Dynamic relocations. */
+ case R_860_COPY:
+ case R_860_GLOB_DAT:
+ case R_860_JUMP_SLOT:
+ case R_860_RELATIVE:
+ case R_860_PLT26:
+ case R_860_LOGOT0:
+ case R_860_SPGOT0:
+ case R_860_LOGOT1:
+ case R_860_SPGOT1:
+ case R_860_LOGOTOFF0:
+ case R_860_SPGOTOFF0:
+ case R_860_LOGOTOFF1:
+ case R_860_SPGOTOFF1:
+ case R_860_LOGOTOFF2:
+ case R_860_LOGOTOFF3:
+ case R_860_LOPC:
+ case R_860_HAGOT:
+ case R_860_HAGOTOFF:
+ case R_860_HAPC:
+ case R_860_HIGOT:
+ case R_860_HIGOTOFF:
+ r = bfd_reloc_notsupported;
+ break;
+ }
+
+ if (r != bfd_reloc_ok)
+ {
+ const char * msg = (const char *) NULL;
+
+ switch (r)
+ {
+ case bfd_reloc_overflow:
+ r = info->callbacks->reloc_overflow
+ (info, (h ? &h->root : NULL), 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, TRUE);
+ 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 whether a symbol name implies a local label. SVR4/860 compilers
+ generate labels of the form ".ep.function_name" to denote the end of a
+ function prolog. These should be local.
+ ??? Do any other SVR4 compilers have this convention? If so, this should
+ be added to the generic routine. */
+static bfd_boolean
+elf32_i860_is_local_label_name (bfd *abfd, const char *name)
+{
+ if (name[0] == '.' && name[1] == 'e' && name[2] == 'p' && name[3] == '.')
+ return TRUE;
+
+ return _bfd_elf_is_local_label_name (abfd, name);
+}
+
+#define TARGET_BIG_SYM i860_elf32_vec
+#define TARGET_BIG_NAME "elf32-i860"
+#define TARGET_LITTLE_SYM i860_elf32_le_vec
+#define TARGET_LITTLE_NAME "elf32-i860-little"
+#define ELF_ARCH bfd_arch_i860
+#define ELF_MACHINE_CODE EM_860
+#define ELF_MAXPAGESIZE 4096
+
+#define elf_backend_rela_normal 1
+#define elf_info_to_howto_rel NULL
+#define elf_info_to_howto elf32_i860_info_to_howto_rela
+#define elf_backend_relocate_section elf32_i860_relocate_section
+#define bfd_elf32_bfd_reloc_type_lookup elf32_i860_reloc_type_lookup
+#define bfd_elf32_bfd_reloc_name_lookup elf32_i860_reloc_name_lookup
+#define bfd_elf32_bfd_is_local_label_name elf32_i860_is_local_label_name
+
+#include "elf32-target.h"
diff --git a/bfd/elf32-i960.c b/bfd/elf32-i960.c
new file mode 100644
index 0000000..c6fbbb8
--- /dev/null
+++ b/bfd/elf32-i960.c
@@ -0,0 +1,167 @@
+/* Intel 960 specific support for 32-bit ELF
+ Copyright (C) 1999-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+#include "elf-bfd.h"
+#include "elf/i960.h"
+
+#define USE_REL 1
+
+#define bfd_elf32_bfd_reloc_type_lookup elf32_i960_reloc_type_lookup
+#define bfd_elf32_bfd_reloc_name_lookup \
+ elf32_i960_reloc_name_lookup
+#define elf_info_to_howto elf32_i960_info_to_howto
+#define elf_info_to_howto_rel elf32_i960_info_to_howto_rel
+
+/* ELF relocs are against symbols. If we are producing relocatable
+ 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
+ relocatable output against an external symbol. */
+
+static bfd_reloc_status_type
+elf32_i960_relocate (bfd *abfd ATTRIBUTE_UNUSED,
+ arelent *reloc_entry,
+ asymbol *symbol,
+ void * data ATTRIBUTE_UNUSED,
+ asection *input_section,
+ bfd *output_bfd,
+ char **error_message ATTRIBUTE_UNUSED)
+{
+ /* HACK: I think this first condition is necessary when producing
+ relocatable output. After the end of HACK, the code is identical
+ to bfd_elf_generic_reloc(). I would _guess_ the first change
+ belongs there rather than here. martindo 1998-10-23. */
+ if (output_bfd != (bfd *) NULL
+ && reloc_entry->howto->pc_relative
+ && !reloc_entry->howto->pcrel_offset)
+ reloc_entry->addend -= symbol->value;
+
+ /* This is more dubious. */
+ else if (output_bfd != (bfd *) NULL
+ && (symbol->flags & BSF_SECTION_SYM) != 0)
+ reloc_entry->addend -= symbol->section->output_section->vma;
+
+ else
+ {
+ /* ...end of HACK. */
+ 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;
+}
+
+static reloc_howto_type elf_howto_table[]=
+{
+ HOWTO (R_960_NONE, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
+ elf32_i960_relocate, "R_960_NONE", TRUE,
+ 0x00000000, 0x00000000, FALSE),
+ EMPTY_HOWTO (1),
+ HOWTO (R_960_32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
+ elf32_i960_relocate, "R_960_32", TRUE,
+ 0xffffffff, 0xffffffff, FALSE),
+ HOWTO (R_960_IP24, 0, 2, 24, TRUE, 0, complain_overflow_signed,
+ elf32_i960_relocate, "R_960_IP24 ", TRUE,
+ 0x00ffffff, 0x00ffffff, FALSE),
+ EMPTY_HOWTO (4),
+ EMPTY_HOWTO (5),
+ EMPTY_HOWTO (6),
+ EMPTY_HOWTO (7)
+};
+
+static enum elf_i960_reloc_type
+elf32_i960_bfd_to_reloc_type (bfd_reloc_code_real_type code)
+{
+ switch (code)
+ {
+ default:
+ return R_960_NONE;
+ case BFD_RELOC_I960_CALLJ:
+ return R_960_OPTCALL;
+ case BFD_RELOC_32:
+ case BFD_RELOC_CTOR:
+ return R_960_32;
+ case BFD_RELOC_24_PCREL:
+ return R_960_IP24;
+ }
+}
+
+static void
+elf32_i960_info_to_howto (bfd * abfd ATTRIBUTE_UNUSED,
+ arelent * cache_ptr ATTRIBUTE_UNUSED,
+ Elf_Internal_Rela * dst ATTRIBUTE_UNUSED)
+{
+ abort ();
+}
+
+static void
+elf32_i960_info_to_howto_rel (bfd *abfd ATTRIBUTE_UNUSED,
+ arelent *cache_ptr,
+ Elf_Internal_Rela *dst)
+{
+ enum elf_i960_reloc_type type;
+
+ type = (enum elf_i960_reloc_type) ELF32_R_TYPE (dst->r_info);
+ BFD_ASSERT (type < R_960_max);
+
+ cache_ptr->howto = &elf_howto_table[(int) type];
+}
+
+static reloc_howto_type *
+elf32_i960_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ bfd_reloc_code_real_type code)
+{
+ return elf_howto_table + elf32_i960_bfd_to_reloc_type (code);
+}
+
+static reloc_howto_type *
+elf32_i960_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ const char *r_name)
+{
+ unsigned int i;
+
+ for (i = 0; i < sizeof (elf_howto_table) / sizeof (elf_howto_table[0]); i++)
+ if (elf_howto_table[i].name != NULL
+ && strcasecmp (elf_howto_table[i].name, r_name) == 0)
+ return &elf_howto_table[i];
+
+ return NULL;
+}
+
+#define TARGET_LITTLE_SYM i960_elf32_vec
+#define TARGET_LITTLE_NAME "elf32-i960"
+#define ELF_ARCH bfd_arch_i960
+#define ELF_MACHINE_CODE EM_960
+#define ELF_MAXPAGESIZE 1 /* FIXME: This number is wrong, It should be the page size in bytes. */
+
+#include "elf32-target.h"
diff --git a/bfd/elf32-ip2k.c b/bfd/elf32-ip2k.c
new file mode 100644
index 0000000..79e1ecc
--- /dev/null
+++ b/bfd/elf32-ip2k.c
@@ -0,0 +1,1518 @@
+/* Ubicom IP2xxx specific support for 32-bit ELF
+ Copyright (C) 2000-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+#include "elf-bfd.h"
+#include "elf/ip2k.h"
+
+/* Struct used to pass miscellaneous paramaters which
+ helps to avoid overly long parameter lists. */
+struct misc
+{
+ Elf_Internal_Shdr * symtab_hdr;
+ Elf_Internal_Rela * irelbase;
+ bfd_byte * contents;
+ Elf_Internal_Sym * isymbuf;
+};
+
+struct ip2k_opcode
+{
+ unsigned short opcode;
+ unsigned short mask;
+};
+
+static bfd_boolean ip2k_relaxed = FALSE;
+
+static const struct ip2k_opcode ip2k_page_opcode[] =
+{
+ {0x0010, 0xFFF8}, /* Page. */
+ {0x0000, 0x0000},
+};
+
+#define IS_PAGE_OPCODE(code) \
+ ip2k_is_opcode (code, ip2k_page_opcode)
+
+static const struct ip2k_opcode ip2k_jmp_opcode[] =
+{
+ {0xE000, 0xE000}, /* Jmp. */
+ {0x0000, 0x0000},
+};
+
+#define IS_JMP_OPCODE(code) \
+ ip2k_is_opcode (code, ip2k_jmp_opcode)
+
+static const struct ip2k_opcode ip2k_snc_opcode[] =
+{
+ {0xA00B, 0xFFFF}, /* Snc. */
+ {0x0000, 0x0000},
+};
+
+#define IS_SNC_OPCODE(code) \
+ ip2k_is_opcode (code, ip2k_snc_opcode)
+
+static const struct ip2k_opcode ip2k_inc_1sp_opcode[] =
+{
+ {0x2B81, 0xFFFF}, /* Inc 1(SP). */
+ {0x0000, 0x0000},
+};
+
+#define IS_INC_1SP_OPCODE(code) \
+ ip2k_is_opcode (code, ip2k_inc_1sp_opcode)
+
+static const struct ip2k_opcode ip2k_add_2sp_w_opcode[] =
+{
+ {0x1F82, 0xFFFF}, /* Add 2(SP),w. */
+ {0x0000, 0x0000},
+};
+
+#define IS_ADD_2SP_W_OPCODE(code) \
+ ip2k_is_opcode (code, ip2k_add_2sp_w_opcode)
+
+static const struct ip2k_opcode ip2k_add_w_wreg_opcode[] =
+{
+ {0x1C0A, 0xFFFF}, /* Add w,wreg. */
+ {0x1E0A, 0xFFFF}, /* Add wreg,w. */
+ {0x0000, 0x0000},
+};
+
+#define IS_ADD_W_WREG_OPCODE(code) \
+ ip2k_is_opcode (code, ip2k_add_w_wreg_opcode)
+
+static const struct ip2k_opcode ip2k_add_pcl_w_opcode[] =
+{
+ {0x1E09, 0xFFFF}, /* Add pcl,w. */
+ {0x0000, 0x0000},
+};
+
+#define IS_ADD_PCL_W_OPCODE(code) \
+ ip2k_is_opcode (code, ip2k_add_pcl_w_opcode)
+
+static const struct ip2k_opcode ip2k_skip_opcodes[] =
+{
+ {0xB000, 0xF000}, /* sb */
+ {0xA000, 0xF000}, /* snb */
+ {0x7600, 0xFE00}, /* cse/csne #lit */
+ {0x5800, 0xFC00}, /* incsnz */
+ {0x4C00, 0xFC00}, /* decsnz */
+ {0x4000, 0xFC00}, /* cse/csne */
+ {0x3C00, 0xFC00}, /* incsz */
+ {0x2C00, 0xFC00}, /* decsz */
+ {0x0000, 0x0000},
+};
+
+#define IS_SKIP_OPCODE(code) \
+ ip2k_is_opcode (code, ip2k_skip_opcodes)
+
+/* Relocation tables. */
+static reloc_howto_type ip2k_elf_howto_table [] =
+{
+#define IP2K_HOWTO(t,rs,s,bs,pr,bp,name,sm,dm) \
+ HOWTO(t, /* type */ \
+ rs, /* rightshift */ \
+ s, /* size (0 = byte, 1 = short, 2 = long) */ \
+ bs, /* bitsize */ \
+ pr, /* pc_relative */ \
+ bp, /* bitpos */ \
+ complain_overflow_dont,/* complain_on_overflow */ \
+ bfd_elf_generic_reloc,/* special_function */ \
+ name, /* name */ \
+ FALSE, /* partial_inplace */ \
+ sm, /* src_mask */ \
+ dm, /* dst_mask */ \
+ pr) /* pcrel_offset */
+
+ /* This reloc does nothing. */
+ IP2K_HOWTO (R_IP2K_NONE, 0,2,32, FALSE, 0, "R_IP2K_NONE", 0, 0),
+ /* A 16 bit absolute relocation. */
+ IP2K_HOWTO (R_IP2K_16, 0,1,16, FALSE, 0, "R_IP2K_16", 0, 0xffff),
+ /* A 32 bit absolute relocation. */
+ IP2K_HOWTO (R_IP2K_32, 0,2,32, FALSE, 0, "R_IP2K_32", 0, 0xffffffff),
+ /* A 8-bit data relocation for the FR9 field. Ninth bit is computed specially. */
+ IP2K_HOWTO (R_IP2K_FR9, 0,1,9, FALSE, 0, "R_IP2K_FR9", 0, 0x00ff),
+ /* A 4-bit data relocation. */
+ IP2K_HOWTO (R_IP2K_BANK, 8,1,4, FALSE, 0, "R_IP2K_BANK", 0, 0x000f),
+ /* A 13-bit insn relocation - word address => right-shift 1 bit extra. */
+ IP2K_HOWTO (R_IP2K_ADDR16CJP, 1,1,13, FALSE, 0, "R_IP2K_ADDR16CJP", 0, 0x1fff),
+ /* A 3-bit insn relocation - word address => right-shift 1 bit extra. */
+ IP2K_HOWTO (R_IP2K_PAGE3, 14,1,3, FALSE, 0, "R_IP2K_PAGE3", 0, 0x0007),
+ /* Two 8-bit data relocations. */
+ IP2K_HOWTO (R_IP2K_LO8DATA, 0,1,8, FALSE, 0, "R_IP2K_LO8DATA", 0, 0x00ff),
+ IP2K_HOWTO (R_IP2K_HI8DATA, 8,1,8, FALSE, 0, "R_IP2K_HI8DATA", 0, 0x00ff),
+ /* Two 8-bit insn relocations. word address => right-shift 1 bit extra. */
+ IP2K_HOWTO (R_IP2K_LO8INSN, 1,1,8, FALSE, 0, "R_IP2K_LO8INSN", 0, 0x00ff),
+ IP2K_HOWTO (R_IP2K_HI8INSN, 9,1,8, FALSE, 0, "R_IP2K_HI8INSN", 0, 0x00ff),
+
+ /* Special 1 bit relocation for SKIP instructions. */
+ IP2K_HOWTO (R_IP2K_PC_SKIP, 1,1,1, FALSE, 12, "R_IP2K_PC_SKIP", 0xfffe, 0x1000),
+ /* 16 bit word address. */
+ IP2K_HOWTO (R_IP2K_TEXT, 1,1,16, FALSE, 0, "R_IP2K_TEXT", 0, 0xffff),
+ /* A 7-bit offset relocation for the FR9 field. Eigth and ninth bit comes from insn. */
+ IP2K_HOWTO (R_IP2K_FR_OFFSET, 0,1,9, FALSE, 0, "R_IP2K_FR_OFFSET", 0x180, 0x007f),
+ /* Bits 23:16 of an address. */
+ IP2K_HOWTO (R_IP2K_EX8DATA, 16,1,8, FALSE, 0, "R_IP2K_EX8DATA", 0, 0x00ff),
+};
+
+
+/* Map BFD reloc types to IP2K ELF reloc types. */
+
+static reloc_howto_type *
+ip2k_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED,
+ bfd_reloc_code_real_type code)
+{
+ /* Note that the ip2k_elf_howto_table is indxed by the R_
+ constants. Thus, the order that the howto records appear in the
+ table *must* match the order of the relocation types defined in
+ include/elf/ip2k.h. */
+
+ switch (code)
+ {
+ case BFD_RELOC_NONE:
+ return &ip2k_elf_howto_table[ (int) R_IP2K_NONE];
+ case BFD_RELOC_16:
+ return &ip2k_elf_howto_table[ (int) R_IP2K_16];
+ case BFD_RELOC_32:
+ return &ip2k_elf_howto_table[ (int) R_IP2K_32];
+ case BFD_RELOC_IP2K_FR9:
+ return &ip2k_elf_howto_table[ (int) R_IP2K_FR9];
+ case BFD_RELOC_IP2K_BANK:
+ return &ip2k_elf_howto_table[ (int) R_IP2K_BANK];
+ case BFD_RELOC_IP2K_ADDR16CJP:
+ return &ip2k_elf_howto_table[ (int) R_IP2K_ADDR16CJP];
+ case BFD_RELOC_IP2K_PAGE3:
+ return &ip2k_elf_howto_table[ (int) R_IP2K_PAGE3];
+ case BFD_RELOC_IP2K_LO8DATA:
+ return &ip2k_elf_howto_table[ (int) R_IP2K_LO8DATA];
+ case BFD_RELOC_IP2K_HI8DATA:
+ return &ip2k_elf_howto_table[ (int) R_IP2K_HI8DATA];
+ case BFD_RELOC_IP2K_LO8INSN:
+ return &ip2k_elf_howto_table[ (int) R_IP2K_LO8INSN];
+ case BFD_RELOC_IP2K_HI8INSN:
+ return &ip2k_elf_howto_table[ (int) R_IP2K_HI8INSN];
+ case BFD_RELOC_IP2K_PC_SKIP:
+ return &ip2k_elf_howto_table[ (int) R_IP2K_PC_SKIP];
+ case BFD_RELOC_IP2K_TEXT:
+ return &ip2k_elf_howto_table[ (int) R_IP2K_TEXT];
+ case BFD_RELOC_IP2K_FR_OFFSET:
+ return &ip2k_elf_howto_table[ (int) R_IP2K_FR_OFFSET];
+ case BFD_RELOC_IP2K_EX8DATA:
+ return &ip2k_elf_howto_table[ (int) R_IP2K_EX8DATA];
+ default:
+ /* Pacify gcc -Wall. */
+ return NULL;
+ }
+ return NULL;
+}
+
+static reloc_howto_type *
+ip2k_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, const char *r_name)
+{
+ unsigned int i;
+
+ for (i = 0;
+ i < sizeof (ip2k_elf_howto_table) / sizeof (ip2k_elf_howto_table[0]);
+ i++)
+ if (ip2k_elf_howto_table[i].name != NULL
+ && strcasecmp (ip2k_elf_howto_table[i].name, r_name) == 0)
+ return &ip2k_elf_howto_table[i];
+
+ return NULL;
+}
+
+static void
+ip2k_get_mem (bfd *abfd ATTRIBUTE_UNUSED,
+ bfd_byte *addr,
+ int length,
+ bfd_byte *ptr)
+{
+ while (length --)
+ * ptr ++ = bfd_get_8 (abfd, addr ++);
+}
+
+static bfd_boolean
+ip2k_is_opcode (bfd_byte *code, const struct ip2k_opcode *opcodes)
+{
+ unsigned short insn = (code[0] << 8) | code[1];
+
+ while (opcodes->mask != 0)
+ {
+ if ((insn & opcodes->mask) == opcodes->opcode)
+ return TRUE;
+
+ opcodes ++;
+ }
+
+ return FALSE;
+}
+
+#define PAGENO(ABSADDR) ((ABSADDR) & 0xFFFFC000)
+#define BASEADDR(SEC) ((SEC)->output_section->vma + (SEC)->output_offset)
+
+#define UNDEFINED_SYMBOL (~(bfd_vma)0)
+
+/* Return the value of the symbol associated with the relocation IREL. */
+
+static bfd_vma
+symbol_value (bfd *abfd,
+ Elf_Internal_Shdr *symtab_hdr,
+ Elf_Internal_Sym *isymbuf,
+ Elf_Internal_Rela *irel)
+{
+ if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
+ {
+ Elf_Internal_Sym *isym;
+ asection *sym_sec;
+
+ isym = isymbuf + ELF32_R_SYM (irel->r_info);
+ if (isym->st_shndx == SHN_UNDEF)
+ sym_sec = bfd_und_section_ptr;
+ 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;
+ else
+ sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
+
+ return isym->st_value + BASEADDR (sym_sec);
+ }
+ else
+ {
+ unsigned long indx;
+ struct elf_link_hash_entry *h;
+
+ 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)
+ return UNDEFINED_SYMBOL;
+
+ return (h->root.u.def.value + BASEADDR (h->root.u.def.section));
+ }
+}
+
+/* Determine if the instruction sequence matches that for
+ the prologue of a switch dispatch table with fewer than
+ 128 entries.
+
+ sc
+ page $nnn0
+ jmp $nnn0
+ add w,wreg
+ add pcl,w
+ addr=>
+ page $nnn1
+ jmp $nnn1
+ page $nnn2
+ jmp $nnn2
+ ...
+ page $nnnN
+ jmp $nnnN
+
+ After relaxation.
+ sc
+ page $nnn0
+ jmp $nnn0
+ add pcl,w
+ addr=>
+ jmp $nnn1
+ jmp $nnn2
+ ...
+ jmp $nnnN */
+
+static int
+ip2k_is_switch_table_128 (bfd *abfd ATTRIBUTE_UNUSED,
+ asection *sec,
+ bfd_vma addr,
+ bfd_byte *contents)
+{
+ bfd_byte code[4];
+ int table_index = 0;
+
+ /* Check current page-jmp. */
+ if (addr + 4 > sec->size)
+ return -1;
+
+ ip2k_get_mem (abfd, contents + addr, 4, code);
+
+ if ((! IS_PAGE_OPCODE (code + 0))
+ || (! IS_JMP_OPCODE (code + 2)))
+ return -1;
+
+ /* Search back. */
+ while (1)
+ {
+ if (addr < 4)
+ return -1;
+
+ /* Check previous 2 instructions. */
+ ip2k_get_mem (abfd, contents + addr - 4, 4, code);
+ if ((IS_ADD_W_WREG_OPCODE (code + 0))
+ && (IS_ADD_PCL_W_OPCODE (code + 2)))
+ return table_index;
+
+ if ((! IS_PAGE_OPCODE (code + 0))
+ || (! IS_JMP_OPCODE (code + 2)))
+ return -1;
+
+ table_index++;
+ addr -= 4;
+ }
+}
+
+/* Determine if the instruction sequence matches that for
+ the prologue switch dispatch table with fewer than
+ 256 entries but more than 127.
+
+ Before relaxation.
+ push %lo8insn(label) ; Push address of table
+ push %hi8insn(label)
+ add w,wreg ; index*2 => offset
+ snc ; CARRY SET?
+ inc 1(sp) ; Propagate MSB into table address
+ add 2(sp),w ; Add low bits of offset to table address
+ snc ; and handle any carry-out
+ inc 1(sp)
+ addr=>
+ page __indjmp ; Do an indirect jump to that location
+ jmp __indjmp
+ label: ; case dispatch table starts here
+ page $nnn1
+ jmp $nnn1
+ page $nnn2
+ jmp $nnn2
+ ...
+ page $nnnN
+ jmp $nnnN
+
+ After relaxation.
+ push %lo8insn(label) ; Push address of table
+ push %hi8insn(label)
+ add 2(sp),w ; Add low bits of offset to table address
+ snc ; and handle any carry-out
+ inc 1(sp)
+ addr=>
+ page __indjmp ; Do an indirect jump to that location
+ jmp __indjmp
+ label: ; case dispatch table starts here
+ jmp $nnn1
+ jmp $nnn2
+ ...
+ jmp $nnnN */
+
+static int
+ip2k_is_switch_table_256 (bfd *abfd ATTRIBUTE_UNUSED,
+ asection *sec,
+ bfd_vma addr,
+ bfd_byte *contents)
+{
+ bfd_byte code[16];
+ int table_index = 0;
+
+ /* Check current page-jmp. */
+ if (addr + 4 > sec->size)
+ return -1;
+
+ ip2k_get_mem (abfd, contents + addr, 4, code);
+ if ((! IS_PAGE_OPCODE (code + 0))
+ || (! IS_JMP_OPCODE (code + 2)))
+ return -1;
+
+ /* Search back. */
+ while (1)
+ {
+ if (addr < 16)
+ return -1;
+
+ /* Check previous 8 instructions. */
+ ip2k_get_mem (abfd, contents + addr - 16, 16, code);
+ if ((IS_ADD_W_WREG_OPCODE (code + 0))
+ && (IS_SNC_OPCODE (code + 2))
+ && (IS_INC_1SP_OPCODE (code + 4))
+ && (IS_ADD_2SP_W_OPCODE (code + 6))
+ && (IS_SNC_OPCODE (code + 8))
+ && (IS_INC_1SP_OPCODE (code + 10))
+ && (IS_PAGE_OPCODE (code + 12))
+ && (IS_JMP_OPCODE (code + 14)))
+ return table_index;
+
+ if ((IS_ADD_W_WREG_OPCODE (code + 2))
+ && (IS_SNC_OPCODE (code + 4))
+ && (IS_INC_1SP_OPCODE (code + 6))
+ && (IS_ADD_2SP_W_OPCODE (code + 8))
+ && (IS_SNC_OPCODE (code + 10))
+ && (IS_INC_1SP_OPCODE (code + 12))
+ && (IS_JMP_OPCODE (code + 14)))
+ return table_index;
+
+ if ((! IS_PAGE_OPCODE (code + 0))
+ || (! IS_JMP_OPCODE (code + 2)))
+ return -1;
+
+ table_index++;
+ addr -= 4;
+ }
+}
+
+/* Returns the expected page state for the given instruction not including
+ the effect of page instructions. */
+
+static bfd_vma
+ip2k_nominal_page_bits (bfd *abfd ATTRIBUTE_UNUSED,
+ asection *sec,
+ bfd_vma addr,
+ bfd_byte *contents)
+{
+ bfd_vma page = PAGENO (BASEADDR (sec) + addr);
+
+ /* Check if section flows into this page. If not then the page
+ bits are assumed to match the PC. This will be true unless
+ the user has a page instruction without a call/jump, in which
+ case they are on their own. */
+ if (PAGENO (BASEADDR (sec)) == page)
+ return page;
+
+ /* Section flows across page boundary. The page bits should match
+ the PC unless there is a possible flow from the previous page,
+ in which case it is not possible to determine the value of the
+ page bits. */
+ while (PAGENO (BASEADDR (sec) + addr - 2) == page)
+ {
+ bfd_byte code[2];
+
+ addr -= 2;
+ ip2k_get_mem (abfd, contents + addr, 2, code);
+ if (!IS_PAGE_OPCODE (code))
+ continue;
+
+ /* Found a page instruction, check if jump table. */
+ if (ip2k_is_switch_table_128 (abfd, sec, addr, contents) != -1)
+ /* Jump table => page is conditional. */
+ continue;
+
+ if (ip2k_is_switch_table_256 (abfd, sec, addr, contents) != -1)
+ /* Jump table => page is conditional. */
+ continue;
+
+ /* Found a page instruction, check if conditional. */
+ if (addr >= 2)
+ {
+ ip2k_get_mem (abfd, contents + addr - 2, 2, code);
+ if (IS_SKIP_OPCODE (code))
+ /* Page is conditional. */
+ continue;
+ }
+
+ /* Unconditional page instruction => page bits should be correct. */
+ return page;
+ }
+
+ /* Flow from previous page => page bits are impossible to determine. */
+ return 0;
+}
+
+static bfd_boolean
+ip2k_test_page_insn (bfd *abfd ATTRIBUTE_UNUSED,
+ asection *sec,
+ Elf_Internal_Rela *irel,
+ struct misc *misc)
+{
+ bfd_vma symval;
+
+ /* Get the value of the symbol referred to by the reloc. */
+ symval = symbol_value (abfd, misc->symtab_hdr, misc->isymbuf, irel);
+ if (symval == UNDEFINED_SYMBOL)
+ /* This appears to be a reference to an undefined
+ symbol. Just ignore it--it will be caught by the
+ regular reloc processing. */
+ return FALSE;
+
+ /* Test if we can delete this page instruction. */
+ if (PAGENO (symval + irel->r_addend) !=
+ ip2k_nominal_page_bits (abfd, sec, irel->r_offset, misc->contents))
+ return FALSE;
+
+ return TRUE;
+}
+
+/* Parts of a Stabs entry. */
+
+#define STRDXOFF 0
+#define TYPEOFF 4
+#define OTHEROFF 5
+#define DESCOFF 6
+#define VALOFF 8
+#define STABSIZE 12
+
+/* Adjust all the relocations entries after adding or inserting instructions. */
+
+static void
+adjust_all_relocations (bfd *abfd,
+ asection *sec,
+ bfd_vma addr,
+ bfd_vma endaddr,
+ int count,
+ int noadj)
+{
+ Elf_Internal_Shdr *symtab_hdr;
+ Elf_Internal_Sym *isymbuf, *isym, *isymend;
+ unsigned int shndx;
+ Elf_Internal_Rela *irel, *irelend, *irelbase;
+ struct elf_link_hash_entry **sym_hashes;
+ struct elf_link_hash_entry **end_hashes;
+ unsigned int symcount;
+ asection *stab;
+
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+ isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
+
+ shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
+
+ irelbase = elf_section_data (sec)->relocs;
+ irelend = irelbase + sec->reloc_count;
+
+ for (irel = irelbase; irel < irelend; irel++)
+ {
+ if (ELF32_R_TYPE (irel->r_info) != R_IP2K_NONE)
+ {
+ /* Get the value of the symbol referred to by the reloc. */
+ if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
+ {
+ asection *sym_sec;
+
+ /* A local symbol. */
+ isym = isymbuf + ELF32_R_SYM (irel->r_info);
+ sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
+
+ if (isym->st_shndx == shndx)
+ {
+ bfd_vma baseaddr = BASEADDR (sec);
+ bfd_vma symval = BASEADDR (sym_sec) + isym->st_value
+ + irel->r_addend;
+
+ if ((baseaddr + addr + noadj) <= symval
+ && symval < (baseaddr + endaddr))
+ irel->r_addend += count;
+ }
+ }
+ }
+
+ /* Do this only for PC space relocations. */
+ if (addr <= irel->r_offset && irel->r_offset < endaddr)
+ irel->r_offset += count;
+ }
+
+ /* Now fix the stab relocations. */
+ stab = bfd_get_section_by_name (abfd, ".stab");
+ if (stab)
+ {
+ bfd_byte *stabcontents, *stabend, *stabp;
+ bfd_size_type stab_size = stab->rawsize ? stab->rawsize : stab->size;
+
+ irelbase = elf_section_data (stab)->relocs;
+ irelend = irelbase + stab->reloc_count;
+
+ /* Pull out the contents of the stab section. */
+ if (elf_section_data (stab)->this_hdr.contents != NULL)
+ stabcontents = elf_section_data (stab)->this_hdr.contents;
+ else
+ {
+ if (!bfd_malloc_and_get_section (abfd, stab, &stabcontents))
+ {
+ if (stabcontents != NULL)
+ free (stabcontents);
+ return;
+ }
+
+ /* We need to remember this. */
+ elf_section_data (stab)->this_hdr.contents = stabcontents;
+ }
+
+ stabend = stabcontents + stab_size;
+
+ for (irel = irelbase; irel < irelend; irel++)
+ {
+ if (ELF32_R_TYPE (irel->r_info) != R_IP2K_NONE)
+ {
+ /* Get the value of the symbol referred to by the reloc. */
+ if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
+ {
+ asection *sym_sec;
+
+ /* A local symbol. */
+ isym = isymbuf + ELF32_R_SYM (irel->r_info);
+ sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
+
+ if (sym_sec == sec)
+ {
+ const char *name;
+ unsigned char type;
+ bfd_vma value;
+ bfd_vma baseaddr = BASEADDR (sec);
+ bfd_vma symval = BASEADDR (sym_sec) + isym->st_value
+ + irel->r_addend;
+
+ if ((baseaddr + addr) <= symval
+ && symval <= (baseaddr + endaddr))
+ irel->r_addend += count;
+
+ /* Go hunt up a function and fix its line info if needed. */
+ stabp = stabcontents + irel->r_offset - 8;
+
+ /* Go pullout the stab entry. */
+ type = bfd_h_get_8 (abfd, stabp + TYPEOFF);
+ value = bfd_h_get_32 (abfd, stabp + VALOFF);
+
+ name = bfd_get_stab_name (type);
+
+ if (strcmp (name, "FUN") == 0)
+ {
+ int function_adjusted = 0;
+
+ if (symval > (baseaddr + addr))
+ /* Not in this function. */
+ continue;
+
+ /* Hey we got a function hit. */
+ stabp += STABSIZE;
+ for (;stabp < stabend; stabp += STABSIZE)
+ {
+ /* Go pullout the stab entry. */
+ type = bfd_h_get_8 (abfd, stabp + TYPEOFF);
+ value = bfd_h_get_32 (abfd, stabp + VALOFF);
+
+ name = bfd_get_stab_name (type);
+
+ if (strcmp (name, "FUN") == 0)
+ {
+ /* Hit another function entry. */
+ if (function_adjusted)
+ {
+ /* Adjust the value. */
+ value += count;
+
+ /* We need to put it back. */
+ bfd_h_put_32 (abfd, value,stabp + VALOFF);
+ }
+
+ /* And then bale out. */
+ break;
+ }
+
+ if (strcmp (name, "SLINE") == 0)
+ {
+ /* Got a line entry. */
+ if ((baseaddr + addr) <= (symval + value))
+ {
+ /* Adjust the line entry. */
+ value += count;
+
+ /* We need to put it back. */
+ bfd_h_put_32 (abfd, value,stabp + VALOFF);
+ function_adjusted = 1;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /* When adding an instruction back it is sometimes necessary to move any
+ global or local symbol that was referencing the first instruction of
+ the moved block to refer to the first instruction of the inserted block.
+
+ For example adding a PAGE instruction before a CALL or JMP requires
+ that any label on the CALL or JMP is moved to the PAGE insn. */
+ addr += noadj;
+
+ /* Adjust the local symbols defined in this section. */
+ isymend = isymbuf + symtab_hdr->sh_info;
+ for (isym = isymbuf; isym < isymend; isym++)
+ {
+ if (isym->st_shndx == shndx
+ && addr <= isym->st_value
+ && isym->st_value < endaddr)
+ isym->st_value += count;
+ }
+
+ /* Now adjust the global symbols defined in this section. */
+ symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
+ - symtab_hdr->sh_info);
+ sym_hashes = elf_sym_hashes (abfd);
+ end_hashes = sym_hashes + symcount;
+ for (; sym_hashes < end_hashes; sym_hashes++)
+ {
+ struct elf_link_hash_entry *sym_hash = *sym_hashes;
+
+ if ((sym_hash->root.type == bfd_link_hash_defined
+ || sym_hash->root.type == bfd_link_hash_defweak)
+ && sym_hash->root.u.def.section == sec)
+ {
+ if (addr <= sym_hash->root.u.def.value
+ && sym_hash->root.u.def.value < endaddr)
+ sym_hash->root.u.def.value += count;
+ }
+ }
+
+ return;
+}
+
+/* Delete some bytes from a section while relaxing. */
+
+static bfd_boolean
+ip2k_elf_relax_delete_bytes (bfd *abfd,
+ asection *sec,
+ bfd_vma addr,
+ int count)
+{
+ bfd_byte *contents = elf_section_data (sec)->this_hdr.contents;
+ bfd_vma endaddr = sec->size;
+
+ /* Actually delete the bytes. */
+ memmove (contents + addr, contents + addr + count,
+ endaddr - addr - count);
+
+ sec->size -= count;
+
+ adjust_all_relocations (abfd, sec, addr + count, endaddr, -count, 0);
+ return TRUE;
+}
+
+static bfd_boolean
+ip2k_delete_page_insn (bfd *abfd ATTRIBUTE_UNUSED,
+ asection *sec,
+ Elf_Internal_Rela *irel,
+ bfd_boolean *again,
+ struct misc *misc)
+{
+ /* Note that we've changed the relocs, section contents, etc. */
+ elf_section_data (sec)->relocs = misc->irelbase;
+ elf_section_data (sec)->this_hdr.contents = misc->contents;
+ misc->symtab_hdr->contents = (bfd_byte *) misc->isymbuf;
+
+ /* Fix the relocation's type. */
+ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info), R_IP2K_NONE);
+
+ /* Delete the PAGE insn. */
+ if (!ip2k_elf_relax_delete_bytes (abfd, sec, irel->r_offset, 2))
+ return FALSE;
+
+ /* Modified => will need to iterate relaxation again. */
+ *again = TRUE;
+
+ return TRUE;
+}
+
+static bfd_boolean
+ip2k_relax_switch_table_128 (bfd *abfd ATTRIBUTE_UNUSED,
+ asection *sec,
+ Elf_Internal_Rela *irel,
+ bfd_boolean *again,
+ struct misc *misc)
+{
+ Elf_Internal_Rela *irelend = misc->irelbase + sec->reloc_count;
+ Elf_Internal_Rela *ireltest = irel;
+ bfd_byte code[4];
+ bfd_vma addr;
+
+ /* Test all page instructions. */
+ addr = irel->r_offset;
+ while (1)
+ {
+ if (addr + 4 > sec->size)
+ break;
+
+ ip2k_get_mem (abfd, misc->contents + addr, 4, code);
+ if ((! IS_PAGE_OPCODE (code + 0))
+ || (! IS_JMP_OPCODE (code + 2)))
+ break;
+
+ /* Validate relocation entry (every entry should have a matching
+ relocation entry). */
+ if (ireltest >= irelend)
+ {
+ _bfd_error_handler (_("ip2k relaxer: switch table without complete matching relocation information."));
+ return FALSE;
+ }
+
+ if (ireltest->r_offset != addr)
+ {
+ _bfd_error_handler (_("ip2k relaxer: switch table without complete matching relocation information."));
+ return FALSE;
+ }
+
+ if (! ip2k_test_page_insn (abfd, sec, ireltest, misc))
+ /* Un-removable page insn => nothing can be done. */
+ return TRUE;
+
+ addr += 4;
+ ireltest += 2;
+ }
+
+ /* Relaxable. Adjust table header. */
+ ip2k_get_mem (abfd, misc->contents + irel->r_offset - 4, 4, code);
+ if ((! IS_ADD_W_WREG_OPCODE (code + 0))
+ || (! IS_ADD_PCL_W_OPCODE (code + 2)))
+ {
+ _bfd_error_handler (_("ip2k relaxer: switch table header corrupt."));
+ return FALSE;
+ }
+
+ if (!ip2k_elf_relax_delete_bytes (abfd, sec, irel->r_offset - 4, 2))
+ return FALSE;
+
+ *again = TRUE;
+
+ /* Delete all page instructions in table. */
+ while (irel < ireltest)
+ {
+ if (!ip2k_delete_page_insn (abfd, sec, irel, again, misc))
+ return FALSE;
+ irel += 2;
+ }
+
+ return TRUE;
+}
+
+static bfd_boolean
+ip2k_relax_switch_table_256 (bfd *abfd ATTRIBUTE_UNUSED,
+ asection *sec,
+ Elf_Internal_Rela *irel,
+ bfd_boolean *again,
+ struct misc *misc)
+{
+ Elf_Internal_Rela *irelend = misc->irelbase + sec->reloc_count;
+ Elf_Internal_Rela *ireltest = irel;
+ bfd_byte code[12];
+ bfd_vma addr;
+
+ /* Test all page instructions. */
+ addr = irel->r_offset;
+
+ while (1)
+ {
+ if (addr + 4 > sec->size)
+ break;
+
+ ip2k_get_mem (abfd, misc->contents + addr, 4, code);
+
+ if ((! IS_PAGE_OPCODE (code + 0))
+ || (! IS_JMP_OPCODE (code + 2)))
+ break;
+
+ /* Validate relocation entry (every entry should have a matching
+ relocation entry). */
+ if (ireltest >= irelend)
+ {
+ _bfd_error_handler (_("ip2k relaxer: switch table without complete matching relocation information."));
+ return FALSE;
+ }
+
+ if (ireltest->r_offset != addr)
+ {
+ _bfd_error_handler (_("ip2k relaxer: switch table without complete matching relocation information."));
+ return FALSE;
+ }
+
+ if (!ip2k_test_page_insn (abfd, sec, ireltest, misc))
+ /* Un-removable page insn => nothing can be done. */
+ return TRUE;
+
+ addr += 4;
+ ireltest += 2;
+ }
+
+ /* Relaxable. Adjust table header. */
+ ip2k_get_mem (abfd, misc->contents + irel->r_offset - 4, 2, code);
+ if (IS_PAGE_OPCODE (code))
+ addr = irel->r_offset - 16;
+ else
+ addr = irel->r_offset - 14;
+
+ ip2k_get_mem (abfd, misc->contents + addr, 12, code);
+ if ((!IS_ADD_W_WREG_OPCODE (code + 0))
+ || (!IS_SNC_OPCODE (code + 2))
+ || (!IS_INC_1SP_OPCODE (code + 4))
+ || (!IS_ADD_2SP_W_OPCODE (code + 6))
+ || (!IS_SNC_OPCODE (code + 8))
+ || (!IS_INC_1SP_OPCODE (code + 10)))
+ {
+ _bfd_error_handler (_("ip2k relaxer: switch table header corrupt."));
+ return FALSE;
+ }
+
+ /* Delete first 3 opcodes. */
+ if (!ip2k_elf_relax_delete_bytes (abfd, sec, addr + 0, 6))
+ return FALSE;
+
+ *again = TRUE;
+
+ /* Delete all page instructions in table. */
+ while (irel < ireltest)
+ {
+ if (!ip2k_delete_page_insn (abfd, sec, irel, again, misc))
+ return FALSE;
+ irel += 2;
+ }
+
+ return TRUE;
+}
+
+/* This function handles relaxation of a section in a specific page. */
+
+static bfd_boolean
+ip2k_elf_relax_section_page (bfd *abfd,
+ asection *sec,
+ bfd_boolean *again,
+ struct misc *misc,
+ unsigned long page_start,
+ unsigned long page_end)
+{
+ Elf_Internal_Rela *irelend = misc->irelbase + sec->reloc_count;
+ Elf_Internal_Rela *irel;
+ int switch_table_128;
+ int switch_table_256;
+
+ /* Walk thru the section looking for relaxation opportunities. */
+ for (irel = misc->irelbase; irel < irelend; irel++)
+ {
+ if (ELF32_R_TYPE (irel->r_info) != (int) R_IP2K_PAGE3)
+ /* Ignore non page instructions. */
+ continue;
+
+ if (BASEADDR (sec) + irel->r_offset < page_start)
+ /* Ignore page instructions on earlier page - they have
+ already been processed. Remember that there is code flow
+ that crosses a page boundary. */
+ continue;
+
+ if (BASEADDR (sec) + irel->r_offset > page_end)
+ /* Flow beyond end of page => nothing more to do for this page. */
+ return TRUE;
+
+ /* Detect switch tables. */
+ switch_table_128 = ip2k_is_switch_table_128 (abfd, sec, irel->r_offset, misc->contents);
+ switch_table_256 = ip2k_is_switch_table_256 (abfd, sec, irel->r_offset, misc->contents);
+
+ if ((switch_table_128 > 0) || (switch_table_256 > 0))
+ /* If the index is greater than 0 then it has already been processed. */
+ continue;
+
+ if (switch_table_128 == 0)
+ {
+ if (!ip2k_relax_switch_table_128 (abfd, sec, irel, again, misc))
+ return FALSE;
+
+ continue;
+ }
+
+ if (switch_table_256 == 0)
+ {
+ if (!ip2k_relax_switch_table_256 (abfd, sec, irel, again, misc))
+ return FALSE;
+
+ continue;
+ }
+
+ /* Simple relax. */
+ if (ip2k_test_page_insn (abfd, sec, irel, misc))
+ {
+ if (!ip2k_delete_page_insn (abfd, sec, irel, again, misc))
+ return FALSE;
+
+ continue;
+ }
+ }
+
+ return TRUE;
+}
+
+/* This function handles relaxing for the ip2k.
+
+ Principle: Start with the first page and remove page instructions that
+ are not require on this first page. By removing page instructions more
+ code will fit into this page - repeat until nothing more can be achieved
+ for this page. Move on to the next page.
+
+ Processing the pages one at a time from the lowest page allows a removal
+ only policy to be used - pages can be removed but are never reinserted. */
+
+static bfd_boolean
+ip2k_elf_relax_section (bfd *abfd,
+ asection *sec,
+ struct bfd_link_info *link_info,
+ bfd_boolean *again)
+{
+ Elf_Internal_Shdr *symtab_hdr;
+ Elf_Internal_Rela *internal_relocs;
+ bfd_byte *contents = NULL;
+ Elf_Internal_Sym *isymbuf = NULL;
+ static asection * first_section = NULL;
+ static unsigned long search_addr;
+ static unsigned long page_start = 0;
+ static unsigned long page_end = 0;
+ static unsigned int pass = 0;
+ static bfd_boolean new_pass = FALSE;
+ static bfd_boolean changed = FALSE;
+ struct misc misc;
+
+ /* Assume nothing changes. */
+ *again = FALSE;
+
+ if (first_section == NULL)
+ {
+ ip2k_relaxed = TRUE;
+ first_section = sec;
+ }
+
+ if (first_section == sec)
+ {
+ pass++;
+ new_pass = TRUE;
+ }
+
+ /* We don't have to do anything for a relocatable link,
+ if this section does not have relocs, or if this is
+ not a code section. */
+ if (link_info->relocatable
+ || (sec->flags & SEC_RELOC) == 0
+ || sec->reloc_count == 0
+ || (sec->flags & SEC_CODE) == 0)
+ return TRUE;
+
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+
+ internal_relocs = _bfd_elf_link_read_relocs (abfd, sec, NULL, NULL,
+ link_info->keep_memory);
+ if (internal_relocs == NULL)
+ goto error_return;
+
+ /* Get section contents cached copy if it exists. */
+ 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. */
+ if (!bfd_malloc_and_get_section (abfd, sec, &contents))
+ goto error_return;
+ }
+ }
+
+ /* Read this BFD's symbols cached copy if it exists. */
+ if (isymbuf == NULL && symtab_hdr->sh_info != 0)
+ {
+ isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
+ if (isymbuf == NULL)
+ isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
+ symtab_hdr->sh_info, 0,
+ NULL, NULL, NULL);
+ if (isymbuf == NULL)
+ goto error_return;
+ }
+
+ misc.symtab_hdr = symtab_hdr;
+ misc.isymbuf = isymbuf;
+ misc.irelbase = internal_relocs;
+ misc.contents = contents;
+
+ /* This is where all the relaxation actually get done. */
+ if ((pass == 1) || (new_pass && !changed))
+ {
+ /* On the first pass we simply search for the lowest page that
+ we havn't relaxed yet. Note that the pass count is reset
+ each time a page is complete in order to move on to the next page.
+ If we can't find any more pages then we are finished. */
+ if (new_pass)
+ {
+ pass = 1;
+ new_pass = FALSE;
+ changed = TRUE; /* Pre-initialize to break out of pass 1. */
+ search_addr = 0xFFFFFFFF;
+ }
+
+ if ((BASEADDR (sec) + sec->size < search_addr)
+ && (BASEADDR (sec) + sec->size > page_end))
+ {
+ if (BASEADDR (sec) <= page_end)
+ search_addr = page_end + 1;
+ else
+ search_addr = BASEADDR (sec);
+
+ /* Found a page => more work to do. */
+ *again = TRUE;
+ }
+ }
+ else
+ {
+ if (new_pass)
+ {
+ new_pass = FALSE;
+ changed = FALSE;
+ page_start = PAGENO (search_addr);
+ page_end = page_start | 0x00003FFF;
+ }
+
+ /* Only process sections in range. */
+ if ((BASEADDR (sec) + sec->size >= page_start)
+ && (BASEADDR (sec) <= page_end))
+ {
+ if (!ip2k_elf_relax_section_page (abfd, sec, &changed, &misc, page_start, page_end))
+ return FALSE;
+ }
+ *again = TRUE;
+ }
+
+ /* Perform some house keeping after relaxing the section. */
+
+ if (isymbuf != NULL
+ && symtab_hdr->contents != (unsigned char *) isymbuf)
+ {
+ if (! link_info->keep_memory)
+ free (isymbuf);
+ else
+ symtab_hdr->contents = (unsigned char *) isymbuf;
+ }
+
+ if (contents != NULL
+ && elf_section_data (sec)->this_hdr.contents != contents)
+ {
+ if (! link_info->keep_memory)
+ free (contents);
+ else
+ {
+ /* Cache the section contents for elf_link_input_bfd. */
+ elf_section_data (sec)->this_hdr.contents = contents;
+ }
+ }
+
+ if (internal_relocs != NULL
+ && elf_section_data (sec)->relocs != internal_relocs)
+ free (internal_relocs);
+
+ return TRUE;
+
+ error_return:
+ if (isymbuf != NULL
+ && symtab_hdr->contents != (unsigned char *) isymbuf)
+ free (isymbuf);
+ if (contents != NULL
+ && elf_section_data (sec)->this_hdr.contents != contents)
+ free (contents);
+ if (internal_relocs != NULL
+ && elf_section_data (sec)->relocs != internal_relocs)
+ free (internal_relocs);
+ return FALSE;
+}
+
+/* Set the howto pointer for a IP2K ELF reloc. */
+
+static void
+ip2k_info_to_howto_rela (bfd * abfd ATTRIBUTE_UNUSED,
+ arelent * cache_ptr,
+ Elf_Internal_Rela * dst)
+{
+ unsigned int r_type;
+
+ r_type = ELF32_R_TYPE (dst->r_info);
+ cache_ptr->howto = & ip2k_elf_howto_table [r_type];
+}
+
+/* Perform a single relocation.
+ By default we use the standard BFD routines. */
+
+static bfd_reloc_status_type
+ip2k_final_link_relocate (reloc_howto_type * howto,
+ bfd * input_bfd,
+ asection * input_section,
+ bfd_byte * contents,
+ Elf_Internal_Rela * rel,
+ bfd_vma relocation)
+{
+ static bfd_vma page_addr = 0;
+
+ bfd_reloc_status_type r = bfd_reloc_ok;
+ switch (howto->type)
+ {
+ /* Handle data space relocations. */
+ case R_IP2K_FR9:
+ case R_IP2K_BANK:
+ if ((relocation & IP2K_DATA_MASK) == IP2K_DATA_VALUE)
+ relocation &= ~IP2K_DATA_MASK;
+ else
+ r = bfd_reloc_notsupported;
+ break;
+
+ case R_IP2K_LO8DATA:
+ case R_IP2K_HI8DATA:
+ case R_IP2K_EX8DATA:
+ break;
+
+ /* Handle insn space relocations. */
+ case R_IP2K_PAGE3:
+ page_addr = BASEADDR (input_section) + rel->r_offset;
+ if ((relocation & IP2K_INSN_MASK) == IP2K_INSN_VALUE)
+ relocation &= ~IP2K_INSN_MASK;
+ else
+ r = bfd_reloc_notsupported;
+ break;
+
+ case R_IP2K_ADDR16CJP:
+ if (BASEADDR (input_section) + rel->r_offset != page_addr + 2)
+ {
+ /* No preceding page instruction, verify that it isn't needed. */
+ if (PAGENO (relocation + rel->r_addend) !=
+ ip2k_nominal_page_bits (input_bfd, input_section,
+ rel->r_offset, contents))
+ _bfd_error_handler (_("ip2k linker: missing page instruction at 0x%08lx (dest = 0x%08lx)."),
+ BASEADDR (input_section) + rel->r_offset,
+ relocation + rel->r_addend);
+ }
+ else if (ip2k_relaxed)
+ {
+ /* Preceding page instruction. Verify that the page instruction is
+ really needed. One reason for the relaxation to miss a page is if
+ the section is not marked as executable. */
+ if (!ip2k_is_switch_table_128 (input_bfd, input_section,
+ rel->r_offset - 2, contents)
+ && !ip2k_is_switch_table_256 (input_bfd, input_section,
+ rel->r_offset - 2, contents)
+ && (PAGENO (relocation + rel->r_addend) ==
+ ip2k_nominal_page_bits (input_bfd, input_section,
+ rel->r_offset - 2, contents)))
+ _bfd_error_handler (_("ip2k linker: redundant page instruction at 0x%08lx (dest = 0x%08lx)."),
+ page_addr,
+ relocation + rel->r_addend);
+ }
+ if ((relocation & IP2K_INSN_MASK) == IP2K_INSN_VALUE)
+ relocation &= ~IP2K_INSN_MASK;
+ else
+ r = bfd_reloc_notsupported;
+ break;
+
+ case R_IP2K_LO8INSN:
+ case R_IP2K_HI8INSN:
+ case R_IP2K_PC_SKIP:
+ if ((relocation & IP2K_INSN_MASK) == IP2K_INSN_VALUE)
+ relocation &= ~IP2K_INSN_MASK;
+ else
+ r = bfd_reloc_notsupported;
+ break;
+
+ case R_IP2K_16:
+ /* If this is a relocation involving a TEXT
+ symbol, reduce it to a word address. */
+ if ((relocation & IP2K_INSN_MASK) == IP2K_INSN_VALUE)
+ howto = &ip2k_elf_howto_table[ (int) R_IP2K_TEXT];
+ break;
+
+ /* Pass others through. */
+ default:
+ break;
+ }
+
+ /* Only install relocation if above tests did not disqualify it. */
+ if (r == bfd_reloc_ok)
+ r = _bfd_final_link_relocate (howto, input_bfd, input_section,
+ contents, rel->r_offset,
+ relocation, rel->r_addend);
+
+ return r;
+}
+
+/* Relocate a IP2K ELF section.
+
+ 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 relocatable
+ 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 relocatable 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 bfd_boolean
+ip2k_elf_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
+ 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);
+ r_symndx = ELF32_R_SYM (rel->r_info);
+ howto = ip2k_elf_howto_table + r_type;
+ h = NULL;
+ sym = NULL;
+ sec = NULL;
+
+ if (r_symndx < symtab_hdr->sh_info)
+ {
+ sym = local_syms + r_symndx;
+ sec = local_sections [r_symndx];
+ relocation = BASEADDR (sec) + 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;
+ }
+ else
+ {
+ bfd_boolean warned, ignored;
+ bfd_boolean unresolved_reloc;
+
+ RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
+ r_symndx, symtab_hdr, sym_hashes,
+ h, sec, relocation,
+ unresolved_reloc, warned, ignored);
+
+ name = h->root.root.string;
+ }
+
+ if (sec != NULL && discarded_section (sec))
+ RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+ rel, 1, relend, howto, 0, contents);
+
+ if (info->relocatable)
+ continue;
+
+ /* Finally, the sole IP2K-specific part. */
+ r = ip2k_final_link_relocate (howto, input_bfd, input_section,
+ contents, rel, relocation);
+
+ if (r != bfd_reloc_ok)
+ {
+ const char * msg = NULL;
+
+ switch (r)
+ {
+ case bfd_reloc_overflow:
+ r = info->callbacks->reloc_overflow
+ (info, (h ? &h->root : NULL), 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, TRUE);
+ break;
+
+ case bfd_reloc_outofrange:
+ msg = _("internal error: out of range error");
+ break;
+
+ /* This is how ip2k_final_link_relocate tells us of a non-kosher
+ reference between insn & data address spaces. */
+ case bfd_reloc_notsupported:
+ if (sym != NULL) /* Only if it's not an unresolved symbol. */
+ msg = _("unsupported relocation between data/insn address spaces");
+ 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;
+}
+
+#define TARGET_BIG_SYM ip2k_elf32_vec
+#define TARGET_BIG_NAME "elf32-ip2k"
+
+#define ELF_ARCH bfd_arch_ip2k
+#define ELF_MACHINE_CODE EM_IP2K
+#define ELF_MACHINE_ALT1 EM_IP2K_OLD
+#define ELF_MAXPAGESIZE 1 /* No pages on the IP2K. */
+
+#define elf_info_to_howto_rel NULL
+#define elf_info_to_howto ip2k_info_to_howto_rela
+
+#define elf_backend_can_gc_sections 1
+#define elf_backend_rela_normal 1
+#define elf_backend_relocate_section ip2k_elf_relocate_section
+
+#define elf_symbol_leading_char '_'
+#define bfd_elf32_bfd_reloc_type_lookup ip2k_reloc_type_lookup
+#define bfd_elf32_bfd_reloc_name_lookup ip2k_reloc_name_lookup
+#define bfd_elf32_bfd_relax_section ip2k_elf_relax_section
+
+#include "elf32-target.h"
diff --git a/bfd/elf32-iq2000.c b/bfd/elf32-iq2000.c
new file mode 100644
index 0000000..a6bf8d2
--- /dev/null
+++ b/bfd/elf32-iq2000.c
@@ -0,0 +1,915 @@
+/* IQ2000-specific support for 32-bit ELF.
+ Copyright (C) 2003-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+#include "elf-bfd.h"
+#include "elf/iq2000.h"
+
+/* Forward declarations. */
+
+static bfd_reloc_status_type iq2000_elf_howto_hi16_reloc (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
+
+
+static reloc_howto_type iq2000_elf_howto_table [] =
+{
+ /* This reloc does nothing. */
+
+ HOWTO (R_IQ2000_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_IQ2000_NONE", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A 16 bit absolute relocation. */
+ HOWTO (R_IQ2000_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_IQ2000_16", /* name */
+ FALSE, /* partial_inplace */
+ 0x0000, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A 32 bit absolute relocation. */
+ HOWTO (R_IQ2000_32, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 31, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_IQ2000_32", /* name */
+ FALSE, /* partial_inplace */
+ 0x00000000, /* src_mask */
+ 0x7fffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* 26 bit branch address. */
+ HOWTO (R_IQ2000_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_IQ2000_26", /* name */
+ FALSE, /* partial_inplace */
+ 0x00000000, /* src_mask */
+ 0x03ffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* 16 bit PC relative reference. */
+ HOWTO (R_IQ2000_PC16, /* 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_IQ2000_PC16", /* name */
+ FALSE, /* partial_inplace */
+ 0x0000, /* src_mask */
+ 0xffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* high 16 bits of symbol value. */
+ HOWTO (R_IQ2000_HI16, /* type */
+ 16, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 15, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ iq2000_elf_howto_hi16_reloc, /* special_function */
+ "R_IQ2000_HI16", /* name */
+ FALSE, /* partial_inplace */
+ 0x0000, /* src_mask */
+ 0x7fff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Low 16 bits of symbol value. */
+ HOWTO (R_IQ2000_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_IQ2000_LO16", /* name */
+ FALSE, /* partial_inplace */
+ 0x0000, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* 16-bit jump offset. */
+ HOWTO (R_IQ2000_OFFSET_16, /* type */
+ 2, /* 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_IQ2000_OFFSET_16", /* name */
+ FALSE, /* partial_inplace */
+ 0x0000, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* 21-bit jump offset. */
+ HOWTO (R_IQ2000_OFFSET_21, /* type */
+ 2, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 21, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_IQ2000_OFFSET_21", /* name */
+ FALSE, /* partial_inplace */
+ 0x000000, /* src_mask */
+ 0x1fffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* unsigned high 16 bits of value. */
+ HOWTO (R_IQ2000_OFFSET_21, /* type */
+ 16, /* 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_IQ2000_UHI16", /* name */
+ FALSE, /* partial_inplace */
+ 0x0000, /* src_mask */
+ 0x7fff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A 32 bit absolute debug relocation. */
+ HOWTO (R_IQ2000_32_DEBUG, /* 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_IQ2000_32", /* name */
+ FALSE, /* partial_inplace */
+ 0x00000000, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+};
+
+/* GNU extension to record C++ vtable hierarchy. */
+static reloc_howto_type iq2000_elf_vtinherit_howto =
+ HOWTO (R_IQ2000_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_IQ2000_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 iq2000_elf_vtentry_howto =
+ HOWTO (R_IQ2000_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 */
+ NULL, /* special_function */
+ "R_IQ2000_GNU_VTENTRY", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ FALSE); /* pcrel_offset */
+
+
+static bfd_reloc_status_type
+iq2000_elf_howto_hi16_reloc (bfd *abfd ATTRIBUTE_UNUSED,
+ arelent *reloc_entry,
+ asymbol *symbol,
+ void * data,
+ asection *input_section,
+ bfd *output_bfd,
+ char **error_message ATTRIBUTE_UNUSED)
+{
+ bfd_reloc_status_type ret;
+ bfd_vma relocation;
+
+ /* 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 (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 %lo will have sign-extension, compensate by add 0x10000 to hi portion. */
+ if (relocation & 0x8000)
+ reloc_entry->addend += 0x10000;
+
+ /* Now do the reloc in the usual way. */
+ ret = bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
+ input_section, output_bfd, error_message);
+
+ /* Put it back the way it was. */
+ if (relocation & 0x8000)
+ reloc_entry->addend -= 0x10000;
+
+ return ret;
+}
+
+static bfd_reloc_status_type
+iq2000_elf_relocate_hi16 (bfd *input_bfd,
+ Elf_Internal_Rela *relhi,
+ bfd_byte *contents,
+ bfd_vma value)
+{
+ bfd_vma insn;
+
+ insn = bfd_get_32 (input_bfd, contents + relhi->r_offset);
+
+ value += relhi->r_addend;
+ value &= 0x7fffffff; /* Mask off top-bit which is Harvard mask bit. */
+
+ /* If top-bit of %lo value is on, this means that %lo will
+ sign-propagate and so we compensate by adding 1 to %hi value. */
+ if (value & 0x8000)
+ value += 0x10000;
+
+ value >>= 16;
+ insn = ((insn & ~0xFFFF) | value);
+
+ bfd_put_32 (input_bfd, insn, contents + relhi->r_offset);
+ return bfd_reloc_ok;
+}
+
+static bfd_reloc_status_type
+iq2000_elf_relocate_offset16 (bfd *input_bfd,
+ Elf_Internal_Rela *rel,
+ bfd_byte *contents,
+ bfd_vma value,
+ bfd_vma location)
+{
+ bfd_vma insn;
+ bfd_vma jtarget;
+
+ insn = bfd_get_32 (input_bfd, contents + rel->r_offset);
+
+ value += rel->r_addend;
+
+ if (value & 3)
+ return bfd_reloc_dangerous;
+
+ jtarget = (value & 0x3fffc) | (location & 0xf0000000L);
+
+ if (jtarget != value)
+ return bfd_reloc_overflow;
+
+ insn = (insn & ~0xFFFF) | ((value >> 2) & 0xFFFF);
+
+ bfd_put_32 (input_bfd, insn, contents + rel->r_offset);
+ return bfd_reloc_ok;
+}
+
+/* Map BFD reloc types to IQ2000 ELF reloc types. */
+
+static reloc_howto_type *
+iq2000_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ bfd_reloc_code_real_type code)
+{
+ /* Note that the iq2000_elf_howto_table is indxed by the R_
+ constants. Thus, the order that the howto records appear in the
+ table *must* match the order of the relocation types defined in
+ include/elf/iq2000.h. */
+
+ switch (code)
+ {
+ case BFD_RELOC_NONE:
+ return &iq2000_elf_howto_table[ (int) R_IQ2000_NONE];
+ case BFD_RELOC_16:
+ return &iq2000_elf_howto_table[ (int) R_IQ2000_16];
+ case BFD_RELOC_32:
+ return &iq2000_elf_howto_table[ (int) R_IQ2000_32];
+ case BFD_RELOC_MIPS_JMP:
+ return &iq2000_elf_howto_table[ (int) R_IQ2000_26];
+ case BFD_RELOC_IQ2000_OFFSET_16:
+ return &iq2000_elf_howto_table[ (int) R_IQ2000_OFFSET_16];
+ case BFD_RELOC_IQ2000_OFFSET_21:
+ return &iq2000_elf_howto_table[ (int) R_IQ2000_OFFSET_21];
+ case BFD_RELOC_16_PCREL_S2:
+ return &iq2000_elf_howto_table[ (int) R_IQ2000_PC16];
+ case BFD_RELOC_HI16:
+ return &iq2000_elf_howto_table[ (int) R_IQ2000_HI16];
+ case BFD_RELOC_IQ2000_UHI16:
+ return &iq2000_elf_howto_table[ (int) R_IQ2000_UHI16];
+ case BFD_RELOC_LO16:
+ return &iq2000_elf_howto_table[ (int) R_IQ2000_LO16];
+ case BFD_RELOC_VTABLE_INHERIT:
+ return &iq2000_elf_vtinherit_howto;
+ case BFD_RELOC_VTABLE_ENTRY:
+ return &iq2000_elf_vtentry_howto;
+ default:
+ /* Pacify gcc -Wall. */
+ return NULL;
+ }
+ return NULL;
+}
+
+static reloc_howto_type *
+iq2000_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, const char *r_name)
+{
+ unsigned int i;
+
+ for (i = 0;
+ i < (sizeof (iq2000_elf_howto_table)
+ / sizeof (iq2000_elf_howto_table[0]));
+ i++)
+ if (iq2000_elf_howto_table[i].name != NULL
+ && strcasecmp (iq2000_elf_howto_table[i].name, r_name) == 0)
+ return &iq2000_elf_howto_table[i];
+
+ if (strcasecmp (iq2000_elf_vtinherit_howto.name, r_name) == 0)
+ return &iq2000_elf_vtinherit_howto;
+ if (strcasecmp (iq2000_elf_vtentry_howto.name, r_name) == 0)
+ return &iq2000_elf_vtentry_howto;
+
+ return NULL;
+}
+
+/* Perform a single relocation. By default we use the standard BFD
+ routines. */
+
+static bfd_reloc_status_type
+iq2000_final_link_relocate (reloc_howto_type * howto,
+ bfd * input_bfd,
+ asection * input_section,
+ bfd_byte * contents,
+ Elf_Internal_Rela * rel,
+ bfd_vma relocation)
+{
+ return _bfd_final_link_relocate (howto, input_bfd, input_section,
+ contents, rel->r_offset,
+ relocation, rel->r_addend);
+}
+
+/* Set the howto pointer for a IQ2000 ELF reloc. */
+
+static void
+iq2000_info_to_howto_rela (bfd * abfd ATTRIBUTE_UNUSED,
+ arelent * cache_ptr,
+ Elf_Internal_Rela * dst)
+{
+ unsigned int r_type;
+
+ r_type = ELF32_R_TYPE (dst->r_info);
+ switch (r_type)
+ {
+ case R_IQ2000_GNU_VTINHERIT:
+ cache_ptr->howto = & iq2000_elf_vtinherit_howto;
+ break;
+
+ case R_IQ2000_GNU_VTENTRY:
+ cache_ptr->howto = & iq2000_elf_vtentry_howto;
+ break;
+
+ default:
+ cache_ptr->howto = & iq2000_elf_howto_table [r_type];
+ break;
+ }
+}
+
+/* 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 bfd_boolean
+iq2000_elf_check_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;
+ const Elf_Internal_Rela *rel;
+ const Elf_Internal_Rela *rel_end;
+ bfd_boolean changed = FALSE;
+
+ if (info->relocatable)
+ return TRUE;
+
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+ sym_hashes = elf_sym_hashes (abfd);
+
+ 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];
+ 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;
+
+ /* PR15323, ref flags aren't set for references in the same
+ object. */
+ h->root.non_ir_ref = 1;
+ }
+
+ switch (ELF32_R_TYPE (rel->r_info))
+ {
+ /* This relocation describes the C++ object vtable
+ hierarchy. Reconstruct it for later use during GC. */
+ case R_IQ2000_GNU_VTINHERIT:
+ if (!bfd_elf_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_IQ2000_GNU_VTENTRY:
+ BFD_ASSERT (h != NULL);
+ if (h != NULL
+ && !bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
+ return FALSE;
+ break;
+
+ case R_IQ2000_32:
+ /* For debug section, change to special harvard-aware relocations. */
+ if (CONST_STRNEQ (sec->name, ".debug")
+ || CONST_STRNEQ (sec->name, ".stab")
+ || CONST_STRNEQ (sec->name, ".eh_frame"))
+ {
+ ((Elf_Internal_Rela *) rel)->r_info
+ = ELF32_R_INFO (ELF32_R_SYM (rel->r_info), R_IQ2000_32_DEBUG);
+ changed = TRUE;
+ }
+ break;
+ }
+ }
+
+ if (changed)
+ /* Note that we've changed relocs, otherwise if !info->keep_memory
+ we'll free the relocs and lose our changes. */
+ elf_section_data (sec)->relocs = (Elf_Internal_Rela *) relocs;
+
+ return TRUE;
+}
+
+
+/* Relocate a IQ2000 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 relocatable
+ 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 relocatable 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 bfd_boolean
+iq2000_elf_relocate_section (bfd * output_bfd ATTRIBUTE_UNUSED,
+ 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_IQ2000_GNU_VTINHERIT
+ || r_type == R_IQ2000_GNU_VTENTRY)
+ continue;
+
+ r_symndx = ELF32_R_SYM (rel->r_info);
+
+ howto = iq2000_elf_howto_table + ELF32_R_TYPE (rel->r_info);
+ h = NULL;
+ sym = NULL;
+ sec = NULL;
+
+ if (r_symndx < symtab_hdr->sh_info)
+ {
+ asection *osec;
+
+ sym = local_syms + r_symndx;
+ osec = sec = local_sections [r_symndx];
+ if ((sec->flags & SEC_MERGE)
+ && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
+ /* This relocation is relative to a section symbol that is
+ going to be merged. Change it so that it is relative
+ to the merged section symbol. */
+ rel->r_addend = _bfd_elf_rel_local_sym (output_bfd, sym, &sec,
+ rel->r_addend);
+
+ 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, osec) : name;
+ }
+ else
+ {
+ bfd_boolean unresolved_reloc;
+ bfd_boolean warned, ignored;
+
+ RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
+ r_symndx, symtab_hdr, sym_hashes,
+ h, sec, relocation,
+ unresolved_reloc, warned, ignored);
+
+ name = h->root.root.string;
+ }
+
+ if (sec != NULL && discarded_section (sec))
+ RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+ rel, 1, relend, howto, 0, contents);
+
+ if (info->relocatable)
+ continue;
+
+ switch (r_type)
+ {
+ case R_IQ2000_HI16:
+ r = iq2000_elf_relocate_hi16 (input_bfd, rel, contents, relocation);
+ break;
+
+ case R_IQ2000_OFFSET_16:
+ r = iq2000_elf_relocate_offset16 (input_bfd, rel, contents, relocation,
+ input_section->output_section->vma
+ + input_section->output_offset
+ + rel->r_offset);
+ break;
+
+ case R_IQ2000_PC16:
+ rel->r_addend -= 4;
+ /* Fall through. */
+
+ default:
+ r = iq2000_final_link_relocate (howto, input_bfd, input_section,
+ contents, rel, relocation);
+ break;
+ }
+
+ if (r != bfd_reloc_ok)
+ {
+ const char * msg = (const char *) NULL;
+
+ switch (r)
+ {
+ case bfd_reloc_overflow:
+ r = info->callbacks->reloc_overflow
+ (info, (h ? &h->root : NULL), 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, TRUE);
+ 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 *
+iq2000_elf_gc_mark_hook (asection *sec,
+ 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_IQ2000_GNU_VTINHERIT:
+ case R_IQ2000_GNU_VTENTRY:
+ return NULL;
+ }
+
+ return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
+}
+
+
+/* Return the MACH for an e_flags value. */
+
+static int
+elf32_iq2000_machine (bfd *abfd)
+{
+ switch (elf_elfheader (abfd)->e_flags & EF_IQ2000_CPU_MASK)
+ {
+ case EF_IQ2000_CPU_IQ10:
+ return bfd_mach_iq10;
+
+ case EF_IQ2000_CPU_IQ2000:
+ default:
+ return bfd_mach_iq2000;
+ }
+}
+
+
+/* Function to set the ELF flag bits. */
+
+static bfd_boolean
+iq2000_elf_set_private_flags (bfd *abfd, flagword flags)
+{
+ elf_elfheader (abfd)->e_flags = flags;
+ elf_flags_init (abfd) = TRUE;
+ return TRUE;
+}
+
+/* Merge backend specific data from an object
+ file to the output object file when linking. */
+
+static bfd_boolean
+iq2000_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
+{
+ flagword old_flags, old_partial;
+ flagword new_flags, new_partial;
+ bfd_boolean error = FALSE;
+ char new_opt[80];
+ char old_opt[80];
+
+ new_opt[0] = old_opt[0] = '\0';
+ 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)
+ {
+ /* Warn if different cpu is used, but allow a
+ specific cpu to override the generic cpu. */
+ new_partial = (new_flags & EF_IQ2000_CPU_MASK);
+ old_partial = (old_flags & EF_IQ2000_CPU_MASK);
+
+ if (new_partial != old_partial)
+ {
+ switch (new_partial)
+ {
+ case EF_IQ2000_CPU_IQ10:
+ strcat (new_opt, " -m10");
+ break;
+
+ default:
+ case EF_IQ2000_CPU_IQ2000:
+ strcat (new_opt, " -m2000");
+ break;
+ }
+
+ switch (old_partial)
+ {
+ case EF_IQ2000_CPU_IQ10:
+ strcat (old_opt, " -m10");
+ break;
+
+ default:
+ case EF_IQ2000_CPU_IQ2000:
+ strcat (old_opt, " -m2000");
+ break;
+ }
+ }
+
+ /* Print out any mismatches from above. */
+ if (new_opt[0])
+ {
+ error = TRUE;
+ _bfd_error_handler
+ (_("%s: compiled with %s and linked with modules compiled with %s"),
+ bfd_get_filename (ibfd), new_opt, old_opt);
+ }
+
+ new_flags &= ~ EF_IQ2000_ALL_FLAGS;
+ old_flags &= ~ EF_IQ2000_ALL_FLAGS;
+
+ /* 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 !error;
+}
+
+
+static bfd_boolean
+iq2000_elf_print_private_bfd_data (bfd *abfd, void * ptr)
+{
+ FILE *file = (FILE *) ptr;
+ flagword flags;
+
+ BFD_ASSERT (abfd != NULL && ptr != NULL);
+
+ /* Print normal ELF private data. */
+ _bfd_elf_print_private_bfd_data (abfd, ptr);
+
+ flags = elf_elfheader (abfd)->e_flags;
+ fprintf (file, _("private flags = 0x%lx:"), (unsigned long) flags);
+
+ switch (flags & EF_IQ2000_CPU_MASK)
+ {
+ case EF_IQ2000_CPU_IQ10:
+ fprintf (file, " -m10");
+ break;
+ case EF_IQ2000_CPU_IQ2000:
+ fprintf (file, " -m2000");
+ break;
+ default:
+ break;
+ }
+
+ fputc ('\n', file);
+ return TRUE;
+}
+
+static
+bfd_boolean
+iq2000_elf_object_p (bfd *abfd)
+{
+ bfd_default_set_arch_mach (abfd, bfd_arch_iq2000,
+ elf32_iq2000_machine (abfd));
+ return TRUE;
+}
+
+
+#define ELF_ARCH bfd_arch_iq2000
+#define ELF_MACHINE_CODE EM_IQ2000
+#define ELF_MAXPAGESIZE 0x1000
+
+#define TARGET_BIG_SYM iq2000_elf32_vec
+#define TARGET_BIG_NAME "elf32-iq2000"
+
+#define elf_info_to_howto_rel NULL
+#define elf_info_to_howto iq2000_info_to_howto_rela
+#define elf_backend_relocate_section iq2000_elf_relocate_section
+#define elf_backend_gc_mark_hook iq2000_elf_gc_mark_hook
+#define elf_backend_check_relocs iq2000_elf_check_relocs
+#define elf_backend_object_p iq2000_elf_object_p
+#define elf_backend_rela_normal 1
+
+#define elf_backend_can_gc_sections 1
+
+#define bfd_elf32_bfd_reloc_type_lookup iq2000_reloc_type_lookup
+#define bfd_elf32_bfd_reloc_name_lookup iq2000_reloc_name_lookup
+#define bfd_elf32_bfd_set_private_flags iq2000_elf_set_private_flags
+#define bfd_elf32_bfd_merge_private_bfd_data iq2000_elf_merge_private_bfd_data
+#define bfd_elf32_bfd_print_private_bfd_data iq2000_elf_print_private_bfd_data
+
+#include "elf32-target.h"
diff --git a/bfd/elf32-lm32.c b/bfd/elf32-lm32.c
new file mode 100644
index 0000000..e694055
--- /dev/null
+++ b/bfd/elf32-lm32.c
@@ -0,0 +1,2726 @@
+/* Lattice Mico32-specific support for 32-bit ELF
+ Copyright (C) 2008-2014 Free Software Foundation, Inc.
+ Contributed by Jon Beniston <jon@beniston.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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+#include "elf-bfd.h"
+#include "elf/lm32.h"
+
+#define DEFAULT_STACK_SIZE 0x20000
+
+#define PLT_ENTRY_SIZE 20
+
+#define PLT0_ENTRY_WORD0 0
+#define PLT0_ENTRY_WORD1 0
+#define PLT0_ENTRY_WORD2 0
+#define PLT0_ENTRY_WORD3 0
+#define PLT0_ENTRY_WORD4 0
+
+#define PLT0_PIC_ENTRY_WORD0 0
+#define PLT0_PIC_ENTRY_WORD1 0
+#define PLT0_PIC_ENTRY_WORD2 0
+#define PLT0_PIC_ENTRY_WORD3 0
+#define PLT0_PIC_ENTRY_WORD4 0
+
+#define ELF_DYNAMIC_INTERPRETER "/usr/lib/libc.so.1"
+
+extern const bfd_target lm32_elf32_fdpic_vec;
+
+#define IS_FDPIC(bfd) ((bfd)->xvec == &lm32_elf32_fdpic_vec)
+
+static bfd_reloc_status_type lm32_elf_gprel_reloc
+ (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
+
+/* The linker needs to keep track of the number of relocs that it
+ decides to copy as dynamic relocs in check_relocs for each symbol.
+ This is so that it can later discard them if they are found to be
+ unnecessary. We store the information in a field extending the
+ regular ELF linker hash table. */
+
+struct elf_lm32_dyn_relocs
+{
+ struct elf_lm32_dyn_relocs *next;
+
+ /* The input section of the reloc. */
+ asection *sec;
+
+ /* Total number of relocs copied for the input section. */
+ bfd_size_type count;
+
+ /* Number of pc-relative relocs copied for the input section. */
+ bfd_size_type pc_count;
+};
+
+/* lm32 ELF linker hash entry. */
+
+struct elf_lm32_link_hash_entry
+{
+ struct elf_link_hash_entry root;
+
+ /* Track dynamic relocs copied for this symbol. */
+ struct elf_lm32_dyn_relocs *dyn_relocs;
+};
+
+/* lm32 ELF linker hash table. */
+
+struct elf_lm32_link_hash_table
+{
+ struct elf_link_hash_table root;
+
+ /* Short-cuts to get to dynamic linker sections. */
+ asection *sgot;
+ asection *sgotplt;
+ asection *srelgot;
+ asection *sfixup32;
+ asection *splt;
+ asection *srelplt;
+ asection *sdynbss;
+ asection *srelbss;
+
+ int relocs32;
+};
+
+/* Get the lm32 ELF linker hash table from a link_info structure. */
+
+#define lm32_elf_hash_table(p) \
+ (elf_hash_table_id ((struct elf_link_hash_table *) ((p)->hash)) \
+ == LM32_ELF_DATA ? ((struct elf_lm32_link_hash_table *) ((p)->hash)) : NULL)
+
+#define lm32fdpic_got_section(info) \
+ (lm32_elf_hash_table (info)->sgot)
+#define lm32fdpic_gotrel_section(info) \
+ (lm32_elf_hash_table (info)->srelgot)
+#define lm32fdpic_fixup32_section(info) \
+ (lm32_elf_hash_table (info)->sfixup32)
+
+struct weak_symbol_list
+{
+ const char *name;
+ struct weak_symbol_list *next;
+};
+
+/* Create an entry in an lm32 ELF linker hash table. */
+
+static struct bfd_hash_entry *
+lm32_elf_link_hash_newfunc (struct bfd_hash_entry *entry,
+ struct bfd_hash_table *table,
+ const char *string)
+{
+ struct elf_lm32_link_hash_entry *ret =
+ (struct elf_lm32_link_hash_entry *) entry;
+
+ /* Allocate the structure if it has not already been allocated by a
+ subclass. */
+ if (ret == NULL)
+ ret = bfd_hash_allocate (table,
+ sizeof (struct elf_lm32_link_hash_entry));
+ if (ret == NULL)
+ return NULL;
+
+ /* Call the allocation method of the superclass. */
+ ret = ((struct elf_lm32_link_hash_entry *)
+ _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry *) ret,
+ table, string));
+ if (ret != NULL)
+ {
+ struct elf_lm32_link_hash_entry *eh;
+
+ eh = (struct elf_lm32_link_hash_entry *) ret;
+ eh->dyn_relocs = NULL;
+ }
+
+ return (struct bfd_hash_entry *) ret;
+}
+
+/* Create an lm32 ELF linker hash table. */
+
+static struct bfd_link_hash_table *
+lm32_elf_link_hash_table_create (bfd *abfd)
+{
+ struct elf_lm32_link_hash_table *ret;
+ bfd_size_type amt = sizeof (struct elf_lm32_link_hash_table);
+
+ ret = bfd_zmalloc (amt);
+ if (ret == NULL)
+ return NULL;
+
+ if (!_bfd_elf_link_hash_table_init (&ret->root, abfd,
+ lm32_elf_link_hash_newfunc,
+ sizeof (struct elf_lm32_link_hash_entry),
+ LM32_ELF_DATA))
+ {
+ free (ret);
+ return NULL;
+ }
+
+ return &ret->root.root;
+}
+
+/* Add a fixup to the ROFIXUP section. */
+
+static bfd_vma
+_lm32fdpic_add_rofixup (bfd *output_bfd, asection *rofixup, bfd_vma relocation)
+{
+ bfd_vma fixup_offset;
+
+ if (rofixup->flags & SEC_EXCLUDE)
+ return -1;
+
+ fixup_offset = rofixup->reloc_count * 4;
+ if (rofixup->contents)
+ {
+ BFD_ASSERT (fixup_offset < rofixup->size);
+ if (fixup_offset < rofixup->size)
+ bfd_put_32 (output_bfd, relocation, rofixup->contents + fixup_offset);
+ }
+ rofixup->reloc_count++;
+
+ return fixup_offset;
+}
+
+/* Create .got, .gotplt, and .rela.got sections in DYNOBJ, and set up
+ shortcuts to them in our hash table. */
+
+static bfd_boolean
+create_got_section (bfd *dynobj, struct bfd_link_info *info)
+{
+ struct elf_lm32_link_hash_table *htab;
+ asection *s;
+
+ /* This function may be called more than once. */
+ s = bfd_get_linker_section (dynobj, ".got");
+ if (s != NULL)
+ return TRUE;
+
+ htab = lm32_elf_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ if (! _bfd_elf_create_got_section (dynobj, info))
+ return FALSE;
+
+ htab->sgot = bfd_get_linker_section (dynobj, ".got");
+ htab->sgotplt = bfd_get_linker_section (dynobj, ".got.plt");
+ htab->srelgot = bfd_get_linker_section (dynobj, ".rela.got");
+ if (! htab->sgot || ! htab->sgotplt || ! htab->srelgot)
+ abort ();
+
+ return TRUE;
+}
+
+/* Create .rofixup sections in DYNOBJ, and set up
+ shortcuts to them in our hash table. */
+
+static bfd_boolean
+create_rofixup_section (bfd *dynobj, struct bfd_link_info *info)
+{
+ struct elf_lm32_link_hash_table *htab;
+ htab = lm32_elf_hash_table (info);
+
+ if (htab == NULL)
+ return FALSE;
+
+ /* Fixup section for R_LM32_32 relocs. */
+ lm32fdpic_fixup32_section (info)
+ = bfd_make_section_anyway_with_flags (dynobj,
+ ".rofixup",
+ (SEC_ALLOC
+ | SEC_LOAD
+ | SEC_HAS_CONTENTS
+ | SEC_IN_MEMORY
+ | SEC_LINKER_CREATED
+ | SEC_READONLY));
+ if (lm32fdpic_fixup32_section (info) == NULL
+ || ! bfd_set_section_alignment (dynobj,
+ lm32fdpic_fixup32_section (info), 2))
+ return FALSE;
+
+ return TRUE;
+}
+
+static reloc_howto_type lm32_elf_howto_table [] =
+{
+ /* This reloc does nothing. */
+ HOWTO (R_LM32_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_LM32_NONE", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* An 8 bit absolute relocation. */
+ HOWTO (R_LM32_8, /* 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_LM32_8", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A 16 bit absolute relocation. */
+ HOWTO (R_LM32_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_LM32_16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A 32 bit absolute relocation. */
+ HOWTO (R_LM32_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_LM32_32", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_LM32_HI16, /* type */
+ 16, /* 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_LM32_HI16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_LM32_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_LM32_LO16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_LM32_GPREL16, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ lm32_elf_gprel_reloc, /* special_function */
+ "R_LM32_GPREL16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_LM32_CALL, /* 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_LM32_CALL", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x3ffffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_LM32_BRANCH, /* 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_LM32_BRANCH", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* GNU extension to record C++ vtable hierarchy. */
+ HOWTO (R_LM32_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_LM32_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_LM32_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_LM32_GNU_VTENTRY", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_LM32_16_GOT, /* 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_LM32_16_GOT", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_LM32_GOTOFF_HI16, /* type */
+ 16, /* 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_LM32_GOTOFF_HI16", /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_LM32_GOTOFF_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_LM32_GOTOFF_LO16", /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_LM32_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_LM32_COPY", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_LM32_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_LM32_GLOB_DAT", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_LM32_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_LM32_JMP_SLOT", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_LM32_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_LM32_RELATIVE", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+};
+
+/* Map BFD reloc types to lm32 ELF reloc types. */
+
+struct lm32_reloc_map
+{
+ bfd_reloc_code_real_type bfd_reloc_val;
+ unsigned char elf_reloc_val;
+};
+
+static const struct lm32_reloc_map lm32_reloc_map[] =
+{
+ { BFD_RELOC_NONE, R_LM32_NONE },
+ { BFD_RELOC_8, R_LM32_8 },
+ { BFD_RELOC_16, R_LM32_16 },
+ { BFD_RELOC_32, R_LM32_32 },
+ { BFD_RELOC_HI16, R_LM32_HI16 },
+ { BFD_RELOC_LO16, R_LM32_LO16 },
+ { BFD_RELOC_GPREL16, R_LM32_GPREL16 },
+ { BFD_RELOC_LM32_CALL, R_LM32_CALL },
+ { BFD_RELOC_LM32_BRANCH, R_LM32_BRANCH },
+ { BFD_RELOC_VTABLE_INHERIT, R_LM32_GNU_VTINHERIT },
+ { BFD_RELOC_VTABLE_ENTRY, R_LM32_GNU_VTENTRY },
+ { BFD_RELOC_LM32_16_GOT, R_LM32_16_GOT },
+ { BFD_RELOC_LM32_GOTOFF_HI16, R_LM32_GOTOFF_HI16 },
+ { BFD_RELOC_LM32_GOTOFF_LO16, R_LM32_GOTOFF_LO16 },
+ { BFD_RELOC_LM32_COPY, R_LM32_COPY },
+ { BFD_RELOC_LM32_GLOB_DAT, R_LM32_GLOB_DAT },
+ { BFD_RELOC_LM32_JMP_SLOT, R_LM32_JMP_SLOT },
+ { BFD_RELOC_LM32_RELATIVE, R_LM32_RELATIVE },
+};
+
+static reloc_howto_type *
+lm32_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ bfd_reloc_code_real_type code)
+{
+ unsigned int i;
+
+ for (i = 0; i < sizeof (lm32_reloc_map) / sizeof (lm32_reloc_map[0]); i++)
+ if (lm32_reloc_map[i].bfd_reloc_val == code)
+ return &lm32_elf_howto_table[lm32_reloc_map[i].elf_reloc_val];
+ return NULL;
+}
+
+static reloc_howto_type *
+lm32_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ const char *r_name)
+{
+ unsigned int i;
+
+ for (i = 0;
+ i < sizeof (lm32_elf_howto_table) / sizeof (lm32_elf_howto_table[0]);
+ i++)
+ if (lm32_elf_howto_table[i].name != NULL
+ && strcasecmp (lm32_elf_howto_table[i].name, r_name) == 0)
+ return &lm32_elf_howto_table[i];
+
+ return NULL;
+}
+
+
+/* Set the howto pointer for an Lattice Mico32 ELF reloc. */
+
+static void
+lm32_info_to_howto_rela (bfd *abfd ATTRIBUTE_UNUSED,
+ arelent *cache_ptr,
+ Elf_Internal_Rela *dst)
+{
+ unsigned int r_type;
+
+ r_type = ELF32_R_TYPE (dst->r_info);
+ BFD_ASSERT (r_type < (unsigned int) R_LM32_max);
+ cache_ptr->howto = &lm32_elf_howto_table[r_type];
+}
+
+/* Set the right machine number for an Lattice Mico32 ELF file. */
+
+static bfd_boolean
+lm32_elf_object_p (bfd *abfd)
+{
+ return bfd_default_set_arch_mach (abfd, bfd_arch_lm32, bfd_mach_lm32);
+}
+
+/* Set machine type flags just before file is written out. */
+
+static void
+lm32_elf_final_write_processing (bfd *abfd, bfd_boolean linker ATTRIBUTE_UNUSED)
+{
+ elf_elfheader (abfd)->e_machine = EM_LATTICEMICO32;
+ elf_elfheader (abfd)->e_flags &=~ EF_LM32_MACH;
+ switch (bfd_get_mach (abfd))
+ {
+ case bfd_mach_lm32:
+ elf_elfheader (abfd)->e_flags |= E_LM32_MACH;
+ break;
+ default:
+ abort ();
+ }
+}
+
+/* Set the GP value for OUTPUT_BFD. Returns FALSE if this is a
+ dangerous relocation. */
+
+static bfd_boolean
+lm32_elf_assign_gp (bfd *output_bfd, bfd_vma *pgp)
+{
+ unsigned int count;
+ asymbol **sym;
+ unsigned int i;
+
+ /* If we've already figured out what GP will be, just return it. */
+ *pgp = _bfd_get_gp_value (output_bfd);
+ if (*pgp)
+ return TRUE;
+
+ count = bfd_get_symcount (output_bfd);
+ sym = bfd_get_outsymbols (output_bfd);
+
+ /* The linker script will have created a symbol named `_gp' with the
+ appropriate value. */
+ if (sym == NULL)
+ i = count;
+ else
+ {
+ for (i = 0; i < count; i++, sym++)
+ {
+ 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);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/* 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 relocatable output. */
+
+static bfd_reloc_status_type
+lm32_elf_final_gp (bfd *output_bfd, asymbol *symbol, bfd_boolean relocatable,
+ char **error_message, bfd_vma *pgp)
+{
+ if (bfd_is_und_section (symbol->section) && !relocatable)
+ {
+ *pgp = 0;
+ return bfd_reloc_undefined;
+ }
+
+ *pgp = _bfd_get_gp_value (output_bfd);
+ if (*pgp == 0 && (!relocatable || (symbol->flags & BSF_SECTION_SYM) != 0))
+ {
+ if (relocatable)
+ {
+ /* Make up a value. */
+ *pgp = symbol->section->output_section->vma + 0x4000;
+ _bfd_set_gp_value (output_bfd, *pgp);
+ }
+ else if (!lm32_elf_assign_gp (output_bfd, pgp))
+ {
+ *error_message =
+ (char *)
+ _("global pointer relative relocation when _gp not defined");
+ return bfd_reloc_dangerous;
+ }
+ }
+
+ return bfd_reloc_ok;
+}
+
+static bfd_reloc_status_type
+lm32_elf_do_gprel_relocate (bfd *abfd,
+ reloc_howto_type *howto,
+ asection *input_section ATTRIBUTE_UNUSED,
+ bfd_byte *data,
+ bfd_vma offset,
+ bfd_vma symbol_value,
+ bfd_vma addend)
+{
+ return _bfd_final_link_relocate (howto, abfd, input_section,
+ data, offset, symbol_value, addend);
+}
+
+static bfd_reloc_status_type
+lm32_elf_gprel_reloc (bfd *abfd,
+ arelent *reloc_entry,
+ asymbol *symbol,
+ void *data,
+ asection *input_section,
+ bfd *output_bfd,
+ char **msg)
+{
+ bfd_vma relocation;
+ bfd_vma gp;
+ bfd_reloc_status_type r;
+
+ 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_ok;
+
+ relocation = symbol->value
+ + symbol->section->output_section->vma + symbol->section->output_offset;
+
+ if ((r =
+ lm32_elf_final_gp (abfd, symbol, FALSE, msg, &gp)) == bfd_reloc_ok)
+ {
+ relocation = relocation + reloc_entry->addend - gp;
+ reloc_entry->addend = 0;
+ if ((signed) relocation < -32768 || (signed) relocation > 32767)
+ {
+ *msg = _("global pointer relative address out of range");
+ r = bfd_reloc_outofrange;
+ }
+ else
+ {
+ r = lm32_elf_do_gprel_relocate (abfd, reloc_entry->howto,
+ input_section,
+ data, reloc_entry->address,
+ relocation, reloc_entry->addend);
+ }
+ }
+
+ return r;
+}
+
+/* Find the segment number in which OSEC, and output section, is
+ located. */
+
+static unsigned
+_lm32fdpic_osec_to_segment (bfd *output_bfd, asection *osec)
+{
+ struct elf_segment_map *m;
+ Elf_Internal_Phdr *p;
+
+ /* Find the segment that contains the output_section. */
+ for (m = elf_seg_map (output_bfd), p = elf_tdata (output_bfd)->phdr;
+ m != NULL;
+ m = m->next, p++)
+ {
+ int i;
+
+ for (i = m->count - 1; i >= 0; i--)
+ if (m->sections[i] == osec)
+ break;
+
+ if (i >= 0)
+ break;
+ }
+
+ return p - elf_tdata (output_bfd)->phdr;
+}
+
+/* Determine if an output section is read-only. */
+
+inline static bfd_boolean
+_lm32fdpic_osec_readonly_p (bfd *output_bfd, asection *osec)
+{
+ unsigned seg = _lm32fdpic_osec_to_segment (output_bfd, osec);
+
+ return ! (elf_tdata (output_bfd)->phdr[seg].p_flags & PF_W);
+}
+
+/* Relocate a section */
+
+static bfd_boolean
+lm32_elf_relocate_section (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;
+ struct elf_lm32_link_hash_table *htab = lm32_elf_hash_table (info);
+ bfd *dynobj;
+ bfd_vma *local_got_offsets;
+ asection *sgot;
+
+ if (htab == NULL)
+ return FALSE;
+
+ dynobj = htab->root.dynobj;
+ local_got_offsets = elf_local_got_offsets (input_bfd);
+
+ sgot = htab->sgot;
+
+ 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++)
+ {
+ reloc_howto_type *howto;
+ unsigned int r_type;
+ unsigned long r_symndx;
+ Elf_Internal_Sym *sym;
+ asection *sec;
+ struct elf_link_hash_entry *h;
+ bfd_vma relocation;
+ bfd_vma gp;
+ bfd_reloc_status_type r;
+ const char *name = NULL;
+
+ r_symndx = ELF32_R_SYM (rel->r_info);
+ r_type = ELF32_R_TYPE (rel->r_info);
+
+ if (r_type == R_LM32_GNU_VTENTRY
+ || r_type == R_LM32_GNU_VTINHERIT )
+ continue;
+
+ h = NULL;
+ sym = NULL;
+ sec = NULL;
+
+ howto = lm32_elf_howto_table + r_type;
+
+ if (r_symndx < symtab_hdr->sh_info)
+ {
+ /* It's a local symbol. */
+ sym = local_syms + r_symndx;
+ sec = local_sections[r_symndx];
+ relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
+ 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;
+ }
+ else
+ {
+ /* It's a global symbol. */
+ bfd_boolean unresolved_reloc;
+ bfd_boolean warned, ignored;
+
+ RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
+ r_symndx, symtab_hdr, sym_hashes,
+ h, sec, relocation,
+ unresolved_reloc, warned, ignored);
+ name = h->root.root.string;
+ }
+
+ if (sec != NULL && discarded_section (sec))
+ RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+ rel, 1, relend, howto, 0, contents);
+
+ if (info->relocatable)
+ {
+ /* This is a relocatable 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 (sym == NULL || ELF_ST_TYPE (sym->st_info) != STT_SECTION)
+ continue;
+
+ /* If partial_inplace, we need to store any additional addend
+ back in the section. */
+ if (! howto->partial_inplace)
+ continue;
+
+ /* Shouldn't reach here. */
+ abort ();
+ r = bfd_reloc_ok;
+ }
+ else
+ {
+ switch (howto->type)
+ {
+ case R_LM32_GPREL16:
+ if (!lm32_elf_assign_gp (output_bfd, &gp))
+ r = bfd_reloc_dangerous;
+ else
+ {
+ relocation = relocation + rel->r_addend - gp;
+ rel->r_addend = 0;
+ if ((signed)relocation < -32768 || (signed)relocation > 32767)
+ r = bfd_reloc_outofrange;
+ else
+ {
+ r = _bfd_final_link_relocate (howto, input_bfd,
+ input_section, contents,
+ rel->r_offset, relocation,
+ rel->r_addend);
+ }
+ }
+ break;
+ case R_LM32_16_GOT:
+ /* Relocation is to the entry for this symbol in the global
+ offset table. */
+ BFD_ASSERT (sgot != NULL);
+ if (h != NULL)
+ {
+ bfd_boolean dyn;
+ bfd_vma off;
+
+ off = h->got.offset;
+ BFD_ASSERT (off != (bfd_vma) -1);
+
+ dyn = htab->root.dynamic_sections_created;
+ if (! WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h)
+ || (info->shared
+ && (info->symbolic
+ || h->dynindx == -1
+ || h->forced_local)
+ && h->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
+ {
+ /* Write entry in GOT */
+ bfd_put_32 (output_bfd, relocation,
+ sgot->contents + off);
+ /* Create entry in .rofixup pointing to GOT entry. */
+ if (IS_FDPIC (output_bfd) && h->root.type != bfd_link_hash_undefweak)
+ {
+ _lm32fdpic_add_rofixup (output_bfd,
+ lm32fdpic_fixup32_section
+ (info),
+ sgot->output_section->vma
+ + sgot->output_offset
+ + off);
+ }
+ /* Mark GOT entry as having been written. */
+ h->got.offset |= 1;
+ }
+ }
+
+ relocation = sgot->output_offset + off;
+ }
+ else
+ {
+ bfd_vma off;
+ bfd_byte *loc;
+
+ BFD_ASSERT (local_got_offsets != NULL
+ && local_got_offsets[r_symndx] != (bfd_vma) -1);
+
+ /* Get offset into GOT table. */
+ 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
+ {
+ /* Write entry in GOT. */
+ bfd_put_32 (output_bfd, relocation, sgot->contents + off);
+ /* Create entry in .rofixup pointing to GOT entry. */
+ if (IS_FDPIC (output_bfd))
+ {
+ _lm32fdpic_add_rofixup (output_bfd,
+ lm32fdpic_fixup32_section
+ (info),
+ sgot->output_section->vma
+ + sgot->output_offset
+ + off);
+ }
+
+ if (info->shared)
+ {
+ asection *srelgot;
+ Elf_Internal_Rela outrel;
+
+ /* We need to generate a R_LM32_RELATIVE reloc
+ for the dynamic linker. */
+ srelgot = bfd_get_linker_section (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_LM32_RELATIVE);
+ outrel.r_addend = relocation;
+ loc = srelgot->contents;
+ loc += srelgot->reloc_count * sizeof (Elf32_External_Rela);
+ bfd_elf32_swap_reloca_out (output_bfd, &outrel,loc);
+ ++srelgot->reloc_count;
+ }
+
+ local_got_offsets[r_symndx] |= 1;
+ }
+
+
+ relocation = sgot->output_offset + off;
+ }
+
+ /* Addend should be zero. */
+ if (rel->r_addend != 0)
+ (*_bfd_error_handler) (_("internal error: addend should be zero for R_LM32_16_GOT"));
+
+ r = _bfd_final_link_relocate (howto,
+ input_bfd,
+ input_section,
+ contents,
+ rel->r_offset,
+ relocation,
+ rel->r_addend);
+ break;
+
+ case R_LM32_GOTOFF_LO16:
+ case R_LM32_GOTOFF_HI16:
+ /* Relocation is offset from GOT. */
+ BFD_ASSERT (sgot != NULL);
+ relocation -= sgot->output_section->vma;
+ /* Account for sign-extension. */
+ if ((r_type == R_LM32_GOTOFF_HI16)
+ && ((relocation + rel->r_addend) & 0x8000))
+ rel->r_addend += 0x10000;
+ r = _bfd_final_link_relocate (howto,
+ input_bfd,
+ input_section,
+ contents,
+ rel->r_offset,
+ relocation,
+ rel->r_addend);
+ break;
+
+ case R_LM32_32:
+ if (IS_FDPIC (output_bfd))
+ {
+ if ((!h) || (h && h->root.type != bfd_link_hash_undefweak))
+ {
+ /* Only create .rofixup entries for relocs in loadable sections. */
+ if ((bfd_get_section_flags (output_bfd, input_section->output_section)
+ & (SEC_ALLOC | SEC_LOAD)) == (SEC_ALLOC | SEC_LOAD))
+
+ {
+ /* Check address to be modified is writable. */
+ if (_lm32fdpic_osec_readonly_p (output_bfd,
+ input_section
+ ->output_section))
+ {
+ info->callbacks->warning
+ (info,
+ _("cannot emit dynamic relocations in read-only section"),
+ name, input_bfd, input_section, rel->r_offset);
+ return FALSE;
+ }
+ /* Create entry in .rofixup section. */
+ _lm32fdpic_add_rofixup (output_bfd,
+ lm32fdpic_fixup32_section (info),
+ input_section->output_section->vma
+ + input_section->output_offset
+ + rel->r_offset);
+ }
+ }
+ }
+ /* Fall through. */
+
+ default:
+ r = _bfd_final_link_relocate (howto,
+ input_bfd,
+ input_section,
+ contents,
+ rel->r_offset,
+ relocation,
+ rel->r_addend);
+ break;
+ }
+ }
+
+ if (r != bfd_reloc_ok)
+ {
+ const char *msg = NULL;
+ arelent bfd_reloc;
+
+ lm32_info_to_howto_rela (input_bfd, &bfd_reloc, rel);
+ howto = bfd_reloc.howto;
+
+ 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 ((h != NULL)
+ && (h->root.type == bfd_link_hash_undefweak))
+ break;
+ if (! ((*info->callbacks->reloc_overflow)
+ (info, (h ? &h->root : NULL), 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, TRUE)))
+ 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;
+}
+
+static asection *
+lm32_elf_gc_mark_hook (asection *sec,
+ 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_LM32_GNU_VTINHERIT:
+ case R_LM32_GNU_VTENTRY:
+ return NULL;
+ }
+
+ return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
+}
+
+static bfd_boolean
+lm32_elf_gc_sweep_hook (bfd *abfd,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ asection *sec,
+ const Elf_Internal_Rela *relocs ATTRIBUTE_UNUSED)
+{
+ /* Update the got entry reference counts for the section being removed. */
+ Elf_Internal_Shdr *symtab_hdr;
+ struct elf_link_hash_entry **sym_hashes;
+ bfd_signed_vma *local_got_refcounts;
+ const Elf_Internal_Rela *rel, *relend;
+
+ elf_section_data (sec)->local_dynrel = NULL;
+
+ 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++)
+ {
+ unsigned long r_symndx;
+ struct elf_link_hash_entry *h = NULL;
+
+ r_symndx = ELF32_R_SYM (rel->r_info);
+ if (r_symndx >= symtab_hdr->sh_info)
+ {
+ 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;
+ }
+
+ switch (ELF32_R_TYPE (rel->r_info))
+ {
+ case R_LM32_16_GOT:
+ if (h != NULL)
+ {
+ if (h->got.refcount > 0)
+ h->got.refcount--;
+ }
+ else
+ {
+ if (local_got_refcounts && local_got_refcounts[r_symndx] > 0)
+ local_got_refcounts[r_symndx]--;
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ return TRUE;
+}
+
+/* Look through the relocs for a section during the first phase. */
+
+static bfd_boolean
+lm32_elf_check_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;
+ struct elf_lm32_link_hash_table *htab;
+ bfd *dynobj;
+
+ if (info->relocatable)
+ 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;
+
+ htab = lm32_elf_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ dynobj = htab->root.dynobj;
+
+ rel_end = relocs + sec->reloc_count;
+ for (rel = relocs; rel < rel_end; rel++)
+ {
+ int r_type;
+ struct elf_link_hash_entry *h;
+ unsigned long r_symndx;
+
+ r_symndx = ELF32_R_SYM (rel->r_info);
+ r_type = ELF32_R_TYPE (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.type == bfd_link_hash_indirect
+ || h->root.type == bfd_link_hash_warning)
+ h = (struct elf_link_hash_entry *) h->root.u.i.link;
+
+ /* PR15323, ref flags aren't set for references in the same
+ object. */
+ h->root.non_ir_ref = 1;
+ }
+
+ /* Some relocs require a global offset table. */
+ if (htab->sgot == NULL)
+ {
+ switch (r_type)
+ {
+ case R_LM32_16_GOT:
+ case R_LM32_GOTOFF_HI16:
+ case R_LM32_GOTOFF_LO16:
+ if (dynobj == NULL)
+ htab->root.dynobj = dynobj = abfd;
+ if (! create_got_section (dynobj, info))
+ return FALSE;
+ break;
+ }
+ }
+
+ /* Some relocs require a rofixup table. */
+ if (IS_FDPIC (abfd))
+ {
+ switch (r_type)
+ {
+ case R_LM32_32:
+ /* FDPIC requires a GOT if there is a .rofixup section
+ (Normal ELF doesn't). */
+ if (dynobj == NULL)
+ htab->root.dynobj = dynobj = abfd;
+ if (! create_got_section (dynobj, info))
+ return FALSE;
+ /* Create .rofixup section */
+ if (htab->sfixup32 == NULL)
+ {
+ if (! create_rofixup_section (dynobj, info))
+ return FALSE;
+ }
+ break;
+ case R_LM32_16_GOT:
+ case R_LM32_GOTOFF_HI16:
+ case R_LM32_GOTOFF_LO16:
+ /* Create .rofixup section. */
+ if (htab->sfixup32 == NULL)
+ {
+ if (dynobj == NULL)
+ htab->root.dynobj = dynobj = abfd;
+ if (! create_rofixup_section (dynobj, info))
+ return FALSE;
+ }
+ break;
+ }
+ }
+
+ switch (r_type)
+ {
+ case R_LM32_16_GOT:
+ if (h != NULL)
+ h->got.refcount += 1;
+ else
+ {
+ bfd_signed_vma *local_got_refcounts;
+
+ /* This is a global offset table entry for a local symbol. */
+ local_got_refcounts = elf_local_got_refcounts (abfd);
+ if (local_got_refcounts == NULL)
+ {
+ bfd_size_type size;
+
+ size = symtab_hdr->sh_info;
+ size *= sizeof (bfd_signed_vma);
+ local_got_refcounts = bfd_zalloc (abfd, size);
+ if (local_got_refcounts == NULL)
+ return FALSE;
+ elf_local_got_refcounts (abfd) = local_got_refcounts;
+ }
+ local_got_refcounts[r_symndx] += 1;
+ }
+ break;
+
+ /* This relocation describes the C++ object vtable hierarchy.
+ Reconstruct it for later use during GC. */
+ case R_LM32_GNU_VTINHERIT:
+ if (!bfd_elf_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_LM32_GNU_VTENTRY:
+ if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
+ return FALSE;
+ break;
+
+ }
+ }
+
+ return TRUE;
+}
+
+/* Finish up the dynamic sections. */
+
+static bfd_boolean
+lm32_elf_finish_dynamic_sections (bfd *output_bfd,
+ struct bfd_link_info *info)
+{
+ struct elf_lm32_link_hash_table *htab;
+ bfd *dynobj;
+ asection *sdyn;
+ asection *sgot;
+
+ htab = lm32_elf_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ dynobj = htab->root.dynobj;
+
+ sgot = htab->sgotplt;
+ sdyn = bfd_get_linker_section (dynobj, ".dynamic");
+
+ if (htab->root.dynamic_sections_created)
+ {
+ asection *splt;
+ Elf32_External_Dyn *dyncon, *dynconend;
+
+ BFD_ASSERT (sgot != NULL && sdyn != NULL);
+
+ dyncon = (Elf32_External_Dyn *) sdyn->contents;
+ dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->size);
+
+ for (; dyncon < dynconend; dyncon++)
+ {
+ Elf_Internal_Dyn dyn;
+ asection *s;
+
+ bfd_elf32_swap_dyn_in (dynobj, dyncon, &dyn);
+
+ switch (dyn.d_tag)
+ {
+ default:
+ break;
+
+ case DT_PLTGOT:
+ s = htab->sgot->output_section;
+ goto get_vma;
+ case DT_JMPREL:
+ s = htab->srelplt->output_section;
+ get_vma:
+ 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 = htab->srelplt->output_section;
+ BFD_ASSERT (s != NULL);
+ dyn.d_un.d_val = s->size;
+ bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
+ break;
+
+ case DT_RELASZ:
+ /* My reading of the SVR4 ABI indicates that the
+ procedure linkage table relocs (DT_JMPREL) should be
+ included in the overall relocs (DT_RELA). This is
+ what Solaris does. However, UnixWare can not handle
+ that case. 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. */
+ if (htab->srelplt != NULL)
+ {
+ s = htab->srelplt->output_section;
+ dyn.d_un.d_val -= s->size;
+ }
+ bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
+ break;
+ }
+ }
+
+ /* Fill in the first entry in the procedure linkage table. */
+ splt = htab->splt;
+ if (splt && splt->size > 0)
+ {
+ if (info->shared)
+ {
+ bfd_put_32 (output_bfd, PLT0_PIC_ENTRY_WORD0, splt->contents);
+ bfd_put_32 (output_bfd, PLT0_PIC_ENTRY_WORD1, splt->contents + 4);
+ bfd_put_32 (output_bfd, PLT0_PIC_ENTRY_WORD2, splt->contents + 8);
+ bfd_put_32 (output_bfd, PLT0_PIC_ENTRY_WORD3, splt->contents + 12);
+ bfd_put_32 (output_bfd, PLT0_PIC_ENTRY_WORD4, splt->contents + 16);
+ }
+ else
+ {
+ unsigned long addr;
+ /* addr = .got + 4 */
+ addr = sgot->output_section->vma + sgot->output_offset + 4;
+ bfd_put_32 (output_bfd,
+ PLT0_ENTRY_WORD0 | ((addr >> 16) & 0xffff),
+ splt->contents);
+ bfd_put_32 (output_bfd,
+ PLT0_ENTRY_WORD1 | (addr & 0xffff),
+ splt->contents + 4);
+ bfd_put_32 (output_bfd, PLT0_ENTRY_WORD2, splt->contents + 8);
+ bfd_put_32 (output_bfd, PLT0_ENTRY_WORD3, splt->contents + 12);
+ bfd_put_32 (output_bfd, PLT0_ENTRY_WORD4, splt->contents + 16);
+ }
+
+ 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 && sgot->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);
+
+ /* FIXME: This can be null if create_dynamic_sections wasn't called. */
+ if (elf_section_data (sgot->output_section) != NULL)
+ elf_section_data (sgot->output_section)->this_hdr.sh_entsize = 4;
+ }
+
+ if (lm32fdpic_fixup32_section (info))
+ {
+ struct elf_link_hash_entry *hgot = elf_hash_table (info)->hgot;
+ bfd_vma got_value = hgot->root.u.def.value
+ + hgot->root.u.def.section->output_section->vma
+ + hgot->root.u.def.section->output_offset;
+ struct bfd_link_hash_entry *hend;
+
+ /* Last entry is pointer to GOT. */
+ _lm32fdpic_add_rofixup (output_bfd, lm32fdpic_fixup32_section (info), got_value);
+
+ /* Check we wrote enough entries. */
+ if (lm32fdpic_fixup32_section (info)->size
+ != (lm32fdpic_fixup32_section (info)->reloc_count * 4))
+ {
+ (*_bfd_error_handler)
+ ("LINKER BUG: .rofixup section size mismatch: size/4 %d != relocs %d",
+ lm32fdpic_fixup32_section (info)->size/4,
+ lm32fdpic_fixup32_section (info)->reloc_count);
+ return FALSE;
+ }
+
+ hend = bfd_link_hash_lookup (info->hash, "__ROFIXUP_END__",
+ FALSE, FALSE, TRUE);
+ if (hend
+ && (hend->type == bfd_link_hash_defined
+ || hend->type == bfd_link_hash_defweak))
+ {
+ bfd_vma value =
+ lm32fdpic_fixup32_section (info)->output_section->vma
+ + lm32fdpic_fixup32_section (info)->output_offset
+ + lm32fdpic_fixup32_section (info)->size
+ - hend->u.def.section->output_section->vma
+ - hend->u.def.section->output_offset;
+ BFD_ASSERT (hend->u.def.value == value);
+ if (hend->u.def.value != value)
+ {
+ (*_bfd_error_handler)
+ ("LINKER BUG: .rofixup section hend->u.def.value != value: %ld != %ld", hend->u.def.value, value);
+ return FALSE;
+ }
+ }
+ }
+
+ return TRUE;
+}
+
+/* Finish up dynamic symbol handling. We set the contents of various
+ dynamic sections here. */
+
+static bfd_boolean
+lm32_elf_finish_dynamic_symbol (bfd *output_bfd,
+ struct bfd_link_info *info,
+ struct elf_link_hash_entry *h,
+ Elf_Internal_Sym *sym)
+{
+ struct elf_lm32_link_hash_table *htab;
+ bfd_byte *loc;
+
+ htab = lm32_elf_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ 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 = htab->splt;
+ sgot = htab->sgotplt;
+ srela = htab->srelplt;
+ 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. */
+ if (! info->shared)
+ {
+ /* TODO */
+ }
+ else
+ {
+ /* TODO */
+ }
+
+ /* Fill in the entry in the global offset table. */
+ bfd_put_32 (output_bfd,
+ (splt->output_section->vma
+ + splt->output_offset
+ + h->plt.offset
+ + 12), /* same offset */
+ 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_LM32_JMP_SLOT);
+ rela.r_addend = 0;
+ loc = srela->contents;
+ loc += plt_index * sizeof (Elf32_External_Rela);
+ bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
+
+ if (!h->def_regular)
+ {
+ /* 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 = htab->sgot;
+ srela = htab->srelgot;
+ 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->forced_local)
+ && h->def_regular)
+ {
+ rela.r_info = ELF32_R_INFO (0, R_LM32_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_LM32_GLOB_DAT);
+ rela.r_addend = 0;
+ }
+
+ loc = srela->contents;
+ loc += srela->reloc_count * sizeof (Elf32_External_Rela);
+ bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
+ ++srela->reloc_count;
+ }
+
+ if (h->needs_copy)
+ {
+ asection *s;
+ Elf_Internal_Rela rela;
+
+ /* This symbols 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_linker_section (htab->root.dynobj, ".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_LM32_COPY);
+ rela.r_addend = 0;
+ loc = s->contents;
+ loc += s->reloc_count * sizeof (Elf32_External_Rela);
+ bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
+ ++s->reloc_count;
+ }
+
+ /* Mark some specially defined symbols as absolute. */
+ if (h == htab->root.hdynamic || h == htab->root.hgot)
+ sym->st_shndx = SHN_ABS;
+
+ return TRUE;
+}
+
+static enum elf_reloc_type_class
+lm32_elf_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ const asection *rel_sec ATTRIBUTE_UNUSED,
+ const Elf_Internal_Rela *rela)
+{
+ switch ((int) ELF32_R_TYPE (rela->r_info))
+ {
+ case R_LM32_RELATIVE: return reloc_class_relative;
+ case R_LM32_JMP_SLOT: return reloc_class_plt;
+ case R_LM32_COPY: return reloc_class_copy;
+ default: return reloc_class_normal;
+ }
+}
+
+/* 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 bfd_boolean
+lm32_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
+ struct elf_link_hash_entry *h)
+{
+ struct elf_lm32_link_hash_table *htab;
+ struct elf_lm32_link_hash_entry *eh;
+ struct elf_lm32_dyn_relocs *p;
+ bfd *dynobj;
+ asection *s;
+
+ dynobj = elf_hash_table (info)->dynobj;
+
+ /* Make sure we know what is going on here. */
+ BFD_ASSERT (dynobj != NULL
+ && (h->needs_plt
+ || h->u.weakdef != NULL
+ || (h->def_dynamic
+ && h->ref_regular
+ && !h->def_regular)));
+
+ /* 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->needs_plt)
+ {
+ if (! info->shared
+ && !h->def_dynamic
+ && !h->ref_dynamic
+ && h->root.type != bfd_link_hash_undefweak
+ && h->root.type != bfd_link_hash_undefined)
+ {
+ /* This case can occur if we saw a PLT 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 PCREL
+ reloc instead. */
+ h->plt.offset = (bfd_vma) -1;
+ h->needs_plt = 0;
+ }
+
+ return TRUE;
+ }
+ else
+ 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->u.weakdef != NULL)
+ {
+ BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
+ || h->u.weakdef->root.type == bfd_link_hash_defweak);
+ h->root.u.def.section = h->u.weakdef->root.u.def.section;
+ h->root.u.def.value = h->u.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;
+
+ /* If there are no references to this symbol that do not use the
+ GOT, we don't need to generate a copy reloc. */
+ if (!h->non_got_ref)
+ return TRUE;
+
+ /* If -z nocopyreloc was given, we won't generate them either. */
+ if (info->nocopyreloc)
+ {
+ h->non_got_ref = 0;
+ return TRUE;
+ }
+
+ eh = (struct elf_lm32_link_hash_entry *) h;
+ for (p = eh->dyn_relocs; p != NULL; p = p->next)
+ {
+ s = p->sec->output_section;
+ if (s != NULL && (s->flags & (SEC_READONLY | SEC_HAS_CONTENTS)) != 0)
+ break;
+ }
+
+ /* If we didn't find any dynamic relocs in sections which needs the
+ copy reloc, then we'll be keeping the dynamic relocs and avoiding
+ the copy reloc. */
+ if (p == NULL)
+ {
+ h->non_got_ref = 0;
+ 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. */
+
+ htab = lm32_elf_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ s = htab->sdynbss;
+ BFD_ASSERT (s != NULL);
+
+ /* We must generate a R_LM32_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 && h->size != 0)
+ {
+ asection *srel;
+
+ srel = htab->srelbss;
+ BFD_ASSERT (srel != NULL);
+ srel->size += sizeof (Elf32_External_Rela);
+ h->needs_copy = 1;
+ }
+
+ return _bfd_elf_adjust_dynamic_copy (h, s);
+}
+
+/* Allocate space in .plt, .got and associated reloc sections for
+ dynamic relocs. */
+
+static bfd_boolean
+allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
+{
+ struct bfd_link_info *info;
+ struct elf_lm32_link_hash_table *htab;
+ struct elf_lm32_link_hash_entry *eh;
+ struct elf_lm32_dyn_relocs *p;
+
+ if (h->root.type == bfd_link_hash_indirect)
+ return TRUE;
+
+ info = (struct bfd_link_info *) inf;
+ htab = lm32_elf_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ eh = (struct elf_lm32_link_hash_entry *) h;
+
+ if (htab->root.dynamic_sections_created
+ && h->plt.refcount > 0)
+ {
+ /* Make sure this symbol is output as a dynamic symbol.
+ Undefined weak syms won't yet be marked as dynamic. */
+ if (h->dynindx == -1
+ && !h->forced_local)
+ {
+ if (! bfd_elf_link_record_dynamic_symbol (info, h))
+ return FALSE;
+ }
+
+ if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, info->shared, h))
+ {
+ asection *s = htab->splt;
+
+ /* If this is the first .plt entry, make room for the special
+ first entry. */
+ if (s->size == 0)
+ s->size += PLT_ENTRY_SIZE;
+
+ h->plt.offset = s->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->def_regular)
+ {
+ h->root.u.def.section = s;
+ h->root.u.def.value = h->plt.offset;
+ }
+
+ /* Make room for this entry. */
+ s->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. */
+ htab->sgotplt->size += 4;
+
+ /* We also need to make an entry in the .rel.plt section. */
+ htab->srelplt->size += sizeof (Elf32_External_Rela);
+ }
+ else
+ {
+ h->plt.offset = (bfd_vma) -1;
+ h->needs_plt = 0;
+ }
+ }
+ else
+ {
+ h->plt.offset = (bfd_vma) -1;
+ h->needs_plt = 0;
+ }
+
+ if (h->got.refcount > 0)
+ {
+ asection *s;
+ bfd_boolean dyn;
+
+ /* Make sure this symbol is output as a dynamic symbol.
+ Undefined weak syms won't yet be marked as dynamic. */
+ if (h->dynindx == -1
+ && !h->forced_local)
+ {
+ if (! bfd_elf_link_record_dynamic_symbol (info, h))
+ return FALSE;
+ }
+
+ s = htab->sgot;
+
+ h->got.offset = s->size;
+ s->size += 4;
+ dyn = htab->root.dynamic_sections_created;
+ if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h))
+ htab->srelgot->size += sizeof (Elf32_External_Rela);
+ }
+ else
+ h->got.offset = (bfd_vma) -1;
+
+ if (eh->dyn_relocs == NULL)
+ return TRUE;
+
+ /* In the shared -Bsymbolic case, discard space allocated for
+ dynamic pc-relative relocs against symbols which turn out to be
+ defined in regular objects. For the normal shared case, discard
+ space for pc-relative relocs that have become local due to symbol
+ visibility changes. */
+
+ if (info->shared)
+ {
+ if (h->def_regular
+ && (h->forced_local
+ || info->symbolic))
+ {
+ struct elf_lm32_dyn_relocs **pp;
+
+ for (pp = &eh->dyn_relocs; (p = *pp) != NULL;)
+ {
+ p->count -= p->pc_count;
+ p->pc_count = 0;
+ if (p->count == 0)
+ *pp = p->next;
+ else
+ pp = &p->next;
+ }
+ }
+
+ /* Also discard relocs on undefined weak syms with non-default
+ visibility. */
+ if (eh->dyn_relocs != NULL
+ && h->root.type == bfd_link_hash_undefweak)
+ {
+ if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
+ eh->dyn_relocs = NULL;
+
+ /* Make sure undefined weak symbols are output as a dynamic
+ symbol in PIEs. */
+ else if (h->dynindx == -1
+ && !h->forced_local)
+ {
+ if (! bfd_elf_link_record_dynamic_symbol (info, h))
+ return FALSE;
+ }
+ }
+ }
+ else
+ {
+ /* For the non-shared case, discard space for relocs against
+ symbols which turn out to need copy relocs or are not
+ dynamic. */
+
+ if (!h->non_got_ref
+ && ((h->def_dynamic
+ && !h->def_regular)
+ || (htab->root.dynamic_sections_created
+ && (h->root.type == bfd_link_hash_undefweak
+ || h->root.type == bfd_link_hash_undefined))))
+ {
+ /* Make sure this symbol is output as a dynamic symbol.
+ Undefined weak syms won't yet be marked as dynamic. */
+ if (h->dynindx == -1
+ && !h->forced_local)
+ {
+ if (! bfd_elf_link_record_dynamic_symbol (info, h))
+ return FALSE;
+ }
+
+ /* If that succeeded, we know we'll be keeping all the
+ relocs. */
+ if (h->dynindx != -1)
+ goto keep;
+ }
+
+ eh->dyn_relocs = NULL;
+
+ keep: ;
+ }
+
+ /* Finally, allocate space. */
+ for (p = eh->dyn_relocs; p != NULL; p = p->next)
+ {
+ asection *sreloc = elf_section_data (p->sec)->sreloc;
+ sreloc->size += p->count * sizeof (Elf32_External_Rela);
+ }
+
+ return TRUE;
+}
+
+/* Find any dynamic relocs that apply to read-only sections. */
+
+static bfd_boolean
+readonly_dynrelocs (struct elf_link_hash_entry *h, void * inf)
+{
+ struct elf_lm32_link_hash_entry *eh;
+ struct elf_lm32_dyn_relocs *p;
+
+ eh = (struct elf_lm32_link_hash_entry *) h;
+ for (p = eh->dyn_relocs; p != NULL; p = p->next)
+ {
+ asection *s = p->sec->output_section;
+
+ if (s != NULL && (s->flags & SEC_READONLY) != 0)
+ {
+ struct bfd_link_info *info = (struct bfd_link_info *) inf;
+
+ info->flags |= DF_TEXTREL;
+
+ /* Not an error, just cut short the traversal. */
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+/* Set the sizes of the dynamic sections. */
+
+static bfd_boolean
+lm32_elf_size_dynamic_sections (bfd *output_bfd,
+ struct bfd_link_info *info)
+{
+ struct elf_lm32_link_hash_table *htab;
+ bfd *dynobj;
+ asection *s;
+ bfd_boolean relocs;
+ bfd *ibfd;
+
+ htab = lm32_elf_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ dynobj = htab->root.dynobj;
+ BFD_ASSERT (dynobj != NULL);
+
+ if (htab->root.dynamic_sections_created)
+ {
+ /* Set the contents of the .interp section to the interpreter. */
+ if (info->executable)
+ {
+ s = bfd_get_linker_section (dynobj, ".interp");
+ BFD_ASSERT (s != NULL);
+ s->size = sizeof ELF_DYNAMIC_INTERPRETER;
+ s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
+ }
+ }
+
+ /* Set up .got offsets for local syms, and space for local dynamic
+ relocs. */
+ for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next)
+ {
+ bfd_signed_vma *local_got;
+ bfd_signed_vma *end_local_got;
+ bfd_size_type locsymcount;
+ Elf_Internal_Shdr *symtab_hdr;
+ asection *srel;
+
+ if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour)
+ continue;
+
+ for (s = ibfd->sections; s != NULL; s = s->next)
+ {
+ struct elf_lm32_dyn_relocs *p;
+
+ for (p = ((struct elf_lm32_dyn_relocs *)
+ elf_section_data (s)->local_dynrel);
+ p != NULL;
+ p = p->next)
+ {
+ if (! bfd_is_abs_section (p->sec)
+ && bfd_is_abs_section (p->sec->output_section))
+ {
+ /* Input section has been discarded, either because
+ it is a copy of a linkonce section or due to
+ linker script /DISCARD/, so we'll be discarding
+ the relocs too. */
+ }
+ else if (p->count != 0)
+ {
+ srel = elf_section_data (p->sec)->sreloc;
+ srel->size += p->count * sizeof (Elf32_External_Rela);
+ if ((p->sec->output_section->flags & SEC_READONLY) != 0)
+ info->flags |= DF_TEXTREL;
+ }
+ }
+ }
+
+ local_got = elf_local_got_refcounts (ibfd);
+ if (!local_got)
+ continue;
+
+ symtab_hdr = &elf_tdata (ibfd)->symtab_hdr;
+ locsymcount = symtab_hdr->sh_info;
+ end_local_got = local_got + locsymcount;
+ s = htab->sgot;
+ srel = htab->srelgot;
+ for (; local_got < end_local_got; ++local_got)
+ {
+ if (*local_got > 0)
+ {
+ *local_got = s->size;
+ s->size += 4;
+ if (info->shared)
+ srel->size += sizeof (Elf32_External_Rela);
+ }
+ else
+ *local_got = (bfd_vma) -1;
+ }
+ }
+
+ /* Allocate global sym .plt and .got entries, and space for global
+ sym dynamic relocs. */
+ elf_link_hash_traverse (&htab->root, allocate_dynrelocs, info);
+
+ /* We now have determined the sizes of the various dynamic sections.
+ Allocate memory for them. */
+ relocs = FALSE;
+ for (s = dynobj->sections; s != NULL; s = s->next)
+ {
+ if ((s->flags & SEC_LINKER_CREATED) == 0)
+ continue;
+
+ if (s == htab->splt
+ || s == htab->sgot
+ || s == htab->sgotplt
+ || s == htab->sdynbss)
+ {
+ /* Strip this section if we don't need it; see the
+ comment below. */
+ }
+ else if (CONST_STRNEQ (bfd_get_section_name (dynobj, s), ".rela"))
+ {
+ if (s->size != 0 && s != htab->srelplt)
+ relocs = 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
+ /* It's not one of our sections, so don't allocate space. */
+ continue;
+
+ if (s->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. */
+ s->flags |= SEC_EXCLUDE;
+ continue;
+ }
+
+ if ((s->flags & SEC_HAS_CONTENTS) == 0)
+ continue;
+
+ /* Allocate memory for the section contents. We use bfd_zalloc
+ here in case unused entries are not reclaimed before the
+ section's contents are written out. This should not happen,
+ but this way if it does, we get a R_LM32_NONE reloc instead
+ of garbage. */
+ s->contents = bfd_zalloc (dynobj, s->size);
+ if (s->contents == NULL)
+ return FALSE;
+ }
+
+ if (htab->root.dynamic_sections_created)
+ {
+ /* Add some entries to the .dynamic section. We fill in the
+ values later, in lm32_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. */
+#define add_dynamic_entry(TAG, VAL) \
+ _bfd_elf_add_dynamic_entry (info, TAG, VAL)
+
+ if (info->executable)
+ {
+ if (! add_dynamic_entry (DT_DEBUG, 0))
+ return FALSE;
+ }
+
+ if (htab->splt->size != 0)
+ {
+ if (! add_dynamic_entry (DT_PLTGOT, 0)
+ || ! add_dynamic_entry (DT_PLTRELSZ, 0)
+ || ! add_dynamic_entry (DT_PLTREL, DT_RELA)
+ || ! add_dynamic_entry (DT_JMPREL, 0))
+ return FALSE;
+ }
+
+ if (relocs)
+ {
+ if (! add_dynamic_entry (DT_RELA, 0)
+ || ! add_dynamic_entry (DT_RELASZ, 0)
+ || ! add_dynamic_entry (DT_RELAENT,
+ sizeof (Elf32_External_Rela)))
+ return FALSE;
+
+ /* If any dynamic relocs apply to a read-only section,
+ then we need a DT_TEXTREL entry. */
+ if ((info->flags & DF_TEXTREL) == 0)
+ elf_link_hash_traverse (&htab->root, readonly_dynrelocs,
+ info);
+
+ if ((info->flags & DF_TEXTREL) != 0)
+ {
+ if (! add_dynamic_entry (DT_TEXTREL, 0))
+ return FALSE;
+ }
+ }
+ }
+#undef add_dynamic_entry
+
+ /* Allocate .rofixup section. */
+ if (IS_FDPIC (output_bfd))
+ {
+ struct weak_symbol_list *list_start = NULL, *list_end = NULL;
+ int rgot_weak_count = 0;
+ int r32_count = 0;
+ int rgot_count = 0;
+ /* Look for deleted sections. */
+ for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next)
+ {
+ for (s = ibfd->sections; s != NULL; s = s->next)
+ {
+ if (s->reloc_count)
+ {
+ /* Count relocs that need .rofixup entires. */
+ Elf_Internal_Rela *internal_relocs, *end;
+ internal_relocs = elf_section_data (s)->relocs;
+ if (internal_relocs == NULL)
+ internal_relocs = (_bfd_elf_link_read_relocs (ibfd, s, NULL, NULL, FALSE));
+ if (internal_relocs != NULL)
+ {
+ end = internal_relocs + s->reloc_count;
+ while (internal_relocs < end)
+ {
+ Elf_Internal_Shdr *symtab_hdr = &elf_tdata (ibfd)->symtab_hdr;
+ struct elf_link_hash_entry **sym_hashes = elf_sym_hashes (ibfd);
+ unsigned long r_symndx;
+ struct elf_link_hash_entry *h;
+
+ symtab_hdr = &elf_tdata (ibfd)->symtab_hdr;
+ sym_hashes = elf_sym_hashes (ibfd);
+ r_symndx = ELF32_R_SYM (internal_relocs->r_info);
+ h = NULL;
+ if (r_symndx < symtab_hdr->sh_info)
+ {
+ }
+ 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;
+ }
+
+ /* Don't generate entries for weak symbols. */
+ if (!h || (h && h->root.type != bfd_link_hash_undefweak))
+ {
+ if (!discarded_section (s) && !((bfd_get_section_flags (ibfd, s) & SEC_ALLOC) == 0))
+ {
+ switch (ELF32_R_TYPE (internal_relocs->r_info))
+ {
+ case R_LM32_32:
+ r32_count++;
+ break;
+ case R_LM32_16_GOT:
+ rgot_count++;
+ break;
+ }
+ }
+ }
+ else
+ {
+ struct weak_symbol_list *current, *new_entry;
+ /* Is this symbol already in the list? */
+ for (current = list_start; current; current = current->next)
+ {
+ if (!strcmp (current->name, h->root.root.string))
+ break;
+ }
+ if (!current && !discarded_section (s) && (bfd_get_section_flags (ibfd, s) & SEC_ALLOC))
+ {
+ /* Will this have an entry in the GOT. */
+ if (ELF32_R_TYPE (internal_relocs->r_info) == R_LM32_16_GOT)
+ {
+ /* Create a new entry. */
+ new_entry = malloc (sizeof (struct weak_symbol_list));
+ if (!new_entry)
+ return FALSE;
+ new_entry->name = h->root.root.string;
+ new_entry->next = NULL;
+ /* Add to list */
+ if (list_start == NULL)
+ {
+ list_start = new_entry;
+ list_end = new_entry;
+ }
+ else
+ {
+ list_end->next = new_entry;
+ list_end = new_entry;
+ }
+ /* Increase count of undefined weak symbols in the got. */
+ rgot_weak_count++;
+ }
+ }
+ }
+ internal_relocs++;
+ }
+ }
+ else
+ return FALSE;
+ }
+ }
+ }
+ /* Free list. */
+ while (list_start)
+ {
+ list_end = list_start->next;
+ free (list_start);
+ list_start = list_end;
+ }
+
+ /* Size sections. */
+ lm32fdpic_fixup32_section (info)->size = (r32_count + (htab->sgot->size / 4) - rgot_weak_count + 1) * 4;
+ if (lm32fdpic_fixup32_section (info)->size == 0)
+ lm32fdpic_fixup32_section (info)->flags |= SEC_EXCLUDE;
+ else
+ {
+ lm32fdpic_fixup32_section (info)->contents =
+ bfd_zalloc (dynobj, lm32fdpic_fixup32_section (info)->size);
+ if (lm32fdpic_fixup32_section (info)->contents == NULL)
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+/* Create dynamic sections when linking against a dynamic object. */
+
+static bfd_boolean
+lm32_elf_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
+{
+ struct elf_lm32_link_hash_table *htab;
+ flagword flags, pltflags;
+ asection *s;
+ const struct elf_backend_data *bed = get_elf_backend_data (abfd);
+ int ptralign = 2; /* 32bit */
+
+ htab = lm32_elf_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ /* Make sure we have a GOT - For the case where we have a dynamic object
+ but none of the relocs in check_relocs */
+ if (! create_got_section (abfd, info))
+ return FALSE;
+ if (IS_FDPIC (abfd) && (htab->sfixup32 == NULL))
+ {
+ if (! create_rofixup_section (abfd, info))
+ return FALSE;
+ }
+
+ /* 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_anyway_with_flags (abfd, ".plt", pltflags);
+ htab->splt = s;
+ if (s == NULL
+ || ! 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 bfd_link_hash_entry *bh = NULL;
+ struct elf_link_hash_entry *h;
+
+ if (! (_bfd_generic_link_add_one_symbol
+ (info, abfd, "_PROCEDURE_LINKAGE_TABLE_", BSF_GLOBAL, s,
+ (bfd_vma) 0, NULL, FALSE,
+ get_elf_backend_data (abfd)->collect, &bh)))
+ return FALSE;
+ h = (struct elf_link_hash_entry *) bh;
+ h->def_regular = 1;
+ h->type = STT_OBJECT;
+ htab->root.hplt = h;
+
+ if (info->shared
+ && ! bfd_elf_link_record_dynamic_symbol (info, h))
+ return FALSE;
+ }
+
+ s = bfd_make_section_anyway_with_flags (abfd,
+ bed->default_use_rela_p
+ ? ".rela.plt" : ".rel.plt",
+ flags | SEC_READONLY);
+ htab->srelplt = s;
+ if (s == NULL
+ || ! bfd_set_section_alignment (abfd, s, ptralign))
+ return FALSE;
+
+ if (htab->sgot == NULL
+ && ! create_got_section (abfd, info))
+ return FALSE;
+
+ if (bed->want_dynbss)
+ {
+ /* 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_anyway_with_flags (abfd, ".dynbss",
+ SEC_ALLOC | SEC_LINKER_CREATED);
+ htab->sdynbss = s;
+ if (s == NULL)
+ 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_anyway_with_flags (abfd,
+ (bed->default_use_rela_p
+ ? ".rela.bss" : ".rel.bss"),
+ flags | SEC_READONLY);
+ htab->srelbss = s;
+ if (s == NULL
+ || ! bfd_set_section_alignment (abfd, s, ptralign))
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+/* Copy the extra info we tack onto an elf_link_hash_entry. */
+
+static void
+lm32_elf_copy_indirect_symbol (struct bfd_link_info *info,
+ struct elf_link_hash_entry *dir,
+ struct elf_link_hash_entry *ind)
+{
+ struct elf_lm32_link_hash_entry * edir;
+ struct elf_lm32_link_hash_entry * eind;
+
+ edir = (struct elf_lm32_link_hash_entry *) dir;
+ eind = (struct elf_lm32_link_hash_entry *) ind;
+
+ if (eind->dyn_relocs != NULL)
+ {
+ if (edir->dyn_relocs != NULL)
+ {
+ struct elf_lm32_dyn_relocs **pp;
+ struct elf_lm32_dyn_relocs *p;
+
+ /* Add reloc counts against the indirect sym to the direct sym
+ list. Merge any entries against the same section. */
+ for (pp = &eind->dyn_relocs; (p = *pp) != NULL;)
+ {
+ struct elf_lm32_dyn_relocs *q;
+
+ for (q = edir->dyn_relocs; q != NULL; q = q->next)
+ if (q->sec == p->sec)
+ {
+ q->pc_count += p->pc_count;
+ q->count += p->count;
+ *pp = p->next;
+ break;
+ }
+ if (q == NULL)
+ pp = &p->next;
+ }
+ *pp = edir->dyn_relocs;
+ }
+
+ edir->dyn_relocs = eind->dyn_relocs;
+ eind->dyn_relocs = NULL;
+ }
+
+ _bfd_elf_link_hash_copy_indirect (info, dir, ind);
+}
+
+static bfd_boolean
+lm32_elf_always_size_sections (bfd *output_bfd, struct bfd_link_info *info)
+{
+ if (!info->relocatable)
+ {
+ if (!bfd_elf_stack_segment_size (output_bfd, info,
+ "__stacksize", DEFAULT_STACK_SIZE))
+ return FALSE;
+
+ asection *sec = bfd_get_section_by_name (output_bfd, ".stack");
+ if (sec)
+ sec->size = info->stacksize >= 0 ? info->stacksize : 0;
+ }
+
+ return TRUE;
+}
+
+static bfd_boolean
+lm32_elf_fdpic_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
+{
+ unsigned i;
+
+ if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
+ || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
+ return TRUE;
+
+ if (! _bfd_elf_copy_private_bfd_data (ibfd, obfd))
+ return FALSE;
+
+ if (! elf_tdata (ibfd) || ! elf_tdata (ibfd)->phdr
+ || ! elf_tdata (obfd) || ! elf_tdata (obfd)->phdr)
+ return TRUE;
+
+ /* Copy the stack size. */
+ for (i = 0; i < elf_elfheader (ibfd)->e_phnum; i++)
+ if (elf_tdata (ibfd)->phdr[i].p_type == PT_GNU_STACK)
+ {
+ Elf_Internal_Phdr *iphdr = &elf_tdata (ibfd)->phdr[i];
+
+ for (i = 0; i < elf_elfheader (obfd)->e_phnum; i++)
+ if (elf_tdata (obfd)->phdr[i].p_type == PT_GNU_STACK)
+ {
+ memcpy (&elf_tdata (obfd)->phdr[i], iphdr, sizeof (*iphdr));
+
+ /* Rewrite the phdrs, since we're only called after they were first written. */
+ if (bfd_seek (obfd, (bfd_signed_vma) get_elf_backend_data (obfd)
+ ->s->sizeof_ehdr, SEEK_SET) != 0
+ || get_elf_backend_data (obfd)->s->write_out_phdrs (obfd, elf_tdata (obfd)->phdr,
+ elf_elfheader (obfd)->e_phnum) != 0)
+ return FALSE;
+ break;
+ }
+
+ break;
+ }
+
+ return TRUE;
+}
+
+
+#define ELF_ARCH bfd_arch_lm32
+#define ELF_TARGET_ID LM32_ELF_DATA
+#define ELF_MACHINE_CODE EM_LATTICEMICO32
+#define ELF_MAXPAGESIZE 0x1000
+
+#define TARGET_BIG_SYM lm32_elf32_vec
+#define TARGET_BIG_NAME "elf32-lm32"
+
+#define bfd_elf32_bfd_reloc_type_lookup lm32_reloc_type_lookup
+#define bfd_elf32_bfd_reloc_name_lookup lm32_reloc_name_lookup
+#define elf_info_to_howto lm32_info_to_howto_rela
+#define elf_info_to_howto_rel 0
+#define elf_backend_rela_normal 1
+#define elf_backend_object_p lm32_elf_object_p
+#define elf_backend_final_write_processing lm32_elf_final_write_processing
+#define elf_backend_stack_align 8
+#define elf_backend_can_gc_sections 1
+#define elf_backend_can_refcount 1
+#define elf_backend_gc_mark_hook lm32_elf_gc_mark_hook
+#define elf_backend_gc_sweep_hook lm32_elf_gc_sweep_hook
+#define elf_backend_plt_readonly 1
+#define elf_backend_want_got_plt 1
+#define elf_backend_want_plt_sym 0
+#define elf_backend_got_header_size 12
+#define bfd_elf32_bfd_link_hash_table_create lm32_elf_link_hash_table_create
+#define elf_backend_check_relocs lm32_elf_check_relocs
+#define elf_backend_reloc_type_class lm32_elf_reloc_type_class
+#define elf_backend_copy_indirect_symbol lm32_elf_copy_indirect_symbol
+#define elf_backend_size_dynamic_sections lm32_elf_size_dynamic_sections
+#define elf_backend_omit_section_dynsym ((bfd_boolean (*) (bfd *, struct bfd_link_info *, asection *)) bfd_true)
+#define elf_backend_create_dynamic_sections lm32_elf_create_dynamic_sections
+#define elf_backend_finish_dynamic_sections lm32_elf_finish_dynamic_sections
+#define elf_backend_adjust_dynamic_symbol lm32_elf_adjust_dynamic_symbol
+#define elf_backend_finish_dynamic_symbol lm32_elf_finish_dynamic_symbol
+#define elf_backend_relocate_section lm32_elf_relocate_section
+
+#include "elf32-target.h"
+
+#undef ELF_MAXPAGESIZE
+#define ELF_MAXPAGESIZE 0x4000
+
+
+#undef TARGET_BIG_SYM
+#define TARGET_BIG_SYM lm32_elf32_fdpic_vec
+#undef TARGET_BIG_NAME
+#define TARGET_BIG_NAME "elf32-lm32fdpic"
+#undef elf32_bed
+#define elf32_bed elf32_lm32fdpic_bed
+
+#undef elf_backend_always_size_sections
+#define elf_backend_always_size_sections lm32_elf_always_size_sections
+#undef bfd_elf32_bfd_copy_private_bfd_data
+#define bfd_elf32_bfd_copy_private_bfd_data lm32_elf_fdpic_copy_private_bfd_data
+
+#include "elf32-target.h"
diff --git a/bfd/elf32-m32c.c b/bfd/elf32-m32c.c
new file mode 100644
index 0000000..3e2c802
--- /dev/null
+++ b/bfd/elf32-m32c.c
@@ -0,0 +1,2080 @@
+/* M16C/M32C specific support for 32-bit ELF.
+ Copyright (C) 2005-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public 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 "bfd.h"
+#include "libbfd.h"
+#include "elf-bfd.h"
+#include "elf/m32c.h"
+#include "libiberty.h"
+
+/* Forward declarations. */
+static reloc_howto_type * m32c_reloc_type_lookup
+ (bfd *, bfd_reloc_code_real_type);
+static void m32c_info_to_howto_rela
+ (bfd *, arelent *, Elf_Internal_Rela *);
+static bfd_boolean m32c_elf_relocate_section
+ (bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *, Elf_Internal_Rela *, Elf_Internal_Sym *, asection **);
+static bfd_boolean m32c_elf_check_relocs
+ (bfd *, struct bfd_link_info *, asection *, const Elf_Internal_Rela *);
+static bfd_boolean m32c_elf_relax_delete_bytes (bfd *, asection *, bfd_vma, int);
+#ifdef DEBUG
+char * m32c_get_reloc (long reloc);
+void dump_symtab (bfd *, void *, void *);
+#endif
+static bfd_boolean m32c_elf_relax_section
+(bfd *abfd, asection *sec, struct bfd_link_info *link_info, bfd_boolean *again);
+
+
+static reloc_howto_type m32c_elf_howto_table [] =
+{
+ /* This reloc does nothing. */
+ HOWTO (R_M32C_NONE, /* type */
+ 0, /* rightshift */
+ 0, /* 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_M32C_NONE", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* GCC intentionally overflows these next two in order to work
+ around limitations in the addressing modes, so don't complain
+ about overflow. */
+ HOWTO (R_M32C_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_M32C_16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_M32C_24, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 24, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_M32C_24", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_M32C_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_M32C_32", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_M32C_8_PCREL, /* type */
+ 0, /* rightshift */
+ 0, /* 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_M32C_8_PCREL", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_M32C_16_PCREL, /* 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_M32C_16_PCREL", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_M32C_8, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 8, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_unsigned, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_M32C_8", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_M32C_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 */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_M32C_LO16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_M32C_HI8, /* 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_M32C_HI8", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_M32C_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 */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_M32C_HI16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_M32C_RL_JUMP, /* 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_M32C_RL_JUMP", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_M32C_RL_1ADDR, /* 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_M32C_RL_1ADDR", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_M32C_RL_2ADDR, /* 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_M32C_RL_2ADDR", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+};
+
+/* Map BFD reloc types to M32C ELF reloc types. */
+
+struct m32c_reloc_map
+{
+ bfd_reloc_code_real_type bfd_reloc_val;
+ unsigned int m32c_reloc_val;
+};
+
+static const struct m32c_reloc_map m32c_reloc_map [] =
+{
+ { BFD_RELOC_NONE, R_M32C_NONE },
+ { BFD_RELOC_16, R_M32C_16 },
+ { BFD_RELOC_24, R_M32C_24 },
+ { BFD_RELOC_32, R_M32C_32 },
+ { BFD_RELOC_8_PCREL, R_M32C_8_PCREL },
+ { BFD_RELOC_16_PCREL, R_M32C_16_PCREL },
+ { BFD_RELOC_8, R_M32C_8 },
+ { BFD_RELOC_LO16, R_M32C_LO16 },
+ { BFD_RELOC_HI16, R_M32C_HI16 },
+ { BFD_RELOC_M32C_HI8, R_M32C_HI8 },
+ { BFD_RELOC_M32C_RL_JUMP, R_M32C_RL_JUMP },
+ { BFD_RELOC_M32C_RL_1ADDR, R_M32C_RL_1ADDR },
+ { BFD_RELOC_M32C_RL_2ADDR, R_M32C_RL_2ADDR }
+};
+
+static reloc_howto_type *
+m32c_reloc_type_lookup
+ (bfd * abfd ATTRIBUTE_UNUSED,
+ bfd_reloc_code_real_type code)
+{
+ unsigned int i;
+
+ for (i = ARRAY_SIZE (m32c_reloc_map); --i;)
+ if (m32c_reloc_map [i].bfd_reloc_val == code)
+ return & m32c_elf_howto_table [m32c_reloc_map[i].m32c_reloc_val];
+
+ return NULL;
+}
+
+static reloc_howto_type *
+m32c_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, const char *r_name)
+{
+ unsigned int i;
+
+ for (i = 0;
+ i < sizeof (m32c_elf_howto_table) / sizeof (m32c_elf_howto_table[0]);
+ i++)
+ if (m32c_elf_howto_table[i].name != NULL
+ && strcasecmp (m32c_elf_howto_table[i].name, r_name) == 0)
+ return &m32c_elf_howto_table[i];
+
+ return NULL;
+}
+
+/* Set the howto pointer for an M32C ELF reloc. */
+
+static void
+m32c_info_to_howto_rela
+ (bfd * abfd ATTRIBUTE_UNUSED,
+ arelent * cache_ptr,
+ Elf_Internal_Rela * dst)
+{
+ unsigned int r_type;
+
+ r_type = ELF32_R_TYPE (dst->r_info);
+ BFD_ASSERT (r_type < (unsigned int) R_M32C_max);
+ cache_ptr->howto = & m32c_elf_howto_table [r_type];
+}
+
+
+
+/* Relocate an M32C 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 relocatable
+ 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 relocatable 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 bfd_boolean
+m32c_elf_relocate_section
+ (bfd * output_bfd ATTRIBUTE_UNUSED,
+ 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;
+ bfd *dynobj;
+ asection *splt;
+
+ symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
+ sym_hashes = elf_sym_hashes (input_bfd);
+ relend = relocs + input_section->reloc_count;
+
+ dynobj = elf_hash_table (info)->dynobj;
+ splt = NULL;
+ if (dynobj != NULL)
+ splt = bfd_get_linker_section (dynobj, ".plt");
+
+ 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);
+
+ /* These are only used for relaxing; we don't actually relocate
+ anything with them, so skip them. */
+ if (r_type == R_M32C_RL_JUMP
+ || r_type == R_M32C_RL_1ADDR
+ || r_type == R_M32C_RL_2ADDR)
+ continue;
+
+ r_symndx = ELF32_R_SYM (rel->r_info);
+
+ howto = m32c_elf_howto_table + ELF32_R_TYPE (rel->r_info);
+ h = NULL;
+ sym = NULL;
+ sec = NULL;
+ relocation = 0;
+
+ 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 = (sym->st_name == 0) ? bfd_section_name (input_bfd, sec) : name;
+ }
+ else
+ {
+ h = sym_hashes [r_symndx - symtab_hdr->sh_info];
+
+ if (info->wrap_hash != NULL
+ && (input_section->flags & SEC_DEBUGGING) != 0)
+ h = ((struct elf_link_hash_entry *)
+ unwrap_hash_lookup (info, input_bfd, &h->root));
+
+ 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);
+ }
+ else if (h->root.type == bfd_link_hash_undefweak)
+ ;
+ else if (!info->relocatable)
+ {
+ if (! ((*info->callbacks->undefined_symbol)
+ (info, h->root.root.string, input_bfd,
+ input_section, rel->r_offset, TRUE)))
+ return FALSE;
+ }
+ }
+
+ if (sec != NULL && discarded_section (sec))
+ RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+ rel, 1, relend, howto, 0, contents);
+
+ if (info->relocatable)
+ {
+ /* This is a relocatable 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 (sym != NULL && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
+ rel->r_addend += sec->output_offset;
+ continue;
+ }
+
+ switch (ELF32_R_TYPE (rel->r_info))
+ {
+ case R_M32C_16:
+ {
+ bfd_vma *plt_offset;
+
+ if (h != NULL)
+ plt_offset = &h->plt.offset;
+ else
+ plt_offset = elf_local_got_offsets (input_bfd) + r_symndx;
+
+ /* printf("%s: rel %x plt %d\n", h ? h->root.root.string : "(none)",
+ relocation, *plt_offset);*/
+ if (relocation <= 0xffff)
+ {
+ /* If the symbol is in range for a 16-bit address, we should
+ have deallocated the plt entry in relax_section. */
+ BFD_ASSERT (*plt_offset == (bfd_vma) -1);
+ }
+ else
+ {
+ /* If the symbol is out of range for a 16-bit address,
+ we must have allocated a plt entry. */
+ BFD_ASSERT (*plt_offset != (bfd_vma) -1);
+
+ /* If this is the first time we've processed this symbol,
+ fill in the plt entry with the correct symbol address. */
+ if ((*plt_offset & 1) == 0)
+ {
+ unsigned int x;
+
+ x = 0x000000fc; /* jmpf */
+ x |= (relocation << 8) & 0xffffff00;
+ bfd_put_32 (input_bfd, x, splt->contents + *plt_offset);
+ *plt_offset |= 1;
+ }
+
+ relocation = (splt->output_section->vma
+ + splt->output_offset
+ + (*plt_offset & -2));
+ if (name)
+ {
+ char *newname = bfd_malloc (strlen(name)+5);
+ strcpy (newname, name);
+ strcat(newname, ".plt");
+ _bfd_generic_link_add_one_symbol (info,
+ input_bfd,
+ newname,
+ BSF_FUNCTION | BSF_WEAK,
+ splt,
+ (*plt_offset & -2),
+ 0,
+ 1,
+ 0,
+ 0);
+ }
+ }
+ }
+ break;
+
+ case R_M32C_HI8:
+ case R_M32C_HI16:
+ relocation >>= 16;
+ break;
+ }
+
+#if 0
+ printf ("relocate %s at %06lx relocation %06lx addend %ld ",
+ m32c_elf_howto_table[ELF32_R_TYPE(rel->r_info)].name,
+ rel->r_offset + input_section->output_section->vma + input_section->output_offset,
+ relocation, rel->r_addend);
+ {
+ int i;
+ for (i=0; i<4; i++)
+ printf (" %02x", contents[rel->r_offset+i]);
+ printf ("\n");
+ }
+#endif
+ 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 *) NULL;
+
+ switch (r)
+ {
+ case bfd_reloc_overflow:
+ r = info->callbacks->reloc_overflow
+ (info, (h ? &h->root : NULL), 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,
+ TRUE);
+ 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;
+}
+
+/* We support 16-bit pointers to code above 64k by generating a thunk
+ below 64k containing a JMP instruction to the final address. */
+
+static bfd_boolean
+m32c_elf_check_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;
+ const Elf_Internal_Rela * rel;
+ const Elf_Internal_Rela * rel_end;
+ bfd_vma *local_plt_offsets;
+ asection *splt;
+ bfd *dynobj;
+
+ if (info->relocatable)
+ return TRUE;
+
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+ sym_hashes = elf_sym_hashes (abfd);
+ local_plt_offsets = elf_local_got_offsets (abfd);
+ splt = NULL;
+ dynobj = elf_hash_table(info)->dynobj;
+
+ rel_end = relocs + sec->reloc_count;
+ for (rel = relocs; rel < rel_end; rel++)
+ {
+ struct elf_link_hash_entry *h;
+ unsigned long r_symndx;
+ bfd_vma *offset;
+
+ 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];
+ 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;
+
+ /* PR15323, ref flags aren't set for references in the same
+ object. */
+ h->root.non_ir_ref = 1;
+ }
+
+ switch (ELF32_R_TYPE (rel->r_info))
+ {
+ /* This relocation describes a 16-bit pointer to a function.
+ We may need to allocate a thunk in low memory; reserve memory
+ for it now. */
+ case R_M32C_16:
+ if (dynobj == NULL)
+ elf_hash_table (info)->dynobj = dynobj = abfd;
+ if (splt == NULL)
+ {
+ splt = bfd_get_linker_section (dynobj, ".plt");
+ if (splt == NULL)
+ {
+ flagword flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS
+ | SEC_IN_MEMORY | SEC_LINKER_CREATED
+ | SEC_READONLY | SEC_CODE);
+ splt = bfd_make_section_anyway_with_flags (dynobj, ".plt",
+ flags);
+ if (splt == NULL
+ || ! bfd_set_section_alignment (dynobj, splt, 1))
+ return FALSE;
+ }
+ }
+
+ if (h != NULL)
+ offset = &h->plt.offset;
+ else
+ {
+ if (local_plt_offsets == NULL)
+ {
+ size_t size;
+ unsigned int i;
+
+ size = symtab_hdr->sh_info * sizeof (bfd_vma);
+ local_plt_offsets = (bfd_vma *) bfd_alloc (abfd, size);
+ if (local_plt_offsets == NULL)
+ return FALSE;
+ elf_local_got_offsets (abfd) = local_plt_offsets;
+
+ for (i = 0; i < symtab_hdr->sh_info; i++)
+ local_plt_offsets[i] = (bfd_vma) -1;
+ }
+ offset = &local_plt_offsets[r_symndx];
+ }
+
+ if (*offset == (bfd_vma) -1)
+ {
+ *offset = splt->size;
+ splt->size += 4;
+ }
+ break;
+ }
+ }
+
+ return TRUE;
+}
+
+/* This must exist if dynobj is ever set. */
+
+static bfd_boolean
+m32c_elf_finish_dynamic_sections (bfd *abfd ATTRIBUTE_UNUSED,
+ struct bfd_link_info *info)
+{
+ bfd *dynobj;
+ asection *splt;
+
+ /* As an extra sanity check, verify that all plt entries have
+ been filled in. */
+
+ if ((dynobj = elf_hash_table (info)->dynobj) != NULL
+ && (splt = bfd_get_linker_section (dynobj, ".plt")) != NULL)
+ {
+ bfd_byte *contents = splt->contents;
+ unsigned int i, size = splt->size;
+ for (i = 0; i < size; i += 4)
+ {
+ unsigned int x = bfd_get_32 (dynobj, contents + i);
+ BFD_ASSERT (x != 0);
+ }
+ }
+
+ return TRUE;
+}
+
+static bfd_boolean
+m32c_elf_always_size_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
+ struct bfd_link_info *info)
+{
+ bfd *dynobj;
+ asection *splt;
+
+ if (info->relocatable)
+ return TRUE;
+
+ dynobj = elf_hash_table (info)->dynobj;
+ if (dynobj == NULL)
+ return TRUE;
+
+ splt = bfd_get_linker_section (dynobj, ".plt");
+ BFD_ASSERT (splt != NULL);
+
+ splt->contents = (bfd_byte *) bfd_zalloc (dynobj, splt->size);
+ if (splt->contents == NULL)
+ return FALSE;
+
+ return TRUE;
+}
+
+/* Function to set the ELF flag bits. */
+
+static bfd_boolean
+m32c_elf_set_private_flags (bfd *abfd, flagword flags)
+{
+ elf_elfheader (abfd)->e_flags = flags;
+ elf_flags_init (abfd) = TRUE;
+ return TRUE;
+}
+
+/* Merge backend specific data from an object file to the output
+ object file when linking. */
+
+static bfd_boolean
+m32c_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
+{
+ flagword old_flags, old_partial;
+ flagword new_flags, new_partial;
+ bfd_boolean error = FALSE;
+ char new_opt[80];
+ char old_opt[80];
+
+ new_opt[0] = old_opt[0] = '\0';
+ new_flags = elf_elfheader (ibfd)->e_flags;
+ old_flags = elf_elfheader (obfd)->e_flags;
+
+#ifdef DEBUG
+ (*_bfd_error_handler) ("old_flags = 0x%.8lx, new_flags = 0x%.8lx, init = %s, filename = %s",
+ old_flags, new_flags, elf_flags_init (obfd) ? "yes" : "no",
+ bfd_get_filename (ibfd));
+#endif
+
+ 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 /* Possibly incompatible flags. */
+ {
+ /* Warn if different cpu is used (allow a specific cpu to override
+ the generic cpu). */
+ new_partial = (new_flags & EF_M32C_CPU_MASK);
+ old_partial = (old_flags & EF_M32C_CPU_MASK);
+ if (new_partial == old_partial)
+ ;
+
+ else
+ {
+ switch (new_partial)
+ {
+ default: strcat (new_opt, " -m16c"); break;
+ case EF_M32C_CPU_M16C: strcat (new_opt, " -m16c"); break;
+ case EF_M32C_CPU_M32C: strcat (new_opt, " -m32c"); break;
+ }
+
+ switch (old_partial)
+ {
+ default: strcat (old_opt, " -m16c"); break;
+ case EF_M32C_CPU_M16C: strcat (old_opt, " -m16c"); break;
+ case EF_M32C_CPU_M32C: strcat (old_opt, " -m32c"); break;
+ }
+ }
+
+ /* Print out any mismatches from above. */
+ if (new_opt[0])
+ {
+ error = TRUE;
+ (*_bfd_error_handler)
+ (_("%s: compiled with %s and linked with modules compiled with %s"),
+ bfd_get_filename (ibfd), new_opt, old_opt);
+ }
+
+ new_flags &= ~ EF_M32C_ALL_FLAGS;
+ old_flags &= ~ EF_M32C_ALL_FLAGS;
+
+ /* 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 !error;
+}
+
+
+static bfd_boolean
+m32c_elf_print_private_bfd_data (bfd *abfd, void *ptr)
+{
+ FILE *file = (FILE *) ptr;
+ flagword flags;
+
+ BFD_ASSERT (abfd != NULL && ptr != NULL);
+
+ /* Print normal ELF private data. */
+ _bfd_elf_print_private_bfd_data (abfd, ptr);
+
+ flags = elf_elfheader (abfd)->e_flags;
+ fprintf (file, _("private flags = 0x%lx:"), (unsigned long) flags);
+
+ switch (flags & EF_M32C_CPU_MASK)
+ {
+ default: break;
+ case EF_M32C_CPU_M16C: fprintf (file, " -m16c"); break;
+ case EF_M32C_CPU_M32C: fprintf (file, " -m32c"); break;
+ }
+
+ fputc ('\n', file);
+ return TRUE;
+}
+
+/* Return the MACH for an e_flags value. */
+
+static int
+elf32_m32c_machine (bfd *abfd)
+{
+ switch (elf_elfheader (abfd)->e_flags & EF_M32C_CPU_MASK)
+ {
+ case EF_M32C_CPU_M16C: return bfd_mach_m16c;
+ case EF_M32C_CPU_M32C: return bfd_mach_m32c;
+ }
+
+ return bfd_mach_m16c;
+}
+
+static bfd_boolean
+m32c_elf_object_p (bfd *abfd)
+{
+ bfd_default_set_arch_mach (abfd, bfd_arch_m32c,
+ elf32_m32c_machine (abfd));
+ return TRUE;
+}
+
+
+#ifdef DEBUG
+void
+dump_symtab (bfd * abfd, void *internal_syms, void *external_syms)
+{
+ size_t locsymcount;
+ Elf_Internal_Sym *isymbuf;
+ Elf_Internal_Sym *isymend;
+ Elf_Internal_Sym *isym;
+ Elf_Internal_Shdr *symtab_hdr;
+ bfd_boolean free_internal = 0, free_external = 0;
+ char * st_info_str;
+ char * st_info_stb_str;
+ char * st_other_str;
+ char * st_shndx_str;
+
+ if (! internal_syms)
+ {
+ internal_syms = bfd_malloc (1000);
+ free_internal = 1;
+ }
+ if (! external_syms)
+ {
+ external_syms = bfd_malloc (1000);
+ free_external = 1;
+ }
+
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+ locsymcount = symtab_hdr->sh_size / get_elf_backend_data(abfd)->s->sizeof_sym;
+ if (free_internal)
+ isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
+ symtab_hdr->sh_info, 0,
+ internal_syms, external_syms, NULL);
+ else
+ isymbuf = internal_syms;
+ isymend = isymbuf + locsymcount;
+
+ for (isym = isymbuf ; isym < isymend ; isym++)
+ {
+ switch (ELF_ST_TYPE (isym->st_info))
+ {
+ case STT_FUNC:
+ st_info_str = "STT_FUNC";
+ break;
+
+ case STT_SECTION:
+ st_info_str = "STT_SECTION";
+ break;
+
+ case STT_FILE:
+ st_info_str = "STT_FILE";
+ break;
+
+ case STT_OBJECT:
+ st_info_str = "STT_OBJECT";
+ break;
+
+ case STT_TLS:
+ st_info_str = "STT_TLS";
+ break;
+
+ default:
+ st_info_str = "";
+ }
+
+ switch (ELF_ST_BIND (isym->st_info))
+ {
+ case STB_LOCAL:
+ st_info_stb_str = "STB_LOCAL";
+ break;
+
+ case STB_GLOBAL:
+ st_info_stb_str = "STB_GLOBAL";
+ break;
+
+ default:
+ st_info_stb_str = "";
+ }
+
+ switch (ELF_ST_VISIBILITY (isym->st_other))
+ {
+ case STV_DEFAULT:
+ st_other_str = "STV_DEFAULT";
+ break;
+
+ case STV_INTERNAL:
+ st_other_str = "STV_INTERNAL";
+ break;
+
+ case STV_PROTECTED:
+ st_other_str = "STV_PROTECTED";
+ break;
+
+ default:
+ st_other_str = "";
+ }
+
+ switch (isym->st_shndx)
+ {
+ case SHN_ABS:
+ st_shndx_str = "SHN_ABS";
+ break;
+
+ case SHN_COMMON:
+ st_shndx_str = "SHN_COMMON";
+ break;
+
+ case SHN_UNDEF:
+ st_shndx_str = "SHN_UNDEF";
+ break;
+
+ default:
+ st_shndx_str = "";
+ }
+
+ printf ("isym = %p st_value = %lx st_size = %lx st_name = (%lu) %s "
+ "st_info = (%d) %s %s st_other = (%d) %s st_shndx = (%d) %s\n",
+ isym,
+ (unsigned long) isym->st_value,
+ (unsigned long) isym->st_size,
+ isym->st_name,
+ bfd_elf_string_from_elf_section (abfd, symtab_hdr->sh_link,
+ isym->st_name),
+ isym->st_info, st_info_str, st_info_stb_str,
+ isym->st_other, st_other_str,
+ isym->st_shndx, st_shndx_str);
+ }
+ if (free_internal)
+ free (internal_syms);
+ if (free_external)
+ free (external_syms);
+}
+
+char *
+m32c_get_reloc (long reloc)
+{
+ if (0 <= reloc && reloc < R_M32C_max)
+ return m32c_elf_howto_table[reloc].name;
+ else
+ return "";
+}
+#endif /* DEBUG */
+
+/* Handle relaxing. */
+
+/* A subroutine of m32c_elf_relax_section. If the global symbol H
+ is within the low 64k, remove any entry for it in the plt. */
+
+struct relax_plt_data
+{
+ asection *splt;
+ bfd_boolean *again;
+};
+
+static bfd_boolean
+m32c_relax_plt_check (struct elf_link_hash_entry *h, void * xdata)
+{
+ struct relax_plt_data *data = (struct relax_plt_data *) xdata;
+
+ if (h->plt.offset != (bfd_vma) -1)
+ {
+ bfd_vma address;
+
+ if (h->root.type == bfd_link_hash_undefined
+ || h->root.type == bfd_link_hash_undefweak)
+ address = 0;
+ else
+ address = (h->root.u.def.section->output_section->vma
+ + h->root.u.def.section->output_offset
+ + h->root.u.def.value);
+
+ if (address <= 0xffff)
+ {
+ h->plt.offset = -1;
+ data->splt->size -= 4;
+ *data->again = TRUE;
+ }
+ }
+
+ return TRUE;
+}
+
+/* A subroutine of m32c_elf_relax_section. If the global symbol H
+ previously had a plt entry, give it a new entry offset. */
+
+static bfd_boolean
+m32c_relax_plt_realloc (struct elf_link_hash_entry *h, void * xdata)
+{
+ bfd_vma *entry = (bfd_vma *) xdata;
+
+ if (h->plt.offset != (bfd_vma) -1)
+ {
+ h->plt.offset = *entry;
+ *entry += 4;
+ }
+
+ return TRUE;
+}
+
+static bfd_boolean
+m32c_elf_relax_plt_section (asection *splt,
+ struct bfd_link_info *info,
+ bfd_boolean *again)
+{
+ struct relax_plt_data relax_plt_data;
+ bfd *ibfd;
+
+ /* Assume nothing changes. */
+ *again = FALSE;
+
+ if (info->relocatable)
+ return TRUE;
+
+ /* Quick check for an empty plt. */
+ if (splt->size == 0)
+ return TRUE;
+
+ /* Map across all global symbols; see which ones happen to
+ fall in the low 64k. */
+ relax_plt_data.splt = splt;
+ relax_plt_data.again = again;
+ elf_link_hash_traverse (elf_hash_table (info), m32c_relax_plt_check,
+ &relax_plt_data);
+
+ /* Likewise for local symbols, though that's somewhat less convenient
+ as we have to walk the list of input bfds and swap in symbol data. */
+ for (ibfd = info->input_bfds; ibfd ; ibfd = ibfd->link.next)
+ {
+ bfd_vma *local_plt_offsets = elf_local_got_offsets (ibfd);
+ Elf_Internal_Shdr *symtab_hdr;
+ Elf_Internal_Sym *isymbuf = NULL;
+ unsigned int idx;
+
+ if (! local_plt_offsets)
+ continue;
+
+ symtab_hdr = &elf_tdata (ibfd)->symtab_hdr;
+ if (symtab_hdr->sh_info != 0)
+ {
+ isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
+ if (isymbuf == NULL)
+ isymbuf = bfd_elf_get_elf_syms (ibfd, symtab_hdr,
+ symtab_hdr->sh_info, 0,
+ NULL, NULL, NULL);
+ if (isymbuf == NULL)
+ return FALSE;
+ }
+
+ for (idx = 0; idx < symtab_hdr->sh_info; ++idx)
+ {
+ Elf_Internal_Sym *isym;
+ asection *tsec;
+ bfd_vma address;
+
+ if (local_plt_offsets[idx] == (bfd_vma) -1)
+ continue;
+
+ isym = &isymbuf[idx];
+ if (isym->st_shndx == SHN_UNDEF)
+ continue;
+ else if (isym->st_shndx == SHN_ABS)
+ tsec = bfd_abs_section_ptr;
+ else if (isym->st_shndx == SHN_COMMON)
+ tsec = bfd_com_section_ptr;
+ else
+ tsec = bfd_section_from_elf_index (ibfd, isym->st_shndx);
+
+ address = (tsec->output_section->vma
+ + tsec->output_offset
+ + isym->st_value);
+ if (address <= 0xffff)
+ {
+ local_plt_offsets[idx] = -1;
+ splt->size -= 4;
+ *again = TRUE;
+ }
+ }
+
+ if (isymbuf != NULL
+ && symtab_hdr->contents != (unsigned char *) isymbuf)
+ {
+ if (! info->keep_memory)
+ free (isymbuf);
+ else
+ {
+ /* Cache the symbols for elf_link_input_bfd. */
+ symtab_hdr->contents = (unsigned char *) isymbuf;
+ }
+ }
+ }
+
+ /* If we changed anything, walk the symbols again to reallocate
+ .plt entry addresses. */
+ if (*again && splt->size > 0)
+ {
+ bfd_vma entry = 0;
+
+ elf_link_hash_traverse (elf_hash_table (info),
+ m32c_relax_plt_realloc, &entry);
+
+ for (ibfd = info->input_bfds; ibfd ; ibfd = ibfd->link.next)
+ {
+ bfd_vma *local_plt_offsets = elf_local_got_offsets (ibfd);
+ unsigned int nlocals = elf_tdata (ibfd)->symtab_hdr.sh_info;
+ unsigned int idx;
+
+ if (! local_plt_offsets)
+ continue;
+
+ for (idx = 0; idx < nlocals; ++idx)
+ if (local_plt_offsets[idx] != (bfd_vma) -1)
+ {
+ local_plt_offsets[idx] = entry;
+ entry += 4;
+ }
+ }
+ }
+
+ return TRUE;
+}
+
+static int
+compare_reloc (const void *e1, const void *e2)
+{
+ const Elf_Internal_Rela *i1 = (const Elf_Internal_Rela *) e1;
+ const Elf_Internal_Rela *i2 = (const Elf_Internal_Rela *) e2;
+
+ if (i1->r_offset == i2->r_offset)
+ return 0;
+ else
+ return i1->r_offset < i2->r_offset ? -1 : 1;
+}
+
+#define OFFSET_FOR_RELOC(rel) m32c_offset_for_reloc (abfd, rel, symtab_hdr, shndx_buf, intsyms)
+static bfd_vma
+m32c_offset_for_reloc (bfd *abfd,
+ Elf_Internal_Rela *rel,
+ Elf_Internal_Shdr *symtab_hdr,
+ Elf_External_Sym_Shndx *shndx_buf ATTRIBUTE_UNUSED,
+ Elf_Internal_Sym *intsyms)
+{
+ bfd_vma symval;
+
+ /* Get the value of the symbol referred to by the reloc. */
+ if (ELF32_R_SYM (rel->r_info) < symtab_hdr->sh_info)
+ {
+ /* A local symbol. */
+ Elf_Internal_Sym *isym;
+ asection *ssec;
+
+ isym = intsyms + ELF32_R_SYM (rel->r_info);
+ ssec = bfd_section_from_elf_index (abfd, isym->st_shndx);
+ symval = isym->st_value;
+ if (ssec)
+ symval += ssec->output_section->vma
+ + ssec->output_offset;
+ }
+ else
+ {
+ unsigned long indx;
+ struct elf_link_hash_entry *h;
+
+ /* An external symbol. */
+ indx = ELF32_R_SYM (rel->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. */
+ return 0;
+
+ symval = (h->root.u.def.value
+ + h->root.u.def.section->output_section->vma
+ + h->root.u.def.section->output_offset);
+ }
+ return symval;
+}
+
+static int bytes_saved = 0;
+
+static int bytes_to_reloc[] = {
+ R_M32C_NONE,
+ R_M32C_8,
+ R_M32C_16,
+ R_M32C_24,
+ R_M32C_32
+};
+
+/* What we use the bits in a relax reloc addend (R_M32C_RL_*) for. */
+
+/* Mask for the number of relocs associated with this insn. */
+#define RLA_RELOCS 0x0000000f
+/* Number of bytes gas emitted (before gas's relaxing) */
+#define RLA_NBYTES 0x00000ff0
+
+/* If the displacement is within the given range and the new encoding
+ differs from the old encoding (the index), then the insn can be
+ relaxed to the new encoding. */
+typedef struct {
+ int bytes;
+ unsigned int max_disp;
+ unsigned char new_encoding;
+} EncodingTable;
+
+static EncodingTable m16c_addr_encodings[] = {
+ { 0, 0, 0 }, /* R0 */
+ { 0, 0, 1 }, /* R1 */
+ { 0, 0, 2 }, /* R2 */
+ { 0, 0, 3 }, /* R3 */
+ { 0, 0, 4 }, /* A0 */
+ { 0, 0, 5 }, /* A1 */
+ { 0, 0, 6 }, /* [A0] */
+ { 0, 0, 7 }, /* [A1] */
+ { 1, 0, 6 }, /* udsp:8[A0] */
+ { 1, 0, 7 }, /* udsp:8[A1] */
+ { 1, 0, 10 }, /* udsp:8[SB] */
+ { 1, 0, 11 }, /* sdsp:8[FB] */
+ { 2, 255, 8 }, /* udsp:16[A0] */
+ { 2, 255, 9 }, /* udsp:16[A1] */
+ { 2, 255, 10 }, /* udsp:16[SB] */
+ { 2, 0, 15 }, /* abs:16 */
+};
+
+static EncodingTable m16c_jmpaddr_encodings[] = {
+ { 0, 0, 0 }, /* R0 */
+ { 0, 0, 1 }, /* R1 */
+ { 0, 0, 2 }, /* R2 */
+ { 0, 0, 3 }, /* R3 */
+ { 0, 0, 4 }, /* A0 */
+ { 0, 0, 5 }, /* A1 */
+ { 0, 0, 6 }, /* [A0] */
+ { 0, 0, 7 }, /* [A1] */
+ { 1, 0, 6 }, /* udsp:8[A0] */
+ { 1, 0, 7 }, /* udsp:8[A1] */
+ { 1, 0, 10 }, /* udsp:8[SB] */
+ { 1, 0, 11 }, /* sdsp:8[FB] */
+ { 3, 255, 8 }, /* udsp:20[A0] */
+ { 3, 255, 9 }, /* udsp:20[A1] */
+ { 2, 255, 10 }, /* udsp:16[SB] */
+ { 2, 0, 15 }, /* abs:16 */
+};
+
+static EncodingTable m32c_addr_encodings[] = {
+ { 0, 0, 0 }, /* [A0] */
+ { 0, 0, 1 }, /* [A1] */
+ { 0, 0, 2 }, /* A0 */
+ { 0, 0, 3 }, /* A1 */
+ { 1, 0, 0 }, /* udsp:8[A0] */
+ { 1, 0, 1 }, /* udsp:8[A1] */
+ { 1, 0, 6 }, /* udsp:8[SB] */
+ { 1, 0, 7 }, /* sdsp:8[FB] */
+ { 2, 255, 4 }, /* udsp:16[A0] */
+ { 2, 255, 5 }, /* udsp:16[A1] */
+ { 2, 255, 6 }, /* udsp:16[SB] */
+ { 2, 127, 7 }, /* sdsp:16[FB] */
+ { 3, 65535, 8 }, /* udsp:24[A0] */
+ { 3, 65535, 9 }, /* udsp:24[A1] */
+ { 3, 65535, 15 }, /* abs24 */
+ { 2, 0, 15 }, /* abs16 */
+ { 0, 0, 16 }, /* R2 */
+ { 0, 0, 17 }, /* R3 */
+ { 0, 0, 18 }, /* R0 */
+ { 0, 0, 19 }, /* R1 */
+ { 0, 0, 20 }, /* */
+ { 0, 0, 21 }, /* */
+ { 0, 0, 22 }, /* */
+ { 0, 0, 23 }, /* */
+ { 0, 0, 24 }, /* */
+ { 0, 0, 25 }, /* */
+ { 0, 0, 26 }, /* */
+ { 0, 0, 27 }, /* */
+ { 0, 0, 28 }, /* */
+ { 0, 0, 29 }, /* */
+ { 0, 0, 30 }, /* */
+ { 0, 0, 31 }, /* */
+};
+
+static bfd_boolean
+m32c_elf_relax_section
+ (bfd * abfd,
+ asection * sec,
+ struct bfd_link_info * link_info,
+ bfd_boolean * again)
+{
+ Elf_Internal_Shdr *symtab_hdr;
+ Elf_Internal_Shdr *shndx_hdr;
+ Elf_Internal_Rela *internal_relocs;
+ Elf_Internal_Rela *free_relocs = NULL;
+ Elf_Internal_Rela *irel, *irelend, *srel;
+ bfd_byte * contents = NULL;
+ bfd_byte * free_contents = NULL;
+ Elf_Internal_Sym *intsyms = NULL;
+ Elf_Internal_Sym *free_intsyms = NULL;
+ Elf_External_Sym_Shndx *shndx_buf = NULL;
+ int machine;
+
+ if (abfd == elf_hash_table (link_info)->dynobj
+ && (sec->flags & SEC_LINKER_CREATED) != 0
+ && strcmp (sec->name, ".plt") == 0)
+ return m32c_elf_relax_plt_section (sec, link_info, again);
+
+ /* Assume nothing changes. */
+ *again = FALSE;
+
+ machine = elf32_m32c_machine (abfd);
+
+ /* We don't have to do anything for a relocatable link, if
+ this section does not have relocs, or if this is not a
+ code section. */
+ if (link_info->relocatable
+ || (sec->flags & SEC_RELOC) == 0
+ || sec->reloc_count == 0
+ || (sec->flags & SEC_CODE) == 0)
+ return TRUE;
+
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+ shndx_hdr = &elf_tdata (abfd)->symtab_shndx_hdr;
+
+ /* Get the section contents. */
+ if (elf_section_data (sec)->this_hdr.contents != NULL)
+ contents = elf_section_data (sec)->this_hdr.contents;
+ /* Go get them off disk. */
+ else if (!bfd_malloc_and_get_section (abfd, sec, &contents))
+ goto error_return;
+
+ /* Read this BFD's symbols. */
+ /* Get cached copy if it exists. */
+ if (symtab_hdr->contents != NULL)
+ {
+ intsyms = (Elf_Internal_Sym *) symtab_hdr->contents;
+ }
+ else
+ {
+ intsyms = bfd_elf_get_elf_syms (abfd, symtab_hdr, symtab_hdr->sh_info, 0, NULL, NULL, NULL);
+ symtab_hdr->contents = (bfd_byte *) intsyms;
+ }
+
+ if (shndx_hdr->sh_size != 0)
+ {
+ bfd_size_type amt;
+
+ amt = symtab_hdr->sh_info;
+ amt *= sizeof (Elf_External_Sym_Shndx);
+ shndx_buf = (Elf_External_Sym_Shndx *) bfd_malloc (amt);
+ if (shndx_buf == NULL)
+ goto error_return;
+ if (bfd_seek (abfd, shndx_hdr->sh_offset, SEEK_SET) != 0
+ || bfd_bread (shndx_buf, amt, abfd) != amt)
+ goto error_return;
+ shndx_hdr->contents = (bfd_byte *) shndx_buf;
+ }
+
+ /* Get a copy of the native relocations. */
+ internal_relocs = (_bfd_elf_link_read_relocs
+ (abfd, sec, 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;
+
+ /* The RL_ relocs must be just before the operand relocs they go
+ with, so we must sort them to guarantee this. */
+ qsort (internal_relocs, sec->reloc_count, sizeof (Elf_Internal_Rela),
+ compare_reloc);
+
+ /* Walk through them looking for relaxing opportunities. */
+ irelend = internal_relocs + sec->reloc_count;
+
+ for (irel = internal_relocs; irel < irelend; irel++)
+ {
+ bfd_vma symval;
+ unsigned char *insn, *gap, *einsn;
+ bfd_vma pc;
+ bfd_signed_vma pcrel;
+ int relax_relocs;
+ int gap_size;
+ int new_type;
+ int posn;
+ int enc;
+ EncodingTable *enctbl;
+ EncodingTable *e;
+
+ if (ELF32_R_TYPE(irel->r_info) != R_M32C_RL_JUMP
+ && ELF32_R_TYPE(irel->r_info) != R_M32C_RL_1ADDR
+ && ELF32_R_TYPE(irel->r_info) != R_M32C_RL_2ADDR)
+ continue;
+
+ srel = irel;
+
+ /* There will always be room for the relaxed insn, since it is smaller
+ than the one it would replace. */
+ BFD_ASSERT (irel->r_offset < sec->size);
+
+ insn = contents + irel->r_offset;
+ relax_relocs = irel->r_addend % 16;
+
+ /* Ok, we only have three relocs we care about, and they're all
+ fake. The lower four bits of the addend is always the number
+ of following relocs (hence the qsort above) that are assigned
+ to this opcode. The next 8 bits of the addend indicates the
+ number of bytes in the insn. We use the rest of them
+ ourselves as flags for the more expensive operations (defines
+ above). The three relocs are:
+
+ RL_JUMP: This marks all direct jump insns. We check the
+ displacement and replace them with shorter jumps if
+ they're in range. We also use this to find JMP.S
+ insns and manually shorten them when we delete bytes.
+ We have to decode these insns to figure out what to
+ do.
+
+ RL_1ADDR: This is a :G or :Q insn, which has a single
+ "standard" operand. We have to extract the type
+ field, see if it's a wide displacement, then figure
+ out if we can replace it with a narrow displacement.
+ We don't have to decode these insns.
+
+ RL_2ADDR: Similarly, but two "standard" operands. Note that
+ r_addend may still be 1, as standard operands don't
+ always have displacements. Gas shouldn't give us one
+ with zero operands, but since we don't know which one
+ has the displacement, we check them both anyway.
+
+ These all point to the beginning of the insn itself, not the
+ operands.
+
+ Note that we only relax one step at a time, relying on the
+ linker to call us repeatedly. Thus, there is no code for
+ JMP.A->JMP.B although that will happen in two steps.
+ Likewise, for 2ADDR relaxes, we do one operand per cycle.
+ */
+
+ /* Get the value of the symbol referred to by the reloc. Just
+ in case this is the last reloc in the list, use the RL's
+ addend to choose between this reloc (no addend) or the next
+ (yes addend, which means at least one following reloc). */
+ srel = irel + (relax_relocs ? 1 : 0);
+ symval = OFFSET_FOR_RELOC (srel);
+
+ /* Setting gap_size nonzero is the flag which means "something
+ shrunk". */
+ gap_size = 0;
+ gap = NULL;
+ new_type = ELF32_R_TYPE(srel->r_info);
+
+ pc = sec->output_section->vma + sec->output_offset
+ + srel->r_offset;
+ pcrel = symval - pc + srel->r_addend;
+
+ if (machine == bfd_mach_m16c)
+ {
+ /* R8C / M16C */
+
+ switch (ELF32_R_TYPE(irel->r_info))
+ {
+
+ case R_M32C_RL_JUMP:
+ switch (insn[0])
+ {
+ case 0xfe: /* jmp.b */
+ if (pcrel >= 2 && pcrel <= 9)
+ {
+ /* Relax JMP.B -> JMP.S. We need to get rid of
+ the following reloc though. */
+ insn[0] = 0x60 | (pcrel - 2);
+ new_type = R_M32C_NONE;
+ irel->r_addend = 0x10;
+ gap_size = 1;
+ gap = insn + 1;
+ }
+ break;
+
+ case 0xf4: /* jmp.w */
+ /* 128 is allowed because it will be one byte closer
+ after relaxing. Likewise for all other pc-rel
+ jumps. */
+ if (pcrel <= 128 && pcrel >= -128)
+ {
+ /* Relax JMP.W -> JMP.B */
+ insn[0] = 0xfe;
+ insn[1] = 0;
+ new_type = R_M32C_8_PCREL;
+ gap_size = 1;
+ gap = insn + 2;
+ }
+ break;
+
+ case 0xfc: /* jmp.a */
+ if (pcrel <= 32768 && pcrel >= -32768)
+ {
+ /* Relax JMP.A -> JMP.W */
+ insn[0] = 0xf4;
+ insn[1] = 0;
+ insn[2] = 0;
+ new_type = R_M32C_16_PCREL;
+ gap_size = 1;
+ gap = insn + 3;
+ }
+ break;
+
+ case 0xfd: /* jsr.a */
+ if (pcrel <= 32768 && pcrel >= -32768)
+ {
+ /* Relax JSR.A -> JSR.W */
+ insn[0] = 0xf5;
+ insn[1] = 0;
+ insn[2] = 0;
+ new_type = R_M32C_16_PCREL;
+ gap_size = 1;
+ gap = insn + 3;
+ }
+ break;
+ }
+ break;
+
+ case R_M32C_RL_2ADDR:
+ /* xxxx xxxx srce dest [src-disp] [dest-disp]*/
+
+ enctbl = m16c_addr_encodings;
+ posn = 2;
+ enc = (insn[1] >> 4) & 0x0f;
+ e = & enctbl[enc];
+
+ if (srel->r_offset == irel->r_offset + posn
+ && e->new_encoding != enc
+ && symval <= e->max_disp)
+ {
+ insn[1] &= 0x0f;
+ insn[1] |= e->new_encoding << 4;
+ gap_size = e->bytes - enctbl[e->new_encoding].bytes;
+ gap = insn + posn + enctbl[e->new_encoding].bytes;
+ new_type = bytes_to_reloc[enctbl[e->new_encoding].bytes];
+ break;
+ }
+ if (relax_relocs == 2)
+ srel ++;
+ posn += e->bytes;
+
+ goto try_1addr_16;
+
+ case R_M32C_RL_1ADDR:
+ /* xxxx xxxx xxxx dest [disp] */
+
+ enctbl = m16c_addr_encodings;
+ posn = 2;
+
+ /* Check the opcode for jumps. We know it's safe to
+ do this because all 2ADDR insns are at least two
+ bytes long. */
+ enc = insn[0] * 256 + insn[1];
+ enc &= 0xfff0;
+ if (enc == 0x7d20
+ || enc == 0x7d00
+ || enc == 0x7d30
+ || enc == 0x7d10)
+ {
+ enctbl = m16c_jmpaddr_encodings;
+ }
+
+ try_1addr_16:
+ /* srel, posn, and enc must be set here. */
+
+ symval = OFFSET_FOR_RELOC (srel);
+ enc = insn[1] & 0x0f;
+ e = & enctbl[enc];
+
+ if (srel->r_offset == irel->r_offset + posn
+ && e->new_encoding != enc
+ && symval <= e->max_disp)
+ {
+ insn[1] &= 0xf0;
+ insn[1] |= e->new_encoding;
+ gap_size = e->bytes - enctbl[e->new_encoding].bytes;
+ gap = insn + posn + enctbl[e->new_encoding].bytes;
+ new_type = bytes_to_reloc[enctbl[e->new_encoding].bytes];
+ break;
+ }
+
+ break;
+
+ } /* Ends switch (reloc type) for m16c. */
+ }
+ else /* machine == bfd_mach_m32c */
+ {
+ /* M32CM / M32C */
+
+ switch (ELF32_R_TYPE(irel->r_info))
+ {
+
+ case R_M32C_RL_JUMP:
+ switch (insn[0])
+ {
+ case 0xbb: /* jmp.b */
+ if (pcrel >= 2 && pcrel <= 9)
+ {
+ int p = pcrel - 2;
+ /* Relax JMP.B -> JMP.S. We need to get rid of
+ the following reloc though. */
+ insn[0] = 0x4a | ((p << 3) & 0x30) | (p & 1);
+ new_type = R_M32C_NONE;
+ irel->r_addend = 0x10;
+ gap_size = 1;
+ gap = insn + 1;
+ }
+ break;
+
+ case 0xce: /* jmp.w */
+ if (pcrel <= 128 && pcrel >= -128)
+ {
+ /* Relax JMP.W -> JMP.B */
+ insn[0] = 0xbb;
+ insn[1] = 0;
+ new_type = R_M32C_8_PCREL;
+ gap_size = 1;
+ gap = insn + 2;
+ }
+ break;
+
+ case 0xcc: /* jmp.a */
+ if (pcrel <= 32768 && pcrel >= -32768)
+ {
+ /* Relax JMP.A -> JMP.W */
+ insn[0] = 0xce;
+ insn[1] = 0;
+ insn[2] = 0;
+ new_type = R_M32C_16_PCREL;
+ gap_size = 1;
+ gap = insn + 3;
+ }
+ break;
+
+ case 0xcd: /* jsr.a */
+ if (pcrel <= 32768 && pcrel >= -32768)
+ {
+ /* Relax JSR.A -> JSR.W */
+ insn[0] = 0xcf;
+ insn[1] = 0;
+ insn[2] = 0;
+ new_type = R_M32C_16_PCREL;
+ gap_size = 1;
+ gap = insn + 3;
+ }
+ break;
+ }
+ break;
+
+ case R_M32C_RL_2ADDR:
+ /* xSSS DDDx DDSS xxxx [src-disp] [dest-disp]*/
+
+ einsn = insn;
+ posn = 2;
+ if (einsn[0] == 1)
+ {
+ /* prefix; remove it as far as the RL reloc is concerned. */
+ einsn ++;
+ posn ++;
+ }
+
+ enctbl = m32c_addr_encodings;
+ enc = ((einsn[0] & 0x70) >> 2) | ((einsn[1] & 0x30) >> 4);
+ e = & enctbl[enc];
+
+ if (srel->r_offset == irel->r_offset + posn
+ && e->new_encoding != enc
+ && symval <= e->max_disp)
+ {
+ einsn[0] &= 0x8f;
+ einsn[0] |= (e->new_encoding & 0x1c) << 2;
+ einsn[1] &= 0xcf;
+ einsn[1] |= (e->new_encoding & 0x03) << 4;
+ gap_size = e->bytes - enctbl[e->new_encoding].bytes;
+ gap = insn + posn + enctbl[e->new_encoding].bytes;
+ new_type = bytes_to_reloc[enctbl[e->new_encoding].bytes];
+ break;
+ }
+ if (relax_relocs == 2)
+ srel ++;
+ posn += e->bytes;
+
+ goto try_1addr_32;
+
+ case R_M32C_RL_1ADDR:
+ /* xxxx DDDx DDxx xxxx [disp] */
+
+ einsn = insn;
+ posn = 2;
+ if (einsn[0] == 1)
+ {
+ /* prefix; remove it as far as the RL reloc is concerned. */
+ einsn ++;
+ posn ++;
+ }
+
+ enctbl = m32c_addr_encodings;
+
+ try_1addr_32:
+ /* srel, posn, and enc must be set here. */
+
+ symval = OFFSET_FOR_RELOC (srel);
+ enc = ((einsn[0] & 0x0e) << 1) | ((einsn[1] & 0xc0) >> 6);
+ e = & enctbl[enc];
+
+ if (srel->r_offset == irel->r_offset + posn
+ && e->new_encoding != enc
+ && symval <= e->max_disp)
+ {
+ einsn[0] &= 0xf1;
+ einsn[0] |= (e->new_encoding & 0x1c) >> 1;
+ einsn[1] &= 0x3f;
+ einsn[1] |= (e->new_encoding & 0x03) << 6;
+ gap_size = e->bytes - enctbl[e->new_encoding].bytes;
+ gap = insn + posn + enctbl[e->new_encoding].bytes;
+ new_type = bytes_to_reloc[enctbl[e->new_encoding].bytes];
+ break;
+ }
+
+ break;
+
+ } /* Ends switch (reloc type) for m32c. */
+ }
+
+ if (gap_size == 0)
+ continue;
+
+ *again = TRUE;
+
+ srel->r_info = ELF32_R_INFO (ELF32_R_SYM (srel->r_info), new_type);
+
+ /* 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 *) intsyms;
+ free_intsyms = NULL;
+
+ bytes_saved += gap_size;
+
+ if (! m32c_elf_relax_delete_bytes(abfd, sec, gap - contents, gap_size))
+ goto error_return;
+
+ } /* next relocation */
+
+ if (free_relocs != NULL)
+ {
+ free (free_relocs);
+ free_relocs = NULL;
+ }
+
+ if (free_contents != NULL)
+ {
+ if (! link_info->keep_memory)
+ free (free_contents);
+ /* Cache the section contents for elf_link_input_bfd. */
+ else
+ elf_section_data (sec)->this_hdr.contents = contents;
+
+ free_contents = NULL;
+ }
+
+ if (shndx_buf != NULL)
+ {
+ shndx_hdr->contents = NULL;
+ free (shndx_buf);
+ }
+
+ if (free_intsyms != NULL)
+ {
+ if (! link_info->keep_memory)
+ free (free_intsyms);
+ /* Cache the symbols for elf_link_input_bfd. */
+ else
+ {
+ symtab_hdr->contents = NULL /* (unsigned char *) intsyms*/;
+ }
+
+ free_intsyms = NULL;
+ }
+
+ return TRUE;
+
+ error_return:
+ if (free_relocs != NULL)
+ free (free_relocs);
+ if (free_contents != NULL)
+ free (free_contents);
+ if (shndx_buf != NULL)
+ {
+ shndx_hdr->contents = NULL;
+ free (shndx_buf);
+ }
+ if (free_intsyms != NULL)
+ free (free_intsyms);
+ return FALSE;
+}
+
+/* Delete some bytes from a section while relaxing. */
+
+static bfd_boolean
+m32c_elf_relax_delete_bytes
+ (bfd * abfd,
+ asection * sec,
+ bfd_vma addr,
+ int count)
+{
+ Elf_Internal_Shdr *symtab_hdr;
+ Elf_Internal_Shdr *shndx_hdr;
+ int sec_shndx;
+ bfd_byte *contents;
+ Elf_Internal_Rela *irel;
+ Elf_Internal_Rela *irelend;
+ bfd_vma toaddr;
+ Elf_Internal_Sym *isym;
+ Elf_Internal_Sym *isymend;
+ Elf_Internal_Sym *intsyms;
+ Elf_External_Sym_Shndx *shndx_buf;
+ Elf_External_Sym_Shndx *shndx;
+ struct elf_link_hash_entry ** sym_hashes;
+ struct elf_link_hash_entry ** end_hashes;
+ unsigned int symcount;
+
+ contents = elf_section_data (sec)->this_hdr.contents;
+
+ toaddr = sec->size;
+
+ irel = elf_section_data (sec)->relocs;
+ irelend = irel + sec->reloc_count;
+
+ /* Actually delete the bytes. */
+ memmove (contents + addr, contents + addr + count, (size_t) (toaddr - addr - count));
+ sec->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;
+
+ if (ELF32_R_TYPE(irel->r_info) == R_M32C_RL_JUMP
+ && irel->r_addend == 0x10 /* one byte insn, no relocs */
+ && irel->r_offset + 1 < addr
+ && irel->r_offset + 7 > addr)
+ {
+ bfd_vma disp;
+ unsigned char *insn = &contents[irel->r_offset];
+ disp = *insn;
+ /* This is a JMP.S, which we have to manually update. */
+ if (elf32_m32c_machine (abfd) == bfd_mach_m16c)
+ {
+ if ((*insn & 0xf8) != 0x60)
+ continue;
+ disp = (disp & 7);
+ }
+ else
+ {
+ if ((*insn & 0xce) != 0x4a)
+ continue;
+ disp = ((disp & 0x30) >> 3) | (disp & 1);
+ }
+ if (irel->r_offset + disp + 2 >= addr+count)
+ {
+ disp -= count;
+ if (elf32_m32c_machine (abfd) == bfd_mach_m16c)
+ {
+ *insn = (*insn & 0xf8) | disp;
+ }
+ else
+ {
+ *insn = (*insn & 0xce) | ((disp & 6) << 3) | (disp & 1);
+ }
+ }
+ }
+ }
+
+ /* Adjust the local symbols defined in this section. */
+ symtab_hdr = & elf_tdata (abfd)->symtab_hdr;
+ intsyms = (Elf_Internal_Sym *) symtab_hdr->contents;
+ isym = intsyms;
+ isymend = isym + symtab_hdr->sh_info;
+
+ sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
+ shndx_hdr = & elf_tdata (abfd)->symtab_shndx_hdr;
+ shndx_buf = (Elf_External_Sym_Shndx *) shndx_hdr->contents;
+ shndx = shndx_buf;
+
+ for (; isym < isymend; isym++, shndx = (shndx ? shndx + 1 : NULL))
+ {
+ /* If the symbol is in the range of memory we just moved, we
+ have to adjust its value. */
+ if ((int) isym->st_shndx == sec_shndx
+ && isym->st_value > addr
+ && isym->st_value < toaddr)
+ {
+ isym->st_value -= count;
+ }
+ /* If the symbol *spans* the bytes we just deleted (i.e. it's
+ *end* is in the moved bytes but it's *start* isn't), then we
+ must adjust its size. */
+ if ((int) isym->st_shndx == sec_shndx
+ && isym->st_value < addr
+ && isym->st_value + isym->st_size > addr
+ && isym->st_value + isym->st_size < toaddr)
+ {
+ isym->st_size -= count;
+ }
+ }
+
+ /* Now adjust the global symbols defined in this section. */
+ symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
+ - symtab_hdr->sh_info);
+ sym_hashes = elf_sym_hashes (abfd);
+ // sym_hashes += symtab_hdr->sh_info;
+ end_hashes = sym_hashes + symcount;
+
+ for (; sym_hashes < end_hashes; sym_hashes ++)
+ {
+ struct elf_link_hash_entry * sym_hash = * sym_hashes;
+
+ if (sym_hash &&
+ (sym_hash->root.type == bfd_link_hash_defined
+ || sym_hash->root.type == bfd_link_hash_defweak)
+ && sym_hash->root.u.def.section == sec)
+ {
+ if (sym_hash->root.u.def.value > addr
+ && sym_hash->root.u.def.value < toaddr)
+ {
+ sym_hash->root.u.def.value -= count;
+ }
+ if (sym_hash->root.u.def.value < addr
+ && sym_hash->root.u.def.value + sym_hash->size > addr
+ && sym_hash->root.u.def.value + sym_hash->size < toaddr)
+ {
+ sym_hash->size -= count;
+ }
+ }
+ }
+
+ return TRUE;
+}
+
+/* This is for versions of gcc prior to 4.3. */
+static unsigned int
+_bfd_m32c_elf_eh_frame_address_size (bfd *abfd, asection *sec ATTRIBUTE_UNUSED)
+{
+ if ((elf_elfheader (abfd)->e_flags & EF_M32C_CPU_MASK) == EF_M32C_CPU_M16C)
+ return 2;
+ return 4;
+}
+
+
+
+#define ELF_ARCH bfd_arch_m32c
+#define ELF_MACHINE_CODE EM_M32C
+#define ELF_MACHINE_ALT1 EM_M32C_OLD
+#define ELF_MAXPAGESIZE 0x100
+
+#if 0
+#define TARGET_BIG_SYM m32c_elf32_vec
+#define TARGET_BIG_NAME "elf32-m32c"
+#else
+#define TARGET_LITTLE_SYM m32c_elf32_vec
+#define TARGET_LITTLE_NAME "elf32-m32c"
+#endif
+
+#define elf_info_to_howto_rel NULL
+#define elf_info_to_howto m32c_info_to_howto_rela
+#define elf_backend_object_p m32c_elf_object_p
+#define elf_backend_relocate_section m32c_elf_relocate_section
+#define elf_backend_check_relocs m32c_elf_check_relocs
+#define elf_backend_object_p m32c_elf_object_p
+#define elf_symbol_leading_char ('_')
+#define elf_backend_always_size_sections \
+ m32c_elf_always_size_sections
+#define elf_backend_finish_dynamic_sections \
+ m32c_elf_finish_dynamic_sections
+
+#define elf_backend_can_gc_sections 1
+#define elf_backend_eh_frame_address_size _bfd_m32c_elf_eh_frame_address_size
+
+#define bfd_elf32_bfd_reloc_type_lookup m32c_reloc_type_lookup
+#define bfd_elf32_bfd_reloc_name_lookup m32c_reloc_name_lookup
+#define bfd_elf32_bfd_relax_section m32c_elf_relax_section
+#define bfd_elf32_bfd_set_private_flags m32c_elf_set_private_flags
+#define bfd_elf32_bfd_merge_private_bfd_data m32c_elf_merge_private_bfd_data
+#define bfd_elf32_bfd_print_private_bfd_data m32c_elf_print_private_bfd_data
+
+#include "elf32-target.h"
diff --git a/bfd/elf32-m32r.c b/bfd/elf32-m32r.c
new file mode 100644
index 0000000..8dba9f0
--- /dev/null
+++ b/bfd/elf32-m32r.c
@@ -0,0 +1,4082 @@
+/* M32R-specific support for 32-bit ELF.
+ Copyright (C) 1996-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+#include "elf-bfd.h"
+#include "elf/m32r.h"
+
+#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 1
+
+#ifndef USE_REL
+#define USE_REL 0
+#endif */
+/* Use RELA. But use REL to link old objects for backwords compatibility. */
+
+/* Functions for the M32R 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 nop opcode we use. */
+
+#define M32R_NOP 0x7000f000
+
+#define PLT_EMPTY 0x10101010 /* RIE -> RIE */
+
+/* The size in bytes of an entry in the procedure linkage table. */
+
+#define PLT_ENTRY_SIZE 20
+#define PLT_HEADER_SIZE 20
+
+/* The first one entries in a procedure linkage table are reserved,
+ and the initial contents are unimportant (we zero them out).
+ Subsequent entries look like this. */
+
+#define PLT0_ENTRY_WORD0 0xd6c00000 /* seth r6, #high(.got+4) */
+#define PLT0_ENTRY_WORD1 0x86e60000 /* or3 r6, r6, #low(.got)+4) */
+#define PLT0_ENTRY_WORD2 0x24e626c6 /* ld r4, @r6+ -> ld r6, @r6 */
+#define PLT0_ENTRY_WORD3 0x1fc6f000 /* jmp r6 || pnop */
+#define PLT0_ENTRY_WORD4 PLT_EMPTY /* RIE -> RIE */
+
+#define PLT0_PIC_ENTRY_WORD0 0xa4cc0004 /* ld r4, @(4,r12) */
+#define PLT0_PIC_ENTRY_WORD1 0xa6cc0008 /* ld r6, @(8,r12) */
+#define PLT0_PIC_ENTRY_WORD2 0x1fc6f000 /* jmp r6 || nop */
+#define PLT0_PIC_ENTRY_WORD3 PLT_EMPTY /* RIE -> RIE */
+#define PLT0_PIC_ENTRY_WORD4 PLT_EMPTY /* RIE -> RIE */
+
+#define PLT_ENTRY_WORD0 0xe6000000 /* ld24 r6, .name_in_GOT */
+#define PLT_ENTRY_WORD1 0x06acf000 /* add r6, r12 || nop */
+#define PLT_ENTRY_WORD0b 0xd6c00000 /* seth r6, #high(.name_in_GOT) */
+#define PLT_ENTRY_WORD1b 0x86e60000 /* or3 r6, r6, #low(.name_in_GOT) */
+#define PLT_ENTRY_WORD2 0x26c61fc6 /* ld r6, @r6 -> jmp r6 */
+#define PLT_ENTRY_WORD3 0xe5000000 /* ld24 r5, $offset */
+#define PLT_ENTRY_WORD4 0xff000000 /* bra .plt0. */
+
+
+/* Utility to actually perform an R_M32R_10_PCREL reloc. */
+
+static bfd_reloc_status_type
+m32r_elf_do_10_pcrel_reloc (bfd *abfd,
+ reloc_howto_type *howto,
+ asection *input_section,
+ bfd_byte *data,
+ bfd_vma offset,
+ asection *symbol_section ATTRIBUTE_UNUSED,
+ 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 > bfd_get_section_limit (abfd, input_section))
+ 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 & -(bfd_vma) 4);
+
+ 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, (bfd_vma) x, data + offset);
+
+ return status;
+}
+
+/* Handle the R_M32R_10_PCREL reloc. */
+
+static bfd_reloc_status_type
+m32r_elf_10_pcrel_reloc (bfd * abfd,
+ arelent * reloc_entry,
+ asymbol * symbol,
+ void * data,
+ asection * input_section,
+ bfd * output_bfd,
+ char ** error_message ATTRIBUTE_UNUSED)
+{
+ /* This part is from bfd_elf_generic_reloc. */
+ if (output_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);
+}
+
+/* Do generic partial_inplace relocation.
+ This is a local replacement for bfd_elf_generic_reloc. */
+
+static bfd_reloc_status_type
+m32r_elf_generic_reloc (bfd *input_bfd,
+ arelent *reloc_entry,
+ asymbol *symbol,
+ void * data,
+ asection *input_section,
+ bfd *output_bfd,
+ char **error_message ATTRIBUTE_UNUSED)
+{
+ bfd_reloc_status_type ret;
+ bfd_vma relocation;
+ bfd_byte *inplace_address;
+
+ /* 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 != NULL
+ && (symbol->flags & BSF_SECTION_SYM) == 0
+ && reloc_entry->addend == 0)
+ {
+ reloc_entry->address += input_section->output_offset;
+ return bfd_reloc_ok;
+ }
+
+ /* Now do the reloc in the usual way.
+ ??? It would be nice to call bfd_elf_generic_reloc here,
+ but we have partial_inplace set. bfd_elf_generic_reloc will
+ pass the handling back to bfd_install_relocation which will install
+ a section relative addend which is wrong. */
+
+ /* Sanity check the address (offset in section). */
+ if (reloc_entry->address > bfd_get_section_limit (input_bfd, input_section))
+ return bfd_reloc_outofrange;
+
+ ret = bfd_reloc_ok;
+ if (bfd_is_und_section (symbol->section)
+ && output_bfd == NULL)
+ ret = bfd_reloc_undefined;
+
+ if (bfd_is_com_section (symbol->section)
+ || output_bfd != NULL)
+ relocation = 0;
+ else
+ relocation = symbol->value;
+
+ /* Only do this for a final link. */
+ if (output_bfd == NULL)
+ {
+ relocation += symbol->section->output_section->vma;
+ relocation += symbol->section->output_offset;
+ }
+
+ relocation += reloc_entry->addend;
+ inplace_address = (bfd_byte *) data + reloc_entry->address;
+
+#define DOIT(x) \
+ x = ( (x & ~reloc_entry->howto->dst_mask) | \
+ (((x & reloc_entry->howto->src_mask) + relocation) & \
+ reloc_entry->howto->dst_mask))
+
+ switch (reloc_entry->howto->size)
+ {
+ case 1:
+ {
+ short x = bfd_get_16 (input_bfd, inplace_address);
+ DOIT (x);
+ bfd_put_16 (input_bfd, (bfd_vma) x, inplace_address);
+ }
+ break;
+ case 2:
+ {
+ unsigned long x = bfd_get_32 (input_bfd, inplace_address);
+ DOIT (x);
+ bfd_put_32 (input_bfd, (bfd_vma)x , inplace_address);
+ }
+ break;
+ default:
+ BFD_ASSERT (0);
+ }
+
+ if (output_bfd != NULL)
+ reloc_entry->address += input_section->output_offset;
+
+ return ret;
+}
+
+/* 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 (bfd *abfd ATTRIBUTE_UNUSED,
+ arelent *reloc_entry,
+ asymbol *symbol,
+ void * data ATTRIBUTE_UNUSED,
+ asection *input_section,
+ bfd *output_bfd,
+ char **error_message ATTRIBUTE_UNUSED)
+{
+ /* This part is from bfd_elf_generic_reloc. */
+ if (output_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 ();
+}
+
+
+/* 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 (bfd *abfd ATTRIBUTE_UNUSED,
+ arelent *reloc_entry,
+ asymbol *symbol,
+ void * data,
+ asection *input_section,
+ bfd *output_bfd,
+ char **error_message ATTRIBUTE_UNUSED)
+{
+ 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 != 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 > bfd_get_section_limit (abfd, input_section))
+ return bfd_reloc_outofrange;
+
+ ret = bfd_reloc_ok;
+ if (bfd_is_und_section (symbol->section)
+ && output_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 = bfd_malloc ((bfd_size_type) 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 != NULL)
+ reloc_entry->address += input_section->output_offset;
+
+ return ret;
+}
+
+/* Handle an M32R ELF HI16 reloc. */
+
+static void
+m32r_elf_relocate_hi16 (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. */
+
+static bfd_reloc_status_type
+m32r_elf_lo16_reloc (bfd *input_bfd,
+ arelent *reloc_entry,
+ asymbol *symbol,
+ void * data,
+ asection *input_section,
+ bfd *output_bfd,
+ char **error_message)
+{
+ /* 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 != NULL
+ && (symbol->flags & BSF_SECTION_SYM) == 0
+ && reloc_entry->addend == 0)
+ {
+ reloc_entry->address += input_section->output_offset;
+ return bfd_reloc_ok;
+ }
+
+ 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 (input_bfd, l->addr);
+ vallo = ((bfd_get_32 (input_bfd, (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 &~ (bfd_vma) 0xffff) | ((val >> 16) & 0xffff);
+ bfd_put_32 (input_bfd, (bfd_vma) insn, l->addr);
+
+ next = l->next;
+ free (l);
+ l = next;
+ }
+
+ m32r_hi16_list = NULL;
+ }
+
+ /* Now do the LO16 reloc in the usual way.
+ ??? It would be nice to call bfd_elf_generic_reloc here,
+ but we have partial_inplace set. bfd_elf_generic_reloc will
+ pass the handling back to bfd_install_relocation which will install
+ a section relative addend which is wrong. */
+ return m32r_elf_generic_reloc (input_bfd, reloc_entry, symbol, data,
+ input_section, output_bfd, error_message);
+}
+
+
+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 */
+ m32r_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 */
+ m32r_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 */
+ m32r_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 */
+
+ EMPTY_HOWTO (13),
+ EMPTY_HOWTO (14),
+ EMPTY_HOWTO (15),
+ EMPTY_HOWTO (16),
+ EMPTY_HOWTO (17),
+ EMPTY_HOWTO (18),
+ EMPTY_HOWTO (19),
+ EMPTY_HOWTO (20),
+ EMPTY_HOWTO (21),
+ EMPTY_HOWTO (22),
+ EMPTY_HOWTO (23),
+ EMPTY_HOWTO (24),
+ EMPTY_HOWTO (25),
+ EMPTY_HOWTO (26),
+ EMPTY_HOWTO (27),
+ EMPTY_HOWTO (28),
+ EMPTY_HOWTO (29),
+ EMPTY_HOWTO (30),
+ EMPTY_HOWTO (31),
+ EMPTY_HOWTO (32),
+
+ /* A 16 bit absolute relocation. */
+ HOWTO (R_M32R_16_RELA, /* 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_RELA", /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A 32 bit absolute relocation. */
+ HOWTO (R_M32R_32_RELA, /* 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_RELA", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A 24 bit address. */
+ HOWTO (R_M32R_24_RELA, /* 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_RELA", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffff, /* src_mask */
+ 0xffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_M32R_10_PCREL_RELA, /* 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_RELA",/* 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_RELA, /* 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_RELA",/* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* A relative 26 bit relocation, right shifted by 2. */
+ HOWTO (R_M32R_26_PCREL_RELA, /* 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_RELA",/* 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_RELA, /* type */
+ 16, /* 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_M32R_HI16_ULO_RELA",/* name */
+ FALSE, /* 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_RELA, /* type */
+ 16, /* 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_M32R_HI16_SLO_RELA",/* name */
+ FALSE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Lower 16 bits of address. */
+ HOWTO (R_M32R_LO16_RELA, /* 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_M32R_LO16_RELA", /* name */
+ FALSE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Small data area 16 bits offset. */
+ HOWTO (R_M32R_SDA16_RELA, /* 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_M32R_SDA16_RELA", /* 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_RELA_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_RELA_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_RELA_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_RELA_GNU_VTENTRY", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A 32 bit PC relative relocation. */
+ HOWTO (R_M32R_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_M32R_REL32", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ EMPTY_HOWTO (46),
+ EMPTY_HOWTO (47),
+
+ /* Like R_M32R_24, but referring to the GOT table entry for
+ the symbol. */
+ HOWTO (R_M32R_GOT24, /* 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_GOT24", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffff, /* src_mask */
+ 0xffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Like R_M32R_PCREL, but referring to the procedure linkage table
+ entry for the symbol. */
+ HOWTO (R_M32R_26_PLTREL, /* 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_M32R_26_PLTREL", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffff, /* src_mask */
+ 0xffffff, /* 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_M32R_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_M32R_COPY", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Like R_M32R_24, but used when setting global offset table
+ entries. */
+ HOWTO (R_M32R_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_M32R_GLOB_DAT", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Marks a procedure linkage table entry for a symbol. */
+ HOWTO (R_M32R_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_M32R_JMP_SLOT", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* 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_M32R_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_M32R_RELATIVE", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_M32R_GOTOFF, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 24, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_M32R_GOTOFF", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffff, /* src_mask */
+ 0xffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* An PC Relative 24-bit relocation used when setting PIC offset
+ table register. */
+ HOWTO (R_M32R_GOTPC24, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 24, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_unsigned, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_M32R_GOTPC24", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffff, /* src_mask */
+ 0xffffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* Like R_M32R_HI16_ULO, but referring to the GOT table entry for
+ the symbol. */
+ HOWTO (R_M32R_GOT16_HI_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 */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_M32R_GOT16_HI_ULO", /* name */
+ FALSE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Like R_M32R_HI16_SLO, but referring to the GOT table entry for
+ the symbol. */
+ HOWTO (R_M32R_GOT16_HI_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 */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_M32R_GOT16_HI_SLO", /* name */
+ FALSE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Like R_M32R_LO16, but referring to the GOT table entry for
+ the symbol. */
+ HOWTO (R_M32R_GOT16_LO, /* 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_M32R_GOT16_LO", /* name */
+ FALSE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* An PC Relative relocation used when setting PIC offset table register.
+ Like R_M32R_HI16_ULO, but referring to the GOT table entry for
+ the symbol. */
+ HOWTO (R_M32R_GOTPC_HI_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 */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_M32R_GOTPC_HI_ULO", /* name */
+ FALSE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* An PC Relative relocation used when setting PIC offset table register.
+ Like R_M32R_HI16_SLO, but referring to the GOT table entry for
+ the symbol. */
+ HOWTO (R_M32R_GOTPC_HI_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 */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_M32R_GOTPC_HI_SLO", /* name */
+ FALSE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* An PC Relative relocation used when setting PIC offset table register.
+ Like R_M32R_LO16, but referring to the GOT table entry for
+ the symbol. */
+ HOWTO (R_M32R_GOTPC_LO, /* 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_M32R_GOTPC_LO", /* name */
+ FALSE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_M32R_GOTOFF_HI_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 */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_M32R_GOTOFF_HI_ULO",/* name */
+ FALSE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_M32R_GOTOFF_HI_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 */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_M32R_GOTOFF_HI_SLO",/* name */
+ FALSE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_M32R_GOTOFF_LO, /* 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_M32R_GOTOFF_LO", /* name */
+ FALSE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+};
+
+/* 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;
+};
+
+#ifdef USE_M32R_OLD_RELOC
+static const struct m32r_reloc_map m32r_reloc_map_old[] =
+{
+ { 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 },
+};
+#else
+static const struct m32r_reloc_map m32r_reloc_map[] =
+{
+ { BFD_RELOC_NONE, R_M32R_NONE },
+ { BFD_RELOC_16, R_M32R_16_RELA },
+ { BFD_RELOC_32, R_M32R_32_RELA },
+ { BFD_RELOC_M32R_24, R_M32R_24_RELA },
+ { BFD_RELOC_M32R_10_PCREL, R_M32R_10_PCREL_RELA },
+ { BFD_RELOC_M32R_18_PCREL, R_M32R_18_PCREL_RELA },
+ { BFD_RELOC_M32R_26_PCREL, R_M32R_26_PCREL_RELA },
+ { BFD_RELOC_M32R_HI16_ULO, R_M32R_HI16_ULO_RELA },
+ { BFD_RELOC_M32R_HI16_SLO, R_M32R_HI16_SLO_RELA },
+ { BFD_RELOC_M32R_LO16, R_M32R_LO16_RELA },
+ { BFD_RELOC_M32R_SDA16, R_M32R_SDA16_RELA },
+ { BFD_RELOC_VTABLE_INHERIT, R_M32R_RELA_GNU_VTINHERIT },
+ { BFD_RELOC_VTABLE_ENTRY, R_M32R_RELA_GNU_VTENTRY },
+ { BFD_RELOC_32_PCREL, R_M32R_REL32 },
+
+ { BFD_RELOC_M32R_GOT24, R_M32R_GOT24 },
+ { BFD_RELOC_M32R_26_PLTREL, R_M32R_26_PLTREL },
+ { BFD_RELOC_M32R_COPY, R_M32R_COPY },
+ { BFD_RELOC_M32R_GLOB_DAT, R_M32R_GLOB_DAT },
+ { BFD_RELOC_M32R_JMP_SLOT, R_M32R_JMP_SLOT },
+ { BFD_RELOC_M32R_RELATIVE, R_M32R_RELATIVE },
+ { BFD_RELOC_M32R_GOTOFF, R_M32R_GOTOFF },
+ { BFD_RELOC_M32R_GOTPC24, R_M32R_GOTPC24 },
+ { BFD_RELOC_M32R_GOT16_HI_ULO, R_M32R_GOT16_HI_ULO },
+ { BFD_RELOC_M32R_GOT16_HI_SLO, R_M32R_GOT16_HI_SLO },
+ { BFD_RELOC_M32R_GOT16_LO, R_M32R_GOT16_LO },
+ { BFD_RELOC_M32R_GOTPC_HI_ULO, R_M32R_GOTPC_HI_ULO },
+ { BFD_RELOC_M32R_GOTPC_HI_SLO, R_M32R_GOTPC_HI_SLO },
+ { BFD_RELOC_M32R_GOTPC_LO, R_M32R_GOTPC_LO },
+ { BFD_RELOC_M32R_GOTOFF_HI_ULO, R_M32R_GOTOFF_HI_ULO },
+ { BFD_RELOC_M32R_GOTOFF_HI_SLO, R_M32R_GOTOFF_HI_SLO },
+ { BFD_RELOC_M32R_GOTOFF_LO, R_M32R_GOTOFF_LO },
+};
+#endif
+
+static reloc_howto_type *
+bfd_elf32_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ bfd_reloc_code_real_type code)
+{
+ unsigned int i;
+
+#ifdef USE_M32R_OLD_RELOC
+ for (i = 0;
+ i < sizeof (m32r_reloc_map_old) / sizeof (struct m32r_reloc_map);
+ i++)
+ if (m32r_reloc_map_old[i].bfd_reloc_val == code)
+ return &m32r_elf_howto_table[m32r_reloc_map_old[i].elf_reloc_val];
+
+#else /* ! USE_M32R_OLD_RELOC */
+
+ 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];
+#endif
+
+ return NULL;
+}
+
+static reloc_howto_type *
+bfd_elf32_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ const char *r_name)
+{
+ unsigned int i;
+
+ for (i = 0;
+ i < sizeof (m32r_elf_howto_table) / sizeof (m32r_elf_howto_table[0]);
+ i++)
+ if (m32r_elf_howto_table[i].name != NULL
+ && strcasecmp (m32r_elf_howto_table[i].name, r_name) == 0)
+ return &m32r_elf_howto_table[i];
+
+ return NULL;
+}
+
+/* Set the howto pointer for an M32R ELF reloc. */
+
+static void
+m32r_info_to_howto_rel (bfd *abfd ATTRIBUTE_UNUSED,
+ arelent *cache_ptr,
+ Elf_Internal_Rela *dst)
+{
+ unsigned int r_type;
+
+ r_type = ELF32_R_TYPE (dst->r_info);
+ BFD_ASSERT (ELF32_R_TYPE(dst->r_info) <= (unsigned int) R_M32R_GNU_VTENTRY);
+ cache_ptr->howto = &m32r_elf_howto_table[r_type];
+}
+
+static void
+m32r_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED,
+ arelent *cache_ptr,
+ Elf_Internal_Rela *dst)
+{
+ BFD_ASSERT ((ELF32_R_TYPE(dst->r_info) == (unsigned int) R_M32R_NONE)
+ || ((ELF32_R_TYPE(dst->r_info) > (unsigned int) R_M32R_GNU_VTENTRY)
+ && (ELF32_R_TYPE(dst->r_info) < (unsigned int) R_M32R_max)));
+ cache_ptr->howto = &m32r_elf_howto_table[ELF32_R_TYPE(dst->r_info)];
+}
+
+
+/* Given a BFD section, try to locate the corresponding ELF section
+ index. */
+
+static bfd_boolean
+_bfd_m32r_elf_section_from_bfd_section (bfd *abfd ATTRIBUTE_UNUSED,
+ 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. */
+
+static void
+_bfd_m32r_elf_symbol_processing (bfd *abfd ATTRIBUTE_UNUSED, asymbol *asym)
+{
+ elf_symbol_type *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 bfd_boolean
+m32r_elf_add_symbol_hook (bfd *abfd,
+ struct bfd_link_info *info,
+ Elf_Internal_Sym *sym,
+ const char **namep,
+ flagword *flagsp ATTRIBUTE_UNUSED,
+ asection **secp,
+ bfd_vma *valp)
+{
+ if (! info->relocatable
+ && (*namep)[0] == '_' && (*namep)[1] == 'S'
+ && strcmp (*namep, "_SDA_BASE_") == 0
+ && is_elf_hash_table (info->hash))
+ {
+ /* 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;
+ struct bfd_link_hash_entry *bh;
+ asection *s = bfd_get_section_by_name (abfd, ".sdata");
+
+ /* The following code was cobbled from elf32-ppc.c and elflink.c. */
+ if (s == NULL)
+ {
+ flagword flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS
+ | SEC_IN_MEMORY | SEC_LINKER_CREATED);
+
+ s = bfd_make_section_anyway_with_flags (abfd, ".sdata",
+ flags);
+ if (s == NULL)
+ return FALSE;
+ if (! bfd_set_section_alignment (abfd, s, 2))
+ return FALSE;
+ }
+
+ bh = bfd_link_hash_lookup (info->hash, "_SDA_BASE_",
+ FALSE, FALSE, FALSE);
+
+ if ((bh == NULL || bh->type == bfd_link_hash_undefined)
+ && !(_bfd_generic_link_add_one_symbol (info,
+ abfd,
+ "_SDA_BASE_",
+ BSF_GLOBAL,
+ s,
+ (bfd_vma) 32768,
+ NULL,
+ FALSE,
+ get_elf_backend_data (abfd)->collect,
+ &bh)))
+ return FALSE;
+ h = (struct elf_link_hash_entry *) bh;
+ 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 relocatable output. */
+
+static bfd_reloc_status_type
+m32r_elf_final_sda_base (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 != 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;
+}
+
+/* Return size of a PLT entry. */
+#define elf_m32r_sizeof_plt(info) PLT_ENTRY_SIZE
+
+/* The m32r 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_m32r_pcrel_relocs_copied
+{
+ /* Next section. */
+ struct elf_m32r_pcrel_relocs_copied *next;
+ /* A section in dynobj. */
+ asection *section;
+ /* Number of relocs copied in this section. */
+ bfd_size_type count;
+};
+
+/* The sh linker needs to keep track of the number of relocs that it
+ decides to copy as dynamic relocs in check_relocs for each symbol.
+ This is so that it can later discard them if they are found to be
+ unnecessary. We store the information in a field extending the
+ regular ELF linker hash table. */
+
+struct elf_m32r_dyn_relocs
+{
+ struct elf_m32r_dyn_relocs *next;
+
+ /* The input section of the reloc. */
+ asection *sec;
+
+ /* Total number of relocs copied for the input section. */
+ bfd_size_type count;
+
+ /* Number of pc-relative relocs copied for the input section. */
+ bfd_size_type pc_count;
+};
+
+
+/* m32r ELF linker hash entry. */
+
+struct elf_m32r_link_hash_entry
+{
+ struct elf_link_hash_entry root;
+
+ /* Track dynamic relocs copied for this symbol. */
+ struct elf_m32r_dyn_relocs *dyn_relocs;
+};
+
+/* m32r ELF linker hash table. */
+
+struct elf_m32r_link_hash_table
+{
+ struct elf_link_hash_table root;
+
+ /* Short-cuts to get to dynamic linker sections. */
+ asection *sgot;
+ asection *sgotplt;
+ asection *srelgot;
+ asection *splt;
+ asection *srelplt;
+ asection *sdynbss;
+ asection *srelbss;
+
+ /* Small local sym cache. */
+ struct sym_cache sym_cache;
+};
+
+/* Traverse an m32r ELF linker hash table. */
+
+#define m32r_elf_link_hash_traverse(table, func, info) \
+ (elf_link_hash_traverse \
+ (&(table)->root, \
+ (bfd_boolean (*) (struct elf_link_hash_entry *, void *)) (func), \
+ (info)))
+
+/* Get the m32r ELF linker hash table from a link_info structure. */
+
+#define m32r_elf_hash_table(p) \
+ (elf_hash_table_id ((struct elf_link_hash_table *) ((p)->hash)) \
+ == M32R_ELF_DATA ? ((struct elf_m32r_link_hash_table *) ((p)->hash)) : NULL)
+
+/* Create an entry in an m32r ELF linker hash table. */
+
+static struct bfd_hash_entry *
+m32r_elf_link_hash_newfunc (struct bfd_hash_entry *entry,
+ struct bfd_hash_table *table,
+ const char *string)
+{
+ struct elf_m32r_link_hash_entry *ret =
+ (struct elf_m32r_link_hash_entry *) entry;
+
+ /* Allocate the structure if it has not already been allocated by a
+ subclass. */
+ if (ret == NULL)
+ ret = bfd_hash_allocate (table,
+ sizeof (struct elf_m32r_link_hash_entry));
+ if (ret == NULL)
+ return NULL;
+
+ /* Call the allocation method of the superclass. */
+ ret = ((struct elf_m32r_link_hash_entry *)
+ _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry *) ret,
+ table, string));
+ if (ret != NULL)
+ {
+ struct elf_m32r_link_hash_entry *eh;
+
+ eh = (struct elf_m32r_link_hash_entry *) ret;
+ eh->dyn_relocs = NULL;
+ }
+
+ return (struct bfd_hash_entry *) ret;
+}
+
+/* Create an m32r ELF linker hash table. */
+
+static struct bfd_link_hash_table *
+m32r_elf_link_hash_table_create (bfd *abfd)
+{
+ struct elf_m32r_link_hash_table *ret;
+ bfd_size_type amt = sizeof (struct elf_m32r_link_hash_table);
+
+ ret = bfd_zmalloc (amt);
+ if (ret == NULL)
+ return NULL;
+
+ if (!_bfd_elf_link_hash_table_init (&ret->root, abfd,
+ m32r_elf_link_hash_newfunc,
+ sizeof (struct elf_m32r_link_hash_entry),
+ M32R_ELF_DATA))
+ {
+ free (ret);
+ return NULL;
+ }
+
+ return &ret->root.root;
+}
+
+/* Create .got, .gotplt, and .rela.got sections in DYNOBJ, and set up
+ shortcuts to them in our hash table. */
+
+static bfd_boolean
+create_got_section (bfd *dynobj, struct bfd_link_info *info)
+{
+ struct elf_m32r_link_hash_table *htab;
+
+ if (! _bfd_elf_create_got_section (dynobj, info))
+ return FALSE;
+
+ htab = m32r_elf_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ htab->sgot = bfd_get_linker_section (dynobj, ".got");
+ htab->sgotplt = bfd_get_linker_section (dynobj, ".got.plt");
+ htab->srelgot = bfd_get_linker_section (dynobj, ".rela.got");
+ if (! htab->sgot || ! htab->sgotplt || ! htab->srelgot)
+ abort ();
+
+ return TRUE;
+}
+
+/* Create dynamic sections when linking against a dynamic object. */
+
+static bfd_boolean
+m32r_elf_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
+{
+ struct elf_m32r_link_hash_table *htab;
+ flagword flags, pltflags;
+ asection *s;
+ const struct elf_backend_data *bed = get_elf_backend_data (abfd);
+ int ptralign = 2; /* 32bit */
+
+ htab = m32r_elf_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ /* 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_anyway_with_flags (abfd, ".plt", pltflags);
+ htab->splt = s;
+ if (s == NULL
+ || ! 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 bfd_link_hash_entry *bh = NULL;
+ struct elf_link_hash_entry *h;
+
+ if (! (_bfd_generic_link_add_one_symbol
+ (info, abfd, "_PROCEDURE_LINKAGE_TABLE_", BSF_GLOBAL, s,
+ (bfd_vma) 0, NULL, FALSE,
+ get_elf_backend_data (abfd)->collect, &bh)))
+ return FALSE;
+ h = (struct elf_link_hash_entry *) bh;
+ h->def_regular = 1;
+ h->type = STT_OBJECT;
+ htab->root.hplt = h;
+
+ if (info->shared
+ && ! bfd_elf_link_record_dynamic_symbol (info, h))
+ return FALSE;
+ }
+
+ s = bfd_make_section_anyway_with_flags (abfd,
+ bed->default_use_rela_p
+ ? ".rela.plt" : ".rel.plt",
+ flags | SEC_READONLY);
+ htab->srelplt = s;
+ if (s == NULL
+ || ! bfd_set_section_alignment (abfd, s, ptralign))
+ return FALSE;
+
+ if (htab->sgot == NULL
+ && ! create_got_section (abfd, info))
+ return FALSE;
+
+ if (bed->want_dynbss)
+ {
+ /* 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_anyway_with_flags (abfd, ".dynbss",
+ SEC_ALLOC | SEC_LINKER_CREATED);
+ htab->sdynbss = s;
+ if (s == NULL)
+ 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_anyway_with_flags (abfd,
+ (bed->default_use_rela_p
+ ? ".rela.bss" : ".rel.bss"),
+ flags | SEC_READONLY);
+ htab->srelbss = s;
+ if (s == NULL
+ || ! bfd_set_section_alignment (abfd, s, ptralign))
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+/* Copy the extra info we tack onto an elf_link_hash_entry. */
+
+static void
+m32r_elf_copy_indirect_symbol (struct bfd_link_info *info,
+ struct elf_link_hash_entry *dir,
+ struct elf_link_hash_entry *ind)
+{
+ struct elf_m32r_link_hash_entry * edir;
+ struct elf_m32r_link_hash_entry * eind;
+
+ edir = (struct elf_m32r_link_hash_entry *) dir;
+ eind = (struct elf_m32r_link_hash_entry *) ind;
+
+ if (eind->dyn_relocs != NULL)
+ {
+ if (edir->dyn_relocs != NULL)
+ {
+ struct elf_m32r_dyn_relocs **pp;
+ struct elf_m32r_dyn_relocs *p;
+
+ /* Add reloc counts against the indirect sym to the direct sym
+ list. Merge any entries against the same section. */
+ for (pp = &eind->dyn_relocs; (p = *pp) != NULL;)
+ {
+ struct elf_m32r_dyn_relocs *q;
+
+ for (q = edir->dyn_relocs; q != NULL; q = q->next)
+ if (q->sec == p->sec)
+ {
+ q->pc_count += p->pc_count;
+ q->count += p->count;
+ *pp = p->next;
+ break;
+ }
+ if (q == NULL)
+ pp = &p->next;
+ }
+ *pp = edir->dyn_relocs;
+ }
+
+ edir->dyn_relocs = eind->dyn_relocs;
+ eind->dyn_relocs = NULL;
+ }
+
+ _bfd_elf_link_hash_copy_indirect (info, dir, ind);
+}
+
+
+/* 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 bfd_boolean
+m32r_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
+ struct elf_link_hash_entry *h)
+{
+ struct elf_m32r_link_hash_table *htab;
+ struct elf_m32r_link_hash_entry *eh;
+ struct elf_m32r_dyn_relocs *p;
+ bfd *dynobj;
+ asection *s;
+
+#ifdef DEBUG_PIC
+ printf ("m32r_elf_adjust_dynamic_symbol()\n");
+#endif
+
+ dynobj = elf_hash_table (info)->dynobj;
+
+ /* Make sure we know what is going on here. */
+ BFD_ASSERT (dynobj != NULL
+ && (h->needs_plt
+ || h->u.weakdef != NULL
+ || (h->def_dynamic
+ && h->ref_regular
+ && !h->def_regular)));
+
+ /* 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->needs_plt)
+ {
+ if (! info->shared
+ && !h->def_dynamic
+ && !h->ref_dynamic
+ && h->root.type != bfd_link_hash_undefweak
+ && h->root.type != bfd_link_hash_undefined)
+ {
+ /* This case can occur if we saw a PLT 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 PCREL
+ reloc instead. */
+ h->plt.offset = (bfd_vma) -1;
+ h->needs_plt = 0;
+ }
+
+ return TRUE;
+ }
+ else
+ 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->u.weakdef != NULL)
+ {
+ BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
+ || h->u.weakdef->root.type == bfd_link_hash_defweak);
+ h->root.u.def.section = h->u.weakdef->root.u.def.section;
+ h->root.u.def.value = h->u.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;
+
+ /* If there are no references to this symbol that do not use the
+ GOT, we don't need to generate a copy reloc. */
+ if (!h->non_got_ref)
+ return TRUE;
+
+ /* If -z nocopyreloc was given, we won't generate them either. */
+ if (info->nocopyreloc)
+ {
+ h->non_got_ref = 0;
+ return TRUE;
+ }
+
+ eh = (struct elf_m32r_link_hash_entry *) h;
+ for (p = eh->dyn_relocs; p != NULL; p = p->next)
+ {
+ s = p->sec->output_section;
+ if (s != NULL && (s->flags & (SEC_READONLY | SEC_HAS_CONTENTS)) != 0)
+ break;
+ }
+
+ /* If we didn't find any dynamic relocs in sections which needs the
+ copy reloc, then we'll be keeping the dynamic relocs and avoiding
+ the copy reloc. */
+ if (p == NULL)
+ {
+ h->non_got_ref = 0;
+ 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. */
+
+ htab = m32r_elf_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ s = htab->sdynbss;
+ BFD_ASSERT (s != NULL);
+
+ /* We must generate a R_M32R_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 && h->size != 0)
+ {
+ asection *srel;
+
+ srel = htab->srelbss;
+ BFD_ASSERT (srel != NULL);
+ srel->size += sizeof (Elf32_External_Rela);
+ h->needs_copy = 1;
+ }
+
+ return _bfd_elf_adjust_dynamic_copy (h, s);
+}
+
+/* Allocate space in .plt, .got and associated reloc sections for
+ dynamic relocs. */
+
+static bfd_boolean
+allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
+{
+ struct bfd_link_info *info;
+ struct elf_m32r_link_hash_table *htab;
+ struct elf_m32r_link_hash_entry *eh;
+ struct elf_m32r_dyn_relocs *p;
+
+ if (h->root.type == bfd_link_hash_indirect)
+ return TRUE;
+
+ info = (struct bfd_link_info *) inf;
+ htab = m32r_elf_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ eh = (struct elf_m32r_link_hash_entry *) h;
+
+ if (htab->root.dynamic_sections_created
+ && h->plt.refcount > 0)
+ {
+ /* Make sure this symbol is output as a dynamic symbol.
+ Undefined weak syms won't yet be marked as dynamic. */
+ if (h->dynindx == -1
+ && !h->forced_local)
+ {
+ if (! bfd_elf_link_record_dynamic_symbol (info, h))
+ return FALSE;
+ }
+
+ if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, info->shared, h))
+ {
+ asection *s = htab->splt;
+
+ /* If this is the first .plt entry, make room for the special
+ first entry. */
+ if (s->size == 0)
+ s->size += PLT_ENTRY_SIZE;
+
+ h->plt.offset = s->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->def_regular)
+ {
+ h->root.u.def.section = s;
+ h->root.u.def.value = h->plt.offset;
+ }
+
+ /* Make room for this entry. */
+ s->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. */
+ htab->sgotplt->size += 4;
+
+ /* We also need to make an entry in the .rel.plt section. */
+ htab->srelplt->size += sizeof (Elf32_External_Rela);
+ }
+ else
+ {
+ h->plt.offset = (bfd_vma) -1;
+ h->needs_plt = 0;
+ }
+ }
+ else
+ {
+ h->plt.offset = (bfd_vma) -1;
+ h->needs_plt = 0;
+ }
+
+ if (h->got.refcount > 0)
+ {
+ asection *s;
+ bfd_boolean dyn;
+
+ /* Make sure this symbol is output as a dynamic symbol.
+ Undefined weak syms won't yet be marked as dynamic. */
+ if (h->dynindx == -1
+ && !h->forced_local)
+ {
+ if (! bfd_elf_link_record_dynamic_symbol (info, h))
+ return FALSE;
+ }
+
+ s = htab->sgot;
+
+ h->got.offset = s->size;
+ s->size += 4;
+ dyn = htab->root.dynamic_sections_created;
+ if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h))
+ htab->srelgot->size += sizeof (Elf32_External_Rela);
+ }
+ else
+ h->got.offset = (bfd_vma) -1;
+
+ if (eh->dyn_relocs == NULL)
+ return TRUE;
+
+ /* In the shared -Bsymbolic case, discard space allocated for
+ dynamic pc-relative relocs against symbols which turn out to be
+ defined in regular objects. For the normal shared case, discard
+ space for pc-relative relocs that have become local due to symbol
+ visibility changes. */
+
+ if (info->shared)
+ {
+ if (h->def_regular
+ && (h->forced_local
+ || info->symbolic))
+ {
+ struct elf_m32r_dyn_relocs **pp;
+
+ for (pp = &eh->dyn_relocs; (p = *pp) != NULL;)
+ {
+ p->count -= p->pc_count;
+ p->pc_count = 0;
+ if (p->count == 0)
+ *pp = p->next;
+ else
+ pp = &p->next;
+ }
+ }
+
+ /* Also discard relocs on undefined weak syms with non-default
+ visibility. */
+ if (eh->dyn_relocs != NULL
+ && h->root.type == bfd_link_hash_undefweak)
+ {
+ if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
+ eh->dyn_relocs = NULL;
+
+ /* Make sure undefined weak symbols are output as a dynamic
+ symbol in PIEs. */
+ else if (h->dynindx == -1
+ && !h->forced_local)
+ {
+ if (! bfd_elf_link_record_dynamic_symbol (info, h))
+ return FALSE;
+ }
+ }
+ }
+ else
+ {
+ /* For the non-shared case, discard space for relocs against
+ symbols which turn out to need copy relocs or are not
+ dynamic. */
+
+ if (!h->non_got_ref
+ && ((h->def_dynamic
+ && !h->def_regular)
+ || (htab->root.dynamic_sections_created
+ && (h->root.type == bfd_link_hash_undefweak
+ || h->root.type == bfd_link_hash_undefined))))
+ {
+ /* Make sure this symbol is output as a dynamic symbol.
+ Undefined weak syms won't yet be marked as dynamic. */
+ if (h->dynindx == -1
+ && !h->forced_local)
+ {
+ if (! bfd_elf_link_record_dynamic_symbol (info, h))
+ return FALSE;
+ }
+
+ /* If that succeeded, we know we'll be keeping all the
+ relocs. */
+ if (h->dynindx != -1)
+ goto keep;
+ }
+
+ eh->dyn_relocs = NULL;
+
+ keep: ;
+ }
+
+ /* Finally, allocate space. */
+ for (p = eh->dyn_relocs; p != NULL; p = p->next)
+ {
+ asection *sreloc = elf_section_data (p->sec)->sreloc;
+ sreloc->size += p->count * sizeof (Elf32_External_Rela);
+ }
+
+ return TRUE;
+}
+
+/* Find any dynamic relocs that apply to read-only sections. */
+
+static bfd_boolean
+readonly_dynrelocs (struct elf_link_hash_entry *h, void * inf)
+{
+ struct elf_m32r_link_hash_entry *eh;
+ struct elf_m32r_dyn_relocs *p;
+
+ eh = (struct elf_m32r_link_hash_entry *) h;
+ for (p = eh->dyn_relocs; p != NULL; p = p->next)
+ {
+ asection *s = p->sec->output_section;
+
+ if (s != NULL && (s->flags & SEC_READONLY) != 0)
+ {
+ struct bfd_link_info *info = (struct bfd_link_info *) inf;
+
+ info->flags |= DF_TEXTREL;
+
+ /* Not an error, just cut short the traversal. */
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+/* Set the sizes of the dynamic sections. */
+
+static bfd_boolean
+m32r_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
+ struct bfd_link_info *info)
+{
+ struct elf_m32r_link_hash_table *htab;
+ bfd *dynobj;
+ asection *s;
+ bfd_boolean relocs;
+ bfd *ibfd;
+
+#ifdef DEBUG_PIC
+ printf ("m32r_elf_size_dynamic_sections()\n");
+#endif
+
+ htab = m32r_elf_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ dynobj = htab->root.dynobj;
+ BFD_ASSERT (dynobj != NULL);
+
+ if (htab->root.dynamic_sections_created)
+ {
+ /* Set the contents of the .interp section to the interpreter. */
+ if (info->executable)
+ {
+ s = bfd_get_linker_section (dynobj, ".interp");
+ BFD_ASSERT (s != NULL);
+ s->size = sizeof ELF_DYNAMIC_INTERPRETER;
+ s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
+ }
+ }
+
+ /* Set up .got offsets for local syms, and space for local dynamic
+ relocs. */
+ for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next)
+ {
+ bfd_signed_vma *local_got;
+ bfd_signed_vma *end_local_got;
+ bfd_size_type locsymcount;
+ Elf_Internal_Shdr *symtab_hdr;
+ asection *srel;
+
+ if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour)
+ continue;
+
+ for (s = ibfd->sections; s != NULL; s = s->next)
+ {
+ struct elf_m32r_dyn_relocs *p;
+
+ for (p = ((struct elf_m32r_dyn_relocs *)
+ elf_section_data (s)->local_dynrel);
+ p != NULL;
+ p = p->next)
+ {
+ if (! bfd_is_abs_section (p->sec)
+ && bfd_is_abs_section (p->sec->output_section))
+ {
+ /* Input section has been discarded, either because
+ it is a copy of a linkonce section or due to
+ linker script /DISCARD/, so we'll be discarding
+ the relocs too. */
+ }
+ else if (p->count != 0)
+ {
+ srel = elf_section_data (p->sec)->sreloc;
+ srel->size += p->count * sizeof (Elf32_External_Rela);
+ if ((p->sec->output_section->flags & SEC_READONLY) != 0)
+ info->flags |= DF_TEXTREL;
+ }
+ }
+ }
+
+ local_got = elf_local_got_refcounts (ibfd);
+ if (!local_got)
+ continue;
+
+ symtab_hdr = &elf_tdata (ibfd)->symtab_hdr;
+ locsymcount = symtab_hdr->sh_info;
+ end_local_got = local_got + locsymcount;
+ s = htab->sgot;
+ srel = htab->srelgot;
+ for (; local_got < end_local_got; ++local_got)
+ {
+ if (*local_got > 0)
+ {
+ *local_got = s->size;
+ s->size += 4;
+ if (info->shared)
+ srel->size += sizeof (Elf32_External_Rela);
+ }
+ else
+ *local_got = (bfd_vma) -1;
+ }
+ }
+
+ /* Allocate global sym .plt and .got entries, and space for global
+ sym dynamic relocs. */
+ elf_link_hash_traverse (&htab->root, allocate_dynrelocs, info);
+
+ /* We now have determined the sizes of the various dynamic sections.
+ Allocate memory for them. */
+ relocs = FALSE;
+ for (s = dynobj->sections; s != NULL; s = s->next)
+ {
+ if ((s->flags & SEC_LINKER_CREATED) == 0)
+ continue;
+
+ if (s == htab->splt
+ || s == htab->sgot
+ || s == htab->sgotplt
+ || s == htab->sdynbss)
+ {
+ /* Strip this section if we don't need it; see the
+ comment below. */
+ }
+ else if (CONST_STRNEQ (bfd_get_section_name (dynobj, s), ".rela"))
+ {
+ if (s->size != 0 && s != htab->srelplt)
+ relocs = 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
+ /* It's not one of our sections, so don't allocate space. */
+ continue;
+
+ if (s->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. */
+ s->flags |= SEC_EXCLUDE;
+ continue;
+ }
+
+ if ((s->flags & SEC_HAS_CONTENTS) == 0)
+ continue;
+
+ /* Allocate memory for the section contents. We use bfd_zalloc
+ here in case unused entries are not reclaimed before the
+ section's contents are written out. This should not happen,
+ but this way if it does, we get a R_M32R_NONE reloc instead
+ of garbage. */
+ s->contents = bfd_zalloc (dynobj, s->size);
+ if (s->contents == NULL)
+ return FALSE;
+ }
+
+ if (htab->root.dynamic_sections_created)
+ {
+ /* Add some entries to the .dynamic section. We fill in the
+ values later, in m32r_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. */
+#define add_dynamic_entry(TAG, VAL) \
+ _bfd_elf_add_dynamic_entry (info, TAG, VAL)
+
+ if (info->executable)
+ {
+ if (! add_dynamic_entry (DT_DEBUG, 0))
+ return FALSE;
+ }
+
+ if (htab->splt->size != 0)
+ {
+ if (! add_dynamic_entry (DT_PLTGOT, 0)
+ || ! add_dynamic_entry (DT_PLTRELSZ, 0)
+ || ! add_dynamic_entry (DT_PLTREL, DT_RELA)
+ || ! add_dynamic_entry (DT_JMPREL, 0))
+ return FALSE;
+ }
+
+ if (relocs)
+ {
+ if (! add_dynamic_entry (DT_RELA, 0)
+ || ! add_dynamic_entry (DT_RELASZ, 0)
+ || ! add_dynamic_entry (DT_RELAENT,
+ sizeof (Elf32_External_Rela)))
+ return FALSE;
+
+ /* If any dynamic relocs apply to a read-only section,
+ then we need a DT_TEXTREL entry. */
+ if ((info->flags & DF_TEXTREL) == 0)
+ elf_link_hash_traverse (&htab->root, readonly_dynrelocs,
+ info);
+
+ if ((info->flags & DF_TEXTREL) != 0)
+ {
+ if (! add_dynamic_entry (DT_TEXTREL, 0))
+ return FALSE;
+ }
+ }
+ }
+#undef add_dynamic_entry
+
+ return TRUE;
+}
+
+/* Relocate an M32R/D ELF section.
+ There is some attempt to make this function usable for many architectures,
+ both for RELA and REL type relocs, 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
+ relocatable 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 relocatable 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 bfd_boolean
+m32r_elf_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
+ 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. */
+ bfd_boolean ret = TRUE;
+ struct elf_m32r_link_hash_table *htab = m32r_elf_hash_table (info);
+ bfd *dynobj;
+ bfd_vma *local_got_offsets;
+ asection *sgot, *splt, *sreloc;
+ bfd_vma high_address = bfd_get_section_limit (input_bfd, input_section);
+
+ if (htab == NULL)
+ return FALSE;
+
+ dynobj = htab->root.dynobj;
+ local_got_offsets = elf_local_got_offsets (input_bfd);
+
+ sgot = htab->sgot;
+ splt = htab->splt;
+ 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;
+ /* 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;
+ bfd_vma relocation;
+ Elf_Internal_Sym *sym;
+ asection *sec;
+ const char *sym_name;
+ bfd_reloc_status_type r;
+ const char *errmsg = NULL;
+ bfd_boolean use_rel = FALSE;
+
+ h = NULL;
+ r_type = ELF32_R_TYPE (rel->r_info);
+ if (r_type < 0 || r_type >= (int) R_M32R_max)
+ {
+ (*_bfd_error_handler) (_("%B: unknown relocation type %d"),
+ 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
+ || r_type == R_M32R_NONE
+ || r_type == R_M32R_RELA_GNU_VTENTRY
+ || r_type == R_M32R_RELA_GNU_VTINHERIT)
+ continue;
+
+ if (r_type <= R_M32R_GNU_VTENTRY)
+ use_rel = TRUE;
+
+ howto = m32r_elf_howto_table + r_type;
+ r_symndx = ELF32_R_SYM (rel->r_info);
+
+ sym = NULL;
+ sec = NULL;
+ h = NULL;
+
+ if (r_symndx < symtab_hdr->sh_info)
+ {
+ /* Local symbol. */
+ sym = local_syms + r_symndx;
+ sec = local_sections[r_symndx];
+ sym_name = "<local symbol>";
+
+ if (!use_rel)
+ {
+ relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
+ addend = rel->r_addend;
+ }
+ else
+ {
+ relocation = (sec->output_section->vma
+ + sec->output_offset
+ + sym->st_value);
+ }
+ }
+ else
+ {
+ /* External symbol. */
+ relocation = 0;
+
+ h = sym_hashes[r_symndx - symtab_hdr->sh_info];
+
+ if (info->wrap_hash != NULL
+ && (input_section->flags & SEC_DEBUGGING) != 0)
+ h = ((struct elf_link_hash_entry *)
+ unwrap_hash_lookup (info, input_bfd, &h->root));
+
+ 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)
+ {
+ bfd_boolean dyn;
+ sec = h->root.u.def.section;
+
+ dyn = htab->root.dynamic_sections_created;
+ sec = h->root.u.def.section;
+ if (r_type == R_M32R_GOTPC24
+ || (r_type == R_M32R_GOTPC_HI_ULO
+ || r_type == R_M32R_GOTPC_HI_SLO
+ || r_type == R_M32R_GOTPC_LO)
+ || (r_type == R_M32R_26_PLTREL
+ && h->plt.offset != (bfd_vma) -1)
+ || ((r_type == R_M32R_GOT24
+ || r_type == R_M32R_GOT16_HI_ULO
+ || r_type == R_M32R_GOT16_HI_SLO
+ || r_type == R_M32R_GOT16_LO)
+ && WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn,
+ info->shared, h)
+ && (! info->shared
+ || (! info->symbolic && h->dynindx != -1)
+ || !h->def_regular))
+ || (info->shared
+ && ((! info->symbolic && h->dynindx != -1)
+ || !h->def_regular)
+ && (((r_type == R_M32R_16_RELA
+ || r_type == R_M32R_32_RELA
+ || r_type == R_M32R_24_RELA
+ || r_type == R_M32R_HI16_ULO_RELA
+ || r_type == R_M32R_HI16_SLO_RELA
+ || r_type == R_M32R_LO16_RELA)
+ && !h->forced_local)
+ || r_type == R_M32R_REL32
+ || r_type == R_M32R_10_PCREL_RELA
+ || r_type == R_M32R_18_PCREL_RELA
+ || r_type == R_M32R_26_PCREL_RELA)
+ && ((input_section->flags & SEC_ALLOC) != 0
+ /* DWARF will emit R_M32R_16(24,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
+ && h->def_dynamic))))
+ {
+ /* In these cases, we don't need the relocation
+ value. We check specially because in some
+ obscure cases sec->output_section will be NULL. */
+ }
+ else if (sec->output_section != NULL)
+ relocation = (h->root.u.def.value
+ + sec->output_section->vma
+ + sec->output_offset);
+ else if (!info->relocatable
+ && (_bfd_elf_section_offset (output_bfd, info,
+ input_section,
+ rel->r_offset)
+ != (bfd_vma) -1))
+ {
+ (*_bfd_error_handler)
+ (_("%B(%A+0x%lx): unresolvable %s relocation against symbol `%s'"),
+ input_bfd,
+ input_section,
+ (long) rel->r_offset,
+ howto->name,
+ h->root.root.string);
+ }
+ }
+ else if (h->root.type == bfd_link_hash_undefweak)
+ ;
+ else if (info->unresolved_syms_in_objects == RM_IGNORE
+ && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)
+ ;
+ else if (!info->relocatable)
+ {
+ if (! ((*info->callbacks->undefined_symbol)
+ (info, h->root.root.string, input_bfd,
+ input_section, offset,
+ (info->unresolved_syms_in_objects == RM_GENERATE_ERROR
+ || ELF_ST_VISIBILITY (h->other)))))
+ return FALSE;
+ }
+ }
+
+ if (sec != NULL && discarded_section (sec))
+ RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+ rel, 1, relend, howto, 0, contents);
+
+ if (info->relocatable && !use_rel)
+ {
+ /* This is a relocatable 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 (sym != NULL && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
+ rel->r_addend += sec->output_offset;
+ continue;
+ }
+
+ if (info->relocatable && use_rel)
+ {
+ /* This is a relocatable 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 (sym == NULL || ELF_ST_TYPE (sym->st_info) != STT_SECTION)
+ continue;
+
+ addend += sec->output_offset;
+
+ /* 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);
+ }
+ }
+ else
+ {
+ /* Sanity check the address. */
+ if (offset > high_address)
+ {
+ r = bfd_reloc_outofrange;
+ goto check_reloc;
+ }
+
+ switch ((int) r_type)
+ {
+ case R_M32R_GOTOFF:
+ /* Relocation is relative to the start of the global offset
+ table (for ld24 rx, #uimm24). eg access at label+addend
+
+ ld24 rx. #label@GOTOFF + addend
+ sub rx, r12. */
+
+ BFD_ASSERT (sgot != NULL);
+
+ relocation = -(relocation - sgot->output_section->vma);
+ rel->r_addend = -rel->r_addend;
+ break;
+
+ case R_M32R_GOTOFF_HI_ULO:
+ case R_M32R_GOTOFF_HI_SLO:
+ case R_M32R_GOTOFF_LO:
+ BFD_ASSERT (sgot != NULL);
+
+ relocation -= sgot->output_section->vma;
+
+ if ((r_type == R_M32R_GOTOFF_HI_SLO)
+ && ((relocation + rel->r_addend) & 0x8000))
+ rel->r_addend += 0x10000;
+ break;
+
+ case R_M32R_GOTPC24:
+ /* .got(_GLOBAL_OFFSET_TABLE_) - pc relocation
+ ld24 rx,#_GLOBAL_OFFSET_TABLE_
+ */
+ relocation = sgot->output_section->vma;
+ break;
+
+ case R_M32R_GOTPC_HI_ULO:
+ case R_M32R_GOTPC_HI_SLO:
+ case R_M32R_GOTPC_LO:
+ {
+ /* .got(_GLOBAL_OFFSET_TABLE_) - pc relocation
+ bl .+4
+ seth rx,#high(_GLOBAL_OFFSET_TABLE_)
+ or3 rx,rx,#low(_GLOBAL_OFFSET_TABLE_ +4)
+ or
+ bl .+4
+ seth rx,#shigh(_GLOBAL_OFFSET_TABLE_)
+ add3 rx,rx,#low(_GLOBAL_OFFSET_TABLE_ +4)
+ */
+ relocation = sgot->output_section->vma;
+ relocation -= (input_section->output_section->vma
+ + input_section->output_offset
+ + rel->r_offset);
+ if ((r_type == R_M32R_GOTPC_HI_SLO)
+ && ((relocation + rel->r_addend) & 0x8000))
+ rel->r_addend += 0x10000;
+
+ break;
+ }
+ case R_M32R_GOT16_HI_ULO:
+ case R_M32R_GOT16_HI_SLO:
+ case R_M32R_GOT16_LO:
+ /* Fall through. */
+ case R_M32R_GOT24:
+ /* Relocation is to the entry for this symbol in the global
+ offset table. */
+ BFD_ASSERT (sgot != NULL);
+
+ if (h != NULL)
+ {
+ bfd_boolean dyn;
+ bfd_vma off;
+
+ off = h->got.offset;
+ BFD_ASSERT (off != (bfd_vma) -1);
+
+ dyn = htab->root.dynamic_sections_created;
+ if (! WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h)
+ || (info->shared
+ && (info->symbolic
+ || h->dynindx == -1
+ || h->forced_local)
+ && h->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;
+ }
+ else
+ {
+ bfd_vma off;
+ bfd_byte *loc;
+
+ 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_M32R_RELATIVE reloc
+ for the dynamic linker. */
+ srelgot = bfd_get_linker_section (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_M32R_RELATIVE);
+ outrel.r_addend = relocation;
+ loc = srelgot->contents;
+ loc += srelgot->reloc_count * sizeof (Elf32_External_Rela);
+ bfd_elf32_swap_reloca_out (output_bfd, &outrel,loc);
+ ++srelgot->reloc_count;
+ }
+
+ local_got_offsets[r_symndx] |= 1;
+ }
+
+ relocation = sgot->output_offset + off;
+ }
+ if ((r_type == R_M32R_GOT16_HI_SLO)
+ && ((relocation + rel->r_addend) & 0x8000))
+ rel->r_addend += 0x10000;
+
+ break;
+
+ case R_M32R_26_PLTREL:
+ /* Relocation is to the entry for this symbol in the
+ procedure linkage table. */
+
+ /* The native assembler will generate a 26_PLTREL reloc
+ for a local symbol if you assemble a call from one
+ section to another when using -K pic. */
+ if (h == NULL)
+ break;
+
+ if (h->forced_local)
+ 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;
+
+ relocation = (splt->output_section->vma
+ + splt->output_offset
+ + h->plt.offset);
+ break;
+
+ case R_M32R_HI16_SLO_RELA:
+ if ((relocation + rel->r_addend) & 0x8000)
+ rel->r_addend += 0x10000;
+ /* Fall through. */
+
+ case R_M32R_16_RELA:
+ case R_M32R_24_RELA:
+ case R_M32R_32_RELA:
+ case R_M32R_REL32:
+ case R_M32R_10_PCREL_RELA:
+ case R_M32R_18_PCREL_RELA:
+ case R_M32R_26_PCREL_RELA:
+ case R_M32R_HI16_ULO_RELA:
+ case R_M32R_LO16_RELA:
+ if (info->shared
+ && r_symndx != STN_UNDEF
+ && (input_section->flags & SEC_ALLOC) != 0
+ && (( r_type != R_M32R_10_PCREL_RELA
+ && r_type != R_M32R_18_PCREL_RELA
+ && r_type != R_M32R_26_PCREL_RELA
+ && r_type != R_M32R_REL32)
+ || (h != NULL
+ && h->dynindx != -1
+ && (! info->symbolic
+ || !h->def_regular))))
+ {
+ Elf_Internal_Rela outrel;
+ bfd_boolean skip, relocate;
+ bfd_byte *loc;
+
+ /* When generating a shared object, these relocations
+ are copied into the output file to be resolved at run
+ time. */
+ if (sreloc == NULL)
+ {
+ sreloc = _bfd_elf_get_dynamic_reloc_section
+ (input_bfd, input_section, /*rela?*/ TRUE);
+ if (sreloc == NULL)
+ return FALSE;
+ }
+
+ skip = FALSE;
+ relocate = FALSE;
+
+ outrel.r_offset = _bfd_elf_section_offset (output_bfd,
+ info,
+ input_section,
+ rel->r_offset);
+ if (outrel.r_offset == (bfd_vma) -1)
+ skip = TRUE;
+ else if (outrel.r_offset == (bfd_vma) -2)
+ skip = relocate = TRUE;
+ outrel.r_offset += (input_section->output_section->vma
+ + input_section->output_offset);
+
+ if (skip)
+ memset (&outrel, 0, sizeof outrel);
+ else if ( r_type == R_M32R_10_PCREL_RELA
+ || r_type == R_M32R_18_PCREL_RELA
+ || r_type == R_M32R_26_PCREL_RELA
+ || r_type == R_M32R_REL32)
+ {
+ BFD_ASSERT (h != NULL && h->dynindx != -1);
+ outrel.r_info = ELF32_R_INFO (h->dynindx, r_type);
+ outrel.r_addend = rel->r_addend;
+ }
+ else
+ {
+ /* h->dynindx may be -1 if this symbol was marked to
+ become local. */
+ if (h == NULL
+ || ((info->symbolic || h->dynindx == -1)
+ && h->def_regular))
+ {
+ relocate = TRUE;
+ outrel.r_info = ELF32_R_INFO (0, R_M32R_RELATIVE);
+ outrel.r_addend = relocation + rel->r_addend;
+ }
+ else
+ {
+ BFD_ASSERT (h->dynindx != -1);
+ outrel.r_info = ELF32_R_INFO (h->dynindx, r_type);
+ outrel.r_addend = relocation + rel->r_addend;
+ }
+ }
+
+ loc = sreloc->contents;
+ loc += sreloc->reloc_count * sizeof (Elf32_External_Rela);
+ bfd_elf32_swap_reloca_out (output_bfd, &outrel,loc);
+ ++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;
+ }
+ else if (r_type != R_M32R_10_PCREL_RELA)
+ break;
+ /* Fall through. */
+
+ case (int) R_M32R_10_PCREL :
+ r = m32r_elf_do_10_pcrel_reloc (input_bfd, howto, input_section,
+ contents, offset,
+ sec, relocation, addend);
+ goto check_reloc;
+
+ 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);
+ }
+
+ goto check_reloc;
+
+ case (int) R_M32R_SDA16_RELA:
+ case (int) R_M32R_SDA16 :
+ {
+ const char *name;
+
+ BFD_ASSERT (sec != NULL);
+ name = bfd_get_section_name (sec->owner, 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)
+ (_("%B: The target (%s) of an %s relocation is in the wrong section (%A)"),
+ input_bfd,
+ sec,
+ sym_name,
+ m32r_elf_howto_table[(int) r_type].name);
+ /*bfd_set_error (bfd_error_bad_value); ??? why? */
+ ret = FALSE;
+ continue;
+ }
+ }
+ /* Fall through. */
+
+ default : /* OLD_M32R_RELOC */
+
+ r = _bfd_final_link_relocate (howto, input_bfd, input_section,
+ contents, offset,
+ relocation, addend);
+ goto check_reloc;
+ }
+
+ r = _bfd_final_link_relocate (howto, input_bfd, input_section,
+ contents, rel->r_offset,
+ relocation, rel->r_addend);
+
+ }
+
+ 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, (h ? &h->root : NULL), 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, TRUE)))
+ 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;
+}
+
+/* Finish up dynamic symbol handling. We set the contents of various
+ dynamic sections here. */
+
+static bfd_boolean
+m32r_elf_finish_dynamic_symbol (bfd *output_bfd,
+ struct bfd_link_info *info,
+ struct elf_link_hash_entry *h,
+ Elf_Internal_Sym *sym)
+{
+ struct elf_m32r_link_hash_table *htab;
+ bfd_byte *loc;
+
+#ifdef DEBUG_PIC
+ printf ("m32r_elf_finish_dynamic_symbol()\n");
+#endif
+
+ htab = m32r_elf_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ 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 = htab->splt;
+ sgot = htab->sgotplt;
+ srela = htab->srelplt;
+ 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. */
+ if (! info->shared)
+ {
+ bfd_put_32 (output_bfd,
+ (PLT_ENTRY_WORD0b
+ + (((sgot->output_section->vma
+ + sgot->output_offset
+ + got_offset) >> 16) & 0xffff)),
+ splt->contents + h->plt.offset);
+ bfd_put_32 (output_bfd,
+ (PLT_ENTRY_WORD1b
+ + ((sgot->output_section->vma
+ + sgot->output_offset
+ + got_offset) & 0xffff)),
+ splt->contents + h->plt.offset + 4);
+ bfd_put_32 (output_bfd, PLT_ENTRY_WORD2,
+ splt->contents + h->plt.offset + 8);
+ bfd_put_32 (output_bfd,
+ (PLT_ENTRY_WORD3
+ + plt_index * sizeof (Elf32_External_Rela)),
+ splt->contents + h->plt.offset + 12);
+ bfd_put_32 (output_bfd,
+ (PLT_ENTRY_WORD4
+ + (((unsigned int) ((- (h->plt.offset + 16)) >> 2)) & 0xffffff)),
+ splt->contents + h->plt.offset + 16);
+ }
+ else
+ {
+ bfd_put_32 (output_bfd,
+ PLT_ENTRY_WORD0 + got_offset,
+ splt->contents + h->plt.offset);
+ bfd_put_32 (output_bfd, PLT_ENTRY_WORD1,
+ splt->contents + h->plt.offset + 4);
+ bfd_put_32 (output_bfd, PLT_ENTRY_WORD2,
+ splt->contents + h->plt.offset + 8);
+ bfd_put_32 (output_bfd,
+ (PLT_ENTRY_WORD3
+ + plt_index * sizeof (Elf32_External_Rela)),
+ splt->contents + h->plt.offset + 12);
+ bfd_put_32 (output_bfd,
+ (PLT_ENTRY_WORD4
+ + (((unsigned int) ((- (h->plt.offset + 16)) >> 2)) & 0xffffff)),
+ 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
+ + 12), /* same offset */
+ 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_M32R_JMP_SLOT);
+ rela.r_addend = 0;
+ loc = srela->contents;
+ loc += plt_index * sizeof (Elf32_External_Rela);
+ bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
+
+ if (!h->def_regular)
+ {
+ /* 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 = htab->sgot;
+ srela = htab->srelgot;
+ 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->forced_local)
+ && h->def_regular)
+ {
+ rela.r_info = ELF32_R_INFO (0, R_M32R_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_M32R_GLOB_DAT);
+ rela.r_addend = 0;
+ }
+
+ loc = srela->contents;
+ loc += srela->reloc_count * sizeof (Elf32_External_Rela);
+ bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
+ ++srela->reloc_count;
+ }
+
+ if (h->needs_copy)
+ {
+ asection *s;
+ Elf_Internal_Rela rela;
+
+ /* This symbols 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_linker_section (htab->root.dynobj, ".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_M32R_COPY);
+ rela.r_addend = 0;
+ loc = s->contents;
+ loc += s->reloc_count * sizeof (Elf32_External_Rela);
+ bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
+ ++s->reloc_count;
+ }
+
+ /* Mark some specially defined symbols as absolute. */
+ if (h == htab->root.hdynamic || h == htab->root.hgot)
+ sym->st_shndx = SHN_ABS;
+
+ return TRUE;
+}
+
+
+/* Finish up the dynamic sections. */
+
+static bfd_boolean
+m32r_elf_finish_dynamic_sections (bfd *output_bfd,
+ struct bfd_link_info *info)
+{
+ struct elf_m32r_link_hash_table *htab;
+ bfd *dynobj;
+ asection *sdyn;
+ asection *sgot;
+
+#ifdef DEBUG_PIC
+ printf ("m32r_elf_finish_dynamic_sections()\n");
+#endif
+
+ htab = m32r_elf_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ dynobj = htab->root.dynobj;
+
+ sgot = htab->sgotplt;
+ sdyn = bfd_get_linker_section (dynobj, ".dynamic");
+
+ if (htab->root.dynamic_sections_created)
+ {
+ asection *splt;
+ Elf32_External_Dyn *dyncon, *dynconend;
+
+ BFD_ASSERT (sgot != NULL && sdyn != NULL);
+
+ dyncon = (Elf32_External_Dyn *) sdyn->contents;
+ dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->size);
+
+ for (; dyncon < dynconend; dyncon++)
+ {
+ Elf_Internal_Dyn dyn;
+ asection *s;
+
+ bfd_elf32_swap_dyn_in (dynobj, dyncon, &dyn);
+
+ switch (dyn.d_tag)
+ {
+ default:
+ break;
+
+ case DT_PLTGOT:
+ s = htab->sgot->output_section;
+ goto get_vma;
+ case DT_JMPREL:
+ s = htab->srelplt->output_section;
+ get_vma:
+ 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 = htab->srelplt->output_section;
+ BFD_ASSERT (s != NULL);
+ dyn.d_un.d_val = s->size;
+ bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
+ break;
+
+ case DT_RELASZ:
+ /* My reading of the SVR4 ABI indicates that the
+ procedure linkage table relocs (DT_JMPREL) should be
+ included in the overall relocs (DT_RELA). This is
+ what Solaris does. However, UnixWare can not handle
+ that case. 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. */
+ if (htab->srelplt != NULL)
+ {
+ s = htab->srelplt->output_section;
+ dyn.d_un.d_val -= s->size;
+ }
+ bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
+ break;
+ }
+ }
+
+ /* Fill in the first entry in the procedure linkage table. */
+ splt = htab->splt;
+ if (splt && splt->size > 0)
+ {
+ if (info->shared)
+ {
+ bfd_put_32 (output_bfd, PLT0_PIC_ENTRY_WORD0, splt->contents);
+ bfd_put_32 (output_bfd, PLT0_PIC_ENTRY_WORD1, splt->contents + 4);
+ bfd_put_32 (output_bfd, PLT0_PIC_ENTRY_WORD2, splt->contents + 8);
+ bfd_put_32 (output_bfd, PLT0_PIC_ENTRY_WORD3, splt->contents + 12);
+ bfd_put_32 (output_bfd, PLT0_PIC_ENTRY_WORD4, splt->contents + 16);
+ }
+ else
+ {
+ unsigned long addr;
+ /* addr = .got + 4 */
+ addr = sgot->output_section->vma + sgot->output_offset + 4;
+ bfd_put_32 (output_bfd,
+ PLT0_ENTRY_WORD0 | ((addr >> 16) & 0xffff),
+ splt->contents);
+ bfd_put_32 (output_bfd,
+ PLT0_ENTRY_WORD1 | (addr & 0xffff),
+ splt->contents + 4);
+ bfd_put_32 (output_bfd, PLT0_ENTRY_WORD2, splt->contents + 8);
+ bfd_put_32 (output_bfd, PLT0_ENTRY_WORD3, splt->contents + 12);
+ bfd_put_32 (output_bfd, PLT0_ENTRY_WORD4, splt->contents + 16);
+ }
+
+ 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 && sgot->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;
+}
+
+
+/* Set the right machine number. */
+
+static bfd_boolean
+m32r_elf_object_p (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;
+ case E_M32RX_ARCH: (void) bfd_default_set_arch_mach (abfd, bfd_arch_m32r, bfd_mach_m32rx); break;
+ case E_M32R2_ARCH: (void) bfd_default_set_arch_mach (abfd, bfd_arch_m32r, bfd_mach_m32r2); break;
+ }
+ return TRUE;
+}
+
+/* Store the machine number in the flags field. */
+
+static void
+m32r_elf_final_write_processing (bfd *abfd,
+ bfd_boolean linker ATTRIBUTE_UNUSED)
+{
+ unsigned long val;
+
+ switch (bfd_get_mach (abfd))
+ {
+ default:
+ case bfd_mach_m32r: val = E_M32R_ARCH; break;
+ case bfd_mach_m32rx: val = E_M32RX_ARCH; break;
+ case bfd_mach_m32r2: val = E_M32R2_ARCH; break;
+ }
+
+ elf_elfheader (abfd)->e_flags &=~ EF_M32R_ARCH;
+ elf_elfheader (abfd)->e_flags |= val;
+}
+
+/* Function to keep M32R specific file flags. */
+
+static bfd_boolean
+m32r_elf_set_private_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;
+}
+
+/* Merge backend specific data from an object file to the output
+ object file when linking. */
+
+static bfd_boolean
+m32r_elf_merge_private_bfd_data (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)
+ || ((out_flags & EF_M32R_ARCH) == E_M32R_ARCH)
+ || ((in_flags & EF_M32R_ARCH) == E_M32R2_ARCH))
+ {
+ (*_bfd_error_handler)
+ (_("%B: Instruction set mismatch with previous modules"), ibfd);
+
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+/* Display the flags field. */
+
+static bfd_boolean
+m32r_elf_print_private_bfd_data (bfd *abfd, void * 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;
+ case E_M32RX_ARCH: fprintf (file, _(": m32rx instructions")); break;
+ case E_M32R2_ARCH: fprintf (file, _(": m32r2 instructions")); break;
+ }
+
+ fputc ('\n', file);
+
+ return TRUE;
+}
+
+static asection *
+m32r_elf_gc_mark_hook (asection *sec,
+ 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:
+ case R_M32R_RELA_GNU_VTINHERIT:
+ case R_M32R_RELA_GNU_VTENTRY:
+ return NULL;
+ }
+
+ return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
+}
+
+static bfd_boolean
+m32r_elf_gc_sweep_hook (bfd *abfd ATTRIBUTE_UNUSED,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ asection *sec ATTRIBUTE_UNUSED,
+ const Elf_Internal_Rela *relocs ATTRIBUTE_UNUSED)
+{
+ /* Update the got entry reference counts for the section being removed. */
+ Elf_Internal_Shdr *symtab_hdr;
+ struct elf_link_hash_entry **sym_hashes;
+ bfd_signed_vma *local_got_refcounts;
+ const Elf_Internal_Rela *rel, *relend;
+
+ if (info->relocatable)
+ return TRUE;
+
+ elf_section_data (sec)->local_dynrel = NULL;
+
+ 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++)
+ {
+ unsigned long r_symndx;
+ struct elf_link_hash_entry *h = NULL;
+
+ r_symndx = ELF32_R_SYM (rel->r_info);
+ if (r_symndx >= symtab_hdr->sh_info)
+ {
+ 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;
+ }
+
+ switch (ELF32_R_TYPE (rel->r_info))
+ {
+ case R_M32R_GOT16_HI_ULO:
+ case R_M32R_GOT16_HI_SLO:
+ case R_M32R_GOT16_LO:
+ case R_M32R_GOTOFF:
+ case R_M32R_GOTOFF_HI_ULO:
+ case R_M32R_GOTOFF_HI_SLO:
+ case R_M32R_GOTOFF_LO:
+ case R_M32R_GOT24:
+ case R_M32R_GOTPC_HI_ULO:
+ case R_M32R_GOTPC_HI_SLO:
+ case R_M32R_GOTPC_LO:
+ case R_M32R_GOTPC24:
+ if (h != NULL)
+ {
+ if (h->got.refcount > 0)
+ h->got.refcount--;
+ }
+ else
+ {
+ if (local_got_refcounts && local_got_refcounts[r_symndx] > 0)
+ local_got_refcounts[r_symndx]--;
+ }
+ break;
+
+ case R_M32R_16_RELA:
+ case R_M32R_24_RELA:
+ case R_M32R_32_RELA:
+ case R_M32R_REL32:
+ case R_M32R_HI16_ULO_RELA:
+ case R_M32R_HI16_SLO_RELA:
+ case R_M32R_LO16_RELA:
+ case R_M32R_SDA16_RELA:
+ case R_M32R_10_PCREL_RELA:
+ case R_M32R_18_PCREL_RELA:
+ case R_M32R_26_PCREL_RELA:
+ if (h != NULL)
+ {
+ struct elf_m32r_link_hash_entry *eh;
+ struct elf_m32r_dyn_relocs **pp;
+ struct elf_m32r_dyn_relocs *p;
+
+ if (!info->shared && h->plt.refcount > 0)
+ h->plt.refcount -= 1;
+
+ eh = (struct elf_m32r_link_hash_entry *) h;
+
+ for (pp = &eh->dyn_relocs; (p = *pp) != NULL; pp = &p->next)
+ if (p->sec == sec)
+ {
+ if ( ELF32_R_TYPE (rel->r_info) == R_M32R_26_PCREL_RELA
+ || ELF32_R_TYPE (rel->r_info) == R_M32R_18_PCREL_RELA
+ || ELF32_R_TYPE (rel->r_info) == R_M32R_10_PCREL_RELA
+ || ELF32_R_TYPE (rel->r_info) == R_M32R_REL32)
+ p->pc_count -= 1;
+ p->count -= 1;
+ if (p->count == 0)
+ *pp = p->next;
+ break;
+ }
+ }
+ break;
+
+ case R_M32R_26_PLTREL:
+ if (h != NULL)
+ {
+ if (h->plt.refcount > 0)
+ h->plt.refcount--;
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ 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 bfd_boolean
+m32r_elf_check_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;
+ const Elf_Internal_Rela *rel;
+ const Elf_Internal_Rela *rel_end;
+ struct elf_m32r_link_hash_table *htab;
+ bfd *dynobj;
+ asection *sreloc;
+
+ if (info->relocatable)
+ return TRUE;
+
+ sreloc = NULL;
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+ sym_hashes = elf_sym_hashes (abfd);
+
+ htab = m32r_elf_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ dynobj = htab->root.dynobj;
+
+ rel_end = relocs + sec->reloc_count;
+ for (rel = relocs; rel < rel_end; rel++)
+ {
+ int r_type;
+ struct elf_link_hash_entry *h;
+ unsigned long r_symndx;
+
+ r_symndx = ELF32_R_SYM (rel->r_info);
+ r_type = ELF32_R_TYPE (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.type == bfd_link_hash_indirect
+ || h->root.type == bfd_link_hash_warning)
+ h = (struct elf_link_hash_entry *) h->root.u.i.link;
+
+ /* PR15323, ref flags aren't set for references in the same
+ object. */
+ h->root.non_ir_ref = 1;
+ }
+
+ /* Some relocs require a global offset table. */
+ if (htab->sgot == NULL)
+ {
+ switch (r_type)
+ {
+ case R_M32R_GOT16_HI_ULO:
+ case R_M32R_GOT16_HI_SLO:
+ case R_M32R_GOTOFF:
+ case R_M32R_GOTOFF_HI_ULO:
+ case R_M32R_GOTOFF_HI_SLO:
+ case R_M32R_GOTOFF_LO:
+ case R_M32R_GOT16_LO:
+ case R_M32R_GOTPC24:
+ case R_M32R_GOTPC_HI_ULO:
+ case R_M32R_GOTPC_HI_SLO:
+ case R_M32R_GOTPC_LO:
+ case R_M32R_GOT24:
+ if (dynobj == NULL)
+ htab->root.dynobj = dynobj = abfd;
+ if (! create_got_section (dynobj, info))
+ return FALSE;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ switch (r_type)
+ {
+ case R_M32R_GOT16_HI_ULO:
+ case R_M32R_GOT16_HI_SLO:
+ case R_M32R_GOT16_LO:
+ case R_M32R_GOT24:
+
+ if (h != NULL)
+ h->got.refcount += 1;
+ else
+ {
+ bfd_signed_vma *local_got_refcounts;
+
+ /* This is a global offset table entry for a local
+ symbol. */
+ local_got_refcounts = elf_local_got_refcounts (abfd);
+ if (local_got_refcounts == NULL)
+ {
+ bfd_size_type size;
+
+ size = symtab_hdr->sh_info;
+ size *= sizeof (bfd_signed_vma);
+ local_got_refcounts = bfd_zalloc (abfd, size);
+ if (local_got_refcounts == NULL)
+ return FALSE;
+ elf_local_got_refcounts (abfd) = local_got_refcounts;
+ }
+ local_got_refcounts[r_symndx] += 1;
+ }
+ break;
+
+ case R_M32R_26_PLTREL:
+ /* 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 this is a local symbol, we resolve it directly without
+ creating a procedure linkage table entry. */
+ if (h == NULL)
+ continue;
+
+ if (h->forced_local)
+ break;
+
+ h->needs_plt = 1;
+ h->plt.refcount += 1;
+ break;
+
+ case R_M32R_16_RELA:
+ case R_M32R_24_RELA:
+ case R_M32R_32_RELA:
+ case R_M32R_REL32:
+ case R_M32R_HI16_ULO_RELA:
+ case R_M32R_HI16_SLO_RELA:
+ case R_M32R_LO16_RELA:
+ case R_M32R_SDA16_RELA:
+ case R_M32R_10_PCREL_RELA:
+ case R_M32R_18_PCREL_RELA:
+ case R_M32R_26_PCREL_RELA:
+
+ if (h != NULL && !info->shared)
+ {
+ h->non_got_ref = 1;
+ h->plt.refcount += 1;
+ }
+
+ /* 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
+ dyn_relocs field of the hash table entry. A similar
+ situation occurs when creating shared libraries and symbol
+ visibility changes render the symbol local.
+
+ If on the other hand, we are creating an executable, we
+ may need to keep relocations for symbols satisfied by a
+ dynamic library if we manage to avoid copy relocs for the
+ symbol. */
+ if ((info->shared
+ && (sec->flags & SEC_ALLOC) != 0
+ && (( r_type != R_M32R_26_PCREL_RELA
+ && r_type != R_M32R_18_PCREL_RELA
+ && r_type != R_M32R_10_PCREL_RELA
+ && r_type != R_M32R_REL32)
+ || (h != NULL
+ && (! info->symbolic
+ || h->root.type == bfd_link_hash_defweak
+ || !h->def_regular))))
+ || (!info->shared
+ && (sec->flags & SEC_ALLOC) != 0
+ && h != NULL
+ && (h->root.type == bfd_link_hash_defweak
+ || !h->def_regular)))
+ {
+ struct elf_m32r_dyn_relocs *p;
+ struct elf_m32r_dyn_relocs **head;
+
+ if (dynobj == NULL)
+ htab->root.dynobj = dynobj = abfd;
+
+ /* 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)
+ {
+ sreloc = _bfd_elf_make_dynamic_reloc_section
+ (sec, dynobj, 2, abfd, /*rela?*/ TRUE);
+
+ if (sreloc == NULL)
+ return FALSE;
+ }
+
+ /* If this is a global symbol, we count the number of
+ relocations we need for this symbol. */
+ if (h != NULL)
+ head = &((struct elf_m32r_link_hash_entry *) h)->dyn_relocs;
+ else
+ {
+ /* Track dynamic relocs needed for local syms too. */
+ asection *s;
+ void *vpp;
+ Elf_Internal_Sym *isym;
+
+ isym = bfd_sym_from_r_symndx (&htab->sym_cache,
+ abfd, r_symndx);
+ if (isym == NULL)
+ return FALSE;
+
+ s = bfd_section_from_elf_index (abfd, isym->st_shndx);
+ if (s == NULL)
+ s = sec;
+
+ vpp = &elf_section_data (s)->local_dynrel;
+ head = (struct elf_m32r_dyn_relocs **) vpp;
+ }
+
+ p = *head;
+ if (p == NULL || p->sec != sec)
+ {
+ bfd_size_type amt = sizeof (*p);
+
+ p = bfd_alloc (dynobj, amt);
+ if (p == NULL)
+ return FALSE;
+ p->next = *head;
+ *head = p;
+ p->sec = sec;
+ p->count = 0;
+ p->pc_count = 0;
+ }
+
+ p->count += 1;
+ if ( ELF32_R_TYPE (rel->r_info) == R_M32R_26_PCREL_RELA
+ || ELF32_R_TYPE (rel->r_info) == R_M32R_18_PCREL_RELA
+ || ELF32_R_TYPE (rel->r_info) == R_M32R_10_PCREL_RELA
+ || ELF32_R_TYPE (rel->r_info) == R_M32R_REL32)
+ p->pc_count += 1;
+ }
+ break;
+
+ /* This relocation describes the C++ object vtable hierarchy.
+ Reconstruct it for later use during GC. */
+ case R_M32R_RELA_GNU_VTINHERIT:
+ case R_M32R_GNU_VTINHERIT:
+ if (!bfd_elf_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:
+ BFD_ASSERT (h != NULL);
+ if (h != NULL
+ && !bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_offset))
+ return FALSE;
+ break;
+ case R_M32R_RELA_GNU_VTENTRY:
+ BFD_ASSERT (h != NULL);
+ if (h != NULL
+ && !bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
+ return FALSE;
+ break;
+ }
+ }
+
+ return TRUE;
+}
+
+static const struct bfd_elf_special_section m32r_elf_special_sections[] =
+{
+ { STRING_COMMA_LEN (".sbss"), -2, SHT_NOBITS, SHF_ALLOC + SHF_WRITE },
+ { STRING_COMMA_LEN (".sdata"), -2, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE },
+ { NULL, 0, 0, 0, 0 }
+};
+
+static enum elf_reloc_type_class
+m32r_elf_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ const asection *rel_sec ATTRIBUTE_UNUSED,
+ const Elf_Internal_Rela *rela)
+{
+ switch ((int) ELF32_R_TYPE (rela->r_info))
+ {
+ case R_M32R_RELATIVE: return reloc_class_relative;
+ case R_M32R_JMP_SLOT: return reloc_class_plt;
+ case R_M32R_COPY: return reloc_class_copy;
+ default: return reloc_class_normal;
+ }
+}
+
+#define ELF_ARCH bfd_arch_m32r
+#define ELF_TARGET_ID M32R_ELF_DATA
+#define ELF_MACHINE_CODE EM_M32R
+#define ELF_MACHINE_ALT1 EM_CYGNUS_M32R
+#define ELF_MAXPAGESIZE 0x1 /* Explicitly requested by Mitsubishi. */
+
+#define TARGET_BIG_SYM m32r_elf32_vec
+#define TARGET_BIG_NAME "elf32-m32r"
+#define TARGET_LITTLE_SYM m32r_elf32_le_vec
+#define TARGET_LITTLE_NAME "elf32-m32rle"
+
+#define elf_info_to_howto m32r_info_to_howto
+#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_create_dynamic_sections m32r_elf_create_dynamic_sections
+#define bfd_elf32_bfd_link_hash_table_create m32r_elf_link_hash_table_create
+#define elf_backend_size_dynamic_sections m32r_elf_size_dynamic_sections
+#define elf_backend_omit_section_dynsym \
+ ((bfd_boolean (*) (bfd *, struct bfd_link_info *, asection *)) bfd_true)
+#define elf_backend_finish_dynamic_sections m32r_elf_finish_dynamic_sections
+#define elf_backend_adjust_dynamic_symbol m32r_elf_adjust_dynamic_symbol
+#define elf_backend_finish_dynamic_symbol m32r_elf_finish_dynamic_symbol
+#define elf_backend_reloc_type_class m32r_elf_reloc_type_class
+#define elf_backend_copy_indirect_symbol m32r_elf_copy_indirect_symbol
+
+#define elf_backend_can_gc_sections 1
+/*#if !USE_REL
+#define elf_backend_rela_normal 1
+#endif*/
+#define elf_backend_can_refcount 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_may_use_rel_p 1
+#ifdef USE_M32R_OLD_RELOC
+#define elf_backend_default_use_rela_p 0
+#define elf_backend_may_use_rela_p 0
+#else
+#define elf_backend_default_use_rela_p 1
+#define elf_backend_may_use_rela_p 1
+#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_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
+#define elf_backend_special_sections m32r_elf_special_sections
+
+#include "elf32-target.h"
+
+#undef ELF_MAXPAGESIZE
+#define ELF_MAXPAGESIZE 0x1000
+
+#undef TARGET_BIG_SYM
+#define TARGET_BIG_SYM m32r_elf32_linux_vec
+#undef TARGET_BIG_NAME
+#define TARGET_BIG_NAME "elf32-m32r-linux"
+#undef TARGET_LITTLE_SYM
+#define TARGET_LITTLE_SYM m32r_elf32_linux_le_vec
+#undef TARGET_LITTLE_NAME
+#define TARGET_LITTLE_NAME "elf32-m32rle-linux"
+#undef elf32_bed
+#define elf32_bed elf32_m32r_lin_bed
+
+#include "elf32-target.h"
+
diff --git a/bfd/elf32-m68hc11.c b/bfd/elf32-m68hc11.c
new file mode 100644
index 0000000..2101bdf
--- /dev/null
+++ b/bfd/elf32-m68hc11.c
@@ -0,0 +1,1314 @@
+/* Motorola 68HC11-specific support for 32-bit ELF
+ Copyright (C) 1999-2014 Free Software Foundation, Inc.
+ Contributed by Stephane Carrez (stcarrez@nerim.fr)
+ (Heavily copied from the D10V port 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "bfdlink.h"
+#include "libbfd.h"
+#include "elf-bfd.h"
+#include "elf32-m68hc1x.h"
+#include "elf/m68hc11.h"
+#include "opcode/m68hc11.h"
+
+/* Relocation functions. */
+static reloc_howto_type *bfd_elf32_bfd_reloc_type_lookup
+ (bfd *, bfd_reloc_code_real_type);
+static void m68hc11_info_to_howto_rel
+ (bfd *, arelent *, Elf_Internal_Rela *);
+
+/* Trampoline generation. */
+static bfd_boolean m68hc11_elf_size_one_stub
+ (struct bfd_hash_entry *gen_entry, void *in_arg);
+static bfd_boolean m68hc11_elf_build_one_stub
+ (struct bfd_hash_entry *gen_entry, void *in_arg);
+static struct bfd_link_hash_table* m68hc11_elf_bfd_link_hash_table_create
+ (bfd* abfd);
+
+/* Linker relaxation. */
+static bfd_boolean m68hc11_elf_relax_section
+ (bfd *, asection *, struct bfd_link_info *, bfd_boolean *);
+static void m68hc11_elf_relax_delete_bytes
+ (bfd *, asection *, bfd_vma, int);
+static void m68hc11_relax_group
+ (bfd *, asection *, bfd_byte *, unsigned, unsigned long, unsigned long);
+static int compare_reloc (const void *, const void *);
+
+/* Use REL instead of RELA to save space */
+#define USE_REL 1
+
+/* The Motorola 68HC11 microcontroller only addresses 64Kb but we also
+ support a memory bank switching mechanism similar to 68HC12.
+ We must handle 8 and 16-bit relocations. The 32-bit relocation
+ are used for debugging sections (DWARF2) to represent a virtual
+ address.
+ The 3-bit and 16-bit PC rel relocation is only used by 68HC12. */
+static reloc_howto_type elf_m68hc11_howto_table[] = {
+ /* This reloc does nothing. */
+ HOWTO (R_M68HC11_NONE, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_M68HC11_NONE", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A 8 bit absolute relocation */
+ HOWTO (R_M68HC11_8, /* 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_M68HC11_8", /* name */
+ FALSE, /* partial_inplace */
+ 0x00ff, /* src_mask */
+ 0x00ff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A 8 bit absolute relocation (upper address) */
+ HOWTO (R_M68HC11_HI8, /* type */
+ 8, /* 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_M68HC11_HI8", /* name */
+ FALSE, /* partial_inplace */
+ 0x00ff, /* src_mask */
+ 0x00ff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A 8 bit absolute relocation (upper address) */
+ HOWTO (R_M68HC11_LO8, /* 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_M68HC11_LO8", /* name */
+ FALSE, /* partial_inplace */
+ 0x00ff, /* src_mask */
+ 0x00ff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A 8 bit PC-rel relocation */
+ HOWTO (R_M68HC11_PCREL_8, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 8, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_M68HC11_PCREL_8", /* name */
+ FALSE, /* partial_inplace */
+ 0x00ff, /* src_mask */
+ 0x00ff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* A 16 bit absolute relocation */
+ HOWTO (R_M68HC11_16, /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont /*bitfield */ , /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_M68HC11_16", /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A 32 bit absolute relocation. This one is never used for the
+ code relocation. It's used by gas for -gstabs generation. */
+ HOWTO (R_M68HC11_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_M68HC11_32", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A 3 bit absolute relocation */
+ HOWTO (R_M68HC11_3B, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 3, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_M68HC11_4B", /* name */
+ FALSE, /* partial_inplace */
+ 0x003, /* src_mask */
+ 0x003, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A 16 bit PC-rel relocation */
+ HOWTO (R_M68HC11_PCREL_16, /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_M68HC11_PCREL_16", /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* GNU extension to record C++ vtable hierarchy */
+ HOWTO (R_M68HC11_GNU_VTINHERIT, /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 0, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ NULL, /* special_function */
+ "R_M68HC11_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_M68HC11_GNU_VTENTRY, /* type */
+ 0, /* rightshift */
+ 1, /* 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_M68HC11_GNU_VTENTRY", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A 24 bit relocation */
+ HOWTO (R_M68HC11_24, /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 24, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_M68HC11_24", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffff, /* src_mask */
+ 0xffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A 16-bit low relocation */
+ HOWTO (R_M68HC11_LO16, /* 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_M68HC11_LO16", /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A page relocation */
+ HOWTO (R_M68HC11_PAGE, /* 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_M68HC11_PAGE", /* name */
+ FALSE, /* partial_inplace */
+ 0x00ff, /* src_mask */
+ 0x00ff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ EMPTY_HOWTO (14),
+ EMPTY_HOWTO (15),
+ EMPTY_HOWTO (16),
+ EMPTY_HOWTO (17),
+ EMPTY_HOWTO (18),
+ EMPTY_HOWTO (19),
+
+ /* Mark beginning of a jump instruction (any form). */
+ HOWTO (R_M68HC11_RL_JUMP, /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 0, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ m68hc11_elf_ignore_reloc, /* special_function */
+ "R_M68HC11_RL_JUMP", /* name */
+ TRUE, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* Mark beginning of Gcc relaxation group instruction. */
+ HOWTO (R_M68HC11_RL_GROUP, /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 0, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ m68hc11_elf_ignore_reloc, /* special_function */
+ "R_M68HC11_RL_GROUP", /* name */
+ TRUE, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ TRUE), /* pcrel_offset */
+};
+
+/* Map BFD reloc types to M68HC11 ELF reloc types. */
+
+struct m68hc11_reloc_map
+{
+ bfd_reloc_code_real_type bfd_reloc_val;
+ unsigned char elf_reloc_val;
+};
+
+static const struct m68hc11_reloc_map m68hc11_reloc_map[] = {
+ {BFD_RELOC_NONE, R_M68HC11_NONE,},
+ {BFD_RELOC_8, R_M68HC11_8},
+ {BFD_RELOC_M68HC11_HI8, R_M68HC11_HI8},
+ {BFD_RELOC_M68HC11_LO8, R_M68HC11_LO8},
+ {BFD_RELOC_8_PCREL, R_M68HC11_PCREL_8},
+ {BFD_RELOC_16_PCREL, R_M68HC11_PCREL_16},
+ {BFD_RELOC_16, R_M68HC11_16},
+ {BFD_RELOC_32, R_M68HC11_32},
+ {BFD_RELOC_M68HC11_3B, R_M68HC11_3B},
+
+ {BFD_RELOC_VTABLE_INHERIT, R_M68HC11_GNU_VTINHERIT},
+ {BFD_RELOC_VTABLE_ENTRY, R_M68HC11_GNU_VTENTRY},
+
+ {BFD_RELOC_M68HC11_LO16, R_M68HC11_LO16},
+ {BFD_RELOC_M68HC11_PAGE, R_M68HC11_PAGE},
+ {BFD_RELOC_M68HC11_24, R_M68HC11_24},
+
+ {BFD_RELOC_M68HC11_RL_JUMP, R_M68HC11_RL_JUMP},
+ {BFD_RELOC_M68HC11_RL_GROUP, R_M68HC11_RL_GROUP},
+};
+
+static reloc_howto_type *
+bfd_elf32_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ bfd_reloc_code_real_type code)
+{
+ unsigned int i;
+
+ for (i = 0;
+ i < sizeof (m68hc11_reloc_map) / sizeof (struct m68hc11_reloc_map);
+ i++)
+ {
+ if (m68hc11_reloc_map[i].bfd_reloc_val == code)
+ return &elf_m68hc11_howto_table[m68hc11_reloc_map[i].elf_reloc_val];
+ }
+
+ return NULL;
+}
+
+static reloc_howto_type *
+bfd_elf32_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ const char *r_name)
+{
+ unsigned int i;
+
+ for (i = 0;
+ i < (sizeof (elf_m68hc11_howto_table)
+ / sizeof (elf_m68hc11_howto_table[0]));
+ i++)
+ if (elf_m68hc11_howto_table[i].name != NULL
+ && strcasecmp (elf_m68hc11_howto_table[i].name, r_name) == 0)
+ return &elf_m68hc11_howto_table[i];
+
+ return NULL;
+}
+
+/* Set the howto pointer for an M68HC11 ELF reloc. */
+
+static void
+m68hc11_info_to_howto_rel (bfd *abfd ATTRIBUTE_UNUSED,
+ arelent *cache_ptr, Elf_Internal_Rela *dst)
+{
+ unsigned int r_type;
+
+ r_type = ELF32_R_TYPE (dst->r_info);
+ BFD_ASSERT (r_type < (unsigned int) R_M68HC11_max);
+ cache_ptr->howto = &elf_m68hc11_howto_table[r_type];
+}
+
+
+/* Far trampoline generation. */
+
+/* Build a 68HC11 trampoline stub. */
+static bfd_boolean
+m68hc11_elf_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
+{
+ struct elf32_m68hc11_stub_hash_entry *stub_entry;
+ struct bfd_link_info *info;
+ struct m68hc11_elf_link_hash_table *htab;
+ asection *stub_sec;
+ bfd *stub_bfd;
+ bfd_byte *loc;
+ bfd_vma sym_value, phys_page, phys_addr;
+
+ /* Massage our args to the form they really have. */
+ stub_entry = (struct elf32_m68hc11_stub_hash_entry *) gen_entry;
+ info = (struct bfd_link_info *) in_arg;
+
+ htab = m68hc11_elf_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ stub_sec = stub_entry->stub_sec;
+
+ /* Make a note of the offset within the stubs for this entry. */
+ stub_entry->stub_offset = stub_sec->size;
+ stub_sec->size += 10;
+ loc = stub_sec->contents + stub_entry->stub_offset;
+
+ stub_bfd = stub_sec->owner;
+
+ /* Create the trampoline call stub:
+
+ pshb
+ ldab #%page(symbol)
+ ldy #%addr(symbol)
+ jmp __trampoline
+
+ */
+ sym_value = (stub_entry->target_value
+ + stub_entry->target_section->output_offset
+ + stub_entry->target_section->output_section->vma);
+ phys_addr = m68hc11_phys_addr (&htab->pinfo, sym_value);
+ phys_page = m68hc11_phys_page (&htab->pinfo, sym_value);
+
+ /* pshb; ldab #%page(sym) */
+ bfd_put_8 (stub_bfd, 0x37, loc);
+ bfd_put_8 (stub_bfd, 0xC6, loc + 1);
+ bfd_put_8 (stub_bfd, phys_page, loc + 2);
+ loc += 3;
+
+ /* ldy #%addr(sym) */
+ bfd_put_8 (stub_bfd, 0x18, loc);
+ bfd_put_8 (stub_bfd, 0xCE, loc + 1);
+ bfd_put_16 (stub_bfd, phys_addr, loc + 2);
+ loc += 4;
+
+ /* jmp __trampoline */
+ bfd_put_8 (stub_bfd, 0x7E, loc);
+ bfd_put_16 (stub_bfd, htab->pinfo.trampoline_addr, loc + 1);
+
+ return TRUE;
+}
+
+/* As above, but don't actually build the stub. Just bump offset so
+ we know stub section sizes. */
+
+static bfd_boolean
+m68hc11_elf_size_one_stub (struct bfd_hash_entry *gen_entry,
+ void *in_arg ATTRIBUTE_UNUSED)
+{
+ struct elf32_m68hc11_stub_hash_entry *stub_entry;
+
+ /* Massage our args to the form they really have. */
+ stub_entry = (struct elf32_m68hc11_stub_hash_entry *) gen_entry;
+
+ stub_entry->stub_sec->size += 10;
+ return TRUE;
+}
+
+/* Create a 68HC11 ELF linker hash table. */
+
+static struct bfd_link_hash_table *
+m68hc11_elf_bfd_link_hash_table_create (bfd *abfd)
+{
+ struct m68hc11_elf_link_hash_table *ret;
+
+ ret = m68hc11_elf_hash_table_create (abfd);
+ if (ret == (struct m68hc11_elf_link_hash_table *) NULL)
+ return NULL;
+
+ ret->size_one_stub = m68hc11_elf_size_one_stub;
+ ret->build_one_stub = m68hc11_elf_build_one_stub;
+
+ return &ret->root.root;
+}
+
+
+/* 68HC11 Linker Relaxation. */
+
+struct m68hc11_direct_relax
+{
+ const char *name;
+ unsigned char code;
+ unsigned char direct_code;
+} m68hc11_direct_relax_table[] = {
+ { "adca", 0xB9, 0x99 },
+ { "adcb", 0xF9, 0xD9 },
+ { "adda", 0xBB, 0x9B },
+ { "addb", 0xFB, 0xDB },
+ { "addd", 0xF3, 0xD3 },
+ { "anda", 0xB4, 0x94 },
+ { "andb", 0xF4, 0xD4 },
+ { "cmpa", 0xB1, 0x91 },
+ { "cmpb", 0xF1, 0xD1 },
+ { "cpd", 0xB3, 0x93 },
+ { "cpxy", 0xBC, 0x9C },
+/* { "cpy", 0xBC, 0x9C }, */
+ { "eora", 0xB8, 0x98 },
+ { "eorb", 0xF8, 0xD8 },
+ { "jsr", 0xBD, 0x9D },
+ { "ldaa", 0xB6, 0x96 },
+ { "ldab", 0xF6, 0xD6 },
+ { "ldd", 0xFC, 0xDC },
+ { "lds", 0xBE, 0x9E },
+ { "ldxy", 0xFE, 0xDE },
+ /* { "ldy", 0xFE, 0xDE },*/
+ { "oraa", 0xBA, 0x9A },
+ { "orab", 0xFA, 0xDA },
+ { "sbca", 0xB2, 0x92 },
+ { "sbcb", 0xF2, 0xD2 },
+ { "staa", 0xB7, 0x97 },
+ { "stab", 0xF7, 0xD7 },
+ { "std", 0xFD, 0xDD },
+ { "sts", 0xBF, 0x9F },
+ { "stxy", 0xFF, 0xDF },
+ /* { "sty", 0xFF, 0xDF },*/
+ { "suba", 0xB0, 0x90 },
+ { "subb", 0xF0, 0xD0 },
+ { "subd", 0xB3, 0x93 },
+ { 0, 0, 0 }
+};
+
+static struct m68hc11_direct_relax *
+find_relaxable_insn (unsigned char code)
+{
+ int i;
+
+ for (i = 0; m68hc11_direct_relax_table[i].name; i++)
+ if (m68hc11_direct_relax_table[i].code == code)
+ return &m68hc11_direct_relax_table[i];
+
+ return 0;
+}
+
+static int
+compare_reloc (const void *e1, const void *e2)
+{
+ const Elf_Internal_Rela *i1 = (const Elf_Internal_Rela *) e1;
+ const Elf_Internal_Rela *i2 = (const Elf_Internal_Rela *) e2;
+
+ if (i1->r_offset == i2->r_offset)
+ return 0;
+ else
+ return i1->r_offset < i2->r_offset ? -1 : 1;
+}
+
+#define M6811_OP_LDX_IMMEDIATE (0xCE)
+
+static void
+m68hc11_relax_group (bfd *abfd, asection *sec, bfd_byte *contents,
+ unsigned value, unsigned long offset,
+ unsigned long end_group)
+{
+ unsigned char code;
+ unsigned long start_offset;
+ unsigned long ldx_offset = offset;
+ unsigned long ldx_size;
+ int can_delete_ldx;
+ int relax_ldy = 0;
+
+ /* First instruction of the relax group must be a
+ LDX #value or LDY #value. If this is not the case,
+ ignore the relax group. */
+ code = bfd_get_8 (abfd, contents + offset);
+ if (code == 0x18)
+ {
+ relax_ldy++;
+ offset++;
+ code = bfd_get_8 (abfd, contents + offset);
+ }
+ ldx_size = offset - ldx_offset + 3;
+ offset += 3;
+ if (code != M6811_OP_LDX_IMMEDIATE || offset >= end_group)
+ return;
+
+
+ /* We can remove the LDX/LDY only when all bset/brclr instructions
+ of the relax group have been converted to use direct addressing
+ mode. */
+ can_delete_ldx = 1;
+ while (offset < end_group)
+ {
+ unsigned isize;
+ unsigned new_value;
+ int bset_use_y;
+
+ bset_use_y = 0;
+ start_offset = offset;
+ code = bfd_get_8 (abfd, contents + offset);
+ if (code == 0x18)
+ {
+ bset_use_y++;
+ offset++;
+ code = bfd_get_8 (abfd, contents + offset);
+ }
+
+ /* Check the instruction and translate to use direct addressing mode. */
+ switch (code)
+ {
+ /* bset */
+ case 0x1C:
+ code = 0x14;
+ isize = 3;
+ break;
+
+ /* brclr */
+ case 0x1F:
+ code = 0x13;
+ isize = 4;
+ break;
+
+ /* brset */
+ case 0x1E:
+ code = 0x12;
+ isize = 4;
+ break;
+
+ /* bclr */
+ case 0x1D:
+ code = 0x15;
+ isize = 3;
+ break;
+
+ /* This instruction is not recognized and we are not
+ at end of the relax group. Ignore and don't remove
+ the first LDX (we don't know what it is used for...). */
+ default:
+ return;
+ }
+ new_value = (unsigned) bfd_get_8 (abfd, contents + offset + 1);
+ new_value += value;
+ if ((new_value & 0xff00) == 0 && bset_use_y == relax_ldy)
+ {
+ bfd_put_8 (abfd, code, contents + offset);
+ bfd_put_8 (abfd, new_value, contents + offset + 1);
+ if (start_offset != offset)
+ {
+ m68hc11_elf_relax_delete_bytes (abfd, sec, start_offset,
+ offset - start_offset);
+ end_group--;
+ }
+ }
+ else
+ {
+ can_delete_ldx = 0;
+ }
+ offset = start_offset + isize;
+ }
+ if (can_delete_ldx)
+ {
+ /* Remove the move instruction (3 or 4 bytes win). */
+ m68hc11_elf_relax_delete_bytes (abfd, sec, ldx_offset, ldx_size);
+ }
+}
+
+/* This function handles relaxing for the 68HC11.
+
+
+ and somewhat more difficult to support. */
+
+static bfd_boolean
+m68hc11_elf_relax_section (bfd *abfd, asection *sec,
+ struct bfd_link_info *link_info, bfd_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 *free_extsyms = NULL;
+ Elf_Internal_Rela *prev_insn_branch = NULL;
+ Elf_Internal_Rela *prev_insn_group = NULL;
+ unsigned insn_group_value = 0;
+ Elf_Internal_Sym *isymbuf = NULL;
+
+ /* Assume nothing changes. */
+ *again = FALSE;
+
+ /* We don't have to do anything for a relocatable link, if
+ this section does not have relocs, or if this is not a
+ code section. */
+ if (link_info->relocatable
+ || (sec->flags & SEC_RELOC) == 0
+ || sec->reloc_count == 0
+ || (sec->flags & SEC_CODE) == 0)
+ return TRUE;
+
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+
+ /* Get a copy of the native relocations. */
+ internal_relocs = (_bfd_elf_link_read_relocs
+ (abfd, sec, 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;
+
+ /* Checking for branch relaxation relies on the relocations to
+ be sorted on 'r_offset'. This is not guaranteed so we must sort. */
+ qsort (internal_relocs, sec->reloc_count, sizeof (Elf_Internal_Rela),
+ compare_reloc);
+
+ /* Walk through them looking for relaxing opportunities. */
+ irelend = internal_relocs + sec->reloc_count;
+ for (irel = internal_relocs; irel < irelend; irel++)
+ {
+ bfd_vma symval;
+ bfd_vma value;
+ Elf_Internal_Sym *isym;
+ asection *sym_sec;
+ int is_far = 0;
+
+ /* If this isn't something that can be relaxed, then ignore
+ this reloc. */
+ if (ELF32_R_TYPE (irel->r_info) != (int) R_M68HC11_16
+ && ELF32_R_TYPE (irel->r_info) != (int) R_M68HC11_RL_JUMP
+ && ELF32_R_TYPE (irel->r_info) != (int) R_M68HC11_RL_GROUP)
+ {
+ prev_insn_branch = 0;
+ prev_insn_group = 0;
+ 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. */
+ if (!bfd_malloc_and_get_section (abfd, sec, &contents))
+ goto error_return;
+ }
+ }
+
+ /* 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_M68HC11_RL_JUMP)
+ {
+ Elf_Internal_Rela *nrel;
+ unsigned char code;
+ unsigned char roffset;
+
+ prev_insn_branch = 0;
+ prev_insn_group = 0;
+
+ /* Do nothing if this reloc is the last byte in the section. */
+ if (irel->r_offset + 2 >= sec->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 + 2);
+ if (code != 0x7e)
+ 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 + 3 != nrel->r_offset
+ || ELF32_R_TYPE (nrel->r_info) != (int) R_M68HC11_16)
+ continue;
+
+ /* Make sure our destination immediately follows the
+ unconditional branch. */
+ roffset = bfd_get_8 (abfd, contents + irel->r_offset + 1);
+ if (roffset != 3)
+ continue;
+
+ prev_insn_branch = irel;
+ prev_insn_group = 0;
+ continue;
+ }
+
+ /* Read this BFD's symbols if we haven't done so already. */
+ if (isymbuf == NULL && symtab_hdr->sh_info != 0)
+ {
+ isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
+ if (isymbuf == NULL)
+ isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
+ symtab_hdr->sh_info, 0,
+ NULL, NULL, NULL);
+ if (isymbuf == NULL)
+ 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)
+ {
+ /* A local symbol. */
+ isym = isymbuf + ELF32_R_SYM (irel->r_info);
+ is_far = isym->st_other & STO_M68HC12_FAR;
+ 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. */
+ prev_insn_branch = 0;
+ prev_insn_group = 0;
+ continue;
+ }
+
+ is_far = h->other & STO_M68HC12_FAR;
+ isym = 0;
+ sym_sec = h->root.u.def.section;
+ symval = (h->root.u.def.value
+ + sym_sec->output_section->vma
+ + sym_sec->output_offset);
+ }
+
+ if (ELF32_R_TYPE (irel->r_info) == (int) R_M68HC11_RL_GROUP)
+ {
+ prev_insn_branch = 0;
+ prev_insn_group = 0;
+
+ /* Do nothing if this reloc is the last byte in the section. */
+ if (irel->r_offset == sec->size)
+ continue;
+
+ prev_insn_group = irel;
+ insn_group_value = isym->st_value;
+ continue;
+ }
+
+ /* When we relax some bytes, the size of our section changes.
+ This affects the layout of next input sections that go in our
+ output section. When the symbol is part of another section that
+ will go in the same output section as the current one, it's
+ final address may now be incorrect (too far). We must let the
+ linker re-compute all section offsets before processing this
+ reloc. Code example:
+
+ Initial Final
+ .sect .text section size = 6 section size = 4
+ jmp foo
+ jmp bar
+ .sect .text.foo_bar output_offset = 6 output_offset = 4
+ foo: rts
+ bar: rts
+
+ If we process the reloc now, the jmp bar is replaced by a
+ relative branch to the initial bar address (output_offset 6). */
+ if (*again && sym_sec != sec
+ && sym_sec->output_section == sec->output_section)
+ {
+ prev_insn_group = 0;
+ prev_insn_branch = 0;
+ continue;
+ }
+
+ value = symval;
+ /* Try to turn a far branch to a near branch. */
+ if (ELF32_R_TYPE (irel->r_info) == (int) R_M68HC11_16
+ && prev_insn_branch)
+ {
+ bfd_vma offset;
+ unsigned char code;
+
+ offset = value - (prev_insn_branch->r_offset
+ + sec->output_section->vma
+ + sec->output_offset + 2);
+
+ /* If the offset is still out of -128..+127 range,
+ leave that far branch unchanged. */
+ if ((offset & 0xff80) != 0 && (offset & 0xff80) != 0xff80)
+ {
+ prev_insn_branch = 0;
+ continue;
+ }
+
+ /* Shrink the branch. */
+ code = bfd_get_8 (abfd, contents + prev_insn_branch->r_offset);
+ if (code == 0x7e)
+ {
+ code = 0x20;
+ bfd_put_8 (abfd, code, contents + prev_insn_branch->r_offset);
+ bfd_put_8 (abfd, 0xff,
+ contents + prev_insn_branch->r_offset + 1);
+ irel->r_offset = prev_insn_branch->r_offset + 1;
+ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
+ R_M68HC11_PCREL_8);
+ m68hc11_elf_relax_delete_bytes (abfd, sec,
+ irel->r_offset + 1, 1);
+ }
+ else
+ {
+ code ^= 0x1;
+ bfd_put_8 (abfd, code, contents + prev_insn_branch->r_offset);
+ bfd_put_8 (abfd, 0xff,
+ contents + prev_insn_branch->r_offset + 1);
+ irel->r_offset = prev_insn_branch->r_offset + 1;
+ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
+ R_M68HC11_PCREL_8);
+ m68hc11_elf_relax_delete_bytes (abfd, sec,
+ irel->r_offset + 1, 3);
+ }
+ prev_insn_branch = 0;
+ *again = TRUE;
+ }
+
+ /* Try to turn a 16 bit address into a 8 bit page0 address. */
+ else if (ELF32_R_TYPE (irel->r_info) == (int) R_M68HC11_16
+ && (value & 0xff00) == 0)
+ {
+ unsigned char code;
+ unsigned short offset;
+ struct m68hc11_direct_relax *rinfo;
+
+ prev_insn_branch = 0;
+ offset = bfd_get_16 (abfd, contents + irel->r_offset);
+ offset += value;
+ if ((offset & 0xff00) != 0)
+ {
+ prev_insn_group = 0;
+ continue;
+ }
+
+ if (prev_insn_group)
+ {
+ unsigned long old_sec_size = sec->size;
+
+ /* 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 *) isymbuf;
+ free_extsyms = NULL;
+
+ m68hc11_relax_group (abfd, sec, contents, offset,
+ prev_insn_group->r_offset,
+ insn_group_value);
+ irel = prev_insn_group;
+ prev_insn_group = 0;
+ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
+ R_M68HC11_NONE);
+ if (sec->size != old_sec_size)
+ *again = TRUE;
+ continue;
+ }
+
+ /* Get the opcode. */
+ code = bfd_get_8 (abfd, contents + irel->r_offset - 1);
+ rinfo = find_relaxable_insn (code);
+ if (rinfo == 0)
+ {
+ prev_insn_group = 0;
+ 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 *) isymbuf;
+ free_extsyms = NULL;
+
+ /* Fix the opcode. */
+ /* printf ("A relaxable case : 0x%02x (%s)\n",
+ code, rinfo->name); */
+ bfd_put_8 (abfd, rinfo->direct_code,
+ contents + irel->r_offset - 1);
+
+ /* Delete one byte of data (upper byte of address). */
+ m68hc11_elf_relax_delete_bytes (abfd, sec, irel->r_offset, 1);
+
+ /* Fix the relocation's type. */
+ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
+ R_M68HC11_8);
+
+ /* That will change things, so, we should relax again. */
+ *again = TRUE;
+ }
+ else if (ELF32_R_TYPE (irel->r_info) == R_M68HC11_16 && !is_far)
+ {
+ unsigned char code;
+ bfd_vma offset;
+
+ prev_insn_branch = 0;
+ code = bfd_get_8 (abfd, contents + irel->r_offset - 1);
+ if (code == 0x7e || code == 0xbd)
+ {
+ offset = value - (irel->r_offset
+ + sec->output_section->vma
+ + sec->output_offset + 1);
+ offset += bfd_get_16 (abfd, contents + irel->r_offset);
+
+ /* If the offset is still out of -128..+127 range,
+ leave that far branch unchanged. */
+ if ((offset & 0xff80) == 0 || (offset & 0xff80) == 0xff80)
+ {
+
+ /* 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 *) isymbuf;
+ free_extsyms = NULL;
+
+ /* Shrink the branch. */
+ code = (code == 0x7e) ? 0x20 : 0x8d;
+ bfd_put_8 (abfd, code,
+ contents + irel->r_offset - 1);
+ bfd_put_8 (abfd, 0xff,
+ contents + irel->r_offset);
+ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
+ R_M68HC11_PCREL_8);
+ m68hc11_elf_relax_delete_bytes (abfd, sec,
+ irel->r_offset + 1, 1);
+ /* That will change things, so, we should relax again. */
+ *again = TRUE;
+ }
+ }
+ }
+ prev_insn_branch = 0;
+ prev_insn_group = 0;
+ }
+
+ 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 = (unsigned char *) isymbuf;
+ }
+ 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 void
+m68hc11_elf_relax_delete_bytes (bfd *abfd, asection *sec,
+ bfd_vma addr, int count)
+{
+ Elf_Internal_Shdr *symtab_hdr;
+ unsigned int sec_shndx;
+ bfd_byte *contents;
+ Elf_Internal_Rela *irel, *irelend;
+ bfd_vma toaddr;
+ Elf_Internal_Sym *isymbuf, *isym, *isymend;
+ struct elf_link_hash_entry **sym_hashes;
+ struct elf_link_hash_entry **end_hashes;
+ unsigned int symcount;
+
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+ isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
+
+ sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
+
+ contents = elf_section_data (sec)->this_hdr.contents;
+
+ toaddr = sec->size;
+
+ irel = elf_section_data (sec)->relocs;
+ irelend = irel + sec->reloc_count;
+
+ /* Actually delete the bytes. */
+ memmove (contents + addr, contents + addr + count,
+ (size_t) (toaddr - addr - count));
+
+ sec->size -= count;
+
+ /* Adjust all the relocs. */
+ for (irel = elf_section_data (sec)->relocs; irel < irelend; irel++)
+ {
+ unsigned char code;
+ unsigned char offset;
+ unsigned short raddr;
+ unsigned long old_offset;
+ int branch_pos;
+
+ old_offset = irel->r_offset;
+
+ /* 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 (ELF32_R_TYPE (irel->r_info) != R_M68HC11_RL_JUMP
+ && irel->r_offset >= addr && irel->r_offset < addr + count)
+ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
+ R_M68HC11_NONE);
+
+ if (ELF32_R_TYPE (irel->r_info) == R_M68HC11_NONE)
+ continue;
+
+ /* Get the new reloc address. */
+ if ((irel->r_offset > addr
+ && irel->r_offset < toaddr))
+ irel->r_offset -= count;
+
+ /* If this is a PC relative reloc, see if the range it covers
+ includes the bytes we have deleted. */
+ switch (ELF32_R_TYPE (irel->r_info))
+ {
+ default:
+ break;
+
+ case R_M68HC11_RL_JUMP:
+ code = bfd_get_8 (abfd, contents + irel->r_offset);
+ switch (code)
+ {
+ /* jsr and jmp instruction are also marked with RL_JUMP
+ relocs but no adjustment must be made. */
+ case 0x7e:
+ case 0x9d:
+ case 0xbd:
+ continue;
+
+ case 0x12:
+ case 0x13:
+ branch_pos = 3;
+ raddr = 4;
+
+ /* Special case when we translate a brclr N,y into brclr *<addr>
+ In this case, the 0x18 page2 prefix is removed.
+ The reloc offset is not modified but the instruction
+ size is reduced by 1. */
+ if (old_offset == addr)
+ raddr++;
+ break;
+
+ case 0x1e:
+ case 0x1f:
+ branch_pos = 3;
+ raddr = 4;
+ break;
+
+ case 0x18:
+ branch_pos = 4;
+ raddr = 5;
+ break;
+
+ default:
+ branch_pos = 1;
+ raddr = 2;
+ break;
+ }
+ offset = bfd_get_8 (abfd, contents + irel->r_offset + branch_pos);
+ raddr += old_offset;
+ raddr += ((unsigned short) offset | ((offset & 0x80) ? 0xff00 : 0));
+ if (irel->r_offset < addr && raddr > addr)
+ {
+ offset -= count;
+ bfd_put_8 (abfd, offset, contents + irel->r_offset + branch_pos);
+ }
+ else if (irel->r_offset >= addr && raddr <= addr)
+ {
+ offset += count;
+ bfd_put_8 (abfd, offset, contents + irel->r_offset + branch_pos);
+ }
+ else
+ {
+ /*printf ("Not adjusted 0x%04x [0x%4x 0x%4x]\n", raddr,
+ irel->r_offset, addr);*/
+ }
+
+ break;
+ }
+ }
+
+ /* Adjust the local symbols defined in this section. */
+ isymend = isymbuf + symtab_hdr->sh_info;
+ for (isym = isymbuf; isym < isymend; isym++)
+ {
+ if (isym->st_shndx == sec_shndx
+ && isym->st_value > addr
+ && isym->st_value <= toaddr)
+ isym->st_value -= count;
+ }
+
+ /* Now adjust the global symbols defined in this section. */
+ symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
+ - symtab_hdr->sh_info);
+ sym_hashes = elf_sym_hashes (abfd);
+ end_hashes = sym_hashes + symcount;
+ for (; sym_hashes < end_hashes; sym_hashes++)
+ {
+ struct elf_link_hash_entry *sym_hash = *sym_hashes;
+ 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
+ && sym_hash->root.u.def.value <= toaddr)
+ {
+ sym_hash->root.u.def.value -= count;
+ }
+ }
+}
+
+/* Specific sections:
+ - The .page0 is a data section that is mapped in [0x0000..0x00FF].
+ Page0 accesses are faster on the M68HC11. Soft registers used by GCC-m6811
+ are located in .page0.
+ - The .vectors is the section that represents the interrupt
+ vectors. */
+static const struct bfd_elf_special_section elf32_m68hc11_special_sections[] =
+{
+ { STRING_COMMA_LEN (".eeprom"), 0, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE },
+ { STRING_COMMA_LEN (".page0"), 0, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE },
+ { STRING_COMMA_LEN (".softregs"), 0, SHT_NOBITS, SHF_ALLOC + SHF_WRITE },
+ { STRING_COMMA_LEN (".vectors"), 0, SHT_PROGBITS, SHF_ALLOC },
+ { NULL, 0, 0, 0, 0 }
+};
+
+#define ELF_ARCH bfd_arch_m68hc11
+#define ELF_TARGET_ID M68HC11_ELF_DATA
+#define ELF_MACHINE_CODE EM_68HC11
+#define ELF_MAXPAGESIZE 0x1000
+
+#define TARGET_BIG_SYM m68hc11_elf32_vec
+#define TARGET_BIG_NAME "elf32-m68hc11"
+
+#define elf_info_to_howto 0
+#define elf_info_to_howto_rel m68hc11_info_to_howto_rel
+#define bfd_elf32_bfd_relax_section m68hc11_elf_relax_section
+#define elf_backend_check_relocs elf32_m68hc11_check_relocs
+#define elf_backend_relocate_section elf32_m68hc11_relocate_section
+#define elf_backend_add_symbol_hook elf32_m68hc11_add_symbol_hook
+#define elf_backend_object_p 0
+#define elf_backend_final_write_processing 0
+#define elf_backend_can_gc_sections 1
+#define elf_backend_special_sections elf32_m68hc11_special_sections
+#define elf_backend_merge_symbol_attribute elf32_m68hc11_merge_symbol_attribute
+
+#define bfd_elf32_bfd_link_hash_table_create \
+ m68hc11_elf_bfd_link_hash_table_create
+#define bfd_elf32_bfd_merge_private_bfd_data \
+ _bfd_m68hc11_elf_merge_private_bfd_data
+#define bfd_elf32_bfd_set_private_flags _bfd_m68hc11_elf_set_private_flags
+#define bfd_elf32_bfd_print_private_bfd_data \
+ _bfd_m68hc11_elf_print_private_bfd_data
+
+#include "elf32-target.h"
diff --git a/bfd/elf32-m68hc12.c b/bfd/elf32-m68hc12.c
new file mode 100644
index 0000000..7f48b7e
--- /dev/null
+++ b/bfd/elf32-m68hc12.c
@@ -0,0 +1,664 @@
+/* Motorola 68HC12-specific support for 32-bit ELF
+ Copyright (C) 1999-2014 Free Software Foundation, Inc.
+ Contributed by Stephane Carrez (stcarrez@nerim.fr)
+ (Heavily copied from the D10V port 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "bfdlink.h"
+#include "libbfd.h"
+#include "elf-bfd.h"
+#include "elf32-m68hc1x.h"
+#include "elf/m68hc11.h"
+#include "opcode/m68hc11.h"
+
+/* Relocation functions. */
+static reloc_howto_type *bfd_elf32_bfd_reloc_type_lookup
+ (bfd *, bfd_reloc_code_real_type);
+static void m68hc11_info_to_howto_rel
+ (bfd *, arelent *, Elf_Internal_Rela *);
+
+/* Trampoline generation. */
+
+
+/* Use REL instead of RELA to save space */
+#define USE_REL 1
+
+/* The 68HC12 microcontroler has a memory bank switching system
+ with a 16Kb window in the 64Kb address space. The extended memory
+ is mapped in the 16Kb window (at 0x8000). The page register controls
+ which 16Kb bank is mapped. The call/rtc instructions take care of
+ bank switching in function calls/returns.
+
+ For GNU Binutils to work, we consider there is a physical memory
+ at 0..0x0ffff and a kind of virtual memory above that. Symbols
+ in virtual memory have their addresses treated in a special way
+ when disassembling and when linking.
+
+ For the linker to work properly, we must always relocate the virtual
+ memory as if it is mapped at 0x8000. When a 16-bit relocation is
+ made in the virtual memory, we check that it does not cross the
+ memory bank where it is used. This would involve a page change
+ which would be wrong. The 24-bit relocation is for that and it
+ treats the address as a physical address + page number.
+
+
+ Banked
+ Address Space
+ | | Page n
+ +---------------+ 0x1010000
+ | |
+ | jsr _foo |
+ | .. | Page 3
+ | _foo: |
+ +---------------+ 0x100C000
+ | |
+ | call _bar |
+ | .. | Page 2
+ | _bar: |
+ +---------------+ 0x1008000
+ /------>| |
+ | | call _foo | Page 1
+ | | |
+ | +---------------+ 0x1004000
+ Physical | | |
+ Address Space | | | Page 0
+ | | |
+ +-----------+ 0x00FFFF | +---------------+ 0x1000000
+ | | |
+ | call _foo | |
+ | | |
+ +-----------+ 0x00BFFF -+---/
+ | | |
+ | | |
+ | | 16K |
+ | | |
+ +-----------+ 0x008000 -+
+ | |
+ | |
+ = =
+ | |
+ | |
+ +-----------+ 0000
+
+
+ The 'call _foo' must be relocated with page 3 and 16-bit address
+ mapped at 0x8000.
+
+ The 3-bit and 16-bit PC rel relocation is only used by 68HC12. */
+static reloc_howto_type elf_m68hc11_howto_table[] = {
+ /* This reloc does nothing. */
+ HOWTO (R_M68HC11_NONE, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_M68HC12_NONE", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A 8 bit absolute relocation */
+ HOWTO (R_M68HC11_8, /* 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_M68HC12_8", /* name */
+ FALSE, /* partial_inplace */
+ 0x00ff, /* src_mask */
+ 0x00ff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A 8 bit absolute relocation (upper address) */
+ HOWTO (R_M68HC11_HI8, /* type */
+ 8, /* 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_M68HC12_HI8", /* name */
+ FALSE, /* partial_inplace */
+ 0x00ff, /* src_mask */
+ 0x00ff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A 8 bit absolute relocation (upper address) */
+ HOWTO (R_M68HC11_LO8, /* 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_M68HC12_LO8", /* name */
+ FALSE, /* partial_inplace */
+ 0x00ff, /* src_mask */
+ 0x00ff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A 8 bit PC-rel relocation */
+ HOWTO (R_M68HC11_PCREL_8, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 8, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_M68HC12_PCREL_8", /* name */
+ FALSE, /* partial_inplace */
+ 0x00ff, /* src_mask */
+ 0x00ff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* A 16 bit absolute relocation */
+ HOWTO (R_M68HC11_16, /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont /*bitfield */ , /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_M68HC12_16", /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A 32 bit absolute relocation. This one is never used for the
+ code relocation. It's used by gas for -gstabs generation. */
+ HOWTO (R_M68HC11_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_M68HC12_32", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A 3 bit absolute relocation */
+ HOWTO (R_M68HC11_3B, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 3, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_M68HC12_4B", /* name */
+ FALSE, /* partial_inplace */
+ 0x003, /* src_mask */
+ 0x003, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A 16 bit PC-rel relocation */
+ HOWTO (R_M68HC11_PCREL_16, /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_M68HC12_PCREL_16", /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* GNU extension to record C++ vtable hierarchy */
+ HOWTO (R_M68HC11_GNU_VTINHERIT, /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 0, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ NULL, /* special_function */
+ "R_M68HC11_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_M68HC11_GNU_VTENTRY, /* type */
+ 0, /* rightshift */
+ 1, /* 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_M68HC11_GNU_VTENTRY", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A 24 bit relocation */
+ HOWTO (R_M68HC11_24, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 24, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ m68hc11_elf_special_reloc, /* special_function */
+ "R_M68HC12_24", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffff, /* src_mask */
+ 0xffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A 16-bit low relocation */
+ HOWTO (R_M68HC11_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 */
+ m68hc11_elf_special_reloc,/* special_function */
+ "R_M68HC12_LO16", /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A page relocation */
+ HOWTO (R_M68HC11_PAGE, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 8, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ m68hc11_elf_special_reloc,/* special_function */
+ "R_M68HC12_PAGE", /* name */
+ FALSE, /* partial_inplace */
+ 0x00ff, /* src_mask */
+ 0x00ff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ EMPTY_HOWTO (14),
+
+ /* A 16 bit absolute relocation. */
+ HOWTO (R_M68HC12_16B, /* 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_M68HC12_16B", /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A 9 bit PC-rel relocation. */
+ HOWTO (R_M68HC12_PCREL_9, /* type */
+ 1, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 10, /* bitsize (result is >>1) */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_M68HC12_PCREL_9", /* name */
+ TRUE, /* partial_inplace */
+ 0xfe00, /* src_mask */
+ 0x01ff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* A 10 bit PC-rel relocation. */
+ HOWTO (R_M68HC12_PCREL_10, /* type */
+ 1, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 11, /* bitsize (result is >>1) */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_M68HC12_PCREL_10", /* name */
+ TRUE, /* partial_inplace */
+ 0xfc00, /* src_mask */
+ 0x03ff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* A 8 bit absolute relocation (upper address). */
+ HOWTO (R_M68HC12_HI8XG, /* type */
+ 8, /* 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_M68HC12_HI8XG", /* name */
+ FALSE, /* partial_inplace */
+ 0x00ff, /* src_mask */
+ 0x00ff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A 8 bit absolute relocation (lower address). */
+ HOWTO (R_M68HC12_LO8XG, /* type */
+ 8, /* 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_M68HC12_LO8XG", /* name */
+ FALSE, /* partial_inplace */
+ 0x00ff, /* src_mask */
+ 0x00ff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Mark beginning of a jump instruction (any form). */
+ HOWTO (R_M68HC11_RL_JUMP, /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 0, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ m68hc11_elf_ignore_reloc, /* special_function */
+ "R_M68HC12_RL_JUMP", /* name */
+ TRUE, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* Mark beginning of Gcc relaxation group instruction. */
+ HOWTO (R_M68HC11_RL_GROUP, /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 0, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ m68hc11_elf_ignore_reloc, /* special_function */
+ "R_M68HC12_RL_GROUP", /* name */
+ TRUE, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ TRUE), /* pcrel_offset */
+};
+
+/* Map BFD reloc types to M68HC11 ELF reloc types. */
+
+struct m68hc11_reloc_map
+{
+ bfd_reloc_code_real_type bfd_reloc_val;
+ unsigned char elf_reloc_val;
+};
+
+static const struct m68hc11_reloc_map m68hc11_reloc_map[] =
+{
+ {BFD_RELOC_NONE, R_M68HC11_NONE,},
+ {BFD_RELOC_8, R_M68HC11_8},
+ {BFD_RELOC_M68HC11_HI8, R_M68HC11_HI8},
+ {BFD_RELOC_M68HC11_LO8, R_M68HC11_LO8},
+ {BFD_RELOC_8_PCREL, R_M68HC11_PCREL_8},
+ {BFD_RELOC_16_PCREL, R_M68HC11_PCREL_16},
+ {BFD_RELOC_16, R_M68HC11_16},
+ {BFD_RELOC_32, R_M68HC11_32},
+ {BFD_RELOC_M68HC11_3B, R_M68HC11_3B},
+
+ {BFD_RELOC_VTABLE_INHERIT, R_M68HC11_GNU_VTINHERIT},
+ {BFD_RELOC_VTABLE_ENTRY, R_M68HC11_GNU_VTENTRY},
+
+ {BFD_RELOC_M68HC11_LO16, R_M68HC11_LO16},
+ {BFD_RELOC_M68HC11_PAGE, R_M68HC11_PAGE},
+ {BFD_RELOC_M68HC11_24, R_M68HC11_24},
+
+ {BFD_RELOC_M68HC11_RL_JUMP, R_M68HC11_RL_JUMP},
+ {BFD_RELOC_M68HC11_RL_GROUP, R_M68HC11_RL_GROUP},
+
+ {BFD_RELOC_M68HC12_16B, R_M68HC12_16B},
+
+ {BFD_RELOC_M68HC12_9_PCREL, R_M68HC12_PCREL_9},
+ {BFD_RELOC_M68HC12_10_PCREL, R_M68HC12_PCREL_10},
+ {BFD_RELOC_M68HC12_HI8XG, R_M68HC12_HI8XG},
+ {BFD_RELOC_M68HC12_LO8XG, R_M68HC12_LO8XG},
+};
+
+static reloc_howto_type *
+bfd_elf32_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ bfd_reloc_code_real_type code)
+{
+ unsigned int i;
+
+ for (i = 0;
+ i < sizeof (m68hc11_reloc_map) / sizeof (struct m68hc11_reloc_map);
+ i++)
+ {
+ if (m68hc11_reloc_map[i].bfd_reloc_val == code)
+ return &elf_m68hc11_howto_table[m68hc11_reloc_map[i].elf_reloc_val];
+ }
+
+ return NULL;
+}
+
+static reloc_howto_type *
+bfd_elf32_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ const char *r_name)
+{
+ unsigned int i;
+
+ for (i = 0;
+ i < (sizeof (elf_m68hc11_howto_table)
+ / sizeof (elf_m68hc11_howto_table[0]));
+ i++)
+ if (elf_m68hc11_howto_table[i].name != NULL
+ && strcasecmp (elf_m68hc11_howto_table[i].name, r_name) == 0)
+ return &elf_m68hc11_howto_table[i];
+
+ return NULL;
+}
+
+/* Set the howto pointer for an M68HC11 ELF reloc. */
+
+static void
+m68hc11_info_to_howto_rel (bfd *abfd ATTRIBUTE_UNUSED,
+ arelent *cache_ptr, Elf_Internal_Rela *dst)
+{
+ unsigned int r_type;
+
+ r_type = ELF32_R_TYPE (dst->r_info);
+ BFD_ASSERT (r_type < (unsigned int) R_M68HC11_max);
+ cache_ptr->howto = &elf_m68hc11_howto_table[r_type];
+}
+
+
+/* Far trampoline generation. */
+
+/* Build a 68HC12 trampoline stub. */
+static bfd_boolean
+m68hc12_elf_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
+{
+ struct elf32_m68hc11_stub_hash_entry *stub_entry;
+ struct bfd_link_info *info;
+ struct m68hc11_elf_link_hash_table *htab;
+ asection *stub_sec;
+ bfd *stub_bfd;
+ bfd_byte *loc;
+ bfd_vma sym_value, phys_page, phys_addr;
+
+ /* Massage our args to the form they really have. */
+ stub_entry = (struct elf32_m68hc11_stub_hash_entry *) gen_entry;
+ info = (struct bfd_link_info *) in_arg;
+
+ htab = m68hc11_elf_hash_table (info);
+
+ stub_sec = stub_entry->stub_sec;
+
+ /* Make a note of the offset within the stubs for this entry. */
+ stub_entry->stub_offset = stub_sec->size;
+ stub_sec->size += 7;
+ loc = stub_sec->contents + stub_entry->stub_offset;
+
+ stub_bfd = stub_sec->owner;
+
+ /* Create the trampoline call stub:
+
+ ldy #%addr(symbol)
+ call %page(symbol), __trampoline
+
+ */
+ sym_value = (stub_entry->target_value
+ + stub_entry->target_section->output_offset
+ + stub_entry->target_section->output_section->vma);
+ phys_addr = m68hc11_phys_addr (&htab->pinfo, sym_value);
+ phys_page = m68hc11_phys_page (&htab->pinfo, sym_value);
+
+ /* ldy #%page(sym) */
+ bfd_put_8 (stub_bfd, 0xCD, loc);
+ bfd_put_16 (stub_bfd, phys_addr, loc + 1);
+ loc += 3;
+
+ /* call %page(sym), __trampoline */
+ bfd_put_8 (stub_bfd, 0x4a, loc);
+ bfd_put_16 (stub_bfd, htab->pinfo.trampoline_addr, loc + 1);
+ bfd_put_8 (stub_bfd, phys_page, loc + 3);
+
+ return TRUE;
+}
+
+/* As above, but don't actually build the stub. Just bump offset so
+ we know stub section sizes. */
+
+static bfd_boolean
+m68hc12_elf_size_one_stub (struct bfd_hash_entry *gen_entry,
+ void *in_arg ATTRIBUTE_UNUSED)
+{
+ struct elf32_m68hc11_stub_hash_entry *stub_entry;
+
+ /* Massage our args to the form they really have. */
+ stub_entry = (struct elf32_m68hc11_stub_hash_entry *) gen_entry;
+
+ stub_entry->stub_sec->size += 7;
+ return TRUE;
+}
+
+/* Create a 68HC12 ELF linker hash table. */
+
+static struct bfd_link_hash_table *
+m68hc12_elf_bfd_link_hash_table_create (bfd *abfd)
+{
+ struct m68hc11_elf_link_hash_table *ret;
+
+ ret = m68hc11_elf_hash_table_create (abfd);
+ if (ret == (struct m68hc11_elf_link_hash_table *) NULL)
+ return NULL;
+
+ ret->size_one_stub = m68hc12_elf_size_one_stub;
+ ret->build_one_stub = m68hc12_elf_build_one_stub;
+
+ return &ret->root.root;
+}
+
+static bfd_boolean
+m68hc12_elf_set_mach_from_flags (bfd *abfd)
+{
+ flagword flags = elf_elfheader (abfd)->e_flags;
+
+ switch (flags & EF_M68HC11_MACH_MASK)
+ {
+ case EF_M68HC12_MACH:
+ bfd_default_set_arch_mach (abfd, bfd_arch_m68hc12, bfd_mach_m6812);
+ break;
+ case EF_M68HCS12_MACH:
+ bfd_default_set_arch_mach (abfd, bfd_arch_m68hc12, bfd_mach_m6812s);
+ break;
+ case EF_M68HC11_GENERIC:
+ bfd_default_set_arch_mach (abfd, bfd_arch_m68hc12,
+ bfd_mach_m6812_default);
+ break;
+ default:
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/* Specific sections:
+ - The .page0 is a data section that is mapped in [0x0000..0x00FF].
+ Page0 accesses are faster on the M68HC12.
+ - The .vectors is the section that represents the interrupt
+ vectors. */
+static const struct bfd_elf_special_section elf32_m68hc12_special_sections[] =
+{
+ { STRING_COMMA_LEN (".eeprom"), 0, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE },
+ { STRING_COMMA_LEN (".page0"), 0, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE },
+ { STRING_COMMA_LEN (".softregs"), 0, SHT_NOBITS, SHF_ALLOC + SHF_WRITE },
+ { STRING_COMMA_LEN (".vectors"), 0, SHT_PROGBITS, SHF_ALLOC },
+ { NULL, 0, 0, 0, 0 }
+};
+
+#define ELF_ARCH bfd_arch_m68hc12
+#define ELF_TARGET_ID M68HC11_ELF_DATA
+#define ELF_MACHINE_CODE EM_68HC12
+#define ELF_MAXPAGESIZE 0x1000
+
+#define TARGET_BIG_SYM m68hc12_elf32_vec
+#define TARGET_BIG_NAME "elf32-m68hc12"
+
+#define elf_info_to_howto 0
+#define elf_info_to_howto_rel m68hc11_info_to_howto_rel
+#define elf_backend_check_relocs elf32_m68hc11_check_relocs
+#define elf_backend_relocate_section elf32_m68hc11_relocate_section
+#define elf_backend_object_p m68hc12_elf_set_mach_from_flags
+#define elf_backend_final_write_processing 0
+#define elf_backend_can_gc_sections 1
+#define elf_backend_special_sections elf32_m68hc12_special_sections
+#define elf_backend_post_process_headers elf32_m68hc11_post_process_headers
+#define elf_backend_add_symbol_hook elf32_m68hc11_add_symbol_hook
+#define elf_backend_merge_symbol_attribute elf32_m68hc11_merge_symbol_attribute
+
+#define bfd_elf32_bfd_link_hash_table_create \
+ m68hc12_elf_bfd_link_hash_table_create
+#define bfd_elf32_bfd_merge_private_bfd_data \
+ _bfd_m68hc11_elf_merge_private_bfd_data
+#define bfd_elf32_bfd_set_private_flags _bfd_m68hc11_elf_set_private_flags
+#define bfd_elf32_bfd_print_private_bfd_data \
+ _bfd_m68hc11_elf_print_private_bfd_data
+
+#include "elf32-target.h"
diff --git a/bfd/elf32-m68hc1x.c b/bfd/elf32-m68hc1x.c
new file mode 100644
index 0000000..c3a99df
--- /dev/null
+++ b/bfd/elf32-m68hc1x.c
@@ -0,0 +1,1501 @@
+/* Motorola 68HC11/HC12-specific support for 32-bit ELF
+ Copyright (C) 1999-2014 Free Software Foundation, Inc.
+ Contributed by Stephane Carrez (stcarrez@nerim.fr)
+
+ This file is part of BFD, the Binary File Descriptor library.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "alloca-conf.h"
+#include "bfd.h"
+#include "bfdlink.h"
+#include "libbfd.h"
+#include "elf-bfd.h"
+#include "elf32-m68hc1x.h"
+#include "elf/m68hc11.h"
+#include "opcode/m68hc11.h"
+
+
+#define m68hc12_stub_hash_lookup(table, string, create, copy) \
+ ((struct elf32_m68hc11_stub_hash_entry *) \
+ bfd_hash_lookup ((table), (string), (create), (copy)))
+
+static struct elf32_m68hc11_stub_hash_entry* m68hc12_add_stub
+ (const char *stub_name,
+ asection *section,
+ struct m68hc11_elf_link_hash_table *htab);
+
+static struct bfd_hash_entry *stub_hash_newfunc
+ (struct bfd_hash_entry *, struct bfd_hash_table *, const char *);
+
+static void m68hc11_elf_set_symbol (bfd* abfd, struct bfd_link_info *info,
+ const char* name, bfd_vma value,
+ asection* sec);
+
+static bfd_boolean m68hc11_elf_export_one_stub
+ (struct bfd_hash_entry *gen_entry, void *in_arg);
+
+static void scan_sections_for_abi (bfd*, asection*, void *);
+
+struct m68hc11_scan_param
+{
+ struct m68hc11_page_info* pinfo;
+ bfd_boolean use_memory_banks;
+};
+
+
+/* Destroy a 68HC11/68HC12 ELF linker hash table. */
+
+static void
+m68hc11_elf_bfd_link_hash_table_free (bfd *obfd)
+{
+ struct m68hc11_elf_link_hash_table *ret
+ = (struct m68hc11_elf_link_hash_table *) obfd->link.hash;
+
+ bfd_hash_table_free (ret->stub_hash_table);
+ free (ret->stub_hash_table);
+ _bfd_elf_link_hash_table_free (obfd);
+}
+
+/* Create a 68HC11/68HC12 ELF linker hash table. */
+
+struct m68hc11_elf_link_hash_table*
+m68hc11_elf_hash_table_create (bfd *abfd)
+{
+ struct m68hc11_elf_link_hash_table *ret;
+ bfd_size_type amt = sizeof (struct m68hc11_elf_link_hash_table);
+
+ ret = (struct m68hc11_elf_link_hash_table *) bfd_zmalloc (amt);
+ if (ret == (struct m68hc11_elf_link_hash_table *) NULL)
+ return NULL;
+
+ if (!_bfd_elf_link_hash_table_init (&ret->root, abfd,
+ _bfd_elf_link_hash_newfunc,
+ sizeof (struct elf_link_hash_entry),
+ M68HC11_ELF_DATA))
+ {
+ free (ret);
+ return NULL;
+ }
+
+ /* Init the stub hash table too. */
+ amt = sizeof (struct bfd_hash_table);
+ ret->stub_hash_table = (struct bfd_hash_table*) bfd_malloc (amt);
+ if (ret->stub_hash_table == NULL)
+ {
+ _bfd_elf_link_hash_table_free (abfd);
+ return NULL;
+ }
+ if (!bfd_hash_table_init (ret->stub_hash_table, stub_hash_newfunc,
+ sizeof (struct elf32_m68hc11_stub_hash_entry)))
+ {
+ free (ret->stub_hash_table);
+ _bfd_elf_link_hash_table_free (abfd);
+ return NULL;
+ }
+ ret->root.root.hash_table_free = m68hc11_elf_bfd_link_hash_table_free;
+
+ return ret;
+}
+
+/* Assorted hash table functions. */
+
+/* Initialize an entry in the stub hash table. */
+
+static struct bfd_hash_entry *
+stub_hash_newfunc (struct bfd_hash_entry *entry, struct bfd_hash_table *table,
+ const char *string)
+{
+ /* Allocate the structure if it has not already been allocated by a
+ subclass. */
+ if (entry == NULL)
+ {
+ entry = bfd_hash_allocate (table,
+ sizeof (struct elf32_m68hc11_stub_hash_entry));
+ if (entry == NULL)
+ return entry;
+ }
+
+ /* Call the allocation method of the superclass. */
+ entry = bfd_hash_newfunc (entry, table, string);
+ if (entry != NULL)
+ {
+ struct elf32_m68hc11_stub_hash_entry *eh;
+
+ /* Initialize the local fields. */
+ eh = (struct elf32_m68hc11_stub_hash_entry *) entry;
+ eh->stub_sec = NULL;
+ eh->stub_offset = 0;
+ eh->target_value = 0;
+ eh->target_section = NULL;
+ }
+
+ return entry;
+}
+
+/* Add a new stub entry to the stub hash. Not all fields of the new
+ stub entry are initialised. */
+
+static struct elf32_m68hc11_stub_hash_entry *
+m68hc12_add_stub (const char *stub_name, asection *section,
+ struct m68hc11_elf_link_hash_table *htab)
+{
+ struct elf32_m68hc11_stub_hash_entry *stub_entry;
+
+ /* Enter this entry into the linker stub hash table. */
+ stub_entry = m68hc12_stub_hash_lookup (htab->stub_hash_table, stub_name,
+ TRUE, FALSE);
+ if (stub_entry == NULL)
+ {
+ (*_bfd_error_handler) (_("%B: cannot create stub entry %s"),
+ section->owner, stub_name);
+ return NULL;
+ }
+
+ if (htab->stub_section == 0)
+ {
+ htab->stub_section = (*htab->add_stub_section) (".tramp",
+ htab->tramp_section);
+ }
+
+ stub_entry->stub_sec = htab->stub_section;
+ stub_entry->stub_offset = 0;
+ return stub_entry;
+}
+
+/* Hook called by the linker routine which adds symbols from an object
+ file. We use it for identify far symbols and force a loading of
+ the trampoline handler. */
+
+bfd_boolean
+elf32_m68hc11_add_symbol_hook (bfd *abfd, struct bfd_link_info *info,
+ Elf_Internal_Sym *sym,
+ const char **namep ATTRIBUTE_UNUSED,
+ flagword *flagsp ATTRIBUTE_UNUSED,
+ asection **secp ATTRIBUTE_UNUSED,
+ bfd_vma *valp ATTRIBUTE_UNUSED)
+{
+ if (sym->st_other & STO_M68HC12_FAR)
+ {
+ struct elf_link_hash_entry *h;
+
+ h = (struct elf_link_hash_entry *)
+ bfd_link_hash_lookup (info->hash, "__far_trampoline",
+ FALSE, FALSE, FALSE);
+ if (h == NULL)
+ {
+ struct bfd_link_hash_entry* entry = NULL;
+
+ _bfd_generic_link_add_one_symbol (info, abfd,
+ "__far_trampoline",
+ BSF_GLOBAL,
+ bfd_und_section_ptr,
+ (bfd_vma) 0, (const char*) NULL,
+ FALSE, FALSE, &entry);
+ }
+
+ }
+ return TRUE;
+}
+
+/* Merge non-visibility st_other attributes, STO_M68HC12_FAR and
+ STO_M68HC12_INTERRUPT. */
+
+void
+elf32_m68hc11_merge_symbol_attribute (struct elf_link_hash_entry *h,
+ const Elf_Internal_Sym *isym,
+ bfd_boolean definition,
+ bfd_boolean dynamic ATTRIBUTE_UNUSED)
+{
+ if (definition)
+ h->other = ((isym->st_other & ~ELF_ST_VISIBILITY (-1))
+ | ELF_ST_VISIBILITY (h->other));
+}
+
+/* External entry points for sizing and building linker stubs. */
+
+/* Set up various things so that we can make a list of input sections
+ for each output section included in the link. Returns -1 on error,
+ 0 when no stubs will be needed, and 1 on success. */
+
+int
+elf32_m68hc11_setup_section_lists (bfd *output_bfd, struct bfd_link_info *info)
+{
+ bfd *input_bfd;
+ unsigned int bfd_count;
+ int top_id, top_index;
+ asection *section;
+ asection **input_list, **list;
+ bfd_size_type amt;
+ asection *text_section;
+ struct m68hc11_elf_link_hash_table *htab;
+
+ htab = m68hc11_elf_hash_table (info);
+ if (htab == NULL)
+ return -1;
+
+ if (bfd_get_flavour (info->output_bfd) != bfd_target_elf_flavour)
+ return 0;
+
+ /* Count the number of input BFDs and find the top input section id.
+ Also search for an existing ".tramp" section so that we know
+ where generated trampolines must go. Default to ".text" if we
+ can't find it. */
+ htab->tramp_section = 0;
+ text_section = 0;
+ for (input_bfd = info->input_bfds, bfd_count = 0, top_id = 0;
+ input_bfd != NULL;
+ input_bfd = input_bfd->link.next)
+ {
+ bfd_count += 1;
+ for (section = input_bfd->sections;
+ section != NULL;
+ section = section->next)
+ {
+ const char* name = bfd_get_section_name (input_bfd, section);
+
+ if (!strcmp (name, ".tramp"))
+ htab->tramp_section = section;
+
+ if (!strcmp (name, ".text"))
+ text_section = section;
+
+ if (top_id < section->id)
+ top_id = section->id;
+ }
+ }
+ htab->bfd_count = bfd_count;
+ if (htab->tramp_section == 0)
+ htab->tramp_section = text_section;
+
+ /* We can't use output_bfd->section_count here to find the top output
+ section index as some sections may have been removed, and
+ strip_excluded_output_sections doesn't renumber the indices. */
+ for (section = output_bfd->sections, top_index = 0;
+ section != NULL;
+ section = section->next)
+ {
+ if (top_index < section->index)
+ top_index = section->index;
+ }
+
+ htab->top_index = top_index;
+ amt = sizeof (asection *) * (top_index + 1);
+ input_list = (asection **) bfd_malloc (amt);
+ htab->input_list = input_list;
+ if (input_list == NULL)
+ return -1;
+
+ /* For sections we aren't interested in, mark their entries with a
+ value we can check later. */
+ list = input_list + top_index;
+ do
+ *list = bfd_abs_section_ptr;
+ while (list-- != input_list);
+
+ for (section = output_bfd->sections;
+ section != NULL;
+ section = section->next)
+ {
+ if ((section->flags & SEC_CODE) != 0)
+ input_list[section->index] = NULL;
+ }
+
+ return 1;
+}
+
+/* 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. */
+
+bfd_boolean
+elf32_m68hc11_size_stubs (bfd *output_bfd, bfd *stub_bfd,
+ struct bfd_link_info *info,
+ asection * (*add_stub_section) (const char*, asection*))
+{
+ bfd *input_bfd;
+ asection *section;
+ Elf_Internal_Sym *local_syms, **all_local_syms;
+ unsigned int bfd_indx, bfd_count;
+ bfd_size_type amt;
+ asection *stub_sec;
+ struct m68hc11_elf_link_hash_table *htab = m68hc11_elf_hash_table (info);
+
+ if (htab == NULL)
+ return FALSE;
+
+ /* Stash our params away. */
+ htab->stub_bfd = stub_bfd;
+ htab->add_stub_section = add_stub_section;
+
+ /* Count the number of input BFDs and find the top input section id. */
+ for (input_bfd = info->input_bfds, bfd_count = 0;
+ input_bfd != NULL;
+ input_bfd = input_bfd->link.next)
+ bfd_count += 1;
+
+ /* 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. */
+ amt = sizeof (Elf_Internal_Sym *) * bfd_count;
+ all_local_syms = (Elf_Internal_Sym **) bfd_zmalloc (amt);
+ if (all_local_syms == NULL)
+ return FALSE;
+
+ /* Walk over all the input BFDs, swapping in local symbols. */
+ for (input_bfd = info->input_bfds, bfd_indx = 0;
+ input_bfd != NULL;
+ input_bfd = input_bfd->link.next, bfd_indx++)
+ {
+ Elf_Internal_Shdr *symtab_hdr;
+
+ /* 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. */
+ local_syms = (Elf_Internal_Sym *) symtab_hdr->contents;
+ if (local_syms == NULL)
+ {
+ local_syms = bfd_elf_get_elf_syms (input_bfd, symtab_hdr,
+ symtab_hdr->sh_info, 0,
+ NULL, NULL, NULL);
+ /* Cache them for elf_link_input_bfd. */
+ symtab_hdr->contents = (unsigned char *) local_syms;
+ }
+ if (local_syms == NULL)
+ {
+ free (all_local_syms);
+ return FALSE;
+ }
+
+ all_local_syms[bfd_indx] = local_syms;
+ }
+
+ for (input_bfd = info->input_bfds, bfd_indx = 0;
+ input_bfd != NULL;
+ input_bfd = input_bfd->link.next, bfd_indx++)
+ {
+ Elf_Internal_Shdr *symtab_hdr;
+ struct elf_link_hash_entry ** sym_hashes;
+
+ sym_hashes = elf_sym_hashes (input_bfd);
+
+ /* 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[bfd_indx];
+
+ /* Walk over each section attached to the input bfd. */
+ for (section = input_bfd->sections;
+ section != NULL;
+ section = section->next)
+ {
+ Elf_Internal_Rela *internal_relocs, *irelaend, *irela;
+
+ /* If there aren't any relocs, then there's nothing more
+ to do. */
+ if ((section->flags & SEC_RELOC) == 0
+ || section->reloc_count == 0)
+ continue;
+
+ /* If this section is a link-once section that will be
+ discarded, then don't create any stubs. */
+ if (section->output_section == NULL
+ || section->output_section->owner != output_bfd)
+ continue;
+
+ /* Get the relocs. */
+ internal_relocs
+ = _bfd_elf_link_read_relocs (input_bfd, section, NULL,
+ (Elf_Internal_Rela *) NULL,
+ info->keep_memory);
+ if (internal_relocs == NULL)
+ goto error_ret_free_local;
+
+ /* Now examine each relocation. */
+ irela = internal_relocs;
+ irelaend = irela + section->reloc_count;
+ for (; irela < irelaend; irela++)
+ {
+ unsigned int r_type, r_indx;
+ struct elf32_m68hc11_stub_hash_entry *stub_entry;
+ asection *sym_sec;
+ bfd_vma sym_value;
+ struct elf_link_hash_entry *hash;
+ const char *stub_name;
+ Elf_Internal_Sym *sym;
+
+ r_type = ELF32_R_TYPE (irela->r_info);
+
+ /* Only look at 16-bit relocs. */
+ if (r_type != (unsigned int) R_M68HC11_16)
+ continue;
+
+ /* Now determine the call target, its name, value,
+ section. */
+ r_indx = ELF32_R_SYM (irela->r_info);
+ if (r_indx < symtab_hdr->sh_info)
+ {
+ /* It's a local symbol. */
+ Elf_Internal_Shdr *hdr;
+ bfd_boolean is_far;
+
+ sym = local_syms + r_indx;
+ is_far = (sym && (sym->st_other & STO_M68HC12_FAR));
+ if (!is_far)
+ continue;
+
+ if (sym->st_shndx >= elf_numsections (input_bfd))
+ sym_sec = NULL;
+ else
+ {
+ hdr = elf_elfsections (input_bfd)[sym->st_shndx];
+ sym_sec = hdr->bfd_section;
+ }
+ stub_name = (bfd_elf_string_from_elf_section
+ (input_bfd, symtab_hdr->sh_link,
+ sym->st_name));
+ sym_value = sym->st_value;
+ hash = NULL;
+ }
+ else
+ {
+ /* It's an external symbol. */
+ int e_indx;
+
+ e_indx = r_indx - symtab_hdr->sh_info;
+ hash = (struct elf_link_hash_entry *)
+ (sym_hashes[e_indx]);
+
+ while (hash->root.type == bfd_link_hash_indirect
+ || hash->root.type == bfd_link_hash_warning)
+ hash = ((struct elf_link_hash_entry *)
+ hash->root.u.i.link);
+
+ if (hash->root.type == bfd_link_hash_defined
+ || hash->root.type == bfd_link_hash_defweak
+ || hash->root.type == bfd_link_hash_new)
+ {
+ if (!(hash->other & STO_M68HC12_FAR))
+ continue;
+ }
+ else if (hash->root.type == bfd_link_hash_undefweak)
+ {
+ continue;
+ }
+ else if (hash->root.type == bfd_link_hash_undefined)
+ {
+ continue;
+ }
+ else
+ {
+ bfd_set_error (bfd_error_bad_value);
+ goto error_ret_free_internal;
+ }
+ sym_sec = hash->root.u.def.section;
+ sym_value = hash->root.u.def.value;
+ stub_name = hash->root.root.string;
+ }
+
+ if (!stub_name)
+ goto error_ret_free_internal;
+
+ stub_entry = m68hc12_stub_hash_lookup
+ (htab->stub_hash_table,
+ stub_name,
+ FALSE, FALSE);
+ if (stub_entry == NULL)
+ {
+ if (add_stub_section == 0)
+ continue;
+
+ stub_entry = m68hc12_add_stub (stub_name, section, htab);
+ if (stub_entry == NULL)
+ {
+ error_ret_free_internal:
+ if (elf_section_data (section)->relocs == NULL)
+ free (internal_relocs);
+ goto error_ret_free_local;
+ }
+ }
+
+ stub_entry->target_value = sym_value;
+ stub_entry->target_section = sym_sec;
+ }
+
+ /* We're done with the internal relocs, free them. */
+ if (elf_section_data (section)->relocs == NULL)
+ free (internal_relocs);
+ }
+ }
+
+ if (add_stub_section)
+ {
+ /* OK, we've added some stubs. Find out the new size of the
+ stub sections. */
+ for (stub_sec = htab->stub_bfd->sections;
+ stub_sec != NULL;
+ stub_sec = stub_sec->next)
+ {
+ stub_sec->size = 0;
+ }
+
+ bfd_hash_traverse (htab->stub_hash_table, htab->size_one_stub, htab);
+ }
+ free (all_local_syms);
+ return TRUE;
+
+ error_ret_free_local:
+ free (all_local_syms);
+ return FALSE;
+}
+
+/* Export the trampoline addresses in the symbol table. */
+static bfd_boolean
+m68hc11_elf_export_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
+{
+ struct bfd_link_info *info;
+ struct m68hc11_elf_link_hash_table *htab;
+ struct elf32_m68hc11_stub_hash_entry *stub_entry;
+ char* name;
+ bfd_boolean result;
+
+ info = (struct bfd_link_info *) in_arg;
+ htab = m68hc11_elf_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ /* Massage our args to the form they really have. */
+ stub_entry = (struct elf32_m68hc11_stub_hash_entry *) gen_entry;
+
+ /* Generate the trampoline according to HC11 or HC12. */
+ result = (* htab->build_one_stub) (gen_entry, in_arg);
+
+ /* Make a printable name that does not conflict with the real function. */
+ name = alloca (strlen (stub_entry->root.string) + 16);
+ sprintf (name, "tramp.%s", stub_entry->root.string);
+
+ /* Export the symbol for debugging/disassembling. */
+ m68hc11_elf_set_symbol (htab->stub_bfd, info, name,
+ stub_entry->stub_offset,
+ stub_entry->stub_sec);
+ return result;
+}
+
+/* Export a symbol or set its value and section. */
+static void
+m68hc11_elf_set_symbol (bfd *abfd, struct bfd_link_info *info,
+ const char *name, bfd_vma value, asection *sec)
+{
+ struct elf_link_hash_entry *h;
+
+ h = (struct elf_link_hash_entry *)
+ bfd_link_hash_lookup (info->hash, name, FALSE, FALSE, FALSE);
+ if (h == NULL)
+ {
+ _bfd_generic_link_add_one_symbol (info, abfd,
+ name,
+ BSF_GLOBAL,
+ sec,
+ value,
+ (const char*) NULL,
+ TRUE, FALSE, NULL);
+ }
+ else
+ {
+ h->root.type = bfd_link_hash_defined;
+ h->root.u.def.value = value;
+ h->root.u.def.section = sec;
+ }
+}
+
+
+/* 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 function is called via m68hc12elf_finish in the
+ linker. */
+
+bfd_boolean
+elf32_m68hc11_build_stubs (bfd *abfd, struct bfd_link_info *info)
+{
+ asection *stub_sec;
+ struct bfd_hash_table *table;
+ struct m68hc11_elf_link_hash_table *htab;
+ struct m68hc11_scan_param param;
+
+ m68hc11_elf_get_bank_parameters (info);
+ htab = m68hc11_elf_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ for (stub_sec = htab->stub_bfd->sections;
+ stub_sec != NULL;
+ stub_sec = stub_sec->next)
+ {
+ bfd_size_type size;
+
+ /* Allocate memory to hold the linker stubs. */
+ size = stub_sec->size;
+ stub_sec->contents = (unsigned char *) bfd_zalloc (htab->stub_bfd, size);
+ if (stub_sec->contents == NULL && size != 0)
+ return FALSE;
+ stub_sec->size = 0;
+ }
+
+ /* Build the stubs as directed by the stub hash table. */
+ table = htab->stub_hash_table;
+ bfd_hash_traverse (table, m68hc11_elf_export_one_stub, info);
+
+ /* Scan the output sections to see if we use the memory banks.
+ If so, export the symbols that define how the memory banks
+ are mapped. This is used by gdb and the simulator to obtain
+ the information. It can be used by programs to burn the eprom
+ at the good addresses. */
+ param.use_memory_banks = FALSE;
+ param.pinfo = &htab->pinfo;
+ bfd_map_over_sections (abfd, scan_sections_for_abi, &param);
+ if (param.use_memory_banks)
+ {
+ m68hc11_elf_set_symbol (abfd, info, BFD_M68HC11_BANK_START_NAME,
+ htab->pinfo.bank_physical,
+ bfd_abs_section_ptr);
+ m68hc11_elf_set_symbol (abfd, info, BFD_M68HC11_BANK_VIRTUAL_NAME,
+ htab->pinfo.bank_virtual,
+ bfd_abs_section_ptr);
+ m68hc11_elf_set_symbol (abfd, info, BFD_M68HC11_BANK_SIZE_NAME,
+ htab->pinfo.bank_size,
+ bfd_abs_section_ptr);
+ }
+
+ return TRUE;
+}
+
+void
+m68hc11_elf_get_bank_parameters (struct bfd_link_info *info)
+{
+ unsigned i;
+ struct m68hc11_page_info *pinfo;
+ struct bfd_link_hash_entry *h;
+ struct m68hc11_elf_link_hash_table *htab;
+
+ htab = m68hc11_elf_hash_table (info);
+ if (htab == NULL)
+ return;
+
+ pinfo = & htab->pinfo;
+ if (pinfo->bank_param_initialized)
+ return;
+
+ pinfo->bank_virtual = M68HC12_BANK_VIRT;
+ pinfo->bank_mask = M68HC12_BANK_MASK;
+ pinfo->bank_physical = M68HC12_BANK_BASE;
+ pinfo->bank_shift = M68HC12_BANK_SHIFT;
+ pinfo->bank_size = 1 << M68HC12_BANK_SHIFT;
+
+ h = bfd_link_hash_lookup (info->hash, BFD_M68HC11_BANK_START_NAME,
+ FALSE, FALSE, TRUE);
+ if (h != (struct bfd_link_hash_entry*) NULL
+ && h->type == bfd_link_hash_defined)
+ pinfo->bank_physical = (h->u.def.value
+ + h->u.def.section->output_section->vma
+ + h->u.def.section->output_offset);
+
+ h = bfd_link_hash_lookup (info->hash, BFD_M68HC11_BANK_VIRTUAL_NAME,
+ FALSE, FALSE, TRUE);
+ if (h != (struct bfd_link_hash_entry*) NULL
+ && h->type == bfd_link_hash_defined)
+ pinfo->bank_virtual = (h->u.def.value
+ + h->u.def.section->output_section->vma
+ + h->u.def.section->output_offset);
+
+ h = bfd_link_hash_lookup (info->hash, BFD_M68HC11_BANK_SIZE_NAME,
+ FALSE, FALSE, TRUE);
+ if (h != (struct bfd_link_hash_entry*) NULL
+ && h->type == bfd_link_hash_defined)
+ pinfo->bank_size = (h->u.def.value
+ + h->u.def.section->output_section->vma
+ + h->u.def.section->output_offset);
+
+ pinfo->bank_shift = 0;
+ for (i = pinfo->bank_size; i != 0; i >>= 1)
+ pinfo->bank_shift++;
+ pinfo->bank_shift--;
+ pinfo->bank_mask = (1 << pinfo->bank_shift) - 1;
+ pinfo->bank_physical_end = pinfo->bank_physical + pinfo->bank_size;
+ pinfo->bank_param_initialized = 1;
+
+ h = bfd_link_hash_lookup (info->hash, "__far_trampoline", FALSE,
+ FALSE, TRUE);
+ if (h != (struct bfd_link_hash_entry*) NULL
+ && h->type == bfd_link_hash_defined)
+ pinfo->trampoline_addr = (h->u.def.value
+ + h->u.def.section->output_section->vma
+ + h->u.def.section->output_offset);
+}
+
+/* Return 1 if the address is in banked memory.
+ This can be applied to a virtual address and to a physical address. */
+int
+m68hc11_addr_is_banked (struct m68hc11_page_info *pinfo, bfd_vma addr)
+{
+ if (addr >= pinfo->bank_virtual)
+ return 1;
+
+ if (addr >= pinfo->bank_physical && addr <= pinfo->bank_physical_end)
+ return 1;
+
+ return 0;
+}
+
+/* Return the physical address seen by the processor, taking
+ into account banked memory. */
+bfd_vma
+m68hc11_phys_addr (struct m68hc11_page_info *pinfo, bfd_vma addr)
+{
+ if (addr < pinfo->bank_virtual)
+ return addr;
+
+ /* Map the address to the memory bank. */
+ addr -= pinfo->bank_virtual;
+ addr &= pinfo->bank_mask;
+ addr += pinfo->bank_physical;
+ return addr;
+}
+
+/* Return the page number corresponding to an address in banked memory. */
+bfd_vma
+m68hc11_phys_page (struct m68hc11_page_info *pinfo, bfd_vma addr)
+{
+ if (addr < pinfo->bank_virtual)
+ return 0;
+
+ /* Map the address to the memory bank. */
+ addr -= pinfo->bank_virtual;
+ addr >>= pinfo->bank_shift;
+ addr &= 0x0ff;
+ return addr;
+}
+
+/* This function is used for relocs which are only used for relaxing,
+ which the linker should otherwise ignore. */
+
+bfd_reloc_status_type
+m68hc11_elf_ignore_reloc (bfd *abfd ATTRIBUTE_UNUSED,
+ arelent *reloc_entry,
+ asymbol *symbol ATTRIBUTE_UNUSED,
+ void *data ATTRIBUTE_UNUSED,
+ asection *input_section,
+ bfd *output_bfd,
+ char **error_message ATTRIBUTE_UNUSED)
+{
+ if (output_bfd != NULL)
+ reloc_entry->address += input_section->output_offset;
+ return bfd_reloc_ok;
+}
+
+bfd_reloc_status_type
+m68hc11_elf_special_reloc (bfd *abfd ATTRIBUTE_UNUSED,
+ arelent *reloc_entry,
+ asymbol *symbol,
+ void *data ATTRIBUTE_UNUSED,
+ asection *input_section,
+ bfd *output_bfd,
+ char **error_message ATTRIBUTE_UNUSED)
+{
+ 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 > bfd_get_section_limit (abfd, input_section))
+ return bfd_reloc_outofrange;
+
+ abort();
+}
+
+/* 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. */
+
+bfd_boolean
+elf32_m68hc11_check_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;
+ const Elf_Internal_Rela * rel;
+ const Elf_Internal_Rela * rel_end;
+
+ if (info->relocatable)
+ return TRUE;
+
+ symtab_hdr = & elf_tdata (abfd)->symtab_hdr;
+ sym_hashes = elf_sym_hashes (abfd);
+ 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];
+ 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;
+
+ /* PR15323, ref flags aren't set for references in the same
+ object. */
+ h->root.non_ir_ref = 1;
+ }
+
+ switch (ELF32_R_TYPE (rel->r_info))
+ {
+ /* This relocation describes the C++ object vtable hierarchy.
+ Reconstruct it for later use during GC. */
+ case R_M68HC11_GNU_VTINHERIT:
+ if (!bfd_elf_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_M68HC11_GNU_VTENTRY:
+ BFD_ASSERT (h != NULL);
+ if (h != NULL
+ && !bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
+ return FALSE;
+ break;
+ }
+ }
+
+ return TRUE;
+}
+
+/* Relocate a 68hc11/68hc12 ELF section. */
+bfd_boolean
+elf32_m68hc11_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
+ 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 = NULL;
+ struct m68hc11_page_info *pinfo;
+ const struct elf_backend_data * const ebd = get_elf_backend_data (input_bfd);
+ struct m68hc11_elf_link_hash_table *htab;
+ unsigned long e_flags;
+
+ symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
+ sym_hashes = elf_sym_hashes (input_bfd);
+ e_flags = elf_elfheader (input_bfd)->e_flags;
+
+ htab = m68hc11_elf_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ /* Get memory bank parameters. */
+ m68hc11_elf_get_bank_parameters (info);
+
+ pinfo = & htab->pinfo;
+ rel = relocs;
+ relend = relocs + input_section->reloc_count;
+
+ for (; rel < relend; rel++)
+ {
+ int r_type;
+ arelent arel;
+ reloc_howto_type *howto;
+ unsigned long r_symndx;
+ Elf_Internal_Sym *sym;
+ asection *sec;
+ bfd_vma relocation = 0;
+ bfd_reloc_status_type r = bfd_reloc_undefined;
+ bfd_vma phys_page;
+ bfd_vma phys_addr;
+ bfd_vma insn_addr;
+ bfd_vma insn_page;
+ bfd_boolean is_far = FALSE;
+ bfd_boolean is_xgate_symbol = FALSE;
+ bfd_boolean is_section_symbol = FALSE;
+ struct elf_link_hash_entry *h;
+ bfd_vma val;
+
+ r_symndx = ELF32_R_SYM (rel->r_info);
+ r_type = ELF32_R_TYPE (rel->r_info);
+
+ if (r_type == R_M68HC11_GNU_VTENTRY
+ || r_type == R_M68HC11_GNU_VTINHERIT)
+ continue;
+
+ (*ebd->elf_info_to_howto_rel) (input_bfd, &arel, rel);
+ howto = arel.howto;
+
+ 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);
+ is_far = (sym && (sym->st_other & STO_M68HC12_FAR));
+ is_xgate_symbol = (sym && (sym->st_target_internal));
+ is_section_symbol = ELF_ST_TYPE (sym->st_info) & STT_SECTION;
+ }
+ else
+ {
+ bfd_boolean unresolved_reloc, warned, ignored;
+
+ RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
+ r_symndx, symtab_hdr, sym_hashes,
+ h, sec, relocation, unresolved_reloc,
+ warned, ignored);
+
+ is_far = (h && (h->other & STO_M68HC12_FAR));
+ is_xgate_symbol = (h && (h->target_internal));
+ }
+
+ if (sec != NULL && discarded_section (sec))
+ RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+ rel, 1, relend, howto, 0, contents);
+
+ if (info->relocatable)
+ {
+ /* This is a relocatable 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 (sym != NULL && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
+ rel->r_addend += sec->output_offset;
+ continue;
+ }
+
+ 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 (is_far && ELF32_R_TYPE (rel->r_info) == R_M68HC11_16)
+ {
+ struct elf32_m68hc11_stub_hash_entry* stub;
+
+ stub = m68hc12_stub_hash_lookup (htab->stub_hash_table,
+ name, FALSE, FALSE);
+ if (stub)
+ {
+ relocation = stub->stub_offset
+ + stub->stub_sec->output_section->vma
+ + stub->stub_sec->output_offset;
+ is_far = FALSE;
+ }
+ }
+
+ /* Do the memory bank mapping. */
+ phys_addr = m68hc11_phys_addr (pinfo, relocation + rel->r_addend);
+ phys_page = m68hc11_phys_page (pinfo, relocation + rel->r_addend);
+ switch (r_type)
+ {
+ case R_M68HC12_LO8XG:
+ /* This relocation is specific to XGATE IMM16 calls and will precede
+ a HI8. tc-m68hc11 only generates them in pairs.
+ Leave the relocation to the HI8XG step. */
+ r = bfd_reloc_ok;
+ r_type = R_M68HC11_NONE;
+ break;
+
+ case R_M68HC12_HI8XG:
+ /* This relocation is specific to XGATE IMM16 calls and must follow
+ a LO8XG. Does not actually check that it was a LO8XG.
+ Adjusts high and low bytes. */
+ relocation = phys_addr;
+ if ((e_flags & E_M68HC11_XGATE_RAMOFFSET)
+ && (relocation >= 0x2000))
+ relocation += 0xc000; /* HARDCODED RAM offset for XGATE. */
+
+ /* Fetch 16 bit value including low byte in previous insn. */
+ val = (bfd_get_8 (input_bfd, (bfd_byte*) contents + rel->r_offset) << 8)
+ | bfd_get_8 (input_bfd, (bfd_byte*) contents + rel->r_offset - 2);
+
+ /* Add on value to preserve carry, then write zero to high byte. */
+ relocation += val;
+
+ /* Write out top byte. */
+ bfd_put_8 (input_bfd, (relocation >> 8) & 0xff,
+ (bfd_byte*) contents + rel->r_offset);
+
+ /* Write out low byte to previous instruction. */
+ bfd_put_8 (input_bfd, relocation & 0xff,
+ (bfd_byte*) contents + rel->r_offset - 2);
+
+ /* Mark as relocation completed. */
+ r = bfd_reloc_ok;
+ r_type = R_M68HC11_NONE;
+ break;
+
+ /* The HI8 and LO8 relocs are generated by %hi(expr) %lo(expr)
+ assembler directives. %hi does not support carry. */
+ case R_M68HC11_HI8:
+ case R_M68HC11_LO8:
+ relocation = phys_addr;
+ break;
+
+ case R_M68HC11_24:
+ /* Reloc used by 68HC12 call instruction. */
+ bfd_put_16 (input_bfd, phys_addr,
+ (bfd_byte*) contents + rel->r_offset);
+ bfd_put_8 (input_bfd, phys_page,
+ (bfd_byte*) contents + rel->r_offset + 2);
+ r = bfd_reloc_ok;
+ r_type = R_M68HC11_NONE;
+ break;
+
+ case R_M68HC11_NONE:
+ r = bfd_reloc_ok;
+ break;
+
+ case R_M68HC11_LO16:
+ /* Reloc generated by %addr(expr) gas to obtain the
+ address as mapped in the memory bank window. */
+ relocation = phys_addr;
+ break;
+
+ case R_M68HC11_PAGE:
+ /* Reloc generated by %page(expr) gas to obtain the
+ page number associated with the address. */
+ relocation = phys_page;
+ break;
+
+ case R_M68HC11_16:
+ /* Get virtual address of instruction having the relocation. */
+ if (is_far)
+ {
+ const char* msg;
+ char* buf;
+ msg = _("Reference to the far symbol `%s' using a wrong "
+ "relocation may result in incorrect execution");
+ buf = alloca (strlen (msg) + strlen (name) + 10);
+ sprintf (buf, msg, name);
+
+ (* info->callbacks->warning)
+ (info, buf, name, input_bfd, NULL, rel->r_offset);
+ }
+
+ /* Get virtual address of instruction having the relocation. */
+ insn_addr = input_section->output_section->vma
+ + input_section->output_offset
+ + rel->r_offset;
+
+ insn_page = m68hc11_phys_page (pinfo, insn_addr);
+
+ /* If we are linking an S12 instruction against an XGATE symbol, we
+ need to change the offset of the symbol value so that it's correct
+ from the S12's perspective. */
+ if (is_xgate_symbol)
+ {
+ /* The ram in the global space is mapped to 0x2000 in the 16-bit
+ address space for S12 and 0xE000 in the 16-bit address space
+ for XGATE. */
+ if (relocation >= 0xE000)
+ {
+ /* We offset the address by the difference
+ between these two mappings. */
+ relocation -= 0xC000;
+ break;
+ }
+ else
+ {
+ const char * msg;
+ char * buf;
+
+ msg = _("XGATE address (%lx) is not within shared RAM"
+ "(0xE000-0xFFFF), therefore you must manually offset "
+ "the address, and possibly manage the page, in your "
+ "code.");
+ buf = alloca (strlen (msg) + 128);
+ sprintf (buf, msg, phys_addr);
+ if (!((*info->callbacks->warning) (info, buf, name, input_bfd,
+ input_section, insn_addr)))
+ return FALSE;
+ break;
+ }
+ }
+
+ if (m68hc11_addr_is_banked (pinfo, relocation + rel->r_addend)
+ && m68hc11_addr_is_banked (pinfo, insn_addr)
+ && phys_page != insn_page && !(e_flags & E_M68HC11_NO_BANK_WARNING))
+ {
+ const char * msg;
+ char * buf;
+
+ msg = _("banked address [%lx:%04lx] (%lx) is not in the same bank "
+ "as current banked address [%lx:%04lx] (%lx)");
+
+ buf = alloca (strlen (msg) + 128);
+ sprintf (buf, msg, phys_page, phys_addr,
+ (long) (relocation + rel->r_addend),
+ insn_page, m68hc11_phys_addr (pinfo, insn_addr),
+ (long) (insn_addr));
+ if (!((*info->callbacks->warning)
+ (info, buf, name, input_bfd, input_section,
+ rel->r_offset)))
+ return FALSE;
+ break;
+ }
+
+ if (phys_page != 0 && insn_page == 0)
+ {
+ const char * msg;
+ char * buf;
+
+ msg = _("reference to a banked address [%lx:%04lx] in the "
+ "normal address space at %04lx");
+
+ buf = alloca (strlen (msg) + 128);
+ sprintf (buf, msg, phys_page, phys_addr, insn_addr);
+ if (!((*info->callbacks->warning)
+ (info, buf, name, input_bfd, input_section,
+ insn_addr)))
+ return FALSE;
+
+ relocation = phys_addr;
+ break;
+ }
+
+ /* If this is a banked address use the phys_addr so that
+ we stay in the banked window. */
+ if (m68hc11_addr_is_banked (pinfo, relocation + rel->r_addend))
+ relocation = phys_addr;
+ break;
+ }
+
+ /* If we are linking an XGATE instruction against an S12 symbol, we
+ need to change the offset of the symbol value so that it's correct
+ from the XGATE's perspective. */
+ if (!strcmp (howto->name, "R_XGATE_IMM8_LO")
+ || !strcmp (howto->name, "R_XGATE_IMM8_HI"))
+ {
+ /* We can only offset S12 addresses that lie within the non-paged
+ area of RAM. */
+ if (!is_xgate_symbol && !is_section_symbol)
+ {
+ /* The ram in the global space is mapped to 0x2000 and stops at
+ 0x4000 in the 16-bit address space for S12 and 0xE000 in the
+ 16-bit address space for XGATE. */
+ if (relocation >= 0x2000 && relocation < 0x4000)
+ /* We offset the address by the difference
+ between these two mappings. */
+ relocation += 0xC000;
+ else
+ {
+ const char * msg;
+ char * buf;
+
+ /* Get virtual address of instruction having the relocation. */
+ insn_addr = input_section->output_section->vma
+ + input_section->output_offset + rel->r_offset;
+
+ msg = _("S12 address (%lx) is not within shared RAM"
+ "(0x2000-0x4000), therefore you must manually "
+ "offset the address in your code");
+ buf = alloca (strlen (msg) + 128);
+ sprintf (buf, msg, phys_addr);
+ if (!((*info->callbacks->warning) (info, buf, name, input_bfd,
+ input_section, insn_addr)))
+ return FALSE;
+ break;
+ }
+ }
+ }
+
+ if (r_type != R_M68HC11_NONE)
+ {
+ if ((r_type == R_M68HC12_PCREL_9) || (r_type == R_M68HC12_PCREL_10))
+ r = _bfd_final_link_relocate (howto, input_bfd, input_section,
+ contents, rel->r_offset,
+ relocation - 2, rel->r_addend);
+ else
+ 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, NULL, 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, TRUE)))
+ 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;
+}
+
+
+
+/* Set and control ELF flags in ELF header. */
+
+bfd_boolean
+_bfd_m68hc11_elf_set_private_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;
+}
+
+/* Merge backend specific data from an object file to the output
+ object file when linking. */
+
+bfd_boolean
+_bfd_m68hc11_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
+{
+ flagword old_flags;
+ flagword new_flags;
+ bfd_boolean ok = TRUE;
+
+ /* Check if we have the same endianness */
+ if (!_bfd_generic_verify_endian_match (ibfd, obfd))
+ 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_M68HC11_ABI;
+ old_flags = elf_elfheader (obfd)->e_flags;
+
+ if (! elf_flags_init (obfd))
+ {
+ elf_flags_init (obfd) = TRUE;
+ elf_elfheader (obfd)->e_flags = new_flags;
+ elf_elfheader (obfd)->e_ident[EI_CLASS]
+ = elf_elfheader (ibfd)->e_ident[EI_CLASS];
+
+ 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 ABI compatibility. */
+ if ((new_flags & E_M68HC11_I32) != (old_flags & E_M68HC11_I32))
+ {
+ (*_bfd_error_handler)
+ (_("%B: linking files compiled for 16-bit integers (-mshort) "
+ "and others for 32-bit integers"), ibfd);
+ ok = FALSE;
+ }
+ if ((new_flags & E_M68HC11_F64) != (old_flags & E_M68HC11_F64))
+ {
+ (*_bfd_error_handler)
+ (_("%B: linking files compiled for 32-bit double (-fshort-double) "
+ "and others for 64-bit double"), ibfd);
+ ok = FALSE;
+ }
+
+ /* Processor compatibility. */
+ if (!EF_M68HC11_CAN_MERGE_MACH (new_flags, old_flags))
+ {
+ (*_bfd_error_handler)
+ (_("%B: linking files compiled for HCS12 with "
+ "others compiled for HC12"), ibfd);
+ ok = FALSE;
+ }
+ new_flags = ((new_flags & ~EF_M68HC11_MACH_MASK)
+ | (EF_M68HC11_MERGE_MACH (new_flags, old_flags)));
+
+ elf_elfheader (obfd)->e_flags = new_flags;
+
+ new_flags &= ~(EF_M68HC11_ABI | EF_M68HC11_MACH_MASK);
+ old_flags &= ~(EF_M68HC11_ABI | EF_M68HC11_MACH_MASK);
+
+ /* Warn about any other mismatches */
+ if (new_flags != old_flags)
+ {
+ (*_bfd_error_handler)
+ (_("%B: uses different e_flags (0x%lx) fields than previous modules (0x%lx)"),
+ ibfd, (unsigned long) new_flags, (unsigned long) old_flags);
+ ok = FALSE;
+ }
+
+ if (! ok)
+ {
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+bfd_boolean
+_bfd_m68hc11_elf_print_private_bfd_data (bfd *abfd, void *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 & E_M68HC11_I32)
+ fprintf (file, _("[abi=32-bit int, "));
+ else
+ fprintf (file, _("[abi=16-bit int, "));
+
+ if (elf_elfheader (abfd)->e_flags & E_M68HC11_F64)
+ fprintf (file, _("64-bit double, "));
+ else
+ fprintf (file, _("32-bit double, "));
+
+ if (strcmp (bfd_get_target (abfd), "elf32-m68hc11") == 0)
+ fprintf (file, _("cpu=HC11]"));
+ else if (elf_elfheader (abfd)->e_flags & EF_M68HCS12_MACH)
+ fprintf (file, _("cpu=HCS12]"));
+ else
+ fprintf (file, _("cpu=HC12]"));
+
+ if (elf_elfheader (abfd)->e_flags & E_M68HC12_BANKS)
+ fprintf (file, _(" [memory=bank-model]"));
+ else
+ fprintf (file, _(" [memory=flat]"));
+
+ if (elf_elfheader (abfd)->e_flags & E_M68HC11_XGATE_RAMOFFSET)
+ fprintf (file, _(" [XGATE RAM offsetting]"));
+
+ fputc ('\n', file);
+
+ return TRUE;
+}
+
+static void scan_sections_for_abi (bfd *abfd ATTRIBUTE_UNUSED,
+ asection *asect, void *arg)
+{
+ struct m68hc11_scan_param* p = (struct m68hc11_scan_param*) arg;
+
+ if (asect->vma >= p->pinfo->bank_virtual)
+ p->use_memory_banks = TRUE;
+}
+
+/* Tweak the OSABI field of the elf header. */
+
+void
+elf32_m68hc11_post_process_headers (bfd *abfd, struct bfd_link_info *link_info)
+{
+ struct m68hc11_scan_param param;
+ struct m68hc11_elf_link_hash_table *htab;
+
+ if (link_info == NULL)
+ return;
+
+ htab = m68hc11_elf_hash_table (link_info);
+ if (htab == NULL)
+ return;
+
+ m68hc11_elf_get_bank_parameters (link_info);
+
+ param.use_memory_banks = FALSE;
+ param.pinfo = & htab->pinfo;
+
+ bfd_map_over_sections (abfd, scan_sections_for_abi, &param);
+
+ if (param.use_memory_banks)
+ {
+ Elf_Internal_Ehdr * i_ehdrp;
+
+ i_ehdrp = elf_elfheader (abfd);
+ i_ehdrp->e_flags |= E_M68HC12_BANKS;
+ }
+}
diff --git a/bfd/elf32-m68hc1x.h b/bfd/elf32-m68hc1x.h
new file mode 100644
index 0000000..89ccd7f
--- /dev/null
+++ b/bfd/elf32-m68hc1x.h
@@ -0,0 +1,192 @@
+/* Motorola 68HC11/68HC12-specific support for 32-bit ELF
+ Copyright (C) 2003-2014 Free Software Foundation, Inc.
+ Contributed by Stephane Carrez (stcarrez@nerim.fr)
+
+ This file is part of BFD, the Binary File Descriptor library.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#ifndef _ELF32_M68HC1X_H
+#define _ELF32_M68HC1X_H
+
+#include "elf-bfd.h"
+#include "bfdlink.h"
+#include "elf/m68hc11.h"
+
+/* Name of symbols exported by HC11/HC12 linker when there is a memory
+ bank window. */
+#define BFD_M68HC11_BANK_START_NAME "__bank_start"
+#define BFD_M68HC11_BANK_SIZE_NAME "__bank_size"
+#define BFD_M68HC11_BANK_VIRTUAL_NAME "__bank_virtual"
+
+/* Set and control ELF flags in ELF header. */
+extern bfd_boolean _bfd_m68hc11_elf_merge_private_bfd_data (bfd*,bfd*);
+extern bfd_boolean _bfd_m68hc11_elf_set_private_flags (bfd*,flagword);
+extern bfd_boolean _bfd_m68hc11_elf_print_private_bfd_data (bfd*, void*);
+
+/* This hash entry is used to record a trampoline that must be generated
+ to call a far function using a normal calling convention ('jsr').
+ The trampoline is used when a pointer to a far function is used.
+ It takes care of installing the proper memory bank as well as creating
+ the 'call/rtc' calling convention. */
+struct elf32_m68hc11_stub_hash_entry
+{
+ /* Base hash table entry structure. */
+ struct bfd_hash_entry root;
+
+ /* The stub section. */
+ asection *stub_sec;
+
+ /* Offset within stub_sec of the beginning of this stub. */
+ bfd_vma stub_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. */
+ bfd_vma target_value;
+ asection *target_section;
+};
+
+/* Placeholder for the parameters to compute memory page and physical address.
+ The following formulas are used:
+
+ sym > bank_virtual =>
+ %addr(sym) = (((sym - bank_virtual) & bank_mask) + bank_physical
+ %page(sym) = (((sym - bank_virtual) >> bank_shift) % 256
+
+ sym < bank_virtual =>
+ %addr(sym) = sym
+ %page(sym) = 0
+
+
+ These parameters are obtained from the symbol table by looking
+ at the following:
+
+ __bank_start Symbol marking the start of memory bank window
+ (bank_physical)
+ __bank_virtual Logical address of symbols for which the transformation
+ must be computed
+ __bank_page_size Size in bytes of page size (this is *NOT* the memory
+ bank window size and the window size is always
+ less or equal to the page size)
+
+ For 68HC12, the window is at 0x8000 and the page size is 16K (full window).
+ For 68HC11 this is board specific (implemented by external hardware). */
+
+struct m68hc11_page_info
+{
+ bfd_vma bank_virtual;
+ bfd_vma bank_physical;
+ bfd_vma bank_physical_end;
+ bfd_vma bank_mask;
+ bfd_vma bank_size;
+ int bank_shift;
+ int bank_param_initialized;
+ bfd_vma trampoline_addr;
+};
+
+struct m68hc11_elf_link_hash_table
+{
+ struct elf_link_hash_table root;
+ struct m68hc11_page_info pinfo;
+
+ /* The stub hash table. */
+ struct bfd_hash_table* stub_hash_table;
+
+ /* Linker stub bfd. */
+ bfd *stub_bfd;
+
+ asection* stub_section;
+ asection* tramp_section;
+
+ /* Linker call-backs. */
+ asection * (*add_stub_section) (const char *, asection *);
+
+ /* Assorted information used by elf32_hppa_size_stubs. */
+ unsigned int bfd_count;
+ int top_index;
+ asection **input_list;
+
+ /* Small local sym cache. */
+ struct sym_cache sym_cache;
+
+ bfd_boolean (* size_one_stub) (struct bfd_hash_entry*, void*);
+ bfd_boolean (* build_one_stub) (struct bfd_hash_entry*, void*);
+};
+
+/* Get the Sparc64 ELF linker hash table from a link_info structure. */
+
+#define m68hc11_elf_hash_table(p) \
+ (elf_hash_table_id ((struct elf_link_hash_table *) ((p)->hash)) \
+ == M68HC11_ELF_DATA ? ((struct m68hc11_elf_link_hash_table *) ((p)->hash)) : NULL)
+
+/* Create a 68HC11/68HC12 ELF linker hash table. */
+
+extern struct m68hc11_elf_link_hash_table* m68hc11_elf_hash_table_create
+ (bfd*);
+
+extern void m68hc11_elf_get_bank_parameters (struct bfd_link_info*);
+
+/* Return 1 if the address is in banked memory.
+ This can be applied to a virtual address and to a physical address. */
+extern int m68hc11_addr_is_banked (struct m68hc11_page_info*, bfd_vma);
+
+/* Return the physical address seen by the processor, taking
+ into account banked memory. */
+extern bfd_vma m68hc11_phys_addr (struct m68hc11_page_info*, bfd_vma);
+
+/* Return the page number corresponding to an address in banked memory. */
+extern bfd_vma m68hc11_phys_page (struct m68hc11_page_info*, bfd_vma);
+
+bfd_reloc_status_type m68hc11_elf_ignore_reloc
+ (bfd *abfd, arelent *reloc_entry,
+ asymbol *symbol, void *data, asection *input_section,
+ bfd *output_bfd, char **error_message);
+bfd_reloc_status_type m68hc11_elf_special_reloc
+ (bfd *abfd, arelent *reloc_entry,
+ asymbol *symbol, void *data, asection *input_section,
+ bfd *output_bfd, char **error_message);
+
+bfd_boolean elf32_m68hc11_check_relocs
+ (bfd * abfd, struct bfd_link_info * info,
+ asection * sec, const Elf_Internal_Rela * relocs);
+bfd_boolean elf32_m68hc11_relocate_section
+ (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_boolean elf32_m68hc11_add_symbol_hook
+ (bfd *abfd, struct bfd_link_info *info,
+ Elf_Internal_Sym *sym, const char **namep,
+ flagword *flagsp, asection **secp,
+ bfd_vma *valp);
+
+void elf32_m68hc11_merge_symbol_attribute
+ (struct elf_link_hash_entry *, const Elf_Internal_Sym *,
+ bfd_boolean, bfd_boolean);
+
+/* Tweak the OSABI field of the elf header. */
+
+extern void elf32_m68hc11_post_process_headers (bfd*, struct bfd_link_info*);
+
+int elf32_m68hc11_setup_section_lists (bfd *, struct bfd_link_info *);
+
+bfd_boolean elf32_m68hc11_size_stubs
+ (bfd *, bfd *, struct bfd_link_info *,
+ asection * (*) (const char *, asection *));
+
+bfd_boolean elf32_m68hc11_build_stubs (bfd* abfd, struct bfd_link_info *);
+#endif
diff --git a/bfd/elf32-m68k.c b/bfd/elf32-m68k.c
new file mode 100644
index 0000000..0058da4
--- /dev/null
+++ b/bfd/elf32-m68k.c
@@ -0,0 +1,4902 @@
+/* Motorola 68k series support for 32-bit ELF
+ Copyright (C) 1993-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "bfdlink.h"
+#include "libbfd.h"
+#include "elf-bfd.h"
+#include "elf/m68k.h"
+#include "opcode/m68k.h"
+
+static bfd_boolean
+elf_m68k_discard_copies (struct elf_link_hash_entry *, void *);
+
+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),
+
+ /* TLS general dynamic variable reference. */
+ HOWTO (R_68K_TLS_GD32, /* 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_68K_TLS_GD32", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_68K_TLS_GD16, /* 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_68K_TLS_GD16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_68K_TLS_GD8, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 8, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_68K_TLS_GD8", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x000000ff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* TLS local dynamic variable reference. */
+ HOWTO (R_68K_TLS_LDM32, /* 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_68K_TLS_LDM32", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_68K_TLS_LDM16, /* 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_68K_TLS_LDM16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_68K_TLS_LDM8, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 8, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_68K_TLS_LDM8", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x000000ff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_68K_TLS_LDO32, /* 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_68K_TLS_LDO32", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_68K_TLS_LDO16, /* 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_68K_TLS_LDO16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_68K_TLS_LDO8, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 8, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_68K_TLS_LDO8", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x000000ff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* TLS initial execution variable reference. */
+ HOWTO (R_68K_TLS_IE32, /* 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_68K_TLS_IE32", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_68K_TLS_IE16, /* 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_68K_TLS_IE16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_68K_TLS_IE8, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 8, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_68K_TLS_IE8", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x000000ff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* TLS local execution variable reference. */
+ HOWTO (R_68K_TLS_LE32, /* 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_68K_TLS_LE32", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_68K_TLS_LE16, /* 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_68K_TLS_LE16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_68K_TLS_LE8, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 8, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_68K_TLS_LE8", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x000000ff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* TLS GD/LD dynamic relocations. */
+ HOWTO (R_68K_TLS_DTPMOD32, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_68K_TLS_DTPMOD32", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_68K_TLS_DTPREL32, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_68K_TLS_DTPREL32", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_68K_TLS_TPREL32, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_68K_TLS_TPREL32", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+};
+
+static void
+rtype_to_howto (bfd *abfd, arelent *cache_ptr, Elf_Internal_Rela *dst)
+{
+ unsigned int indx = ELF32_R_TYPE (dst->r_info);
+
+ if (indx >= (unsigned int) R_68K_max)
+ {
+ (*_bfd_error_handler) (_("%B: invalid relocation type %d"),
+ abfd, (int) indx);
+ indx = R_68K_NONE;
+ }
+ cache_ptr->howto = &howto_table[indx];
+}
+
+#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 },
+ { BFD_RELOC_68K_TLS_GD32, R_68K_TLS_GD32 },
+ { BFD_RELOC_68K_TLS_GD16, R_68K_TLS_GD16 },
+ { BFD_RELOC_68K_TLS_GD8, R_68K_TLS_GD8 },
+ { BFD_RELOC_68K_TLS_LDM32, R_68K_TLS_LDM32 },
+ { BFD_RELOC_68K_TLS_LDM16, R_68K_TLS_LDM16 },
+ { BFD_RELOC_68K_TLS_LDM8, R_68K_TLS_LDM8 },
+ { BFD_RELOC_68K_TLS_LDO32, R_68K_TLS_LDO32 },
+ { BFD_RELOC_68K_TLS_LDO16, R_68K_TLS_LDO16 },
+ { BFD_RELOC_68K_TLS_LDO8, R_68K_TLS_LDO8 },
+ { BFD_RELOC_68K_TLS_IE32, R_68K_TLS_IE32 },
+ { BFD_RELOC_68K_TLS_IE16, R_68K_TLS_IE16 },
+ { BFD_RELOC_68K_TLS_IE8, R_68K_TLS_IE8 },
+ { BFD_RELOC_68K_TLS_LE32, R_68K_TLS_LE32 },
+ { BFD_RELOC_68K_TLS_LE16, R_68K_TLS_LE16 },
+ { BFD_RELOC_68K_TLS_LE8, R_68K_TLS_LE8 },
+};
+
+static reloc_howto_type *
+reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ 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;
+}
+
+static reloc_howto_type *
+reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, const char *r_name)
+{
+ unsigned int i;
+
+ for (i = 0; i < sizeof (howto_table) / sizeof (howto_table[0]); i++)
+ if (howto_table[i].name != NULL
+ && strcasecmp (howto_table[i].name, r_name) == 0)
+ return &howto_table[i];
+
+ return NULL;
+}
+
+#define bfd_elf32_bfd_reloc_type_lookup reloc_type_lookup
+#define bfd_elf32_bfd_reloc_name_lookup reloc_name_lookup
+#define ELF_ARCH bfd_arch_m68k
+#define ELF_TARGET_ID M68K_ELF_DATA
+
+/* 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"
+
+/* Describes one of the various PLT styles. */
+
+struct elf_m68k_plt_info
+{
+ /* The size of each PLT entry. */
+ bfd_vma size;
+
+ /* The template for the first PLT entry. */
+ const bfd_byte *plt0_entry;
+
+ /* Offsets of fields in PLT0_ENTRY that require R_68K_PC32 relocations.
+ The comments by each member indicate the value that the relocation
+ is against. */
+ struct {
+ unsigned int got4; /* .got + 4 */
+ unsigned int got8; /* .got + 8 */
+ } plt0_relocs;
+
+ /* The template for a symbol's PLT entry. */
+ const bfd_byte *symbol_entry;
+
+ /* Offsets of fields in SYMBOL_ENTRY that require R_68K_PC32 relocations.
+ The comments by each member indicate the value that the relocation
+ is against. */
+ struct {
+ unsigned int got; /* the symbol's .got.plt entry */
+ unsigned int plt; /* .plt */
+ } symbol_relocs;
+
+ /* The offset of the resolver stub from the start of SYMBOL_ENTRY.
+ The stub starts with "move.l #relocoffset,%d0". */
+ bfd_vma symbol_resolve_entry;
+};
+
+/* 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, 2, /* + (.got + 4) - . */
+ 0x4e, 0xfb, 0x01, 0x71, /* jmp ([%pc,addr]) */
+ 0, 0, 0, 2, /* + (.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, 2, /* + (.got.plt entry) - . */
+ 0x2f, 0x3c, /* move.l #offset,-(%sp) */
+ 0, 0, 0, 0, /* + reloc index */
+ 0x60, 0xff, /* bra.l .plt */
+ 0, 0, 0, 0 /* + .plt - . */
+};
+
+static const struct elf_m68k_plt_info elf_m68k_plt_info = {
+ PLT_ENTRY_SIZE,
+ elf_m68k_plt0_entry, { 4, 12 },
+ elf_m68k_plt_entry, { 4, 16 }, 8
+};
+
+#define ISAB_PLT_ENTRY_SIZE 24
+
+static const bfd_byte elf_isab_plt0_entry[ISAB_PLT_ENTRY_SIZE] =
+{
+ 0x20, 0x3c, /* move.l #offset,%d0 */
+ 0, 0, 0, 0, /* + (.got + 4) - . */
+ 0x2f, 0x3b, 0x08, 0xfa, /* move.l (-6,%pc,%d0:l),-(%sp) */
+ 0x20, 0x3c, /* move.l #offset,%d0 */
+ 0, 0, 0, 0, /* + (.got + 8) - . */
+ 0x20, 0x7b, 0x08, 0xfa, /* move.l (-6,%pc,%d0:l), %a0 */
+ 0x4e, 0xd0, /* jmp (%a0) */
+ 0x4e, 0x71 /* nop */
+};
+
+/* Subsequent entries in a procedure linkage table look like this. */
+
+static const bfd_byte elf_isab_plt_entry[ISAB_PLT_ENTRY_SIZE] =
+{
+ 0x20, 0x3c, /* move.l #offset,%d0 */
+ 0, 0, 0, 0, /* + (.got.plt entry) - . */
+ 0x20, 0x7b, 0x08, 0xfa, /* move.l (-6,%pc,%d0:l), %a0 */
+ 0x4e, 0xd0, /* jmp (%a0) */
+ 0x2f, 0x3c, /* move.l #offset,-(%sp) */
+ 0, 0, 0, 0, /* + reloc index */
+ 0x60, 0xff, /* bra.l .plt */
+ 0, 0, 0, 0 /* + .plt - . */
+};
+
+static const struct elf_m68k_plt_info elf_isab_plt_info = {
+ ISAB_PLT_ENTRY_SIZE,
+ elf_isab_plt0_entry, { 2, 12 },
+ elf_isab_plt_entry, { 2, 20 }, 12
+};
+
+#define ISAC_PLT_ENTRY_SIZE 24
+
+static const bfd_byte elf_isac_plt0_entry[ISAC_PLT_ENTRY_SIZE] =
+{
+ 0x20, 0x3c, /* move.l #offset,%d0 */
+ 0, 0, 0, 0, /* replaced with .got + 4 - . */
+ 0x2e, 0xbb, 0x08, 0xfa, /* move.l (-6,%pc,%d0:l),(%sp) */
+ 0x20, 0x3c, /* move.l #offset,%d0 */
+ 0, 0, 0, 0, /* replaced with .got + 8 - . */
+ 0x20, 0x7b, 0x08, 0xfa, /* move.l (-6,%pc,%d0:l), %a0 */
+ 0x4e, 0xd0, /* jmp (%a0) */
+ 0x4e, 0x71 /* nop */
+};
+
+/* Subsequent entries in a procedure linkage table look like this. */
+
+static const bfd_byte elf_isac_plt_entry[ISAC_PLT_ENTRY_SIZE] =
+{
+ 0x20, 0x3c, /* move.l #offset,%d0 */
+ 0, 0, 0, 0, /* replaced with (.got entry) - . */
+ 0x20, 0x7b, 0x08, 0xfa, /* move.l (-6,%pc,%d0:l), %a0 */
+ 0x4e, 0xd0, /* jmp (%a0) */
+ 0x2f, 0x3c, /* move.l #offset,-(%sp) */
+ 0, 0, 0, 0, /* replaced with offset into relocation table */
+ 0x61, 0xff, /* bsr.l .plt */
+ 0, 0, 0, 0 /* replaced with .plt - . */
+};
+
+static const struct elf_m68k_plt_info elf_isac_plt_info = {
+ ISAC_PLT_ENTRY_SIZE,
+ elf_isac_plt0_entry, { 2, 12},
+ elf_isac_plt_entry, { 2, 20 }, 12
+};
+
+#define CPU32_PLT_ENTRY_SIZE 24
+/* Procedure linkage table entries for the cpu32 */
+static const bfd_byte elf_cpu32_plt0_entry[CPU32_PLT_ENTRY_SIZE] =
+{
+ 0x2f, 0x3b, 0x01, 0x70, /* move.l (%pc,addr),-(%sp) */
+ 0, 0, 0, 2, /* + (.got + 4) - . */
+ 0x22, 0x7b, 0x01, 0x70, /* moveal %pc@(0xc), %a1 */
+ 0, 0, 0, 2, /* + (.got + 8) - . */
+ 0x4e, 0xd1, /* jmp %a1@ */
+ 0, 0, 0, 0, /* pad out to 24 bytes. */
+ 0, 0
+};
+
+static const bfd_byte elf_cpu32_plt_entry[CPU32_PLT_ENTRY_SIZE] =
+{
+ 0x22, 0x7b, 0x01, 0x70, /* moveal %pc@(0xc), %a1 */
+ 0, 0, 0, 2, /* + (.got.plt entry) - . */
+ 0x4e, 0xd1, /* jmp %a1@ */
+ 0x2f, 0x3c, /* move.l #offset,-(%sp) */
+ 0, 0, 0, 0, /* + reloc index */
+ 0x60, 0xff, /* bra.l .plt */
+ 0, 0, 0, 0, /* + .plt - . */
+ 0, 0
+};
+
+static const struct elf_m68k_plt_info elf_cpu32_plt_info = {
+ CPU32_PLT_ENTRY_SIZE,
+ elf_cpu32_plt0_entry, { 4, 12 },
+ elf_cpu32_plt_entry, { 4, 18 }, 10
+};
+
+/* 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;
+};
+
+/* Forward declaration. */
+struct elf_m68k_got_entry;
+
+/* 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;
+
+ /* Key to got_entries. */
+ unsigned long got_entry_key;
+
+ /* List of GOT entries for this symbol. This list is build during
+ offset finalization and is used within elf_m68k_finish_dynamic_symbol
+ to traverse all GOT entries for a particular symbol.
+
+ ??? We could've used root.got.glist field instead, but having
+ a separate field is cleaner. */
+ struct elf_m68k_got_entry *glist;
+};
+
+#define elf_m68k_hash_entry(ent) ((struct elf_m68k_link_hash_entry *) (ent))
+
+/* Key part of GOT entry in hashtable. */
+struct elf_m68k_got_entry_key
+{
+ /* BFD in which this symbol was defined. NULL for global symbols. */
+ const bfd *bfd;
+
+ /* Symbol index. Either local symbol index or h->got_entry_key. */
+ unsigned long symndx;
+
+ /* Type is one of R_68K_GOT{8, 16, 32}O, R_68K_TLS_GD{8, 16, 32},
+ R_68K_TLS_LDM{8, 16, 32} or R_68K_TLS_IE{8, 16, 32}.
+
+ From perspective of hashtable key, only elf_m68k_got_reloc_type (type)
+ matters. That is, we distinguish between, say, R_68K_GOT16O
+ and R_68K_GOT32O when allocating offsets, but they are considered to be
+ the same when searching got->entries. */
+ enum elf_m68k_reloc_type type;
+};
+
+/* Size of the GOT offset suitable for relocation. */
+enum elf_m68k_got_offset_size { R_8, R_16, R_32, R_LAST };
+
+/* Entry of the GOT. */
+struct elf_m68k_got_entry
+{
+ /* GOT entries are put into a got->entries hashtable. This is the key. */
+ struct elf_m68k_got_entry_key key_;
+
+ /* GOT entry data. We need s1 before offset finalization and s2 after. */
+ union
+ {
+ struct
+ {
+ /* Number of times this entry is referenced. It is used to
+ filter out unnecessary GOT slots in elf_m68k_gc_sweep_hook. */
+ bfd_vma refcount;
+ } s1;
+
+ struct
+ {
+ /* Offset from the start of .got section. To calculate offset relative
+ to GOT pointer one should substract got->offset from this value. */
+ bfd_vma offset;
+
+ /* Pointer to the next GOT entry for this global symbol.
+ Symbols have at most one entry in one GOT, but might
+ have entries in more than one GOT.
+ Root of this list is h->glist.
+ NULL for local symbols. */
+ struct elf_m68k_got_entry *next;
+ } s2;
+ } u;
+};
+
+/* Return representative type for relocation R_TYPE.
+ This is used to avoid enumerating many relocations in comparisons,
+ switches etc. */
+
+static enum elf_m68k_reloc_type
+elf_m68k_reloc_got_type (enum elf_m68k_reloc_type r_type)
+{
+ switch (r_type)
+ {
+ /* In most cases R_68K_GOTx relocations require the very same
+ handling as R_68K_GOT32O relocation. In cases when we need
+ to distinguish between the two, we use explicitly compare against
+ r_type. */
+ case R_68K_GOT32:
+ case R_68K_GOT16:
+ case R_68K_GOT8:
+ case R_68K_GOT32O:
+ case R_68K_GOT16O:
+ case R_68K_GOT8O:
+ return R_68K_GOT32O;
+
+ case R_68K_TLS_GD32:
+ case R_68K_TLS_GD16:
+ case R_68K_TLS_GD8:
+ return R_68K_TLS_GD32;
+
+ case R_68K_TLS_LDM32:
+ case R_68K_TLS_LDM16:
+ case R_68K_TLS_LDM8:
+ return R_68K_TLS_LDM32;
+
+ case R_68K_TLS_IE32:
+ case R_68K_TLS_IE16:
+ case R_68K_TLS_IE8:
+ return R_68K_TLS_IE32;
+
+ default:
+ BFD_ASSERT (FALSE);
+ return 0;
+ }
+}
+
+/* Return size of the GOT entry offset for relocation R_TYPE. */
+
+static enum elf_m68k_got_offset_size
+elf_m68k_reloc_got_offset_size (enum elf_m68k_reloc_type r_type)
+{
+ switch (r_type)
+ {
+ case R_68K_GOT32: case R_68K_GOT16: case R_68K_GOT8:
+ case R_68K_GOT32O: case R_68K_TLS_GD32: case R_68K_TLS_LDM32:
+ case R_68K_TLS_IE32:
+ return R_32;
+
+ case R_68K_GOT16O: case R_68K_TLS_GD16: case R_68K_TLS_LDM16:
+ case R_68K_TLS_IE16:
+ return R_16;
+
+ case R_68K_GOT8O: case R_68K_TLS_GD8: case R_68K_TLS_LDM8:
+ case R_68K_TLS_IE8:
+ return R_8;
+
+ default:
+ BFD_ASSERT (FALSE);
+ return 0;
+ }
+}
+
+/* Return number of GOT entries we need to allocate in GOT for
+ relocation R_TYPE. */
+
+static bfd_vma
+elf_m68k_reloc_got_n_slots (enum elf_m68k_reloc_type r_type)
+{
+ switch (elf_m68k_reloc_got_type (r_type))
+ {
+ case R_68K_GOT32O:
+ case R_68K_TLS_IE32:
+ return 1;
+
+ case R_68K_TLS_GD32:
+ case R_68K_TLS_LDM32:
+ return 2;
+
+ default:
+ BFD_ASSERT (FALSE);
+ return 0;
+ }
+}
+
+/* Return TRUE if relocation R_TYPE is a TLS one. */
+
+static bfd_boolean
+elf_m68k_reloc_tls_p (enum elf_m68k_reloc_type r_type)
+{
+ switch (r_type)
+ {
+ case R_68K_TLS_GD32: case R_68K_TLS_GD16: case R_68K_TLS_GD8:
+ case R_68K_TLS_LDM32: case R_68K_TLS_LDM16: case R_68K_TLS_LDM8:
+ case R_68K_TLS_LDO32: case R_68K_TLS_LDO16: case R_68K_TLS_LDO8:
+ case R_68K_TLS_IE32: case R_68K_TLS_IE16: case R_68K_TLS_IE8:
+ case R_68K_TLS_LE32: case R_68K_TLS_LE16: case R_68K_TLS_LE8:
+ case R_68K_TLS_DTPMOD32: case R_68K_TLS_DTPREL32: case R_68K_TLS_TPREL32:
+ return TRUE;
+
+ default:
+ return FALSE;
+ }
+}
+
+/* Data structure representing a single GOT. */
+struct elf_m68k_got
+{
+ /* Hashtable of 'struct elf_m68k_got_entry's.
+ Starting size of this table is the maximum number of
+ R_68K_GOT8O entries. */
+ htab_t entries;
+
+ /* Number of R_x slots in this GOT. Some (e.g., TLS) entries require
+ several GOT slots.
+
+ n_slots[R_8] is the count of R_8 slots in this GOT.
+ n_slots[R_16] is the cumulative count of R_8 and R_16 slots
+ in this GOT.
+ n_slots[R_32] is the cumulative count of R_8, R_16 and R_32 slots
+ in this GOT. This is the total number of slots. */
+ bfd_vma n_slots[R_LAST];
+
+ /* Number of local (entry->key_.h == NULL) slots in this GOT.
+ This is only used to properly calculate size of .rela.got section;
+ see elf_m68k_partition_multi_got. */
+ bfd_vma local_n_slots;
+
+ /* Offset of this GOT relative to beginning of .got section. */
+ bfd_vma offset;
+};
+
+/* BFD and its GOT. This is an entry in multi_got->bfd2got hashtable. */
+struct elf_m68k_bfd2got_entry
+{
+ /* BFD. */
+ const bfd *bfd;
+
+ /* Assigned GOT. Before partitioning multi-GOT each BFD has its own
+ GOT structure. After partitioning several BFD's might [and often do]
+ share a single GOT. */
+ struct elf_m68k_got *got;
+};
+
+/* The main data structure holding all the pieces. */
+struct elf_m68k_multi_got
+{
+ /* Hashtable mapping each BFD to its GOT. If a BFD doesn't have an entry
+ here, then it doesn't need a GOT (this includes the case of a BFD
+ having an empty GOT).
+
+ ??? This hashtable can be replaced by an array indexed by bfd->id. */
+ htab_t bfd2got;
+
+ /* Next symndx to assign a global symbol.
+ h->got_entry_key is initialized from this counter. */
+ unsigned long global_symndx;
+};
+
+/* m68k ELF linker hash table. */
+
+struct elf_m68k_link_hash_table
+{
+ struct elf_link_hash_table root;
+
+ /* Small local sym cache. */
+ struct sym_cache sym_cache;
+
+ /* The PLT format used by this link, or NULL if the format has not
+ yet been chosen. */
+ const struct elf_m68k_plt_info *plt_info;
+
+ /* True, if GP is loaded within each function which uses it.
+ Set to TRUE when GOT negative offsets or multi-GOT is enabled. */
+ bfd_boolean local_gp_p;
+
+ /* Switch controlling use of negative offsets to double the size of GOTs. */
+ bfd_boolean use_neg_got_offsets_p;
+
+ /* Switch controlling generation of multiple GOTs. */
+ bfd_boolean allow_multigot_p;
+
+ /* Multi-GOT data structure. */
+ struct elf_m68k_multi_got multi_got_;
+};
+
+/* Get the m68k ELF linker hash table from a link_info structure. */
+
+#define elf_m68k_hash_table(p) \
+ (elf_hash_table_id ((struct elf_link_hash_table *) ((p)->hash)) \
+ == M68K_ELF_DATA ? ((struct elf_m68k_link_hash_table *) ((p)->hash)) : NULL)
+
+/* Shortcut to multi-GOT data. */
+#define elf_m68k_multi_got(INFO) (&elf_m68k_hash_table (INFO)->multi_got_)
+
+/* Create an entry in an m68k ELF linker hash table. */
+
+static struct bfd_hash_entry *
+elf_m68k_link_hash_newfunc (struct bfd_hash_entry *entry,
+ struct bfd_hash_table *table,
+ const char *string)
+{
+ struct bfd_hash_entry *ret = entry;
+
+ /* Allocate the structure if it has not already been allocated by a
+ subclass. */
+ if (ret == NULL)
+ ret = bfd_hash_allocate (table,
+ sizeof (struct elf_m68k_link_hash_entry));
+ if (ret == NULL)
+ return ret;
+
+ /* Call the allocation method of the superclass. */
+ ret = _bfd_elf_link_hash_newfunc (ret, table, string);
+ if (ret != NULL)
+ {
+ elf_m68k_hash_entry (ret)->pcrel_relocs_copied = NULL;
+ elf_m68k_hash_entry (ret)->got_entry_key = 0;
+ elf_m68k_hash_entry (ret)->glist = NULL;
+ }
+
+ return ret;
+}
+
+/* Destroy an m68k ELF linker hash table. */
+
+static void
+elf_m68k_link_hash_table_free (bfd *obfd)
+{
+ struct elf_m68k_link_hash_table *htab;
+
+ htab = (struct elf_m68k_link_hash_table *) obfd->link.hash;
+
+ if (htab->multi_got_.bfd2got != NULL)
+ {
+ htab_delete (htab->multi_got_.bfd2got);
+ htab->multi_got_.bfd2got = NULL;
+ }
+ _bfd_elf_link_hash_table_free (obfd);
+}
+
+/* Create an m68k ELF linker hash table. */
+
+static struct bfd_link_hash_table *
+elf_m68k_link_hash_table_create (bfd *abfd)
+{
+ struct elf_m68k_link_hash_table *ret;
+ bfd_size_type amt = sizeof (struct elf_m68k_link_hash_table);
+
+ ret = (struct elf_m68k_link_hash_table *) bfd_zmalloc (amt);
+ 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,
+ sizeof (struct elf_m68k_link_hash_entry),
+ M68K_ELF_DATA))
+ {
+ free (ret);
+ return NULL;
+ }
+ ret->root.root.hash_table_free = elf_m68k_link_hash_table_free;
+
+ ret->multi_got_.global_symndx = 1;
+
+ return &ret->root.root;
+}
+
+/* Set the right machine number. */
+
+static bfd_boolean
+elf32_m68k_object_p (bfd *abfd)
+{
+ unsigned int mach = 0;
+ unsigned features = 0;
+ flagword eflags = elf_elfheader (abfd)->e_flags;
+
+ if ((eflags & EF_M68K_ARCH_MASK) == EF_M68K_M68000)
+ features |= m68000;
+ else if ((eflags & EF_M68K_ARCH_MASK) == EF_M68K_CPU32)
+ features |= cpu32;
+ else if ((eflags & EF_M68K_ARCH_MASK) == EF_M68K_FIDO)
+ features |= fido_a;
+ else
+ {
+ switch (eflags & EF_M68K_CF_ISA_MASK)
+ {
+ case EF_M68K_CF_ISA_A_NODIV:
+ features |= mcfisa_a;
+ break;
+ case EF_M68K_CF_ISA_A:
+ features |= mcfisa_a|mcfhwdiv;
+ break;
+ case EF_M68K_CF_ISA_A_PLUS:
+ features |= mcfisa_a|mcfisa_aa|mcfhwdiv|mcfusp;
+ break;
+ case EF_M68K_CF_ISA_B_NOUSP:
+ features |= mcfisa_a|mcfisa_b|mcfhwdiv;
+ break;
+ case EF_M68K_CF_ISA_B:
+ features |= mcfisa_a|mcfisa_b|mcfhwdiv|mcfusp;
+ break;
+ case EF_M68K_CF_ISA_C:
+ features |= mcfisa_a|mcfisa_c|mcfhwdiv|mcfusp;
+ break;
+ case EF_M68K_CF_ISA_C_NODIV:
+ features |= mcfisa_a|mcfisa_c|mcfusp;
+ break;
+ }
+ switch (eflags & EF_M68K_CF_MAC_MASK)
+ {
+ case EF_M68K_CF_MAC:
+ features |= mcfmac;
+ break;
+ case EF_M68K_CF_EMAC:
+ features |= mcfemac;
+ break;
+ }
+ if (eflags & EF_M68K_CF_FLOAT)
+ features |= cfloat;
+ }
+
+ mach = bfd_m68k_features_to_mach (features);
+ bfd_default_set_arch_mach (abfd, bfd_arch_m68k, mach);
+
+ return TRUE;
+}
+
+/* Somewhat reverse of elf32_m68k_object_p, this sets the e_flag
+ field based on the machine number. */
+
+static void
+elf_m68k_final_write_processing (bfd *abfd,
+ bfd_boolean linker ATTRIBUTE_UNUSED)
+{
+ int mach = bfd_get_mach (abfd);
+ unsigned long e_flags = elf_elfheader (abfd)->e_flags;
+
+ if (!e_flags)
+ {
+ unsigned int arch_mask;
+
+ arch_mask = bfd_m68k_mach_to_features (mach);
+
+ if (arch_mask & m68000)
+ e_flags = EF_M68K_M68000;
+ else if (arch_mask & cpu32)
+ e_flags = EF_M68K_CPU32;
+ else if (arch_mask & fido_a)
+ e_flags = EF_M68K_FIDO;
+ else
+ {
+ switch (arch_mask
+ & (mcfisa_a | mcfisa_aa | mcfisa_b | mcfisa_c | mcfhwdiv | mcfusp))
+ {
+ case mcfisa_a:
+ e_flags |= EF_M68K_CF_ISA_A_NODIV;
+ break;
+ case mcfisa_a | mcfhwdiv:
+ e_flags |= EF_M68K_CF_ISA_A;
+ break;
+ case mcfisa_a | mcfisa_aa | mcfhwdiv | mcfusp:
+ e_flags |= EF_M68K_CF_ISA_A_PLUS;
+ break;
+ case mcfisa_a | mcfisa_b | mcfhwdiv:
+ e_flags |= EF_M68K_CF_ISA_B_NOUSP;
+ break;
+ case mcfisa_a | mcfisa_b | mcfhwdiv | mcfusp:
+ e_flags |= EF_M68K_CF_ISA_B;
+ break;
+ case mcfisa_a | mcfisa_c | mcfhwdiv | mcfusp:
+ e_flags |= EF_M68K_CF_ISA_C;
+ break;
+ case mcfisa_a | mcfisa_c | mcfusp:
+ e_flags |= EF_M68K_CF_ISA_C_NODIV;
+ break;
+ }
+ if (arch_mask & mcfmac)
+ e_flags |= EF_M68K_CF_MAC;
+ else if (arch_mask & mcfemac)
+ e_flags |= EF_M68K_CF_EMAC;
+ if (arch_mask & cfloat)
+ e_flags |= EF_M68K_CF_FLOAT | EF_M68K_CFV4E;
+ }
+ elf_elfheader (abfd)->e_flags = e_flags;
+ }
+}
+
+/* Keep m68k-specific flags in the ELF header. */
+
+static bfd_boolean
+elf32_m68k_set_private_flags (bfd *abfd, flagword flags)
+{
+ elf_elfheader (abfd)->e_flags = flags;
+ elf_flags_init (abfd) = TRUE;
+ return TRUE;
+}
+
+/* Merge backend specific data from an object file to the output
+ object file when linking. */
+static bfd_boolean
+elf32_m68k_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
+{
+ flagword out_flags;
+ flagword in_flags;
+ flagword out_isa;
+ flagword in_isa;
+ const bfd_arch_info_type *arch_info;
+
+ if ( bfd_get_flavour (ibfd) != bfd_target_elf_flavour
+ || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
+ return FALSE;
+
+ /* Get the merged machine. This checks for incompatibility between
+ Coldfire & non-Coldfire flags, incompability between different
+ Coldfire ISAs, and incompability between different MAC types. */
+ arch_info = bfd_arch_get_compatible (ibfd, obfd, FALSE);
+ if (!arch_info)
+ return FALSE;
+
+ bfd_set_arch_mach (obfd, bfd_arch_m68k, arch_info->mach);
+
+ in_flags = elf_elfheader (ibfd)->e_flags;
+ if (!elf_flags_init (obfd))
+ {
+ elf_flags_init (obfd) = TRUE;
+ out_flags = in_flags;
+ }
+ else
+ {
+ out_flags = elf_elfheader (obfd)->e_flags;
+ unsigned int variant_mask;
+
+ if ((in_flags & EF_M68K_ARCH_MASK) == EF_M68K_M68000)
+ variant_mask = 0;
+ else if ((in_flags & EF_M68K_ARCH_MASK) == EF_M68K_CPU32)
+ variant_mask = 0;
+ else if ((in_flags & EF_M68K_ARCH_MASK) == EF_M68K_FIDO)
+ variant_mask = 0;
+ else
+ variant_mask = EF_M68K_CF_ISA_MASK;
+
+ in_isa = (in_flags & variant_mask);
+ out_isa = (out_flags & variant_mask);
+ if (in_isa > out_isa)
+ out_flags ^= in_isa ^ out_isa;
+ if (((in_flags & EF_M68K_ARCH_MASK) == EF_M68K_CPU32
+ && (out_flags & EF_M68K_ARCH_MASK) == EF_M68K_FIDO)
+ || ((in_flags & EF_M68K_ARCH_MASK) == EF_M68K_FIDO
+ && (out_flags & EF_M68K_ARCH_MASK) == EF_M68K_CPU32))
+ out_flags = EF_M68K_FIDO;
+ else
+ out_flags |= in_flags ^ in_isa;
+ }
+ elf_elfheader (obfd)->e_flags = out_flags;
+
+ return TRUE;
+}
+
+/* Display the flags field. */
+
+static bfd_boolean
+elf32_m68k_print_private_bfd_data (bfd *abfd, void * ptr)
+{
+ FILE *file = (FILE *) ptr;
+ flagword eflags = elf_elfheader (abfd)->e_flags;
+
+ 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 ((eflags & EF_M68K_ARCH_MASK) == EF_M68K_M68000)
+ fprintf (file, " [m68000]");
+ else if ((eflags & EF_M68K_ARCH_MASK) == EF_M68K_CPU32)
+ fprintf (file, " [cpu32]");
+ else if ((eflags & EF_M68K_ARCH_MASK) == EF_M68K_FIDO)
+ fprintf (file, " [fido]");
+ else
+ {
+ if ((eflags & EF_M68K_ARCH_MASK) == EF_M68K_CFV4E)
+ fprintf (file, " [cfv4e]");
+
+ if (eflags & EF_M68K_CF_ISA_MASK)
+ {
+ char const *isa = _("unknown");
+ char const *mac = _("unknown");
+ char const *additional = "";
+
+ switch (eflags & EF_M68K_CF_ISA_MASK)
+ {
+ case EF_M68K_CF_ISA_A_NODIV:
+ isa = "A";
+ additional = " [nodiv]";
+ break;
+ case EF_M68K_CF_ISA_A:
+ isa = "A";
+ break;
+ case EF_M68K_CF_ISA_A_PLUS:
+ isa = "A+";
+ break;
+ case EF_M68K_CF_ISA_B_NOUSP:
+ isa = "B";
+ additional = " [nousp]";
+ break;
+ case EF_M68K_CF_ISA_B:
+ isa = "B";
+ break;
+ case EF_M68K_CF_ISA_C:
+ isa = "C";
+ break;
+ case EF_M68K_CF_ISA_C_NODIV:
+ isa = "C";
+ additional = " [nodiv]";
+ break;
+ }
+ fprintf (file, " [isa %s]%s", isa, additional);
+
+ if (eflags & EF_M68K_CF_FLOAT)
+ fprintf (file, " [float]");
+
+ switch (eflags & EF_M68K_CF_MAC_MASK)
+ {
+ case 0:
+ mac = NULL;
+ break;
+ case EF_M68K_CF_MAC:
+ mac = "mac";
+ break;
+ case EF_M68K_CF_EMAC:
+ mac = "emac";
+ break;
+ case EF_M68K_CF_EMAC_B:
+ mac = "emac_b";
+ break;
+ }
+ if (mac)
+ fprintf (file, " [%s]", mac);
+ }
+ }
+
+ fputc ('\n', file);
+
+ return TRUE;
+}
+
+/* Multi-GOT support implementation design:
+
+ Multi-GOT starts in check_relocs hook. There we scan all
+ relocations of a BFD and build a local GOT (struct elf_m68k_got)
+ for it. If a single BFD appears to require too many GOT slots with
+ R_68K_GOT8O or R_68K_GOT16O relocations, we fail with notification
+ to user.
+ After check_relocs has been invoked for each input BFD, we have
+ constructed a GOT for each input BFD.
+
+ To minimize total number of GOTs required for a particular output BFD
+ (as some environments support only 1 GOT per output object) we try
+ to merge some of the GOTs to share an offset space. Ideally [and in most
+ cases] we end up with a single GOT. In cases when there are too many
+ restricted relocations (e.g., R_68K_GOT16O relocations) we end up with
+ several GOTs, assuming the environment can handle them.
+
+ Partitioning is done in elf_m68k_partition_multi_got. We start with
+ an empty GOT and traverse bfd2got hashtable putting got_entries from
+ local GOTs to the new 'big' one. We do that by constructing an
+ intermediate GOT holding all the entries the local GOT has and the big
+ GOT lacks. Then we check if there is room in the big GOT to accomodate
+ all the entries from diff. On success we add those entries to the big
+ GOT; on failure we start the new 'big' GOT and retry the adding of
+ entries from the local GOT. Note that this retry will always succeed as
+ each local GOT doesn't overflow the limits. After partitioning we
+ end up with each bfd assigned one of the big GOTs. GOT entries in the
+ big GOTs are initialized with GOT offsets. Note that big GOTs are
+ positioned consequently in program space and represent a single huge GOT
+ to the outside world.
+
+ After that we get to elf_m68k_relocate_section. There we
+ adjust relocations of GOT pointer (_GLOBAL_OFFSET_TABLE_) and symbol
+ relocations to refer to appropriate [assigned to current input_bfd]
+ big GOT.
+
+ Notes:
+
+ GOT entry type: We have several types of GOT entries.
+ * R_8 type is used in entries for symbols that have at least one
+ R_68K_GOT8O or R_68K_TLS_*8 relocation. We can have at most 0x40
+ such entries in one GOT.
+ * R_16 type is used in entries for symbols that have at least one
+ R_68K_GOT16O or R_68K_TLS_*16 relocation and no R_8 relocations.
+ We can have at most 0x4000 such entries in one GOT.
+ * R_32 type is used in all other cases. We can have as many
+ such entries in one GOT as we'd like.
+ When counting relocations we have to include the count of the smaller
+ ranged relocations in the counts of the larger ranged ones in order
+ to correctly detect overflow.
+
+ Sorting the GOT: In each GOT starting offsets are assigned to
+ R_8 entries, which are followed by R_16 entries, and
+ R_32 entries go at the end. See finalize_got_offsets for details.
+
+ Negative GOT offsets: To double usable offset range of GOTs we use
+ negative offsets. As we assign entries with GOT offsets relative to
+ start of .got section, the offset values are positive. They become
+ negative only in relocate_section where got->offset value is
+ subtracted from them.
+
+ 3 special GOT entries: There are 3 special GOT entries used internally
+ by loader. These entries happen to be placed to .got.plt section,
+ so we don't do anything about them in multi-GOT support.
+
+ Memory management: All data except for hashtables
+ multi_got->bfd2got and got->entries are allocated on
+ elf_hash_table (info)->dynobj bfd (for this reason we pass 'info'
+ to most functions), so we don't need to care to free them. At the
+ moment of allocation hashtables are being linked into main data
+ structure (multi_got), all pieces of which are reachable from
+ elf_m68k_multi_got (info). We deallocate them in
+ elf_m68k_link_hash_table_free. */
+
+/* Initialize GOT. */
+
+static void
+elf_m68k_init_got (struct elf_m68k_got *got)
+{
+ got->entries = NULL;
+ got->n_slots[R_8] = 0;
+ got->n_slots[R_16] = 0;
+ got->n_slots[R_32] = 0;
+ got->local_n_slots = 0;
+ got->offset = (bfd_vma) -1;
+}
+
+/* Destruct GOT. */
+
+static void
+elf_m68k_clear_got (struct elf_m68k_got *got)
+{
+ if (got->entries != NULL)
+ {
+ htab_delete (got->entries);
+ got->entries = NULL;
+ }
+}
+
+/* Create and empty GOT structure. INFO is the context where memory
+ should be allocated. */
+
+static struct elf_m68k_got *
+elf_m68k_create_empty_got (struct bfd_link_info *info)
+{
+ struct elf_m68k_got *got;
+
+ got = bfd_alloc (elf_hash_table (info)->dynobj, sizeof (*got));
+ if (got == NULL)
+ return NULL;
+
+ elf_m68k_init_got (got);
+
+ return got;
+}
+
+/* Initialize KEY. */
+
+static void
+elf_m68k_init_got_entry_key (struct elf_m68k_got_entry_key *key,
+ struct elf_link_hash_entry *h,
+ const bfd *abfd, unsigned long symndx,
+ enum elf_m68k_reloc_type reloc_type)
+{
+ if (elf_m68k_reloc_got_type (reloc_type) == R_68K_TLS_LDM32)
+ /* All TLS_LDM relocations share a single GOT entry. */
+ {
+ key->bfd = NULL;
+ key->symndx = 0;
+ }
+ else if (h != NULL)
+ /* Global symbols are identified with their got_entry_key. */
+ {
+ key->bfd = NULL;
+ key->symndx = elf_m68k_hash_entry (h)->got_entry_key;
+ BFD_ASSERT (key->symndx != 0);
+ }
+ else
+ /* Local symbols are identified by BFD they appear in and symndx. */
+ {
+ key->bfd = abfd;
+ key->symndx = symndx;
+ }
+
+ key->type = reloc_type;
+}
+
+/* Calculate hash of got_entry.
+ ??? Is it good? */
+
+static hashval_t
+elf_m68k_got_entry_hash (const void *_entry)
+{
+ const struct elf_m68k_got_entry_key *key;
+
+ key = &((const struct elf_m68k_got_entry *) _entry)->key_;
+
+ return (key->symndx
+ + (key->bfd != NULL ? (int) key->bfd->id : -1)
+ + elf_m68k_reloc_got_type (key->type));
+}
+
+/* Check if two got entries are equal. */
+
+static int
+elf_m68k_got_entry_eq (const void *_entry1, const void *_entry2)
+{
+ const struct elf_m68k_got_entry_key *key1;
+ const struct elf_m68k_got_entry_key *key2;
+
+ key1 = &((const struct elf_m68k_got_entry *) _entry1)->key_;
+ key2 = &((const struct elf_m68k_got_entry *) _entry2)->key_;
+
+ return (key1->bfd == key2->bfd
+ && key1->symndx == key2->symndx
+ && (elf_m68k_reloc_got_type (key1->type)
+ == elf_m68k_reloc_got_type (key2->type)));
+}
+
+/* When using negative offsets, we allocate one extra R_8, one extra R_16
+ and one extra R_32 slots to simplify handling of 2-slot entries during
+ offset allocation -- hence -1 for R_8 slots and -2 for R_16 slots. */
+
+/* Maximal number of R_8 slots in a single GOT. */
+#define ELF_M68K_R_8_MAX_N_SLOTS_IN_GOT(INFO) \
+ (elf_m68k_hash_table (INFO)->use_neg_got_offsets_p \
+ ? (0x40 - 1) \
+ : 0x20)
+
+/* Maximal number of R_8 and R_16 slots in a single GOT. */
+#define ELF_M68K_R_8_16_MAX_N_SLOTS_IN_GOT(INFO) \
+ (elf_m68k_hash_table (INFO)->use_neg_got_offsets_p \
+ ? (0x4000 - 2) \
+ : 0x2000)
+
+/* SEARCH - simply search the hashtable, don't insert new entries or fail when
+ the entry cannot be found.
+ FIND_OR_CREATE - search for an existing entry, but create new if there's
+ no such.
+ MUST_FIND - search for an existing entry and assert that it exist.
+ MUST_CREATE - assert that there's no such entry and create new one. */
+enum elf_m68k_get_entry_howto
+ {
+ SEARCH,
+ FIND_OR_CREATE,
+ MUST_FIND,
+ MUST_CREATE
+ };
+
+/* Get or create (depending on HOWTO) entry with KEY in GOT.
+ INFO is context in which memory should be allocated (can be NULL if
+ HOWTO is SEARCH or MUST_FIND). */
+
+static struct elf_m68k_got_entry *
+elf_m68k_get_got_entry (struct elf_m68k_got *got,
+ const struct elf_m68k_got_entry_key *key,
+ enum elf_m68k_get_entry_howto howto,
+ struct bfd_link_info *info)
+{
+ struct elf_m68k_got_entry entry_;
+ struct elf_m68k_got_entry *entry;
+ void **ptr;
+
+ BFD_ASSERT ((info == NULL) == (howto == SEARCH || howto == MUST_FIND));
+
+ if (got->entries == NULL)
+ /* This is the first entry in ABFD. Initialize hashtable. */
+ {
+ if (howto == SEARCH)
+ return NULL;
+
+ got->entries = htab_try_create (ELF_M68K_R_8_MAX_N_SLOTS_IN_GOT
+ (info),
+ elf_m68k_got_entry_hash,
+ elf_m68k_got_entry_eq, NULL);
+ if (got->entries == NULL)
+ {
+ bfd_set_error (bfd_error_no_memory);
+ return NULL;
+ }
+ }
+
+ entry_.key_ = *key;
+ ptr = htab_find_slot (got->entries, &entry_, (howto != SEARCH
+ ? INSERT : NO_INSERT));
+ if (ptr == NULL)
+ {
+ if (howto == SEARCH)
+ /* Entry not found. */
+ return NULL;
+
+ /* We're out of memory. */
+ bfd_set_error (bfd_error_no_memory);
+ return NULL;
+ }
+
+ if (*ptr == NULL)
+ /* We didn't find the entry and we're asked to create a new one. */
+ {
+ BFD_ASSERT (howto != MUST_FIND && howto != SEARCH);
+
+ entry = bfd_alloc (elf_hash_table (info)->dynobj, sizeof (*entry));
+ if (entry == NULL)
+ return NULL;
+
+ /* Initialize new entry. */
+ entry->key_ = *key;
+
+ entry->u.s1.refcount = 0;
+
+ /* Mark the entry as not initialized. */
+ entry->key_.type = R_68K_max;
+
+ *ptr = entry;
+ }
+ else
+ /* We found the entry. */
+ {
+ BFD_ASSERT (howto != MUST_CREATE);
+
+ entry = *ptr;
+ }
+
+ return entry;
+}
+
+/* Update GOT counters when merging entry of WAS type with entry of NEW type.
+ Return the value to which ENTRY's type should be set. */
+
+static enum elf_m68k_reloc_type
+elf_m68k_update_got_entry_type (struct elf_m68k_got *got,
+ enum elf_m68k_reloc_type was,
+ enum elf_m68k_reloc_type new_reloc)
+{
+ enum elf_m68k_got_offset_size was_size;
+ enum elf_m68k_got_offset_size new_size;
+ bfd_vma n_slots;
+
+ if (was == R_68K_max)
+ /* The type of the entry is not initialized yet. */
+ {
+ /* Update all got->n_slots counters, including n_slots[R_32]. */
+ was_size = R_LAST;
+
+ was = new_reloc;
+ }
+ else
+ {
+ /* !!! We, probably, should emit an error rather then fail on assert
+ in such a case. */
+ BFD_ASSERT (elf_m68k_reloc_got_type (was)
+ == elf_m68k_reloc_got_type (new_reloc));
+
+ was_size = elf_m68k_reloc_got_offset_size (was);
+ }
+
+ new_size = elf_m68k_reloc_got_offset_size (new_reloc);
+ n_slots = elf_m68k_reloc_got_n_slots (new_reloc);
+
+ while (was_size > new_size)
+ {
+ --was_size;
+ got->n_slots[was_size] += n_slots;
+ }
+
+ if (new_reloc > was)
+ /* Relocations are ordered from bigger got offset size to lesser,
+ so choose the relocation type with lesser offset size. */
+ was = new_reloc;
+
+ return was;
+}
+
+/* Update GOT counters when removing an entry of type TYPE. */
+
+static void
+elf_m68k_remove_got_entry_type (struct elf_m68k_got *got,
+ enum elf_m68k_reloc_type type)
+{
+ enum elf_m68k_got_offset_size os;
+ bfd_vma n_slots;
+
+ n_slots = elf_m68k_reloc_got_n_slots (type);
+
+ /* Decrese counter of slots with offset size corresponding to TYPE
+ and all greater offset sizes. */
+ for (os = elf_m68k_reloc_got_offset_size (type); os <= R_32; ++os)
+ {
+ BFD_ASSERT (got->n_slots[os] >= n_slots);
+
+ got->n_slots[os] -= n_slots;
+ }
+}
+
+/* Add new or update existing entry to GOT.
+ H, ABFD, TYPE and SYMNDX is data for the entry.
+ INFO is a context where memory should be allocated. */
+
+static struct elf_m68k_got_entry *
+elf_m68k_add_entry_to_got (struct elf_m68k_got *got,
+ struct elf_link_hash_entry *h,
+ const bfd *abfd,
+ enum elf_m68k_reloc_type reloc_type,
+ unsigned long symndx,
+ struct bfd_link_info *info)
+{
+ struct elf_m68k_got_entry_key key_;
+ struct elf_m68k_got_entry *entry;
+
+ if (h != NULL && elf_m68k_hash_entry (h)->got_entry_key == 0)
+ elf_m68k_hash_entry (h)->got_entry_key
+ = elf_m68k_multi_got (info)->global_symndx++;
+
+ elf_m68k_init_got_entry_key (&key_, h, abfd, symndx, reloc_type);
+
+ entry = elf_m68k_get_got_entry (got, &key_, FIND_OR_CREATE, info);
+ if (entry == NULL)
+ return NULL;
+
+ /* Determine entry's type and update got->n_slots counters. */
+ entry->key_.type = elf_m68k_update_got_entry_type (got,
+ entry->key_.type,
+ reloc_type);
+
+ /* Update refcount. */
+ ++entry->u.s1.refcount;
+
+ if (entry->u.s1.refcount == 1)
+ /* We see this entry for the first time. */
+ {
+ if (entry->key_.bfd != NULL)
+ got->local_n_slots += elf_m68k_reloc_got_n_slots (entry->key_.type);
+ }
+
+ BFD_ASSERT (got->n_slots[R_32] >= got->local_n_slots);
+
+ if ((got->n_slots[R_8]
+ > ELF_M68K_R_8_MAX_N_SLOTS_IN_GOT (info))
+ || (got->n_slots[R_16]
+ > ELF_M68K_R_8_16_MAX_N_SLOTS_IN_GOT (info)))
+ /* This BFD has too many relocation. */
+ {
+ if (got->n_slots[R_8] > ELF_M68K_R_8_MAX_N_SLOTS_IN_GOT (info))
+ (*_bfd_error_handler) (_("%B: GOT overflow: "
+ "Number of relocations with 8-bit "
+ "offset > %d"),
+ abfd,
+ ELF_M68K_R_8_MAX_N_SLOTS_IN_GOT (info));
+ else
+ (*_bfd_error_handler) (_("%B: GOT overflow: "
+ "Number of relocations with 8- or 16-bit "
+ "offset > %d"),
+ abfd,
+ ELF_M68K_R_8_16_MAX_N_SLOTS_IN_GOT (info));
+
+ return NULL;
+ }
+
+ return entry;
+}
+
+/* Compute the hash value of the bfd in a bfd2got hash entry. */
+
+static hashval_t
+elf_m68k_bfd2got_entry_hash (const void *entry)
+{
+ const struct elf_m68k_bfd2got_entry *e;
+
+ e = (const struct elf_m68k_bfd2got_entry *) entry;
+
+ return e->bfd->id;
+}
+
+/* Check whether two hash entries have the same bfd. */
+
+static int
+elf_m68k_bfd2got_entry_eq (const void *entry1, const void *entry2)
+{
+ const struct elf_m68k_bfd2got_entry *e1;
+ const struct elf_m68k_bfd2got_entry *e2;
+
+ e1 = (const struct elf_m68k_bfd2got_entry *) entry1;
+ e2 = (const struct elf_m68k_bfd2got_entry *) entry2;
+
+ return e1->bfd == e2->bfd;
+}
+
+/* Destruct a bfd2got entry. */
+
+static void
+elf_m68k_bfd2got_entry_del (void *_entry)
+{
+ struct elf_m68k_bfd2got_entry *entry;
+
+ entry = (struct elf_m68k_bfd2got_entry *) _entry;
+
+ BFD_ASSERT (entry->got != NULL);
+ elf_m68k_clear_got (entry->got);
+}
+
+/* Find existing or create new (depending on HOWTO) bfd2got entry in
+ MULTI_GOT. ABFD is the bfd we need a GOT for. INFO is a context where
+ memory should be allocated. */
+
+static struct elf_m68k_bfd2got_entry *
+elf_m68k_get_bfd2got_entry (struct elf_m68k_multi_got *multi_got,
+ const bfd *abfd,
+ enum elf_m68k_get_entry_howto howto,
+ struct bfd_link_info *info)
+{
+ struct elf_m68k_bfd2got_entry entry_;
+ void **ptr;
+ struct elf_m68k_bfd2got_entry *entry;
+
+ BFD_ASSERT ((info == NULL) == (howto == SEARCH || howto == MUST_FIND));
+
+ if (multi_got->bfd2got == NULL)
+ /* This is the first GOT. Initialize bfd2got. */
+ {
+ if (howto == SEARCH)
+ return NULL;
+
+ multi_got->bfd2got = htab_try_create (1, elf_m68k_bfd2got_entry_hash,
+ elf_m68k_bfd2got_entry_eq,
+ elf_m68k_bfd2got_entry_del);
+ if (multi_got->bfd2got == NULL)
+ {
+ bfd_set_error (bfd_error_no_memory);
+ return NULL;
+ }
+ }
+
+ entry_.bfd = abfd;
+ ptr = htab_find_slot (multi_got->bfd2got, &entry_, (howto != SEARCH
+ ? INSERT : NO_INSERT));
+ if (ptr == NULL)
+ {
+ if (howto == SEARCH)
+ /* Entry not found. */
+ return NULL;
+
+ /* We're out of memory. */
+ bfd_set_error (bfd_error_no_memory);
+ return NULL;
+ }
+
+ if (*ptr == NULL)
+ /* Entry was not found. Create new one. */
+ {
+ BFD_ASSERT (howto != MUST_FIND && howto != SEARCH);
+
+ entry = ((struct elf_m68k_bfd2got_entry *)
+ bfd_alloc (elf_hash_table (info)->dynobj, sizeof (*entry)));
+ if (entry == NULL)
+ return NULL;
+
+ entry->bfd = abfd;
+
+ entry->got = elf_m68k_create_empty_got (info);
+ if (entry->got == NULL)
+ return NULL;
+
+ *ptr = entry;
+ }
+ else
+ {
+ BFD_ASSERT (howto != MUST_CREATE);
+
+ /* Return existing entry. */
+ entry = *ptr;
+ }
+
+ return entry;
+}
+
+struct elf_m68k_can_merge_gots_arg
+{
+ /* A current_got that we constructing a DIFF against. */
+ struct elf_m68k_got *big;
+
+ /* GOT holding entries not present or that should be changed in
+ BIG. */
+ struct elf_m68k_got *diff;
+
+ /* Context where to allocate memory. */
+ struct bfd_link_info *info;
+
+ /* Error flag. */
+ bfd_boolean error_p;
+};
+
+/* Process a single entry from the small GOT to see if it should be added
+ or updated in the big GOT. */
+
+static int
+elf_m68k_can_merge_gots_1 (void **_entry_ptr, void *_arg)
+{
+ const struct elf_m68k_got_entry *entry1;
+ struct elf_m68k_can_merge_gots_arg *arg;
+ const struct elf_m68k_got_entry *entry2;
+ enum elf_m68k_reloc_type type;
+
+ entry1 = (const struct elf_m68k_got_entry *) *_entry_ptr;
+ arg = (struct elf_m68k_can_merge_gots_arg *) _arg;
+
+ entry2 = elf_m68k_get_got_entry (arg->big, &entry1->key_, SEARCH, NULL);
+
+ if (entry2 != NULL)
+ /* We found an existing entry. Check if we should update it. */
+ {
+ type = elf_m68k_update_got_entry_type (arg->diff,
+ entry2->key_.type,
+ entry1->key_.type);
+
+ if (type == entry2->key_.type)
+ /* ENTRY1 doesn't update data in ENTRY2. Skip it.
+ To skip creation of difference entry we use the type,
+ which we won't see in GOT entries for sure. */
+ type = R_68K_max;
+ }
+ else
+ /* We didn't find the entry. Add entry1 to DIFF. */
+ {
+ BFD_ASSERT (entry1->key_.type != R_68K_max);
+
+ type = elf_m68k_update_got_entry_type (arg->diff,
+ R_68K_max, entry1->key_.type);
+
+ if (entry1->key_.bfd != NULL)
+ arg->diff->local_n_slots += elf_m68k_reloc_got_n_slots (type);
+ }
+
+ if (type != R_68K_max)
+ /* Create an entry in DIFF. */
+ {
+ struct elf_m68k_got_entry *entry;
+
+ entry = elf_m68k_get_got_entry (arg->diff, &entry1->key_, MUST_CREATE,
+ arg->info);
+ if (entry == NULL)
+ {
+ arg->error_p = TRUE;
+ return 0;
+ }
+
+ entry->key_.type = type;
+ }
+
+ return 1;
+}
+
+/* Return TRUE if SMALL GOT can be added to BIG GOT without overflowing it.
+ Construct DIFF GOT holding the entries which should be added or updated
+ in BIG GOT to accumulate information from SMALL.
+ INFO is the context where memory should be allocated. */
+
+static bfd_boolean
+elf_m68k_can_merge_gots (struct elf_m68k_got *big,
+ const struct elf_m68k_got *small,
+ struct bfd_link_info *info,
+ struct elf_m68k_got *diff)
+{
+ struct elf_m68k_can_merge_gots_arg arg_;
+
+ BFD_ASSERT (small->offset == (bfd_vma) -1);
+
+ arg_.big = big;
+ arg_.diff = diff;
+ arg_.info = info;
+ arg_.error_p = FALSE;
+ htab_traverse_noresize (small->entries, elf_m68k_can_merge_gots_1, &arg_);
+ if (arg_.error_p)
+ {
+ diff->offset = 0;
+ return FALSE;
+ }
+
+ /* Check for overflow. */
+ if ((big->n_slots[R_8] + arg_.diff->n_slots[R_8]
+ > ELF_M68K_R_8_MAX_N_SLOTS_IN_GOT (info))
+ || (big->n_slots[R_16] + arg_.diff->n_slots[R_16]
+ > ELF_M68K_R_8_16_MAX_N_SLOTS_IN_GOT (info)))
+ return FALSE;
+
+ return TRUE;
+}
+
+struct elf_m68k_merge_gots_arg
+{
+ /* The BIG got. */
+ struct elf_m68k_got *big;
+
+ /* Context where memory should be allocated. */
+ struct bfd_link_info *info;
+
+ /* Error flag. */
+ bfd_boolean error_p;
+};
+
+/* Process a single entry from DIFF got. Add or update corresponding
+ entry in the BIG got. */
+
+static int
+elf_m68k_merge_gots_1 (void **entry_ptr, void *_arg)
+{
+ const struct elf_m68k_got_entry *from;
+ struct elf_m68k_merge_gots_arg *arg;
+ struct elf_m68k_got_entry *to;
+
+ from = (const struct elf_m68k_got_entry *) *entry_ptr;
+ arg = (struct elf_m68k_merge_gots_arg *) _arg;
+
+ to = elf_m68k_get_got_entry (arg->big, &from->key_, FIND_OR_CREATE,
+ arg->info);
+ if (to == NULL)
+ {
+ arg->error_p = TRUE;
+ return 0;
+ }
+
+ BFD_ASSERT (to->u.s1.refcount == 0);
+ /* All we need to merge is TYPE. */
+ to->key_.type = from->key_.type;
+
+ return 1;
+}
+
+/* Merge data from DIFF to BIG. INFO is context where memory should be
+ allocated. */
+
+static bfd_boolean
+elf_m68k_merge_gots (struct elf_m68k_got *big,
+ struct elf_m68k_got *diff,
+ struct bfd_link_info *info)
+{
+ if (diff->entries != NULL)
+ /* DIFF is not empty. Merge it into BIG GOT. */
+ {
+ struct elf_m68k_merge_gots_arg arg_;
+
+ /* Merge entries. */
+ arg_.big = big;
+ arg_.info = info;
+ arg_.error_p = FALSE;
+ htab_traverse_noresize (diff->entries, elf_m68k_merge_gots_1, &arg_);
+ if (arg_.error_p)
+ return FALSE;
+
+ /* Merge counters. */
+ big->n_slots[R_8] += diff->n_slots[R_8];
+ big->n_slots[R_16] += diff->n_slots[R_16];
+ big->n_slots[R_32] += diff->n_slots[R_32];
+ big->local_n_slots += diff->local_n_slots;
+ }
+ else
+ /* DIFF is empty. */
+ {
+ BFD_ASSERT (diff->n_slots[R_8] == 0);
+ BFD_ASSERT (diff->n_slots[R_16] == 0);
+ BFD_ASSERT (diff->n_slots[R_32] == 0);
+ BFD_ASSERT (diff->local_n_slots == 0);
+ }
+
+ BFD_ASSERT (!elf_m68k_hash_table (info)->allow_multigot_p
+ || ((big->n_slots[R_8]
+ <= ELF_M68K_R_8_MAX_N_SLOTS_IN_GOT (info))
+ && (big->n_slots[R_16]
+ <= ELF_M68K_R_8_16_MAX_N_SLOTS_IN_GOT (info))));
+
+ return TRUE;
+}
+
+struct elf_m68k_finalize_got_offsets_arg
+{
+ /* Ranges of the offsets for GOT entries.
+ R_x entries receive offsets between offset1[R_x] and offset2[R_x].
+ R_x is R_8, R_16 and R_32. */
+ bfd_vma *offset1;
+ bfd_vma *offset2;
+
+ /* Mapping from global symndx to global symbols.
+ This is used to build lists of got entries for global symbols. */
+ struct elf_m68k_link_hash_entry **symndx2h;
+
+ bfd_vma n_ldm_entries;
+};
+
+/* Assign ENTRY an offset. Build list of GOT entries for global symbols
+ along the way. */
+
+static int
+elf_m68k_finalize_got_offsets_1 (void **entry_ptr, void *_arg)
+{
+ struct elf_m68k_got_entry *entry;
+ struct elf_m68k_finalize_got_offsets_arg *arg;
+
+ enum elf_m68k_got_offset_size got_offset_size;
+ bfd_vma entry_size;
+
+ entry = (struct elf_m68k_got_entry *) *entry_ptr;
+ arg = (struct elf_m68k_finalize_got_offsets_arg *) _arg;
+
+ /* This should be a fresh entry created in elf_m68k_can_merge_gots. */
+ BFD_ASSERT (entry->u.s1.refcount == 0);
+
+ /* Get GOT offset size for the entry . */
+ got_offset_size = elf_m68k_reloc_got_offset_size (entry->key_.type);
+
+ /* Calculate entry size in bytes. */
+ entry_size = 4 * elf_m68k_reloc_got_n_slots (entry->key_.type);
+
+ /* Check if we should switch to negative range of the offsets. */
+ if (arg->offset1[got_offset_size] + entry_size
+ > arg->offset2[got_offset_size])
+ {
+ /* Verify that this is the only switch to negative range for
+ got_offset_size. If this assertion fails, then we've miscalculated
+ range for got_offset_size entries in
+ elf_m68k_finalize_got_offsets. */
+ BFD_ASSERT (arg->offset2[got_offset_size]
+ != arg->offset2[-(int) got_offset_size - 1]);
+
+ /* Switch. */
+ arg->offset1[got_offset_size] = arg->offset1[-(int) got_offset_size - 1];
+ arg->offset2[got_offset_size] = arg->offset2[-(int) got_offset_size - 1];
+
+ /* Verify that now we have enough room for the entry. */
+ BFD_ASSERT (arg->offset1[got_offset_size] + entry_size
+ <= arg->offset2[got_offset_size]);
+ }
+
+ /* Assign offset to entry. */
+ entry->u.s2.offset = arg->offset1[got_offset_size];
+ arg->offset1[got_offset_size] += entry_size;
+
+ if (entry->key_.bfd == NULL)
+ /* Hook up this entry into the list of got_entries of H. */
+ {
+ struct elf_m68k_link_hash_entry *h;
+
+ h = arg->symndx2h[entry->key_.symndx];
+ if (h != NULL)
+ {
+ entry->u.s2.next = h->glist;
+ h->glist = entry;
+ }
+ else
+ /* This should be the entry for TLS_LDM relocation then. */
+ {
+ BFD_ASSERT ((elf_m68k_reloc_got_type (entry->key_.type)
+ == R_68K_TLS_LDM32)
+ && entry->key_.symndx == 0);
+
+ ++arg->n_ldm_entries;
+ }
+ }
+ else
+ /* This entry is for local symbol. */
+ entry->u.s2.next = NULL;
+
+ return 1;
+}
+
+/* Assign offsets within GOT. USE_NEG_GOT_OFFSETS_P indicates if we
+ should use negative offsets.
+ Build list of GOT entries for global symbols along the way.
+ SYMNDX2H is mapping from global symbol indices to actual
+ global symbols.
+ Return offset at which next GOT should start. */
+
+static void
+elf_m68k_finalize_got_offsets (struct elf_m68k_got *got,
+ bfd_boolean use_neg_got_offsets_p,
+ struct elf_m68k_link_hash_entry **symndx2h,
+ bfd_vma *final_offset, bfd_vma *n_ldm_entries)
+{
+ struct elf_m68k_finalize_got_offsets_arg arg_;
+ bfd_vma offset1_[2 * R_LAST];
+ bfd_vma offset2_[2 * R_LAST];
+ int i;
+ bfd_vma start_offset;
+
+ BFD_ASSERT (got->offset != (bfd_vma) -1);
+
+ /* We set entry offsets relative to the .got section (and not the
+ start of a particular GOT), so that we can use them in
+ finish_dynamic_symbol without needing to know the GOT which they come
+ from. */
+
+ /* Put offset1 in the middle of offset1_, same for offset2. */
+ arg_.offset1 = offset1_ + R_LAST;
+ arg_.offset2 = offset2_ + R_LAST;
+
+ start_offset = got->offset;
+
+ if (use_neg_got_offsets_p)
+ /* Setup both negative and positive ranges for R_8, R_16 and R_32. */
+ i = -(int) R_32 - 1;
+ else
+ /* Setup positives ranges for R_8, R_16 and R_32. */
+ i = (int) R_8;
+
+ for (; i <= (int) R_32; ++i)
+ {
+ int j;
+ size_t n;
+
+ /* Set beginning of the range of offsets I. */
+ arg_.offset1[i] = start_offset;
+
+ /* Calculate number of slots that require I offsets. */
+ j = (i >= 0) ? i : -i - 1;
+ n = (j >= 1) ? got->n_slots[j - 1] : 0;
+ n = got->n_slots[j] - n;
+
+ if (use_neg_got_offsets_p && n != 0)
+ {
+ if (i < 0)
+ /* We first fill the positive side of the range, so we might
+ end up with one empty slot at that side when we can't fit
+ whole 2-slot entry. Account for that at negative side of
+ the interval with one additional entry. */
+ n = n / 2 + 1;
+ else
+ /* When the number of slots is odd, make positive side of the
+ range one entry bigger. */
+ n = (n + 1) / 2;
+ }
+
+ /* N is the number of slots that require I offsets.
+ Calculate length of the range for I offsets. */
+ n = 4 * n;
+
+ /* Set end of the range. */
+ arg_.offset2[i] = start_offset + n;
+
+ start_offset = arg_.offset2[i];
+ }
+
+ if (!use_neg_got_offsets_p)
+ /* Make sure that if we try to switch to negative offsets in
+ elf_m68k_finalize_got_offsets_1, the assert therein will catch
+ the bug. */
+ for (i = R_8; i <= R_32; ++i)
+ arg_.offset2[-i - 1] = arg_.offset2[i];
+
+ /* Setup got->offset. offset1[R_8] is either in the middle or at the
+ beginning of GOT depending on use_neg_got_offsets_p. */
+ got->offset = arg_.offset1[R_8];
+
+ arg_.symndx2h = symndx2h;
+ arg_.n_ldm_entries = 0;
+
+ /* Assign offsets. */
+ htab_traverse (got->entries, elf_m68k_finalize_got_offsets_1, &arg_);
+
+ /* Check offset ranges we have actually assigned. */
+ for (i = (int) R_8; i <= (int) R_32; ++i)
+ BFD_ASSERT (arg_.offset2[i] - arg_.offset1[i] <= 4);
+
+ *final_offset = start_offset;
+ *n_ldm_entries = arg_.n_ldm_entries;
+}
+
+struct elf_m68k_partition_multi_got_arg
+{
+ /* The GOT we are adding entries to. Aka big got. */
+ struct elf_m68k_got *current_got;
+
+ /* Offset to assign the next CURRENT_GOT. */
+ bfd_vma offset;
+
+ /* Context where memory should be allocated. */
+ struct bfd_link_info *info;
+
+ /* Total number of slots in the .got section.
+ This is used to calculate size of the .got and .rela.got sections. */
+ bfd_vma n_slots;
+
+ /* Difference in numbers of allocated slots in the .got section
+ and necessary relocations in the .rela.got section.
+ This is used to calculate size of the .rela.got section. */
+ bfd_vma slots_relas_diff;
+
+ /* Error flag. */
+ bfd_boolean error_p;
+
+ /* Mapping from global symndx to global symbols.
+ This is used to build lists of got entries for global symbols. */
+ struct elf_m68k_link_hash_entry **symndx2h;
+};
+
+static void
+elf_m68k_partition_multi_got_2 (struct elf_m68k_partition_multi_got_arg *arg)
+{
+ bfd_vma n_ldm_entries;
+
+ elf_m68k_finalize_got_offsets (arg->current_got,
+ (elf_m68k_hash_table (arg->info)
+ ->use_neg_got_offsets_p),
+ arg->symndx2h,
+ &arg->offset, &n_ldm_entries);
+
+ arg->n_slots += arg->current_got->n_slots[R_32];
+
+ if (!arg->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. Overwise we
+ don't need space in .rela.got for local symbols. */
+ arg->slots_relas_diff += arg->current_got->local_n_slots;
+
+ /* @LDM relocations require a 2-slot GOT entry, but only
+ one relocation. Account for that. */
+ arg->slots_relas_diff += n_ldm_entries;
+
+ BFD_ASSERT (arg->slots_relas_diff <= arg->n_slots);
+}
+
+
+/* Process a single BFD2GOT entry and either merge GOT to CURRENT_GOT
+ or start a new CURRENT_GOT. */
+
+static int
+elf_m68k_partition_multi_got_1 (void **_entry, void *_arg)
+{
+ struct elf_m68k_bfd2got_entry *entry;
+ struct elf_m68k_partition_multi_got_arg *arg;
+ struct elf_m68k_got *got;
+ struct elf_m68k_got diff_;
+ struct elf_m68k_got *diff;
+
+ entry = (struct elf_m68k_bfd2got_entry *) *_entry;
+ arg = (struct elf_m68k_partition_multi_got_arg *) _arg;
+
+ got = entry->got;
+ BFD_ASSERT (got != NULL);
+ BFD_ASSERT (got->offset == (bfd_vma) -1);
+
+ diff = NULL;
+
+ if (arg->current_got != NULL)
+ /* Construct diff. */
+ {
+ diff = &diff_;
+ elf_m68k_init_got (diff);
+
+ if (!elf_m68k_can_merge_gots (arg->current_got, got, arg->info, diff))
+ {
+ if (diff->offset == 0)
+ /* Offset set to 0 in the diff_ indicates an error. */
+ {
+ arg->error_p = TRUE;
+ goto final_return;
+ }
+
+ if (elf_m68k_hash_table (arg->info)->allow_multigot_p)
+ {
+ elf_m68k_clear_got (diff);
+ /* Schedule to finish up current_got and start new one. */
+ diff = NULL;
+ }
+ /* else
+ Merge GOTs no matter what. If big GOT overflows,
+ we'll fail in relocate_section due to truncated relocations.
+
+ ??? May be fail earlier? E.g., in can_merge_gots. */
+ }
+ }
+ else
+ /* Diff of got against empty current_got is got itself. */
+ {
+ /* Create empty current_got to put subsequent GOTs to. */
+ arg->current_got = elf_m68k_create_empty_got (arg->info);
+ if (arg->current_got == NULL)
+ {
+ arg->error_p = TRUE;
+ goto final_return;
+ }
+
+ arg->current_got->offset = arg->offset;
+
+ diff = got;
+ }
+
+ if (diff != NULL)
+ {
+ if (!elf_m68k_merge_gots (arg->current_got, diff, arg->info))
+ {
+ arg->error_p = TRUE;
+ goto final_return;
+ }
+
+ /* Now we can free GOT. */
+ elf_m68k_clear_got (got);
+
+ entry->got = arg->current_got;
+ }
+ else
+ {
+ /* Finish up current_got. */
+ elf_m68k_partition_multi_got_2 (arg);
+
+ /* Schedule to start a new current_got. */
+ arg->current_got = NULL;
+
+ /* Retry. */
+ if (!elf_m68k_partition_multi_got_1 (_entry, _arg))
+ {
+ BFD_ASSERT (arg->error_p);
+ goto final_return;
+ }
+ }
+
+ final_return:
+ if (diff != NULL)
+ elf_m68k_clear_got (diff);
+
+ return arg->error_p == FALSE ? 1 : 0;
+}
+
+/* Helper function to build symndx2h mapping. */
+
+static bfd_boolean
+elf_m68k_init_symndx2h_1 (struct elf_link_hash_entry *_h,
+ void *_arg)
+{
+ struct elf_m68k_link_hash_entry *h;
+
+ h = elf_m68k_hash_entry (_h);
+
+ if (h->got_entry_key != 0)
+ /* H has at least one entry in the GOT. */
+ {
+ struct elf_m68k_partition_multi_got_arg *arg;
+
+ arg = (struct elf_m68k_partition_multi_got_arg *) _arg;
+
+ BFD_ASSERT (arg->symndx2h[h->got_entry_key] == NULL);
+ arg->symndx2h[h->got_entry_key] = h;
+ }
+
+ return TRUE;
+}
+
+/* Merge GOTs of some BFDs, assign offsets to GOT entries and build
+ lists of GOT entries for global symbols.
+ Calculate sizes of .got and .rela.got sections. */
+
+static bfd_boolean
+elf_m68k_partition_multi_got (struct bfd_link_info *info)
+{
+ struct elf_m68k_multi_got *multi_got;
+ struct elf_m68k_partition_multi_got_arg arg_;
+
+ multi_got = elf_m68k_multi_got (info);
+
+ arg_.current_got = NULL;
+ arg_.offset = 0;
+ arg_.info = info;
+ arg_.n_slots = 0;
+ arg_.slots_relas_diff = 0;
+ arg_.error_p = FALSE;
+
+ if (multi_got->bfd2got != NULL)
+ {
+ /* Initialize symndx2h mapping. */
+ {
+ arg_.symndx2h = bfd_zmalloc (multi_got->global_symndx
+ * sizeof (*arg_.symndx2h));
+ if (arg_.symndx2h == NULL)
+ return FALSE;
+
+ elf_link_hash_traverse (elf_hash_table (info),
+ elf_m68k_init_symndx2h_1, &arg_);
+ }
+
+ /* Partition. */
+ htab_traverse (multi_got->bfd2got, elf_m68k_partition_multi_got_1,
+ &arg_);
+ if (arg_.error_p)
+ {
+ free (arg_.symndx2h);
+ arg_.symndx2h = NULL;
+
+ return FALSE;
+ }
+
+ /* Finish up last current_got. */
+ elf_m68k_partition_multi_got_2 (&arg_);
+
+ free (arg_.symndx2h);
+ }
+
+ if (elf_hash_table (info)->dynobj != NULL)
+ /* Set sizes of .got and .rela.got sections. */
+ {
+ asection *s;
+
+ s = bfd_get_linker_section (elf_hash_table (info)->dynobj, ".got");
+ if (s != NULL)
+ s->size = arg_.offset;
+ else
+ BFD_ASSERT (arg_.offset == 0);
+
+ BFD_ASSERT (arg_.slots_relas_diff <= arg_.n_slots);
+ arg_.n_slots -= arg_.slots_relas_diff;
+
+ s = bfd_get_linker_section (elf_hash_table (info)->dynobj, ".rela.got");
+ if (s != NULL)
+ s->size = arg_.n_slots * sizeof (Elf32_External_Rela);
+ else
+ BFD_ASSERT (arg_.n_slots == 0);
+ }
+ else
+ BFD_ASSERT (multi_got->bfd2got == NULL);
+
+ return TRUE;
+}
+
+/* Specialized version of elf_m68k_get_got_entry that returns pointer
+ to hashtable slot, thus allowing removal of entry via
+ elf_m68k_remove_got_entry. */
+
+static struct elf_m68k_got_entry **
+elf_m68k_find_got_entry_ptr (struct elf_m68k_got *got,
+ struct elf_m68k_got_entry_key *key)
+{
+ void **ptr;
+ struct elf_m68k_got_entry entry_;
+ struct elf_m68k_got_entry **entry_ptr;
+
+ entry_.key_ = *key;
+ ptr = htab_find_slot (got->entries, &entry_, NO_INSERT);
+ BFD_ASSERT (ptr != NULL);
+
+ entry_ptr = (struct elf_m68k_got_entry **) ptr;
+
+ return entry_ptr;
+}
+
+/* Remove entry pointed to by ENTRY_PTR from GOT. */
+
+static void
+elf_m68k_remove_got_entry (struct elf_m68k_got *got,
+ struct elf_m68k_got_entry **entry_ptr)
+{
+ struct elf_m68k_got_entry *entry;
+
+ entry = *entry_ptr;
+
+ /* Check that offsets have not been finalized yet. */
+ BFD_ASSERT (got->offset == (bfd_vma) -1);
+ /* Check that this entry is indeed unused. */
+ BFD_ASSERT (entry->u.s1.refcount == 0);
+
+ elf_m68k_remove_got_entry_type (got, entry->key_.type);
+
+ if (entry->key_.bfd != NULL)
+ got->local_n_slots -= elf_m68k_reloc_got_n_slots (entry->key_.type);
+
+ BFD_ASSERT (got->n_slots[R_32] >= got->local_n_slots);
+
+ htab_clear_slot (got->entries, (void **) entry_ptr);
+}
+
+/* Copy any information related to dynamic linking from a pre-existing
+ symbol to a newly created symbol. Also called to copy flags and
+ other back-end info to a weakdef, in which case the symbol is not
+ newly created and plt/got refcounts and dynamic indices should not
+ be copied. */
+
+static void
+elf_m68k_copy_indirect_symbol (struct bfd_link_info *info,
+ struct elf_link_hash_entry *_dir,
+ struct elf_link_hash_entry *_ind)
+{
+ struct elf_m68k_link_hash_entry *dir;
+ struct elf_m68k_link_hash_entry *ind;
+
+ _bfd_elf_link_hash_copy_indirect (info, _dir, _ind);
+
+ if (_ind->root.type != bfd_link_hash_indirect)
+ return;
+
+ dir = elf_m68k_hash_entry (_dir);
+ ind = elf_m68k_hash_entry (_ind);
+
+ /* Any absolute non-dynamic relocations against an indirect or weak
+ definition will be against the target symbol. */
+ _dir->non_got_ref |= _ind->non_got_ref;
+
+ /* We might have a direct symbol already having entries in the GOTs.
+ Update its key only in case indirect symbol has GOT entries and
+ assert that both indirect and direct symbols don't have GOT entries
+ at the same time. */
+ if (ind->got_entry_key != 0)
+ {
+ BFD_ASSERT (dir->got_entry_key == 0);
+ /* Assert that GOTs aren't partioned yet. */
+ BFD_ASSERT (ind->glist == NULL);
+
+ dir->got_entry_key = ind->got_entry_key;
+ ind->got_entry_key = 0;
+ }
+}
+
+/* Look through the relocs for a section during the first phase, and
+ allocate space in the global offset table or procedure linkage
+ table. */
+
+static bfd_boolean
+elf_m68k_check_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;
+ const Elf_Internal_Rela *rel;
+ const Elf_Internal_Rela *rel_end;
+ asection *sgot;
+ asection *srelgot;
+ asection *sreloc;
+ struct elf_m68k_got *got;
+
+ if (info->relocatable)
+ return TRUE;
+
+ dynobj = elf_hash_table (info)->dynobj;
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+ sym_hashes = elf_sym_hashes (abfd);
+
+ sgot = NULL;
+ srelgot = NULL;
+ sreloc = NULL;
+
+ got = 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];
+ 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;
+
+ /* PR15323, ref flags aren't set for references in the same
+ object. */
+ h->root.non_ir_ref = 1;
+ }
+
+ 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. */
+
+ /* Relative GOT relocations. */
+ case R_68K_GOT8O:
+ case R_68K_GOT16O:
+ case R_68K_GOT32O:
+ /* Fall through. */
+
+ /* TLS relocations. */
+ case R_68K_TLS_GD8:
+ case R_68K_TLS_GD16:
+ case R_68K_TLS_GD32:
+ case R_68K_TLS_LDM8:
+ case R_68K_TLS_LDM16:
+ case R_68K_TLS_LDM32:
+ case R_68K_TLS_IE8:
+ case R_68K_TLS_IE16:
+ case R_68K_TLS_IE32:
+
+ case R_68K_TLS_TPREL32:
+ case R_68K_TLS_DTPREL32:
+
+ if (ELF32_R_TYPE (rel->r_info) == R_68K_TLS_TPREL32
+ && info->shared)
+ /* Do the special chorus for libraries with static TLS. */
+ info->flags |= DF_STATIC_TLS;
+
+ /* 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_linker_section (dynobj, ".got");
+ BFD_ASSERT (sgot != NULL);
+ }
+
+ if (srelgot == NULL
+ && (h != NULL || info->shared))
+ {
+ srelgot = bfd_get_linker_section (dynobj, ".rela.got");
+ if (srelgot == NULL)
+ {
+ flagword flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS
+ | SEC_IN_MEMORY | SEC_LINKER_CREATED
+ | SEC_READONLY);
+ srelgot = bfd_make_section_anyway_with_flags (dynobj,
+ ".rela.got",
+ flags);
+ if (srelgot == NULL
+ || !bfd_set_section_alignment (dynobj, srelgot, 2))
+ return FALSE;
+ }
+ }
+
+ if (got == NULL)
+ {
+ struct elf_m68k_bfd2got_entry *bfd2got_entry;
+
+ bfd2got_entry
+ = elf_m68k_get_bfd2got_entry (elf_m68k_multi_got (info),
+ abfd, FIND_OR_CREATE, info);
+ if (bfd2got_entry == NULL)
+ return FALSE;
+
+ got = bfd2got_entry->got;
+ BFD_ASSERT (got != NULL);
+ }
+
+ {
+ struct elf_m68k_got_entry *got_entry;
+
+ /* Add entry to got. */
+ got_entry = elf_m68k_add_entry_to_got (got, h, abfd,
+ ELF32_R_TYPE (rel->r_info),
+ r_symndx, info);
+ if (got_entry == NULL)
+ return FALSE;
+
+ if (got_entry->u.s1.refcount == 1)
+ {
+ /* Make sure this symbol is output as a dynamic symbol. */
+ if (h != NULL
+ && h->dynindx == -1
+ && !h->forced_local)
+ {
+ if (!bfd_elf_link_record_dynamic_symbol (info, h))
+ return FALSE;
+ }
+ }
+ }
+
+ 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->needs_plt = 1;
+ 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
+ && !h->forced_local)
+ {
+ if (!bfd_elf_link_record_dynamic_symbol (info, h))
+ return FALSE;
+ }
+
+ h->needs_plt = 1;
+ 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->root.type == bfd_link_hash_defweak
+ || !h->def_regular)))
+ {
+ 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. */
+ h->plt.refcount++;
+ }
+ break;
+ }
+ /* Fall through. */
+ case R_68K_8:
+ case R_68K_16:
+ case R_68K_32:
+ /* We don't need to handle relocs into sections not going into
+ the "real" output. */
+ if ((sec->flags & SEC_ALLOC) == 0)
+ break;
+
+ 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. */
+ h->plt.refcount++;
+
+ if (info->executable)
+ /* This symbol needs a non-GOT reference. */
+ h->non_got_ref = 1;
+ }
+
+ /* If we are creating a shared library, we need to copy the
+ reloc into the shared library. */
+ if (info->shared)
+ {
+ /* 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)
+ {
+ sreloc = _bfd_elf_make_dynamic_reloc_section
+ (sec, dynobj, 2, abfd, /*rela?*/ TRUE);
+
+ if (sreloc == NULL)
+ return FALSE;
+ }
+
+ if (sec->flags & SEC_READONLY
+ /* Don't set DF_TEXTREL yet for PC relative
+ relocations, they might be discarded later. */
+ && !(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->flags |= DF_TEXTREL;
+
+ sreloc->size += sizeof (Elf32_External_Rela);
+
+ /* We count the number of PC relative relocations we have
+ entered for this symbol, so that we can discard them
+ again if, in the -Bsymbolic case, the symbol is later
+ defined by a regular object, or, in the normal shared
+ case, the symbol is forced to be local. 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)
+ {
+ struct elf_m68k_pcrel_relocs_copied *p;
+ struct elf_m68k_pcrel_relocs_copied **head;
+
+ if (h != NULL)
+ {
+ struct elf_m68k_link_hash_entry *eh
+ = elf_m68k_hash_entry (h);
+ head = &eh->pcrel_relocs_copied;
+ }
+ else
+ {
+ asection *s;
+ void *vpp;
+ Elf_Internal_Sym *isym;
+
+ isym = bfd_sym_from_r_symndx (&elf_m68k_hash_table (info)->sym_cache,
+ abfd, r_symndx);
+ if (isym == NULL)
+ return FALSE;
+
+ s = bfd_section_from_elf_index (abfd, isym->st_shndx);
+ if (s == NULL)
+ s = sec;
+
+ vpp = &elf_section_data (s)->local_dynrel;
+ head = (struct elf_m68k_pcrel_relocs_copied **) vpp;
+ }
+
+ for (p = *head; p != NULL; p = p->next)
+ if (p->section == sreloc)
+ break;
+
+ if (p == NULL)
+ {
+ p = ((struct elf_m68k_pcrel_relocs_copied *)
+ bfd_alloc (dynobj, (bfd_size_type) sizeof *p));
+ if (p == NULL)
+ return FALSE;
+ p->next = *head;
+ *head = 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_elf_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:
+ BFD_ASSERT (h != NULL);
+ if (h != NULL
+ && !bfd_elf_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 (asection *sec,
+ 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:
+ return NULL;
+ }
+
+ return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
+}
+
+/* Update the got entry reference counts for the section being removed. */
+
+static bfd_boolean
+elf_m68k_gc_sweep_hook (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;
+ const Elf_Internal_Rela *rel, *relend;
+ bfd *dynobj;
+ struct elf_m68k_got *got;
+
+ if (info->relocatable)
+ return TRUE;
+
+ dynobj = elf_hash_table (info)->dynobj;
+ if (dynobj == NULL)
+ return TRUE;
+
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+ sym_hashes = elf_sym_hashes (abfd);
+ got = NULL;
+
+ relend = relocs + sec->reloc_count;
+ for (rel = relocs; rel < relend; rel++)
+ {
+ unsigned long r_symndx;
+ struct elf_link_hash_entry *h = NULL;
+
+ r_symndx = ELF32_R_SYM (rel->r_info);
+ if (r_symndx >= symtab_hdr->sh_info)
+ {
+ 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;
+ }
+
+ 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;
+
+ /* FALLTHRU */
+ case R_68K_GOT8O:
+ case R_68K_GOT16O:
+ case R_68K_GOT32O:
+ /* Fall through. */
+
+ /* TLS relocations. */
+ case R_68K_TLS_GD8:
+ case R_68K_TLS_GD16:
+ case R_68K_TLS_GD32:
+ case R_68K_TLS_LDM8:
+ case R_68K_TLS_LDM16:
+ case R_68K_TLS_LDM32:
+ case R_68K_TLS_IE8:
+ case R_68K_TLS_IE16:
+ case R_68K_TLS_IE32:
+
+ case R_68K_TLS_TPREL32:
+ case R_68K_TLS_DTPREL32:
+
+ if (got == NULL)
+ {
+ got = elf_m68k_get_bfd2got_entry (elf_m68k_multi_got (info),
+ abfd, MUST_FIND, NULL)->got;
+ BFD_ASSERT (got != NULL);
+ }
+
+ {
+ struct elf_m68k_got_entry_key key_;
+ struct elf_m68k_got_entry **got_entry_ptr;
+ struct elf_m68k_got_entry *got_entry;
+
+ elf_m68k_init_got_entry_key (&key_, h, abfd, r_symndx,
+ ELF32_R_TYPE (rel->r_info));
+ got_entry_ptr = elf_m68k_find_got_entry_ptr (got, &key_);
+
+ got_entry = *got_entry_ptr;
+
+ if (got_entry->u.s1.refcount > 0)
+ {
+ --got_entry->u.s1.refcount;
+
+ if (got_entry->u.s1.refcount == 0)
+ /* We don't need the .got entry any more. */
+ elf_m68k_remove_got_entry (got, got_entry_ptr);
+ }
+ }
+ 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:
+ if (h != NULL)
+ {
+ if (h->plt.refcount > 0)
+ --h->plt.refcount;
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ return TRUE;
+}
+
+/* Return the type of PLT associated with OUTPUT_BFD. */
+
+static const struct elf_m68k_plt_info *
+elf_m68k_get_plt_info (bfd *output_bfd)
+{
+ unsigned int features;
+
+ features = bfd_m68k_mach_to_features (bfd_get_mach (output_bfd));
+ if (features & cpu32)
+ return &elf_cpu32_plt_info;
+ if (features & mcfisa_b)
+ return &elf_isab_plt_info;
+ if (features & mcfisa_c)
+ return &elf_isac_plt_info;
+ return &elf_m68k_plt_info;
+}
+
+/* This function is called after all the input files have been read,
+ and the input sections have been assigned to output sections.
+ It's a convenient place to determine the PLT style. */
+
+static bfd_boolean
+elf_m68k_always_size_sections (bfd *output_bfd, struct bfd_link_info *info)
+{
+ /* Bind input BFDs to GOTs and calculate sizes of .got and .rela.got
+ sections. */
+ if (!elf_m68k_partition_multi_got (info))
+ return FALSE;
+
+ elf_m68k_hash_table (info)->plt_info = elf_m68k_get_plt_info (output_bfd);
+ 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 bfd_boolean
+elf_m68k_adjust_dynamic_symbol (struct bfd_link_info *info,
+ struct elf_link_hash_entry *h)
+{
+ struct elf_m68k_link_hash_table *htab;
+ bfd *dynobj;
+ asection *s;
+
+ htab = elf_m68k_hash_table (info);
+ dynobj = elf_hash_table (info)->dynobj;
+
+ /* Make sure we know what is going on here. */
+ BFD_ASSERT (dynobj != NULL
+ && (h->needs_plt
+ || h->u.weakdef != NULL
+ || (h->def_dynamic
+ && h->ref_regular
+ && !h->def_regular)));
+
+ /* 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->needs_plt)
+ {
+ if ((h->plt.refcount <= 0
+ || SYMBOL_CALLS_LOCAL (info, h)
+ || (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
+ && h->root.type == bfd_link_hash_undefweak))
+ /* 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, or if all references were garbage collected. In
+ such a case, we don't actually need to build a procedure
+ linkage table, and we can just do a PCxx reloc instead. */
+ h->plt.offset = (bfd_vma) -1;
+ h->needs_plt = 0;
+ return TRUE;
+ }
+
+ /* Make sure this symbol is output as a dynamic symbol. */
+ if (h->dynindx == -1
+ && !h->forced_local)
+ {
+ if (! bfd_elf_link_record_dynamic_symbol (info, h))
+ return FALSE;
+ }
+
+ s = bfd_get_linker_section (dynobj, ".plt");
+ BFD_ASSERT (s != NULL);
+
+ /* If this is the first .plt entry, make room for the special
+ first entry. */
+ if (s->size == 0)
+ s->size = htab->plt_info->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->def_regular)
+ {
+ h->root.u.def.section = s;
+ h->root.u.def.value = s->size;
+ }
+
+ h->plt.offset = s->size;
+
+ /* Make room for this entry. */
+ s->size += htab->plt_info->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_linker_section (dynobj, ".got.plt");
+ BFD_ASSERT (s != NULL);
+ s->size += 4;
+
+ /* We also need to make an entry in the .rela.plt section. */
+ s = bfd_get_linker_section (dynobj, ".rela.plt");
+ BFD_ASSERT (s != NULL);
+ s->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->u.weakdef != NULL)
+ {
+ BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
+ || h->u.weakdef->root.type == bfd_link_hash_defweak);
+ h->root.u.def.section = h->u.weakdef->root.u.def.section;
+ h->root.u.def.value = h->u.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;
+
+ /* If there are no references to this symbol that do not use the
+ GOT, we don't need to generate a copy reloc. */
+ if (!h->non_got_ref)
+ 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_linker_section (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 && h->size != 0)
+ {
+ asection *srel;
+
+ srel = bfd_get_linker_section (dynobj, ".rela.bss");
+ BFD_ASSERT (srel != NULL);
+ srel->size += sizeof (Elf32_External_Rela);
+ h->needs_copy = 1;
+ }
+
+ return _bfd_elf_adjust_dynamic_copy (h, s);
+}
+
+/* Set the sizes of the dynamic sections. */
+
+static bfd_boolean
+elf_m68k_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
+ struct bfd_link_info *info)
+{
+ bfd *dynobj;
+ asection *s;
+ bfd_boolean plt;
+ bfd_boolean relocs;
+
+ 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->executable)
+ {
+ s = bfd_get_linker_section (dynobj, ".interp");
+ BFD_ASSERT (s != NULL);
+ s->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_linker_section (dynobj, ".rela.got");
+ if (s != NULL)
+ s->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.
+ For the normal shared case we discard the PC relative relocs
+ against symbols that have become local due to visibility changes.
+ 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)
+ elf_link_hash_traverse (elf_hash_table (info),
+ elf_m68k_discard_copies,
+ info);
+
+ /* 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;
+ for (s = dynobj->sections; s != NULL; s = s->next)
+ {
+ const char *name;
+
+ 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);
+
+ if (strcmp (name, ".plt") == 0)
+ {
+ /* Remember whether there is a PLT. */
+ plt = s->size != 0;
+ }
+ else if (CONST_STRNEQ (name, ".rela"))
+ {
+ if (s->size != 0)
+ {
+ relocs = 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 (! CONST_STRNEQ (name, ".got")
+ && strcmp (name, ".dynbss") != 0)
+ {
+ /* It's not one of our sections, so don't allocate space. */
+ continue;
+ }
+
+ if (s->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. */
+ s->flags |= SEC_EXCLUDE;
+ continue;
+ }
+
+ if ((s->flags & SEC_HAS_CONTENTS) == 0)
+ continue;
+
+ /* Allocate memory for the section contents. */
+ /* FIXME: This should be a call to bfd_alloc not bfd_zalloc.
+ Unused entries should be reclaimed before the section's contents
+ are written out, but at the moment this does not happen. Thus in
+ order to prevent writing out garbage, we initialise the section's
+ contents to zero. */
+ s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->size);
+ if (s->contents == NULL)
+ 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. */
+#define add_dynamic_entry(TAG, VAL) \
+ _bfd_elf_add_dynamic_entry (info, TAG, VAL)
+
+ if (info->executable)
+ {
+ if (!add_dynamic_entry (DT_DEBUG, 0))
+ return FALSE;
+ }
+
+ if (plt)
+ {
+ if (!add_dynamic_entry (DT_PLTGOT, 0)
+ || !add_dynamic_entry (DT_PLTRELSZ, 0)
+ || !add_dynamic_entry (DT_PLTREL, DT_RELA)
+ || !add_dynamic_entry (DT_JMPREL, 0))
+ return FALSE;
+ }
+
+ if (relocs)
+ {
+ if (!add_dynamic_entry (DT_RELA, 0)
+ || !add_dynamic_entry (DT_RELASZ, 0)
+ || !add_dynamic_entry (DT_RELAENT, sizeof (Elf32_External_Rela)))
+ return FALSE;
+ }
+
+ if ((info->flags & DF_TEXTREL) != 0)
+ {
+ if (!add_dynamic_entry (DT_TEXTREL, 0))
+ return FALSE;
+ }
+ }
+#undef add_dynamic_entry
+
+ return TRUE;
+}
+
+/* This function is called via elf_link_hash_traverse if we are
+ creating a shared object. In the -Bsymbolic case it discards the
+ space allocated to copy PC relative relocs against symbols which
+ are defined in regular objects. For the normal shared case, it
+ discards space for pc-relative relocs that have become local due to
+ symbol visibility changes. We allocated space for them in the
+ check_relocs routine, but we won't fill them in in the
+ relocate_section routine.
+
+ We also check whether any of the remaining relocations apply
+ against a readonly section, and set the DF_TEXTREL flag in this
+ case. */
+
+static bfd_boolean
+elf_m68k_discard_copies (struct elf_link_hash_entry *h,
+ void * inf)
+{
+ struct bfd_link_info *info = (struct bfd_link_info *) inf;
+ struct elf_m68k_pcrel_relocs_copied *s;
+
+ if (!SYMBOL_CALLS_LOCAL (info, h))
+ {
+ if ((info->flags & DF_TEXTREL) == 0)
+ {
+ /* Look for relocations against read-only sections. */
+ for (s = elf_m68k_hash_entry (h)->pcrel_relocs_copied;
+ s != NULL;
+ s = s->next)
+ if ((s->section->flags & SEC_READONLY) != 0)
+ {
+ info->flags |= DF_TEXTREL;
+ break;
+ }
+ }
+
+ /* Make sure undefined weak symbols are output as a dynamic symbol
+ in PIEs. */
+ if (h->non_got_ref
+ && h->root.type == bfd_link_hash_undefweak
+ && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
+ && h->dynindx == -1
+ && !h->forced_local)
+ {
+ if (! bfd_elf_link_record_dynamic_symbol (info, h))
+ return FALSE;
+ }
+
+ return TRUE;
+ }
+
+ for (s = elf_m68k_hash_entry (h)->pcrel_relocs_copied;
+ s != NULL;
+ s = s->next)
+ s->section->size -= s->count * sizeof (Elf32_External_Rela);
+
+ return TRUE;
+}
+
+
+/* Install relocation RELA. */
+
+static void
+elf_m68k_install_rela (bfd *output_bfd,
+ asection *srela,
+ Elf_Internal_Rela *rela)
+{
+ bfd_byte *loc;
+
+ loc = srela->contents;
+ loc += srela->reloc_count++ * sizeof (Elf32_External_Rela);
+ bfd_elf32_swap_reloca_out (output_bfd, rela, loc);
+}
+
+/* Find the base offsets for thread-local storage in this object,
+ for GD/LD and IE/LE respectively. */
+
+#define DTP_OFFSET 0x8000
+#define TP_OFFSET 0x7000
+
+static bfd_vma
+dtpoff_base (struct bfd_link_info *info)
+{
+ /* If tls_sec is NULL, we should have signalled an error already. */
+ if (elf_hash_table (info)->tls_sec == NULL)
+ return 0;
+ return elf_hash_table (info)->tls_sec->vma + DTP_OFFSET;
+}
+
+static bfd_vma
+tpoff_base (struct bfd_link_info *info)
+{
+ /* If tls_sec is NULL, we should have signalled an error already. */
+ if (elf_hash_table (info)->tls_sec == NULL)
+ return 0;
+ return elf_hash_table (info)->tls_sec->vma + TP_OFFSET;
+}
+
+/* Output necessary relocation to handle a symbol during static link.
+ This function is called from elf_m68k_relocate_section. */
+
+static void
+elf_m68k_init_got_entry_static (struct bfd_link_info *info,
+ bfd *output_bfd,
+ enum elf_m68k_reloc_type r_type,
+ asection *sgot,
+ bfd_vma got_entry_offset,
+ bfd_vma relocation)
+{
+ switch (elf_m68k_reloc_got_type (r_type))
+ {
+ case R_68K_GOT32O:
+ bfd_put_32 (output_bfd, relocation, sgot->contents + got_entry_offset);
+ break;
+
+ case R_68K_TLS_GD32:
+ /* We know the offset within the module,
+ put it into the second GOT slot. */
+ bfd_put_32 (output_bfd, relocation - dtpoff_base (info),
+ sgot->contents + got_entry_offset + 4);
+ /* FALLTHRU */
+
+ case R_68K_TLS_LDM32:
+ /* Mark it as belonging to module 1, the executable. */
+ bfd_put_32 (output_bfd, 1, sgot->contents + got_entry_offset);
+ break;
+
+ case R_68K_TLS_IE32:
+ bfd_put_32 (output_bfd, relocation - tpoff_base (info),
+ sgot->contents + got_entry_offset);
+ break;
+
+ default:
+ BFD_ASSERT (FALSE);
+ }
+}
+
+/* Output necessary relocation to handle a local symbol
+ during dynamic link.
+ This function is called either from elf_m68k_relocate_section
+ or from elf_m68k_finish_dynamic_symbol. */
+
+static void
+elf_m68k_init_got_entry_local_shared (struct bfd_link_info *info,
+ bfd *output_bfd,
+ enum elf_m68k_reloc_type r_type,
+ asection *sgot,
+ bfd_vma got_entry_offset,
+ bfd_vma relocation,
+ asection *srela)
+{
+ Elf_Internal_Rela outrel;
+
+ switch (elf_m68k_reloc_got_type (r_type))
+ {
+ case R_68K_GOT32O:
+ /* Emit RELATIVE relocation to initialize GOT slot
+ at run-time. */
+ outrel.r_info = ELF32_R_INFO (0, R_68K_RELATIVE);
+ outrel.r_addend = relocation;
+ break;
+
+ case R_68K_TLS_GD32:
+ /* We know the offset within the module,
+ put it into the second GOT slot. */
+ bfd_put_32 (output_bfd, relocation - dtpoff_base (info),
+ sgot->contents + got_entry_offset + 4);
+ /* FALLTHRU */
+
+ case R_68K_TLS_LDM32:
+ /* We don't know the module number,
+ create a relocation for it. */
+ outrel.r_info = ELF32_R_INFO (0, R_68K_TLS_DTPMOD32);
+ outrel.r_addend = 0;
+ break;
+
+ case R_68K_TLS_IE32:
+ /* Emit TPREL relocation to initialize GOT slot
+ at run-time. */
+ outrel.r_info = ELF32_R_INFO (0, R_68K_TLS_TPREL32);
+ outrel.r_addend = relocation - elf_hash_table (info)->tls_sec->vma;
+ break;
+
+ default:
+ BFD_ASSERT (FALSE);
+ }
+
+ /* Offset of the GOT entry. */
+ outrel.r_offset = (sgot->output_section->vma
+ + sgot->output_offset
+ + got_entry_offset);
+
+ /* Install one of the above relocations. */
+ elf_m68k_install_rela (output_bfd, srela, &outrel);
+
+ bfd_put_32 (output_bfd, outrel.r_addend, sgot->contents + got_entry_offset);
+}
+
+/* Relocate an M68K ELF section. */
+
+static bfd_boolean
+elf_m68k_relocate_section (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;
+ asection *sgot;
+ asection *splt;
+ asection *sreloc;
+ asection *srela;
+ struct elf_m68k_got *got;
+ 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);
+
+ sgot = NULL;
+ splt = NULL;
+ sreloc = NULL;
+ srela = NULL;
+
+ got = 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_boolean unresolved_reloc;
+ 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);
+
+ h = NULL;
+ sym = NULL;
+ sec = NULL;
+ unresolved_reloc = FALSE;
+
+ if (r_symndx < symtab_hdr->sh_info)
+ {
+ sym = local_syms + r_symndx;
+ sec = local_sections[r_symndx];
+ relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
+ }
+ else
+ {
+ bfd_boolean warned, ignored;
+
+ RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
+ r_symndx, symtab_hdr, sym_hashes,
+ h, sec, relocation,
+ unresolved_reloc, warned, ignored);
+ }
+
+ if (sec != NULL && discarded_section (sec))
+ RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+ rel, 1, relend, howto, 0, contents);
+
+ if (info->relocatable)
+ continue;
+
+ 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)
+ {
+ if (elf_m68k_hash_table (info)->local_gp_p)
+ {
+ bfd_vma sgot_output_offset;
+ bfd_vma got_offset;
+
+ if (sgot == NULL)
+ {
+ sgot = bfd_get_linker_section (dynobj, ".got");
+
+ if (sgot != NULL)
+ sgot_output_offset = sgot->output_offset;
+ else
+ /* In this case we have a reference to
+ _GLOBAL_OFFSET_TABLE_, but the GOT itself is
+ empty.
+ ??? Issue a warning? */
+ sgot_output_offset = 0;
+ }
+ else
+ sgot_output_offset = sgot->output_offset;
+
+ if (got == NULL)
+ {
+ struct elf_m68k_bfd2got_entry *bfd2got_entry;
+
+ bfd2got_entry
+ = elf_m68k_get_bfd2got_entry (elf_m68k_multi_got (info),
+ input_bfd, SEARCH, NULL);
+
+ if (bfd2got_entry != NULL)
+ {
+ got = bfd2got_entry->got;
+ BFD_ASSERT (got != NULL);
+
+ got_offset = got->offset;
+ }
+ else
+ /* In this case we have a reference to
+ _GLOBAL_OFFSET_TABLE_, but no other references
+ accessing any GOT entries.
+ ??? Issue a warning? */
+ got_offset = 0;
+ }
+ else
+ got_offset = got->offset;
+
+ /* Adjust GOT pointer to point to the GOT
+ assigned to input_bfd. */
+ rel->r_addend += sgot_output_offset + got_offset;
+ }
+ else
+ BFD_ASSERT (got == NULL || got->offset == 0);
+
+ break;
+ }
+ /* Fall through. */
+ case R_68K_GOT8O:
+ case R_68K_GOT16O:
+ case R_68K_GOT32O:
+
+ case R_68K_TLS_LDM32:
+ case R_68K_TLS_LDM16:
+ case R_68K_TLS_LDM8:
+
+ case R_68K_TLS_GD8:
+ case R_68K_TLS_GD16:
+ case R_68K_TLS_GD32:
+
+ case R_68K_TLS_IE8:
+ case R_68K_TLS_IE16:
+ case R_68K_TLS_IE32:
+
+ /* Relocation is the offset of the entry for this symbol in
+ the global offset table. */
+
+ {
+ struct elf_m68k_got_entry_key key_;
+ bfd_vma *off_ptr;
+ bfd_vma off;
+
+ if (sgot == NULL)
+ {
+ sgot = bfd_get_linker_section (dynobj, ".got");
+ BFD_ASSERT (sgot != NULL);
+ }
+
+ if (got == NULL)
+ {
+ got = elf_m68k_get_bfd2got_entry (elf_m68k_multi_got (info),
+ input_bfd, MUST_FIND,
+ NULL)->got;
+ BFD_ASSERT (got != NULL);
+ }
+
+ /* Get GOT offset for this symbol. */
+ elf_m68k_init_got_entry_key (&key_, h, input_bfd, r_symndx,
+ r_type);
+ off_ptr = &elf_m68k_get_got_entry (got, &key_, MUST_FIND,
+ NULL)->u.s2.offset;
+ off = *off_ptr;
+
+ /* 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
+ {
+ if (h != NULL
+ /* @TLSLDM relocations are bounded to the module, in
+ which the symbol is defined -- not to the symbol
+ itself. */
+ && elf_m68k_reloc_got_type (r_type) != R_68K_TLS_LDM32)
+ {
+ bfd_boolean dyn;
+
+ dyn = elf_hash_table (info)->dynamic_sections_created;
+ if (!WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h)
+ || (info->shared
+ && SYMBOL_REFERENCES_LOCAL (info, h))
+ || (ELF_ST_VISIBILITY (h->other)
+ && h->root.type == bfd_link_hash_undefweak))
+ {
+ /* 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. */
+
+ elf_m68k_init_got_entry_static (info,
+ output_bfd,
+ r_type,
+ sgot,
+ off,
+ relocation);
+
+ *off_ptr |= 1;
+ }
+ else
+ unresolved_reloc = FALSE;
+ }
+ else if (info->shared) /* && h == NULL */
+ /* Process local symbol during dynamic link. */
+ {
+ if (srela == NULL)
+ {
+ srela = bfd_get_linker_section (dynobj, ".rela.got");
+ BFD_ASSERT (srela != NULL);
+ }
+
+ elf_m68k_init_got_entry_local_shared (info,
+ output_bfd,
+ r_type,
+ sgot,
+ off,
+ relocation,
+ srela);
+
+ *off_ptr |= 1;
+ }
+ else /* h == NULL && !info->shared */
+ {
+ elf_m68k_init_got_entry_static (info,
+ output_bfd,
+ r_type,
+ sgot,
+ off,
+ relocation);
+
+ *off_ptr |= 1;
+ }
+ }
+
+ /* We don't use elf_m68k_reloc_got_type in the condition below
+ because this is the only place where difference between
+ R_68K_GOTx and R_68K_GOTxO relocations matters. */
+ if (r_type == R_68K_GOT32O
+ || r_type == R_68K_GOT16O
+ || r_type == R_68K_GOT8O
+ || elf_m68k_reloc_got_type (r_type) == R_68K_TLS_GD32
+ || elf_m68k_reloc_got_type (r_type) == R_68K_TLS_LDM32
+ || elf_m68k_reloc_got_type (r_type) == R_68K_TLS_IE32)
+ {
+ /* GOT pointer is adjusted to point to the start/middle
+ of local GOT. Adjust the offset accordingly. */
+ BFD_ASSERT (elf_m68k_hash_table (info)->use_neg_got_offsets_p
+ || off >= got->offset);
+
+ if (elf_m68k_hash_table (info)->local_gp_p)
+ relocation = off - got->offset;
+ else
+ {
+ BFD_ASSERT (got->offset == 0);
+ relocation = sgot->output_offset + off;
+ }
+
+ /* This relocation does not use the addend. */
+ rel->r_addend = 0;
+ }
+ else
+ relocation = (sgot->output_section->vma + sgot->output_offset
+ + off);
+ }
+ break;
+
+ case R_68K_TLS_LDO32:
+ case R_68K_TLS_LDO16:
+ case R_68K_TLS_LDO8:
+ relocation -= dtpoff_base (info);
+ break;
+
+ case R_68K_TLS_LE32:
+ case R_68K_TLS_LE16:
+ case R_68K_TLS_LE8:
+ if (info->shared && !info->pie)
+ {
+ (*_bfd_error_handler)
+ (_("%B(%A+0x%lx): R_68K_TLS_LE32 relocation not permitted "
+ "in shared object"),
+ input_bfd, input_section, (long) rel->r_offset, howto->name);
+
+ return FALSE;
+ }
+ else
+ relocation -= tpoff_base (info);
+
+ 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_linker_section (dynobj, ".plt");
+ BFD_ASSERT (splt != NULL);
+ }
+
+ relocation = (splt->output_section->vma
+ + splt->output_offset
+ + h->plt.offset);
+ unresolved_reloc = FALSE;
+ 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_linker_section (dynobj, ".plt");
+ BFD_ASSERT (splt != NULL);
+ }
+
+ relocation = h->plt.offset;
+ unresolved_reloc = FALSE;
+
+ /* This relocation does not use the addend. */
+ rel->r_addend = 0;
+
+ break;
+
+ case R_68K_8:
+ case R_68K_16:
+ case R_68K_32:
+ case R_68K_PC8:
+ case R_68K_PC16:
+ case R_68K_PC32:
+ if (info->shared
+ && r_symndx != STN_UNDEF
+ && (input_section->flags & SEC_ALLOC) != 0
+ && (h == NULL
+ || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
+ || h->root.type != bfd_link_hash_undefweak)
+ && ((r_type != R_68K_PC8
+ && r_type != R_68K_PC16
+ && r_type != R_68K_PC32)
+ || !SYMBOL_CALLS_LOCAL (info, h)))
+ {
+ Elf_Internal_Rela outrel;
+ bfd_byte *loc;
+ bfd_boolean skip, relocate;
+
+ /* When generating a shared object, these relocations
+ are copied into the output file to be resolved at run
+ time. */
+
+ skip = FALSE;
+ relocate = FALSE;
+
+ outrel.r_offset =
+ _bfd_elf_section_offset (output_bfd, info, input_section,
+ rel->r_offset);
+ if (outrel.r_offset == (bfd_vma) -1)
+ skip = TRUE;
+ else if (outrel.r_offset == (bfd_vma) -2)
+ skip = TRUE, relocate = TRUE;
+ outrel.r_offset += (input_section->output_section->vma
+ + input_section->output_offset);
+
+ if (skip)
+ memset (&outrel, 0, sizeof outrel);
+ else if (h != NULL
+ && h->dynindx != -1
+ && (r_type == R_68K_PC8
+ || r_type == R_68K_PC16
+ || r_type == R_68K_PC32
+ || !info->shared
+ || !info->symbolic
+ || !h->def_regular))
+ {
+ outrel.r_info = ELF32_R_INFO (h->dynindx, r_type);
+ outrel.r_addend = rel->r_addend;
+ }
+ else
+ {
+ /* This symbol is local, or marked to become local. */
+ outrel.r_addend = relocation + rel->r_addend;
+
+ if (r_type == R_68K_32)
+ {
+ relocate = TRUE;
+ outrel.r_info = ELF32_R_INFO (0, R_68K_RELATIVE);
+ }
+ else
+ {
+ long indx;
+
+ if (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;
+
+ /* We are turning this relocation into one
+ against a section symbol. It would be
+ proper to subtract the symbol's value,
+ osec->vma, from the emitted reloc addend,
+ but ld.so expects buggy relocs. */
+ osec = sec->output_section;
+ indx = elf_section_data (osec)->dynindx;
+ if (indx == 0)
+ {
+ struct elf_link_hash_table *htab;
+ htab = elf_hash_table (info);
+ osec = htab->text_index_section;
+ indx = elf_section_data (osec)->dynindx;
+ }
+ BFD_ASSERT (indx != 0);
+ }
+
+ outrel.r_info = ELF32_R_INFO (indx, r_type);
+ }
+ }
+
+ sreloc = elf_section_data (input_section)->sreloc;
+ if (sreloc == NULL)
+ abort ();
+
+ loc = sreloc->contents;
+ loc += sreloc->reloc_count++ * sizeof (Elf32_External_Rela);
+ bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
+
+ /* 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;
+ }
+
+ /* Dynamic relocs are not propagated for SEC_DEBUGGING sections
+ because such sections are not SEC_ALLOC and thus ld.so will
+ not process them. */
+ if (unresolved_reloc
+ && !((input_section->flags & SEC_DEBUGGING) != 0
+ && h->def_dynamic)
+ && _bfd_elf_section_offset (output_bfd, info, input_section,
+ rel->r_offset) != (bfd_vma) -1)
+ {
+ (*_bfd_error_handler)
+ (_("%B(%A+0x%lx): unresolvable %s relocation against symbol `%s'"),
+ input_bfd,
+ input_section,
+ (long) rel->r_offset,
+ howto->name,
+ h->root.root.string);
+ return FALSE;
+ }
+
+ if (r_symndx != STN_UNDEF
+ && r_type != R_68K_NONE
+ && (h == NULL
+ || h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak))
+ {
+ char sym_type;
+
+ sym_type = (sym != NULL) ? ELF32_ST_TYPE (sym->st_info) : h->type;
+
+ if (elf_m68k_reloc_tls_p (r_type) != (sym_type == STT_TLS))
+ {
+ 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);
+ }
+
+ (*_bfd_error_handler)
+ ((sym_type == STT_TLS
+ ? _("%B(%A+0x%lx): %s used with TLS symbol %s")
+ : _("%B(%A+0x%lx): %s used with non-TLS symbol %s")),
+ input_bfd,
+ input_section,
+ (long) rel->r_offset,
+ howto->name,
+ name);
+ }
+ }
+
+ 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 *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 (r == bfd_reloc_overflow)
+ {
+ if (!(info->callbacks->reloc_overflow
+ (info, (h ? &h->root : NULL), name, howto->name,
+ (bfd_vma) 0, input_bfd, input_section,
+ rel->r_offset)))
+ return FALSE;
+ }
+ else
+ {
+ (*_bfd_error_handler)
+ (_("%B(%A+0x%lx): reloc against `%s': error %d"),
+ input_bfd, input_section,
+ (long) rel->r_offset, name, (int) r);
+ return FALSE;
+ }
+ }
+ }
+
+ return TRUE;
+}
+
+/* Install an M_68K_PC32 relocation against VALUE at offset OFFSET
+ into section SEC. */
+
+static void
+elf_m68k_install_pc32 (asection *sec, bfd_vma offset, bfd_vma value)
+{
+ /* Make VALUE PC-relative. */
+ value -= sec->output_section->vma + offset;
+
+ /* Apply any in-place addend. */
+ value += bfd_get_32 (sec->owner, sec->contents + offset);
+
+ bfd_put_32 (sec->owner, value, sec->contents + offset);
+}
+
+/* Finish up dynamic symbol handling. We set the contents of various
+ dynamic sections here. */
+
+static bfd_boolean
+elf_m68k_finish_dynamic_symbol (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)
+ {
+ const struct elf_m68k_plt_info *plt_info;
+ asection *splt;
+ asection *sgot;
+ asection *srela;
+ bfd_vma plt_index;
+ bfd_vma got_offset;
+ Elf_Internal_Rela rela;
+ bfd_byte *loc;
+
+ /* This symbol has an entry in the procedure linkage table. Set
+ it up. */
+
+ BFD_ASSERT (h->dynindx != -1);
+
+ plt_info = elf_m68k_hash_table (info)->plt_info;
+ splt = bfd_get_linker_section (dynobj, ".plt");
+ sgot = bfd_get_linker_section (dynobj, ".got.plt");
+ srela = bfd_get_linker_section (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_info->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;
+
+ memcpy (splt->contents + h->plt.offset,
+ plt_info->symbol_entry,
+ plt_info->size);
+
+ elf_m68k_install_pc32 (splt, h->plt.offset + plt_info->symbol_relocs.got,
+ (sgot->output_section->vma
+ + sgot->output_offset
+ + got_offset));
+
+ bfd_put_32 (output_bfd, plt_index * sizeof (Elf32_External_Rela),
+ splt->contents
+ + h->plt.offset
+ + plt_info->symbol_resolve_entry + 2);
+
+ elf_m68k_install_pc32 (splt, h->plt.offset + plt_info->symbol_relocs.plt,
+ splt->output_section->vma);
+
+ /* Fill in the entry in the global offset table. */
+ bfd_put_32 (output_bfd,
+ (splt->output_section->vma
+ + splt->output_offset
+ + h->plt.offset
+ + plt_info->symbol_resolve_entry),
+ 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;
+ loc = srela->contents + plt_index * sizeof (Elf32_External_Rela);
+ bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
+
+ if (!h->def_regular)
+ {
+ /* Mark the symbol as undefined, rather than as defined in
+ the .plt section. Leave the value alone. */
+ sym->st_shndx = SHN_UNDEF;
+ }
+ }
+
+ if (elf_m68k_hash_entry (h)->glist != NULL)
+ {
+ asection *sgot;
+ asection *srela;
+ struct elf_m68k_got_entry *got_entry;
+
+ /* This symbol has an entry in the global offset table. Set it
+ up. */
+
+ sgot = bfd_get_linker_section (dynobj, ".got");
+ srela = bfd_get_linker_section (dynobj, ".rela.got");
+ BFD_ASSERT (sgot != NULL && srela != NULL);
+
+ got_entry = elf_m68k_hash_entry (h)->glist;
+
+ while (got_entry != NULL)
+ {
+ enum elf_m68k_reloc_type r_type;
+ bfd_vma got_entry_offset;
+
+ r_type = got_entry->key_.type;
+ got_entry_offset = got_entry->u.s2.offset &~ (bfd_vma) 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 already have been
+ initialized in the relocate_section function. */
+ if (info->shared
+ && SYMBOL_REFERENCES_LOCAL (info, h))
+ {
+ bfd_vma relocation;
+
+ relocation = bfd_get_signed_32 (output_bfd,
+ (sgot->contents
+ + got_entry_offset));
+
+ /* Undo TP bias. */
+ switch (elf_m68k_reloc_got_type (r_type))
+ {
+ case R_68K_GOT32O:
+ case R_68K_TLS_LDM32:
+ break;
+
+ case R_68K_TLS_GD32:
+ /* The value for this relocation is actually put in
+ the second GOT slot. */
+ relocation = bfd_get_signed_32 (output_bfd,
+ (sgot->contents
+ + got_entry_offset + 4));
+ relocation += dtpoff_base (info);
+ break;
+
+ case R_68K_TLS_IE32:
+ relocation += tpoff_base (info);
+ break;
+
+ default:
+ BFD_ASSERT (FALSE);
+ }
+
+ elf_m68k_init_got_entry_local_shared (info,
+ output_bfd,
+ r_type,
+ sgot,
+ got_entry_offset,
+ relocation,
+ srela);
+ }
+ else
+ {
+ Elf_Internal_Rela rela;
+
+ /* Put zeros to GOT slots that will be initialized
+ at run-time. */
+ {
+ bfd_vma n_slots;
+
+ n_slots = elf_m68k_reloc_got_n_slots (got_entry->key_.type);
+ while (n_slots--)
+ bfd_put_32 (output_bfd, (bfd_vma) 0,
+ (sgot->contents + got_entry_offset
+ + 4 * n_slots));
+ }
+
+ rela.r_addend = 0;
+ rela.r_offset = (sgot->output_section->vma
+ + sgot->output_offset
+ + got_entry_offset);
+
+ switch (elf_m68k_reloc_got_type (r_type))
+ {
+ case R_68K_GOT32O:
+ rela.r_info = ELF32_R_INFO (h->dynindx, R_68K_GLOB_DAT);
+ elf_m68k_install_rela (output_bfd, srela, &rela);
+ break;
+
+ case R_68K_TLS_GD32:
+ rela.r_info = ELF32_R_INFO (h->dynindx, R_68K_TLS_DTPMOD32);
+ elf_m68k_install_rela (output_bfd, srela, &rela);
+
+ rela.r_offset += 4;
+ rela.r_info = ELF32_R_INFO (h->dynindx, R_68K_TLS_DTPREL32);
+ elf_m68k_install_rela (output_bfd, srela, &rela);
+ break;
+
+ case R_68K_TLS_IE32:
+ rela.r_info = ELF32_R_INFO (h->dynindx, R_68K_TLS_TPREL32);
+ elf_m68k_install_rela (output_bfd, srela, &rela);
+ break;
+
+ default:
+ BFD_ASSERT (FALSE);
+ break;
+ }
+ }
+
+ got_entry = got_entry->u.s2.next;
+ }
+ }
+
+ if (h->needs_copy)
+ {
+ asection *s;
+ Elf_Internal_Rela rela;
+ bfd_byte *loc;
+
+ /* 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_linker_section (dynobj, ".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;
+ loc = s->contents + s->reloc_count++ * sizeof (Elf32_External_Rela);
+ bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
+ }
+
+ return TRUE;
+}
+
+/* Finish up the dynamic sections. */
+
+static bfd_boolean
+elf_m68k_finish_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
+{
+ bfd *dynobj;
+ asection *sgot;
+ asection *sdyn;
+
+ dynobj = elf_hash_table (info)->dynobj;
+
+ sgot = bfd_get_linker_section (dynobj, ".got.plt");
+ BFD_ASSERT (sgot != NULL);
+ sdyn = bfd_get_linker_section (dynobj, ".dynamic");
+
+ if (elf_hash_table (info)->dynamic_sections_created)
+ {
+ asection *splt;
+ Elf32_External_Dyn *dyncon, *dynconend;
+
+ splt = bfd_get_linker_section (dynobj, ".plt");
+ BFD_ASSERT (splt != NULL && sdyn != NULL);
+
+ dyncon = (Elf32_External_Dyn *) sdyn->contents;
+ dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->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);
+ dyn.d_un.d_val = s->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)
+ dyn.d_un.d_val -= s->size;
+ bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
+ break;
+ }
+ }
+
+ /* Fill in the first entry in the procedure linkage table. */
+ if (splt->size > 0)
+ {
+ const struct elf_m68k_plt_info *plt_info;
+
+ plt_info = elf_m68k_hash_table (info)->plt_info;
+ memcpy (splt->contents, plt_info->plt0_entry, plt_info->size);
+
+ elf_m68k_install_pc32 (splt, plt_info->plt0_relocs.got4,
+ (sgot->output_section->vma
+ + sgot->output_offset
+ + 4));
+
+ elf_m68k_install_pc32 (splt, plt_info->plt0_relocs.got8,
+ (sgot->output_section->vma
+ + sgot->output_offset
+ + 8));
+
+ elf_section_data (splt->output_section)->this_hdr.sh_entsize
+ = plt_info->size;
+ }
+ }
+
+ /* Fill in the first three entries in the global offset table. */
+ if (sgot->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;
+}
+
+/* Given a .data section and a .emreloc in-memory section, store
+ relocation information into the .emreloc 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. */
+
+bfd_boolean
+bfd_m68k_elf32_create_embedded_relocs (abfd, info, datasec, relsec, errmsg)
+ bfd *abfd;
+ struct bfd_link_info *info;
+ asection *datasec;
+ asection *relsec;
+ char **errmsg;
+{
+ Elf_Internal_Shdr *symtab_hdr;
+ Elf_Internal_Sym *isymbuf = NULL;
+ Elf_Internal_Rela *internal_relocs = NULL;
+ Elf_Internal_Rela *irel, *irelend;
+ bfd_byte *p;
+ bfd_size_type amt;
+
+ BFD_ASSERT (! info->relocatable);
+
+ *errmsg = NULL;
+
+ if (datasec->reloc_count == 0)
+ return TRUE;
+
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+
+ /* Get a copy of the native relocations. */
+ internal_relocs = (_bfd_elf_link_read_relocs
+ (abfd, datasec, NULL, (Elf_Internal_Rela *) NULL,
+ info->keep_memory));
+ if (internal_relocs == NULL)
+ goto error_return;
+
+ amt = (bfd_size_type) datasec->reloc_count * 12;
+ relsec->contents = (bfd_byte *) bfd_alloc (abfd, amt);
+ if (relsec->contents == NULL)
+ goto error_return;
+
+ p = relsec->contents;
+
+ irelend = internal_relocs + datasec->reloc_count;
+ for (irel = internal_relocs; irel < irelend; irel++, p += 12)
+ {
+ asection *targetsec;
+
+ /* We are going to write a four byte longword into the runtime
+ reloc section. The longword will be the address in the data
+ section which must be relocated. It is followed by the name
+ of the target section NUL-padded or truncated to 8
+ characters. */
+
+ /* We can only relocate absolute longword relocs at run time. */
+ if (ELF32_R_TYPE (irel->r_info) != (int) R_68K_32)
+ {
+ *errmsg = _("unsupported reloc type");
+ bfd_set_error (bfd_error_bad_value);
+ goto error_return;
+ }
+
+ /* Get the target section referred to by the reloc. */
+ if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
+ {
+ /* A local symbol. */
+ Elf_Internal_Sym *isym;
+
+ /* Read this BFD's local symbols if we haven't done so already. */
+ if (isymbuf == NULL)
+ {
+ isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
+ if (isymbuf == NULL)
+ isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
+ symtab_hdr->sh_info, 0,
+ NULL, NULL, NULL);
+ if (isymbuf == NULL)
+ goto error_return;
+ }
+
+ isym = isymbuf + ELF32_R_SYM (irel->r_info);
+ targetsec = bfd_section_from_elf_index (abfd, isym->st_shndx);
+ }
+ 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)
+ targetsec = h->root.u.def.section;
+ else
+ targetsec = NULL;
+ }
+
+ bfd_put_32 (abfd, irel->r_offset + datasec->output_offset, p);
+ memset (p + 4, 0, 8);
+ if (targetsec != NULL)
+ strncpy ((char *) p + 4, targetsec->output_section->name, 8);
+ }
+
+ if (isymbuf != NULL && symtab_hdr->contents != (unsigned char *) isymbuf)
+ free (isymbuf);
+ if (internal_relocs != NULL
+ && elf_section_data (datasec)->relocs != internal_relocs)
+ free (internal_relocs);
+ return TRUE;
+
+error_return:
+ if (isymbuf != NULL && symtab_hdr->contents != (unsigned char *) isymbuf)
+ free (isymbuf);
+ if (internal_relocs != NULL
+ && elf_section_data (datasec)->relocs != internal_relocs)
+ free (internal_relocs);
+ return FALSE;
+}
+
+/* Set target options. */
+
+void
+bfd_elf_m68k_set_target_options (struct bfd_link_info *info, int got_handling)
+{
+ struct elf_m68k_link_hash_table *htab;
+ bfd_boolean use_neg_got_offsets_p;
+ bfd_boolean allow_multigot_p;
+ bfd_boolean local_gp_p;
+
+ switch (got_handling)
+ {
+ case 0:
+ /* --got=single. */
+ local_gp_p = FALSE;
+ use_neg_got_offsets_p = FALSE;
+ allow_multigot_p = FALSE;
+ break;
+
+ case 1:
+ /* --got=negative. */
+ local_gp_p = TRUE;
+ use_neg_got_offsets_p = TRUE;
+ allow_multigot_p = FALSE;
+ break;
+
+ case 2:
+ /* --got=multigot. */
+ local_gp_p = TRUE;
+ use_neg_got_offsets_p = TRUE;
+ allow_multigot_p = TRUE;
+ break;
+
+ default:
+ BFD_ASSERT (FALSE);
+ return;
+ }
+
+ htab = elf_m68k_hash_table (info);
+ if (htab != NULL)
+ {
+ htab->local_gp_p = local_gp_p;
+ htab->use_neg_got_offsets_p = use_neg_got_offsets_p;
+ htab->allow_multigot_p = allow_multigot_p;
+ }
+}
+
+static enum elf_reloc_type_class
+elf32_m68k_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ const asection *rel_sec ATTRIBUTE_UNUSED,
+ const Elf_Internal_Rela *rela)
+{
+ switch ((int) ELF32_R_TYPE (rela->r_info))
+ {
+ case R_68K_RELATIVE:
+ return reloc_class_relative;
+ case R_68K_JMP_SLOT:
+ return reloc_class_plt;
+ case R_68K_COPY:
+ return reloc_class_copy;
+ default:
+ return reloc_class_normal;
+ }
+}
+
+/* Return address for Ith PLT stub in section PLT, for relocation REL
+ or (bfd_vma) -1 if it should not be included. */
+
+static bfd_vma
+elf_m68k_plt_sym_val (bfd_vma i, const asection *plt,
+ const arelent *rel ATTRIBUTE_UNUSED)
+{
+ return plt->vma + (i + 1) * elf_m68k_get_plt_info (plt->owner)->size;
+}
+
+/* Support for core dump NOTE sections. */
+
+static bfd_boolean
+elf_m68k_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
+{
+ int offset;
+ size_t size;
+
+ switch (note->descsz)
+ {
+ default:
+ return FALSE;
+
+ case 154: /* Linux/m68k */
+ /* pr_cursig */
+ elf_tdata (abfd)->core->signal = bfd_get_16 (abfd, note->descdata + 12);
+
+ /* pr_pid */
+ elf_tdata (abfd)->core->lwpid = bfd_get_32 (abfd, note->descdata + 22);
+
+ /* pr_reg */
+ offset = 70;
+ size = 80;
+
+ break;
+ }
+
+ /* Make a ".reg/999" section. */
+ return _bfd_elfcore_make_pseudosection (abfd, ".reg",
+ size, note->descpos + offset);
+}
+
+static bfd_boolean
+elf_m68k_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
+{
+ switch (note->descsz)
+ {
+ default:
+ return FALSE;
+
+ case 124: /* Linux/m68k elf_prpsinfo. */
+ elf_tdata (abfd)->core->pid
+ = bfd_get_32 (abfd, note->descdata + 12);
+ elf_tdata (abfd)->core->program
+ = _bfd_elfcore_strndup (abfd, note->descdata + 28, 16);
+ elf_tdata (abfd)->core->command
+ = _bfd_elfcore_strndup (abfd, note->descdata + 44, 80);
+ }
+
+ /* 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 (n > 0 && command[n - 1] == ' ')
+ command[n - 1] = '\0';
+ }
+
+ return TRUE;
+}
+
+/* Hook called by the linker routine which adds symbols from an object
+ file. */
+
+static bfd_boolean
+elf_m68k_add_symbol_hook (bfd *abfd,
+ struct bfd_link_info *info,
+ Elf_Internal_Sym *sym,
+ const char **namep ATTRIBUTE_UNUSED,
+ flagword *flagsp ATTRIBUTE_UNUSED,
+ asection **secp ATTRIBUTE_UNUSED,
+ bfd_vma *valp ATTRIBUTE_UNUSED)
+{
+ if ((ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC
+ || ELF_ST_BIND (sym->st_info) == STB_GNU_UNIQUE)
+ && (abfd->flags & DYNAMIC) == 0
+ && bfd_get_flavour (info->output_bfd) == bfd_target_elf_flavour)
+ elf_tdata (info->output_bfd)->has_gnu_symbols = TRUE;
+
+ return TRUE;
+}
+
+#define TARGET_BIG_SYM m68k_elf32_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_elf_final_link
+
+#define elf_backend_check_relocs elf_m68k_check_relocs
+#define elf_backend_always_size_sections \
+ elf_m68k_always_size_sections
+#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_final_write_processing elf_m68k_final_write_processing
+#define elf_backend_init_index_section _bfd_elf_init_1_index_section
+#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_copy_indirect_symbol elf_m68k_copy_indirect_symbol
+#define bfd_elf32_bfd_merge_private_bfd_data \
+ elf32_m68k_merge_private_bfd_data
+#define bfd_elf32_bfd_set_private_flags \
+ elf32_m68k_set_private_flags
+#define bfd_elf32_bfd_print_private_bfd_data \
+ elf32_m68k_print_private_bfd_data
+#define elf_backend_reloc_type_class elf32_m68k_reloc_type_class
+#define elf_backend_plt_sym_val elf_m68k_plt_sym_val
+#define elf_backend_object_p elf32_m68k_object_p
+#define elf_backend_grok_prstatus elf_m68k_grok_prstatus
+#define elf_backend_grok_psinfo elf_m68k_grok_psinfo
+#define elf_backend_add_symbol_hook elf_m68k_add_symbol_hook
+
+#define elf_backend_can_gc_sections 1
+#define elf_backend_can_refcount 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_rela_normal 1
+
+#include "elf32-target.h"
diff --git a/bfd/elf32-m88k.c b/bfd/elf32-m88k.c
new file mode 100644
index 0000000..487cc0c
--- /dev/null
+++ b/bfd/elf32-m88k.c
@@ -0,0 +1,38 @@
+/* Motorola 88k-specific support for 32-bit ELF
+ Copyright (C) 1993-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.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 m88k_elf32_vec
+#define TARGET_BIG_NAME "elf32-m88k"
+#define ELF_ARCH bfd_arch_m88k
+#define ELF_MACHINE_CODE EM_88K
+#define ELF_MAXPAGESIZE 1 /* FIXME: This number is wrong, It should be the page size in bytes. */
+#define bfd_elf32_bfd_reloc_type_lookup bfd_default_reloc_type_lookup
+#define bfd_elf32_bfd_reloc_name_lookup _bfd_norelocs_bfd_reloc_name_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 0000000..903d379
--- /dev/null
+++ b/bfd/elf32-mcore.c
@@ -0,0 +1,675 @@
+/* Motorola MCore specific support for 32-bit ELF
+ Copyright (C) 1994-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+
+/* This file is based on a preliminary RCE ELF ABI. The
+ information may not match the final RCE ELF ABI. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "bfdlink.h"
+#include "libbfd.h"
+#include "elf-bfd.h"
+#include "elf/mcore.h"
+#include <assert.h>
+
+/* RELA relocs are used here... */
+
+/* Function to set whether a module needs the -mrelocatable bit set. */
+
+static bfd_boolean
+mcore_elf_set_private_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;
+}
+
+/* Merge backend specific data from an object file to the output
+ object file when linking. */
+
+static bfd_boolean
+mcore_elf_merge_private_bfd_data (bfd * ibfd, bfd * obfd)
+{
+ flagword old_flags;
+ flagword new_flags;
+
+ /* Check if we have the same endianness. */
+ if (! _bfd_generic_verify_endian_match (ibfd, obfd))
+ 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
+ {
+ /* FIXME */
+ }
+
+ return TRUE;
+}
+
+/* Don't pretend we can deal with unsupported relocs. */
+
+static bfd_reloc_status_type
+mcore_elf_unsupported_reloc (bfd * abfd,
+ arelent * reloc_entry,
+ asymbol * symbol ATTRIBUTE_UNUSED,
+ void * data ATTRIBUTE_UNUSED,
+ asection * input_section ATTRIBUTE_UNUSED,
+ bfd * output_bfd ATTRIBUTE_UNUSED,
+ char ** error_message ATTRIBUTE_UNUSED)
+{
+ BFD_ASSERT (reloc_entry->howto != (reloc_howto_type *)0);
+
+ _bfd_error_handler (_("%B: Relocation %s (%d) is not currently supported.\n"),
+ abfd,
+ reloc_entry->howto->name,
+ reloc_entry->howto->type);
+
+ return bfd_reloc_notsupported;
+}
+
+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) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ NULL, /* special_function */
+ "R_MCORE_NONE", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ FALSE), /* 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 compatibility 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 */
+
+ HOWTO (R_MCORE_RELATIVE, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ NULL, /* special_function */
+ "R_MCORE_RELATIVE", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* 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 (void)
+{
+ 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 (bfd * abfd ATTRIBUTE_UNUSED,
+ 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;
+ case BFD_RELOC_RVA: mcore_reloc = R_MCORE_RELATIVE; break;
+ default:
+ return 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];
+};
+
+static reloc_howto_type *
+mcore_elf_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ const char *r_name)
+{
+ unsigned int i;
+
+ for (i = 0;
+ i < sizeof (mcore_elf_howto_raw) / sizeof (mcore_elf_howto_raw[0]);
+ i++)
+ if (mcore_elf_howto_raw[i].name != NULL
+ && strcasecmp (mcore_elf_howto_raw[i].name, r_name) == 0)
+ return &mcore_elf_howto_raw[i];
+
+ return NULL;
+}
+
+/* Set the howto pointer for a RCE ELF reloc. */
+
+static void
+mcore_elf_info_to_howto (bfd * abfd ATTRIBUTE_UNUSED,
+ arelent * cache_ptr,
+ Elf_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)];
+}
+
+/* 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
+ relocatable 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 relocatable 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 bfd_boolean
+mcore_elf_relocate_section (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;
+ bfd_boolean ret = TRUE;
+
+#ifdef DEBUG
+ _bfd_error_handler
+ ("mcore_elf_relocate_section called for %B section %A, %ld relocations%s",
+ input_bfd,
+ input_section,
+ (long) input_section->reloc_count,
+ (info->relocatable) ? " (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 = NULL;
+ reloc_howto_type * howto;
+ bfd_vma relocation;
+ Elf_Internal_Sym * sym = NULL;
+ unsigned long r_symndx;
+ struct elf_link_hash_entry * h = NULL;
+ unsigned short oldinst = 0;
+
+ /* Unknown relocation handling. */
+ if ((unsigned) r_type >= (unsigned) R_MCORE_max
+ || ! mcore_elf_howto_table [(int)r_type])
+ {
+ _bfd_error_handler (_("%B: Unknown relocation type %d\n"),
+ 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);
+
+ /* Complain about known relocation that are not yet supported. */
+ if (howto->special_function == mcore_elf_unsupported_reloc)
+ {
+ _bfd_error_handler (_("%B: Relocation %s (%d) is not currently supported.\n"),
+ 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 = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
+ addend = rel->r_addend;
+ }
+ else
+ {
+ bfd_boolean unresolved_reloc, warned, ignored;
+
+ RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
+ r_symndx, symtab_hdr, sym_hashes,
+ h, sec, relocation,
+ unresolved_reloc, warned, ignored);
+ }
+
+ if (sec != NULL && discarded_section (sec))
+ RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+ rel, 1, relend, howto, 0, contents);
+
+ if (info->relocatable)
+ continue;
+
+ switch (r_type)
+ {
+ default:
+ break;
+
+ case R_MCORE_PCRELJSR_IMM11BY2:
+ oldinst = bfd_get_16 (input_bfd, contents + offset);
+#define MCORE_INST_BSR 0xF800
+ bfd_put_16 (input_bfd, (bfd_vma) 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, (bfd_vma) 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 = NULL;
+ 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, (h ? &h->root : NULL), 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 (asection *sec,
+ 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:
+ return NULL;
+ }
+
+ return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
+}
+
+/* Update the got entry reference counts for the section being removed. */
+
+static bfd_boolean
+mcore_elf_gc_sweep_hook (bfd * abfd ATTRIBUTE_UNUSED,
+ struct bfd_link_info * info ATTRIBUTE_UNUSED,
+ asection * sec ATTRIBUTE_UNUSED,
+ const Elf_Internal_Rela * relocs ATTRIBUTE_UNUSED)
+{
+ 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 bfd_boolean
+mcore_elf_check_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;
+ const Elf_Internal_Rela * rel;
+ const Elf_Internal_Rela * rel_end;
+
+ if (info->relocatable)
+ return TRUE;
+
+ symtab_hdr = & elf_tdata (abfd)->symtab_hdr;
+ sym_hashes = elf_sym_hashes (abfd);
+
+ 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];
+ 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;
+
+ /* PR15323, ref flags aren't set for references in the same
+ object. */
+ h->root.non_ir_ref = 1;
+ }
+
+ 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_elf_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:
+ BFD_ASSERT (h != NULL);
+ if (h != NULL
+ && !bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
+ return FALSE;
+ break;
+ }
+ }
+
+ return TRUE;
+}
+
+static const struct bfd_elf_special_section mcore_elf_special_sections[]=
+{
+ { STRING_COMMA_LEN (".ctors"), -2, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE },
+ { STRING_COMMA_LEN (".dtors"), -2, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE },
+ { NULL, 0, 0, 0, 0 }
+};
+
+#define TARGET_BIG_SYM mcore_elf32_be_vec
+#define TARGET_BIG_NAME "elf32-mcore-big"
+#define TARGET_LITTLE_SYM mcore_elf32_le_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_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 bfd_elf32_bfd_reloc_name_lookup mcore_elf_reloc_name_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_special_sections mcore_elf_special_sections
+
+#define elf_backend_can_gc_sections 1
+#define elf_backend_rela_normal 1
+
+#include "elf32-target.h"
diff --git a/bfd/elf32-mep.c b/bfd/elf32-mep.c
new file mode 100644
index 0000000..548359f
--- /dev/null
+++ b/bfd/elf32-mep.c
@@ -0,0 +1,769 @@
+/* MeP-specific support for 32-bit ELF.
+ Copyright (C) 2001-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+#include "elf-bfd.h"
+#include "elf/mep.h"
+#include "libiberty.h"
+
+/* Forward declarations. */
+
+/* Private relocation functions. */
+
+#define MEPREL(type, size, bits, right, left, pcrel, overflow, mask) \
+ {(unsigned)type, right, size, bits, pcrel, left, overflow, mep_reloc, #type, FALSE, 0, mask, 0 }
+
+#define N complain_overflow_dont
+#define S complain_overflow_signed
+#define U complain_overflow_unsigned
+
+static bfd_reloc_status_type mep_reloc (bfd *, arelent *, struct bfd_symbol *,
+ void *, asection *, bfd *, char **);
+
+static reloc_howto_type mep_elf_howto_table [] =
+{
+ /* type, size, bits, leftshift, rightshift, pcrel, OD/OS/OU, mask. */
+ MEPREL (R_MEP_NONE, 0, 0, 0, 0, 0, N, 0),
+ MEPREL (R_RELC, 0, 0, 0, 0, 0, N, 0),
+ /* MEPRELOC:HOWTO */
+ /* This section generated from bfd/mep-relocs.pl from include/elf/mep.h. */
+ MEPREL (R_MEP_8, 0, 8, 0, 0, 0, U, 0xff),
+ MEPREL (R_MEP_16, 1, 16, 0, 0, 0, U, 0xffff),
+ MEPREL (R_MEP_32, 2, 32, 0, 0, 0, U, 0xffffffff),
+ MEPREL (R_MEP_PCREL8A2, 1, 8, 1, 1, 1, S, 0x00fe),
+ MEPREL (R_MEP_PCREL12A2,1, 12, 1, 1, 1, S, 0x0ffe),
+ MEPREL (R_MEP_PCREL17A2,2, 17, 0, 1, 1, S, 0x0000ffff),
+ MEPREL (R_MEP_PCREL24A2,2, 24, 0, 1, 1, S, 0x07f0ffff),
+ MEPREL (R_MEP_PCABS24A2,2, 24, 0, 1, 0, U, 0x07f0ffff),
+ MEPREL (R_MEP_LOW16, 2, 16, 0, 0, 0, N, 0x0000ffff),
+ MEPREL (R_MEP_HI16U, 2, 32, 0,16, 0, N, 0x0000ffff),
+ MEPREL (R_MEP_HI16S, 2, 32, 0,16, 0, N, 0x0000ffff),
+ MEPREL (R_MEP_GPREL, 2, 16, 0, 0, 0, S, 0x0000ffff),
+ MEPREL (R_MEP_TPREL, 2, 16, 0, 0, 0, S, 0x0000ffff),
+ MEPREL (R_MEP_TPREL7, 1, 7, 0, 0, 0, U, 0x007f),
+ MEPREL (R_MEP_TPREL7A2, 1, 7, 1, 1, 0, U, 0x007e),
+ MEPREL (R_MEP_TPREL7A4, 1, 7, 2, 2, 0, U, 0x007c),
+ MEPREL (R_MEP_UIMM24, 2, 24, 0, 0, 0, U, 0x00ffffff),
+ MEPREL (R_MEP_ADDR24A4, 2, 24, 0, 2, 0, U, 0x00fcffff),
+ MEPREL (R_MEP_GNU_VTINHERIT,1, 0,16,32, 0, N, 0x0000),
+ MEPREL (R_MEP_GNU_VTENTRY,1, 0,16,32, 0, N, 0x0000),
+ /* MEPRELOC:END */
+};
+
+#define VALID_MEP_RELOC(N) ((N) >= 0 \
+ && (N) < ARRAY_SIZE (mep_elf_howto_table)
+
+#undef N
+#undef S
+#undef U
+
+static bfd_reloc_status_type
+mep_reloc
+ (bfd * abfd ATTRIBUTE_UNUSED,
+ arelent * reloc_entry ATTRIBUTE_UNUSED,
+ struct bfd_symbol * symbol ATTRIBUTE_UNUSED,
+ void * data ATTRIBUTE_UNUSED,
+ asection * input_section ATTRIBUTE_UNUSED,
+ bfd * output_bfd ATTRIBUTE_UNUSED,
+ char ** error_message ATTRIBUTE_UNUSED)
+{
+ return bfd_reloc_ok;
+}
+
+
+
+#define BFD_RELOC_MEP_NONE BFD_RELOC_NONE
+#if defined (__STDC__) || defined (ALMOST_STDC) || defined (HAVE_STRINGIZE)
+#define MAP(n) case BFD_RELOC_MEP_##n: type = R_MEP_##n; break
+#else
+#define MAP(n) case BFD_RELOC_MEP_/**/n: type = R_MEP_/**/n; break
+#endif
+
+static reloc_howto_type *
+mep_reloc_type_lookup
+ (bfd * abfd ATTRIBUTE_UNUSED,
+ bfd_reloc_code_real_type code)
+{
+ unsigned int type = 0;
+
+ switch (code)
+ {
+ MAP(NONE);
+ case BFD_RELOC_8:
+ type = R_MEP_8;
+ break;
+ case BFD_RELOC_16:
+ type = R_MEP_16;
+ break;
+ case BFD_RELOC_32:
+ type = R_MEP_32;
+ break;
+ case BFD_RELOC_VTABLE_ENTRY:
+ type = R_MEP_GNU_VTENTRY;
+ break;
+ case BFD_RELOC_VTABLE_INHERIT:
+ type = R_MEP_GNU_VTINHERIT;
+ break;
+ case BFD_RELOC_RELC:
+ type = R_RELC;
+ break;
+
+ /* MEPRELOC:MAP */
+ /* This section generated from bfd/mep-relocs.pl from include/elf/mep.h. */
+ MAP(8);
+ MAP(16);
+ MAP(32);
+ MAP(PCREL8A2);
+ MAP(PCREL12A2);
+ MAP(PCREL17A2);
+ MAP(PCREL24A2);
+ MAP(PCABS24A2);
+ MAP(LOW16);
+ MAP(HI16U);
+ MAP(HI16S);
+ MAP(GPREL);
+ MAP(TPREL);
+ MAP(TPREL7);
+ MAP(TPREL7A2);
+ MAP(TPREL7A4);
+ MAP(UIMM24);
+ MAP(ADDR24A4);
+ MAP(GNU_VTINHERIT);
+ MAP(GNU_VTENTRY);
+ /* MEPRELOC:END */
+
+ default:
+ /* Pacify gcc -Wall. */
+ (*_bfd_error_handler) (_("mep: no reloc for code %d"), code);
+ return NULL;
+ }
+
+ if (mep_elf_howto_table[type].type != type)
+ {
+ (*_bfd_error_handler) (_("MeP: howto %d has type %d"),
+ type, mep_elf_howto_table[type].type);
+ abort ();
+ }
+
+ return mep_elf_howto_table + type;
+}
+
+#undef MAP
+
+static reloc_howto_type *
+mep_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, const char *r_name)
+{
+ unsigned int i;
+
+ for (i = 0;
+ i < sizeof (mep_elf_howto_table) / sizeof (mep_elf_howto_table[0]);
+ i++)
+ if (mep_elf_howto_table[i].name != NULL
+ && strcasecmp (mep_elf_howto_table[i].name, r_name) == 0)
+ return &mep_elf_howto_table[i];
+
+ return NULL;
+}
+
+/* Perform a single relocation. */
+
+static struct bfd_link_info *mep_info;
+static int warn_tp = 0, warn_sda = 0;
+
+static bfd_vma
+mep_lookup_global
+ (char * name,
+ bfd_vma ofs,
+ bfd_vma * cache,
+ int * warn)
+{
+ struct bfd_link_hash_entry *h;
+
+ if (*cache || *warn)
+ return *cache;
+
+ h = bfd_link_hash_lookup (mep_info->hash, name, FALSE, FALSE, TRUE);
+ if (h == 0 || h->type != bfd_link_hash_defined)
+ {
+ *warn = ofs + 1;
+ return 0;
+ }
+ *cache = (h->u.def.value
+ + h->u.def.section->output_section->vma
+ + h->u.def.section->output_offset);
+ return *cache;
+}
+
+static bfd_vma
+mep_tpoff_base (bfd_vma ofs)
+{
+ static bfd_vma cache = 0;
+ return mep_lookup_global ("__tpbase", ofs, &cache, &warn_tp);
+}
+
+static bfd_vma
+mep_sdaoff_base (bfd_vma ofs)
+{
+ static bfd_vma cache = 0;
+ return mep_lookup_global ("__sdabase", ofs, &cache, &warn_sda);
+}
+
+static bfd_reloc_status_type
+mep_final_link_relocate
+ (reloc_howto_type * howto,
+ bfd * input_bfd,
+ asection * input_section,
+ bfd_byte * contents,
+ Elf_Internal_Rela * rel,
+ bfd_vma relocation)
+{
+ unsigned long u;
+ long s;
+ unsigned char *byte;
+ bfd_vma pc;
+ bfd_reloc_status_type r = bfd_reloc_ok;
+ int e2, e4;
+
+ if (bfd_big_endian (input_bfd))
+ {
+ e2 = 0;
+ e4 = 0;
+ }
+ else
+ {
+ e2 = 1;
+ e4 = 3;
+ }
+
+ pc = (input_section->output_section->vma
+ + input_section->output_offset
+ + rel->r_offset);
+
+ s = relocation + rel->r_addend;
+
+ byte = (unsigned char *)contents + rel->r_offset;
+
+ if (howto->type == R_MEP_PCREL24A2
+ && s == 0
+ && pc >= 0x800000)
+ {
+ /* This is an unreachable branch to an undefined weak function.
+ Silently ignore it, since the opcode can't do that but should
+ never be executed anyway. */
+ return bfd_reloc_ok;
+ }
+
+ if (howto->pc_relative)
+ s -= pc;
+
+ u = (unsigned long) s;
+
+ switch (howto->type)
+ {
+ /* MEPRELOC:APPLY */
+ /* This section generated from bfd/mep-relocs.pl from include/elf/mep.h. */
+ case R_MEP_8: /* 76543210 */
+ if (u > 255) r = bfd_reloc_overflow;
+ byte[0] = (u & 0xff);
+ break;
+ case R_MEP_16: /* fedcba9876543210 */
+ if (u > 65535) r = bfd_reloc_overflow;
+ byte[0^e2] = ((u >> 8) & 0xff);
+ byte[1^e2] = (u & 0xff);
+ break;
+ case R_MEP_32: /* vutsrqponmlkjihgfedcba9876543210 */
+ byte[0^e4] = ((u >> 24) & 0xff);
+ byte[1^e4] = ((u >> 16) & 0xff);
+ byte[2^e4] = ((u >> 8) & 0xff);
+ byte[3^e4] = (u & 0xff);
+ break;
+ case R_MEP_PCREL8A2: /* --------7654321- */
+ if (-128 > s || s > 127) r = bfd_reloc_overflow;
+ byte[1^e2] = (byte[1^e2] & 0x01) | (s & 0xfe);
+ break;
+ case R_MEP_PCREL12A2: /* ----ba987654321- */
+ if (-2048 > s || s > 2047) r = bfd_reloc_overflow;
+ byte[0^e2] = (byte[0^e2] & 0xf0) | ((s >> 8) & 0x0f);
+ byte[1^e2] = (byte[1^e2] & 0x01) | (s & 0xfe);
+ break;
+ case R_MEP_PCREL17A2: /* ----------------gfedcba987654321 */
+ if (-65536 > s || s > 65535) r = bfd_reloc_overflow;
+ byte[2^e2] = ((s >> 9) & 0xff);
+ byte[3^e2] = ((s >> 1) & 0xff);
+ break;
+ case R_MEP_PCREL24A2: /* -----7654321----nmlkjihgfedcba98 */
+ if (-8388608 > s || s > 8388607) r = bfd_reloc_overflow;
+ byte[0^e2] = (byte[0^e2] & 0xf8) | ((s >> 5) & 0x07);
+ byte[1^e2] = (byte[1^e2] & 0x0f) | ((s << 3) & 0xf0);
+ byte[2^e2] = ((s >> 16) & 0xff);
+ byte[3^e2] = ((s >> 8) & 0xff);
+ break;
+ case R_MEP_PCABS24A2: /* -----7654321----nmlkjihgfedcba98 */
+ if (u > 16777215) r = bfd_reloc_overflow;
+ byte[0^e2] = (byte[0^e2] & 0xf8) | ((u >> 5) & 0x07);
+ byte[1^e2] = (byte[1^e2] & 0x0f) | ((u << 3) & 0xf0);
+ byte[2^e2] = ((u >> 16) & 0xff);
+ byte[3^e2] = ((u >> 8) & 0xff);
+ break;
+ case R_MEP_LOW16: /* ----------------fedcba9876543210 */
+ byte[2^e2] = ((u >> 8) & 0xff);
+ byte[3^e2] = (u & 0xff);
+ break;
+ case R_MEP_HI16U: /* ----------------vutsrqponmlkjihg */
+ byte[2^e2] = ((u >> 24) & 0xff);
+ byte[3^e2] = ((u >> 16) & 0xff);
+ break;
+ case R_MEP_HI16S: /* ----------------vutsrqponmlkjihg */
+ if (s & 0x8000)
+ s += 0x10000;
+ byte[2^e2] = ((s >> 24) & 0xff);
+ byte[3^e2] = ((s >> 16) & 0xff);
+ break;
+ case R_MEP_GPREL: /* ----------------fedcba9876543210 */
+ s -= mep_sdaoff_base(rel->r_offset);
+ if (-32768 > s || s > 32767) r = bfd_reloc_overflow;
+ byte[2^e2] = ((s >> 8) & 0xff);
+ byte[3^e2] = (s & 0xff);
+ break;
+ case R_MEP_TPREL: /* ----------------fedcba9876543210 */
+ s -= mep_tpoff_base(rel->r_offset);
+ if (-32768 > s || s > 32767) r = bfd_reloc_overflow;
+ byte[2^e2] = ((s >> 8) & 0xff);
+ byte[3^e2] = (s & 0xff);
+ break;
+ case R_MEP_TPREL7: /* ---------6543210 */
+ u -= mep_tpoff_base(rel->r_offset);
+ if (u > 127) r = bfd_reloc_overflow;
+ byte[1^e2] = (byte[1^e2] & 0x80) | (u & 0x7f);
+ break;
+ case R_MEP_TPREL7A2: /* ---------654321- */
+ u -= mep_tpoff_base(rel->r_offset);
+ if (u > 127) r = bfd_reloc_overflow;
+ byte[1^e2] = (byte[1^e2] & 0x81) | (u & 0x7e);
+ break;
+ case R_MEP_TPREL7A4: /* ---------65432-- */
+ u -= mep_tpoff_base(rel->r_offset);
+ if (u > 127) r = bfd_reloc_overflow;
+ byte[1^e2] = (byte[1^e2] & 0x83) | (u & 0x7c);
+ break;
+ case R_MEP_UIMM24: /* --------76543210nmlkjihgfedcba98 */
+ if (u > 16777215) r = bfd_reloc_overflow;
+ byte[1^e2] = (u & 0xff);
+ byte[2^e2] = ((u >> 16) & 0xff);
+ byte[3^e2] = ((u >> 8) & 0xff);
+ break;
+ case R_MEP_ADDR24A4: /* --------765432--nmlkjihgfedcba98 */
+ if (u > 16777215) r = bfd_reloc_overflow;
+ byte[1^e2] = (byte[1^e2] & 0x03) | (u & 0xfc);
+ byte[2^e2] = ((u >> 16) & 0xff);
+ byte[3^e2] = ((u >> 8) & 0xff);
+ break;
+ case R_MEP_GNU_VTINHERIT: /* ---------------- */
+ break;
+ case R_MEP_GNU_VTENTRY: /* ---------------- */
+ break;
+ /* MEPRELOC:END */
+ default:
+ abort ();
+ }
+
+ return r;
+}
+
+/* Set the howto pointer for a MEP ELF reloc. */
+
+static void
+mep_info_to_howto_rela
+ (bfd * abfd ATTRIBUTE_UNUSED,
+ arelent * cache_ptr,
+ Elf_Internal_Rela * dst)
+{
+ unsigned int r_type;
+
+ r_type = ELF32_R_TYPE (dst->r_info);
+ cache_ptr->howto = & mep_elf_howto_table [r_type];
+}
+
+/* Relocate a MEP 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 relocatable
+ 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 relocatable 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 bfd_boolean
+mep_elf_relocate_section
+ (bfd * output_bfd ATTRIBUTE_UNUSED,
+ 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;
+
+ mep_info = info;
+
+ 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);
+ r_symndx = ELF32_R_SYM (rel->r_info);
+ howto = mep_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 = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
+
+ 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;
+ }
+ else
+ {
+ bfd_boolean warned, unresolved_reloc, ignored;
+
+ RELOC_FOR_GLOBAL_SYMBOL(info, input_bfd, input_section, rel,
+ r_symndx, symtab_hdr, sym_hashes,
+ h, sec, relocation,
+ unresolved_reloc, warned, ignored);
+
+ name = h->root.root.string;
+ }
+
+ if (sec != NULL && discarded_section (sec))
+ RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+ rel, 1, relend, howto, 0, contents);
+
+ if (info->relocatable)
+ continue;
+
+ if (r_type == R_RELC)
+ r = bfd_elf_perform_complex_relocation (input_bfd, input_section,
+ contents, rel, relocation);
+ else
+ r = mep_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, (h ? &h->root : NULL), 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, TRUE);
+ 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;
+ }
+ }
+
+ if (warn_tp)
+ info->callbacks->undefined_symbol
+ (info, "__tpbase", input_bfd, input_section, warn_tp-1, TRUE);
+ if (warn_sda)
+ info->callbacks->undefined_symbol
+ (info, "__sdabase", input_bfd, input_section, warn_sda-1, TRUE);
+ if (warn_sda || warn_tp)
+ return FALSE;
+
+ return TRUE;
+}
+
+/* Function to set the ELF flag bits. */
+
+static bfd_boolean
+mep_elf_set_private_flags (bfd * abfd,
+ flagword flags)
+{
+ elf_elfheader (abfd)->e_flags = flags;
+ elf_flags_init (abfd) = TRUE;
+ return TRUE;
+}
+
+/* Merge backend specific data from an object file to the output
+ object file when linking. */
+
+static bfd_boolean
+mep_elf_merge_private_bfd_data (bfd * ibfd, bfd * obfd)
+{
+ static bfd *last_ibfd = 0;
+ flagword old_flags, new_flags;
+ flagword old_partial, new_partial;
+
+ /* Check if we have the same endianness. */
+ if (_bfd_generic_verify_endian_match (ibfd, obfd) == FALSE)
+ return FALSE;
+
+ new_flags = elf_elfheader (ibfd)->e_flags;
+ old_flags = elf_elfheader (obfd)->e_flags;
+
+#ifdef DEBUG
+ _bfd_error_handler ("%B: old_flags = 0x%.8lx, new_flags = 0x%.8lx, init = %s",
+ ibfd, old_flags, new_flags, elf_flags_init (obfd) ? "yes" : "no");
+#endif
+
+ /* First call, no flags set. */
+ if (!elf_flags_init (obfd))
+ {
+ elf_flags_init (obfd) = TRUE;
+ old_flags = new_flags;
+ }
+ else if ((new_flags | old_flags) & EF_MEP_LIBRARY)
+ {
+ /* Non-library flags trump library flags. The choice doesn't really
+ matter if both OLD_FLAGS and NEW_FLAGS have EF_MEP_LIBRARY set. */
+ if (old_flags & EF_MEP_LIBRARY)
+ old_flags = new_flags;
+ }
+ else
+ {
+ /* Make sure they're for the same mach. Allow upgrade from the "mep"
+ mach. */
+ new_partial = (new_flags & EF_MEP_CPU_MASK);
+ old_partial = (old_flags & EF_MEP_CPU_MASK);
+ if (new_partial == old_partial)
+ ;
+ else if (new_partial == EF_MEP_CPU_MEP)
+ ;
+ else if (old_partial == EF_MEP_CPU_MEP)
+ old_flags = (old_flags & ~EF_MEP_CPU_MASK) | new_partial;
+ else
+ {
+ _bfd_error_handler (_("%B and %B are for different cores"), last_ibfd, ibfd);
+ bfd_set_error (bfd_error_invalid_target);
+ return FALSE;
+ }
+
+ /* Make sure they're for the same me_module. Allow basic config to
+ mix with any other. */
+ new_partial = (new_flags & EF_MEP_INDEX_MASK);
+ old_partial = (old_flags & EF_MEP_INDEX_MASK);
+ if (new_partial == old_partial)
+ ;
+ else if (new_partial == 0)
+ ;
+ else if (old_partial == 0)
+ old_flags = (old_flags & ~EF_MEP_INDEX_MASK) | new_partial;
+ else
+ {
+ _bfd_error_handler (_("%B and %B are for different configurations"), last_ibfd, ibfd);
+ bfd_set_error (bfd_error_invalid_target);
+ return FALSE;
+ }
+ }
+
+ elf_elfheader (obfd)->e_flags = old_flags;
+ last_ibfd = ibfd;
+ return TRUE;
+}
+
+/* This will be edited by the MeP configration tool. */
+static const char * config_names[] =
+{
+ "basic"
+ /* start-mepcfgtool */
+ ,"default"
+ /* end-mepcfgtool */
+};
+
+static const char * core_names[] =
+{
+ "MeP", "MeP-c2", "MeP-c3", "MeP-h1"
+};
+
+static bfd_boolean
+mep_elf_print_private_bfd_data (bfd * abfd, void * ptr)
+{
+ FILE * file = (FILE *) ptr;
+ flagword flags, partial_flags;
+
+ BFD_ASSERT (abfd != NULL && ptr != NULL);
+
+ /* Print normal ELF private data. */
+ _bfd_elf_print_private_bfd_data (abfd, ptr);
+
+ flags = elf_elfheader (abfd)->e_flags;
+ fprintf (file, _("private flags = 0x%lx"), (unsigned long) flags);
+
+ partial_flags = (flags & EF_MEP_CPU_MASK) >> 24;
+ if (partial_flags < ARRAY_SIZE (core_names))
+ fprintf (file, " core: %s", core_names[(long)partial_flags]);
+
+ partial_flags = flags & EF_MEP_INDEX_MASK;
+ if (partial_flags < ARRAY_SIZE (config_names))
+ fprintf (file, " me_module: %s", config_names[(long)partial_flags]);
+
+ fputc ('\n', file);
+
+ return TRUE;
+}
+
+/* Return the machine subcode from the ELF e_flags header. */
+
+static int
+elf32_mep_machine (bfd * abfd)
+{
+ switch (elf_elfheader (abfd)->e_flags & EF_MEP_CPU_MASK)
+ {
+ default: break;
+ case EF_MEP_CPU_C2: return bfd_mach_mep;
+ case EF_MEP_CPU_C3: return bfd_mach_mep;
+ case EF_MEP_CPU_C4: return bfd_mach_mep;
+ case EF_MEP_CPU_C5: return bfd_mach_mep_c5;
+ case EF_MEP_CPU_H1: return bfd_mach_mep_h1;
+ }
+
+ return bfd_mach_mep;
+}
+
+static bfd_boolean
+mep_elf_object_p (bfd * abfd)
+{
+ bfd_default_set_arch_mach (abfd, bfd_arch_mep, elf32_mep_machine (abfd));
+ return TRUE;
+}
+
+static bfd_boolean
+mep_elf_section_flags (flagword * flags, const Elf_Internal_Shdr * hdr)
+{
+ if (hdr->sh_flags & SHF_MEP_VLIW)
+ * flags |= SEC_MEP_VLIW;
+ return TRUE;
+}
+
+static bfd_boolean
+mep_elf_fake_sections (bfd * abfd ATTRIBUTE_UNUSED,
+ Elf_Internal_Shdr * hdr,
+ asection * sec)
+{
+ if (sec->flags & SEC_MEP_VLIW)
+ hdr->sh_flags |= SHF_MEP_VLIW;
+ return TRUE;
+}
+
+
+#define ELF_ARCH bfd_arch_mep
+#define ELF_MACHINE_CODE EM_CYGNUS_MEP
+#define ELF_MAXPAGESIZE 0x1000
+
+#define TARGET_BIG_SYM mep_elf32_vec
+#define TARGET_BIG_NAME "elf32-mep"
+
+#define TARGET_LITTLE_SYM mep_elf32_le_vec
+#define TARGET_LITTLE_NAME "elf32-mep-little"
+
+#define elf_info_to_howto_rel NULL
+#define elf_info_to_howto mep_info_to_howto_rela
+#define elf_backend_relocate_section mep_elf_relocate_section
+#define elf_backend_object_p mep_elf_object_p
+#define elf_backend_section_flags mep_elf_section_flags
+#define elf_backend_fake_sections mep_elf_fake_sections
+
+#define bfd_elf32_bfd_reloc_type_lookup mep_reloc_type_lookup
+#define bfd_elf32_bfd_reloc_name_lookup mep_reloc_name_lookup
+#define bfd_elf32_bfd_set_private_flags mep_elf_set_private_flags
+#define bfd_elf32_bfd_merge_private_bfd_data mep_elf_merge_private_bfd_data
+#define bfd_elf32_bfd_print_private_bfd_data mep_elf_print_private_bfd_data
+
+#define elf_backend_rela_normal 1
+
+#include "elf32-target.h"
diff --git a/bfd/elf32-metag.c b/bfd/elf32-metag.c
new file mode 100644
index 0000000..47ca5de
--- /dev/null
+++ b/bfd/elf32-metag.c
@@ -0,0 +1,4329 @@
+/* Meta support for 32-bit ELF
+ Copyright (C) 2013-2014 Free Software Foundation, Inc.
+ Contributed by Imagination Technologies Ltd.
+
+ This file is part of BFD, the Binary File Descriptor library.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+#include "elf-bfd.h"
+#include "elf32-metag.h"
+#include "elf/metag.h"
+
+#define GOT_ENTRY_SIZE 4
+#define ELF_DYNAMIC_INTERPRETER "/lib/ld-uClibc.so.0"
+
+/* ABI version:
+ 0 - original
+ 1 - with GOT offset */
+#define METAG_ELF_ABI_VERSION 1
+
+static const unsigned int plt0_entry[] =
+ {
+ 0x02000005, /* MOVT D0Re0, #HI(GOT+4) */
+ 0x02000000, /* ADD D0Re0, D0Re0, #LO(GOT+4) */
+ 0xb70001e3, /* SETL [A0StP++], D0Re0, D1Re0 */
+ 0xc600012a, /* GETD PC, [D0Re0+#4] */
+ 0xa0fffffe /* NOP */
+ };
+
+static const unsigned int plt0_pic_entry[] =
+ {
+ 0x82900001, /* ADDT A0.2, CPC0, #0 */
+ 0x82100000, /* ADD A0.2, A0.2, #0 */
+ 0xa3100c20, /* MOV D0Re0, A0.2 */
+ 0xb70001e3, /* SETL [A0StP++], D0Re0, D1Re0 */
+ 0xc600012a, /* GETD PC, [D0Re0+#4] */
+ };
+
+static const unsigned int plt_entry[] =
+ {
+ 0x82100005, /* MOVT A0.2, #HI(GOT+off) */
+ 0x82100000, /* ADD A0.2, A0.2, #LO(GOT+off) */
+ 0xc600806a, /* GETD PC, [A0.2] */
+ 0x03000004, /* MOV D1Re0, #LO(offset) */
+ 0xa0000000 /* B PLT0 */
+ };
+
+static const unsigned int plt_pic_entry[] =
+ {
+ 0x82900001, /* ADDT A0.2, CPC0, #HI(GOT+off) */
+ 0x82100000, /* ADD A0.2, A0.2, #LO(GOT+off) */
+ 0xc600806a, /* GETD PC, [A0.2] */
+ 0x03000004, /* MOV D1Re0, #LO(offset) */
+ 0xa0000000 /* B PLT0 */
+ };
+
+/* Variable names follow a coding style.
+ Please follow this (Apps Hungarian) style:
+
+ Structure/Variable Prefix
+ elf_link_hash_table "etab"
+ elf_link_hash_entry "eh"
+
+ elf_metag_link_hash_table "htab"
+ elf_metag_link_hash_entry "hh"
+
+ bfd_link_hash_table "btab"
+ bfd_link_hash_entry "bh"
+
+ bfd_hash_table containing stubs "bstab"
+ elf_metag_stub_hash_entry "hsh"
+
+ elf_metag_dyn_reloc_entry "hdh"
+
+ Always remember to use GNU Coding Style. */
+
+#define PLT_ENTRY_SIZE sizeof(plt_entry)
+
+static reloc_howto_type elf_metag_howto_table[] =
+{
+ /* High order 16 bit absolute. */
+ HOWTO (R_METAG_HIADDR16, /* type */
+ 16, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 3, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_METAG_HIADDR16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0007fff8, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Low order 16 bit absolute. */
+ HOWTO (R_METAG_LOADDR16, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 3, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_METAG_LOADDR16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0007fff8, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* 32 bit absolute. */
+ HOWTO (R_METAG_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_METAG_ADDR32", /* name */
+ FALSE, /* partial_inplace */
+ 0x00000000, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* No relocation. */
+ HOWTO (R_METAG_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_METAG_NONE", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* 19 bit pc relative */
+ HOWTO (R_METAG_RELBRANCH, /* type */
+ 2, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 19, /* bitsize */
+ TRUE, /* pc_relative */
+ 5, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_METAG_RELBRANCH", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x00ffffe0, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* GET/SET offset */
+ HOWTO (R_METAG_GETSETOFF, /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 12, /* bitsize */
+ FALSE, /* pc_relative */
+ 7, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_METAG_GETSETOFF", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ EMPTY_HOWTO (6),
+ EMPTY_HOWTO (7),
+ EMPTY_HOWTO (8),
+ EMPTY_HOWTO (9),
+ EMPTY_HOWTO (10),
+ EMPTY_HOWTO (11),
+ EMPTY_HOWTO (12),
+ EMPTY_HOWTO (13),
+ EMPTY_HOWTO (14),
+ EMPTY_HOWTO (15),
+ EMPTY_HOWTO (16),
+ EMPTY_HOWTO (17),
+ EMPTY_HOWTO (18),
+ EMPTY_HOWTO (19),
+ EMPTY_HOWTO (20),
+ EMPTY_HOWTO (21),
+ EMPTY_HOWTO (22),
+ EMPTY_HOWTO (23),
+ EMPTY_HOWTO (24),
+ EMPTY_HOWTO (25),
+ EMPTY_HOWTO (26),
+ EMPTY_HOWTO (27),
+ EMPTY_HOWTO (28),
+ EMPTY_HOWTO (29),
+
+ HOWTO (R_METAG_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_METAG_GNU_VTINHERIT", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_METAG_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_METAG_GNU_VTENTRY", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* High order 16 bit GOT offset */
+ HOWTO (R_METAG_HI16_GOTOFF, /* type */
+ 16, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 3, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_METAG_HI16_GOTOFF", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0007fff8, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Low order 16 bit GOT offset */
+ HOWTO (R_METAG_LO16_GOTOFF, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 3, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_METAG_LO16_GOTOFF", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0007fff8, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* GET/SET GOT offset */
+ HOWTO (R_METAG_GETSET_GOTOFF, /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 12, /* bitsize */
+ FALSE, /* pc_relative */
+ 7, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_METAG_GETSET_GOTOFF", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* GET/SET GOT relative */
+ HOWTO (R_METAG_GETSET_GOT, /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 12, /* bitsize */
+ FALSE, /* pc_relative */
+ 7, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_METAG_GETSET_GOT", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* High order 16 bit GOT reference */
+ HOWTO (R_METAG_HI16_GOTPC, /* type */
+ 16, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 3, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_METAG_HI16_GOTPC", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0007fff8, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Low order 16 bit GOT reference */
+ HOWTO (R_METAG_LO16_GOTPC, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 3, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_METAG_LO16_GOTPC", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0007fff8, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* High order 16 bit PLT */
+ HOWTO (R_METAG_HI16_PLT, /* type */
+ 16, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 3, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_METAG_HI16_PLT", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0007fff8, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Low order 16 bit PLT */
+ HOWTO (R_METAG_LO16_PLT, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 3, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_METAG_LO16_PLT", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_METAG_RELBRANCH_PLT, /* type */
+ 2, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 19, /* bitsize */
+ TRUE, /* pc_relative */
+ 5, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_METAG_RELBRANCH_PLT", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x00ffffe0, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Dummy relocs used by the linker internally. */
+ HOWTO (R_METAG_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_METAG_GOTOFF", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_METAG_PLT, /* 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_METAG_GOTOFF", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* 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_METAG_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_METAG_COPY", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Marks a procedure linkage table entry for a symbol. */
+ HOWTO (R_METAG_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_METAG_JMP_SLOT", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* 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_METAG_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_METAG_RELATIVE", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_METAG_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_METAG_GLOB_DAT", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_METAG_TLS_GD, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 3, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_METAG_TLS_GD", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0007fff8, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_METAG_TLS_LDM, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 3, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_METAG_TLS_LDM", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0007fff8, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_METAG_TLS_LDO_HI16, /* type */
+ 16, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 3, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_METAG_TLS_LDO_HI16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0007fff8, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_METAG_TLS_LDO_LO16, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 3, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_METAG_TLS_LDO_LO16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0007fff8, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Dummy reloc used by the linker internally. */
+ HOWTO (R_METAG_TLS_LDO, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 3, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_METAG_TLS_LDO", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0007fff8, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_METAG_TLS_IE, /* type */
+ 2, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 12, /* bitsize */
+ FALSE, /* pc_relative */
+ 7, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_METAG_TLS_IE", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0007ff80, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Dummy reloc used by the linker internally. */
+ HOWTO (R_METAG_TLS_IENONPIC, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 3, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_METAG_TLS_IENONPIC", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0007fff8, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_METAG_TLS_IENONPIC_HI16,/* type */
+ 16, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 3, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_METAG_TLS_IENONPIC_HI16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0007fff8, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_METAG_TLS_IENONPIC_LO16,/* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 3, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_METAG_TLS_IENONPIC_LO16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0007fff8, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_METAG_TLS_TPOFF, /* 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_METAG_TLS_TPOFF", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_METAG_TLS_DTPMOD, /* 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_METAG_TLS_DTPMOD", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_METAG_TLS_DTPOFF, /* 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_METAG_TLS_DTPOFF", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Dummy reloc used by the linker internally. */
+ HOWTO (R_METAG_TLS_LE, /* 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_METAG_TLS_LE", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_METAG_TLS_LE_HI16, /* type */
+ 16, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 3, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_METAG_TLS_LE_HI16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0007fff8, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_METAG_TLS_LE_LO16, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 3, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_METAG_TLS_LE_LO16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0007fff8, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+};
+
+#define BRANCH_BITS 19
+
+/* The GOT is typically accessed using a [GS]ETD instruction. The size of the
+ immediate offset which can be used in such instructions therefore limits
+ the usable size of the GOT. If the base register for the [GS]ETD (A1LbP)
+ is pointing to the base of the GOT then the size is limited to the maximum
+ 11 bits unsigned dword offset, or 2^13 = 0x2000 bytes. However the offset
+ in a [GS]ETD instruction is signed, so by setting the base address register
+ to an offset of that 0x2000 byte maximum unsigned offset from the base of
+ the GOT we can use negative offsets in addition to positive. This
+ effectively doubles the usable GOT size to 0x4000 bytes. */
+#define GOT_REG_OFFSET 0x2000
+
+struct metag_reloc_map
+{
+ bfd_reloc_code_real_type bfd_reloc_val;
+ unsigned int metag_reloc_val;
+};
+
+static const struct metag_reloc_map metag_reloc_map [] =
+ {
+ { BFD_RELOC_NONE, R_METAG_NONE },
+ { BFD_RELOC_32, R_METAG_ADDR32 },
+ { BFD_RELOC_METAG_HIADDR16, R_METAG_HIADDR16 },
+ { BFD_RELOC_METAG_LOADDR16, R_METAG_LOADDR16 },
+ { BFD_RELOC_METAG_RELBRANCH, R_METAG_RELBRANCH },
+ { BFD_RELOC_METAG_GETSETOFF, R_METAG_GETSETOFF },
+ { BFD_RELOC_VTABLE_INHERIT, R_METAG_GNU_VTINHERIT },
+ { BFD_RELOC_VTABLE_ENTRY, R_METAG_GNU_VTENTRY },
+ { BFD_RELOC_METAG_REL8, R_METAG_REL8 },
+ { BFD_RELOC_METAG_REL16, R_METAG_REL16 },
+ { BFD_RELOC_METAG_HI16_GOTOFF, R_METAG_HI16_GOTOFF },
+ { BFD_RELOC_METAG_LO16_GOTOFF, R_METAG_LO16_GOTOFF },
+ { BFD_RELOC_METAG_GETSET_GOTOFF, R_METAG_GETSET_GOTOFF },
+ { BFD_RELOC_METAG_GETSET_GOT, R_METAG_GETSET_GOT },
+ { BFD_RELOC_METAG_HI16_GOTPC, R_METAG_HI16_GOTPC },
+ { BFD_RELOC_METAG_LO16_GOTPC, R_METAG_LO16_GOTPC },
+ { BFD_RELOC_METAG_HI16_PLT, R_METAG_HI16_PLT },
+ { BFD_RELOC_METAG_LO16_PLT, R_METAG_LO16_PLT },
+ { BFD_RELOC_METAG_RELBRANCH_PLT, R_METAG_RELBRANCH_PLT },
+ { BFD_RELOC_METAG_GOTOFF, R_METAG_GOTOFF },
+ { BFD_RELOC_METAG_PLT, R_METAG_PLT },
+ { BFD_RELOC_METAG_COPY, R_METAG_COPY },
+ { BFD_RELOC_METAG_JMP_SLOT, R_METAG_JMP_SLOT },
+ { BFD_RELOC_METAG_RELATIVE, R_METAG_RELATIVE },
+ { BFD_RELOC_METAG_GLOB_DAT, R_METAG_GLOB_DAT },
+ { BFD_RELOC_METAG_TLS_GD, R_METAG_TLS_GD },
+ { BFD_RELOC_METAG_TLS_LDM, R_METAG_TLS_LDM },
+ { BFD_RELOC_METAG_TLS_LDO_HI16, R_METAG_TLS_LDO_HI16 },
+ { BFD_RELOC_METAG_TLS_LDO_LO16, R_METAG_TLS_LDO_LO16 },
+ { BFD_RELOC_METAG_TLS_LDO, R_METAG_TLS_LDO },
+ { BFD_RELOC_METAG_TLS_IE, R_METAG_TLS_IE },
+ { BFD_RELOC_METAG_TLS_IENONPIC, R_METAG_TLS_IENONPIC },
+ { BFD_RELOC_METAG_TLS_IENONPIC_HI16, R_METAG_TLS_IENONPIC_HI16 },
+ { BFD_RELOC_METAG_TLS_IENONPIC_LO16, R_METAG_TLS_IENONPIC_LO16 },
+ { BFD_RELOC_METAG_TLS_TPOFF, R_METAG_TLS_TPOFF },
+ { BFD_RELOC_METAG_TLS_DTPMOD, R_METAG_TLS_DTPMOD },
+ { BFD_RELOC_METAG_TLS_DTPOFF, R_METAG_TLS_DTPOFF },
+ { BFD_RELOC_METAG_TLS_LE, R_METAG_TLS_LE },
+ { BFD_RELOC_METAG_TLS_LE_HI16, R_METAG_TLS_LE_HI16 },
+ { BFD_RELOC_METAG_TLS_LE_LO16, R_METAG_TLS_LE_LO16 },
+ };
+
+enum elf_metag_stub_type
+{
+ metag_stub_long_branch,
+ metag_stub_long_branch_shared,
+ metag_stub_none
+};
+
+struct elf_metag_stub_hash_entry
+{
+ /* Base hash table entry structure. */
+ struct bfd_hash_entry bh_root;
+
+ /* The stub section. */
+ asection *stub_sec;
+
+ /* Offset within stub_sec of the beginning of this stub. */
+ bfd_vma stub_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. */
+ bfd_vma target_value;
+ asection *target_section;
+
+ enum elf_metag_stub_type stub_type;
+
+ /* The symbol table entry, if any, that this was derived from. */
+ struct elf_metag_link_hash_entry *hh;
+
+ /* And the reloc addend that this was derived from. */
+ bfd_vma addend;
+
+ /* Where this stub is being called from, or, in the case of combined
+ stub sections, the first input section in the group. */
+ asection *id_sec;
+};
+
+struct elf_metag_link_hash_entry
+{
+ struct elf_link_hash_entry eh;
+
+ /* A pointer to the most recently used stub hash entry against this
+ symbol. */
+ struct elf_metag_stub_hash_entry *hsh_cache;
+
+ /* Used to count relocations for delayed sizing of relocation
+ sections. */
+ struct elf_metag_dyn_reloc_entry {
+
+ /* Next relocation in the chain. */
+ struct elf_metag_dyn_reloc_entry *hdh_next;
+
+ /* The input section of the reloc. */
+ asection *sec;
+
+ /* Number of relocs copied in this section. */
+ bfd_size_type count;
+
+ /* Number of relative relocs copied for the input section. */
+ bfd_size_type relative_count;
+ } *dyn_relocs;
+
+ enum
+ {
+ GOT_UNKNOWN = 0, GOT_NORMAL = 1, GOT_TLS_IE = 2, GOT_TLS_LDM = 4, GOT_TLS_GD = 8
+ } tls_type;
+};
+
+struct elf_metag_link_hash_table
+{
+ /* The main hash table. */
+ struct elf_link_hash_table etab;
+
+ /* The stub hash table. */
+ struct bfd_hash_table bstab;
+
+ /* Linker stub bfd. */
+ bfd *stub_bfd;
+
+ /* Linker call-backs. */
+ asection * (*add_stub_section) (const char *, asection *);
+ void (*layout_sections_again) (void);
+
+ /* Array to keep track of which stub sections have been created, and
+ information on stub grouping. */
+ struct map_stub
+ {
+ /* This is the section to which stubs in the group will be
+ attached. */
+ asection *link_sec;
+ /* The stub section. */
+ asection *stub_sec;
+ } *stub_group;
+
+ /* Assorted information used by elf_metag_size_stubs. */
+ unsigned int bfd_count;
+ int top_index;
+ asection **input_list;
+ Elf_Internal_Sym **all_local_syms;
+
+ /* Short-cuts to get to dynamic linker sections. */
+ asection *sgot;
+ asection *sgotplt;
+ asection *srelgot;
+ asection *splt;
+ asection *srelplt;
+ asection *sdynbss;
+ asection *srelbss;
+
+ /* Small local sym cache. */
+ struct sym_cache sym_cache;
+
+ /* Data for LDM relocations. */
+ union
+ {
+ bfd_signed_vma refcount;
+ bfd_vma offset;
+ } tls_ldm_got;
+};
+
+/* Return the base vma address which should be subtracted from the
+ real address when resolving a dtpoff relocation. This is PT_TLS
+ segment p_vaddr. */
+static bfd_vma
+dtpoff_base (struct bfd_link_info *info)
+{
+ /* If tls_sec is NULL, we should have signalled an error already. */
+ if (elf_hash_table (info)->tls_sec == NULL)
+ return 0;
+ return elf_hash_table (info)->tls_sec->vma;
+}
+
+/* Return the relocation value for R_METAG_TLS_IE */
+static bfd_vma
+tpoff (struct bfd_link_info *info, bfd_vma address)
+{
+ /* If tls_sec is NULL, we should have signalled an error already. */
+ if (elf_hash_table (info)->tls_sec == NULL)
+ return 0;
+ /* METAG TLS ABI is variant I and static TLS blocks start just after
+ tcbhead structure which has 2 pointer fields. */
+ return (address - elf_hash_table (info)->tls_sec->vma
+ + align_power ((bfd_vma) 8,
+ elf_hash_table (info)->tls_sec->alignment_power));
+}
+
+static void
+metag_info_to_howto_rela (bfd *abfd ATTRIBUTE_UNUSED,
+ arelent *cache_ptr,
+ Elf_Internal_Rela *dst)
+{
+ unsigned int r_type;
+
+ r_type = ELF32_R_TYPE (dst->r_info);
+ BFD_ASSERT (r_type < (unsigned int) R_METAG_MAX);
+ cache_ptr->howto = & elf_metag_howto_table [r_type];
+}
+
+static reloc_howto_type *
+metag_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED,
+ bfd_reloc_code_real_type code)
+{
+ unsigned int i;
+
+ for (i = 0; i < sizeof (metag_reloc_map) / sizeof (metag_reloc_map[0]); i++)
+ if (metag_reloc_map [i].bfd_reloc_val == code)
+ return & elf_metag_howto_table [metag_reloc_map[i].metag_reloc_val];
+
+ return NULL;
+}
+
+static reloc_howto_type *
+metag_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ const char *r_name)
+{
+ unsigned int i;
+
+ for (i = 0; i < sizeof (elf_metag_howto_table) / sizeof (elf_metag_howto_table[0]); i++)
+ if (elf_metag_howto_table[i].name != NULL
+ && strcasecmp (elf_metag_howto_table[i].name, r_name) == 0)
+ return &elf_metag_howto_table[i];
+
+ return NULL;
+}
+
+/* Various hash macros and functions. */
+#define metag_link_hash_table(p) \
+ (elf_hash_table_id ((struct elf_link_hash_table *) ((p)->hash)) \
+ == METAG_ELF_DATA ? ((struct elf_metag_link_hash_table *) ((p)->hash)) : NULL)
+
+#define metag_elf_hash_entry(ent) \
+ ((struct elf_metag_link_hash_entry *)(ent))
+
+#define metag_stub_hash_entry(ent) \
+ ((struct elf_metag_stub_hash_entry *)(ent))
+
+#define metag_stub_hash_lookup(table, string, create, copy) \
+ ((struct elf_metag_stub_hash_entry *) \
+ bfd_hash_lookup ((table), (string), (create), (copy)))
+
+#define metag_elf_local_got_tls_type(abfd) \
+ ((char *)(elf_local_got_offsets (abfd) + (elf_tdata (abfd)->symtab_hdr.sh_info)))
+
+/* Assorted hash table functions. */
+
+/* Initialize an entry in the stub hash table. */
+
+static struct bfd_hash_entry *
+stub_hash_newfunc (struct bfd_hash_entry *entry,
+ struct bfd_hash_table *table,
+ const char *string)
+{
+ /* Allocate the structure if it has not already been allocated by a
+ subclass. */
+ if (entry == NULL)
+ {
+ entry = bfd_hash_allocate (table,
+ sizeof (struct elf_metag_stub_hash_entry));
+ if (entry == NULL)
+ return entry;
+ }
+
+ /* Call the allocation method of the superclass. */
+ entry = bfd_hash_newfunc (entry, table, string);
+ if (entry != NULL)
+ {
+ struct elf_metag_stub_hash_entry *hsh;
+
+ /* Initialize the local fields. */
+ hsh = (struct elf_metag_stub_hash_entry *) entry;
+ hsh->stub_sec = NULL;
+ hsh->stub_offset = 0;
+ hsh->target_value = 0;
+ hsh->target_section = NULL;
+ hsh->stub_type = metag_stub_long_branch;
+ hsh->hh = NULL;
+ hsh->id_sec = NULL;
+ }
+
+ return entry;
+}
+
+/* Initialize an entry in the link hash table. */
+
+static struct bfd_hash_entry *
+metag_link_hash_newfunc (struct bfd_hash_entry *entry,
+ struct bfd_hash_table *table,
+ const char *string)
+{
+ /* Allocate the structure if it has not already been allocated by a
+ subclass. */
+ if (entry == NULL)
+ {
+ entry = bfd_hash_allocate (table,
+ sizeof (struct elf_metag_link_hash_entry));
+ if (entry == NULL)
+ return entry;
+ }
+
+ /* Call the allocation method of the superclass. */
+ entry = _bfd_elf_link_hash_newfunc (entry, table, string);
+ if (entry != NULL)
+ {
+ struct elf_metag_link_hash_entry *hh;
+
+ /* Initialize the local fields. */
+ hh = (struct elf_metag_link_hash_entry *) entry;
+ hh->hsh_cache = NULL;
+ hh->dyn_relocs = NULL;
+ hh->tls_type = GOT_UNKNOWN;
+ }
+
+ return entry;
+}
+
+/* Free the derived linker hash table. */
+
+static void
+elf_metag_link_hash_table_free (bfd *obfd)
+{
+ struct elf_metag_link_hash_table *htab
+ = (struct elf_metag_link_hash_table *) obfd->link.hash;
+
+ bfd_hash_table_free (&htab->bstab);
+ _bfd_elf_link_hash_table_free (obfd);
+}
+
+/* Create the derived linker hash table. The Meta ELF port uses the derived
+ hash table to keep information specific to the Meta ELF linker (without
+ using static variables). */
+
+static struct bfd_link_hash_table *
+elf_metag_link_hash_table_create (bfd *abfd)
+{
+ struct elf_metag_link_hash_table *htab;
+ bfd_size_type amt = sizeof (*htab);
+
+ htab = bfd_zmalloc (amt);
+ if (htab == NULL)
+ return NULL;
+
+ if (!_bfd_elf_link_hash_table_init (&htab->etab, abfd,
+ metag_link_hash_newfunc,
+ sizeof (struct elf_metag_link_hash_entry),
+ METAG_ELF_DATA))
+ {
+ free (htab);
+ return NULL;
+ }
+
+ /* Init the stub hash table too. */
+ if (!bfd_hash_table_init (&htab->bstab, stub_hash_newfunc,
+ sizeof (struct elf_metag_stub_hash_entry)))
+ {
+ _bfd_elf_link_hash_table_free (abfd);
+ return NULL;
+ }
+ htab->etab.root.hash_table_free = elf_metag_link_hash_table_free;
+
+ return &htab->etab.root;
+}
+
+/* Section name for stubs is the associated section name plus this
+ string. */
+#define STUB_SUFFIX ".stub"
+
+/* Build a name for an entry in the stub hash table. */
+
+static char *
+metag_stub_name (const asection *input_section,
+ const asection *sym_sec,
+ const struct elf_metag_link_hash_entry *hh,
+ const Elf_Internal_Rela *rel)
+{
+ char *stub_name;
+ bfd_size_type len;
+
+ if (hh)
+ {
+ len = 8 + 1 + strlen (hh->eh.root.root.string) + 1 + 8 + 1;
+ stub_name = bfd_malloc (len);
+ if (stub_name != NULL)
+ {
+ sprintf (stub_name, "%08x_%s+%x",
+ input_section->id & 0xffffffff,
+ hh->eh.root.root.string,
+ (int) rel->r_addend & 0xffffffff);
+ }
+ }
+ else
+ {
+ len = 8 + 1 + 8 + 1 + 8 + 1 + 8 + 1;
+ stub_name = bfd_malloc (len);
+ if (stub_name != NULL)
+ {
+ sprintf (stub_name, "%08x_%x:%x+%x",
+ input_section->id & 0xffffffff,
+ sym_sec->id & 0xffffffff,
+ (int) ELF32_R_SYM (rel->r_info) & 0xffffffff,
+ (int) rel->r_addend & 0xffffffff);
+ }
+ }
+ return stub_name;
+}
+
+/* Look up an entry in the stub hash. Stub entries are cached because
+ creating the stub name takes a bit of time. */
+
+static struct elf_metag_stub_hash_entry *
+metag_get_stub_entry (const asection *input_section,
+ const asection *sym_sec,
+ struct elf_metag_link_hash_entry *hh,
+ const Elf_Internal_Rela *rel,
+ struct elf_metag_link_hash_table *htab)
+{
+ struct elf_metag_stub_hash_entry *hsh;
+ const asection *id_sec;
+
+ /* If this input section is part of a group of sections sharing one
+ stub section, then use the id of the first section in the group.
+ Stub names need to include a section id, as there may well be
+ more than one stub used to reach say, printf, and we need to
+ distinguish between them. */
+ id_sec = htab->stub_group[input_section->id].link_sec;
+
+ if (hh != NULL && hh->hsh_cache != NULL
+ && hh->hsh_cache->hh == hh
+ && hh->hsh_cache->id_sec == id_sec)
+ {
+ hsh = hh->hsh_cache;
+ }
+ else
+ {
+ char *stub_name;
+
+ stub_name = metag_stub_name (id_sec, sym_sec, hh, rel);
+ if (stub_name == NULL)
+ return NULL;
+
+ hsh = metag_stub_hash_lookup (&htab->bstab,
+ stub_name, FALSE, FALSE);
+
+ if (hh != NULL)
+ hh->hsh_cache = hsh;
+
+ free (stub_name);
+ }
+
+ return hsh;
+}
+
+/* Add a new stub entry to the stub hash. Not all fields of the new
+ stub entry are initialised. */
+
+static struct elf_metag_stub_hash_entry *
+metag_add_stub (const char *stub_name,
+ asection *section,
+ struct elf_metag_link_hash_table *htab)
+{
+ asection *link_sec;
+ asection *stub_sec;
+ struct elf_metag_stub_hash_entry *hsh;
+
+ link_sec = htab->stub_group[section->id].link_sec;
+ stub_sec = htab->stub_group[section->id].stub_sec;
+ if (stub_sec == NULL)
+ {
+ stub_sec = htab->stub_group[link_sec->id].stub_sec;
+ if (stub_sec == NULL)
+ {
+ size_t namelen;
+ bfd_size_type len;
+ char *s_name;
+
+ namelen = strlen (link_sec->name);
+ len = namelen + sizeof (STUB_SUFFIX);
+ s_name = bfd_alloc (htab->stub_bfd, len);
+ if (s_name == NULL)
+ return NULL;
+
+ memcpy (s_name, link_sec->name, namelen);
+ memcpy (s_name + namelen, STUB_SUFFIX, sizeof (STUB_SUFFIX));
+
+ stub_sec = (*htab->add_stub_section) (s_name, link_sec);
+ if (stub_sec == NULL)
+ return NULL;
+ htab->stub_group[link_sec->id].stub_sec = stub_sec;
+ }
+ htab->stub_group[section->id].stub_sec = stub_sec;
+ }
+
+ /* Enter this entry into the linker stub hash table. */
+ hsh = metag_stub_hash_lookup (&htab->bstab, stub_name,
+ TRUE, FALSE);
+ if (hsh == NULL)
+ {
+ (*_bfd_error_handler) (_("%B: cannot create stub entry %s"),
+ section->owner,
+ stub_name);
+ return NULL;
+ }
+
+ hsh->stub_sec = stub_sec;
+ hsh->stub_offset = 0;
+ hsh->id_sec = link_sec;
+ return hsh;
+}
+
+/* Check a signed integer value can be represented in the given number
+ of bits. */
+
+static bfd_boolean
+within_signed_range (int value, unsigned int bits)
+{
+ int min_val = -(1 << (bits - 1));
+ int max_val = (1 << (bits - 1)) - 1;
+ return (value <= max_val) && (value >= min_val);
+}
+
+/* Perform a relocation as part of a final link. */
+
+static bfd_reloc_status_type
+metag_final_link_relocate (reloc_howto_type *howto,
+ bfd *input_bfd,
+ asection *input_section,
+ bfd_byte *contents,
+ Elf_Internal_Rela *rel,
+ bfd_vma relocation,
+ struct elf_metag_link_hash_entry *hh,
+ struct elf_metag_link_hash_table *htab,
+ asection *sym_sec)
+{
+ bfd_reloc_status_type r = bfd_reloc_ok;
+ bfd_byte *hit_data = contents + rel->r_offset;
+ int opcode, op_shift, op_extended, l1, l2;
+ bfd_signed_vma srel, addend = rel->r_addend;
+ struct elf_metag_stub_hash_entry *hsh = NULL;
+ bfd_vma location;
+
+ /* Find out where we are and where we're going. */
+ location = (rel->r_offset +
+ input_section->output_offset +
+ input_section->output_section->vma);
+
+ switch (howto->type)
+ {
+ case R_METAG_RELBRANCH:
+ case R_METAG_RELBRANCH_PLT:
+ /* Make it a pc relative offset. */
+ relocation -= location;
+ break;
+ case R_METAG_TLS_GD:
+ case R_METAG_TLS_IE:
+ relocation -= elf_gp (input_section->output_section->owner);
+ break;
+ default:
+ break;
+ }
+
+ switch (howto->type)
+ {
+ case R_METAG_RELBRANCH_PLT:
+ case R_METAG_RELBRANCH:
+ opcode = bfd_get_32 (input_bfd, hit_data);
+
+ srel = (bfd_signed_vma) relocation;
+ srel += addend;
+
+ /* If the branch is out of reach, then redirect the
+ call to the local stub for this function. */
+ if (srel > ((1 << (BRANCH_BITS + 1)) - 1) ||
+ (srel < - (1 << (BRANCH_BITS + 1))))
+ {
+ if (sym_sec == NULL)
+ break;
+
+ hsh = metag_get_stub_entry (input_section, sym_sec,
+ hh, rel, htab);
+ if (hsh == NULL)
+ return bfd_reloc_undefined;
+
+ /* Munge up the value and addend so that we call the stub
+ rather than the procedure directly. */
+ srel = (hsh->stub_offset
+ + hsh->stub_sec->output_offset
+ + hsh->stub_sec->output_section->vma);
+ srel -= location;
+ }
+
+ srel = srel >> 2;
+
+ if (!within_signed_range (srel, BRANCH_BITS))
+ {
+ if (hh && hh->eh.root.type == bfd_link_hash_undefweak)
+ srel = 0;
+ else
+ return bfd_reloc_overflow;
+ }
+
+ opcode &= ~(0x7ffff << 5);
+ opcode |= ((srel & 0x7ffff) << 5);
+
+ bfd_put_32 (input_bfd, opcode, hit_data);
+ break;
+ case R_METAG_GETSETOFF:
+ case R_METAG_GETSET_GOT:
+ case R_METAG_GETSET_GOTOFF:
+ opcode = bfd_get_32 (input_bfd, hit_data);
+
+ srel = (bfd_signed_vma) relocation;
+ srel += addend;
+
+ /* Is this a standard or extended GET/SET? */
+ if ((opcode & 0xf0000000) == 0xa0000000)
+ {
+ /* Extended GET/SET. */
+ l1 = opcode & 0x2;
+ l2 = opcode & 0x4;
+ op_extended = 1;
+ }
+ else
+ {
+ /* Standard GET/SET. */
+ l1 = opcode & 0x01000000;
+ l2 = opcode & 0x04000000;
+ op_extended = 0;
+ }
+
+ /* Calculate the width of the GET/SET and how much we need to
+ shift the result by. */
+ if (l2)
+ if (l1)
+ op_shift = 3;
+ else
+ op_shift = 2;
+ else
+ if (l1)
+ op_shift = 1;
+ else
+ op_shift = 0;
+
+ /* GET/SET offsets are scaled by the width of the transfer. */
+ srel = srel >> op_shift;
+
+ /* Extended GET/SET has signed 12 bits of offset, standard has
+ signed 6 bits. */
+ if (op_extended)
+ {
+ if (!within_signed_range (srel, 12))
+ {
+ if (hh && hh->eh.root.type == bfd_link_hash_undefweak)
+ srel = 0;
+ else
+ return bfd_reloc_overflow;
+ }
+ opcode &= ~(0xfff << 7);
+ opcode |= ((srel & 0xfff) << 7);
+ }
+ else
+ {
+ if (!within_signed_range (srel, 5))
+ {
+ if (hh && hh->eh.root.type == bfd_link_hash_undefweak)
+ srel = 0;
+ else
+ return bfd_reloc_overflow;
+ }
+ opcode &= ~(0x3f << 8);
+ opcode |= ((srel & 0x3f) << 8);
+ }
+
+ bfd_put_32 (input_bfd, opcode, hit_data);
+ break;
+ case R_METAG_TLS_GD:
+ case R_METAG_TLS_LDM:
+ opcode = bfd_get_32 (input_bfd, hit_data);
+
+ if ((bfd_signed_vma)relocation < 0)
+ {
+ /* sign extend immediate */
+ if ((opcode & 0xf2000001) == 0x02000000)
+ {
+ /* ADD De.e,Dx.r,#I16 */
+ /* set SE bit */
+ opcode |= (1 << 1);
+ } else
+ return bfd_reloc_overflow;
+ }
+
+ bfd_put_32 (input_bfd, opcode, hit_data);
+
+ r = _bfd_final_link_relocate (howto, input_bfd, input_section,
+ contents, rel->r_offset,
+ relocation, rel->r_addend);
+ break;
+ default:
+ r = _bfd_final_link_relocate (howto, input_bfd, input_section,
+ contents, rel->r_offset,
+ relocation, rel->r_addend);
+ }
+
+ return r;
+}
+
+/* This is defined because R_METAG_NONE != 0...
+ See RELOC_AGAINST_DISCARDED_SECTION for details. */
+#define METAG_RELOC_AGAINST_DISCARDED_SECTION(info, input_bfd, input_section, \
+ rel, relend, howto, contents) \
+ { \
+ _bfd_clear_contents (howto, input_bfd, input_section, \
+ contents + rel->r_offset); \
+ \
+ if (info->relocatable \
+ && (input_section->flags & SEC_DEBUGGING)) \
+ { \
+ /* Only remove relocations in debug sections since other \
+ sections may require relocations. */ \
+ Elf_Internal_Shdr *rel_hdr; \
+ \
+ rel_hdr = _bfd_elf_single_rel_hdr (input_section->output_section); \
+ \
+ /* Avoid empty output section. */ \
+ if (rel_hdr->sh_size > rel_hdr->sh_entsize) \
+ { \
+ rel_hdr->sh_size -= rel_hdr->sh_entsize; \
+ rel_hdr = _bfd_elf_single_rel_hdr (input_section); \
+ rel_hdr->sh_size -= rel_hdr->sh_entsize; \
+ \
+ memmove (rel, rel + 1, (relend - rel) * sizeof (*rel)); \
+ \
+ input_section->reloc_count--; \
+ relend--; \
+ rel--; \
+ continue; \
+ } \
+ } \
+ \
+ rel->r_info = R_METAG_NONE; \
+ rel->r_addend = 0; \
+ continue; \
+ }
+
+/* Relocate a META ELF section.
+
+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 relocatable
+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 relocatable 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 bfd_boolean
+elf_metag_relocate_section (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_vma *local_got_offsets;
+ Elf_Internal_Shdr *symtab_hdr;
+ struct elf_link_hash_entry **eh_syms;
+ struct elf_metag_link_hash_table *htab;
+ Elf_Internal_Rela *rel;
+ Elf_Internal_Rela *relend;
+ asection *sreloc;
+
+ symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
+ eh_syms = elf_sym_hashes (input_bfd);
+ relend = relocs + input_section->reloc_count;
+
+ htab = metag_link_hash_table (info);
+ local_got_offsets = elf_local_got_offsets (input_bfd);
+
+ sreloc = NULL;
+
+ for (rel = relocs; rel < relend; rel ++)
+ {
+ reloc_howto_type *howto;
+ unsigned long r_symndx;
+ Elf_Internal_Sym *sym;
+ asection *sec;
+ struct elf_metag_link_hash_entry *hh;
+ bfd_vma relocation;
+ bfd_reloc_status_type r;
+ const char *name;
+ int r_type;
+
+ r_type = ELF32_R_TYPE (rel->r_info);
+
+ if (r_type == R_METAG_GNU_VTINHERIT
+ || r_type == R_METAG_GNU_VTENTRY
+ || r_type == R_METAG_NONE)
+ continue;
+
+ r_symndx = ELF32_R_SYM (rel->r_info);
+
+ howto = elf_metag_howto_table + ELF32_R_TYPE (rel->r_info);
+ hh = NULL;
+ sym = NULL;
+ sec = NULL;
+
+ if (r_symndx < symtab_hdr->sh_info)
+ {
+ sym = local_syms + r_symndx;
+ sec = local_sections [r_symndx];
+ relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
+
+ 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;
+ }
+ else
+ {
+ struct elf_link_hash_entry *eh;
+ bfd_boolean unresolved_reloc, warned, ignored;
+
+ RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
+ r_symndx, symtab_hdr, eh_syms,
+ eh, sec, relocation,
+ unresolved_reloc, warned, ignored);
+
+ name = eh->root.root.string;
+ hh = (struct elf_metag_link_hash_entry *) eh;
+ }
+
+ if (sec != NULL && discarded_section (sec))
+ METAG_RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+ rel, relend, howto, contents);
+
+ if (info->relocatable)
+ continue;
+
+ switch (r_type)
+ {
+ case R_METAG_ADDR32:
+ case R_METAG_RELBRANCH:
+ if ((input_section->flags & SEC_ALLOC) == 0)
+ break;
+
+ if ((info->shared
+ && r_symndx != STN_UNDEF
+ && (input_section->flags & SEC_ALLOC) != 0
+ && (r_type != R_METAG_RELBRANCH
+ || !SYMBOL_CALLS_LOCAL (info, &hh->eh)))
+ || (!info->shared
+ && hh != NULL
+ && hh->eh.dynindx != -1
+ && !hh->eh.non_got_ref
+ && ((hh->eh.def_dynamic
+ && !hh->eh.def_regular)
+ || hh->eh.root.type == bfd_link_hash_undefweak
+ || hh->eh.root.type == bfd_link_hash_undefined)))
+ {
+ Elf_Internal_Rela outrel;
+ bfd_boolean skip, relocate;
+ bfd_byte *loc;
+
+ /* When generating a shared object, these relocations
+ are copied into the output file to be resolved at run
+ time. */
+
+ sreloc = elf_section_data (input_section)->sreloc;
+ BFD_ASSERT (sreloc != NULL);
+
+ skip = FALSE;
+ relocate = FALSE;
+
+ outrel.r_offset = _bfd_elf_section_offset (output_bfd,
+ info,
+ input_section,
+ rel->r_offset);
+ if (outrel.r_offset == (bfd_vma) -1)
+ skip = TRUE;
+ else if (outrel.r_offset == (bfd_vma) -2)
+ skip = TRUE, relocate = TRUE;
+ outrel.r_offset += (input_section->output_section->vma
+ + input_section->output_offset);
+
+ if (skip)
+ {
+ memset (&outrel, 0, sizeof outrel);
+ outrel.r_info = ELF32_R_INFO (0, R_METAG_NONE);
+ }
+ else if (r_type == R_METAG_RELBRANCH)
+ {
+ BFD_ASSERT (hh != NULL && hh->eh.dynindx != -1);
+ outrel.r_info = ELF32_R_INFO (hh->eh.dynindx, r_type);
+ outrel.r_addend = rel->r_addend;
+ }
+ else
+ {
+ /* h->dynindx may be -1 if this symbol was marked to
+ become local. */
+ if (hh == NULL
+ || ((info->symbolic || hh->eh.dynindx == -1)
+ && hh->eh.def_regular))
+ {
+ relocate = TRUE;
+ outrel.r_info = ELF32_R_INFO (0, R_METAG_RELATIVE);
+ outrel.r_addend = relocation + rel->r_addend;
+ }
+ else
+ {
+ BFD_ASSERT (hh->eh.dynindx != -1);
+ outrel.r_info = ELF32_R_INFO (hh->eh.dynindx, r_type);
+ outrel.r_addend = rel->r_addend;
+ }
+ }
+
+ loc = sreloc->contents;
+ loc += sreloc->reloc_count * sizeof(Elf32_External_Rela);
+ bfd_elf32_swap_reloca_out (output_bfd, &outrel,loc);
+ ++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;
+
+ case R_METAG_RELBRANCH_PLT:
+ /* Relocation is to the entry for this symbol in the
+ procedure linkage table. */
+
+ if (hh == NULL)
+ break;
+
+ if (hh->eh.forced_local)
+ break;
+
+ if (hh->eh.plt.offset == (bfd_vma) -1 ||
+ htab->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 = (htab->splt->output_section->vma
+ + htab->splt->output_offset
+ + hh->eh.plt.offset);
+ break;
+ case R_METAG_HI16_GOTPC:
+ case R_METAG_LO16_GOTPC:
+ BFD_ASSERT (htab->sgot != NULL);
+
+ relocation = (htab->sgot->output_section->vma +
+ htab->sgot->output_offset);
+ relocation += GOT_REG_OFFSET;
+ relocation -= (input_section->output_section->vma
+ + input_section->output_offset
+ + rel->r_offset);
+ break;
+ case R_METAG_HI16_GOTOFF:
+ case R_METAG_LO16_GOTOFF:
+ case R_METAG_GETSET_GOTOFF:
+ BFD_ASSERT (htab->sgot != NULL);
+
+ relocation -= (htab->sgot->output_section->vma +
+ htab->sgot->output_offset);
+ relocation -= GOT_REG_OFFSET;
+ break;
+ case R_METAG_GETSET_GOT:
+ {
+ bfd_vma off;
+ bfd_boolean do_got = 0;
+
+ /* Relocation is to the entry for this symbol in the
+ global offset table. */
+ if (hh != NULL)
+ {
+ bfd_boolean dyn;
+
+ off = hh->eh.got.offset;
+ dyn = htab->etab.dynamic_sections_created;
+ if (! WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared,
+ &hh->eh))
+ {
+ /* If we aren't going to call finish_dynamic_symbol,
+ then we need to handle initialisation of the .got
+ entry and create needed relocs here. Since the
+ offset must always be a multiple of 4, we use the
+ least significant bit to record whether we have
+ initialised it already. */
+ if ((off & 1) != 0)
+ off &= ~1;
+ else
+ {
+ hh->eh.got.offset |= 1;
+ do_got = 1;
+ }
+ }
+ }
+ else
+ {
+ /* Local symbol case. */
+ if (local_got_offsets == NULL)
+ abort ();
+
+ 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
+ {
+ local_got_offsets[r_symndx] |= 1;
+ do_got = 1;
+ }
+ }
+
+ if (do_got)
+ {
+ if (info->shared)
+ {
+ /* Output a dynamic relocation for this GOT entry.
+ In this case it is relative to the base of the
+ object because the symbol index is zero. */
+ Elf_Internal_Rela outrel;
+ bfd_byte *loc;
+ asection *s = htab->srelgot;
+
+ outrel.r_offset = (off
+ + htab->sgot->output_offset
+ + htab->sgot->output_section->vma);
+ outrel.r_info = ELF32_R_INFO (0, R_METAG_RELATIVE);
+ outrel.r_addend = relocation;
+ loc = s->contents;
+ loc += s->reloc_count++ * sizeof (Elf32_External_Rela);
+ bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
+ }
+ else
+ bfd_put_32 (output_bfd, relocation,
+ htab->sgot->contents + off);
+ }
+
+ if (off >= (bfd_vma) -2)
+ abort ();
+
+ relocation = off - GOT_REG_OFFSET;
+ }
+ break;
+ case R_METAG_TLS_GD:
+ case R_METAG_TLS_IE:
+ {
+ /* XXXMJF There is room here for optimisations. For example
+ converting from GD->IE, etc. */
+ bfd_vma off;
+ int indx;
+ char tls_type;
+
+ if (htab->sgot == NULL)
+ abort();
+
+ indx = 0;
+ if (hh != NULL)
+ {
+ bfd_boolean dyn;
+ dyn = htab->etab.dynamic_sections_created;
+
+ if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, &hh->eh)
+ && (!info->shared
+ || !SYMBOL_REFERENCES_LOCAL (info, &hh->eh)))
+ {
+ indx = hh->eh.dynindx;
+ }
+ off = hh->eh.got.offset;
+ tls_type = hh->tls_type;
+ }
+ else
+ {
+ /* Local symbol case. */
+ if (local_got_offsets == NULL)
+ abort ();
+
+ off = local_got_offsets[r_symndx];
+ tls_type = metag_elf_local_got_tls_type (input_bfd) [r_symndx];
+ }
+
+ if (tls_type == GOT_UNKNOWN)
+ abort();
+
+ if ((off & 1) != 0)
+ off &= ~1;
+ else
+ {
+ bfd_boolean need_relocs = FALSE;
+ Elf_Internal_Rela outrel;
+ bfd_byte *loc = NULL;
+ int cur_off = off;
+
+ /* The GOT entries have not been initialized yet. Do it
+ now, and emit any relocations. If both an IE GOT and a
+ GD GOT are necessary, we emit the GD first. */
+
+ if ((info->shared || indx != 0)
+ && (hh == NULL
+ || ELF_ST_VISIBILITY (hh->eh.other) == STV_DEFAULT
+ || hh->eh.root.type != bfd_link_hash_undefweak))
+ {
+ need_relocs = TRUE;
+ loc = htab->srelgot->contents;
+ /* FIXME (CAO): Should this be reloc_count++ ? */
+ loc += htab->srelgot->reloc_count * sizeof (Elf32_External_Rela);
+ }
+
+ if (tls_type & GOT_TLS_GD)
+ {
+ if (need_relocs)
+ {
+ outrel.r_offset = (cur_off
+ + htab->sgot->output_section->vma
+ + htab->sgot->output_offset);
+ outrel.r_info = ELF32_R_INFO (indx, R_METAG_TLS_DTPMOD);
+ outrel.r_addend = 0;
+ bfd_put_32 (output_bfd, 0, htab->sgot->contents + cur_off);
+
+ bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
+ htab->srelgot->reloc_count++;
+ loc += sizeof (Elf32_External_Rela);
+
+ if (indx == 0)
+ bfd_put_32 (output_bfd, 0,
+ htab->sgot->contents + cur_off + 4);
+ else
+ {
+ bfd_put_32 (output_bfd, 0,
+ htab->sgot->contents + cur_off + 4);
+ outrel.r_info = ELF32_R_INFO (indx,
+ R_METAG_TLS_DTPOFF);
+ outrel.r_offset += 4;
+ bfd_elf32_swap_reloca_out (output_bfd,
+ &outrel, loc);
+ htab->srelgot->reloc_count++;
+ loc += sizeof (Elf32_External_Rela);
+ }
+ }
+ else
+ {
+ /* We don't support changing the TLS model. */
+ abort ();
+ }
+
+ cur_off += 8;
+ }
+
+ if (tls_type & GOT_TLS_IE)
+ {
+ if (need_relocs)
+ {
+ outrel.r_offset = (cur_off
+ + htab->sgot->output_section->vma
+ + htab->sgot->output_offset);
+ outrel.r_info = ELF32_R_INFO (indx, R_METAG_TLS_TPOFF);
+
+ if (indx == 0)
+ outrel.r_addend = relocation - dtpoff_base (info);
+ else
+ outrel.r_addend = 0;
+
+ bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
+ htab->srelgot->reloc_count++;
+ loc += sizeof (Elf32_External_Rela);
+ }
+ else
+ bfd_put_32 (output_bfd, tpoff (info, relocation),
+ htab->sgot->contents + cur_off);
+
+ cur_off += 4;
+ }
+
+ if (hh != NULL)
+ hh->eh.got.offset |= 1;
+ else
+ local_got_offsets[r_symndx] |= 1;
+ }
+
+ /* Add the base of the GOT to the relocation value. */
+ relocation = off - GOT_REG_OFFSET;
+
+ break;
+ }
+
+ case R_METAG_TLS_IENONPIC_HI16:
+ case R_METAG_TLS_IENONPIC_LO16:
+ case R_METAG_TLS_LE_HI16:
+ case R_METAG_TLS_LE_LO16:
+ if (info->shared)
+ {
+ (*_bfd_error_handler)
+ (_("%B(%A+0x%lx): R_METAG_TLS_LE/IENONPIC relocation not permitted in shared object"),
+ input_bfd, input_section,
+ (long) rel->r_offset, howto->name);
+ return FALSE;
+ }
+ else
+ relocation = tpoff (info, relocation);
+ break;
+ case R_METAG_TLS_LDO_HI16:
+ case R_METAG_TLS_LDO_LO16:
+ if (! info->shared)
+ relocation = tpoff (info, relocation);
+ else
+ relocation -= dtpoff_base (info);
+ break;
+ case R_METAG_TLS_LDM:
+ {
+ bfd_vma off;
+
+ if (htab->sgot == NULL)
+ abort();
+ off = htab->tls_ldm_got.offset;
+ if (off & 1)
+ off &= ~1;
+ else
+ {
+ Elf_Internal_Rela outrel;
+ bfd_byte *loc;
+
+ outrel.r_offset = (off
+ + htab->sgot->output_section->vma
+ + htab->sgot->output_offset);
+
+ outrel.r_addend = 0;
+ outrel.r_info = ELF32_R_INFO (0, R_METAG_TLS_DTPMOD);
+ loc = htab->srelgot->contents;
+ loc += htab->srelgot->reloc_count++ * sizeof (Elf32_External_Rela);
+ bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
+ htab->tls_ldm_got.offset |= 1;
+ }
+
+ relocation = off - GOT_REG_OFFSET;
+ break;
+ }
+ default:
+ break;
+ }
+
+ r = metag_final_link_relocate (howto, input_bfd, input_section,
+ contents, rel, relocation, hh, htab,
+ sec);
+
+ if (r != bfd_reloc_ok)
+ {
+ const char * msg = (const char *) NULL;
+
+ switch (r)
+ {
+ case bfd_reloc_overflow:
+ r = info->callbacks->reloc_overflow
+ (info, (hh ? &hh->eh.root : NULL), 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,
+ TRUE);
+ 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;
+}
+
+/* Create the .plt and .got sections, and set up our hash table
+ short-cuts to various dynamic sections. */
+
+static bfd_boolean
+elf_metag_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
+{
+ struct elf_metag_link_hash_table *htab;
+ struct elf_link_hash_entry *eh;
+ struct bfd_link_hash_entry *bh;
+ const struct elf_backend_data *bed = get_elf_backend_data (abfd);
+
+ /* Don't try to create the .plt and .got twice. */
+ htab = metag_link_hash_table (info);
+ if (htab->splt != NULL)
+ return TRUE;
+
+ /* Call the generic code to do most of the work. */
+ if (! _bfd_elf_create_dynamic_sections (abfd, info))
+ return FALSE;
+
+ htab->sgot = bfd_get_linker_section (abfd, ".got");
+ if (! htab->sgot)
+ return FALSE;
+
+ htab->sgotplt = bfd_make_section_with_flags (abfd, ".got.plt",
+ (SEC_ALLOC | SEC_LOAD |
+ SEC_HAS_CONTENTS |
+ SEC_IN_MEMORY |
+ SEC_LINKER_CREATED));
+ if (htab->sgotplt == NULL
+ || !bfd_set_section_alignment (abfd, htab->sgotplt, 2))
+ return FALSE;
+
+ /* Define the symbol __GLOBAL_OFFSET_TABLE__ at the start of the .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. */
+ bh = NULL;
+ if (!(_bfd_generic_link_add_one_symbol
+ (info, abfd, "__GLOBAL_OFFSET_TABLE__", BSF_GLOBAL, htab->sgot,
+ (bfd_vma) 0, NULL, FALSE, bed->collect, &bh)))
+ return FALSE;
+ eh = (struct elf_link_hash_entry *) bh;
+ eh->def_regular = 1;
+ eh->type = STT_OBJECT;
+ eh->other = STV_HIDDEN;
+
+ if (! info->executable
+ && ! bfd_elf_link_record_dynamic_symbol (info, eh))
+ return FALSE;
+
+ elf_hash_table (info)->hgot = eh;
+
+ htab->splt = bfd_get_linker_section (abfd, ".plt");
+ htab->srelplt = bfd_get_linker_section (abfd, ".rela.plt");
+
+ htab->srelgot = bfd_get_linker_section (abfd, ".rela.got");
+
+ htab->sdynbss = bfd_get_linker_section (abfd, ".dynbss");
+ htab->srelbss = bfd_get_linker_section (abfd, ".rela.bss");
+
+ return TRUE;
+}
+
+/* Look through the relocs for a section during the first phase, and
+ calculate needed space in the global offset table, procedure linkage
+ table, and dynamic reloc sections. At this point we haven't
+ necessarily read all the input files. */
+
+static bfd_boolean
+elf_metag_check_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 **eh_syms;
+ const Elf_Internal_Rela *rel;
+ const Elf_Internal_Rela *rel_end;
+ struct elf_metag_link_hash_table *htab;
+ asection *sreloc;
+ bfd *dynobj;
+ int tls_type = GOT_UNKNOWN, old_tls_type = GOT_UNKNOWN;
+
+ if (info->relocatable)
+ return TRUE;
+
+ htab = metag_link_hash_table (info);
+ dynobj = htab->etab.dynobj;
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+ eh_syms = elf_sym_hashes (abfd);
+ sreloc = NULL;
+
+ if (htab == NULL)
+ return FALSE;
+
+ rel_end = relocs + sec->reloc_count;
+ for (rel = relocs; rel < rel_end; rel++)
+ {
+ int r_type;
+ struct elf_metag_link_hash_entry *hh;
+ Elf_Internal_Sym *isym;
+ unsigned long r_symndx;
+
+ r_symndx = ELF32_R_SYM (rel->r_info);
+ r_type = ELF32_R_TYPE (rel->r_info);
+ if (r_symndx < symtab_hdr->sh_info)
+ {
+ /* A local symbol. */
+ isym = bfd_sym_from_r_symndx (&htab->sym_cache,
+ abfd, r_symndx);
+ if (isym == NULL)
+ return FALSE;
+
+ hh = NULL;
+ }
+ else
+ {
+ isym = NULL;
+
+ hh = (struct elf_metag_link_hash_entry *)
+ eh_syms[r_symndx - symtab_hdr->sh_info];
+ while (hh->eh.root.type == bfd_link_hash_indirect
+ || hh->eh.root.type == bfd_link_hash_warning)
+ hh = (struct elf_metag_link_hash_entry *) hh->eh.root.u.i.link;
+
+ /* PR15323, ref flags aren't set for references in the same
+ object. */
+ hh->eh.root.non_ir_ref = 1;
+ }
+
+ /* Some relocs require a global offset table. */
+ if (htab->sgot == NULL)
+ {
+ switch (r_type)
+ {
+ case R_METAG_TLS_GD:
+ case R_METAG_TLS_LDM:
+ case R_METAG_TLS_IE:
+ if (info->shared)
+ info->flags |= DF_STATIC_TLS;
+ /* Fall through. */
+
+ case R_METAG_HI16_GOTOFF:
+ case R_METAG_LO16_GOTOFF:
+ case R_METAG_GETSET_GOTOFF:
+ case R_METAG_GETSET_GOT:
+ case R_METAG_HI16_GOTPC:
+ case R_METAG_LO16_GOTPC:
+ if (dynobj == NULL)
+ htab->etab.dynobj = dynobj = abfd;
+ if (!elf_metag_create_dynamic_sections (dynobj, info))
+ return FALSE;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ switch (r_type)
+ {
+ case R_METAG_TLS_IE:
+ case R_METAG_TLS_GD:
+ case R_METAG_GETSET_GOT:
+ switch (r_type)
+ {
+ default:
+ tls_type = GOT_NORMAL;
+ break;
+ case R_METAG_TLS_IE:
+ tls_type = GOT_TLS_IE;
+ break;
+ case R_METAG_TLS_GD:
+ tls_type = GOT_TLS_GD;
+ break;
+ }
+
+ if (hh != NULL)
+ {
+ hh->eh.got.refcount += 1;
+ old_tls_type = hh->tls_type;
+ }
+ else
+ {
+ bfd_signed_vma *local_got_refcounts;
+
+ /* This is a global offset table entry for a local
+ symbol. */
+ local_got_refcounts = elf_local_got_refcounts (abfd);
+ if (local_got_refcounts == NULL)
+ {
+ bfd_size_type size;
+
+ size = symtab_hdr->sh_info;
+ size *= sizeof (bfd_signed_vma);
+ /* Add in space to store the local GOT TLS types. */
+ size += symtab_hdr->sh_info;
+ local_got_refcounts = ((bfd_signed_vma *)
+ bfd_zalloc (abfd, size));
+ if (local_got_refcounts == NULL)
+ return FALSE;
+ elf_local_got_refcounts (abfd) = local_got_refcounts;
+ memset (metag_elf_local_got_tls_type (abfd),
+ GOT_UNKNOWN, symtab_hdr->sh_info);
+ }
+ local_got_refcounts[r_symndx] += 1;
+ old_tls_type = metag_elf_local_got_tls_type (abfd) [r_symndx];
+ }
+
+ if (old_tls_type != tls_type)
+ {
+ if (hh != NULL)
+ {
+ hh->tls_type = tls_type;
+ }
+ else
+ {
+ metag_elf_local_got_tls_type (abfd) [r_symndx] = tls_type;
+ }
+ }
+
+ break;
+
+ case R_METAG_TLS_LDM:
+ metag_link_hash_table (info)->tls_ldm_got.refcount += 1;
+ break;
+
+ case R_METAG_RELBRANCH_PLT:
+ /* 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 this is a local symbol, we resolve it directly without
+ creating a procedure linkage table entry. */
+ if (hh == NULL)
+ continue;
+
+ if (hh->eh.forced_local)
+ break;
+
+ hh->eh.needs_plt = 1;
+ hh->eh.plt.refcount += 1;
+ break;
+
+ case R_METAG_HIADDR16:
+ case R_METAG_LOADDR16:
+ /* Let's help debug shared library creation. These relocs
+ cannot be used in shared libs. Don't error out for
+ sections we don't care about, such as debug sections or
+ non-constant sections. */
+ if (info->shared
+ && (sec->flags & SEC_ALLOC) != 0
+ && (sec->flags & SEC_READONLY) != 0)
+ {
+ const char *name;
+
+ if (hh)
+ name = hh->eh.root.root.string;
+ else
+ name = bfd_elf_sym_name (abfd, symtab_hdr, isym, NULL);
+ (*_bfd_error_handler)
+ (_("%B: relocation %s against `%s' can not be used when making a shared object; recompile with -fPIC"),
+ abfd, elf_metag_howto_table[r_type].name, name);
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+
+ /* Fall through. */
+ case R_METAG_ADDR32:
+ case R_METAG_RELBRANCH:
+ case R_METAG_GETSETOFF:
+ if (hh != NULL && !info->shared)
+ {
+ hh->eh.non_got_ref = 1;
+ hh->eh.plt.refcount += 1;
+ }
+
+ /* 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
+ dyn_relocs field of the hash table entry. A similar
+ situation occurs when creating shared libraries and symbol
+ visibility changes render the symbol local.
+
+ If on the other hand, we are creating an executable, we
+ may need to keep relocations for symbols satisfied by a
+ dynamic library if we manage to avoid copy relocs for the
+ symbol. */
+ if ((info->shared
+ && (sec->flags & SEC_ALLOC) != 0
+ && (r_type != R_METAG_RELBRANCH
+ || (hh != NULL
+ && (! info->symbolic
+ || hh->eh.root.type == bfd_link_hash_defweak
+ || !hh->eh.def_regular))))
+ || (!info->shared
+ && (sec->flags & SEC_ALLOC) != 0
+ && hh != NULL
+ && (hh->eh.root.type == bfd_link_hash_defweak
+ || !hh->eh.def_regular)))
+ {
+ struct elf_metag_dyn_reloc_entry *hdh_p;
+ struct elf_metag_dyn_reloc_entry **hdh_head;
+
+ if (dynobj == NULL)
+ htab->etab.dynobj = dynobj = abfd;
+
+ /* 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)
+ {
+ sreloc = _bfd_elf_make_dynamic_reloc_section
+ (sec, htab->etab.dynobj, 2, abfd, /*rela?*/ TRUE);
+
+ if (sreloc == NULL)
+ {
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+
+ elf_section_data (sec)->sreloc = sreloc;
+ }
+
+ /* If this is a global symbol, we count the number of
+ relocations we need for this symbol. */
+ if (hh != NULL)
+ hdh_head = &((struct elf_metag_link_hash_entry *) hh)->dyn_relocs;
+ else
+ {
+ /* Track dynamic relocs needed for local syms too. */
+ asection *sr;
+ void *vpp;
+
+ sr = bfd_section_from_elf_index (abfd, isym->st_shndx);
+ if (sr == NULL)
+ sr = sec;
+
+ vpp = &elf_section_data (sr)->local_dynrel;
+ hdh_head = (struct elf_metag_dyn_reloc_entry **) vpp;
+ }
+
+ hdh_p = *hdh_head;
+ if (hdh_p == NULL || hdh_p->sec != sec)
+ {
+ hdh_p = ((struct elf_metag_dyn_reloc_entry *)
+ bfd_alloc (dynobj, sizeof *hdh_p));
+ if (hdh_p == NULL)
+ return FALSE;
+ hdh_p->hdh_next = *hdh_head;
+ *hdh_head = hdh_p;
+ hdh_p->sec = sec;
+ hdh_p->count = 0;
+ hdh_p->relative_count = 0;
+ }
+
+ hdh_p->count += 1;
+ if (ELF32_R_TYPE (rel->r_info) == R_METAG_RELBRANCH)
+ hdh_p->relative_count += 1;
+ }
+ break;
+
+ /* This relocation describes the C++ object vtable hierarchy.
+ Reconstruct it for later use during GC. */
+ case R_METAG_GNU_VTINHERIT:
+ if (!bfd_elf_gc_record_vtinherit (abfd, sec, &hh->eh,
+ rel->r_offset))
+ return FALSE;
+ break;
+
+ /* This relocation describes which C++ vtable entries are actually
+ used. Record for later use during GC. */
+ case R_METAG_GNU_VTENTRY:
+ BFD_ASSERT (hh != NULL);
+ if (hh != NULL
+ && !bfd_elf_gc_record_vtentry (abfd, sec, &hh->eh, rel->r_addend))
+ return FALSE;
+ break;
+ }
+ }
+
+ return TRUE;
+}
+
+/* Copy the extra info we tack onto an elf_link_hash_entry. */
+
+static void
+elf_metag_copy_indirect_symbol (struct bfd_link_info *info,
+ struct elf_link_hash_entry *eh_dir,
+ struct elf_link_hash_entry *eh_ind)
+{
+ struct elf_metag_link_hash_entry *hh_dir, *hh_ind;
+
+ hh_dir = metag_elf_hash_entry (eh_dir);
+ hh_ind = metag_elf_hash_entry (eh_ind);
+
+ if (hh_ind->dyn_relocs != NULL)
+ {
+ if (hh_dir->dyn_relocs != NULL)
+ {
+ struct elf_metag_dyn_reloc_entry **hdh_pp;
+ struct elf_metag_dyn_reloc_entry *hdh_p;
+
+ if (eh_ind->root.type == bfd_link_hash_indirect)
+ abort ();
+
+ /* Add reloc counts against the weak sym to the strong sym
+ list. Merge any entries against the same section. */
+ for (hdh_pp = &hh_ind->dyn_relocs; (hdh_p = *hdh_pp) != NULL; )
+ {
+ struct elf_metag_dyn_reloc_entry *hdh_q;
+
+ for (hdh_q = hh_dir->dyn_relocs; hdh_q != NULL;
+ hdh_q = hdh_q->hdh_next)
+ if (hdh_q->sec == hdh_p->sec)
+ {
+ hdh_q->relative_count += hdh_p->relative_count;
+ hdh_q->count += hdh_p->count;
+ *hdh_pp = hdh_p->hdh_next;
+ break;
+ }
+ if (hdh_q == NULL)
+ hdh_pp = &hdh_p->hdh_next;
+ }
+ *hdh_pp = hh_dir->dyn_relocs;
+ }
+
+ hh_dir->dyn_relocs = hh_ind->dyn_relocs;
+ hh_ind->dyn_relocs = NULL;
+ }
+
+ if (eh_ind->root.type == bfd_link_hash_indirect
+ && eh_dir->got.refcount <= 0)
+ {
+ hh_dir->tls_type = hh_ind->tls_type;
+ hh_ind->tls_type = GOT_UNKNOWN;
+ }
+
+ _bfd_elf_link_hash_copy_indirect (info, eh_dir, eh_ind);
+}
+
+/* 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 bfd_boolean
+elf_metag_adjust_dynamic_symbol (struct bfd_link_info *info,
+ struct elf_link_hash_entry *eh)
+{
+ struct elf_metag_link_hash_table *htab;
+ struct elf_metag_link_hash_entry *hh;
+ struct elf_metag_dyn_reloc_entry *hdh_p;
+ asection *s;
+
+ /* 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 (eh->type == STT_FUNC
+ || eh->needs_plt)
+ {
+ if (eh->plt.refcount <= 0
+ || SYMBOL_CALLS_LOCAL (info, eh)
+ || (ELF_ST_VISIBILITY (eh->other) != STV_DEFAULT
+ && eh->root.type == bfd_link_hash_undefweak))
+ {
+ /* This case can occur if we saw a PLT 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 PCREL
+ reloc instead. */
+ eh->plt.offset = (bfd_vma) -1;
+ eh->needs_plt = 0;
+ }
+
+ return TRUE;
+ }
+ else
+ eh->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 (eh->u.weakdef != NULL)
+ {
+ if (eh->u.weakdef->root.type != bfd_link_hash_defined
+ && eh->u.weakdef->root.type != bfd_link_hash_defweak)
+ abort ();
+ eh->root.u.def.section = eh->u.weakdef->root.u.def.section;
+ eh->root.u.def.value = eh->u.weakdef->root.u.def.value;
+ eh->non_got_ref = eh->u.weakdef->non_got_ref;
+ 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;
+
+ /* If there are no references to this symbol that do not use the
+ GOT, we don't need to generate a copy reloc. */
+ if (!eh->non_got_ref)
+ return TRUE;
+
+ /* If -z nocopyreloc was given, we won't generate them either. */
+ if (info->nocopyreloc)
+ {
+ eh->non_got_ref = 0;
+ return TRUE;
+ }
+
+ hh = (struct elf_metag_link_hash_entry *) eh;
+ for (hdh_p = hh->dyn_relocs; hdh_p != NULL; hdh_p = hdh_p->hdh_next)
+ {
+ s = hdh_p->sec->output_section;
+ if (s != NULL && (s->flags & SEC_READONLY) != 0)
+ break;
+ }
+
+ /* If we didn't find any dynamic relocs in read-only sections, then
+ we'll be keeping the dynamic relocs and avoiding the copy reloc. */
+ if (hdh_p == NULL)
+ {
+ eh->non_got_ref = 0;
+ 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. */
+
+ htab = metag_link_hash_table (info);
+
+ /* We must generate a COPY reloc to tell the dynamic linker to
+ copy the initial value out of the dynamic object and into the
+ runtime process image. */
+ if ((eh->root.u.def.section->flags & SEC_ALLOC) != 0 && eh->size != 0)
+ {
+ htab->srelbss->size += sizeof (Elf32_External_Rela);
+ eh->needs_copy = 1;
+ }
+
+ s = htab->sdynbss;
+
+ return _bfd_elf_adjust_dynamic_copy (eh, s);
+}
+
+/* Allocate space in .plt, .got and associated reloc sections for
+ global syms. */
+
+static bfd_boolean
+allocate_dynrelocs (struct elf_link_hash_entry *eh, void *inf)
+{
+ struct bfd_link_info *info;
+ struct elf_metag_link_hash_table *htab;
+ struct elf_metag_link_hash_entry *hh;
+ struct elf_metag_dyn_reloc_entry *hdh_p;
+
+ if (eh->root.type == bfd_link_hash_indirect)
+ return TRUE;
+
+ if (eh->root.type == bfd_link_hash_warning)
+ eh = (struct elf_link_hash_entry *) eh->root.u.i.link;
+
+ info = inf;
+ htab = metag_link_hash_table (info);
+
+ if (htab->etab.dynamic_sections_created
+ && eh->plt.refcount > 0)
+ {
+ /* Make sure this symbol is output as a dynamic symbol.
+ Undefined weak syms won't yet be marked as dynamic. */
+ if (eh->dynindx == -1
+ && !eh->forced_local)
+ {
+ if (! bfd_elf_link_record_dynamic_symbol (info, eh))
+ return FALSE;
+ }
+
+ if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, info->shared, eh))
+ {
+ asection *s = htab->splt;
+
+ /* If this is the first .plt entry, make room for the special
+ first entry. */
+ if (s->size == 0)
+ s->size += PLT_ENTRY_SIZE;
+
+ eh->plt.offset = s->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
+ && !eh->def_regular)
+ {
+ eh->root.u.def.section = s;
+ eh->root.u.def.value = eh->plt.offset;
+ }
+
+ /* Make room for this entry. */
+ s->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. */
+ htab->sgotplt->size += 4;
+
+ /* We also need to make an entry in the .rel.plt section. */
+ htab->srelplt->size += sizeof (Elf32_External_Rela);
+ }
+ else
+ {
+ eh->plt.offset = (bfd_vma) -1;
+ eh->needs_plt = 0;
+ }
+ }
+ else
+ {
+ eh->plt.offset = (bfd_vma) -1;
+ eh->needs_plt = 0;
+ }
+
+ if (eh->got.refcount > 0)
+ {
+ asection *s;
+ bfd_boolean dyn;
+ int tls_type = metag_elf_hash_entry (eh)->tls_type;
+
+ /* Make sure this symbol is output as a dynamic symbol.
+ Undefined weak syms won't yet be marked as dynamic. */
+ if (eh->dynindx == -1
+ && !eh->forced_local)
+ {
+ if (! bfd_elf_link_record_dynamic_symbol (info, eh))
+ return FALSE;
+ }
+
+ s = htab->sgot;
+
+ eh->got.offset = s->size;
+ s->size += 4;
+ /* R_METAG_TLS_GD needs 2 consecutive GOT slots. */
+ if (tls_type == GOT_TLS_GD)
+ s->size += 4;
+ dyn = htab->etab.dynamic_sections_created;
+ /* R_METAG_TLS_IE needs one dynamic relocation if dynamic,
+ R_METAG_TLS_GD needs one if local symbol and two if global. */
+ if ((tls_type == GOT_TLS_GD && eh->dynindx == -1)
+ || (tls_type == GOT_TLS_IE && dyn))
+ htab->srelgot->size += sizeof (Elf32_External_Rela);
+ else if (tls_type == GOT_TLS_GD)
+ htab->srelgot->size += 2 * sizeof (Elf32_External_Rela);
+ else if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, eh))
+ htab->srelgot->size += sizeof (Elf32_External_Rela);
+ }
+ else
+ eh->got.offset = (bfd_vma) -1;
+
+ hh = (struct elf_metag_link_hash_entry *) eh;
+ if (hh->dyn_relocs == NULL)
+ return TRUE;
+
+ /* If this is a -Bsymbolic shared link, then we need to discard all
+ space allocated for dynamic pc-relative relocs against symbols
+ defined in a regular object. For the normal shared case, discard
+ space for relocs that have become local due to symbol visibility
+ changes. */
+ if (info->shared)
+ {
+ if (SYMBOL_CALLS_LOCAL (info, eh))
+ {
+ struct elf_metag_dyn_reloc_entry **hdh_pp;
+
+ for (hdh_pp = &hh->dyn_relocs; (hdh_p = *hdh_pp) != NULL; )
+ {
+ hdh_p->count -= hdh_p->relative_count;
+ hdh_p->relative_count = 0;
+ if (hdh_p->count == 0)
+ *hdh_pp = hdh_p->hdh_next;
+ else
+ hdh_pp = &hdh_p->hdh_next;
+ }
+ }
+
+ /* Also discard relocs on undefined weak syms with non-default
+ visibility. */
+ if (hh->dyn_relocs != NULL
+ && eh->root.type == bfd_link_hash_undefweak)
+ {
+ if (ELF_ST_VISIBILITY (eh->other) != STV_DEFAULT)
+ hh->dyn_relocs = NULL;
+
+ /* Make sure undefined weak symbols are output as a dynamic
+ symbol in PIEs. */
+ else if (eh->dynindx == -1
+ && !eh->forced_local)
+ {
+ if (! bfd_elf_link_record_dynamic_symbol (info, eh))
+ return FALSE;
+ }
+ }
+ }
+ else
+ {
+ /* For the non-shared case, discard space for relocs against
+ symbols which turn out to need copy relocs or are not
+ dynamic. */
+ if (!eh->non_got_ref
+ && ((eh->def_dynamic
+ && !eh->def_regular)
+ || (htab->etab.dynamic_sections_created
+ && (eh->root.type == bfd_link_hash_undefweak
+ || eh->root.type == bfd_link_hash_undefined))))
+ {
+ /* Make sure this symbol is output as a dynamic symbol.
+ Undefined weak syms won't yet be marked as dynamic. */
+ if (eh->dynindx == -1
+ && !eh->forced_local)
+ {
+ if (! bfd_elf_link_record_dynamic_symbol (info, eh))
+ return FALSE;
+ }
+
+ /* If that succeeded, we know we'll be keeping all the
+ relocs. */
+ if (eh->dynindx != -1)
+ goto keep;
+ }
+
+ hh->dyn_relocs = NULL;
+ return TRUE;
+
+ keep: ;
+ }
+
+ /* Finally, allocate space. */
+ for (hdh_p = hh->dyn_relocs; hdh_p != NULL; hdh_p = hdh_p->hdh_next)
+ {
+ asection *sreloc = elf_section_data (hdh_p->sec)->sreloc;
+ sreloc->size += hdh_p->count * sizeof (Elf32_External_Rela);
+ }
+
+ return TRUE;
+}
+
+/* Find any dynamic relocs that apply to read-only sections. */
+
+static bfd_boolean
+readonly_dynrelocs (struct elf_link_hash_entry *eh, void *inf)
+{
+ struct elf_metag_link_hash_entry *hh;
+ struct elf_metag_dyn_reloc_entry *hdh_p;
+
+ if (eh->root.type == bfd_link_hash_warning)
+ eh = (struct elf_link_hash_entry *) eh->root.u.i.link;
+
+ hh = (struct elf_metag_link_hash_entry *) eh;
+ for (hdh_p = hh->dyn_relocs; hdh_p != NULL; hdh_p = hdh_p->hdh_next)
+ {
+ asection *s = hdh_p->sec->output_section;
+
+ if (s != NULL && (s->flags & SEC_READONLY) != 0)
+ {
+ struct bfd_link_info *info = inf;
+
+ info->flags |= DF_TEXTREL;
+
+ /* Not an error, just cut short the traversal. */
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+/* Set the sizes of the dynamic sections. */
+
+static bfd_boolean
+elf_metag_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
+ struct bfd_link_info *info)
+{
+ struct elf_metag_link_hash_table *htab;
+ bfd *dynobj;
+ bfd *ibfd;
+ asection *s;
+ bfd_boolean relocs;
+
+ htab = metag_link_hash_table (info);
+ dynobj = htab->etab.dynobj;
+ if (dynobj == NULL)
+ abort ();
+
+ if (htab->etab.dynamic_sections_created)
+ {
+ /* Set the contents of the .interp section to the interpreter. */
+ if (info->executable)
+ {
+ s = bfd_get_linker_section (dynobj, ".interp");
+ if (s == NULL)
+ abort ();
+ s->size = sizeof ELF_DYNAMIC_INTERPRETER;
+ s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
+ }
+ }
+
+ /* Set up .got offsets for local syms, and space for local dynamic
+ relocs. */
+ for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next)
+ {
+ bfd_signed_vma *local_got;
+ bfd_signed_vma *end_local_got;
+ bfd_size_type locsymcount;
+ Elf_Internal_Shdr *symtab_hdr;
+ asection *srel;
+ char *local_tls_type;
+
+ if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour)
+ continue;
+
+ for (s = ibfd->sections; s != NULL; s = s->next)
+ {
+ struct elf_metag_dyn_reloc_entry *hdh_p;
+
+ for (hdh_p = ((struct elf_metag_dyn_reloc_entry *)
+ elf_section_data (s)->local_dynrel);
+ hdh_p != NULL;
+ hdh_p = hdh_p->hdh_next)
+ {
+ if (!bfd_is_abs_section (hdh_p->sec)
+ && bfd_is_abs_section (hdh_p->sec->output_section))
+ {
+ /* Input section has been discarded, either because
+ it is a copy of a linkonce section or due to
+ linker script /DISCARD/, so we'll be discarding
+ the relocs too. */
+ }
+ else if (hdh_p->count != 0)
+ {
+ srel = elf_section_data (hdh_p->sec)->sreloc;
+ srel->size += hdh_p->count * sizeof (Elf32_External_Rela);
+ if ((hdh_p->sec->output_section->flags & SEC_READONLY) != 0)
+ info->flags |= DF_TEXTREL;
+ }
+ }
+ }
+
+ local_got = elf_local_got_refcounts (ibfd);
+ if (!local_got)
+ continue;
+
+ symtab_hdr = &elf_tdata (ibfd)->symtab_hdr;
+ locsymcount = symtab_hdr->sh_info;
+ end_local_got = local_got + locsymcount;
+ local_tls_type = metag_elf_local_got_tls_type (ibfd);
+ s = htab->sgot;
+ srel = htab->srelgot;
+ for (; local_got < end_local_got; ++local_got)
+ {
+ if (*local_got > 0)
+ {
+ *local_got = s->size;
+ s->size += GOT_ENTRY_SIZE;
+ /* R_METAG_TLS_GD relocs need 2 consecutive GOT entries. */
+ if (*local_tls_type == GOT_TLS_GD)
+ s->size += 4;
+ if (info->shared)
+ srel->size += sizeof (Elf32_External_Rela);
+ }
+ else
+ *local_got = (bfd_vma) -1;
+ ++local_tls_type;
+ }
+ }
+
+ if (htab->tls_ldm_got.refcount > 0)
+ {
+ /* Allocate 2 got entries and 1 dynamic reloc for R_METAG_TLS_LDM
+ reloc. */
+ htab->tls_ldm_got.offset = htab->sgot->size;
+ htab->sgot->size += 8;
+ htab->srelgot->size += sizeof (Elf32_External_Rela);
+ }
+ else
+ htab->tls_ldm_got.offset = -1;
+
+ /* Allocate global sym .plt and .got entries, and space for global
+ sym dynamic relocs. */
+ elf_link_hash_traverse (&htab->etab, allocate_dynrelocs, info);
+
+ /* We now have determined the sizes of the various dynamic sections.
+ Allocate memory for them. */
+ relocs = FALSE;
+ for (s = dynobj->sections; s != NULL; s = s->next)
+ {
+ bfd_boolean reloc_section = FALSE;
+
+ if ((s->flags & SEC_LINKER_CREATED) == 0)
+ continue;
+
+ if (s == htab->splt
+ || s == htab->sgot
+ || s == htab->sgotplt
+ || s == htab->sdynbss)
+ {
+ /* Strip this section if we don't need it; see the
+ comment below. */
+ }
+ else if (CONST_STRNEQ (bfd_get_section_name (dynobj, s), ".rela"))
+ {
+ if (s->size != 0 && s != htab->srelplt)
+ relocs = TRUE;
+
+ /* We use the reloc_count field as a counter if we need
+ to copy relocs into the output file. */
+ s->reloc_count = 0;
+ reloc_section = TRUE;
+ }
+ else
+ {
+ /* It's not one of our sections, so don't allocate space. */
+ continue;
+ }
+
+ if (s->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. */
+ s->flags |= SEC_EXCLUDE;
+ continue;
+ }
+
+ if ((s->flags & SEC_HAS_CONTENTS) == 0)
+ continue;
+
+ /* Allocate memory for the section contents. */
+ s->contents = bfd_zalloc (dynobj, s->size);
+ if (s->contents == NULL)
+ return FALSE;
+ else if (reloc_section)
+ {
+ unsigned char *contents = s->contents;
+ Elf32_External_Rela reloc;
+
+ /* Fill the reloc section with a R_METAG_NONE type reloc. */
+ memset(&reloc, 0, sizeof(Elf32_External_Rela));
+ reloc.r_info[0] = R_METAG_NONE;
+ for (; contents < (s->contents + s->size);
+ contents += sizeof(Elf32_External_Rela))
+ {
+ memcpy(contents, &reloc, sizeof(Elf32_External_Rela));
+ }
+ }
+ }
+
+ if (htab->etab.dynamic_sections_created)
+ {
+ /* Add some entries to the .dynamic section. We fill in the
+ values later, in elf_metag_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. */
+#define add_dynamic_entry(TAG, VAL) \
+ _bfd_elf_add_dynamic_entry (info, TAG, VAL)
+
+ if (!add_dynamic_entry (DT_PLTGOT, 0))
+ return FALSE;
+
+ if (info->executable)
+ {
+ if (!add_dynamic_entry (DT_DEBUG, 0))
+ return FALSE;
+ }
+
+ if (htab->srelplt->size != 0)
+ {
+ if (!add_dynamic_entry (DT_PLTRELSZ, 0)
+ || !add_dynamic_entry (DT_PLTREL, DT_RELA)
+ || !add_dynamic_entry (DT_JMPREL, 0))
+ return FALSE;
+ }
+
+ if (relocs)
+ {
+ if (!add_dynamic_entry (DT_RELA, 0)
+ || !add_dynamic_entry (DT_RELASZ, 0)
+ || !add_dynamic_entry (DT_RELAENT, sizeof (Elf32_External_Rela)))
+ return FALSE;
+
+ /* If any dynamic relocs apply to a read-only section,
+ then we need a DT_TEXTREL entry. */
+ if ((info->flags & DF_TEXTREL) == 0)
+ elf_link_hash_traverse (&htab->etab, readonly_dynrelocs, info);
+
+ if ((info->flags & DF_TEXTREL) != 0)
+ {
+ if (!add_dynamic_entry (DT_TEXTREL, 0))
+ return FALSE;
+ }
+ }
+ }
+#undef add_dynamic_entry
+
+ return TRUE;
+}
+
+/* Finish up dynamic symbol handling. We set the contents of various
+ dynamic sections here. */
+
+static bfd_boolean
+elf_metag_finish_dynamic_symbol (bfd *output_bfd,
+ struct bfd_link_info *info,
+ struct elf_link_hash_entry *eh,
+ Elf_Internal_Sym *sym)
+{
+ struct elf_metag_link_hash_table *htab;
+ Elf_Internal_Rela rel;
+ bfd_byte *loc;
+
+ htab = metag_link_hash_table (info);
+
+ if (eh->plt.offset != (bfd_vma) -1)
+ {
+ asection *splt;
+ asection *sgot;
+ asection *srela;
+
+ bfd_vma plt_index;
+ bfd_vma got_offset;
+ bfd_vma got_entry;
+
+ if (eh->plt.offset & 1)
+ abort ();
+
+ BFD_ASSERT (eh->dynindx != -1);
+
+ splt = htab->splt;
+ sgot = htab->sgotplt;
+ srela = htab->srelplt;
+ 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 = eh->plt.offset / PLT_ENTRY_SIZE - 1;
+
+ /* Get the offset into the .got.plt table of the entry that
+ corresponds to this function. */
+ got_offset = plt_index * GOT_ENTRY_SIZE;
+
+ BFD_ASSERT (got_offset < (1 << 16));
+
+ got_entry = sgot->output_section->vma
+ + sgot->output_offset
+ + got_offset;
+
+ BFD_ASSERT (plt_index < (1 << 16));
+
+ /* Fill in the entry in the procedure linkage table. */
+ if (! info->shared)
+ {
+ bfd_put_32 (output_bfd,
+ (plt_entry[0]
+ | (((got_entry >> 16) & 0xffff) << 3)),
+ splt->contents + eh->plt.offset);
+ bfd_put_32 (output_bfd,
+ (plt_entry[1]
+ | ((got_entry & 0xffff) << 3)),
+ splt->contents + eh->plt.offset + 4);
+ bfd_put_32 (output_bfd, plt_entry[2],
+ splt->contents + eh->plt.offset + 8);
+ bfd_put_32 (output_bfd,
+ (plt_entry[3] | (plt_index << 3)),
+ splt->contents + eh->plt.offset + 12);
+ bfd_put_32 (output_bfd,
+ (plt_entry[4]
+ | ((((unsigned int) ((- (eh->plt.offset + 16)) >> 2)) & 0x7ffff) << 5)),
+ splt->contents + eh->plt.offset + 16);
+ }
+ else
+ {
+ bfd_vma addr = got_entry - (splt->output_section->vma +
+ splt->output_offset + eh->plt.offset);
+
+ bfd_put_32 (output_bfd,
+ plt_pic_entry[0] | (((addr >> 16) & 0xffff) << 3),
+ splt->contents + eh->plt.offset);
+ bfd_put_32 (output_bfd,
+ plt_pic_entry[1] | ((addr & 0xffff) << 3),
+ splt->contents + eh->plt.offset + 4);
+ bfd_put_32 (output_bfd, plt_pic_entry[2],
+ splt->contents + eh->plt.offset + 8);
+ bfd_put_32 (output_bfd,
+ (plt_pic_entry[3] | (plt_index << 3)),
+ splt->contents + eh->plt.offset + 12);
+ bfd_put_32 (output_bfd,
+ (plt_pic_entry[4]
+ + ((((unsigned int) ((- (eh->plt.offset + 16)) >> 2)) & 0x7ffff) << 5)),
+ splt->contents + eh->plt.offset + 16);
+ }
+
+ /* Fill in the entry in the global offset table. */
+ bfd_put_32 (output_bfd,
+ (splt->output_section->vma
+ + splt->output_offset
+ + eh->plt.offset
+ + 12), /* offset within PLT entry */
+ sgot->contents + got_offset);
+
+ /* Fill in the entry in the .rela.plt section. */
+ rel.r_offset = (sgot->output_section->vma
+ + sgot->output_offset
+ + got_offset);
+ rel.r_info = ELF32_R_INFO (eh->dynindx, R_METAG_JMP_SLOT);
+ rel.r_addend = 0;
+ loc = htab->srelplt->contents;
+ loc += plt_index * sizeof(Elf32_External_Rela);
+ bfd_elf32_swap_reloca_out (output_bfd, &rel, loc);
+
+ if (!eh->def_regular)
+ {
+ /* Mark the symbol as undefined, rather than as defined in
+ the .plt section. Leave the value alone. */
+ sym->st_shndx = SHN_UNDEF;
+ }
+ }
+
+ if (eh->got.offset != (bfd_vma) -1
+ && (metag_elf_hash_entry (eh)->tls_type & GOT_TLS_GD) == 0
+ && (metag_elf_hash_entry (eh)->tls_type & GOT_TLS_IE) == 0)
+ {
+ /* This symbol has an entry in the global offset table. Set it
+ up. */
+
+ rel.r_offset = ((eh->got.offset &~ (bfd_vma) 1)
+ + htab->sgot->output_offset
+ + htab->sgot->output_section->vma);
+
+ /* If this is a -Bsymbolic link and the symbol is defined
+ locally or was forced to be local because of a version file,
+ 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 || eh->dynindx == -1)
+ && eh->def_regular)
+ {
+ rel.r_info = ELF32_R_INFO (0, R_METAG_RELATIVE);
+ rel.r_addend = (eh->root.u.def.value
+ + eh->root.u.def.section->output_offset
+ + eh->root.u.def.section->output_section->vma);
+ }
+ else
+ {
+ if ((eh->got.offset & 1) != 0)
+ abort ();
+ bfd_put_32 (output_bfd, 0, htab->sgot->contents + eh->got.offset);
+ rel.r_info = ELF32_R_INFO (eh->dynindx, R_METAG_GLOB_DAT);
+ rel.r_addend = 0;
+ }
+
+ loc = htab->srelgot->contents;
+ loc += htab->srelgot->reloc_count++ * sizeof (Elf32_External_Rela);
+ bfd_elf32_swap_reloca_out (output_bfd, &rel, loc);
+ }
+
+ if (eh->needs_copy)
+ {
+ asection *s;
+
+ /* This symbol needs a copy reloc. Set it up. */
+
+ if (! (eh->dynindx != -1
+ && (eh->root.type == bfd_link_hash_defined
+ || eh->root.type == bfd_link_hash_defweak)))
+ abort ();
+
+ s = htab->srelbss;
+
+ rel.r_offset = (eh->root.u.def.value
+ + eh->root.u.def.section->output_offset
+ + eh->root.u.def.section->output_section->vma);
+ rel.r_addend = 0;
+ rel.r_info = ELF32_R_INFO (eh->dynindx, R_METAG_COPY);
+ loc = s->contents + s->reloc_count++ * sizeof (Elf32_External_Rela);
+ bfd_elf32_swap_reloca_out (output_bfd, &rel, loc);
+ }
+
+ /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute. */
+ if (eh->root.root.string[0] == '_'
+ && (strcmp (eh->root.root.string, "_DYNAMIC") == 0
+ || eh == htab->etab.hgot))
+ {
+ sym->st_shndx = SHN_ABS;
+ }
+
+ return TRUE;
+}
+
+/* Set the Meta ELF ABI version. */
+
+static void
+elf_metag_post_process_headers (bfd * abfd, struct bfd_link_info * link_info)
+{
+ Elf_Internal_Ehdr * i_ehdrp; /* ELF file header, internal form. */
+
+ _bfd_elf_post_process_headers (abfd, link_info);
+ i_ehdrp = elf_elfheader (abfd);
+ i_ehdrp->e_ident[EI_ABIVERSION] = METAG_ELF_ABI_VERSION;
+}
+
+/* Used to decide how to sort relocs in an optimal manner for the
+ dynamic linker, before writing them out. */
+
+static enum elf_reloc_type_class
+elf_metag_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ const asection *rel_sec ATTRIBUTE_UNUSED,
+ const Elf_Internal_Rela *rela)
+{
+ switch ((int) ELF32_R_TYPE (rela->r_info))
+ {
+ case R_METAG_RELATIVE:
+ return reloc_class_relative;
+ case R_METAG_JMP_SLOT:
+ return reloc_class_plt;
+ case R_METAG_COPY:
+ return reloc_class_copy;
+ default:
+ return reloc_class_normal;
+ }
+}
+
+/* Finish up the dynamic sections. */
+
+static bfd_boolean
+elf_metag_finish_dynamic_sections (bfd *output_bfd,
+ struct bfd_link_info *info)
+{
+ bfd *dynobj;
+ struct elf_metag_link_hash_table *htab;
+ asection *sdyn;
+
+ htab = metag_link_hash_table (info);
+ dynobj = htab->etab.dynobj;
+
+ sdyn = bfd_get_linker_section (dynobj, ".dynamic");
+
+ if (htab->etab.dynamic_sections_created)
+ {
+ asection *splt;
+ Elf32_External_Dyn *dyncon, *dynconend;
+
+ if (sdyn == NULL)
+ abort ();
+
+ dyncon = (Elf32_External_Dyn *) sdyn->contents;
+ dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->size);
+ for (; dyncon < dynconend; dyncon++)
+ {
+ Elf_Internal_Dyn dyn;
+ asection *s;
+
+ bfd_elf32_swap_dyn_in (dynobj, dyncon, &dyn);
+
+ switch (dyn.d_tag)
+ {
+ default:
+ continue;
+
+ case DT_PLTGOT:
+ s = htab->sgot->output_section;
+ BFD_ASSERT (s != NULL);
+ dyn.d_un.d_ptr = s->vma + htab->sgot->output_offset;
+ bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
+ break;
+
+ case DT_JMPREL:
+ s = htab->srelplt->output_section;
+ 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 = htab->srelplt;
+ dyn.d_un.d_val = s->size;
+ bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
+ break;
+
+ case DT_RELASZ:
+ /* Don't count procedure linkage table relocs in the
+ overall reloc count. */
+ if (htab->srelplt) {
+ s = htab->srelplt;
+ dyn.d_un.d_val -= s->size;
+ }
+ bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
+ break;
+
+ case DT_RELA:
+ /* We may not be using the standard ELF linker script.
+ If .rela.plt is the first .rela section, we adjust
+ DT_RELA to not include it. */
+ if (htab->srelplt) {
+ s = htab->srelplt;
+ if (dyn.d_un.d_ptr == s->output_section->vma + s->output_offset)
+ dyn.d_un.d_ptr += s->size;
+ }
+ bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
+ break;
+ }
+
+ }
+
+ /* Fill in the first entry in the procedure linkage table. */
+ splt = htab->splt;
+ if (splt && splt->size > 0)
+ {
+ unsigned long addr;
+ /* addr = .got + 4 */
+ addr = htab->sgot->output_section->vma +
+ htab->sgot->output_offset + 4;
+ if (info->shared)
+ {
+ addr -= splt->output_section->vma + splt->output_offset;
+ bfd_put_32 (output_bfd,
+ plt0_pic_entry[0] | (((addr >> 16) & 0xffff) << 3),
+ splt->contents);
+ bfd_put_32 (output_bfd,
+ plt0_pic_entry[1] | ((addr & 0xffff) << 3),
+ splt->contents + 4);
+ bfd_put_32 (output_bfd, plt0_pic_entry[2], splt->contents + 8);
+ bfd_put_32 (output_bfd, plt0_pic_entry[3], splt->contents + 12);
+ bfd_put_32 (output_bfd, plt0_pic_entry[4], splt->contents + 16);
+ }
+ else
+ {
+ bfd_put_32 (output_bfd,
+ plt0_entry[0] | (((addr >> 16) & 0xffff) << 3),
+ splt->contents);
+ bfd_put_32 (output_bfd,
+ plt0_entry[1] | ((addr & 0xffff) << 3),
+ splt->contents + 4);
+ bfd_put_32 (output_bfd, plt0_entry[2], splt->contents + 8);
+ bfd_put_32 (output_bfd, plt0_entry[3], splt->contents + 12);
+ bfd_put_32 (output_bfd, plt0_entry[4], splt->contents + 16);
+ }
+
+ elf_section_data (splt->output_section)->this_hdr.sh_entsize =
+ PLT_ENTRY_SIZE;
+ }
+ }
+
+ if (htab->sgot != NULL && htab->sgot->size != 0)
+ {
+ /* Fill in the first entry in the global offset table.
+ We use it to point to our dynamic section, if we have one. */
+ bfd_put_32 (output_bfd,
+ sdyn ? sdyn->output_section->vma + sdyn->output_offset : 0,
+ htab->sgot->contents);
+
+ /* The second entry is reserved for use by the dynamic linker. */
+ memset (htab->sgot->contents + GOT_ENTRY_SIZE, 0, GOT_ENTRY_SIZE);
+
+ /* Set .got entry size. */
+ elf_section_data (htab->sgot->output_section)
+ ->this_hdr.sh_entsize = GOT_ENTRY_SIZE;
+ }
+
+ return TRUE;
+}
+
+/* Return the section that should be marked against GC for a given
+ relocation. */
+
+static asection *
+elf_metag_gc_mark_hook (asection *sec,
+ struct bfd_link_info *info,
+ Elf_Internal_Rela *rela,
+ struct elf_link_hash_entry *hh,
+ Elf_Internal_Sym *sym)
+{
+ if (hh != NULL)
+ switch ((unsigned int) ELF32_R_TYPE (rela->r_info))
+ {
+ case R_METAG_GNU_VTINHERIT:
+ case R_METAG_GNU_VTENTRY:
+ return NULL;
+ }
+
+ return _bfd_elf_gc_mark_hook (sec, info, rela, hh, sym);
+}
+
+/* Update the got and plt entry reference counts for the section being
+ removed. */
+
+static bfd_boolean
+elf_metag_gc_sweep_hook (bfd *abfd ATTRIBUTE_UNUSED,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ asection *sec ATTRIBUTE_UNUSED,
+ const Elf_Internal_Rela *relocs ATTRIBUTE_UNUSED)
+{
+ Elf_Internal_Shdr *symtab_hdr;
+ struct elf_link_hash_entry **eh_syms;
+ bfd_signed_vma *local_got_refcounts;
+ bfd_signed_vma *local_plt_refcounts;
+ const Elf_Internal_Rela *rel, *relend;
+
+ if (info->relocatable)
+ return TRUE;
+
+ elf_section_data (sec)->local_dynrel = NULL;
+
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+ eh_syms = elf_sym_hashes (abfd);
+ local_got_refcounts = elf_local_got_refcounts (abfd);
+ local_plt_refcounts = local_got_refcounts;
+ if (local_plt_refcounts != NULL)
+ local_plt_refcounts += symtab_hdr->sh_info;
+
+ relend = relocs + sec->reloc_count;
+ for (rel = relocs; rel < relend; rel++)
+ {
+ unsigned long r_symndx;
+ unsigned int r_type;
+ struct elf_link_hash_entry *eh = NULL;
+
+ r_symndx = ELF32_R_SYM (rel->r_info);
+ if (r_symndx >= symtab_hdr->sh_info)
+ {
+ struct elf_metag_link_hash_entry *hh;
+ struct elf_metag_dyn_reloc_entry **hdh_pp;
+ struct elf_metag_dyn_reloc_entry *hdh_p;
+
+ eh = eh_syms[r_symndx - symtab_hdr->sh_info];
+ while (eh->root.type == bfd_link_hash_indirect
+ || eh->root.type == bfd_link_hash_warning)
+ eh = (struct elf_link_hash_entry *) eh->root.u.i.link;
+ hh = (struct elf_metag_link_hash_entry *) eh;
+
+ for (hdh_pp = &hh->dyn_relocs; (hdh_p = *hdh_pp) != NULL;
+ hdh_pp = &hdh_p->hdh_next)
+ if (hdh_p->sec == sec)
+ {
+ /* Everything must go for SEC. */
+ *hdh_pp = hdh_p->hdh_next;
+ break;
+ }
+ }
+
+ r_type = ELF32_R_TYPE (rel->r_info);
+ switch (r_type)
+ {
+ case R_METAG_TLS_LDM:
+ if (metag_link_hash_table (info)->tls_ldm_got.refcount > 0)
+ metag_link_hash_table (info)->tls_ldm_got.refcount -= 1;
+ break;
+ case R_METAG_TLS_IE:
+ case R_METAG_TLS_GD:
+ case R_METAG_GETSET_GOT:
+ if (eh != NULL)
+ {
+ if (eh->got.refcount > 0)
+ eh->got.refcount -= 1;
+ }
+ else if (local_got_refcounts != NULL)
+ {
+ if (local_got_refcounts[r_symndx] > 0)
+ local_got_refcounts[r_symndx] -= 1;
+ }
+ break;
+
+ case R_METAG_RELBRANCH_PLT:
+ if (eh != NULL)
+ {
+ if (eh->plt.refcount > 0)
+ eh->plt.refcount -= 1;
+ }
+ break;
+
+ case R_METAG_ADDR32:
+ case R_METAG_HIADDR16:
+ case R_METAG_LOADDR16:
+ case R_METAG_GETSETOFF:
+ case R_METAG_RELBRANCH:
+ if (eh != NULL)
+ {
+ struct elf_metag_link_hash_entry *hh;
+ struct elf_metag_dyn_reloc_entry **hdh_pp;
+ struct elf_metag_dyn_reloc_entry *hdh_p;
+
+ if (!info->shared && eh->plt.refcount > 0)
+ eh->plt.refcount -= 1;
+
+ hh = (struct elf_metag_link_hash_entry *) eh;
+
+ for (hdh_pp = &hh->dyn_relocs; (hdh_p = *hdh_pp) != NULL;
+ hdh_pp = &hdh_p->hdh_next)
+ if (hdh_p->sec == sec)
+ {
+ if (ELF32_R_TYPE (rel->r_info) == R_METAG_RELBRANCH)
+ hdh_p->relative_count -= 1;
+ hdh_p->count -= 1;
+ if (hdh_p->count == 0)
+ *hdh_pp = hdh_p->hdh_next;
+ break;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ return TRUE;
+}
+
+/* Determine the type of stub needed, if any, for a call. */
+
+static enum elf_metag_stub_type
+metag_type_of_stub (asection *input_sec,
+ const Elf_Internal_Rela *rel,
+ struct elf_metag_link_hash_entry *hh,
+ bfd_vma destination,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED)
+{
+ bfd_vma location;
+ bfd_vma branch_offset;
+ bfd_vma max_branch_offset;
+
+ if (hh != NULL &&
+ !(hh->eh.root.type == bfd_link_hash_defined
+ || hh->eh.root.type == bfd_link_hash_defweak))
+ return metag_stub_none;
+
+ /* Determine where the call point is. */
+ location = (input_sec->output_offset
+ + input_sec->output_section->vma
+ + rel->r_offset);
+
+ branch_offset = destination - location;
+
+ /* Determine if a long branch stub is needed. Meta branch offsets
+ are signed 19 bits 4 byte aligned. */
+ max_branch_offset = (1 << (BRANCH_BITS-1)) << 2;
+
+ if (branch_offset + max_branch_offset >= 2*max_branch_offset)
+ {
+ if (info->shared)
+ return metag_stub_long_branch_shared;
+ else
+ return metag_stub_long_branch;
+ }
+
+ return metag_stub_none;
+}
+
+#define MOVT_A0_3 0x82180005
+#define JUMP_A0_3 0xac180003
+
+#define MOVT_A1LBP 0x83080005
+#define ADD_A1LBP 0x83080000
+
+#define ADDT_A0_3_CPC 0x82980001
+#define ADD_A0_3_A0_3 0x82180000
+#define MOV_PC_A0_3 0xa3180ca0
+
+static bfd_boolean
+metag_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg ATTRIBUTE_UNUSED)
+{
+ struct elf_metag_stub_hash_entry *hsh;
+ asection *stub_sec;
+ bfd *stub_bfd;
+ bfd_byte *loc;
+ bfd_vma sym_value;
+ int size;
+
+ /* Massage our args to the form they really have. */
+ hsh = (struct elf_metag_stub_hash_entry *) gen_entry;
+
+ stub_sec = hsh->stub_sec;
+
+ /* Make a note of the offset within the stubs for this entry. */
+ hsh->stub_offset = stub_sec->size;
+ loc = stub_sec->contents + hsh->stub_offset;
+
+ stub_bfd = stub_sec->owner;
+
+ switch (hsh->stub_type)
+ {
+ case metag_stub_long_branch_shared:
+ /* A PIC long branch stub is an ADDT and an ADD instruction used to
+ calculate the jump target using A0.3 as a temporary. Then a MOV
+ to PC carries out the jump. */
+ sym_value = (hsh->target_value
+ + hsh->target_section->output_offset
+ + hsh->target_section->output_section->vma
+ + hsh->addend);
+
+ sym_value -= (hsh->stub_offset
+ + stub_sec->output_offset
+ + stub_sec->output_section->vma);
+
+ bfd_put_32 (stub_bfd, ADDT_A0_3_CPC | (((sym_value >> 16) & 0xffff) << 3),
+ loc);
+
+ bfd_put_32 (stub_bfd, ADD_A0_3_A0_3 | ((sym_value & 0xffff) << 3),
+ loc + 4);
+
+ bfd_put_32 (stub_bfd, MOV_PC_A0_3, loc + 8);
+
+ size = 12;
+ break;
+ case metag_stub_long_branch:
+ /* A standard long branch stub is a MOVT instruction followed by a
+ JUMP instruction using the A0.3 register as a temporary. This is
+ the same method used by the LDLK linker (patch.c). */
+ sym_value = (hsh->target_value
+ + hsh->target_section->output_offset
+ + hsh->target_section->output_section->vma
+ + hsh->addend);
+
+ bfd_put_32 (stub_bfd, MOVT_A0_3 | (((sym_value >> 16) & 0xffff) << 3),
+ loc);
+
+ bfd_put_32 (stub_bfd, JUMP_A0_3 | ((sym_value & 0xffff) << 3), loc + 4);
+
+ size = 8;
+ break;
+ default:
+ BFD_FAIL ();
+ return FALSE;
+ }
+
+ stub_sec->size += size;
+ return TRUE;
+}
+
+/* As above, but don't actually build the stub. Just bump offset so
+ we know stub section sizes. */
+
+static bfd_boolean
+metag_size_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg ATTRIBUTE_UNUSED)
+{
+ struct elf_metag_stub_hash_entry *hsh;
+ int size = 0;
+
+ /* Massage our args to the form they really have. */
+ hsh = (struct elf_metag_stub_hash_entry *) gen_entry;
+
+ if (hsh->stub_type == metag_stub_long_branch)
+ size = 8;
+ else if (hsh->stub_type == metag_stub_long_branch_shared)
+ size = 12;
+
+ hsh->stub_sec->size += size;
+ return TRUE;
+}
+
+/* Set up various things so that we can make a list of input sections
+ for each output section included in the link. Returns -1 on error,
+ 0 when no stubs will be needed, and 1 on success. */
+
+int
+elf_metag_setup_section_lists (bfd *output_bfd, struct bfd_link_info *info)
+{
+ bfd *input_bfd;
+ unsigned int bfd_count;
+ int top_id, top_index;
+ asection *section;
+ asection **input_list, **list;
+ bfd_size_type amt;
+ struct elf_metag_link_hash_table *htab = metag_link_hash_table (info);
+
+ /* Count the number of input BFDs and find the top input section id. */
+ for (input_bfd = info->input_bfds, bfd_count = 0, top_id = 0;
+ input_bfd != NULL;
+ input_bfd = input_bfd->link.next)
+ {
+ bfd_count += 1;
+ for (section = input_bfd->sections;
+ section != NULL;
+ section = section->next)
+ {
+ if (top_id < section->id)
+ top_id = section->id;
+ }
+ }
+
+ htab->bfd_count = bfd_count;
+
+ amt = sizeof (struct map_stub) * (top_id + 1);
+ htab->stub_group = bfd_zmalloc (amt);
+ if (htab->stub_group == NULL)
+ return -1;
+
+ /* We can't use output_bfd->section_count here to find the top output
+ section index as some sections may have been removed, and
+ strip_excluded_output_sections doesn't renumber the indices. */
+ for (section = output_bfd->sections, top_index = 0;
+ section != NULL;
+ section = section->next)
+ {
+ if (top_index < section->index)
+ top_index = section->index;
+ }
+
+ htab->top_index = top_index;
+ amt = sizeof (asection *) * (top_index + 1);
+ input_list = bfd_malloc (amt);
+ htab->input_list = input_list;
+ if (input_list == NULL)
+ return -1;
+
+ /* For sections we aren't interested in, mark their entries with a
+ value we can check later. */
+ list = input_list + top_index;
+ do
+ *list = bfd_abs_section_ptr;
+ while (list-- != input_list);
+
+ for (section = output_bfd->sections;
+ section != NULL;
+ section = section->next)
+ {
+ /* FIXME: This is a bit of hack. Currently our .ctors and .dtors
+ * have PC relative relocs in them but no code flag set. */
+ if (((section->flags & SEC_CODE) != 0) ||
+ strcmp(".ctors", section->name) ||
+ strcmp(".dtors", section->name))
+ input_list[section->index] = NULL;
+ }
+
+ return 1;
+}
+
+/* The linker repeatedly calls this function for each input section,
+ in the order that input sections are linked into output sections.
+ Build lists of input sections to determine groupings between which
+ we may insert linker stubs. */
+
+void
+elf_metag_next_input_section (struct bfd_link_info *info, asection *isec)
+{
+ struct elf_metag_link_hash_table *htab = metag_link_hash_table (info);
+
+ if (isec->output_section->index <= htab->top_index)
+ {
+ asection **list = htab->input_list + isec->output_section->index;
+ if (*list != bfd_abs_section_ptr)
+ {
+ /* Steal the link_sec pointer for our list. */
+#define PREV_SEC(sec) (htab->stub_group[(sec)->id].link_sec)
+ /* This happens to make the list in reverse order,
+ which is what we want. */
+ PREV_SEC (isec) = *list;
+ *list = isec;
+ }
+ }
+}
+
+/* See whether we can group stub sections together. Grouping stub
+ sections may result in fewer stubs. More importantly, we need to
+ put all .init* and .fini* stubs at the beginning of the .init or
+ .fini output sections respectively, because glibc splits the
+ _init and _fini functions into multiple parts. Putting a stub in
+ the middle of a function is not a good idea. */
+
+static void
+group_sections (struct elf_metag_link_hash_table *htab,
+ bfd_size_type stub_group_size,
+ bfd_boolean stubs_always_before_branch)
+{
+ asection **list = htab->input_list + htab->top_index;
+ do
+ {
+ asection *tail = *list;
+ if (tail == bfd_abs_section_ptr)
+ continue;
+ while (tail != NULL)
+ {
+ asection *curr;
+ asection *prev;
+ bfd_size_type total;
+ bfd_boolean big_sec;
+
+ curr = tail;
+ total = tail->size;
+ big_sec = total >= stub_group_size;
+
+ while ((prev = PREV_SEC (curr)) != NULL
+ && ((total += curr->output_offset - prev->output_offset)
+ < stub_group_size))
+ curr = prev;
+
+ /* OK, the size from the start of CURR to the end is less
+ than stub_group_size bytes and thus can be handled by one stub
+ section. (or the tail section is itself larger than
+ stub_group_size bytes, in which case we may be toast.)
+ We should really be keeping track of the total size of
+ stubs added here, as stubs contribute to the final output
+ section size. */
+ do
+ {
+ prev = PREV_SEC (tail);
+ /* Set up this stub group. */
+ htab->stub_group[tail->id].link_sec = curr;
+ }
+ while (tail != curr && (tail = prev) != NULL);
+
+ /* But wait, there's more! Input sections up to stub_group_size
+ bytes before the stub section can be handled by it too.
+ Don't do this if we have a really large section after the
+ stubs, as adding more stubs increases the chance that
+ branches may not reach into the stub section. */
+ if (!stubs_always_before_branch && !big_sec)
+ {
+ total = 0;
+ while (prev != NULL
+ && ((total += tail->output_offset - prev->output_offset)
+ < stub_group_size))
+ {
+ tail = prev;
+ prev = PREV_SEC (tail);
+ htab->stub_group[tail->id].link_sec = curr;
+ }
+ }
+ tail = prev;
+ }
+ }
+ while (list-- != htab->input_list);
+ free (htab->input_list);
+#undef PREV_SEC
+}
+
+/* Read in all local syms for all input bfds.
+ Returns -1 on error, 0 otherwise. */
+
+static int
+get_local_syms (bfd *output_bfd ATTRIBUTE_UNUSED, bfd *input_bfd,
+ struct bfd_link_info *info)
+{
+ unsigned int bfd_indx;
+ Elf_Internal_Sym *local_syms, **all_local_syms;
+ int stub_changed = 0;
+ struct elf_metag_link_hash_table *htab = metag_link_hash_table (info);
+
+ /* 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. */
+ bfd_size_type amt = sizeof (Elf_Internal_Sym *) * htab->bfd_count;
+ all_local_syms = bfd_zmalloc (amt);
+ htab->all_local_syms = all_local_syms;
+ if (all_local_syms == NULL)
+ return -1;
+
+ /* Walk over all the input BFDs, swapping in local symbols. */
+ for (bfd_indx = 0;
+ input_bfd != NULL;
+ input_bfd = input_bfd->link.next, bfd_indx++)
+ {
+ Elf_Internal_Shdr *symtab_hdr;
+
+ /* 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. */
+ local_syms = (Elf_Internal_Sym *) symtab_hdr->contents;
+ if (local_syms == NULL)
+ {
+ local_syms = bfd_elf_get_elf_syms (input_bfd, symtab_hdr,
+ symtab_hdr->sh_info, 0,
+ NULL, NULL, NULL);
+ /* Cache them for elf_link_input_bfd. */
+ symtab_hdr->contents = (unsigned char *) local_syms;
+ }
+ if (local_syms == NULL)
+ return -1;
+
+ all_local_syms[bfd_indx] = local_syms;
+ }
+
+ return stub_changed;
+}
+
+/* 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 "CALLR"
+instruction. */
+
+/* See elf32-hppa.c and elf64-ppc.c. */
+
+bfd_boolean
+elf_metag_size_stubs(bfd *output_bfd, bfd *stub_bfd,
+ struct bfd_link_info *info,
+ bfd_signed_vma group_size,
+ asection * (*add_stub_section) (const char *, asection *),
+ void (*layout_sections_again) (void))
+{
+ bfd_size_type stub_group_size;
+ bfd_boolean stubs_always_before_branch;
+ bfd_boolean stub_changed;
+ struct elf_metag_link_hash_table *htab = metag_link_hash_table (info);
+
+ /* Stash our params away. */
+ htab->stub_bfd = stub_bfd;
+ htab->add_stub_section = add_stub_section;
+ htab->layout_sections_again = layout_sections_again;
+ stubs_always_before_branch = group_size < 0;
+ if (group_size < 0)
+ stub_group_size = -group_size;
+ else
+ stub_group_size = group_size;
+ if (stub_group_size == 1)
+ {
+ /* Default values. */
+ /* FIXME: not sure what these values should be */
+ if (stubs_always_before_branch)
+ {
+ stub_group_size = (1 << BRANCH_BITS);
+ }
+ else
+ {
+ stub_group_size = (1 << BRANCH_BITS);
+ }
+ }
+
+ group_sections (htab, stub_group_size, stubs_always_before_branch);
+
+ switch (get_local_syms (output_bfd, info->input_bfds, info))
+ {
+ default:
+ if (htab->all_local_syms)
+ goto error_ret_free_local;
+ return FALSE;
+
+ case 0:
+ stub_changed = FALSE;
+ break;
+
+ case 1:
+ stub_changed = TRUE;
+ break;
+ }
+
+ while (1)
+ {
+ bfd *input_bfd;
+ unsigned int bfd_indx;
+ asection *stub_sec;
+
+ for (input_bfd = info->input_bfds, bfd_indx = 0;
+ input_bfd != NULL;
+ input_bfd = input_bfd->link.next, bfd_indx++)
+ {
+ Elf_Internal_Shdr *symtab_hdr;
+ asection *section;
+ Elf_Internal_Sym *local_syms;
+
+ /* 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 = htab->all_local_syms[bfd_indx];
+
+ /* Walk over each section attached to the input bfd. */
+ for (section = input_bfd->sections;
+ section != NULL;
+ section = section->next)
+ {
+ Elf_Internal_Rela *internal_relocs, *irelaend, *irela;
+
+ /* If there aren't any relocs, then there's nothing more
+ to do. */
+ if ((section->flags & SEC_RELOC) == 0
+ || section->reloc_count == 0)
+ continue;
+
+ /* If this section is a link-once section that will be
+ discarded, then don't create any stubs. */
+ if (section->output_section == NULL
+ || section->output_section->owner != output_bfd)
+ continue;
+
+ /* Get the relocs. */
+ internal_relocs
+ = _bfd_elf_link_read_relocs (input_bfd, section, NULL, NULL,
+ info->keep_memory);
+ if (internal_relocs == NULL)
+ goto error_ret_free_local;
+
+ /* Now examine each relocation. */
+ irela = internal_relocs;
+ irelaend = irela + section->reloc_count;
+ for (; irela < irelaend; irela++)
+ {
+ unsigned int r_type, r_indx;
+ enum elf_metag_stub_type stub_type;
+ struct elf_metag_stub_hash_entry *hsh;
+ asection *sym_sec;
+ bfd_vma sym_value;
+ bfd_vma destination;
+ struct elf_metag_link_hash_entry *hh;
+ char *stub_name;
+ const asection *id_sec;
+
+ r_type = ELF32_R_TYPE (irela->r_info);
+ r_indx = ELF32_R_SYM (irela->r_info);
+
+ if (r_type >= (unsigned int) R_METAG_MAX)
+ {
+ bfd_set_error (bfd_error_bad_value);
+ error_ret_free_internal:
+ if (elf_section_data (section)->relocs == NULL)
+ free (internal_relocs);
+ goto error_ret_free_local;
+ }
+
+ /* Only look for stubs on CALLR and B instructions. */
+ if (!(r_type == (unsigned int) R_METAG_RELBRANCH ||
+ r_type == (unsigned int) R_METAG_RELBRANCH_PLT))
+ continue;
+
+ /* Now determine the call target, its name, value,
+ section. */
+ sym_sec = NULL;
+ sym_value = 0;
+ destination = 0;
+ hh = NULL;
+ if (r_indx < symtab_hdr->sh_info)
+ {
+ /* It's a local symbol. */
+ Elf_Internal_Sym *sym;
+ Elf_Internal_Shdr *hdr;
+ unsigned int shndx;
+
+ sym = local_syms + r_indx;
+ if (ELF_ST_TYPE (sym->st_info) != STT_SECTION)
+ sym_value = sym->st_value;
+ shndx = sym->st_shndx;
+ if (shndx < elf_numsections (input_bfd))
+ {
+ hdr = elf_elfsections (input_bfd)[shndx];
+ sym_sec = hdr->bfd_section;
+ destination = (sym_value + irela->r_addend
+ + sym_sec->output_offset
+ + sym_sec->output_section->vma);
+ }
+ }
+ else
+ {
+ /* It's an external symbol. */
+ int e_indx;
+
+ e_indx = r_indx - symtab_hdr->sh_info;
+ hh = ((struct elf_metag_link_hash_entry *)
+ elf_sym_hashes (input_bfd)[e_indx]);
+
+ while (hh->eh.root.type == bfd_link_hash_indirect
+ || hh->eh.root.type == bfd_link_hash_warning)
+ hh = ((struct elf_metag_link_hash_entry *)
+ hh->eh.root.u.i.link);
+
+ if (hh->eh.root.type == bfd_link_hash_defined
+ || hh->eh.root.type == bfd_link_hash_defweak)
+ {
+ sym_sec = hh->eh.root.u.def.section;
+ sym_value = hh->eh.root.u.def.value;
+ if (hh->eh.plt.offset != (bfd_vma) -1
+ && hh->eh.dynindx != -1
+ && r_type == (unsigned int) R_METAG_RELBRANCH_PLT)
+ {
+ sym_sec = htab->splt;
+ sym_value = hh->eh.plt.offset;
+ }
+
+ if (sym_sec->output_section != NULL)
+ destination = (sym_value + irela->r_addend
+ + sym_sec->output_offset
+ + sym_sec->output_section->vma);
+ else
+ continue;
+ }
+ else if (hh->eh.root.type == bfd_link_hash_undefweak)
+ {
+ if (! info->shared)
+ continue;
+ }
+ else if (hh->eh.root.type == bfd_link_hash_undefined)
+ {
+ if (! (info->unresolved_syms_in_objects == RM_IGNORE
+ && (ELF_ST_VISIBILITY (hh->eh.other)
+ == STV_DEFAULT)))
+ continue;
+ }
+ else
+ {
+ bfd_set_error (bfd_error_bad_value);
+ goto error_ret_free_internal;
+ }
+ }
+
+ /* Determine what (if any) linker stub is needed. */
+ stub_type = metag_type_of_stub (section, irela, hh,
+ destination, info);
+ if (stub_type == metag_stub_none)
+ continue;
+
+ /* Support for grouping stub sections. */
+ id_sec = htab->stub_group[section->id].link_sec;
+
+ /* Get the name of this stub. */
+ stub_name = metag_stub_name (id_sec, sym_sec, hh, irela);
+ if (!stub_name)
+ goto error_ret_free_internal;
+
+ hsh = metag_stub_hash_lookup (&htab->bstab,
+ stub_name,
+ FALSE, FALSE);
+ if (hsh != NULL)
+ {
+ /* The proper stub has already been created. */
+ free (stub_name);
+ continue;
+ }
+
+ hsh = metag_add_stub (stub_name, section, htab);
+ if (hsh == NULL)
+ {
+ free (stub_name);
+ goto error_ret_free_internal;
+ }
+ hsh->target_value = sym_value;
+ hsh->target_section = sym_sec;
+ hsh->stub_type = stub_type;
+ hsh->hh = hh;
+ hsh->addend = irela->r_addend;
+ stub_changed = TRUE;
+ }
+
+ /* We're done with the internal relocs, free them. */
+ if (elf_section_data (section)->relocs == NULL)
+ free (internal_relocs);
+ }
+ }
+
+ if (!stub_changed)
+ break;
+
+ /* OK, we've added some stubs. Find out the new size of the
+ stub sections. */
+ for (stub_sec = htab->stub_bfd->sections;
+ stub_sec != NULL;
+ stub_sec = stub_sec->next)
+ stub_sec->size = 0;
+
+ bfd_hash_traverse (&htab->bstab, metag_size_one_stub, htab);
+
+ /* Ask the linker to do its stuff. */
+ (*htab->layout_sections_again) ();
+ stub_changed = FALSE;
+ }
+
+ free (htab->all_local_syms);
+ return TRUE;
+
+ error_ret_free_local:
+ free (htab->all_local_syms);
+ return FALSE;
+}
+
+/* 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 function is called via metagelf_finish in the linker. */
+
+bfd_boolean
+elf_metag_build_stubs (struct bfd_link_info *info)
+{
+ asection *stub_sec;
+ struct bfd_hash_table *table;
+ struct elf_metag_link_hash_table *htab;
+
+ htab = metag_link_hash_table (info);
+
+ for (stub_sec = htab->stub_bfd->sections;
+ stub_sec != NULL;
+ stub_sec = stub_sec->next)
+ {
+ bfd_size_type size;
+
+ /* Allocate memory to hold the linker stubs. */
+ size = stub_sec->size;
+ stub_sec->contents = bfd_zalloc (htab->stub_bfd, size);
+ if (stub_sec->contents == NULL && size != 0)
+ return FALSE;
+ stub_sec->size = 0;
+ }
+
+ /* Build the stubs as directed by the stub hash table. */
+ table = &htab->bstab;
+ bfd_hash_traverse (table, metag_build_one_stub, info);
+
+ return TRUE;
+}
+
+/* Return TRUE if SYM represents a local label symbol. */
+
+static bfd_boolean
+elf_metag_is_local_label_name (bfd *abfd ATTRIBUTE_UNUSED, const char *name)
+{
+ if (name[0] == '$' && name[1] == 'L')
+ return 1;
+ return _bfd_elf_is_local_label_name (abfd, name);
+}
+
+/* Return address for Ith PLT stub in section PLT, for relocation REL
+ or (bfd_vma) -1 if it should not be included. */
+
+static bfd_vma
+elf_metag_plt_sym_val (bfd_vma i, const asection *plt,
+ const arelent *rel ATTRIBUTE_UNUSED)
+{
+ return plt->vma + (i + 1) * PLT_ENTRY_SIZE;
+}
+
+#define ELF_ARCH bfd_arch_metag
+#define ELF_TARGET_ID METAG_ELF_DATA
+#define ELF_MACHINE_CODE EM_METAG
+#define ELF_MINPAGESIZE 0x1000
+#define ELF_MAXPAGESIZE 0x4000
+#define ELF_COMMONPAGESIZE 0x1000
+
+#define TARGET_LITTLE_SYM metag_elf32_vec
+#define TARGET_LITTLE_NAME "elf32-metag"
+
+#define elf_symbol_leading_char '_'
+
+#define elf_info_to_howto_rel NULL
+#define elf_info_to_howto metag_info_to_howto_rela
+
+#define bfd_elf32_bfd_is_local_label_name elf_metag_is_local_label_name
+#define bfd_elf32_bfd_link_hash_table_create \
+ elf_metag_link_hash_table_create
+#define elf_backend_relocate_section elf_metag_relocate_section
+#define elf_backend_gc_mark_hook elf_metag_gc_mark_hook
+#define elf_backend_gc_sweep_hook elf_metag_gc_sweep_hook
+#define elf_backend_check_relocs elf_metag_check_relocs
+#define elf_backend_create_dynamic_sections elf_metag_create_dynamic_sections
+#define elf_backend_adjust_dynamic_symbol elf_metag_adjust_dynamic_symbol
+#define elf_backend_finish_dynamic_symbol elf_metag_finish_dynamic_symbol
+#define elf_backend_finish_dynamic_sections elf_metag_finish_dynamic_sections
+#define elf_backend_size_dynamic_sections elf_metag_size_dynamic_sections
+#define elf_backend_omit_section_dynsym \
+ ((bfd_boolean (*) (bfd *, struct bfd_link_info *, asection *)) bfd_true)
+#define elf_backend_post_process_headers elf_metag_post_process_headers
+#define elf_backend_reloc_type_class elf_metag_reloc_type_class
+#define elf_backend_copy_indirect_symbol elf_metag_copy_indirect_symbol
+#define elf_backend_plt_sym_val elf_metag_plt_sym_val
+
+#define elf_backend_can_gc_sections 1
+#define elf_backend_can_refcount 1
+#define elf_backend_got_header_size 12
+#define elf_backend_rela_normal 1
+#define elf_backend_want_got_sym 0
+#define elf_backend_want_plt_sym 0
+#define elf_backend_plt_readonly 1
+
+#define bfd_elf32_bfd_reloc_type_lookup metag_reloc_type_lookup
+#define bfd_elf32_bfd_reloc_name_lookup metag_reloc_name_lookup
+
+#include "elf32-target.h"
diff --git a/bfd/elf32-metag.h b/bfd/elf32-metag.h
new file mode 100644
index 0000000..57f9e95
--- /dev/null
+++ b/bfd/elf32-metag.h
@@ -0,0 +1,38 @@
+/* Meta support for 32-bit ELF
+ Copyright (C) 2013-2014 Free Software Foundation, Inc.
+ Contributed by Imagination Technologies Ltd.
+
+ This file is part of BFD, the Binary File Descriptor library.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#ifndef _ELF32_METAG_H
+#define _ELF32_METAG_H
+
+extern int elf_metag_setup_section_lists
+ (bfd *, struct bfd_link_info *);
+
+extern void elf_metag_next_input_section
+ (struct bfd_link_info *, asection *);
+
+extern bfd_boolean elf_metag_size_stubs
+ (bfd *, bfd *, struct bfd_link_info *, bfd_signed_vma,
+ asection * (*) (const char *, asection *), void (*) (void));
+
+extern bfd_boolean elf_metag_build_stubs
+ (struct bfd_link_info *);
+
+#endif /* _ELF32_METAG_H */
diff --git a/bfd/elf32-microblaze.c b/bfd/elf32-microblaze.c
new file mode 100644
index 0000000..a4cc6a3
--- /dev/null
+++ b/bfd/elf32-microblaze.c
@@ -0,0 +1,3509 @@
+/* Xilinx MicroBlaze-specific support for 32-bit ELF
+
+ Copyright (C) 2009-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the
+ Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
+ Boston, MA 02110-1301, USA. */
+
+
+int dbg = 0;
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "bfdlink.h"
+#include "libbfd.h"
+#include "elf-bfd.h"
+#include "elf/microblaze.h"
+#include <assert.h>
+
+#define USE_RELA /* Only USE_REL is actually significant, but this is
+ here are a reminder... */
+#define INST_WORD_SIZE 4
+
+static int ro_small_data_pointer = 0;
+static int rw_small_data_pointer = 0;
+
+static reloc_howto_type * microblaze_elf_howto_table [(int) R_MICROBLAZE_max];
+
+static reloc_howto_type microblaze_elf_howto_raw[] =
+{
+ /* This reloc does nothing. */
+ HOWTO (R_MICROBLAZE_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. */
+ NULL, /* Special Function. */
+ "R_MICROBLAZE_NONE", /* Name. */
+ FALSE, /* Partial Inplace. */
+ 0, /* Source Mask. */
+ 0, /* Dest Mask. */
+ FALSE), /* PC relative offset? */
+
+ /* A standard 32 bit relocation. */
+ HOWTO (R_MICROBLAZE_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_MICROBLAZE_32", /* Name. */
+ FALSE, /* Partial Inplace. */
+ 0, /* Source Mask. */
+ 0xffffffff, /* Dest Mask. */
+ FALSE), /* PC relative offset? */
+
+ /* A standard PCREL 32 bit relocation. */
+ HOWTO (R_MICROBLAZE_32_PCREL,/* 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_MICROBLAZE_32_PCREL", /* Name. */
+ TRUE, /* Partial Inplace. */
+ 0, /* Source Mask. */
+ 0xffffffff, /* Dest Mask. */
+ TRUE), /* PC relative offset? */
+
+ /* A 64 bit PCREL relocation. Table-entry not really used. */
+ HOWTO (R_MICROBLAZE_64_PCREL,/* Type. */
+ 0, /* Rightshift. */
+ 2, /* Size (0 = byte, 1 = short, 2 = long). */
+ 16, /* Bitsize. */
+ TRUE, /* PC_relative. */
+ 0, /* Bitpos. */
+ complain_overflow_dont, /* Complain on overflow. */
+ bfd_elf_generic_reloc,/* Special Function. */
+ "R_MICROBLAZE_64_PCREL", /* Name. */
+ FALSE, /* Partial Inplace. */
+ 0, /* Source Mask. */
+ 0x0000ffff, /* Dest Mask. */
+ TRUE), /* PC relative offset? */
+
+ /* The low half of a PCREL 32 bit relocation. */
+ HOWTO (R_MICROBLAZE_32_PCREL_LO, /* 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_MICROBLAZE_32_PCREL_LO", /* Name. */
+ FALSE, /* Partial Inplace. */
+ 0, /* Source Mask. */
+ 0x0000ffff, /* Dest Mask. */
+ TRUE), /* PC relative offset? */
+
+ /* A 64 bit relocation. Table entry not really used. */
+ HOWTO (R_MICROBLAZE_64, /* 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_MICROBLAZE_64", /* Name. */
+ FALSE, /* Partial Inplace. */
+ 0, /* Source Mask. */
+ 0x0000ffff, /* Dest Mask. */
+ FALSE), /* PC relative offset? */
+
+ /* The low half of a 32 bit relocation. */
+ HOWTO (R_MICROBLAZE_32_LO, /* 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_MICROBLAZE_32_LO", /* Name. */
+ FALSE, /* Partial Inplace. */
+ 0, /* Source Mask. */
+ 0x0000ffff, /* Dest Mask. */
+ FALSE), /* PC relative offset? */
+
+ /* Read-only small data section relocation. */
+ HOWTO (R_MICROBLAZE_SRO32, /* 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_MICROBLAZE_SRO32", /* Name. */
+ FALSE, /* Partial Inplace. */
+ 0, /* Source Mask. */
+ 0x0000ffff, /* Dest Mask. */
+ FALSE), /* PC relative offset? */
+
+ /* Read-write small data area relocation. */
+ HOWTO (R_MICROBLAZE_SRW32, /* 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_MICROBLAZE_SRW32", /* Name. */
+ FALSE, /* Partial Inplace. */
+ 0, /* Source Mask. */
+ 0x0000ffff, /* Dest Mask. */
+ FALSE), /* PC relative offset? */
+
+ /* This reloc does nothing. Used for relaxation. */
+ HOWTO (R_MICROBLAZE_64_NONE, /* 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. */
+ "R_MICROBLAZE_64_NONE",/* Name. */
+ FALSE, /* Partial Inplace. */
+ 0, /* Source Mask. */
+ 0, /* Dest Mask. */
+ FALSE), /* PC relative offset? */
+
+ /* Symbol Op Symbol relocation. */
+ HOWTO (R_MICROBLAZE_32_SYM_OP_SYM, /* 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_MICROBLAZE_32_SYM_OP_SYM", /* Name. */
+ FALSE, /* Partial Inplace. */
+ 0, /* Source Mask. */
+ 0xffffffff, /* Dest Mask. */
+ FALSE), /* PC relative offset? */
+
+ /* GNU extension to record C++ vtable hierarchy. */
+ HOWTO (R_MICROBLAZE_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_MICROBLAZE_GNU_VTINHERIT", /* Name. */
+ FALSE, /* Partial Inplace. */
+ 0, /* Source Mask. */
+ 0, /* Dest Mask. */
+ FALSE), /* PC relative offset? */
+
+ /* GNU extension to record C++ vtable member usage. */
+ HOWTO (R_MICROBLAZE_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_MICROBLAZE_GNU_VTENTRY", /* Name. */
+ FALSE, /* Partial Inplace. */
+ 0, /* Source Mask. */
+ 0, /* Dest Mask. */
+ FALSE), /* PC relative offset? */
+
+ /* A 64 bit GOTPC relocation. Table-entry not really used. */
+ HOWTO (R_MICROBLAZE_GOTPC_64, /* Type. */
+ 0, /* Rightshift. */
+ 2, /* Size (0 = byte, 1 = short, 2 = long). */
+ 16, /* Bitsize. */
+ TRUE, /* PC_relative. */
+ 0, /* Bitpos. */
+ complain_overflow_dont, /* Complain on overflow. */
+ bfd_elf_generic_reloc, /* Special Function. */
+ "R_MICROBLAZE_GOTPC_64", /* Name. */
+ FALSE, /* Partial Inplace. */
+ 0, /* Source Mask. */
+ 0x0000ffff, /* Dest Mask. */
+ TRUE), /* PC relative offset? */
+
+ /* A 64 bit GOT relocation. Table-entry not really used. */
+ HOWTO (R_MICROBLAZE_GOT_64, /* 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_MICROBLAZE_GOT_64",/* Name. */
+ FALSE, /* Partial Inplace. */
+ 0, /* Source Mask. */
+ 0x0000ffff, /* Dest Mask. */
+ FALSE), /* PC relative offset? */
+
+ /* A 64 bit PLT relocation. Table-entry not really used. */
+ HOWTO (R_MICROBLAZE_PLT_64, /* Type. */
+ 0, /* Rightshift. */
+ 2, /* Size (0 = byte, 1 = short, 2 = long). */
+ 16, /* Bitsize. */
+ TRUE, /* PC_relative. */
+ 0, /* Bitpos. */
+ complain_overflow_dont, /* Complain on overflow. */
+ bfd_elf_generic_reloc,/* Special Function. */
+ "R_MICROBLAZE_PLT_64",/* Name. */
+ FALSE, /* Partial Inplace. */
+ 0, /* Source Mask. */
+ 0x0000ffff, /* Dest Mask. */
+ TRUE), /* PC relative offset? */
+
+ /* Table-entry not really used. */
+ HOWTO (R_MICROBLAZE_REL, /* Type. */
+ 0, /* Rightshift. */
+ 2, /* Size (0 = byte, 1 = short, 2 = long). */
+ 16, /* Bitsize. */
+ TRUE, /* PC_relative. */
+ 0, /* Bitpos. */
+ complain_overflow_dont, /* Complain on overflow. */
+ bfd_elf_generic_reloc,/* Special Function. */
+ "R_MICROBLAZE_REL", /* Name. */
+ FALSE, /* Partial Inplace. */
+ 0, /* Source Mask. */
+ 0x0000ffff, /* Dest Mask. */
+ TRUE), /* PC relative offset? */
+
+ /* Table-entry not really used. */
+ HOWTO (R_MICROBLAZE_JUMP_SLOT,/* Type. */
+ 0, /* Rightshift. */
+ 2, /* Size (0 = byte, 1 = short, 2 = long). */
+ 16, /* Bitsize. */
+ TRUE, /* PC_relative. */
+ 0, /* Bitpos. */
+ complain_overflow_dont, /* Complain on overflow. */
+ bfd_elf_generic_reloc,/* Special Function. */
+ "R_MICROBLAZE_JUMP_SLOT", /* Name. */
+ FALSE, /* Partial Inplace. */
+ 0, /* Source Mask. */
+ 0x0000ffff, /* Dest Mask. */
+ TRUE), /* PC relative offset? */
+
+ /* Table-entry not really used. */
+ HOWTO (R_MICROBLAZE_GLOB_DAT,/* Type. */
+ 0, /* Rightshift. */
+ 2, /* Size (0 = byte, 1 = short, 2 = long). */
+ 16, /* Bitsize. */
+ TRUE, /* PC_relative. */
+ 0, /* Bitpos. */
+ complain_overflow_dont, /* Complain on overflow. */
+ bfd_elf_generic_reloc,/* Special Function. */
+ "R_MICROBLAZE_GLOB_DAT", /* Name. */
+ FALSE, /* Partial Inplace. */
+ 0, /* Source Mask. */
+ 0x0000ffff, /* Dest Mask. */
+ TRUE), /* PC relative offset? */
+
+ /* A 64 bit GOT relative relocation. Table-entry not really used. */
+ HOWTO (R_MICROBLAZE_GOTOFF_64, /* 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_MICROBLAZE_GOTOFF_64", /* Name. */
+ FALSE, /* Partial Inplace. */
+ 0, /* Source Mask. */
+ 0x0000ffff, /* Dest Mask. */
+ FALSE), /* PC relative offset? */
+
+ /* A 32 bit GOT relative relocation. Table-entry not really used. */
+ HOWTO (R_MICROBLAZE_GOTOFF_32, /* 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_MICROBLAZE_GOTOFF_32", /* Name. */
+ FALSE, /* Partial Inplace. */
+ 0, /* Source Mask. */
+ 0x0000ffff, /* Dest Mask. */
+ FALSE), /* PC relative offset? */
+
+ /* COPY relocation. Table-entry not really used. */
+ HOWTO (R_MICROBLAZE_COPY, /* 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_MICROBLAZE_COPY", /* Name. */
+ FALSE, /* Partial Inplace. */
+ 0, /* Source Mask. */
+ 0x0000ffff, /* Dest Mask. */
+ FALSE), /* PC relative offset? */
+
+ /* Marker relocs for TLS. */
+ HOWTO (R_MICROBLAZE_TLS,
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MICROBLAZE_TLS", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_MICROBLAZE_TLSGD,
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MICROBLAZE_TLSGD", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_MICROBLAZE_TLSLD,
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MICROBLAZE_TLSLD", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Computes the load module index of the load module that contains the
+ definition of its TLS sym. */
+ HOWTO (R_MICROBLAZE_TLSDTPMOD32,
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MICROBLAZE_TLSDTPMOD32", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Computes a dtv-relative displacement, the difference between the value
+ of sym+add and the base address of the thread-local storage block that
+ contains the definition of sym, minus 0x8000. Used for initializing GOT */
+ HOWTO (R_MICROBLAZE_TLSDTPREL32,
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MICROBLAZE_TLSDTPREL32", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Computes a dtv-relative displacement, the difference between the value
+ of sym+add and the base address of the thread-local storage block that
+ contains the definition of sym, minus 0x8000. */
+ HOWTO (R_MICROBLAZE_TLSDTPREL64,
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MICROBLAZE_TLSDTPREL64", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Computes a tp-relative displacement, the difference between the value of
+ sym+add and the value of the thread pointer (r13). */
+ HOWTO (R_MICROBLAZE_TLSGOTTPREL32,
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MICROBLAZE_TLSGOTTPREL32", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Computes a tp-relative displacement, the difference between the value of
+ sym+add and the value of the thread pointer (r13). */
+ HOWTO (R_MICROBLAZE_TLSTPREL32,
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MICROBLAZE_TLSTPREL32", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+};
+
+#ifndef NUM_ELEM
+#define NUM_ELEM(a) (sizeof (a) / sizeof (a)[0])
+#endif
+
+/* Initialize the microblaze_elf_howto_table, so that linear accesses can be done. */
+
+static void
+microblaze_elf_howto_init (void)
+{
+ unsigned int i;
+
+ for (i = NUM_ELEM (microblaze_elf_howto_raw); i--;)
+ {
+ unsigned int type;
+
+ type = microblaze_elf_howto_raw[i].type;
+
+ BFD_ASSERT (type < NUM_ELEM (microblaze_elf_howto_table));
+
+ microblaze_elf_howto_table [type] = & microblaze_elf_howto_raw [i];
+ }
+}
+
+static reloc_howto_type *
+microblaze_elf_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED,
+ bfd_reloc_code_real_type code)
+{
+ enum elf_microblaze_reloc_type microblaze_reloc = R_MICROBLAZE_NONE;
+
+ switch (code)
+ {
+ case BFD_RELOC_NONE:
+ microblaze_reloc = R_MICROBLAZE_NONE;
+ break;
+ case BFD_RELOC_MICROBLAZE_64_NONE:
+ microblaze_reloc = R_MICROBLAZE_64_NONE;
+ break;
+ case BFD_RELOC_32:
+ microblaze_reloc = R_MICROBLAZE_32;
+ break;
+ /* RVA is treated the same as 32 */
+ case BFD_RELOC_RVA:
+ microblaze_reloc = R_MICROBLAZE_32;
+ break;
+ case BFD_RELOC_32_PCREL:
+ microblaze_reloc = R_MICROBLAZE_32_PCREL;
+ break;
+ case BFD_RELOC_64_PCREL:
+ microblaze_reloc = R_MICROBLAZE_64_PCREL;
+ break;
+ case BFD_RELOC_MICROBLAZE_32_LO_PCREL:
+ microblaze_reloc = R_MICROBLAZE_32_PCREL_LO;
+ break;
+ case BFD_RELOC_64:
+ microblaze_reloc = R_MICROBLAZE_64;
+ break;
+ case BFD_RELOC_MICROBLAZE_32_LO:
+ microblaze_reloc = R_MICROBLAZE_32_LO;
+ break;
+ case BFD_RELOC_MICROBLAZE_32_ROSDA:
+ microblaze_reloc = R_MICROBLAZE_SRO32;
+ break;
+ case BFD_RELOC_MICROBLAZE_32_RWSDA:
+ microblaze_reloc = R_MICROBLAZE_SRW32;
+ break;
+ case BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM:
+ microblaze_reloc = R_MICROBLAZE_32_SYM_OP_SYM;
+ break;
+ case BFD_RELOC_VTABLE_INHERIT:
+ microblaze_reloc = R_MICROBLAZE_GNU_VTINHERIT;
+ break;
+ case BFD_RELOC_VTABLE_ENTRY:
+ microblaze_reloc = R_MICROBLAZE_GNU_VTENTRY;
+ break;
+ case BFD_RELOC_MICROBLAZE_64_GOTPC:
+ microblaze_reloc = R_MICROBLAZE_GOTPC_64;
+ break;
+ case BFD_RELOC_MICROBLAZE_64_GOT:
+ microblaze_reloc = R_MICROBLAZE_GOT_64;
+ break;
+ case BFD_RELOC_MICROBLAZE_64_PLT:
+ microblaze_reloc = R_MICROBLAZE_PLT_64;
+ break;
+ case BFD_RELOC_MICROBLAZE_64_GOTOFF:
+ microblaze_reloc = R_MICROBLAZE_GOTOFF_64;
+ break;
+ case BFD_RELOC_MICROBLAZE_32_GOTOFF:
+ microblaze_reloc = R_MICROBLAZE_GOTOFF_32;
+ break;
+ case BFD_RELOC_MICROBLAZE_64_TLSGD:
+ microblaze_reloc = R_MICROBLAZE_TLSGD;
+ break;
+ case BFD_RELOC_MICROBLAZE_64_TLSLD:
+ microblaze_reloc = R_MICROBLAZE_TLSLD;
+ break;
+ case BFD_RELOC_MICROBLAZE_32_TLSDTPREL:
+ microblaze_reloc = R_MICROBLAZE_TLSDTPREL32;
+ break;
+ case BFD_RELOC_MICROBLAZE_64_TLSDTPREL:
+ microblaze_reloc = R_MICROBLAZE_TLSDTPREL64;
+ break;
+ case BFD_RELOC_MICROBLAZE_32_TLSDTPMOD:
+ microblaze_reloc = R_MICROBLAZE_TLSDTPMOD32;
+ break;
+ case BFD_RELOC_MICROBLAZE_64_TLSGOTTPREL:
+ microblaze_reloc = R_MICROBLAZE_TLSGOTTPREL32;
+ break;
+ case BFD_RELOC_MICROBLAZE_64_TLSTPREL:
+ microblaze_reloc = R_MICROBLAZE_TLSTPREL32;
+ break;
+ case BFD_RELOC_MICROBLAZE_COPY:
+ microblaze_reloc = R_MICROBLAZE_COPY;
+ break;
+ default:
+ return (reloc_howto_type *) NULL;
+ }
+
+ if (!microblaze_elf_howto_table [R_MICROBLAZE_32])
+ /* Initialize howto table if needed. */
+ microblaze_elf_howto_init ();
+
+ return microblaze_elf_howto_table [(int) microblaze_reloc];
+};
+
+static reloc_howto_type *
+microblaze_elf_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ const char *r_name)
+{
+ unsigned int i;
+
+ for (i = 0; i < NUM_ELEM (microblaze_elf_howto_raw); i++)
+ if (microblaze_elf_howto_raw[i].name != NULL
+ && strcasecmp (microblaze_elf_howto_raw[i].name, r_name) == 0)
+ return &microblaze_elf_howto_raw[i];
+
+ return NULL;
+}
+
+/* Set the howto pointer for a RCE ELF reloc. */
+
+static void
+microblaze_elf_info_to_howto (bfd * abfd ATTRIBUTE_UNUSED,
+ arelent * cache_ptr,
+ Elf_Internal_Rela * dst)
+{
+ if (!microblaze_elf_howto_table [R_MICROBLAZE_32])
+ /* Initialize howto table if needed. */
+ microblaze_elf_howto_init ();
+
+ BFD_ASSERT (ELF32_R_TYPE (dst->r_info) < (unsigned int) R_MICROBLAZE_max);
+
+ cache_ptr->howto = microblaze_elf_howto_table [ELF32_R_TYPE (dst->r_info)];
+}
+
+/* Microblaze ELF local labels start with 'L.' or '$L', not '.L'. */
+
+static bfd_boolean
+microblaze_elf_is_local_label_name (bfd *abfd, const char *name)
+{
+ if (name[0] == 'L' && name[1] == '.')
+ return TRUE;
+
+ if (name[0] == '$' && name[1] == 'L')
+ return TRUE;
+
+ /* With gcc, 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);
+}
+
+/* The microblaze linker (like many others) needs to keep track of
+ the number of relocs that it decides to copy as dynamic relocs in
+ check_relocs for each symbol. This is so that it can later discard
+ them if they are found to be unnecessary. We store the information
+ in a field extending the regular ELF linker hash table. */
+
+struct elf32_mb_dyn_relocs
+{
+ struct elf32_mb_dyn_relocs *next;
+
+ /* The input section of the reloc. */
+ asection *sec;
+
+ /* Total number of relocs copied for the input section. */
+ bfd_size_type count;
+
+ /* Number of pc-relative relocs copied for the input section. */
+ bfd_size_type pc_count;
+};
+
+/* ELF linker hash entry. */
+
+struct elf32_mb_link_hash_entry
+{
+ struct elf_link_hash_entry elf;
+
+ /* Track dynamic relocs copied for this symbol. */
+ struct elf32_mb_dyn_relocs *dyn_relocs;
+
+ /* TLS Reference Types for the symbol; Updated by check_relocs */
+#define TLS_GD 1 /* GD reloc. */
+#define TLS_LD 2 /* LD reloc. */
+#define TLS_TPREL 4 /* TPREL reloc, => IE. */
+#define TLS_DTPREL 8 /* DTPREL reloc, => LD. */
+#define TLS_TLS 16 /* Any TLS reloc. */
+ unsigned char tls_mask;
+
+};
+
+#define IS_TLS_GD(x) (x == (TLS_TLS | TLS_GD))
+#define IS_TLS_LD(x) (x == (TLS_TLS | TLS_LD))
+#define IS_TLS_DTPREL(x) (x == (TLS_TLS | TLS_DTPREL))
+#define IS_TLS_NONE(x) (x == 0)
+
+#define elf32_mb_hash_entry(ent) ((struct elf32_mb_link_hash_entry *)(ent))
+
+/* ELF linker hash table. */
+
+struct elf32_mb_link_hash_table
+{
+ struct elf_link_hash_table elf;
+
+ /* Short-cuts to get to dynamic linker sections. */
+ asection *sgot;
+ asection *sgotplt;
+ asection *srelgot;
+ asection *splt;
+ asection *srelplt;
+ asection *sdynbss;
+ asection *srelbss;
+
+ /* Small local sym to section mapping cache. */
+ struct sym_cache sym_sec;
+
+ /* TLS Local Dynamic GOT Entry */
+ union {
+ bfd_signed_vma refcount;
+ bfd_vma offset;
+ } tlsld_got;
+};
+
+/* Nonzero if this section has TLS related relocations. */
+#define has_tls_reloc sec_flg0
+
+/* Get the ELF linker hash table from a link_info structure. */
+
+#define elf32_mb_hash_table(p) \
+ (elf_hash_table_id ((struct elf_link_hash_table *) ((p)->hash)) \
+ == MICROBLAZE_ELF_DATA ? ((struct elf32_mb_link_hash_table *) ((p)->hash)) : NULL)
+
+/* Create an entry in a microblaze ELF linker hash table. */
+
+static struct bfd_hash_entry *
+link_hash_newfunc (struct bfd_hash_entry *entry,
+ struct bfd_hash_table *table,
+ const char *string)
+{
+ /* Allocate the structure if it has not already been allocated by a
+ subclass. */
+ if (entry == NULL)
+ {
+ entry = bfd_hash_allocate (table,
+ sizeof (struct elf32_mb_link_hash_entry));
+ if (entry == NULL)
+ return entry;
+ }
+
+ /* Call the allocation method of the superclass. */
+ entry = _bfd_elf_link_hash_newfunc (entry, table, string);
+ if (entry != NULL)
+ {
+ struct elf32_mb_link_hash_entry *eh;
+
+ eh = (struct elf32_mb_link_hash_entry *) entry;
+ eh->dyn_relocs = NULL;
+ eh->tls_mask = 0;
+ }
+
+ return entry;
+}
+
+/* Create a mb ELF linker hash table. */
+
+static struct bfd_link_hash_table *
+microblaze_elf_link_hash_table_create (bfd *abfd)
+{
+ struct elf32_mb_link_hash_table *ret;
+ bfd_size_type amt = sizeof (struct elf32_mb_link_hash_table);
+
+ ret = (struct elf32_mb_link_hash_table *) bfd_zmalloc (amt);
+ if (ret == NULL)
+ return NULL;
+
+ if (!_bfd_elf_link_hash_table_init (&ret->elf, abfd, link_hash_newfunc,
+ sizeof (struct elf32_mb_link_hash_entry),
+ MICROBLAZE_ELF_DATA))
+ {
+ free (ret);
+ return NULL;
+ }
+
+ return &ret->elf.root;
+}
+
+/* Set the values of the small data pointers. */
+
+static void
+microblaze_elf_final_sdp (struct bfd_link_info *info)
+{
+ struct bfd_link_hash_entry *h;
+
+ h = bfd_link_hash_lookup (info->hash, RO_SDA_ANCHOR_NAME, FALSE, FALSE, TRUE);
+ if (h != (struct bfd_link_hash_entry *) NULL
+ && h->type == bfd_link_hash_defined)
+ ro_small_data_pointer = (h->u.def.value
+ + h->u.def.section->output_section->vma
+ + h->u.def.section->output_offset);
+
+ h = bfd_link_hash_lookup (info->hash, RW_SDA_ANCHOR_NAME, FALSE, FALSE, TRUE);
+ if (h != (struct bfd_link_hash_entry *) NULL
+ && h->type == bfd_link_hash_defined)
+ rw_small_data_pointer = (h->u.def.value
+ + h->u.def.section->output_section->vma
+ + h->u.def.section->output_offset);
+}
+
+static bfd_vma
+dtprel_base (struct bfd_link_info *info)
+{
+ /* If tls_sec is NULL, we should have signalled an error already. */
+ if (elf_hash_table (info)->tls_sec == NULL)
+ return 0;
+ return elf_hash_table (info)->tls_sec->vma;
+}
+
+/* The size of the thread control block. */
+#define TCB_SIZE 8
+
+/* Output a simple dynamic relocation into SRELOC. */
+
+static void
+microblaze_elf_output_dynamic_relocation (bfd *output_bfd,
+ asection *sreloc,
+ unsigned long reloc_index,
+ unsigned long indx,
+ int r_type,
+ bfd_vma offset,
+ bfd_vma addend)
+{
+
+ Elf_Internal_Rela rel;
+
+ rel.r_info = ELF32_R_INFO (indx, r_type);
+ rel.r_offset = offset;
+ rel.r_addend = addend;
+
+ bfd_elf32_swap_reloca_out (output_bfd, &rel,
+ (sreloc->contents + reloc_index * sizeof (Elf32_External_Rela)));
+}
+
+/* This code is taken from elf32-m32r.c
+ 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
+ relocatable 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 relocatable 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 bfd_boolean
+microblaze_elf_relocate_section (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)
+{
+ struct elf32_mb_link_hash_table *htab;
+ 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;
+ int endian = (bfd_little_endian (output_bfd)) ? 0 : 2;
+ /* Assume success. */
+ bfd_boolean ret = TRUE;
+ asection *sreloc;
+ bfd_vma *local_got_offsets;
+ unsigned int tls_type;
+
+ if (!microblaze_elf_howto_table[R_MICROBLAZE_max-1])
+ microblaze_elf_howto_init ();
+
+ htab = elf32_mb_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ local_got_offsets = elf_local_got_offsets (input_bfd);
+
+ sreloc = elf_section_data (input_section)->sreloc;
+
+ 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 = 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 = bfd_reloc_ok;
+ const char *errmsg = NULL;
+ bfd_boolean unresolved_reloc = FALSE;
+
+ h = NULL;
+ r_type = ELF32_R_TYPE (rel->r_info);
+ tls_type = 0;
+
+ if (r_type < 0 || r_type >= (int) R_MICROBLAZE_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;
+ }
+
+ howto = microblaze_elf_howto_table[r_type];
+ r_symndx = ELF32_R_SYM (rel->r_info);
+
+ if (info->relocatable)
+ {
+ /* This is a relocatable 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. */
+ 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;
+ unresolved_reloc = FALSE;
+
+ if (r_symndx < symtab_hdr->sh_info)
+ {
+ /* Local symbol. */
+ sym = local_syms + r_symndx;
+ sec = local_sections[r_symndx];
+ if (sec == 0)
+ continue;
+ sym_name = "<local symbol>";
+ relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
+ /* r_addend may have changed if the reference section was
+ a merge section. */
+ addend = rel->r_addend;
+ }
+ else
+ {
+ /* External symbol. */
+ bfd_boolean warned ATTRIBUTE_UNUSED;
+ bfd_boolean ignored ATTRIBUTE_UNUSED;
+
+ RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
+ r_symndx, symtab_hdr, sym_hashes,
+ h, sec, relocation,
+ unresolved_reloc, warned, ignored);
+ sym_name = h->root.root.string;
+ }
+
+ /* Sanity check the address. */
+ if (offset > bfd_get_section_limit (input_bfd, input_section))
+ {
+ r = bfd_reloc_outofrange;
+ goto check_reloc;
+ }
+
+ switch ((int) r_type)
+ {
+ case (int) R_MICROBLAZE_SRO32 :
+ {
+ const char *name;
+
+ /* Only relocate if the symbol is defined. */
+ if (sec)
+ {
+ name = bfd_get_section_name (sec->owner, sec);
+
+ if (strcmp (name, ".sdata2") == 0
+ || strcmp (name, ".sbss2") == 0)
+ {
+ if (ro_small_data_pointer == 0)
+ microblaze_elf_final_sdp (info);
+ if (ro_small_data_pointer == 0)
+ {
+ ret = FALSE;
+ r = bfd_reloc_undefined;
+ goto check_reloc;
+ }
+
+ /* At this point `relocation' contains the object's
+ address. */
+ relocation -= ro_small_data_pointer;
+ /* Now it contains the offset from _SDA2_BASE_. */
+ r = _bfd_final_link_relocate (howto, input_bfd,
+ input_section,
+ contents, offset,
+ relocation, addend);
+ }
+ 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,
+ microblaze_elf_howto_table[(int) r_type]->name,
+ bfd_get_section_name (sec->owner, sec));
+ /*bfd_set_error (bfd_error_bad_value); ??? why? */
+ ret = FALSE;
+ continue;
+ }
+ }
+ }
+ break;
+
+ case (int) R_MICROBLAZE_SRW32 :
+ {
+ const char *name;
+
+ /* Only relocate if the symbol is defined. */
+ if (sec)
+ {
+ name = bfd_get_section_name (sec->owner, sec);
+
+ if (strcmp (name, ".sdata") == 0
+ || strcmp (name, ".sbss") == 0)
+ {
+ if (rw_small_data_pointer == 0)
+ microblaze_elf_final_sdp (info);
+ if (rw_small_data_pointer == 0)
+ {
+ ret = FALSE;
+ r = bfd_reloc_undefined;
+ goto check_reloc;
+ }
+
+ /* At this point `relocation' contains the object's
+ address. */
+ relocation -= rw_small_data_pointer;
+ /* Now it contains the offset from _SDA_BASE_. */
+ r = _bfd_final_link_relocate (howto, input_bfd,
+ input_section,
+ contents, offset,
+ relocation, addend);
+ }
+ 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,
+ microblaze_elf_howto_table[(int) r_type]->name,
+ bfd_get_section_name (sec->owner, sec));
+ /*bfd_set_error (bfd_error_bad_value); ??? why? */
+ ret = FALSE;
+ continue;
+ }
+ }
+ }
+ break;
+
+ case (int) R_MICROBLAZE_32_SYM_OP_SYM:
+ break; /* Do nothing. */
+
+ case (int) R_MICROBLAZE_GOTPC_64:
+ relocation = htab->sgotplt->output_section->vma
+ + htab->sgotplt->output_offset;
+ relocation -= (input_section->output_section->vma
+ + input_section->output_offset
+ + offset + INST_WORD_SIZE);
+ relocation += addend;
+ bfd_put_16 (input_bfd, (relocation >> 16) & 0xffff,
+ contents + offset + endian);
+ bfd_put_16 (input_bfd, relocation & 0xffff,
+ contents + offset + endian + INST_WORD_SIZE);
+ break;
+
+ case (int) R_MICROBLAZE_PLT_64:
+ {
+ bfd_vma immediate;
+ if (htab->splt != NULL && h != NULL
+ && h->plt.offset != (bfd_vma) -1)
+ {
+ relocation = (htab->splt->output_section->vma
+ + htab->splt->output_offset
+ + h->plt.offset);
+ unresolved_reloc = FALSE;
+ immediate = relocation - (input_section->output_section->vma
+ + input_section->output_offset
+ + offset + INST_WORD_SIZE);
+ bfd_put_16 (input_bfd, (immediate >> 16) & 0xffff,
+ contents + offset + endian);
+ bfd_put_16 (input_bfd, immediate & 0xffff,
+ contents + offset + endian + INST_WORD_SIZE);
+ }
+ else
+ {
+ relocation -= (input_section->output_section->vma
+ + input_section->output_offset
+ + offset + INST_WORD_SIZE);
+ immediate = relocation;
+ bfd_put_16 (input_bfd, (immediate >> 16) & 0xffff,
+ contents + offset + endian);
+ bfd_put_16 (input_bfd, immediate & 0xffff,
+ contents + offset + endian + INST_WORD_SIZE);
+ }
+ break;
+ }
+
+ case (int) R_MICROBLAZE_TLSGD:
+ tls_type = (TLS_TLS | TLS_GD);
+ goto dogot;
+ case (int) R_MICROBLAZE_TLSLD:
+ tls_type = (TLS_TLS | TLS_LD);
+ dogot:
+ case (int) R_MICROBLAZE_GOT_64:
+ {
+ bfd_vma *offp;
+ bfd_vma off, off2;
+ unsigned long indx;
+ bfd_vma static_value;
+
+ bfd_boolean need_relocs = FALSE;
+ if (htab->sgot == NULL)
+ abort ();
+
+ indx = 0;
+ offp = NULL;
+
+ /* 1. Identify GOT Offset;
+ 2. Compute Static Values
+ 3. Process Module Id, Process Offset
+ 4. Fixup Relocation with GOT offset value. */
+
+ /* 1. Determine GOT Offset to use : TLS_LD, global, local */
+ if (IS_TLS_LD (tls_type))
+ offp = &htab->tlsld_got.offset;
+ else if (h != NULL)
+ {
+ if (htab->sgotplt != NULL && h->got.offset != (bfd_vma) -1)
+ offp = &h->got.offset;
+ else
+ abort ();
+ }
+ else
+ {
+ if (local_got_offsets == NULL)
+ abort ();
+ offp = &local_got_offsets[r_symndx];
+ }
+
+ if (!offp)
+ abort ();
+
+ off = (*offp) & ~1;
+ off2 = off;
+
+ if (IS_TLS_LD(tls_type) || IS_TLS_GD(tls_type))
+ off2 = off + 4;
+
+ /* Symbol index to use for relocs */
+ if (h != NULL)
+ {
+ bfd_boolean dyn =
+ elf_hash_table (info)->dynamic_sections_created;
+
+ if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h)
+ && (!info->shared || !SYMBOL_REFERENCES_LOCAL (info, h)))
+ indx = h->dynindx;
+ }
+
+ /* Need to generate relocs ? */
+ if ((info->shared || indx != 0)
+ && (h == NULL
+ || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
+ || h->root.type != bfd_link_hash_undefweak))
+ need_relocs = TRUE;
+
+ /* 2. Compute/Emit Static value of r-expression */
+ static_value = relocation + addend;
+
+ /* 3. Process module-id and offset */
+ if (! ((*offp) & 1) )
+ {
+ bfd_vma got_offset;
+
+ got_offset = (htab->sgot->output_section->vma
+ + htab->sgot->output_offset
+ + off);
+
+ /* Process module-id */
+ if (IS_TLS_LD(tls_type))
+ {
+ if (! info->shared)
+ {
+ bfd_put_32 (output_bfd, 1, htab->sgot->contents + off);
+ }
+ else
+ {
+ microblaze_elf_output_dynamic_relocation (output_bfd,
+ htab->srelgot, htab->srelgot->reloc_count++,
+ /* symindex= */ 0, R_MICROBLAZE_TLSDTPMOD32,
+ got_offset, 0);
+ }
+ }
+ else if (IS_TLS_GD(tls_type))
+ {
+ if (! need_relocs)
+ {
+ bfd_put_32 (output_bfd, 1, htab->sgot->contents + off);
+ }
+ else
+ {
+ microblaze_elf_output_dynamic_relocation (output_bfd,
+ htab->srelgot,
+ htab->srelgot->reloc_count++,
+ /* symindex= */ indx, R_MICROBLAZE_TLSDTPMOD32,
+ got_offset, indx ? 0 : static_value);
+ }
+ }
+
+ /* Process Offset */
+ if (htab->srelgot == NULL)
+ abort ();
+
+ got_offset = (htab->sgot->output_section->vma
+ + htab->sgot->output_offset
+ + off2);
+ if (IS_TLS_LD(tls_type))
+ {
+ /* For LD, offset should be 0 */
+ *offp |= 1;
+ bfd_put_32 (output_bfd, 0, htab->sgot->contents + off2);
+ }
+ else if (IS_TLS_GD(tls_type))
+ {
+ *offp |= 1;
+ static_value -= dtprel_base(info);
+ if (need_relocs)
+ {
+ microblaze_elf_output_dynamic_relocation (output_bfd,
+ htab->srelgot, htab->srelgot->reloc_count++,
+ /* symindex= */ indx, R_MICROBLAZE_TLSDTPREL32,
+ got_offset, indx ? 0 : static_value);
+ }
+ else
+ {
+ bfd_put_32 (output_bfd, static_value,
+ htab->sgot->contents + off2);
+ }
+ }
+ else
+ {
+ bfd_put_32 (output_bfd, static_value,
+ htab->sgot->contents + off2);
+
+ /* Relocs for dyn symbols generated by
+ finish_dynamic_symbols */
+ if (info->shared && h == NULL)
+ {
+ *offp |= 1;
+ microblaze_elf_output_dynamic_relocation (output_bfd,
+ htab->srelgot, htab->srelgot->reloc_count++,
+ /* symindex= */ indx, R_MICROBLAZE_REL,
+ got_offset, static_value);
+ }
+ }
+ }
+
+ /* 4. Fixup Relocation with GOT offset value
+ Compute relative address of GOT entry for applying
+ the current relocation */
+ relocation = htab->sgot->output_section->vma
+ + htab->sgot->output_offset
+ + off
+ - htab->sgotplt->output_section->vma
+ - htab->sgotplt->output_offset;
+
+ /* Apply Current Relocation */
+ bfd_put_16 (input_bfd, (relocation >> 16) & 0xffff,
+ contents + offset + endian);
+ bfd_put_16 (input_bfd, relocation & 0xffff,
+ contents + offset + endian + INST_WORD_SIZE);
+
+ unresolved_reloc = FALSE;
+ break;
+ }
+
+ case (int) R_MICROBLAZE_GOTOFF_64:
+ {
+ bfd_vma immediate;
+ unsigned short lo, high;
+ relocation += addend;
+ relocation -= htab->sgotplt->output_section->vma
+ + htab->sgotplt->output_offset;
+ /* Write this value into correct location. */
+ immediate = relocation;
+ lo = immediate & 0x0000ffff;
+ high = (immediate >> 16) & 0x0000ffff;
+ bfd_put_16 (input_bfd, high, contents + offset + endian);
+ bfd_put_16 (input_bfd, lo, contents + offset + INST_WORD_SIZE + endian);
+ break;
+ }
+
+ case (int) R_MICROBLAZE_GOTOFF_32:
+ {
+ relocation += addend;
+ relocation -= htab->sgotplt->output_section->vma
+ + htab->sgotplt->output_offset;
+ /* Write this value into correct location. */
+ bfd_put_32 (input_bfd, relocation, contents + offset);
+ break;
+ }
+
+ case (int) R_MICROBLAZE_TLSDTPREL64:
+ relocation += addend;
+ relocation -= dtprel_base(info);
+ bfd_put_16 (input_bfd, (relocation >> 16) & 0xffff,
+ contents + offset + 2);
+ bfd_put_16 (input_bfd, relocation & 0xffff,
+ contents + offset + 2 + INST_WORD_SIZE);
+ break;
+ case (int) R_MICROBLAZE_64_PCREL :
+ case (int) R_MICROBLAZE_64:
+ case (int) R_MICROBLAZE_32:
+ {
+ /* r_symndx will be STN_UNDEF (zero) only for relocs against symbols
+ from removed linkonce sections, or sections discarded by
+ a linker script. */
+ if (r_symndx == STN_UNDEF || (input_section->flags & SEC_ALLOC) == 0)
+ {
+ relocation += addend;
+ if (r_type == R_MICROBLAZE_32)
+ bfd_put_32 (input_bfd, relocation, contents + offset);
+ else
+ {
+ if (r_type == R_MICROBLAZE_64_PCREL)
+ relocation -= (input_section->output_section->vma
+ + input_section->output_offset
+ + offset + INST_WORD_SIZE);
+ bfd_put_16 (input_bfd, (relocation >> 16) & 0xffff,
+ contents + offset + endian);
+ bfd_put_16 (input_bfd, relocation & 0xffff,
+ contents + offset + endian + INST_WORD_SIZE);
+ }
+ break;
+ }
+
+ if ((info->shared
+ && (h == NULL
+ || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
+ || h->root.type != bfd_link_hash_undefweak)
+ && (!howto->pc_relative
+ || (h != NULL
+ && h->dynindx != -1
+ && (!info->symbolic
+ || !h->def_regular))))
+ || (!info->shared
+ && h != NULL
+ && h->dynindx != -1
+ && !h->non_got_ref
+ && ((h->def_dynamic
+ && !h->def_regular)
+ || h->root.type == bfd_link_hash_undefweak
+ || h->root.type == bfd_link_hash_undefined)))
+ {
+ Elf_Internal_Rela outrel;
+ bfd_byte *loc;
+ bfd_boolean skip;
+
+ /* When generating a shared object, these relocations
+ are copied into the output file to be resolved at run
+ time. */
+
+ BFD_ASSERT (sreloc != NULL);
+
+ skip = FALSE;
+
+ outrel.r_offset =
+ _bfd_elf_section_offset (output_bfd, info, input_section,
+ rel->r_offset);
+ if (outrel.r_offset == (bfd_vma) -1)
+ skip = TRUE;
+ else if (outrel.r_offset == (bfd_vma) -2)
+ skip = TRUE;
+ 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->def_regular))
+ {
+ BFD_ASSERT (h->dynindx != -1);
+ outrel.r_info = ELF32_R_INFO (h->dynindx, r_type);
+ outrel.r_addend = addend;
+ }
+ else
+ {
+ if (r_type == R_MICROBLAZE_32)
+ {
+ outrel.r_info = ELF32_R_INFO (0, R_MICROBLAZE_REL);
+ outrel.r_addend = relocation + addend;
+ }
+ else
+ {
+ BFD_FAIL ();
+ (*_bfd_error_handler)
+ (_("%B: probably compiled without -fPIC?"),
+ input_bfd);
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+ }
+
+ loc = sreloc->contents;
+ loc += sreloc->reloc_count++ * sizeof (Elf32_External_Rela);
+ bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
+ break;
+ }
+ else
+ {
+ relocation += addend;
+ if (r_type == R_MICROBLAZE_32)
+ bfd_put_32 (input_bfd, relocation, contents + offset);
+ else
+ {
+ if (r_type == R_MICROBLAZE_64_PCREL)
+ relocation -= (input_section->output_section->vma
+ + input_section->output_offset
+ + offset + INST_WORD_SIZE);
+ bfd_put_16 (input_bfd, (relocation >> 16) & 0xffff,
+ contents + offset + endian);
+ bfd_put_16 (input_bfd, relocation & 0xffff,
+ contents + offset + endian + INST_WORD_SIZE);
+ }
+ break;
+ }
+ }
+
+ 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, (h ? &h->root : NULL), 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, TRUE)))
+ 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;
+}
+
+/* Merge backend specific data from an object file to the output
+ object file when linking.
+
+ Note: We only use this hook to catch endian mismatches. */
+static bfd_boolean
+microblaze_elf_merge_private_bfd_data (bfd * ibfd, bfd * obfd)
+{
+ /* Check if we have the same endianess. */
+ if (! _bfd_generic_verify_endian_match (ibfd, obfd))
+ return FALSE;
+
+ return TRUE;
+}
+
+
+/* Calculate fixup value for reference. */
+
+static int
+calc_fixup (bfd_vma start, bfd_vma size, asection *sec)
+{
+ bfd_vma end = start + size;
+ int i, fixup = 0;
+
+ if (sec == NULL || sec->relax == NULL)
+ return 0;
+
+ /* Look for addr in relax table, total fixup value. */
+ for (i = 0; i < sec->relax_count; i++)
+ {
+ if (end <= sec->relax[i].addr)
+ break;
+ if ((end != start) && (start > sec->relax[i].addr))
+ continue;
+ fixup += sec->relax[i].size;
+ }
+ return fixup;
+}
+
+/* Read-modify-write into the bfd, an immediate value into appropriate fields of
+ a 32-bit instruction. */
+static void
+microblaze_bfd_write_imm_value_32 (bfd *abfd, bfd_byte *bfd_addr, bfd_vma val)
+{
+ unsigned long instr = bfd_get_32 (abfd, bfd_addr);
+ instr &= ~0x0000ffff;
+ instr |= (val & 0x0000ffff);
+ bfd_put_32 (abfd, instr, bfd_addr);
+}
+
+/* Read-modify-write into the bfd, an immediate value into appropriate fields of
+ two consecutive 32-bit instructions. */
+static void
+microblaze_bfd_write_imm_value_64 (bfd *abfd, bfd_byte *bfd_addr, bfd_vma val)
+{
+ unsigned long instr_hi;
+ unsigned long instr_lo;
+
+ instr_hi = bfd_get_32 (abfd, bfd_addr);
+ instr_hi &= ~0x0000ffff;
+ instr_hi |= ((val >> 16) & 0x0000ffff);
+ bfd_put_32 (abfd, instr_hi, bfd_addr);
+
+ instr_lo = bfd_get_32 (abfd, bfd_addr + INST_WORD_SIZE);
+ instr_lo &= ~0x0000ffff;
+ instr_lo |= (val & 0x0000ffff);
+ bfd_put_32 (abfd, instr_lo, bfd_addr + INST_WORD_SIZE);
+}
+
+static bfd_boolean
+microblaze_elf_relax_section (bfd *abfd,
+ asection *sec,
+ struct bfd_link_info *link_info,
+ bfd_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;
+ int rel_count;
+ unsigned int shndx;
+ int i, sym_index;
+ asection *o;
+ struct elf_link_hash_entry *sym_hash;
+ Elf_Internal_Sym *isymbuf, *isymend;
+ Elf_Internal_Sym *isym;
+ int symcount;
+ int offset;
+ bfd_vma src, dest;
+
+ /* We only do this once per section. We may be able to delete some code
+ by running multiple passes, but it is not worth it. */
+ *again = FALSE;
+
+ /* Only do this for a text section. */
+ if (link_info->relocatable
+ || (sec->flags & SEC_RELOC) == 0
+ || (sec->reloc_count == 0)
+ || (sec->flags & SEC_CODE) == 0)
+ return TRUE;
+
+ BFD_ASSERT ((sec->size > 0) || (sec->rawsize > 0));
+
+ /* If this is the first time we have been called for this section,
+ initialize the cooked size. */
+ if (sec->size == 0)
+ sec->size = sec->rawsize;
+
+ /* Get symbols for this section. */
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+ isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
+ symcount = symtab_hdr->sh_size / sizeof (Elf32_External_Sym);
+ if (isymbuf == NULL)
+ isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr, symcount,
+ 0, NULL, NULL, NULL);
+ BFD_ASSERT (isymbuf != NULL);
+
+ internal_relocs = _bfd_elf_link_read_relocs (abfd, sec, NULL, NULL, link_info->keep_memory);
+ if (internal_relocs == NULL)
+ goto error_return;
+ if (! link_info->keep_memory)
+ free_relocs = internal_relocs;
+
+ sec->relax = (struct relax_table *) bfd_malloc ((sec->reloc_count + 1)
+ * sizeof (struct relax_table));
+ if (sec->relax == NULL)
+ goto error_return;
+ sec->relax_count = 0;
+
+ irelend = internal_relocs + sec->reloc_count;
+ rel_count = 0;
+ for (irel = internal_relocs; irel < irelend; irel++, rel_count++)
+ {
+ bfd_vma symval;
+ if ((ELF32_R_TYPE (irel->r_info) != (int) R_MICROBLAZE_64_PCREL)
+ && (ELF32_R_TYPE (irel->r_info) != (int) R_MICROBLAZE_64 ))
+ continue; /* Can't delete this reloc. */
+
+ /* 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->size);
+ if (contents == NULL)
+ goto error_return;
+ free_contents = contents;
+
+ if (!bfd_get_section_contents (abfd, sec, contents,
+ (file_ptr) 0, sec->size))
+ goto error_return;
+ elf_section_data (sec)->this_hdr.contents = contents;
+ }
+ }
+
+ /* Get the value of the symbol referred to by the reloc. */
+ if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
+ {
+ /* A local symbol. */
+ asection *sym_sec;
+
+ isym = isymbuf + ELF32_R_SYM (irel->r_info);
+ if (isym->st_shndx == SHN_UNDEF)
+ sym_sec = bfd_und_section_ptr;
+ 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;
+ else
+ sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
+
+ symval = _bfd_elf_rela_local_sym (abfd, isym, &sym_sec, irel);
+ }
+ else
+ {
+ unsigned long indx;
+ struct elf_link_hash_entry *h;
+
+ 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);
+ }
+
+ /* If this is a PC-relative reloc, subtract the instr offset from
+ the symbol value. */
+ if (ELF32_R_TYPE (irel->r_info) == (int) R_MICROBLAZE_64_PCREL)
+ {
+ symval = symval + irel->r_addend
+ - (irel->r_offset
+ + sec->output_section->vma
+ + sec->output_offset);
+ }
+ else
+ symval += irel->r_addend;
+
+ if ((symval & 0xffff8000) == 0
+ || (symval & 0xffff8000) == 0xffff8000)
+ {
+ /* We can delete this instruction. */
+ sec->relax[sec->relax_count].addr = irel->r_offset;
+ sec->relax[sec->relax_count].size = INST_WORD_SIZE;
+ sec->relax_count++;
+
+ /* Rewrite relocation type. */
+ switch ((enum elf_microblaze_reloc_type) ELF32_R_TYPE (irel->r_info))
+ {
+ case R_MICROBLAZE_64_PCREL:
+ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
+ (int) R_MICROBLAZE_32_PCREL_LO);
+ break;
+ case R_MICROBLAZE_64:
+ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
+ (int) R_MICROBLAZE_32_LO);
+ break;
+ default:
+ /* Cannot happen. */
+ BFD_ASSERT (FALSE);
+ }
+ }
+ } /* Loop through all relocations. */
+
+ /* Loop through the relocs again, and see if anything needs to change. */
+ if (sec->relax_count > 0)
+ {
+ shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
+ rel_count = 0;
+ sec->relax[sec->relax_count].addr = sec->size;
+
+ for (irel = internal_relocs; irel < irelend; irel++, rel_count++)
+ {
+ bfd_vma nraddr;
+
+ /* Get the new reloc address. */
+ nraddr = irel->r_offset - calc_fixup (irel->r_offset, 0, sec);
+ switch ((enum elf_microblaze_reloc_type) ELF32_R_TYPE (irel->r_info))
+ {
+ default:
+ break;
+ case R_MICROBLAZE_64_PCREL:
+ break;
+ case R_MICROBLAZE_64:
+ case R_MICROBLAZE_32_LO:
+ /* If this reloc is against a symbol defined in this
+ section, 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)
+ {
+ isym = isymbuf + ELF32_R_SYM (irel->r_info);
+ /* Only handle relocs against .text. */
+ if (isym->st_shndx == shndx
+ && ELF32_ST_TYPE (isym->st_info) == STT_SECTION)
+ irel->r_addend -= calc_fixup (irel->r_addend, 0, sec);
+ }
+ break;
+ case R_MICROBLAZE_NONE:
+ {
+ /* This was a PC-relative instruction that was
+ completely resolved. */
+ int sfix, efix;
+ bfd_vma target_address;
+ target_address = irel->r_addend + irel->r_offset;
+ sfix = calc_fixup (irel->r_offset, 0, sec);
+ efix = calc_fixup (target_address, 0, sec);
+ irel->r_addend -= (efix - sfix);
+ /* Should use HOWTO. */
+ microblaze_bfd_write_imm_value_32 (abfd, contents + irel->r_offset,
+ irel->r_addend);
+ }
+ break;
+ case R_MICROBLAZE_64_NONE:
+ {
+ /* This was a PC-relative 64-bit instruction that was
+ completely resolved. */
+ int sfix, efix;
+ bfd_vma target_address;
+ target_address = irel->r_addend + irel->r_offset + INST_WORD_SIZE;
+ sfix = calc_fixup (irel->r_offset + INST_WORD_SIZE, 0, sec);
+ efix = calc_fixup (target_address, 0, sec);
+ irel->r_addend -= (efix - sfix);
+ microblaze_bfd_write_imm_value_32 (abfd, contents + irel->r_offset
+ + INST_WORD_SIZE, irel->r_addend);
+ }
+ break;
+ }
+ irel->r_offset = nraddr;
+ } /* Change all relocs in this section. */
+
+ /* Look through all other sections. */
+ for (o = abfd->sections; o != NULL; o = o->next)
+ {
+ Elf_Internal_Rela *irelocs;
+ 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. */
+
+ irelocs = _bfd_elf_link_read_relocs (abfd, o, NULL, NULL, TRUE);
+ if (irelocs == NULL)
+ goto error_return;
+
+ ocontents = NULL;
+ irelscanend = irelocs + o->reloc_count;
+ for (irelscan = irelocs; irelscan < irelscanend; irelscan++)
+ {
+ if (ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_32)
+ {
+ isym = isymbuf + ELF32_R_SYM (irelscan->r_info);
+
+ /* Look at the reloc only if the value has been resolved. */
+ if (isym->st_shndx == shndx
+ && (ELF32_ST_TYPE (isym->st_info) == STT_SECTION))
+ {
+ 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. */
+ if (o->rawsize == 0)
+ o->rawsize = o->size;
+ ocontents = (bfd_byte *) bfd_malloc (o->rawsize);
+ if (ocontents == NULL)
+ goto error_return;
+ if (!bfd_get_section_contents (abfd, o, ocontents,
+ (file_ptr) 0,
+ o->rawsize))
+ goto error_return;
+ elf_section_data (o)->this_hdr.contents = ocontents;
+ }
+
+ }
+ irelscan->r_addend -= calc_fixup (irelscan->r_addend, 0, sec);
+ }
+ else if (ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_32_SYM_OP_SYM)
+ {
+ isym = isymbuf + ELF32_R_SYM (irelscan->r_info);
+
+ /* Look at the reloc only if the value has been resolved. */
+ 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. */
+
+ if (o->rawsize == 0)
+ o->rawsize = o->size;
+ ocontents = (bfd_byte *) bfd_malloc (o->rawsize);
+ if (ocontents == NULL)
+ goto error_return;
+ if (!bfd_get_section_contents (abfd, o, ocontents,
+ (file_ptr) 0,
+ o->rawsize))
+ goto error_return;
+ elf_section_data (o)->this_hdr.contents = ocontents;
+ }
+ }
+ irelscan->r_addend -= calc_fixup (irel->r_addend
+ + isym->st_value,
+ 0,
+ sec);
+ }
+ }
+ else if ((ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_32_PCREL_LO)
+ || (ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_32_LO))
+ {
+ isym = isymbuf + ELF32_R_SYM (irelscan->r_info);
+
+ /* Look at the reloc only if the value has been resolved. */
+ if (isym->st_shndx == shndx
+ && (ELF32_ST_TYPE (isym->st_info) == STT_SECTION))
+ {
+ bfd_vma immediate;
+ bfd_vma target_address;
+
+ 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. */
+ if (o->rawsize == 0)
+ o->rawsize = o->size;
+ ocontents = (bfd_byte *) bfd_malloc (o->rawsize);
+ if (ocontents == NULL)
+ goto error_return;
+ if (!bfd_get_section_contents (abfd, o, ocontents,
+ (file_ptr) 0,
+ o->rawsize))
+ goto error_return;
+ elf_section_data (o)->this_hdr.contents = ocontents;
+ }
+ }
+
+ unsigned long instr = bfd_get_32 (abfd, ocontents + irelscan->r_offset);
+ immediate = instr & 0x0000ffff;
+ target_address = immediate;
+ offset = calc_fixup (target_address, 0, sec);
+ immediate -= offset;
+ irelscan->r_addend -= offset;
+ microblaze_bfd_write_imm_value_32 (abfd, ocontents + irelscan->r_offset,
+ irelscan->r_addend);
+ }
+ }
+
+ if (ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_64)
+ {
+ isym = isymbuf + ELF32_R_SYM (irelscan->r_info);
+
+ /* Look at the reloc only if the value has been resolved. */
+ if (isym->st_shndx == shndx
+ && (ELF32_ST_TYPE (isym->st_info) == STT_SECTION))
+ {
+ bfd_vma immediate;
+
+ 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. */
+
+ if (o->rawsize == 0)
+ o->rawsize = o->size;
+ ocontents = (bfd_byte *) bfd_malloc (o->rawsize);
+ if (ocontents == NULL)
+ goto error_return;
+ if (!bfd_get_section_contents (abfd, o, ocontents,
+ (file_ptr) 0,
+ o->rawsize))
+ goto error_return;
+ elf_section_data (o)->this_hdr.contents = ocontents;
+ }
+ }
+ unsigned long instr_hi = bfd_get_32 (abfd, ocontents
+ + irelscan->r_offset);
+ unsigned long instr_lo = bfd_get_32 (abfd, ocontents
+ + irelscan->r_offset
+ + INST_WORD_SIZE);
+ immediate = (instr_hi & 0x0000ffff) << 16;
+ immediate |= (instr_lo & 0x0000ffff);
+ offset = calc_fixup (irelscan->r_addend, 0, sec);
+ immediate -= offset;
+ irelscan->r_addend -= offset;
+ }
+ }
+ else if (ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_64_PCREL)
+ {
+ isym = isymbuf + ELF32_R_SYM (irelscan->r_info);
+
+ /* Look at the reloc only if the value has been resolved. */
+ if (isym->st_shndx == shndx
+ && (ELF32_ST_TYPE (isym->st_info) == STT_SECTION))
+ {
+ bfd_vma immediate;
+ bfd_vma target_address;
+
+ 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. */
+ if (o->rawsize == 0)
+ o->rawsize = o->size;
+ ocontents = (bfd_byte *) bfd_malloc (o->rawsize);
+ if (ocontents == NULL)
+ goto error_return;
+ if (!bfd_get_section_contents (abfd, o, ocontents,
+ (file_ptr) 0,
+ o->rawsize))
+ goto error_return;
+ elf_section_data (o)->this_hdr.contents = ocontents;
+ }
+ }
+ unsigned long instr_hi = bfd_get_32 (abfd, ocontents
+ + irelscan->r_offset);
+ unsigned long instr_lo = bfd_get_32 (abfd, ocontents
+ + irelscan->r_offset
+ + INST_WORD_SIZE);
+ immediate = (instr_hi & 0x0000ffff) << 16;
+ immediate |= (instr_lo & 0x0000ffff);
+ target_address = immediate;
+ offset = calc_fixup (target_address, 0, sec);
+ immediate -= offset;
+ irelscan->r_addend -= offset;
+ microblaze_bfd_write_imm_value_64 (abfd, ocontents
+ + irelscan->r_offset, immediate);
+ }
+ }
+ }
+ }
+
+ /* Adjust the local symbols defined in this section. */
+ isymend = isymbuf + symtab_hdr->sh_info;
+ for (isym = isymbuf; isym < isymend; isym++)
+ {
+ if (isym->st_shndx == shndx)
+ {
+ isym->st_value -= calc_fixup (isym->st_value, 0, sec);
+ if (isym->st_size)
+ isym->st_size -= calc_fixup (isym->st_value, isym->st_size, sec);
+ }
+ }
+
+ /* Now adjust the global symbols defined in this section. */
+ isym = isymbuf + symtab_hdr->sh_info;
+ symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)) - symtab_hdr->sh_info;
+ for (sym_index = 0; sym_index < symcount; sym_index++)
+ {
+ sym_hash = elf_sym_hashes (abfd)[sym_index];
+ 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 -= calc_fixup (sym_hash->root.u.def.value,
+ 0, sec);
+ if (sym_hash->size)
+ sym_hash->size -= calc_fixup (sym_hash->root.u.def.value,
+ sym_hash->size, sec);
+ }
+ }
+
+ /* Physically move the code and change the cooked size. */
+ dest = sec->relax[0].addr;
+ for (i = 0; i < sec->relax_count; i++)
+ {
+ int len;
+ src = sec->relax[i].addr + sec->relax[i].size;
+ len = sec->relax[i+1].addr - sec->relax[i].addr - sec->relax[i].size;
+
+ memmove (contents + dest, contents + src, len);
+ sec->size -= sec->relax[i].size;
+ dest += len;
+ }
+
+ 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 *) isymbuf;
+ }
+
+ 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 (sec->relax_count == 0)
+ {
+ *again = FALSE;
+ free (sec->relax);
+ sec->relax = NULL;
+ }
+ else
+ *again = TRUE;
+ return TRUE;
+
+ error_return:
+ if (free_relocs != NULL)
+ free (free_relocs);
+ if (free_contents != NULL)
+ free (free_contents);
+ if (sec->relax != NULL)
+ {
+ free (sec->relax);
+ sec->relax = NULL;
+ sec->relax_count = 0;
+ }
+ return FALSE;
+}
+
+/* Return the section that should be marked against GC for a given
+ relocation. */
+
+static asection *
+microblaze_elf_gc_mark_hook (asection *sec,
+ 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_MICROBLAZE_GNU_VTINHERIT:
+ case R_MICROBLAZE_GNU_VTENTRY:
+ return NULL;
+ }
+
+ return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
+}
+
+/* Update the got entry reference counts for the section being removed. */
+
+static bfd_boolean
+microblaze_elf_gc_sweep_hook (bfd * abfd ATTRIBUTE_UNUSED,
+ struct bfd_link_info * info ATTRIBUTE_UNUSED,
+ asection * sec ATTRIBUTE_UNUSED,
+ const Elf_Internal_Rela * relocs ATTRIBUTE_UNUSED)
+{
+ return TRUE;
+}
+
+/* PIC support. */
+
+#define PLT_ENTRY_SIZE 16
+
+#define PLT_ENTRY_WORD_0 0xb0000000 /* "imm 0". */
+#define PLT_ENTRY_WORD_1 0xe9940000 /* "lwi r12,r20,0" - relocated to lwi r12,r20,func@GOT. */
+#define PLT_ENTRY_WORD_1_NOPIC 0xe9800000 /* "lwi r12,r0,0" - non-PIC object. */
+#define PLT_ENTRY_WORD_2 0x98186000 /* "brad r12". */
+#define PLT_ENTRY_WORD_3 0x80000000 /* "nop". */
+
+/* Create .got, .gotplt, and .rela.got sections in DYNOBJ, and set up
+ shortcuts to them in our hash table. */
+
+static bfd_boolean
+create_got_section (bfd *dynobj, struct bfd_link_info *info)
+{
+ struct elf32_mb_link_hash_table *htab;
+
+ if (! _bfd_elf_create_got_section (dynobj, info))
+ return FALSE;
+ htab = elf32_mb_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ htab->sgot = bfd_get_linker_section (dynobj, ".got");
+ htab->sgotplt = bfd_get_linker_section (dynobj, ".got.plt");
+ if (!htab->sgot || !htab->sgotplt)
+ return FALSE;
+
+ if ((htab->srelgot = bfd_get_linker_section (dynobj, ".rela.got")) == NULL)
+ htab->srelgot = bfd_make_section_anyway (dynobj, ".rela.got");
+ if (htab->srelgot == NULL
+ || ! bfd_set_section_flags (dynobj, htab->srelgot, SEC_ALLOC
+ | SEC_LOAD
+ | SEC_HAS_CONTENTS
+ | SEC_IN_MEMORY
+ | SEC_LINKER_CREATED
+ | SEC_READONLY)
+ || ! bfd_set_section_alignment (dynobj, htab->srelgot, 2))
+ return FALSE;
+ return TRUE;
+}
+
+static bfd_boolean
+update_local_sym_info (bfd *abfd,
+ Elf_Internal_Shdr *symtab_hdr,
+ unsigned long r_symndx,
+ unsigned int tls_type)
+{
+ bfd_signed_vma *local_got_refcounts = elf_local_got_refcounts (abfd);
+ unsigned char *local_got_tls_masks;
+
+ if (local_got_refcounts == NULL)
+ {
+ bfd_size_type size = symtab_hdr->sh_info;
+
+ size *= (sizeof (*local_got_refcounts) + sizeof (*local_got_tls_masks));
+ local_got_refcounts = bfd_zalloc (abfd, size);
+ if (local_got_refcounts == NULL)
+ return FALSE;
+ elf_local_got_refcounts (abfd) = local_got_refcounts;
+ }
+
+ local_got_tls_masks =
+ (unsigned char *) (local_got_refcounts + symtab_hdr->sh_info);
+ local_got_tls_masks[r_symndx] |= tls_type;
+ local_got_refcounts[r_symndx] += 1;
+
+ return TRUE;
+}
+/* Look through the relocs for a section during the first phase. */
+
+static bfd_boolean
+microblaze_elf_check_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;
+ struct elf32_mb_link_hash_table *htab;
+ asection *sreloc = NULL;
+
+ if (info->relocatable)
+ return TRUE;
+
+ htab = elf32_mb_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ 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++)
+ {
+ unsigned int r_type;
+ struct elf_link_hash_entry * h;
+ unsigned long r_symndx;
+ unsigned char tls_type = 0;
+
+ r_symndx = ELF32_R_SYM (rel->r_info);
+ r_type = ELF32_R_TYPE (rel->r_info);
+
+ if (r_symndx < symtab_hdr->sh_info)
+ h = NULL;
+ else
+ {
+ h = sym_hashes [r_symndx - symtab_hdr->sh_info];
+
+ /* PR15323, ref flags aren't set for references in the same
+ object. */
+ h->root.non_ir_ref = 1;
+ }
+
+ switch (r_type)
+ {
+ /* This relocation describes the C++ object vtable hierarchy.
+ Reconstruct it for later use during GC. */
+ case R_MICROBLAZE_GNU_VTINHERIT:
+ if (!bfd_elf_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_MICROBLAZE_GNU_VTENTRY:
+ if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
+ return FALSE;
+ break;
+
+ /* This relocation requires .plt entry. */
+ case R_MICROBLAZE_PLT_64:
+ if (h != NULL)
+ {
+ h->needs_plt = 1;
+ h->plt.refcount += 1;
+ }
+ break;
+
+ /* This relocation requires .got entry. */
+ case R_MICROBLAZE_TLSGD:
+ tls_type |= (TLS_TLS | TLS_GD);
+ goto dogottls;
+ case R_MICROBLAZE_TLSLD:
+ tls_type |= (TLS_TLS | TLS_LD);
+ dogottls:
+ sec->has_tls_reloc = 1;
+ case R_MICROBLAZE_GOT_64:
+ if (htab->sgot == NULL)
+ {
+ if (htab->elf.dynobj == NULL)
+ htab->elf.dynobj = abfd;
+ if (!create_got_section (htab->elf.dynobj, info))
+ return FALSE;
+ }
+ if (h != NULL)
+ {
+ h->got.refcount += 1;
+ elf32_mb_hash_entry (h)->tls_mask |= tls_type;
+ }
+ else
+ {
+ if (! update_local_sym_info(abfd, symtab_hdr, r_symndx, tls_type) )
+ return FALSE;
+ }
+ break;
+
+ case R_MICROBLAZE_64:
+ case R_MICROBLAZE_64_PCREL:
+ case R_MICROBLAZE_32:
+ {
+ if (h != NULL && !info->shared)
+ {
+ /* we may need a copy reloc. */
+ h->non_got_ref = 1;
+
+ /* we may also need a .plt entry. */
+ h->plt.refcount += 1;
+ if (ELF32_R_TYPE (rel->r_info) != R_MICROBLAZE_64_PCREL)
+ h->pointer_equality_needed = 1;
+ }
+
+
+ /* 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). In case of a weak definition,
+ DEF_REGULAR may be cleared later by a strong definition in
+ a shared library. We account for that possibility below by
+ storing information in the relocs_copied field of the hash
+ table entry. A similar situation occurs when creating
+ shared libraries and symbol visibility changes render the
+ symbol local.
+
+ If on the other hand, we are creating an executable, we
+ may need to keep relocations for symbols satisfied by a
+ dynamic library if we manage to avoid copy relocs for the
+ symbol. */
+
+ if ((info->shared
+ && (sec->flags & SEC_ALLOC) != 0
+ && (r_type != R_MICROBLAZE_64_PCREL
+ || (h != NULL
+ && (! info->symbolic
+ || h->root.type == bfd_link_hash_defweak
+ || !h->def_regular))))
+ || (!info->shared
+ && (sec->flags & SEC_ALLOC) != 0
+ && h != NULL
+ && (h->root.type == bfd_link_hash_defweak
+ || !h->def_regular)))
+ {
+ struct elf32_mb_dyn_relocs *p;
+ struct elf32_mb_dyn_relocs **head;
+
+ /* 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)
+ {
+ bfd *dynobj;
+
+ if (htab->elf.dynobj == NULL)
+ htab->elf.dynobj = abfd;
+ dynobj = htab->elf.dynobj;
+
+ sreloc = _bfd_elf_make_dynamic_reloc_section (sec, dynobj,
+ 2, abfd, 1);
+ if (sreloc == NULL)
+ return FALSE;
+ }
+
+ /* If this is a global symbol, we count the number of
+ relocations we need for this symbol. */
+ if (h != NULL)
+ head = &((struct elf32_mb_link_hash_entry *) h)->dyn_relocs;
+ else
+ {
+ /* Track dynamic relocs needed for local syms too.
+ We really need local syms available to do this
+ easily. Oh well. */
+
+ asection *s;
+ Elf_Internal_Sym *isym;
+ void *vpp;
+
+ isym = bfd_sym_from_r_symndx (&htab->sym_sec,
+ abfd, r_symndx);
+ if (isym == NULL)
+ return FALSE;
+
+ s = bfd_section_from_elf_index (abfd, isym->st_shndx);
+ if (s == NULL)
+ return FALSE;
+
+ vpp = &elf_section_data (s)->local_dynrel;
+ head = (struct elf32_mb_dyn_relocs **) vpp;
+ }
+
+ p = *head;
+ if (p == NULL || p->sec != sec)
+ {
+ bfd_size_type amt = sizeof *p;
+ p = ((struct elf32_mb_dyn_relocs *)
+ bfd_alloc (htab->elf.dynobj, amt));
+ if (p == NULL)
+ return FALSE;
+ p->next = *head;
+ *head = p;
+ p->sec = sec;
+ p->count = 0;
+ p->pc_count = 0;
+ }
+
+ p->count += 1;
+ if (r_type == R_MICROBLAZE_64_PCREL)
+ p->pc_count += 1;
+ }
+ }
+ break;
+ }
+ }
+
+ return TRUE;
+}
+
+static bfd_boolean
+microblaze_elf_create_dynamic_sections (bfd *dynobj, struct bfd_link_info *info)
+{
+ struct elf32_mb_link_hash_table *htab;
+
+ htab = elf32_mb_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ if (!htab->sgot && !create_got_section (dynobj, info))
+ return FALSE;
+
+ if (!_bfd_elf_create_dynamic_sections (dynobj, info))
+ return FALSE;
+
+ htab->splt = bfd_get_linker_section (dynobj, ".plt");
+ htab->srelplt = bfd_get_linker_section (dynobj, ".rela.plt");
+ htab->sdynbss = bfd_get_linker_section (dynobj, ".dynbss");
+ if (!info->shared)
+ htab->srelbss = bfd_get_linker_section (dynobj, ".rela.bss");
+
+ if (!htab->splt || !htab->srelplt || !htab->sdynbss
+ || (!info->shared && !htab->srelbss))
+ abort ();
+
+ return TRUE;
+}
+
+/* Copy the extra info we tack onto an elf_link_hash_entry. */
+
+static void
+microblaze_elf_copy_indirect_symbol (struct bfd_link_info *info,
+ struct elf_link_hash_entry *dir,
+ struct elf_link_hash_entry *ind)
+{
+ struct elf32_mb_link_hash_entry *edir, *eind;
+
+ edir = (struct elf32_mb_link_hash_entry *) dir;
+ eind = (struct elf32_mb_link_hash_entry *) ind;
+
+ if (eind->dyn_relocs != NULL)
+ {
+ if (edir->dyn_relocs != NULL)
+ {
+ struct elf32_mb_dyn_relocs **pp;
+ struct elf32_mb_dyn_relocs *p;
+
+ if (ind->root.type == bfd_link_hash_indirect)
+ abort ();
+
+ /* Add reloc counts against the weak sym to the strong sym
+ list. Merge any entries against the same section. */
+ for (pp = &eind->dyn_relocs; (p = *pp) != NULL; )
+ {
+ struct elf32_mb_dyn_relocs *q;
+
+ for (q = edir->dyn_relocs; q != NULL; q = q->next)
+ if (q->sec == p->sec)
+ {
+ q->pc_count += p->pc_count;
+ q->count += p->count;
+ *pp = p->next;
+ break;
+ }
+ if (q == NULL)
+ pp = &p->next;
+ }
+ *pp = edir->dyn_relocs;
+ }
+
+ edir->dyn_relocs = eind->dyn_relocs;
+ eind->dyn_relocs = NULL;
+ }
+
+ edir->tls_mask |= eind->tls_mask;
+
+ _bfd_elf_link_hash_copy_indirect (info, dir, ind);
+}
+
+static bfd_boolean
+microblaze_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
+ struct elf_link_hash_entry *h)
+{
+ struct elf32_mb_link_hash_table *htab;
+ struct elf32_mb_link_hash_entry * eh;
+ struct elf32_mb_dyn_relocs *p;
+ asection *sdynbss, *s;
+ unsigned int power_of_two;
+ bfd *dynobj;
+
+ htab = elf32_mb_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ /* 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->needs_plt)
+ {
+ if (h->plt.refcount <= 0
+ || SYMBOL_CALLS_LOCAL (info, h)
+ || (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
+ && h->root.type == bfd_link_hash_undefweak))
+ {
+ /* This case can occur if we saw a PLT reloc in an input
+ file, but the symbol was never referred to by a dynamic
+ object, or if all references were garbage collected. In
+ such a case, we don't actually need to build a procedure
+ linkage table, and we can just do a PC32 reloc instead. */
+ h->plt.offset = (bfd_vma) -1;
+ h->needs_plt = 0;
+ }
+
+ return TRUE;
+ }
+ else
+ /* It's possible that we incorrectly decided a .plt reloc was
+ needed for an R_MICROBLAZE_64_PCREL reloc to a non-function sym in
+ check_relocs. We can't decide accurately between function and
+ non-function syms in check-relocs; Objects loaded later in
+ the link may change h->type. So fix it now. */
+ 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->u.weakdef != NULL)
+ {
+ BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
+ || h->u.weakdef->root.type == bfd_link_hash_defweak);
+ h->root.u.def.section = h->u.weakdef->root.u.def.section;
+ h->root.u.def.value = h->u.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;
+
+ /* If there are no references to this symbol that do not use the
+ GOT, we don't need to generate a copy reloc. */
+ if (!h->non_got_ref)
+ return TRUE;
+
+ /* If -z nocopyreloc was given, we won't generate them either. */
+ if (info->nocopyreloc)
+ {
+ h->non_got_ref = 0;
+ return TRUE;
+ }
+
+ eh = (struct elf32_mb_link_hash_entry *) h;
+ for (p = eh->dyn_relocs; p != NULL; p = p->next)
+ {
+ s = p->sec->output_section;
+ if (s != NULL && (s->flags & SEC_READONLY) != 0)
+ break;
+ }
+
+ /* If we didn't find any dynamic relocs in read-only sections, then
+ we'll be keeping the dynamic relocs and avoiding the copy reloc. */
+ if (p == NULL)
+ {
+ h->non_got_ref = 0;
+ 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. */
+
+ /* We must generate a R_MICROBLAZE_COPY reloc to tell the dynamic linker
+ to copy the initial value out of the dynamic object and into the
+ runtime process image. */
+ dynobj = elf_hash_table (info)->dynobj;
+ BFD_ASSERT (dynobj != NULL);
+ if ((h->root.u.def.section->flags & SEC_ALLOC) != 0)
+ {
+ htab->srelbss->size += sizeof (Elf32_External_Rela);
+ h->needs_copy = 1;
+ }
+
+ /* 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;
+
+ sdynbss = htab->sdynbss;
+ /* Apply the required alignment. */
+ sdynbss->size = BFD_ALIGN (sdynbss->size, (bfd_size_type) (1 << power_of_two));
+ if (power_of_two > bfd_get_section_alignment (dynobj, sdynbss))
+ {
+ if (! bfd_set_section_alignment (dynobj, sdynbss, power_of_two))
+ return FALSE;
+ }
+
+ /* Define the symbol as being at this point in the section. */
+ h->root.u.def.section = sdynbss;
+ h->root.u.def.value = sdynbss->size;
+
+ /* Increment the section size to make room for the symbol. */
+ sdynbss->size += h->size;
+ return TRUE;
+}
+
+/* Allocate space in .plt, .got and associated reloc sections for
+ dynamic relocs. */
+
+static bfd_boolean
+allocate_dynrelocs (struct elf_link_hash_entry *h, void * dat)
+{
+ struct bfd_link_info *info;
+ struct elf32_mb_link_hash_table *htab;
+ struct elf32_mb_link_hash_entry *eh;
+ struct elf32_mb_dyn_relocs *p;
+
+ if (h->root.type == bfd_link_hash_indirect)
+ return TRUE;
+
+ info = (struct bfd_link_info *) dat;
+ htab = elf32_mb_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ if (htab->elf.dynamic_sections_created
+ && h->plt.refcount > 0)
+ {
+ /* Make sure this symbol is output as a dynamic symbol.
+ Undefined weak syms won't yet be marked as dynamic. */
+ if (h->dynindx == -1
+ && !h->forced_local)
+ {
+ if (! bfd_elf_link_record_dynamic_symbol (info, h))
+ return FALSE;
+ }
+
+ if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, info->shared, h))
+ {
+ asection *s = htab->splt;
+
+ /* The first entry in .plt is reserved. */
+ if (s->size == 0)
+ s->size = PLT_ENTRY_SIZE;
+
+ h->plt.offset = s->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->def_regular)
+ {
+ h->root.u.def.section = s;
+ h->root.u.def.value = h->plt.offset;
+ }
+
+ /* Make room for this entry. */
+ s->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. */
+ htab->sgotplt->size += 4;
+
+ /* We also need to make an entry in the .rel.plt section. */
+ htab->srelplt->size += sizeof (Elf32_External_Rela);
+ }
+ else
+ {
+ h->plt.offset = (bfd_vma) -1;
+ h->needs_plt = 0;
+ }
+ }
+ else
+ {
+ h->plt.offset = (bfd_vma) -1;
+ h->needs_plt = 0;
+ }
+
+ eh = (struct elf32_mb_link_hash_entry *) h;
+ if (h->got.refcount > 0)
+ {
+ unsigned int need;
+ asection *s;
+
+ /* Make sure this symbol is output as a dynamic symbol.
+ Undefined weak syms won't yet be marked as dynamic. */
+ if (h->dynindx == -1
+ && !h->forced_local)
+ {
+ if (! bfd_elf_link_record_dynamic_symbol (info, h))
+ return FALSE;
+ }
+
+ need = 0;
+ if ((eh->tls_mask & TLS_TLS) != 0)
+ {
+ /* Handle TLS Symbol */
+ if ((eh->tls_mask & TLS_LD) != 0)
+ {
+ if (!eh->elf.def_dynamic)
+ /* We'll just use htab->tlsld_got.offset. This should
+ always be the case. It's a little odd if we have
+ a local dynamic reloc against a non-local symbol. */
+ htab->tlsld_got.refcount += 1;
+ else
+ need += 8;
+ }
+ if ((eh->tls_mask & TLS_GD) != 0)
+ need += 8;
+ }
+ else
+ {
+ /* Regular (non-TLS) symbol */
+ need += 4;
+ }
+ if (need == 0)
+ {
+ h->got.offset = (bfd_vma) -1;
+ }
+ else
+ {
+ s = htab->sgot;
+ h->got.offset = s->size;
+ s->size += need;
+ htab->srelgot->size += need * (sizeof (Elf32_External_Rela) / 4);
+ }
+ }
+ else
+ h->got.offset = (bfd_vma) -1;
+
+ if (eh->dyn_relocs == NULL)
+ return TRUE;
+
+ /* In the shared -Bsymbolic case, discard space allocated for
+ dynamic pc-relative relocs against symbols which turn out to be
+ defined in regular objects. For the normal shared case, discard
+ space for pc-relative relocs that have become local due to symbol
+ visibility changes. */
+
+ if (info->shared)
+ {
+ if (h->def_regular
+ && (h->forced_local
+ || info->symbolic))
+ {
+ struct elf32_mb_dyn_relocs **pp;
+
+ for (pp = &eh->dyn_relocs; (p = *pp) != NULL; )
+ {
+ p->count -= p->pc_count;
+ p->pc_count = 0;
+ if (p->count == 0)
+ *pp = p->next;
+ else
+ pp = &p->next;
+ }
+ }
+ }
+ else
+ {
+ /* For the non-shared case, discard space for relocs against
+ symbols which turn out to need copy relocs or are not
+ dynamic. */
+
+ if (!h->non_got_ref
+ && ((h->def_dynamic
+ && !h->def_regular)
+ || (htab->elf.dynamic_sections_created
+ && (h->root.type == bfd_link_hash_undefweak
+ || h->root.type == bfd_link_hash_undefined))))
+ {
+ /* Make sure this symbol is output as a dynamic symbol.
+ Undefined weak syms won't yet be marked as dynamic. */
+ if (h->dynindx == -1
+ && !h->forced_local)
+ {
+ if (! bfd_elf_link_record_dynamic_symbol (info, h))
+ return FALSE;
+ }
+
+ /* If that succeeded, we know we'll be keeping all the
+ relocs. */
+ if (h->dynindx != -1)
+ goto keep;
+ }
+
+ eh->dyn_relocs = NULL;
+
+ keep: ;
+ }
+
+ /* Finally, allocate space. */
+ for (p = eh->dyn_relocs; p != NULL; p = p->next)
+ {
+ asection *sreloc = elf_section_data (p->sec)->sreloc;
+ sreloc->size += p->count * sizeof (Elf32_External_Rela);
+ }
+
+ return TRUE;
+}
+
+/* Set the sizes of the dynamic sections. */
+
+static bfd_boolean
+microblaze_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
+ struct bfd_link_info *info)
+{
+ struct elf32_mb_link_hash_table *htab;
+ bfd *dynobj;
+ asection *s;
+ bfd *ibfd;
+
+ htab = elf32_mb_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ dynobj = htab->elf.dynobj;
+ BFD_ASSERT (dynobj != NULL);
+
+ /* Set up .got offsets for local syms, and space for local dynamic
+ relocs. */
+ for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next)
+ {
+ bfd_signed_vma *local_got;
+ bfd_signed_vma *end_local_got;
+ bfd_size_type locsymcount;
+ Elf_Internal_Shdr *symtab_hdr;
+ unsigned char *lgot_masks;
+ asection *srel;
+
+ if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour)
+ continue;
+
+ for (s = ibfd->sections; s != NULL; s = s->next)
+ {
+ struct elf32_mb_dyn_relocs *p;
+
+ for (p = ((struct elf32_mb_dyn_relocs *)
+ elf_section_data (s)->local_dynrel);
+ p != NULL;
+ p = p->next)
+ {
+ if (!bfd_is_abs_section (p->sec)
+ && bfd_is_abs_section (p->sec->output_section))
+ {
+ /* Input section has been discarded, either because
+ it is a copy of a linkonce section or due to
+ linker script /DISCARD/, so we'll be discarding
+ the relocs too. */
+ }
+ else if (p->count != 0)
+ {
+ srel = elf_section_data (p->sec)->sreloc;
+ srel->size += p->count * sizeof (Elf32_External_Rela);
+ if ((p->sec->output_section->flags & SEC_READONLY) != 0)
+ info->flags |= DF_TEXTREL;
+ }
+ }
+ }
+
+ local_got = elf_local_got_refcounts (ibfd);
+ if (!local_got)
+ continue;
+
+ symtab_hdr = &elf_tdata (ibfd)->symtab_hdr;
+ locsymcount = symtab_hdr->sh_info;
+ end_local_got = local_got + locsymcount;
+ lgot_masks = (unsigned char *) end_local_got;
+ s = htab->sgot;
+ srel = htab->srelgot;
+
+ for (; local_got < end_local_got; ++local_got, ++lgot_masks)
+ {
+ if (*local_got > 0)
+ {
+ unsigned int need = 0;
+ if ((*lgot_masks & TLS_TLS) != 0)
+ {
+ if ((*lgot_masks & TLS_GD) != 0)
+ need += 8;
+ if ((*lgot_masks & TLS_LD) != 0)
+ htab->tlsld_got.refcount += 1;
+ }
+ else
+ need += 4;
+
+ if (need == 0)
+ {
+ *local_got = (bfd_vma) -1;
+ }
+ else
+ {
+ *local_got = s->size;
+ s->size += need;
+ if (info->shared)
+ srel->size += need * (sizeof (Elf32_External_Rela) / 4);
+ }
+ }
+ else
+ *local_got = (bfd_vma) -1;
+ }
+ }
+
+ /* Allocate global sym .plt and .got entries, and space for global
+ sym dynamic relocs. */
+ elf_link_hash_traverse (elf_hash_table (info), allocate_dynrelocs, info);
+
+ if (htab->tlsld_got.refcount > 0)
+ {
+ htab->tlsld_got.offset = htab->sgot->size;
+ htab->sgot->size += 8;
+ if (info->shared)
+ htab->srelgot->size += sizeof (Elf32_External_Rela);
+ }
+ else
+ htab->tlsld_got.offset = (bfd_vma) -1;
+
+ if (elf_hash_table (info)->dynamic_sections_created)
+ {
+ /* Make space for the trailing nop in .plt. */
+ if (htab->splt->size > 0)
+ htab->splt->size += 4;
+ }
+
+ /* The check_relocs and adjust_dynamic_symbol entry points have
+ determined the sizes of the various dynamic sections. Allocate
+ memory for them. */
+ for (s = dynobj->sections; s != NULL; s = s->next)
+ {
+ const char *name;
+ bfd_boolean strip = FALSE;
+
+ 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);
+
+ if (strncmp (name, ".rela", 5) == 0)
+ {
+ if (s->size == 0)
+ {
+ /* 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 = TRUE;
+ }
+ else
+ {
+ /* 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 (s != htab->splt && s != htab->sgot && s != htab->sgotplt)
+ {
+ /* It's not one of our sections, so don't allocate space. */
+ continue;
+ }
+
+ if (strip)
+ {
+ s->flags |= SEC_EXCLUDE;
+ continue;
+ }
+
+ /* Allocate memory for the section contents. */
+ /* FIXME: This should be a call to bfd_alloc not bfd_zalloc.
+ Unused entries should be reclaimed before the section's contents
+ are written out, but at the moment this does not happen. Thus in
+ order to prevent writing out garbage, we initialise the section's
+ contents to zero. */
+ s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->size);
+ if (s->contents == NULL && s->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 microblaze_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. */
+#define add_dynamic_entry(TAG, VAL) \
+ _bfd_elf_add_dynamic_entry (info, TAG, VAL)
+
+ if (info->executable)
+ {
+ if (!add_dynamic_entry (DT_DEBUG, 0))
+ return FALSE;
+ }
+
+ if (!add_dynamic_entry (DT_RELA, 0)
+ || !add_dynamic_entry (DT_RELASZ, 0)
+ || !add_dynamic_entry (DT_RELAENT, sizeof (Elf32_External_Rela)))
+ return FALSE;
+
+ if (htab->splt->size != 0)
+ {
+ if (!add_dynamic_entry (DT_PLTGOT, 0)
+ || !add_dynamic_entry (DT_PLTRELSZ, 0)
+ || !add_dynamic_entry (DT_PLTREL, DT_RELA)
+ || !add_dynamic_entry (DT_JMPREL, 0)
+ || !add_dynamic_entry (DT_BIND_NOW, 1))
+ return FALSE;
+ }
+
+ if (info->flags & DF_TEXTREL)
+ {
+ if (!add_dynamic_entry (DT_TEXTREL, 0))
+ return FALSE;
+ }
+ }
+#undef add_dynamic_entry
+ return TRUE;
+}
+
+/* Finish up dynamic symbol handling. We set the contents of various
+ dynamic sections here. */
+
+static bfd_boolean
+microblaze_elf_finish_dynamic_symbol (bfd *output_bfd,
+ struct bfd_link_info *info,
+ struct elf_link_hash_entry *h,
+ Elf_Internal_Sym *sym)
+{
+ struct elf32_mb_link_hash_table *htab;
+ struct elf32_mb_link_hash_entry *eh = elf32_mb_hash_entry(h);
+
+ htab = elf32_mb_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ if (h->plt.offset != (bfd_vma) -1)
+ {
+ asection *splt;
+ asection *srela;
+ asection *sgotplt;
+ Elf_Internal_Rela rela;
+ bfd_byte *loc;
+ bfd_vma plt_index;
+ bfd_vma got_offset;
+ bfd_vma got_addr;
+
+ /* This symbol has an entry in the procedure linkage table. Set
+ it up. */
+ BFD_ASSERT (h->dynindx != -1);
+
+ splt = htab->splt;
+ srela = htab->srelplt;
+ sgotplt = htab->sgotplt;
+ BFD_ASSERT (splt != NULL && srela != NULL && sgotplt != NULL);
+
+ plt_index = h->plt.offset / PLT_ENTRY_SIZE - 1; /* first entry reserved. */
+ got_offset = (plt_index + 3) * 4; /* 3 reserved ??? */
+ got_addr = got_offset;
+
+ /* For non-PIC objects we need absolute address of the GOT entry. */
+ if (!info->shared)
+ got_addr += htab->sgotplt->output_section->vma + sgotplt->output_offset;
+
+ /* Fill in the entry in the procedure linkage table. */
+ bfd_put_32 (output_bfd, PLT_ENTRY_WORD_0 + ((got_addr >> 16) & 0xffff),
+ splt->contents + h->plt.offset);
+ if (info->shared)
+ bfd_put_32 (output_bfd, PLT_ENTRY_WORD_1 + (got_addr & 0xffff),
+ splt->contents + h->plt.offset + 4);
+ else
+ bfd_put_32 (output_bfd, PLT_ENTRY_WORD_1_NOPIC + (got_addr & 0xffff),
+ splt->contents + h->plt.offset + 4);
+ bfd_put_32 (output_bfd, (bfd_vma) PLT_ENTRY_WORD_2,
+ splt->contents + h->plt.offset + 8);
+ bfd_put_32 (output_bfd, (bfd_vma) PLT_ENTRY_WORD_3,
+ splt->contents + h->plt.offset + 12);
+
+ /* Any additions to the .got section??? */
+ /* bfd_put_32 (output_bfd,
+ splt->output_section->vma + splt->output_offset + h->plt.offset + 4,
+ sgotplt->contents + got_offset); */
+
+ /* Fill in the entry in the .rela.plt section. */
+ rela.r_offset = (sgotplt->output_section->vma
+ + sgotplt->output_offset
+ + got_offset);
+ rela.r_info = ELF32_R_INFO (h->dynindx, R_MICROBLAZE_JUMP_SLOT);
+ rela.r_addend = 0;
+ loc = srela->contents;
+ loc += plt_index * sizeof (Elf32_External_Rela);
+ bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
+
+ if (!h->def_regular)
+ {
+ /* Mark the symbol as undefined, rather than as defined in
+ the .plt section. Zero the value. */
+ sym->st_shndx = SHN_UNDEF;
+ sym->st_value = 0;
+ }
+ }
+
+ /* h->got.refcount to be checked ? */
+ if (h->got.offset != (bfd_vma) -1 &&
+ ! ((h->got.offset & 1) ||
+ IS_TLS_LD(eh->tls_mask) || IS_TLS_GD(eh->tls_mask)))
+ {
+ asection *sgot;
+ asection *srela;
+ bfd_vma offset;
+
+ /* This symbol has an entry in the global offset table. Set it
+ up. */
+
+ sgot = htab->sgot;
+ srela = htab->srelgot;
+ BFD_ASSERT (sgot != NULL && srela != NULL);
+
+ offset = (sgot->output_section->vma + sgot->output_offset
+ + (h->got.offset &~ (bfd_vma) 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->def_regular)
+ {
+ asection *sec = h->root.u.def.section;
+ microblaze_elf_output_dynamic_relocation (output_bfd,
+ srela, srela->reloc_count++,
+ /* symindex= */ 0,
+ R_MICROBLAZE_REL, offset,
+ h->root.u.def.value
+ + sec->output_section->vma
+ + sec->output_offset);
+ }
+ else
+ {
+ microblaze_elf_output_dynamic_relocation (output_bfd,
+ srela, srela->reloc_count++,
+ h->dynindx,
+ R_MICROBLAZE_GLOB_DAT,
+ offset, 0);
+ }
+
+ bfd_put_32 (output_bfd, (bfd_vma) 0,
+ sgot->contents + (h->got.offset &~ (bfd_vma) 1));
+ }
+
+ if (h->needs_copy)
+ {
+ asection *s;
+ Elf_Internal_Rela rela;
+ bfd_byte *loc;
+
+ /* This symbols needs a copy reloc. Set it up. */
+
+ BFD_ASSERT (h->dynindx != -1);
+
+ s = bfd_get_linker_section (htab->elf.dynobj, ".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_MICROBLAZE_COPY);
+ rela.r_addend = 0;
+ loc = s->contents + s->reloc_count++ * sizeof (Elf32_External_Rela);
+ bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
+ }
+
+ /* Mark some specially defined symbols as absolute. */
+ if (h == htab->elf.hdynamic
+ || h == htab->elf.hgot
+ || h == htab->elf.hplt)
+ sym->st_shndx = SHN_ABS;
+
+ return TRUE;
+}
+
+
+/* Finish up the dynamic sections. */
+
+static bfd_boolean
+microblaze_elf_finish_dynamic_sections (bfd *output_bfd,
+ struct bfd_link_info *info)
+{
+ bfd *dynobj;
+ asection *sdyn, *sgot;
+ struct elf32_mb_link_hash_table *htab;
+
+ htab = elf32_mb_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ dynobj = htab->elf.dynobj;
+
+ sdyn = bfd_get_linker_section (dynobj, ".dynamic");
+
+ if (htab->elf.dynamic_sections_created)
+ {
+ asection *splt;
+ Elf32_External_Dyn *dyncon, *dynconend;
+
+ splt = bfd_get_linker_section (dynobj, ".plt");
+ BFD_ASSERT (splt != NULL && sdyn != NULL);
+
+ dyncon = (Elf32_External_Dyn *) sdyn->contents;
+ dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->size);
+ for (; dyncon < dynconend; dyncon++)
+ {
+ Elf_Internal_Dyn dyn;
+ const char *name;
+ bfd_boolean size;
+
+ bfd_elf32_swap_dyn_in (dynobj, dyncon, &dyn);
+
+ switch (dyn.d_tag)
+ {
+ case DT_PLTGOT: name = ".got.plt"; size = FALSE; break;
+ case DT_PLTRELSZ: name = ".rela.plt"; size = TRUE; break;
+ case DT_JMPREL: name = ".rela.plt"; size = FALSE; break;
+ case DT_RELA: name = ".rela.dyn"; size = FALSE; break;
+ case DT_RELASZ: name = ".rela.dyn"; size = TRUE; 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
+ dyn.d_un.d_val = s->size;
+ }
+ bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
+ }
+ }
+
+ /* Clear the first entry in the procedure linkage table,
+ and put a nop in the last four bytes. */
+ if (splt->size > 0)
+ {
+ memset (splt->contents, 0, PLT_ENTRY_SIZE);
+ bfd_put_32 (output_bfd, (bfd_vma) 0x80000000 /* nop. */,
+ splt->contents + splt->size - 4);
+ }
+
+ elf_section_data (splt->output_section)->this_hdr.sh_entsize = 4;
+ }
+
+ /* Set the first entry in the global offset table to the address of
+ the dynamic section. */
+ sgot = bfd_get_linker_section (dynobj, ".got.plt");
+ if (sgot && sgot->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 (htab->sgot && htab->sgot->size > 0)
+ elf_section_data (htab->sgot->output_section)->this_hdr.sh_entsize = 4;
+
+ 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 bfd_boolean
+microblaze_elf_add_symbol_hook (bfd *abfd,
+ struct bfd_link_info *info,
+ Elf_Internal_Sym *sym,
+ const char **namep ATTRIBUTE_UNUSED,
+ flagword *flagsp ATTRIBUTE_UNUSED,
+ asection **secp,
+ bfd_vma *valp)
+{
+ if (sym->st_shndx == SHN_COMMON
+ && !info->relocatable
+ && sym->st_size <= elf_gp_size (abfd))
+ {
+ /* Common symbols less than or equal to -G nn bytes are automatically
+ put into .sbss. */
+ *secp = bfd_make_section_old_way (abfd, ".sbss");
+ if (*secp == NULL
+ || ! bfd_set_section_flags (abfd, *secp, SEC_IS_COMMON))
+ return FALSE;
+
+ *valp = sym->st_size;
+ }
+
+ return TRUE;
+}
+
+#define TARGET_LITTLE_SYM microblaze_elf32_le_vec
+#define TARGET_LITTLE_NAME "elf32-microblazeel"
+
+#define TARGET_BIG_SYM microblaze_elf32_vec
+#define TARGET_BIG_NAME "elf32-microblaze"
+
+#define ELF_ARCH bfd_arch_microblaze
+#define ELF_TARGET_ID MICROBLAZE_ELF_DATA
+#define ELF_MACHINE_CODE EM_MICROBLAZE
+#define ELF_MACHINE_ALT1 EM_MICROBLAZE_OLD
+#define ELF_MAXPAGESIZE 0x1000
+#define elf_info_to_howto microblaze_elf_info_to_howto
+#define elf_info_to_howto_rel NULL
+
+#define bfd_elf32_bfd_reloc_type_lookup microblaze_elf_reloc_type_lookup
+#define bfd_elf32_bfd_is_local_label_name microblaze_elf_is_local_label_name
+#define elf_backend_relocate_section microblaze_elf_relocate_section
+#define bfd_elf32_bfd_relax_section microblaze_elf_relax_section
+#define bfd_elf32_bfd_merge_private_bfd_data microblaze_elf_merge_private_bfd_data
+#define bfd_elf32_bfd_reloc_name_lookup microblaze_elf_reloc_name_lookup
+
+#define elf_backend_gc_mark_hook microblaze_elf_gc_mark_hook
+#define elf_backend_gc_sweep_hook microblaze_elf_gc_sweep_hook
+#define elf_backend_check_relocs microblaze_elf_check_relocs
+#define elf_backend_copy_indirect_symbol microblaze_elf_copy_indirect_symbol
+#define bfd_elf32_bfd_link_hash_table_create microblaze_elf_link_hash_table_create
+#define elf_backend_can_gc_sections 1
+#define elf_backend_can_refcount 1
+#define elf_backend_want_got_plt 1
+#define elf_backend_plt_readonly 1
+#define elf_backend_got_header_size 12
+#define elf_backend_rela_normal 1
+
+#define elf_backend_adjust_dynamic_symbol microblaze_elf_adjust_dynamic_symbol
+#define elf_backend_create_dynamic_sections microblaze_elf_create_dynamic_sections
+#define elf_backend_finish_dynamic_sections microblaze_elf_finish_dynamic_sections
+#define elf_backend_finish_dynamic_symbol microblaze_elf_finish_dynamic_symbol
+#define elf_backend_size_dynamic_sections microblaze_elf_size_dynamic_sections
+#define elf_backend_add_symbol_hook microblaze_elf_add_symbol_hook
+
+#include "elf32-target.h"
diff --git a/bfd/elf32-mips.c b/bfd/elf32-mips.c
new file mode 100644
index 0000000..4cfef7a
--- /dev/null
+++ b/bfd/elf32-mips.c
@@ -0,0 +1,2624 @@
+/* MIPS-specific support for 32-bit ELF
+ Copyright (C) 1993-2014 Free Software Foundation, Inc.
+
+ Most of the information added by Ian Lance Taylor, Cygnus Support,
+ <ian@cygnus.com>.
+ N32/64 ABI support added by Mark Mitchell, CodeSourcery, LLC.
+ <mark@codesourcery.com>
+ Traditional MIPS targets support added by Koundinya.K, Dansk Data
+ Elektronik & Operations Research Group. <kk@ddeorg.soft.net>
+
+ This file is part of BFD, the Binary File Descriptor library.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, 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 "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+#include "bfdlink.h"
+#include "genlink.h"
+#include "elf-bfd.h"
+#include "elfxx-mips.h"
+#include "elf/mips.h"
+#include "elf-vxworks.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_SIGNED_32
+#include "ecoffswap.h"
+
+static bfd_reloc_status_type gprel32_with_gp
+ (bfd *, asymbol *, arelent *, asection *, bfd_boolean, void *, bfd_vma);
+static bfd_reloc_status_type mips_elf_gprel32_reloc
+ (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
+static bfd_reloc_status_type mips32_64bit_reloc
+ (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
+static reloc_howto_type *bfd_elf32_bfd_reloc_type_lookup
+ (bfd *, bfd_reloc_code_real_type);
+static reloc_howto_type *mips_elf32_rtype_to_howto
+ (unsigned int, bfd_boolean);
+static void mips_info_to_howto_rel
+ (bfd *, arelent *, Elf_Internal_Rela *);
+static void mips_info_to_howto_rela
+ (bfd *, arelent *, Elf_Internal_Rela *);
+static bfd_boolean mips_elf_sym_is_global
+ (bfd *, asymbol *);
+static bfd_boolean mips_elf32_object_p
+ (bfd *);
+static bfd_boolean mips_elf_is_local_label_name
+ (bfd *, const char *);
+static bfd_reloc_status_type mips16_gprel_reloc
+ (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
+static bfd_reloc_status_type mips_elf_final_gp
+ (bfd *, asymbol *, bfd_boolean, char **, bfd_vma *);
+static bfd_boolean mips_elf_assign_gp
+ (bfd *, bfd_vma *);
+static bfd_boolean elf32_mips_grok_prstatus
+ (bfd *, Elf_Internal_Note *);
+static bfd_boolean elf32_mips_grok_psinfo
+ (bfd *, Elf_Internal_Note *);
+static irix_compat_t elf32_mips_irix_compat
+ (bfd *);
+
+extern const bfd_target mips_elf32_be_vec;
+extern const bfd_target mips_elf32_le_vec;
+
+/* Nonzero if ABFD is using the N32 ABI. */
+#define ABI_N32_P(abfd) \
+ ((elf_elfheader (abfd)->e_flags & EF_MIPS_ABI2) != 0)
+
+/* Whether we are trying to be compatible with IRIX at all. */
+#define SGI_COMPAT(abfd) \
+ (elf32_mips_irix_compat (abfd) != ict_none)
+
+/* The number of local .got entries we reserve. */
+#define MIPS_RESERVED_GOTNO (2)
+
+/* 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 elf_mips_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_mips_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 */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_16", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* 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_dont, /* complain_on_overflow */
+ _bfd_mips_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_dont, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_REL32", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* 26 bit jump 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 + 4. */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_26", /* name */
+ TRUE, /* partial_inplace */
+ 0x03ffffff, /* src_mask */
+ 0x03ffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* High 16 bits of symbol value. */
+ HOWTO (R_MIPS_HI16, /* type */
+ 16, /* 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 */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* 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 */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* 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_elf32_gprel16_reloc, /* special_function */
+ "R_MIPS_GPREL16", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* 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_elf32_gprel16_reloc, /* special_function */
+ "R_MIPS_LITERAL", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* 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 */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* 16 bit PC relative reference. Note that the ABI document has a typo
+ and claims R_MIPS_PC16 to be not rightshifted, rendering it useless.
+ We do the right thing here. */
+ HOWTO (R_MIPS_PC16, /* 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_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_PC16", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* 16 bit call through global offset table. */
+ 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_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_CALL16", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* 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_dont, /* complain_on_overflow */
+ 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. */
+ EMPTY_HOWTO (13),
+ EMPTY_HOWTO (14),
+ EMPTY_HOWTO (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_mips_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_mips_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. */
+ HOWTO (R_MIPS_64, /* type */
+ 0, /* rightshift */
+ 4, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ mips32_64bit_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. */
+ 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_signed, /* complain_on_overflow */
+ _bfd_mips_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. */
+ 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_signed, /* complain_on_overflow */
+ _bfd_mips_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. */
+ 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_signed, /* complain_on_overflow */
+ _bfd_mips_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. */
+ 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_mips_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. */
+ 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_mips_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. Used in the N32 ABI. */
+ HOWTO (R_MIPS_SUB, /* type */
+ 0, /* rightshift */
+ 4, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_SUB", /* name */
+ TRUE, /* partial_inplace */
+ MINUS_ONE, /* src_mask */
+ MINUS_ONE, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Used to cause the linker to insert and delete instructions? */
+ EMPTY_HOWTO (R_MIPS_INSERT_A),
+ EMPTY_HOWTO (R_MIPS_INSERT_B),
+ EMPTY_HOWTO (R_MIPS_DELETE),
+
+ /* Get the higher value of a 64 bit addend. */
+ 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_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_HIGHER", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Get the highest value of a 64 bit addend. */
+ 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_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_HIGHEST", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* High 16 bits of displacement in global offset table. */
+ 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_mips_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. */
+ 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_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_CALL_LO16", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Section displacement. */
+ HOWTO (R_MIPS_SCN_DISP, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_SCN_DISP", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ EMPTY_HOWTO (R_MIPS_REL16),
+ EMPTY_HOWTO (R_MIPS_ADD_IMMEDIATE),
+ EMPTY_HOWTO (R_MIPS_PJUMP),
+ EMPTY_HOWTO (R_MIPS_RELGOT),
+
+ /* Protected jump conversion. This is an optimization hint. No
+ relocation is required for correctness. */
+ HOWTO (R_MIPS_JALR, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_JALR", /* name */
+ FALSE, /* partial_inplace */
+ 0x00000000, /* src_mask */
+ 0x00000000, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* TLS GD/LD dynamic relocations. */
+ HOWTO (R_MIPS_TLS_DTPMOD32, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_TLS_DTPMOD32", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_MIPS_TLS_DTPREL32, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_TLS_DTPREL32", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ EMPTY_HOWTO (R_MIPS_TLS_DTPMOD64),
+ EMPTY_HOWTO (R_MIPS_TLS_DTPREL64),
+
+ /* TLS general dynamic variable reference. */
+ HOWTO (R_MIPS_TLS_GD, /* 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_generic_reloc, /* special_function */
+ "R_MIPS_TLS_GD", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* TLS local dynamic variable reference. */
+ HOWTO (R_MIPS_TLS_LDM, /* 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_generic_reloc, /* special_function */
+ "R_MIPS_TLS_LDM", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* TLS local dynamic offset. */
+ HOWTO (R_MIPS_TLS_DTPREL_HI16, /* 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_generic_reloc, /* special_function */
+ "R_MIPS_TLS_DTPREL_HI16", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* TLS local dynamic offset. */
+ HOWTO (R_MIPS_TLS_DTPREL_LO16, /* 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_generic_reloc, /* special_function */
+ "R_MIPS_TLS_DTPREL_LO16", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* TLS thread pointer offset. */
+ HOWTO (R_MIPS_TLS_GOTTPREL, /* 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_generic_reloc, /* special_function */
+ "R_MIPS_TLS_GOTTPREL", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* TLS IE dynamic relocations. */
+ HOWTO (R_MIPS_TLS_TPREL32, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_TLS_TPREL32", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ EMPTY_HOWTO (R_MIPS_TLS_TPREL64),
+
+ /* TLS thread pointer offset. */
+ HOWTO (R_MIPS_TLS_TPREL_HI16, /* 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_generic_reloc, /* special_function */
+ "R_MIPS_TLS_TPREL_HI16", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* TLS thread pointer offset. */
+ HOWTO (R_MIPS_TLS_TPREL_LO16, /* 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_generic_reloc, /* special_function */
+ "R_MIPS_TLS_TPREL_LO16", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* 32 bit relocation with no addend. */
+ HOWTO (R_MIPS_GLOB_DAT, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_GLOB_DAT", /* name */
+ FALSE, /* partial_inplace */
+ 0x0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ EMPTY_HOWTO (52),
+ EMPTY_HOWTO (53),
+ EMPTY_HOWTO (54),
+ EMPTY_HOWTO (55),
+ EMPTY_HOWTO (56),
+ EMPTY_HOWTO (57),
+ EMPTY_HOWTO (58),
+ EMPTY_HOWTO (59),
+
+ HOWTO (R_MIPS_PC21_S2, /* type */
+ 2, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 21, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_PC21_S2", /* name */
+ TRUE, /* partial_inplace */
+ 0x001fffff, /* src_mask */
+ 0x001fffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_MIPS_PC26_S2, /* 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_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_PC26_S2", /* name */
+ TRUE, /* partial_inplace */
+ 0x03ffffff, /* src_mask */
+ 0x03ffffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_MIPS_PC18_S3, /* 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_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_PC18_S3", /* name */
+ TRUE, /* partial_inplace */
+ 0x0003ffff, /* src_mask */
+ 0x0003ffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_MIPS_PC19_S2, /* type */
+ 2, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 19, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_PC19_S2", /* name */
+ TRUE, /* partial_inplace */
+ 0x0007ffff, /* src_mask */
+ 0x0007ffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_MIPS_PCHI16, /* type */
+ 16, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_PCHI16", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_MIPS_PCLO16, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_PCLO16", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+};
+
+/* 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 */
+
+static reloc_howto_type elf_mips16_howto_table_rel[] =
+{
+ /* The reloc used for the mips16 jump instruction. */
+ 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. */
+ _bfd_mips_elf_generic_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. */
+ 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 */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A MIPS16 reference to the global offset table. */
+ HOWTO (R_MIPS16_GOT16, /* 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_got16_reloc, /* special_function */
+ "R_MIPS16_GOT16", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A MIPS16 call through the global offset table. */
+ HOWTO (R_MIPS16_CALL16, /* 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_generic_reloc, /* special_function */
+ "R_MIPS16_CALL16", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* MIPS16 high 16 bits of symbol value. */
+ HOWTO (R_MIPS16_HI16, /* type */
+ 16, /* 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_MIPS16_HI16", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* MIPS16 low 16 bits of symbol value. */
+ HOWTO (R_MIPS16_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_MIPS16_LO16", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* MIPS16 TLS general dynamic variable reference. */
+ HOWTO (R_MIPS16_TLS_GD, /* 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_generic_reloc, /* special_function */
+ "R_MIPS16_TLS_GD", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* MIPS16 TLS local dynamic variable reference. */
+ HOWTO (R_MIPS16_TLS_LDM, /* 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_generic_reloc, /* special_function */
+ "R_MIPS16_TLS_LDM", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* MIPS16 TLS local dynamic offset. */
+ HOWTO (R_MIPS16_TLS_DTPREL_HI16, /* 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_generic_reloc, /* special_function */
+ "R_MIPS16_TLS_DTPREL_HI16", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* MIPS16 TLS local dynamic offset. */
+ HOWTO (R_MIPS16_TLS_DTPREL_LO16, /* 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_generic_reloc, /* special_function */
+ "R_MIPS16_TLS_DTPREL_LO16", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* MIPS16 TLS thread pointer offset. */
+ HOWTO (R_MIPS16_TLS_GOTTPREL, /* 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_generic_reloc, /* special_function */
+ "R_MIPS16_TLS_GOTTPREL", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* MIPS16 TLS thread pointer offset. */
+ HOWTO (R_MIPS16_TLS_TPREL_HI16, /* 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_generic_reloc, /* special_function */
+ "R_MIPS16_TLS_TPREL_HI16", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* MIPS16 TLS thread pointer offset. */
+ HOWTO (R_MIPS16_TLS_TPREL_LO16, /* 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_generic_reloc, /* special_function */
+ "R_MIPS16_TLS_TPREL_LO16", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+};
+
+static reloc_howto_type elf_micromips_howto_table_rel[] =
+{
+ EMPTY_HOWTO (130),
+ EMPTY_HOWTO (131),
+ EMPTY_HOWTO (132),
+
+ /* 26 bit jump address. */
+ HOWTO (R_MICROMIPS_26_S1, /* type */
+ 1, /* 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_mips_elf_generic_reloc, /* special_function */
+ "R_MICROMIPS_26_S1", /* name */
+ TRUE, /* partial_inplace */
+ 0x3ffffff, /* src_mask */
+ 0x3ffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* High 16 bits of symbol value. */
+ HOWTO (R_MICROMIPS_HI16, /* type */
+ 16, /* 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_MICROMIPS_HI16", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Low 16 bits of symbol value. */
+ HOWTO (R_MICROMIPS_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_MICROMIPS_LO16", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* GP relative reference. */
+ HOWTO (R_MICROMIPS_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_elf32_gprel16_reloc, /* special_function */
+ "R_MICROMIPS_GPREL16", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Reference to literal section. */
+ HOWTO (R_MICROMIPS_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_elf32_gprel16_reloc, /* special_function */
+ "R_MICROMIPS_LITERAL", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Reference to global offset table. */
+ HOWTO (R_MICROMIPS_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_MICROMIPS_GOT16", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* This is for microMIPS branches. */
+ HOWTO (R_MICROMIPS_PC7_S1, /* type */
+ 1, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 7, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MICROMIPS_PC7_S1", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000007f, /* src_mask */
+ 0x0000007f, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_MICROMIPS_PC10_S1, /* type */
+ 1, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 10, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MICROMIPS_PC10_S1", /* name */
+ TRUE, /* partial_inplace */
+ 0x000003ff, /* src_mask */
+ 0x000003ff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_MICROMIPS_PC16_S1, /* type */
+ 1, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MICROMIPS_PC16_S1", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* 16 bit call through global offset table. */
+ HOWTO (R_MICROMIPS_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_mips_elf_generic_reloc, /* special_function */
+ "R_MICROMIPS_CALL16", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ EMPTY_HOWTO (143),
+ EMPTY_HOWTO (144),
+
+ /* Displacement in the global offset table. */
+ HOWTO (R_MICROMIPS_GOT_DISP, /* 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_generic_reloc, /* special_function */
+ "R_MICROMIPS_GOT_DISP",/* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Displacement to page pointer in the global offset table. */
+ HOWTO (R_MICROMIPS_GOT_PAGE, /* 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_generic_reloc, /* special_function */
+ "R_MICROMIPS_GOT_PAGE",/* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Offset from page pointer in the global offset table. */
+ HOWTO (R_MICROMIPS_GOT_OFST, /* 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_generic_reloc, /* special_function */
+ "R_MICROMIPS_GOT_OFST",/* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* High 16 bits of displacement in global offset table. */
+ HOWTO (R_MICROMIPS_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_mips_elf_generic_reloc, /* special_function */
+ "R_MICROMIPS_GOT_HI16",/* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Low 16 bits of displacement in global offset table. */
+ HOWTO (R_MICROMIPS_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_mips_elf_generic_reloc, /* special_function */
+ "R_MICROMIPS_GOT_LO16",/* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* 64 bit subtraction. Used in the N32 ABI. */
+ HOWTO (R_MICROMIPS_SUB, /* type */
+ 0, /* rightshift */
+ 4, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MICROMIPS_SUB", /* name */
+ TRUE, /* partial_inplace */
+ MINUS_ONE, /* src_mask */
+ MINUS_ONE, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Get the higher value of a 64 bit addend. */
+ HOWTO (R_MICROMIPS_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_mips_elf_generic_reloc, /* special_function */
+ "R_MICROMIPS_HIGHER", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Get the highest value of a 64 bit addend. */
+ HOWTO (R_MICROMIPS_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_mips_elf_generic_reloc, /* special_function */
+ "R_MICROMIPS_HIGHEST", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* High 16 bits of displacement in global offset table. */
+ HOWTO (R_MICROMIPS_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_mips_elf_generic_reloc, /* special_function */
+ "R_MICROMIPS_CALL_HI16",/* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Low 16 bits of displacement in global offset table. */
+ HOWTO (R_MICROMIPS_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_mips_elf_generic_reloc, /* special_function */
+ "R_MICROMIPS_CALL_LO16",/* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Section displacement. */
+ HOWTO (R_MICROMIPS_SCN_DISP, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MICROMIPS_SCN_DISP",/* name */
+ TRUE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Protected jump conversion. This is an optimization hint. No
+ relocation is required for correctness. */
+ HOWTO (R_MICROMIPS_JALR, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MICROMIPS_JALR", /* name */
+ FALSE, /* partial_inplace */
+ 0x00000000, /* src_mask */
+ 0x00000000, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Low 16 bits of symbol value. Note that the high 16 bits of symbol values
+ must be zero. This is used for relaxation. */
+ HOWTO (R_MICROMIPS_HI0_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_generic_reloc, /* special_function */
+ "R_MICROMIPS_HI0_LO16",/* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ EMPTY_HOWTO (158),
+ EMPTY_HOWTO (159),
+ EMPTY_HOWTO (160),
+ EMPTY_HOWTO (161),
+
+ /* TLS general dynamic variable reference. */
+ HOWTO (R_MICROMIPS_TLS_GD, /* 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_generic_reloc, /* special_function */
+ "R_MICROMIPS_TLS_GD", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* TLS local dynamic variable reference. */
+ HOWTO (R_MICROMIPS_TLS_LDM, /* 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_generic_reloc, /* special_function */
+ "R_MICROMIPS_TLS_LDM", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* TLS local dynamic offset. */
+ HOWTO (R_MICROMIPS_TLS_DTPREL_HI16, /* 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_generic_reloc, /* special_function */
+ "R_MICROMIPS_TLS_DTPREL_HI16", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* TLS local dynamic offset. */
+ HOWTO (R_MICROMIPS_TLS_DTPREL_LO16, /* 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_generic_reloc, /* special_function */
+ "R_MICROMIPS_TLS_DTPREL_LO16", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* TLS thread pointer offset. */
+ HOWTO (R_MICROMIPS_TLS_GOTTPREL, /* 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_generic_reloc, /* special_function */
+ "R_MICROMIPS_TLS_GOTTPREL", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ EMPTY_HOWTO (167),
+ EMPTY_HOWTO (168),
+
+ /* TLS thread pointer offset. */
+ HOWTO (R_MICROMIPS_TLS_TPREL_HI16, /* 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_generic_reloc, /* special_function */
+ "R_MICROMIPS_TLS_TPREL_HI16", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* TLS thread pointer offset. */
+ HOWTO (R_MICROMIPS_TLS_TPREL_LO16, /* 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_generic_reloc, /* special_function */
+ "R_MICROMIPS_TLS_TPREL_LO16", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ EMPTY_HOWTO (171),
+
+ /* GP- and PC-relative relocations. */
+ HOWTO (R_MICROMIPS_GPREL7_S2, /* type */
+ 2, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 7, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ _bfd_mips_elf32_gprel16_reloc, /* special_function */
+ "R_MICROMIPS_GPREL7_S2", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000007f, /* src_mask */
+ 0x0000007f, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_MICROMIPS_PC23_S2, /* type */
+ 2, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 23, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MICROMIPS_PC23_S2", /* name */
+ TRUE, /* partial_inplace */
+ 0x007fffff, /* src_mask */
+ 0x007fffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+};
+
+/* 16 bit offset for pc-relative branches. */
+static reloc_howto_type elf_mips_gnu_rel16_s2 =
+ HOWTO (R_MIPS_GNU_REL16_S2, /* 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_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_GNU_REL16_S2", /* name */
+ TRUE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ TRUE); /* pcrel_offset */
+
+/* 32 bit pc-relative. This was a GNU extension used by embedded-PIC.
+ It was co-opted by mips-linux for exception-handling data. It is no
+ longer used, but should continue to be supported by the linker for
+ backward compatibility. (GCC stopped using it in May, 2004.) */
+static reloc_howto_type elf_mips_gnu_pcrel32 =
+ HOWTO (R_MIPS_PC32, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_PC32", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ TRUE); /* 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 */
+
+/* Originally a VxWorks extension, but now used for other systems too. */
+static reloc_howto_type elf_mips_copy_howto =
+ HOWTO (R_MIPS_COPY, /* type */
+ 0, /* rightshift */
+ 0, /* this one is variable size */
+ 0, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_COPY", /* name */
+ FALSE, /* partial_inplace */
+ 0x0, /* src_mask */
+ 0x0, /* dst_mask */
+ FALSE); /* pcrel_offset */
+
+/* Originally a VxWorks extension, but now used for other systems too. */
+static reloc_howto_type elf_mips_jump_slot_howto =
+ HOWTO (R_MIPS_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_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_JUMP_SLOT", /* name */
+ FALSE, /* partial_inplace */
+ 0x0, /* src_mask */
+ 0x0, /* dst_mask */
+ FALSE); /* pcrel_offset */
+
+/* Used in EH tables. */
+static reloc_howto_type elf_mips_eh_howto =
+ HOWTO (R_MIPS_EH, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_EH", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE); /* pcrel_offset */
+
+/* Set the GP value for OUTPUT_BFD. Returns FALSE if this is a
+ dangerous relocation. */
+
+static bfd_boolean
+mips_elf_assign_gp (bfd *output_bfd, bfd_vma *pgp)
+{
+ unsigned int count;
+ asymbol **sym;
+ unsigned int i;
+
+ /* If we've already figured out what GP will be, just return it. */
+ *pgp = _bfd_get_gp_value (output_bfd);
+ if (*pgp)
+ return TRUE;
+
+ count = bfd_get_symcount (output_bfd);
+ sym = bfd_get_outsymbols (output_bfd);
+
+ /* The linker script will have created a symbol named `_gp' with the
+ appropriate value. */
+ if (sym == 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);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/* 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 relocatable output. */
+
+static bfd_reloc_status_type
+mips_elf_final_gp (bfd *output_bfd, asymbol *symbol, bfd_boolean relocatable,
+ char **error_message, bfd_vma *pgp)
+{
+ if (bfd_is_und_section (symbol->section)
+ && ! relocatable)
+ {
+ *pgp = 0;
+ return bfd_reloc_undefined;
+ }
+
+ *pgp = _bfd_get_gp_value (output_bfd);
+ if (*pgp == 0
+ && (! relocatable
+ || (symbol->flags & BSF_SECTION_SYM) != 0))
+ {
+ if (relocatable)
+ {
+ /* Make up a value. */
+ *pgp = symbol->section->output_section->vma /*+ 0x4000*/;
+ _bfd_set_gp_value (output_bfd, *pgp);
+ }
+ else if (!mips_elf_assign_gp (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. */
+
+bfd_reloc_status_type
+_bfd_mips_elf32_gprel16_reloc (bfd *abfd, arelent *reloc_entry,
+ asymbol *symbol, void *data,
+ asection *input_section, bfd *output_bfd,
+ char **error_message)
+{
+ bfd_boolean relocatable;
+ bfd_reloc_status_type ret;
+ bfd_byte *location;
+ bfd_vma gp;
+
+ /* R_MIPS_LITERAL/R_MICROMIPS_LITERAL relocations are defined for local
+ symbols only. */
+ if (literal_reloc_p (reloc_entry->howto->type)
+ && output_bfd != NULL
+ && (symbol->flags & BSF_SECTION_SYM) == 0
+ && (symbol->flags & BSF_LOCAL) != 0)
+ {
+ *error_message = (char *)
+ _("literal relocation occurs for an external symbol");
+ return bfd_reloc_outofrange;
+ }
+
+ if (output_bfd != NULL)
+ relocatable = TRUE;
+ else
+ {
+ relocatable = FALSE;
+ output_bfd = symbol->section->output_section->owner;
+ }
+
+ ret = mips_elf_final_gp (output_bfd, symbol, relocatable, error_message,
+ &gp);
+ if (ret != bfd_reloc_ok)
+ return ret;
+
+ location = (bfd_byte *) data + reloc_entry->address;
+ _bfd_mips_elf_reloc_unshuffle (abfd, reloc_entry->howto->type, FALSE,
+ location);
+ ret = _bfd_mips_elf_gprel16_with_gp (abfd, symbol, reloc_entry,
+ input_section, relocatable,
+ data, gp);
+ _bfd_mips_elf_reloc_shuffle (abfd, reloc_entry->howto->type, !relocatable,
+ location);
+
+ return ret;
+}
+
+/* Do a R_MIPS_GPREL32 relocation. This is a 32 bit value which must
+ become the offset from the gp register. */
+
+static bfd_reloc_status_type
+mips_elf_gprel32_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
+ void *data, asection *input_section, bfd *output_bfd,
+ char **error_message)
+{
+ bfd_boolean relocatable;
+ bfd_reloc_status_type ret;
+ bfd_vma gp;
+
+ /* R_MIPS_GPREL32 relocations are defined for local symbols only. */
+ if (output_bfd != NULL
+ && (symbol->flags & BSF_SECTION_SYM) == 0
+ && (symbol->flags & BSF_LOCAL) != 0)
+ {
+ *error_message = (char *)
+ _("32bits gp relative relocation occurs for an external symbol");
+ return bfd_reloc_outofrange;
+ }
+
+ if (output_bfd != NULL)
+ relocatable = TRUE;
+ else
+ {
+ relocatable = FALSE;
+ output_bfd = symbol->section->output_section->owner;
+ }
+
+ ret = mips_elf_final_gp (output_bfd, symbol, relocatable,
+ error_message, &gp);
+ if (ret != bfd_reloc_ok)
+ return ret;
+
+ return gprel32_with_gp (abfd, symbol, reloc_entry, input_section,
+ relocatable, data, gp);
+}
+
+static bfd_reloc_status_type
+gprel32_with_gp (bfd *abfd, asymbol *symbol, arelent *reloc_entry,
+ asection *input_section, bfd_boolean relocatable,
+ void *data, bfd_vma gp)
+{
+ bfd_vma relocation;
+ bfd_vma 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 > bfd_get_section_limit (abfd, input_section))
+ return bfd_reloc_outofrange;
+
+ /* Set val to the offset into the section or symbol. */
+ val = reloc_entry->addend;
+
+ if (reloc_entry->howto->partial_inplace)
+ val += bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
+
+ /* Adjust val for the final section location and GP value. If we
+ are producing relocatable output, we don't want to do this for
+ an external symbol. */
+ if (! relocatable
+ || (symbol->flags & BSF_SECTION_SYM) != 0)
+ val += relocation - gp;
+
+ if (reloc_entry->howto->partial_inplace)
+ bfd_put_32 (abfd, val, (bfd_byte *) data + reloc_entry->address);
+ else
+ reloc_entry->addend = val;
+
+ if (relocatable)
+ 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 addresses are 64 bits. The upper 32 bits are a simple
+ sign extension. */
+
+static bfd_reloc_status_type
+mips32_64bit_reloc (bfd *abfd, arelent *reloc_entry,
+ asymbol *symbol ATTRIBUTE_UNUSED,
+ void *data, asection *input_section,
+ bfd *output_bfd, char **error_message)
+{
+ bfd_reloc_status_type r;
+ arelent reloc32;
+ unsigned long val;
+ bfd_size_type addr;
+
+ /* 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_rel[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 GP relative reloc. */
+
+static bfd_reloc_status_type
+mips16_gprel_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
+ void *data, asection *input_section, bfd *output_bfd,
+ char **error_message)
+{
+ bfd_boolean relocatable;
+ bfd_reloc_status_type ret;
+ bfd_byte *location;
+ bfd_vma gp;
+
+ /* If we're relocating, and this is an external symbol, we don't want
+ to change anything. */
+ if (output_bfd != NULL
+ && (symbol->flags & BSF_SECTION_SYM) == 0
+ && (symbol->flags & BSF_LOCAL) != 0)
+ {
+ reloc_entry->address += input_section->output_offset;
+ return bfd_reloc_ok;
+ }
+
+ if (output_bfd != NULL)
+ relocatable = TRUE;
+ else
+ {
+ relocatable = FALSE;
+ output_bfd = symbol->section->output_section->owner;
+ }
+
+ ret = mips_elf_final_gp (output_bfd, symbol, relocatable, error_message,
+ &gp);
+ if (ret != bfd_reloc_ok)
+ return ret;
+
+ location = (bfd_byte *) data + reloc_entry->address;
+ _bfd_mips_elf_reloc_unshuffle (abfd, reloc_entry->howto->type, FALSE,
+ location);
+ ret = _bfd_mips_elf_gprel16_with_gp (abfd, symbol, reloc_entry,
+ input_section, relocatable,
+ data, gp);
+ _bfd_mips_elf_reloc_shuffle (abfd, reloc_entry->howto->type, !relocatable,
+ location);
+
+ return ret;
+}
+
+/* A mapping from BFD reloc types to MIPS ELF reloc types. */
+
+struct elf_reloc_map {
+ bfd_reloc_code_real_type bfd_val;
+ enum elf_mips_reloc_type elf_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 },
+ /* There is no BFD reloc for R_MIPS_REL32. */
+ { 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_GPREL16, R_MIPS_GPREL16 },
+ { BFD_RELOC_MIPS_LITERAL, R_MIPS_LITERAL },
+ { BFD_RELOC_MIPS_GOT16, R_MIPS_GOT16 },
+ { BFD_RELOC_16_PCREL_S2, R_MIPS_PC16 },
+ { BFD_RELOC_MIPS_CALL16, R_MIPS_CALL16 },
+ { BFD_RELOC_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 },
+ { BFD_RELOC_MIPS_SUB, R_MIPS_SUB },
+ { BFD_RELOC_MIPS_GOT_PAGE, R_MIPS_GOT_PAGE },
+ { BFD_RELOC_MIPS_GOT_OFST, R_MIPS_GOT_OFST },
+ { BFD_RELOC_MIPS_GOT_DISP, R_MIPS_GOT_DISP },
+ { BFD_RELOC_MIPS_JALR, R_MIPS_JALR },
+ { BFD_RELOC_MIPS_TLS_DTPMOD32, R_MIPS_TLS_DTPMOD32 },
+ { BFD_RELOC_MIPS_TLS_DTPREL32, R_MIPS_TLS_DTPREL32 },
+ { BFD_RELOC_MIPS_TLS_DTPMOD64, R_MIPS_TLS_DTPMOD64 },
+ { BFD_RELOC_MIPS_TLS_DTPREL64, R_MIPS_TLS_DTPREL64 },
+ { BFD_RELOC_MIPS_TLS_GD, R_MIPS_TLS_GD },
+ { BFD_RELOC_MIPS_TLS_LDM, R_MIPS_TLS_LDM },
+ { BFD_RELOC_MIPS_TLS_DTPREL_HI16, R_MIPS_TLS_DTPREL_HI16 },
+ { BFD_RELOC_MIPS_TLS_DTPREL_LO16, R_MIPS_TLS_DTPREL_LO16 },
+ { BFD_RELOC_MIPS_TLS_GOTTPREL, R_MIPS_TLS_GOTTPREL },
+ { BFD_RELOC_MIPS_TLS_TPREL32, R_MIPS_TLS_TPREL32 },
+ { BFD_RELOC_MIPS_TLS_TPREL64, R_MIPS_TLS_TPREL64 },
+ { BFD_RELOC_MIPS_TLS_TPREL_HI16, R_MIPS_TLS_TPREL_HI16 },
+ { BFD_RELOC_MIPS_TLS_TPREL_LO16, R_MIPS_TLS_TPREL_LO16 },
+ { BFD_RELOC_MIPS_21_PCREL_S2, R_MIPS_PC21_S2 },
+ { BFD_RELOC_MIPS_26_PCREL_S2, R_MIPS_PC26_S2 },
+ { BFD_RELOC_MIPS_18_PCREL_S3, R_MIPS_PC18_S3 },
+ { BFD_RELOC_MIPS_19_PCREL_S2, R_MIPS_PC19_S2 },
+ { BFD_RELOC_HI16_S_PCREL, R_MIPS_PCHI16 },
+ { BFD_RELOC_LO16_PCREL, R_MIPS_PCLO16 }
+};
+
+static const struct elf_reloc_map mips16_reloc_map[] =
+{
+ { BFD_RELOC_MIPS16_JMP, R_MIPS16_26 - R_MIPS16_min },
+ { BFD_RELOC_MIPS16_GPREL, R_MIPS16_GPREL - R_MIPS16_min },
+ { BFD_RELOC_MIPS16_GOT16, R_MIPS16_GOT16 - R_MIPS16_min },
+ { BFD_RELOC_MIPS16_CALL16, R_MIPS16_CALL16 - R_MIPS16_min },
+ { BFD_RELOC_MIPS16_HI16_S, R_MIPS16_HI16 - R_MIPS16_min },
+ { BFD_RELOC_MIPS16_LO16, R_MIPS16_LO16 - R_MIPS16_min },
+ { BFD_RELOC_MIPS16_TLS_GD, R_MIPS16_TLS_GD - R_MIPS16_min },
+ { BFD_RELOC_MIPS16_TLS_LDM, R_MIPS16_TLS_LDM - R_MIPS16_min },
+ { BFD_RELOC_MIPS16_TLS_DTPREL_HI16,
+ R_MIPS16_TLS_DTPREL_HI16 - R_MIPS16_min },
+ { BFD_RELOC_MIPS16_TLS_DTPREL_LO16,
+ R_MIPS16_TLS_DTPREL_LO16 - R_MIPS16_min },
+ { BFD_RELOC_MIPS16_TLS_GOTTPREL, R_MIPS16_TLS_GOTTPREL - R_MIPS16_min },
+ { BFD_RELOC_MIPS16_TLS_TPREL_HI16, R_MIPS16_TLS_TPREL_HI16 - R_MIPS16_min },
+ { BFD_RELOC_MIPS16_TLS_TPREL_LO16, R_MIPS16_TLS_TPREL_LO16 - R_MIPS16_min }
+};
+
+static const struct elf_reloc_map micromips_reloc_map[] =
+{
+ { BFD_RELOC_MICROMIPS_JMP, R_MICROMIPS_26_S1 - R_MICROMIPS_min },
+ { BFD_RELOC_MICROMIPS_HI16_S, R_MICROMIPS_HI16 - R_MICROMIPS_min },
+ { BFD_RELOC_MICROMIPS_LO16, R_MICROMIPS_LO16 - R_MICROMIPS_min },
+ { BFD_RELOC_MICROMIPS_GPREL16, R_MICROMIPS_GPREL16 - R_MICROMIPS_min },
+ { BFD_RELOC_MICROMIPS_LITERAL, R_MICROMIPS_LITERAL - R_MICROMIPS_min },
+ { BFD_RELOC_MICROMIPS_GOT16, R_MICROMIPS_GOT16 - R_MICROMIPS_min },
+ { BFD_RELOC_MICROMIPS_7_PCREL_S1, R_MICROMIPS_PC7_S1 - R_MICROMIPS_min },
+ { BFD_RELOC_MICROMIPS_10_PCREL_S1, R_MICROMIPS_PC10_S1 - R_MICROMIPS_min },
+ { BFD_RELOC_MICROMIPS_16_PCREL_S1, R_MICROMIPS_PC16_S1 - R_MICROMIPS_min },
+ { BFD_RELOC_MICROMIPS_CALL16, R_MICROMIPS_CALL16 - R_MICROMIPS_min },
+ { BFD_RELOC_MICROMIPS_GOT_DISP, R_MICROMIPS_GOT_DISP - R_MICROMIPS_min },
+ { BFD_RELOC_MICROMIPS_GOT_PAGE, R_MICROMIPS_GOT_PAGE - R_MICROMIPS_min },
+ { BFD_RELOC_MICROMIPS_GOT_OFST, R_MICROMIPS_GOT_OFST - R_MICROMIPS_min },
+ { BFD_RELOC_MICROMIPS_GOT_HI16, R_MICROMIPS_GOT_HI16 - R_MICROMIPS_min },
+ { BFD_RELOC_MICROMIPS_GOT_LO16, R_MICROMIPS_GOT_LO16 - R_MICROMIPS_min },
+ { BFD_RELOC_MICROMIPS_SUB, R_MICROMIPS_SUB - R_MICROMIPS_min },
+ { BFD_RELOC_MICROMIPS_HIGHER, R_MICROMIPS_HIGHER - R_MICROMIPS_min },
+ { BFD_RELOC_MICROMIPS_HIGHEST, R_MICROMIPS_HIGHEST - R_MICROMIPS_min },
+ { BFD_RELOC_MICROMIPS_CALL_HI16, R_MICROMIPS_CALL_HI16 - R_MICROMIPS_min },
+ { BFD_RELOC_MICROMIPS_CALL_LO16, R_MICROMIPS_CALL_LO16 - R_MICROMIPS_min },
+ { BFD_RELOC_MICROMIPS_SCN_DISP, R_MICROMIPS_SCN_DISP - R_MICROMIPS_min },
+ { BFD_RELOC_MICROMIPS_JALR, R_MICROMIPS_JALR - R_MICROMIPS_min },
+ /* There is no BFD reloc for R_MICROMIPS_HI0_LO16. */
+ { BFD_RELOC_MICROMIPS_TLS_GD, R_MICROMIPS_TLS_GD - R_MICROMIPS_min },
+ { BFD_RELOC_MICROMIPS_TLS_LDM, R_MICROMIPS_TLS_LDM - R_MICROMIPS_min },
+ { BFD_RELOC_MICROMIPS_TLS_DTPREL_HI16,
+ R_MICROMIPS_TLS_DTPREL_HI16 - R_MICROMIPS_min },
+ { BFD_RELOC_MICROMIPS_TLS_DTPREL_LO16,
+ R_MICROMIPS_TLS_DTPREL_LO16 - R_MICROMIPS_min },
+ { BFD_RELOC_MICROMIPS_TLS_GOTTPREL,
+ R_MICROMIPS_TLS_GOTTPREL - R_MICROMIPS_min },
+ { BFD_RELOC_MICROMIPS_TLS_TPREL_HI16,
+ R_MICROMIPS_TLS_TPREL_HI16 - R_MICROMIPS_min },
+ { BFD_RELOC_MICROMIPS_TLS_TPREL_LO16,
+ R_MICROMIPS_TLS_TPREL_LO16 - R_MICROMIPS_min },
+ /* There is no BFD reloc for R_MICROMIPS_GPREL7_S2. */
+ /* There is no BFD reloc for R_MICROMIPS_PC23_S2. */
+};
+
+/* Given a BFD reloc type, return a howto structure. */
+
+static reloc_howto_type *
+bfd_elf32_bfd_reloc_type_lookup (bfd *abfd, bfd_reloc_code_real_type code)
+{
+ unsigned int i;
+ reloc_howto_type *howto_table = elf_mips_howto_table_rel;
+ reloc_howto_type *howto16_table = elf_mips16_howto_table_rel;
+ reloc_howto_type *howto_micromips_table = elf_micromips_howto_table_rel;
+
+ for (i = 0; i < sizeof (mips_reloc_map) / sizeof (struct elf_reloc_map);
+ i++)
+ {
+ if (mips_reloc_map[i].bfd_val == code)
+ return &howto_table[(int) mips_reloc_map[i].elf_val];
+ }
+
+ for (i = 0; i < sizeof (mips16_reloc_map) / sizeof (struct elf_reloc_map);
+ i++)
+ {
+ if (mips16_reloc_map[i].bfd_val == code)
+ return &howto16_table[(int) mips16_reloc_map[i].elf_val];
+ }
+
+ for (i = 0; i < sizeof (micromips_reloc_map) / sizeof (struct elf_reloc_map);
+ i++)
+ {
+ if (micromips_reloc_map[i].bfd_val == code)
+ return &howto_micromips_table[(int) micromips_reloc_map[i].elf_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 of the ABI. */
+ if ((elf_elfheader (abfd)->e_flags & (E_MIPS_ABI_O64
+ | E_MIPS_ABI_EABI64)) != 0)
+ return &elf_mips_ctor64_howto;
+ else
+ return &howto_table[(int) R_MIPS_32];
+
+ case BFD_RELOC_VTABLE_INHERIT:
+ return &elf_mips_gnu_vtinherit_howto;
+ case BFD_RELOC_VTABLE_ENTRY:
+ return &elf_mips_gnu_vtentry_howto;
+ case BFD_RELOC_32_PCREL:
+ return &elf_mips_gnu_pcrel32;
+ case BFD_RELOC_MIPS_COPY:
+ return &elf_mips_copy_howto;
+ case BFD_RELOC_MIPS_JUMP_SLOT:
+ return &elf_mips_jump_slot_howto;
+ case BFD_RELOC_MIPS_EH:
+ return &elf_mips_eh_howto;
+ }
+}
+
+static reloc_howto_type *
+bfd_elf32_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ const char *r_name)
+{
+ unsigned int i;
+
+ for (i = 0;
+ i < (sizeof (elf_mips_howto_table_rel)
+ / sizeof (elf_mips_howto_table_rel[0]));
+ i++)
+ if (elf_mips_howto_table_rel[i].name != NULL
+ && strcasecmp (elf_mips_howto_table_rel[i].name, r_name) == 0)
+ return &elf_mips_howto_table_rel[i];
+
+ for (i = 0;
+ i < (sizeof (elf_mips16_howto_table_rel)
+ / sizeof (elf_mips16_howto_table_rel[0]));
+ i++)
+ if (elf_mips16_howto_table_rel[i].name != NULL
+ && strcasecmp (elf_mips16_howto_table_rel[i].name, r_name) == 0)
+ return &elf_mips16_howto_table_rel[i];
+
+ for (i = 0;
+ i < (sizeof (elf_micromips_howto_table_rel)
+ / sizeof (elf_micromips_howto_table_rel[0]));
+ i++)
+ if (elf_micromips_howto_table_rel[i].name != NULL
+ && strcasecmp (elf_micromips_howto_table_rel[i].name, r_name) == 0)
+ return &elf_micromips_howto_table_rel[i];
+
+ if (strcasecmp (elf_mips_gnu_pcrel32.name, r_name) == 0)
+ return &elf_mips_gnu_pcrel32;
+ if (strcasecmp (elf_mips_gnu_rel16_s2.name, r_name) == 0)
+ return &elf_mips_gnu_rel16_s2;
+ if (strcasecmp (elf_mips_gnu_vtinherit_howto.name, r_name) == 0)
+ return &elf_mips_gnu_vtinherit_howto;
+ if (strcasecmp (elf_mips_gnu_vtentry_howto.name, r_name) == 0)
+ return &elf_mips_gnu_vtentry_howto;
+ if (strcasecmp (elf_mips_copy_howto.name, r_name) == 0)
+ return &elf_mips_copy_howto;
+ if (strcasecmp (elf_mips_jump_slot_howto.name, r_name) == 0)
+ return &elf_mips_jump_slot_howto;
+ if (strcasecmp (elf_mips_eh_howto.name, r_name) == 0)
+ return &elf_mips_eh_howto;
+
+ return NULL;
+}
+
+/* Given a MIPS Elf_Internal_Rel, fill in an arelent structure. */
+
+static reloc_howto_type *
+mips_elf32_rtype_to_howto (unsigned int r_type,
+ bfd_boolean rela_p ATTRIBUTE_UNUSED)
+{
+ switch (r_type)
+ {
+ case R_MIPS_GNU_VTINHERIT:
+ return &elf_mips_gnu_vtinherit_howto;
+ case R_MIPS_GNU_VTENTRY:
+ return &elf_mips_gnu_vtentry_howto;
+ case R_MIPS_GNU_REL16_S2:
+ return &elf_mips_gnu_rel16_s2;
+ case R_MIPS_PC32:
+ return &elf_mips_gnu_pcrel32;
+ case R_MIPS_COPY:
+ return &elf_mips_copy_howto;
+ case R_MIPS_JUMP_SLOT:
+ return &elf_mips_jump_slot_howto;
+ case R_MIPS_EH:
+ return &elf_mips_eh_howto;
+ default:
+ if (r_type >= R_MICROMIPS_min && r_type < R_MICROMIPS_max)
+ return &elf_micromips_howto_table_rel[r_type - R_MICROMIPS_min];
+ if (r_type >= R_MIPS16_min && r_type < R_MIPS16_max)
+ return &elf_mips16_howto_table_rel[r_type - R_MIPS16_min];
+ BFD_ASSERT (r_type < (unsigned int) R_MIPS_max);
+ return &elf_mips_howto_table_rel[r_type];
+ }
+}
+
+/* Given a MIPS Elf_Internal_Rel, fill in an arelent structure. */
+
+static void
+mips_info_to_howto_rel (bfd *abfd, arelent *cache_ptr, Elf_Internal_Rela *dst)
+{
+ const struct elf_backend_data *bed;
+ unsigned int r_type;
+
+ r_type = ELF32_R_TYPE (dst->r_info);
+ bed = get_elf_backend_data (abfd);
+ cache_ptr->howto = bed->elf_backend_mips_rtype_to_howto (r_type, FALSE);
+
+ /* 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
+ && (gprel16_reloc_p (r_type) || literal_reloc_p (r_type)))
+ cache_ptr->addend = elf_gp (abfd);
+}
+
+/* Given a MIPS Elf_Internal_Rela, fill in an arelent structure. */
+
+static void
+mips_info_to_howto_rela (bfd *abfd, arelent *cache_ptr, Elf_Internal_Rela *dst)
+{
+ mips_info_to_howto_rel (abfd, cache_ptr, dst);
+
+ /* If we ever need to do any extra processing with dst->r_addend
+ (the field omitted in an Elf_Internal_Rel) we can do it here. */
+}
+
+/* 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. */
+
+static bfd_boolean
+mips_elf_sym_is_global (bfd *abfd ATTRIBUTE_UNUSED, asymbol *sym)
+{
+ if (SGI_COMPAT (abfd))
+ return (sym->flags & BSF_SECTION_SYM) == 0;
+ else
+ return ((sym->flags & (BSF_GLOBAL | BSF_WEAK | BSF_GNU_UNIQUE)) != 0
+ || bfd_is_und_section (bfd_get_section (sym))
+ || bfd_is_com_section (bfd_get_section (sym)));
+}
+
+/* Set the right machine number for a MIPS ELF file. */
+
+static bfd_boolean
+mips_elf32_object_p (bfd *abfd)
+{
+ unsigned long mach;
+
+ if (ABI_N32_P (abfd))
+ return FALSE;
+
+ /* Irix 5 and 6 are 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. */
+ if (SGI_COMPAT (abfd))
+ elf_bad_symtab (abfd) = TRUE;
+
+ mach = _bfd_elf_mips_mach (elf_elfheader (abfd)->e_flags);
+ bfd_default_set_arch_mach (abfd, bfd_arch_mips, mach);
+ return TRUE;
+}
+
+/* MIPS ELF local labels start with '$', not 'L'. */
+
+static bfd_boolean
+mips_elf_is_local_label_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);
+}
+
+/* Support for core dump NOTE sections. */
+static bfd_boolean
+elf32_mips_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
+{
+ int offset;
+ unsigned int size;
+
+ switch (note->descsz)
+ {
+ default:
+ return FALSE;
+
+ case 256: /* Linux/MIPS */
+ /* pr_cursig */
+ elf_tdata (abfd)->core->signal = bfd_get_16 (abfd, note->descdata + 12);
+
+ /* pr_pid */
+ elf_tdata (abfd)->core->lwpid = bfd_get_32 (abfd, note->descdata + 24);
+
+ /* pr_reg */
+ offset = 72;
+ size = 180;
+
+ break;
+ }
+
+ /* Make a ".reg/999" section. */
+ return _bfd_elfcore_make_pseudosection (abfd, ".reg",
+ size, note->descpos + offset);
+}
+
+static bfd_boolean
+elf32_mips_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
+{
+ switch (note->descsz)
+ {
+ default:
+ return FALSE;
+
+ case 128: /* Linux/MIPS elf_prpsinfo */
+ elf_tdata (abfd)->core->program
+ = _bfd_elfcore_strndup (abfd, note->descdata + 32, 16);
+ elf_tdata (abfd)->core->command
+ = _bfd_elfcore_strndup (abfd, note->descdata + 48, 80);
+ }
+
+ /* 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;
+}
+
+/* Depending on the target vector we generate some version of Irix
+ executables or "normal" MIPS ELF ABI executables. */
+static irix_compat_t
+elf32_mips_irix_compat (bfd *abfd)
+{
+ if ((abfd->xvec == &mips_elf32_be_vec)
+ || (abfd->xvec == &mips_elf32_le_vec))
+ return ict_irix5;
+ else
+ return ict_none;
+}
+
+/* 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 ELF_ARCH bfd_arch_mips
+#define ELF_TARGET_ID MIPS_ELF_DATA
+#define ELF_MACHINE_CODE EM_MIPS
+
+#define elf_backend_collect TRUE
+#define elf_backend_type_change_ok TRUE
+#define elf_backend_can_gc_sections TRUE
+#define elf_backend_gc_mark_extra_sections \
+ _bfd_mips_elf_gc_mark_extra_sections
+#define elf_info_to_howto mips_info_to_howto_rela
+#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_symbol_processing _bfd_mips_elf_symbol_processing
+#define elf_backend_section_processing _bfd_mips_elf_section_processing
+#define elf_backend_section_from_shdr _bfd_mips_elf_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_add_symbol_hook _bfd_mips_elf_add_symbol_hook
+#define elf_backend_link_output_symbol_hook \
+ _bfd_mips_elf_link_output_symbol_hook
+#define elf_backend_create_dynamic_sections \
+ _bfd_mips_elf_create_dynamic_sections
+#define elf_backend_check_relocs _bfd_mips_elf_check_relocs
+#define elf_backend_merge_symbol_attribute \
+ _bfd_mips_elf_merge_symbol_attribute
+#define elf_backend_get_target_dtag _bfd_mips_elf_get_target_dtag
+#define elf_backend_adjust_dynamic_symbol \
+ _bfd_mips_elf_adjust_dynamic_symbol
+#define elf_backend_always_size_sections \
+ _bfd_mips_elf_always_size_sections
+#define elf_backend_size_dynamic_sections \
+ _bfd_mips_elf_size_dynamic_sections
+#define elf_backend_init_index_section _bfd_elf_init_1_index_section
+#define elf_backend_relocate_section _bfd_mips_elf_relocate_section
+#define elf_backend_finish_dynamic_symbol \
+ _bfd_mips_elf_finish_dynamic_symbol
+#define elf_backend_finish_dynamic_sections \
+ _bfd_mips_elf_finish_dynamic_sections
+#define elf_backend_final_write_processing \
+ _bfd_mips_elf_final_write_processing
+#define elf_backend_additional_program_headers \
+ _bfd_mips_elf_additional_program_headers
+#define elf_backend_modify_segment_map _bfd_mips_elf_modify_segment_map
+#define elf_backend_gc_mark_hook _bfd_mips_elf_gc_mark_hook
+#define elf_backend_gc_sweep_hook _bfd_mips_elf_gc_sweep_hook
+#define elf_backend_copy_indirect_symbol \
+ _bfd_mips_elf_copy_indirect_symbol
+#define elf_backend_grok_prstatus elf32_mips_grok_prstatus
+#define elf_backend_grok_psinfo elf32_mips_grok_psinfo
+#define elf_backend_ecoff_debug_swap &mips_elf32_ecoff_debug_swap
+
+#define elf_backend_got_header_size (4 * MIPS_RESERVED_GOTNO)
+#define elf_backend_may_use_rel_p 1
+#define elf_backend_may_use_rela_p 0
+#define elf_backend_default_use_rela_p 0
+#define elf_backend_sign_extend_vma TRUE
+#define elf_backend_plt_readonly 1
+
+#define elf_backend_discard_info _bfd_mips_elf_discard_info
+#define elf_backend_ignore_discarded_relocs \
+ _bfd_mips_elf_ignore_discarded_relocs
+#define elf_backend_write_section _bfd_mips_elf_write_section
+#define elf_backend_mips_irix_compat elf32_mips_irix_compat
+#define elf_backend_mips_rtype_to_howto mips_elf32_rtype_to_howto
+#define bfd_elf32_bfd_is_local_label_name \
+ mips_elf_is_local_label_name
+#define bfd_elf32_bfd_is_target_special_symbol \
+ _bfd_mips_elf_is_target_special_symbol
+#define bfd_elf32_get_synthetic_symtab _bfd_mips_elf_get_synthetic_symtab
+#define bfd_elf32_find_nearest_line _bfd_mips_elf_find_nearest_line
+#define bfd_elf32_find_inliner_info _bfd_mips_elf_find_inliner_info
+#define bfd_elf32_new_section_hook _bfd_mips_elf_new_section_hook
+#define bfd_elf32_set_section_contents _bfd_mips_elf_set_section_contents
+#define bfd_elf32_bfd_get_relocated_section_contents \
+ _bfd_elf_mips_get_relocated_section_contents
+#define bfd_elf32_bfd_link_hash_table_create \
+ _bfd_mips_elf_link_hash_table_create
+#define bfd_elf32_bfd_final_link _bfd_mips_elf_final_link
+#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 bfd_elf32_bfd_relax_section _bfd_mips_elf_relax_section
+#define bfd_elf32_mkobject _bfd_mips_elf_mkobject
+
+/* Support for SGI-ish mips targets. */
+#define TARGET_LITTLE_SYM mips_elf32_le_vec
+#define TARGET_LITTLE_NAME "elf32-littlemips"
+#define TARGET_BIG_SYM mips_elf32_be_vec
+#define TARGET_BIG_NAME "elf32-bigmips"
+
+/* 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_COMMONPAGESIZE 0x1000
+
+#include "elf32-target.h"
+
+/* Support for traditional mips targets. */
+#undef TARGET_LITTLE_SYM
+#undef TARGET_LITTLE_NAME
+#undef TARGET_BIG_SYM
+#undef TARGET_BIG_NAME
+
+#undef ELF_MAXPAGESIZE
+#undef ELF_COMMONPAGESIZE
+
+#define TARGET_LITTLE_SYM mips_elf32_trad_le_vec
+#define TARGET_LITTLE_NAME "elf32-tradlittlemips"
+#define TARGET_BIG_SYM mips_elf32_trad_be_vec
+#define TARGET_BIG_NAME "elf32-tradbigmips"
+
+/* The MIPS ABI says at Page 5-1:
+ Virtual addresses and file offsets for MIPS segments are congruent
+ modulo 64 KByte (0x10000) or larger powers of 2. Because 64 KBytes
+ is the maximum page size, the files are suitable for paging
+ regardless of physical page size. */
+#define ELF_MAXPAGESIZE 0x10000
+#define ELF_COMMONPAGESIZE 0x1000
+#define elf32_bed elf32_tradbed
+
+/* Include the target file again for this target. */
+#include "elf32-target.h"
+
+/* FreeBSD support. */
+
+#undef TARGET_LITTLE_SYM
+#undef TARGET_LITTLE_NAME
+#undef TARGET_BIG_SYM
+#undef TARGET_BIG_NAME
+
+#define TARGET_LITTLE_SYM mips_elf32_tradfbsd_le_vec
+#define TARGET_LITTLE_NAME "elf32-tradlittlemips-freebsd"
+#define TARGET_BIG_SYM mips_elf32_tradfbsd_be_vec
+#define TARGET_BIG_NAME "elf32-tradbigmips-freebsd"
+
+#undef ELF_OSABI
+#define ELF_OSABI ELFOSABI_FREEBSD
+
+#undef elf32_bed
+#define elf32_bed elf32_fbsd_tradbed
+
+#include "elf32-target.h"
+/* Implement elf_backend_final_write_processing for VxWorks. */
+
+static void
+mips_vxworks_final_write_processing (bfd *abfd, bfd_boolean linker)
+{
+ _bfd_mips_elf_final_write_processing (abfd, linker);
+ elf_vxworks_final_write_processing (abfd, linker);
+}
+
+#undef TARGET_LITTLE_SYM
+#undef TARGET_LITTLE_NAME
+#undef TARGET_BIG_SYM
+#undef TARGET_BIG_NAME
+
+#undef ELF_MAXPAGESIZE
+#undef ELF_COMMONPAGESIZE
+
+#define TARGET_LITTLE_SYM mips_elf32_vxworks_le_vec
+#define TARGET_LITTLE_NAME "elf32-littlemips-vxworks"
+#define TARGET_BIG_SYM mips_elf32_vxworks_be_vec
+#define TARGET_BIG_NAME "elf32-bigmips-vxworks"
+#undef ELF_OSABI
+
+#undef elf32_bed
+#define elf32_bed elf32_mips_vxworks_bed
+
+#define ELF_MAXPAGESIZE 0x1000
+#define ELF_COMMONPAGESIZE 0x1000
+
+#undef elf_backend_want_got_plt
+#define elf_backend_want_got_plt 1
+#undef elf_backend_want_plt_sym
+#define elf_backend_want_plt_sym 1
+#undef elf_backend_may_use_rel_p
+#define elf_backend_may_use_rel_p 0
+#undef elf_backend_may_use_rela_p
+#define elf_backend_may_use_rela_p 1
+#undef elf_backend_default_use_rela_p
+#define elf_backend_default_use_rela_p 1
+#undef elf_backend_got_header_size
+#define elf_backend_got_header_size (4 * 3)
+
+#undef elf_backend_finish_dynamic_symbol
+#define elf_backend_finish_dynamic_symbol \
+ _bfd_mips_vxworks_finish_dynamic_symbol
+#undef bfd_elf32_bfd_link_hash_table_create
+#define bfd_elf32_bfd_link_hash_table_create \
+ _bfd_mips_vxworks_link_hash_table_create
+#undef elf_backend_add_symbol_hook
+#define elf_backend_add_symbol_hook \
+ elf_vxworks_add_symbol_hook
+#undef elf_backend_link_output_symbol_hook
+#define elf_backend_link_output_symbol_hook \
+ elf_vxworks_link_output_symbol_hook
+#undef elf_backend_emit_relocs
+#define elf_backend_emit_relocs \
+ elf_vxworks_emit_relocs
+#undef elf_backend_final_write_processing
+#define elf_backend_final_write_processing \
+ mips_vxworks_final_write_processing
+
+#undef elf_backend_additional_program_headers
+#undef elf_backend_modify_segment_map
+#undef elf_backend_symbol_processing
+/* NOTE: elf_backend_rela_normal is not defined for MIPS. */
+
+#undef bfd_elf32_get_synthetic_symtab
+
+#include "elf32-target.h"
diff --git a/bfd/elf32-moxie.c b/bfd/elf32-moxie.c
new file mode 100644
index 0000000..1f685b9
--- /dev/null
+++ b/bfd/elf32-moxie.c
@@ -0,0 +1,389 @@
+/* moxie-specific support for 32-bit ELF.
+ Copyright (C) 2009-2014 Free Software Foundation, Inc.
+
+ Copied from elf32-fr30.c which is..
+ Copyright (C) 1998-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+#include "elf-bfd.h"
+#include "elf/moxie.h"
+
+/* Forward declarations. */
+
+static reloc_howto_type moxie_elf_howto_table [] =
+{
+ /* This reloc does nothing. */
+ HOWTO (R_MOXIE_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_MOXIE_NONE", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A 32 bit absolute relocation. */
+ HOWTO (R_MOXIE_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_MOXIE_32", /* name */
+ FALSE, /* partial_inplace */
+ 0x00000000, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A 10 bit PC-relative relocation. */
+ HOWTO (R_MOXIE_PCREL10, /* type. */
+ 1, /* rightshift. */
+ 1, /* size (0 = byte, 1 = short, 2 = long). */
+ 10, /* bitsize. */
+ TRUE, /* pc_relative. */
+ 0, /* bitpos. */
+ complain_overflow_signed, /* complain_on_overflow. */
+ bfd_elf_generic_reloc, /* special_function. */
+ "R_MOXIE_PCREL10", /* name. */
+ FALSE, /* partial_inplace. */
+ 0, /* src_mask. */
+ 0x000003FF, /* dst_mask. */
+ TRUE), /* pcrel_offset. */
+};
+
+/* Map BFD reloc types to MOXIE ELF reloc types. */
+
+struct moxie_reloc_map
+{
+ bfd_reloc_code_real_type bfd_reloc_val;
+ unsigned int moxie_reloc_val;
+};
+
+static const struct moxie_reloc_map moxie_reloc_map [] =
+{
+ { BFD_RELOC_NONE, R_MOXIE_NONE },
+ { BFD_RELOC_32, R_MOXIE_32 },
+ { BFD_RELOC_MOXIE_10_PCREL, R_MOXIE_PCREL10 },
+};
+
+static reloc_howto_type *
+moxie_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ bfd_reloc_code_real_type code)
+{
+ unsigned int i;
+
+ for (i = sizeof (moxie_reloc_map) / sizeof (moxie_reloc_map[0]);
+ --i;)
+ if (moxie_reloc_map [i].bfd_reloc_val == code)
+ return & moxie_elf_howto_table [moxie_reloc_map[i].moxie_reloc_val];
+
+ return NULL;
+}
+
+static reloc_howto_type *
+moxie_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, const char *r_name)
+{
+ unsigned int i;
+
+ for (i = 0;
+ i < sizeof (moxie_elf_howto_table) / sizeof (moxie_elf_howto_table[0]);
+ i++)
+ if (moxie_elf_howto_table[i].name != NULL
+ && strcasecmp (moxie_elf_howto_table[i].name, r_name) == 0)
+ return &moxie_elf_howto_table[i];
+
+ return NULL;
+}
+
+/* Set the howto pointer for an MOXIE ELF reloc. */
+
+static void
+moxie_info_to_howto_rela (bfd *abfd ATTRIBUTE_UNUSED,
+ arelent *cache_ptr,
+ Elf_Internal_Rela *dst)
+{
+ unsigned int r_type;
+
+ r_type = ELF32_R_TYPE (dst->r_info);
+ BFD_ASSERT (r_type < (unsigned int) R_MOXIE_max);
+ cache_ptr->howto = & moxie_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
+moxie_final_link_relocate (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;
+
+ switch (howto->type)
+ {
+ default:
+ r = _bfd_final_link_relocate (howto, input_bfd, input_section,
+ contents, rel->r_offset,
+ relocation, rel->r_addend);
+ }
+
+ return r;
+}
+
+/* Relocate an MOXIE ELF section.
+
+ 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 relocatable
+ 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 relocatable 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 bfd_boolean
+moxie_elf_relocate_section (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;
+ int r_type;
+
+ r_type = ELF32_R_TYPE (rel->r_info);
+ r_symndx = ELF32_R_SYM (rel->r_info);
+ howto = moxie_elf_howto_table + r_type;
+ h = NULL;
+ sym = NULL;
+ sec = NULL;
+
+ if (r_symndx < symtab_hdr->sh_info)
+ {
+ sym = local_syms + r_symndx;
+ sec = local_sections [r_symndx];
+ relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
+
+ 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;
+ }
+ else
+ {
+ bfd_boolean unresolved_reloc, warned, ignored;
+
+ RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
+ r_symndx, symtab_hdr, sym_hashes,
+ h, sec, relocation,
+ unresolved_reloc, warned, ignored);
+
+ name = h->root.root.string;
+ }
+
+ if (sec != NULL && discarded_section (sec))
+ RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+ rel, 1, relend, howto, 0, contents);
+
+ if (info->relocatable)
+ continue;
+
+ r = moxie_final_link_relocate (howto, input_bfd, input_section,
+ contents, rel, relocation);
+
+ if (r != bfd_reloc_ok)
+ {
+ const char * msg = NULL;
+
+ switch (r)
+ {
+ case bfd_reloc_overflow:
+ r = info->callbacks->reloc_overflow
+ (info, (h ? &h->root : NULL), 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,
+ TRUE);
+ 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 *
+moxie_elf_gc_mark_hook (asection *sec,
+ struct bfd_link_info *info,
+ Elf_Internal_Rela *rel,
+ struct elf_link_hash_entry *h,
+ Elf_Internal_Sym *sym)
+{
+ return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
+}
+
+/* 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 bfd_boolean
+moxie_elf_check_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;
+ const Elf_Internal_Rela *rel;
+ const Elf_Internal_Rela *rel_end;
+
+ if (info->relocatable)
+ return TRUE;
+
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+ sym_hashes = elf_sym_hashes (abfd);
+
+ 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];
+ 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;
+
+ /* PR15323, ref flags aren't set for references in the same
+ object. */
+ h->root.non_ir_ref = 1;
+ }
+ }
+
+ return TRUE;
+}
+
+#define ELF_ARCH bfd_arch_moxie
+#define ELF_MACHINE_CODE EM_MOXIE
+#define ELF_MAXPAGESIZE 0x1
+
+#define TARGET_BIG_SYM moxie_elf32_be_vec
+#define TARGET_BIG_NAME "elf32-bigmoxie"
+#define TARGET_LITTLE_SYM moxie_elf32_le_vec
+#define TARGET_LITTLE_NAME "elf32-littlemoxie"
+
+#define elf_info_to_howto_rel NULL
+#define elf_info_to_howto moxie_info_to_howto_rela
+#define elf_backend_relocate_section moxie_elf_relocate_section
+#define elf_backend_gc_mark_hook moxie_elf_gc_mark_hook
+#define elf_backend_check_relocs moxie_elf_check_relocs
+
+#define elf_backend_can_gc_sections 1
+#define elf_backend_rela_normal 1
+
+#define bfd_elf32_bfd_reloc_type_lookup moxie_reloc_type_lookup
+#define bfd_elf32_bfd_reloc_name_lookup moxie_reloc_name_lookup
+
+#include "elf32-target.h"
diff --git a/bfd/elf32-msp430.c b/bfd/elf32-msp430.c
new file mode 100644
index 0000000..2f55c53
--- /dev/null
+++ b/bfd/elf32-msp430.c
@@ -0,0 +1,2477 @@
+/* MSP430-specific support for 32-bit ELF
+ Copyright (C) 2002-2014 Free Software Foundation, Inc.
+ Contributed by Dmitry Diky <diwil@mail.ru>
+
+ This file is part of BFD, the Binary File Descriptor library.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libiberty.h"
+#include "libbfd.h"
+#include "elf-bfd.h"
+#include "elf/msp430.h"
+
+static reloc_howto_type elf_msp430_howto_table[] =
+{
+ HOWTO (R_MSP430_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_MSP430_NONE", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_MSP430_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_MSP430_32", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A 10 bit PC relative relocation. */
+ HOWTO (R_MSP430_10_PCREL, /* type */
+ 1, /* rightshift */
+ 1, /* 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_MSP430_10_PCREL", /* name */
+ FALSE, /* partial_inplace */
+ 0x3ff, /* src_mask */
+ 0x3ff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* A 16 bit absolute relocation. */
+ HOWTO (R_MSP430_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_MSP430_16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A 16 bit PC relative relocation for command address. */
+ HOWTO (R_MSP430_16_PCREL, /* type */
+ 1, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MSP430_16_PCREL", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* A 16 bit absolute relocation, byte operations. */
+ HOWTO (R_MSP430_16_BYTE, /* 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_MSP430_16_BYTE", /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A 16 bit absolute relocation for command address. */
+ HOWTO (R_MSP430_16_PCREL_BYTE,/* type */
+ 1, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MSP430_16_PCREL_BYTE",/* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* A 10 bit PC relative relocation for complicated polymorphs. */
+ HOWTO (R_MSP430_2X_PCREL, /* type */
+ 1, /* 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_MSP430_2X_PCREL", /* name */
+ FALSE, /* partial_inplace */
+ 0x3ff, /* src_mask */
+ 0x3ff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* A 16 bit relaxable relocation for command address. */
+ HOWTO (R_MSP430_RL_PCREL, /* type */
+ 1, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MSP430_RL_PCREL", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ TRUE) /* pcrel_offset */
+
+ /* A 8-bit absolute relocation. */
+ , HOWTO (R_MSP430_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_MSP430_8", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Together with a following reloc, allows for the difference
+ between two symbols to be the real addend of the second reloc. */
+ HOWTO (R_MSP430_SYM_DIFF, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ NULL, /* special handler. */
+ "R_MSP430_SYM_DIFF", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE) /* pcrel_offset */
+};
+
+static reloc_howto_type elf_msp430x_howto_table[] =
+{
+ HOWTO (R_MSP430_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_MSP430_NONE", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_MSP430_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_MSP430_ABS32", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_MSP430_ABS16, /* 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_MSP430_ABS16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_MSP430_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_MSP430_ABS8", /* name */
+ FALSE, /* partial_inplace */
+ 0xff, /* src_mask */
+ 0xff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_MSP430_PCR16, /* type */
+ 1, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MSP430_PCR16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_MSP430X_PCR20_EXT_SRC,/* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MSP430X_PCR20_EXT_SRC",/* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_MSP430X_PCR20_EXT_DST,/* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MSP430X_PCR20_EXT_DST",/* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_MSP430X_PCR20_EXT_ODST,/* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MSP430X_PCR20_EXT_ODST",/* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_MSP430X_ABS20_EXT_SRC,/* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MSP430X_ABS20_EXT_SRC",/* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_MSP430X_ABS20_EXT_DST,/* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MSP430X_ABS20_EXT_DST",/* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_MSP430X_ABS20_EXT_ODST,/* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MSP430X_ABS20_EXT_ODST",/* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_MSP430X_ABS20_ADR_SRC,/* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MSP430X_ABS20_ADR_SRC",/* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_MSP430X_ABS20_ADR_DST,/* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MSP430X_ABS20_ADR_DST",/* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_MSP430X_PCR16, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MSP430X_PCR16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_MSP430X_PCR20_CALL, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MSP430X_PCR20_CALL",/* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_MSP430X_ABS16, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MSP430X_ABS16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_MSP430_ABS_HI16, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MSP430_ABS_HI16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_MSP430_PREL31, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MSP430_PREL31", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ EMPTY_HOWTO (R_MSP430_EHTYPE),
+
+ /* A 10 bit PC relative relocation. */
+ HOWTO (R_MSP430X_10_PCREL, /* type */
+ 1, /* rightshift */
+ 1, /* 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_MSP430X_10_PCREL", /* name */
+ FALSE, /* partial_inplace */
+ 0x3ff, /* src_mask */
+ 0x3ff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* A 10 bit PC relative relocation for complicated polymorphs. */
+ HOWTO (R_MSP430X_2X_PCREL, /* type */
+ 1, /* 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_MSP430X_2X_PCREL", /* name */
+ FALSE, /* partial_inplace */
+ 0x3ff, /* src_mask */
+ 0x3ff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* Together with a following reloc, allows for the difference
+ between two symbols to be the real addend of the second reloc. */
+ HOWTO (R_MSP430X_SYM_DIFF, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ NULL, /* special handler. */
+ "R_MSP430X_SYM_DIFF", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE) /* pcrel_offset */
+};
+
+/* Map BFD reloc types to MSP430 ELF reloc types. */
+
+struct msp430_reloc_map
+{
+ bfd_reloc_code_real_type bfd_reloc_val;
+ unsigned int elf_reloc_val;
+};
+
+static const struct msp430_reloc_map msp430_reloc_map[] =
+{
+ {BFD_RELOC_NONE, R_MSP430_NONE},
+ {BFD_RELOC_32, R_MSP430_32},
+ {BFD_RELOC_MSP430_10_PCREL, R_MSP430_10_PCREL},
+ {BFD_RELOC_16, R_MSP430_16_BYTE},
+ {BFD_RELOC_MSP430_16_PCREL, R_MSP430_16_PCREL},
+ {BFD_RELOC_MSP430_16, R_MSP430_16},
+ {BFD_RELOC_MSP430_16_PCREL_BYTE, R_MSP430_16_PCREL_BYTE},
+ {BFD_RELOC_MSP430_16_BYTE, R_MSP430_16_BYTE},
+ {BFD_RELOC_MSP430_2X_PCREL, R_MSP430_2X_PCREL},
+ {BFD_RELOC_MSP430_RL_PCREL, R_MSP430_RL_PCREL},
+ {BFD_RELOC_8, R_MSP430_8},
+ {BFD_RELOC_MSP430_SYM_DIFF, R_MSP430_SYM_DIFF}
+};
+
+static const struct msp430_reloc_map msp430x_reloc_map[] =
+{
+ {BFD_RELOC_NONE, R_MSP430_NONE},
+ {BFD_RELOC_32, R_MSP430_ABS32},
+ {BFD_RELOC_16, R_MSP430_ABS16},
+ {BFD_RELOC_8, R_MSP430_ABS8},
+ {BFD_RELOC_MSP430_ABS8, R_MSP430_ABS8},
+ {BFD_RELOC_MSP430X_PCR20_EXT_SRC, R_MSP430X_PCR20_EXT_SRC},
+ {BFD_RELOC_MSP430X_PCR20_EXT_DST, R_MSP430X_PCR20_EXT_DST},
+ {BFD_RELOC_MSP430X_PCR20_EXT_ODST, R_MSP430X_PCR20_EXT_ODST},
+ {BFD_RELOC_MSP430X_ABS20_EXT_SRC, R_MSP430X_ABS20_EXT_SRC},
+ {BFD_RELOC_MSP430X_ABS20_EXT_DST, R_MSP430X_ABS20_EXT_DST},
+ {BFD_RELOC_MSP430X_ABS20_EXT_ODST, R_MSP430X_ABS20_EXT_ODST},
+ {BFD_RELOC_MSP430X_ABS20_ADR_SRC, R_MSP430X_ABS20_ADR_SRC},
+ {BFD_RELOC_MSP430X_ABS20_ADR_DST, R_MSP430X_ABS20_ADR_DST},
+ {BFD_RELOC_MSP430X_PCR16, R_MSP430X_PCR16},
+ {BFD_RELOC_MSP430X_PCR20_CALL, R_MSP430X_PCR20_CALL},
+ {BFD_RELOC_MSP430X_ABS16, R_MSP430X_ABS16},
+ {BFD_RELOC_MSP430_ABS_HI16, R_MSP430_ABS_HI16},
+ {BFD_RELOC_MSP430_PREL31, R_MSP430_PREL31},
+ {BFD_RELOC_MSP430_10_PCREL, R_MSP430X_10_PCREL},
+ {BFD_RELOC_MSP430_2X_PCREL, R_MSP430X_2X_PCREL},
+ {BFD_RELOC_MSP430_RL_PCREL, R_MSP430X_PCR16},
+ {BFD_RELOC_MSP430_SYM_DIFF, R_MSP430X_SYM_DIFF}
+};
+
+static inline bfd_boolean
+uses_msp430x_relocs (bfd * abfd)
+{
+ extern const bfd_target msp430_elf32_ti_vec;
+
+ return bfd_get_mach (abfd) == bfd_mach_msp430x
+ || abfd->xvec == & msp430_elf32_ti_vec;
+}
+
+static reloc_howto_type *
+bfd_elf32_bfd_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED,
+ bfd_reloc_code_real_type code)
+{
+ unsigned int i;
+
+ if (uses_msp430x_relocs (abfd))
+ {
+ for (i = ARRAY_SIZE (msp430x_reloc_map); i--;)
+ if (msp430x_reloc_map[i].bfd_reloc_val == code)
+ return elf_msp430x_howto_table + msp430x_reloc_map[i].elf_reloc_val;
+ }
+ else
+ {
+ for (i = 0; i < ARRAY_SIZE (msp430_reloc_map); i++)
+ if (msp430_reloc_map[i].bfd_reloc_val == code)
+ return &elf_msp430_howto_table[msp430_reloc_map[i].elf_reloc_val];
+ }
+
+ return NULL;
+}
+
+static reloc_howto_type *
+bfd_elf32_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ const char *r_name)
+{
+ unsigned int i;
+
+ if (uses_msp430x_relocs (abfd))
+ {
+ for (i = ARRAY_SIZE (elf_msp430x_howto_table); i--;)
+ if (elf_msp430x_howto_table[i].name != NULL
+ && strcasecmp (elf_msp430x_howto_table[i].name, r_name) == 0)
+ return elf_msp430x_howto_table + i;
+ }
+ else
+ {
+ for (i = 0;
+ i < (sizeof (elf_msp430_howto_table)
+ / sizeof (elf_msp430_howto_table[0]));
+ i++)
+ if (elf_msp430_howto_table[i].name != NULL
+ && strcasecmp (elf_msp430_howto_table[i].name, r_name) == 0)
+ return &elf_msp430_howto_table[i];
+ }
+
+ return NULL;
+}
+
+/* Set the howto pointer for an MSP430 ELF reloc. */
+
+static void
+msp430_info_to_howto_rela (bfd * abfd ATTRIBUTE_UNUSED,
+ arelent * cache_ptr,
+ Elf_Internal_Rela * dst)
+{
+ unsigned int r_type;
+
+ r_type = ELF32_R_TYPE (dst->r_info);
+
+ if (uses_msp430x_relocs (abfd))
+ {
+ BFD_ASSERT (r_type < (unsigned int) R_MSP430x_max);
+ cache_ptr->howto = elf_msp430x_howto_table + r_type;
+ return;
+ }
+
+ BFD_ASSERT (r_type < (unsigned int) R_MSP430_max);
+ cache_ptr->howto = &elf_msp430_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 bfd_boolean
+elf32_msp430_check_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;
+ const Elf_Internal_Rela *rel;
+ const Elf_Internal_Rela *rel_end;
+
+ if (info->relocatable)
+ return TRUE;
+
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+ sym_hashes = elf_sym_hashes (abfd);
+
+ 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];
+ 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;
+
+ /* PR15323, ref flags aren't set for references in the same
+ object. */
+ h->root.non_ir_ref = 1;
+ }
+ }
+
+ return TRUE;
+}
+
+/* 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
+msp430_final_link_relocate (reloc_howto_type * howto,
+ bfd * input_bfd,
+ asection * input_section,
+ bfd_byte * contents,
+ Elf_Internal_Rela * rel,
+ bfd_vma relocation,
+ struct bfd_link_info * info)
+{
+ static asection * sym_diff_section;
+ static bfd_vma sym_diff_value;
+
+ struct bfd_elf_section_data * esd = elf_section_data (input_section);
+ bfd_reloc_status_type r = bfd_reloc_ok;
+ bfd_vma x;
+ bfd_signed_vma srel;
+ bfd_boolean is_rel_reloc = FALSE;
+
+ if (uses_msp430x_relocs (input_bfd))
+ {
+ /* See if we have a REL type relocation. */
+ is_rel_reloc = (esd->rel.hdr != NULL);
+ /* Sanity check - only one type of relocation per section.
+ FIXME: Theoretically it is possible to have both types,
+ but if that happens how can we distinguish between the two ? */
+ BFD_ASSERT (! is_rel_reloc || ! esd->rela.hdr);
+ /* If we are using a REL relocation then the addend should be empty. */
+ BFD_ASSERT (! is_rel_reloc || rel->r_addend == 0);
+ }
+
+ if (sym_diff_section != NULL)
+ {
+ BFD_ASSERT (sym_diff_section == input_section);
+
+ if (uses_msp430x_relocs (input_bfd))
+ switch (howto->type)
+ {
+ case R_MSP430_ABS32:
+ /* If we are computing a 32-bit value for the location lists
+ and the result is 0 then we add one to the value. A zero
+ value can result because of linker relaxation deleteing
+ prologue instructions and using a value of 1 (for the begin
+ and end offsets in the location list entry) results in a
+ nul entry which does not prevent the following entries from
+ being parsed. */
+ if (relocation == sym_diff_value
+ && strcmp (input_section->name, ".debug_loc") == 0)
+ ++ relocation;
+ /* Fall through. */
+ case R_MSP430_ABS16:
+ case R_MSP430X_ABS16:
+ case R_MSP430_ABS8:
+ BFD_ASSERT (! is_rel_reloc);
+ relocation -= sym_diff_value;
+ break;
+
+ default:
+ return bfd_reloc_dangerous;
+ }
+ else
+ switch (howto->type)
+ {
+ case R_MSP430_32:
+ case R_MSP430_16:
+ case R_MSP430_16_BYTE:
+ case R_MSP430_8:
+ relocation -= sym_diff_value;
+ break;
+
+ default:
+ return bfd_reloc_dangerous;
+ }
+
+ sym_diff_section = NULL;
+ }
+
+ if (uses_msp430x_relocs (input_bfd))
+ switch (howto->type)
+ {
+ case R_MSP430X_SYM_DIFF:
+ /* Cache the input section and value.
+ The offset is unreliable, since relaxation may
+ have reduced the following reloc's offset. */
+ BFD_ASSERT (! is_rel_reloc);
+ sym_diff_section = input_section;
+ sym_diff_value = relocation;
+ return bfd_reloc_ok;
+
+ case R_MSP430_ABS16:
+ contents += rel->r_offset;
+ srel = (bfd_signed_vma) relocation;
+ if (is_rel_reloc)
+ srel += bfd_get_16 (input_bfd, contents);
+ else
+ srel += rel->r_addend;
+ bfd_put_16 (input_bfd, srel & 0xffff, contents);
+ break;
+
+ case R_MSP430X_10_PCREL:
+ contents += rel->r_offset;
+ srel = (bfd_signed_vma) relocation;
+ if (is_rel_reloc)
+ srel += bfd_get_16 (input_bfd, contents) & 0x3ff;
+ else
+ 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;
+
+ /* MSP430 addresses commands as words. */
+ srel >>= 1;
+
+ /* Check for an overflow. */
+ if (srel < -512 || srel > 511)
+ {
+ if (info->disable_target_specific_optimizations < 0)
+ {
+ static bfd_boolean warned = FALSE;
+ if (! warned)
+ {
+ info->callbacks->warning
+ (info,
+ _("Try enabling relaxation to avoid relocation truncations"),
+ NULL, input_bfd, input_section, relocation);
+ warned = TRUE;
+ }
+ }
+ return bfd_reloc_overflow;
+ }
+
+ x = bfd_get_16 (input_bfd, contents);
+ x = (x & 0xfc00) | (srel & 0x3ff);
+ bfd_put_16 (input_bfd, x, contents);
+ break;
+
+ case R_MSP430X_PCR20_EXT_ODST:
+ /* [0,4]+[48,16] = ---F ---- FFFF */
+ contents += rel->r_offset;
+ srel = (bfd_signed_vma) relocation;
+ if (is_rel_reloc)
+ {
+ bfd_vma addend;
+ addend = (bfd_get_16 (input_bfd, contents) & 0xf) << 16;
+ addend |= bfd_get_16 (input_bfd, contents+4);
+ srel += addend;
+
+ }
+ else
+ srel += rel->r_addend;
+ srel -= rel->r_offset;
+ srel -= (input_section->output_section->vma +
+ input_section->output_offset);
+ bfd_put_16 (input_bfd, (srel & 0xffff), contents + 6);
+ x = bfd_get_16 (input_bfd, contents);
+ x = (x & 0xfff0) | ((srel >> 16) & 0xf);
+ bfd_put_16 (input_bfd, x, contents);
+ break;
+
+ case R_MSP430X_ABS20_EXT_SRC:
+ /* [7,4]+[32,16] = -78- FFFF */
+ contents += rel->r_offset;
+ srel = (bfd_signed_vma) relocation;
+ if (is_rel_reloc)
+ {
+ bfd_vma addend;
+ addend = (bfd_get_16 (input_bfd, contents) & 0x0780) << 9;
+ addend |= bfd_get_16 (input_bfd, contents+2);
+ srel += addend;
+ }
+ else
+ srel += rel->r_addend;
+ bfd_put_16 (input_bfd, (srel & 0xffff), contents + 4);
+ srel >>= 16;
+ x = bfd_get_16 (input_bfd, contents);
+ x = (x & 0xf87f) | ((srel << 7) & 0x0780);
+ bfd_put_16 (input_bfd, x, contents);
+ break;
+
+ case R_MSP430_16_PCREL:
+ contents += rel->r_offset;
+ srel = (bfd_signed_vma) relocation;
+ if (is_rel_reloc)
+ srel += bfd_get_16 (input_bfd, contents);
+ else
+ srel += rel->r_addend;
+ srel -= rel->r_offset;
+ /* Only branch instructions add 2 to the PC... */
+ srel -= (input_section->output_section->vma +
+ input_section->output_offset);
+ if (srel & 1)
+ return bfd_reloc_outofrange;
+ bfd_put_16 (input_bfd, srel & 0xffff, contents);
+ break;
+
+ case R_MSP430X_PCR20_EXT_DST:
+ /* [0,4]+[32,16] = ---F FFFF */
+ contents += rel->r_offset;
+ srel = (bfd_signed_vma) relocation;
+ if (is_rel_reloc)
+ {
+ bfd_vma addend;
+ addend = (bfd_get_16 (input_bfd, contents) & 0xf) << 16;
+ addend |= bfd_get_16 (input_bfd, contents+2);
+ srel += addend;
+ }
+ else
+ srel += rel->r_addend;
+ srel -= rel->r_offset;
+ srel -= (input_section->output_section->vma +
+ input_section->output_offset);
+ bfd_put_16 (input_bfd, (srel & 0xffff), contents + 4);
+ srel >>= 16;
+ x = bfd_get_16 (input_bfd, contents);
+ x = (x & 0xfff0) | (srel & 0xf);
+ bfd_put_16 (input_bfd, x, contents);
+ break;
+
+ case R_MSP430X_PCR20_EXT_SRC:
+ /* [7,4]+32,16] = -78- FFFF */
+ contents += rel->r_offset;
+ srel = (bfd_signed_vma) relocation;
+ if (is_rel_reloc)
+ {
+ bfd_vma addend;
+ addend = ((bfd_get_16 (input_bfd, contents) & 0x0780) << 9);
+ addend |= bfd_get_16 (input_bfd, contents+2);
+ srel += addend;;
+ }
+ else
+ srel += rel->r_addend;
+ srel -= rel->r_offset;
+ /* Only branch instructions add 2 to the PC... */
+ srel -= (input_section->output_section->vma +
+ input_section->output_offset);
+ bfd_put_16 (input_bfd, (srel & 0xffff), contents + 4);
+ srel >>= 16;
+ x = bfd_get_16 (input_bfd, contents);
+ x = (x & 0xf87f) | ((srel << 7) & 0x0780);
+ bfd_put_16 (input_bfd, x, contents);
+ break;
+
+ case R_MSP430_ABS8:
+ contents += rel->r_offset;
+ srel = (bfd_signed_vma) relocation;
+ if (is_rel_reloc)
+ srel += bfd_get_8 (input_bfd, contents);
+ else
+ srel += rel->r_addend;
+ bfd_put_8 (input_bfd, srel & 0xff, contents);
+ break;
+
+ case R_MSP430X_ABS20_EXT_DST:
+ contents += rel->r_offset;
+ srel = (bfd_signed_vma) relocation;
+ if (is_rel_reloc)
+ srel += bfd_get_16 (input_bfd, contents) & 0xf;
+ else
+ srel += rel->r_addend;
+ bfd_put_16 (input_bfd, (srel & 0xffff), contents + 4);
+ srel >>= 16;
+ x = bfd_get_16 (input_bfd, contents);
+ x = (x & 0xfff0) | (srel & 0xf);
+ bfd_put_16 (input_bfd, x, contents);
+ break;
+
+ case R_MSP430X_ABS20_EXT_ODST:
+ /* [0,4]+[48,16] = ---F ---- FFFF */
+ contents += rel->r_offset;
+ srel = (bfd_signed_vma) relocation;
+ if (is_rel_reloc)
+ {
+ bfd_vma addend;
+ addend = (bfd_get_16 (input_bfd, contents) & 0xf) << 16;
+ addend |= bfd_get_16 (input_bfd, contents+4);
+ srel += addend;
+ }
+ else
+ srel += rel->r_addend;
+ bfd_put_16 (input_bfd, (srel & 0xffff), contents + 6);
+ srel >>= 16;
+ x = bfd_get_16 (input_bfd, contents);
+ x = (x & 0xfff0) | (srel & 0xf);
+ bfd_put_16 (input_bfd, x, contents);
+ break;
+
+ case R_MSP430X_ABS20_ADR_SRC:
+ /* [8,4]+[32,16] = -F-- FFFF */
+ contents += rel->r_offset;
+ srel = (bfd_signed_vma) relocation;
+ if (is_rel_reloc)
+ {
+ bfd_vma addend;
+
+ addend = ((bfd_get_16 (input_bfd, contents) & 0xf00) << 8);
+ addend |= bfd_get_16 (input_bfd, contents+2);
+ srel += addend;
+ }
+ else
+ srel += rel->r_addend;
+ bfd_put_16 (input_bfd, (srel & 0xffff), contents + 2);
+ srel >>= 16;
+ x = bfd_get_16 (input_bfd, contents);
+ x = (x & 0xf0ff) | ((srel << 8) & 0x0f00);
+ bfd_put_16 (input_bfd, x, contents);
+ break;
+
+ case R_MSP430X_ABS20_ADR_DST:
+ /* [0,4]+[32,16] = ---F FFFF */
+ contents += rel->r_offset;
+ srel = (bfd_signed_vma) relocation;
+ if (is_rel_reloc)
+ {
+ bfd_vma addend;
+ addend = ((bfd_get_16 (input_bfd, contents) & 0xf) << 16);
+ addend |= bfd_get_16 (input_bfd, contents+2);
+ srel += addend;
+ }
+ else
+ srel += rel->r_addend;
+ bfd_put_16 (input_bfd, (srel & 0xffff), contents + 2);
+ srel >>= 16;
+ x = bfd_get_16 (input_bfd, contents);
+ x = (x & 0xfff0) | (srel & 0xf);
+ bfd_put_16 (input_bfd, x, contents);
+ break;
+
+ case R_MSP430X_ABS16:
+ contents += rel->r_offset;
+ srel = (bfd_signed_vma) relocation;
+ if (is_rel_reloc)
+ srel += bfd_get_16 (input_bfd, contents);
+ else
+ srel += rel->r_addend;
+ x = srel;
+ if (x > 0xffff)
+ return bfd_reloc_overflow;
+ bfd_put_16 (input_bfd, srel & 0xffff, contents);
+ break;
+
+ case R_MSP430_ABS_HI16:
+ /* The EABI specifies that this must be a RELA reloc. */
+ BFD_ASSERT (! is_rel_reloc);
+ contents += rel->r_offset;
+ srel = (bfd_signed_vma) relocation;
+ srel += rel->r_addend;
+ bfd_put_16 (input_bfd, (srel >> 16) & 0xffff, contents);
+ break;
+
+ case R_MSP430X_PCR20_CALL:
+ /* [0,4]+[32,16] = ---F FFFF*/
+ contents += rel->r_offset;
+ srel = (bfd_signed_vma) relocation;
+ if (is_rel_reloc)
+ {
+ bfd_vma addend;
+ addend = (bfd_get_16 (input_bfd, contents) & 0xf) << 16;
+ addend |= bfd_get_16 (input_bfd, contents+2);
+ srel += addend;
+ }
+ else
+ srel += rel->r_addend;
+ srel -= rel->r_offset;
+ srel -= (input_section->output_section->vma +
+ input_section->output_offset);
+ bfd_put_16 (input_bfd, srel & 0xffff, contents + 2);
+ srel >>= 16;
+ x = bfd_get_16 (input_bfd, contents);
+ x = (x & 0xfff0) | (srel & 0xf);
+ bfd_put_16 (input_bfd, x, contents);
+ break;
+
+ case R_MSP430X_PCR16:
+ contents += rel->r_offset;
+ srel = (bfd_signed_vma) relocation;
+ if (is_rel_reloc)
+ srel += bfd_get_16 (input_bfd, contents);
+ else
+ srel += rel->r_addend;
+ srel -= rel->r_offset;
+ srel -= (input_section->output_section->vma +
+ input_section->output_offset);
+ bfd_put_16 (input_bfd, srel & 0xffff, contents);
+ break;
+
+ case R_MSP430_PREL31:
+ contents += rel->r_offset;
+ srel = (bfd_signed_vma) relocation;
+ if (is_rel_reloc)
+ srel += (bfd_get_32 (input_bfd, contents) & 0x7fffffff);
+ else
+ srel += rel->r_addend;
+ srel += rel->r_addend;
+ x = bfd_get_32 (input_bfd, contents);
+ x = (x & 0x80000000) | ((srel >> 31) & 0x7fffffff);
+ bfd_put_32 (input_bfd, x, contents);
+ break;
+
+ default:
+ r = _bfd_final_link_relocate (howto, input_bfd, input_section,
+ contents, rel->r_offset,
+ relocation, rel->r_addend);
+ }
+ else
+ switch (howto->type)
+ {
+ case R_MSP430_10_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;
+
+ /* MSP430 addresses commands as words. */
+ srel >>= 1;
+
+ /* Check for an overflow. */
+ if (srel < -512 || srel > 511)
+ {
+ if (info->disable_target_specific_optimizations < 0)
+ {
+ static bfd_boolean warned = FALSE;
+ if (! warned)
+ {
+ info->callbacks->warning
+ (info,
+ _("Try enabling relaxation to avoid relocation truncations"),
+ NULL, input_bfd, input_section, relocation);
+ warned = TRUE;
+ }
+ }
+ return bfd_reloc_overflow;
+ }
+
+ x = bfd_get_16 (input_bfd, contents);
+ x = (x & 0xfc00) | (srel & 0x3ff);
+ bfd_put_16 (input_bfd, x, contents);
+ break;
+
+ case R_MSP430_2X_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;
+
+ /* MSP430 addresses commands as words. */
+ srel >>= 1;
+
+ /* Check for an overflow. */
+ if (srel < -512 || srel > 511)
+ return bfd_reloc_overflow;
+
+ x = bfd_get_16 (input_bfd, contents);
+ x = (x & 0xfc00) | (srel & 0x3ff);
+ bfd_put_16 (input_bfd, x, contents);
+ /* Handle second jump instruction. */
+ x = bfd_get_16 (input_bfd, contents - 2);
+ srel += 1;
+ x = (x & 0xfc00) | (srel & 0x3ff);
+ bfd_put_16 (input_bfd, x, contents - 2);
+ break;
+
+ case R_MSP430_RL_PCREL:
+ case R_MSP430_16_PCREL:
+ contents += rel->r_offset;
+ srel = (bfd_signed_vma) relocation;
+ srel += rel->r_addend;
+ srel -= rel->r_offset;
+ /* Only branch instructions add 2 to the PC... */
+ srel -= (input_section->output_section->vma +
+ input_section->output_offset);
+
+ if (srel & 1)
+ return bfd_reloc_outofrange;
+
+ bfd_put_16 (input_bfd, srel & 0xffff, contents);
+ break;
+
+ case R_MSP430_16_PCREL_BYTE:
+ contents += rel->r_offset;
+ srel = (bfd_signed_vma) relocation;
+ srel += rel->r_addend;
+ srel -= rel->r_offset;
+ /* Only branch instructions add 2 to the PC... */
+ srel -= (input_section->output_section->vma +
+ input_section->output_offset);
+
+ bfd_put_16 (input_bfd, srel & 0xffff, contents);
+ break;
+
+ case R_MSP430_16_BYTE:
+ contents += rel->r_offset;
+ srel = (bfd_signed_vma) relocation;
+ srel += rel->r_addend;
+ bfd_put_16 (input_bfd, srel & 0xffff, contents);
+ break;
+
+ case R_MSP430_16:
+ contents += rel->r_offset;
+ srel = (bfd_signed_vma) relocation;
+ srel += rel->r_addend;
+
+ if (srel & 1)
+ return bfd_reloc_notsupported;
+
+ bfd_put_16 (input_bfd, srel & 0xffff, contents);
+ break;
+
+ case R_MSP430_8:
+ contents += rel->r_offset;
+ srel = (bfd_signed_vma) relocation;
+ srel += rel->r_addend;
+
+ bfd_put_8 (input_bfd, srel & 0xff, contents);
+ break;
+
+ case R_MSP430_SYM_DIFF:
+ /* Cache the input section and value.
+ The offset is unreliable, since relaxation may
+ have reduced the following reloc's offset. */
+ sym_diff_section = input_section;
+ sym_diff_value = relocation;
+ return bfd_reloc_ok;
+
+ default:
+ r = _bfd_final_link_relocate (howto, input_bfd, input_section,
+ contents, rel->r_offset,
+ relocation, rel->r_addend);
+ }
+
+ return r;
+}
+
+/* Relocate an MSP430 ELF section. */
+
+static bfd_boolean
+elf32_msp430_relocate_section (bfd * output_bfd ATTRIBUTE_UNUSED,
+ 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);
+ r_symndx = ELF32_R_SYM (rel->r_info);
+
+ if (uses_msp430x_relocs (input_bfd))
+ howto = elf_msp430x_howto_table + r_type;
+ else
+ howto = elf_msp430_howto_table + r_type;
+
+ h = NULL;
+ sym = NULL;
+ sec = NULL;
+
+ if (r_symndx < symtab_hdr->sh_info)
+ {
+ sym = local_syms + r_symndx;
+ sec = local_sections[r_symndx];
+ relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
+
+ name = bfd_elf_string_from_elf_section
+ (input_bfd, symtab_hdr->sh_link, sym->st_name);
+ name = (name == NULL || * name == 0) ? bfd_section_name (input_bfd, sec) : name;
+ }
+ else
+ {
+ bfd_boolean unresolved_reloc, warned, ignored;
+
+ RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
+ r_symndx, symtab_hdr, sym_hashes,
+ h, sec, relocation,
+ unresolved_reloc, warned, ignored);
+ name = h->root.root.string;
+ }
+
+ if (sec != NULL && discarded_section (sec))
+ RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+ rel, 1, relend, howto, 0, contents);
+
+ if (info->relocatable)
+ continue;
+
+ r = msp430_final_link_relocate (howto, input_bfd, input_section,
+ contents, rel, relocation, info);
+
+ if (r != bfd_reloc_ok)
+ {
+ const char *msg = (const char *) NULL;
+
+ switch (r)
+ {
+ case bfd_reloc_overflow:
+ r = info->callbacks->reloc_overflow
+ (info, (h ? &h->root : NULL), 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, TRUE);
+ break;
+
+ case bfd_reloc_outofrange:
+ msg = _("internal error: branch/jump to an odd address detected");
+ 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;
+}
+
+/* The final processing done just before writing out a MSP430 ELF object
+ file. This gets the MSP430 architecture right based on the machine
+ number. */
+
+static void
+bfd_elf_msp430_final_write_processing (bfd * abfd,
+ bfd_boolean linker ATTRIBUTE_UNUSED)
+{
+ unsigned long val;
+
+ switch (bfd_get_mach (abfd))
+ {
+ default:
+ case bfd_mach_msp110: val = E_MSP430_MACH_MSP430x11x1; break;
+ case bfd_mach_msp11: val = E_MSP430_MACH_MSP430x11; break;
+ case bfd_mach_msp12: val = E_MSP430_MACH_MSP430x12; break;
+ case bfd_mach_msp13: val = E_MSP430_MACH_MSP430x13; break;
+ case bfd_mach_msp14: val = E_MSP430_MACH_MSP430x14; break;
+ case bfd_mach_msp15: val = E_MSP430_MACH_MSP430x15; break;
+ case bfd_mach_msp16: val = E_MSP430_MACH_MSP430x16; break;
+ case bfd_mach_msp31: val = E_MSP430_MACH_MSP430x31; break;
+ case bfd_mach_msp32: val = E_MSP430_MACH_MSP430x32; break;
+ case bfd_mach_msp33: val = E_MSP430_MACH_MSP430x33; break;
+ case bfd_mach_msp41: val = E_MSP430_MACH_MSP430x41; break;
+ case bfd_mach_msp42: val = E_MSP430_MACH_MSP430x42; break;
+ case bfd_mach_msp43: val = E_MSP430_MACH_MSP430x43; break;
+ case bfd_mach_msp44: val = E_MSP430_MACH_MSP430x44; break;
+ case bfd_mach_msp20: val = E_MSP430_MACH_MSP430x20; break;
+ case bfd_mach_msp22: val = E_MSP430_MACH_MSP430x22; break;
+ case bfd_mach_msp23: val = E_MSP430_MACH_MSP430x23; break;
+ case bfd_mach_msp24: val = E_MSP430_MACH_MSP430x24; break;
+ case bfd_mach_msp26: val = E_MSP430_MACH_MSP430x26; break;
+ case bfd_mach_msp46: val = E_MSP430_MACH_MSP430x46; break;
+ case bfd_mach_msp47: val = E_MSP430_MACH_MSP430x47; break;
+ case bfd_mach_msp54: val = E_MSP430_MACH_MSP430x54; break;
+ case bfd_mach_msp430x: val = E_MSP430_MACH_MSP430X; break;
+ }
+
+ elf_elfheader (abfd)->e_machine = EM_MSP430;
+ elf_elfheader (abfd)->e_flags &= ~EF_MSP430_MACH;
+ elf_elfheader (abfd)->e_flags |= val;
+}
+
+/* Set the right machine number. */
+
+static bfd_boolean
+elf32_msp430_object_p (bfd * abfd)
+{
+ int e_set = bfd_mach_msp14;
+
+ if (elf_elfheader (abfd)->e_machine == EM_MSP430
+ || elf_elfheader (abfd)->e_machine == EM_MSP430_OLD)
+ {
+ int e_mach = elf_elfheader (abfd)->e_flags & EF_MSP430_MACH;
+
+ switch (e_mach)
+ {
+ default:
+ case E_MSP430_MACH_MSP430x11: e_set = bfd_mach_msp11; break;
+ case E_MSP430_MACH_MSP430x11x1: e_set = bfd_mach_msp110; break;
+ case E_MSP430_MACH_MSP430x12: e_set = bfd_mach_msp12; break;
+ case E_MSP430_MACH_MSP430x13: e_set = bfd_mach_msp13; break;
+ case E_MSP430_MACH_MSP430x14: e_set = bfd_mach_msp14; break;
+ case E_MSP430_MACH_MSP430x15: e_set = bfd_mach_msp15; break;
+ case E_MSP430_MACH_MSP430x16: e_set = bfd_mach_msp16; break;
+ case E_MSP430_MACH_MSP430x31: e_set = bfd_mach_msp31; break;
+ case E_MSP430_MACH_MSP430x32: e_set = bfd_mach_msp32; break;
+ case E_MSP430_MACH_MSP430x33: e_set = bfd_mach_msp33; break;
+ case E_MSP430_MACH_MSP430x41: e_set = bfd_mach_msp41; break;
+ case E_MSP430_MACH_MSP430x42: e_set = bfd_mach_msp42; break;
+ case E_MSP430_MACH_MSP430x43: e_set = bfd_mach_msp43; break;
+ case E_MSP430_MACH_MSP430x44: e_set = bfd_mach_msp44; break;
+ case E_MSP430_MACH_MSP430x20: e_set = bfd_mach_msp20; break;
+ case E_MSP430_MACH_MSP430x22: e_set = bfd_mach_msp22; break;
+ case E_MSP430_MACH_MSP430x23: e_set = bfd_mach_msp23; break;
+ case E_MSP430_MACH_MSP430x24: e_set = bfd_mach_msp24; break;
+ case E_MSP430_MACH_MSP430x26: e_set = bfd_mach_msp26; break;
+ case E_MSP430_MACH_MSP430x46: e_set = bfd_mach_msp46; break;
+ case E_MSP430_MACH_MSP430x47: e_set = bfd_mach_msp47; break;
+ case E_MSP430_MACH_MSP430x54: e_set = bfd_mach_msp54; break;
+ case E_MSP430_MACH_MSP430X: e_set = bfd_mach_msp430x; break;
+ }
+ }
+
+ return bfd_default_set_arch_mach (abfd, bfd_arch_msp430, e_set);
+}
+
+/* These functions handle relaxing for the msp430.
+ Relaxation required only in two cases:
+ - Bad hand coding like jumps from one section to another or
+ from file to file.
+ - Sibling calls. This will affect only 'jump label' polymorph. Without
+ relaxing this enlarges code by 2 bytes. Sibcalls implemented but
+ do not work in gcc's port by the reason I do not know.
+ - To convert out of range conditional jump instructions (found inside
+ a function) into inverted jumps over an unconditional branch instruction.
+ Anyway, if a relaxation required, user should pass -relax option to the
+ linker.
+
+ There are quite a few relaxing opportunities available on the msp430:
+
+ ================================================================
+
+ 1. 3 words -> 1 word
+
+ eq == jeq label jne +4; br lab
+ ne != jne label jeq +4; br lab
+ lt < jl label jge +4; br lab
+ ltu < jlo label lhs +4; br lab
+ ge >= jge label jl +4; br lab
+ geu >= jhs label jlo +4; br lab
+
+ 2. 4 words -> 1 word
+
+ ltn < jn jn +2; jmp +4; br lab
+
+ 3. 4 words -> 2 words
+
+ gt > jeq +2; jge label jeq +6; jl +4; br label
+ gtu > jeq +2; jhs label jeq +6; jlo +4; br label
+
+ 4. 4 words -> 2 words and 2 labels
+
+ leu <= jeq label; jlo label jeq +2; jhs +4; br label
+ le <= jeq label; jl label jeq +2; jge +4; br label
+ =================================================================
+
+ codemap for first cases is (labels masked ):
+ eq: 0x2002,0x4010,0x0000 -> 0x2400
+ ne: 0x2402,0x4010,0x0000 -> 0x2000
+ lt: 0x3402,0x4010,0x0000 -> 0x3800
+ ltu: 0x2c02,0x4010,0x0000 -> 0x2800
+ ge: 0x3802,0x4010,0x0000 -> 0x3400
+ geu: 0x2802,0x4010,0x0000 -> 0x2c00
+
+ second case:
+ ltn: 0x3001,0x3c02,0x4010,0x0000 -> 0x3000
+
+ third case:
+ gt: 0x2403,0x3802,0x4010,0x0000 -> 0x2401,0x3400
+ gtu: 0x2403,0x2802,0x4010,0x0000 -> 0x2401,0x2c00
+
+ fourth case:
+ leu: 0x2401,0x2c02,0x4010,0x0000 -> 0x2400,0x2800
+ le: 0x2401,0x3402,0x4010,0x0000 -> 0x2400,0x3800
+
+ Unspecified case :)
+ jump: 0x4010,0x0000 -> 0x3c00. */
+
+#define NUMB_RELAX_CODES 12
+static struct rcodes_s
+{
+ int f0, f1; /* From code. */
+ int t0, t1; /* To code. */
+ int labels; /* Position of labels: 1 - one label at first
+ word, 2 - one at second word, 3 - two
+ labels at both. */
+ int cdx; /* Words to match. */
+ int bs; /* Shrink bytes. */
+ int off; /* Offset from old label for new code. */
+ int ncl; /* New code length. */
+} rcode[] =
+{/* lab,cdx,bs,off,ncl */
+ { 0x0000, 0x0000, 0x3c00, 0x0000, 1, 0, 2, 2, 2}, /* jump */
+ { 0x0000, 0x2002, 0x2400, 0x0000, 1, 1, 4, 4, 2}, /* eq */
+ { 0x0000, 0x2402, 0x2000, 0x0000, 1, 1, 4, 4, 2}, /* ne */
+ { 0x0000, 0x3402, 0x3800, 0x0000, 1, 1, 4, 4, 2}, /* lt */
+ { 0x0000, 0x2c02, 0x2800, 0x0000, 1, 1, 4, 4, 2}, /* ltu */
+ { 0x0000, 0x3802, 0x3400, 0x0000, 1, 1, 4, 4, 2}, /* ge */
+ { 0x0000, 0x2802, 0x2c00, 0x0000, 1, 1, 4, 4, 2}, /* geu */
+ { 0x3001, 0x3c02, 0x3000, 0x0000, 1, 2, 6, 6, 2}, /* ltn */
+ { 0x2403, 0x3802, 0x2401, 0x3400, 2, 2, 4, 6, 4}, /* gt */
+ { 0x2403, 0x2802, 0x2401, 0x2c00, 2, 2, 4, 6, 4}, /* gtu */
+ { 0x2401, 0x2c02, 0x2400, 0x2800, 3, 2, 4, 6, 4}, /* leu , 2 labels */
+ { 0x2401, 0x2c02, 0x2400, 0x2800, 3, 2, 4, 6, 4}, /* le , 2 labels */
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0}
+};
+
+/* Return TRUE if a symbol exists at the given address. */
+
+static bfd_boolean
+msp430_elf_symbol_address_p (bfd * abfd,
+ asection * sec,
+ Elf_Internal_Sym * isym,
+ bfd_vma addr)
+{
+ Elf_Internal_Shdr *symtab_hdr;
+ unsigned int sec_shndx;
+ Elf_Internal_Sym *isymend;
+ struct elf_link_hash_entry **sym_hashes;
+ struct elf_link_hash_entry **end_hashes;
+ unsigned int symcount;
+
+ sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
+
+ /* Examine all the local symbols. */
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+ for (isymend = isym + symtab_hdr->sh_info; isym < isymend; isym++)
+ if (isym->st_shndx == sec_shndx && isym->st_value == addr)
+ return TRUE;
+
+ symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
+ - symtab_hdr->sh_info);
+ sym_hashes = elf_sym_hashes (abfd);
+ end_hashes = sym_hashes + symcount;
+ for (; sym_hashes < end_hashes; sym_hashes++)
+ {
+ struct elf_link_hash_entry *sym_hash = *sym_hashes;
+
+ 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;
+}
+
+/* Adjust all local symbols defined as '.section + 0xXXXX' (.section has
+ sec_shndx) referenced from current and other sections. */
+
+static bfd_boolean
+msp430_elf_relax_adjust_locals (bfd * abfd, asection * sec, bfd_vma addr,
+ int count, unsigned int sec_shndx,
+ bfd_vma toaddr)
+{
+ Elf_Internal_Shdr *symtab_hdr;
+ Elf_Internal_Rela *irel;
+ Elf_Internal_Rela *irelend;
+ Elf_Internal_Sym *isym;
+
+ irel = elf_section_data (sec)->relocs;
+ if (irel == NULL)
+ return TRUE;
+
+ irelend = irel + sec->reloc_count;
+ symtab_hdr = & elf_tdata (abfd)->symtab_hdr;
+ isym = (Elf_Internal_Sym *) symtab_hdr->contents;
+
+ for (;irel < irelend; irel++)
+ {
+ unsigned int sidx = ELF32_R_SYM(irel->r_info);
+ Elf_Internal_Sym *lsym = isym + sidx;
+
+ /* Adjust symbols referenced by .sec+0xXX */
+ if (irel->r_addend > addr && irel->r_addend < toaddr
+ && sidx < symtab_hdr->sh_info
+ && lsym->st_shndx == sec_shndx)
+ irel->r_addend -= count;
+ }
+
+ return TRUE;
+}
+
+/* Delete some bytes from a section while relaxing. */
+
+static bfd_boolean
+msp430_elf_relax_delete_bytes (bfd * abfd, asection * sec, bfd_vma addr,
+ int count)
+{
+ Elf_Internal_Shdr *symtab_hdr;
+ unsigned int sec_shndx;
+ bfd_byte *contents;
+ Elf_Internal_Rela *irel;
+ Elf_Internal_Rela *irelend;
+ bfd_vma toaddr;
+ Elf_Internal_Sym *isym;
+ Elf_Internal_Sym *isymend;
+ struct elf_link_hash_entry **sym_hashes;
+ struct elf_link_hash_entry **end_hashes;
+ unsigned int symcount;
+ asection *p;
+
+ sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
+
+ contents = elf_section_data (sec)->this_hdr.contents;
+
+ toaddr = sec->size;
+
+ irel = elf_section_data (sec)->relocs;
+ irelend = irel + sec->reloc_count;
+
+ /* Actually delete the bytes. */
+ memmove (contents + addr, contents + addr + count,
+ (size_t) (toaddr - addr - count));
+ sec->size -= count;
+
+ /* Adjust all the relocs. */
+ symtab_hdr = & elf_tdata (abfd)->symtab_hdr;
+ isym = (Elf_Internal_Sym *) symtab_hdr->contents;
+ for (; irel < irelend; irel++)
+ {
+ /* Get the new reloc address. */
+ if ((irel->r_offset > addr && irel->r_offset < toaddr))
+ irel->r_offset -= count;
+ }
+
+ for (p = abfd->sections; p != NULL; p = p->next)
+ msp430_elf_relax_adjust_locals (abfd,p,addr,count,sec_shndx,toaddr);
+
+ /* Adjust the local symbols defined in this section. */
+ symtab_hdr = & elf_tdata (abfd)->symtab_hdr;
+ isym = (Elf_Internal_Sym *) symtab_hdr->contents;
+ for (isymend = isym + symtab_hdr->sh_info; isym < isymend; isym++)
+ if (isym->st_shndx == sec_shndx
+ && isym->st_value > addr && isym->st_value < toaddr)
+ isym->st_value -= count;
+
+ /* Now adjust the global symbols defined in this section. */
+ symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
+ - symtab_hdr->sh_info);
+ sym_hashes = elf_sym_hashes (abfd);
+ end_hashes = sym_hashes + symcount;
+ for (; sym_hashes < end_hashes; sym_hashes++)
+ {
+ struct elf_link_hash_entry *sym_hash = *sym_hashes;
+
+ 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
+ && sym_hash->root.u.def.value < toaddr)
+ sym_hash->root.u.def.value -= count;
+ }
+
+ return TRUE;
+}
+
+/* Insert two words into a section whilst relaxing. */
+
+static bfd_byte *
+msp430_elf_relax_add_two_words (bfd * abfd, asection * sec, bfd_vma addr,
+ int word1, int word2)
+{
+ Elf_Internal_Shdr *symtab_hdr;
+ unsigned int sec_shndx;
+ bfd_byte *contents;
+ Elf_Internal_Rela *irel;
+ Elf_Internal_Rela *irelend;
+ Elf_Internal_Sym *isym;
+ Elf_Internal_Sym *isymend;
+ struct elf_link_hash_entry **sym_hashes;
+ struct elf_link_hash_entry **end_hashes;
+ unsigned int symcount;
+ bfd_vma sec_end;
+ asection *p;
+
+ contents = elf_section_data (sec)->this_hdr.contents;
+ sec_end = sec->size;
+
+ /* Make space for the new words. */
+ contents = bfd_realloc (contents, sec_end + 4);
+ memmove (contents + addr + 4, contents + addr, sec_end - addr);
+
+ /* Insert the new words. */
+ bfd_put_16 (abfd, word1, contents + addr);
+ bfd_put_16 (abfd, word2, contents + addr + 2);
+
+ /* Update the section information. */
+ sec->size += 4;
+ elf_section_data (sec)->this_hdr.contents = contents;
+
+ /* Adjust all the relocs. */
+ irel = elf_section_data (sec)->relocs;
+ irelend = irel + sec->reloc_count;
+
+ for (; irel < irelend; irel++)
+ if ((irel->r_offset >= addr && irel->r_offset < sec_end))
+ irel->r_offset += 4;
+
+ /* Adjust the local symbols defined in this section. */
+ sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
+ for (p = abfd->sections; p != NULL; p = p->next)
+ msp430_elf_relax_adjust_locals (abfd, p, addr, -4,
+ sec_shndx, sec_end);
+
+ /* Adjust the global symbols affected by the move. */
+ symtab_hdr = & elf_tdata (abfd)->symtab_hdr;
+ isym = (Elf_Internal_Sym *) symtab_hdr->contents;
+ for (isymend = isym + symtab_hdr->sh_info; isym < isymend; isym++)
+ if (isym->st_shndx == sec_shndx
+ && isym->st_value >= addr && isym->st_value < sec_end)
+ isym->st_value += 4;
+
+ /* Now adjust the global symbols defined in this section. */
+ symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
+ - symtab_hdr->sh_info);
+ sym_hashes = elf_sym_hashes (abfd);
+ end_hashes = sym_hashes + symcount;
+ for (; sym_hashes < end_hashes; sym_hashes++)
+ {
+ struct elf_link_hash_entry *sym_hash = *sym_hashes;
+
+ 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
+ && sym_hash->root.u.def.value < sec_end)
+ sym_hash->root.u.def.value += 4;
+ }
+
+ return contents;
+}
+
+static bfd_boolean
+msp430_elf_relax_section (bfd * abfd, asection * sec,
+ struct bfd_link_info * link_info,
+ bfd_boolean * again)
+{
+ Elf_Internal_Shdr * symtab_hdr;
+ Elf_Internal_Rela * internal_relocs;
+ Elf_Internal_Rela * irel;
+ Elf_Internal_Rela * irelend;
+ bfd_byte * contents = NULL;
+ Elf_Internal_Sym * isymbuf = NULL;
+
+
+ /* Assume nothing changes. */
+ *again = FALSE;
+
+ /* We don't have to do anything for a relocatable link, if
+ this section does not have relocs, or if this is not a
+ code section. */
+ if (link_info->relocatable
+ || (sec->flags & SEC_RELOC) == 0
+ || sec->reloc_count == 0 || (sec->flags & SEC_CODE) == 0)
+ return TRUE;
+
+ symtab_hdr = & elf_tdata (abfd)->symtab_hdr;
+
+ /* Get a copy of the native relocations. */
+ internal_relocs =
+ _bfd_elf_link_read_relocs (abfd, sec, NULL, NULL, link_info->keep_memory);
+ if (internal_relocs == NULL)
+ goto error_return;
+
+ /* Walk through them looking for relaxing opportunities. */
+ irelend = internal_relocs + sec->reloc_count;
+
+ /* Do code size growing relocs first. */
+ for (irel = internal_relocs; irel < irelend; irel++)
+ {
+ bfd_vma symval;
+
+ /* If this isn't something that can be relaxed, then ignore
+ this reloc. */
+ if (uses_msp430x_relocs (abfd)
+ && ELF32_R_TYPE (irel->r_info) == (int) R_MSP430X_10_PCREL)
+ ;
+ else if (! uses_msp430x_relocs (abfd)
+ && ELF32_R_TYPE (irel->r_info) == (int) R_MSP430_10_PCREL)
+ ;
+ else
+ 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 if (! bfd_malloc_and_get_section (abfd, sec, &contents))
+ goto error_return;
+ }
+
+ /* Read this BFD's local symbols if we haven't done so already. */
+ if (isymbuf == NULL && symtab_hdr->sh_info != 0)
+ {
+ isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
+ if (isymbuf == NULL)
+ isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
+ symtab_hdr->sh_info, 0,
+ NULL, NULL, NULL);
+ if (isymbuf == NULL)
+ 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)
+ {
+ /* A local symbol. */
+ Elf_Internal_Sym *isym;
+ asection *sym_sec;
+
+ isym = isymbuf + ELF32_R_SYM (irel->r_info);
+ if (isym->st_shndx == SHN_UNDEF)
+ sym_sec = bfd_und_section_ptr;
+ 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;
+ else
+ 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. */
+
+ bfd_signed_vma value = symval;
+ int opcode;
+
+ /* Compute the value that will be relocated. */
+ value += irel->r_addend;
+ /* Convert to PC relative. */
+ value -= (sec->output_section->vma + sec->output_offset);
+ value -= irel->r_offset;
+ value -= 2;
+ /* Scale. */
+ value >>= 1;
+
+ /* If it is in range then no modifications are needed. */
+ if (value >= -512 && value <= 511)
+ continue;
+
+ /* Get the opcode. */
+ opcode = bfd_get_16 (abfd, contents + irel->r_offset);
+
+ /* Compute the new opcode. We are going to convert:
+ J<cond> label
+ into:
+ J<inv-cond> 1f
+ BR[A] #label
+ 1: */
+ switch (opcode & 0xfc00)
+ {
+ case 0x3800: opcode = 0x3402; break; /* Jl -> Jge +2 */
+ case 0x3400: opcode = 0x3802; break; /* Jge -> Jl +2 */
+ case 0x2c00: opcode = 0x2802; break; /* Jhs -> Jlo +2 */
+ case 0x2800: opcode = 0x2c02; break; /* Jlo -> Jhs +2 */
+ case 0x2400: opcode = 0x2002; break; /* Jeq -> Jne +2 */
+ case 0x2000: opcode = 0x2402; break; /* jne -> Jeq +2 */
+ case 0x3000: /* jn */
+ /* There is no direct inverse of the Jn insn.
+ FIXME: we could do this as:
+ Jn 1f
+ br 2f
+ 1: br label
+ 2: */
+ continue;
+ default:
+ /* Not a conditional branch instruction. */
+ /* fprintf (stderr, "unrecog: %x\n", opcode); */
+ goto error_return;
+ }
+
+ /* Note that we've changed the relocs, section contents, etc. */
+ elf_section_data (sec)->relocs = internal_relocs;
+ elf_section_data (sec)->this_hdr.contents = contents;
+ symtab_hdr->contents = (unsigned char *) isymbuf;
+
+ /* Install the new opcode. */
+ bfd_put_16 (abfd, opcode, contents + irel->r_offset);
+
+ /* Insert the new branch instruction. */
+ if (uses_msp430x_relocs (abfd))
+ {
+ /* Insert an absolute branch (aka MOVA) instruction. */
+ contents = msp430_elf_relax_add_two_words
+ (abfd, sec, irel->r_offset + 2, 0x0080, 0x0000);
+
+ /* Update the relocation to point to the inserted branch
+ instruction. Note - we are changing a PC-relative reloc
+ into an absolute reloc, but this is OK because we have
+ arranged with the assembler to have the reloc's value be
+ a (local) symbol, not a section+offset value. */
+ irel->r_offset += 2;
+ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
+ R_MSP430X_ABS20_ADR_SRC);
+ }
+ else
+ {
+ contents = msp430_elf_relax_add_two_words
+ (abfd, sec, irel->r_offset + 2, 0x4030, 0x0000);
+
+ /* See comment above about converting a 10-bit PC-rel
+ relocation into a 16-bit absolute relocation. */
+ irel->r_offset += 4;
+ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
+ R_MSP430_16);
+ }
+
+ /* Growing the section may mean that other
+ conditional branches need to be fixed. */
+ *again = TRUE;
+ }
+
+ if (! uses_msp430x_relocs (abfd))
+ /* Now perform the relocations that shrink the code size.
+ We only do this for non msp430x as gas only generates the RL
+ reloc for the msp430. */
+ for (irel = internal_relocs; irel < irelend; irel++)
+ {
+ bfd_vma symval;
+
+ /* 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 if (! bfd_malloc_and_get_section (abfd, sec, &contents))
+ goto error_return;
+ }
+
+ /* Read this BFD's local symbols if we haven't done so already. */
+ if (isymbuf == NULL && symtab_hdr->sh_info != 0)
+ {
+ isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
+ if (isymbuf == NULL)
+ isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
+ symtab_hdr->sh_info, 0,
+ NULL, NULL, NULL);
+ if (isymbuf == NULL)
+ 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)
+ {
+ /* A local symbol. */
+ Elf_Internal_Sym *isym;
+ asection *sym_sec;
+
+ isym = isymbuf + ELF32_R_SYM (irel->r_info);
+ if (isym->st_shndx == SHN_UNDEF)
+ sym_sec = bfd_und_section_ptr;
+ 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;
+ else
+ 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 16bit pc-relative branch into a 10bit pc-relative
+ branch. */
+ /* Paranoia? paranoia... */
+ if (ELF32_R_TYPE (irel->r_info) == (int) R_MSP430_RL_PCREL)
+ {
+ bfd_vma value = symval;
+
+ /* 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 10 bits, note the high value is
+ 1016 as the target will be two bytes closer if we are
+ able to relax. */
+ if ((long) value < 1016 && (long) value > -1016)
+ {
+ int code0 = 0, code1 = 0, code2 = 0;
+ int i;
+ struct rcodes_s *rx;
+
+ /* Get the opcode. */
+ if (irel->r_offset >= 6)
+ code0 = bfd_get_16 (abfd, contents + irel->r_offset - 6);
+
+ if (irel->r_offset >= 4)
+ code1 = bfd_get_16 (abfd, contents + irel->r_offset - 4);
+
+ code2 = bfd_get_16 (abfd, contents + irel->r_offset - 2);
+
+ if (code2 != 0x4010)
+ continue;
+
+ /* Check r4 and r3. */
+ for (i = NUMB_RELAX_CODES - 1; i >= 0; i--)
+ {
+ rx = &rcode[i];
+ if (rx->cdx == 2 && rx->f0 == code0 && rx->f1 == code1)
+ break;
+ else if (rx->cdx == 1 && rx->f1 == code1)
+ break;
+ else if (rx->cdx == 0) /* This is an unconditional jump. */
+ break;
+ }
+
+ /* Check labels:
+ .Label0: ; we do not care about this label
+ jeq +6
+ .Label1: ; make sure there is no label here
+ jl +4
+ .Label2: ; make sure there is no label here
+ br .Label_dst
+
+ So, if there is .Label1 or .Label2 we cannot relax this code.
+ This actually should not happen, cause for relaxable
+ instructions we use RL_PCREL reloc instead of 16_PCREL.
+ Will change this in the future. */
+
+ if (rx->cdx > 0
+ && msp430_elf_symbol_address_p (abfd, sec, isymbuf,
+ irel->r_offset - 2))
+ continue;
+ if (rx->cdx > 1
+ && msp430_elf_symbol_address_p (abfd, sec, isymbuf,
+ irel->r_offset - 4))
+ continue;
+
+ /* Note that we've changed the relocs, section contents, etc. */
+ elf_section_data (sec)->relocs = internal_relocs;
+ elf_section_data (sec)->this_hdr.contents = contents;
+ symtab_hdr->contents = (unsigned char *) isymbuf;
+
+ /* Fix the relocation's type. */
+ if (uses_msp430x_relocs (abfd))
+ {
+ if (rx->labels == 3) /* Handle special cases. */
+ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
+ R_MSP430X_2X_PCREL);
+ else
+ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
+ R_MSP430X_10_PCREL);
+ }
+ else
+ {
+ if (rx->labels == 3) /* Handle special cases. */
+ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
+ R_MSP430_2X_PCREL);
+ else
+ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
+ R_MSP430_10_PCREL);
+ }
+
+ /* Fix the opcode right way. */
+ bfd_put_16 (abfd, rx->t0, contents + irel->r_offset - rx->off);
+ if (rx->t1)
+ bfd_put_16 (abfd, rx->t1,
+ contents + irel->r_offset - rx->off + 2);
+
+ /* Delete bytes. */
+ if (!msp430_elf_relax_delete_bytes (abfd, sec,
+ irel->r_offset - rx->off +
+ rx->ncl, rx->bs))
+ goto error_return;
+
+ /* Handle unconditional jumps. */
+ if (rx->cdx == 0)
+ irel->r_offset -= 2;
+
+ /* That will change things, so, we should relax again.
+ Note that this is not required, and it may be slow. */
+ *again = TRUE;
+ }
+ }
+ }
+
+ if (isymbuf != NULL && symtab_hdr->contents != (unsigned char *) isymbuf)
+ {
+ if (!link_info->keep_memory)
+ free (isymbuf);
+ else
+ {
+ /* Cache the symbols for elf_link_input_bfd. */
+ symtab_hdr->contents = (unsigned char *) isymbuf;
+ }
+ }
+
+ if (contents != NULL
+ && elf_section_data (sec)->this_hdr.contents != contents)
+ {
+ if (!link_info->keep_memory)
+ free (contents);
+ else
+ {
+ /* Cache the section contents for elf_link_input_bfd. */
+ elf_section_data (sec)->this_hdr.contents = contents;
+ }
+ }
+
+ if (internal_relocs != NULL
+ && elf_section_data (sec)->relocs != internal_relocs)
+ free (internal_relocs);
+
+ return TRUE;
+
+error_return:
+ if (isymbuf != NULL && symtab_hdr->contents != (unsigned char *) isymbuf)
+ free (isymbuf);
+ if (contents != NULL
+ && elf_section_data (sec)->this_hdr.contents != contents)
+ free (contents);
+ if (internal_relocs != NULL
+ && elf_section_data (sec)->relocs != internal_relocs)
+ free (internal_relocs);
+
+ return FALSE;
+}
+
+/* Handle an MSP430 specific section when reading an object file.
+ This is called when bfd_section_from_shdr finds a section with
+ an unknown type. */
+
+static bfd_boolean
+elf32_msp430_section_from_shdr (bfd *abfd,
+ Elf_Internal_Shdr * hdr,
+ const char *name,
+ int shindex)
+{
+ switch (hdr->sh_type)
+ {
+ case SHT_MSP430_SEC_FLAGS:
+ case SHT_MSP430_SYM_ALIASES:
+ case SHT_MSP430_ATTRIBUTES:
+ return _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex);
+ default:
+ return FALSE;
+ }
+}
+
+static bfd_boolean
+elf32_msp430_obj_attrs_handle_unknown (bfd *abfd, int tag)
+{
+ _bfd_error_handler
+ (_("Warning: %B: Unknown MSPABI object attribute %d"),
+ abfd, tag);
+ return TRUE;
+}
+
+/* Determine whether an object attribute tag takes an integer, a
+ string or both. */
+
+static int
+elf32_msp430_obj_attrs_arg_type (int tag)
+{
+ if (tag == Tag_compatibility)
+ return ATTR_TYPE_FLAG_INT_VAL | ATTR_TYPE_FLAG_STR_VAL;
+
+ if (tag < 32)
+ return ATTR_TYPE_FLAG_INT_VAL;
+
+ return (tag & 1) != 0 ? ATTR_TYPE_FLAG_STR_VAL : ATTR_TYPE_FLAG_INT_VAL;
+}
+
+static inline const char *
+isa_type (int isa)
+{
+ switch (isa)
+ {
+ case 1: return "MSP430";
+ case 2: return "MSP430X";
+ default: return "unknown";
+ }
+}
+
+static inline const char *
+code_model (int model)
+{
+ switch (model)
+ {
+ case 1: return "small";
+ case 2: return "large";
+ default: return "unknown";
+ }
+}
+
+static inline const char *
+data_model (int model)
+{
+ switch (model)
+ {
+ case 1: return "small";
+ case 2: return "large";
+ case 3: return "restricted large";
+ default: return "unknown";
+ }
+}
+
+/* Merge MSPABI object attributes from IBFD into OBFD.
+ Raise an error if there are conflicting attributes. */
+
+static bfd_boolean
+elf32_msp430_merge_mspabi_attributes (bfd *ibfd, bfd *obfd)
+{
+ obj_attribute *in_attr;
+ obj_attribute *out_attr;
+ bfd_boolean result = TRUE;
+ static bfd * first_input_bfd = NULL;
+
+ /* Skip linker created files. */
+ if (ibfd->flags & BFD_LINKER_CREATED)
+ return TRUE;
+
+ /* If this is the first real object just copy the attributes. */
+ if (!elf_known_obj_attributes_proc (obfd)[0].i)
+ {
+ _bfd_elf_copy_obj_attributes (ibfd, obfd);
+
+ out_attr = elf_known_obj_attributes_proc (obfd);
+
+ /* Use the Tag_null value to indicate that
+ the attributes have been initialized. */
+ out_attr[0].i = 1;
+
+ first_input_bfd = ibfd;
+ return TRUE;
+ }
+
+ in_attr = elf_known_obj_attributes_proc (ibfd);
+ out_attr = elf_known_obj_attributes_proc (obfd);
+
+ /* The ISAs must be the same. */
+ if (in_attr[OFBA_MSPABI_Tag_ISA].i != out_attr[OFBA_MSPABI_Tag_ISA].i)
+ {
+ _bfd_error_handler
+ (_("error: %B uses %s instructions but %B uses %s"),
+ ibfd, first_input_bfd,
+ isa_type (in_attr[OFBA_MSPABI_Tag_ISA].i),
+ isa_type (out_attr[OFBA_MSPABI_Tag_ISA].i));
+ result = FALSE;
+ }
+
+ /* The code models must be the same. */
+ if (in_attr[OFBA_MSPABI_Tag_Code_Model].i !=
+ out_attr[OFBA_MSPABI_Tag_Code_Model].i)
+ {
+ _bfd_error_handler
+ (_("error: %B uses the %s code model whereas %B uses the %s code model"),
+ ibfd, first_input_bfd,
+ code_model (in_attr[OFBA_MSPABI_Tag_Code_Model].i),
+ code_model (out_attr[OFBA_MSPABI_Tag_Code_Model].i));
+ result = FALSE;
+ }
+
+ /* The large code model is only supported by the MSP430X. */
+ if (in_attr[OFBA_MSPABI_Tag_Code_Model].i == 2
+ && out_attr[OFBA_MSPABI_Tag_ISA].i != 2)
+ {
+ _bfd_error_handler
+ (_("error: %B uses the large code model but %B uses MSP430 instructions"),
+ ibfd, first_input_bfd);
+ result = FALSE;
+ }
+
+ /* The data models must be the same. */
+ if (in_attr[OFBA_MSPABI_Tag_Data_Model].i !=
+ out_attr[OFBA_MSPABI_Tag_Data_Model].i)
+ {
+ _bfd_error_handler
+ (_("error: %B uses the %s data model whereas %B uses the %s data model"),
+ ibfd, first_input_bfd,
+ data_model (in_attr[OFBA_MSPABI_Tag_Data_Model].i),
+ data_model (out_attr[OFBA_MSPABI_Tag_Data_Model].i));
+ result = FALSE;
+ }
+
+ /* The small code model requires the use of the small data model. */
+ if (in_attr[OFBA_MSPABI_Tag_Code_Model].i == 1
+ && out_attr[OFBA_MSPABI_Tag_Data_Model].i != 1)
+ {
+ _bfd_error_handler
+ (_("error: %B uses the small code model but %B uses the %s data model"),
+ ibfd, first_input_bfd,
+ data_model (out_attr[OFBA_MSPABI_Tag_Data_Model].i));
+ result = FALSE;
+ }
+
+ /* The large data models are only supported by the MSP430X. */
+ if (in_attr[OFBA_MSPABI_Tag_Data_Model].i > 1
+ && out_attr[OFBA_MSPABI_Tag_ISA].i != 2)
+ {
+ _bfd_error_handler
+ (_("error: %B uses the %s data model but %B only uses MSP430 instructions"),
+ ibfd, first_input_bfd,
+ data_model (in_attr[OFBA_MSPABI_Tag_Data_Model].i));
+ result = FALSE;
+ }
+
+ return result;
+}
+
+/* Merge backend specific data from an object file to the output
+ object file when linking. */
+
+static bfd_boolean
+elf32_msp430_merge_private_bfd_data (bfd * ibfd, bfd * obfd)
+{
+ /* Make sure that the machine number reflects the most
+ advanced version of the MSP architecture required. */
+#define max(a,b) ((a) > (b) ? (a) : (b))
+ if (bfd_get_mach (ibfd) != bfd_get_mach (obfd))
+ bfd_default_set_arch_mach (obfd, bfd_get_arch (obfd),
+ max (bfd_get_mach (ibfd), bfd_get_mach (obfd)));
+#undef max
+
+ return elf32_msp430_merge_mspabi_attributes (ibfd, obfd);
+}
+
+static bfd_boolean
+msp430_elf_is_target_special_symbol (bfd *abfd, asymbol *sym)
+{
+ return _bfd_elf_is_local_label_name (abfd, sym->name);
+}
+
+/* This is gross. The MSP430 EABI says that (sec 11.5):
+
+ "An implementation may choose to use Rel or Rela
+ type relocations for other relocations."
+
+ But it also says that:
+
+ "Certain relocations are identified as Rela only. [snip]
+ Where Rela is specified, an implementation must honor
+ this requirement."
+
+ There is one relocation marked as requiring RELA - R_MSP430_ABS_HI16 - but
+ to keep things simple we choose to use RELA relocations throughout. The
+ problem is that the TI compiler generates REL relocations, so we have to
+ be able to accept those as well. */
+
+#define elf_backend_may_use_rel_p 1
+#define elf_backend_may_use_rela_p 1
+#define elf_backend_default_use_rela_p 1
+
+#undef elf_backend_obj_attrs_vendor
+#define elf_backend_obj_attrs_vendor "mspabi"
+#undef elf_backend_obj_attrs_section
+#define elf_backend_obj_attrs_section ".MSP430.attributes"
+#undef elf_backend_obj_attrs_section_type
+#define elf_backend_obj_attrs_section_type SHT_MSP430_ATTRIBUTES
+#define elf_backend_section_from_shdr elf32_msp430_section_from_shdr
+#define elf_backend_obj_attrs_handle_unknown elf32_msp430_obj_attrs_handle_unknown
+#undef elf_backend_obj_attrs_arg_type
+#define elf_backend_obj_attrs_arg_type elf32_msp430_obj_attrs_arg_type
+#define bfd_elf32_bfd_merge_private_bfd_data elf32_msp430_merge_private_bfd_data
+
+#define ELF_ARCH bfd_arch_msp430
+#define ELF_MACHINE_CODE EM_MSP430
+#define ELF_MACHINE_ALT1 EM_MSP430_OLD
+#define ELF_MAXPAGESIZE 4
+#define ELF_OSABI ELFOSABI_STANDALONE
+
+#define TARGET_LITTLE_SYM msp430_elf32_vec
+#define TARGET_LITTLE_NAME "elf32-msp430"
+
+#define elf_info_to_howto msp430_info_to_howto_rela
+#define elf_info_to_howto_rel NULL
+#define elf_backend_relocate_section elf32_msp430_relocate_section
+#define elf_backend_check_relocs elf32_msp430_check_relocs
+#define elf_backend_can_gc_sections 1
+#define elf_backend_final_write_processing bfd_elf_msp430_final_write_processing
+#define elf_backend_object_p elf32_msp430_object_p
+#define bfd_elf32_bfd_relax_section msp430_elf_relax_section
+#define bfd_elf32_bfd_is_target_special_symbol msp430_elf_is_target_special_symbol
+
+#undef elf32_bed
+#define elf32_bed elf32_msp430_bed
+
+#include "elf32-target.h"
+
+/* The TI compiler sets the OSABI field to ELFOSABI_NONE. */
+#undef TARGET_LITTLE_SYM
+#define TARGET_LITTLE_SYM msp430_elf32_ti_vec
+
+#undef elf32_bed
+#define elf32_bed elf32_msp430_ti_bed
+
+#undef ELF_OSABI
+#define ELF_OSABI ELFOSABI_NONE
+
+static const struct bfd_elf_special_section msp430_ti_elf_special_sections[] =
+{
+ /* prefix, prefix_length, suffix_len, type, attributes. */
+ { STRING_COMMA_LEN (".TI.symbol.alias"), 0, SHT_MSP430_SYM_ALIASES, 0 },
+ { STRING_COMMA_LEN (".TI.section.flags"), 0, SHT_MSP430_SEC_FLAGS, 0 },
+ { STRING_COMMA_LEN ("_TI_build_attrib"), 0, SHT_MSP430_ATTRIBUTES, 0 },
+ { NULL, 0, 0, 0, 0 }
+};
+
+#include "elf32-target.h"
diff --git a/bfd/elf32-mt.c b/bfd/elf32-mt.c
new file mode 100644
index 0000000..6df1521
--- /dev/null
+++ b/bfd/elf32-mt.c
@@ -0,0 +1,601 @@
+/* Morpho Technologies MT specific support for 32-bit ELF
+ Copyright (C) 2001-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public 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 "bfd.h"
+#include "libbfd.h"
+#include "elf-bfd.h"
+#include "elf/mt.h"
+
+/* Prototypes. */
+static reloc_howto_type * mt_reloc_type_lookup
+ (bfd *, bfd_reloc_code_real_type);
+
+static void mt_info_to_howto_rela
+ (bfd *, arelent *, Elf_Internal_Rela *);
+
+static bfd_reloc_status_type mt_elf_relocate_hi16
+ (bfd *, Elf_Internal_Rela *, bfd_byte *, bfd_vma);
+
+static bfd_reloc_status_type mt_final_link_relocate
+ (reloc_howto_type *, bfd *, asection *, bfd_byte *,
+ Elf_Internal_Rela *, bfd_vma);
+
+static bfd_boolean mt_elf_relocate_section
+ (bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
+ Elf_Internal_Rela *, Elf_Internal_Sym *, asection **);
+
+/* Relocation tables. */
+static reloc_howto_type mt_elf_howto_table [] =
+{
+ /* This reloc does nothing. */
+ HOWTO (R_MT_NONE, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MT_NONE", /* name */
+ FALSE, /* partial_inplace */
+ 0 , /* src_mask */
+ 0, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A 16 bit absolute relocation. */
+ HOWTO (R_MT_16, /* 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_MT_16", /* name */
+ FALSE, /* partial_inplace */
+ 0 , /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A 32 bit absolute relocation. */
+ HOWTO (R_MT_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 */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MT_32", /* name */
+ FALSE, /* partial_inplace */
+ 0 , /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A 32 bit pc-relative relocation. */
+ HOWTO (R_MT_32_PCREL, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MT_32_PCREL", /* name */
+ FALSE, /* partial_inplace */
+ 0 , /* src_mask */
+ 0xffffffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* A 16 bit pc-relative relocation. */
+ HOWTO (R_MT_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_MT_PC16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* high 16 bits of symbol value. */
+ HOWTO (R_MT_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_MT_HI16", /* name */
+ FALSE, /* partial_inplace */
+ 0xffff0000, /* src_mask */
+ 0xffff0000, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Low 16 bits of symbol value. */
+ HOWTO (R_MT_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_MT_LO16", /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+};
+
+/* Map BFD reloc types to MT ELF reloc types. */
+
+static reloc_howto_type *
+mt_reloc_type_lookup
+ (bfd * abfd ATTRIBUTE_UNUSED,
+ bfd_reloc_code_real_type code)
+{
+ /* Note that the mt_elf_howto_table is indxed by the R_
+ constants. Thus, the order that the howto records appear in the
+ table *must* match the order of the relocation types defined in
+ include/elf/mt.h. */
+
+ switch (code)
+ {
+ case BFD_RELOC_NONE:
+ return &mt_elf_howto_table[ (int) R_MT_NONE];
+ case BFD_RELOC_16:
+ return &mt_elf_howto_table[ (int) R_MT_16];
+ case BFD_RELOC_32:
+ return &mt_elf_howto_table[ (int) R_MT_32];
+ case BFD_RELOC_32_PCREL:
+ return &mt_elf_howto_table[ (int) R_MT_32_PCREL];
+ case BFD_RELOC_16_PCREL:
+ return &mt_elf_howto_table[ (int) R_MT_PC16];
+ case BFD_RELOC_HI16:
+ return &mt_elf_howto_table[ (int) R_MT_HI16];
+ case BFD_RELOC_LO16:
+ return &mt_elf_howto_table[ (int) R_MT_LO16];
+
+ default:
+ /* Pacify gcc -Wall. */
+ return NULL;
+ }
+ return NULL;
+}
+
+static reloc_howto_type *
+mt_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ const char *r_name)
+{
+ unsigned int i;
+
+ for (i = 0;
+ i < sizeof (mt_elf_howto_table) / sizeof (mt_elf_howto_table[0]);
+ i++)
+ if (mt_elf_howto_table[i].name != NULL
+ && strcasecmp (mt_elf_howto_table[i].name, r_name) == 0)
+ return &mt_elf_howto_table[i];
+
+ return NULL;
+}
+
+bfd_reloc_status_type
+mt_elf_relocate_hi16
+ (bfd * input_bfd,
+ Elf_Internal_Rela * relhi,
+ bfd_byte * contents,
+ bfd_vma value)
+{
+ bfd_vma insn;
+
+ insn = bfd_get_32 (input_bfd, contents + relhi->r_offset);
+
+ value += relhi->r_addend;
+ value >>= 16;
+ insn = ((insn & ~0xFFFF) | value);
+
+ bfd_put_32 (input_bfd, insn, contents + relhi->r_offset);
+ return bfd_reloc_ok;
+}
+
+/* XXX: The following code is the result of a cut&paste. This unfortunate
+ practice is very widespread in the various target back-end files. */
+
+/* Set the howto pointer for a MT ELF reloc. */
+
+static void
+mt_info_to_howto_rela
+ (bfd * abfd ATTRIBUTE_UNUSED,
+ arelent * cache_ptr,
+ Elf_Internal_Rela * dst)
+{
+ unsigned int r_type;
+
+ r_type = ELF32_R_TYPE (dst->r_info);
+ cache_ptr->howto = & mt_elf_howto_table [r_type];
+}
+
+/* Perform a single relocation. By default we use the standard BFD
+ routines. */
+
+static bfd_reloc_status_type
+mt_final_link_relocate
+ (reloc_howto_type * howto,
+ bfd * input_bfd,
+ asection * input_section,
+ bfd_byte * contents,
+ Elf_Internal_Rela * rel,
+ bfd_vma relocation)
+{
+ return _bfd_final_link_relocate (howto, input_bfd, input_section,
+ contents, rel->r_offset,
+ relocation, rel->r_addend);
+}
+
+/* Relocate a MT 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 relocatable
+ 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 relocatable 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 bfd_boolean
+mt_elf_relocate_section
+ (bfd * output_bfd ATTRIBUTE_UNUSED,
+ 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);
+
+ r_symndx = ELF32_R_SYM (rel->r_info);
+
+ howto = mt_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 = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
+
+ 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;
+ }
+ else
+ {
+ bfd_boolean unresolved_reloc;
+ bfd_boolean warned, ignored;
+
+ RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
+ r_symndx, symtab_hdr, sym_hashes,
+ h, sec, relocation,
+ unresolved_reloc, warned, ignored);
+
+ name = h->root.root.string;
+ }
+
+ if (sec != NULL && discarded_section (sec))
+ RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+ rel, 1, relend, howto, 0, contents);
+
+ if (info->relocatable)
+ continue;
+
+ /* Finally, the sole MT-specific part. */
+ switch (r_type)
+ {
+ case R_MT_HI16:
+ r = mt_elf_relocate_hi16 (input_bfd, rel, contents, relocation);
+ break;
+ default:
+ r = mt_final_link_relocate (howto, input_bfd, input_section,
+ contents, rel, relocation);
+ break;
+ }
+
+
+ if (r != bfd_reloc_ok)
+ {
+ const char * msg = (const char *) NULL;
+
+ switch (r)
+ {
+ case bfd_reloc_overflow:
+ r = info->callbacks->reloc_overflow
+ (info, (h ? &h->root : NULL), 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, TRUE);
+ break;
+
+ case bfd_reloc_outofrange:
+ msg = _("internal error: out of range 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;
+}
+
+/* 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 bfd_boolean
+mt_elf_check_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;
+ const Elf_Internal_Rela * rel;
+ const Elf_Internal_Rela * rel_end;
+
+ if (info->relocatable)
+ return TRUE;
+
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+ sym_hashes = elf_sym_hashes (abfd);
+
+ 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];
+ 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;
+
+ /* PR15323, ref flags aren't set for references in the same
+ object. */
+ h->root.non_ir_ref = 1;
+ }
+ }
+
+ return TRUE;
+}
+
+/* Return the MACH for an e_flags value. */
+
+static int
+elf32_mt_machine (bfd *abfd)
+{
+ switch (elf_elfheader (abfd)->e_flags & EF_MT_CPU_MASK)
+ {
+ case EF_MT_CPU_MRISC: return bfd_mach_ms1;
+ case EF_MT_CPU_MRISC2: return bfd_mach_mrisc2;
+ case EF_MT_CPU_MS2: return bfd_mach_ms2;
+ }
+
+ return bfd_mach_ms1;
+}
+
+static bfd_boolean
+mt_elf_object_p (bfd * abfd)
+{
+ bfd_default_set_arch_mach (abfd, bfd_arch_mt, elf32_mt_machine (abfd));
+
+ return TRUE;
+}
+
+/* Function to set the ELF flag bits. */
+
+static bfd_boolean
+mt_elf_set_private_flags (bfd * abfd,
+ flagword flags)
+{
+ elf_elfheader (abfd)->e_flags = flags;
+ elf_flags_init (abfd) = TRUE;
+ return TRUE;
+}
+
+/* Merge backend specific data from an object file to the output
+ object file when linking. */
+
+static bfd_boolean
+mt_elf_merge_private_bfd_data (bfd * ibfd, bfd * obfd)
+{
+ flagword old_flags, new_flags;
+ bfd_boolean ok = TRUE;
+
+ /* Check if we have the same endianness. */
+ if (_bfd_generic_verify_endian_match (ibfd, obfd) == FALSE)
+ return FALSE;
+
+ /* If they're not both mt, then merging is meaningless, so just
+ don't do it. */
+ if (strcmp (ibfd->arch_info->arch_name, "mt") != 0)
+ return TRUE;
+ if (strcmp (obfd->arch_info->arch_name, "mt") != 0)
+ return TRUE;
+
+ new_flags = elf_elfheader (ibfd)->e_flags;
+ old_flags = elf_elfheader (obfd)->e_flags;
+
+#ifdef DEBUG
+ _bfd_error_handler ("%B: old_flags = 0x%.8lx, new_flags = 0x%.8lx, init = %s",
+ ibfd, old_flags, new_flags, elf_flags_init (obfd) ? "yes" : "no");
+#endif
+
+ if (!elf_flags_init (obfd))
+ {
+ old_flags = new_flags;
+ elf_flags_init (obfd) = TRUE;
+ }
+ else if ((new_flags & EF_MT_CPU_MASK) != (old_flags & EF_MT_CPU_MASK))
+ {
+ /* CPU has changed. This is invalid, because MRISC, MRISC2 and
+ MS2 are not subsets of each other. */
+ ok = FALSE;
+ }
+
+ if (ok)
+ {
+ obfd->arch_info = ibfd->arch_info;
+ elf_elfheader (obfd)->e_flags = old_flags;
+ }
+
+ return ok;
+}
+
+static bfd_boolean
+mt_elf_print_private_bfd_data (bfd * abfd, void * ptr)
+{
+ FILE * file = (FILE *) ptr;
+ flagword flags;
+
+ BFD_ASSERT (abfd != NULL && ptr != NULL);
+
+ /* Print normal ELF private data. */
+ _bfd_elf_print_private_bfd_data (abfd, ptr);
+
+ flags = elf_elfheader (abfd)->e_flags;
+ fprintf (file, _("private flags = 0x%lx:"), (unsigned long) flags);
+
+ switch (flags & EF_MT_CPU_MASK)
+ {
+ default:
+ case EF_MT_CPU_MRISC: fprintf (file, " ms1-16-002"); break;
+ case EF_MT_CPU_MRISC2: fprintf (file, " ms1-16-003"); break;
+ case EF_MT_CPU_MS2: fprintf (file, " ms2"); break;
+ }
+
+ fputc ('\n', file);
+
+ return TRUE;
+}
+
+
+#define TARGET_BIG_SYM mt_elf32_vec
+#define TARGET_BIG_NAME "elf32-mt"
+
+#define ELF_ARCH bfd_arch_mt
+#define ELF_MACHINE_CODE EM_MT
+#define ELF_MAXPAGESIZE 1 /* No pages on the MT. */
+
+#define elf_info_to_howto_rel NULL
+#define elf_info_to_howto mt_info_to_howto_rela
+
+#define elf_backend_relocate_section mt_elf_relocate_section
+
+#define bfd_elf32_bfd_reloc_type_lookup mt_reloc_type_lookup
+#define bfd_elf32_bfd_reloc_name_lookup mt_reloc_name_lookup
+
+#define elf_backend_check_relocs mt_elf_check_relocs
+#define elf_backend_object_p mt_elf_object_p
+#define elf_backend_rela_normal 1
+
+#define elf_backend_can_gc_sections 1
+
+#define bfd_elf32_bfd_set_private_flags mt_elf_set_private_flags
+#define bfd_elf32_bfd_merge_private_bfd_data mt_elf_merge_private_bfd_data
+#define bfd_elf32_bfd_print_private_bfd_data mt_elf_print_private_bfd_data
+
+#include "elf32-target.h"
diff --git a/bfd/elf32-nds32.c b/bfd/elf32-nds32.c
new file mode 100644
index 0000000..2b63024
--- /dev/null
+++ b/bfd/elf32-nds32.c
@@ -0,0 +1,15722 @@
+/* NDS32-specific support for 32-bit ELF.
+ Copyright (C) 2012-2014 Free Software Foundation, Inc.
+ Contributed by Andes Technology Corporation.
+
+ This file is part of BFD, the Binary File Descriptor library.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
+ 02110-1301, USA. */
+
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "bfd_stdint.h"
+#include "bfdlink.h"
+#include "libbfd.h"
+#include "elf-bfd.h"
+#include "libiberty.h"
+#include "bfd_stdint.h"
+#include "elf/nds32.h"
+#include "opcode/nds32.h"
+#include "elf32-nds32.h"
+#include "opcode/cgen.h"
+#include "../opcodes/nds32-opc.h"
+
+/* Relocation HOWTO functions. */
+static bfd_reloc_status_type nds32_elf_ignore_reloc
+ (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
+static bfd_reloc_status_type nds32_elf_9_pcrel_reloc
+ (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
+static bfd_reloc_status_type nds32_elf_hi20_reloc
+ (bfd *, arelent *, asymbol *, void *,
+ asection *, bfd *, char **);
+static bfd_reloc_status_type nds32_elf_lo12_reloc
+ (bfd *, arelent *, asymbol *, void *,
+ asection *, bfd *, char **);
+static bfd_reloc_status_type nds32_elf_generic_reloc
+ (bfd *, arelent *, asymbol *, void *,
+ asection *, bfd *, char **);
+static bfd_reloc_status_type nds32_elf_sda15_reloc
+ (bfd *, arelent *, asymbol *, void *,
+ asection *, bfd *, char **);
+
+/* Helper functions for HOWTO. */
+static bfd_reloc_status_type nds32_elf_do_9_pcrel_reloc
+ (bfd *, reloc_howto_type *, asection *, bfd_byte *, bfd_vma,
+ asection *, bfd_vma, bfd_vma);
+static void nds32_elf_relocate_hi20
+ (bfd *, int, Elf_Internal_Rela *, Elf_Internal_Rela *, bfd_byte *, bfd_vma);
+static reloc_howto_type *bfd_elf32_bfd_reloc_type_table_lookup
+ (enum elf_nds32_reloc_type);
+static reloc_howto_type *bfd_elf32_bfd_reloc_type_lookup
+ (bfd *, bfd_reloc_code_real_type);
+
+/* Target hooks. */
+static void nds32_info_to_howto_rel
+ (bfd *, arelent *, Elf_Internal_Rela *dst);
+static void nds32_info_to_howto
+ (bfd *, arelent *, Elf_Internal_Rela *dst);
+static bfd_boolean nds32_elf_add_symbol_hook
+ (bfd *, struct bfd_link_info *, Elf_Internal_Sym *, const char **,
+ flagword *, asection **, bfd_vma *);
+static bfd_boolean nds32_elf_relocate_section
+ (bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
+ Elf_Internal_Rela *, Elf_Internal_Sym *, asection **);
+static bfd_boolean nds32_elf_object_p (bfd *);
+static void nds32_elf_final_write_processing (bfd *, bfd_boolean);
+static bfd_boolean nds32_elf_set_private_flags (bfd *, flagword);
+static bfd_boolean nds32_elf_merge_private_bfd_data (bfd *, bfd *);
+static bfd_boolean nds32_elf_print_private_bfd_data (bfd *, void *);
+static bfd_boolean nds32_elf_gc_sweep_hook
+ (bfd *, struct bfd_link_info *, asection *, const Elf_Internal_Rela *);
+static bfd_boolean nds32_elf_check_relocs
+ (bfd *, struct bfd_link_info *, asection *, const Elf_Internal_Rela *);
+static asection *nds32_elf_gc_mark_hook
+ (asection *, struct bfd_link_info *, Elf_Internal_Rela *,
+ struct elf_link_hash_entry *, Elf_Internal_Sym *);
+static bfd_boolean nds32_elf_adjust_dynamic_symbol
+ (struct bfd_link_info *, struct elf_link_hash_entry *);
+static bfd_boolean nds32_elf_size_dynamic_sections
+ (bfd *, struct bfd_link_info *);
+static bfd_boolean nds32_elf_create_dynamic_sections
+ (bfd *, struct bfd_link_info *);
+static bfd_boolean nds32_elf_finish_dynamic_sections
+ (bfd *, struct bfd_link_info *info);
+static bfd_boolean nds32_elf_finish_dynamic_symbol
+ (bfd *, struct bfd_link_info *, struct elf_link_hash_entry *,
+ Elf_Internal_Sym *);
+static bfd_boolean nds32_elf_mkobject (bfd *);
+
+/* Nds32 helper functions. */
+static bfd_reloc_status_type nds32_elf_final_sda_base
+ (bfd *, struct bfd_link_info *, bfd_vma *, bfd_boolean);
+static bfd_boolean allocate_dynrelocs (struct elf_link_hash_entry *, void *);
+static bfd_boolean readonly_dynrelocs (struct elf_link_hash_entry *, void *);
+static Elf_Internal_Rela *find_relocs_at_address
+ (Elf_Internal_Rela *, Elf_Internal_Rela *,
+ Elf_Internal_Rela *, enum elf_nds32_reloc_type);
+static bfd_vma calculate_memory_address
+ (bfd *, Elf_Internal_Rela *, Elf_Internal_Sym *, Elf_Internal_Shdr *);
+static int nds32_get_section_contents (bfd *, asection *, bfd_byte **);
+static bfd_boolean nds32_elf_ex9_build_hash_table
+ (bfd *, asection *, struct bfd_link_info *);
+static bfd_boolean nds32_elf_ex9_itb_base (struct bfd_link_info *);
+static void nds32_elf_ex9_import_table (struct bfd_link_info *);
+static void nds32_elf_ex9_finish (struct bfd_link_info *);
+static void nds32_elf_ex9_reloc_jmp (struct bfd_link_info *);
+static void nds32_elf_get_insn_with_reg
+ (Elf_Internal_Rela *, uint32_t, uint32_t *);
+static int nds32_get_local_syms (bfd *, asection *ATTRIBUTE_UNUSED,
+ Elf_Internal_Sym **);
+static bfd_boolean nds32_elf_ex9_replace_instruction
+ (struct bfd_link_info *, bfd *, asection *);
+static bfd_boolean nds32_elf_ifc_calc (struct bfd_link_info *, bfd *,
+ asection *);
+static bfd_boolean nds32_elf_ifc_finish (struct bfd_link_info *);
+static bfd_boolean nds32_elf_ifc_replace (struct bfd_link_info *);
+static bfd_boolean nds32_elf_ifc_reloc (void);
+static bfd_boolean nds32_relax_fp_as_gp
+ (struct bfd_link_info *link_info, bfd *abfd, asection *sec,
+ Elf_Internal_Rela *internal_relocs, Elf_Internal_Rela *irelend,
+ Elf_Internal_Sym *isymbuf);
+static bfd_boolean nds32_fag_remove_unused_fpbase
+ (bfd *abfd, asection *sec, Elf_Internal_Rela *internal_relocs,
+ Elf_Internal_Rela *irelend);
+static bfd_byte *
+nds32_elf_get_relocated_section_contents (bfd *abfd,
+ struct bfd_link_info *link_info,
+ struct bfd_link_order *link_order,
+ bfd_byte *data,
+ bfd_boolean relocatable,
+ asymbol **symbols);
+
+enum
+{
+ MACH_V1 = bfd_mach_n1h,
+ MACH_V2 = bfd_mach_n1h_v2,
+ MACH_V3 = bfd_mach_n1h_v3,
+ MACH_V3M = bfd_mach_n1h_v3m
+};
+
+#define MIN(a, b) ((a) > (b) ? (b) : (a))
+#define MAX(a, b) ((a) > (b) ? (a) : (b))
+
+/* 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 NDS32_NOP32 0x40000009
+#define NDS32_NOP16 0x9200
+
+/* The size in bytes of an entry in the procedure linkage table. */
+#define PLT_ENTRY_SIZE 24
+#define PLT_HEADER_SIZE 24
+
+/* The first entry in a procedure linkage table are reserved,
+ and the initial contents are unimportant (we zero them out).
+ Subsequent entries look like this. */
+#define PLT0_ENTRY_WORD0 0x46f00000 /* sethi r15, HI20(.got+4) */
+#define PLT0_ENTRY_WORD1 0x58f78000 /* ori r15, r25, LO12(.got+4) */
+#define PLT0_ENTRY_WORD2 0x05178000 /* lwi r17, [r15+0] */
+#define PLT0_ENTRY_WORD3 0x04f78001 /* lwi r15, [r15+4] */
+#define PLT0_ENTRY_WORD4 0x4a003c00 /* jr r15 */
+
+/* $ta is change to $r15 (from $r25). */
+#define PLT0_PIC_ENTRY_WORD0 0x46f00000 /* sethi r15, HI20(got[1]@GOT) */
+#define PLT0_PIC_ENTRY_WORD1 0x58f78000 /* ori r15, r15, LO12(got[1]@GOT) */
+#define PLT0_PIC_ENTRY_WORD2 0x40f7f400 /* add r15, gp, r15 */
+#define PLT0_PIC_ENTRY_WORD3 0x05178000 /* lwi r17, [r15+0] */
+#define PLT0_PIC_ENTRY_WORD4 0x04f78001 /* lwi r15, [r15+4] */
+#define PLT0_PIC_ENTRY_WORD5 0x4a003c00 /* jr r15 */
+
+#define PLT_ENTRY_WORD0 0x46f00000 /* sethi r15, HI20(&got[n+3]) */
+#define PLT_ENTRY_WORD1 0x04f78000 /* lwi r15, r15, LO12(&got[n+3]) */
+#define PLT_ENTRY_WORD2 0x4a003c00 /* jr r15 */
+#define PLT_ENTRY_WORD3 0x45000000 /* movi r16, sizeof(RELA) * n */
+#define PLT_ENTRY_WORD4 0x48000000 /* j .plt0. */
+
+#define PLT_PIC_ENTRY_WORD0 0x46f00000 /* sethi r15, HI20(got[n+3]@GOT) */
+#define PLT_PIC_ENTRY_WORD1 0x58f78000 /* ori r15, r15, LO12(got[n+3]@GOT) */
+#define PLT_PIC_ENTRY_WORD2 0x38febc02 /* lw r15, [gp+r15] */
+#define PLT_PIC_ENTRY_WORD3 0x4a003c00 /* jr r15 */
+#define PLT_PIC_ENTRY_WORD4 0x45000000 /* movi r16, sizeof(RELA) * n */
+#define PLT_PIC_ENTRY_WORD5 0x48000000 /* j .plt0 */
+
+/* These are macros used to get the relocation accurate value. */
+#define ACCURATE_8BIT_S1 (0x100)
+#define ACCURATE_U9BIT_S1 (0x400)
+#define ACCURATE_12BIT_S1 (0x2000)
+#define ACCURATE_14BIT_S1 (0x4000)
+#define ACCURATE_19BIT (0x40000)
+
+/* These are macros used to get the relocation conservative value. */
+#define CONSERVATIVE_8BIT_S1 (0x100 - 4)
+#define CONSERVATIVE_14BIT_S1 (0x4000 - 4)
+#define CONSERVATIVE_16BIT_S1 (0x10000 - 4)
+#define CONSERVATIVE_24BIT_S1 (0x1000000 - 4)
+/* These must be more conservative because the address may be in
+ different segment. */
+#define CONSERVATIVE_15BIT (0x4000 - 0x1000)
+#define CONSERVATIVE_15BIT_S1 (0x8000 - 0x1000)
+#define CONSERVATIVE_15BIT_S2 (0x10000 - 0x1000)
+#define CONSERVATIVE_19BIT (0x40000 - 0x1000)
+#define CONSERVATIVE_20BIT (0x80000 - 0x1000)
+
+/* Size of small data/bss sections, used to calculate SDA_BASE. */
+static long got_size = 0;
+static int is_SDA_BASE_set = 0;
+static int is_ITB_BASE_set = 0;
+
+/* Convert ELF-VER in eflags to string for debugging purpose. */
+static const char *const nds32_elfver_strtab[] =
+{
+ "ELF-1.2",
+ "ELF-1.3",
+ "ELF-1.4",
+};
+
+/* The nds32 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_nds32_pcrel_relocs_copied
+{
+ /* Next section. */
+ struct elf_nds32_pcrel_relocs_copied *next;
+ /* A section in dynobj. */
+ asection *section;
+ /* Number of relocs copied in this section. */
+ bfd_size_type count;
+};
+
+/* The sh linker needs to keep track of the number of relocs that it
+ decides to copy as dynamic relocs in check_relocs for each symbol.
+ This is so that it can later discard them if they are found to be
+ unnecessary. We store the information in a field extending the
+ regular ELF linker hash table. */
+
+struct elf_nds32_dyn_relocs
+{
+ struct elf_nds32_dyn_relocs *next;
+
+ /* The input section of the reloc. */
+ asection *sec;
+
+ /* Total number of relocs copied for the input section. */
+ bfd_size_type count;
+
+ /* Number of pc-relative relocs copied for the input section. */
+ bfd_size_type pc_count;
+};
+
+/* Nds32 ELF linker hash entry. */
+
+struct elf_nds32_link_hash_entry
+{
+ struct elf_link_hash_entry root;
+
+ /* Track dynamic relocs copied for this symbol. */
+ struct elf_nds32_dyn_relocs *dyn_relocs;
+
+ /* For checking relocation type. */
+#define GOT_UNKNOWN 0
+#define GOT_NORMAL 1
+#define GOT_TLS_IE 2
+ unsigned int tls_type;
+};
+
+/* Get the nds32 ELF linker hash table from a link_info structure. */
+
+#define FP_BASE_NAME "_FP_BASE_"
+static int check_start_export_sym = 0;
+static size_t ex9_relax_size = 0; /* Save ex9 predicted reducing size. */
+
+/* The offset for executable tls relaxation. */
+#define TP_OFFSET 0x0
+
+struct elf_nds32_obj_tdata
+{
+ struct elf_obj_tdata root;
+
+ /* tls_type for each local got entry. */
+ char *local_got_tls_type;
+};
+
+#define elf_nds32_tdata(bfd) \
+ ((struct elf_nds32_obj_tdata *) (bfd)->tdata.any)
+
+#define elf32_nds32_local_got_tls_type(bfd) \
+ (elf_nds32_tdata (bfd)->local_got_tls_type)
+
+#define elf32_nds32_hash_entry(ent) ((struct elf_nds32_link_hash_entry *)(ent))
+
+static bfd_boolean
+nds32_elf_mkobject (bfd *abfd)
+{
+ return bfd_elf_allocate_object (abfd, sizeof (struct elf_nds32_obj_tdata),
+ NDS32_ELF_DATA);
+}
+
+/* Relocations used for relocation. */
+static reloc_howto_type nds32_elf_howto_table[] =
+{
+ /* This reloc does nothing. */
+ HOWTO (R_NDS32_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_NDS32_NONE", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A 16 bit absolute relocation. */
+ HOWTO (R_NDS32_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 */
+ nds32_elf_generic_reloc, /* special_function */
+ "R_NDS32_16", /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A 32 bit absolute relocation. */
+ HOWTO (R_NDS32_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 */
+ nds32_elf_generic_reloc, /* special_function */
+ "R_NDS32_32", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A 20 bit address. */
+ HOWTO (R_NDS32_20, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 20, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_unsigned, /* complain_on_overflow */
+ nds32_elf_generic_reloc, /* special_function */
+ "R_NDS32_20", /* name */
+ FALSE, /* partial_inplace */
+ 0xfffff, /* src_mask */
+ 0xfffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* An PC Relative 9-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_NDS32_9_PCREL, /* type */
+ 1, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 8, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ nds32_elf_9_pcrel_reloc, /* special_function */
+ "R_NDS32_9_PCREL", /* name */
+ FALSE, /* partial_inplace */
+ 0xff, /* src_mask */
+ 0xff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* A relative 15 bit relocation, right shifted by 1. */
+ HOWTO (R_NDS32_15_PCREL, /* type */
+ 1, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 14, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_NDS32_15_PCREL", /* name */
+ FALSE, /* partial_inplace */
+ 0x3fff, /* src_mask */
+ 0x3fff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* A relative 17 bit relocation, right shifted by 1. */
+ HOWTO (R_NDS32_17_PCREL, /* type */
+ 1, /* 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_NDS32_17_PCREL", /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* A relative 25 bit relocation, right shifted by 1. */
+ /* ??? 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_NDS32_25_PCREL, /* type */
+ 1, /* 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_NDS32_25_PCREL", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffff, /* src_mask */
+ 0xffffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* High 20 bits of address when lower 12 is or'd in. */
+ HOWTO (R_NDS32_HI20, /* type */
+ 12, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 20, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ nds32_elf_hi20_reloc, /* special_function */
+ "R_NDS32_HI20", /* name */
+ FALSE, /* partial_inplace */
+ 0x000fffff, /* src_mask */
+ 0x000fffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Lower 12 bits of address. */
+ HOWTO (R_NDS32_LO12S3, /* type */
+ 3, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 9, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ nds32_elf_lo12_reloc, /* special_function */
+ "R_NDS32_LO12S3", /* name */
+ FALSE, /* partial_inplace */
+ 0x000001ff, /* src_mask */
+ 0x000001ff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Lower 12 bits of address. */
+ HOWTO (R_NDS32_LO12S2, /* type */
+ 2, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 10, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ nds32_elf_lo12_reloc, /* special_function */
+ "R_NDS32_LO12S2", /* name */
+ FALSE, /* partial_inplace */
+ 0x000003ff, /* src_mask */
+ 0x000003ff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Lower 12 bits of address. */
+ HOWTO (R_NDS32_LO12S1, /* type */
+ 1, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 11, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ nds32_elf_lo12_reloc, /* special_function */
+ "R_NDS32_LO12S1", /* name */
+ FALSE, /* partial_inplace */
+ 0x000007ff, /* src_mask */
+ 0x000007ff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Lower 12 bits of address. */
+ HOWTO (R_NDS32_LO12S0, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 12, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ nds32_elf_lo12_reloc, /* special_function */
+ "R_NDS32_LO12S0", /* name */
+ FALSE, /* partial_inplace */
+ 0x00000fff, /* src_mask */
+ 0x00000fff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Small data area 15 bits offset. */
+ HOWTO (R_NDS32_SDA15S3, /* type */
+ 3, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 15, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ nds32_elf_sda15_reloc, /* special_function */
+ "R_NDS32_SDA15S3", /* name */
+ FALSE, /* partial_inplace */
+ 0x00007fff, /* src_mask */
+ 0x00007fff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Small data area 15 bits offset. */
+ HOWTO (R_NDS32_SDA15S2, /* type */
+ 2, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 15, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ nds32_elf_sda15_reloc, /* special_function */
+ "R_NDS32_SDA15S2", /* name */
+ FALSE, /* partial_inplace */
+ 0x00007fff, /* src_mask */
+ 0x00007fff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Small data area 15 bits offset. */
+ HOWTO (R_NDS32_SDA15S1, /* type */
+ 1, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 15, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ nds32_elf_sda15_reloc, /* special_function */
+ "R_NDS32_SDA15S1", /* name */
+ FALSE, /* partial_inplace */
+ 0x00007fff, /* src_mask */
+ 0x00007fff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Small data area 15 bits offset. */
+ HOWTO (R_NDS32_SDA15S0, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 15, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ nds32_elf_sda15_reloc, /* special_function */
+ "R_NDS32_SDA15S0", /* name */
+ FALSE, /* partial_inplace */
+ 0x00007fff, /* src_mask */
+ 0x00007fff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* GNU extension to record C++ vtable hierarchy */
+ HOWTO (R_NDS32_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_NDS32_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_NDS32_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_NDS32_GNU_VTENTRY", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A 16 bit absolute relocation. */
+ HOWTO (R_NDS32_16_RELA, /* 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_NDS32_16_RELA", /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A 32 bit absolute relocation. */
+ HOWTO (R_NDS32_32_RELA, /* 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_NDS32_32_RELA", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A 20 bit address. */
+ HOWTO (R_NDS32_20_RELA, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 20, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_NDS32_20_RELA", /* name */
+ FALSE, /* partial_inplace */
+ 0xfffff, /* src_mask */
+ 0xfffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_NDS32_9_PCREL_RELA, /* 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_NDS32_9_PCREL_RELA",/* name */
+ FALSE, /* partial_inplace */
+ 0xff, /* src_mask */
+ 0xff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* A relative 15 bit relocation, right shifted by 1. */
+ HOWTO (R_NDS32_15_PCREL_RELA, /* type */
+ 1, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 14, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_NDS32_15_PCREL_RELA", /* name */
+ FALSE, /* partial_inplace */
+ 0x3fff, /* src_mask */
+ 0x3fff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* A relative 17 bit relocation, right shifted by 1. */
+ HOWTO (R_NDS32_17_PCREL_RELA, /* type */
+ 1, /* 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_NDS32_17_PCREL_RELA", /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* A relative 25 bit relocation, right shifted by 2. */
+ HOWTO (R_NDS32_25_PCREL_RELA, /* type */
+ 1, /* 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_NDS32_25_PCREL_RELA", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffff, /* src_mask */
+ 0xffffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* High 20 bits of address when lower 16 is or'd in. */
+ HOWTO (R_NDS32_HI20_RELA, /* type */
+ 12, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 20, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_NDS32_HI20_RELA", /* name */
+ FALSE, /* partial_inplace */
+ 0x000fffff, /* src_mask */
+ 0x000fffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Lower 12 bits of address. */
+ HOWTO (R_NDS32_LO12S3_RELA, /* type */
+ 3, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 9, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_NDS32_LO12S3_RELA", /* name */
+ FALSE, /* partial_inplace */
+ 0x000001ff, /* src_mask */
+ 0x000001ff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Lower 12 bits of address. */
+ HOWTO (R_NDS32_LO12S2_RELA, /* type */
+ 2, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 10, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_NDS32_LO12S2_RELA", /* name */
+ FALSE, /* partial_inplace */
+ 0x000003ff, /* src_mask */
+ 0x000003ff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Lower 12 bits of address. */
+ HOWTO (R_NDS32_LO12S1_RELA, /* type */
+ 1, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 11, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_NDS32_LO12S1_RELA", /* name */
+ FALSE, /* partial_inplace */
+ 0x000007ff, /* src_mask */
+ 0x000007ff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Lower 12 bits of address. */
+ HOWTO (R_NDS32_LO12S0_RELA, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 12, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_NDS32_LO12S0_RELA", /* name */
+ FALSE, /* partial_inplace */
+ 0x00000fff, /* src_mask */
+ 0x00000fff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Small data area 15 bits offset. */
+ HOWTO (R_NDS32_SDA15S3_RELA, /* type */
+ 3, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 15, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_NDS32_SDA15S3_RELA",/* name */
+ FALSE, /* partial_inplace */
+ 0x00007fff, /* src_mask */
+ 0x00007fff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Small data area 15 bits offset. */
+ HOWTO (R_NDS32_SDA15S2_RELA, /* type */
+ 2, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 15, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_NDS32_SDA15S2_RELA",/* name */
+ FALSE, /* partial_inplace */
+ 0x00007fff, /* src_mask */
+ 0x00007fff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_NDS32_SDA15S1_RELA, /* type */
+ 1, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 15, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_NDS32_SDA15S1_RELA",/* name */
+ FALSE, /* partial_inplace */
+ 0x00007fff, /* src_mask */
+ 0x00007fff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_NDS32_SDA15S0_RELA, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 15, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_NDS32_SDA15S0_RELA",/* name */
+ FALSE, /* partial_inplace */
+ 0x00007fff, /* src_mask */
+ 0x00007fff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* GNU extension to record C++ vtable hierarchy */
+ HOWTO (R_NDS32_RELA_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_NDS32_RELA_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_NDS32_RELA_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_NDS32_RELA_GNU_VTENTRY", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Like R_NDS32_20, but referring to the GOT table entry for
+ the symbol. */
+ HOWTO (R_NDS32_GOT20, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 20, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_NDS32_GOT20", /* name */
+ FALSE, /* partial_inplace */
+ 0xfffff, /* src_mask */
+ 0xfffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Like R_NDS32_PCREL, but referring to the procedure linkage table
+ entry for the symbol. */
+ HOWTO (R_NDS32_25_PLTREL, /* type */
+ 1, /* 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_NDS32_25_PLTREL", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffff, /* src_mask */
+ 0xffffff, /* 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_NDS32_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_NDS32_COPY", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Like R_NDS32_20, but used when setting global offset table
+ entries. */
+ HOWTO (R_NDS32_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_NDS32_GLOB_DAT", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Marks a procedure linkage table entry for a symbol. */
+ HOWTO (R_NDS32_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_NDS32_JMP_SLOT", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* 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_NDS32_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_NDS32_RELATIVE", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_NDS32_GOTOFF, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 20, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_NDS32_GOTOFF", /* name */
+ FALSE, /* partial_inplace */
+ 0xfffff, /* src_mask */
+ 0xfffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* An PC Relative 20-bit relocation used when setting PIC offset
+ table register. */
+ HOWTO (R_NDS32_GOTPC20, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 20, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_NDS32_GOTPC20", /* name */
+ FALSE, /* partial_inplace */
+ 0xfffff, /* src_mask */
+ 0xfffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* Like R_NDS32_HI20, but referring to the GOT table entry for
+ the symbol. */
+ HOWTO (R_NDS32_GOT_HI20, /* type */
+ 12, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 20, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_NDS32_GOT_HI20", /* name */
+ FALSE, /* partial_inplace */
+ 0x000fffff, /* src_mask */
+ 0x000fffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ HOWTO (R_NDS32_GOT_LO12, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 12, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_NDS32_GOT_LO12", /* name */
+ FALSE, /* partial_inplace */
+ 0x00000fff, /* src_mask */
+ 0x00000fff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* An PC Relative relocation used when setting PIC offset table register.
+ Like R_NDS32_HI20, but referring to the GOT table entry for
+ the symbol. */
+ HOWTO (R_NDS32_GOTPC_HI20, /* type */
+ 12, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 20, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_NDS32_GOTPC_HI20", /* name */
+ FALSE, /* partial_inplace */
+ 0x000fffff, /* src_mask */
+ 0x000fffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+ HOWTO (R_NDS32_GOTPC_LO12, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 12, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_NDS32_GOTPC_LO12", /* name */
+ FALSE, /* partial_inplace */
+ 0x00000fff, /* src_mask */
+ 0x00000fff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_NDS32_GOTOFF_HI20, /* type */
+ 12, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 20, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_NDS32_GOTOFF_HI20", /* name */
+ FALSE, /* partial_inplace */
+ 0x000fffff, /* src_mask */
+ 0x000fffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ HOWTO (R_NDS32_GOTOFF_LO12, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 12, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_NDS32_GOTOFF_LO12", /* name */
+ FALSE, /* partial_inplace */
+ 0x00000fff, /* src_mask */
+ 0x00000fff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Alignment hint for relaxable instruction. This is used with
+ R_NDS32_LABEL as a pair. Relax this instruction from 4 bytes to 2
+ in order to make next label aligned on word boundary. */
+ HOWTO (R_NDS32_INSN16, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ nds32_elf_ignore_reloc,/* special_function */
+ "R_NDS32_INSN16", /* name */
+ FALSE, /* partial_inplace */
+ 0x00000fff, /* src_mask */
+ 0x00000fff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Alignment hint for label. */
+ HOWTO (R_NDS32_LABEL, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ nds32_elf_ignore_reloc,/* special_function */
+ "R_NDS32_LABEL", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Relax hint for unconditional call sequence */
+ HOWTO (R_NDS32_LONGCALL1, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ nds32_elf_ignore_reloc,/* special_function */
+ "R_NDS32_LONGCALL1", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Relax hint for conditional call sequence. */
+ HOWTO (R_NDS32_LONGCALL2, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ nds32_elf_ignore_reloc,/* special_function */
+ "R_NDS32_LONGCALL2", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Relax hint for conditional call sequence. */
+ HOWTO (R_NDS32_LONGCALL3, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ nds32_elf_ignore_reloc,/* special_function */
+ "R_NDS32_LONGCALL3", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Relax hint for unconditional branch sequence. */
+ HOWTO (R_NDS32_LONGJUMP1, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ nds32_elf_ignore_reloc,/* special_function */
+ "R_NDS32_LONGJUMP1", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Relax hint for conditional branch sequence. */
+ HOWTO (R_NDS32_LONGJUMP2, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ nds32_elf_ignore_reloc,/* special_function */
+ "R_NDS32_LONGJUMP2", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Relax hint for conditional branch sequence. */
+ HOWTO (R_NDS32_LONGJUMP3, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ nds32_elf_ignore_reloc,/* special_function */
+ "R_NDS32_LONGJUMP3", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Relax hint for load/store sequence. */
+ HOWTO (R_NDS32_LOADSTORE, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ nds32_elf_ignore_reloc,/* special_function */
+ "R_NDS32_LOADSTORE", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Relax hint for load/store sequence. */
+ HOWTO (R_NDS32_9_FIXED_RELA, /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ nds32_elf_ignore_reloc,/* special_function */
+ "R_NDS32_9_FIXED_RELA",/* name */
+ FALSE, /* partial_inplace */
+ 0x000000ff, /* src_mask */
+ 0x000000ff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Relax hint for load/store sequence. */
+ HOWTO (R_NDS32_15_FIXED_RELA, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ nds32_elf_ignore_reloc,/* special_function */
+ "R_NDS32_15_FIXED_RELA", /* name */
+ FALSE, /* partial_inplace */
+ 0x00003fff, /* src_mask */
+ 0x00003fff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Relax hint for load/store sequence. */
+ HOWTO (R_NDS32_17_FIXED_RELA, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ nds32_elf_ignore_reloc,/* special_function */
+ "R_NDS32_17_FIXED_RELA", /* name */
+ FALSE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Relax hint for load/store sequence. */
+ HOWTO (R_NDS32_25_FIXED_RELA, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ nds32_elf_ignore_reloc,/* special_function */
+ "R_NDS32_25_FIXED_RELA", /* name */
+ FALSE, /* partial_inplace */
+ 0x00ffffff, /* src_mask */
+ 0x00ffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* High 20 bits of PLT symbol offset relative to PC. */
+ HOWTO (R_NDS32_PLTREL_HI20, /* type */
+ 12, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 20, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_NDS32_PLTREL_HI20", /* name */
+ FALSE, /* partial_inplace */
+ 0x000fffff, /* src_mask */
+ 0x000fffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Low 12 bits of PLT symbol offset relative to PC. */
+ HOWTO (R_NDS32_PLTREL_LO12, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 12, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_NDS32_PLTREL_LO12", /* name */
+ FALSE, /* partial_inplace */
+ 0x00000fff, /* src_mask */
+ 0x00000fff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* High 20 bits of PLT symbol offset relative to GOT (GP). */
+ HOWTO (R_NDS32_PLT_GOTREL_HI20, /* type */
+ 12, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 20, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_NDS32_PLT_GOTREL_HI20", /* name */
+ FALSE, /* partial_inplace */
+ 0x000fffff, /* src_mask */
+ 0x000fffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Low 12 bits of PLT symbol offset relative to GOT (GP). */
+ HOWTO (R_NDS32_PLT_GOTREL_LO12, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 12, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_NDS32_PLT_GOTREL_LO12", /* name */
+ FALSE, /* partial_inplace */
+ 0x00000fff, /* src_mask */
+ 0x00000fff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Small data area 12 bits offset. */
+ HOWTO (R_NDS32_SDA12S2_DP_RELA, /* type */
+ 2, /* 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_NDS32_SDA12S2_DP_RELA", /* name */
+ FALSE, /* partial_inplace */
+ 0x00000fff, /* src_mask */
+ 0x00000fff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Small data area 12 bits offset. */
+ HOWTO (R_NDS32_SDA12S2_SP_RELA, /* type */
+ 2, /* 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_NDS32_SDA12S2_SP_RELA", /* name */
+ FALSE, /* partial_inplace */
+ 0x00000fff, /* src_mask */
+ 0x00000fff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ /* Lower 12 bits of address. */
+
+ HOWTO (R_NDS32_LO12S2_DP_RELA, /* type */
+ 2, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 10, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_NDS32_LO12S2_DP_RELA", /* name */
+ FALSE, /* partial_inplace */
+ 0x000003ff, /* src_mask */
+ 0x000003ff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Lower 12 bits of address. */
+ HOWTO (R_NDS32_LO12S2_SP_RELA,/* type */
+ 2, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 10, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_NDS32_LO12S2_SP_RELA", /* name */
+ FALSE, /* partial_inplace */
+ 0x000003ff, /* src_mask */
+ 0x000003ff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ /* Lower 12 bits of address. Special identity for or case. */
+ HOWTO (R_NDS32_LO12S0_ORI_RELA, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 12, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_NDS32_LO12S0_ORI_RELA", /* name */
+ FALSE, /* partial_inplace */
+ 0x00000fff, /* src_mask */
+ 0x00000fff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ /* Small data area 19 bits offset. */
+ HOWTO (R_NDS32_SDA16S3_RELA, /* type */
+ 3, /* 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_NDS32_SDA16S3_RELA",/* name */
+ FALSE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Small data area 15 bits offset. */
+ HOWTO (R_NDS32_SDA17S2_RELA, /* type */
+ 2, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 17, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_NDS32_SDA17S2_RELA",/* name */
+ FALSE, /* partial_inplace */
+ 0x0001ffff, /* src_mask */
+ 0x0001ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_NDS32_SDA18S1_RELA, /* type */
+ 1, /* 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_NDS32_SDA18S1_RELA",/* name */
+ FALSE, /* partial_inplace */
+ 0x0003ffff, /* src_mask */
+ 0x0003ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_NDS32_SDA19S0_RELA, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 19, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_NDS32_SDA19S0_RELA",/* name */
+ FALSE, /* partial_inplace */
+ 0x0007ffff, /* src_mask */
+ 0x0007ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ HOWTO (R_NDS32_DWARF2_OP1_RELA, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 8, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ nds32_elf_ignore_reloc,/* special_function */
+ "R_NDS32_DWARF2_OP1_RELA", /* name */
+ FALSE, /* partial_inplace */
+ 0xff, /* src_mask */
+ 0xff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ HOWTO (R_NDS32_DWARF2_OP2_RELA, /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ nds32_elf_ignore_reloc,/* special_function */
+ "R_NDS32_DWARF2_OP2_RELA", /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ HOWTO (R_NDS32_DWARF2_LEB_RELA, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ nds32_elf_ignore_reloc,/* special_function */
+ "R_NDS32_DWARF2_LEB_RELA", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ HOWTO (R_NDS32_UPDATE_TA_RELA,/* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ nds32_elf_ignore_reloc,/* special_function */
+ "R_NDS32_UPDATE_TA_RELA", /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ /* Like R_NDS32_PCREL, but referring to the procedure linkage table
+ entry for the symbol. */
+ HOWTO (R_NDS32_9_PLTREL, /* 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_NDS32_9_PLTREL", /* name */
+ FALSE, /* partial_inplace */
+ 0xff, /* src_mask */
+ 0xff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+ /* Low 20 bits of PLT symbol offset relative to GOT (GP). */
+ HOWTO (R_NDS32_PLT_GOTREL_LO20, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 20, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_NDS32_PLT_GOTREL_LO20", /* name */
+ FALSE, /* partial_inplace */
+ 0x000fffff, /* src_mask */
+ 0x000fffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ /* low 15 bits of PLT symbol offset relative to GOT (GP) */
+ HOWTO (R_NDS32_PLT_GOTREL_LO15, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 15, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_NDS32_PLT_GOTREL_LO15", /* name */
+ FALSE, /* partial_inplace */
+ 0x00007fff, /* src_mask */
+ 0x00007fff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ /* Low 19 bits of PLT symbol offset relative to GOT (GP). */
+ HOWTO (R_NDS32_PLT_GOTREL_LO19, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 19, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_NDS32_PLT_GOTREL_LO19", /* name */
+ FALSE, /* partial_inplace */
+ 0x0007ffff, /* src_mask */
+ 0x0007ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ HOWTO (R_NDS32_GOT_LO15, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 15, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_NDS32_GOT_LO15", /* name */
+ FALSE, /* partial_inplace */
+ 0x00007fff, /* src_mask */
+ 0x00007fff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ HOWTO (R_NDS32_GOT_LO19, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 19, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_NDS32_GOT_LO19", /* name */
+ FALSE, /* partial_inplace */
+ 0x0007ffff, /* src_mask */
+ 0x0007ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ HOWTO (R_NDS32_GOTOFF_LO15, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 15, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_NDS32_GOTOFF_LO15", /* name */
+ FALSE, /* partial_inplace */
+ 0x00007fff, /* src_mask */
+ 0x00007fff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ HOWTO (R_NDS32_GOTOFF_LO19, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 19, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_NDS32_GOTOFF_LO19", /* name */
+ FALSE, /* partial_inplace */
+ 0x0007ffff, /* src_mask */
+ 0x0007ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ /* GOT 15 bits offset. */
+ HOWTO (R_NDS32_GOT15S2_RELA, /* type */
+ 2, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 15, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_NDS32_GOT15S2_RELA",/* name */
+ FALSE, /* partial_inplace */
+ 0x00007fff, /* src_mask */
+ 0x00007fff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ /* GOT 17 bits offset. */
+ HOWTO (R_NDS32_GOT17S2_RELA, /* type */
+ 2, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 17, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_NDS32_GOT17S2_RELA",/* name */
+ FALSE, /* partial_inplace */
+ 0x0001ffff, /* src_mask */
+ 0x0001ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ /* A 5 bit address. */
+ HOWTO (R_NDS32_5_RELA, /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 5, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_NDS32_5_RELA", /* name */
+ FALSE, /* partial_inplace */
+ 0x1f, /* src_mask */
+ 0x1f, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ HOWTO (R_NDS32_10_UPCREL_RELA,/* type */
+ 1, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 9, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_unsigned, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_NDS32_10_UPCREL_RELA", /* name */
+ FALSE, /* partial_inplace */
+ 0x1ff, /* src_mask */
+ 0x1ff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+ HOWTO (R_NDS32_SDA_FP7U2_RELA,/* type */
+ 2, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 7, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_unsigned, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_NDS32_SDA_FP7U2_RELA", /* name */
+ FALSE, /* partial_inplace */
+ 0x0000007f, /* src_mask */
+ 0x0000007f, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ HOWTO (R_NDS32_WORD_9_PCREL_RELA, /* type */
+ 1, /* rightshift */
+ 2, /* 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_NDS32_WORD_9_PCREL_RELA", /* name */
+ FALSE, /* partial_inplace */
+ 0xff, /* src_mask */
+ 0xff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+ HOWTO (R_NDS32_25_ABS_RELA, /* type */
+ 1, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 24, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_NDS32_25_ABS_RELA", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffff, /* src_mask */
+ 0xffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A relative 17 bit relocation for ifc, right shifted by 1. */
+ HOWTO (R_NDS32_17IFC_PCREL_RELA, /* type */
+ 1, /* 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_NDS32_17IFC_PCREL_RELA", /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* A relative unsigned 10 bit relocation for ifc, right shifted by 1. */
+ HOWTO (R_NDS32_10IFCU_PCREL_RELA, /* type */
+ 1, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 9, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_unsigned, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_NDS32_10IFCU_PCREL_RELA", /* name */
+ FALSE, /* partial_inplace */
+ 0x1ff, /* src_mask */
+ 0x1ff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* Like R_NDS32_HI20, but referring to the TLS entry for the symbol. */
+ HOWTO (R_NDS32_TLS_LE_HI20, /* type */
+ 12, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 20, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_NDS32_TLS_LE_HI20", /* name */
+ FALSE, /* partial_inplace */
+ 0x000fffff, /* src_mask */
+ 0x000fffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ HOWTO (R_NDS32_TLS_LE_LO12, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 12, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_NDS32_TLS_LE_LO12", /* name */
+ FALSE, /* partial_inplace */
+ 0x00000fff, /* src_mask */
+ 0x00000fff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Like R_NDS32_HI20, but referring to the TLS entry for the symbol. */
+ HOWTO (R_NDS32_TLS_IE_HI20, /* type */
+ 12, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 20, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_NDS32_TLS_IE_HI20", /* name */
+ FALSE, /* partial_inplace */
+ 0x000fffff, /* src_mask */
+ 0x000fffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ HOWTO (R_NDS32_TLS_IE_LO12S2, /* type */
+ 2, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 10, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_NDS32_TLS_IE_LO12S2", /* name */
+ FALSE, /* partial_inplace */
+ 0x000003ff, /* src_mask */
+ 0x000003ff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ /* Mark a TLS IE entry in GOT. */
+ HOWTO (R_NDS32_TLS_TPOFF, /* 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_NDS32_TLS_TPOFF", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ /* A 20 bit address. */
+ HOWTO (R_NDS32_TLS_LE_20, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 20, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_NDS32_TLS_LE_20", /* name */
+ FALSE, /* partial_inplace */
+ 0xfffff, /* src_mask */
+ 0xfffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ HOWTO (R_NDS32_TLS_LE_15S0, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 15, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_NDS32_TLS_LE_15S0", /* name */
+ FALSE, /* partial_inplace */
+ 0x7fff, /* src_mask */
+ 0x7fff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ HOWTO (R_NDS32_TLS_LE_15S1, /* type */
+ 1, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 15, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_NDS32_TLS_LE_15S1", /* name */
+ FALSE, /* partial_inplace */
+ 0x7fff, /* src_mask */
+ 0x7fff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ HOWTO (R_NDS32_TLS_LE_15S2, /* type */
+ 2, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 15, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_NDS32_TLS_LE_15S2", /* name */
+ FALSE, /* partial_inplace */
+ 0x7fff, /* src_mask */
+ 0x7fff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Relax hint for unconditional call sequence */
+ HOWTO (R_NDS32_LONGCALL4, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ nds32_elf_ignore_reloc, /* special_function */
+ "R_NDS32_LONGCALL4", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Relax hint for conditional call sequence. */
+ HOWTO (R_NDS32_LONGCALL5, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ nds32_elf_ignore_reloc, /* special_function */
+ "R_NDS32_LONGCALL5", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Relax hint for conditional call sequence. */
+ HOWTO (R_NDS32_LONGCALL6, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ nds32_elf_ignore_reloc, /* special_function */
+ "R_NDS32_LONGCALL6", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Relax hint for unconditional branch sequence. */
+ HOWTO (R_NDS32_LONGJUMP4, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ nds32_elf_ignore_reloc, /* special_function */
+ "R_NDS32_LONGJUMP4", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Relax hint for conditional branch sequence. */
+ HOWTO (R_NDS32_LONGJUMP5, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ nds32_elf_ignore_reloc, /* special_function */
+ "R_NDS32_LONGJUMP5", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Relax hint for conditional branch sequence. */
+ HOWTO (R_NDS32_LONGJUMP6, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ nds32_elf_ignore_reloc, /* special_function */
+ "R_NDS32_LONGJUMP6", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Relax hint for conditional branch sequence. */
+ HOWTO (R_NDS32_LONGJUMP7, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ nds32_elf_ignore_reloc, /* special_function */
+ "R_NDS32_LONGJUMP7", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+};
+
+/* Relocations used for relaxation. */
+static reloc_howto_type nds32_elf_relax_howto_table[] =
+{
+ HOWTO (R_NDS32_RELAX_ENTRY, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ nds32_elf_ignore_reloc,/* special_function */
+ "R_NDS32_RELAX_ENTRY", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ HOWTO (R_NDS32_GOT_SUFF, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ nds32_elf_ignore_reloc,/* special_function */
+ "R_NDS32_GOT_SUFF", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ HOWTO (R_NDS32_GOTOFF_SUFF, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ nds32_elf_ignore_reloc,/* special_function */
+ "R_NDS32_GOTOFF_SUFF", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ HOWTO (R_NDS32_PLT_GOT_SUFF, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ nds32_elf_ignore_reloc,/* special_function */
+ "R_NDS32_PLT_GOT_SUFF",/* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ HOWTO (R_NDS32_MULCALL_SUFF, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ nds32_elf_ignore_reloc,/* special_function */
+ "R_NDS32_MULCALL_SUFF",/* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ HOWTO (R_NDS32_PTR, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ nds32_elf_ignore_reloc,/* special_function */
+ "R_NDS32_PTR", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ HOWTO (R_NDS32_PTR_COUNT, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ nds32_elf_ignore_reloc,/* special_function */
+ "R_NDS32_PTR_COUNT", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ HOWTO (R_NDS32_PTR_RESOLVED, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ nds32_elf_ignore_reloc,/* special_function */
+ "R_NDS32_PTR_RESOLVED",/* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ HOWTO (R_NDS32_PLTBLOCK, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ nds32_elf_ignore_reloc,/* special_function */
+ "R_NDS32_PLTBLOCK", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ HOWTO (R_NDS32_RELAX_REGION_BEGIN, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ nds32_elf_ignore_reloc,/* special_function */
+ "R_NDS32_RELAX_REGION_BEGIN", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ HOWTO (R_NDS32_RELAX_REGION_END, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ nds32_elf_ignore_reloc,/* special_function */
+ "R_NDS32_RELAX_REGION_END", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ HOWTO (R_NDS32_MINUEND, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ nds32_elf_ignore_reloc,/* special_function */
+ "R_NDS32_MINUEND", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ HOWTO (R_NDS32_SUBTRAHEND, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ nds32_elf_ignore_reloc,/* special_function */
+ "R_NDS32_SUBTRAHEND", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ HOWTO (R_NDS32_DIFF8, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 8, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ nds32_elf_ignore_reloc,/* special_function */
+ "R_NDS32_DIFF8", /* name */
+ FALSE, /* partial_inplace */
+ 0x000000ff, /* src_mask */
+ 0x000000ff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ HOWTO (R_NDS32_DIFF16, /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ nds32_elf_ignore_reloc,/* special_function */
+ "R_NDS32_DIFF16", /* name */
+ FALSE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ HOWTO (R_NDS32_DIFF32, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ nds32_elf_ignore_reloc,/* special_function */
+ "R_NDS32_DIFF32", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ HOWTO (R_NDS32_DIFF_ULEB128, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 0, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ nds32_elf_ignore_reloc,/* special_function */
+ "R_NDS32_DIFF_ULEB128",/* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ HOWTO (R_NDS32_DATA, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ nds32_elf_ignore_reloc,/* special_function */
+ "R_NDS32_DATA", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ HOWTO (R_NDS32_TRAN, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ nds32_elf_ignore_reloc,/* special_function */
+ "R_NDS32_TRAN", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ HOWTO (R_NDS32_TLS_LE_ADD, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ nds32_elf_ignore_reloc, /* special_function */
+ "R_NDS32_TLS_LE_ADD", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ HOWTO (R_NDS32_TLS_LE_LS, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ nds32_elf_ignore_reloc, /* special_function */
+ "R_NDS32_TLS_LE_LS", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ HOWTO (R_NDS32_EMPTY, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ nds32_elf_ignore_reloc, /* special_function */
+ "R_NDS32_EMPTY", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+};
+
+
+/* nds32_insertion_sort sorts an array with nmemb elements of size size.
+ This prototype is the same as qsort (). */
+
+void
+nds32_insertion_sort (void *base, size_t nmemb, size_t size,
+ int (*compar) (const void *lhs, const void *rhs))
+{
+ char *ptr = (char *) base;
+ int i, j;
+ char *tmp = alloca (size);
+
+ /* If i is less than j, i is inserted before j.
+
+ |---- j ----- i --------------|
+ \ / \ /
+ sorted unsorted
+ */
+
+ for (i = 1; i < (int) nmemb; i++)
+ {
+ for (j = (i - 1); j >= 0; j--)
+ if (compar (ptr + i * size, ptr + j * size) >= 0)
+ break;
+
+ j++;
+
+ if (i == j)
+ continue; /* i is in order. */
+
+ memcpy (tmp, ptr + i * size, size);
+ memmove (ptr + (j + 1) * size, ptr + j * size, (i - j) * size);
+ memcpy (ptr + j * size, tmp, size);
+ }
+}
+
+/* Sort relocation by r_offset.
+
+ We didn't use qsort () in stdlib, because quick-sort is not a stable sorting
+ algorithm. Relocations at the same r_offset must keep their order.
+ For example, RELAX_ENTRY must be the very first relocation entry.
+
+ Currently, this function implements insertion-sort.
+
+ FIXME: If we already sort them in assembler, why bother sort them
+ here again? */
+
+static int
+compar_reloc (const void *lhs, const void *rhs)
+{
+ const Elf_Internal_Rela *l = (const Elf_Internal_Rela *) lhs;
+ const Elf_Internal_Rela *r = (const Elf_Internal_Rela *) rhs;
+
+ if (l->r_offset > r->r_offset)
+ return 1;
+ else if (l->r_offset == r->r_offset)
+ return 0;
+ else
+ return -1;
+}
+
+/* Functions listed below are only used for old relocs.
+ * nds32_elf_9_pcrel_reloc
+ * nds32_elf_do_9_pcrel_reloc
+ * nds32_elf_hi20_reloc
+ * nds32_elf_relocate_hi20
+ * nds32_elf_lo12_reloc
+ * nds32_elf_sda15_reloc
+ * nds32_elf_generic_reloc
+ */
+
+/* Handle the R_NDS32_9_PCREL & R_NDS32_9_PCREL_RELA reloc. */
+
+static bfd_reloc_status_type
+nds32_elf_9_pcrel_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
+ void *data, asection *input_section, bfd *output_bfd,
+ char **error_message ATTRIBUTE_UNUSED)
+{
+ /* 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 nds32_elf_do_9_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_NDS32_9_PCREL reloc. */
+#define N_ONES(n) (((((bfd_vma) 1 << ((n) - 1)) - 1) << 1) | 1)
+
+static bfd_reloc_status_type
+nds32_elf_do_9_pcrel_reloc (bfd *abfd, reloc_howto_type *howto,
+ asection *input_section, bfd_byte *data,
+ bfd_vma offset,
+ asection *symbol_section ATTRIBUTE_UNUSED,
+ bfd_vma symbol_value, bfd_vma addend)
+{
+ bfd_signed_vma relocation;
+ unsigned short x;
+ bfd_reloc_status_type status;
+
+ /* Sanity check the address (offset in section). */
+ if (offset > bfd_get_section_limit (abfd, input_section))
+ 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 & -(bfd_vma) 2);
+
+ if (relocation < -ACCURATE_8BIT_S1 || relocation >= ACCURATE_8BIT_S1)
+ status = bfd_reloc_overflow;
+ else
+ status = bfd_reloc_ok;
+
+ x = bfd_getb16 (data + offset);
+
+ relocation >>= howto->rightshift;
+ relocation <<= howto->bitpos;
+ x = (x & ~howto->dst_mask)
+ | (((x & howto->src_mask) + relocation) & howto->dst_mask);
+
+ bfd_putb16 ((bfd_vma) x, data + offset);
+
+ return status;
+}
+
+/* Handle the R_NDS32_HI20_[SU]LO relocs.
+ HI20_SLO is for the add3 and load/store with displacement instructions.
+ HI20 is for the or3 instruction.
+ For R_NDS32_HI20_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_NDS32_LO12 reloc
+ because there is a carry from the LO12 to the HI20. Here we just save
+ the information we need; we do the actual relocation when we see the LO12.
+ This code is copied from the elf32-mips.c. We also support an arbitrary
+ number of HI20 relocs to be associated with a single LO12 reloc. The
+ assembler sorts the relocs to ensure each HI20 immediately precedes its
+ LO12. However if there are multiple copies, the assembler may not find
+ the real LO12 so it picks the first one it finds. */
+
+struct nds32_hi20
+{
+ struct nds32_hi20 *next;
+ bfd_byte *addr;
+ bfd_vma addend;
+};
+
+static struct nds32_hi20 *nds32_hi20_list;
+
+static bfd_reloc_status_type
+nds32_elf_hi20_reloc (bfd *abfd ATTRIBUTE_UNUSED, arelent *reloc_entry,
+ asymbol *symbol, void *data, asection *input_section,
+ bfd *output_bfd, char **error_message ATTRIBUTE_UNUSED)
+{
+ bfd_reloc_status_type ret;
+ bfd_vma relocation;
+ struct nds32_hi20 *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 > bfd_get_section_limit (abfd, input_section))
+ 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 LO12 do the actual relocation. */
+ n = (struct nds32_hi20 *) bfd_malloc ((bfd_size_type) sizeof *n);
+ if (n == NULL)
+ return bfd_reloc_outofrange;
+
+ n->addr = (bfd_byte *) data + reloc_entry->address;
+ n->addend = relocation;
+ n->next = nds32_hi20_list;
+ nds32_hi20_list = n;
+
+ if (output_bfd != (bfd *) NULL)
+ reloc_entry->address += input_section->output_offset;
+
+ return ret;
+}
+
+/* Handle an NDS32 ELF HI20 reloc. */
+
+static void
+nds32_elf_relocate_hi20 (bfd *input_bfd ATTRIBUTE_UNUSED,
+ int type ATTRIBUTE_UNUSED, Elf_Internal_Rela *relhi,
+ Elf_Internal_Rela *rello, bfd_byte *contents,
+ bfd_vma addend)
+{
+ unsigned long insn;
+ bfd_vma addlo;
+
+ insn = bfd_getb32 (contents + relhi->r_offset);
+
+ addlo = bfd_getb32 (contents + rello->r_offset);
+ addlo &= 0xfff;
+
+ addend += ((insn & 0xfffff) << 20) + addlo;
+
+ insn = (insn & 0xfff00000) | ((addend >> 12) & 0xfffff);
+ bfd_putb32 (insn, contents + relhi->r_offset);
+}
+
+/* Do an R_NDS32_LO12 relocation. This is a straightforward 12 bit
+ inplace relocation; this function exists in order to do the
+ R_NDS32_HI20_[SU]LO relocation described above. */
+
+static bfd_reloc_status_type
+nds32_elf_lo12_reloc (bfd *input_bfd, arelent *reloc_entry, asymbol *symbol,
+ void *data, asection *input_section, bfd *output_bfd,
+ char **error_message)
+{
+ /* 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 != NULL && (symbol->flags & BSF_SECTION_SYM) == 0
+ && reloc_entry->addend == 0)
+ {
+ reloc_entry->address += input_section->output_offset;
+ return bfd_reloc_ok;
+ }
+
+ if (nds32_hi20_list != NULL)
+ {
+ struct nds32_hi20 *l;
+
+ l = nds32_hi20_list;
+ while (l != NULL)
+ {
+ unsigned long insn;
+ unsigned long val;
+ unsigned long vallo;
+ struct nds32_hi20 *next;
+
+ /* Do the HI20 relocation. Note that we actually don't need
+ to know anything about the LO12 itself, except where to
+ find the low 12 bits of the addend needed by the LO12. */
+ insn = bfd_getb32 (l->addr);
+ vallo = bfd_getb32 ((bfd_byte *) data + reloc_entry->address);
+ vallo &= 0xfff;
+ switch (reloc_entry->howto->type)
+ {
+ case R_NDS32_LO12S3:
+ vallo <<= 3;
+ break;
+
+ case R_NDS32_LO12S2:
+ vallo <<= 2;
+ break;
+
+ case R_NDS32_LO12S1:
+ vallo <<= 1;
+ break;
+
+ case R_NDS32_LO12S0:
+ vallo <<= 0;
+ break;
+ }
+
+ val = ((insn & 0xfffff) << 12) + vallo;
+ val += l->addend;
+
+ insn = (insn & ~(bfd_vma) 0xfffff) | ((val >> 12) & 0xfffff);
+ bfd_putb32 ((bfd_vma) insn, l->addr);
+
+ next = l->next;
+ free (l);
+ l = next;
+ }
+
+ nds32_hi20_list = NULL;
+ }
+
+ /* Now do the LO12 reloc in the usual way.
+ ??? It would be nice to call bfd_elf_generic_reloc here,
+ but we have partial_inplace set. bfd_elf_generic_reloc will
+ pass the handling back to bfd_install_relocation which will install
+ a section relative addend which is wrong. */
+ return nds32_elf_generic_reloc (input_bfd, reloc_entry, symbol, data,
+ input_section, output_bfd, error_message);
+}
+
+/* Do generic partial_inplace relocation.
+ This is a local replacement for bfd_elf_generic_reloc. */
+
+static bfd_reloc_status_type
+nds32_elf_generic_reloc (bfd *input_bfd, arelent *reloc_entry,
+ asymbol *symbol, void *data, asection *input_section,
+ bfd *output_bfd, char **error_message ATTRIBUTE_UNUSED)
+{
+ bfd_reloc_status_type ret;
+ bfd_vma relocation;
+ bfd_byte *inplace_address;
+
+ /* 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 != NULL && (symbol->flags & BSF_SECTION_SYM) == 0
+ && reloc_entry->addend == 0)
+ {
+ reloc_entry->address += input_section->output_offset;
+ return bfd_reloc_ok;
+ }
+
+ /* Now do the reloc in the usual way.
+ ??? It would be nice to call bfd_elf_generic_reloc here,
+ but we have partial_inplace set. bfd_elf_generic_reloc will
+ pass the handling back to bfd_install_relocation which will install
+ a section relative addend which is wrong. */
+
+ /* Sanity check the address (offset in section). */
+ if (reloc_entry->address > bfd_get_section_limit (input_bfd, input_section))
+ 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) || output_bfd != (bfd *) NULL)
+ relocation = 0;
+ else
+ relocation = symbol->value;
+
+ /* Only do this for a final link. */
+ if (output_bfd == (bfd *) NULL)
+ {
+ relocation += symbol->section->output_section->vma;
+ relocation += symbol->section->output_offset;
+ }
+
+ relocation += reloc_entry->addend;
+ switch (reloc_entry->howto->type)
+ {
+ case R_NDS32_LO12S3:
+ relocation >>= 3;
+ break;
+
+ case R_NDS32_LO12S2:
+ relocation >>= 2;
+ break;
+
+ case R_NDS32_LO12S1:
+ relocation >>= 1;
+ break;
+
+ case R_NDS32_LO12S0:
+ default:
+ relocation >>= 0;
+ break;
+ }
+
+ inplace_address = (bfd_byte *) data + reloc_entry->address;
+
+#define DOIT(x) \
+ x = ((x & ~reloc_entry->howto->dst_mask) | \
+ (((x & reloc_entry->howto->src_mask) + relocation) & \
+ reloc_entry->howto->dst_mask))
+
+ switch (reloc_entry->howto->size)
+ {
+ case 1:
+ {
+ short x = bfd_getb16 (inplace_address);
+
+ DOIT (x);
+ bfd_putb16 ((bfd_vma) x, inplace_address);
+ }
+ break;
+ case 2:
+ {
+ unsigned long x = bfd_getb32 (inplace_address);
+
+ DOIT (x);
+ bfd_putb32 ((bfd_vma) x, inplace_address);
+ }
+ break;
+ default:
+ BFD_ASSERT (0);
+ }
+
+ if (output_bfd != (bfd *) NULL)
+ reloc_entry->address += input_section->output_offset;
+
+ return ret;
+}
+
+/* Handle the R_NDS32_SDA15 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 15 bits are sign extended and added to the register specified
+ in the instruction, which is assumed to point to _SDA_BASE_.
+
+ Since the lower 15 bits offset is left-shifted 0, 1 or 2 bits depending on
+ the access size, this must be taken care of. */
+
+static bfd_reloc_status_type
+nds32_elf_sda15_reloc (bfd *abfd ATTRIBUTE_UNUSED, arelent *reloc_entry,
+ asymbol *symbol, void *data ATTRIBUTE_UNUSED,
+ asection *input_section, bfd *output_bfd,
+ char **error_message ATTRIBUTE_UNUSED)
+{
+ /* 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 ();
+}
+
+/* nds32_elf_ignore_reloc is the special function for
+ relocation types which don't need to be relocated
+ like relaxation relocation types.
+ This function simply return bfd_reloc_ok when it is
+ invoked. */
+
+static bfd_reloc_status_type
+nds32_elf_ignore_reloc (bfd *abfd ATTRIBUTE_UNUSED, arelent *reloc_entry,
+ asymbol *symbol ATTRIBUTE_UNUSED,
+ void *data ATTRIBUTE_UNUSED, asection *input_section,
+ bfd *output_bfd, char **error_message ATTRIBUTE_UNUSED)
+{
+ if (output_bfd != NULL)
+ reloc_entry->address += input_section->output_offset;
+
+ return bfd_reloc_ok;
+}
+
+
+/* Map BFD reloc types to NDS32 ELF reloc types. */
+
+struct nds32_reloc_map_entry
+{
+ bfd_reloc_code_real_type bfd_reloc_val;
+ unsigned char elf_reloc_val;
+};
+
+static const struct nds32_reloc_map_entry nds32_reloc_map[] =
+{
+ {BFD_RELOC_NONE, R_NDS32_NONE},
+ {BFD_RELOC_16, R_NDS32_16_RELA},
+ {BFD_RELOC_32, R_NDS32_32_RELA},
+ {BFD_RELOC_NDS32_20, R_NDS32_20_RELA},
+ {BFD_RELOC_NDS32_5, R_NDS32_5_RELA},
+ {BFD_RELOC_NDS32_9_PCREL, R_NDS32_9_PCREL_RELA},
+ {BFD_RELOC_NDS32_WORD_9_PCREL, R_NDS32_WORD_9_PCREL_RELA},
+ {BFD_RELOC_NDS32_15_PCREL, R_NDS32_15_PCREL_RELA},
+ {BFD_RELOC_NDS32_17_PCREL, R_NDS32_17_PCREL_RELA},
+ {BFD_RELOC_NDS32_25_PCREL, R_NDS32_25_PCREL_RELA},
+ {BFD_RELOC_NDS32_10_UPCREL, R_NDS32_10_UPCREL_RELA},
+ {BFD_RELOC_NDS32_HI20, R_NDS32_HI20_RELA},
+ {BFD_RELOC_NDS32_LO12S3, R_NDS32_LO12S3_RELA},
+ {BFD_RELOC_NDS32_LO12S2, R_NDS32_LO12S2_RELA},
+ {BFD_RELOC_NDS32_LO12S1, R_NDS32_LO12S1_RELA},
+ {BFD_RELOC_NDS32_LO12S0, R_NDS32_LO12S0_RELA},
+ {BFD_RELOC_NDS32_LO12S0_ORI, R_NDS32_LO12S0_ORI_RELA},
+ {BFD_RELOC_NDS32_SDA15S3, R_NDS32_SDA15S3_RELA},
+ {BFD_RELOC_NDS32_SDA15S2, R_NDS32_SDA15S2_RELA},
+ {BFD_RELOC_NDS32_SDA15S1, R_NDS32_SDA15S1_RELA},
+ {BFD_RELOC_NDS32_SDA15S0, R_NDS32_SDA15S0_RELA},
+ {BFD_RELOC_VTABLE_INHERIT, R_NDS32_RELA_GNU_VTINHERIT},
+ {BFD_RELOC_VTABLE_ENTRY, R_NDS32_RELA_GNU_VTENTRY},
+
+ {BFD_RELOC_NDS32_GOT20, R_NDS32_GOT20},
+ {BFD_RELOC_NDS32_9_PLTREL, R_NDS32_9_PLTREL},
+ {BFD_RELOC_NDS32_25_PLTREL, R_NDS32_25_PLTREL},
+ {BFD_RELOC_NDS32_COPY, R_NDS32_COPY},
+ {BFD_RELOC_NDS32_GLOB_DAT, R_NDS32_GLOB_DAT},
+ {BFD_RELOC_NDS32_JMP_SLOT, R_NDS32_JMP_SLOT},
+ {BFD_RELOC_NDS32_RELATIVE, R_NDS32_RELATIVE},
+ {BFD_RELOC_NDS32_GOTOFF, R_NDS32_GOTOFF},
+ {BFD_RELOC_NDS32_GOTPC20, R_NDS32_GOTPC20},
+ {BFD_RELOC_NDS32_GOT_HI20, R_NDS32_GOT_HI20},
+ {BFD_RELOC_NDS32_GOT_LO12, R_NDS32_GOT_LO12},
+ {BFD_RELOC_NDS32_GOT_LO15, R_NDS32_GOT_LO15},
+ {BFD_RELOC_NDS32_GOT_LO19, R_NDS32_GOT_LO19},
+ {BFD_RELOC_NDS32_GOTPC_HI20, R_NDS32_GOTPC_HI20},
+ {BFD_RELOC_NDS32_GOTPC_LO12, R_NDS32_GOTPC_LO12},
+ {BFD_RELOC_NDS32_GOTOFF_HI20, R_NDS32_GOTOFF_HI20},
+ {BFD_RELOC_NDS32_GOTOFF_LO12, R_NDS32_GOTOFF_LO12},
+ {BFD_RELOC_NDS32_GOTOFF_LO15, R_NDS32_GOTOFF_LO15},
+ {BFD_RELOC_NDS32_GOTOFF_LO19, R_NDS32_GOTOFF_LO19},
+ {BFD_RELOC_NDS32_INSN16, R_NDS32_INSN16},
+ {BFD_RELOC_NDS32_LABEL, R_NDS32_LABEL},
+ {BFD_RELOC_NDS32_LONGCALL1, R_NDS32_LONGCALL1},
+ {BFD_RELOC_NDS32_LONGCALL2, R_NDS32_LONGCALL2},
+ {BFD_RELOC_NDS32_LONGCALL3, R_NDS32_LONGCALL3},
+ {BFD_RELOC_NDS32_LONGCALL4, R_NDS32_LONGCALL4},
+ {BFD_RELOC_NDS32_LONGCALL5, R_NDS32_LONGCALL5},
+ {BFD_RELOC_NDS32_LONGCALL6, R_NDS32_LONGCALL6},
+ {BFD_RELOC_NDS32_LONGJUMP1, R_NDS32_LONGJUMP1},
+ {BFD_RELOC_NDS32_LONGJUMP2, R_NDS32_LONGJUMP2},
+ {BFD_RELOC_NDS32_LONGJUMP3, R_NDS32_LONGJUMP3},
+ {BFD_RELOC_NDS32_LONGJUMP4, R_NDS32_LONGJUMP4},
+ {BFD_RELOC_NDS32_LONGJUMP5, R_NDS32_LONGJUMP5},
+ {BFD_RELOC_NDS32_LONGJUMP6, R_NDS32_LONGJUMP6},
+ {BFD_RELOC_NDS32_LONGJUMP7, R_NDS32_LONGJUMP7},
+ {BFD_RELOC_NDS32_LOADSTORE, R_NDS32_LOADSTORE},
+ {BFD_RELOC_NDS32_9_FIXED, R_NDS32_9_FIXED_RELA},
+ {BFD_RELOC_NDS32_15_FIXED, R_NDS32_15_FIXED_RELA},
+ {BFD_RELOC_NDS32_17_FIXED, R_NDS32_17_FIXED_RELA},
+ {BFD_RELOC_NDS32_25_FIXED, R_NDS32_25_FIXED_RELA},
+ {BFD_RELOC_NDS32_PLTREL_HI20, R_NDS32_PLTREL_HI20},
+ {BFD_RELOC_NDS32_PLTREL_LO12, R_NDS32_PLTREL_LO12},
+ {BFD_RELOC_NDS32_PLT_GOTREL_HI20, R_NDS32_PLT_GOTREL_HI20},
+ {BFD_RELOC_NDS32_PLT_GOTREL_LO12, R_NDS32_PLT_GOTREL_LO12},
+ {BFD_RELOC_NDS32_PLT_GOTREL_LO15, R_NDS32_PLT_GOTREL_LO15},
+ {BFD_RELOC_NDS32_PLT_GOTREL_LO19, R_NDS32_PLT_GOTREL_LO19},
+ {BFD_RELOC_NDS32_PLT_GOTREL_LO20, R_NDS32_PLT_GOTREL_LO20},
+ {BFD_RELOC_NDS32_SDA12S2_DP, R_NDS32_SDA12S2_DP_RELA},
+ {BFD_RELOC_NDS32_SDA12S2_SP, R_NDS32_SDA12S2_SP_RELA},
+ {BFD_RELOC_NDS32_LO12S2_DP, R_NDS32_LO12S2_DP_RELA},
+ {BFD_RELOC_NDS32_LO12S2_SP, R_NDS32_LO12S2_SP_RELA},
+ {BFD_RELOC_NDS32_SDA16S3, R_NDS32_SDA16S3_RELA},
+ {BFD_RELOC_NDS32_SDA17S2, R_NDS32_SDA17S2_RELA},
+ {BFD_RELOC_NDS32_SDA18S1, R_NDS32_SDA18S1_RELA},
+ {BFD_RELOC_NDS32_SDA19S0, R_NDS32_SDA19S0_RELA},
+ {BFD_RELOC_NDS32_SDA_FP7U2_RELA, R_NDS32_SDA_FP7U2_RELA},
+ {BFD_RELOC_NDS32_DWARF2_OP1, R_NDS32_DWARF2_OP1_RELA},
+ {BFD_RELOC_NDS32_DWARF2_OP2, R_NDS32_DWARF2_OP2_RELA},
+ {BFD_RELOC_NDS32_DWARF2_LEB, R_NDS32_DWARF2_LEB_RELA},
+ {BFD_RELOC_NDS32_UPDATE_TA, R_NDS32_UPDATE_TA_RELA},
+ {BFD_RELOC_NDS32_GOT_SUFF, R_NDS32_GOT_SUFF},
+ {BFD_RELOC_NDS32_GOTOFF_SUFF, R_NDS32_GOTOFF_SUFF},
+ {BFD_RELOC_NDS32_GOT15S2, R_NDS32_GOT15S2_RELA},
+ {BFD_RELOC_NDS32_GOT17S2, R_NDS32_GOT17S2_RELA},
+ {BFD_RELOC_NDS32_PTR, R_NDS32_PTR},
+ {BFD_RELOC_NDS32_PTR_COUNT, R_NDS32_PTR_COUNT},
+ {BFD_RELOC_NDS32_PLT_GOT_SUFF, R_NDS32_PLT_GOT_SUFF},
+ {BFD_RELOC_NDS32_PTR_RESOLVED, R_NDS32_PTR_RESOLVED},
+ {BFD_RELOC_NDS32_RELAX_ENTRY, R_NDS32_RELAX_ENTRY},
+ {BFD_RELOC_NDS32_MULCALL_SUFF, R_NDS32_MULCALL_SUFF},
+ {BFD_RELOC_NDS32_PLTBLOCK, R_NDS32_PLTBLOCK},
+ {BFD_RELOC_NDS32_RELAX_REGION_BEGIN, R_NDS32_RELAX_REGION_BEGIN},
+ {BFD_RELOC_NDS32_RELAX_REGION_END, R_NDS32_RELAX_REGION_END},
+ {BFD_RELOC_NDS32_MINUEND, R_NDS32_MINUEND},
+ {BFD_RELOC_NDS32_SUBTRAHEND, R_NDS32_SUBTRAHEND},
+ {BFD_RELOC_NDS32_EMPTY, R_NDS32_EMPTY},
+
+ {BFD_RELOC_NDS32_DIFF8, R_NDS32_DIFF8},
+ {BFD_RELOC_NDS32_DIFF16, R_NDS32_DIFF16},
+ {BFD_RELOC_NDS32_DIFF32, R_NDS32_DIFF32},
+ {BFD_RELOC_NDS32_DIFF_ULEB128, R_NDS32_DIFF_ULEB128},
+ {BFD_RELOC_NDS32_25_ABS, R_NDS32_25_ABS_RELA},
+ {BFD_RELOC_NDS32_DATA, R_NDS32_DATA},
+ {BFD_RELOC_NDS32_TRAN, R_NDS32_TRAN},
+ {BFD_RELOC_NDS32_17IFC_PCREL, R_NDS32_17IFC_PCREL_RELA},
+ {BFD_RELOC_NDS32_10IFCU_PCREL, R_NDS32_10IFCU_PCREL_RELA},
+ {BFD_RELOC_NDS32_TLS_LE_HI20, R_NDS32_TLS_LE_HI20},
+ {BFD_RELOC_NDS32_TLS_LE_LO12, R_NDS32_TLS_LE_LO12},
+ {BFD_RELOC_NDS32_TLS_LE_ADD, R_NDS32_TLS_LE_ADD},
+ {BFD_RELOC_NDS32_TLS_LE_LS, R_NDS32_TLS_LE_LS},
+ {BFD_RELOC_NDS32_TLS_IE_HI20, R_NDS32_TLS_IE_HI20},
+ {BFD_RELOC_NDS32_TLS_IE_LO12S2, R_NDS32_TLS_IE_LO12S2},
+ {BFD_RELOC_NDS32_TLS_TPOFF, R_NDS32_TLS_TPOFF},
+ {BFD_RELOC_NDS32_TLS_LE_20, R_NDS32_TLS_LE_20},
+ {BFD_RELOC_NDS32_TLS_LE_15S0, R_NDS32_TLS_LE_15S0},
+ {BFD_RELOC_NDS32_TLS_LE_15S1, R_NDS32_TLS_LE_15S1},
+ {BFD_RELOC_NDS32_TLS_LE_15S2, R_NDS32_TLS_LE_15S2},
+};
+
+/* Patch tag. */
+
+static reloc_howto_type *
+bfd_elf32_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ const char *r_name)
+{
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE (nds32_elf_howto_table); i++)
+ if (nds32_elf_howto_table[i].name != NULL
+ && strcasecmp (nds32_elf_howto_table[i].name, r_name) == 0)
+ return &nds32_elf_howto_table[i];
+
+ for (i = 0; i < ARRAY_SIZE (nds32_elf_relax_howto_table); i++)
+ if (nds32_elf_relax_howto_table[i].name != NULL
+ && strcasecmp (nds32_elf_relax_howto_table[i].name, r_name) == 0)
+ return &nds32_elf_relax_howto_table[i];
+
+ return NULL;
+}
+
+static reloc_howto_type *
+bfd_elf32_bfd_reloc_type_table_lookup (enum elf_nds32_reloc_type code)
+{
+ if (code < R_NDS32_RELAX_ENTRY)
+ {
+ BFD_ASSERT (code < ARRAY_SIZE (nds32_elf_howto_table));
+ return &nds32_elf_howto_table[code];
+ }
+ else
+ {
+ BFD_ASSERT ((size_t) (code - R_NDS32_RELAX_ENTRY)
+ < ARRAY_SIZE (nds32_elf_relax_howto_table));
+ return &nds32_elf_relax_howto_table[code - R_NDS32_RELAX_ENTRY];
+ }
+}
+
+static reloc_howto_type *
+bfd_elf32_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ bfd_reloc_code_real_type code)
+{
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE (nds32_reloc_map); i++)
+ {
+ if (nds32_reloc_map[i].bfd_reloc_val == code)
+ return bfd_elf32_bfd_reloc_type_table_lookup
+ (nds32_reloc_map[i].elf_reloc_val);
+ }
+
+ return NULL;
+}
+
+/* Set the howto pointer for an NDS32 ELF reloc. */
+
+static void
+nds32_info_to_howto_rel (bfd *abfd ATTRIBUTE_UNUSED, arelent *cache_ptr,
+ Elf_Internal_Rela *dst)
+{
+ enum elf_nds32_reloc_type r_type;
+
+ r_type = ELF32_R_TYPE (dst->r_info);
+ BFD_ASSERT (ELF32_R_TYPE (dst->r_info) <= R_NDS32_GNU_VTENTRY);
+ cache_ptr->howto = bfd_elf32_bfd_reloc_type_table_lookup (r_type);
+}
+
+static void
+nds32_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED, arelent *cache_ptr,
+ Elf_Internal_Rela *dst)
+{
+ BFD_ASSERT ((ELF32_R_TYPE (dst->r_info) == R_NDS32_NONE)
+ || ((ELF32_R_TYPE (dst->r_info) > R_NDS32_GNU_VTENTRY)
+ && (ELF32_R_TYPE (dst->r_info) < R_NDS32_max)));
+ cache_ptr->howto = bfd_elf32_bfd_reloc_type_table_lookup (ELF32_R_TYPE (dst->r_info));
+}
+
+/* Support for core dump NOTE sections.
+ Reference to include/linux/elfcore.h in Linux. */
+
+static bfd_boolean
+nds32_elf_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
+{
+ int offset;
+ size_t size;
+
+ switch (note->descsz)
+ {
+ case 0x114:
+ /* Linux/NDS32 32-bit, ABI1 */
+
+ /* pr_cursig */
+ elf_tdata (abfd)->core->signal = bfd_get_16 (abfd, note->descdata + 12);
+
+ /* pr_pid */
+ elf_tdata (abfd)->core->pid = bfd_get_32 (abfd, note->descdata + 24);
+
+ /* pr_reg */
+ offset = 72;
+ size = 200;
+ break;
+
+ case 0xfc:
+ /* Linux/NDS32 32-bit */
+
+ /* pr_cursig */
+ elf_tdata (abfd)->core->signal = bfd_get_16 (abfd, note->descdata + 12);
+
+ /* pr_pid */
+ elf_tdata (abfd)->core->pid = bfd_get_32 (abfd, note->descdata + 24);
+
+ /* pr_reg */
+ offset = 72;
+ size = 176;
+ break;
+
+ default:
+ return FALSE;
+ }
+
+ /* Make a ".reg" section. */
+ return _bfd_elfcore_make_pseudosection (abfd, ".reg",
+ size, note->descpos + offset);
+}
+
+static bfd_boolean
+nds32_elf_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
+{
+ switch (note->descsz)
+ {
+ case 124:
+ /* Linux/NDS32 */
+
+ /* __kernel_uid_t, __kernel_gid_t are short on NDS32 platform. */
+ elf_tdata (abfd)->core->program =
+ _bfd_elfcore_strndup (abfd, note->descdata + 28, 16);
+ elf_tdata (abfd)->core->command =
+ _bfd_elfcore_strndup (abfd, note->descdata + 44, 80);
+
+ default:
+ return FALSE;
+ }
+
+ /* 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;
+}
+
+/* Hook called by the linker routine which adds symbols from an object
+ file. We must handle the special NDS32 section numbers here.
+ We also keep watching for whether we need to create the sdata special
+ linker sections. */
+
+static bfd_boolean
+nds32_elf_add_symbol_hook (bfd *abfd,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ Elf_Internal_Sym *sym,
+ const char **namep ATTRIBUTE_UNUSED,
+ flagword *flagsp ATTRIBUTE_UNUSED,
+ asection **secp, bfd_vma *valp)
+{
+ 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)
+ || ELF_ST_TYPE (sym->st_info) == STT_TLS)
+ break;
+
+ /* st_value is the alignemnt constraint.
+ That might be its actual size if it is an array or structure. */
+ switch (sym->st_value)
+ {
+ case 1:
+ *secp = bfd_make_section_old_way (abfd, ".scommon_b");
+ break;
+ case 2:
+ *secp = bfd_make_section_old_way (abfd, ".scommon_h");
+ break;
+ case 4:
+ *secp = bfd_make_section_old_way (abfd, ".scommon_w");
+ break;
+ case 8:
+ *secp = bfd_make_section_old_way (abfd, ".scommon_d");
+ break;
+ default:
+ return TRUE;
+ }
+
+ (*secp)->flags |= SEC_IS_COMMON;
+ *valp = sym->st_size;
+ break;
+ }
+
+ return TRUE;
+}
+
+
+/* This function can figure out the best location for a base register to access
+ data relative to this base register
+ INPUT:
+ sda_d0: size of first DOUBLE WORD data section
+ sda_w0: size of first WORD data section
+ sda_h0: size of first HALF WORD data section
+ sda_b : size of BYTE data section
+ sda_hi: size of second HALF WORD data section
+ sda_w1: size of second WORD data section
+ sda_d1: size of second DOUBLE WORD data section
+ OUTPUT:
+ offset (always positive) from the beginning of sda_d0 if OK
+ a negative error value if fail
+ NOTE:
+ these 7 sections have to be located back to back if exist
+ a pass in 0 value for non-existing section */
+
+/* Due to the interpretation of simm15 field of load/store depending on
+ data accessing size, the organization of base register relative data shall
+ like the following figure
+ -------------------------------------------
+ | DOUBLE WORD sized data (range +/- 128K)
+ -------------------------------------------
+ | WORD sized data (range +/- 64K)
+ -------------------------------------------
+ | HALF WORD sized data (range +/- 32K)
+ -------------------------------------------
+ | BYTE sized data (range +/- 16K)
+ -------------------------------------------
+ | HALF WORD sized data (range +/- 32K)
+ -------------------------------------------
+ | WORD sized data (range +/- 64K)
+ -------------------------------------------
+ | DOUBLE WORD sized data (range +/- 128K)
+ -------------------------------------------
+ Its base register shall be set to access these data freely. */
+
+/* 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 relocatable output. */
+
+static asection *sda_rela_sec = NULL;
+
+#define SDA_SECTION_NUM 10
+
+static bfd_reloc_status_type
+nds32_elf_final_sda_base (bfd *output_bfd, struct bfd_link_info *info,
+ bfd_vma *psb, bfd_boolean add_symbol)
+{
+ int relax_fp_as_gp;
+ struct elf_nds32_link_hash_table *table;
+ struct bfd_link_hash_entry *h, *h2;
+ long unsigned int total = 0;
+
+ h = bfd_link_hash_lookup (info->hash, "_SDA_BASE_", FALSE, FALSE, TRUE);
+ if (!h || (h->type != bfd_link_hash_defined && h->type != bfd_link_hash_defweak))
+ {
+ asection *first = NULL, *final = NULL, *temp;
+ bfd_vma sda_base;
+ /* The first section must be 4-byte aligned to promise _SDA_BASE_ being
+ 4 byte-aligned. Therefore, it has to set the first section ".data"
+ 4 byte-aligned. */
+ static const char sec_name[SDA_SECTION_NUM][10] =
+ {
+ ".data", ".got", ".sdata_d", ".sdata_w", ".sdata_h", ".sdata_b",
+ ".sbss_b", ".sbss_h", ".sbss_w", ".sbss_d"
+ };
+ size_t i = 0;
+
+ if (output_bfd->sections == NULL)
+ {
+ *psb = elf_gp (output_bfd);
+ return bfd_reloc_ok;
+ }
+
+ /* Get the first and final section. */
+ while (i < sizeof (sec_name) / sizeof (sec_name [0]))
+ {
+ temp = bfd_get_section_by_name (output_bfd, sec_name[i]);
+ if (temp && !first && (temp->size != 0 || temp->rawsize != 0))
+ first = temp;
+ if (temp && (temp->size != 0 || temp->rawsize != 0))
+ final = temp;
+
+ /* Summarize the sections in order to check if joining .bss. */
+ if (temp && temp->size != 0)
+ total += temp->size;
+ else if (temp && temp->rawsize != 0)
+ total += temp->rawsize;
+
+ i++;
+ }
+
+ /* Check .bss size. */
+ temp = bfd_get_section_by_name (output_bfd, ".bss");
+ if (temp)
+ {
+ if (temp->size != 0)
+ total += temp->size;
+ else if (temp->rawsize != 0)
+ total += temp->rawsize;
+
+ if (total < 0x80000)
+ {
+ if (!first && (temp->size != 0 || temp->rawsize != 0))
+ first = temp;
+ if ((temp->size != 0 || temp->rawsize != 0))
+ final = temp;
+ }
+ }
+
+ if (first && final)
+ {
+ /* The middle of data region. */
+ sda_base = final->vma / 2 + final->rawsize / 2 + first->vma / 2;
+
+ /* Find the section sda_base located. */
+ i = 0;
+ while (i < sizeof (sec_name) / sizeof (sec_name [0]))
+ {
+ final = bfd_get_section_by_name (output_bfd, sec_name[i]);
+ if (final && (final->size != 0 || final->rawsize != 0)
+ && sda_base >= final->vma)
+ {
+ first = final;
+ i++;
+ }
+ else
+ break;
+ }
+ }
+ else
+ {
+ /* There is not any data section in output bfd, and set _SDA_BASE_ in
+ first output section. */
+ first = output_bfd->sections;
+ while (first && first->size == 0 && first->rawsize == 0)
+ first = first->next;
+ if (!first)
+ {
+ *psb = elf_gp (output_bfd);
+ return bfd_reloc_ok;
+ }
+ sda_base = first->vma + first->rawsize;
+ }
+
+ sda_base -= first->vma;
+ sda_base = sda_base & (~7);
+
+ if (!_bfd_generic_link_add_one_symbol
+ (info, output_bfd, "_SDA_BASE_", BSF_GLOBAL | BSF_WEAK, first,
+ (bfd_vma) sda_base, (const char *) NULL, FALSE,
+ get_elf_backend_data (output_bfd)->collect, &h))
+ return FALSE;
+
+ sda_rela_sec = first;
+
+ table = nds32_elf_hash_table (info);
+ relax_fp_as_gp = table->relax_fp_as_gp;
+ if (relax_fp_as_gp)
+ {
+ h2 = bfd_link_hash_lookup (info->hash, FP_BASE_NAME,
+ FALSE, FALSE, FALSE);
+ /* Define a weak FP_BASE_NAME here to prevent the undefined symbol.
+ And set FP equal to SDA_BASE to do relaxation for
+ la $fp, _FP_BASE_. */
+ if (!_bfd_generic_link_add_one_symbol
+ (info, output_bfd, FP_BASE_NAME, BSF_GLOBAL | BSF_WEAK,
+ first, (bfd_vma) sda_base, (const char *) NULL,
+ FALSE, get_elf_backend_data (output_bfd)->collect, &h2))
+ return FALSE;
+ }
+ }
+
+ if (add_symbol == TRUE)
+ {
+ if (h)
+ {
+ /* Now set gp. */
+ elf_gp (output_bfd) = (h->u.def.value
+ + h->u.def.section->output_section->vma
+ + h->u.def.section->output_offset);
+ }
+ else
+ {
+ (*_bfd_error_handler) (_("error: Can't find symbol: _SDA_BASE_."));
+ return bfd_reloc_dangerous;
+ }
+ }
+
+ *psb = h->u.def.value + h->u.def.section->output_section->vma
+ + h->u.def.section->output_offset;
+ return bfd_reloc_ok;
+}
+
+
+/* Return size of a PLT entry. */
+#define elf_nds32_sizeof_plt(info) PLT_ENTRY_SIZE
+
+
+/* Create an entry in an nds32 ELF linker hash table. */
+
+static struct bfd_hash_entry *
+nds32_elf_link_hash_newfunc (struct bfd_hash_entry *entry,
+ struct bfd_hash_table *table,
+ const char *string)
+{
+ struct elf_nds32_link_hash_entry *ret;
+
+ ret = (struct elf_nds32_link_hash_entry *) entry;
+
+ /* Allocate the structure if it has not already been allocated by a
+ subclass. */
+ if (ret == NULL)
+ ret = (struct elf_nds32_link_hash_entry *)
+ bfd_hash_allocate (table, sizeof (struct elf_nds32_link_hash_entry));
+
+ if (ret == NULL)
+ return (struct bfd_hash_entry *) ret;
+
+ /* Call the allocation method of the superclass. */
+ ret = (struct elf_nds32_link_hash_entry *)
+ _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry *) ret, table, string);
+
+ if (ret != NULL)
+ {
+ struct elf_nds32_link_hash_entry *eh;
+
+ eh = (struct elf_nds32_link_hash_entry *) ret;
+ eh->dyn_relocs = NULL;
+ eh->tls_type = GOT_UNKNOWN;
+ }
+
+ return (struct bfd_hash_entry *) ret;
+}
+
+/* Create an nds32 ELF linker hash table. */
+
+static struct bfd_link_hash_table *
+nds32_elf_link_hash_table_create (bfd *abfd)
+{
+ struct elf_nds32_link_hash_table *ret;
+
+ bfd_size_type amt = sizeof (struct elf_nds32_link_hash_table);
+
+ ret = (struct elf_nds32_link_hash_table *) bfd_zmalloc (amt);
+ if (ret == NULL)
+ return NULL;
+
+ /* patch tag. */
+ if (!_bfd_elf_link_hash_table_init (&ret->root, abfd,
+ nds32_elf_link_hash_newfunc,
+ sizeof (struct elf_nds32_link_hash_entry),
+ NDS32_ELF_DATA))
+ {
+ free (ret);
+ return NULL;
+ }
+
+ ret->sgot = NULL;
+ ret->sgotplt = NULL;
+ ret->srelgot = NULL;
+ ret->splt = NULL;
+ ret->srelplt = NULL;
+ ret->sdynbss = NULL;
+ ret->srelbss = NULL;
+ ret->sym_ld_script = NULL;
+ ret->ex9_export_file = NULL;
+ ret->ex9_import_file = NULL;
+
+ return &ret->root.root;
+}
+
+/* Create .got, .gotplt, and .rela.got sections in DYNOBJ, and set up
+ shortcuts to them in our hash table. */
+
+static bfd_boolean
+create_got_section (bfd *dynobj, struct bfd_link_info *info)
+{
+ struct elf_nds32_link_hash_table *htab;
+
+ if (!_bfd_elf_create_got_section (dynobj, info))
+ return FALSE;
+
+ htab = nds32_elf_hash_table (info);
+ htab->sgot = bfd_get_section_by_name (dynobj, ".got");
+ htab->sgotplt = bfd_get_section_by_name (dynobj, ".got.plt");
+ if (!htab->sgot || !htab->sgotplt)
+ abort ();
+
+ /* _bfd_elf_create_got_section will create it for us. */
+ htab->srelgot = bfd_get_section_by_name (dynobj, ".rela.got");
+ if (htab->srelgot == NULL
+ || !bfd_set_section_flags (dynobj, htab->srelgot,
+ (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS
+ | SEC_IN_MEMORY | SEC_LINKER_CREATED
+ | SEC_READONLY))
+ || !bfd_set_section_alignment (dynobj, htab->srelgot, 2))
+ return FALSE;
+
+ return TRUE;
+}
+
+/* Create dynamic sections when linking against a dynamic object. */
+
+static bfd_boolean
+nds32_elf_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
+{
+ struct elf_nds32_link_hash_table *htab;
+ flagword flags, pltflags;
+ register asection *s;
+ const struct elf_backend_data *bed;
+ int ptralign = 2; /* 32-bit */
+
+ bed = get_elf_backend_data (abfd);
+
+ htab = nds32_elf_hash_table (info);
+
+ /* 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");
+ htab->splt = s;
+ 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 bfd_link_hash_entry *bh = NULL;
+ struct elf_link_hash_entry *h;
+
+ 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, &bh)))
+ return FALSE;
+
+ h = (struct elf_link_hash_entry *) bh;
+ h->def_regular = 1;
+ h->type = STT_OBJECT;
+
+ if (info->shared && !bfd_elf_link_record_dynamic_symbol (info, h))
+ return FALSE;
+ }
+
+ s = bfd_make_section (abfd,
+ bed->default_use_rela_p ? ".rela.plt" : ".rel.plt");
+ htab->srelplt = s;
+ if (s == NULL
+ || !bfd_set_section_flags (abfd, s, flags | SEC_READONLY)
+ || !bfd_set_section_alignment (abfd, s, ptralign))
+ return FALSE;
+
+ if (htab->sgot == NULL && !create_got_section (abfd, info))
+ return FALSE;
+
+ {
+ const char *secname;
+ char *relname;
+ flagword secflags;
+ asection *sec;
+
+ for (sec = abfd->sections; sec; sec = sec->next)
+ {
+ secflags = bfd_get_section_flags (abfd, sec);
+ if ((secflags & (SEC_DATA | SEC_LINKER_CREATED))
+ || ((secflags & SEC_HAS_CONTENTS) != SEC_HAS_CONTENTS))
+ continue;
+ secname = bfd_get_section_name (abfd, sec);
+ relname = (char *) bfd_malloc ((bfd_size_type) strlen (secname) + 6);
+ strcpy (relname, ".rela");
+ strcat (relname, secname);
+ if (bfd_get_section_by_name (abfd, secname))
+ continue;
+ s = bfd_make_section (abfd, relname);
+ if (s == NULL
+ || !bfd_set_section_flags (abfd, s, flags | SEC_READONLY)
+ || !bfd_set_section_alignment (abfd, s, ptralign))
+ return FALSE;
+ }
+ }
+
+ if (bed->want_dynbss)
+ {
+ /* 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");
+ htab->sdynbss = s;
+ if (s == NULL
+ || !bfd_set_section_flags (abfd, s, SEC_ALLOC | SEC_LINKER_CREATED))
+ 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->default_use_rela_p
+ ? ".rela.bss" : ".rel.bss"));
+ htab->srelbss = s;
+ if (s == NULL
+ || !bfd_set_section_flags (abfd, s, flags | SEC_READONLY)
+ || !bfd_set_section_alignment (abfd, s, ptralign))
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+/* Copy the extra info we tack onto an elf_link_hash_entry. */
+static void
+nds32_elf_copy_indirect_symbol (struct bfd_link_info *info,
+ struct elf_link_hash_entry *dir,
+ struct elf_link_hash_entry *ind)
+{
+ struct elf_nds32_link_hash_entry *edir, *eind;
+
+ edir = (struct elf_nds32_link_hash_entry *) dir;
+ eind = (struct elf_nds32_link_hash_entry *) ind;
+
+ if (eind->dyn_relocs != NULL)
+ {
+ if (edir->dyn_relocs != NULL)
+ {
+ struct elf_nds32_dyn_relocs **pp;
+ struct elf_nds32_dyn_relocs *p;
+
+ if (ind->root.type == bfd_link_hash_indirect)
+ abort ();
+
+ /* Add reloc counts against the weak sym to the strong sym
+ list. Merge any entries against the same section. */
+ for (pp = &eind->dyn_relocs; (p = *pp) != NULL;)
+ {
+ struct elf_nds32_dyn_relocs *q;
+
+ for (q = edir->dyn_relocs; q != NULL; q = q->next)
+ if (q->sec == p->sec)
+ {
+ q->pc_count += p->pc_count;
+ q->count += p->count;
+ *pp = p->next;
+ break;
+ }
+ if (q == NULL)
+ pp = &p->next;
+ }
+ *pp = edir->dyn_relocs;
+ }
+
+ edir->dyn_relocs = eind->dyn_relocs;
+ eind->dyn_relocs = NULL;
+ }
+
+ _bfd_elf_link_hash_copy_indirect (info, dir, ind);
+}
+
+
+/* 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 bfd_boolean
+nds32_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
+ struct elf_link_hash_entry *h)
+{
+ struct elf_nds32_link_hash_table *htab;
+ struct elf_nds32_link_hash_entry *eh;
+ struct elf_nds32_dyn_relocs *p;
+ 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->needs_plt
+ || h->u.weakdef != NULL
+ || (h->def_dynamic && h->ref_regular && !h->def_regular)));
+
+
+ /* 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->needs_plt)
+ {
+ if (!info->shared
+ && !h->def_dynamic
+ && !h->ref_dynamic
+ && h->root.type != bfd_link_hash_undefweak
+ && h->root.type != bfd_link_hash_undefined)
+ {
+ /* This case can occur if we saw a PLT 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 PCREL
+ reloc instead. */
+ h->plt.offset = (bfd_vma) - 1;
+ h->needs_plt = 0;
+ }
+
+ return TRUE;
+ }
+ else
+ 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->u.weakdef != NULL)
+ {
+ BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
+ || h->u.weakdef->root.type == bfd_link_hash_defweak);
+ h->root.u.def.section = h->u.weakdef->root.u.def.section;
+ h->root.u.def.value = h->u.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;
+
+ /* If there are no references to this symbol that do not use the
+ GOT, we don't need to generate a copy reloc. */
+ if (!h->non_got_ref)
+ return TRUE;
+
+ /* If -z nocopyreloc was given, we won't generate them either. */
+ if (info->nocopyreloc)
+ {
+ h->non_got_ref = 0;
+ return TRUE;
+ }
+
+ eh = (struct elf_nds32_link_hash_entry *) h;
+ for (p = eh->dyn_relocs; p != NULL; p = p->next)
+ {
+ s = p->sec->output_section;
+ if (s != NULL && (s->flags & (SEC_READONLY | SEC_HAS_CONTENTS)) != 0)
+ break;
+ }
+
+ /* If we didn't find any dynamic relocs in sections which needs the
+ copy reloc, then we'll be keeping the dynamic relocs and avoiding
+ the copy reloc. */
+ if (p == NULL)
+ {
+ h->non_got_ref = 0;
+ 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. */
+
+ htab = nds32_elf_hash_table (info);
+ s = htab->sdynbss;
+ BFD_ASSERT (s != NULL);
+
+ /* We must generate a R_NDS32_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 = htab->srelbss;
+ BFD_ASSERT (srel != NULL);
+ srel->size += sizeof (Elf32_External_Rela);
+ h->needs_copy = 1;
+ }
+
+ /* 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->size = BFD_ALIGN (s->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->size;
+
+ /* Increment the section size to make room for the symbol. */
+ s->size += h->size;
+
+ return TRUE;
+}
+
+/* Allocate space in .plt, .got and associated reloc sections for
+ dynamic relocs. */
+
+static bfd_boolean
+allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
+{
+ struct bfd_link_info *info;
+ struct elf_nds32_link_hash_table *htab;
+ struct elf_nds32_link_hash_entry *eh;
+ struct elf_nds32_dyn_relocs *p;
+
+ if (h->root.type == bfd_link_hash_indirect)
+ return TRUE;
+
+ if (h->root.type == bfd_link_hash_warning)
+ /* When warning symbols are created, they **replace** the "real"
+ entry in the hash table, thus we never get to see the real
+ symbol in a hash traversal. So look at it now. */
+ h = (struct elf_link_hash_entry *) h->root.u.i.link;
+
+ info = (struct bfd_link_info *) inf;
+ htab = nds32_elf_hash_table (info);
+
+ eh = (struct elf_nds32_link_hash_entry *) h;
+
+ if (htab->root.dynamic_sections_created && h->plt.refcount > 0)
+ {
+ /* Make sure this symbol is output as a dynamic symbol.
+ Undefined weak syms won't yet be marked as dynamic. */
+ if (h->dynindx == -1 && !h->forced_local)
+ {
+ if (!bfd_elf_link_record_dynamic_symbol (info, h))
+ return FALSE;
+ }
+
+ if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, info->shared, h))
+ {
+ asection *s = htab->splt;
+
+ /* If this is the first .plt entry, make room for the special
+ first entry. */
+ if (s->size == 0)
+ s->size += PLT_ENTRY_SIZE;
+
+ h->plt.offset = s->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->def_regular)
+ {
+ h->root.u.def.section = s;
+ h->root.u.def.value = h->plt.offset;
+ }
+
+ /* Make room for this entry. */
+ s->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. */
+ htab->sgotplt->size += 4;
+
+ /* We also need to make an entry in the .rel.plt section. */
+ htab->srelplt->size += sizeof (Elf32_External_Rela);
+ }
+ else
+ {
+ h->plt.offset = (bfd_vma) - 1;
+ h->needs_plt = 0;
+ }
+ }
+ else
+ {
+ h->plt.offset = (bfd_vma) - 1;
+ h->needs_plt = 0;
+ }
+
+ if (h->got.refcount > 0)
+ {
+ asection *s;
+ bfd_boolean dyn;
+ int tls_type = elf32_nds32_hash_entry (h)->tls_type;
+
+ /* Make sure this symbol is output as a dynamic symbol.
+ Undefined weak syms won't yet be marked as dynamic. */
+ if (h->dynindx == -1 && !h->forced_local)
+ {
+ if (!bfd_elf_link_record_dynamic_symbol (info, h))
+ return FALSE;
+ }
+
+ s = htab->sgot;
+ h->got.offset = s->size;
+
+ if (tls_type == GOT_UNKNOWN)
+ abort ();
+ else if (tls_type == GOT_NORMAL
+ || tls_type == GOT_TLS_IE)
+ /* Need a GOT slot. */
+ s->size += 4;
+
+ dyn = htab->root.dynamic_sections_created;
+ if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h))
+ htab->srelgot->size += sizeof (Elf32_External_Rela);
+ }
+ else
+ h->got.offset = (bfd_vma) - 1;
+
+ if (eh->dyn_relocs == NULL)
+ return TRUE;
+
+ /* In the shared -Bsymbolic case, discard space allocated for
+ dynamic pc-relative relocs against symbols which turn out to be
+ defined in regular objects. For the normal shared case, discard
+ space for pc-relative relocs that have become local due to symbol
+ visibility changes. */
+
+ if (info->shared)
+ {
+ if (h->def_regular && (h->forced_local || info->symbolic))
+ {
+ struct elf_nds32_dyn_relocs **pp;
+
+ for (pp = &eh->dyn_relocs; (p = *pp) != NULL;)
+ {
+ p->count -= p->pc_count;
+ p->pc_count = 0;
+ if (p->count == 0)
+ *pp = p->next;
+ else
+ pp = &p->next;
+ }
+ }
+ }
+ else
+ {
+ /* For the non-shared case, discard space for relocs against
+ symbols which turn out to need copy relocs or are not dynamic. */
+
+ if (!h->non_got_ref
+ && ((h->def_dynamic
+ && !h->def_regular)
+ || (htab->root.dynamic_sections_created
+ && (h->root.type == bfd_link_hash_undefweak
+ || h->root.type == bfd_link_hash_undefined))))
+ {
+ /* Make sure this symbol is output as a dynamic symbol.
+ Undefined weak syms won't yet be marked as dynamic. */
+ if (h->dynindx == -1 && !h->forced_local)
+ {
+ if (!bfd_elf_link_record_dynamic_symbol (info, h))
+ return FALSE;
+ }
+
+ /* If that succeeded, we know we'll be keeping all the
+ relocs. */
+ if (h->dynindx != -1)
+ goto keep;
+ }
+
+ eh->dyn_relocs = NULL;
+
+ keep:;
+ }
+
+ /* Finally, allocate space. */
+ for (p = eh->dyn_relocs; p != NULL; p = p->next)
+ {
+ asection *sreloc = elf_section_data (p->sec)->sreloc;
+ sreloc->size += p->count * sizeof (Elf32_External_Rela);
+ }
+
+ return TRUE;
+}
+
+/* Find any dynamic relocs that apply to read-only sections. */
+
+static bfd_boolean
+readonly_dynrelocs (struct elf_link_hash_entry *h, void *inf)
+{
+ struct elf_nds32_link_hash_entry *eh;
+ struct elf_nds32_dyn_relocs *p;
+
+ if (h->root.type == bfd_link_hash_warning)
+ h = (struct elf_link_hash_entry *) h->root.u.i.link;
+
+ eh = (struct elf_nds32_link_hash_entry *) h;
+ for (p = eh->dyn_relocs; p != NULL; p = p->next)
+ {
+ asection *s = p->sec->output_section;
+
+ if (s != NULL && (s->flags & SEC_READONLY) != 0)
+ {
+ struct bfd_link_info *info = (struct bfd_link_info *) inf;
+
+ info->flags |= DF_TEXTREL;
+
+ /* Not an error, just cut short the traversal. */
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+/* Set the sizes of the dynamic sections. */
+
+static bfd_boolean
+nds32_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
+ struct bfd_link_info *info)
+{
+ struct elf_nds32_link_hash_table *htab;
+ bfd *dynobj;
+ asection *s;
+ bfd_boolean relocs;
+ bfd *ibfd;
+
+ htab = nds32_elf_hash_table (info);
+ dynobj = htab->root.dynobj;
+ BFD_ASSERT (dynobj != NULL);
+
+ if (htab->root.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->size = sizeof ELF_DYNAMIC_INTERPRETER;
+ s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
+ }
+ }
+
+ /* Set up .got offsets for local syms, and space for local dynamic
+ relocs. */
+ for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next)
+ {
+ bfd_signed_vma *local_got;
+ bfd_signed_vma *end_local_got;
+ bfd_size_type locsymcount;
+ Elf_Internal_Shdr *symtab_hdr;
+ asection *srel;
+
+ if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour)
+ continue;
+
+ for (s = ibfd->sections; s != NULL; s = s->next)
+ {
+ struct elf_nds32_dyn_relocs *p;
+
+ for (p = ((struct elf_nds32_dyn_relocs *)
+ elf_section_data (s)->local_dynrel);
+ p != NULL; p = p->next)
+ {
+ if (!bfd_is_abs_section (p->sec)
+ && bfd_is_abs_section (p->sec->output_section))
+ {
+ /* Input section has been discarded, either because
+ it is a copy of a linkonce section or due to
+ linker script /DISCARD/, so we'll be discarding
+ the relocs too. */
+ }
+ else if (p->count != 0)
+ {
+ srel = elf_section_data (p->sec)->sreloc;
+ srel->size += p->count * sizeof (Elf32_External_Rela);
+ if ((p->sec->output_section->flags & SEC_READONLY) != 0)
+ info->flags |= DF_TEXTREL;
+ }
+ }
+ }
+
+ local_got = elf_local_got_refcounts (ibfd);
+ if (!local_got)
+ continue;
+
+ symtab_hdr = &elf_tdata (ibfd)->symtab_hdr;
+ locsymcount = symtab_hdr->sh_info;
+ end_local_got = local_got + locsymcount;
+ s = htab->sgot;
+ srel = htab->srelgot;
+ for (; local_got < end_local_got; ++local_got)
+ {
+ if (*local_got > 0)
+ {
+ *local_got = s->size;
+ s->size += 4;
+ if (info->shared)
+ srel->size += sizeof (Elf32_External_Rela);
+ }
+ else
+ *local_got = (bfd_vma) - 1;
+ }
+ }
+
+ /* Allocate global sym .plt and .got entries, and space for global
+ sym dynamic relocs. */
+ elf_link_hash_traverse (&htab->root, allocate_dynrelocs, (void *) info);
+
+ /* We now have determined the sizes of the various dynamic sections.
+ Allocate memory for them. */
+ relocs = FALSE;
+ for (s = dynobj->sections; s != NULL; s = s->next)
+ {
+ if ((s->flags & SEC_LINKER_CREATED) == 0)
+ continue;
+
+ if (s == htab->splt)
+ {
+ /* Strip this section if we don't need it; see the
+ comment below. */
+ }
+ else if (s == htab->sgot)
+ {
+ got_size += s->size;
+ }
+ else if (s == htab->sgotplt)
+ {
+ got_size += s->size;
+ }
+ else if (strncmp (bfd_get_section_name (dynobj, s), ".rela", 5) == 0)
+ {
+ if (s->size != 0 && s != htab->srelplt)
+ relocs = 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
+ {
+ /* It's not one of our sections, so don't allocate space. */
+ continue;
+ }
+
+ if (s->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. */
+ s->flags |= SEC_EXCLUDE;
+ continue;
+ }
+
+ /* Allocate memory for the section contents. We use bfd_zalloc
+ here in case unused entries are not reclaimed before the
+ section's contents are written out. This should not happen,
+ but this way if it does, we get a R_NDS32_NONE reloc instead
+ of garbage. */
+ s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->size);
+ if (s->contents == NULL)
+ return FALSE;
+ }
+
+
+ if (htab->root.dynamic_sections_created)
+ {
+ /* Add some entries to the .dynamic section. We fill in the
+ values later, in nds32_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. */
+#define add_dynamic_entry(TAG, VAL) \
+ _bfd_elf_add_dynamic_entry (info, TAG, VAL)
+
+ if (!info->shared)
+ {
+ if (!add_dynamic_entry (DT_DEBUG, 0))
+ return FALSE;
+ }
+
+ if (htab->splt->size != 0)
+ {
+ if (!add_dynamic_entry (DT_PLTGOT, 0)
+ || !add_dynamic_entry (DT_PLTRELSZ, 0)
+ || !add_dynamic_entry (DT_PLTREL, DT_RELA)
+ || !add_dynamic_entry (DT_JMPREL, 0))
+ return FALSE;
+ }
+
+ if (relocs)
+ {
+ if (!add_dynamic_entry (DT_RELA, 0)
+ || !add_dynamic_entry (DT_RELASZ, 0)
+ || !add_dynamic_entry (DT_RELAENT, sizeof (Elf32_External_Rela)))
+ return FALSE;
+
+ /* If any dynamic relocs apply to a read-only section,
+ then we need a DT_TEXTREL entry. */
+ if ((info->flags & DF_TEXTREL) == 0)
+ elf_link_hash_traverse (&htab->root, readonly_dynrelocs,
+ (void *) info);
+
+ if ((info->flags & DF_TEXTREL) != 0)
+ {
+ if (!add_dynamic_entry (DT_TEXTREL, 0))
+ return FALSE;
+ }
+ }
+ }
+#undef add_dynamic_entry
+
+ return TRUE;
+}
+
+static bfd_reloc_status_type
+nds32_relocate_contents (reloc_howto_type *howto, bfd *input_bfd,
+ bfd_vma relocation, bfd_byte *location)
+{
+ int size;
+ bfd_vma x = 0;
+ bfd_reloc_status_type flag;
+ 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:
+ case 1:
+ case 8:
+ abort ();
+ break;
+ case 2:
+ x = bfd_getb16 (location);
+ break;
+ case 4:
+ x = bfd_getb32 (location);
+ 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. */
+ flag = bfd_reloc_ok;
+ 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);
+ signmask = ~fieldmask;
+ addrmask = N_ONES (bfd_arch_bits_per_address (input_bfd)) | fieldmask;
+ a = (relocation & addrmask) >> rightshift;
+ b = (x & howto->src_mask & addrmask) >> bitpos;
+
+ switch (howto->complain_on_overflow)
+ {
+ 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. */
+ signmask = ~(fieldmask >> 1);
+ /* Fall through. */
+
+ case complain_overflow_bitfield:
+ /* Much like the signed check, but for a field one bit
+ wider. We allow a bitfield to represent numbers in the
+ range -2**n to 2**n-1, where n is the number of bits in the
+ field. Note that when bfd_vma is 32 bits, a 32-bit reloc
+ can't overflow, which is exactly what we want. */
+ ss = a & signmask;
+ if (ss != 0 && ss != ((addrmask >> rightshift) & signmask))
+ flag = bfd_reloc_overflow;
+
+ /* 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. */
+ ss = ((~howto->src_mask) >> 1) & howto->src_mask;
+ ss >>= bitpos;
+
+ /* Set all the bits above the sign bit. */
+ b = (b ^ ss) - ss;
+
+ /* 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)
+
+ We mask with addrmask here to explicitly allow an address
+ wrap-around. The Linux kernel relies on it, and it is
+ the only way to write assembler code which can run when
+ loaded at a location 0x80000000 away from the location at
+ which it is linked. */
+ if (((~(a ^ b)) & (a ^ sum)) & signmask & addrmask)
+ flag = bfd_reloc_overflow;
+
+ 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. */
+ sum = (a + b) & addrmask;
+ if ((a | b | sum) & signmask)
+ flag = bfd_reloc_overflow;
+ 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. */
+ /* FIXME : 090616
+ Because the relaxation may generate duplicate relocation at one address,
+ an addition to immediate in the instruction may cause the relocation added
+ several times.
+ This bug should be fixed in assembler, but a check is also needed here. */
+ if (howto->partial_inplace)
+ x = ((x & ~howto->dst_mask)
+ | (((x & howto->src_mask) + relocation) & howto->dst_mask));
+ else
+ x = ((x & ~howto->dst_mask) | ((relocation) & howto->dst_mask));
+
+
+ /* Put the relocated value back in the object file. */
+ switch (size)
+ {
+ default:
+ case 0:
+ case 1:
+ case 8:
+ abort ();
+ break;
+ case 2:
+ bfd_putb16 (x, location);
+ break;
+ case 4:
+ bfd_putb32 (x, location);
+ break;
+ }
+
+ return flag;
+}
+
+static bfd_reloc_status_type
+nds32_elf_final_link_relocate (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 > bfd_get_section_limit (input_bfd, input_section))
+ 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 nds32_relocate_contents (howto, input_bfd, relocation,
+ contents + address);
+}
+
+static bfd_boolean
+nds32_elf_output_symbol_hook (struct bfd_link_info *info,
+ const char *name,
+ Elf_Internal_Sym *elfsym ATTRIBUTE_UNUSED,
+ asection *input_sec,
+ struct elf_link_hash_entry *h ATTRIBUTE_UNUSED)
+{
+ const char *source;
+ FILE *sym_ld_script = NULL;
+ struct elf_nds32_link_hash_table *table;
+
+ table = nds32_elf_hash_table (info);
+ sym_ld_script = table->sym_ld_script;
+ if (!sym_ld_script)
+ return TRUE;
+
+ if (!h || !name || *name == '\0')
+ return TRUE;
+
+ if (input_sec->flags & SEC_EXCLUDE)
+ return TRUE;
+
+ if (!check_start_export_sym)
+ {
+ fprintf (sym_ld_script, "SECTIONS\n{\n");
+ check_start_export_sym = 1;
+ }
+
+ if (h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak)
+ {
+ if (!h->root.u.def.section->output_section)
+ return TRUE;
+
+ if (bfd_is_const_section (input_sec))
+ source = input_sec->name;
+ else
+ source = input_sec->owner->filename;
+
+ fprintf (sym_ld_script, "\t%s = 0x%08lx;\t /* %s */\n",
+ h->root.root.string,
+ (long) (h->root.u.def.value
+ + h->root.u.def.section->output_section->vma
+ + h->root.u.def.section->output_offset), source);
+ }
+
+ return TRUE;
+}
+
+/* Relocate an NDS32/D ELF section.
+ There is some attempt to make this function usable for many architectures,
+ both for RELA and REL type relocs, 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
+ relocatable 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 relocatable 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 bfd_vma
+dtpoff_base (struct bfd_link_info *info)
+{
+ /* If tls_sec is NULL, we should have signalled an error already. */
+ if (elf_hash_table (info)->tls_sec == NULL)
+ return 0;
+ return elf_hash_table (info)->tls_sec->vma;
+}
+
+static bfd_boolean
+nds32_elf_relocate_section (bfd * output_bfd ATTRIBUTE_UNUSED,
+ 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;
+ bfd_boolean ret = TRUE; /* Assume success. */
+ int align = 0;
+ bfd_reloc_status_type r;
+ const char *errmsg = NULL;
+ bfd_vma gp;
+ struct elf_nds32_link_hash_table *htab;
+ bfd *dynobj;
+ bfd_vma *local_got_offsets;
+ asection *sgot, *splt, *sreloc;
+ bfd_vma high_address;
+ struct elf_nds32_link_hash_table *table;
+ int eliminate_gc_relocs;
+ bfd_vma fpbase_addr;
+
+ symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
+ sym_hashes = elf_sym_hashes (input_bfd);
+ htab = nds32_elf_hash_table (info);
+ high_address = bfd_get_section_limit (input_bfd, input_section);
+
+ dynobj = htab->root.dynobj;
+ local_got_offsets = elf_local_got_offsets (input_bfd);
+
+ sgot = htab->sgot;
+ splt = htab->splt;
+ sreloc = NULL;
+
+ rel = relocs;
+ relend = relocs + input_section->reloc_count;
+
+ table = nds32_elf_hash_table (info);
+ eliminate_gc_relocs = table->eliminate_gc_relocs;
+ /* By this time, we can adjust the value of _SDA_BASE_. */
+ if ((!info->relocatable))
+ {
+ is_SDA_BASE_set = 1;
+ r = nds32_elf_final_sda_base (output_bfd, info, &gp, TRUE);
+ if (r != bfd_reloc_ok)
+ return FALSE;
+ }
+
+ if (table->target_optimize & NDS32_RELAX_JUMP_IFC_ON)
+ if (!nds32_elf_ifc_reloc ())
+ (*_bfd_error_handler) (_("error: IFC relocation error."));
+
+ /* Relocation for .ex9.itable. */
+ if (table->target_optimize & NDS32_RELAX_EX9_ON
+ || (table->ex9_import_file && table->update_ex9_table))
+ nds32_elf_ex9_reloc_jmp (info);
+
+ /* Use gp as fp to prevent truncated fit. Because in relaxation time
+ the fp value is set as gp, and it has be reverted for instruction
+ setting fp. */
+ fpbase_addr = elf_gp (output_bfd);
+
+ for (rel = relocs; rel < relend; rel++)
+ {
+ enum elf_nds32_reloc_type r_type;
+ reloc_howto_type *howto = NULL;
+ unsigned long r_symndx;
+ struct elf_link_hash_entry *h = NULL;
+ Elf_Internal_Sym *sym = NULL;
+ asection *sec;
+ bfd_vma relocation;
+
+ /* 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;
+
+ r_type = ELF32_R_TYPE (rel->r_info);
+ if (r_type >= R_NDS32_max)
+ {
+ (*_bfd_error_handler) (_("%B: error: unknown relocation type %d."),
+ input_bfd, r_type);
+ bfd_set_error (bfd_error_bad_value);
+ ret = FALSE;
+ continue;
+ }
+
+ if (r_type == R_NDS32_GNU_VTENTRY
+ || r_type == R_NDS32_GNU_VTINHERIT
+ || r_type == R_NDS32_NONE
+ || r_type == R_NDS32_RELA_GNU_VTENTRY
+ || r_type == R_NDS32_RELA_GNU_VTINHERIT
+ || (r_type >= R_NDS32_INSN16 && r_type <= R_NDS32_25_FIXED_RELA)
+ || r_type == R_NDS32_DATA
+ || r_type == R_NDS32_TRAN
+ || (r_type >= R_NDS32_LONGCALL4 && r_type <= R_NDS32_LONGJUMP6))
+ continue;
+
+ /* If we enter the fp-as-gp region. Resolve the address of best fp-base. */
+ if (ELF32_R_TYPE (rel->r_info) == R_NDS32_RELAX_REGION_BEGIN
+ && (rel->r_addend & R_NDS32_RELAX_REGION_OMIT_FP_FLAG))
+ {
+ int dist;
+
+ /* Distance to relocation of best fp-base is encoded in R_SYM. */
+ dist = rel->r_addend >> 16;
+ fpbase_addr = calculate_memory_address (input_bfd, rel + dist,
+ local_syms, symtab_hdr);
+ }
+ else if (ELF32_R_TYPE (rel->r_info) == R_NDS32_RELAX_REGION_END
+ && (rel->r_addend & R_NDS32_RELAX_REGION_OMIT_FP_FLAG))
+ {
+ fpbase_addr = elf_gp (output_bfd);
+ }
+
+ if (((r_type >= R_NDS32_DWARF2_OP1_RELA
+ && r_type <= R_NDS32_DWARF2_LEB_RELA)
+ || r_type >= R_NDS32_RELAX_ENTRY) && !info->relocatable)
+ continue;
+
+ howto = bfd_elf32_bfd_reloc_type_table_lookup (r_type);
+ r_symndx = ELF32_R_SYM (rel->r_info);
+
+ /* This is a final link. */
+ sym = NULL;
+ sec = NULL;
+ h = NULL;
+
+ if (r_symndx < symtab_hdr->sh_info)
+ {
+ /* Local symbol. */
+ sym = local_syms + r_symndx;
+ sec = local_sections[r_symndx];
+
+ relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
+ addend = rel->r_addend;
+ }
+ else
+ {
+ /* External symbol. */
+ bfd_boolean warned, ignored, unresolved_reloc;
+ int symndx = r_symndx - symtab_hdr->sh_info;
+
+ RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
+ r_symndx, symtab_hdr, sym_hashes, h, sec,
+ relocation, unresolved_reloc, warned,
+ ignored);
+
+ /* la $fp, _FP_BASE_ is per-function (region).
+ Handle it specially. */
+ switch ((int) r_type)
+ {
+ case R_NDS32_SDA19S0_RELA:
+ case R_NDS32_SDA15S0_RELA:
+ case R_NDS32_20_RELA:
+ if (strcmp (elf_sym_hashes (input_bfd)[symndx]->root.root.string,
+ FP_BASE_NAME) == 0)
+ {
+ relocation = fpbase_addr;
+ break;
+ }
+ }
+
+ }
+
+ if (info->relocatable)
+ {
+ /* This is a relocatable 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 (sym != NULL && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
+ rel->r_addend += sec->output_offset + sym->st_value;
+
+ continue;
+ }
+
+ /* Sanity check the address. */
+ if (offset > high_address)
+ {
+ r = bfd_reloc_outofrange;
+ goto check_reloc;
+ }
+
+ if ((r_type >= R_NDS32_DWARF2_OP1_RELA
+ && r_type <= R_NDS32_DWARF2_LEB_RELA)
+ || r_type >= R_NDS32_RELAX_ENTRY)
+ continue;
+
+ switch ((int) r_type)
+ {
+ case R_NDS32_GOTOFF:
+ /* Relocation is relative to the start of the global offset
+ table (for ld24 rx, #uimm24), e.g. access at label+addend
+
+ ld24 rx. #label@GOTOFF + addend
+ sub rx, r12. */
+ case R_NDS32_GOTOFF_HI20:
+ case R_NDS32_GOTOFF_LO12:
+ case R_NDS32_GOTOFF_LO15:
+ case R_NDS32_GOTOFF_LO19:
+ BFD_ASSERT (sgot != NULL);
+
+ relocation -= elf_gp (output_bfd);
+ break;
+
+ case R_NDS32_9_PLTREL:
+ case R_NDS32_25_PLTREL:
+ /* Relocation is to the entry for this symbol in the
+ procedure linkage table. */
+
+ /* The native assembler will generate a 25_PLTREL reloc
+ for a local symbol if you assemble a call from one
+ section to another when using -K pic. */
+ if (h == NULL)
+ break;
+
+ if (h->forced_local)
+ break;
+
+ /* We didn't make a PLT entry for this symbol. This
+ happens when statically linking PIC code, or when
+ using -Bsymbolic. */
+ if (h->plt.offset == (bfd_vma) - 1)
+ break;
+
+ relocation = (splt->output_section->vma
+ + splt->output_offset + h->plt.offset);
+ break;
+
+ case R_NDS32_PLT_GOTREL_HI20:
+ case R_NDS32_PLT_GOTREL_LO12:
+ case R_NDS32_PLT_GOTREL_LO15:
+ case R_NDS32_PLT_GOTREL_LO19:
+ case R_NDS32_PLT_GOTREL_LO20:
+ if (h == NULL || h->forced_local || 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. */
+ relocation -= elf_gp (output_bfd);
+ break;
+ }
+
+ relocation = (splt->output_section->vma
+ + splt->output_offset + h->plt.offset);
+
+ relocation -= elf_gp (output_bfd);
+ break;
+
+ case R_NDS32_PLTREL_HI20:
+ case R_NDS32_PLTREL_LO12:
+
+ /* Relocation is to the entry for this symbol in the
+ procedure linkage table. */
+
+ /* The native assembler will generate a 25_PLTREL reloc
+ for a local symbol if you assemble a call from one
+ section to another when using -K pic. */
+ if (h == NULL)
+ break;
+
+ if (h->forced_local)
+ 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)
+ break;
+
+ relocation = (splt->output_section->vma
+ + splt->output_offset
+ + h->plt.offset + 4)
+ - (input_section->output_section->vma
+ + input_section->output_offset
+ + rel->r_offset);
+
+ break;
+
+ case R_NDS32_GOTPC20:
+ /* .got(_GLOBAL_OFFSET_TABLE_) - pc relocation
+ ld24 rx,#_GLOBAL_OFFSET_TABLE_ */
+ relocation = elf_gp (output_bfd);
+ break;
+
+ case R_NDS32_GOTPC_HI20:
+ case R_NDS32_GOTPC_LO12:
+ {
+ /* .got(_GLOBAL_OFFSET_TABLE_) - pc relocation
+ bl .+4
+ seth rx,#high(_GLOBAL_OFFSET_TABLE_)
+ or3 rx,rx,#low(_GLOBAL_OFFSET_TABLE_ +4)
+ or
+ bl .+4
+ seth rx,#shigh(_GLOBAL_OFFSET_TABLE_)
+ add3 rx,rx,#low(_GLOBAL_OFFSET_TABLE_ +4)
+ */
+ relocation = elf_gp (output_bfd);
+ relocation -= (input_section->output_section->vma
+ + input_section->output_offset + rel->r_offset);
+ break;
+ }
+
+ case R_NDS32_GOT20:
+ /* Fall through. */
+ case R_NDS32_GOT_HI20:
+ case R_NDS32_GOT_LO12:
+ case R_NDS32_GOT_LO15:
+ case R_NDS32_GOT_LO19:
+ /* Relocation is to the entry for this symbol in the global
+ offset table. */
+ BFD_ASSERT (sgot != NULL);
+
+ if (h != NULL)
+ {
+ bfd_boolean dyn;
+ bfd_vma off;
+
+ off = h->got.offset;
+ BFD_ASSERT (off != (bfd_vma) - 1);
+ dyn = htab->root.dynamic_sections_created;
+ if (!WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h)
+ || (info->shared
+ && (info->symbolic
+ || h->dynindx == -1
+ || h->forced_local) && h->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_section->vma + sgot->output_offset + off
+ - elf_gp (output_bfd);
+ }
+ else
+ {
+ bfd_vma off;
+ bfd_byte *loc;
+
+ 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_NDS32_RELATIVE reloc
+ for the dynamic linker. */
+ srelgot = bfd_get_section_by_name (dynobj, ".rela.got");
+ BFD_ASSERT (srelgot != NULL);
+
+ outrel.r_offset = (elf_gp (output_bfd)
+ + sgot->output_offset + off);
+ outrel.r_info = ELF32_R_INFO (0, R_NDS32_RELATIVE);
+ outrel.r_addend = relocation;
+ loc = srelgot->contents;
+ loc +=
+ srelgot->reloc_count * sizeof (Elf32_External_Rela);
+ bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
+ ++srelgot->reloc_count;
+ }
+ local_got_offsets[r_symndx] |= 1;
+ }
+ relocation = sgot->output_section->vma + sgot->output_offset + off
+ - elf_gp (output_bfd);
+ }
+
+ break;
+
+ case R_NDS32_16_RELA:
+ case R_NDS32_20_RELA:
+ case R_NDS32_5_RELA:
+ case R_NDS32_32_RELA:
+ case R_NDS32_9_PCREL_RELA:
+ case R_NDS32_WORD_9_PCREL_RELA:
+ case R_NDS32_10_UPCREL_RELA:
+ case R_NDS32_15_PCREL_RELA:
+ case R_NDS32_17_PCREL_RELA:
+ case R_NDS32_25_PCREL_RELA:
+ case R_NDS32_HI20_RELA:
+ case R_NDS32_LO12S3_RELA:
+ case R_NDS32_LO12S2_RELA:
+ case R_NDS32_LO12S2_DP_RELA:
+ case R_NDS32_LO12S2_SP_RELA:
+ case R_NDS32_LO12S1_RELA:
+ case R_NDS32_LO12S0_RELA:
+ case R_NDS32_LO12S0_ORI_RELA:
+ if (info->shared && r_symndx != 0
+ && (input_section->flags & SEC_ALLOC) != 0
+ && (eliminate_gc_relocs == 0
+ || (sec && (sec->flags & SEC_EXCLUDE) == 0))
+ && ((r_type != R_NDS32_9_PCREL_RELA
+ && r_type != R_NDS32_WORD_9_PCREL_RELA
+ && r_type != R_NDS32_10_UPCREL_RELA
+ && r_type != R_NDS32_15_PCREL_RELA
+ && r_type != R_NDS32_17_PCREL_RELA
+ && r_type != R_NDS32_25_PCREL_RELA
+ && !(r_type == R_NDS32_32_RELA
+ && strcmp (input_section->name, ".eh_frame") == 0))
+ || (h != NULL && h->dynindx != -1
+ && (!info->symbolic || !h->def_regular))))
+ {
+ Elf_Internal_Rela outrel;
+ bfd_boolean skip, relocate;
+ bfd_byte *loc;
+
+ /* 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)->rela.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;
+ relocate = FALSE;
+
+ outrel.r_offset = _bfd_elf_section_offset (output_bfd,
+ info,
+ input_section,
+ rel->r_offset);
+ if (outrel.r_offset == (bfd_vma) - 1)
+ skip = TRUE;
+ else if (outrel.r_offset == (bfd_vma) - 2)
+ skip = TRUE, relocate = TRUE;
+ outrel.r_offset += (input_section->output_section->vma
+ + input_section->output_offset);
+
+ if (skip)
+ memset (&outrel, 0, sizeof outrel);
+ else if (r_type == R_NDS32_17_PCREL_RELA
+ || r_type == R_NDS32_15_PCREL_RELA
+ || r_type == R_NDS32_25_PCREL_RELA)
+ {
+ BFD_ASSERT (h != NULL && h->dynindx != -1);
+ outrel.r_info = ELF32_R_INFO (h->dynindx, r_type);
+ outrel.r_addend = rel->r_addend;
+ }
+ else
+ {
+ /* h->dynindx may be -1 if this symbol was marked to
+ become local. */
+ if (h == NULL
+ || ((info->symbolic || h->dynindx == -1)
+ && h->def_regular))
+ {
+ relocate = TRUE;
+ outrel.r_info = ELF32_R_INFO (0, R_NDS32_RELATIVE);
+ outrel.r_addend = relocation + rel->r_addend;
+ }
+ else
+ {
+ BFD_ASSERT (h->dynindx != -1);
+ outrel.r_info = ELF32_R_INFO (h->dynindx, r_type);
+ outrel.r_addend = rel->r_addend;
+ }
+ }
+
+ loc = sreloc->contents;
+ loc += sreloc->reloc_count * sizeof (Elf32_External_Rela);
+ bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
+ ++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;
+
+ case R_NDS32_25_ABS_RELA:
+ if (info->shared)
+ {
+ (*_bfd_error_handler)
+ (_("%s: warning: cannot deal R_NDS32_25_ABS_RELA in shared "
+ "mode."), bfd_get_filename (input_bfd));
+ return FALSE;
+ }
+ break;
+
+ case R_NDS32_9_PCREL:
+ r = nds32_elf_do_9_pcrel_reloc (input_bfd, howto, input_section,
+ contents, offset,
+ sec, relocation, addend);
+ goto check_reloc;
+
+ case R_NDS32_HI20:
+ {
+ Elf_Internal_Rela *lorel;
+
+ /* We allow an arbitrary number of HI20 relocs before the
+ LO12 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_NDS32_HI20); lorel++)
+ continue;
+ if (lorel < relend
+ && (ELF32_R_TYPE (lorel->r_info) == R_NDS32_LO12S3
+ || ELF32_R_TYPE (lorel->r_info) == R_NDS32_LO12S2
+ || ELF32_R_TYPE (lorel->r_info) == R_NDS32_LO12S1
+ || ELF32_R_TYPE (lorel->r_info) == R_NDS32_LO12S0))
+ {
+ nds32_elf_relocate_hi20 (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);
+ }
+
+ goto check_reloc;
+
+ case R_NDS32_GOT17S2_RELA:
+ case R_NDS32_GOT15S2_RELA:
+ {
+ bfd_vma off;
+
+ BFD_ASSERT (sgot != NULL);
+
+ if (h != NULL)
+ {
+ bfd_boolean dyn;
+
+ off = h->got.offset;
+ BFD_ASSERT (off != (bfd_vma) - 1);
+
+ dyn = htab->root.dynamic_sections_created;
+ if (!WILL_CALL_FINISH_DYNAMIC_SYMBOL
+ (dyn, info->shared, h) || (info->shared
+ && (info->symbolic
+ || h->dynindx == -1
+ || h->forced_local)
+ && h->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_byte *loc;
+
+ 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_NDS32_RELATIVE reloc
+ for the dynamic linker. */
+ srelgot = bfd_get_section_by_name (dynobj, ".rela.got");
+ BFD_ASSERT (srelgot != NULL);
+
+ outrel.r_offset = (elf_gp (output_bfd)
+ + sgot->output_offset + off);
+ outrel.r_info = ELF32_R_INFO (0, R_NDS32_RELATIVE);
+ outrel.r_addend = relocation;
+ loc = srelgot->contents;
+ loc +=
+ srelgot->reloc_count * sizeof (Elf32_External_Rela);
+ bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
+ ++srelgot->reloc_count;
+ }
+ local_got_offsets[r_symndx] |= 1;
+ }
+ }
+ relocation = sgot->output_section->vma + sgot->output_offset + off
+ - elf_gp (output_bfd);
+ }
+ if (relocation & align)
+ {
+ /* Incorrect alignment. */
+ (*_bfd_error_handler)
+ (_("%B: warning: unaligned access to GOT entry."), input_bfd);
+ ret = FALSE;
+ r = bfd_reloc_dangerous;
+ goto check_reloc;
+ }
+ break;
+
+ case R_NDS32_SDA16S3_RELA:
+ case R_NDS32_SDA15S3_RELA:
+ case R_NDS32_SDA15S3:
+ align = 0x7;
+ goto handle_sda;
+
+ case R_NDS32_SDA17S2_RELA:
+ case R_NDS32_SDA15S2_RELA:
+ case R_NDS32_SDA12S2_SP_RELA:
+ case R_NDS32_SDA12S2_DP_RELA:
+ case R_NDS32_SDA15S2:
+ case R_NDS32_SDA_FP7U2_RELA:
+ align = 0x3;
+ goto handle_sda;
+
+ case R_NDS32_SDA18S1_RELA:
+ case R_NDS32_SDA15S1_RELA:
+ case R_NDS32_SDA15S1:
+ align = 0x1;
+ goto handle_sda;
+
+ case R_NDS32_SDA19S0_RELA:
+ case R_NDS32_SDA15S0_RELA:
+ case R_NDS32_SDA15S0:
+ {
+ align = 0x0;
+handle_sda:
+ BFD_ASSERT (sec != NULL);
+
+ /* If the symbol is in the abs section, the out_bfd will be null.
+ This happens when the relocation has a symbol@GOTOFF. */
+ r = nds32_elf_final_sda_base (output_bfd, info, &gp, FALSE);
+ if (r != bfd_reloc_ok)
+ {
+ (*_bfd_error_handler)
+ (_("%B: warning: relocate SDA_BASE failed."), input_bfd);
+ ret = FALSE;
+ goto check_reloc;
+ }
+
+ /* At this point `relocation' contains the object's
+ address. */
+ if (r_type == R_NDS32_SDA_FP7U2_RELA)
+ {
+ relocation -= fpbase_addr;
+ }
+ else
+ relocation -= gp;
+ /* Now it contains the offset from _SDA_BASE_. */
+
+ /* Make sure alignment is correct. */
+
+ if (relocation & align)
+ {
+ /* Incorrect alignment. */
+ (*_bfd_error_handler)
+ (_("%B(%A): warning: unaligned small data access of type %d."),
+ input_bfd, input_section, r_type);
+ ret = FALSE;
+ goto check_reloc;
+ }
+ }
+
+ break;
+ case R_NDS32_17IFC_PCREL_RELA:
+ case R_NDS32_10IFCU_PCREL_RELA:
+ /* do nothing */
+ break;
+
+ case R_NDS32_TLS_LE_HI20:
+ case R_NDS32_TLS_LE_LO12:
+ case R_NDS32_TLS_LE_20:
+ case R_NDS32_TLS_LE_15S0:
+ case R_NDS32_TLS_LE_15S1:
+ case R_NDS32_TLS_LE_15S2:
+ if (elf_hash_table (info)->tls_sec != NULL)
+ relocation -= (elf_hash_table (info)->tls_sec->vma + TP_OFFSET);
+ break;
+ case R_NDS32_TLS_IE_HI20:
+ case R_NDS32_TLS_IE_LO12S2:
+ {
+ /* Relocation is to the entry for this symbol in the global
+ offset table. */
+ unsigned int tls_type;
+ asection *srelgot;
+ Elf_Internal_Rela outrel;
+ bfd_vma off;
+ bfd_byte *loc;
+ int indx = 0;
+
+ BFD_ASSERT (sgot != NULL);
+ if (h != NULL)
+ {
+ bfd_boolean dyn;
+
+ off = h->got.offset;
+ BFD_ASSERT (off != (bfd_vma) - 1);
+ dyn = htab->root.dynamic_sections_created;
+ tls_type = ((struct elf_nds32_link_hash_entry *) h)->tls_type;
+ if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h)
+ && (!info->shared
+ || !SYMBOL_REFERENCES_LOCAL (info, h)))
+ indx = h->dynindx;
+ }
+ else
+ {
+ /* Never happen currently. */
+ BFD_ASSERT (local_got_offsets != NULL
+ && local_got_offsets[r_symndx] != (bfd_vma) - 1);
+
+ off = local_got_offsets[r_symndx];
+
+ tls_type = elf32_nds32_local_got_tls_type (input_bfd)[r_symndx];
+ }
+ relocation = sgot->output_section->vma + sgot->output_offset + off;
+
+ if (r_type == R_NDS32_TLS_IE_LO12S2)
+ break;
+
+ /* 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_boolean need_relocs = FALSE;
+ srelgot = htab->srelgot;
+ if ((info->shared || indx != 0)
+ && (h == NULL
+ || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
+ || h->root.type != bfd_link_hash_undefweak))
+ {
+ need_relocs = TRUE;
+ BFD_ASSERT (srelgot != NULL);
+ }
+ if (tls_type & GOT_TLS_IE)
+ {
+ if (need_relocs)
+ {
+ if (h->dynindx == 0)
+ outrel.r_addend = relocation - dtpoff_base (info);
+ else
+ outrel.r_addend = 0;
+ outrel.r_offset = (sgot->output_section->vma
+ + sgot->output_offset
+ + off);
+ outrel.r_info =
+ ELF32_R_INFO (h->dynindx, R_NDS32_TLS_TPOFF);
+
+ loc = srelgot->contents;
+ loc +=
+ srelgot->reloc_count * sizeof (Elf32_External_Rela);
+ bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
+ ++srelgot->reloc_count;
+ }
+ else
+ bfd_put_32 (output_bfd, h->root.u.def.value - TP_OFFSET,
+ sgot->contents + off);
+ }
+ }
+ }
+ break;
+
+ /* DON'T fall through. */
+
+ default:
+ /* OLD_NDS32_RELOC. */
+
+ r = _bfd_final_link_relocate (howto, input_bfd, input_section,
+ contents, offset, relocation, addend);
+ goto check_reloc;
+ }
+
+ switch ((int) r_type)
+ {
+ case R_NDS32_20_RELA:
+ case R_NDS32_5_RELA:
+ case R_NDS32_9_PCREL_RELA:
+ case R_NDS32_WORD_9_PCREL_RELA:
+ case R_NDS32_10_UPCREL_RELA:
+ case R_NDS32_15_PCREL_RELA:
+ case R_NDS32_17_PCREL_RELA:
+ case R_NDS32_25_PCREL_RELA:
+ case R_NDS32_25_ABS_RELA:
+ case R_NDS32_HI20_RELA:
+ case R_NDS32_LO12S3_RELA:
+ case R_NDS32_LO12S2_RELA:
+ case R_NDS32_LO12S2_DP_RELA:
+ case R_NDS32_LO12S2_SP_RELA:
+ case R_NDS32_LO12S1_RELA:
+ case R_NDS32_LO12S0_RELA:
+ case R_NDS32_LO12S0_ORI_RELA:
+ case R_NDS32_SDA16S3_RELA:
+ case R_NDS32_SDA17S2_RELA:
+ case R_NDS32_SDA18S1_RELA:
+ case R_NDS32_SDA19S0_RELA:
+ case R_NDS32_SDA15S3_RELA:
+ case R_NDS32_SDA15S2_RELA:
+ case R_NDS32_SDA12S2_DP_RELA:
+ case R_NDS32_SDA12S2_SP_RELA:
+ case R_NDS32_SDA15S1_RELA:
+ case R_NDS32_SDA15S0_RELA:
+ case R_NDS32_SDA_FP7U2_RELA:
+ case R_NDS32_9_PLTREL:
+ case R_NDS32_25_PLTREL:
+ case R_NDS32_GOT20:
+ case R_NDS32_GOT_HI20:
+ case R_NDS32_GOT_LO12:
+ case R_NDS32_GOT_LO15:
+ case R_NDS32_GOT_LO19:
+ case R_NDS32_GOT15S2_RELA:
+ case R_NDS32_GOT17S2_RELA:
+ case R_NDS32_GOTPC20:
+ case R_NDS32_GOTPC_HI20:
+ case R_NDS32_GOTPC_LO12:
+ case R_NDS32_GOTOFF:
+ case R_NDS32_GOTOFF_HI20:
+ case R_NDS32_GOTOFF_LO12:
+ case R_NDS32_GOTOFF_LO15:
+ case R_NDS32_GOTOFF_LO19:
+ case R_NDS32_PLTREL_HI20:
+ case R_NDS32_PLTREL_LO12:
+ case R_NDS32_PLT_GOTREL_HI20:
+ case R_NDS32_PLT_GOTREL_LO12:
+ case R_NDS32_PLT_GOTREL_LO15:
+ case R_NDS32_PLT_GOTREL_LO19:
+ case R_NDS32_PLT_GOTREL_LO20:
+ case R_NDS32_17IFC_PCREL_RELA:
+ case R_NDS32_10IFCU_PCREL_RELA:
+ case R_NDS32_TLS_LE_HI20:
+ case R_NDS32_TLS_LE_LO12:
+ case R_NDS32_TLS_IE_HI20:
+ case R_NDS32_TLS_IE_LO12S2:
+ case R_NDS32_TLS_LE_20:
+ case R_NDS32_TLS_LE_15S0:
+ case R_NDS32_TLS_LE_15S1:
+ case R_NDS32_TLS_LE_15S2:
+ /* Instruction related relocs must handle endian properly. */
+ /* NOTE: PIC IS NOT HANDLE YET; DO IT LATER. */
+ r = nds32_elf_final_link_relocate (howto, input_bfd,
+ input_section, contents,
+ rel->r_offset, relocation,
+ rel->r_addend);
+ break;
+
+ default:
+ /* All other relocs can use default handler. */
+ r = _bfd_final_link_relocate (howto, input_bfd, input_section,
+ contents, rel->r_offset,
+ relocation, rel->r_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, (h ? &h->root : NULL), 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, TRUE)))
+ 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;
+}
+
+/* Finish up dynamic symbol handling. We set the contents of various
+ dynamic sections here. */
+
+static bfd_boolean
+nds32_elf_finish_dynamic_symbol (bfd *output_bfd, struct bfd_link_info *info,
+ struct elf_link_hash_entry *h, Elf_Internal_Sym *sym)
+{
+ struct elf_nds32_link_hash_table *htab;
+ bfd_byte *loc;
+
+ htab = nds32_elf_hash_table (info);
+
+ if (h->plt.offset != (bfd_vma) - 1)
+ {
+ asection *splt;
+ asection *sgot;
+ asection *srela;
+
+ bfd_vma plt_index;
+ bfd_vma got_offset;
+ bfd_vma local_plt_offset;
+ Elf_Internal_Rela rela;
+
+ /* This symbol has an entry in the procedure linkage table. Set
+ it up. */
+
+ BFD_ASSERT (h->dynindx != -1);
+
+ splt = htab->splt;
+ sgot = htab->sgotplt;
+ srela = htab->srelplt;
+ 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. */
+ if (!info->shared)
+ {
+ unsigned long insn;
+
+ insn = PLT_ENTRY_WORD0 + (((sgot->output_section->vma
+ + sgot->output_offset + got_offset) >> 12)
+ & 0xfffff);
+ bfd_putb32 (insn, splt->contents + h->plt.offset);
+
+ insn = PLT_ENTRY_WORD1 + (((sgot->output_section->vma
+ + sgot->output_offset + got_offset) & 0x0fff)
+ >> 2);
+ bfd_putb32 (insn, splt->contents + h->plt.offset + 4);
+
+ insn = PLT_ENTRY_WORD2;
+ bfd_putb32 (insn, splt->contents + h->plt.offset + 8);
+
+ insn = PLT_ENTRY_WORD3 + (plt_index & 0x7ffff);
+ bfd_putb32 (insn, splt->contents + h->plt.offset + 12);
+
+ insn = PLT_ENTRY_WORD4
+ + (((unsigned int) ((-(h->plt.offset + 16)) >> 1)) & 0xffffff);
+ bfd_putb32 (insn, splt->contents + h->plt.offset + 16);
+ local_plt_offset = 12;
+ }
+ else
+ {
+ /* sda_base must be set at this time. */
+ unsigned long insn;
+ long offset;
+
+ /* FIXME, sda_base is 65536, it will damage opcode. */
+ /* insn = PLT_PIC_ENTRY_WORD0 + (((got_offset - sda_base) >> 2) & 0x7fff); */
+ offset = sgot->output_section->vma + sgot->output_offset + got_offset
+ - elf_gp (output_bfd);
+ insn = PLT_PIC_ENTRY_WORD0 + ((offset >> 12) & 0xfffff);
+ bfd_putb32 (insn, splt->contents + h->plt.offset);
+
+ insn = PLT_PIC_ENTRY_WORD1 + (offset & 0xfff);
+ bfd_putb32 (insn, splt->contents + h->plt.offset + 4);
+
+ insn = PLT_PIC_ENTRY_WORD2;
+ bfd_putb32 (insn, splt->contents + h->plt.offset + 8);
+
+ insn = PLT_PIC_ENTRY_WORD3;
+ bfd_putb32 (insn, splt->contents + h->plt.offset + 12);
+
+ insn = PLT_PIC_ENTRY_WORD4 + (plt_index & 0x7fffff);
+ bfd_putb32 (insn, splt->contents + h->plt.offset + 16);
+
+ insn = PLT_PIC_ENTRY_WORD5
+ + (((unsigned int) ((-(h->plt.offset + 20)) >> 1)) & 0xffffff);
+ bfd_putb32 (insn, splt->contents + h->plt.offset + 20);
+
+ local_plt_offset = 16;
+ }
+
+ /* Fill in the entry in the global offset table,
+ so it will fall through to the next instruction for the first time. */
+ bfd_put_32 (output_bfd,
+ (splt->output_section->vma + splt->output_offset
+ + h->plt.offset + local_plt_offset),
+ 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_NDS32_JMP_SLOT);
+ rela.r_addend = 0;
+ loc = srela->contents;
+ loc += plt_index * sizeof (Elf32_External_Rela);
+ bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
+
+ if (!h->def_regular)
+ {
+ /* Mark the symbol as undefined, rather than as defined in
+ the .plt section. Leave the value alone. */
+ sym->st_shndx = SHN_UNDEF;
+ if (!h->ref_regular_nonweak)
+ sym->st_value = 0;
+ }
+ }
+
+ 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 = htab->sgot;
+ srela = htab->srelgot;
+ 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->forced_local) && h->def_regular)
+ {
+ rela.r_info = ELF32_R_INFO (0, R_NDS32_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_NDS32_GLOB_DAT);
+ rela.r_addend = 0;
+ }
+
+ loc = srela->contents;
+ loc += srela->reloc_count * sizeof (Elf32_External_Rela);
+ bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
+ ++srela->reloc_count;
+ }
+
+ if (h->needs_copy)
+ {
+ asection *s;
+ Elf_Internal_Rela rela;
+
+ /* This symbols 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_NDS32_COPY);
+ rela.r_addend = 0;
+ loc = s->contents;
+ loc += s->reloc_count * sizeof (Elf32_External_Rela);
+ bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
+ ++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)
+ sym->st_shndx = SHN_ABS;
+
+ return TRUE;
+}
+
+
+/* Finish up the dynamic sections. */
+
+static bfd_boolean
+nds32_elf_finish_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
+{
+ struct elf_nds32_link_hash_table *htab;
+ bfd *dynobj;
+ asection *sdyn;
+ asection *sgot;
+
+ htab = nds32_elf_hash_table (info);
+ dynobj = htab->root.dynobj;
+
+ sgot = htab->sgotplt;
+ sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
+
+ if (htab->root.dynamic_sections_created)
+ {
+ asection *splt;
+ Elf32_External_Dyn *dyncon, *dynconend;
+
+ BFD_ASSERT (sgot != NULL && sdyn != NULL);
+
+ dyncon = (Elf32_External_Dyn *) sdyn->contents;
+ dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->size);
+
+ for (; dyncon < dynconend; dyncon++)
+ {
+ Elf_Internal_Dyn dyn;
+ asection *s;
+
+ bfd_elf32_swap_dyn_in (dynobj, dyncon, &dyn);
+
+ switch (dyn.d_tag)
+ {
+ default:
+ break;
+
+ case DT_PLTGOT:
+ /* name = ".got"; */
+ s = htab->sgot->output_section;
+ goto get_vma;
+ case DT_JMPREL:
+ s = htab->srelplt->output_section;
+ get_vma:
+ 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 = htab->srelplt->output_section;
+ BFD_ASSERT (s != NULL);
+ dyn.d_un.d_val = s->size;
+ bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
+ break;
+
+ case DT_RELASZ:
+ /* My reading of the SVR4 ABI indicates that the
+ procedure linkage table relocs (DT_JMPREL) should be
+ included in the overall relocs (DT_RELA). This is
+ what Solaris does. However, UnixWare can not handle
+ that case. 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. */
+ if (htab->srelplt != NULL)
+ {
+ s = htab->srelplt->output_section;
+ dyn.d_un.d_val -= s->size;
+ }
+ bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
+ break;
+ }
+ }
+
+ /* Fill in the first entry in the procedure linkage table. */
+ splt = htab->splt;
+ if (splt && splt->size > 0)
+ {
+ if (info->shared)
+ {
+ unsigned long insn;
+ long offset;
+
+ /* FIXME, sda_base is 65536, it will damage opcode. */
+ /* insn = PLT_PIC_ENTRY_WORD0 + (((got_offset - sda_base) >> 2) & 0x7fff); */
+ offset = sgot->output_section->vma + sgot->output_offset + 4
+ - elf_gp (output_bfd);
+ insn = PLT0_PIC_ENTRY_WORD0 | ((offset >> 12) & 0xfffff);
+ bfd_putb32 (insn, splt->contents);
+
+ /* insn = PLT0_PIC_ENTRY_WORD0 | (((8 - sda_base) >> 2) & 0x7fff) ; */
+ /* here has a typo? */
+ insn = PLT0_PIC_ENTRY_WORD1 | (offset & 0xfff);
+ bfd_putb32 (insn, splt->contents + 4);
+
+ insn = PLT0_PIC_ENTRY_WORD2;
+ bfd_putb32 (insn, splt->contents + 8);
+
+ insn = PLT0_PIC_ENTRY_WORD3;
+ bfd_putb32 (insn, splt->contents + 12);
+
+ insn = PLT0_PIC_ENTRY_WORD4;
+ bfd_putb32 (insn, splt->contents + 16);
+
+ insn = PLT0_PIC_ENTRY_WORD5;
+ bfd_putb32 (insn, splt->contents + 20);
+ }
+ else
+ {
+ unsigned long insn;
+ unsigned long addr;
+
+ /* addr = .got + 4 */
+ addr = sgot->output_section->vma + sgot->output_offset + 4;
+ insn = PLT0_ENTRY_WORD0 | ((addr >> 12) & 0xfffff);
+ bfd_putb32 (insn, splt->contents);
+
+ insn = PLT0_ENTRY_WORD1 | (addr & 0x0fff);
+ bfd_putb32 (insn, splt->contents + 4);
+
+ insn = PLT0_ENTRY_WORD2;
+ bfd_putb32 (insn, splt->contents + 8);
+
+ insn = PLT0_ENTRY_WORD3;
+ bfd_putb32 (insn, splt->contents + 12);
+
+ insn = PLT0_ENTRY_WORD4;
+ bfd_putb32 (insn, splt->contents + 16);
+ }
+
+ 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 && sgot->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;
+}
+
+
+/* Set the right machine number. */
+
+static bfd_boolean
+nds32_elf_object_p (bfd *abfd)
+{
+ static unsigned int cur_arch = 0;
+
+ if (E_N1_ARCH != (elf_elfheader (abfd)->e_flags & EF_NDS_ARCH))
+ {
+ /* E_N1_ARCH is a wild card, so it is set only when no others exist. */
+ cur_arch = (elf_elfheader (abfd)->e_flags & EF_NDS_ARCH);
+ }
+
+ switch (cur_arch)
+ {
+ default:
+ case E_N1_ARCH:
+ bfd_default_set_arch_mach (abfd, bfd_arch_nds32, bfd_mach_n1);
+ break;
+ case E_N1H_ARCH:
+ bfd_default_set_arch_mach (abfd, bfd_arch_nds32, bfd_mach_n1h);
+ break;
+ case E_NDS_ARCH_STAR_V2_0:
+ bfd_default_set_arch_mach (abfd, bfd_arch_nds32, bfd_mach_n1h_v2);
+ break;
+ case E_NDS_ARCH_STAR_V3_0:
+ bfd_default_set_arch_mach (abfd, bfd_arch_nds32, bfd_mach_n1h_v3);
+ break;
+ case E_NDS_ARCH_STAR_V3_M:
+ bfd_default_set_arch_mach (abfd, bfd_arch_nds32, bfd_mach_n1h_v3m);
+ break;
+ }
+
+ return TRUE;
+}
+
+/* Store the machine number in the flags field. */
+
+static void
+nds32_elf_final_write_processing (bfd *abfd,
+ bfd_boolean linker ATTRIBUTE_UNUSED)
+{
+ unsigned long val;
+ static unsigned int cur_mach = 0;
+
+ if (bfd_mach_n1 != bfd_get_mach (abfd))
+ {
+ cur_mach = bfd_get_mach (abfd);
+ }
+
+ switch (cur_mach)
+ {
+ case bfd_mach_n1:
+ /* Only happen when object is empty, since the case is abandon. */
+ val = E_N1_ARCH;
+ val |= E_NDS_ABI_AABI;
+ val |= E_NDS32_ELF_VER_1_4;
+ break;
+ case bfd_mach_n1h:
+ val = E_N1H_ARCH;
+ break;
+ case bfd_mach_n1h_v2:
+ val = E_NDS_ARCH_STAR_V2_0;
+ break;
+ case bfd_mach_n1h_v3:
+ val = E_NDS_ARCH_STAR_V3_0;
+ break;
+ case bfd_mach_n1h_v3m:
+ val = E_NDS_ARCH_STAR_V3_M;
+ break;
+ default:
+ val = 0;
+ break;
+ }
+
+ elf_elfheader (abfd)->e_flags &= ~EF_NDS_ARCH;
+ elf_elfheader (abfd)->e_flags |= val;
+}
+
+/* Function to keep NDS32 specific file flags. */
+
+static bfd_boolean
+nds32_elf_set_private_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;
+}
+
+static unsigned int
+convert_e_flags (unsigned int e_flags, unsigned int arch)
+{
+ if ((e_flags & EF_NDS_ARCH) == E_NDS_ARCH_STAR_V0_9)
+ {
+ /* From 0.9 to 1.0. */
+ e_flags = (e_flags & (~EF_NDS_ARCH)) | E_NDS_ARCH_STAR_V1_0;
+
+ /* Invert E_NDS32_HAS_NO_MAC_INST. */
+ e_flags ^= E_NDS32_HAS_NO_MAC_INST;
+ if (arch == E_NDS_ARCH_STAR_V1_0)
+ {
+ /* Done. */
+ return e_flags;
+ }
+ }
+
+ /* From 1.0 to 2.0. */
+ e_flags = (e_flags & (~EF_NDS_ARCH)) | E_NDS_ARCH_STAR_V2_0;
+
+ /* Clear E_NDS32_HAS_MFUSR_PC_INST. */
+ e_flags &= ~E_NDS32_HAS_MFUSR_PC_INST;
+
+ /* Invert E_NDS32_HAS_NO_MAC_INST. */
+ e_flags ^= E_NDS32_HAS_NO_MAC_INST;
+ return e_flags;
+}
+
+static bfd_boolean
+nds32_check_vec_size (bfd *ibfd)
+{
+ static unsigned int nds32_vec_size = 0;
+
+ asection *sec_t = NULL;
+ bfd_byte *contents = NULL;
+
+ sec_t = bfd_get_section_by_name (ibfd, ".nds32_e_flags");
+
+ if (sec_t && sec_t->size >= 4)
+ {
+ /* Get vec_size in file. */
+ unsigned int flag_t;
+
+ nds32_get_section_contents (ibfd, sec_t, &contents);
+ flag_t = bfd_get_32 (ibfd, contents);
+
+ /* The value could only be 4 or 16. */
+
+ if (!nds32_vec_size)
+ /* Set if not set yet. */
+ nds32_vec_size = (flag_t & 0x3);
+ else if (nds32_vec_size != (flag_t & 0x3))
+ {
+ (*_bfd_error_handler) (_("%B: ISR vector size mismatch"
+ " with previous modules, previous %u-byte, current %u-byte"),
+ ibfd,
+ nds32_vec_size == 1 ? 4 : nds32_vec_size == 2 ? 16 : 0xffffffff,
+ (flag_t & 0x3) == 1 ? 4 : (flag_t & 0x3) == 2 ? 16 : 0xffffffff);
+ return FALSE;
+ }
+ else
+ /* Only keep the first vec_size section. */
+ sec_t->flags |= SEC_EXCLUDE;
+ }
+
+ return TRUE;
+}
+
+/* Merge backend specific data from an object file to the output
+ object file when linking. */
+
+static bfd_boolean
+nds32_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
+{
+ flagword out_flags;
+ flagword in_flags;
+ flagword out_16regs;
+ flagword in_no_mac;
+ flagword out_no_mac;
+ flagword in_16regs;
+ flagword out_version;
+ flagword in_version;
+ flagword out_fpu_config;
+ flagword in_fpu_config;
+
+ /* TODO: Revise to use object-attributes instead. */
+ if (!nds32_check_vec_size (ibfd))
+ return FALSE;
+
+ if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
+ || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
+ return TRUE;
+
+ if (bfd_little_endian (ibfd) != bfd_little_endian (obfd))
+ {
+ (*_bfd_error_handler)
+ (_("%B: warning: Endian mismatch with previous modules."), ibfd);
+
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+
+ in_version = elf_elfheader (ibfd)->e_flags & EF_NDS32_ELF_VERSION;
+ if (in_version == E_NDS32_ELF_VER_1_2)
+ {
+ (*_bfd_error_handler)
+ (_("%B: warning: Older version of object file encountered, "
+ "Please recompile with current tool chain."), ibfd);
+ }
+
+ /* We may need to merge V1 and V2 arch object files to V2. */
+ if ((elf_elfheader (ibfd)->e_flags & EF_NDS_ARCH)
+ != (elf_elfheader (obfd)->e_flags & EF_NDS_ARCH))
+ {
+ /* Need to convert version. */
+ if ((elf_elfheader (ibfd)->e_flags & EF_NDS_ARCH)
+ == E_NDS_ARCH_STAR_RESERVED)
+ {
+ elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags;
+ }
+ else if ((elf_elfheader (obfd)->e_flags & EF_NDS_ARCH) == E_NDS_ARCH_STAR_V0_9
+ || (elf_elfheader (ibfd)->e_flags & EF_NDS_ARCH)
+ > (elf_elfheader (obfd)->e_flags & EF_NDS_ARCH))
+ {
+ elf_elfheader (obfd)->e_flags =
+ convert_e_flags (elf_elfheader (obfd)->e_flags,
+ (elf_elfheader (ibfd)->e_flags & EF_NDS_ARCH));
+ }
+ else
+ {
+ elf_elfheader (ibfd)->e_flags =
+ convert_e_flags (elf_elfheader (ibfd)->e_flags,
+ (elf_elfheader (obfd)->e_flags & EF_NDS_ARCH));
+ }
+ }
+
+ /* Extract some flags. */
+ in_flags = elf_elfheader (ibfd)->e_flags
+ & (~(E_NDS32_HAS_REDUCED_REGS | EF_NDS32_ELF_VERSION
+ | E_NDS32_HAS_NO_MAC_INST | E_NDS32_FPU_REG_CONF));
+
+ /* The following flags need special treatment. */
+ in_16regs = elf_elfheader (ibfd)->e_flags & E_NDS32_HAS_REDUCED_REGS;
+ in_no_mac = elf_elfheader (ibfd)->e_flags & E_NDS32_HAS_NO_MAC_INST;
+ in_fpu_config = elf_elfheader (ibfd)->e_flags & E_NDS32_FPU_REG_CONF;
+
+ /* Extract some flags. */
+ out_flags = elf_elfheader (obfd)->e_flags
+ & (~(E_NDS32_HAS_REDUCED_REGS | EF_NDS32_ELF_VERSION
+ | E_NDS32_HAS_NO_MAC_INST | E_NDS32_FPU_REG_CONF));
+
+ /* The following flags need special treatment. */
+ out_16regs = elf_elfheader (obfd)->e_flags & E_NDS32_HAS_REDUCED_REGS;
+ out_no_mac = elf_elfheader (obfd)->e_flags & E_NDS32_HAS_NO_MAC_INST;
+ out_fpu_config = elf_elfheader (obfd)->e_flags & E_NDS32_FPU_REG_CONF;
+ out_version = elf_elfheader (obfd)->e_flags & EF_NDS32_ELF_VERSION;
+ 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 = elf_elfheader (ibfd)->e_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 & EF_NDS_ABI) != (out_flags & EF_NDS_ABI))
+ {
+ (*_bfd_error_handler)
+ (_("%B: error: ABI mismatch with previous modules."), ibfd);
+
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+
+ if ((in_flags & EF_NDS_ARCH) != (out_flags & EF_NDS_ARCH))
+ {
+ if (((in_flags & EF_NDS_ARCH) != E_N1_ARCH))
+ {
+ (*_bfd_error_handler)
+ (_("%B: error: Instruction set mismatch with previous modules."), ibfd);
+
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+ }
+
+ /* When linking with V1.2 and V1.3 objects together the output is V1.2.
+ and perf ext1 and DIV are mergerd to perf ext1. */
+ if (in_version == E_NDS32_ELF_VER_1_2 || out_version == E_NDS32_ELF_VER_1_2)
+ {
+ elf_elfheader (obfd)->e_flags =
+ (in_flags & (~(E_NDS32_HAS_EXT_INST | E_NDS32_HAS_DIV_INST)))
+ | (out_flags & (~(E_NDS32_HAS_EXT_INST | E_NDS32_HAS_DIV_INST)))
+ | (((in_flags & (E_NDS32_HAS_EXT_INST | E_NDS32_HAS_DIV_INST)))
+ ? E_NDS32_HAS_EXT_INST : 0)
+ | (((out_flags & (E_NDS32_HAS_EXT_INST | E_NDS32_HAS_DIV_INST)))
+ ? E_NDS32_HAS_EXT_INST : 0)
+ | (in_16regs & out_16regs) | (in_no_mac & out_no_mac)
+ | ((in_version > out_version) ? out_version : in_version);
+ }
+ else
+ {
+ if (in_version != out_version)
+ (*_bfd_error_handler) (_("%B: warning: Incompatible elf-versions %s and %s."),
+ ibfd, nds32_elfver_strtab[out_version],
+ nds32_elfver_strtab[in_version]);
+
+ elf_elfheader (obfd)->e_flags = in_flags | out_flags
+ | (in_16regs & out_16regs) | (in_no_mac & out_no_mac)
+ | (in_fpu_config > out_fpu_config ? in_fpu_config : out_fpu_config)
+ | (in_version > out_version ? out_version : in_version);
+ }
+
+ return TRUE;
+}
+
+/* Display the flags field. */
+
+static bfd_boolean
+nds32_elf_print_private_bfd_data (bfd *abfd, void *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_NDS_ARCH)
+ {
+ default:
+ case E_N1_ARCH:
+ fprintf (file, _(": n1 instructions"));
+ break;
+ case E_N1H_ARCH:
+ fprintf (file, _(": n1h instructions"));
+ break;
+ }
+
+ fputc ('\n', file);
+
+ return TRUE;
+}
+
+static unsigned int
+nds32_elf_action_discarded (asection *sec)
+{
+
+ if (strncmp
+ (".gcc_except_table", sec->name, sizeof (".gcc_except_table") - 1) == 0)
+ return 0;
+
+ return _bfd_elf_default_action_discarded (sec);
+}
+
+static asection *
+nds32_elf_gc_mark_hook (asection *sec, 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_NDS32_GNU_VTINHERIT:
+ case R_NDS32_GNU_VTENTRY:
+ case R_NDS32_RELA_GNU_VTINHERIT:
+ case R_NDS32_RELA_GNU_VTENTRY:
+ return NULL;
+ }
+
+ return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
+}
+
+static bfd_boolean
+nds32_elf_gc_sweep_hook (bfd *abfd, struct bfd_link_info *info, asection *sec,
+ const Elf_Internal_Rela *relocs)
+{
+ /* Update the got entry reference counts for the section being removed. */
+ Elf_Internal_Shdr *symtab_hdr;
+ struct elf_link_hash_entry **sym_hashes;
+ bfd_signed_vma *local_got_refcounts;
+ const Elf_Internal_Rela *rel, *relend;
+
+ elf_section_data (sec)->local_dynrel = NULL;
+
+ 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++)
+ {
+ unsigned long r_symndx;
+ struct elf_link_hash_entry *h = NULL;
+
+ r_symndx = ELF32_R_SYM (rel->r_info);
+ if (r_symndx >= symtab_hdr->sh_info)
+ {
+ /* 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;
+ }
+
+ switch (ELF32_R_TYPE (rel->r_info))
+ {
+ case R_NDS32_GOT_HI20:
+ case R_NDS32_GOT_LO12:
+ case R_NDS32_GOT_LO15:
+ case R_NDS32_GOT_LO19:
+ case R_NDS32_GOT17S2_RELA:
+ case R_NDS32_GOT15S2_RELA:
+ case R_NDS32_GOTOFF:
+ case R_NDS32_GOTOFF_HI20:
+ case R_NDS32_GOTOFF_LO12:
+ case R_NDS32_GOTOFF_LO15:
+ case R_NDS32_GOTOFF_LO19:
+ case R_NDS32_GOT20:
+ case R_NDS32_GOTPC_HI20:
+ case R_NDS32_GOTPC_LO12:
+ case R_NDS32_GOTPC20:
+ if (h != NULL)
+ {
+ if (h->got.refcount > 0)
+ h->got.refcount--;
+ }
+ else
+ {
+ if (local_got_refcounts && local_got_refcounts[r_symndx] > 0)
+ local_got_refcounts[r_symndx]--;
+ }
+ break;
+
+ case R_NDS32_16_RELA:
+ case R_NDS32_20_RELA:
+ case R_NDS32_5_RELA:
+ case R_NDS32_32_RELA:
+ case R_NDS32_HI20_RELA:
+ case R_NDS32_LO12S3_RELA:
+ case R_NDS32_LO12S2_RELA:
+ case R_NDS32_LO12S2_DP_RELA:
+ case R_NDS32_LO12S2_SP_RELA:
+ case R_NDS32_LO12S1_RELA:
+ case R_NDS32_LO12S0_RELA:
+ case R_NDS32_LO12S0_ORI_RELA:
+ case R_NDS32_SDA16S3_RELA:
+ case R_NDS32_SDA17S2_RELA:
+ case R_NDS32_SDA18S1_RELA:
+ case R_NDS32_SDA19S0_RELA:
+ case R_NDS32_SDA15S3_RELA:
+ case R_NDS32_SDA15S2_RELA:
+ case R_NDS32_SDA12S2_DP_RELA:
+ case R_NDS32_SDA12S2_SP_RELA:
+ case R_NDS32_SDA15S1_RELA:
+ case R_NDS32_SDA15S0_RELA:
+ case R_NDS32_SDA_FP7U2_RELA:
+ case R_NDS32_15_PCREL_RELA:
+ case R_NDS32_17_PCREL_RELA:
+ case R_NDS32_25_PCREL_RELA:
+ if (h != NULL)
+ {
+ struct elf_nds32_link_hash_entry *eh;
+ struct elf_nds32_dyn_relocs **pp;
+ struct elf_nds32_dyn_relocs *p;
+
+ if (!info->shared && h->plt.refcount > 0)
+ h->plt.refcount -= 1;
+
+ eh = (struct elf_nds32_link_hash_entry *) h;
+
+ for (pp = &eh->dyn_relocs; (p = *pp) != NULL; pp = &p->next)
+ if (p->sec == sec)
+ {
+ if (ELF32_R_TYPE (rel->r_info) == R_NDS32_15_PCREL_RELA
+ || ELF32_R_TYPE (rel->r_info) == R_NDS32_17_PCREL_RELA
+ || ELF32_R_TYPE (rel->r_info) == R_NDS32_25_PCREL_RELA)
+ p->pc_count -= 1;
+ p->count -= 1;
+ if (p->count == 0)
+ *pp = p->next;
+ break;
+ }
+ }
+ break;
+
+ case R_NDS32_9_PLTREL:
+ case R_NDS32_25_PLTREL:
+ if (h != NULL)
+ {
+ if (h->plt.refcount > 0)
+ h->plt.refcount--;
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ 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 bfd_boolean
+nds32_elf_check_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;
+ struct elf_nds32_link_hash_table *htab;
+ bfd *dynobj;
+ asection *sreloc = NULL;
+
+ if (info->relocatable)
+ 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;
+
+ htab = nds32_elf_hash_table (info);
+ dynobj = htab->root.dynobj;
+
+ rel_end = relocs + sec->reloc_count;
+ for (rel = relocs; rel < rel_end; rel++)
+ {
+ enum elf_nds32_reloc_type r_type;
+ struct elf_link_hash_entry *h;
+ unsigned long r_symndx;
+ int tls_type, old_tls_type;
+
+ r_symndx = ELF32_R_SYM (rel->r_info);
+ r_type = ELF32_R_TYPE (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.type == bfd_link_hash_indirect
+ || h->root.type == bfd_link_hash_warning)
+ h = (struct elf_link_hash_entry *) h->root.u.i.link;
+ }
+
+ /* Some relocs require a global offset table. We create
+ got section here, since these relocation need got section
+ and it is not created yet. */
+ if (htab->sgot == NULL)
+ {
+ switch (r_type)
+ {
+ case R_NDS32_GOT_HI20:
+ case R_NDS32_GOT_LO12:
+ case R_NDS32_GOT_LO15:
+ case R_NDS32_GOT_LO19:
+ case R_NDS32_GOT17S2_RELA:
+ case R_NDS32_GOT15S2_RELA:
+ case R_NDS32_GOTOFF:
+ case R_NDS32_GOTOFF_HI20:
+ case R_NDS32_GOTOFF_LO12:
+ case R_NDS32_GOTOFF_LO15:
+ case R_NDS32_GOTOFF_LO19:
+ case R_NDS32_GOTPC20:
+ case R_NDS32_GOTPC_HI20:
+ case R_NDS32_GOTPC_LO12:
+ case R_NDS32_GOT20:
+ case R_NDS32_TLS_IE_HI20:
+ case R_NDS32_TLS_IE_LO12S2:
+ if (dynobj == NULL)
+ htab->root.dynobj = dynobj = abfd;
+ if (!create_got_section (dynobj, info))
+ return FALSE;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ switch ((int) r_type)
+ {
+ case R_NDS32_GOT_HI20:
+ case R_NDS32_GOT_LO12:
+ case R_NDS32_GOT_LO15:
+ case R_NDS32_GOT_LO19:
+ case R_NDS32_GOT20:
+ case R_NDS32_TLS_IE_HI20:
+ case R_NDS32_TLS_IE_LO12S2:
+ switch (r_type)
+ {
+ case R_NDS32_TLS_IE_HI20:
+ case R_NDS32_TLS_IE_LO12S2:
+ tls_type = GOT_TLS_IE;
+ break;
+ default:
+ tls_type = GOT_NORMAL;
+ break;
+ }
+ if (h != NULL)
+ {
+ old_tls_type = elf32_nds32_hash_entry (h)->tls_type;
+ h->got.refcount += 1;
+ }
+ else
+ {
+ bfd_signed_vma *local_got_refcounts;
+
+ /* This is a global offset table entry for a local
+ symbol. */
+ local_got_refcounts = elf_local_got_refcounts (abfd);
+ if (local_got_refcounts == NULL)
+ {
+ bfd_size_type size;
+
+ size = symtab_hdr->sh_info;
+ size *= sizeof (bfd_signed_vma);
+ local_got_refcounts = (bfd_signed_vma *) bfd_zalloc (abfd, size);
+ if (local_got_refcounts == NULL)
+ return FALSE;
+ elf_local_got_refcounts (abfd) = local_got_refcounts;
+ }
+ local_got_refcounts[r_symndx] += 1;
+ old_tls_type = elf32_nds32_local_got_tls_type (abfd)[r_symndx];
+ }
+
+ /* We will already have issued an error message if there
+ is a TLS/non-TLS mismatch, based on the symbol
+ type. So just combine any TLS types needed. */
+ if (old_tls_type != GOT_UNKNOWN && old_tls_type != GOT_NORMAL
+ && tls_type != GOT_NORMAL)
+ tls_type |= old_tls_type;
+
+ if (old_tls_type != tls_type)
+ {
+ if (h != NULL)
+ elf32_nds32_hash_entry (h)->tls_type = tls_type;
+ else
+ elf32_nds32_local_got_tls_type (abfd)[r_symndx] = tls_type;
+ }
+ break;
+ case R_NDS32_9_PLTREL:
+ case R_NDS32_25_PLTREL:
+ case R_NDS32_PLTREL_HI20:
+ case R_NDS32_PLTREL_LO12:
+ case R_NDS32_PLT_GOTREL_HI20:
+ case R_NDS32_PLT_GOTREL_LO12:
+ case R_NDS32_PLT_GOTREL_LO15:
+ case R_NDS32_PLT_GOTREL_LO19:
+ case R_NDS32_PLT_GOTREL_LO20:
+
+ /* 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 this is a local symbol, we resolve it directly without
+ creating a procedure linkage table entry. */
+ if (h == NULL)
+ continue;
+
+ if (h->forced_local)
+ break;
+
+ elf32_nds32_hash_entry (h)->tls_type = GOT_NORMAL;
+ h->needs_plt = 1;
+ h->plt.refcount += 1;
+ break;
+
+ case R_NDS32_16_RELA:
+ case R_NDS32_20_RELA:
+ case R_NDS32_5_RELA:
+ case R_NDS32_32_RELA:
+ case R_NDS32_HI20_RELA:
+ case R_NDS32_LO12S3_RELA:
+ case R_NDS32_LO12S2_RELA:
+ case R_NDS32_LO12S2_DP_RELA:
+ case R_NDS32_LO12S2_SP_RELA:
+ case R_NDS32_LO12S1_RELA:
+ case R_NDS32_LO12S0_RELA:
+ case R_NDS32_LO12S0_ORI_RELA:
+ case R_NDS32_SDA16S3_RELA:
+ case R_NDS32_SDA17S2_RELA:
+ case R_NDS32_SDA18S1_RELA:
+ case R_NDS32_SDA19S0_RELA:
+ case R_NDS32_SDA15S3_RELA:
+ case R_NDS32_SDA15S2_RELA:
+ case R_NDS32_SDA12S2_DP_RELA:
+ case R_NDS32_SDA12S2_SP_RELA:
+ case R_NDS32_SDA15S1_RELA:
+ case R_NDS32_SDA15S0_RELA:
+ case R_NDS32_SDA_FP7U2_RELA:
+ case R_NDS32_15_PCREL_RELA:
+ case R_NDS32_17_PCREL_RELA:
+ case R_NDS32_25_PCREL_RELA:
+
+ if (h != NULL && !info->shared)
+ {
+ h->non_got_ref = 1;
+ h->plt.refcount += 1;
+ }
+
+ /* 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 dyn_relocs field of the hash table
+ entry. A similar situation occurs when creating shared libraries
+ and symbol visibility changes render the symbol local.
+
+ If on the other hand, we are creating an executable, we may need
+ to keep relocations for symbols satisfied by a dynamic library
+ if we manage to avoid copy relocs for the symbol. */
+ if ((info->shared
+ && (sec->flags & SEC_ALLOC) != 0
+ && ((r_type != R_NDS32_25_PCREL_RELA
+ && r_type != R_NDS32_15_PCREL_RELA
+ && r_type != R_NDS32_17_PCREL_RELA
+ && !(r_type == R_NDS32_32_RELA
+ && strcmp (sec->name, ".eh_frame") == 0))
+ || (h != NULL
+ && (!info->symbolic
+ || h->root.type == bfd_link_hash_defweak
+ || !h->def_regular))))
+ || (!info->shared
+ && (sec->flags & SEC_ALLOC) != 0
+ && h != NULL
+ && (h->root.type == bfd_link_hash_defweak
+ || !h->def_regular)))
+ {
+ struct elf_nds32_dyn_relocs *p;
+ struct elf_nds32_dyn_relocs **head;
+
+ if (dynobj == NULL)
+ htab->root.dynobj = dynobj = abfd;
+
+ /* 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)->rela.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;
+
+ elf_section_type (sreloc) = SHT_RELA;
+ }
+ elf_section_data (sec)->sreloc = sreloc;
+ }
+
+ /* If this is a global symbol, we count the number of
+ relocations we need for this symbol. */
+ if (h != NULL)
+ head = &((struct elf_nds32_link_hash_entry *) h)->dyn_relocs;
+ else
+ {
+ asection *s;
+
+ Elf_Internal_Sym *isym;
+ isym = bfd_sym_from_r_symndx (&htab->sym_cache, abfd, r_symndx);
+ if (isym == NULL)
+ return FALSE;
+
+ /* Track dynamic relocs needed for local syms too. */
+ s = bfd_section_from_elf_index (abfd, isym->st_shndx);
+ if (s == NULL)
+ return FALSE;
+
+ head = ((struct elf_nds32_dyn_relocs **)
+ &elf_section_data (s)->local_dynrel);
+ }
+
+ p = *head;
+ if (p == NULL || p->sec != sec)
+ {
+ bfd_size_type amt = sizeof (*p);
+ p = (struct elf_nds32_dyn_relocs *) bfd_alloc (dynobj, amt);
+ if (p == NULL)
+ return FALSE;
+ p->next = *head;
+ *head = p;
+ p->sec = sec;
+ p->count = 0;
+ p->pc_count = 0;
+ }
+
+ p->count += 1;
+ if (ELF32_R_TYPE (rel->r_info) == R_NDS32_25_PCREL_RELA
+ || ELF32_R_TYPE (rel->r_info) == R_NDS32_15_PCREL_RELA
+ || ELF32_R_TYPE (rel->r_info) == R_NDS32_17_PCREL_RELA)
+ p->pc_count += 1;
+ }
+ break;
+
+ /* This relocation describes the C++ object vtable hierarchy.
+ Reconstruct it for later use during GC. */
+ case R_NDS32_RELA_GNU_VTINHERIT:
+ case R_NDS32_GNU_VTINHERIT:
+ if (!bfd_elf_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_NDS32_GNU_VTENTRY:
+ if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_offset))
+ return FALSE;
+ break;
+ case R_NDS32_RELA_GNU_VTENTRY:
+ if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
+ return FALSE;
+ break;
+ }
+ }
+
+ return TRUE;
+}
+
+/* Write VAL in uleb128 format to P, returning a pointer to the
+ following byte.
+ This code is copied from elf-attr.c. */
+
+static bfd_byte *
+write_uleb128 (bfd_byte *p, unsigned int val)
+{
+ bfd_byte c;
+ do
+ {
+ c = val & 0x7f;
+ val >>= 7;
+ if (val)
+ c |= 0x80;
+ *(p++) = c;
+ }
+ while (val);
+ return p;
+}
+
+static bfd_signed_vma
+calculate_offset (bfd *abfd, asection *sec, Elf_Internal_Rela *irel,
+ Elf_Internal_Sym *isymbuf, Elf_Internal_Shdr *symtab_hdr,
+ int *pic_ext_target)
+{
+ bfd_signed_vma foff;
+ bfd_vma symval, addend;
+ asection *sym_sec;
+
+ /* 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;
+
+ /* A local symbol. */
+ isym = isymbuf + ELF32_R_SYM (irel->r_info);
+
+ if (isym->st_shndx == SHN_UNDEF)
+ sym_sec = bfd_und_section_ptr;
+ 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;
+ else
+ 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;
+ bfd *owner;
+
+ /* 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. */
+ return 0;
+ owner = h->root.u.def.section->owner;
+ if (owner && (elf_elfheader (owner)->e_flags & E_NDS32_HAS_PIC))
+ *pic_ext_target = 1;
+
+ if (h->root.u.def.section->flags & SEC_MERGE)
+ {
+ sym_sec = h->root.u.def.section;
+ symval = _bfd_merged_section_offset (abfd, &sym_sec,
+ elf_section_data (sym_sec)->sec_info,
+ h->root.u.def.value);
+ symval = symval + sym_sec->output_section->vma
+ + sym_sec->output_offset;
+ }
+ else
+ symval = (h->root.u.def.value
+ + h->root.u.def.section->output_section->vma
+ + h->root.u.def.section->output_offset);
+ }
+
+ addend = irel->r_addend;
+
+ foff = (symval + addend
+ - (irel->r_offset + sec->output_section->vma + sec->output_offset));
+ return foff;
+}
+
+static bfd_vma
+calculate_plt_memory_address (bfd *abfd, struct bfd_link_info *link_info,
+ Elf_Internal_Sym *isymbuf,
+ Elf_Internal_Rela *irel,
+ Elf_Internal_Shdr *symtab_hdr)
+{
+ bfd_vma symval;
+
+ if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
+ {
+ Elf_Internal_Sym *isym;
+ asection *sym_sec;
+ /* A local symbol. */
+ isym = isymbuf + ELF32_R_SYM (irel->r_info);
+
+ if (isym->st_shndx == SHN_UNDEF)
+ sym_sec = bfd_und_section_ptr;
+ 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;
+ else
+ 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;
+ struct elf_nds32_link_hash_table *htab;
+ asection *splt;
+
+ /* An external symbol. */
+ indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info;
+ h = elf_sym_hashes (abfd)[indx];
+ BFD_ASSERT (h != NULL);
+ htab = nds32_elf_hash_table (link_info);
+ splt = htab->splt;
+
+ 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->plt.offset == (bfd_vma) - 1)
+ {
+ 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. */
+ return 0;
+ symval = (h->root.u.def.value
+ + h->root.u.def.section->output_section->vma
+ + h->root.u.def.section->output_offset);
+ }
+ else
+ symval = splt->output_section->vma + h->plt.offset;
+ }
+
+ return symval;
+}
+
+static bfd_signed_vma
+calculate_plt_offset (bfd *abfd, asection *sec, struct bfd_link_info *link_info,
+ Elf_Internal_Sym *isymbuf, Elf_Internal_Rela *irel,
+ Elf_Internal_Shdr *symtab_hdr)
+{
+ bfd_vma foff;
+ if ((foff = calculate_plt_memory_address (abfd, link_info, isymbuf, irel,
+ symtab_hdr)) == 0)
+ return 0;
+ else
+ return foff - (irel->r_offset
+ + sec->output_section->vma + sec->output_offset);
+}
+
+/* Convert a 32-bit instruction to 16-bit one.
+ INSN is the input 32-bit instruction, INSN16 is the output 16-bit
+ instruction. If INSN_TYPE is not NULL, it the CGEN instruction
+ type of INSN16. Return 1 if successful. */
+
+static int
+nds32_convert_32_to_16_alu1 (bfd *abfd, uint32_t insn, uint16_t *pinsn16,
+ int *pinsn_type)
+{
+ uint16_t insn16 = 0;
+ int insn_type;
+ unsigned long mach = bfd_get_mach (abfd);
+
+ if (N32_SH5 (insn) != 0)
+ return 0;
+
+ switch (N32_SUB5 (insn))
+ {
+ case N32_ALU1_ADD_SLLI:
+ case N32_ALU1_ADD_SRLI:
+ if (N32_IS_RT3 (insn) && N32_IS_RA3 (insn) && N32_IS_RB3 (insn))
+ {
+ insn16 = N16_TYPE333 (ADD333, N32_RT5 (insn), N32_RA5 (insn),
+ N32_RB5 (insn));
+ insn_type = NDS32_INSN_ADD333;
+ }
+ else if (N32_IS_RT4 (insn))
+ {
+ if (N32_RT5 (insn) == N32_RA5 (insn))
+ insn16 = N16_TYPE45 (ADD45, N32_RT54 (insn), N32_RB5 (insn));
+ else if (N32_RT5 (insn) == N32_RB5 (insn))
+ insn16 = N16_TYPE45 (ADD45, N32_RT54 (insn), N32_RA5 (insn));
+ insn_type = NDS32_INSN_ADD45;
+ }
+ break;
+
+ case N32_ALU1_SUB_SLLI:
+ case N32_ALU1_SUB_SRLI:
+ if (N32_IS_RT3 (insn) && N32_IS_RA3 (insn) && N32_IS_RB3 (insn))
+ {
+ insn16 = N16_TYPE333 (SUB333, N32_RT5 (insn), N32_RA5 (insn),
+ N32_RB5 (insn));
+ insn_type = NDS32_INSN_SUB333;
+ }
+ else if (N32_IS_RT4 (insn) && N32_RT5 (insn) == N32_RA5 (insn))
+ {
+ insn16 = N16_TYPE45 (SUB45, N32_RT54 (insn), N32_RB5 (insn));
+ insn_type = NDS32_INSN_SUB45;
+ }
+ break;
+
+ case N32_ALU1_AND_SLLI:
+ case N32_ALU1_AND_SRLI:
+ /* and $rt, $rt, $rb -> and33 for v3, v3m. */
+ if (mach >= MACH_V3 && N32_IS_RT3 (insn) && N32_IS_RA3 (insn)
+ && N32_IS_RB3 (insn))
+ {
+ if (N32_RT5 (insn) == N32_RA5 (insn))
+ insn16 = N16_MISC33 (AND33, N32_RT5 (insn), N32_RB5 (insn));
+ else if (N32_RT5 (insn) == N32_RB5 (insn))
+ insn16 = N16_MISC33 (AND33, N32_RT5 (insn), N32_RA5 (insn));
+ if (insn16)
+ insn_type = NDS32_INSN_AND33;
+ }
+ break;
+
+ case N32_ALU1_XOR_SLLI:
+ case N32_ALU1_XOR_SRLI:
+ /* xor $rt, $rt, $rb -> xor33 for v3, v3m. */
+ if (mach >= MACH_V3 && N32_IS_RT3 (insn) && N32_IS_RA3 (insn)
+ && N32_IS_RB3 (insn))
+ {
+ if (N32_RT5 (insn) == N32_RA5 (insn))
+ insn16 = N16_MISC33 (XOR33, N32_RT5 (insn), N32_RB5 (insn));
+ else if (N32_RT5 (insn) == N32_RB5 (insn))
+ insn16 = N16_MISC33 (XOR33, N32_RT5 (insn), N32_RA5 (insn));
+ if (insn16)
+ insn_type = NDS32_INSN_XOR33;
+ }
+ break;
+
+ case N32_ALU1_OR_SLLI:
+ case N32_ALU1_OR_SRLI:
+ /* or $rt, $rt, $rb -> or33 for v3, v3m. */
+ if (mach >= MACH_V3 && N32_IS_RT3 (insn) && N32_IS_RA3 (insn)
+ && N32_IS_RB3 (insn))
+ {
+ if (N32_RT5 (insn) == N32_RA5 (insn))
+ insn16 = N16_MISC33 (OR33, N32_RT5 (insn), N32_RB5 (insn));
+ else if (N32_RT5 (insn) == N32_RB5 (insn))
+ insn16 = N16_MISC33 (OR33, N32_RT5 (insn), N32_RA5 (insn));
+ if (insn16)
+ insn_type = NDS32_INSN_OR33;
+ }
+ break;
+ case N32_ALU1_NOR:
+ /* nor $rt, $ra, $ra -> not33 for v3, v3m. */
+ if (mach >= MACH_V3 && N32_IS_RT3 (insn) && N32_IS_RB3 (insn)
+ && N32_RA5 (insn) == N32_RB5 (insn))
+ {
+ insn16 = N16_MISC33 (NOT33, N32_RT5 (insn), N32_RA5 (insn));
+ insn_type = NDS32_INSN_NOT33;
+ }
+ break;
+ case N32_ALU1_SRAI:
+ if (N32_IS_RT4 (insn) && N32_RT5 (insn) == N32_RA5 (insn))
+ {
+ insn16 = N16_TYPE45 (SRAI45, N32_RT54 (insn), N32_UB5 (insn));
+ insn_type = NDS32_INSN_SRAI45;
+ }
+ break;
+
+ case N32_ALU1_SRLI:
+ if (N32_IS_RT4 (insn) && N32_RT5 (insn) == N32_RA5 (insn))
+ {
+ insn16 = N16_TYPE45 (SRLI45, N32_RT54 (insn), N32_UB5 (insn));
+ insn_type = NDS32_INSN_SRLI45;
+ }
+ break;
+
+ case N32_ALU1_SLLI:
+ if (N32_IS_RT3 (insn) && N32_IS_RA3 (insn) && N32_UB5 (insn) < 8)
+ {
+ insn16 = N16_TYPE333 (SLLI333, N32_RT5 (insn), N32_RA5 (insn),
+ N32_UB5 (insn));
+ insn_type = NDS32_INSN_SLLI333;
+ }
+ break;
+
+ case N32_ALU1_ZEH:
+ if (N32_IS_RT3 (insn) && N32_IS_RA3 (insn))
+ {
+ insn16 = N16_BFMI333 (ZEH33, N32_RT5 (insn), N32_RA5 (insn));
+ insn_type = NDS32_INSN_ZEH33;
+ }
+ break;
+
+ case N32_ALU1_SEB:
+ if (N32_IS_RT3 (insn) && N32_IS_RA3 (insn))
+ {
+ insn16 = N16_BFMI333 (SEB33, N32_RT5 (insn), N32_RA5 (insn));
+ insn_type = NDS32_INSN_SEB33;
+ }
+ break;
+
+ case N32_ALU1_SEH:
+ if (N32_IS_RT3 (insn) && N32_IS_RA3 (insn))
+ {
+ insn16 = N16_BFMI333 (SEH33, N32_RT5 (insn), N32_RA5 (insn));
+ insn_type = NDS32_INSN_SEH33;
+ }
+ break;
+
+ case N32_ALU1_SLT:
+ if (N32_RT5 (insn) == REG_R15 && N32_IS_RA4 (insn))
+ {
+ /* Implicit r15. */
+ insn16 = N16_TYPE45 (SLT45, N32_RA54 (insn), N32_RB5 (insn));
+ insn_type = NDS32_INSN_SLT45;
+ }
+ break;
+
+ case N32_ALU1_SLTS:
+ if (N32_RT5 (insn) == REG_R15 && N32_IS_RA4 (insn))
+ {
+ /* Implicit r15. */
+ insn16 = N16_TYPE45 (SLTS45, N32_RA54 (insn), N32_RB5 (insn));
+ insn_type = NDS32_INSN_SLTS45;
+ }
+ break;
+ }
+
+ if ((insn16 & 0x8000) == 0)
+ return 0;
+
+ if (pinsn16)
+ *pinsn16 = insn16;
+ if (pinsn_type)
+ *pinsn_type = insn_type;
+ return 1;
+}
+
+static int
+nds32_convert_32_to_16_alu2 (bfd *abfd, uint32_t insn, uint16_t *pinsn16,
+ int *pinsn_type)
+{
+ uint16_t insn16 = 0;
+ int insn_type;
+ unsigned long mach = bfd_get_mach (abfd);
+
+ /* TODO: bset, bclr, btgl, btst. */
+ if (__GF (insn, 6, 4) != 0)
+ return 0;
+
+ switch (N32_IMMU (insn, 6))
+ {
+ case N32_ALU2_MUL:
+ if (mach >= MACH_V3 && N32_IS_RT3 (insn) && N32_IS_RA3 (insn)
+ && N32_IS_RB3 (insn))
+ {
+ if (N32_RT5 (insn) == N32_RA5 (insn))
+ insn16 = N16_MISC33 (MUL33, N32_RT5 (insn), N32_RB5 (insn));
+ else if (N32_RT5 (insn) == N32_RB5 (insn))
+ insn16 = N16_MISC33 (MUL33, N32_RT5 (insn), N32_RA5 (insn));
+ if (insn16)
+ insn_type = NDS32_INSN_MUL33;
+ }
+ }
+
+ if ((insn16 & 0x8000) == 0)
+ return 0;
+
+ if (pinsn16)
+ *pinsn16 = insn16;
+ if (pinsn_type)
+ *pinsn_type = insn_type;
+ return 1;
+}
+
+int
+nds32_convert_32_to_16 (bfd *abfd, uint32_t insn, uint16_t *pinsn16,
+ int *pinsn_type)
+{
+ int op6;
+ uint16_t insn16 = 0;
+ int insn_type;
+ unsigned long mach = bfd_get_mach (abfd);
+
+ /* Decode 32-bit instruction. */
+ if (insn & 0x80000000)
+ {
+ /* Not 32-bit insn. */
+ return 0;
+ }
+
+ op6 = N32_OP6 (insn);
+
+ /* Convert it to 16-bit instruction. */
+ switch (op6)
+ {
+ case N32_OP6_MOVI:
+ if (IS_WITHIN_S (N32_IMM20S (insn), 5))
+ {
+ insn16 = N16_TYPE55 (MOVI55, N32_RT5 (insn), N32_IMM20S (insn));
+ insn_type = NDS32_INSN_MOVI55;
+ }
+ else if (mach >= MACH_V3 && N32_IMM20S (insn) >= 16
+ && N32_IMM20S (insn) < 48 && N32_IS_RT4 (insn))
+ {
+ insn16 = N16_TYPE45 (MOVPI45, N32_RT54 (insn),
+ N32_IMM20S (insn) - 16);
+ insn_type = NDS32_INSN_MOVPI45;
+ }
+ break;
+
+ case N32_OP6_ADDI:
+ if (N32_IMM15S (insn) == 0)
+ {
+ /* Do not convert `addi $sp, $sp, 0' to `mov55 $sp, $sp',
+ because `mov55 $sp, $sp' is ifret16 in V3 ISA. */
+ if (mach <= MACH_V2
+ || N32_RT5 (insn) != REG_SP || N32_RA5 (insn) != REG_SP)
+ {
+ insn16 = N16_TYPE55 (MOV55, N32_RT5 (insn), N32_RA5 (insn));
+ insn_type = NDS32_INSN_MOV55;
+ }
+ }
+ else if (N32_IMM15S (insn) > 0)
+ {
+ if (N32_IS_RT3 (insn) && N32_IS_RA3 (insn) && N32_IMM15S (insn) < 8)
+ {
+ insn16 = N16_TYPE333 (ADDI333, N32_RT5 (insn), N32_RA5 (insn),
+ N32_IMM15S (insn));
+ insn_type = NDS32_INSN_ADDI333;
+ }
+ else if (N32_IS_RT4 (insn) && N32_RT5 (insn) == N32_RA5 (insn)
+ && N32_IMM15S (insn) < 32)
+ {
+ insn16 = N16_TYPE45 (ADDI45, N32_RT54 (insn), N32_IMM15S (insn));
+ insn_type = NDS32_INSN_ADDI45;
+ }
+ else if (mach >= MACH_V2 && N32_RT5 (insn) == REG_SP
+ && N32_RT5 (insn) == N32_RA5 (insn)
+ && N32_IMM15S (insn) < 512)
+ {
+ insn16 = N16_TYPE10 (ADDI10S, N32_IMM15S (insn));
+ insn_type = NDS32_INSN_ADDI10_SP;
+ }
+ else if (mach >= MACH_V3 && N32_IS_RT3 (insn)
+ && N32_RA5 (insn) == REG_SP && N32_IMM15S (insn) < 256
+ && (N32_IMM15S (insn) % 4 == 0))
+ {
+ insn16 = N16_TYPE36 (ADDRI36_SP, N32_RT5 (insn),
+ N32_IMM15S (insn) >> 2);
+ insn_type = NDS32_INSN_ADDRI36_SP;
+ }
+ }
+ else
+ {
+ /* Less than 0. */
+ if (N32_IS_RT3 (insn) && N32_IS_RA3 (insn) && N32_IMM15S (insn) > -8)
+ {
+ insn16 = N16_TYPE333 (SUBI333, N32_RT5 (insn), N32_RA5 (insn),
+ 0 - N32_IMM15S (insn));
+ insn_type = NDS32_INSN_SUBI333;
+ }
+ else if (N32_IS_RT4 (insn) && N32_RT5 (insn) == N32_RA5 (insn)
+ && N32_IMM15S (insn) > -32)
+ {
+ insn16 = N16_TYPE45 (SUBI45, N32_RT54 (insn),
+ 0 - N32_IMM15S (insn));
+ insn_type = NDS32_INSN_SUBI45;
+ }
+ else if (mach >= MACH_V2 && N32_RT5 (insn) == REG_SP
+ && N32_RT5 (insn) == N32_RA5 (insn)
+ && N32_IMM15S (insn) >= -512)
+ {
+ insn16 = N16_TYPE10 (ADDI10S, N32_IMM15S (insn));
+ insn_type = NDS32_INSN_ADDI10_SP;
+ }
+ }
+ break;
+
+ case N32_OP6_ORI:
+ if (N32_IMM15S (insn) == 0)
+ {
+ /* Do not convert `ori $sp, $sp, 0' to `mov55 $sp, $sp',
+ because `mov55 $sp, $sp' is ifret16 in V3 ISA. */
+ if (mach <= MACH_V2
+ || N32_RT5 (insn) != REG_SP || N32_RA5 (insn) != REG_SP)
+ {
+ insn16 = N16_TYPE55 (MOV55, N32_RT5 (insn), N32_RA5 (insn));
+ insn_type = NDS32_INSN_MOV55;
+ }
+ }
+ break;
+
+ case N32_OP6_SUBRI:
+ if (mach >= MACH_V3 && N32_IS_RT3 (insn)
+ && N32_IS_RA3 (insn) && N32_IMM15S (insn) == 0)
+ {
+ insn16 = N16_MISC33 (NEG33, N32_RT5 (insn), N32_RA5 (insn));
+ insn_type = NDS32_INSN_NEG33;
+ }
+ break;
+
+ case N32_OP6_ANDI:
+ if (N32_IS_RT3 (insn) && N32_IS_RA3 (insn))
+ {
+ if (N32_IMM15U (insn) == 1)
+ {
+ insn16 = N16_BFMI333 (XLSB33, N32_RT5 (insn), N32_RA5 (insn));
+ insn_type = NDS32_INSN_XLSB33;
+ }
+ else if (N32_IMM15U (insn) == 0x7ff)
+ {
+ insn16 = N16_BFMI333 (X11B33, N32_RT5 (insn), N32_RA5 (insn));
+ insn_type = NDS32_INSN_X11B33;
+ }
+ else if (N32_IMM15U (insn) == 0xff)
+ {
+ insn16 = N16_BFMI333 (ZEB33, N32_RT5 (insn), N32_RA5 (insn));
+ insn_type = NDS32_INSN_ZEB33;
+ }
+ else if (mach >= MACH_V3 && N32_RT5 (insn) == N32_RA5 (insn)
+ && N32_IMM15U (insn) < 256)
+ {
+ int imm15u = N32_IMM15U (insn);
+
+ if (__builtin_popcount (imm15u) == 1)
+ {
+ /* BMSKI33 */
+ int imm3u = __builtin_ctz (imm15u);
+
+ insn16 = N16_BFMI333 (BMSKI33, N32_RT5 (insn), imm3u);
+ insn_type = NDS32_INSN_BMSKI33;
+ }
+ else if (imm15u != 0 && __builtin_popcount (imm15u + 1) == 1)
+ {
+ /* FEXTI33 */
+ int imm3u = __builtin_ctz (imm15u + 1) - 1;
+
+ insn16 = N16_BFMI333 (FEXTI33, N32_RT5 (insn), imm3u);
+ insn_type = NDS32_INSN_FEXTI33;
+ }
+ }
+ }
+ break;
+
+ case N32_OP6_SLTI:
+ if (N32_RT5 (insn) == REG_R15 && N32_IS_RA4 (insn)
+ && IS_WITHIN_U (N32_IMM15S (insn), 5))
+ {
+ insn16 = N16_TYPE45 (SLTI45, N32_RA54 (insn), N32_IMM15S (insn));
+ insn_type = NDS32_INSN_SLTI45;
+ }
+ break;
+
+ case N32_OP6_SLTSI:
+ if (N32_RT5 (insn) == REG_R15 && N32_IS_RA4 (insn)
+ && IS_WITHIN_U (N32_IMM15S (insn), 5))
+ {
+ insn16 = N16_TYPE45 (SLTSI45, N32_RA54 (insn), N32_IMM15S (insn));
+ insn_type = NDS32_INSN_SLTSI45;
+ }
+ break;
+
+ case N32_OP6_LWI:
+ if (N32_IS_RT4 (insn) && N32_IMM15S (insn) == 0)
+ {
+ insn16 = N16_TYPE45 (LWI450, N32_RT54 (insn), N32_RA5 (insn));
+ insn_type = NDS32_INSN_LWI450;
+ }
+ else if (N32_IS_RT3 (insn) && N32_IS_RA3 (insn)
+ && IS_WITHIN_U (N32_IMM15S (insn), 3))
+ {
+ insn16 = N16_TYPE333 (LWI333, N32_RT5 (insn), N32_RA5 (insn),
+ N32_IMM15S (insn));
+ insn_type = NDS32_INSN_LWI333;
+ }
+ else if (N32_IS_RT3 (insn) && N32_RA5 (insn) == REG_FP
+ && IS_WITHIN_U (N32_IMM15S (insn), 7))
+ {
+ insn16 = N16_TYPE37 (XWI37, N32_RT5 (insn), 0, N32_IMM15S (insn));
+ insn_type = NDS32_INSN_LWI37;
+ }
+ else if (mach >= MACH_V2 && N32_IS_RT3 (insn) && N32_RA5 (insn) == REG_SP
+ && IS_WITHIN_U (N32_IMM15S (insn), 7))
+ {
+ insn16 = N16_TYPE37 (XWI37SP, N32_RT5 (insn), 0, N32_IMM15S (insn));
+ insn_type = NDS32_INSN_LWI37_SP;
+ }
+ else if (mach >= MACH_V2 && N32_IS_RT4 (insn) && N32_RA5 (insn) == REG_R8
+ && -32 <= N32_IMM15S (insn) && N32_IMM15S (insn) < 0)
+ {
+ insn16 = N16_TYPE45 (LWI45_FE, N32_RT54 (insn),
+ N32_IMM15S (insn) + 32);
+ insn_type = NDS32_INSN_LWI45_FE;
+ }
+ break;
+
+ case N32_OP6_SWI:
+ if (N32_IS_RT4 (insn) && N32_IMM15S (insn) == 0)
+ {
+ insn16 = N16_TYPE45 (SWI450, N32_RT54 (insn), N32_RA5 (insn));
+ insn_type = NDS32_INSN_SWI450;
+ }
+ else if (N32_IS_RT3 (insn) && N32_IS_RA3 (insn)
+ && IS_WITHIN_U (N32_IMM15S (insn), 3))
+ {
+ insn16 = N16_TYPE333 (SWI333, N32_RT5 (insn), N32_RA5 (insn),
+ N32_IMM15S (insn));
+ insn_type = NDS32_INSN_SWI333;
+ }
+ else if (N32_IS_RT3 (insn) && N32_RA5 (insn) == REG_FP
+ && IS_WITHIN_U (N32_IMM15S (insn), 7))
+ {
+ insn16 = N16_TYPE37 (XWI37, N32_RT5 (insn), 1, N32_IMM15S (insn));
+ insn_type = NDS32_INSN_SWI37;
+ }
+ else if (mach >= MACH_V2 && N32_IS_RT3 (insn) && N32_RA5 (insn) == REG_SP
+ && IS_WITHIN_U (N32_IMM15S (insn), 7))
+ {
+ insn16 = N16_TYPE37 (XWI37SP, N32_RT5 (insn), 1, N32_IMM15S (insn));
+ insn_type = NDS32_INSN_SWI37_SP;
+ }
+ break;
+
+ case N32_OP6_LWI_BI:
+ if (N32_IS_RT3 (insn) && N32_IS_RA3 (insn)
+ && IS_WITHIN_U (N32_IMM15S (insn), 3))
+ {
+ insn16 = N16_TYPE333 (LWI333_BI, N32_RT5 (insn), N32_RA5 (insn),
+ N32_IMM15S (insn));
+ insn_type = NDS32_INSN_LWI333_BI;
+ }
+ break;
+
+ case N32_OP6_SWI_BI:
+ if (N32_IS_RT3 (insn) && N32_IS_RA3 (insn)
+ && IS_WITHIN_U (N32_IMM15S (insn), 3))
+ {
+ insn16 = N16_TYPE333 (SWI333_BI, N32_RT5 (insn), N32_RA5 (insn),
+ N32_IMM15S (insn));
+ insn_type = NDS32_INSN_SWI333_BI;
+ }
+ break;
+
+ case N32_OP6_LHI:
+ if (N32_IS_RT3 (insn) && N32_IS_RA3 (insn)
+ && IS_WITHIN_U (N32_IMM15S (insn), 3))
+ {
+ insn16 = N16_TYPE333 (LHI333, N32_RT5 (insn), N32_RA5 (insn),
+ N32_IMM15S (insn));
+ insn_type = NDS32_INSN_LHI333;
+ }
+ break;
+
+ case N32_OP6_SHI:
+ if (N32_IS_RT3 (insn) && N32_IS_RA3 (insn)
+ && IS_WITHIN_U (N32_IMM15S (insn), 3))
+ {
+ insn16 = N16_TYPE333 (SHI333, N32_RT5 (insn), N32_RA5 (insn),
+ N32_IMM15S (insn));
+ insn_type = NDS32_INSN_SHI333;
+ }
+ break;
+
+ case N32_OP6_LBI:
+ if (N32_IS_RT3 (insn) && N32_IS_RA3 (insn)
+ && IS_WITHIN_U (N32_IMM15S (insn), 3))
+ {
+ insn16 = N16_TYPE333 (LBI333, N32_RT5 (insn), N32_RA5 (insn),
+ N32_IMM15S (insn));
+ insn_type = NDS32_INSN_LBI333;
+ }
+ break;
+
+ case N32_OP6_SBI:
+ if (N32_IS_RT3 (insn) && N32_IS_RA3 (insn)
+ && IS_WITHIN_U (N32_IMM15S (insn), 3))
+ {
+ insn16 = N16_TYPE333 (SBI333, N32_RT5 (insn), N32_RA5 (insn),
+ N32_IMM15S (insn));
+ insn_type = NDS32_INSN_SBI333;
+ }
+ break;
+
+ case N32_OP6_ALU1:
+ return nds32_convert_32_to_16_alu1 (abfd, insn, pinsn16, pinsn_type);
+
+ case N32_OP6_ALU2:
+ return nds32_convert_32_to_16_alu2 (abfd, insn, pinsn16, pinsn_type);
+
+ case N32_OP6_BR1:
+ if (!IS_WITHIN_S (N32_IMM14S (insn), 8))
+ goto done;
+
+ if ((insn & __BIT (14)) == 0)
+ {
+ /* N32_BR1_BEQ */
+ if (N32_IS_RT3 (insn) && N32_RA5 (insn) == REG_R5
+ && N32_RT5 (insn) != REG_R5)
+ insn16 = N16_TYPE38 (BEQS38, N32_RT5 (insn), N32_IMM14S (insn));
+ else if (N32_IS_RA3 (insn) && N32_RT5 (insn) == REG_R5
+ && N32_RA5 (insn) != REG_R5)
+ insn16 = N16_TYPE38 (BEQS38, N32_RA5 (insn), N32_IMM14S (insn));
+ insn_type = NDS32_INSN_BEQS38;
+ break;
+ }
+ else
+ {
+ /* N32_BR1_BNE */
+ if (N32_IS_RT3 (insn) && N32_RA5 (insn) == REG_R5
+ && N32_RT5 (insn) != REG_R5)
+ insn16 = N16_TYPE38 (BNES38, N32_RT5 (insn), N32_IMM14S (insn));
+ else if (N32_IS_RA3 (insn) && N32_RT5 (insn) == REG_R5
+ && N32_RA5 (insn) != REG_R5)
+ insn16 = N16_TYPE38 (BNES38, N32_RA5 (insn), N32_IMM14S (insn));
+ insn_type = NDS32_INSN_BNES38;
+ break;
+ }
+ break;
+
+ case N32_OP6_BR2:
+ switch (N32_BR2_SUB (insn))
+ {
+ case N32_BR2_BEQZ:
+ if (N32_IS_RT3 (insn) && IS_WITHIN_S (N32_IMM16S (insn), 8))
+ {
+ insn16 = N16_TYPE38 (BEQZ38, N32_RT5 (insn), N32_IMM16S (insn));
+ insn_type = NDS32_INSN_BEQZ38;
+ }
+ else if (N32_RT5 (insn) == REG_R15
+ && IS_WITHIN_S (N32_IMM16S (insn), 8))
+ {
+ insn16 = N16_TYPE8 (BEQZS8, N32_IMM16S (insn));
+ insn_type = NDS32_INSN_BEQZS8;
+ }
+ break;
+
+ case N32_BR2_BNEZ:
+ if (N32_IS_RT3 (insn) && IS_WITHIN_S (N32_IMM16S (insn), 8))
+ {
+ insn16 = N16_TYPE38 (BNEZ38, N32_RT5 (insn), N32_IMM16S (insn));
+ insn_type = NDS32_INSN_BNEZ38;
+ }
+ else if (N32_RT5 (insn) == REG_R15
+ && IS_WITHIN_S (N32_IMM16S (insn), 8))
+ {
+ insn16 = N16_TYPE8 (BNEZS8, N32_IMM16S (insn));
+ insn_type = NDS32_INSN_BNEZS8;
+ }
+ break;
+
+ case N32_BR2_IFCALL:
+ if (IS_WITHIN_U (N32_IMM16S (insn), 9))
+ {
+ insn16 = N16_TYPE9 (IFCALL9, N32_IMM16S (insn));
+ insn_type = NDS32_INSN_IFCALL9;
+ }
+ break;
+ }
+ break;
+
+ case N32_OP6_JI:
+ if ((insn & __BIT (24)) == 0)
+ {
+ /* N32_JI_J */
+ if (IS_WITHIN_S (N32_IMM24S (insn), 8))
+ {
+ insn16 = N16_TYPE8 (J8, N32_IMM24S (insn));
+ insn_type = NDS32_INSN_J8;
+ }
+ }
+ break;
+
+ case N32_OP6_JREG:
+ if (__GF (insn, 8, 2) != 0)
+ goto done;
+
+ switch (N32_IMMU (insn, 5))
+ {
+ case N32_JREG_JR:
+ if (N32_JREG_HINT (insn) == 0)
+ {
+ /* jr */
+ insn16 = N16_TYPE5 (JR5, N32_RB5 (insn));
+ insn_type = NDS32_INSN_JR5;
+ }
+ else if (N32_JREG_HINT (insn) == 1)
+ {
+ /* ret */
+ insn16 = N16_TYPE5 (RET5, N32_RB5 (insn));
+ insn_type = NDS32_INSN_RET5;
+ }
+ else if (N32_JREG_HINT (insn) == 3)
+ {
+ /* ifret = mov55 $sp, $sp */
+ insn16 = N16_TYPE55 (MOV55, REG_SP, REG_SP);
+ insn_type = NDS32_INSN_IFRET;
+ }
+ break;
+
+ case N32_JREG_JRAL:
+ /* It's convertible when return rt5 is $lp and address
+ translation is kept. */
+ if (N32_RT5 (insn) == REG_LP && N32_JREG_HINT (insn) == 0)
+ {
+ insn16 = N16_TYPE5 (JRAL5, N32_RB5 (insn));
+ insn_type = NDS32_INSN_JRAL5;
+ }
+ break;
+ }
+ break;
+
+ case N32_OP6_MISC:
+ if (N32_SUB5 (insn) == N32_MISC_BREAK && N32_SWID (insn) < 32)
+ {
+ /* For v3, swid above 31 are used for ex9.it. */
+ insn16 = N16_TYPE5 (BREAK16, N32_SWID (insn));
+ insn_type = NDS32_INSN_BREAK16;
+ }
+ break;
+
+ default:
+ /* This instruction has no 16-bit variant. */
+ goto done;
+ }
+
+done:
+ /* Bit-15 of insn16 should be set for a valid instruction. */
+ if ((insn16 & 0x8000) == 0)
+ return 0;
+
+ if (pinsn16)
+ *pinsn16 = insn16;
+ if (pinsn_type)
+ *pinsn_type = insn_type;
+ return 1;
+}
+
+static int
+special_convert_32_to_16 (unsigned long insn, uint16_t *pinsn16,
+ Elf_Internal_Rela *reloc)
+{
+ uint16_t insn16 = 0;
+
+ if ((reloc->r_addend & R_NDS32_INSN16_FP7U2_FLAG) == 0
+ || (ELF32_R_TYPE (reloc->r_info) != R_NDS32_INSN16))
+ return 0;
+
+ if (!N32_IS_RT3 (insn))
+ return 0;
+
+ switch (N32_OP6 (insn))
+ {
+ case N32_OP6_LWI:
+ if (N32_RA5 (insn) == REG_GP && IS_WITHIN_U (N32_IMM15S (insn), 7))
+ insn16 = N16_TYPE37 (XWI37, N32_RT5 (insn), 0, N32_IMM15S (insn));
+ break;
+ case N32_OP6_SWI:
+ if (N32_RA5 (insn) == REG_GP && IS_WITHIN_U (N32_IMM15S (insn), 7))
+ insn16 = N16_TYPE37 (XWI37, N32_RT5 (insn), 1, N32_IMM15S (insn));
+ break;
+ case N32_OP6_HWGP:
+ if (!IS_WITHIN_U (N32_IMM17S (insn), 7))
+ break;
+
+ if (__GF (insn, 17, 3) == 6)
+ insn16 = N16_TYPE37 (XWI37, N32_RT5 (insn), 0, N32_IMM17S (insn));
+ else if (__GF (insn, 17, 3) == 7)
+ insn16 = N16_TYPE37 (XWI37, N32_RT5 (insn), 1, N32_IMM17S (insn));
+ break;
+ }
+
+ if ((insn16 & 0x8000) == 0)
+ return 0;
+
+ *pinsn16 = insn16;
+ return 1;
+}
+
+/* Convert a 16-bit instruction to 32-bit one.
+ INSN16 it the input and PINSN it the point to output.
+ Return non-zero on successful. Otherwise 0 is returned. */
+
+int
+nds32_convert_16_to_32 (bfd *abfd, uint16_t insn16, uint32_t *pinsn)
+{
+ uint32_t insn = 0xffffffff;
+ unsigned long mach = bfd_get_mach (abfd);
+
+ /* NOTE: push25, pop25 and movd44 do not have 32-bit variants. */
+
+ switch (__GF (insn16, 9, 6))
+ {
+ case 0x4: /* add45 */
+ insn = N32_ALU1 (ADD, N16_RT4 (insn16), N16_RT4 (insn16),
+ N16_RA5 (insn16));
+ goto done;
+ case 0x5: /* sub45 */
+ insn = N32_ALU1 (SUB, N16_RT4 (insn16), N16_RT4 (insn16),
+ N16_RA5 (insn16));
+ goto done;
+ case 0x6: /* addi45 */
+ insn = N32_TYPE2 (ADDI, N16_RT4 (insn16), N16_RT4 (insn16),
+ N16_IMM5U (insn16));
+ goto done;
+ case 0x7: /* subi45 */
+ insn = N32_TYPE2 (ADDI, N16_RT4 (insn16), N16_RT4 (insn16),
+ -N16_IMM5U (insn16));
+ goto done;
+ case 0x8: /* srai45 */
+ insn = N32_ALU1 (SRAI, N16_RT4 (insn16), N16_RT4 (insn16),
+ N16_IMM5U (insn16));
+ goto done;
+ case 0x9: /* srli45 */
+ insn = N32_ALU1 (SRLI, N16_RT4 (insn16), N16_RT4 (insn16),
+ N16_IMM5U (insn16));
+ goto done;
+ case 0xa: /* slli333 */
+ insn = N32_ALU1 (SLLI, N16_RT3 (insn16), N16_RA3 (insn16),
+ N16_IMM3U (insn16));
+ goto done;
+ case 0xc: /* add333 */
+ insn = N32_ALU1 (ADD, N16_RT3 (insn16), N16_RA3 (insn16),
+ N16_RB3 (insn16));
+ goto done;
+ case 0xd: /* sub333 */
+ insn = N32_ALU1 (SUB, N16_RT3 (insn16), N16_RA3 (insn16),
+ N16_RB3 (insn16));
+ goto done;
+ case 0xe: /* addi333 */
+ insn = N32_TYPE2 (ADDI, N16_RT3 (insn16), N16_RA3 (insn16),
+ N16_IMM3U (insn16));
+ goto done;
+ case 0xf: /* subi333 */
+ insn = N32_TYPE2 (ADDI, N16_RT3 (insn16), N16_RA3 (insn16),
+ -N16_IMM3U (insn16));
+ goto done;
+ case 0x10: /* lwi333 */
+ insn = N32_TYPE2 (LWI, N16_RT3 (insn16), N16_RA3 (insn16),
+ N16_IMM3U (insn16));
+ goto done;
+ case 0x12: /* lhi333 */
+ insn = N32_TYPE2 (LHI, N16_RT3 (insn16), N16_RA3 (insn16),
+ N16_IMM3U (insn16));
+ goto done;
+ case 0x13: /* lbi333 */
+ insn = N32_TYPE2 (LBI, N16_RT3 (insn16), N16_RA3 (insn16),
+ N16_IMM3U (insn16));
+ goto done;
+ case 0x11: /* lwi333.bi */
+ insn = N32_TYPE2 (LWI_BI, N16_RT3 (insn16), N16_RA3 (insn16),
+ N16_IMM3U (insn16));
+ goto done;
+ case 0x14: /* swi333 */
+ insn = N32_TYPE2 (SWI, N16_RT3 (insn16), N16_RA3 (insn16),
+ N16_IMM3U (insn16));
+ goto done;
+ case 0x16: /* shi333 */
+ insn = N32_TYPE2 (SHI, N16_RT3 (insn16), N16_RA3 (insn16),
+ N16_IMM3U (insn16));
+ goto done;
+ case 0x17: /* sbi333 */
+ insn = N32_TYPE2 (SBI, N16_RT3 (insn16), N16_RA3 (insn16),
+ N16_IMM3U (insn16));
+ goto done;
+ case 0x15: /* swi333.bi */
+ insn = N32_TYPE2 (SWI_BI, N16_RT3 (insn16), N16_RA3 (insn16),
+ N16_IMM3U (insn16));
+ goto done;
+ case 0x18: /* addri36.sp */
+ insn = N32_TYPE2 (ADDI, N16_RT3 (insn16), REG_SP,
+ N16_IMM6U (insn16) << 2);
+ goto done;
+ case 0x19: /* lwi45.fe */
+ insn = N32_TYPE2 (LWI, N16_RT4 (insn16), REG_R8,
+ (N16_IMM5U (insn16) - 32));
+ goto done;
+ case 0x1a: /* lwi450 */
+ insn = N32_TYPE2 (LWI, N16_RT4 (insn16), N16_RA5 (insn16), 0);
+ goto done;
+ case 0x1b: /* swi450 */
+ insn = N32_TYPE2 (SWI, N16_RT4 (insn16), N16_RA5 (insn16), 0);
+ goto done;
+
+ /* These are r15 implied instructions. */
+ case 0x30: /* slts45 */
+ insn = N32_ALU1 (SLTS, REG_TA, N16_RT4 (insn16), N16_RA5 (insn16));
+ goto done;
+ case 0x31: /* slt45 */
+ insn = N32_ALU1 (SLT, REG_TA, N16_RT4 (insn16), N16_RA5 (insn16));
+ goto done;
+ case 0x32: /* sltsi45 */
+ insn = N32_TYPE2 (SLTSI, REG_TA, N16_RT4 (insn16), N16_IMM5U (insn16));
+ goto done;
+ case 0x33: /* slti45 */
+ insn = N32_TYPE2 (SLTI, REG_TA, N16_RT4 (insn16), N16_IMM5U (insn16));
+ goto done;
+ case 0x34: /* beqzs8, bnezs8 */
+ if (insn16 & __BIT (8))
+ insn = N32_BR2 (BNEZ, REG_TA, N16_IMM8S (insn16));
+ else
+ insn = N32_BR2 (BEQZ, REG_TA, N16_IMM8S (insn16));
+ goto done;
+
+ case 0x35: /* break16, ex9.it */
+ /* Only consider range of v3 break16. */
+ insn = N32_TYPE0 (MISC, (N16_IMM5U (insn16) << 5) | N32_MISC_BREAK);
+ goto done;
+
+ case 0x3c: /* ifcall9 */
+ insn = N32_BR2 (IFCALL, 0, N16_IMM9U (insn16));
+ goto done;
+ case 0x3d: /* movpi45 */
+ insn = N32_TYPE1 (MOVI, N16_RT4 (insn16), N16_IMM5U (insn16) + 16);
+ goto done;
+
+ case 0x3f: /* MISC33 */
+ switch (insn16 & 0x7)
+ {
+ case 2: /* neg33 */
+ insn = N32_TYPE2 (SUBRI, N16_RT3 (insn16), N16_RA3 (insn16), 0);
+ break;
+ case 3: /* not33 */
+ insn = N32_ALU1 (NOR, N16_RT3 (insn16), N16_RA3 (insn16),
+ N16_RA3 (insn16));
+ break;
+ case 4: /* mul33 */
+ insn = N32_ALU2 (MUL, N16_RT3 (insn16), N16_RT3 (insn16),
+ N16_RA3 (insn16));
+ break;
+ case 5: /* xor33 */
+ insn = N32_ALU1 (XOR, N16_RT3 (insn16), N16_RT3 (insn16),
+ N16_RA3 (insn16));
+ break;
+ case 6: /* and33 */
+ insn = N32_ALU1 (AND, N16_RT3 (insn16), N16_RT3 (insn16),
+ N16_RA3 (insn16));
+ break;
+ case 7: /* or33 */
+ insn = N32_ALU1 (OR, N16_RT3 (insn16), N16_RT3 (insn16),
+ N16_RA3 (insn16));
+ break;
+ }
+ goto done;
+
+ case 0xb:
+ switch (insn16 & 0x7)
+ {
+ case 0: /* zeb33 */
+ insn = N32_TYPE2 (ANDI, N16_RT3 (insn16), N16_RA3 (insn16), 0xff);
+ break;
+ case 1: /* zeh33 */
+ insn = N32_ALU1 (ZEH, N16_RT3 (insn16), N16_RA3 (insn16), 0);
+ break;
+ case 2: /* seb33 */
+ insn = N32_ALU1 (SEB, N16_RT3 (insn16), N16_RA3 (insn16), 0);
+ break;
+ case 3: /* seh33 */
+ insn = N32_ALU1 (SEH, N16_RT3 (insn16), N16_RA3 (insn16), 0);
+ break;
+ case 4: /* xlsb33 */
+ insn = N32_TYPE2 (ANDI, N16_RT3 (insn16), N16_RA3 (insn16), 1);
+ break;
+ case 5: /* x11b33 */
+ insn = N32_TYPE2 (ANDI, N16_RT3 (insn16), N16_RA3 (insn16), 0x7ff);
+ break;
+ case 6: /* bmski33 */
+ insn = N32_TYPE2 (ANDI, N16_RT3 (insn16), N16_RT3 (insn16),
+ 1 << __GF (insn16, 3, 3));
+ break;
+ case 7: /* fexti33 */
+ insn = N32_TYPE2 (ANDI, N16_RT3 (insn16), N16_RT3 (insn16),
+ (1 << (__GF (insn16, 3, 3) + 1)) - 1);
+ break;
+ }
+ goto done;
+ }
+
+ switch (__GF (insn16, 10, 5))
+ {
+ case 0x0: /* mov55 or ifret16 */
+ if (mach >= MACH_V3 && N16_RT5 (insn16) == REG_SP
+ && N16_RT5 (insn16) == N16_RA5 (insn16))
+ insn = N32_JREG (JR, 0, 0, 0, 3);
+ else
+ insn = N32_TYPE2 (ADDI, N16_RT5 (insn16), N16_RA5 (insn16), 0);
+ goto done;
+ case 0x1: /* movi55 */
+ insn = N32_TYPE1 (MOVI, N16_RT5 (insn16), N16_IMM5S (insn16));
+ goto done;
+ case 0x1b: /* addi10s (V2) */
+ insn = N32_TYPE2 (ADDI, REG_SP, REG_SP, N16_IMM10S (insn16));
+ goto done;
+ }
+
+ switch (__GF (insn16, 11, 4))
+ {
+ case 0x7: /* lwi37.fp/swi37.fp */
+ if (insn16 & __BIT (7)) /* swi37.fp */
+ insn = N32_TYPE2 (SWI, N16_RT38 (insn16), REG_FP, N16_IMM7U (insn16));
+ else /* lwi37.fp */
+ insn = N32_TYPE2 (LWI, N16_RT38 (insn16), REG_FP, N16_IMM7U (insn16));
+ goto done;
+ case 0x8: /* beqz38 */
+ insn = N32_BR2 (BEQZ, N16_RT38 (insn16), N16_IMM8S (insn16));
+ goto done;
+ case 0x9: /* bnez38 */
+ insn = N32_BR2 (BNEZ, N16_RT38 (insn16), N16_IMM8S (insn16));
+ goto done;
+ case 0xa: /* beqs38/j8, implied r5 */
+ if (N16_RT38 (insn16) == 5)
+ insn = N32_JI (J, N16_IMM8S (insn16));
+ else
+ insn = N32_BR1 (BEQ, N16_RT38 (insn16), REG_R5, N16_IMM8S (insn16));
+ goto done;
+ case 0xb: /* bnes38 and others */
+ if (N16_RT38 (insn16) == 5)
+ {
+ switch (__GF (insn16, 5, 3))
+ {
+ case 0: /* jr5 */
+ insn = N32_JREG (JR, 0, N16_RA5 (insn16), 0, 0);
+ break;
+ case 4: /* ret5 */
+ insn = N32_JREG (JR, 0, N16_RA5 (insn16), 0, 1);
+ break;
+ case 1: /* jral5 */
+ insn = N32_JREG (JRAL, REG_LP, N16_RA5 (insn16), 0, 0);
+ break;
+ case 2: /* ex9.it imm5 */
+ /* ex9.it had no 32-bit variantl. */
+ break;
+ case 5: /* add5.pc */
+ /* add5.pc had no 32-bit variantl. */
+ break;
+ }
+ }
+ else /* bnes38 */
+ insn = N32_BR1 (BNE, N16_RT38 (insn16), REG_R5, N16_IMM8S (insn16));
+ goto done;
+ case 0xe: /* lwi37/swi37 */
+ if (insn16 & (1 << 7)) /* swi37.sp */
+ insn = N32_TYPE2 (SWI, N16_RT38 (insn16), REG_SP, N16_IMM7U (insn16));
+ else /* lwi37.sp */
+ insn = N32_TYPE2 (LWI, N16_RT38 (insn16), REG_SP, N16_IMM7U (insn16));
+ goto done;
+ }
+
+done:
+ if (insn & 0x80000000)
+ return 0;
+
+ if (pinsn)
+ *pinsn = insn;
+ return 1;
+}
+
+static bfd_boolean
+is_sda_access_insn (unsigned long insn)
+{
+ switch (N32_OP6 (insn))
+ {
+ case N32_OP6_LWI:
+ case N32_OP6_LHI:
+ case N32_OP6_LHSI:
+ case N32_OP6_LBI:
+ case N32_OP6_LBSI:
+ case N32_OP6_SWI:
+ case N32_OP6_SHI:
+ case N32_OP6_SBI:
+ case N32_OP6_LWC:
+ case N32_OP6_LDC:
+ case N32_OP6_SWC:
+ case N32_OP6_SDC:
+ return TRUE;
+ default:
+ ;
+ }
+ return FALSE;
+}
+
+static unsigned long
+turn_insn_to_sda_access (uint32_t insn, bfd_signed_vma type, uint32_t *pinsn)
+{
+ uint32_t oinsn = 0;
+
+ switch (type)
+ {
+ case R_NDS32_GOT_LO12:
+ case R_NDS32_GOTOFF_LO12:
+ case R_NDS32_PLTREL_LO12:
+ case R_NDS32_PLT_GOTREL_LO12:
+ case R_NDS32_LO12S0_RELA:
+ switch (N32_OP6 (insn))
+ {
+ case N32_OP6_LBI:
+ /* lbi.gp */
+ oinsn = N32_TYPE1 (LBGP, N32_RT5 (insn), 0);
+ break;
+ case N32_OP6_LBSI:
+ /* lbsi.gp */
+ oinsn = N32_TYPE1 (LBGP, N32_RT5 (insn), __BIT (19));
+ break;
+ case N32_OP6_SBI:
+ /* sbi.gp */
+ oinsn = N32_TYPE1 (SBGP, N32_RT5 (insn), 0);
+ break;
+ case N32_OP6_ORI:
+ /* addi.gp */
+ oinsn = N32_TYPE1 (SBGP, N32_RT5 (insn), __BIT (19));
+ break;
+ }
+ break;
+
+ case R_NDS32_LO12S1_RELA:
+ switch (N32_OP6 (insn))
+ {
+ case N32_OP6_LHI:
+ /* lhi.gp */
+ oinsn = N32_TYPE1 (HWGP, N32_RT5 (insn), 0);
+ break;
+ case N32_OP6_LHSI:
+ /* lhsi.gp */
+ oinsn = N32_TYPE1 (HWGP, N32_RT5 (insn), __BIT (18));
+ break;
+ case N32_OP6_SHI:
+ /* shi.gp */
+ oinsn = N32_TYPE1 (HWGP, N32_RT5 (insn), __BIT (19));
+ break;
+ }
+ break;
+
+ case R_NDS32_LO12S2_RELA:
+ switch (N32_OP6 (insn))
+ {
+ case N32_OP6_LWI:
+ /* lwi.gp */
+ oinsn = N32_TYPE1 (HWGP, N32_RT5 (insn), __MF (6, 17, 3));
+ break;
+ case N32_OP6_SWI:
+ /* swi.gp */
+ oinsn = N32_TYPE1 (HWGP, N32_RT5 (insn), __MF (7, 17, 3));
+ break;
+ }
+ break;
+
+ case R_NDS32_LO12S2_DP_RELA:
+ case R_NDS32_LO12S2_SP_RELA:
+ oinsn = (insn & 0x7ff07000) | (REG_GP << 15);
+ break;
+ }
+
+ if (oinsn)
+ *pinsn = oinsn;
+
+ return oinsn != 0;
+}
+
+/* Linker hasn't found the correct merge section for non-section symbol
+ in relax time, this work is left to the function elf_link_input_bfd().
+ So for non-section symbol, _bfd_merged_section_offset is also needed
+ to find the correct symbol address. */
+
+static bfd_vma
+nds32_elf_rela_local_sym (bfd *abfd, Elf_Internal_Sym *sym,
+ asection **psec, Elf_Internal_Rela *rel)
+{
+ asection *sec = *psec;
+ bfd_vma relocation;
+
+ relocation = (sec->output_section->vma
+ + sec->output_offset + sym->st_value);
+ if ((sec->flags & SEC_MERGE) && sec->sec_info_type == SEC_INFO_TYPE_MERGE)
+ {
+ if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
+ rel->r_addend =
+ _bfd_merged_section_offset (abfd, psec,
+ elf_section_data (sec)->sec_info,
+ sym->st_value + rel->r_addend);
+ else
+ rel->r_addend =
+ _bfd_merged_section_offset (abfd, psec,
+ elf_section_data (sec)->sec_info,
+ sym->st_value) + rel->r_addend;
+
+ if (sec != *psec)
+ {
+ /* If we have changed the section, and our original section is
+ marked with SEC_EXCLUDE, it means that the original
+ SEC_MERGE section has been completely subsumed in some
+ other SEC_MERGE section. In this case, we need to leave
+ some info around for --emit-relocs. */
+ if ((sec->flags & SEC_EXCLUDE) != 0)
+ sec->kept_section = *psec;
+ sec = *psec;
+ }
+ rel->r_addend -= relocation;
+ rel->r_addend += sec->output_section->vma + sec->output_offset;
+ }
+ return relocation;
+}
+
+static bfd_vma
+calculate_memory_address (bfd *abfd, Elf_Internal_Rela *irel,
+ Elf_Internal_Sym *isymbuf,
+ Elf_Internal_Shdr *symtab_hdr)
+{
+ bfd_signed_vma foff;
+ bfd_vma symval, addend;
+ Elf_Internal_Rela irel_fn;
+ Elf_Internal_Sym *isym;
+ asection *sym_sec;
+
+ /* Get the value of the symbol referred to by the reloc. */
+ if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
+ {
+ /* A local symbol. */
+ isym = isymbuf + ELF32_R_SYM (irel->r_info);
+
+ if (isym->st_shndx == SHN_UNDEF)
+ sym_sec = bfd_und_section_ptr;
+ 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;
+ else
+ sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
+ memcpy (&irel_fn, irel, sizeof (Elf_Internal_Rela));
+ symval = nds32_elf_rela_local_sym (abfd, isym, &sym_sec, &irel_fn);
+ addend = irel_fn.r_addend;
+ }
+ 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);
+
+ 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)
+ /* This appears to be a reference to an undefined
+ symbol. Just ignore it--it will be caught by the
+ regular reloc processing. */
+ return 0;
+
+ if (h->root.u.def.section->flags & SEC_MERGE)
+ {
+ sym_sec = h->root.u.def.section;
+ symval = _bfd_merged_section_offset (abfd, &sym_sec, elf_section_data
+ (sym_sec)->sec_info, h->root.u.def.value);
+ symval = symval + sym_sec->output_section->vma
+ + sym_sec->output_offset;
+ }
+ else
+ symval = (h->root.u.def.value
+ + h->root.u.def.section->output_section->vma
+ + h->root.u.def.section->output_offset);
+ addend = irel->r_addend;
+ }
+
+ foff = symval + addend;
+
+ return foff;
+}
+
+static bfd_vma
+calculate_got_memory_address (bfd *abfd, struct bfd_link_info *link_info,
+ Elf_Internal_Rela *irel,
+ Elf_Internal_Shdr *symtab_hdr)
+{
+ int symndx;
+ bfd_vma *local_got_offsets;
+ /* Get the value of the symbol referred to by the reloc. */
+ struct elf_link_hash_entry *h;
+ struct elf_nds32_link_hash_table *htab = nds32_elf_hash_table (link_info);
+
+ /* An external symbol. */
+ symndx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info;
+ h = elf_sym_hashes (abfd)[symndx];
+ 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 (symndx >= 0)
+ {
+ BFD_ASSERT (h != NULL);
+ return htab->sgot->output_section->vma + htab->sgot->output_offset
+ + h->got.offset;
+ }
+ else
+ {
+ local_got_offsets = elf_local_got_offsets (abfd);
+ BFD_ASSERT (local_got_offsets != NULL);
+ return htab->sgot->output_section->vma + htab->sgot->output_offset
+ + local_got_offsets[ELF32_R_SYM (irel->r_info)];
+ }
+
+ /* The _GLOBAL_OFFSET_TABLE_ may be undefweak(or should be?). */
+ /* The check of h->root.type is passed. */
+}
+
+static int
+is_16bit_NOP (bfd *abfd ATTRIBUTE_UNUSED,
+ asection *sec, Elf_Internal_Rela *rel)
+{
+ bfd_byte *contents;
+ unsigned short insn16;
+
+ if (!(rel->r_addend & R_NDS32_INSN16_CONVERT_FLAG))
+ return FALSE;
+ contents = elf_section_data (sec)->this_hdr.contents;
+ insn16 = bfd_getb16 (contents + rel->r_offset);
+ if (insn16 == NDS32_NOP16)
+ return TRUE;
+ return FALSE;
+}
+
+/* It checks whether the instruction could be converted to
+ 16-bit form and returns the converted one.
+
+ `internal_relocs' is supposed to be sorted. */
+
+static int
+is_convert_32_to_16 (bfd *abfd, asection *sec,
+ Elf_Internal_Rela *reloc,
+ Elf_Internal_Rela *internal_relocs,
+ Elf_Internal_Rela *irelend,
+ uint16_t *insn16)
+{
+#define NORMAL_32_TO_16 (1 << 0)
+#define SPECIAL_32_TO_16 (1 << 1)
+ bfd_byte *contents = NULL;
+ bfd_signed_vma off;
+ bfd_vma mem_addr;
+ uint32_t insn = 0;
+ Elf_Internal_Rela *pc_rel;
+ int pic_ext_target = 0;
+ Elf_Internal_Shdr *symtab_hdr;
+ Elf_Internal_Sym *isymbuf = NULL;
+ int convert_type;
+ bfd_vma offset;
+
+ if (reloc->r_offset + 4 > sec->size)
+ return FALSE;
+
+ offset = reloc->r_offset;
+
+ if (!nds32_get_section_contents (abfd, sec, &contents))
+ return FALSE;
+ insn = bfd_getb32 (contents + offset);
+
+ if (nds32_convert_32_to_16 (abfd, insn, insn16, NULL))
+ convert_type = NORMAL_32_TO_16;
+ else if (special_convert_32_to_16 (insn, insn16, reloc))
+ convert_type = SPECIAL_32_TO_16;
+ else
+ return FALSE;
+
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+ if (!nds32_get_local_syms (abfd, sec, &isymbuf))
+ return FALSE;
+
+ /* Find the first relocation of the same relocation-type,
+ so we iteratie them forward. */
+ pc_rel = reloc;
+ while ((pc_rel - 1) >= internal_relocs && pc_rel[-1].r_offset == offset)
+ pc_rel--;
+
+ for (; pc_rel < irelend && pc_rel->r_offset == offset; pc_rel++)
+ {
+ if (ELF32_R_TYPE (pc_rel->r_info) == R_NDS32_15_PCREL_RELA
+ || ELF32_R_TYPE (pc_rel->r_info) == R_NDS32_17_PCREL_RELA
+ || ELF32_R_TYPE (pc_rel->r_info) == R_NDS32_25_PCREL_RELA
+ || ELF32_R_TYPE (pc_rel->r_info) == R_NDS32_25_PLTREL)
+ {
+ off = calculate_offset (abfd, sec, pc_rel, isymbuf, symtab_hdr,
+ &pic_ext_target);
+ if (off >= ACCURATE_8BIT_S1 || off < -ACCURATE_8BIT_S1
+ || off == 0)
+ return FALSE;
+ break;
+ }
+ else if (ELF32_R_TYPE (pc_rel->r_info) == R_NDS32_20_RELA)
+ {
+ /* movi => movi55 */
+ mem_addr = calculate_memory_address (abfd, pc_rel, isymbuf,
+ symtab_hdr);
+ /* mem_addr is unsigned, but the value should
+ be between [-16, 15]. */
+ if ((mem_addr + 0x10) >> 5)
+ return FALSE;
+ break;
+ }
+ else if ((ELF32_R_TYPE (pc_rel->r_info) == R_NDS32_TLS_LE_20)
+ || (ELF32_R_TYPE (pc_rel->r_info) == R_NDS32_TLS_LE_LO12))
+ {
+ /* It never happen movi to movi55 for R_NDS32_TLS_LE_20,
+ because it can be relaxed to addi for TLS_LE_ADD. */
+ return FALSE;
+ }
+ else if ((ELF32_R_TYPE (pc_rel->r_info) == R_NDS32_SDA15S2_RELA
+ || ELF32_R_TYPE (pc_rel->r_info) == R_NDS32_SDA17S2_RELA)
+ && (reloc->r_addend & R_NDS32_INSN16_FP7U2_FLAG)
+ && convert_type == SPECIAL_32_TO_16)
+ {
+ /* fp-as-gp
+ We've selected a best fp-base for this access, so we can
+ always resolve it anyway. Do nothing. */
+ break;
+ }
+ else if ((ELF32_R_TYPE (pc_rel->r_info) > R_NDS32_NONE
+ && (ELF32_R_TYPE (pc_rel->r_info) < R_NDS32_RELA_GNU_VTINHERIT))
+ || ((ELF32_R_TYPE (pc_rel->r_info) > R_NDS32_RELA_GNU_VTENTRY)
+ && (ELF32_R_TYPE (pc_rel->r_info) < R_NDS32_INSN16))
+ || ((ELF32_R_TYPE (pc_rel->r_info) > R_NDS32_LOADSTORE)
+ && (ELF32_R_TYPE (pc_rel->r_info) < R_NDS32_DWARF2_OP1_RELA)))
+ {
+ /* Prevent unresolved addi instruction translate
+ to addi45 or addi333. */
+ return FALSE;
+ }
+ else if ((ELF32_R_TYPE (pc_rel->r_info) == R_NDS32_17IFC_PCREL_RELA))
+ {
+ off = calculate_offset (abfd, sec, pc_rel, isymbuf, symtab_hdr,
+ &pic_ext_target);
+ if (off >= ACCURATE_U9BIT_S1 || off <= 0)
+ return FALSE;
+ break;
+ }
+ }
+
+ return TRUE;
+}
+
+static void
+nds32_elf_write_16 (bfd *abfd ATTRIBUTE_UNUSED, bfd_byte *contents,
+ Elf_Internal_Rela *reloc,
+ Elf_Internal_Rela *internal_relocs,
+ Elf_Internal_Rela *irelend,
+ unsigned short insn16)
+{
+ Elf_Internal_Rela *pc_rel;
+ bfd_vma offset;
+
+ offset = reloc->r_offset;
+ bfd_putb16 (insn16, contents + offset);
+ /* Find the first relocation of the same relocation-type,
+ so we iteratie them forward. */
+ pc_rel = reloc;
+ while ((pc_rel - 1) > internal_relocs && pc_rel[-1].r_offset == offset)
+ pc_rel--;
+
+ for (; pc_rel < irelend && pc_rel->r_offset == offset; pc_rel++)
+ {
+ if (ELF32_R_TYPE (pc_rel->r_info) == R_NDS32_15_PCREL_RELA
+ || ELF32_R_TYPE (pc_rel->r_info) == R_NDS32_17_PCREL_RELA
+ || ELF32_R_TYPE (pc_rel->r_info) == R_NDS32_25_PCREL_RELA)
+ {
+ pc_rel->r_info =
+ ELF32_R_INFO (ELF32_R_SYM (pc_rel->r_info), R_NDS32_9_PCREL_RELA);
+ }
+ else if (ELF32_R_TYPE (pc_rel->r_info) == R_NDS32_25_PLTREL)
+ pc_rel->r_info =
+ ELF32_R_INFO (ELF32_R_SYM (pc_rel->r_info), R_NDS32_9_PLTREL);
+ else if (ELF32_R_TYPE (pc_rel->r_info) == R_NDS32_20_RELA)
+ pc_rel->r_info =
+ ELF32_R_INFO (ELF32_R_SYM (pc_rel->r_info), R_NDS32_5_RELA);
+ else if (ELF32_R_TYPE (pc_rel->r_info) == R_NDS32_SDA15S2_RELA
+ || ELF32_R_TYPE (pc_rel->r_info) == R_NDS32_SDA17S2_RELA)
+ pc_rel->r_info =
+ ELF32_R_INFO (ELF32_R_SYM (pc_rel->r_info), R_NDS32_SDA_FP7U2_RELA);
+ else if ((ELF32_R_TYPE (pc_rel->r_info) == R_NDS32_17IFC_PCREL_RELA))
+ pc_rel->r_info =
+ ELF32_R_INFO (ELF32_R_SYM (pc_rel->r_info), R_NDS32_10IFCU_PCREL_RELA);
+ }
+}
+
+/* Find a relocation of type specified by `reloc_type'
+ of the same r_offset with reloc.
+ If not found, return irelend.
+
+ Assuming relocations are sorted by r_offset,
+ we find the relocation from `reloc' backward untill relocs,
+ or find it from `reloc' forward untill irelend. */
+
+static Elf_Internal_Rela *
+find_relocs_at_address (Elf_Internal_Rela *reloc,
+ Elf_Internal_Rela *relocs,
+ Elf_Internal_Rela *irelend,
+ enum elf_nds32_reloc_type reloc_type)
+{
+ Elf_Internal_Rela *rel_t;
+
+ /* Find backward. */
+ for (rel_t = reloc;
+ rel_t >= relocs && rel_t->r_offset == reloc->r_offset;
+ rel_t--)
+ if (ELF32_R_TYPE (rel_t->r_info) == reloc_type)
+ return rel_t;
+
+ /* We didn't find it backward. Try find it forward. */
+ for (rel_t = reloc;
+ rel_t < irelend && rel_t->r_offset == reloc->r_offset;
+ rel_t++)
+ if (ELF32_R_TYPE (rel_t->r_info) == reloc_type)
+ return rel_t;
+
+ return irelend;
+}
+
+/* Find a relocation of specified type and offset.
+ `reloc' is just a refence point to find a relocation at specified offset.
+ If not found, return irelend.
+
+ Assuming relocations are sorted by r_offset,
+ we find the relocation from `reloc' backward untill relocs,
+ or find it from `reloc' forward untill irelend. */
+
+static Elf_Internal_Rela *
+find_relocs_at_address_addr (Elf_Internal_Rela *reloc,
+ Elf_Internal_Rela *relocs,
+ Elf_Internal_Rela *irelend,
+ unsigned char reloc_type,
+ bfd_vma offset_p)
+{
+ Elf_Internal_Rela *rel_t = NULL;
+
+ /* First, we try to find a relocation of offset `offset_p',
+ and then we use find_relocs_at_address to find specific type. */
+
+ if (reloc->r_offset > offset_p)
+ {
+ /* Find backward. */
+ for (rel_t = reloc;
+ rel_t >= relocs && rel_t->r_offset > offset_p; rel_t--)
+ /* Do nothing. */;
+ }
+ else if (reloc->r_offset < offset_p)
+ {
+ /* Find forward. */
+ for (rel_t = reloc;
+ rel_t < irelend && rel_t->r_offset < offset_p; rel_t++)
+ /* Do nothing. */;
+ }
+ else
+ rel_t = reloc;
+
+ /* Not found? */
+ if (rel_t < relocs || rel_t == irelend || rel_t->r_offset != offset_p)
+ return irelend;
+
+ return find_relocs_at_address (rel_t, relocs, irelend, reloc_type);
+}
+
+static bfd_boolean
+nds32_elf_check_dup_relocs (Elf_Internal_Rela *reloc,
+ Elf_Internal_Rela *internal_relocs,
+ Elf_Internal_Rela *irelend,
+ unsigned char reloc_type)
+{
+ Elf_Internal_Rela *rel_t;
+
+ for (rel_t = reloc;
+ rel_t >= internal_relocs && rel_t->r_offset == reloc->r_offset;
+ rel_t--)
+ if (ELF32_R_TYPE (rel_t->r_info) == reloc_type)
+ {
+ if (ELF32_R_SYM (rel_t->r_info) == ELF32_R_SYM (reloc->r_info)
+ && rel_t->r_addend == reloc->r_addend)
+ continue;
+ return TRUE;
+ }
+
+ for (rel_t = reloc; rel_t < irelend && rel_t->r_offset == reloc->r_offset;
+ rel_t++)
+ if (ELF32_R_TYPE (rel_t->r_info) == reloc_type)
+ {
+ if (ELF32_R_SYM (rel_t->r_info) == ELF32_R_SYM (reloc->r_info)
+ && rel_t->r_addend == reloc->r_addend)
+ continue;
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+typedef struct nds32_elf_blank nds32_elf_blank_t;
+struct nds32_elf_blank
+{
+ /* Where the blank begins. */
+ bfd_vma offset;
+ /* The size of the blank. */
+ bfd_vma size;
+ /* The accumulative size before this blank. */
+ bfd_vma total_size;
+ nds32_elf_blank_t *next;
+ nds32_elf_blank_t *prev;
+};
+
+static nds32_elf_blank_t *blank_free_list = NULL;
+
+static nds32_elf_blank_t *
+create_nds32_elf_blank (bfd_vma offset_p, bfd_vma size_p)
+{
+ nds32_elf_blank_t *blank_t;
+
+ if (blank_free_list)
+ {
+ blank_t = blank_free_list;
+ blank_free_list = blank_free_list->next;
+ }
+ else
+ blank_t = bfd_malloc (sizeof (nds32_elf_blank_t));
+
+ if (blank_t == NULL)
+ return NULL;
+
+ blank_t->offset = offset_p;
+ blank_t->size = size_p;
+ blank_t->total_size = 0;
+ blank_t->next = NULL;
+ blank_t->prev = NULL;
+
+ return blank_t;
+}
+
+static void
+remove_nds32_elf_blank (nds32_elf_blank_t *blank_p)
+{
+ if (blank_free_list)
+ {
+ blank_free_list->prev = blank_p;
+ blank_p->next = blank_free_list;
+ }
+ else
+ blank_p->next = NULL;
+
+ blank_p->prev = NULL;
+ blank_free_list = blank_p;
+}
+
+static void
+clean_nds32_elf_blank (void)
+{
+ nds32_elf_blank_t *blank_t;
+
+ while (blank_free_list)
+ {
+ blank_t = blank_free_list;
+ blank_free_list = blank_free_list->next;
+ free (blank_t);
+ }
+}
+
+static nds32_elf_blank_t *
+search_nds32_elf_blank (nds32_elf_blank_t *blank_p, bfd_vma addr)
+{
+ nds32_elf_blank_t *blank_t;
+
+ if (!blank_p)
+ return NULL;
+ blank_t = blank_p;
+
+ while (blank_t && addr < blank_t->offset)
+ blank_t = blank_t->prev;
+ while (blank_t && blank_t->next && addr >= blank_t->next->offset)
+ blank_t = blank_t->next;
+
+ return blank_t;
+}
+
+static bfd_vma
+get_nds32_elf_blank_total (nds32_elf_blank_t **blank_p, bfd_vma addr,
+ int overwrite)
+{
+ nds32_elf_blank_t *blank_t;
+
+ blank_t = search_nds32_elf_blank (*blank_p, addr);
+ if (!blank_t)
+ return 0;
+
+ if (overwrite)
+ *blank_p = blank_t;
+
+ if (addr < blank_t->offset + blank_t->size)
+ return blank_t->total_size + (addr - blank_t->offset);
+ else
+ return blank_t->total_size + blank_t->size;
+}
+
+static bfd_boolean
+insert_nds32_elf_blank (nds32_elf_blank_t **blank_p, bfd_vma addr, bfd_vma len)
+{
+ nds32_elf_blank_t *blank_t, *blank_t2;
+
+ if (!*blank_p)
+ {
+ *blank_p = create_nds32_elf_blank (addr, len);
+ return *blank_p ? TRUE : FALSE;
+ }
+
+ blank_t = search_nds32_elf_blank (*blank_p, addr);
+
+ if (blank_t == NULL)
+ {
+ blank_t = create_nds32_elf_blank (addr, len);
+ if (!blank_t)
+ return FALSE;
+ while ((*blank_p)->prev != NULL)
+ *blank_p = (*blank_p)->prev;
+ blank_t->next = *blank_p;
+ (*blank_p)->prev = blank_t;
+ (*blank_p) = blank_t;
+ return TRUE;
+ }
+
+ if (addr < blank_t->offset + blank_t->size)
+ {
+ if (addr > blank_t->offset + blank_t->size)
+ blank_t->size = addr - blank_t->offset;
+ }
+ else
+ {
+ blank_t2 = create_nds32_elf_blank (addr, len);
+ if (!blank_t2)
+ return FALSE;
+ if (blank_t->next)
+ {
+ blank_t->next->prev = blank_t2;
+ blank_t2->next = blank_t->next;
+ }
+ blank_t2->prev = blank_t;
+ blank_t->next = blank_t2;
+ *blank_p = blank_t2;
+ }
+
+ return TRUE;
+}
+
+static bfd_boolean
+insert_nds32_elf_blank_recalc_total (nds32_elf_blank_t **blank_p, bfd_vma addr,
+ bfd_vma len)
+{
+ nds32_elf_blank_t *blank_t;
+
+ if (!insert_nds32_elf_blank (blank_p, addr, len))
+ return FALSE;
+
+ blank_t = *blank_p;
+
+ if (!blank_t->prev)
+ {
+ blank_t->total_size = 0;
+ blank_t = blank_t->next;
+ }
+
+ while (blank_t)
+ {
+ blank_t->total_size = blank_t->prev->total_size + blank_t->prev->size;
+ blank_t = blank_t->next;
+ }
+
+ return TRUE;
+}
+
+static void
+calc_nds32_blank_total (nds32_elf_blank_t *blank_p)
+{
+ nds32_elf_blank_t *blank_t;
+ bfd_vma total_size = 0;
+
+ if (!blank_p)
+ return;
+
+ blank_t = blank_p;
+ while (blank_t->prev)
+ blank_t = blank_t->prev;
+ while (blank_t)
+ {
+ blank_t->total_size = total_size;
+ total_size += blank_t->size;
+ blank_t = blank_t->next;
+ }
+}
+
+static bfd_boolean
+nds32_elf_relax_delete_blanks (bfd *abfd, asection *sec,
+ nds32_elf_blank_t *blank_p)
+{
+ Elf_Internal_Shdr *symtab_hdr; /* Symbol table header of this bfd. */
+ Elf_Internal_Sym *isym = NULL; /* Symbol table of this bfd. */
+ Elf_Internal_Sym *isymend; /* Symbol entry iterator. */
+ unsigned int sec_shndx; /* The section the be relaxed. */
+ bfd_byte *contents; /* Contents data of iterating section. */
+ Elf_Internal_Rela *internal_relocs;
+ Elf_Internal_Rela *irel;
+ Elf_Internal_Rela *irelend;
+ struct elf_link_hash_entry **sym_hashes;
+ struct elf_link_hash_entry **end_hashes;
+ unsigned int symcount;
+ asection *sect;
+ nds32_elf_blank_t *blank_t;
+ nds32_elf_blank_t *blank_t2;
+ nds32_elf_blank_t *blank_head;
+
+ blank_head = blank_t = blank_p;
+ while (blank_head->prev != NULL)
+ blank_head = blank_head->prev;
+ while (blank_t->next != NULL)
+ blank_t = blank_t->next;
+
+ if (blank_t->offset + blank_t->size <= sec->size)
+ {
+ blank_t->next = create_nds32_elf_blank (sec->size + 4, 0);
+ blank_t->next->prev = blank_t;
+ }
+ if (blank_head->offset > 0)
+ {
+ blank_head->prev = create_nds32_elf_blank (0, 0);
+ blank_head->prev->next = blank_head;
+ blank_head = blank_head->prev;
+ }
+
+ sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
+
+ /* The deletion must stop at the next ALIGN reloc for an alignment
+ power larger than the number of bytes we are deleting. */
+
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+ if (!nds32_get_local_syms (abfd, sec, &isym))
+ return FALSE;
+
+ if (isym == NULL)
+ {
+ isym = bfd_elf_get_elf_syms (abfd, symtab_hdr,
+ symtab_hdr->sh_info, 0, NULL, NULL, NULL);
+ symtab_hdr->contents = (bfd_byte *) isym;
+ }
+
+ if (isym == NULL || symtab_hdr->sh_info == 0)
+ return FALSE;
+
+ blank_t = blank_head;
+ calc_nds32_blank_total (blank_head);
+
+ for (sect = abfd->sections; sect != NULL; sect = sect->next)
+ {
+ /* Adjust all the relocs. */
+
+ /* Relocations MUST be kept in memory, because relaxation adjust them. */
+ internal_relocs = _bfd_elf_link_read_relocs (abfd, sect, NULL, NULL,
+ TRUE /* keep_memory */);
+ irelend = internal_relocs + sect->reloc_count;
+
+ blank_t = blank_head;
+ blank_t2 = blank_head;
+
+ if (!(sect->flags & SEC_RELOC))
+ continue;
+
+ nds32_get_section_contents (abfd, sect, &contents);
+
+ for (irel = internal_relocs; irel < irelend; irel++)
+ {
+ bfd_vma raddr;
+
+ if (ELF32_R_TYPE (irel->r_info) >= R_NDS32_DIFF8
+ && ELF32_R_TYPE (irel->r_info) <= R_NDS32_DIFF32
+ && isym[ELF32_R_SYM (irel->r_info)].st_shndx == sec_shndx)
+ {
+ unsigned long val = 0;
+ unsigned long mask;
+ long before, between;
+ long offset;
+
+ switch (ELF32_R_TYPE (irel->r_info))
+ {
+ case R_NDS32_DIFF8:
+ offset = bfd_get_8 (abfd, contents + irel->r_offset);
+ break;
+ case R_NDS32_DIFF16:
+ offset = bfd_get_16 (abfd, contents + irel->r_offset);
+ break;
+ case R_NDS32_DIFF32:
+ val = bfd_get_32 (abfd, contents + irel->r_offset);
+ /* Get the signed bit and mask for the high part. The
+ gcc will alarm when right shift 32-bit since the
+ type size of long may be 32-bit. */
+ mask = 0 - (val >> 31);
+ if (mask)
+ offset = (val | (mask - 0xffffffff));
+ else
+ offset = val;
+ break;
+ default:
+ BFD_ASSERT (0);
+ }
+
+ /* DIFF value
+ 0 |encoded in location|
+ |------------|-------------------|---------
+ sym+off(addend)
+ -- before ---| *****************
+ --------------------- between ---|
+
+ We only care how much data are relax between DIFF,
+ marked as ***. */
+
+ before = get_nds32_elf_blank_total (&blank_t, irel->r_addend, 0);
+ between = get_nds32_elf_blank_total (&blank_t,
+ irel->r_addend + offset, 0);
+ if (between == before)
+ goto done_adjust_diff;
+
+ switch (ELF32_R_TYPE (irel->r_info))
+ {
+ case R_NDS32_DIFF8:
+ bfd_put_8 (abfd, offset - (between - before),
+ contents + irel->r_offset);
+ break;
+ case R_NDS32_DIFF16:
+ bfd_put_16 (abfd, offset - (between - before),
+ contents + irel->r_offset);
+ break;
+ case R_NDS32_DIFF32:
+ bfd_put_32 (abfd, offset - (between - before),
+ contents + irel->r_offset);
+ break;
+ }
+ }
+ else if (ELF32_R_TYPE (irel->r_info) == R_NDS32_DIFF_ULEB128
+ && isym[ELF32_R_SYM (irel->r_info)].st_shndx == sec_shndx)
+ {
+ bfd_vma val = 0;
+ unsigned int len = 0;
+ unsigned long before, between;
+ bfd_byte *endp, *p;
+
+ val = read_unsigned_leb128 (abfd, contents + irel->r_offset,
+ &len);
+
+ before = get_nds32_elf_blank_total (&blank_t, irel->r_addend, 0);
+ between = get_nds32_elf_blank_total (&blank_t,
+ irel->r_addend + val, 0);
+ if (between == before)
+ goto done_adjust_diff;
+
+ p = contents + irel->r_offset;
+ endp = p + len -1;
+ memset (p, 0x80, len);
+ *(endp) = 0;
+ p = write_uleb128 (p, val - (between - before)) - 1;
+ if (p < endp)
+ *p |= 0x80;
+ }
+done_adjust_diff:
+
+ if (sec == sect)
+ {
+ raddr = irel->r_offset;
+ irel->r_offset -= get_nds32_elf_blank_total (&blank_t2,
+ irel->r_offset, 1);
+
+ if (ELF32_R_TYPE (irel->r_info) == R_NDS32_NONE)
+ continue;
+ if (blank_t2 && blank_t2->next
+ && (blank_t2->offset > raddr
+ || blank_t2->next->offset <= raddr))
+ (*_bfd_error_handler)
+ (_("%B: %s\n"), abfd,
+ "Error: search_nds32_elf_blank reports wrong node");
+
+ /* Mark reloc in deleted portion as NONE.
+ For some relocs like R_NDS32_LABEL that doesn't modify the
+ content in the section. R_NDS32_LABEL doesn't belong to the
+ instruction in the section, so we should preserve it. */
+ if (raddr >= blank_t2->offset
+ && raddr < blank_t2->offset + blank_t2->size
+ && ELF32_R_TYPE (irel->r_info) != R_NDS32_LABEL
+ && ELF32_R_TYPE (irel->r_info) != R_NDS32_RELAX_REGION_BEGIN
+ && ELF32_R_TYPE (irel->r_info) != R_NDS32_RELAX_REGION_END
+ && ELF32_R_TYPE (irel->r_info) != R_NDS32_RELAX_ENTRY
+ && ELF32_R_TYPE (irel->r_info) != R_NDS32_SUBTRAHEND
+ && ELF32_R_TYPE (irel->r_info) != R_NDS32_MINUEND)
+ {
+ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
+ R_NDS32_NONE);
+ continue;
+ }
+ }
+
+ if (ELF32_R_TYPE (irel->r_info) == R_NDS32_NONE
+ || ELF32_R_TYPE (irel->r_info) == R_NDS32_LABEL
+ || ELF32_R_TYPE (irel->r_info) == R_NDS32_RELAX_ENTRY)
+ continue;
+
+ if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info
+ && isym[ELF32_R_SYM (irel->r_info)].st_shndx == sec_shndx
+ && ELF_ST_TYPE (isym[ELF32_R_SYM (irel->r_info)].st_info) == STT_SECTION)
+ {
+ if (irel->r_addend <= sec->size)
+ irel->r_addend -=
+ get_nds32_elf_blank_total (&blank_t, irel->r_addend, 1);
+ }
+ }
+ }
+
+ /* Adjust the local symbols defined in this section. */
+ blank_t = blank_head;
+ for (isymend = isym + symtab_hdr->sh_info; isym < isymend; isym++)
+ {
+ if (isym->st_shndx == sec_shndx)
+ {
+ if (isym->st_value <= sec->size)
+ {
+ bfd_vma ahead;
+ bfd_vma orig_addr = isym->st_value;
+
+ ahead = get_nds32_elf_blank_total (&blank_t, isym->st_value, 1);
+ isym->st_value -= ahead;
+
+ /* Adjust function size. */
+ if (ELF32_ST_TYPE (isym->st_info) == STT_FUNC
+ && isym->st_size > 0)
+ isym->st_size -=
+ get_nds32_elf_blank_total
+ (&blank_t, orig_addr + isym->st_size, 0) - ahead;
+ }
+ }
+ }
+
+ /* Now adjust the global symbols defined in this section. */
+ symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
+ - symtab_hdr->sh_info);
+ sym_hashes = elf_sym_hashes (abfd);
+ end_hashes = sym_hashes + symcount;
+ blank_t = blank_head;
+ for (; sym_hashes < end_hashes; sym_hashes++)
+ {
+ struct elf_link_hash_entry *sym_hash = *sym_hashes;
+
+ if ((sym_hash->root.type == bfd_link_hash_defined
+ || sym_hash->root.type == bfd_link_hash_defweak)
+ && sym_hash->root.u.def.section == sec)
+ {
+ if (sym_hash->root.u.def.value <= sec->size)
+ {
+ bfd_vma ahead;
+ bfd_vma orig_addr = sym_hash->root.u.def.value;
+
+ ahead = get_nds32_elf_blank_total (&blank_t, sym_hash->root.u.def.value, 1);
+ sym_hash->root.u.def.value -= ahead;
+
+ /* Adjust function size. */
+ if (sym_hash->type == STT_FUNC)
+ sym_hash->size -=
+ get_nds32_elf_blank_total
+ (&blank_t, orig_addr + sym_hash->size, 0) - ahead;
+
+ }
+ }
+ }
+
+ contents = elf_section_data (sec)->this_hdr.contents;
+ blank_t = blank_head;
+ while (blank_t->next)
+ {
+ /* Actually delete the bytes. */
+
+ /* If current blank is the last blank overlap with current section,
+ go to finish process. */
+ if (sec->size <= (blank_t->next->offset))
+ break;
+
+ memmove (contents + blank_t->offset - blank_t->total_size,
+ contents + blank_t->offset + blank_t->size,
+ blank_t->next->offset - (blank_t->offset + blank_t->size));
+
+ blank_t = blank_t->next;
+ }
+
+ if (sec->size > (blank_t->offset + blank_t->size))
+ {
+ /* There are remaining code between blank and section boundary.
+ Move the remaining code to appropriate location. */
+ memmove (contents + blank_t->offset - blank_t->total_size,
+ contents + blank_t->offset + blank_t->size,
+ sec->size - (blank_t->offset + blank_t->size));
+ sec->size -= blank_t->total_size + blank_t->size;
+ }
+ else
+ /* This blank is not entirely included in the section,
+ reduce the section size by only part of the blank size. */
+ sec->size -= blank_t->total_size + (sec->size - blank_t->offset);
+
+ while (blank_head)
+ {
+ blank_t = blank_head;
+ blank_head = blank_head->next;
+ remove_nds32_elf_blank (blank_t);
+ }
+
+ return TRUE;
+}
+
+/* Get the contents of a section. */
+
+static int
+nds32_get_section_contents (bfd *abfd, asection *sec, bfd_byte **contents_p)
+{
+ /* Get the section contents. */
+ if (elf_section_data (sec)->this_hdr.contents != NULL)
+ *contents_p = elf_section_data (sec)->this_hdr.contents;
+ else
+ {
+ if (!bfd_malloc_and_get_section (abfd, sec, contents_p))
+ return FALSE;
+ elf_section_data (sec)->this_hdr.contents = *contents_p;
+ }
+
+ return TRUE;
+}
+
+/* Get the contents of the internal symbol of abfd. */
+
+static int
+nds32_get_local_syms (bfd *abfd, asection *sec ATTRIBUTE_UNUSED,
+ Elf_Internal_Sym **isymbuf_p)
+{
+ Elf_Internal_Shdr *symtab_hdr;
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+
+ /* Read this BFD's local symbols if we haven't done so already. */
+ if (*isymbuf_p == NULL && symtab_hdr->sh_info != 0)
+ {
+ *isymbuf_p = (Elf_Internal_Sym *) symtab_hdr->contents;
+ if (*isymbuf_p == NULL)
+ {
+ *isymbuf_p = bfd_elf_get_elf_syms (abfd, symtab_hdr,
+ symtab_hdr->sh_info, 0,
+ NULL, NULL, NULL);
+ if (*isymbuf_p == NULL)
+ return FALSE;
+ }
+ }
+ symtab_hdr->contents = (bfd_byte *) (*isymbuf_p);
+
+ return TRUE;
+}
+
+/* Range of small data. */
+static bfd_vma sdata_range[2][2];
+static bfd_vma const sdata_init_range[2] =
+{ ACCURATE_12BIT_S1, ACCURATE_19BIT };
+
+static int
+nds32_elf_insn_size (bfd *abfd ATTRIBUTE_UNUSED,
+ bfd_byte *contents, bfd_vma addr)
+{
+ unsigned long insn = bfd_getb32 (contents + addr);
+
+ if (insn & 0x80000000)
+ return 2;
+
+ return 4;
+}
+
+/* Set the gp relax range. We have to measure the safe range
+ to do gp relaxation. */
+
+static void
+relax_range_measurement (bfd *abfd)
+{
+ asection *sec_f, *sec_b;
+ /* For upper bound. */
+ bfd_vma maxpgsz = get_elf_backend_data (abfd)->maxpagesize;
+ bfd_vma align;
+ static int decide_relax_range = 0;
+ int i;
+ int range_number = sizeof (sdata_init_range) / sizeof (sdata_init_range[0]);
+
+ if (decide_relax_range)
+ return;
+ decide_relax_range = 1;
+
+ if (sda_rela_sec == NULL)
+ {
+ /* Since there is no data sections, we assume the range is page size. */
+ for (i = 0; i < range_number; i++)
+ {
+ sdata_range[i][0] = sdata_init_range[i] - 0x1000;
+ sdata_range[i][1] = sdata_init_range[i] - 0x1000;
+ }
+ return;
+ }
+
+ /* Get the biggest alignment power after the gp located section. */
+ sec_f = sda_rela_sec->output_section;
+ sec_b = sec_f->next;
+ align = 0;
+ while (sec_b != NULL)
+ {
+ if ((unsigned)(1 << sec_b->alignment_power) > align)
+ align = (1 << sec_b->alignment_power);
+ sec_b = sec_b->next;
+ }
+
+ /* I guess we can not determine the section before
+ gp located section, so we assume the align is max page size. */
+ for (i = 0; i < range_number; i++)
+ {
+ sdata_range[i][1] = sdata_init_range[i] - align;
+ BFD_ASSERT (sdata_range[i][1] <= sdata_init_range[i]);
+ sdata_range[i][0] = sdata_init_range[i] - maxpgsz;
+ BFD_ASSERT (sdata_range[i][0] <= sdata_init_range[i]);
+ }
+}
+
+/* These are macros used to check flags encoded in r_addend.
+ They are only used by nds32_elf_relax_section (). */
+#define GET_SEQ_LEN(addend) ((addend) & 0x000000ff)
+#define IS_1ST_CONVERT(addend) ((addend) & 0x80000000)
+#define IS_OPTIMIZE(addend) ((addend) & 0x40000000)
+#define IS_16BIT_ON(addend) ((addend) & 0x20000000)
+
+/* Relax LONGCALL1 relocation for nds32_elf_relax_section. */
+
+static bfd_boolean
+nds32_elf_relax_longcall1 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel,
+ Elf_Internal_Rela *internal_relocs, int *insn_len,
+ bfd_byte *contents, Elf_Internal_Sym *isymbuf,
+ Elf_Internal_Shdr *symtab_hdr)
+{
+ /* There are 3 variations for LONGCALL1
+ case 4-4-2; 16-bit on, optimize off or optimize for space
+ sethi ta, hi20(symbol) ; LONGCALL1/HI20
+ ori ta, ta, lo12(symbol) ; LO12S0
+ jral5 ta ;
+
+ case 4-4-4; 16-bit off, optimize don't care
+ sethi ta, hi20(symbol) ; LONGCALL1/HI20
+ ori ta, ta, lo12(symbol) ; LO12S0
+ jral ta ;
+
+ case 4-4-4; 16-bit on, optimize for speed
+ sethi ta, hi20(symbol) ; LONGCALL1/HI20
+ ori ta, ta, lo12(symbol) ; LO12S0
+ jral ta ;
+ Check code for -mlong-calls output. */
+
+ /* Get the reloc for the address from which the register is
+ being loaded. This reloc will tell us which function is
+ actually being called. */
+
+ bfd_vma laddr;
+ int seq_len; /* Original length of instruction sequence. */
+ uint32_t insn;
+ Elf_Internal_Rela *hi_irelfn, *lo_irelfn, *irelend;
+ int pic_ext_target = 0;
+ bfd_signed_vma foff;
+ uint16_t insn16;
+
+ irelend = internal_relocs + sec->reloc_count;
+ seq_len = GET_SEQ_LEN (irel->r_addend);
+ laddr = irel->r_offset;
+ *insn_len = seq_len;
+
+ hi_irelfn = find_relocs_at_address_addr (irel, internal_relocs, irelend,
+ R_NDS32_HI20_RELA, laddr);
+ lo_irelfn = find_relocs_at_address_addr (irel, internal_relocs, irelend,
+ R_NDS32_LO12S0_ORI_RELA,
+ laddr + 4);
+
+ if (hi_irelfn == irelend || lo_irelfn == irelend)
+ {
+ (*_bfd_error_handler)
+ ("%B: warning: R_NDS32_LONGCALL1 points to unrecognized"
+ "reloc at 0x%lx.", abfd, (long) irel->r_offset);
+ return FALSE;
+ }
+
+ /* Get the value of the symbol referred to by the reloc. */
+ foff = calculate_offset (abfd, sec, hi_irelfn, isymbuf, symtab_hdr,
+ &pic_ext_target);
+
+ /* This condition only happened when symbol is undefined. */
+ if (pic_ext_target || foff == 0 || foff < -CONSERVATIVE_24BIT_S1
+ || foff >= CONSERVATIVE_24BIT_S1)
+ return FALSE;
+
+ /* Relax to: jal symbol; 25_PCREL */
+ /* 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. */
+
+ /* Replace the long call with a jal. */
+ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (hi_irelfn->r_info),
+ R_NDS32_25_PCREL_RELA);
+ irel->r_addend = hi_irelfn->r_addend;
+
+ /* We don't resolve this here but resolve it in relocate_section. */
+ insn = INSN_JAL;
+ bfd_putb32 (insn, contents + irel->r_offset);
+
+ hi_irelfn->r_info =
+ ELF32_R_INFO (ELF32_R_SYM (hi_irelfn->r_info), R_NDS32_NONE);
+ lo_irelfn->r_info =
+ ELF32_R_INFO (ELF32_R_SYM (lo_irelfn->r_info), R_NDS32_NONE);
+ *insn_len = 4;
+
+ if (seq_len & 0x2)
+ {
+ insn16 = NDS32_NOP16;
+ bfd_putb16 (insn16, contents + irel->r_offset + *insn_len);
+ lo_irelfn->r_info =
+ ELF32_R_INFO (ELF32_R_SYM (lo_irelfn->r_info), R_NDS32_INSN16);
+ lo_irelfn->r_addend = R_NDS32_INSN16_CONVERT_FLAG;
+ *insn_len += 2;
+ }
+ return TRUE;
+}
+
+#define CONVERT_CONDITION_CALL(insn) (((insn) & 0xffff0000) ^ 0x90000)
+/* Relax LONGCALL2 relocation for nds32_elf_relax_section. */
+
+static bfd_boolean
+nds32_elf_relax_longcall2 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel,
+ Elf_Internal_Rela *internal_relocs, int *insn_len,
+ bfd_byte *contents, Elf_Internal_Sym *isymbuf,
+ Elf_Internal_Shdr *symtab_hdr)
+{
+ /* bltz rt, .L1 ; LONGCALL2
+ jal symbol ; 25_PCREL
+ .L1: */
+
+ /* Get the reloc for the address from which the register is
+ being loaded. This reloc will tell us which function is
+ actually being called. */
+
+ bfd_vma laddr;
+ uint32_t insn;
+ Elf_Internal_Rela *i1_irelfn, *cond_irelfn, *irelend;
+ int pic_ext_target = 0;
+ bfd_signed_vma foff;
+
+ irelend = internal_relocs + sec->reloc_count;
+ laddr = irel->r_offset;
+ i1_irelfn =
+ find_relocs_at_address_addr (irel, internal_relocs, irelend,
+ R_NDS32_25_PCREL_RELA, laddr + 4);
+
+ if (i1_irelfn == irelend)
+ {
+ (*_bfd_error_handler)
+ ("%B: warning: R_NDS32_LONGCALL2 points to unrecognized"
+ "reloc at 0x%lx.", abfd, (long) irel->r_offset);
+ return FALSE;
+ }
+
+ insn = bfd_getb32 (contents + laddr);
+
+ /* Get the value of the symbol referred to by the reloc. */
+ foff = calculate_offset (abfd, sec, i1_irelfn, isymbuf, symtab_hdr,
+ &pic_ext_target);
+
+ if (foff == 0 || foff < -CONSERVATIVE_16BIT_S1
+ || foff >= CONSERVATIVE_16BIT_S1)
+ return FALSE;
+
+ /* Relax to bgezal rt, label ; 17_PCREL
+ or bltzal rt, label ; 17_PCREL */
+
+ /* Convert to complimentary conditional call. */
+ insn = CONVERT_CONDITION_CALL (insn);
+
+ /* 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. */
+
+ /* Clean unnessary relocations. */
+ i1_irelfn->r_info =
+ ELF32_R_INFO (ELF32_R_SYM (i1_irelfn->r_info), R_NDS32_NONE);
+ cond_irelfn =
+ find_relocs_at_address_addr (irel, internal_relocs, irelend,
+ R_NDS32_17_PCREL_RELA, laddr);
+ if (cond_irelfn != irelend)
+ cond_irelfn->r_info =
+ ELF32_R_INFO (ELF32_R_SYM (cond_irelfn->r_info), R_NDS32_NONE);
+
+ /* Replace the long call with a bgezal. */
+ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (i1_irelfn->r_info),
+ R_NDS32_17_PCREL_RELA);
+ irel->r_addend = i1_irelfn->r_addend;
+
+ bfd_putb32 (insn, contents + irel->r_offset);
+
+ *insn_len = 4;
+ return TRUE;
+}
+
+/* Relax LONGCALL3 relocation for nds32_elf_relax_section. */
+
+static bfd_boolean
+nds32_elf_relax_longcall3 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel,
+ Elf_Internal_Rela *internal_relocs, int *insn_len,
+ bfd_byte *contents, Elf_Internal_Sym *isymbuf,
+ Elf_Internal_Shdr *symtab_hdr)
+{
+ /* There are 3 variations for LONGCALL3
+ case 4-4-4-2; 16-bit on, optimize off or optimize for space
+ bltz rt, $1 ; LONGCALL3
+ sethi ta, hi20(symbol) ; HI20
+ ori ta, ta, lo12(symbol) ; LO12S0
+ jral5 ta ;
+ $1
+
+ case 4-4-4-4; 16-bit off, optimize don't care
+ bltz rt, $1 ; LONGCALL3
+ sethi ta, hi20(symbol) ; HI20
+ ori ta, ta, lo12(symbol) ; LO12S0
+ jral ta ;
+ $1
+
+ case 4-4-4-4; 16-bit on, optimize for speed
+ bltz rt, $1 ; LONGCALL3
+ sethi ta, hi20(symbol) ; HI20
+ ori ta, ta, lo12(symbol) ; LO12S0
+ jral ta ;
+ $1 */
+
+ /* Get the reloc for the address from which the register is
+ being loaded. This reloc will tell us which function is
+ actually being called. */
+
+ bfd_vma laddr;
+ int seq_len; /* Original length of instruction sequence. */
+ uint32_t insn;
+ Elf_Internal_Rela *hi_irelfn, *lo_irelfn, *cond_irelfn, *irelend;
+ int pic_ext_target = 0;
+ bfd_signed_vma foff;
+ uint16_t insn16;
+
+ irelend = internal_relocs + sec->reloc_count;
+ seq_len = GET_SEQ_LEN (irel->r_addend);
+ laddr = irel->r_offset;
+ *insn_len = seq_len;
+
+ hi_irelfn =
+ find_relocs_at_address_addr (irel, internal_relocs, irelend,
+ R_NDS32_HI20_RELA, laddr + 4);
+ lo_irelfn =
+ find_relocs_at_address_addr (irel, internal_relocs, irelend,
+ R_NDS32_LO12S0_ORI_RELA, laddr + 8);
+
+ if (hi_irelfn == irelend || lo_irelfn == irelend)
+ {
+ (*_bfd_error_handler)
+ ("%B: warning: R_NDS32_LONGCALL3 points to unrecognized"
+ "reloc at 0x%lx.", abfd, (long) irel->r_offset);
+ return FALSE;
+ }
+
+ /* Get the value of the symbol referred to by the reloc. */
+ foff = calculate_offset (abfd, sec, hi_irelfn, isymbuf, symtab_hdr,
+ &pic_ext_target);
+
+ if (pic_ext_target || foff == 0 || foff < -CONSERVATIVE_24BIT_S1
+ || foff >= CONSERVATIVE_24BIT_S1)
+ return FALSE;
+
+ insn = bfd_getb32 (contents + laddr);
+ if (foff >= -CONSERVATIVE_16BIT_S1 && foff < CONSERVATIVE_16BIT_S1)
+ {
+ /* Relax to bgezal rt, label ; 17_PCREL
+ or bltzal rt, label ; 17_PCREL */
+
+ /* Convert to complimentary conditional call. */
+ insn = CONVERT_CONDITION_CALL (insn);
+ bfd_putb32 (insn, contents + irel->r_offset);
+
+ *insn_len = 4;
+ irel->r_info =
+ ELF32_R_INFO (ELF32_R_SYM (hi_irelfn->r_info), R_NDS32_NONE);
+ hi_irelfn->r_info =
+ ELF32_R_INFO (ELF32_R_SYM (hi_irelfn->r_info), R_NDS32_NONE);
+ lo_irelfn->r_info =
+ ELF32_R_INFO (ELF32_R_SYM (lo_irelfn->r_info), R_NDS32_NONE);
+
+ cond_irelfn =
+ find_relocs_at_address_addr (irel, internal_relocs, irelend,
+ R_NDS32_17_PCREL_RELA, laddr);
+ if (cond_irelfn != irelend)
+ {
+ cond_irelfn->r_info = ELF32_R_INFO (ELF32_R_SYM (hi_irelfn->r_info),
+ R_NDS32_17_PCREL_RELA);
+ cond_irelfn->r_addend = hi_irelfn->r_addend;
+ }
+
+ if (seq_len & 0x2)
+ {
+ insn16 = NDS32_NOP16;
+ bfd_putb16 (insn16, contents + irel->r_offset + *insn_len);
+ hi_irelfn->r_info = ELF32_R_INFO (ELF32_R_SYM (hi_irelfn->r_info),
+ R_NDS32_INSN16);
+ hi_irelfn->r_addend = R_NDS32_INSN16_CONVERT_FLAG;
+ insn_len += 2;
+ }
+ }
+ else if (foff >= -CONSERVATIVE_24BIT_S1 && foff < CONSERVATIVE_24BIT_S1)
+ {
+ /* Relax to the following instruction sequence
+ bltz rt, $1 ; LONGCALL2
+ jal symbol ; 25_PCREL
+ $1 */
+ *insn_len = 8;
+ insn = INSN_JAL;
+ bfd_putb32 (insn, contents + hi_irelfn->r_offset);
+
+ hi_irelfn->r_info = ELF32_R_INFO (ELF32_R_SYM (hi_irelfn->r_info),
+ R_NDS32_25_PCREL_RELA);
+ irel->r_info =
+ ELF32_R_INFO (ELF32_R_SYM (irel->r_info), R_NDS32_LONGCALL2);
+
+ lo_irelfn->r_info =
+ ELF32_R_INFO (ELF32_R_SYM (lo_irelfn->r_info), R_NDS32_NONE);
+
+ if (seq_len & 0x2)
+ {
+ insn16 = NDS32_NOP16;
+ bfd_putb16 (insn16, contents + irel->r_offset + *insn_len);
+ lo_irelfn->r_info =
+ ELF32_R_INFO (ELF32_R_SYM (lo_irelfn->r_info), R_NDS32_INSN16);
+ lo_irelfn->r_addend = R_NDS32_INSN16_CONVERT_FLAG;
+ insn_len += 2;
+ }
+ }
+ return TRUE;
+}
+
+/* Relax LONGJUMP1 relocation for nds32_elf_relax_section. */
+
+static bfd_boolean
+nds32_elf_relax_longjump1 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel,
+ Elf_Internal_Rela *internal_relocs, int *insn_len,
+ bfd_byte *contents, Elf_Internal_Sym *isymbuf,
+ Elf_Internal_Shdr *symtab_hdr)
+{
+ /* There are 3 variations for LONGJUMP1
+ case 4-4-2; 16-bit bit on, optimize off or optimize for space
+ sethi ta, hi20(symbol) ; LONGJUMP1/HI20
+ ori ta, ta, lo12(symbol) ; LO12S0
+ jr5 ta ;
+
+ case 4-4-4; 16-bit off, optimize don't care
+ sethi ta, hi20(symbol) ; LONGJUMP1/HI20
+ ori ta, ta, lo12(symbol) ; LO12S0
+ jr ta ;
+
+ case 4-4-4; 16-bit on, optimize for speed
+ sethi ta, hi20(symbol) ; LONGJUMP1/HI20
+ ori ta, ta, lo12(symbol) ; LO12S0
+ jr ta ; */
+
+ /* Get the reloc for the address from which the register is
+ being loaded. This reloc will tell us which function is
+ actually being called. */
+
+ bfd_vma laddr;
+ int seq_len; /* Original length of instruction sequence. */
+ int insn16_on; /* 16-bit on/off. */
+ uint32_t insn;
+ Elf_Internal_Rela *hi_irelfn, *lo_irelfn, *irelend;
+ int pic_ext_target = 0;
+ bfd_signed_vma foff;
+ uint16_t insn16;
+ unsigned long reloc;
+
+ irelend = internal_relocs + sec->reloc_count;
+ seq_len = GET_SEQ_LEN (irel->r_addend);
+ laddr = irel->r_offset;
+ *insn_len = seq_len;
+ insn16_on = IS_16BIT_ON (irel->r_addend);
+
+ hi_irelfn =
+ find_relocs_at_address_addr (irel, internal_relocs, irelend,
+ R_NDS32_HI20_RELA, laddr);
+ lo_irelfn =
+ find_relocs_at_address_addr (irel, internal_relocs, irelend,
+ R_NDS32_LO12S0_ORI_RELA, laddr + 4);
+ if (hi_irelfn == irelend || lo_irelfn == irelend)
+ {
+ (*_bfd_error_handler)
+ ("%B: warning: R_NDS32_LONGJUMP1 points to unrecognized"
+ "reloc at 0x%lx.", abfd, (long) irel->r_offset);
+ return FALSE;
+ }
+
+ /* Get the value of the symbol referred to by the reloc. */
+ foff = calculate_offset (abfd, sec, hi_irelfn, isymbuf, symtab_hdr,
+ &pic_ext_target);
+
+ if (pic_ext_target || foff == 0 || foff >= CONSERVATIVE_24BIT_S1
+ || foff < -CONSERVATIVE_24BIT_S1)
+ return FALSE;
+
+ if (insn16_on && foff >= -ACCURATE_8BIT_S1
+ && foff < ACCURATE_8BIT_S1 && (seq_len & 0x2))
+ {
+ /* j8 label */
+ /* 16-bit on, but not optimized for speed. */
+ reloc = R_NDS32_9_PCREL_RELA;
+ insn16 = INSN_J8;
+ bfd_putb16 (insn16, contents + irel->r_offset);
+ *insn_len = 2;
+ irel->r_info =
+ ELF32_R_INFO (ELF32_R_SYM (irel->r_info), R_NDS32_NONE);
+ }
+ else
+ {
+ /* j label */
+ reloc = R_NDS32_25_PCREL_RELA;
+ insn = INSN_J;
+ bfd_putb32 (insn, contents + irel->r_offset);
+ *insn_len = 4;
+ irel->r_info =
+ ELF32_R_INFO (ELF32_R_SYM (irel->r_info), R_NDS32_INSN16);
+ irel->r_addend = 0;
+ }
+
+ hi_irelfn->r_info =
+ ELF32_R_INFO (ELF32_R_SYM (hi_irelfn->r_info), reloc);
+ lo_irelfn->r_info =
+ ELF32_R_INFO (ELF32_R_SYM (lo_irelfn->r_info), R_NDS32_NONE);
+
+ if ((seq_len & 0x2) && ((*insn_len & 2) == 0))
+ {
+ insn16 = NDS32_NOP16;
+ bfd_putb16 (insn16, contents + irel->r_offset + *insn_len);
+ lo_irelfn->r_info =
+ ELF32_R_INFO (ELF32_R_SYM (lo_irelfn->r_info),
+ R_NDS32_INSN16);
+ lo_irelfn->r_addend = R_NDS32_INSN16_CONVERT_FLAG;
+ *insn_len += 2;
+ }
+ return TRUE;
+}
+
+/* Revert condition branch. This function does not check if the input
+ instruction is condition branch or not. */
+
+static void
+nds32_elf_convert_branch (uint16_t insn16, uint32_t insn,
+ uint16_t *re_insn16, uint32_t *re_insn)
+{
+ uint32_t comp_insn = 0;
+ uint16_t comp_insn16 = 0;
+
+ if (insn)
+ {
+ if (N32_OP6 (insn) == N32_OP6_BR1)
+ {
+ /* beqs label. */
+ comp_insn = (insn ^ 0x4000) & 0xffffc000;
+ if (N32_IS_RT3 (insn) && N32_RA5 (insn) == REG_R5)
+ {
+ /* Insn can be contracted to 16-bit implied r5. */
+ comp_insn16 =
+ (comp_insn & 0x4000) ? INSN_BNES38 : INSN_BEQS38;
+ comp_insn16 |= (N32_RT5 (insn) & 0x7) << 8;
+ }
+ }
+ else if (N32_OP6 (insn) == N32_OP6_BR3)
+ {
+ /* bnec $ta, imm11, label. */
+ comp_insn = (insn ^ 0x80000) & 0xffffff00;
+ }
+ else
+ {
+ comp_insn = (insn ^ 0x10000) & 0xffffc000;
+ if (N32_BR2_SUB (insn) == N32_BR2_BEQZ
+ || N32_BR2_SUB (insn) == N32_BR2_BNEZ)
+ {
+ if (N32_IS_RT3 (insn))
+ {
+ /* Insn can be contracted to 16-bit. */
+ comp_insn16 =
+ (comp_insn & 0x10000) ? INSN_BNEZ38 : INSN_BEQZ38;
+ comp_insn16 |= (N32_RT5 (insn) & 0x7) << 8;
+ }
+ else if (N32_RT5 (insn) == REG_R15)
+ {
+ /* Insn can be contracted to 16-bit. */
+ comp_insn16 =
+ (comp_insn & 0x10000) ? INSN_BNES38 : INSN_BEQS38;
+ }
+ }
+ }
+ }
+ else
+ {
+ switch ((insn16 & 0xf000) >> 12)
+ {
+ case 0xc:
+ /* beqz38 or bnez38 */
+ comp_insn16 = (insn16 ^ 0x0800) & 0xff00;
+ comp_insn = (comp_insn16 & 0x0800) ? INSN_BNEZ : INSN_BEQZ;
+ comp_insn |= ((comp_insn16 & 0x0700) >> 8) << 20;
+ break;
+
+ case 0xd:
+ /* beqs38 or bnes38 */
+ comp_insn16 = (insn16 ^ 0x0800) & 0xff00;
+ comp_insn = (comp_insn16 & 0x0800) ? INSN_BNE : INSN_BEQ;
+ comp_insn |= (((comp_insn16 & 0x0700) >> 8) << 20)
+ | (REG_R5 << 15);
+ break;
+
+ case 0xe:
+ /* beqzS8 or bnezS8 */
+ comp_insn16 = (insn16 ^ 0x0100) & 0xff00;
+ comp_insn = (comp_insn16 & 0x0100) ? INSN_BNEZ : INSN_BEQZ;
+ comp_insn |= REG_R15 << 20;
+ break;
+
+ default:
+ break;
+ }
+ }
+ if (comp_insn && re_insn)
+ *re_insn = comp_insn;
+ if (comp_insn16 && re_insn16)
+ *re_insn16 = comp_insn16;
+}
+
+/* Relax LONGJUMP2 relocation for nds32_elf_relax_section. */
+
+static bfd_boolean
+nds32_elf_relax_longjump2 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel,
+ Elf_Internal_Rela *internal_relocs, int *insn_len,
+ bfd_byte *contents, Elf_Internal_Sym *isymbuf,
+ Elf_Internal_Shdr *symtab_hdr)
+{
+ /* There are 3 variations for LONGJUMP2
+ case 2-4; 1st insn convertible, 16-bit on,
+ optimize off or optimize for space
+ bnes38 rt, ra, $1 ; LONGJUMP2
+ j label ; 25_PCREL
+ $1:
+
+ case 4-4; 1st insn not convertible
+ bne rt, ra, $1 ; LONGJUMP2
+ j label ; 25_PCREL
+ $1:
+
+ case 4-4; 1st insn convertible, 16-bit on, optimize for speed
+ bne rt, ra, $1 ; LONGJUMP2
+ j label ; 25_PCREL
+ $1: */
+
+ /* Get the reloc for the address from which the register is
+ being loaded. This reloc will tell us which function is
+ actually being called. */
+
+ bfd_vma laddr;
+ int seq_len; /* Original length of instruction sequence. */
+ Elf_Internal_Rela *i2_irelfn, *cond_irelfn, *irelend;
+ int pic_ext_target = 0, first_size;
+ unsigned int i;
+ bfd_signed_vma foff;
+ uint32_t insn, re_insn = 0;
+ uint16_t insn16, re_insn16 = 0;
+ unsigned long reloc, cond_reloc;
+
+ enum elf_nds32_reloc_type checked_types[] =
+ { R_NDS32_15_PCREL_RELA, R_NDS32_9_PCREL_RELA };
+
+ irelend = internal_relocs + sec->reloc_count;
+ seq_len = GET_SEQ_LEN (irel->r_addend);
+ laddr = irel->r_offset;
+ *insn_len = seq_len;
+ first_size = (seq_len == 6) ? 2 : 4;
+
+ i2_irelfn =
+ find_relocs_at_address_addr (irel, internal_relocs,
+ irelend, R_NDS32_25_PCREL_RELA,
+ laddr + first_size);
+
+ for (i = 0; i < sizeof (checked_types) / sizeof(checked_types[0]); i++)
+ {
+ cond_irelfn =
+ find_relocs_at_address_addr (irel, internal_relocs, irelend,
+ checked_types[i], laddr);
+ if (cond_irelfn != irelend)
+ break;
+ }
+
+ if (i2_irelfn == irelend || cond_irelfn == irelend)
+ {
+ (*_bfd_error_handler)
+ ("%B: warning: R_NDS32_LONGJUMP2 points to unrecognized"
+ "reloc at 0x%lx.", abfd, (long) irel->r_offset);
+ return FALSE;
+ }
+
+ /* Get the value of the symbol referred to by the reloc. */
+ foff =
+ calculate_offset (abfd, sec, i2_irelfn, isymbuf, symtab_hdr,
+ &pic_ext_target);
+ if (pic_ext_target || foff == 0 || foff < -CONSERVATIVE_16BIT_S1
+ || foff >= CONSERVATIVE_16BIT_S1)
+ return FALSE;
+
+ /* Get the all corresponding instructions. */
+ if (first_size == 4)
+ {
+ insn = bfd_getb32 (contents + laddr);
+ nds32_elf_convert_branch (0, insn, &re_insn16, &re_insn);
+ }
+ else
+ {
+ insn16 = bfd_getb16 (contents + laddr);
+ nds32_elf_convert_branch (insn16, 0, &re_insn16, &re_insn);
+ }
+
+ if (re_insn16 && foff >= -(ACCURATE_8BIT_S1 - first_size)
+ && foff < ACCURATE_8BIT_S1 - first_size)
+ {
+ if (first_size == 4)
+ {
+ /* Don't convert it to 16-bit now, keep this as relaxable for
+ ``label reloc; INSN16''. */
+
+ /* Save comp_insn32 to buffer. */
+ bfd_putb32 (re_insn, contents + irel->r_offset);
+ *insn_len = 4;
+ reloc = (N32_OP6 (re_insn) == N32_OP6_BR1) ?
+ R_NDS32_15_PCREL_RELA : R_NDS32_17_PCREL_RELA;
+ cond_reloc = R_NDS32_INSN16;
+ }
+ else
+ {
+ bfd_putb16 (re_insn16, contents + irel->r_offset);
+ *insn_len = 2;
+ reloc = R_NDS32_9_PCREL_RELA;
+ cond_reloc = R_NDS32_NONE;
+ }
+ }
+ else if (N32_OP6 (re_insn) == N32_OP6_BR1
+ && (foff >= -(ACCURATE_14BIT_S1 - first_size)
+ && foff < ACCURATE_14BIT_S1 - first_size))
+ {
+ /* beqs label ; 15_PCREL */
+ bfd_putb32 (re_insn, contents + irel->r_offset);
+ *insn_len = 4;
+ reloc = R_NDS32_15_PCREL_RELA;
+ cond_reloc = R_NDS32_NONE;
+ }
+ else if (N32_OP6 (re_insn) == N32_OP6_BR2
+ && foff >= -CONSERVATIVE_16BIT_S1
+ && foff < CONSERVATIVE_16BIT_S1)
+ {
+ /* beqz label ; 17_PCREL */
+ bfd_putb32 (re_insn, contents + irel->r_offset);
+ *insn_len = 4;
+ reloc = R_NDS32_17_PCREL_RELA;
+ cond_reloc = R_NDS32_NONE;
+ }
+ else
+ return FALSE;
+
+ /* Set all relocations. */
+ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (i2_irelfn->r_info), reloc);
+ irel->r_addend = i2_irelfn->r_addend;
+
+ cond_irelfn->r_info = ELF32_R_INFO (ELF32_R_SYM (cond_irelfn->r_info),
+ cond_reloc);
+ cond_irelfn->r_addend = 0;
+
+ if ((seq_len ^ *insn_len ) & 0x2)
+ {
+ insn16 = NDS32_NOP16;
+ bfd_putb16 (insn16, contents + irel->r_offset + 4);
+ i2_irelfn->r_offset = 4;
+ i2_irelfn->r_info = ELF32_R_INFO (ELF32_R_SYM (i2_irelfn->r_info),
+ R_NDS32_INSN16);
+ i2_irelfn->r_addend = R_NDS32_INSN16_CONVERT_FLAG;
+ *insn_len += 2;
+ }
+ else
+ i2_irelfn->r_info = ELF32_R_INFO (ELF32_R_SYM (i2_irelfn->r_info),
+ R_NDS32_NONE);
+ return TRUE;
+}
+
+/* Relax LONGJUMP3 relocation for nds32_elf_relax_section. */
+
+static bfd_boolean
+nds32_elf_relax_longjump3 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel,
+ Elf_Internal_Rela *internal_relocs, int *insn_len,
+ bfd_byte *contents, Elf_Internal_Sym *isymbuf,
+ Elf_Internal_Shdr *symtab_hdr)
+{
+ /* There are 5 variations for LONGJUMP3
+ case 1: 2-4-4-2; 1st insn convertible, 16-bit on,
+ optimize off or optimize for space
+ bnes38 rt, ra, $1 ; LONGJUMP3
+ sethi ta, hi20(symbol) ; HI20
+ ori ta, ta, lo12(symbol) ; LO12S0
+ jr5 ta ;
+ $1: ;
+
+ case 2: 2-4-4-2; 1st insn convertible, 16-bit on, optimize for speed
+ bnes38 rt, ra, $1 ; LONGJUMP3
+ sethi ta, hi20(symbol) ; HI20
+ ori ta, ta, lo12(symbol) ; LO12S0
+ jr5 ta ;
+ $1: ; LABEL
+
+ case 3: 4-4-4-2; 1st insn not convertible, 16-bit on,
+ optimize off or optimize for space
+ bne rt, ra, $1 ; LONGJUMP3
+ sethi ta, hi20(symbol) ; HI20
+ ori ta, ta, lo12(symbol) ; LO12S0
+ jr5 ta ;
+ $1: ;
+
+ case 4: 4-4-4-4; 1st insn don't care, 16-bit off, optimize don't care
+ 16-bit off if no INSN16
+ bne rt, ra, $1 ; LONGJUMP3
+ sethi ta, hi20(symbol) ; HI20
+ ori ta, ta, lo12(symbol) ; LO12S0
+ jr ta ;
+ $1: ;
+
+ case 5: 4-4-4-4; 1st insn not convertible, 16-bit on, optimize for speed
+ 16-bit off if no INSN16
+ bne rt, ra, $1 ; LONGJUMP3
+ sethi ta, hi20(symbol) ; HI20
+ ori ta, ta, lo12(symbol) ; LO12S0
+ jr ta ;
+ $1: ; LABEL */
+
+ /* Get the reloc for the address from which the register is
+ being loaded. This reloc will tell us which function is
+ actually being called. */
+ enum elf_nds32_reloc_type checked_types[] =
+ { R_NDS32_15_PCREL_RELA, R_NDS32_9_PCREL_RELA };
+
+ int reloc_off = 0, cond_removed = 0, convertible;
+ bfd_vma laddr;
+ int seq_len; /* Original length of instruction sequence. */
+ Elf_Internal_Rela *hi_irelfn, *lo_irelfn, *cond_irelfn, *irelend;
+ int pic_ext_target = 0, first_size;
+ unsigned int i;
+ bfd_signed_vma foff;
+ uint32_t insn, re_insn = 0;
+ uint16_t insn16, re_insn16 = 0;
+ unsigned long reloc, cond_reloc;
+
+ irelend = internal_relocs + sec->reloc_count;
+ seq_len = GET_SEQ_LEN (irel->r_addend);
+ laddr = irel->r_offset;
+ *insn_len = seq_len;
+
+ convertible = IS_1ST_CONVERT (irel->r_addend);
+
+ if (convertible)
+ first_size = 2;
+ else
+ first_size = 4;
+
+ /* Get all needed relocations. */
+ hi_irelfn =
+ find_relocs_at_address_addr (irel, internal_relocs, irelend,
+ R_NDS32_HI20_RELA, laddr + first_size);
+ lo_irelfn =
+ find_relocs_at_address_addr (irel, internal_relocs, irelend,
+ R_NDS32_LO12S0_ORI_RELA,
+ laddr + first_size + 4);
+
+ for (i = 0; i < sizeof (checked_types) / sizeof (checked_types[0]); i++)
+ {
+ cond_irelfn =
+ find_relocs_at_address_addr (irel, internal_relocs, irelend,
+ checked_types[i], laddr);
+ if (cond_irelfn != irelend)
+ break;
+ }
+
+ if (hi_irelfn == irelend || lo_irelfn == irelend || cond_irelfn == irelend)
+ {
+ (*_bfd_error_handler)
+ ("%B: warning: R_NDS32_LONGJUMP3 points to unrecognized"
+ "reloc at 0x%lx.", abfd, (long) irel->r_offset);
+ return FALSE;
+ }
+
+ /* Get the value of the symbol referred to by the reloc. */
+ foff = calculate_offset (abfd, sec, hi_irelfn, isymbuf, symtab_hdr,
+ &pic_ext_target);
+
+ if (pic_ext_target || foff == 0 || foff < -CONSERVATIVE_24BIT_S1
+ || foff >= CONSERVATIVE_24BIT_S1)
+ return FALSE;
+
+ /* Get the all corresponding instructions. */
+ if (first_size == 4)
+ {
+ insn = bfd_getb32 (contents + laddr);
+ nds32_elf_convert_branch (0, insn, &re_insn16, &re_insn);
+ }
+ else
+ {
+ insn16 = bfd_getb16 (contents + laddr);
+ nds32_elf_convert_branch (insn16, 0, &re_insn16, &re_insn);
+ }
+
+ /* 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 (re_insn16 && foff >= -ACCURATE_8BIT_S1 - first_size
+ && foff < ACCURATE_8BIT_S1 - first_size)
+ {
+ if (!(seq_len & 0x2))
+ {
+ /* Don't convert it to 16-bit now, keep this as relaxable
+ for ``label reloc; INSN1a''6. */
+ /* Save comp_insn32 to buffer. */
+ bfd_putb32 (re_insn, contents + irel->r_offset);
+ *insn_len = 4;
+ reloc = (N32_OP6 (re_insn) == N32_OP6_BR1) ?
+ R_NDS32_15_PCREL_RELA : R_NDS32_17_PCREL_RELA;
+ cond_reloc = R_NDS32_INSN16;
+ }
+ else
+ {
+ /* Not optimize for speed; convert sequence to 16-bit. */
+ /* Save comp_insn16 to buffer. */
+ bfd_putb16 (re_insn16, contents + irel->r_offset);
+ *insn_len = 2;
+ reloc = R_NDS32_9_PCREL_RELA;
+ cond_reloc = R_NDS32_NONE;
+ }
+ cond_removed = 1;
+ }
+ else if (N32_OP6 (re_insn) == N32_OP6_BR1
+ && (foff >= -(ACCURATE_14BIT_S1 - first_size)
+ && foff < ACCURATE_14BIT_S1 - first_size))
+ {
+ /* beqs label ; 15_PCREL */
+ bfd_putb32 (re_insn, contents + irel->r_offset);
+ *insn_len = 4;
+ reloc = R_NDS32_15_PCREL_RELA;
+ cond_reloc = R_NDS32_NONE;
+ cond_removed = 1;
+ }
+ else if (N32_OP6 (re_insn) == N32_OP6_BR2
+ && foff >= -CONSERVATIVE_16BIT_S1
+ && foff < CONSERVATIVE_16BIT_S1)
+ {
+ /* beqz label ; 17_PCREL */
+ bfd_putb32 (re_insn, contents + irel->r_offset);
+ *insn_len = 4;
+ reloc = R_NDS32_17_PCREL_RELA;
+ cond_reloc = R_NDS32_NONE;
+ cond_removed = 1;
+ }
+ else if (foff >= -CONSERVATIVE_24BIT_S1 - reloc_off
+ && foff < CONSERVATIVE_24BIT_S1 - reloc_off)
+ {
+ /* Relax to one of the following 3 variations
+
+ case 2-4; 1st insn convertible, 16-bit on, optimize off or optimize
+ for space
+ bnes38 rt, $1 ; LONGJUMP2
+ j label ; 25_PCREL
+ $1
+
+ case 4-4; 1st insn not convertible, others don't care
+ bne rt, ra, $1 ; LONGJUMP2
+ j label ; 25_PCREL
+ $1
+
+ case 4-4; 1st insn convertible, 16-bit on, optimize for speed
+ bne rt, ra, $1 ; LONGJUMP2
+ j label ; 25_PCREL
+ $1 */
+
+ /* Offset for first instruction. */
+
+ /* Use j label as second instruction. */
+ *insn_len = 4 + first_size;
+ insn = INSN_J;
+ bfd_putb32 (insn, contents + hi_irelfn->r_offset);
+ reloc = R_NDS32_LONGJUMP2;
+ cond_reloc = R_NDS32_25_PLTREL;
+ }
+ else
+ return FALSE;
+
+ if (cond_removed == 1)
+ {
+ /* Set all relocations. */
+ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (hi_irelfn->r_info), reloc);
+ irel->r_addend = hi_irelfn->r_addend;
+
+ cond_irelfn->r_info = ELF32_R_INFO (ELF32_R_SYM (cond_irelfn->r_info),
+ cond_reloc);
+ cond_irelfn->r_addend = 0;
+ hi_irelfn->r_info = ELF32_R_INFO (ELF32_R_SYM (hi_irelfn->r_info),
+ R_NDS32_NONE);
+ }
+ else
+ {
+ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info), reloc);
+ irel->r_addend = irel->r_addend;
+ hi_irelfn->r_info = ELF32_R_INFO (ELF32_R_SYM (hi_irelfn->r_info),
+ cond_reloc);
+ }
+
+ if ((seq_len ^ *insn_len ) & 0x2)
+ {
+ insn16 = NDS32_NOP16;
+ bfd_putb16 (insn16, contents + irel->r_offset + *insn_len);
+ lo_irelfn->r_offset = *insn_len;
+ lo_irelfn->r_info = ELF32_R_INFO (ELF32_R_SYM (lo_irelfn->r_info),
+ R_NDS32_INSN16);
+ lo_irelfn->r_addend = R_NDS32_INSN16_CONVERT_FLAG;
+ *insn_len += 2;
+ }
+ else
+ lo_irelfn->r_info = ELF32_R_INFO (ELF32_R_SYM (lo_irelfn->r_info),
+ R_NDS32_NONE);
+ return TRUE;
+}
+
+/* Relax LONGCALL4 relocation for nds32_elf_relax_section. */
+
+static bfd_boolean
+nds32_elf_relax_longcall4 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel,
+ Elf_Internal_Rela *internal_relocs, int *insn_len,
+ bfd_byte *contents, Elf_Internal_Sym *isymbuf,
+ Elf_Internal_Shdr *symtab_hdr)
+{
+ /* The pattern for LONGCALL4. Support for function cse.
+ sethi ta, hi20(symbol) ; LONGCALL4/HI20
+ ori ta, ta, lo12(symbol) ; LO12S0_ORI/PTR
+ jral ta ; PTR_RES/EMPTY/INSN16 */
+
+ bfd_vma laddr;
+ uint32_t insn;
+ Elf_Internal_Rela *hi_irel, *ptr_irel, *insn_irel, *em_irel, *call_irel;
+ Elf_Internal_Rela *irelend;
+ int pic_ext_target = 0;
+ bfd_signed_vma foff;
+
+ irelend = internal_relocs + sec->reloc_count;
+ laddr = irel->r_offset;
+
+ /* Get the reloc for the address from which the register is
+ being loaded. This reloc will tell us which function is
+ actually being called. */
+ hi_irel = find_relocs_at_address_addr (irel, internal_relocs, irelend,
+ R_NDS32_HI20_RELA, laddr);
+
+ if (hi_irel == irelend)
+ {
+ (*_bfd_error_handler)
+ ("%B: warning: R_NDS32_LONGCALL4 points to unrecognized"
+ "reloc at 0x%lx.", abfd, (long) irel->r_offset);
+ return FALSE;
+ }
+
+ /* Get the value of the symbol referred to by the reloc. */
+ foff = calculate_offset (abfd, sec, hi_irel, isymbuf, symtab_hdr,
+ &pic_ext_target);
+
+ /* This condition only happened when symbol is undefined. */
+ if (pic_ext_target || foff == 0 || foff < -CONSERVATIVE_24BIT_S1
+ || foff >= CONSERVATIVE_24BIT_S1)
+ return FALSE;
+
+ /* Relax to: jal symbol; 25_PCREL */
+ /* 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. */
+
+ ptr_irel = find_relocs_at_address_addr (irel, internal_relocs, irelend,
+ R_NDS32_PTR_RESOLVED, irel->r_addend);
+ em_irel = find_relocs_at_address_addr (irel, internal_relocs, irelend,
+ R_NDS32_EMPTY, irel->r_addend);
+
+ if (ptr_irel == irelend || em_irel == irelend)
+ {
+ (*_bfd_error_handler)
+ ("%B: warning: R_NDS32_LONGCALL4 points to unrecognized"
+ "reloc at 0x%lx.", abfd, (long) irel->r_offset);
+ return FALSE;
+ }
+ /* Check these is enough space to insert jal in R_NDS32_EMPTY. */
+ insn = bfd_getb32 (contents + irel->r_addend);
+ if (insn & 0x80000000)
+ return FALSE;
+
+ /* Replace the long call with a jal. */
+ em_irel->r_info = ELF32_R_INFO (ELF32_R_SYM (em_irel->r_info),
+ R_NDS32_25_PCREL_RELA);
+ ptr_irel->r_addend = 1;
+
+ /* We don't resolve this here but resolve it in relocate_section. */
+ insn = INSN_JAL;
+ bfd_putb32 (insn, contents + em_irel->r_offset);
+
+ irel->r_info =
+ ELF32_R_INFO (ELF32_R_SYM (irel->r_info), R_NDS32_NONE);
+
+ /* If there is function cse, HI20 can not remove now. */
+ call_irel = find_relocs_at_address_addr (irel, internal_relocs, irelend,
+ R_NDS32_LONGCALL4, laddr);
+ if (call_irel == irelend)
+ {
+ *insn_len = 0;
+ hi_irel->r_info =
+ ELF32_R_INFO (ELF32_R_SYM (hi_irel->r_info), R_NDS32_NONE);
+ }
+
+ insn_irel = find_relocs_at_address_addr (irel, internal_relocs, irelend,
+ R_NDS32_INSN16, irel->r_addend);
+ if (insn_irel != irelend)
+ insn_irel->r_info =
+ ELF32_R_INFO (ELF32_R_SYM (irel->r_info), R_NDS32_NONE);
+
+ return TRUE;
+}
+
+/* Relax LONGCALL5 relocation for nds32_elf_relax_section. */
+
+static bfd_boolean
+nds32_elf_relax_longcall5 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel,
+ Elf_Internal_Rela *internal_relocs, int *insn_len,
+ bfd_byte *contents, Elf_Internal_Sym *isymbuf,
+ Elf_Internal_Shdr *symtab_hdr)
+{
+ /* The pattern for LONGCALL5.
+ bltz rt, .L1 ; LONGCALL5/17_PCREL
+ jal symbol ; 25_PCREL
+ .L1: */
+
+ bfd_vma laddr;
+ uint32_t insn;
+ Elf_Internal_Rela *cond_irel, *irelend;
+ int pic_ext_target = 0;
+ bfd_signed_vma foff;
+
+ irelend = internal_relocs + sec->reloc_count;
+ laddr = irel->r_offset;
+ insn = bfd_getb32 (contents + laddr);
+
+ /* Get the reloc for the address from which the register is
+ being loaded. This reloc will tell us which function is
+ actually being called. */
+ cond_irel =
+ find_relocs_at_address_addr (irel, internal_relocs, irelend,
+ R_NDS32_25_PCREL_RELA, irel->r_addend);
+ if (cond_irel == irelend)
+ {
+ (*_bfd_error_handler)
+ ("%B: warning: R_NDS32_LONGCALL5 points to unrecognized"
+ "reloc at 0x%lx.", abfd, (long) irel->r_offset);
+ return FALSE;
+ }
+
+ /* Get the value of the symbol referred to by the reloc. */
+ foff = calculate_offset (abfd, sec, cond_irel, isymbuf, symtab_hdr,
+ &pic_ext_target);
+
+ if (foff == 0 || foff < -CONSERVATIVE_16BIT_S1
+ || foff >= CONSERVATIVE_16BIT_S1)
+ return FALSE;
+
+ /* Relax to bgezal rt, label ; 17_PCREL
+ or bltzal rt, label ; 17_PCREL */
+
+ /* Convert to complimentary conditional call. */
+ insn = CONVERT_CONDITION_CALL (insn);
+
+ /* 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. */
+
+ /* Modify relocation and contents. */
+ cond_irel->r_info =
+ ELF32_R_INFO (ELF32_R_SYM (cond_irel->r_info), R_NDS32_17_PCREL_RELA);
+
+ /* Replace the long call with a bgezal. */
+ bfd_putb32 (insn, contents + cond_irel->r_offset);
+ *insn_len = 0;
+
+ /* Clean unnessary relocations. */
+ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info), R_NDS32_NONE);
+
+ cond_irel = find_relocs_at_address_addr (irel, internal_relocs, irelend,
+ R_NDS32_17_PCREL_RELA, laddr);
+ cond_irel->r_info =
+ ELF32_R_INFO (ELF32_R_SYM (cond_irel->r_info), R_NDS32_NONE);
+
+ return TRUE;
+}
+
+/* Relax LONGCALL6 relocation for nds32_elf_relax_section. */
+
+static bfd_boolean
+nds32_elf_relax_longcall6 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel,
+ Elf_Internal_Rela *internal_relocs, int *insn_len,
+ bfd_byte *contents, Elf_Internal_Sym *isymbuf,
+ Elf_Internal_Shdr *symtab_hdr)
+{
+ /* The pattern for LONGCALL6.
+ bltz rt, .L1 ; LONGCALL6/17_PCREL
+ sethi ta, hi20(symbol) ; HI20/PTR
+ ori ta, ta, lo12(symbol) ; LO12S0_ORI/PTR
+ jral ta ; PTR_RES/EMPTY/INSN16
+ .L1 */
+
+ bfd_vma laddr;
+ uint32_t insn;
+ Elf_Internal_Rela *em_irel, *cond_irel, *irelend;
+ int pic_ext_target = 0;
+ bfd_signed_vma foff;
+
+ irelend = internal_relocs + sec->reloc_count;
+ laddr = irel->r_offset;
+
+ /* Get the reloc for the address from which the register is
+ being loaded. This reloc will tell us which function is
+ actually being called. */
+ em_irel = find_relocs_at_address_addr (irel, internal_relocs, irelend,
+ R_NDS32_EMPTY, irel->r_addend);
+
+ if (em_irel == irelend)
+ {
+ (*_bfd_error_handler)
+ ("%B: warning: R_NDS32_LONGCALL6 points to unrecognized"
+ "reloc at 0x%lx.", abfd, (long) irel->r_offset);
+ return FALSE;
+ }
+
+ /* Get the value of the symbol referred to by the reloc. */
+ foff = calculate_offset (abfd, sec, em_irel, isymbuf, symtab_hdr,
+ &pic_ext_target);
+
+ if (pic_ext_target || foff == 0 || foff < -CONSERVATIVE_24BIT_S1
+ || foff >= CONSERVATIVE_24BIT_S1)
+ return FALSE;
+
+ /* Check these is enough space to insert jal in R_NDS32_EMPTY. */
+ insn = bfd_getb32 (contents + irel->r_addend);
+ if (insn & 0x80000000)
+ return FALSE;
+
+ insn = bfd_getb32 (contents + laddr);
+ if (foff >= -CONSERVATIVE_16BIT_S1 && foff < CONSERVATIVE_16BIT_S1)
+ {
+ /* Relax to bgezal rt, label ; 17_PCREL
+ or bltzal rt, label ; 17_PCREL */
+
+ /* Convert to complimentary conditional call. */
+ *insn_len = 0;
+ insn = CONVERT_CONDITION_CALL (insn);
+ bfd_putb32 (insn, contents + em_irel->r_offset);
+
+ em_irel->r_info =
+ ELF32_R_INFO (ELF32_R_SYM (em_irel->r_info), R_NDS32_17_PCREL_RELA);
+
+ /* Set resolved relocation. */
+ cond_irel =
+ find_relocs_at_address_addr (irel, internal_relocs, irelend,
+ R_NDS32_PTR_RESOLVED, irel->r_addend);
+ if (cond_irel == irelend)
+ {
+ (*_bfd_error_handler)
+ ("%B: warning: R_NDS32_LONGCALL6 points to unrecognized"
+ "reloc at 0x%lx.", abfd, (long) irel->r_offset);
+ return FALSE;
+ }
+ cond_irel->r_addend = 1;
+
+ /* Clear relocations. */
+
+ irel->r_info =
+ ELF32_R_INFO (ELF32_R_SYM (irel->r_info), R_NDS32_NONE);
+
+ cond_irel =
+ find_relocs_at_address_addr (irel, internal_relocs, irelend,
+ R_NDS32_17_PCREL_RELA, laddr);
+ if (cond_irel != irelend)
+ cond_irel->r_info =
+ ELF32_R_INFO (ELF32_R_SYM (cond_irel->r_info), R_NDS32_NONE);
+
+ cond_irel =
+ find_relocs_at_address_addr (irel, internal_relocs, irelend,
+ R_NDS32_INSN16, irel->r_addend);
+ if (cond_irel != irelend)
+ cond_irel->r_info =
+ ELF32_R_INFO (ELF32_R_SYM (cond_irel->r_info), R_NDS32_NONE);
+
+ }
+ else if (foff >= -CONSERVATIVE_24BIT_S1 && foff < CONSERVATIVE_24BIT_S1)
+ {
+ /* Relax to the following instruction sequence
+ bltz rt, .L1 ; LONGCALL2/17_PCREL
+ jal symbol ; 25_PCREL/PTR_RES
+ .L1 */
+ *insn_len = 4;
+ /* Convert instruction. */
+ insn = INSN_JAL;
+ bfd_putb32 (insn, contents + em_irel->r_offset);
+
+ /* Convert relocations. */
+ em_irel->r_info = ELF32_R_INFO (ELF32_R_SYM (em_irel->r_info),
+ R_NDS32_25_PCREL_RELA);
+ irel->r_info =
+ ELF32_R_INFO (ELF32_R_SYM (irel->r_info), R_NDS32_LONGCALL5);
+
+ /* Set resolved relocation. */
+ cond_irel =
+ find_relocs_at_address_addr (irel, internal_relocs, irelend,
+ R_NDS32_PTR_RESOLVED, irel->r_addend);
+ if (cond_irel == irelend)
+ {
+ (*_bfd_error_handler)
+ ("%B: warning: R_NDS32_LONGCALL6 points to unrecognized"
+ "reloc at 0x%lx.", abfd, (long) irel->r_offset);
+ return FALSE;
+ }
+ cond_irel->r_addend = 1;
+
+ cond_irel =
+ find_relocs_at_address_addr (irel, internal_relocs, irelend,
+ R_NDS32_INSN16, irel->r_addend);
+ if (cond_irel != irelend)
+ cond_irel->r_info =
+ ELF32_R_INFO (ELF32_R_SYM (cond_irel->r_info), R_NDS32_NONE);
+ }
+ return TRUE;
+}
+
+/* Relax LONGJUMP4 relocation for nds32_elf_relax_section. */
+
+static bfd_boolean
+nds32_elf_relax_longjump4 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel,
+ Elf_Internal_Rela *internal_relocs, int *insn_len,
+ bfd_byte *contents, Elf_Internal_Sym *isymbuf,
+ Elf_Internal_Shdr *symtab_hdr)
+{
+ /* The pattern for LONGJUMP4.
+ sethi ta, hi20(symbol) ; LONGJUMP4/HI20
+ ori ta, ta, lo12(symbol) ; LO12S0_ORI/PTR
+ jr ta ; PTR_RES/INSN16/EMPTY */
+
+ bfd_vma laddr;
+ int seq_len; /* Original length of instruction sequence. */
+ uint32_t insn;
+ Elf_Internal_Rela *hi_irel, *ptr_irel, *em_irel, *call_irel, *irelend;
+ int pic_ext_target = 0;
+ bfd_signed_vma foff;
+
+ irelend = internal_relocs + sec->reloc_count;
+ seq_len = GET_SEQ_LEN (irel->r_addend);
+ laddr = irel->r_offset;
+ *insn_len = seq_len;
+
+ /* Get the reloc for the address from which the register is
+ being loaded. This reloc will tell us which function is
+ actually being called. */
+
+ hi_irel = find_relocs_at_address_addr (irel, internal_relocs, irelend,
+ R_NDS32_HI20_RELA, laddr);
+
+ if (hi_irel == irelend)
+ {
+ (*_bfd_error_handler)
+ ("%B: warning: R_NDS32_LONGJUMP4 points to unrecognized"
+ "reloc at 0x%lx.", abfd, (long) irel->r_offset);
+ return FALSE;
+ }
+
+ /* Get the value of the symbol referred to by the reloc. */
+ foff = calculate_offset (abfd, sec, hi_irel, isymbuf, symtab_hdr,
+ &pic_ext_target);
+
+ if (pic_ext_target || foff == 0 || foff >= CONSERVATIVE_24BIT_S1
+ || foff < -CONSERVATIVE_24BIT_S1)
+ return FALSE;
+
+ /* Convert it to "j label", it may be converted to j8 in the final
+ pass of relaxation. Therefore, we do not consider this currently. */
+ ptr_irel = find_relocs_at_address_addr (irel, internal_relocs, irelend,
+ R_NDS32_PTR_RESOLVED, irel->r_addend);
+ em_irel = find_relocs_at_address_addr (irel, internal_relocs, irelend,
+ R_NDS32_EMPTY, irel->r_addend);
+
+ if (ptr_irel == irelend || em_irel == irelend)
+ {
+ (*_bfd_error_handler)
+ ("%B: warning: R_NDS32_LONGJUMP4 points to unrecognized"
+ "reloc at 0x%lx.", abfd, (long) irel->r_offset);
+ return FALSE;
+ }
+
+ em_irel->r_info =
+ ELF32_R_INFO (ELF32_R_SYM (em_irel->r_info), R_NDS32_25_PCREL_RELA);
+ ptr_irel->r_addend = 1;
+
+ /* Write instruction. */
+ insn = INSN_J;
+ bfd_putb32 (insn, contents + em_irel->r_offset);
+
+ /* Clear relocations. */
+ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info), R_NDS32_NONE);
+
+ /* If there is function cse, HI20 can not remove now. */
+ call_irel = find_relocs_at_address_addr (irel, internal_relocs, irelend,
+ R_NDS32_LONGJUMP4, laddr);
+ if (call_irel == irelend)
+ {
+ *insn_len = 0;
+ hi_irel->r_info =
+ ELF32_R_INFO (ELF32_R_SYM (hi_irel->r_info), R_NDS32_NONE);
+ }
+
+ return TRUE;
+}
+
+/* Relax LONGJUMP5 relocation for nds32_elf_relax_section. */
+
+static bfd_boolean
+nds32_elf_relax_longjump5 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel,
+ Elf_Internal_Rela *internal_relocs, int *insn_len,
+ int *seq_len, bfd_byte *contents,
+ Elf_Internal_Sym *isymbuf,
+ Elf_Internal_Shdr *symtab_hdr)
+{
+ /* There are 2 variations for LONGJUMP5
+ case 2-4; 1st insn convertible, 16-bit on.
+ bnes38 rt, ra, .L1 ; LONGJUMP5/9_PCREL/INSN16
+ j label ; 25_PCREL/INSN16
+ $1:
+
+ case 4-4; 1st insn not convertible
+ bne rt, ra, .L1 ; LONGJUMP5/15_PCREL/INSN16
+ j label ; 25_PCREL/INSN16
+ .L1: */
+
+ bfd_vma laddr;
+ Elf_Internal_Rela *cond_irel, *irelend;
+ int pic_ext_target = 0;
+ unsigned int i;
+ bfd_signed_vma foff;
+ uint32_t insn, re_insn = 0;
+ uint16_t insn16, re_insn16 = 0;
+ unsigned long reloc;
+
+ enum elf_nds32_reloc_type checked_types[] =
+ { R_NDS32_17_PCREL_RELA, R_NDS32_15_PCREL_RELA,
+ R_NDS32_9_PCREL_RELA, R_NDS32_INSN16 };
+
+ irelend = internal_relocs + sec->reloc_count;
+ laddr = irel->r_offset;
+
+ /* Get the reloc for the address from which the register is
+ being loaded. This reloc will tell us which function is
+ actually being called. */
+
+ cond_irel =
+ find_relocs_at_address_addr (irel, internal_relocs, irelend,
+ R_NDS32_25_PCREL_RELA, irel->r_addend);
+ if (cond_irel == irelend)
+ {
+ (*_bfd_error_handler)
+ ("%B: warning: R_NDS32_LONGJUMP5 points to unrecognized"
+ "reloc at 0x%lx.", abfd, (long) irel->r_offset);
+ return FALSE;
+ }
+
+ /* Get the value of the symbol referred to by the reloc. */
+ foff = calculate_offset (abfd, sec, cond_irel, isymbuf, symtab_hdr,
+ &pic_ext_target);
+
+ if (pic_ext_target || foff == 0 || foff < -CONSERVATIVE_16BIT_S1
+ || foff >= CONSERVATIVE_16BIT_S1)
+ return FALSE;
+
+ /* Get the all corresponding instructions. */
+ insn = bfd_getb32 (contents + laddr);
+ /* Check instruction size. */
+ if (insn & 0x80000000)
+ {
+ *seq_len = 0;
+ insn16 = insn >> 16;
+ nds32_elf_convert_branch (insn16, 0, &re_insn16, &re_insn);
+ }
+ else
+ nds32_elf_convert_branch (0, insn, &re_insn16, &re_insn);
+
+ if (N32_OP6 (re_insn) == N32_OP6_BR1
+ && (foff >= -CONSERVATIVE_14BIT_S1 && foff < CONSERVATIVE_14BIT_S1))
+ {
+ /* beqs label ; 15_PCREL. */
+ bfd_putb32 (re_insn, contents + cond_irel->r_offset);
+ reloc = R_NDS32_15_PCREL_RELA;
+ }
+ else if (N32_OP6 (re_insn) == N32_OP6_BR2
+ && foff >= -CONSERVATIVE_16BIT_S1 && foff < CONSERVATIVE_16BIT_S1)
+ {
+ /* beqz label ; 17_PCREL. */
+ bfd_putb32 (re_insn, contents + cond_irel->r_offset);
+ reloc = R_NDS32_17_PCREL_RELA;
+ }
+ else if ( N32_OP6 (re_insn) == N32_OP6_BR3
+ && foff >= -CONSERVATIVE_8BIT_S1 && foff < CONSERVATIVE_8BIT_S1)
+ {
+ /* beqc label ; 9_PCREL. */
+ bfd_putb32 (re_insn, contents + cond_irel->r_offset);
+ reloc = R_NDS32_WORD_9_PCREL_RELA;
+ }
+ else
+ return FALSE;
+
+ /* Set all relocations. */
+ cond_irel->r_info = ELF32_R_INFO (ELF32_R_SYM (cond_irel->r_info), reloc);
+
+ /* Clean relocations. */
+ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info), R_NDS32_NONE);
+ for (i = 0; i < sizeof (checked_types) / sizeof (checked_types[0]); i++)
+ {
+ cond_irel = find_relocs_at_address_addr (irel, internal_relocs, irelend,
+ checked_types[i], laddr);
+ if (cond_irel != irelend)
+ {
+ if (*seq_len == 0
+ && (ELF32_R_TYPE (cond_irel->r_info) == R_NDS32_INSN16))
+ {
+ /* If the branch instruction is 2 byte, it cannot remove
+ directly. Only convert it to nop16 and remove it after
+ checking alignment issue. */
+ insn16 = NDS32_NOP16;
+ bfd_putb16 (insn16, contents + laddr);
+ cond_irel->r_addend = R_NDS32_INSN16_CONVERT_FLAG;
+ }
+ else
+ cond_irel->r_info = ELF32_R_INFO (ELF32_R_SYM (cond_irel->r_info),
+ R_NDS32_NONE);
+ }
+ }
+ *insn_len = 0;
+
+ return TRUE;
+}
+
+/* Relax LONGJUMP6 relocation for nds32_elf_relax_section. */
+
+static bfd_boolean
+nds32_elf_relax_longjump6 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel,
+ Elf_Internal_Rela *internal_relocs, int *insn_len,
+ int *seq_len, bfd_byte *contents,
+ Elf_Internal_Sym *isymbuf,
+ Elf_Internal_Shdr *symtab_hdr)
+{
+ /* There are 5 variations for LONGJUMP6
+ case : 2-4-4-4; 1st insn convertible, 16-bit on.
+ bnes38 rt, ra, .L1 ; LONGJUMP6/15_PCREL/INSN16
+ sethi ta, hi20(symbol) ; HI20/PTR
+ ori ta, ta, lo12(symbol) ; LO12S0_ORI/PTR
+ jr ta ; PTR_RES/INSN16/EMPTY
+ .L1:
+
+ case : 4-4-4-4; 1st insn not convertible, 16-bit on.
+ bne rt, ra, .L1 ; LONGJUMP6/15_PCREL/INSN16
+ sethi ta, hi20(symbol) ; HI20/PTR
+ ori ta, ta, lo12(symbol) ; LO12S0_ORI/PTR
+ jr ta ; PTR_RES/INSN16/EMPTY
+ .L1: */
+
+ enum elf_nds32_reloc_type checked_types[] =
+ { R_NDS32_17_PCREL_RELA, R_NDS32_15_PCREL_RELA,
+ R_NDS32_9_PCREL_RELA, R_NDS32_INSN16 };
+
+ int reloc_off = 0, cond_removed = 0;
+ bfd_vma laddr;
+ Elf_Internal_Rela *cond_irel, *em_irel, *irelend, *insn_irel;
+ int pic_ext_target = 0;
+ unsigned int i;
+ bfd_signed_vma foff;
+ uint32_t insn, re_insn = 0;
+ uint16_t insn16, re_insn16 = 0;
+ unsigned long reloc;
+
+ irelend = internal_relocs + sec->reloc_count;
+ laddr = irel->r_offset;
+
+ /* Get the reloc for the address from which the register is
+ being loaded. This reloc will tell us which function is
+ actually being called. */
+ em_irel = find_relocs_at_address_addr (irel, internal_relocs, irelend,
+ R_NDS32_EMPTY, irel->r_addend);
+
+ if (em_irel == irelend)
+ {
+ (*_bfd_error_handler)
+ ("%B: warning: R_NDS32_LONGJUMP6 points to unrecognized"
+ "reloc at 0x%lx.", abfd, (long) irel->r_offset);
+ return FALSE;
+ }
+
+ /* Get the value of the symbol referred to by the reloc. */
+ foff = calculate_offset (abfd, sec, em_irel, isymbuf, symtab_hdr,
+ &pic_ext_target);
+
+ if (pic_ext_target || foff == 0 || foff < -CONSERVATIVE_24BIT_S1
+ || foff >= CONSERVATIVE_24BIT_S1)
+ return FALSE;
+
+ insn = bfd_getb32 (contents + laddr);
+ /* Check instruction size. */
+ if (insn & 0x80000000)
+ {
+ *seq_len = 0;
+ insn16 = insn >> 16;
+ nds32_elf_convert_branch (insn16, 0, &re_insn16, &re_insn);
+ }
+ else
+ nds32_elf_convert_branch (0, insn, &re_insn16, &re_insn);
+
+ /* 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 (N32_OP6 (re_insn) == N32_OP6_BR1
+ && (foff >= -CONSERVATIVE_14BIT_S1 && foff < CONSERVATIVE_14BIT_S1))
+ {
+ /* beqs label ; 15_PCREL */
+ bfd_putb32 (re_insn, contents + em_irel->r_offset);
+ reloc = R_NDS32_15_PCREL_RELA;
+ cond_removed = 1;
+ }
+ else if (N32_OP6 (re_insn) == N32_OP6_BR2
+ && foff >= -CONSERVATIVE_16BIT_S1 && foff < CONSERVATIVE_16BIT_S1)
+ {
+ /* beqz label ; 17_PCREL */
+ bfd_putb32 (re_insn, contents + em_irel->r_offset);
+ reloc = R_NDS32_17_PCREL_RELA;
+ cond_removed = 1;
+ }
+ else if (foff >= -CONSERVATIVE_24BIT_S1 - reloc_off
+ && foff < CONSERVATIVE_24BIT_S1 - reloc_off)
+ {
+ /* Relax to one of the following 2 variations
+
+ case 2-4; 1st insn convertible, 16-bit on.
+ bnes38 rt, ra, .L1 ; LONGJUMP5/9_PCREL/INSN16
+ j label ; 25_PCREL/INSN16
+ $1:
+
+ case 4-4; 1st insn not convertible
+ bne rt, ra, .L1 ; LONGJUMP5/15_PCREL/INSN16
+ j label ; 25_PCREL/INSN16
+ .L1: */
+
+ /* Use j label as second instruction. */
+ insn = INSN_J;
+ reloc = R_NDS32_25_PCREL_RELA;
+ bfd_putb32 (insn, contents + em_irel->r_offset);
+ }
+ else
+ return FALSE;
+
+ /* Set all relocations. */
+ em_irel->r_info = ELF32_R_INFO (ELF32_R_SYM (em_irel->r_info), reloc);
+
+ cond_irel =
+ find_relocs_at_address_addr (irel, internal_relocs, irelend,
+ R_NDS32_PTR_RESOLVED, em_irel->r_offset);
+ cond_irel->r_addend = 1;
+
+ /* Use INSN16 of first branch instruction to distinguish if keeping
+ INSN16 of final instruction or not. */
+ insn_irel = find_relocs_at_address_addr (irel, internal_relocs, irelend,
+ R_NDS32_INSN16, irel->r_offset);
+ if (insn_irel == irelend)
+ {
+ /* Clean the final INSN16. */
+ insn_irel =
+ find_relocs_at_address_addr (irel, internal_relocs, irelend,
+ R_NDS32_INSN16, em_irel->r_offset);
+ insn_irel->r_info = ELF32_R_INFO (ELF32_R_SYM (cond_irel->r_info),
+ R_NDS32_NONE);
+ }
+
+ if (cond_removed == 1)
+ {
+ *insn_len = 0;
+
+ /* Clear relocations. */
+ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info), R_NDS32_NONE);
+
+ for (i = 0; i < sizeof (checked_types) / sizeof (checked_types[0]); i++)
+ {
+ cond_irel =
+ find_relocs_at_address_addr (irel, internal_relocs, irelend,
+ checked_types[i], laddr);
+ if (cond_irel != irelend)
+ {
+ if (*seq_len == 0
+ && (ELF32_R_TYPE (cond_irel->r_info) == R_NDS32_INSN16))
+ {
+ /* If the branch instruction is 2 byte, it cannot remove
+ directly. Only convert it to nop16 and remove it after
+ checking alignment issue. */
+ insn16 = NDS32_NOP16;
+ bfd_putb16 (insn16, contents + laddr);
+ cond_irel->r_addend = R_NDS32_INSN16_CONVERT_FLAG;
+ }
+ else
+ cond_irel->r_info =
+ ELF32_R_INFO (ELF32_R_SYM (cond_irel->r_info), R_NDS32_NONE);
+ }
+ }
+ }
+ else
+ {
+ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
+ R_NDS32_LONGJUMP5);
+ }
+
+ return TRUE;
+}
+
+/* Relax LONGJUMP7 relocation for nds32_elf_relax_section. */
+
+static bfd_boolean
+nds32_elf_relax_longjump7 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel,
+ Elf_Internal_Rela *internal_relocs, int *insn_len,
+ int *seq_len, bfd_byte *contents,
+ Elf_Internal_Sym *isymbuf,
+ Elf_Internal_Shdr *symtab_hdr)
+{
+ /* There are 2 variations for LONGJUMP5
+ case 2-4; 1st insn convertible, 16-bit on.
+ movi55 ta, imm11 ; LONGJUMP7/INSN16
+ beq rt, ta, label ; 15_PCREL
+
+ case 4-4; 1st insn not convertible
+ movi55 ta, imm11 ; LONGJUMP7/INSN16
+ beq rt, ta, label ; 15_PCREL */
+
+ bfd_vma laddr;
+ Elf_Internal_Rela *cond_irel, *irelend, *insn_irel;
+ int pic_ext_target = 0;
+ bfd_signed_vma foff;
+ uint32_t insn, re_insn = 0;
+ uint16_t insn16;
+ uint32_t imm11;
+
+ irelend = internal_relocs + sec->reloc_count;
+ laddr = irel->r_offset;
+
+ /* Get the reloc for the address from which the register is
+ being loaded. This reloc will tell us which function is
+ actually being called. */
+
+ cond_irel =
+ find_relocs_at_address_addr (irel, internal_relocs, irelend,
+ R_NDS32_15_PCREL_RELA, irel->r_addend);
+ if (cond_irel == irelend)
+ {
+ (*_bfd_error_handler)
+ ("%B: warning: R_NDS32_LONGJUMP7 points to unrecognized"
+ "reloc at 0x%lx.", abfd, (long) irel->r_offset);
+ return FALSE;
+ }
+
+ /* Get the value of the symbol referred to by the reloc. */
+ foff = calculate_offset (abfd, sec, cond_irel, isymbuf, symtab_hdr,
+ &pic_ext_target);
+
+ if (pic_ext_target || foff == 0 || foff < -CONSERVATIVE_8BIT_S1
+ || foff >= CONSERVATIVE_8BIT_S1)
+ return FALSE;
+
+ /* Get the first instruction for its size. */
+ insn = bfd_getb32 (contents + laddr);
+ if (insn & 0x80000000)
+ {
+ *seq_len = 0;
+ /* Get the immediate from movi55. */
+ imm11 = N16_IMM5S (insn >> 16);
+ }
+ else
+ {
+ /* Get the immediate from movi. */
+ imm11 = N32_IMM20S (insn);
+ }
+
+ /* Get the branch instruction. */
+ insn = bfd_getb32 (contents + irel->r_addend);
+ /* Convert instruction to BR3. */
+ if ((insn >> 14) & 0x1)
+ re_insn = N32_BR3 (BNEC, N32_RT5 (insn), imm11, 0);
+ else
+ re_insn = N32_BR3 (BEQC, N32_RT5 (insn), imm11, 0);
+
+ bfd_putb32 (re_insn, contents + cond_irel->r_offset);
+
+ /* Set all relocations. */
+ cond_irel->r_info = ELF32_R_INFO (ELF32_R_SYM (cond_irel->r_info),
+ R_NDS32_WORD_9_PCREL_RELA);
+
+ /* Clean relocations. */
+ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info), R_NDS32_NONE);
+ insn_irel = find_relocs_at_address_addr (irel, internal_relocs, irelend,
+ R_NDS32_INSN16, irel->r_offset);
+ if (insn_irel != irelend)
+ {
+ if (*seq_len == 0)
+ {
+ /* If the first insntruction is 16bit, convert it to nop16. */
+ insn16 = NDS32_NOP16;
+ bfd_putb16 (insn16, contents + laddr);
+ insn_irel->r_addend = R_NDS32_INSN16_CONVERT_FLAG;
+ }
+ else
+ cond_irel->r_info = ELF32_R_INFO (ELF32_R_SYM (cond_irel->r_info),
+ R_NDS32_NONE);
+ }
+ *insn_len = 0;
+
+ return TRUE;
+}
+
+#define GET_LOADSTORE_RANGE(addend) (((addend) >> 8) & 0x3f)
+
+/* Relax LOADSTORE relocation for nds32_elf_relax_section. */
+
+static bfd_boolean
+nds32_elf_relax_loadstore (struct bfd_link_info *link_info, bfd *abfd,
+ asection *sec, Elf_Internal_Rela *irel,
+ Elf_Internal_Rela *internal_relocs, int *insn_len,
+ bfd_byte *contents, Elf_Internal_Sym *isymbuf,
+ Elf_Internal_Shdr *symtab_hdr, int load_store_relax)
+{
+ int eliminate_sethi = 0, range_type, i;
+ bfd_vma local_sda, laddr;
+ int seq_len; /* Original length of instruction sequence. */
+ uint32_t insn;
+ Elf_Internal_Rela *hi_irelfn = NULL, *irelend;
+ bfd_vma access_addr = 0;
+ bfd_vma range_l = 0, range_h = 0; /* Upper/lower bound. */
+ enum elf_nds32_reloc_type checked_types[] =
+ { R_NDS32_HI20_RELA, R_NDS32_GOT_HI20,
+ R_NDS32_GOTPC_HI20, R_NDS32_GOTOFF_HI20,
+ R_NDS32_PLTREL_HI20, R_NDS32_PLT_GOTREL_HI20,
+ R_NDS32_TLS_LE_HI20
+ };
+
+ irelend = internal_relocs + sec->reloc_count;
+ seq_len = GET_SEQ_LEN (irel->r_addend);
+ laddr = irel->r_offset;
+ *insn_len = seq_len;
+
+ /* Get the high part relocation. */
+ for (i = 0; (unsigned) i < sizeof (checked_types); i++)
+ {
+ hi_irelfn = find_relocs_at_address_addr (irel, internal_relocs, irelend,
+ checked_types[i], laddr);
+ if (hi_irelfn != irelend)
+ break;
+ }
+
+ if (hi_irelfn == irelend)
+ {
+ (*_bfd_error_handler)
+ ("%B: warning: R_NDS32_LOADSTORE points to unrecognized"
+ "reloc at 0x%lx.", abfd, (long) irel->r_offset);
+ return FALSE;
+ }
+
+ range_type = GET_LOADSTORE_RANGE (irel->r_addend);
+ nds32_elf_final_sda_base (sec->output_section->owner,
+ link_info, &local_sda, FALSE);
+
+ switch (ELF32_R_TYPE (hi_irelfn->r_info))
+ {
+ case R_NDS32_HI20_RELA:
+ insn = bfd_getb32 (contents + laddr);
+ access_addr =
+ calculate_memory_address (abfd, hi_irelfn, isymbuf, symtab_hdr);
+
+ if (range_type == NDS32_LOADSTORE_IMM)
+ {
+ struct elf_link_hash_entry *h = NULL;
+ int indx;
+
+ if (ELF32_R_SYM (hi_irelfn->r_info) >= symtab_hdr->sh_info)
+ {
+ indx = ELF32_R_SYM (hi_irelfn->r_info) - symtab_hdr->sh_info;
+ h = elf_sym_hashes (abfd)[indx];
+ }
+
+ if ((access_addr < CONSERVATIVE_20BIT)
+ && (!h || (h && strcmp (h->root.root.string, FP_BASE_NAME) != 0)))
+ {
+ eliminate_sethi = 1;
+ break;
+ }
+
+ /* This is avoid to relax symbol address which is fixed
+ relocations. Ex: _stack. */
+ if (h && bfd_is_abs_section (h->root.u.def.section))
+ return FALSE;
+ }
+
+ if (!load_store_relax)
+ return FALSE;
+
+ /* Case for set gp register. */
+ if (N32_RT5 (insn) == REG_GP)
+ break;
+
+ if (range_type == NDS32_LOADSTORE_FLOAT_S
+ || range_type == NDS32_LOADSTORE_FLOAT_S)
+ {
+ range_l = sdata_range[0][0];
+ range_h = sdata_range[0][1];
+ }
+ else
+ {
+ range_l = sdata_range[1][0];
+ range_h = sdata_range[1][1];
+ }
+ break;
+
+ case R_NDS32_GOT_HI20:
+ access_addr =
+ calculate_got_memory_address (abfd, link_info, hi_irelfn, symtab_hdr);
+
+ /* If this symbol is not in .got, the return value will be -1.
+ Since the gp value is set to SDA_BASE but not GLOBAL_OFFSET_TABLE,
+ a negative offset is allowed. */
+ if ((bfd_signed_vma) (access_addr - local_sda) < CONSERVATIVE_20BIT
+ && (bfd_signed_vma) (access_addr - local_sda) >= -CONSERVATIVE_20BIT)
+ eliminate_sethi = 1;
+ break;
+
+ case R_NDS32_PLT_GOTREL_HI20:
+ access_addr = calculate_plt_memory_address (abfd, link_info, isymbuf,
+ hi_irelfn, symtab_hdr);
+
+ if ((bfd_signed_vma) (access_addr - local_sda) < CONSERVATIVE_20BIT
+ && (bfd_signed_vma) (access_addr - local_sda) >= -CONSERVATIVE_20BIT)
+ eliminate_sethi = 1;
+ break;
+
+ case R_NDS32_GOTOFF_HI20:
+ access_addr =
+ calculate_memory_address (abfd, hi_irelfn, isymbuf, symtab_hdr);
+
+ if ((bfd_signed_vma) (access_addr - local_sda) < CONSERVATIVE_20BIT
+ && (bfd_signed_vma) (access_addr - local_sda) >= -CONSERVATIVE_20BIT)
+ eliminate_sethi = 1;
+ break;
+
+ case R_NDS32_GOTPC_HI20:
+ /* The access_addr must consider r_addend of hi_irel. */
+ access_addr = sec->output_section->vma + sec->output_offset
+ + irel->r_offset + hi_irelfn->r_addend;
+
+ if ((bfd_signed_vma) (local_sda - access_addr) < CONSERVATIVE_20BIT
+ && (bfd_signed_vma) (local_sda - access_addr) >= -CONSERVATIVE_20BIT)
+ eliminate_sethi = 1;
+ break;
+
+ case R_NDS32_TLS_LE_HI20:
+ access_addr =
+ calculate_memory_address (abfd, hi_irelfn, isymbuf, symtab_hdr);
+ BFD_ASSERT (elf_hash_table (link_info)->tls_sec != NULL);
+ access_addr -= (elf_hash_table (link_info)->tls_sec->vma + TP_OFFSET);
+ if ((range_type == NDS32_LOADSTORE_IMM)
+ && (bfd_signed_vma) (access_addr) < CONSERVATIVE_20BIT
+ && (bfd_signed_vma) (access_addr) >= -CONSERVATIVE_20BIT)
+ eliminate_sethi = 1;
+ break;
+
+ default:
+ return FALSE;
+ }
+
+ /* Delete sethi instruction. */
+ if (eliminate_sethi == 1
+ || (local_sda <= access_addr && (access_addr - local_sda) < range_h)
+ || (local_sda > access_addr && (local_sda - access_addr) <= range_l))
+ {
+ hi_irelfn->r_info =
+ ELF32_R_INFO (ELF32_R_SYM (hi_irelfn->r_info), R_NDS32_NONE);
+ irel->r_info =
+ ELF32_R_INFO (ELF32_R_SYM (irel->r_info), R_NDS32_NONE);
+ *insn_len = 0;
+ }
+ return TRUE;
+}
+
+/* Relax LO12 relocation for nds32_elf_relax_section. */
+
+static void
+nds32_elf_relax_lo12 (struct bfd_link_info *link_info, bfd *abfd,
+ asection *sec, Elf_Internal_Rela *irel,
+ Elf_Internal_Rela *internal_relocs, bfd_byte *contents,
+ Elf_Internal_Sym *isymbuf, Elf_Internal_Shdr *symtab_hdr)
+{
+ uint32_t insn;
+ bfd_vma local_sda, laddr;
+ unsigned long reloc;
+ bfd_vma access_addr;
+ bfd_vma range_l = 0, range_h = 0; /* Upper/lower bound. */
+ Elf_Internal_Rela *irelfn = NULL, *irelend;
+ struct elf_link_hash_entry *h = NULL;
+ int indx;
+
+ /* For SDA base relative relaxation. */
+ nds32_elf_final_sda_base (sec->output_section->owner, link_info,
+ &local_sda, FALSE);
+
+ irelend = internal_relocs + sec->reloc_count;
+ laddr = irel->r_offset;
+ insn = bfd_getb32 (contents + laddr);
+
+ if (!is_sda_access_insn (insn) && N32_OP6 (insn) != N32_OP6_ORI)
+ return;
+
+ access_addr = calculate_memory_address (abfd, irel, isymbuf, symtab_hdr);
+
+ if (ELF32_R_SYM (irel->r_info) >= symtab_hdr->sh_info)
+ {
+ indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info;
+ h = elf_sym_hashes (abfd)[indx];
+ }
+
+ if (N32_OP6 (insn) == N32_OP6_ORI && access_addr < CONSERVATIVE_20BIT
+ && (!h || (h && strcmp (h->root.root.string, FP_BASE_NAME) != 0)))
+ {
+ reloc = R_NDS32_20_RELA;
+ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info), reloc);
+ insn = N32_TYPE1 (MOVI, N32_RT5 (insn), 0);
+ bfd_putb32 (insn, contents + laddr);
+ }
+ /* This is avoid to relax symbol address which is fixed
+ relocations. Ex: _stack. */
+ else if (N32_OP6 (insn) == N32_OP6_ORI
+ && h && bfd_is_abs_section (h->root.u.def.section))
+ return;
+ else
+ {
+ range_l = sdata_range[1][0];
+ range_h = sdata_range[1][1];
+ switch (ELF32_R_TYPE (irel->r_info))
+ {
+ case R_NDS32_LO12S0_RELA:
+ reloc = R_NDS32_SDA19S0_RELA;
+ break;
+ case R_NDS32_LO12S1_RELA:
+ reloc = R_NDS32_SDA18S1_RELA;
+ break;
+ case R_NDS32_LO12S2_RELA:
+ reloc = R_NDS32_SDA17S2_RELA;
+ break;
+ case R_NDS32_LO12S2_DP_RELA:
+ range_l = sdata_range[0][0];
+ range_h = sdata_range[0][1];
+ reloc = R_NDS32_SDA12S2_DP_RELA;
+ break;
+ case R_NDS32_LO12S2_SP_RELA:
+ range_l = sdata_range[0][0];
+ range_h = sdata_range[0][1];
+ reloc = R_NDS32_SDA12S2_SP_RELA;
+ break;
+ default:
+ return;
+ }
+
+ /* There are range_h and range_l because linker has to promise
+ all sections move cross one page together. */
+ if ((local_sda <= access_addr && (access_addr - local_sda) < range_h)
+ || (local_sda > access_addr && (local_sda - access_addr) <= range_l))
+ {
+ if (N32_OP6 (insn) == N32_OP6_ORI && N32_RT5 (insn) == REG_GP)
+ {
+ /* Maybe we should add R_NDS32_INSN16 reloc type here
+ or manually do some optimization. sethi can't be
+ eliminated when updating $gp so the relative ori
+ needs to be preserved. */
+ return;
+ }
+ if (!turn_insn_to_sda_access (insn, ELF32_R_TYPE (irel->r_info),
+ &insn))
+ return;
+ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info), reloc);
+ bfd_putb32 (insn, contents + laddr);
+
+ irelfn = find_relocs_at_address (irel, internal_relocs, irelend,
+ R_NDS32_INSN16);
+ /* SDA17 must keep INSN16 for converting fp_as_gp. */
+ if (irelfn != irelend && reloc != R_NDS32_SDA17S2_RELA)
+ irelfn->r_info =
+ ELF32_R_INFO (ELF32_R_SYM (irelfn->r_info), R_NDS32_NONE);
+
+ }
+ }
+ return;
+}
+
+/* Relax low part of PIC instruction pattern. */
+
+static void
+nds32_elf_relax_piclo12 (struct bfd_link_info *link_info, bfd *abfd,
+ asection *sec, Elf_Internal_Rela *irel,
+ bfd_byte *contents, Elf_Internal_Sym *isymbuf,
+ Elf_Internal_Shdr *symtab_hdr)
+{
+ uint32_t insn;
+ bfd_vma local_sda, laddr;
+ bfd_signed_vma foff;
+ unsigned long reloc;
+
+ nds32_elf_final_sda_base (sec->output_section->owner, link_info,
+ &local_sda, FALSE);
+ laddr = irel->r_offset;
+ insn = bfd_getb32 (contents + laddr);
+
+ if (N32_OP6 (insn) != N32_OP6_ORI)
+ return;
+
+ if (ELF32_R_TYPE (irel->r_info) == R_NDS32_GOT_LO12)
+ {
+ foff = calculate_got_memory_address (abfd, link_info, irel,
+ symtab_hdr) - local_sda;
+ reloc = R_NDS32_GOT20;
+ }
+ else if (ELF32_R_TYPE (irel->r_info) == R_NDS32_PLT_GOTREL_LO12)
+ {
+ foff = calculate_plt_memory_address (abfd, link_info, isymbuf, irel,
+ symtab_hdr) - local_sda;
+ reloc = R_NDS32_PLT_GOTREL_LO20;
+ }
+ else if (ELF32_R_TYPE (irel->r_info) == R_NDS32_GOTOFF_LO12)
+ {
+ foff = calculate_memory_address (abfd, irel, isymbuf,
+ symtab_hdr) - local_sda;
+ reloc = R_NDS32_GOTOFF;
+ }
+ else if (ELF32_R_TYPE (irel->r_info) == R_NDS32_GOTPC_LO12)
+ {
+ foff = local_sda - sec->output_section->vma + sec->output_offset
+ + irel->r_offset + irel->r_addend;
+ reloc = R_NDS32_GOTPC20;
+ }
+ else
+ return;
+
+ if ((foff < CONSERVATIVE_20BIT) && (foff >= -CONSERVATIVE_20BIT))
+ {
+ /* Turn into MOVI. */
+ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info), reloc);
+ insn = N32_TYPE1 (MOVI, N32_RT5 (insn), 0);
+ bfd_putb32 (insn, contents + laddr);
+ }
+}
+
+/* Relax low part of LE TLS instruction pattern. */
+
+static void
+nds32_elf_relax_letlslo12 (struct bfd_link_info *link_info, bfd *abfd,
+ Elf_Internal_Rela *irel,
+ bfd_byte *contents, Elf_Internal_Sym *isymbuf,
+ Elf_Internal_Shdr *symtab_hdr)
+{
+ uint32_t insn;
+ bfd_vma laddr;
+ bfd_signed_vma foff;
+ unsigned long reloc;
+
+ laddr = irel->r_offset;
+ foff = calculate_memory_address (abfd, irel, isymbuf, symtab_hdr);
+ BFD_ASSERT (elf_hash_table (link_info)->tls_sec != NULL);
+ foff -= (elf_hash_table (link_info)->tls_sec->vma + TP_OFFSET);
+ insn = bfd_getb32 (contents + laddr);
+
+ if ( (bfd_signed_vma) (foff) < CONSERVATIVE_20BIT
+ && (bfd_signed_vma) (foff) >= -CONSERVATIVE_20BIT)
+ {
+ /* Pattern sethi-ori transform to movi. */
+ reloc = R_NDS32_TLS_LE_20;
+ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info), reloc);
+ insn = N32_TYPE1 (MOVI, N32_RT5 (insn), 0);
+ bfd_putb32 (insn, contents + laddr);
+ }
+}
+
+/* Relax LE TLS calculate address instruction pattern. */
+
+static void
+nds32_elf_relax_letlsadd (struct bfd_link_info *link_info, bfd *abfd,
+ asection *sec, Elf_Internal_Rela *irel,
+ Elf_Internal_Rela *internal_relocs,
+ bfd_byte *contents, Elf_Internal_Sym *isymbuf,
+ Elf_Internal_Shdr *symtab_hdr, bfd_boolean *again)
+{
+ /* Local TLS non-pic
+ sethi ta, hi20(symbol@tpoff) ; TLS_LE_HI20
+ ori ta, ta, lo12(symbol@tpoff) ; TLS_LE_LO12
+ add ra, ta, tp ; TLS_LE_ADD */
+
+ uint32_t insn;
+ bfd_vma laddr;
+ bfd_signed_vma foff;
+ Elf_Internal_Rela *i1_irelfn, *irelend;
+
+ irelend = internal_relocs + sec->reloc_count;
+ laddr = irel->r_offset;
+ insn = bfd_getb32 (contents + laddr);
+ i1_irelfn = find_relocs_at_address (irel, internal_relocs, irelend,
+ R_NDS32_PTR_RESOLVED);
+ foff = calculate_memory_address (abfd, irel, isymbuf, symtab_hdr);
+ BFD_ASSERT (elf_hash_table (link_info)->tls_sec != NULL);
+ foff -= (elf_hash_table (link_info)->tls_sec->vma + TP_OFFSET);
+
+ /* The range is +/-16k. */
+ if ((bfd_signed_vma) (foff) < CONSERVATIVE_15BIT
+ && (bfd_signed_vma) (foff) >= -CONSERVATIVE_15BIT)
+ {
+ /* Transform add to addi. */
+ insn = N32_TYPE2 (ADDI, N32_RT5 (insn), N32_RB5 (insn), 0);
+ irel->r_info =
+ ELF32_R_INFO (ELF32_R_SYM (irel->r_info), R_NDS32_TLS_LE_15S0);
+
+ bfd_putb32 (insn, contents + laddr);
+ if (i1_irelfn != irelend)
+ {
+ i1_irelfn->r_addend |= 1;
+ *again = TRUE;
+ }
+ }
+}
+
+/* Relax LE TLS load store instruction pattern. */
+
+static void
+nds32_elf_relax_letlsls (struct bfd_link_info *link_info, bfd *abfd,
+ asection *sec, Elf_Internal_Rela *irel,
+ Elf_Internal_Rela *internal_relocs,
+ bfd_byte *contents, Elf_Internal_Sym *isymbuf,
+ Elf_Internal_Shdr *symtab_hdr, bfd_boolean *again)
+{
+
+ uint32_t insn;
+ bfd_vma laddr;
+ bfd_signed_vma foff;
+ Elf_Internal_Rela *i1_irelfn, *irelend;
+ int success = 0;
+
+ irelend = internal_relocs + sec->reloc_count;
+ laddr = irel->r_offset;
+ insn = bfd_getb32 (contents + laddr);
+ i1_irelfn = find_relocs_at_address (irel, internal_relocs, irelend,
+ R_NDS32_PTR_RESOLVED);
+ foff = calculate_memory_address (abfd, irel, isymbuf, symtab_hdr);
+ BFD_ASSERT (elf_hash_table (link_info)->tls_sec != NULL);
+ foff -= (elf_hash_table (link_info)->tls_sec->vma + TP_OFFSET);
+
+ switch ((N32_OP6 (insn) << 8) | (insn & 0xff))
+ {
+ case (N32_OP6_MEM << 8) | N32_MEM_LB:
+ case (N32_OP6_MEM << 8) | N32_MEM_SB:
+ case (N32_OP6_MEM << 8) | N32_MEM_LBS:
+ /* The range is +/-16k. */
+ if ((bfd_signed_vma) (foff) < CONSERVATIVE_15BIT
+ && (bfd_signed_vma) (foff) >= -CONSERVATIVE_15BIT)
+ {
+ insn =
+ ((insn & 0xff) << 25) | (insn & 0x1f00000) | ((insn & 0x7c00) << 5);
+ irel->r_info =
+ ELF32_R_INFO (ELF32_R_SYM (irel->r_info), R_NDS32_TLS_LE_15S0);
+ success = 1;
+ break;
+ }
+ case (N32_OP6_MEM << 8) | N32_MEM_LH:
+ case (N32_OP6_MEM << 8) | N32_MEM_SH:
+ case (N32_OP6_MEM << 8) | N32_MEM_LHS:
+ /* The range is +/-32k. */
+ if ((bfd_signed_vma) (foff) < CONSERVATIVE_15BIT_S1
+ && (bfd_signed_vma) (foff) >= -CONSERVATIVE_15BIT_S1)
+ {
+ insn =
+ ((insn & 0xff) << 25) | (insn & 0x1f00000) | ((insn & 0x7c00) << 5);
+ irel->r_info =
+ ELF32_R_INFO (ELF32_R_SYM (irel->r_info), R_NDS32_TLS_LE_15S1);
+ success = 1;
+ break;
+ }
+ case (N32_OP6_MEM << 8) | N32_MEM_LW:
+ case (N32_OP6_MEM << 8) | N32_MEM_SW:
+ /* The range is +/-64k. */
+ if ((bfd_signed_vma) (foff) < CONSERVATIVE_15BIT_S2
+ && (bfd_signed_vma) (foff) >= -CONSERVATIVE_15BIT_S2)
+ {
+ insn =
+ ((insn & 0xff) << 25) | (insn & 0x1f00000) | ((insn & 0x7c00) << 5);
+ irel->r_info =
+ ELF32_R_INFO (ELF32_R_SYM (irel->r_info), R_NDS32_TLS_LE_15S2);
+ success = 1;
+ break;
+ }
+ default:
+ break;
+ }
+
+ if (success)
+ {
+ bfd_putb32 (insn, contents + laddr);
+ if (i1_irelfn != irelend)
+ {
+ i1_irelfn->r_addend |= 1;
+ *again = TRUE;
+ }
+ }
+}
+
+/* Relax PTR relocation for nds32_elf_relax_section. */
+
+static bfd_boolean
+nds32_elf_relax_ptr (bfd *abfd, asection *sec, Elf_Internal_Rela *irel,
+ Elf_Internal_Rela *internal_relocs, int *insn_len,
+ int *seq_len, bfd_byte *contents)
+{
+ Elf_Internal_Rela *ptr_irel, *irelend, *count_irel, *re_irel;
+
+ irelend = internal_relocs + sec->reloc_count;
+
+ re_irel =
+ find_relocs_at_address_addr (irel, internal_relocs, irelend,
+ R_NDS32_PTR_RESOLVED, irel->r_addend);
+
+ if (re_irel == irelend)
+ {
+ (*_bfd_error_handler)
+ ("%B: warning: R_NDS32_PTR points to unrecognized reloc at 0x%lx.",
+ abfd, (long) irel->r_offset);
+ return FALSE;
+ }
+
+ if (re_irel->r_addend != 1)
+ return FALSE;
+
+ /* Pointed target is relaxed and no longer needs this void *,
+ change the type to NONE. */
+ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info), R_NDS32_NONE);
+
+ /* Find PTR_COUNT to decide remove it or not. If PTR_COUNT does
+ not exist, it means only count 1 and remove it directly. */
+ /* TODO: I hope we can obsolate R_NDS32_COUNT in the future. */
+ count_irel = find_relocs_at_address (irel, internal_relocs, irelend,
+ R_NDS32_PTR_COUNT);
+ ptr_irel = find_relocs_at_address (irel, internal_relocs, irelend,
+ R_NDS32_PTR);
+ if (count_irel != irelend)
+ {
+ if (--count_irel->r_addend > 0)
+ return FALSE;
+ }
+
+ if (ptr_irel != irelend)
+ return FALSE;
+
+ /* If the PTR_COUNT is already 0, remove current instruction. */
+ *seq_len = nds32_elf_insn_size (abfd, contents, irel->r_offset);
+ *insn_len = 0;
+ return TRUE;
+}
+
+/* Relax PLT_GOT_SUFF relocation for nds32_elf_relax_section. */
+
+static void
+nds32_elf_relax_pltgot_suff (struct bfd_link_info *link_info, bfd *abfd,
+ asection *sec, Elf_Internal_Rela *irel,
+ Elf_Internal_Rela *internal_relocs,
+ bfd_byte *contents, Elf_Internal_Sym *isymbuf,
+ Elf_Internal_Shdr *symtab_hdr, bfd_boolean *again)
+{
+ uint32_t insn;
+ bfd_signed_vma foff;
+ Elf_Internal_Rela *i1_irelfn, *irelend;
+ bfd_vma local_sda, laddr;
+
+ irelend = internal_relocs + sec->reloc_count;
+ laddr = irel->r_offset;
+ insn = bfd_getb32 (contents + laddr);
+
+ /* FIXME: It's a little trouble to turn JRAL5 to JAL since
+ we need additional space. It might be help if we could
+ borrow some space from instructions to be eliminated
+ such as sethi, ori, add. */
+ if (insn & 0x80000000)
+ return;
+
+ if (nds32_elf_check_dup_relocs
+ (irel, internal_relocs, irelend, R_NDS32_PLT_GOT_SUFF))
+ return;
+
+ i1_irelfn =
+ find_relocs_at_address (irel, internal_relocs, irelend,
+ R_NDS32_PTR_RESOLVED);
+
+ /* FIXIT 090606
+ The boundary should be reduced since the .plt section hasn't
+ been created and the address of specific entry is still unknown
+ Maybe the range between the function call and the begin of the
+ .text section can be used to decide if the .plt is in the range
+ of function call. */
+
+ if (N32_OP6 (insn) == N32_OP6_ALU1
+ && N32_SUB5 (insn) == N32_ALU1_ADD)
+ {
+ /* Get the value of the symbol referred to by the reloc. */
+ nds32_elf_final_sda_base (sec->output_section->owner, link_info,
+ &local_sda, FALSE);
+ foff = (bfd_signed_vma) (calculate_plt_memory_address
+ (abfd, link_info, isymbuf, irel,
+ symtab_hdr) - local_sda);
+ /* This condition only happened when symbol is undefined. */
+ if (foff == 0)
+ return;
+
+ if (foff < -CONSERVATIVE_19BIT || foff >= CONSERVATIVE_19BIT)
+ return;
+ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
+ R_NDS32_PLT_GOTREL_LO19);
+ /* addi.gp */
+ insn = N32_TYPE1 (SBGP, N32_RT5 (insn), __BIT (19));
+ }
+ else if (N32_OP6 (insn) == N32_OP6_JREG
+ && N32_SUB5 (insn) == N32_JREG_JRAL)
+ {
+ /* Get the value of the symbol referred to by the reloc. */
+ foff =
+ calculate_plt_offset (abfd, sec, link_info, isymbuf, irel, symtab_hdr);
+ /* This condition only happened when symbol is undefined. */
+ if (foff == 0)
+ return;
+ if (foff < -CONSERVATIVE_24BIT_S1 || foff >= CONSERVATIVE_24BIT_S1)
+ return;
+ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info), R_NDS32_25_PLTREL);
+ insn = INSN_JAL;
+ }
+ else
+ return;
+
+ bfd_putb32 (insn, contents + laddr);
+ if (i1_irelfn != irelend)
+ {
+ i1_irelfn->r_addend |= 1;
+ *again = TRUE;
+ }
+}
+
+/* Relax GOT_SUFF relocation for nds32_elf_relax_section. */
+
+static void
+nds32_elf_relax_got_suff (struct bfd_link_info *link_info, bfd *abfd,
+ asection *sec, Elf_Internal_Rela *irel,
+ Elf_Internal_Rela *internal_relocs,
+ bfd_byte *contents, Elf_Internal_Shdr *symtab_hdr,
+ bfd_boolean *again)
+{
+ uint32_t insn;
+ bfd_signed_vma foff;
+ Elf_Internal_Rela *i1_irelfn, *irelend;
+ bfd_vma local_sda, laddr;
+
+ irelend = internal_relocs + sec->reloc_count;
+ laddr = irel->r_offset;
+ insn = bfd_getb32 (contents + laddr);
+ if (insn & 0x80000000)
+ return;
+
+ if (nds32_elf_check_dup_relocs
+ (irel, internal_relocs, irelend, R_NDS32_GOT_SUFF))
+ return;
+
+ i1_irelfn = find_relocs_at_address (irel, internal_relocs, irelend,
+ R_NDS32_PTR_RESOLVED);
+
+ nds32_elf_final_sda_base (sec->output_section->owner, link_info,
+ &local_sda, FALSE);
+ foff = calculate_got_memory_address (abfd, link_info, irel,
+ symtab_hdr) - local_sda;
+
+ if (foff < CONSERVATIVE_19BIT && foff >= -CONSERVATIVE_19BIT)
+ {
+ /* Turn LW to LWI.GP. Change relocation type to R_NDS32_GOT_REL. */
+ insn = N32_TYPE1 (HWGP, N32_RT5 (insn), __MF (6, 17, 3));
+ irel->r_info =
+ ELF32_R_INFO (ELF32_R_SYM (irel->r_info), R_NDS32_GOT17S2_RELA);
+ bfd_putb32 (insn, contents + laddr);
+ if (i1_irelfn != irelend)
+ {
+ i1_irelfn->r_addend |= 1;
+ *again = TRUE;
+ }
+ }
+}
+
+/* Relax PLT_GOT_SUFF relocation for nds32_elf_relax_section. */
+
+static void
+nds32_elf_relax_gotoff_suff (struct bfd_link_info *link_info, bfd *abfd,
+ asection *sec, Elf_Internal_Rela *irel,
+ Elf_Internal_Rela *internal_relocs,
+ bfd_byte *contents, Elf_Internal_Sym *isymbuf,
+ Elf_Internal_Shdr *symtab_hdr, bfd_boolean *again)
+{
+ int opc_insn_gotoff;
+ uint32_t insn;
+ bfd_signed_vma foff;
+ Elf_Internal_Rela *i1_irelfn, *i2_irelfn, *irelend;
+ bfd_vma local_sda, laddr;
+
+ irelend = internal_relocs + sec->reloc_count;
+ laddr = irel->r_offset;
+ insn = bfd_getb32 (contents + laddr);
+
+ if (insn & 0x80000000)
+ return;
+
+ if (nds32_elf_check_dup_relocs
+ (irel, internal_relocs, irelend, R_NDS32_GOTOFF_SUFF))
+ return;
+
+ i1_irelfn = find_relocs_at_address (irel, internal_relocs, irelend,
+ R_NDS32_PTR_RESOLVED);
+ nds32_elf_final_sda_base (sec->output_section->owner, link_info,
+ &local_sda, FALSE);
+ foff = calculate_memory_address (abfd, irel, isymbuf, symtab_hdr);
+ foff = foff - local_sda;
+
+ if (foff >= CONSERVATIVE_19BIT || foff < -CONSERVATIVE_19BIT)
+ return;
+
+ /* Concatenate opcode and sub-opcode for switch case.
+ It may be MEM or ALU1. */
+ opc_insn_gotoff = (N32_OP6 (insn) << 8) | (insn & 0xff);
+ switch (opc_insn_gotoff)
+ {
+ case (N32_OP6_MEM << 8) | N32_MEM_LW:
+ /* 4-byte aligned. */
+ insn = N32_TYPE1 (HWGP, N32_RT5 (insn), __MF (6, 17, 3));
+ irel->r_info =
+ ELF32_R_INFO (ELF32_R_SYM (irel->r_info), R_NDS32_SDA17S2_RELA);
+ break;
+ case (N32_OP6_MEM << 8) | N32_MEM_SW:
+ insn = N32_TYPE1 (HWGP, N32_RT5 (insn), __MF (7, 17, 3));
+ irel->r_info =
+ ELF32_R_INFO (ELF32_R_SYM (irel->r_info), R_NDS32_SDA17S2_RELA);
+ break;
+ case (N32_OP6_MEM << 8) | N32_MEM_LH:
+ /* 2-byte aligned. */
+ insn = N32_TYPE1 (HWGP, N32_RT5 (insn), 0);
+ irel->r_info =
+ ELF32_R_INFO (ELF32_R_SYM (irel->r_info), R_NDS32_SDA18S1_RELA);
+ break;
+ case (N32_OP6_MEM << 8) | N32_MEM_LHS:
+ insn = N32_TYPE1 (HWGP, N32_RT5 (insn), __BIT (18));
+ irel->r_info =
+ ELF32_R_INFO (ELF32_R_SYM (irel->r_info), R_NDS32_SDA18S1_RELA);
+ break;
+ case (N32_OP6_MEM << 8) | N32_MEM_SH:
+ insn = N32_TYPE1 (HWGP, N32_RT5 (insn), __BIT (19));
+ irel->r_info =
+ ELF32_R_INFO (ELF32_R_SYM (irel->r_info), R_NDS32_SDA18S1_RELA);
+ break;
+ case (N32_OP6_MEM << 8) | N32_MEM_LB:
+ /* 1-byte aligned. */
+ insn = N32_TYPE1 (LBGP, N32_RT5 (insn), 0);
+ irel->r_info =
+ ELF32_R_INFO (ELF32_R_SYM (irel->r_info), R_NDS32_SDA19S0_RELA);
+ break;
+ case (N32_OP6_MEM << 8) | N32_MEM_LBS:
+ insn = N32_TYPE1 (LBGP, N32_RT5 (insn), __BIT (19));
+ irel->r_info =
+ ELF32_R_INFO (ELF32_R_SYM (irel->r_info), R_NDS32_SDA19S0_RELA);
+ break;
+ case (N32_OP6_MEM << 8) | N32_MEM_SB:
+ insn = N32_TYPE1 (SBGP, N32_RT5 (insn), 0);
+ irel->r_info =
+ ELF32_R_INFO (ELF32_R_SYM (irel->r_info), R_NDS32_SDA19S0_RELA);
+ break;
+ case (N32_OP6_ALU1 << 8) | N32_ALU1_ADD:
+ insn = N32_TYPE1 (SBGP, N32_RT5 (insn), __BIT (19));
+ irel->r_info =
+ ELF32_R_INFO (ELF32_R_SYM (irel->r_info), R_NDS32_SDA19S0_RELA);
+ break;
+ default:
+ return;
+ }
+
+ bfd_putb32 (insn, contents + laddr);
+ if (i1_irelfn != irelend)
+ {
+ i1_irelfn->r_addend |= 1;
+ *again = TRUE;
+ }
+ if ((i2_irelfn = find_relocs_at_address (irel, internal_relocs, irelend,
+ R_NDS32_INSN16)) != irelend)
+ i2_irelfn->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info), R_NDS32_NONE);
+
+}
+
+static bfd_boolean
+nds32_relax_adjust_label (bfd *abfd, asection *sec,
+ Elf_Internal_Rela *internal_relocs,
+ bfd_byte *contents,
+ nds32_elf_blank_t **relax_blank_list,
+ int optimize, int opt_size)
+{
+ /* This code block is used to adjust 4-byte alignment by relax a pair
+ of instruction a time.
+
+ It recognizes three types of relocations.
+ 1. R_NDS32_LABEL - a aligment.
+ 2. R_NDS32_INSN16 - relax a 32-bit instruction to 16-bit.
+ 3. is_16bit_NOP () - remove a 16-bit instruction. */
+
+ /* TODO: It seems currently implementation only support 4-byte aligment.
+ We should handle any-aligment. */
+
+ Elf_Internal_Rela *insn_rel = NULL, *label_rel = NULL, *irel;
+ Elf_Internal_Rela *tmp_rel, *tmp2_rel = NULL;
+ Elf_Internal_Rela rel_temp;
+ Elf_Internal_Rela *irelend;
+ bfd_vma address;
+ uint16_t insn16;
+
+ /* Checking for branch relaxation relies on the relocations to
+ be sorted on 'r_offset'. This is not guaranteed so we must sort. */
+ nds32_insertion_sort (internal_relocs, sec->reloc_count,
+ sizeof (Elf_Internal_Rela), compar_reloc);
+
+ irelend = internal_relocs + sec->reloc_count;
+
+ /* Force R_NDS32_LABEL before R_NDS32_INSN16. */
+ /* FIXME: Can we generate the right order in assembler?
+ So we don't have to swapping them here. */
+
+ for (label_rel = internal_relocs, insn_rel = internal_relocs;
+ label_rel < irelend; label_rel++)
+ {
+ if (ELF32_R_TYPE (label_rel->r_info) != R_NDS32_LABEL)
+ continue;
+
+ /* Find the first reloc has the same offset with label_rel. */
+ while (insn_rel < irelend && insn_rel->r_offset < label_rel->r_offset)
+ insn_rel++;
+
+ for (;insn_rel < irelend && insn_rel->r_offset == label_rel->r_offset;
+ insn_rel++)
+ /* Check if there were R_NDS32_INSN16 and R_NDS32_LABEL at the same
+ address. */
+ if (ELF32_R_TYPE (insn_rel->r_info) == R_NDS32_INSN16)
+ break;
+
+ if (insn_rel < irelend && insn_rel->r_offset == label_rel->r_offset
+ && insn_rel < label_rel)
+ {
+ /* Swap the two reloc if the R_NDS32_INSN16 is
+ before R_NDS32_LABEL. */
+ memcpy (&rel_temp, insn_rel, sizeof (Elf_Internal_Rela));
+ memcpy (insn_rel, label_rel, sizeof (Elf_Internal_Rela));
+ memcpy (label_rel, &rel_temp, sizeof (Elf_Internal_Rela));
+ }
+ }
+
+ label_rel = NULL;
+ insn_rel = NULL;
+ /* If there were a sequence of R_NDS32_LABEL end up with .align 2
+ or higher, remove other R_NDS32_LABEL with lower alignment.
+ If an R_NDS32_INSN16 in between R_NDS32_LABELs must be converted,
+ then the R_NDS32_LABEL sequence is broke. */
+ for (tmp_rel = internal_relocs; tmp_rel < irelend; tmp_rel++)
+ {
+ if (ELF32_R_TYPE (tmp_rel->r_info) == R_NDS32_LABEL)
+ {
+ if (label_rel == NULL)
+ {
+ if (tmp_rel->r_addend < 2)
+ label_rel = tmp_rel;
+ continue;
+ }
+ else if (tmp_rel->r_addend > 1)
+ {
+ /* Remove all LABEL relocation from label_rel to tmp_rel
+ including relocations with same offset as tmp_rel. */
+ for (tmp2_rel = label_rel; tmp2_rel < tmp_rel
+ || tmp2_rel->r_offset == tmp_rel->r_offset; tmp2_rel++)
+ {
+ if (ELF32_R_TYPE (tmp2_rel->r_info) == R_NDS32_LABEL
+ && tmp2_rel->r_addend < 2)
+ tmp2_rel->r_info =
+ ELF32_R_INFO (ELF32_R_SYM (tmp2_rel->r_info),
+ R_NDS32_NONE);
+ }
+ label_rel = NULL;
+ }
+ }
+ else if (ELF32_R_TYPE (tmp_rel->r_info) == R_NDS32_INSN16 && label_rel)
+ {
+ /* A new INSN16 which can be converted, so clear label_rel. */
+ if (is_convert_32_to_16 (abfd, sec, tmp_rel, internal_relocs,
+ irelend, &insn16)
+ || is_16bit_NOP (abfd, sec, tmp_rel))
+ label_rel = NULL;
+ }
+ }
+
+ label_rel = NULL;
+ insn_rel = NULL;
+ /* Optimized for speed and nothing has not been relaxed.
+ It's time to align labels.
+ We may convert a 16-bit instruction right before a label to
+ 32-bit, in order to align the label if necessary
+ all reloc entries has been sorted by r_offset. */
+ for (irel = internal_relocs; irel < irelend; irel++)
+ {
+ if (ELF32_R_TYPE (irel->r_info) != R_NDS32_INSN16
+ && ELF32_R_TYPE (irel->r_info) != R_NDS32_LABEL)
+ continue;
+
+ if (ELF32_R_TYPE (irel->r_info) == R_NDS32_INSN16)
+ {
+ /* A new INSN16 found, resize the old one. */
+ if (is_convert_32_to_16
+ (abfd, sec, irel, internal_relocs, irelend, &insn16)
+ || is_16bit_NOP (abfd, sec, irel))
+ {
+ if (insn_rel)
+ {
+ /* Previous INSN16 reloc exists, reduce its
+ size to 16-bit. */
+ if (is_convert_32_to_16 (abfd, sec, insn_rel, internal_relocs,
+ irelend, &insn16))
+ {
+ nds32_elf_write_16 (abfd, contents, insn_rel,
+ internal_relocs, irelend, insn16);
+
+ if (!insert_nds32_elf_blank_recalc_total
+ (relax_blank_list, insn_rel->r_offset + 2, 2))
+ return FALSE;
+ }
+ else if (is_16bit_NOP (abfd, sec, insn_rel))
+ {
+ if (!insert_nds32_elf_blank_recalc_total
+ (relax_blank_list, insn_rel->r_offset, 2))
+ return FALSE;
+ }
+ insn_rel->r_info =
+ ELF32_R_INFO (ELF32_R_SYM (insn_rel->r_info), R_NDS32_NONE);
+ }
+ /* Save the new one for later use. */
+ insn_rel = irel;
+ }
+ else
+ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
+ R_NDS32_NONE);
+ }
+ else if (ELF32_R_TYPE (irel->r_info) == R_NDS32_LABEL)
+ {
+ /* Search for label. */
+ int force_relax = 0;
+
+ /* Label on 16-bit instruction or optimization
+ needless, just reset this reloc. */
+ insn16 = bfd_getb16 (contents + irel->r_offset);
+ if ((irel->r_addend & 0x1f) < 2 && (!optimize || (insn16 & 0x8000)))
+ {
+ irel->r_info =
+ ELF32_R_INFO (ELF32_R_SYM (irel->r_info), R_NDS32_NONE);
+ continue;
+ }
+
+ address =
+ irel->r_offset - get_nds32_elf_blank_total (relax_blank_list,
+ irel->r_offset, 1);
+
+ if (!insn_rel)
+ {
+ /* Check if there is case which can not be aligned. */
+ if (irel->r_addend == 2 && address & 0x2)
+ return FALSE;
+ continue;
+ }
+
+ /* Try to align this label. */
+
+ if ((irel->r_addend & 0x1f) < 2)
+ {
+ /* Check if there is a INSN16 at the same address.
+ Label_rel always seats before insn_rel after
+ our sort. */
+
+ /* Search for INSN16 at LABEL location. If INSN16 is at
+ same location and this LABEL alignment is lower than 2,
+ the INSN16 can be converted to 2-byte. */
+ for (tmp_rel = irel;
+ tmp_rel < irelend && tmp_rel->r_offset == irel->r_offset;
+ tmp_rel++)
+ {
+ if (ELF32_R_TYPE (tmp_rel->r_info) == R_NDS32_INSN16
+ && (is_convert_32_to_16
+ (abfd, sec, tmp_rel, internal_relocs,
+ irelend, &insn16)
+ || is_16bit_NOP (abfd, sec, tmp_rel)))
+ {
+ force_relax = 1;
+ break;
+ }
+ }
+ }
+
+ if (force_relax || irel->r_addend == 1 || address & 0x2)
+ {
+ /* Label not aligned. */
+ /* Previous reloc exists, reduce its size to 16-bit. */
+ if (is_convert_32_to_16 (abfd, sec, insn_rel,
+ internal_relocs, irelend, &insn16))
+ {
+ nds32_elf_write_16 (abfd, contents, insn_rel,
+ internal_relocs, irelend, insn16);
+
+ if (!insert_nds32_elf_blank_recalc_total
+ (relax_blank_list, insn_rel->r_offset + 2, 2))
+ return FALSE;
+ }
+ else if (is_16bit_NOP (abfd, sec, insn_rel))
+ {
+ if (!insert_nds32_elf_blank_recalc_total
+ (relax_blank_list, insn_rel->r_offset, 2))
+ return FALSE;
+ }
+
+ }
+ /* INSN16 reloc is used. */
+ insn_rel = NULL;
+ }
+ }
+
+ address =
+ sec->size - get_nds32_elf_blank_total (relax_blank_list, sec->size, 0);
+ if (insn_rel && (address & 0x2 || opt_size))
+ {
+ if (is_convert_32_to_16 (abfd, sec, insn_rel, internal_relocs,
+ irelend, &insn16))
+ {
+ nds32_elf_write_16 (abfd, contents, insn_rel, internal_relocs,
+ irelend, insn16);
+ if (!insert_nds32_elf_blank_recalc_total
+ (relax_blank_list, insn_rel->r_offset + 2, 2))
+ return FALSE;
+ insn_rel->r_info = ELF32_R_INFO (ELF32_R_SYM (insn_rel->r_info),
+ R_NDS32_NONE);
+ }
+ else if (is_16bit_NOP (abfd, sec, insn_rel))
+ {
+ if (!insert_nds32_elf_blank_recalc_total
+ (relax_blank_list, insn_rel->r_offset, 2))
+ return FALSE;
+ insn_rel->r_info = ELF32_R_INFO (ELF32_R_SYM (insn_rel->r_info),
+ R_NDS32_NONE);
+ }
+ }
+ insn_rel = NULL;
+ return TRUE;
+}
+
+/* Pick relaxation round. */
+
+static int
+nds32_elf_pick_relax (bfd_boolean init, asection *sec, bfd_boolean *again,
+ struct elf_nds32_link_hash_table *table,
+ struct bfd_link_info *link_info)
+{
+ static asection *final_sec;
+ static bfd_boolean set = FALSE;
+ static bfd_boolean first = TRUE;
+ int round_table[] = {
+ NDS32_RELAX_NORMAL_ROUND,
+ NDS32_RELAX_JUMP_IFC_ROUND,
+ NDS32_RELAX_EX9_BUILD_ROUND,
+ NDS32_RELAX_EX9_REPLACE_ROUND,
+ };
+ static int pass = 0;
+ static int relax_round;
+
+ if (first)
+ {
+ /* Run an empty run to get the final section. */
+ relax_round = NDS32_RELAX_EMPTY_ROUND;
+
+ /* It has to enter relax again because we can
+ not make sure what the final turn is. */
+ *again = TRUE;
+ first = FALSE;
+ }
+
+ if (!set && *again)
+ {
+ /* It is reentered when again is FALSE. */
+ final_sec = sec;
+ return relax_round;
+ }
+
+ /* The second round begins. */
+ set = TRUE;
+
+ relax_round = round_table[pass];
+
+ if (!init && final_sec == sec)
+ {
+ switch (relax_round)
+ {
+ case NDS32_RELAX_NORMAL_ROUND:
+ if (!*again)
+ {
+ /* Normal relaxation done. */
+ if (table->target_optimize & NDS32_RELAX_JUMP_IFC_ON)
+ {
+ pass++;
+ *again = TRUE;
+ }
+ else if (table->target_optimize & NDS32_RELAX_EX9_ON)
+ {
+ pass += 2; /* NDS32_RELAX_EX9_BUILD_ROUND */
+ *again = TRUE;
+ }
+ else if (table->ex9_import_file)
+ {
+ /* Import ex9 table. */
+ if (table->update_ex9_table)
+ pass += 2; /* NDS32_RELAX_EX9_BUILD_ROUND */
+ else
+ pass += 3; /* NDS32_RELAX_EX9_REPLACE_ROUND */
+ nds32_elf_ex9_import_table (link_info);
+ *again = TRUE;
+ }
+ }
+ break;
+ case NDS32_RELAX_JUMP_IFC_ROUND:
+ if (!nds32_elf_ifc_finish (link_info))
+ (*_bfd_error_handler) (_("error: Jump IFC Fail."));
+ if (table->target_optimize & NDS32_RELAX_EX9_ON)
+ {
+ pass++;
+ *again = TRUE;
+ }
+ break;
+ case NDS32_RELAX_EX9_BUILD_ROUND:
+ nds32_elf_ex9_finish (link_info);
+ pass++;
+ *again = TRUE;
+ break;
+ case NDS32_RELAX_EX9_REPLACE_ROUND:
+ if (table->target_optimize & NDS32_RELAX_JUMP_IFC_ON)
+ {
+ /* Do jump IFC optimization again. */
+ if (!nds32_elf_ifc_finish (link_info))
+ (*_bfd_error_handler) (_("error: Jump IFC Fail."));
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ return relax_round;
+}
+
+static bfd_boolean
+nds32_elf_relax_section (bfd *abfd, asection *sec,
+ struct bfd_link_info *link_info, bfd_boolean *again)
+{
+ nds32_elf_blank_t *relax_blank_list = NULL;
+ Elf_Internal_Shdr *symtab_hdr;
+ Elf_Internal_Rela *internal_relocs;
+ Elf_Internal_Rela *irel;
+ Elf_Internal_Rela *irelend;
+ Elf_Internal_Sym *isymbuf = NULL;
+ bfd_byte *contents = NULL;
+ bfd_boolean result = TRUE;
+ int optimize = 0;
+ int opt_size = 0;
+ uint32_t insn;
+ uint16_t insn16;
+
+ /* Target dependnet option. */
+ struct elf_nds32_link_hash_table *table;
+ int load_store_relax;
+ int relax_round;
+
+ relax_blank_list = NULL;
+
+ *again = FALSE;
+
+ /* Nothing to do for
+ * relocatable link or
+ * non-relocatable section or
+ * non-code section or
+ * empty content or
+ * no reloc entry. */
+ if (link_info->relocatable
+ || (sec->flags & SEC_RELOC) == 0
+ || (sec->flags & SEC_EXCLUDE) == 1
+ || (sec->flags & SEC_CODE) == 0
+ || sec->size == 0)
+ return TRUE;
+
+ /* 09.12.11 Workaround. */
+ /* We have to adjust align for R_NDS32_LABEL if needed.
+ The adjust approach only can fix 2-byte align once. */
+ if (sec->alignment_power > 2)
+ return TRUE;
+
+ /* The optimization type to do. */
+
+ table = nds32_elf_hash_table (link_info);
+ relax_round = nds32_elf_pick_relax (TRUE, sec, again, table, link_info);
+ switch (relax_round)
+ {
+ case NDS32_RELAX_JUMP_IFC_ROUND:
+ /* Here is the entrance of ifc jump relaxation. */
+ if (!nds32_elf_ifc_calc (link_info, abfd, sec))
+ return FALSE;
+ nds32_elf_pick_relax (FALSE, sec, again, table, link_info);
+ return TRUE;
+
+ case NDS32_RELAX_EX9_BUILD_ROUND:
+ /* Here is the entrance of ex9 relaxation. There are two pass of
+ ex9 relaxation. The one is to traverse all instructions and build
+ the hash table. The other one is to compare instructions and replace
+ it by ex9.it. */
+ if (!nds32_elf_ex9_build_hash_table (abfd, sec, link_info))
+ return FALSE;
+ nds32_elf_pick_relax (FALSE, sec, again, table, link_info);
+ return TRUE;
+
+ case NDS32_RELAX_EX9_REPLACE_ROUND:
+ if (!nds32_elf_ex9_replace_instruction (link_info, abfd, sec))
+ return FALSE;
+ return TRUE;
+
+ case NDS32_RELAX_EMPTY_ROUND:
+ nds32_elf_pick_relax (FALSE, sec, again, table, link_info);
+ return TRUE;
+
+ case NDS32_RELAX_NORMAL_ROUND:
+ default:
+ if (sec->reloc_count == 0)
+ return TRUE;
+ break;
+ }
+
+ /* The begining of general relaxation. */
+
+ if (is_SDA_BASE_set == 0)
+ {
+ bfd_vma gp;
+ is_SDA_BASE_set = 1;
+ nds32_elf_final_sda_base (sec->output_section->owner, link_info,
+ &gp, FALSE);
+ relax_range_measurement (abfd);
+ }
+
+ if (is_ITB_BASE_set == 0)
+ {
+ /* Set the _ITB_BASE_. */
+ if (!nds32_elf_ex9_itb_base (link_info))
+ {
+ (*_bfd_error_handler) (_("%B: error: Cannot set _ITB_BASE_"), abfd);
+ bfd_set_error (bfd_error_bad_value);
+ }
+ }
+
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+ /* Relocations MUST be kept in memory, because relaxation adjust them. */
+ internal_relocs = _bfd_elf_link_read_relocs (abfd, sec, NULL, NULL,
+ TRUE /* keep_memory */);
+ if (internal_relocs == NULL)
+ goto error_return;
+
+ irelend = internal_relocs + sec->reloc_count;
+ irel = find_relocs_at_address (internal_relocs, internal_relocs,
+ irelend, R_NDS32_RELAX_ENTRY);
+
+ if (irel == irelend)
+ return TRUE;
+
+ if (ELF32_R_TYPE (irel->r_info) == R_NDS32_RELAX_ENTRY)
+ {
+ if (irel->r_addend & R_NDS32_RELAX_ENTRY_DISABLE_RELAX_FLAG)
+ return TRUE;
+
+ if (irel->r_addend & R_NDS32_RELAX_ENTRY_OPTIMIZE_FLAG)
+ optimize = 1;
+
+ if (irel->r_addend & R_NDS32_RELAX_ENTRY_OPTIMIZE_FOR_SPACE_FLAG)
+ opt_size = 1;
+ }
+
+ load_store_relax = table->load_store_relax;
+
+ /* Get symbol table and section content. */
+ if (!nds32_get_section_contents (abfd, sec, &contents)
+ || !nds32_get_local_syms (abfd, sec, &isymbuf))
+ goto error_return;
+
+ /* Do relax loop only when finalize is not done.
+ Take care of relaxable relocs except INSN16. */
+ for (irel = internal_relocs; irel < irelend; irel++)
+ {
+ int seq_len; /* Original length of instruction sequence. */
+ int insn_len = 0; /* Final length of instruction sequence. */
+ bfd_boolean removed;
+
+ insn = 0;
+ if (ELF32_R_TYPE (irel->r_info) == R_NDS32_LABEL
+ && (irel->r_addend & 0x1f) >= 2)
+ optimize = 1;
+
+ /* Relocation Types
+ R_NDS32_LONGCALL1 53
+ R_NDS32_LONGCALL2 54
+ R_NDS32_LONGCALL3 55
+ R_NDS32_LONGJUMP1 56
+ R_NDS32_LONGJUMP2 57
+ R_NDS32_LONGJUMP3 58
+ R_NDS32_LOADSTORE 59 */
+ if (ELF32_R_TYPE (irel->r_info) >= R_NDS32_LONGCALL1
+ && ELF32_R_TYPE (irel->r_info) <= R_NDS32_LOADSTORE)
+ seq_len = GET_SEQ_LEN (irel->r_addend);
+
+ /* Relocation Types
+ R_NDS32_LONGCALL4 107
+ R_NDS32_LONGCALL5 108
+ R_NDS32_LONGCALL6 109
+ R_NDS32_LONGJUMP4 110
+ R_NDS32_LONGJUMP5 111
+ R_NDS32_LONGJUMP6 112
+ R_NDS32_LONGJUMP7 113 */
+ else if (ELF32_R_TYPE (irel->r_info) >= R_NDS32_LONGCALL4
+ && ELF32_R_TYPE (irel->r_info) <= R_NDS32_LONGJUMP7)
+ seq_len = 4;
+
+ /* Relocation Types
+ R_NDS32_LO12S0_RELA 30
+ R_NDS32_LO12S1_RELA 29
+ R_NDS32_LO12S2_RELA 28
+ R_NDS32_LO12S2_SP_RELA 71
+ R_NDS32_LO12S2_DP_RELA 70
+ R_NDS32_GOT_LO12 46
+ R_NDS32_GOTOFF_LO12 50
+ R_NDS32_PLTREL_LO12 65
+ R_NDS32_PLT_GOTREL_LO12 67
+ R_NDS32_17IFC_PCREL_RELA 96
+ R_NDS32_GOT_SUFF 193
+ R_NDS32_GOTOFF_SUFF 194
+ R_NDS32_PLT_GOT_SUFF 195
+ R_NDS32_MULCALL_SUFF 196
+ R_NDS32_PTR 197 */
+ else if ((ELF32_R_TYPE (irel->r_info) <= R_NDS32_LO12S0_RELA
+ && ELF32_R_TYPE (irel->r_info) >= R_NDS32_LO12S2_RELA)
+ || ELF32_R_TYPE (irel->r_info) == R_NDS32_LO12S2_SP_RELA
+ || ELF32_R_TYPE (irel->r_info) == R_NDS32_LO12S2_DP_RELA
+ || ELF32_R_TYPE (irel->r_info) == R_NDS32_GOT_LO12
+ || ELF32_R_TYPE (irel->r_info) == R_NDS32_GOTOFF_LO12
+ || ELF32_R_TYPE (irel->r_info) == R_NDS32_GOTPC_LO12
+ || ELF32_R_TYPE (irel->r_info) == R_NDS32_PLTREL_LO12
+ || ELF32_R_TYPE (irel->r_info) == R_NDS32_PLT_GOTREL_LO12
+ || (ELF32_R_TYPE (irel->r_info) >= R_NDS32_GOT_SUFF
+ && ELF32_R_TYPE (irel->r_info) <= R_NDS32_PTR)
+ || ELF32_R_TYPE (irel->r_info) == R_NDS32_17IFC_PCREL_RELA
+ || ELF32_R_TYPE (irel->r_info) == R_NDS32_TLS_LE_LO12
+ || ELF32_R_TYPE (irel->r_info) == R_NDS32_TLS_LE_ADD
+ || ELF32_R_TYPE (irel->r_info) == R_NDS32_TLS_LE_LS)
+ seq_len = 0;
+ else
+ continue;
+
+ insn_len = seq_len;
+ removed = FALSE;
+
+ switch (ELF32_R_TYPE (irel->r_info))
+ {
+ case R_NDS32_LONGCALL1:
+ removed = nds32_elf_relax_longcall1 (abfd, sec, irel, internal_relocs,
+ &insn_len, contents, isymbuf,
+ symtab_hdr);
+ break;
+ case R_NDS32_LONGCALL2:
+ removed = nds32_elf_relax_longcall2 (abfd, sec, irel, internal_relocs,
+ &insn_len, contents, isymbuf,
+ symtab_hdr);
+ break;
+ case R_NDS32_LONGCALL3:
+ removed = nds32_elf_relax_longcall3 (abfd, sec, irel, internal_relocs,
+ &insn_len, contents, isymbuf,
+ symtab_hdr);
+ break;
+ case R_NDS32_LONGJUMP1:
+ removed = nds32_elf_relax_longjump1 (abfd, sec, irel, internal_relocs,
+ &insn_len, contents, isymbuf,
+ symtab_hdr);
+ break;
+ case R_NDS32_LONGJUMP2:
+ removed = nds32_elf_relax_longjump2 (abfd, sec, irel, internal_relocs,
+ &insn_len, contents, isymbuf,
+ symtab_hdr);
+ break;
+ case R_NDS32_LONGJUMP3:
+ removed = nds32_elf_relax_longjump3 (abfd, sec, irel, internal_relocs,
+ &insn_len, contents, isymbuf,
+ symtab_hdr);
+ break;
+ case R_NDS32_LONGCALL4:
+ removed = nds32_elf_relax_longcall4 (abfd, sec, irel, internal_relocs,
+ &insn_len, contents, isymbuf,
+ symtab_hdr);
+ break;
+ case R_NDS32_LONGCALL5:
+ removed = nds32_elf_relax_longcall5 (abfd, sec, irel, internal_relocs,
+ &insn_len, contents, isymbuf,
+ symtab_hdr);
+ break;
+ case R_NDS32_LONGCALL6:
+ removed = nds32_elf_relax_longcall6 (abfd, sec, irel, internal_relocs,
+ &insn_len, contents, isymbuf,
+ symtab_hdr);
+ break;
+ case R_NDS32_LONGJUMP4:
+ removed = nds32_elf_relax_longjump4 (abfd, sec, irel, internal_relocs,
+ &insn_len, contents, isymbuf,
+ symtab_hdr);
+ break;
+ case R_NDS32_LONGJUMP5:
+ removed = nds32_elf_relax_longjump5 (abfd, sec, irel, internal_relocs,
+ &insn_len, &seq_len, contents,
+ isymbuf, symtab_hdr);
+ break;
+ case R_NDS32_LONGJUMP6:
+ removed = nds32_elf_relax_longjump6 (abfd, sec, irel, internal_relocs,
+ &insn_len, &seq_len, contents,
+ isymbuf, symtab_hdr);
+ break;
+ case R_NDS32_LONGJUMP7:
+ removed = nds32_elf_relax_longjump7 (abfd, sec, irel, internal_relocs,
+ &insn_len, &seq_len, contents,
+ isymbuf, symtab_hdr);
+ break;
+ case R_NDS32_LOADSTORE:
+ removed = nds32_elf_relax_loadstore (link_info, abfd, sec, irel,
+ internal_relocs, &insn_len,
+ contents, isymbuf, symtab_hdr,
+ load_store_relax);
+ break;
+ case R_NDS32_LO12S0_RELA:
+ case R_NDS32_LO12S1_RELA:
+ case R_NDS32_LO12S2_DP_RELA:
+ case R_NDS32_LO12S2_SP_RELA:
+ case R_NDS32_LO12S2_RELA:
+ /* Relax for low part. */
+ nds32_elf_relax_lo12 (link_info, abfd, sec, irel, internal_relocs,
+ contents, isymbuf, symtab_hdr);
+
+ /* It is impossible to delete blank, so just continue. */
+ continue;
+ case R_NDS32_GOT_LO12:
+ case R_NDS32_GOTOFF_LO12:
+ case R_NDS32_PLTREL_LO12:
+ case R_NDS32_PLT_GOTREL_LO12:
+ case R_NDS32_GOTPC_LO12:
+ /* Relax for PIC gp-relative low part. */
+ nds32_elf_relax_piclo12 (link_info, abfd, sec, irel, contents,
+ isymbuf, symtab_hdr);
+
+ /* It is impossible to delete blank, so just continue. */
+ continue;
+ case R_NDS32_TLS_LE_LO12:
+ /* Relax for LE TLS low part. */
+ nds32_elf_relax_letlslo12 (link_info, abfd, irel, contents,
+ isymbuf, symtab_hdr);
+
+ /* It is impossible to delete blank, so just continue. */
+ continue;
+ case R_NDS32_TLS_LE_ADD:
+ nds32_elf_relax_letlsadd (link_info, abfd, sec, irel, internal_relocs,
+ contents, isymbuf, symtab_hdr, again);
+ /* It is impossible to delete blank, so just continue. */
+ continue;
+ case R_NDS32_TLS_LE_LS:
+ nds32_elf_relax_letlsls (link_info, abfd, sec, irel, internal_relocs,
+ contents, isymbuf, symtab_hdr, again);
+ continue;
+ case R_NDS32_PTR:
+ removed = nds32_elf_relax_ptr (abfd, sec, irel, internal_relocs,
+ &insn_len, &seq_len, contents);
+ break;
+ case R_NDS32_PLT_GOT_SUFF:
+ nds32_elf_relax_pltgot_suff (link_info, abfd, sec, irel,
+ internal_relocs, contents,
+ isymbuf, symtab_hdr, again);
+ /* It is impossible to delete blank, so just continue. */
+ continue;
+ case R_NDS32_GOT_SUFF:
+ nds32_elf_relax_got_suff (link_info, abfd, sec, irel,
+ internal_relocs, contents,
+ symtab_hdr, again);
+ /* It is impossible to delete blank, so just continue. */
+ continue;
+ case R_NDS32_GOTOFF_SUFF:
+ nds32_elf_relax_gotoff_suff (link_info, abfd, sec, irel,
+ internal_relocs, contents,
+ isymbuf, symtab_hdr, again);
+ /* It is impossible to delete blank, so just continue. */
+ continue;
+ default:
+ continue;
+
+ }
+ if (removed && seq_len - insn_len > 0)
+ {
+ if (!insert_nds32_elf_blank
+ (&relax_blank_list, irel->r_offset + insn_len,
+ seq_len - insn_len))
+ goto error_return;
+ *again = TRUE;
+ }
+ }
+
+ calc_nds32_blank_total (relax_blank_list);
+
+ if (table->relax_fp_as_gp)
+ {
+ if (!nds32_relax_fp_as_gp (link_info, abfd, sec, internal_relocs,
+ irelend, isymbuf))
+ goto error_return;
+
+ if (*again == FALSE)
+ {
+ if (!nds32_fag_remove_unused_fpbase (abfd, sec, internal_relocs,
+ irelend))
+ goto error_return;
+ }
+ }
+
+ nds32_elf_pick_relax (FALSE, sec, again, table, link_info);
+
+ if (*again == FALSE)
+ {
+ if (!nds32_relax_adjust_label (abfd, sec, internal_relocs, contents,
+ &relax_blank_list, optimize, opt_size))
+ goto error_return;
+ }
+
+ /* It doesn't matter optimize_for_space_no_align anymore.
+ If object file is assembled with flag '-Os',
+ the we don't adjust jump-destination on 4-byte boundary. */
+
+ if (relax_blank_list)
+ {
+ nds32_elf_relax_delete_blanks (abfd, sec, relax_blank_list);
+ relax_blank_list = NULL;
+ }
+
+ if (*again == FALSE)
+ {
+ /* Closing the section, so we don't relax it anymore. */
+ bfd_vma sec_size_align;
+ Elf_Internal_Rela *tmp_rel;
+
+ /* Pad to alignment boundary. Only handle current section alignment. */
+ sec_size_align = (sec->size + (~((-1) << sec->alignment_power)))
+ & ((-1) << sec->alignment_power);
+ if ((sec_size_align - sec->size) & 0x2)
+ {
+ insn16 = NDS32_NOP16;
+ bfd_putb16 (insn16, contents + sec->size);
+ sec->size += 2;
+ }
+
+ while (sec_size_align != sec->size)
+ {
+ insn = NDS32_NOP32;
+ bfd_putb32 (insn, contents + sec->size);
+ sec->size += 4;
+ }
+
+ tmp_rel = find_relocs_at_address (internal_relocs, internal_relocs,
+ irelend, R_NDS32_RELAX_ENTRY);
+ if (tmp_rel != irelend)
+ tmp_rel->r_addend |= R_NDS32_RELAX_ENTRY_DISABLE_RELAX_FLAG;
+
+ clean_nds32_elf_blank ();
+ }
+
+finish:
+ if (internal_relocs != NULL
+ && elf_section_data (sec)->relocs != internal_relocs)
+ free (internal_relocs);
+
+ if (contents != NULL
+ && elf_section_data (sec)->this_hdr.contents != contents)
+ free (contents);
+
+ if (isymbuf != NULL && symtab_hdr->contents != (bfd_byte *) isymbuf)
+ free (isymbuf);
+
+ return result;
+
+error_return:
+ result = FALSE;
+ goto finish;
+}
+
+static struct bfd_elf_special_section const nds32_elf_special_sections[] =
+{
+ {".sdata", 6, -2, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE},
+ {".sbss", 5, -2, SHT_NOBITS, SHF_ALLOC + SHF_WRITE},
+ {NULL, 0, 0, 0, 0}
+};
+
+static bfd_boolean
+nds32_elf_output_arch_syms (bfd *output_bfd ATTRIBUTE_UNUSED,
+ struct bfd_link_info *info,
+ void *finfo ATTRIBUTE_UNUSED,
+ bfd_boolean (*func) (void *, const char *,
+ Elf_Internal_Sym *,
+ asection *,
+ struct elf_link_hash_entry *)
+ ATTRIBUTE_UNUSED)
+{
+ FILE *sym_ld_script = NULL;
+ struct elf_nds32_link_hash_table *table;
+
+ table = nds32_elf_hash_table (info);
+ sym_ld_script = table->sym_ld_script;
+
+ if (check_start_export_sym)
+ fprintf (sym_ld_script, "}\n");
+
+ return TRUE;
+}
+
+static enum elf_reloc_type_class
+nds32_elf_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ const asection *rel_sec ATTRIBUTE_UNUSED,
+ const Elf_Internal_Rela *rela)
+{
+ switch ((int) ELF32_R_TYPE (rela->r_info))
+ {
+ case R_NDS32_RELATIVE:
+ return reloc_class_relative;
+ case R_NDS32_JMP_SLOT:
+ return reloc_class_plt;
+ case R_NDS32_COPY:
+ return reloc_class_copy;
+ default:
+ return reloc_class_normal;
+ }
+}
+
+/* Put target dependent option into info hash table. */
+void
+bfd_elf32_nds32_set_target_option (struct bfd_link_info *link_info,
+ int relax_fp_as_gp,
+ int eliminate_gc_relocs,
+ FILE * sym_ld_script, int load_store_relax,
+ int target_optimize, int relax_status,
+ int relax_round, FILE * ex9_export_file,
+ FILE * ex9_import_file,
+ int update_ex9_table, int ex9_limit,
+ bfd_boolean ex9_loop_aware,
+ bfd_boolean ifc_loop_aware)
+{
+ struct elf_nds32_link_hash_table *table;
+
+ table = nds32_elf_hash_table (link_info);
+ if (table == NULL)
+ return;
+
+ table->relax_fp_as_gp = relax_fp_as_gp;
+ table->eliminate_gc_relocs = eliminate_gc_relocs;
+ table->sym_ld_script = sym_ld_script;
+ table ->load_store_relax = load_store_relax;
+ table->target_optimize = target_optimize;
+ table->relax_status = relax_status;
+ table->relax_round = relax_round;
+ table->ex9_export_file = ex9_export_file;
+ table->ex9_import_file = ex9_import_file;
+ table->update_ex9_table = update_ex9_table;
+ table->ex9_limit = ex9_limit;
+ table->ex9_loop_aware = ex9_loop_aware;
+ table->ifc_loop_aware = ifc_loop_aware;
+}
+
+/* These functions and data-structures are used for fp-as-gp
+ optimization. */
+
+#define FAG_THRESHOLD 3 /* At least 3 gp-access. */
+/* lwi37.fp covers 508 bytes, but there may be 32-byte padding between
+ the read-only section and read-write section. */
+#define FAG_WINDOW (508 - 32)
+
+/* An nds32_fag represent a gp-relative access.
+ We find best fp-base by using a sliding window
+ to find a base address which can cover most gp-access. */
+struct nds32_fag
+{
+ struct nds32_fag *next; /* NULL-teminated linked list. */
+ bfd_vma addr; /* The address of this fag. */
+ Elf_Internal_Rela **relas; /* The relocations associated with this fag.
+ It is used for applying FP7U2_FLAG. */
+ int count; /* How many times this address is referred.
+ There should be exactly `count' relocations
+ in relas. */
+ int relas_capcity; /* The buffer size of relas.
+ We use an array instead of linked-list,
+ and realloc is used to adjust buffer size. */
+};
+
+static void
+nds32_fag_init (struct nds32_fag *head)
+{
+ memset (head, 0, sizeof (struct nds32_fag));
+}
+
+static void
+nds32_fag_verify (struct nds32_fag *head)
+{
+ struct nds32_fag *iter;
+ struct nds32_fag *prev;
+
+ prev = NULL;
+ iter = head->next;
+ while (iter)
+ {
+ if (prev && prev->addr >= iter->addr)
+ puts ("Bug in fp-as-gp insertion.");
+ prev = iter;
+ iter = iter->next;
+ }
+}
+
+/* Insert a fag in ascending order.
+ If a fag of the same address already exists,
+ they are chained by relas array. */
+
+static void
+nds32_fag_insert (struct nds32_fag *head, bfd_vma addr,
+ Elf_Internal_Rela * rel)
+{
+ struct nds32_fag *iter;
+ struct nds32_fag *new_fag;
+ const int INIT_RELAS_CAP = 4;
+
+ for (iter = head;
+ iter->next && iter->next->addr <= addr;
+ iter = iter->next)
+ /* Find somewhere to insert. */ ;
+
+ /* `iter' will be equal to `head' if the list is empty. */
+ if (iter != head && iter->addr == addr)
+ {
+ /* The address exists in the list.
+ Insert `rel' into relocation list, relas. */
+
+ /* Check whether relas is big enough. */
+ if (iter->count >= iter->relas_capcity)
+ {
+ iter->relas_capcity *= 2;
+ iter->relas = bfd_realloc
+ (iter->relas, iter->relas_capcity * sizeof (void *));
+ }
+ iter->relas[iter->count++] = rel;
+ return;
+ }
+
+ /* This is a new address. Create a fag node for it. */
+ new_fag = bfd_malloc (sizeof (struct nds32_fag));
+ memset (new_fag, 0, sizeof (*new_fag));
+ new_fag->addr = addr;
+ new_fag->count = 1;
+ new_fag->next = iter->next;
+ new_fag->relas_capcity = INIT_RELAS_CAP;
+ new_fag->relas = (Elf_Internal_Rela **)
+ bfd_malloc (new_fag->relas_capcity * sizeof (void *));
+ new_fag->relas[0] = rel;
+ iter->next = new_fag;
+
+ nds32_fag_verify (head);
+}
+
+static void
+nds32_fag_free_list (struct nds32_fag *head)
+{
+ struct nds32_fag *iter;
+
+ iter = head->next;
+ while (iter)
+ {
+ struct nds32_fag *tmp = iter;
+ iter = iter->next;
+ free (tmp->relas);
+ tmp->relas = NULL;
+ free (tmp);
+ }
+}
+
+/* Find the best fp-base address.
+ The relocation associated with that address is returned,
+ so we can track the symbol instead of a fixed address.
+
+ When relaxation, the address of an datum may change,
+ because a text section is shrinked, so the data section
+ moves forward. If the aligments of text and data section
+ are different, their distance may change too.
+ Therefore, tracking a fixed address is not appriate. */
+
+static int
+nds32_fag_find_base (struct nds32_fag *head, struct nds32_fag **bestpp)
+{
+ struct nds32_fag *base; /* First fag in the window. */
+ struct nds32_fag *last; /* First fag outside the window. */
+ int accu = 0; /* Usage accumulation. */
+ struct nds32_fag *best; /* Best fag. */
+ int baccu = 0; /* Best accumulation. */
+
+ /* Use first fag for initial, and find the last fag in the window.
+
+ In each iteration, we could simply subtract previous fag
+ and accumulate following fags which are inside the window,
+ untill we each the end. */
+
+ if (head->next == NULL)
+ {
+ *bestpp = NULL;
+ return 0;
+ }
+
+ /* Initialize base. */
+ base = head->next;
+ best = base;
+ for (last = base;
+ last && last->addr < base->addr + FAG_WINDOW;
+ last = last->next)
+ accu += last->count;
+
+ baccu = accu;
+
+ /* Record the best base in each iteration. */
+ while (base->next)
+ {
+ accu -= base->count;
+ base = base->next;
+ /* Account fags in window. */
+ for (/* Nothing. */;
+ last && last->addr < base->addr + FAG_WINDOW;
+ last = last->next)
+ accu += last->count;
+
+ /* A better fp-base? */
+ if (accu > baccu)
+ {
+ best = base;
+ baccu = accu;
+ }
+ }
+
+ if (bestpp)
+ *bestpp = best;
+ return baccu;
+}
+
+/* Apply R_NDS32_INSN16_FP7U2_FLAG on gp-relative accesses,
+ so we can convert it fo fp-relative access later.
+ `best_fag' is the best fp-base. Only those inside the window
+ of best_fag is applied the flag. */
+
+static bfd_boolean
+nds32_fag_mark_relax (struct bfd_link_info *link_info,
+ bfd *abfd, struct nds32_fag *best_fag,
+ Elf_Internal_Rela *internal_relocs,
+ Elf_Internal_Rela *irelend)
+{
+ struct nds32_fag *ifag;
+ bfd_vma best_fpbase, gp;
+ bfd *output_bfd;
+
+ output_bfd = abfd->sections->output_section->owner;
+ nds32_elf_final_sda_base (output_bfd, link_info, &gp, FALSE);
+ best_fpbase = best_fag->addr;
+
+ if (best_fpbase > gp + sdata_range[1][1]
+ || best_fpbase < gp - sdata_range[1][0])
+ return FALSE;
+
+ /* Mark these inside the window R_NDS32_INSN16_FP7U2_FLAG flag,
+ so we know they can be converted to lwi37.fp. */
+ for (ifag = best_fag;
+ ifag && ifag->addr < best_fpbase + FAG_WINDOW; ifag = ifag->next)
+ {
+ int i;
+
+ for (i = 0; i < ifag->count; i++)
+ {
+ Elf_Internal_Rela *insn16_rel;
+ Elf_Internal_Rela *fag_rel;
+
+ fag_rel = ifag->relas[i];
+
+ /* Only if this is within the WINDOWS, FP7U2_FLAG
+ is applied. */
+
+ insn16_rel = find_relocs_at_address
+ (fag_rel, internal_relocs, irelend, R_NDS32_INSN16);
+
+ if (insn16_rel != irelend)
+ insn16_rel->r_addend = R_NDS32_INSN16_FP7U2_FLAG;
+ }
+ }
+ return TRUE;
+}
+
+/* Reset INSN16 to clean fp as gp. */
+
+static void
+nds32_fag_unmark_relax (struct nds32_fag *fag,
+ Elf_Internal_Rela *internal_relocs,
+ Elf_Internal_Rela *irelend)
+{
+ struct nds32_fag *ifag;
+ int i;
+ Elf_Internal_Rela *insn16_rel;
+ Elf_Internal_Rela *fag_rel;
+
+ for (ifag = fag; ifag; ifag = ifag->next)
+ {
+ for (i = 0; i < ifag->count; i++)
+ {
+ fag_rel = ifag->relas[i];
+
+ /* Restore the INSN16 relocation. */
+ insn16_rel = find_relocs_at_address
+ (fag_rel, internal_relocs, irelend, R_NDS32_INSN16);
+
+ if (insn16_rel != irelend)
+ insn16_rel->r_addend &= ~R_NDS32_INSN16_FP7U2_FLAG;
+ }
+ }
+}
+
+/* This is the main function of fp-as-gp optimization.
+ It should be called by relax_section. */
+
+static bfd_boolean
+nds32_relax_fp_as_gp (struct bfd_link_info *link_info,
+ bfd *abfd, asection *sec,
+ Elf_Internal_Rela *internal_relocs,
+ Elf_Internal_Rela *irelend,
+ Elf_Internal_Sym *isymbuf)
+{
+ Elf_Internal_Rela *begin_rel = NULL;
+ Elf_Internal_Rela *irel;
+ struct nds32_fag fag_head;
+ Elf_Internal_Shdr *symtab_hdr;
+ bfd_byte *contents;
+ bfd_boolean ifc_inside = FALSE;
+
+ /* FIXME: Can we bfd_elf_link_read_relocs for the relocs? */
+
+ /* Per-function fp-base selection.
+ 1. Create a list for all the gp-relative access.
+ 2. Base on those gp-relative address,
+ find a fp-base which can cover most access.
+ 3. Use the fp-base for fp-as-gp relaxation.
+
+ NOTE: If fp-as-gp is not worth to do, (e.g., less than 3 times),
+ we should
+ 1. delete the `la $fp, _FP_BASE_' instruction and
+ 2. not convert lwi.gp to lwi37.fp.
+
+ To delete the _FP_BASE_ instruction, we simply apply
+ R_NDS32_RELAX_REGION_NOT_OMIT_FP_FLAG flag in the r_addend to disable it.
+
+ To suppress the conversion, we simply NOT to apply
+ R_NDS32_INSN16_FP7U2_FLAG flag. */
+
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+
+ if (!nds32_get_section_contents (abfd, sec, &contents)
+ || !nds32_get_local_syms (abfd, sec, &isymbuf))
+ return FALSE;
+
+ /* Check whether it is worth for fp-as-gp optimization,
+ i.e., at least 3 gp-load.
+
+ Set R_NDS32_RELAX_REGION_NOT_OMIT_FP_FLAG if we should NOT
+ apply this optimization. */
+
+ for (irel = internal_relocs; irel < irelend; irel++)
+ {
+ /* We recognize R_NDS32_RELAX_REGION_BEGIN/_END for the region.
+ One we enter the begin of the region, we track all the LW/ST
+ instructions, so when we leave the region, we try to find
+ the best fp-base address for those LW/ST instructions. */
+
+ if (ELF32_R_TYPE (irel->r_info) == R_NDS32_RELAX_REGION_BEGIN
+ && (irel->r_addend & R_NDS32_RELAX_REGION_OMIT_FP_FLAG))
+ {
+ /* Begin of the region. */
+ if (begin_rel)
+ (*_bfd_error_handler) (_("%B: Nested OMIT_FP in %A."), abfd, sec);
+
+ begin_rel = irel;
+ nds32_fag_init (&fag_head);
+ ifc_inside = FALSE;
+ }
+ else if (ELF32_R_TYPE (irel->r_info) == R_NDS32_RELAX_REGION_END
+ && (irel->r_addend & R_NDS32_RELAX_REGION_OMIT_FP_FLAG))
+ {
+ int accu;
+ struct nds32_fag *best_fag, *tmp_fag;
+ int dist;
+
+ /* End of the region.
+ Check whether it is worth to do fp-as-gp. */
+
+ if (begin_rel == NULL)
+ {
+ (*_bfd_error_handler) (_("%B: Unmatched OMIT_FP in %A."), abfd, sec);
+ continue;
+ }
+
+ accu = nds32_fag_find_base (&fag_head, &best_fag);
+
+ /* Clean FP7U2_FLAG because they may set ever. */
+ tmp_fag = fag_head.next;
+ nds32_fag_unmark_relax (tmp_fag, internal_relocs, irelend);
+
+ /* Check if it is worth, and FP_BASE is near enough to SDA_BASE. */
+ if (accu < FAG_THRESHOLD
+ || !nds32_fag_mark_relax (link_info, abfd, best_fag,
+ internal_relocs, irelend))
+ {
+ /* Not worth to do fp-as-gp. */
+ begin_rel->r_addend |= R_NDS32_RELAX_REGION_NOT_OMIT_FP_FLAG;
+ begin_rel->r_addend &= ~R_NDS32_RELAX_REGION_OMIT_FP_FLAG;
+ irel->r_addend |= R_NDS32_RELAX_REGION_NOT_OMIT_FP_FLAG;
+ irel->r_addend &= ~R_NDS32_RELAX_REGION_OMIT_FP_FLAG;
+ nds32_fag_free_list (&fag_head);
+ begin_rel = NULL;
+ continue;
+ }
+
+ /* R_SYM of R_NDS32_RELAX_REGION_BEGIN is not used by assembler,
+ so we use it to record the distance to the reloction of best
+ fp-base. */
+ dist = best_fag->relas[0] - begin_rel;
+ BFD_ASSERT (dist > 0 && dist < 0xffffff);
+ /* Use high 16 bits of addend to record the _FP_BASE_ matched
+ relocation. And get the base value when relocating. */
+ begin_rel->r_addend &= (0x1 << 16) - 1;
+ begin_rel->r_addend |= dist << 16;
+
+ nds32_fag_free_list (&fag_head);
+ begin_rel = NULL;
+ }
+
+ if (begin_rel == NULL || ifc_inside)
+ /* Skip if we are not in the region of fp-as-gp. */
+ continue;
+
+ if (ELF32_R_TYPE (irel->r_info) == R_NDS32_SDA15S2_RELA
+ || ELF32_R_TYPE (irel->r_info) == R_NDS32_SDA17S2_RELA)
+ {
+ bfd_vma addr;
+ uint32_t insn;
+
+ /* A gp-relative access is found. Insert it to the fag-list. */
+
+ /* Rt is necessary an RT3, so it can be converted to lwi37.fp. */
+ insn = bfd_getb32 (contents + irel->r_offset);
+ if (!N32_IS_RT3 (insn))
+ continue;
+
+ addr = calculate_memory_address (abfd, irel, isymbuf, symtab_hdr);
+ nds32_fag_insert (&fag_head, addr, irel);
+ }
+ else if (ELF32_R_TYPE (irel->r_info) == R_NDS32_SDA_FP7U2_RELA)
+ {
+ begin_rel = NULL;
+ }
+ else if (ELF32_R_TYPE (irel->r_info) == R_NDS32_17IFC_PCREL_RELA
+ || ELF32_R_TYPE (irel->r_info) == R_NDS32_10IFCU_PCREL_RELA)
+ {
+ /* Suppress fp as gp when encounter ifc. */
+ ifc_inside = TRUE;
+ }
+ }
+
+ return TRUE;
+}
+
+/* Remove unused `la $fp, _FD_BASE_' instruction. */
+
+static bfd_boolean
+nds32_fag_remove_unused_fpbase (bfd *abfd, asection *sec,
+ Elf_Internal_Rela *internal_relocs,
+ Elf_Internal_Rela *irelend)
+{
+ Elf_Internal_Rela *irel;
+ Elf_Internal_Shdr *symtab_hdr;
+ bfd_byte *contents = NULL;
+ nds32_elf_blank_t *relax_blank_list = NULL;
+ bfd_boolean result = TRUE;
+ bfd_boolean unused_region = FALSE;
+
+ /*
+ NOTE: Disable fp-as-gp if we encounter ifcall relocations.
+ * R_NDS32_17IFC_PCREL_RELA
+ * R_NDS32_10IFCU_PCREL_RELA
+
+ CASE??????????????
+ */
+
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+ nds32_get_section_contents (abfd, sec, &contents);
+
+ for (irel = internal_relocs; irel < irelend; irel++)
+ {
+ /* To remove unused fp-base, we simply find the REGION_NOT_OMIT_FP
+ we marked to in previous pass.
+ DO NOT scan relocations again, since we've alreadly decided it
+ and set the flag. */
+ const char *syname;
+ int syndx;
+ uint32_t insn;
+
+ if (ELF32_R_TYPE (irel->r_info) == R_NDS32_RELAX_REGION_BEGIN
+ && (irel->r_addend & R_NDS32_RELAX_REGION_NOT_OMIT_FP_FLAG))
+ unused_region = TRUE;
+ else if (ELF32_R_TYPE (irel->r_info) == R_NDS32_RELAX_REGION_END
+ && (irel->r_addend & R_NDS32_RELAX_REGION_NOT_OMIT_FP_FLAG))
+ unused_region = FALSE;
+
+ /* We're not in the region. */
+ if (!unused_region)
+ continue;
+
+ /* _FP_BASE_ must be a GLOBAL symbol. */
+ syndx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info;
+ if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
+ continue;
+
+ /* The symbol name must be _FP_BASE_. */
+ syname = elf_sym_hashes (abfd)[syndx]->root.root.string;
+ if (strcmp (syname, FP_BASE_NAME) != 0)
+ continue;
+
+ if (ELF32_R_TYPE (irel->r_info) == R_NDS32_SDA19S0_RELA)
+ {
+ /* addi.gp $fp, -256 */
+ insn = bfd_getb32 (contents + irel->r_offset);
+ if (insn != INSN_ADDIGP_TO_FP)
+ continue;
+ }
+ else if (ELF32_R_TYPE (irel->r_info) == R_NDS32_SDA15S0_RELA)
+ {
+ /* addi $fp, $gp, -256 */
+ insn = bfd_getb32 (contents + irel->r_offset);
+ if (insn != INSN_ADDI_GP_TO_FP)
+ continue;
+ }
+ else if (ELF32_R_TYPE (irel->r_info) == R_NDS32_20_RELA)
+ {
+ /* movi $fp, FP_BASE */
+ insn = bfd_getb32 (contents + irel->r_offset);
+ if (insn != INSN_MOVI_TO_FP)
+ continue;
+ }
+ else
+ continue;
+
+ /* We got here because a FP_BASE instruction is found. */
+ if (!insert_nds32_elf_blank_recalc_total
+ (&relax_blank_list, irel->r_offset, 4))
+ goto error_return;
+ }
+
+finish:
+ if (relax_blank_list)
+ {
+ nds32_elf_relax_delete_blanks (abfd, sec, relax_blank_list);
+ relax_blank_list = NULL;
+ }
+ return result;
+
+error_return:
+ result = FALSE;
+ goto finish;
+}
+
+/* This is a version of bfd_generic_get_relocated_section_contents.
+ We need this variety because relaxation will modify the dwarf
+ infomation. When there is undefined symbol reference error mesage,
+ linker need to dump line number where the symbol be used. However
+ the address is be relaxed, it can not get the original dwarf contents.
+ The variety only modify function call for reading in the section. */
+
+static bfd_byte *
+nds32_elf_get_relocated_section_contents (bfd *abfd,
+ struct bfd_link_info *link_info,
+ struct bfd_link_order *link_order,
+ bfd_byte *data,
+ bfd_boolean relocatable,
+ asymbol **symbols)
+{
+ bfd *input_bfd = link_order->u.indirect.section->owner;
+ asection *input_section = link_order->u.indirect.section;
+ long reloc_size;
+ arelent **reloc_vector;
+ long reloc_count;
+
+ reloc_size = bfd_get_reloc_upper_bound (input_bfd, input_section);
+ if (reloc_size < 0)
+ return NULL;
+
+ /* Read in the section. */
+ if (!nds32_get_section_contents (input_bfd, input_section, &data))
+ return NULL;
+
+ if (reloc_size == 0)
+ return data;
+
+ reloc_vector = (arelent **) bfd_malloc (reloc_size);
+ if (reloc_vector == NULL)
+ return NULL;
+
+ 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 != NULL; parent++)
+ {
+ char *error_message = NULL;
+ asymbol *symbol;
+ bfd_reloc_status_type r;
+
+ symbol = *(*parent)->sym_ptr_ptr;
+ if (symbol->section && discarded_section (symbol->section))
+ {
+ bfd_byte *p;
+ static reloc_howto_type none_howto
+ = HOWTO (0, 0, 0, 0, FALSE, 0, complain_overflow_dont, NULL,
+ "unused", FALSE, 0, 0, FALSE);
+
+ p = data + (*parent)->address * bfd_octets_per_byte (input_bfd);
+ _bfd_clear_contents ((*parent)->howto, input_bfd, input_section,
+ p);
+ (*parent)->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
+ (*parent)->addend = 0;
+ (*parent)->howto = &none_howto;
+ r = bfd_reloc_ok;
+ }
+ else
+ r = bfd_perform_relocation (input_bfd, *parent, data,
+ input_section,
+ relocatable ? abfd : NULL,
+ &error_message);
+
+ if (relocatable)
+ {
+ 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, TRUE)))
+ goto error_return;
+ break;
+ case bfd_reloc_dangerous:
+ BFD_ASSERT (error_message != 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, NULL,
+ 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:
+ /* PR ld/13730:
+ This error can result when processing some partially
+ complete binaries. Do not abort, but issue an error
+ message instead. */
+ link_info->callbacks->einfo
+ (_("%X%P: %B(%A): relocation \"%R\" goes out of range\n"),
+ abfd, input_section, * parent);
+ goto error_return;
+
+ default:
+ abort ();
+ break;
+ }
+ }
+ }
+ }
+
+ free (reloc_vector);
+ return data;
+
+error_return:
+ free (reloc_vector);
+ return NULL;
+}
+
+/* Link-time IFC relaxation.
+ In this optimization, we chains jump instructions
+ of the same destination with ifcall. */
+
+
+/* List to save jal and j relocation. */
+struct elf_nds32_ifc_symbol_entry
+{
+ asection *sec;
+ struct elf_link_hash_entry *h;
+ struct elf_nds32_ifc_irel_list *irel_head;
+ unsigned long insn;
+ int times;
+ int enable; /* Apply ifc. */
+ int ex9_enable; /* Apply ifc after ex9. */
+ struct elf_nds32_ifc_symbol_entry *next;
+};
+
+struct elf_nds32_ifc_irel_list
+{
+ Elf_Internal_Rela *irel;
+ asection *sec;
+ bfd_vma addr;
+ /* If this is set, then it is the last instruction for
+ ifc-chain, so it must be keep for the actual branching. */
+ int keep;
+ struct elf_nds32_ifc_irel_list *next;
+};
+
+static struct elf_nds32_ifc_symbol_entry *ifc_symbol_head = NULL;
+
+/* Insert symbol of jal and j for ifc. */
+
+static void
+nds32_elf_ifc_insert_symbol (asection *sec,
+ struct elf_link_hash_entry *h,
+ Elf_Internal_Rela *irel,
+ unsigned long insn)
+{
+ struct elf_nds32_ifc_symbol_entry *ptr = ifc_symbol_head;
+
+ /* Check there is target of existing entry the same as the new one. */
+ while (ptr != NULL)
+ {
+ if (((h == NULL && ptr->sec == sec
+ && ELF32_R_SYM (ptr->irel_head->irel->r_info) == ELF32_R_SYM (irel->r_info)
+ && ptr->irel_head->irel->r_addend == irel->r_addend)
+ || h != NULL)
+ && ptr->h == h
+ && ptr->insn == insn)
+ {
+ /* The same target exist, so insert into list. */
+ struct elf_nds32_ifc_irel_list *irel_list = ptr->irel_head;
+
+ while (irel_list->next != NULL)
+ irel_list = irel_list->next;
+ irel_list->next = bfd_malloc (sizeof (struct elf_nds32_ifc_irel_list));
+ irel_list = irel_list->next;
+ irel_list->irel = irel;
+ irel_list->keep = 1;
+
+ if (h == NULL)
+ irel_list->sec = NULL;
+ else
+ irel_list->sec = sec;
+ irel_list->next = NULL;
+ return;
+ }
+ if (ptr->next == NULL)
+ break;
+ ptr = ptr->next;
+ }
+
+ /* There is no same target entry, so build a new one. */
+ if (ifc_symbol_head == NULL)
+ {
+ ifc_symbol_head = bfd_malloc (sizeof (struct elf_nds32_ifc_symbol_entry));
+ ptr = ifc_symbol_head;
+ }
+ else
+ {
+ ptr->next = bfd_malloc (sizeof (struct elf_nds32_ifc_symbol_entry));
+ ptr = ptr->next;
+ }
+
+ ptr->h = h;
+ ptr->irel_head = bfd_malloc (sizeof (struct elf_nds32_ifc_irel_list));
+ ptr->irel_head->irel = irel;
+ ptr->insn = insn;
+ ptr->irel_head->keep = 1;
+
+ if (h == NULL)
+ {
+ /* Local symbols. */
+ ptr->sec = sec;
+ ptr->irel_head->sec = NULL;
+ }
+ else
+ {
+ /* Global symbol. */
+ ptr->sec = NULL;
+ ptr->irel_head->sec = sec;
+ }
+
+ ptr->irel_head->next = NULL;
+ ptr->times = 0;
+ ptr->enable = 0;
+ ptr->ex9_enable = 0;
+ ptr->next = NULL;
+}
+
+/* Gather all jal and j instructions. */
+
+static bfd_boolean
+nds32_elf_ifc_calc (struct bfd_link_info *info,
+ bfd *abfd, asection *sec)
+{
+ Elf_Internal_Rela *internal_relocs;
+ Elf_Internal_Rela *irelend;
+ Elf_Internal_Rela *irel;
+ Elf_Internal_Shdr *symtab_hdr;
+ bfd_byte *contents = NULL;
+ uint32_t insn, insn_with_reg;
+ unsigned long r_symndx;
+ struct elf_link_hash_entry *h;
+ struct elf_link_hash_entry **sym_hashes = elf_sym_hashes (abfd);
+ struct elf_nds32_link_hash_table *table;
+ bfd_boolean ifc_loop_aware;
+
+ internal_relocs = _bfd_elf_link_read_relocs (abfd, sec, NULL, NULL,
+ TRUE /* keep_memory */);
+ irelend = internal_relocs + sec->reloc_count;
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+
+ /* Check if the object enable ifc. */
+ irel = find_relocs_at_address (internal_relocs, internal_relocs, irelend,
+ R_NDS32_RELAX_ENTRY);
+
+ if (irel == NULL
+ || irel >= irelend
+ || ELF32_R_TYPE (irel->r_info) != R_NDS32_RELAX_ENTRY
+ || (ELF32_R_TYPE (irel->r_info) == R_NDS32_RELAX_ENTRY
+ && !(irel->r_addend & R_NDS32_RELAX_ENTRY_IFC_FLAG)))
+ return TRUE;
+
+ if (!nds32_get_section_contents (abfd, sec, &contents))
+ return FALSE;
+
+ table = nds32_elf_hash_table (info);
+ ifc_loop_aware = table->ifc_loop_aware;
+ while (irel != NULL && irel < irelend)
+ {
+ /* Traverse all relocation and gather all of them to build the list. */
+
+ if (ELF32_R_TYPE (irel->r_info) == R_NDS32_RELAX_REGION_BEGIN)
+ {
+ if (ifc_loop_aware == 1
+ && (irel->r_addend & R_NDS32_RELAX_REGION_INNERMOST_LOOP_FLAG) != 0)
+ {
+ /* Check the region if loop or not. If it is true and
+ ifc-loop-aware is true, ignore the region till region end. */
+ while (irel != NULL
+ && irel < irelend
+ && (ELF32_R_TYPE (irel->r_info) != R_NDS32_RELAX_REGION_END
+ || (irel->r_addend & R_NDS32_RELAX_REGION_INNERMOST_LOOP_FLAG) != 0))
+ irel++;
+ }
+ }
+
+ if (ELF32_R_TYPE (irel->r_info) == R_NDS32_25_PCREL_RELA)
+ {
+ insn = bfd_getb32 (contents + irel->r_offset);
+ nds32_elf_get_insn_with_reg (irel, insn, &insn_with_reg);
+ r_symndx = ELF32_R_SYM (irel->r_info);
+ if (r_symndx < symtab_hdr->sh_info)
+ {
+ /* Local symbol. */
+ nds32_elf_ifc_insert_symbol (sec, NULL, irel, insn_with_reg);
+ }
+ else
+ {
+ /* External symbol. */
+ h = sym_hashes[r_symndx - symtab_hdr->sh_info];
+ nds32_elf_ifc_insert_symbol (sec, h, irel, insn_with_reg);
+ }
+ }
+ irel++;
+ }
+ return TRUE;
+}
+
+/* Determine whether j and jal should be substituted. */
+
+static void
+nds32_elf_ifc_filter (struct bfd_link_info *info)
+{
+ struct elf_nds32_ifc_symbol_entry *ptr = ifc_symbol_head;
+ struct elf_nds32_ifc_irel_list *irel_ptr = NULL;
+ struct elf_nds32_ifc_irel_list *irel_keeper = NULL;
+ struct elf_nds32_link_hash_table *table;
+ int target_optimize;
+ bfd_vma address;
+
+ table = nds32_elf_hash_table (info);
+ target_optimize = table->target_optimize;
+ while (ptr)
+ {
+ irel_ptr = ptr->irel_head;
+ if (ptr->h == NULL)
+ {
+ /* Local symbol. */
+ irel_keeper = irel_ptr;
+ while (irel_ptr && irel_ptr->next)
+ {
+ /* Check there is jump target can be used. */
+ if ((irel_ptr->next->irel->r_offset
+ - irel_keeper->irel->r_offset) > 1022)
+ irel_keeper = irel_ptr->next;
+ else
+ {
+ ptr->enable = 1;
+ irel_ptr->keep = 0;
+ }
+ irel_ptr = irel_ptr->next;
+ }
+ }
+ else
+ {
+ /* Global symbol. */
+ /* We have to get the absolute address and decide
+ whether to keep it or not. */
+ while (irel_ptr)
+ {
+ address = (irel_ptr->irel->r_offset
+ + irel_ptr->sec->output_section->vma
+ + irel_ptr->sec->output_offset);
+ irel_ptr->addr = address;
+ irel_ptr = irel_ptr->next;
+ }
+
+ irel_ptr = ptr->irel_head;
+ while (irel_ptr)
+ {
+ /* Sort by address. */
+ struct elf_nds32_ifc_irel_list *irel_dest = irel_ptr;
+ struct elf_nds32_ifc_irel_list *irel_temp = irel_ptr;
+ struct elf_nds32_ifc_irel_list *irel_ptr_prev = NULL;
+ struct elf_nds32_ifc_irel_list *irel_dest_prev = NULL;
+
+ /* Get the smallest one. */
+ while (irel_temp->next)
+ {
+ if (irel_temp->next->addr < irel_dest->addr)
+ {
+ irel_dest_prev = irel_temp;
+ irel_dest = irel_temp->next;
+ }
+ irel_temp = irel_temp->next;
+ }
+
+ if (irel_dest != irel_ptr)
+ {
+ if (irel_ptr_prev)
+ irel_ptr_prev->next = irel_dest;
+ if (irel_dest_prev)
+ irel_dest_prev->next = irel_ptr;
+ irel_temp = irel_ptr->next;
+ irel_ptr->next = irel_dest->next;
+ irel_dest->next = irel_temp;
+ }
+ irel_ptr_prev = irel_ptr;
+ irel_ptr = irel_ptr->next;
+ }
+
+ irel_ptr = ptr->irel_head;
+ irel_keeper = irel_ptr;
+ while (irel_ptr && irel_ptr->next)
+ {
+ if ((irel_ptr->next->addr - irel_keeper->addr) > 1022)
+ irel_keeper = irel_ptr->next;
+ else
+ {
+ ptr->enable = 1;
+ irel_ptr->keep = 0;
+ }
+ irel_ptr = irel_ptr->next;
+ }
+ }
+
+ /* Ex9 enable. Reserve it for ex9. */
+ if ((target_optimize & NDS32_RELAX_EX9_ON)
+ && ptr->irel_head != irel_keeper)
+ ptr->enable = 0;
+ ptr = ptr->next;
+ }
+}
+
+/* Determine whether j and jal should be substituted after ex9 done. */
+
+static void
+nds32_elf_ifc_filter_after_ex9 (void)
+{
+ struct elf_nds32_ifc_symbol_entry *ptr = ifc_symbol_head;
+ struct elf_nds32_ifc_irel_list *irel_ptr = NULL;
+
+ while (ptr)
+ {
+ if (ptr->enable == 0)
+ {
+ /* Check whether ifc is applied or not. */
+ irel_ptr = ptr->irel_head;
+ ptr->ex9_enable = 1;
+ while (irel_ptr)
+ {
+ if (ELF32_R_TYPE (irel_ptr->irel->r_info) == R_NDS32_TRAN)
+ {
+ /* Ex9 already. */
+ ptr->ex9_enable = 0;
+ break;
+ }
+ irel_ptr = irel_ptr->next;
+ }
+ }
+ ptr = ptr->next;
+ }
+}
+
+/* Wrapper to do ifc relaxation. */
+
+bfd_boolean
+nds32_elf_ifc_finish (struct bfd_link_info *info)
+{
+ int relax_status;
+ struct elf_nds32_link_hash_table *table;
+
+ table = nds32_elf_hash_table (info);
+ relax_status = table->relax_status;
+
+ if (!(relax_status & NDS32_RELAX_JUMP_IFC_DONE))
+ nds32_elf_ifc_filter (info);
+ else
+ nds32_elf_ifc_filter_after_ex9 ();
+
+ if (!nds32_elf_ifc_replace (info))
+ return FALSE;
+
+ if (table)
+ table->relax_status |= NDS32_RELAX_JUMP_IFC_DONE;
+ return TRUE;
+}
+
+/* Traverse the result of ifc filter and replace it with ifcall9. */
+
+static bfd_boolean
+nds32_elf_ifc_replace (struct bfd_link_info *info)
+{
+ struct elf_nds32_ifc_symbol_entry *ptr = ifc_symbol_head;
+ struct elf_nds32_ifc_irel_list *irel_ptr = NULL;
+ nds32_elf_blank_t *relax_blank_list = NULL;
+ bfd_byte *contents = NULL;
+ Elf_Internal_Rela *internal_relocs;
+ Elf_Internal_Rela *irel;
+ Elf_Internal_Rela *irelend;
+ unsigned short insn16 = INSN_IFCALL9;
+ struct elf_nds32_link_hash_table *table;
+ int relax_status;
+
+ table = nds32_elf_hash_table (info);
+ relax_status = table->relax_status;
+
+ while (ptr)
+ {
+ /* Traverse the ifc gather list, and replace the
+ filter entries by ifcall9. */
+ if ((!(relax_status & NDS32_RELAX_JUMP_IFC_DONE) && ptr->enable == 1)
+ || ((relax_status & NDS32_RELAX_JUMP_IFC_DONE)
+ && ptr->ex9_enable == 1))
+ {
+ irel_ptr = ptr->irel_head;
+ if (ptr->h == NULL)
+ {
+ /* Local symbol. */
+ internal_relocs = _bfd_elf_link_read_relocs
+ (ptr->sec->owner, ptr->sec, NULL, NULL, TRUE /* keep_memory */);
+ irelend = internal_relocs + ptr->sec->reloc_count;
+
+ if (!nds32_get_section_contents (ptr->sec->owner, ptr->sec,
+ &contents))
+ return FALSE;
+
+ while (irel_ptr)
+ {
+ if (irel_ptr->keep == 0 && irel_ptr->next)
+ {
+ /* The one can be replaced. We have to check whether
+ there is any alignment point in the region. */
+ irel = irel_ptr->irel;
+ while (((irel_ptr->next->keep == 0
+ && irel < irel_ptr->next->irel)
+ || (irel_ptr->next->keep == 1 && irel < irelend))
+ && !(ELF32_R_TYPE (irel->r_info) == R_NDS32_LABEL
+ && (irel->r_addend & 0x1f) == 2))
+ irel++;
+ if (irel >= irelend
+ || !(ELF32_R_TYPE (irel->r_info) == R_NDS32_LABEL
+ && (irel->r_addend & 0x1f) == 2
+ && ((irel->r_offset - get_nds32_elf_blank_total
+ (&relax_blank_list, irel->r_offset, 1))
+ & 0x02) == 0))
+ {
+ /* Replace by ifcall9. */
+ bfd_putb16 (insn16, contents + irel_ptr->irel->r_offset);
+ if (!insert_nds32_elf_blank_recalc_total
+ (&relax_blank_list, irel_ptr->irel->r_offset + 2, 2))
+ return FALSE;
+ irel_ptr->irel->r_info =
+ ELF32_R_INFO (ELF32_R_SYM (irel_ptr->irel->r_info),
+ R_NDS32_10IFCU_PCREL_RELA);
+ }
+ }
+ irel_ptr = irel_ptr->next;
+ }
+
+ /* Delete the redundant code. */
+ if (relax_blank_list)
+ {
+ nds32_elf_relax_delete_blanks (ptr->sec->owner, ptr->sec,
+ relax_blank_list);
+ relax_blank_list = NULL;
+ }
+ }
+ else
+ {
+ /* Global symbol. */
+ while (irel_ptr)
+ {
+ if (irel_ptr->keep == 0 && irel_ptr->next)
+ {
+ /* The one can be replaced, and we have to check
+ whether there is any alignment point in the region. */
+ internal_relocs = _bfd_elf_link_read_relocs
+ (irel_ptr->sec->owner, irel_ptr->sec, NULL, NULL,
+ TRUE /* keep_memory */);
+ irelend = internal_relocs + irel_ptr->sec->reloc_count;
+ if (!nds32_get_section_contents
+ (irel_ptr->sec->owner, irel_ptr->sec, &contents))
+ return FALSE;
+
+ irel = irel_ptr->irel;
+ while (((irel_ptr->sec == irel_ptr->next->sec
+ && irel_ptr->next->keep == 0
+ && irel < irel_ptr->next->irel)
+ || ((irel_ptr->sec != irel_ptr->next->sec
+ || irel_ptr->next->keep == 1)
+ && irel < irelend))
+ && !(ELF32_R_TYPE (irel->r_info) == R_NDS32_LABEL
+ && (irel->r_addend & 0x1f) == 2))
+ irel++;
+ if (irel >= irelend
+ || !(ELF32_R_TYPE (irel->r_info) == R_NDS32_LABEL
+ && (irel->r_addend & 0x1f) == 2
+ && ((irel->r_offset
+ - get_nds32_elf_blank_total (&relax_blank_list,
+ irel->r_offset, 1)) & 0x02) == 0))
+ {
+ /* Replace by ifcall9. */
+ bfd_putb16 (insn16, contents + irel_ptr->irel->r_offset);
+ if (!insert_nds32_elf_blank_recalc_total
+ (&relax_blank_list, irel_ptr->irel->r_offset + 2, 2))
+ return FALSE;
+
+ /* Delete the redundant code, and clear the relocation. */
+ nds32_elf_relax_delete_blanks (irel_ptr->sec->owner,
+ irel_ptr->sec,
+ relax_blank_list);
+ irel_ptr->irel->r_info =
+ ELF32_R_INFO (ELF32_R_SYM (irel_ptr->irel->r_info),
+ R_NDS32_10IFCU_PCREL_RELA);
+ relax_blank_list = NULL;
+ }
+ }
+
+ irel_ptr = irel_ptr->next;
+ }
+ }
+ }
+ ptr = ptr->next;
+ }
+
+ return TRUE;
+}
+
+/* Relocate ifcall. */
+
+static bfd_boolean
+nds32_elf_ifc_reloc (void)
+{
+ struct elf_nds32_ifc_symbol_entry *ptr = ifc_symbol_head;
+ struct elf_nds32_ifc_irel_list *irel_ptr = NULL;
+ struct elf_nds32_ifc_irel_list *irel_keeper = NULL;
+ bfd_vma relocation, address;
+ unsigned short insn16;
+ bfd_byte *contents = NULL;
+ static bfd_boolean done = FALSE;
+
+ if (done)
+ return TRUE;
+
+ done = TRUE;
+
+ while (ptr)
+ {
+ /* Check the entry is enable ifcall. */
+ if (ptr->enable == 1 || ptr->ex9_enable == 1)
+ {
+ /* Get the reserve jump. */
+ irel_ptr = ptr->irel_head;
+ while (irel_ptr)
+ {
+ if (irel_ptr->keep == 1)
+ {
+ irel_keeper = irel_ptr;
+ break;
+ }
+ irel_ptr = irel_ptr->next;
+ }
+
+ irel_ptr = ptr->irel_head;
+ if (ptr->h == NULL)
+ {
+ /* Local symbol. */
+ if (!nds32_get_section_contents (ptr->sec->owner, ptr->sec, &contents))
+ return FALSE;
+
+ while (irel_ptr)
+ {
+ if (irel_ptr->keep == 0
+ && ELF32_R_TYPE (irel_ptr->irel->r_info) == R_NDS32_10IFCU_PCREL_RELA)
+ {
+ relocation = irel_keeper->irel->r_offset;
+ relocation = relocation - irel_ptr->irel->r_offset;
+ while (irel_keeper && relocation > 1022)
+ {
+ irel_keeper = irel_keeper->next;
+ if (irel_keeper && irel_keeper->keep == 1)
+ {
+ relocation = irel_keeper->irel->r_offset;
+ relocation = relocation - irel_ptr->irel->r_offset;
+ }
+ }
+ if (relocation > 1022)
+ {
+ /* Double check. */
+ irel_keeper = ptr->irel_head;
+ while (irel_keeper)
+ {
+ if (irel_keeper->keep == 1)
+ {
+ relocation = irel_keeper->irel->r_offset;
+ relocation = relocation - irel_ptr->irel->r_offset;
+ }
+ if (relocation <= 1022)
+ break;
+ irel_keeper = irel_keeper->next;
+ }
+ if (!irel_keeper)
+ return FALSE;
+ }
+ irel_ptr->irel->r_info =
+ ELF32_R_INFO (ELF32_R_SYM (irel_ptr->irel->r_info),
+ R_NDS32_NONE);
+ insn16 = INSN_IFCALL9 | (relocation >> 1);
+ bfd_putb16 (insn16, contents + irel_ptr->irel->r_offset);
+ }
+ irel_ptr = irel_ptr->next;
+ }
+ }
+ else
+ {
+ /* Global symbol. */
+ while (irel_ptr)
+ {
+ if (irel_ptr->keep == 0
+ && ELF32_R_TYPE (irel_ptr->irel->r_info) == R_NDS32_10IFCU_PCREL_RELA)
+ {
+ /* Get the distance between ifcall and jump. */
+ relocation = (irel_keeper->irel->r_offset
+ + irel_keeper->sec->output_section->vma
+ + irel_keeper->sec->output_offset);
+ address = (irel_ptr->irel->r_offset
+ + irel_ptr->sec->output_section->vma
+ + irel_ptr->sec->output_offset);
+ relocation = relocation - address;
+
+ /* The distance is over ragne, find callee again. */
+ while (irel_keeper && relocation > 1022)
+ {
+ irel_keeper = irel_keeper->next;
+ if (irel_keeper && irel_keeper->keep ==1)
+ {
+ relocation = (irel_keeper->irel->r_offset
+ + irel_keeper->sec->output_section->vma
+ + irel_keeper->sec->output_offset);
+ relocation = relocation - address;
+ }
+ }
+
+ if (relocation > 1022)
+ {
+ /* Double check. */
+ irel_keeper = ptr->irel_head;
+ while (irel_keeper)
+ {
+ if (irel_keeper->keep == 1)
+ {
+
+ relocation = (irel_keeper->irel->r_offset
+ + irel_keeper->sec->output_section->vma
+ + irel_keeper->sec->output_offset);
+ relocation = relocation - address;
+ }
+ if (relocation <= 1022)
+ break;
+ irel_keeper = irel_keeper->next;
+ }
+ if (!irel_keeper)
+ return FALSE;
+ }
+ if (!nds32_get_section_contents
+ (irel_ptr->sec->owner, irel_ptr->sec, &contents))
+ return FALSE;
+ insn16 = INSN_IFCALL9 | (relocation >> 1);
+ bfd_putb16 (insn16, contents + irel_ptr->irel->r_offset);
+ irel_ptr->irel->r_info =
+ ELF32_R_INFO (ELF32_R_SYM (irel_ptr->irel->r_info),
+ R_NDS32_NONE);
+ }
+ irel_ptr =irel_ptr->next;
+ }
+ }
+ }
+ ptr = ptr->next;
+ }
+
+ return TRUE;
+}
+
+/* End of IFC relaxation. */
+
+/* EX9 Instruction Table Relaxation. */
+
+/* Global hash list. */
+struct elf_link_hash_entry_list
+{
+ struct elf_link_hash_entry *h;
+ struct elf_link_hash_entry_list *next;
+};
+
+/* Save different destination but same insn. */
+struct elf_link_hash_entry_mul_list
+{
+ /* Global symbol times. */
+ int times;
+ /* Save relocation for each global symbol but useful?? */
+ Elf_Internal_Rela *irel;
+ /* For sethi, two sethi may have the same high-part but different low-parts. */
+ Elf_Internal_Rela rel_backup;
+ struct elf_link_hash_entry_list *h_list;
+ struct elf_link_hash_entry_mul_list *next;
+};
+
+/* Instruction hash table. */
+struct elf_nds32_code_hash_entry
+{
+ struct bfd_hash_entry root;
+ int times;
+ /* For insn that can use relocation or constant ex: sethi. */
+ int const_insn;
+ asection *sec;
+ struct elf_link_hash_entry_mul_list *m_list;
+ /* Using r_addend. */
+ Elf_Internal_Rela *irel;
+ /* Using r_info. */
+ Elf_Internal_Rela rel_backup;
+};
+
+/* Instruction count list. */
+struct elf_nds32_insn_times_entry
+{
+ const char *string;
+ int times;
+ int order;
+ asection *sec;
+ struct elf_link_hash_entry_mul_list *m_list;
+ Elf_Internal_Rela *irel;
+ Elf_Internal_Rela rel_backup;
+ struct elf_nds32_insn_times_entry *next;
+};
+
+/* J and JAL symbol list. */
+struct elf_nds32_symbol_entry
+{
+ char *string;
+ unsigned long insn;
+ struct elf_nds32_symbol_entry *next;
+};
+
+/* Relocation list. */
+struct elf_nds32_irel_entry
+{
+ Elf_Internal_Rela *irel;
+ struct elf_nds32_irel_entry *next;
+};
+
+/* ex9.it insn need to be fixed. */
+struct elf_nds32_ex9_refix
+{
+ Elf_Internal_Rela *irel;
+ asection *sec;
+ struct elf_link_hash_entry *h;
+ int order;
+ struct elf_nds32_ex9_refix *next;
+};
+
+static struct bfd_hash_table ex9_code_table;
+static struct elf_nds32_insn_times_entry *ex9_insn_head = NULL;
+static struct elf_nds32_ex9_refix *ex9_refix_head = NULL;
+
+/* EX9 hash function. */
+
+static struct bfd_hash_entry *
+nds32_elf_code_hash_newfunc (struct bfd_hash_entry *entry,
+ struct bfd_hash_table *table,
+ const char *string)
+{
+ struct elf_nds32_code_hash_entry *ret;
+
+ /* Allocate the structure if it has not already been allocated by a
+ subclass. */
+ if (entry == NULL)
+ {
+ entry = (struct bfd_hash_entry *)
+ bfd_hash_allocate (table, sizeof (*ret));
+ if (entry == NULL)
+ return entry;
+ }
+
+ /* Call the allocation method of the superclass. */
+ entry = bfd_hash_newfunc (entry, table, string);
+ if (entry == NULL)
+ return entry;
+
+ ret = (struct elf_nds32_code_hash_entry*) entry;
+ ret->times = 0;
+ ret->const_insn = 0;
+ ret->m_list = NULL;
+ ret->sec = NULL;
+ ret->irel = NULL;
+ return &ret->root;
+}
+
+/* Insert ex9 entry
+ this insert must be stable sorted by times. */
+
+static void
+nds32_elf_ex9_insert_entry (struct elf_nds32_insn_times_entry *ptr)
+{
+ struct elf_nds32_insn_times_entry *temp;
+ struct elf_nds32_insn_times_entry *temp2;
+
+ if (ex9_insn_head == NULL)
+ {
+ ex9_insn_head = ptr;
+ ptr->next = NULL;
+ }
+ else
+ {
+ temp = ex9_insn_head;
+ temp2 = ex9_insn_head;
+ while (temp->next &&
+ (temp->next->times >= ptr->times
+ || temp->times == -1))
+ {
+ if (temp->times == -1)
+ temp2 = temp;
+ temp = temp->next;
+ }
+ if (ptr->times > temp->times && temp->times != -1)
+ {
+ ptr->next = temp;
+ if (temp2->times == -1)
+ temp2->next = ptr;
+ else
+ ex9_insn_head = ptr;
+ }
+ else if (temp->next == NULL)
+ {
+ temp->next = ptr;
+ ptr->next = NULL;
+ }
+ else
+ {
+ ptr->next = temp->next;
+ temp->next = ptr;
+ }
+ }
+}
+
+/* Examine each insn times in hash table.
+ Handle multi-link hash entry.
+
+ TODO: This function doesn't assign so much info since it is fake. */
+
+static int
+nds32_elf_examine_insn_times (struct elf_nds32_code_hash_entry *h)
+{
+ struct elf_nds32_insn_times_entry *ptr;
+ int times;
+
+ if (h->m_list == NULL)
+ {
+ /* Local symbol insn or insn without relocation. */
+ if (h->times < 3)
+ return TRUE;
+
+ ptr = (struct elf_nds32_insn_times_entry *)
+ bfd_malloc (sizeof (struct elf_nds32_insn_times_entry));
+ ptr->times = h->times;
+ ptr->string = h->root.string;
+ ptr->m_list = NULL;
+ ptr->sec = h->sec;
+ ptr->irel = h->irel;
+ ptr->rel_backup = h->rel_backup;
+ nds32_elf_ex9_insert_entry (ptr);
+ }
+ else
+ {
+ /* Global symbol insn. */
+ /* Only sethi insn has multiple m_list. */
+ struct elf_link_hash_entry_mul_list *m_list = h->m_list;
+
+ times = 0;
+ while (m_list)
+ {
+ times += m_list->times;
+ m_list = m_list->next;
+ }
+ if (times >= 3)
+ {
+ m_list = h->m_list;
+ ptr = (struct elf_nds32_insn_times_entry *)
+ bfd_malloc (sizeof (struct elf_nds32_insn_times_entry));
+ ptr->times = times; /* Use the total times. */
+ ptr->string = h->root.string;
+ ptr->m_list = m_list;
+ ptr->sec = h->sec;
+ ptr->irel = m_list->irel;
+ ptr->rel_backup = m_list->rel_backup;
+ nds32_elf_ex9_insert_entry (ptr);
+ }
+ if (h->const_insn == 1)
+ {
+ /* sethi with constant value. */
+ if (h->times < 3)
+ return TRUE;
+
+ ptr = (struct elf_nds32_insn_times_entry *)
+ bfd_malloc (sizeof (struct elf_nds32_insn_times_entry));
+ ptr->times = h->times;
+ ptr->string = h->root.string;
+ ptr->m_list = NULL;
+ ptr->sec = NULL;
+ ptr->irel = NULL;
+ ptr->rel_backup = h->rel_backup;
+ nds32_elf_ex9_insert_entry (ptr);
+ }
+ }
+ return TRUE;
+}
+
+/* Count each insn times in hash table.
+ Handle multi-link hash entry. */
+
+static int
+nds32_elf_count_insn_times (struct elf_nds32_code_hash_entry *h)
+{
+ int reservation, times;
+ unsigned long relocation, min_relocation;
+ struct elf_nds32_insn_times_entry *ptr;
+
+ if (h->m_list == NULL)
+ {
+ /* Local symbol insn or insn without relocation. */
+ if (h->times < 3)
+ return TRUE;
+ ptr = (struct elf_nds32_insn_times_entry *)
+ bfd_malloc (sizeof (struct elf_nds32_insn_times_entry));
+ ptr->times = h->times;
+ ptr->string = h->root.string;
+ ptr->m_list = NULL;
+ ptr->sec = h->sec;
+ ptr->irel = h->irel;
+ ptr->rel_backup = h->rel_backup;
+ nds32_elf_ex9_insert_entry (ptr);
+ }
+ else
+ {
+ /* Global symbol insn. */
+ /* Only sethi insn has multiple m_list. */
+ struct elf_link_hash_entry_mul_list *m_list = h->m_list;
+
+ if (ELF32_R_TYPE (m_list->rel_backup.r_info) == R_NDS32_HI20_RELA
+ && m_list->next != NULL)
+ {
+ /* Sethi insn has different symbol or addend but has same hi20. */
+ times = 0;
+ reservation = 1;
+ relocation = 0;
+ min_relocation = 0xffffffff;
+ while (m_list)
+ {
+ /* Get the minimum sethi address
+ and calculate how many entry the sethi-list have to use. */
+ if ((m_list->h_list->h->root.type == bfd_link_hash_defined
+ || m_list->h_list->h->root.type == bfd_link_hash_defweak)
+ && (m_list->h_list->h->root.u.def.section != NULL
+ && m_list->h_list->h->root.u.def.section->output_section != NULL))
+ {
+ relocation = (m_list->h_list->h->root.u.def.value +
+ m_list->h_list->h->root.u.def.section->output_section->vma +
+ m_list->h_list->h->root.u.def.section->output_offset);
+ relocation += m_list->irel->r_addend;
+ }
+ else
+ relocation = 0;
+ if (relocation < min_relocation)
+ min_relocation = relocation;
+ times += m_list->times;
+ m_list = m_list->next;
+ }
+ if (min_relocation < ex9_relax_size)
+ reservation = (min_relocation >> 12) + 1;
+ else
+ reservation = (min_relocation >> 12)
+ - ((min_relocation - ex9_relax_size) >> 12) + 1;
+ if (reservation < (times / 3))
+ {
+ /* Efficient enough to use ex9. */
+ int i;
+
+ for (i = reservation ; i > 0; i--)
+ {
+ /* Allocate number of reservation ex9 entry. */
+ ptr = (struct elf_nds32_insn_times_entry *)
+ bfd_malloc (sizeof (struct elf_nds32_insn_times_entry));
+ ptr->times = h->m_list->times / reservation;
+ ptr->string = h->root.string;
+ ptr->m_list = h->m_list;
+ ptr->sec = h->sec;
+ ptr->irel = h->m_list->irel;
+ ptr->rel_backup = h->m_list->rel_backup;
+ nds32_elf_ex9_insert_entry (ptr);
+ }
+ }
+ }
+ else
+ {
+ /* Normal global symbol that means no different address symbol
+ using same ex9 entry. */
+ if (m_list->times >= 3)
+ {
+ ptr = (struct elf_nds32_insn_times_entry *)
+ bfd_malloc (sizeof (struct elf_nds32_insn_times_entry));
+ ptr->times = m_list->times;
+ ptr->string = h->root.string;
+ ptr->m_list = h->m_list;
+ ptr->sec = h->sec;
+ ptr->irel = h->m_list->irel;
+ ptr->rel_backup = h->m_list->rel_backup;
+ nds32_elf_ex9_insert_entry (ptr);
+ }
+ }
+
+ if (h->const_insn == 1)
+ {
+ /* sethi with constant value. */
+ if (h->times < 3)
+ return TRUE;
+
+ ptr = (struct elf_nds32_insn_times_entry *)
+ bfd_malloc (sizeof (struct elf_nds32_insn_times_entry));
+ ptr->times = h->times;
+ ptr->string = h->root.string;
+ ptr->m_list = NULL;
+ ptr->sec = NULL;
+ ptr->irel = NULL;
+ ptr->rel_backup = h->rel_backup;
+ nds32_elf_ex9_insert_entry (ptr);
+ }
+ }
+
+ return TRUE;
+}
+
+/* Hash table traverse function. */
+
+static void
+nds32_elf_code_hash_traverse (int (*func) (struct elf_nds32_code_hash_entry*))
+{
+ unsigned int i;
+
+ ex9_code_table.frozen = 1;
+ for (i = 0; i < ex9_code_table.size; i++)
+ {
+ struct bfd_hash_entry *p;
+
+ for (p = ex9_code_table.table[i]; p != NULL; p = p->next)
+ if (!func ((struct elf_nds32_code_hash_entry *) p))
+ goto out;
+ }
+out:
+ ex9_code_table.frozen = 0;
+}
+
+
+/* Give order number to insn list. */
+
+static void
+nds32_elf_order_insn_times (struct bfd_link_info *info)
+{
+ struct elf_nds32_insn_times_entry *ex9_insn;
+ struct elf_nds32_insn_times_entry *temp = NULL;
+ struct elf_nds32_link_hash_table *table;
+ int ex9_limit;
+ int number = 0;
+
+ if (ex9_insn_head == NULL)
+ return;
+
+/* The max number of entries is 512. */
+ ex9_insn = ex9_insn_head;
+ table = nds32_elf_hash_table (info);
+ ex9_limit = table->ex9_limit;
+
+ ex9_insn = ex9_insn_head;
+
+ while (ex9_insn != NULL && number < ex9_limit)
+ {
+ ex9_insn->order = number;
+ number++;
+ temp = ex9_insn;
+ ex9_insn = ex9_insn->next;
+ }
+
+ if (ex9_insn && temp)
+ temp->next = NULL;
+
+ while (ex9_insn != NULL)
+ {
+ /* Free useless entry. */
+ temp = ex9_insn;
+ ex9_insn = ex9_insn->next;
+ free (temp);
+ }
+}
+
+/* Build .ex9.itable section. */
+
+static void
+nds32_elf_ex9_build_itable (struct bfd_link_info *link_info)
+{
+ asection *table_sec;
+ struct elf_nds32_insn_times_entry *ptr;
+ bfd *it_abfd;
+ int number = 0;
+ bfd_byte *contents = NULL;
+
+ for (it_abfd = link_info->input_bfds; it_abfd != NULL;
+ it_abfd = it_abfd->link.next)
+ {
+ /* Find the section .ex9.itable, and put all entries into it. */
+ table_sec = bfd_get_section_by_name (it_abfd, ".ex9.itable");
+ if (table_sec != NULL)
+ {
+ if (!nds32_get_section_contents (it_abfd, table_sec, &contents))
+ return;
+
+ for (ptr = ex9_insn_head; ptr !=NULL ; ptr = ptr->next)
+ number++;
+
+ table_sec->size = number * 4;
+
+ if (number == 0)
+ return;
+
+ elf_elfheader (link_info->output_bfd)->e_flags |= E_NDS32_HAS_EX9_INST;
+ number = 0;
+ for (ptr = ex9_insn_head; ptr !=NULL ; ptr = ptr->next)
+ {
+ long val;
+
+ val = strtol (ptr->string, NULL, 16);
+ bfd_putb32 ((bfd_vma) val, (char *) contents + (number * 4));
+ number++;
+ }
+ break;
+ }
+ }
+}
+
+/* Get insn with regs according to relocation type. */
+
+static void
+nds32_elf_get_insn_with_reg (Elf_Internal_Rela *irel,
+ uint32_t insn, uint32_t *insn_with_reg)
+{
+ reloc_howto_type *howto = NULL;
+
+ if (irel == NULL
+ || (ELF32_R_TYPE (irel->r_info) >= (int) ARRAY_SIZE (nds32_elf_howto_table)
+ && (ELF32_R_TYPE (irel->r_info) - R_NDS32_RELAX_ENTRY)
+ >= (int) ARRAY_SIZE (nds32_elf_relax_howto_table)))
+ {
+ *insn_with_reg = insn;
+ return;
+ }
+
+ howto = bfd_elf32_bfd_reloc_type_table_lookup (ELF32_R_TYPE (irel->r_info));
+ *insn_with_reg = insn & (0xffffffff ^ howto->dst_mask);
+}
+
+/* Mask number of address bits according to relocation. */
+
+static unsigned long
+nds32_elf_irel_mask (Elf_Internal_Rela *irel)
+{
+ reloc_howto_type *howto = NULL;
+
+ if (irel == NULL
+ || (ELF32_R_TYPE (irel->r_info) >= (int) ARRAY_SIZE (nds32_elf_howto_table)
+ && (ELF32_R_TYPE (irel->r_info) - R_NDS32_RELAX_ENTRY)
+ >= (int) ARRAY_SIZE (nds32_elf_relax_howto_table)))
+ return 0;
+
+ howto = bfd_elf32_bfd_reloc_type_table_lookup (ELF32_R_TYPE (irel->r_info));
+ return howto->dst_mask;
+}
+
+static void
+nds32_elf_insert_irel_entry (struct elf_nds32_irel_entry **irel_list,
+ struct elf_nds32_irel_entry *irel_ptr)
+{
+ if (*irel_list == NULL)
+ {
+ *irel_list = irel_ptr;
+ irel_ptr->next = NULL;
+ }
+ else
+ {
+ irel_ptr->next = *irel_list;
+ *irel_list = irel_ptr;
+ }
+}
+
+static void
+nds32_elf_ex9_insert_fix (asection * sec, Elf_Internal_Rela * irel,
+ struct elf_link_hash_entry *h, int order)
+{
+ struct elf_nds32_ex9_refix *ptr;
+
+ ptr = bfd_malloc (sizeof (struct elf_nds32_ex9_refix));
+ ptr->sec = sec;
+ ptr->irel = irel;
+ ptr->h = h;
+ ptr->order = order;
+ ptr->next = NULL;
+
+ if (ex9_refix_head == NULL)
+ ex9_refix_head = ptr;
+ else
+ {
+ struct elf_nds32_ex9_refix *temp = ex9_refix_head;
+
+ while (temp->next != NULL)
+ temp = temp->next;
+ temp->next = ptr;
+ }
+}
+
+enum
+{
+ DATA_EXIST = 1,
+ CLEAN_PRE = 1 << 1,
+ PUSH_PRE = 1 << 2
+};
+
+/* Check relocation type if supporting for ex9. */
+
+static int
+nds32_elf_ex9_relocation_check (struct bfd_link_info *info,
+ Elf_Internal_Rela **irel,
+ Elf_Internal_Rela *irelend,
+ nds32_elf_blank_t *relax_blank_list,
+ asection *sec,bfd_vma *off,
+ bfd_byte *contents)
+{
+ /* Suppress ex9 if `.no_relax ex9' or inner loop. */
+ bfd_boolean nested_ex9, nested_loop;
+ bfd_boolean ex9_loop_aware;
+ /* We use the highest 1 byte of result to record
+ how many bytes location counter has to move. */
+ int result = 0;
+ Elf_Internal_Rela *irel_save = NULL;
+ struct elf_nds32_link_hash_table *table;
+
+ table = nds32_elf_hash_table (info);
+ ex9_loop_aware = table->ex9_loop_aware;
+
+ while ((*irel) != NULL && (*irel) < irelend && *off == (*irel)->r_offset)
+ {
+ switch (ELF32_R_TYPE ((*irel)->r_info))
+ {
+ case R_NDS32_RELAX_REGION_BEGIN:
+ /* Ignore code block. */
+ nested_ex9 = FALSE;
+ nested_loop = FALSE;
+ if (((*irel)->r_addend & R_NDS32_RELAX_REGION_NO_EX9_FLAG)
+ || (ex9_loop_aware
+ && ((*irel)->r_addend & R_NDS32_RELAX_REGION_INNERMOST_LOOP_FLAG)))
+ {
+ /* Check the region if loop or not. If it is true and
+ ex9-loop-aware is true, ignore the region till region end. */
+ /* To save the status for in .no_relax ex9 region and
+ loop region to conform the block can do ex9 relaxation. */
+ nested_ex9 = ((*irel)->r_addend & R_NDS32_RELAX_REGION_NO_EX9_FLAG);
+ nested_loop = (ex9_loop_aware
+ && ((*irel)->r_addend & R_NDS32_RELAX_REGION_INNERMOST_LOOP_FLAG));
+ while ((*irel) && (*irel) < irelend && (nested_ex9 || nested_loop))
+ {
+ (*irel)++;
+ if (ELF32_R_TYPE ((*irel)->r_info) == R_NDS32_RELAX_REGION_BEGIN)
+ {
+ /* There may be nested region. */
+ if (((*irel)->r_addend & R_NDS32_RELAX_REGION_NO_EX9_FLAG) != 0)
+ nested_ex9 = TRUE;
+ else if (ex9_loop_aware
+ && ((*irel)->r_addend & R_NDS32_RELAX_REGION_INNERMOST_LOOP_FLAG))
+ nested_loop = TRUE;
+ }
+ else if (ELF32_R_TYPE ((*irel)->r_info) == R_NDS32_RELAX_REGION_END)
+ {
+ /* The end of region. */
+ if (((*irel)->r_addend & R_NDS32_RELAX_REGION_NO_EX9_FLAG) != 0)
+ nested_ex9 = FALSE;
+ else if (ex9_loop_aware
+ && ((*irel)->r_addend & R_NDS32_RELAX_REGION_INNERMOST_LOOP_FLAG))
+ nested_loop = FALSE;
+ }
+ else if (ELF32_R_TYPE ((*irel)->r_info) == R_NDS32_LABEL
+ && ((*irel)->r_addend & 0x1f) == 2)
+ {
+ /* Alignment exist in the region. */
+ result |= CLEAN_PRE;
+ if (((*irel)->r_offset -
+ get_nds32_elf_blank_total (&relax_blank_list,
+ (*irel)->r_offset, 0)) & 0x02)
+ result |= PUSH_PRE;
+ }
+ }
+ if ((*irel) >= irelend)
+ *off = sec->size;
+ else
+ *off = (*irel)->r_offset;
+
+ /* The final instruction in the region, regard this one as data to ignore it. */
+ result |= DATA_EXIST;
+ return result;
+ }
+ break;
+
+ case R_NDS32_LABEL:
+ if (((*irel)->r_addend & 0x1f) == 2)
+ {
+ /* Check this point is align and decide to do ex9 or not. */
+ result |= CLEAN_PRE;
+ if (((*irel)->r_offset -
+ get_nds32_elf_blank_total (&relax_blank_list,
+ (*irel)->r_offset, 0)) & 0x02)
+ result |= PUSH_PRE;
+ }
+ break;
+ case R_NDS32_32_RELA:
+ /* Data. */
+ result |= (4 << 24);
+ result |= DATA_EXIST;
+ break;
+ case R_NDS32_16_RELA:
+ /* Data. */
+ result |= (2 << 24);
+ result |= DATA_EXIST;
+ break;
+ case R_NDS32_DATA:
+ /* Data. */
+ /* The least code alignment is 2. If the data is only one byte,
+ we have to shift one more byte. */
+ if ((*irel)->r_addend == 1)
+ result |= ((*irel)->r_addend << 25) ;
+ else
+ result |= ((*irel)->r_addend << 24) ;
+
+ result |= DATA_EXIST;
+ break;
+
+ case R_NDS32_25_PCREL_RELA:
+ case R_NDS32_SDA16S3_RELA:
+ case R_NDS32_SDA15S3_RELA:
+ case R_NDS32_SDA15S3:
+ case R_NDS32_SDA17S2_RELA:
+ case R_NDS32_SDA15S2_RELA:
+ case R_NDS32_SDA12S2_SP_RELA:
+ case R_NDS32_SDA12S2_DP_RELA:
+ case R_NDS32_SDA15S2:
+ case R_NDS32_SDA18S1_RELA:
+ case R_NDS32_SDA15S1_RELA:
+ case R_NDS32_SDA15S1:
+ case R_NDS32_SDA19S0_RELA:
+ case R_NDS32_SDA15S0_RELA:
+ case R_NDS32_SDA15S0:
+ case R_NDS32_HI20_RELA:
+ case R_NDS32_LO12S0_ORI_RELA:
+ case R_NDS32_LO12S0_RELA:
+ case R_NDS32_LO12S1_RELA:
+ case R_NDS32_LO12S2_RELA:
+ /* These relocation is supported ex9 relaxation currently. */
+ /* We have to save the relocation for using later, since we have
+ to check there is any alignment in the same address. */
+ irel_save = *irel;
+ break;
+ default:
+ /* Not support relocations. */
+ if (ELF32_R_TYPE ((*irel)->r_info) < ARRAY_SIZE (nds32_elf_howto_table)
+ && ELF32_R_TYPE ((*irel)->r_info) != R_NDS32_NONE
+ && ELF32_R_TYPE ((*irel)->r_info) != R_NDS32_INSN16)
+ {
+ /* Note: To optimize aggressively, it maybe can ignore R_NDS32_INSN16 here.
+ But we have to consider if there is any side-effect. */
+ if (!(result & DATA_EXIST))
+ {
+ /* We have to confirm there is no data relocation in the
+ same address. In general case, this won't happen. */
+ /* We have to do ex9 conservative, for those relocation not
+ considerd we ignore instruction. */
+ result |= DATA_EXIST;
+ if (*(contents + *off) & 0x80)
+ result |= (2 << 24);
+ else
+ result |= (4 << 24);
+ break;
+ }
+ }
+ }
+ if ((*irel) < irelend
+ && ((*irel) + 1) < irelend
+ && (*irel)->r_offset == ((*irel) + 1)->r_offset)
+ /* There are relocations pointing to the same address, we have to
+ check all of them. */
+ (*irel)++;
+ else
+ {
+ if (irel_save)
+ *irel = irel_save;
+ return result;
+ }
+ }
+ return result;
+}
+
+/* Replace with ex9 instruction. */
+
+static bfd_boolean
+nds32_elf_ex9_push_insn (uint16_t insn16, bfd_byte *contents, bfd_vma pre_off,
+ nds32_elf_blank_t **relax_blank_list,
+ struct elf_nds32_irel_entry *pre_irel_ptr,
+ struct elf_nds32_irel_entry **irel_list)
+{
+ if (insn16 != 0)
+ {
+ /* Implement the ex9 relaxation. */
+ bfd_putb16 (insn16, contents + pre_off);
+ if (!insert_nds32_elf_blank_recalc_total (relax_blank_list,
+ pre_off + 2, 2))
+ return FALSE;
+ if (pre_irel_ptr != NULL)
+ nds32_elf_insert_irel_entry (irel_list, pre_irel_ptr);
+ }
+ return TRUE;
+}
+
+/* Replace input file instruction which is in ex9 itable. */
+
+static bfd_boolean
+nds32_elf_ex9_replace_instruction (struct bfd_link_info *info, bfd *abfd, asection *sec)
+{
+ struct elf_nds32_insn_times_entry *ex9_insn = ex9_insn_head;
+ bfd_byte *contents = NULL;
+ bfd_vma off;
+ uint16_t insn16, insn_ex9;
+ /* `pre_*' are used to track previous instruction that can use ex9.it. */
+ bfd_vma pre_off = -1;
+ uint16_t pre_insn16 = 0;
+ struct elf_nds32_irel_entry *pre_irel_ptr = NULL;
+ Elf_Internal_Rela *internal_relocs;
+ Elf_Internal_Rela *irel;
+ Elf_Internal_Rela *irelend;
+ Elf_Internal_Shdr *symtab_hdr;
+ Elf_Internal_Sym *isym = NULL;
+ nds32_elf_blank_t *relax_blank_list = NULL;
+ uint32_t insn = 0;
+ uint32_t insn_with_reg = 0;
+ uint32_t it_insn;
+ uint32_t it_insn_with_reg;
+ unsigned long r_symndx;
+ asection *isec;
+ struct elf_nds32_irel_entry *irel_list = NULL;
+ struct elf_link_hash_entry **sym_hashes = elf_sym_hashes (abfd);
+ int data_flag, do_replace, save_irel;
+ struct elf_link_hash_entry_list *h_list;
+
+
+ /* Load section instructions, relocations, and symbol table. */
+ if (!nds32_get_section_contents (abfd, sec, &contents)
+ || !nds32_get_local_syms (abfd, sec, &isym))
+ return FALSE;
+ internal_relocs =
+ _bfd_elf_link_read_relocs (abfd, sec, NULL, NULL, TRUE /* keep_memory */);
+ irelend = internal_relocs + sec->reloc_count;
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+
+ off = 0;
+
+ /* Check if the object enable ex9. */
+ irel = find_relocs_at_address (internal_relocs, internal_relocs,
+ irelend, R_NDS32_RELAX_ENTRY);
+
+ /* Check this section trigger ex9 relaxation. */
+ if (irel == NULL
+ || irel >= irelend
+ || ELF32_R_TYPE (irel->r_info) != R_NDS32_RELAX_ENTRY
+ || (ELF32_R_TYPE (irel->r_info) == R_NDS32_RELAX_ENTRY
+ && !(irel->r_addend & R_NDS32_RELAX_ENTRY_EX9_FLAG)))
+ return TRUE;
+
+ irel = internal_relocs;
+
+ /* Check alignment and fetch proper relocation. */
+ while (off < sec->size)
+ {
+ struct elf_link_hash_entry *h = NULL;
+ struct elf_nds32_irel_entry *irel_ptr = NULL;
+
+ /* Syn the instruction and the relocation. */
+ while (irel != NULL && irel < irelend && irel->r_offset < off)
+ irel++;
+
+ data_flag = nds32_elf_ex9_relocation_check (info, &irel, irelend,
+ relax_blank_list, sec,
+ &off, contents);
+ if (data_flag & PUSH_PRE)
+ if (!nds32_elf_ex9_push_insn (pre_insn16, contents, pre_off,
+ &relax_blank_list, pre_irel_ptr,
+ &irel_list))
+ return FALSE;
+
+ if (data_flag & CLEAN_PRE)
+ {
+ pre_off = 0;
+ pre_insn16 = 0;
+ pre_irel_ptr = NULL;
+ }
+ if (data_flag & DATA_EXIST)
+ {
+ /* We save the move offset in the highest byte. */
+ off += (data_flag >> 24);
+ continue;
+ }
+
+ if (*(contents + off) & 0x80)
+ {
+ /* 2-byte instruction. */
+ off += 2;
+ continue;
+ }
+
+ /* Load the instruction and its opcode with register for comparing. */
+ ex9_insn = ex9_insn_head;
+ insn = bfd_getb32 (contents + off);
+ insn_with_reg = 0;
+ while (ex9_insn)
+ {
+ it_insn = strtol (ex9_insn->string, NULL, 16);
+ it_insn_with_reg = 0;
+ do_replace = 0;
+ save_irel = 0;
+
+ if (irel != NULL && irel < irelend && irel->r_offset == off)
+ {
+ /* Insn with relocation. */
+ nds32_elf_get_insn_with_reg (irel, insn, &insn_with_reg);
+
+ if (ex9_insn->irel != NULL)
+ nds32_elf_get_insn_with_reg (ex9_insn->irel, it_insn,
+ &it_insn_with_reg);
+
+ if (ex9_insn->irel != NULL
+ && (ELF32_R_TYPE (irel->r_info) ==
+ ELF32_R_TYPE (ex9_insn->irel->r_info))
+ && (insn_with_reg == it_insn_with_reg))
+ {
+ /* Insn relocation and format is the same as table entry. */
+
+ if (ELF32_R_TYPE (irel->r_info) == R_NDS32_25_PCREL_RELA
+ || ELF32_R_TYPE (irel->r_info) == R_NDS32_LO12S0_ORI_RELA
+ || ELF32_R_TYPE (irel->r_info) == R_NDS32_LO12S0_RELA
+ || ELF32_R_TYPE (irel->r_info) == R_NDS32_LO12S1_RELA
+ || ELF32_R_TYPE (irel->r_info) == R_NDS32_LO12S2_RELA
+ || (ELF32_R_TYPE (irel->r_info) >= R_NDS32_SDA15S3
+ && ELF32_R_TYPE (irel->r_info) <= R_NDS32_SDA15S0)
+ || (ELF32_R_TYPE (irel->r_info) >= R_NDS32_SDA15S3_RELA
+ && ELF32_R_TYPE (irel->r_info) <= R_NDS32_SDA15S0_RELA)
+ || (ELF32_R_TYPE (irel->r_info) >= R_NDS32_SDA12S2_DP_RELA
+ && ELF32_R_TYPE (irel->r_info) <=
+ R_NDS32_SDA12S2_SP_RELA)
+ || (ELF32_R_TYPE (irel->r_info) >= R_NDS32_SDA16S3_RELA
+ && ELF32_R_TYPE (irel->r_info) <= R_NDS32_SDA19S0_RELA))
+ {
+ r_symndx = ELF32_R_SYM (irel->r_info);
+ if (r_symndx < symtab_hdr->sh_info)
+ {
+ /* Local symbol. */
+ int shndx = isym[r_symndx].st_shndx;
+
+ isec = elf_elfsections (abfd)[shndx]->bfd_section;
+ if (ex9_insn->sec == isec
+ && ex9_insn->irel->r_addend == irel->r_addend
+ && ex9_insn->irel->r_info == irel->r_info)
+ {
+ do_replace = 1;
+ save_irel = 1;
+ }
+ }
+ else
+ {
+ /* External symbol. */
+ h = sym_hashes[r_symndx - symtab_hdr->sh_info];
+ if (ex9_insn->m_list)
+ {
+ h_list = ex9_insn->m_list->h_list;
+ while (h_list)
+ {
+ if (h == h_list->h
+ && (ex9_insn->m_list->irel->r_addend ==
+ irel->r_addend))
+ {
+ do_replace = 1;
+ save_irel = 1;
+ break;
+ }
+ h_list = h_list->next;
+ }
+ }
+ }
+ }
+ else if (ELF32_R_TYPE (irel->r_info) == R_NDS32_HI20_RELA)
+ {
+ r_symndx = ELF32_R_SYM (irel->r_info);
+ if (r_symndx < symtab_hdr->sh_info)
+ {
+ /* Local symbols. Compare its base symbol and offset. */
+ int shndx = isym[r_symndx].st_shndx;
+
+ isec = elf_elfsections (abfd)[shndx]->bfd_section;
+ if (ex9_insn->sec == isec
+ && ex9_insn->irel->r_addend == irel->r_addend
+ && ex9_insn->irel->r_info == irel->r_info)
+ {
+ do_replace = 1;
+ save_irel = 1;
+ }
+ }
+ else
+ {
+ /* External symbol. */
+ struct elf_link_hash_entry_mul_list *m_list;
+
+ h = sym_hashes[r_symndx - symtab_hdr->sh_info];
+ m_list = ex9_insn->m_list;
+
+ while (m_list)
+ {
+ h_list = m_list->h_list;
+
+ while (h_list)
+ {
+ if (h == h_list->h
+ && (m_list->irel->r_addend
+ == irel->r_addend))
+ {
+ do_replace = 1;
+ save_irel = 1;
+ if (ex9_insn->next
+ && ex9_insn->m_list
+ && ex9_insn->m_list == ex9_insn->next->m_list)
+ {
+ /* sethi multiple entry must be fixed */
+ nds32_elf_ex9_insert_fix (sec, irel,
+ h, ex9_insn->order);
+ }
+ break;
+ }
+ h_list = h_list->next;
+ }
+ m_list = m_list->next;
+ }
+ }
+ }
+ }
+
+ /* Import table: Check the symbol hash table and the
+ jump target. Only R_NDS32_25_PCREL_RELA now. */
+ else if (ex9_insn->times == -1
+ && ELF32_R_TYPE (irel->r_info) == R_NDS32_25_PCREL_RELA)
+ {
+ nds32_elf_get_insn_with_reg (irel, it_insn, &it_insn_with_reg);
+ if (insn_with_reg == it_insn_with_reg)
+ {
+ char code[10];
+ bfd_vma relocation;
+
+ r_symndx = ELF32_R_SYM (irel->r_info);
+ if (r_symndx >= symtab_hdr->sh_info)
+ {
+ h = sym_hashes[r_symndx - symtab_hdr->sh_info];
+ if ((h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak)
+ && h->root.u.def.section != NULL
+ && h->root.u.def.section->output_section != NULL
+ && h->root.u.def.section->gc_mark == 1
+ && bfd_is_abs_section (h->root.u.def.section)
+ && h->root.u.def.value > sec->size)
+ {
+ relocation = h->root.u.def.value +
+ h->root.u.def.section->output_section->vma +
+ h->root.u.def.section->output_offset;
+ relocation += irel->r_addend;
+ insn = insn_with_reg
+ | ((relocation >> 1) & 0xffffff);
+ snprintf (code, sizeof (code), "%08x", insn);
+ if (strcmp (code, ex9_insn->string) == 0)
+ {
+ do_replace = 1;
+ save_irel = 1;
+ }
+ }
+ }
+ }
+ }
+ else if (ELF32_R_TYPE (irel->r_info) == R_NDS32_RELAX_REGION_BEGIN
+ || ELF32_R_TYPE (irel->r_info) == R_NDS32_RELAX_REGION_END
+ || ELF32_R_TYPE (irel->r_info) == R_NDS32_NONE)
+ {
+ /* These relocations do not have to relocate contens, so it can
+ be regard as instruction without relocation. */
+ if (insn == it_insn && ex9_insn->irel == NULL)
+ do_replace = 1;
+ }
+ }
+ else
+ {
+ /* Instruction without relocation, we only
+ have to compare their byte code. */
+ if (insn == it_insn && ex9_insn->irel == NULL)
+ do_replace = 1;
+ }
+
+ /* Insntruction match so replacing the code here. */
+ if (do_replace == 1)
+ {
+ /* There are two formats of ex9 instruction. */
+ if (ex9_insn->order < 32)
+ insn_ex9 = INSN_EX9_IT_2;
+ else
+ insn_ex9 = INSN_EX9_IT_1;
+ insn16 = insn_ex9 | ex9_insn->order;
+
+ /* Insert ex9 instruction. */
+ nds32_elf_ex9_push_insn (pre_insn16, contents, pre_off,
+ &relax_blank_list, pre_irel_ptr,
+ &irel_list);
+ pre_off = off;
+ pre_insn16 = insn16;
+
+ if (save_irel)
+ {
+ /* For instuction with relocation do relax. */
+ irel_ptr = (struct elf_nds32_irel_entry *)
+ bfd_malloc (sizeof (struct elf_nds32_irel_entry));
+ irel_ptr->irel = irel;
+ irel_ptr->next = NULL;
+ pre_irel_ptr = irel_ptr;
+ }
+ else
+ pre_irel_ptr = NULL;
+ break;
+ }
+ ex9_insn = ex9_insn->next;
+ }
+ off += 4;
+ }
+
+ /* Insert ex9 instruction. */
+ nds32_elf_ex9_push_insn (pre_insn16, contents, pre_off,
+ &relax_blank_list, pre_irel_ptr,
+ &irel_list);
+
+ /* Delete the redundant code. */
+ if (relax_blank_list)
+ {
+ nds32_elf_relax_delete_blanks (abfd, sec, relax_blank_list);
+ relax_blank_list = NULL;
+ }
+
+ /* Clear the relocation that is replaced by ex9. */
+ while (irel_list)
+ {
+ struct elf_nds32_irel_entry *irel_ptr;
+
+ irel_ptr = irel_list;
+ irel_list = irel_ptr->next;
+ irel_ptr->irel->r_info =
+ ELF32_R_INFO (ELF32_R_SYM (irel_ptr->irel->r_info), R_NDS32_TRAN);
+ free (irel_ptr);
+ }
+ return TRUE;
+}
+
+/* Initialize ex9 hash table. */
+
+int
+nds32_elf_ex9_init (void)
+{
+ if (!bfd_hash_table_init_n (&ex9_code_table, nds32_elf_code_hash_newfunc,
+ sizeof (struct elf_nds32_code_hash_entry),
+ 1023))
+ {
+ (*_bfd_error_handler) (_("Linker: cannot init ex9 hash table error \n"));
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/* Predict how many bytes will be relaxed with ex9 and ifc. */
+
+static void
+nds32_elf_ex9_total_relax (struct bfd_link_info *info)
+{
+ struct elf_nds32_insn_times_entry *ex9_insn;
+ struct elf_nds32_insn_times_entry *temp;
+ int target_optimize;
+ struct elf_nds32_link_hash_table *table;
+
+ if (ex9_insn_head == NULL)
+ return;
+
+ table = nds32_elf_hash_table (info);
+ target_optimize = table->target_optimize;
+ ex9_insn = ex9_insn_head;
+ while (ex9_insn)
+ {
+ ex9_relax_size = ex9_insn->times * 2 + ex9_relax_size;
+ temp = ex9_insn;
+ ex9_insn = ex9_insn->next;
+ free (temp);
+ }
+ ex9_insn_head = NULL;
+
+ if ((target_optimize & NDS32_RELAX_JUMP_IFC_ON))
+ {
+ /* Examine ifc reduce size. */
+ struct elf_nds32_ifc_symbol_entry *ifc_ent = ifc_symbol_head;
+ struct elf_nds32_ifc_irel_list *irel_ptr = NULL;
+ int size = 0;
+
+ while (ifc_ent)
+ {
+ if (ifc_ent->enable == 0)
+ {
+ /* Not ifc yet. */
+ irel_ptr = ifc_ent->irel_head;
+ while (irel_ptr)
+ {
+ size += 2;
+ irel_ptr = irel_ptr->next;
+ }
+ }
+ size -= 2;
+ ifc_ent = ifc_ent->next;
+ }
+ ex9_relax_size += size;
+ }
+}
+
+/* Finish ex9 table. */
+
+void
+nds32_elf_ex9_finish (struct bfd_link_info *link_info)
+{
+ nds32_elf_code_hash_traverse (nds32_elf_examine_insn_times);
+ nds32_elf_order_insn_times (link_info);
+ nds32_elf_ex9_total_relax (link_info);
+ /* Traverse the hash table and count its times. */
+ nds32_elf_code_hash_traverse (nds32_elf_count_insn_times);
+ nds32_elf_order_insn_times (link_info);
+ nds32_elf_ex9_build_itable (link_info);
+}
+
+/* Relocate the entries in ex9 table. */
+
+static bfd_vma
+nds32_elf_ex9_reloc_insn (struct elf_nds32_insn_times_entry *ptr,
+ struct bfd_link_info *link_info)
+{
+ Elf_Internal_Sym *isym = NULL;
+ bfd_vma relocation = -1;
+ struct elf_link_hash_entry *h;
+
+ if (ptr->m_list != NULL)
+ {
+ /* Global symbol. */
+ h = ptr->m_list->h_list->h;
+ if ((h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak)
+ && h->root.u.def.section != NULL
+ && h->root.u.def.section->output_section != NULL)
+ {
+
+ relocation = h->root.u.def.value +
+ h->root.u.def.section->output_section->vma +
+ h->root.u.def.section->output_offset;
+ relocation += ptr->m_list->irel->r_addend;
+ }
+ else
+ relocation = 0;
+ }
+ else if (ptr->sec !=NULL)
+ {
+ /* Local symbol. */
+ Elf_Internal_Sym sym;
+ asection *sec = NULL;
+ asection isec;
+ asection *isec_ptr = &isec;
+ Elf_Internal_Rela irel_backup = *(ptr->irel);
+ asection *sec_backup = ptr->sec;
+ bfd *abfd = ptr->sec->owner;
+
+ if (!nds32_get_local_syms (abfd, sec, &isym))
+ return FALSE;
+ isym = isym + ELF32_R_SYM (ptr->irel->r_info);
+
+ sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
+ if (sec != NULL)
+ *isec_ptr = *sec;
+ sym = *isym;
+
+ /* The purpose is same as elf_link_input_bfd. */
+ if (isec_ptr != NULL
+ && isec_ptr->sec_info_type == SEC_INFO_TYPE_MERGE
+ && ELF_ST_TYPE (isym->st_info) != STT_SECTION)
+ {
+ sym.st_value =
+ _bfd_merged_section_offset (ptr->sec->output_section->owner, &isec_ptr,
+ elf_section_data (isec_ptr)->sec_info,
+ isym->st_value);
+ }
+ relocation = _bfd_elf_rela_local_sym (link_info->output_bfd, &sym,
+ &ptr->sec, ptr->irel);
+ if (ptr->irel != NULL)
+ relocation += ptr->irel->r_addend;
+
+ /* Restore origin value since there may be some insntructions that
+ could not be replaced with ex9.it. */
+ *(ptr->irel) = irel_backup;
+ ptr->sec = sec_backup;
+ }
+
+ return relocation;
+}
+
+/* Import ex9 table and build list. */
+
+void
+nds32_elf_ex9_import_table (struct bfd_link_info *info)
+{
+ int num = 0;
+ bfd_byte *contents;
+ unsigned long insn;
+ FILE *ex9_import_file;
+ int update_ex9_table;
+ struct elf_nds32_link_hash_table *table;
+
+ table = nds32_elf_hash_table (info);
+ ex9_import_file = table->ex9_import_file;
+ rewind (table->ex9_import_file);
+
+ contents = bfd_malloc (sizeof (bfd_byte) * 4);
+
+ /* Read instructions from the input file and build the list. */
+ while (!feof (ex9_import_file))
+ {
+ char *code;
+ struct elf_nds32_insn_times_entry *ptr;
+ size_t nread;
+
+ nread = fread (contents, sizeof (bfd_byte) * 4, 1, ex9_import_file);
+ /* Ignore the final byte 0x0a. */
+ if (nread < 1)
+ break;
+ insn = bfd_getb32 (contents);
+ code = bfd_malloc (sizeof (char) * 9);
+ snprintf (code, 9, "%08lx", insn);
+ ptr = bfd_malloc (sizeof (struct elf_nds32_insn_times_entry));
+ ptr->string = code;
+ ptr->order = num;
+ ptr->times = -1;
+ ptr->sec = NULL;
+ ptr->m_list = NULL;
+ ptr->rel_backup.r_offset = 0;
+ ptr->rel_backup.r_info = 0;
+ ptr->rel_backup.r_addend = 0;
+ ptr->irel = NULL;
+ ptr->next = NULL;
+ nds32_elf_ex9_insert_entry (ptr);
+ num++;
+ }
+
+ update_ex9_table = table->update_ex9_table;
+ if (update_ex9_table == 1)
+ {
+ /* It has to consider of sethi need to use multiple page
+ but it not be done yet. */
+ nds32_elf_code_hash_traverse (nds32_elf_examine_insn_times);
+ nds32_elf_order_insn_times (info);
+ }
+}
+
+/* Export ex9 table. */
+
+static void
+nds32_elf_ex9_export (struct bfd_link_info *info,
+ bfd_byte *contents, int size)
+{
+ FILE *ex9_export_file;
+ struct elf_nds32_link_hash_table *table;
+
+ table = nds32_elf_hash_table (info);
+ ex9_export_file = table->ex9_export_file;
+ fwrite (contents, sizeof (bfd_byte), size, ex9_export_file);
+ fclose (ex9_export_file);
+}
+
+/* Adjust relocations of J and JAL in ex9.itable.
+ Export ex9 table. */
+
+static void
+nds32_elf_ex9_reloc_jmp (struct bfd_link_info *link_info)
+{
+ asection *table_sec = NULL;
+ struct elf_nds32_insn_times_entry *ex9_insn = ex9_insn_head;
+ struct elf_nds32_insn_times_entry *temp_ptr, *temp_ptr2;
+ bfd *it_abfd;
+ uint32_t insn, insn_with_reg, source_insn;
+ bfd_byte *contents = NULL, *source_contents = NULL;
+ int size = 0;
+ bfd_vma gp;
+ int shift, update_ex9_table, offset = 0;
+ reloc_howto_type *howto = NULL;
+ Elf_Internal_Rela rel_backup;
+ unsigned short insn_ex9;
+ struct elf_nds32_link_hash_table *table;
+ FILE *ex9_export_file;
+ static bfd_boolean done = FALSE;
+
+ if (done)
+ return;
+
+ done = TRUE;
+
+ table = nds32_elf_hash_table (link_info);
+ if (table)
+ table->relax_status |= NDS32_RELAX_EX9_DONE;
+
+
+ update_ex9_table = table->update_ex9_table;
+ /* Generated ex9.itable exactly. */
+ if (update_ex9_table == 0)
+ {
+ for (it_abfd = link_info->input_bfds; it_abfd != NULL;
+ it_abfd = it_abfd->link.next)
+ {
+ table_sec = bfd_get_section_by_name (it_abfd, ".ex9.itable");
+ if (table_sec != NULL)
+ break;
+ }
+
+ if (table_sec != NULL)
+ {
+ bfd *output_bfd;
+
+ output_bfd = table_sec->output_section->owner;
+ nds32_elf_final_sda_base (output_bfd, link_info, &gp, FALSE);
+ if (table_sec->size == 0)
+ return;
+
+ if (!nds32_get_section_contents (it_abfd, table_sec, &contents))
+ return;
+ }
+ }
+ else
+ {
+ /* Set gp. */
+ bfd *output_bfd;
+
+ output_bfd = link_info->input_bfds->sections->output_section->owner;
+ nds32_elf_final_sda_base (output_bfd, link_info, &gp, FALSE);
+ contents = bfd_malloc (sizeof (bfd_byte) * 2048);
+ }
+
+ /* Relocate instruction. */
+ while (ex9_insn)
+ {
+ bfd_vma relocation, min_relocation = 0xffffffff;
+
+ insn = strtol (ex9_insn->string, NULL, 16);
+ insn_with_reg = 0;
+ if (ex9_insn->m_list != NULL || ex9_insn->sec != NULL)
+ {
+ if (ex9_insn->m_list)
+ rel_backup = ex9_insn->m_list->rel_backup;
+ else
+ rel_backup = ex9_insn->rel_backup;
+
+ nds32_elf_get_insn_with_reg (&rel_backup, insn, &insn_with_reg);
+ howto =
+ bfd_elf32_bfd_reloc_type_table_lookup (ELF32_R_TYPE
+ (rel_backup.r_info));
+ shift = howto->rightshift;
+ if (ELF32_R_TYPE (rel_backup.r_info) == R_NDS32_25_PCREL_RELA
+ || ELF32_R_TYPE (rel_backup.r_info) == R_NDS32_LO12S0_ORI_RELA
+ || ELF32_R_TYPE (rel_backup.r_info) == R_NDS32_LO12S0_RELA
+ || ELF32_R_TYPE (rel_backup.r_info) == R_NDS32_LO12S1_RELA
+ || ELF32_R_TYPE (rel_backup.r_info) == R_NDS32_LO12S2_RELA)
+ {
+ relocation = nds32_elf_ex9_reloc_insn (ex9_insn, link_info);
+ insn =
+ insn_with_reg | ((relocation >> shift) &
+ nds32_elf_irel_mask (&rel_backup));
+ bfd_putb32 (insn, contents + (ex9_insn->order) * 4);
+ }
+ else if ((ELF32_R_TYPE (rel_backup.r_info) >= R_NDS32_SDA15S3
+ && ELF32_R_TYPE (rel_backup.r_info) <= R_NDS32_SDA15S0)
+ || (ELF32_R_TYPE (rel_backup.r_info) >= R_NDS32_SDA15S3_RELA
+ && ELF32_R_TYPE (rel_backup.r_info) <= R_NDS32_SDA15S0_RELA)
+ || (ELF32_R_TYPE (rel_backup.r_info) >= R_NDS32_SDA12S2_DP_RELA
+ && ELF32_R_TYPE (rel_backup.r_info) <= R_NDS32_SDA12S2_SP_RELA)
+ || (ELF32_R_TYPE (rel_backup.r_info) >= R_NDS32_SDA16S3_RELA
+ && ELF32_R_TYPE (rel_backup.r_info) <= R_NDS32_SDA19S0_RELA))
+ {
+ relocation = nds32_elf_ex9_reloc_insn (ex9_insn, link_info);
+ insn =
+ insn_with_reg | (((relocation - gp) >> shift) &
+ nds32_elf_irel_mask (&rel_backup));
+ bfd_putb32 (insn, contents + (ex9_insn->order) * 4);
+ }
+ else if (ELF32_R_TYPE (rel_backup.r_info) == R_NDS32_HI20_RELA)
+ {
+ /* Sethi may be multiple entry for one insn. */
+ if (ex9_insn->next && ex9_insn->m_list
+ && ex9_insn->m_list == ex9_insn->next->m_list)
+ {
+ struct elf_link_hash_entry_mul_list *m_list;
+ struct elf_nds32_ex9_refix *fix_ptr;
+ struct elf_link_hash_entry *h;
+
+ temp_ptr = ex9_insn;
+ temp_ptr2 = ex9_insn;
+ m_list = ex9_insn->m_list;
+ while (m_list)
+ {
+ h = m_list->h_list->h;
+ relocation = h->root.u.def.value +
+ h->root.u.def.section->output_section->vma +
+ h->root.u.def.section->output_offset;
+ relocation += m_list->irel->r_addend;
+
+ if (relocation < min_relocation)
+ min_relocation = relocation;
+ m_list = m_list->next;
+ }
+ relocation = min_relocation;
+
+ /* Put insntruction into ex9 table. */
+ insn = insn_with_reg
+ | ((relocation >> shift) & nds32_elf_irel_mask (&rel_backup));
+ bfd_putb32 (insn, contents + (ex9_insn->order) * 4);
+ relocation = relocation + 0x1000; /* hi20 */
+
+ while (ex9_insn->next && ex9_insn->m_list
+ && ex9_insn->m_list == ex9_insn->next->m_list)
+ {
+ /* Multiple sethi. */
+ ex9_insn = ex9_insn->next;
+ size += 4;
+ insn =
+ insn_with_reg | ((relocation >> shift) &
+ nds32_elf_irel_mask (&rel_backup));
+ bfd_putb32 (insn, contents + (ex9_insn->order) * 4);
+ relocation = relocation + 0x1000; /* hi20 */
+ }
+
+ fix_ptr = ex9_refix_head;
+ while (fix_ptr)
+ {
+ /* Fix ex9 insn. */
+ /* temp_ptr2 points to the head of multiple sethi. */
+ temp_ptr = temp_ptr2;
+ while (fix_ptr->order != temp_ptr->order && fix_ptr->next)
+ {
+ fix_ptr = fix_ptr->next;
+ }
+ if (fix_ptr->order != temp_ptr->order)
+ break;
+
+ /* Set source insn. */
+ relocation =
+ fix_ptr->h->root.u.def.value +
+ fix_ptr->h->root.u.def.section->output_section->vma +
+ fix_ptr->h->root.u.def.section->output_offset;
+ relocation += fix_ptr->irel->r_addend;
+ /* sethi imm is imm20s. */
+ source_insn = insn_with_reg | ((relocation >> shift) & 0xfffff);
+
+ while (temp_ptr)
+ {
+ /* Match entry and source code. */
+ insn = bfd_getb32 (contents + (temp_ptr->order) * 4 + offset);
+ if (insn == source_insn)
+ {
+ /* Fix the ex9 insn. */
+ if (temp_ptr->order != fix_ptr->order)
+ {
+ if (!nds32_get_section_contents
+ (fix_ptr->sec->owner, fix_ptr->sec,
+ &source_contents))
+ (*_bfd_error_handler)
+ (_("Linker: error cannot fixed ex9 relocation \n"));
+ if (temp_ptr->order < 32)
+ insn_ex9 = INSN_EX9_IT_2;
+ else
+ insn_ex9 = INSN_EX9_IT_1;
+ insn_ex9 = insn_ex9 | temp_ptr->order;
+ bfd_putb16 (insn_ex9, source_contents + fix_ptr->irel->r_offset);
+ }
+ break;
+ }
+ else
+ {
+ if (!temp_ptr->next || temp_ptr->m_list != temp_ptr->next->m_list)
+ (*_bfd_error_handler)
+ (_("Linker: error cannot fixed ex9 relocation \n"));
+ else
+ temp_ptr = temp_ptr->next;
+ }
+ }
+ fix_ptr = fix_ptr->next;
+ }
+ }
+ else
+ {
+ relocation = nds32_elf_ex9_reloc_insn (ex9_insn, link_info);
+ insn = insn_with_reg
+ | ((relocation >> shift) & nds32_elf_irel_mask (&rel_backup));
+ bfd_putb32 (insn, contents + (ex9_insn->order) * 4);
+ }
+ }
+ }
+ else
+ {
+ /* Insn without relocation does not have to be fixed
+ if need to update export table. */
+ if (update_ex9_table == 1)
+ bfd_putb32 (insn, contents + (ex9_insn->order) * 4);
+ }
+ ex9_insn = ex9_insn->next;
+ size += 4;
+ }
+
+ ex9_export_file = table->ex9_export_file;
+ if (ex9_export_file != NULL)
+ nds32_elf_ex9_export (link_info, contents, table_sec->size);
+ else if (update_ex9_table == 1)
+ {
+ table->ex9_export_file = table->ex9_import_file;
+ rewind (table->ex9_export_file);
+ nds32_elf_ex9_export (link_info, contents, size);
+ }
+}
+
+/* Generate ex9 hash table. */
+
+static bfd_boolean
+nds32_elf_ex9_build_hash_table (bfd *abfd, asection *sec,
+ struct bfd_link_info *link_info)
+{
+ Elf_Internal_Rela *internal_relocs;
+ Elf_Internal_Rela *irelend;
+ Elf_Internal_Rela *irel;
+ Elf_Internal_Rela *jrel;
+ Elf_Internal_Rela rel_backup;
+ Elf_Internal_Shdr *symtab_hdr;
+ Elf_Internal_Sym *isym = NULL;
+ asection *isec;
+ struct elf_link_hash_entry **sym_hashes;
+ bfd_byte *contents = NULL;
+ bfd_vma off = 0;
+ unsigned long r_symndx;
+ uint32_t insn, insn_with_reg;
+ struct elf_link_hash_entry *h;
+ int data_flag, shift, align;
+ bfd_vma relocation;
+ /* Suppress ex9 if `.no_relax ex9' or inner loop. */
+ reloc_howto_type *howto = NULL;
+
+ sym_hashes = elf_sym_hashes (abfd);
+ /* Load section instructions, relocations, and symbol table. */
+ if (!nds32_get_section_contents (abfd, sec, &contents))
+ return FALSE;
+
+ internal_relocs = _bfd_elf_link_read_relocs (abfd, sec, NULL, NULL,
+ TRUE /* keep_memory */);
+ irelend = internal_relocs + sec->reloc_count;
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+ if (!nds32_get_local_syms (abfd, sec, &isym))
+ return FALSE;
+
+ /* Check the object if enable ex9. */
+ irel = find_relocs_at_address (internal_relocs, internal_relocs, irelend,
+ R_NDS32_RELAX_ENTRY);
+
+ /* Check this section trigger ex9 relaxation. */
+ if (irel == NULL
+ || irel >= irelend
+ || ELF32_R_TYPE (irel->r_info) != R_NDS32_RELAX_ENTRY
+ || (ELF32_R_TYPE (irel->r_info) == R_NDS32_RELAX_ENTRY
+ && !(irel->r_addend & R_NDS32_RELAX_ENTRY_EX9_FLAG)))
+ return TRUE;
+
+ irel = internal_relocs;
+
+ /* Push each insn into hash table. */
+ while (off < sec->size)
+ {
+ char code[10];
+ struct elf_nds32_code_hash_entry *entry;
+
+ while (irel != NULL && irel < irelend && irel->r_offset < off)
+ irel++;
+
+ data_flag = nds32_elf_ex9_relocation_check (link_info, &irel, irelend,
+ NULL, sec, &off, contents);
+ if (data_flag & DATA_EXIST)
+ {
+ /* We save the move offset in the highest byte. */
+ off += (data_flag >> 24);
+ continue;
+ }
+
+ if (*(contents + off) & 0x80)
+ {
+ off += 2;
+ }
+ else
+ {
+ h = NULL;
+ isec = NULL;
+ jrel = NULL;
+ rel_backup.r_info = 0;
+ rel_backup.r_offset = 0;
+ rel_backup.r_addend = 0;
+ /* Load the instruction and its opcode with register for comparing. */
+ insn = bfd_getb32 (contents + off);
+ insn_with_reg = 0;
+ if (irel != NULL && irel < irelend && irel->r_offset == off)
+ {
+ nds32_elf_get_insn_with_reg (irel, insn, &insn_with_reg);
+ howto = bfd_elf32_bfd_reloc_type_table_lookup (ELF32_R_TYPE (irel->r_info));
+ shift = howto->rightshift;
+ align = (1 << shift) - 1;
+ if (ELF32_R_TYPE (irel->r_info) == R_NDS32_25_PCREL_RELA
+ || ELF32_R_TYPE (irel->r_info) == R_NDS32_HI20_RELA
+ || ELF32_R_TYPE (irel->r_info) == R_NDS32_LO12S0_ORI_RELA
+ || ELF32_R_TYPE (irel->r_info) == R_NDS32_LO12S0_RELA
+ || ELF32_R_TYPE (irel->r_info) == R_NDS32_LO12S1_RELA
+ || ELF32_R_TYPE (irel->r_info) == R_NDS32_LO12S2_RELA
+ ||(ELF32_R_TYPE (irel->r_info) >= R_NDS32_SDA15S3
+ && ELF32_R_TYPE (irel->r_info) <= R_NDS32_SDA15S0)
+ || (ELF32_R_TYPE (irel->r_info) >= R_NDS32_SDA15S3_RELA
+ && ELF32_R_TYPE (irel->r_info) <= R_NDS32_SDA15S0_RELA)
+ || (ELF32_R_TYPE (irel->r_info) >= R_NDS32_SDA12S2_DP_RELA
+ && ELF32_R_TYPE (irel->r_info) <= R_NDS32_SDA12S2_SP_RELA)
+ || (ELF32_R_TYPE (irel->r_info) >= R_NDS32_SDA16S3_RELA
+ && ELF32_R_TYPE (irel->r_info) <= R_NDS32_SDA19S0_RELA))
+ {
+ r_symndx = ELF32_R_SYM (irel->r_info);
+ jrel = irel;
+ rel_backup = *irel;
+ if (r_symndx < symtab_hdr->sh_info)
+ {
+ /* Local symbol. */
+ int shndx = isym[r_symndx].st_shndx;
+
+ bfd_vma st_value = (isym + r_symndx)->st_value;
+ isec = elf_elfsections (abfd)[shndx]->bfd_section;
+ relocation = (isec->output_section->vma + isec->output_offset
+ + st_value + irel->r_addend);
+ }
+ else
+ {
+ /* External symbol. */
+ bfd_boolean warned ATTRIBUTE_UNUSED;
+ bfd_boolean ignored ATTRIBUTE_UNUSED;
+ bfd_boolean unresolved_reloc ATTRIBUTE_UNUSED;
+ asection *sym_sec;
+
+ /* Maybe there is a better way to get h and relocation */
+ RELOC_FOR_GLOBAL_SYMBOL (link_info, abfd, sec, irel,
+ r_symndx, symtab_hdr, sym_hashes,
+ h, sym_sec, relocation,
+ unresolved_reloc, warned, ignored);
+ relocation += irel->r_addend;
+ if ((h->root.type != bfd_link_hash_defined
+ && h->root.type != bfd_link_hash_defweak)
+ || strcmp (h->root.root.string, "_FP_BASE_") == 0)
+ {
+ off += 4;
+ continue;
+ }
+ }
+
+ /* Check for gp relative instruction alignment. */
+ if ((ELF32_R_TYPE (irel->r_info) >= R_NDS32_SDA15S3
+ && ELF32_R_TYPE (irel->r_info) <= R_NDS32_SDA15S0)
+ || (ELF32_R_TYPE (irel->r_info) >= R_NDS32_SDA15S3_RELA
+ && ELF32_R_TYPE (irel->r_info) <= R_NDS32_SDA15S0_RELA)
+ || (ELF32_R_TYPE (irel->r_info) >= R_NDS32_SDA12S2_DP_RELA
+ && ELF32_R_TYPE (irel->r_info) <= R_NDS32_SDA12S2_SP_RELA)
+ || (ELF32_R_TYPE (irel->r_info) >= R_NDS32_SDA16S3_RELA
+ && ELF32_R_TYPE (irel->r_info) <= R_NDS32_SDA19S0_RELA))
+ {
+ bfd_vma gp;
+ bfd *output_bfd = sec->output_section->owner;
+ bfd_reloc_status_type r;
+
+ /* If the symbol is in the abs section, the out_bfd will be null.
+ This happens when the relocation has a symbol@GOTOFF. */
+ r = nds32_elf_final_sda_base (output_bfd, link_info, &gp, FALSE);
+ if (r != bfd_reloc_ok)
+ {
+ off += 4;
+ continue;
+ }
+
+ relocation -= gp;
+
+ /* Make sure alignment is correct. */
+ if (relocation & align)
+ {
+ /* Incorrect alignment. */
+ (*_bfd_error_handler)
+ (_("%s: warning: unaligned small data access. "
+ "For entry: {%d, %d, %d}, addr = 0x%x, align = 0x%x."),
+ bfd_get_filename (abfd), irel->r_offset,
+ irel->r_info, irel->r_addend, relocation, align);
+ off += 4;
+ continue;
+ }
+ }
+
+ insn = insn_with_reg
+ | ((relocation >> shift) & nds32_elf_irel_mask (irel));
+ }
+ else if (ELF32_R_TYPE (irel->r_info) == R_NDS32_RELAX_REGION_BEGIN
+ || ELF32_R_TYPE (irel->r_info) == R_NDS32_RELAX_REGION_END
+ || ELF32_R_TYPE (irel->r_info) == R_NDS32_NONE)
+ {
+ /* These relocations do not have to relocate contens, so it can
+ be regard as instruction without relocation. */
+ }
+ else
+ {
+ off += 4;
+ continue;
+ }
+ }
+
+ snprintf (code, sizeof (code), "%08x", insn);
+ /* Copy "code". */
+ entry = (struct elf_nds32_code_hash_entry*)
+ bfd_hash_lookup (&ex9_code_table, code, TRUE, TRUE);
+ if (entry == NULL)
+ {
+ (*_bfd_error_handler)
+ (_("%P%F: failed creating ex9.it %s hash table: %E\n"), code);
+ return FALSE;
+ }
+ if (h)
+ {
+ if (h->root.type == bfd_link_hash_undefined)
+ return TRUE;
+ /* Global symbol. */
+ /* In order to do sethi with different symbol but same value. */
+ if (entry->m_list == NULL)
+ {
+ struct elf_link_hash_entry_mul_list *m_list_new;
+ struct elf_link_hash_entry_list *h_list_new;
+
+ m_list_new = (struct elf_link_hash_entry_mul_list *)
+ bfd_malloc (sizeof (struct elf_link_hash_entry_mul_list));
+ h_list_new = (struct elf_link_hash_entry_list *)
+ bfd_malloc (sizeof (struct elf_link_hash_entry_list));
+ entry->m_list = m_list_new;
+ m_list_new->h_list = h_list_new;
+ m_list_new->rel_backup = rel_backup;
+ m_list_new->times = 1;
+ m_list_new->irel = jrel;
+ m_list_new->next = NULL;
+ h_list_new->h = h;
+ h_list_new->next = NULL;
+ }
+ else
+ {
+ struct elf_link_hash_entry_mul_list *m_list = entry->m_list;
+ struct elf_link_hash_entry_list *h_list;
+
+ while (m_list)
+ {
+ /* Build the different symbols that point to the same address. */
+ h_list = m_list->h_list;
+ if (h_list->h->root.u.def.value == h->root.u.def.value
+ && h_list->h->root.u.def.section->output_section->vma
+ == h->root.u.def.section->output_section->vma
+ && h_list->h->root.u.def.section->output_offset
+ == h->root.u.def.section->output_offset
+ && m_list->rel_backup.r_addend == rel_backup.r_addend)
+ {
+ m_list->times++;
+ m_list->irel = jrel;
+ while (h_list->h != h && h_list->next)
+ h_list = h_list->next;
+ if (h_list->h != h)
+ {
+ struct elf_link_hash_entry_list *h_list_new;
+
+ h_list_new = (struct elf_link_hash_entry_list *)
+ bfd_malloc (sizeof (struct elf_link_hash_entry_list));
+ h_list->next = h_list_new;
+ h_list_new->h = h;
+ h_list_new->next = NULL;
+ }
+ break;
+ }
+ /* The sethi case may have different address but the
+ hi20 is the same. */
+ else if (ELF32_R_TYPE (jrel->r_info) == R_NDS32_HI20_RELA
+ && m_list->next == NULL)
+ {
+ struct elf_link_hash_entry_mul_list *m_list_new;
+ struct elf_link_hash_entry_list *h_list_new;
+
+ m_list_new = (struct elf_link_hash_entry_mul_list *)
+ bfd_malloc (sizeof (struct elf_link_hash_entry_mul_list));
+ h_list_new = (struct elf_link_hash_entry_list *)
+ bfd_malloc (sizeof (struct elf_link_hash_entry_list));
+ m_list->next = m_list_new;
+ m_list_new->h_list = h_list_new;
+ m_list_new->rel_backup = rel_backup;
+ m_list_new->times = 1;
+ m_list_new->irel = jrel;
+ m_list_new->next = NULL;
+ h_list_new->h = h;
+ h_list_new->next = NULL;
+ break;
+ }
+ m_list = m_list->next;
+ }
+ if (!m_list)
+ {
+ off += 4;
+ continue;
+ }
+ }
+ }
+ else
+ {
+ /* Local symbol and insn without relocation*/
+ entry->times++;
+ entry->rel_backup = rel_backup;
+ }
+
+ /* Use in sethi insn with constant and global symbol in same format. */
+ if (!jrel)
+ entry->const_insn = 1;
+ else
+ entry->irel = jrel;
+ entry->sec = isec;
+ off += 4;
+ }
+ }
+ return TRUE;
+}
+
+/* Set the _ITB_BASE, and point it to ex9 table. */
+
+bfd_boolean
+nds32_elf_ex9_itb_base (struct bfd_link_info *link_info)
+{
+ bfd *abfd;
+ asection *sec;
+ bfd *output_bfd = NULL;
+ struct bfd_link_hash_entry *bh = NULL;
+
+ if (is_ITB_BASE_set == 1)
+ return TRUE;
+
+ is_ITB_BASE_set = 1;
+
+ bh = bfd_link_hash_lookup (link_info->hash, "_ITB_BASE_", FALSE, FALSE, TRUE);
+
+ if (bh && (bh->type == bfd_link_hash_defined
+ || bh->type == bfd_link_hash_defweak))
+ return TRUE;
+
+ for (abfd = link_info->input_bfds; abfd != NULL;
+ abfd = abfd->link.next)
+ {
+ sec = bfd_get_section_by_name (abfd, ".ex9.itable");
+ if (sec != NULL)
+ {
+ output_bfd = sec->output_section->owner;
+ break;
+ }
+ }
+ if (output_bfd == NULL)
+ {
+ output_bfd = link_info->output_bfd;
+ if (output_bfd->sections == NULL)
+ return TRUE;
+ else
+ sec = bfd_abs_section_ptr;
+ }
+ bh = bfd_link_hash_lookup (link_info->hash, "_ITB_BASE_",
+ FALSE, FALSE, TRUE);
+ return (_bfd_generic_link_add_one_symbol
+ (link_info, output_bfd, "_ITB_BASE_",
+ BSF_GLOBAL | BSF_WEAK, sec, 0,
+ (const char *) NULL, FALSE, get_elf_backend_data
+ (output_bfd)->collect, &bh));
+} /* End EX9.IT */
+
+
+#define ELF_ARCH bfd_arch_nds32
+#define ELF_MACHINE_CODE EM_NDS32
+#define ELF_MAXPAGESIZE 0x1000
+#define ELF_TARGET_ID NDS32_ELF_DATA
+
+#define TARGET_BIG_SYM nds32_elf32_be_vec
+#define TARGET_BIG_NAME "elf32-nds32be"
+#define TARGET_LITTLE_SYM nds32_elf32_le_vec
+#define TARGET_LITTLE_NAME "elf32-nds32le"
+
+#define elf_info_to_howto nds32_info_to_howto
+#define elf_info_to_howto_rel nds32_info_to_howto_rel
+
+#define bfd_elf32_bfd_link_hash_table_create nds32_elf_link_hash_table_create
+#define bfd_elf32_bfd_merge_private_bfd_data nds32_elf_merge_private_bfd_data
+#define bfd_elf32_bfd_print_private_bfd_data nds32_elf_print_private_bfd_data
+#define bfd_elf32_bfd_relax_section nds32_elf_relax_section
+#define bfd_elf32_bfd_set_private_flags nds32_elf_set_private_flags
+
+#define bfd_elf32_mkobject nds32_elf_mkobject
+#define elf_backend_action_discarded nds32_elf_action_discarded
+#define elf_backend_add_symbol_hook nds32_elf_add_symbol_hook
+#define elf_backend_check_relocs nds32_elf_check_relocs
+#define elf_backend_adjust_dynamic_symbol nds32_elf_adjust_dynamic_symbol
+#define elf_backend_create_dynamic_sections nds32_elf_create_dynamic_sections
+#define elf_backend_finish_dynamic_sections nds32_elf_finish_dynamic_sections
+#define elf_backend_finish_dynamic_symbol nds32_elf_finish_dynamic_symbol
+#define elf_backend_size_dynamic_sections nds32_elf_size_dynamic_sections
+#define elf_backend_relocate_section nds32_elf_relocate_section
+#define elf_backend_gc_mark_hook nds32_elf_gc_mark_hook
+#define elf_backend_gc_sweep_hook nds32_elf_gc_sweep_hook
+#define elf_backend_grok_prstatus nds32_elf_grok_prstatus
+#define elf_backend_grok_psinfo nds32_elf_grok_psinfo
+#define elf_backend_reloc_type_class nds32_elf_reloc_type_class
+#define elf_backend_copy_indirect_symbol nds32_elf_copy_indirect_symbol
+#define elf_backend_link_output_symbol_hook nds32_elf_output_symbol_hook
+#define elf_backend_output_arch_syms nds32_elf_output_arch_syms
+#define elf_backend_object_p nds32_elf_object_p
+#define elf_backend_final_write_processing nds32_elf_final_write_processing
+#define elf_backend_special_sections nds32_elf_special_sections
+#define bfd_elf32_bfd_get_relocated_section_contents \
+ nds32_elf_get_relocated_section_contents
+
+#define elf_backend_can_gc_sections 1
+#define elf_backend_can_refcount 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_may_use_rel_p 1
+#define elf_backend_default_use_rela_p 1
+#define elf_backend_may_use_rela_p 1
+
+#include "elf32-target.h"
+
+#undef ELF_MAXPAGESIZE
+#define ELF_MAXPAGESIZE 0x2000
+
+#undef TARGET_BIG_SYM
+#define TARGET_BIG_SYM nds32_elf32_linux_be_vec
+#undef TARGET_BIG_NAME
+#define TARGET_BIG_NAME "elf32-nds32be-linux"
+#undef TARGET_LITTLE_SYM
+#define TARGET_LITTLE_SYM nds32_elf32_linux_le_vec
+#undef TARGET_LITTLE_NAME
+#define TARGET_LITTLE_NAME "elf32-nds32le-linux"
+#undef elf32_bed
+#define elf32_bed elf32_nds32_lin_bed
+
+#include "elf32-target.h"
diff --git a/bfd/elf32-nds32.h b/bfd/elf32-nds32.h
new file mode 100644
index 0000000..d4d4e93
--- /dev/null
+++ b/bfd/elf32-nds32.h
@@ -0,0 +1,155 @@
+/* NDS32-specific support for 32-bit ELF.
+ Copyright (C) 2012-2014 Free Software Foundation, Inc.
+ Contributed by Andes Technology Corporation.
+
+ This file is part of BFD, the Binary File Descriptor library.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
+ 02110-1301, USA.*/
+
+#ifndef ELF32_NDS32_H
+#define ELF32_NDS32_H
+
+/* Relocation flags encoded in r_addend. */
+
+/* Relocation flags for R_NDS32_ERLAX_ENTRY. */
+
+/* Set if relax on this section is done or disabled. */
+#define R_NDS32_RELAX_ENTRY_DISABLE_RELAX_FLAG (1 << 31)
+/* Optimize for performance. */
+#define R_NDS32_RELAX_ENTRY_OPTIMIZE_FLAG (1 << 30)
+/* Optimize for size. Branch destination 4-byte adjustment
+ may be disabled. */
+#define R_NDS32_RELAX_ENTRY_OPTIMIZE_FOR_SPACE_FLAG (1 << 29)
+/* To distinguish the assembly code generated by compiler
+ or written manually. */
+#define R_NDS32_RELAX_ENTRY_VERBATIM_FLAG (1 << 28)
+/* EX9 and link-time IFC must be explicitly enabled, so we
+ won't mess up handcraft assembly code. */
+/* Enable EX9 optimization for this section. */
+#define R_NDS32_RELAX_ENTRY_EX9_FLAG (1 << 2)
+/* Enable IFC optimization for this section. */
+#define R_NDS32_RELAX_ENTRY_IFC_FLAG (1 << 3)
+
+
+/* Relocation flags for R_NDS32_INSN16. */
+
+/* Tag the nop16 can be removed. */
+#define R_NDS32_INSN16_CONVERT_FLAG (1 << 0)
+/* Convert a gp-relative access (e.g., lwi.gp)
+ to fp-as-gp access (lwi37.fp).
+ This value is used by linker internally only.
+ It's fine to change the vlaue. */
+#define R_NDS32_INSN16_FP7U2_FLAG (1 << 1)
+
+/* Relocation flags for R_NDS32_RELAX_REGION_OMIT_FP_START/END. */
+
+/* OMIT_FP_FLAG marks the region for applying fp-as-gp
+ optimization. */
+#define R_NDS32_RELAX_REGION_OMIT_FP_FLAG (1 << 0)
+/* NOT_OMIT_FP_FLAG is set if this region is not worth
+ for fp-as-gp. */
+#define R_NDS32_RELAX_REGION_NOT_OMIT_FP_FLAG (1 << 1)
+/* Suppress EX9 optimization in the region. */
+#define R_NDS32_RELAX_REGION_NO_EX9_FLAG (1 << 2)
+/* A Innermost loop region. Some optimizations is suppressed
+ in this region due to performance drop. */
+#define R_NDS32_RELAX_REGION_INNERMOST_LOOP_FLAG (1 << 4)
+
+/* Tag range for LOADSTORE relocation. */
+enum
+{
+ NDS32_LOADSTORE_NONE = 0x0,
+ NDS32_LOADSTORE_BYTE = 0x1,
+ NDS32_LOADSTORE_HALF = 0x2,
+ NDS32_LOADSTORE_WORD = 0x4,
+ NDS32_LOADSTORE_FLOAT_S = 0x8,
+ NDS32_LOADSTORE_FLOAT_D = 0x10,
+ NDS32_LOADSTORE_IMM = 0x20
+};
+
+/* Relax tag for nds32_elf_relax_section, we have to specify which
+ optimization do in this round. */
+enum
+{
+ NDS32_RELAX_NONE_ROUND = 0,
+ NDS32_RELAX_NORMAL_ROUND,
+ NDS32_RELAX_JUMP_IFC_ROUND,
+ NDS32_RELAX_EX9_BUILD_ROUND,
+ NDS32_RELAX_EX9_REPLACE_ROUND,
+ NDS32_RELAX_EMPTY_ROUND
+};
+
+/* Optimization status mask. */
+#define NDS32_RELAX_JUMP_IFC_DONE (1 << 0)
+#define NDS32_RELAX_EX9_DONE (1 << 1)
+
+/* Optimization turn on mask. */
+#define NDS32_RELAX_JUMP_IFC_ON (1 << 0)
+#define NDS32_RELAX_EX9_ON (1 << 1)
+
+extern void nds32_insertion_sort
+ (void *, size_t, size_t, int (*) (const void *, const void *));
+
+extern int nds32_elf_ex9_init (void);
+extern int nds32_convert_32_to_16 (bfd *, uint32_t, uint16_t *, int *);
+extern int nds32_convert_16_to_32 (bfd *, uint16_t, uint32_t *);
+extern void bfd_elf32_nds32_set_target_option (struct bfd_link_info *,
+ int, int, FILE *, int,
+ int, int, int, FILE *,
+ FILE *, int, int,
+ bfd_boolean, bfd_boolean);
+
+#define nds32_elf_hash_table(info) \
+ (elf_hash_table_id ((struct elf_link_hash_table *) ((info)->hash)) \
+ == NDS32_ELF_DATA ? \
+ ((struct elf_nds32_link_hash_table *) ((info)->hash)) : NULL)
+
+/* Hash table structure for target nds32. There are some members to
+ save target options passed from nds32elf.em to bfd. */
+
+struct elf_nds32_link_hash_table
+{
+ struct elf_link_hash_table root;
+
+ /* Short-cuts to get to dynamic linker sections. */
+ asection *sgot;
+ asection *sgotplt;
+ asection *srelgot;
+ asection *splt;
+ asection *srelplt;
+ asection *sdynbss;
+ asection *srelbss;
+
+ /* Small local sym to section mapping cache. */
+ struct sym_cache sym_cache;
+
+ /* Target dependent options. */
+ int relax_fp_as_gp; /* --mrelax-omit-fp */
+ int eliminate_gc_relocs; /* --meliminate-gc-relocs */
+ FILE *sym_ld_script; /* --mgen-symbol-ld-script=<file> */
+ /* Disable if linking a dynamically linked executable. */
+ int load_store_relax;
+ int target_optimize; /* Switch optimization. */
+ int relax_status; /* Finished optimization. */
+ int relax_round; /* Going optimization. */
+ FILE *ex9_export_file; /* --mexport-ex9=<file> */
+ FILE *ex9_import_file; /* --mimport-ex9=<file> */
+ int update_ex9_table; /* --mupdate-ex9. */
+ int ex9_limit;
+ bfd_boolean ex9_loop_aware; /* Ignore ex9 if inside a loop. */
+ bfd_boolean ifc_loop_aware; /* Ignore ifc if inside a loop. */
+};
+#endif
diff --git a/bfd/elf32-nios2.c b/bfd/elf32-nios2.c
new file mode 100644
index 0000000..9b3f436
--- /dev/null
+++ b/bfd/elf32-nios2.c
@@ -0,0 +1,5311 @@
+/* 32-bit ELF support for Nios II.
+ Copyright (C) 2012-2014 Free Software Foundation, Inc.
+ Contributed by Nigel Gray (ngray@altera.com).
+ Contributed by Mentor Graphics, 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+/* This file handles Altera Nios II ELF targets. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+#include "bfdlink.h"
+#include "genlink.h"
+#include "elf-bfd.h"
+#include "elf/nios2.h"
+#include "opcode/nios2.h"
+#include "elf32-nios2.h"
+
+/* Use RELA relocations. */
+#ifndef USE_RELA
+#define USE_RELA
+#endif
+
+#ifdef USE_REL
+#undef USE_REL
+#endif
+
+/* Forward declarations. */
+static bfd_reloc_status_type nios2_elf32_ignore_reloc
+ (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
+static bfd_reloc_status_type nios2_elf32_hi16_relocate
+ (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
+static bfd_reloc_status_type nios2_elf32_lo16_relocate
+ (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
+static bfd_reloc_status_type nios2_elf32_hiadj16_relocate
+ (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
+static bfd_reloc_status_type nios2_elf32_pcrel_lo16_relocate
+ (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
+static bfd_reloc_status_type nios2_elf32_pcrel_hiadj16_relocate
+ (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
+static bfd_reloc_status_type nios2_elf32_pcrel16_relocate
+ (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
+static bfd_reloc_status_type nios2_elf32_call26_relocate
+ (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
+static bfd_reloc_status_type nios2_elf32_gprel_relocate
+ (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
+static bfd_reloc_status_type nios2_elf32_ujmp_relocate
+ (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
+static bfd_reloc_status_type nios2_elf32_cjmp_relocate
+ (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
+static bfd_reloc_status_type nios2_elf32_callr_relocate
+ (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
+
+/* Target vector. */
+extern const bfd_target nios2_elf32_le_vec;
+extern const bfd_target nios2_elf32_be_vec;
+
+/* Offset of tp and dtp pointers from start of TLS block. */
+#define TP_OFFSET 0x7000
+#define DTP_OFFSET 0x8000
+
+/* The relocation table used for SHT_REL sections. */
+static reloc_howto_type elf_nios2_howto_table_rel[] = {
+ /* No relocation. */
+ HOWTO (R_NIOS2_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_NIOS2_NONE", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* 16-bit signed immediate relocation. */
+ HOWTO (R_NIOS2_S16, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 6, /* bitpos */
+ complain_overflow_signed, /* complain on overflow */
+ bfd_elf_generic_reloc, /* special function */
+ "R_NIOS2_S16", /* name */
+ FALSE, /* partial_inplace */
+ 0x003fffc0, /* src_mask */
+ 0x003fffc0, /* dest_mask */
+ FALSE), /* pcrel_offset */
+
+ /* 16-bit unsigned immediate relocation. */
+ HOWTO (R_NIOS2_U16, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 6, /* bitpos */
+ complain_overflow_unsigned, /* complain on overflow */
+ bfd_elf_generic_reloc, /* special function */
+ "R_NIOS2_U16", /* name */
+ FALSE, /* partial_inplace */
+ 0x003fffc0, /* src_mask */
+ 0x003fffc0, /* dest_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_NIOS2_PCREL16, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ TRUE, /* pc_relative */
+ 6, /* bitpos */
+ complain_overflow_signed, /* complain on overflow */
+ nios2_elf32_pcrel16_relocate, /* special function */
+ "R_NIOS2_PCREL16", /* name */
+ FALSE, /* partial_inplace */
+ 0x003fffc0, /* src_mask */
+ 0x003fffc0, /* dest_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_NIOS2_CALL26, /* type */
+ 2, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 26, /* bitsize */
+ FALSE, /* pc_relative */
+ 6, /* bitpos */
+ complain_overflow_dont, /* complain on overflow */
+ nios2_elf32_call26_relocate, /* special function */
+ "R_NIOS2_CALL26", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffc0, /* src_mask */
+ 0xffffffc0, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_NIOS2_IMM5,
+ 0,
+ 2,
+ 5,
+ FALSE,
+ 6,
+ complain_overflow_bitfield,
+ bfd_elf_generic_reloc,
+ "R_NIOS2_IMM5",
+ FALSE,
+ 0x000007c0,
+ 0x000007c0,
+ FALSE),
+
+ HOWTO (R_NIOS2_CACHE_OPX,
+ 0,
+ 2,
+ 5,
+ FALSE,
+ 22,
+ complain_overflow_bitfield,
+ bfd_elf_generic_reloc,
+ "R_NIOS2_CACHE_OPX",
+ FALSE,
+ 0x07c00000,
+ 0x07c00000,
+ FALSE),
+
+ HOWTO (R_NIOS2_IMM6,
+ 0,
+ 2,
+ 6,
+ FALSE,
+ 6,
+ complain_overflow_bitfield,
+ bfd_elf_generic_reloc,
+ "R_NIOS2_IMM6",
+ FALSE,
+ 0x00000fc0,
+ 0x00000fc0,
+ FALSE),
+
+ HOWTO (R_NIOS2_IMM8,
+ 0,
+ 2,
+ 8,
+ FALSE,
+ 6,
+ complain_overflow_bitfield,
+ bfd_elf_generic_reloc,
+ "R_NIOS2_IMM8",
+ FALSE,
+ 0x00003fc0,
+ 0x00003fc0,
+ FALSE),
+
+ HOWTO (R_NIOS2_HI16,
+ 0,
+ 2,
+ 32,
+ FALSE,
+ 6,
+ complain_overflow_dont,
+ nios2_elf32_hi16_relocate,
+ "R_NIOS2_HI16",
+ FALSE,
+ 0x003fffc0,
+ 0x003fffc0,
+ FALSE),
+
+ HOWTO (R_NIOS2_LO16,
+ 0,
+ 2,
+ 32,
+ FALSE,
+ 6,
+ complain_overflow_dont,
+ nios2_elf32_lo16_relocate,
+ "R_NIOS2_LO16",
+ FALSE,
+ 0x003fffc0,
+ 0x003fffc0,
+ FALSE),
+
+ HOWTO (R_NIOS2_HIADJ16,
+ 0,
+ 2,
+ 32,
+ FALSE,
+ 6,
+ complain_overflow_dont,
+ nios2_elf32_hiadj16_relocate,
+ "R_NIOS2_HIADJ16",
+ FALSE,
+ 0x003fffc0,
+ 0x003fffc0,
+ FALSE),
+
+ HOWTO (R_NIOS2_BFD_RELOC_32,
+ 0,
+ 2, /* long */
+ 32,
+ FALSE,
+ 0,
+ complain_overflow_dont,
+ bfd_elf_generic_reloc,
+ "R_NIOS2_BFD_RELOC32",
+ FALSE,
+ 0xffffffff,
+ 0xffffffff,
+ FALSE),
+
+ HOWTO (R_NIOS2_BFD_RELOC_16,
+ 0,
+ 1, /* short */
+ 16,
+ FALSE,
+ 0,
+ complain_overflow_bitfield,
+ bfd_elf_generic_reloc,
+ "R_NIOS2_BFD_RELOC16",
+ FALSE,
+ 0x0000ffff,
+ 0x0000ffff,
+ FALSE),
+
+ HOWTO (R_NIOS2_BFD_RELOC_8,
+ 0,
+ 0, /* byte */
+ 8,
+ FALSE,
+ 0,
+ complain_overflow_bitfield,
+ bfd_elf_generic_reloc,
+ "R_NIOS2_BFD_RELOC8",
+ FALSE,
+ 0x000000ff,
+ 0x000000ff,
+ FALSE),
+
+ HOWTO (R_NIOS2_GPREL,
+ 0,
+ 2,
+ 32,
+ FALSE,
+ 6,
+ complain_overflow_dont,
+ nios2_elf32_gprel_relocate,
+ "R_NIOS2_GPREL",
+ FALSE,
+ 0x003fffc0,
+ 0x003fffc0,
+ FALSE),
+
+ HOWTO (R_NIOS2_GNU_VTINHERIT,
+ 0,
+ 2, /* short */
+ 0,
+ FALSE,
+ 0,
+ complain_overflow_dont,
+ NULL,
+ "R_NIOS2_GNU_VTINHERIT",
+ FALSE,
+ 0,
+ 0,
+ FALSE),
+
+ HOWTO (R_NIOS2_GNU_VTENTRY,
+ 0,
+ 2, /* byte */
+ 0,
+ FALSE,
+ 0,
+ complain_overflow_dont,
+ _bfd_elf_rel_vtable_reloc_fn,
+ "R_NIOS2_GNU_VTENTRY",
+ FALSE,
+ 0,
+ 0,
+ FALSE),
+
+ HOWTO (R_NIOS2_UJMP,
+ 0,
+ 2,
+ 32,
+ FALSE,
+ 6,
+ complain_overflow_dont,
+ nios2_elf32_ujmp_relocate,
+ "R_NIOS2_UJMP",
+ FALSE,
+ 0x003fffc0,
+ 0x003fffc0,
+ FALSE),
+
+ HOWTO (R_NIOS2_CJMP,
+ 0,
+ 2,
+ 32,
+ FALSE,
+ 6,
+ complain_overflow_dont,
+ nios2_elf32_cjmp_relocate,
+ "R_NIOS2_CJMP",
+ FALSE,
+ 0x003fffc0,
+ 0x003fffc0,
+ FALSE),
+
+ HOWTO (R_NIOS2_CALLR,
+ 0,
+ 2,
+ 32,
+ FALSE,
+ 6,
+ complain_overflow_dont,
+ nios2_elf32_callr_relocate,
+ "R_NIOS2_CALLR",
+ FALSE,
+ 0x003fffc0,
+ 0x003fffc0,
+ FALSE),
+
+ HOWTO (R_NIOS2_ALIGN,
+ 0,
+ 2,
+ 0,
+ FALSE,
+ 0,
+ complain_overflow_dont,
+ nios2_elf32_ignore_reloc,
+ "R_NIOS2_ALIGN",
+ FALSE,
+ 0,
+ 0,
+ TRUE),
+
+
+ HOWTO (R_NIOS2_GOT16,
+ 0,
+ 2,
+ 16,
+ FALSE,
+ 6,
+ complain_overflow_bitfield,
+ bfd_elf_generic_reloc,
+ "R_NIOS2_GOT16",
+ FALSE,
+ 0x003fffc0,
+ 0x003fffc0,
+ FALSE),
+
+ HOWTO (R_NIOS2_CALL16,
+ 0,
+ 2,
+ 16,
+ FALSE,
+ 6,
+ complain_overflow_bitfield,
+ bfd_elf_generic_reloc,
+ "R_NIOS2_CALL16",
+ FALSE,
+ 0x003fffc0,
+ 0x003fffc0,
+ FALSE),
+
+ HOWTO (R_NIOS2_GOTOFF_LO,
+ 0,
+ 2,
+ 16,
+ FALSE,
+ 6,
+ complain_overflow_dont,
+ bfd_elf_generic_reloc,
+ "R_NIOS2_GOTOFF_LO",
+ FALSE,
+ 0x003fffc0,
+ 0x003fffc0,
+ FALSE),
+
+ HOWTO (R_NIOS2_GOTOFF_HA,
+ 0,
+ 2,
+ 16,
+ FALSE,
+ 6,
+ complain_overflow_dont,
+ bfd_elf_generic_reloc,
+ "R_NIOS2_GOTOFF_HA",
+ FALSE,
+ 0x003fffc0,
+ 0x003fffc0,
+ FALSE),
+
+ HOWTO (R_NIOS2_PCREL_LO,
+ 0,
+ 2,
+ 16,
+ TRUE,
+ 6,
+ complain_overflow_dont,
+ nios2_elf32_pcrel_lo16_relocate,
+ "R_NIOS2_PCREL_LO",
+ FALSE,
+ 0x003fffc0,
+ 0x003fffc0,
+ TRUE),
+
+ HOWTO (R_NIOS2_PCREL_HA,
+ 0,
+ 2,
+ 16,
+ FALSE, /* This is a PC-relative relocation, but we need to subtract
+ PC ourselves before the HIADJ. */
+ 6,
+ complain_overflow_dont,
+ nios2_elf32_pcrel_hiadj16_relocate,
+ "R_NIOS2_PCREL_HA",
+ FALSE,
+ 0x003fffc0,
+ 0x003fffc0,
+ TRUE),
+
+ HOWTO (R_NIOS2_TLS_GD16,
+ 0,
+ 2,
+ 16,
+ FALSE,
+ 6,
+ complain_overflow_bitfield,
+ bfd_elf_generic_reloc,
+ "R_NIOS2_TLS_GD16",
+ FALSE,
+ 0x003fffc0,
+ 0x003fffc0,
+ FALSE),
+
+ HOWTO (R_NIOS2_TLS_LDM16,
+ 0,
+ 2,
+ 16,
+ FALSE,
+ 6,
+ complain_overflow_bitfield,
+ bfd_elf_generic_reloc,
+ "R_NIOS2_TLS_LDM16",
+ FALSE,
+ 0x003fffc0,
+ 0x003fffc0,
+ FALSE),
+
+ HOWTO (R_NIOS2_TLS_LDO16,
+ 0,
+ 2,
+ 16,
+ FALSE,
+ 6,
+ complain_overflow_bitfield,
+ bfd_elf_generic_reloc,
+ "R_NIOS2_TLS_LDO16",
+ FALSE,
+ 0x003fffc0,
+ 0x003fffc0,
+ FALSE),
+
+ HOWTO (R_NIOS2_TLS_IE16,
+ 0,
+ 2,
+ 16,
+ FALSE,
+ 6,
+ complain_overflow_bitfield,
+ bfd_elf_generic_reloc,
+ "R_NIOS2_TLS_IE16",
+ FALSE,
+ 0x003fffc0,
+ 0x003fffc0,
+ FALSE),
+
+ HOWTO (R_NIOS2_TLS_LE16,
+ 0,
+ 2,
+ 16,
+ FALSE,
+ 6,
+ complain_overflow_bitfield,
+ bfd_elf_generic_reloc,
+ "R_NIOS2_TLS_LE16",
+ FALSE,
+ 0x003fffc0,
+ 0x003fffc0,
+ FALSE),
+
+ HOWTO (R_NIOS2_TLS_DTPMOD,
+ 0,
+ 2,
+ 32,
+ FALSE,
+ 0,
+ complain_overflow_dont,
+ bfd_elf_generic_reloc,
+ "R_NIOS2_TLS_DTPMOD",
+ FALSE,
+ 0xffffffff,
+ 0xffffffff,
+ FALSE),
+
+ HOWTO (R_NIOS2_TLS_DTPREL,
+ 0,
+ 2,
+ 32,
+ FALSE,
+ 0,
+ complain_overflow_dont,
+ bfd_elf_generic_reloc,
+ "R_NIOS2_TLS_DTPREL",
+ FALSE,
+ 0xffffffff,
+ 0xffffffff,
+ FALSE),
+
+ HOWTO (R_NIOS2_TLS_TPREL,
+ 0,
+ 2,
+ 32,
+ FALSE,
+ 0,
+ complain_overflow_dont,
+ bfd_elf_generic_reloc,
+ "R_NIOS2_TLS_TPREL",
+ FALSE,
+ 0xffffffff,
+ 0xffffffff,
+ FALSE),
+
+ HOWTO (R_NIOS2_COPY,
+ 0,
+ 2,
+ 32,
+ FALSE,
+ 0,
+ complain_overflow_dont,
+ bfd_elf_generic_reloc,
+ "R_NIOS2_COPY",
+ FALSE,
+ 0,
+ 0,
+ FALSE),
+
+ HOWTO (R_NIOS2_GLOB_DAT,
+ 0,
+ 2,
+ 32,
+ FALSE,
+ 0,
+ complain_overflow_dont,
+ bfd_elf_generic_reloc,
+ "R_NIOS2_GLOB_DAT",
+ FALSE,
+ 0xffffffff,
+ 0xffffffff,
+ FALSE),
+
+ HOWTO (R_NIOS2_JUMP_SLOT,
+ 0,
+ 2,
+ 32,
+ FALSE,
+ 0,
+ complain_overflow_dont,
+ bfd_elf_generic_reloc,
+ "R_NIOS2_JUMP_SLOT",
+ FALSE,
+ 0xffffffff,
+ 0xffffffff,
+ FALSE),
+
+ HOWTO (R_NIOS2_RELATIVE,
+ 0,
+ 2,
+ 32,
+ FALSE,
+ 0,
+ complain_overflow_dont,
+ bfd_elf_generic_reloc,
+ "R_NIOS2_RELATIVE",
+ FALSE,
+ 0xffffffff,
+ 0xffffffff,
+ FALSE),
+
+ HOWTO (R_NIOS2_GOTOFF,
+ 0,
+ 2,
+ 32,
+ FALSE,
+ 0,
+ complain_overflow_dont,
+ bfd_elf_generic_reloc,
+ "R_NIOS2_GOTOFF",
+ FALSE,
+ 0xffffffff,
+ 0xffffffff,
+ FALSE),
+
+ HOWTO (R_NIOS2_CALL26_NOAT, /* type */
+ 2, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 26, /* bitsize */
+ FALSE, /* pc_relative */
+ 6, /* bitpos */
+ complain_overflow_dont, /* complain on overflow */
+ nios2_elf32_call26_relocate, /* special function */
+ "R_NIOS2_CALL26_NOAT", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffc0, /* src_mask */
+ 0xffffffc0, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_NIOS2_GOT_LO,
+ 0,
+ 2,
+ 16,
+ FALSE,
+ 6,
+ complain_overflow_dont,
+ bfd_elf_generic_reloc,
+ "R_NIOS2_GOT_LO",
+ FALSE,
+ 0x003fffc0,
+ 0x003fffc0,
+ FALSE),
+
+ HOWTO (R_NIOS2_GOT_HA,
+ 0,
+ 2,
+ 16,
+ FALSE,
+ 6,
+ complain_overflow_dont,
+ bfd_elf_generic_reloc,
+ "R_NIOS2_GOT_HA",
+ FALSE,
+ 0x003fffc0,
+ 0x003fffc0,
+ FALSE),
+
+ HOWTO (R_NIOS2_CALL_LO,
+ 0,
+ 2,
+ 16,
+ FALSE,
+ 6,
+ complain_overflow_dont,
+ bfd_elf_generic_reloc,
+ "R_NIOS2_CALL_LO",
+ FALSE,
+ 0x003fffc0,
+ 0x003fffc0,
+ FALSE),
+
+ HOWTO (R_NIOS2_CALL_HA,
+ 0,
+ 2,
+ 16,
+ FALSE,
+ 6,
+ complain_overflow_dont,
+ bfd_elf_generic_reloc,
+ "R_NIOS2_CALL_HA",
+ FALSE,
+ 0x003fffc0,
+ 0x003fffc0,
+ FALSE),
+
+/* Add other relocations here. */
+};
+
+static unsigned char elf_code_to_howto_index[R_NIOS2_ILLEGAL + 1];
+
+/* Return the howto for relocation RTYPE. */
+static reloc_howto_type *
+lookup_howto (unsigned int rtype)
+{
+ static int initialized = 0;
+ int i;
+ int howto_tbl_size = (int) (sizeof (elf_nios2_howto_table_rel)
+ / sizeof (elf_nios2_howto_table_rel[0]));
+
+ if (!initialized)
+ {
+ initialized = 1;
+ memset (elf_code_to_howto_index, 0xff,
+ sizeof (elf_code_to_howto_index));
+ for (i = 0; i < howto_tbl_size; i++)
+ elf_code_to_howto_index[elf_nios2_howto_table_rel[i].type] = i;
+ }
+
+ BFD_ASSERT (rtype <= R_NIOS2_ILLEGAL);
+ i = elf_code_to_howto_index[rtype];
+ if (i >= howto_tbl_size)
+ return 0;
+ return elf_nios2_howto_table_rel + i;
+}
+
+/* Map for converting BFD reloc types to Nios II reloc types. */
+struct elf_reloc_map
+{
+ bfd_reloc_code_real_type bfd_val;
+ enum elf_nios2_reloc_type elf_val;
+};
+
+static const struct elf_reloc_map nios2_reloc_map[] = {
+ {BFD_RELOC_NIOS2_S16, R_NIOS2_S16},
+ {BFD_RELOC_NIOS2_U16, R_NIOS2_U16},
+ {BFD_RELOC_16_PCREL, R_NIOS2_PCREL16},
+ {BFD_RELOC_NIOS2_CALL26, R_NIOS2_CALL26},
+ {BFD_RELOC_NIOS2_IMM5, R_NIOS2_IMM5},
+ {BFD_RELOC_NIOS2_CACHE_OPX, R_NIOS2_CACHE_OPX},
+ {BFD_RELOC_NIOS2_IMM6, R_NIOS2_IMM6},
+ {BFD_RELOC_NIOS2_IMM8, R_NIOS2_IMM8},
+ {BFD_RELOC_NIOS2_HI16, R_NIOS2_HI16},
+ {BFD_RELOC_NIOS2_LO16, R_NIOS2_LO16},
+ {BFD_RELOC_NIOS2_HIADJ16, R_NIOS2_HIADJ16},
+ {BFD_RELOC_32, R_NIOS2_BFD_RELOC_32},
+ {BFD_RELOC_16, R_NIOS2_BFD_RELOC_16},
+ {BFD_RELOC_8, R_NIOS2_BFD_RELOC_8},
+ {BFD_RELOC_NIOS2_GPREL, R_NIOS2_GPREL},
+ {BFD_RELOC_VTABLE_INHERIT, R_NIOS2_GNU_VTINHERIT},
+ {BFD_RELOC_VTABLE_ENTRY, R_NIOS2_GNU_VTENTRY},
+ {BFD_RELOC_NIOS2_UJMP, R_NIOS2_UJMP},
+ {BFD_RELOC_NIOS2_CJMP, R_NIOS2_CJMP},
+ {BFD_RELOC_NIOS2_CALLR, R_NIOS2_CALLR},
+ {BFD_RELOC_NIOS2_ALIGN, R_NIOS2_ALIGN},
+ {BFD_RELOC_NIOS2_GOT16, R_NIOS2_GOT16},
+ {BFD_RELOC_NIOS2_CALL16, R_NIOS2_CALL16},
+ {BFD_RELOC_NIOS2_GOTOFF_LO, R_NIOS2_GOTOFF_LO},
+ {BFD_RELOC_NIOS2_GOTOFF_HA, R_NIOS2_GOTOFF_HA},
+ {BFD_RELOC_NIOS2_PCREL_LO, R_NIOS2_PCREL_LO},
+ {BFD_RELOC_NIOS2_PCREL_HA, R_NIOS2_PCREL_HA},
+ {BFD_RELOC_NIOS2_TLS_GD16, R_NIOS2_TLS_GD16},
+ {BFD_RELOC_NIOS2_TLS_LDM16, R_NIOS2_TLS_LDM16},
+ {BFD_RELOC_NIOS2_TLS_LDO16, R_NIOS2_TLS_LDO16},
+ {BFD_RELOC_NIOS2_TLS_IE16, R_NIOS2_TLS_IE16},
+ {BFD_RELOC_NIOS2_TLS_LE16, R_NIOS2_TLS_LE16},
+ {BFD_RELOC_NIOS2_TLS_DTPMOD, R_NIOS2_TLS_DTPMOD},
+ {BFD_RELOC_NIOS2_TLS_DTPREL, R_NIOS2_TLS_DTPREL},
+ {BFD_RELOC_NIOS2_TLS_TPREL, R_NIOS2_TLS_TPREL},
+ {BFD_RELOC_NIOS2_COPY, R_NIOS2_COPY},
+ {BFD_RELOC_NIOS2_GLOB_DAT, R_NIOS2_GLOB_DAT},
+ {BFD_RELOC_NIOS2_JUMP_SLOT, R_NIOS2_JUMP_SLOT},
+ {BFD_RELOC_NIOS2_RELATIVE, R_NIOS2_RELATIVE},
+ {BFD_RELOC_NIOS2_GOTOFF, R_NIOS2_GOTOFF},
+ {BFD_RELOC_NIOS2_CALL26_NOAT, R_NIOS2_CALL26_NOAT},
+ {BFD_RELOC_NIOS2_GOT_LO, R_NIOS2_GOT_LO},
+ {BFD_RELOC_NIOS2_GOT_HA, R_NIOS2_GOT_HA},
+ {BFD_RELOC_NIOS2_CALL_LO, R_NIOS2_CALL_LO},
+ {BFD_RELOC_NIOS2_CALL_HA, R_NIOS2_CALL_HA},
+};
+
+enum elf32_nios2_stub_type
+{
+ nios2_stub_call26_before,
+ nios2_stub_call26_after,
+ nios2_stub_none
+};
+
+struct elf32_nios2_stub_hash_entry
+{
+ /* Base hash table entry structure. */
+ struct bfd_hash_entry bh_root;
+
+ /* The stub section. */
+ asection *stub_sec;
+
+ /* Offset within stub_sec of the beginning of this stub. */
+ bfd_vma stub_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. */
+ bfd_vma target_value;
+ asection *target_section;
+
+ enum elf32_nios2_stub_type stub_type;
+
+ /* The symbol table entry, if any, that this was derived from. */
+ struct elf32_nios2_link_hash_entry *hh;
+
+ /* And the reloc addend that this was derived from. */
+ bfd_vma addend;
+
+ /* Where this stub is being called from, or, in the case of combined
+ stub sections, the first input section in the group. */
+ asection *id_sec;
+};
+
+#define nios2_stub_hash_entry(ent) \
+ ((struct elf32_nios2_stub_hash_entry *)(ent))
+
+#define nios2_stub_hash_lookup(table, string, create, copy) \
+ ((struct elf32_nios2_stub_hash_entry *) \
+ bfd_hash_lookup ((table), (string), (create), (copy)))
+
+
+/* The Nios II linker needs to keep track of the number of relocs that it
+ decides to copy as dynamic relocs in check_relocs for each symbol.
+ This is so that it can later discard them if they are found to be
+ unnecessary. We store the information in a field extending the
+ regular ELF linker hash table. */
+
+struct elf32_nios2_dyn_relocs
+{
+ struct elf32_nios2_dyn_relocs *next;
+
+ /* The input section of the reloc. */
+ asection *sec;
+
+ /* Total number of relocs copied for the input section. */
+ bfd_size_type count;
+
+ /* Number of pc-relative relocs copied for the input section. */
+ bfd_size_type pc_count;
+};
+
+/* Nios II ELF linker hash entry. */
+
+struct elf32_nios2_link_hash_entry
+{
+ struct elf_link_hash_entry root;
+
+ /* A pointer to the most recently used stub hash entry against this
+ symbol. */
+ struct elf32_nios2_stub_hash_entry *hsh_cache;
+
+ /* Track dynamic relocs copied for this symbol. */
+ struct elf32_nios2_dyn_relocs *dyn_relocs;
+
+#define GOT_UNKNOWN 0
+#define GOT_NORMAL 1
+#define GOT_TLS_GD 2
+#define GOT_TLS_IE 4
+ unsigned char tls_type;
+
+ /* We need to detect and take special action for symbols which are only
+ referenced with %call() and not with %got(). Such symbols do not need
+ a dynamic GOT reloc in shared objects, only a dynamic PLT reloc. Lazy
+ linking will not work if the dynamic GOT reloc exists.
+ To check for this condition efficiently, we compare got_types_used against
+ CALL_USED, meaning
+ (got_types_used & (GOT_USED | CALL_USED)) == CALL_USED.
+ */
+#define GOT_USED 1
+#define CALL_USED 2
+ unsigned char got_types_used;
+};
+
+#define elf32_nios2_hash_entry(ent) \
+ ((struct elf32_nios2_link_hash_entry *) (ent))
+
+/* Get the Nios II elf linker hash table from a link_info structure. */
+#define elf32_nios2_hash_table(info) \
+ ((struct elf32_nios2_link_hash_table *) ((info)->hash))
+
+/* Nios II ELF linker hash table. */
+struct elf32_nios2_link_hash_table
+ {
+ /* The main hash table. */
+ struct elf_link_hash_table root;
+
+ /* The stub hash table. */
+ struct bfd_hash_table bstab;
+
+ /* Linker stub bfd. */
+ bfd *stub_bfd;
+
+ /* Linker call-backs. */
+ asection * (*add_stub_section) (const char *, asection *, bfd_boolean);
+ void (*layout_sections_again) (void);
+
+ /* Array to keep track of which stub sections have been created, and
+ information on stub grouping. */
+ struct map_stub
+ {
+ /* These are the section to which stubs in the group will be
+ attached. */
+ asection *first_sec, *last_sec;
+ /* The stub sections. There might be stubs inserted either before
+ or after the real section.*/
+ asection *first_stub_sec, *last_stub_sec;
+ } *stub_group;
+
+ /* Assorted information used by nios2_elf32_size_stubs. */
+ unsigned int bfd_count;
+ int top_index;
+ asection **input_list;
+ Elf_Internal_Sym **all_local_syms;
+
+ /* Short-cuts to get to dynamic linker sections. */
+ asection *sdynbss;
+ asection *srelbss;
+ asection *sbss;
+
+ /* GOT pointer symbol _gp_got. */
+ struct elf_link_hash_entry *h_gp_got;
+
+ union {
+ bfd_signed_vma refcount;
+ bfd_vma offset;
+ } tls_ldm_got;
+
+ /* Small local sym cache. */
+ struct sym_cache sym_cache;
+
+ bfd_vma res_n_size;
+ };
+
+struct nios2_elf32_obj_tdata
+{
+ struct elf_obj_tdata root;
+
+ /* tls_type for each local got entry. */
+ char *local_got_tls_type;
+
+ /* TRUE if TLS GD relocs have been seen for this object. */
+ bfd_boolean has_tlsgd;
+};
+
+#define elf32_nios2_tdata(abfd) \
+ ((struct nios2_elf32_obj_tdata *) (abfd)->tdata.any)
+
+#define elf32_nios2_local_got_tls_type(abfd) \
+ (elf32_nios2_tdata (abfd)->local_got_tls_type)
+
+/* The name of the dynamic interpreter. This is put in the .interp
+ section. */
+#define ELF_DYNAMIC_INTERPRETER "/lib/ld.so.1"
+
+/* PLT implementation for position-dependent code. */
+static const bfd_vma nios2_plt_entry[] = { /* .PLTn: */
+ 0x03c00034, /* movhi r15, %hiadj(plt_got_slot_address) */
+ 0x7bc00017, /* ldw r15, %lo(plt_got_slot_address)(r15) */
+ 0x7800683a /* jmp r15 */
+};
+
+static const bfd_vma nios2_plt0_entry[] = { /* .PLTresolve */
+ 0x03800034, /* movhi r14, %hiadj(res_0) */
+ 0x73800004, /* addi r14, r14, %lo(res_0) */
+ 0x7b9fc83a, /* sub r15, r15, r14 */
+ 0x03400034, /* movhi r13, %hiadj(_GLOBAL_OFFSET_TABLE_) */
+ 0x6b800017, /* ldw r14, %lo(_GLOBAL_OFFSET_TABLE_+4)(r13) */
+ 0x6b400017, /* ldw r13, %lo(_GLOBAL_OFFSET_TABLE_+8)(r13) */
+ 0x6800683a /* jmp r13 */
+};
+
+/* PLT implementation for position-independent code. */
+static const bfd_vma nios2_so_plt_entry[] = { /* .PLTn */
+ 0x03c00034, /* movhi r15, %hiadj(index * 4) */
+ 0x7bc00004, /* addi r15, r15, %lo(index * 4) */
+ 0x00000006 /* br .PLTresolve */
+};
+
+static const bfd_vma nios2_so_plt0_entry[] = { /* .PLTresolve */
+ 0x001ce03a, /* nextpc r14 */
+ 0x03400034, /* movhi r13, %hiadj(_GLOBAL_OFFSET_TABLE_) */
+ 0x6b9b883a, /* add r13, r13, r14 */
+ 0x6b800017, /* ldw r14, %lo(_GLOBAL_OFFSET_TABLE_+4)(r13) */
+ 0x6b400017, /* ldw r13, %lo(_GLOBAL_OFFSET_TABLE_+8)(r13) */
+ 0x6800683a /* jmp r13 */
+};
+
+/* CALL26 stub. */
+static const bfd_vma nios2_call26_stub_entry[] = {
+ 0x00400034, /* orhi at, r0, %hiadj(dest) */
+ 0x08400004, /* addi at, at, %lo(dest) */
+ 0x0800683a /* jmp at */
+};
+
+/* Install 16-bit immediate value VALUE at offset OFFSET into section SEC. */
+static void
+nios2_elf32_install_imm16 (asection *sec, bfd_vma offset, bfd_vma value)
+{
+ bfd_vma word = bfd_get_32 (sec->owner, sec->contents + offset);
+
+ BFD_ASSERT(value <= 0xffff);
+
+ bfd_put_32 (sec->owner, word | ((value & 0xffff) << 6),
+ sec->contents + offset);
+}
+
+/* Install COUNT 32-bit values DATA starting at offset OFFSET into
+ section SEC. */
+static void
+nios2_elf32_install_data (asection *sec, const bfd_vma *data, bfd_vma offset,
+ int count)
+{
+ while (count--)
+ {
+ bfd_put_32 (sec->owner, *data, sec->contents + offset);
+ offset += 4;
+ ++data;
+ }
+}
+
+/* The usual way of loading a 32-bit constant into a Nios II register is to
+ load the high 16 bits in one instruction and then add the low 16 bits with
+ a signed add. This means that the high halfword needs to be adjusted to
+ compensate for the sign bit of the low halfword. This function returns the
+ adjusted high halfword for a given 32-bit constant. */
+static
+bfd_vma hiadj (bfd_vma symbol_value)
+{
+ return ((symbol_value + 0x8000) >> 16) & 0xffff;
+}
+
+/* Implement elf_backend_grok_prstatus:
+ Support for core dump NOTE sections. */
+static bfd_boolean
+nios2_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
+{
+ int offset;
+ size_t size;
+
+ switch (note->descsz)
+ {
+ default:
+ return FALSE;
+
+ case 212: /* Linux/Nios II */
+ /* pr_cursig */
+ elf_tdata (abfd)->core->signal = bfd_get_16 (abfd, note->descdata + 12);
+
+ /* pr_pid */
+ elf_tdata (abfd)->core->pid = bfd_get_32 (abfd, note->descdata + 24);
+
+ /* pr_reg */
+ offset = 72;
+ size = 136;
+
+ break;
+ }
+
+ /* Make a ".reg/999" section. */
+ return _bfd_elfcore_make_pseudosection (abfd, ".reg",
+ size, note->descpos + offset);
+}
+
+/* Implement elf_backend_grok_psinfo. */
+static bfd_boolean
+nios2_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
+{
+ switch (note->descsz)
+ {
+ default:
+ return FALSE;
+
+ case 124: /* Linux/Nios II elf_prpsinfo */
+ elf_tdata (abfd)->core->program
+ = _bfd_elfcore_strndup (abfd, note->descdata + 28, 16);
+ elf_tdata (abfd)->core->command
+ = _bfd_elfcore_strndup (abfd, note->descdata + 44, 80);
+ }
+
+ /* 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;
+}
+
+/* Assorted hash table functions. */
+
+/* Initialize an entry in the stub hash table. */
+static struct bfd_hash_entry *
+stub_hash_newfunc (struct bfd_hash_entry *entry,
+ struct bfd_hash_table *table,
+ const char *string)
+{
+ /* Allocate the structure if it has not already been allocated by a
+ subclass. */
+ if (entry == NULL)
+ {
+ entry = bfd_hash_allocate (table,
+ sizeof (struct elf32_nios2_stub_hash_entry));
+ if (entry == NULL)
+ return entry;
+ }
+
+ /* Call the allocation method of the superclass. */
+ entry = bfd_hash_newfunc (entry, table, string);
+ if (entry != NULL)
+ {
+ struct elf32_nios2_stub_hash_entry *hsh;
+
+ /* Initialize the local fields. */
+ hsh = (struct elf32_nios2_stub_hash_entry *) entry;
+ hsh->stub_sec = NULL;
+ hsh->stub_offset = 0;
+ hsh->target_value = 0;
+ hsh->target_section = NULL;
+ hsh->stub_type = nios2_stub_none;
+ hsh->hh = NULL;
+ hsh->id_sec = NULL;
+ }
+
+ return entry;
+}
+
+/* Create an entry in a Nios II ELF linker hash table. */
+static struct bfd_hash_entry *
+link_hash_newfunc (struct bfd_hash_entry *entry,
+ struct bfd_hash_table *table, const char *string)
+{
+ /* Allocate the structure if it has not already been allocated by a
+ subclass. */
+ if (entry == NULL)
+ {
+ entry = bfd_hash_allocate (table,
+ sizeof (struct elf32_nios2_link_hash_entry));
+ if (entry == NULL)
+ return entry;
+ }
+
+ /* Call the allocation method of the superclass. */
+ entry = _bfd_elf_link_hash_newfunc (entry, table, string);
+ if (entry)
+ {
+ struct elf32_nios2_link_hash_entry *eh;
+
+ eh = (struct elf32_nios2_link_hash_entry *) entry;
+ eh->hsh_cache = NULL;
+ eh->dyn_relocs = NULL;
+ eh->tls_type = GOT_UNKNOWN;
+ eh->got_types_used = 0;
+ }
+
+ return entry;
+}
+
+/* Section name for stubs is the associated section name plus this
+ string. */
+#define STUB_SUFFIX ".stub"
+
+/* Build a name for an entry in the stub hash table. */
+static char *
+nios2_stub_name (const asection *input_section,
+ const asection *sym_sec,
+ const struct elf32_nios2_link_hash_entry *hh,
+ const Elf_Internal_Rela *rel,
+ enum elf32_nios2_stub_type stub_type)
+{
+ char *stub_name;
+ bfd_size_type len;
+ char stubpos = (stub_type == nios2_stub_call26_before) ? 'b' : 'a';
+
+ if (hh)
+ {
+ len = 8 + 1 + 1 + 1+ strlen (hh->root.root.root.string) + 1 + 8 + 1;
+ stub_name = bfd_malloc (len);
+ if (stub_name != NULL)
+ {
+ sprintf (stub_name, "%08x_%c_%s+%x",
+ input_section->id & 0xffffffff,
+ stubpos,
+ hh->root.root.root.string,
+ (int) rel->r_addend & 0xffffffff);
+ }
+ }
+ else
+ {
+ len = 8 + 1 + 1 + 1+ 8 + 1 + 8 + 1 + 8 + 1;
+ stub_name = bfd_malloc (len);
+ if (stub_name != NULL)
+ {
+ sprintf (stub_name, "%08x_%c_%x:%x+%x",
+ input_section->id & 0xffffffff,
+ stubpos,
+ sym_sec->id & 0xffffffff,
+ (int) ELF32_R_SYM (rel->r_info) & 0xffffffff,
+ (int) rel->r_addend & 0xffffffff);
+ }
+ }
+ return stub_name;
+}
+
+/* Look up an entry in the stub hash. Stub entries are cached because
+ creating the stub name takes a bit of time. */
+static struct elf32_nios2_stub_hash_entry *
+nios2_get_stub_entry (const asection *input_section,
+ const asection *sym_sec,
+ struct elf32_nios2_link_hash_entry *hh,
+ const Elf_Internal_Rela *rel,
+ struct elf32_nios2_link_hash_table *htab,
+ enum elf32_nios2_stub_type stub_type)
+{
+ struct elf32_nios2_stub_hash_entry *hsh;
+ const asection *id_sec;
+
+ /* If this input section is part of a group of sections sharing one
+ stub section, then use the id of the first/last section in the group,
+ depending on the stub section placement relative to the group.
+ Stub names need to include a section id, as there may well be
+ more than one stub used to reach say, printf, and we need to
+ distinguish between them. */
+ if (stub_type == nios2_stub_call26_before)
+ id_sec = htab->stub_group[input_section->id].first_sec;
+ else
+ id_sec = htab->stub_group[input_section->id].last_sec;
+
+ if (hh != NULL && hh->hsh_cache != NULL
+ && hh->hsh_cache->hh == hh
+ && hh->hsh_cache->id_sec == id_sec
+ && hh->hsh_cache->stub_type == stub_type)
+ {
+ hsh = hh->hsh_cache;
+ }
+ else
+ {
+ char *stub_name;
+
+ stub_name = nios2_stub_name (id_sec, sym_sec, hh, rel, stub_type);
+ if (stub_name == NULL)
+ return NULL;
+
+ hsh = nios2_stub_hash_lookup (&htab->bstab,
+ stub_name, FALSE, FALSE);
+
+ if (hh != NULL)
+ hh->hsh_cache = hsh;
+
+ free (stub_name);
+ }
+
+ return hsh;
+}
+
+/* Add a new stub entry to the stub hash. Not all fields of the new
+ stub entry are initialised. */
+static struct elf32_nios2_stub_hash_entry *
+nios2_add_stub (const char *stub_name,
+ asection *section,
+ struct elf32_nios2_link_hash_table *htab,
+ enum elf32_nios2_stub_type stub_type)
+{
+ asection *link_sec;
+ asection *stub_sec;
+ asection **secptr, **linkptr;
+ struct elf32_nios2_stub_hash_entry *hsh;
+ bfd_boolean afterp;
+
+ if (stub_type == nios2_stub_call26_before)
+ {
+ link_sec = htab->stub_group[section->id].first_sec;
+ secptr = &(htab->stub_group[section->id].first_stub_sec);
+ linkptr = &(htab->stub_group[link_sec->id].first_stub_sec);
+ afterp = FALSE;
+ }
+ else
+ {
+ link_sec = htab->stub_group[section->id].last_sec;
+ secptr = &(htab->stub_group[section->id].last_stub_sec);
+ linkptr = &(htab->stub_group[link_sec->id].last_stub_sec);
+ afterp = TRUE;
+ }
+ stub_sec = *secptr;
+ if (stub_sec == NULL)
+ {
+ stub_sec = *linkptr;
+ if (stub_sec == NULL)
+ {
+ size_t namelen;
+ bfd_size_type len;
+ char *s_name;
+
+ namelen = strlen (link_sec->name);
+ len = namelen + sizeof (STUB_SUFFIX);
+ s_name = bfd_alloc (htab->stub_bfd, len);
+ if (s_name == NULL)
+ return NULL;
+
+ memcpy (s_name, link_sec->name, namelen);
+ memcpy (s_name + namelen, STUB_SUFFIX, sizeof (STUB_SUFFIX));
+
+ stub_sec = (*htab->add_stub_section) (s_name, link_sec, afterp);
+ if (stub_sec == NULL)
+ return NULL;
+ *linkptr = stub_sec;
+ }
+ *secptr = stub_sec;
+ }
+
+ /* Enter this entry into the linker stub hash table. */
+ hsh = nios2_stub_hash_lookup (&htab->bstab, stub_name,
+ TRUE, FALSE);
+ if (hsh == NULL)
+ {
+ (*_bfd_error_handler) (_("%B: cannot create stub entry %s"),
+ section->owner,
+ stub_name);
+ return NULL;
+ }
+
+ hsh->stub_sec = stub_sec;
+ hsh->stub_offset = 0;
+ hsh->id_sec = link_sec;
+ return hsh;
+}
+
+/* Set up various things so that we can make a list of input sections
+ for each output section included in the link. Returns -1 on error,
+ 0 when no stubs will be needed, and 1 on success. */
+int
+nios2_elf32_setup_section_lists (bfd *output_bfd, struct bfd_link_info *info)
+{
+ bfd *input_bfd;
+ unsigned int bfd_count;
+ int top_id, top_index;
+ asection *section;
+ asection **input_list, **list;
+ bfd_size_type amt;
+ struct elf32_nios2_link_hash_table *htab = elf32_nios2_hash_table (info);
+
+ /* Count the number of input BFDs and find the top input section id. */
+ for (input_bfd = info->input_bfds, bfd_count = 0, top_id = 0;
+ input_bfd != NULL;
+ input_bfd = input_bfd->link.next)
+ {
+ bfd_count += 1;
+ for (section = input_bfd->sections;
+ section != NULL;
+ section = section->next)
+ {
+ if (top_id < section->id)
+ top_id = section->id;
+ }
+ }
+
+ htab->bfd_count = bfd_count;
+
+ amt = sizeof (struct map_stub) * (top_id + 1);
+ htab->stub_group = bfd_zmalloc (amt);
+ if (htab->stub_group == NULL)
+ return -1;
+
+ /* We can't use output_bfd->section_count here to find the top output
+ section index as some sections may have been removed, and
+ strip_excluded_output_sections doesn't renumber the indices. */
+ for (section = output_bfd->sections, top_index = 0;
+ section != NULL;
+ section = section->next)
+ {
+ if (top_index < section->index)
+ top_index = section->index;
+ }
+
+ htab->top_index = top_index;
+ amt = sizeof (asection *) * (top_index + 1);
+ input_list = bfd_malloc (amt);
+ htab->input_list = input_list;
+ if (input_list == NULL)
+ return -1;
+
+ /* For sections we aren't interested in, mark their entries with a
+ value we can check later. */
+ list = input_list + top_index;
+ do
+ *list = bfd_abs_section_ptr;
+ while (list-- != input_list);
+
+ for (section = output_bfd->sections;
+ section != NULL;
+ section = section->next)
+ {
+ /* FIXME: This is a bit of hack. Currently our .ctors and .dtors
+ * have PC relative relocs in them but no code flag set. */
+ if (((section->flags & SEC_CODE) != 0) ||
+ strcmp(".ctors", section->name) ||
+ strcmp(".dtors", section->name))
+ input_list[section->index] = NULL;
+ }
+
+ return 1;
+}
+
+/* The linker repeatedly calls this function for each input section,
+ in the order that input sections are linked into output sections.
+ Build lists of input sections to determine groupings between which
+ we may insert linker stubs. */
+void
+nios2_elf32_next_input_section (struct bfd_link_info *info, asection *isec)
+{
+ struct elf32_nios2_link_hash_table *htab = elf32_nios2_hash_table (info);
+
+ if (isec->output_section->index <= htab->top_index)
+ {
+ asection **list = htab->input_list + isec->output_section->index;
+ if (*list != bfd_abs_section_ptr)
+ {
+ /* Steal the last_sec pointer for our list.
+ This happens to make the list in reverse order,
+ which is what we want. */
+ htab->stub_group[isec->id].last_sec = *list;
+ *list = isec;
+ }
+ }
+}
+
+/* Segment mask for CALL26 relocation relaxation. */
+#define CALL26_SEGMENT(x) ((x) & 0xf0000000)
+
+/* Fudge factor for approximate maximum size of all stubs that might
+ be inserted by the linker. This does not actually limit the number
+ of stubs that might be inserted, and only affects strategy for grouping
+ and placement of stubs. Perhaps this should be computed based on number
+ of relocations seen, or be specifiable on the command line. */
+#define MAX_STUB_SECTION_SIZE 0xffff
+
+/* See whether we can group stub sections together. Grouping stub
+ sections may result in fewer stubs. More importantly, we need to
+ put all .init* and .fini* stubs at the end of the .init or
+ .fini output sections respectively, because glibc splits the
+ _init and _fini functions into multiple parts. Putting a stub in
+ the middle of a function is not a good idea.
+ Rather than computing groups of a maximum fixed size, for Nios II
+ CALL26 relaxation it makes more sense to compute the groups based on
+ sections that fit within a 256MB address segment. Also do not allow
+ a group to span more than one output section, since different output
+ sections might correspond to different memory banks on a bare-metal
+ target, etc. */
+static void
+group_sections (struct elf32_nios2_link_hash_table *htab)
+{
+ asection **list = htab->input_list + htab->top_index;
+ do
+ {
+ /* The list is in reverse order so we'll search backwards looking
+ for the first section that begins in the same memory segment,
+ marking sections along the way to point at the tail for this
+ group. */
+ asection *tail = *list;
+ if (tail == bfd_abs_section_ptr)
+ continue;
+ while (tail != NULL)
+ {
+ bfd_vma start = tail->output_section->vma + tail->output_offset;
+ bfd_vma end = start + tail->size;
+ bfd_vma segment = CALL26_SEGMENT (end);
+ asection *prev;
+
+ if (segment != CALL26_SEGMENT (start)
+ || segment != CALL26_SEGMENT (end + MAX_STUB_SECTION_SIZE))
+ /* This section spans more than one memory segment, or is
+ close enough to the end of the segment that adding stub
+ sections before it might cause it to move so that it
+ spans memory segments, or that stubs added at the end of
+ this group might overflow into the next memory segment.
+ Put it in a group by itself to localize the effects. */
+ {
+ prev = htab->stub_group[tail->id].last_sec;
+ htab->stub_group[tail->id].last_sec = tail;
+ htab->stub_group[tail->id].first_sec = tail;
+ }
+ else
+ /* Collect more sections for this group. */
+ {
+ asection *curr, *first;
+ for (curr = tail; ; curr = prev)
+ {
+ prev = htab->stub_group[curr->id].last_sec;
+ if (!prev
+ || tail->output_section != prev->output_section
+ || (CALL26_SEGMENT (prev->output_section->vma
+ + prev->output_offset)
+ != segment))
+ break;
+ }
+ first = curr;
+ for (curr = tail; ; curr = prev)
+ {
+ prev = htab->stub_group[curr->id].last_sec;
+ htab->stub_group[curr->id].last_sec = tail;
+ htab->stub_group[curr->id].first_sec = first;
+ if (curr == first)
+ break;
+ }
+ }
+
+ /* Reset tail for the next group. */
+ tail = prev;
+ }
+ }
+ while (list-- != htab->input_list);
+ free (htab->input_list);
+}
+
+/* Determine the type of stub needed, if any, for a call. */
+static enum elf32_nios2_stub_type
+nios2_type_of_stub (asection *input_sec,
+ const Elf_Internal_Rela *rel,
+ struct elf32_nios2_link_hash_entry *hh,
+ struct elf32_nios2_link_hash_table *htab,
+ bfd_vma destination,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED)
+{
+ bfd_vma location, segment, start, end;
+ asection *s0, *s1, *s;
+
+ if (hh != NULL &&
+ !(hh->root.root.type == bfd_link_hash_defined
+ || hh->root.root.type == bfd_link_hash_defweak))
+ return nios2_stub_none;
+
+ /* Determine where the call point is. */
+ location = (input_sec->output_section->vma
+ + input_sec->output_offset + rel->r_offset);
+ segment = CALL26_SEGMENT (location);
+
+ /* Nios II CALL and JMPI instructions can transfer control to addresses
+ within the same 256MB segment as the PC. */
+ if (segment == CALL26_SEGMENT (destination))
+ return nios2_stub_none;
+
+ /* Find the start and end addresses of the stub group. Also account for
+ any already-created stub sections for this group. Note that for stubs
+ in the end section, only the first instruction of the last stub
+ (12 bytes long) needs to be within range. */
+ s0 = htab->stub_group[input_sec->id].first_sec;
+ s = htab->stub_group[s0->id].first_stub_sec;
+ if (s != NULL && s->size > 0)
+ start = s->output_section->vma + s->output_offset;
+ else
+ start = s0->output_section->vma + s0->output_offset;
+
+ s1 = htab->stub_group[input_sec->id].last_sec;
+ s = htab->stub_group[s1->id].last_stub_sec;
+ if (s != NULL && s->size > 0)
+ end = s->output_section->vma + s->output_offset + s->size - 8;
+ else
+ end = s1->output_section->vma + s1->output_offset + s1->size;
+
+ BFD_ASSERT (start < end);
+ BFD_ASSERT (start <= location);
+ BFD_ASSERT (location < end);
+
+ /* Put stubs at the end of the group unless that is not a valid
+ location and the beginning of the group is. It might be that
+ neither the beginning nor end works if we have an input section
+ so large that it spans multiple segment boundaries. In that
+ case, punt; the end result will be a relocation overflow error no
+ matter what we do here.
+
+ Note that adding stubs pushes up the addresses of all subsequent
+ sections, so that stubs allocated on one pass through the
+ relaxation loop may not be valid on the next pass. (E.g., we may
+ allocate a stub at the beginning of the section on one pass and
+ find that the call site has been bumped into the next memory
+ segment on the next pass.) The important thing to note is that
+ we never try to reclaim the space allocated to such unused stubs,
+ so code size and section addresses can only increase with each
+ iteration. Accounting for the start and end addresses of the
+ already-created stub sections ensures that when the algorithm
+ converges, it converges accurately, with the entire appropriate
+ stub section accessible from the call site and not just the
+ address at the start or end of the stub group proper. */
+
+ if (segment == CALL26_SEGMENT (end))
+ return nios2_stub_call26_after;
+ else if (segment == CALL26_SEGMENT (start))
+ return nios2_stub_call26_before;
+ else
+ /* Perhaps this should be a dedicated error code. */
+ return nios2_stub_none;
+}
+
+static bfd_boolean
+nios2_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg ATTRIBUTE_UNUSED)
+{
+ struct elf32_nios2_stub_hash_entry *hsh
+ = (struct elf32_nios2_stub_hash_entry *) gen_entry;
+ asection *stub_sec = hsh->stub_sec;
+ bfd_vma sym_value;
+
+ /* Make a note of the offset within the stubs for this entry. */
+ hsh->stub_offset = stub_sec->size;
+
+ switch (hsh->stub_type)
+ {
+ case nios2_stub_call26_before:
+ case nios2_stub_call26_after:
+ /* A call26 stub looks like:
+ orhi at, %hiadj(dest)
+ addi at, at, %lo(dest)
+ jmp at
+ Note that call/jmpi instructions can't be used in PIC code
+ so there is no reason for the stub to be PIC, either. */
+ sym_value = (hsh->target_value
+ + hsh->target_section->output_offset
+ + hsh->target_section->output_section->vma
+ + hsh->addend);
+
+ nios2_elf32_install_data (stub_sec, nios2_call26_stub_entry,
+ hsh->stub_offset, 3);
+ nios2_elf32_install_imm16 (stub_sec, hsh->stub_offset,
+ hiadj (sym_value));
+ nios2_elf32_install_imm16 (stub_sec, hsh->stub_offset + 4,
+ (sym_value & 0xffff));
+ stub_sec->size += 12;
+ break;
+ default:
+ BFD_FAIL ();
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/* As above, but don't actually build the stub. Just bump offset so
+ we know stub section sizes. */
+static bfd_boolean
+nios2_size_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg ATTRIBUTE_UNUSED)
+{
+ struct elf32_nios2_stub_hash_entry *hsh
+ = (struct elf32_nios2_stub_hash_entry *) gen_entry;
+
+ switch (hsh->stub_type)
+ {
+ case nios2_stub_call26_before:
+ case nios2_stub_call26_after:
+ hsh->stub_sec->size += 12;
+ break;
+ default:
+ BFD_FAIL ();
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/* Read in all local syms for all input bfds.
+ Returns -1 on error, 0 otherwise. */
+
+static int
+get_local_syms (bfd *output_bfd ATTRIBUTE_UNUSED, bfd *input_bfd,
+ struct bfd_link_info *info)
+{
+ unsigned int bfd_indx;
+ Elf_Internal_Sym *local_syms, **all_local_syms;
+ struct elf32_nios2_link_hash_table *htab = elf32_nios2_hash_table (info);
+
+ /* 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. */
+ bfd_size_type amt = sizeof (Elf_Internal_Sym *) * htab->bfd_count;
+ all_local_syms = bfd_zmalloc (amt);
+ htab->all_local_syms = all_local_syms;
+ if (all_local_syms == NULL)
+ return -1;
+
+ /* Walk over all the input BFDs, swapping in local symbols. */
+ for (bfd_indx = 0;
+ input_bfd != NULL;
+ input_bfd = input_bfd->link.next, bfd_indx++)
+ {
+ Elf_Internal_Shdr *symtab_hdr;
+
+ /* 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. */
+ local_syms = (Elf_Internal_Sym *) symtab_hdr->contents;
+ if (local_syms == NULL)
+ {
+ local_syms = bfd_elf_get_elf_syms (input_bfd, symtab_hdr,
+ symtab_hdr->sh_info, 0,
+ NULL, NULL, NULL);
+ /* Cache them for elf_link_input_bfd. */
+ symtab_hdr->contents = (unsigned char *) local_syms;
+ }
+ if (local_syms == NULL)
+ return -1;
+
+ all_local_syms[bfd_indx] = local_syms;
+ }
+
+ return 0;
+}
+
+/* Determine and set the size of the stub section for a final link. */
+bfd_boolean
+nios2_elf32_size_stubs (bfd *output_bfd, bfd *stub_bfd,
+ struct bfd_link_info *info,
+ asection *(*add_stub_section) (const char *,
+ asection *, bfd_boolean),
+ void (*layout_sections_again) (void))
+{
+ bfd_boolean stub_changed = FALSE;
+ struct elf32_nios2_link_hash_table *htab = elf32_nios2_hash_table (info);
+
+ /* Stash our params away. */
+ htab->stub_bfd = stub_bfd;
+ htab->add_stub_section = add_stub_section;
+ htab->layout_sections_again = layout_sections_again;
+
+ /* FIXME: We only compute the section groups once. This could cause
+ problems if adding a large stub section causes following sections,
+ or parts of them, to move into another segment. However, this seems
+ to be consistent with the way other back ends handle this.... */
+ group_sections (htab);
+
+ if (get_local_syms (output_bfd, info->input_bfds, info))
+ {
+ if (htab->all_local_syms)
+ goto error_ret_free_local;
+ return FALSE;
+ }
+
+ while (1)
+ {
+ bfd *input_bfd;
+ unsigned int bfd_indx;
+ asection *stub_sec;
+
+ for (input_bfd = info->input_bfds, bfd_indx = 0;
+ input_bfd != NULL;
+ input_bfd = input_bfd->link.next, bfd_indx++)
+ {
+ Elf_Internal_Shdr *symtab_hdr;
+ asection *section;
+ Elf_Internal_Sym *local_syms;
+
+ /* 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 = htab->all_local_syms[bfd_indx];
+
+ /* Walk over each section attached to the input bfd. */
+ for (section = input_bfd->sections;
+ section != NULL;
+ section = section->next)
+ {
+ Elf_Internal_Rela *internal_relocs, *irelaend, *irela;
+
+ /* If there aren't any relocs, then there's nothing more
+ to do. */
+ if ((section->flags & SEC_RELOC) == 0
+ || section->reloc_count == 0)
+ continue;
+
+ /* If this section is a link-once section that will be
+ discarded, then don't create any stubs. */
+ if (section->output_section == NULL
+ || section->output_section->owner != output_bfd)
+ continue;
+
+ /* Get the relocs. */
+ internal_relocs
+ = _bfd_elf_link_read_relocs (input_bfd, section, NULL, NULL,
+ info->keep_memory);
+ if (internal_relocs == NULL)
+ goto error_ret_free_local;
+
+ /* Now examine each relocation. */
+ irela = internal_relocs;
+ irelaend = irela + section->reloc_count;
+ for (; irela < irelaend; irela++)
+ {
+ unsigned int r_type, r_indx;
+ enum elf32_nios2_stub_type stub_type;
+ struct elf32_nios2_stub_hash_entry *hsh;
+ asection *sym_sec;
+ bfd_vma sym_value;
+ bfd_vma destination;
+ struct elf32_nios2_link_hash_entry *hh;
+ char *stub_name;
+ const asection *id_sec;
+
+ r_type = ELF32_R_TYPE (irela->r_info);
+ r_indx = ELF32_R_SYM (irela->r_info);
+
+ if (r_type >= (unsigned int) R_NIOS2_ILLEGAL)
+ {
+ bfd_set_error (bfd_error_bad_value);
+ error_ret_free_internal:
+ if (elf_section_data (section)->relocs == NULL)
+ free (internal_relocs);
+ goto error_ret_free_local;
+ }
+
+ /* Only look for stubs on CALL and JMPI instructions. */
+ if (r_type != (unsigned int) R_NIOS2_CALL26)
+ continue;
+
+ /* Now determine the call target, its name, value,
+ section. */
+ sym_sec = NULL;
+ sym_value = 0;
+ destination = 0;
+ hh = NULL;
+ if (r_indx < symtab_hdr->sh_info)
+ {
+ /* It's a local symbol. */
+ Elf_Internal_Sym *sym;
+ Elf_Internal_Shdr *hdr;
+ unsigned int shndx;
+
+ sym = local_syms + r_indx;
+ if (ELF_ST_TYPE (sym->st_info) != STT_SECTION)
+ sym_value = sym->st_value;
+ shndx = sym->st_shndx;
+ if (shndx < elf_numsections (input_bfd))
+ {
+ hdr = elf_elfsections (input_bfd)[shndx];
+ sym_sec = hdr->bfd_section;
+ destination = (sym_value + irela->r_addend
+ + sym_sec->output_offset
+ + sym_sec->output_section->vma);
+ }
+ }
+ else
+ {
+ /* It's an external symbol. */
+ int e_indx;
+
+ e_indx = r_indx - symtab_hdr->sh_info;
+ hh = ((struct elf32_nios2_link_hash_entry *)
+ elf_sym_hashes (input_bfd)[e_indx]);
+
+ while (hh->root.root.type == bfd_link_hash_indirect
+ || hh->root.root.type == bfd_link_hash_warning)
+ hh = ((struct elf32_nios2_link_hash_entry *)
+ hh->root.root.u.i.link);
+
+ if (hh->root.root.type == bfd_link_hash_defined
+ || hh->root.root.type == bfd_link_hash_defweak)
+ {
+ sym_sec = hh->root.root.u.def.section;
+ sym_value = hh->root.root.u.def.value;
+
+ if (sym_sec->output_section != NULL)
+ destination = (sym_value + irela->r_addend
+ + sym_sec->output_offset
+ + sym_sec->output_section->vma);
+ else
+ continue;
+ }
+ else if (hh->root.root.type == bfd_link_hash_undefweak)
+ {
+ if (! info->shared)
+ continue;
+ }
+ else if (hh->root.root.type == bfd_link_hash_undefined)
+ {
+ if (! (info->unresolved_syms_in_objects == RM_IGNORE
+ && (ELF_ST_VISIBILITY (hh->root.other)
+ == STV_DEFAULT)))
+ continue;
+ }
+ else
+ {
+ bfd_set_error (bfd_error_bad_value);
+ goto error_ret_free_internal;
+ }
+ }
+
+ /* Determine what (if any) linker stub is needed. */
+ stub_type = nios2_type_of_stub (section, irela, hh, htab,
+ destination, info);
+ if (stub_type == nios2_stub_none)
+ continue;
+
+ /* Support for grouping stub sections. */
+ if (stub_type == nios2_stub_call26_before)
+ id_sec = htab->stub_group[section->id].first_sec;
+ else
+ id_sec = htab->stub_group[section->id].last_sec;
+
+ /* Get the name of this stub. */
+ stub_name = nios2_stub_name (id_sec, sym_sec, hh, irela,
+ stub_type);
+ if (!stub_name)
+ goto error_ret_free_internal;
+
+ hsh = nios2_stub_hash_lookup (&htab->bstab,
+ stub_name,
+ FALSE, FALSE);
+ if (hsh != NULL)
+ {
+ /* The proper stub has already been created. */
+ free (stub_name);
+ continue;
+ }
+
+ hsh = nios2_add_stub (stub_name, section, htab, stub_type);
+ if (hsh == NULL)
+ {
+ free (stub_name);
+ goto error_ret_free_internal;
+ }
+ hsh->target_value = sym_value;
+ hsh->target_section = sym_sec;
+ hsh->stub_type = stub_type;
+ hsh->hh = hh;
+ hsh->addend = irela->r_addend;
+ stub_changed = TRUE;
+ }
+
+ /* We're done with the internal relocs, free them. */
+ if (elf_section_data (section)->relocs == NULL)
+ free (internal_relocs);
+ }
+ }
+
+ if (!stub_changed)
+ break;
+
+ /* OK, we've added some stubs. Find out the new size of the
+ stub sections. */
+ for (stub_sec = htab->stub_bfd->sections;
+ stub_sec != NULL;
+ stub_sec = stub_sec->next)
+ stub_sec->size = 0;
+
+ bfd_hash_traverse (&htab->bstab, nios2_size_one_stub, htab);
+
+ /* Ask the linker to do its stuff. */
+ (*htab->layout_sections_again) ();
+ stub_changed = FALSE;
+ }
+
+ free (htab->all_local_syms);
+ return TRUE;
+
+ error_ret_free_local:
+ free (htab->all_local_syms);
+ return FALSE;
+}
+
+/* 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 function is called via nios2elf_finish in the linker. */
+bfd_boolean
+nios2_elf32_build_stubs (struct bfd_link_info *info)
+{
+ asection *stub_sec;
+ struct bfd_hash_table *table;
+ struct elf32_nios2_link_hash_table *htab;
+
+ htab = elf32_nios2_hash_table (info);
+
+ for (stub_sec = htab->stub_bfd->sections;
+ stub_sec != NULL;
+ stub_sec = stub_sec->next)
+ /* The stub_bfd may contain non-stub sections if it is also the
+ dynobj. Any such non-stub sections are created with the
+ SEC_LINKER_CREATED flag set, while stub sections do not
+ have that flag. Ignore any non-stub sections here. */
+ if ((stub_sec->flags & SEC_LINKER_CREATED) == 0)
+ {
+ bfd_size_type size;
+
+ /* Allocate memory to hold the linker stubs. */
+ size = stub_sec->size;
+ stub_sec->contents = bfd_zalloc (htab->stub_bfd, size);
+ if (stub_sec->contents == NULL && size != 0)
+ return FALSE;
+ stub_sec->size = 0;
+ }
+
+ /* Build the stubs as directed by the stub hash table. */
+ table = &htab->bstab;
+ bfd_hash_traverse (table, nios2_build_one_stub, info);
+
+ return TRUE;
+}
+
+
+/* Implement bfd_elf32_bfd_reloc_type_lookup:
+ Given a BFD reloc type, return a howto structure. */
+static reloc_howto_type *
+nios2_elf32_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ bfd_reloc_code_real_type code)
+{
+ int i;
+ for (i = 0;
+ i < (int) (sizeof (nios2_reloc_map) / sizeof (struct elf_reloc_map));
+ ++i)
+ if (nios2_reloc_map[i].bfd_val == code)
+ return &elf_nios2_howto_table_rel[(int) nios2_reloc_map[i].elf_val];
+ return NULL;
+}
+
+/* Implement bfd_elf32_bfd_reloc_name_lookup:
+ Given a reloc name, return a howto structure. */
+static reloc_howto_type *
+nios2_elf32_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ const char *r_name)
+{
+ unsigned int i;
+ for (i = 0;
+ i < (sizeof (elf_nios2_howto_table_rel)
+ / sizeof (elf_nios2_howto_table_rel[0]));
+ i++)
+ if (elf_nios2_howto_table_rel[i].name
+ && strcasecmp (elf_nios2_howto_table_rel[i].name, r_name) == 0)
+ return &elf_nios2_howto_table_rel[i];
+
+ return NULL;
+}
+
+/* Implement elf_info_to_howto:
+ Given a ELF32 relocation, fill in a arelent structure. */
+static void
+nios2_elf32_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED, arelent *cache_ptr,
+ Elf_Internal_Rela *dst)
+{
+ unsigned int r_type;
+
+ r_type = ELF32_R_TYPE (dst->r_info);
+ BFD_ASSERT (r_type < R_NIOS2_ILLEGAL);
+ cache_ptr->howto = &elf_nios2_howto_table_rel[r_type];
+}
+
+/* Return the base VMA address which should be subtracted from real addresses
+ when resolving @dtpoff relocation.
+ This is PT_TLS segment p_vaddr. */
+static bfd_vma
+dtpoff_base (struct bfd_link_info *info)
+{
+ /* If tls_sec is NULL, we should have signalled an error already. */
+ if (elf_hash_table (info)->tls_sec == NULL)
+ return 0;
+ return elf_hash_table (info)->tls_sec->vma;
+}
+
+/* Return the relocation value for @tpoff relocation
+ if STT_TLS virtual address is ADDRESS. */
+static bfd_vma
+tpoff (struct bfd_link_info *info, bfd_vma address)
+{
+ struct elf_link_hash_table *htab = elf_hash_table (info);
+
+ /* If tls_sec is NULL, we should have signalled an error already. */
+ if (htab->tls_sec == NULL)
+ return 0;
+ return address - htab->tls_sec->vma;
+}
+
+/* Set the GP value for OUTPUT_BFD. Returns FALSE if this is a
+ dangerous relocation. */
+static bfd_boolean
+nios2_elf_assign_gp (bfd *output_bfd, bfd_vma *pgp, struct bfd_link_info *info)
+{
+
+ bfd_boolean gp_found;
+ struct bfd_hash_entry *h;
+ struct bfd_link_hash_entry *lh;
+
+ /* If we've already figured out what GP will be, just return it. */
+ *pgp = _bfd_get_gp_value (output_bfd);
+ if (*pgp)
+ return TRUE;
+
+ h = bfd_hash_lookup (&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 = FALSE;
+ break;
+ case bfd_link_hash_defined:
+ case bfd_link_hash_defweak:
+ gp_found = TRUE;
+ *pgp = 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 = FALSE;
+
+ if (!gp_found)
+ {
+ /* Only get the error once. */
+ *pgp = 4;
+ _bfd_set_gp_value (output_bfd, *pgp);
+ return FALSE;
+ }
+
+ _bfd_set_gp_value (output_bfd, *pgp);
+
+ return TRUE;
+}
+
+/* Retrieve the previously cached _gp pointer, returning bfd_reloc_dangerous
+ if it's not available as we don't have a link_info pointer available here
+ to look it up in the output symbol table. We don't need to adjust the
+ symbol value for an external symbol if we are producing relocatable
+ output. */
+static bfd_reloc_status_type
+nios2_elf_final_gp (bfd *output_bfd, asymbol *symbol, bfd_boolean relocatable,
+ char **error_message, bfd_vma *pgp)
+{
+ if (bfd_is_und_section (symbol->section) && !relocatable)
+ {
+ *pgp = 0;
+ return bfd_reloc_undefined;
+ }
+
+ *pgp = _bfd_get_gp_value (output_bfd);
+ if (*pgp == 0 && (!relocatable || (symbol->flags & BSF_SECTION_SYM) != 0))
+ {
+ if (relocatable)
+ {
+ /* Make up a value. */
+ *pgp = symbol->section->output_section->vma + 0x4000;
+ _bfd_set_gp_value (output_bfd, *pgp);
+ }
+ else
+ {
+ *error_message
+ = (char *) _("global pointer relative relocation when _gp not defined");
+ return bfd_reloc_dangerous;
+ }
+ }
+
+ return bfd_reloc_ok;
+}
+
+/* Do the relocations that require special handling. */
+static bfd_reloc_status_type
+nios2_elf32_do_hi16_relocate (bfd *abfd, reloc_howto_type *howto,
+ asection *input_section,
+ bfd_byte *data, bfd_vma offset,
+ bfd_vma symbol_value, bfd_vma addend)
+{
+ symbol_value = symbol_value + addend;
+ addend = 0;
+ symbol_value = (symbol_value >> 16) & 0xffff;
+ return _bfd_final_link_relocate (howto, abfd, input_section,
+ data, offset, symbol_value, addend);
+}
+
+static bfd_reloc_status_type
+nios2_elf32_do_lo16_relocate (bfd *abfd, reloc_howto_type *howto,
+ asection *input_section,
+ bfd_byte *data, bfd_vma offset,
+ bfd_vma symbol_value, bfd_vma addend)
+{
+ symbol_value = symbol_value + addend;
+ addend = 0;
+ symbol_value = symbol_value & 0xffff;
+ return _bfd_final_link_relocate (howto, abfd, input_section,
+ data, offset, symbol_value, addend);
+}
+
+static bfd_reloc_status_type
+nios2_elf32_do_hiadj16_relocate (bfd *abfd, reloc_howto_type *howto,
+ asection *input_section,
+ bfd_byte *data, bfd_vma offset,
+ bfd_vma symbol_value, bfd_vma addend)
+{
+ symbol_value = symbol_value + addend;
+ addend = 0;
+ symbol_value = hiadj(symbol_value);
+ return _bfd_final_link_relocate (howto, abfd, input_section, data, offset,
+ symbol_value, addend);
+}
+
+static bfd_reloc_status_type
+nios2_elf32_do_pcrel_lo16_relocate (bfd *abfd, reloc_howto_type *howto,
+ asection *input_section,
+ bfd_byte *data, bfd_vma offset,
+ bfd_vma symbol_value, bfd_vma addend)
+{
+ symbol_value = symbol_value + addend;
+ addend = 0;
+ symbol_value = symbol_value & 0xffff;
+ return _bfd_final_link_relocate (howto, abfd, input_section,
+ data, offset, symbol_value, addend);
+}
+
+static bfd_reloc_status_type
+nios2_elf32_do_pcrel_hiadj16_relocate (bfd *abfd, reloc_howto_type *howto,
+ asection *input_section,
+ bfd_byte *data, bfd_vma offset,
+ bfd_vma symbol_value, bfd_vma addend)
+{
+ symbol_value = symbol_value + addend;
+ symbol_value -= (input_section->output_section->vma
+ + input_section->output_offset);
+ symbol_value -= offset;
+ addend = 0;
+ symbol_value = hiadj(symbol_value);
+ return _bfd_final_link_relocate (howto, abfd, input_section, data, offset,
+ symbol_value, addend);
+}
+
+static bfd_reloc_status_type
+nios2_elf32_do_pcrel16_relocate (bfd *abfd, reloc_howto_type *howto,
+ asection *input_section,
+ bfd_byte *data, bfd_vma offset,
+ bfd_vma symbol_value, bfd_vma addend)
+{
+ /* NIOS2 pc relative relocations are relative to the next 32-bit instruction
+ so we need to subtract 4 before doing a final_link_relocate. */
+ symbol_value = symbol_value + addend - 4;
+ addend = 0;
+ return _bfd_final_link_relocate (howto, abfd, input_section,
+ data, offset, symbol_value, addend);
+}
+
+static bfd_reloc_status_type
+nios2_elf32_do_call26_relocate (bfd *abfd, reloc_howto_type *howto,
+ asection *input_section,
+ bfd_byte *data, bfd_vma offset,
+ bfd_vma symbol_value, bfd_vma addend)
+{
+ /* Check that the relocation is in the same page as the current address. */
+ if (CALL26_SEGMENT (symbol_value + addend)
+ != CALL26_SEGMENT (input_section->output_section->vma
+ + input_section->output_offset
+ + offset))
+ return bfd_reloc_overflow;
+
+ return _bfd_final_link_relocate (howto, abfd, input_section,
+ data, offset, symbol_value, addend);
+}
+
+static bfd_reloc_status_type
+nios2_elf32_do_gprel_relocate (bfd *abfd, reloc_howto_type *howto,
+ asection *input_section,
+ bfd_byte *data, bfd_vma offset,
+ bfd_vma symbol_value, bfd_vma addend)
+{
+ /* Because we need the output_bfd, the special handling is done
+ in nios2_elf32_relocate_section or in nios2_elf32_gprel_relocate. */
+ return _bfd_final_link_relocate (howto, abfd, input_section,
+ data, offset, symbol_value, addend);
+}
+
+static bfd_reloc_status_type
+nios2_elf32_do_ujmp_relocate (bfd *abfd, reloc_howto_type *howto,
+ asection *input_section,
+ bfd_byte *data, bfd_vma offset,
+ bfd_vma symbol_value, bfd_vma addend)
+{
+ bfd_vma symbol_lo16, symbol_hi16;
+ bfd_reloc_status_type r;
+ symbol_value = symbol_value + addend;
+ addend = 0;
+ symbol_hi16 = (symbol_value >> 16) & 0xffff;
+ symbol_lo16 = symbol_value & 0xffff;
+
+ r = _bfd_final_link_relocate (howto, abfd, input_section,
+ data, offset, symbol_hi16, addend);
+
+ if (r == bfd_reloc_ok)
+ return _bfd_final_link_relocate (howto, abfd, input_section,
+ data, offset + 4, symbol_lo16, addend);
+
+ return r;
+}
+
+static bfd_reloc_status_type
+nios2_elf32_do_cjmp_relocate (bfd *abfd, reloc_howto_type *howto,
+ asection *input_section,
+ bfd_byte *data, bfd_vma offset,
+ bfd_vma symbol_value, bfd_vma addend)
+{
+ bfd_vma symbol_lo16, symbol_hi16;
+ bfd_reloc_status_type r;
+ symbol_value = symbol_value + addend;
+ addend = 0;
+ symbol_hi16 = (symbol_value >> 16) & 0xffff;
+ symbol_lo16 = symbol_value & 0xffff;
+
+ r = _bfd_final_link_relocate (howto, abfd, input_section,
+ data, offset, symbol_hi16, addend);
+
+ if (r == bfd_reloc_ok)
+ return _bfd_final_link_relocate (howto, abfd, input_section,
+ data, offset + 4, symbol_lo16, addend);
+
+ return r;
+}
+
+static bfd_reloc_status_type
+nios2_elf32_do_callr_relocate (bfd *abfd, reloc_howto_type *howto,
+ asection *input_section,
+ bfd_byte *data, bfd_vma offset,
+ bfd_vma symbol_value, bfd_vma addend)
+{
+ bfd_vma symbol_lo16, symbol_hi16;
+ bfd_reloc_status_type r;
+ symbol_value = symbol_value + addend;
+ addend = 0;
+ symbol_hi16 = (symbol_value >> 16) & 0xffff;
+ symbol_lo16 = symbol_value & 0xffff;
+
+ r = _bfd_final_link_relocate (howto, abfd, input_section,
+ data, offset, symbol_hi16, addend);
+
+ if (r == bfd_reloc_ok)
+ return _bfd_final_link_relocate (howto, abfd, input_section,
+ data, offset + 4, symbol_lo16, addend);
+
+ return r;
+}
+
+/* HOWTO handlers for relocations that require special handling. */
+
+/* This is for relocations used only when relaxing to ensure
+ changes in size of section don't screw up .align. */
+static bfd_reloc_status_type
+nios2_elf32_ignore_reloc (bfd *abfd ATTRIBUTE_UNUSED, arelent *reloc_entry,
+ asymbol *symbol ATTRIBUTE_UNUSED,
+ void *data ATTRIBUTE_UNUSED, asection *input_section,
+ bfd *output_bfd,
+ char **error_message ATTRIBUTE_UNUSED)
+{
+ if (output_bfd != NULL)
+ reloc_entry->address += input_section->output_offset;
+ return bfd_reloc_ok;
+}
+
+static bfd_reloc_status_type
+nios2_elf32_hi16_relocate (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
+ void *data, asection *input_section,
+ bfd *output_bfd,
+ char **error_message ATTRIBUTE_UNUSED)
+{
+ /* This part is from bfd_elf_generic_reloc. */
+ if (output_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 nios2_elf32_do_hi16_relocate (abfd, reloc_entry->howto,
+ input_section,
+ data, reloc_entry->address,
+ (symbol->value
+ + symbol->section->output_section->vma
+ + symbol->section->output_offset),
+ reloc_entry->addend);
+}
+
+static bfd_reloc_status_type
+nios2_elf32_lo16_relocate (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
+ void *data, asection *input_section,
+ bfd *output_bfd,
+ char **error_message ATTRIBUTE_UNUSED)
+{
+ /* This part is from bfd_elf_generic_reloc. */
+ if (output_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 nios2_elf32_do_lo16_relocate (abfd, reloc_entry->howto,
+ input_section,
+ data, reloc_entry->address,
+ (symbol->value
+ + symbol->section->output_section->vma
+ + symbol->section->output_offset),
+ reloc_entry->addend);
+}
+
+static bfd_reloc_status_type
+nios2_elf32_hiadj16_relocate (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
+ void *data, asection *input_section,
+ bfd *output_bfd,
+ char **error_message ATTRIBUTE_UNUSED)
+{
+ /* This part is from bfd_elf_generic_reloc. */
+ if (output_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 nios2_elf32_do_hiadj16_relocate (abfd, reloc_entry->howto,
+ input_section,
+ data, reloc_entry->address,
+ (symbol->value
+ + symbol->section->output_section->vma
+ + symbol->section->output_offset),
+ reloc_entry->addend);
+}
+
+static bfd_reloc_status_type
+nios2_elf32_pcrel_lo16_relocate (bfd *abfd, arelent *reloc_entry,
+ asymbol *symbol, void *data,
+ asection *input_section, bfd *output_bfd,
+ char **error_message ATTRIBUTE_UNUSED)
+{
+ /* This part is from bfd_elf_generic_reloc. */
+ if (output_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 nios2_elf32_do_pcrel_lo16_relocate (
+ abfd, reloc_entry->howto, input_section, data, reloc_entry->address,
+ (symbol->value + symbol->section->output_section->vma
+ + symbol->section->output_offset),
+ reloc_entry->addend);
+}
+
+static bfd_reloc_status_type
+nios2_elf32_pcrel_hiadj16_relocate (bfd *abfd, arelent *reloc_entry,
+ asymbol *symbol, void *data,
+ asection *input_section, bfd *output_bfd,
+ char **error_message ATTRIBUTE_UNUSED)
+{
+ /* This part is from bfd_elf_generic_reloc. */
+ if (output_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 nios2_elf32_do_pcrel_hiadj16_relocate (
+ abfd, reloc_entry->howto, input_section, data, reloc_entry->address,
+ (symbol->value + symbol->section->output_section->vma
+ + symbol->section->output_offset),
+ reloc_entry->addend);
+}
+
+static bfd_reloc_status_type
+nios2_elf32_pcrel16_relocate (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
+ void *data, asection *input_section,
+ bfd *output_bfd,
+ char **error_message ATTRIBUTE_UNUSED)
+{
+ /* This part is from bfd_elf_generic_reloc. */
+ if (output_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 nios2_elf32_do_pcrel16_relocate (abfd, reloc_entry->howto,
+ input_section,
+ data, reloc_entry->address,
+ (symbol->value
+ + symbol->section->output_section->vma
+ + symbol->section->output_offset),
+ reloc_entry->addend);
+}
+
+static bfd_reloc_status_type
+nios2_elf32_call26_relocate (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
+ void *data, asection *input_section,
+ bfd *output_bfd,
+ char **error_message ATTRIBUTE_UNUSED)
+{
+ /* This part is from bfd_elf_generic_reloc. */
+ if (output_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 nios2_elf32_do_call26_relocate (abfd, reloc_entry->howto,
+ input_section,
+ data, reloc_entry->address,
+ (symbol->value
+ + symbol->section->output_section->vma
+ + symbol->section->output_offset),
+ reloc_entry->addend);
+}
+
+static bfd_reloc_status_type
+nios2_elf32_gprel_relocate (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
+ void *data, asection *input_section,
+ bfd *output_bfd, char **msg)
+{
+ bfd_vma relocation;
+ bfd_vma gp;
+ bfd_reloc_status_type r;
+
+
+ /* This part is from bfd_elf_generic_reloc. */
+ if (output_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;
+
+ relocation = (symbol->value
+ + symbol->section->output_section->vma
+ + symbol->section->output_offset);
+
+ /* This assumes we've already cached the _gp symbol. */
+ r = nios2_elf_final_gp (abfd, symbol, FALSE, msg, &gp);
+ if (r == bfd_reloc_ok)
+ {
+ relocation = relocation + reloc_entry->addend - gp;
+ reloc_entry->addend = 0;
+ if ((signed) relocation < -32768 || (signed) relocation > 32767)
+ {
+ *msg = _("global pointer relative address out of range");
+ r = bfd_reloc_outofrange;
+ }
+ else
+ r = nios2_elf32_do_gprel_relocate (abfd, reloc_entry->howto,
+ input_section,
+ data, reloc_entry->address,
+ relocation, reloc_entry->addend);
+ }
+
+ return r;
+}
+
+static bfd_reloc_status_type
+nios2_elf32_ujmp_relocate (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
+ void *data, asection *input_section,
+ bfd *output_bfd, char **msg ATTRIBUTE_UNUSED)
+{
+ /* This part is from bfd_elf_generic_reloc. */
+ if (output_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 nios2_elf32_do_ujmp_relocate (abfd, reloc_entry->howto,
+ input_section,
+ data, reloc_entry->address,
+ (symbol->value
+ + symbol->section->output_section->vma
+ + symbol->section->output_offset),
+ reloc_entry->addend);
+}
+
+static bfd_reloc_status_type
+nios2_elf32_cjmp_relocate (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
+ void *data, asection *input_section,
+ bfd *output_bfd, char **msg ATTRIBUTE_UNUSED)
+{
+ /* This part is from bfd_elf_generic_reloc. */
+ if (output_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 nios2_elf32_do_cjmp_relocate (abfd, reloc_entry->howto,
+ input_section,
+ data, reloc_entry->address,
+ (symbol->value
+ + symbol->section->output_section->vma
+ + symbol->section->output_offset),
+ reloc_entry->addend);
+}
+
+static bfd_reloc_status_type
+nios2_elf32_callr_relocate (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
+ void *data, asection *input_section,
+ bfd *output_bfd, char **msg ATTRIBUTE_UNUSED)
+{
+ /* This part is from bfd_elf_generic_reloc. */
+ if (output_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 nios2_elf32_do_callr_relocate (abfd, reloc_entry->howto,
+ input_section,
+ data, reloc_entry->address,
+ (symbol->value
+ + symbol->section->output_section->vma
+ + symbol->section->output_offset),
+ reloc_entry->addend);
+}
+
+
+/* Implement elf_backend_relocate_section. */
+static bfd_boolean
+nios2_elf32_relocate_section (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;
+ struct elf32_nios2_link_hash_table *htab;
+ asection *sgot;
+ asection *splt;
+ asection *sreloc = NULL;
+ bfd_vma *local_got_offsets;
+ bfd_vma got_base;
+
+ symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
+ sym_hashes = elf_sym_hashes (input_bfd);
+ relend = relocs + input_section->reloc_count;
+
+ htab = elf32_nios2_hash_table (info);
+ sgot = htab->root.sgot;
+ splt = htab->root.splt;
+ local_got_offsets = elf_local_got_offsets (input_bfd);
+
+ if (elf32_nios2_hash_table (info)->h_gp_got == NULL)
+ got_base = 0;
+ else
+ got_base = elf32_nios2_hash_table (info)->h_gp_got->root.u.def.value;
+
+ 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;
+ struct elf32_nios2_link_hash_entry *eh;
+ bfd_vma relocation;
+ bfd_vma gp;
+ bfd_vma reloc_address;
+ bfd_reloc_status_type r = bfd_reloc_ok;
+ const char *name = NULL;
+ int r_type;
+ const char *format;
+ char msgbuf[256];
+ const char* msg = (const char*) NULL;
+ bfd_boolean unresolved_reloc;
+ bfd_vma off;
+ int use_plt;
+
+ r_type = ELF32_R_TYPE (rel->r_info);
+ r_symndx = ELF32_R_SYM (rel->r_info);
+
+ howto = lookup_howto ((unsigned) 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 = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
+ }
+ else
+ {
+ bfd_boolean warned, ignored;
+
+ RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
+ r_symndx, symtab_hdr, sym_hashes,
+ h, sec, relocation,
+ unresolved_reloc, warned, ignored);
+ }
+
+ if (sec && discarded_section (sec))
+ RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+ rel, 1, relend, howto, 0, contents);
+
+ /* Nothing more to do unless this is a final link. */
+ if (info->relocatable)
+ continue;
+
+ if (sec && sec->output_section)
+ reloc_address = (sec->output_section->vma + sec->output_offset
+ + rel->r_offset);
+ else
+ reloc_address = 0;
+
+ if (howto)
+ {
+ switch (howto->type)
+ {
+ case R_NIOS2_HI16:
+ r = nios2_elf32_do_hi16_relocate (input_bfd, howto,
+ input_section,
+ contents, rel->r_offset,
+ relocation, rel->r_addend);
+ break;
+ case R_NIOS2_LO16:
+ r = nios2_elf32_do_lo16_relocate (input_bfd, howto,
+ input_section,
+ contents, rel->r_offset,
+ relocation, rel->r_addend);
+ break;
+ case R_NIOS2_PCREL_LO:
+ r = nios2_elf32_do_pcrel_lo16_relocate (input_bfd, howto,
+ input_section,
+ contents,
+ rel->r_offset,
+ relocation,
+ rel->r_addend);
+ break;
+ case R_NIOS2_HIADJ16:
+ r = nios2_elf32_do_hiadj16_relocate (input_bfd, howto,
+ input_section, contents,
+ rel->r_offset, relocation,
+ rel->r_addend);
+ break;
+ case R_NIOS2_PCREL_HA:
+ r = nios2_elf32_do_pcrel_hiadj16_relocate (input_bfd, howto,
+ input_section,
+ contents,
+ rel->r_offset,
+ relocation,
+ rel->r_addend);
+ break;
+ case R_NIOS2_PCREL16:
+ r = nios2_elf32_do_pcrel16_relocate (input_bfd, howto,
+ input_section, contents,
+ rel->r_offset, relocation,
+ rel->r_addend);
+ break;
+ case R_NIOS2_GPREL:
+ /* Turns an absolute address into a gp-relative address. */
+ if (!nios2_elf_assign_gp (output_bfd, &gp, info))
+ {
+ format = _("global pointer relative relocation at address "
+ "0x%08x when _gp not defined\n");
+ sprintf (msgbuf, format, reloc_address);
+ msg = msgbuf;
+ r = bfd_reloc_dangerous;
+ }
+ else
+ {
+ bfd_vma symbol_address = rel->r_addend + relocation;
+ relocation = relocation + rel->r_addend - gp;
+ rel->r_addend = 0;
+ if (((signed) relocation < -32768
+ || (signed) relocation > 32767)
+ && (!h
+ || h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak))
+ {
+ format = _("Unable to reach %s (at 0x%08x) from the "
+ "global pointer (at 0x%08x) because the "
+ "offset (%d) is out of the allowed range, "
+ "-32678 to 32767.\n" );
+ sprintf (msgbuf, format, name, symbol_address, gp,
+ (signed)relocation);
+ msg = msgbuf;
+ r = bfd_reloc_outofrange;
+ }
+ else
+ r = _bfd_final_link_relocate (howto, input_bfd,
+ input_section, contents,
+ rel->r_offset, relocation,
+ rel->r_addend);
+ }
+
+ break;
+ case R_NIOS2_UJMP:
+ r = nios2_elf32_do_ujmp_relocate (input_bfd, howto,
+ input_section,
+ contents, rel->r_offset,
+ relocation, rel->r_addend);
+ break;
+ case R_NIOS2_CJMP:
+ r = nios2_elf32_do_cjmp_relocate (input_bfd, howto,
+ input_section,
+ contents, rel->r_offset,
+ relocation, rel->r_addend);
+ break;
+ case R_NIOS2_CALLR:
+ r = nios2_elf32_do_callr_relocate (input_bfd, howto,
+ input_section, contents,
+ rel->r_offset, relocation,
+ rel->r_addend);
+ break;
+ case R_NIOS2_CALL26:
+ case R_NIOS2_CALL26_NOAT:
+ /* If we have a call to an undefined weak symbol, we just want
+ to stuff a zero in the bits of the call instruction and
+ bypass the normal call26 relocation handling, because it'll
+ diagnose an overflow error if address 0 isn't in the same
+ 256MB segment as the call site. Presumably the call
+ should be guarded by a null check anyway. */
+ if (h != NULL && h->root.type == bfd_link_hash_undefweak)
+ {
+ BFD_ASSERT (relocation == 0 && rel->r_addend == 0);
+ r = _bfd_final_link_relocate (howto, input_bfd,
+ input_section, contents,
+ rel->r_offset, relocation,
+ rel->r_addend);
+ break;
+ }
+ /* Handle relocations which should use the PLT entry.
+ NIOS2_BFD_RELOC_32 relocations will use the symbol's value,
+ which may point to a PLT entry, but we don't need to handle
+ that here. If we created a PLT entry, all branches in this
+ object should go to it. */
+ if (h != NULL && splt != NULL && h->plt.offset != (bfd_vma) -1)
+ {
+ /* If we've created a .plt section, and assigned a PLT entry
+ to this function, it should not be known to bind locally.
+ If it were, we would have cleared the PLT entry. */
+ BFD_ASSERT (!SYMBOL_CALLS_LOCAL (info, h));
+
+ relocation = (splt->output_section->vma
+ + splt->output_offset
+ + h->plt.offset);
+
+ unresolved_reloc = FALSE;
+ }
+ /* Detect R_NIOS2_CALL26 relocations that would overflow the
+ 256MB segment. Replace the target with a reference to a
+ trampoline instead.
+ Note that htab->stub_group is null if relaxation has been
+ disabled by the --no-relax linker command-line option, so
+ we can use that to skip this processing entirely. */
+ if (howto->type == R_NIOS2_CALL26 && htab->stub_group)
+ {
+ bfd_vma dest = relocation + rel->r_addend;
+ enum elf32_nios2_stub_type stub_type;
+
+ eh = (struct elf32_nios2_link_hash_entry *)h;
+ stub_type = nios2_type_of_stub (input_section, rel, eh,
+ htab, dest, NULL);
+
+ if (stub_type != nios2_stub_none)
+ {
+ struct elf32_nios2_stub_hash_entry *hsh;
+
+ hsh = nios2_get_stub_entry (input_section, sec,
+ eh, rel, htab, stub_type);
+ if (hsh == NULL)
+ {
+ r = bfd_reloc_undefined;
+ break;
+ }
+
+ dest = (hsh->stub_offset
+ + hsh->stub_sec->output_offset
+ + hsh->stub_sec->output_section->vma);
+ r = nios2_elf32_do_call26_relocate (input_bfd, howto,
+ input_section,
+ contents,
+ rel->r_offset,
+ dest, 0);
+ break;
+ }
+ }
+
+ /* Normal case. */
+ r = nios2_elf32_do_call26_relocate (input_bfd, howto,
+ input_section, contents,
+ rel->r_offset, relocation,
+ rel->r_addend);
+ break;
+ case R_NIOS2_ALIGN:
+ r = bfd_reloc_ok;
+ /* For symmetry this would be
+ r = nios2_elf32_do_ignore_reloc (input_bfd, howto,
+ input_section, contents,
+ rel->r_offset, relocation,
+ rel->r_addend);
+ but do_ignore_reloc would do no more than return
+ bfd_reloc_ok. */
+ break;
+
+ case R_NIOS2_GOT16:
+ case R_NIOS2_CALL16:
+ case R_NIOS2_GOT_LO:
+ case R_NIOS2_GOT_HA:
+ case R_NIOS2_CALL_LO:
+ case R_NIOS2_CALL_HA:
+ /* Relocation is to the entry for this symbol in the
+ global offset table. */
+ if (sgot == NULL)
+ {
+ r = bfd_reloc_notsupported;
+ break;
+ }
+
+ use_plt = 0;
+
+ if (h != NULL)
+ {
+ bfd_boolean dyn;
+
+ eh = (struct elf32_nios2_link_hash_entry *)h;
+ use_plt = (eh->got_types_used == CALL_USED
+ && h->plt.offset != (bfd_vma) -1);
+
+ off = h->got.offset;
+ BFD_ASSERT (off != (bfd_vma) -1);
+ dyn = elf_hash_table (info)->dynamic_sections_created;
+ if (! WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h)
+ || (info->shared
+ && SYMBOL_REFERENCES_LOCAL (info, h))
+ || (ELF_ST_VISIBILITY (h->other)
+ && h->root.type == bfd_link_hash_undefweak))
+ {
+ /* 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;
+ }
+ }
+ else
+ unresolved_reloc = FALSE;
+ }
+ 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;
+ bfd_byte *loc;
+
+ srelgot = htab->root.srelgot;
+ BFD_ASSERT (srelgot != NULL);
+
+ outrel.r_addend = relocation;
+ outrel.r_offset = (sgot->output_section->vma
+ + sgot->output_offset
+ + off);
+ outrel.r_info = ELF32_R_INFO (0, R_NIOS2_RELATIVE);
+ loc = srelgot->contents;
+ loc += (srelgot->reloc_count++ *
+ sizeof (Elf32_External_Rela));
+ bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
+ }
+
+ local_got_offsets[r_symndx] |= 1;
+ }
+ }
+
+ if (use_plt && info->shared)
+ {
+ off = ((h->plt.offset - 24) / 12 + 3) * 4;
+ relocation = (htab->root.sgotplt->output_offset + off
+ - got_base);
+ }
+ else
+ relocation = sgot->output_offset + off - got_base;
+
+ /* This relocation does not use the addend. */
+ rel->r_addend = 0;
+
+ switch (howto->type)
+ {
+ case R_NIOS2_GOT_LO:
+ case R_NIOS2_CALL_LO:
+ r = nios2_elf32_do_lo16_relocate (input_bfd, howto,
+ input_section, contents,
+ rel->r_offset, relocation,
+ rel->r_addend);
+ break;
+ case R_NIOS2_GOT_HA:
+ case R_NIOS2_CALL_HA:
+ r = nios2_elf32_do_hiadj16_relocate (input_bfd, howto,
+ input_section, contents,
+ rel->r_offset,
+ relocation,
+ rel->r_addend);
+ break;
+ default:
+ r = _bfd_final_link_relocate (howto, input_bfd,
+ input_section, contents,
+ rel->r_offset, relocation,
+ rel->r_addend);
+ break;
+ }
+ break;
+
+ case R_NIOS2_GOTOFF_LO:
+ case R_NIOS2_GOTOFF_HA:
+ case R_NIOS2_GOTOFF:
+ /* Relocation is relative to the global offset table pointer. */
+
+ BFD_ASSERT (sgot != NULL);
+ if (sgot == NULL)
+ {
+ r = bfd_reloc_notsupported;
+ break;
+ }
+
+ /* Note that sgot->output_offset is not involved in this
+ calculation. We always want the start of .got. */
+ relocation -= sgot->output_section->vma;
+
+ /* Now we adjust the relocation to be relative to the GOT pointer
+ (the _gp_got symbol), which possibly contains the 0x8000 bias. */
+ relocation -= got_base;
+
+ switch (howto->type)
+ {
+ case R_NIOS2_GOTOFF_LO:
+ r = nios2_elf32_do_lo16_relocate (input_bfd, howto,
+ input_section, contents,
+ rel->r_offset, relocation,
+ rel->r_addend);
+ break;
+ case R_NIOS2_GOTOFF_HA:
+ r = nios2_elf32_do_hiadj16_relocate (input_bfd, howto,
+ input_section, contents,
+ rel->r_offset,
+ relocation,
+ rel->r_addend);
+ break;
+ default:
+ r = _bfd_final_link_relocate (howto, input_bfd,
+ input_section, contents,
+ rel->r_offset, relocation,
+ rel->r_addend);
+ break;
+ }
+ break;
+
+ case R_NIOS2_TLS_LDO16:
+ relocation -= dtpoff_base (info) + DTP_OFFSET;
+
+ r = _bfd_final_link_relocate (howto, input_bfd, input_section,
+ contents, rel->r_offset,
+ relocation, rel->r_addend);
+ break;
+ case R_NIOS2_TLS_LDM16:
+ if (htab->root.sgot == NULL)
+ abort ();
+
+ off = htab->tls_ldm_got.offset;
+
+ if ((off & 1) != 0)
+ off &= ~1;
+ else
+ {
+ /* If we don't know the module number, create a relocation
+ for it. */
+ if (info->shared)
+ {
+ Elf_Internal_Rela outrel;
+ bfd_byte *loc;
+
+ if (htab->root.srelgot == NULL)
+ abort ();
+
+ outrel.r_addend = 0;
+ outrel.r_offset = (htab->root.sgot->output_section->vma
+ + htab->root.sgot->output_offset
+ + off);
+ outrel.r_info = ELF32_R_INFO (0, R_NIOS2_TLS_DTPMOD);
+
+ loc = htab->root.srelgot->contents;
+ loc += (htab->root.srelgot->reloc_count++
+ * sizeof (Elf32_External_Rela));
+ bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
+ }
+ else
+ bfd_put_32 (output_bfd, 1,
+ htab->root.sgot->contents + off);
+
+ htab->tls_ldm_got.offset |= 1;
+ }
+
+ relocation = htab->root.sgot->output_offset + off - got_base;
+
+ r = _bfd_final_link_relocate (howto, input_bfd, input_section,
+ contents, rel->r_offset,
+ relocation, rel->r_addend);
+
+ break;
+ case R_NIOS2_TLS_GD16:
+ case R_NIOS2_TLS_IE16:
+ {
+ int indx;
+ char tls_type;
+
+ if (htab->root.sgot == NULL)
+ abort ();
+
+ indx = 0;
+ if (h != NULL)
+ {
+ bfd_boolean dyn;
+ dyn = htab->root.dynamic_sections_created;
+ if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h)
+ && (!info->shared
+ || !SYMBOL_REFERENCES_LOCAL (info, h)))
+ {
+ unresolved_reloc = FALSE;
+ indx = h->dynindx;
+ }
+ off = h->got.offset;
+ tls_type = (((struct elf32_nios2_link_hash_entry *) h)
+ ->tls_type);
+ }
+ else
+ {
+ if (local_got_offsets == NULL)
+ abort ();
+ off = local_got_offsets[r_symndx];
+ tls_type = (elf32_nios2_local_got_tls_type (input_bfd)
+ [r_symndx]);
+ }
+
+ if (tls_type == GOT_UNKNOWN)
+ abort ();
+
+ if ((off & 1) != 0)
+ off &= ~1;
+ else
+ {
+ bfd_boolean need_relocs = FALSE;
+ Elf_Internal_Rela outrel;
+ bfd_byte *loc = NULL;
+ int cur_off = off;
+
+ /* The GOT entries have not been initialized yet. Do it
+ now, and emit any relocations. If both an IE GOT and a
+ GD GOT are necessary, we emit the GD first. */
+
+ if ((info->shared || indx != 0)
+ && (h == NULL
+ || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
+ || h->root.type != bfd_link_hash_undefweak))
+ {
+ need_relocs = TRUE;
+ if (htab->root.srelgot == NULL)
+ abort ();
+ loc = htab->root.srelgot->contents;
+ loc += (htab->root.srelgot->reloc_count *
+ sizeof (Elf32_External_Rela));
+ }
+
+ if (tls_type & GOT_TLS_GD)
+ {
+ if (need_relocs)
+ {
+ outrel.r_addend = 0;
+ outrel.r_offset = (htab->root.sgot->output_section->vma
+ + htab->root.sgot->output_offset
+ + cur_off);
+ outrel.r_info = ELF32_R_INFO (indx,
+ R_NIOS2_TLS_DTPMOD);
+
+ bfd_elf32_swap_reloca_out (output_bfd, &outrel,
+ loc);
+ htab->root.srelgot->reloc_count++;
+ loc += sizeof (Elf32_External_Rela);
+
+ if (indx == 0)
+ bfd_put_32 (output_bfd,
+ (relocation - dtpoff_base (info) -
+ DTP_OFFSET),
+ htab->root.sgot->contents + cur_off + 4);
+ else
+ {
+ outrel.r_addend = 0;
+ outrel.r_info = ELF32_R_INFO (indx,
+ R_NIOS2_TLS_DTPREL);
+ outrel.r_offset += 4;
+
+ bfd_elf32_swap_reloca_out (output_bfd, &outrel,
+ loc);
+ htab->root.srelgot->reloc_count++;
+ loc += sizeof (Elf32_External_Rela);
+ }
+ }
+ else
+ {
+ /* If we are not emitting relocations for a
+ general dynamic reference, then we must be in a
+ static link or an executable link with the
+ symbol binding locally. Mark it as belonging
+ to module 1, the executable. */
+ bfd_put_32 (output_bfd, 1,
+ htab->root.sgot->contents + cur_off);
+ bfd_put_32 (output_bfd, (relocation -
+ dtpoff_base (info) -
+ DTP_OFFSET),
+ htab->root.sgot->contents + cur_off + 4);
+ }
+
+ cur_off += 8;
+ }
+
+ if (tls_type & GOT_TLS_IE)
+ {
+ if (need_relocs)
+ {
+ if (indx == 0)
+ outrel.r_addend = (relocation -
+ dtpoff_base (info));
+ else
+ outrel.r_addend = 0;
+ outrel.r_offset = (htab->root.sgot->output_section->vma
+ + htab->root.sgot->output_offset
+ + cur_off);
+ outrel.r_info = ELF32_R_INFO (indx,
+ R_NIOS2_TLS_TPREL);
+
+ bfd_elf32_swap_reloca_out (output_bfd, &outrel,
+ loc);
+ htab->root.srelgot->reloc_count++;
+ loc += sizeof (Elf32_External_Rela);
+ }
+ else
+ bfd_put_32 (output_bfd, (tpoff (info, relocation)
+ - TP_OFFSET),
+ htab->root.sgot->contents + cur_off);
+ cur_off += 4;
+ }
+
+ if (h != NULL)
+ h->got.offset |= 1;
+ else
+ local_got_offsets[r_symndx] |= 1;
+ }
+
+ if ((tls_type & GOT_TLS_GD) && r_type != R_NIOS2_TLS_GD16)
+ off += 8;
+ relocation = htab->root.sgot->output_offset + off - got_base;
+
+ r = _bfd_final_link_relocate (howto, input_bfd, input_section,
+ contents, rel->r_offset,
+ relocation, rel->r_addend);
+ }
+
+ break;
+ case R_NIOS2_TLS_LE16:
+ if (info->shared && !info->pie)
+ {
+ (*_bfd_error_handler)
+ (_("%B(%A+0x%lx): R_NIOS2_TLS_LE16 relocation not "
+ "permitted in shared object"),
+ input_bfd, input_section,
+ (long) rel->r_offset, howto->name);
+ return FALSE;
+ }
+ else
+ relocation = tpoff (info, relocation) - TP_OFFSET;
+
+ r = _bfd_final_link_relocate (howto, input_bfd, input_section,
+ contents, rel->r_offset,
+ relocation, rel->r_addend);
+ break;
+
+ case R_NIOS2_BFD_RELOC_32:
+ if (info->shared
+ && (input_section->flags & SEC_ALLOC) != 0
+ && (h == NULL
+ || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
+ || h->root.type != bfd_link_hash_undefweak))
+ {
+ Elf_Internal_Rela outrel;
+ bfd_byte *loc;
+ bfd_boolean skip, relocate;
+
+ /* When generating a shared object, these relocations
+ are copied into the output file to be resolved at run
+ time. */
+
+ skip = FALSE;
+ relocate = FALSE;
+
+ outrel.r_offset
+ = _bfd_elf_section_offset (output_bfd, info,
+ input_section, rel->r_offset);
+ if (outrel.r_offset == (bfd_vma) -1)
+ skip = TRUE;
+ else if (outrel.r_offset == (bfd_vma) -2)
+ skip = TRUE, relocate = TRUE;
+ outrel.r_offset += (input_section->output_section->vma
+ + input_section->output_offset);
+
+ if (skip)
+ memset (&outrel, 0, sizeof outrel);
+ else if (h != NULL
+ && h->dynindx != -1
+ && (!info->shared
+ || !info->symbolic
+ || !h->def_regular))
+ {
+ outrel.r_info = ELF32_R_INFO (h->dynindx, r_type);
+ outrel.r_addend = rel->r_addend;
+ }
+ else
+ {
+ /* This symbol is local, or marked to become local. */
+ outrel.r_addend = relocation + rel->r_addend;
+ relocate = TRUE;
+ outrel.r_info = ELF32_R_INFO (0, R_NIOS2_RELATIVE);
+ }
+
+ sreloc = elf_section_data (input_section)->sreloc;
+ if (sreloc == NULL)
+ abort ();
+
+ loc = sreloc->contents;
+ loc += sreloc->reloc_count++ * sizeof (Elf32_External_Rela);
+ bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
+
+ /* This reloc will be computed at runtime, so there's no
+ need to do anything now, except for R_NIOS2_BFD_RELOC_32
+ relocations that have been turned into
+ R_NIOS2_RELATIVE. */
+ if (!relocate)
+ break;
+ }
+
+ r = _bfd_final_link_relocate (howto, input_bfd,
+ input_section, contents,
+ rel->r_offset, relocation,
+ rel->r_addend);
+ break;
+
+ case R_NIOS2_TLS_DTPREL:
+ relocation -= dtpoff_base (info);
+ /* Fall through. */
+
+ default:
+ r = _bfd_final_link_relocate (howto, input_bfd,
+ input_section, contents,
+ rel->r_offset, relocation,
+ rel->r_addend);
+ break;
+ }
+ }
+ else
+ r = bfd_reloc_notsupported;
+
+ if (r != bfd_reloc_ok)
+ {
+ 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:
+ r = info->callbacks->reloc_overflow (info, NULL, 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, TRUE);
+ break;
+
+ case bfd_reloc_outofrange:
+ if (msg == NULL)
+ msg = _("relocation out of range");
+ break;
+
+ case bfd_reloc_notsupported:
+ if (msg == NULL)
+ msg = _("unsupported relocation");
+ break;
+
+ case bfd_reloc_dangerous:
+ if (msg == NULL)
+ msg = _("dangerous relocation");
+ break;
+
+ default:
+ if (msg == NULL)
+ msg = _("unknown error");
+ break;
+ }
+
+ if (msg)
+ {
+ r = info->callbacks->warning
+ (info, msg, name, input_bfd, input_section, rel->r_offset);
+ return FALSE;
+ }
+ }
+ }
+ return TRUE;
+}
+
+/* Implement elf-backend_section_flags:
+ Convert NIOS2 specific section flags to bfd internal section flags. */
+static bfd_boolean
+nios2_elf32_section_flags (flagword *flags, const Elf_Internal_Shdr *hdr)
+{
+ if (hdr->sh_flags & SHF_NIOS2_GPREL)
+ *flags |= SEC_SMALL_DATA;
+
+ return TRUE;
+}
+
+/* Implement elf_backend_fake_sections:
+ Set the correct type for an NIOS2 ELF section. We do this by the
+ section name, which is a hack, but ought to work. */
+static bfd_boolean
+nios2_elf32_fake_sections (bfd *abfd ATTRIBUTE_UNUSED,
+ Elf_Internal_Shdr *hdr, asection *sec)
+{
+ register const char *name = bfd_get_section_name (abfd, sec);
+
+ if ((sec->flags & SEC_SMALL_DATA)
+ || strcmp (name, ".sdata") == 0
+ || strcmp (name, ".sbss") == 0
+ || strcmp (name, ".lit4") == 0 || strcmp (name, ".lit8") == 0)
+ hdr->sh_flags |= SHF_NIOS2_GPREL;
+
+ return TRUE;
+}
+
+/* Create .got, .gotplt, and .rela.got sections in DYNOBJ, and set up
+ shortcuts to them in our hash table. */
+static bfd_boolean
+create_got_section (bfd *dynobj, struct bfd_link_info *info)
+{
+ struct elf32_nios2_link_hash_table *htab;
+ struct elf_link_hash_entry *h;
+
+ htab = elf32_nios2_hash_table (info);
+
+ if (! _bfd_elf_create_got_section (dynobj, info))
+ return FALSE;
+
+ /* In order for the two loads in .PLTresolve to share the same %hiadj,
+ _GLOBAL_OFFSET_TABLE_ must be aligned to a 16-byte boundary. */
+ if (!bfd_set_section_alignment (dynobj, htab->root.sgotplt, 4))
+ return FALSE;
+
+ /* The Nios II ABI specifies that GOT-relative relocations are relative
+ to the linker-created symbol _gp_got, rather than using
+ _GLOBAL_OFFSET_TABLE_ directly. In particular, the latter always
+ points to the base of the GOT while _gp_got may include a bias. */
+ h = _bfd_elf_define_linkage_sym (dynobj, info, htab->root.sgotplt,
+ "_gp_got");
+ elf32_nios2_hash_table (info)->h_gp_got = h;
+ if (h == NULL)
+ return FALSE;
+
+ return TRUE;
+}
+
+/* Implement elf_backend_create_dynamic_sections:
+ Create .plt, .rela.plt, .got, .got.plt, .rela.got, .dynbss, and
+ .rela.bss sections in DYNOBJ, and set up shortcuts to them in our
+ hash table. */
+static bfd_boolean
+nios2_elf32_create_dynamic_sections (bfd *dynobj, struct bfd_link_info *info)
+{
+ struct elf32_nios2_link_hash_table *htab;
+
+ htab = elf32_nios2_hash_table (info);
+ if (!htab->root.sgot && !create_got_section (dynobj, info))
+ return FALSE;
+
+ _bfd_elf_create_dynamic_sections (dynobj, info);
+
+ /* In order for the two loads in a shared object .PLTresolve to share the
+ same %hiadj, the start of the PLT (as well as the GOT) must be aligned
+ to a 16-byte boundary. This is because the addresses for these loads
+ include the -(.plt+4) PIC correction. */
+ if (!bfd_set_section_alignment (dynobj, htab->root.splt, 4))
+ return FALSE;
+
+ htab->sdynbss = bfd_get_linker_section (dynobj, ".dynbss");
+ if (!htab->sdynbss)
+ return FALSE;
+ if (!info->shared)
+ {
+ htab->srelbss = bfd_get_linker_section (dynobj, ".rela.bss");
+ if (!htab->srelbss)
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/* Implement elf_backend_copy_indirect_symbol:
+ Copy the extra info we tack onto an elf_link_hash_entry. */
+static void
+nios2_elf32_copy_indirect_symbol (struct bfd_link_info *info,
+ struct elf_link_hash_entry *dir,
+ struct elf_link_hash_entry *ind)
+{
+ struct elf32_nios2_link_hash_entry *edir, *eind;
+
+ edir = (struct elf32_nios2_link_hash_entry *) dir;
+ eind = (struct elf32_nios2_link_hash_entry *) ind;
+
+ if (eind->dyn_relocs != NULL)
+ {
+ if (edir->dyn_relocs != NULL)
+ {
+ struct elf32_nios2_dyn_relocs **pp;
+ struct elf32_nios2_dyn_relocs *p;
+
+ /* Add reloc counts against the indirect sym to the direct sym
+ list. Merge any entries against the same section. */
+ for (pp = &eind->dyn_relocs; (p = *pp) != NULL; )
+ {
+ struct elf32_nios2_dyn_relocs *q;
+
+ for (q = edir->dyn_relocs; q != NULL; q = q->next)
+ if (q->sec == p->sec)
+ {
+ q->pc_count += p->pc_count;
+ q->count += p->count;
+ *pp = p->next;
+ break;
+ }
+ if (q == NULL)
+ pp = &p->next;
+ }
+ *pp = edir->dyn_relocs;
+ }
+
+ edir->dyn_relocs = eind->dyn_relocs;
+ eind->dyn_relocs = NULL;
+ }
+
+ if (ind->root.type == bfd_link_hash_indirect
+ && dir->got.refcount <= 0)
+ {
+ edir->tls_type = eind->tls_type;
+ eind->tls_type = GOT_UNKNOWN;
+ }
+
+ edir->got_types_used |= eind->got_types_used;
+
+ _bfd_elf_link_hash_copy_indirect (info, dir, ind);
+}
+
+/* Implement elf_backend_check_relocs:
+ Look through the relocs for a section during the first phase. */
+static bfd_boolean
+nios2_elf32_check_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;
+ struct elf32_nios2_link_hash_table *htab;
+ asection *sgot;
+ asection *srelgot;
+ asection *sreloc = NULL;
+ bfd_signed_vma *local_got_refcounts;
+
+ if (info->relocatable)
+ return TRUE;
+
+ dynobj = elf_hash_table (info)->dynobj;
+ 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;
+ local_got_refcounts = elf_local_got_refcounts (abfd);
+
+ htab = elf32_nios2_hash_table (info);
+ sgot = htab->root.sgot;
+ srelgot = htab->root.srelgot;
+
+ rel_end = relocs + sec->reloc_count;
+ for (rel = relocs; rel < rel_end; rel++)
+ {
+ unsigned int r_type;
+ 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];
+ 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;
+
+ /* PR15323, ref flags aren't set for references in the same
+ object. */
+ h->root.non_ir_ref = 1;
+ }
+
+ r_type = ELF32_R_TYPE (rel->r_info);
+
+ switch (r_type)
+ {
+ case R_NIOS2_GOT16:
+ case R_NIOS2_GOT_LO:
+ case R_NIOS2_GOT_HA:
+ case R_NIOS2_CALL16:
+ case R_NIOS2_CALL_LO:
+ case R_NIOS2_CALL_HA:
+ case R_NIOS2_TLS_GD16:
+ case R_NIOS2_TLS_IE16:
+ /* This symbol requires a global offset table entry. */
+ {
+ int tls_type, old_tls_type;
+
+ switch (r_type)
+ {
+ default:
+ case R_NIOS2_GOT16:
+ case R_NIOS2_GOT_LO:
+ case R_NIOS2_GOT_HA:
+ case R_NIOS2_CALL16:
+ case R_NIOS2_CALL_LO:
+ case R_NIOS2_CALL_HA:
+ tls_type = GOT_NORMAL;
+ break;
+ case R_NIOS2_TLS_GD16:
+ tls_type = GOT_TLS_GD;
+ break;
+ case R_NIOS2_TLS_IE16:
+ tls_type = GOT_TLS_IE;
+ break;
+ }
+
+ if (dynobj == NULL)
+ {
+ /* Create the .got section. */
+ elf_hash_table (info)->dynobj = dynobj = abfd;
+ nios2_elf32_create_dynamic_sections (dynobj, info);
+ }
+
+ if (sgot == NULL)
+ {
+ sgot = htab->root.sgot;
+ BFD_ASSERT (sgot != NULL);
+ }
+
+ if (srelgot == NULL
+ && (h != NULL || info->shared))
+ {
+ srelgot = htab->root.srelgot;
+ BFD_ASSERT (srelgot != NULL);
+ }
+
+ if (h != NULL)
+ {
+ struct elf32_nios2_link_hash_entry *eh
+ = (struct elf32_nios2_link_hash_entry *)h;
+ h->got.refcount++;
+ old_tls_type = elf32_nios2_hash_entry(h)->tls_type;
+ if (r_type == R_NIOS2_CALL16
+ || r_type == R_NIOS2_CALL_LO
+ || r_type == R_NIOS2_CALL_HA)
+ {
+ /* Make sure a plt entry is created for this symbol if
+ it turns out to be a function defined by a dynamic
+ object. */
+ h->plt.refcount++;
+ h->needs_plt = 1;
+ h->type = STT_FUNC;
+ eh->got_types_used |= CALL_USED;
+ }
+ else
+ eh->got_types_used |= GOT_USED;
+ }
+ else
+ {
+ /* This is a global offset table entry for a local symbol. */
+ if (local_got_refcounts == NULL)
+ {
+ bfd_size_type size;
+
+ size = symtab_hdr->sh_info;
+ size *= (sizeof (bfd_signed_vma) + sizeof (char));
+ local_got_refcounts
+ = ((bfd_signed_vma *) bfd_zalloc (abfd, size));
+ if (local_got_refcounts == NULL)
+ return FALSE;
+ elf_local_got_refcounts (abfd) = local_got_refcounts;
+ elf32_nios2_local_got_tls_type (abfd)
+ = (char *) (local_got_refcounts + symtab_hdr->sh_info);
+ }
+ local_got_refcounts[r_symndx]++;
+ old_tls_type = elf32_nios2_local_got_tls_type (abfd) [r_symndx];
+ }
+
+ /* We will already have issued an error message if there is a
+ TLS / non-TLS mismatch, based on the symbol type. We don't
+ support any linker relaxations. So just combine any TLS
+ types needed. */
+ if (old_tls_type != GOT_UNKNOWN && old_tls_type != GOT_NORMAL
+ && tls_type != GOT_NORMAL)
+ tls_type |= old_tls_type;
+
+ if (old_tls_type != tls_type)
+ {
+ if (h != NULL)
+ elf32_nios2_hash_entry (h)->tls_type = tls_type;
+ else
+ elf32_nios2_local_got_tls_type (abfd) [r_symndx] = tls_type;
+ }
+ }
+ /* Fall through */
+ case R_NIOS2_TLS_LDM16:
+ if (r_type == R_NIOS2_TLS_LDM16)
+ htab->tls_ldm_got.refcount++;
+
+ if (htab->root.sgot == NULL)
+ {
+ if (htab->root.dynobj == NULL)
+ htab->root.dynobj = abfd;
+ if (!create_got_section (htab->root.dynobj, info))
+ return FALSE;
+ }
+ break;
+
+ /* This relocation describes the C++ object vtable hierarchy.
+ Reconstruct it for later use during GC. */
+ case R_NIOS2_GNU_VTINHERIT:
+ if (!bfd_elf_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_NIOS2_GNU_VTENTRY:
+ if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
+ return FALSE;
+ break;
+
+ case R_NIOS2_BFD_RELOC_32:
+ case R_NIOS2_CALL26:
+ case R_NIOS2_CALL26_NOAT:
+ case R_NIOS2_HIADJ16:
+ case R_NIOS2_LO16:
+
+ if (h != NULL)
+ {
+ /* If this reloc is in a read-only section, we might
+ need a copy reloc. We can't check reliably at this
+ stage whether the section is read-only, as input
+ sections have not yet been mapped to output sections.
+ Tentatively set the flag for now, and correct in
+ adjust_dynamic_symbol. */
+ if (!info->shared)
+ h->non_got_ref = 1;
+
+ /* Make sure a plt entry is created for this symbol if it
+ turns out to be a function defined by a dynamic object. */
+ h->plt.refcount++;
+
+ if (r_type == R_NIOS2_CALL26 || r_type == R_NIOS2_CALL26_NOAT)
+ h->needs_plt = 1;
+ }
+
+ /* 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
+ && (r_type == R_NIOS2_BFD_RELOC_32
+ || (h != NULL && ! h->needs_plt
+ && (! info->symbolic || ! h->def_regular))))
+ {
+ struct elf32_nios2_dyn_relocs *p;
+ struct elf32_nios2_dyn_relocs **head;
+
+ /* 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)
+ {
+ sreloc = _bfd_elf_make_dynamic_reloc_section
+ (sec, dynobj, 2, abfd, TRUE);
+ if (sreloc == NULL)
+ return FALSE;
+ }
+
+ /* If this is a global symbol, we count the number of
+ relocations we need for this symbol. */
+ if (h != NULL)
+ head = &((struct elf32_nios2_link_hash_entry *) h)->dyn_relocs;
+ else
+ {
+ /* Track dynamic relocs needed for local syms too.
+ We really need local syms available to do this
+ easily. Oh well. */
+
+ asection *s;
+ void *vpp;
+ Elf_Internal_Sym *isym;
+
+ isym = bfd_sym_from_r_symndx (&htab->sym_cache,
+ abfd, r_symndx);
+ if (isym == NULL)
+ return FALSE;
+
+ s = bfd_section_from_elf_index (abfd, isym->st_shndx);
+ if (s == NULL)
+ s = sec;
+
+ vpp = &elf_section_data (s)->local_dynrel;
+ head = (struct elf32_nios2_dyn_relocs **) vpp;
+ }
+
+ p = *head;
+ if (p == NULL || p->sec != sec)
+ {
+ bfd_size_type amt = sizeof *p;
+ p = ((struct elf32_nios2_dyn_relocs *)
+ bfd_alloc (htab->root.dynobj, amt));
+ if (p == NULL)
+ return FALSE;
+ p->next = *head;
+ *head = p;
+ p->sec = sec;
+ p->count = 0;
+ p->pc_count = 0;
+ }
+
+ p->count += 1;
+
+ }
+ break;
+ }
+ }
+
+ return TRUE;
+}
+
+
+/* Implement elf_backend_gc_mark_hook:
+ Return the section that should be marked against GC for a given
+ relocation. */
+static asection *
+nios2_elf32_gc_mark_hook (asection *sec,
+ 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_NIOS2_GNU_VTINHERIT:
+ case R_NIOS2_GNU_VTENTRY:
+ return NULL;
+ }
+ return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
+}
+
+/* Implement elf_backend_gc_sweep_hook:
+ Update the got entry reference counts for the section being removed. */
+static bfd_boolean
+nios2_elf32_gc_sweep_hook (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;
+ bfd *dynobj;
+
+ if (info->relocatable)
+ return TRUE;
+
+ elf_section_data (sec)->local_dynrel = NULL;
+
+ dynobj = elf_hash_table (info)->dynobj;
+ if (dynobj == NULL)
+ return TRUE;
+
+ 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++)
+ {
+ unsigned long r_symndx;
+ struct elf_link_hash_entry *h = NULL;
+ int r_type;
+
+ r_symndx = ELF32_R_SYM (rel->r_info);
+ if (r_symndx >= symtab_hdr->sh_info)
+ {
+ 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;
+ }
+
+ r_type = ELF32_R_TYPE (rel->r_info);
+ switch (r_type)
+ {
+ case R_NIOS2_GOT16:
+ case R_NIOS2_GOT_LO:
+ case R_NIOS2_GOT_HA:
+ case R_NIOS2_CALL16:
+ case R_NIOS2_CALL_LO:
+ case R_NIOS2_CALL_HA:
+ if (h != NULL)
+ {
+ if (h->got.refcount > 0)
+ --h->got.refcount;
+ }
+ else if (local_got_refcounts != NULL)
+ {
+ if (local_got_refcounts[r_symndx] > 0)
+ --local_got_refcounts[r_symndx];
+ }
+ break;
+
+ case R_NIOS2_PCREL_LO:
+ case R_NIOS2_PCREL_HA:
+ case R_NIOS2_BFD_RELOC_32:
+ case R_NIOS2_CALL26:
+ case R_NIOS2_CALL26_NOAT:
+ if (h != NULL)
+ {
+ struct elf32_nios2_link_hash_entry *eh;
+ struct elf32_nios2_dyn_relocs **pp;
+ struct elf32_nios2_dyn_relocs *p;
+
+ eh = (struct elf32_nios2_link_hash_entry *) h;
+
+ if (h->plt.refcount > 0)
+ --h->plt.refcount;
+
+ if (r_type == R_NIOS2_PCREL_LO || r_type == R_NIOS2_PCREL_HA
+ || r_type == R_NIOS2_BFD_RELOC_32)
+ {
+ for (pp = &eh->dyn_relocs; (p = *pp) != NULL;
+ pp = &p->next)
+ if (p->sec == sec)
+ {
+ p->count -= 1;
+ if (p->count == 0)
+ *pp = p->next;
+ break;
+ }
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ return TRUE;
+}
+
+/* Implement elf_backend_finish_dynamic_symbols:
+ Finish up dynamic symbol handling. We set the contents of various
+ dynamic sections here. */
+static bfd_boolean
+nios2_elf32_finish_dynamic_symbol (bfd *output_bfd,
+ struct bfd_link_info *info,
+ struct elf_link_hash_entry *h,
+ Elf_Internal_Sym *sym)
+{
+ struct elf32_nios2_link_hash_table *htab;
+ struct elf32_nios2_link_hash_entry *eh
+ = (struct elf32_nios2_link_hash_entry *)h;
+ int use_plt;
+
+ htab = elf32_nios2_hash_table (info);
+
+ if (h->plt.offset != (bfd_vma) -1)
+ {
+ asection *splt;
+ asection *sgotplt;
+ asection *srela;
+ bfd_vma plt_index;
+ bfd_vma got_offset;
+ Elf_Internal_Rela rela;
+ bfd_byte *loc;
+ bfd_vma got_address;
+
+ /* This symbol has an entry in the procedure linkage table. Set
+ it up. */
+ BFD_ASSERT (h->dynindx != -1);
+ splt = htab->root.splt;
+ sgotplt = htab->root.sgotplt;
+ srela = htab->root.srelplt;
+ BFD_ASSERT (splt != NULL && sgotplt != NULL && srela != NULL);
+
+ /* Emit the PLT entry. */
+ if (info->shared)
+ {
+ nios2_elf32_install_data (splt, nios2_so_plt_entry, h->plt.offset,
+ 3);
+ plt_index = (h->plt.offset - 24) / 12;
+ got_offset = (plt_index + 3) * 4;
+ nios2_elf32_install_imm16 (splt, h->plt.offset,
+ hiadj(plt_index * 4));
+ nios2_elf32_install_imm16 (splt, h->plt.offset + 4,
+ (plt_index * 4) & 0xffff);
+ nios2_elf32_install_imm16 (splt, h->plt.offset + 8,
+ 0xfff4 - h->plt.offset);
+ got_address = (sgotplt->output_section->vma + sgotplt->output_offset
+ + got_offset);
+
+ /* Fill in the entry in the global offset table. There are no
+ res_n slots for a shared object PLT, instead the .got.plt entries
+ point to the PLT entries. */
+ bfd_put_32 (output_bfd,
+ splt->output_section->vma + splt->output_offset
+ + h->plt.offset, sgotplt->contents + got_offset);
+ }
+ else
+ {
+ plt_index = (h->plt.offset - 28 - htab->res_n_size) / 12;
+ got_offset = (plt_index + 3) * 4;
+
+ nios2_elf32_install_data (splt, nios2_plt_entry, h->plt.offset, 3);
+ got_address = (sgotplt->output_section->vma + sgotplt->output_offset
+ + got_offset);
+ nios2_elf32_install_imm16 (splt, h->plt.offset, hiadj(got_address));
+ nios2_elf32_install_imm16 (splt, h->plt.offset + 4,
+ got_address & 0xffff);
+
+ /* Fill in the entry in the global offset table. */
+ bfd_put_32 (output_bfd,
+ splt->output_section->vma + splt->output_offset
+ + plt_index * 4, sgotplt->contents + got_offset);
+ }
+
+ /* Fill in the entry in the .rela.plt section. */
+ rela.r_offset = got_address;
+ rela.r_info = ELF32_R_INFO (h->dynindx, R_NIOS2_JUMP_SLOT);
+ rela.r_addend = 0;
+ loc = srela->contents + plt_index * sizeof (Elf32_External_Rela);
+ bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
+
+ if (!h->def_regular)
+ {
+ /* Mark the symbol as undefined, rather than as defined in
+ the .plt section. Leave the value alone. */
+ sym->st_shndx = SHN_UNDEF;
+ /* If the symbol is weak, we do need to clear the value.
+ Otherwise, the PLT entry would provide a definition for
+ the symbol even if the symbol wasn't defined anywhere,
+ and so the symbol would never be NULL. */
+ if (!h->ref_regular_nonweak)
+ sym->st_value = 0;
+ }
+ }
+
+ use_plt = (eh->got_types_used == CALL_USED
+ && h->plt.offset != (bfd_vma) -1);
+
+ if (!use_plt && h->got.offset != (bfd_vma) -1
+ && (elf32_nios2_hash_entry (h)->tls_type & GOT_TLS_GD) == 0
+ && (elf32_nios2_hash_entry (h)->tls_type & GOT_TLS_IE) == 0)
+ {
+ asection *sgot;
+ asection *srela;
+ Elf_Internal_Rela rela;
+ bfd_byte *loc;
+ bfd_vma offset;
+
+ /* This symbol has an entry in the global offset table. Set it
+ up. */
+ sgot = htab->root.sgot;
+ srela = htab->root.srelgot;
+ BFD_ASSERT (sgot != NULL && srela != NULL);
+
+ offset = (h->got.offset & ~(bfd_vma) 1);
+ rela.r_offset = (sgot->output_section->vma
+ + sgot->output_offset + offset);
+
+ /* 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 && SYMBOL_REFERENCES_LOCAL (info, h))
+ {
+ rela.r_info = ELF32_R_INFO (0, R_NIOS2_RELATIVE);
+ rela.r_addend = bfd_get_signed_32 (output_bfd,
+ (sgot->contents + offset));
+ bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents + offset);
+ }
+ else
+ {
+ bfd_put_32 (output_bfd, (bfd_vma) 0,
+ sgot->contents + offset);
+ rela.r_info = ELF32_R_INFO (h->dynindx, R_NIOS2_GLOB_DAT);
+ rela.r_addend = 0;
+ }
+
+ loc = srela->contents;
+ loc += srela->reloc_count++ * sizeof (Elf32_External_Rela);
+ bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
+ }
+
+ if (use_plt && h->got.offset != (bfd_vma) -1)
+ {
+ bfd_vma offset = (h->got.offset & ~(bfd_vma) 1);
+ asection *sgot = htab->root.sgot;
+ asection *splt = htab->root.splt;
+ bfd_put_32 (output_bfd, (splt->output_section->vma + splt->output_offset
+ + h->plt.offset),
+ sgot->contents + offset);
+ }
+
+ if (h->needs_copy)
+ {
+ asection *s;
+ Elf_Internal_Rela rela;
+ bfd_byte *loc;
+
+ /* 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 = htab->srelbss;
+ 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_NIOS2_COPY);
+ rela.r_addend = 0;
+ loc = s->contents + s->reloc_count++ * sizeof (Elf32_External_Rela);
+ bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
+ }
+
+ /* Mark _DYNAMIC, _GLOBAL_OFFSET_TABLE_, and _gp_got as absolute. */
+ if (strcmp (h->root.root.string, "_DYNAMIC") == 0
+ || h == elf_hash_table (info)->hgot
+ || h == elf32_nios2_hash_table (info)->h_gp_got)
+ sym->st_shndx = SHN_ABS;
+
+ return TRUE;
+}
+
+/* Implement elf_backend_finish_dynamic_sections. */
+static bfd_boolean
+nios2_elf32_finish_dynamic_sections (bfd *output_bfd,
+ struct bfd_link_info *info)
+{
+ bfd *dynobj;
+ asection *sgotplt;
+ asection *sdyn;
+ struct elf32_nios2_link_hash_table *htab;
+
+ htab = elf32_nios2_hash_table (info);
+ dynobj = elf_hash_table (info)->dynobj;
+ sgotplt = htab->root.sgotplt;
+ BFD_ASSERT (sgotplt != NULL);
+ sdyn = bfd_get_linker_section (dynobj, ".dynamic");
+
+ if (elf_hash_table (info)->dynamic_sections_created)
+ {
+ asection *splt;
+ Elf32_External_Dyn *dyncon, *dynconend;
+
+ splt = htab->root.splt;
+ BFD_ASSERT (splt != NULL && sdyn != NULL);
+
+ dyncon = (Elf32_External_Dyn *) sdyn->contents;
+ dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->size);
+ for (; dyncon < dynconend; dyncon++)
+ {
+ Elf_Internal_Dyn dyn;
+ asection *s;
+
+ bfd_elf32_swap_dyn_in (dynobj, dyncon, &dyn);
+
+ switch (dyn.d_tag)
+ {
+ default:
+ break;
+
+ case DT_PLTGOT:
+ s = htab->root.sgot;
+ BFD_ASSERT (s != NULL);
+ dyn.d_un.d_ptr = s->output_section->vma;
+ bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
+ break;
+
+ case DT_JMPREL:
+ s = htab->root.srelplt;
+ BFD_ASSERT (s != NULL);
+ dyn.d_un.d_ptr = s->output_section->vma;
+ bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
+ break;
+
+ case DT_PLTRELSZ:
+ s = htab->root.srelplt;
+ BFD_ASSERT (s != NULL);
+ dyn.d_un.d_val = s->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 = htab->root.srelplt;
+ if (s != NULL)
+ dyn.d_un.d_val -= s->size;
+ bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
+ break;
+
+ case DT_NIOS2_GP:
+ s = htab->root.sgot;
+ BFD_ASSERT (s != NULL);
+ dyn.d_un.d_ptr = s->output_section->vma + 0x7ff0;
+ bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
+ break;
+ }
+ }
+
+ /* Fill in the first entry in the procedure linkage table. */
+ if (splt->size > 0)
+ {
+ bfd_vma got_address = (sgotplt->output_section->vma
+ + sgotplt->output_offset);
+ if (info->shared)
+ {
+ bfd_vma corrected = got_address - (splt->output_section->vma
+ + splt->output_offset + 4);
+ nios2_elf32_install_data (splt, nios2_so_plt0_entry, 0, 6);
+ nios2_elf32_install_imm16 (splt, 4, hiadj (corrected));
+ nios2_elf32_install_imm16 (splt, 12, (corrected & 0xffff) + 4);
+ nios2_elf32_install_imm16 (splt, 16, (corrected & 0xffff) + 8);
+ }
+ else
+ {
+ /* Divide by 4 here, not 3 because we already corrected for the
+ res_N branches. */
+ bfd_vma res_size = (splt->size - 28) / 4;
+ bfd_vma res_start = (splt->output_section->vma
+ + splt->output_offset);
+ bfd_vma res_offset;
+
+ for (res_offset = 0; res_offset < res_size; res_offset += 4)
+ bfd_put_32 (output_bfd,
+ 6 | ((res_size - (res_offset + 4)) << 6),
+ splt->contents + res_offset);
+
+ nios2_elf32_install_data (splt, nios2_plt0_entry, res_size, 7);
+ nios2_elf32_install_imm16 (splt, res_size, hiadj (res_start));
+ nios2_elf32_install_imm16 (splt, res_size + 4,
+ res_start & 0xffff);
+ nios2_elf32_install_imm16 (splt, res_size + 12,
+ hiadj (got_address));
+ nios2_elf32_install_imm16 (splt, res_size + 16,
+ (got_address & 0xffff) + 4);
+ nios2_elf32_install_imm16 (splt, res_size + 20,
+ (got_address & 0xffff) + 8);
+ }
+ }
+ }
+ /* Fill in the first three entries in the global offset table. */
+ if (sgotplt->size > 0)
+ {
+ if (sdyn == NULL)
+ bfd_put_32 (output_bfd, (bfd_vma) 0, sgotplt->contents);
+ else
+ bfd_put_32 (output_bfd,
+ sdyn->output_section->vma + sdyn->output_offset,
+ sgotplt->contents);
+ bfd_put_32 (output_bfd, (bfd_vma) 0, sgotplt->contents + 4);
+ bfd_put_32 (output_bfd, (bfd_vma) 0, sgotplt->contents + 8);
+ }
+
+ elf_section_data (sgotplt->output_section)->this_hdr.sh_entsize = 4;
+
+ return TRUE;
+}
+
+/* Implement elf_backend_adjust_dynamic_symbol:
+ 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 bfd_boolean
+nios2_elf32_adjust_dynamic_symbol (struct bfd_link_info *info,
+ struct elf_link_hash_entry *h)
+{
+ struct elf32_nios2_link_hash_table *htab;
+ bfd *dynobj;
+ asection *s;
+ unsigned align2;
+
+ htab = elf32_nios2_hash_table (info);
+ dynobj = elf_hash_table (info)->dynobj;
+
+ /* Make sure we know what is going on here. */
+ BFD_ASSERT (dynobj != NULL
+ && (h->needs_plt
+ || h->u.weakdef != NULL
+ || (h->def_dynamic
+ && h->ref_regular
+ && !h->def_regular)));
+
+ /* 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->needs_plt)
+ {
+ if (h->plt.refcount <= 0
+ || SYMBOL_CALLS_LOCAL (info, h)
+ || (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
+ && h->root.type == bfd_link_hash_undefweak))
+ {
+ /* This case can occur if we saw a PLT reloc in an input
+ file, but the symbol was never referred to by a dynamic
+ object, or if all references were garbage collected. In
+ such a case, we don't actually need to build a procedure
+ linkage table, and we can just do a PCREL reloc instead. */
+ h->plt.offset = (bfd_vma) -1;
+ h->needs_plt = 0;
+ }
+
+ 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->u.weakdef != NULL)
+ {
+ BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
+ || h->u.weakdef->root.type == bfd_link_hash_defweak);
+ h->root.u.def.section = h->u.weakdef->root.u.def.section;
+ h->root.u.def.value = h->u.weakdef->root.u.def.value;
+ return TRUE;
+ }
+
+ /* If there are no non-GOT references, we do not need a copy
+ relocation. */
+ if (!h->non_got_ref)
+ 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;
+
+ if (h->size == 0)
+ {
+ (*_bfd_error_handler) (_("dynamic variable `%s' is zero size"),
+ h->root.root.string);
+ 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 = htab->sdynbss;
+ BFD_ASSERT (s != NULL);
+
+ /* We must generate a R_NIOS2_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 = htab->srelbss;
+ BFD_ASSERT (srel != NULL);
+ srel->size += sizeof (Elf32_External_Rela);
+ h->needs_copy = 1;
+ }
+
+ align2 = bfd_log2 (h->size);
+ if (align2 > h->root.u.def.section->alignment_power)
+ align2 = h->root.u.def.section->alignment_power;
+
+ /* Align dynbss. */
+ s->size = BFD_ALIGN (s->size, (bfd_size_type)1 << align2);
+ if (align2 > bfd_get_section_alignment (dynobj, s)
+ && !bfd_set_section_alignment (dynobj, s, align2))
+ 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->size;
+
+ /* Increment the section size to make room for the symbol. */
+ s->size += h->size;
+
+ return TRUE;
+}
+
+/* Worker function for nios2_elf32_size_dynamic_sections. */
+static bfd_boolean
+adjust_dynrelocs (struct elf_link_hash_entry *h, PTR inf)
+{
+ struct bfd_link_info *info;
+ struct elf32_nios2_link_hash_table *htab;
+
+ if (h->root.type == bfd_link_hash_indirect)
+ return TRUE;
+
+ if (h->root.type == bfd_link_hash_warning)
+ /* When warning symbols are created, they **replace** the "real"
+ entry in the hash table, thus we never get to see the real
+ symbol in a hash traversal. So look at it now. */
+ h = (struct elf_link_hash_entry *) h->root.u.i.link;
+
+ info = (struct bfd_link_info *) inf;
+ htab = elf32_nios2_hash_table (info);
+
+ if (h->plt.offset != (bfd_vma)-1)
+ h->plt.offset += htab->res_n_size;
+ if (htab->root.splt == h->root.u.def.section)
+ h->root.u.def.value += htab->res_n_size;
+
+ return TRUE;
+}
+
+/* Another worker function for nios2_elf32_size_dynamic_sections.
+ Allocate space in .plt, .got and associated reloc sections for
+ dynamic relocs. */
+static bfd_boolean
+allocate_dynrelocs (struct elf_link_hash_entry *h, PTR inf)
+{
+ struct bfd_link_info *info;
+ struct elf32_nios2_link_hash_table *htab;
+ struct elf32_nios2_link_hash_entry *eh;
+ struct elf32_nios2_dyn_relocs *p;
+ int use_plt;
+
+ if (h->root.type == bfd_link_hash_indirect)
+ return TRUE;
+
+ if (h->root.type == bfd_link_hash_warning)
+ /* When warning symbols are created, they **replace** the "real"
+ entry in the hash table, thus we never get to see the real
+ symbol in a hash traversal. So look at it now. */
+ h = (struct elf_link_hash_entry *) h->root.u.i.link;
+
+ info = (struct bfd_link_info *) inf;
+ htab = elf32_nios2_hash_table (info);
+
+ if (htab->root.dynamic_sections_created
+ && h->plt.refcount > 0)
+ {
+ /* Make sure this symbol is output as a dynamic symbol.
+ Undefined weak syms won't yet be marked as dynamic. */
+ if (h->dynindx == -1
+ && !h->forced_local
+ && !bfd_elf_link_record_dynamic_symbol (info, h))
+ return FALSE;
+
+ if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, info->shared, h))
+ {
+ asection *s = htab->root.splt;
+
+ /* Allocate room for the header. */
+ if (s->size == 0)
+ {
+ if (info->shared)
+ s->size = 24;
+ else
+ s->size = 28;
+ }
+
+ h->plt.offset = s->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->def_regular)
+ {
+ h->root.u.def.section = s;
+ h->root.u.def.value = h->plt.offset;
+ }
+
+ /* Make room for this entry. */
+ s->size += 12;
+
+ /* We also need to make an entry in the .rela.plt section. */
+ htab->root.srelplt->size += sizeof (Elf32_External_Rela);
+
+ /* And the .got.plt section. */
+ htab->root.sgotplt->size += 4;
+ }
+ else
+ {
+ h->plt.offset = (bfd_vma) -1;
+ h->needs_plt = 0;
+ }
+ }
+ else
+ {
+ h->plt.offset = (bfd_vma) -1;
+ h->needs_plt = 0;
+ }
+
+ eh = (struct elf32_nios2_link_hash_entry *) h;
+ use_plt = (eh->got_types_used == CALL_USED
+ && h->plt.offset != (bfd_vma) -1);
+
+ if (h->got.refcount > 0)
+ {
+ asection *s;
+ bfd_boolean dyn;
+ int tls_type = eh->tls_type;
+ int indx;
+
+ /* Make sure this symbol is output as a dynamic symbol.
+ Undefined weak syms won't yet be marked as dynamic. */
+ if (h->dynindx == -1
+ && !h->forced_local
+ && !bfd_elf_link_record_dynamic_symbol (info, h))
+ return FALSE;
+
+ s = htab->root.sgot;
+ h->got.offset = s->size;
+
+ if (tls_type == GOT_UNKNOWN)
+ abort ();
+
+ if (tls_type == GOT_NORMAL)
+ /* Non-TLS symbols need one GOT slot. */
+ s->size += 4;
+ else
+ {
+ if (tls_type & GOT_TLS_GD)
+ /* R_NIOS2_TLS_GD16 needs 2 consecutive GOT slots. */
+ s->size += 8;
+ if (tls_type & GOT_TLS_IE)
+ /* R_NIOS2_TLS_IE16 needs one GOT slot. */
+ s->size += 4;
+ }
+
+ dyn = htab->root.dynamic_sections_created;
+
+ indx = 0;
+ if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h)
+ && (!info->shared
+ || !SYMBOL_REFERENCES_LOCAL (info, h)))
+ indx = h->dynindx;
+
+ if (tls_type != GOT_NORMAL
+ && (info->shared || indx != 0)
+ && (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
+ || h->root.type != bfd_link_hash_undefweak))
+ {
+ if (tls_type & GOT_TLS_IE)
+ htab->root.srelgot->size += sizeof (Elf32_External_Rela);
+
+ if (tls_type & GOT_TLS_GD)
+ htab->root.srelgot->size += sizeof (Elf32_External_Rela);
+
+ if ((tls_type & GOT_TLS_GD) && indx != 0)
+ htab->root.srelgot->size += sizeof (Elf32_External_Rela);
+ }
+ else if ((ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
+ || h->root.type != bfd_link_hash_undefweak)
+ && !use_plt
+ && (info->shared
+ || WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, 0, h)))
+ htab->root.srelgot->size += sizeof (Elf32_External_Rela);
+ }
+ else
+ h->got.offset = (bfd_vma) -1;
+
+ if (eh->dyn_relocs == NULL)
+ return TRUE;
+
+ /* In the shared -Bsymbolic case, discard space allocated for
+ dynamic pc-relative relocs against symbols which turn out to be
+ defined in regular objects. For the normal shared case, discard
+ space for pc-relative relocs that have become local due to symbol
+ visibility changes. */
+
+ if (info->shared)
+ {
+ if (h->def_regular
+ && (h->forced_local || info->symbolic))
+ {
+ struct elf32_nios2_dyn_relocs **pp;
+
+ for (pp = &eh->dyn_relocs; (p = *pp) != NULL; )
+ {
+ p->count -= p->pc_count;
+ p->pc_count = 0;
+ if (p->count == 0)
+ *pp = p->next;
+ else
+ pp = &p->next;
+ }
+ }
+
+ /* Also discard relocs on undefined weak syms with non-default
+ visibility. */
+ if (eh->dyn_relocs != NULL
+ && h->root.type == bfd_link_hash_undefweak)
+ {
+ if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
+ eh->dyn_relocs = NULL;
+
+ /* Make sure undefined weak symbols are output as a dynamic
+ symbol in PIEs. */
+ else if (h->dynindx == -1
+ && !h->forced_local
+ && !bfd_elf_link_record_dynamic_symbol (info, h))
+ return FALSE;
+ }
+ }
+ else
+ {
+ /* For the non-shared case, discard space for relocs against
+ symbols which turn out to need copy relocs or are not
+ dynamic. */
+
+ if (!h->non_got_ref
+ && ((h->def_dynamic && !h->def_regular)
+ || (htab->root.dynamic_sections_created
+ && (h->root.type == bfd_link_hash_undefweak
+ || h->root.type == bfd_link_hash_undefined))))
+ {
+ /* Make sure this symbol is output as a dynamic symbol.
+ Undefined weak syms won't yet be marked as dynamic. */
+ if (h->dynindx == -1
+ && !h->forced_local
+ && !bfd_elf_link_record_dynamic_symbol (info, h))
+ return FALSE;
+
+ /* If that succeeded, we know we'll be keeping all the
+ relocs. */
+ if (h->dynindx != -1)
+ goto keep;
+ }
+
+ eh->dyn_relocs = NULL;
+
+ keep: ;
+ }
+
+ /* Finally, allocate space. */
+ for (p = eh->dyn_relocs; p != NULL; p = p->next)
+ {
+ asection *sreloc = elf_section_data (p->sec)->sreloc;
+ sreloc->size += p->count * sizeof (Elf32_External_Rela);
+ }
+
+ return TRUE;
+}
+
+/* Implement elf_backend_size_dynamic_sections:
+ Set the sizes of the dynamic sections. */
+static bfd_boolean
+nios2_elf32_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
+ struct bfd_link_info *info)
+{
+ bfd *dynobj;
+ asection *s;
+ bfd_boolean plt;
+ bfd_boolean got;
+ bfd_boolean relocs;
+ bfd *ibfd;
+ struct elf32_nios2_link_hash_table *htab;
+
+ htab = elf32_nios2_hash_table (info);
+ dynobj = elf_hash_table (info)->dynobj;
+ BFD_ASSERT (dynobj != NULL);
+
+ htab->res_n_size = 0;
+ if (elf_hash_table (info)->dynamic_sections_created)
+ {
+ /* Set the contents of the .interp section to the interpreter. */
+ if (info->executable)
+ {
+ s = bfd_get_linker_section (dynobj, ".interp");
+ BFD_ASSERT (s != NULL);
+ s->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 = htab->root.srelgot;
+ if (s != NULL)
+ s->size = 0;
+ }
+
+ /* Set up .got offsets for local syms, and space for local dynamic
+ relocs. */
+ for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next)
+ {
+ bfd_signed_vma *local_got;
+ bfd_signed_vma *end_local_got;
+ char *local_tls_type;
+ bfd_size_type locsymcount;
+ Elf_Internal_Shdr *symtab_hdr;
+ asection *srel;
+
+ if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour)
+ continue;
+
+ for (s = ibfd->sections; s != NULL; s = s->next)
+ {
+ struct elf32_nios2_dyn_relocs *p;
+
+ for (p = elf_section_data (s)->local_dynrel; p != NULL; p = p->next)
+ {
+ if (!bfd_is_abs_section (p->sec)
+ && bfd_is_abs_section (p->sec->output_section))
+ {
+ /* Input section has been discarded, either because
+ it is a copy of a linkonce section or due to
+ linker script /DISCARD/, so we'll be discarding
+ the relocs too. */
+ }
+ else if (p->count != 0)
+ {
+ srel = elf_section_data (p->sec)->sreloc;
+ srel->size += p->count * sizeof (Elf32_External_Rela);
+ if ((p->sec->output_section->flags & SEC_READONLY) != 0)
+ info->flags |= DF_TEXTREL;
+ }
+ }
+ }
+
+ local_got = elf_local_got_refcounts (ibfd);
+ if (!local_got)
+ continue;
+
+ symtab_hdr = &elf_tdata (ibfd)->symtab_hdr;
+ locsymcount = symtab_hdr->sh_info;
+ end_local_got = local_got + locsymcount;
+ local_tls_type = elf32_nios2_local_got_tls_type (ibfd);
+ s = htab->root.sgot;
+ srel = htab->root.srelgot;
+ for (; local_got < end_local_got; ++local_got, ++local_tls_type)
+ {
+ if (*local_got > 0)
+ {
+ *local_got = s->size;
+ if (*local_tls_type & GOT_TLS_GD)
+ /* TLS_GD relocs need an 8-byte structure in the GOT. */
+ s->size += 8;
+ if (*local_tls_type & GOT_TLS_IE)
+ s->size += 4;
+ if (*local_tls_type == GOT_NORMAL)
+ s->size += 4;
+
+ if (info->shared || *local_tls_type == GOT_TLS_GD)
+ srel->size += sizeof (Elf32_External_Rela);
+ }
+ else
+ *local_got = (bfd_vma) -1;
+ }
+ }
+
+ if (htab->tls_ldm_got.refcount > 0)
+ {
+ /* Allocate two GOT entries and one dynamic relocation (if necessary)
+ for R_NIOS2_TLS_LDM16 relocations. */
+ htab->tls_ldm_got.offset = htab->root.sgot->size;
+ htab->root.sgot->size += 8;
+ if (info->shared)
+ htab->root.srelgot->size += sizeof (Elf32_External_Rela);
+ }
+ else
+ htab->tls_ldm_got.offset = -1;
+
+ /* Allocate global sym .plt and .got entries, and space for global
+ sym dynamic relocs. */
+ elf_link_hash_traverse (& htab->root, allocate_dynrelocs, info);
+
+ if (elf_hash_table (info)->dynamic_sections_created)
+ {
+ /* If the .got section is more than 0x8000 bytes, we add
+ 0x8000 to the value of _gp_got, so that 16-bit relocations
+ have a greater chance of working. */
+ if (htab->root.sgot->size >= 0x8000
+ && elf32_nios2_hash_table (info)->h_gp_got->root.u.def.value == 0)
+ elf32_nios2_hash_table (info)->h_gp_got->root.u.def.value = 0x8000;
+ }
+
+ /* The check_relocs and adjust_dynamic_symbol entry points have
+ determined the sizes of the various dynamic sections. Allocate
+ memory for them. */
+ plt = FALSE;
+ got = FALSE;
+ relocs = FALSE;
+ for (s = dynobj->sections; s != NULL; s = s->next)
+ {
+ const char *name;
+
+ 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);
+
+ if (strcmp (name, ".plt") == 0)
+ {
+ /* Remember whether there is a PLT. */
+ plt = s->size != 0;
+
+ /* Correct for the number of res_N branches. */
+ if (plt && !info->shared)
+ {
+ htab->res_n_size = (s->size-28) / 3;
+ s->size += htab->res_n_size;
+ }
+ }
+ else if (CONST_STRNEQ (name, ".rela"))
+ {
+ if (s->size != 0)
+ {
+ relocs = 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 (CONST_STRNEQ (name, ".got"))
+ got = s->size != 0;
+ else if (strcmp (name, ".dynbss") != 0)
+ /* It's not one of our sections, so don't allocate space. */
+ continue;
+
+ if (s->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. */
+ s->flags |= SEC_EXCLUDE;
+ continue;
+ }
+
+ if ((s->flags & SEC_HAS_CONTENTS) == 0)
+ continue;
+
+ /* Allocate memory for the section contents. */
+ /* FIXME: This should be a call to bfd_alloc not bfd_zalloc.
+ Unused entries should be reclaimed before the section's contents
+ are written out, but at the moment this does not happen. Thus in
+ order to prevent writing out garbage, we initialize the section's
+ contents to zero. */
+ s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->size);
+ if (s->contents == NULL)
+ return FALSE;
+ }
+
+ /* Adjust dynamic symbols that point to the plt to account for the
+ now-known number of resN slots. */
+ if (htab->res_n_size)
+ elf_link_hash_traverse (& htab->root, adjust_dynrelocs, info);
+
+ if (elf_hash_table (info)->dynamic_sections_created)
+ {
+ /* Add some entries to the .dynamic section. We fill in the
+ values later, in elf_nios2_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. */
+#define add_dynamic_entry(TAG, VAL) \
+ _bfd_elf_add_dynamic_entry (info, TAG, VAL)
+
+ if (!info->shared && !add_dynamic_entry (DT_DEBUG, 0))
+ return FALSE;
+
+ if (got && !add_dynamic_entry (DT_PLTGOT, 0))
+ return FALSE;
+
+ if (plt
+ && (!add_dynamic_entry (DT_PLTRELSZ, 0)
+ || !add_dynamic_entry (DT_PLTREL, DT_RELA)
+ || !add_dynamic_entry (DT_JMPREL, 0)))
+ return FALSE;
+
+ if (relocs
+ && (!add_dynamic_entry (DT_RELA, 0)
+ || !add_dynamic_entry (DT_RELASZ, 0)
+ || !add_dynamic_entry (DT_RELAENT, sizeof (Elf32_External_Rela))))
+ return FALSE;
+
+ if (!info->shared && !add_dynamic_entry (DT_NIOS2_GP, 0))
+ return FALSE;
+
+ if ((info->flags & DF_TEXTREL) != 0
+ && !add_dynamic_entry (DT_TEXTREL, 0))
+ return FALSE;
+ }
+#undef add_dynamic_entry
+
+ return TRUE;
+}
+
+/* Free the derived linker hash table. */
+static void
+nios2_elf32_link_hash_table_free (bfd *obfd)
+{
+ struct elf32_nios2_link_hash_table *htab
+ = (struct elf32_nios2_link_hash_table *) obfd->link.hash;
+
+ bfd_hash_table_free (&htab->bstab);
+ _bfd_elf_link_hash_table_free (obfd);
+}
+
+/* Implement bfd_elf32_bfd_link_hash_table_create. */
+static struct bfd_link_hash_table *
+nios2_elf32_link_hash_table_create (bfd *abfd)
+{
+ struct elf32_nios2_link_hash_table *ret;
+ bfd_size_type amt = sizeof (struct elf32_nios2_link_hash_table);
+
+ ret = bfd_zmalloc (amt);
+ if (ret == NULL)
+ return NULL;
+
+ if (!_bfd_elf_link_hash_table_init (&ret->root, abfd,
+ link_hash_newfunc,
+ sizeof (struct
+ elf32_nios2_link_hash_entry),
+ NIOS2_ELF_DATA))
+ {
+ free (ret);
+ return NULL;
+ }
+
+ /* Init the stub hash table too. */
+ if (!bfd_hash_table_init (&ret->bstab, stub_hash_newfunc,
+ sizeof (struct elf32_nios2_stub_hash_entry)))
+ {
+ _bfd_elf_link_hash_table_free (abfd);
+ return NULL;
+ }
+ ret->root.root.hash_table_free = nios2_elf32_link_hash_table_free;
+
+ return &ret->root.root;
+}
+
+/* Implement elf_backend_reloc_type_class. */
+static enum elf_reloc_type_class
+nios2_elf32_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ const asection *rel_sec ATTRIBUTE_UNUSED,
+ const Elf_Internal_Rela *rela)
+{
+ switch ((int) ELF32_R_TYPE (rela->r_info))
+ {
+ case R_NIOS2_RELATIVE:
+ return reloc_class_relative;
+ case R_NIOS2_JUMP_SLOT:
+ return reloc_class_plt;
+ case R_NIOS2_COPY:
+ return reloc_class_copy;
+ default:
+ return reloc_class_normal;
+ }
+}
+
+/* Return 1 if target is one of ours. */
+static bfd_boolean
+is_nios2_elf_target (const struct bfd_target *targ)
+{
+ return (targ == &nios2_elf32_le_vec
+ || targ == &nios2_elf32_be_vec);
+}
+
+/* Implement elf_backend_add_symbol_hook.
+ This hook is called by the linker when adding symbols from an object
+ file. We use it to put .comm items in .sbss, and not .bss. */
+static bfd_boolean
+nios2_elf_add_symbol_hook (bfd *abfd,
+ struct bfd_link_info *info,
+ Elf_Internal_Sym *sym,
+ const char **namep ATTRIBUTE_UNUSED,
+ flagword *flagsp ATTRIBUTE_UNUSED,
+ asection **secp,
+ bfd_vma *valp)
+{
+ bfd *dynobj;
+
+ if (sym->st_shndx == SHN_COMMON
+ && !info->relocatable
+ && sym->st_size <= elf_gp_size (abfd)
+ && is_nios2_elf_target (info->output_bfd->xvec))
+ {
+ /* Common symbols less than or equal to -G nn bytes are automatically
+ put into .sbss. */
+ struct elf32_nios2_link_hash_table *htab;
+
+ htab = elf32_nios2_hash_table (info);
+ if (htab->sbss == NULL)
+ {
+ flagword flags = SEC_IS_COMMON | SEC_LINKER_CREATED;
+
+ dynobj = elf_hash_table (info)->dynobj;
+ if (!dynobj)
+ dynobj = abfd;
+
+ htab->sbss = bfd_make_section_anyway_with_flags (dynobj, ".sbss",
+ flags);
+ if (htab->sbss == NULL)
+ return FALSE;
+ }
+
+ *secp = htab->sbss;
+ *valp = sym->st_size;
+ }
+
+ return TRUE;
+}
+
+/* Implement elf_backend_can_make_relative_eh_frame:
+ Decide whether to attempt to turn absptr or lsda encodings in
+ shared libraries into pcrel within the given input section. */
+static bfd_boolean
+nios2_elf32_can_make_relative_eh_frame (bfd *input_bfd ATTRIBUTE_UNUSED,
+ struct bfd_link_info *info
+ ATTRIBUTE_UNUSED,
+ asection *eh_frame_section
+ ATTRIBUTE_UNUSED)
+{
+ /* We can't use PC-relative encodings in the .eh_frame section. */
+ return FALSE;
+}
+
+/* Implement elf_backend_special_sections. */
+const struct bfd_elf_special_section elf32_nios2_special_sections[] =
+{
+ { STRING_COMMA_LEN (".sbss"), -2, SHT_NOBITS,
+ SHF_ALLOC + SHF_WRITE + SHF_NIOS2_GPREL },
+ { STRING_COMMA_LEN (".sdata"), -2, SHT_PROGBITS,
+ SHF_ALLOC + SHF_WRITE + SHF_NIOS2_GPREL },
+ { NULL, 0, 0, 0, 0 }
+};
+
+#define ELF_ARCH bfd_arch_nios2
+#define ELF_TARGET_ID NIOS2_ELF_DATA
+#define ELF_MACHINE_CODE EM_ALTERA_NIOS2
+
+/* The Nios II MMU uses a 4K page size. */
+
+#define ELF_MAXPAGESIZE 0x1000
+
+#define bfd_elf32_bfd_link_hash_table_create \
+ nios2_elf32_link_hash_table_create
+
+/* Relocation table lookup macros. */
+
+#define bfd_elf32_bfd_reloc_type_lookup nios2_elf32_bfd_reloc_type_lookup
+#define bfd_elf32_bfd_reloc_name_lookup nios2_elf32_bfd_reloc_name_lookup
+
+/* JUMP_TABLE_LINK macros. */
+
+/* elf_info_to_howto (using RELA relocations). */
+
+#define elf_info_to_howto nios2_elf32_info_to_howto
+
+/* elf backend functions. */
+
+#define elf_backend_can_gc_sections 1
+#define elf_backend_can_refcount 1
+#define elf_backend_plt_readonly 1
+#define elf_backend_want_got_plt 1
+#define elf_backend_rela_normal 1
+
+#define elf_backend_relocate_section nios2_elf32_relocate_section
+#define elf_backend_section_flags nios2_elf32_section_flags
+#define elf_backend_fake_sections nios2_elf32_fake_sections
+#define elf_backend_check_relocs nios2_elf32_check_relocs
+
+#define elf_backend_gc_mark_hook nios2_elf32_gc_mark_hook
+#define elf_backend_gc_sweep_hook nios2_elf32_gc_sweep_hook
+#define elf_backend_create_dynamic_sections \
+ nios2_elf32_create_dynamic_sections
+#define elf_backend_finish_dynamic_symbol nios2_elf32_finish_dynamic_symbol
+#define elf_backend_finish_dynamic_sections \
+ nios2_elf32_finish_dynamic_sections
+#define elf_backend_adjust_dynamic_symbol nios2_elf32_adjust_dynamic_symbol
+#define elf_backend_reloc_type_class nios2_elf32_reloc_type_class
+#define elf_backend_size_dynamic_sections nios2_elf32_size_dynamic_sections
+#define elf_backend_add_symbol_hook nios2_elf_add_symbol_hook
+#define elf_backend_copy_indirect_symbol nios2_elf32_copy_indirect_symbol
+
+#define elf_backend_grok_prstatus nios2_grok_prstatus
+#define elf_backend_grok_psinfo nios2_grok_psinfo
+
+#undef elf_backend_can_make_relative_eh_frame
+#define elf_backend_can_make_relative_eh_frame \
+ nios2_elf32_can_make_relative_eh_frame
+
+#define elf_backend_special_sections elf32_nios2_special_sections
+
+#define TARGET_LITTLE_SYM nios2_elf32_le_vec
+#define TARGET_LITTLE_NAME "elf32-littlenios2"
+#define TARGET_BIG_SYM nios2_elf32_be_vec
+#define TARGET_BIG_NAME "elf32-bignios2"
+
+#define elf_backend_got_header_size 12
+
+#include "elf32-target.h"
diff --git a/bfd/elf32-nios2.h b/bfd/elf32-nios2.h
new file mode 100644
index 0000000..1307802
--- /dev/null
+++ b/bfd/elf32-nios2.h
@@ -0,0 +1,38 @@
+/* Nios II support for 32-bit ELF
+ Copyright (C) 2013-2014 Free Software Foundation, Inc.
+ Contributed by Mentor Graphics
+
+ This file is part of BFD, the Binary File Descriptor library.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#ifndef _ELF32_NIOS2_H
+#define _ELF32_NIOS2_H
+
+extern int nios2_elf32_setup_section_lists
+ (bfd *, struct bfd_link_info *);
+
+extern void nios2_elf32_next_input_section
+ (struct bfd_link_info *, asection *);
+
+extern bfd_boolean nios2_elf32_size_stubs
+ (bfd *, bfd *, struct bfd_link_info *,
+ asection * (*) (const char *, asection *, bfd_boolean), void (*) (void));
+
+extern bfd_boolean nios2_elf32_build_stubs
+ (struct bfd_link_info *);
+
+#endif /* _ELF32_NIOS2_H */
diff --git a/bfd/elf32-or1k.c b/bfd/elf32-or1k.c
new file mode 100644
index 0000000..5cf29e1
--- /dev/null
+++ b/bfd/elf32-or1k.c
@@ -0,0 +1,2853 @@
+/* Or1k-specific support for 32-bit ELF.
+ Copyright 2001-2014 Free Software Foundation, Inc.
+ Contributed for OR32 by Johan Rydberg, jrydberg@opencores.org
+
+ PIC parts added by Stefan Kristiansson, stefan.kristiansson@saunalahti.fi,
+ largely based on elf32-m32r.c and elf32-microblaze.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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, see <http://www.gnu.org/licenses/>. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+#include "elf-bfd.h"
+#include "elf/or1k.h"
+#include "libiberty.h"
+
+#define PLT_ENTRY_SIZE 20
+
+#define PLT0_ENTRY_WORD0 0x19800000 /* l.movhi r12, 0 <- hi(.got+4) */
+#define PLT0_ENTRY_WORD1 0xa98c0000 /* l.ori r12, r12, 0 <- lo(.got+4) */
+#define PLT0_ENTRY_WORD2 0x85ec0004 /* l.lwz r15, 4(r12) <- *(.got+8)*/
+#define PLT0_ENTRY_WORD3 0x44007800 /* l.jr r15 */
+#define PLT0_ENTRY_WORD4 0x858c0000 /* l.lwz r12, 0(r12) */
+
+#define PLT0_PIC_ENTRY_WORD0 0x85900004 /* l.lwz r12, 4(r16) */
+#define PLT0_PIC_ENTRY_WORD1 0x85f00008 /* l.lwz r15, 8(r16) */
+#define PLT0_PIC_ENTRY_WORD2 0x44007800 /* l.jr r15 */
+#define PLT0_PIC_ENTRY_WORD3 0x15000000 /* l.nop */
+#define PLT0_PIC_ENTRY_WORD4 0x15000000 /* l.nop */
+
+#define PLT_ENTRY_WORD0 0x19800000 /* l.movhi r12, 0 <- hi(got idx addr) */
+#define PLT_ENTRY_WORD1 0xa98c0000 /* l.ori r12, r12, 0 <- lo(got idx addr) */
+#define PLT_ENTRY_WORD2 0x858c0000 /* l.lwz r12, 0(r12) */
+#define PLT_ENTRY_WORD3 0x44006000 /* l.jr r12 */
+#define PLT_ENTRY_WORD4 0xa9600000 /* l.ori r11, r0, 0 <- reloc offset */
+
+#define PLT_PIC_ENTRY_WORD0 0x85900000 /* l.lwz r12, 0(r16) <- index in got */
+#define PLT_PIC_ENTRY_WORD1 0xa9600000 /* l.ori r11, r0, 0 <- reloc offset */
+#define PLT_PIC_ENTRY_WORD2 0x44006000 /* l.jr r12 */
+#define PLT_PIC_ENTRY_WORD3 0x15000000 /* l.nop */
+#define PLT_PIC_ENTRY_WORD4 0x15000000 /* l.nop */
+
+#define ELF_DYNAMIC_INTERPRETER "/usr/lib/ld.so.1"
+
+static reloc_howto_type or1k_elf_howto_table[] =
+{
+ /* This reloc does nothing. */
+ HOWTO (R_OR1K_NONE, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_OR1K_NONE", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_OR1K_32,
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_unsigned, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_OR1K_32", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_OR1K_16,
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_unsigned, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_OR1K_16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_OR1K_8,
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 8, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_unsigned, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_OR1K_8", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_OR1K_LO_16_IN_INSN, /* 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_OR1K_LO_16_IN_INSN", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_OR1K_HI_16_IN_INSN, /* type */
+ 16, /* 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_OR1K_HI_16_IN_INSN", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A PC relative 26 bit relocation, right shifted by 2. */
+ HOWTO (R_OR1K_INSN_REL_26, /* 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_OR1K_INSN_REL_26", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x03ffffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* GNU extension to record C++ vtable hierarchy. */
+ HOWTO (R_OR1K_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_OR1K_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_OR1K_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_OR1K_GNU_VTENTRY", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_OR1K_32_PCREL,
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_OR1K_32_PCREL", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_OR1K_16_PCREL,
+ 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_OR1K_16_PCREL", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_OR1K_8_PCREL,
+ 0, /* rightshift */
+ 0, /* 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_OR1K_8_PCREL", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_OR1K_GOTPC_HI16, /* Type. */
+ 16, /* Rightshift. */
+ 2, /* Size (0 = byte, 1 = short, 2 = long). */
+ 16, /* Bitsize. */
+ TRUE, /* PC_relative. */
+ 0, /* Bitpos. */
+ complain_overflow_dont, /* Complain on overflow. */
+ bfd_elf_generic_reloc, /* Special Function. */
+ "R_OR1K_GOTPC_HI16", /* Name. */
+ FALSE, /* Partial Inplace. */
+ 0, /* Source Mask. */
+ 0xffff, /* Dest Mask. */
+ TRUE), /* PC relative offset? */
+
+ HOWTO (R_OR1K_GOTPC_LO16, /* Type. */
+ 0, /* Rightshift. */
+ 2, /* Size (0 = byte, 1 = short, 2 = long). */
+ 16, /* Bitsize. */
+ TRUE, /* PC_relative. */
+ 0, /* Bitpos. */
+ complain_overflow_dont, /* Complain on overflow. */
+ bfd_elf_generic_reloc, /* Special Function. */
+ "R_OR1K_GOTPC_LO16", /* Name. */
+ FALSE, /* Partial Inplace. */
+ 0, /* Source Mask. */
+ 0xffff, /* Dest Mask. */
+ TRUE), /* PC relative offset? */
+
+ HOWTO (R_OR1K_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_OR1K_GOT16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A 26 bit PLT relocation. Shifted by 2. */
+ HOWTO (R_OR1K_PLT26, /* Type. */
+ 2, /* Rightshift. */
+ 2, /* Size (0 = byte, 1 = short, 2 = long). */
+ 26, /* Bitsize. */
+ TRUE, /* PC_relative. */
+ 0, /* Bitpos. */
+ complain_overflow_dont, /* Complain on overflow. */
+ bfd_elf_generic_reloc,/* Special Function. */
+ "R_OR1K_PLT26", /* Name. */
+ FALSE, /* Partial Inplace. */
+ 0, /* Source Mask. */
+ 0x03ffffff, /* Dest Mask. */
+ TRUE), /* PC relative offset? */
+
+ HOWTO (R_OR1K_GOTOFF_HI16, /* type */
+ 16, /* 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_OR1K_GOTOFF_HI16", /* name */
+ FALSE, /* partial_inplace */
+ 0x0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_OR1K_GOTOFF_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_OR1K_GOTOFF_LO16", /* name */
+ FALSE, /* partial_inplace */
+ 0x0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_OR1K_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_OR1K_COPY", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_OR1K_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_OR1K_GLOB_DAT", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_OR1K_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_OR1K_JMP_SLOT", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_OR1K_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_OR1K_RELATIVE", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_OR1K_TLS_GD_HI16, /* type */
+ 16, /* 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_OR1K_TLS_GD_HI16", /* name */
+ FALSE, /* partial_inplace */
+ 0x0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_OR1K_TLS_GD_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_OR1K_TLS_GD_LO16", /* name */
+ FALSE, /* partial_inplace */
+ 0x0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_OR1K_TLS_LDM_HI16, /* type */
+ 16, /* 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_OR1K_TLS_LDM_HI16", /* name */
+ FALSE, /* partial_inplace */
+ 0x0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_OR1K_TLS_LDM_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_OR1K_TLS_LDM_LO16", /* name */
+ FALSE, /* partial_inplace */
+ 0x0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_OR1K_TLS_LDO_HI16, /* type */
+ 16, /* 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_OR1K_TLS_LDO_HI16", /* name */
+ FALSE, /* partial_inplace */
+ 0x0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_OR1K_TLS_LDO_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_OR1K_TLS_LDO_LO16", /* name */
+ FALSE, /* partial_inplace */
+ 0x0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_OR1K_TLS_IE_HI16, /* type */
+ 16, /* 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_OR1K_TLS_IE_HI16", /* name */
+ FALSE, /* partial_inplace */
+ 0x0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_OR1K_TLS_IE_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_OR1K_TLS_IE_LO16", /* name */
+ FALSE, /* partial_inplace */
+ 0x0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_OR1K_TLS_LE_HI16, /* type */
+ 16, /* 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_OR1K_TLS_LE_HI16", /* name */
+ FALSE, /* partial_inplace */
+ 0x0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_OR1K_TLS_LE_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_OR1K_TLS_LE_LO16", /* name */
+ FALSE, /* partial_inplace */
+ 0x0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+};
+
+/* Map BFD reloc types to Or1k ELF reloc types. */
+
+struct or1k_reloc_map
+{
+ bfd_reloc_code_real_type bfd_reloc_val;
+ unsigned int or1k_reloc_val;
+};
+
+static const struct or1k_reloc_map or1k_reloc_map[] =
+{
+ { BFD_RELOC_NONE, R_OR1K_NONE },
+ { BFD_RELOC_32, R_OR1K_32 },
+ { BFD_RELOC_16, R_OR1K_16 },
+ { BFD_RELOC_8, R_OR1K_8 },
+ { BFD_RELOC_LO16, R_OR1K_LO_16_IN_INSN },
+ { BFD_RELOC_HI16, R_OR1K_HI_16_IN_INSN },
+ { BFD_RELOC_OR1K_REL_26, R_OR1K_INSN_REL_26 },
+ { BFD_RELOC_VTABLE_ENTRY, R_OR1K_GNU_VTENTRY },
+ { BFD_RELOC_VTABLE_INHERIT, R_OR1K_GNU_VTINHERIT },
+ { BFD_RELOC_32_PCREL, R_OR1K_32_PCREL },
+ { BFD_RELOC_16_PCREL, R_OR1K_16_PCREL },
+ { BFD_RELOC_8_PCREL, R_OR1K_8_PCREL },
+ { BFD_RELOC_OR1K_GOTPC_HI16, R_OR1K_GOTPC_HI16 },
+ { BFD_RELOC_OR1K_GOTPC_LO16, R_OR1K_GOTPC_LO16 },
+ { BFD_RELOC_OR1K_GOT16, R_OR1K_GOT16 },
+ { BFD_RELOC_OR1K_PLT26, R_OR1K_PLT26 },
+ { BFD_RELOC_OR1K_GOTOFF_HI16, R_OR1K_GOTOFF_HI16 },
+ { BFD_RELOC_OR1K_GOTOFF_LO16, R_OR1K_GOTOFF_LO16 },
+ { BFD_RELOC_OR1K_GLOB_DAT, R_OR1K_GLOB_DAT },
+ { BFD_RELOC_OR1K_COPY, R_OR1K_COPY },
+ { BFD_RELOC_OR1K_JMP_SLOT, R_OR1K_JMP_SLOT },
+ { BFD_RELOC_OR1K_RELATIVE, R_OR1K_RELATIVE },
+ { BFD_RELOC_OR1K_TLS_GD_HI16, R_OR1K_TLS_GD_HI16 },
+ { BFD_RELOC_OR1K_TLS_GD_LO16, R_OR1K_TLS_GD_LO16 },
+ { BFD_RELOC_OR1K_TLS_LDM_HI16, R_OR1K_TLS_LDM_HI16 },
+ { BFD_RELOC_OR1K_TLS_LDM_LO16, R_OR1K_TLS_LDM_LO16 },
+ { BFD_RELOC_OR1K_TLS_LDO_HI16, R_OR1K_TLS_LDO_HI16 },
+ { BFD_RELOC_OR1K_TLS_LDO_LO16, R_OR1K_TLS_LDO_LO16 },
+ { BFD_RELOC_OR1K_TLS_IE_HI16, R_OR1K_TLS_IE_HI16 },
+ { BFD_RELOC_OR1K_TLS_IE_LO16, R_OR1K_TLS_IE_LO16 },
+ { BFD_RELOC_OR1K_TLS_LE_HI16, R_OR1K_TLS_LE_HI16 },
+ { BFD_RELOC_OR1K_TLS_LE_LO16, R_OR1K_TLS_LE_LO16 },
+};
+
+/* The linker needs to keep track of the number of relocs that it
+ decides to copy as dynamic relocs in check_relocs for each symbol.
+ This is so that it can later discard them if they are found to be
+ unnecessary. We store the information in a field extending the
+ regular ELF linker hash table. */
+
+struct elf_or1k_dyn_relocs
+{
+ struct elf_or1k_dyn_relocs *next;
+
+ /* The input section of the reloc. */
+ asection *sec;
+
+ /* Total number of relocs copied for the input section. */
+ bfd_size_type count;
+
+ /* Number of pc-relative relocs copied for the input section. */
+ bfd_size_type pc_count;
+};
+
+#define TLS_UNKNOWN 0
+#define TLS_NONE 1
+#define TLS_GD 2
+#define TLS_LD 3
+#define TLS_IE 4
+#define TLS_LE 5
+
+/* ELF linker hash entry. */
+struct elf_or1k_link_hash_entry
+{
+ struct elf_link_hash_entry root;
+
+ /* Track dynamic relocs copied for this symbol. */
+ struct elf_or1k_dyn_relocs *dyn_relocs;
+
+ /* Track type of TLS access. */
+ unsigned char tls_type;
+};
+
+/* ELF object data. */
+struct elf_or1k_obj_tdata
+{
+ struct elf_obj_tdata root;
+
+ /* tls_type for each local got entry. */
+ unsigned char *local_tls_type;
+};
+
+#define elf_or1k_tdata(abfd) \
+ ((struct elf_or1k_obj_tdata *) (abfd)->tdata.any)
+
+#define elf_or1k_local_tls_type(abfd) \
+ (elf_or1k_tdata (abfd)->local_tls_type)
+
+/* ELF linker hash table. */
+struct elf_or1k_link_hash_table
+{
+ struct elf_link_hash_table root;
+
+ /* Short-cuts to get to dynamic linker sections. */
+ asection *sgot;
+ asection *sgotplt;
+ asection *srelgot;
+ asection *splt;
+ asection *srelplt;
+ asection *sdynbss;
+ asection *srelbss;
+
+ /* Small local sym to section mapping cache. */
+ struct sym_cache sym_sec;
+};
+
+/* Get the ELF linker hash table from a link_info structure. */
+#define or1k_elf_hash_table(p) \
+ (elf_hash_table_id ((struct elf_link_hash_table *) ((p)->hash)) \
+ == OR1K_ELF_DATA ? ((struct elf_or1k_link_hash_table *) ((p)->hash)) : NULL)
+
+static bfd_boolean
+elf_or1k_mkobject (bfd *abfd)
+{
+ return bfd_elf_allocate_object (abfd, sizeof (struct elf_or1k_obj_tdata),
+ OR1K_ELF_DATA);
+}
+
+/* Create an entry in an or1k ELF linker hash table. */
+
+static struct bfd_hash_entry *
+or1k_elf_link_hash_newfunc (struct bfd_hash_entry *entry,
+ struct bfd_hash_table *table,
+ const char *string)
+{
+ struct elf_or1k_link_hash_entry *ret =
+ (struct elf_or1k_link_hash_entry *) entry;
+
+ /* Allocate the structure if it has not already been allocated by a
+ subclass. */
+ if (ret == NULL)
+ ret = bfd_hash_allocate (table,
+ sizeof (struct elf_or1k_link_hash_entry));
+ if (ret == NULL)
+ return NULL;
+
+ /* Call the allocation method of the superclass. */
+ ret = ((struct elf_or1k_link_hash_entry *)
+ _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry *) ret,
+ table, string));
+ if (ret != NULL)
+ {
+ struct elf_or1k_link_hash_entry *eh;
+
+ eh = (struct elf_or1k_link_hash_entry *) ret;
+ eh->dyn_relocs = NULL;
+ eh->tls_type = TLS_UNKNOWN;
+ }
+
+ return (struct bfd_hash_entry *) ret;
+}
+
+/* Create an or1k ELF linker hash table. */
+
+static struct bfd_link_hash_table *
+or1k_elf_link_hash_table_create (bfd *abfd)
+{
+ struct elf_or1k_link_hash_table *ret;
+ bfd_size_type amt = sizeof (struct elf_or1k_link_hash_table);
+
+ ret = bfd_zmalloc (amt);
+ if (ret == NULL)
+ return NULL;
+
+ if (!_bfd_elf_link_hash_table_init (&ret->root, abfd,
+ or1k_elf_link_hash_newfunc,
+ sizeof (struct elf_or1k_link_hash_entry),
+ OR1K_ELF_DATA))
+ {
+ free (ret);
+ return NULL;
+ }
+
+ return &ret->root.root;
+}
+
+static reloc_howto_type *
+or1k_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED,
+ bfd_reloc_code_real_type code)
+{
+ unsigned int i;
+
+ for (i = ARRAY_SIZE (or1k_reloc_map); --i;)
+ if (or1k_reloc_map[i].bfd_reloc_val == code)
+ return & or1k_elf_howto_table[or1k_reloc_map[i].or1k_reloc_val];
+
+ return NULL;
+}
+
+static reloc_howto_type *
+or1k_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ const char *r_name)
+{
+ unsigned int i;
+
+ for (i = 0;
+ i < (sizeof (or1k_elf_howto_table)
+ / sizeof (or1k_elf_howto_table[0]));
+ i++)
+ if (or1k_elf_howto_table[i].name != NULL
+ && strcasecmp (or1k_elf_howto_table[i].name, r_name) == 0)
+ return &or1k_elf_howto_table[i];
+
+ return NULL;
+}
+
+/* Set the howto pointer for an Or1k ELF reloc. */
+
+static void
+or1k_info_to_howto_rela (bfd * abfd ATTRIBUTE_UNUSED,
+ arelent * cache_ptr,
+ Elf_Internal_Rela * dst)
+{
+ unsigned int r_type;
+
+ r_type = ELF32_R_TYPE (dst->r_info);
+ BFD_ASSERT (r_type < (unsigned int) R_OR1K_max);
+ cache_ptr->howto = & or1k_elf_howto_table[r_type];
+}
+
+
+/* Return the relocation value for @tpoff relocations.. */
+static bfd_vma
+tpoff (struct bfd_link_info *info, bfd_vma address)
+{
+ /* If tls_sec is NULL, we should have signalled an error already. */
+ if (elf_hash_table (info)->tls_sec == NULL)
+ return 0;
+
+ /* The thread pointer on or1k stores the address after the TCB where
+ the data is, just compute the difference. No need to compensate
+ for the size of TCB. */
+ return (address - elf_hash_table (info)->tls_sec->vma);
+}
+
+/* Relocate an Or1k ELF section.
+
+ 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 relocatable
+ 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 relocatable 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 bfd_boolean
+or1k_elf_relocate_section (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;
+ struct elf_or1k_link_hash_table *htab = or1k_elf_hash_table (info);
+ bfd *dynobj;
+ asection *sreloc;
+ bfd_vma *local_got_offsets;
+ asection *sgot;
+
+ if (htab == NULL)
+ return FALSE;
+
+ dynobj = htab->root.dynobj;
+ local_got_offsets = elf_local_got_offsets (input_bfd);
+
+ sreloc = elf_section_data (input_section)->sreloc;
+
+ sgot = htab->sgot;
+
+ 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);
+ r_symndx = ELF32_R_SYM (rel->r_info);
+
+ if (r_type == R_OR1K_GNU_VTINHERIT
+ || r_type == R_OR1K_GNU_VTENTRY)
+ continue;
+
+ if (r_type < 0 || r_type >= (int) R_OR1K_max)
+ {
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+
+ howto = or1k_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 = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
+
+ 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;
+ }
+ else
+ {
+ bfd_boolean unresolved_reloc, warned, ignored;
+
+ RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
+ r_symndx, symtab_hdr, sym_hashes,
+ h, sec, relocation,
+ unresolved_reloc, warned, ignored);
+ }
+
+ if (sec != NULL && discarded_section (sec))
+ RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+ rel, 1, relend, howto, 0, contents);
+
+ if (info->relocatable)
+ continue;
+
+ switch (howto->type)
+ {
+ case R_OR1K_PLT26:
+ {
+ if (htab->splt != NULL && h != NULL
+ && h->plt.offset != (bfd_vma) -1)
+ {
+ relocation = (htab->splt->output_section->vma
+ + htab->splt->output_offset
+ + h->plt.offset);
+ }
+ break;
+ }
+
+ case R_OR1K_GOT16:
+ /* Relocation is to the entry for this symbol in the global
+ offset table. */
+ BFD_ASSERT (sgot != NULL);
+ if (h != NULL)
+ {
+ bfd_boolean dyn;
+ bfd_vma off;
+
+ off = h->got.offset;
+ BFD_ASSERT (off != (bfd_vma) -1);
+
+ dyn = htab->root.dynamic_sections_created;
+ if (! WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h)
+ || (info->shared
+ && SYMBOL_REFERENCES_LOCAL (info, h)))
+ {
+ /* 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
+ {
+ /* Write entry in GOT. */
+ bfd_put_32 (output_bfd, relocation,
+ sgot->contents + off);
+ /* Mark GOT entry as having been written. */
+ h->got.offset |= 1;
+ }
+ }
+
+ relocation = sgot->output_offset + off;
+ }
+ else
+ {
+ bfd_vma off;
+ bfd_byte *loc;
+
+ BFD_ASSERT (local_got_offsets != NULL
+ && local_got_offsets[r_symndx] != (bfd_vma) -1);
+
+ /* Get offset into GOT table. */
+ 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
+ {
+ /* Write entry in GOT. */
+ bfd_put_32 (output_bfd, relocation, sgot->contents + off);
+ if (info->shared)
+ {
+ asection *srelgot;
+ Elf_Internal_Rela outrel;
+
+ /* We need to generate a R_OR1K_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_OR1K_RELATIVE);
+ outrel.r_addend = relocation;
+ loc = srelgot->contents;
+ loc += srelgot->reloc_count * sizeof (Elf32_External_Rela);
+ bfd_elf32_swap_reloca_out (output_bfd, &outrel,loc);
+ ++srelgot->reloc_count;
+ }
+
+ local_got_offsets[r_symndx] |= 1;
+ }
+ relocation = sgot->output_offset + off;
+ }
+
+ /* Addend should be zero. */
+ if (rel->r_addend != 0)
+ (*_bfd_error_handler)
+ (_("internal error: addend should be zero for R_OR1K_GOT16"));
+
+ break;
+
+ case R_OR1K_GOTOFF_LO16:
+ case R_OR1K_GOTOFF_HI16:
+ /* Relocation is offset from GOT. */
+ BFD_ASSERT (sgot != NULL);
+ relocation -= sgot->output_section->vma;
+ break;
+
+ case R_OR1K_INSN_REL_26:
+ case R_OR1K_HI_16_IN_INSN:
+ case R_OR1K_LO_16_IN_INSN:
+ case R_OR1K_32:
+ /* R_OR1K_16? */
+ {
+ /* r_symndx will be STN_UNDEF (zero) only for relocs against symbols
+ from removed linkonce sections, or sections discarded by
+ a linker script. */
+ if (r_symndx == STN_UNDEF
+ || (input_section->flags & SEC_ALLOC) == 0)
+ break;
+
+ if ((info->shared
+ && (h == NULL
+ || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
+ || h->root.type != bfd_link_hash_undefweak)
+ && (howto->type != R_OR1K_INSN_REL_26
+ || !SYMBOL_CALLS_LOCAL (info, h)))
+ || (!info->shared
+ && h != NULL
+ && h->dynindx != -1
+ && !h->non_got_ref
+ && ((h->def_dynamic
+ && !h->def_regular)
+ || h->root.type == bfd_link_hash_undefweak
+ || h->root.type == bfd_link_hash_undefined)))
+ {
+ Elf_Internal_Rela outrel;
+ bfd_byte *loc;
+ bfd_boolean skip;
+
+ /* When generating a shared object, these relocations
+ are copied into the output file to be resolved at run
+ time. */
+
+ BFD_ASSERT (sreloc != NULL);
+
+ skip = FALSE;
+
+ outrel.r_offset =
+ _bfd_elf_section_offset (output_bfd, info, input_section,
+ rel->r_offset);
+ if (outrel.r_offset == (bfd_vma) -1)
+ skip = TRUE;
+ else if (outrel.r_offset == (bfd_vma) -2)
+ skip = TRUE;
+ 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->def_regular))
+ {
+ 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_OR1K_32)
+ {
+ outrel.r_info = ELF32_R_INFO (0, R_OR1K_RELATIVE);
+ outrel.r_addend = relocation + rel->r_addend;
+ }
+ else
+ {
+ BFD_FAIL ();
+ (*_bfd_error_handler)
+ (_("%B: probably compiled without -fPIC?"),
+ input_bfd);
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+ }
+
+ loc = sreloc->contents;
+ loc += sreloc->reloc_count++ * sizeof (Elf32_External_Rela);
+ bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
+ break;
+ }
+ break;
+ }
+
+ case R_OR1K_TLS_LDM_HI16:
+ case R_OR1K_TLS_LDM_LO16:
+ case R_OR1K_TLS_LDO_HI16:
+ case R_OR1K_TLS_LDO_LO16:
+ /* TODO: implement support for local dynamic. */
+ BFD_FAIL ();
+ (*_bfd_error_handler)
+ (_("%B: support for local dynamic not implemented"),
+ input_bfd);
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+
+
+ case R_OR1K_TLS_GD_HI16:
+ case R_OR1K_TLS_GD_LO16:
+ case R_OR1K_TLS_IE_HI16:
+ case R_OR1K_TLS_IE_LO16:
+ {
+ bfd_vma gotoff;
+ Elf_Internal_Rela rela;
+ bfd_byte *loc;
+ int dynamic;
+
+ sreloc = bfd_get_section_by_name (dynobj, ".rela.got");
+
+ /* Mark as TLS related GOT entry by setting
+ bit 2 as well as bit 1. */
+ if (h != NULL)
+ {
+ gotoff = h->got.offset;
+ h->got.offset |= 3;
+ }
+ else
+ {
+ gotoff = local_got_offsets[r_symndx];
+ local_got_offsets[r_symndx] |= 3;
+ }
+
+ /* Only process the relocation once. */
+ if (gotoff & 1)
+ {
+ relocation = sgot->output_offset + (gotoff & ~3);
+ break;
+ }
+
+ BFD_ASSERT (elf_hash_table (info)->hgot == NULL
+ || elf_hash_table (info)->hgot->root.u.def.value == 0);
+
+ /* Dynamic entries will require relocations. if we do not need
+ them we will just use the default R_OR1K_NONE and
+ not set anything. */
+ dynamic = info->shared
+ || (sec && (sec->flags & SEC_ALLOC) != 0
+ && h != NULL
+ && (h->root.type == bfd_link_hash_defweak || !h->def_regular));
+
+ /* Shared GD. */
+ if (dynamic && (howto->type == R_OR1K_TLS_GD_HI16
+ || howto->type == R_OR1K_TLS_GD_LO16))
+ {
+ int i;
+
+ /* Add DTPMOD and DTPOFF GOT and rela entries. */
+ for (i = 0; i < 2; ++i)
+ {
+ rela.r_offset = sgot->output_section->vma +
+ sgot->output_offset + gotoff + i*4;
+ if (h != NULL && h->dynindx != -1)
+ {
+ rela.r_info = ELF32_R_INFO (h->dynindx,
+ (i == 0 ? R_OR1K_TLS_DTPMOD : R_OR1K_TLS_DTPOFF));
+ rela.r_addend = 0;
+ }
+ else
+ {
+ rela.r_info = ELF32_R_INFO (0,
+ (i == 0 ? R_OR1K_TLS_DTPMOD : R_OR1K_TLS_DTPOFF));
+ rela.r_addend = tpoff (info, relocation);
+ }
+
+ loc = sreloc->contents;
+ loc += sreloc->reloc_count++ *
+ sizeof (Elf32_External_Rela);
+
+ bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
+ bfd_put_32 (output_bfd, 0, sgot->contents + gotoff + i*4);
+ }
+ }
+ /* Static GD. */
+ else if (howto->type == R_OR1K_TLS_GD_HI16
+ || howto->type == R_OR1K_TLS_GD_LO16)
+ {
+ bfd_put_32 (output_bfd, 1, sgot->contents + gotoff);
+ bfd_put_32 (output_bfd, tpoff (info, relocation),
+ sgot->contents + gotoff + 4);
+ }
+ /* Shared IE. */
+ else if (dynamic)
+ {
+ /* Add TPOFF GOT and rela entries. */
+ rela.r_offset = sgot->output_section->vma +
+ sgot->output_offset + gotoff;
+ if (h != NULL && h->dynindx != -1)
+ {
+ rela.r_info = ELF32_R_INFO (h->dynindx, R_OR1K_TLS_TPOFF);
+ rela.r_addend = 0;
+ }
+ else
+ {
+ rela.r_info = ELF32_R_INFO (0, R_OR1K_TLS_TPOFF);
+ rela.r_addend = tpoff (info, relocation);
+ }
+
+ loc = sreloc->contents;
+ loc += sreloc->reloc_count++ * sizeof (Elf32_External_Rela);
+
+ bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
+ bfd_put_32 (output_bfd, 0, sgot->contents + gotoff);
+ }
+ /* Static IE. */
+ else
+ {
+ bfd_put_32 (output_bfd, tpoff (info, relocation),
+ sgot->contents + gotoff);
+ }
+ relocation = sgot->output_offset + gotoff;
+ break;
+ }
+ case R_OR1K_TLS_LE_HI16:
+ case R_OR1K_TLS_LE_LO16:
+
+ /* Relocation is offset from TP. */
+ relocation = tpoff (info, relocation);
+ break;
+
+ case R_OR1K_TLS_DTPMOD:
+ case R_OR1K_TLS_DTPOFF:
+ case R_OR1K_TLS_TPOFF:
+ /* These are resolved dynamically on load and shouldn't
+ be used as linker input. */
+ BFD_FAIL ();
+ (*_bfd_error_handler)
+ (_("%B: will not resolve runtime TLS relocation"),
+ input_bfd);
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+
+ 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)
+ {
+ const char *msg = NULL;
+
+ switch (r)
+ {
+ case bfd_reloc_overflow:
+ r = info->callbacks->reloc_overflow
+ (info, (h ? &h->root : NULL), 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, TRUE);
+ 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 *
+or1k_elf_gc_mark_hook (asection *sec,
+ 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_OR1K_GNU_VTINHERIT:
+ case R_OR1K_GNU_VTENTRY:
+ return NULL;
+ }
+
+ return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
+}
+
+static bfd_boolean
+or1k_elf_gc_sweep_hook (bfd *abfd,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ asection *sec,
+ const Elf_Internal_Rela *relocs ATTRIBUTE_UNUSED)
+{
+ /* Update the got entry reference counts for the section being removed. */
+ Elf_Internal_Shdr *symtab_hdr;
+ struct elf_link_hash_entry **sym_hashes;
+ bfd_signed_vma *local_got_refcounts;
+ const Elf_Internal_Rela *rel, *relend;
+
+ elf_section_data (sec)->local_dynrel = NULL;
+
+ 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++)
+ {
+ unsigned long r_symndx;
+ struct elf_link_hash_entry *h = NULL;
+
+ r_symndx = ELF32_R_SYM (rel->r_info);
+ if (r_symndx >= symtab_hdr->sh_info)
+ {
+ 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;
+ }
+
+ switch (ELF32_R_TYPE (rel->r_info))
+ {
+ case R_OR1K_GOT16:
+ if (h != NULL)
+ {
+ if (h->got.refcount > 0)
+ h->got.refcount--;
+ }
+ else
+ {
+ if (local_got_refcounts && local_got_refcounts[r_symndx] > 0)
+ local_got_refcounts[r_symndx]--;
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ return TRUE;
+}
+
+/* Create .got, .gotplt, and .rela.got sections in DYNOBJ, and set up
+ shortcuts to them in our hash table. */
+
+static bfd_boolean
+create_got_section (bfd *dynobj, struct bfd_link_info *info)
+{
+ struct elf_or1k_link_hash_table *htab;
+ asection *s;
+
+ /* This function may be called more than once. */
+ s = bfd_get_section_by_name (dynobj, ".got");
+ if (s != NULL && (s->flags & SEC_LINKER_CREATED) != 0)
+ return TRUE;
+
+ htab = or1k_elf_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ if (! _bfd_elf_create_got_section (dynobj, info))
+ return FALSE;
+
+ htab->sgot = bfd_get_section_by_name (dynobj, ".got");
+ htab->sgotplt = bfd_get_section_by_name (dynobj, ".got.plt");
+ htab->srelgot = bfd_get_section_by_name (dynobj, ".rela.got");
+
+ if (! htab->sgot || ! htab->sgotplt || ! htab->srelgot)
+ abort ();
+
+ if (! bfd_set_section_flags (dynobj, htab->srelgot, SEC_ALLOC
+ | SEC_LOAD
+ | SEC_HAS_CONTENTS
+ | SEC_IN_MEMORY
+ | SEC_LINKER_CREATED
+ | SEC_READONLY)
+ || ! bfd_set_section_alignment (dynobj, htab->srelgot, 2))
+ return FALSE;
+
+ return TRUE;
+}
+
+/* Look through the relocs for a section during the first phase. */
+
+static bfd_boolean
+or1k_elf_check_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;
+ const Elf_Internal_Rela *rel;
+
+ const Elf_Internal_Rela *rel_end;
+ struct elf_or1k_link_hash_table *htab;
+ bfd *dynobj;
+ asection *sreloc = NULL;
+
+ if (info->relocatable)
+ return TRUE;
+
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+ sym_hashes = elf_sym_hashes (abfd);
+
+ htab = or1k_elf_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ dynobj = htab->root.dynobj;
+
+ rel_end = relocs + sec->reloc_count;
+ for (rel = relocs; rel < rel_end; rel++)
+ {
+ struct elf_link_hash_entry *h;
+ unsigned long r_symndx;
+ unsigned char tls_type;
+
+ 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];
+ 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;
+
+ /* PR15323, ref flags aren't set for references in the same
+ object. */
+ h->root.non_ir_ref = 1;
+ }
+
+ switch (ELF32_R_TYPE (rel->r_info))
+ {
+ case R_OR1K_TLS_GD_HI16:
+ case R_OR1K_TLS_GD_LO16:
+ tls_type = TLS_GD;
+ break;
+ case R_OR1K_TLS_LDM_HI16:
+ case R_OR1K_TLS_LDM_LO16:
+ case R_OR1K_TLS_LDO_HI16:
+ case R_OR1K_TLS_LDO_LO16:
+ tls_type = TLS_LD;
+ break;
+ case R_OR1K_TLS_IE_HI16:
+ case R_OR1K_TLS_IE_LO16:
+ tls_type = TLS_IE;
+ break;
+ case R_OR1K_TLS_LE_HI16:
+ case R_OR1K_TLS_LE_LO16:
+ tls_type = TLS_LE;
+ break;
+ default:
+ tls_type = TLS_NONE;
+ }
+
+ /* Record TLS type. */
+ if (h != NULL)
+ ((struct elf_or1k_link_hash_entry *) h)->tls_type = tls_type;
+ else
+ {
+ unsigned char *local_tls_type;
+
+ /* This is a TLS type record for a local symbol. */
+ local_tls_type = (unsigned char *) elf_or1k_local_tls_type (abfd);
+ if (local_tls_type == NULL)
+ {
+ bfd_size_type size;
+
+ size = symtab_hdr->sh_info;
+ local_tls_type = bfd_zalloc (abfd, size);
+ if (local_tls_type == NULL)
+ return FALSE;
+ elf_or1k_local_tls_type (abfd) = local_tls_type;
+ }
+ local_tls_type[r_symndx] = tls_type;
+ }
+
+ switch (ELF32_R_TYPE (rel->r_info))
+ {
+ /* This relocation describes the C++ object vtable hierarchy.
+ Reconstruct it for later use during GC. */
+ case R_OR1K_GNU_VTINHERIT:
+ if (!bfd_elf_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_OR1K_GNU_VTENTRY:
+ BFD_ASSERT (h != NULL);
+ if (h != NULL
+ && !bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
+ return FALSE;
+ break;
+
+ /* This relocation requires .plt entry. */
+ case R_OR1K_PLT26:
+ if (h != NULL)
+ {
+ h->needs_plt = 1;
+ h->plt.refcount += 1;
+ }
+ break;
+
+ case R_OR1K_GOT16:
+ case R_OR1K_GOTOFF_HI16:
+ case R_OR1K_GOTOFF_LO16:
+ case R_OR1K_TLS_GD_HI16:
+ case R_OR1K_TLS_GD_LO16:
+ case R_OR1K_TLS_IE_HI16:
+ case R_OR1K_TLS_IE_LO16:
+ if (htab->sgot == NULL)
+ {
+ if (dynobj == NULL)
+ htab->root.dynobj = dynobj = abfd;
+ if (! create_got_section (dynobj, info))
+ return FALSE;
+ }
+
+ if (ELF32_R_TYPE (rel->r_info) != R_OR1K_GOTOFF_HI16 &&
+ ELF32_R_TYPE (rel->r_info) != R_OR1K_GOTOFF_LO16)
+ {
+ if (h != NULL)
+ h->got.refcount += 1;
+ else
+ {
+ bfd_signed_vma *local_got_refcounts;
+
+ /* This is a global offset table entry for a local symbol. */
+ local_got_refcounts = elf_local_got_refcounts (abfd);
+ if (local_got_refcounts == NULL)
+ {
+ bfd_size_type size;
+
+ size = symtab_hdr->sh_info;
+ size *= sizeof (bfd_signed_vma);
+ local_got_refcounts = bfd_zalloc (abfd, size);
+ if (local_got_refcounts == NULL)
+ return FALSE;
+ elf_local_got_refcounts (abfd) = local_got_refcounts;
+ }
+ local_got_refcounts[r_symndx] += 1;
+ }
+ }
+ break;
+
+ case R_OR1K_INSN_REL_26:
+ case R_OR1K_HI_16_IN_INSN:
+ case R_OR1K_LO_16_IN_INSN:
+ case R_OR1K_32:
+ /* R_OR1K_16? */
+ {
+ if (h != NULL && !info->shared)
+ {
+ /* We may need a copy reloc. */
+ h->non_got_ref = 1;
+
+ /* We may also need a .plt entry. */
+ h->plt.refcount += 1;
+ if (ELF32_R_TYPE (rel->r_info) != R_OR1K_INSN_REL_26)
+ h->pointer_equality_needed = 1;
+ }
+
+ /* 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). In case of a weak definition,
+ DEF_REGULAR may be cleared later by a strong definition in
+ a shared library. We account for that possibility below by
+ storing information in the relocs_copied field of the hash
+ table entry. A similar situation occurs when creating
+ shared libraries and symbol visibility changes render the
+ symbol local.
+
+ If on the other hand, we are creating an executable, we
+ may need to keep relocations for symbols satisfied by a
+ dynamic library if we manage to avoid copy relocs for the
+ symbol. */
+
+ if ((info->shared
+ && (sec->flags & SEC_ALLOC) != 0
+ && (ELF32_R_TYPE (rel->r_info) != R_OR1K_INSN_REL_26
+ || (h != NULL
+ && (!SYMBOLIC_BIND (info, h)
+ || h->root.type == bfd_link_hash_defweak
+ || !h->def_regular))))
+ || (!info->shared
+ && (sec->flags & SEC_ALLOC) != 0
+ && h != NULL
+ && (h->root.type == bfd_link_hash_defweak
+ || !h->def_regular)))
+ {
+ struct elf_or1k_dyn_relocs *p;
+ struct elf_or1k_dyn_relocs **head;
+
+ /* 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;
+ unsigned int strndx = elf_elfheader (abfd)->e_shstrndx;
+ unsigned int shnam = _bfd_elf_single_rel_hdr (sec)->sh_name;
+
+ name = bfd_elf_string_from_elf_section (abfd, strndx, shnam);
+ if (name == NULL)
+ return FALSE;
+
+ if (strncmp (name, ".rela", 5) != 0
+ || strcmp (bfd_get_section_name (abfd, sec),
+ name + 5) != 0)
+ {
+ (*_bfd_error_handler)
+ (_("%B: bad relocation section name `%s\'"),
+ abfd, name);
+ }
+
+ if (htab->root.dynobj == NULL)
+ htab->root.dynobj = abfd;
+ dynobj = htab->root.dynobj;
+
+ sreloc = bfd_get_section_by_name (dynobj, name);
+ if (sreloc == NULL)
+ {
+ sreloc = _bfd_elf_make_dynamic_reloc_section
+ (sec, dynobj, 2, abfd, /*rela?*/ TRUE);
+
+ if (sreloc == NULL)
+ return FALSE;
+ }
+ elf_section_data (sec)->sreloc = sreloc;
+ }
+
+ /* If this is a global symbol, we count the number of
+ relocations we need for this symbol. */
+ if (h != NULL)
+ head = &((struct elf_or1k_link_hash_entry *) h)->dyn_relocs;
+ else
+ {
+ /* Track dynamic relocs needed for local syms too.
+ We really need local syms available to do this
+ easily. Oh well. */
+
+ asection *s;
+ Elf_Internal_Sym *isym;
+ void *vpp;
+
+ isym = bfd_sym_from_r_symndx (&htab->sym_sec,
+ abfd, r_symndx);
+ if (isym == NULL)
+ return FALSE;
+
+ s = bfd_section_from_elf_index (abfd, isym->st_shndx);
+ if (s == NULL)
+ return FALSE;
+
+ vpp = &elf_section_data (s)->local_dynrel;
+ head = (struct elf_or1k_dyn_relocs **) vpp;
+ }
+
+ p = *head;
+ if (p == NULL || p->sec != sec)
+ {
+ bfd_size_type amt = sizeof *p;
+ p = ((struct elf_or1k_dyn_relocs *)
+ bfd_alloc (htab->root.dynobj, amt));
+ if (p == NULL)
+ return FALSE;
+ p->next = *head;
+ *head = p;
+ p->sec = sec;
+ p->count = 0;
+ p->pc_count = 0;
+ }
+
+ p->count += 1;
+ if (ELF32_R_TYPE (rel->r_info) == R_OR1K_INSN_REL_26)
+ p->pc_count += 1;
+ }
+ }
+ break;
+ }
+ }
+
+ return TRUE;
+}
+
+/* Finish up the dynamic sections. */
+
+static bfd_boolean
+or1k_elf_finish_dynamic_sections (bfd *output_bfd,
+ struct bfd_link_info *info)
+{
+ bfd *dynobj;
+ asection *sdyn, *sgot;
+ struct elf_or1k_link_hash_table *htab;
+
+ htab = or1k_elf_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ dynobj = htab->root.dynobj;
+
+ sgot = htab->sgotplt;
+ sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
+
+ if (htab->root.dynamic_sections_created)
+ {
+ asection *splt;
+ Elf32_External_Dyn *dyncon, *dynconend;
+
+ BFD_ASSERT (sgot != NULL && sdyn != NULL);
+
+ dyncon = (Elf32_External_Dyn *) sdyn->contents;
+ dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->size);
+
+ for (; dyncon < dynconend; dyncon++)
+ {
+ Elf_Internal_Dyn dyn;
+ asection *s;
+
+ bfd_elf32_swap_dyn_in (dynobj, dyncon, &dyn);
+
+ switch (dyn.d_tag)
+ {
+ default:
+ continue;
+
+ case DT_PLTGOT:
+ s = htab->sgot->output_section;
+ BFD_ASSERT (s != NULL);
+ dyn.d_un.d_ptr = s->vma;
+ break;
+
+ case DT_JMPREL:
+ s = htab->srelplt->output_section;
+ BFD_ASSERT (s != NULL);
+ dyn.d_un.d_ptr = s->vma;
+ break;
+
+ case DT_PLTRELSZ:
+ s = htab->srelplt->output_section;
+ BFD_ASSERT (s != NULL);
+ dyn.d_un.d_val = s->size;
+ break;
+
+ case DT_RELASZ:
+ /* My reading of the SVR4 ABI indicates that the
+ procedure linkage table relocs (DT_JMPREL) should be
+ included in the overall relocs (DT_RELA). This is
+ what Solaris does. However, UnixWare can not handle
+ that case. 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. */
+ if (htab->srelplt != NULL)
+ {
+ /* FIXME: this calculation sometimes produces
+ wrong result, the problem is that the dyn.d_un.d_val
+ is not always correct, needs investigation why
+ that happens. In the meantime, reading the
+ ".rela.dyn" section by name seems to yield
+ correct result.
+
+ s = htab->srelplt->output_section;
+ dyn.d_un.d_val -= s->size;
+ */
+
+ s = bfd_get_section_by_name (output_bfd, ".rela.dyn");
+ dyn.d_un.d_val = s ? s->size : 0;
+ }
+ break;
+ }
+ bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
+ }
+
+
+ /* Fill in the first entry in the procedure linkage table. */
+ splt = htab->splt;
+ if (splt && splt->size > 0)
+ {
+ if (info->shared)
+ {
+ bfd_put_32 (output_bfd, PLT0_PIC_ENTRY_WORD0,
+ splt->contents);
+ bfd_put_32 (output_bfd, PLT0_PIC_ENTRY_WORD1,
+ splt->contents + 4);
+ bfd_put_32 (output_bfd, PLT0_PIC_ENTRY_WORD2,
+ splt->contents + 8);
+ bfd_put_32 (output_bfd, PLT0_PIC_ENTRY_WORD3,
+ splt->contents + 12);
+ bfd_put_32 (output_bfd, PLT0_PIC_ENTRY_WORD4,
+ splt->contents + 16);
+ }
+ else
+ {
+ unsigned long addr;
+ /* addr = .got + 4 */
+ addr = sgot->output_section->vma + sgot->output_offset + 4;
+ bfd_put_32 (output_bfd,
+ PLT0_ENTRY_WORD0 | ((addr >> 16) & 0xffff),
+ splt->contents);
+ bfd_put_32 (output_bfd,
+ PLT0_ENTRY_WORD1 | (addr & 0xffff),
+ splt->contents + 4);
+ bfd_put_32 (output_bfd, PLT0_ENTRY_WORD2, splt->contents + 8);
+ bfd_put_32 (output_bfd, PLT0_ENTRY_WORD3, splt->contents + 12);
+ bfd_put_32 (output_bfd, PLT0_ENTRY_WORD4, splt->contents + 16);
+ }
+
+ elf_section_data (splt->output_section)->this_hdr.sh_entsize = 4;
+ }
+ }
+
+ /* Set the first entry in the global offset table to the address of
+ the dynamic section. */
+ if (sgot && sgot->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 (htab->sgot && htab->sgot->size > 0)
+ elf_section_data (htab->sgot->output_section)->this_hdr.sh_entsize = 4;
+
+ return TRUE;
+}
+
+/* Finish up dynamic symbol handling. We set the contents of various
+ dynamic sections here. */
+
+static bfd_boolean
+or1k_elf_finish_dynamic_symbol (bfd *output_bfd,
+ struct bfd_link_info *info,
+ struct elf_link_hash_entry *h,
+ Elf_Internal_Sym *sym)
+{
+ struct elf_or1k_link_hash_table *htab;
+ bfd_byte *loc;
+
+ htab = or1k_elf_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ if (h->plt.offset != (bfd_vma) -1)
+ {
+ asection *splt;
+ asection *sgot;
+ asection *srela;
+
+ bfd_vma plt_index;
+ bfd_vma got_offset;
+ bfd_vma got_addr;
+ Elf_Internal_Rela rela;
+
+ /* This symbol has an entry in the procedure linkage table. Set
+ it up. */
+ BFD_ASSERT (h->dynindx != -1);
+
+ splt = htab->splt;
+ sgot = htab->sgotplt;
+ srela = htab->srelplt;
+ 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;
+ got_addr = got_offset;
+
+ /* Fill in the entry in the procedure linkage table. */
+ if (! info->shared)
+ {
+ got_addr += htab->sgotplt->output_section->vma
+ + htab->sgotplt->output_offset;
+ bfd_put_32 (output_bfd, PLT_ENTRY_WORD0 | ((got_addr >> 16) & 0xffff),
+ splt->contents + h->plt.offset);
+ bfd_put_32 (output_bfd, PLT_ENTRY_WORD1 | (got_addr & 0xffff),
+ splt->contents + h->plt.offset + 4);
+ bfd_put_32 (output_bfd, (bfd_vma) PLT_ENTRY_WORD2,
+ splt->contents + h->plt.offset + 8);
+ bfd_put_32 (output_bfd, (bfd_vma) PLT_ENTRY_WORD3,
+ splt->contents + h->plt.offset + 12);
+ bfd_put_32 (output_bfd, PLT_ENTRY_WORD4
+ | plt_index * sizeof (Elf32_External_Rela),
+ splt->contents + h->plt.offset + 16);
+ }
+ else
+ {
+ bfd_put_32 (output_bfd, PLT_PIC_ENTRY_WORD0 | (got_addr & 0xffff),
+ splt->contents + h->plt.offset);
+ bfd_put_32 (output_bfd, PLT_PIC_ENTRY_WORD1
+ | plt_index * sizeof (Elf32_External_Rela),
+ splt->contents + h->plt.offset + 4);
+ bfd_put_32 (output_bfd, (bfd_vma) PLT_PIC_ENTRY_WORD2,
+ splt->contents + h->plt.offset + 8);
+ bfd_put_32 (output_bfd, (bfd_vma) PLT_PIC_ENTRY_WORD3,
+ splt->contents + h->plt.offset + 12);
+ bfd_put_32 (output_bfd, (bfd_vma) PLT_PIC_ENTRY_WORD4,
+ 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), /* Same offset. */
+ 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_OR1K_JMP_SLOT);
+ rela.r_addend = 0;
+ loc = srela->contents;
+ loc += plt_index * sizeof (Elf32_External_Rela);
+ bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
+
+ if (!h->def_regular)
+ {
+ /* 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
+ && (h->got.offset & 2) == 0) /* Homemade TLS check. */
+ {
+ asection *sgot;
+ asection *srela;
+ Elf_Internal_Rela rela;
+
+ /* This symbol has an entry in the global offset table. Set it
+ up. */
+ sgot = htab->sgot;
+ srela = htab->srelgot;
+ 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 && SYMBOL_REFERENCES_LOCAL (info, h))
+ {
+ rela.r_info = ELF32_R_INFO (0, R_OR1K_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_OR1K_GLOB_DAT);
+ rela.r_addend = 0;
+ }
+
+ loc = srela->contents;
+ loc += srela->reloc_count * sizeof (Elf32_External_Rela);
+ bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
+ ++srela->reloc_count;
+ }
+
+ if (h->needs_copy)
+ {
+ asection *s;
+ Elf_Internal_Rela rela;
+
+ /* This symbols 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_OR1K_COPY);
+ rela.r_addend = 0;
+ loc = s->contents;
+ loc += s->reloc_count * sizeof (Elf32_External_Rela);
+ bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
+ ++s->reloc_count;
+ }
+
+ /* Mark some specially defined symbols as absolute. */
+ if (strcmp (h->root.root.string, "_DYNAMIC") == 0
+ || h == htab->root.hgot)
+ sym->st_shndx = SHN_ABS;
+
+ return TRUE;
+}
+
+static enum elf_reloc_type_class
+or1k_elf_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ const asection *rel_sec ATTRIBUTE_UNUSED,
+ const Elf_Internal_Rela *rela)
+{
+ switch ((int) ELF32_R_TYPE (rela->r_info))
+ {
+ case R_OR1K_RELATIVE: return reloc_class_relative;
+ case R_OR1K_JMP_SLOT: return reloc_class_plt;
+ case R_OR1K_COPY: return reloc_class_copy;
+ default: return reloc_class_normal;
+ }
+}
+
+/* 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 bfd_boolean
+or1k_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
+ struct elf_link_hash_entry *h)
+{
+ struct elf_or1k_link_hash_table *htab;
+ struct elf_or1k_link_hash_entry *eh;
+ struct elf_or1k_dyn_relocs *p;
+ bfd *dynobj;
+ asection *s;
+
+ dynobj = elf_hash_table (info)->dynobj;
+
+ /* Make sure we know what is going on here. */
+ BFD_ASSERT (dynobj != NULL
+ && (h->needs_plt
+ || h->u.weakdef != NULL
+ || (h->def_dynamic
+ && h->ref_regular
+ && !h->def_regular)));
+
+ /* 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->needs_plt)
+ {
+ if (! info->shared
+ && !h->def_dynamic
+ && !h->ref_dynamic
+ && h->root.type != bfd_link_hash_undefweak
+ && h->root.type != bfd_link_hash_undefined)
+ {
+ /* This case can occur if we saw a PLT 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 PCREL
+ reloc instead. */
+ h->plt.offset = (bfd_vma) -1;
+ h->needs_plt = 0;
+ }
+
+ return TRUE;
+ }
+ else
+ 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->u.weakdef != NULL)
+ {
+ BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
+ || h->u.weakdef->root.type == bfd_link_hash_defweak);
+ h->root.u.def.section = h->u.weakdef->root.u.def.section;
+ h->root.u.def.value = h->u.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;
+
+ /* If there are no references to this symbol that do not use the
+ GOT, we don't need to generate a copy reloc. */
+ if (!h->non_got_ref)
+ return TRUE;
+
+ /* If -z nocopyreloc was given, we won't generate them either. */
+ if (info->nocopyreloc)
+ {
+ h->non_got_ref = 0;
+ return TRUE;
+ }
+
+ eh = (struct elf_or1k_link_hash_entry *) h;
+ for (p = eh->dyn_relocs; p != NULL; p = p->next)
+ {
+ s = p->sec->output_section;
+ if (s != NULL && (s->flags & (SEC_READONLY | SEC_HAS_CONTENTS)) != 0)
+ break;
+ }
+
+ /* If we didn't find any dynamic relocs in sections which needs the
+ copy reloc, then we'll be keeping the dynamic relocs and avoiding
+ the copy reloc. */
+ if (p == NULL)
+ {
+ h->non_got_ref = 0;
+ 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. */
+
+ htab = or1k_elf_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ s = htab->sdynbss;
+ BFD_ASSERT (s != NULL);
+
+ /* We must generate a R_OR1K_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 && h->size != 0)
+ {
+ asection *srel;
+
+ srel = htab->srelbss;
+ BFD_ASSERT (srel != NULL);
+ srel->size += sizeof (Elf32_External_Rela);
+ h->needs_copy = 1;
+ }
+
+ return _bfd_elf_adjust_dynamic_copy (h, s);
+}
+
+/* Allocate space in .plt, .got and associated reloc sections for
+ dynamic relocs. */
+
+static bfd_boolean
+allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
+{
+ struct bfd_link_info *info;
+ struct elf_or1k_link_hash_table *htab;
+ struct elf_or1k_link_hash_entry *eh;
+ struct elf_or1k_dyn_relocs *p;
+
+ if (h->root.type == bfd_link_hash_indirect)
+ return TRUE;
+
+ info = (struct bfd_link_info *) inf;
+ htab = or1k_elf_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ eh = (struct elf_or1k_link_hash_entry *) h;
+
+ if (htab->root.dynamic_sections_created
+ && h->plt.refcount > 0)
+ {
+ /* Make sure this symbol is output as a dynamic symbol.
+ Undefined weak syms won't yet be marked as dynamic. */
+ if (h->dynindx == -1
+ && !h->forced_local)
+ {
+ if (! bfd_elf_link_record_dynamic_symbol (info, h))
+ return FALSE;
+ }
+
+ if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, info->shared, h))
+ {
+ asection *s = htab->splt;
+
+ /* If this is the first .plt entry, make room for the special
+ first entry. */
+ if (s->size == 0)
+ s->size = PLT_ENTRY_SIZE;
+
+ h->plt.offset = s->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->def_regular)
+ {
+ h->root.u.def.section = s;
+ h->root.u.def.value = h->plt.offset;
+ }
+
+ /* Make room for this entry. */
+ s->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. */
+ htab->sgotplt->size += 4;
+
+ /* We also need to make an entry in the .rel.plt section. */
+ htab->srelplt->size += sizeof (Elf32_External_Rela);
+ }
+ else
+ {
+ h->plt.offset = (bfd_vma) -1;
+ h->needs_plt = 0;
+ }
+ }
+ else
+ {
+ h->plt.offset = (bfd_vma) -1;
+ h->needs_plt = 0;
+ }
+
+ if (h->got.refcount > 0)
+ {
+ asection *s;
+ bfd_boolean dyn;
+ unsigned char tls_type;
+
+ /* Make sure this symbol is output as a dynamic symbol.
+ Undefined weak syms won't yet be marked as dynamic. */
+ if (h->dynindx == -1
+ && !h->forced_local)
+ {
+ if (! bfd_elf_link_record_dynamic_symbol (info, h))
+ return FALSE;
+ }
+
+ s = htab->sgot;
+
+ h->got.offset = s->size;
+
+ tls_type = ((struct elf_or1k_link_hash_entry *) h)->tls_type;
+
+ /* TLS GD requires two GOT and two relocs. */
+ if (tls_type == TLS_GD)
+ s->size += 8;
+ else
+ s->size += 4;
+ dyn = htab->root.dynamic_sections_created;
+ if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h))
+ {
+ if (tls_type == TLS_GD)
+ htab->srelgot->size += 2 * sizeof (Elf32_External_Rela);
+ else
+ htab->srelgot->size += sizeof (Elf32_External_Rela);
+ }
+ }
+ else
+ h->got.offset = (bfd_vma) -1;
+
+ if (eh->dyn_relocs == NULL)
+ return TRUE;
+
+ /* In the shared -Bsymbolic case, discard space allocated for
+ dynamic pc-relative relocs against symbols which turn out to be
+ defined in regular objects. For the normal shared case, discard
+ space for pc-relative relocs that have become local due to symbol
+ visibility changes. */
+
+ if (info->shared)
+ {
+ if (SYMBOL_CALLS_LOCAL (info, h))
+ {
+ struct elf_or1k_dyn_relocs **pp;
+
+ for (pp = &eh->dyn_relocs; (p = *pp) != NULL;)
+ {
+ p->count -= p->pc_count;
+ p->pc_count = 0;
+ if (p->count == 0)
+ *pp = p->next;
+ else
+ pp = &p->next;
+ }
+ }
+
+ /* Also discard relocs on undefined weak syms with non-default
+ visibility. */
+ if (eh->dyn_relocs != NULL
+ && h->root.type == bfd_link_hash_undefweak)
+ {
+ if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
+ eh->dyn_relocs = NULL;
+
+ /* Make sure undefined weak symbols are output as a dynamic
+ symbol in PIEs. */
+ else if (h->dynindx == -1
+ && !h->forced_local)
+ {
+ if (! bfd_elf_link_record_dynamic_symbol (info, h))
+ return FALSE;
+ }
+ }
+ }
+ else
+ {
+ /* For the non-shared case, discard space for relocs against
+ symbols which turn out to need copy relocs or are not
+ dynamic. */
+
+ if (!h->non_got_ref
+ && ((h->def_dynamic
+ && !h->def_regular)
+ || (htab->root.dynamic_sections_created
+ && (h->root.type == bfd_link_hash_undefweak
+ || h->root.type == bfd_link_hash_undefined))))
+ {
+ /* Make sure this symbol is output as a dynamic symbol.
+ Undefined weak syms won't yet be marked as dynamic. */
+ if (h->dynindx == -1
+ && !h->forced_local)
+ {
+ if (! bfd_elf_link_record_dynamic_symbol (info, h))
+ return FALSE;
+ }
+
+ /* If that succeeded, we know we'll be keeping all the
+ relocs. */
+ if (h->dynindx != -1)
+ goto keep;
+ }
+
+ eh->dyn_relocs = NULL;
+
+ keep: ;
+ }
+
+ /* Finally, allocate space. */
+ for (p = eh->dyn_relocs; p != NULL; p = p->next)
+ {
+ asection *sreloc = elf_section_data (p->sec)->sreloc;
+ sreloc->size += p->count * sizeof (Elf32_External_Rela);
+ }
+
+ return TRUE;
+}
+
+/* Find any dynamic relocs that apply to read-only sections. */
+
+static bfd_boolean
+readonly_dynrelocs (struct elf_link_hash_entry *h, void * inf)
+{
+ struct elf_or1k_link_hash_entry *eh;
+ struct elf_or1k_dyn_relocs *p;
+
+ eh = (struct elf_or1k_link_hash_entry *) h;
+ for (p = eh->dyn_relocs; p != NULL; p = p->next)
+ {
+ asection *s = p->sec->output_section;
+
+ if (s != NULL && (s->flags & SEC_READONLY) != 0)
+ {
+ struct bfd_link_info *info = (struct bfd_link_info *) inf;
+
+ info->flags |= DF_TEXTREL;
+
+ /* Not an error, just cut short the traversal. */
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+/* Set the sizes of the dynamic sections. */
+
+static bfd_boolean
+or1k_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
+ struct bfd_link_info *info)
+{
+ struct elf_or1k_link_hash_table *htab;
+ bfd *dynobj;
+ asection *s;
+ bfd_boolean relocs;
+ bfd *ibfd;
+
+ htab = or1k_elf_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ dynobj = htab->root.dynobj;
+ BFD_ASSERT (dynobj != NULL);
+
+ if (htab->root.dynamic_sections_created)
+ {
+ /* Set the contents of the .interp section to the interpreter. */
+ if (info->executable)
+ {
+ s = bfd_get_section_by_name (dynobj, ".interp");
+ BFD_ASSERT (s != NULL);
+ s->size = sizeof ELF_DYNAMIC_INTERPRETER;
+ s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
+ }
+ }
+
+ /* Set up .got offsets for local syms, and space for local dynamic
+ relocs. */
+ for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next)
+ {
+ bfd_signed_vma *local_got;
+ bfd_signed_vma *end_local_got;
+ bfd_size_type locsymcount;
+ Elf_Internal_Shdr *symtab_hdr;
+ unsigned char *local_tls_type;
+ asection *srel;
+
+ if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour)
+ continue;
+
+ for (s = ibfd->sections; s != NULL; s = s->next)
+ {
+ struct elf_or1k_dyn_relocs *p;
+
+ for (p = ((struct elf_or1k_dyn_relocs *)
+ elf_section_data (s)->local_dynrel);
+ p != NULL;
+ p = p->next)
+ {
+ if (! bfd_is_abs_section (p->sec)
+ && bfd_is_abs_section (p->sec->output_section))
+ {
+ /* Input section has been discarded, either because
+ it is a copy of a linkonce section or due to
+ linker script /DISCARD/, so we'll be discarding
+ the relocs too. */
+ }
+ else if (p->count != 0)
+ {
+ srel = elf_section_data (p->sec)->sreloc;
+ srel->size += p->count * sizeof (Elf32_External_Rela);
+ if ((p->sec->output_section->flags & SEC_READONLY) != 0)
+ info->flags |= DF_TEXTREL;
+ }
+ }
+ }
+
+ local_got = elf_local_got_refcounts (ibfd);
+ if (!local_got)
+ continue;
+
+ symtab_hdr = &elf_tdata (ibfd)->symtab_hdr;
+ locsymcount = symtab_hdr->sh_info;
+ end_local_got = local_got + locsymcount;
+ s = htab->sgot;
+ srel = htab->srelgot;
+ local_tls_type = (unsigned char *) elf_or1k_local_tls_type (ibfd);
+ for (; local_got < end_local_got; ++local_got)
+ {
+ if (*local_got > 0)
+ {
+ *local_got = s->size;
+
+ /* TLS GD requires two GOT and two relocs. */
+ if (local_tls_type != NULL && *local_tls_type == TLS_GD)
+ s->size += 8;
+ else
+ s->size += 4;
+ if (info->shared)
+ {
+ if (local_tls_type != NULL && *local_tls_type == TLS_GD)
+ srel->size += 2 * sizeof (Elf32_External_Rela);
+ else
+ srel->size += sizeof (Elf32_External_Rela);
+ }
+ }
+ else
+
+ *local_got = (bfd_vma) -1;
+
+ if (local_tls_type)
+ ++local_tls_type;
+ }
+ }
+
+ /* Allocate global sym .plt and .got entries, and space for global
+ sym dynamic relocs. */
+ elf_link_hash_traverse (&htab->root, allocate_dynrelocs, info);
+
+ /* We now have determined the sizes of the various dynamic sections.
+ Allocate memory for them. */
+ relocs = FALSE;
+ for (s = dynobj->sections; s != NULL; s = s->next)
+ {
+ if ((s->flags & SEC_LINKER_CREATED) == 0)
+ continue;
+
+ if (s == htab->splt
+ || s == htab->sgot
+ || s == htab->sgotplt
+ || s == htab->sdynbss)
+ {
+ /* Strip this section if we don't need it; see the
+ comment below. */
+ }
+ else if (CONST_STRNEQ (bfd_get_section_name (dynobj, s), ".rela"))
+ {
+ if (s->size != 0 && s != htab->srelplt)
+ relocs = 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
+ /* It's not one of our sections, so don't allocate space. */
+ continue;
+
+ if (s->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. */
+ s->flags |= SEC_EXCLUDE;
+ continue;
+ }
+
+ if ((s->flags & SEC_HAS_CONTENTS) == 0)
+ continue;
+
+ /* Allocate memory for the section contents. We use bfd_zalloc
+ here in case unused entries are not reclaimed before the
+ section's contents are written out. This should not happen,
+ but this way if it does, we get a R_OR1K_NONE reloc instead
+ of garbage. */
+ s->contents = bfd_zalloc (dynobj, s->size);
+
+ if (s->contents == NULL)
+ return FALSE;
+ }
+
+ if (htab->root.dynamic_sections_created)
+ {
+ /* Add some entries to the .dynamic section. We fill in the
+ values later, in or1k_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. */
+#define add_dynamic_entry(TAG, VAL) \
+ _bfd_elf_add_dynamic_entry (info, TAG, VAL)
+
+ if (info->executable)
+ {
+ if (! add_dynamic_entry (DT_DEBUG, 0))
+ return FALSE;
+ }
+
+ if (htab->splt->size != 0)
+ {
+ if (! add_dynamic_entry (DT_PLTGOT, 0)
+ || ! add_dynamic_entry (DT_PLTRELSZ, 0)
+ || ! add_dynamic_entry (DT_PLTREL, DT_RELA)
+ || ! add_dynamic_entry (DT_JMPREL, 0))
+ return FALSE;
+ }
+
+ if (relocs)
+ {
+ if (! add_dynamic_entry (DT_RELA, 0)
+ || ! add_dynamic_entry (DT_RELASZ, 0)
+ || ! add_dynamic_entry (DT_RELAENT,
+ sizeof (Elf32_External_Rela)))
+ return FALSE;
+
+ /* If any dynamic relocs apply to a read-only section,
+ then we need a DT_TEXTREL entry. */
+ if ((info->flags & DF_TEXTREL) == 0)
+ elf_link_hash_traverse (&htab->root, readonly_dynrelocs,
+ info);
+
+ if ((info->flags & DF_TEXTREL) != 0)
+ {
+ if (! add_dynamic_entry (DT_TEXTREL, 0))
+ return FALSE;
+ }
+ }
+ }
+
+#undef add_dynamic_entry
+ return TRUE;
+}
+
+/* Create dynamic sections when linking against a dynamic object. */
+
+static bfd_boolean
+or1k_elf_create_dynamic_sections (bfd *dynobj, struct bfd_link_info *info)
+{
+ struct elf_or1k_link_hash_table *htab;
+
+ htab = or1k_elf_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ if (!htab->sgot && !create_got_section (dynobj, info))
+ return FALSE;
+
+ if (!_bfd_elf_create_dynamic_sections (dynobj, info))
+ return FALSE;
+
+ htab->splt = bfd_get_section_by_name (dynobj, ".plt");
+ htab->srelplt = bfd_get_section_by_name (dynobj, ".rela.plt");
+ htab->sdynbss = bfd_get_section_by_name (dynobj, ".dynbss");
+ if (!info->shared)
+ htab->srelbss = bfd_get_section_by_name (dynobj, ".rela.bss");
+
+ if (!htab->splt || !htab->srelplt || !htab->sdynbss
+ || (!info->shared && !htab->srelbss))
+ abort ();
+
+ return TRUE;
+}
+
+/* Copy the extra info we tack onto an elf_link_hash_entry. */
+
+static void
+or1k_elf_copy_indirect_symbol (struct bfd_link_info *info,
+ struct elf_link_hash_entry *dir,
+ struct elf_link_hash_entry *ind)
+{
+ struct elf_or1k_link_hash_entry * edir;
+ struct elf_or1k_link_hash_entry * eind;
+
+ edir = (struct elf_or1k_link_hash_entry *) dir;
+ eind = (struct elf_or1k_link_hash_entry *) ind;
+
+ if (eind->dyn_relocs != NULL)
+ {
+ if (edir->dyn_relocs != NULL)
+ {
+ struct elf_or1k_dyn_relocs **pp;
+ struct elf_or1k_dyn_relocs *p;
+
+ /* Add reloc counts against the indirect sym to the direct sym
+ list. Merge any entries against the same section. */
+ for (pp = &eind->dyn_relocs; (p = *pp) != NULL;)
+ {
+ struct elf_or1k_dyn_relocs *q;
+
+ for (q = edir->dyn_relocs; q != NULL; q = q->next)
+ if (q->sec == p->sec)
+ {
+ q->pc_count += p->pc_count;
+ q->count += p->count;
+ *pp = p->next;
+ break;
+ }
+ if (q == NULL)
+ pp = &p->next;
+ }
+ *pp = edir->dyn_relocs;
+ }
+
+ edir->dyn_relocs = eind->dyn_relocs;
+ eind->dyn_relocs = NULL;
+ }
+
+ if (ind->root.type == bfd_link_hash_indirect)
+ {
+ if (dir->got.refcount <= 0)
+ {
+ edir->tls_type = eind->tls_type;
+ eind->tls_type = TLS_UNKNOWN;
+ }
+ }
+
+ _bfd_elf_link_hash_copy_indirect (info, dir, ind);
+}
+
+/* Set the right machine number. */
+
+static bfd_boolean
+or1k_elf_object_p (bfd *abfd)
+{
+ unsigned long mach = bfd_mach_or1k;
+
+ if (elf_elfheader (abfd)->e_flags & EF_OR1K_NODELAY)
+ mach = bfd_mach_or1knd;
+
+ return bfd_default_set_arch_mach (abfd, bfd_arch_or1k, mach);
+}
+
+/* Store the machine number in the flags field. */
+
+static void
+or1k_elf_final_write_processing (bfd *abfd,
+ bfd_boolean linker ATTRIBUTE_UNUSED)
+{
+ switch (bfd_get_mach (abfd))
+ {
+ default:
+ case bfd_mach_or1k:
+ break;
+ case bfd_mach_or1knd:
+ elf_elfheader (abfd)->e_flags |= EF_OR1K_NODELAY;
+ break;
+ }
+}
+
+static bfd_boolean
+or1k_elf_set_private_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;
+}
+
+/* Make sure all input files are consistent with respect to
+ EF_OR1K_NODELAY flag setting. */
+
+static bfd_boolean
+elf32_or1k_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
+{
+ flagword out_flags;
+ flagword in_flags;
+
+ in_flags = elf_elfheader (ibfd)->e_flags;
+ out_flags = elf_elfheader (obfd)->e_flags;
+
+ if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
+ || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
+ return TRUE;
+
+ if (!elf_flags_init (obfd))
+ {
+ elf_flags_init (obfd) = TRUE;
+ elf_elfheader (obfd)->e_flags = in_flags;
+
+ return TRUE;
+ }
+
+ if (in_flags == out_flags)
+ return TRUE;
+
+ if ((in_flags & EF_OR1K_NODELAY) != (out_flags & EF_OR1K_NODELAY))
+ {
+ (*_bfd_error_handler)
+ (_("%B: EF_OR1K_NODELAY flag mismatch with previous modules"), ibfd);
+
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+
+ return TRUE;
+
+}
+
+#define ELF_ARCH bfd_arch_or1k
+#define ELF_MACHINE_CODE EM_OR1K
+#define ELF_TARGET_ID OR1K_ELF_DATA
+#define ELF_MAXPAGESIZE 0x2000
+
+#define TARGET_BIG_SYM or1k_elf32_vec
+#define TARGET_BIG_NAME "elf32-or1k"
+
+#define elf_info_to_howto_rel NULL
+#define elf_info_to_howto or1k_info_to_howto_rela
+#define elf_backend_relocate_section or1k_elf_relocate_section
+#define elf_backend_gc_mark_hook or1k_elf_gc_mark_hook
+#define elf_backend_gc_sweep_hook or1k_elf_gc_sweep_hook
+#define elf_backend_check_relocs or1k_elf_check_relocs
+#define elf_backend_reloc_type_class or1k_elf_reloc_type_class
+#define elf_backend_can_gc_sections 1
+#define elf_backend_rela_normal 1
+
+#define bfd_elf32_mkobject elf_or1k_mkobject
+
+#define bfd_elf32_bfd_merge_private_bfd_data elf32_or1k_merge_private_bfd_data
+#define bfd_elf32_bfd_set_private_flags or1k_elf_set_private_flags
+#define bfd_elf32_bfd_reloc_type_lookup or1k_reloc_type_lookup
+#define bfd_elf32_bfd_reloc_name_lookup or1k_reloc_name_lookup
+
+#define elf_backend_object_p or1k_elf_object_p
+#define elf_backend_final_write_processing or1k_elf_final_write_processing
+#define elf_backend_can_refcount 1
+
+#define elf_backend_plt_readonly 1
+#define elf_backend_want_got_plt 1
+#define elf_backend_want_plt_sym 0
+#define elf_backend_got_header_size 12
+#define bfd_elf32_bfd_link_hash_table_create or1k_elf_link_hash_table_create
+#define elf_backend_copy_indirect_symbol or1k_elf_copy_indirect_symbol
+#define elf_backend_create_dynamic_sections or1k_elf_create_dynamic_sections
+#define elf_backend_finish_dynamic_sections or1k_elf_finish_dynamic_sections
+#define elf_backend_size_dynamic_sections or1k_elf_size_dynamic_sections
+#define elf_backend_adjust_dynamic_symbol or1k_elf_adjust_dynamic_symbol
+#define elf_backend_finish_dynamic_symbol or1k_elf_finish_dynamic_symbol
+
+#include "elf32-target.h"
diff --git a/bfd/elf32-pj.c b/bfd/elf32-pj.c
new file mode 100644
index 0000000..84b61f9
--- /dev/null
+++ b/bfd/elf32-pj.c
@@ -0,0 +1,352 @@
+/* picoJava specific support for 32-bit ELF
+ Copyright (C) 1999-2014 Free Software Foundation, Inc.
+ Contributed by Steve Chamberlan of Transmeta (sac@pobox.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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "bfdlink.h"
+#include "libbfd.h"
+#include "elf-bfd.h"
+#include "elf/pj.h"
+
+/* 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
+pj_elf_reloc (bfd *abfd,
+ arelent *reloc_entry,
+ asymbol *symbol_in,
+ void * data,
+ asection *input_section,
+ bfd *output_bfd,
+ char **error_message ATTRIBUTE_UNUSED)
+{
+ unsigned long insn;
+ bfd_vma sym_value;
+ enum elf_pj_reloc_type r_type;
+ bfd_vma addr = reloc_entry->address;
+ bfd_byte *hit_data = addr + (bfd_byte *) data;
+
+ r_type = (enum elf_pj_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;
+ }
+
+ 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_PJ_DATA_DIR32:
+ insn = bfd_get_32 (abfd, hit_data);
+ insn += sym_value + reloc_entry->addend;
+ bfd_put_32 (abfd, (bfd_vma) insn, hit_data);
+ break;
+
+ /* Relocations in code are always bigendian, no matter what the
+ data endianness is. */
+
+ case R_PJ_CODE_DIR32:
+ insn = bfd_getb32 (hit_data);
+ insn += sym_value + reloc_entry->addend;
+ bfd_putb32 ((bfd_vma) insn, hit_data);
+ break;
+
+ case R_PJ_CODE_REL16:
+ insn = bfd_getb16 (hit_data);
+ insn += sym_value + reloc_entry->addend
+ - (input_section->output_section->vma
+ + input_section->output_offset);
+ bfd_putb16 ((bfd_vma) insn, hit_data);
+ break;
+ case R_PJ_CODE_LO16:
+ insn = bfd_getb16 (hit_data);
+ insn += sym_value + reloc_entry->addend;
+ bfd_putb16 ((bfd_vma) insn, hit_data);
+ break;
+
+ case R_PJ_CODE_HI16:
+ insn = bfd_getb16 (hit_data);
+ insn += (sym_value + reloc_entry->addend) >> 16;
+ bfd_putb16 ((bfd_vma) insn, hit_data);
+ break;
+
+ default:
+ abort ();
+ break;
+ }
+
+ return bfd_reloc_ok;
+}
+
+static reloc_howto_type pj_elf_howto_table[] =
+{
+ /* No relocation. */
+ HOWTO (R_PJ_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 */
+ pj_elf_reloc, /* special_function */
+ "R_PJ_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_PJ_DATA_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 */
+ pj_elf_reloc, /* special_function */
+ "R_PJ_DIR32", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* 32 bit PC relative relocation. */
+ HOWTO (R_PJ_CODE_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 */
+ pj_elf_reloc, /* special_function */
+ "R_PJ_REL32", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+/* 16 bit PC relative relocation. */
+ HOWTO (R_PJ_CODE_REL16, /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overf6w */
+ pj_elf_reloc, /* special_function */
+ "R_PJ_REL16", /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+ EMPTY_HOWTO (4),
+ EMPTY_HOWTO (5),
+ HOWTO (R_PJ_CODE_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 */
+ pj_elf_reloc, /* special_function */
+ "R_PJ_CODE_DIR32", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ EMPTY_HOWTO (7),
+ EMPTY_HOWTO (8),
+ EMPTY_HOWTO (9),
+ EMPTY_HOWTO (10),
+ EMPTY_HOWTO (11),
+ EMPTY_HOWTO (12),
+
+ HOWTO (R_PJ_CODE_LO16, /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_unsigned, /* complain_on_overflow */
+ pj_elf_reloc, /* special_function */
+ "R_PJ_LO16", /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_PJ_CODE_HI16, /* type */
+ 16, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_unsigned, /* complain_on_overflow */
+ pj_elf_reloc, /* special_function */
+ "R_PJ_HI16", /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* GNU extension to record C++ vtable hierarchy. */
+ HOWTO (R_PJ_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_PJ_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_PJ_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_PJ_GNU_VTENTRY", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ FALSE), /* pcrel_offset */
+};
+
+/* This structure is used to map BFD reloc codes to PJ 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 PJ ELF relocs. */
+
+static const struct elf_reloc_map pj_reloc_map[] =
+{
+ { BFD_RELOC_NONE, R_PJ_NONE },
+ { BFD_RELOC_32, R_PJ_DATA_DIR32 },
+ { BFD_RELOC_PJ_CODE_DIR16, R_PJ_CODE_DIR16 },
+ { BFD_RELOC_PJ_CODE_DIR32, R_PJ_CODE_DIR32 },
+ { BFD_RELOC_PJ_CODE_LO16, R_PJ_CODE_LO16 },
+ { BFD_RELOC_PJ_CODE_HI16, R_PJ_CODE_HI16 },
+ { BFD_RELOC_PJ_CODE_REL32, R_PJ_CODE_REL32 },
+ { BFD_RELOC_PJ_CODE_REL16, R_PJ_CODE_REL16 },
+ { BFD_RELOC_VTABLE_INHERIT, R_PJ_GNU_VTINHERIT },
+ { BFD_RELOC_VTABLE_ENTRY, R_PJ_GNU_VTENTRY },
+};
+
+/* Given a BFD reloc code, return the howto structure for the
+ corresponding PJ ELf reloc. */
+
+static reloc_howto_type *
+pj_elf_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ bfd_reloc_code_real_type code)
+{
+ unsigned int i;
+
+ for (i = 0; i < sizeof (pj_reloc_map) / sizeof (struct elf_reloc_map); i++)
+ if (pj_reloc_map[i].bfd_reloc_val == code)
+ return & pj_elf_howto_table[(int) pj_reloc_map[i].elf_reloc_val];
+
+ return NULL;
+}
+
+static reloc_howto_type *
+pj_elf_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ const char *r_name)
+{
+ unsigned int i;
+
+ for (i = 0;
+ i < sizeof (pj_elf_howto_table) / sizeof (pj_elf_howto_table[0]);
+ i++)
+ if (pj_elf_howto_table[i].name != NULL
+ && strcasecmp (pj_elf_howto_table[i].name, r_name) == 0)
+ return &pj_elf_howto_table[i];
+
+ return NULL;
+}
+
+/* Given an ELF reloc, fill in the howto field of a relent. */
+
+static void
+pj_elf_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED,
+ arelent *cache_ptr,
+ Elf_Internal_Rela *dst)
+{
+ unsigned int r;
+
+ r = ELF32_R_TYPE (dst->r_info);
+
+ BFD_ASSERT (r < (unsigned int) R_PJ_max);
+
+ cache_ptr->howto = &pj_elf_howto_table[r];
+}
+
+/* Take this moment to fill in the special picoJava bits in the
+ e_flags field. */
+
+static void
+pj_elf_final_write_processing (bfd *abfd,
+ bfd_boolean linker ATTRIBUTE_UNUSED)
+{
+ elf_elfheader (abfd)->e_flags |= EF_PICOJAVA_ARCH;
+ elf_elfheader (abfd)->e_flags |= EF_PICOJAVA_GNUCALLS;
+}
+
+#define TARGET_BIG_SYM pj_elf32_vec
+#define TARGET_BIG_NAME "elf32-pj"
+#define TARGET_LITTLE_SYM pj_elf32_le_vec
+#define TARGET_LITTLE_NAME "elf32-pjl"
+#define ELF_ARCH bfd_arch_pj
+#define ELF_MACHINE_CODE EM_PJ
+#define ELF_MACHINE_ALT1 EM_PJ_OLD
+#define ELF_MAXPAGESIZE 0x1000
+#define bfd_elf32_bfd_get_relocated_section_contents \
+ bfd_generic_get_relocated_section_contents
+#define bfd_elf32_bfd_reloc_type_lookup pj_elf_reloc_type_lookup
+#define bfd_elf32_bfd_reloc_name_lookup pj_elf_reloc_name_lookup
+#define elf_backend_final_write_processing pj_elf_final_write_processing
+#define elf_info_to_howto pj_elf_info_to_howto
+#include "elf32-target.h"
diff --git a/bfd/elf32-ppc.c b/bfd/elf32-ppc.c
new file mode 100644
index 0000000..b4d2075
--- /dev/null
+++ b/bfd/elf32-ppc.c
@@ -0,0 +1,10521 @@
+/* PowerPC-specific support for 32-bit ELF
+ Copyright (C) 1994-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the
+ Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
+ Boston, MA 02110-1301, 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 "sysdep.h"
+#include <stdarg.h>
+#include "bfd.h"
+#include "bfdlink.h"
+#include "libbfd.h"
+#include "elf-bfd.h"
+#include "elf/ppc.h"
+#include "elf32-ppc.h"
+#include "elf-vxworks.h"
+#include "dwarf2.h"
+#include "elf-linux-psinfo.h"
+
+typedef enum split16_format_type
+{
+ split16a_type = 0,
+ split16d_type
+}
+split16_format_type;
+
+/* RELA relocations are used here. */
+
+static bfd_reloc_status_type ppc_elf_addr16_ha_reloc
+ (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
+static bfd_reloc_status_type ppc_elf_unhandled_reloc
+ (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
+
+/* Branch prediction bit for branch taken relocs. */
+#define BRANCH_PREDICT_BIT 0x200000
+/* Mask to set RA in memory instructions. */
+#define RA_REGISTER_MASK 0x001f0000
+/* Value to shift register by to insert RA. */
+#define RA_REGISTER_SHIFT 16
+
+/* The name of the dynamic interpreter. This is put in the .interp
+ section. */
+#define ELF_DYNAMIC_INTERPRETER "/usr/lib/ld.so.1"
+
+/* For old-style PLT. */
+/* The number of single-slot PLT entries (the rest use two slots). */
+#define PLT_NUM_SINGLE_ENTRIES 8192
+
+/* For new-style .glink and .plt. */
+#define GLINK_PLTRESOLVE 16*4
+#define GLINK_ENTRY_SIZE 4*4
+#define TLS_GET_ADDR_GLINK_SIZE 12*4
+
+/* VxWorks uses its own plt layout, filled in by the static linker. */
+
+/* The standard VxWorks PLT entry. */
+#define VXWORKS_PLT_ENTRY_SIZE 32
+static const bfd_vma ppc_elf_vxworks_plt_entry
+ [VXWORKS_PLT_ENTRY_SIZE / 4] =
+ {
+ 0x3d800000, /* lis r12,0 */
+ 0x818c0000, /* lwz r12,0(r12) */
+ 0x7d8903a6, /* mtctr r12 */
+ 0x4e800420, /* bctr */
+ 0x39600000, /* li r11,0 */
+ 0x48000000, /* b 14 <.PLT0resolve+0x4> */
+ 0x60000000, /* nop */
+ 0x60000000, /* nop */
+ };
+static const bfd_vma ppc_elf_vxworks_pic_plt_entry
+ [VXWORKS_PLT_ENTRY_SIZE / 4] =
+ {
+ 0x3d9e0000, /* addis r12,r30,0 */
+ 0x818c0000, /* lwz r12,0(r12) */
+ 0x7d8903a6, /* mtctr r12 */
+ 0x4e800420, /* bctr */
+ 0x39600000, /* li r11,0 */
+ 0x48000000, /* b 14 <.PLT0resolve+0x4> 14: R_PPC_REL24 .PLTresolve */
+ 0x60000000, /* nop */
+ 0x60000000, /* nop */
+ };
+
+/* The initial VxWorks PLT entry. */
+#define VXWORKS_PLT_INITIAL_ENTRY_SIZE 32
+static const bfd_vma ppc_elf_vxworks_plt0_entry
+ [VXWORKS_PLT_INITIAL_ENTRY_SIZE / 4] =
+ {
+ 0x3d800000, /* lis r12,0 */
+ 0x398c0000, /* addi r12,r12,0 */
+ 0x800c0008, /* lwz r0,8(r12) */
+ 0x7c0903a6, /* mtctr r0 */
+ 0x818c0004, /* lwz r12,4(r12) */
+ 0x4e800420, /* bctr */
+ 0x60000000, /* nop */
+ 0x60000000, /* nop */
+ };
+static const bfd_vma ppc_elf_vxworks_pic_plt0_entry
+ [VXWORKS_PLT_INITIAL_ENTRY_SIZE / 4] =
+ {
+ 0x819e0008, /* lwz r12,8(r30) */
+ 0x7d8903a6, /* mtctr r12 */
+ 0x819e0004, /* lwz r12,4(r30) */
+ 0x4e800420, /* bctr */
+ 0x60000000, /* nop */
+ 0x60000000, /* nop */
+ 0x60000000, /* nop */
+ 0x60000000, /* nop */
+ };
+
+/* For executables, we have some additional relocations in
+ .rela.plt.unloaded, for the kernel loader. */
+
+/* The number of non-JMP_SLOT relocations per PLT0 slot. */
+#define VXWORKS_PLT_NON_JMP_SLOT_RELOCS 3
+/* The number of relocations in the PLTResolve slot. */
+#define VXWORKS_PLTRESOLVE_RELOCS 2
+/* The number of relocations in the PLTResolve slot when when creating
+ a shared library. */
+#define VXWORKS_PLTRESOLVE_RELOCS_SHLIB 0
+
+/* Some instructions. */
+#define ADDIS_11_11 0x3d6b0000
+#define ADDIS_11_30 0x3d7e0000
+#define ADDIS_12_12 0x3d8c0000
+#define ADDI_11_11 0x396b0000
+#define ADD_0_11_11 0x7c0b5a14
+#define ADD_3_12_2 0x7c6c1214
+#define ADD_11_0_11 0x7d605a14
+#define B 0x48000000
+#define BA 0x48000002
+#define BCL_20_31 0x429f0005
+#define BCTR 0x4e800420
+#define BEQLR 0x4d820020
+#define CMPWI_11_0 0x2c0b0000
+#define LIS_11 0x3d600000
+#define LIS_12 0x3d800000
+#define LWZU_0_12 0x840c0000
+#define LWZ_0_12 0x800c0000
+#define LWZ_11_3 0x81630000
+#define LWZ_11_11 0x816b0000
+#define LWZ_11_30 0x817e0000
+#define LWZ_12_3 0x81830000
+#define LWZ_12_12 0x818c0000
+#define MR_0_3 0x7c601b78
+#define MR_3_0 0x7c030378
+#define MFLR_0 0x7c0802a6
+#define MFLR_12 0x7d8802a6
+#define MTCTR_0 0x7c0903a6
+#define MTCTR_11 0x7d6903a6
+#define MTLR_0 0x7c0803a6
+#define NOP 0x60000000
+#define SUB_11_11_12 0x7d6c5850
+
+/* Offset of tp and dtp pointers from start of TLS block. */
+#define TP_OFFSET 0x7000
+#define DTP_OFFSET 0x8000
+
+/* The value of a defined global symbol. */
+#define SYM_VAL(SYM) \
+ ((SYM)->root.u.def.section->output_section->vma \
+ + (SYM)->root.u.def.section->output_offset \
+ + (SYM)->root.u.def.value)
+
+static reloc_howto_type *ppc_elf_howto_table[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_dont, /* 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_dont, /* 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_signed, /* 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_signed, /* 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_signed, /* 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_signed, /* 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_dont, /* 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_dont, /* 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_dont, /* 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_dont, /* 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_dont, /* 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_dont, /* 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_dont, /* 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_dont, /* 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_dont, /* 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_dont, /* 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_dont, /* 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_dont, /* 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 */
+
+ /* 16-bit section relative relocation. */
+ HOWTO (R_PPC_SECTOFF, /* 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_SECTOFF", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* 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_dont, /* 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_dont, /* 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 */
+
+ /* Marker relocs for TLS. */
+ HOWTO (R_PPC_TLS,
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_PPC_TLS", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_PPC_TLSGD,
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_PPC_TLSGD", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_PPC_TLSLD,
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_PPC_TLSLD", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Computes the load module index of the load module that contains the
+ definition of its TLS sym. */
+ HOWTO (R_PPC_DTPMOD32,
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ ppc_elf_unhandled_reloc, /* special_function */
+ "R_PPC_DTPMOD32", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Computes a dtv-relative displacement, the difference between the value
+ of sym+add and the base address of the thread-local storage block that
+ contains the definition of sym, minus 0x8000. */
+ HOWTO (R_PPC_DTPREL32,
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ ppc_elf_unhandled_reloc, /* special_function */
+ "R_PPC_DTPREL32", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A 16 bit dtprel reloc. */
+ HOWTO (R_PPC_DTPREL16,
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ ppc_elf_unhandled_reloc, /* special_function */
+ "R_PPC_DTPREL16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Like DTPREL16, but no overflow. */
+ HOWTO (R_PPC_DTPREL16_LO,
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ ppc_elf_unhandled_reloc, /* special_function */
+ "R_PPC_DTPREL16_LO", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Like DTPREL16_LO, but next higher group of 16 bits. */
+ HOWTO (R_PPC_DTPREL16_HI,
+ 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_unhandled_reloc, /* special_function */
+ "R_PPC_DTPREL16_HI", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Like DTPREL16_HI, but adjust for low 16 bits. */
+ HOWTO (R_PPC_DTPREL16_HA,
+ 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_unhandled_reloc, /* special_function */
+ "R_PPC_DTPREL16_HA", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Computes a tp-relative displacement, the difference between the value of
+ sym+add and the value of the thread pointer (r13). */
+ HOWTO (R_PPC_TPREL32,
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ ppc_elf_unhandled_reloc, /* special_function */
+ "R_PPC_TPREL32", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A 16 bit tprel reloc. */
+ HOWTO (R_PPC_TPREL16,
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ ppc_elf_unhandled_reloc, /* special_function */
+ "R_PPC_TPREL16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Like TPREL16, but no overflow. */
+ HOWTO (R_PPC_TPREL16_LO,
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ ppc_elf_unhandled_reloc, /* special_function */
+ "R_PPC_TPREL16_LO", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Like TPREL16_LO, but next higher group of 16 bits. */
+ HOWTO (R_PPC_TPREL16_HI,
+ 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_unhandled_reloc, /* special_function */
+ "R_PPC_TPREL16_HI", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Like TPREL16_HI, but adjust for low 16 bits. */
+ HOWTO (R_PPC_TPREL16_HA,
+ 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_unhandled_reloc, /* special_function */
+ "R_PPC_TPREL16_HA", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Allocates two contiguous entries in the GOT to hold a tls_index structure,
+ with values (sym+add)@dtpmod and (sym+add)@dtprel, and computes the offset
+ to the first entry. */
+ HOWTO (R_PPC_GOT_TLSGD16,
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ ppc_elf_unhandled_reloc, /* special_function */
+ "R_PPC_GOT_TLSGD16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Like GOT_TLSGD16, but no overflow. */
+ HOWTO (R_PPC_GOT_TLSGD16_LO,
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ ppc_elf_unhandled_reloc, /* special_function */
+ "R_PPC_GOT_TLSGD16_LO", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Like GOT_TLSGD16_LO, but next higher group of 16 bits. */
+ HOWTO (R_PPC_GOT_TLSGD16_HI,
+ 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_unhandled_reloc, /* special_function */
+ "R_PPC_GOT_TLSGD16_HI", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Like GOT_TLSGD16_HI, but adjust for low 16 bits. */
+ HOWTO (R_PPC_GOT_TLSGD16_HA,
+ 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_unhandled_reloc, /* special_function */
+ "R_PPC_GOT_TLSGD16_HA", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Allocates two contiguous entries in the GOT to hold a tls_index structure,
+ with values (sym+add)@dtpmod and zero, and computes the offset to the
+ first entry. */
+ HOWTO (R_PPC_GOT_TLSLD16,
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ ppc_elf_unhandled_reloc, /* special_function */
+ "R_PPC_GOT_TLSLD16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Like GOT_TLSLD16, but no overflow. */
+ HOWTO (R_PPC_GOT_TLSLD16_LO,
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ ppc_elf_unhandled_reloc, /* special_function */
+ "R_PPC_GOT_TLSLD16_LO", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Like GOT_TLSLD16_LO, but next higher group of 16 bits. */
+ HOWTO (R_PPC_GOT_TLSLD16_HI,
+ 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_unhandled_reloc, /* special_function */
+ "R_PPC_GOT_TLSLD16_HI", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Like GOT_TLSLD16_HI, but adjust for low 16 bits. */
+ HOWTO (R_PPC_GOT_TLSLD16_HA,
+ 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_unhandled_reloc, /* special_function */
+ "R_PPC_GOT_TLSLD16_HA", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Allocates an entry in the GOT with value (sym+add)@dtprel, and computes
+ the offset to the entry. */
+ HOWTO (R_PPC_GOT_DTPREL16,
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ ppc_elf_unhandled_reloc, /* special_function */
+ "R_PPC_GOT_DTPREL16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Like GOT_DTPREL16, but no overflow. */
+ HOWTO (R_PPC_GOT_DTPREL16_LO,
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ ppc_elf_unhandled_reloc, /* special_function */
+ "R_PPC_GOT_DTPREL16_LO", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Like GOT_DTPREL16_LO, but next higher group of 16 bits. */
+ HOWTO (R_PPC_GOT_DTPREL16_HI,
+ 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_unhandled_reloc, /* special_function */
+ "R_PPC_GOT_DTPREL16_HI", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Like GOT_DTPREL16_HI, but adjust for low 16 bits. */
+ HOWTO (R_PPC_GOT_DTPREL16_HA,
+ 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_unhandled_reloc, /* special_function */
+ "R_PPC_GOT_DTPREL16_HA", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Allocates an entry in the GOT with value (sym+add)@tprel, and computes the
+ offset to the entry. */
+ HOWTO (R_PPC_GOT_TPREL16,
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ ppc_elf_unhandled_reloc, /* special_function */
+ "R_PPC_GOT_TPREL16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Like GOT_TPREL16, but no overflow. */
+ HOWTO (R_PPC_GOT_TPREL16_LO,
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ ppc_elf_unhandled_reloc, /* special_function */
+ "R_PPC_GOT_TPREL16_LO", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Like GOT_TPREL16_LO, but next higher group of 16 bits. */
+ HOWTO (R_PPC_GOT_TPREL16_HI,
+ 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_unhandled_reloc, /* special_function */
+ "R_PPC_GOT_TPREL16_HI", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Like GOT_TPREL16_HI, but adjust for low 16 bits. */
+ HOWTO (R_PPC_GOT_TPREL16_HA,
+ 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_unhandled_reloc, /* special_function */
+ "R_PPC_GOT_TPREL16_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_dont, /* 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_signed, /* 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_signed, /* 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_signed, /* 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 */
+ FALSE, /* 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 */
+
+ /* A relative 8 bit branch. */
+ HOWTO (R_PPC_VLE_REL8, /* 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_PPC_VLE_REL8", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* A relative 15 bit branch. */
+ HOWTO (R_PPC_VLE_REL15, /* type */
+ 1, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 15, /* bitsize */
+ TRUE, /* pc_relative */
+ 1, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_PPC_VLE_REL15", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xfe, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* A relative 24 bit branch. */
+ HOWTO (R_PPC_VLE_REL24, /* type */
+ 1, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 24, /* bitsize */
+ TRUE, /* pc_relative */
+ 1, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_PPC_VLE_REL24", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x1fffffe, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* The 16 LSBS in split16a format. */
+ HOWTO (R_PPC_VLE_LO16A, /* 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_PPC_VLE_LO16A", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x1f007ff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* The 16 LSBS in split16d format. */
+ HOWTO (R_PPC_VLE_LO16D, /* 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_PPC_VLE_LO16D", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x1f07ff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Bits 16-31 split16a format. */
+ HOWTO (R_PPC_VLE_HI16A, /* type */
+ 16, /* 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_PPC_VLE_HI16A", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x1f007ff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Bits 16-31 split16d format. */
+ HOWTO (R_PPC_VLE_HI16D, /* type */
+ 16, /* 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_PPC_VLE_HI16D", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x1f07ff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Bits 16-31 (High Adjusted) in split16a format. */
+ HOWTO (R_PPC_VLE_HA16A, /* type */
+ 16, /* 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_PPC_VLE_HA16A", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x1f007ff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Bits 16-31 (High Adjusted) in split16d format. */
+ HOWTO (R_PPC_VLE_HA16D, /* type */
+ 16, /* 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_PPC_VLE_HA16D", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x1f07ff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* This reloc is like R_PPC_EMB_SDA21 but only applies to e_add16i
+ instructions. If the register base is 0 then the linker changes
+ the e_add16i to an e_li instruction. */
+ HOWTO (R_PPC_VLE_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_VLE_SDA21", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Like R_PPC_VLE_SDA21 but ignore overflow. */
+ HOWTO (R_PPC_VLE_SDA21_LO, /* 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_PPC_VLE_SDA21_LO", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* The 16 LSBS relative to _SDA_BASE_ in split16a format. */
+ HOWTO (R_PPC_VLE_SDAREL_LO16A,/* 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_PPC_VLE_SDAREL_LO16A", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x1f007ff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* The 16 LSBS relative to _SDA_BASE_ in split16d format. */
+ HOWTO (R_PPC_VLE_SDAREL_LO16D, /* 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_PPC_VLE_SDAREL_LO16D", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x1f07ff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Bits 16-31 relative to _SDA_BASE_ in split16a format. */
+ HOWTO (R_PPC_VLE_SDAREL_HI16A, /* type */
+ 16, /* 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_PPC_VLE_SDAREL_HI16A", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x1f007ff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Bits 16-31 relative to _SDA_BASE_ in split16d format. */
+ HOWTO (R_PPC_VLE_SDAREL_HI16D, /* type */
+ 16, /* 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_PPC_VLE_SDAREL_HI16D", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x1f07ff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Bits 16-31 (HA) relative to _SDA_BASE split16a format. */
+ HOWTO (R_PPC_VLE_SDAREL_HA16A, /* type */
+ 16, /* 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_PPC_VLE_SDAREL_HA16A", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x1f007ff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Bits 16-31 (HA) relative to _SDA_BASE split16d format. */
+ HOWTO (R_PPC_VLE_SDAREL_HA16D, /* type */
+ 16, /* 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_PPC_VLE_SDAREL_HA16D", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x1f07ff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_PPC_IRELATIVE, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_PPC_IRELATIVE", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A 16 bit relative relocation. */
+ HOWTO (R_PPC_REL16, /* 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_REL16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* A 16 bit relative relocation without overflow. */
+ HOWTO (R_PPC_REL16_LO, /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_PPC_REL16_LO", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* The high order 16 bits of a relative address. */
+ HOWTO (R_PPC_REL16_HI, /* type */
+ 16, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_PPC_REL16_HI", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* The high order 16 bits of a relative address, plus 1 if the contents of
+ the low 16 bits, treated as a signed number, is negative. */
+ HOWTO (R_PPC_REL16_HA, /* type */
+ 16, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ ppc_elf_addr16_ha_reloc, /* special_function */
+ "R_PPC_REL16_HA", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ TRUE), /* 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 */
+};
+
+/* External 32-bit PPC structure for PRPSINFO. This structure is
+ ABI-defined, thus we choose to use char arrays here in order to
+ avoid dealing with different types in different architectures.
+
+ The PPC 32-bit structure uses int for `pr_uid' and `pr_gid' while
+ most non-PPC architectures use `short int'.
+
+ This structure will ultimately be written in the corefile's note
+ section, as the PRPSINFO. */
+
+struct elf_external_ppc_linux_prpsinfo32
+ {
+ char pr_state; /* Numeric process state. */
+ char pr_sname; /* Char for pr_state. */
+ char pr_zomb; /* Zombie. */
+ char pr_nice; /* Nice val. */
+ char pr_flag[4]; /* Flags. */
+ char pr_uid[4];
+ char pr_gid[4];
+ char pr_pid[4];
+ char pr_ppid[4];
+ char pr_pgrp[4];
+ char pr_sid[4];
+ char pr_fname[16]; /* Filename of executable. */
+ char pr_psargs[80]; /* Initial part of arg list. */
+ };
+
+/* Helper macro to swap (properly handling endianess) things from the
+ `elf_internal_prpsinfo' structure to the `elf_external_ppc_prpsinfo32'
+ structure.
+
+ Note that FROM should be a pointer, and TO should be the explicit type. */
+
+#define PPC_LINUX_PRPSINFO32_SWAP_FIELDS(abfd, from, to) \
+ do \
+ { \
+ H_PUT_8 (abfd, from->pr_state, &to.pr_state); \
+ H_PUT_8 (abfd, from->pr_sname, &to.pr_sname); \
+ H_PUT_8 (abfd, from->pr_zomb, &to.pr_zomb); \
+ H_PUT_8 (abfd, from->pr_nice, &to.pr_nice); \
+ H_PUT_32 (abfd, from->pr_flag, to.pr_flag); \
+ H_PUT_32 (abfd, from->pr_uid, to.pr_uid); \
+ H_PUT_32 (abfd, from->pr_gid, to.pr_gid); \
+ H_PUT_32 (abfd, from->pr_pid, to.pr_pid); \
+ H_PUT_32 (abfd, from->pr_ppid, to.pr_ppid); \
+ H_PUT_32 (abfd, from->pr_pgrp, to.pr_pgrp); \
+ H_PUT_32 (abfd, from->pr_sid, to.pr_sid); \
+ strncpy (to.pr_fname, from->pr_fname, sizeof (to.pr_fname)); \
+ strncpy (to.pr_psargs, from->pr_psargs, sizeof (to.pr_psargs)); \
+ } while (0)
+
+
+/* Initialize the ppc_elf_howto_table, so that linear accesses can be done. */
+
+static void
+ppc_elf_howto_init (void)
+{
+ 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;
+ if (type >= (sizeof (ppc_elf_howto_table)
+ / sizeof (ppc_elf_howto_table[0])))
+ abort ();
+ ppc_elf_howto_table[type] = &ppc_elf_howto_raw[i];
+ }
+}
+
+static reloc_howto_type *
+ppc_elf_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ bfd_reloc_code_real_type code)
+{
+ enum elf_ppc_reloc_type r;
+
+ /* Initialize howto table if not already done. */
+ if (!ppc_elf_howto_table[R_PPC_ADDR32])
+ ppc_elf_howto_init ();
+
+ switch (code)
+ {
+ default:
+ return NULL;
+
+ case BFD_RELOC_NONE: r = R_PPC_NONE; break;
+ case BFD_RELOC_32: r = R_PPC_ADDR32; break;
+ case BFD_RELOC_PPC_BA26: r = R_PPC_ADDR24; break;
+ case BFD_RELOC_PPC64_ADDR16_DS:
+ case BFD_RELOC_16: r = R_PPC_ADDR16; break;
+ case BFD_RELOC_PPC64_ADDR16_LO_DS:
+ case BFD_RELOC_LO16: r = R_PPC_ADDR16_LO; break;
+ case BFD_RELOC_HI16: r = R_PPC_ADDR16_HI; break;
+ case BFD_RELOC_HI16_S: r = R_PPC_ADDR16_HA; break;
+ case BFD_RELOC_PPC_BA16: r = R_PPC_ADDR14; break;
+ case BFD_RELOC_PPC_BA16_BRTAKEN: r = R_PPC_ADDR14_BRTAKEN; break;
+ case BFD_RELOC_PPC_BA16_BRNTAKEN: r = R_PPC_ADDR14_BRNTAKEN; break;
+ case BFD_RELOC_PPC_B26: r = R_PPC_REL24; break;
+ case BFD_RELOC_PPC_B16: r = R_PPC_REL14; break;
+ case BFD_RELOC_PPC_B16_BRTAKEN: r = R_PPC_REL14_BRTAKEN; break;
+ case BFD_RELOC_PPC_B16_BRNTAKEN: r = R_PPC_REL14_BRNTAKEN; break;
+ case BFD_RELOC_PPC64_GOT16_DS:
+ case BFD_RELOC_16_GOTOFF: r = R_PPC_GOT16; break;
+ case BFD_RELOC_PPC64_GOT16_LO_DS:
+ case BFD_RELOC_LO16_GOTOFF: r = R_PPC_GOT16_LO; break;
+ case BFD_RELOC_HI16_GOTOFF: r = R_PPC_GOT16_HI; break;
+ case BFD_RELOC_HI16_S_GOTOFF: r = R_PPC_GOT16_HA; break;
+ case BFD_RELOC_24_PLT_PCREL: r = R_PPC_PLTREL24; break;
+ case BFD_RELOC_PPC_COPY: r = R_PPC_COPY; break;
+ case BFD_RELOC_PPC_GLOB_DAT: r = R_PPC_GLOB_DAT; break;
+ case BFD_RELOC_PPC_LOCAL24PC: r = R_PPC_LOCAL24PC; break;
+ case BFD_RELOC_32_PCREL: r = R_PPC_REL32; break;
+ case BFD_RELOC_32_PLTOFF: r = R_PPC_PLT32; break;
+ case BFD_RELOC_32_PLT_PCREL: r = R_PPC_PLTREL32; break;
+ case BFD_RELOC_PPC64_PLT16_LO_DS:
+ case BFD_RELOC_LO16_PLTOFF: r = R_PPC_PLT16_LO; break;
+ case BFD_RELOC_HI16_PLTOFF: r = R_PPC_PLT16_HI; break;
+ case BFD_RELOC_HI16_S_PLTOFF: r = R_PPC_PLT16_HA; break;
+ case BFD_RELOC_GPREL16: r = R_PPC_SDAREL16; break;
+ case BFD_RELOC_PPC64_SECTOFF_DS:
+ case BFD_RELOC_16_BASEREL: r = R_PPC_SECTOFF; break;
+ case BFD_RELOC_PPC64_SECTOFF_LO_DS:
+ case BFD_RELOC_LO16_BASEREL: r = R_PPC_SECTOFF_LO; break;
+ case BFD_RELOC_HI16_BASEREL: r = R_PPC_SECTOFF_HI; break;
+ case BFD_RELOC_HI16_S_BASEREL: r = R_PPC_SECTOFF_HA; break;
+ case BFD_RELOC_CTOR: r = R_PPC_ADDR32; break;
+ case BFD_RELOC_PPC64_TOC16_DS:
+ case BFD_RELOC_PPC_TOC16: r = R_PPC_TOC16; break;
+ case BFD_RELOC_PPC_TLS: r = R_PPC_TLS; break;
+ case BFD_RELOC_PPC_TLSGD: r = R_PPC_TLSGD; break;
+ case BFD_RELOC_PPC_TLSLD: r = R_PPC_TLSLD; break;
+ case BFD_RELOC_PPC_DTPMOD: r = R_PPC_DTPMOD32; break;
+ case BFD_RELOC_PPC64_TPREL16_DS:
+ case BFD_RELOC_PPC_TPREL16: r = R_PPC_TPREL16; break;
+ case BFD_RELOC_PPC64_TPREL16_LO_DS:
+ case BFD_RELOC_PPC_TPREL16_LO: r = R_PPC_TPREL16_LO; break;
+ case BFD_RELOC_PPC_TPREL16_HI: r = R_PPC_TPREL16_HI; break;
+ case BFD_RELOC_PPC_TPREL16_HA: r = R_PPC_TPREL16_HA; break;
+ case BFD_RELOC_PPC_TPREL: r = R_PPC_TPREL32; break;
+ case BFD_RELOC_PPC64_DTPREL16_DS:
+ case BFD_RELOC_PPC_DTPREL16: r = R_PPC_DTPREL16; break;
+ case BFD_RELOC_PPC64_DTPREL16_LO_DS:
+ case BFD_RELOC_PPC_DTPREL16_LO: r = R_PPC_DTPREL16_LO; break;
+ case BFD_RELOC_PPC_DTPREL16_HI: r = R_PPC_DTPREL16_HI; break;
+ case BFD_RELOC_PPC_DTPREL16_HA: r = R_PPC_DTPREL16_HA; break;
+ case BFD_RELOC_PPC_DTPREL: r = R_PPC_DTPREL32; break;
+ case BFD_RELOC_PPC_GOT_TLSGD16: r = R_PPC_GOT_TLSGD16; break;
+ case BFD_RELOC_PPC_GOT_TLSGD16_LO: r = R_PPC_GOT_TLSGD16_LO; break;
+ case BFD_RELOC_PPC_GOT_TLSGD16_HI: r = R_PPC_GOT_TLSGD16_HI; break;
+ case BFD_RELOC_PPC_GOT_TLSGD16_HA: r = R_PPC_GOT_TLSGD16_HA; break;
+ case BFD_RELOC_PPC_GOT_TLSLD16: r = R_PPC_GOT_TLSLD16; break;
+ case BFD_RELOC_PPC_GOT_TLSLD16_LO: r = R_PPC_GOT_TLSLD16_LO; break;
+ case BFD_RELOC_PPC_GOT_TLSLD16_HI: r = R_PPC_GOT_TLSLD16_HI; break;
+ case BFD_RELOC_PPC_GOT_TLSLD16_HA: r = R_PPC_GOT_TLSLD16_HA; break;
+ case BFD_RELOC_PPC_GOT_TPREL16: r = R_PPC_GOT_TPREL16; break;
+ case BFD_RELOC_PPC_GOT_TPREL16_LO: r = R_PPC_GOT_TPREL16_LO; break;
+ case BFD_RELOC_PPC_GOT_TPREL16_HI: r = R_PPC_GOT_TPREL16_HI; break;
+ case BFD_RELOC_PPC_GOT_TPREL16_HA: r = R_PPC_GOT_TPREL16_HA; break;
+ case BFD_RELOC_PPC_GOT_DTPREL16: r = R_PPC_GOT_DTPREL16; break;
+ case BFD_RELOC_PPC_GOT_DTPREL16_LO: r = R_PPC_GOT_DTPREL16_LO; break;
+ case BFD_RELOC_PPC_GOT_DTPREL16_HI: r = R_PPC_GOT_DTPREL16_HI; break;
+ case BFD_RELOC_PPC_GOT_DTPREL16_HA: r = R_PPC_GOT_DTPREL16_HA; break;
+ case BFD_RELOC_PPC_EMB_NADDR32: r = R_PPC_EMB_NADDR32; break;
+ case BFD_RELOC_PPC_EMB_NADDR16: r = R_PPC_EMB_NADDR16; break;
+ case BFD_RELOC_PPC_EMB_NADDR16_LO: r = R_PPC_EMB_NADDR16_LO; break;
+ case BFD_RELOC_PPC_EMB_NADDR16_HI: r = R_PPC_EMB_NADDR16_HI; break;
+ case BFD_RELOC_PPC_EMB_NADDR16_HA: r = R_PPC_EMB_NADDR16_HA; break;
+ case BFD_RELOC_PPC_EMB_SDAI16: r = R_PPC_EMB_SDAI16; break;
+ case BFD_RELOC_PPC_EMB_SDA2I16: r = R_PPC_EMB_SDA2I16; break;
+ case BFD_RELOC_PPC_EMB_SDA2REL: r = R_PPC_EMB_SDA2REL; break;
+ case BFD_RELOC_PPC_EMB_SDA21: r = R_PPC_EMB_SDA21; break;
+ case BFD_RELOC_PPC_EMB_MRKREF: r = R_PPC_EMB_MRKREF; break;
+ case BFD_RELOC_PPC_EMB_RELSEC16: r = R_PPC_EMB_RELSEC16; break;
+ case BFD_RELOC_PPC_EMB_RELST_LO: r = R_PPC_EMB_RELST_LO; break;
+ case BFD_RELOC_PPC_EMB_RELST_HI: r = R_PPC_EMB_RELST_HI; break;
+ case BFD_RELOC_PPC_EMB_RELST_HA: r = R_PPC_EMB_RELST_HA; break;
+ case BFD_RELOC_PPC_EMB_BIT_FLD: r = R_PPC_EMB_BIT_FLD; break;
+ case BFD_RELOC_PPC_EMB_RELSDA: r = R_PPC_EMB_RELSDA; break;
+ case BFD_RELOC_PPC_VLE_REL8: r = R_PPC_VLE_REL8; break;
+ case BFD_RELOC_PPC_VLE_REL15: r = R_PPC_VLE_REL15; break;
+ case BFD_RELOC_PPC_VLE_REL24: r = R_PPC_VLE_REL24; break;
+ case BFD_RELOC_PPC_VLE_LO16A: r = R_PPC_VLE_LO16A; break;
+ case BFD_RELOC_PPC_VLE_LO16D: r = R_PPC_VLE_LO16D; break;
+ case BFD_RELOC_PPC_VLE_HI16A: r = R_PPC_VLE_HI16A; break;
+ case BFD_RELOC_PPC_VLE_HI16D: r = R_PPC_VLE_HI16D; break;
+ case BFD_RELOC_PPC_VLE_HA16A: r = R_PPC_VLE_HA16A; break;
+ case BFD_RELOC_PPC_VLE_HA16D: r = R_PPC_VLE_HA16D; break;
+ case BFD_RELOC_PPC_VLE_SDA21: r = R_PPC_VLE_SDA21; break;
+ case BFD_RELOC_PPC_VLE_SDA21_LO: r = R_PPC_VLE_SDA21_LO; break;
+ case BFD_RELOC_PPC_VLE_SDAREL_LO16A:
+ r = R_PPC_VLE_SDAREL_LO16A;
+ break;
+ case BFD_RELOC_PPC_VLE_SDAREL_LO16D:
+ r = R_PPC_VLE_SDAREL_LO16D;
+ break;
+ case BFD_RELOC_PPC_VLE_SDAREL_HI16A:
+ r = R_PPC_VLE_SDAREL_HI16A;
+ break;
+ case BFD_RELOC_PPC_VLE_SDAREL_HI16D:
+ r = R_PPC_VLE_SDAREL_HI16D;
+ break;
+ case BFD_RELOC_PPC_VLE_SDAREL_HA16A:
+ r = R_PPC_VLE_SDAREL_HA16A;
+ break;
+ case BFD_RELOC_PPC_VLE_SDAREL_HA16D:
+ r = R_PPC_VLE_SDAREL_HA16D;
+ break;
+ case BFD_RELOC_16_PCREL: r = R_PPC_REL16; break;
+ case BFD_RELOC_LO16_PCREL: r = R_PPC_REL16_LO; break;
+ case BFD_RELOC_HI16_PCREL: r = R_PPC_REL16_HI; break;
+ case BFD_RELOC_HI16_S_PCREL: r = R_PPC_REL16_HA; break;
+ case BFD_RELOC_VTABLE_INHERIT: r = R_PPC_GNU_VTINHERIT; break;
+ case BFD_RELOC_VTABLE_ENTRY: r = R_PPC_GNU_VTENTRY; break;
+ }
+
+ return ppc_elf_howto_table[r];
+};
+
+static reloc_howto_type *
+ppc_elf_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ const char *r_name)
+{
+ unsigned int i;
+
+ for (i = 0;
+ i < sizeof (ppc_elf_howto_raw) / sizeof (ppc_elf_howto_raw[0]);
+ i++)
+ if (ppc_elf_howto_raw[i].name != NULL
+ && strcasecmp (ppc_elf_howto_raw[i].name, r_name) == 0)
+ return &ppc_elf_howto_raw[i];
+
+ return NULL;
+}
+
+/* Set the howto pointer for a PowerPC ELF reloc. */
+
+static void
+ppc_elf_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED,
+ arelent *cache_ptr,
+ Elf_Internal_Rela *dst)
+{
+ /* Initialize howto table if not already done. */
+ if (!ppc_elf_howto_table[R_PPC_ADDR32])
+ 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)];
+
+ /* Just because the above assert didn't trigger doesn't mean that
+ ELF32_R_TYPE (dst->r_info) is necessarily a valid relocation. */
+ if (!cache_ptr->howto)
+ {
+ (*_bfd_error_handler) (_("%B: invalid relocation type %d"),
+ abfd, ELF32_R_TYPE (dst->r_info));
+ bfd_set_error (bfd_error_bad_value);
+
+ cache_ptr->howto = ppc_elf_howto_table[R_PPC_NONE];
+ }
+}
+
+/* Handle the R_PPC_ADDR16_HA and R_PPC_REL16_HA relocs. */
+
+static bfd_reloc_status_type
+ppc_elf_addr16_ha_reloc (bfd *abfd ATTRIBUTE_UNUSED,
+ arelent *reloc_entry,
+ asymbol *symbol,
+ void *data ATTRIBUTE_UNUSED,
+ asection *input_section,
+ bfd *output_bfd,
+ char **error_message ATTRIBUTE_UNUSED)
+{
+ bfd_vma relocation;
+
+ if (output_bfd != NULL)
+ {
+ reloc_entry->address += input_section->output_offset;
+ return bfd_reloc_ok;
+ }
+
+ if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
+ 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;
+ if (reloc_entry->howto->pc_relative)
+ relocation -= reloc_entry->address;
+
+ reloc_entry->addend += (relocation & 0x8000) << 1;
+
+ return bfd_reloc_continue;
+}
+
+static bfd_reloc_status_type
+ppc_elf_unhandled_reloc (bfd *abfd,
+ arelent *reloc_entry,
+ asymbol *symbol,
+ void *data,
+ asection *input_section,
+ bfd *output_bfd,
+ char **error_message)
+{
+ /* If this is a relocatable link (output_bfd test tells us), just
+ call the generic function. Any adjustment will be done at final
+ link time. */
+ if (output_bfd != NULL)
+ return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
+ input_section, output_bfd, error_message);
+
+ if (error_message != NULL)
+ {
+ static char buf[60];
+ sprintf (buf, _("generic linker can't handle %s"),
+ reloc_entry->howto->name);
+ *error_message = buf;
+ }
+ return bfd_reloc_dangerous;
+}
+
+/* Sections created by the linker. */
+
+typedef struct elf_linker_section
+{
+ /* Pointer to the bfd section. */
+ asection *section;
+ /* Section name. */
+ const char *name;
+ /* Associated bss section name. */
+ const char *bss_name;
+ /* Associated symbol name. */
+ const char *sym_name;
+ /* Associated symbol. */
+ struct elf_link_hash_entry *sym;
+} 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
+{
+ /* next allocated pointer for this symbol */
+ struct elf_linker_section_pointers *next;
+ /* offset of pointer from beginning of section */
+ bfd_vma offset;
+ /* addend used */
+ bfd_vma addend;
+ /* which linker section this is */
+ elf_linker_section_t *lsect;
+} elf_linker_section_pointers_t;
+
+struct ppc_elf_obj_tdata
+{
+ struct elf_obj_tdata elf;
+
+ /* 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;
+
+ /* Flags used to auto-detect plt type. */
+ unsigned int makes_plt_call : 1;
+ unsigned int has_rel16 : 1;
+};
+
+#define ppc_elf_tdata(bfd) \
+ ((struct ppc_elf_obj_tdata *) (bfd)->tdata.any)
+
+#define elf_local_ptr_offsets(bfd) \
+ (ppc_elf_tdata (bfd)->linker_section_pointers)
+
+#define is_ppc_elf(bfd) \
+ (bfd_get_flavour (bfd) == bfd_target_elf_flavour \
+ && elf_object_id (bfd) == PPC32_ELF_DATA)
+
+/* Override the generic function because we store some extras. */
+
+static bfd_boolean
+ppc_elf_mkobject (bfd *abfd)
+{
+ return bfd_elf_allocate_object (abfd, sizeof (struct ppc_elf_obj_tdata),
+ PPC32_ELF_DATA);
+}
+
+/* Fix bad default arch selected for a 32 bit input bfd when the
+ default is 64 bit. */
+
+static bfd_boolean
+ppc_elf_object_p (bfd *abfd)
+{
+ if (abfd->arch_info->the_default && abfd->arch_info->bits_per_word == 64)
+ {
+ Elf_Internal_Ehdr *i_ehdr = elf_elfheader (abfd);
+
+ if (i_ehdr->e_ident[EI_CLASS] == ELFCLASS32)
+ {
+ /* Relies on arch after 64 bit default being 32 bit default. */
+ abfd->arch_info = abfd->arch_info->next;
+ BFD_ASSERT (abfd->arch_info->bits_per_word == 32);
+ }
+ }
+ return TRUE;
+}
+
+/* Function to set whether a module needs the -mrelocatable bit set. */
+
+static bfd_boolean
+ppc_elf_set_private_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;
+}
+
+/* Support for core dump NOTE sections. */
+
+static bfd_boolean
+ppc_elf_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
+{
+ int offset;
+ unsigned int size;
+
+ switch (note->descsz)
+ {
+ default:
+ return FALSE;
+
+ case 268: /* Linux/PPC. */
+ /* pr_cursig */
+ elf_tdata (abfd)->core->signal = bfd_get_16 (abfd, note->descdata + 12);
+
+ /* pr_pid */
+ elf_tdata (abfd)->core->lwpid = bfd_get_32 (abfd, note->descdata + 24);
+
+ /* pr_reg */
+ offset = 72;
+ size = 192;
+
+ break;
+ }
+
+ /* Make a ".reg/999" section. */
+ return _bfd_elfcore_make_pseudosection (abfd, ".reg",
+ size, note->descpos + offset);
+}
+
+static bfd_boolean
+ppc_elf_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
+{
+ switch (note->descsz)
+ {
+ default:
+ return FALSE;
+
+ case 128: /* Linux/PPC elf_prpsinfo. */
+ elf_tdata (abfd)->core->pid
+ = bfd_get_32 (abfd, note->descdata + 16);
+ elf_tdata (abfd)->core->program
+ = _bfd_elfcore_strndup (abfd, note->descdata + 32, 16);
+ elf_tdata (abfd)->core->command
+ = _bfd_elfcore_strndup (abfd, note->descdata + 48, 80);
+ }
+
+ /* 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;
+}
+
+char *
+elfcore_write_ppc_linux_prpsinfo32 (bfd *abfd, char *buf, int *bufsiz,
+ const struct elf_internal_linux_prpsinfo *prpsinfo)
+{
+ struct elf_external_ppc_linux_prpsinfo32 data;
+
+ memset (&data, 0, sizeof (data));
+ PPC_LINUX_PRPSINFO32_SWAP_FIELDS (abfd, prpsinfo, data);
+
+ return elfcore_write_note (abfd, buf, bufsiz,
+ "CORE", NT_PRPSINFO, &data, sizeof (data));
+}
+
+static char *
+ppc_elf_write_core_note (bfd *abfd, char *buf, int *bufsiz, int note_type, ...)
+{
+ switch (note_type)
+ {
+ default:
+ return NULL;
+
+ case NT_PRPSINFO:
+ {
+ char data[128];
+ va_list ap;
+
+ va_start (ap, note_type);
+ memset (data, 0, sizeof (data));
+ strncpy (data + 32, va_arg (ap, const char *), 16);
+ strncpy (data + 48, va_arg (ap, const char *), 80);
+ va_end (ap);
+ return elfcore_write_note (abfd, buf, bufsiz,
+ "CORE", note_type, data, sizeof (data));
+ }
+
+ case NT_PRSTATUS:
+ {
+ char data[268];
+ va_list ap;
+ long pid;
+ int cursig;
+ const void *greg;
+
+ va_start (ap, note_type);
+ memset (data, 0, 72);
+ pid = va_arg (ap, long);
+ bfd_put_32 (abfd, pid, data + 24);
+ cursig = va_arg (ap, int);
+ bfd_put_16 (abfd, cursig, data + 12);
+ greg = va_arg (ap, const void *);
+ memcpy (data + 72, greg, 192);
+ memset (data + 264, 0, 4);
+ va_end (ap);
+ return elfcore_write_note (abfd, buf, bufsiz,
+ "CORE", note_type, data, sizeof (data));
+ }
+ }
+}
+
+static flagword
+ppc_elf_lookup_section_flags (char *flag_name)
+{
+
+ if (!strcmp (flag_name, "SHF_PPC_VLE"))
+ return SHF_PPC_VLE;
+
+ return 0;
+}
+
+/* Add the VLE flag if required. */
+
+bfd_boolean
+ppc_elf_section_processing (bfd *abfd, Elf_Internal_Shdr *shdr)
+{
+ if (bfd_get_mach (abfd) == bfd_mach_ppc_vle
+ && (shdr->sh_flags & SHF_EXECINSTR) != 0)
+ shdr->sh_flags |= SHF_PPC_VLE;
+
+ return TRUE;
+}
+
+/* Return address for Ith PLT stub in section PLT, for relocation REL
+ or (bfd_vma) -1 if it should not be included. */
+
+static bfd_vma
+ppc_elf_plt_sym_val (bfd_vma i ATTRIBUTE_UNUSED,
+ const asection *plt ATTRIBUTE_UNUSED,
+ const arelent *rel)
+{
+ return rel->address;
+}
+
+/* Handle a PowerPC specific section when reading an object file. This
+ is called when bfd_section_from_shdr finds a section with an unknown
+ type. */
+
+static bfd_boolean
+ppc_elf_section_from_shdr (bfd *abfd,
+ Elf_Internal_Shdr *hdr,
+ const char *name,
+ int shindex)
+{
+ asection *newsect;
+ flagword flags;
+
+ if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex))
+ 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 bfd_boolean
+ppc_elf_fake_sections (bfd *abfd ATTRIBUTE_UNUSED,
+ Elf_Internal_Shdr *shdr,
+ asection *asect)
+{
+ if ((asect->flags & SEC_SORT_ENTRIES) != 0)
+ shdr->sh_type = SHT_ORDERED;
+
+ return TRUE;
+}
+
+/* If we have .sbss2 or .PPC.EMB.sbss0 output sections, we
+ need to bump up the number of section headers. */
+
+static int
+ppc_elf_additional_program_headers (bfd *abfd,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED)
+{
+ asection *s;
+ int ret = 0;
+
+ s = bfd_get_section_by_name (abfd, ".sbss2");
+ if (s != NULL && (s->flags & SEC_ALLOC) != 0)
+ ++ret;
+
+ s = bfd_get_section_by_name (abfd, ".PPC.EMB.sbss0");
+ if (s != NULL && (s->flags & SEC_ALLOC) != 0)
+ ++ret;
+
+ return ret;
+}
+
+/* Modify the segment map for VLE executables. */
+
+bfd_boolean
+ppc_elf_modify_segment_map (bfd *abfd,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED)
+{
+ struct elf_segment_map *m, *n;
+ bfd_size_type amt;
+ unsigned int j, k;
+ bfd_boolean sect0_vle, sectj_vle;
+
+ /* At this point in the link, output sections have already been sorted by
+ LMA and assigned to segments. All that is left to do is to ensure
+ there is no mixing of VLE & non-VLE sections in a text segment.
+ If we find that case, we split the segment.
+ We maintain the original output section order. */
+
+ for (m = elf_seg_map (abfd); m != NULL; m = m->next)
+ {
+ if (m->count == 0)
+ continue;
+
+ sect0_vle = (elf_section_flags (m->sections[0]) & SHF_PPC_VLE) != 0;
+ for (j = 1; j < m->count; ++j)
+ {
+ sectj_vle = (elf_section_flags (m->sections[j]) & SHF_PPC_VLE) != 0;
+
+ if (sectj_vle != sect0_vle)
+ break;
+ }
+ if (j >= m->count)
+ continue;
+
+ /* sections 0..j-1 stay in this (current) segment,
+ the remainder are put in a new segment.
+ The scan resumes with the new segment. */
+
+ /* Fix the new segment. */
+ amt = sizeof (struct elf_segment_map);
+ amt += (m->count - j - 1) * sizeof (asection *);
+ n = (struct elf_segment_map *) bfd_zalloc (abfd, amt);
+ if (n == NULL)
+ return FALSE;
+
+ n->p_type = PT_LOAD;
+ n->p_flags = PF_X | PF_R;
+ if (sectj_vle)
+ n->p_flags |= PF_PPC_VLE;
+ n->count = m->count - j;
+ for (k = 0; k < n->count; ++k)
+ {
+ n->sections[k] = m->sections[j+k];
+ m->sections[j+k] = NULL;
+ }
+ n->next = m->next;
+ m->next = n;
+
+ /* Fix the current segment */
+ m->count = j;
+ }
+
+ return TRUE;
+}
+
+/* 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. */
+
+static const struct bfd_elf_special_section ppc_elf_special_sections[] =
+{
+ { STRING_COMMA_LEN (".plt"), 0, SHT_NOBITS, SHF_ALLOC + SHF_EXECINSTR },
+ { STRING_COMMA_LEN (".sbss"), -2, SHT_NOBITS, SHF_ALLOC + SHF_WRITE },
+ { STRING_COMMA_LEN (".sbss2"), -2, SHT_PROGBITS, SHF_ALLOC },
+ { STRING_COMMA_LEN (".sdata"), -2, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE },
+ { STRING_COMMA_LEN (".sdata2"), -2, SHT_PROGBITS, SHF_ALLOC },
+ { STRING_COMMA_LEN (".tags"), 0, SHT_ORDERED, SHF_ALLOC },
+ { STRING_COMMA_LEN (".PPC.EMB.apuinfo"), 0, SHT_NOTE, 0 },
+ { STRING_COMMA_LEN (".PPC.EMB.sbss0"), 0, SHT_PROGBITS, SHF_ALLOC },
+ { STRING_COMMA_LEN (".PPC.EMB.sdata0"), 0, SHT_PROGBITS, SHF_ALLOC },
+ { NULL, 0, 0, 0, 0 }
+};
+
+/* This is what we want for new plt/got. */
+static struct bfd_elf_special_section ppc_alt_plt =
+ { STRING_COMMA_LEN (".plt"), 0, SHT_PROGBITS, SHF_ALLOC };
+
+static const struct bfd_elf_special_section *
+ppc_elf_get_sec_type_attr (bfd *abfd ATTRIBUTE_UNUSED, asection *sec)
+{
+ const struct bfd_elf_special_section *ssect;
+
+ /* See if this is one of the special sections. */
+ if (sec->name == NULL)
+ return NULL;
+
+ ssect = _bfd_elf_get_special_section (sec->name, ppc_elf_special_sections,
+ sec->use_rela_p);
+ if (ssect != NULL)
+ {
+ if (ssect == ppc_elf_special_sections && (sec->flags & SEC_LOAD) != 0)
+ ssect = &ppc_alt_plt;
+ return ssect;
+ }
+
+ return _bfd_elf_get_sec_type_attr (abfd, sec);
+}
+
+/* Very simple linked list structure for recording apuinfo values. */
+typedef struct apuinfo_list
+{
+ struct apuinfo_list *next;
+ unsigned long value;
+}
+apuinfo_list;
+
+static apuinfo_list *head;
+static bfd_boolean apuinfo_set;
+
+static void
+apuinfo_list_init (void)
+{
+ head = NULL;
+ apuinfo_set = FALSE;
+}
+
+static void
+apuinfo_list_add (unsigned long value)
+{
+ apuinfo_list *entry = head;
+
+ while (entry != NULL)
+ {
+ if (entry->value == value)
+ return;
+ entry = entry->next;
+ }
+
+ entry = bfd_malloc (sizeof (* entry));
+ if (entry == NULL)
+ return;
+
+ entry->value = value;
+ entry->next = head;
+ head = entry;
+}
+
+static unsigned
+apuinfo_list_length (void)
+{
+ apuinfo_list *entry;
+ unsigned long count;
+
+ for (entry = head, count = 0;
+ entry;
+ entry = entry->next)
+ ++ count;
+
+ return count;
+}
+
+static inline unsigned long
+apuinfo_list_element (unsigned long number)
+{
+ apuinfo_list * entry;
+
+ for (entry = head;
+ entry && number --;
+ entry = entry->next)
+ ;
+
+ return entry ? entry->value : 0;
+}
+
+static void
+apuinfo_list_finish (void)
+{
+ apuinfo_list *entry;
+
+ for (entry = head; entry;)
+ {
+ apuinfo_list *next = entry->next;
+ free (entry);
+ entry = next;
+ }
+
+ head = NULL;
+}
+
+#define APUINFO_SECTION_NAME ".PPC.EMB.apuinfo"
+#define APUINFO_LABEL "APUinfo"
+
+/* Scan the input BFDs and create a linked list of
+ the APUinfo values that will need to be emitted. */
+
+static void
+ppc_elf_begin_write_processing (bfd *abfd, struct bfd_link_info *link_info)
+{
+ bfd *ibfd;
+ asection *asec;
+ char *buffer = NULL;
+ bfd_size_type largest_input_size = 0;
+ unsigned i;
+ unsigned long length;
+ const char *error_message = NULL;
+
+ if (link_info == NULL)
+ return;
+
+ apuinfo_list_init ();
+
+ /* Read in the input sections contents. */
+ for (ibfd = link_info->input_bfds; ibfd; ibfd = ibfd->link.next)
+ {
+ unsigned long datum;
+
+ asec = bfd_get_section_by_name (ibfd, APUINFO_SECTION_NAME);
+ if (asec == NULL)
+ continue;
+
+ error_message = _("corrupt %s section in %B");
+ length = asec->size;
+ if (length < 20)
+ goto fail;
+
+ apuinfo_set = TRUE;
+ if (largest_input_size < asec->size)
+ {
+ if (buffer)
+ free (buffer);
+ largest_input_size = asec->size;
+ buffer = bfd_malloc (largest_input_size);
+ if (!buffer)
+ return;
+ }
+
+ if (bfd_seek (ibfd, asec->filepos, SEEK_SET) != 0
+ || (bfd_bread (buffer, length, ibfd) != length))
+ {
+ error_message = _("unable to read in %s section from %B");
+ goto fail;
+ }
+
+ /* Verify the contents of the header. Note - we have to
+ extract the values this way in order to allow for a
+ host whose endian-ness is different from the target. */
+ datum = bfd_get_32 (ibfd, buffer);
+ if (datum != sizeof APUINFO_LABEL)
+ goto fail;
+
+ datum = bfd_get_32 (ibfd, buffer + 8);
+ if (datum != 0x2)
+ goto fail;
+
+ if (strcmp (buffer + 12, APUINFO_LABEL) != 0)
+ goto fail;
+
+ /* Get the number of bytes used for apuinfo entries. */
+ datum = bfd_get_32 (ibfd, buffer + 4);
+ if (datum + 20 != length)
+ goto fail;
+
+ /* Scan the apuinfo section, building a list of apuinfo numbers. */
+ for (i = 0; i < datum; i += 4)
+ apuinfo_list_add (bfd_get_32 (ibfd, buffer + 20 + i));
+ }
+
+ error_message = NULL;
+
+ if (apuinfo_set)
+ {
+ /* Compute the size of the output section. */
+ unsigned num_entries = apuinfo_list_length ();
+
+ /* Set the output section size, if it exists. */
+ asec = bfd_get_section_by_name (abfd, APUINFO_SECTION_NAME);
+
+ if (asec && ! bfd_set_section_size (abfd, asec, 20 + num_entries * 4))
+ {
+ ibfd = abfd;
+ error_message = _("warning: unable to set size of %s section in %B");
+ }
+ }
+
+ fail:
+ if (buffer)
+ free (buffer);
+
+ if (error_message)
+ (*_bfd_error_handler) (error_message, ibfd, APUINFO_SECTION_NAME);
+}
+
+/* Prevent the output section from accumulating the input sections'
+ contents. We have already stored this in our linked list structure. */
+
+static bfd_boolean
+ppc_elf_write_section (bfd *abfd ATTRIBUTE_UNUSED,
+ struct bfd_link_info *link_info ATTRIBUTE_UNUSED,
+ asection *asec,
+ bfd_byte *contents ATTRIBUTE_UNUSED)
+{
+ return apuinfo_set && strcmp (asec->name, APUINFO_SECTION_NAME) == 0;
+}
+
+/* Finally we can generate the output section. */
+
+static void
+ppc_elf_final_write_processing (bfd *abfd, bfd_boolean linker ATTRIBUTE_UNUSED)
+{
+ bfd_byte *buffer;
+ asection *asec;
+ unsigned i;
+ unsigned num_entries;
+ bfd_size_type length;
+
+ asec = bfd_get_section_by_name (abfd, APUINFO_SECTION_NAME);
+ if (asec == NULL)
+ return;
+
+ if (!apuinfo_set)
+ return;
+
+ length = asec->size;
+ if (length < 20)
+ return;
+
+ buffer = bfd_malloc (length);
+ if (buffer == NULL)
+ {
+ (*_bfd_error_handler)
+ (_("failed to allocate space for new APUinfo section."));
+ return;
+ }
+
+ /* Create the apuinfo header. */
+ num_entries = apuinfo_list_length ();
+ bfd_put_32 (abfd, sizeof APUINFO_LABEL, buffer);
+ bfd_put_32 (abfd, num_entries * 4, buffer + 4);
+ bfd_put_32 (abfd, 0x2, buffer + 8);
+ strcpy ((char *) buffer + 12, APUINFO_LABEL);
+
+ length = 20;
+ for (i = 0; i < num_entries; i++)
+ {
+ bfd_put_32 (abfd, apuinfo_list_element (i), buffer + length);
+ length += 4;
+ }
+
+ if (length != asec->size)
+ (*_bfd_error_handler) (_("failed to compute new APUinfo section."));
+
+ if (! bfd_set_section_contents (abfd, asec, buffer, (file_ptr) 0, length))
+ (*_bfd_error_handler) (_("failed to install new APUinfo section."));
+
+ free (buffer);
+
+ apuinfo_list_finish ();
+}
+
+static bfd_boolean
+is_nonpic_glink_stub (bfd *abfd, asection *glink, bfd_vma off)
+{
+ bfd_byte buf[GLINK_ENTRY_SIZE];
+
+ if (!bfd_get_section_contents (abfd, glink, buf, off, GLINK_ENTRY_SIZE))
+ return FALSE;
+
+ return ((bfd_get_32 (abfd, buf + 0) & 0xffff0000) == LIS_11
+ && (bfd_get_32 (abfd, buf + 4) & 0xffff0000) == LWZ_11_11
+ && bfd_get_32 (abfd, buf + 8) == MTCTR_11
+ && bfd_get_32 (abfd, buf + 12) == BCTR);
+}
+
+static bfd_boolean
+section_covers_vma (bfd *abfd ATTRIBUTE_UNUSED, asection *section, void *ptr)
+{
+ bfd_vma vma = *(bfd_vma *) ptr;
+ return ((section->flags & SEC_ALLOC) != 0
+ && section->vma <= vma
+ && vma < section->vma + section->size);
+}
+
+static long
+ppc_elf_get_synthetic_symtab (bfd *abfd, long symcount, asymbol **syms,
+ long dynsymcount, asymbol **dynsyms,
+ asymbol **ret)
+{
+ bfd_boolean (*slurp_relocs) (bfd *, asection *, asymbol **, bfd_boolean);
+ asection *plt, *relplt, *dynamic, *glink;
+ bfd_vma glink_vma = 0;
+ bfd_vma resolv_vma = 0;
+ bfd_vma stub_vma;
+ asymbol *s;
+ arelent *p;
+ long count, i;
+ size_t size;
+ char *names;
+ bfd_byte buf[4];
+
+ *ret = NULL;
+
+ if ((abfd->flags & (DYNAMIC | EXEC_P)) == 0)
+ return 0;
+
+ if (dynsymcount <= 0)
+ return 0;
+
+ relplt = bfd_get_section_by_name (abfd, ".rela.plt");
+ if (relplt == NULL)
+ return 0;
+
+ plt = bfd_get_section_by_name (abfd, ".plt");
+ if (plt == NULL)
+ return 0;
+
+ /* Call common code to handle old-style executable PLTs. */
+ if (elf_section_flags (plt) & SHF_EXECINSTR)
+ return _bfd_elf_get_synthetic_symtab (abfd, symcount, syms,
+ dynsymcount, dynsyms, ret);
+
+ /* If this object was prelinked, the prelinker stored the address
+ of .glink at got[1]. If it wasn't prelinked, got[1] will be zero. */
+ dynamic = bfd_get_section_by_name (abfd, ".dynamic");
+ if (dynamic != NULL)
+ {
+ bfd_byte *dynbuf, *extdyn, *extdynend;
+ size_t extdynsize;
+ void (*swap_dyn_in) (bfd *, const void *, Elf_Internal_Dyn *);
+
+ if (!bfd_malloc_and_get_section (abfd, dynamic, &dynbuf))
+ return -1;
+
+ 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 + dynamic->size;
+ for (; extdyn < extdynend; extdyn += extdynsize)
+ {
+ Elf_Internal_Dyn dyn;
+ (*swap_dyn_in) (abfd, extdyn, &dyn);
+
+ if (dyn.d_tag == DT_NULL)
+ break;
+
+ if (dyn.d_tag == DT_PPC_GOT)
+ {
+ unsigned int g_o_t = dyn.d_un.d_val;
+ asection *got = bfd_get_section_by_name (abfd, ".got");
+ if (got != NULL
+ && bfd_get_section_contents (abfd, got, buf,
+ g_o_t - got->vma + 4, 4))
+ glink_vma = bfd_get_32 (abfd, buf);
+ break;
+ }
+ }
+ free (dynbuf);
+ }
+
+ /* Otherwise we read the first plt entry. */
+ if (glink_vma == 0)
+ {
+ if (bfd_get_section_contents (abfd, plt, buf, 0, 4))
+ glink_vma = bfd_get_32 (abfd, buf);
+ }
+
+ if (glink_vma == 0)
+ return 0;
+
+ /* The .glink section usually does not survive the final
+ link; search for the section (usually .text) where the
+ glink stubs now reside. */
+ glink = bfd_sections_find_if (abfd, section_covers_vma, &glink_vma);
+ if (glink == NULL)
+ return 0;
+
+ /* Determine glink PLT resolver by reading the relative branch
+ from the first glink stub. */
+ if (bfd_get_section_contents (abfd, glink, buf,
+ glink_vma - glink->vma, 4))
+ {
+ unsigned int insn = bfd_get_32 (abfd, buf);
+
+ /* The first glink stub may either branch to the resolver ... */
+ insn ^= B;
+ if ((insn & ~0x3fffffc) == 0)
+ resolv_vma = glink_vma + (insn ^ 0x2000000) - 0x2000000;
+
+ /* ... or fall through a bunch of NOPs. */
+ else if ((insn ^ B ^ NOP) == 0)
+ for (i = 4;
+ bfd_get_section_contents (abfd, glink, buf,
+ glink_vma - glink->vma + i, 4);
+ i += 4)
+ if (bfd_get_32 (abfd, buf) != NOP)
+ {
+ resolv_vma = glink_vma + i;
+ break;
+ }
+ }
+
+ count = relplt->size / sizeof (Elf32_External_Rela);
+ stub_vma = glink_vma - (bfd_vma) count * 16;
+ /* If the stubs are those for -shared/-pie then we might have
+ multiple stubs for each plt entry. If that is the case then
+ there is no way to associate stubs with their plt entries short
+ of figuring out the GOT pointer value used in the stub. */
+ if (!is_nonpic_glink_stub (abfd, glink,
+ glink_vma - GLINK_ENTRY_SIZE - glink->vma))
+ return 0;
+
+ slurp_relocs = get_elf_backend_data (abfd)->s->slurp_reloc_table;
+ if (! (*slurp_relocs) (abfd, relplt, dynsyms, TRUE))
+ return -1;
+
+ size = count * sizeof (asymbol);
+ p = relplt->relocation;
+ for (i = 0; i < count; i++, p++)
+ {
+ size += strlen ((*p->sym_ptr_ptr)->name) + sizeof ("@plt");
+ if (p->addend != 0)
+ size += sizeof ("+0x") - 1 + 8;
+ }
+
+ size += sizeof (asymbol) + sizeof ("__glink");
+
+ if (resolv_vma)
+ size += sizeof (asymbol) + sizeof ("__glink_PLTresolve");
+
+ s = *ret = bfd_malloc (size);
+ if (s == NULL)
+ return -1;
+
+ names = (char *) (s + count + 1 + (resolv_vma != 0));
+ p = relplt->relocation;
+ for (i = 0; i < count; i++, p++)
+ {
+ size_t len;
+
+ *s = **p->sym_ptr_ptr;
+ /* Undefined syms won't have BSF_LOCAL or BSF_GLOBAL set. Since
+ we are defining a symbol, ensure one of them is set. */
+ if ((s->flags & BSF_LOCAL) == 0)
+ s->flags |= BSF_GLOBAL;
+ s->flags |= BSF_SYNTHETIC;
+ s->section = glink;
+ s->value = stub_vma - glink->vma;
+ s->name = names;
+ s->udata.p = NULL;
+ len = strlen ((*p->sym_ptr_ptr)->name);
+ memcpy (names, (*p->sym_ptr_ptr)->name, len);
+ names += len;
+ if (p->addend != 0)
+ {
+ memcpy (names, "+0x", sizeof ("+0x") - 1);
+ names += sizeof ("+0x") - 1;
+ bfd_sprintf_vma (abfd, names, p->addend);
+ names += strlen (names);
+ }
+ memcpy (names, "@plt", sizeof ("@plt"));
+ names += sizeof ("@plt");
+ ++s;
+ stub_vma += 16;
+ }
+
+ /* Add a symbol at the start of the glink branch table. */
+ memset (s, 0, sizeof *s);
+ s->the_bfd = abfd;
+ s->flags = BSF_GLOBAL | BSF_SYNTHETIC;
+ s->section = glink;
+ s->value = glink_vma - glink->vma;
+ s->name = names;
+ memcpy (names, "__glink", sizeof ("__glink"));
+ names += sizeof ("__glink");
+ s++;
+ count++;
+
+ if (resolv_vma)
+ {
+ /* Add a symbol for the glink PLT resolver. */
+ memset (s, 0, sizeof *s);
+ s->the_bfd = abfd;
+ s->flags = BSF_GLOBAL | BSF_SYNTHETIC;
+ s->section = glink;
+ s->value = resolv_vma - glink->vma;
+ s->name = names;
+ memcpy (names, "__glink_PLTresolve", sizeof ("__glink_PLTresolve"));
+ names += sizeof ("__glink_PLTresolve");
+ s++;
+ count++;
+ }
+
+ return count;
+}
+
+/* The following functions are specific to the ELF linker, while
+ functions above are used generally. They appear in this file more
+ or less in the order in which they are called. eg.
+ ppc_elf_check_relocs is called early in the link process,
+ ppc_elf_finish_dynamic_sections is one of the last functions
+ called. */
+
+/* Track PLT entries needed for a given symbol. We might need more
+ than one glink entry per symbol when generating a pic binary. */
+struct plt_entry
+{
+ struct plt_entry *next;
+
+ /* -fPIC uses multiple GOT sections, one per file, called ".got2".
+ This field stores the offset into .got2 used to initialise the
+ GOT pointer reg. It will always be at least 32768. (Current
+ gcc always uses an offset of 32768, but ld -r will pack .got2
+ sections together resulting in larger offsets). */
+ bfd_vma addend;
+
+ /* The .got2 section. */
+ asection *sec;
+
+ /* PLT refcount or offset. */
+ union
+ {
+ bfd_signed_vma refcount;
+ bfd_vma offset;
+ } plt;
+
+ /* .glink stub offset. */
+ bfd_vma glink_offset;
+};
+
+/* Of those relocs that might be copied as dynamic relocs, this function
+ selects those that must be copied when linking a shared library,
+ even when the symbol is local. */
+
+static int
+must_be_dyn_reloc (struct bfd_link_info *info,
+ enum elf_ppc_reloc_type r_type)
+{
+ switch (r_type)
+ {
+ default:
+ return 1;
+
+ case R_PPC_REL24:
+ case R_PPC_REL14:
+ case R_PPC_REL14_BRTAKEN:
+ case R_PPC_REL14_BRNTAKEN:
+ case R_PPC_REL32:
+ return 0;
+
+ case R_PPC_TPREL32:
+ case R_PPC_TPREL16:
+ case R_PPC_TPREL16_LO:
+ case R_PPC_TPREL16_HI:
+ case R_PPC_TPREL16_HA:
+ return !info->executable;
+ }
+}
+
+/* If ELIMINATE_COPY_RELOCS is non-zero, the linker will try to avoid
+ copying dynamic variables from a shared lib into an app's dynbss
+ section, and instead use a dynamic relocation to point into the
+ shared lib. */
+#define ELIMINATE_COPY_RELOCS 1
+
+/* Used to track dynamic relocations for local symbols. */
+struct ppc_dyn_relocs
+{
+ struct ppc_dyn_relocs *next;
+
+ /* The input section of the reloc. */
+ asection *sec;
+
+ /* Total number of relocs copied for the input section. */
+ unsigned int count : 31;
+
+ /* Whether this entry is for STT_GNU_IFUNC symbols. */
+ unsigned int ifunc : 1;
+};
+
+/* PPC ELF linker hash entry. */
+
+struct ppc_elf_link_hash_entry
+{
+ struct elf_link_hash_entry elf;
+
+ /* 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. */
+ elf_linker_section_pointers_t *linker_section_pointer;
+
+ /* Track dynamic relocs copied for this symbol. */
+ struct elf_dyn_relocs *dyn_relocs;
+
+ /* Contexts in which symbol is used in the GOT (or TOC).
+ TLS_GD .. TLS_TLS bits are or'd into the mask as the
+ corresponding relocs are encountered during check_relocs.
+ tls_optimize clears TLS_GD .. TLS_TPREL when optimizing to
+ indicate the corresponding GOT entry type is not needed. */
+#define TLS_GD 1 /* GD reloc. */
+#define TLS_LD 2 /* LD reloc. */
+#define TLS_TPREL 4 /* TPREL reloc, => IE. */
+#define TLS_DTPREL 8 /* DTPREL reloc, => LD. */
+#define TLS_TLS 16 /* Any TLS reloc. */
+#define TLS_TPRELGD 32 /* TPREL reloc resulting from GD->IE. */
+#define PLT_IFUNC 64 /* STT_GNU_IFUNC. */
+ char tls_mask;
+
+ /* Nonzero if we have seen a small data relocation referring to this
+ symbol. */
+ unsigned char has_sda_refs;
+};
+
+#define ppc_elf_hash_entry(ent) ((struct ppc_elf_link_hash_entry *) (ent))
+
+/* PPC ELF linker hash table. */
+
+struct ppc_elf_link_hash_table
+{
+ struct elf_link_hash_table elf;
+
+ /* Various options passed from the linker. */
+ struct ppc_elf_params *params;
+
+ /* Short-cuts to get to dynamic linker sections. */
+ asection *got;
+ asection *relgot;
+ asection *glink;
+ asection *plt;
+ asection *relplt;
+ asection *iplt;
+ asection *reliplt;
+ asection *dynbss;
+ asection *relbss;
+ asection *dynsbss;
+ asection *relsbss;
+ elf_linker_section_t sdata[2];
+ asection *sbss;
+ asection *glink_eh_frame;
+
+ /* The (unloaded but important) .rela.plt.unloaded on VxWorks. */
+ asection *srelplt2;
+
+ /* The .got.plt section (VxWorks only)*/
+ asection *sgotplt;
+
+ /* Shortcut to __tls_get_addr. */
+ struct elf_link_hash_entry *tls_get_addr;
+
+ /* The bfd that forced an old-style PLT. */
+ bfd *old_bfd;
+
+ /* TLS local dynamic got entry handling. */
+ union {
+ bfd_signed_vma refcount;
+ bfd_vma offset;
+ } tlsld_got;
+
+ /* Offset of branch table to PltResolve function in glink. */
+ bfd_vma glink_pltresolve;
+
+ /* Size of reserved GOT entries. */
+ unsigned int got_header_size;
+ /* Non-zero if allocating the header left a gap. */
+ unsigned int got_gap;
+
+ /* The type of PLT we have chosen to use. */
+ enum ppc_elf_plt_type plt_type;
+
+ /* True if the target system is VxWorks. */
+ unsigned int is_vxworks:1;
+
+ /* The size of PLT entries. */
+ int plt_entry_size;
+ /* The distance between adjacent PLT slots. */
+ int plt_slot_size;
+ /* The size of the first PLT entry. */
+ int plt_initial_entry_size;
+
+ /* Small local sym cache. */
+ struct sym_cache sym_cache;
+};
+
+/* Rename some of the generic section flags to better document how they
+ are used for ppc32. The flags are only valid for ppc32 elf objects. */
+
+/* Nonzero if this section has TLS related relocations. */
+#define has_tls_reloc sec_flg0
+
+/* Nonzero if this section has a call to __tls_get_addr. */
+#define has_tls_get_addr_call sec_flg1
+
+/* Get the PPC ELF linker hash table from a link_info structure. */
+
+#define ppc_elf_hash_table(p) \
+ (elf_hash_table_id ((struct elf_link_hash_table *) ((p)->hash)) \
+ == PPC32_ELF_DATA ? ((struct ppc_elf_link_hash_table *) ((p)->hash)) : NULL)
+
+/* Create an entry in a PPC ELF linker hash table. */
+
+static struct bfd_hash_entry *
+ppc_elf_link_hash_newfunc (struct bfd_hash_entry *entry,
+ struct bfd_hash_table *table,
+ const char *string)
+{
+ /* Allocate the structure if it has not already been allocated by a
+ subclass. */
+ if (entry == NULL)
+ {
+ entry = bfd_hash_allocate (table,
+ sizeof (struct ppc_elf_link_hash_entry));
+ if (entry == NULL)
+ return entry;
+ }
+
+ /* Call the allocation method of the superclass. */
+ entry = _bfd_elf_link_hash_newfunc (entry, table, string);
+ if (entry != NULL)
+ {
+ ppc_elf_hash_entry (entry)->linker_section_pointer = NULL;
+ ppc_elf_hash_entry (entry)->dyn_relocs = NULL;
+ ppc_elf_hash_entry (entry)->tls_mask = 0;
+ ppc_elf_hash_entry (entry)->has_sda_refs = 0;
+ }
+
+ return entry;
+}
+
+/* Create a PPC ELF linker hash table. */
+
+static struct bfd_link_hash_table *
+ppc_elf_link_hash_table_create (bfd *abfd)
+{
+ struct ppc_elf_link_hash_table *ret;
+ static struct ppc_elf_params default_params = { PLT_OLD, 0, 1, 0, 0, 12 };
+
+ ret = bfd_zmalloc (sizeof (struct ppc_elf_link_hash_table));
+ if (ret == NULL)
+ return NULL;
+
+ if (!_bfd_elf_link_hash_table_init (&ret->elf, abfd,
+ ppc_elf_link_hash_newfunc,
+ sizeof (struct ppc_elf_link_hash_entry),
+ PPC32_ELF_DATA))
+ {
+ free (ret);
+ return NULL;
+ }
+
+ ret->elf.init_plt_refcount.refcount = 0;
+ ret->elf.init_plt_refcount.glist = NULL;
+ ret->elf.init_plt_offset.offset = 0;
+ ret->elf.init_plt_offset.glist = NULL;
+
+ ret->params = &default_params;
+
+ ret->sdata[0].name = ".sdata";
+ ret->sdata[0].sym_name = "_SDA_BASE_";
+ ret->sdata[0].bss_name = ".sbss";
+
+ ret->sdata[1].name = ".sdata2";
+ ret->sdata[1].sym_name = "_SDA2_BASE_";
+ ret->sdata[1].bss_name = ".sbss2";
+
+ ret->plt_entry_size = 12;
+ ret->plt_slot_size = 8;
+ ret->plt_initial_entry_size = 72;
+
+ return &ret->elf.root;
+}
+
+/* Hook linker params into hash table. */
+
+void
+ppc_elf_link_params (struct bfd_link_info *info, struct ppc_elf_params *params)
+{
+ struct ppc_elf_link_hash_table *htab = ppc_elf_hash_table (info);
+
+ if (htab)
+ htab->params = params;
+}
+
+/* Create .got and the related sections. */
+
+static bfd_boolean
+ppc_elf_create_got (bfd *abfd, struct bfd_link_info *info)
+{
+ struct ppc_elf_link_hash_table *htab;
+ asection *s;
+ flagword flags;
+
+ if (!_bfd_elf_create_got_section (abfd, info))
+ return FALSE;
+
+ htab = ppc_elf_hash_table (info);
+ htab->got = s = bfd_get_linker_section (abfd, ".got");
+ if (s == NULL)
+ abort ();
+
+ if (htab->is_vxworks)
+ {
+ htab->sgotplt = bfd_get_linker_section (abfd, ".got.plt");
+ if (!htab->sgotplt)
+ abort ();
+ }
+ else
+ {
+ /* The powerpc .got has a blrl instruction in it. Mark it
+ executable. */
+ flags = (SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS
+ | SEC_IN_MEMORY | SEC_LINKER_CREATED);
+ if (!bfd_set_section_flags (abfd, s, flags))
+ return FALSE;
+ }
+
+ htab->relgot = bfd_get_linker_section (abfd, ".rela.got");
+ if (!htab->relgot)
+ abort ();
+
+ return TRUE;
+}
+
+/* Create a special linker section, used for R_PPC_EMB_SDAI16 and
+ R_PPC_EMB_SDA2I16 pointers. These sections become part of .sdata
+ and .sdata2. Create _SDA_BASE_ and _SDA2_BASE too. */
+
+static bfd_boolean
+ppc_elf_create_linker_section (bfd *abfd,
+ struct bfd_link_info *info,
+ flagword flags,
+ elf_linker_section_t *lsect)
+{
+ asection *s;
+
+ flags |= (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
+ | SEC_LINKER_CREATED);
+
+ s = bfd_make_section_anyway_with_flags (abfd, lsect->name, flags);
+ if (s == NULL)
+ return FALSE;
+ lsect->section = s;
+
+ /* Define the sym on the first section of this name. */
+ s = bfd_get_section_by_name (abfd, lsect->name);
+
+ lsect->sym = _bfd_elf_define_linkage_sym (abfd, info, s, lsect->sym_name);
+ if (lsect->sym == NULL)
+ return FALSE;
+ lsect->sym->root.u.def.value = 0x8000;
+ return TRUE;
+}
+
+static bfd_boolean
+ppc_elf_create_glink (bfd *abfd, struct bfd_link_info *info)
+{
+ struct ppc_elf_link_hash_table *htab = ppc_elf_hash_table (info);
+ asection *s;
+ flagword flags;
+
+ flags = (SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_READONLY | SEC_HAS_CONTENTS
+ | SEC_IN_MEMORY | SEC_LINKER_CREATED);
+ s = bfd_make_section_anyway_with_flags (abfd, ".glink", flags);
+ htab->glink = s;
+ if (s == NULL
+ || !bfd_set_section_alignment (abfd, s,
+ htab->params->ppc476_workaround ? 6 : 4))
+ return FALSE;
+
+ if (!info->no_ld_generated_unwind_info)
+ {
+ flags = (SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_HAS_CONTENTS
+ | SEC_IN_MEMORY | SEC_LINKER_CREATED);
+ s = bfd_make_section_anyway_with_flags (abfd, ".eh_frame", flags);
+ htab->glink_eh_frame = s;
+ if (s == NULL
+ || !bfd_set_section_alignment (abfd, s, 2))
+ return FALSE;
+ }
+
+ flags = SEC_ALLOC | SEC_LINKER_CREATED;
+ s = bfd_make_section_anyway_with_flags (abfd, ".iplt", flags);
+ htab->iplt = s;
+ if (s == NULL
+ || !bfd_set_section_alignment (abfd, s, 4))
+ return FALSE;
+
+ flags = (SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_HAS_CONTENTS
+ | SEC_IN_MEMORY | SEC_LINKER_CREATED);
+ s = bfd_make_section_anyway_with_flags (abfd, ".rela.iplt", flags);
+ htab->reliplt = s;
+ if (s == NULL
+ || ! bfd_set_section_alignment (abfd, s, 2))
+ return FALSE;
+
+ if (!ppc_elf_create_linker_section (abfd, info, 0,
+ &htab->sdata[0]))
+ return FALSE;
+
+ if (!ppc_elf_create_linker_section (abfd, info, SEC_READONLY,
+ &htab->sdata[1]))
+ return FALSE;
+
+ 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 bfd_boolean
+ppc_elf_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
+{
+ struct ppc_elf_link_hash_table *htab;
+ asection *s;
+ flagword flags;
+
+ htab = ppc_elf_hash_table (info);
+
+ if (htab->got == NULL
+ && !ppc_elf_create_got (abfd, info))
+ return FALSE;
+
+ if (!_bfd_elf_create_dynamic_sections (abfd, info))
+ return FALSE;
+
+ if (htab->glink == NULL
+ && !ppc_elf_create_glink (abfd, info))
+ return FALSE;
+
+ htab->dynbss = bfd_get_linker_section (abfd, ".dynbss");
+ s = bfd_make_section_anyway_with_flags (abfd, ".dynsbss",
+ SEC_ALLOC | SEC_LINKER_CREATED);
+ htab->dynsbss = s;
+ if (s == NULL)
+ return FALSE;
+
+ if (! info->shared)
+ {
+ htab->relbss = bfd_get_linker_section (abfd, ".rela.bss");
+ flags = (SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_HAS_CONTENTS
+ | SEC_IN_MEMORY | SEC_LINKER_CREATED);
+ s = bfd_make_section_anyway_with_flags (abfd, ".rela.sbss", flags);
+ htab->relsbss = s;
+ if (s == NULL
+ || ! bfd_set_section_alignment (abfd, s, 2))
+ return FALSE;
+ }
+
+ if (htab->is_vxworks
+ && !elf_vxworks_create_dynamic_sections (abfd, info, &htab->srelplt2))
+ return FALSE;
+
+ htab->relplt = bfd_get_linker_section (abfd, ".rela.plt");
+ htab->plt = s = bfd_get_linker_section (abfd, ".plt");
+ if (s == NULL)
+ abort ();
+
+ flags = SEC_ALLOC | SEC_CODE | SEC_LINKER_CREATED;
+ if (htab->plt_type == PLT_VXWORKS)
+ /* The VxWorks PLT is a loaded section with contents. */
+ flags |= SEC_HAS_CONTENTS | SEC_LOAD | SEC_READONLY;
+ return bfd_set_section_flags (abfd, s, flags);
+}
+
+/* Copy the extra info we tack onto an elf_link_hash_entry. */
+
+static void
+ppc_elf_copy_indirect_symbol (struct bfd_link_info *info,
+ struct elf_link_hash_entry *dir,
+ struct elf_link_hash_entry *ind)
+{
+ struct ppc_elf_link_hash_entry *edir, *eind;
+
+ edir = (struct ppc_elf_link_hash_entry *) dir;
+ eind = (struct ppc_elf_link_hash_entry *) ind;
+
+ edir->tls_mask |= eind->tls_mask;
+ edir->has_sda_refs |= eind->has_sda_refs;
+
+ /* If called to transfer flags for a weakdef during processing
+ of elf_adjust_dynamic_symbol, don't copy non_got_ref.
+ We clear it ourselves for ELIMINATE_COPY_RELOCS. */
+ if (!(ELIMINATE_COPY_RELOCS
+ && eind->elf.root.type != bfd_link_hash_indirect
+ && edir->elf.dynamic_adjusted))
+ edir->elf.non_got_ref |= eind->elf.non_got_ref;
+
+ edir->elf.ref_dynamic |= eind->elf.ref_dynamic;
+ edir->elf.ref_regular |= eind->elf.ref_regular;
+ edir->elf.ref_regular_nonweak |= eind->elf.ref_regular_nonweak;
+ edir->elf.needs_plt |= eind->elf.needs_plt;
+ edir->elf.pointer_equality_needed |= eind->elf.pointer_equality_needed;
+
+ if (eind->dyn_relocs != NULL)
+ {
+ if (edir->dyn_relocs != NULL)
+ {
+ struct elf_dyn_relocs **pp;
+ struct elf_dyn_relocs *p;
+
+ /* Add reloc counts against the indirect sym to the direct sym
+ list. Merge any entries against the same section. */
+ for (pp = &eind->dyn_relocs; (p = *pp) != NULL; )
+ {
+ struct elf_dyn_relocs *q;
+
+ for (q = edir->dyn_relocs; q != NULL; q = q->next)
+ if (q->sec == p->sec)
+ {
+ q->pc_count += p->pc_count;
+ q->count += p->count;
+ *pp = p->next;
+ break;
+ }
+ if (q == NULL)
+ pp = &p->next;
+ }
+ *pp = edir->dyn_relocs;
+ }
+
+ edir->dyn_relocs = eind->dyn_relocs;
+ eind->dyn_relocs = NULL;
+ }
+
+ /* If we were called to copy over info for a weak sym, that's all.
+ You might think dyn_relocs need not be copied over; After all,
+ both syms will be dynamic or both non-dynamic so we're just
+ moving reloc accounting around. However, ELIMINATE_COPY_RELOCS
+ code in ppc_elf_adjust_dynamic_symbol needs to check for
+ dyn_relocs in read-only sections, and it does so on what is the
+ DIR sym here. */
+ if (eind->elf.root.type != bfd_link_hash_indirect)
+ return;
+
+ /* Copy over the GOT refcount entries that we may have already seen to
+ the symbol which just became indirect. */
+ edir->elf.got.refcount += eind->elf.got.refcount;
+ eind->elf.got.refcount = 0;
+
+ /* And plt entries. */
+ if (eind->elf.plt.plist != NULL)
+ {
+ if (edir->elf.plt.plist != NULL)
+ {
+ struct plt_entry **entp;
+ struct plt_entry *ent;
+
+ for (entp = &eind->elf.plt.plist; (ent = *entp) != NULL; )
+ {
+ struct plt_entry *dent;
+
+ for (dent = edir->elf.plt.plist; dent != NULL; dent = dent->next)
+ if (dent->sec == ent->sec && dent->addend == ent->addend)
+ {
+ dent->plt.refcount += ent->plt.refcount;
+ *entp = ent->next;
+ break;
+ }
+ if (dent == NULL)
+ entp = &ent->next;
+ }
+ *entp = edir->elf.plt.plist;
+ }
+
+ edir->elf.plt.plist = eind->elf.plt.plist;
+ eind->elf.plt.plist = NULL;
+ }
+
+ if (eind->elf.dynindx != -1)
+ {
+ if (edir->elf.dynindx != -1)
+ _bfd_elf_strtab_delref (elf_hash_table (info)->dynstr,
+ edir->elf.dynstr_index);
+ edir->elf.dynindx = eind->elf.dynindx;
+ edir->elf.dynstr_index = eind->elf.dynstr_index;
+ eind->elf.dynindx = -1;
+ eind->elf.dynstr_index = 0;
+ }
+}
+
+/* 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 bfd_boolean
+ppc_elf_add_symbol_hook (bfd *abfd,
+ struct bfd_link_info *info,
+ Elf_Internal_Sym *sym,
+ const char **namep ATTRIBUTE_UNUSED,
+ flagword *flagsp ATTRIBUTE_UNUSED,
+ asection **secp,
+ bfd_vma *valp)
+{
+ if (sym->st_shndx == SHN_COMMON
+ && !info->relocatable
+ && is_ppc_elf (info->output_bfd)
+ && sym->st_size <= elf_gp_size (abfd))
+ {
+ /* Common symbols less than or equal to -G nn bytes are automatically
+ put into .sbss. */
+ struct ppc_elf_link_hash_table *htab;
+
+ htab = ppc_elf_hash_table (info);
+ if (htab->sbss == NULL)
+ {
+ flagword flags = SEC_IS_COMMON | SEC_LINKER_CREATED;
+
+ if (!htab->elf.dynobj)
+ htab->elf.dynobj = abfd;
+
+ htab->sbss = bfd_make_section_anyway_with_flags (htab->elf.dynobj,
+ ".sbss",
+ flags);
+ if (htab->sbss == NULL)
+ return FALSE;
+ }
+
+ *secp = htab->sbss;
+ *valp = sym->st_size;
+ }
+
+ if ((ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC
+ || ELF_ST_BIND (sym->st_info) == STB_GNU_UNIQUE)
+ && (abfd->flags & DYNAMIC) == 0
+ && bfd_get_flavour (info->output_bfd) == bfd_target_elf_flavour)
+ elf_tdata (info->output_bfd)->has_gnu_symbols = TRUE;
+
+ return TRUE;
+}
+
+/* Find a linker generated pointer with a given addend and type. */
+
+static elf_linker_section_pointers_t *
+elf_find_pointer_linker_section
+ (elf_linker_section_pointers_t *linker_pointers,
+ bfd_vma addend,
+ elf_linker_section_t *lsect)
+{
+ for ( ; linker_pointers != NULL; linker_pointers = linker_pointers->next)
+ if (lsect == linker_pointers->lsect && addend == linker_pointers->addend)
+ return linker_pointers;
+
+ return NULL;
+}
+
+/* Allocate a pointer to live in a linker created section. */
+
+static bfd_boolean
+elf_allocate_pointer_linker_section (bfd *abfd,
+ 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 = ELF32_R_SYM (rel->r_info);
+ bfd_size_type amt;
+
+ BFD_ASSERT (lsect != NULL);
+
+ /* Is this a global symbol? */
+ if (h != NULL)
+ {
+ struct ppc_elf_link_hash_entry *eh;
+
+ /* Has this symbol already been allocated? If so, our work is done. */
+ eh = (struct ppc_elf_link_hash_entry *) h;
+ if (elf_find_pointer_linker_section (eh->linker_section_pointer,
+ rel->r_addend,
+ lsect))
+ return TRUE;
+
+ ptr_linker_section_ptr = &eh->linker_section_pointer;
+ }
+ else
+ {
+ BFD_ASSERT (is_ppc_elf (abfd));
+
+ /* 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_symtab_hdr (abfd).sh_info;
+
+ amt = num_symbols;
+ amt *= sizeof (elf_linker_section_pointers_t *);
+ ptr = bfd_zalloc (abfd, amt);
+
+ if (!ptr)
+ return FALSE;
+
+ elf_local_ptr_offsets (abfd) = ptr;
+ }
+
+ /* Has this symbol already been allocated? If so, our work is done. */
+ if (elf_find_pointer_linker_section (ptr[r_symndx],
+ rel->r_addend,
+ lsect))
+ return TRUE;
+
+ ptr_linker_section_ptr = &ptr[r_symndx];
+ }
+
+ /* 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);
+ amt = sizeof (elf_linker_section_pointers_t);
+ linker_section_ptr = bfd_alloc (abfd, amt);
+
+ if (!linker_section_ptr)
+ return FALSE;
+
+ linker_section_ptr->next = *ptr_linker_section_ptr;
+ linker_section_ptr->addend = rel->r_addend;
+ linker_section_ptr->lsect = lsect;
+ *ptr_linker_section_ptr = linker_section_ptr;
+
+ if (!bfd_set_section_alignment (lsect->section->owner, lsect->section, 2))
+ return FALSE;
+ linker_section_ptr->offset = lsect->section->size;
+ lsect->section->size += 4;
+
+#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->size);
+#endif
+
+ return TRUE;
+}
+
+static struct plt_entry **
+update_local_sym_info (bfd *abfd,
+ Elf_Internal_Shdr *symtab_hdr,
+ unsigned long r_symndx,
+ int tls_type)
+{
+ bfd_signed_vma *local_got_refcounts = elf_local_got_refcounts (abfd);
+ struct plt_entry **local_plt;
+ char *local_got_tls_masks;
+
+ if (local_got_refcounts == NULL)
+ {
+ bfd_size_type size = symtab_hdr->sh_info;
+
+ size *= (sizeof (*local_got_refcounts)
+ + sizeof (*local_plt)
+ + sizeof (*local_got_tls_masks));
+ local_got_refcounts = bfd_zalloc (abfd, size);
+ if (local_got_refcounts == NULL)
+ return NULL;
+ elf_local_got_refcounts (abfd) = local_got_refcounts;
+ }
+
+ local_plt = (struct plt_entry **) (local_got_refcounts + symtab_hdr->sh_info);
+ local_got_tls_masks = (char *) (local_plt + symtab_hdr->sh_info);
+ local_got_tls_masks[r_symndx] |= tls_type;
+ if (tls_type != PLT_IFUNC)
+ local_got_refcounts[r_symndx] += 1;
+ return local_plt + r_symndx;
+}
+
+static bfd_boolean
+update_plt_info (bfd *abfd, struct plt_entry **plist,
+ asection *sec, bfd_vma addend)
+{
+ struct plt_entry *ent;
+
+ if (addend < 32768)
+ sec = NULL;
+ for (ent = *plist; ent != NULL; ent = ent->next)
+ if (ent->sec == sec && ent->addend == addend)
+ break;
+ if (ent == NULL)
+ {
+ bfd_size_type amt = sizeof (*ent);
+ ent = bfd_alloc (abfd, amt);
+ if (ent == NULL)
+ return FALSE;
+ ent->next = *plist;
+ ent->sec = sec;
+ ent->addend = addend;
+ ent->plt.refcount = 0;
+ *plist = ent;
+ }
+ ent->plt.refcount += 1;
+ return TRUE;
+}
+
+static struct plt_entry *
+find_plt_ent (struct plt_entry **plist, asection *sec, bfd_vma addend)
+{
+ struct plt_entry *ent;
+
+ if (addend < 32768)
+ sec = NULL;
+ for (ent = *plist; ent != NULL; ent = ent->next)
+ if (ent->sec == sec && ent->addend == addend)
+ break;
+ return ent;
+}
+
+static bfd_boolean
+is_branch_reloc (enum elf_ppc_reloc_type r_type)
+{
+ return (r_type == R_PPC_PLTREL24
+ || r_type == R_PPC_LOCAL24PC
+ || r_type == R_PPC_REL24
+ || r_type == R_PPC_REL14
+ || r_type == R_PPC_REL14_BRTAKEN
+ || r_type == R_PPC_REL14_BRNTAKEN
+ || r_type == R_PPC_ADDR24
+ || r_type == R_PPC_ADDR14
+ || r_type == R_PPC_ADDR14_BRTAKEN
+ || r_type == R_PPC_ADDR14_BRNTAKEN);
+}
+
+static void
+bad_shared_reloc (bfd *abfd, enum elf_ppc_reloc_type r_type)
+{
+ (*_bfd_error_handler)
+ (_("%B: relocation %s cannot be used when making a shared object"),
+ abfd,
+ ppc_elf_howto_table[r_type]->name);
+ bfd_set_error (bfd_error_bad_value);
+}
+
+/* Look through the relocs for a section during the first phase, and
+ allocate space in the global offset table or procedure linkage
+ table. */
+
+static bfd_boolean
+ppc_elf_check_relocs (bfd *abfd,
+ struct bfd_link_info *info,
+ asection *sec,
+ const Elf_Internal_Rela *relocs)
+{
+ struct ppc_elf_link_hash_table *htab;
+ Elf_Internal_Shdr *symtab_hdr;
+ struct elf_link_hash_entry **sym_hashes;
+ const Elf_Internal_Rela *rel;
+ const Elf_Internal_Rela *rel_end;
+ asection *got2, *sreloc;
+ struct elf_link_hash_entry *tga;
+
+ if (info->relocatable)
+ return TRUE;
+
+ /* Don't do anything special with non-loaded, non-alloced sections.
+ In particular, any relocs in such sections should not affect GOT
+ and PLT reference counting (ie. we don't allow them to create GOT
+ or PLT entries), there's no possibility or desire to optimize TLS
+ relocs, and there's not much point in propagating relocs to shared
+ libs that the dynamic linker won't relocate. */
+ if ((sec->flags & SEC_ALLOC) == 0)
+ return TRUE;
+
+#ifdef DEBUG
+ _bfd_error_handler ("ppc_elf_check_relocs called for section %A in %B",
+ sec, abfd);
+#endif
+
+ BFD_ASSERT (is_ppc_elf (abfd));
+
+ /* Initialize howto table if not already done. */
+ if (!ppc_elf_howto_table[R_PPC_ADDR32])
+ ppc_elf_howto_init ();
+
+ htab = ppc_elf_hash_table (info);
+ if (htab->glink == NULL)
+ {
+ if (htab->elf.dynobj == NULL)
+ htab->elf.dynobj = abfd;
+ if (!ppc_elf_create_glink (htab->elf.dynobj, info))
+ return FALSE;
+ }
+ tga = elf_link_hash_lookup (&htab->elf, "__tls_get_addr",
+ FALSE, FALSE, TRUE);
+ symtab_hdr = &elf_symtab_hdr (abfd);
+ sym_hashes = elf_sym_hashes (abfd);
+ got2 = bfd_get_section_by_name (abfd, ".got2");
+ sreloc = NULL;
+
+ rel_end = relocs + sec->reloc_count;
+ for (rel = relocs; rel < rel_end; rel++)
+ {
+ unsigned long r_symndx;
+ enum elf_ppc_reloc_type r_type;
+ struct elf_link_hash_entry *h;
+ int tls_type;
+
+ 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];
+ 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;
+
+ /* PR15323, ref flags aren't set for references in the same
+ object. */
+ h->root.non_ir_ref = 1;
+ }
+
+ /* 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 != NULL
+ && htab->got == NULL
+ && strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0)
+ {
+ if (htab->elf.dynobj == NULL)
+ htab->elf.dynobj = abfd;
+ if (!ppc_elf_create_got (htab->elf.dynobj, info))
+ return FALSE;
+ BFD_ASSERT (h == htab->elf.hgot);
+ }
+
+ tls_type = 0;
+ r_type = ELF32_R_TYPE (rel->r_info);
+ if (h == NULL && !htab->is_vxworks)
+ {
+ Elf_Internal_Sym *isym = bfd_sym_from_r_symndx (&htab->sym_cache,
+ abfd, r_symndx);
+ if (isym == NULL)
+ return FALSE;
+
+ if (ELF_ST_TYPE (isym->st_info) == STT_GNU_IFUNC)
+ {
+ struct plt_entry **ifunc;
+
+ /* Set PLT_IFUNC flag for this sym, no GOT entry yet. */
+ ifunc = update_local_sym_info (abfd, symtab_hdr, r_symndx,
+ PLT_IFUNC);
+ if (ifunc == NULL)
+ return FALSE;
+
+ /* STT_GNU_IFUNC symbols must have a PLT entry;
+ In a non-pie executable even when there are
+ no plt calls. */
+ if (!info->shared
+ || is_branch_reloc (r_type))
+ {
+ bfd_vma addend = 0;
+ if (r_type == R_PPC_PLTREL24)
+ {
+ ppc_elf_tdata (abfd)->makes_plt_call = 1;
+ if (info->shared)
+ addend = rel->r_addend;
+ }
+ if (!update_plt_info (abfd, ifunc, got2, addend))
+ return FALSE;
+ }
+ }
+ }
+
+ if (!htab->is_vxworks
+ && is_branch_reloc (r_type)
+ && h != NULL
+ && h == tga)
+ {
+ if (rel != relocs
+ && (ELF32_R_TYPE (rel[-1].r_info) == R_PPC_TLSGD
+ || ELF32_R_TYPE (rel[-1].r_info) == R_PPC_TLSLD))
+ /* We have a new-style __tls_get_addr call with a marker
+ reloc. */
+ ;
+ else
+ /* Mark this section as having an old-style call. */
+ sec->has_tls_get_addr_call = 1;
+ }
+
+ switch (r_type)
+ {
+ case R_PPC_TLSGD:
+ case R_PPC_TLSLD:
+ /* These special tls relocs tie a call to __tls_get_addr with
+ its parameter symbol. */
+ break;
+
+ case R_PPC_GOT_TLSLD16:
+ case R_PPC_GOT_TLSLD16_LO:
+ case R_PPC_GOT_TLSLD16_HI:
+ case R_PPC_GOT_TLSLD16_HA:
+ tls_type = TLS_TLS | TLS_LD;
+ goto dogottls;
+
+ case R_PPC_GOT_TLSGD16:
+ case R_PPC_GOT_TLSGD16_LO:
+ case R_PPC_GOT_TLSGD16_HI:
+ case R_PPC_GOT_TLSGD16_HA:
+ tls_type = TLS_TLS | TLS_GD;
+ goto dogottls;
+
+ case R_PPC_GOT_TPREL16:
+ case R_PPC_GOT_TPREL16_LO:
+ case R_PPC_GOT_TPREL16_HI:
+ case R_PPC_GOT_TPREL16_HA:
+ if (info->shared)
+ info->flags |= DF_STATIC_TLS;
+ tls_type = TLS_TLS | TLS_TPREL;
+ goto dogottls;
+
+ case R_PPC_GOT_DTPREL16:
+ case R_PPC_GOT_DTPREL16_LO:
+ case R_PPC_GOT_DTPREL16_HI:
+ case R_PPC_GOT_DTPREL16_HA:
+ tls_type = TLS_TLS | TLS_DTPREL;
+ dogottls:
+ sec->has_tls_reloc = 1;
+ /* Fall thru */
+
+ /* 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 (htab->got == NULL)
+ {
+ if (htab->elf.dynobj == NULL)
+ htab->elf.dynobj = abfd;
+ if (!ppc_elf_create_got (htab->elf.dynobj, info))
+ return FALSE;
+ }
+ if (h != NULL)
+ {
+ h->got.refcount += 1;
+ ppc_elf_hash_entry (h)->tls_mask |= tls_type;
+ }
+ else
+ /* This is a global offset table entry for a local symbol. */
+ if (!update_local_sym_info (abfd, symtab_hdr, r_symndx, tls_type))
+ return FALSE;
+
+ /* We may also need a plt entry if the symbol turns out to be
+ an ifunc. */
+ if (h != NULL && !info->shared)
+ {
+ if (!update_plt_info (abfd, &h->plt.plist, NULL, 0))
+ return FALSE;
+ }
+ break;
+
+ /* Indirect .sdata relocation. */
+ case R_PPC_EMB_SDAI16:
+ if (info->shared)
+ {
+ bad_shared_reloc (abfd, r_type);
+ return FALSE;
+ }
+ htab->sdata[0].sym->ref_regular = 1;
+ if (!elf_allocate_pointer_linker_section (abfd, &htab->sdata[0],
+ h, rel))
+ return FALSE;
+ if (h != NULL)
+ {
+ ppc_elf_hash_entry (h)->has_sda_refs = TRUE;
+ h->non_got_ref = TRUE;
+ }
+ break;
+
+ /* Indirect .sdata2 relocation. */
+ case R_PPC_EMB_SDA2I16:
+ if (info->shared)
+ {
+ bad_shared_reloc (abfd, r_type);
+ return FALSE;
+ }
+ htab->sdata[1].sym->ref_regular = 1;
+ if (!elf_allocate_pointer_linker_section (abfd, &htab->sdata[1],
+ h, rel))
+ return FALSE;
+ if (h != NULL)
+ {
+ ppc_elf_hash_entry (h)->has_sda_refs = TRUE;
+ h->non_got_ref = TRUE;
+ }
+ break;
+
+ case R_PPC_SDAREL16:
+ htab->sdata[0].sym->ref_regular = 1;
+ /* Fall thru */
+
+ case R_PPC_VLE_SDAREL_LO16A:
+ case R_PPC_VLE_SDAREL_LO16D:
+ case R_PPC_VLE_SDAREL_HI16A:
+ case R_PPC_VLE_SDAREL_HI16D:
+ case R_PPC_VLE_SDAREL_HA16A:
+ case R_PPC_VLE_SDAREL_HA16D:
+ if (h != NULL)
+ {
+ ppc_elf_hash_entry (h)->has_sda_refs = TRUE;
+ h->non_got_ref = TRUE;
+ }
+ break;
+
+ case R_PPC_VLE_REL8:
+ case R_PPC_VLE_REL15:
+ case R_PPC_VLE_REL24:
+ case R_PPC_VLE_LO16A:
+ case R_PPC_VLE_LO16D:
+ case R_PPC_VLE_HI16A:
+ case R_PPC_VLE_HI16D:
+ case R_PPC_VLE_HA16A:
+ case R_PPC_VLE_HA16D:
+ break;
+
+ case R_PPC_EMB_SDA2REL:
+ if (info->shared)
+ {
+ bad_shared_reloc (abfd, r_type);
+ return FALSE;
+ }
+ htab->sdata[1].sym->ref_regular = 1;
+ if (h != NULL)
+ {
+ ppc_elf_hash_entry (h)->has_sda_refs = TRUE;
+ h->non_got_ref = TRUE;
+ }
+ break;
+
+ case R_PPC_VLE_SDA21_LO:
+ case R_PPC_VLE_SDA21:
+ case R_PPC_EMB_SDA21:
+ case R_PPC_EMB_RELSDA:
+ if (info->shared)
+ {
+ bad_shared_reloc (abfd, r_type);
+ return FALSE;
+ }
+ if (h != NULL)
+ {
+ ppc_elf_hash_entry (h)->has_sda_refs = TRUE;
+ h->non_got_ref = TRUE;
+ }
+ break;
+
+ case R_PPC_EMB_NADDR32:
+ case R_PPC_EMB_NADDR16:
+ case R_PPC_EMB_NADDR16_LO:
+ case R_PPC_EMB_NADDR16_HI:
+ case R_PPC_EMB_NADDR16_HA:
+ if (info->shared)
+ {
+ bad_shared_reloc (abfd, r_type);
+ return FALSE;
+ }
+ if (h != NULL)
+ h->non_got_ref = TRUE;
+ break;
+
+ case R_PPC_PLTREL24:
+ if (h == NULL)
+ break;
+ /* Fall through */
+ case R_PPC_PLT32:
+ case R_PPC_PLTREL32:
+ 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 finish_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. */
+ info->callbacks->einfo (_("%P: %H: %s reloc against local symbol\n"),
+ abfd, sec, rel->r_offset,
+ ppc_elf_howto_table[r_type]->name);
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+ else
+ {
+ bfd_vma addend = 0;
+
+ if (r_type == R_PPC_PLTREL24)
+ {
+ ppc_elf_tdata (abfd)->makes_plt_call = 1;
+ if (info->shared)
+ addend = rel->r_addend;
+ }
+ h->needs_plt = 1;
+ if (!update_plt_info (abfd, &h->plt.plist, got2, addend))
+ return FALSE;
+ }
+ 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:
+ case R_PPC_DTPREL16:
+ case R_PPC_DTPREL16_LO:
+ case R_PPC_DTPREL16_HI:
+ case R_PPC_DTPREL16_HA:
+ case R_PPC_TOC16:
+ break;
+
+ case R_PPC_REL16:
+ case R_PPC_REL16_LO:
+ case R_PPC_REL16_HI:
+ case R_PPC_REL16_HA:
+ ppc_elf_tdata (abfd)->has_rel16 = 1;
+ break;
+
+ /* These are just markers. */
+ case R_PPC_TLS:
+ case R_PPC_EMB_MRKREF:
+ case R_PPC_NONE:
+ case R_PPC_max:
+ case R_PPC_RELAX:
+ case R_PPC_RELAX_PLT:
+ case R_PPC_RELAX_PLTREL24:
+ break;
+
+ /* These should only appear in dynamic objects. */
+ case R_PPC_COPY:
+ case R_PPC_GLOB_DAT:
+ case R_PPC_JMP_SLOT:
+ case R_PPC_RELATIVE:
+ case R_PPC_IRELATIVE:
+ break;
+
+ /* These aren't handled yet. We'll report an error later. */
+ case R_PPC_ADDR30:
+ case R_PPC_EMB_RELSEC16:
+ case R_PPC_EMB_RELST_LO:
+ case R_PPC_EMB_RELST_HI:
+ case R_PPC_EMB_RELST_HA:
+ case R_PPC_EMB_BIT_FLD:
+ break;
+
+ /* This refers only to functions defined in the shared library. */
+ case R_PPC_LOCAL24PC:
+ if (h != NULL && h == htab->elf.hgot && htab->plt_type == PLT_UNSET)
+ {
+ htab->plt_type = PLT_OLD;
+ htab->old_bfd = abfd;
+ }
+ if (h != NULL && h->type == STT_GNU_IFUNC)
+ {
+ if (info->shared)
+ {
+ info->callbacks->einfo (_("%P: %H: @local call to ifunc %s\n"),
+ abfd, sec, rel->r_offset,
+ h->root.root.string);
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+ h->needs_plt = 1;
+ if (!update_plt_info (abfd, &h->plt.plist, NULL, 0))
+ return FALSE;
+ }
+ break;
+
+ /* This relocation describes the C++ object vtable hierarchy.
+ Reconstruct it for later use during GC. */
+ case R_PPC_GNU_VTINHERIT:
+ if (!bfd_elf_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:
+ BFD_ASSERT (h != NULL);
+ if (h != NULL
+ && !bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
+ return FALSE;
+ break;
+
+ /* We shouldn't really be seeing these. */
+ case R_PPC_TPREL32:
+ case R_PPC_TPREL16:
+ case R_PPC_TPREL16_LO:
+ case R_PPC_TPREL16_HI:
+ case R_PPC_TPREL16_HA:
+ if (info->shared)
+ info->flags |= DF_STATIC_TLS;
+ goto dodyn;
+
+ /* Nor these. */
+ case R_PPC_DTPMOD32:
+ case R_PPC_DTPREL32:
+ goto dodyn;
+
+ case R_PPC_REL32:
+ if (h == NULL
+ && got2 != NULL
+ && (sec->flags & SEC_CODE) != 0
+ && info->shared
+ && htab->plt_type == PLT_UNSET)
+ {
+ /* Old -fPIC gcc code has .long LCTOC1-LCFx just before
+ the start of a function, which assembles to a REL32
+ reference to .got2. If we detect one of these, then
+ force the old PLT layout because the linker cannot
+ reliably deduce the GOT pointer value needed for
+ PLT call stubs. */
+ asection *s;
+ Elf_Internal_Sym *isym;
+
+ isym = bfd_sym_from_r_symndx (&htab->sym_cache,
+ abfd, r_symndx);
+ if (isym == NULL)
+ return FALSE;
+
+ s = bfd_section_from_elf_index (abfd, isym->st_shndx);
+ if (s == got2)
+ {
+ htab->plt_type = PLT_OLD;
+ htab->old_bfd = abfd;
+ }
+ }
+ if (h == NULL || h == htab->elf.hgot)
+ break;
+ /* fall through */
+
+ case R_PPC_ADDR32:
+ case R_PPC_ADDR16:
+ case R_PPC_ADDR16_LO:
+ case R_PPC_ADDR16_HI:
+ case R_PPC_ADDR16_HA:
+ case R_PPC_UADDR32:
+ case R_PPC_UADDR16:
+ if (h != NULL && !info->shared)
+ {
+ /* We may need a plt entry if the symbol turns out to be
+ a function defined in a dynamic object. */
+ if (!update_plt_info (abfd, &h->plt.plist, NULL, 0))
+ return FALSE;
+
+ /* We may need a copy reloc too. */
+ h->non_got_ref = 1;
+ h->pointer_equality_needed = 1;
+ }
+ goto dodyn;
+
+ case R_PPC_REL24:
+ case R_PPC_REL14:
+ case R_PPC_REL14_BRTAKEN:
+ case R_PPC_REL14_BRNTAKEN:
+ if (h == NULL)
+ break;
+ if (h == htab->elf.hgot)
+ {
+ if (htab->plt_type == PLT_UNSET)
+ {
+ htab->plt_type = PLT_OLD;
+ htab->old_bfd = abfd;
+ }
+ break;
+ }
+ /* fall through */
+
+ case R_PPC_ADDR24:
+ case R_PPC_ADDR14:
+ case R_PPC_ADDR14_BRTAKEN:
+ case R_PPC_ADDR14_BRNTAKEN:
+ if (h != NULL && !info->shared)
+ {
+ /* We may need a plt entry if the symbol turns out to be
+ a function defined in a dynamic object. */
+ h->needs_plt = 1;
+ if (!update_plt_info (abfd, &h->plt.plist, NULL, 0))
+ return FALSE;
+ break;
+ }
+
+ dodyn:
+ /* 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). In case of a weak definition,
+ DEF_REGULAR may be cleared later by a strong definition in
+ a shared library. We account for that possibility below by
+ storing information in the dyn_relocs field of the hash
+ table entry. A similar situation occurs when creating
+ shared libraries and symbol visibility changes render the
+ symbol local.
+
+ If on the other hand, we are creating an executable, we
+ may need to keep relocations for symbols satisfied by a
+ dynamic library if we manage to avoid copy relocs for the
+ symbol. */
+ if ((info->shared
+ && (must_be_dyn_reloc (info, r_type)
+ || (h != NULL
+ && (!SYMBOLIC_BIND (info, h)
+ || h->root.type == bfd_link_hash_defweak
+ || !h->def_regular))))
+ || (ELIMINATE_COPY_RELOCS
+ && !info->shared
+ && h != NULL
+ && (h->root.type == bfd_link_hash_defweak
+ || !h->def_regular)))
+ {
+#ifdef DEBUG
+ fprintf (stderr,
+ "ppc_elf_check_relocs needs to "
+ "create relocation for %s\n",
+ (h && h->root.root.string
+ ? h->root.root.string : "<unknown>"));
+#endif
+ if (sreloc == NULL)
+ {
+ if (htab->elf.dynobj == NULL)
+ htab->elf.dynobj = abfd;
+
+ sreloc = _bfd_elf_make_dynamic_reloc_section
+ (sec, htab->elf.dynobj, 2, abfd, /*rela?*/ TRUE);
+
+ if (sreloc == NULL)
+ return FALSE;
+ }
+
+ /* If this is a global symbol, we count the number of
+ relocations we need for this symbol. */
+ if (h != NULL)
+ {
+ struct elf_dyn_relocs *p;
+ struct elf_dyn_relocs **rel_head;
+
+ rel_head = &ppc_elf_hash_entry (h)->dyn_relocs;
+ p = *rel_head;
+ if (p == NULL || p->sec != sec)
+ {
+ p = bfd_alloc (htab->elf.dynobj, sizeof *p);
+ if (p == NULL)
+ return FALSE;
+ p->next = *rel_head;
+ *rel_head = p;
+ p->sec = sec;
+ p->count = 0;
+ p->pc_count = 0;
+ }
+ p->count += 1;
+ if (!must_be_dyn_reloc (info, r_type))
+ p->pc_count += 1;
+ }
+ else
+ {
+ /* Track dynamic relocs needed for local syms too.
+ We really need local syms available to do this
+ easily. Oh well. */
+ struct ppc_dyn_relocs *p;
+ struct ppc_dyn_relocs **rel_head;
+ bfd_boolean is_ifunc;
+ asection *s;
+ void *vpp;
+ Elf_Internal_Sym *isym;
+
+ isym = bfd_sym_from_r_symndx (&htab->sym_cache,
+ abfd, r_symndx);
+ if (isym == NULL)
+ return FALSE;
+
+ s = bfd_section_from_elf_index (abfd, isym->st_shndx);
+ if (s == NULL)
+ s = sec;
+
+ vpp = &elf_section_data (s)->local_dynrel;
+ rel_head = (struct ppc_dyn_relocs **) vpp;
+ is_ifunc = ELF_ST_TYPE (isym->st_info) == STT_GNU_IFUNC;
+ p = *rel_head;
+ if (p != NULL && p->sec == sec && p->ifunc != is_ifunc)
+ p = p->next;
+ if (p == NULL || p->sec != sec || p->ifunc != is_ifunc)
+ {
+ p = bfd_alloc (htab->elf.dynobj, sizeof *p);
+ if (p == NULL)
+ return FALSE;
+ p->next = *rel_head;
+ *rel_head = p;
+ p->sec = sec;
+ p->ifunc = is_ifunc;
+ p->count = 0;
+ }
+ p->count += 1;
+ }
+ }
+
+ break;
+ }
+ }
+
+ return TRUE;
+}
+
+
+/* Merge object attributes from IBFD into OBFD. Raise an error if
+ there are conflicting attributes. */
+static bfd_boolean
+ppc_elf_merge_obj_attributes (bfd *ibfd, bfd *obfd)
+{
+ obj_attribute *in_attr, *in_attrs;
+ obj_attribute *out_attr, *out_attrs;
+
+ if (!elf_known_obj_attributes_proc (obfd)[0].i)
+ {
+ /* This is the first object. Copy the attributes. */
+ _bfd_elf_copy_obj_attributes (ibfd, obfd);
+
+ /* Use the Tag_null value to indicate the attributes have been
+ initialized. */
+ elf_known_obj_attributes_proc (obfd)[0].i = 1;
+
+ return TRUE;
+ }
+
+ in_attrs = elf_known_obj_attributes (ibfd)[OBJ_ATTR_GNU];
+ out_attrs = elf_known_obj_attributes (obfd)[OBJ_ATTR_GNU];
+
+ /* Check for conflicting Tag_GNU_Power_ABI_FP attributes and merge
+ non-conflicting ones. */
+ in_attr = &in_attrs[Tag_GNU_Power_ABI_FP];
+ out_attr = &out_attrs[Tag_GNU_Power_ABI_FP];
+ if (in_attr->i != out_attr->i)
+ {
+ out_attr->type = 1;
+ if (out_attr->i == 0)
+ out_attr->i = in_attr->i;
+ else if (in_attr->i == 0)
+ ;
+ else if (out_attr->i == 1 && in_attr->i == 2)
+ _bfd_error_handler
+ (_("Warning: %B uses hard float, %B uses soft float"), obfd, ibfd);
+ else if (out_attr->i == 1 && in_attr->i == 3)
+ _bfd_error_handler
+ (_("Warning: %B uses double-precision hard float, %B uses single-precision hard float"),
+ obfd, ibfd);
+ else if (out_attr->i == 3 && in_attr->i == 1)
+ _bfd_error_handler
+ (_("Warning: %B uses double-precision hard float, %B uses single-precision hard float"),
+ ibfd, obfd);
+ else if (out_attr->i == 3 && in_attr->i == 2)
+ _bfd_error_handler
+ (_("Warning: %B uses soft float, %B uses single-precision hard float"),
+ ibfd, obfd);
+ else if (out_attr->i == 2 && (in_attr->i == 1 || in_attr->i == 3))
+ _bfd_error_handler
+ (_("Warning: %B uses hard float, %B uses soft float"), ibfd, obfd);
+ else if (in_attr->i > 3)
+ _bfd_error_handler
+ (_("Warning: %B uses unknown floating point ABI %d"), ibfd,
+ in_attr->i);
+ else
+ _bfd_error_handler
+ (_("Warning: %B uses unknown floating point ABI %d"), obfd,
+ out_attr->i);
+ }
+
+ /* Check for conflicting Tag_GNU_Power_ABI_Vector attributes and
+ merge non-conflicting ones. */
+ in_attr = &in_attrs[Tag_GNU_Power_ABI_Vector];
+ out_attr = &out_attrs[Tag_GNU_Power_ABI_Vector];
+ if (in_attr->i != out_attr->i)
+ {
+ const char *in_abi = NULL, *out_abi = NULL;
+
+ switch (in_attr->i)
+ {
+ case 1: in_abi = "generic"; break;
+ case 2: in_abi = "AltiVec"; break;
+ case 3: in_abi = "SPE"; break;
+ }
+
+ switch (out_attr->i)
+ {
+ case 1: out_abi = "generic"; break;
+ case 2: out_abi = "AltiVec"; break;
+ case 3: out_abi = "SPE"; break;
+ }
+
+ out_attr->type = 1;
+ if (out_attr->i == 0)
+ out_attr->i = in_attr->i;
+ else if (in_attr->i == 0)
+ ;
+ /* For now, allow generic to transition to AltiVec or SPE
+ without a warning. If GCC marked files with their stack
+ alignment and used don't-care markings for files which are
+ not affected by the vector ABI, we could warn about this
+ case too. */
+ else if (out_attr->i == 1)
+ out_attr->i = in_attr->i;
+ else if (in_attr->i == 1)
+ ;
+ else if (in_abi == NULL)
+ _bfd_error_handler
+ (_("Warning: %B uses unknown vector ABI %d"), ibfd,
+ in_attr->i);
+ else if (out_abi == NULL)
+ _bfd_error_handler
+ (_("Warning: %B uses unknown vector ABI %d"), obfd,
+ in_attr->i);
+ else
+ _bfd_error_handler
+ (_("Warning: %B uses vector ABI \"%s\", %B uses \"%s\""),
+ ibfd, obfd, in_abi, out_abi);
+ }
+
+ /* Check for conflicting Tag_GNU_Power_ABI_Struct_Return attributes
+ and merge non-conflicting ones. */
+ in_attr = &in_attrs[Tag_GNU_Power_ABI_Struct_Return];
+ out_attr = &out_attrs[Tag_GNU_Power_ABI_Struct_Return];
+ if (in_attr->i != out_attr->i)
+ {
+ out_attr->type = 1;
+ if (out_attr->i == 0)
+ out_attr->i = in_attr->i;
+ else if (in_attr->i == 0)
+ ;
+ else if (out_attr->i == 1 && in_attr->i == 2)
+ _bfd_error_handler
+ (_("Warning: %B uses r3/r4 for small structure returns, %B uses memory"), obfd, ibfd);
+ else if (out_attr->i == 2 && in_attr->i == 1)
+ _bfd_error_handler
+ (_("Warning: %B uses r3/r4 for small structure returns, %B uses memory"), ibfd, obfd);
+ else if (in_attr->i > 2)
+ _bfd_error_handler
+ (_("Warning: %B uses unknown small structure return convention %d"), ibfd,
+ in_attr->i);
+ else
+ _bfd_error_handler
+ (_("Warning: %B uses unknown small structure return convention %d"), obfd,
+ out_attr->i);
+ }
+
+ /* Merge Tag_compatibility attributes and any common GNU ones. */
+ _bfd_elf_merge_object_attributes (ibfd, obfd);
+
+ return TRUE;
+}
+
+/* Merge backend specific data from an object file to the output
+ object file when linking. */
+
+static bfd_boolean
+ppc_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
+{
+ flagword old_flags;
+ flagword new_flags;
+ bfd_boolean error;
+
+ if (!is_ppc_elf (ibfd) || !is_ppc_elf (obfd))
+ return TRUE;
+
+ /* Check if we have the same endianness. */
+ if (! _bfd_generic_verify_endian_match (ibfd, obfd))
+ return FALSE;
+
+ if (!ppc_elf_merge_obj_attributes (ibfd, obfd))
+ return FALSE;
+
+ 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;
+ }
+
+ /* Compatible flags are ok. */
+ else if (new_flags == old_flags)
+ ;
+
+ /* Incompatible flags. */
+ else
+ {
+ /* 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)
+ (_("%B: compiled with -mrelocatable and linked with "
+ "modules compiled normally"), ibfd);
+ }
+ else if ((new_flags & (EF_PPC_RELOCATABLE | EF_PPC_RELOCATABLE_LIB)) == 0
+ && (old_flags & EF_PPC_RELOCATABLE) != 0)
+ {
+ error = TRUE;
+ (*_bfd_error_handler)
+ (_("%B: compiled normally and linked with "
+ "modules compiled with -mrelocatable"), 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)
+ (_("%B: uses different e_flags (0x%lx) fields "
+ "than previous modules (0x%lx)"),
+ ibfd, (long) new_flags, (long) old_flags);
+ }
+
+ if (error)
+ {
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+static void
+ppc_elf_vle_split16 (bfd *output_bfd, bfd_byte *loc,
+ bfd_vma value,
+ split16_format_type split16_format)
+
+{
+ unsigned int insn, top5;
+
+ insn = bfd_get_32 (output_bfd, loc);
+ top5 = value & 0xf800;
+ top5 = top5 << (split16_format == split16a_type ? 9 : 5);
+ insn |= top5;
+ insn |= value & 0x7ff;
+ bfd_put_32 (output_bfd, insn, loc);
+}
+
+
+/* Choose which PLT scheme to use, and set .plt flags appropriately.
+ Returns -1 on error, 0 for old PLT, 1 for new PLT. */
+int
+ppc_elf_select_plt_layout (bfd *output_bfd ATTRIBUTE_UNUSED,
+ struct bfd_link_info *info)
+{
+ struct ppc_elf_link_hash_table *htab;
+ flagword flags;
+
+ htab = ppc_elf_hash_table (info);
+
+ if (htab->plt_type == PLT_UNSET)
+ {
+ struct elf_link_hash_entry *h;
+
+ if (htab->params->plt_style == PLT_OLD)
+ htab->plt_type = PLT_OLD;
+ else if (info->shared
+ && htab->elf.dynamic_sections_created
+ && (h = elf_link_hash_lookup (&htab->elf, "_mcount",
+ FALSE, FALSE, TRUE)) != NULL
+ && (h->type == STT_FUNC
+ || h->needs_plt)
+ && h->ref_regular
+ && !(SYMBOL_CALLS_LOCAL (info, h)
+ || (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
+ && h->root.type == bfd_link_hash_undefweak)))
+ {
+ /* Profiling of shared libs (and pies) is not supported with
+ secure plt, because ppc32 does profiling before a
+ function prologue and a secure plt pic call stubs needs
+ r30 to be set up. */
+ htab->plt_type = PLT_OLD;
+ }
+ else
+ {
+ bfd *ibfd;
+ enum ppc_elf_plt_type plt_type = htab->params->plt_style;
+
+ /* Look through the reloc flags left by ppc_elf_check_relocs.
+ Use the old style bss plt if a file makes plt calls
+ without using the new relocs, and if ld isn't given
+ --secure-plt and we never see REL16 relocs. */
+ if (plt_type == PLT_UNSET)
+ plt_type = PLT_OLD;
+ for (ibfd = info->input_bfds; ibfd; ibfd = ibfd->link.next)
+ if (is_ppc_elf (ibfd))
+ {
+ if (ppc_elf_tdata (ibfd)->has_rel16)
+ plt_type = PLT_NEW;
+ else if (ppc_elf_tdata (ibfd)->makes_plt_call)
+ {
+ plt_type = PLT_OLD;
+ htab->old_bfd = ibfd;
+ break;
+ }
+ }
+ htab->plt_type = plt_type;
+ }
+ }
+ if (htab->plt_type == PLT_OLD && htab->params->plt_style == PLT_NEW)
+ {
+ if (htab->old_bfd != NULL)
+ info->callbacks->einfo (_("%P: bss-plt forced due to %B\n"),
+ htab->old_bfd);
+ else
+ info->callbacks->einfo (_("%P: bss-plt forced by profiling\n"));
+ }
+
+ BFD_ASSERT (htab->plt_type != PLT_VXWORKS);
+
+ if (htab->plt_type == PLT_NEW)
+ {
+ flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS
+ | SEC_IN_MEMORY | SEC_LINKER_CREATED);
+
+ /* The new PLT is a loaded section. */
+ if (htab->plt != NULL
+ && !bfd_set_section_flags (htab->elf.dynobj, htab->plt, flags))
+ return -1;
+
+ /* The new GOT is not executable. */
+ if (htab->got != NULL
+ && !bfd_set_section_flags (htab->elf.dynobj, htab->got, flags))
+ return -1;
+ }
+ else
+ {
+ /* Stop an unused .glink section from affecting .text alignment. */
+ if (htab->glink != NULL
+ && !bfd_set_section_alignment (htab->elf.dynobj, htab->glink, 0))
+ return -1;
+ }
+ return htab->plt_type == PLT_NEW;
+}
+
+/* Return the section that should be marked against GC for a given
+ relocation. */
+
+static asection *
+ppc_elf_gc_mark_hook (asection *sec,
+ 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:
+ return NULL;
+ }
+
+ return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
+}
+
+/* Update the got, plt and dynamic reloc reference counts for the
+ section being removed. */
+
+static bfd_boolean
+ppc_elf_gc_sweep_hook (bfd *abfd,
+ struct bfd_link_info *info,
+ asection *sec,
+ const Elf_Internal_Rela *relocs)
+{
+ struct ppc_elf_link_hash_table *htab;
+ Elf_Internal_Shdr *symtab_hdr;
+ struct elf_link_hash_entry **sym_hashes;
+ bfd_signed_vma *local_got_refcounts;
+ const Elf_Internal_Rela *rel, *relend;
+ asection *got2;
+
+ if (info->relocatable)
+ return TRUE;
+
+ if ((sec->flags & SEC_ALLOC) == 0)
+ return TRUE;
+
+ elf_section_data (sec)->local_dynrel = NULL;
+
+ htab = ppc_elf_hash_table (info);
+ symtab_hdr = &elf_symtab_hdr (abfd);
+ sym_hashes = elf_sym_hashes (abfd);
+ local_got_refcounts = elf_local_got_refcounts (abfd);
+ got2 = bfd_get_section_by_name (abfd, ".got2");
+
+ relend = relocs + sec->reloc_count;
+ for (rel = relocs; rel < relend; rel++)
+ {
+ unsigned long r_symndx;
+ enum elf_ppc_reloc_type r_type;
+ struct elf_link_hash_entry *h = NULL;
+
+ r_symndx = ELF32_R_SYM (rel->r_info);
+ if (r_symndx >= symtab_hdr->sh_info)
+ {
+ struct elf_dyn_relocs **pp, *p;
+ struct ppc_elf_link_hash_entry *eh;
+
+ 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;
+ eh = (struct ppc_elf_link_hash_entry *) h;
+
+ for (pp = &eh->dyn_relocs; (p = *pp) != NULL; pp = &p->next)
+ if (p->sec == sec)
+ {
+ /* Everything must go for SEC. */
+ *pp = p->next;
+ break;
+ }
+ }
+
+ r_type = ELF32_R_TYPE (rel->r_info);
+ if (!htab->is_vxworks
+ && h == NULL
+ && local_got_refcounts != NULL
+ && (!info->shared
+ || is_branch_reloc (r_type)))
+ {
+ struct plt_entry **local_plt = (struct plt_entry **)
+ (local_got_refcounts + symtab_hdr->sh_info);
+ char *local_got_tls_masks = (char *)
+ (local_plt + symtab_hdr->sh_info);
+ if ((local_got_tls_masks[r_symndx] & PLT_IFUNC) != 0)
+ {
+ struct plt_entry **ifunc = local_plt + r_symndx;
+ bfd_vma addend = 0;
+ struct plt_entry *ent;
+
+ if (r_type == R_PPC_PLTREL24 && info->shared)
+ addend = rel->r_addend;
+ ent = find_plt_ent (ifunc, got2, addend);
+ if (ent->plt.refcount > 0)
+ ent->plt.refcount -= 1;
+ continue;
+ }
+ }
+
+ switch (r_type)
+ {
+ case R_PPC_GOT_TLSLD16:
+ case R_PPC_GOT_TLSLD16_LO:
+ case R_PPC_GOT_TLSLD16_HI:
+ case R_PPC_GOT_TLSLD16_HA:
+ case R_PPC_GOT_TLSGD16:
+ case R_PPC_GOT_TLSGD16_LO:
+ case R_PPC_GOT_TLSGD16_HI:
+ case R_PPC_GOT_TLSGD16_HA:
+ case R_PPC_GOT_TPREL16:
+ case R_PPC_GOT_TPREL16_LO:
+ case R_PPC_GOT_TPREL16_HI:
+ case R_PPC_GOT_TPREL16_HA:
+ case R_PPC_GOT_DTPREL16:
+ case R_PPC_GOT_DTPREL16_LO:
+ case R_PPC_GOT_DTPREL16_HI:
+ case R_PPC_GOT_DTPREL16_HA:
+ case R_PPC_GOT16:
+ case R_PPC_GOT16_LO:
+ case R_PPC_GOT16_HI:
+ case R_PPC_GOT16_HA:
+ if (h != NULL)
+ {
+ if (h->got.refcount > 0)
+ h->got.refcount--;
+ if (!info->shared)
+ {
+ struct plt_entry *ent;
+
+ ent = find_plt_ent (&h->plt.plist, NULL, 0);
+ if (ent != NULL && ent->plt.refcount > 0)
+ ent->plt.refcount -= 1;
+ }
+ }
+ else if (local_got_refcounts != NULL)
+ {
+ if (local_got_refcounts[r_symndx] > 0)
+ local_got_refcounts[r_symndx]--;
+ }
+ break;
+
+ 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 || h == htab->elf.hgot)
+ break;
+ /* Fall thru */
+
+ case R_PPC_ADDR32:
+ case R_PPC_ADDR24:
+ case R_PPC_ADDR16:
+ case R_PPC_ADDR16_LO:
+ case R_PPC_ADDR16_HI:
+ case R_PPC_ADDR16_HA:
+ case R_PPC_ADDR14:
+ case R_PPC_ADDR14_BRTAKEN:
+ case R_PPC_ADDR14_BRNTAKEN:
+ case R_PPC_UADDR32:
+ case R_PPC_UADDR16:
+ if (info->shared)
+ break;
+
+ case R_PPC_PLT32:
+ case R_PPC_PLTREL24:
+ case R_PPC_PLTREL32:
+ case R_PPC_PLT16_LO:
+ case R_PPC_PLT16_HI:
+ case R_PPC_PLT16_HA:
+ if (h != NULL)
+ {
+ bfd_vma addend = 0;
+ struct plt_entry *ent;
+
+ if (r_type == R_PPC_PLTREL24 && info->shared)
+ addend = rel->r_addend;
+ ent = find_plt_ent (&h->plt.plist, got2, addend);
+ if (ent != NULL && ent->plt.refcount > 0)
+ ent->plt.refcount -= 1;
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ return TRUE;
+}
+
+/* Set plt output section type, htab->tls_get_addr, and call the
+ generic ELF tls_setup function. */
+
+asection *
+ppc_elf_tls_setup (bfd *obfd, struct bfd_link_info *info)
+{
+ struct ppc_elf_link_hash_table *htab;
+
+ htab = ppc_elf_hash_table (info);
+ htab->tls_get_addr = elf_link_hash_lookup (&htab->elf, "__tls_get_addr",
+ FALSE, FALSE, TRUE);
+ if (!htab->params->no_tls_get_addr_opt)
+ {
+ struct elf_link_hash_entry *opt, *tga;
+ opt = elf_link_hash_lookup (&htab->elf, "__tls_get_addr_opt",
+ FALSE, FALSE, TRUE);
+ if (opt != NULL
+ && (opt->root.type == bfd_link_hash_defined
+ || opt->root.type == bfd_link_hash_defweak))
+ {
+ /* If glibc supports an optimized __tls_get_addr call stub,
+ signalled by the presence of __tls_get_addr_opt, and we'll
+ be calling __tls_get_addr via a plt call stub, then
+ make __tls_get_addr point to __tls_get_addr_opt. */
+ tga = htab->tls_get_addr;
+ if (htab->elf.dynamic_sections_created
+ && tga != NULL
+ && (tga->type == STT_FUNC
+ || tga->needs_plt)
+ && !(SYMBOL_CALLS_LOCAL (info, tga)
+ || (ELF_ST_VISIBILITY (tga->other) != STV_DEFAULT
+ && tga->root.type == bfd_link_hash_undefweak)))
+ {
+ struct plt_entry *ent;
+ for (ent = tga->plt.plist; ent != NULL; ent = ent->next)
+ if (ent->plt.refcount > 0)
+ break;
+ if (ent != NULL)
+ {
+ tga->root.type = bfd_link_hash_indirect;
+ tga->root.u.i.link = &opt->root;
+ ppc_elf_copy_indirect_symbol (info, opt, tga);
+ if (opt->dynindx != -1)
+ {
+ /* Use __tls_get_addr_opt in dynamic relocations. */
+ opt->dynindx = -1;
+ _bfd_elf_strtab_delref (elf_hash_table (info)->dynstr,
+ opt->dynstr_index);
+ if (!bfd_elf_link_record_dynamic_symbol (info, opt))
+ return FALSE;
+ }
+ htab->tls_get_addr = opt;
+ }
+ }
+ }
+ else
+ htab->params->no_tls_get_addr_opt = TRUE;
+ }
+ if (htab->plt_type == PLT_NEW
+ && htab->plt != NULL
+ && htab->plt->output_section != NULL)
+ {
+ elf_section_type (htab->plt->output_section) = SHT_PROGBITS;
+ elf_section_flags (htab->plt->output_section) = SHF_ALLOC + SHF_WRITE;
+ }
+
+ return _bfd_elf_tls_setup (obfd, info);
+}
+
+/* Return TRUE iff REL is a branch reloc with a global symbol matching
+ HASH. */
+
+static bfd_boolean
+branch_reloc_hash_match (const bfd *ibfd,
+ const Elf_Internal_Rela *rel,
+ const struct elf_link_hash_entry *hash)
+{
+ Elf_Internal_Shdr *symtab_hdr = &elf_symtab_hdr (ibfd);
+ enum elf_ppc_reloc_type r_type = ELF32_R_TYPE (rel->r_info);
+ unsigned int r_symndx = ELF32_R_SYM (rel->r_info);
+
+ if (r_symndx >= symtab_hdr->sh_info && is_branch_reloc (r_type))
+ {
+ struct elf_link_hash_entry **sym_hashes = elf_sym_hashes (ibfd);
+ struct elf_link_hash_entry *h;
+
+ 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 == hash)
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/* Run through all the TLS relocs looking for optimization
+ opportunities. */
+
+bfd_boolean
+ppc_elf_tls_optimize (bfd *obfd ATTRIBUTE_UNUSED,
+ struct bfd_link_info *info)
+{
+ bfd *ibfd;
+ asection *sec;
+ struct ppc_elf_link_hash_table *htab;
+ int pass;
+
+ if (info->relocatable || !info->executable)
+ return TRUE;
+
+ htab = ppc_elf_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ /* Make two passes through the relocs. First time check that tls
+ relocs involved in setting up a tls_get_addr call are indeed
+ followed by such a call. If they are not, don't do any tls
+ optimization. On the second pass twiddle tls_mask flags to
+ notify relocate_section that optimization can be done, and
+ adjust got and plt refcounts. */
+ for (pass = 0; pass < 2; ++pass)
+ for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next)
+ {
+ Elf_Internal_Sym *locsyms = NULL;
+ Elf_Internal_Shdr *symtab_hdr = &elf_symtab_hdr (ibfd);
+ asection *got2 = bfd_get_section_by_name (ibfd, ".got2");
+
+ for (sec = ibfd->sections; sec != NULL; sec = sec->next)
+ if (sec->has_tls_reloc && !bfd_is_abs_section (sec->output_section))
+ {
+ Elf_Internal_Rela *relstart, *rel, *relend;
+ int expecting_tls_get_addr = 0;
+
+ /* Read the relocations. */
+ relstart = _bfd_elf_link_read_relocs (ibfd, sec, NULL, NULL,
+ info->keep_memory);
+ if (relstart == NULL)
+ return FALSE;
+
+ relend = relstart + sec->reloc_count;
+ for (rel = relstart; rel < relend; rel++)
+ {
+ enum elf_ppc_reloc_type r_type;
+ unsigned long r_symndx;
+ struct elf_link_hash_entry *h = NULL;
+ char *tls_mask;
+ char tls_set, tls_clear;
+ bfd_boolean is_local;
+ bfd_signed_vma *got_count;
+
+ r_symndx = ELF32_R_SYM (rel->r_info);
+ if (r_symndx >= symtab_hdr->sh_info)
+ {
+ struct elf_link_hash_entry **sym_hashes;
+
+ sym_hashes = elf_sym_hashes (ibfd);
+ 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;
+ }
+
+ is_local = FALSE;
+ if (h == NULL
+ || !h->def_dynamic)
+ is_local = TRUE;
+
+ r_type = ELF32_R_TYPE (rel->r_info);
+ /* If this section has old-style __tls_get_addr calls
+ without marker relocs, then check that each
+ __tls_get_addr call reloc is preceded by a reloc
+ that conceivably belongs to the __tls_get_addr arg
+ setup insn. If we don't find matching arg setup
+ relocs, don't do any tls optimization. */
+ if (pass == 0
+ && sec->has_tls_get_addr_call
+ && h != NULL
+ && h == htab->tls_get_addr
+ && !expecting_tls_get_addr
+ && is_branch_reloc (r_type))
+ {
+ info->callbacks->minfo ("%H __tls_get_addr lost arg, "
+ "TLS optimization disabled\n",
+ ibfd, sec, rel->r_offset);
+ if (elf_section_data (sec)->relocs != relstart)
+ free (relstart);
+ return TRUE;
+ }
+
+ expecting_tls_get_addr = 0;
+ switch (r_type)
+ {
+ case R_PPC_GOT_TLSLD16:
+ case R_PPC_GOT_TLSLD16_LO:
+ expecting_tls_get_addr = 1;
+ /* Fall thru */
+
+ case R_PPC_GOT_TLSLD16_HI:
+ case R_PPC_GOT_TLSLD16_HA:
+ /* These relocs should never be against a symbol
+ defined in a shared lib. Leave them alone if
+ that turns out to be the case. */
+ if (!is_local)
+ continue;
+
+ /* LD -> LE */
+ tls_set = 0;
+ tls_clear = TLS_LD;
+ break;
+
+ case R_PPC_GOT_TLSGD16:
+ case R_PPC_GOT_TLSGD16_LO:
+ expecting_tls_get_addr = 1;
+ /* Fall thru */
+
+ case R_PPC_GOT_TLSGD16_HI:
+ case R_PPC_GOT_TLSGD16_HA:
+ if (is_local)
+ /* GD -> LE */
+ tls_set = 0;
+ else
+ /* GD -> IE */
+ tls_set = TLS_TLS | TLS_TPRELGD;
+ tls_clear = TLS_GD;
+ break;
+
+ case R_PPC_GOT_TPREL16:
+ case R_PPC_GOT_TPREL16_LO:
+ case R_PPC_GOT_TPREL16_HI:
+ case R_PPC_GOT_TPREL16_HA:
+ if (is_local)
+ {
+ /* IE -> LE */
+ tls_set = 0;
+ tls_clear = TLS_TPREL;
+ break;
+ }
+ else
+ continue;
+
+ case R_PPC_TLSGD:
+ case R_PPC_TLSLD:
+ expecting_tls_get_addr = 2;
+ tls_set = 0;
+ tls_clear = 0;
+ break;
+
+ default:
+ continue;
+ }
+
+ if (pass == 0)
+ {
+ if (!expecting_tls_get_addr
+ || (expecting_tls_get_addr == 1
+ && !sec->has_tls_get_addr_call))
+ continue;
+
+ if (rel + 1 < relend
+ && branch_reloc_hash_match (ibfd, rel + 1,
+ htab->tls_get_addr))
+ continue;
+
+ /* Uh oh, we didn't find the expected call. We
+ could just mark this symbol to exclude it
+ from tls optimization but it's safer to skip
+ the entire optimization. */
+ info->callbacks->minfo (_("%H arg lost __tls_get_addr, "
+ "TLS optimization disabled\n"),
+ ibfd, sec, rel->r_offset);
+ if (elf_section_data (sec)->relocs != relstart)
+ free (relstart);
+ return TRUE;
+ }
+
+ if (expecting_tls_get_addr)
+ {
+ struct plt_entry *ent;
+ bfd_vma addend = 0;
+
+ if (info->shared
+ && ELF32_R_TYPE (rel[1].r_info) == R_PPC_PLTREL24)
+ addend = rel[1].r_addend;
+ ent = find_plt_ent (&htab->tls_get_addr->plt.plist,
+ got2, addend);
+ if (ent != NULL && ent->plt.refcount > 0)
+ ent->plt.refcount -= 1;
+
+ if (expecting_tls_get_addr == 2)
+ continue;
+ }
+
+ if (h != NULL)
+ {
+ tls_mask = &ppc_elf_hash_entry (h)->tls_mask;
+ got_count = &h->got.refcount;
+ }
+ else
+ {
+ bfd_signed_vma *lgot_refs;
+ struct plt_entry **local_plt;
+ char *lgot_masks;
+
+ if (locsyms == NULL)
+ {
+ locsyms = (Elf_Internal_Sym *) symtab_hdr->contents;
+ if (locsyms == NULL)
+ locsyms = bfd_elf_get_elf_syms (ibfd, symtab_hdr,
+ symtab_hdr->sh_info,
+ 0, NULL, NULL, NULL);
+ if (locsyms == NULL)
+ {
+ if (elf_section_data (sec)->relocs != relstart)
+ free (relstart);
+ return FALSE;
+ }
+ }
+ lgot_refs = elf_local_got_refcounts (ibfd);
+ if (lgot_refs == NULL)
+ abort ();
+ local_plt = (struct plt_entry **)
+ (lgot_refs + symtab_hdr->sh_info);
+ lgot_masks = (char *) (local_plt + symtab_hdr->sh_info);
+ tls_mask = &lgot_masks[r_symndx];
+ got_count = &lgot_refs[r_symndx];
+ }
+
+ if (tls_set == 0)
+ {
+ /* We managed to get rid of a got entry. */
+ if (*got_count > 0)
+ *got_count -= 1;
+ }
+
+ *tls_mask |= tls_set;
+ *tls_mask &= ~tls_clear;
+ }
+
+ if (elf_section_data (sec)->relocs != relstart)
+ free (relstart);
+ }
+
+ if (locsyms != NULL
+ && (symtab_hdr->contents != (unsigned char *) locsyms))
+ {
+ if (!info->keep_memory)
+ free (locsyms);
+ else
+ symtab_hdr->contents = (unsigned char *) locsyms;
+ }
+ }
+ return TRUE;
+}
+
+/* Return true if we have dynamic relocs that apply to read-only sections. */
+
+static bfd_boolean
+readonly_dynrelocs (struct elf_link_hash_entry *h)
+{
+ struct elf_dyn_relocs *p;
+
+ for (p = ppc_elf_hash_entry (h)->dyn_relocs; p != NULL; p = p->next)
+ {
+ asection *s = p->sec->output_section;
+
+ if (s != NULL
+ && ((s->flags & (SEC_READONLY | SEC_ALLOC))
+ == (SEC_READONLY | SEC_ALLOC)))
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/* 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 bfd_boolean
+ppc_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
+ struct elf_link_hash_entry *h)
+{
+ struct ppc_elf_link_hash_table *htab;
+ asection *s;
+
+#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. */
+ htab = ppc_elf_hash_table (info);
+ BFD_ASSERT (htab->elf.dynobj != NULL
+ && (h->needs_plt
+ || h->type == STT_GNU_IFUNC
+ || h->u.weakdef != NULL
+ || (h->def_dynamic
+ && h->ref_regular
+ && !h->def_regular)));
+
+ /* Deal with function syms. */
+ if (h->type == STT_FUNC
+ || h->type == STT_GNU_IFUNC
+ || h->needs_plt)
+ {
+ /* Clear procedure linkage table information for any symbol that
+ won't need a .plt entry. */
+ struct plt_entry *ent;
+ for (ent = h->plt.plist; ent != NULL; ent = ent->next)
+ if (ent->plt.refcount > 0)
+ break;
+ if (ent == NULL
+ || (h->type != STT_GNU_IFUNC
+ && (SYMBOL_CALLS_LOCAL (info, h)
+ || (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
+ && h->root.type == bfd_link_hash_undefweak))))
+ {
+ /* 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. In this case,
+ ppc_elf_adjust_dynamic_symbol won't even be called.
+
+ 2. GC has rendered the entry unused.
+
+ 3. We know for certain that a call to this symbol
+ will go to this object, or will remain undefined. */
+ h->plt.plist = NULL;
+ h->needs_plt = 0;
+ h->pointer_equality_needed = 0;
+ }
+ else
+ {
+ /* Taking a function's address in a read/write section
+ doesn't require us to define the function symbol in the
+ executable on a plt call stub. A dynamic reloc can
+ be used instead. */
+ if (h->pointer_equality_needed
+ && h->type != STT_GNU_IFUNC
+ && !htab->is_vxworks
+ && !ppc_elf_hash_entry (h)->has_sda_refs
+ && !readonly_dynrelocs (h))
+ {
+ h->pointer_equality_needed = 0;
+ h->non_got_ref = 0;
+ }
+
+ /* After adjust_dynamic_symbol, non_got_ref set in the
+ non-shared case means that we have allocated space in
+ .dynbss for the symbol and thus dyn_relocs for this
+ symbol should be discarded.
+ If we get here we know we are making a PLT entry for this
+ symbol, and in an executable we'd normally resolve
+ relocations against this symbol to the PLT entry. Allow
+ dynamic relocs if the reference is weak, and the dynamic
+ relocs will not cause text relocation. */
+ else if (!h->ref_regular_nonweak
+ && h->non_got_ref
+ && h->type != STT_GNU_IFUNC
+ && !htab->is_vxworks
+ && !ppc_elf_hash_entry (h)->has_sda_refs
+ && !readonly_dynrelocs (h))
+ h->non_got_ref = 0;
+ }
+ return TRUE;
+ }
+ else
+ h->plt.plist = NULL;
+
+ /* 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->u.weakdef != NULL)
+ {
+ BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
+ || h->u.weakdef->root.type == bfd_link_hash_defweak);
+ h->root.u.def.section = h->u.weakdef->root.u.def.section;
+ h->root.u.def.value = h->u.weakdef->root.u.def.value;
+ if (ELIMINATE_COPY_RELOCS)
+ h->non_got_ref = h->u.weakdef->non_got_ref;
+ 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;
+
+ /* If there are no references to this symbol that do not use the
+ GOT, we don't need to generate a copy reloc. */
+ if (!h->non_got_ref)
+ return TRUE;
+
+ /* If we didn't find any dynamic relocs in read-only sections, then
+ we'll be keeping the dynamic relocs and avoiding the copy reloc.
+ We can't do this if there are any small data relocations. This
+ doesn't work on VxWorks, where we can not have dynamic
+ relocations (other than copy and jump slot relocations) in an
+ executable. */
+ if (ELIMINATE_COPY_RELOCS
+ && !ppc_elf_hash_entry (h)->has_sda_refs
+ && !htab->is_vxworks
+ && !h->def_regular
+ && !readonly_dynrelocs (h))
+ {
+ h->non_got_ref = 0;
+ 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 referenced using SDAREL relocs, we
+ must instead allocate it in .sbss. */
+
+ if (ppc_elf_hash_entry (h)->has_sda_refs)
+ s = htab->dynsbss;
+ else
+ s = htab->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 && h->size != 0)
+ {
+ asection *srel;
+
+ if (ppc_elf_hash_entry (h)->has_sda_refs)
+ srel = htab->relsbss;
+ else
+ srel = htab->relbss;
+ BFD_ASSERT (srel != NULL);
+ srel->size += sizeof (Elf32_External_Rela);
+ h->needs_copy = 1;
+ }
+
+ return _bfd_elf_adjust_dynamic_copy (h, s);
+}
+
+/* Generate a symbol to mark plt call stubs. For non-PIC code the sym is
+ xxxxxxxx.plt_call32.<callee> where xxxxxxxx is a hex number, usually 0,
+ specifying the addend on the plt relocation. For -fpic code, the sym
+ is xxxxxxxx.plt_pic32.<callee>, and for -fPIC
+ xxxxxxxx.got2.plt_pic32.<callee>. */
+
+static bfd_boolean
+add_stub_sym (struct plt_entry *ent,
+ struct elf_link_hash_entry *h,
+ struct bfd_link_info *info)
+{
+ struct elf_link_hash_entry *sh;
+ size_t len1, len2, len3;
+ char *name;
+ const char *stub;
+ struct ppc_elf_link_hash_table *htab = ppc_elf_hash_table (info);
+
+ if (info->shared)
+ stub = ".plt_pic32.";
+ else
+ stub = ".plt_call32.";
+
+ len1 = strlen (h->root.root.string);
+ len2 = strlen (stub);
+ len3 = 0;
+ if (ent->sec)
+ len3 = strlen (ent->sec->name);
+ name = bfd_malloc (len1 + len2 + len3 + 9);
+ if (name == NULL)
+ return FALSE;
+ sprintf (name, "%08x", (unsigned) ent->addend & 0xffffffff);
+ if (ent->sec)
+ memcpy (name + 8, ent->sec->name, len3);
+ memcpy (name + 8 + len3, stub, len2);
+ memcpy (name + 8 + len3 + len2, h->root.root.string, len1 + 1);
+ sh = elf_link_hash_lookup (&htab->elf, name, TRUE, FALSE, FALSE);
+ if (sh == NULL)
+ return FALSE;
+ if (sh->root.type == bfd_link_hash_new)
+ {
+ sh->root.type = bfd_link_hash_defined;
+ sh->root.u.def.section = htab->glink;
+ sh->root.u.def.value = ent->glink_offset;
+ sh->ref_regular = 1;
+ sh->def_regular = 1;
+ sh->ref_regular_nonweak = 1;
+ sh->forced_local = 1;
+ sh->non_elf = 0;
+ }
+ return TRUE;
+}
+
+/* Allocate NEED contiguous space in .got, and return the offset.
+ Handles allocation of the got header when crossing 32k. */
+
+static bfd_vma
+allocate_got (struct ppc_elf_link_hash_table *htab, unsigned int need)
+{
+ bfd_vma where;
+ unsigned int max_before_header;
+
+ if (htab->plt_type == PLT_VXWORKS)
+ {
+ where = htab->got->size;
+ htab->got->size += need;
+ }
+ else
+ {
+ max_before_header = htab->plt_type == PLT_NEW ? 32768 : 32764;
+ if (need <= htab->got_gap)
+ {
+ where = max_before_header - htab->got_gap;
+ htab->got_gap -= need;
+ }
+ else
+ {
+ if (htab->got->size + need > max_before_header
+ && htab->got->size <= max_before_header)
+ {
+ htab->got_gap = max_before_header - htab->got->size;
+ htab->got->size = max_before_header + htab->got_header_size;
+ }
+ where = htab->got->size;
+ htab->got->size += need;
+ }
+ }
+ return where;
+}
+
+/* Allocate space in associated reloc sections for dynamic relocs. */
+
+static bfd_boolean
+allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
+{
+ struct bfd_link_info *info = inf;
+ struct ppc_elf_link_hash_entry *eh;
+ struct ppc_elf_link_hash_table *htab;
+ struct elf_dyn_relocs *p;
+
+ if (h->root.type == bfd_link_hash_indirect)
+ return TRUE;
+
+ htab = ppc_elf_hash_table (info);
+ if (htab->elf.dynamic_sections_created
+ || h->type == STT_GNU_IFUNC)
+ {
+ struct plt_entry *ent;
+ bfd_boolean doneone = FALSE;
+ bfd_vma plt_offset = 0, glink_offset = 0;
+ bfd_boolean dyn;
+
+ for (ent = h->plt.plist; ent != NULL; ent = ent->next)
+ if (ent->plt.refcount > 0)
+ {
+ /* Make sure this symbol is output as a dynamic symbol. */
+ if (h->dynindx == -1
+ && !h->forced_local
+ && !h->def_regular
+ && htab->elf.dynamic_sections_created)
+ {
+ if (! bfd_elf_link_record_dynamic_symbol (info, h))
+ return FALSE;
+ }
+
+ dyn = htab->elf.dynamic_sections_created;
+ if (info->shared
+ || h->type == STT_GNU_IFUNC
+ || WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, 0, h))
+ {
+ asection *s = htab->plt;
+ if (!dyn || h->dynindx == -1)
+ s = htab->iplt;
+
+ if (htab->plt_type == PLT_NEW || !dyn || h->dynindx == -1)
+ {
+ if (!doneone)
+ {
+ plt_offset = s->size;
+ s->size += 4;
+ }
+ ent->plt.offset = plt_offset;
+
+ s = htab->glink;
+ if (!doneone || info->shared)
+ {
+ glink_offset = s->size;
+ s->size += GLINK_ENTRY_SIZE;
+ if (h == htab->tls_get_addr
+ && !htab->params->no_tls_get_addr_opt)
+ s->size += TLS_GET_ADDR_GLINK_SIZE - GLINK_ENTRY_SIZE;
+ }
+ if (!doneone
+ && !info->shared
+ && h->def_dynamic
+ && !h->def_regular)
+ {
+ h->root.u.def.section = s;
+ h->root.u.def.value = glink_offset;
+ }
+ ent->glink_offset = glink_offset;
+
+ if (htab->params->emit_stub_syms
+ && !add_stub_sym (ent, h, info))
+ return FALSE;
+ }
+ else
+ {
+ if (!doneone)
+ {
+ /* If this is the first .plt entry, make room
+ for the special first entry. */
+ if (s->size == 0)
+ s->size += htab->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 = (htab->plt_initial_entry_size
+ + (htab->plt_slot_size
+ * ((s->size
+ - htab->plt_initial_entry_size)
+ / htab->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 to avoid text
+ relocations, and is required to make
+ function pointers compare as equal between
+ the normal executable and the shared library. */
+ if (! info->shared
+ && h->def_dynamic
+ && !h->def_regular)
+ {
+ h->root.u.def.section = s;
+ h->root.u.def.value = plt_offset;
+ }
+
+ /* Make room for this entry. */
+ s->size += htab->plt_entry_size;
+ /* After the 8192nd entry, room for two entries
+ is allocated. */
+ if (htab->plt_type == PLT_OLD
+ && (s->size - htab->plt_initial_entry_size)
+ / htab->plt_entry_size
+ > PLT_NUM_SINGLE_ENTRIES)
+ s->size += htab->plt_entry_size;
+ }
+ ent->plt.offset = plt_offset;
+ }
+
+ /* We also need to make an entry in the .rela.plt section. */
+ if (!doneone)
+ {
+ if (!htab->elf.dynamic_sections_created
+ || h->dynindx == -1)
+ htab->reliplt->size += sizeof (Elf32_External_Rela);
+ else
+ {
+ htab->relplt->size += sizeof (Elf32_External_Rela);
+
+ if (htab->plt_type == PLT_VXWORKS)
+ {
+ /* Allocate space for the unloaded relocations. */
+ if (!info->shared
+ && htab->elf.dynamic_sections_created)
+ {
+ if (ent->plt.offset
+ == (bfd_vma) htab->plt_initial_entry_size)
+ {
+ htab->srelplt2->size
+ += (sizeof (Elf32_External_Rela)
+ * VXWORKS_PLTRESOLVE_RELOCS);
+ }
+
+ htab->srelplt2->size
+ += (sizeof (Elf32_External_Rela)
+ * VXWORKS_PLT_NON_JMP_SLOT_RELOCS);
+ }
+
+ /* Every PLT entry has an associated GOT entry in
+ .got.plt. */
+ htab->sgotplt->size += 4;
+ }
+ }
+ doneone = TRUE;
+ }
+ }
+ else
+ ent->plt.offset = (bfd_vma) -1;
+ }
+ else
+ ent->plt.offset = (bfd_vma) -1;
+
+ if (!doneone)
+ {
+ h->plt.plist = NULL;
+ h->needs_plt = 0;
+ }
+ }
+ else
+ {
+ h->plt.plist = NULL;
+ h->needs_plt = 0;
+ }
+
+ eh = (struct ppc_elf_link_hash_entry *) h;
+ if (eh->elf.got.refcount > 0)
+ {
+ bfd_boolean dyn;
+ unsigned int need;
+
+ /* Make sure this symbol is output as a dynamic symbol. */
+ if (eh->elf.dynindx == -1
+ && !eh->elf.forced_local
+ && eh->elf.type != STT_GNU_IFUNC
+ && htab->elf.dynamic_sections_created)
+ {
+ if (!bfd_elf_link_record_dynamic_symbol (info, &eh->elf))
+ return FALSE;
+ }
+
+ need = 0;
+ if ((eh->tls_mask & TLS_TLS) != 0)
+ {
+ if ((eh->tls_mask & TLS_LD) != 0)
+ {
+ if (!eh->elf.def_dynamic)
+ /* We'll just use htab->tlsld_got.offset. This should
+ always be the case. It's a little odd if we have
+ a local dynamic reloc against a non-local symbol. */
+ htab->tlsld_got.refcount += 1;
+ else
+ need += 8;
+ }
+ if ((eh->tls_mask & TLS_GD) != 0)
+ need += 8;
+ if ((eh->tls_mask & (TLS_TPREL | TLS_TPRELGD)) != 0)
+ need += 4;
+ if ((eh->tls_mask & TLS_DTPREL) != 0)
+ need += 4;
+ }
+ else
+ need += 4;
+ if (need == 0)
+ eh->elf.got.offset = (bfd_vma) -1;
+ else
+ {
+ eh->elf.got.offset = allocate_got (htab, need);
+ dyn = htab->elf.dynamic_sections_created;
+ if ((info->shared
+ || WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, 0, &eh->elf))
+ && (ELF_ST_VISIBILITY (eh->elf.other) == STV_DEFAULT
+ || eh->elf.root.type != bfd_link_hash_undefweak))
+ {
+ asection *rsec = htab->relgot;
+
+ if (eh->elf.type == STT_GNU_IFUNC)
+ rsec = htab->reliplt;
+ /* All the entries we allocated need relocs.
+ Except LD only needs one. */
+ if ((eh->tls_mask & TLS_LD) != 0
+ && eh->elf.def_dynamic)
+ need -= 4;
+ rsec->size += need * (sizeof (Elf32_External_Rela) / 4);
+ }
+ }
+ }
+ else
+ eh->elf.got.offset = (bfd_vma) -1;
+
+ if (eh->dyn_relocs == NULL
+ || !htab->elf.dynamic_sections_created)
+ return TRUE;
+
+ /* In the shared -Bsymbolic case, discard space allocated for
+ dynamic pc-relative relocs against symbols which turn out to be
+ defined in regular objects. For the normal shared case, discard
+ space for relocs that have become local due to symbol visibility
+ changes. */
+
+ if (info->shared)
+ {
+ /* Relocs that use pc_count are those that appear on a call insn,
+ or certain REL relocs (see must_be_dyn_reloc) that can be
+ generated via assembly. We want calls to protected symbols to
+ resolve directly to the function rather than going via the plt.
+ If people want function pointer comparisons to work as expected
+ then they should avoid writing weird assembly. */
+ if (SYMBOL_CALLS_LOCAL (info, h))
+ {
+ struct elf_dyn_relocs **pp;
+
+ for (pp = &eh->dyn_relocs; (p = *pp) != NULL; )
+ {
+ p->count -= p->pc_count;
+ p->pc_count = 0;
+ if (p->count == 0)
+ *pp = p->next;
+ else
+ pp = &p->next;
+ }
+ }
+
+ if (htab->is_vxworks)
+ {
+ struct elf_dyn_relocs **pp;
+
+ for (pp = &eh->dyn_relocs; (p = *pp) != NULL; )
+ {
+ if (strcmp (p->sec->output_section->name, ".tls_vars") == 0)
+ *pp = p->next;
+ else
+ pp = &p->next;
+ }
+ }
+
+ /* Discard relocs on undefined symbols that must be local. */
+ if (eh->dyn_relocs != NULL
+ && h->root.type == bfd_link_hash_undefined
+ && (ELF_ST_VISIBILITY (h->other) == STV_HIDDEN
+ || ELF_ST_VISIBILITY (h->other) == STV_INTERNAL))
+ eh->dyn_relocs = NULL;
+
+ /* Also discard relocs on undefined weak syms with non-default
+ visibility. */
+ if (eh->dyn_relocs != NULL
+ && h->root.type == bfd_link_hash_undefweak)
+ {
+ if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
+ eh->dyn_relocs = NULL;
+
+ /* Make sure undefined weak symbols are output as a dynamic
+ symbol in PIEs. */
+ else if (h->dynindx == -1
+ && !h->forced_local
+ && !h->def_regular)
+ {
+ if (! bfd_elf_link_record_dynamic_symbol (info, h))
+ return FALSE;
+ }
+ }
+ }
+ else if (ELIMINATE_COPY_RELOCS)
+ {
+ /* For the non-shared case, discard space for relocs against
+ symbols which turn out to need copy relocs or are not
+ dynamic. */
+
+ if (!h->non_got_ref
+ && !h->def_regular)
+ {
+ /* Make sure this symbol is output as a dynamic symbol.
+ Undefined weak syms won't yet be marked as dynamic. */
+ if (h->dynindx == -1
+ && !h->forced_local)
+ {
+ if (! bfd_elf_link_record_dynamic_symbol (info, h))
+ return FALSE;
+ }
+
+ /* If that succeeded, we know we'll be keeping all the
+ relocs. */
+ if (h->dynindx != -1)
+ goto keep;
+ }
+
+ eh->dyn_relocs = NULL;
+
+ keep: ;
+ }
+
+ /* Finally, allocate space. */
+ for (p = eh->dyn_relocs; p != NULL; p = p->next)
+ {
+ asection *sreloc = elf_section_data (p->sec)->sreloc;
+ if (eh->elf.type == STT_GNU_IFUNC)
+ sreloc = htab->reliplt;
+ sreloc->size += p->count * sizeof (Elf32_External_Rela);
+ }
+
+ return TRUE;
+}
+
+/* Set DF_TEXTREL if we find any dynamic relocs that apply to
+ read-only sections. */
+
+static bfd_boolean
+maybe_set_textrel (struct elf_link_hash_entry *h, void *info)
+{
+ if (h->root.type == bfd_link_hash_indirect)
+ return TRUE;
+
+ if (readonly_dynrelocs (h))
+ {
+ ((struct bfd_link_info *) info)->flags |= DF_TEXTREL;
+
+ /* Not an error, just cut short the traversal. */
+ return FALSE;
+ }
+ return TRUE;
+}
+
+static const unsigned char glink_eh_frame_cie[] =
+{
+ 0, 0, 0, 16, /* length. */
+ 0, 0, 0, 0, /* id. */
+ 1, /* CIE version. */
+ 'z', 'R', 0, /* Augmentation string. */
+ 4, /* Code alignment. */
+ 0x7c, /* Data alignment. */
+ 65, /* RA reg. */
+ 1, /* Augmentation size. */
+ DW_EH_PE_pcrel | DW_EH_PE_sdata4, /* FDE encoding. */
+ DW_CFA_def_cfa, 1, 0 /* def_cfa: r1 offset 0. */
+};
+
+/* Set the sizes of the dynamic sections. */
+
+static bfd_boolean
+ppc_elf_size_dynamic_sections (bfd *output_bfd,
+ struct bfd_link_info *info)
+{
+ struct ppc_elf_link_hash_table *htab;
+ asection *s;
+ bfd_boolean relocs;
+ bfd *ibfd;
+
+#ifdef DEBUG
+ fprintf (stderr, "ppc_elf_size_dynamic_sections called\n");
+#endif
+
+ htab = ppc_elf_hash_table (info);
+ BFD_ASSERT (htab->elf.dynobj != NULL);
+
+ if (elf_hash_table (info)->dynamic_sections_created)
+ {
+ /* Set the contents of the .interp section to the interpreter. */
+ if (info->executable)
+ {
+ s = bfd_get_linker_section (htab->elf.dynobj, ".interp");
+ BFD_ASSERT (s != NULL);
+ s->size = sizeof ELF_DYNAMIC_INTERPRETER;
+ s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
+ }
+ }
+
+ if (htab->plt_type == PLT_OLD)
+ htab->got_header_size = 16;
+ else if (htab->plt_type == PLT_NEW)
+ htab->got_header_size = 12;
+
+ /* Set up .got offsets for local syms, and space for local dynamic
+ relocs. */
+ for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next)
+ {
+ bfd_signed_vma *local_got;
+ bfd_signed_vma *end_local_got;
+ struct plt_entry **local_plt;
+ struct plt_entry **end_local_plt;
+ char *lgot_masks;
+ bfd_size_type locsymcount;
+ Elf_Internal_Shdr *symtab_hdr;
+
+ if (!is_ppc_elf (ibfd))
+ continue;
+
+ for (s = ibfd->sections; s != NULL; s = s->next)
+ {
+ struct ppc_dyn_relocs *p;
+
+ for (p = ((struct ppc_dyn_relocs *)
+ elf_section_data (s)->local_dynrel);
+ p != NULL;
+ p = p->next)
+ {
+ if (!bfd_is_abs_section (p->sec)
+ && bfd_is_abs_section (p->sec->output_section))
+ {
+ /* Input section has been discarded, either because
+ it is a copy of a linkonce section or due to
+ linker script /DISCARD/, so we'll be discarding
+ the relocs too. */
+ }
+ else if (htab->is_vxworks
+ && strcmp (p->sec->output_section->name,
+ ".tls_vars") == 0)
+ {
+ /* Relocations in vxworks .tls_vars sections are
+ handled specially by the loader. */
+ }
+ else if (p->count != 0)
+ {
+ asection *sreloc = elf_section_data (p->sec)->sreloc;
+ if (p->ifunc)
+ sreloc = htab->reliplt;
+ sreloc->size += p->count * sizeof (Elf32_External_Rela);
+ if ((p->sec->output_section->flags
+ & (SEC_READONLY | SEC_ALLOC))
+ == (SEC_READONLY | SEC_ALLOC))
+ info->flags |= DF_TEXTREL;
+ }
+ }
+ }
+
+ local_got = elf_local_got_refcounts (ibfd);
+ if (!local_got)
+ continue;
+
+ symtab_hdr = &elf_symtab_hdr (ibfd);
+ locsymcount = symtab_hdr->sh_info;
+ end_local_got = local_got + locsymcount;
+ local_plt = (struct plt_entry **) end_local_got;
+ end_local_plt = local_plt + locsymcount;
+ lgot_masks = (char *) end_local_plt;
+
+ for (; local_got < end_local_got; ++local_got, ++lgot_masks)
+ if (*local_got > 0)
+ {
+ unsigned int need = 0;
+ if ((*lgot_masks & TLS_TLS) != 0)
+ {
+ if ((*lgot_masks & TLS_GD) != 0)
+ need += 8;
+ if ((*lgot_masks & TLS_LD) != 0)
+ htab->tlsld_got.refcount += 1;
+ if ((*lgot_masks & (TLS_TPREL | TLS_TPRELGD)) != 0)
+ need += 4;
+ if ((*lgot_masks & TLS_DTPREL) != 0)
+ need += 4;
+ }
+ else
+ need += 4;
+ if (need == 0)
+ *local_got = (bfd_vma) -1;
+ else
+ {
+ *local_got = allocate_got (htab, need);
+ if (info->shared)
+ {
+ asection *srel = htab->relgot;
+ if ((*lgot_masks & PLT_IFUNC) != 0)
+ srel = htab->reliplt;
+ srel->size += need * (sizeof (Elf32_External_Rela) / 4);
+ }
+ }
+ }
+ else
+ *local_got = (bfd_vma) -1;
+
+ if (htab->is_vxworks)
+ continue;
+
+ /* Allocate space for calls to local STT_GNU_IFUNC syms in .iplt. */
+ for (; local_plt < end_local_plt; ++local_plt)
+ {
+ struct plt_entry *ent;
+ bfd_boolean doneone = FALSE;
+ bfd_vma plt_offset = 0, glink_offset = 0;
+
+ for (ent = *local_plt; ent != NULL; ent = ent->next)
+ if (ent->plt.refcount > 0)
+ {
+ s = htab->iplt;
+
+ if (!doneone)
+ {
+ plt_offset = s->size;
+ s->size += 4;
+ }
+ ent->plt.offset = plt_offset;
+
+ s = htab->glink;
+ if (!doneone || info->shared)
+ {
+ glink_offset = s->size;
+ s->size += GLINK_ENTRY_SIZE;
+ }
+ ent->glink_offset = glink_offset;
+
+ if (!doneone)
+ {
+ htab->reliplt->size += sizeof (Elf32_External_Rela);
+ doneone = TRUE;
+ }
+ }
+ else
+ ent->plt.offset = (bfd_vma) -1;
+ }
+ }
+
+ /* Allocate space for global sym dynamic relocs. */
+ elf_link_hash_traverse (elf_hash_table (info), allocate_dynrelocs, info);
+
+ if (htab->tlsld_got.refcount > 0)
+ {
+ htab->tlsld_got.offset = allocate_got (htab, 8);
+ if (info->shared)
+ htab->relgot->size += sizeof (Elf32_External_Rela);
+ }
+ else
+ htab->tlsld_got.offset = (bfd_vma) -1;
+
+ if (htab->got != NULL && htab->plt_type != PLT_VXWORKS)
+ {
+ unsigned int g_o_t = 32768;
+
+ /* If we haven't allocated the header, do so now. When we get here,
+ for old plt/got the got size will be 0 to 32764 (not allocated),
+ or 32780 to 65536 (header allocated). For new plt/got, the
+ corresponding ranges are 0 to 32768 and 32780 to 65536. */
+ if (htab->got->size <= 32768)
+ {
+ g_o_t = htab->got->size;
+ if (htab->plt_type == PLT_OLD)
+ g_o_t += 4;
+ htab->got->size += htab->got_header_size;
+ }
+
+ htab->elf.hgot->root.u.def.value = g_o_t;
+ }
+ if (info->shared)
+ {
+ struct elf_link_hash_entry *sda = htab->sdata[0].sym;
+
+ sda->root.u.def.section = htab->elf.hgot->root.u.def.section;
+ sda->root.u.def.value = htab->elf.hgot->root.u.def.value;
+ }
+ if (info->emitrelocations)
+ {
+ struct elf_link_hash_entry *sda = htab->sdata[0].sym;
+
+ if (sda != NULL && sda->ref_regular)
+ sda->root.u.def.section->flags |= SEC_KEEP;
+ sda = htab->sdata[1].sym;
+ if (sda != NULL && sda->ref_regular)
+ sda->root.u.def.section->flags |= SEC_KEEP;
+ }
+
+ if (htab->glink != NULL
+ && htab->glink->size != 0
+ && htab->elf.dynamic_sections_created)
+ {
+ htab->glink_pltresolve = htab->glink->size;
+ /* Space for the branch table. */
+ htab->glink->size += htab->glink->size / (GLINK_ENTRY_SIZE / 4) - 4;
+ /* Pad out to align the start of PLTresolve. */
+ htab->glink->size += -htab->glink->size & (htab->params->ppc476_workaround
+ ? 63 : 15);
+ htab->glink->size += GLINK_PLTRESOLVE;
+
+ if (htab->params->emit_stub_syms)
+ {
+ struct elf_link_hash_entry *sh;
+ sh = elf_link_hash_lookup (&htab->elf, "__glink",
+ TRUE, FALSE, FALSE);
+ if (sh == NULL)
+ return FALSE;
+ if (sh->root.type == bfd_link_hash_new)
+ {
+ sh->root.type = bfd_link_hash_defined;
+ sh->root.u.def.section = htab->glink;
+ sh->root.u.def.value = htab->glink_pltresolve;
+ sh->ref_regular = 1;
+ sh->def_regular = 1;
+ sh->ref_regular_nonweak = 1;
+ sh->forced_local = 1;
+ sh->non_elf = 0;
+ }
+ sh = elf_link_hash_lookup (&htab->elf, "__glink_PLTresolve",
+ TRUE, FALSE, FALSE);
+ if (sh == NULL)
+ return FALSE;
+ if (sh->root.type == bfd_link_hash_new)
+ {
+ sh->root.type = bfd_link_hash_defined;
+ sh->root.u.def.section = htab->glink;
+ sh->root.u.def.value = htab->glink->size - GLINK_PLTRESOLVE;
+ sh->ref_regular = 1;
+ sh->def_regular = 1;
+ sh->ref_regular_nonweak = 1;
+ sh->forced_local = 1;
+ sh->non_elf = 0;
+ }
+ }
+ }
+
+ if (htab->glink != NULL
+ && htab->glink->size != 0
+ && htab->glink_eh_frame != NULL
+ && !bfd_is_abs_section (htab->glink_eh_frame->output_section)
+ && _bfd_elf_eh_frame_present (info))
+ {
+ s = htab->glink_eh_frame;
+ s->size = sizeof (glink_eh_frame_cie) + 20;
+ if (info->shared)
+ {
+ s->size += 4;
+ if (htab->glink->size - GLINK_PLTRESOLVE + 8 >= 256)
+ s->size += 4;
+ }
+ }
+
+ /* We've now determined the sizes of the various dynamic sections.
+ Allocate memory for them. */
+ relocs = FALSE;
+ for (s = htab->elf.dynobj->sections; s != NULL; s = s->next)
+ {
+ bfd_boolean strip_section = TRUE;
+
+ if ((s->flags & SEC_LINKER_CREATED) == 0)
+ continue;
+
+ if (s == htab->plt
+ || s == htab->got)
+ {
+ /* We'd like to strip these sections if they aren't needed, but if
+ we've exported dynamic symbols from them we must leave them.
+ It's too late to tell BFD to get rid of the symbols. */
+ if (htab->elf.hplt != NULL)
+ strip_section = FALSE;
+ /* Strip this section if we don't need it; see the
+ comment below. */
+ }
+ else if (s == htab->iplt
+ || s == htab->glink
+ || s == htab->glink_eh_frame
+ || s == htab->sgotplt
+ || s == htab->sbss
+ || s == htab->dynbss
+ || s == htab->dynsbss)
+ {
+ /* Strip these too. */
+ }
+ else if (s == htab->sdata[0].section
+ || s == htab->sdata[1].section)
+ {
+ strip_section = (s->flags & SEC_KEEP) == 0;
+ }
+ else if (CONST_STRNEQ (bfd_get_section_name (htab->elf.dynobj, s),
+ ".rela"))
+ {
+ if (s->size != 0)
+ {
+ /* Remember whether there are any relocation sections. */
+ relocs = 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
+ {
+ /* It's not one of our sections, so don't allocate space. */
+ continue;
+ }
+
+ if (s->size == 0 && strip_section)
+ {
+ /* 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. */
+ s->flags |= SEC_EXCLUDE;
+ continue;
+ }
+
+ if ((s->flags & SEC_HAS_CONTENTS) == 0)
+ continue;
+
+ /* Allocate memory for the section contents. */
+ s->contents = bfd_zalloc (htab->elf.dynobj, s->size);
+ if (s->contents == NULL)
+ return FALSE;
+ }
+
+ if (htab->elf.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. */
+#define add_dynamic_entry(TAG, VAL) \
+ _bfd_elf_add_dynamic_entry (info, TAG, VAL)
+
+ if (info->executable)
+ {
+ if (!add_dynamic_entry (DT_DEBUG, 0))
+ return FALSE;
+ }
+
+ if (htab->plt != NULL && htab->plt->size != 0)
+ {
+ if (!add_dynamic_entry (DT_PLTGOT, 0)
+ || !add_dynamic_entry (DT_PLTRELSZ, 0)
+ || !add_dynamic_entry (DT_PLTREL, DT_RELA)
+ || !add_dynamic_entry (DT_JMPREL, 0))
+ return FALSE;
+ }
+
+ if (htab->plt_type == PLT_NEW
+ && htab->glink != NULL
+ && htab->glink->size != 0)
+ {
+ if (!add_dynamic_entry (DT_PPC_GOT, 0))
+ return FALSE;
+ if (!htab->params->no_tls_get_addr_opt
+ && htab->tls_get_addr != NULL
+ && htab->tls_get_addr->plt.plist != NULL
+ && !add_dynamic_entry (DT_PPC_OPT, PPC_OPT_TLS))
+ return FALSE;
+ }
+
+ if (relocs)
+ {
+ if (!add_dynamic_entry (DT_RELA, 0)
+ || !add_dynamic_entry (DT_RELASZ, 0)
+ || !add_dynamic_entry (DT_RELAENT, sizeof (Elf32_External_Rela)))
+ return FALSE;
+ }
+
+ /* If any dynamic relocs apply to a read-only section, then we
+ need a DT_TEXTREL entry. */
+ if ((info->flags & DF_TEXTREL) == 0)
+ elf_link_hash_traverse (elf_hash_table (info), maybe_set_textrel,
+ info);
+
+ if ((info->flags & DF_TEXTREL) != 0)
+ {
+ if (!add_dynamic_entry (DT_TEXTREL, 0))
+ return FALSE;
+ }
+ if (htab->is_vxworks
+ && !elf_vxworks_add_dynamic_entries (output_bfd, info))
+ return FALSE;
+ }
+#undef add_dynamic_entry
+
+ if (htab->glink_eh_frame != NULL
+ && htab->glink_eh_frame->contents != NULL)
+ {
+ unsigned char *p = htab->glink_eh_frame->contents;
+ bfd_vma val;
+
+ memcpy (p, glink_eh_frame_cie, sizeof (glink_eh_frame_cie));
+ /* CIE length (rewrite in case little-endian). */
+ bfd_put_32 (htab->elf.dynobj, sizeof (glink_eh_frame_cie) - 4, p);
+ p += sizeof (glink_eh_frame_cie);
+ /* FDE length. */
+ val = htab->glink_eh_frame->size - 4 - sizeof (glink_eh_frame_cie);
+ bfd_put_32 (htab->elf.dynobj, val, p);
+ p += 4;
+ /* CIE pointer. */
+ val = p - htab->glink_eh_frame->contents;
+ bfd_put_32 (htab->elf.dynobj, val, p);
+ p += 4;
+ /* Offset to .glink. Set later. */
+ p += 4;
+ /* .glink size. */
+ bfd_put_32 (htab->elf.dynobj, htab->glink->size, p);
+ p += 4;
+ /* Augmentation. */
+ p += 1;
+
+ if (info->shared
+ && htab->elf.dynamic_sections_created)
+ {
+ bfd_vma adv = (htab->glink->size - GLINK_PLTRESOLVE + 8) >> 2;
+ if (adv < 64)
+ *p++ = DW_CFA_advance_loc + adv;
+ else if (adv < 256)
+ {
+ *p++ = DW_CFA_advance_loc1;
+ *p++ = adv;
+ }
+ else if (adv < 65536)
+ {
+ *p++ = DW_CFA_advance_loc2;
+ bfd_put_16 (htab->elf.dynobj, adv, p);
+ p += 2;
+ }
+ else
+ {
+ *p++ = DW_CFA_advance_loc4;
+ bfd_put_32 (htab->elf.dynobj, adv, p);
+ p += 4;
+ }
+ *p++ = DW_CFA_register;
+ *p++ = 65;
+ p++;
+ *p++ = DW_CFA_advance_loc + 4;
+ *p++ = DW_CFA_restore_extended;
+ *p++ = 65;
+ }
+ BFD_ASSERT ((bfd_vma) ((p + 3 - htab->glink_eh_frame->contents) & -4)
+ == htab->glink_eh_frame->size);
+ }
+
+ return TRUE;
+}
+
+/* Arrange to have _SDA_BASE_ or _SDA2_BASE_ stripped from the output
+ if it looks like nothing is using them. */
+
+static void
+maybe_strip_sdasym (bfd *output_bfd, elf_linker_section_t *lsect)
+{
+ struct elf_link_hash_entry *sda = lsect->sym;
+
+ if (sda != NULL && !sda->ref_regular && sda->dynindx == -1)
+ {
+ asection *s;
+
+ s = bfd_get_section_by_name (output_bfd, lsect->name);
+ if (s == NULL || bfd_section_removed_from_list (output_bfd, s))
+ {
+ s = bfd_get_section_by_name (output_bfd, lsect->bss_name);
+ if (s == NULL || bfd_section_removed_from_list (output_bfd, s))
+ {
+ sda->def_regular = 0;
+ /* This is somewhat magic. See elf_link_output_extsym. */
+ sda->ref_dynamic = 1;
+ sda->forced_local = 0;
+ }
+ }
+ }
+}
+
+void
+ppc_elf_maybe_strip_sdata_syms (struct bfd_link_info *info)
+{
+ struct ppc_elf_link_hash_table *htab = ppc_elf_hash_table (info);
+
+ if (htab != NULL)
+ {
+ maybe_strip_sdasym (info->output_bfd, &htab->sdata[0]);
+ maybe_strip_sdasym (info->output_bfd, &htab->sdata[1]);
+ }
+}
+
+
+/* Return TRUE if symbol should be hashed in the `.gnu.hash' section. */
+
+static bfd_boolean
+ppc_elf_hash_symbol (struct elf_link_hash_entry *h)
+{
+ if (h->plt.plist != NULL
+ && !h->def_regular
+ && (!h->pointer_equality_needed
+ || !h->ref_regular_nonweak))
+ return FALSE;
+
+ return _bfd_elf_hash_symbol (h);
+}
+
+#define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0]))
+
+/* Relaxation trampolines. r12 is available for clobbering (r11, is
+ used for some functions that are allowed to break the ABI). */
+static const int shared_stub_entry[] =
+ {
+ 0x7c0802a6, /* mflr 0 */
+ 0x429f0005, /* bcl 20, 31, .Lxxx */
+ 0x7d8802a6, /* mflr 12 */
+ 0x3d8c0000, /* addis 12, 12, (xxx-.Lxxx)@ha */
+ 0x398c0000, /* addi 12, 12, (xxx-.Lxxx)@l */
+ 0x7c0803a6, /* mtlr 0 */
+ 0x7d8903a6, /* mtctr 12 */
+ 0x4e800420, /* bctr */
+ };
+
+static const int stub_entry[] =
+ {
+ 0x3d800000, /* lis 12,xxx@ha */
+ 0x398c0000, /* addi 12,12,xxx@l */
+ 0x7d8903a6, /* mtctr 12 */
+ 0x4e800420, /* bctr */
+ };
+
+struct ppc_elf_relax_info
+{
+ unsigned int workaround_size;
+};
+
+/* This function implements long branch trampolines, and the ppc476
+ icache bug workaround. Any section needing trampolines or patch
+ space for the workaround has its size extended so that we can
+ add trampolines at the end of the section. */
+
+static bfd_boolean
+ppc_elf_relax_section (bfd *abfd,
+ asection *isec,
+ struct bfd_link_info *link_info,
+ bfd_boolean *again)
+{
+ struct one_fixup
+ {
+ struct one_fixup *next;
+ asection *tsec;
+ /* Final link, can use the symbol offset. For a
+ relocatable link we use the symbol's index. */
+ bfd_vma toff;
+ bfd_vma trampoff;
+ };
+
+ Elf_Internal_Shdr *symtab_hdr;
+ bfd_byte *contents = NULL;
+ Elf_Internal_Sym *isymbuf = NULL;
+ Elf_Internal_Rela *internal_relocs = NULL;
+ Elf_Internal_Rela *irel, *irelend = NULL;
+ struct one_fixup *fixups = NULL;
+ struct ppc_elf_relax_info *relax_info = NULL;
+ unsigned changes = 0;
+ bfd_boolean workaround_change;
+ struct ppc_elf_link_hash_table *htab;
+ bfd_size_type trampbase, trampoff, newsize;
+ asection *got2;
+ bfd_boolean maybe_pasted;
+
+ *again = FALSE;
+
+ /* No need to do anything with non-alloc or non-code sections. */
+ if ((isec->flags & SEC_ALLOC) == 0
+ || (isec->flags & SEC_CODE) == 0
+ || (isec->flags & SEC_LINKER_CREATED) != 0
+ || isec->size < 4)
+ return TRUE;
+
+ /* We cannot represent the required PIC relocs in the output, so don't
+ do anything. The linker doesn't support mixing -shared and -r
+ anyway. */
+ if (link_info->relocatable && link_info->shared)
+ return TRUE;
+
+ htab = ppc_elf_hash_table (link_info);
+ if (htab == NULL)
+ return TRUE;
+
+ isec->size = (isec->size + 3) & -4;
+ if (isec->rawsize == 0)
+ isec->rawsize = isec->size;
+ trampbase = isec->size;
+
+ BFD_ASSERT (isec->sec_info_type == SEC_INFO_TYPE_NONE
+ || isec->sec_info_type == SEC_INFO_TYPE_TARGET);
+ isec->sec_info_type = SEC_INFO_TYPE_TARGET;
+
+ if (htab->params->ppc476_workaround)
+ {
+ if (elf_section_data (isec)->sec_info == NULL)
+ {
+ elf_section_data (isec)->sec_info
+ = bfd_zalloc (abfd, sizeof (struct ppc_elf_relax_info));
+ if (elf_section_data (isec)->sec_info == NULL)
+ return FALSE;
+ }
+ relax_info = elf_section_data (isec)->sec_info;
+ trampbase -= relax_info->workaround_size;
+ }
+
+ maybe_pasted = (strcmp (isec->output_section->name, ".init") == 0
+ || strcmp (isec->output_section->name, ".fini") == 0);
+ /* Space for a branch around any trampolines. */
+ trampoff = trampbase;
+ if (maybe_pasted && trampbase == isec->rawsize)
+ trampoff += 4;
+
+ symtab_hdr = &elf_symtab_hdr (abfd);
+
+ if (htab->params->branch_trampolines)
+ {
+ /* Get a copy of the native relocations. */
+ if (isec->reloc_count != 0)
+ {
+ internal_relocs = _bfd_elf_link_read_relocs (abfd, isec, NULL, NULL,
+ link_info->keep_memory);
+ if (internal_relocs == NULL)
+ goto error_return;
+ }
+
+ got2 = bfd_get_section_by_name (abfd, ".got2");
+
+ irelend = internal_relocs + isec->reloc_count;
+ for (irel = internal_relocs; irel < irelend; irel++)
+ {
+ unsigned long r_type = ELF32_R_TYPE (irel->r_info);
+ bfd_vma toff, roff;
+ asection *tsec;
+ struct one_fixup *f;
+ size_t insn_offset = 0;
+ bfd_vma max_branch_offset, val;
+ bfd_byte *hit_addr;
+ unsigned long t0;
+ struct elf_link_hash_entry *h;
+ struct plt_entry **plist;
+ unsigned char sym_type;
+
+ switch (r_type)
+ {
+ case R_PPC_REL24:
+ case R_PPC_LOCAL24PC:
+ case R_PPC_PLTREL24:
+ max_branch_offset = 1 << 25;
+ break;
+
+ case R_PPC_REL14:
+ case R_PPC_REL14_BRTAKEN:
+ case R_PPC_REL14_BRNTAKEN:
+ max_branch_offset = 1 << 15;
+ break;
+
+ default:
+ continue;
+ }
+
+ /* Get the value of the symbol referred to by the reloc. */
+ h = NULL;
+ if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
+ {
+ /* A local symbol. */
+ Elf_Internal_Sym *isym;
+
+ /* Read this BFD's local symbols. */
+ if (isymbuf == NULL)
+ {
+ isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
+ if (isymbuf == NULL)
+ isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
+ symtab_hdr->sh_info, 0,
+ NULL, NULL, NULL);
+ if (isymbuf == 0)
+ goto error_return;
+ }
+ isym = isymbuf + ELF32_R_SYM (irel->r_info);
+ if (isym->st_shndx == SHN_UNDEF)
+ tsec = bfd_und_section_ptr;
+ else if (isym->st_shndx == SHN_ABS)
+ tsec = bfd_abs_section_ptr;
+ else if (isym->st_shndx == SHN_COMMON)
+ tsec = bfd_com_section_ptr;
+ else
+ tsec = bfd_section_from_elf_index (abfd, isym->st_shndx);
+
+ toff = isym->st_value;
+ sym_type = ELF_ST_TYPE (isym->st_info);
+ }
+ else
+ {
+ /* Global symbol handling. */
+ unsigned long indx;
+
+ indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info;
+ h = elf_sym_hashes (abfd)[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)
+ {
+ tsec = h->root.u.def.section;
+ toff = h->root.u.def.value;
+ }
+ else if (h->root.type == bfd_link_hash_undefined
+ || h->root.type == bfd_link_hash_undefweak)
+ {
+ tsec = bfd_und_section_ptr;
+ toff = link_info->relocatable ? indx : 0;
+ }
+ else
+ continue;
+
+ /* If this branch is to __tls_get_addr then we may later
+ optimise away the call. We won't be needing a long-
+ branch stub in that case. */
+ if (link_info->executable
+ && !link_info->relocatable
+ && h == htab->tls_get_addr
+ && irel != internal_relocs)
+ {
+ unsigned long t_symndx = ELF32_R_SYM (irel[-1].r_info);
+ unsigned long t_rtype = ELF32_R_TYPE (irel[-1].r_info);
+ unsigned int tls_mask = 0;
+
+ /* The previous reloc should be one of R_PPC_TLSGD or
+ R_PPC_TLSLD, or for older object files, a reloc
+ on the __tls_get_addr arg setup insn. Get tls
+ mask bits from the symbol on that reloc. */
+ if (t_symndx < symtab_hdr->sh_info)
+ {
+ bfd_vma *local_got_offsets = elf_local_got_offsets (abfd);
+
+ if (local_got_offsets != NULL)
+ {
+ struct plt_entry **local_plt = (struct plt_entry **)
+ (local_got_offsets + symtab_hdr->sh_info);
+ char *lgot_masks = (char *)
+ (local_plt + symtab_hdr->sh_info);
+ tls_mask = lgot_masks[t_symndx];
+ }
+ }
+ else
+ {
+ struct elf_link_hash_entry *th
+ = elf_sym_hashes (abfd)[t_symndx - symtab_hdr->sh_info];
+
+ while (th->root.type == bfd_link_hash_indirect
+ || th->root.type == bfd_link_hash_warning)
+ th = (struct elf_link_hash_entry *) th->root.u.i.link;
+
+ tls_mask
+ = ((struct ppc_elf_link_hash_entry *) th)->tls_mask;
+ }
+
+ /* The mask bits tell us if the call will be
+ optimised away. */
+ if ((tls_mask & TLS_TLS) != 0 && (tls_mask & TLS_GD) == 0
+ && (t_rtype == R_PPC_TLSGD
+ || t_rtype == R_PPC_GOT_TLSGD16
+ || t_rtype == R_PPC_GOT_TLSGD16_LO))
+ continue;
+ if ((tls_mask & TLS_TLS) != 0 && (tls_mask & TLS_LD) == 0
+ && (t_rtype == R_PPC_TLSLD
+ || t_rtype == R_PPC_GOT_TLSLD16
+ || t_rtype == R_PPC_GOT_TLSLD16_LO))
+ continue;
+ }
+
+ sym_type = h->type;
+ }
+
+ /* The condition here under which we call find_plt_ent must
+ match that in relocate_section. If we call find_plt_ent here
+ but not in relocate_section, or vice versa, then the branch
+ destination used here may be incorrect. */
+ plist = NULL;
+ if (h != NULL)
+ {
+ /* We know is_branch_reloc (r_type) is true. */
+ if (h->type == STT_GNU_IFUNC
+ || r_type == R_PPC_PLTREL24)
+ plist = &h->plt.plist;
+ }
+ else if (sym_type == STT_GNU_IFUNC
+ && elf_local_got_offsets (abfd) != NULL)
+ {
+ bfd_vma *local_got_offsets = elf_local_got_offsets (abfd);
+ struct plt_entry **local_plt = (struct plt_entry **)
+ (local_got_offsets + symtab_hdr->sh_info);
+ plist = local_plt + ELF32_R_SYM (irel->r_info);
+ }
+ if (plist != NULL)
+ {
+ bfd_vma addend = 0;
+ struct plt_entry *ent;
+
+ if (r_type == R_PPC_PLTREL24 && link_info->shared)
+ addend = irel->r_addend;
+ ent = find_plt_ent (plist, got2, addend);
+ if (ent != NULL)
+ {
+ if (htab->plt_type == PLT_NEW
+ || h == NULL
+ || !htab->elf.dynamic_sections_created
+ || h->dynindx == -1)
+ {
+ tsec = htab->glink;
+ toff = ent->glink_offset;
+ }
+ else
+ {
+ tsec = htab->plt;
+ toff = ent->plt.offset;
+ }
+ }
+ }
+
+ /* If the branch and target are in the same section, you have
+ no hope of adding stubs. We'll error out later should the
+ branch overflow. */
+ if (tsec == isec)
+ continue;
+
+ /* There probably isn't any reason to handle symbols in
+ SEC_MERGE sections; SEC_MERGE doesn't seem a likely
+ attribute for a code section, and we are only looking at
+ branches. However, implement it correctly here as a
+ reference for other target relax_section functions. */
+ if (0 && tsec->sec_info_type == SEC_INFO_TYPE_MERGE)
+ {
+ /* At this stage in linking, no SEC_MERGE symbol has been
+ adjusted, so all references to such symbols need to be
+ passed through _bfd_merged_section_offset. (Later, in
+ relocate_section, all SEC_MERGE symbols *except* for
+ section symbols have been adjusted.)
+
+ gas may reduce relocations against symbols in SEC_MERGE
+ sections to a relocation against the section symbol when
+ the original addend was zero. When the reloc is against
+ a section symbol we should include the addend in the
+ offset passed to _bfd_merged_section_offset, since the
+ location of interest is the original symbol. On the
+ other hand, an access to "sym+addend" where "sym" is not
+ a section symbol should not include the addend; Such an
+ access is presumed to be an offset from "sym"; The
+ location of interest is just "sym". */
+ if (sym_type == STT_SECTION)
+ toff += irel->r_addend;
+
+ toff
+ = _bfd_merged_section_offset (abfd, &tsec,
+ elf_section_data (tsec)->sec_info,
+ toff);
+
+ if (sym_type != STT_SECTION)
+ toff += irel->r_addend;
+ }
+ /* PLTREL24 addends are special. */
+ else if (r_type != R_PPC_PLTREL24)
+ toff += irel->r_addend;
+
+ /* Attempted -shared link of non-pic code loses. */
+ if ((!link_info->relocatable
+ && tsec == bfd_und_section_ptr)
+ || tsec->output_section == NULL
+ || (tsec->owner != NULL
+ && (tsec->owner->flags & BFD_PLUGIN) != 0))
+ continue;
+
+ roff = irel->r_offset;
+
+ /* If the branch is in range, no need to do anything. */
+ if (tsec != bfd_und_section_ptr
+ && (!link_info->relocatable
+ /* A relocatable link may have sections moved during
+ final link, so do not presume they remain in range. */
+ || tsec->output_section == isec->output_section))
+ {
+ bfd_vma symaddr, reladdr;
+
+ symaddr = tsec->output_section->vma + tsec->output_offset + toff;
+ reladdr = isec->output_section->vma + isec->output_offset + roff;
+ if (symaddr - reladdr + max_branch_offset
+ < 2 * max_branch_offset)
+ continue;
+ }
+
+ /* Look for an existing fixup to this address. */
+ for (f = fixups; f ; f = f->next)
+ if (f->tsec == tsec && f->toff == toff)
+ break;
+
+ if (f == NULL)
+ {
+ size_t size;
+ unsigned long stub_rtype;
+
+ val = trampoff - roff;
+ if (val >= max_branch_offset)
+ /* Oh dear, we can't reach a trampoline. Don't try to add
+ one. We'll report an error later. */
+ continue;
+
+ if (link_info->shared)
+ {
+ size = 4 * ARRAY_SIZE (shared_stub_entry);
+ insn_offset = 12;
+ }
+ else
+ {
+ size = 4 * ARRAY_SIZE (stub_entry);
+ insn_offset = 0;
+ }
+ stub_rtype = R_PPC_RELAX;
+ if (tsec == htab->plt
+ || tsec == htab->glink)
+ {
+ stub_rtype = R_PPC_RELAX_PLT;
+ if (r_type == R_PPC_PLTREL24)
+ stub_rtype = R_PPC_RELAX_PLTREL24;
+ }
+
+ /* Hijack the old relocation. Since we need two
+ relocations for this use a "composite" reloc. */
+ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
+ stub_rtype);
+ irel->r_offset = trampoff + insn_offset;
+ if (r_type == R_PPC_PLTREL24
+ && stub_rtype != R_PPC_RELAX_PLTREL24)
+ irel->r_addend = 0;
+
+ /* Record the fixup so we don't do it again this section. */
+ f = bfd_malloc (sizeof (*f));
+ f->next = fixups;
+ f->tsec = tsec;
+ f->toff = toff;
+ f->trampoff = trampoff;
+ fixups = f;
+
+ trampoff += size;
+ changes++;
+ }
+ else
+ {
+ val = f->trampoff - roff;
+ if (val >= max_branch_offset)
+ continue;
+
+ /* Nop out the reloc, since we're finalizing things here. */
+ irel->r_info = ELF32_R_INFO (0, R_PPC_NONE);
+ }
+
+ /* Get the section contents. */
+ if (contents == NULL)
+ {
+ /* Get cached copy if it exists. */
+ if (elf_section_data (isec)->this_hdr.contents != NULL)
+ contents = elf_section_data (isec)->this_hdr.contents;
+ /* Go get them off disk. */
+ else if (!bfd_malloc_and_get_section (abfd, isec, &contents))
+ goto error_return;
+ }
+
+ /* Fix up the existing branch to hit the trampoline. */
+ hit_addr = contents + roff;
+ switch (r_type)
+ {
+ case R_PPC_REL24:
+ case R_PPC_LOCAL24PC:
+ case R_PPC_PLTREL24:
+ t0 = bfd_get_32 (abfd, hit_addr);
+ t0 &= ~0x3fffffc;
+ t0 |= val & 0x3fffffc;
+ bfd_put_32 (abfd, t0, hit_addr);
+ break;
+
+ case R_PPC_REL14:
+ case R_PPC_REL14_BRTAKEN:
+ case R_PPC_REL14_BRNTAKEN:
+ t0 = bfd_get_32 (abfd, hit_addr);
+ t0 &= ~0xfffc;
+ t0 |= val & 0xfffc;
+ bfd_put_32 (abfd, t0, hit_addr);
+ break;
+ }
+ }
+
+ while (fixups != NULL)
+ {
+ struct one_fixup *f = fixups;
+ fixups = fixups->next;
+ free (f);
+ }
+ }
+
+ workaround_change = FALSE;
+ newsize = trampoff;
+ if (htab->params->ppc476_workaround
+ && (!link_info->relocatable
+ || isec->output_section->alignment_power >= htab->params->pagesize_p2))
+ {
+ bfd_vma addr, end_addr;
+ unsigned int crossings;
+ bfd_vma pagesize = (bfd_vma) 1 << htab->params->pagesize_p2;
+
+ addr = isec->output_section->vma + isec->output_offset;
+ end_addr = addr + trampoff;
+ addr &= -pagesize;
+ crossings = ((end_addr & -pagesize) - addr) >> htab->params->pagesize_p2;
+ if (crossings != 0)
+ {
+ /* Keep space aligned, to ensure the patch code itself does
+ not cross a page. Don't decrease size calculated on a
+ previous pass as otherwise we might never settle on a layout. */
+ newsize = 15 - ((end_addr - 1) & 15);
+ newsize += crossings * 16;
+ if (relax_info->workaround_size < newsize)
+ {
+ relax_info->workaround_size = newsize;
+ workaround_change = TRUE;
+ }
+ /* Ensure relocate_section is called. */
+ isec->flags |= SEC_RELOC;
+ }
+ newsize = trampoff + relax_info->workaround_size;
+ }
+
+ if (changes || workaround_change)
+ isec->size = newsize;
+
+ if (isymbuf != NULL
+ && symtab_hdr->contents != (unsigned char *) isymbuf)
+ {
+ if (! link_info->keep_memory)
+ free (isymbuf);
+ else
+ {
+ /* Cache the symbols for elf_link_input_bfd. */
+ symtab_hdr->contents = (unsigned char *) isymbuf;
+ }
+ }
+
+ if (contents != NULL
+ && elf_section_data (isec)->this_hdr.contents != contents)
+ {
+ if (!changes && !link_info->keep_memory)
+ free (contents);
+ else
+ {
+ /* Cache the section contents for elf_link_input_bfd. */
+ elf_section_data (isec)->this_hdr.contents = contents;
+ }
+ }
+
+ if (changes != 0)
+ {
+ /* Append sufficient NOP relocs so we can write out relocation
+ information for the trampolines. */
+ Elf_Internal_Shdr *rel_hdr;
+ Elf_Internal_Rela *new_relocs = bfd_malloc ((changes + isec->reloc_count)
+ * sizeof (*new_relocs));
+ unsigned ix;
+
+ if (!new_relocs)
+ goto error_return;
+ memcpy (new_relocs, internal_relocs,
+ isec->reloc_count * sizeof (*new_relocs));
+ for (ix = changes; ix--;)
+ {
+ irel = new_relocs + ix + isec->reloc_count;
+
+ irel->r_info = ELF32_R_INFO (0, R_PPC_NONE);
+ }
+ if (internal_relocs != elf_section_data (isec)->relocs)
+ free (internal_relocs);
+ elf_section_data (isec)->relocs = new_relocs;
+ isec->reloc_count += changes;
+ rel_hdr = _bfd_elf_single_rel_hdr (isec);
+ rel_hdr->sh_size += changes * rel_hdr->sh_entsize;
+ }
+ else if (internal_relocs != NULL
+ && elf_section_data (isec)->relocs != internal_relocs)
+ free (internal_relocs);
+
+ *again = changes != 0 || workaround_change;
+ return TRUE;
+
+ error_return:
+ while (fixups != NULL)
+ {
+ struct one_fixup *f = fixups;
+ fixups = fixups->next;
+ free (f);
+ }
+ if (isymbuf != NULL && (unsigned char *) isymbuf != symtab_hdr->contents)
+ free (isymbuf);
+ if (contents != NULL
+ && elf_section_data (isec)->this_hdr.contents != contents)
+ free (contents);
+ if (internal_relocs != NULL
+ && elf_section_data (isec)->relocs != internal_relocs)
+ free (internal_relocs);
+ return FALSE;
+}
+
+/* What to do when ld finds relocations against symbols defined in
+ discarded sections. */
+
+static unsigned int
+ppc_elf_action_discarded (asection *sec)
+{
+ if (strcmp (".fixup", sec->name) == 0)
+ return 0;
+
+ if (strcmp (".got2", sec->name) == 0)
+ return 0;
+
+ return _bfd_elf_default_action_discarded (sec);
+}
+
+/* Fill in the address for a pointer generated in a linker section. */
+
+static bfd_vma
+elf_finish_pointer_linker_section (bfd *input_bfd,
+ elf_linker_section_t *lsect,
+ struct elf_link_hash_entry *h,
+ bfd_vma relocation,
+ const Elf_Internal_Rela *rel)
+{
+ elf_linker_section_pointers_t *linker_section_ptr;
+
+ BFD_ASSERT (lsect != NULL);
+
+ if (h != NULL)
+ {
+ /* Handle global symbol. */
+ struct ppc_elf_link_hash_entry *eh;
+
+ eh = (struct ppc_elf_link_hash_entry *) h;
+ BFD_ASSERT (eh->elf.def_regular);
+ linker_section_ptr = eh->linker_section_pointer;
+ }
+ else
+ {
+ /* Handle local symbol. */
+ unsigned long r_symndx = ELF32_R_SYM (rel->r_info);
+
+ BFD_ASSERT (is_ppc_elf (input_bfd));
+ BFD_ASSERT (elf_local_ptr_offsets (input_bfd) != NULL);
+ linker_section_ptr = elf_local_ptr_offsets (input_bfd)[r_symndx];
+ }
+
+ linker_section_ptr = elf_find_pointer_linker_section (linker_section_ptr,
+ rel->r_addend,
+ lsect);
+ BFD_ASSERT (linker_section_ptr != NULL);
+
+ /* Offset will always be a multiple of four, so use the bottom bit
+ as a "written" flag. */
+ if ((linker_section_ptr->offset & 1) == 0)
+ {
+ bfd_put_32 (lsect->section->owner,
+ relocation + linker_section_ptr->addend,
+ lsect->section->contents + linker_section_ptr->offset);
+ linker_section_ptr->offset += 1;
+ }
+
+ relocation = (lsect->section->output_section->vma
+ + lsect->section->output_offset
+ + linker_section_ptr->offset - 1
+ - SYM_VAL (lsect->sym));
+
+#ifdef DEBUG
+ fprintf (stderr,
+ "Finish pointer in linker section %s, offset = %ld (0x%lx)\n",
+ lsect->name, (long) relocation, (long) relocation);
+#endif
+
+ return relocation;
+}
+
+#define PPC_LO(v) ((v) & 0xffff)
+#define PPC_HI(v) (((v) >> 16) & 0xffff)
+#define PPC_HA(v) PPC_HI ((v) + 0x8000)
+
+static void
+write_glink_stub (struct plt_entry *ent, asection *plt_sec, unsigned char *p,
+ struct bfd_link_info *info)
+{
+ struct ppc_elf_link_hash_table *htab = ppc_elf_hash_table (info);
+ bfd *output_bfd = info->output_bfd;
+ bfd_vma plt;
+
+ plt = ((ent->plt.offset & ~1)
+ + plt_sec->output_section->vma
+ + plt_sec->output_offset);
+
+ if (info->shared)
+ {
+ bfd_vma got = 0;
+
+ if (ent->addend >= 32768)
+ got = (ent->addend
+ + ent->sec->output_section->vma
+ + ent->sec->output_offset);
+ else if (htab->elf.hgot != NULL)
+ got = SYM_VAL (htab->elf.hgot);
+
+ plt -= got;
+
+ if (plt + 0x8000 < 0x10000)
+ {
+ bfd_put_32 (output_bfd, LWZ_11_30 + PPC_LO (plt), p);
+ p += 4;
+ bfd_put_32 (output_bfd, MTCTR_11, p);
+ p += 4;
+ bfd_put_32 (output_bfd, BCTR, p);
+ p += 4;
+ bfd_put_32 (output_bfd, htab->params->ppc476_workaround ? BA : NOP, p);
+ p += 4;
+ }
+ else
+ {
+ bfd_put_32 (output_bfd, ADDIS_11_30 + PPC_HA (plt), p);
+ p += 4;
+ bfd_put_32 (output_bfd, LWZ_11_11 + PPC_LO (plt), p);
+ p += 4;
+ bfd_put_32 (output_bfd, MTCTR_11, p);
+ p += 4;
+ bfd_put_32 (output_bfd, BCTR, p);
+ p += 4;
+ }
+ }
+ else
+ {
+ bfd_put_32 (output_bfd, LIS_11 + PPC_HA (plt), p);
+ p += 4;
+ bfd_put_32 (output_bfd, LWZ_11_11 + PPC_LO (plt), p);
+ p += 4;
+ bfd_put_32 (output_bfd, MTCTR_11, p);
+ p += 4;
+ bfd_put_32 (output_bfd, BCTR, p);
+ p += 4;
+ }
+}
+
+/* Return true if symbol is defined statically. */
+
+static bfd_boolean
+is_static_defined (struct elf_link_hash_entry *h)
+{
+ return ((h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak)
+ && h->root.u.def.section != NULL
+ && h->root.u.def.section->output_section != NULL);
+}
+
+/* If INSN is an opcode that may be used with an @tls operand, return
+ the transformed insn for TLS optimisation, otherwise return 0. If
+ REG is non-zero only match an insn with RB or RA equal to REG. */
+
+unsigned int
+_bfd_elf_ppc_at_tls_transform (unsigned int insn, unsigned int reg)
+{
+ unsigned int rtra;
+
+ if ((insn & (0x3f << 26)) != 31 << 26)
+ return 0;
+
+ if (reg == 0 || ((insn >> 11) & 0x1f) == reg)
+ rtra = insn & ((1 << 26) - (1 << 16));
+ else if (((insn >> 16) & 0x1f) == reg)
+ rtra = (insn & (0x1f << 21)) | ((insn & (0x1f << 11)) << 5);
+ else
+ return 0;
+
+ if ((insn & (0x3ff << 1)) == 266 << 1)
+ /* add -> addi. */
+ insn = 14 << 26;
+ else if ((insn & (0x1f << 1)) == 23 << 1
+ && ((insn & (0x1f << 6)) < 14 << 6
+ || ((insn & (0x1f << 6)) >= 16 << 6
+ && (insn & (0x1f << 6)) < 24 << 6)))
+ /* load and store indexed -> dform. */
+ insn = (32 | ((insn >> 6) & 0x1f)) << 26;
+ else if ((insn & (((0x1a << 5) | 0x1f) << 1)) == 21 << 1)
+ /* ldx, ldux, stdx, stdux -> ld, ldu, std, stdu. */
+ insn = ((58 | ((insn >> 6) & 4)) << 26) | ((insn >> 6) & 1);
+ else if ((insn & (((0x1f << 5) | 0x1f) << 1)) == 341 << 1)
+ /* lwax -> lwa. */
+ insn = (58 << 26) | 2;
+ else
+ return 0;
+ insn |= rtra;
+ return insn;
+}
+
+/* If INSN is an opcode that may be used with an @tprel operand, return
+ the transformed insn for an undefined weak symbol, ie. with the
+ thread pointer REG operand removed. Otherwise return 0. */
+
+unsigned int
+_bfd_elf_ppc_at_tprel_transform (unsigned int insn, unsigned int reg)
+{
+ if ((insn & (0x1f << 16)) == reg << 16
+ && ((insn & (0x3f << 26)) == 14u << 26 /* addi */
+ || (insn & (0x3f << 26)) == 15u << 26 /* addis */
+ || (insn & (0x3f << 26)) == 32u << 26 /* lwz */
+ || (insn & (0x3f << 26)) == 34u << 26 /* lbz */
+ || (insn & (0x3f << 26)) == 36u << 26 /* stw */
+ || (insn & (0x3f << 26)) == 38u << 26 /* stb */
+ || (insn & (0x3f << 26)) == 40u << 26 /* lhz */
+ || (insn & (0x3f << 26)) == 42u << 26 /* lha */
+ || (insn & (0x3f << 26)) == 44u << 26 /* sth */
+ || (insn & (0x3f << 26)) == 46u << 26 /* lmw */
+ || (insn & (0x3f << 26)) == 47u << 26 /* stmw */
+ || (insn & (0x3f << 26)) == 48u << 26 /* lfs */
+ || (insn & (0x3f << 26)) == 50u << 26 /* lfd */
+ || (insn & (0x3f << 26)) == 52u << 26 /* stfs */
+ || (insn & (0x3f << 26)) == 54u << 26 /* stfd */
+ || ((insn & (0x3f << 26)) == 58u << 26 /* lwa,ld,lmd */
+ && (insn & 3) != 1)
+ || ((insn & (0x3f << 26)) == 62u << 26 /* std, stmd */
+ && ((insn & 3) == 0 || (insn & 3) == 3))))
+ {
+ insn &= ~(0x1f << 16);
+ }
+ else if ((insn & (0x1f << 21)) == reg << 21
+ && ((insn & (0x3e << 26)) == 24u << 26 /* ori, oris */
+ || (insn & (0x3e << 26)) == 26u << 26 /* xori,xoris */
+ || (insn & (0x3e << 26)) == 28u << 26 /* andi,andis */))
+ {
+ insn &= ~(0x1f << 21);
+ insn |= (insn & (0x1f << 16)) << 5;
+ if ((insn & (0x3e << 26)) == 26 << 26 /* xori,xoris */)
+ insn -= 2 >> 26; /* convert to ori,oris */
+ }
+ else
+ insn = 0;
+ return insn;
+}
+
+static bfd_boolean
+is_insn_ds_form (unsigned int insn)
+{
+ return ((insn & (0x3f << 26)) == 58u << 26 /* ld,ldu,lwa */
+ || (insn & (0x3f << 26)) == 62u << 26 /* std,stdu,stq */
+ || (insn & (0x3f << 26)) == 57u << 26 /* lfdp */
+ || (insn & (0x3f << 26)) == 61u << 26 /* stfdp */);
+}
+
+static bfd_boolean
+is_insn_dq_form (unsigned int insn)
+{
+ return (insn & (0x3f << 26)) == 56u << 26; /* lq */
+}
+
+/* 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
+ relocatable 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 relocatable 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 bfd_boolean
+ppc_elf_relocate_section (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;
+ struct ppc_elf_link_hash_table *htab;
+ Elf_Internal_Rela *rel;
+ Elf_Internal_Rela *relend;
+ Elf_Internal_Rela outrel;
+ asection *got2;
+ bfd_vma *local_got_offsets;
+ bfd_boolean ret = TRUE;
+ bfd_vma d_offset = (bfd_big_endian (output_bfd) ? 2 : 0);
+ bfd_boolean is_vxworks_tls;
+
+#ifdef DEBUG
+ _bfd_error_handler ("ppc_elf_relocate_section called for %B section %A, "
+ "%ld relocations%s",
+ input_bfd, input_section,
+ (long) input_section->reloc_count,
+ (info->relocatable) ? " (relocatable)" : "");
+#endif
+
+ got2 = bfd_get_section_by_name (input_bfd, ".got2");
+
+ /* Initialize howto table if not already done. */
+ if (!ppc_elf_howto_table[R_PPC_ADDR32])
+ ppc_elf_howto_init ();
+
+ htab = ppc_elf_hash_table (info);
+ local_got_offsets = elf_local_got_offsets (input_bfd);
+ symtab_hdr = &elf_symtab_hdr (input_bfd);
+ sym_hashes = elf_sym_hashes (input_bfd);
+ /* We have to handle relocations in vxworks .tls_vars sections
+ specially, because the dynamic loader is 'weird'. */
+ is_vxworks_tls = (htab->is_vxworks && info->shared
+ && !strcmp (input_section->output_section->name,
+ ".tls_vars"));
+ rel = relocs;
+ relend = relocs + input_section->reloc_count;
+ for (; rel < relend; rel++)
+ {
+ enum elf_ppc_reloc_type r_type;
+ bfd_vma addend;
+ bfd_reloc_status_type r;
+ Elf_Internal_Sym *sym;
+ asection *sec;
+ struct elf_link_hash_entry *h;
+ const char *sym_name;
+ reloc_howto_type *howto;
+ unsigned long r_symndx;
+ bfd_vma relocation;
+ bfd_vma branch_bit, from;
+ bfd_boolean unresolved_reloc;
+ bfd_boolean warned;
+ unsigned int tls_type, tls_mask, tls_gd;
+ struct plt_entry **ifunc;
+ struct reloc_howto_struct alt_howto;
+
+ r_type = ELF32_R_TYPE (rel->r_info);
+ sym = NULL;
+ sec = NULL;
+ h = NULL;
+ unresolved_reloc = FALSE;
+ warned = FALSE;
+ r_symndx = ELF32_R_SYM (rel->r_info);
+
+ if (r_symndx < symtab_hdr->sh_info)
+ {
+ sym = local_syms + r_symndx;
+ sec = local_sections[r_symndx];
+ sym_name = bfd_elf_sym_name (input_bfd, symtab_hdr, sym, sec);
+
+ relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
+ }
+ else
+ {
+ bfd_boolean ignored;
+
+ RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
+ r_symndx, symtab_hdr, sym_hashes,
+ h, sec, relocation,
+ unresolved_reloc, warned, ignored);
+
+ sym_name = h->root.root.string;
+ }
+
+ if (sec != NULL && discarded_section (sec))
+ {
+ /* For relocs against symbols from removed linkonce sections,
+ or sections discarded by a linker script, we just want the
+ section contents zeroed. Avoid any special processing. */
+ howto = NULL;
+ if (r_type < R_PPC_max)
+ howto = ppc_elf_howto_table[r_type];
+ RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+ rel, 1, relend, howto, 0, contents);
+ }
+
+ if (info->relocatable)
+ {
+ if (got2 != NULL
+ && r_type == R_PPC_PLTREL24
+ && rel->r_addend != 0)
+ {
+ /* R_PPC_PLTREL24 is rather special. If non-zero, the
+ addend specifies the GOT pointer offset within .got2. */
+ rel->r_addend += got2->output_offset;
+ }
+ if (r_type != R_PPC_RELAX_PLT
+ && r_type != R_PPC_RELAX_PLTREL24
+ && r_type != R_PPC_RELAX)
+ continue;
+ }
+
+ /* TLS optimizations. Replace instruction sequences and relocs
+ based on information we collected in tls_optimize. We edit
+ RELOCS so that --emit-relocs will output something sensible
+ for the final instruction stream. */
+ tls_mask = 0;
+ tls_gd = 0;
+ if (h != NULL)
+ tls_mask = ((struct ppc_elf_link_hash_entry *) h)->tls_mask;
+ else if (local_got_offsets != NULL)
+ {
+ struct plt_entry **local_plt;
+ char *lgot_masks;
+ local_plt
+ = (struct plt_entry **) (local_got_offsets + symtab_hdr->sh_info);
+ lgot_masks = (char *) (local_plt + symtab_hdr->sh_info);
+ tls_mask = lgot_masks[r_symndx];
+ }
+
+ /* Ensure reloc mapping code below stays sane. */
+ if ((R_PPC_GOT_TLSLD16 & 3) != (R_PPC_GOT_TLSGD16 & 3)
+ || (R_PPC_GOT_TLSLD16_LO & 3) != (R_PPC_GOT_TLSGD16_LO & 3)
+ || (R_PPC_GOT_TLSLD16_HI & 3) != (R_PPC_GOT_TLSGD16_HI & 3)
+ || (R_PPC_GOT_TLSLD16_HA & 3) != (R_PPC_GOT_TLSGD16_HA & 3)
+ || (R_PPC_GOT_TLSLD16 & 3) != (R_PPC_GOT_TPREL16 & 3)
+ || (R_PPC_GOT_TLSLD16_LO & 3) != (R_PPC_GOT_TPREL16_LO & 3)
+ || (R_PPC_GOT_TLSLD16_HI & 3) != (R_PPC_GOT_TPREL16_HI & 3)
+ || (R_PPC_GOT_TLSLD16_HA & 3) != (R_PPC_GOT_TPREL16_HA & 3))
+ abort ();
+ switch (r_type)
+ {
+ default:
+ break;
+
+ case R_PPC_GOT_TPREL16:
+ case R_PPC_GOT_TPREL16_LO:
+ if ((tls_mask & TLS_TLS) != 0
+ && (tls_mask & TLS_TPREL) == 0)
+ {
+ bfd_vma insn;
+
+ insn = bfd_get_32 (output_bfd, contents + rel->r_offset - d_offset);
+ insn &= 31 << 21;
+ insn |= 0x3c020000; /* addis 0,2,0 */
+ bfd_put_32 (output_bfd, insn, contents + rel->r_offset - d_offset);
+ r_type = R_PPC_TPREL16_HA;
+ rel->r_info = ELF32_R_INFO (r_symndx, r_type);
+ }
+ break;
+
+ case R_PPC_TLS:
+ if ((tls_mask & TLS_TLS) != 0
+ && (tls_mask & TLS_TPREL) == 0)
+ {
+ bfd_vma insn;
+
+ insn = bfd_get_32 (output_bfd, contents + rel->r_offset);
+ insn = _bfd_elf_ppc_at_tls_transform (insn, 2);
+ if (insn == 0)
+ abort ();
+ bfd_put_32 (output_bfd, insn, contents + rel->r_offset);
+ r_type = R_PPC_TPREL16_LO;
+ rel->r_info = ELF32_R_INFO (r_symndx, r_type);
+
+ /* Was PPC_TLS which sits on insn boundary, now
+ PPC_TPREL16_LO which is at low-order half-word. */
+ rel->r_offset += d_offset;
+ }
+ break;
+
+ case R_PPC_GOT_TLSGD16_HI:
+ case R_PPC_GOT_TLSGD16_HA:
+ tls_gd = TLS_TPRELGD;
+ if ((tls_mask & TLS_TLS) != 0 && (tls_mask & TLS_GD) == 0)
+ goto tls_gdld_hi;
+ break;
+
+ case R_PPC_GOT_TLSLD16_HI:
+ case R_PPC_GOT_TLSLD16_HA:
+ if ((tls_mask & TLS_TLS) != 0 && (tls_mask & TLS_LD) == 0)
+ {
+ tls_gdld_hi:
+ if ((tls_mask & tls_gd) != 0)
+ r_type = (((r_type - (R_PPC_GOT_TLSGD16 & 3)) & 3)
+ + R_PPC_GOT_TPREL16);
+ else
+ {
+ bfd_put_32 (output_bfd, NOP, contents + rel->r_offset);
+ rel->r_offset -= d_offset;
+ r_type = R_PPC_NONE;
+ }
+ rel->r_info = ELF32_R_INFO (r_symndx, r_type);
+ }
+ break;
+
+ case R_PPC_GOT_TLSGD16:
+ case R_PPC_GOT_TLSGD16_LO:
+ tls_gd = TLS_TPRELGD;
+ if ((tls_mask & TLS_TLS) != 0 && (tls_mask & TLS_GD) == 0)
+ goto tls_ldgd_opt;
+ break;
+
+ case R_PPC_GOT_TLSLD16:
+ case R_PPC_GOT_TLSLD16_LO:
+ if ((tls_mask & TLS_TLS) != 0 && (tls_mask & TLS_LD) == 0)
+ {
+ unsigned int insn1, insn2;
+ bfd_vma offset;
+
+ tls_ldgd_opt:
+ offset = (bfd_vma) -1;
+ /* If not using the newer R_PPC_TLSGD/LD to mark
+ __tls_get_addr calls, we must trust that the call
+ stays with its arg setup insns, ie. that the next
+ reloc is the __tls_get_addr call associated with
+ the current reloc. Edit both insns. */
+ if (input_section->has_tls_get_addr_call
+ && rel + 1 < relend
+ && branch_reloc_hash_match (input_bfd, rel + 1,
+ htab->tls_get_addr))
+ offset = rel[1].r_offset;
+ if ((tls_mask & tls_gd) != 0)
+ {
+ /* IE */
+ insn1 = bfd_get_32 (output_bfd,
+ contents + rel->r_offset - d_offset);
+ insn1 &= (1 << 26) - 1;
+ insn1 |= 32 << 26; /* lwz */
+ if (offset != (bfd_vma) -1)
+ {
+ rel[1].r_info = ELF32_R_INFO (STN_UNDEF, R_PPC_NONE);
+ insn2 = 0x7c631214; /* add 3,3,2 */
+ bfd_put_32 (output_bfd, insn2, contents + offset);
+ }
+ r_type = (((r_type - (R_PPC_GOT_TLSGD16 & 3)) & 3)
+ + R_PPC_GOT_TPREL16);
+ rel->r_info = ELF32_R_INFO (r_symndx, r_type);
+ }
+ else
+ {
+ /* LE */
+ insn1 = 0x3c620000; /* addis 3,2,0 */
+ if (tls_gd == 0)
+ {
+ /* Was an LD reloc. */
+ for (r_symndx = 0;
+ r_symndx < symtab_hdr->sh_info;
+ r_symndx++)
+ if (local_sections[r_symndx] == sec)
+ break;
+ if (r_symndx >= symtab_hdr->sh_info)
+ r_symndx = STN_UNDEF;
+ rel->r_addend = htab->elf.tls_sec->vma + DTP_OFFSET;
+ if (r_symndx != STN_UNDEF)
+ rel->r_addend -= (local_syms[r_symndx].st_value
+ + sec->output_offset
+ + sec->output_section->vma);
+ }
+ r_type = R_PPC_TPREL16_HA;
+ rel->r_info = ELF32_R_INFO (r_symndx, r_type);
+ if (offset != (bfd_vma) -1)
+ {
+ rel[1].r_info = ELF32_R_INFO (r_symndx, R_PPC_TPREL16_LO);
+ rel[1].r_offset = offset + d_offset;
+ rel[1].r_addend = rel->r_addend;
+ insn2 = 0x38630000; /* addi 3,3,0 */
+ bfd_put_32 (output_bfd, insn2, contents + offset);
+ }
+ }
+ bfd_put_32 (output_bfd, insn1,
+ contents + rel->r_offset - d_offset);
+ if (tls_gd == 0)
+ {
+ /* We changed the symbol on an LD reloc. Start over
+ in order to get h, sym, sec etc. right. */
+ rel--;
+ continue;
+ }
+ }
+ break;
+
+ case R_PPC_TLSGD:
+ if ((tls_mask & TLS_TLS) != 0 && (tls_mask & TLS_GD) == 0)
+ {
+ unsigned int insn2;
+ bfd_vma offset = rel->r_offset;
+
+ if ((tls_mask & TLS_TPRELGD) != 0)
+ {
+ /* IE */
+ r_type = R_PPC_NONE;
+ insn2 = 0x7c631214; /* add 3,3,2 */
+ }
+ else
+ {
+ /* LE */
+ r_type = R_PPC_TPREL16_LO;
+ rel->r_offset += d_offset;
+ insn2 = 0x38630000; /* addi 3,3,0 */
+ }
+ rel->r_info = ELF32_R_INFO (r_symndx, r_type);
+ bfd_put_32 (output_bfd, insn2, contents + offset);
+ /* Zap the reloc on the _tls_get_addr call too. */
+ BFD_ASSERT (offset == rel[1].r_offset);
+ rel[1].r_info = ELF32_R_INFO (STN_UNDEF, R_PPC_NONE);
+ }
+ break;
+
+ case R_PPC_TLSLD:
+ if ((tls_mask & TLS_TLS) != 0 && (tls_mask & TLS_LD) == 0)
+ {
+ unsigned int insn2;
+
+ for (r_symndx = 0;
+ r_symndx < symtab_hdr->sh_info;
+ r_symndx++)
+ if (local_sections[r_symndx] == sec)
+ break;
+ if (r_symndx >= symtab_hdr->sh_info)
+ r_symndx = STN_UNDEF;
+ rel->r_addend = htab->elf.tls_sec->vma + DTP_OFFSET;
+ if (r_symndx != STN_UNDEF)
+ rel->r_addend -= (local_syms[r_symndx].st_value
+ + sec->output_offset
+ + sec->output_section->vma);
+
+ rel->r_info = ELF32_R_INFO (r_symndx, R_PPC_TPREL16_LO);
+ rel->r_offset += d_offset;
+ insn2 = 0x38630000; /* addi 3,3,0 */
+ bfd_put_32 (output_bfd, insn2,
+ contents + rel->r_offset - d_offset);
+ /* Zap the reloc on the _tls_get_addr call too. */
+ BFD_ASSERT (rel->r_offset - d_offset == rel[1].r_offset);
+ rel[1].r_info = ELF32_R_INFO (STN_UNDEF, R_PPC_NONE);
+ rel--;
+ continue;
+ }
+ break;
+ }
+
+ /* Handle other relocations that tweak non-addend part of insn. */
+ branch_bit = 0;
+ switch (r_type)
+ {
+ default:
+ break;
+
+ /* Branch taken prediction relocations. */
+ case R_PPC_ADDR14_BRTAKEN:
+ case R_PPC_REL14_BRTAKEN:
+ branch_bit = BRANCH_PREDICT_BIT;
+ /* Fall thru */
+
+ /* Branch not taken prediction relocations. */
+ case R_PPC_ADDR14_BRNTAKEN:
+ case R_PPC_REL14_BRNTAKEN:
+ {
+ bfd_vma insn;
+
+ insn = bfd_get_32 (output_bfd, contents + rel->r_offset);
+ insn &= ~BRANCH_PREDICT_BIT;
+ insn |= branch_bit;
+
+ from = (rel->r_offset
+ + input_section->output_offset
+ + input_section->output_section->vma);
+
+ /* Invert 'y' bit if not the default. */
+ if ((bfd_signed_vma) (relocation + rel->r_addend - from) < 0)
+ insn ^= BRANCH_PREDICT_BIT;
+
+ bfd_put_32 (output_bfd, insn, contents + rel->r_offset);
+ break;
+ }
+ }
+
+ ifunc = NULL;
+ if (!htab->is_vxworks)
+ {
+ struct plt_entry *ent;
+
+ if (h != NULL)
+ {
+ if (h->type == STT_GNU_IFUNC)
+ ifunc = &h->plt.plist;
+ }
+ else if (local_got_offsets != NULL
+ && ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC)
+ {
+ struct plt_entry **local_plt;
+
+ local_plt = (struct plt_entry **) (local_got_offsets
+ + symtab_hdr->sh_info);
+ ifunc = local_plt + r_symndx;
+ }
+
+ ent = NULL;
+ if (ifunc != NULL
+ && (!info->shared
+ || is_branch_reloc (r_type)))
+ {
+ addend = 0;
+ if (r_type == R_PPC_PLTREL24 && info->shared)
+ addend = rel->r_addend;
+ ent = find_plt_ent (ifunc, got2, addend);
+ }
+ if (ent != NULL)
+ {
+ if (h == NULL && (ent->plt.offset & 1) == 0)
+ {
+ Elf_Internal_Rela rela;
+ bfd_byte *loc;
+
+ rela.r_offset = (htab->iplt->output_section->vma
+ + htab->iplt->output_offset
+ + ent->plt.offset);
+ rela.r_info = ELF32_R_INFO (0, R_PPC_IRELATIVE);
+ rela.r_addend = relocation;
+ loc = htab->reliplt->contents;
+ loc += (htab->reliplt->reloc_count++
+ * sizeof (Elf32_External_Rela));
+ bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
+
+ ent->plt.offset |= 1;
+ }
+ if (h == NULL && (ent->glink_offset & 1) == 0)
+ {
+ unsigned char *p = ((unsigned char *) htab->glink->contents
+ + ent->glink_offset);
+ write_glink_stub (ent, htab->iplt, p, info);
+ ent->glink_offset |= 1;
+ }
+
+ unresolved_reloc = FALSE;
+ if (htab->plt_type == PLT_NEW
+ || !htab->elf.dynamic_sections_created
+ || h == NULL
+ || h->dynindx == -1)
+ relocation = (htab->glink->output_section->vma
+ + htab->glink->output_offset
+ + (ent->glink_offset & ~1));
+ else
+ relocation = (htab->plt->output_section->vma
+ + htab->plt->output_offset
+ + ent->plt.offset);
+ }
+ }
+
+ addend = rel->r_addend;
+ tls_type = 0;
+ howto = NULL;
+ if (r_type < R_PPC_max)
+ howto = ppc_elf_howto_table[r_type];
+ switch (r_type)
+ {
+ default:
+ info->callbacks->einfo
+ (_("%P: %B: unknown relocation type %d for symbol %s\n"),
+ input_bfd, (int) r_type, sym_name);
+
+ bfd_set_error (bfd_error_bad_value);
+ ret = FALSE;
+ continue;
+
+ case R_PPC_NONE:
+ case R_PPC_TLS:
+ case R_PPC_TLSGD:
+ case R_PPC_TLSLD:
+ case R_PPC_EMB_MRKREF:
+ case R_PPC_GNU_VTINHERIT:
+ case R_PPC_GNU_VTENTRY:
+ continue;
+
+ /* GOT16 relocations. Like an ADDR16 using the symbol's
+ address in the GOT as relocation value instead of the
+ symbol's value itself. Also, create a GOT entry for the
+ symbol and put the symbol value there. */
+ case R_PPC_GOT_TLSGD16:
+ case R_PPC_GOT_TLSGD16_LO:
+ case R_PPC_GOT_TLSGD16_HI:
+ case R_PPC_GOT_TLSGD16_HA:
+ tls_type = TLS_TLS | TLS_GD;
+ goto dogot;
+
+ case R_PPC_GOT_TLSLD16:
+ case R_PPC_GOT_TLSLD16_LO:
+ case R_PPC_GOT_TLSLD16_HI:
+ case R_PPC_GOT_TLSLD16_HA:
+ tls_type = TLS_TLS | TLS_LD;
+ goto dogot;
+
+ case R_PPC_GOT_TPREL16:
+ case R_PPC_GOT_TPREL16_LO:
+ case R_PPC_GOT_TPREL16_HI:
+ case R_PPC_GOT_TPREL16_HA:
+ tls_type = TLS_TLS | TLS_TPREL;
+ goto dogot;
+
+ case R_PPC_GOT_DTPREL16:
+ case R_PPC_GOT_DTPREL16_LO:
+ case R_PPC_GOT_DTPREL16_HI:
+ case R_PPC_GOT_DTPREL16_HA:
+ tls_type = TLS_TLS | TLS_DTPREL;
+ goto dogot;
+
+ case R_PPC_GOT16:
+ case R_PPC_GOT16_LO:
+ case R_PPC_GOT16_HI:
+ case R_PPC_GOT16_HA:
+ tls_mask = 0;
+ dogot:
+ {
+ /* Relocation is to the entry for this symbol in the global
+ offset table. */
+ bfd_vma off;
+ bfd_vma *offp;
+ unsigned long indx;
+
+ if (htab->got == NULL)
+ abort ();
+
+ indx = 0;
+ if (tls_type == (TLS_TLS | TLS_LD)
+ && (h == NULL
+ || !h->def_dynamic))
+ offp = &htab->tlsld_got.offset;
+ else if (h != NULL)
+ {
+ bfd_boolean dyn;
+ dyn = htab->elf.dynamic_sections_created;
+ if (! WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h)
+ || (info->shared
+ && SYMBOL_REFERENCES_LOCAL (info, h)))
+ /* 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. */
+ ;
+ else
+ {
+ BFD_ASSERT (h->dynindx != -1);
+ indx = h->dynindx;
+ unresolved_reloc = FALSE;
+ }
+ offp = &h->got.offset;
+ }
+ else
+ {
+ if (local_got_offsets == NULL)
+ abort ();
+ offp = &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. */
+ off = *offp;
+ if ((off & 1) != 0)
+ off &= ~1;
+ else
+ {
+ unsigned int tls_m = (tls_mask
+ & (TLS_LD | TLS_GD | TLS_DTPREL
+ | TLS_TPREL | TLS_TPRELGD));
+
+ if (offp == &htab->tlsld_got.offset)
+ tls_m = TLS_LD;
+ else if (h == NULL
+ || !h->def_dynamic)
+ tls_m &= ~TLS_LD;
+
+ /* We might have multiple got entries for this sym.
+ Initialize them all. */
+ do
+ {
+ int tls_ty = 0;
+
+ if ((tls_m & TLS_LD) != 0)
+ {
+ tls_ty = TLS_TLS | TLS_LD;
+ tls_m &= ~TLS_LD;
+ }
+ else if ((tls_m & TLS_GD) != 0)
+ {
+ tls_ty = TLS_TLS | TLS_GD;
+ tls_m &= ~TLS_GD;
+ }
+ else if ((tls_m & TLS_DTPREL) != 0)
+ {
+ tls_ty = TLS_TLS | TLS_DTPREL;
+ tls_m &= ~TLS_DTPREL;
+ }
+ else if ((tls_m & (TLS_TPREL | TLS_TPRELGD)) != 0)
+ {
+ tls_ty = TLS_TLS | TLS_TPREL;
+ tls_m = 0;
+ }
+
+ /* Generate relocs for the dynamic linker. */
+ if ((info->shared || indx != 0)
+ && (offp == &htab->tlsld_got.offset
+ || h == NULL
+ || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
+ || h->root.type != bfd_link_hash_undefweak))
+ {
+ asection *rsec = htab->relgot;
+ bfd_byte * loc;
+
+ if (ifunc != NULL)
+ rsec = htab->reliplt;
+ outrel.r_offset = (htab->got->output_section->vma
+ + htab->got->output_offset
+ + off);
+ outrel.r_addend = 0;
+ if (tls_ty & (TLS_LD | TLS_GD))
+ {
+ outrel.r_info = ELF32_R_INFO (indx, R_PPC_DTPMOD32);
+ if (tls_ty == (TLS_TLS | TLS_GD))
+ {
+ loc = rsec->contents;
+ loc += (rsec->reloc_count++
+ * sizeof (Elf32_External_Rela));
+ bfd_elf32_swap_reloca_out (output_bfd,
+ &outrel, loc);
+ outrel.r_offset += 4;
+ outrel.r_info
+ = ELF32_R_INFO (indx, R_PPC_DTPREL32);
+ }
+ }
+ else if (tls_ty == (TLS_TLS | TLS_DTPREL))
+ outrel.r_info = ELF32_R_INFO (indx, R_PPC_DTPREL32);
+ else if (tls_ty == (TLS_TLS | TLS_TPREL))
+ outrel.r_info = ELF32_R_INFO (indx, R_PPC_TPREL32);
+ else if (indx != 0)
+ outrel.r_info = ELF32_R_INFO (indx, R_PPC_GLOB_DAT);
+ else if (ifunc != NULL)
+ outrel.r_info = ELF32_R_INFO (0, R_PPC_IRELATIVE);
+ else
+ outrel.r_info = ELF32_R_INFO (0, R_PPC_RELATIVE);
+ if (indx == 0 && tls_ty != (TLS_TLS | TLS_LD))
+ {
+ outrel.r_addend += relocation;
+ if (tls_ty & (TLS_GD | TLS_DTPREL | TLS_TPREL))
+ outrel.r_addend -= htab->elf.tls_sec->vma;
+ }
+ loc = rsec->contents;
+ loc += (rsec->reloc_count++
+ * sizeof (Elf32_External_Rela));
+ bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
+ }
+
+ /* Init the .got section contents if we're not
+ emitting a reloc. */
+ else
+ {
+ bfd_vma value = relocation;
+
+ if (tls_ty == (TLS_TLS | TLS_LD))
+ value = 1;
+ else if (tls_ty != 0)
+ {
+ value -= htab->elf.tls_sec->vma + DTP_OFFSET;
+ if (tls_ty == (TLS_TLS | TLS_TPREL))
+ value += DTP_OFFSET - TP_OFFSET;
+
+ if (tls_ty == (TLS_TLS | TLS_GD))
+ {
+ bfd_put_32 (output_bfd, value,
+ htab->got->contents + off + 4);
+ value = 1;
+ }
+ }
+ bfd_put_32 (output_bfd, value,
+ htab->got->contents + off);
+ }
+
+ off += 4;
+ if (tls_ty & (TLS_LD | TLS_GD))
+ off += 4;
+ }
+ while (tls_m != 0);
+
+ off = *offp;
+ *offp = off | 1;
+ }
+
+ if (off >= (bfd_vma) -2)
+ abort ();
+
+ if ((tls_type & TLS_TLS) != 0)
+ {
+ if (tls_type != (TLS_TLS | TLS_LD))
+ {
+ if ((tls_mask & TLS_LD) != 0
+ && !(h == NULL
+ || !h->def_dynamic))
+ off += 8;
+ if (tls_type != (TLS_TLS | TLS_GD))
+ {
+ if ((tls_mask & TLS_GD) != 0)
+ off += 8;
+ if (tls_type != (TLS_TLS | TLS_DTPREL))
+ {
+ if ((tls_mask & TLS_DTPREL) != 0)
+ off += 4;
+ }
+ }
+ }
+ }
+
+ relocation = (htab->got->output_section->vma
+ + htab->got->output_offset
+ + off
+ - SYM_VAL (htab->elf.hgot));
+
+ /* Addends on got relocations don't make much sense.
+ x+off@got is actually x@got+off, and since the got is
+ generated by a hash table traversal, the value in the
+ got at entry m+n bears little relation to the entry m. */
+ if (addend != 0)
+ info->callbacks->einfo
+ (_("%P: %H: non-zero addend on %s reloc against `%s'\n"),
+ input_bfd, input_section, rel->r_offset,
+ howto->name,
+ sym_name);
+ }
+ break;
+
+ /* Relocations that need no special processing. */
+ case R_PPC_LOCAL24PC:
+ /* It makes no sense to point a local relocation
+ at a symbol not in this object. */
+ if (unresolved_reloc)
+ {
+ if (! (*info->callbacks->undefined_symbol) (info,
+ h->root.root.string,
+ input_bfd,
+ input_section,
+ rel->r_offset,
+ TRUE))
+ return FALSE;
+ continue;
+ }
+ break;
+
+ case R_PPC_DTPREL16:
+ case R_PPC_DTPREL16_LO:
+ case R_PPC_DTPREL16_HI:
+ case R_PPC_DTPREL16_HA:
+ addend -= htab->elf.tls_sec->vma + DTP_OFFSET;
+ break;
+
+ /* Relocations that may need to be propagated if this is a shared
+ object. */
+ case R_PPC_TPREL16:
+ case R_PPC_TPREL16_LO:
+ case R_PPC_TPREL16_HI:
+ case R_PPC_TPREL16_HA:
+ if (h != NULL
+ && h->root.type == bfd_link_hash_undefweak
+ && h->dynindx == -1)
+ {
+ /* Make this relocation against an undefined weak symbol
+ resolve to zero. This is really just a tweak, since
+ code using weak externs ought to check that they are
+ defined before using them. */
+ bfd_byte *p = contents + rel->r_offset - d_offset;
+ unsigned int insn = bfd_get_32 (output_bfd, p);
+ insn = _bfd_elf_ppc_at_tprel_transform (insn, 2);
+ if (insn != 0)
+ bfd_put_32 (output_bfd, insn, p);
+ break;
+ }
+ addend -= htab->elf.tls_sec->vma + TP_OFFSET;
+ /* The TPREL16 relocs shouldn't really be used in shared
+ libs as they will result in DT_TEXTREL being set, but
+ support them anyway. */
+ goto dodyn;
+
+ case R_PPC_TPREL32:
+ addend -= htab->elf.tls_sec->vma + TP_OFFSET;
+ goto dodyn;
+
+ case R_PPC_DTPREL32:
+ addend -= htab->elf.tls_sec->vma + DTP_OFFSET;
+ goto dodyn;
+
+ case R_PPC_DTPMOD32:
+ relocation = 1;
+ addend = 0;
+ goto dodyn;
+
+ case R_PPC_REL16:
+ case R_PPC_REL16_LO:
+ case R_PPC_REL16_HI:
+ case R_PPC_REL16_HA:
+ break;
+
+ case R_PPC_REL32:
+ if (h == NULL || h == htab->elf.hgot)
+ break;
+ /* fall through */
+
+ case R_PPC_ADDR32:
+ case R_PPC_ADDR16:
+ case R_PPC_ADDR16_LO:
+ case R_PPC_ADDR16_HI:
+ case R_PPC_ADDR16_HA:
+ case R_PPC_UADDR32:
+ case R_PPC_UADDR16:
+ goto dodyn;
+
+ case R_PPC_VLE_REL8:
+ case R_PPC_VLE_REL15:
+ case R_PPC_VLE_REL24:
+ case R_PPC_REL24:
+ case R_PPC_REL14:
+ case R_PPC_REL14_BRTAKEN:
+ case R_PPC_REL14_BRNTAKEN:
+ /* If these relocations are not to a named symbol, they can be
+ handled right here, no need to bother the dynamic linker. */
+ if (SYMBOL_CALLS_LOCAL (info, h)
+ || h == htab->elf.hgot)
+ break;
+ /* fall through */
+
+ case R_PPC_ADDR24:
+ case R_PPC_ADDR14:
+ case R_PPC_ADDR14_BRTAKEN:
+ case R_PPC_ADDR14_BRNTAKEN:
+ if (h != NULL && !info->shared)
+ break;
+ /* fall through */
+
+ dodyn:
+ if ((input_section->flags & SEC_ALLOC) == 0
+ || is_vxworks_tls)
+ break;
+
+ if ((info->shared
+ && !(h != NULL
+ && ((h->root.type == bfd_link_hash_undefined
+ && (ELF_ST_VISIBILITY (h->other) == STV_HIDDEN
+ || ELF_ST_VISIBILITY (h->other) == STV_INTERNAL))
+ || (h->root.type == bfd_link_hash_undefweak
+ && ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)))
+ && (must_be_dyn_reloc (info, r_type)
+ || !SYMBOL_CALLS_LOCAL (info, h)))
+ || (ELIMINATE_COPY_RELOCS
+ && !info->shared
+ && h != NULL
+ && h->dynindx != -1
+ && !h->non_got_ref
+ && !h->def_regular))
+ {
+ int skip;
+ bfd_byte *loc;
+ asection *sreloc;
+#ifdef DEBUG
+ fprintf (stderr, "ppc_elf_relocate_section needs 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. */
+ sreloc = elf_section_data (input_section)->sreloc;
+ if (ifunc)
+ sreloc = htab->reliplt;
+ if (sreloc == NULL)
+ return FALSE;
+
+ skip = 0;
+ outrel.r_offset = _bfd_elf_section_offset (output_bfd, info,
+ input_section,
+ rel->r_offset);
+ if (outrel.r_offset == (bfd_vma) -1
+ || outrel.r_offset == (bfd_vma) -2)
+ skip = (int) outrel.r_offset;
+ outrel.r_offset += (input_section->output_section->vma
+ + input_section->output_offset);
+
+ if (skip)
+ memset (&outrel, 0, sizeof outrel);
+ else if ((h != NULL
+ && (h->root.type == bfd_link_hash_undefined
+ || h->root.type == bfd_link_hash_undefweak))
+ || !SYMBOL_REFERENCES_LOCAL (info, h))
+ {
+ BFD_ASSERT (h->dynindx != -1);
+ unresolved_reloc = FALSE;
+ outrel.r_info = ELF32_R_INFO (h->dynindx, r_type);
+ outrel.r_addend = rel->r_addend;
+ }
+ else
+ {
+ outrel.r_addend = relocation + rel->r_addend;
+
+ if (r_type != R_PPC_ADDR32)
+ {
+ long indx = 0;
+
+ if (ifunc != NULL)
+ {
+ /* If we get here when building a static
+ executable, then the libc startup function
+ responsible for applying indirect function
+ relocations is going to complain about
+ the reloc type.
+ If we get here when building a dynamic
+ executable, it will be because we have
+ a text relocation. The dynamic loader
+ will set the text segment writable and
+ non-executable to apply text relocations.
+ So we'll segfault when trying to run the
+ indirection function to resolve the reloc. */
+ info->callbacks->einfo
+ (_("%P: %H: relocation %s for indirect "
+ "function %s unsupported\n"),
+ input_bfd, input_section, rel->r_offset,
+ howto->name,
+ sym_name);
+ ret = FALSE;
+ }
+ else if (r_symndx == STN_UNDEF || bfd_is_abs_section (sec))
+ ;
+ else if (sec == NULL || sec->owner == NULL)
+ {
+ bfd_set_error (bfd_error_bad_value);
+ ret = FALSE;
+ }
+ else
+ {
+ asection *osec;
+
+ /* We are turning this relocation into one
+ against a section symbol. It would be
+ proper to subtract the symbol's value,
+ osec->vma, from the emitted reloc addend,
+ but ld.so expects buggy relocs.
+ FIXME: Why not always use a zero index? */
+ osec = sec->output_section;
+ indx = elf_section_data (osec)->dynindx;
+ if (indx == 0)
+ {
+ osec = htab->elf.text_index_section;
+ indx = elf_section_data (osec)->dynindx;
+ }
+ BFD_ASSERT (indx != 0);
+#ifdef DEBUG
+ if (indx == 0)
+ printf ("indx=%ld 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);
+ }
+ else if (ifunc != NULL)
+ outrel.r_info = ELF32_R_INFO (0, R_PPC_IRELATIVE);
+ else
+ outrel.r_info = ELF32_R_INFO (0, R_PPC_RELATIVE);
+ }
+
+ loc = sreloc->contents;
+ loc += sreloc->reloc_count++ * sizeof (Elf32_External_Rela);
+ bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
+
+ if (skip == -1)
+ continue;
+
+ /* This reloc will be computed at runtime. We clear the memory
+ so that it contains predictable value. */
+ if (! skip
+ && ((input_section->flags & SEC_ALLOC) != 0
+ || ELF32_R_TYPE (outrel.r_info) != R_PPC_RELATIVE))
+ {
+ relocation = howto->pc_relative ? outrel.r_offset : 0;
+ addend = 0;
+ break;
+ }
+ }
+ break;
+
+ case R_PPC_RELAX_PLT:
+ case R_PPC_RELAX_PLTREL24:
+ if (h != NULL)
+ {
+ struct plt_entry *ent;
+ bfd_vma got2_addend = 0;
+
+ if (r_type == R_PPC_RELAX_PLTREL24)
+ {
+ if (info->shared)
+ got2_addend = addend;
+ addend = 0;
+ }
+ ent = find_plt_ent (&h->plt.plist, got2, got2_addend);
+ if (htab->plt_type == PLT_NEW)
+ relocation = (htab->glink->output_section->vma
+ + htab->glink->output_offset
+ + ent->glink_offset);
+ else
+ relocation = (htab->plt->output_section->vma
+ + htab->plt->output_offset
+ + ent->plt.offset);
+ }
+ /* Fall thru */
+
+ case R_PPC_RELAX:
+ {
+ const int *stub;
+ size_t size;
+ size_t insn_offset = rel->r_offset;
+ unsigned int insn;
+
+ if (info->shared)
+ {
+ relocation -= (input_section->output_section->vma
+ + input_section->output_offset
+ + rel->r_offset - 4);
+ stub = shared_stub_entry;
+ bfd_put_32 (output_bfd, stub[0], contents + insn_offset - 12);
+ bfd_put_32 (output_bfd, stub[1], contents + insn_offset - 8);
+ bfd_put_32 (output_bfd, stub[2], contents + insn_offset - 4);
+ stub += 3;
+ size = ARRAY_SIZE (shared_stub_entry) - 3;
+ }
+ else
+ {
+ stub = stub_entry;
+ size = ARRAY_SIZE (stub_entry);
+ }
+
+ relocation += addend;
+ if (info->relocatable)
+ relocation = 0;
+
+ /* First insn is HA, second is LO. */
+ insn = *stub++;
+ insn |= ((relocation + 0x8000) >> 16) & 0xffff;
+ bfd_put_32 (output_bfd, insn, contents + insn_offset);
+ insn_offset += 4;
+
+ insn = *stub++;
+ insn |= relocation & 0xffff;
+ bfd_put_32 (output_bfd, insn, contents + insn_offset);
+ insn_offset += 4;
+ size -= 2;
+
+ while (size != 0)
+ {
+ insn = *stub++;
+ --size;
+ bfd_put_32 (output_bfd, insn, contents + insn_offset);
+ insn_offset += 4;
+ }
+
+ /* Rewrite the reloc and convert one of the trailing nop
+ relocs to describe this relocation. */
+ BFD_ASSERT (ELF32_R_TYPE (relend[-1].r_info) == R_PPC_NONE);
+ /* The relocs are at the bottom 2 bytes */
+ rel[0].r_offset += d_offset;
+ memmove (rel + 1, rel, (relend - rel - 1) * sizeof (*rel));
+ rel[0].r_info = ELF32_R_INFO (r_symndx, R_PPC_ADDR16_HA);
+ rel[1].r_offset += 4;
+ rel[1].r_info = ELF32_R_INFO (r_symndx, R_PPC_ADDR16_LO);
+ rel++;
+ }
+ continue;
+
+ /* Indirect .sdata relocation. */
+ case R_PPC_EMB_SDAI16:
+ BFD_ASSERT (htab->sdata[0].section != NULL);
+ if (!is_static_defined (htab->sdata[0].sym))
+ {
+ unresolved_reloc = TRUE;
+ break;
+ }
+ relocation
+ = elf_finish_pointer_linker_section (input_bfd, &htab->sdata[0],
+ h, relocation, rel);
+ addend = 0;
+ break;
+
+ /* Indirect .sdata2 relocation. */
+ case R_PPC_EMB_SDA2I16:
+ BFD_ASSERT (htab->sdata[1].section != NULL);
+ if (!is_static_defined (htab->sdata[1].sym))
+ {
+ unresolved_reloc = TRUE;
+ break;
+ }
+ relocation
+ = elf_finish_pointer_linker_section (input_bfd, &htab->sdata[1],
+ h, relocation, rel);
+ addend = 0;
+ 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 R_PPC_TOC16: /* phony GOT16 relocations */
+ if (sec == NULL || sec->output_section == NULL)
+ {
+ unresolved_reloc = TRUE;
+ break;
+ }
+ BFD_ASSERT (strcmp (bfd_get_section_name (sec->owner, sec),
+ ".got") == 0
+ || strcmp (bfd_get_section_name (sec->owner, sec),
+ ".cgot") == 0);
+
+ addend -= sec->output_section->vma + sec->output_offset + 0x8000;
+ break;
+
+ case R_PPC_PLTREL24:
+ if (h != NULL && ifunc == NULL)
+ {
+ struct plt_entry *ent = find_plt_ent (&h->plt.plist, got2,
+ info->shared ? addend : 0);
+ if (ent == NULL
+ || htab->plt == NULL)
+ {
+ /* We didn't make a PLT entry for this symbol. This
+ happens when statically linking PIC code, or when
+ using -Bsymbolic. */
+ }
+ else
+ {
+ /* Relocation is to the entry for this symbol in the
+ procedure linkage table. */
+ unresolved_reloc = FALSE;
+ if (htab->plt_type == PLT_NEW)
+ relocation = (htab->glink->output_section->vma
+ + htab->glink->output_offset
+ + ent->glink_offset);
+ else
+ relocation = (htab->plt->output_section->vma
+ + htab->plt->output_offset
+ + ent->plt.offset);
+ }
+ }
+
+ /* R_PPC_PLTREL24 is rather special. If non-zero, the
+ addend specifies the GOT pointer offset within .got2.
+ Don't apply it to the relocation field. */
+ addend = 0;
+ break;
+
+ /* Relocate against _SDA_BASE_. */
+ case R_PPC_SDAREL16:
+ {
+ const char *name;
+ struct elf_link_hash_entry *sda = htab->sdata[0].sym;
+
+ if (sec == NULL
+ || sec->output_section == NULL
+ || !is_static_defined (sda))
+ {
+ unresolved_reloc = TRUE;
+ break;
+ }
+ addend -= SYM_VAL (sda);
+
+ name = bfd_get_section_name (output_bfd, sec->output_section);
+ if (!(strcmp (name, ".sdata") == 0
+ || strcmp (name, ".sbss") == 0))
+ {
+ info->callbacks->einfo
+ (_("%P: %B: the target (%s) of a %s relocation is "
+ "in the wrong output section (%s)\n"),
+ input_bfd,
+ sym_name,
+ howto->name,
+ name);
+ }
+ }
+ break;
+
+ /* Relocate against _SDA2_BASE_. */
+ case R_PPC_EMB_SDA2REL:
+ {
+ const char *name;
+ struct elf_link_hash_entry *sda = htab->sdata[1].sym;
+
+ if (sec == NULL
+ || sec->output_section == NULL
+ || !is_static_defined (sda))
+ {
+ unresolved_reloc = TRUE;
+ break;
+ }
+ addend -= SYM_VAL (sda);
+
+ name = bfd_get_section_name (output_bfd, sec->output_section);
+ if (!(strcmp (name, ".sdata2") == 0
+ || strcmp (name, ".sbss2") == 0))
+ {
+ info->callbacks->einfo
+ (_("%P: %B: the target (%s) of a %s relocation is "
+ "in the wrong output section (%s)\n"),
+ input_bfd,
+ sym_name,
+ howto->name,
+ name);
+ }
+ }
+ break;
+
+ case R_PPC_VLE_LO16A:
+ relocation = relocation + addend;
+ ppc_elf_vle_split16 (output_bfd, contents + rel->r_offset,
+ relocation, split16a_type);
+ continue;
+
+ case R_PPC_VLE_LO16D:
+ relocation = relocation + addend;
+ ppc_elf_vle_split16 (output_bfd, contents + rel->r_offset,
+ relocation, split16d_type);
+ continue;
+
+ case R_PPC_VLE_HI16A:
+ relocation = (relocation + addend) >> 16;
+ ppc_elf_vle_split16 (output_bfd, contents + rel->r_offset,
+ relocation, split16a_type);
+ continue;
+
+ case R_PPC_VLE_HI16D:
+ relocation = (relocation + addend) >> 16;
+ ppc_elf_vle_split16 (output_bfd, contents + rel->r_offset,
+ relocation, split16d_type);
+ continue;
+
+ case R_PPC_VLE_HA16A:
+ relocation = (relocation + addend + 0x8000) >> 16;
+ ppc_elf_vle_split16 (output_bfd, contents + rel->r_offset,
+ relocation, split16a_type);
+ continue;
+
+ case R_PPC_VLE_HA16D:
+ relocation = (relocation + addend + 0x8000) >> 16;
+ ppc_elf_vle_split16 (output_bfd, contents + rel->r_offset,
+ relocation, split16d_type);
+ continue;
+
+ /* Relocate against either _SDA_BASE_, _SDA2_BASE_, or 0. */
+ case R_PPC_EMB_SDA21:
+ case R_PPC_VLE_SDA21:
+ case R_PPC_EMB_RELSDA:
+ case R_PPC_VLE_SDA21_LO:
+ {
+ const char *name;
+ int reg;
+ unsigned int insn;
+ struct elf_link_hash_entry *sda = NULL;
+
+ if (sec == NULL || sec->output_section == NULL)
+ {
+ unresolved_reloc = TRUE;
+ break;
+ }
+
+ name = bfd_get_section_name (output_bfd, sec->output_section);
+ if (strcmp (name, ".sdata") == 0
+ || strcmp (name, ".sbss") == 0)
+ {
+ reg = 13;
+ sda = htab->sdata[0].sym;
+ }
+ else if (strcmp (name, ".sdata2") == 0
+ || strcmp (name, ".sbss2") == 0)
+ {
+ reg = 2;
+ sda = htab->sdata[1].sym;
+ }
+ else if (strcmp (name, ".PPC.EMB.sdata0") == 0
+ || strcmp (name, ".PPC.EMB.sbss0") == 0)
+ {
+ reg = 0;
+ }
+ else
+ {
+ info->callbacks->einfo
+ (_("%P: %B: the target (%s) of a %s relocation is "
+ "in the wrong output section (%s)\n"),
+ input_bfd,
+ sym_name,
+ howto->name,
+ name);
+
+ bfd_set_error (bfd_error_bad_value);
+ ret = FALSE;
+ continue;
+ }
+
+ if (sda != NULL)
+ {
+ if (!is_static_defined (sda))
+ {
+ unresolved_reloc = TRUE;
+ break;
+ }
+ addend -= SYM_VAL (sda);
+ }
+
+ insn = bfd_get_32 (output_bfd, contents + rel->r_offset);
+ if (reg == 0
+ && (r_type == R_PPC_VLE_SDA21
+ || r_type == R_PPC_VLE_SDA21_LO))
+ {
+ relocation = relocation + addend;
+ addend = 0;
+
+ /* Force e_li insn, keeping RT from original insn. */
+ insn &= 0x1f << 21;
+ insn |= 28u << 26;
+
+ /* We have an li20 field, bits 17..20, 11..15, 21..31. */
+ /* Top 4 bits of value to 17..20. */
+ insn |= (relocation & 0xf0000) >> 5;
+ /* Next 5 bits of the value to 11..15. */
+ insn |= (relocation & 0xf800) << 5;
+ /* And the final 11 bits of the value to bits 21 to 31. */
+ insn |= relocation & 0x7ff;
+
+ bfd_put_32 (output_bfd, insn, contents + rel->r_offset);
+
+ if (r_type == R_PPC_VLE_SDA21
+ && ((relocation + 0x80000) & 0xffffffff) > 0x100000)
+ goto overflow;
+ continue;
+ }
+ else if (r_type == R_PPC_EMB_SDA21
+ || r_type == R_PPC_VLE_SDA21
+ || r_type == R_PPC_VLE_SDA21_LO)
+ {
+ /* Fill in register field. */
+ insn = (insn & ~RA_REGISTER_MASK) | (reg << RA_REGISTER_SHIFT);
+ }
+ bfd_put_32 (output_bfd, insn, contents + rel->r_offset);
+ }
+ break;
+
+ case R_PPC_VLE_SDAREL_LO16A:
+ case R_PPC_VLE_SDAREL_LO16D:
+ case R_PPC_VLE_SDAREL_HI16A:
+ case R_PPC_VLE_SDAREL_HI16D:
+ case R_PPC_VLE_SDAREL_HA16A:
+ case R_PPC_VLE_SDAREL_HA16D:
+ {
+ bfd_vma value;
+ const char *name;
+ //int reg;
+ struct elf_link_hash_entry *sda = NULL;
+
+ if (sec == NULL || sec->output_section == NULL)
+ {
+ unresolved_reloc = TRUE;
+ break;
+ }
+
+ name = bfd_get_section_name (output_bfd, sec->output_section);
+ if (strcmp (name, ".sdata") == 0
+ || strcmp (name, ".sbss") == 0)
+ {
+ //reg = 13;
+ sda = htab->sdata[0].sym;
+ }
+ else if (strcmp (name, ".sdata2") == 0
+ || strcmp (name, ".sbss2") == 0)
+ {
+ //reg = 2;
+ sda = htab->sdata[1].sym;
+ }
+ else
+ {
+ (*_bfd_error_handler)
+ (_("%B: the target (%s) of a %s relocation is "
+ "in the wrong output section (%s)"),
+ input_bfd,
+ sym_name,
+ howto->name,
+ name);
+
+ bfd_set_error (bfd_error_bad_value);
+ ret = FALSE;
+ continue;
+ }
+
+ if (sda != NULL)
+ {
+ if (!is_static_defined (sda))
+ {
+ unresolved_reloc = TRUE;
+ break;
+ }
+ }
+
+ value = (sda->root.u.def.section->output_section->vma
+ + sda->root.u.def.section->output_offset
+ + addend);
+
+ if (r_type == R_PPC_VLE_SDAREL_LO16A)
+ ppc_elf_vle_split16 (output_bfd, contents + rel->r_offset,
+ value, split16a_type);
+ else if (r_type == R_PPC_VLE_SDAREL_LO16D)
+ ppc_elf_vle_split16 (output_bfd, contents + rel->r_offset,
+ value, split16d_type);
+ else if (r_type == R_PPC_VLE_SDAREL_HI16A)
+ {
+ value = value >> 16;
+ ppc_elf_vle_split16 (output_bfd, contents + rel->r_offset,
+ value, split16a_type);
+ }
+ else if (r_type == R_PPC_VLE_SDAREL_HI16D)
+ {
+ value = value >> 16;
+ ppc_elf_vle_split16 (output_bfd, contents + rel->r_offset,
+ value, split16d_type);
+ }
+ else if (r_type == R_PPC_VLE_SDAREL_HA16A)
+ {
+ value = (value + 0x8000) >> 16;
+ ppc_elf_vle_split16 (output_bfd, contents + rel->r_offset,
+ value, split16a_type);
+ }
+ else if (r_type == R_PPC_VLE_SDAREL_HA16D)
+ {
+ value = (value + 0x8000) >> 16;
+ ppc_elf_vle_split16 (output_bfd, contents + rel->r_offset,
+ value, split16d_type);
+ }
+ }
+ continue;
+
+ /* Relocate against the beginning of the section. */
+ case R_PPC_SECTOFF:
+ case R_PPC_SECTOFF_LO:
+ case R_PPC_SECTOFF_HI:
+ case R_PPC_SECTOFF_HA:
+ if (sec == NULL || sec->output_section == NULL)
+ {
+ unresolved_reloc = TRUE;
+ break;
+ }
+ addend -= sec->output_section->vma;
+ break;
+
+ /* Negative relocations. */
+ case R_PPC_EMB_NADDR32:
+ case R_PPC_EMB_NADDR16:
+ case R_PPC_EMB_NADDR16_LO:
+ case R_PPC_EMB_NADDR16_HI:
+ case R_PPC_EMB_NADDR16_HA:
+ addend -= 2 * relocation;
+ break;
+
+ case R_PPC_COPY:
+ case R_PPC_GLOB_DAT:
+ case R_PPC_JMP_SLOT:
+ case R_PPC_RELATIVE:
+ case R_PPC_IRELATIVE:
+ case R_PPC_PLT32:
+ case R_PPC_PLTREL32:
+ case R_PPC_PLT16_LO:
+ case R_PPC_PLT16_HI:
+ case R_PPC_PLT16_HA:
+ case R_PPC_ADDR30:
+ case R_PPC_EMB_RELSEC16:
+ case R_PPC_EMB_RELST_LO:
+ case R_PPC_EMB_RELST_HI:
+ case R_PPC_EMB_RELST_HA:
+ case R_PPC_EMB_BIT_FLD:
+ info->callbacks->einfo
+ (_("%P: %B: relocation %s is not yet supported for symbol %s\n"),
+ input_bfd,
+ howto->name,
+ sym_name);
+
+ bfd_set_error (bfd_error_invalid_operation);
+ ret = FALSE;
+ continue;
+ }
+
+ /* Do any further special processing. */
+ switch (r_type)
+ {
+ default:
+ break;
+
+ case R_PPC_ADDR16_HA:
+ case R_PPC_REL16_HA:
+ case R_PPC_SECTOFF_HA:
+ case R_PPC_TPREL16_HA:
+ case R_PPC_DTPREL16_HA:
+ case R_PPC_EMB_NADDR16_HA:
+ case R_PPC_EMB_RELST_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). */
+ if (sec == NULL)
+ break;
+ /* Fall thru */
+
+ case R_PPC_PLT16_HA:
+ case R_PPC_GOT16_HA:
+ case R_PPC_GOT_TLSGD16_HA:
+ case R_PPC_GOT_TLSLD16_HA:
+ case R_PPC_GOT_TPREL16_HA:
+ case R_PPC_GOT_DTPREL16_HA:
+ /* Add 0x10000 if sign bit in 0:15 is set.
+ Bits 0:15 are not used. */
+ addend += 0x8000;
+ break;
+
+ case R_PPC_ADDR16:
+ case R_PPC_ADDR16_LO:
+ case R_PPC_GOT16:
+ case R_PPC_GOT16_LO:
+ case R_PPC_SDAREL16:
+ case R_PPC_SECTOFF:
+ case R_PPC_SECTOFF_LO:
+ case R_PPC_DTPREL16:
+ case R_PPC_DTPREL16_LO:
+ case R_PPC_TPREL16:
+ case R_PPC_TPREL16_LO:
+ case R_PPC_GOT_TLSGD16:
+ case R_PPC_GOT_TLSGD16_LO:
+ case R_PPC_GOT_TLSLD16:
+ case R_PPC_GOT_TLSLD16_LO:
+ case R_PPC_GOT_DTPREL16:
+ case R_PPC_GOT_DTPREL16_LO:
+ case R_PPC_GOT_TPREL16:
+ case R_PPC_GOT_TPREL16_LO:
+ {
+ /* The 32-bit ABI lacks proper relocations to deal with
+ certain 64-bit instructions. Prevent damage to bits
+ that make up part of the insn opcode. */
+ unsigned int insn, mask, lobit;
+
+ insn = bfd_get_32 (output_bfd, contents + rel->r_offset - d_offset);
+ mask = 0;
+ if (is_insn_ds_form (insn))
+ mask = 3;
+ else if (is_insn_dq_form (insn))
+ mask = 15;
+ else
+ break;
+ lobit = mask & (relocation + addend);
+ if (lobit != 0)
+ {
+ addend -= lobit;
+ info->callbacks->einfo
+ (_("%P: %H: error: %s against `%s' not a multiple of %u\n"),
+ input_bfd, input_section, rel->r_offset,
+ howto->name, sym_name, mask + 1);
+ bfd_set_error (bfd_error_bad_value);
+ ret = FALSE;
+ }
+ addend += insn & mask;
+ }
+ break;
+ }
+
+#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) rel->r_offset,
+ (long) addend);
+#endif
+
+ if (unresolved_reloc
+ && !((input_section->flags & SEC_DEBUGGING) != 0
+ && h->def_dynamic)
+ && _bfd_elf_section_offset (output_bfd, info, input_section,
+ rel->r_offset) != (bfd_vma) -1)
+ {
+ info->callbacks->einfo
+ (_("%P: %H: unresolvable %s relocation against symbol `%s'\n"),
+ input_bfd, input_section, rel->r_offset,
+ howto->name,
+ sym_name);
+ ret = FALSE;
+ }
+
+ /* 16-bit fields in insns mostly have signed values, but a
+ few insns have 16-bit unsigned values. Really, we should
+ have different reloc types. */
+ if (howto->complain_on_overflow != complain_overflow_dont
+ && howto->dst_mask == 0xffff
+ && (input_section->flags & SEC_CODE) != 0)
+ {
+ enum complain_overflow complain = complain_overflow_signed;
+
+ if ((elf_section_flags (input_section) & SHF_PPC_VLE) == 0)
+ {
+ unsigned int insn;
+
+ insn = bfd_get_32 (input_bfd, contents + (rel->r_offset & ~3));
+ if ((insn & (0x3f << 26)) == 10u << 26 /* cmpli */)
+ complain = complain_overflow_bitfield;
+ else if ((insn & (0x3f << 26)) == 28u << 26 /* andi */
+ || (insn & (0x3f << 26)) == 24u << 26 /* ori */
+ || (insn & (0x3f << 26)) == 26u << 26 /* xori */)
+ complain = complain_overflow_unsigned;
+ }
+ if (howto->complain_on_overflow != complain)
+ {
+ alt_howto = *howto;
+ alt_howto.complain_on_overflow = complain;
+ howto = &alt_howto;
+ }
+ }
+
+ r = _bfd_final_link_relocate (howto, input_bfd, input_section, contents,
+ rel->r_offset, relocation, addend);
+
+ if (r != bfd_reloc_ok)
+ {
+ if (r == bfd_reloc_overflow)
+ {
+ overflow:
+ if (warned)
+ continue;
+ if (h != NULL
+ && 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. */
+
+ continue;
+ }
+
+ if (! (*info->callbacks->reloc_overflow) (info,
+ (h ? &h->root : NULL),
+ sym_name,
+ howto->name,
+ rel->r_addend,
+ input_bfd,
+ input_section,
+ rel->r_offset))
+ return FALSE;
+ }
+ else
+ {
+ info->callbacks->einfo
+ (_("%P: %H: %s reloc against `%s': error %d\n"),
+ input_bfd, input_section, rel->r_offset,
+ howto->name, sym_name, (int) r);
+ ret = FALSE;
+ }
+ }
+ }
+
+#ifdef DEBUG
+ fprintf (stderr, "\n");
+#endif
+
+ if (input_section->sec_info_type == SEC_INFO_TYPE_TARGET
+ && input_section->size != input_section->rawsize
+ && (strcmp (input_section->output_section->name, ".init") == 0
+ || strcmp (input_section->output_section->name, ".fini") == 0))
+ {
+ /* Branch around the trampolines. */
+ unsigned int insn = B + input_section->size - input_section->rawsize;
+ bfd_put_32 (input_bfd, insn, contents + input_section->rawsize);
+ }
+
+ if (htab->params->ppc476_workaround
+ && input_section->sec_info_type == SEC_INFO_TYPE_TARGET
+ && (!info->relocatable
+ || (input_section->output_section->alignment_power
+ >= htab->params->pagesize_p2)))
+ {
+ struct ppc_elf_relax_info *relax_info;
+ bfd_vma start_addr, end_addr, addr;
+ bfd_vma pagesize = (bfd_vma) 1 << htab->params->pagesize_p2;
+
+ relax_info = elf_section_data (input_section)->sec_info;
+ if (relax_info->workaround_size != 0)
+ {
+ bfd_byte *p;
+ unsigned int n;
+ bfd_byte fill[4];
+
+ bfd_put_32 (input_bfd, BA, fill);
+ p = contents + input_section->size - relax_info->workaround_size;
+ n = relax_info->workaround_size >> 2;
+ while (n--)
+ {
+ memcpy (p, fill, 4);
+ p += 4;
+ }
+ }
+
+ /* The idea is: Replace the last instruction on a page with a
+ branch to a patch area. Put the insn there followed by a
+ branch back to the next page. Complicated a little by
+ needing to handle moved conditional branches, and by not
+ wanting to touch data-in-text. */
+
+ start_addr = (input_section->output_section->vma
+ + input_section->output_offset);
+ end_addr = (start_addr + input_section->size
+ - relax_info->workaround_size);
+ for (addr = ((start_addr & -pagesize) + pagesize - 4);
+ addr < end_addr;
+ addr += pagesize)
+ {
+ bfd_vma offset = addr - start_addr;
+ Elf_Internal_Rela *lo, *hi;
+ bfd_boolean is_data;
+ bfd_vma patch_off, patch_addr;
+ unsigned int insn;
+
+ /* Do we have a data reloc at this offset? If so, leave
+ the word alone. */
+ is_data = FALSE;
+ lo = relocs;
+ hi = relend;
+ rel = NULL;
+ while (lo < hi)
+ {
+ rel = lo + (hi - lo) / 2;
+ if (rel->r_offset < offset)
+ lo = rel + 1;
+ else if (rel->r_offset > offset + 3)
+ hi = rel;
+ else
+ {
+ switch (ELF32_R_TYPE (rel->r_info))
+ {
+ case R_PPC_ADDR32:
+ case R_PPC_UADDR32:
+ case R_PPC_REL32:
+ case R_PPC_ADDR30:
+ is_data = TRUE;
+ break;
+ default:
+ break;
+ }
+ break;
+ }
+ }
+ if (is_data)
+ continue;
+
+ /* Some instructions can be left alone too. Unconditional
+ branches, except for bcctr with BO=0x14 (bctr, bctrl),
+ avoid the icache failure.
+
+ The problem occurs due to prefetch across a page boundary
+ where stale instructions can be fetched from the next
+ page, and the mechanism for flushing these bad
+ instructions fails under certain circumstances. The
+ unconditional branches:
+ 1) Branch: b, bl, ba, bla,
+ 2) Branch Conditional: bc, bca, bcl, bcla,
+ 3) Branch Conditional to Link Register: bclr, bclrl,
+ where (2) and (3) have BO=0x14 making them unconditional,
+ prevent the bad prefetch because the prefetch itself is
+ affected by these instructions. This happens even if the
+ instruction is not executed.
+
+ A bctr example:
+ .
+ . lis 9,new_page@ha
+ . addi 9,9,new_page@l
+ . mtctr 9
+ . bctr
+ . nop
+ . nop
+ . new_page:
+ .
+ The bctr is not predicted taken due to ctr not being
+ ready, so prefetch continues on past the bctr into the
+ new page which might have stale instructions. If they
+ fail to be flushed, then they will be executed after the
+ bctr executes. Either of the following modifications
+ prevent the bad prefetch from happening in the first
+ place:
+ .
+ . lis 9,new_page@ha lis 9,new_page@ha
+ . addi 9,9,new_page@l addi 9,9,new_page@l
+ . mtctr 9 mtctr 9
+ . bctr bctr
+ . nop b somewhere_else
+ . b somewhere_else nop
+ . new_page: new_page:
+ . */
+ insn = bfd_get_32 (input_bfd, contents + offset);
+ if ((insn & (0x3f << 26)) == (18u << 26) /* b,bl,ba,bla */
+ || ((insn & (0x3f << 26)) == (16u << 26) /* bc,bcl,bca,bcla*/
+ && (insn & (0x14 << 21)) == (0x14 << 21)) /* with BO=0x14 */
+ || ((insn & (0x3f << 26)) == (19u << 26)
+ && (insn & (0x3ff << 1)) == (16u << 1) /* bclr,bclrl */
+ && (insn & (0x14 << 21)) == (0x14 << 21)))/* with BO=0x14 */
+ continue;
+
+ patch_addr = (start_addr + input_section->size
+ - relax_info->workaround_size);
+ patch_addr = (patch_addr + 15) & -16;
+ patch_off = patch_addr - start_addr;
+ bfd_put_32 (input_bfd, B + patch_off - offset, contents + offset);
+
+ if (rel != NULL
+ && rel->r_offset >= offset
+ && rel->r_offset < offset + 4)
+ {
+ /* If the insn we are patching had a reloc, adjust the
+ reloc r_offset so that the reloc applies to the moved
+ location. This matters for -r and --emit-relocs. */
+ if (rel + 1 != relend)
+ {
+ Elf_Internal_Rela tmp = *rel;
+
+ /* Keep the relocs sorted by r_offset. */
+ memmove (rel, rel + 1, (relend - (rel + 1)) * sizeof (*rel));
+ relend[-1] = tmp;
+ }
+ relend[-1].r_offset += patch_off - offset;
+ }
+ else
+ rel = NULL;
+
+ if ((insn & (0x3f << 26)) == (16u << 26) /* bc */
+ && (insn & 2) == 0 /* relative */)
+ {
+ bfd_vma delta = ((insn & 0xfffc) ^ 0x8000) - 0x8000;
+
+ delta += offset - patch_off;
+ if (info->relocatable && rel != NULL)
+ delta = 0;
+ if (!info->relocatable && rel != NULL)
+ {
+ enum elf_ppc_reloc_type r_type;
+
+ r_type = ELF32_R_TYPE (relend[-1].r_info);
+ if (r_type == R_PPC_REL14_BRTAKEN)
+ insn |= BRANCH_PREDICT_BIT;
+ else if (r_type == R_PPC_REL14_BRNTAKEN)
+ insn &= ~BRANCH_PREDICT_BIT;
+ else
+ BFD_ASSERT (r_type == R_PPC_REL14);
+
+ if ((r_type == R_PPC_REL14_BRTAKEN
+ || r_type == R_PPC_REL14_BRNTAKEN)
+ && delta + 0x8000 < 0x10000
+ && (bfd_signed_vma) delta < 0)
+ insn ^= BRANCH_PREDICT_BIT;
+ }
+ if (delta + 0x8000 < 0x10000)
+ {
+ bfd_put_32 (input_bfd,
+ (insn & ~0xfffc) | (delta & 0xfffc),
+ contents + patch_off);
+ patch_off += 4;
+ bfd_put_32 (input_bfd,
+ B | ((offset + 4 - patch_off) & 0x3fffffc),
+ contents + patch_off);
+ patch_off += 4;
+ }
+ else
+ {
+ if (rel != NULL)
+ {
+ unsigned int r_sym = ELF32_R_SYM (relend[-1].r_info);
+
+ relend[-1].r_offset += 8;
+ relend[-1].r_info = ELF32_R_INFO (r_sym, R_PPC_REL24);
+ }
+ bfd_put_32 (input_bfd,
+ (insn & ~0xfffc) | 8,
+ contents + patch_off);
+ patch_off += 4;
+ bfd_put_32 (input_bfd,
+ B | ((offset + 4 - patch_off) & 0x3fffffc),
+ contents + patch_off);
+ patch_off += 4;
+ bfd_put_32 (input_bfd,
+ B | ((delta - 8) & 0x3fffffc),
+ contents + patch_off);
+ patch_off += 4;
+ }
+ }
+ else
+ {
+ bfd_put_32 (input_bfd, insn, contents + patch_off);
+ patch_off += 4;
+ bfd_put_32 (input_bfd,
+ B | ((offset + 4 - patch_off) & 0x3fffffc),
+ contents + patch_off);
+ patch_off += 4;
+ }
+ BFD_ASSERT (patch_off <= input_section->size);
+ relax_info->workaround_size = input_section->size - patch_off;
+ }
+ }
+
+ return ret;
+}
+
+/* Finish up dynamic symbol handling. We set the contents of various
+ dynamic sections here. */
+
+static bfd_boolean
+ppc_elf_finish_dynamic_symbol (bfd *output_bfd,
+ struct bfd_link_info *info,
+ struct elf_link_hash_entry *h,
+ Elf_Internal_Sym *sym)
+{
+ struct ppc_elf_link_hash_table *htab;
+ struct plt_entry *ent;
+ bfd_boolean doneone;
+
+#ifdef DEBUG
+ fprintf (stderr, "ppc_elf_finish_dynamic_symbol called for %s",
+ h->root.root.string);
+#endif
+
+ htab = ppc_elf_hash_table (info);
+ BFD_ASSERT (htab->elf.dynobj != NULL);
+
+ doneone = FALSE;
+ for (ent = h->plt.plist; ent != NULL; ent = ent->next)
+ if (ent->plt.offset != (bfd_vma) -1)
+ {
+ if (!doneone)
+ {
+ Elf_Internal_Rela rela;
+ bfd_byte *loc;
+ bfd_vma reloc_index;
+
+ if (htab->plt_type == PLT_NEW
+ || !htab->elf.dynamic_sections_created
+ || h->dynindx == -1)
+ reloc_index = ent->plt.offset / 4;
+ else
+ {
+ reloc_index = ((ent->plt.offset - htab->plt_initial_entry_size)
+ / htab->plt_slot_size);
+ if (reloc_index > PLT_NUM_SINGLE_ENTRIES
+ && htab->plt_type == PLT_OLD)
+ reloc_index -= (reloc_index - PLT_NUM_SINGLE_ENTRIES) / 2;
+ }
+
+ /* This symbol has an entry in the procedure linkage table.
+ Set it up. */
+ if (htab->plt_type == PLT_VXWORKS
+ && htab->elf.dynamic_sections_created
+ && h->dynindx != -1)
+ {
+ bfd_vma got_offset;
+ const bfd_vma *plt_entry;
+
+ /* The first three entries in .got.plt are reserved. */
+ got_offset = (reloc_index + 3) * 4;
+
+ /* Use the right PLT. */
+ plt_entry = info->shared ? ppc_elf_vxworks_pic_plt_entry
+ : ppc_elf_vxworks_plt_entry;
+
+ /* Fill in the .plt on VxWorks. */
+ if (info->shared)
+ {
+ bfd_put_32 (output_bfd,
+ plt_entry[0] | PPC_HA (got_offset),
+ htab->plt->contents + ent->plt.offset + 0);
+ bfd_put_32 (output_bfd,
+ plt_entry[1] | PPC_LO (got_offset),
+ htab->plt->contents + ent->plt.offset + 4);
+ }
+ else
+ {
+ bfd_vma got_loc = got_offset + SYM_VAL (htab->elf.hgot);
+
+ bfd_put_32 (output_bfd,
+ plt_entry[0] | PPC_HA (got_loc),
+ htab->plt->contents + ent->plt.offset + 0);
+ bfd_put_32 (output_bfd,
+ plt_entry[1] | PPC_LO (got_loc),
+ htab->plt->contents + ent->plt.offset + 4);
+ }
+
+ bfd_put_32 (output_bfd, plt_entry[2],
+ htab->plt->contents + ent->plt.offset + 8);
+ bfd_put_32 (output_bfd, plt_entry[3],
+ htab->plt->contents + ent->plt.offset + 12);
+
+ /* This instruction is an immediate load. The value loaded is
+ the byte offset of the R_PPC_JMP_SLOT relocation from the
+ start of the .rela.plt section. The value is stored in the
+ low-order 16 bits of the load instruction. */
+ /* NOTE: It appears that this is now an index rather than a
+ prescaled offset. */
+ bfd_put_32 (output_bfd,
+ plt_entry[4] | reloc_index,
+ htab->plt->contents + ent->plt.offset + 16);
+ /* This instruction is a PC-relative branch whose target is
+ the start of the PLT section. The address of this branch
+ instruction is 20 bytes beyond the start of this PLT entry.
+ The address is encoded in bits 6-29, inclusive. The value
+ stored is right-shifted by two bits, permitting a 26-bit
+ offset. */
+ bfd_put_32 (output_bfd,
+ (plt_entry[5]
+ | (-(ent->plt.offset + 20) & 0x03fffffc)),
+ htab->plt->contents + ent->plt.offset + 20);
+ bfd_put_32 (output_bfd, plt_entry[6],
+ htab->plt->contents + ent->plt.offset + 24);
+ bfd_put_32 (output_bfd, plt_entry[7],
+ htab->plt->contents + ent->plt.offset + 28);
+
+ /* Fill in the GOT entry corresponding to this PLT slot with
+ the address immediately after the "bctr" instruction
+ in this PLT entry. */
+ bfd_put_32 (output_bfd, (htab->plt->output_section->vma
+ + htab->plt->output_offset
+ + ent->plt.offset + 16),
+ htab->sgotplt->contents + got_offset);
+
+ if (!info->shared)
+ {
+ /* Fill in a couple of entries in .rela.plt.unloaded. */
+ loc = htab->srelplt2->contents
+ + ((VXWORKS_PLTRESOLVE_RELOCS + reloc_index
+ * VXWORKS_PLT_NON_JMP_SLOT_RELOCS)
+ * sizeof (Elf32_External_Rela));
+
+ /* Provide the @ha relocation for the first instruction. */
+ rela.r_offset = (htab->plt->output_section->vma
+ + htab->plt->output_offset
+ + ent->plt.offset + 2);
+ rela.r_info = ELF32_R_INFO (htab->elf.hgot->indx,
+ R_PPC_ADDR16_HA);
+ rela.r_addend = got_offset;
+ bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
+ loc += sizeof (Elf32_External_Rela);
+
+ /* Provide the @l relocation for the second instruction. */
+ rela.r_offset = (htab->plt->output_section->vma
+ + htab->plt->output_offset
+ + ent->plt.offset + 6);
+ rela.r_info = ELF32_R_INFO (htab->elf.hgot->indx,
+ R_PPC_ADDR16_LO);
+ rela.r_addend = got_offset;
+ bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
+ loc += sizeof (Elf32_External_Rela);
+
+ /* Provide a relocation for the GOT entry corresponding to this
+ PLT slot. Point it at the middle of the .plt entry. */
+ rela.r_offset = (htab->sgotplt->output_section->vma
+ + htab->sgotplt->output_offset
+ + got_offset);
+ rela.r_info = ELF32_R_INFO (htab->elf.hplt->indx,
+ R_PPC_ADDR32);
+ rela.r_addend = ent->plt.offset + 16;
+ bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
+ }
+
+ /* VxWorks uses non-standard semantics for R_PPC_JMP_SLOT.
+ In particular, the offset for the relocation is not the
+ address of the PLT entry for this function, as specified
+ by the ABI. Instead, the offset is set to the address of
+ the GOT slot for this function. See EABI 4.4.4.1. */
+ rela.r_offset = (htab->sgotplt->output_section->vma
+ + htab->sgotplt->output_offset
+ + got_offset);
+
+ }
+ else
+ {
+ asection *splt = htab->plt;
+ if (!htab->elf.dynamic_sections_created
+ || h->dynindx == -1)
+ splt = htab->iplt;
+
+ rela.r_offset = (splt->output_section->vma
+ + splt->output_offset
+ + ent->plt.offset);
+ if (htab->plt_type == PLT_OLD
+ || !htab->elf.dynamic_sections_created
+ || h->dynindx == -1)
+ {
+ /* We don't need to fill in the .plt. The ppc dynamic
+ linker will fill it in. */
+ }
+ else
+ {
+ bfd_vma val = (htab->glink_pltresolve + ent->plt.offset
+ + htab->glink->output_section->vma
+ + htab->glink->output_offset);
+ bfd_put_32 (output_bfd, val,
+ splt->contents + ent->plt.offset);
+ }
+ }
+
+ /* Fill in the entry in the .rela.plt section. */
+ rela.r_addend = 0;
+ if (!htab->elf.dynamic_sections_created
+ || h->dynindx == -1)
+ {
+ BFD_ASSERT (h->type == STT_GNU_IFUNC
+ && h->def_regular
+ && (h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak));
+ rela.r_info = ELF32_R_INFO (0, R_PPC_IRELATIVE);
+ rela.r_addend = SYM_VAL (h);
+ }
+ else
+ rela.r_info = ELF32_R_INFO (h->dynindx, R_PPC_JMP_SLOT);
+
+ if (!htab->elf.dynamic_sections_created
+ || h->dynindx == -1)
+ loc = (htab->reliplt->contents
+ + (htab->reliplt->reloc_count++
+ * sizeof (Elf32_External_Rela)));
+ else
+ loc = (htab->relplt->contents
+ + reloc_index * sizeof (Elf32_External_Rela));
+ bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
+
+ if (!h->def_regular)
+ {
+ /* Mark the symbol as undefined, rather than as
+ defined in the .plt section. Leave the value if
+ there were any relocations where pointer equality
+ matters (this is a clue for the dynamic linker, to
+ make function pointer comparisons work between an
+ application and shared library), otherwise set it
+ to zero. */
+ sym->st_shndx = SHN_UNDEF;
+ if (!h->pointer_equality_needed)
+ sym->st_value = 0;
+ else if (!h->ref_regular_nonweak)
+ {
+ /* This breaks function pointer comparisons, but
+ that is better than breaking tests for a NULL
+ function pointer. */
+ sym->st_value = 0;
+ }
+ }
+ else if (h->type == STT_GNU_IFUNC
+ && !info->shared)
+ {
+ /* Set the value of ifunc symbols in a non-pie
+ executable to the glink entry. This is to avoid
+ text relocations. We can't do this for ifunc in
+ allocate_dynrelocs, as we do for normal dynamic
+ function symbols with plt entries, because we need
+ to keep the original value around for the ifunc
+ relocation. */
+ sym->st_shndx = (_bfd_elf_section_from_bfd_section
+ (output_bfd, htab->glink->output_section));
+ sym->st_value = (ent->glink_offset
+ + htab->glink->output_offset
+ + htab->glink->output_section->vma);
+ }
+ doneone = TRUE;
+ }
+
+ if (htab->plt_type == PLT_NEW
+ || !htab->elf.dynamic_sections_created
+ || h->dynindx == -1)
+ {
+ unsigned char *p;
+ asection *splt = htab->plt;
+ if (!htab->elf.dynamic_sections_created
+ || h->dynindx == -1)
+ splt = htab->iplt;
+
+ p = (unsigned char *) htab->glink->contents + ent->glink_offset;
+
+ if (h == htab->tls_get_addr && !htab->params->no_tls_get_addr_opt)
+ {
+ bfd_put_32 (output_bfd, LWZ_11_3, p);
+ p += 4;
+ bfd_put_32 (output_bfd, LWZ_12_3 + 4, p);
+ p += 4;
+ bfd_put_32 (output_bfd, MR_0_3, p);
+ p += 4;
+ bfd_put_32 (output_bfd, CMPWI_11_0, p);
+ p += 4;
+ bfd_put_32 (output_bfd, ADD_3_12_2, p);
+ p += 4;
+ bfd_put_32 (output_bfd, BEQLR, p);
+ p += 4;
+ bfd_put_32 (output_bfd, MR_3_0, p);
+ p += 4;
+ bfd_put_32 (output_bfd, NOP, p);
+ p += 4;
+ }
+
+ write_glink_stub (ent, splt, p, info);
+
+ if (!info->shared)
+ /* We only need one non-PIC glink stub. */
+ break;
+ }
+ else
+ break;
+ }
+
+ if (h->needs_copy)
+ {
+ asection *s;
+ Elf_Internal_Rela rela;
+ bfd_byte *loc;
+
+ /* This symbols needs a copy reloc. Set it up. */
+
+#ifdef DEBUG
+ fprintf (stderr, ", copy");
+#endif
+
+ BFD_ASSERT (h->dynindx != -1);
+
+ if (ppc_elf_hash_entry (h)->has_sda_refs)
+ s = htab->relsbss;
+ else
+ s = htab->relbss;
+ BFD_ASSERT (s != NULL);
+
+ rela.r_offset = SYM_VAL (h);
+ rela.r_info = ELF32_R_INFO (h->dynindx, R_PPC_COPY);
+ rela.r_addend = 0;
+ loc = s->contents + s->reloc_count++ * sizeof (Elf32_External_Rela);
+ bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
+ }
+
+#ifdef DEBUG
+ fprintf (stderr, "\n");
+#endif
+
+ return TRUE;
+}
+
+static enum elf_reloc_type_class
+ppc_elf_reloc_type_class (const struct bfd_link_info *info,
+ const asection *rel_sec,
+ const Elf_Internal_Rela *rela)
+{
+ struct ppc_elf_link_hash_table *htab = ppc_elf_hash_table (info);
+
+ if (rel_sec == htab->reliplt)
+ return reloc_class_ifunc;
+
+ switch (ELF32_R_TYPE (rela->r_info))
+ {
+ case R_PPC_RELATIVE:
+ return reloc_class_relative;
+ case R_PPC_JMP_SLOT:
+ return reloc_class_plt;
+ case R_PPC_COPY:
+ return reloc_class_copy;
+ default:
+ return reloc_class_normal;
+ }
+}
+
+/* Finish up the dynamic sections. */
+
+static bfd_boolean
+ppc_elf_finish_dynamic_sections (bfd *output_bfd,
+ struct bfd_link_info *info)
+{
+ asection *sdyn;
+ asection *splt;
+ struct ppc_elf_link_hash_table *htab;
+ bfd_vma got;
+ bfd *dynobj;
+ bfd_boolean ret = TRUE;
+
+#ifdef DEBUG
+ fprintf (stderr, "ppc_elf_finish_dynamic_sections called\n");
+#endif
+
+ htab = ppc_elf_hash_table (info);
+ dynobj = elf_hash_table (info)->dynobj;
+ sdyn = bfd_get_linker_section (dynobj, ".dynamic");
+ if (htab->is_vxworks)
+ splt = bfd_get_linker_section (dynobj, ".plt");
+ else
+ splt = NULL;
+
+ got = 0;
+ if (htab->elf.hgot != NULL)
+ got = SYM_VAL (htab->elf.hgot);
+
+ if (htab->elf.dynamic_sections_created)
+ {
+ Elf32_External_Dyn *dyncon, *dynconend;
+
+ BFD_ASSERT (htab->plt != NULL && sdyn != NULL);
+
+ dyncon = (Elf32_External_Dyn *) sdyn->contents;
+ dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->size);
+ for (; dyncon < dynconend; dyncon++)
+ {
+ Elf_Internal_Dyn dyn;
+ asection *s;
+
+ bfd_elf32_swap_dyn_in (dynobj, dyncon, &dyn);
+
+ switch (dyn.d_tag)
+ {
+ case DT_PLTGOT:
+ if (htab->is_vxworks)
+ s = htab->sgotplt;
+ else
+ s = htab->plt;
+ dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
+ break;
+
+ case DT_PLTRELSZ:
+ dyn.d_un.d_val = htab->relplt->size;
+ break;
+
+ case DT_JMPREL:
+ s = htab->relplt;
+ dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
+ break;
+
+ case DT_PPC_GOT:
+ dyn.d_un.d_ptr = got;
+ break;
+
+ case DT_RELASZ:
+ if (htab->is_vxworks)
+ {
+ if (htab->relplt)
+ dyn.d_un.d_ptr -= htab->relplt->size;
+ break;
+ }
+ continue;
+
+ default:
+ if (htab->is_vxworks
+ && elf_vxworks_finish_dynamic_entry (output_bfd, &dyn))
+ break;
+ continue;
+ }
+
+ bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
+ }
+ }
+
+ if (htab->got != NULL)
+ {
+ if (htab->elf.hgot->root.u.def.section == htab->got
+ || htab->elf.hgot->root.u.def.section == htab->sgotplt)
+ {
+ unsigned char *p = htab->elf.hgot->root.u.def.section->contents;
+
+ p += htab->elf.hgot->root.u.def.value;
+ if (htab->plt_type == PLT_OLD)
+ {
+ /* Add a blrl instruction at _GLOBAL_OFFSET_TABLE_-4
+ so that a function can easily find the address of
+ _GLOBAL_OFFSET_TABLE_. */
+ BFD_ASSERT (htab->elf.hgot->root.u.def.value - 4
+ < htab->elf.hgot->root.u.def.section->size);
+ bfd_put_32 (output_bfd, 0x4e800021, p - 4);
+ }
+
+ if (sdyn != NULL)
+ {
+ bfd_vma val = sdyn->output_section->vma + sdyn->output_offset;
+ BFD_ASSERT (htab->elf.hgot->root.u.def.value
+ < htab->elf.hgot->root.u.def.section->size);
+ bfd_put_32 (output_bfd, val, p);
+ }
+ }
+ else
+ {
+ info->callbacks->einfo (_("%P: %s not defined in linker created %s\n"),
+ htab->elf.hgot->root.root.string,
+ (htab->sgotplt != NULL
+ ? htab->sgotplt->name : htab->got->name));
+ bfd_set_error (bfd_error_bad_value);
+ ret = FALSE;
+ }
+
+ elf_section_data (htab->got->output_section)->this_hdr.sh_entsize = 4;
+ }
+
+ /* Fill in the first entry in the VxWorks procedure linkage table. */
+ if (splt && splt->size > 0)
+ {
+ /* Use the right PLT. */
+ const bfd_vma *plt_entry = (info->shared
+ ? ppc_elf_vxworks_pic_plt0_entry
+ : ppc_elf_vxworks_plt0_entry);
+
+ if (!info->shared)
+ {
+ bfd_vma got_value = SYM_VAL (htab->elf.hgot);
+
+ bfd_put_32 (output_bfd, plt_entry[0] | PPC_HA (got_value),
+ splt->contents + 0);
+ bfd_put_32 (output_bfd, plt_entry[1] | PPC_LO (got_value),
+ splt->contents + 4);
+ }
+ else
+ {
+ bfd_put_32 (output_bfd, plt_entry[0], splt->contents + 0);
+ bfd_put_32 (output_bfd, plt_entry[1], splt->contents + 4);
+ }
+ bfd_put_32 (output_bfd, plt_entry[2], splt->contents + 8);
+ bfd_put_32 (output_bfd, plt_entry[3], splt->contents + 12);
+ bfd_put_32 (output_bfd, plt_entry[4], splt->contents + 16);
+ bfd_put_32 (output_bfd, plt_entry[5], splt->contents + 20);
+ bfd_put_32 (output_bfd, plt_entry[6], splt->contents + 24);
+ bfd_put_32 (output_bfd, plt_entry[7], splt->contents + 28);
+
+ if (! info->shared)
+ {
+ Elf_Internal_Rela rela;
+ bfd_byte *loc;
+
+ loc = htab->srelplt2->contents;
+
+ /* Output the @ha relocation for the first instruction. */
+ rela.r_offset = (htab->plt->output_section->vma
+ + htab->plt->output_offset
+ + 2);
+ rela.r_info = ELF32_R_INFO (htab->elf.hgot->indx, R_PPC_ADDR16_HA);
+ rela.r_addend = 0;
+ bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
+ loc += sizeof (Elf32_External_Rela);
+
+ /* Output the @l relocation for the second instruction. */
+ rela.r_offset = (htab->plt->output_section->vma
+ + htab->plt->output_offset
+ + 6);
+ rela.r_info = ELF32_R_INFO (htab->elf.hgot->indx, R_PPC_ADDR16_LO);
+ rela.r_addend = 0;
+ bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
+ loc += sizeof (Elf32_External_Rela);
+
+ /* Fix up the remaining relocations. They may have the wrong
+ symbol index for _G_O_T_ or _P_L_T_ depending on the order
+ in which symbols were output. */
+ while (loc < htab->srelplt2->contents + htab->srelplt2->size)
+ {
+ Elf_Internal_Rela rel;
+
+ bfd_elf32_swap_reloc_in (output_bfd, loc, &rel);
+ rel.r_info = ELF32_R_INFO (htab->elf.hgot->indx, R_PPC_ADDR16_HA);
+ bfd_elf32_swap_reloc_out (output_bfd, &rel, loc);
+ loc += sizeof (Elf32_External_Rela);
+
+ bfd_elf32_swap_reloc_in (output_bfd, loc, &rel);
+ rel.r_info = ELF32_R_INFO (htab->elf.hgot->indx, R_PPC_ADDR16_LO);
+ bfd_elf32_swap_reloc_out (output_bfd, &rel, loc);
+ loc += sizeof (Elf32_External_Rela);
+
+ bfd_elf32_swap_reloc_in (output_bfd, loc, &rel);
+ rel.r_info = ELF32_R_INFO (htab->elf.hplt->indx, R_PPC_ADDR32);
+ bfd_elf32_swap_reloc_out (output_bfd, &rel, loc);
+ loc += sizeof (Elf32_External_Rela);
+ }
+ }
+ }
+
+ if (htab->glink != NULL
+ && htab->glink->contents != NULL
+ && htab->elf.dynamic_sections_created)
+ {
+ unsigned char *p;
+ unsigned char *endp;
+ bfd_vma res0;
+ unsigned int i;
+
+ /*
+ * PIC glink code is the following:
+ *
+ * # ith PLT code stub.
+ * addis 11,30,(plt+(i-1)*4-got)@ha
+ * lwz 11,(plt+(i-1)*4-got)@l(11)
+ * mtctr 11
+ * bctr
+ *
+ * # A table of branches, one for each plt entry.
+ * # The idea is that the plt call stub loads ctr and r11 with these
+ * # addresses, so (r11 - res_0) gives the plt index * 4.
+ * res_0: b PLTresolve
+ * res_1: b PLTresolve
+ * .
+ * # Some number of entries towards the end can be nops
+ * res_n_m3: nop
+ * res_n_m2: nop
+ * res_n_m1:
+ *
+ * PLTresolve:
+ * addis 11,11,(1f-res_0)@ha
+ * mflr 0
+ * bcl 20,31,1f
+ * 1: addi 11,11,(1b-res_0)@l
+ * mflr 12
+ * mtlr 0
+ * sub 11,11,12 # r11 = index * 4
+ * addis 12,12,(got+4-1b)@ha
+ * lwz 0,(got+4-1b)@l(12) # got[1] address of dl_runtime_resolve
+ * lwz 12,(got+8-1b)@l(12) # got[2] contains the map address
+ * mtctr 0
+ * add 0,11,11
+ * add 11,0,11 # r11 = index * 12 = reloc offset.
+ * bctr
+ */
+ static const unsigned int pic_plt_resolve[] =
+ {
+ ADDIS_11_11,
+ MFLR_0,
+ BCL_20_31,
+ ADDI_11_11,
+ MFLR_12,
+ MTLR_0,
+ SUB_11_11_12,
+ ADDIS_12_12,
+ LWZ_0_12,
+ LWZ_12_12,
+ MTCTR_0,
+ ADD_0_11_11,
+ ADD_11_0_11,
+ BCTR,
+ NOP,
+ NOP
+ };
+
+ /*
+ * Non-PIC glink code is a little simpler.
+ *
+ * # ith PLT code stub.
+ * lis 11,(plt+(i-1)*4)@ha
+ * lwz 11,(plt+(i-1)*4)@l(11)
+ * mtctr 11
+ * bctr
+ *
+ * The branch table is the same, then comes
+ *
+ * PLTresolve:
+ * lis 12,(got+4)@ha
+ * addis 11,11,(-res_0)@ha
+ * lwz 0,(got+4)@l(12) # got[1] address of dl_runtime_resolve
+ * addi 11,11,(-res_0)@l # r11 = index * 4
+ * mtctr 0
+ * add 0,11,11
+ * lwz 12,(got+8)@l(12) # got[2] contains the map address
+ * add 11,0,11 # r11 = index * 12 = reloc offset.
+ * bctr
+ */
+ static const unsigned int plt_resolve[] =
+ {
+ LIS_12,
+ ADDIS_11_11,
+ LWZ_0_12,
+ ADDI_11_11,
+ MTCTR_0,
+ ADD_0_11_11,
+ LWZ_12_12,
+ ADD_11_0_11,
+ BCTR,
+ NOP,
+ NOP,
+ NOP,
+ NOP,
+ NOP,
+ NOP,
+ NOP
+ };
+
+ if (ARRAY_SIZE (pic_plt_resolve) != GLINK_PLTRESOLVE / 4)
+ abort ();
+ if (ARRAY_SIZE (plt_resolve) != GLINK_PLTRESOLVE / 4)
+ abort ();
+
+ /* Build the branch table, one for each plt entry (less one),
+ and perhaps some padding. */
+ p = htab->glink->contents;
+ p += htab->glink_pltresolve;
+ endp = htab->glink->contents;
+ endp += htab->glink->size - GLINK_PLTRESOLVE;
+ while (p < endp - (htab->params->ppc476_workaround ? 0 : 8 * 4))
+ {
+ bfd_put_32 (output_bfd, B + endp - p, p);
+ p += 4;
+ }
+ while (p < endp)
+ {
+ bfd_put_32 (output_bfd, NOP, p);
+ p += 4;
+ }
+
+ res0 = (htab->glink_pltresolve
+ + htab->glink->output_section->vma
+ + htab->glink->output_offset);
+
+ if (htab->params->ppc476_workaround)
+ {
+ /* Ensure that a call stub at the end of a page doesn't
+ result in prefetch over the end of the page into the
+ glink branch table. */
+ bfd_vma pagesize = (bfd_vma) 1 << htab->params->pagesize_p2;
+ bfd_vma page_addr;
+ bfd_vma glink_start = (htab->glink->output_section->vma
+ + htab->glink->output_offset);
+
+ for (page_addr = res0 & -pagesize;
+ page_addr > glink_start;
+ page_addr -= pagesize)
+ {
+ /* We have a plt call stub that may need fixing. */
+ bfd_byte *loc;
+ unsigned int insn;
+
+ loc = htab->glink->contents + page_addr - 4 - glink_start;
+ insn = bfd_get_32 (output_bfd, loc);
+ if (insn == BCTR)
+ {
+ /* By alignment, we know that there must be at least
+ one other call stub before this one. */
+ insn = bfd_get_32 (output_bfd, loc - 16);
+ if (insn == BCTR)
+ bfd_put_32 (output_bfd, B | (-16 & 0x3fffffc), loc);
+ else
+ bfd_put_32 (output_bfd, B | (-20 & 0x3fffffc), loc);
+ }
+ }
+ }
+
+ /* Last comes the PLTresolve stub. */
+ if (info->shared)
+ {
+ bfd_vma bcl;
+
+ for (i = 0; i < ARRAY_SIZE (pic_plt_resolve); i++)
+ {
+ unsigned int insn = pic_plt_resolve[i];
+
+ if (htab->params->ppc476_workaround && insn == NOP)
+ insn = BA + 0;
+ bfd_put_32 (output_bfd, insn, p);
+ p += 4;
+ }
+ p -= 4 * ARRAY_SIZE (pic_plt_resolve);
+
+ bcl = (htab->glink->size - GLINK_PLTRESOLVE + 3*4
+ + htab->glink->output_section->vma
+ + htab->glink->output_offset);
+
+ bfd_put_32 (output_bfd,
+ ADDIS_11_11 + PPC_HA (bcl - res0), p + 0*4);
+ bfd_put_32 (output_bfd,
+ ADDI_11_11 + PPC_LO (bcl - res0), p + 3*4);
+ bfd_put_32 (output_bfd,
+ ADDIS_12_12 + PPC_HA (got + 4 - bcl), p + 7*4);
+ if (PPC_HA (got + 4 - bcl) == PPC_HA (got + 8 - bcl))
+ {
+ bfd_put_32 (output_bfd,
+ LWZ_0_12 + PPC_LO (got + 4 - bcl), p + 8*4);
+ bfd_put_32 (output_bfd,
+ LWZ_12_12 + PPC_LO (got + 8 - bcl), p + 9*4);
+ }
+ else
+ {
+ bfd_put_32 (output_bfd,
+ LWZU_0_12 + PPC_LO (got + 4 - bcl), p + 8*4);
+ bfd_put_32 (output_bfd,
+ LWZ_12_12 + 4, p + 9*4);
+ }
+ }
+ else
+ {
+ for (i = 0; i < ARRAY_SIZE (plt_resolve); i++)
+ {
+ unsigned int insn = plt_resolve[i];
+
+ if (htab->params->ppc476_workaround && insn == NOP)
+ insn = BA + 0;
+ bfd_put_32 (output_bfd, insn, p);
+ p += 4;
+ }
+ p -= 4 * ARRAY_SIZE (plt_resolve);
+
+ bfd_put_32 (output_bfd,
+ LIS_12 + PPC_HA (got + 4), p + 0*4);
+ bfd_put_32 (output_bfd,
+ ADDIS_11_11 + PPC_HA (-res0), p + 1*4);
+ bfd_put_32 (output_bfd,
+ ADDI_11_11 + PPC_LO (-res0), p + 3*4);
+ if (PPC_HA (got + 4) == PPC_HA (got + 8))
+ {
+ bfd_put_32 (output_bfd,
+ LWZ_0_12 + PPC_LO (got + 4), p + 2*4);
+ bfd_put_32 (output_bfd,
+ LWZ_12_12 + PPC_LO (got + 8), p + 6*4);
+ }
+ else
+ {
+ bfd_put_32 (output_bfd,
+ LWZU_0_12 + PPC_LO (got + 4), p + 2*4);
+ bfd_put_32 (output_bfd,
+ LWZ_12_12 + 4, p + 6*4);
+ }
+ }
+ }
+
+ if (htab->glink_eh_frame != NULL
+ && htab->glink_eh_frame->contents != NULL)
+ {
+ unsigned char *p = htab->glink_eh_frame->contents;
+ bfd_vma val;
+
+ p += sizeof (glink_eh_frame_cie);
+ /* FDE length. */
+ p += 4;
+ /* CIE pointer. */
+ p += 4;
+ /* Offset to .glink. */
+ val = (htab->glink->output_section->vma
+ + htab->glink->output_offset);
+ val -= (htab->glink_eh_frame->output_section->vma
+ + htab->glink_eh_frame->output_offset);
+ val -= p - htab->glink_eh_frame->contents;
+ bfd_put_32 (htab->elf.dynobj, val, p);
+
+ if (htab->glink_eh_frame->sec_info_type == SEC_INFO_TYPE_EH_FRAME
+ && !_bfd_elf_write_section_eh_frame (output_bfd, info,
+ htab->glink_eh_frame,
+ htab->glink_eh_frame->contents))
+ return FALSE;
+ }
+
+ return ret;
+}
+
+#define TARGET_LITTLE_SYM powerpc_elf32_le_vec
+#define TARGET_LITTLE_NAME "elf32-powerpcle"
+#define TARGET_BIG_SYM powerpc_elf32_vec
+#define TARGET_BIG_NAME "elf32-powerpc"
+#define ELF_ARCH bfd_arch_powerpc
+#define ELF_TARGET_ID PPC32_ELF_DATA
+#define ELF_MACHINE_CODE EM_PPC
+#ifdef __QNXTARGET__
+#define ELF_MAXPAGESIZE 0x1000
+#else
+#define ELF_MAXPAGESIZE 0x10000
+#endif
+#define ELF_MINPAGESIZE 0x1000
+#define ELF_COMMONPAGESIZE 0x1000
+#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_can_gc_sections 1
+#define elf_backend_can_refcount 1
+#define elf_backend_rela_normal 1
+#define elf_backend_caches_rawsize 1
+
+#define bfd_elf32_mkobject ppc_elf_mkobject
+#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_reloc_name_lookup ppc_elf_reloc_name_lookup
+#define bfd_elf32_bfd_set_private_flags ppc_elf_set_private_flags
+#define bfd_elf32_bfd_link_hash_table_create ppc_elf_link_hash_table_create
+#define bfd_elf32_get_synthetic_symtab ppc_elf_get_synthetic_symtab
+
+#define elf_backend_object_p ppc_elf_object_p
+#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_copy_indirect_symbol ppc_elf_copy_indirect_symbol
+#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_hash_symbol ppc_elf_hash_symbol
+#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
+#define elf_backend_grok_prstatus ppc_elf_grok_prstatus
+#define elf_backend_grok_psinfo ppc_elf_grok_psinfo
+#define elf_backend_write_core_note ppc_elf_write_core_note
+#define elf_backend_reloc_type_class ppc_elf_reloc_type_class
+#define elf_backend_begin_write_processing ppc_elf_begin_write_processing
+#define elf_backend_final_write_processing ppc_elf_final_write_processing
+#define elf_backend_write_section ppc_elf_write_section
+#define elf_backend_get_sec_type_attr ppc_elf_get_sec_type_attr
+#define elf_backend_plt_sym_val ppc_elf_plt_sym_val
+#define elf_backend_action_discarded ppc_elf_action_discarded
+#define elf_backend_init_index_section _bfd_elf_init_1_index_section
+#define elf_backend_lookup_section_flags_hook ppc_elf_lookup_section_flags
+#define elf_backend_section_processing ppc_elf_section_processing
+
+#include "elf32-target.h"
+
+/* FreeBSD Target */
+
+#undef TARGET_LITTLE_SYM
+#undef TARGET_LITTLE_NAME
+
+#undef TARGET_BIG_SYM
+#define TARGET_BIG_SYM powerpc_elf32_fbsd_vec
+#undef TARGET_BIG_NAME
+#define TARGET_BIG_NAME "elf32-powerpc-freebsd"
+
+#undef ELF_OSABI
+#define ELF_OSABI ELFOSABI_FREEBSD
+
+#undef elf32_bed
+#define elf32_bed elf32_powerpc_fbsd_bed
+
+#include "elf32-target.h"
+
+/* VxWorks Target */
+
+#undef TARGET_LITTLE_SYM
+#undef TARGET_LITTLE_NAME
+
+#undef TARGET_BIG_SYM
+#define TARGET_BIG_SYM powerpc_elf32_vxworks_vec
+#undef TARGET_BIG_NAME
+#define TARGET_BIG_NAME "elf32-powerpc-vxworks"
+
+#undef ELF_OSABI
+
+/* VxWorks uses the elf default section flags for .plt. */
+static const struct bfd_elf_special_section *
+ppc_elf_vxworks_get_sec_type_attr (bfd *abfd ATTRIBUTE_UNUSED, asection *sec)
+{
+ if (sec->name == NULL)
+ return NULL;
+
+ if (strcmp (sec->name, ".plt") == 0)
+ return _bfd_elf_get_sec_type_attr (abfd, sec);
+
+ return ppc_elf_get_sec_type_attr (abfd, sec);
+}
+
+/* Like ppc_elf_link_hash_table_create, but overrides
+ appropriately for VxWorks. */
+static struct bfd_link_hash_table *
+ppc_elf_vxworks_link_hash_table_create (bfd *abfd)
+{
+ struct bfd_link_hash_table *ret;
+
+ ret = ppc_elf_link_hash_table_create (abfd);
+ if (ret)
+ {
+ struct ppc_elf_link_hash_table *htab
+ = (struct ppc_elf_link_hash_table *)ret;
+ htab->is_vxworks = 1;
+ htab->plt_type = PLT_VXWORKS;
+ htab->plt_entry_size = VXWORKS_PLT_ENTRY_SIZE;
+ htab->plt_slot_size = VXWORKS_PLT_ENTRY_SIZE;
+ htab->plt_initial_entry_size = VXWORKS_PLT_INITIAL_ENTRY_SIZE;
+ }
+ return ret;
+}
+
+/* Tweak magic VxWorks symbols as they are loaded. */
+static bfd_boolean
+ppc_elf_vxworks_add_symbol_hook (bfd *abfd,
+ struct bfd_link_info *info,
+ Elf_Internal_Sym *sym,
+ const char **namep ATTRIBUTE_UNUSED,
+ flagword *flagsp ATTRIBUTE_UNUSED,
+ asection **secp,
+ bfd_vma *valp)
+{
+ if (!elf_vxworks_add_symbol_hook(abfd, info, sym,namep, flagsp, secp,
+ valp))
+ return FALSE;
+
+ return ppc_elf_add_symbol_hook(abfd, info, sym,namep, flagsp, secp, valp);
+}
+
+static void
+ppc_elf_vxworks_final_write_processing (bfd *abfd, bfd_boolean linker)
+{
+ ppc_elf_final_write_processing(abfd, linker);
+ elf_vxworks_final_write_processing(abfd, linker);
+}
+
+/* On VxWorks, we emit relocations against _PROCEDURE_LINKAGE_TABLE_, so
+ define it. */
+#undef elf_backend_want_plt_sym
+#define elf_backend_want_plt_sym 1
+#undef elf_backend_want_got_plt
+#define elf_backend_want_got_plt 1
+#undef elf_backend_got_symbol_offset
+#define elf_backend_got_symbol_offset 0
+#undef elf_backend_plt_not_loaded
+#define elf_backend_plt_not_loaded 0
+#undef elf_backend_plt_readonly
+#define elf_backend_plt_readonly 1
+#undef elf_backend_got_header_size
+#define elf_backend_got_header_size 12
+
+#undef bfd_elf32_get_synthetic_symtab
+
+#undef bfd_elf32_bfd_link_hash_table_create
+#define bfd_elf32_bfd_link_hash_table_create \
+ ppc_elf_vxworks_link_hash_table_create
+#undef elf_backend_add_symbol_hook
+#define elf_backend_add_symbol_hook \
+ ppc_elf_vxworks_add_symbol_hook
+#undef elf_backend_link_output_symbol_hook
+#define elf_backend_link_output_symbol_hook \
+ elf_vxworks_link_output_symbol_hook
+#undef elf_backend_final_write_processing
+#define elf_backend_final_write_processing \
+ ppc_elf_vxworks_final_write_processing
+#undef elf_backend_get_sec_type_attr
+#define elf_backend_get_sec_type_attr \
+ ppc_elf_vxworks_get_sec_type_attr
+#undef elf_backend_emit_relocs
+#define elf_backend_emit_relocs \
+ elf_vxworks_emit_relocs
+
+#undef elf32_bed
+#define elf32_bed ppc_elf_vxworks_bed
+#undef elf_backend_post_process_headers
+
+#include "elf32-target.h"
diff --git a/bfd/elf32-ppc.h b/bfd/elf32-ppc.h
new file mode 100644
index 0000000..07dc4c8
--- /dev/null
+++ b/bfd/elf32-ppc.h
@@ -0,0 +1,56 @@
+/* PowerPC-specific support for 64-bit ELF.
+ Copyright (C) 2003-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+enum ppc_elf_plt_type
+{
+ PLT_UNSET,
+ PLT_OLD,
+ PLT_NEW,
+ PLT_VXWORKS
+};
+
+/* Various options passed from the linker to bfd backend. */
+struct ppc_elf_params
+{
+ /* Chooses the type of .plt. */
+ enum ppc_elf_plt_type plt_style;
+
+ /* Whether to emit symbols for stubs. */
+ int emit_stub_syms;
+
+ /* Whether to emit special stub for __tls_get_addr calls. */
+ int no_tls_get_addr_opt;
+
+ /* Insert trampolines for branches that won't reach their destination. */
+ int branch_trampolines;
+
+ /* Avoid execution falling into new page. */
+ int ppc476_workaround;
+ unsigned int pagesize_p2;
+};
+
+void ppc_elf_link_params (struct bfd_link_info *, struct ppc_elf_params *);
+int ppc_elf_select_plt_layout (bfd *, struct bfd_link_info *);
+asection *ppc_elf_tls_setup (bfd *, struct bfd_link_info *);
+bfd_boolean ppc_elf_tls_optimize (bfd *, struct bfd_link_info *);
+void ppc_elf_maybe_strip_sdata_syms (struct bfd_link_info *);
+extern bfd_boolean ppc_elf_modify_segment_map (bfd *,
+ struct bfd_link_info * ATTRIBUTE_UNUSED);
+extern bfd_boolean ppc_elf_section_processing (bfd *, Elf_Internal_Shdr *);
diff --git a/bfd/elf32-rl78.c b/bfd/elf32-rl78.c
new file mode 100644
index 0000000..2a5ec99
--- /dev/null
+++ b/bfd/elf32-rl78.c
@@ -0,0 +1,2459 @@
+/* Renesas RL78 specific support for 32-bit ELF.
+ Copyright (C) 2011-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public 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 "bfd.h"
+#include "bfd_stdint.h"
+#include "libbfd.h"
+#include "elf-bfd.h"
+#include "elf/rl78.h"
+#include "libiberty.h"
+
+#define valid_16bit_address(v) ((v) <= 0x0ffff || (v) >= 0xf0000)
+
+#define RL78REL(n,sz,bit,shift,complain,pcrel) \
+ HOWTO (R_RL78_##n, shift, sz, bit, pcrel, 0, complain_overflow_ ## complain, \
+ bfd_elf_generic_reloc, "R_RL78_" #n, FALSE, 0, ~0, FALSE)
+
+/* Note that the relocations around 0x7f are internal to this file;
+ feel free to move them as needed to avoid conflicts with published
+ relocation numbers. */
+
+static reloc_howto_type rl78_elf_howto_table [] =
+{
+ RL78REL (NONE, 0, 0, 0, dont, FALSE),
+ RL78REL (DIR32, 2, 32, 0, signed, FALSE),
+ RL78REL (DIR24S, 2, 24, 0, signed, FALSE),
+ RL78REL (DIR16, 1, 16, 0, dont, FALSE),
+ RL78REL (DIR16U, 1, 16, 0, unsigned, FALSE),
+ RL78REL (DIR16S, 1, 16, 0, signed, FALSE),
+ RL78REL (DIR8, 0, 8, 0, dont, FALSE),
+ RL78REL (DIR8U, 0, 8, 0, unsigned, FALSE),
+ RL78REL (DIR8S, 0, 8, 0, signed, FALSE),
+ RL78REL (DIR24S_PCREL, 2, 24, 0, signed, TRUE),
+ RL78REL (DIR16S_PCREL, 1, 16, 0, signed, TRUE),
+ RL78REL (DIR8S_PCREL, 0, 8, 0, signed, TRUE),
+ RL78REL (DIR16UL, 1, 16, 2, unsigned, FALSE),
+ RL78REL (DIR16UW, 1, 16, 1, unsigned, FALSE),
+ RL78REL (DIR8UL, 0, 8, 2, unsigned, FALSE),
+ RL78REL (DIR8UW, 0, 8, 1, unsigned, FALSE),
+ RL78REL (DIR32_REV, 1, 16, 0, dont, FALSE),
+ RL78REL (DIR16_REV, 1, 16, 0, dont, FALSE),
+ RL78REL (DIR3U_PCREL, 0, 3, 0, dont, TRUE),
+
+ EMPTY_HOWTO (0x13),
+ EMPTY_HOWTO (0x14),
+ EMPTY_HOWTO (0x15),
+ EMPTY_HOWTO (0x16),
+ EMPTY_HOWTO (0x17),
+ EMPTY_HOWTO (0x18),
+ EMPTY_HOWTO (0x19),
+ EMPTY_HOWTO (0x1a),
+ EMPTY_HOWTO (0x1b),
+ EMPTY_HOWTO (0x1c),
+ EMPTY_HOWTO (0x1d),
+ EMPTY_HOWTO (0x1e),
+ EMPTY_HOWTO (0x1f),
+
+ EMPTY_HOWTO (0x20),
+ EMPTY_HOWTO (0x21),
+ EMPTY_HOWTO (0x22),
+ EMPTY_HOWTO (0x23),
+ EMPTY_HOWTO (0x24),
+ EMPTY_HOWTO (0x25),
+ EMPTY_HOWTO (0x26),
+ EMPTY_HOWTO (0x27),
+ EMPTY_HOWTO (0x28),
+ EMPTY_HOWTO (0x29),
+ EMPTY_HOWTO (0x2a),
+ EMPTY_HOWTO (0x2b),
+ EMPTY_HOWTO (0x2c),
+ RL78REL (RH_RELAX, 0, 0, 0, dont, FALSE),
+
+ EMPTY_HOWTO (0x2e),
+ EMPTY_HOWTO (0x2f),
+ EMPTY_HOWTO (0x30),
+ EMPTY_HOWTO (0x31),
+ EMPTY_HOWTO (0x32),
+ EMPTY_HOWTO (0x33),
+ EMPTY_HOWTO (0x34),
+ EMPTY_HOWTO (0x35),
+ EMPTY_HOWTO (0x36),
+ EMPTY_HOWTO (0x37),
+ EMPTY_HOWTO (0x38),
+ EMPTY_HOWTO (0x39),
+ EMPTY_HOWTO (0x3a),
+ EMPTY_HOWTO (0x3b),
+ EMPTY_HOWTO (0x3c),
+ EMPTY_HOWTO (0x3d),
+ EMPTY_HOWTO (0x3e),
+ EMPTY_HOWTO (0x3f),
+ EMPTY_HOWTO (0x40),
+
+ RL78REL (ABS32, 2, 32, 0, dont, FALSE),
+ RL78REL (ABS24S, 2, 24, 0, signed, FALSE),
+ RL78REL (ABS16, 1, 16, 0, dont, FALSE),
+ RL78REL (ABS16U, 1, 16, 0, unsigned, FALSE),
+ RL78REL (ABS16S, 1, 16, 0, signed, FALSE),
+ RL78REL (ABS8, 0, 8, 0, dont, FALSE),
+ RL78REL (ABS8U, 0, 8, 0, unsigned, FALSE),
+ RL78REL (ABS8S, 0, 8, 0, signed, FALSE),
+ RL78REL (ABS24S_PCREL, 2, 24, 0, signed, TRUE),
+ RL78REL (ABS16S_PCREL, 1, 16, 0, signed, TRUE),
+ RL78REL (ABS8S_PCREL, 0, 8, 0, signed, TRUE),
+ RL78REL (ABS16UL, 1, 16, 0, unsigned, FALSE),
+ RL78REL (ABS16UW, 1, 16, 0, unsigned, FALSE),
+ RL78REL (ABS8UL, 0, 8, 0, unsigned, FALSE),
+ RL78REL (ABS8UW, 0, 8, 0, unsigned, FALSE),
+ RL78REL (ABS32_REV, 2, 32, 0, dont, FALSE),
+ RL78REL (ABS16_REV, 1, 16, 0, dont, FALSE),
+
+#define STACK_REL_P(x) ((x) <= R_RL78_ABS16_REV && (x) >= R_RL78_ABS32)
+
+ EMPTY_HOWTO (0x52),
+ EMPTY_HOWTO (0x53),
+ EMPTY_HOWTO (0x54),
+ EMPTY_HOWTO (0x55),
+ EMPTY_HOWTO (0x56),
+ EMPTY_HOWTO (0x57),
+ EMPTY_HOWTO (0x58),
+ EMPTY_HOWTO (0x59),
+ EMPTY_HOWTO (0x5a),
+ EMPTY_HOWTO (0x5b),
+ EMPTY_HOWTO (0x5c),
+ EMPTY_HOWTO (0x5d),
+ EMPTY_HOWTO (0x5e),
+ EMPTY_HOWTO (0x5f),
+ EMPTY_HOWTO (0x60),
+ EMPTY_HOWTO (0x61),
+ EMPTY_HOWTO (0x62),
+ EMPTY_HOWTO (0x63),
+ EMPTY_HOWTO (0x64),
+ EMPTY_HOWTO (0x65),
+ EMPTY_HOWTO (0x66),
+ EMPTY_HOWTO (0x67),
+ EMPTY_HOWTO (0x68),
+ EMPTY_HOWTO (0x69),
+ EMPTY_HOWTO (0x6a),
+ EMPTY_HOWTO (0x6b),
+ EMPTY_HOWTO (0x6c),
+ EMPTY_HOWTO (0x6d),
+ EMPTY_HOWTO (0x6e),
+ EMPTY_HOWTO (0x6f),
+ EMPTY_HOWTO (0x70),
+ EMPTY_HOWTO (0x71),
+ EMPTY_HOWTO (0x72),
+ EMPTY_HOWTO (0x73),
+ EMPTY_HOWTO (0x74),
+ EMPTY_HOWTO (0x75),
+ EMPTY_HOWTO (0x76),
+ EMPTY_HOWTO (0x77),
+
+ EMPTY_HOWTO (0x78),
+ EMPTY_HOWTO (0x79),
+ EMPTY_HOWTO (0x7a),
+ EMPTY_HOWTO (0x7b),
+ EMPTY_HOWTO (0x7c),
+ EMPTY_HOWTO (0x7d),
+ EMPTY_HOWTO (0x7e),
+ EMPTY_HOWTO (0x7f),
+
+ RL78REL (SYM, 2, 32, 0, dont, FALSE),
+ RL78REL (OPneg, 2, 32, 0, dont, FALSE),
+ RL78REL (OPadd, 2, 32, 0, dont, FALSE),
+ RL78REL (OPsub, 2, 32, 0, dont, FALSE),
+ RL78REL (OPmul, 2, 32, 0, dont, FALSE),
+ RL78REL (OPdiv, 2, 32, 0, dont, FALSE),
+ RL78REL (OPshla, 2, 32, 0, dont, FALSE),
+ RL78REL (OPshra, 2, 32, 0, dont, FALSE),
+ RL78REL (OPsctsize, 2, 32, 0, dont, FALSE),
+ EMPTY_HOWTO (0x89),
+ EMPTY_HOWTO (0x8a),
+ EMPTY_HOWTO (0x8b),
+ EMPTY_HOWTO (0x8c),
+ RL78REL (OPscttop, 2, 32, 0, dont, FALSE),
+ EMPTY_HOWTO (0x8e),
+ EMPTY_HOWTO (0x8f),
+ RL78REL (OPand, 2, 32, 0, dont, FALSE),
+ RL78REL (OPor, 2, 32, 0, dont, FALSE),
+ RL78REL (OPxor, 2, 32, 0, dont, FALSE),
+ RL78REL (OPnot, 2, 32, 0, dont, FALSE),
+ RL78REL (OPmod, 2, 32, 0, dont, FALSE),
+ RL78REL (OPromtop, 2, 32, 0, dont, FALSE),
+ RL78REL (OPramtop, 2, 32, 0, dont, FALSE)
+};
+
+/* Map BFD reloc types to RL78 ELF reloc types. */
+
+struct rl78_reloc_map
+{
+ bfd_reloc_code_real_type bfd_reloc_val;
+ unsigned int rl78_reloc_val;
+};
+
+static const struct rl78_reloc_map rl78_reloc_map [] =
+{
+ { BFD_RELOC_NONE, R_RL78_NONE },
+ { BFD_RELOC_8, R_RL78_DIR8S },
+ { BFD_RELOC_16, R_RL78_DIR16S },
+ { BFD_RELOC_24, R_RL78_DIR24S },
+ { BFD_RELOC_32, R_RL78_DIR32 },
+ { BFD_RELOC_RL78_16_OP, R_RL78_DIR16 },
+ { BFD_RELOC_RL78_DIR3U_PCREL, R_RL78_DIR3U_PCREL },
+ { BFD_RELOC_8_PCREL, R_RL78_DIR8S_PCREL },
+ { BFD_RELOC_16_PCREL, R_RL78_DIR16S_PCREL },
+ { BFD_RELOC_24_PCREL, R_RL78_DIR24S_PCREL },
+ { BFD_RELOC_RL78_8U, R_RL78_DIR8U },
+ { BFD_RELOC_RL78_16U, R_RL78_DIR16U },
+ { BFD_RELOC_RL78_SYM, R_RL78_SYM },
+ { BFD_RELOC_RL78_OP_SUBTRACT, R_RL78_OPsub },
+ { BFD_RELOC_RL78_OP_NEG, R_RL78_OPneg },
+ { BFD_RELOC_RL78_OP_AND, R_RL78_OPand },
+ { BFD_RELOC_RL78_OP_SHRA, R_RL78_OPshra },
+ { BFD_RELOC_RL78_ABS8, R_RL78_ABS8 },
+ { BFD_RELOC_RL78_ABS16, R_RL78_ABS16 },
+ { BFD_RELOC_RL78_ABS16_REV, R_RL78_ABS16_REV },
+ { BFD_RELOC_RL78_ABS32, R_RL78_ABS32 },
+ { BFD_RELOC_RL78_ABS32_REV, R_RL78_ABS32_REV },
+ { BFD_RELOC_RL78_ABS16UL, R_RL78_ABS16UL },
+ { BFD_RELOC_RL78_ABS16UW, R_RL78_ABS16UW },
+ { BFD_RELOC_RL78_ABS16U, R_RL78_ABS16U },
+ { BFD_RELOC_RL78_RELAX, R_RL78_RH_RELAX }
+};
+
+static reloc_howto_type *
+rl78_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED,
+ bfd_reloc_code_real_type code)
+{
+ unsigned int i;
+
+ if (code == BFD_RELOC_RL78_32_OP)
+ return rl78_elf_howto_table + R_RL78_DIR32;
+
+ for (i = ARRAY_SIZE (rl78_reloc_map); --i;)
+ if (rl78_reloc_map [i].bfd_reloc_val == code)
+ return rl78_elf_howto_table + rl78_reloc_map[i].rl78_reloc_val;
+
+ return NULL;
+}
+
+static reloc_howto_type *
+rl78_reloc_name_lookup (bfd * abfd ATTRIBUTE_UNUSED, const char * r_name)
+{
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE (rl78_elf_howto_table); i++)
+ if (rl78_elf_howto_table[i].name != NULL
+ && strcasecmp (rl78_elf_howto_table[i].name, r_name) == 0)
+ return rl78_elf_howto_table + i;
+
+ return NULL;
+}
+
+/* Set the howto pointer for an RL78 ELF reloc. */
+
+static void
+rl78_info_to_howto_rela (bfd * abfd ATTRIBUTE_UNUSED,
+ arelent * cache_ptr,
+ Elf_Internal_Rela * dst)
+{
+ unsigned int r_type;
+
+ r_type = ELF32_R_TYPE (dst->r_info);
+ BFD_ASSERT (r_type < (unsigned int) R_RL78_max);
+ cache_ptr->howto = rl78_elf_howto_table + r_type;
+}
+
+static bfd_vma
+get_symbol_value (const char * name,
+ bfd_reloc_status_type * status,
+ struct bfd_link_info * info,
+ bfd * input_bfd,
+ asection * input_section,
+ int offset)
+{
+ bfd_vma value = 0;
+ struct bfd_link_hash_entry * h;
+
+ h = bfd_link_hash_lookup (info->hash, name, FALSE, FALSE, TRUE);
+
+ if (h == NULL
+ || (h->type != bfd_link_hash_defined
+ && h->type != bfd_link_hash_defweak))
+ * status = info->callbacks->undefined_symbol
+ (info, name, input_bfd, input_section, offset, TRUE);
+ else
+ value = (h->u.def.value
+ + h->u.def.section->output_section->vma
+ + h->u.def.section->output_offset);
+
+ return value;
+}
+
+static bfd_vma
+get_romstart (bfd_reloc_status_type * status,
+ struct bfd_link_info * info,
+ bfd * abfd,
+ asection * sec,
+ int offset)
+{
+ static bfd_boolean cached = FALSE;
+ static bfd_vma cached_value = 0;
+
+ if (!cached)
+ {
+ cached_value = get_symbol_value ("_start", status, info, abfd, sec, offset);
+ cached = TRUE;
+ }
+ return cached_value;
+}
+
+static bfd_vma
+get_ramstart (bfd_reloc_status_type * status,
+ struct bfd_link_info * info,
+ bfd * abfd,
+ asection * sec,
+ int offset)
+{
+ static bfd_boolean cached = FALSE;
+ static bfd_vma cached_value = 0;
+
+ if (!cached)
+ {
+ cached_value = get_symbol_value ("__datastart", status, info, abfd, sec, offset);
+ cached = TRUE;
+ }
+ return cached_value;
+}
+
+#define NUM_STACK_ENTRIES 16
+static int32_t rl78_stack [ NUM_STACK_ENTRIES ];
+static unsigned int rl78_stack_top;
+
+#define RL78_STACK_PUSH(val) \
+ do \
+ { \
+ if (rl78_stack_top < NUM_STACK_ENTRIES) \
+ rl78_stack [rl78_stack_top ++] = (val); \
+ else \
+ r = bfd_reloc_dangerous; \
+ } \
+ while (0)
+
+#define RL78_STACK_POP(dest) \
+ do \
+ { \
+ if (rl78_stack_top > 0) \
+ (dest) = rl78_stack [-- rl78_stack_top]; \
+ else \
+ (dest) = 0, r = bfd_reloc_dangerous; \
+ } \
+ while (0)
+
+/* Relocate an RL78 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 relocatable
+ 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 relocatable 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 bfd_boolean
+rl78_elf_relocate_section
+ (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;
+ bfd *dynobj;
+ asection *splt;
+
+ symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
+ sym_hashes = elf_sym_hashes (input_bfd);
+ relend = relocs + input_section->reloc_count;
+
+ dynobj = elf_hash_table (info)->dynobj;
+ splt = NULL;
+ if (dynobj != NULL)
+ splt = bfd_get_linker_section (dynobj, ".plt");
+
+ 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;
+ bfd_boolean unresolved_reloc = TRUE;
+ int r_type;
+
+ r_type = ELF32_R_TYPE (rel->r_info);
+ r_symndx = ELF32_R_SYM (rel->r_info);
+
+ howto = rl78_elf_howto_table + ELF32_R_TYPE (rel->r_info);
+ h = NULL;
+ sym = NULL;
+ sec = NULL;
+ relocation = 0;
+
+ if (r_symndx < symtab_hdr->sh_info)
+ {
+ sym = local_syms + r_symndx;
+ sec = local_sections [r_symndx];
+ relocation = _bfd_elf_rela_local_sym (output_bfd, sym, & sec, rel);
+
+ name = bfd_elf_string_from_elf_section
+ (input_bfd, symtab_hdr->sh_link, sym->st_name);
+ name = (sym->st_name == 0) ? bfd_section_name (input_bfd, sec) : name;
+ }
+ else
+ {
+ bfd_boolean warned ATTRIBUTE_UNUSED;
+ bfd_boolean ignored ATTRIBUTE_UNUSED;
+
+ RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
+ r_symndx, symtab_hdr, sym_hashes, h,
+ sec, relocation, unresolved_reloc,
+ warned, ignored);
+
+ name = h->root.root.string;
+ }
+
+ if (sec != NULL && discarded_section (sec))
+ RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+ rel, 1, relend, howto, 0, contents);
+
+ if (info->relocatable)
+ {
+ /* This is a relocatable 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 (sym != NULL && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
+ rel->r_addend += sec->output_offset;
+ continue;
+ }
+
+ switch (ELF32_R_TYPE (rel->r_info))
+ {
+ case R_RL78_DIR16S:
+ {
+ bfd_vma *plt_offset;
+
+ if (h != NULL)
+ plt_offset = &h->plt.offset;
+ else
+ plt_offset = elf_local_got_offsets (input_bfd) + r_symndx;
+
+ if (! valid_16bit_address (relocation))
+ {
+ /* If this is the first time we've processed this symbol,
+ fill in the plt entry with the correct symbol address. */
+ if ((*plt_offset & 1) == 0)
+ {
+ unsigned int x;
+
+ x = 0x000000ec; /* br !!abs24 */
+ x |= (relocation << 8) & 0xffffff00;
+ bfd_put_32 (input_bfd, x, splt->contents + *plt_offset);
+ *plt_offset |= 1;
+ }
+
+ relocation = (splt->output_section->vma
+ + splt->output_offset
+ + (*plt_offset & -2));
+ if (name)
+ {
+ char *newname = bfd_malloc (strlen(name)+5);
+ strcpy (newname, name);
+ strcat(newname, ".plt");
+ _bfd_generic_link_add_one_symbol (info,
+ input_bfd,
+ newname,
+ BSF_FUNCTION | BSF_WEAK,
+ splt,
+ (*plt_offset & -2),
+ 0,
+ 1,
+ 0,
+ 0);
+ }
+ }
+ }
+ break;
+ }
+
+ if (h != NULL && h->root.type == bfd_link_hash_undefweak)
+ /* If the symbol is undefined and weak
+ then the relocation resolves to zero. */
+ relocation = 0;
+ else
+ {
+ if (howto->pc_relative)
+ {
+ relocation -= (input_section->output_section->vma
+ + input_section->output_offset
+ + rel->r_offset);
+ relocation -= bfd_get_reloc_size (howto);
+ }
+
+ relocation += rel->r_addend;
+ }
+
+ r = bfd_reloc_ok;
+
+#define RANGE(a,b) if (a > (long) relocation || (long) relocation > b) r = bfd_reloc_overflow
+#define ALIGN(m) if (relocation & m) r = bfd_reloc_other;
+#define OP(i) (contents[rel->r_offset + (i)])
+
+ /* Opcode relocs are always big endian. Data relocs are bi-endian. */
+ switch (r_type)
+ {
+ case R_RL78_NONE:
+ break;
+
+ case R_RL78_RH_RELAX:
+ break;
+
+ case R_RL78_DIR8S_PCREL:
+ RANGE (-128, 127);
+ OP (0) = relocation;
+ break;
+
+ case R_RL78_DIR8S:
+ RANGE (-128, 255);
+ OP (0) = relocation;
+ break;
+
+ case R_RL78_DIR8U:
+ RANGE (0, 255);
+ OP (0) = relocation;
+ break;
+
+ case R_RL78_DIR16S_PCREL:
+ RANGE (-32768, 32767);
+ OP (0) = relocation;
+ OP (1) = relocation >> 8;
+ break;
+
+ case R_RL78_DIR16S:
+ if ((relocation & 0xf0000) == 0xf0000)
+ relocation &= 0xffff;
+ RANGE (-32768, 65535);
+ OP (0) = relocation;
+ OP (1) = relocation >> 8;
+ break;
+
+ case R_RL78_DIR16U:
+ RANGE (0, 65536);
+ OP (0) = relocation;
+ OP (1) = relocation >> 8;
+ break;
+
+ case R_RL78_DIR16:
+ RANGE (-32768, 65536);
+ OP (0) = relocation;
+ OP (1) = relocation >> 8;
+ break;
+
+ case R_RL78_DIR16_REV:
+ RANGE (-32768, 65536);
+ OP (1) = relocation;
+ OP (0) = relocation >> 8;
+ break;
+
+ case R_RL78_DIR3U_PCREL:
+ RANGE (3, 10);
+ OP (0) &= 0xf8;
+ OP (0) |= relocation & 0x07;
+ break;
+
+ case R_RL78_DIR24S_PCREL:
+ RANGE (-0x800000, 0x7fffff);
+ OP (0) = relocation;
+ OP (1) = relocation >> 8;
+ OP (2) = relocation >> 16;
+ break;
+
+ case R_RL78_DIR24S:
+ RANGE (-0x800000, 0x7fffff);
+ OP (0) = relocation;
+ OP (1) = relocation >> 8;
+ OP (2) = relocation >> 16;
+ break;
+
+ case R_RL78_DIR32:
+ OP (0) = relocation;
+ OP (1) = relocation >> 8;
+ OP (2) = relocation >> 16;
+ OP (3) = relocation >> 24;
+ break;
+
+ case R_RL78_DIR32_REV:
+ OP (3) = relocation;
+ OP (2) = relocation >> 8;
+ OP (1) = relocation >> 16;
+ OP (0) = relocation >> 24;
+ break;
+
+ case R_RL78_RH_SFR:
+ RANGE (0xfff00, 0xfffff);
+ OP (0) = relocation & 0xff;
+ break;
+
+ case R_RL78_RH_SADDR:
+ RANGE (0xffe20, 0xfff1f);
+ OP (0) = relocation & 0xff;
+ break;
+
+ /* Complex reloc handling: */
+
+ case R_RL78_ABS32:
+ RL78_STACK_POP (relocation);
+ OP (0) = relocation;
+ OP (1) = relocation >> 8;
+ OP (2) = relocation >> 16;
+ OP (3) = relocation >> 24;
+ break;
+
+ case R_RL78_ABS32_REV:
+ RL78_STACK_POP (relocation);
+ OP (3) = relocation;
+ OP (2) = relocation >> 8;
+ OP (1) = relocation >> 16;
+ OP (0) = relocation >> 24;
+ break;
+
+ case R_RL78_ABS24S_PCREL:
+ case R_RL78_ABS24S:
+ RL78_STACK_POP (relocation);
+ RANGE (-0x800000, 0x7fffff);
+ OP (0) = relocation;
+ OP (1) = relocation >> 8;
+ OP (2) = relocation >> 16;
+ break;
+
+ case R_RL78_ABS16:
+ RL78_STACK_POP (relocation);
+ RANGE (-32768, 65535);
+ OP (0) = relocation;
+ OP (1) = relocation >> 8;
+ break;
+
+ case R_RL78_ABS16_REV:
+ RL78_STACK_POP (relocation);
+ RANGE (-32768, 65535);
+ OP (1) = relocation;
+ OP (0) = relocation >> 8;
+ break;
+
+ case R_RL78_ABS16S_PCREL:
+ case R_RL78_ABS16S:
+ RL78_STACK_POP (relocation);
+ RANGE (-32768, 32767);
+ OP (0) = relocation;
+ OP (1) = relocation >> 8;
+ break;
+
+ case R_RL78_ABS16U:
+ RL78_STACK_POP (relocation);
+ RANGE (0, 65536);
+ OP (0) = relocation;
+ OP (1) = relocation >> 8;
+ break;
+
+ case R_RL78_ABS16UL:
+ RL78_STACK_POP (relocation);
+ relocation >>= 2;
+ RANGE (0, 65536);
+ OP (0) = relocation;
+ OP (1) = relocation >> 8;
+ break;
+
+ case R_RL78_ABS16UW:
+ RL78_STACK_POP (relocation);
+ relocation >>= 1;
+ RANGE (0, 65536);
+ OP (0) = relocation;
+ OP (1) = relocation >> 8;
+ break;
+
+ case R_RL78_ABS8:
+ RL78_STACK_POP (relocation);
+ RANGE (-128, 255);
+ OP (0) = relocation;
+ break;
+
+ case R_RL78_ABS8U:
+ RL78_STACK_POP (relocation);
+ RANGE (0, 255);
+ OP (0) = relocation;
+ break;
+
+ case R_RL78_ABS8UL:
+ RL78_STACK_POP (relocation);
+ relocation >>= 2;
+ RANGE (0, 255);
+ OP (0) = relocation;
+ break;
+
+ case R_RL78_ABS8UW:
+ RL78_STACK_POP (relocation);
+ relocation >>= 1;
+ RANGE (0, 255);
+ OP (0) = relocation;
+ break;
+
+ case R_RL78_ABS8S_PCREL:
+ case R_RL78_ABS8S:
+ RL78_STACK_POP (relocation);
+ RANGE (-128, 127);
+ OP (0) = relocation;
+ break;
+
+ case R_RL78_SYM:
+ if (r_symndx < symtab_hdr->sh_info)
+ RL78_STACK_PUSH (sec->output_section->vma
+ + sec->output_offset
+ + sym->st_value
+ + rel->r_addend);
+ else
+ {
+ if (h != NULL
+ && (h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak))
+ RL78_STACK_PUSH (h->root.u.def.value
+ + sec->output_section->vma
+ + sec->output_offset
+ + rel->r_addend);
+ else if (h->root.type == bfd_link_hash_undefweak)
+ RL78_STACK_PUSH (0);
+ else
+ _bfd_error_handler (_("Warning: RL78_SYM reloc with an unknown symbol"));
+ }
+ break;
+
+ case R_RL78_OPneg:
+ {
+ int32_t tmp;
+
+ RL78_STACK_POP (tmp);
+ tmp = - tmp;
+ RL78_STACK_PUSH (tmp);
+ }
+ break;
+
+ case R_RL78_OPadd:
+ {
+ int32_t tmp1, tmp2;
+
+ RL78_STACK_POP (tmp2);
+ RL78_STACK_POP (tmp1);
+ tmp1 += tmp2;
+ RL78_STACK_PUSH (tmp1);
+ }
+ break;
+
+ case R_RL78_OPsub:
+ {
+ int32_t tmp1, tmp2;
+
+ /* For the expression "A - B", the assembler pushes A,
+ then B, then OPSUB. So the first op we pop is B, not
+ A. */
+ RL78_STACK_POP (tmp2); /* B */
+ RL78_STACK_POP (tmp1); /* A */
+ tmp1 -= tmp2; /* A - B */
+ RL78_STACK_PUSH (tmp1);
+ }
+ break;
+
+ case R_RL78_OPmul:
+ {
+ int32_t tmp1, tmp2;
+
+ RL78_STACK_POP (tmp2);
+ RL78_STACK_POP (tmp1);
+ tmp1 *= tmp2;
+ RL78_STACK_PUSH (tmp1);
+ }
+ break;
+
+ case R_RL78_OPdiv:
+ {
+ int32_t tmp1, tmp2;
+
+ RL78_STACK_POP (tmp2);
+ RL78_STACK_POP (tmp1);
+ tmp1 /= tmp2;
+ RL78_STACK_PUSH (tmp1);
+ }
+ break;
+
+ case R_RL78_OPshla:
+ {
+ int32_t tmp1, tmp2;
+
+ RL78_STACK_POP (tmp2);
+ RL78_STACK_POP (tmp1);
+ tmp1 <<= tmp2;
+ RL78_STACK_PUSH (tmp1);
+ }
+ break;
+
+ case R_RL78_OPshra:
+ {
+ int32_t tmp1, tmp2;
+
+ RL78_STACK_POP (tmp2);
+ RL78_STACK_POP (tmp1);
+ tmp1 >>= tmp2;
+ RL78_STACK_PUSH (tmp1);
+ }
+ break;
+
+ case R_RL78_OPsctsize:
+ RL78_STACK_PUSH (input_section->size);
+ break;
+
+ case R_RL78_OPscttop:
+ RL78_STACK_PUSH (input_section->output_section->vma);
+ break;
+
+ case R_RL78_OPand:
+ {
+ int32_t tmp1, tmp2;
+
+ RL78_STACK_POP (tmp2);
+ RL78_STACK_POP (tmp1);
+ tmp1 &= tmp2;
+ RL78_STACK_PUSH (tmp1);
+ }
+ break;
+
+ case R_RL78_OPor:
+ {
+ int32_t tmp1, tmp2;
+
+ RL78_STACK_POP (tmp2);
+ RL78_STACK_POP (tmp1);
+ tmp1 |= tmp2;
+ RL78_STACK_PUSH (tmp1);
+ }
+ break;
+
+ case R_RL78_OPxor:
+ {
+ int32_t tmp1, tmp2;
+
+ RL78_STACK_POP (tmp2);
+ RL78_STACK_POP (tmp1);
+ tmp1 ^= tmp2;
+ RL78_STACK_PUSH (tmp1);
+ }
+ break;
+
+ case R_RL78_OPnot:
+ {
+ int32_t tmp;
+
+ RL78_STACK_POP (tmp);
+ tmp = ~ tmp;
+ RL78_STACK_PUSH (tmp);
+ }
+ break;
+
+ case R_RL78_OPmod:
+ {
+ int32_t tmp1, tmp2;
+
+ RL78_STACK_POP (tmp2);
+ RL78_STACK_POP (tmp1);
+ tmp1 %= tmp2;
+ RL78_STACK_PUSH (tmp1);
+ }
+ break;
+
+ case R_RL78_OPromtop:
+ RL78_STACK_PUSH (get_romstart (&r, info, input_bfd, input_section, rel->r_offset));
+ break;
+
+ case R_RL78_OPramtop:
+ RL78_STACK_PUSH (get_ramstart (&r, info, input_bfd, input_section, rel->r_offset));
+ break;
+
+ default:
+ r = bfd_reloc_notsupported;
+ break;
+ }
+
+ if (r != bfd_reloc_ok)
+ {
+ const char * msg = NULL;
+
+ switch (r)
+ {
+ case bfd_reloc_overflow:
+ /* Catch the case of a missing function declaration
+ and emit a more helpful error message. */
+ if (r_type == R_RL78_DIR24S_PCREL)
+ msg = _("%B(%A): error: call to undefined function '%s'");
+ else
+ r = info->callbacks->reloc_overflow
+ (info, (h ? &h->root : NULL), 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,
+ TRUE);
+ break;
+
+ case bfd_reloc_other:
+ msg = _("%B(%A): warning: unaligned access to symbol '%s' in the small data area");
+ break;
+
+ case bfd_reloc_outofrange:
+ msg = _("%B(%A): internal error: out of range error");
+ break;
+
+ case bfd_reloc_notsupported:
+ msg = _("%B(%A): internal error: unsupported relocation error");
+ break;
+
+ case bfd_reloc_dangerous:
+ msg = _("%B(%A): internal error: dangerous relocation");
+ break;
+
+ default:
+ msg = _("%B(%A): internal error: unknown error");
+ break;
+ }
+
+ if (msg)
+ _bfd_error_handler (msg, input_bfd, input_section, name);
+
+ if (! r)
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+/* Function to set the ELF flag bits. */
+
+static bfd_boolean
+rl78_elf_set_private_flags (bfd * abfd, flagword flags)
+{
+ elf_elfheader (abfd)->e_flags = flags;
+ elf_flags_init (abfd) = TRUE;
+ return TRUE;
+}
+
+static bfd_boolean no_warn_mismatch = FALSE;
+
+void bfd_elf32_rl78_set_target_flags (bfd_boolean);
+
+void
+bfd_elf32_rl78_set_target_flags (bfd_boolean user_no_warn_mismatch)
+{
+ no_warn_mismatch = user_no_warn_mismatch;
+}
+
+/* Merge backend specific data from an object file to the output
+ object file when linking. */
+
+static bfd_boolean
+rl78_elf_merge_private_bfd_data (bfd * ibfd, bfd * obfd)
+{
+ flagword new_flags;
+ flagword old_flags;
+ bfd_boolean error = FALSE;
+
+ 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 (old_flags != new_flags)
+ {
+ flagword changed_flags = old_flags ^ new_flags;
+
+ if (changed_flags & E_FLAG_RL78_G10)
+ {
+ (*_bfd_error_handler)
+ (_("RL78/G10 ABI conflict: cannot link G10 and non-G10 objects together"));
+
+ if (old_flags & E_FLAG_RL78_G10)
+ (*_bfd_error_handler) (_("- %s is G10, %s is not"),
+ bfd_get_filename (obfd), bfd_get_filename (ibfd));
+ else
+ (*_bfd_error_handler) (_("- %s is G10, %s is not"),
+ bfd_get_filename (ibfd), bfd_get_filename (obfd));
+ }
+
+ if (changed_flags & E_FLAG_RL78_64BIT_DOUBLES)
+ {
+ (*_bfd_error_handler)
+ (_("RL78 merge conflict: cannot link 32-bit and 64-bit objects together"));
+
+ if (old_flags & E_FLAG_RL78_64BIT_DOUBLES)
+ (*_bfd_error_handler) (_("- %s is 64-bit, %s is not"),
+ bfd_get_filename (obfd), bfd_get_filename (ibfd));
+ else
+ (*_bfd_error_handler) (_("- %s is 64-bit, %s is not"),
+ bfd_get_filename (ibfd), bfd_get_filename (obfd));
+ }
+ }
+
+ return !error;
+}
+
+static bfd_boolean
+rl78_elf_print_private_bfd_data (bfd * abfd, void * ptr)
+{
+ FILE * file = (FILE *) ptr;
+ flagword flags;
+
+ BFD_ASSERT (abfd != NULL && ptr != NULL);
+
+ /* Print normal ELF private data. */
+ _bfd_elf_print_private_bfd_data (abfd, ptr);
+
+ flags = elf_elfheader (abfd)->e_flags;
+ fprintf (file, _("private flags = 0x%lx:"), (long) flags);
+
+ if (flags & E_FLAG_RL78_G10)
+ fprintf (file, _(" [G10]"));
+
+ if (flags & E_FLAG_RL78_64BIT_DOUBLES)
+ fprintf (file, _(" [64-bit doubles]"));
+
+ fputc ('\n', file);
+ return TRUE;
+}
+
+/* Return the MACH for an e_flags value. */
+
+static int
+elf32_rl78_machine (bfd * abfd)
+{
+ if ((elf_elfheader (abfd)->e_flags & EF_RL78_CPU_MASK) == EF_RL78_CPU_RL78)
+ return bfd_mach_rl78;
+
+ return 0;
+}
+
+static bfd_boolean
+rl78_elf_object_p (bfd * abfd)
+{
+ bfd_default_set_arch_mach (abfd, bfd_arch_rl78,
+ elf32_rl78_machine (abfd));
+ return TRUE;
+}
+
+/* support PLT for 16-bit references to 24-bit functions. */
+
+/* We support 16-bit pointers to code above 64k by generating a thunk
+ below 64k containing a JMP instruction to the final address. */
+
+static bfd_boolean
+rl78_elf_check_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;
+ const Elf_Internal_Rela * rel;
+ const Elf_Internal_Rela * rel_end;
+ bfd_vma *local_plt_offsets;
+ asection *splt;
+ bfd *dynobj;
+
+ if (info->relocatable)
+ return TRUE;
+
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+ sym_hashes = elf_sym_hashes (abfd);
+ local_plt_offsets = elf_local_got_offsets (abfd);
+ splt = NULL;
+ dynobj = elf_hash_table(info)->dynobj;
+
+ rel_end = relocs + sec->reloc_count;
+ for (rel = relocs; rel < rel_end; rel++)
+ {
+ struct elf_link_hash_entry *h;
+ unsigned long r_symndx;
+ bfd_vma *offset;
+
+ 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];
+ 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;
+
+ /* PR15323, ref flags aren't set for references in the same
+ object. */
+ h->root.non_ir_ref = 1;
+ }
+
+ switch (ELF32_R_TYPE (rel->r_info))
+ {
+ /* This relocation describes a 16-bit pointer to a function.
+ We may need to allocate a thunk in low memory; reserve memory
+ for it now. */
+ case R_RL78_DIR16S:
+ if (dynobj == NULL)
+ elf_hash_table (info)->dynobj = dynobj = abfd;
+ if (splt == NULL)
+ {
+ splt = bfd_get_linker_section (dynobj, ".plt");
+ if (splt == NULL)
+ {
+ flagword flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS
+ | SEC_IN_MEMORY | SEC_LINKER_CREATED
+ | SEC_READONLY | SEC_CODE);
+ splt = bfd_make_section_anyway_with_flags (dynobj, ".plt",
+ flags);
+ if (splt == NULL
+ || ! bfd_set_section_alignment (dynobj, splt, 1))
+ return FALSE;
+ }
+ }
+
+ if (h != NULL)
+ offset = &h->plt.offset;
+ else
+ {
+ if (local_plt_offsets == NULL)
+ {
+ size_t size;
+ unsigned int i;
+
+ size = symtab_hdr->sh_info * sizeof (bfd_vma);
+ local_plt_offsets = (bfd_vma *) bfd_alloc (abfd, size);
+ if (local_plt_offsets == NULL)
+ return FALSE;
+ elf_local_got_offsets (abfd) = local_plt_offsets;
+
+ for (i = 0; i < symtab_hdr->sh_info; i++)
+ local_plt_offsets[i] = (bfd_vma) -1;
+ }
+ offset = &local_plt_offsets[r_symndx];
+ }
+
+ if (*offset == (bfd_vma) -1)
+ {
+ *offset = splt->size;
+ splt->size += 4;
+ }
+ break;
+ }
+ }
+
+ return TRUE;
+}
+
+/* This must exist if dynobj is ever set. */
+
+static bfd_boolean
+rl78_elf_finish_dynamic_sections (bfd *abfd ATTRIBUTE_UNUSED,
+ struct bfd_link_info *info)
+{
+ bfd *dynobj;
+ asection *splt;
+
+ if (!elf_hash_table (info)->dynamic_sections_created)
+ return TRUE;
+
+ /* As an extra sanity check, verify that all plt entries have been
+ filled in. However, relaxing might have changed the relocs so
+ that some plt entries don't get filled in, so we have to skip
+ this check if we're relaxing. Unfortunately, check_relocs is
+ called before relaxation. */
+
+ if (info->relax_trip > 0)
+ return TRUE;
+
+ if ((dynobj = elf_hash_table (info)->dynobj) != NULL
+ && (splt = bfd_get_linker_section (dynobj, ".plt")) != NULL)
+ {
+ bfd_byte *contents = splt->contents;
+ unsigned int i, size = splt->size;
+
+ for (i = 0; i < size; i += 4)
+ {
+ unsigned int x = bfd_get_32 (dynobj, contents + i);
+ BFD_ASSERT (x != 0);
+ }
+ }
+
+ return TRUE;
+}
+
+static bfd_boolean
+rl78_elf_always_size_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
+ struct bfd_link_info *info)
+{
+ bfd *dynobj;
+ asection *splt;
+
+ if (info->relocatable)
+ return TRUE;
+
+ dynobj = elf_hash_table (info)->dynobj;
+ if (dynobj == NULL)
+ return TRUE;
+
+ splt = bfd_get_linker_section (dynobj, ".plt");
+ BFD_ASSERT (splt != NULL);
+
+ splt->contents = (bfd_byte *) bfd_zalloc (dynobj, splt->size);
+ if (splt->contents == NULL)
+ return FALSE;
+
+ return TRUE;
+}
+
+
+
+/* Handle relaxing. */
+
+/* A subroutine of rl78_elf_relax_section. If the global symbol H
+ is within the low 64k, remove any entry for it in the plt. */
+
+struct relax_plt_data
+{
+ asection *splt;
+ bfd_boolean *again;
+};
+
+static bfd_boolean
+rl78_relax_plt_check (struct elf_link_hash_entry *h, void * xdata)
+{
+ struct relax_plt_data *data = (struct relax_plt_data *) xdata;
+
+ if (h->plt.offset != (bfd_vma) -1)
+ {
+ bfd_vma address;
+
+ if (h->root.type == bfd_link_hash_undefined
+ || h->root.type == bfd_link_hash_undefweak)
+ address = 0;
+ else
+ address = (h->root.u.def.section->output_section->vma
+ + h->root.u.def.section->output_offset
+ + h->root.u.def.value);
+
+ if (valid_16bit_address (address))
+ {
+ h->plt.offset = -1;
+ data->splt->size -= 4;
+ *data->again = TRUE;
+ }
+ }
+
+ return TRUE;
+}
+
+/* A subroutine of rl78_elf_relax_section. If the global symbol H
+ previously had a plt entry, give it a new entry offset. */
+
+static bfd_boolean
+rl78_relax_plt_realloc (struct elf_link_hash_entry *h, void * xdata)
+{
+ bfd_vma *entry = (bfd_vma *) xdata;
+
+ if (h->plt.offset != (bfd_vma) -1)
+ {
+ h->plt.offset = *entry;
+ *entry += 4;
+ }
+
+ return TRUE;
+}
+
+static bfd_boolean
+rl78_elf_relax_plt_section (bfd *dynobj,
+ asection *splt,
+ struct bfd_link_info *info,
+ bfd_boolean *again)
+{
+ struct relax_plt_data relax_plt_data;
+ bfd *ibfd;
+
+ /* Assume nothing changes. */
+ *again = FALSE;
+
+ if (info->relocatable)
+ return TRUE;
+
+ /* We only relax the .plt section at the moment. */
+ if (dynobj != elf_hash_table (info)->dynobj
+ || strcmp (splt->name, ".plt") != 0)
+ return TRUE;
+
+ /* Quick check for an empty plt. */
+ if (splt->size == 0)
+ return TRUE;
+
+ /* Map across all global symbols; see which ones happen to
+ fall in the low 64k. */
+ relax_plt_data.splt = splt;
+ relax_plt_data.again = again;
+ elf_link_hash_traverse (elf_hash_table (info), rl78_relax_plt_check,
+ &relax_plt_data);
+
+ /* Likewise for local symbols, though that's somewhat less convenient
+ as we have to walk the list of input bfds and swap in symbol data. */
+ for (ibfd = info->input_bfds; ibfd ; ibfd = ibfd->link.next)
+ {
+ bfd_vma *local_plt_offsets = elf_local_got_offsets (ibfd);
+ Elf_Internal_Shdr *symtab_hdr;
+ Elf_Internal_Sym *isymbuf = NULL;
+ unsigned int idx;
+
+ if (! local_plt_offsets)
+ continue;
+
+ symtab_hdr = &elf_tdata (ibfd)->symtab_hdr;
+ if (symtab_hdr->sh_info != 0)
+ {
+ isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
+ if (isymbuf == NULL)
+ isymbuf = bfd_elf_get_elf_syms (ibfd, symtab_hdr,
+ symtab_hdr->sh_info, 0,
+ NULL, NULL, NULL);
+ if (isymbuf == NULL)
+ return FALSE;
+ }
+
+ for (idx = 0; idx < symtab_hdr->sh_info; ++idx)
+ {
+ Elf_Internal_Sym *isym;
+ asection *tsec;
+ bfd_vma address;
+
+ if (local_plt_offsets[idx] == (bfd_vma) -1)
+ continue;
+
+ isym = &isymbuf[idx];
+ if (isym->st_shndx == SHN_UNDEF)
+ continue;
+ else if (isym->st_shndx == SHN_ABS)
+ tsec = bfd_abs_section_ptr;
+ else if (isym->st_shndx == SHN_COMMON)
+ tsec = bfd_com_section_ptr;
+ else
+ tsec = bfd_section_from_elf_index (ibfd, isym->st_shndx);
+
+ address = (tsec->output_section->vma
+ + tsec->output_offset
+ + isym->st_value);
+ if (valid_16bit_address (address))
+ {
+ local_plt_offsets[idx] = -1;
+ splt->size -= 4;
+ *again = TRUE;
+ }
+ }
+
+ if (isymbuf != NULL
+ && symtab_hdr->contents != (unsigned char *) isymbuf)
+ {
+ if (! info->keep_memory)
+ free (isymbuf);
+ else
+ {
+ /* Cache the symbols for elf_link_input_bfd. */
+ symtab_hdr->contents = (unsigned char *) isymbuf;
+ }
+ }
+ }
+
+ /* If we changed anything, walk the symbols again to reallocate
+ .plt entry addresses. */
+ if (*again && splt->size > 0)
+ {
+ bfd_vma entry = 0;
+
+ elf_link_hash_traverse (elf_hash_table (info),
+ rl78_relax_plt_realloc, &entry);
+
+ for (ibfd = info->input_bfds; ibfd ; ibfd = ibfd->link.next)
+ {
+ bfd_vma *local_plt_offsets = elf_local_got_offsets (ibfd);
+ unsigned int nlocals = elf_tdata (ibfd)->symtab_hdr.sh_info;
+ unsigned int idx;
+
+ if (! local_plt_offsets)
+ continue;
+
+ for (idx = 0; idx < nlocals; ++idx)
+ if (local_plt_offsets[idx] != (bfd_vma) -1)
+ {
+ local_plt_offsets[idx] = entry;
+ entry += 4;
+ }
+ }
+ }
+
+ return TRUE;
+}
+
+/* Delete some bytes from a section while relaxing. */
+
+static bfd_boolean
+elf32_rl78_relax_delete_bytes (bfd *abfd, asection *sec, bfd_vma addr, int count,
+ Elf_Internal_Rela *alignment_rel, int force_snip)
+{
+ Elf_Internal_Shdr * symtab_hdr;
+ unsigned int sec_shndx;
+ bfd_byte * contents;
+ Elf_Internal_Rela * irel;
+ Elf_Internal_Rela * irelend;
+ Elf_Internal_Sym * isym;
+ Elf_Internal_Sym * isymend;
+ bfd_vma toaddr;
+ unsigned int symcount;
+ struct elf_link_hash_entry ** sym_hashes;
+ struct elf_link_hash_entry ** end_hashes;
+
+ if (!alignment_rel)
+ force_snip = 1;
+
+ sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
+
+ contents = elf_section_data (sec)->this_hdr.contents;
+
+ /* The deletion must stop at the next alignment boundary, if
+ ALIGNMENT_REL is non-NULL. */
+ toaddr = sec->size;
+ if (alignment_rel)
+ toaddr = alignment_rel->r_offset;
+
+ irel = elf_section_data (sec)->relocs;
+ if (irel == NULL)
+ {
+ _bfd_elf_link_read_relocs (sec->owner, sec, NULL, NULL, TRUE);
+ irel = elf_section_data (sec)->relocs;
+ }
+
+ irelend = irel + sec->reloc_count;
+
+ /* Actually delete the bytes. */
+ memmove (contents + addr, contents + addr + count,
+ (size_t) (toaddr - addr - count));
+
+ /* If we don't have an alignment marker to worry about, we can just
+ shrink the section. Otherwise, we have to fill in the newly
+ created gap with NOP insns (0x03). */
+ if (force_snip)
+ sec->size -= count;
+ else
+ memset (contents + toaddr - count, 0x03, count);
+
+ /* Adjust all the relocs. */
+ for (; irel && irel < irelend; irel++)
+ {
+ /* Get the new reloc address. */
+ if (irel->r_offset > addr
+ && (irel->r_offset < toaddr
+ || (force_snip && irel->r_offset == toaddr)))
+ irel->r_offset -= count;
+
+ /* If we see an ALIGN marker at the end of the gap, we move it
+ to the beginning of the gap, since marking these gaps is what
+ they're for. */
+ if (irel->r_offset == toaddr
+ && ELF32_R_TYPE (irel->r_info) == R_RL78_RH_RELAX
+ && irel->r_addend & RL78_RELAXA_ALIGN)
+ irel->r_offset -= count;
+ }
+
+ /* Adjust the local symbols defined in this section. */
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+ isym = (Elf_Internal_Sym *) symtab_hdr->contents;
+ isymend = isym + symtab_hdr->sh_info;
+
+ for (; isym < isymend; isym++)
+ {
+ /* If the symbol is in the range of memory we just moved, we
+ have to adjust its value. */
+ if (isym->st_shndx == sec_shndx
+ && isym->st_value > addr
+ && isym->st_value < toaddr)
+ isym->st_value -= count;
+
+ /* If the symbol *spans* the bytes we just deleted (i.e. it's
+ *end* is in the moved bytes but it's *start* isn't), then we
+ must adjust its size. */
+ if (isym->st_shndx == sec_shndx
+ && isym->st_value < addr
+ && isym->st_value + isym->st_size > addr
+ && isym->st_value + isym->st_size < toaddr)
+ isym->st_size -= count;
+ }
+
+ /* Now adjust the global symbols defined in this section. */
+ symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
+ - symtab_hdr->sh_info);
+ sym_hashes = elf_sym_hashes (abfd);
+ end_hashes = sym_hashes + symcount;
+
+ for (; sym_hashes < end_hashes; sym_hashes++)
+ {
+ struct elf_link_hash_entry *sym_hash = *sym_hashes;
+
+ if ((sym_hash->root.type == bfd_link_hash_defined
+ || sym_hash->root.type == bfd_link_hash_defweak)
+ && sym_hash->root.u.def.section == sec)
+ {
+ /* As above, adjust the value if needed. */
+ if (sym_hash->root.u.def.value > addr
+ && sym_hash->root.u.def.value < toaddr)
+ sym_hash->root.u.def.value -= count;
+
+ /* As above, adjust the size if needed. */
+ if (sym_hash->root.u.def.value < addr
+ && sym_hash->root.u.def.value + sym_hash->size > addr
+ && sym_hash->root.u.def.value + sym_hash->size < toaddr)
+ sym_hash->size -= count;
+ }
+ }
+
+ return TRUE;
+}
+
+/* Used to sort relocs by address. If relocs have the same address,
+ we maintain their relative order, except that R_RL78_RH_RELAX
+ alignment relocs must be the first reloc for any given address. */
+
+static void
+reloc_bubblesort (Elf_Internal_Rela * r, int count)
+{
+ int i;
+ bfd_boolean again;
+ bfd_boolean swappit;
+
+ /* This is almost a classic bubblesort. It's the slowest sort, but
+ we're taking advantage of the fact that the relocations are
+ mostly in order already (the assembler emits them that way) and
+ we need relocs with the same address to remain in the same
+ relative order. */
+ again = TRUE;
+ while (again)
+ {
+ again = FALSE;
+ for (i = 0; i < count - 1; i ++)
+ {
+ if (r[i].r_offset > r[i + 1].r_offset)
+ swappit = TRUE;
+ else if (r[i].r_offset < r[i + 1].r_offset)
+ swappit = FALSE;
+ else if (ELF32_R_TYPE (r[i + 1].r_info) == R_RL78_RH_RELAX
+ && (r[i + 1].r_addend & RL78_RELAXA_ALIGN))
+ swappit = TRUE;
+ else if (ELF32_R_TYPE (r[i + 1].r_info) == R_RL78_RH_RELAX
+ && (r[i + 1].r_addend & RL78_RELAXA_ELIGN)
+ && !(ELF32_R_TYPE (r[i].r_info) == R_RL78_RH_RELAX
+ && (r[i].r_addend & RL78_RELAXA_ALIGN)))
+ swappit = TRUE;
+ else
+ swappit = FALSE;
+
+ if (swappit)
+ {
+ Elf_Internal_Rela tmp;
+
+ tmp = r[i];
+ r[i] = r[i + 1];
+ r[i + 1] = tmp;
+ /* If we do move a reloc back, re-scan to see if it
+ needs to be moved even further back. This avoids
+ most of the O(n^2) behavior for our cases. */
+ if (i > 0)
+ i -= 2;
+ again = TRUE;
+ }
+ }
+ }
+}
+
+
+#define OFFSET_FOR_RELOC(rel, lrel, scale) \
+ rl78_offset_for_reloc (abfd, rel + 1, symtab_hdr, shndx_buf, intsyms, \
+ lrel, abfd, sec, link_info, scale)
+
+static bfd_vma
+rl78_offset_for_reloc (bfd * abfd,
+ Elf_Internal_Rela * rel,
+ Elf_Internal_Shdr * symtab_hdr,
+ Elf_External_Sym_Shndx * shndx_buf ATTRIBUTE_UNUSED,
+ Elf_Internal_Sym * intsyms,
+ Elf_Internal_Rela ** lrel,
+ bfd * input_bfd,
+ asection * input_section,
+ struct bfd_link_info * info,
+ int * scale)
+{
+ bfd_vma symval;
+ bfd_reloc_status_type r;
+
+ *scale = 1;
+
+ /* REL is the first of 1..N relocations. We compute the symbol
+ value for each relocation, then combine them if needed. LREL
+ gets a pointer to the last relocation used. */
+ while (1)
+ {
+ int32_t tmp1, tmp2;
+
+ /* Get the value of the symbol referred to by the reloc. */
+ if (ELF32_R_SYM (rel->r_info) < symtab_hdr->sh_info)
+ {
+ /* A local symbol. */
+ Elf_Internal_Sym *isym;
+ asection *ssec;
+
+ isym = intsyms + ELF32_R_SYM (rel->r_info);
+
+ if (isym->st_shndx == SHN_UNDEF)
+ ssec = bfd_und_section_ptr;
+ else if (isym->st_shndx == SHN_ABS)
+ ssec = bfd_abs_section_ptr;
+ else if (isym->st_shndx == SHN_COMMON)
+ ssec = bfd_com_section_ptr;
+ else
+ ssec = bfd_section_from_elf_index (abfd,
+ isym->st_shndx);
+
+ /* Initial symbol value. */
+ symval = isym->st_value;
+
+ /* GAS may have made this symbol relative to a section, in
+ which case, we have to add the addend to find the
+ symbol. */
+ if (ELF_ST_TYPE (isym->st_info) == STT_SECTION)
+ symval += rel->r_addend;
+
+ if (ssec)
+ {
+ if ((ssec->flags & SEC_MERGE)
+ && ssec->sec_info_type == SEC_INFO_TYPE_MERGE)
+ symval = _bfd_merged_section_offset (abfd, & ssec,
+ elf_section_data (ssec)->sec_info,
+ symval);
+ }
+
+ /* Now make the offset relative to where the linker is putting it. */
+ if (ssec)
+ symval +=
+ ssec->output_section->vma + ssec->output_offset;
+
+ symval += rel->r_addend;
+ }
+ else
+ {
+ unsigned long indx;
+ struct elf_link_hash_entry * h;
+
+ /* An external symbol. */
+ indx = ELF32_R_SYM (rel->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. */
+ if (lrel)
+ *lrel = rel;
+ return 0;
+ }
+
+ symval = (h->root.u.def.value
+ + h->root.u.def.section->output_section->vma
+ + h->root.u.def.section->output_offset);
+
+ symval += rel->r_addend;
+ }
+
+ switch (ELF32_R_TYPE (rel->r_info))
+ {
+ case R_RL78_SYM:
+ RL78_STACK_PUSH (symval);
+ break;
+
+ case R_RL78_OPneg:
+ RL78_STACK_POP (tmp1);
+ tmp1 = - tmp1;
+ RL78_STACK_PUSH (tmp1);
+ break;
+
+ case R_RL78_OPadd:
+ RL78_STACK_POP (tmp1);
+ RL78_STACK_POP (tmp2);
+ tmp1 += tmp2;
+ RL78_STACK_PUSH (tmp1);
+ break;
+
+ case R_RL78_OPsub:
+ RL78_STACK_POP (tmp1);
+ RL78_STACK_POP (tmp2);
+ tmp2 -= tmp1;
+ RL78_STACK_PUSH (tmp2);
+ break;
+
+ case R_RL78_OPmul:
+ RL78_STACK_POP (tmp1);
+ RL78_STACK_POP (tmp2);
+ tmp1 *= tmp2;
+ RL78_STACK_PUSH (tmp1);
+ break;
+
+ case R_RL78_OPdiv:
+ RL78_STACK_POP (tmp1);
+ RL78_STACK_POP (tmp2);
+ tmp1 /= tmp2;
+ RL78_STACK_PUSH (tmp1);
+ break;
+
+ case R_RL78_OPshla:
+ RL78_STACK_POP (tmp1);
+ RL78_STACK_POP (tmp2);
+ tmp1 <<= tmp2;
+ RL78_STACK_PUSH (tmp1);
+ break;
+
+ case R_RL78_OPshra:
+ RL78_STACK_POP (tmp1);
+ RL78_STACK_POP (tmp2);
+ tmp1 >>= tmp2;
+ RL78_STACK_PUSH (tmp1);
+ break;
+
+ case R_RL78_OPsctsize:
+ RL78_STACK_PUSH (input_section->size);
+ break;
+
+ case R_RL78_OPscttop:
+ RL78_STACK_PUSH (input_section->output_section->vma);
+ break;
+
+ case R_RL78_OPand:
+ RL78_STACK_POP (tmp1);
+ RL78_STACK_POP (tmp2);
+ tmp1 &= tmp2;
+ RL78_STACK_PUSH (tmp1);
+ break;
+
+ case R_RL78_OPor:
+ RL78_STACK_POP (tmp1);
+ RL78_STACK_POP (tmp2);
+ tmp1 |= tmp2;
+ RL78_STACK_PUSH (tmp1);
+ break;
+
+ case R_RL78_OPxor:
+ RL78_STACK_POP (tmp1);
+ RL78_STACK_POP (tmp2);
+ tmp1 ^= tmp2;
+ RL78_STACK_PUSH (tmp1);
+ break;
+
+ case R_RL78_OPnot:
+ RL78_STACK_POP (tmp1);
+ tmp1 = ~ tmp1;
+ RL78_STACK_PUSH (tmp1);
+ break;
+
+ case R_RL78_OPmod:
+ RL78_STACK_POP (tmp1);
+ RL78_STACK_POP (tmp2);
+ tmp1 %= tmp2;
+ RL78_STACK_PUSH (tmp1);
+ break;
+
+ case R_RL78_OPromtop:
+ RL78_STACK_PUSH (get_romstart (&r, info, input_bfd, input_section, rel->r_offset));
+ break;
+
+ case R_RL78_OPramtop:
+ RL78_STACK_PUSH (get_ramstart (&r, info, input_bfd, input_section, rel->r_offset));
+ break;
+
+ case R_RL78_DIR16UL:
+ case R_RL78_DIR8UL:
+ case R_RL78_ABS16UL:
+ case R_RL78_ABS8UL:
+ if (rl78_stack_top)
+ RL78_STACK_POP (symval);
+ if (lrel)
+ *lrel = rel;
+ *scale = 4;
+ return symval;
+
+ case R_RL78_DIR16UW:
+ case R_RL78_DIR8UW:
+ case R_RL78_ABS16UW:
+ case R_RL78_ABS8UW:
+ if (rl78_stack_top)
+ RL78_STACK_POP (symval);
+ if (lrel)
+ *lrel = rel;
+ *scale = 2;
+ return symval;
+
+ default:
+ if (rl78_stack_top)
+ RL78_STACK_POP (symval);
+ if (lrel)
+ *lrel = rel;
+ return symval;
+ }
+
+ rel ++;
+ }
+}
+
+struct {
+ int prefix; /* or -1 for "no prefix" */
+ int insn; /* or -1 for "end of list" */
+ int insn_for_saddr; /* or -1 for "no alternative" */
+ int insn_for_sfr; /* or -1 for "no alternative" */
+} relax_addr16[] = {
+ { -1, 0x02, 0x06, -1 }, /* ADDW AX, !addr16 */
+ { -1, 0x22, 0x26, -1 }, /* SUBW AX, !addr16 */
+ { -1, 0x42, 0x46, -1 }, /* CMPW AX, !addr16 */
+ { -1, 0x40, 0x4a, -1 }, /* CMP !addr16, #byte */
+
+ { -1, 0x0f, 0x0b, -1 }, /* ADD A, !addr16 */
+ { -1, 0x1f, 0x1b, -1 }, /* ADDC A, !addr16 */
+ { -1, 0x2f, 0x2b, -1 }, /* SUB A, !addr16 */
+ { -1, 0x3f, 0x3b, -1 }, /* SUBC A, !addr16 */
+ { -1, 0x4f, 0x4b, -1 }, /* CMP A, !addr16 */
+ { -1, 0x5f, 0x5b, -1 }, /* AND A, !addr16 */
+ { -1, 0x6f, 0x6b, -1 }, /* OR A, !addr16 */
+ { -1, 0x7f, 0x7b, -1 }, /* XOR A, !addr16 */
+
+ { -1, 0x8f, 0x8d, 0x8e }, /* MOV A, !addr16 */
+ { -1, 0x9f, 0x9d, 0x9e }, /* MOV !addr16, A */
+ { -1, 0xaf, 0xad, 0xae }, /* MOVW AX, !addr16 */
+ { -1, 0xbf, 0xbd, 0xbe }, /* MOVW !addr16, AX */
+ { -1, 0xcf, 0xcd, 0xce }, /* MOVW !addr16, #word */
+
+ { -1, 0xa0, 0xa4, -1 }, /* INC !addr16 */
+ { -1, 0xa2, 0xa6, -1 }, /* INCW !addr16 */
+ { -1, 0xb0, 0xb4, -1 }, /* DEC !addr16 */
+ { -1, 0xb2, 0xb6, -1 }, /* DECW !addr16 */
+
+ { -1, 0xd5, 0xd4, -1 }, /* CMP0 !addr16 */
+ { -1, 0xe5, 0xe4, -1 }, /* ONEB !addr16 */
+ { -1, 0xf5, 0xf4, -1 }, /* CLRB !addr16 */
+
+ { -1, 0xd9, 0xd8, -1 }, /* MOV X, !addr16 */
+ { -1, 0xe9, 0xe8, -1 }, /* MOV B, !addr16 */
+ { -1, 0xf9, 0xf8, -1 }, /* MOV C, !addr16 */
+ { -1, 0xdb, 0xda, -1 }, /* MOVW BC, !addr16 */
+ { -1, 0xeb, 0xea, -1 }, /* MOVW DE, !addr16 */
+ { -1, 0xfb, 0xfa, -1 }, /* MOVW HL, !addr16 */
+
+ { 0x61, 0xaa, 0xa8, -1 }, /* XCH A, !addr16 */
+
+ { 0x71, 0x00, 0x02, 0x0a }, /* SET1 !addr16.0 */
+ { 0x71, 0x10, 0x12, 0x1a }, /* SET1 !addr16.0 */
+ { 0x71, 0x20, 0x22, 0x2a }, /* SET1 !addr16.0 */
+ { 0x71, 0x30, 0x32, 0x3a }, /* SET1 !addr16.0 */
+ { 0x71, 0x40, 0x42, 0x4a }, /* SET1 !addr16.0 */
+ { 0x71, 0x50, 0x52, 0x5a }, /* SET1 !addr16.0 */
+ { 0x71, 0x60, 0x62, 0x6a }, /* SET1 !addr16.0 */
+ { 0x71, 0x70, 0x72, 0x7a }, /* SET1 !addr16.0 */
+
+ { 0x71, 0x08, 0x03, 0x0b }, /* CLR1 !addr16.0 */
+ { 0x71, 0x18, 0x13, 0x1b }, /* CLR1 !addr16.0 */
+ { 0x71, 0x28, 0x23, 0x2b }, /* CLR1 !addr16.0 */
+ { 0x71, 0x38, 0x33, 0x3b }, /* CLR1 !addr16.0 */
+ { 0x71, 0x48, 0x43, 0x4b }, /* CLR1 !addr16.0 */
+ { 0x71, 0x58, 0x53, 0x5b }, /* CLR1 !addr16.0 */
+ { 0x71, 0x68, 0x63, 0x6b }, /* CLR1 !addr16.0 */
+ { 0x71, 0x78, 0x73, 0x7b }, /* CLR1 !addr16.0 */
+
+ { -1, -1, -1, -1 }
+};
+
+/* Relax one section. */
+
+static bfd_boolean
+rl78_elf_relax_section
+ (bfd * abfd,
+ asection * sec,
+ struct bfd_link_info * link_info,
+ bfd_boolean * again)
+{
+ Elf_Internal_Shdr * symtab_hdr;
+ Elf_Internal_Shdr * shndx_hdr;
+ Elf_Internal_Rela * internal_relocs;
+ Elf_Internal_Rela * free_relocs = NULL;
+ Elf_Internal_Rela * irel;
+ Elf_Internal_Rela * srel;
+ Elf_Internal_Rela * irelend;
+ Elf_Internal_Rela * next_alignment;
+ bfd_byte * contents = NULL;
+ bfd_byte * free_contents = NULL;
+ Elf_Internal_Sym * intsyms = NULL;
+ Elf_Internal_Sym * free_intsyms = NULL;
+ Elf_External_Sym_Shndx * shndx_buf = NULL;
+ bfd_vma pc;
+ bfd_vma symval ATTRIBUTE_UNUSED = 0;
+ int pcrel ATTRIBUTE_UNUSED = 0;
+ int code ATTRIBUTE_UNUSED = 0;
+ int section_alignment_glue;
+ int scale;
+
+ if (abfd == elf_hash_table (link_info)->dynobj
+ && strcmp (sec->name, ".plt") == 0)
+ return rl78_elf_relax_plt_section (abfd, sec, link_info, again);
+
+ /* Assume nothing changes. */
+ *again = FALSE;
+
+ /* We don't have to do anything for a relocatable link, if
+ this section does not have relocs, or if this is not a
+ code section. */
+ if (link_info->relocatable
+ || (sec->flags & SEC_RELOC) == 0
+ || sec->reloc_count == 0
+ || (sec->flags & SEC_CODE) == 0)
+ return TRUE;
+
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+ shndx_hdr = &elf_tdata (abfd)->symtab_shndx_hdr;
+
+ /* Get the section contents. */
+ if (elf_section_data (sec)->this_hdr.contents != NULL)
+ contents = elf_section_data (sec)->this_hdr.contents;
+ /* Go get them off disk. */
+ else
+ {
+ if (! bfd_malloc_and_get_section (abfd, sec, &contents))
+ goto error_return;
+ elf_section_data (sec)->this_hdr.contents = contents;
+ }
+
+ /* Read this BFD's symbols. */
+ /* Get cached copy if it exists. */
+ if (symtab_hdr->contents != NULL)
+ intsyms = (Elf_Internal_Sym *) symtab_hdr->contents;
+ else
+ {
+ intsyms = bfd_elf_get_elf_syms (abfd, symtab_hdr, symtab_hdr->sh_info, 0, NULL, NULL, NULL);
+ symtab_hdr->contents = (bfd_byte *) intsyms;
+ }
+
+ if (shndx_hdr->sh_size != 0)
+ {
+ bfd_size_type amt;
+
+ amt = symtab_hdr->sh_info;
+ amt *= sizeof (Elf_External_Sym_Shndx);
+ shndx_buf = (Elf_External_Sym_Shndx *) bfd_malloc (amt);
+ if (shndx_buf == NULL)
+ goto error_return;
+ if (bfd_seek (abfd, shndx_hdr->sh_offset, SEEK_SET) != 0
+ || bfd_bread (shndx_buf, amt, abfd) != amt)
+ goto error_return;
+ shndx_hdr->contents = (bfd_byte *) shndx_buf;
+ }
+
+ /* Get a copy of the native relocations. */
+ internal_relocs = (_bfd_elf_link_read_relocs
+ (abfd, sec, 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;
+
+ /* The RL_ relocs must be just before the operand relocs they go
+ with, so we must sort them to guarantee this. We use bubblesort
+ instead of qsort so we can guarantee that relocs with the same
+ address remain in the same relative order. */
+ reloc_bubblesort (internal_relocs, sec->reloc_count);
+
+ /* Walk through them looking for relaxing opportunities. */
+ irelend = internal_relocs + sec->reloc_count;
+
+
+ /* This will either be NULL or a pointer to the next alignment
+ relocation. */
+ next_alignment = internal_relocs;
+
+ /* We calculate worst case shrinkage caused by alignment directives.
+ No fool-proof, but better than either ignoring the problem or
+ doing heavy duty analysis of all the alignment markers in all
+ input sections. */
+ section_alignment_glue = 0;
+ for (irel = internal_relocs; irel < irelend; irel++)
+ if (ELF32_R_TYPE (irel->r_info) == R_RL78_RH_RELAX
+ && irel->r_addend & RL78_RELAXA_ALIGN)
+ {
+ int this_glue = 1 << (irel->r_addend & RL78_RELAXA_ANUM);
+
+ if (section_alignment_glue < this_glue)
+ section_alignment_glue = this_glue;
+ }
+ /* Worst case is all 0..N alignments, in order, causing 2*N-1 byte
+ shrinkage. */
+ section_alignment_glue *= 2;
+
+ for (irel = internal_relocs; irel < irelend; irel++)
+ {
+ unsigned char *insn;
+ int nrelocs;
+
+ /* The insns we care about are all marked with one of these. */
+ if (ELF32_R_TYPE (irel->r_info) != R_RL78_RH_RELAX)
+ continue;
+
+ if (irel->r_addend & RL78_RELAXA_ALIGN
+ || next_alignment == internal_relocs)
+ {
+ /* When we delete bytes, we need to maintain all the alignments
+ indicated. In addition, we need to be careful about relaxing
+ jumps across alignment boundaries - these displacements
+ *grow* when we delete bytes. For now, don't shrink
+ displacements across an alignment boundary, just in case.
+ Note that this only affects relocations to the same
+ section. */
+ next_alignment += 2;
+ while (next_alignment < irelend
+ && (ELF32_R_TYPE (next_alignment->r_info) != R_RL78_RH_RELAX
+ || !(next_alignment->r_addend & RL78_RELAXA_ELIGN)))
+ next_alignment ++;
+ if (next_alignment >= irelend || next_alignment->r_offset == 0)
+ next_alignment = NULL;
+ }
+
+ /* When we hit alignment markers, see if we've shrunk enough
+ before them to reduce the gap without violating the alignment
+ requirements. */
+ if (irel->r_addend & RL78_RELAXA_ALIGN)
+ {
+ /* At this point, the next relocation *should* be the ELIGN
+ end marker. */
+ Elf_Internal_Rela *erel = irel + 1;
+ unsigned int alignment, nbytes;
+
+ if (ELF32_R_TYPE (erel->r_info) != R_RL78_RH_RELAX)
+ continue;
+ if (!(erel->r_addend & RL78_RELAXA_ELIGN))
+ continue;
+
+ alignment = 1 << (irel->r_addend & RL78_RELAXA_ANUM);
+
+ if (erel->r_offset - irel->r_offset < alignment)
+ continue;
+
+ nbytes = erel->r_offset - irel->r_offset;
+ nbytes /= alignment;
+ nbytes *= alignment;
+
+ elf32_rl78_relax_delete_bytes (abfd, sec, erel->r_offset-nbytes, nbytes, next_alignment,
+ erel->r_offset == sec->size);
+ *again = TRUE;
+
+ continue;
+ }
+
+ if (irel->r_addend & RL78_RELAXA_ELIGN)
+ continue;
+
+ insn = contents + irel->r_offset;
+
+ nrelocs = irel->r_addend & RL78_RELAXA_RNUM;
+
+ /* At this point, we have an insn that is a candidate for linker
+ relaxation. There are NRELOCS relocs following that may be
+ relaxed, although each reloc may be made of more than one
+ reloc entry (such as gp-rel symbols). */
+
+ /* Get the value of the symbol referred to by the reloc. Just
+ in case this is the last reloc in the list, use the RL's
+ addend to choose between this reloc (no addend) or the next
+ (yes addend, which means at least one following reloc). */
+
+ /* srel points to the "current" reloction for this insn -
+ actually the last reloc for a given operand, which is the one
+ we need to update. We check the relaxations in the same
+ order that the relocations happen, so we'll just push it
+ along as we go. */
+ srel = irel;
+
+ pc = sec->output_section->vma + sec->output_offset
+ + srel->r_offset;
+
+#define GET_RELOC \
+ BFD_ASSERT (nrelocs > 0); \
+ symval = OFFSET_FOR_RELOC (srel, &srel, &scale); \
+ pcrel = symval - pc + srel->r_addend; \
+ nrelocs --;
+
+#define SNIPNR(offset, nbytes) \
+ elf32_rl78_relax_delete_bytes (abfd, sec, (insn - contents) + offset, nbytes, next_alignment, 0);
+#define SNIP(offset, nbytes, newtype) \
+ SNIPNR (offset, nbytes); \
+ srel->r_info = ELF32_R_INFO (ELF32_R_SYM (srel->r_info), newtype)
+
+ /* The order of these bit tests must match the order that the
+ relocs appear in. Since we sorted those by offset, we can
+ predict them. */
+
+ /*----------------------------------------------------------------------*/
+ /* EF ad BR $rel8 pcrel
+ ED al ah BR !abs16 abs
+ EE al ah BR $!rel16 pcrel
+ EC al ah as BR !!abs20 abs
+
+ FD al ah CALL !abs16 abs
+ FE al ah CALL $!rel16 pcrel
+ FC al ah as CALL !!abs20 abs
+
+ DC ad BC $rel8
+ DE ad BNC $rel8
+ DD ad BZ $rel8
+ DF ad BNZ $rel8
+ 61 C3 ad BH $rel8
+ 61 D3 ad BNH $rel8
+ 61 C8 EF ad SKC ; BR $rel8
+ 61 D8 EF ad SKNC ; BR $rel8
+ 61 E8 EF ad SKZ ; BR $rel8
+ 61 F8 EF ad SKNZ ; BR $rel8
+ 61 E3 EF ad SKH ; BR $rel8
+ 61 F3 EF ad SKNH ; BR $rel8
+ */
+
+ if ((irel->r_addend & RL78_RELAXA_MASK) == RL78_RELAXA_BRA)
+ {
+ /* SKIP opcodes that skip non-branches will have a relax tag
+ but no corresponding symbol to relax against; we just
+ skip those. */
+ if (irel->r_addend & RL78_RELAXA_RNUM)
+ {
+ GET_RELOC;
+ }
+
+ switch (insn[0])
+ {
+ case 0xec: /* BR !!abs20 */
+
+ if (pcrel < 127
+ && pcrel > -127)
+ {
+ insn[0] = 0xef;
+ insn[1] = pcrel;
+ SNIP (2, 2, R_RL78_DIR8S_PCREL);
+ *again = TRUE;
+ }
+ else if (symval < 65536)
+ {
+ insn[0] = 0xed;
+ insn[1] = symval & 0xff;
+ insn[2] = symval >> 8;
+ SNIP (2, 1, R_RL78_DIR16S);
+ *again = TRUE;
+ }
+ else if (pcrel < 32767
+ && pcrel > -32767)
+ {
+ insn[0] = 0xee;
+ insn[1] = pcrel & 0xff;
+ insn[2] = pcrel >> 8;
+ SNIP (2, 1, R_RL78_DIR16S_PCREL);
+ *again = TRUE;
+ }
+ break;
+
+ case 0xee: /* BR $!pcrel16 */
+ case 0xed: /* BR $!abs16 */
+ if (pcrel < 127
+ && pcrel > -127)
+ {
+ insn[0] = 0xef;
+ insn[1] = pcrel;
+ SNIP (2, 1, R_RL78_DIR8S_PCREL);
+ *again = TRUE;
+ }
+ break;
+
+ case 0xfc: /* CALL !!abs20 */
+ if (symval < 65536)
+ {
+ insn[0] = 0xfd;
+ insn[1] = symval & 0xff;
+ insn[2] = symval >> 8;
+ SNIP (2, 1, R_RL78_DIR16S);
+ *again = TRUE;
+ }
+ else if (pcrel < 32767
+ && pcrel > -32767)
+ {
+ insn[0] = 0xfe;
+ insn[1] = pcrel & 0xff;
+ insn[2] = pcrel >> 8;
+ SNIP (2, 1, R_RL78_DIR16S_PCREL);
+ *again = TRUE;
+ }
+ break;
+
+ case 0x61: /* PREFIX */
+ /* For SKIP/BR, we change the BR opcode and delete the
+ SKIP. That way, we don't have to find and change the
+ relocation for the BR. */
+ /* Note that, for the case where we're skipping some
+ other insn, we have no "other" reloc but that's safe
+ here anyway. */
+ switch (insn[1])
+ {
+ case 0xc8: /* SKC */
+ if (insn[2] == 0xef)
+ {
+ insn[2] = 0xde; /* BNC */
+ SNIPNR (0, 2);
+ }
+ break;
+
+ case 0xd8: /* SKNC */
+ if (insn[2] == 0xef)
+ {
+ insn[2] = 0xdc; /* BC */
+ SNIPNR (0, 2);
+ }
+ break;
+
+ case 0xe8: /* SKZ */
+ if (insn[2] == 0xef)
+ {
+ insn[2] = 0xdf; /* BNZ */
+ SNIPNR (0, 2);
+ }
+ break;
+
+ case 0xf8: /* SKNZ */
+ if (insn[2] == 0xef)
+ {
+ insn[2] = 0xdd; /* BZ */
+ SNIPNR (0, 2);
+ }
+ break;
+
+ case 0xe3: /* SKH */
+ if (insn[2] == 0xef)
+ {
+ insn[2] = 0xd3; /* BNH */
+ SNIPNR (1, 1); /* we reuse the 0x61 prefix from the SKH */
+ }
+ break;
+
+ case 0xf3: /* SKNH */
+ if (insn[2] == 0xef)
+ {
+ insn[2] = 0xc3; /* BH */
+ SNIPNR (1, 1); /* we reuse the 0x61 prefix from the SKH */
+ }
+ break;
+ }
+ break;
+ }
+
+ }
+
+ if ((irel->r_addend & RL78_RELAXA_MASK) == RL78_RELAXA_ADDR16)
+ {
+ /*----------------------------------------------------------------------*/
+ /* Some insns have both a 16-bit address operand and an 8-bit
+ variant if the address is within a special range:
+
+ Address 16-bit operand SADDR range SFR range
+ FFF00-FFFFF 0xff00-0xffff 0x00-0xff
+ FFE20-FFF1F 0xfe20-0xff1f 0x00-0xff
+
+ The RELAX_ADDR16[] array has the insn encodings for the
+ 16-bit operand version, as well as the SFR and SADDR
+ variants. We only need to replace the encodings and
+ adjust the operand.
+
+ Note: we intentionally do not attempt to decode and skip
+ any ES: prefix, as adding ES: means the addr16 (likely)
+ no longer points to saddr/sfr space.
+ */
+
+ int is_sfr;
+ int is_saddr;
+ int idx;
+ int poff;
+
+ GET_RELOC;
+
+ if (0xffe20 <= symval && symval <= 0xfffff)
+ {
+
+ is_saddr = (0xffe20 <= symval && symval <= 0xfff1f);
+ is_sfr = (0xfff00 <= symval && symval <= 0xfffff);
+
+ for (idx = 0; relax_addr16[idx].insn != -1; idx ++)
+ {
+ if (relax_addr16[idx].prefix != -1
+ && insn[0] == relax_addr16[idx].prefix
+ && insn[1] == relax_addr16[idx].insn)
+ {
+ poff = 1;
+ }
+ else if (relax_addr16[idx].prefix == -1
+ && insn[0] == relax_addr16[idx].insn)
+ {
+ poff = 0;
+ }
+ else
+ continue;
+
+ /* We have a matched insn, and poff is 0 or 1 depending
+ on the base pattern size. */
+
+ if (is_sfr && relax_addr16[idx].insn_for_sfr != -1)
+ {
+ insn[poff] = relax_addr16[idx].insn_for_sfr;
+ SNIP (poff+2, 1, R_RL78_RH_SFR);
+ }
+
+ else if (is_saddr && relax_addr16[idx].insn_for_saddr != -1)
+ {
+ insn[poff] = relax_addr16[idx].insn_for_saddr;
+ SNIP (poff+2, 1, R_RL78_RH_SADDR);
+ }
+
+ }
+ }
+ }
+
+ /*----------------------------------------------------------------------*/
+
+ }
+
+ return TRUE;
+
+ error_return:
+ if (free_relocs != NULL)
+ free (free_relocs);
+
+ if (free_contents != NULL)
+ free (free_contents);
+
+ if (shndx_buf != NULL)
+ {
+ shndx_hdr->contents = NULL;
+ free (shndx_buf);
+ }
+
+ if (free_intsyms != NULL)
+ free (free_intsyms);
+
+ return TRUE;
+}
+
+
+
+#define ELF_ARCH bfd_arch_rl78
+#define ELF_MACHINE_CODE EM_RL78
+#define ELF_MAXPAGESIZE 0x1000
+
+#define TARGET_LITTLE_SYM rl78_elf32_vec
+#define TARGET_LITTLE_NAME "elf32-rl78"
+
+#define elf_info_to_howto_rel NULL
+#define elf_info_to_howto rl78_info_to_howto_rela
+#define elf_backend_object_p rl78_elf_object_p
+#define elf_backend_relocate_section rl78_elf_relocate_section
+#define elf_symbol_leading_char ('_')
+#define elf_backend_can_gc_sections 1
+
+#define bfd_elf32_bfd_reloc_type_lookup rl78_reloc_type_lookup
+#define bfd_elf32_bfd_reloc_name_lookup rl78_reloc_name_lookup
+#define bfd_elf32_bfd_set_private_flags rl78_elf_set_private_flags
+#define bfd_elf32_bfd_merge_private_bfd_data rl78_elf_merge_private_bfd_data
+#define bfd_elf32_bfd_print_private_bfd_data rl78_elf_print_private_bfd_data
+
+#define bfd_elf32_bfd_relax_section rl78_elf_relax_section
+#define elf_backend_check_relocs rl78_elf_check_relocs
+#define elf_backend_always_size_sections \
+ rl78_elf_always_size_sections
+#define elf_backend_finish_dynamic_sections \
+ rl78_elf_finish_dynamic_sections
+
+#include "elf32-target.h"
diff --git a/bfd/elf32-rx.c b/bfd/elf32-rx.c
new file mode 100644
index 0000000..5d09f21
--- /dev/null
+++ b/bfd/elf32-rx.c
@@ -0,0 +1,3987 @@
+/* Renesas RX specific support for 32-bit ELF.
+ Copyright (C) 2008-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public 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 "bfd.h"
+#include "bfd_stdint.h"
+#include "libbfd.h"
+#include "elf-bfd.h"
+#include "elf/rx.h"
+#include "libiberty.h"
+#include "elf32-rx.h"
+
+#define RX_OPCODE_BIG_ENDIAN 0
+
+/* This is a meta-target that's used only with objcopy, to avoid the
+ endian-swap we would otherwise get. We check for this in
+ rx_elf_object_p(). */
+const bfd_target rx_elf32_be_ns_vec;
+const bfd_target rx_elf32_be_vec;
+
+#ifdef DEBUG
+char * rx_get_reloc (long);
+void rx_dump_symtab (bfd *, void *, void *);
+#endif
+
+#define RXREL(n,sz,bit,shift,complain,pcrel) \
+ HOWTO (R_RX_##n, shift, sz, bit, pcrel, 0, complain_overflow_ ## complain, \
+ bfd_elf_generic_reloc, "R_RX_" #n, FALSE, 0, ~0, FALSE)
+
+/* Note that the relocations around 0x7f are internal to this file;
+ feel free to move them as needed to avoid conflicts with published
+ relocation numbers. */
+
+static reloc_howto_type rx_elf_howto_table [] =
+{
+ RXREL (NONE, 0, 0, 0, dont, FALSE),
+ RXREL (DIR32, 2, 32, 0, signed, FALSE),
+ RXREL (DIR24S, 2, 24, 0, signed, FALSE),
+ RXREL (DIR16, 1, 16, 0, dont, FALSE),
+ RXREL (DIR16U, 1, 16, 0, unsigned, FALSE),
+ RXREL (DIR16S, 1, 16, 0, signed, FALSE),
+ RXREL (DIR8, 0, 8, 0, dont, FALSE),
+ RXREL (DIR8U, 0, 8, 0, unsigned, FALSE),
+ RXREL (DIR8S, 0, 8, 0, signed, FALSE),
+ RXREL (DIR24S_PCREL, 2, 24, 0, signed, TRUE),
+ RXREL (DIR16S_PCREL, 1, 16, 0, signed, TRUE),
+ RXREL (DIR8S_PCREL, 0, 8, 0, signed, TRUE),
+ RXREL (DIR16UL, 1, 16, 2, unsigned, FALSE),
+ RXREL (DIR16UW, 1, 16, 1, unsigned, FALSE),
+ RXREL (DIR8UL, 0, 8, 2, unsigned, FALSE),
+ RXREL (DIR8UW, 0, 8, 1, unsigned, FALSE),
+ RXREL (DIR32_REV, 1, 16, 0, dont, FALSE),
+ RXREL (DIR16_REV, 1, 16, 0, dont, FALSE),
+ RXREL (DIR3U_PCREL, 0, 3, 0, dont, TRUE),
+
+ EMPTY_HOWTO (0x13),
+ EMPTY_HOWTO (0x14),
+ EMPTY_HOWTO (0x15),
+ EMPTY_HOWTO (0x16),
+ EMPTY_HOWTO (0x17),
+ EMPTY_HOWTO (0x18),
+ EMPTY_HOWTO (0x19),
+ EMPTY_HOWTO (0x1a),
+ EMPTY_HOWTO (0x1b),
+ EMPTY_HOWTO (0x1c),
+ EMPTY_HOWTO (0x1d),
+ EMPTY_HOWTO (0x1e),
+ EMPTY_HOWTO (0x1f),
+
+ RXREL (RH_3_PCREL, 0, 3, 0, signed, TRUE),
+ RXREL (RH_16_OP, 1, 16, 0, signed, FALSE),
+ RXREL (RH_24_OP, 2, 24, 0, signed, FALSE),
+ RXREL (RH_32_OP, 2, 32, 0, signed, FALSE),
+ RXREL (RH_24_UNS, 2, 24, 0, unsigned, FALSE),
+ RXREL (RH_8_NEG, 0, 8, 0, signed, FALSE),
+ RXREL (RH_16_NEG, 1, 16, 0, signed, FALSE),
+ RXREL (RH_24_NEG, 2, 24, 0, signed, FALSE),
+ RXREL (RH_32_NEG, 2, 32, 0, signed, FALSE),
+ RXREL (RH_DIFF, 2, 32, 0, signed, FALSE),
+ RXREL (RH_GPRELB, 1, 16, 0, unsigned, FALSE),
+ RXREL (RH_GPRELW, 1, 16, 0, unsigned, FALSE),
+ RXREL (RH_GPRELL, 1, 16, 0, unsigned, FALSE),
+ RXREL (RH_RELAX, 0, 0, 0, dont, FALSE),
+
+ EMPTY_HOWTO (0x2e),
+ EMPTY_HOWTO (0x2f),
+ EMPTY_HOWTO (0x30),
+ EMPTY_HOWTO (0x31),
+ EMPTY_HOWTO (0x32),
+ EMPTY_HOWTO (0x33),
+ EMPTY_HOWTO (0x34),
+ EMPTY_HOWTO (0x35),
+ EMPTY_HOWTO (0x36),
+ EMPTY_HOWTO (0x37),
+ EMPTY_HOWTO (0x38),
+ EMPTY_HOWTO (0x39),
+ EMPTY_HOWTO (0x3a),
+ EMPTY_HOWTO (0x3b),
+ EMPTY_HOWTO (0x3c),
+ EMPTY_HOWTO (0x3d),
+ EMPTY_HOWTO (0x3e),
+ EMPTY_HOWTO (0x3f),
+ EMPTY_HOWTO (0x40),
+
+ RXREL (ABS32, 2, 32, 0, dont, FALSE),
+ RXREL (ABS24S, 2, 24, 0, signed, FALSE),
+ RXREL (ABS16, 1, 16, 0, dont, FALSE),
+ RXREL (ABS16U, 1, 16, 0, unsigned, FALSE),
+ RXREL (ABS16S, 1, 16, 0, signed, FALSE),
+ RXREL (ABS8, 0, 8, 0, dont, FALSE),
+ RXREL (ABS8U, 0, 8, 0, unsigned, FALSE),
+ RXREL (ABS8S, 0, 8, 0, signed, FALSE),
+ RXREL (ABS24S_PCREL, 2, 24, 0, signed, TRUE),
+ RXREL (ABS16S_PCREL, 1, 16, 0, signed, TRUE),
+ RXREL (ABS8S_PCREL, 0, 8, 0, signed, TRUE),
+ RXREL (ABS16UL, 1, 16, 0, unsigned, FALSE),
+ RXREL (ABS16UW, 1, 16, 0, unsigned, FALSE),
+ RXREL (ABS8UL, 0, 8, 0, unsigned, FALSE),
+ RXREL (ABS8UW, 0, 8, 0, unsigned, FALSE),
+ RXREL (ABS32_REV, 2, 32, 0, dont, FALSE),
+ RXREL (ABS16_REV, 1, 16, 0, dont, FALSE),
+
+#define STACK_REL_P(x) ((x) <= R_RX_ABS16_REV && (x) >= R_RX_ABS32)
+
+ EMPTY_HOWTO (0x52),
+ EMPTY_HOWTO (0x53),
+ EMPTY_HOWTO (0x54),
+ EMPTY_HOWTO (0x55),
+ EMPTY_HOWTO (0x56),
+ EMPTY_HOWTO (0x57),
+ EMPTY_HOWTO (0x58),
+ EMPTY_HOWTO (0x59),
+ EMPTY_HOWTO (0x5a),
+ EMPTY_HOWTO (0x5b),
+ EMPTY_HOWTO (0x5c),
+ EMPTY_HOWTO (0x5d),
+ EMPTY_HOWTO (0x5e),
+ EMPTY_HOWTO (0x5f),
+ EMPTY_HOWTO (0x60),
+ EMPTY_HOWTO (0x61),
+ EMPTY_HOWTO (0x62),
+ EMPTY_HOWTO (0x63),
+ EMPTY_HOWTO (0x64),
+ EMPTY_HOWTO (0x65),
+ EMPTY_HOWTO (0x66),
+ EMPTY_HOWTO (0x67),
+ EMPTY_HOWTO (0x68),
+ EMPTY_HOWTO (0x69),
+ EMPTY_HOWTO (0x6a),
+ EMPTY_HOWTO (0x6b),
+ EMPTY_HOWTO (0x6c),
+ EMPTY_HOWTO (0x6d),
+ EMPTY_HOWTO (0x6e),
+ EMPTY_HOWTO (0x6f),
+ EMPTY_HOWTO (0x70),
+ EMPTY_HOWTO (0x71),
+ EMPTY_HOWTO (0x72),
+ EMPTY_HOWTO (0x73),
+ EMPTY_HOWTO (0x74),
+ EMPTY_HOWTO (0x75),
+ EMPTY_HOWTO (0x76),
+ EMPTY_HOWTO (0x77),
+
+ /* These are internal. */
+ /* A 5-bit unsigned displacement to a B/W/L address, at bit position 8/12. */
+ /* ---- ---- 4--- 3210. */
+#define R_RX_RH_ABS5p8B 0x78
+ RXREL (RH_ABS5p8B, 0, 0, 0, dont, FALSE),
+#define R_RX_RH_ABS5p8W 0x79
+ RXREL (RH_ABS5p8W, 0, 0, 0, dont, FALSE),
+#define R_RX_RH_ABS5p8L 0x7a
+ RXREL (RH_ABS5p8L, 0, 0, 0, dont, FALSE),
+ /* A 5-bit unsigned displacement to a B/W/L address, at bit position 5/12. */
+ /* ---- -432 1--- 0---. */
+#define R_RX_RH_ABS5p5B 0x7b
+ RXREL (RH_ABS5p5B, 0, 0, 0, dont, FALSE),
+#define R_RX_RH_ABS5p5W 0x7c
+ RXREL (RH_ABS5p5W, 0, 0, 0, dont, FALSE),
+#define R_RX_RH_ABS5p5L 0x7d
+ RXREL (RH_ABS5p5L, 0, 0, 0, dont, FALSE),
+ /* A 4-bit unsigned immediate at bit position 8. */
+#define R_RX_RH_UIMM4p8 0x7e
+ RXREL (RH_UIMM4p8, 0, 0, 0, dont, FALSE),
+ /* A 4-bit negative unsigned immediate at bit position 8. */
+#define R_RX_RH_UNEG4p8 0x7f
+ RXREL (RH_UNEG4p8, 0, 0, 0, dont, FALSE),
+ /* End of internal relocs. */
+
+ RXREL (SYM, 2, 32, 0, dont, FALSE),
+ RXREL (OPneg, 2, 32, 0, dont, FALSE),
+ RXREL (OPadd, 2, 32, 0, dont, FALSE),
+ RXREL (OPsub, 2, 32, 0, dont, FALSE),
+ RXREL (OPmul, 2, 32, 0, dont, FALSE),
+ RXREL (OPdiv, 2, 32, 0, dont, FALSE),
+ RXREL (OPshla, 2, 32, 0, dont, FALSE),
+ RXREL (OPshra, 2, 32, 0, dont, FALSE),
+ RXREL (OPsctsize, 2, 32, 0, dont, FALSE),
+ RXREL (OPscttop, 2, 32, 0, dont, FALSE),
+ RXREL (OPand, 2, 32, 0, dont, FALSE),
+ RXREL (OPor, 2, 32, 0, dont, FALSE),
+ RXREL (OPxor, 2, 32, 0, dont, FALSE),
+ RXREL (OPnot, 2, 32, 0, dont, FALSE),
+ RXREL (OPmod, 2, 32, 0, dont, FALSE),
+ RXREL (OPromtop, 2, 32, 0, dont, FALSE),
+ RXREL (OPramtop, 2, 32, 0, dont, FALSE)
+};
+
+/* Map BFD reloc types to RX ELF reloc types. */
+
+struct rx_reloc_map
+{
+ bfd_reloc_code_real_type bfd_reloc_val;
+ unsigned int rx_reloc_val;
+};
+
+static const struct rx_reloc_map rx_reloc_map [] =
+{
+ { BFD_RELOC_NONE, R_RX_NONE },
+ { BFD_RELOC_8, R_RX_DIR8S },
+ { BFD_RELOC_16, R_RX_DIR16S },
+ { BFD_RELOC_24, R_RX_DIR24S },
+ { BFD_RELOC_32, R_RX_DIR32 },
+ { BFD_RELOC_RX_16_OP, R_RX_DIR16 },
+ { BFD_RELOC_RX_DIR3U_PCREL, R_RX_DIR3U_PCREL },
+ { BFD_RELOC_8_PCREL, R_RX_DIR8S_PCREL },
+ { BFD_RELOC_16_PCREL, R_RX_DIR16S_PCREL },
+ { BFD_RELOC_24_PCREL, R_RX_DIR24S_PCREL },
+ { BFD_RELOC_RX_8U, R_RX_DIR8U },
+ { BFD_RELOC_RX_16U, R_RX_DIR16U },
+ { BFD_RELOC_RX_24U, R_RX_RH_24_UNS },
+ { BFD_RELOC_RX_NEG8, R_RX_RH_8_NEG },
+ { BFD_RELOC_RX_NEG16, R_RX_RH_16_NEG },
+ { BFD_RELOC_RX_NEG24, R_RX_RH_24_NEG },
+ { BFD_RELOC_RX_NEG32, R_RX_RH_32_NEG },
+ { BFD_RELOC_RX_DIFF, R_RX_RH_DIFF },
+ { BFD_RELOC_RX_GPRELB, R_RX_RH_GPRELB },
+ { BFD_RELOC_RX_GPRELW, R_RX_RH_GPRELW },
+ { BFD_RELOC_RX_GPRELL, R_RX_RH_GPRELL },
+ { BFD_RELOC_RX_RELAX, R_RX_RH_RELAX },
+ { BFD_RELOC_RX_SYM, R_RX_SYM },
+ { BFD_RELOC_RX_OP_SUBTRACT, R_RX_OPsub },
+ { BFD_RELOC_RX_OP_NEG, R_RX_OPneg },
+ { BFD_RELOC_RX_ABS8, R_RX_ABS8 },
+ { BFD_RELOC_RX_ABS16, R_RX_ABS16 },
+ { BFD_RELOC_RX_ABS16_REV, R_RX_ABS16_REV },
+ { BFD_RELOC_RX_ABS32, R_RX_ABS32 },
+ { BFD_RELOC_RX_ABS32_REV, R_RX_ABS32_REV },
+ { BFD_RELOC_RX_ABS16UL, R_RX_ABS16UL },
+ { BFD_RELOC_RX_ABS16UW, R_RX_ABS16UW },
+ { BFD_RELOC_RX_ABS16U, R_RX_ABS16U }
+};
+
+#define BIGE(abfd) ((abfd)->xvec->byteorder == BFD_ENDIAN_BIG)
+
+static reloc_howto_type *
+rx_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED,
+ bfd_reloc_code_real_type code)
+{
+ unsigned int i;
+
+ if (code == BFD_RELOC_RX_32_OP)
+ return rx_elf_howto_table + R_RX_DIR32;
+
+ for (i = ARRAY_SIZE (rx_reloc_map); --i;)
+ if (rx_reloc_map [i].bfd_reloc_val == code)
+ return rx_elf_howto_table + rx_reloc_map[i].rx_reloc_val;
+
+ return NULL;
+}
+
+static reloc_howto_type *
+rx_reloc_name_lookup (bfd * abfd ATTRIBUTE_UNUSED, const char * r_name)
+{
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE (rx_elf_howto_table); i++)
+ if (rx_elf_howto_table[i].name != NULL
+ && strcasecmp (rx_elf_howto_table[i].name, r_name) == 0)
+ return rx_elf_howto_table + i;
+
+ return NULL;
+}
+
+/* Set the howto pointer for an RX ELF reloc. */
+
+static void
+rx_info_to_howto_rela (bfd * abfd ATTRIBUTE_UNUSED,
+ arelent * cache_ptr,
+ Elf_Internal_Rela * dst)
+{
+ unsigned int r_type;
+
+ r_type = ELF32_R_TYPE (dst->r_info);
+ BFD_ASSERT (r_type < (unsigned int) R_RX_max);
+ cache_ptr->howto = rx_elf_howto_table + r_type;
+}
+
+static bfd_vma
+get_symbol_value (const char * name,
+ bfd_reloc_status_type * status,
+ struct bfd_link_info * info,
+ bfd * input_bfd,
+ asection * input_section,
+ int offset)
+{
+ bfd_vma value = 0;
+ struct bfd_link_hash_entry * h;
+
+ h = bfd_link_hash_lookup (info->hash, name, FALSE, FALSE, TRUE);
+
+ if (h == NULL
+ || (h->type != bfd_link_hash_defined
+ && h->type != bfd_link_hash_defweak))
+ * status = info->callbacks->undefined_symbol
+ (info, name, input_bfd, input_section, offset, TRUE);
+ else
+ value = (h->u.def.value
+ + h->u.def.section->output_section->vma
+ + h->u.def.section->output_offset);
+
+ return value;
+}
+static bfd_vma
+get_symbol_value_maybe (const char * name,
+ struct bfd_link_info * info)
+{
+ bfd_vma value = 0;
+ struct bfd_link_hash_entry * h;
+
+ h = bfd_link_hash_lookup (info->hash, name, FALSE, FALSE, TRUE);
+
+ if (h == NULL
+ || (h->type != bfd_link_hash_defined
+ && h->type != bfd_link_hash_defweak))
+ return 0;
+ else
+ value = (h->u.def.value
+ + h->u.def.section->output_section->vma
+ + h->u.def.section->output_offset);
+
+ return value;
+}
+
+static bfd_vma
+get_gp (bfd_reloc_status_type * status,
+ struct bfd_link_info * info,
+ bfd * abfd,
+ asection * sec,
+ int offset)
+{
+ static bfd_boolean cached = FALSE;
+ static bfd_vma cached_value = 0;
+
+ if (!cached)
+ {
+ cached_value = get_symbol_value ("__gp", status, info, abfd, sec, offset);
+ cached = TRUE;
+ }
+ return cached_value;
+}
+
+static bfd_vma
+get_romstart (bfd_reloc_status_type * status,
+ struct bfd_link_info * info,
+ bfd * abfd,
+ asection * sec,
+ int offset)
+{
+ static bfd_boolean cached = FALSE;
+ static bfd_vma cached_value = 0;
+
+ if (!cached)
+ {
+ cached_value = get_symbol_value ("_start", status, info, abfd, sec, offset);
+ cached = TRUE;
+ }
+ return cached_value;
+}
+
+static bfd_vma
+get_ramstart (bfd_reloc_status_type * status,
+ struct bfd_link_info * info,
+ bfd * abfd,
+ asection * sec,
+ int offset)
+{
+ static bfd_boolean cached = FALSE;
+ static bfd_vma cached_value = 0;
+
+ if (!cached)
+ {
+ cached_value = get_symbol_value ("__datastart", status, info, abfd, sec, offset);
+ cached = TRUE;
+ }
+ return cached_value;
+}
+
+#define NUM_STACK_ENTRIES 16
+static int32_t rx_stack [ NUM_STACK_ENTRIES ];
+static unsigned int rx_stack_top;
+
+#define RX_STACK_PUSH(val) \
+ do \
+ { \
+ if (rx_stack_top < NUM_STACK_ENTRIES) \
+ rx_stack [rx_stack_top ++] = (val); \
+ else \
+ r = bfd_reloc_dangerous; \
+ } \
+ while (0)
+
+#define RX_STACK_POP(dest) \
+ do \
+ { \
+ if (rx_stack_top > 0) \
+ (dest) = rx_stack [-- rx_stack_top]; \
+ else \
+ (dest) = 0, r = bfd_reloc_dangerous; \
+ } \
+ while (0)
+
+/* Relocate an RX 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 relocatable
+ 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 relocatable 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 bfd_boolean
+rx_elf_relocate_section
+ (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;
+ bfd_boolean pid_mode;
+ bfd_boolean saw_subtract = FALSE;
+ const char * table_default_cache = NULL;
+ bfd_vma table_start_cache = 0;
+ bfd_vma table_end_cache = 0;
+
+ if (elf_elfheader (output_bfd)->e_flags & E_FLAG_RX_PID)
+ pid_mode = TRUE;
+ else
+ pid_mode = FALSE;
+
+ 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;
+ bfd_boolean unresolved_reloc = TRUE;
+ int r_type;
+
+ r_type = ELF32_R_TYPE (rel->r_info);
+ r_symndx = ELF32_R_SYM (rel->r_info);
+
+ howto = rx_elf_howto_table + ELF32_R_TYPE (rel->r_info);
+ h = NULL;
+ sym = NULL;
+ sec = NULL;
+ relocation = 0;
+
+ if (rx_stack_top == 0)
+ saw_subtract = FALSE;
+
+ if (r_symndx < symtab_hdr->sh_info)
+ {
+ sym = local_syms + r_symndx;
+ sec = local_sections [r_symndx];
+ relocation = _bfd_elf_rela_local_sym (output_bfd, sym, & sec, rel);
+
+ name = bfd_elf_string_from_elf_section
+ (input_bfd, symtab_hdr->sh_link, sym->st_name);
+ name = (sym->st_name == 0) ? bfd_section_name (input_bfd, sec) : name;
+ }
+ else
+ {
+ bfd_boolean warned, ignored;
+
+ RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
+ r_symndx, symtab_hdr, sym_hashes, h,
+ sec, relocation, unresolved_reloc,
+ warned, ignored);
+
+ name = h->root.root.string;
+ }
+
+ if (strncmp (name, "$tableentry$default$", 20) == 0)
+ {
+ bfd_vma entry_vma;
+ int idx;
+ char *buf;
+ bfd_reloc_status_type tstat = 0;
+
+ if (table_default_cache != name)
+ {
+
+ /* All relocs for a given table should be to the same
+ (weak) default symbol) so we can use it to detect a
+ cache miss. We use the offset into the table to find
+ the "real" symbol. Calculate and store the table's
+ offset here. */
+
+ table_default_cache = name;
+
+ /* We have already done error checking in rx_table_find(). */
+
+ buf = (char *) malloc (13 + strlen (name + 20));
+
+ sprintf (buf, "$tablestart$%s", name + 20);
+ tstat = 0;
+ table_start_cache = get_symbol_value (buf,
+ &tstat,
+ info,
+ input_bfd,
+ input_section,
+ rel->r_offset);
+
+ sprintf (buf, "$tableend$%s", name + 20);
+ tstat = 0;
+ table_end_cache = get_symbol_value (buf,
+ &tstat,
+ info,
+ input_bfd,
+ input_section,
+ rel->r_offset);
+
+ free (buf);
+ }
+
+ entry_vma = (input_section->output_section->vma
+ + input_section->output_offset
+ + rel->r_offset);
+
+ if (table_end_cache <= entry_vma || entry_vma < table_start_cache)
+ {
+ _bfd_error_handler (_("%B:%A: table entry %s outside table"),
+ input_bfd, input_section,
+ name);
+ }
+ else if ((int) (entry_vma - table_start_cache) % 4)
+ {
+ _bfd_error_handler (_("%B:%A: table entry %s not word-aligned within table"),
+ input_bfd, input_section,
+ name);
+ }
+ else
+ {
+ idx = (int) (entry_vma - table_start_cache) / 4;
+
+ /* This will look like $tableentry$<N>$<name> */
+ buf = (char *) malloc (12 + 20 + strlen (name + 20));
+ sprintf (buf, "$tableentry$%d$%s", idx, name + 20);
+
+ h = (struct elf_link_hash_entry *) bfd_link_hash_lookup (info->hash, buf, FALSE, FALSE, TRUE);
+
+ if (h)
+ {
+ relocation = (h->root.u.def.value
+ + h->root.u.def.section->output_section->vma
+ + h->root.u.def.section->output_offset);;
+ }
+
+ free (buf);
+ }
+ }
+
+ if (sec != NULL && discarded_section (sec))
+ RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+ rel, 1, relend, howto, 0, contents);
+
+ if (info->relocatable)
+ {
+ /* This is a relocatable 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 (sym != NULL && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
+ rel->r_addend += sec->output_offset;
+ continue;
+ }
+
+ if (h != NULL && h->root.type == bfd_link_hash_undefweak)
+ /* If the symbol is undefined and weak
+ then the relocation resolves to zero. */
+ relocation = 0;
+ else
+ {
+ if (howto->pc_relative)
+ {
+ relocation -= (input_section->output_section->vma
+ + input_section->output_offset
+ + rel->r_offset);
+ if (r_type != R_RX_RH_3_PCREL
+ && r_type != R_RX_DIR3U_PCREL)
+ relocation ++;
+ }
+
+ relocation += rel->r_addend;
+ }
+
+ r = bfd_reloc_ok;
+
+#define RANGE(a,b) if (a > (long) relocation || (long) relocation > b) r = bfd_reloc_overflow
+#define ALIGN(m) if (relocation & m) r = bfd_reloc_other;
+#define OP(i) (contents[rel->r_offset + (i)])
+#define WARN_REDHAT(type) \
+ _bfd_error_handler (_("%B:%A: Warning: deprecated Red Hat reloc " type " detected against: %s."), \
+ input_bfd, input_section, name)
+
+ /* Check for unsafe relocs in PID mode. These are any relocs where
+ an absolute address is being computed. There are special cases
+ for relocs against symbols that are known to be referenced in
+ crt0.o before the PID base address register has been initialised. */
+#define UNSAFE_FOR_PID \
+ do \
+ { \
+ if (pid_mode \
+ && sec != NULL \
+ && sec->flags & SEC_READONLY \
+ && !(input_section->flags & SEC_DEBUGGING) \
+ && strcmp (name, "__pid_base") != 0 \
+ && strcmp (name, "__gp") != 0 \
+ && strcmp (name, "__romdatastart") != 0 \
+ && !saw_subtract) \
+ _bfd_error_handler (_("%B(%A): unsafe PID relocation %s at 0x%08lx (against %s in %s)"), \
+ input_bfd, input_section, howto->name, \
+ input_section->output_section->vma + input_section->output_offset + rel->r_offset, \
+ name, sec->name); \
+ } \
+ while (0)
+
+ /* Opcode relocs are always big endian. Data relocs are bi-endian. */
+ switch (r_type)
+ {
+ case R_RX_NONE:
+ break;
+
+ case R_RX_RH_RELAX:
+ break;
+
+ case R_RX_RH_3_PCREL:
+ WARN_REDHAT ("RX_RH_3_PCREL");
+ RANGE (3, 10);
+ OP (0) &= 0xf8;
+ OP (0) |= relocation & 0x07;
+ break;
+
+ case R_RX_RH_8_NEG:
+ WARN_REDHAT ("RX_RH_8_NEG");
+ relocation = - relocation;
+ case R_RX_DIR8S_PCREL:
+ UNSAFE_FOR_PID;
+ RANGE (-128, 127);
+ OP (0) = relocation;
+ break;
+
+ case R_RX_DIR8S:
+ UNSAFE_FOR_PID;
+ RANGE (-128, 255);
+ OP (0) = relocation;
+ break;
+
+ case R_RX_DIR8U:
+ UNSAFE_FOR_PID;
+ RANGE (0, 255);
+ OP (0) = relocation;
+ break;
+
+ case R_RX_RH_16_NEG:
+ WARN_REDHAT ("RX_RH_16_NEG");
+ relocation = - relocation;
+ case R_RX_DIR16S_PCREL:
+ UNSAFE_FOR_PID;
+ RANGE (-32768, 32767);
+#if RX_OPCODE_BIG_ENDIAN
+#else
+ OP (0) = relocation;
+ OP (1) = relocation >> 8;
+#endif
+ break;
+
+ case R_RX_RH_16_OP:
+ WARN_REDHAT ("RX_RH_16_OP");
+ UNSAFE_FOR_PID;
+ RANGE (-32768, 32767);
+#if RX_OPCODE_BIG_ENDIAN
+ OP (1) = relocation;
+ OP (0) = relocation >> 8;
+#else
+ OP (0) = relocation;
+ OP (1) = relocation >> 8;
+#endif
+ break;
+
+ case R_RX_DIR16S:
+ UNSAFE_FOR_PID;
+ RANGE (-32768, 65535);
+ if (BIGE (output_bfd) && !(input_section->flags & SEC_CODE))
+ {
+ OP (1) = relocation;
+ OP (0) = relocation >> 8;
+ }
+ else
+ {
+ OP (0) = relocation;
+ OP (1) = relocation >> 8;
+ }
+ break;
+
+ case R_RX_DIR16U:
+ UNSAFE_FOR_PID;
+ RANGE (0, 65536);
+#if RX_OPCODE_BIG_ENDIAN
+ OP (1) = relocation;
+ OP (0) = relocation >> 8;
+#else
+ OP (0) = relocation;
+ OP (1) = relocation >> 8;
+#endif
+ break;
+
+ case R_RX_DIR16:
+ UNSAFE_FOR_PID;
+ RANGE (-32768, 65536);
+#if RX_OPCODE_BIG_ENDIAN
+ OP (1) = relocation;
+ OP (0) = relocation >> 8;
+#else
+ OP (0) = relocation;
+ OP (1) = relocation >> 8;
+#endif
+ break;
+
+ case R_RX_DIR16_REV:
+ UNSAFE_FOR_PID;
+ RANGE (-32768, 65536);
+#if RX_OPCODE_BIG_ENDIAN
+ OP (0) = relocation;
+ OP (1) = relocation >> 8;
+#else
+ OP (1) = relocation;
+ OP (0) = relocation >> 8;
+#endif
+ break;
+
+ case R_RX_DIR3U_PCREL:
+ RANGE (3, 10);
+ OP (0) &= 0xf8;
+ OP (0) |= relocation & 0x07;
+ break;
+
+ case R_RX_RH_24_NEG:
+ UNSAFE_FOR_PID;
+ WARN_REDHAT ("RX_RH_24_NEG");
+ relocation = - relocation;
+ case R_RX_DIR24S_PCREL:
+ RANGE (-0x800000, 0x7fffff);
+#if RX_OPCODE_BIG_ENDIAN
+ OP (2) = relocation;
+ OP (1) = relocation >> 8;
+ OP (0) = relocation >> 16;
+#else
+ OP (0) = relocation;
+ OP (1) = relocation >> 8;
+ OP (2) = relocation >> 16;
+#endif
+ break;
+
+ case R_RX_RH_24_OP:
+ UNSAFE_FOR_PID;
+ WARN_REDHAT ("RX_RH_24_OP");
+ RANGE (-0x800000, 0x7fffff);
+#if RX_OPCODE_BIG_ENDIAN
+ OP (2) = relocation;
+ OP (1) = relocation >> 8;
+ OP (0) = relocation >> 16;
+#else
+ OP (0) = relocation;
+ OP (1) = relocation >> 8;
+ OP (2) = relocation >> 16;
+#endif
+ break;
+
+ case R_RX_DIR24S:
+ UNSAFE_FOR_PID;
+ RANGE (-0x800000, 0x7fffff);
+ if (BIGE (output_bfd) && !(input_section->flags & SEC_CODE))
+ {
+ OP (2) = relocation;
+ OP (1) = relocation >> 8;
+ OP (0) = relocation >> 16;
+ }
+ else
+ {
+ OP (0) = relocation;
+ OP (1) = relocation >> 8;
+ OP (2) = relocation >> 16;
+ }
+ break;
+
+ case R_RX_RH_24_UNS:
+ UNSAFE_FOR_PID;
+ WARN_REDHAT ("RX_RH_24_UNS");
+ RANGE (0, 0xffffff);
+#if RX_OPCODE_BIG_ENDIAN
+ OP (2) = relocation;
+ OP (1) = relocation >> 8;
+ OP (0) = relocation >> 16;
+#else
+ OP (0) = relocation;
+ OP (1) = relocation >> 8;
+ OP (2) = relocation >> 16;
+#endif
+ break;
+
+ case R_RX_RH_32_NEG:
+ UNSAFE_FOR_PID;
+ WARN_REDHAT ("RX_RH_32_NEG");
+ relocation = - relocation;
+#if RX_OPCODE_BIG_ENDIAN
+ OP (3) = relocation;
+ OP (2) = relocation >> 8;
+ OP (1) = relocation >> 16;
+ OP (0) = relocation >> 24;
+#else
+ OP (0) = relocation;
+ OP (1) = relocation >> 8;
+ OP (2) = relocation >> 16;
+ OP (3) = relocation >> 24;
+#endif
+ break;
+
+ case R_RX_RH_32_OP:
+ UNSAFE_FOR_PID;
+ WARN_REDHAT ("RX_RH_32_OP");
+#if RX_OPCODE_BIG_ENDIAN
+ OP (3) = relocation;
+ OP (2) = relocation >> 8;
+ OP (1) = relocation >> 16;
+ OP (0) = relocation >> 24;
+#else
+ OP (0) = relocation;
+ OP (1) = relocation >> 8;
+ OP (2) = relocation >> 16;
+ OP (3) = relocation >> 24;
+#endif
+ break;
+
+ case R_RX_DIR32:
+ if (BIGE (output_bfd) && !(input_section->flags & SEC_CODE))
+ {
+ OP (3) = relocation;
+ OP (2) = relocation >> 8;
+ OP (1) = relocation >> 16;
+ OP (0) = relocation >> 24;
+ }
+ else
+ {
+ OP (0) = relocation;
+ OP (1) = relocation >> 8;
+ OP (2) = relocation >> 16;
+ OP (3) = relocation >> 24;
+ }
+ break;
+
+ case R_RX_DIR32_REV:
+ if (BIGE (output_bfd))
+ {
+ OP (0) = relocation;
+ OP (1) = relocation >> 8;
+ OP (2) = relocation >> 16;
+ OP (3) = relocation >> 24;
+ }
+ else
+ {
+ OP (3) = relocation;
+ OP (2) = relocation >> 8;
+ OP (1) = relocation >> 16;
+ OP (0) = relocation >> 24;
+ }
+ break;
+
+ case R_RX_RH_DIFF:
+ {
+ bfd_vma val;
+ WARN_REDHAT ("RX_RH_DIFF");
+ val = bfd_get_32 (output_bfd, & OP (0));
+ val -= relocation;
+ bfd_put_32 (output_bfd, val, & OP (0));
+ }
+ break;
+
+ case R_RX_RH_GPRELB:
+ WARN_REDHAT ("RX_RH_GPRELB");
+ relocation -= get_gp (&r, info, input_bfd, input_section, rel->r_offset);
+ RANGE (0, 65535);
+#if RX_OPCODE_BIG_ENDIAN
+ OP (1) = relocation;
+ OP (0) = relocation >> 8;
+#else
+ OP (0) = relocation;
+ OP (1) = relocation >> 8;
+#endif
+ break;
+
+ case R_RX_RH_GPRELW:
+ WARN_REDHAT ("RX_RH_GPRELW");
+ relocation -= get_gp (&r, info, input_bfd, input_section, rel->r_offset);
+ ALIGN (1);
+ relocation >>= 1;
+ RANGE (0, 65535);
+#if RX_OPCODE_BIG_ENDIAN
+ OP (1) = relocation;
+ OP (0) = relocation >> 8;
+#else
+ OP (0) = relocation;
+ OP (1) = relocation >> 8;
+#endif
+ break;
+
+ case R_RX_RH_GPRELL:
+ WARN_REDHAT ("RX_RH_GPRELL");
+ relocation -= get_gp (&r, info, input_bfd, input_section, rel->r_offset);
+ ALIGN (3);
+ relocation >>= 2;
+ RANGE (0, 65535);
+#if RX_OPCODE_BIG_ENDIAN
+ OP (1) = relocation;
+ OP (0) = relocation >> 8;
+#else
+ OP (0) = relocation;
+ OP (1) = relocation >> 8;
+#endif
+ break;
+
+ /* Internal relocations just for relaxation: */
+ case R_RX_RH_ABS5p5B:
+ RX_STACK_POP (relocation);
+ RANGE (0, 31);
+ OP (0) &= 0xf8;
+ OP (0) |= relocation >> 2;
+ OP (1) &= 0x77;
+ OP (1) |= (relocation << 6) & 0x80;
+ OP (1) |= (relocation << 3) & 0x08;
+ break;
+
+ case R_RX_RH_ABS5p5W:
+ RX_STACK_POP (relocation);
+ RANGE (0, 62);
+ ALIGN (1);
+ relocation >>= 1;
+ OP (0) &= 0xf8;
+ OP (0) |= relocation >> 2;
+ OP (1) &= 0x77;
+ OP (1) |= (relocation << 6) & 0x80;
+ OP (1) |= (relocation << 3) & 0x08;
+ break;
+
+ case R_RX_RH_ABS5p5L:
+ RX_STACK_POP (relocation);
+ RANGE (0, 124);
+ ALIGN (3);
+ relocation >>= 2;
+ OP (0) &= 0xf8;
+ OP (0) |= relocation >> 2;
+ OP (1) &= 0x77;
+ OP (1) |= (relocation << 6) & 0x80;
+ OP (1) |= (relocation << 3) & 0x08;
+ break;
+
+ case R_RX_RH_ABS5p8B:
+ RX_STACK_POP (relocation);
+ RANGE (0, 31);
+ OP (0) &= 0x70;
+ OP (0) |= (relocation << 3) & 0x80;
+ OP (0) |= relocation & 0x0f;
+ break;
+
+ case R_RX_RH_ABS5p8W:
+ RX_STACK_POP (relocation);
+ RANGE (0, 62);
+ ALIGN (1);
+ relocation >>= 1;
+ OP (0) &= 0x70;
+ OP (0) |= (relocation << 3) & 0x80;
+ OP (0) |= relocation & 0x0f;
+ break;
+
+ case R_RX_RH_ABS5p8L:
+ RX_STACK_POP (relocation);
+ RANGE (0, 124);
+ ALIGN (3);
+ relocation >>= 2;
+ OP (0) &= 0x70;
+ OP (0) |= (relocation << 3) & 0x80;
+ OP (0) |= relocation & 0x0f;
+ break;
+
+ case R_RX_RH_UIMM4p8:
+ RANGE (0, 15);
+ OP (0) &= 0x0f;
+ OP (0) |= relocation << 4;
+ break;
+
+ case R_RX_RH_UNEG4p8:
+ RANGE (-15, 0);
+ OP (0) &= 0x0f;
+ OP (0) |= (-relocation) << 4;
+ break;
+
+ /* Complex reloc handling: */
+
+ case R_RX_ABS32:
+ UNSAFE_FOR_PID;
+ RX_STACK_POP (relocation);
+#if RX_OPCODE_BIG_ENDIAN
+ OP (3) = relocation;
+ OP (2) = relocation >> 8;
+ OP (1) = relocation >> 16;
+ OP (0) = relocation >> 24;
+#else
+ OP (0) = relocation;
+ OP (1) = relocation >> 8;
+ OP (2) = relocation >> 16;
+ OP (3) = relocation >> 24;
+#endif
+ break;
+
+ case R_RX_ABS32_REV:
+ UNSAFE_FOR_PID;
+ RX_STACK_POP (relocation);
+#if RX_OPCODE_BIG_ENDIAN
+ OP (0) = relocation;
+ OP (1) = relocation >> 8;
+ OP (2) = relocation >> 16;
+ OP (3) = relocation >> 24;
+#else
+ OP (3) = relocation;
+ OP (2) = relocation >> 8;
+ OP (1) = relocation >> 16;
+ OP (0) = relocation >> 24;
+#endif
+ break;
+
+ case R_RX_ABS24S_PCREL:
+ case R_RX_ABS24S:
+ UNSAFE_FOR_PID;
+ RX_STACK_POP (relocation);
+ RANGE (-0x800000, 0x7fffff);
+ if (BIGE (output_bfd) && !(input_section->flags & SEC_CODE))
+ {
+ OP (2) = relocation;
+ OP (1) = relocation >> 8;
+ OP (0) = relocation >> 16;
+ }
+ else
+ {
+ OP (0) = relocation;
+ OP (1) = relocation >> 8;
+ OP (2) = relocation >> 16;
+ }
+ break;
+
+ case R_RX_ABS16:
+ UNSAFE_FOR_PID;
+ RX_STACK_POP (relocation);
+ RANGE (-32768, 65535);
+#if RX_OPCODE_BIG_ENDIAN
+ OP (1) = relocation;
+ OP (0) = relocation >> 8;
+#else
+ OP (0) = relocation;
+ OP (1) = relocation >> 8;
+#endif
+ break;
+
+ case R_RX_ABS16_REV:
+ UNSAFE_FOR_PID;
+ RX_STACK_POP (relocation);
+ RANGE (-32768, 65535);
+#if RX_OPCODE_BIG_ENDIAN
+ OP (0) = relocation;
+ OP (1) = relocation >> 8;
+#else
+ OP (1) = relocation;
+ OP (0) = relocation >> 8;
+#endif
+ break;
+
+ case R_RX_ABS16S_PCREL:
+ case R_RX_ABS16S:
+ RX_STACK_POP (relocation);
+ RANGE (-32768, 32767);
+ if (BIGE (output_bfd) && !(input_section->flags & SEC_CODE))
+ {
+ OP (1) = relocation;
+ OP (0) = relocation >> 8;
+ }
+ else
+ {
+ OP (0) = relocation;
+ OP (1) = relocation >> 8;
+ }
+ break;
+
+ case R_RX_ABS16U:
+ UNSAFE_FOR_PID;
+ RX_STACK_POP (relocation);
+ RANGE (0, 65536);
+#if RX_OPCODE_BIG_ENDIAN
+ OP (1) = relocation;
+ OP (0) = relocation >> 8;
+#else
+ OP (0) = relocation;
+ OP (1) = relocation >> 8;
+#endif
+ break;
+
+ case R_RX_ABS16UL:
+ UNSAFE_FOR_PID;
+ RX_STACK_POP (relocation);
+ relocation >>= 2;
+ RANGE (0, 65536);
+#if RX_OPCODE_BIG_ENDIAN
+ OP (1) = relocation;
+ OP (0) = relocation >> 8;
+#else
+ OP (0) = relocation;
+ OP (1) = relocation >> 8;
+#endif
+ break;
+
+ case R_RX_ABS16UW:
+ UNSAFE_FOR_PID;
+ RX_STACK_POP (relocation);
+ relocation >>= 1;
+ RANGE (0, 65536);
+#if RX_OPCODE_BIG_ENDIAN
+ OP (1) = relocation;
+ OP (0) = relocation >> 8;
+#else
+ OP (0) = relocation;
+ OP (1) = relocation >> 8;
+#endif
+ break;
+
+ case R_RX_ABS8:
+ UNSAFE_FOR_PID;
+ RX_STACK_POP (relocation);
+ RANGE (-128, 255);
+ OP (0) = relocation;
+ break;
+
+ case R_RX_ABS8U:
+ UNSAFE_FOR_PID;
+ RX_STACK_POP (relocation);
+ RANGE (0, 255);
+ OP (0) = relocation;
+ break;
+
+ case R_RX_ABS8UL:
+ UNSAFE_FOR_PID;
+ RX_STACK_POP (relocation);
+ relocation >>= 2;
+ RANGE (0, 255);
+ OP (0) = relocation;
+ break;
+
+ case R_RX_ABS8UW:
+ UNSAFE_FOR_PID;
+ RX_STACK_POP (relocation);
+ relocation >>= 1;
+ RANGE (0, 255);
+ OP (0) = relocation;
+ break;
+
+ case R_RX_ABS8S:
+ UNSAFE_FOR_PID;
+ case R_RX_ABS8S_PCREL:
+ RX_STACK_POP (relocation);
+ RANGE (-128, 127);
+ OP (0) = relocation;
+ break;
+
+ case R_RX_SYM:
+ if (r_symndx < symtab_hdr->sh_info)
+ RX_STACK_PUSH (sec->output_section->vma
+ + sec->output_offset
+ + sym->st_value
+ + rel->r_addend);
+ else
+ {
+ if (h != NULL
+ && (h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak))
+ RX_STACK_PUSH (h->root.u.def.value
+ + sec->output_section->vma
+ + sec->output_offset
+ + rel->r_addend);
+ else
+ _bfd_error_handler (_("Warning: RX_SYM reloc with an unknown symbol"));
+ }
+ break;
+
+ case R_RX_OPneg:
+ {
+ int32_t tmp;
+
+ saw_subtract = TRUE;
+ RX_STACK_POP (tmp);
+ tmp = - tmp;
+ RX_STACK_PUSH (tmp);
+ }
+ break;
+
+ case R_RX_OPadd:
+ {
+ int32_t tmp1, tmp2;
+
+ RX_STACK_POP (tmp1);
+ RX_STACK_POP (tmp2);
+ tmp1 += tmp2;
+ RX_STACK_PUSH (tmp1);
+ }
+ break;
+
+ case R_RX_OPsub:
+ {
+ int32_t tmp1, tmp2;
+
+ saw_subtract = TRUE;
+ RX_STACK_POP (tmp1);
+ RX_STACK_POP (tmp2);
+ tmp2 -= tmp1;
+ RX_STACK_PUSH (tmp2);
+ }
+ break;
+
+ case R_RX_OPmul:
+ {
+ int32_t tmp1, tmp2;
+
+ RX_STACK_POP (tmp1);
+ RX_STACK_POP (tmp2);
+ tmp1 *= tmp2;
+ RX_STACK_PUSH (tmp1);
+ }
+ break;
+
+ case R_RX_OPdiv:
+ {
+ int32_t tmp1, tmp2;
+
+ RX_STACK_POP (tmp1);
+ RX_STACK_POP (tmp2);
+ tmp1 /= tmp2;
+ RX_STACK_PUSH (tmp1);
+ }
+ break;
+
+ case R_RX_OPshla:
+ {
+ int32_t tmp1, tmp2;
+
+ RX_STACK_POP (tmp1);
+ RX_STACK_POP (tmp2);
+ tmp1 <<= tmp2;
+ RX_STACK_PUSH (tmp1);
+ }
+ break;
+
+ case R_RX_OPshra:
+ {
+ int32_t tmp1, tmp2;
+
+ RX_STACK_POP (tmp1);
+ RX_STACK_POP (tmp2);
+ tmp1 >>= tmp2;
+ RX_STACK_PUSH (tmp1);
+ }
+ break;
+
+ case R_RX_OPsctsize:
+ RX_STACK_PUSH (input_section->size);
+ break;
+
+ case R_RX_OPscttop:
+ RX_STACK_PUSH (input_section->output_section->vma);
+ break;
+
+ case R_RX_OPand:
+ {
+ int32_t tmp1, tmp2;
+
+ RX_STACK_POP (tmp1);
+ RX_STACK_POP (tmp2);
+ tmp1 &= tmp2;
+ RX_STACK_PUSH (tmp1);
+ }
+ break;
+
+ case R_RX_OPor:
+ {
+ int32_t tmp1, tmp2;
+
+ RX_STACK_POP (tmp1);
+ RX_STACK_POP (tmp2);
+ tmp1 |= tmp2;
+ RX_STACK_PUSH (tmp1);
+ }
+ break;
+
+ case R_RX_OPxor:
+ {
+ int32_t tmp1, tmp2;
+
+ RX_STACK_POP (tmp1);
+ RX_STACK_POP (tmp2);
+ tmp1 ^= tmp2;
+ RX_STACK_PUSH (tmp1);
+ }
+ break;
+
+ case R_RX_OPnot:
+ {
+ int32_t tmp;
+
+ RX_STACK_POP (tmp);
+ tmp = ~ tmp;
+ RX_STACK_PUSH (tmp);
+ }
+ break;
+
+ case R_RX_OPmod:
+ {
+ int32_t tmp1, tmp2;
+
+ RX_STACK_POP (tmp1);
+ RX_STACK_POP (tmp2);
+ tmp1 %= tmp2;
+ RX_STACK_PUSH (tmp1);
+ }
+ break;
+
+ case R_RX_OPromtop:
+ RX_STACK_PUSH (get_romstart (&r, info, input_bfd, input_section, rel->r_offset));
+ break;
+
+ case R_RX_OPramtop:
+ RX_STACK_PUSH (get_ramstart (&r, info, input_bfd, input_section, rel->r_offset));
+ break;
+
+ default:
+ r = bfd_reloc_notsupported;
+ break;
+ }
+
+ if (r != bfd_reloc_ok)
+ {
+ const char * msg = NULL;
+
+ switch (r)
+ {
+ case bfd_reloc_overflow:
+ /* Catch the case of a missing function declaration
+ and emit a more helpful error message. */
+ if (r_type == R_RX_DIR24S_PCREL)
+ msg = _("%B(%A): error: call to undefined function '%s'");
+ else
+ r = info->callbacks->reloc_overflow
+ (info, (h ? &h->root : NULL), 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,
+ TRUE);
+ break;
+
+ case bfd_reloc_other:
+ msg = _("%B(%A): warning: unaligned access to symbol '%s' in the small data area");
+ break;
+
+ case bfd_reloc_outofrange:
+ msg = _("%B(%A): internal error: out of range error");
+ break;
+
+ case bfd_reloc_notsupported:
+ msg = _("%B(%A): internal error: unsupported relocation error");
+ break;
+
+ case bfd_reloc_dangerous:
+ msg = _("%B(%A): internal error: dangerous relocation");
+ break;
+
+ default:
+ msg = _("%B(%A): internal error: unknown error");
+ break;
+ }
+
+ if (msg)
+ _bfd_error_handler (msg, input_bfd, input_section, name);
+
+ if (! r)
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+/* Relaxation Support. */
+
+/* Progression of relocations from largest operand size to smallest
+ operand size. */
+
+static int
+next_smaller_reloc (int r)
+{
+ switch (r)
+ {
+ case R_RX_DIR32: return R_RX_DIR24S;
+ case R_RX_DIR24S: return R_RX_DIR16S;
+ case R_RX_DIR16S: return R_RX_DIR8S;
+ case R_RX_DIR8S: return R_RX_NONE;
+
+ case R_RX_DIR16: return R_RX_DIR8;
+ case R_RX_DIR8: return R_RX_NONE;
+
+ case R_RX_DIR16U: return R_RX_DIR8U;
+ case R_RX_DIR8U: return R_RX_NONE;
+
+ case R_RX_DIR24S_PCREL: return R_RX_DIR16S_PCREL;
+ case R_RX_DIR16S_PCREL: return R_RX_DIR8S_PCREL;
+ case R_RX_DIR8S_PCREL: return R_RX_DIR3U_PCREL;
+
+ case R_RX_DIR16UL: return R_RX_DIR8UL;
+ case R_RX_DIR8UL: return R_RX_NONE;
+ case R_RX_DIR16UW: return R_RX_DIR8UW;
+ case R_RX_DIR8UW: return R_RX_NONE;
+
+ case R_RX_RH_32_OP: return R_RX_RH_24_OP;
+ case R_RX_RH_24_OP: return R_RX_RH_16_OP;
+ case R_RX_RH_16_OP: return R_RX_DIR8;
+
+ case R_RX_ABS32: return R_RX_ABS24S;
+ case R_RX_ABS24S: return R_RX_ABS16S;
+ case R_RX_ABS16: return R_RX_ABS8;
+ case R_RX_ABS16U: return R_RX_ABS8U;
+ case R_RX_ABS16S: return R_RX_ABS8S;
+ case R_RX_ABS8: return R_RX_NONE;
+ case R_RX_ABS8U: return R_RX_NONE;
+ case R_RX_ABS8S: return R_RX_NONE;
+ case R_RX_ABS24S_PCREL: return R_RX_ABS16S_PCREL;
+ case R_RX_ABS16S_PCREL: return R_RX_ABS8S_PCREL;
+ case R_RX_ABS8S_PCREL: return R_RX_NONE;
+ case R_RX_ABS16UL: return R_RX_ABS8UL;
+ case R_RX_ABS16UW: return R_RX_ABS8UW;
+ case R_RX_ABS8UL: return R_RX_NONE;
+ case R_RX_ABS8UW: return R_RX_NONE;
+ }
+ return r;
+};
+
+/* Delete some bytes from a section while relaxing. */
+
+static bfd_boolean
+elf32_rx_relax_delete_bytes (bfd *abfd, asection *sec, bfd_vma addr, int count,
+ Elf_Internal_Rela *alignment_rel, int force_snip)
+{
+ Elf_Internal_Shdr * symtab_hdr;
+ unsigned int sec_shndx;
+ bfd_byte * contents;
+ Elf_Internal_Rela * irel;
+ Elf_Internal_Rela * irelend;
+ Elf_Internal_Sym * isym;
+ Elf_Internal_Sym * isymend;
+ bfd_vma toaddr;
+ unsigned int symcount;
+ struct elf_link_hash_entry ** sym_hashes;
+ struct elf_link_hash_entry ** end_hashes;
+
+ if (!alignment_rel)
+ force_snip = 1;
+
+ sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
+
+ contents = elf_section_data (sec)->this_hdr.contents;
+
+ /* The deletion must stop at the next alignment boundary, if
+ ALIGNMENT_REL is non-NULL. */
+ toaddr = sec->size;
+ if (alignment_rel)
+ toaddr = alignment_rel->r_offset;
+
+ irel = elf_section_data (sec)->relocs;
+ irelend = irel + sec->reloc_count;
+
+ /* Actually delete the bytes. */
+ memmove (contents + addr, contents + addr + count,
+ (size_t) (toaddr - addr - count));
+
+ /* If we don't have an alignment marker to worry about, we can just
+ shrink the section. Otherwise, we have to fill in the newly
+ created gap with NOP insns (0x03). */
+ if (force_snip)
+ sec->size -= count;
+ else
+ memset (contents + toaddr - count, 0x03, 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
+ || (force_snip && irel->r_offset == toaddr)))
+ irel->r_offset -= count;
+
+ /* If we see an ALIGN marker at the end of the gap, we move it
+ to the beginning of the gap, since marking these gaps is what
+ they're for. */
+ if (irel->r_offset == toaddr
+ && ELF32_R_TYPE (irel->r_info) == R_RX_RH_RELAX
+ && irel->r_addend & RX_RELAXA_ALIGN)
+ irel->r_offset -= count;
+ }
+
+ /* Adjust the local symbols defined in this section. */
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+ isym = (Elf_Internal_Sym *) symtab_hdr->contents;
+ isymend = isym + symtab_hdr->sh_info;
+
+ for (; isym < isymend; isym++)
+ {
+ /* If the symbol is in the range of memory we just moved, we
+ have to adjust its value. */
+ if (isym->st_shndx == sec_shndx
+ && isym->st_value > addr
+ && isym->st_value < toaddr)
+ isym->st_value -= count;
+
+ /* If the symbol *spans* the bytes we just deleted (i.e. it's
+ *end* is in the moved bytes but it's *start* isn't), then we
+ must adjust its size. */
+ if (isym->st_shndx == sec_shndx
+ && isym->st_value < addr
+ && isym->st_value + isym->st_size > addr
+ && isym->st_value + isym->st_size < toaddr)
+ isym->st_size -= count;
+ }
+
+ /* Now adjust the global symbols defined in this section. */
+ symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
+ - symtab_hdr->sh_info);
+ sym_hashes = elf_sym_hashes (abfd);
+ end_hashes = sym_hashes + symcount;
+
+ for (; sym_hashes < end_hashes; sym_hashes++)
+ {
+ struct elf_link_hash_entry *sym_hash = *sym_hashes;
+
+ if ((sym_hash->root.type == bfd_link_hash_defined
+ || sym_hash->root.type == bfd_link_hash_defweak)
+ && sym_hash->root.u.def.section == sec)
+ {
+ /* As above, adjust the value if needed. */
+ if (sym_hash->root.u.def.value > addr
+ && sym_hash->root.u.def.value < toaddr)
+ sym_hash->root.u.def.value -= count;
+
+ /* As above, adjust the size if needed. */
+ if (sym_hash->root.u.def.value < addr
+ && sym_hash->root.u.def.value + sym_hash->size > addr
+ && sym_hash->root.u.def.value + sym_hash->size < toaddr)
+ sym_hash->size -= count;
+ }
+ }
+
+ return TRUE;
+}
+
+/* Used to sort relocs by address. If relocs have the same address,
+ we maintain their relative order, except that R_RX_RH_RELAX
+ alignment relocs must be the first reloc for any given address. */
+
+static void
+reloc_bubblesort (Elf_Internal_Rela * r, int count)
+{
+ int i;
+ bfd_boolean again;
+ bfd_boolean swappit;
+
+ /* This is almost a classic bubblesort. It's the slowest sort, but
+ we're taking advantage of the fact that the relocations are
+ mostly in order already (the assembler emits them that way) and
+ we need relocs with the same address to remain in the same
+ relative order. */
+ again = TRUE;
+ while (again)
+ {
+ again = FALSE;
+ for (i = 0; i < count - 1; i ++)
+ {
+ if (r[i].r_offset > r[i + 1].r_offset)
+ swappit = TRUE;
+ else if (r[i].r_offset < r[i + 1].r_offset)
+ swappit = FALSE;
+ else if (ELF32_R_TYPE (r[i + 1].r_info) == R_RX_RH_RELAX
+ && (r[i + 1].r_addend & RX_RELAXA_ALIGN))
+ swappit = TRUE;
+ else if (ELF32_R_TYPE (r[i + 1].r_info) == R_RX_RH_RELAX
+ && (r[i + 1].r_addend & RX_RELAXA_ELIGN)
+ && !(ELF32_R_TYPE (r[i].r_info) == R_RX_RH_RELAX
+ && (r[i].r_addend & RX_RELAXA_ALIGN)))
+ swappit = TRUE;
+ else
+ swappit = FALSE;
+
+ if (swappit)
+ {
+ Elf_Internal_Rela tmp;
+
+ tmp = r[i];
+ r[i] = r[i + 1];
+ r[i + 1] = tmp;
+ /* If we do move a reloc back, re-scan to see if it
+ needs to be moved even further back. This avoids
+ most of the O(n^2) behavior for our cases. */
+ if (i > 0)
+ i -= 2;
+ again = TRUE;
+ }
+ }
+ }
+}
+
+
+#define OFFSET_FOR_RELOC(rel, lrel, scale) \
+ rx_offset_for_reloc (abfd, rel + 1, symtab_hdr, shndx_buf, intsyms, \
+ lrel, abfd, sec, link_info, scale)
+
+static bfd_vma
+rx_offset_for_reloc (bfd * abfd,
+ Elf_Internal_Rela * rel,
+ Elf_Internal_Shdr * symtab_hdr,
+ Elf_External_Sym_Shndx * shndx_buf ATTRIBUTE_UNUSED,
+ Elf_Internal_Sym * intsyms,
+ Elf_Internal_Rela ** lrel,
+ bfd * input_bfd,
+ asection * input_section,
+ struct bfd_link_info * info,
+ int * scale)
+{
+ bfd_vma symval;
+ bfd_reloc_status_type r;
+
+ *scale = 1;
+
+ /* REL is the first of 1..N relocations. We compute the symbol
+ value for each relocation, then combine them if needed. LREL
+ gets a pointer to the last relocation used. */
+ while (1)
+ {
+ int32_t tmp1, tmp2;
+
+ /* Get the value of the symbol referred to by the reloc. */
+ if (ELF32_R_SYM (rel->r_info) < symtab_hdr->sh_info)
+ {
+ /* A local symbol. */
+ Elf_Internal_Sym *isym;
+ asection *ssec;
+
+ isym = intsyms + ELF32_R_SYM (rel->r_info);
+
+ if (isym->st_shndx == SHN_UNDEF)
+ ssec = bfd_und_section_ptr;
+ else if (isym->st_shndx == SHN_ABS)
+ ssec = bfd_abs_section_ptr;
+ else if (isym->st_shndx == SHN_COMMON)
+ ssec = bfd_com_section_ptr;
+ else
+ ssec = bfd_section_from_elf_index (abfd,
+ isym->st_shndx);
+
+ /* Initial symbol value. */
+ symval = isym->st_value;
+
+ /* GAS may have made this symbol relative to a section, in
+ which case, we have to add the addend to find the
+ symbol. */
+ if (ELF_ST_TYPE (isym->st_info) == STT_SECTION)
+ symval += rel->r_addend;
+
+ if (ssec)
+ {
+ if ((ssec->flags & SEC_MERGE)
+ && ssec->sec_info_type == SEC_INFO_TYPE_MERGE)
+ symval = _bfd_merged_section_offset (abfd, & ssec,
+ elf_section_data (ssec)->sec_info,
+ symval);
+ }
+
+ /* Now make the offset relative to where the linker is putting it. */
+ if (ssec)
+ symval +=
+ ssec->output_section->vma + ssec->output_offset;
+
+ symval += rel->r_addend;
+ }
+ else
+ {
+ unsigned long indx;
+ struct elf_link_hash_entry * h;
+
+ /* An external symbol. */
+ indx = ELF32_R_SYM (rel->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. */
+ if (lrel)
+ *lrel = rel;
+ return 0;
+ }
+
+ symval = (h->root.u.def.value
+ + h->root.u.def.section->output_section->vma
+ + h->root.u.def.section->output_offset);
+
+ symval += rel->r_addend;
+ }
+
+ switch (ELF32_R_TYPE (rel->r_info))
+ {
+ case R_RX_SYM:
+ RX_STACK_PUSH (symval);
+ break;
+
+ case R_RX_OPneg:
+ RX_STACK_POP (tmp1);
+ tmp1 = - tmp1;
+ RX_STACK_PUSH (tmp1);
+ break;
+
+ case R_RX_OPadd:
+ RX_STACK_POP (tmp1);
+ RX_STACK_POP (tmp2);
+ tmp1 += tmp2;
+ RX_STACK_PUSH (tmp1);
+ break;
+
+ case R_RX_OPsub:
+ RX_STACK_POP (tmp1);
+ RX_STACK_POP (tmp2);
+ tmp2 -= tmp1;
+ RX_STACK_PUSH (tmp2);
+ break;
+
+ case R_RX_OPmul:
+ RX_STACK_POP (tmp1);
+ RX_STACK_POP (tmp2);
+ tmp1 *= tmp2;
+ RX_STACK_PUSH (tmp1);
+ break;
+
+ case R_RX_OPdiv:
+ RX_STACK_POP (tmp1);
+ RX_STACK_POP (tmp2);
+ tmp1 /= tmp2;
+ RX_STACK_PUSH (tmp1);
+ break;
+
+ case R_RX_OPshla:
+ RX_STACK_POP (tmp1);
+ RX_STACK_POP (tmp2);
+ tmp1 <<= tmp2;
+ RX_STACK_PUSH (tmp1);
+ break;
+
+ case R_RX_OPshra:
+ RX_STACK_POP (tmp1);
+ RX_STACK_POP (tmp2);
+ tmp1 >>= tmp2;
+ RX_STACK_PUSH (tmp1);
+ break;
+
+ case R_RX_OPsctsize:
+ RX_STACK_PUSH (input_section->size);
+ break;
+
+ case R_RX_OPscttop:
+ RX_STACK_PUSH (input_section->output_section->vma);
+ break;
+
+ case R_RX_OPand:
+ RX_STACK_POP (tmp1);
+ RX_STACK_POP (tmp2);
+ tmp1 &= tmp2;
+ RX_STACK_PUSH (tmp1);
+ break;
+
+ case R_RX_OPor:
+ RX_STACK_POP (tmp1);
+ RX_STACK_POP (tmp2);
+ tmp1 |= tmp2;
+ RX_STACK_PUSH (tmp1);
+ break;
+
+ case R_RX_OPxor:
+ RX_STACK_POP (tmp1);
+ RX_STACK_POP (tmp2);
+ tmp1 ^= tmp2;
+ RX_STACK_PUSH (tmp1);
+ break;
+
+ case R_RX_OPnot:
+ RX_STACK_POP (tmp1);
+ tmp1 = ~ tmp1;
+ RX_STACK_PUSH (tmp1);
+ break;
+
+ case R_RX_OPmod:
+ RX_STACK_POP (tmp1);
+ RX_STACK_POP (tmp2);
+ tmp1 %= tmp2;
+ RX_STACK_PUSH (tmp1);
+ break;
+
+ case R_RX_OPromtop:
+ RX_STACK_PUSH (get_romstart (&r, info, input_bfd, input_section, rel->r_offset));
+ break;
+
+ case R_RX_OPramtop:
+ RX_STACK_PUSH (get_ramstart (&r, info, input_bfd, input_section, rel->r_offset));
+ break;
+
+ case R_RX_DIR16UL:
+ case R_RX_DIR8UL:
+ case R_RX_ABS16UL:
+ case R_RX_ABS8UL:
+ if (rx_stack_top)
+ RX_STACK_POP (symval);
+ if (lrel)
+ *lrel = rel;
+ *scale = 4;
+ return symval;
+
+ case R_RX_DIR16UW:
+ case R_RX_DIR8UW:
+ case R_RX_ABS16UW:
+ case R_RX_ABS8UW:
+ if (rx_stack_top)
+ RX_STACK_POP (symval);
+ if (lrel)
+ *lrel = rel;
+ *scale = 2;
+ return symval;
+
+ default:
+ if (rx_stack_top)
+ RX_STACK_POP (symval);
+ if (lrel)
+ *lrel = rel;
+ return symval;
+ }
+
+ rel ++;
+ }
+}
+
+static void
+move_reloc (Elf_Internal_Rela * irel, Elf_Internal_Rela * srel, int delta)
+{
+ bfd_vma old_offset = srel->r_offset;
+
+ irel ++;
+ while (irel <= srel)
+ {
+ if (irel->r_offset == old_offset)
+ irel->r_offset += delta;
+ irel ++;
+ }
+}
+
+/* Relax one section. */
+
+static bfd_boolean
+elf32_rx_relax_section (bfd * abfd,
+ asection * sec,
+ struct bfd_link_info * link_info,
+ bfd_boolean * again,
+ bfd_boolean allow_pcrel3)
+{
+ Elf_Internal_Shdr * symtab_hdr;
+ Elf_Internal_Shdr * shndx_hdr;
+ Elf_Internal_Rela * internal_relocs;
+ Elf_Internal_Rela * free_relocs = NULL;
+ Elf_Internal_Rela * irel;
+ Elf_Internal_Rela * srel;
+ Elf_Internal_Rela * irelend;
+ Elf_Internal_Rela * next_alignment;
+ Elf_Internal_Rela * prev_alignment;
+ bfd_byte * contents = NULL;
+ bfd_byte * free_contents = NULL;
+ Elf_Internal_Sym * intsyms = NULL;
+ Elf_Internal_Sym * free_intsyms = NULL;
+ Elf_External_Sym_Shndx * shndx_buf = NULL;
+ bfd_vma pc;
+ bfd_vma sec_start;
+ bfd_vma symval = 0;
+ int pcrel = 0;
+ int code = 0;
+ int section_alignment_glue;
+ /* how much to scale the relocation by - 1, 2, or 4. */
+ int scale;
+
+ /* Assume nothing changes. */
+ *again = FALSE;
+
+ /* We don't have to do anything for a relocatable link, if
+ this section does not have relocs, or if this is not a
+ code section. */
+ if (link_info->relocatable
+ || (sec->flags & SEC_RELOC) == 0
+ || sec->reloc_count == 0
+ || (sec->flags & SEC_CODE) == 0)
+ return TRUE;
+
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+ shndx_hdr = &elf_tdata (abfd)->symtab_shndx_hdr;
+
+ sec_start = sec->output_section->vma + sec->output_offset;
+
+ /* Get the section contents. */
+ if (elf_section_data (sec)->this_hdr.contents != NULL)
+ contents = elf_section_data (sec)->this_hdr.contents;
+ /* Go get them off disk. */
+ else
+ {
+ if (! bfd_malloc_and_get_section (abfd, sec, &contents))
+ goto error_return;
+ elf_section_data (sec)->this_hdr.contents = contents;
+ }
+
+ /* Read this BFD's symbols. */
+ /* Get cached copy if it exists. */
+ if (symtab_hdr->contents != NULL)
+ intsyms = (Elf_Internal_Sym *) symtab_hdr->contents;
+ else
+ {
+ intsyms = bfd_elf_get_elf_syms (abfd, symtab_hdr, symtab_hdr->sh_info, 0, NULL, NULL, NULL);
+ symtab_hdr->contents = (bfd_byte *) intsyms;
+ }
+
+ if (shndx_hdr->sh_size != 0)
+ {
+ bfd_size_type amt;
+
+ amt = symtab_hdr->sh_info;
+ amt *= sizeof (Elf_External_Sym_Shndx);
+ shndx_buf = (Elf_External_Sym_Shndx *) bfd_malloc (amt);
+ if (shndx_buf == NULL)
+ goto error_return;
+ if (bfd_seek (abfd, shndx_hdr->sh_offset, SEEK_SET) != 0
+ || bfd_bread (shndx_buf, amt, abfd) != amt)
+ goto error_return;
+ shndx_hdr->contents = (bfd_byte *) shndx_buf;
+ }
+
+ /* Get a copy of the native relocations. */
+ internal_relocs = (_bfd_elf_link_read_relocs
+ (abfd, sec, 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;
+
+ /* The RL_ relocs must be just before the operand relocs they go
+ with, so we must sort them to guarantee this. We use bubblesort
+ instead of qsort so we can guarantee that relocs with the same
+ address remain in the same relative order. */
+ reloc_bubblesort (internal_relocs, sec->reloc_count);
+
+ /* Walk through them looking for relaxing opportunities. */
+ irelend = internal_relocs + sec->reloc_count;
+
+ /* This will either be NULL or a pointer to the next alignment
+ relocation. */
+ next_alignment = internal_relocs;
+ /* This will be the previous alignment, although at first it points
+ to the first real relocation. */
+ prev_alignment = internal_relocs;
+
+ /* We calculate worst case shrinkage caused by alignment directives.
+ No fool-proof, but better than either ignoring the problem or
+ doing heavy duty analysis of all the alignment markers in all
+ input sections. */
+ section_alignment_glue = 0;
+ for (irel = internal_relocs; irel < irelend; irel++)
+ if (ELF32_R_TYPE (irel->r_info) == R_RX_RH_RELAX
+ && irel->r_addend & RX_RELAXA_ALIGN)
+ {
+ int this_glue = 1 << (irel->r_addend & RX_RELAXA_ANUM);
+
+ if (section_alignment_glue < this_glue)
+ section_alignment_glue = this_glue;
+ }
+ /* Worst case is all 0..N alignments, in order, causing 2*N-1 byte
+ shrinkage. */
+ section_alignment_glue *= 2;
+
+ for (irel = internal_relocs; irel < irelend; irel++)
+ {
+ unsigned char *insn;
+ int nrelocs;
+
+ /* The insns we care about are all marked with one of these. */
+ if (ELF32_R_TYPE (irel->r_info) != R_RX_RH_RELAX)
+ continue;
+
+ if (irel->r_addend & RX_RELAXA_ALIGN
+ || next_alignment == internal_relocs)
+ {
+ /* When we delete bytes, we need to maintain all the alignments
+ indicated. In addition, we need to be careful about relaxing
+ jumps across alignment boundaries - these displacements
+ *grow* when we delete bytes. For now, don't shrink
+ displacements across an alignment boundary, just in case.
+ Note that this only affects relocations to the same
+ section. */
+ prev_alignment = next_alignment;
+ next_alignment += 2;
+ while (next_alignment < irelend
+ && (ELF32_R_TYPE (next_alignment->r_info) != R_RX_RH_RELAX
+ || !(next_alignment->r_addend & RX_RELAXA_ELIGN)))
+ next_alignment ++;
+ if (next_alignment >= irelend || next_alignment->r_offset == 0)
+ next_alignment = NULL;
+ }
+
+ /* When we hit alignment markers, see if we've shrunk enough
+ before them to reduce the gap without violating the alignment
+ requirements. */
+ if (irel->r_addend & RX_RELAXA_ALIGN)
+ {
+ /* At this point, the next relocation *should* be the ELIGN
+ end marker. */
+ Elf_Internal_Rela *erel = irel + 1;
+ unsigned int alignment, nbytes;
+
+ if (ELF32_R_TYPE (erel->r_info) != R_RX_RH_RELAX)
+ continue;
+ if (!(erel->r_addend & RX_RELAXA_ELIGN))
+ continue;
+
+ alignment = 1 << (irel->r_addend & RX_RELAXA_ANUM);
+
+ if (erel->r_offset - irel->r_offset < alignment)
+ continue;
+
+ nbytes = erel->r_offset - irel->r_offset;
+ nbytes /= alignment;
+ nbytes *= alignment;
+
+ elf32_rx_relax_delete_bytes (abfd, sec, erel->r_offset-nbytes, nbytes, next_alignment,
+ erel->r_offset == sec->size);
+ *again = TRUE;
+
+ continue;
+ }
+
+ if (irel->r_addend & RX_RELAXA_ELIGN)
+ continue;
+
+ insn = contents + irel->r_offset;
+
+ nrelocs = irel->r_addend & RX_RELAXA_RNUM;
+
+ /* At this point, we have an insn that is a candidate for linker
+ relaxation. There are NRELOCS relocs following that may be
+ relaxed, although each reloc may be made of more than one
+ reloc entry (such as gp-rel symbols). */
+
+ /* Get the value of the symbol referred to by the reloc. Just
+ in case this is the last reloc in the list, use the RL's
+ addend to choose between this reloc (no addend) or the next
+ (yes addend, which means at least one following reloc). */
+
+ /* srel points to the "current" reloction for this insn -
+ actually the last reloc for a given operand, which is the one
+ we need to update. We check the relaxations in the same
+ order that the relocations happen, so we'll just push it
+ along as we go. */
+ srel = irel;
+
+ pc = sec->output_section->vma + sec->output_offset
+ + srel->r_offset;
+
+#define GET_RELOC \
+ symval = OFFSET_FOR_RELOC (srel, &srel, &scale); \
+ pcrel = symval - pc + srel->r_addend; \
+ nrelocs --;
+
+#define SNIPNR(offset, nbytes) \
+ elf32_rx_relax_delete_bytes (abfd, sec, (insn - contents) + offset, nbytes, next_alignment, 0);
+#define SNIP(offset, nbytes, newtype) \
+ SNIPNR (offset, nbytes); \
+ srel->r_info = ELF32_R_INFO (ELF32_R_SYM (srel->r_info), newtype)
+
+ /* The order of these bit tests must match the order that the
+ relocs appear in. Since we sorted those by offset, we can
+ predict them. */
+
+ /* Note that the numbers in, say, DSP6 are the bit offsets of
+ the code fields that describe the operand. Bits number 0 for
+ the MSB of insn[0]. */
+
+ /* DSP* codes:
+ 0 00 [reg]
+ 1 01 dsp:8[reg]
+ 2 10 dsp:16[reg]
+ 3 11 reg */
+ if (irel->r_addend & RX_RELAXA_DSP6)
+ {
+ GET_RELOC;
+
+ code = insn[0] & 3;
+ if (code == 2 && symval/scale <= 255)
+ {
+ unsigned int newrel = ELF32_R_TYPE (srel->r_info);
+ insn[0] &= 0xfc;
+ insn[0] |= 0x01;
+ newrel = next_smaller_reloc (ELF32_R_TYPE (srel->r_info));
+ if (newrel != ELF32_R_TYPE (srel->r_info))
+ {
+ SNIP (3, 1, newrel);
+ *again = TRUE;
+ }
+ }
+
+ else if (code == 1 && symval == 0)
+ {
+ insn[0] &= 0xfc;
+ SNIP (2, 1, R_RX_NONE);
+ *again = TRUE;
+ }
+
+ /* Special case DSP:5 format: MOV.bwl dsp:5[Rsrc],Rdst. */
+ else if (code == 1 && symval/scale <= 31
+ /* Decodable bits. */
+ && (insn[0] & 0xcc) == 0xcc
+ /* Width. */
+ && (insn[0] & 0x30) != 0x30
+ /* Register MSBs. */
+ && (insn[1] & 0x88) == 0x00)
+ {
+ int newrel = 0;
+
+ insn[0] = 0x88 | (insn[0] & 0x30);
+ /* The register fields are in the right place already. */
+
+ /* We can't relax this new opcode. */
+ irel->r_addend = 0;
+
+ switch ((insn[0] & 0x30) >> 4)
+ {
+ case 0:
+ newrel = R_RX_RH_ABS5p5B;
+ break;
+ case 1:
+ newrel = R_RX_RH_ABS5p5W;
+ break;
+ case 2:
+ newrel = R_RX_RH_ABS5p5L;
+ break;
+ }
+
+ move_reloc (irel, srel, -2);
+ SNIP (2, 1, newrel);
+ }
+
+ /* Special case DSP:5 format: MOVU.bw dsp:5[Rsrc],Rdst. */
+ else if (code == 1 && symval/scale <= 31
+ /* Decodable bits. */
+ && (insn[0] & 0xf8) == 0x58
+ /* Register MSBs. */
+ && (insn[1] & 0x88) == 0x00)
+ {
+ int newrel = 0;
+
+ insn[0] = 0xb0 | ((insn[0] & 0x04) << 1);
+ /* The register fields are in the right place already. */
+
+ /* We can't relax this new opcode. */
+ irel->r_addend = 0;
+
+ switch ((insn[0] & 0x08) >> 3)
+ {
+ case 0:
+ newrel = R_RX_RH_ABS5p5B;
+ break;
+ case 1:
+ newrel = R_RX_RH_ABS5p5W;
+ break;
+ }
+
+ move_reloc (irel, srel, -2);
+ SNIP (2, 1, newrel);
+ }
+ }
+
+ /* A DSP4 operand always follows a DSP6 operand, even if there's
+ no relocation for it. We have to read the code out of the
+ opcode to calculate the offset of the operand. */
+ if (irel->r_addend & RX_RELAXA_DSP4)
+ {
+ int code6, offset = 0;
+
+ GET_RELOC;
+
+ code6 = insn[0] & 0x03;
+ switch (code6)
+ {
+ case 0: offset = 2; break;
+ case 1: offset = 3; break;
+ case 2: offset = 4; break;
+ case 3: offset = 2; break;
+ }
+
+ code = (insn[0] & 0x0c) >> 2;
+
+ if (code == 2 && symval / scale <= 255)
+ {
+ unsigned int newrel = ELF32_R_TYPE (srel->r_info);
+
+ insn[0] &= 0xf3;
+ insn[0] |= 0x04;
+ newrel = next_smaller_reloc (ELF32_R_TYPE (srel->r_info));
+ if (newrel != ELF32_R_TYPE (srel->r_info))
+ {
+ SNIP (offset+1, 1, newrel);
+ *again = TRUE;
+ }
+ }
+
+ else if (code == 1 && symval == 0)
+ {
+ insn[0] &= 0xf3;
+ SNIP (offset, 1, R_RX_NONE);
+ *again = TRUE;
+ }
+ /* Special case DSP:5 format: MOV.bwl Rsrc,dsp:5[Rdst] */
+ else if (code == 1 && symval/scale <= 31
+ /* Decodable bits. */
+ && (insn[0] & 0xc3) == 0xc3
+ /* Width. */
+ && (insn[0] & 0x30) != 0x30
+ /* Register MSBs. */
+ && (insn[1] & 0x88) == 0x00)
+ {
+ int newrel = 0;
+
+ insn[0] = 0x80 | (insn[0] & 0x30);
+ /* The register fields are in the right place already. */
+
+ /* We can't relax this new opcode. */
+ irel->r_addend = 0;
+
+ switch ((insn[0] & 0x30) >> 4)
+ {
+ case 0:
+ newrel = R_RX_RH_ABS5p5B;
+ break;
+ case 1:
+ newrel = R_RX_RH_ABS5p5W;
+ break;
+ case 2:
+ newrel = R_RX_RH_ABS5p5L;
+ break;
+ }
+
+ move_reloc (irel, srel, -2);
+ SNIP (2, 1, newrel);
+ }
+ }
+
+ /* These always occur alone, but the offset depends on whether
+ it's a MEMEX opcode (0x06) or not. */
+ if (irel->r_addend & RX_RELAXA_DSP14)
+ {
+ int offset;
+ GET_RELOC;
+
+ if (insn[0] == 0x06)
+ offset = 3;
+ else
+ offset = 4;
+
+ code = insn[1] & 3;
+
+ if (code == 2 && symval / scale <= 255)
+ {
+ unsigned int newrel = ELF32_R_TYPE (srel->r_info);
+
+ insn[1] &= 0xfc;
+ insn[1] |= 0x01;
+ newrel = next_smaller_reloc (ELF32_R_TYPE (srel->r_info));
+ if (newrel != ELF32_R_TYPE (srel->r_info))
+ {
+ SNIP (offset, 1, newrel);
+ *again = TRUE;
+ }
+ }
+ else if (code == 1 && symval == 0)
+ {
+ insn[1] &= 0xfc;
+ SNIP (offset, 1, R_RX_NONE);
+ *again = TRUE;
+ }
+ }
+
+ /* IMM* codes:
+ 0 00 imm:32
+ 1 01 simm:8
+ 2 10 simm:16
+ 3 11 simm:24. */
+
+ /* These always occur alone. */
+ if (irel->r_addend & RX_RELAXA_IMM6)
+ {
+ long ssymval;
+
+ GET_RELOC;
+
+ /* These relocations sign-extend, so we must do signed compares. */
+ ssymval = (long) symval;
+
+ code = insn[0] & 0x03;
+
+ if (code == 0 && ssymval <= 8388607 && ssymval >= -8388608)
+ {
+ unsigned int newrel = ELF32_R_TYPE (srel->r_info);
+
+ insn[0] &= 0xfc;
+ insn[0] |= 0x03;
+ newrel = next_smaller_reloc (ELF32_R_TYPE (srel->r_info));
+ if (newrel != ELF32_R_TYPE (srel->r_info))
+ {
+ SNIP (2, 1, newrel);
+ *again = TRUE;
+ }
+ }
+
+ else if (code == 3 && ssymval <= 32767 && ssymval >= -32768)
+ {
+ unsigned int newrel = ELF32_R_TYPE (srel->r_info);
+
+ insn[0] &= 0xfc;
+ insn[0] |= 0x02;
+ newrel = next_smaller_reloc (ELF32_R_TYPE (srel->r_info));
+ if (newrel != ELF32_R_TYPE (srel->r_info))
+ {
+ SNIP (2, 1, newrel);
+ *again = TRUE;
+ }
+ }
+
+ /* Special case UIMM8 format: CMP #uimm8,Rdst. */
+ else if (code == 2 && ssymval <= 255 && ssymval >= 16
+ /* Decodable bits. */
+ && (insn[0] & 0xfc) == 0x74
+ /* Decodable bits. */
+ && ((insn[1] & 0xf0) == 0x00))
+ {
+ int newrel;
+
+ insn[0] = 0x75;
+ insn[1] = 0x50 | (insn[1] & 0x0f);
+
+ /* We can't relax this new opcode. */
+ irel->r_addend = 0;
+
+ if (STACK_REL_P (ELF32_R_TYPE (srel->r_info)))
+ newrel = R_RX_ABS8U;
+ else
+ newrel = R_RX_DIR8U;
+
+ SNIP (2, 1, newrel);
+ *again = TRUE;
+ }
+
+ else if (code == 2 && ssymval <= 127 && ssymval >= -128)
+ {
+ unsigned int newrel = ELF32_R_TYPE (srel->r_info);
+
+ insn[0] &= 0xfc;
+ insn[0] |= 0x01;
+ newrel = next_smaller_reloc (ELF32_R_TYPE (srel->r_info));
+ if (newrel != ELF32_R_TYPE (srel->r_info))
+ {
+ SNIP (2, 1, newrel);
+ *again = TRUE;
+ }
+ }
+
+ /* Special case UIMM4 format: CMP, MUL, AND, OR. */
+ else if (code == 1 && ssymval <= 15 && ssymval >= 0
+ /* Decodable bits and immediate type. */
+ && insn[0] == 0x75
+ /* Decodable bits. */
+ && (insn[1] & 0xc0) == 0x00)
+ {
+ static const int newop[4] = { 1, 3, 4, 5 };
+
+ insn[0] = 0x60 | newop[insn[1] >> 4];
+ /* The register number doesn't move. */
+
+ /* We can't relax this new opcode. */
+ irel->r_addend = 0;
+
+ move_reloc (irel, srel, -1);
+
+ SNIP (2, 1, R_RX_RH_UIMM4p8);
+ *again = TRUE;
+ }
+
+ /* Special case UIMM4 format: ADD -> ADD/SUB. */
+ else if (code == 1 && ssymval <= 15 && ssymval >= -15
+ /* Decodable bits and immediate type. */
+ && insn[0] == 0x71
+ /* Same register for source and destination. */
+ && ((insn[1] >> 4) == (insn[1] & 0x0f)))
+ {
+ int newrel;
+
+ /* Note that we can't turn "add $0,Rs" into a NOP
+ because the flags need to be set right. */
+
+ if (ssymval < 0)
+ {
+ insn[0] = 0x60; /* Subtract. */
+ newrel = R_RX_RH_UNEG4p8;
+ }
+ else
+ {
+ insn[0] = 0x62; /* Add. */
+ newrel = R_RX_RH_UIMM4p8;
+ }
+
+ /* The register number is in the right place. */
+
+ /* We can't relax this new opcode. */
+ irel->r_addend = 0;
+
+ move_reloc (irel, srel, -1);
+
+ SNIP (2, 1, newrel);
+ *again = TRUE;
+ }
+ }
+
+ /* These are either matched with a DSP6 (2-byte base) or an id24
+ (3-byte base). */
+ if (irel->r_addend & RX_RELAXA_IMM12)
+ {
+ int dspcode, offset = 0;
+ long ssymval;
+
+ GET_RELOC;
+
+ if ((insn[0] & 0xfc) == 0xfc)
+ dspcode = 1; /* Just something with one byte operand. */
+ else
+ dspcode = insn[0] & 3;
+ switch (dspcode)
+ {
+ case 0: offset = 2; break;
+ case 1: offset = 3; break;
+ case 2: offset = 4; break;
+ case 3: offset = 2; break;
+ }
+
+ /* These relocations sign-extend, so we must do signed compares. */
+ ssymval = (long) symval;
+
+ code = (insn[1] >> 2) & 3;
+ if (code == 0 && ssymval <= 8388607 && ssymval >= -8388608)
+ {
+ unsigned int newrel = ELF32_R_TYPE (srel->r_info);
+
+ insn[1] &= 0xf3;
+ insn[1] |= 0x0c;
+ newrel = next_smaller_reloc (ELF32_R_TYPE (srel->r_info));
+ if (newrel != ELF32_R_TYPE (srel->r_info))
+ {
+ SNIP (offset, 1, newrel);
+ *again = TRUE;
+ }
+ }
+
+ else if (code == 3 && ssymval <= 32767 && ssymval >= -32768)
+ {
+ unsigned int newrel = ELF32_R_TYPE (srel->r_info);
+
+ insn[1] &= 0xf3;
+ insn[1] |= 0x08;
+ newrel = next_smaller_reloc (ELF32_R_TYPE (srel->r_info));
+ if (newrel != ELF32_R_TYPE (srel->r_info))
+ {
+ SNIP (offset, 1, newrel);
+ *again = TRUE;
+ }
+ }
+
+ /* Special case UIMM8 format: MOV #uimm8,Rdst. */
+ else if (code == 2 && ssymval <= 255 && ssymval >= 16
+ /* Decodable bits. */
+ && insn[0] == 0xfb
+ /* Decodable bits. */
+ && ((insn[1] & 0x03) == 0x02))
+ {
+ int newrel;
+
+ insn[0] = 0x75;
+ insn[1] = 0x40 | (insn[1] >> 4);
+
+ /* We can't relax this new opcode. */
+ irel->r_addend = 0;
+
+ if (STACK_REL_P (ELF32_R_TYPE (srel->r_info)))
+ newrel = R_RX_ABS8U;
+ else
+ newrel = R_RX_DIR8U;
+
+ SNIP (2, 1, newrel);
+ *again = TRUE;
+ }
+
+ else if (code == 2 && ssymval <= 127 && ssymval >= -128)
+ {
+ unsigned int newrel = ELF32_R_TYPE(srel->r_info);
+
+ insn[1] &= 0xf3;
+ insn[1] |= 0x04;
+ newrel = next_smaller_reloc (ELF32_R_TYPE (srel->r_info));
+ if (newrel != ELF32_R_TYPE(srel->r_info))
+ {
+ SNIP (offset, 1, newrel);
+ *again = TRUE;
+ }
+ }
+
+ /* Special case UIMM4 format: MOV #uimm4,Rdst. */
+ else if (code == 1 && ssymval <= 15 && ssymval >= 0
+ /* Decodable bits. */
+ && insn[0] == 0xfb
+ /* Decodable bits. */
+ && ((insn[1] & 0x03) == 0x02))
+ {
+ insn[0] = 0x66;
+ insn[1] = insn[1] >> 4;
+
+ /* We can't relax this new opcode. */
+ irel->r_addend = 0;
+
+ move_reloc (irel, srel, -1);
+
+ SNIP (2, 1, R_RX_RH_UIMM4p8);
+ *again = TRUE;
+ }
+ }
+
+ if (irel->r_addend & RX_RELAXA_BRA)
+ {
+ unsigned int newrel = ELF32_R_TYPE (srel->r_info);
+ int max_pcrel3 = 4;
+ int alignment_glue = 0;
+
+ GET_RELOC;
+
+ /* Branches over alignment chunks are problematic, as
+ deleting bytes here makes the branch *further* away. We
+ can be agressive with branches within this alignment
+ block, but not branches outside it. */
+ if ((prev_alignment == NULL
+ || symval < (bfd_vma)(sec_start + prev_alignment->r_offset))
+ && (next_alignment == NULL
+ || symval > (bfd_vma)(sec_start + next_alignment->r_offset)))
+ alignment_glue = section_alignment_glue;
+
+ if (ELF32_R_TYPE(srel[1].r_info) == R_RX_RH_RELAX
+ && srel[1].r_addend & RX_RELAXA_BRA
+ && srel[1].r_offset < irel->r_offset + pcrel)
+ max_pcrel3 ++;
+
+ newrel = next_smaller_reloc (ELF32_R_TYPE (srel->r_info));
+
+ /* The values we compare PCREL with are not what you'd
+ expect; they're off by a little to compensate for (1)
+ where the reloc is relative to the insn, and (2) how much
+ the insn is going to change when we relax it. */
+
+ /* These we have to decode. */
+ switch (insn[0])
+ {
+ case 0x04: /* BRA pcdsp:24 */
+ if (-32768 + alignment_glue <= pcrel
+ && pcrel <= 32765 - alignment_glue)
+ {
+ insn[0] = 0x38;
+ SNIP (3, 1, newrel);
+ *again = TRUE;
+ }
+ break;
+
+ case 0x38: /* BRA pcdsp:16 */
+ if (-128 + alignment_glue <= pcrel
+ && pcrel <= 127 - alignment_glue)
+ {
+ insn[0] = 0x2e;
+ SNIP (2, 1, newrel);
+ *again = TRUE;
+ }
+ break;
+
+ case 0x2e: /* BRA pcdsp:8 */
+ /* Note that there's a risk here of shortening things so
+ much that we no longer fit this reloc; it *should*
+ only happen when you branch across a branch, and that
+ branch also devolves into BRA.S. "Real" code should
+ be OK. */
+ if (max_pcrel3 + alignment_glue <= pcrel
+ && pcrel <= 10 - alignment_glue
+ && allow_pcrel3)
+ {
+ insn[0] = 0x08;
+ SNIP (1, 1, newrel);
+ move_reloc (irel, srel, -1);
+ *again = TRUE;
+ }
+ break;
+
+ case 0x05: /* BSR pcdsp:24 */
+ if (-32768 + alignment_glue <= pcrel
+ && pcrel <= 32765 - alignment_glue)
+ {
+ insn[0] = 0x39;
+ SNIP (1, 1, newrel);
+ *again = TRUE;
+ }
+ break;
+
+ case 0x3a: /* BEQ.W pcdsp:16 */
+ case 0x3b: /* BNE.W pcdsp:16 */
+ if (-128 + alignment_glue <= pcrel
+ && pcrel <= 127 - alignment_glue)
+ {
+ insn[0] = 0x20 | (insn[0] & 1);
+ SNIP (1, 1, newrel);
+ *again = TRUE;
+ }
+ break;
+
+ case 0x20: /* BEQ.B pcdsp:8 */
+ case 0x21: /* BNE.B pcdsp:8 */
+ if (max_pcrel3 + alignment_glue <= pcrel
+ && pcrel - alignment_glue <= 10
+ && allow_pcrel3)
+ {
+ insn[0] = 0x10 | ((insn[0] & 1) << 3);
+ SNIP (1, 1, newrel);
+ move_reloc (irel, srel, -1);
+ *again = TRUE;
+ }
+ break;
+
+ case 0x16: /* synthetic BNE dsp24 */
+ case 0x1e: /* synthetic BEQ dsp24 */
+ if (-32767 + alignment_glue <= pcrel
+ && pcrel <= 32766 - alignment_glue
+ && insn[1] == 0x04)
+ {
+ if (insn[0] == 0x16)
+ insn[0] = 0x3b;
+ else
+ insn[0] = 0x3a;
+ /* We snip out the bytes at the end else the reloc
+ will get moved too, and too much. */
+ SNIP (3, 2, newrel);
+ move_reloc (irel, srel, -1);
+ *again = TRUE;
+ }
+ break;
+ }
+
+ /* Special case - synthetic conditional branches, pcrel24.
+ Note that EQ and NE have been handled above. */
+ if ((insn[0] & 0xf0) == 0x20
+ && insn[1] == 0x06
+ && insn[2] == 0x04
+ && srel->r_offset != irel->r_offset + 1
+ && -32767 + alignment_glue <= pcrel
+ && pcrel <= 32766 - alignment_glue)
+ {
+ insn[1] = 0x05;
+ insn[2] = 0x38;
+ SNIP (5, 1, newrel);
+ *again = TRUE;
+ }
+
+ /* Special case - synthetic conditional branches, pcrel16 */
+ if ((insn[0] & 0xf0) == 0x20
+ && insn[1] == 0x05
+ && insn[2] == 0x38
+ && srel->r_offset != irel->r_offset + 1
+ && -127 + alignment_glue <= pcrel
+ && pcrel <= 126 - alignment_glue)
+ {
+ int cond = (insn[0] & 0x0f) ^ 0x01;
+
+ insn[0] = 0x20 | cond;
+ /* By moving the reloc first, we avoid having
+ delete_bytes move it also. */
+ move_reloc (irel, srel, -2);
+ SNIP (2, 3, newrel);
+ *again = TRUE;
+ }
+ }
+
+ BFD_ASSERT (nrelocs == 0);
+
+ /* Special case - check MOV.bwl #IMM, dsp[reg] and see if we can
+ use MOV.bwl #uimm:8, dsp:5[r7] format. This is tricky
+ because it may have one or two relocations. */
+ if ((insn[0] & 0xfc) == 0xf8
+ && (insn[1] & 0x80) == 0x00
+ && (insn[0] & 0x03) != 0x03)
+ {
+ int dcode, icode, reg, ioff, dscale, ilen;
+ bfd_vma disp_val = 0;
+ long imm_val = 0;
+ Elf_Internal_Rela * disp_rel = 0;
+ Elf_Internal_Rela * imm_rel = 0;
+
+ /* Reset this. */
+ srel = irel;
+
+ dcode = insn[0] & 0x03;
+ icode = (insn[1] >> 2) & 0x03;
+ reg = (insn[1] >> 4) & 0x0f;
+
+ ioff = dcode == 1 ? 3 : dcode == 2 ? 4 : 2;
+
+ /* Figure out what the dispacement is. */
+ if (dcode == 1 || dcode == 2)
+ {
+ /* There's a displacement. See if there's a reloc for it. */
+ if (srel[1].r_offset == irel->r_offset + 2)
+ {
+ GET_RELOC;
+ disp_val = symval;
+ disp_rel = srel;
+ }
+ else
+ {
+ if (dcode == 1)
+ disp_val = insn[2];
+ else
+ {
+#if RX_OPCODE_BIG_ENDIAN
+ disp_val = insn[2] * 256 + insn[3];
+#else
+ disp_val = insn[2] + insn[3] * 256;
+#endif
+ }
+ switch (insn[1] & 3)
+ {
+ case 1:
+ disp_val *= 2;
+ scale = 2;
+ break;
+ case 2:
+ disp_val *= 4;
+ scale = 4;
+ break;
+ }
+ }
+ }
+
+ dscale = scale;
+
+ /* Figure out what the immediate is. */
+ if (srel[1].r_offset == irel->r_offset + ioff)
+ {
+ GET_RELOC;
+ imm_val = (long) symval;
+ imm_rel = srel;
+ }
+ else
+ {
+ unsigned char * ip = insn + ioff;
+
+ switch (icode)
+ {
+ case 1:
+ /* For byte writes, we don't sign extend. Makes the math easier later. */
+ if (scale == 1)
+ imm_val = ip[0];
+ else
+ imm_val = (char) ip[0];
+ break;
+ case 2:
+#if RX_OPCODE_BIG_ENDIAN
+ imm_val = ((char) ip[0] << 8) | ip[1];
+#else
+ imm_val = ((char) ip[1] << 8) | ip[0];
+#endif
+ break;
+ case 3:
+#if RX_OPCODE_BIG_ENDIAN
+ imm_val = ((char) ip[0] << 16) | (ip[1] << 8) | ip[2];
+#else
+ imm_val = ((char) ip[2] << 16) | (ip[1] << 8) | ip[0];
+#endif
+ break;
+ case 0:
+#if RX_OPCODE_BIG_ENDIAN
+ imm_val = (ip[0] << 24) | (ip[1] << 16) | (ip[2] << 8) | ip[3];
+#else
+ imm_val = (ip[3] << 24) | (ip[2] << 16) | (ip[1] << 8) | ip[0];
+#endif
+ break;
+ }
+ }
+
+ ilen = 2;
+
+ switch (dcode)
+ {
+ case 1:
+ ilen += 1;
+ break;
+ case 2:
+ ilen += 2;
+ break;
+ }
+
+ switch (icode)
+ {
+ case 1:
+ ilen += 1;
+ break;
+ case 2:
+ ilen += 2;
+ break;
+ case 3:
+ ilen += 3;
+ break;
+ case 4:
+ ilen += 4;
+ break;
+ }
+
+ /* The shortcut happens when the immediate is 0..255,
+ register r0 to r7, and displacement (scaled) 0..31. */
+
+ if (0 <= imm_val && imm_val <= 255
+ && 0 <= reg && reg <= 7
+ && disp_val / dscale <= 31)
+ {
+ insn[0] = 0x3c | (insn[1] & 0x03);
+ insn[1] = (((disp_val / dscale) << 3) & 0x80) | (reg << 4) | ((disp_val/dscale) & 0x0f);
+ insn[2] = imm_val;
+
+ if (disp_rel)
+ {
+ int newrel = R_RX_NONE;
+
+ switch (dscale)
+ {
+ case 1:
+ newrel = R_RX_RH_ABS5p8B;
+ break;
+ case 2:
+ newrel = R_RX_RH_ABS5p8W;
+ break;
+ case 4:
+ newrel = R_RX_RH_ABS5p8L;
+ break;
+ }
+ disp_rel->r_info = ELF32_R_INFO (ELF32_R_SYM (disp_rel->r_info), newrel);
+ move_reloc (irel, disp_rel, -1);
+ }
+ if (imm_rel)
+ {
+ imm_rel->r_info = ELF32_R_INFO (ELF32_R_SYM (imm_rel->r_info), R_RX_DIR8U);
+ move_reloc (disp_rel ? disp_rel : irel,
+ imm_rel,
+ irel->r_offset - imm_rel->r_offset + 2);
+ }
+
+ SNIPNR (3, ilen - 3);
+ *again = TRUE;
+
+ /* We can't relax this new opcode. */
+ irel->r_addend = 0;
+ }
+ }
+ }
+
+ /* We can't reliably relax branches to DIR3U_PCREL unless we know
+ whatever they're branching over won't shrink any more. If we're
+ basically done here, do one more pass just for branches - but
+ don't request a pass after that one! */
+ if (!*again && !allow_pcrel3)
+ {
+ bfd_boolean ignored;
+
+ elf32_rx_relax_section (abfd, sec, link_info, &ignored, TRUE);
+ }
+
+ return TRUE;
+
+ error_return:
+ if (free_relocs != NULL)
+ free (free_relocs);
+
+ if (free_contents != NULL)
+ free (free_contents);
+
+ if (shndx_buf != NULL)
+ {
+ shndx_hdr->contents = NULL;
+ free (shndx_buf);
+ }
+
+ if (free_intsyms != NULL)
+ free (free_intsyms);
+
+ return FALSE;
+}
+
+static bfd_boolean
+elf32_rx_relax_section_wrapper (bfd * abfd,
+ asection * sec,
+ struct bfd_link_info * link_info,
+ bfd_boolean * again)
+{
+ return elf32_rx_relax_section (abfd, sec, link_info, again, FALSE);
+}
+
+/* Function to set the ELF flag bits. */
+
+static bfd_boolean
+rx_elf_set_private_flags (bfd * abfd, flagword flags)
+{
+ elf_elfheader (abfd)->e_flags = flags;
+ elf_flags_init (abfd) = TRUE;
+ return TRUE;
+}
+
+static bfd_boolean no_warn_mismatch = FALSE;
+static bfd_boolean ignore_lma = TRUE;
+
+void bfd_elf32_rx_set_target_flags (bfd_boolean, bfd_boolean);
+
+void
+bfd_elf32_rx_set_target_flags (bfd_boolean user_no_warn_mismatch,
+ bfd_boolean user_ignore_lma)
+{
+ no_warn_mismatch = user_no_warn_mismatch;
+ ignore_lma = user_ignore_lma;
+}
+
+/* Converts FLAGS into a descriptive string.
+ Returns a static pointer. */
+
+static const char *
+describe_flags (flagword flags)
+{
+ static char buf [128];
+
+ buf[0] = 0;
+
+ if (flags & E_FLAG_RX_64BIT_DOUBLES)
+ strcat (buf, "64-bit doubles");
+ else
+ strcat (buf, "32-bit doubles");
+
+ if (flags & E_FLAG_RX_DSP)
+ strcat (buf, ", dsp");
+ else
+ strcat (buf, ", no dsp");
+
+ if (flags & E_FLAG_RX_PID)
+ strcat (buf, ", pid");
+ else
+ strcat (buf, ", no pid");
+
+ if (flags & E_FLAG_RX_ABI)
+ strcat (buf, ", RX ABI");
+ else
+ strcat (buf, ", GCC ABI");
+
+ return buf;
+}
+
+/* Merge backend specific data from an object file to the output
+ object file when linking. */
+
+static bfd_boolean
+rx_elf_merge_private_bfd_data (bfd * ibfd, bfd * obfd)
+{
+ flagword old_flags;
+ flagword new_flags;
+ bfd_boolean error = FALSE;
+
+ 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 (old_flags != new_flags)
+ {
+ flagword known_flags;
+
+ known_flags = E_FLAG_RX_ABI | E_FLAG_RX_64BIT_DOUBLES
+ | E_FLAG_RX_DSP | E_FLAG_RX_PID;
+
+ if ((old_flags ^ new_flags) & known_flags)
+ {
+ /* Only complain if flag bits we care about do not match.
+ Other bits may be set, since older binaries did use some
+ deprecated flags. */
+ if (no_warn_mismatch)
+ {
+ elf_elfheader (obfd)->e_flags = (new_flags | old_flags) & known_flags;
+ }
+ else
+ {
+ _bfd_error_handler ("There is a conflict merging the ELF header flags from %s",
+ bfd_get_filename (ibfd));
+ _bfd_error_handler (" the input file's flags: %s",
+ describe_flags (new_flags));
+ _bfd_error_handler (" the output file's flags: %s",
+ describe_flags (old_flags));
+ error = TRUE;
+ }
+ }
+ else
+ elf_elfheader (obfd)->e_flags = new_flags & known_flags;
+ }
+
+ if (error)
+ bfd_set_error (bfd_error_bad_value);
+
+ return !error;
+}
+
+static bfd_boolean
+rx_elf_print_private_bfd_data (bfd * abfd, void * ptr)
+{
+ FILE * file = (FILE *) ptr;
+ flagword flags;
+
+ BFD_ASSERT (abfd != NULL && ptr != NULL);
+
+ /* Print normal ELF private data. */
+ _bfd_elf_print_private_bfd_data (abfd, ptr);
+
+ flags = elf_elfheader (abfd)->e_flags;
+ fprintf (file, _("private flags = 0x%lx:"), (long) flags);
+
+ fprintf (file, "%s", describe_flags (flags));
+ return TRUE;
+}
+
+/* Return the MACH for an e_flags value. */
+
+static int
+elf32_rx_machine (bfd * abfd ATTRIBUTE_UNUSED)
+{
+#if 0 /* FIXME: EF_RX_CPU_MASK collides with E_FLAG_RX_...
+ Need to sort out how these flag bits are used.
+ For now we assume that the flags are OK. */
+ if ((elf_elfheader (abfd)->e_flags & EF_RX_CPU_MASK) == EF_RX_CPU_RX)
+#endif
+ return bfd_mach_rx;
+
+ return 0;
+}
+
+static bfd_boolean
+rx_elf_object_p (bfd * abfd)
+{
+ int i;
+ unsigned int u;
+ Elf_Internal_Phdr *phdr = elf_tdata (abfd)->phdr;
+ int nphdrs = elf_elfheader (abfd)->e_phnum;
+ sec_ptr bsec;
+ static int saw_be = FALSE;
+
+ /* We never want to automatically choose the non-swapping big-endian
+ target. The user can only get that explicitly, such as with -I
+ and objcopy. */
+ if (abfd->xvec == &rx_elf32_be_ns_vec
+ && abfd->target_defaulted)
+ return FALSE;
+
+ /* BFD->target_defaulted is not set to TRUE when a target is chosen
+ as a fallback, so we check for "scanning" to know when to stop
+ using the non-swapping target. */
+ if (abfd->xvec == &rx_elf32_be_ns_vec
+ && saw_be)
+ return FALSE;
+ if (abfd->xvec == &rx_elf32_be_vec)
+ saw_be = TRUE;
+
+ bfd_default_set_arch_mach (abfd, bfd_arch_rx,
+ elf32_rx_machine (abfd));
+
+ /* For each PHDR in the object, we must find some section that
+ corresponds (based on matching file offsets) and use its VMA
+ information to reconstruct the p_vaddr field we clobbered when we
+ wrote it out. */
+ for (i=0; i<nphdrs; i++)
+ {
+ for (u=0; u<elf_tdata(abfd)->num_elf_sections; u++)
+ {
+ Elf_Internal_Shdr *sec = elf_tdata(abfd)->elf_sect_ptr[u];
+
+ if (phdr[i].p_filesz
+ && phdr[i].p_offset <= (bfd_vma) sec->sh_offset
+ && (bfd_vma)sec->sh_offset <= phdr[i].p_offset + (phdr[i].p_filesz - 1))
+ {
+ /* Found one! The difference between the two addresses,
+ plus the difference between the two file offsets, is
+ enough information to reconstruct the lma. */
+
+ /* Example where they aren't:
+ PHDR[1] = lma fffc0100 offset 00002010 size 00000100
+ SEC[6] = vma 00000050 offset 00002050 size 00000040
+
+ The correct LMA for the section is fffc0140 + (2050-2010).
+ */
+
+ phdr[i].p_vaddr = sec->sh_addr + (sec->sh_offset - phdr[i].p_offset);
+ break;
+ }
+ }
+
+ /* We must update the bfd sections as well, so we don't stop
+ with one match. */
+ bsec = abfd->sections;
+ while (bsec)
+ {
+ if (phdr[i].p_filesz
+ && phdr[i].p_vaddr <= bsec->vma
+ && bsec->vma <= phdr[i].p_vaddr + (phdr[i].p_filesz - 1))
+ {
+ bsec->lma = phdr[i].p_paddr + (bsec->vma - phdr[i].p_vaddr);
+ }
+ bsec = bsec->next;
+ }
+ }
+
+ return TRUE;
+}
+
+
+#ifdef DEBUG
+void
+rx_dump_symtab (bfd * abfd, void * internal_syms, void * external_syms)
+{
+ size_t locsymcount;
+ Elf_Internal_Sym * isymbuf;
+ Elf_Internal_Sym * isymend;
+ Elf_Internal_Sym * isym;
+ Elf_Internal_Shdr * symtab_hdr;
+ bfd_boolean free_internal = FALSE, free_external = FALSE;
+ char * st_info_str;
+ char * st_info_stb_str;
+ char * st_other_str;
+ char * st_shndx_str;
+
+ if (! internal_syms)
+ {
+ internal_syms = bfd_malloc (1000);
+ free_internal = 1;
+ }
+ if (! external_syms)
+ {
+ external_syms = bfd_malloc (1000);
+ free_external = 1;
+ }
+
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+ locsymcount = symtab_hdr->sh_size / get_elf_backend_data (abfd)->s->sizeof_sym;
+ if (free_internal)
+ isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
+ symtab_hdr->sh_info, 0,
+ internal_syms, external_syms, NULL);
+ else
+ isymbuf = internal_syms;
+ isymend = isymbuf + locsymcount;
+
+ for (isym = isymbuf ; isym < isymend ; isym++)
+ {
+ switch (ELF_ST_TYPE (isym->st_info))
+ {
+ case STT_FUNC: st_info_str = "STT_FUNC"; break;
+ case STT_SECTION: st_info_str = "STT_SECTION"; break;
+ case STT_FILE: st_info_str = "STT_FILE"; break;
+ case STT_OBJECT: st_info_str = "STT_OBJECT"; break;
+ case STT_TLS: st_info_str = "STT_TLS"; break;
+ default: st_info_str = "";
+ }
+ switch (ELF_ST_BIND (isym->st_info))
+ {
+ case STB_LOCAL: st_info_stb_str = "STB_LOCAL"; break;
+ case STB_GLOBAL: st_info_stb_str = "STB_GLOBAL"; break;
+ default: st_info_stb_str = "";
+ }
+ switch (ELF_ST_VISIBILITY (isym->st_other))
+ {
+ case STV_DEFAULT: st_other_str = "STV_DEFAULT"; break;
+ case STV_INTERNAL: st_other_str = "STV_INTERNAL"; break;
+ case STV_PROTECTED: st_other_str = "STV_PROTECTED"; break;
+ default: st_other_str = "";
+ }
+ switch (isym->st_shndx)
+ {
+ case SHN_ABS: st_shndx_str = "SHN_ABS"; break;
+ case SHN_COMMON: st_shndx_str = "SHN_COMMON"; break;
+ case SHN_UNDEF: st_shndx_str = "SHN_UNDEF"; break;
+ default: st_shndx_str = "";
+ }
+
+ printf ("isym = %p st_value = %lx st_size = %lx st_name = (%lu) %s "
+ "st_info = (%d) %s %s st_other = (%d) %s st_shndx = (%d) %s\n",
+ isym,
+ (unsigned long) isym->st_value,
+ (unsigned long) isym->st_size,
+ isym->st_name,
+ bfd_elf_string_from_elf_section (abfd, symtab_hdr->sh_link,
+ isym->st_name),
+ isym->st_info, st_info_str, st_info_stb_str,
+ isym->st_other, st_other_str,
+ isym->st_shndx, st_shndx_str);
+ }
+ if (free_internal)
+ free (internal_syms);
+ if (free_external)
+ free (external_syms);
+}
+
+char *
+rx_get_reloc (long reloc)
+{
+ if (0 <= reloc && reloc < R_RX_max)
+ return rx_elf_howto_table[reloc].name;
+ return "";
+}
+#endif /* DEBUG */
+
+
+/* We must take care to keep the on-disk copy of any code sections
+ that are fully linked swapped if the target is big endian, to match
+ the Renesas tools. */
+
+/* The rule is: big endian object that are final-link executables,
+ have code sections stored with 32-bit words swapped relative to
+ what you'd get by default. */
+
+static bfd_boolean
+rx_get_section_contents (bfd * abfd,
+ sec_ptr section,
+ void * location,
+ file_ptr offset,
+ bfd_size_type count)
+{
+ int exec = (abfd->flags & EXEC_P) ? 1 : 0;
+ int s_code = (section->flags & SEC_CODE) ? 1 : 0;
+ bfd_boolean rv;
+
+#ifdef DJDEBUG
+ fprintf (stderr, "dj: get %ld %ld from %s %s e%d sc%d %08lx:%08lx\n",
+ (long) offset, (long) count, section->name,
+ bfd_big_endian(abfd) ? "be" : "le",
+ exec, s_code, (long unsigned) section->filepos,
+ (long unsigned) offset);
+#endif
+
+ if (exec && s_code && bfd_big_endian (abfd))
+ {
+ char * cloc = (char *) location;
+ bfd_size_type cnt, end_cnt;
+
+ rv = TRUE;
+
+ /* Fetch and swap unaligned bytes at the beginning. */
+ if (offset % 4)
+ {
+ char buf[4];
+
+ rv = _bfd_generic_get_section_contents (abfd, section, buf,
+ (offset & -4), 4);
+ if (!rv)
+ return FALSE;
+
+ bfd_putb32 (bfd_getl32 (buf), buf);
+
+ cnt = 4 - (offset % 4);
+ if (cnt > count)
+ cnt = count;
+
+ memcpy (location, buf + (offset % 4), cnt);
+
+ count -= cnt;
+ offset += cnt;
+ cloc += count;
+ }
+
+ end_cnt = count % 4;
+
+ /* Fetch and swap the middle bytes. */
+ if (count >= 4)
+ {
+ rv = _bfd_generic_get_section_contents (abfd, section, cloc, offset,
+ count - end_cnt);
+ if (!rv)
+ return FALSE;
+
+ for (cnt = count; cnt >= 4; cnt -= 4, cloc += 4)
+ bfd_putb32 (bfd_getl32 (cloc), cloc);
+ }
+
+ /* Fetch and swap the end bytes. */
+ if (end_cnt > 0)
+ {
+ char buf[4];
+
+ /* Fetch the end bytes. */
+ rv = _bfd_generic_get_section_contents (abfd, section, buf,
+ offset + count - end_cnt, 4);
+ if (!rv)
+ return FALSE;
+
+ bfd_putb32 (bfd_getl32 (buf), buf);
+ memcpy (cloc, buf, end_cnt);
+ }
+ }
+ else
+ rv = _bfd_generic_get_section_contents (abfd, section, location, offset, count);
+
+ return rv;
+}
+
+#ifdef DJDEBUG
+static bfd_boolean
+rx2_set_section_contents (bfd * abfd,
+ sec_ptr section,
+ const void * location,
+ file_ptr offset,
+ bfd_size_type count)
+{
+ bfd_size_type i;
+
+ fprintf (stderr, " set sec %s %08x loc %p offset %#x count %#x\n",
+ section->name, (unsigned) section->vma, location, (int) offset, (int) count);
+ for (i = 0; i < count; i++)
+ {
+ if (i % 16 == 0 && i > 0)
+ fprintf (stderr, "\n");
+
+ if (i % 16 && i % 4 == 0)
+ fprintf (stderr, " ");
+
+ if (i % 16 == 0)
+ fprintf (stderr, " %08x:", (int) (section->vma + offset + i));
+
+ fprintf (stderr, " %02x", ((unsigned char *) location)[i]);
+ }
+ fprintf (stderr, "\n");
+
+ return _bfd_elf_set_section_contents (abfd, section, location, offset, count);
+}
+#define _bfd_elf_set_section_contents rx2_set_section_contents
+#endif
+
+static bfd_boolean
+rx_set_section_contents (bfd * abfd,
+ sec_ptr section,
+ const void * location,
+ file_ptr offset,
+ bfd_size_type count)
+{
+ bfd_boolean exec = (abfd->flags & EXEC_P) ? TRUE : FALSE;
+ bfd_boolean s_code = (section->flags & SEC_CODE) ? TRUE : FALSE;
+ bfd_boolean rv;
+ char * swapped_data = NULL;
+ bfd_size_type i;
+ bfd_vma caddr = section->vma + offset;
+ file_ptr faddr = 0;
+ bfd_size_type scount;
+
+#ifdef DJDEBUG
+ bfd_size_type i;
+
+ fprintf (stderr, "\ndj: set %ld %ld to %s %s e%d sc%d\n",
+ (long) offset, (long) count, section->name,
+ bfd_big_endian (abfd) ? "be" : "le",
+ exec, s_code);
+
+ for (i = 0; i < count; i++)
+ {
+ int a = section->vma + offset + i;
+
+ if (a % 16 == 0 && a > 0)
+ fprintf (stderr, "\n");
+
+ if (a % 16 && a % 4 == 0)
+ fprintf (stderr, " ");
+
+ if (a % 16 == 0 || i == 0)
+ fprintf (stderr, " %08x:", (int) (section->vma + offset + i));
+
+ fprintf (stderr, " %02x", ((unsigned char *) location)[i]);
+ }
+
+ fprintf (stderr, "\n");
+#endif
+
+ if (! exec || ! s_code || ! bfd_big_endian (abfd))
+ return _bfd_elf_set_section_contents (abfd, section, location, offset, count);
+
+ while (count > 0 && caddr > 0 && caddr % 4)
+ {
+ switch (caddr % 4)
+ {
+ case 0: faddr = offset + 3; break;
+ case 1: faddr = offset + 1; break;
+ case 2: faddr = offset - 1; break;
+ case 3: faddr = offset - 3; break;
+ }
+
+ rv = _bfd_elf_set_section_contents (abfd, section, location, faddr, 1);
+ if (! rv)
+ return rv;
+
+ location ++;
+ offset ++;
+ count --;
+ caddr ++;
+ }
+
+ scount = (int)(count / 4) * 4;
+ if (scount > 0)
+ {
+ char * cloc = (char *) location;
+
+ swapped_data = (char *) bfd_alloc (abfd, count);
+
+ for (i = 0; i < count; i += 4)
+ {
+ bfd_vma v = bfd_getl32 (cloc + i);
+ bfd_putb32 (v, swapped_data + i);
+ }
+
+ rv = _bfd_elf_set_section_contents (abfd, section, swapped_data, offset, scount);
+
+ if (!rv)
+ return rv;
+ }
+
+ count -= scount;
+ location += scount;
+ offset += scount;
+
+ if (count > 0)
+ {
+ caddr = section->vma + offset;
+ while (count > 0)
+ {
+ switch (caddr % 4)
+ {
+ case 0: faddr = offset + 3; break;
+ case 1: faddr = offset + 1; break;
+ case 2: faddr = offset - 1; break;
+ case 3: faddr = offset - 3; break;
+ }
+ rv = _bfd_elf_set_section_contents (abfd, section, location, faddr, 1);
+ if (! rv)
+ return rv;
+
+ location ++;
+ offset ++;
+ count --;
+ caddr ++;
+ }
+ }
+
+ return TRUE;
+}
+
+static bfd_boolean
+rx_final_link (bfd * abfd, struct bfd_link_info * info)
+{
+ asection * o;
+
+ for (o = abfd->sections; o != NULL; o = o->next)
+ {
+#ifdef DJDEBUG
+ fprintf (stderr, "sec %s fl %x vma %lx lma %lx size %lx raw %lx\n",
+ o->name, o->flags, o->vma, o->lma, o->size, o->rawsize);
+#endif
+ if (o->flags & SEC_CODE
+ && bfd_big_endian (abfd)
+ && o->size % 4)
+ {
+#ifdef DJDEBUG
+ fprintf (stderr, "adjusting...\n");
+#endif
+ o->size += 4 - (o->size % 4);
+ }
+ }
+
+ return bfd_elf_final_link (abfd, info);
+}
+
+static bfd_boolean
+elf32_rx_modify_program_headers (bfd * abfd ATTRIBUTE_UNUSED,
+ struct bfd_link_info * info ATTRIBUTE_UNUSED)
+{
+ const struct elf_backend_data * bed;
+ struct elf_obj_tdata * tdata;
+ Elf_Internal_Phdr * phdr;
+ unsigned int count;
+ unsigned int i;
+
+ bed = get_elf_backend_data (abfd);
+ tdata = elf_tdata (abfd);
+ phdr = tdata->phdr;
+ count = elf_program_header_size (abfd) / bed->s->sizeof_phdr;
+
+ if (ignore_lma)
+ for (i = count; i-- != 0;)
+ if (phdr[i].p_type == PT_LOAD)
+ {
+ /* The Renesas tools expect p_paddr to be zero. However,
+ there is no other way to store the writable data in ROM for
+ startup initialization. So, we let the linker *think*
+ we're using paddr and vaddr the "usual" way, but at the
+ last minute we move the paddr into the vaddr (which is what
+ the simulator uses) and zero out paddr. Note that this
+ does not affect the section headers, just the program
+ headers. We hope. */
+ phdr[i].p_vaddr = phdr[i].p_paddr;
+#if 0 /* If we zero out p_paddr, then the LMA in the section table
+ becomes wrong. */
+ phdr[i].p_paddr = 0;
+#endif
+ }
+
+ return TRUE;
+}
+
+/* The default literal sections should always be marked as "code" (i.e.,
+ SHF_EXECINSTR). This is particularly important for big-endian mode
+ when we do not want their contents byte reversed. */
+static const struct bfd_elf_special_section elf32_rx_special_sections[] =
+{
+ { STRING_COMMA_LEN (".init_array"), 0, SHT_INIT_ARRAY, SHF_ALLOC + SHF_EXECINSTR },
+ { STRING_COMMA_LEN (".fini_array"), 0, SHT_FINI_ARRAY, SHF_ALLOC + SHF_EXECINSTR },
+ { STRING_COMMA_LEN (".preinit_array"), 0, SHT_PREINIT_ARRAY, SHF_ALLOC + SHF_EXECINSTR },
+ { NULL, 0, 0, 0, 0 }
+};
+
+typedef struct {
+ bfd *abfd;
+ struct bfd_link_info *info;
+ bfd_vma table_start;
+ int table_size;
+ bfd_vma *table_handlers;
+ bfd_vma table_default_handler;
+ struct bfd_link_hash_entry **table_entries;
+ struct bfd_link_hash_entry *table_default_entry;
+ FILE *mapfile;
+} RX_Table_Info;
+
+static bfd_boolean
+rx_table_find (struct bfd_hash_entry *vent, void *vinfo)
+{
+ RX_Table_Info *info = (RX_Table_Info *)vinfo;
+ struct bfd_link_hash_entry *ent = (struct bfd_link_hash_entry *)vent;
+ const char *name; /* of the symbol we've found */
+ asection *sec;
+ struct bfd *abfd;
+ int idx;
+ const char *tname; /* name of the table */
+ bfd_vma start_addr, end_addr;
+ char *buf;
+ struct bfd_link_hash_entry * h;
+
+ /* We're looking for globally defined symbols of the form
+ $tablestart$<NAME>. */
+ if (ent->type != bfd_link_hash_defined
+ && ent->type != bfd_link_hash_defweak)
+ return TRUE;
+
+ name = ent->root.string;
+ sec = ent->u.def.section;
+ abfd = sec->owner;
+
+ if (strncmp (name, "$tablestart$", 12))
+ return TRUE;
+
+ sec->flags |= SEC_KEEP;
+
+ tname = name + 12;
+
+ start_addr = ent->u.def.value;
+
+ /* At this point, we can't build the table but we can (and must)
+ find all the related symbols and mark their sections as SEC_KEEP
+ so we don't garbage collect them. */
+
+ buf = (char *) malloc (12 + 10 + strlen (tname));
+
+ sprintf (buf, "$tableend$%s", tname);
+ h = bfd_link_hash_lookup (info->info->hash, buf, FALSE, FALSE, TRUE);
+ if (!h || (h->type != bfd_link_hash_defined
+ && h->type != bfd_link_hash_defweak))
+ {
+ _bfd_error_handler (_("%B:%A: table %s missing corresponding %s"),
+ abfd, sec, name, buf);
+ return TRUE;
+ }
+
+ if (h->u.def.section != ent->u.def.section)
+ {
+ _bfd_error_handler (_("%B:%A: %s and %s must be in the same input section"),
+ h->u.def.section->owner, h->u.def.section,
+ name, buf);
+ return TRUE;
+ }
+
+ end_addr = h->u.def.value;
+
+ sprintf (buf, "$tableentry$default$%s", tname);
+ h = bfd_link_hash_lookup (info->info->hash, buf, FALSE, FALSE, TRUE);
+ if (h && (h->type == bfd_link_hash_defined
+ || h->type == bfd_link_hash_defweak))
+ {
+ h->u.def.section->flags |= SEC_KEEP;
+ }
+
+ for (idx = 0; idx < (int) (end_addr - start_addr) / 4; idx ++)
+ {
+ sprintf (buf, "$tableentry$%d$%s", idx, tname);
+ h = bfd_link_hash_lookup (info->info->hash, buf, FALSE, FALSE, TRUE);
+ if (h && (h->type == bfd_link_hash_defined
+ || h->type == bfd_link_hash_defweak))
+ {
+ h->u.def.section->flags |= SEC_KEEP;
+ }
+ }
+
+ /* Return TRUE to keep scanning, FALSE to end the traversal. */
+ return TRUE;
+}
+
+/* We need to check for table entry symbols and build the tables, and
+ we need to do it before the linker does garbage collection. This function is
+ called once per input object file. */
+static bfd_boolean
+rx_check_directives
+ (bfd * abfd ATTRIBUTE_UNUSED,
+ struct bfd_link_info * info ATTRIBUTE_UNUSED)
+{
+ RX_Table_Info stuff;
+
+ stuff.abfd = abfd;
+ stuff.info = info;
+ bfd_hash_traverse (&(info->hash->table), rx_table_find, &stuff);
+
+ return TRUE;
+}
+
+
+static bfd_boolean
+rx_table_map_2 (struct bfd_hash_entry *vent, void *vinfo)
+{
+ RX_Table_Info *info = (RX_Table_Info *)vinfo;
+ struct bfd_link_hash_entry *ent = (struct bfd_link_hash_entry *)vent;
+ int idx;
+ const char *name;
+ bfd_vma addr;
+
+ /* See if the symbol ENT has an address listed in the table, and
+ isn't a debug/special symbol. If so, put it in the table. */
+
+ if (ent->type != bfd_link_hash_defined
+ && ent->type != bfd_link_hash_defweak)
+ return TRUE;
+
+ name = ent->root.string;
+
+ if (name[0] == '$' || name[0] == '.' || name[0] < ' ')
+ return TRUE;
+
+ addr = (ent->u.def.value
+ + ent->u.def.section->output_section->vma
+ + ent->u.def.section->output_offset);
+
+ for (idx = 0; idx < info->table_size; idx ++)
+ if (addr == info->table_handlers[idx])
+ info->table_entries[idx] = ent;
+
+ if (addr == info->table_default_handler)
+ info->table_default_entry = ent;
+
+ return TRUE;
+}
+
+static bfd_boolean
+rx_table_map (struct bfd_hash_entry *vent, void *vinfo)
+{
+ RX_Table_Info *info = (RX_Table_Info *)vinfo;
+ struct bfd_link_hash_entry *ent = (struct bfd_link_hash_entry *)vent;
+ const char *name; /* of the symbol we've found */
+ int idx;
+ const char *tname; /* name of the table */
+ bfd_vma start_addr, end_addr;
+ char *buf;
+ struct bfd_link_hash_entry * h;
+ int need_elipses;
+
+ /* We're looking for globally defined symbols of the form
+ $tablestart$<NAME>. */
+ if (ent->type != bfd_link_hash_defined
+ && ent->type != bfd_link_hash_defweak)
+ return TRUE;
+
+ name = ent->root.string;
+
+ if (strncmp (name, "$tablestart$", 12))
+ return TRUE;
+
+ tname = name + 12;
+ start_addr = (ent->u.def.value
+ + ent->u.def.section->output_section->vma
+ + ent->u.def.section->output_offset);
+
+ buf = (char *) malloc (12 + 10 + strlen (tname));
+
+ sprintf (buf, "$tableend$%s", tname);
+ end_addr = get_symbol_value_maybe (buf, info->info);
+
+ sprintf (buf, "$tableentry$default$%s", tname);
+ h = bfd_link_hash_lookup (info->info->hash, buf, FALSE, FALSE, TRUE);
+ if (h)
+ {
+ info->table_default_handler = (h->u.def.value
+ + h->u.def.section->output_section->vma
+ + h->u.def.section->output_offset);
+ }
+ else
+ /* Zero is a valid handler address! */
+ info->table_default_handler = (bfd_vma) (-1);
+ info->table_default_entry = NULL;
+
+ info->table_start = start_addr;
+ info->table_size = (int) (end_addr - start_addr) / 4;
+ info->table_handlers = (bfd_vma *) malloc (info->table_size * sizeof (bfd_vma));
+ info->table_entries = (struct bfd_link_hash_entry **) malloc (info->table_size * sizeof (struct bfd_link_hash_entry));
+
+ for (idx = 0; idx < (int) (end_addr - start_addr) / 4; idx ++)
+ {
+ sprintf (buf, "$tableentry$%d$%s", idx, tname);
+ h = bfd_link_hash_lookup (info->info->hash, buf, FALSE, FALSE, TRUE);
+ if (h && (h->type == bfd_link_hash_defined
+ || h->type == bfd_link_hash_defweak))
+ {
+ info->table_handlers[idx] = (h->u.def.value
+ + h->u.def.section->output_section->vma
+ + h->u.def.section->output_offset);
+ }
+ else
+ info->table_handlers[idx] = info->table_default_handler;
+ info->table_entries[idx] = NULL;
+ }
+
+ free (buf);
+
+ bfd_hash_traverse (&(info->info->hash->table), rx_table_map_2, info);
+
+ fprintf (info->mapfile, "\nRX Vector Table: %s has %d entries at 0x%08" BFD_VMA_FMT "x\n\n",
+ tname, info->table_size, start_addr);
+
+ if (info->table_default_entry)
+ fprintf (info->mapfile, " default handler is: %s at 0x%08" BFD_VMA_FMT "x\n",
+ info->table_default_entry->root.string,
+ info->table_default_handler);
+ else if (info->table_default_handler != (bfd_vma)(-1))
+ fprintf (info->mapfile, " default handler is at 0x%08" BFD_VMA_FMT "x\n",
+ info->table_default_handler);
+ else
+ fprintf (info->mapfile, " no default handler\n");
+
+ need_elipses = 1;
+ for (idx = 0; idx < info->table_size; idx ++)
+ {
+ if (info->table_handlers[idx] == info->table_default_handler)
+ {
+ if (need_elipses)
+ fprintf (info->mapfile, " . . .\n");
+ need_elipses = 0;
+ continue;
+ }
+ need_elipses = 1;
+
+ fprintf (info->mapfile, " 0x%08" BFD_VMA_FMT "x [%3d] ", start_addr + 4 * idx, idx);
+
+ if (info->table_handlers[idx] == (bfd_vma) (-1))
+ fprintf (info->mapfile, "(no handler found)\n");
+
+ else if (info->table_handlers[idx] == info->table_default_handler)
+ {
+ if (info->table_default_entry)
+ fprintf (info->mapfile, "(default)\n");
+ else
+ fprintf (info->mapfile, "(default)\n");
+ }
+
+ else if (info->table_entries[idx])
+ {
+ fprintf (info->mapfile, "0x%08" BFD_VMA_FMT "x %s\n", info->table_handlers[idx], info->table_entries[idx]->root.string);
+ }
+
+ else
+ {
+ fprintf (info->mapfile, "0x%08" BFD_VMA_FMT "x ???\n", info->table_handlers[idx]);
+ }
+ }
+ if (need_elipses)
+ fprintf (info->mapfile, " . . .\n");
+
+ return TRUE;
+}
+
+void
+rx_additional_link_map_text (bfd *obfd, struct bfd_link_info *info, FILE *mapfile)
+{
+ /* We scan the symbol table looking for $tableentry$'s, and for
+ each, try to deduce which handlers go with which entries. */
+
+ RX_Table_Info stuff;
+
+ stuff.abfd = obfd;
+ stuff.info = info;
+ stuff.mapfile = mapfile;
+ bfd_hash_traverse (&(info->hash->table), rx_table_map, &stuff);
+}
+
+
+#define ELF_ARCH bfd_arch_rx
+#define ELF_MACHINE_CODE EM_RX
+#define ELF_MAXPAGESIZE 0x1000
+
+#define TARGET_BIG_SYM rx_elf32_be_vec
+#define TARGET_BIG_NAME "elf32-rx-be"
+
+#define TARGET_LITTLE_SYM rx_elf32_le_vec
+#define TARGET_LITTLE_NAME "elf32-rx-le"
+
+#define elf_info_to_howto_rel NULL
+#define elf_info_to_howto rx_info_to_howto_rela
+#define elf_backend_object_p rx_elf_object_p
+#define elf_backend_relocate_section rx_elf_relocate_section
+#define elf_symbol_leading_char ('_')
+#define elf_backend_can_gc_sections 1
+#define elf_backend_modify_program_headers elf32_rx_modify_program_headers
+
+#define bfd_elf32_bfd_reloc_type_lookup rx_reloc_type_lookup
+#define bfd_elf32_bfd_reloc_name_lookup rx_reloc_name_lookup
+#define bfd_elf32_bfd_set_private_flags rx_elf_set_private_flags
+#define bfd_elf32_bfd_merge_private_bfd_data rx_elf_merge_private_bfd_data
+#define bfd_elf32_bfd_print_private_bfd_data rx_elf_print_private_bfd_data
+#define bfd_elf32_get_section_contents rx_get_section_contents
+#define bfd_elf32_set_section_contents rx_set_section_contents
+#define bfd_elf32_bfd_final_link rx_final_link
+#define bfd_elf32_bfd_relax_section elf32_rx_relax_section_wrapper
+#define elf_backend_special_sections elf32_rx_special_sections
+#define elf_backend_check_directives rx_check_directives
+
+#include "elf32-target.h"
+
+/* We define a second big-endian target that doesn't have the custom
+ section get/set hooks, for times when we want to preserve the
+ pre-swapped .text sections (like objcopy). */
+
+#undef TARGET_BIG_SYM
+#define TARGET_BIG_SYM rx_elf32_be_ns_vec
+#undef TARGET_BIG_NAME
+#define TARGET_BIG_NAME "elf32-rx-be-ns"
+#undef TARGET_LITTLE_SYM
+
+#undef bfd_elf32_get_section_contents
+#undef bfd_elf32_set_section_contents
+
+#undef elf32_bed
+#define elf32_bed elf32_rx_be_ns_bed
+
+#include "elf32-target.h"
diff --git a/bfd/elf32-rx.h b/bfd/elf32-rx.h
new file mode 100644
index 0000000..3779388
--- /dev/null
+++ b/bfd/elf32-rx.h
@@ -0,0 +1,21 @@
+/* Renesas RX specific support for 32-bit ELF.
+ Copyright (C) 2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+
+void rx_additional_link_map_text (bfd *obfd, struct bfd_link_info *info, FILE *mapfile);
diff --git a/bfd/elf32-s390.c b/bfd/elf32-s390.c
new file mode 100644
index 0000000..ebcb028
--- /dev/null
+++ b/bfd/elf32-s390.c
@@ -0,0 +1,4035 @@
+/* IBM S/390-specific support for 32-bit ELF
+ Copyright (C) 2000-2014 Free Software Foundation, Inc.
+ Contributed by Carl B. Pedersen and Martin Schwidefsky.
+
+ This file is part of BFD, the Binary File Descriptor library.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
+ 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "bfdlink.h"
+#include "libbfd.h"
+#include "elf-bfd.h"
+#include "elf/s390.h"
+
+static bfd_reloc_status_type
+s390_tls_reloc (bfd *, arelent *, asymbol *, void *,
+ asection *, bfd *, char **);
+static bfd_reloc_status_type
+s390_elf_ldisp_reloc (bfd *, arelent *, asymbol *, void *,
+ asection *, bfd *, char **);
+
+/* The relocation "howto" table. */
+
+static reloc_howto_type elf_howto_table[] =
+{
+ HOWTO (R_390_NONE, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = 2 byte, 2 = 4 byte) */
+ 0, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_390_NONE", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO(R_390_8, 0, 0, 8, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_390_8", FALSE, 0,0x000000ff, FALSE),
+ HOWTO(R_390_12, 0, 1, 12, FALSE, 0, complain_overflow_dont,
+ bfd_elf_generic_reloc, "R_390_12", FALSE, 0,0x00000fff, FALSE),
+ HOWTO(R_390_16, 0, 1, 16, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_390_16", FALSE, 0,0x0000ffff, FALSE),
+ HOWTO(R_390_32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_390_32", FALSE, 0,0xffffffff, FALSE),
+ HOWTO(R_390_PC32, 0, 2, 32, TRUE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_390_PC32", FALSE, 0,0xffffffff, TRUE),
+ HOWTO(R_390_GOT12, 0, 1, 12, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_390_GOT12", FALSE, 0,0x00000fff, FALSE),
+ HOWTO(R_390_GOT32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_390_GOT32", FALSE, 0,0xffffffff, FALSE),
+ HOWTO(R_390_PLT32, 0, 2, 32, TRUE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_390_PLT32", FALSE, 0,0xffffffff, TRUE),
+ HOWTO(R_390_COPY, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_390_COPY", FALSE, 0,0xffffffff, FALSE),
+ HOWTO(R_390_GLOB_DAT, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_390_GLOB_DAT", FALSE, 0,0xffffffff, FALSE),
+ HOWTO(R_390_JMP_SLOT, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_390_JMP_SLOT", FALSE, 0,0xffffffff, FALSE),
+ HOWTO(R_390_RELATIVE, 0, 2, 32, TRUE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_390_RELATIVE", FALSE, 0,0xffffffff, FALSE),
+ HOWTO(R_390_GOTOFF32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_390_GOTOFF32", FALSE, 0,0xffffffff, FALSE),
+ HOWTO(R_390_GOTPC, 0, 2, 32, TRUE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_390_GOTPC", FALSE, 0,0xffffffff, TRUE),
+ HOWTO(R_390_GOT16, 0, 1, 16, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_390_GOT16", FALSE, 0,0x0000ffff, FALSE),
+ HOWTO(R_390_PC16, 0, 1, 16, TRUE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_390_PC16", FALSE, 0,0x0000ffff, TRUE),
+ HOWTO(R_390_PC16DBL, 1, 1, 16, TRUE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_390_PC16DBL", FALSE, 0,0x0000ffff, TRUE),
+ HOWTO(R_390_PLT16DBL, 1, 1, 16, TRUE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_390_PLT16DBL", FALSE, 0,0x0000ffff, TRUE),
+ HOWTO(R_390_PC32DBL, 1, 2, 32, TRUE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_390_PC32DBL", FALSE, 0,0xffffffff, TRUE),
+ HOWTO(R_390_PLT32DBL, 1, 2, 32, TRUE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_390_PLT32DBL", FALSE, 0,0xffffffff, TRUE),
+ HOWTO(R_390_GOTPCDBL, 1, 2, 32, TRUE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_390_GOTPCDBL", FALSE, 0,0xffffffff, TRUE),
+ EMPTY_HOWTO (R_390_64), /* Empty entry for R_390_64. */
+ EMPTY_HOWTO (R_390_PC64), /* Empty entry for R_390_PC64. */
+ EMPTY_HOWTO (R_390_GOT64), /* Empty entry for R_390_GOT64. */
+ EMPTY_HOWTO (R_390_PLT64), /* Empty entry for R_390_PLT64. */
+ HOWTO(R_390_GOTENT, 1, 2, 32, TRUE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_390_GOTENT", FALSE, 0,0xffffffff, TRUE),
+ HOWTO(R_390_GOTOFF16, 0, 1, 16, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_390_GOTOFF16", FALSE, 0,0x0000ffff, FALSE),
+ EMPTY_HOWTO (R_390_GOTOFF64), /* Empty entry for R_390_GOTOFF64. */
+ HOWTO(R_390_GOTPLT12, 0, 1, 12, FALSE, 0, complain_overflow_dont,
+ bfd_elf_generic_reloc, "R_390_GOTPLT12", FALSE, 0,0x00000fff, FALSE),
+ HOWTO(R_390_GOTPLT16, 0, 1, 16, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_390_GOTPLT16", FALSE, 0,0x0000ffff, FALSE),
+ HOWTO(R_390_GOTPLT32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_390_GOTPLT32", FALSE, 0,0xffffffff, FALSE),
+ EMPTY_HOWTO (R_390_GOTPLT64), /* Empty entry for R_390_GOTPLT64. */
+ HOWTO(R_390_GOTPLTENT, 1, 2, 32, TRUE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_390_GOTPLTENT",FALSE, 0,0xffffffff, TRUE),
+ HOWTO(R_390_PLTOFF16, 0, 1, 16, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_390_PLTOFF16", FALSE, 0,0x0000ffff, FALSE),
+ HOWTO(R_390_PLTOFF32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_390_PLTOFF32", FALSE, 0,0xffffffff, FALSE),
+ EMPTY_HOWTO (R_390_PLTOFF64), /* Empty entry for R_390_PLTOFF64. */
+ HOWTO(R_390_TLS_LOAD, 0, 0, 0, FALSE, 0, complain_overflow_dont,
+ s390_tls_reloc, "R_390_TLS_LOAD", FALSE, 0, 0, FALSE),
+ HOWTO(R_390_TLS_GDCALL, 0, 0, 0, FALSE, 0, complain_overflow_dont,
+ s390_tls_reloc, "R_390_TLS_GDCALL", FALSE, 0, 0, FALSE),
+ HOWTO(R_390_TLS_LDCALL, 0, 0, 0, FALSE, 0, complain_overflow_dont,
+ s390_tls_reloc, "R_390_TLS_LDCALL", FALSE, 0, 0, FALSE),
+ HOWTO(R_390_TLS_GD32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_390_TLS_GD32", FALSE, 0, 0xffffffff, FALSE),
+ EMPTY_HOWTO (R_390_TLS_GD64), /* Empty entry for R_390_TLS_GD64. */
+ HOWTO(R_390_TLS_GOTIE12, 0, 1, 12, FALSE, 0, complain_overflow_dont,
+ bfd_elf_generic_reloc, "R_390_TLS_GOTIE12", FALSE, 0, 0x00000fff, FALSE),
+ HOWTO(R_390_TLS_GOTIE32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_390_TLS_GOTIE32", FALSE, 0, 0xffffffff, FALSE),
+ EMPTY_HOWTO (R_390_TLS_GOTIE64), /* Empty entry for R_390_TLS_GOTIE64. */
+ HOWTO(R_390_TLS_LDM32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_390_TLS_LDM32", FALSE, 0, 0xffffffff, FALSE),
+ EMPTY_HOWTO (R_390_TLS_LDM64), /* Empty entry for R_390_TLS_LDM64. */
+ HOWTO(R_390_TLS_IE32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_390_TLS_IE32", FALSE, 0, 0xffffffff, FALSE),
+ EMPTY_HOWTO (R_390_TLS_IE64), /* Empty entry for R_390_TLS_IE64. */
+ HOWTO(R_390_TLS_IEENT, 1, 2, 32, TRUE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_390_TLS_IEENT", FALSE, 0, 0xffffffff, TRUE),
+ HOWTO(R_390_TLS_LE32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_390_TLS_LE32", FALSE, 0, 0xffffffff, FALSE),
+ EMPTY_HOWTO (R_390_TLS_LE64), /* Empty entry for R_390_TLS_LE64. */
+ HOWTO(R_390_TLS_LDO32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_390_TLS_LDO32", FALSE, 0, 0xffffffff, FALSE),
+ EMPTY_HOWTO (R_390_TLS_LDO64), /* Empty entry for R_390_TLS_LDO64. */
+ HOWTO(R_390_TLS_DTPMOD, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_390_TLS_DTPMOD", FALSE, 0, 0xffffffff, FALSE),
+ HOWTO(R_390_TLS_DTPOFF, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_390_TLS_DTPOFF", FALSE, 0, 0xffffffff, FALSE),
+ HOWTO(R_390_TLS_TPOFF, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_390_TLS_TPOFF", FALSE, 0, 0xffffffff, FALSE),
+ HOWTO(R_390_20, 0, 2, 20, FALSE, 8, complain_overflow_dont,
+ s390_elf_ldisp_reloc, "R_390_20", FALSE, 0,0x0fffff00, FALSE),
+ HOWTO(R_390_GOT20, 0, 2, 20, FALSE, 8, complain_overflow_dont,
+ s390_elf_ldisp_reloc, "R_390_GOT20", FALSE, 0,0x0fffff00, FALSE),
+ HOWTO(R_390_GOTPLT20, 0, 2, 20, FALSE, 8, complain_overflow_dont,
+ s390_elf_ldisp_reloc, "R_390_GOTPLT20", FALSE, 0,0x0fffff00, FALSE),
+ HOWTO(R_390_TLS_GOTIE20, 0, 2, 20, FALSE, 8, complain_overflow_dont,
+ s390_elf_ldisp_reloc, "R_390_TLS_GOTIE20", FALSE, 0,0x0fffff00, FALSE),
+ HOWTO(R_390_IRELATIVE, 0, 2, 32, TRUE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_390_IRELATIVE", FALSE, 0, 0xffffffff, FALSE),
+ HOWTO(R_390_PC12DBL, 1, 1, 12, TRUE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_390_PC12DBL", FALSE, 0,0x00000fff, TRUE),
+ HOWTO(R_390_PLT12DBL, 1, 1, 12, TRUE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_390_PLT12DBL", FALSE, 0,0x00000fff, TRUE),
+ HOWTO(R_390_PC24DBL, 1, 2, 24, TRUE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_390_PC24DBL", FALSE, 0,0x00ffffff, TRUE),
+ HOWTO(R_390_PLT24DBL, 1, 2, 24, TRUE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_390_PLT24DBL", FALSE, 0,0x00ffffff, TRUE),
+};
+
+/* GNU extension to record C++ vtable hierarchy. */
+static reloc_howto_type elf32_s390_vtinherit_howto =
+ HOWTO (R_390_GNU_VTINHERIT, 0,2,0,FALSE,0,complain_overflow_dont, NULL, "R_390_GNU_VTINHERIT", FALSE,0, 0, FALSE);
+static reloc_howto_type elf32_s390_vtentry_howto =
+ HOWTO (R_390_GNU_VTENTRY, 0,2,0,FALSE,0,complain_overflow_dont, _bfd_elf_rel_vtable_reloc_fn,"R_390_GNU_VTENTRY", FALSE,0,0, FALSE);
+
+static reloc_howto_type *
+elf_s390_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ bfd_reloc_code_real_type code)
+{
+ switch (code)
+ {
+ case BFD_RELOC_NONE:
+ return &elf_howto_table[(int) R_390_NONE];
+ case BFD_RELOC_8:
+ return &elf_howto_table[(int) R_390_8];
+ case BFD_RELOC_390_12:
+ return &elf_howto_table[(int) R_390_12];
+ case BFD_RELOC_16:
+ return &elf_howto_table[(int) R_390_16];
+ case BFD_RELOC_32:
+ return &elf_howto_table[(int) R_390_32];
+ case BFD_RELOC_CTOR:
+ return &elf_howto_table[(int) R_390_32];
+ case BFD_RELOC_32_PCREL:
+ return &elf_howto_table[(int) R_390_PC32];
+ case BFD_RELOC_390_GOT12:
+ return &elf_howto_table[(int) R_390_GOT12];
+ case BFD_RELOC_32_GOT_PCREL:
+ return &elf_howto_table[(int) R_390_GOT32];
+ case BFD_RELOC_390_PLT32:
+ return &elf_howto_table[(int) R_390_PLT32];
+ case BFD_RELOC_390_COPY:
+ return &elf_howto_table[(int) R_390_COPY];
+ case BFD_RELOC_390_GLOB_DAT:
+ return &elf_howto_table[(int) R_390_GLOB_DAT];
+ case BFD_RELOC_390_JMP_SLOT:
+ return &elf_howto_table[(int) R_390_JMP_SLOT];
+ case BFD_RELOC_390_RELATIVE:
+ return &elf_howto_table[(int) R_390_RELATIVE];
+ case BFD_RELOC_32_GOTOFF:
+ return &elf_howto_table[(int) R_390_GOTOFF32];
+ case BFD_RELOC_390_GOTPC:
+ return &elf_howto_table[(int) R_390_GOTPC];
+ case BFD_RELOC_390_GOT16:
+ return &elf_howto_table[(int) R_390_GOT16];
+ case BFD_RELOC_16_PCREL:
+ return &elf_howto_table[(int) R_390_PC16];
+ case BFD_RELOC_390_PC12DBL:
+ return &elf_howto_table[(int) R_390_PC12DBL];
+ case BFD_RELOC_390_PLT12DBL:
+ return &elf_howto_table[(int) R_390_PLT12DBL];
+ case BFD_RELOC_390_PC16DBL:
+ return &elf_howto_table[(int) R_390_PC16DBL];
+ case BFD_RELOC_390_PLT16DBL:
+ return &elf_howto_table[(int) R_390_PLT16DBL];
+ case BFD_RELOC_390_PC24DBL:
+ return &elf_howto_table[(int) R_390_PC24DBL];
+ case BFD_RELOC_390_PLT24DBL:
+ return &elf_howto_table[(int) R_390_PLT24DBL];
+ case BFD_RELOC_390_PC32DBL:
+ return &elf_howto_table[(int) R_390_PC32DBL];
+ case BFD_RELOC_390_PLT32DBL:
+ return &elf_howto_table[(int) R_390_PLT32DBL];
+ case BFD_RELOC_390_GOTPCDBL:
+ return &elf_howto_table[(int) R_390_GOTPCDBL];
+ case BFD_RELOC_390_GOTENT:
+ return &elf_howto_table[(int) R_390_GOTENT];
+ case BFD_RELOC_16_GOTOFF:
+ return &elf_howto_table[(int) R_390_GOTOFF16];
+ case BFD_RELOC_390_GOTPLT12:
+ return &elf_howto_table[(int) R_390_GOTPLT12];
+ case BFD_RELOC_390_GOTPLT16:
+ return &elf_howto_table[(int) R_390_GOTPLT16];
+ case BFD_RELOC_390_GOTPLT32:
+ return &elf_howto_table[(int) R_390_GOTPLT32];
+ case BFD_RELOC_390_GOTPLTENT:
+ return &elf_howto_table[(int) R_390_GOTPLTENT];
+ case BFD_RELOC_390_PLTOFF16:
+ return &elf_howto_table[(int) R_390_PLTOFF16];
+ case BFD_RELOC_390_PLTOFF32:
+ return &elf_howto_table[(int) R_390_PLTOFF32];
+ case BFD_RELOC_390_TLS_LOAD:
+ return &elf_howto_table[(int) R_390_TLS_LOAD];
+ case BFD_RELOC_390_TLS_GDCALL:
+ return &elf_howto_table[(int) R_390_TLS_GDCALL];
+ case BFD_RELOC_390_TLS_LDCALL:
+ return &elf_howto_table[(int) R_390_TLS_LDCALL];
+ case BFD_RELOC_390_TLS_GD32:
+ return &elf_howto_table[(int) R_390_TLS_GD32];
+ case BFD_RELOC_390_TLS_GOTIE12:
+ return &elf_howto_table[(int) R_390_TLS_GOTIE12];
+ case BFD_RELOC_390_TLS_GOTIE32:
+ return &elf_howto_table[(int) R_390_TLS_GOTIE32];
+ case BFD_RELOC_390_TLS_LDM32:
+ return &elf_howto_table[(int) R_390_TLS_LDM32];
+ case BFD_RELOC_390_TLS_IE32:
+ return &elf_howto_table[(int) R_390_TLS_IE32];
+ case BFD_RELOC_390_TLS_IEENT:
+ return &elf_howto_table[(int) R_390_TLS_IEENT];
+ case BFD_RELOC_390_TLS_LE32:
+ return &elf_howto_table[(int) R_390_TLS_LE32];
+ case BFD_RELOC_390_TLS_LDO32:
+ return &elf_howto_table[(int) R_390_TLS_LDO32];
+ case BFD_RELOC_390_TLS_DTPMOD:
+ return &elf_howto_table[(int) R_390_TLS_DTPMOD];
+ case BFD_RELOC_390_TLS_DTPOFF:
+ return &elf_howto_table[(int) R_390_TLS_DTPOFF];
+ case BFD_RELOC_390_TLS_TPOFF:
+ return &elf_howto_table[(int) R_390_TLS_TPOFF];
+ case BFD_RELOC_390_20:
+ return &elf_howto_table[(int) R_390_20];
+ case BFD_RELOC_390_GOT20:
+ return &elf_howto_table[(int) R_390_GOT20];
+ case BFD_RELOC_390_GOTPLT20:
+ return &elf_howto_table[(int) R_390_GOTPLT20];
+ case BFD_RELOC_390_TLS_GOTIE20:
+ return &elf_howto_table[(int) R_390_TLS_GOTIE20];
+ case BFD_RELOC_390_IRELATIVE:
+ return &elf_howto_table[(int) R_390_IRELATIVE];
+ case BFD_RELOC_VTABLE_INHERIT:
+ return &elf32_s390_vtinherit_howto;
+ case BFD_RELOC_VTABLE_ENTRY:
+ return &elf32_s390_vtentry_howto;
+ default:
+ break;
+ }
+ return 0;
+}
+
+static reloc_howto_type *
+elf_s390_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ const char *r_name)
+{
+ unsigned int i;
+
+ for (i = 0; i < sizeof (elf_howto_table) / sizeof (elf_howto_table[0]); i++)
+ if (elf_howto_table[i].name != NULL
+ && strcasecmp (elf_howto_table[i].name, r_name) == 0)
+ return &elf_howto_table[i];
+
+ if (strcasecmp (elf32_s390_vtinherit_howto.name, r_name) == 0)
+ return &elf32_s390_vtinherit_howto;
+ if (strcasecmp (elf32_s390_vtentry_howto.name, r_name) == 0)
+ return &elf32_s390_vtentry_howto;
+
+ return NULL;
+}
+
+/* We need to use ELF32_R_TYPE so we have our own copy of this function,
+ and elf32-s390.c has its own copy. */
+
+static void
+elf_s390_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED,
+ arelent *cache_ptr,
+ Elf_Internal_Rela *dst)
+{
+ unsigned int r_type = ELF32_R_TYPE(dst->r_info);
+ switch (r_type)
+ {
+ case R_390_GNU_VTINHERIT:
+ cache_ptr->howto = &elf32_s390_vtinherit_howto;
+ break;
+
+ case R_390_GNU_VTENTRY:
+ cache_ptr->howto = &elf32_s390_vtentry_howto;
+ break;
+
+ default:
+ if (r_type >= sizeof (elf_howto_table) / sizeof (elf_howto_table[0]))
+ {
+ (*_bfd_error_handler) (_("%B: invalid relocation type %d"),
+ abfd, (int) r_type);
+ r_type = R_390_NONE;
+ }
+ cache_ptr->howto = &elf_howto_table[r_type];
+ }
+}
+
+/* A relocation function which doesn't do anything. */
+static bfd_reloc_status_type
+s390_tls_reloc (bfd *abfd ATTRIBUTE_UNUSED,
+ arelent *reloc_entry,
+ asymbol *symbol ATTRIBUTE_UNUSED,
+ void * data ATTRIBUTE_UNUSED,
+ asection *input_section,
+ bfd *output_bfd,
+ char **error_message ATTRIBUTE_UNUSED)
+{
+ if (output_bfd)
+ reloc_entry->address += input_section->output_offset;
+ return bfd_reloc_ok;
+}
+
+/* Handle the large displacement relocs. */
+static bfd_reloc_status_type
+s390_elf_ldisp_reloc (bfd *abfd ATTRIBUTE_UNUSED,
+ arelent *reloc_entry,
+ asymbol *symbol,
+ void * data ATTRIBUTE_UNUSED,
+ asection *input_section,
+ bfd *output_bfd,
+ char **error_message ATTRIBUTE_UNUSED)
+{
+ reloc_howto_type *howto = reloc_entry->howto;
+ bfd_vma relocation;
+ bfd_vma insn;
+
+ 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;
+ }
+
+ if (output_bfd != NULL)
+ return bfd_reloc_continue;
+
+ if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
+ 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;
+ }
+
+ insn = bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
+ insn |= (relocation & 0xfff) << 16 | (relocation & 0xff000) >> 4;
+ bfd_put_32 (abfd, insn, (bfd_byte *) data + reloc_entry->address);
+
+ if ((bfd_signed_vma) relocation < - 0x80000
+ || (bfd_signed_vma) relocation > 0x7ffff)
+ return bfd_reloc_overflow;
+ else
+ return bfd_reloc_ok;
+}
+
+static bfd_boolean
+elf_s390_is_local_label_name (bfd *abfd, const char *name)
+{
+ if (name[0] == '.' && (name[1] == 'X' || name[1] == 'L'))
+ return TRUE;
+
+ return _bfd_elf_is_local_label_name (abfd, name);
+}
+
+/* Functions for the 390 ELF linker. */
+
+/* The name of the dynamic interpreter. This is put in the .interp
+ section. */
+
+#define ELF_DYNAMIC_INTERPRETER "/lib/ld.so.1"
+
+/* If ELIMINATE_COPY_RELOCS is non-zero, the linker will try to avoid
+ copying dynamic variables from a shared lib into an app's dynbss
+ section, and instead use a dynamic relocation to point into the
+ shared lib. */
+#define ELIMINATE_COPY_RELOCS 1
+
+/* The size in bytes of the first entry in the procedure linkage table. */
+#define PLT_FIRST_ENTRY_SIZE 32
+/* The size in bytes of an entry in the procedure linkage table. */
+#define PLT_ENTRY_SIZE 32
+
+#define GOT_ENTRY_SIZE 4
+
+#define RELA_ENTRY_SIZE sizeof (Elf32_External_Rela)
+
+/* The first three 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 386
+ supplement to see how this works. */
+
+/* For the s390, simple addr offset can only be 0 - 4096.
+ To use the full 2 GB address space, several instructions
+ are needed to load an address in a register and execute
+ a branch( or just saving the address)
+
+ Furthermore, only r 0 and 1 are free to use!!! */
+
+/* The first 3 words in the GOT are then reserved.
+ Word 0 is the address of the dynamic table.
+ Word 1 is a pointer to a structure describing the object
+ Word 2 is used to point to the loader entry address.
+
+ The code for position independent PLT entries looks like this:
+
+ r12 holds addr of the current GOT at entry to the PLT
+
+ The GOT holds the address in the PLT to be executed.
+ The loader then gets:
+ 24(15) = Pointer to the structure describing the object.
+ 28(15) = Offset into rela.plt
+
+ The loader must then find the module where the function is
+ and insert the address in the GOT.
+
+ Note: 390 can only address +- 64 K relative.
+ We check if offset > 65536, then make a relative branch -64xxx
+ back to a previous defined branch
+
+PLT1: BASR 1,0 # 2 bytes
+ L 1,22(1) # 4 bytes Load offset in GOT in r 1
+ L 1,(1,12) # 4 bytes Load address from GOT in r1
+ BCR 15,1 # 2 bytes Jump to address
+RET1: BASR 1,0 # 2 bytes Return from GOT 1st time
+ L 1,14(1) # 4 bytes Load offset in symol table in r1
+ BRC 15,-x # 4 bytes Jump to start of PLT
+ .word 0 # 2 bytes filler
+ .long ? # 4 bytes offset in GOT
+ .long ? # 4 bytes offset into rela.plt
+
+ This was the general case. There are two additional, optimizes PLT
+ definitions. One for GOT offsets < 4096 and one for GOT offsets < 32768.
+ First the one for GOT offsets < 4096:
+
+PLT1: L 1,<offset>(12) # 4 bytes Load address from GOT in R1
+ BCR 15,1 # 2 bytes Jump to address
+ .word 0,0,0 # 6 bytes filler
+RET1: BASR 1,0 # 2 bytes Return from GOT 1st time
+ L 1,14(1) # 4 bytes Load offset in rela.plt in r1
+ BRC 15,-x # 4 bytes Jump to start of PLT
+ .word 0,0,0 # 6 bytes filler
+ .long ? # 4 bytes offset into rela.plt
+
+ Second the one for GOT offsets < 32768:
+
+PLT1: LHI 1,<offset> # 4 bytes Load offset in GOT to r1
+ L 1,(1,12) # 4 bytes Load address from GOT to r1
+ BCR 15,1 # 2 bytes Jump to address
+ .word 0 # 2 bytes filler
+RET1: BASR 1,0 # 2 bytes Return from GOT 1st time
+ L 1,14(1) # 4 bytes Load offset in rela.plt in r1
+ BRC 15,-x # 4 bytes Jump to start of PLT
+ .word 0,0,0 # 6 bytes filler
+ .long ? # 4 bytes offset into rela.plt
+
+Total = 32 bytes per PLT entry
+
+ The code for static build PLT entries looks like this:
+
+PLT1: BASR 1,0 # 2 bytes
+ L 1,22(1) # 4 bytes Load address of GOT entry
+ L 1,0(0,1) # 4 bytes Load address from GOT in r1
+ BCR 15,1 # 2 bytes Jump to address
+RET1: BASR 1,0 # 2 bytes Return from GOT 1st time
+ L 1,14(1) # 4 bytes Load offset in symbol table in r1
+ BRC 15,-x # 4 bytes Jump to start of PLT
+ .word 0 # 2 bytes filler
+ .long ? # 4 bytes address of GOT entry
+ .long ? # 4 bytes offset into rela.plt */
+
+static const bfd_byte elf_s390_plt_entry[PLT_ENTRY_SIZE] =
+ {
+ 0x0d, 0x10, /* basr %r1,%r0 */
+ 0x58, 0x10, 0x10, 0x16, /* l %r1,22(%r1) */
+ 0x58, 0x10, 0x10, 0x00, /* l %r1,0(%r1) */
+ 0x07, 0xf1, /* br %r1 */
+ 0x0d, 0x10, /* basr %r1,%r0 */
+ 0x58, 0x10, 0x10, 0x0e, /* l %r1,14(%r1) */
+ 0xa7, 0xf4, 0x00, 0x00, /* j first plt */
+ 0x00, 0x00, /* padding */
+ 0x00, 0x00, 0x00, 0x00, /* GOT offset */
+ 0x00, 0x00, 0x00, 0x00 /* rela.plt offset */
+ };
+
+/* Generic PLT pic entry. */
+static const bfd_byte elf_s390_plt_pic_entry[PLT_ENTRY_SIZE] =
+ {
+ 0x0d, 0x10, /* basr %r1,%r0 */
+ 0x58, 0x10, 0x10, 0x16, /* l %r1,22(%r1) */
+ 0x58, 0x11, 0xc0, 0x00, /* l %r1,0(%r1,%r12) */
+ 0x07, 0xf1, /* br %r1 */
+ 0x0d, 0x10, /* basr %r1,%r0 */
+ 0x58, 0x10, 0x10, 0x0e, /* l %r1,14(%r1) */
+ 0xa7, 0xf4, 0x00, 0x00, /* j first plt */
+ 0x00, 0x00, /* padding */
+ 0x00, 0x00, 0x00, 0x00, /* GOT offset */
+ 0x00, 0x00, 0x00, 0x00 /* rela.plt offset */
+ };
+
+/* Optimized PLT pic entry for GOT offset < 4k. xx will be replaced
+ when generating the PLT slot with the GOT offset. */
+static const bfd_byte elf_s390_plt_pic12_entry[PLT_ENTRY_SIZE] =
+ {
+ 0x58, 0x10, 0xc0, 0x00, /* l %r1,xx(%r12) */
+ 0x07, 0xf1, /* br %r1 */
+ 0x00, 0x00, 0x00, 0x00, /* padding */
+ 0x00, 0x00,
+ 0x0d, 0x10, /* basr %r1,%r0 */
+ 0x58, 0x10, 0x10, 0x0e, /* l %r1,14(%r1) */
+ 0xa7, 0xf4, 0x00, 0x00, /* j first plt */
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00
+ };
+
+/* Optimized PLT pic entry for GOT offset < 32k. xx will be replaced
+ when generating the PLT slot with the GOT offset. */
+static const bfd_byte elf_s390_plt_pic16_entry[PLT_ENTRY_SIZE] =
+ {
+ 0xa7, 0x18, 0x00, 0x00, /* lhi %r1,xx */
+ 0x58, 0x11, 0xc0, 0x00, /* l %r1,0(%r1,%r12) */
+ 0x07, 0xf1, /* br %r1 */
+ 0x00, 0x00,
+ 0x0d, 0x10, /* basr %r1,%r0 */
+ 0x58, 0x10, 0x10, 0x0e, /* l %r1,14(%r1) */
+ 0xa7, 0xf4, 0x00, 0x00, /* j first plt */
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00
+ };
+
+/* The first PLT entry pushes the offset into the rela.plt
+ from R1 onto the stack at 8(15) and the loader object info
+ at 12(15), loads the loader address in R1 and jumps to it. */
+
+/* The first entry in the PLT for PIC code:
+
+PLT0:
+ ST 1,28(15) # R1 has offset into rela.plt
+ L 1,4(12) # Get loader ino(object struct address)
+ ST 1,24(15) # Store address
+ L 1,8(12) # Entry address of loader in R1
+ BR 1 # Jump to loader
+
+ The first entry in the PLT for static code:
+
+PLT0:
+ ST 1,28(15) # R1 has offset into rela.plt
+ BASR 1,0
+ L 1,18(0,1) # Get address of GOT
+ MVC 24(4,15),4(1) # Move loader ino to stack
+ L 1,8(1) # Get address of loader
+ BR 1 # Jump to loader
+ .word 0 # filler
+ .long got # address of GOT */
+
+static const bfd_byte elf_s390_plt_first_entry[PLT_FIRST_ENTRY_SIZE] =
+ {
+ 0x50, 0x10, 0xf0, 0x1c, /* st %r1,28(%r15) */
+ 0x0d, 0x10, /* basr %r1,%r0 */
+ 0x58, 0x10, 0x10, 0x12, /* l %r1,18(%r1) */
+ 0xd2, 0x03, 0xf0, 0x18, 0x10, 0x04, /* mvc 24(4,%r15),4(%r1) */
+ 0x58, 0x10, 0x10, 0x08, /* l %r1,8(%r1) */
+ 0x07, 0xf1, /* br %r1 */
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00
+ };
+
+static const bfd_byte elf_s390_plt_pic_first_entry[PLT_FIRST_ENTRY_SIZE] =
+ {
+ 0x50, 0x10, 0xf0, 0x1c, /* st %r1,28(%r15) */
+ 0x58, 0x10, 0xc0, 0x04, /* l %r1,4(%r12) */
+ 0x50, 0x10, 0xf0, 0x18, /* st %r1,24(%r15) */
+ 0x58, 0x10, 0xc0, 0x08, /* l %r1,8(%r12) */
+ 0x07, 0xf1, /* br %r1 */
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00
+ };
+
+
+/* s390 ELF linker hash entry. */
+
+struct elf_s390_link_hash_entry
+{
+ struct elf_link_hash_entry elf;
+
+ /* Track dynamic relocs copied for this symbol. */
+ struct elf_dyn_relocs *dyn_relocs;
+
+ /* Number of GOTPLT references for a function. */
+ bfd_signed_vma gotplt_refcount;
+
+#define GOT_UNKNOWN 0
+#define GOT_NORMAL 1
+#define GOT_TLS_GD 2
+#define GOT_TLS_IE 3
+#define GOT_TLS_IE_NLT 4
+ unsigned char tls_type;
+
+ /* For pointer equality reasons we might need to change the symbol
+ type from STT_GNU_IFUNC to STT_FUNC together with its value and
+ section entry. So after alloc_dynrelocs only these values should
+ be used. In order to check whether a symbol is IFUNC use
+ s390_is_ifunc_symbol_p. */
+ bfd_vma ifunc_resolver_address;
+ asection *ifunc_resolver_section;
+};
+
+#define elf_s390_hash_entry(ent) \
+ ((struct elf_s390_link_hash_entry *)(ent))
+
+/* This structure represents an entry in the local PLT list needed for
+ local IFUNC symbols. */
+struct plt_entry
+{
+ /* The section of the local symbol.
+ Set in relocate_section and used in finish_dynamic_sections. */
+ asection *sec;
+
+ union
+ {
+ bfd_signed_vma refcount;
+ bfd_vma offset;
+ } plt;
+};
+
+/* NOTE: Keep this structure in sync with
+ the one declared in elf64-s390.c. */
+struct elf_s390_obj_tdata
+{
+ struct elf_obj_tdata root;
+
+ /* A local PLT is needed for ifunc symbols. */
+ struct plt_entry *local_plt;
+
+ /* TLS type for each local got entry. */
+ char *local_got_tls_type;
+};
+
+#define elf_s390_tdata(abfd) \
+ ((struct elf_s390_obj_tdata *) (abfd)->tdata.any)
+
+#define elf_s390_local_plt(abfd) \
+ (elf_s390_tdata (abfd)->local_plt)
+
+#define elf_s390_local_got_tls_type(abfd) \
+ (elf_s390_tdata (abfd)->local_got_tls_type)
+
+#define is_s390_elf(bfd) \
+ (bfd_get_flavour (bfd) == bfd_target_elf_flavour \
+ && elf_tdata (bfd) != NULL \
+ && elf_object_id (bfd) == S390_ELF_DATA)
+
+static bfd_boolean
+elf_s390_mkobject (bfd *abfd)
+{
+ return bfd_elf_allocate_object (abfd, sizeof (struct elf_s390_obj_tdata),
+ S390_ELF_DATA);
+}
+
+static bfd_boolean
+elf_s390_object_p (bfd *abfd)
+{
+ /* Set the right machine number for an s390 elf32 file. */
+ return bfd_default_set_arch_mach (abfd, bfd_arch_s390, bfd_mach_s390_31);
+}
+
+/* s390 ELF linker hash table. */
+
+struct elf_s390_link_hash_table
+{
+ struct elf_link_hash_table elf;
+
+ /* Short-cuts to get to dynamic linker sections. */
+ asection *sdynbss;
+ asection *srelbss;
+ asection *irelifunc;
+
+ union
+ {
+ bfd_signed_vma refcount;
+ bfd_vma offset;
+ } tls_ldm_got;
+
+ /* Small local sym cache. */
+ struct sym_cache sym_cache;
+};
+
+/* Get the s390 ELF linker hash table from a link_info structure. */
+
+#define elf_s390_hash_table(p) \
+ (elf_hash_table_id ((struct elf_link_hash_table *) ((p)->hash)) \
+ == S390_ELF_DATA ? ((struct elf_s390_link_hash_table *) ((p)->hash)) : NULL)
+
+#undef ELF64
+#include "elf-s390-common.c"
+
+/* Create an entry in an s390 ELF linker hash table. */
+
+static struct bfd_hash_entry *
+link_hash_newfunc (struct bfd_hash_entry *entry,
+ struct bfd_hash_table *table,
+ const char *string)
+{
+ /* Allocate the structure if it has not already been allocated by a
+ subclass. */
+ if (entry == NULL)
+ {
+ entry = bfd_hash_allocate (table,
+ sizeof (struct elf_s390_link_hash_entry));
+ if (entry == NULL)
+ return entry;
+ }
+
+ /* Call the allocation method of the superclass. */
+ entry = _bfd_elf_link_hash_newfunc (entry, table, string);
+ if (entry != NULL)
+ {
+ struct elf_s390_link_hash_entry *eh;
+
+ eh = (struct elf_s390_link_hash_entry *) entry;
+ eh->dyn_relocs = NULL;
+ eh->gotplt_refcount = 0;
+ eh->tls_type = GOT_UNKNOWN;
+ eh->ifunc_resolver_address = 0;
+ eh->ifunc_resolver_section = NULL;
+ }
+
+ return entry;
+}
+
+/* Create an s390 ELF linker hash table. */
+
+static struct bfd_link_hash_table *
+elf_s390_link_hash_table_create (bfd *abfd)
+{
+ struct elf_s390_link_hash_table *ret;
+ bfd_size_type amt = sizeof (struct elf_s390_link_hash_table);
+
+ ret = (struct elf_s390_link_hash_table *) bfd_zmalloc (amt);
+ if (ret == NULL)
+ return NULL;
+
+ if (!_bfd_elf_link_hash_table_init (&ret->elf, abfd, link_hash_newfunc,
+ sizeof (struct elf_s390_link_hash_entry),
+ S390_ELF_DATA))
+ {
+ free (ret);
+ return NULL;
+ }
+
+ return &ret->elf.root;
+}
+
+/* Create .got, .gotplt, and .rela.got sections in DYNOBJ, and set up
+ shortcuts to them in our hash table. */
+
+static bfd_boolean
+create_got_section (bfd *dynobj, struct bfd_link_info *info)
+{
+ struct elf_s390_link_hash_table *htab;
+
+ if (! _bfd_elf_create_got_section (dynobj, info))
+ return FALSE;
+
+ htab = elf_s390_hash_table (info);
+ htab->elf.sgot = bfd_get_linker_section (dynobj, ".got");
+ htab->elf.sgotplt = bfd_get_linker_section (dynobj, ".got.plt");
+ htab->elf.srelgot = bfd_get_linker_section (dynobj, ".rela.got");
+ if (!htab->elf.sgot || !htab->elf.sgotplt || !htab->elf.srelgot)
+ abort ();
+
+ return TRUE;
+}
+
+/* Create .plt, .rela.plt, .got, .got.plt, .rela.got, .dynbss, and
+ .rela.bss sections in DYNOBJ, and set up shortcuts to them in our
+ hash table. */
+
+static bfd_boolean
+elf_s390_create_dynamic_sections (bfd *dynobj, struct bfd_link_info *info)
+{
+ struct elf_s390_link_hash_table *htab;
+
+ htab = elf_s390_hash_table (info);
+ if (!htab->elf.sgot && !create_got_section (dynobj, info))
+ return FALSE;
+
+ if (!_bfd_elf_create_dynamic_sections (dynobj, info))
+ return FALSE;
+
+ htab->elf.splt = bfd_get_linker_section (dynobj, ".plt");
+ htab->elf.srelplt = bfd_get_linker_section (dynobj, ".rela.plt");
+ htab->sdynbss = bfd_get_linker_section (dynobj, ".dynbss");
+ if (!info->shared)
+ htab->srelbss = bfd_get_linker_section (dynobj, ".rela.bss");
+
+ if (!htab->elf.splt || !htab->elf.srelplt || !htab->sdynbss
+ || (!info->shared && !htab->srelbss))
+ abort ();
+
+ return TRUE;
+}
+
+/* Copy the extra info we tack onto an elf_link_hash_entry. */
+
+static void
+elf_s390_copy_indirect_symbol (struct bfd_link_info *info,
+ struct elf_link_hash_entry *dir,
+ struct elf_link_hash_entry *ind)
+{
+ struct elf_s390_link_hash_entry *edir, *eind;
+
+ edir = (struct elf_s390_link_hash_entry *) dir;
+ eind = (struct elf_s390_link_hash_entry *) ind;
+
+ if (eind->dyn_relocs != NULL)
+ {
+ if (edir->dyn_relocs != NULL)
+ {
+ struct elf_dyn_relocs **pp;
+ struct elf_dyn_relocs *p;
+
+ /* Add reloc counts against the indirect sym to the direct sym
+ list. Merge any entries against the same section. */
+ for (pp = &eind->dyn_relocs; (p = *pp) != NULL; )
+ {
+ struct elf_dyn_relocs *q;
+
+ for (q = edir->dyn_relocs; q != NULL; q = q->next)
+ if (q->sec == p->sec)
+ {
+ q->pc_count += p->pc_count;
+ q->count += p->count;
+ *pp = p->next;
+ break;
+ }
+ if (q == NULL)
+ pp = &p->next;
+ }
+ *pp = edir->dyn_relocs;
+ }
+
+ edir->dyn_relocs = eind->dyn_relocs;
+ eind->dyn_relocs = NULL;
+ }
+
+ if (ind->root.type == bfd_link_hash_indirect
+ && dir->got.refcount <= 0)
+ {
+ edir->tls_type = eind->tls_type;
+ eind->tls_type = GOT_UNKNOWN;
+ }
+
+ if (ELIMINATE_COPY_RELOCS
+ && ind->root.type != bfd_link_hash_indirect
+ && dir->dynamic_adjusted)
+ {
+ /* If called to transfer flags for a weakdef during processing
+ of elf_adjust_dynamic_symbol, don't copy non_got_ref.
+ We clear it ourselves for ELIMINATE_COPY_RELOCS. */
+ dir->ref_dynamic |= ind->ref_dynamic;
+ dir->ref_regular |= ind->ref_regular;
+ dir->ref_regular_nonweak |= ind->ref_regular_nonweak;
+ dir->needs_plt |= ind->needs_plt;
+ }
+ else
+ _bfd_elf_link_hash_copy_indirect (info, dir, ind);
+}
+
+static int
+elf_s390_tls_transition (struct bfd_link_info *info,
+ int r_type,
+ int is_local)
+{
+ if (info->shared)
+ return r_type;
+
+ switch (r_type)
+ {
+ case R_390_TLS_GD32:
+ case R_390_TLS_IE32:
+ if (is_local)
+ return R_390_TLS_LE32;
+ return R_390_TLS_IE32;
+ case R_390_TLS_GOTIE32:
+ if (is_local)
+ return R_390_TLS_LE32;
+ return R_390_TLS_GOTIE32;
+ case R_390_TLS_LDM32:
+ return R_390_TLS_LE32;
+ }
+
+ return 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 bfd_boolean
+elf_s390_check_relocs (bfd *abfd,
+ struct bfd_link_info *info,
+ asection *sec,
+ const Elf_Internal_Rela *relocs)
+{
+ struct elf_s390_link_hash_table *htab;
+ 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;
+ bfd_signed_vma *local_got_refcounts;
+ int tls_type, old_tls_type;
+ Elf_Internal_Sym *isym;
+
+ if (info->relocatable)
+ return TRUE;
+
+ BFD_ASSERT (is_s390_elf (abfd));
+
+ htab = elf_s390_hash_table (info);
+ symtab_hdr = &elf_symtab_hdr (abfd);
+ sym_hashes = elf_sym_hashes (abfd);
+ local_got_refcounts = elf_local_got_refcounts (abfd);
+
+ sreloc = NULL;
+
+ rel_end = relocs + sec->reloc_count;
+ for (rel = relocs; rel < rel_end; rel++)
+ {
+ unsigned int r_type;
+ unsigned long r_symndx;
+ struct elf_link_hash_entry *h;
+
+ r_symndx = ELF32_R_SYM (rel->r_info);
+
+ if (r_symndx >= NUM_SHDR_ENTRIES (symtab_hdr))
+ {
+ (*_bfd_error_handler) (_("%B: bad symbol index: %d"),
+ abfd, r_symndx);
+ return FALSE;
+ }
+
+ if (r_symndx < symtab_hdr->sh_info)
+ {
+ /* A local symbol. */
+ isym = bfd_sym_from_r_symndx (&htab->sym_cache,
+ abfd, r_symndx);
+ if (isym == NULL)
+ return FALSE;
+
+ if (ELF_ST_TYPE (isym->st_info) == STT_GNU_IFUNC)
+ {
+ struct plt_entry *plt;
+
+ if (htab->elf.dynobj == NULL)
+ htab->elf.dynobj = abfd;
+
+ if (!s390_elf_create_ifunc_sections (htab->elf.dynobj, info))
+ return FALSE;
+
+ if (local_got_refcounts == NULL)
+ {
+ if (!elf_s390_allocate_local_syminfo (abfd, symtab_hdr))
+ return FALSE;
+ local_got_refcounts = elf_local_got_refcounts (abfd);
+ }
+ plt = elf_s390_local_plt (abfd);
+ plt[r_symndx].plt.refcount++;
+ }
+ h = NULL;
+ }
+ 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;
+
+ /* PR15323, ref flags aren't set for references in the same
+ object. */
+ h->root.non_ir_ref = 1;
+ }
+
+ /* Create got section and local_got_refcounts array if they
+ are needed. */
+ r_type = elf_s390_tls_transition (info,
+ ELF32_R_TYPE (rel->r_info),
+ h == NULL);
+ switch (r_type)
+ {
+ case R_390_GOT12:
+ case R_390_GOT16:
+ case R_390_GOT20:
+ case R_390_GOT32:
+ case R_390_GOTENT:
+ case R_390_GOTPLT12:
+ case R_390_GOTPLT16:
+ case R_390_GOTPLT20:
+ case R_390_GOTPLT32:
+ case R_390_GOTPLTENT:
+ case R_390_TLS_GD32:
+ case R_390_TLS_GOTIE12:
+ case R_390_TLS_GOTIE20:
+ case R_390_TLS_GOTIE32:
+ case R_390_TLS_IEENT:
+ case R_390_TLS_IE32:
+ case R_390_TLS_LDM32:
+ if (h == NULL
+ && local_got_refcounts == NULL)
+ {
+ if (!elf_s390_allocate_local_syminfo (abfd, symtab_hdr))
+ return FALSE;
+ local_got_refcounts = elf_local_got_refcounts (abfd);
+ }
+ /* Fall through. */
+ case R_390_GOTOFF16:
+ case R_390_GOTOFF32:
+ case R_390_GOTPC:
+ case R_390_GOTPCDBL:
+ if (htab->elf.sgot == NULL)
+ {
+ if (htab->elf.dynobj == NULL)
+ htab->elf.dynobj = abfd;
+ if (!create_got_section (htab->elf.dynobj, info))
+ return FALSE;
+ }
+ }
+
+ if (h != NULL)
+ {
+ if (htab->elf.dynobj == NULL)
+ htab->elf.dynobj = abfd;
+ if (!s390_elf_create_ifunc_sections (htab->elf.dynobj, info))
+ return FALSE;
+
+ /* Make sure an IFUNC symbol defined in a non-shared object
+ always gets a PLT slot. */
+ if (s390_is_ifunc_symbol_p (h) && h->def_regular)
+ {
+ /* The symbol is called by the dynamic loader in order
+ to resolve the relocation. So it is in fact also
+ referenced. */
+ h->ref_regular = 1;
+ h->needs_plt = 1;
+ }
+ }
+ switch (r_type)
+ {
+ case R_390_GOTOFF16:
+ case R_390_GOTOFF32:
+ case R_390_GOTPC:
+ case R_390_GOTPCDBL:
+ /* These relocs do not need a GOT slot. They just load the
+ GOT pointer itself or address something else relative to
+ the GOT. Since the GOT pointer has been set up above we
+ are done. */
+ break;
+
+ case R_390_PLT12DBL:
+ case R_390_PLT16DBL:
+ case R_390_PLT24DBL:
+ case R_390_PLT32DBL:
+ case R_390_PLT32:
+ case R_390_PLTOFF16:
+ case R_390_PLTOFF32:
+ /* 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)
+ {
+ h->needs_plt = 1;
+ h->plt.refcount += 1;
+ }
+ break;
+
+ case R_390_GOTPLT12:
+ case R_390_GOTPLT16:
+ case R_390_GOTPLT20:
+ case R_390_GOTPLT32:
+ case R_390_GOTPLTENT:
+ /* This symbol requires either a procedure linkage table entry
+ or an entry in the local got. We actually build the entry
+ in adjust_dynamic_symbol because whether this is really a
+ global reference can change and with it the fact if we have
+ to create a plt entry or a local got entry. To be able to
+ make a once global symbol a local one we have to keep track
+ of the number of gotplt references that exist for this
+ symbol. */
+ if (h != NULL)
+ {
+ ((struct elf_s390_link_hash_entry *) h)->gotplt_refcount++;
+ h->needs_plt = 1;
+ h->plt.refcount += 1;
+ }
+ else
+ local_got_refcounts[r_symndx] += 1;
+ break;
+
+ case R_390_TLS_LDM32:
+ htab->tls_ldm_got.refcount += 1;
+ break;
+
+ case R_390_TLS_IE32:
+ case R_390_TLS_GOTIE12:
+ case R_390_TLS_GOTIE20:
+ case R_390_TLS_GOTIE32:
+ case R_390_TLS_IEENT:
+ if (info->shared)
+ info->flags |= DF_STATIC_TLS;
+ /* Fall through. */
+
+ case R_390_GOT12:
+ case R_390_GOT16:
+ case R_390_GOT20:
+ case R_390_GOT32:
+ case R_390_GOTENT:
+ case R_390_TLS_GD32:
+ /* This symbol requires a global offset table entry. */
+ switch (r_type)
+ {
+ default:
+ case R_390_GOT12:
+ case R_390_GOT16:
+ case R_390_GOT20:
+ case R_390_GOT32:
+ case R_390_GOTENT:
+ tls_type = GOT_NORMAL;
+ break;
+ case R_390_TLS_GD32:
+ tls_type = GOT_TLS_GD;
+ break;
+ case R_390_TLS_IE32:
+ case R_390_TLS_GOTIE32:
+ tls_type = GOT_TLS_IE;
+ break;
+ case R_390_TLS_GOTIE12:
+ case R_390_TLS_GOTIE20:
+ case R_390_TLS_IEENT:
+ tls_type = GOT_TLS_IE_NLT;
+ break;
+ }
+
+ if (h != NULL)
+ {
+ h->got.refcount += 1;
+ old_tls_type = elf_s390_hash_entry(h)->tls_type;
+ }
+ else
+ {
+ local_got_refcounts[r_symndx] += 1;
+ old_tls_type = elf_s390_local_got_tls_type (abfd) [r_symndx];
+ }
+ /* If a TLS symbol is accessed using IE at least once,
+ there is no point to use dynamic model for it. */
+ if (old_tls_type != tls_type && old_tls_type != GOT_UNKNOWN)
+ {
+ if (old_tls_type == GOT_NORMAL || tls_type == GOT_NORMAL)
+ {
+ (*_bfd_error_handler)
+ (_("%B: `%s' accessed both as normal and thread local symbol"),
+ abfd, h->root.root.string);
+ return FALSE;
+ }
+ if (old_tls_type > tls_type)
+ tls_type = old_tls_type;
+ }
+
+ if (old_tls_type != tls_type)
+ {
+ if (h != NULL)
+ elf_s390_hash_entry (h)->tls_type = tls_type;
+ else
+ elf_s390_local_got_tls_type (abfd) [r_symndx] = tls_type;
+ }
+
+ if (r_type != R_390_TLS_IE32)
+ break;
+ /* Fall through. */
+
+ case R_390_TLS_LE32:
+ /* For static linking and executables this reloc will be
+ calculated at linktime otherwise a TLS_TPOFF runtime
+ reloc will be generated. */
+ if (r_type == R_390_TLS_LE32 && info->pie)
+ break;
+
+ if (!info->shared)
+ break;
+ info->flags |= DF_STATIC_TLS;
+ /* Fall through. */
+
+ case R_390_8:
+ case R_390_16:
+ case R_390_32:
+ case R_390_PC16:
+ case R_390_PC12DBL:
+ case R_390_PC16DBL:
+ case R_390_PC24DBL:
+ case R_390_PC32DBL:
+ case R_390_PC32:
+ if (h != NULL)
+ {
+ /* If this reloc is in a read-only section, we might
+ need a copy reloc. We can't check reliably at this
+ stage whether the section is read-only, as input
+ sections have not yet been mapped to output sections.
+ Tentatively set the flag for now, and correct in
+ adjust_dynamic_symbol. */
+ h->non_got_ref = 1;
+
+ if (!info->shared)
+ {
+ /* We may need a .plt entry if the function this reloc
+ refers to is in a shared lib. */
+ h->plt.refcount += 1;
+ }
+ }
+
+ /* 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). In case of a weak definition,
+ DEF_REGULAR may be cleared later by a strong definition in
+ a shared library. We account for that possibility below by
+ storing information in the relocs_copied field of the hash
+ table entry. A similar situation occurs when creating
+ shared libraries and symbol visibility changes render the
+ symbol local.
+
+ If on the other hand, we are creating an executable, we
+ may need to keep relocations for symbols satisfied by a
+ dynamic library if we manage to avoid copy relocs for the
+ symbol. */
+ if ((info->shared
+ && (sec->flags & SEC_ALLOC) != 0
+ && ((ELF32_R_TYPE (rel->r_info) != R_390_PC16
+ && ELF32_R_TYPE (rel->r_info) != R_390_PC12DBL
+ && ELF32_R_TYPE (rel->r_info) != R_390_PC16DBL
+ && ELF32_R_TYPE (rel->r_info) != R_390_PC24DBL
+ && ELF32_R_TYPE (rel->r_info) != R_390_PC32DBL
+ && ELF32_R_TYPE (rel->r_info) != R_390_PC32)
+ || (h != NULL
+ && (! SYMBOLIC_BIND (info, h)
+ || h->root.type == bfd_link_hash_defweak
+ || !h->def_regular))))
+ || (ELIMINATE_COPY_RELOCS
+ && !info->shared
+ && (sec->flags & SEC_ALLOC) != 0
+ && h != NULL
+ && (h->root.type == bfd_link_hash_defweak
+ || !h->def_regular)))
+ {
+ struct elf_dyn_relocs *p;
+ struct elf_dyn_relocs **head;
+
+ /* We must copy these reloc types into the output file.
+ Create a reloc section in dynobj and make room for
+ this reloc. */
+ if (sreloc == NULL)
+ {
+ if (htab->elf.dynobj == NULL)
+ htab->elf.dynobj = abfd;
+
+ sreloc = _bfd_elf_make_dynamic_reloc_section
+ (sec, htab->elf.dynobj, 2, abfd, /*rela?*/ TRUE);
+
+ if (sreloc == NULL)
+ return FALSE;
+ }
+
+ /* If this is a global symbol, we count the number of
+ relocations we need for this symbol. */
+ if (h != NULL)
+ {
+ head = &((struct elf_s390_link_hash_entry *) h)->dyn_relocs;
+ }
+ else
+ {
+ /* Track dynamic relocs needed for local syms too.
+ We really need local syms available to do this
+ easily. Oh well. */
+ asection *s;
+ void *vpp;
+
+ isym = bfd_sym_from_r_symndx (&htab->sym_cache,
+ abfd, r_symndx);
+ if (isym == NULL)
+ return FALSE;
+
+ s = bfd_section_from_elf_index (abfd, isym->st_shndx);
+ if (s == NULL)
+ s = sec;
+
+ vpp = &elf_section_data (s)->local_dynrel;
+ head = (struct elf_dyn_relocs **) vpp;
+ }
+
+ p = *head;
+ if (p == NULL || p->sec != sec)
+ {
+ bfd_size_type amt = sizeof *p;
+
+ p = ((struct elf_dyn_relocs *)
+ bfd_alloc (htab->elf.dynobj, amt));
+ if (p == NULL)
+ return FALSE;
+ p->next = *head;
+ *head = p;
+ p->sec = sec;
+ p->count = 0;
+ p->pc_count = 0;
+ }
+
+ p->count += 1;
+ if (ELF32_R_TYPE (rel->r_info) == R_390_PC16
+ || ELF32_R_TYPE (rel->r_info) == R_390_PC12DBL
+ || ELF32_R_TYPE (rel->r_info) == R_390_PC16DBL
+ || ELF32_R_TYPE (rel->r_info) == R_390_PC24DBL
+ || ELF32_R_TYPE (rel->r_info) == R_390_PC32DBL
+ || ELF32_R_TYPE (rel->r_info) == R_390_PC32)
+ p->pc_count += 1;
+ }
+ break;
+
+ /* This relocation describes the C++ object vtable hierarchy.
+ Reconstruct it for later use during GC. */
+ case R_390_GNU_VTINHERIT:
+ if (!bfd_elf_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_390_GNU_VTENTRY:
+ BFD_ASSERT (h != NULL);
+ if (h != NULL
+ && !bfd_elf_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_s390_gc_mark_hook (asection *sec,
+ 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_390_GNU_VTINHERIT:
+ case R_390_GNU_VTENTRY:
+ return NULL;
+ }
+ return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
+
+}
+
+/* Update the got entry reference counts for the section being removed. */
+
+static bfd_boolean
+elf_s390_gc_sweep_hook (bfd *abfd,
+ struct bfd_link_info *info,
+ asection *sec,
+ const Elf_Internal_Rela *relocs)
+{
+ struct elf_s390_link_hash_table *htab;
+ Elf_Internal_Shdr *symtab_hdr;
+ struct elf_link_hash_entry **sym_hashes;
+ bfd_signed_vma *local_got_refcounts;
+ const Elf_Internal_Rela *rel, *relend;
+
+ if (info->relocatable)
+ return TRUE;
+
+ htab = elf_s390_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ elf_section_data (sec)->local_dynrel = NULL;
+
+ symtab_hdr = &elf_symtab_hdr (abfd);
+ 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++)
+ {
+ unsigned long r_symndx;
+ unsigned int r_type;
+ struct elf_link_hash_entry *h = NULL;
+
+ r_symndx = ELF32_R_SYM (rel->r_info);
+ if (r_symndx >= symtab_hdr->sh_info)
+ {
+ struct elf_s390_link_hash_entry *eh;
+ struct elf_dyn_relocs **pp;
+ struct elf_dyn_relocs *p;
+
+ 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;
+ eh = (struct elf_s390_link_hash_entry *) h;
+
+ for (pp = &eh->dyn_relocs; (p = *pp) != NULL; pp = &p->next)
+ if (p->sec == sec)
+ {
+ /* Everything must go for SEC. */
+ *pp = p->next;
+ break;
+ }
+ }
+ else
+ {
+ Elf_Internal_Sym *isym;
+
+ /* A local symbol. */
+ isym = bfd_sym_from_r_symndx (&htab->sym_cache,
+ abfd, r_symndx);
+ if (isym == NULL)
+ return FALSE;
+
+ if (ELF_ST_TYPE (isym->st_info) == STT_GNU_IFUNC)
+ {
+ struct plt_entry *plt = elf_s390_local_plt (abfd);
+ if (plt[r_symndx].plt.refcount > 0)
+ plt[r_symndx].plt.refcount--;
+ }
+ }
+
+ r_type = ELF32_R_TYPE (rel->r_info);
+ r_type = elf_s390_tls_transition (info, r_type, h != NULL);
+ switch (r_type)
+ {
+ case R_390_TLS_LDM32:
+ if (elf_s390_hash_table (info)->tls_ldm_got.refcount > 0)
+ elf_s390_hash_table (info)->tls_ldm_got.refcount -= 1;
+ break;
+
+ case R_390_TLS_GD32:
+ case R_390_TLS_IE32:
+ case R_390_TLS_GOTIE12:
+ case R_390_TLS_GOTIE20:
+ case R_390_TLS_GOTIE32:
+ case R_390_TLS_IEENT:
+ case R_390_GOT12:
+ case R_390_GOT16:
+ case R_390_GOT20:
+ case R_390_GOT32:
+ case R_390_GOTOFF16:
+ case R_390_GOTOFF32:
+ case R_390_GOTPC:
+ case R_390_GOTPCDBL:
+ case R_390_GOTENT:
+ if (h != NULL)
+ {
+ if (h->got.refcount > 0)
+ h->got.refcount -= 1;
+ }
+ else if (local_got_refcounts != NULL)
+ {
+ if (local_got_refcounts[r_symndx] > 0)
+ local_got_refcounts[r_symndx] -= 1;
+ }
+ break;
+
+ case R_390_8:
+ case R_390_12:
+ case R_390_16:
+ case R_390_20:
+ case R_390_32:
+ case R_390_PC16:
+ case R_390_PC12DBL:
+ case R_390_PC16DBL:
+ case R_390_PC24DBL:
+ case R_390_PC32DBL:
+ case R_390_PC32:
+ if (info->shared)
+ break;
+ /* Fall through. */
+
+ case R_390_PLT12DBL:
+ case R_390_PLT16DBL:
+ case R_390_PLT24DBL:
+ case R_390_PLT32DBL:
+ case R_390_PLT32:
+ case R_390_PLTOFF16:
+ case R_390_PLTOFF32:
+ if (h != NULL)
+ {
+ if (h->plt.refcount > 0)
+ h->plt.refcount -= 1;
+ }
+ break;
+
+ case R_390_GOTPLT12:
+ case R_390_GOTPLT16:
+ case R_390_GOTPLT20:
+ case R_390_GOTPLT32:
+ case R_390_GOTPLTENT:
+ if (h != NULL)
+ {
+ if (h->plt.refcount > 0)
+ {
+ ((struct elf_s390_link_hash_entry *) h)->gotplt_refcount--;
+ h->plt.refcount -= 1;
+ }
+ }
+ else if (local_got_refcounts != NULL)
+ {
+ if (local_got_refcounts[r_symndx] > 0)
+ local_got_refcounts[r_symndx] -= 1;
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ return TRUE;
+}
+
+/* Make sure we emit a GOT entry if the symbol was supposed to have a PLT
+ entry but we found we will not create any. Called when we find we will
+ not have any PLT for this symbol, by for example
+ elf_s390_adjust_dynamic_symbol when we're doing a proper dynamic link,
+ or elf_s390_size_dynamic_sections if no dynamic sections will be
+ created (we're only linking static objects). */
+
+static void
+elf_s390_adjust_gotplt (struct elf_s390_link_hash_entry *h)
+{
+ if (h->elf.root.type == bfd_link_hash_warning)
+ h = (struct elf_s390_link_hash_entry *) h->elf.root.u.i.link;
+
+ if (h->gotplt_refcount <= 0)
+ return;
+
+ /* We simply add the number of gotplt references to the number
+ * of got references for this symbol. */
+ h->elf.got.refcount += h->gotplt_refcount;
+ h->gotplt_refcount = -1;
+}
+
+/* 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 bfd_boolean
+elf_s390_adjust_dynamic_symbol (struct bfd_link_info *info,
+ struct elf_link_hash_entry *h)
+{
+ struct elf_s390_link_hash_table *htab;
+ asection *s;
+
+ /* STT_GNU_IFUNC symbol must go through PLT. */
+ if (s390_is_ifunc_symbol_p (h))
+ return TRUE;
+
+ /* 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). */
+ if (h->type == STT_FUNC
+ || h->needs_plt)
+ {
+ if (h->plt.refcount <= 0
+ || SYMBOL_CALLS_LOCAL (info, h)
+ || (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
+ && h->root.type != bfd_link_hash_undefweak))
+ {
+ /* 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, or if all references were garbage collected. In
+ such a case, we don't actually need to build a procedure
+ linkage table, and we can just do a PC32 reloc instead. */
+ h->plt.offset = (bfd_vma) -1;
+ h->needs_plt = 0;
+ elf_s390_adjust_gotplt((struct elf_s390_link_hash_entry *) h);
+ }
+
+ return TRUE;
+ }
+ else
+ /* It's possible that we incorrectly decided a .plt reloc was
+ needed for an R_390_PC32 reloc to a non-function sym in
+ check_relocs. We can't decide accurately between function and
+ non-function syms in check-relocs; Objects loaded later in
+ the link may change h->type. So fix it now. */
+ 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->u.weakdef != NULL)
+ {
+ BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
+ || h->u.weakdef->root.type == bfd_link_hash_defweak);
+ h->root.u.def.section = h->u.weakdef->root.u.def.section;
+ h->root.u.def.value = h->u.weakdef->root.u.def.value;
+ if (ELIMINATE_COPY_RELOCS || info->nocopyreloc)
+ h->non_got_ref = h->u.weakdef->non_got_ref;
+ 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;
+
+ /* If there are no references to this symbol that do not use the
+ GOT, we don't need to generate a copy reloc. */
+ if (!h->non_got_ref)
+ return TRUE;
+
+ /* If -z nocopyreloc was given, we won't generate them either. */
+ if (info->nocopyreloc)
+ {
+ h->non_got_ref = 0;
+ return TRUE;
+ }
+
+ if (ELIMINATE_COPY_RELOCS)
+ {
+ struct elf_s390_link_hash_entry * eh;
+ struct elf_dyn_relocs *p;
+
+ eh = (struct elf_s390_link_hash_entry *) h;
+ for (p = eh->dyn_relocs; p != NULL; p = p->next)
+ {
+ s = p->sec->output_section;
+ if (s != NULL && (s->flags & SEC_READONLY) != 0)
+ break;
+ }
+
+ /* If we didn't find any dynamic relocs in read-only sections, then
+ we'll be keeping the dynamic relocs and avoiding the copy reloc. */
+ if (p == NULL)
+ {
+ h->non_got_ref = 0;
+ 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. */
+
+ htab = elf_s390_hash_table (info);
+
+ /* We must generate a R_390_COPY reloc to tell the dynamic linker to
+ copy the initial value out of the dynamic object and into the
+ runtime process image. */
+ if ((h->root.u.def.section->flags & SEC_ALLOC) != 0 && h->size != 0)
+ {
+ htab->srelbss->size += sizeof (Elf32_External_Rela);
+ h->needs_copy = 1;
+ }
+
+ s = htab->sdynbss;
+
+ return _bfd_elf_adjust_dynamic_copy (h, s);
+}
+
+/* Allocate space in .plt, .got and associated reloc sections for
+ dynamic relocs. */
+
+static bfd_boolean
+allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
+{
+ struct bfd_link_info *info;
+ struct elf_s390_link_hash_table *htab;
+ struct elf_s390_link_hash_entry *eh = (struct elf_s390_link_hash_entry *)h;
+ struct elf_dyn_relocs *p;
+
+ if (h->root.type == bfd_link_hash_indirect)
+ return TRUE;
+
+ info = (struct bfd_link_info *) inf;
+ htab = elf_s390_hash_table (info);
+
+ /* Since STT_GNU_IFUNC symbol must go through PLT, we handle it
+ here if it is defined and referenced in a non-shared object. */
+ if (s390_is_ifunc_symbol_p (h) && h->def_regular)
+ return s390_elf_allocate_ifunc_dyn_relocs (info, h,
+ &eh->dyn_relocs);
+ else if (htab->elf.dynamic_sections_created
+ && h->plt.refcount > 0)
+ {
+ /* Make sure this symbol is output as a dynamic symbol.
+ Undefined weak syms won't yet be marked as dynamic. */
+ if (h->dynindx == -1
+ && !h->forced_local)
+ {
+ if (! bfd_elf_link_record_dynamic_symbol (info, h))
+ return FALSE;
+ }
+
+ if (info->shared
+ || WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, 0, h))
+ {
+ asection *s = htab->elf.splt;
+
+ /* If this is the first .plt entry, make room for the special
+ first entry. */
+ if (s->size == 0)
+ s->size += PLT_FIRST_ENTRY_SIZE;
+
+ h->plt.offset = s->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->def_regular)
+ {
+ h->root.u.def.section = s;
+ h->root.u.def.value = h->plt.offset;
+ }
+
+ /* Make room for this entry. */
+ s->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. */
+ htab->elf.sgotplt->size += GOT_ENTRY_SIZE;
+
+ /* We also need to make an entry in the .rela.plt section. */
+ htab->elf.srelplt->size += sizeof (Elf32_External_Rela);
+ }
+ else
+ {
+ h->plt.offset = (bfd_vma) -1;
+ h->needs_plt = 0;
+ elf_s390_adjust_gotplt((struct elf_s390_link_hash_entry *) h);
+ }
+ }
+ else
+ {
+ h->plt.offset = (bfd_vma) -1;
+ h->needs_plt = 0;
+ elf_s390_adjust_gotplt((struct elf_s390_link_hash_entry *) h);
+ }
+
+ /* If R_390_TLS_{IE32,GOTIE32,GOTIE12,IEENT} symbol is now local to
+ the binary, we can optimize a bit. IE32 and GOTIE32 get converted
+ to R_390_TLS_LE32 requiring no TLS entry. For GOTIE12 and IEENT
+ we can save the dynamic TLS relocation. */
+ if (h->got.refcount > 0
+ && !info->shared
+ && h->dynindx == -1
+ && elf_s390_hash_entry(h)->tls_type >= GOT_TLS_IE)
+ {
+ if (elf_s390_hash_entry(h)->tls_type == GOT_TLS_IE_NLT)
+ /* For the GOTIE access without a literal pool entry the offset has
+ to be stored somewhere. The immediate value in the instruction
+ is not bit enough so the value is stored in the got. */
+ {
+ h->got.offset = htab->elf.sgot->size;
+ htab->elf.sgot->size += GOT_ENTRY_SIZE;
+ }
+ else
+ h->got.offset = (bfd_vma) -1;
+ }
+ else if (h->got.refcount > 0)
+ {
+ asection *s;
+ bfd_boolean dyn;
+ int tls_type = elf_s390_hash_entry(h)->tls_type;
+
+ /* Make sure this symbol is output as a dynamic symbol.
+ Undefined weak syms won't yet be marked as dynamic. */
+ if (h->dynindx == -1
+ && !h->forced_local)
+ {
+ if (! bfd_elf_link_record_dynamic_symbol (info, h))
+ return FALSE;
+ }
+
+ s = htab->elf.sgot;
+ h->got.offset = s->size;
+ s->size += GOT_ENTRY_SIZE;
+ /* R_390_TLS_GD32 needs 2 consecutive GOT slots. */
+ if (tls_type == GOT_TLS_GD)
+ s->size += GOT_ENTRY_SIZE;
+ dyn = htab->elf.dynamic_sections_created;
+ /* R_390_TLS_IE32 needs one dynamic relocation,
+ R_390_TLS_GD32 needs one if local symbol and two if global. */
+ if ((tls_type == GOT_TLS_GD && h->dynindx == -1)
+ || tls_type >= GOT_TLS_IE)
+ htab->elf.srelgot->size += sizeof (Elf32_External_Rela);
+ else if (tls_type == GOT_TLS_GD)
+ htab->elf.srelgot->size += 2 * sizeof (Elf32_External_Rela);
+ else if ((ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
+ || h->root.type != bfd_link_hash_undefweak)
+ && (info->shared
+ || WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, 0, h)))
+ htab->elf.srelgot->size += sizeof (Elf32_External_Rela);
+ }
+ else
+ h->got.offset = (bfd_vma) -1;
+
+ if (eh->dyn_relocs == NULL)
+ return TRUE;
+
+ /* In the shared -Bsymbolic case, discard space allocated for
+ dynamic pc-relative relocs against symbols which turn out to be
+ defined in regular objects. For the normal shared case, discard
+ space for pc-relative relocs that have become local due to symbol
+ visibility changes. */
+
+ if (info->shared)
+ {
+ if (SYMBOL_CALLS_LOCAL (info, h))
+ {
+ struct elf_dyn_relocs **pp;
+
+ for (pp = &eh->dyn_relocs; (p = *pp) != NULL; )
+ {
+ p->count -= p->pc_count;
+ p->pc_count = 0;
+ if (p->count == 0)
+ *pp = p->next;
+ else
+ pp = &p->next;
+ }
+ }
+
+ /* Also discard relocs on undefined weak syms with non-default
+ visibility. */
+ if (eh->dyn_relocs != NULL
+ && h->root.type == bfd_link_hash_undefweak)
+ {
+ if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
+ eh->dyn_relocs = NULL;
+
+ /* Make sure undefined weak symbols are output as a dynamic
+ symbol in PIEs. */
+ else if (h->dynindx == -1
+ && !h->forced_local)
+ {
+ if (! bfd_elf_link_record_dynamic_symbol (info, h))
+ return FALSE;
+ }
+ }
+ }
+ else if (ELIMINATE_COPY_RELOCS)
+ {
+ /* For the non-shared case, discard space for relocs against
+ symbols which turn out to need copy relocs or are not
+ dynamic. */
+
+ if (!h->non_got_ref
+ && ((h->def_dynamic
+ && !h->def_regular)
+ || (htab->elf.dynamic_sections_created
+ && (h->root.type == bfd_link_hash_undefweak
+ || h->root.type == bfd_link_hash_undefined))))
+ {
+ /* Make sure this symbol is output as a dynamic symbol.
+ Undefined weak syms won't yet be marked as dynamic. */
+ if (h->dynindx == -1
+ && !h->forced_local)
+ {
+ if (! bfd_elf_link_record_dynamic_symbol (info, h))
+ return FALSE;
+ }
+
+ /* If that succeeded, we know we'll be keeping all the
+ relocs. */
+ if (h->dynindx != -1)
+ goto keep;
+ }
+
+ eh->dyn_relocs = NULL;
+
+ keep: ;
+ }
+
+ /* Finally, allocate space. */
+ for (p = eh->dyn_relocs; p != NULL; p = p->next)
+ {
+ asection *sreloc = elf_section_data (p->sec)->sreloc;
+
+ sreloc->size += p->count * sizeof (Elf32_External_Rela);
+ }
+
+ return TRUE;
+}
+
+/* Find any dynamic relocs that apply to read-only sections. */
+
+static bfd_boolean
+readonly_dynrelocs (struct elf_link_hash_entry *h, void * inf)
+{
+ struct elf_s390_link_hash_entry *eh;
+ struct elf_dyn_relocs *p;
+
+ eh = (struct elf_s390_link_hash_entry *) h;
+ for (p = eh->dyn_relocs; p != NULL; p = p->next)
+ {
+ asection *s = p->sec->output_section;
+
+ if (s != NULL && (s->flags & SEC_READONLY) != 0)
+ {
+ struct bfd_link_info *info = (struct bfd_link_info *) inf;
+
+ info->flags |= DF_TEXTREL;
+
+ /* Not an error, just cut short the traversal. */
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+/* Set the sizes of the dynamic sections. */
+
+static bfd_boolean
+elf_s390_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
+ struct bfd_link_info *info)
+{
+ struct elf_s390_link_hash_table *htab;
+ bfd *dynobj;
+ asection *s;
+ bfd_boolean relocs;
+ bfd *ibfd;
+
+ htab = elf_s390_hash_table (info);
+ dynobj = htab->elf.dynobj;
+ if (dynobj == NULL)
+ abort ();
+
+ if (htab->elf.dynamic_sections_created)
+ {
+ /* Set the contents of the .interp section to the interpreter. */
+ if (info->executable)
+ {
+ s = bfd_get_linker_section (dynobj, ".interp");
+ if (s == NULL)
+ abort ();
+ s->size = sizeof ELF_DYNAMIC_INTERPRETER;
+ s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
+ }
+ }
+
+ /* Set up .got offsets for local syms, and space for local dynamic
+ relocs. */
+ for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next)
+ {
+ bfd_signed_vma *local_got;
+ bfd_signed_vma *end_local_got;
+ char *local_tls_type;
+ bfd_size_type locsymcount;
+ Elf_Internal_Shdr *symtab_hdr;
+ asection *srela;
+ struct plt_entry *local_plt;
+ unsigned int i;
+
+ if (! is_s390_elf (ibfd))
+ continue;
+
+ for (s = ibfd->sections; s != NULL; s = s->next)
+ {
+ struct elf_dyn_relocs *p;
+
+ for (p = elf_section_data (s)->local_dynrel; p != NULL; p = p->next)
+ {
+ if (!bfd_is_abs_section (p->sec)
+ && bfd_is_abs_section (p->sec->output_section))
+ {
+ /* Input section has been discarded, either because
+ it is a copy of a linkonce section or due to
+ linker script /DISCARD/, so we'll be discarding
+ the relocs too. */
+ }
+ else if (p->count != 0)
+ {
+ srela = elf_section_data (p->sec)->sreloc;
+ srela->size += p->count * sizeof (Elf32_External_Rela);
+ if ((p->sec->output_section->flags & SEC_READONLY) != 0)
+ info->flags |= DF_TEXTREL;
+ }
+ }
+ }
+
+ local_got = elf_local_got_refcounts (ibfd);
+ if (!local_got)
+ continue;
+
+ symtab_hdr = &elf_symtab_hdr (ibfd);
+ locsymcount = symtab_hdr->sh_info;
+ end_local_got = local_got + locsymcount;
+ local_tls_type = elf_s390_local_got_tls_type (ibfd);
+ s = htab->elf.sgot;
+ srela = htab->elf.srelgot;
+ for (; local_got < end_local_got; ++local_got, ++local_tls_type)
+ {
+ if (*local_got > 0)
+ {
+ *local_got = s->size;
+ s->size += GOT_ENTRY_SIZE;
+ if (*local_tls_type == GOT_TLS_GD)
+ s->size += GOT_ENTRY_SIZE;
+ if (info->shared)
+ srela->size += sizeof (Elf32_External_Rela);
+ }
+ else
+ *local_got = (bfd_vma) -1;
+ }
+ local_plt = elf_s390_local_plt (ibfd);
+ for (i = 0; i < symtab_hdr->sh_info; i++)
+ {
+ if (local_plt[i].plt.refcount > 0)
+ {
+ local_plt[i].plt.offset = htab->elf.iplt->size;
+ htab->elf.iplt->size += PLT_ENTRY_SIZE;
+ htab->elf.igotplt->size += GOT_ENTRY_SIZE;
+ htab->elf.irelplt->size += RELA_ENTRY_SIZE;
+ }
+ else
+ local_plt[i].plt.offset = (bfd_vma) -1;
+ }
+ }
+
+ if (htab->tls_ldm_got.refcount > 0)
+ {
+ /* Allocate 2 got entries and 1 dynamic reloc for R_390_TLS_LDM32
+ relocs. */
+ htab->tls_ldm_got.offset = htab->elf.sgot->size;
+ htab->elf.sgot->size += 2 * GOT_ENTRY_SIZE;
+ htab->elf.srelgot->size += sizeof (Elf32_External_Rela);
+ }
+ else
+ htab->tls_ldm_got.offset = -1;
+
+ /* Allocate global sym .plt and .got entries, and space for global
+ sym dynamic relocs. */
+ elf_link_hash_traverse (&htab->elf, allocate_dynrelocs, info);
+
+ /* We now have determined the sizes of the various dynamic sections.
+ Allocate memory for them. */
+ relocs = FALSE;
+ for (s = dynobj->sections; s != NULL; s = s->next)
+ {
+ if ((s->flags & SEC_LINKER_CREATED) == 0)
+ continue;
+
+ if (s == htab->elf.splt
+ || s == htab->elf.sgot
+ || s == htab->elf.sgotplt
+ || s == htab->sdynbss
+ || s == htab->elf.iplt
+ || s == htab->elf.igotplt
+ || s == htab->irelifunc)
+ {
+ /* Strip this section if we don't need it; see the
+ comment below. */
+ }
+ else if (CONST_STRNEQ (bfd_get_section_name (dynobj, s), ".rela"))
+ {
+ if (s->size != 0)
+ relocs = 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
+ {
+ /* It's not one of our sections, so don't allocate space. */
+ continue;
+ }
+
+ if (s->size == 0)
+ {
+ /* 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. */
+
+ s->flags |= SEC_EXCLUDE;
+ continue;
+ }
+
+ if ((s->flags & SEC_HAS_CONTENTS) == 0)
+ continue;
+
+ /* Allocate memory for the section contents. We use bfd_zalloc
+ here in case unused entries are not reclaimed before the
+ section's contents are written out. This should not happen,
+ but this way if it does, we get a R_390_NONE reloc instead
+ of garbage. */
+ s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->size);
+ if (s->contents == NULL)
+ return FALSE;
+ }
+
+ if (htab->elf.dynamic_sections_created)
+ {
+ /* Add some entries to the .dynamic section. We fill in the
+ values later, in elf_s390_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. */
+#define add_dynamic_entry(TAG, VAL) \
+ _bfd_elf_add_dynamic_entry (info, TAG, VAL)
+
+ if (info->executable)
+ {
+ if (!add_dynamic_entry (DT_DEBUG, 0))
+ return FALSE;
+ }
+
+ if (htab->elf.splt->size != 0)
+ {
+ if (!add_dynamic_entry (DT_PLTGOT, 0)
+ || !add_dynamic_entry (DT_PLTRELSZ, 0)
+ || !add_dynamic_entry (DT_PLTREL, DT_RELA)
+ || !add_dynamic_entry (DT_JMPREL, 0))
+ return FALSE;
+ }
+
+ if (relocs)
+ {
+ if (!add_dynamic_entry (DT_RELA, 0)
+ || !add_dynamic_entry (DT_RELASZ, 0)
+ || !add_dynamic_entry (DT_RELAENT, sizeof (Elf32_External_Rela)))
+ return FALSE;
+
+ /* If any dynamic relocs apply to a read-only section,
+ then we need a DT_TEXTREL entry. */
+ if ((info->flags & DF_TEXTREL) == 0)
+ elf_link_hash_traverse (&htab->elf, readonly_dynrelocs, info);
+
+ if ((info->flags & DF_TEXTREL) != 0)
+ {
+ if (!add_dynamic_entry (DT_TEXTREL, 0))
+ return FALSE;
+ }
+ }
+ }
+#undef add_dynamic_entry
+
+ return TRUE;
+}
+
+/* Return the base VMA address which should be subtracted from real addresses
+ when resolving @dtpoff relocation.
+ This is PT_TLS segment p_vaddr. */
+
+static bfd_vma
+dtpoff_base (struct bfd_link_info *info)
+{
+ /* If tls_sec is NULL, we should have signalled an error already. */
+ if (elf_hash_table (info)->tls_sec == NULL)
+ return 0;
+ return elf_hash_table (info)->tls_sec->vma;
+}
+
+/* Return the relocation value for @tpoff relocation
+ if STT_TLS virtual address is ADDRESS. */
+
+static bfd_vma
+tpoff (struct bfd_link_info *info, bfd_vma address)
+{
+ struct elf_link_hash_table *htab = elf_hash_table (info);
+
+ /* If tls_sec is NULL, we should have signalled an error already. */
+ if (htab->tls_sec == NULL)
+ return 0;
+ return htab->tls_size + htab->tls_sec->vma - address;
+}
+
+/* Complain if TLS instruction relocation is against an invalid
+ instruction. */
+
+static void
+invalid_tls_insn (bfd *input_bfd,
+ asection *input_section,
+ Elf_Internal_Rela *rel)
+{
+ reloc_howto_type *howto;
+
+ howto = elf_howto_table + ELF32_R_TYPE (rel->r_info);
+ (*_bfd_error_handler)
+ (_("%B(%A+0x%lx): invalid instruction for TLS relocation %s"),
+ input_bfd,
+ input_section,
+ (long) rel->r_offset,
+ howto->name);
+ bfd_set_error (bfd_error_bad_value);
+}
+
+/* Relocate a 390 ELF section. */
+
+static bfd_boolean
+elf_s390_relocate_section (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)
+{
+ struct elf_s390_link_hash_table *htab;
+ Elf_Internal_Shdr *symtab_hdr;
+ struct elf_link_hash_entry **sym_hashes;
+ bfd_vma *local_got_offsets;
+ Elf_Internal_Rela *rel;
+ Elf_Internal_Rela *relend;
+
+ BFD_ASSERT (is_s390_elf (input_bfd));
+
+ htab = elf_s390_hash_table (info);
+ symtab_hdr = &elf_symtab_hdr (input_bfd);
+ sym_hashes = elf_sym_hashes (input_bfd);
+ local_got_offsets = elf_local_got_offsets (input_bfd);
+
+ rel = relocs;
+ relend = relocs + input_section->reloc_count;
+ for (; rel < relend; rel++)
+ {
+ unsigned 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 off;
+ bfd_vma relocation;
+ bfd_boolean unresolved_reloc;
+ bfd_reloc_status_type r;
+ int tls_type;
+ asection *base_got = htab->elf.sgot;
+
+ r_type = ELF32_R_TYPE (rel->r_info);
+ if (r_type == (int) R_390_GNU_VTINHERIT
+ || r_type == (int) R_390_GNU_VTENTRY)
+ continue;
+ if (r_type >= (int) R_390_max)
+ {
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+
+ howto = elf_howto_table + r_type;
+ r_symndx = ELF32_R_SYM (rel->r_info);
+
+ h = NULL;
+ sym = NULL;
+ sec = NULL;
+ unresolved_reloc = FALSE;
+ if (r_symndx < symtab_hdr->sh_info)
+ {
+ sym = local_syms + r_symndx;
+ sec = local_sections[r_symndx];
+ if (ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC)
+ {
+ struct plt_entry *local_plt = elf_s390_local_plt (input_bfd);
+ if (local_plt == NULL)
+ return FALSE;
+
+ /* Address of the PLT slot. */
+ relocation = (htab->elf.iplt->output_section->vma
+ + htab->elf.iplt->output_offset
+ + local_plt[r_symndx].plt.offset);
+
+ switch (r_type)
+ {
+ case R_390_PLTOFF16:
+ case R_390_PLTOFF32:
+ relocation -= htab->elf.sgot->output_section->vma;
+ break;
+ case R_390_GOTPLT12:
+ case R_390_GOTPLT16:
+ case R_390_GOTPLT20:
+ case R_390_GOTPLT32:
+ case R_390_GOTPLTENT:
+ case R_390_GOT12:
+ case R_390_GOT16:
+ case R_390_GOT20:
+ case R_390_GOT32:
+ case R_390_GOTENT:
+ {
+ /* Write the PLT slot address into the GOT slot. */
+ bfd_put_32 (output_bfd, relocation,
+ htab->elf.sgot->contents +
+ local_got_offsets[r_symndx]);
+ relocation = (local_got_offsets[r_symndx] +
+ htab->elf.sgot->output_offset);
+
+ if (r_type == R_390_GOTENT || r_type == R_390_GOTPLTENT)
+ relocation += htab->elf.sgot->output_section->vma;
+ break;
+ }
+ default:
+ break;
+ }
+ /* The output section is needed later in
+ finish_dynamic_section when creating the dynamic
+ relocation. */
+ local_plt[r_symndx].sec = sec;
+ goto do_relocation;
+ }
+ else
+ relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
+ }
+ else
+ {
+ bfd_boolean warned ATTRIBUTE_UNUSED;
+ bfd_boolean ignored ATTRIBUTE_UNUSED;
+
+ RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
+ r_symndx, symtab_hdr, sym_hashes,
+ h, sec, relocation,
+ unresolved_reloc, warned, ignored);
+ }
+
+ if (sec != NULL && discarded_section (sec))
+ RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+ rel, 1, relend, howto, 0, contents);
+
+ if (info->relocatable)
+ continue;
+
+ switch (r_type)
+ {
+ case R_390_GOTPLT12:
+ case R_390_GOTPLT16:
+ case R_390_GOTPLT20:
+ case R_390_GOTPLT32:
+ case R_390_GOTPLTENT:
+ /* There are three cases for a GOTPLT relocation. 1) The
+ relocation is against the jump slot entry of a plt that
+ will get emitted to the output file. 2) The relocation
+ is against the jump slot of a plt entry that has been
+ removed. elf_s390_adjust_gotplt has created a GOT entry
+ as replacement. 3) The relocation is against a local symbol.
+ Cases 2) and 3) are the same as the GOT relocation code
+ so we just have to test for case 1 and fall through for
+ the other two. */
+ if (h != NULL && h->plt.offset != (bfd_vma) -1)
+ {
+ bfd_vma plt_index;
+
+ if (s390_is_ifunc_symbol_p (h))
+ {
+ plt_index = h->plt.offset / PLT_ENTRY_SIZE;
+ relocation = (plt_index * GOT_ENTRY_SIZE +
+ htab->elf.igotplt->output_offset);
+ if (r_type == R_390_GOTPLTENT)
+ relocation += htab->elf.igotplt->output_section->vma;
+ }
+ else
+ {
+ /* Calc. index no.
+ Current offset - size first entry / entry size. */
+ plt_index = (h->plt.offset - PLT_FIRST_ENTRY_SIZE) /
+ PLT_ENTRY_SIZE;
+
+ /* Offset in GOT is PLT index plus GOT headers(3)
+ times 4, addr & GOT addr. */
+ relocation = (plt_index + 3) * GOT_ENTRY_SIZE;
+ if (r_type == R_390_GOTPLTENT)
+ relocation += htab->elf.sgot->output_section->vma;
+ }
+ unresolved_reloc = FALSE;
+
+ }
+ /* Fall through. */
+
+ case R_390_GOT12:
+ case R_390_GOT16:
+ case R_390_GOT20:
+ case R_390_GOT32:
+ case R_390_GOTENT:
+ /* Relocation is to the entry for this symbol in the global
+ offset table. */
+ if (base_got == NULL)
+ abort ();
+
+ if (h != NULL)
+ {
+ bfd_boolean dyn;
+
+ off = h->got.offset;
+ dyn = htab->elf.dynamic_sections_created;
+
+ if (s390_is_ifunc_symbol_p (h))
+ {
+ BFD_ASSERT (h->plt.offset != (bfd_vma) -1);
+ if (off == (bfd_vma)-1)
+ {
+ /* No explicit GOT usage so redirect to the
+ got.iplt slot. */
+ base_got = htab->elf.igotplt;
+ off = h->plt.offset / PLT_ENTRY_SIZE * GOT_ENTRY_SIZE;
+ }
+ else
+ {
+ /* Explicit GOT slots must contain the address
+ of the PLT slot. This will be handled in
+ finish_dynamic_symbol. */
+ }
+ }
+ else if (! WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h)
+ || (info->shared
+ && SYMBOL_REFERENCES_LOCAL (info, h))
+ || (ELF_ST_VISIBILITY (h->other)
+ && h->root.type == bfd_link_hash_undefweak))
+
+ {
+ /* 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 2, 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,
+ base_got->contents + off);
+ h->got.offset |= 1;
+ }
+
+ if ((h->def_regular
+ && info->shared
+ && SYMBOL_REFERENCES_LOCAL (info, h))
+ /* lrl rx,sym@GOTENT -> larl rx, sym */
+ && ((r_type == R_390_GOTENT
+ && (bfd_get_16 (input_bfd,
+ contents + rel->r_offset - 2)
+ & 0xff0f) == 0xc40d)
+ /* ly rx, sym@GOT(r12) -> larl rx, sym */
+ || (r_type == R_390_GOT20
+ && (bfd_get_32 (input_bfd,
+ contents + rel->r_offset - 2)
+ & 0xff00f000) == 0xe300c000
+ && bfd_get_8 (input_bfd,
+ contents + rel->r_offset + 3) == 0x58)))
+ {
+ unsigned short new_insn =
+ (0xc000 | (bfd_get_8 (input_bfd,
+ contents + rel->r_offset - 1) & 0xf0));
+ bfd_put_16 (output_bfd, new_insn,
+ contents + rel->r_offset - 2);
+ r_type = R_390_PC32DBL;
+ rel->r_addend = 2;
+ howto = elf_howto_table + r_type;
+ relocation = h->root.u.def.value
+ + h->root.u.def.section->output_section->vma
+ + h->root.u.def.section->output_offset;
+ goto do_relocation;
+ }
+ }
+ else
+ unresolved_reloc = FALSE;
+ }
+ else
+ {
+ if (local_got_offsets == NULL)
+ abort ();
+
+ 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,
+ htab->elf.sgot->contents + off);
+
+ if (info->shared)
+ {
+ asection *srelgot;
+ Elf_Internal_Rela outrel;
+ bfd_byte *loc;
+
+ srelgot = htab->elf.srelgot;
+ if (srelgot == NULL)
+ abort ();
+
+ outrel.r_offset = (htab->elf.sgot->output_section->vma
+ + htab->elf.sgot->output_offset
+ + off);
+ outrel.r_info = ELF32_R_INFO (0, R_390_RELATIVE);
+ outrel.r_addend = relocation;
+ loc = srelgot->contents;
+ loc += srelgot->reloc_count++ * sizeof (Elf32_External_Rela);
+ bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
+ }
+
+ local_got_offsets[r_symndx] |= 1;
+ }
+ }
+
+ if (off >= (bfd_vma) -2)
+ abort ();
+
+ relocation = base_got->output_offset + off;
+
+ /* For @GOTENT the relocation is against the offset between
+ the instruction and the symbols entry in the GOT and not
+ between the start of the GOT and the symbols entry. We
+ add the vma of the GOT to get the correct value. */
+ if ( r_type == R_390_GOTENT
+ || r_type == R_390_GOTPLTENT)
+ relocation += base_got->output_section->vma;
+
+ break;
+
+ case R_390_GOTOFF16:
+ case R_390_GOTOFF32:
+ /* Relocation is relative to the start of the global offset
+ table. */
+
+ /* 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 -= htab->elf.sgot->output_section->vma;
+ break;
+
+ case R_390_GOTPC:
+ case R_390_GOTPCDBL:
+ /* Use global offset table as symbol value. */
+ relocation = htab->elf.sgot->output_section->vma;
+ unresolved_reloc = FALSE;
+ break;
+
+ case R_390_PLT12DBL:
+ case R_390_PLT16DBL:
+ case R_390_PLT24DBL:
+ case R_390_PLT32DBL:
+ case R_390_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)
+ break;
+
+ if (h->plt.offset == (bfd_vma) -1
+ || (htab->elf.splt == NULL && htab->elf.iplt == NULL))
+ {
+ /* We didn't make a PLT entry for this symbol. This
+ happens when statically linking PIC code, or when
+ using -Bsymbolic. */
+ break;
+ }
+
+ if (s390_is_ifunc_symbol_p (h))
+ relocation = (htab->elf.iplt->output_section->vma
+ + htab->elf.iplt->output_offset
+ + h->plt.offset);
+ else
+ relocation = (htab->elf.splt->output_section->vma
+ + htab->elf.splt->output_offset
+ + h->plt.offset);
+ unresolved_reloc = FALSE;
+ break;
+
+ case R_390_PLTOFF16:
+ case R_390_PLTOFF32:
+ /* Relocation is to the entry for this symbol in the
+ procedure linkage table relative to the start of the GOT. */
+
+ /* For local symbols or if we didn't make a PLT entry for
+ this symbol resolve the symbol directly. */
+ if (h == NULL
+ || h->plt.offset == (bfd_vma) -1
+ || (htab->elf.splt == NULL && !s390_is_ifunc_symbol_p (h)))
+ {
+ relocation -= htab->elf.sgot->output_section->vma;
+ break;
+ }
+
+ if (s390_is_ifunc_symbol_p (h))
+ relocation = (htab->elf.iplt->output_section->vma
+ + htab->elf.iplt->output_offset
+ + h->plt.offset
+ - htab->elf.sgot->output_section->vma);
+ else
+ relocation = (htab->elf.splt->output_section->vma
+ + htab->elf.splt->output_offset
+ + h->plt.offset
+ - htab->elf.sgot->output_section->vma);
+ unresolved_reloc = FALSE;
+ break;
+
+ case R_390_8:
+ case R_390_16:
+ case R_390_32:
+ case R_390_PC16:
+ case R_390_PC12DBL:
+ case R_390_PC16DBL:
+ case R_390_PC24DBL:
+ case R_390_PC32DBL:
+ case R_390_PC32:
+ if (h != NULL
+ && s390_is_ifunc_symbol_p (h)
+ && h->def_regular)
+ {
+ if (!info->shared || !h->non_got_ref)
+ {
+ /* For a non-shared object STT_GNU_IFUNC symbol must
+ go through PLT. */
+ relocation = (htab->elf.iplt->output_section->vma
+ + htab->elf.iplt->output_offset
+ + h ->plt.offset);
+ goto do_relocation;
+ }
+ else
+ {
+ /* For shared objects a runtime relocation is needed. */
+
+ Elf_Internal_Rela outrel;
+ asection *sreloc;
+
+ /* Need a dynamic relocation to get the real function
+ address. */
+ outrel.r_offset = _bfd_elf_section_offset (output_bfd,
+ info,
+ input_section,
+ rel->r_offset);
+ if (outrel.r_offset == (bfd_vma) -1
+ || outrel.r_offset == (bfd_vma) -2)
+ abort ();
+
+ outrel.r_offset += (input_section->output_section->vma
+ + input_section->output_offset);
+
+ if (h->dynindx == -1
+ || h->forced_local
+ || info->executable)
+ {
+ /* This symbol is resolved locally. */
+ outrel.r_info = ELF32_R_INFO (0, R_390_IRELATIVE);
+ outrel.r_addend = (h->root.u.def.value
+ + h->root.u.def.section->output_section->vma
+ + h->root.u.def.section->output_offset);
+ }
+ else
+ {
+ outrel.r_info = ELF32_R_INFO (h->dynindx, r_type);
+ outrel.r_addend = 0;
+ }
+
+ sreloc = htab->elf.irelifunc;
+ elf_append_rela (output_bfd, sreloc, &outrel);
+
+ /* 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. For an
+ internal symbol, we have updated addend. */
+ continue;
+ }
+ }
+
+ if ((input_section->flags & SEC_ALLOC) == 0)
+ break;
+
+ if ((info->shared
+ && (h == NULL
+ || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
+ || h->root.type != bfd_link_hash_undefweak)
+ && ((r_type != R_390_PC16
+ && r_type != R_390_PC12DBL
+ && r_type != R_390_PC16DBL
+ && r_type != R_390_PC24DBL
+ && r_type != R_390_PC32DBL
+ && r_type != R_390_PC32)
+ || !SYMBOL_CALLS_LOCAL (info, h)))
+ || (ELIMINATE_COPY_RELOCS
+ && !info->shared
+ && h != NULL
+ && h->dynindx != -1
+ && !h->non_got_ref
+ && ((h->def_dynamic
+ && !h->def_regular)
+ || h->root.type == bfd_link_hash_undefweak
+ || h->root.type == bfd_link_hash_undefined)))
+ {
+ Elf_Internal_Rela outrel;
+ bfd_boolean skip, relocate;
+ asection *sreloc;
+ bfd_byte *loc;
+
+ /* When generating a shared object, these relocations
+ are copied into the output file to be resolved at run
+ time. */
+
+ skip = FALSE;
+ relocate = FALSE;
+
+ outrel.r_offset =
+ _bfd_elf_section_offset (output_bfd, info, input_section,
+ rel->r_offset);
+ if (outrel.r_offset == (bfd_vma) -1)
+ skip = TRUE;
+ else if (outrel.r_offset == (bfd_vma) -2)
+ skip = TRUE, relocate = TRUE;
+ outrel.r_offset += (input_section->output_section->vma
+ + input_section->output_offset);
+
+ if (skip)
+ memset (&outrel, 0, sizeof outrel);
+ else if (h != NULL
+ && h->dynindx != -1
+ && (r_type == R_390_PC16
+ || r_type == R_390_PC12DBL
+ || r_type == R_390_PC16DBL
+ || r_type == R_390_PC24DBL
+ || r_type == R_390_PC32DBL
+ || r_type == R_390_PC32
+ || !info->shared
+ || !SYMBOLIC_BIND (info, h)
+ || !h->def_regular))
+ {
+ outrel.r_info = ELF32_R_INFO (h->dynindx, r_type);
+ outrel.r_addend = rel->r_addend;
+ }
+ else
+ {
+ /* This symbol is local, or marked to become local. */
+ outrel.r_addend = relocation + rel->r_addend;
+ if (r_type == R_390_32)
+ {
+ relocate = TRUE;
+ outrel.r_info = ELF32_R_INFO (0, R_390_RELATIVE);
+ }
+ else
+ {
+ long sindx;
+
+ if (bfd_is_abs_section (sec))
+ sindx = 0;
+ else if (sec == NULL || sec->owner == NULL)
+ {
+ bfd_set_error(bfd_error_bad_value);
+ return FALSE;
+ }
+ else
+ {
+ asection *osec;
+
+ osec = sec->output_section;
+ sindx = elf_section_data (osec)->dynindx;
+ if (sindx == 0)
+ {
+ osec = htab->elf.text_index_section;
+ sindx = elf_section_data (osec)->dynindx;
+ }
+ BFD_ASSERT (sindx != 0);
+
+ /* We are turning this relocation into one
+ against a section symbol, so subtract out
+ the output section's address but not the
+ offset of the input section in the output
+ section. */
+ outrel.r_addend -= osec->vma;
+ }
+ outrel.r_info = ELF32_R_INFO (sindx, r_type);
+ }
+ }
+
+ sreloc = elf_section_data (input_section)->sreloc;
+ if (sreloc == NULL)
+ abort ();
+
+ loc = sreloc->contents;
+ loc += sreloc->reloc_count++ * sizeof (Elf32_External_Rela);
+ bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
+
+ /* 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;
+
+ /* Relocations for tls literal pool entries. */
+ case R_390_TLS_IE32:
+ if (info->shared)
+ {
+ Elf_Internal_Rela outrel;
+ asection *sreloc;
+ bfd_byte *loc;
+
+ outrel.r_offset = rel->r_offset
+ + input_section->output_section->vma
+ + input_section->output_offset;
+ outrel.r_info = ELF32_R_INFO (0, R_390_RELATIVE);
+ sreloc = elf_section_data (input_section)->sreloc;
+ if (sreloc == NULL)
+ abort ();
+ loc = sreloc->contents;
+ loc += sreloc->reloc_count++ * sizeof (Elf32_External_Rela);
+ bfd_elf32_swap_reloc_out (output_bfd, &outrel, loc);
+ }
+ /* Fall through. */
+
+ case R_390_TLS_GD32:
+ case R_390_TLS_GOTIE32:
+ r_type = elf_s390_tls_transition (info, r_type, h == NULL);
+ tls_type = GOT_UNKNOWN;
+ if (h == NULL && local_got_offsets)
+ tls_type = elf_s390_local_got_tls_type (input_bfd) [r_symndx];
+ else if (h != NULL)
+ {
+ tls_type = elf_s390_hash_entry(h)->tls_type;
+ if (!info->shared && h->dynindx == -1 && tls_type >= GOT_TLS_IE)
+ r_type = R_390_TLS_LE32;
+ }
+ if (r_type == R_390_TLS_GD32 && tls_type >= GOT_TLS_IE)
+ r_type = R_390_TLS_IE32;
+
+ if (r_type == R_390_TLS_LE32)
+ {
+ /* This relocation gets optimized away by the local exec
+ access optimization. */
+ BFD_ASSERT (! unresolved_reloc);
+ bfd_put_32 (output_bfd, -tpoff (info, relocation),
+ contents + rel->r_offset);
+ continue;
+ }
+
+ if (htab->elf.sgot == NULL)
+ abort ();
+
+ if (h != NULL)
+ off = h->got.offset;
+ else
+ {
+ if (local_got_offsets == NULL)
+ abort ();
+
+ off = local_got_offsets[r_symndx];
+ }
+
+ emit_tls_relocs:
+
+ if ((off & 1) != 0)
+ off &= ~1;
+ else
+ {
+ Elf_Internal_Rela outrel;
+ bfd_byte *loc;
+ int dr_type, indx;
+
+ if (htab->elf.srelgot == NULL)
+ abort ();
+
+ outrel.r_offset = (htab->elf.sgot->output_section->vma
+ + htab->elf.sgot->output_offset + off);
+
+ indx = h && h->dynindx != -1 ? h->dynindx : 0;
+ if (r_type == R_390_TLS_GD32)
+ dr_type = R_390_TLS_DTPMOD;
+ else
+ dr_type = R_390_TLS_TPOFF;
+ if (dr_type == R_390_TLS_TPOFF && indx == 0)
+ outrel.r_addend = relocation - dtpoff_base (info);
+ else
+ outrel.r_addend = 0;
+ outrel.r_info = ELF32_R_INFO (indx, dr_type);
+ loc = htab->elf.srelgot->contents;
+ loc += htab->elf.srelgot->reloc_count++
+ * sizeof (Elf32_External_Rela);
+ bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
+
+ if (r_type == R_390_TLS_GD32)
+ {
+ if (indx == 0)
+ {
+ BFD_ASSERT (! unresolved_reloc);
+ bfd_put_32 (output_bfd,
+ relocation - dtpoff_base (info),
+ htab->elf.sgot->contents + off + GOT_ENTRY_SIZE);
+ }
+ else
+ {
+ outrel.r_info = ELF32_R_INFO (indx, R_390_TLS_DTPOFF);
+ outrel.r_offset += GOT_ENTRY_SIZE;
+ outrel.r_addend = 0;
+ htab->elf.srelgot->reloc_count++;
+ loc += sizeof (Elf32_External_Rela);
+ bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
+ }
+ }
+
+ if (h != NULL)
+ h->got.offset |= 1;
+ else
+ local_got_offsets[r_symndx] |= 1;
+ }
+
+ if (off >= (bfd_vma) -2)
+ abort ();
+ if (r_type == ELF32_R_TYPE (rel->r_info))
+ {
+ relocation = htab->elf.sgot->output_offset + off;
+ if (r_type == R_390_TLS_IE32 || r_type == R_390_TLS_IEENT)
+ relocation += htab->elf.sgot->output_section->vma;
+ unresolved_reloc = FALSE;
+ }
+ else
+ {
+ bfd_put_32 (output_bfd, htab->elf.sgot->output_offset + off,
+ contents + rel->r_offset);
+ continue;
+ }
+ break;
+
+ case R_390_TLS_GOTIE12:
+ case R_390_TLS_GOTIE20:
+ case R_390_TLS_IEENT:
+ if (h == NULL)
+ {
+ if (local_got_offsets == NULL)
+ abort();
+ off = local_got_offsets[r_symndx];
+ if (info->shared)
+ goto emit_tls_relocs;
+ }
+ else
+ {
+ off = h->got.offset;
+ tls_type = elf_s390_hash_entry(h)->tls_type;
+ if (info->shared || h->dynindx != -1 || tls_type < GOT_TLS_IE)
+ goto emit_tls_relocs;
+ }
+
+ if (htab->elf.sgot == NULL)
+ abort ();
+
+ BFD_ASSERT (! unresolved_reloc);
+ bfd_put_32 (output_bfd, -tpoff (info, relocation),
+ htab->elf.sgot->contents + off);
+ relocation = htab->elf.sgot->output_offset + off;
+ if (r_type == R_390_TLS_IEENT)
+ relocation += htab->elf.sgot->output_section->vma;
+ unresolved_reloc = FALSE;
+ break;
+
+ case R_390_TLS_LDM32:
+ if (! info->shared)
+ /* The literal pool entry this relocation refers to gets ignored
+ by the optimized code of the local exec model. Do nothing
+ and the value will turn out zero. */
+ continue;
+
+ if (htab->elf.sgot == NULL)
+ abort ();
+
+ off = htab->tls_ldm_got.offset;
+ if (off & 1)
+ off &= ~1;
+ else
+ {
+ Elf_Internal_Rela outrel;
+ bfd_byte *loc;
+
+ if (htab->elf.srelgot == NULL)
+ abort ();
+
+ outrel.r_offset = (htab->elf.sgot->output_section->vma
+ + htab->elf.sgot->output_offset + off);
+
+ bfd_put_32 (output_bfd, 0,
+ htab->elf.sgot->contents + off + GOT_ENTRY_SIZE);
+ outrel.r_info = ELF32_R_INFO (0, R_390_TLS_DTPMOD);
+ outrel.r_addend = 0;
+ loc = htab->elf.srelgot->contents;
+ loc += htab->elf.srelgot->reloc_count++
+ * sizeof (Elf32_External_Rela);
+ bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
+ htab->tls_ldm_got.offset |= 1;
+ }
+ relocation = htab->elf.sgot->output_offset + off;
+ unresolved_reloc = FALSE;
+ break;
+
+ case R_390_TLS_LE32:
+ if (info->shared && !info->pie)
+ {
+ /* Linking a shared library with non-fpic code requires
+ a R_390_TLS_TPOFF relocation. */
+ Elf_Internal_Rela outrel;
+ asection *sreloc;
+ bfd_byte *loc;
+ int indx;
+
+ outrel.r_offset = rel->r_offset
+ + input_section->output_section->vma
+ + input_section->output_offset;
+ if (h != NULL && h->dynindx != -1)
+ indx = h->dynindx;
+ else
+ indx = 0;
+ outrel.r_info = ELF32_R_INFO (indx, R_390_TLS_TPOFF);
+ if (indx == 0)
+ outrel.r_addend = relocation - dtpoff_base (info);
+ else
+ outrel.r_addend = 0;
+ sreloc = elf_section_data (input_section)->sreloc;
+ if (sreloc == NULL)
+ abort ();
+ loc = sreloc->contents;
+ loc += sreloc->reloc_count++ * sizeof (Elf32_External_Rela);
+ bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
+ }
+ else
+ {
+ BFD_ASSERT (! unresolved_reloc);
+ bfd_put_32 (output_bfd, -tpoff (info, relocation),
+ contents + rel->r_offset);
+ }
+ continue;
+
+ case R_390_TLS_LDO32:
+ if (info->shared || (input_section->flags & SEC_DEBUGGING))
+ relocation -= dtpoff_base (info);
+ else
+ /* When converting LDO to LE, we must negate. */
+ relocation = -tpoff (info, relocation);
+ break;
+
+ /* Relocations for tls instructions. */
+ case R_390_TLS_LOAD:
+ case R_390_TLS_GDCALL:
+ case R_390_TLS_LDCALL:
+ tls_type = GOT_UNKNOWN;
+ if (h == NULL && local_got_offsets)
+ tls_type = elf_s390_local_got_tls_type (input_bfd) [r_symndx];
+ else if (h != NULL)
+ tls_type = elf_s390_hash_entry(h)->tls_type;
+
+ if (tls_type == GOT_TLS_GD)
+ continue;
+
+ if (r_type == R_390_TLS_LOAD)
+ {
+ if (!info->shared && (h == NULL || h->dynindx == -1))
+ {
+ /* IE->LE transition. Four valid cases:
+ l %rx,0(0,%ry) -> lr %rx,%ry + bcr 0,0
+ l %rx,0(%ry,0) -> lr %rx,%ry + bcr 0,0
+ l %rx,0(%ry,%r12) -> lr %rx,%ry + bcr 0,0
+ l %rx,0(%r12,%ry) -> lr %rx,%ry + bcr 0,0 */
+ unsigned int insn, ry;
+
+ insn = bfd_get_32 (input_bfd, contents + rel->r_offset);
+ ry = 0;
+ if ((insn & 0xff00f000) == 0x58000000)
+ /* l %rx,0(%ry,0) -> lr %rx,%ry + bcr 0,0 */
+ ry = (insn & 0x000f0000);
+ else if ((insn & 0xff0f0000) == 0x58000000)
+ /* l %rx,0(0,%ry) -> lr %rx,%ry + bcr 0,0 */
+ ry = (insn & 0x0000f000) << 4;
+ else if ((insn & 0xff00f000) == 0x5800c000)
+ /* l %rx,0(%ry,%r12) -> lr %rx,%ry + bcr 0,0 */
+ ry = (insn & 0x000f0000);
+ else if ((insn & 0xff0f0000) == 0x580c0000)
+ /* l %rx,0(%r12,%ry) -> lr %rx,%ry + bcr 0,0 */
+ ry = (insn & 0x0000f000) << 4;
+ else
+ invalid_tls_insn (input_bfd, input_section, rel);
+ insn = 0x18000700 | (insn & 0x00f00000) | ry;
+ bfd_put_32 (output_bfd, insn, contents + rel->r_offset);
+ }
+ }
+ else if (r_type == R_390_TLS_GDCALL)
+ {
+ unsigned int insn;
+
+ insn = bfd_get_32 (input_bfd, contents + rel->r_offset);
+ if ((insn & 0xff000fff) != 0x4d000000 &&
+ (insn & 0xffff0000) != 0xc0e50000 &&
+ (insn & 0xff000000) != 0x0d000000)
+ invalid_tls_insn (input_bfd, input_section, rel);
+ if (!info->shared && (h == NULL || h->dynindx == -1))
+ {
+ if ((insn & 0xff000000) == 0x0d000000)
+ {
+ /* GD->LE transition.
+ basr rx, ry -> nopr r7 */
+ insn = 0x07070000 | (insn & 0xffff);
+ }
+ else if ((insn & 0xff000000) == 0x4d000000)
+ {
+ /* GD->LE transition.
+ bas %r14,0(%rx,%r13) -> bc 0,0 */
+ insn = 0x47000000;
+ }
+ else
+ {
+ /* GD->LE transition.
+ brasl %r14,_tls_get_offset@plt -> brcl 0,. */
+ insn = 0xc0040000;
+ bfd_put_16 (output_bfd, 0x0000,
+ contents + rel->r_offset + 4);
+ }
+ }
+ else
+ {
+ /* If basr is used in the pic case to invoke
+ _tls_get_offset, something went wrong before. */
+ if ((insn & 0xff000000) == 0x0d000000)
+ invalid_tls_insn (input_bfd, input_section, rel);
+
+ if ((insn & 0xff000000) == 0x4d000000)
+ {
+ /* GD->IE transition.
+ bas %r14,0(%rx,%r13) -> l %r2,0(%r2,%r12) */
+ insn = 0x5822c000;
+ }
+ else
+ {
+ /* GD->IE transition.
+ brasl %r14,__tls_get_addr@plt ->
+ l %r2,0(%r2,%r12) ; bcr 0,0 */
+ insn = 0x5822c000;
+ bfd_put_16 (output_bfd, 0x0700,
+ contents + rel->r_offset + 4);
+ }
+ }
+ bfd_put_32 (output_bfd, insn, contents + rel->r_offset);
+ }
+ else if (r_type == R_390_TLS_LDCALL)
+ {
+ if (!info->shared)
+ {
+ unsigned int insn;
+
+ insn = bfd_get_32 (input_bfd, contents + rel->r_offset);
+ if ((insn & 0xff000fff) != 0x4d000000 &&
+ (insn & 0xffff0000) != 0xc0e50000 &&
+ (insn & 0xff000000) != 0x0d000000)
+ invalid_tls_insn (input_bfd, input_section, rel);
+
+ if ((insn & 0xff000000) == 0x0d000000)
+ {
+ /* LD->LE transition.
+ basr rx, ry -> nopr r7 */
+ insn = 0x07070000 | (insn & 0xffff);
+ }
+ else if ((insn & 0xff000000) == 0x4d000000)
+ {
+ /* LD->LE transition.
+ bas %r14,0(%rx,%r13) -> bc 0,0 */
+ insn = 0x47000000;
+ }
+ else
+ {
+ /* LD->LE transition.
+ brasl %r14,__tls_get_offset@plt -> brcl 0,. */
+ insn = 0xc0040000;
+ bfd_put_16 (output_bfd, 0x0000,
+ contents + rel->r_offset + 4);
+ }
+ bfd_put_32 (output_bfd, insn, contents + rel->r_offset);
+ }
+ }
+ continue;
+
+ default:
+ break;
+ }
+
+ /* Dynamic relocs are not propagated for SEC_DEBUGGING sections
+ because such sections are not SEC_ALLOC and thus ld.so will
+ not process them. */
+ if (unresolved_reloc
+ && !((input_section->flags & SEC_DEBUGGING) != 0
+ && h->def_dynamic)
+ && _bfd_elf_section_offset (output_bfd, info, input_section,
+ rel->r_offset) != (bfd_vma) -1)
+ (*_bfd_error_handler)
+ (_("%B(%A+0x%lx): unresolvable %s relocation against symbol `%s'"),
+ input_bfd,
+ input_section,
+ (long) rel->r_offset,
+ howto->name,
+ h->root.root.string);
+
+ do_relocation:
+
+ /* When applying a 24 bit reloc we need to start one byte
+ earlier. Otherwise the 32 bit get/put bfd operations might
+ access a byte after the actual section. */
+ if (r_type == R_390_PC24DBL
+ || r_type == R_390_PLT24DBL)
+ rel->r_offset--;
+
+ if (r_type == R_390_20
+ || r_type == R_390_GOT20
+ || r_type == R_390_GOTPLT20
+ || r_type == R_390_TLS_GOTIE20)
+ {
+ relocation += rel->r_addend;
+ relocation = (relocation&0xfff) << 8 | (relocation&0xff000) >> 12;
+ r = _bfd_final_link_relocate (howto, input_bfd, input_section,
+ contents, rel->r_offset,
+ relocation, 0);
+ }
+ else
+ 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 *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 (r == bfd_reloc_overflow)
+ {
+
+ if (! ((*info->callbacks->reloc_overflow)
+ (info, (h ? &h->root : NULL), name, howto->name,
+ (bfd_vma) 0, input_bfd, input_section,
+ rel->r_offset)))
+ return FALSE;
+ }
+ else
+ {
+ (*_bfd_error_handler)
+ (_("%B(%A+0x%lx): reloc against `%s': error %d"),
+ input_bfd, input_section,
+ (long) rel->r_offset, name, (int) r);
+ return FALSE;
+ }
+ }
+ }
+
+ return TRUE;
+}
+
+/* Generate the PLT slots together with the dynamic relocations needed
+ for IFUNC symbols. */
+
+static void
+elf_s390_finish_ifunc_symbol (bfd *output_bfd,
+ struct bfd_link_info *info,
+ struct elf_link_hash_entry *h,
+ struct elf_s390_link_hash_table *htab,
+ bfd_vma iplt_offset,
+ bfd_vma resolver_address)
+{
+ bfd_vma iplt_index;
+ bfd_vma got_offset;
+ bfd_vma igotiplt_offset;
+ Elf_Internal_Rela rela;
+ bfd_byte *loc;
+ asection *plt, *gotplt, *relplt;
+ bfd_vma relative_offset;
+
+ if (htab->elf.iplt == NULL
+ || htab->elf.igotplt == NULL
+ || htab->elf.irelplt == NULL)
+ abort ();
+
+ gotplt = htab->elf.igotplt;
+ relplt = htab->elf.irelplt;
+
+ /* Index of the PLT slot within iplt section. */
+ iplt_index = iplt_offset / PLT_ENTRY_SIZE;
+ plt = htab->elf.iplt;
+ /* Offset into the igot.plt section. */
+ igotiplt_offset = iplt_index * GOT_ENTRY_SIZE;
+ /* Offset into the got section. */
+ got_offset = igotiplt_offset + gotplt->output_offset;
+
+ /* S390 uses halfwords for relative branch calc! */
+ relative_offset = - (plt->output_offset +
+ (PLT_ENTRY_SIZE * iplt_index) + 18) / 2;
+/* If offset is > 32768, branch to a previous branch
+ 390 can only handle +-64 K jumps. */
+ if ( -32768 > (int) relative_offset )
+ relative_offset
+ = -(unsigned) (((65536 / PLT_ENTRY_SIZE - 1) * PLT_ENTRY_SIZE) / 2);
+
+ /* Fill in the entry in the procedure linkage table. */
+ if (!info->shared)
+ {
+ memcpy (plt->contents + iplt_offset, elf_s390_plt_entry,
+ PLT_ENTRY_SIZE);
+
+ /* Adjust jump to the first plt entry. */
+ bfd_put_32 (output_bfd, (bfd_vma) 0+(relative_offset << 16),
+ plt->contents + iplt_offset + 20);
+
+ /* Push the GOT offset field. */
+ bfd_put_32 (output_bfd,
+ (gotplt->output_section->vma
+ + got_offset),
+ plt->contents + iplt_offset + 24);
+ }
+ else if (got_offset < 4096)
+ {
+ /* The GOT offset is small enough to be used directly as
+ displacement. */
+ memcpy (plt->contents + iplt_offset,
+ elf_s390_plt_pic12_entry,
+ PLT_ENTRY_SIZE);
+
+ /* Put in the GOT offset as displacement value. The 0xc000
+ value comes from the first word of the plt entry. Look
+ at the elf_s390_plt_pic16_entry content. */
+ bfd_put_16 (output_bfd, (bfd_vma)0xc000 | got_offset,
+ plt->contents + iplt_offset + 2);
+
+ /* Adjust the jump to the first plt entry. */
+ bfd_put_32 (output_bfd, (bfd_vma) 0+(relative_offset << 16),
+ plt->contents + iplt_offset + 20);
+ }
+ else if (got_offset < 32768)
+ {
+ /* The GOT offset is too big for a displacement but small
+ enough to be a signed 16 bit immediate value as it can be
+ used in an lhi instruction. */
+ memcpy (plt->contents + iplt_offset,
+ elf_s390_plt_pic16_entry,
+ PLT_ENTRY_SIZE);
+
+ /* Put in the GOT offset for the lhi instruction. */
+ bfd_put_16 (output_bfd, (bfd_vma)got_offset,
+ plt->contents + iplt_offset + 2);
+
+ /* Adjust the jump to the first plt entry. */
+ bfd_put_32 (output_bfd, (bfd_vma) 0+(relative_offset << 16),
+ plt->contents + iplt_offset + 20);
+ }
+ else
+ {
+ memcpy (plt->contents + iplt_offset,
+ elf_s390_plt_pic_entry,
+ PLT_ENTRY_SIZE);
+
+ /* Adjust the jump to the first plt entry. */
+ bfd_put_32 (output_bfd, (bfd_vma) 0+(relative_offset << 16),
+ plt->contents + iplt_offset + 20);
+
+ /* Push the GOT offset field. */
+ bfd_put_32 (output_bfd, got_offset,
+ plt->contents + iplt_offset + 24);
+ }
+ /* Insert offset into reloc. table here. */
+ bfd_put_32 (output_bfd, relplt->output_offset +
+ iplt_index * RELA_ENTRY_SIZE,
+ plt->contents + iplt_offset + 28);
+
+ /* Fill in the entry in the global offset table.
+ Points to instruction after GOT offset. */
+ bfd_put_32 (output_bfd,
+ (plt->output_section->vma
+ + plt->output_offset
+ + iplt_offset
+ + 12),
+ gotplt->contents + igotiplt_offset);
+
+ /* Fill in the entry in the .rela.plt section. */
+ rela.r_offset = gotplt->output_section->vma + got_offset;
+
+ if (!h
+ || h->dynindx == -1
+ || ((info->executable
+ || ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
+ && h->def_regular))
+ {
+ /* The symbol can be locally resolved. */
+ rela.r_info = ELF32_R_INFO (0, R_390_IRELATIVE);
+ rela.r_addend = resolver_address;
+ }
+ else
+ {
+ rela.r_info = ELF32_R_INFO (h->dynindx, R_390_JMP_SLOT);
+ rela.r_addend = 0;
+ }
+
+ loc = relplt->contents + iplt_index * RELA_ENTRY_SIZE;
+ bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
+}
+
+/* Finish up dynamic symbol handling. We set the contents of various
+ dynamic sections here. */
+
+static bfd_boolean
+elf_s390_finish_dynamic_symbol (bfd *output_bfd,
+ struct bfd_link_info *info,
+ struct elf_link_hash_entry *h,
+ Elf_Internal_Sym *sym)
+{
+ struct elf_s390_link_hash_table *htab;
+ struct elf_s390_link_hash_entry *eh = (struct elf_s390_link_hash_entry*)h;
+
+ htab = elf_s390_hash_table (info);
+
+ if (h->plt.offset != (bfd_vma) -1)
+ {
+ bfd_vma plt_index;
+ bfd_vma got_offset;
+ Elf_Internal_Rela rela;
+ bfd_byte *loc;
+ bfd_vma relative_offset;
+
+ /* This symbol has an entry in the procedure linkage table. Set
+ it up. */
+ if (s390_is_ifunc_symbol_p (h))
+ {
+ /* If we can resolve the IFUNC symbol locally we generate an
+ IRELATIVE reloc. */
+ elf_s390_finish_ifunc_symbol (output_bfd, info, h, htab, h->plt.offset,
+ eh->ifunc_resolver_address +
+ eh->ifunc_resolver_section->output_offset +
+ eh->ifunc_resolver_section->output_section->vma);
+ /* Fallthrough. Handling of explicit GOT slots of IFUNC
+ symbols is below. */
+ }
+ else
+ {
+ if (h->dynindx == -1
+ || htab->elf.splt == NULL
+ || htab->elf.sgotplt == NULL
+ || htab->elf.srelplt == NULL)
+ abort ();
+
+ /* Calc. index no.
+ Current offset - size first entry / entry size. */
+ plt_index = (h->plt.offset - PLT_FIRST_ENTRY_SIZE) / PLT_ENTRY_SIZE;
+
+ /* Offset in GOT is PLT index plus GOT headers(3) times 4,
+ addr & GOT addr. */
+ got_offset = (plt_index + 3) * GOT_ENTRY_SIZE;
+
+ /* S390 uses halfwords for relative branch calc! */
+ relative_offset = - ((PLT_FIRST_ENTRY_SIZE +
+ (PLT_ENTRY_SIZE * plt_index) + 18) / 2);
+ /* If offset is > 32768, branch to a previous branch
+ 390 can only handle +-64 K jumps. */
+ if ( -32768 > (int) relative_offset )
+ relative_offset
+ = -(unsigned) (((65536 / PLT_ENTRY_SIZE - 1) * PLT_ENTRY_SIZE) / 2);
+
+ /* Fill in the entry in the procedure linkage table. */
+ if (!info->shared)
+ {
+ memcpy (htab->elf.splt->contents + h->plt.offset, elf_s390_plt_entry,
+ PLT_ENTRY_SIZE);
+
+ /* Adjust jump to the first plt entry. */
+ bfd_put_32 (output_bfd, (bfd_vma) 0+(relative_offset << 16),
+ htab->elf.splt->contents + h->plt.offset + 20);
+
+ /* Push the GOT offset field. */
+ bfd_put_32 (output_bfd,
+ (htab->elf.sgotplt->output_section->vma
+ + htab->elf.sgotplt->output_offset
+ + got_offset),
+ htab->elf.splt->contents + h->plt.offset + 24);
+ }
+ else if (got_offset < 4096)
+ {
+ /* The GOT offset is small enough to be used directly as
+ displacement. */
+ memcpy (htab->elf.splt->contents + h->plt.offset,
+ elf_s390_plt_pic12_entry,
+ PLT_ENTRY_SIZE);
+
+ /* Put in the GOT offset as displacement value. The 0xc000
+ value comes from the first word of the plt entry. Look
+ at the elf_s390_plt_pic16_entry content. */
+ bfd_put_16 (output_bfd, (bfd_vma)0xc000 | got_offset,
+ htab->elf.splt->contents + h->plt.offset + 2);
+
+ /* Adjust the jump to the first plt entry. */
+ bfd_put_32 (output_bfd, (bfd_vma) 0+(relative_offset << 16),
+ htab->elf.splt->contents + h->plt.offset + 20);
+ }
+ else if (got_offset < 32768)
+ {
+ /* The GOT offset is too big for a displacement but small
+ enough to be a signed 16 bit immediate value as it can be
+ used in an lhi instruction. */
+ memcpy (htab->elf.splt->contents + h->plt.offset,
+ elf_s390_plt_pic16_entry,
+ PLT_ENTRY_SIZE);
+
+ /* Put in the GOT offset for the lhi instruction. */
+ bfd_put_16 (output_bfd, (bfd_vma)got_offset,
+ htab->elf.splt->contents + h->plt.offset + 2);
+
+ /* Adjust the jump to the first plt entry. */
+ bfd_put_32 (output_bfd, (bfd_vma) 0+(relative_offset << 16),
+ htab->elf.splt->contents + h->plt.offset + 20);
+ }
+ else
+ {
+ memcpy (htab->elf.splt->contents + h->plt.offset,
+ elf_s390_plt_pic_entry,
+ PLT_ENTRY_SIZE);
+
+ /* Adjust the jump to the first plt entry. */
+ bfd_put_32 (output_bfd, (bfd_vma) 0+(relative_offset << 16),
+ htab->elf.splt->contents + h->plt.offset + 20);
+
+ /* Push the GOT offset field. */
+ bfd_put_32 (output_bfd, got_offset,
+ htab->elf.splt->contents + h->plt.offset + 24);
+ }
+ /* Insert offset into reloc. table here. */
+ bfd_put_32 (output_bfd, plt_index * sizeof (Elf32_External_Rela),
+ htab->elf.splt->contents + h->plt.offset + 28);
+
+ /* Fill in the entry in the global offset table.
+ Points to instruction after GOT offset. */
+ bfd_put_32 (output_bfd,
+ (htab->elf.splt->output_section->vma
+ + htab->elf.splt->output_offset
+ + h->plt.offset
+ + 12),
+ htab->elf.sgotplt->contents + got_offset);
+
+ /* Fill in the entry in the .rela.plt section. */
+ rela.r_offset = (htab->elf.sgotplt->output_section->vma
+ + htab->elf.sgotplt->output_offset
+ + got_offset);
+ rela.r_info = ELF32_R_INFO (h->dynindx, R_390_JMP_SLOT);
+ rela.r_addend = 0;
+ loc = htab->elf.srelplt->contents + plt_index * sizeof (Elf32_External_Rela);
+ bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
+
+ if (!h->def_regular)
+ {
+ /* Mark the symbol as undefined, rather than as defined in
+ the .plt section. Leave the value alone. This is a clue
+ for the dynamic linker, to make function pointer
+ comparisons work between an application and shared
+ library. */
+ sym->st_shndx = SHN_UNDEF;
+ }
+ }
+ }
+
+ if (h->got.offset != (bfd_vma) -1
+ && elf_s390_hash_entry(h)->tls_type != GOT_TLS_GD
+ && elf_s390_hash_entry(h)->tls_type != GOT_TLS_IE
+ && elf_s390_hash_entry(h)->tls_type != GOT_TLS_IE_NLT)
+ {
+ Elf_Internal_Rela rela;
+ bfd_byte *loc;
+
+ /* This symbol has an entry in the global offset table. Set it
+ up. */
+
+ if (htab->elf.sgot == NULL || htab->elf.srelgot == NULL)
+ abort ();
+
+ rela.r_offset = (htab->elf.sgot->output_section->vma
+ + htab->elf.sgot->output_offset
+ + (h->got.offset &~ (bfd_vma) 1));
+
+ /* If this is a static link, or it is a -Bsymbolic link and the
+ symbol is defined locally or was forced to be local because
+ of a version file, 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 (h->def_regular && s390_is_ifunc_symbol_p (h))
+ {
+ if (info->shared)
+ {
+ /* An explicit GOT slot usage needs GLOB_DAT. If the
+ symbol references local the implicit got.iplt slot
+ will be used and the IRELATIVE reloc has been created
+ above. */
+ goto do_glob_dat;
+ }
+ else
+ {
+ /* For non-shared objects explicit GOT slots must be
+ filled with the PLT slot address for pointer
+ equality reasons. */
+ bfd_put_32 (output_bfd, (htab->elf.iplt->output_section->vma
+ + htab->elf.iplt->output_offset
+ + h->plt.offset),
+ htab->elf.sgot->contents + h->got.offset);
+ return TRUE;
+ }
+ }
+ else if (info->shared
+ && SYMBOL_REFERENCES_LOCAL (info, h))
+ {
+ /* If this is a static link, or it is a -Bsymbolic link and
+ the symbol is defined locally or was forced to be local
+ because of a version file, 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 (!h->def_regular)
+ return FALSE;
+ BFD_ASSERT((h->got.offset & 1) != 0);
+ rela.r_info = ELF32_R_INFO (0, R_390_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);
+ do_glob_dat:
+ bfd_put_32 (output_bfd, (bfd_vma) 0, htab->elf.sgot->contents + h->got.offset);
+ rela.r_info = ELF32_R_INFO (h->dynindx, R_390_GLOB_DAT);
+ rela.r_addend = 0;
+ }
+
+ loc = htab->elf.srelgot->contents;
+ loc += htab->elf.srelgot->reloc_count++ * sizeof (Elf32_External_Rela);
+ bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
+ }
+
+ if (h->needs_copy)
+ {
+ Elf_Internal_Rela rela;
+ bfd_byte *loc;
+
+ /* This symbols needs a copy reloc. Set it up. */
+
+ if (h->dynindx == -1
+ || (h->root.type != bfd_link_hash_defined
+ && h->root.type != bfd_link_hash_defweak)
+ || htab->srelbss == NULL)
+ abort ();
+
+ 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_390_COPY);
+ rela.r_addend = 0;
+ loc = htab->srelbss->contents;
+ loc += htab->srelbss->reloc_count++ * sizeof (Elf32_External_Rela);
+ bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
+ }
+
+ /* Mark some specially defined symbols as absolute. */
+ if (h == htab->elf.hdynamic
+ || h == htab->elf.hgot
+ || h == htab->elf.hplt)
+ sym->st_shndx = SHN_ABS;
+
+ return TRUE;
+}
+
+/* Used to decide how to sort relocs in an optimal manner for the
+ dynamic linker, before writing them out. */
+
+static enum elf_reloc_type_class
+elf_s390_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ const asection *rel_sec ATTRIBUTE_UNUSED,
+ const Elf_Internal_Rela *rela)
+{
+ switch ((int) ELF32_R_TYPE (rela->r_info))
+ {
+ case R_390_RELATIVE:
+ return reloc_class_relative;
+ case R_390_JMP_SLOT:
+ return reloc_class_plt;
+ case R_390_COPY:
+ return reloc_class_copy;
+ default:
+ return reloc_class_normal;
+ }
+}
+
+/* Finish up the dynamic sections. */
+
+static bfd_boolean
+elf_s390_finish_dynamic_sections (bfd *output_bfd,
+ struct bfd_link_info *info)
+{
+ struct elf_s390_link_hash_table *htab;
+ bfd *dynobj;
+ asection *sdyn;
+ bfd *ibfd;
+ unsigned int i;
+
+ htab = elf_s390_hash_table (info);
+ dynobj = htab->elf.dynobj;
+ sdyn = bfd_get_linker_section (dynobj, ".dynamic");
+
+ if (htab->elf.dynamic_sections_created)
+ {
+ Elf32_External_Dyn *dyncon, *dynconend;
+
+ if (sdyn == NULL || htab->elf.sgot == NULL)
+ abort ();
+
+ dyncon = (Elf32_External_Dyn *) sdyn->contents;
+ dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->size);
+ for (; dyncon < dynconend; dyncon++)
+ {
+ Elf_Internal_Dyn dyn;
+ asection *s;
+
+ bfd_elf32_swap_dyn_in (dynobj, dyncon, &dyn);
+
+ switch (dyn.d_tag)
+ {
+ default:
+ continue;
+
+ case DT_PLTGOT:
+ dyn.d_un.d_ptr = htab->elf.sgot->output_section->vma;
+ break;
+
+ case DT_JMPREL:
+ dyn.d_un.d_ptr = htab->elf.srelplt->output_section->vma;
+ break;
+
+ case DT_PLTRELSZ:
+ s = htab->elf.srelplt->output_section;
+ dyn.d_un.d_val = s->size;
+ break;
+ }
+
+ bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
+ }
+
+ /* Fill in the special first entry in the procedure linkage table. */
+ if (htab->elf.splt && htab->elf.splt->size > 0)
+ {
+ memset (htab->elf.splt->contents, 0, PLT_FIRST_ENTRY_SIZE);
+ if (info->shared)
+ {
+ memcpy (htab->elf.splt->contents, elf_s390_plt_pic_first_entry,
+ PLT_FIRST_ENTRY_SIZE);
+ }
+ else
+ {
+ memcpy (htab->elf.splt->contents, elf_s390_plt_first_entry,
+ PLT_FIRST_ENTRY_SIZE);
+ bfd_put_32 (output_bfd,
+ htab->elf.sgotplt->output_section->vma
+ + htab->elf.sgotplt->output_offset,
+ htab->elf.splt->contents + 24);
+ }
+ elf_section_data (htab->elf.splt->output_section)
+ ->this_hdr.sh_entsize = 4;
+ }
+
+ }
+
+ if (htab->elf.sgotplt)
+ {
+ /* Fill in the first three entries in the global offset table. */
+ if (htab->elf.sgotplt->size > 0)
+ {
+ bfd_put_32 (output_bfd,
+ (sdyn == NULL ? (bfd_vma) 0
+ : sdyn->output_section->vma + sdyn->output_offset),
+ htab->elf.sgotplt->contents);
+ /* One entry for shared object struct ptr. */
+ bfd_put_32 (output_bfd, (bfd_vma) 0, htab->elf.sgotplt->contents + 4);
+ /* One entry for _dl_runtime_resolve. */
+ bfd_put_32 (output_bfd, (bfd_vma) 0, htab->elf.sgotplt->contents + 8);
+ }
+
+ elf_section_data (htab->elf.sgotplt->output_section)
+ ->this_hdr.sh_entsize = 4;
+ }
+ /* Finish dynamic symbol for local IFUNC symbols. */
+ for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next)
+ {
+ struct plt_entry *local_plt;
+ Elf_Internal_Sym *isym;
+ Elf_Internal_Shdr *symtab_hdr;
+
+ symtab_hdr = &elf_symtab_hdr (ibfd);
+
+ local_plt = elf_s390_local_plt (ibfd);
+ if (local_plt != NULL)
+ for (i = 0; i < symtab_hdr->sh_info; i++)
+ {
+ if (local_plt[i].plt.offset != (bfd_vma) -1)
+ {
+ asection *sec = local_plt[i].sec;
+ isym = bfd_sym_from_r_symndx (&htab->sym_cache, ibfd, i);
+ if (isym == NULL)
+ return FALSE;
+
+ if (ELF_ST_TYPE (isym->st_info) == STT_GNU_IFUNC)
+ elf_s390_finish_ifunc_symbol (output_bfd, info, NULL, htab,
+ local_plt[i].plt.offset,
+ isym->st_value
+ + sec->output_section->vma
+ + sec->output_offset);
+
+ }
+ }
+ }
+ return TRUE;
+}
+
+static bfd_boolean
+elf_s390_grok_prstatus (bfd * abfd, Elf_Internal_Note * note)
+{
+ int offset;
+ unsigned int size;
+
+ switch (note->descsz)
+ {
+ default:
+ return FALSE;
+
+ case 224: /* S/390 Linux. */
+ /* pr_cursig */
+ elf_tdata (abfd)->core->signal = bfd_get_16 (abfd, note->descdata + 12);
+
+ /* pr_pid */
+ elf_tdata (abfd)->core->lwpid = bfd_get_32 (abfd, note->descdata + 24);
+
+ /* pr_reg */
+ offset = 72;
+ size = 144;
+ break;
+ }
+
+ /* Make a ".reg/999" section. */
+ return _bfd_elfcore_make_pseudosection (abfd, ".reg",
+ size, note->descpos + offset);
+}
+
+/* Return address for Ith PLT stub in section PLT, for relocation REL
+ or (bfd_vma) -1 if it should not be included. */
+
+static bfd_vma
+elf_s390_plt_sym_val (bfd_vma i, const asection *plt,
+ const arelent *rel ATTRIBUTE_UNUSED)
+{
+ return plt->vma + PLT_FIRST_ENTRY_SIZE + i * PLT_ENTRY_SIZE;
+}
+
+static bfd_boolean
+elf32_s390_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
+{
+ elf_elfheader (obfd)->e_flags |= elf_elfheader (ibfd)->e_flags;
+ return TRUE;
+}
+
+
+#define TARGET_BIG_SYM s390_elf32_vec
+#define TARGET_BIG_NAME "elf32-s390"
+#define ELF_ARCH bfd_arch_s390
+#define ELF_TARGET_ID S390_ELF_DATA
+#define ELF_MACHINE_CODE EM_S390
+#define ELF_MACHINE_ALT1 EM_S390_OLD
+#define ELF_MAXPAGESIZE 0x1000
+
+#define elf_backend_can_gc_sections 1
+#define elf_backend_can_refcount 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_rela_normal 1
+
+#define elf_info_to_howto elf_s390_info_to_howto
+
+#define bfd_elf32_bfd_is_local_label_name elf_s390_is_local_label_name
+#define bfd_elf32_bfd_link_hash_table_create elf_s390_link_hash_table_create
+#define bfd_elf32_bfd_reloc_type_lookup elf_s390_reloc_type_lookup
+#define bfd_elf32_bfd_reloc_name_lookup elf_s390_reloc_name_lookup
+
+#define bfd_elf32_bfd_merge_private_bfd_data elf32_s390_merge_private_bfd_data
+
+#define elf_backend_adjust_dynamic_symbol elf_s390_adjust_dynamic_symbol
+#define elf_backend_check_relocs elf_s390_check_relocs
+#define elf_backend_copy_indirect_symbol elf_s390_copy_indirect_symbol
+#define elf_backend_create_dynamic_sections elf_s390_create_dynamic_sections
+#define elf_backend_finish_dynamic_sections elf_s390_finish_dynamic_sections
+#define elf_backend_finish_dynamic_symbol elf_s390_finish_dynamic_symbol
+#define elf_backend_gc_mark_hook elf_s390_gc_mark_hook
+#define elf_backend_gc_sweep_hook elf_s390_gc_sweep_hook
+#define elf_backend_reloc_type_class elf_s390_reloc_type_class
+#define elf_backend_relocate_section elf_s390_relocate_section
+#define elf_backend_size_dynamic_sections elf_s390_size_dynamic_sections
+#define elf_backend_init_index_section _bfd_elf_init_1_index_section
+#define elf_backend_grok_prstatus elf_s390_grok_prstatus
+#define elf_backend_plt_sym_val elf_s390_plt_sym_val
+#define elf_backend_add_symbol_hook elf_s390_add_symbol_hook
+
+#define bfd_elf32_mkobject elf_s390_mkobject
+#define elf_backend_object_p elf_s390_object_p
+
+#include "elf32-target.h"
diff --git a/bfd/elf32-score.c b/bfd/elf32-score.c
new file mode 100644
index 0000000..1ab54cd
--- /dev/null
+++ b/bfd/elf32-score.c
@@ -0,0 +1,4515 @@
+/* 32-bit ELF support for S+core.
+ Copyright (C) 2006-2014 Free Software Foundation, Inc.
+ Contributed by
+ Brain.lin (brain.lin@sunplusct.com)
+ Mei Ligang (ligang@sunnorth.com.cn)
+ Pei-Lin Tsai (pltsai@sunplus.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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+#include "libiberty.h"
+#include "elf-bfd.h"
+#include "elf/score.h"
+#include "elf/common.h"
+#include "elf/internal.h"
+#include "hashtab.h"
+#include "elf32-score.h"
+
+
+int score3 = 0;
+int score7 = 1;
+
+/* The SCORE ELF linker needs additional information for each symbol in
+ the global hash table. */
+struct score_elf_link_hash_entry
+{
+ struct elf_link_hash_entry root;
+
+ /* Number of R_SCORE_ABS32, R_SCORE_REL32 relocs against this symbol. */
+ unsigned int possibly_dynamic_relocs;
+
+ /* If the R_SCORE_ABS32, R_SCORE_REL32 reloc is against a readonly section. */
+ bfd_boolean readonly_reloc;
+
+ /* We must not create a stub for a symbol that has relocations related to
+ taking the function's address, i.e. any but R_SCORE_CALL15 ones. */
+ bfd_boolean no_fn_stub;
+
+ /* Are we forced local? This will only be set if we have converted
+ the initial global GOT entry to a local GOT entry. */
+ bfd_boolean forced_local;
+};
+
+/* Traverse a score ELF linker hash table. */
+#define score_elf_link_hash_traverse(table, func, info) \
+ (elf_link_hash_traverse \
+ ((table), \
+ (bfd_boolean (*) (struct elf_link_hash_entry *, void *)) (func), \
+ (info)))
+
+/* This structure is used to hold .got entries while estimating got sizes. */
+struct score_got_entry
+{
+ /* The input bfd in which the symbol is defined. */
+ bfd *abfd;
+ /* The index of the symbol, as stored in the relocation r_info, if
+ we have a local symbol; -1 otherwise. */
+ long symndx;
+ union
+ {
+ /* If abfd == NULL, an address that must be stored in the got. */
+ bfd_vma address;
+ /* If abfd != NULL && symndx != -1, the addend of the relocation
+ that should be added to the symbol value. */
+ bfd_vma addend;
+ /* If abfd != NULL && symndx == -1, the hash table entry
+ corresponding to a global symbol in the got (or, local, if
+ h->forced_local). */
+ struct score_elf_link_hash_entry *h;
+ } d;
+
+ /* The offset from the beginning of the .got section to the entry
+ corresponding to this symbol+addend. If it's a global symbol
+ whose offset is yet to be decided, it's going to be -1. */
+ long gotidx;
+};
+
+/* This structure is passed to score_elf_sort_hash_table_f when sorting
+ the dynamic symbols. */
+
+struct score_elf_hash_sort_data
+{
+ /* The symbol in the global GOT with the lowest dynamic symbol table index. */
+ struct elf_link_hash_entry *low;
+ /* The least dynamic symbol table index corresponding to a symbol with a GOT entry. */
+ long min_got_dynindx;
+ /* The greatest dynamic symbol table index corresponding to a symbol
+ with a GOT entry that is not referenced (e.g., a dynamic symbol
+ with dynamic relocations pointing to it from non-primary GOTs). */
+ long max_unref_got_dynindx;
+ /* The greatest dynamic symbol table index not corresponding to a
+ symbol without a GOT entry. */
+ long max_non_got_dynindx;
+};
+
+struct score_got_info
+{
+ /* The global symbol in the GOT with the lowest index in the dynamic
+ symbol table. */
+ struct elf_link_hash_entry *global_gotsym;
+ /* The number of global .got entries. */
+ unsigned int global_gotno;
+ /* The number of local .got entries. */
+ unsigned int local_gotno;
+ /* The number of local .got entries we have used. */
+ unsigned int assigned_gotno;
+ /* A hash table holding members of the got. */
+ struct htab *got_entries;
+ /* In multi-got links, a pointer to the next got (err, rather, most
+ of the time, it points to the previous got). */
+ struct score_got_info *next;
+};
+
+/* A structure used to count GOT entries, for GOT entry or ELF symbol table traversal. */
+struct _score_elf_section_data
+{
+ struct bfd_elf_section_data elf;
+ union
+ {
+ struct score_got_info *got_info;
+ bfd_byte *tdata;
+ }
+ u;
+};
+
+#define score_elf_section_data(sec) \
+ ((struct _score_elf_section_data *) elf_section_data (sec))
+
+/* The size of a symbol-table entry. */
+#define SCORE_ELF_SYM_SIZE(abfd) \
+ (get_elf_backend_data (abfd)->s->sizeof_sym)
+
+/* 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)
+#define MINUS_TWO (((bfd_vma)0) - 2)
+
+#define PDR_SIZE 32
+
+
+/* The number of local .got entries we reserve. */
+#define SCORE_RESERVED_GOTNO (2)
+#define ELF_DYNAMIC_INTERPRETER "/usr/lib/ld.so.1"
+
+/* The offset of $gp from the beginning of the .got section. */
+#define ELF_SCORE_GP_OFFSET(abfd) (0x3ff0)
+/* The maximum size of the GOT for it to be addressable using 15-bit offsets from $gp. */
+#define SCORE_ELF_GOT_MAX_SIZE(abfd) (ELF_SCORE_GP_OFFSET(abfd) + 0x3fff)
+
+#define SCORE_ELF_STUB_SECTION_NAME (".SCORE.stub")
+#define SCORE_FUNCTION_STUB_SIZE (16)
+
+#define STUB_LW 0xc3bcc010 /* lw r29, [r28, -0x3ff0] */
+#define STUB_MOVE 0x8363bc56 /* mv r27, r3 */
+#define STUB_LI16 0x87548000 /* ori r26, .dynsym_index */
+#define STUB_BRL 0x801dbc09 /* brl r29 */
+
+#define SCORE_ELF_GOT_SIZE(abfd) \
+ (get_elf_backend_data (abfd)->s->arch_size / 8)
+
+#define SCORE_ELF_ADD_DYNAMIC_ENTRY(info, tag, val) \
+ (_bfd_elf_add_dynamic_entry (info, (bfd_vma) tag, (bfd_vma) val))
+
+/* The size of an external dynamic table entry. */
+#define SCORE_ELF_DYN_SIZE(abfd) \
+ (get_elf_backend_data (abfd)->s->sizeof_dyn)
+
+/* The size of an external REL relocation. */
+#define SCORE_ELF_REL_SIZE(abfd) \
+ (get_elf_backend_data (abfd)->s->sizeof_rel)
+
+/* The default alignment for sections, as a power of two. */
+#define SCORE_ELF_LOG_FILE_ALIGN(abfd)\
+ (get_elf_backend_data (abfd)->s->log_file_align)
+
+static bfd_byte *hi16_rel_addr;
+
+/* This will be used when we sort the dynamic relocation records. */
+static bfd *reldyn_sorting_bfd;
+
+/* SCORE 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 score_elf_scom_section;
+static asymbol score_elf_scom_symbol;
+static asymbol *score_elf_scom_symbol_ptr;
+
+static bfd_vma
+score_bfd_get_16 (bfd *abfd, const void *data)
+{
+ return bfd_get_16 (abfd, data);
+}
+
+static bfd_vma
+score3_bfd_getl32 (const void *p)
+{
+ const bfd_byte *addr = p;
+ unsigned long v;
+
+ v = (unsigned long) addr[2];
+ v |= (unsigned long) addr[3] << 8;
+ v |= (unsigned long) addr[0] << 16;
+ v |= (unsigned long) addr[1] << 24;
+ return v;
+}
+
+static bfd_vma
+score3_bfd_getl48 (const void *p)
+{
+ const bfd_byte *addr = p;
+ unsigned long long v;
+
+ v = (unsigned long long) addr[4];
+ v |= (unsigned long long) addr[5] << 8;
+ v |= (unsigned long long) addr[2] << 16;
+ v |= (unsigned long long) addr[3] << 24;
+ v |= (unsigned long long) addr[0] << 32;
+ v |= (unsigned long long) addr[1] << 40;
+ return v;
+}
+
+static bfd_vma
+score_bfd_get_32 (bfd *abfd, const void *data)
+{
+ if (/* score3 && */ abfd->xvec->byteorder == BFD_ENDIAN_LITTLE)
+ return score3_bfd_getl32 (data);
+ else
+ return bfd_get_32 (abfd, data);
+}
+
+static bfd_vma
+score_bfd_get_48 (bfd *abfd, const void *p)
+{
+ if (/* score3 && */ abfd->xvec->byteorder == BFD_ENDIAN_LITTLE)
+ return score3_bfd_getl48 (p);
+ else
+ return bfd_get_bits (p, 48, 1);
+}
+
+static void
+score_bfd_put_16 (bfd *abfd, bfd_vma addr, void *data)
+{
+ return bfd_put_16 (abfd, addr, data);
+}
+
+static void
+score3_bfd_putl32 (bfd_vma data, void *p)
+{
+ bfd_byte *addr = p;
+ addr[0] = (data >> 16) & 0xff;
+ addr[1] = (data >> 24) & 0xff;
+ addr[2] = data & 0xff;
+ addr[3] = (data >> 8) & 0xff;
+}
+
+static void
+score3_bfd_putl48 (bfd_vma data, void *p)
+{
+ bfd_byte *addr = p;
+ addr[0] = (data >> 32) & 0xff;
+ addr[1] = (data >> 40) & 0xff;
+ addr[2] = (data >> 16) & 0xff;
+ addr[3] = (data >> 24) & 0xff;
+ addr[4] = data & 0xff;
+ addr[5] = (data >> 8) & 0xff;
+}
+
+static void
+score_bfd_put_32 (bfd *abfd, bfd_vma addr, void *data)
+{
+ if (/* score3 && */ abfd->xvec->byteorder == BFD_ENDIAN_LITTLE)
+ return score3_bfd_putl32 (addr, data);
+ else
+ return bfd_put_32 (abfd, addr, data);
+}
+
+static void
+score_bfd_put_48 (bfd *abfd, bfd_vma val, void *p)
+{
+ if (/* score3 && */ abfd->xvec->byteorder == BFD_ENDIAN_LITTLE)
+ return score3_bfd_putl48 (val, p);
+ else
+ return bfd_put_bits (val, p, 48, 1);
+}
+
+static bfd_reloc_status_type
+score_elf_hi16_reloc (bfd *abfd ATTRIBUTE_UNUSED,
+ arelent *reloc_entry,
+ asymbol *symbol ATTRIBUTE_UNUSED,
+ void * data,
+ asection *input_section ATTRIBUTE_UNUSED,
+ bfd *output_bfd ATTRIBUTE_UNUSED,
+ char **error_message ATTRIBUTE_UNUSED)
+{
+ hi16_rel_addr = (bfd_byte *) data + reloc_entry->address;
+ return bfd_reloc_ok;
+}
+
+static bfd_reloc_status_type
+score_elf_lo16_reloc (bfd *abfd,
+ arelent *reloc_entry,
+ asymbol *symbol ATTRIBUTE_UNUSED,
+ void * data,
+ asection *input_section,
+ bfd *output_bfd ATTRIBUTE_UNUSED,
+ char **error_message ATTRIBUTE_UNUSED)
+{
+ bfd_vma addend = 0, offset = 0;
+ unsigned long val;
+ unsigned long hi16_offset, hi16_value, uvalue;
+
+ hi16_value = score_bfd_get_32 (abfd, hi16_rel_addr);
+ hi16_offset = ((((hi16_value >> 16) & 0x3) << 15) | (hi16_value & 0x7fff)) >> 1;
+ addend = score_bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
+ offset = ((((addend >> 16) & 0x3) << 15) | (addend & 0x7fff)) >> 1;
+ val = reloc_entry->addend;
+ if (reloc_entry->address > input_section->size)
+ return bfd_reloc_outofrange;
+ uvalue = ((hi16_offset << 16) | (offset & 0xffff)) + val;
+ hi16_offset = (uvalue >> 16) << 1;
+ hi16_value = (hi16_value & ~0x37fff) | (hi16_offset & 0x7fff) | ((hi16_offset << 1) & 0x30000);
+ score_bfd_put_32 (abfd, hi16_value, hi16_rel_addr);
+ offset = (uvalue & 0xffff) << 1;
+ addend = (addend & ~0x37fff) | (offset & 0x7fff) | ((offset << 1) & 0x30000);
+ score_bfd_put_32 (abfd, addend, (bfd_byte *) data + reloc_entry->address);
+ return bfd_reloc_ok;
+}
+
+/* Set the GP value for OUTPUT_BFD. Returns FALSE if this is a
+ dangerous relocation. */
+
+static bfd_boolean
+score_elf_assign_gp (bfd *output_bfd, bfd_vma *pgp)
+{
+ unsigned int count;
+ asymbol **sym;
+ unsigned int i;
+
+ /* If we've already figured out what GP will be, just return it. */
+ *pgp = _bfd_get_gp_value (output_bfd);
+ if (*pgp)
+ return TRUE;
+
+ count = bfd_get_symcount (output_bfd);
+ sym = bfd_get_outsymbols (output_bfd);
+
+ /* The linker script will have created a symbol named `_gp' with the
+ appropriate value. */
+ if (sym == NULL)
+ i = count;
+ else
+ {
+ for (i = 0; i < count; i++, sym++)
+ {
+ 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);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/* 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 relocatable output. */
+static bfd_reloc_status_type
+score_elf_final_gp (bfd *output_bfd,
+ asymbol *symbol,
+ bfd_boolean relocatable,
+ char **error_message,
+ bfd_vma *pgp)
+{
+ if (bfd_is_und_section (symbol->section)
+ && ! relocatable)
+ {
+ *pgp = 0;
+ return bfd_reloc_undefined;
+ }
+
+ *pgp = _bfd_get_gp_value (output_bfd);
+ if (*pgp == 0
+ && (! relocatable
+ || (symbol->flags & BSF_SECTION_SYM) != 0))
+ {
+ if (relocatable)
+ {
+ /* Make up a value. */
+ *pgp = symbol->section->output_section->vma + 0x4000;
+ _bfd_set_gp_value (output_bfd, *pgp);
+ }
+ else if (!score_elf_assign_gp (output_bfd, pgp))
+ {
+ *error_message =
+ (char *) _("GP relative relocation when _gp not defined");
+ return bfd_reloc_dangerous;
+ }
+ }
+
+ return bfd_reloc_ok;
+}
+
+static bfd_reloc_status_type
+score_elf_gprel15_with_gp (bfd *abfd,
+ asymbol *symbol,
+ arelent *reloc_entry,
+ asection *input_section,
+ bfd_boolean relocateable,
+ void * data,
+ bfd_vma gp ATTRIBUTE_UNUSED)
+{
+ bfd_vma relocation;
+ unsigned long insn;
+
+ 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->size)
+ return bfd_reloc_outofrange;
+
+ insn = score_bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
+ if (((reloc_entry->addend & 0xffffc000) != 0)
+ && ((reloc_entry->addend & 0xffffc000) != 0xffffc000))
+ return bfd_reloc_overflow;
+
+ insn = (insn & ~0x7fff) | (reloc_entry->addend & 0x7fff);
+ score_bfd_put_32 (abfd, insn, (bfd_byte *) data + reloc_entry->address);
+ if (relocateable)
+ reloc_entry->address += input_section->output_offset;
+
+ return bfd_reloc_ok;
+}
+
+static bfd_reloc_status_type
+gprel32_with_gp (bfd *abfd, asymbol *symbol, arelent *reloc_entry,
+ asection *input_section, bfd_boolean relocatable,
+ void *data, bfd_vma gp)
+{
+ bfd_vma relocation;
+ bfd_vma 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 > bfd_get_section_limit (abfd, input_section))
+ return bfd_reloc_outofrange;
+
+ /* Set val to the offset into the section or symbol. */
+ val = reloc_entry->addend;
+
+ if (reloc_entry->howto->partial_inplace)
+ val += score_bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
+
+ /* Adjust val for the final section location and GP value. If we
+ are producing relocatable output, we don't want to do this for
+ an external symbol. */
+ if (! relocatable
+ || (symbol->flags & BSF_SECTION_SYM) != 0)
+ val += relocation - gp;
+
+ if (reloc_entry->howto->partial_inplace)
+ score_bfd_put_32 (abfd, val, (bfd_byte *) data + reloc_entry->address);
+ else
+ reloc_entry->addend = val;
+
+ if (relocatable)
+ reloc_entry->address += input_section->output_offset;
+
+ return bfd_reloc_ok;
+}
+
+static bfd_reloc_status_type
+score_elf_gprel15_reloc (bfd *abfd,
+ arelent *reloc_entry,
+ asymbol *symbol,
+ void * data,
+ asection *input_section,
+ bfd *output_bfd,
+ char **error_message)
+{
+ bfd_boolean relocateable;
+ bfd_reloc_status_type ret;
+ bfd_vma gp;
+
+ 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 = score_elf_final_gp (output_bfd, symbol, relocateable, error_message, &gp);
+ if (ret != bfd_reloc_ok)
+ return ret;
+
+ return score_elf_gprel15_with_gp (abfd, symbol, reloc_entry,
+ input_section, relocateable, data, gp);
+}
+
+/* Do a R_SCORE_GPREL32 relocation. This is a 32 bit value which must
+ become the offset from the gp register. */
+
+static bfd_reloc_status_type
+score_elf_gprel32_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
+ void *data, asection *input_section, bfd *output_bfd,
+ char **error_message)
+{
+ bfd_boolean relocatable;
+ bfd_reloc_status_type ret;
+ bfd_vma gp;
+
+ /* R_SCORE_GPREL32 relocations are defined for local symbols only. */
+ if (output_bfd != NULL
+ && (symbol->flags & BSF_SECTION_SYM) == 0
+ && (symbol->flags & BSF_LOCAL) != 0)
+ {
+ *error_message = (char *)
+ _("32bits gp relative relocation occurs for an external symbol");
+ return bfd_reloc_outofrange;
+ }
+
+ if (output_bfd != NULL)
+ relocatable = TRUE;
+ else
+ {
+ relocatable = FALSE;
+ output_bfd = symbol->section->output_section->owner;
+ }
+
+ ret = score_elf_final_gp (output_bfd, symbol, relocatable, error_message, &gp);
+ if (ret != bfd_reloc_ok)
+ return ret;
+
+ gp = 0;
+ return gprel32_with_gp (abfd, symbol, reloc_entry, input_section,
+ relocatable, data, gp);
+}
+
+/* A howto special_function for R_SCORE_GOT15 relocations. This is just
+ like any other 16-bit relocation when applied to global symbols, but is
+ treated in the same as R_SCORE_HI16 when applied to local symbols. */
+static bfd_reloc_status_type
+score_elf_got15_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
+ void *data, asection *input_section,
+ bfd *output_bfd, char **error_message)
+{
+ if ((symbol->flags & (BSF_GLOBAL | BSF_WEAK)) != 0
+ || bfd_is_und_section (bfd_get_section (symbol))
+ || bfd_is_com_section (bfd_get_section (symbol)))
+ /* The relocation is against a global symbol. */
+ return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
+ input_section, output_bfd,
+ error_message);
+
+ return score_elf_hi16_reloc (abfd, reloc_entry, symbol, data,
+ input_section, output_bfd, error_message);
+}
+
+static bfd_reloc_status_type
+score_elf_got_lo16_reloc (bfd *abfd,
+ arelent *reloc_entry,
+ asymbol *symbol ATTRIBUTE_UNUSED,
+ void * data,
+ asection *input_section,
+ bfd *output_bfd ATTRIBUTE_UNUSED,
+ char **error_message ATTRIBUTE_UNUSED)
+{
+ bfd_vma addend = 0, offset = 0;
+ signed long val;
+ signed long hi16_offset, hi16_value, uvalue;
+
+ hi16_value = score_bfd_get_32 (abfd, hi16_rel_addr);
+ hi16_offset = ((((hi16_value >> 16) & 0x3) << 15) | (hi16_value & 0x7fff)) >> 1;
+ addend = score_bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
+ offset = ((((addend >> 16) & 0x3) << 15) | (addend & 0x7fff)) >> 1;
+ val = reloc_entry->addend;
+ if (reloc_entry->address > input_section->size)
+ return bfd_reloc_outofrange;
+ uvalue = ((hi16_offset << 16) | (offset & 0xffff)) + val;
+ if ((uvalue > -0x8000) && (uvalue < 0x7fff))
+ hi16_offset = 0;
+ else
+ hi16_offset = (uvalue >> 16) & 0x7fff;
+ hi16_value = (hi16_value & ~0x37fff) | (hi16_offset & 0x7fff) | ((hi16_offset << 1) & 0x30000);
+ score_bfd_put_32 (abfd, hi16_value, hi16_rel_addr);
+ offset = (uvalue & 0xffff) << 1;
+ addend = (addend & ~0x37fff) | (offset & 0x7fff) | ((offset << 1) & 0x30000);
+ score_bfd_put_32 (abfd, addend, (bfd_byte *) data + reloc_entry->address);
+ return bfd_reloc_ok;
+}
+
+static reloc_howto_type elf32_score_howto_table[] =
+{
+ /* No relocation. */
+ HOWTO (R_SCORE_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_SCORE_NONE", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* R_SCORE_HI16 */
+ HOWTO (R_SCORE_HI16, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 1, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ score_elf_hi16_reloc, /* special_function */
+ "R_SCORE_HI16", /* name */
+ TRUE, /* partial_inplace */
+ 0x37fff, /* src_mask */
+ 0x37fff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* R_SCORE_LO16 */
+ HOWTO (R_SCORE_LO16, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 1, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ score_elf_lo16_reloc, /* special_function */
+ "R_SCORE_LO16", /* name */
+ TRUE, /* partial_inplace */
+ 0x37fff, /* src_mask */
+ 0x37fff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* R_SCORE_BCMP */
+ HOWTO (R_SCORE_BCMP, /* type */
+ 1, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ TRUE, /* pc_relative */
+ 1, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SCORE_BCMP", /* name */
+ FALSE, /* partial_inplace */
+ 0x03e00381, /* src_mask */
+ 0x03e00381, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /*R_SCORE_24 */
+ HOWTO (R_SCORE_24, /* type */
+ 1, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 24, /* bitsize */
+ FALSE, /* pc_relative */
+ 1, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SCORE_24", /* name */
+ FALSE, /* partial_inplace */
+ 0x3ff7fff, /* src_mask */
+ 0x3ff7fff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /*R_SCORE_PC19 */
+ HOWTO (R_SCORE_PC19, /* type */
+ 1, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 19, /* bitsize */
+ TRUE, /* pc_relative */
+ 1, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SCORE_PC19", /* name */
+ FALSE, /* partial_inplace */
+ 0x3ff03fe, /* src_mask */
+ 0x3ff03fe, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /*R_SCORE16_11 */
+ HOWTO (R_SCORE16_11, /* type */
+ 1, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 11, /* bitsize */
+ FALSE, /* pc_relative */
+ 1, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SCORE16_11", /* name */
+ FALSE, /* partial_inplace */
+ 0x000000ffe, /* src_mask */
+ 0x000000ffe, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* R_SCORE16_PC8 */
+ HOWTO (R_SCORE16_PC8, /* type */
+ 1, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 9, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SCORE16_PC8", /* name */
+ FALSE, /* partial_inplace */
+ 0x000001ff, /* src_mask */
+ 0x000001ff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* 32 bit absolute */
+ HOWTO (R_SCORE_ABS32, /* type 8 */
+ 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_SCORE_ABS32", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* 16 bit absolute */
+ HOWTO (R_SCORE_ABS16, /* type 11 */
+ 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_SCORE_ABS16", /* name */
+ FALSE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* R_SCORE_DUMMY2 */
+ HOWTO (R_SCORE_DUMMY2, /* 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_SCORE_DUMMY2", /* name */
+ TRUE, /* partial_inplace */
+ 0x00007fff, /* src_mask */
+ 0x00007fff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* R_SCORE_GP15 */
+ HOWTO (R_SCORE_GP15, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ score_elf_gprel15_reloc,/* special_function */
+ "R_SCORE_GP15", /* name */
+ TRUE, /* partial_inplace */
+ 0x00007fff, /* src_mask */
+ 0x00007fff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* GNU extension to record C++ vtable hierarchy. */
+ HOWTO (R_SCORE_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_SCORE_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_SCORE_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_SCORE_GNU_VTENTRY", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Reference to global offset table. */
+ HOWTO (R_SCORE_GOT15, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ score_elf_got15_reloc, /* special_function */
+ "R_SCORE_GOT15", /* name */
+ TRUE, /* partial_inplace */
+ 0x00007fff, /* src_mask */
+ 0x00007fff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Low 16 bits of displacement in global offset table. */
+ HOWTO (R_SCORE_GOT_LO16, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 1, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ score_elf_got_lo16_reloc, /* special_function */
+ "R_SCORE_GOT_LO16", /* name */
+ TRUE, /* partial_inplace */
+ 0x37ffe, /* src_mask */
+ 0x37ffe, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* 15 bit call through global offset table. */
+ HOWTO (R_SCORE_CALL15, /* 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_SCORE_CALL15", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* 32 bit GP relative reference. */
+ HOWTO (R_SCORE_GPREL32, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ score_elf_gprel32_reloc, /* special_function */
+ "R_SCORE_GPREL32", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* 32 bit symbol relative relocation. */
+ HOWTO (R_SCORE_REL32, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SCORE_REL32", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* R_SCORE_DUMMY_HI16 */
+ HOWTO (R_SCORE_DUMMY_HI16, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 1, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ score_elf_hi16_reloc, /* special_function */
+ "R_SCORE_DUMMY_HI16", /* name */
+ TRUE, /* partial_inplace */
+ 0x37fff, /* src_mask */
+ 0x37fff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* R_SCORE_IMM30 */
+ HOWTO (R_SCORE_IMM30, /* type */
+ 2, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 30, /* bitsize */
+ FALSE, /* pc_relative */
+ 7, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SCORE_IMM30", /* name */
+ FALSE, /* partial_inplace */
+ 0x7f7fff7f80LL, /* src_mask */
+ 0x7f7fff7f80LL, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* R_SCORE_IMM32 */
+ HOWTO (R_SCORE_IMM32, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 5, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SCORE_IMM32", /* name */
+ FALSE, /* partial_inplace */
+ 0x7f7fff7fe0LL, /* src_mask */
+ 0x7f7fff7fe0LL, /* dst_mask */
+ FALSE), /* pcrel_offset */
+};
+
+struct score_reloc_map
+{
+ bfd_reloc_code_real_type bfd_reloc_val;
+ unsigned char elf_reloc_val;
+};
+
+static const struct score_reloc_map elf32_score_reloc_map[] =
+{
+ {BFD_RELOC_NONE, R_SCORE_NONE},
+ {BFD_RELOC_HI16_S, R_SCORE_HI16},
+ {BFD_RELOC_LO16, R_SCORE_LO16},
+ {BFD_RELOC_SCORE_BCMP, R_SCORE_BCMP},
+ {BFD_RELOC_SCORE_JMP, R_SCORE_24},
+ {BFD_RELOC_SCORE_BRANCH, R_SCORE_PC19},
+ {BFD_RELOC_SCORE16_JMP, R_SCORE16_11},
+ {BFD_RELOC_SCORE16_BRANCH, R_SCORE16_PC8},
+ {BFD_RELOC_32, R_SCORE_ABS32},
+ {BFD_RELOC_16, R_SCORE_ABS16},
+ {BFD_RELOC_SCORE_DUMMY2, R_SCORE_DUMMY2},
+ {BFD_RELOC_SCORE_GPREL15, R_SCORE_GP15},
+ {BFD_RELOC_VTABLE_INHERIT, R_SCORE_GNU_VTINHERIT},
+ {BFD_RELOC_VTABLE_ENTRY, R_SCORE_GNU_VTENTRY},
+ {BFD_RELOC_SCORE_GOT15, R_SCORE_GOT15},
+ {BFD_RELOC_SCORE_GOT_LO16, R_SCORE_GOT_LO16},
+ {BFD_RELOC_SCORE_CALL15, R_SCORE_CALL15},
+ {BFD_RELOC_GPREL32, R_SCORE_GPREL32},
+ {BFD_RELOC_32_PCREL, R_SCORE_REL32},
+ {BFD_RELOC_SCORE_DUMMY_HI16, R_SCORE_DUMMY_HI16},
+ {BFD_RELOC_SCORE_IMM30, R_SCORE_IMM30},
+ {BFD_RELOC_SCORE_IMM32, R_SCORE_IMM32},
+};
+
+/* got_entries only match if they're identical, except for gotidx, so
+ use all fields to compute the hash, and compare the appropriate
+ union members. */
+static hashval_t
+score_elf_got_entry_hash (const void *entry_)
+{
+ const struct score_got_entry *entry = (struct score_got_entry *)entry_;
+
+ return entry->symndx
+ + (!entry->abfd ? entry->d.address : entry->abfd->id);
+}
+
+static int
+score_elf_got_entry_eq (const void *entry1, const void *entry2)
+{
+ const struct score_got_entry *e1 = (struct score_got_entry *)entry1;
+ const struct score_got_entry *e2 = (struct score_got_entry *)entry2;
+
+ return e1->abfd == e2->abfd && e1->symndx == e2->symndx
+ && (! e1->abfd ? e1->d.address == e2->d.address
+ : e1->symndx >= 0 ? e1->d.addend == e2->d.addend
+ : e1->d.h == e2->d.h);
+}
+
+/* If H needs a GOT entry, assign it the highest available dynamic
+ index. Otherwise, assign it the lowest available dynamic
+ index. */
+static bfd_boolean
+score_elf_sort_hash_table_f (struct score_elf_link_hash_entry *h, void *data)
+{
+ struct score_elf_hash_sort_data *hsd = data;
+
+ /* Symbols without dynamic symbol table entries aren't interesting at all. */
+ if (h->root.dynindx == -1)
+ return TRUE;
+
+ /* Global symbols that need GOT entries that are not explicitly
+ referenced are marked with got offset 2. Those that are
+ referenced get a 1, and those that don't need GOT entries get
+ -1. */
+ if (h->root.got.offset == 2)
+ {
+ if (hsd->max_unref_got_dynindx == hsd->min_got_dynindx)
+ hsd->low = (struct elf_link_hash_entry *) h;
+ h->root.dynindx = hsd->max_unref_got_dynindx++;
+ }
+ else if (h->root.got.offset != 1)
+ h->root.dynindx = hsd->max_non_got_dynindx++;
+ else
+ {
+ h->root.dynindx = --hsd->min_got_dynindx;
+ hsd->low = (struct elf_link_hash_entry *) h;
+ }
+
+ return TRUE;
+}
+
+static asection *
+score_elf_got_section (bfd *abfd, bfd_boolean maybe_excluded)
+{
+ asection *sgot = bfd_get_linker_section (abfd, ".got");
+
+ if (sgot == NULL || (! maybe_excluded && (sgot->flags & SEC_EXCLUDE) != 0))
+ return NULL;
+ return sgot;
+}
+
+/* Returns the GOT information associated with the link indicated by
+ INFO. If SGOTP is non-NULL, it is filled in with the GOT section. */
+static struct score_got_info *
+score_elf_got_info (bfd *abfd, asection **sgotp)
+{
+ asection *sgot;
+ struct score_got_info *g;
+
+ sgot = score_elf_got_section (abfd, TRUE);
+ BFD_ASSERT (sgot != NULL);
+ BFD_ASSERT (elf_section_data (sgot) != NULL);
+ g = score_elf_section_data (sgot)->u.got_info;
+ BFD_ASSERT (g != NULL);
+
+ if (sgotp)
+ *sgotp = sgot;
+ return g;
+}
+
+/* Sort the dynamic symbol table so that symbols that need GOT entries
+ appear towards the end. This reduces the amount of GOT space
+ required. MAX_LOCAL is used to set the number of local symbols
+ known to be in the dynamic symbol table. During
+ s3_bfd_score_elf_size_dynamic_sections, this value is 1. Afterward, the
+ section symbols are added and the count is higher. */
+static bfd_boolean
+score_elf_sort_hash_table (struct bfd_link_info *info,
+ unsigned long max_local)
+{
+ struct score_elf_hash_sort_data hsd;
+ struct score_got_info *g;
+ bfd *dynobj;
+
+ dynobj = elf_hash_table (info)->dynobj;
+
+ g = score_elf_got_info (dynobj, NULL);
+
+ hsd.low = NULL;
+ hsd.max_unref_got_dynindx =
+ hsd.min_got_dynindx = elf_hash_table (info)->dynsymcount
+ /* In the multi-got case, assigned_gotno of the master got_info
+ indicate the number of entries that aren't referenced in the
+ primary GOT, but that must have entries because there are
+ dynamic relocations that reference it. Since they aren't
+ referenced, we move them to the end of the GOT, so that they
+ don't prevent other entries that are referenced from getting
+ too large offsets. */
+ - (g->next ? g->assigned_gotno : 0);
+ hsd.max_non_got_dynindx = max_local;
+ score_elf_link_hash_traverse (elf_hash_table (info),
+ score_elf_sort_hash_table_f,
+ &hsd);
+
+ /* There should have been enough room in the symbol table to
+ accommodate both the GOT and non-GOT symbols. */
+ BFD_ASSERT (hsd.max_non_got_dynindx <= hsd.min_got_dynindx);
+ BFD_ASSERT ((unsigned long)hsd.max_unref_got_dynindx
+ <= elf_hash_table (info)->dynsymcount);
+
+ /* Now we know which dynamic symbol has the lowest dynamic symbol
+ table index in the GOT. */
+ g->global_gotsym = hsd.low;
+
+ return TRUE;
+}
+
+/* Create an entry in an score ELF linker hash table. */
+
+static struct bfd_hash_entry *
+score_elf_link_hash_newfunc (struct bfd_hash_entry *entry,
+ struct bfd_hash_table *table,
+ const char *string)
+{
+ struct score_elf_link_hash_entry *ret = (struct score_elf_link_hash_entry *) entry;
+
+ /* Allocate the structure if it has not already been allocated by a subclass. */
+ if (ret == NULL)
+ ret = bfd_hash_allocate (table, sizeof (struct score_elf_link_hash_entry));
+ if (ret == NULL)
+ return (struct bfd_hash_entry *) ret;
+
+ /* Call the allocation method of the superclass. */
+ ret = ((struct score_elf_link_hash_entry *)
+ _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry *) ret, table, string));
+
+ if (ret != NULL)
+ {
+ ret->possibly_dynamic_relocs = 0;
+ ret->readonly_reloc = FALSE;
+ ret->no_fn_stub = FALSE;
+ ret->forced_local = FALSE;
+ }
+
+ return (struct bfd_hash_entry *) ret;
+}
+
+/* Returns the first relocation of type r_type found, beginning with
+ RELOCATION. RELEND is one-past-the-end of the relocation table. */
+static const Elf_Internal_Rela *
+score_elf_next_relocation (bfd *abfd ATTRIBUTE_UNUSED, unsigned int r_type,
+ const Elf_Internal_Rela *relocation,
+ const Elf_Internal_Rela *relend)
+{
+ while (relocation < relend)
+ {
+ if (ELF32_R_TYPE (relocation->r_info) == r_type)
+ return relocation;
+
+ ++relocation;
+ }
+
+ /* We didn't find it. */
+ bfd_set_error (bfd_error_bad_value);
+ return NULL;
+}
+
+/* This function is called via qsort() to sort the dynamic relocation
+ entries by increasing r_symndx value. */
+static int
+score_elf_sort_dynamic_relocs (const void *arg1, const void *arg2)
+{
+ Elf_Internal_Rela int_reloc1;
+ Elf_Internal_Rela int_reloc2;
+
+ bfd_elf32_swap_reloc_in (reldyn_sorting_bfd, arg1, &int_reloc1);
+ bfd_elf32_swap_reloc_in (reldyn_sorting_bfd, arg2, &int_reloc2);
+
+ return (ELF32_R_SYM (int_reloc1.r_info) - ELF32_R_SYM (int_reloc2.r_info));
+}
+
+/* Return whether a relocation is against a local symbol. */
+static bfd_boolean
+score_elf_local_relocation_p (bfd *input_bfd,
+ const Elf_Internal_Rela *relocation,
+ asection **local_sections,
+ bfd_boolean check_forced)
+{
+ unsigned long r_symndx;
+ Elf_Internal_Shdr *symtab_hdr;
+ struct score_elf_link_hash_entry *h;
+ size_t extsymoff;
+
+ r_symndx = ELF32_R_SYM (relocation->r_info);
+ symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
+ extsymoff = (elf_bad_symtab (input_bfd)) ? 0 : symtab_hdr->sh_info;
+
+ if (r_symndx < extsymoff)
+ return TRUE;
+ if (elf_bad_symtab (input_bfd) && local_sections[r_symndx] != NULL)
+ return TRUE;
+
+ if (check_forced)
+ {
+ /* Look up the hash table to check whether the symbol was forced local. */
+ h = (struct score_elf_link_hash_entry *)
+ elf_sym_hashes (input_bfd) [r_symndx - extsymoff];
+ /* Find the real hash-table entry for this symbol. */
+ while (h->root.root.type == bfd_link_hash_indirect
+ || h->root.root.type == bfd_link_hash_warning)
+ h = (struct score_elf_link_hash_entry *) h->root.root.u.i.link;
+ if (h->root.forced_local)
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/* Returns the dynamic relocation section for DYNOBJ. */
+static asection *
+score_elf_rel_dyn_section (bfd *dynobj, bfd_boolean create_p)
+{
+ static const char dname[] = ".rel.dyn";
+ asection *sreloc;
+
+ sreloc = bfd_get_linker_section (dynobj, dname);
+ if (sreloc == NULL && create_p)
+ {
+ sreloc = bfd_make_section_anyway_with_flags (dynobj, dname,
+ (SEC_ALLOC
+ | SEC_LOAD
+ | SEC_HAS_CONTENTS
+ | SEC_IN_MEMORY
+ | SEC_LINKER_CREATED
+ | SEC_READONLY));
+ if (sreloc == NULL
+ || ! bfd_set_section_alignment (dynobj, sreloc,
+ SCORE_ELF_LOG_FILE_ALIGN (dynobj)))
+ return NULL;
+ }
+ return sreloc;
+}
+
+static void
+score_elf_allocate_dynamic_relocations (bfd *abfd, unsigned int n)
+{
+ asection *s;
+
+ s = score_elf_rel_dyn_section (abfd, FALSE);
+ BFD_ASSERT (s != NULL);
+
+ if (s->size == 0)
+ {
+ /* Make room for a null element. */
+ s->size += SCORE_ELF_REL_SIZE (abfd);
+ ++s->reloc_count;
+ }
+ s->size += n * SCORE_ELF_REL_SIZE (abfd);
+}
+
+/* Create a rel.dyn relocation for the dynamic linker to resolve. REL
+ is the original relocation, which is now being transformed into a
+ dynamic relocation. The ADDENDP is adjusted if necessary; the
+ caller should store the result in place of the original addend. */
+static bfd_boolean
+score_elf_create_dynamic_relocation (bfd *output_bfd,
+ struct bfd_link_info *info,
+ const Elf_Internal_Rela *rel,
+ struct score_elf_link_hash_entry *h,
+ bfd_vma symbol,
+ bfd_vma *addendp, asection *input_section)
+{
+ Elf_Internal_Rela outrel[3];
+ asection *sreloc;
+ bfd *dynobj;
+ int r_type;
+ long indx;
+ bfd_boolean defined_p;
+
+ r_type = ELF32_R_TYPE (rel->r_info);
+ dynobj = elf_hash_table (info)->dynobj;
+ sreloc = score_elf_rel_dyn_section (dynobj, FALSE);
+ BFD_ASSERT (sreloc != NULL);
+ BFD_ASSERT (sreloc->contents != NULL);
+ BFD_ASSERT (sreloc->reloc_count * SCORE_ELF_REL_SIZE (output_bfd) < sreloc->size);
+
+ outrel[0].r_offset =
+ _bfd_elf_section_offset (output_bfd, info, input_section, rel[0].r_offset);
+ outrel[1].r_offset =
+ _bfd_elf_section_offset (output_bfd, info, input_section, rel[1].r_offset);
+ outrel[2].r_offset =
+ _bfd_elf_section_offset (output_bfd, info, input_section, rel[2].r_offset);
+
+ if (outrel[0].r_offset == MINUS_ONE)
+ /* The relocation field has been deleted. */
+ return TRUE;
+
+ if (outrel[0].r_offset == MINUS_TWO)
+ {
+ /* The relocation field has been converted into a relative value of
+ some sort. Functions like _bfd_elf_write_section_eh_frame expect
+ the field to be fully relocated, so add in the symbol's value. */
+ *addendp += symbol;
+ return TRUE;
+ }
+
+ /* We must now calculate the dynamic symbol table index to use
+ in the relocation. */
+ if (h != NULL
+ && (! info->symbolic || !h->root.def_regular)
+ /* h->root.dynindx may be -1 if this symbol was marked to
+ become local. */
+ && h->root.dynindx != -1)
+ {
+ indx = h->root.dynindx;
+ /* ??? glibc's ld.so just adds the final GOT entry to the
+ relocation field. It therefore treats relocs against
+ defined symbols in the same way as relocs against
+ undefined symbols. */
+ defined_p = FALSE;
+ }
+ else
+ {
+ indx = 0;
+ defined_p = TRUE;
+ }
+
+ /* If the relocation was previously an absolute relocation and
+ this symbol will not be referred to by the relocation, we must
+ adjust it by the value we give it in the dynamic symbol table.
+ Otherwise leave the job up to the dynamic linker. */
+ if (defined_p && r_type != R_SCORE_REL32)
+ *addendp += symbol;
+
+ /* The relocation is always an REL32 relocation because we don't
+ know where the shared library will wind up at load-time. */
+ outrel[0].r_info = ELF32_R_INFO ((unsigned long) indx, R_SCORE_REL32);
+
+ /* For strict adherence to the ABI specification, we should
+ generate a R_SCORE_64 relocation record by itself before the
+ _REL32/_64 record as well, such that the addend is read in as
+ a 64-bit value (REL32 is a 32-bit relocation, after all).
+ However, since none of the existing ELF64 SCORE dynamic
+ loaders seems to care, we don't waste space with these
+ artificial relocations. If this turns out to not be true,
+ score_elf_allocate_dynamic_relocations() should be tweaked so
+ as to make room for a pair of dynamic relocations per
+ invocation if ABI_64_P, and here we should generate an
+ additional relocation record with R_SCORE_64 by itself for a
+ NULL symbol before this relocation record. */
+ outrel[1].r_info = ELF32_R_INFO (0, R_SCORE_NONE);
+ outrel[2].r_info = ELF32_R_INFO (0, R_SCORE_NONE);
+
+ /* Adjust the output offset of the relocation to reference the
+ correct location in the output file. */
+ outrel[0].r_offset += (input_section->output_section->vma
+ + input_section->output_offset);
+ outrel[1].r_offset += (input_section->output_section->vma
+ + input_section->output_offset);
+ outrel[2].r_offset += (input_section->output_section->vma
+ + input_section->output_offset);
+
+ /* Put the relocation back out. We have to use the special
+ relocation outputter in the 64-bit case since the 64-bit
+ relocation format is non-standard. */
+ bfd_elf32_swap_reloc_out
+ (output_bfd, &outrel[0],
+ (sreloc->contents + sreloc->reloc_count * sizeof (Elf32_External_Rel)));
+
+ /* We've now added another relocation. */
+ ++sreloc->reloc_count;
+
+ /* Make sure the output section is writable. The dynamic linker
+ will be writing to it. */
+ elf_section_data (input_section->output_section)->this_hdr.sh_flags |= SHF_WRITE;
+
+ return TRUE;
+}
+
+static bfd_boolean
+score_elf_create_got_section (bfd *abfd,
+ struct bfd_link_info *info,
+ bfd_boolean maybe_exclude)
+{
+ flagword flags;
+ asection *s;
+ struct elf_link_hash_entry *h;
+ struct bfd_link_hash_entry *bh;
+ struct score_got_info *g;
+ bfd_size_type amt;
+
+ /* This function may be called more than once. */
+ s = score_elf_got_section (abfd, TRUE);
+ if (s)
+ {
+ if (! maybe_exclude)
+ s->flags &= ~SEC_EXCLUDE;
+ return TRUE;
+ }
+
+ flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_LINKER_CREATED);
+
+ if (maybe_exclude)
+ flags |= SEC_EXCLUDE;
+
+ /* We have to use an alignment of 2**4 here because this is hardcoded
+ in the function stub generation and in the linker script. */
+ s = bfd_make_section_anyway_with_flags (abfd, ".got", flags);
+ if (s == NULL
+ || ! 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. */
+ bh = NULL;
+ if (! (_bfd_generic_link_add_one_symbol
+ (info, abfd, "_GLOBAL_OFFSET_TABLE_", BSF_GLOBAL, s,
+ 0, NULL, FALSE, get_elf_backend_data (abfd)->collect, &bh)))
+ return FALSE;
+
+ h = (struct elf_link_hash_entry *) bh;
+ h->non_elf = 0;
+ h->def_regular = 1;
+ h->type = STT_OBJECT;
+
+ if (info->shared && ! bfd_elf_link_record_dynamic_symbol (info, h))
+ return FALSE;
+
+ amt = sizeof (struct score_got_info);
+ g = bfd_alloc (abfd, amt);
+ if (g == NULL)
+ return FALSE;
+
+ g->global_gotsym = NULL;
+ g->global_gotno = 0;
+
+ g->local_gotno = SCORE_RESERVED_GOTNO;
+ g->assigned_gotno = SCORE_RESERVED_GOTNO;
+ g->next = NULL;
+
+ g->got_entries = htab_try_create (1, score_elf_got_entry_hash,
+ score_elf_got_entry_eq, NULL);
+ if (g->got_entries == NULL)
+ return FALSE;
+ score_elf_section_data (s)->u.got_info = g;
+ score_elf_section_data (s)->elf.this_hdr.sh_flags |= SHF_ALLOC | SHF_WRITE | SHF_SCORE_GPREL;
+
+ return TRUE;
+}
+
+/* Calculate the %high function. */
+static bfd_vma
+score_elf_high (bfd_vma value)
+{
+ return ((value + (bfd_vma) 0x8000) >> 16) & 0xffff;
+}
+
+/* Create a local GOT entry for VALUE. Return the index of the entry,
+ or -1 if it could not be created. */
+static struct score_got_entry *
+score_elf_create_local_got_entry (bfd *abfd,
+ bfd *ibfd ATTRIBUTE_UNUSED,
+ struct score_got_info *gg,
+ asection *sgot, bfd_vma value,
+ unsigned long r_symndx ATTRIBUTE_UNUSED,
+ struct score_elf_link_hash_entry *h ATTRIBUTE_UNUSED,
+ int r_type ATTRIBUTE_UNUSED)
+{
+ struct score_got_entry entry, **loc;
+ struct score_got_info *g;
+
+ entry.abfd = NULL;
+ entry.symndx = -1;
+ entry.d.address = value;
+
+ g = gg;
+ loc = (struct score_got_entry **) htab_find_slot (g->got_entries, &entry, INSERT);
+ if (*loc)
+ return *loc;
+
+ entry.gotidx = SCORE_ELF_GOT_SIZE (abfd) * g->assigned_gotno++;
+
+ *loc = bfd_alloc (abfd, sizeof entry);
+
+ if (! *loc)
+ return NULL;
+
+ memcpy (*loc, &entry, sizeof entry);
+
+ if (g->assigned_gotno >= g->local_gotno)
+ {
+ (*loc)->gotidx = -1;
+ /* We didn't allocate enough space in the GOT. */
+ (*_bfd_error_handler)
+ (_("not enough GOT space for local GOT entries"));
+ bfd_set_error (bfd_error_bad_value);
+ return NULL;
+ }
+
+ score_bfd_put_32 (abfd, value, (sgot->contents + entry.gotidx));
+
+ return *loc;
+}
+
+/* Find a GOT entry whose higher-order 16 bits are the same as those
+ for value. Return the index into the GOT for this entry. */
+static bfd_vma
+score_elf_got16_entry (bfd *abfd, bfd *ibfd, struct bfd_link_info *info,
+ bfd_vma value, bfd_boolean external)
+{
+ asection *sgot;
+ struct score_got_info *g;
+ struct score_got_entry *entry;
+
+ if (!external)
+ {
+ /* Although the ABI says that it is "the high-order 16 bits" that we
+ want, it is really the %high value. The complete value is
+ calculated with a `addiu' of a LO16 relocation, just as with a
+ HI16/LO16 pair. */
+ value = score_elf_high (value) << 16;
+ }
+
+ g = score_elf_got_info (elf_hash_table (info)->dynobj, &sgot);
+
+ entry = score_elf_create_local_got_entry (abfd, ibfd, g, sgot, value, 0, NULL,
+ R_SCORE_GOT15);
+ if (entry)
+ return entry->gotidx;
+ else
+ return MINUS_ONE;
+}
+
+static void
+s3_bfd_score_elf_hide_symbol (struct bfd_link_info *info,
+ struct elf_link_hash_entry *entry,
+ bfd_boolean force_local)
+{
+ bfd *dynobj;
+ asection *got;
+ struct score_got_info *g;
+ struct score_elf_link_hash_entry *h;
+
+ h = (struct score_elf_link_hash_entry *) entry;
+ if (h->forced_local)
+ return;
+ h->forced_local = TRUE;
+
+ dynobj = elf_hash_table (info)->dynobj;
+ if (dynobj != NULL && force_local)
+ {
+ got = score_elf_got_section (dynobj, FALSE);
+ if (got == NULL)
+ return;
+ g = score_elf_section_data (got)->u.got_info;
+
+ if (g->next)
+ {
+ struct score_got_entry e;
+ struct score_got_info *gg = g;
+
+ /* Since we're turning what used to be a global symbol into a
+ local one, bump up the number of local entries of each GOT
+ that had an entry for it. This will automatically decrease
+ the number of global entries, since global_gotno is actually
+ the upper limit of global entries. */
+ e.abfd = dynobj;
+ e.symndx = -1;
+ e.d.h = h;
+
+ for (g = g->next; g != gg; g = g->next)
+ if (htab_find (g->got_entries, &e))
+ {
+ BFD_ASSERT (g->global_gotno > 0);
+ g->local_gotno++;
+ g->global_gotno--;
+ }
+
+ /* If this was a global symbol forced into the primary GOT, we
+ no longer need an entry for it. We can't release the entry
+ at this point, but we must at least stop counting it as one
+ of the symbols that required a forced got entry. */
+ if (h->root.got.offset == 2)
+ {
+ BFD_ASSERT (gg->assigned_gotno > 0);
+ gg->assigned_gotno--;
+ }
+ }
+ else if (g->global_gotno == 0 && g->global_gotsym == NULL)
+ /* If we haven't got through GOT allocation yet, just bump up the
+ number of local entries, as this symbol won't be counted as
+ global. */
+ g->local_gotno++;
+ else if (h->root.got.offset == 1)
+ {
+ /* If we're past non-multi-GOT allocation and this symbol had
+ been marked for a global got entry, give it a local entry
+ instead. */
+ BFD_ASSERT (g->global_gotno > 0);
+ g->local_gotno++;
+ g->global_gotno--;
+ }
+ }
+
+ _bfd_elf_link_hash_hide_symbol (info, &h->root, force_local);
+}
+
+/* If H is a symbol that needs a global GOT entry, but has a dynamic
+ symbol table index lower than any we've seen to date, record it for
+ posterity. */
+static bfd_boolean
+score_elf_record_global_got_symbol (struct elf_link_hash_entry *h,
+ bfd *abfd,
+ struct bfd_link_info *info,
+ struct score_got_info *g)
+{
+ struct score_got_entry entry, **loc;
+
+ /* A global symbol in the GOT must also be in the dynamic symbol table. */
+ if (h->dynindx == -1)
+ {
+ switch (ELF_ST_VISIBILITY (h->other))
+ {
+ case STV_INTERNAL:
+ case STV_HIDDEN:
+ s3_bfd_score_elf_hide_symbol (info, h, TRUE);
+ break;
+ }
+ if (!bfd_elf_link_record_dynamic_symbol (info, h))
+ return FALSE;
+ }
+
+ entry.abfd = abfd;
+ entry.symndx = -1;
+ entry.d.h = (struct score_elf_link_hash_entry *)h;
+
+ loc = (struct score_got_entry **)htab_find_slot (g->got_entries, &entry, INSERT);
+
+ /* If we've already marked this entry as needing GOT space, we don't
+ need to do it again. */
+ if (*loc)
+ return TRUE;
+
+ *loc = bfd_alloc (abfd, sizeof entry);
+ if (! *loc)
+ return FALSE;
+
+ entry.gotidx = -1;
+
+ memcpy (*loc, &entry, sizeof (entry));
+
+ if (h->got.offset != MINUS_ONE)
+ return TRUE;
+
+ /* By setting this to a value other than -1, we are indicating that
+ there needs to be a GOT entry for H. Avoid using zero, as the
+ generic ELF copy_indirect_symbol tests for <= 0. */
+ h->got.offset = 1;
+
+ return TRUE;
+}
+
+/* Reserve space in G for a GOT entry containing the value of symbol
+ SYMNDX in input bfd ABDF, plus ADDEND. */
+static bfd_boolean
+score_elf_record_local_got_symbol (bfd *abfd,
+ long symndx,
+ bfd_vma addend,
+ struct score_got_info *g)
+{
+ struct score_got_entry entry, **loc;
+
+ entry.abfd = abfd;
+ entry.symndx = symndx;
+ entry.d.addend = addend;
+ loc = (struct score_got_entry **)htab_find_slot (g->got_entries, &entry, INSERT);
+
+ if (*loc)
+ return TRUE;
+
+ entry.gotidx = g->local_gotno++;
+
+ *loc = bfd_alloc (abfd, sizeof(entry));
+ if (! *loc)
+ return FALSE;
+
+ memcpy (*loc, &entry, sizeof (entry));
+
+ return TRUE;
+}
+
+/* Returns the GOT offset at which the indicated address can be found.
+ If there is not yet a GOT entry for this value, create one.
+ Returns -1 if no satisfactory GOT offset can be found. */
+static bfd_vma
+score_elf_local_got_index (bfd *abfd, bfd *ibfd, struct bfd_link_info *info,
+ bfd_vma value, unsigned long r_symndx,
+ struct score_elf_link_hash_entry *h, int r_type)
+{
+ asection *sgot;
+ struct score_got_info *g;
+ struct score_got_entry *entry;
+
+ g = score_elf_got_info (elf_hash_table (info)->dynobj, &sgot);
+
+ entry = score_elf_create_local_got_entry (abfd, ibfd, g, sgot, value,
+ r_symndx, h, r_type);
+ if (!entry)
+ return MINUS_ONE;
+
+ else
+ return entry->gotidx;
+}
+
+/* Returns the GOT index for the global symbol indicated by H. */
+
+static bfd_vma
+score_elf_global_got_index (bfd *abfd, struct elf_link_hash_entry *h)
+{
+ bfd_vma got_index;
+ asection *sgot;
+ struct score_got_info *g;
+ long global_got_dynindx = 0;
+
+ g = score_elf_got_info (abfd, &sgot);
+ if (g->global_gotsym != NULL)
+ global_got_dynindx = g->global_gotsym->dynindx;
+
+ /* Once we determine the global GOT entry with the lowest dynamic
+ symbol table index, we must put all dynamic symbols with greater
+ indices into the GOT. That makes it easy to calculate the GOT
+ offset. */
+ BFD_ASSERT (h->dynindx >= global_got_dynindx);
+ got_index = ((h->dynindx - global_got_dynindx + g->local_gotno) * SCORE_ELF_GOT_SIZE (abfd));
+ BFD_ASSERT (got_index < sgot->size);
+
+ return got_index;
+}
+
+/* Returns the offset for the entry at the INDEXth position in the GOT. */
+
+static bfd_vma
+score_elf_got_offset_from_index (bfd *dynobj,
+ bfd *output_bfd,
+ bfd *input_bfd ATTRIBUTE_UNUSED,
+ bfd_vma got_index)
+{
+ asection *sgot;
+ bfd_vma gp;
+
+ score_elf_got_info (dynobj, &sgot);
+ gp = _bfd_get_gp_value (output_bfd);
+
+ return sgot->output_section->vma + sgot->output_offset + got_index - gp;
+}
+
+/* Follow indirect and warning hash entries so that each got entry
+ points to the final symbol definition. P must point to a pointer
+ to the hash table we're traversing. Since this traversal may
+ modify the hash table, we set this pointer to NULL to indicate
+ we've made a potentially-destructive change to the hash table, so
+ the traversal must be restarted. */
+static int
+score_elf_resolve_final_got_entry (void **entryp, void *p)
+{
+ struct score_got_entry *entry = (struct score_got_entry *)*entryp;
+ htab_t got_entries = *(htab_t *)p;
+
+ if (entry->abfd != NULL && entry->symndx == -1)
+ {
+ struct score_elf_link_hash_entry *h = entry->d.h;
+
+ while (h->root.root.type == bfd_link_hash_indirect
+ || h->root.root.type == bfd_link_hash_warning)
+ h = (struct score_elf_link_hash_entry *) h->root.root.u.i.link;
+
+ if (entry->d.h == h)
+ return 1;
+
+ entry->d.h = h;
+
+ /* If we can't find this entry with the new bfd hash, re-insert
+ it, and get the traversal restarted. */
+ if (! htab_find (got_entries, entry))
+ {
+ htab_clear_slot (got_entries, entryp);
+ entryp = htab_find_slot (got_entries, entry, INSERT);
+ if (! *entryp)
+ *entryp = entry;
+ /* Abort the traversal, since the whole table may have
+ moved, and leave it up to the parent to restart the
+ process. */
+ *(htab_t *)p = NULL;
+ return 0;
+ }
+ /* We might want to decrement the global_gotno count, but it's
+ either too early or too late for that at this point. */
+ }
+
+ return 1;
+}
+
+/* Turn indirect got entries in a got_entries table into their final locations. */
+static void
+score_elf_resolve_final_got_entries (struct score_got_info *g)
+{
+ htab_t got_entries;
+
+ do
+ {
+ got_entries = g->got_entries;
+
+ htab_traverse (got_entries,
+ score_elf_resolve_final_got_entry,
+ &got_entries);
+ }
+ while (got_entries == NULL);
+}
+
+/* Add INCREMENT to the reloc (of type HOWTO) at ADDRESS. for -r */
+static void
+score_elf_add_to_rel (bfd *abfd,
+ bfd_byte *address,
+ reloc_howto_type *howto,
+ bfd_signed_vma increment)
+{
+ bfd_signed_vma addend;
+ bfd_vma contents;
+ unsigned long offset;
+ unsigned long r_type = howto->type;
+ unsigned long hi16_addend, hi16_offset, hi16_value, uvalue;
+
+ contents = score_bfd_get_32 (abfd, address);
+ /* Get the (signed) value from the instruction. */
+ addend = contents & howto->src_mask;
+ if (addend & ((howto->src_mask + 1) >> 1))
+ {
+ bfd_signed_vma mask;
+
+ mask = -1;
+ mask &= ~howto->src_mask;
+ addend |= mask;
+ }
+ /* Add in the increment, (which is a byte value). */
+ switch (r_type)
+ {
+ case R_SCORE_PC19:
+ offset =
+ (((contents & howto->src_mask) & 0x3ff0000) >> 6) | ((contents & howto->src_mask) & 0x3ff);
+ offset += increment;
+ contents =
+ (contents & ~howto->
+ src_mask) | (((offset << 6) & howto->src_mask) & 0x3ff0000) | (offset & 0x3ff);
+ score_bfd_put_32 (abfd, contents, address);
+ break;
+ case R_SCORE_HI16:
+ break;
+ case R_SCORE_LO16:
+ hi16_addend = score_bfd_get_32 (abfd, address - 4);
+ hi16_offset = ((((hi16_addend >> 16) & 0x3) << 15) | (hi16_addend & 0x7fff)) >> 1;
+ offset = ((((contents >> 16) & 0x3) << 15) | (contents & 0x7fff)) >> 1;
+ offset = (hi16_offset << 16) | (offset & 0xffff);
+ uvalue = increment + offset;
+ hi16_offset = (uvalue >> 16) << 1;
+ hi16_value = (hi16_addend & (~(howto->dst_mask)))
+ | (hi16_offset & 0x7fff) | ((hi16_offset << 1) & 0x30000);
+ score_bfd_put_32 (abfd, hi16_value, address - 4);
+ offset = (uvalue & 0xffff) << 1;
+ contents = (contents & (~(howto->dst_mask))) | (offset & 0x7fff) | ((offset << 1) & 0x30000);
+ score_bfd_put_32 (abfd, contents, address);
+ break;
+ case R_SCORE_24:
+ offset =
+ (((contents & howto->src_mask) >> 1) & 0x1ff8000) | ((contents & howto->src_mask) & 0x7fff);
+ offset += increment;
+ contents =
+ (contents & ~howto->
+ src_mask) | (((offset << 1) & howto->src_mask) & 0x3ff0000) | (offset & 0x7fff);
+ score_bfd_put_32 (abfd, contents, address);
+ break;
+
+ case R_SCORE16_11:
+
+ contents = score_bfd_get_16 (abfd, address);
+ offset = contents & howto->src_mask;
+ offset += increment;
+ contents = (contents & ~howto->src_mask) | (offset & howto->src_mask);
+ score_bfd_put_16 (abfd, contents, address);
+
+ break;
+ case R_SCORE16_PC8:
+
+ contents = score_bfd_get_16 (abfd, address);
+ offset = (contents & howto->src_mask) + ((increment >> 1) & 0x1ff);
+ contents = (contents & (~howto->src_mask)) | (offset & howto->src_mask);
+ score_bfd_put_16 (abfd, contents, address);
+
+ break;
+
+ case R_SCORE_BCMP:
+ contents = score_bfd_get_32 (abfd, address);
+ offset = (contents & howto->src_mask);
+ offset <<= howto->rightshift;
+ offset += increment;
+ offset >>= howto->rightshift;
+ contents = (contents & (~howto->src_mask)) | (offset & howto->src_mask);
+ score_bfd_put_32 (abfd, contents, address);
+ break;
+
+ case R_SCORE_IMM30:
+ contents = score_bfd_get_48 (abfd, address);
+ offset = (contents & howto->src_mask);
+ offset <<= howto->rightshift;
+ offset += increment;
+ offset >>= howto->rightshift;
+ contents = (contents & (~howto->src_mask)) | (offset & howto->src_mask);
+ score_bfd_put_48 (abfd, contents, address);
+ break;
+
+ case R_SCORE_IMM32:
+ contents = score_bfd_get_48 (abfd, address);
+ offset = (contents & howto->src_mask);
+ offset += increment;
+ contents = (contents & (~howto->src_mask)) | (offset & howto->src_mask);
+ score_bfd_put_48 (abfd, contents, address);
+ break;
+
+ default:
+ addend += increment;
+ contents = (contents & ~howto->dst_mask) | (addend & howto->dst_mask);
+ score_bfd_put_32 (abfd, contents, address);
+ break;
+ }
+}
+
+/* Perform a relocation as part of a final link. */
+static bfd_reloc_status_type
+score_elf_final_link_relocate (reloc_howto_type *howto,
+ bfd *input_bfd,
+ bfd *output_bfd,
+ asection *input_section,
+ bfd_byte *contents,
+ Elf_Internal_Rela *rel,
+ Elf_Internal_Rela *relocs,
+ bfd_vma symbol,
+ struct bfd_link_info *info,
+ const char *sym_name ATTRIBUTE_UNUSED,
+ int sym_flags ATTRIBUTE_UNUSED,
+ struct score_elf_link_hash_entry *h,
+ asection **local_sections,
+ bfd_boolean gp_disp_p)
+{
+ unsigned long r_type;
+ unsigned long r_symndx;
+ bfd_byte *hit_data = contents + rel->r_offset;
+ bfd_vma addend;
+ /* The final GP value to be used for the relocatable, executable, or
+ shared object file being produced. */
+ bfd_vma gp = MINUS_ONE;
+ /* The place (section offset or address) of the storage unit being relocated. */
+ bfd_vma rel_addr;
+ /* The offset into the global offset table at which the address of the relocation entry
+ symbol, adjusted by the addend, resides during execution. */
+ bfd_vma g = MINUS_ONE;
+ /* TRUE if the symbol referred to by this relocation is a local symbol. */
+ bfd_boolean local_p;
+ /* The eventual value we will relocate. */
+ bfd_vma value = symbol;
+ unsigned long hi16_addend, hi16_offset, hi16_value, uvalue, offset, abs_value = 0;
+
+
+ if (elf_gp (output_bfd) == 0)
+ {
+ struct bfd_link_hash_entry *bh;
+ asection *o;
+
+ bh = bfd_link_hash_lookup (info->hash, "_gp", 0, 0, 1);
+ if (bh != NULL && bh->type == bfd_link_hash_defined)
+ elf_gp (output_bfd) = (bh->u.def.value
+ + bh->u.def.section->output_section->vma
+ + bh->u.def.section->output_offset);
+ else if (info->relocatable)
+ {
+ bfd_vma lo = -1;
+
+ /* Find the GP-relative section with the lowest offset. */
+ for (o = output_bfd->sections; o != NULL; o = o->next)
+ if (o->vma < lo)
+ lo = o->vma;
+ /* And calculate GP relative to that. */
+ elf_gp (output_bfd) = lo + ELF_SCORE_GP_OFFSET (input_bfd);
+ }
+ 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. */
+ }
+ }
+
+ /* Parse the relocation. */
+ r_symndx = ELF32_R_SYM (rel->r_info);
+ r_type = ELF32_R_TYPE (rel->r_info);
+ rel_addr = (input_section->output_section->vma + input_section->output_offset + rel->r_offset);
+ local_p = score_elf_local_relocation_p (input_bfd, rel, local_sections, TRUE);
+
+ if (r_type == R_SCORE_GOT15)
+ {
+ const Elf_Internal_Rela *relend;
+ const Elf_Internal_Rela *lo16_rel;
+ const struct elf_backend_data *bed;
+ bfd_vma lo_value = 0;
+
+ bed = get_elf_backend_data (output_bfd);
+ relend = relocs + input_section->reloc_count * bed->s->int_rels_per_ext_rel;
+ lo16_rel = score_elf_next_relocation (input_bfd, R_SCORE_GOT_LO16, rel, relend);
+ if ((local_p) && (lo16_rel != NULL))
+ {
+ bfd_vma tmp = 0;
+ tmp = score_bfd_get_32 (input_bfd, contents + lo16_rel->r_offset);
+ lo_value = (((tmp >> 16) & 0x3) << 14) | ((tmp & 0x7fff) >> 1);
+ }
+ addend = lo_value;
+ }
+ /* For score3 R_SCORE_ABS32. */
+ else if (r_type == R_SCORE_ABS32 || r_type == R_SCORE_REL32)
+ {
+ addend = (bfd_get_32 (input_bfd, hit_data) >> howto->bitpos) & howto->src_mask;
+ }
+ else
+ {
+ addend = (score_bfd_get_32 (input_bfd, hit_data) >> howto->bitpos) & howto->src_mask;
+ }
+
+ /* If we haven't already determined the GOT offset, or the GP value,
+ and we're going to need it, get it now. */
+ switch (r_type)
+ {
+ case R_SCORE_CALL15:
+ case R_SCORE_GOT15:
+ if (!local_p)
+ {
+ g = score_elf_global_got_index (elf_hash_table (info)->dynobj,
+ (struct elf_link_hash_entry *) h);
+ if ((! elf_hash_table (info)->dynamic_sections_created
+ || (info->shared
+ && (info->symbolic || h->root.dynindx == -1)
+ && h->root.def_regular)))
+ {
+ /* This is a static link or a -Bsymbolic link. The
+ symbol is defined locally, or was forced to be local.
+ We must initialize this entry in the GOT. */
+ bfd *tmpbfd = elf_hash_table (info)->dynobj;
+ asection *sgot = score_elf_got_section (tmpbfd, FALSE);
+ score_bfd_put_32 (tmpbfd, value, sgot->contents + g);
+ }
+ }
+ else if (r_type == R_SCORE_GOT15 || r_type == R_SCORE_CALL15)
+ {
+ /* There's no need to create a local GOT entry here; the
+ calculation for a local GOT15 entry does not involve G. */
+ ;
+ }
+ else
+ {
+ g = score_elf_local_got_index (output_bfd, input_bfd, info,
+ symbol + addend, r_symndx, h, r_type);
+ if (g == MINUS_ONE)
+ return bfd_reloc_outofrange;
+ }
+
+ /* Convert GOT indices to actual offsets. */
+ g = score_elf_got_offset_from_index (elf_hash_table (info)->dynobj,
+ output_bfd, input_bfd, g);
+ break;
+
+ case R_SCORE_HI16:
+ case R_SCORE_LO16:
+ case R_SCORE_GPREL32:
+ gp = _bfd_get_gp_value (output_bfd);
+ break;
+
+ case R_SCORE_GP15:
+ gp = _bfd_get_gp_value (output_bfd);
+
+ default:
+ break;
+ }
+
+ switch (r_type)
+ {
+ case R_SCORE_NONE:
+ return bfd_reloc_ok;
+
+ case R_SCORE_ABS32:
+ case R_SCORE_REL32:
+ if ((info->shared
+ || (elf_hash_table (info)->dynamic_sections_created
+ && h != NULL
+ && h->root.def_dynamic
+ && !h->root.def_regular))
+ && r_symndx != STN_UNDEF
+ && (input_section->flags & SEC_ALLOC) != 0)
+ {
+ /* If we're creating a shared library, or this relocation is against a symbol
+ in a shared library, then we can't know where the symbol will end up.
+ So, we create a relocation record in the output, and leave the job up
+ to the dynamic linker. */
+ value = addend;
+ if (!score_elf_create_dynamic_relocation (output_bfd, info, rel, h,
+ symbol, &value,
+ input_section))
+ return bfd_reloc_undefined;
+ }
+ else if (r_symndx == STN_UNDEF)
+ /* r_symndx will be STN_UNDEF (zero) only for relocs against symbols
+ from removed linkonce sections, or sections discarded by
+ a linker script. */
+ value = 0;
+ else
+ {
+ if (r_type != R_SCORE_REL32)
+ value = symbol + addend;
+ else
+ value = addend;
+ }
+ value &= howto->dst_mask;
+ bfd_put_32 (input_bfd, value, hit_data);
+ return bfd_reloc_ok;
+
+ case R_SCORE_ABS16:
+ value += addend;
+ if ((long)value > 0x7fff || (long)value < -0x8000)
+ return bfd_reloc_overflow;
+ score_bfd_put_16 (input_bfd, value, hit_data);
+ return bfd_reloc_ok;
+
+ case R_SCORE_24:
+ addend = score_bfd_get_32 (input_bfd, hit_data);
+ offset = (((addend & howto->src_mask) >> 1) & 0x1ff8000) | ((addend & howto->src_mask) & 0x7fff);
+ if ((offset & 0x1000000) != 0)
+ offset |= 0xfe000000;
+ value += offset;
+ abs_value = abs (value - rel_addr);
+ if ((abs_value & 0xfe000000) != 0)
+ return bfd_reloc_overflow;
+ addend = (addend & ~howto->src_mask)
+ | (((value << 1) & howto->src_mask) & 0x3ff0000) | (value & 0x7fff);
+ score_bfd_put_32 (input_bfd, addend, hit_data);
+ return bfd_reloc_ok;
+
+ /* signed imm32. */
+ case R_SCORE_IMM30:
+ {
+ int not_word_align_p = 0;
+ bfd_vma imm_offset = 0;
+ addend = score_bfd_get_48 (input_bfd, hit_data);
+ imm_offset = ((addend >> 7) & 0xff)
+ | (((addend >> 16) & 0x7fff) << 8)
+ | (((addend >> 32) & 0x7f) << 23);
+ imm_offset <<= howto->rightshift;
+ value += imm_offset;
+ value &= 0xffffffff;
+
+ /* Check lw48/sw48 rd, value/label word align. */
+ if ((value & 0x3) != 0)
+ not_word_align_p = 1;
+
+ value >>= howto->rightshift;
+ addend = (addend & ~howto->src_mask)
+ | (((value & 0xff) >> 0) << 7)
+ | (((value & 0x7fff00) >> 8) << 16)
+ | (((value & 0x3f800000) >> 23) << 32);
+ score_bfd_put_48 (input_bfd, addend, hit_data);
+ if (not_word_align_p)
+ return bfd_reloc_other;
+ else
+ return bfd_reloc_ok;
+ }
+
+ case R_SCORE_IMM32:
+ {
+ bfd_vma imm_offset = 0;
+ addend = score_bfd_get_48 (input_bfd, hit_data);
+ imm_offset = ((addend >> 5) & 0x3ff)
+ | (((addend >> 16) & 0x7fff) << 10)
+ | (((addend >> 32) & 0x7f) << 25);
+ value += imm_offset;
+ value &= 0xffffffff;
+ addend = (addend & ~howto->src_mask)
+ | ((value & 0x3ff) << 5)
+ | (((value >> 10) & 0x7fff) << 16)
+ | (((value >> 25) & 0x7f) << 32);
+ score_bfd_put_48 (input_bfd, addend, hit_data);
+ return bfd_reloc_ok;
+ }
+
+ case R_SCORE_PC19:
+ addend = score_bfd_get_32 (input_bfd, hit_data);
+ offset = (((addend & howto->src_mask) & 0x3ff0000) >> 6) | ((addend & howto->src_mask) & 0x3ff);
+ if ((offset & 0x80000) != 0)
+ offset |= 0xfff00000;
+ abs_value = value = value - rel_addr + offset;
+ /* exceed 20 bit : overflow. */
+ if ((abs_value & 0x80000000) == 0x80000000)
+ abs_value = 0xffffffff - value + 1;
+ if ((abs_value & 0xfff80000) != 0)
+ return bfd_reloc_overflow;
+ addend = (addend & ~howto->src_mask)
+ | (((value << 6) & howto->src_mask) & 0x3ff0000) | (value & 0x3ff);
+ score_bfd_put_32 (input_bfd, addend, hit_data);
+ return bfd_reloc_ok;
+
+ case R_SCORE16_11:
+ addend = score_bfd_get_16 (input_bfd, hit_data);
+ offset = addend & howto->src_mask;
+ if ((offset & 0x800) != 0) /* Offset is negative. */
+ offset |= 0xfffff000;
+ value += offset;
+ abs_value = abs (value - rel_addr);
+ if ((abs_value & 0xfffff000) != 0)
+ return bfd_reloc_overflow;
+ addend = (addend & ~howto->src_mask) | (value & howto->src_mask);
+ score_bfd_put_16 (input_bfd, addend, hit_data);
+ return bfd_reloc_ok;
+
+ case R_SCORE16_PC8:
+ addend = score_bfd_get_16 (input_bfd, hit_data);
+ offset = (addend & howto->src_mask) << 1;
+ if ((offset & 0x200) != 0) /* Offset is negative. */
+ offset |= 0xfffffe00;
+ abs_value = value = value - rel_addr + offset;
+ /* Sign bit + exceed 9 bit. */
+ if (((value & 0xfffffe00) != 0) && ((value & 0xfffffe00) != 0xfffffe00))
+ return bfd_reloc_overflow;
+ value >>= 1;
+ addend = (addend & ~howto->src_mask) | (value & howto->src_mask);
+ score_bfd_put_16 (input_bfd, addend, hit_data);
+ return bfd_reloc_ok;
+
+ case R_SCORE_BCMP:
+ addend = score_bfd_get_32 (input_bfd, hit_data);
+ offset = (addend & howto->src_mask) << howto->rightshift;
+ if ((offset & 0x200) != 0) /* Offset is negative. */
+ offset |= 0xfffffe00;
+ value = value - rel_addr + offset;
+ /* Sign bit + exceed 9 bit. */
+ if (((value & 0xfffffe00) != 0) && ((value & 0xfffffe00) != 0xfffffe00))
+ return bfd_reloc_overflow;
+ value >>= howto->rightshift;
+ addend = (addend & ~howto->src_mask)
+ | (value & 0x1)
+ | (((value >> 1) & 0x7) << 7)
+ | (((value >> 4) & 0x1f) << 21);
+ score_bfd_put_32 (input_bfd, addend, hit_data);
+ return bfd_reloc_ok;
+
+ case R_SCORE_HI16:
+ return bfd_reloc_ok;
+
+ case R_SCORE_LO16:
+ hi16_addend = score_bfd_get_32 (input_bfd, hit_data - 4);
+ hi16_offset = ((((hi16_addend >> 16) & 0x3) << 15) | (hi16_addend & 0x7fff)) >> 1;
+ addend = score_bfd_get_32 (input_bfd, hit_data);
+ offset = ((((addend >> 16) & 0x3) << 15) | (addend & 0x7fff)) >> 1;
+ offset = (hi16_offset << 16) | (offset & 0xffff);
+
+ if (!gp_disp_p)
+ uvalue = value + offset;
+ else
+ uvalue = offset + gp - rel_addr + 4;
+
+ hi16_offset = (uvalue >> 16) << 1;
+ hi16_value = (hi16_addend & (~(howto->dst_mask)))
+ | (hi16_offset & 0x7fff) | ((hi16_offset << 1) & 0x30000);
+ score_bfd_put_32 (input_bfd, hi16_value, hit_data - 4);
+ offset = (uvalue & 0xffff) << 1;
+ value = (addend & (~(howto->dst_mask))) | (offset & 0x7fff) | ((offset << 1) & 0x30000);
+ score_bfd_put_32 (input_bfd, value, hit_data);
+ return bfd_reloc_ok;
+
+ case R_SCORE_GP15:
+ addend = score_bfd_get_32 (input_bfd, hit_data);
+ offset = addend & 0x7fff;
+ if ((offset & 0x4000) == 0x4000)
+ offset |= 0xffffc000;
+ value = value + offset - gp;
+ if (((value & 0xffffc000) != 0) && ((value & 0xffffc000) != 0xffffc000))
+ return bfd_reloc_overflow;
+ value = (addend & ~howto->src_mask) | (value & howto->src_mask);
+ score_bfd_put_32 (input_bfd, value, hit_data);
+ return bfd_reloc_ok;
+
+ case R_SCORE_GOT15:
+ case R_SCORE_CALL15:
+ if (local_p)
+ {
+ bfd_boolean forced;
+
+ /* The special case is when the symbol is forced to be local. We need the
+ full address in the GOT since no R_SCORE_GOT_LO16 relocation follows. */
+ forced = ! score_elf_local_relocation_p (input_bfd, rel,
+ local_sections, FALSE);
+ value = score_elf_got16_entry (output_bfd, input_bfd, info,
+ symbol + addend, forced);
+ if (value == MINUS_ONE)
+ return bfd_reloc_outofrange;
+ value = score_elf_got_offset_from_index (elf_hash_table (info)->dynobj,
+ output_bfd, input_bfd, value);
+ }
+ else
+ {
+ value = g;
+ }
+
+ if ((long) value > 0x3fff || (long) value < -0x4000)
+ return bfd_reloc_overflow;
+
+ addend = score_bfd_get_32 (input_bfd, hit_data);
+ value = (addend & ~howto->dst_mask) | (value & howto->dst_mask);
+ score_bfd_put_32 (input_bfd, value, hit_data);
+ return bfd_reloc_ok;
+
+ case R_SCORE_GPREL32:
+ value = (addend + symbol - gp);
+ value &= howto->dst_mask;
+ score_bfd_put_32 (input_bfd, value, hit_data);
+ return bfd_reloc_ok;
+
+ case R_SCORE_GOT_LO16:
+ addend = score_bfd_get_32 (input_bfd, hit_data);
+ value = (((addend >> 16) & 0x3) << 14) | ((addend & 0x7fff) >> 1);
+ value += symbol;
+ value = (addend & (~(howto->dst_mask))) | ((value & 0x3fff) << 1)
+ | (((value >> 14) & 0x3) << 16);
+
+ score_bfd_put_32 (input_bfd, value, hit_data);
+ return bfd_reloc_ok;
+
+ case R_SCORE_DUMMY_HI16:
+ return bfd_reloc_ok;
+
+ case R_SCORE_GNU_VTINHERIT:
+ case R_SCORE_GNU_VTENTRY:
+ /* We don't do anything with these at present. */
+ return bfd_reloc_continue;
+
+ default:
+ return bfd_reloc_notsupported;
+ }
+}
+
+/* Score backend functions. */
+static void
+s3_bfd_score_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED,
+ arelent *bfd_reloc,
+ Elf_Internal_Rela *elf_reloc)
+{
+ unsigned int r_type;
+
+ r_type = ELF32_R_TYPE (elf_reloc->r_info);
+ if (r_type >= ARRAY_SIZE (elf32_score_howto_table))
+ bfd_reloc->howto = NULL;
+ else
+ bfd_reloc->howto = &elf32_score_howto_table[r_type];
+}
+
+/* Relocate an score ELF section. */
+static bfd_boolean
+s3_bfd_score_elf_relocate_section (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;
+ const char *name;
+ unsigned long offset;
+ unsigned long hi16_addend, hi16_offset, hi16_value, uvalue;
+ size_t extsymoff;
+ bfd_boolean gp_disp_p = FALSE;
+
+ /* Sort dynsym. */
+ if (elf_hash_table (info)->dynamic_sections_created)
+ {
+ bfd_size_type dynsecsymcount = 0;
+ if (info->shared)
+ {
+ asection * p;
+ const struct elf_backend_data *bed = get_elf_backend_data (output_bfd);
+
+ for (p = output_bfd->sections; p ; p = p->next)
+ if ((p->flags & SEC_EXCLUDE) == 0
+ && (p->flags & SEC_ALLOC) != 0
+ && !(*bed->elf_backend_omit_section_dynsym) (output_bfd, info, p))
+ ++ dynsecsymcount;
+ }
+
+ if (!score_elf_sort_hash_table (info, dynsecsymcount + 1))
+ return FALSE;
+ }
+
+ symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
+ extsymoff = (elf_bad_symtab (input_bfd)) ? 0 : symtab_hdr->sh_info;
+ 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 score_elf_link_hash_entry *h;
+ bfd_vma relocation = 0;
+ bfd_reloc_status_type r;
+ arelent bfd_reloc;
+
+ r_symndx = ELF32_R_SYM (rel->r_info);
+ r_type = ELF32_R_TYPE (rel->r_info);
+
+ s3_bfd_score_info_to_howto (input_bfd, &bfd_reloc, (Elf_Internal_Rela *) rel);
+ howto = bfd_reloc.howto;
+
+ h = NULL;
+ sym = NULL;
+ sec = NULL;
+
+ if (r_symndx < extsymoff)
+ {
+ sym = local_syms + r_symndx;
+ sec = local_sections[r_symndx];
+ relocation = (sec->output_section->vma
+ + sec->output_offset
+ + sym->st_value);
+ name = bfd_elf_sym_name (input_bfd, symtab_hdr, sym, sec);
+
+ if (!info->relocatable
+ && (sec->flags & SEC_MERGE)
+ && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
+ {
+ asection *msec;
+ bfd_vma addend, value;
+
+ switch (r_type)
+ {
+ case R_SCORE_HI16:
+ break;
+ case R_SCORE_LO16:
+ hi16_addend = score_bfd_get_32 (input_bfd, contents + rel->r_offset - 4);
+ hi16_offset = ((((hi16_addend >> 16) & 0x3) << 15) | (hi16_addend & 0x7fff)) >> 1;
+ value = score_bfd_get_32 (input_bfd, contents + rel->r_offset);
+ offset = ((((value >> 16) & 0x3) << 15) | (value & 0x7fff)) >> 1;
+ addend = (hi16_offset << 16) | (offset & 0xffff);
+ msec = sec;
+ addend = _bfd_elf_rel_local_sym (output_bfd, sym, &msec, addend);
+ addend -= relocation;
+ addend += msec->output_section->vma + msec->output_offset;
+ uvalue = addend;
+ hi16_offset = (uvalue >> 16) << 1;
+ hi16_value = (hi16_addend & (~(howto->dst_mask)))
+ | (hi16_offset & 0x7fff) | ((hi16_offset << 1) & 0x30000);
+ score_bfd_put_32 (input_bfd, hi16_value, contents + rel->r_offset - 4);
+ offset = (uvalue & 0xffff) << 1;
+ value = (value & (~(howto->dst_mask)))
+ | (offset & 0x7fff) | ((offset << 1) & 0x30000);
+ score_bfd_put_32 (input_bfd, value, contents + rel->r_offset);
+ break;
+
+ case R_SCORE_IMM32:
+ {
+ value = score_bfd_get_48 (input_bfd, contents + rel->r_offset);
+ addend = ((value >> 5) & 0x3ff)
+ | (((value >> 16) & 0x7fff) << 10)
+ | (((value >> 32) & 0x7f) << 25);
+ msec = sec;
+ addend = _bfd_elf_rel_local_sym (output_bfd, sym, &msec, addend);
+ addend -= relocation;
+ addend += msec->output_section->vma + msec->output_offset;
+ addend &= 0xffffffff;
+ value = (value & ~howto->src_mask)
+ | ((addend & 0x3ff) << 5)
+ | (((addend >> 10) & 0x7fff) << 16)
+ | (((addend >> 25) & 0x7f) << 32);
+ score_bfd_put_48 (input_bfd, value, contents + rel->r_offset);
+ break;
+ }
+
+ case R_SCORE_IMM30:
+ {
+ int not_word_align_p = 0;
+ value = score_bfd_get_48 (input_bfd, contents + rel->r_offset);
+ addend = ((value >> 7) & 0xff)
+ | (((value >> 16) & 0x7fff) << 8)
+ | (((value >> 32) & 0x7f) << 23);
+ addend <<= howto->rightshift;
+ msec = sec;
+ addend = _bfd_elf_rel_local_sym (output_bfd, sym, &msec, addend);
+ addend -= relocation;
+ addend += msec->output_section->vma + msec->output_offset;
+ addend &= 0xffffffff;
+
+ /* Check lw48/sw48 rd, value/label word align. */
+ if ((addend & 0x3) != 0)
+ not_word_align_p = 1;
+
+ addend >>= howto->rightshift;
+ value = (value & ~howto->src_mask)
+ | (((addend & 0xff) >> 0) << 7)
+ | (((addend & 0x7fff00) >> 8) << 16)
+ | (((addend & 0x3f800000) >> 23) << 32);
+ score_bfd_put_48 (input_bfd, value, contents + rel->r_offset);
+
+ if (not_word_align_p)
+ return bfd_reloc_other;
+ else
+ break;
+ }
+
+ case R_SCORE_GOT_LO16:
+ value = score_bfd_get_32 (input_bfd, contents + rel->r_offset);
+ addend = (((value >> 16) & 0x3) << 14) | ((value & 0x7fff) >> 1);
+ msec = sec;
+ addend = _bfd_elf_rel_local_sym (output_bfd, sym, &msec, addend) - relocation;
+ addend += msec->output_section->vma + msec->output_offset;
+ value = (value & (~(howto->dst_mask))) | ((addend & 0x3fff) << 1)
+ | (((addend >> 14) & 0x3) << 16);
+
+ score_bfd_put_32 (input_bfd, value, contents + rel->r_offset);
+ break;
+
+ case R_SCORE_ABS32:
+ case R_SCORE_REL32:
+ value = bfd_get_32 (input_bfd, contents + rel->r_offset);
+ /* Get the (signed) value from the instruction. */
+ addend = value & howto->src_mask;
+ if (addend & ((howto->src_mask + 1) >> 1))
+ {
+ bfd_signed_vma mask;
+
+ mask = -1;
+ mask &= ~howto->src_mask;
+ addend |= mask;
+ }
+ msec = sec;
+ addend = _bfd_elf_rel_local_sym (output_bfd, sym, &msec, addend) - relocation;
+ addend += msec->output_section->vma + msec->output_offset;
+ value = (value & ~howto->dst_mask) | (addend & howto->dst_mask);
+ bfd_put_32 (input_bfd, value, contents + rel->r_offset);
+ break;
+
+ default:
+ value = score_bfd_get_32 (input_bfd, contents + rel->r_offset);
+ /* Get the (signed) value from the instruction. */
+ addend = value & howto->src_mask;
+ if (addend & ((howto->src_mask + 1) >> 1))
+ {
+ bfd_signed_vma mask;
+
+ mask = -1;
+ mask &= ~howto->src_mask;
+ addend |= mask;
+ }
+ msec = sec;
+ addend = _bfd_elf_rel_local_sym (output_bfd, sym, &msec, addend) - relocation;
+ addend += msec->output_section->vma + msec->output_offset;
+ value = (value & ~howto->dst_mask) | (addend & howto->dst_mask);
+ score_bfd_put_32 (input_bfd, value, contents + rel->r_offset);
+ break;
+ }
+ }
+ }
+ else
+ {
+ /* For global symbols we look up the symbol in the hash-table. */
+ h = ((struct score_elf_link_hash_entry *)
+ elf_sym_hashes (input_bfd) [r_symndx - extsymoff]);
+
+ if (info->wrap_hash != NULL
+ && (input_section->flags & SEC_DEBUGGING) != 0)
+ h = ((struct score_elf_link_hash_entry *)
+ unwrap_hash_lookup (info, input_bfd, &h->root.root));
+
+ /* Find the real hash-table entry for this symbol. */
+ while (h->root.root.type == bfd_link_hash_indirect
+ || h->root.root.type == bfd_link_hash_warning)
+ h = (struct score_elf_link_hash_entry *) h->root.root.u.i.link;
+
+ /* Record the name of this symbol, for our caller. */
+ name = h->root.root.root.string;
+
+ /* See if this is the special GP_DISP_LABEL symbol. Note that such a
+ symbol must always be a global symbol. */
+ if (strcmp (name, GP_DISP_LABEL) == 0)
+ {
+ /* Relocations against GP_DISP_LABEL are permitted only with
+ R_SCORE_HI16 and R_SCORE_LO16 relocations. */
+ if (r_type != R_SCORE_HI16 && r_type != R_SCORE_LO16)
+ return bfd_reloc_notsupported;
+
+ gp_disp_p = TRUE;
+ }
+
+ /* If this symbol is defined, calculate its address. Note that
+ GP_DISP_LABEL is a magic symbol, always implicitly defined by the
+ linker, so it's inappropriate to check to see whether or not
+ its defined. */
+ else if ((h->root.root.type == bfd_link_hash_defined
+ || h->root.root.type == bfd_link_hash_defweak)
+ && h->root.root.u.def.section)
+ {
+ sec = h->root.root.u.def.section;
+ if (sec->output_section)
+ relocation = (h->root.root.u.def.value
+ + sec->output_section->vma
+ + sec->output_offset);
+ else
+ {
+ relocation = h->root.root.u.def.value;
+ }
+ }
+ else if (h->root.root.type == bfd_link_hash_undefweak)
+ /* We allow relocations against undefined weak symbols, giving
+ it the value zero, so that you can undefined weak functions
+ and check to see if they exist by looking at their addresses. */
+ relocation = 0;
+ else if (info->unresolved_syms_in_objects == RM_IGNORE
+ && ELF_ST_VISIBILITY (h->root.other) == STV_DEFAULT)
+ relocation = 0;
+ else if (strcmp (name, "_DYNAMIC_LINK") == 0)
+ {
+ /* If this is a dynamic link, we should have created a _DYNAMIC_LINK symbol
+ in s3_bfd_score_elf_create_dynamic_sections. Otherwise, we should define
+ the symbol with a value of 0. */
+ BFD_ASSERT (! info->shared);
+ BFD_ASSERT (bfd_get_section_by_name (output_bfd, ".dynamic") == NULL);
+ relocation = 0;
+ }
+ else if (!info->relocatable)
+ {
+ if (! ((*info->callbacks->undefined_symbol)
+ (info, h->root.root.root.string, input_bfd,
+ input_section, rel->r_offset,
+ (info->unresolved_syms_in_objects == RM_GENERATE_ERROR)
+ || ELF_ST_VISIBILITY (h->root.other))))
+ return bfd_reloc_undefined;
+ relocation = 0;
+ }
+ }
+
+ if (sec != NULL && discarded_section (sec))
+ RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+ rel, 1, relend, howto, 0, contents);
+
+ if (info->relocatable)
+ {
+ /* This is a relocatable 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];
+ score_elf_add_to_rel (input_bfd, contents + rel->r_offset,
+ howto, (bfd_signed_vma) (sec->output_offset + sym->st_value));
+ }
+ }
+ continue;
+ }
+
+ /* This is a final link. */
+ r = score_elf_final_link_relocate (howto, input_bfd, output_bfd,
+ input_section, contents, rel, relocs,
+ relocation, info, name,
+ (h ? ELF_ST_TYPE ((unsigned int)h->root.root.type) :
+ ELF_ST_TYPE ((unsigned int)sym->st_info)), h, local_sections,
+ gp_disp_p);
+
+ if (r != bfd_reloc_ok)
+ {
+ const char *msg = (const char *)0;
+
+ switch (r)
+ {
+ case bfd_reloc_overflow:
+ /* If the overflowing reloc was to an undefined symbol,
+ we have already printed one error message and there
+ is no point complaining again. */
+ if (((!h) || (h->root.root.type != bfd_link_hash_undefined))
+ && (!((*info->callbacks->reloc_overflow)
+ (info, NULL, 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, TRUE)))
+ 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;
+
+ /* Use bfd_reloc_other to check lw48, sw48 word align. */
+ case bfd_reloc_other:
+ msg = _("address not word align");
+ 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;
+}
+
+/* Look through the relocs for a section during the first phase, and
+ allocate space in the global offset table. */
+static bfd_boolean
+s3_bfd_score_elf_check_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 score_got_info *g;
+ size_t extsymoff;
+ const Elf_Internal_Rela *rel;
+ const Elf_Internal_Rela *rel_end;
+ asection *sgot;
+ asection *sreloc;
+ const struct elf_backend_data *bed;
+
+ if (info->relocatable)
+ 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;
+
+ name = bfd_get_section_name (abfd, sec);
+
+ if (dynobj == NULL)
+ {
+ sgot = NULL;
+ g = NULL;
+ }
+ else
+ {
+ sgot = score_elf_got_section (dynobj, FALSE);
+ if (sgot == NULL)
+ g = NULL;
+ else
+ {
+ BFD_ASSERT (score_elf_section_data (sgot) != NULL);
+ g = score_elf_section_data (sgot)->u.got_info;
+ BFD_ASSERT (g != NULL);
+ }
+ }
+
+ sreloc = NULL;
+ bed = get_elf_backend_data (abfd);
+ rel_end = relocs + sec->reloc_count * bed->s->int_rels_per_ext_rel;
+ for (rel = relocs; rel < rel_end; ++rel)
+ {
+ unsigned long r_symndx;
+ unsigned int r_type;
+ struct elf_link_hash_entry *h;
+
+ r_symndx = ELF32_R_SYM (rel->r_info);
+ r_type = ELF32_R_TYPE (rel->r_info);
+
+ if (r_symndx < extsymoff)
+ {
+ h = NULL;
+ }
+ else if (r_symndx >= extsymoff + NUM_SHDR_ENTRIES (symtab_hdr))
+ {
+ (*_bfd_error_handler) (_("%s: Malformed reloc detected for section %s"), abfd, name);
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+ 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;
+
+ /* PR15323, ref flags aren't set for references in the
+ same object. */
+ h->root.non_ir_ref = 1;
+ }
+ }
+
+ /* Some relocs require a global offset table. */
+ if (dynobj == NULL || sgot == NULL)
+ {
+ switch (r_type)
+ {
+ case R_SCORE_GOT15:
+ case R_SCORE_CALL15:
+ if (dynobj == NULL)
+ elf_hash_table (info)->dynobj = dynobj = abfd;
+ if (!score_elf_create_got_section (dynobj, info, FALSE))
+ return FALSE;
+ g = score_elf_got_info (dynobj, &sgot);
+ break;
+ case R_SCORE_ABS32:
+ case R_SCORE_REL32:
+ if (dynobj == NULL && (info->shared || h != NULL) && (sec->flags & SEC_ALLOC) != 0)
+ elf_hash_table (info)->dynobj = dynobj = abfd;
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (!h && (r_type == R_SCORE_GOT_LO16))
+ {
+ if (! score_elf_record_local_got_symbol (abfd, r_symndx, rel->r_addend, g))
+ return FALSE;
+ }
+
+ switch (r_type)
+ {
+ case R_SCORE_CALL15:
+ if (h == NULL)
+ {
+ (*_bfd_error_handler)
+ (_("%B: CALL15 reloc at 0x%lx not against global symbol"),
+ abfd, (unsigned long) rel->r_offset);
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+ else
+ {
+ /* This symbol requires a global offset table entry. */
+ if (! score_elf_record_global_got_symbol (h, abfd, info, g))
+ return FALSE;
+
+ /* We need a stub, not a plt entry for the undefined function. But we record
+ it as if it needs plt. See _bfd_elf_adjust_dynamic_symbol. */
+ h->needs_plt = 1;
+ h->type = STT_FUNC;
+ }
+ break;
+ case R_SCORE_GOT15:
+ if (h && ! score_elf_record_global_got_symbol (h, abfd, info, g))
+ return FALSE;
+ break;
+ case R_SCORE_ABS32:
+ case R_SCORE_REL32:
+ if ((info->shared || h != NULL) && (sec->flags & SEC_ALLOC) != 0)
+ {
+ if (sreloc == NULL)
+ {
+ sreloc = score_elf_rel_dyn_section (dynobj, TRUE);
+ if (sreloc == NULL)
+ return FALSE;
+ }
+#define SCORE_READONLY_SECTION (SEC_ALLOC | SEC_LOAD | SEC_READONLY)
+ if (info->shared)
+ {
+ /* When creating a shared object, we must copy these reloc types into
+ the output file as R_SCORE_REL32 relocs. We make room for this reloc
+ in the .rel.dyn reloc section. */
+ score_elf_allocate_dynamic_relocations (dynobj, 1);
+ if ((sec->flags & SCORE_READONLY_SECTION)
+ == SCORE_READONLY_SECTION)
+ /* We tell the dynamic linker that there are
+ relocations against the text segment. */
+ info->flags |= DF_TEXTREL;
+ }
+ else
+ {
+ struct score_elf_link_hash_entry *hscore;
+
+ /* We only need to copy this reloc if the symbol is
+ defined in a dynamic object. */
+ hscore = (struct score_elf_link_hash_entry *)h;
+ ++hscore->possibly_dynamic_relocs;
+ if ((sec->flags & SCORE_READONLY_SECTION)
+ == SCORE_READONLY_SECTION)
+ /* We need it to tell the dynamic linker if there
+ are relocations against the text segment. */
+ hscore->readonly_reloc = TRUE;
+ }
+
+ /* Even though we don't directly need a GOT entry for this symbol,
+ a symbol must have a dynamic symbol table index greater that
+ DT_SCORE_GOTSYM if there are dynamic relocations against it. */
+ if (h != NULL)
+ {
+ if (dynobj == NULL)
+ elf_hash_table (info)->dynobj = dynobj = abfd;
+ if (! score_elf_create_got_section (dynobj, info, TRUE))
+ return FALSE;
+ g = score_elf_got_info (dynobj, &sgot);
+ if (! score_elf_record_global_got_symbol (h, abfd, info, g))
+ return FALSE;
+ }
+ }
+ break;
+
+ /* This relocation describes the C++ object vtable hierarchy.
+ Reconstruct it for later use during GC. */
+ case R_SCORE_GNU_VTINHERIT:
+ if (!bfd_elf_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_SCORE_GNU_VTENTRY:
+ if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_offset))
+ return FALSE;
+ break;
+ default:
+ break;
+ }
+
+ /* We must not create a stub for a symbol that has relocations
+ related to taking the function's address. */
+ switch (r_type)
+ {
+ default:
+ if (h != NULL)
+ {
+ struct score_elf_link_hash_entry *sh;
+
+ sh = (struct score_elf_link_hash_entry *) h;
+ sh->no_fn_stub = TRUE;
+ }
+ break;
+ case R_SCORE_CALL15:
+ break;
+ }
+ }
+
+ return TRUE;
+}
+
+static bfd_boolean
+s3_bfd_score_elf_add_symbol_hook (bfd *abfd,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ Elf_Internal_Sym *sym,
+ const char **namep ATTRIBUTE_UNUSED,
+ flagword *flagsp ATTRIBUTE_UNUSED,
+ asection **secp,
+ bfd_vma *valp)
+{
+ switch (sym->st_shndx)
+ {
+ case SHN_COMMON:
+ if (sym->st_size > elf_gp_size (abfd))
+ break;
+ /* Fall through. */
+ case SHN_SCORE_SCOMMON:
+ *secp = bfd_make_section_old_way (abfd, ".scommon");
+ (*secp)->flags |= SEC_IS_COMMON;
+ *valp = sym->st_size;
+ break;
+ }
+
+ return TRUE;
+}
+
+static void
+s3_bfd_score_elf_symbol_processing (bfd *abfd, asymbol *asym)
+{
+ elf_symbol_type *elfsym;
+
+ elfsym = (elf_symbol_type *) asym;
+ switch (elfsym->internal_elf_sym.st_shndx)
+ {
+ case SHN_COMMON:
+ if (asym->value > elf_gp_size (abfd))
+ break;
+ /* Fall through. */
+ case SHN_SCORE_SCOMMON:
+ if (score_elf_scom_section.name == NULL)
+ {
+ /* Initialize the small common section. */
+ score_elf_scom_section.name = ".scommon";
+ score_elf_scom_section.flags = SEC_IS_COMMON;
+ score_elf_scom_section.output_section = &score_elf_scom_section;
+ score_elf_scom_section.symbol = &score_elf_scom_symbol;
+ score_elf_scom_section.symbol_ptr_ptr = &score_elf_scom_symbol_ptr;
+ score_elf_scom_symbol.name = ".scommon";
+ score_elf_scom_symbol.flags = BSF_SECTION_SYM;
+ score_elf_scom_symbol.section = &score_elf_scom_section;
+ score_elf_scom_symbol_ptr = &score_elf_scom_symbol;
+ }
+ asym->section = &score_elf_scom_section;
+ asym->value = elfsym->internal_elf_sym.st_size;
+ break;
+ }
+}
+
+static int
+s3_bfd_score_elf_link_output_symbol_hook (struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ const char *name ATTRIBUTE_UNUSED,
+ Elf_Internal_Sym *sym,
+ asection *input_sec,
+ struct elf_link_hash_entry *h ATTRIBUTE_UNUSED)
+{
+ /* 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_SCORE_SCOMMON;
+
+ return 1;
+}
+
+static bfd_boolean
+s3_bfd_score_elf_section_from_bfd_section (bfd *abfd ATTRIBUTE_UNUSED,
+ asection *sec,
+ int *retval)
+{
+ if (strcmp (bfd_get_section_name (abfd, sec), ".scommon") == 0)
+ {
+ *retval = SHN_SCORE_SCOMMON;
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/* 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 bfd_boolean
+s3_bfd_score_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
+ struct elf_link_hash_entry *h)
+{
+ bfd *dynobj;
+ struct score_elf_link_hash_entry *hscore;
+ asection *s;
+
+ dynobj = elf_hash_table (info)->dynobj;
+
+ /* Make sure we know what is going on here. */
+ BFD_ASSERT (dynobj != NULL
+ && (h->needs_plt
+ || h->u.weakdef != NULL
+ || (h->def_dynamic && h->ref_regular && !h->def_regular)));
+
+ /* If this symbol is defined in a dynamic object, we need to copy
+ any R_SCORE_ABS32 or R_SCORE_REL32 relocs against it into the output
+ file. */
+ hscore = (struct score_elf_link_hash_entry *)h;
+ if (!info->relocatable
+ && hscore->possibly_dynamic_relocs != 0
+ && (h->root.type == bfd_link_hash_defweak || !h->def_regular))
+ {
+ score_elf_allocate_dynamic_relocations (dynobj, hscore->possibly_dynamic_relocs);
+ if (hscore->readonly_reloc)
+ /* We tell the dynamic linker that there are relocations
+ against the text segment. */
+ info->flags |= DF_TEXTREL;
+ }
+
+ /* For a function, create a stub, if allowed. */
+ if (!hscore->no_fn_stub && h->needs_plt)
+ {
+ 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->def_regular)
+ {
+ /* We need .stub section. */
+ s = bfd_get_linker_section (dynobj, SCORE_ELF_STUB_SECTION_NAME);
+ BFD_ASSERT (s != NULL);
+
+ h->root.u.def.section = s;
+ h->root.u.def.value = s->size;
+
+ /* XXX Write this stub address somewhere. */
+ h->plt.offset = s->size;
+
+ /* Make room for this stub code. */
+ s->size += SCORE_FUNCTION_STUB_SIZE;
+
+ /* The last half word of the stub will be filled with the index
+ of this symbol in .dynsym section. */
+ return TRUE;
+ }
+ }
+ else if ((h->type == STT_FUNC) && !h->needs_plt)
+ {
+ /* This will set the entry for this symbol in the GOT to 0, and
+ the dynamic linker will take care of this. */
+ h->root.u.def.value = 0;
+ 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->u.weakdef != NULL)
+ {
+ BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
+ || h->u.weakdef->root.type == bfd_link_hash_defweak);
+ h->root.u.def.section = h->u.weakdef->root.u.def.section;
+ h->root.u.def.value = h->u.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. */
+static bfd_boolean
+s3_bfd_score_elf_always_size_sections (bfd *output_bfd,
+ struct bfd_link_info *info)
+{
+ bfd *dynobj;
+ asection *s;
+ struct score_got_info *g;
+ int i;
+ bfd_size_type loadable_size = 0;
+ bfd_size_type local_gotno;
+ bfd *sub;
+
+ dynobj = elf_hash_table (info)->dynobj;
+ if (dynobj == NULL)
+ /* Relocatable links don't have it. */
+ return TRUE;
+
+ g = score_elf_got_info (dynobj, &s);
+ if (s == NULL)
+ return TRUE;
+
+ /* Calculate the total loadable size of the output. That will give us the
+ maximum number of GOT_PAGE entries required. */
+ for (sub = info->input_bfds; sub; sub = sub->link.next)
+ {
+ asection *subsection;
+
+ for (subsection = sub->sections;
+ subsection;
+ subsection = subsection->next)
+ {
+ if ((subsection->flags & SEC_ALLOC) == 0)
+ continue;
+ loadable_size += ((subsection->size + 0xf)
+ &~ (bfd_size_type) 0xf);
+ }
+ }
+
+ /* There has to be a global GOT entry for every symbol with
+ a dynamic symbol table index of DT_SCORE_GOTSYM or
+ higher. Therefore, it make sense to put those symbols
+ that need GOT entries at the end of the symbol table. We
+ do that here. */
+ if (! score_elf_sort_hash_table (info, 1))
+ return FALSE;
+
+ if (g->global_gotsym != NULL)
+ i = elf_hash_table (info)->dynsymcount - g->global_gotsym->dynindx;
+ else
+ /* If there are no global symbols, or none requiring
+ relocations, then GLOBAL_GOTSYM will be NULL. */
+ i = 0;
+
+ /* In the worst case, we'll get one stub per dynamic symbol. */
+ loadable_size += SCORE_FUNCTION_STUB_SIZE * i;
+
+ /* Assume there are two loadable segments consisting of
+ contiguous sections. Is 5 enough? */
+ local_gotno = (loadable_size >> 16) + 5;
+
+ g->local_gotno += local_gotno;
+ s->size += g->local_gotno * SCORE_ELF_GOT_SIZE (output_bfd);
+
+ g->global_gotno = i;
+ s->size += i * SCORE_ELF_GOT_SIZE (output_bfd);
+
+ score_elf_resolve_final_got_entries (g);
+
+ if (s->size > SCORE_ELF_GOT_MAX_SIZE (output_bfd))
+ {
+ /* Fixme. Error message or Warning message should be issued here. */
+ }
+
+ return TRUE;
+}
+
+/* Set the sizes of the dynamic sections. */
+static bfd_boolean
+s3_bfd_score_elf_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
+{
+ bfd *dynobj;
+ asection *s;
+ bfd_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_linker_section (dynobj, ".interp");
+ BFD_ASSERT (s != NULL);
+ s->size = strlen (ELF_DYNAMIC_INTERPRETER) + 1;
+ s->contents = (bfd_byte *) ELF_DYNAMIC_INTERPRETER;
+ }
+ }
+
+ /* 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;
+
+ 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);
+
+ if (CONST_STRNEQ (name, ".rel"))
+ {
+ if (s->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)
+ s->flags |= SEC_EXCLUDE;
+ }
+ 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 (CONST_STRNEQ (name, ".got"))
+ {
+ /* s3_bfd_score_elf_always_size_sections() has already done
+ most of the work, but some symbols may have been mapped
+ to versions that we must now resolve in the got_entries
+ hash tables. */
+ }
+ else if (strcmp (name, SCORE_ELF_STUB_SECTION_NAME) == 0)
+ {
+ /* IRIX rld assumes that the function stub isn't at the end
+ of .text section. So put a dummy. XXX */
+ s->size += SCORE_FUNCTION_STUB_SIZE;
+ }
+ else if (! CONST_STRNEQ (name, ".init"))
+ {
+ /* It's not one of our sections, so don't allocate space. */
+ continue;
+ }
+
+ /* Allocate memory for the section contents. */
+ s->contents = bfd_zalloc (dynobj, s->size);
+ if (s->contents == NULL && s->size != 0)
+ {
+ bfd_set_error (bfd_error_no_memory);
+ return FALSE;
+ }
+ }
+
+ if (elf_hash_table (info)->dynamic_sections_created)
+ {
+ /* Add some entries to the .dynamic section. We fill in the
+ values later, in s3_bfd_score_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 (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_DEBUG, 0))
+ return FALSE;
+
+ if (reltext)
+ info->flags |= DF_TEXTREL;
+
+ if ((info->flags & DF_TEXTREL) != 0)
+ {
+ if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_TEXTREL, 0))
+ return FALSE;
+ }
+
+ if (! SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_PLTGOT, 0))
+ return FALSE;
+
+ if (score_elf_rel_dyn_section (dynobj, FALSE))
+ {
+ if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_REL, 0))
+ return FALSE;
+
+ if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_RELSZ, 0))
+ return FALSE;
+
+ if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_RELENT, 0))
+ return FALSE;
+ }
+
+ if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_SCORE_BASE_ADDRESS, 0))
+ return FALSE;
+
+ if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_SCORE_LOCAL_GOTNO, 0))
+ return FALSE;
+
+ if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_SCORE_SYMTABNO, 0))
+ return FALSE;
+
+ if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_SCORE_UNREFEXTNO, 0))
+ return FALSE;
+
+ if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_SCORE_GOTSYM, 0))
+ return FALSE;
+
+ if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_SCORE_HIPAGENO, 0))
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static bfd_boolean
+s3_bfd_score_elf_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
+{
+ struct elf_link_hash_entry *h;
+ struct bfd_link_hash_entry *bh;
+ flagword flags;
+ asection *s;
+
+ flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
+ | SEC_LINKER_CREATED | SEC_READONLY);
+
+ /* ABI requests the .dynamic section to be read only. */
+ s = bfd_get_linker_section (abfd, ".dynamic");
+ if (s != NULL)
+ {
+ if (!bfd_set_section_flags (abfd, s, flags))
+ return FALSE;
+ }
+
+ /* We need to create .got section. */
+ if (!score_elf_create_got_section (abfd, info, FALSE))
+ return FALSE;
+
+ if (!score_elf_rel_dyn_section (elf_hash_table (info)->dynobj, TRUE))
+ return FALSE;
+
+ /* Create .stub section. */
+ if (bfd_get_linker_section (abfd, SCORE_ELF_STUB_SECTION_NAME) == NULL)
+ {
+ s = bfd_make_section_anyway_with_flags (abfd, SCORE_ELF_STUB_SECTION_NAME,
+ flags | SEC_CODE);
+ if (s == NULL
+ || !bfd_set_section_alignment (abfd, s, 2))
+
+ return FALSE;
+ }
+
+ if (!info->shared)
+ {
+ const char *name;
+
+ name = "_DYNAMIC_LINK";
+ bh = NULL;
+ if (!(_bfd_generic_link_add_one_symbol
+ (info, abfd, name, BSF_GLOBAL, bfd_abs_section_ptr,
+ (bfd_vma) 0, NULL, FALSE, get_elf_backend_data (abfd)->collect, &bh)))
+ return FALSE;
+
+ h = (struct elf_link_hash_entry *)bh;
+ h->non_elf = 0;
+ h->def_regular = 1;
+ h->type = STT_SECTION;
+
+ if (!bfd_elf_link_record_dynamic_symbol (info, h))
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+/* Finish up dynamic symbol handling. We set the contents of various
+ dynamic sections here. */
+static bfd_boolean
+s3_bfd_score_elf_finish_dynamic_symbol (bfd *output_bfd,
+ struct bfd_link_info *info,
+ struct elf_link_hash_entry *h,
+ Elf_Internal_Sym *sym)
+{
+ bfd *dynobj;
+ asection *sgot;
+ struct score_got_info *g;
+ const char *name;
+
+ dynobj = elf_hash_table (info)->dynobj;
+
+ if (h->plt.offset != MINUS_ONE)
+ {
+ asection *s;
+ bfd_byte stub[SCORE_FUNCTION_STUB_SIZE];
+
+ /* This symbol has a stub. Set it up. */
+ BFD_ASSERT (h->dynindx != -1);
+
+ s = bfd_get_linker_section (dynobj, SCORE_ELF_STUB_SECTION_NAME);
+ BFD_ASSERT (s != NULL);
+
+ /* FIXME: Can h->dynindex be more than 64K? */
+ if (h->dynindx & 0xffff0000)
+ return FALSE;
+
+ /* Fill the stub. */
+ score_bfd_put_32 (output_bfd, STUB_LW, stub);
+ score_bfd_put_32 (output_bfd, STUB_MOVE, stub + 4);
+ score_bfd_put_32 (output_bfd, STUB_LI16 | (h->dynindx << 1), stub + 8);
+ score_bfd_put_32 (output_bfd, STUB_BRL, stub + 12);
+
+ BFD_ASSERT (h->plt.offset <= s->size);
+ memcpy (s->contents + h->plt.offset, stub, SCORE_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. */
+ sym->st_value = (s->output_section->vma + s->output_offset + h->plt.offset);
+ }
+
+ BFD_ASSERT (h->dynindx != -1 || h->forced_local);
+
+ sgot = score_elf_got_section (dynobj, FALSE);
+ BFD_ASSERT (sgot != NULL);
+ BFD_ASSERT (score_elf_section_data (sgot) != NULL);
+ g = score_elf_section_data (sgot)->u.got_info;
+ BFD_ASSERT (g != NULL);
+
+ /* Run through the global symbol table, creating GOT entries for all
+ the symbols that need them. */
+ if (g->global_gotsym != NULL && h->dynindx >= g->global_gotsym->dynindx)
+ {
+ bfd_vma offset;
+ bfd_vma value;
+
+ value = sym->st_value;
+ offset = score_elf_global_got_index (dynobj, h);
+ score_bfd_put_32 (output_bfd, value, sgot->contents + offset);
+ }
+
+ /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute. */
+ name = h->root.root.string;
+ if (h == elf_hash_table (info)->hdynamic
+ || h == elf_hash_table (info)->hgot)
+ 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 (strcmp (name, GP_DISP_LABEL) == 0)
+ {
+ sym->st_shndx = SHN_ABS;
+ sym->st_info = ELF_ST_INFO (STB_GLOBAL, STT_SECTION);
+ sym->st_value = elf_gp (output_bfd);
+ }
+
+ return TRUE;
+}
+
+/* Finish up the dynamic sections. */
+static bfd_boolean
+s3_bfd_score_elf_finish_dynamic_sections (bfd *output_bfd,
+ struct bfd_link_info *info)
+{
+ bfd *dynobj;
+ asection *sdyn;
+ asection *sgot;
+ asection *s;
+ struct score_got_info *g;
+
+ dynobj = elf_hash_table (info)->dynobj;
+
+ sdyn = bfd_get_linker_section (dynobj, ".dynamic");
+
+ sgot = score_elf_got_section (dynobj, FALSE);
+ if (sgot == NULL)
+ g = NULL;
+ else
+ {
+ BFD_ASSERT (score_elf_section_data (sgot) != NULL);
+ g = score_elf_section_data (sgot)->u.got_info;
+ BFD_ASSERT (g != NULL);
+ }
+
+ if (elf_hash_table (info)->dynamic_sections_created)
+ {
+ bfd_byte *b;
+
+ BFD_ASSERT (sdyn != NULL);
+ BFD_ASSERT (g != NULL);
+
+ for (b = sdyn->contents;
+ b < sdyn->contents + sdyn->size;
+ b += SCORE_ELF_DYN_SIZE (dynobj))
+ {
+ Elf_Internal_Dyn dyn;
+ const char *name;
+ size_t elemsize;
+ bfd_boolean swap_out_p;
+
+ /* Read in the current dynamic entry. */
+ (*get_elf_backend_data (dynobj)->s->swap_dyn_in) (dynobj, b, &dyn);
+
+ /* Assume that we're going to modify it and write it out. */
+ swap_out_p = TRUE;
+
+ switch (dyn.d_tag)
+ {
+ case DT_RELENT:
+ s = score_elf_rel_dyn_section (dynobj, FALSE);
+ BFD_ASSERT (s != NULL);
+ dyn.d_un.d_val = SCORE_ELF_REL_SIZE (dynobj);
+ break;
+
+ case DT_STRSZ:
+ /* Rewrite DT_STRSZ. */
+ dyn.d_un.d_val = _bfd_elf_strtab_size (elf_hash_table (info)->dynstr);
+ break;
+
+ case DT_PLTGOT:
+ name = ".got";
+ s = bfd_get_section_by_name (output_bfd, name);
+ BFD_ASSERT (s != NULL);
+ dyn.d_un.d_ptr = s->vma;
+ break;
+
+ case DT_SCORE_BASE_ADDRESS:
+ s = output_bfd->sections;
+ BFD_ASSERT (s != NULL);
+ dyn.d_un.d_ptr = s->vma & ~(bfd_vma) 0xffff;
+ break;
+
+ case DT_SCORE_LOCAL_GOTNO:
+ dyn.d_un.d_val = g->local_gotno;
+ break;
+
+ case DT_SCORE_UNREFEXTNO:
+ /* The index into the dynamic symbol table which is the
+ entry of the first external symbol that is not
+ referenced within the same object. */
+ dyn.d_un.d_val = bfd_count_sections (output_bfd) + 1;
+ break;
+
+ case DT_SCORE_GOTSYM:
+ if (g->global_gotsym)
+ {
+ dyn.d_un.d_val = g->global_gotsym->dynindx;
+ break;
+ }
+ /* In case if we don't have global got symbols we default
+ to setting DT_SCORE_GOTSYM to the same value as
+ DT_SCORE_SYMTABNO, so we just fall through. */
+
+ case DT_SCORE_SYMTABNO:
+ name = ".dynsym";
+ elemsize = SCORE_ELF_SYM_SIZE (output_bfd);
+ s = bfd_get_section_by_name (output_bfd, name);
+ BFD_ASSERT (s != NULL);
+
+ dyn.d_un.d_val = s->size / elemsize;
+ break;
+
+ case DT_SCORE_HIPAGENO:
+ dyn.d_un.d_val = g->local_gotno - SCORE_RESERVED_GOTNO;
+ break;
+
+ default:
+ swap_out_p = FALSE;
+ break;
+ }
+
+ if (swap_out_p)
+ (*get_elf_backend_data (dynobj)->s->swap_dyn_out) (dynobj, &dyn, b);
+ }
+ }
+
+ /* 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->size > 0)
+ {
+ score_bfd_put_32 (output_bfd, 0, sgot->contents);
+ score_bfd_put_32 (output_bfd, 0x80000000, sgot->contents + SCORE_ELF_GOT_SIZE (output_bfd));
+ }
+
+ if (sgot != NULL)
+ elf_section_data (sgot->output_section)->this_hdr.sh_entsize
+ = SCORE_ELF_GOT_SIZE (output_bfd);
+
+
+ /* We need to sort the entries of the dynamic relocation section. */
+ s = score_elf_rel_dyn_section (dynobj, FALSE);
+
+ if (s != NULL && s->size > (bfd_vma)2 * SCORE_ELF_REL_SIZE (output_bfd))
+ {
+ reldyn_sorting_bfd = output_bfd;
+ qsort ((Elf32_External_Rel *) s->contents + 1, s->reloc_count - 1,
+ sizeof (Elf32_External_Rel), score_elf_sort_dynamic_relocs);
+ }
+
+ return TRUE;
+}
+
+/* This function 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. */
+static bfd_boolean
+s3_bfd_score_elf_fake_sections (bfd *abfd ATTRIBUTE_UNUSED,
+ Elf_Internal_Shdr *hdr,
+ asection *sec)
+{
+ const char *name;
+
+ name = bfd_get_section_name (abfd, sec);
+
+ if (strcmp (name, ".got") == 0
+ || strcmp (name, ".srdata") == 0
+ || strcmp (name, ".sdata") == 0
+ || strcmp (name, ".sbss") == 0)
+ hdr->sh_flags |= SHF_SCORE_GPREL;
+
+ return TRUE;
+}
+
+/* This function do additional processing on the ELF section header before writing
+ it out. This is used to set the flags and type fields for some sections. */
+
+/* assign_file_positions_except_relocs() check section flag and if it is allocatable,
+ warning message will be issued. backend_fake_section is called before
+ assign_file_positions_except_relocs(); backend_section_processing after it. so, we
+ modify section flag there, but not backend_fake_section. */
+static bfd_boolean
+s3_bfd_score_elf_section_processing (bfd *abfd ATTRIBUTE_UNUSED, 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_SCORE_GPREL;
+ hdr->sh_type = SHT_PROGBITS;
+ }
+ else if (strcmp (name, ".sbss") == 0)
+ {
+ hdr->sh_flags |= SHF_ALLOC | SHF_WRITE | SHF_SCORE_GPREL;
+ hdr->sh_type = SHT_NOBITS;
+ }
+ else if (strcmp (name, ".srdata") == 0)
+ {
+ hdr->sh_flags |= SHF_ALLOC | SHF_SCORE_GPREL;
+ hdr->sh_type = SHT_PROGBITS;
+ }
+ }
+
+ return TRUE;
+}
+
+static bfd_boolean
+s3_bfd_score_elf_write_section (bfd *output_bfd, asection *sec, bfd_byte *contents)
+{
+ bfd_byte *to, *from, *end;
+ int i;
+
+ if (strcmp (sec->name, ".pdr") != 0)
+ return FALSE;
+
+ if (score_elf_section_data (sec)->u.tdata == NULL)
+ return FALSE;
+
+ to = contents;
+ end = contents + sec->size;
+ for (from = contents, i = 0; from < end; from += PDR_SIZE, i++)
+ {
+ if ((score_elf_section_data (sec)->u.tdata)[i] == 1)
+ continue;
+
+ if (to != from)
+ memcpy (to, from, PDR_SIZE);
+
+ to += PDR_SIZE;
+ }
+ bfd_set_section_contents (output_bfd, sec->output_section, contents,
+ (file_ptr) sec->output_offset, sec->size);
+
+ return TRUE;
+}
+
+/* Copy data from a SCORE ELF indirect symbol to its direct symbol, hiding the old
+ indirect symbol. Process additional relocation information. */
+static void
+s3_bfd_score_elf_copy_indirect_symbol (struct bfd_link_info *info,
+ struct elf_link_hash_entry *dir,
+ struct elf_link_hash_entry *ind)
+{
+ struct score_elf_link_hash_entry *dirscore, *indscore;
+
+ _bfd_elf_link_hash_copy_indirect (info, dir, ind);
+
+ if (ind->root.type != bfd_link_hash_indirect)
+ return;
+
+ dirscore = (struct score_elf_link_hash_entry *) dir;
+ indscore = (struct score_elf_link_hash_entry *) ind;
+ dirscore->possibly_dynamic_relocs += indscore->possibly_dynamic_relocs;
+
+ if (indscore->readonly_reloc)
+ dirscore->readonly_reloc = TRUE;
+
+ if (indscore->no_fn_stub)
+ dirscore->no_fn_stub = TRUE;
+}
+
+/* Remove information about discarded functions from other sections which mention them. */
+static bfd_boolean
+s3_bfd_score_elf_discard_info (bfd *abfd, struct elf_reloc_cookie *cookie,
+ struct bfd_link_info *info)
+{
+ asection *o;
+ bfd_boolean ret = FALSE;
+ unsigned char *tdata;
+ size_t i, skip;
+
+ o = bfd_get_section_by_name (abfd, ".pdr");
+ if ((!o) || (o->size == 0) || (o->size % PDR_SIZE != 0)
+ || (o->output_section != NULL && bfd_is_abs_section (o->output_section)))
+ return FALSE;
+
+ tdata = bfd_zmalloc (o->size / PDR_SIZE);
+ if (!tdata)
+ return FALSE;
+
+ cookie->rels = _bfd_elf_link_read_relocs (abfd, o, NULL, NULL, info->keep_memory);
+ if (!cookie->rels)
+ {
+ free (tdata);
+ return FALSE;
+ }
+
+ cookie->rel = cookie->rels;
+ cookie->relend = cookie->rels + o->reloc_count;
+
+ for (i = 0, skip = 0; i < o->size; i++)
+ {
+ if (bfd_elf_reloc_symbol_deleted_p (i * PDR_SIZE, cookie))
+ {
+ tdata[i] = 1;
+ skip++;
+ }
+ }
+
+ if (skip != 0)
+ {
+ score_elf_section_data (o)->u.tdata = tdata;
+ o->size -= skip * PDR_SIZE;
+ ret = TRUE;
+ }
+ else
+ free (tdata);
+
+ if (!info->keep_memory)
+ free (cookie->rels);
+
+ return ret;
+}
+
+/* Signal that discard_info() has removed the discarded relocations for this section. */
+static bfd_boolean
+s3_bfd_score_elf_ignore_discarded_relocs (asection *sec)
+{
+ if (strcmp (sec->name, ".pdr") == 0)
+ return TRUE;
+ return FALSE;
+}
+
+/* Return the section that should be marked against GC for a given
+ relocation. */
+static asection *
+s3_bfd_score_elf_gc_mark_hook (asection *sec,
+ 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_SCORE_GNU_VTINHERIT:
+ case R_SCORE_GNU_VTENTRY:
+ return NULL;
+ }
+
+ return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
+}
+
+/* Support for core dump NOTE sections. */
+
+static bfd_boolean
+s3_bfd_score_elf_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
+{
+ int offset;
+ unsigned int raw_size;
+
+ switch (note->descsz)
+ {
+ default:
+ return FALSE;
+
+ case 148: /* Linux/Score 32-bit. */
+ /* pr_cursig */
+ elf_tdata (abfd)->core->signal
+ = score_bfd_get_16 (abfd, note->descdata + 12);
+
+ /* pr_pid */
+ elf_tdata (abfd)->core->lwpid
+ = score_bfd_get_32 (abfd, note->descdata + 24);
+
+ /* pr_reg */
+ offset = 72;
+ raw_size = 72;
+
+ break;
+ }
+
+ /* Make a ".reg/999" section. */
+ return _bfd_elfcore_make_pseudosection (abfd, ".reg", raw_size,
+ note->descpos + offset);
+}
+
+static bfd_boolean
+s3_bfd_score_elf_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
+{
+ switch (note->descsz)
+ {
+ default:
+ return FALSE;
+
+ case 124: /* Linux/Score elf_prpsinfo. */
+ elf_tdata (abfd)->core->program
+ = _bfd_elfcore_strndup (abfd, note->descdata + 28, 16);
+ elf_tdata (abfd)->core->command
+ = _bfd_elfcore_strndup (abfd, note->descdata + 44, 80);
+ }
+
+ /* 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;
+}
+
+
+/* Score BFD functions. */
+static reloc_howto_type *
+s3_elf32_score_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, bfd_reloc_code_real_type code)
+{
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE (elf32_score_reloc_map); i++)
+ if (elf32_score_reloc_map[i].bfd_reloc_val == code)
+ return &elf32_score_howto_table[elf32_score_reloc_map[i].elf_reloc_val];
+
+ return NULL;
+}
+
+static reloc_howto_type *
+elf32_score_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ const char *r_name)
+{
+ unsigned int i;
+
+ for (i = 0;
+ i < (sizeof (elf32_score_howto_table)
+ / sizeof (elf32_score_howto_table[0]));
+ i++)
+ if (elf32_score_howto_table[i].name != NULL
+ && strcasecmp (elf32_score_howto_table[i].name, r_name) == 0)
+ return &elf32_score_howto_table[i];
+
+ return NULL;
+}
+
+static bfd_boolean
+s3_elf32_score_print_private_bfd_data (bfd *abfd, void * 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_SCORE_PIC)
+ {
+ fprintf (file, _(" [pic]"));
+ }
+ if (elf_elfheader (abfd)->e_flags & EF_SCORE_FIXDEP)
+ {
+ fprintf (file, _(" [fix dep]"));
+ }
+ fputc ('\n', file);
+
+ return TRUE;
+}
+
+static bfd_boolean
+s3_elf32_score_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
+{
+ flagword in_flags;
+ flagword out_flags;
+
+ if (!_bfd_generic_verify_endian_match (ibfd, obfd))
+ return FALSE;
+
+ in_flags = elf_elfheader (ibfd)->e_flags;
+ out_flags = elf_elfheader (obfd)->e_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))
+ {
+ 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;
+ }
+
+ if (((in_flags & EF_SCORE_PIC) != 0) != ((out_flags & EF_SCORE_PIC) != 0))
+ {
+ (*_bfd_error_handler) (_("%B: warning: linking PIC files with non-PIC files"), ibfd);
+ }
+
+ /* FIXME: Maybe dependency fix compatibility should be checked here. */
+
+ return TRUE;
+}
+
+static bfd_boolean
+s3_elf32_score_new_section_hook (bfd *abfd, asection *sec)
+{
+ struct _score_elf_section_data *sdata;
+ bfd_size_type amt = sizeof (*sdata);
+
+ sdata = bfd_zalloc (abfd, amt);
+ if (sdata == NULL)
+ return FALSE;
+ sec->used_by_bfd = sdata;
+
+ return _bfd_elf_new_section_hook (abfd, sec);
+}
+
+/*****************************************************************************/
+
+/* s3_s7: backend hooks. */
+static void
+_bfd_score_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED,
+ arelent *bfd_reloc,
+ Elf_Internal_Rela *elf_reloc)
+{
+ if (bfd_get_mach (abfd) == bfd_mach_score3)
+ return s3_bfd_score_info_to_howto (abfd, bfd_reloc, elf_reloc);
+ else
+ return s7_bfd_score_info_to_howto (abfd, bfd_reloc, elf_reloc);
+}
+
+static bfd_boolean
+_bfd_score_elf_relocate_section (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)
+{
+ if (bfd_get_mach (output_bfd) == bfd_mach_score3)
+ return s3_bfd_score_elf_relocate_section (output_bfd,
+ info, input_bfd, input_section, contents, relocs,
+ local_syms, local_sections);
+ else
+ return s7_bfd_score_elf_relocate_section (output_bfd,
+ info, input_bfd, input_section, contents, relocs,
+ local_syms, local_sections);
+}
+
+static bfd_boolean
+_bfd_score_elf_check_relocs (bfd *abfd,
+ struct bfd_link_info *info,
+ asection *sec,
+ const Elf_Internal_Rela *relocs)
+{
+ if (bfd_get_mach (abfd) == bfd_mach_score3)
+ return s3_bfd_score_elf_check_relocs (abfd, info, sec, relocs);
+ else
+ return s7_bfd_score_elf_check_relocs (abfd, info, sec, relocs);
+}
+
+static bfd_boolean
+_bfd_score_elf_add_symbol_hook (bfd *abfd,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ Elf_Internal_Sym *sym,
+ const char **namep ATTRIBUTE_UNUSED,
+ flagword *flagsp ATTRIBUTE_UNUSED,
+ asection **secp,
+ bfd_vma *valp)
+{
+ if (bfd_get_mach (abfd) == bfd_mach_score3)
+ return s3_bfd_score_elf_add_symbol_hook (abfd, info, sym, namep, flagsp,
+ secp, valp);
+ else
+ return s7_bfd_score_elf_add_symbol_hook (abfd, info, sym, namep, flagsp,
+ secp, valp);
+}
+
+static void
+_bfd_score_elf_symbol_processing (bfd *abfd, asymbol *asym)
+{
+ if (bfd_get_mach (abfd) == bfd_mach_score3)
+ return s3_bfd_score_elf_symbol_processing (abfd, asym);
+ else
+ return s7_bfd_score_elf_symbol_processing (abfd, asym);
+}
+
+static int
+_bfd_score_elf_link_output_symbol_hook (struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ const char *name ATTRIBUTE_UNUSED,
+ Elf_Internal_Sym *sym,
+ asection *input_sec,
+ struct elf_link_hash_entry *h ATTRIBUTE_UNUSED)
+{
+ /* If link a empty .o, then this filed is NULL. */
+ if (info->input_bfds == NULL)
+ {
+ /* 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_SCORE_SCOMMON;
+ return 1;
+ }
+
+ if (bfd_get_mach (info->input_bfds) == bfd_mach_score3)
+ return s3_bfd_score_elf_link_output_symbol_hook (info, name, sym, input_sec, h);
+ else
+ return s7_bfd_score_elf_link_output_symbol_hook (info, name, sym, input_sec, h);
+}
+
+static bfd_boolean
+_bfd_score_elf_section_from_bfd_section (bfd *abfd ATTRIBUTE_UNUSED,
+ asection *sec,
+ int *retval)
+{
+ if (bfd_get_mach (abfd) == bfd_mach_score3)
+ return s3_bfd_score_elf_section_from_bfd_section (abfd, sec, retval);
+ else
+ return s7_bfd_score_elf_section_from_bfd_section (abfd, sec, retval);
+}
+
+static bfd_boolean
+_bfd_score_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
+ struct elf_link_hash_entry *h)
+{
+ if (bfd_get_mach (info->input_bfds) == bfd_mach_score3)
+ return s3_bfd_score_elf_adjust_dynamic_symbol (info, h);
+ else
+ return s7_bfd_score_elf_adjust_dynamic_symbol (info, h);
+}
+
+static bfd_boolean
+_bfd_score_elf_always_size_sections (bfd *output_bfd,
+ struct bfd_link_info *info)
+{
+ if (bfd_get_mach (output_bfd) == bfd_mach_score3)
+ return s3_bfd_score_elf_always_size_sections (output_bfd, info);
+ else
+ return s7_bfd_score_elf_always_size_sections (output_bfd, info);
+}
+
+static bfd_boolean
+_bfd_score_elf_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
+{
+ if (bfd_get_mach (output_bfd) == bfd_mach_score3)
+ return s3_bfd_score_elf_size_dynamic_sections (output_bfd, info);
+ else
+ return s7_bfd_score_elf_size_dynamic_sections (output_bfd, info);
+}
+
+static bfd_boolean
+_bfd_score_elf_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
+{
+ if (bfd_get_mach (abfd) == bfd_mach_score3)
+ return s3_bfd_score_elf_create_dynamic_sections (abfd, info);
+ else
+ return s7_bfd_score_elf_create_dynamic_sections (abfd, info);
+}
+
+static bfd_boolean
+_bfd_score_elf_finish_dynamic_symbol (bfd *output_bfd,
+ struct bfd_link_info *info,
+ struct elf_link_hash_entry *h,
+ Elf_Internal_Sym *sym)
+{
+ if (bfd_get_mach (output_bfd) == bfd_mach_score3)
+ return s3_bfd_score_elf_finish_dynamic_symbol (output_bfd, info, h, sym);
+ else
+ return s7_bfd_score_elf_finish_dynamic_symbol (output_bfd, info, h, sym);
+}
+
+static bfd_boolean
+_bfd_score_elf_finish_dynamic_sections (bfd *output_bfd,
+ struct bfd_link_info *info)
+{
+ if (bfd_get_mach (output_bfd) == bfd_mach_score3)
+ return s3_bfd_score_elf_finish_dynamic_sections (output_bfd, info);
+ else
+ return s7_bfd_score_elf_finish_dynamic_sections (output_bfd, info);
+}
+
+static bfd_boolean
+_bfd_score_elf_fake_sections (bfd *abfd ATTRIBUTE_UNUSED,
+ Elf_Internal_Shdr *hdr,
+ asection *sec)
+{
+ if (bfd_get_mach (abfd) == bfd_mach_score3)
+ return s3_bfd_score_elf_fake_sections (abfd, hdr, sec);
+ else
+ return s7_bfd_score_elf_fake_sections (abfd, hdr, sec);
+}
+
+static bfd_boolean
+_bfd_score_elf_section_processing (bfd *abfd ATTRIBUTE_UNUSED, Elf_Internal_Shdr *hdr)
+{
+ if (bfd_get_mach (abfd) == bfd_mach_score3)
+ return s3_bfd_score_elf_section_processing (abfd, hdr);
+ else
+ return s7_bfd_score_elf_section_processing (abfd, hdr);
+}
+
+static bfd_boolean
+_bfd_score_elf_write_section (bfd *output_bfd,
+ struct bfd_link_info *link_info ATTRIBUTE_UNUSED,
+ asection *sec, bfd_byte *contents)
+{
+ if (bfd_get_mach (output_bfd) == bfd_mach_score3)
+ return s3_bfd_score_elf_write_section (output_bfd, sec, contents);
+ else
+ return s7_bfd_score_elf_write_section (output_bfd, sec, contents);
+}
+
+static void
+_bfd_score_elf_copy_indirect_symbol (struct bfd_link_info *info,
+ struct elf_link_hash_entry *dir,
+ struct elf_link_hash_entry *ind)
+{
+ if (bfd_get_mach (info->input_bfds) == bfd_mach_score3)
+ return s3_bfd_score_elf_copy_indirect_symbol (info, dir, ind);
+ else
+ return s7_bfd_score_elf_copy_indirect_symbol (info, dir, ind);
+}
+
+static void
+_bfd_score_elf_hide_symbol (struct bfd_link_info *info,
+ struct elf_link_hash_entry *entry,
+ bfd_boolean force_local)
+{
+ if (bfd_get_mach (info->input_bfds) == bfd_mach_score3)
+ return s3_bfd_score_elf_hide_symbol (info, entry, force_local);
+ else
+ return s7_bfd_score_elf_hide_symbol (info, entry, force_local);
+}
+
+static bfd_boolean
+_bfd_score_elf_discard_info (bfd *abfd, struct elf_reloc_cookie *cookie,
+ struct bfd_link_info *info)
+{
+ if (bfd_get_mach (abfd) == bfd_mach_score3)
+ return s3_bfd_score_elf_discard_info (abfd, cookie, info);
+ else
+ return s7_bfd_score_elf_discard_info (abfd, cookie, info);
+}
+
+static bfd_boolean
+_bfd_score_elf_ignore_discarded_relocs (asection *sec)
+{
+ if (bfd_get_mach (sec->owner) == bfd_mach_score3)
+ return s3_bfd_score_elf_ignore_discarded_relocs (sec);
+ else
+ return s7_bfd_score_elf_ignore_discarded_relocs (sec);
+}
+
+static asection *
+_bfd_score_elf_gc_mark_hook (asection *sec,
+ struct bfd_link_info *info,
+ Elf_Internal_Rela *rel,
+ struct elf_link_hash_entry *h,
+ Elf_Internal_Sym *sym)
+{
+ if (bfd_get_mach (info->input_bfds) == bfd_mach_score3)
+ return s3_bfd_score_elf_gc_mark_hook (sec, info, rel, h, sym);
+ else
+ return s7_bfd_score_elf_gc_mark_hook (sec, info, rel, h, sym);
+}
+
+static bfd_boolean
+_bfd_score_elf_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
+{
+ if (bfd_get_mach (abfd) == bfd_mach_score3)
+ return s3_bfd_score_elf_grok_prstatus (abfd, note);
+ else
+ return s7_bfd_score_elf_grok_prstatus (abfd, note);
+}
+
+static bfd_boolean
+_bfd_score_elf_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
+{
+ if (bfd_get_mach (abfd) == bfd_mach_score3)
+ return s3_bfd_score_elf_grok_psinfo (abfd, note);
+ else
+ return s7_bfd_score_elf_grok_psinfo (abfd, note);
+}
+
+static reloc_howto_type *
+elf32_score_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, bfd_reloc_code_real_type code)
+{
+ /* s3: NOTE!!!
+ gas will call elf32_score_reloc_type_lookup, and don't write elf file.
+ So just using score3, but we don't know ld will call this or not.
+ If so, this way can't work. */
+
+ if (score3)
+ return s3_elf32_score_reloc_type_lookup (abfd, code);
+ else
+ return s7_elf32_score_reloc_type_lookup (abfd, code);
+}
+
+/* Create a score elf linker hash table.
+ This is a copy of _bfd_elf_link_hash_table_create() except with a
+ different hash table entry creation function. */
+
+static struct bfd_link_hash_table *
+elf32_score_link_hash_table_create (bfd *abfd)
+{
+ struct elf_link_hash_table *ret;
+ bfd_size_type amt = sizeof (struct elf_link_hash_table);
+
+ ret = (struct elf_link_hash_table *) bfd_zmalloc (amt);
+ if (ret == NULL)
+ return NULL;
+
+ if (!_bfd_elf_link_hash_table_init (ret, abfd, score_elf_link_hash_newfunc,
+ sizeof (struct score_elf_link_hash_entry),
+ GENERIC_ELF_DATA))
+ {
+ free (ret);
+ return NULL;
+ }
+
+ return &ret->root;
+}
+
+static bfd_boolean
+elf32_score_print_private_bfd_data (bfd *abfd, void * ptr)
+{
+ if (bfd_get_mach (abfd) == bfd_mach_score3)
+ return s3_elf32_score_print_private_bfd_data (abfd, ptr);
+ else
+ return s7_elf32_score_print_private_bfd_data (abfd, ptr);
+}
+
+static bfd_boolean
+elf32_score_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
+{
+ if (bfd_get_mach (obfd) == bfd_mach_score3)
+ return s3_elf32_score_merge_private_bfd_data (ibfd, obfd);
+ else
+ return s7_elf32_score_merge_private_bfd_data (ibfd, obfd);
+}
+
+static bfd_boolean
+elf32_score_new_section_hook (bfd *abfd, asection *sec)
+{
+ if (bfd_get_mach (abfd) == bfd_mach_score3)
+ return s3_elf32_score_new_section_hook (abfd, sec);
+ else
+ return s7_elf32_score_new_section_hook (abfd, sec);
+}
+
+
+/* s3_s7: don't need to split. */
+
+/* Set the right machine number. */
+static bfd_boolean
+_bfd_score_elf_score_object_p (bfd * abfd)
+{
+ int e_set = bfd_mach_score7;
+
+ if (elf_elfheader (abfd)->e_machine == EM_SCORE)
+ {
+ int e_mach = elf_elfheader (abfd)->e_flags & EF_SCORE_MACH & EF_OMIT_PIC_FIXDD;
+ switch (e_mach)
+ {
+ /* Set default target is score7. */
+ default:
+ case E_SCORE_MACH_SCORE7:
+ e_set = bfd_mach_score7;
+ break;
+
+ case E_SCORE_MACH_SCORE3:
+ e_set = bfd_mach_score3;
+ break;
+ }
+ }
+
+ return bfd_default_set_arch_mach (abfd, bfd_arch_score, e_set);
+}
+
+bfd_boolean
+_bfd_score_elf_common_definition (Elf_Internal_Sym *sym)
+{
+ return (sym->st_shndx == SHN_COMMON || sym->st_shndx == SHN_SCORE_SCOMMON);
+}
+
+/*****************************************************************************/
+
+
+#define USE_REL 1
+#define TARGET_LITTLE_SYM score_elf32_le_vec
+#define TARGET_LITTLE_NAME "elf32-littlescore"
+#define TARGET_BIG_SYM score_elf32_be_vec
+#define TARGET_BIG_NAME "elf32-bigscore"
+#define ELF_ARCH bfd_arch_score
+#define ELF_MACHINE_CODE EM_SCORE
+#define ELF_MACHINE_ALT1 EM_SCORE_OLD
+#define ELF_MAXPAGESIZE 0x8000
+
+#define elf_info_to_howto 0
+#define elf_info_to_howto_rel _bfd_score_info_to_howto
+#define elf_backend_relocate_section _bfd_score_elf_relocate_section
+#define elf_backend_check_relocs _bfd_score_elf_check_relocs
+#define elf_backend_add_symbol_hook _bfd_score_elf_add_symbol_hook
+#define elf_backend_symbol_processing _bfd_score_elf_symbol_processing
+#define elf_backend_link_output_symbol_hook \
+ _bfd_score_elf_link_output_symbol_hook
+#define elf_backend_section_from_bfd_section \
+ _bfd_score_elf_section_from_bfd_section
+#define elf_backend_adjust_dynamic_symbol \
+ _bfd_score_elf_adjust_dynamic_symbol
+#define elf_backend_always_size_sections \
+ _bfd_score_elf_always_size_sections
+#define elf_backend_size_dynamic_sections \
+ _bfd_score_elf_size_dynamic_sections
+#define elf_backend_omit_section_dynsym \
+ ((bfd_boolean (*) (bfd *, struct bfd_link_info *, asection *)) bfd_true)
+#define elf_backend_create_dynamic_sections \
+ _bfd_score_elf_create_dynamic_sections
+#define elf_backend_finish_dynamic_symbol \
+ _bfd_score_elf_finish_dynamic_symbol
+#define elf_backend_finish_dynamic_sections \
+ _bfd_score_elf_finish_dynamic_sections
+#define elf_backend_fake_sections _bfd_score_elf_fake_sections
+#define elf_backend_section_processing _bfd_score_elf_section_processing
+#define elf_backend_write_section _bfd_score_elf_write_section
+#define elf_backend_copy_indirect_symbol _bfd_score_elf_copy_indirect_symbol
+#define elf_backend_hide_symbol _bfd_score_elf_hide_symbol
+#define elf_backend_discard_info _bfd_score_elf_discard_info
+#define elf_backend_ignore_discarded_relocs \
+ _bfd_score_elf_ignore_discarded_relocs
+#define elf_backend_gc_mark_hook _bfd_score_elf_gc_mark_hook
+#define elf_backend_grok_prstatus _bfd_score_elf_grok_prstatus
+#define elf_backend_grok_psinfo _bfd_score_elf_grok_psinfo
+#define elf_backend_can_gc_sections 1
+#define elf_backend_want_plt_sym 0
+#define elf_backend_got_header_size (4 * SCORE_RESERVED_GOTNO)
+#define elf_backend_plt_header_size 0
+#define elf_backend_collect TRUE
+#define elf_backend_type_change_ok TRUE
+#define elf_backend_object_p _bfd_score_elf_score_object_p
+
+#define bfd_elf32_bfd_reloc_type_lookup elf32_score_reloc_type_lookup
+#define bfd_elf32_bfd_reloc_name_lookup \
+ elf32_score_reloc_name_lookup
+#define bfd_elf32_bfd_link_hash_table_create elf32_score_link_hash_table_create
+#define bfd_elf32_bfd_print_private_bfd_data elf32_score_print_private_bfd_data
+#define bfd_elf32_bfd_merge_private_bfd_data elf32_score_merge_private_bfd_data
+#define bfd_elf32_new_section_hook elf32_score_new_section_hook
+
+#include "elf32-target.h"
diff --git a/bfd/elf32-score.h b/bfd/elf32-score.h
new file mode 100644
index 0000000..f71436d
--- /dev/null
+++ b/bfd/elf32-score.h
@@ -0,0 +1,152 @@
+/* 32-bit ELF support for S+core.
+ Copyright (C) 2009-2014 Free Software Foundation, Inc.
+ Contributed by
+ Brain.lin (brain.lin@sunplusct.com)
+ Mei Ligang (ligang@sunnorth.com.cn)
+ Pei-Lin Tsai (pltsai@sunplus.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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "elf/common.h"
+#include "elf/internal.h"
+
+extern void
+s7_bfd_score_elf_hide_symbol (struct bfd_link_info *,
+ struct elf_link_hash_entry *,
+ bfd_boolean);
+
+extern void
+s7_bfd_score_info_to_howto (bfd *, arelent *, Elf_Internal_Rela *);
+
+extern bfd_boolean
+s7_bfd_score_elf_relocate_section (bfd *,
+ struct bfd_link_info *,
+ bfd *,
+ asection *,
+ bfd_byte *,
+ Elf_Internal_Rela *,
+ Elf_Internal_Sym *,
+ asection **);
+
+extern bfd_boolean
+s7_bfd_score_elf_check_relocs (bfd *,
+ struct bfd_link_info *,
+ asection *,
+ const Elf_Internal_Rela *);
+
+extern bfd_boolean
+s7_bfd_score_elf_add_symbol_hook (bfd *,
+ struct bfd_link_info *,
+ Elf_Internal_Sym *,
+ const char **,
+ flagword *,
+ asection **,
+ bfd_vma *);
+
+extern void
+s7_bfd_score_elf_symbol_processing (bfd *, asymbol *);
+
+extern int
+s7_bfd_score_elf_link_output_symbol_hook (struct bfd_link_info *,
+ const char *,
+ Elf_Internal_Sym *,
+ asection *,
+ struct elf_link_hash_entry *);
+
+extern bfd_boolean
+s7_bfd_score_elf_section_from_bfd_section (bfd *,
+ asection *,
+ int *);
+
+extern bfd_boolean
+s7_bfd_score_elf_adjust_dynamic_symbol (struct bfd_link_info *,
+ struct elf_link_hash_entry *);
+
+extern bfd_boolean
+s7_bfd_score_elf_always_size_sections (bfd *, struct bfd_link_info *);
+
+extern bfd_boolean
+s7_bfd_score_elf_size_dynamic_sections (bfd *, struct bfd_link_info *);
+
+extern bfd_boolean
+s7_bfd_score_elf_create_dynamic_sections (bfd *, struct bfd_link_info *);
+
+extern bfd_boolean
+s7_bfd_score_elf_finish_dynamic_symbol (bfd *,
+ struct bfd_link_info *,
+ struct elf_link_hash_entry *,
+ Elf_Internal_Sym *);
+
+extern bfd_boolean
+s7_bfd_score_elf_finish_dynamic_sections (bfd *, struct bfd_link_info *);
+
+extern bfd_boolean
+s7_bfd_score_elf_fake_sections (bfd *,
+ Elf_Internal_Shdr *,
+ asection *);
+
+extern bfd_boolean
+s7_bfd_score_elf_section_processing (bfd *, Elf_Internal_Shdr *);
+
+extern bfd_boolean
+s7_bfd_score_elf_write_section (bfd *, asection *, bfd_byte *);
+
+extern void
+s7_bfd_score_elf_copy_indirect_symbol (struct bfd_link_info *,
+ struct elf_link_hash_entry *,
+ struct elf_link_hash_entry *);
+
+extern bfd_boolean
+s7_bfd_score_elf_discard_info (bfd *, struct elf_reloc_cookie *,
+ struct bfd_link_info *);
+
+extern bfd_boolean
+s7_bfd_score_elf_ignore_discarded_relocs (asection *);
+
+extern asection *
+s7_bfd_score_elf_gc_mark_hook (asection *,
+ struct bfd_link_info *,
+ Elf_Internal_Rela *,
+ struct elf_link_hash_entry *,
+ Elf_Internal_Sym *);
+
+extern bfd_boolean
+s7_bfd_score_elf_grok_prstatus (bfd *, Elf_Internal_Note *);
+
+extern bfd_boolean
+s7_bfd_score_elf_grok_psinfo (bfd *, Elf_Internal_Note *);
+
+extern reloc_howto_type *
+s7_elf32_score_reloc_type_lookup (bfd *, bfd_reloc_code_real_type);
+
+extern struct bfd_link_hash_table *
+s7_elf32_score_link_hash_table_create (bfd *);
+
+extern bfd_boolean
+s7_elf32_score_print_private_bfd_data (bfd *, void *);
+
+extern bfd_boolean
+s7_elf32_score_merge_private_bfd_data (bfd *, bfd *);
+
+extern bfd_boolean
+s7_elf32_score_new_section_hook (bfd *, asection *);
+
+extern bfd_boolean
+_bfd_score_elf_common_definition (Elf_Internal_Sym *);
+
+#define elf_backend_common_definition _bfd_score_elf_common_definition
diff --git a/bfd/elf32-score7.c b/bfd/elf32-score7.c
new file mode 100644
index 0000000..0b3cf20
--- /dev/null
+++ b/bfd/elf32-score7.c
@@ -0,0 +1,3885 @@
+/* 32-bit ELF support for S+core.
+ Copyright (C) 2009-2014 Free Software Foundation, Inc.
+ Contributed by
+ Brain.lin (brain.lin@sunplusct.com)
+ Mei Ligang (ligang@sunnorth.com.cn)
+ Pei-Lin Tsai (pltsai@sunplus.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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+#include "libiberty.h"
+#include "elf-bfd.h"
+#include "elf/score.h"
+#include "elf/common.h"
+#include "elf/internal.h"
+#include "hashtab.h"
+#include "elf32-score.h"
+
+
+/* The SCORE ELF linker needs additional information for each symbol in
+ the global hash table. */
+struct score_elf_link_hash_entry
+{
+ struct elf_link_hash_entry root;
+
+ /* Number of R_SCORE_ABS32, R_SCORE_REL32 relocs against this symbol. */
+ unsigned int possibly_dynamic_relocs;
+
+ /* If the R_SCORE_ABS32, R_SCORE_REL32 reloc is against a readonly section. */
+ bfd_boolean readonly_reloc;
+
+ /* We must not create a stub for a symbol that has relocations related to
+ taking the function's address, i.e. any but R_SCORE_CALL15 ones. */
+ bfd_boolean no_fn_stub;
+
+ /* Are we forced local? This will only be set if we have converted
+ the initial global GOT entry to a local GOT entry. */
+ bfd_boolean forced_local;
+};
+
+/* Traverse a score ELF linker hash table. */
+#define score_elf_link_hash_traverse(table, func, info) \
+ (elf_link_hash_traverse \
+ ((table), \
+ (bfd_boolean (*) (struct elf_link_hash_entry *, void *)) (func), \
+ (info)))
+
+/* This structure is used to hold .got entries while estimating got sizes. */
+struct score_got_entry
+{
+ /* The input bfd in which the symbol is defined. */
+ bfd *abfd;
+ /* The index of the symbol, as stored in the relocation r_info, if
+ we have a local symbol; -1 otherwise. */
+ long symndx;
+ union
+ {
+ /* If abfd == NULL, an address that must be stored in the got. */
+ bfd_vma address;
+ /* If abfd != NULL && symndx != -1, the addend of the relocation
+ that should be added to the symbol value. */
+ bfd_vma addend;
+ /* If abfd != NULL && symndx == -1, the hash table entry
+ corresponding to a global symbol in the got (or, local, if
+ h->forced_local). */
+ struct score_elf_link_hash_entry *h;
+ } d;
+
+ /* The offset from the beginning of the .got section to the entry
+ corresponding to this symbol+addend. If it's a global symbol
+ whose offset is yet to be decided, it's going to be -1. */
+ long gotidx;
+};
+
+/* This structure is passed to score_elf_sort_hash_table_f when sorting
+ the dynamic symbols. */
+struct score_elf_hash_sort_data
+{
+ /* The symbol in the global GOT with the lowest dynamic symbol table index. */
+ struct elf_link_hash_entry *low;
+ /* The least dynamic symbol table index corresponding to a symbol with a GOT entry. */
+ long min_got_dynindx;
+ /* The greatest dynamic symbol table index corresponding to a symbol
+ with a GOT entry that is not referenced (e.g., a dynamic symbol
+ with dynamic relocations pointing to it from non-primary GOTs). */
+ long max_unref_got_dynindx;
+ /* The greatest dynamic symbol table index not corresponding to a
+ symbol without a GOT entry. */
+ long max_non_got_dynindx;
+};
+
+struct score_got_info
+{
+ /* The global symbol in the GOT with the lowest index in the dynamic
+ symbol table. */
+ struct elf_link_hash_entry *global_gotsym;
+ /* The number of global .got entries. */
+ unsigned int global_gotno;
+ /* The number of local .got entries. */
+ unsigned int local_gotno;
+ /* The number of local .got entries we have used. */
+ unsigned int assigned_gotno;
+ /* A hash table holding members of the got. */
+ struct htab *got_entries;
+ /* In multi-got links, a pointer to the next got (err, rather, most
+ of the time, it points to the previous got). */
+ struct score_got_info *next;
+};
+
+/* A structure used to count GOT entries, for GOT entry or ELF symbol table traversal. */
+struct _score_elf_section_data
+{
+ struct bfd_elf_section_data elf;
+ union
+ {
+ struct score_got_info *got_info;
+ bfd_byte *tdata;
+ }
+ u;
+};
+
+#define score_elf_section_data(sec) \
+ ((struct _score_elf_section_data *) elf_section_data (sec))
+
+/* The size of a symbol-table entry. */
+#define SCORE_ELF_SYM_SIZE(abfd) \
+ (get_elf_backend_data (abfd)->s->sizeof_sym)
+
+/* 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)
+#define MINUS_TWO (((bfd_vma)0) - 2)
+
+#define PDR_SIZE 32
+
+
+/* The number of local .got entries we reserve. */
+#define SCORE_RESERVED_GOTNO (2)
+#define ELF_DYNAMIC_INTERPRETER "/usr/lib/ld.so.1"
+
+/* The offset of $gp from the beginning of the .got section. */
+#define ELF_SCORE_GP_OFFSET(abfd) (0x3ff0)
+
+/* The maximum size of the GOT for it to be addressable using 15-bit offsets from $gp. */
+#define SCORE_ELF_GOT_MAX_SIZE(abfd) (ELF_SCORE_GP_OFFSET(abfd) + 0x3fff)
+
+#define SCORE_ELF_STUB_SECTION_NAME (".SCORE.stub")
+#define SCORE_FUNCTION_STUB_SIZE (16)
+
+#define STUB_LW 0xc3bcc010 /* lw r29, [r28, -0x3ff0] */
+#define STUB_MOVE 0x8323bc56 /* mv r25, r3 */
+#define STUB_LI16 0x87548000 /* ori r26, .dynsym_index */
+#define STUB_BRL 0x801dbc09 /* brl r29 */
+
+#define SCORE_ELF_GOT_SIZE(abfd) \
+ (get_elf_backend_data (abfd)->s->arch_size / 8)
+
+#define SCORE_ELF_ADD_DYNAMIC_ENTRY(info, tag, val) \
+ (_bfd_elf_add_dynamic_entry (info, (bfd_vma) tag, (bfd_vma) val))
+
+/* The size of an external dynamic table entry. */
+#define SCORE_ELF_DYN_SIZE(abfd) \
+ (get_elf_backend_data (abfd)->s->sizeof_dyn)
+
+/* The size of an external REL relocation. */
+#define SCORE_ELF_REL_SIZE(abfd) \
+ (get_elf_backend_data (abfd)->s->sizeof_rel)
+
+/* The default alignment for sections, as a power of two. */
+#define SCORE_ELF_LOG_FILE_ALIGN(abfd)\
+ (get_elf_backend_data (abfd)->s->log_file_align)
+
+static bfd_byte *hi16_rel_addr;
+
+/* This will be used when we sort the dynamic relocation records. */
+static bfd *reldyn_sorting_bfd;
+
+/* SCORE 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 score_elf_scom_section;
+static asymbol score_elf_scom_symbol;
+static asymbol * score_elf_scom_symbol_ptr;
+
+static bfd_reloc_status_type
+score_elf_hi16_reloc (bfd *abfd ATTRIBUTE_UNUSED,
+ arelent *reloc_entry,
+ asymbol *symbol ATTRIBUTE_UNUSED,
+ void * data,
+ asection *input_section ATTRIBUTE_UNUSED,
+ bfd *output_bfd ATTRIBUTE_UNUSED,
+ char **error_message ATTRIBUTE_UNUSED)
+{
+ hi16_rel_addr = (bfd_byte *) data + reloc_entry->address;
+ return bfd_reloc_ok;
+}
+
+static bfd_reloc_status_type
+score_elf_lo16_reloc (bfd *abfd,
+ arelent *reloc_entry,
+ asymbol *symbol ATTRIBUTE_UNUSED,
+ void * data,
+ asection *input_section,
+ bfd *output_bfd ATTRIBUTE_UNUSED,
+ char **error_message ATTRIBUTE_UNUSED)
+{
+ bfd_vma addend = 0, offset = 0;
+ unsigned long val;
+ unsigned long hi16_offset, hi16_value, uvalue;
+
+ hi16_value = bfd_get_32 (abfd, hi16_rel_addr);
+ hi16_offset = ((((hi16_value >> 16) & 0x3) << 15) | (hi16_value & 0x7fff)) >> 1;
+ addend = bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
+ offset = ((((addend >> 16) & 0x3) << 15) | (addend & 0x7fff)) >> 1;
+ val = reloc_entry->addend;
+ if (reloc_entry->address > input_section->size)
+ return bfd_reloc_outofrange;
+ uvalue = ((hi16_offset << 16) | (offset & 0xffff)) + val;
+ hi16_offset = (uvalue >> 16) << 1;
+ hi16_value = (hi16_value & ~0x37fff) | (hi16_offset & 0x7fff) | ((hi16_offset << 1) & 0x30000);
+ bfd_put_32 (abfd, hi16_value, hi16_rel_addr);
+ offset = (uvalue & 0xffff) << 1;
+ addend = (addend & ~0x37fff) | (offset & 0x7fff) | ((offset << 1) & 0x30000);
+ bfd_put_32 (abfd, addend, (bfd_byte *) data + reloc_entry->address);
+ return bfd_reloc_ok;
+}
+
+/* Set the GP value for OUTPUT_BFD. Returns FALSE if this is a
+ dangerous relocation. */
+
+static bfd_boolean
+score_elf_assign_gp (bfd *output_bfd, bfd_vma *pgp)
+{
+ unsigned int count;
+ asymbol **sym;
+ unsigned int i;
+
+ /* If we've already figured out what GP will be, just return it. */
+ *pgp = _bfd_get_gp_value (output_bfd);
+ if (*pgp)
+ return TRUE;
+
+ count = bfd_get_symcount (output_bfd);
+ sym = bfd_get_outsymbols (output_bfd);
+
+ /* The linker script will have created a symbol named `_gp' with the
+ appropriate value. */
+ if (sym == NULL)
+ i = count;
+ else
+ {
+ for (i = 0; i < count; i++, sym++)
+ {
+ 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);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/* 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 relocatable output. */
+
+static bfd_reloc_status_type
+score_elf_final_gp (bfd *output_bfd,
+ asymbol *symbol,
+ bfd_boolean relocatable,
+ char **error_message,
+ bfd_vma *pgp)
+{
+ if (bfd_is_und_section (symbol->section)
+ && ! relocatable)
+ {
+ *pgp = 0;
+ return bfd_reloc_undefined;
+ }
+
+ *pgp = _bfd_get_gp_value (output_bfd);
+ if (*pgp == 0
+ && (! relocatable
+ || (symbol->flags & BSF_SECTION_SYM) != 0))
+ {
+ if (relocatable)
+ {
+ /* Make up a value. */
+ *pgp = symbol->section->output_section->vma + 0x4000;
+ _bfd_set_gp_value (output_bfd, *pgp);
+ }
+ else if (!score_elf_assign_gp (output_bfd, pgp))
+ {
+ *error_message =
+ (char *) _("GP relative relocation when _gp not defined");
+ return bfd_reloc_dangerous;
+ }
+ }
+
+ return bfd_reloc_ok;
+}
+
+static bfd_reloc_status_type
+score_elf_gprel15_with_gp (bfd *abfd,
+ asymbol *symbol,
+ arelent *reloc_entry,
+ asection *input_section,
+ bfd_boolean relocateable,
+ void * data,
+ bfd_vma gp ATTRIBUTE_UNUSED)
+{
+ bfd_vma relocation;
+ unsigned long insn;
+
+ 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->size)
+ return bfd_reloc_outofrange;
+
+ insn = bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
+ if (((reloc_entry->addend & 0xffffc000) != 0)
+ && ((reloc_entry->addend & 0xffffc000) != 0xffffc000))
+ return bfd_reloc_overflow;
+
+ insn = (insn & ~0x7fff) | (reloc_entry->addend & 0x7fff);
+ bfd_put_32 (abfd, insn, (bfd_byte *) data + reloc_entry->address);
+ if (relocateable)
+ reloc_entry->address += input_section->output_offset;
+
+ return bfd_reloc_ok;
+}
+
+static bfd_reloc_status_type
+gprel32_with_gp (bfd *abfd, asymbol *symbol, arelent *reloc_entry,
+ asection *input_section, bfd_boolean relocatable,
+ void *data, bfd_vma gp)
+{
+ bfd_vma relocation;
+ bfd_vma 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 > bfd_get_section_limit (abfd, input_section))
+ return bfd_reloc_outofrange;
+
+ /* Set val to the offset into the section or symbol. */
+ val = reloc_entry->addend;
+
+ if (reloc_entry->howto->partial_inplace)
+ val += bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
+
+ /* Adjust val for the final section location and GP value. If we
+ are producing relocatable output, we don't want to do this for
+ an external symbol. */
+ if (! relocatable
+ || (symbol->flags & BSF_SECTION_SYM) != 0)
+ val += relocation - gp;
+
+ if (reloc_entry->howto->partial_inplace)
+ bfd_put_32 (abfd, val, (bfd_byte *) data + reloc_entry->address);
+ else
+ reloc_entry->addend = val;
+
+ if (relocatable)
+ reloc_entry->address += input_section->output_offset;
+
+ return bfd_reloc_ok;
+}
+
+static bfd_reloc_status_type
+score_elf_gprel15_reloc (bfd *abfd,
+ arelent *reloc_entry,
+ asymbol *symbol,
+ void * data,
+ asection *input_section,
+ bfd *output_bfd,
+ char **error_message)
+{
+ bfd_boolean relocateable;
+ bfd_reloc_status_type ret;
+ bfd_vma gp;
+
+ 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 = score_elf_final_gp (output_bfd, symbol, relocateable, error_message, &gp);
+ if (ret != bfd_reloc_ok)
+ return ret;
+
+ return score_elf_gprel15_with_gp (abfd, symbol, reloc_entry,
+ input_section, relocateable, data, gp);
+}
+
+/* Do a R_SCORE_GPREL32 relocation. This is a 32 bit value which must
+ become the offset from the gp register. */
+
+static bfd_reloc_status_type
+score_elf_gprel32_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
+ void *data, asection *input_section, bfd *output_bfd,
+ char **error_message)
+{
+ bfd_boolean relocatable;
+ bfd_reloc_status_type ret;
+ bfd_vma gp;
+
+ /* R_SCORE_GPREL32 relocations are defined for local symbols only. */
+ if (output_bfd != NULL
+ && (symbol->flags & BSF_SECTION_SYM) == 0
+ && (symbol->flags & BSF_LOCAL) != 0)
+ {
+ *error_message = (char *)
+ _("32bits gp relative relocation occurs for an external symbol");
+ return bfd_reloc_outofrange;
+ }
+
+ if (output_bfd != NULL)
+ relocatable = TRUE;
+ else
+ {
+ relocatable = FALSE;
+ output_bfd = symbol->section->output_section->owner;
+ }
+
+ ret = score_elf_final_gp (output_bfd, symbol, relocatable, error_message, &gp);
+ if (ret != bfd_reloc_ok)
+ return ret;
+
+ gp = 0;
+ return gprel32_with_gp (abfd, symbol, reloc_entry, input_section,
+ relocatable, data, gp);
+}
+
+/* A howto special_function for R_SCORE_GOT15 relocations. This is just
+ like any other 16-bit relocation when applied to global symbols, but is
+ treated in the same as R_SCORE_HI16 when applied to local symbols. */
+
+static bfd_reloc_status_type
+score_elf_got15_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
+ void *data, asection *input_section,
+ bfd *output_bfd, char **error_message)
+{
+ if ((symbol->flags & (BSF_GLOBAL | BSF_WEAK)) != 0
+ || bfd_is_und_section (bfd_get_section (symbol))
+ || bfd_is_com_section (bfd_get_section (symbol)))
+ /* The relocation is against a global symbol. */
+ return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
+ input_section, output_bfd,
+ error_message);
+
+ return score_elf_hi16_reloc (abfd, reloc_entry, symbol, data,
+ input_section, output_bfd, error_message);
+}
+
+static bfd_reloc_status_type
+score_elf_got_lo16_reloc (bfd *abfd,
+ arelent *reloc_entry,
+ asymbol *symbol ATTRIBUTE_UNUSED,
+ void * data,
+ asection *input_section,
+ bfd *output_bfd ATTRIBUTE_UNUSED,
+ char **error_message ATTRIBUTE_UNUSED)
+{
+ bfd_vma addend = 0, offset = 0;
+ signed long val;
+ signed long hi16_offset, hi16_value, uvalue;
+
+ hi16_value = bfd_get_32 (abfd, hi16_rel_addr);
+ hi16_offset = ((((hi16_value >> 16) & 0x3) << 15) | (hi16_value & 0x7fff)) >> 1;
+ addend = bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
+ offset = ((((addend >> 16) & 0x3) << 15) | (addend & 0x7fff)) >> 1;
+ val = reloc_entry->addend;
+ if (reloc_entry->address > input_section->size)
+ return bfd_reloc_outofrange;
+ uvalue = ((hi16_offset << 16) | (offset & 0xffff)) + val;
+ if ((uvalue > -0x8000) && (uvalue < 0x7fff))
+ hi16_offset = 0;
+ else
+ hi16_offset = (uvalue >> 16) & 0x7fff;
+ hi16_value = (hi16_value & ~0x37fff) | (hi16_offset & 0x7fff) | ((hi16_offset << 1) & 0x30000);
+ bfd_put_32 (abfd, hi16_value, hi16_rel_addr);
+ offset = (uvalue & 0xffff) << 1;
+ addend = (addend & ~0x37fff) | (offset & 0x7fff) | ((offset << 1) & 0x30000);
+ bfd_put_32 (abfd, addend, (bfd_byte *) data + reloc_entry->address);
+ return bfd_reloc_ok;
+}
+
+static reloc_howto_type elf32_score_howto_table[] =
+{
+ /* No relocation. */
+ HOWTO (R_SCORE_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_SCORE_NONE", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* R_SCORE_HI16 */
+ HOWTO (R_SCORE_HI16, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 1, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ score_elf_hi16_reloc, /* special_function */
+ "R_SCORE_HI16", /* name */
+ TRUE, /* partial_inplace */
+ 0x37fff, /* src_mask */
+ 0x37fff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* R_SCORE_LO16 */
+ HOWTO (R_SCORE_LO16, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 1, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ score_elf_lo16_reloc, /* special_function */
+ "R_SCORE_LO16", /* name */
+ TRUE, /* partial_inplace */
+ 0x37fff, /* src_mask */
+ 0x37fff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* R_SCORE_BCMP */
+ HOWTO (R_SCORE_BCMP, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 1, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SCORE_BCMP", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_SCORE_24, /* type */
+ 1, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 24, /* bitsize */
+ FALSE, /* pc_relative */
+ 1, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SCORE_24", /* name */
+ FALSE, /* partial_inplace */
+ 0x3ff7fff, /* src_mask */
+ 0x3ff7fff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /*R_SCORE_PC19 */
+ HOWTO (R_SCORE_PC19, /* type */
+ 1, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 19, /* bitsize */
+ TRUE, /* pc_relative */
+ 1, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SCORE_PC19", /* name */
+ FALSE, /* partial_inplace */
+ 0x3ff03fe, /* src_mask */
+ 0x3ff03fe, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /*R_SCORE16_11 */
+ HOWTO (R_SCORE16_11, /* type */
+ 1, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 11, /* bitsize */
+ FALSE, /* pc_relative */
+ 1, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SCORE16_11", /* name */
+ FALSE, /* partial_inplace */
+ 0x000000ffe, /* src_mask */
+ 0x000000ffe, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* R_SCORE16_PC8 */
+ HOWTO (R_SCORE16_PC8, /* type */
+ 1, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 8, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SCORE16_PC8", /* name */
+ FALSE, /* partial_inplace */
+ 0x000000ff, /* src_mask */
+ 0x000000ff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* 32 bit absolute */
+ HOWTO (R_SCORE_ABS32, /* type 8 */
+ 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_SCORE_ABS32", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* 16 bit absolute */
+ HOWTO (R_SCORE_ABS16, /* type 11 */
+ 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_SCORE_ABS16", /* name */
+ FALSE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* R_SCORE_DUMMY2 */
+ HOWTO (R_SCORE_DUMMY2, /* 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_SCORE_DUMMY2", /* name */
+ TRUE, /* partial_inplace */
+ 0x00007fff, /* src_mask */
+ 0x00007fff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* R_SCORE_GP15 */
+ HOWTO (R_SCORE_GP15, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ score_elf_gprel15_reloc,/* special_function */
+ "R_SCORE_GP15", /* name */
+ TRUE, /* partial_inplace */
+ 0x00007fff, /* src_mask */
+ 0x00007fff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* GNU extension to record C++ vtable hierarchy. */
+ HOWTO (R_SCORE_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_SCORE_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_SCORE_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_SCORE_GNU_VTENTRY", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Reference to global offset table. */
+ HOWTO (R_SCORE_GOT15, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ score_elf_got15_reloc, /* special_function */
+ "R_SCORE_GOT15", /* name */
+ TRUE, /* partial_inplace */
+ 0x00007fff, /* src_mask */
+ 0x00007fff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Low 16 bits of displacement in global offset table. */
+ HOWTO (R_SCORE_GOT_LO16, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 1, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ score_elf_got_lo16_reloc, /* special_function */
+ "R_SCORE_GOT_LO16", /* name */
+ TRUE, /* partial_inplace */
+ 0x37ffe, /* src_mask */
+ 0x37ffe, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* 15 bit call through global offset table. */
+ HOWTO (R_SCORE_CALL15, /* 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_SCORE_CALL15", /* name */
+ TRUE, /* partial_inplace */
+ 0x00007fff, /* src_mask */
+ 0x00007fff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* 32 bit GP relative reference. */
+ HOWTO (R_SCORE_GPREL32, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ score_elf_gprel32_reloc, /* special_function */
+ "R_SCORE_GPREL32", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* 32 bit symbol relative relocation. */
+ HOWTO (R_SCORE_REL32, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SCORE_REL32", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* R_SCORE_DUMMY_HI16 */
+ HOWTO (R_SCORE_DUMMY_HI16, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 1, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ score_elf_hi16_reloc, /* special_function */
+ "R_SCORE_DUMMY_HI16", /* name */
+ TRUE, /* partial_inplace */
+ 0x37fff, /* src_mask */
+ 0x37fff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+};
+
+struct score_reloc_map
+{
+ bfd_reloc_code_real_type bfd_reloc_val;
+ unsigned char elf_reloc_val;
+};
+
+static const struct score_reloc_map elf32_score_reloc_map[] =
+{
+ {BFD_RELOC_NONE, R_SCORE_NONE},
+ {BFD_RELOC_HI16_S, R_SCORE_HI16},
+ {BFD_RELOC_LO16, R_SCORE_LO16},
+ {BFD_RELOC_SCORE_BCMP, R_SCORE_BCMP},
+ {BFD_RELOC_SCORE_JMP, R_SCORE_24},
+ {BFD_RELOC_SCORE_BRANCH, R_SCORE_PC19},
+ {BFD_RELOC_SCORE16_JMP, R_SCORE16_11},
+ {BFD_RELOC_SCORE16_BRANCH, R_SCORE16_PC8},
+ {BFD_RELOC_32, R_SCORE_ABS32},
+ {BFD_RELOC_16, R_SCORE_ABS16},
+ {BFD_RELOC_SCORE_DUMMY2, R_SCORE_DUMMY2},
+ {BFD_RELOC_SCORE_GPREL15, R_SCORE_GP15},
+ {BFD_RELOC_VTABLE_INHERIT, R_SCORE_GNU_VTINHERIT},
+ {BFD_RELOC_VTABLE_ENTRY, R_SCORE_GNU_VTENTRY},
+ {BFD_RELOC_SCORE_GOT15, R_SCORE_GOT15},
+ {BFD_RELOC_SCORE_GOT_LO16, R_SCORE_GOT_LO16},
+ {BFD_RELOC_SCORE_CALL15, R_SCORE_CALL15},
+ {BFD_RELOC_GPREL32, R_SCORE_GPREL32},
+ {BFD_RELOC_32_PCREL, R_SCORE_REL32},
+ {BFD_RELOC_SCORE_DUMMY_HI16, R_SCORE_DUMMY_HI16},
+};
+
+static INLINE hashval_t
+score_elf_hash_bfd_vma (bfd_vma addr)
+{
+#ifdef BFD64
+ return addr + (addr >> 32);
+#else
+ return addr;
+#endif
+}
+
+/* got_entries only match if they're identical, except for gotidx, so
+ use all fields to compute the hash, and compare the appropriate
+ union members. */
+
+static hashval_t
+score_elf_got_entry_hash (const void *entry_)
+{
+ const struct score_got_entry *entry = (struct score_got_entry *) entry_;
+
+ return entry->symndx
+ + (! entry->abfd ? score_elf_hash_bfd_vma (entry->d.address)
+ : entry->abfd->id
+ + (entry->symndx >= 0 ? score_elf_hash_bfd_vma (entry->d.addend)
+ : entry->d.h->root.root.root.hash));
+}
+
+static int
+score_elf_got_entry_eq (const void *entry1, const void *entry2)
+{
+ const struct score_got_entry *e1 = (struct score_got_entry *) entry1;
+ const struct score_got_entry *e2 = (struct score_got_entry *) entry2;
+
+ return e1->abfd == e2->abfd && e1->symndx == e2->symndx
+ && (! e1->abfd ? e1->d.address == e2->d.address
+ : e1->symndx >= 0 ? e1->d.addend == e2->d.addend
+ : e1->d.h == e2->d.h);
+}
+
+/* If H needs a GOT entry, assign it the highest available dynamic
+ index. Otherwise, assign it the lowest available dynamic
+ index. */
+
+static bfd_boolean
+score_elf_sort_hash_table_f (struct score_elf_link_hash_entry *h, void *data)
+{
+ struct score_elf_hash_sort_data *hsd = data;
+
+ /* Symbols without dynamic symbol table entries aren't interesting at all. */
+ if (h->root.dynindx == -1)
+ return TRUE;
+
+ /* Global symbols that need GOT entries that are not explicitly
+ referenced are marked with got offset 2. Those that are
+ referenced get a 1, and those that don't need GOT entries get
+ -1. */
+ if (h->root.got.offset == 2)
+ {
+ if (hsd->max_unref_got_dynindx == hsd->min_got_dynindx)
+ hsd->low = (struct elf_link_hash_entry *) h;
+ h->root.dynindx = hsd->max_unref_got_dynindx++;
+ }
+ else if (h->root.got.offset != 1)
+ h->root.dynindx = hsd->max_non_got_dynindx++;
+ else
+ {
+ h->root.dynindx = --hsd->min_got_dynindx;
+ hsd->low = (struct elf_link_hash_entry *) h;
+ }
+
+ return TRUE;
+}
+
+static asection *
+score_elf_got_section (bfd *abfd, bfd_boolean maybe_excluded)
+{
+ asection *sgot = bfd_get_linker_section (abfd, ".got");
+
+ if (sgot == NULL || (! maybe_excluded && (sgot->flags & SEC_EXCLUDE) != 0))
+ return NULL;
+ return sgot;
+}
+
+/* Returns the GOT information associated with the link indicated by
+ INFO. If SGOTP is non-NULL, it is filled in with the GOT section. */
+
+static struct score_got_info *
+score_elf_got_info (bfd *abfd, asection **sgotp)
+{
+ asection *sgot;
+ struct score_got_info *g;
+
+ sgot = score_elf_got_section (abfd, TRUE);
+ BFD_ASSERT (sgot != NULL);
+ BFD_ASSERT (elf_section_data (sgot) != NULL);
+ g = score_elf_section_data (sgot)->u.got_info;
+ BFD_ASSERT (g != NULL);
+
+ if (sgotp)
+ *sgotp = sgot;
+ return g;
+}
+
+/* Sort the dynamic symbol table so that symbols that need GOT entries
+ appear towards the end. This reduces the amount of GOT space
+ required. MAX_LOCAL is used to set the number of local symbols
+ known to be in the dynamic symbol table. During
+ s7_bfd_score_elf_size_dynamic_sections, this value is 1. Afterward, the
+ section symbols are added and the count is higher. */
+
+static bfd_boolean
+score_elf_sort_hash_table (struct bfd_link_info *info,
+ unsigned long max_local)
+{
+ struct score_elf_hash_sort_data hsd;
+ struct score_got_info *g;
+ bfd *dynobj;
+
+ dynobj = elf_hash_table (info)->dynobj;
+
+ g = score_elf_got_info (dynobj, NULL);
+
+ hsd.low = NULL;
+ hsd.max_unref_got_dynindx =
+ hsd.min_got_dynindx = elf_hash_table (info)->dynsymcount
+ /* In the multi-got case, assigned_gotno of the master got_info
+ indicate the number of entries that aren't referenced in the
+ primary GOT, but that must have entries because there are
+ dynamic relocations that reference it. Since they aren't
+ referenced, we move them to the end of the GOT, so that they
+ don't prevent other entries that are referenced from getting
+ too large offsets. */
+ - (g->next ? g->assigned_gotno : 0);
+ hsd.max_non_got_dynindx = max_local;
+ score_elf_link_hash_traverse (elf_hash_table (info),
+ score_elf_sort_hash_table_f,
+ &hsd);
+
+ /* There should have been enough room in the symbol table to
+ accommodate both the GOT and non-GOT symbols. */
+ BFD_ASSERT (hsd.max_non_got_dynindx <= hsd.min_got_dynindx);
+ BFD_ASSERT ((unsigned long) hsd.max_unref_got_dynindx
+ <= elf_hash_table (info)->dynsymcount);
+
+ /* Now we know which dynamic symbol has the lowest dynamic symbol
+ table index in the GOT. */
+ g->global_gotsym = hsd.low;
+
+ return TRUE;
+}
+
+/* Returns the first relocation of type r_type found, beginning with
+ RELOCATION. RELEND is one-past-the-end of the relocation table. */
+
+static const Elf_Internal_Rela *
+score_elf_next_relocation (bfd *abfd ATTRIBUTE_UNUSED, unsigned int r_type,
+ const Elf_Internal_Rela *relocation,
+ const Elf_Internal_Rela *relend)
+{
+ while (relocation < relend)
+ {
+ if (ELF32_R_TYPE (relocation->r_info) == r_type)
+ return relocation;
+
+ ++relocation;
+ }
+
+ /* We didn't find it. */
+ bfd_set_error (bfd_error_bad_value);
+ return NULL;
+}
+
+/* This function is called via qsort() to sort the dynamic relocation
+ entries by increasing r_symndx value. */
+static int
+score_elf_sort_dynamic_relocs (const void *arg1, const void *arg2)
+{
+ Elf_Internal_Rela int_reloc1;
+ Elf_Internal_Rela int_reloc2;
+
+ bfd_elf32_swap_reloc_in (reldyn_sorting_bfd, arg1, &int_reloc1);
+ bfd_elf32_swap_reloc_in (reldyn_sorting_bfd, arg2, &int_reloc2);
+
+ return (ELF32_R_SYM (int_reloc1.r_info) - ELF32_R_SYM (int_reloc2.r_info));
+}
+
+/* Return whether a relocation is against a local symbol. */
+static bfd_boolean
+score_elf_local_relocation_p (bfd *input_bfd,
+ const Elf_Internal_Rela *relocation,
+ asection **local_sections,
+ bfd_boolean check_forced)
+{
+ unsigned long r_symndx;
+ Elf_Internal_Shdr *symtab_hdr;
+ struct score_elf_link_hash_entry *h;
+ size_t extsymoff;
+
+ r_symndx = ELF32_R_SYM (relocation->r_info);
+ symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
+ extsymoff = (elf_bad_symtab (input_bfd)) ? 0 : symtab_hdr->sh_info;
+
+ if (r_symndx < extsymoff)
+ return TRUE;
+ if (elf_bad_symtab (input_bfd) && local_sections[r_symndx] != NULL)
+ return TRUE;
+
+ if (check_forced)
+ {
+ /* Look up the hash table to check whether the symbol was forced local. */
+ h = (struct score_elf_link_hash_entry *)
+ elf_sym_hashes (input_bfd) [r_symndx - extsymoff];
+ /* Find the real hash-table entry for this symbol. */
+ while (h->root.root.type == bfd_link_hash_indirect
+ || h->root.root.type == bfd_link_hash_warning)
+ h = (struct score_elf_link_hash_entry *) h->root.root.u.i.link;
+ if (h->root.forced_local)
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/* Returns the dynamic relocation section for DYNOBJ. */
+
+static asection *
+score_elf_rel_dyn_section (bfd *dynobj, bfd_boolean create_p)
+{
+ static const char dname[] = ".rel.dyn";
+ asection *sreloc;
+
+ sreloc = bfd_get_linker_section (dynobj, dname);
+ if (sreloc == NULL && create_p)
+ {
+ sreloc = bfd_make_section_anyway_with_flags (dynobj, dname,
+ (SEC_ALLOC
+ | SEC_LOAD
+ | SEC_HAS_CONTENTS
+ | SEC_IN_MEMORY
+ | SEC_LINKER_CREATED
+ | SEC_READONLY));
+ if (sreloc == NULL
+ || ! bfd_set_section_alignment (dynobj, sreloc,
+ SCORE_ELF_LOG_FILE_ALIGN (dynobj)))
+ return NULL;
+ }
+ return sreloc;
+}
+
+static void
+score_elf_allocate_dynamic_relocations (bfd *abfd, unsigned int n)
+{
+ asection *s;
+
+ s = score_elf_rel_dyn_section (abfd, FALSE);
+ BFD_ASSERT (s != NULL);
+
+ if (s->size == 0)
+ {
+ /* Make room for a null element. */
+ s->size += SCORE_ELF_REL_SIZE (abfd);
+ ++s->reloc_count;
+ }
+ s->size += n * SCORE_ELF_REL_SIZE (abfd);
+}
+
+/* Create a rel.dyn relocation for the dynamic linker to resolve. REL
+ is the original relocation, which is now being transformed into a
+ dynamic relocation. The ADDENDP is adjusted if necessary; the
+ caller should store the result in place of the original addend. */
+
+static bfd_boolean
+score_elf_create_dynamic_relocation (bfd *output_bfd,
+ struct bfd_link_info *info,
+ const Elf_Internal_Rela *rel,
+ struct score_elf_link_hash_entry *h,
+ bfd_vma symbol,
+ bfd_vma *addendp, asection *input_section)
+{
+ Elf_Internal_Rela outrel[3];
+ asection *sreloc;
+ bfd *dynobj;
+ int r_type;
+ long indx;
+ bfd_boolean defined_p;
+
+ r_type = ELF32_R_TYPE (rel->r_info);
+ dynobj = elf_hash_table (info)->dynobj;
+ sreloc = score_elf_rel_dyn_section (dynobj, FALSE);
+ BFD_ASSERT (sreloc != NULL);
+ BFD_ASSERT (sreloc->contents != NULL);
+ BFD_ASSERT (sreloc->reloc_count * SCORE_ELF_REL_SIZE (output_bfd) < sreloc->size);
+
+ outrel[0].r_offset =
+ _bfd_elf_section_offset (output_bfd, info, input_section, rel[0].r_offset);
+ outrel[1].r_offset =
+ _bfd_elf_section_offset (output_bfd, info, input_section, rel[1].r_offset);
+ outrel[2].r_offset =
+ _bfd_elf_section_offset (output_bfd, info, input_section, rel[2].r_offset);
+
+ if (outrel[0].r_offset == MINUS_ONE)
+ /* The relocation field has been deleted. */
+ return TRUE;
+
+ if (outrel[0].r_offset == MINUS_TWO)
+ {
+ /* The relocation field has been converted into a relative value of
+ some sort. Functions like _bfd_elf_write_section_eh_frame expect
+ the field to be fully relocated, so add in the symbol's value. */
+ *addendp += symbol;
+ return TRUE;
+ }
+
+ /* We must now calculate the dynamic symbol table index to use
+ in the relocation. */
+ if (h != NULL
+ && (! info->symbolic || !h->root.def_regular)
+ /* h->root.dynindx may be -1 if this symbol was marked to
+ become local. */
+ && h->root.dynindx != -1)
+ {
+ indx = h->root.dynindx;
+ /* ??? glibc's ld.so just adds the final GOT entry to the
+ relocation field. It therefore treats relocs against
+ defined symbols in the same way as relocs against
+ undefined symbols. */
+ defined_p = FALSE;
+ }
+ else
+ {
+ indx = 0;
+ defined_p = TRUE;
+ }
+
+ /* If the relocation was previously an absolute relocation and
+ this symbol will not be referred to by the relocation, we must
+ adjust it by the value we give it in the dynamic symbol table.
+ Otherwise leave the job up to the dynamic linker. */
+ if (defined_p && r_type != R_SCORE_REL32)
+ *addendp += symbol;
+
+ /* The relocation is always an REL32 relocation because we don't
+ know where the shared library will wind up at load-time. */
+ outrel[0].r_info = ELF32_R_INFO ((unsigned long) indx, R_SCORE_REL32);
+
+ /* For strict adherence to the ABI specification, we should
+ generate a R_SCORE_64 relocation record by itself before the
+ _REL32/_64 record as well, such that the addend is read in as
+ a 64-bit value (REL32 is a 32-bit relocation, after all).
+ However, since none of the existing ELF64 SCORE dynamic
+ loaders seems to care, we don't waste space with these
+ artificial relocations. If this turns out to not be true,
+ score_elf_allocate_dynamic_relocations() should be tweaked so
+ as to make room for a pair of dynamic relocations per
+ invocation if ABI_64_P, and here we should generate an
+ additional relocation record with R_SCORE_64 by itself for a
+ NULL symbol before this relocation record. */
+ outrel[1].r_info = ELF32_R_INFO (0, R_SCORE_NONE);
+ outrel[2].r_info = ELF32_R_INFO (0, R_SCORE_NONE);
+
+ /* Adjust the output offset of the relocation to reference the
+ correct location in the output file. */
+ outrel[0].r_offset += (input_section->output_section->vma
+ + input_section->output_offset);
+ outrel[1].r_offset += (input_section->output_section->vma
+ + input_section->output_offset);
+ outrel[2].r_offset += (input_section->output_section->vma
+ + input_section->output_offset);
+
+ /* Put the relocation back out. We have to use the special
+ relocation outputter in the 64-bit case since the 64-bit
+ relocation format is non-standard. */
+ bfd_elf32_swap_reloc_out
+ (output_bfd, &outrel[0],
+ (sreloc->contents + sreloc->reloc_count * sizeof (Elf32_External_Rel)));
+
+ /* We've now added another relocation. */
+ ++sreloc->reloc_count;
+
+ /* Make sure the output section is writable. The dynamic linker
+ will be writing to it. */
+ elf_section_data (input_section->output_section)->this_hdr.sh_flags |= SHF_WRITE;
+
+ return TRUE;
+}
+
+static bfd_boolean
+score_elf_create_got_section (bfd *abfd,
+ struct bfd_link_info *info,
+ bfd_boolean maybe_exclude)
+{
+ flagword flags;
+ asection *s;
+ struct elf_link_hash_entry *h;
+ struct bfd_link_hash_entry *bh;
+ struct score_got_info *g;
+ bfd_size_type amt;
+
+ /* This function may be called more than once. */
+ s = score_elf_got_section (abfd, TRUE);
+ if (s)
+ {
+ if (! maybe_exclude)
+ s->flags &= ~SEC_EXCLUDE;
+ return TRUE;
+ }
+
+ flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_LINKER_CREATED);
+
+ if (maybe_exclude)
+ flags |= SEC_EXCLUDE;
+
+ /* We have to use an alignment of 2**4 here because this is hardcoded
+ in the function stub generation and in the linker script. */
+ s = bfd_make_section_anyway_with_flags (abfd, ".got", flags);
+ if (s == NULL
+ || ! 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. */
+ bh = NULL;
+ if (! (_bfd_generic_link_add_one_symbol
+ (info, abfd, "_GLOBAL_OFFSET_TABLE_", BSF_GLOBAL, s,
+ 0, NULL, FALSE, get_elf_backend_data (abfd)->collect, &bh)))
+ return FALSE;
+
+ h = (struct elf_link_hash_entry *) bh;
+ h->non_elf = 0;
+ h->def_regular = 1;
+ h->type = STT_OBJECT;
+
+ if (info->shared && ! bfd_elf_link_record_dynamic_symbol (info, h))
+ return FALSE;
+
+ amt = sizeof (struct score_got_info);
+ g = bfd_alloc (abfd, amt);
+ if (g == NULL)
+ return FALSE;
+
+ g->global_gotsym = NULL;
+ g->global_gotno = 0;
+
+ g->local_gotno = SCORE_RESERVED_GOTNO;
+ g->assigned_gotno = SCORE_RESERVED_GOTNO;
+ g->next = NULL;
+
+ g->got_entries = htab_try_create (1, score_elf_got_entry_hash,
+ score_elf_got_entry_eq, NULL);
+ if (g->got_entries == NULL)
+ return FALSE;
+ score_elf_section_data (s)->u.got_info = g;
+ score_elf_section_data (s)->elf.this_hdr.sh_flags |= SHF_ALLOC | SHF_WRITE | SHF_SCORE_GPREL;
+
+ return TRUE;
+}
+
+/* Calculate the %high function. */
+
+static bfd_vma
+score_elf_high (bfd_vma value)
+{
+ return ((value + (bfd_vma) 0x8000) >> 16) & 0xffff;
+}
+
+/* Create a local GOT entry for VALUE. Return the index of the entry,
+ or -1 if it could not be created. */
+
+static struct score_got_entry *
+score_elf_create_local_got_entry (bfd *abfd,
+ bfd *ibfd ATTRIBUTE_UNUSED,
+ struct score_got_info *gg,
+ asection *sgot, bfd_vma value,
+ unsigned long r_symndx ATTRIBUTE_UNUSED,
+ struct score_elf_link_hash_entry *h ATTRIBUTE_UNUSED,
+ int r_type ATTRIBUTE_UNUSED)
+{
+ struct score_got_entry entry, **loc;
+ struct score_got_info *g;
+
+ entry.abfd = NULL;
+ entry.symndx = -1;
+ entry.d.address = value;
+
+ g = gg;
+ loc = (struct score_got_entry **) htab_find_slot (g->got_entries, &entry, INSERT);
+ if (*loc)
+ return *loc;
+
+ entry.gotidx = SCORE_ELF_GOT_SIZE (abfd) * g->assigned_gotno++;
+
+ *loc = bfd_alloc (abfd, sizeof entry);
+
+ if (! *loc)
+ return NULL;
+
+ memcpy (*loc, &entry, sizeof entry);
+
+ if (g->assigned_gotno >= g->local_gotno)
+ {
+ (*loc)->gotidx = -1;
+ /* We didn't allocate enough space in the GOT. */
+ (*_bfd_error_handler)
+ (_("not enough GOT space for local GOT entries"));
+ bfd_set_error (bfd_error_bad_value);
+ return NULL;
+ }
+
+ bfd_put_32 (abfd, value, (sgot->contents + entry.gotidx));
+
+ return *loc;
+}
+
+/* Find a GOT entry whose higher-order 16 bits are the same as those
+ for value. Return the index into the GOT for this entry. */
+
+static bfd_vma
+score_elf_got16_entry (bfd *abfd, bfd *ibfd, struct bfd_link_info *info,
+ bfd_vma value, bfd_boolean external)
+{
+ asection *sgot;
+ struct score_got_info *g;
+ struct score_got_entry *entry;
+
+ if (!external)
+ {
+ /* Although the ABI says that it is "the high-order 16 bits" that we
+ want, it is really the %high value. The complete value is
+ calculated with a `addiu' of a LO16 relocation, just as with a
+ HI16/LO16 pair. */
+ value = score_elf_high (value) << 16;
+ }
+
+ g = score_elf_got_info (elf_hash_table (info)->dynobj, &sgot);
+
+ entry = score_elf_create_local_got_entry (abfd, ibfd, g, sgot, value, 0, NULL,
+ R_SCORE_GOT15);
+ if (entry)
+ return entry->gotidx;
+ else
+ return MINUS_ONE;
+}
+
+void
+s7_bfd_score_elf_hide_symbol (struct bfd_link_info *info,
+ struct elf_link_hash_entry *entry,
+ bfd_boolean force_local)
+{
+ bfd *dynobj;
+ asection *got;
+ struct score_got_info *g;
+ struct score_elf_link_hash_entry *h;
+
+ h = (struct score_elf_link_hash_entry *) entry;
+ if (h->forced_local)
+ return;
+ h->forced_local = TRUE;
+
+ dynobj = elf_hash_table (info)->dynobj;
+ if (dynobj != NULL && force_local)
+ {
+ got = score_elf_got_section (dynobj, FALSE);
+ if (got == NULL)
+ return;
+ g = score_elf_section_data (got)->u.got_info;
+
+ if (g->next)
+ {
+ struct score_got_entry e;
+ struct score_got_info *gg = g;
+
+ /* Since we're turning what used to be a global symbol into a
+ local one, bump up the number of local entries of each GOT
+ that had an entry for it. This will automatically decrease
+ the number of global entries, since global_gotno is actually
+ the upper limit of global entries. */
+ e.abfd = dynobj;
+ e.symndx = -1;
+ e.d.h = h;
+
+ for (g = g->next; g != gg; g = g->next)
+ if (htab_find (g->got_entries, &e))
+ {
+ BFD_ASSERT (g->global_gotno > 0);
+ g->local_gotno++;
+ g->global_gotno--;
+ }
+
+ /* If this was a global symbol forced into the primary GOT, we
+ no longer need an entry for it. We can't release the entry
+ at this point, but we must at least stop counting it as one
+ of the symbols that required a forced got entry. */
+ if (h->root.got.offset == 2)
+ {
+ BFD_ASSERT (gg->assigned_gotno > 0);
+ gg->assigned_gotno--;
+ }
+ }
+ else if (g->global_gotno == 0 && g->global_gotsym == NULL)
+ /* If we haven't got through GOT allocation yet, just bump up the
+ number of local entries, as this symbol won't be counted as
+ global. */
+ g->local_gotno++;
+ else if (h->root.got.offset == 1)
+ {
+ /* If we're past non-multi-GOT allocation and this symbol had
+ been marked for a global got entry, give it a local entry
+ instead. */
+ BFD_ASSERT (g->global_gotno > 0);
+ g->local_gotno++;
+ g->global_gotno--;
+ }
+ }
+
+ _bfd_elf_link_hash_hide_symbol (info, &h->root, force_local);
+}
+
+/* If H is a symbol that needs a global GOT entry, but has a dynamic
+ symbol table index lower than any we've seen to date, record it for
+ posterity. */
+
+static bfd_boolean
+score_elf_record_global_got_symbol (struct elf_link_hash_entry *h,
+ bfd *abfd,
+ struct bfd_link_info *info,
+ struct score_got_info *g)
+{
+ struct score_got_entry entry, **loc;
+
+ /* A global symbol in the GOT must also be in the dynamic symbol table. */
+ if (h->dynindx == -1)
+ {
+ switch (ELF_ST_VISIBILITY (h->other))
+ {
+ case STV_INTERNAL:
+ case STV_HIDDEN:
+ s7_bfd_score_elf_hide_symbol (info, h, TRUE);
+ break;
+ }
+ if (!bfd_elf_link_record_dynamic_symbol (info, h))
+ return FALSE;
+ }
+
+ entry.abfd = abfd;
+ entry.symndx = -1;
+ entry.d.h = (struct score_elf_link_hash_entry *) h;
+
+ loc = (struct score_got_entry **) htab_find_slot (g->got_entries, &entry, INSERT);
+
+ /* If we've already marked this entry as needing GOT space, we don't
+ need to do it again. */
+ if (*loc)
+ return TRUE;
+
+ *loc = bfd_alloc (abfd, sizeof entry);
+ if (! *loc)
+ return FALSE;
+
+ entry.gotidx = -1;
+
+ memcpy (*loc, &entry, sizeof (entry));
+
+ if (h->got.offset != MINUS_ONE)
+ return TRUE;
+
+ /* By setting this to a value other than -1, we are indicating that
+ there needs to be a GOT entry for H. Avoid using zero, as the
+ generic ELF copy_indirect_symbol tests for <= 0. */
+ h->got.offset = 1;
+
+ return TRUE;
+}
+
+/* Reserve space in G for a GOT entry containing the value of symbol
+ SYMNDX in input bfd ABDF, plus ADDEND. */
+
+static bfd_boolean
+score_elf_record_local_got_symbol (bfd *abfd,
+ long symndx,
+ bfd_vma addend,
+ struct score_got_info *g)
+{
+ struct score_got_entry entry, **loc;
+
+ entry.abfd = abfd;
+ entry.symndx = symndx;
+ entry.d.addend = addend;
+ loc = (struct score_got_entry **) htab_find_slot (g->got_entries, &entry, INSERT);
+
+ if (*loc)
+ return TRUE;
+
+ entry.gotidx = g->local_gotno++;
+
+ *loc = bfd_alloc (abfd, sizeof(entry));
+ if (! *loc)
+ return FALSE;
+
+ memcpy (*loc, &entry, sizeof (entry));
+
+ return TRUE;
+}
+
+/* Returns the GOT offset at which the indicated address can be found.
+ If there is not yet a GOT entry for this value, create one.
+ Returns -1 if no satisfactory GOT offset can be found. */
+
+static bfd_vma
+score_elf_local_got_index (bfd *abfd, bfd *ibfd, struct bfd_link_info *info,
+ bfd_vma value, unsigned long r_symndx,
+ struct score_elf_link_hash_entry *h, int r_type)
+{
+ asection *sgot;
+ struct score_got_info *g;
+ struct score_got_entry *entry;
+
+ g = score_elf_got_info (elf_hash_table (info)->dynobj, &sgot);
+
+ entry = score_elf_create_local_got_entry (abfd, ibfd, g, sgot, value,
+ r_symndx, h, r_type);
+ if (!entry)
+ return MINUS_ONE;
+
+ else
+ return entry->gotidx;
+}
+
+/* Returns the GOT index for the global symbol indicated by H. */
+
+static bfd_vma
+score_elf_global_got_index (bfd *abfd, struct elf_link_hash_entry *h)
+{
+ bfd_vma got_index;
+ asection *sgot;
+ struct score_got_info *g;
+ long global_got_dynindx = 0;
+
+ g = score_elf_got_info (abfd, &sgot);
+ if (g->global_gotsym != NULL)
+ global_got_dynindx = g->global_gotsym->dynindx;
+
+ /* Once we determine the global GOT entry with the lowest dynamic
+ symbol table index, we must put all dynamic symbols with greater
+ indices into the GOT. That makes it easy to calculate the GOT
+ offset. */
+ BFD_ASSERT (h->dynindx >= global_got_dynindx);
+ got_index = ((h->dynindx - global_got_dynindx + g->local_gotno) * SCORE_ELF_GOT_SIZE (abfd));
+ BFD_ASSERT (got_index < sgot->size);
+
+ return got_index;
+}
+
+/* Returns the offset for the entry at the INDEXth position in the GOT. */
+
+static bfd_vma
+score_elf_got_offset_from_index (bfd *dynobj,
+ bfd *output_bfd,
+ bfd *input_bfd ATTRIBUTE_UNUSED,
+ bfd_vma got_index)
+{
+ asection *sgot;
+ bfd_vma gp;
+
+ score_elf_got_info (dynobj, &sgot);
+ gp = _bfd_get_gp_value (output_bfd);
+
+ return sgot->output_section->vma + sgot->output_offset + got_index - gp;
+}
+
+/* Follow indirect and warning hash entries so that each got entry
+ points to the final symbol definition. P must point to a pointer
+ to the hash table we're traversing. Since this traversal may
+ modify the hash table, we set this pointer to NULL to indicate
+ we've made a potentially-destructive change to the hash table, so
+ the traversal must be restarted. */
+
+static int
+score_elf_resolve_final_got_entry (void **entryp, void *p)
+{
+ struct score_got_entry *entry = (struct score_got_entry *) *entryp;
+ htab_t got_entries = *(htab_t *) p;
+
+ if (entry->abfd != NULL && entry->symndx == -1)
+ {
+ struct score_elf_link_hash_entry *h = entry->d.h;
+
+ while (h->root.root.type == bfd_link_hash_indirect
+ || h->root.root.type == bfd_link_hash_warning)
+ h = (struct score_elf_link_hash_entry *) h->root.root.u.i.link;
+
+ if (entry->d.h == h)
+ return 1;
+
+ entry->d.h = h;
+
+ /* If we can't find this entry with the new bfd hash, re-insert
+ it, and get the traversal restarted. */
+ if (! htab_find (got_entries, entry))
+ {
+ htab_clear_slot (got_entries, entryp);
+ entryp = htab_find_slot (got_entries, entry, INSERT);
+ if (! *entryp)
+ *entryp = entry;
+ /* Abort the traversal, since the whole table may have
+ moved, and leave it up to the parent to restart the
+ process. */
+ *(htab_t *) p = NULL;
+ return 0;
+ }
+ /* We might want to decrement the global_gotno count, but it's
+ either too early or too late for that at this point. */
+ }
+
+ return 1;
+}
+
+/* Turn indirect got entries in a got_entries table into their final locations. */
+
+static void
+score_elf_resolve_final_got_entries (struct score_got_info *g)
+{
+ htab_t got_entries;
+
+ do
+ {
+ got_entries = g->got_entries;
+
+ htab_traverse (got_entries,
+ score_elf_resolve_final_got_entry,
+ &got_entries);
+ }
+ while (got_entries == NULL);
+}
+
+/* Add INCREMENT to the reloc (of type HOWTO) at ADDRESS. for -r */
+
+static void
+score_elf_add_to_rel (bfd *abfd,
+ bfd_byte *address,
+ reloc_howto_type *howto,
+ bfd_signed_vma increment)
+{
+ bfd_signed_vma addend;
+ bfd_vma contents;
+ unsigned long offset;
+ unsigned long r_type = howto->type;
+ unsigned long hi16_addend, hi16_offset, hi16_value, uvalue;
+
+ contents = bfd_get_32 (abfd, address);
+ /* Get the (signed) value from the instruction. */
+ addend = contents & howto->src_mask;
+ if (addend & ((howto->src_mask + 1) >> 1))
+ {
+ bfd_signed_vma mask;
+
+ mask = -1;
+ mask &= ~howto->src_mask;
+ addend |= mask;
+ }
+ /* Add in the increment, (which is a byte value). */
+ switch (r_type)
+ {
+ case R_SCORE_PC19:
+ offset =
+ (((contents & howto->src_mask) & 0x3ff0000) >> 6) | ((contents & howto->src_mask) & 0x3ff);
+ offset += increment;
+ contents =
+ (contents & ~howto->
+ src_mask) | (((offset << 6) & howto->src_mask) & 0x3ff0000) | (offset & 0x3ff);
+ bfd_put_32 (abfd, contents, address);
+ break;
+ case R_SCORE_HI16:
+ break;
+ case R_SCORE_LO16:
+ hi16_addend = bfd_get_32 (abfd, address - 4);
+ hi16_offset = ((((hi16_addend >> 16) & 0x3) << 15) | (hi16_addend & 0x7fff)) >> 1;
+ offset = ((((contents >> 16) & 0x3) << 15) | (contents & 0x7fff)) >> 1;
+ offset = (hi16_offset << 16) | (offset & 0xffff);
+ uvalue = increment + offset;
+ hi16_offset = (uvalue >> 16) << 1;
+ hi16_value = (hi16_addend & (~(howto->dst_mask)))
+ | (hi16_offset & 0x7fff) | ((hi16_offset << 1) & 0x30000);
+ bfd_put_32 (abfd, hi16_value, address - 4);
+ offset = (uvalue & 0xffff) << 1;
+ contents = (contents & (~(howto->dst_mask))) | (offset & 0x7fff) | ((offset << 1) & 0x30000);
+ bfd_put_32 (abfd, contents, address);
+ break;
+ case R_SCORE_24:
+ offset =
+ (((contents & howto->src_mask) >> 1) & 0x1ff8000) | ((contents & howto->src_mask) & 0x7fff);
+ offset += increment;
+ contents =
+ (contents & ~howto->
+ src_mask) | (((offset << 1) & howto->src_mask) & 0x3ff0000) | (offset & 0x7fff);
+ bfd_put_32 (abfd, contents, address);
+ break;
+ case R_SCORE16_11:
+
+ contents = bfd_get_16 (abfd, address);
+ offset = contents & howto->src_mask;
+ offset += increment;
+ contents = (contents & ~howto->src_mask) | (offset & howto->src_mask);
+ bfd_put_16 (abfd, contents, address);
+
+ break;
+ case R_SCORE16_PC8:
+
+ contents = bfd_get_16 (abfd, address);
+ offset = (contents & howto->src_mask) + ((increment >> 1) & 0xff);
+ contents = (contents & (~howto->src_mask)) | (offset & howto->src_mask);
+ bfd_put_16 (abfd, contents, address);
+
+ break;
+ case R_SCORE_GOT15:
+ case R_SCORE_GOT_LO16:
+ break;
+
+ default:
+ addend += increment;
+ contents = (contents & ~howto->dst_mask) | (addend & howto->dst_mask);
+ bfd_put_32 (abfd, contents, address);
+ break;
+ }
+}
+
+/* Perform a relocation as part of a final link. */
+
+static bfd_reloc_status_type
+score_elf_final_link_relocate (reloc_howto_type *howto,
+ bfd *input_bfd,
+ bfd *output_bfd,
+ asection *input_section,
+ bfd_byte *contents,
+ Elf_Internal_Rela *rel,
+ Elf_Internal_Rela *relocs,
+ bfd_vma symbol,
+ struct bfd_link_info *info,
+ const char *sym_name ATTRIBUTE_UNUSED,
+ int sym_flags ATTRIBUTE_UNUSED,
+ struct score_elf_link_hash_entry *h,
+ Elf_Internal_Sym *local_syms,
+ asection **local_sections,
+ bfd_boolean gp_disp_p)
+{
+ unsigned long r_type;
+ unsigned long r_symndx;
+ bfd_byte *hit_data = contents + rel->r_offset;
+ bfd_vma addend;
+ /* The final GP value to be used for the relocatable, executable, or
+ shared object file being produced. */
+ bfd_vma gp = MINUS_ONE;
+ /* The place (section offset or address) of the storage unit being relocated. */
+ bfd_vma rel_addr;
+ /* The value of GP used to create the relocatable object. */
+ bfd_vma gp0 = MINUS_ONE;
+ /* The offset into the global offset table at which the address of the relocation entry
+ symbol, adjusted by the addend, resides during execution. */
+ bfd_vma g = MINUS_ONE;
+ /* TRUE if the symbol referred to by this relocation is a local symbol. */
+ bfd_boolean local_p;
+ /* The eventual value we will relocate. */
+ bfd_vma value = symbol;
+ unsigned long hi16_addend, hi16_offset, hi16_value, uvalue, offset, abs_value = 0;
+
+ Elf_Internal_Sym *sym = 0;
+ asection *sec = NULL;
+ bfd_boolean merge_p = 0;
+
+
+ if (elf_gp (output_bfd) == 0)
+ {
+ struct bfd_link_hash_entry *bh;
+ asection *o;
+
+ bh = bfd_link_hash_lookup (info->hash, "_gp", 0, 0, 1);
+ if (bh != NULL && bh->type == bfd_link_hash_defined)
+ elf_gp (output_bfd) = (bh->u.def.value
+ + bh->u.def.section->output_section->vma
+ + bh->u.def.section->output_offset);
+ else if (info->relocatable)
+ {
+ bfd_vma lo = -1;
+
+ /* Find the GP-relative section with the lowest offset. */
+ for (o = output_bfd->sections; o != NULL; o = o->next)
+ if (o->vma < lo)
+ lo = o->vma;
+ /* And calculate GP relative to that. */
+ elf_gp (output_bfd) = lo + ELF_SCORE_GP_OFFSET (input_bfd);
+ }
+ 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. */
+ }
+ }
+
+ /* Parse the relocation. */
+ r_symndx = ELF32_R_SYM (rel->r_info);
+ r_type = ELF32_R_TYPE (rel->r_info);
+ rel_addr = (input_section->output_section->vma + input_section->output_offset + rel->r_offset);
+
+ /* For hidden symbol. */
+ local_p = score_elf_local_relocation_p (input_bfd, rel, local_sections, FALSE);
+ if (local_p)
+ {
+ sym = local_syms + r_symndx;
+ sec = local_sections[r_symndx];
+
+ symbol = sec->output_section->vma + sec->output_offset;
+ if (ELF_ST_TYPE (sym->st_info) != STT_SECTION
+ || (sec->flags & SEC_MERGE))
+ symbol += sym->st_value;
+ if ((sec->flags & SEC_MERGE)
+ && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
+ merge_p = 1;
+ }
+
+ if (r_type == R_SCORE_GOT15)
+ {
+ const Elf_Internal_Rela *relend;
+ const Elf_Internal_Rela *lo16_rel;
+ const struct elf_backend_data *bed;
+ bfd_vma lo_value = 0;
+
+ bed = get_elf_backend_data (output_bfd);
+ relend = relocs + input_section->reloc_count * bed->s->int_rels_per_ext_rel;
+ lo16_rel = score_elf_next_relocation (input_bfd, R_SCORE_GOT_LO16, rel, relend);
+ if ((local_p) && (lo16_rel != NULL))
+ {
+ bfd_vma tmp = 0;
+ tmp = bfd_get_32 (input_bfd, contents + lo16_rel->r_offset);
+ lo_value = (((tmp >> 16) & 0x3) << 14) | ((tmp & 0x7fff) >> 1);
+ if (merge_p)
+ {
+ asection *msec = sec;
+ lo_value = _bfd_elf_rel_local_sym (output_bfd, sym, &msec, lo_value);
+ lo_value -= symbol;
+ lo_value += msec->output_section->vma + msec->output_offset;
+ }
+ }
+ addend = lo_value;
+ }
+ else
+ {
+ addend = (bfd_get_32 (input_bfd, hit_data) >> howto->bitpos) & howto->src_mask;
+ }
+
+ /* Figure out the value of the symbol. */
+ if (local_p && !merge_p)
+ {
+ if (r_type == R_SCORE_GOT15)
+ {
+ const Elf_Internal_Rela *relend;
+ const Elf_Internal_Rela *lo16_rel;
+ const struct elf_backend_data *bed;
+ bfd_vma lo_value = 0;
+
+ value = bfd_get_32 (input_bfd, contents + rel->r_offset);
+ addend = value & 0x7fff;
+ if ((addend & 0x4000) == 0x4000)
+ addend |= 0xffffc000;
+
+ bed = get_elf_backend_data (output_bfd);
+ relend = relocs + input_section->reloc_count * bed->s->int_rels_per_ext_rel;
+ lo16_rel = score_elf_next_relocation (input_bfd, R_SCORE_GOT_LO16, rel, relend);
+ if ((local_p) && (lo16_rel != NULL))
+ {
+ bfd_vma tmp = 0;
+ tmp = bfd_get_32 (input_bfd, contents + lo16_rel->r_offset);
+ lo_value = (((tmp >> 16) & 0x3) << 14) | ((tmp & 0x7fff) >> 1);
+ }
+
+ addend <<= 16;
+ addend += lo_value;
+ }
+ }
+
+ local_p = score_elf_local_relocation_p (input_bfd, rel, local_sections, TRUE);
+
+ /* If we haven't already determined the GOT offset, or the GP value,
+ and we're going to need it, get it now. */
+ switch (r_type)
+ {
+ case R_SCORE_CALL15:
+ case R_SCORE_GOT15:
+ if (!local_p)
+ {
+ g = score_elf_global_got_index (elf_hash_table (info)->dynobj,
+ (struct elf_link_hash_entry *) h);
+ if ((! elf_hash_table(info)->dynamic_sections_created
+ || (info->shared
+ && (info->symbolic || h->root.dynindx == -1)
+ && h->root.def_regular)))
+ {
+ /* This is a static link or a -Bsymbolic link. The
+ symbol is defined locally, or was forced to be local.
+ We must initialize this entry in the GOT. */
+ bfd *tmpbfd = elf_hash_table (info)->dynobj;
+ asection *sgot = score_elf_got_section (tmpbfd, FALSE);
+ bfd_put_32 (tmpbfd, value, sgot->contents + g);
+ }
+ }
+ else if (r_type == R_SCORE_GOT15 || r_type == R_SCORE_CALL15)
+ {
+ /* There's no need to create a local GOT entry here; the
+ calculation for a local GOT15 entry does not involve G. */
+ ;
+ }
+ else
+ {
+ g = score_elf_local_got_index (output_bfd, input_bfd, info,
+ symbol + addend, r_symndx, h, r_type);
+ if (g == MINUS_ONE)
+ return bfd_reloc_outofrange;
+ }
+
+ /* Convert GOT indices to actual offsets. */
+ g = score_elf_got_offset_from_index (elf_hash_table (info)->dynobj,
+ output_bfd, input_bfd, g);
+ break;
+
+ case R_SCORE_HI16:
+ case R_SCORE_LO16:
+ case R_SCORE_GPREL32:
+ gp0 = _bfd_get_gp_value (input_bfd);
+ gp = _bfd_get_gp_value (output_bfd);
+ break;
+
+ case R_SCORE_GP15:
+ gp = _bfd_get_gp_value (output_bfd);
+
+ default:
+ break;
+ }
+
+ switch (r_type)
+ {
+ case R_SCORE_NONE:
+ return bfd_reloc_ok;
+
+ case R_SCORE_ABS32:
+ case R_SCORE_REL32:
+ if ((info->shared
+ || (elf_hash_table (info)->dynamic_sections_created
+ && h != NULL
+ && h->root.def_dynamic
+ && !h->root.def_regular))
+ && r_symndx != STN_UNDEF
+ && (input_section->flags & SEC_ALLOC) != 0)
+ {
+ /* If we're creating a shared library, or this relocation is against a symbol
+ in a shared library, then we can't know where the symbol will end up.
+ So, we create a relocation record in the output, and leave the job up
+ to the dynamic linker. */
+ value = addend;
+ if (!score_elf_create_dynamic_relocation (output_bfd, info, rel, h,
+ symbol, &value,
+ input_section))
+ return bfd_reloc_undefined;
+ }
+ else if (r_symndx == STN_UNDEF)
+ /* r_symndx will be STN_UNDEF (zero) only for relocs against symbols
+ from removed linkonce sections, or sections discarded by
+ a linker script. */
+ value = 0;
+ else
+ {
+ if (r_type != R_SCORE_REL32)
+ value = symbol + addend;
+ else
+ value = addend;
+ }
+ value &= howto->dst_mask;
+ bfd_put_32 (input_bfd, value, hit_data);
+ return bfd_reloc_ok;
+
+ case R_SCORE_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_SCORE_24:
+ addend = bfd_get_32 (input_bfd, hit_data);
+ offset = (((addend & howto->src_mask) >> 1) & 0x1ff8000) | ((addend & howto->src_mask) & 0x7fff);
+ if ((offset & 0x1000000) != 0)
+ offset |= 0xfe000000;
+ value += offset;
+ abs_value = abs (value - rel_addr);
+ if ((abs_value & 0xfe000000) != 0)
+ return bfd_reloc_overflow;
+ addend = (addend & ~howto->src_mask)
+ | (((value << 1) & howto->src_mask) & 0x3ff0000) | (value & 0x7fff);
+ bfd_put_32 (input_bfd, addend, hit_data);
+ return bfd_reloc_ok;
+
+ case R_SCORE_PC19:
+ addend = bfd_get_32 (input_bfd, hit_data);
+ offset = (((addend & howto->src_mask) & 0x3ff0000) >> 6) | ((addend & howto->src_mask) & 0x3ff);
+ if ((offset & 0x80000) != 0)
+ offset |= 0xfff00000;
+ abs_value = value = value - rel_addr + offset;
+ /* exceed 20 bit : overflow. */
+ if ((abs_value & 0x80000000) == 0x80000000)
+ abs_value = 0xffffffff - value + 1;
+ if ((abs_value & 0xfff80000) != 0)
+ return bfd_reloc_overflow;
+ addend = (addend & ~howto->src_mask)
+ | (((value << 6) & howto->src_mask) & 0x3ff0000) | (value & 0x3ff);
+ bfd_put_32 (input_bfd, addend, hit_data);
+ return bfd_reloc_ok;
+
+ case R_SCORE16_11:
+ addend = bfd_get_16 (input_bfd, hit_data);
+ offset = addend & howto->src_mask;
+ if ((offset & 0x800) != 0) /* Offset is negative. */
+ offset |= 0xfffff000;
+ value += offset;
+ abs_value = abs (value - rel_addr);
+ if ((abs_value & 0xfffff000) != 0)
+ return bfd_reloc_overflow;
+ addend = (addend & ~howto->src_mask) | (value & howto->src_mask);
+ bfd_put_16 (input_bfd, addend, hit_data);
+ return bfd_reloc_ok;
+
+ case R_SCORE16_PC8:
+ addend = bfd_get_16 (input_bfd, hit_data);
+ offset = (addend & howto->src_mask) << 1;
+ if ((offset & 0x100) != 0) /* Offset is negative. */
+ offset |= 0xfffffe00;
+ abs_value = value = value - rel_addr + offset;
+ /* Sign bit + exceed 9 bit. */
+ if (((value & 0xffffff00) != 0) && ((value & 0xffffff00) != 0xffffff00))
+ return bfd_reloc_overflow;
+ value >>= 1;
+ addend = (addend & ~howto->src_mask) | (value & howto->src_mask);
+ bfd_put_16 (input_bfd, addend, hit_data);
+ return bfd_reloc_ok;
+
+ case R_SCORE_HI16:
+ return bfd_reloc_ok;
+
+ case R_SCORE_LO16:
+ hi16_addend = bfd_get_32 (input_bfd, hit_data - 4);
+ hi16_offset = ((((hi16_addend >> 16) & 0x3) << 15) | (hi16_addend & 0x7fff)) >> 1;
+ addend = bfd_get_32 (input_bfd, hit_data);
+ offset = ((((addend >> 16) & 0x3) << 15) | (addend & 0x7fff)) >> 1;
+ offset = (hi16_offset << 16) | (offset & 0xffff);
+
+ if (!gp_disp_p)
+ uvalue = value + offset;
+ else
+ uvalue = offset + gp - rel_addr + 4;
+
+ hi16_offset = (uvalue >> 16) << 1;
+ hi16_value = (hi16_addend & (~(howto->dst_mask)))
+ | (hi16_offset & 0x7fff) | ((hi16_offset << 1) & 0x30000);
+ bfd_put_32 (input_bfd, hi16_value, hit_data - 4);
+ offset = (uvalue & 0xffff) << 1;
+ value = (addend & (~(howto->dst_mask))) | (offset & 0x7fff) | ((offset << 1) & 0x30000);
+ bfd_put_32 (input_bfd, value, hit_data);
+ return bfd_reloc_ok;
+
+ case R_SCORE_GP15:
+ addend = bfd_get_32 (input_bfd, hit_data);
+ offset = addend & 0x7fff;
+ if ((offset & 0x4000) == 0x4000)
+ offset |= 0xffffc000;
+ value = value + offset - gp;
+ if (((value & 0xffffc000) != 0) && ((value & 0xffffc000) != 0xffffc000))
+ return bfd_reloc_overflow;
+ value = (addend & ~howto->src_mask) | (value & howto->src_mask);
+ bfd_put_32 (input_bfd, value, hit_data);
+ return bfd_reloc_ok;
+
+ case R_SCORE_GOT15:
+ case R_SCORE_CALL15:
+ if (local_p)
+ {
+ bfd_boolean forced;
+
+ /* The special case is when the symbol is forced to be local. We need the
+ full address in the GOT since no R_SCORE_GOT_LO16 relocation follows. */
+ forced = ! score_elf_local_relocation_p (input_bfd, rel,
+ local_sections, FALSE);
+ value = score_elf_got16_entry (output_bfd, input_bfd, info,
+ symbol + addend, forced);
+ if (value == MINUS_ONE)
+ return bfd_reloc_outofrange;
+ value = score_elf_got_offset_from_index (elf_hash_table (info)->dynobj,
+ output_bfd, input_bfd, value);
+ }
+ else
+ {
+ value = g;
+ }
+
+ if ((long) value > 0x3fff || (long) value < -0x4000)
+ return bfd_reloc_overflow;
+
+ addend = bfd_get_32 (input_bfd, hit_data);
+ value = (addend & ~howto->dst_mask) | (value & howto->dst_mask);
+ bfd_put_32 (input_bfd, value, hit_data);
+ return bfd_reloc_ok;
+
+ case R_SCORE_GPREL32:
+ value = (addend + symbol + gp0 - gp);
+ value &= howto->dst_mask;
+ bfd_put_32 (input_bfd, value, hit_data);
+ return bfd_reloc_ok;
+
+ case R_SCORE_GOT_LO16:
+ addend = bfd_get_32 (input_bfd, hit_data);
+ value = (((addend >> 16) & 0x3) << 14) | ((addend & 0x7fff) >> 1);
+ value += symbol;
+ value = (addend & (~(howto->dst_mask))) | ((value & 0x3fff) << 1)
+ | (((value >> 14) & 0x3) << 16);
+
+ bfd_put_32 (input_bfd, value, hit_data);
+ return bfd_reloc_ok;
+
+ case R_SCORE_DUMMY_HI16:
+ return bfd_reloc_ok;
+
+ case R_SCORE_GNU_VTINHERIT:
+ case R_SCORE_GNU_VTENTRY:
+ /* We don't do anything with these at present. */
+ return bfd_reloc_continue;
+
+ default:
+ return bfd_reloc_notsupported;
+ }
+}
+
+/* Score backend functions. */
+
+void
+s7_bfd_score_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED,
+ arelent *bfd_reloc,
+ Elf_Internal_Rela *elf_reloc)
+{
+ unsigned int r_type;
+
+ r_type = ELF32_R_TYPE (elf_reloc->r_info);
+ if (r_type >= ARRAY_SIZE (elf32_score_howto_table))
+ bfd_reloc->howto = NULL;
+ else
+ bfd_reloc->howto = &elf32_score_howto_table[r_type];
+}
+
+/* Relocate an score ELF section. */
+
+bfd_boolean
+s7_bfd_score_elf_relocate_section (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;
+ const char *name;
+ unsigned long offset;
+ unsigned long hi16_addend, hi16_offset, hi16_value, uvalue;
+ size_t extsymoff;
+ bfd_boolean gp_disp_p = FALSE;
+
+ /* Sort dynsym. */
+ if (elf_hash_table (info)->dynamic_sections_created)
+ {
+ bfd_size_type dynsecsymcount = 0;
+ if (info->shared)
+ {
+ asection * p;
+ const struct elf_backend_data *bed = get_elf_backend_data (output_bfd);
+
+ for (p = output_bfd->sections; p ; p = p->next)
+ if ((p->flags & SEC_EXCLUDE) == 0
+ && (p->flags & SEC_ALLOC) != 0
+ && !(*bed->elf_backend_omit_section_dynsym) (output_bfd, info, p))
+ ++ dynsecsymcount;
+ }
+
+ if (!score_elf_sort_hash_table (info, dynsecsymcount + 1))
+ return FALSE;
+ }
+
+ symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
+ extsymoff = (elf_bad_symtab (input_bfd)) ? 0 : symtab_hdr->sh_info;
+ 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 score_elf_link_hash_entry *h;
+ bfd_vma relocation = 0;
+ bfd_reloc_status_type r;
+ arelent bfd_reloc;
+
+ r_symndx = ELF32_R_SYM (rel->r_info);
+ r_type = ELF32_R_TYPE (rel->r_info);
+
+ s7_bfd_score_info_to_howto (input_bfd, &bfd_reloc, (Elf_Internal_Rela *) rel);
+ howto = bfd_reloc.howto;
+
+ h = NULL;
+ sym = NULL;
+ sec = NULL;
+
+ if (r_symndx < extsymoff)
+ {
+ sym = local_syms + r_symndx;
+ sec = local_sections[r_symndx];
+ relocation = sec->output_section->vma + sec->output_offset;
+ name = bfd_elf_sym_name (input_bfd, symtab_hdr, sym, sec);
+
+ if (!info->relocatable)
+ {
+ if (ELF_ST_TYPE (sym->st_info) != STT_SECTION
+ || (sec->flags & SEC_MERGE))
+ {
+ relocation += sym->st_value;
+ }
+
+ if ((sec->flags & SEC_MERGE)
+ && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
+ {
+ asection *msec;
+ bfd_vma addend, value;
+
+ switch (r_type)
+ {
+ case R_SCORE_HI16:
+ break;
+ case R_SCORE_LO16:
+ hi16_addend = bfd_get_32 (input_bfd, contents + rel->r_offset - 4);
+ hi16_offset = ((((hi16_addend >> 16) & 0x3) << 15) | (hi16_addend & 0x7fff)) >> 1;
+ value = bfd_get_32 (input_bfd, contents + rel->r_offset);
+ offset = ((((value >> 16) & 0x3) << 15) | (value & 0x7fff)) >> 1;
+ addend = (hi16_offset << 16) | (offset & 0xffff);
+ msec = sec;
+ addend = _bfd_elf_rel_local_sym (output_bfd, sym, &msec, addend);
+ addend -= relocation;
+ addend += msec->output_section->vma + msec->output_offset;
+ uvalue = addend;
+ hi16_offset = (uvalue >> 16) << 1;
+ hi16_value = (hi16_addend & (~(howto->dst_mask)))
+ | (hi16_offset & 0x7fff) | ((hi16_offset << 1) & 0x30000);
+ bfd_put_32 (input_bfd, hi16_value, contents + rel->r_offset - 4);
+ offset = (uvalue & 0xffff) << 1;
+ value = (value & (~(howto->dst_mask)))
+ | (offset & 0x7fff) | ((offset << 1) & 0x30000);
+ bfd_put_32 (input_bfd, value, contents + rel->r_offset);
+ break;
+ case R_SCORE_GOT_LO16:
+ value = bfd_get_32 (input_bfd, contents + rel->r_offset);
+ addend = (((value >> 16) & 0x3) << 14) | ((value & 0x7fff) >> 1);
+ msec = sec;
+ addend = _bfd_elf_rel_local_sym (output_bfd, sym, &msec, addend) - relocation;
+ addend += msec->output_section->vma + msec->output_offset;
+ value = (value & (~(howto->dst_mask))) | ((addend & 0x3fff) << 1)
+ | (((addend >> 14) & 0x3) << 16);
+
+ bfd_put_32 (input_bfd, value, contents + rel->r_offset);
+ break;
+ default:
+ value = bfd_get_32 (input_bfd, contents + rel->r_offset);
+ /* Get the (signed) value from the instruction. */
+ addend = value & howto->src_mask;
+ if (addend & ((howto->src_mask + 1) >> 1))
+ {
+ bfd_signed_vma mask;
+
+ mask = -1;
+ mask &= ~howto->src_mask;
+ addend |= mask;
+ }
+ msec = sec;
+ addend = _bfd_elf_rel_local_sym (output_bfd, sym, &msec, addend) - relocation;
+ addend += msec->output_section->vma + msec->output_offset;
+ value = (value & ~howto->dst_mask) | (addend & howto->dst_mask);
+ bfd_put_32 (input_bfd, value, contents + rel->r_offset);
+ break;
+ }
+ }
+ }
+ }
+ else
+ {
+ /* For global symbols we look up the symbol in the hash-table. */
+ h = ((struct score_elf_link_hash_entry *)
+ elf_sym_hashes (input_bfd) [r_symndx - extsymoff]);
+
+ if (info->wrap_hash != NULL
+ && (input_section->flags & SEC_DEBUGGING) != 0)
+ h = ((struct score_elf_link_hash_entry *)
+ unwrap_hash_lookup (info, input_bfd, &h->root.root));
+
+ /* Find the real hash-table entry for this symbol. */
+ while (h->root.root.type == bfd_link_hash_indirect
+ || h->root.root.type == bfd_link_hash_warning)
+ h = (struct score_elf_link_hash_entry *) h->root.root.u.i.link;
+
+ /* Record the name of this symbol, for our caller. */
+ name = h->root.root.root.string;
+
+ /* See if this is the special GP_DISP_LABEL symbol. Note that such a
+ symbol must always be a global symbol. */
+ if (strcmp (name, GP_DISP_LABEL) == 0)
+ {
+ /* Relocations against GP_DISP_LABEL are permitted only with
+ R_SCORE_HI16 and R_SCORE_LO16 relocations. */
+ if (r_type != R_SCORE_HI16 && r_type != R_SCORE_LO16)
+ return bfd_reloc_notsupported;
+
+ gp_disp_p = TRUE;
+ }
+
+ /* If this symbol is defined, calculate its address. Note that
+ GP_DISP_LABEL is a magic symbol, always implicitly defined by the
+ linker, so it's inappropriate to check to see whether or not
+ its defined. */
+ else if ((h->root.root.type == bfd_link_hash_defined
+ || h->root.root.type == bfd_link_hash_defweak)
+ && h->root.root.u.def.section)
+ {
+ sec = h->root.root.u.def.section;
+ if (sec->output_section)
+ relocation = (h->root.root.u.def.value
+ + sec->output_section->vma
+ + sec->output_offset);
+ else
+ {
+ relocation = h->root.root.u.def.value;
+ }
+ }
+ else if (h->root.root.type == bfd_link_hash_undefweak)
+ /* We allow relocations against undefined weak symbols, giving
+ it the value zero, so that you can undefined weak functions
+ and check to see if they exist by looking at their addresses. */
+ relocation = 0;
+ else if (info->unresolved_syms_in_objects == RM_IGNORE
+ && ELF_ST_VISIBILITY (h->root.other) == STV_DEFAULT)
+ relocation = 0;
+ else if (strcmp (name, "_DYNAMIC_LINK") == 0)
+ {
+ /* If this is a dynamic link, we should have created a _DYNAMIC_LINK symbol
+ in s7_bfd_score_elf_create_dynamic_sections. Otherwise, we should define
+ the symbol with a value of 0. */
+ BFD_ASSERT (! info->shared);
+ BFD_ASSERT (bfd_get_section_by_name (output_bfd, ".dynamic") == NULL);
+ relocation = 0;
+ }
+ else if (!info->relocatable)
+ {
+ if (! ((*info->callbacks->undefined_symbol)
+ (info, h->root.root.root.string, input_bfd,
+ input_section, rel->r_offset,
+ (info->unresolved_syms_in_objects == RM_GENERATE_ERROR)
+ || ELF_ST_VISIBILITY (h->root.other))))
+ return bfd_reloc_undefined;
+ relocation = 0;
+ }
+ }
+
+ if (sec != NULL && discarded_section (sec))
+ RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+ rel, 1, relend, howto, 0, contents);
+
+ if (info->relocatable)
+ {
+ /* This is a relocatable 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 (r_type == R_SCORE_GOT15)
+ {
+ const Elf_Internal_Rela *lo16_rel;
+ const struct elf_backend_data *bed;
+ bfd_vma lo_addend = 0, lo_value = 0;
+ bfd_vma addend, value;
+
+ value = bfd_get_32 (input_bfd, contents + rel->r_offset);
+ addend = value & 0x7fff;
+ if ((addend & 0x4000) == 0x4000)
+ addend |= 0xffffc000;
+
+ bed = get_elf_backend_data (output_bfd);
+ relend = relocs + input_section->reloc_count * bed->s->int_rels_per_ext_rel;
+ lo16_rel = score_elf_next_relocation (input_bfd, R_SCORE_GOT_LO16, rel, relend);
+ if (lo16_rel != NULL)
+ {
+ lo_value = bfd_get_32 (input_bfd, contents + lo16_rel->r_offset);
+ lo_addend = (((lo_value >> 16) & 0x3) << 14) | ((lo_value & 0x7fff) >> 1);
+ }
+
+ addend <<= 16;
+ addend += lo_addend;
+
+ if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
+ addend += local_sections[r_symndx]->output_offset;
+
+ lo_addend = addend & 0xffff;
+ lo_value = (lo_value & (~(howto->dst_mask))) | ((lo_addend & 0x3fff) << 1)
+ | (((lo_addend >> 14) & 0x3) << 16);
+ bfd_put_32 (input_bfd, lo_value, contents + lo16_rel->r_offset);
+
+ addend = addend >> 16;
+ value = (value & ~howto->src_mask) | (addend & howto->src_mask);
+ bfd_put_32 (input_bfd, value, contents + rel->r_offset);
+ }
+ else if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
+ {
+ sec = local_sections[r_symndx];
+ score_elf_add_to_rel (input_bfd, contents + rel->r_offset,
+ howto, (bfd_signed_vma) (sec->output_offset + sym->st_value));
+ }
+ }
+ continue;
+ }
+
+ /* This is a final link. */
+ r = score_elf_final_link_relocate (howto, input_bfd, output_bfd,
+ input_section, contents, rel, relocs,
+ relocation, info, name,
+ (h ? ELF_ST_TYPE ((unsigned int) h->root.root.type) :
+ ELF_ST_TYPE ((unsigned int) sym->st_info)), h, local_syms,
+ local_sections, gp_disp_p);
+
+ if (r != bfd_reloc_ok)
+ {
+ const char *msg = (const char *)0;
+
+ switch (r)
+ {
+ case bfd_reloc_overflow:
+ /* If the overflowing reloc was to an undefined symbol,
+ we have already printed one error message and there
+ is no point complaining again. */
+ if (((!h) || (h->root.root.type != bfd_link_hash_undefined))
+ && (!((*info->callbacks->reloc_overflow)
+ (info, NULL, 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, TRUE)))
+ 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;
+}
+
+/* Look through the relocs for a section during the first phase, and
+ allocate space in the global offset table. */
+
+bfd_boolean
+s7_bfd_score_elf_check_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 score_got_info *g;
+ size_t extsymoff;
+ const Elf_Internal_Rela *rel;
+ const Elf_Internal_Rela *rel_end;
+ asection *sgot;
+ asection *sreloc;
+ const struct elf_backend_data *bed;
+
+ if (info->relocatable)
+ 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;
+
+ name = bfd_get_section_name (abfd, sec);
+
+ if (dynobj == NULL)
+ {
+ sgot = NULL;
+ g = NULL;
+ }
+ else
+ {
+ sgot = score_elf_got_section (dynobj, FALSE);
+ if (sgot == NULL)
+ g = NULL;
+ else
+ {
+ BFD_ASSERT (score_elf_section_data (sgot) != NULL);
+ g = score_elf_section_data (sgot)->u.got_info;
+ BFD_ASSERT (g != NULL);
+ }
+ }
+
+ sreloc = NULL;
+ bed = get_elf_backend_data (abfd);
+ rel_end = relocs + sec->reloc_count * bed->s->int_rels_per_ext_rel;
+ for (rel = relocs; rel < rel_end; ++rel)
+ {
+ unsigned long r_symndx;
+ unsigned int r_type;
+ struct elf_link_hash_entry *h;
+
+ r_symndx = ELF32_R_SYM (rel->r_info);
+ r_type = ELF32_R_TYPE (rel->r_info);
+
+ if (r_symndx < extsymoff)
+ {
+ h = NULL;
+ }
+ else if (r_symndx >= extsymoff + NUM_SHDR_ENTRIES (symtab_hdr))
+ {
+ (*_bfd_error_handler) (_("%s: Malformed reloc detected for section %s"), abfd, name);
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+ 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;
+
+ /* PR15323, ref flags aren't set for references in the
+ same object. */
+ h->root.non_ir_ref = 1;
+ }
+ }
+
+ /* Some relocs require a global offset table. */
+ if (dynobj == NULL || sgot == NULL)
+ {
+ switch (r_type)
+ {
+ case R_SCORE_GOT15:
+ case R_SCORE_CALL15:
+ if (dynobj == NULL)
+ elf_hash_table (info)->dynobj = dynobj = abfd;
+ if (!score_elf_create_got_section (dynobj, info, FALSE))
+ return FALSE;
+ g = score_elf_got_info (dynobj, &sgot);
+ break;
+ case R_SCORE_ABS32:
+ case R_SCORE_REL32:
+ if (dynobj == NULL && (info->shared || h != NULL) && (sec->flags & SEC_ALLOC) != 0)
+ elf_hash_table (info)->dynobj = dynobj = abfd;
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (!h && (r_type == R_SCORE_GOT_LO16))
+ {
+ if (! score_elf_record_local_got_symbol (abfd, r_symndx, rel->r_addend, g))
+ return FALSE;
+ }
+
+ switch (r_type)
+ {
+ case R_SCORE_CALL15:
+ if (h == NULL)
+ {
+ (*_bfd_error_handler)
+ (_("%B: CALL15 reloc at 0x%lx not against global symbol"),
+ abfd, (unsigned long) rel->r_offset);
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+ else
+ {
+ /* This symbol requires a global offset table entry. */
+ if (! score_elf_record_global_got_symbol (h, abfd, info, g))
+ return FALSE;
+
+ /* We need a stub, not a plt entry for the undefined function. But we record
+ it as if it needs plt. See _bfd_elf_adjust_dynamic_symbol. */
+ h->needs_plt = 1;
+ h->type = STT_FUNC;
+ }
+ break;
+ case R_SCORE_GOT15:
+ if (h && ! score_elf_record_global_got_symbol (h, abfd, info, g))
+ return FALSE;
+ break;
+ case R_SCORE_ABS32:
+ case R_SCORE_REL32:
+ if ((info->shared || h != NULL) && (sec->flags & SEC_ALLOC) != 0)
+ {
+ if (sreloc == NULL)
+ {
+ sreloc = score_elf_rel_dyn_section (dynobj, TRUE);
+ if (sreloc == NULL)
+ return FALSE;
+ }
+#define SCORE_READONLY_SECTION (SEC_ALLOC | SEC_LOAD | SEC_READONLY)
+ if (info->shared)
+ {
+ /* When creating a shared object, we must copy these reloc types into
+ the output file as R_SCORE_REL32 relocs. We make room for this reloc
+ in the .rel.dyn reloc section. */
+ score_elf_allocate_dynamic_relocations (dynobj, 1);
+ if ((sec->flags & SCORE_READONLY_SECTION)
+ == SCORE_READONLY_SECTION)
+ /* We tell the dynamic linker that there are
+ relocations against the text segment. */
+ info->flags |= DF_TEXTREL;
+ }
+ else
+ {
+ struct score_elf_link_hash_entry *hscore;
+
+ /* We only need to copy this reloc if the symbol is
+ defined in a dynamic object. */
+ hscore = (struct score_elf_link_hash_entry *) h;
+ ++hscore->possibly_dynamic_relocs;
+ if ((sec->flags & SCORE_READONLY_SECTION)
+ == SCORE_READONLY_SECTION)
+ /* We need it to tell the dynamic linker if there
+ are relocations against the text segment. */
+ hscore->readonly_reloc = TRUE;
+ }
+
+ /* Even though we don't directly need a GOT entry for this symbol,
+ a symbol must have a dynamic symbol table index greater that
+ DT_SCORE_GOTSYM if there are dynamic relocations against it. */
+ if (h != NULL)
+ {
+ if (dynobj == NULL)
+ elf_hash_table (info)->dynobj = dynobj = abfd;
+ if (! score_elf_create_got_section (dynobj, info, TRUE))
+ return FALSE;
+ g = score_elf_got_info (dynobj, &sgot);
+ if (! score_elf_record_global_got_symbol (h, abfd, info, g))
+ return FALSE;
+ }
+ }
+ break;
+
+ /* This relocation describes the C++ object vtable hierarchy.
+ Reconstruct it for later use during GC. */
+ case R_SCORE_GNU_VTINHERIT:
+ if (!bfd_elf_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_SCORE_GNU_VTENTRY:
+ if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_offset))
+ return FALSE;
+ break;
+ default:
+ break;
+ }
+
+ /* We must not create a stub for a symbol that has relocations
+ related to taking the function's address. */
+ switch (r_type)
+ {
+ default:
+ if (h != NULL)
+ {
+ struct score_elf_link_hash_entry *sh;
+
+ sh = (struct score_elf_link_hash_entry *) h;
+ sh->no_fn_stub = TRUE;
+ }
+ break;
+ case R_SCORE_CALL15:
+ break;
+ }
+ }
+
+ return TRUE;
+}
+
+bfd_boolean
+s7_bfd_score_elf_add_symbol_hook (bfd *abfd,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ Elf_Internal_Sym *sym,
+ const char **namep ATTRIBUTE_UNUSED,
+ flagword *flagsp ATTRIBUTE_UNUSED,
+ asection **secp,
+ bfd_vma *valp)
+{
+ switch (sym->st_shndx)
+ {
+ case SHN_COMMON:
+ if (sym->st_size > elf_gp_size (abfd))
+ break;
+ /* Fall through. */
+ case SHN_SCORE_SCOMMON:
+ *secp = bfd_make_section_old_way (abfd, ".scommon");
+ (*secp)->flags |= SEC_IS_COMMON;
+ *valp = sym->st_size;
+ break;
+ }
+
+ return TRUE;
+}
+
+void
+s7_bfd_score_elf_symbol_processing (bfd *abfd, asymbol *asym)
+{
+ elf_symbol_type *elfsym;
+
+ elfsym = (elf_symbol_type *) asym;
+ switch (elfsym->internal_elf_sym.st_shndx)
+ {
+ case SHN_COMMON:
+ if (asym->value > elf_gp_size (abfd))
+ break;
+ /* Fall through. */
+ case SHN_SCORE_SCOMMON:
+ if (score_elf_scom_section.name == NULL)
+ {
+ /* Initialize the small common section. */
+ score_elf_scom_section.name = ".scommon";
+ score_elf_scom_section.flags = SEC_IS_COMMON;
+ score_elf_scom_section.output_section = &score_elf_scom_section;
+ score_elf_scom_section.symbol = &score_elf_scom_symbol;
+ score_elf_scom_section.symbol_ptr_ptr = &score_elf_scom_symbol_ptr;
+ score_elf_scom_symbol.name = ".scommon";
+ score_elf_scom_symbol.flags = BSF_SECTION_SYM;
+ score_elf_scom_symbol.section = &score_elf_scom_section;
+ score_elf_scom_symbol_ptr = &score_elf_scom_symbol;
+ }
+ asym->section = &score_elf_scom_section;
+ asym->value = elfsym->internal_elf_sym.st_size;
+ break;
+ }
+}
+
+int
+s7_bfd_score_elf_link_output_symbol_hook (struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ const char *name ATTRIBUTE_UNUSED,
+ Elf_Internal_Sym *sym,
+ asection *input_sec,
+ struct elf_link_hash_entry *h ATTRIBUTE_UNUSED)
+{
+ /* 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_SCORE_SCOMMON;
+
+ return 1;
+}
+
+bfd_boolean
+s7_bfd_score_elf_section_from_bfd_section (bfd *abfd ATTRIBUTE_UNUSED,
+ asection *sec,
+ int *retval)
+{
+ if (strcmp (bfd_get_section_name (abfd, sec), ".scommon") == 0)
+ {
+ *retval = SHN_SCORE_SCOMMON;
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/* 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. */
+
+bfd_boolean
+s7_bfd_score_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
+ struct elf_link_hash_entry *h)
+{
+ bfd *dynobj;
+ struct score_elf_link_hash_entry *hscore;
+ asection *s;
+
+ dynobj = elf_hash_table (info)->dynobj;
+
+ /* Make sure we know what is going on here. */
+ BFD_ASSERT (dynobj != NULL
+ && (h->needs_plt
+ || h->u.weakdef != NULL
+ || (h->def_dynamic && h->ref_regular && !h->def_regular)));
+
+ /* If this symbol is defined in a dynamic object, we need to copy
+ any R_SCORE_ABS32 or R_SCORE_REL32 relocs against it into the output
+ file. */
+ hscore = (struct score_elf_link_hash_entry *) h;
+ if (!info->relocatable
+ && hscore->possibly_dynamic_relocs != 0
+ && (h->root.type == bfd_link_hash_defweak || !h->def_regular))
+ {
+ score_elf_allocate_dynamic_relocations (dynobj, hscore->possibly_dynamic_relocs);
+ if (hscore->readonly_reloc)
+ /* We tell the dynamic linker that there are relocations
+ against the text segment. */
+ info->flags |= DF_TEXTREL;
+ }
+
+ /* For a function, create a stub, if allowed. */
+ if (!hscore->no_fn_stub && h->needs_plt)
+ {
+ 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->def_regular)
+ {
+ /* We need .stub section. */
+ s = bfd_get_linker_section (dynobj, SCORE_ELF_STUB_SECTION_NAME);
+ BFD_ASSERT (s != NULL);
+
+ h->root.u.def.section = s;
+ h->root.u.def.value = s->size;
+
+ /* XXX Write this stub address somewhere. */
+ h->plt.offset = s->size;
+
+ /* Make room for this stub code. */
+ s->size += SCORE_FUNCTION_STUB_SIZE;
+
+ /* The last half word of the stub will be filled with the index
+ of this symbol in .dynsym section. */
+ return TRUE;
+ }
+ }
+ else if ((h->type == STT_FUNC) && !h->needs_plt)
+ {
+ /* This will set the entry for this symbol in the GOT to 0, and
+ the dynamic linker will take care of this. */
+ h->root.u.def.value = 0;
+ 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->u.weakdef != NULL)
+ {
+ BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
+ || h->u.weakdef->root.type == bfd_link_hash_defweak);
+ h->root.u.def.section = h->u.weakdef->root.u.def.section;
+ h->root.u.def.value = h->u.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. */
+
+bfd_boolean
+s7_bfd_score_elf_always_size_sections (bfd *output_bfd,
+ struct bfd_link_info *info)
+{
+ bfd *dynobj;
+ asection *s;
+ struct score_got_info *g;
+ int i;
+ bfd_size_type loadable_size = 0;
+ bfd_size_type local_gotno;
+ bfd *sub;
+
+ dynobj = elf_hash_table (info)->dynobj;
+ if (dynobj == NULL)
+ /* Relocatable links don't have it. */
+ return TRUE;
+
+ g = score_elf_got_info (dynobj, &s);
+ if (s == NULL)
+ return TRUE;
+
+ /* Calculate the total loadable size of the output. That will give us the
+ maximum number of GOT_PAGE entries required. */
+ for (sub = info->input_bfds; sub; sub = sub->link.next)
+ {
+ asection *subsection;
+
+ for (subsection = sub->sections;
+ subsection;
+ subsection = subsection->next)
+ {
+ if ((subsection->flags & SEC_ALLOC) == 0)
+ continue;
+ loadable_size += ((subsection->size + 0xf)
+ &~ (bfd_size_type) 0xf);
+ }
+ }
+
+ /* There has to be a global GOT entry for every symbol with
+ a dynamic symbol table index of DT_SCORE_GOTSYM or
+ higher. Therefore, it make sense to put those symbols
+ that need GOT entries at the end of the symbol table. We
+ do that here. */
+ if (! score_elf_sort_hash_table (info, 1))
+ return FALSE;
+
+ if (g->global_gotsym != NULL)
+ i = elf_hash_table (info)->dynsymcount - g->global_gotsym->dynindx;
+ else
+ /* If there are no global symbols, or none requiring
+ relocations, then GLOBAL_GOTSYM will be NULL. */
+ i = 0;
+
+ /* In the worst case, we'll get one stub per dynamic symbol. */
+ loadable_size += SCORE_FUNCTION_STUB_SIZE * i;
+
+ /* Assume there are two loadable segments consisting of
+ contiguous sections. Is 5 enough? */
+ local_gotno = (loadable_size >> 16) + 5;
+
+ g->local_gotno += local_gotno;
+ s->size += g->local_gotno * SCORE_ELF_GOT_SIZE (output_bfd);
+
+ g->global_gotno = i;
+ s->size += i * SCORE_ELF_GOT_SIZE (output_bfd);
+
+ score_elf_resolve_final_got_entries (g);
+
+ if (s->size > SCORE_ELF_GOT_MAX_SIZE (output_bfd))
+ {
+ /* Fixme. Error message or Warning message should be issued here. */
+ }
+
+ return TRUE;
+}
+
+/* Set the sizes of the dynamic sections. */
+
+bfd_boolean
+s7_bfd_score_elf_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
+{
+ bfd *dynobj;
+ asection *s;
+ bfd_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_linker_section (dynobj, ".interp");
+ BFD_ASSERT (s != NULL);
+ s->size = strlen (ELF_DYNAMIC_INTERPRETER) + 1;
+ s->contents = (bfd_byte *) ELF_DYNAMIC_INTERPRETER;
+ }
+ }
+
+ /* 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;
+
+ 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);
+
+ if (CONST_STRNEQ (name, ".rel"))
+ {
+ if (s->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)
+ s->flags |= SEC_EXCLUDE;
+ }
+ 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 (CONST_STRNEQ (name, ".got"))
+ {
+ /* s7_bfd_score_elf_always_size_sections() has already done
+ most of the work, but some symbols may have been mapped
+ to versions that we must now resolve in the got_entries
+ hash tables. */
+ }
+ else if (strcmp (name, SCORE_ELF_STUB_SECTION_NAME) == 0)
+ {
+ /* IRIX rld assumes that the function stub isn't at the end
+ of .text section. So put a dummy. XXX */
+ s->size += SCORE_FUNCTION_STUB_SIZE;
+ }
+ else if (! CONST_STRNEQ (name, ".init"))
+ {
+ /* It's not one of our sections, so don't allocate space. */
+ continue;
+ }
+
+ /* Allocate memory for the section contents. */
+ s->contents = bfd_zalloc (dynobj, s->size);
+ if (s->contents == NULL && s->size != 0)
+ {
+ bfd_set_error (bfd_error_no_memory);
+ return FALSE;
+ }
+ }
+
+ if (elf_hash_table (info)->dynamic_sections_created)
+ {
+ /* Add some entries to the .dynamic section. We fill in the
+ values later, in s7_bfd_score_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 (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_DEBUG, 0))
+ return FALSE;
+
+ if (reltext)
+ info->flags |= DF_TEXTREL;
+
+ if ((info->flags & DF_TEXTREL) != 0)
+ {
+ if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_TEXTREL, 0))
+ return FALSE;
+ }
+
+ if (! SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_PLTGOT, 0))
+ return FALSE;
+
+ if (score_elf_rel_dyn_section (dynobj, FALSE))
+ {
+ if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_REL, 0))
+ return FALSE;
+
+ if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_RELSZ, 0))
+ return FALSE;
+
+ if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_RELENT, 0))
+ return FALSE;
+ }
+
+ if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_SCORE_BASE_ADDRESS, 0))
+ return FALSE;
+
+ if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_SCORE_LOCAL_GOTNO, 0))
+ return FALSE;
+
+ if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_SCORE_SYMTABNO, 0))
+ return FALSE;
+
+ if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_SCORE_UNREFEXTNO, 0))
+ return FALSE;
+
+ if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_SCORE_GOTSYM, 0))
+ return FALSE;
+
+ if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_SCORE_HIPAGENO, 0))
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+bfd_boolean
+s7_bfd_score_elf_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
+{
+ struct elf_link_hash_entry *h;
+ struct bfd_link_hash_entry *bh;
+ flagword flags;
+ asection *s;
+
+ flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
+ | SEC_LINKER_CREATED | SEC_READONLY);
+
+ /* ABI requests the .dynamic section to be read only. */
+ s = bfd_get_linker_section (abfd, ".dynamic");
+ if (s != NULL)
+ {
+ if (!bfd_set_section_flags (abfd, s, flags))
+ return FALSE;
+ }
+
+ /* We need to create .got section. */
+ if (!score_elf_create_got_section (abfd, info, FALSE))
+ return FALSE;
+
+ if (!score_elf_rel_dyn_section (elf_hash_table (info)->dynobj, TRUE))
+ return FALSE;
+
+ /* Create .stub section. */
+ if (bfd_get_linker_section (abfd, SCORE_ELF_STUB_SECTION_NAME) == NULL)
+ {
+ s = bfd_make_section_anyway_with_flags (abfd, SCORE_ELF_STUB_SECTION_NAME,
+ flags | SEC_CODE);
+ if (s == NULL
+ || !bfd_set_section_alignment (abfd, s, 2))
+
+ return FALSE;
+ }
+
+ if (!info->shared)
+ {
+ const char *name;
+
+ name = "_DYNAMIC_LINK";
+ bh = NULL;
+ if (!(_bfd_generic_link_add_one_symbol
+ (info, abfd, name, BSF_GLOBAL, bfd_abs_section_ptr,
+ (bfd_vma) 0, NULL, FALSE, get_elf_backend_data (abfd)->collect, &bh)))
+ return FALSE;
+
+ h = (struct elf_link_hash_entry *) bh;
+ h->non_elf = 0;
+ h->def_regular = 1;
+ h->type = STT_SECTION;
+
+ if (!bfd_elf_link_record_dynamic_symbol (info, h))
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+/* Finish up dynamic symbol handling. We set the contents of various
+ dynamic sections here. */
+
+bfd_boolean
+s7_bfd_score_elf_finish_dynamic_symbol (bfd *output_bfd,
+ struct bfd_link_info *info,
+ struct elf_link_hash_entry *h,
+ Elf_Internal_Sym *sym)
+{
+ bfd *dynobj;
+ asection *sgot;
+ struct score_got_info *g;
+ const char *name;
+
+ dynobj = elf_hash_table (info)->dynobj;
+
+ if (h->plt.offset != MINUS_ONE)
+ {
+ asection *s;
+ bfd_byte stub[SCORE_FUNCTION_STUB_SIZE];
+
+ /* This symbol has a stub. Set it up. */
+ BFD_ASSERT (h->dynindx != -1);
+
+ s = bfd_get_linker_section (dynobj, SCORE_ELF_STUB_SECTION_NAME);
+ BFD_ASSERT (s != NULL);
+
+ /* FIXME: Can h->dynindex be more than 64K? */
+ if (h->dynindx & 0xffff0000)
+ return FALSE;
+
+ /* Fill the stub. */
+ bfd_put_32 (output_bfd, STUB_LW, stub);
+ bfd_put_32 (output_bfd, STUB_MOVE, stub + 4);
+ bfd_put_32 (output_bfd, STUB_LI16 | (h->dynindx << 1), stub + 8);
+ bfd_put_32 (output_bfd, STUB_BRL, stub + 12);
+
+ BFD_ASSERT (h->plt.offset <= s->size);
+ memcpy (s->contents + h->plt.offset, stub, SCORE_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. */
+ sym->st_value = (s->output_section->vma + s->output_offset + h->plt.offset);
+ }
+
+ BFD_ASSERT (h->dynindx != -1 || h->forced_local);
+
+ sgot = score_elf_got_section (dynobj, FALSE);
+ BFD_ASSERT (sgot != NULL);
+ BFD_ASSERT (score_elf_section_data (sgot) != NULL);
+ g = score_elf_section_data (sgot)->u.got_info;
+ BFD_ASSERT (g != NULL);
+
+ /* Run through the global symbol table, creating GOT entries for all
+ the symbols that need them. */
+ if (g->global_gotsym != NULL && h->dynindx >= g->global_gotsym->dynindx)
+ {
+ bfd_vma offset;
+ bfd_vma value;
+
+ value = sym->st_value;
+ offset = score_elf_global_got_index (dynobj, h);
+ bfd_put_32 (output_bfd, value, sgot->contents + offset);
+ }
+
+ /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute. */
+ name = h->root.root.string;
+ if (h == elf_hash_table (info)->hdynamic
+ || h == elf_hash_table (info)->hgot)
+ 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 (strcmp (name, GP_DISP_LABEL) == 0)
+ {
+ sym->st_shndx = SHN_ABS;
+ sym->st_info = ELF_ST_INFO (STB_GLOBAL, STT_SECTION);
+ sym->st_value = elf_gp (output_bfd);
+ }
+
+ return TRUE;
+}
+
+/* Finish up the dynamic sections. */
+
+bfd_boolean
+s7_bfd_score_elf_finish_dynamic_sections (bfd *output_bfd,
+ struct bfd_link_info *info)
+{
+ bfd *dynobj;
+ asection *sdyn;
+ asection *sgot;
+ asection *s;
+ struct score_got_info *g;
+
+ dynobj = elf_hash_table (info)->dynobj;
+
+ sdyn = bfd_get_linker_section (dynobj, ".dynamic");
+
+ sgot = score_elf_got_section (dynobj, FALSE);
+ if (sgot == NULL)
+ g = NULL;
+ else
+ {
+ BFD_ASSERT (score_elf_section_data (sgot) != NULL);
+ g = score_elf_section_data (sgot)->u.got_info;
+ BFD_ASSERT (g != NULL);
+ }
+
+ if (elf_hash_table (info)->dynamic_sections_created)
+ {
+ bfd_byte *b;
+
+ BFD_ASSERT (sdyn != NULL);
+ BFD_ASSERT (g != NULL);
+
+ for (b = sdyn->contents;
+ b < sdyn->contents + sdyn->size;
+ b += SCORE_ELF_DYN_SIZE (dynobj))
+ {
+ Elf_Internal_Dyn dyn;
+ const char *name;
+ size_t elemsize;
+ bfd_boolean swap_out_p;
+
+ /* Read in the current dynamic entry. */
+ (*get_elf_backend_data (dynobj)->s->swap_dyn_in) (dynobj, b, &dyn);
+
+ /* Assume that we're going to modify it and write it out. */
+ swap_out_p = TRUE;
+
+ switch (dyn.d_tag)
+ {
+ case DT_RELENT:
+ s = score_elf_rel_dyn_section (dynobj, FALSE);
+ BFD_ASSERT (s != NULL);
+ dyn.d_un.d_val = SCORE_ELF_REL_SIZE (dynobj);
+ break;
+
+ case DT_STRSZ:
+ /* Rewrite DT_STRSZ. */
+ dyn.d_un.d_val = _bfd_elf_strtab_size (elf_hash_table (info)->dynstr);
+ break;
+
+ case DT_PLTGOT:
+ name = ".got";
+ s = bfd_get_section_by_name (output_bfd, name);
+ BFD_ASSERT (s != NULL);
+ dyn.d_un.d_ptr = s->vma;
+ break;
+
+ case DT_SCORE_BASE_ADDRESS:
+ s = output_bfd->sections;
+ BFD_ASSERT (s != NULL);
+ dyn.d_un.d_ptr = s->vma & ~(bfd_vma) 0xffff;
+ break;
+
+ case DT_SCORE_LOCAL_GOTNO:
+ dyn.d_un.d_val = g->local_gotno;
+ break;
+
+ case DT_SCORE_UNREFEXTNO:
+ /* The index into the dynamic symbol table which is the
+ entry of the first external symbol that is not
+ referenced within the same object. */
+ dyn.d_un.d_val = bfd_count_sections (output_bfd) + 1;
+ break;
+
+ case DT_SCORE_GOTSYM:
+ if (g->global_gotsym)
+ {
+ dyn.d_un.d_val = g->global_gotsym->dynindx;
+ break;
+ }
+ /* In case if we don't have global got symbols we default
+ to setting DT_SCORE_GOTSYM to the same value as
+ DT_SCORE_SYMTABNO, so we just fall through. */
+
+ case DT_SCORE_SYMTABNO:
+ name = ".dynsym";
+ elemsize = SCORE_ELF_SYM_SIZE (output_bfd);
+ s = bfd_get_section_by_name (output_bfd, name);
+ BFD_ASSERT (s != NULL);
+
+ dyn.d_un.d_val = s->size / elemsize;
+ break;
+
+ case DT_SCORE_HIPAGENO:
+ dyn.d_un.d_val = g->local_gotno - SCORE_RESERVED_GOTNO;
+ break;
+
+ default:
+ swap_out_p = FALSE;
+ break;
+ }
+
+ if (swap_out_p)
+ (*get_elf_backend_data (dynobj)->s->swap_dyn_out) (dynobj, &dyn, b);
+ }
+ }
+
+ /* 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->size > 0)
+ {
+ bfd_put_32 (output_bfd, 0, sgot->contents);
+ bfd_put_32 (output_bfd, 0x80000000, sgot->contents + SCORE_ELF_GOT_SIZE (output_bfd));
+ }
+
+ if (sgot != NULL)
+ elf_section_data (sgot->output_section)->this_hdr.sh_entsize
+ = SCORE_ELF_GOT_SIZE (output_bfd);
+
+
+ /* We need to sort the entries of the dynamic relocation section. */
+ s = score_elf_rel_dyn_section (dynobj, FALSE);
+
+ if (s != NULL && s->size > (bfd_vma)2 * SCORE_ELF_REL_SIZE (output_bfd))
+ {
+ reldyn_sorting_bfd = output_bfd;
+ qsort ((Elf32_External_Rel *) s->contents + 1, s->reloc_count - 1,
+ sizeof (Elf32_External_Rel), score_elf_sort_dynamic_relocs);
+ }
+
+ return TRUE;
+}
+
+/* This function 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. */
+
+bfd_boolean
+s7_bfd_score_elf_fake_sections (bfd *abfd ATTRIBUTE_UNUSED,
+ Elf_Internal_Shdr *hdr,
+ asection *sec)
+{
+ const char *name;
+
+ name = bfd_get_section_name (abfd, sec);
+
+ if (strcmp (name, ".got") == 0
+ || strcmp (name, ".srdata") == 0
+ || strcmp (name, ".sdata") == 0
+ || strcmp (name, ".sbss") == 0)
+ hdr->sh_flags |= SHF_SCORE_GPREL;
+
+ return TRUE;
+}
+
+/* This function do additional processing on the ELF section header before writing
+ it out. This is used to set the flags and type fields for some sections. */
+
+/* assign_file_positions_except_relocs() check section flag and if it is allocatable,
+ warning message will be issued. backend_fake_section is called before
+ assign_file_positions_except_relocs(); backend_section_processing after it. so, we
+ modify section flag there, but not backend_fake_section. */
+
+bfd_boolean
+s7_bfd_score_elf_section_processing (bfd *abfd ATTRIBUTE_UNUSED, 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_SCORE_GPREL;
+ hdr->sh_type = SHT_PROGBITS;
+ }
+ else if (strcmp (name, ".sbss") == 0)
+ {
+ hdr->sh_flags |= SHF_ALLOC | SHF_WRITE | SHF_SCORE_GPREL;
+ hdr->sh_type = SHT_NOBITS;
+ }
+ else if (strcmp (name, ".srdata") == 0)
+ {
+ hdr->sh_flags |= SHF_ALLOC | SHF_SCORE_GPREL;
+ hdr->sh_type = SHT_PROGBITS;
+ }
+ }
+
+ return TRUE;
+}
+
+bfd_boolean
+s7_bfd_score_elf_write_section (bfd *output_bfd, asection *sec, bfd_byte *contents)
+{
+ bfd_byte *to, *from, *end;
+ int i;
+
+ if (strcmp (sec->name, ".pdr") != 0)
+ return FALSE;
+
+ if (score_elf_section_data (sec)->u.tdata == NULL)
+ return FALSE;
+
+ to = contents;
+ end = contents + sec->size;
+ for (from = contents, i = 0; from < end; from += PDR_SIZE, i++)
+ {
+ if ((score_elf_section_data (sec)->u.tdata)[i] == 1)
+ continue;
+
+ if (to != from)
+ memcpy (to, from, PDR_SIZE);
+
+ to += PDR_SIZE;
+ }
+ bfd_set_section_contents (output_bfd, sec->output_section, contents,
+ (file_ptr) sec->output_offset, sec->size);
+
+ return TRUE;
+}
+
+/* Copy data from a SCORE ELF indirect symbol to its direct symbol, hiding the old
+ indirect symbol. Process additional relocation information. */
+
+void
+s7_bfd_score_elf_copy_indirect_symbol (struct bfd_link_info *info,
+ struct elf_link_hash_entry *dir,
+ struct elf_link_hash_entry *ind)
+{
+ struct score_elf_link_hash_entry *dirscore, *indscore;
+
+ _bfd_elf_link_hash_copy_indirect (info, dir, ind);
+
+ if (ind->root.type != bfd_link_hash_indirect)
+ return;
+
+ dirscore = (struct score_elf_link_hash_entry *) dir;
+ indscore = (struct score_elf_link_hash_entry *) ind;
+ dirscore->possibly_dynamic_relocs += indscore->possibly_dynamic_relocs;
+
+ if (indscore->readonly_reloc)
+ dirscore->readonly_reloc = TRUE;
+
+ if (indscore->no_fn_stub)
+ dirscore->no_fn_stub = TRUE;
+}
+
+/* Remove information about discarded functions from other sections which mention them. */
+
+bfd_boolean
+s7_bfd_score_elf_discard_info (bfd *abfd,
+ struct elf_reloc_cookie *cookie,
+ struct bfd_link_info *info)
+{
+ asection *o;
+ bfd_boolean ret = FALSE;
+ unsigned char *tdata;
+ size_t i, skip;
+
+ o = bfd_get_section_by_name (abfd, ".pdr");
+ if ((!o) || (o->size == 0) || (o->size % PDR_SIZE != 0)
+ || (o->output_section != NULL && bfd_is_abs_section (o->output_section)))
+ return FALSE;
+
+ tdata = bfd_zmalloc (o->size / PDR_SIZE);
+ if (!tdata)
+ return FALSE;
+
+ cookie->rels = _bfd_elf_link_read_relocs (abfd, o, NULL, NULL, info->keep_memory);
+ if (!cookie->rels)
+ {
+ free (tdata);
+ return FALSE;
+ }
+
+ cookie->rel = cookie->rels;
+ cookie->relend = cookie->rels + o->reloc_count;
+
+ for (i = 0, skip = 0; i < o->size; i++)
+ {
+ if (bfd_elf_reloc_symbol_deleted_p (i * PDR_SIZE, cookie))
+ {
+ tdata[i] = 1;
+ skip++;
+ }
+ }
+
+ if (skip != 0)
+ {
+ score_elf_section_data (o)->u.tdata = tdata;
+ o->size -= skip * PDR_SIZE;
+ ret = TRUE;
+ }
+ else
+ free (tdata);
+
+ if (!info->keep_memory)
+ free (cookie->rels);
+
+ return ret;
+}
+
+/* Signal that discard_info() has removed the discarded relocations for this section. */
+
+bfd_boolean
+s7_bfd_score_elf_ignore_discarded_relocs (asection *sec)
+{
+ if (strcmp (sec->name, ".pdr") == 0)
+ return TRUE;
+ return FALSE;
+}
+
+/* Return the section that should be marked against GC for a given
+ relocation. */
+
+asection *
+s7_bfd_score_elf_gc_mark_hook (asection *sec,
+ 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_SCORE_GNU_VTINHERIT:
+ case R_SCORE_GNU_VTENTRY:
+ return NULL;
+ }
+
+ return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
+}
+
+/* Support for core dump NOTE sections. */
+
+bfd_boolean
+s7_bfd_score_elf_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
+{
+ int offset;
+ unsigned int raw_size;
+
+ switch (note->descsz)
+ {
+ default:
+ return FALSE;
+ case 272: /* Linux/Score elf_prstatus */
+
+ /* pr_cursig */
+ elf_tdata (abfd)->core->signal = bfd_get_16 (abfd, note->descdata + 12);
+
+ /* pr_pid */
+ elf_tdata (abfd)->core->lwpid = bfd_get_32 (abfd, note->descdata + 24);
+
+ /* pr_reg */
+ offset = 72;
+
+ /* sizeof(elf_gregset_t) */
+ raw_size = 196;
+
+ break;
+ }
+
+ /* Make a ".reg/999" section. */
+ return _bfd_elfcore_make_pseudosection (abfd, ".reg", raw_size,
+ note->descpos + offset);
+}
+
+bfd_boolean
+s7_bfd_score_elf_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
+{
+ switch (note->descsz)
+ {
+ default:
+ return FALSE;
+
+ case 128: /* Linux/Score elf_prpsinfo. */
+ /* pr_fname */
+ elf_tdata (abfd)->core->program
+ = _bfd_elfcore_strndup (abfd, note->descdata + 32, 16);
+
+ /* pr_psargs */
+ elf_tdata (abfd)->core->command
+ = _bfd_elfcore_strndup (abfd, note->descdata + 48, 80);
+ break;
+ }
+
+ /* 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;
+}
+
+
+/* Score BFD functions. */
+
+reloc_howto_type *
+s7_elf32_score_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, bfd_reloc_code_real_type code)
+{
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE (elf32_score_reloc_map); i++)
+ if (elf32_score_reloc_map[i].bfd_reloc_val == code)
+ return &elf32_score_howto_table[elf32_score_reloc_map[i].elf_reloc_val];
+
+ return NULL;
+}
+
+bfd_boolean
+s7_elf32_score_print_private_bfd_data (bfd *abfd, void * 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_SCORE_PIC)
+ {
+ fprintf (file, _(" [pic]"));
+ }
+ if (elf_elfheader (abfd)->e_flags & EF_SCORE_FIXDEP)
+ {
+ fprintf (file, _(" [fix dep]"));
+ }
+ fputc ('\n', file);
+
+ return TRUE;
+}
+
+bfd_boolean
+s7_elf32_score_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
+{
+ flagword in_flags;
+ flagword out_flags;
+
+ if (!_bfd_generic_verify_endian_match (ibfd, obfd))
+ return FALSE;
+
+ in_flags = elf_elfheader (ibfd)->e_flags;
+ out_flags = elf_elfheader (obfd)->e_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))
+ {
+ 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;
+ }
+
+ if (((in_flags & EF_SCORE_PIC) != 0) != ((out_flags & EF_SCORE_PIC) != 0))
+ {
+ (*_bfd_error_handler) (_("%B: warning: linking PIC files with non-PIC files"), ibfd);
+ }
+
+ /* Maybe dependency fix compatibility should be checked here. */
+ return TRUE;
+}
+
+bfd_boolean
+s7_elf32_score_new_section_hook (bfd *abfd, asection *sec)
+{
+ struct _score_elf_section_data *sdata;
+ bfd_size_type amt = sizeof (*sdata);
+
+ sdata = bfd_zalloc (abfd, amt);
+ if (sdata == NULL)
+ return FALSE;
+ sec->used_by_bfd = sdata;
+
+ return _bfd_elf_new_section_hook (abfd, sec);
+}
+
+#define elf_backend_omit_section_dynsym \
+ ((bfd_boolean (*) (bfd *, struct bfd_link_info *, asection *)) bfd_true)
diff --git a/bfd/elf32-sh-relocs.h b/bfd/elf32-sh-relocs.h
new file mode 100644
index 0000000..fb54c9a
--- /dev/null
+++ b/bfd/elf32-sh-relocs.h
@@ -0,0 +1,1880 @@
+/* Copyright (C) 2006-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+/* 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_ignore_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 */
+ SH_PARTIAL32, /* partial_inplace */
+ SH_SRC_MASK32, /* 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_ignore_reloc, /* special_function */
+ "R_SH_REL32", /* name */
+ SH_PARTIAL32, /* partial_inplace */
+ SH_SRC_MASK32, /* 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_ignore_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. */
+ /* This cannot be partial_inplace because relaxation can't know the
+ eventual value of a symbol. */
+ 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 */
+ NULL, /* special_function */
+ "R_SH_IND12W", /* name */
+ FALSE, /* partial_inplace */
+ 0x0, /* 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_ignore_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_ignore_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_ignore_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_ignore_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_ignore_reloc, /* special_function */
+ "R_SH_DIR8L", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* 8 bit PC relative divided by 2 - but specified in a very odd way. */
+ HOWTO (R_SH_LOOP_START, /* type */
+ 1, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 8, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ sh_elf_ignore_reloc, /* special_function */
+ "R_SH_LOOP_START", /* name */
+ TRUE, /* partial_inplace */
+ 0xff, /* src_mask */
+ 0xff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* 8 bit PC relative divided by 2 - but specified in a very odd way. */
+ HOWTO (R_SH_LOOP_END, /* type */
+ 1, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 8, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ sh_elf_ignore_reloc, /* special_function */
+ "R_SH_LOOP_END", /* name */
+ TRUE, /* partial_inplace */
+ 0xff, /* src_mask */
+ 0xff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ EMPTY_HOWTO (12),
+ EMPTY_HOWTO (13),
+ EMPTY_HOWTO (14),
+ EMPTY_HOWTO (15),
+ EMPTY_HOWTO (16),
+ EMPTY_HOWTO (17),
+ EMPTY_HOWTO (18),
+ EMPTY_HOWTO (19),
+ EMPTY_HOWTO (20),
+ EMPTY_HOWTO (21),
+
+ /* 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. */
+
+ /* 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 */
+
+ /* 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 */
+
+ /* 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 assuming 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 */
+
+ /* The next 12 are only supported via linking in SHC-generated objects. */
+ HOWTO (R_SH_DIR16, /* 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_SH_DIR16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_SH_DIR8, /* 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_SH_DIR8", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_SH_DIR8UL, /* type */
+ 2, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 8, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_unsigned, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SH_DIR8UL", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_SH_DIR8UW, /* type */
+ 1, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 8, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_unsigned, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SH_DIR8UW", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_SH_DIR8U, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 8, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_unsigned, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SH_DIR8U", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_SH_DIR8SW, /* type */
+ 1, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 8, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SH_DIR8SW", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_SH_DIR8S, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 8, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SH_DIR8S", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_SH_DIR4UL, /* type */
+ 2, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 4, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_unsigned, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SH_DIR4UL", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0f, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_SH_DIR4UW, /* type */
+ 1, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 4, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_unsigned, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SH_DIR4UW", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0f, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_SH_DIR4U, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 4, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_unsigned, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SH_DIR4U", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0f, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_SH_PSHA, /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 7, /* bitsize */
+ FALSE, /* pc_relative */
+ 4, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SH_PSHA", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0f, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_SH_PSHL, /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 7, /* bitsize */
+ FALSE, /* pc_relative */
+ 4, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SH_PSHL", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0f, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+#ifdef INCLUDE_SHMEDIA
+ /* Used in SHLLI.L and SHLRI.L. */
+ HOWTO (R_SH_DIR5U, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 5, /* bitsize */
+ FALSE, /* pc_relative */
+ 10, /* bitpos */
+ complain_overflow_unsigned, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SH_DIR5U", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xfc00, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Used in SHARI, SHLLI et al. */
+ HOWTO (R_SH_DIR6U, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 6, /* bitsize */
+ FALSE, /* pc_relative */
+ 10, /* bitpos */
+ complain_overflow_unsigned, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SH_DIR6U", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xfc00, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Used in BxxI, LDHI.L et al. */
+ HOWTO (R_SH_DIR6S, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 6, /* bitsize */
+ FALSE, /* pc_relative */
+ 10, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SH_DIR6S", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xfc00, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Used in ADDI, ANDI et al. */
+ HOWTO (R_SH_DIR10S, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 10, /* bitsize */
+ FALSE, /* pc_relative */
+ 10, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SH_DIR10S", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffc00, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Used in LD.UW, ST.W et al. */
+ HOWTO (R_SH_DIR10SW, /* type */
+ 1, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 11, /* bitsize */
+ FALSE, /* pc_relative */
+ 10, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SH_DIR10SW", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffc00, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Used in LD.L, FLD.S et al. */
+ HOWTO (R_SH_DIR10SL, /* type */
+ 2, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 12, /* bitsize */
+ FALSE, /* pc_relative */
+ 10, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SH_DIR10SL", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffc00, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Used in FLD.D, FST.P et al. */
+ HOWTO (R_SH_DIR10SQ, /* type */
+ 3, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 13, /* bitsize */
+ FALSE, /* pc_relative */
+ 10, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SH_DIR10SQ", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffc00, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+#else
+ EMPTY_HOWTO (45),
+ EMPTY_HOWTO (46),
+ EMPTY_HOWTO (47),
+ EMPTY_HOWTO (48),
+ EMPTY_HOWTO (49),
+ EMPTY_HOWTO (50),
+ EMPTY_HOWTO (51),
+#endif
+
+ EMPTY_HOWTO (52),
+
+ HOWTO (R_SH_DIR16S, /* 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_SH_DIR16S", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ EMPTY_HOWTO (54),
+ EMPTY_HOWTO (55),
+ EMPTY_HOWTO (56),
+ EMPTY_HOWTO (57),
+ EMPTY_HOWTO (58),
+ EMPTY_HOWTO (59),
+ EMPTY_HOWTO (60),
+ EMPTY_HOWTO (61),
+ EMPTY_HOWTO (62),
+ EMPTY_HOWTO (63),
+ EMPTY_HOWTO (64),
+ EMPTY_HOWTO (65),
+ EMPTY_HOWTO (66),
+ EMPTY_HOWTO (67),
+ EMPTY_HOWTO (68),
+ EMPTY_HOWTO (69),
+ EMPTY_HOWTO (70),
+ EMPTY_HOWTO (71),
+ EMPTY_HOWTO (72),
+ EMPTY_HOWTO (73),
+ EMPTY_HOWTO (74),
+ EMPTY_HOWTO (75),
+ EMPTY_HOWTO (76),
+ EMPTY_HOWTO (77),
+ EMPTY_HOWTO (78),
+ EMPTY_HOWTO (79),
+ EMPTY_HOWTO (80),
+ EMPTY_HOWTO (81),
+ EMPTY_HOWTO (82),
+ EMPTY_HOWTO (83),
+ EMPTY_HOWTO (84),
+ EMPTY_HOWTO (85),
+ EMPTY_HOWTO (86),
+ EMPTY_HOWTO (87),
+ EMPTY_HOWTO (88),
+ EMPTY_HOWTO (89),
+ EMPTY_HOWTO (90),
+ EMPTY_HOWTO (91),
+ EMPTY_HOWTO (92),
+ EMPTY_HOWTO (93),
+ EMPTY_HOWTO (94),
+ EMPTY_HOWTO (95),
+ EMPTY_HOWTO (96),
+ EMPTY_HOWTO (97),
+ EMPTY_HOWTO (98),
+ EMPTY_HOWTO (99),
+ EMPTY_HOWTO (100),
+ EMPTY_HOWTO (101),
+ EMPTY_HOWTO (102),
+ EMPTY_HOWTO (103),
+ EMPTY_HOWTO (104),
+ EMPTY_HOWTO (105),
+ EMPTY_HOWTO (106),
+ EMPTY_HOWTO (107),
+ EMPTY_HOWTO (108),
+ EMPTY_HOWTO (109),
+ EMPTY_HOWTO (110),
+ EMPTY_HOWTO (111),
+ EMPTY_HOWTO (112),
+ EMPTY_HOWTO (113),
+ EMPTY_HOWTO (114),
+ EMPTY_HOWTO (115),
+ EMPTY_HOWTO (116),
+ EMPTY_HOWTO (117),
+ EMPTY_HOWTO (118),
+ EMPTY_HOWTO (119),
+ EMPTY_HOWTO (120),
+ EMPTY_HOWTO (121),
+ EMPTY_HOWTO (122),
+ EMPTY_HOWTO (123),
+ EMPTY_HOWTO (124),
+ EMPTY_HOWTO (125),
+ EMPTY_HOWTO (126),
+ EMPTY_HOWTO (127),
+ EMPTY_HOWTO (128),
+ EMPTY_HOWTO (129),
+ EMPTY_HOWTO (130),
+ EMPTY_HOWTO (131),
+ EMPTY_HOWTO (132),
+ EMPTY_HOWTO (133),
+ EMPTY_HOWTO (134),
+ EMPTY_HOWTO (135),
+ EMPTY_HOWTO (136),
+ EMPTY_HOWTO (137),
+ EMPTY_HOWTO (138),
+ EMPTY_HOWTO (139),
+ EMPTY_HOWTO (140),
+ EMPTY_HOWTO (141),
+ EMPTY_HOWTO (142),
+ EMPTY_HOWTO (143),
+
+ HOWTO (R_SH_TLS_GD_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, /* */
+ "R_SH_TLS_GD_32", /* name */
+ SH_PARTIAL32, /* partial_inplace */
+ SH_SRC_MASK32, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_SH_TLS_LD_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, /* */
+ "R_SH_TLS_LD_32", /* name */
+ SH_PARTIAL32, /* partial_inplace */
+ SH_SRC_MASK32, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_SH_TLS_LDO_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, /* */
+ "R_SH_TLS_LDO_32", /* name */
+ SH_PARTIAL32, /* partial_inplace */
+ SH_SRC_MASK32, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_SH_TLS_IE_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, /* */
+ "R_SH_TLS_IE_32", /* name */
+ SH_PARTIAL32, /* partial_inplace */
+ SH_SRC_MASK32, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_SH_TLS_LE_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, /* */
+ "R_SH_TLS_LE_32", /* name */
+ SH_PARTIAL32, /* partial_inplace */
+ SH_SRC_MASK32, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_SH_TLS_DTPMOD32, /* 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, /* */
+ "R_SH_TLS_DTPMOD32", /* name */
+ SH_PARTIAL32, /* partial_inplace */
+ SH_SRC_MASK32, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_SH_TLS_DTPOFF32, /* 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, /* */
+ "R_SH_TLS_DTPOFF32", /* name */
+ SH_PARTIAL32, /* partial_inplace */
+ SH_SRC_MASK32, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_SH_TLS_TPOFF32, /* 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, /* */
+ "R_SH_TLS_TPOFF32", /* name */
+ SH_PARTIAL32, /* partial_inplace */
+ SH_SRC_MASK32, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ EMPTY_HOWTO (152),
+ EMPTY_HOWTO (153),
+ EMPTY_HOWTO (154),
+ EMPTY_HOWTO (155),
+ EMPTY_HOWTO (156),
+ EMPTY_HOWTO (157),
+ EMPTY_HOWTO (158),
+ EMPTY_HOWTO (159),
+
+ HOWTO (R_SH_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, /* */
+ "R_SH_GOT32", /* name */
+ SH_PARTIAL32, /* partial_inplace */
+ SH_SRC_MASK32, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_SH_PLT32, /* 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, /* */
+ "R_SH_PLT32", /* name */
+ SH_PARTIAL32, /* partial_inplace */
+ SH_SRC_MASK32, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_SH_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, /* */
+ "R_SH_COPY", /* name */
+ SH_PARTIAL32, /* partial_inplace */
+ SH_SRC_MASK32, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_SH_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, /* */
+ "R_SH_GLOB_DAT", /* name */
+ SH_PARTIAL32, /* partial_inplace */
+ SH_SRC_MASK32, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_SH_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, /* */
+ "R_SH_JMP_SLOT", /* name */
+ SH_PARTIAL32, /* partial_inplace */
+ SH_SRC_MASK32, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_SH_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, /* */
+ "R_SH_RELATIVE", /* name */
+ SH_PARTIAL32, /* partial_inplace */
+ SH_SRC_MASK32, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_SH_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, /* */
+ "R_SH_GOTOFF", /* name */
+ SH_PARTIAL32, /* partial_inplace */
+ SH_SRC_MASK32, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_SH_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, /* */
+ "R_SH_GOTPC", /* name */
+ SH_PARTIAL32, /* partial_inplace */
+ SH_SRC_MASK32, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_SH_GOTPLT32, /* 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, /* */
+ "R_SH_GOTPLT32", /* name */
+ FALSE, /* partial_inplace */
+ /* ??? Why not 0? */
+ SH_SRC_MASK32, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+#ifdef INCLUDE_SHMEDIA
+ /* Used in MOVI and SHORI (x & 65536). */
+ HOWTO (R_SH_GOT_LOW16, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ FALSE, /* pc_relative */
+ 10, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SH_GOT_LOW16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x3fffc00, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Used in MOVI and SHORI ((x >> 16) & 65536). */
+ HOWTO (R_SH_GOT_MEDLOW16, /* type */
+ 16, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ FALSE, /* pc_relative */
+ 10, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SH_GOT_MEDLOW16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x3fffc00, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Used in MOVI and SHORI ((x >> 32) & 65536). */
+ HOWTO (R_SH_GOT_MEDHI16, /* type */
+ 32, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ FALSE, /* pc_relative */
+ 10, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SH_GOT_MEDHI16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x3fffc00, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Used in MOVI and SHORI ((x >> 48) & 65536). */
+ HOWTO (R_SH_GOT_HI16, /* type */
+ 48, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ FALSE, /* pc_relative */
+ 10, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SH_GOT_HI16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x3fffc00, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Used in MOVI and SHORI (x & 65536). */
+ HOWTO (R_SH_GOTPLT_LOW16, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ FALSE, /* pc_relative */
+ 10, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SH_GOTPLT_LOW16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x3fffc00, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Used in MOVI and SHORI ((x >> 16) & 65536). */
+ HOWTO (R_SH_GOTPLT_MEDLOW16, /* type */
+ 16, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ FALSE, /* pc_relative */
+ 10, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SH_GOTPLT_MEDLOW16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x3fffc00, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Used in MOVI and SHORI ((x >> 32) & 65536). */
+ HOWTO (R_SH_GOTPLT_MEDHI16, /* type */
+ 32, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ FALSE, /* pc_relative */
+ 10, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SH_GOTPLT_MEDHI16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x3fffc00, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Used in MOVI and SHORI ((x >> 48) & 65536). */
+ HOWTO (R_SH_GOTPLT_HI16, /* type */
+ 48, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ FALSE, /* pc_relative */
+ 10, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SH_GOTPLT_HI16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x3fffc00, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Used in MOVI and SHORI (x & 65536). */
+ HOWTO (R_SH_PLT_LOW16, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ TRUE, /* pc_relative */
+ 10, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SH_PLT_LOW16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x3fffc00, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* Used in MOVI and SHORI ((x >> 16) & 65536). */
+ HOWTO (R_SH_PLT_MEDLOW16, /* type */
+ 16, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ TRUE, /* pc_relative */
+ 10, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SH_PLT_MEDLOW16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x3fffc00, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* Used in MOVI and SHORI ((x >> 32) & 65536). */
+ HOWTO (R_SH_PLT_MEDHI16, /* type */
+ 32, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ TRUE, /* pc_relative */
+ 10, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SH_PLT_MEDHI16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x3fffc00, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* Used in MOVI and SHORI ((x >> 48) & 65536). */
+ HOWTO (R_SH_PLT_HI16, /* type */
+ 48, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ TRUE, /* pc_relative */
+ 10, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SH_PLT_HI16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x3fffc00, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* Used in MOVI and SHORI (x & 65536). */
+ HOWTO (R_SH_GOTOFF_LOW16, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ FALSE, /* pc_relative */
+ 10, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SH_GOTOFF_LOW16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x3fffc00, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Used in MOVI and SHORI ((x >> 16) & 65536). */
+ HOWTO (R_SH_GOTOFF_MEDLOW16, /* type */
+ 16, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ FALSE, /* pc_relative */
+ 10, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SH_GOTOFF_MEDLOW16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x3fffc00, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Used in MOVI and SHORI ((x >> 32) & 65536). */
+ HOWTO (R_SH_GOTOFF_MEDHI16, /* type */
+ 32, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ FALSE, /* pc_relative */
+ 10, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SH_GOTOFF_MEDHI16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x3fffc00, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Used in MOVI and SHORI ((x >> 48) & 65536). */
+ HOWTO (R_SH_GOTOFF_HI16, /* type */
+ 48, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ FALSE, /* pc_relative */
+ 10, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SH_GOTOFF_HI16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x3fffc00, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Used in MOVI and SHORI (x & 65536). */
+ HOWTO (R_SH_GOTPC_LOW16, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ TRUE, /* pc_relative */
+ 10, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SH_GOTPC_LOW16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x3fffc00, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* Used in MOVI and SHORI ((x >> 16) & 65536). */
+ HOWTO (R_SH_GOTPC_MEDLOW16, /* type */
+ 16, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ TRUE, /* pc_relative */
+ 10, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SH_GOTPC_MEDLOW16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x3fffc00, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* Used in MOVI and SHORI ((x >> 32) & 65536). */
+ HOWTO (R_SH_GOTPC_MEDHI16, /* type */
+ 32, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ TRUE, /* pc_relative */
+ 10, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SH_GOTPC_MEDHI16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x3fffc00, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* Used in MOVI and SHORI ((x >> 48) & 65536). */
+ HOWTO (R_SH_GOTPC_HI16, /* type */
+ 48, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ TRUE, /* pc_relative */
+ 10, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SH_GOTPC_HI16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x3fffc00, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* Used in LD.L, FLD.S et al. */
+ HOWTO (R_SH_GOT10BY4, /* type */
+ 2, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 12, /* bitsize */
+ FALSE, /* pc_relative */
+ 10, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SH_GOT10BY4", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffc00, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Used in LD.L, FLD.S et al. */
+ HOWTO (R_SH_GOTPLT10BY4, /* type */
+ 2, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 12, /* bitsize */
+ FALSE, /* pc_relative */
+ 10, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SH_GOTPLT10BY4", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffc00, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Used in FLD.D, FST.P et al. */
+ HOWTO (R_SH_GOT10BY8, /* type */
+ 3, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 13, /* bitsize */
+ FALSE, /* pc_relative */
+ 10, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SH_GOT10BY8", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffc00, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Used in FLD.D, FST.P et al. */
+ HOWTO (R_SH_GOTPLT10BY8, /* type */
+ 3, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 13, /* bitsize */
+ FALSE, /* pc_relative */
+ 10, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SH_GOTPLT10BY8", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffc00, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_SH_COPY64, /* type */
+ 0, /* rightshift */
+ 4, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SH_COPY64", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ ((bfd_vma) 0) - 1, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_SH_GLOB_DAT64, /* type */
+ 0, /* rightshift */
+ 4, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SH_GLOB_DAT64", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ ((bfd_vma) 0) - 1, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_SH_JMP_SLOT64, /* type */
+ 0, /* rightshift */
+ 4, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SH_JMP_SLOT64", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ ((bfd_vma) 0) - 1, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_SH_RELATIVE64, /* type */
+ 0, /* rightshift */
+ 4, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SH_RELATIVE64", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ ((bfd_vma) 0) - 1, /* dst_mask */
+ FALSE), /* pcrel_offset */
+#else
+ EMPTY_HOWTO (169),
+ EMPTY_HOWTO (170),
+ EMPTY_HOWTO (171),
+ EMPTY_HOWTO (172),
+ EMPTY_HOWTO (173),
+ EMPTY_HOWTO (174),
+ EMPTY_HOWTO (175),
+ EMPTY_HOWTO (176),
+ EMPTY_HOWTO (177),
+ EMPTY_HOWTO (178),
+ EMPTY_HOWTO (179),
+ EMPTY_HOWTO (180),
+ EMPTY_HOWTO (181),
+ EMPTY_HOWTO (182),
+ EMPTY_HOWTO (183),
+ EMPTY_HOWTO (184),
+ EMPTY_HOWTO (185),
+ EMPTY_HOWTO (186),
+ EMPTY_HOWTO (187),
+ EMPTY_HOWTO (188),
+ EMPTY_HOWTO (189),
+ EMPTY_HOWTO (190),
+ EMPTY_HOWTO (191),
+ EMPTY_HOWTO (192),
+ EMPTY_HOWTO (193),
+ EMPTY_HOWTO (194),
+ EMPTY_HOWTO (195),
+ EMPTY_HOWTO (196),
+#endif
+
+ EMPTY_HOWTO (197),
+ EMPTY_HOWTO (198),
+ EMPTY_HOWTO (199),
+ EMPTY_HOWTO (200),
+
+ /* FDPIC-relative offset to a GOT entry, for movi20. */
+ HOWTO (R_SH_GOT20, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 20, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SH_GOT20", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x00f0ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* FDPIC-relative offset to a data object, for movi20. */
+ HOWTO (R_SH_GOTOFF20, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 20, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SH_GOTOFF20", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x00f0ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* FDPIC-relative offset to a GOT entry for a function descriptor. */
+ HOWTO (R_SH_GOTFUNCDESC, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SH_GOTFUNCDESC", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* FDPIC-relative offset to a GOT entry for a function descriptor,
+ for movi20. */
+ HOWTO (R_SH_GOTFUNCDESC20, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 20, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SH_GOTFUNCDESC20", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x00f0ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* FDPIC-relative offset to a function descriptor. */
+ HOWTO (R_SH_GOTOFFFUNCDESC, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SH_GOTOFFFUNCDESC", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* FDPIC-relative offset to a function descriptor, for movi20. */
+ HOWTO (R_SH_GOTOFFFUNCDESC20, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 20, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SH_GOTOFFFUNCDESC20", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x00f0ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Address of an official function descriptor. */
+ HOWTO (R_SH_FUNCDESC, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SH_FUNCDESC", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Function descriptor to be filled in by the dynamic linker. */
+ HOWTO (R_SH_FUNCDESC_VALUE, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SH_FUNCDESC_VALUE", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+#ifdef INCLUDE_SHMEDIA
+ EMPTY_HOWTO (209),
+ EMPTY_HOWTO (210),
+ EMPTY_HOWTO (211),
+ EMPTY_HOWTO (212),
+ EMPTY_HOWTO (213),
+ EMPTY_HOWTO (214),
+ EMPTY_HOWTO (215),
+ EMPTY_HOWTO (216),
+ EMPTY_HOWTO (217),
+ EMPTY_HOWTO (218),
+ EMPTY_HOWTO (219),
+ EMPTY_HOWTO (220),
+ EMPTY_HOWTO (221),
+ EMPTY_HOWTO (222),
+ EMPTY_HOWTO (223),
+ EMPTY_HOWTO (224),
+ EMPTY_HOWTO (225),
+ EMPTY_HOWTO (226),
+ EMPTY_HOWTO (227),
+ EMPTY_HOWTO (228),
+ EMPTY_HOWTO (229),
+ EMPTY_HOWTO (230),
+ EMPTY_HOWTO (231),
+ EMPTY_HOWTO (232),
+ EMPTY_HOWTO (233),
+ EMPTY_HOWTO (234),
+ EMPTY_HOWTO (235),
+ EMPTY_HOWTO (236),
+ EMPTY_HOWTO (237),
+ EMPTY_HOWTO (238),
+ EMPTY_HOWTO (239),
+ EMPTY_HOWTO (240),
+ EMPTY_HOWTO (241),
+
+ /* Relocations for SHmedia code. None of these are partial_inplace or
+ use the field being relocated (except R_SH_PT_16). */
+
+ /* The assembler will generate this reloc before a block of SHmedia
+ instructions. A section should be processed as assuming it contains
+ data, unless this reloc is seen. Note that a block of SHcompact
+ instructions are instead preceded by R_SH_CODE.
+ This is currently not implemented, but should be used for SHmedia
+ linker relaxation. */
+ HOWTO (R_SH_SHMEDIA_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_SHMEDIA_CODE", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* The assembler will generate this reloc at a PTA or PTB instruction,
+ and the linker checks the right type of target, or changes a PTA to a
+ PTB, if the original insn was PT. */
+ HOWTO (R_SH_PT_16, /* type */
+ 2, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 18, /* bitsize */
+ TRUE, /* pc_relative */
+ 10, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SH_PT_16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x3fffc00, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* Used in unexpanded MOVI. */
+ HOWTO (R_SH_IMMS16, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 10, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SH_IMMS16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x3fffc00, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Used in SHORI. */
+ HOWTO (R_SH_IMMU16, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 10, /* bitpos */
+ complain_overflow_unsigned, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SH_IMMU16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x3fffc00, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Used in MOVI and SHORI (x & 65536). */
+ HOWTO (R_SH_IMM_LOW16, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ FALSE, /* pc_relative */
+ 10, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SH_IMM_LOW16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x3fffc00, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Used in MOVI and SHORI ((x - $) & 65536). */
+ HOWTO (R_SH_IMM_LOW16_PCREL, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ TRUE, /* pc_relative */
+ 10, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SH_IMM_LOW16_PCREL", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x3fffc00, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* Used in MOVI and SHORI ((x >> 16) & 65536). */
+ HOWTO (R_SH_IMM_MEDLOW16, /* type */
+ 16, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ FALSE, /* pc_relative */
+ 10, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SH_IMM_MEDLOW16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x3fffc00, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Used in MOVI and SHORI (((x - $) >> 16) & 65536). */
+ HOWTO (R_SH_IMM_MEDLOW16_PCREL, /* type */
+ 16, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ TRUE, /* pc_relative */
+ 10, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SH_IMM_MEDLOW16_PCREL", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x3fffc00, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* Used in MOVI and SHORI ((x >> 32) & 65536). */
+ HOWTO (R_SH_IMM_MEDHI16, /* type */
+ 32, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ FALSE, /* pc_relative */
+ 10, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SH_IMM_MEDHI16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x3fffc00, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Used in MOVI and SHORI (((x - $) >> 32) & 65536). */
+ HOWTO (R_SH_IMM_MEDHI16_PCREL, /* type */
+ 32, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ TRUE, /* pc_relative */
+ 10, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SH_IMM_MEDHI16_PCREL", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x3fffc00, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* Used in MOVI and SHORI ((x >> 48) & 65536). */
+ HOWTO (R_SH_IMM_HI16, /* type */
+ 48, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ FALSE, /* pc_relative */
+ 10, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SH_IMM_HI16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x3fffc00, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Used in MOVI and SHORI (((x - $) >> 48) & 65536). */
+ HOWTO (R_SH_IMM_HI16_PCREL, /* type */
+ 48, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ TRUE, /* pc_relative */
+ 10, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SH_IMM_HI16_PCREL", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x3fffc00, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* For the .uaquad pseudo. */
+ HOWTO (R_SH_64, /* type */
+ 0, /* rightshift */
+ 4, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SH_64", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ ((bfd_vma) 0) - 1, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* For the .uaquad pseudo, (x - $). */
+ HOWTO (R_SH_64_PCREL, /* type */
+ 48, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ TRUE, /* pc_relative */
+ 10, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SH_64_PCREL", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ ((bfd_vma) 0) - 1, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+#endif
+#undef SH_PARTIAL32
+#undef SH_SRC_MASK32
+#undef SH_ELF_RELOC
diff --git a/bfd/elf32-sh-symbian.c b/bfd/elf32-sh-symbian.c
new file mode 100644
index 0000000..5239de3
--- /dev/null
+++ b/bfd/elf32-sh-symbian.c
@@ -0,0 +1,612 @@
+/* Renesas / SuperH specific support for Symbian 32-bit ELF files
+ Copyright (C) 2004-2014 Free Software Foundation, Inc.
+ Contributed by Red Hat
+
+ This file is part of BFD, the Binary File Descriptor library.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+
+/* Stop elf32-sh.c from defining any target vectors. */
+#define SH_TARGET_ALREADY_DEFINED
+#define sh_find_elf_flags sh_symbian_find_elf_flags
+#define sh_elf_get_flags_from_mach sh_symbian_elf_get_flags_from_mach
+#include "elf32-sh.c"
+
+
+//#define SYMBIAN_DEBUG 1
+#define SYMBIAN_DEBUG 0
+
+#define DIRECTIVE_HEADER "#<SYMEDIT>#\n"
+#define DIRECTIVE_IMPORT "IMPORT "
+#define DIRECTIVE_EXPORT "EXPORT "
+#define DIRECTIVE_AS "AS "
+
+/* Macro to advance 's' until either it reaches 'e' or the
+ character pointed to by 's' is equal to 'c'. If 'e' is
+ reached and SYMBIAN_DEBUG is enabled then the error message 'm'
+ is displayed. */
+#define SKIP_UNTIL(s,e,c,m) \
+ do \
+ { \
+ while (s < e && *s != c) \
+ ++ s; \
+ if (s >= e) \
+ { \
+ if (SYMBIAN_DEBUG) \
+ fprintf (stderr, "Corrupt directive: %s\n", m); \
+ result = FALSE; \
+ } \
+ } \
+ while (0); \
+ if (!result) \
+ break;
+
+/* Like SKIP_UNTIL except there are two terminator characters
+ c1 and c2. */
+#define SKIP_UNTIL2(s,e,c1,c2,m) \
+ do \
+ { \
+ while (s < e && *s != c1 && *s != c2) \
+ ++ s; \
+ if (s >= e) \
+ { \
+ if (SYMBIAN_DEBUG) \
+ fprintf (stderr, "Corrupt directive: %s\n", m); \
+ result = FALSE; \
+ } \
+ } \
+ while (0); \
+ if (!result) \
+ break;
+
+/* Macro to advance 's' until either it reaches 'e' or the
+ character pointed to by 's' is not equal to 'c'. If 'e'
+ is reached and SYMBIAN_DEBUG is enabled then the error message
+ 'm' is displayed. */
+#define SKIP_WHILE(s,e,c,m) \
+ do \
+ { \
+ while (s < e && *s == c) \
+ ++ s; \
+ if (s >= e) \
+ { \
+ if (SYMBIAN_DEBUG) \
+ fprintf (stderr, "Corrupt directive: %s\n", m); \
+ result = FALSE; \
+ } \
+ } \
+ while (0); \
+ if (!result) \
+ break;
+
+
+typedef struct symbol_rename
+{
+ struct symbol_rename * next;
+ char * current_name;
+ char * new_name;
+ struct elf_link_hash_entry * current_hash;
+ unsigned long new_symndx;
+}
+symbol_rename;
+
+static symbol_rename * rename_list = NULL;
+
+/* Accumulate a list of symbols to be renamed. */
+
+static bfd_boolean
+sh_symbian_import_as (struct bfd_link_info *info, bfd * abfd,
+ char * current_name, char * new_name)
+{
+ struct elf_link_hash_entry * new_hash;
+ symbol_rename * node;
+
+ if (SYMBIAN_DEBUG)
+ fprintf (stderr, "IMPORT '%s' AS '%s'\n", current_name, new_name);
+
+ for (node = rename_list; node; node = node->next)
+ if (strcmp (node->current_name, current_name) == 0)
+ {
+ if (strcmp (node->new_name, new_name) == 0)
+ /* Already added to rename list. */
+ return TRUE;
+
+ bfd_set_error (bfd_error_invalid_operation);
+ _bfd_error_handler (_("%B: IMPORT AS directive for %s conceals previous IMPORT AS"),
+ abfd, current_name);
+ return FALSE;
+ }
+
+ if ((node = bfd_malloc (sizeof * node)) == NULL)
+ {
+ if (SYMBIAN_DEBUG)
+ fprintf (stderr, "IMPORT AS: No mem for new rename node\n");
+ return FALSE;
+ }
+
+ if ((node->current_name = bfd_malloc (strlen (current_name) + 1)) == NULL)
+ {
+ if (SYMBIAN_DEBUG)
+ fprintf (stderr, "IMPORT AS: No mem for current name field in rename node\n");
+ free (node);
+ return FALSE;
+ }
+ else
+ strcpy (node->current_name, current_name);
+
+ if ((node->new_name = bfd_malloc (strlen (new_name) + 1)) == NULL)
+ {
+ if (SYMBIAN_DEBUG)
+ fprintf (stderr, "IMPORT AS: No mem for new name field in rename node\n");
+ free (node->current_name);
+ free (node);
+ return FALSE;
+ }
+ else
+ strcpy (node->new_name, new_name);
+
+ node->next = rename_list;
+ node->current_hash = NULL;
+ node->new_symndx = 0;
+ rename_list = node;
+
+ new_hash = elf_link_hash_lookup (elf_hash_table (info), node->new_name, TRUE, FALSE, TRUE);
+ bfd_elf_link_record_dynamic_symbol (info, new_hash);
+ if (new_hash->root.type == bfd_link_hash_new)
+ new_hash->root.type = bfd_link_hash_undefined;
+
+ return TRUE;
+}
+
+
+static bfd_boolean
+sh_symbian_import (bfd * abfd ATTRIBUTE_UNUSED, char * name)
+{
+ if (SYMBIAN_DEBUG)
+ fprintf (stderr, "IMPORT '%s'\n", name);
+
+ /* XXX: Generate an import somehow ? */
+
+ return TRUE;
+}
+
+static bfd_boolean
+sh_symbian_export (bfd * abfd ATTRIBUTE_UNUSED, char * name)
+{
+ if (SYMBIAN_DEBUG)
+ fprintf (stderr, "EXPORT '%s'\n", name);
+
+ /* XXX: Generate an export somehow ? */
+
+ return TRUE;
+}
+
+/* Process any magic embedded commands in the .directive. section.
+ Returns TRUE upon sucecss, but if it fails it sets bfd_error and
+ returns FALSE. */
+
+static bfd_boolean
+sh_symbian_process_embedded_commands (struct bfd_link_info *info, bfd * abfd,
+ asection * sec, bfd_byte * contents)
+{
+ char *s;
+ char *e;
+ bfd_boolean result = TRUE;
+ bfd_size_type sz = sec->rawsize ? sec->rawsize : sec->size;
+
+ for (s = (char *) contents, e = s + sz; s < e;)
+ {
+ char * directive = s;
+
+ switch (*s)
+ {
+ /* I want to use "case DIRECTIVE_HEADER [0]:" here but gcc won't let me :-( */
+ case '#':
+ if (strcmp (s, DIRECTIVE_HEADER))
+ result = FALSE;
+ else
+ /* Just ignore the header.
+ XXX: Strictly speaking we ought to check that the header
+ is present and that it is the first thing in the file. */
+ s += strlen (DIRECTIVE_HEADER) + 1;
+ break;
+
+ case 'I':
+ if (! CONST_STRNEQ (s, DIRECTIVE_IMPORT))
+ result = FALSE;
+ else
+ {
+ char * new_name;
+ char * new_name_end;
+ char name_end_char;
+
+ /* Skip the IMPORT directive. */
+ s += strlen (DIRECTIVE_IMPORT);
+
+ new_name = s;
+ /* Find the end of the new name. */
+ while (s < e && *s != ' ' && *s != '\n')
+ ++ s;
+ if (s >= e)
+ {
+ /* We have reached the end of the .directive section
+ without encountering a string terminator. This is
+ allowed for IMPORT directives. */
+ new_name_end = e - 1;
+ name_end_char = * new_name_end;
+ * new_name_end = 0;
+ result = sh_symbian_import (abfd, new_name);
+ * new_name_end = name_end_char;
+ break;
+ }
+
+ /* Remember where the name ends. */
+ new_name_end = s;
+ /* Skip any whitespace before the 'AS'. */
+ SKIP_WHILE (s, e, ' ', "IMPORT: Name just followed by spaces");
+ /* Terminate the new name. (Do this after skiping...) */
+ name_end_char = * new_name_end;
+ * new_name_end = 0;
+
+ /* Check to see if 'AS '... is present. If so we have an
+ IMPORT AS directive, otherwise we have an IMPORT directive. */
+ if (! CONST_STRNEQ (s, DIRECTIVE_AS))
+ {
+ /* Skip the new-line at the end of the name. */
+ if (SYMBIAN_DEBUG && name_end_char != '\n')
+ fprintf (stderr, "IMPORT: No newline at end of directive\n");
+ else
+ s ++;
+
+ result = sh_symbian_import (abfd, new_name);
+
+ /* Skip past the NUL character. */
+ if (* s ++ != 0)
+ {
+ if (SYMBIAN_DEBUG)
+ fprintf (stderr, "IMPORT: No NUL at end of directive\n");
+ }
+ }
+ else
+ {
+ char * current_name;
+ char * current_name_end;
+ char current_name_end_char;
+
+ /* Skip the 'AS '. */
+ s += strlen (DIRECTIVE_AS);
+ /* Skip any white space after the 'AS '. */
+ SKIP_WHILE (s, e, ' ', "IMPORT AS: Nothing after AS");
+ current_name = s;
+ /* Find the end of the current name. */
+ SKIP_UNTIL2 (s, e, ' ', '\n', "IMPORT AS: No newline at the end of the current name");
+ /* Skip (backwards) over spaces at the end of the current name. */
+ current_name_end = s;
+ current_name_end_char = * current_name_end;
+
+ SKIP_WHILE (s, e, ' ', "IMPORT AS: Current name just followed by spaces");
+ /* Skip past the newline character. */
+ if (* s ++ != '\n')
+ if (SYMBIAN_DEBUG)
+ fprintf (stderr, "IMPORT AS: No newline at end of directive\n");
+
+ /* Terminate the current name after having performed the skips. */
+ * current_name_end = 0;
+
+ result = sh_symbian_import_as (info, abfd, current_name, new_name);
+
+ /* The next character should be a NUL. */
+ if (* s != 0)
+ {
+ if (SYMBIAN_DEBUG)
+ fprintf (stderr, "IMPORT AS: Junk at end of directive\n");
+ result = FALSE;
+ }
+ s ++;
+
+ * current_name_end = current_name_end_char;
+ }
+
+ /* Restore the characters we overwrote, since
+ the .directive section will be emitted. */
+ * new_name_end = name_end_char;
+ }
+ break;
+
+ case 'E':
+ if (! CONST_STRNEQ (s, DIRECTIVE_EXPORT))
+ result = FALSE;
+ else
+ {
+ char * name;
+ char * name_end;
+ char name_end_char;
+
+ /* Skip the directive. */
+ s += strlen (DIRECTIVE_EXPORT);
+ name = s;
+ /* Find the end of the name to be exported. */
+ SKIP_UNTIL (s, e, '\n', "EXPORT: no newline at end of directive");
+ /* Skip (backwards) over spaces at end of exported name. */
+ for (name_end = s; name_end[-1] == ' '; name_end --)
+ ;
+ /* name_end now points at the first character after the
+ end of the exported name, so we can termiante it */
+ name_end_char = * name_end;
+ * name_end = 0;
+ /* Skip passed the newline character. */
+ s ++;
+
+ result = sh_symbian_export (abfd, name);
+
+ /* The next character should be a NUL. */
+ if (* s != 0)
+ {
+ if (SYMBIAN_DEBUG)
+ fprintf (stderr, "EXPORT: Junk at end of directive\n");
+ result = FALSE;
+ }
+ s++;
+
+ /* Restore the character we deleted. */
+ * name_end = name_end_char;
+ }
+ break;
+
+ default:
+ result = FALSE;
+ break;
+ }
+
+ if (! result)
+ {
+ if (SYMBIAN_DEBUG)
+ fprintf (stderr, "offset into .directive section: %ld\n",
+ (long) (directive - (char *) contents));
+
+ bfd_set_error (bfd_error_invalid_operation);
+ _bfd_error_handler (_("%B: Unrecognised .directive command: %s"),
+ abfd, directive);
+ break;
+ }
+ }
+
+ return result;
+}
+
+
+/* Scan a bfd for a .directive section, and if found process it.
+ Returns TRUE upon success, FALSE otherwise. */
+
+static bfd_boolean
+sh_symbian_process_directives (bfd *abfd, struct bfd_link_info *info)
+{
+ bfd_boolean result = FALSE;
+ bfd_byte * contents;
+ asection * sec = bfd_get_section_by_name (abfd, ".directive");
+ bfd_size_type sz;
+
+ if (!sec)
+ return TRUE;
+
+ sz = sec->rawsize ? sec->rawsize : sec->size;
+ contents = bfd_malloc (sz);
+
+ if (!contents)
+ bfd_set_error (bfd_error_no_memory);
+ else
+ {
+ if (bfd_get_section_contents (abfd, sec, contents, 0, sz))
+ result = sh_symbian_process_embedded_commands (info, abfd, sec, contents);
+ free (contents);
+ }
+
+ return result;
+}
+
+/* Intercept the normal sh_relocate_section() function
+ and magle the relocs to allow for symbol renaming. */
+
+static bfd_boolean
+sh_symbian_relocate_section (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)
+{
+ /* When performing a final link we implement the IMPORT AS directives. */
+ if (!info->relocatable)
+ {
+ Elf_Internal_Rela * rel;
+ Elf_Internal_Rela * relend;
+ Elf_Internal_Shdr * symtab_hdr;
+ struct elf_link_hash_entry ** sym_hashes;
+ struct elf_link_hash_entry ** sym_hashes_end;
+ struct elf_link_hash_table * hash_table;
+ symbol_rename * ptr;
+ bfd_size_type num_global_syms;
+ unsigned long num_local_syms;
+
+ BFD_ASSERT (! elf_bad_symtab (input_bfd));
+
+ symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
+ hash_table = elf_hash_table (info);
+ num_local_syms = symtab_hdr->sh_info;
+ num_global_syms = symtab_hdr->sh_size / sizeof (Elf32_External_Sym);
+ num_global_syms -= num_local_syms;
+ sym_hashes = elf_sym_hashes (input_bfd);
+ sym_hashes_end = sym_hashes + num_global_syms;
+
+ /* First scan the rename table, caching the hash entry and the new index. */
+ for (ptr = rename_list; ptr; ptr = ptr->next)
+ {
+ struct elf_link_hash_entry * new_hash;
+ struct elf_link_hash_entry ** h;
+
+ ptr->current_hash = elf_link_hash_lookup (hash_table, ptr->current_name, FALSE, FALSE, TRUE);
+
+ if (ptr->current_hash == NULL)
+ {
+ if (SYMBIAN_DEBUG)
+ fprintf (stderr, "IMPORT AS: current symbol '%s' does not exist\n", ptr->current_name);
+ continue;
+ }
+
+ new_hash = elf_link_hash_lookup (hash_table, ptr->new_name,
+ FALSE, FALSE, TRUE);
+ /* If we could not find the symbol then it is a new, undefined symbol.
+ Symbian want this behaviour - ie they want to be able to rename the
+ reference in a reloc from one undefined symbol to another, new and
+ undefined symbol. So we create that symbol here. */
+ if (new_hash == NULL)
+ {
+ struct bfd_link_hash_entry *bh = NULL;
+ bfd_boolean collect = get_elf_backend_data (input_bfd)->collect;
+ if (_bfd_generic_link_add_one_symbol (info, input_bfd,
+ ptr->new_name, BSF_GLOBAL,
+ bfd_und_section_ptr, 0,
+ NULL, FALSE, collect,
+ &bh))
+ {
+ new_hash = (struct elf_link_hash_entry *) bh;
+ new_hash->type = STT_FUNC;
+ new_hash->non_elf = 0;
+
+ if (SYMBIAN_DEBUG)
+ fprintf (stderr, "Created new symbol %s\n", ptr->new_name);
+ }
+ }
+
+ if (new_hash == NULL)
+ {
+ _bfd_error_handler (_("%B: Failed to add renamed symbol %s"),
+ input_bfd, ptr->new_name);
+ continue;
+ }
+
+ /* Convert the new_hash value into a index into the table of symbol hashes. */
+ for (h = sym_hashes; h < sym_hashes_end; h ++)
+ {
+ if (* h == new_hash)
+ {
+ ptr->new_symndx = h - sym_hashes + num_local_syms;
+ if (SYMBIAN_DEBUG)
+ fprintf (stderr, "Converted new hash to index of %ld\n", ptr->new_symndx);
+ break;
+ }
+ }
+ /* If the new symbol is not in the hash table then it must be
+ because it is one of the newly created undefined symbols
+ manufactured above. So we extend the sym has table here to
+ include this extra symbol. */
+ if (h == sym_hashes_end)
+ {
+ struct elf_link_hash_entry ** new_sym_hashes;
+
+ /* This is not very efficient, but it works. */
+ ++ num_global_syms;
+ new_sym_hashes = bfd_alloc (input_bfd, num_global_syms * sizeof * sym_hashes);
+ if (new_sym_hashes == NULL)
+ {
+ if (SYMBIAN_DEBUG)
+ fprintf (stderr, "Out of memory extending hash table\n");
+ continue;
+ }
+ memcpy (new_sym_hashes, sym_hashes, (num_global_syms - 1) * sizeof * sym_hashes);
+ new_sym_hashes[num_global_syms - 1] = new_hash;
+ elf_sym_hashes (input_bfd) = sym_hashes = new_sym_hashes;
+ sym_hashes_end = sym_hashes + num_global_syms;
+ symtab_hdr->sh_size = (num_global_syms + num_local_syms) * sizeof (Elf32_External_Sym);
+
+ ptr->new_symndx = num_global_syms - 1 + num_local_syms;
+
+ if (SYMBIAN_DEBUG)
+ fprintf (stderr, "Extended symbol hash table to insert new symbol as index %ld\n",
+ ptr->new_symndx);
+ }
+ }
+
+ /* Walk the reloc list looking for references to renamed symbols.
+ When we find one, we alter the index in the reloc to point to the new symbol. */
+ for (rel = relocs, relend = relocs + input_section->reloc_count;
+ rel < relend;
+ rel ++)
+ {
+ int r_type;
+ unsigned long r_symndx;
+ struct elf_link_hash_entry * h;
+
+ r_symndx = ELF32_R_SYM (rel->r_info);
+ r_type = ELF32_R_TYPE (rel->r_info);
+
+ /* Ignore unused relocs. */
+ if ((r_type >= (int) R_SH_GNU_VTINHERIT
+ && r_type <= (int) R_SH_LABEL)
+ || r_type == (int) R_SH_NONE
+ || r_type < 0
+ || r_type >= R_SH_max)
+ continue;
+
+ /* Ignore relocs against local symbols. */
+ if (r_symndx < num_local_syms)
+ continue;
+
+ BFD_ASSERT (r_symndx < (num_global_syms + num_local_syms));
+ h = sym_hashes[r_symndx - num_local_syms];
+ BFD_ASSERT (h != NULL);
+
+ 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 the symbol is defined there is no need to rename it.
+ XXX - is this true ? */
+ if ( h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak
+ || h->root.type == bfd_link_hash_undefweak)
+ continue;
+
+ for (ptr = rename_list; ptr; ptr = ptr->next)
+ if (h == ptr->current_hash)
+ {
+ BFD_ASSERT (ptr->new_symndx);
+ if (SYMBIAN_DEBUG)
+ fprintf (stderr, "convert reloc %lx from using index %ld to using index %ld\n",
+ (unsigned long) rel->r_info,
+ (long) ELF32_R_SYM (rel->r_info), ptr->new_symndx);
+ rel->r_info = ELF32_R_INFO (ptr->new_symndx, r_type);
+ break;
+ }
+ }
+ }
+
+ return sh_elf_relocate_section (output_bfd, info, input_bfd, input_section,
+ contents, relocs, local_syms, local_sections);
+}
+
+#define TARGET_LITTLE_SYM sh_elf32_symbian_le_vec
+#define TARGET_LITTLE_NAME "elf32-shl-symbian"
+
+#undef elf_backend_relocate_section
+#define elf_backend_relocate_section sh_symbian_relocate_section
+#undef elf_backend_check_directives
+#define elf_backend_check_directives sh_symbian_process_directives
+
+#include "elf32-target.h"
diff --git a/bfd/elf32-sh.c b/bfd/elf32-sh.c
new file mode 100644
index 0000000..44a3aa7
--- /dev/null
+++ b/bfd/elf32-sh.c
@@ -0,0 +1,7578 @@
+/* Renesas / SuperH SH specific support for 32-bit ELF
+ Copyright (C) 1996-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "bfdlink.h"
+#include "libbfd.h"
+#include "elf-bfd.h"
+#include "elf-vxworks.h"
+#include "elf/sh.h"
+#include "dwarf2.h"
+#include "libiberty.h"
+#include "../opcodes/sh-opc.h"
+
+static bfd_reloc_status_type sh_elf_reloc
+ (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
+static bfd_reloc_status_type sh_elf_ignore_reloc
+ (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
+static bfd_boolean sh_elf_relax_delete_bytes
+ (bfd *, asection *, bfd_vma, int);
+static bfd_boolean sh_elf_align_loads
+ (bfd *, asection *, Elf_Internal_Rela *, bfd_byte *, bfd_boolean *);
+#ifndef SH64_ELF
+static bfd_boolean sh_elf_swap_insns
+ (bfd *, asection *, void *, bfd_byte *, bfd_vma);
+#endif
+static int sh_elf_optimized_tls_reloc
+ (struct bfd_link_info *, int, int);
+static bfd_vma dtpoff_base
+ (struct bfd_link_info *);
+static bfd_vma tpoff
+ (struct bfd_link_info *, bfd_vma);
+
+/* The name of the dynamic interpreter. This is put in the .interp
+ section. */
+
+#define ELF_DYNAMIC_INTERPRETER "/usr/lib/libc.so.1"
+
+/* FDPIC binaries have a default 128K stack. */
+#define DEFAULT_STACK_SIZE 0x20000
+
+#define MINUS_ONE ((bfd_vma) 0 - 1)
+
+/* Decide whether a reference to a symbol can be resolved locally or
+ not. If the symbol is protected, we want the local address, but
+ its function descriptor must be assigned by the dynamic linker. */
+#define SYMBOL_FUNCDESC_LOCAL(INFO, H) \
+ (SYMBOL_REFERENCES_LOCAL (INFO, H) \
+ || ! elf_hash_table (INFO)->dynamic_sections_created)
+
+#define SH_PARTIAL32 TRUE
+#define SH_SRC_MASK32 0xffffffff
+#define SH_ELF_RELOC sh_elf_reloc
+static reloc_howto_type sh_elf_howto_table[] =
+{
+#include "elf32-sh-relocs.h"
+};
+
+#define SH_PARTIAL32 FALSE
+#define SH_SRC_MASK32 0
+#define SH_ELF_RELOC bfd_elf_generic_reloc
+static reloc_howto_type sh_vxworks_howto_table[] =
+{
+#include "elf32-sh-relocs.h"
+};
+
+/* Return true if OUTPUT_BFD is a VxWorks object. */
+
+static bfd_boolean
+vxworks_object_p (bfd *abfd ATTRIBUTE_UNUSED)
+{
+#if !defined INCLUDE_SHMEDIA && !defined SH_TARGET_ALREADY_DEFINED
+ extern const bfd_target sh_elf32_vxworks_le_vec;
+ extern const bfd_target sh_elf32_vxworks_vec;
+
+ return (abfd->xvec == &sh_elf32_vxworks_le_vec
+ || abfd->xvec == &sh_elf32_vxworks_vec);
+#else
+ return FALSE;
+#endif
+}
+
+/* Return true if OUTPUT_BFD is an FDPIC object. */
+
+static bfd_boolean
+fdpic_object_p (bfd *abfd ATTRIBUTE_UNUSED)
+{
+#if !defined INCLUDE_SHMEDIA && !defined SH_TARGET_ALREADY_DEFINED
+ extern const bfd_target sh_elf32_fdpic_le_vec;
+ extern const bfd_target sh_elf32_fdpic_be_vec;
+
+ return (abfd->xvec == &sh_elf32_fdpic_le_vec
+ || abfd->xvec == &sh_elf32_fdpic_be_vec);
+#else
+ return FALSE;
+#endif
+}
+
+/* Return the howto table for ABFD. */
+
+static reloc_howto_type *
+get_howto_table (bfd *abfd)
+{
+ if (vxworks_object_p (abfd))
+ return sh_vxworks_howto_table;
+ return sh_elf_howto_table;
+}
+
+static bfd_reloc_status_type
+sh_elf_reloc_loop (int r_type ATTRIBUTE_UNUSED, bfd *input_bfd,
+ asection *input_section, bfd_byte *contents,
+ bfd_vma addr, asection *symbol_section,
+ bfd_vma start, bfd_vma end)
+{
+ static bfd_vma last_addr;
+ static asection *last_symbol_section;
+ bfd_byte *start_ptr, *ptr, *last_ptr;
+ int diff, cum_diff;
+ bfd_signed_vma x;
+ int insn;
+
+ /* Sanity check the address. */
+ if (addr > bfd_get_section_limit (input_bfd, input_section))
+ return bfd_reloc_outofrange;
+
+ /* We require the start and end relocations to be processed consecutively -
+ although we allow then to be processed forwards or backwards. */
+ if (! last_addr)
+ {
+ last_addr = addr;
+ last_symbol_section = symbol_section;
+ return bfd_reloc_ok;
+ }
+ if (last_addr != addr)
+ abort ();
+ last_addr = 0;
+
+ if (! symbol_section || last_symbol_section != symbol_section || end < start)
+ return bfd_reloc_outofrange;
+
+ /* Get the symbol_section contents. */
+ if (symbol_section != input_section)
+ {
+ if (elf_section_data (symbol_section)->this_hdr.contents != NULL)
+ contents = elf_section_data (symbol_section)->this_hdr.contents;
+ else
+ {
+ if (!bfd_malloc_and_get_section (input_bfd, symbol_section,
+ &contents))
+ {
+ if (contents != NULL)
+ free (contents);
+ return bfd_reloc_outofrange;
+ }
+ }
+ }
+#define IS_PPI(PTR) ((bfd_get_16 (input_bfd, (PTR)) & 0xfc00) == 0xf800)
+ start_ptr = contents + start;
+ for (cum_diff = -6, ptr = contents + end; cum_diff < 0 && ptr > start_ptr;)
+ {
+ for (last_ptr = ptr, ptr -= 4; ptr >= start_ptr && IS_PPI (ptr);)
+ ptr -= 2;
+ ptr += 2;
+ diff = (last_ptr - ptr) >> 1;
+ cum_diff += diff & 1;
+ cum_diff += diff;
+ }
+ /* Calculate the start / end values to load into rs / re minus four -
+ so that will cancel out the four we would otherwise have to add to
+ addr to get the value to subtract in order to get relative addressing. */
+ if (cum_diff >= 0)
+ {
+ start -= 4;
+ end = (ptr + cum_diff * 2) - contents;
+ }
+ else
+ {
+ bfd_vma start0 = start - 4;
+
+ while (start0 && IS_PPI (contents + start0))
+ start0 -= 2;
+ start0 = start - 2 - ((start - start0) & 2);
+ start = start0 - cum_diff - 2;
+ end = start0;
+ }
+
+ if (contents != NULL
+ && elf_section_data (symbol_section)->this_hdr.contents != contents)
+ free (contents);
+
+ insn = bfd_get_16 (input_bfd, contents + addr);
+
+ x = (insn & 0x200 ? end : start) - addr;
+ if (input_section != symbol_section)
+ x += ((symbol_section->output_section->vma + symbol_section->output_offset)
+ - (input_section->output_section->vma
+ + input_section->output_offset));
+ x >>= 1;
+ if (x < -128 || x > 127)
+ return bfd_reloc_overflow;
+
+ x = (insn & ~0xff) | (x & 0xff);
+ bfd_put_16 (input_bfd, (bfd_vma) x, contents + addr);
+
+ return bfd_reloc_ok;
+}
+
+/* This function is used for normal relocs. This used to be like the COFF
+ function, and is almost certainly incorrect for other ELF targets. */
+
+static bfd_reloc_status_type
+sh_elf_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol_in,
+ void *data, asection *input_section, bfd *output_bfd,
+ char **error_message ATTRIBUTE_UNUSED)
+{
+ 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_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, (bfd_vma) 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, (bfd_vma) 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 (bfd *abfd ATTRIBUTE_UNUSED, arelent *reloc_entry,
+ asymbol *symbol ATTRIBUTE_UNUSED,
+ void *data ATTRIBUTE_UNUSED, asection *input_section,
+ bfd *output_bfd,
+ char **error_message ATTRIBUTE_UNUSED)
+{
+ 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_16, R_SH_DIR16 },
+ { BFD_RELOC_8, R_SH_DIR8 },
+ { 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 },
+ { BFD_RELOC_SH_LOOP_START, R_SH_LOOP_START },
+ { BFD_RELOC_SH_LOOP_END, R_SH_LOOP_END },
+ { BFD_RELOC_SH_TLS_GD_32, R_SH_TLS_GD_32 },
+ { BFD_RELOC_SH_TLS_LD_32, R_SH_TLS_LD_32 },
+ { BFD_RELOC_SH_TLS_LDO_32, R_SH_TLS_LDO_32 },
+ { BFD_RELOC_SH_TLS_IE_32, R_SH_TLS_IE_32 },
+ { BFD_RELOC_SH_TLS_LE_32, R_SH_TLS_LE_32 },
+ { BFD_RELOC_SH_TLS_DTPMOD32, R_SH_TLS_DTPMOD32 },
+ { BFD_RELOC_SH_TLS_DTPOFF32, R_SH_TLS_DTPOFF32 },
+ { BFD_RELOC_SH_TLS_TPOFF32, R_SH_TLS_TPOFF32 },
+ { BFD_RELOC_32_GOT_PCREL, R_SH_GOT32 },
+ { BFD_RELOC_32_PLT_PCREL, R_SH_PLT32 },
+ { BFD_RELOC_SH_COPY, R_SH_COPY },
+ { BFD_RELOC_SH_GLOB_DAT, R_SH_GLOB_DAT },
+ { BFD_RELOC_SH_JMP_SLOT, R_SH_JMP_SLOT },
+ { BFD_RELOC_SH_RELATIVE, R_SH_RELATIVE },
+ { BFD_RELOC_32_GOTOFF, R_SH_GOTOFF },
+ { BFD_RELOC_SH_GOTPC, R_SH_GOTPC },
+ { BFD_RELOC_SH_GOTPLT32, R_SH_GOTPLT32 },
+ { BFD_RELOC_SH_GOT20, R_SH_GOT20 },
+ { BFD_RELOC_SH_GOTOFF20, R_SH_GOTOFF20 },
+ { BFD_RELOC_SH_GOTFUNCDESC, R_SH_GOTFUNCDESC },
+ { BFD_RELOC_SH_GOTFUNCDESC20, R_SH_GOTFUNCDESC20 },
+ { BFD_RELOC_SH_GOTOFFFUNCDESC, R_SH_GOTOFFFUNCDESC },
+ { BFD_RELOC_SH_GOTOFFFUNCDESC20, R_SH_GOTOFFFUNCDESC20 },
+ { BFD_RELOC_SH_FUNCDESC, R_SH_FUNCDESC },
+#ifdef INCLUDE_SHMEDIA
+ { BFD_RELOC_SH_GOT_LOW16, R_SH_GOT_LOW16 },
+ { BFD_RELOC_SH_GOT_MEDLOW16, R_SH_GOT_MEDLOW16 },
+ { BFD_RELOC_SH_GOT_MEDHI16, R_SH_GOT_MEDHI16 },
+ { BFD_RELOC_SH_GOT_HI16, R_SH_GOT_HI16 },
+ { BFD_RELOC_SH_GOTPLT_LOW16, R_SH_GOTPLT_LOW16 },
+ { BFD_RELOC_SH_GOTPLT_MEDLOW16, R_SH_GOTPLT_MEDLOW16 },
+ { BFD_RELOC_SH_GOTPLT_MEDHI16, R_SH_GOTPLT_MEDHI16 },
+ { BFD_RELOC_SH_GOTPLT_HI16, R_SH_GOTPLT_HI16 },
+ { BFD_RELOC_SH_PLT_LOW16, R_SH_PLT_LOW16 },
+ { BFD_RELOC_SH_PLT_MEDLOW16, R_SH_PLT_MEDLOW16 },
+ { BFD_RELOC_SH_PLT_MEDHI16, R_SH_PLT_MEDHI16 },
+ { BFD_RELOC_SH_PLT_HI16, R_SH_PLT_HI16 },
+ { BFD_RELOC_SH_GOTOFF_LOW16, R_SH_GOTOFF_LOW16 },
+ { BFD_RELOC_SH_GOTOFF_MEDLOW16, R_SH_GOTOFF_MEDLOW16 },
+ { BFD_RELOC_SH_GOTOFF_MEDHI16, R_SH_GOTOFF_MEDHI16 },
+ { BFD_RELOC_SH_GOTOFF_HI16, R_SH_GOTOFF_HI16 },
+ { BFD_RELOC_SH_GOTPC_LOW16, R_SH_GOTPC_LOW16 },
+ { BFD_RELOC_SH_GOTPC_MEDLOW16, R_SH_GOTPC_MEDLOW16 },
+ { BFD_RELOC_SH_GOTPC_MEDHI16, R_SH_GOTPC_MEDHI16 },
+ { BFD_RELOC_SH_GOTPC_HI16, R_SH_GOTPC_HI16 },
+ { BFD_RELOC_SH_COPY64, R_SH_COPY64 },
+ { BFD_RELOC_SH_GLOB_DAT64, R_SH_GLOB_DAT64 },
+ { BFD_RELOC_SH_JMP_SLOT64, R_SH_JMP_SLOT64 },
+ { BFD_RELOC_SH_RELATIVE64, R_SH_RELATIVE64 },
+ { BFD_RELOC_SH_GOT10BY4, R_SH_GOT10BY4 },
+ { BFD_RELOC_SH_GOT10BY8, R_SH_GOT10BY8 },
+ { BFD_RELOC_SH_GOTPLT10BY4, R_SH_GOTPLT10BY4 },
+ { BFD_RELOC_SH_GOTPLT10BY8, R_SH_GOTPLT10BY8 },
+ { BFD_RELOC_SH_PT_16, R_SH_PT_16 },
+ { BFD_RELOC_SH_SHMEDIA_CODE, R_SH_SHMEDIA_CODE },
+ { BFD_RELOC_SH_IMMU5, R_SH_DIR5U },
+ { BFD_RELOC_SH_IMMS6, R_SH_DIR6S },
+ { BFD_RELOC_SH_IMMU6, R_SH_DIR6U },
+ { BFD_RELOC_SH_IMMS10, R_SH_DIR10S },
+ { BFD_RELOC_SH_IMMS10BY2, R_SH_DIR10SW },
+ { BFD_RELOC_SH_IMMS10BY4, R_SH_DIR10SL },
+ { BFD_RELOC_SH_IMMS10BY8, R_SH_DIR10SQ },
+ { BFD_RELOC_SH_IMMS16, R_SH_IMMS16 },
+ { BFD_RELOC_SH_IMMU16, R_SH_IMMU16 },
+ { BFD_RELOC_SH_IMM_LOW16, R_SH_IMM_LOW16 },
+ { BFD_RELOC_SH_IMM_LOW16_PCREL, R_SH_IMM_LOW16_PCREL },
+ { BFD_RELOC_SH_IMM_MEDLOW16, R_SH_IMM_MEDLOW16 },
+ { BFD_RELOC_SH_IMM_MEDLOW16_PCREL, R_SH_IMM_MEDLOW16_PCREL },
+ { BFD_RELOC_SH_IMM_MEDHI16, R_SH_IMM_MEDHI16 },
+ { BFD_RELOC_SH_IMM_MEDHI16_PCREL, R_SH_IMM_MEDHI16_PCREL },
+ { BFD_RELOC_SH_IMM_HI16, R_SH_IMM_HI16 },
+ { BFD_RELOC_SH_IMM_HI16_PCREL, R_SH_IMM_HI16_PCREL },
+ { BFD_RELOC_64, R_SH_64 },
+ { BFD_RELOC_64_PCREL, R_SH_64_PCREL },
+#endif /* not INCLUDE_SHMEDIA */
+};
+
+/* Given a BFD reloc code, return the howto structure for the
+ corresponding SH ELF reloc. */
+
+static reloc_howto_type *
+sh_elf_reloc_type_lookup (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 get_howto_table (abfd) + (int) sh_reloc_map[i].elf_reloc_val;
+ }
+
+ return NULL;
+}
+
+static reloc_howto_type *
+sh_elf_reloc_name_lookup (bfd *abfd, const char *r_name)
+{
+ unsigned int i;
+
+ if (vxworks_object_p (abfd))
+ {
+ for (i = 0;
+ i < (sizeof (sh_vxworks_howto_table)
+ / sizeof (sh_vxworks_howto_table[0]));
+ i++)
+ if (sh_vxworks_howto_table[i].name != NULL
+ && strcasecmp (sh_vxworks_howto_table[i].name, r_name) == 0)
+ return &sh_vxworks_howto_table[i];
+ }
+ else
+ {
+ for (i = 0;
+ i < (sizeof (sh_elf_howto_table)
+ / sizeof (sh_elf_howto_table[0]));
+ i++)
+ if (sh_elf_howto_table[i].name != NULL
+ && strcasecmp (sh_elf_howto_table[i].name, r_name) == 0)
+ return &sh_elf_howto_table[i];
+ }
+
+ return NULL;
+}
+
+/* Given an ELF reloc, fill in the howto field of a relent. */
+
+static void
+sh_elf_info_to_howto (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);
+ BFD_ASSERT (r < R_SH_FIRST_INVALID_RELOC_2 || r > R_SH_LAST_INVALID_RELOC_2);
+ BFD_ASSERT (r < R_SH_FIRST_INVALID_RELOC_3 || r > R_SH_LAST_INVALID_RELOC_3);
+ BFD_ASSERT (r < R_SH_FIRST_INVALID_RELOC_4 || r > R_SH_LAST_INVALID_RELOC_4);
+ BFD_ASSERT (r < R_SH_FIRST_INVALID_RELOC_5 || r > R_SH_LAST_INVALID_RELOC_5);
+ BFD_ASSERT (r < R_SH_FIRST_INVALID_RELOC_6 || r > R_SH_LAST_INVALID_RELOC_6);
+
+ cache_ptr->howto = get_howto_table (abfd) + 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 bfd_boolean
+sh_elf_relax_section (bfd *abfd, asection *sec,
+ struct bfd_link_info *link_info, bfd_boolean *again)
+{
+ Elf_Internal_Shdr *symtab_hdr;
+ Elf_Internal_Rela *internal_relocs;
+ bfd_boolean have_code;
+ Elf_Internal_Rela *irel, *irelend;
+ bfd_byte *contents = NULL;
+ Elf_Internal_Sym *isymbuf = NULL;
+
+ *again = FALSE;
+
+ if (link_info->relocatable
+ || (sec->flags & SEC_RELOC) == 0
+ || sec->reloc_count == 0)
+ return TRUE;
+
+#ifdef INCLUDE_SHMEDIA
+ if (elf_section_data (sec)->this_hdr.sh_flags
+ & (SHF_SH5_ISA32 | SHF_SH5_ISA32_MIXED))
+ {
+ return TRUE;
+ }
+#endif
+
+ symtab_hdr = &elf_symtab_hdr (abfd);
+
+ internal_relocs = (_bfd_elf_link_read_relocs
+ (abfd, sec, NULL, (Elf_Internal_Rela *) NULL,
+ link_info->keep_memory));
+ if (internal_relocs == NULL)
+ goto error_return;
+
+ 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
+ {
+ if (!bfd_malloc_and_get_section (abfd, sec, &contents))
+ 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->size)
+ {
+ (*_bfd_error_handler) (_("%B: 0x%lx: warning: bad R_SH_USES offset"),
+ 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)
+ (_("%B: 0x%lx: warning: R_SH_USES points to unrecognized insn 0x%x"),
+ 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) &~ (bfd_vma) 3;
+ if (paddr >= sec->size)
+ {
+ ((*_bfd_error_handler)
+ (_("%B: 0x%lx: warning: bad R_SH_USES load offset"),
+ 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)
+ (_("%B: 0x%lx: warning: could not find expected reloc"),
+ abfd, (unsigned long) paddr));
+ continue;
+ }
+
+ /* Read this BFD's symbols if we haven't done so already. */
+ if (isymbuf == NULL && symtab_hdr->sh_info != 0)
+ {
+ isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
+ if (isymbuf == NULL)
+ isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
+ symtab_hdr->sh_info, 0,
+ NULL, NULL, NULL);
+ if (isymbuf == NULL)
+ 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)
+ {
+ /* A local symbol. */
+ Elf_Internal_Sym *isym;
+
+ isym = isymbuf + ELF32_R_SYM (irelfn->r_info);
+ if (isym->st_shndx
+ != (unsigned int) _bfd_elf_section_from_bfd_section (abfd, sec))
+ {
+ ((*_bfd_error_handler)
+ (_("%B: 0x%lx: warning: symbol in unexpected section"),
+ 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);
+ }
+
+ if (get_howto_table (abfd)[R_SH_DIR32].partial_inplace)
+ symval += bfd_get_32 (abfd, contents + paddr);
+ else
+ symval += irelfn->r_addend;
+
+ /* See if this function call can be shortened. */
+ foff = (symval
+ - (irel->r_offset
+ + sec->output_section->vma
+ + sec->output_offset
+ + 4));
+ /* A branch to an address beyond ours might be increased by an
+ .align that doesn't move when bytes behind us are deleted.
+ So, we add some slop in this calculation to allow for
+ that. */
+ if (foff < -0x1000 || foff >= 0x1000 - 8)
+ {
+ /* 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;
+ elf_section_data (sec)->this_hdr.contents = contents;
+ symtab_hdr->contents = (unsigned char *) isymbuf;
+
+ /* Replace the jmp/jsr with a bra/bsr. */
+
+ /* Change the R_SH_USES reloc into an R_SH_IND12W reloc, and
+ replace the jmp/jsr with a bra/bsr. */
+ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irelfn->r_info), R_SH_IND12W);
+ /* We used to test (ELF32_R_SYM (irelfn->r_info) < symtab_hdr->sh_info)
+ here, but that only checks if the symbol is an external symbol,
+ not if the symbol is in a different section. Besides, we need
+ a consistent meaning for the relocation, so we just assume here that
+ the value of the symbol is not available. */
+
+ /* 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. */
+ if (bfd_get_16 (abfd, contents + irel->r_offset) & 0x0020)
+ bfd_put_16 (abfd, (bfd_vma) 0xa000, contents + irel->r_offset);
+ else
+ bfd_put_16 (abfd, (bfd_vma) 0xb000, contents + irel->r_offset);
+
+ irel->r_addend = -4;
+
+ /* When we calculated the symbol "value" we had an offset in the
+ DIR32's word in memory (we read and add it above). However,
+ the jsr we create does NOT have this offset encoded, so we
+ have to add it to the addend to preserve it. */
+ irel->r_addend += bfd_get_32 (abfd, contents + paddr);
+
+ /* 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)
+ (_("%B: 0x%lx: warning: could not find expected COUNT reloc"),
+ 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) (_("%B: 0x%lx: warning: bad count"),
+ 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 ((elf_elfheader (abfd)->e_flags & EF_SH_MACH_MASK) != EF_SH4
+ && have_code)
+ {
+ bfd_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
+ {
+ if (!bfd_malloc_and_get_section (abfd, sec, &contents))
+ 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;
+ elf_section_data (sec)->this_hdr.contents = contents;
+ symtab_hdr->contents = (unsigned char *) isymbuf;
+ }
+ }
+
+ if (isymbuf != NULL
+ && symtab_hdr->contents != (unsigned char *) isymbuf)
+ {
+ if (! link_info->keep_memory)
+ free (isymbuf);
+ else
+ {
+ /* Cache the symbols for elf_link_input_bfd. */
+ symtab_hdr->contents = (unsigned char *) isymbuf;
+ }
+ }
+
+ if (contents != NULL
+ && elf_section_data (sec)->this_hdr.contents != contents)
+ {
+ if (! link_info->keep_memory)
+ free (contents);
+ else
+ {
+ /* Cache the section contents for elf_link_input_bfd. */
+ elf_section_data (sec)->this_hdr.contents = contents;
+ }
+ }
+
+ if (internal_relocs != NULL
+ && elf_section_data (sec)->relocs != internal_relocs)
+ free (internal_relocs);
+
+ return TRUE;
+
+ error_return:
+ if (isymbuf != NULL
+ && symtab_hdr->contents != (unsigned char *) isymbuf)
+ free (isymbuf);
+ if (contents != NULL
+ && elf_section_data (sec)->this_hdr.contents != contents)
+ free (contents);
+ if (internal_relocs != NULL
+ && elf_section_data (sec)->relocs != internal_relocs)
+ free (internal_relocs);
+
+ 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 bfd_boolean
+sh_elf_relax_delete_bytes (bfd *abfd, asection *sec, bfd_vma addr,
+ int count)
+{
+ Elf_Internal_Shdr *symtab_hdr;
+ unsigned int sec_shndx;
+ bfd_byte *contents;
+ Elf_Internal_Rela *irel, *irelend;
+ Elf_Internal_Rela *irelalign;
+ bfd_vma toaddr;
+ Elf_Internal_Sym *isymbuf, *isym, *isymend;
+ struct elf_link_hash_entry **sym_hashes;
+ struct elf_link_hash_entry **end_hashes;
+ unsigned int symcount;
+ asection *o;
+
+ symtab_hdr = &elf_symtab_hdr (abfd);
+ isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
+
+ sec_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->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,
+ (size_t) (toaddr - addr - count));
+ if (irelalign == NULL)
+ sec->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, (bfd_vma) 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;
+ int off, adjust, oinsn;
+ bfd_signed_vma voff = 0;
+ bfd_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)
+ {
+ isym = isymbuf + ELF32_R_SYM (irel->r_info);
+ if (isym->st_shndx == sec_shndx
+ && (isym->st_value <= addr
+ || isym->st_value >= toaddr))
+ {
+ bfd_vma val;
+
+ if (get_howto_table (abfd)[R_SH_DIR32].partial_inplace)
+ {
+ val = bfd_get_32 (abfd, contents + nraddr);
+ val += isym->st_value;
+ if (val > addr && val < toaddr)
+ bfd_put_32 (abfd, val - count, contents + nraddr);
+ }
+ else
+ {
+ val = isym->st_value + irel->r_addend;
+ if (val > addr && val < toaddr)
+ irel->r_addend -= count;
+ }
+ }
+ }
+ 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:
+ off = insn & 0xfff;
+ if (! off)
+ {
+ /* This has been made by previous relaxation. Since the
+ relocation will be against an external symbol, the
+ final relocation will just do the right thing. */
+ start = stop = addr;
+ }
+ else
+ {
+ if (off & 0x800)
+ off -= 0x1000;
+ stop = (bfd_vma) ((bfd_signed_vma) start + 4 + off * 2);
+
+ /* The addend will be against the section symbol, thus
+ for adjusting the addend, the relevant start is the
+ start of the section.
+ N.B. If we want to abandon in-place changes here and
+ test directly using symbol + addend, we have to take into
+ account that the addend has already been adjusted by -4. */
+ if (stop > addr && stop < toaddr)
+ irel->r_addend -= count;
+ }
+ 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_addend 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.
+ N.B. in gas / coff bfd, the elf bfd r_addend is called r_offset,
+ and the elf bfd r_offset is called r_vaddr. */
+
+ stop = irel->r_offset;
+ start = (bfd_vma) ((bfd_signed_vma) stop - (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;
+
+ 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, (bfd_vma) insn, contents + nraddr);
+ break;
+
+ case R_SH_IND12W:
+ insn += adjust / 2;
+ if ((oinsn & 0xf000) != (insn & 0xf000))
+ overflow = TRUE;
+ bfd_put_16 (abfd, (bfd_vma) 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, (bfd_vma) 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, (bfd_vma) voff, contents + nraddr);
+ break;
+
+ case R_SH_SWITCH32:
+ voff += adjust;
+ bfd_put_signed_32 (abfd, (bfd_vma) voff, contents + nraddr);
+ break;
+
+ case R_SH_USES:
+ irel->r_addend += adjust;
+ break;
+ }
+
+ if (overflow)
+ {
+ ((*_bfd_error_handler)
+ (_("%B: 0x%lx: fatal: reloc overflow while relaxing"),
+ 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_elf_link_read_relocs
+ (abfd, o, 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++)
+ {
+ /* Dwarf line numbers use R_SH_SWITCH32 relocs. */
+ if (ELF32_R_TYPE (irelscan->r_info) == (int) R_SH_SWITCH32)
+ {
+ bfd_vma start, stop;
+ bfd_signed_vma voff;
+
+ 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. */
+ if (!bfd_malloc_and_get_section (abfd, o, &ocontents))
+ {
+ if (ocontents != NULL)
+ free (ocontents);
+ return FALSE;
+ }
+
+ elf_section_data (o)->this_hdr.contents = ocontents;
+ }
+ }
+
+ stop = irelscan->r_offset;
+ start
+ = (bfd_vma) ((bfd_signed_vma) stop - (long) irelscan->r_addend);
+
+ /* STOP is in a different section, so it won't change. */
+ if (start > addr && start < toaddr)
+ irelscan->r_addend += count;
+
+ voff = bfd_get_signed_32 (abfd, ocontents + irelscan->r_offset);
+ stop = (bfd_vma) ((bfd_signed_vma) start + voff);
+
+ if (start > addr
+ && start < toaddr
+ && (stop <= addr || stop >= toaddr))
+ bfd_put_signed_32 (abfd, (bfd_vma) voff + count,
+ ocontents + irelscan->r_offset);
+ else if (stop > addr
+ && stop < toaddr
+ && (start <= addr || start >= toaddr))
+ bfd_put_signed_32 (abfd, (bfd_vma) voff - count,
+ ocontents + irelscan->r_offset);
+ }
+
+ if (ELF32_R_TYPE (irelscan->r_info) != (int) R_SH_DIR32)
+ continue;
+
+ if (ELF32_R_SYM (irelscan->r_info) >= symtab_hdr->sh_info)
+ continue;
+
+
+ isym = isymbuf + ELF32_R_SYM (irelscan->r_info);
+ if (isym->st_shndx == sec_shndx
+ && (isym->st_value <= addr
+ || isym->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. */
+ if (!bfd_malloc_and_get_section (abfd, o, &ocontents))
+ {
+ if (ocontents != NULL)
+ free (ocontents);
+ return FALSE;
+ }
+
+ elf_section_data (o)->this_hdr.contents = ocontents;
+ }
+ }
+
+ val = bfd_get_32 (abfd, ocontents + irelscan->r_offset);
+ val += isym->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. */
+ isymend = isymbuf + symtab_hdr->sh_info;
+ for (isym = isymbuf; isym < isymend; isym++)
+ {
+ if (isym->st_shndx == sec_shndx
+ && isym->st_value > addr
+ && isym->st_value < toaddr)
+ isym->st_value -= count;
+ }
+
+ /* Now adjust the global symbols defined in this section. */
+ symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
+ - symtab_hdr->sh_info);
+ sym_hashes = elf_sym_hashes (abfd);
+ end_hashes = sym_hashes + symcount;
+ for (; sym_hashes < end_hashes; sym_hashes++)
+ {
+ struct elf_link_hash_entry *sym_hash = *sym_hashes;
+ 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
+ && 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,
+ (int) (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 bfd_boolean
+sh_elf_align_loads (bfd *abfd ATTRIBUTE_UNUSED, asection *sec,
+ Elf_Internal_Rela *internal_relocs,
+ bfd_byte *contents ATTRIBUTE_UNUSED,
+ bfd_boolean *pswapped)
+{
+ Elf_Internal_Rela *irel, *irelend;
+ bfd_vma *labels = NULL;
+ bfd_vma *label, *label_end;
+ bfd_size_type amt;
+
+ *pswapped = FALSE;
+
+ irelend = internal_relocs + sec->reloc_count;
+
+ /* Get all the addresses with labels on them. */
+ amt = sec->reloc_count;
+ amt *= sizeof (bfd_vma);
+ labels = (bfd_vma *) bfd_malloc (amt);
+ 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->size;
+
+ if (! _bfd_sh_align_load_span (abfd, sec, contents, sh_elf_swap_insns,
+ internal_relocs, &label,
+ label_end, start, stop, pswapped))
+ goto error_return;
+ }
+
+ free (labels);
+
+ return TRUE;
+
+ error_return:
+ if (labels != NULL)
+ free (labels);
+ return FALSE;
+}
+
+#ifndef SH64_ELF
+/* Swap two SH instructions. This is like sh_swap_insns in coff-sh.c. */
+
+static bfd_boolean
+sh_elf_swap_insns (bfd *abfd, asection *sec, void *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, (bfd_vma) i2, contents + addr);
+ bfd_put_16 (abfd, (bfd_vma) 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;
+ bfd_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, (bfd_vma) 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, (bfd_vma) 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, (bfd_vma) insn, loc);
+ }
+
+ break;
+ }
+
+ if (overflow)
+ {
+ ((*_bfd_error_handler)
+ (_("%B: 0x%lx: fatal: reloc overflow while relaxing"),
+ abfd, (unsigned long) irel->r_offset));
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+ }
+ }
+
+ return TRUE;
+}
+#endif /* defined SH64_ELF */
+
+/* Describes one of the various PLT styles. */
+
+struct elf_sh_plt_info
+{
+ /* The template for the first PLT entry, or NULL if there is no special
+ first entry. */
+ const bfd_byte *plt0_entry;
+
+ /* The size of PLT0_ENTRY in bytes, or 0 if PLT0_ENTRY is NULL. */
+ bfd_vma plt0_entry_size;
+
+ /* Index I is the offset into PLT0_ENTRY of a pointer to
+ _GLOBAL_OFFSET_TABLE_ + I * 4. The value is MINUS_ONE
+ if there is no such pointer. */
+ bfd_vma plt0_got_fields[3];
+
+ /* The template for a symbol's PLT entry. */
+ const bfd_byte *symbol_entry;
+
+ /* The size of SYMBOL_ENTRY in bytes. */
+ bfd_vma symbol_entry_size;
+
+ /* Byte offsets of fields in SYMBOL_ENTRY. Not all fields are used
+ on all targets. The comments by each member indicate the value
+ that the field must hold. */
+ struct {
+ bfd_vma got_entry; /* the address of the symbol's .got.plt entry */
+ bfd_vma plt; /* .plt (or a branch to .plt on VxWorks) */
+ bfd_vma reloc_offset; /* the offset of the symbol's JMP_SLOT reloc */
+ bfd_boolean got20; /* TRUE if got_entry points to a movi20
+ instruction (instead of a constant pool
+ entry). */
+ } symbol_fields;
+
+ /* The offset of the resolver stub from the start of SYMBOL_ENTRY. */
+ bfd_vma symbol_resolve_offset;
+
+ /* A different PLT layout which can be used for the first
+ MAX_SHORT_PLT entries. It must share the same plt0. NULL in
+ other cases. */
+ const struct elf_sh_plt_info *short_plt;
+};
+
+#ifdef INCLUDE_SHMEDIA
+
+/* The size in bytes of an entry in the procedure linkage table. */
+
+#define ELF_PLT_ENTRY_SIZE 64
+
+/* First entry in an absolute procedure linkage table look like this. */
+
+static const bfd_byte elf_sh_plt0_entry_be[ELF_PLT_ENTRY_SIZE] =
+{
+ 0xcc, 0x00, 0x01, 0x10, /* movi .got.plt >> 16, r17 */
+ 0xc8, 0x00, 0x01, 0x10, /* shori .got.plt & 65535, r17 */
+ 0x89, 0x10, 0x09, 0x90, /* ld.l r17, 8, r25 */
+ 0x6b, 0xf1, 0x66, 0x00, /* ptabs r25, tr0 */
+ 0x89, 0x10, 0x05, 0x10, /* ld.l r17, 4, r17 */
+ 0x44, 0x01, 0xff, 0xf0, /* blink tr0, r63 */
+ 0x6f, 0xf0, 0xff, 0xf0, /* nop */
+ 0x6f, 0xf0, 0xff, 0xf0, /* nop */
+ 0x6f, 0xf0, 0xff, 0xf0, /* nop */
+ 0x6f, 0xf0, 0xff, 0xf0, /* nop */
+ 0x6f, 0xf0, 0xff, 0xf0, /* nop */
+ 0x6f, 0xf0, 0xff, 0xf0, /* nop */
+ 0x6f, 0xf0, 0xff, 0xf0, /* nop */
+ 0x6f, 0xf0, 0xff, 0xf0, /* nop */
+ 0x6f, 0xf0, 0xff, 0xf0, /* nop */
+ 0x6f, 0xf0, 0xff, 0xf0, /* nop */
+};
+
+static const bfd_byte elf_sh_plt0_entry_le[ELF_PLT_ENTRY_SIZE] =
+{
+ 0x10, 0x01, 0x00, 0xcc, /* movi .got.plt >> 16, r17 */
+ 0x10, 0x01, 0x00, 0xc8, /* shori .got.plt & 65535, r17 */
+ 0x90, 0x09, 0x10, 0x89, /* ld.l r17, 8, r25 */
+ 0x00, 0x66, 0xf1, 0x6b, /* ptabs r25, tr0 */
+ 0x10, 0x05, 0x10, 0x89, /* ld.l r17, 4, r17 */
+ 0xf0, 0xff, 0x01, 0x44, /* blink tr0, r63 */
+ 0xf0, 0xff, 0xf0, 0x6f, /* nop */
+ 0xf0, 0xff, 0xf0, 0x6f, /* nop */
+ 0xf0, 0xff, 0xf0, 0x6f, /* nop */
+ 0xf0, 0xff, 0xf0, 0x6f, /* nop */
+ 0xf0, 0xff, 0xf0, 0x6f, /* nop */
+ 0xf0, 0xff, 0xf0, 0x6f, /* nop */
+ 0xf0, 0xff, 0xf0, 0x6f, /* nop */
+ 0xf0, 0xff, 0xf0, 0x6f, /* nop */
+ 0xf0, 0xff, 0xf0, 0x6f, /* nop */
+ 0xf0, 0xff, 0xf0, 0x6f, /* nop */
+};
+
+/* Sebsequent entries in an absolute procedure linkage table look like
+ this. */
+
+static const bfd_byte elf_sh_plt_entry_be[ELF_PLT_ENTRY_SIZE] =
+{
+ 0xcc, 0x00, 0x01, 0x90, /* movi nameN-in-GOT >> 16, r25 */
+ 0xc8, 0x00, 0x01, 0x90, /* shori nameN-in-GOT & 65535, r25 */
+ 0x89, 0x90, 0x01, 0x90, /* ld.l r25, 0, r25 */
+ 0x6b, 0xf1, 0x66, 0x00, /* ptabs r25, tr0 */
+ 0x44, 0x01, 0xff, 0xf0, /* blink tr0, r63 */
+ 0x6f, 0xf0, 0xff, 0xf0, /* nop */
+ 0x6f, 0xf0, 0xff, 0xf0, /* nop */
+ 0x6f, 0xf0, 0xff, 0xf0, /* nop */
+ 0xcc, 0x00, 0x01, 0x90, /* movi .PLT0 >> 16, r25 */
+ 0xc8, 0x00, 0x01, 0x90, /* shori .PLT0 & 65535, r25 */
+ 0x6b, 0xf1, 0x66, 0x00, /* ptabs r25, tr0 */
+ 0xcc, 0x00, 0x01, 0x50, /* movi reloc-offset >> 16, r21 */
+ 0xc8, 0x00, 0x01, 0x50, /* shori reloc-offset & 65535, r21 */
+ 0x44, 0x01, 0xff, 0xf0, /* blink tr0, r63 */
+ 0x6f, 0xf0, 0xff, 0xf0, /* nop */
+ 0x6f, 0xf0, 0xff, 0xf0, /* nop */
+};
+
+static const bfd_byte elf_sh_plt_entry_le[ELF_PLT_ENTRY_SIZE] =
+{
+ 0x90, 0x01, 0x00, 0xcc, /* movi nameN-in-GOT >> 16, r25 */
+ 0x90, 0x01, 0x00, 0xc8, /* shori nameN-in-GOT & 65535, r25 */
+ 0x90, 0x01, 0x90, 0x89, /* ld.l r25, 0, r25 */
+ 0x00, 0x66, 0xf1, 0x6b, /* ptabs r25, tr0 */
+ 0xf0, 0xff, 0x01, 0x44, /* blink tr0, r63 */
+ 0xf0, 0xff, 0xf0, 0x6f, /* nop */
+ 0xf0, 0xff, 0xf0, 0x6f, /* nop */
+ 0xf0, 0xff, 0xf0, 0x6f, /* nop */
+ 0x90, 0x01, 0x00, 0xcc, /* movi .PLT0 >> 16, r25 */
+ 0x90, 0x01, 0x00, 0xc8, /* shori .PLT0 & 65535, r25 */
+ 0x00, 0x66, 0xf1, 0x6b, /* ptabs r25, tr0 */
+ 0x50, 0x01, 0x00, 0xcc, /* movi reloc-offset >> 16, r21 */
+ 0x50, 0x01, 0x00, 0xc8, /* shori reloc-offset & 65535, r21 */
+ 0xf0, 0xff, 0x01, 0x44, /* blink tr0, r63 */
+ 0xf0, 0xff, 0xf0, 0x6f, /* nop */
+ 0xf0, 0xff, 0xf0, 0x6f, /* nop */
+};
+
+/* Entries in a PIC procedure linkage table look like this. */
+
+static const bfd_byte elf_sh_pic_plt_entry_be[ELF_PLT_ENTRY_SIZE] =
+{
+ 0xcc, 0x00, 0x01, 0x90, /* movi nameN@GOT >> 16, r25 */
+ 0xc8, 0x00, 0x01, 0x90, /* shori nameN@GOT & 65535, r25 */
+ 0x40, 0xc2, 0x65, 0x90, /* ldx.l r12, r25, r25 */
+ 0x6b, 0xf1, 0x66, 0x00, /* ptabs r25, tr0 */
+ 0x44, 0x01, 0xff, 0xf0, /* blink tr0, r63 */
+ 0x6f, 0xf0, 0xff, 0xf0, /* nop */
+ 0x6f, 0xf0, 0xff, 0xf0, /* nop */
+ 0x6f, 0xf0, 0xff, 0xf0, /* nop */
+ 0xce, 0x00, 0x01, 0x10, /* movi -GOT_BIAS, r17 */
+ 0x00, 0xc8, 0x45, 0x10, /* add.l r12, r17, r17 */
+ 0x89, 0x10, 0x09, 0x90, /* ld.l r17, 8, r25 */
+ 0x6b, 0xf1, 0x66, 0x00, /* ptabs r25, tr0 */
+ 0x89, 0x10, 0x05, 0x10, /* ld.l r17, 4, r17 */
+ 0xcc, 0x00, 0x01, 0x50, /* movi reloc-offset >> 16, r21 */
+ 0xc8, 0x00, 0x01, 0x50, /* shori reloc-offset & 65535, r21 */
+ 0x44, 0x01, 0xff, 0xf0, /* blink tr0, r63 */
+};
+
+static const bfd_byte elf_sh_pic_plt_entry_le[ELF_PLT_ENTRY_SIZE] =
+{
+ 0x90, 0x01, 0x00, 0xcc, /* movi nameN@GOT >> 16, r25 */
+ 0x90, 0x01, 0x00, 0xc8, /* shori nameN@GOT & 65535, r25 */
+ 0x90, 0x65, 0xc2, 0x40, /* ldx.l r12, r25, r25 */
+ 0x00, 0x66, 0xf1, 0x6b, /* ptabs r25, tr0 */
+ 0xf0, 0xff, 0x01, 0x44, /* blink tr0, r63 */
+ 0xf0, 0xff, 0xf0, 0x6f, /* nop */
+ 0xf0, 0xff, 0xf0, 0x6f, /* nop */
+ 0xf0, 0xff, 0xf0, 0x6f, /* nop */
+ 0x10, 0x01, 0x00, 0xce, /* movi -GOT_BIAS, r17 */
+ 0x10, 0x45, 0xc8, 0x00, /* add.l r12, r17, r17 */
+ 0x90, 0x09, 0x10, 0x89, /* ld.l r17, 8, r25 */
+ 0x00, 0x66, 0xf1, 0x6b, /* ptabs r25, tr0 */
+ 0x10, 0x05, 0x10, 0x89, /* ld.l r17, 4, r17 */
+ 0x50, 0x01, 0x00, 0xcc, /* movi reloc-offset >> 16, r21 */
+ 0x50, 0x01, 0x00, 0xc8, /* shori reloc-offset & 65535, r21 */
+ 0xf0, 0xff, 0x01, 0x44, /* blink tr0, r63 */
+};
+
+static const struct elf_sh_plt_info elf_sh_plts[2][2] = {
+ {
+ {
+ /* Big-endian non-PIC. */
+ elf_sh_plt0_entry_be,
+ ELF_PLT_ENTRY_SIZE,
+ { 0, MINUS_ONE, MINUS_ONE },
+ elf_sh_plt_entry_be,
+ ELF_PLT_ENTRY_SIZE,
+ { 0, 32, 48, FALSE },
+ 33, /* includes ISA encoding */
+ NULL
+ },
+ {
+ /* Little-endian non-PIC. */
+ elf_sh_plt0_entry_le,
+ ELF_PLT_ENTRY_SIZE,
+ { 0, MINUS_ONE, MINUS_ONE },
+ elf_sh_plt_entry_le,
+ ELF_PLT_ENTRY_SIZE,
+ { 0, 32, 48, FALSE },
+ 33, /* includes ISA encoding */
+ NULL
+ },
+ },
+ {
+ {
+ /* Big-endian PIC. */
+ elf_sh_plt0_entry_be,
+ ELF_PLT_ENTRY_SIZE,
+ { MINUS_ONE, MINUS_ONE, MINUS_ONE },
+ elf_sh_pic_plt_entry_be,
+ ELF_PLT_ENTRY_SIZE,
+ { 0, MINUS_ONE, 52, FALSE },
+ 33, /* includes ISA encoding */
+ NULL
+ },
+ {
+ /* Little-endian PIC. */
+ elf_sh_plt0_entry_le,
+ ELF_PLT_ENTRY_SIZE,
+ { MINUS_ONE, MINUS_ONE, MINUS_ONE },
+ elf_sh_pic_plt_entry_le,
+ ELF_PLT_ENTRY_SIZE,
+ { 0, MINUS_ONE, 52, FALSE },
+ 33, /* includes ISA encoding */
+ NULL
+ },
+ }
+};
+
+/* Return offset of the linker in PLT0 entry. */
+#define elf_sh_plt0_gotplt_offset(info) 0
+
+/* Install a 32-bit PLT field starting at ADDR, which occurs in OUTPUT_BFD.
+ VALUE is the field's value and CODE_P is true if VALUE refers to code,
+ not data.
+
+ On SH64, each 32-bit field is loaded by a movi/shori pair. */
+
+inline static void
+install_plt_field (bfd *output_bfd, bfd_boolean code_p,
+ unsigned long value, bfd_byte *addr)
+{
+ value |= code_p;
+ bfd_put_32 (output_bfd,
+ bfd_get_32 (output_bfd, addr)
+ | ((value >> 6) & 0x3fffc00),
+ addr);
+ bfd_put_32 (output_bfd,
+ bfd_get_32 (output_bfd, addr + 4)
+ | ((value << 10) & 0x3fffc00),
+ addr + 4);
+}
+
+/* Return the type of PLT associated with ABFD. PIC_P is true if
+ the object is position-independent. */
+
+static const struct elf_sh_plt_info *
+get_plt_info (bfd *abfd ATTRIBUTE_UNUSED, bfd_boolean pic_p)
+{
+ return &elf_sh_plts[pic_p][!bfd_big_endian (abfd)];
+}
+#else
+/* The size in bytes of an entry in the procedure linkage table. */
+
+#define ELF_PLT_ENTRY_SIZE 28
+
+/* First entry in an absolute procedure linkage table look like this. */
+
+/* Note - this code has been "optimised" not to use r2. r2 is used by
+ GCC to return the address of large structures, so it should not be
+ corrupted here. This does mean however, that this PLT does not conform
+ to the SH PIC ABI. That spec says that r0 contains the type of the PLT
+ and r2 contains the GOT id. This version stores the GOT id in r0 and
+ ignores the type. Loaders can easily detect this difference however,
+ since the type will always be 0 or 8, and the GOT ids will always be
+ greater than or equal to 12. */
+static const bfd_byte elf_sh_plt0_entry_be[ELF_PLT_ENTRY_SIZE] =
+{
+ 0xd0, 0x05, /* mov.l 2f,r0 */
+ 0x60, 0x02, /* mov.l @r0,r0 */
+ 0x2f, 0x06, /* mov.l r0,@-r15 */
+ 0xd0, 0x03, /* mov.l 1f,r0 */
+ 0x60, 0x02, /* mov.l @r0,r0 */
+ 0x40, 0x2b, /* jmp @r0 */
+ 0x60, 0xf6, /* mov.l @r15+,r0 */
+ 0x00, 0x09, /* nop */
+ 0x00, 0x09, /* nop */
+ 0x00, 0x09, /* nop */
+ 0, 0, 0, 0, /* 1: replaced with address of .got.plt + 8. */
+ 0, 0, 0, 0, /* 2: replaced with address of .got.plt + 4. */
+};
+
+static const bfd_byte elf_sh_plt0_entry_le[ELF_PLT_ENTRY_SIZE] =
+{
+ 0x05, 0xd0, /* mov.l 2f,r0 */
+ 0x02, 0x60, /* mov.l @r0,r0 */
+ 0x06, 0x2f, /* mov.l r0,@-r15 */
+ 0x03, 0xd0, /* mov.l 1f,r0 */
+ 0x02, 0x60, /* mov.l @r0,r0 */
+ 0x2b, 0x40, /* jmp @r0 */
+ 0xf6, 0x60, /* mov.l @r15+,r0 */
+ 0x09, 0x00, /* nop */
+ 0x09, 0x00, /* nop */
+ 0x09, 0x00, /* nop */
+ 0, 0, 0, 0, /* 1: replaced with address of .got.plt + 8. */
+ 0, 0, 0, 0, /* 2: replaced with address of .got.plt + 4. */
+};
+
+/* Sebsequent entries in an absolute procedure linkage table look like
+ this. */
+
+static const bfd_byte elf_sh_plt_entry_be[ELF_PLT_ENTRY_SIZE] =
+{
+ 0xd0, 0x04, /* mov.l 1f,r0 */
+ 0x60, 0x02, /* mov.l @(r0,r12),r0 */
+ 0xd1, 0x02, /* mov.l 0f,r1 */
+ 0x40, 0x2b, /* jmp @r0 */
+ 0x60, 0x13, /* mov r1,r0 */
+ 0xd1, 0x03, /* mov.l 2f,r1 */
+ 0x40, 0x2b, /* jmp @r0 */
+ 0x00, 0x09, /* nop */
+ 0, 0, 0, 0, /* 0: replaced with address of .PLT0. */
+ 0, 0, 0, 0, /* 1: replaced with address of this symbol in .got. */
+ 0, 0, 0, 0, /* 2: replaced with offset into relocation table. */
+};
+
+static const bfd_byte elf_sh_plt_entry_le[ELF_PLT_ENTRY_SIZE] =
+{
+ 0x04, 0xd0, /* mov.l 1f,r0 */
+ 0x02, 0x60, /* mov.l @r0,r0 */
+ 0x02, 0xd1, /* mov.l 0f,r1 */
+ 0x2b, 0x40, /* jmp @r0 */
+ 0x13, 0x60, /* mov r1,r0 */
+ 0x03, 0xd1, /* mov.l 2f,r1 */
+ 0x2b, 0x40, /* jmp @r0 */
+ 0x09, 0x00, /* nop */
+ 0, 0, 0, 0, /* 0: replaced with address of .PLT0. */
+ 0, 0, 0, 0, /* 1: replaced with address of this symbol in .got. */
+ 0, 0, 0, 0, /* 2: replaced with offset into relocation table. */
+};
+
+/* Entries in a PIC procedure linkage table look like this. */
+
+static const bfd_byte elf_sh_pic_plt_entry_be[ELF_PLT_ENTRY_SIZE] =
+{
+ 0xd0, 0x04, /* mov.l 1f,r0 */
+ 0x00, 0xce, /* mov.l @(r0,r12),r0 */
+ 0x40, 0x2b, /* jmp @r0 */
+ 0x00, 0x09, /* nop */
+ 0x50, 0xc2, /* mov.l @(8,r12),r0 */
+ 0xd1, 0x03, /* mov.l 2f,r1 */
+ 0x40, 0x2b, /* jmp @r0 */
+ 0x50, 0xc1, /* mov.l @(4,r12),r0 */
+ 0x00, 0x09, /* nop */
+ 0x00, 0x09, /* nop */
+ 0, 0, 0, 0, /* 1: replaced with address of this symbol in .got. */
+ 0, 0, 0, 0 /* 2: replaced with offset into relocation table. */
+};
+
+static const bfd_byte elf_sh_pic_plt_entry_le[ELF_PLT_ENTRY_SIZE] =
+{
+ 0x04, 0xd0, /* mov.l 1f,r0 */
+ 0xce, 0x00, /* mov.l @(r0,r12),r0 */
+ 0x2b, 0x40, /* jmp @r0 */
+ 0x09, 0x00, /* nop */
+ 0xc2, 0x50, /* mov.l @(8,r12),r0 */
+ 0x03, 0xd1, /* mov.l 2f,r1 */
+ 0x2b, 0x40, /* jmp @r0 */
+ 0xc1, 0x50, /* mov.l @(4,r12),r0 */
+ 0x09, 0x00, /* nop */
+ 0x09, 0x00, /* nop */
+ 0, 0, 0, 0, /* 1: replaced with address of this symbol in .got. */
+ 0, 0, 0, 0 /* 2: replaced with offset into relocation table. */
+};
+
+static const struct elf_sh_plt_info elf_sh_plts[2][2] = {
+ {
+ {
+ /* Big-endian non-PIC. */
+ elf_sh_plt0_entry_be,
+ ELF_PLT_ENTRY_SIZE,
+ { MINUS_ONE, 24, 20 },
+ elf_sh_plt_entry_be,
+ ELF_PLT_ENTRY_SIZE,
+ { 20, 16, 24, FALSE },
+ 8,
+ NULL
+ },
+ {
+ /* Little-endian non-PIC. */
+ elf_sh_plt0_entry_le,
+ ELF_PLT_ENTRY_SIZE,
+ { MINUS_ONE, 24, 20 },
+ elf_sh_plt_entry_le,
+ ELF_PLT_ENTRY_SIZE,
+ { 20, 16, 24, FALSE },
+ 8,
+ NULL
+ },
+ },
+ {
+ {
+ /* Big-endian PIC. */
+ elf_sh_plt0_entry_be,
+ ELF_PLT_ENTRY_SIZE,
+ { MINUS_ONE, MINUS_ONE, MINUS_ONE },
+ elf_sh_pic_plt_entry_be,
+ ELF_PLT_ENTRY_SIZE,
+ { 20, MINUS_ONE, 24, FALSE },
+ 8,
+ NULL
+ },
+ {
+ /* Little-endian PIC. */
+ elf_sh_plt0_entry_le,
+ ELF_PLT_ENTRY_SIZE,
+ { MINUS_ONE, MINUS_ONE, MINUS_ONE },
+ elf_sh_pic_plt_entry_le,
+ ELF_PLT_ENTRY_SIZE,
+ { 20, MINUS_ONE, 24, FALSE },
+ 8,
+ NULL
+ },
+ }
+};
+
+#define VXWORKS_PLT_HEADER_SIZE 12
+#define VXWORKS_PLT_ENTRY_SIZE 24
+
+static const bfd_byte vxworks_sh_plt0_entry_be[VXWORKS_PLT_HEADER_SIZE] =
+{
+ 0xd1, 0x01, /* mov.l @(8,pc),r1 */
+ 0x61, 0x12, /* mov.l @r1,r1 */
+ 0x41, 0x2b, /* jmp @r1 */
+ 0x00, 0x09, /* nop */
+ 0, 0, 0, 0 /* 0: replaced with _GLOBAL_OFFSET_TABLE+8. */
+};
+
+static const bfd_byte vxworks_sh_plt0_entry_le[VXWORKS_PLT_HEADER_SIZE] =
+{
+ 0x01, 0xd1, /* mov.l @(8,pc),r1 */
+ 0x12, 0x61, /* mov.l @r1,r1 */
+ 0x2b, 0x41, /* jmp @r1 */
+ 0x09, 0x00, /* nop */
+ 0, 0, 0, 0 /* 0: replaced with _GLOBAL_OFFSET_TABLE+8. */
+};
+
+static const bfd_byte vxworks_sh_plt_entry_be[VXWORKS_PLT_ENTRY_SIZE] =
+{
+ 0xd0, 0x01, /* mov.l @(8,pc),r0 */
+ 0x60, 0x02, /* mov.l @r0,r0 */
+ 0x40, 0x2b, /* jmp @r0 */
+ 0x00, 0x09, /* nop */
+ 0, 0, 0, 0, /* 0: replaced with address of this symbol in .got. */
+ 0xd0, 0x01, /* mov.l @(8,pc),r0 */
+ 0xa0, 0x00, /* bra PLT (We need to fix the offset.) */
+ 0x00, 0x09, /* nop */
+ 0x00, 0x09, /* nop */
+ 0, 0, 0, 0, /* 1: replaced with offset into relocation table. */
+};
+
+static const bfd_byte vxworks_sh_plt_entry_le[VXWORKS_PLT_ENTRY_SIZE] =
+{
+ 0x01, 0xd0, /* mov.l @(8,pc),r0 */
+ 0x02, 0x60, /* mov.l @r0,r0 */
+ 0x2b, 0x40, /* jmp @r0 */
+ 0x09, 0x00, /* nop */
+ 0, 0, 0, 0, /* 0: replaced with address of this symbol in .got. */
+ 0x01, 0xd0, /* mov.l @(8,pc),r0 */
+ 0x00, 0xa0, /* bra PLT (We need to fix the offset.) */
+ 0x09, 0x00, /* nop */
+ 0x09, 0x00, /* nop */
+ 0, 0, 0, 0, /* 1: replaced with offset into relocation table. */
+};
+
+static const bfd_byte vxworks_sh_pic_plt_entry_be[VXWORKS_PLT_ENTRY_SIZE] =
+{
+ 0xd0, 0x01, /* mov.l @(8,pc),r0 */
+ 0x00, 0xce, /* mov.l @(r0,r12),r0 */
+ 0x40, 0x2b, /* jmp @r0 */
+ 0x00, 0x09, /* nop */
+ 0, 0, 0, 0, /* 0: replaced with offset of this symbol in .got. */
+ 0xd0, 0x01, /* mov.l @(8,pc),r0 */
+ 0x51, 0xc2, /* mov.l @(8,r12),r1 */
+ 0x41, 0x2b, /* jmp @r1 */
+ 0x00, 0x09, /* nop */
+ 0, 0, 0, 0, /* 1: replaced with offset into relocation table. */
+};
+
+static const bfd_byte vxworks_sh_pic_plt_entry_le[VXWORKS_PLT_ENTRY_SIZE] =
+{
+ 0x01, 0xd0, /* mov.l @(8,pc),r0 */
+ 0xce, 0x00, /* mov.l @(r0,r12),r0 */
+ 0x2b, 0x40, /* jmp @r0 */
+ 0x09, 0x00, /* nop */
+ 0, 0, 0, 0, /* 0: replaced with offset of this symbol in .got. */
+ 0x01, 0xd0, /* mov.l @(8,pc),r0 */
+ 0xc2, 0x51, /* mov.l @(8,r12),r1 */
+ 0x2b, 0x41, /* jmp @r1 */
+ 0x09, 0x00, /* nop */
+ 0, 0, 0, 0, /* 1: replaced with offset into relocation table. */
+};
+
+static const struct elf_sh_plt_info vxworks_sh_plts[2][2] = {
+ {
+ {
+ /* Big-endian non-PIC. */
+ vxworks_sh_plt0_entry_be,
+ VXWORKS_PLT_HEADER_SIZE,
+ { MINUS_ONE, MINUS_ONE, 8 },
+ vxworks_sh_plt_entry_be,
+ VXWORKS_PLT_ENTRY_SIZE,
+ { 8, 14, 20, FALSE },
+ 12,
+ NULL
+ },
+ {
+ /* Little-endian non-PIC. */
+ vxworks_sh_plt0_entry_le,
+ VXWORKS_PLT_HEADER_SIZE,
+ { MINUS_ONE, MINUS_ONE, 8 },
+ vxworks_sh_plt_entry_le,
+ VXWORKS_PLT_ENTRY_SIZE,
+ { 8, 14, 20, FALSE },
+ 12,
+ NULL
+ },
+ },
+ {
+ {
+ /* Big-endian PIC. */
+ NULL,
+ 0,
+ { MINUS_ONE, MINUS_ONE, MINUS_ONE },
+ vxworks_sh_pic_plt_entry_be,
+ VXWORKS_PLT_ENTRY_SIZE,
+ { 8, MINUS_ONE, 20, FALSE },
+ 12,
+ NULL
+ },
+ {
+ /* Little-endian PIC. */
+ NULL,
+ 0,
+ { MINUS_ONE, MINUS_ONE, MINUS_ONE },
+ vxworks_sh_pic_plt_entry_le,
+ VXWORKS_PLT_ENTRY_SIZE,
+ { 8, MINUS_ONE, 20, FALSE },
+ 12,
+ NULL
+ },
+ }
+};
+
+/* FDPIC PLT entries. Two unimplemented optimizations for lazy
+ binding are to omit the lazy binding stub when linking with -z now
+ and to move lazy binding stubs into a separate region for better
+ cache behavior. */
+
+#define FDPIC_PLT_ENTRY_SIZE 28
+#define FDPIC_PLT_LAZY_OFFSET 20
+
+/* FIXME: The lazy binding stub requires a plt0 - which may need to be
+ duplicated if it is out of range, or which can be inlined. So
+ right now it is always inlined, which wastes a word per stub. It
+ might be easier to handle the duplication if we put the lazy
+ stubs separately. */
+
+static const bfd_byte fdpic_sh_plt_entry_be[FDPIC_PLT_ENTRY_SIZE] =
+{
+ 0xd0, 0x02, /* mov.l @(12,pc),r0 */
+ 0x01, 0xce, /* mov.l @(r0,r12),r1 */
+ 0x70, 0x04, /* add #4, r0 */
+ 0x41, 0x2b, /* jmp @r1 */
+ 0x0c, 0xce, /* mov.l @(r0,r12),r12 */
+ 0x00, 0x09, /* nop */
+ 0, 0, 0, 0, /* 0: replaced with offset of this symbol's funcdesc */
+ 0, 0, 0, 0, /* 1: replaced with offset into relocation table. */
+ 0x60, 0xc2, /* mov.l @r12,r0 */
+ 0x40, 0x2b, /* jmp @r0 */
+ 0x53, 0xc1, /* mov.l @(4,r12),r3 */
+ 0x00, 0x09, /* nop */
+};
+
+static const bfd_byte fdpic_sh_plt_entry_le[FDPIC_PLT_ENTRY_SIZE] =
+{
+ 0x02, 0xd0, /* mov.l @(12,pc),r0 */
+ 0xce, 0x01, /* mov.l @(r0,r12),r1 */
+ 0x04, 0x70, /* add #4, r0 */
+ 0x2b, 0x41, /* jmp @r1 */
+ 0xce, 0x0c, /* mov.l @(r0,r12),r12 */
+ 0x09, 0x00, /* nop */
+ 0, 0, 0, 0, /* 0: replaced with offset of this symbol's funcdesc */
+ 0, 0, 0, 0, /* 1: replaced with offset into relocation table. */
+ 0xc2, 0x60, /* mov.l @r12,r0 */
+ 0x2b, 0x40, /* jmp @r0 */
+ 0xc1, 0x53, /* mov.l @(4,r12),r3 */
+ 0x09, 0x00, /* nop */
+};
+
+static const struct elf_sh_plt_info fdpic_sh_plts[2] = {
+ {
+ /* Big-endian PIC. */
+ NULL,
+ 0,
+ { MINUS_ONE, MINUS_ONE, MINUS_ONE },
+ fdpic_sh_plt_entry_be,
+ FDPIC_PLT_ENTRY_SIZE,
+ { 12, MINUS_ONE, 16, FALSE },
+ FDPIC_PLT_LAZY_OFFSET,
+ NULL
+ },
+ {
+ /* Little-endian PIC. */
+ NULL,
+ 0,
+ { MINUS_ONE, MINUS_ONE, MINUS_ONE },
+ fdpic_sh_plt_entry_le,
+ FDPIC_PLT_ENTRY_SIZE,
+ { 12, MINUS_ONE, 16, FALSE },
+ FDPIC_PLT_LAZY_OFFSET,
+ NULL
+ },
+};
+
+/* On SH2A, we can use the movi20 instruction to generate shorter PLT
+ entries for the first 64K slots. We use the normal FDPIC PLT entry
+ past that point; we could also use movi20s, which might be faster,
+ but would not be any smaller. */
+
+#define FDPIC_SH2A_PLT_ENTRY_SIZE 24
+#define FDPIC_SH2A_PLT_LAZY_OFFSET 16
+
+static const bfd_byte fdpic_sh2a_plt_entry_be[FDPIC_SH2A_PLT_ENTRY_SIZE] =
+{
+ 0, 0, 0, 0, /* movi20 #gotofffuncdesc,r0 */
+ 0x01, 0xce, /* mov.l @(r0,r12),r1 */
+ 0x70, 0x04, /* add #4, r0 */
+ 0x41, 0x2b, /* jmp @r1 */
+ 0x0c, 0xce, /* mov.l @(r0,r12),r12 */
+ 0, 0, 0, 0, /* 1: replaced with offset into relocation table. */
+ 0x60, 0xc2, /* mov.l @r12,r0 */
+ 0x40, 0x2b, /* jmp @r0 */
+ 0x53, 0xc1, /* mov.l @(4,r12),r3 */
+ 0x00, 0x09, /* nop */
+};
+
+static const bfd_byte fdpic_sh2a_plt_entry_le[FDPIC_SH2A_PLT_ENTRY_SIZE] =
+{
+ 0, 0, 0, 0, /* movi20 #gotofffuncdesc,r0 */
+ 0xce, 0x01, /* mov.l @(r0,r12),r1 */
+ 0x04, 0x70, /* add #4, r0 */
+ 0x2b, 0x41, /* jmp @r1 */
+ 0xce, 0x0c, /* mov.l @(r0,r12),r12 */
+ 0, 0, 0, 0, /* 1: replaced with offset into relocation table. */
+ 0xc2, 0x60, /* mov.l @r12,r0 */
+ 0x2b, 0x40, /* jmp @r0 */
+ 0xc1, 0x53, /* mov.l @(4,r12),r3 */
+ 0x09, 0x00, /* nop */
+};
+
+static const struct elf_sh_plt_info fdpic_sh2a_short_plt_be = {
+ /* Big-endian FDPIC, max index 64K. */
+ NULL,
+ 0,
+ { MINUS_ONE, MINUS_ONE, MINUS_ONE },
+ fdpic_sh2a_plt_entry_be,
+ FDPIC_SH2A_PLT_ENTRY_SIZE,
+ { 0, MINUS_ONE, 12, TRUE },
+ FDPIC_SH2A_PLT_LAZY_OFFSET,
+ NULL
+};
+
+static const struct elf_sh_plt_info fdpic_sh2a_short_plt_le = {
+ /* Little-endian FDPIC, max index 64K. */
+ NULL,
+ 0,
+ { MINUS_ONE, MINUS_ONE, MINUS_ONE },
+ fdpic_sh2a_plt_entry_le,
+ FDPIC_SH2A_PLT_ENTRY_SIZE,
+ { 0, MINUS_ONE, 12, TRUE },
+ FDPIC_SH2A_PLT_LAZY_OFFSET,
+ NULL
+};
+
+static const struct elf_sh_plt_info fdpic_sh2a_plts[2] = {
+ {
+ /* Big-endian PIC. */
+ NULL,
+ 0,
+ { MINUS_ONE, MINUS_ONE, MINUS_ONE },
+ fdpic_sh_plt_entry_be,
+ FDPIC_PLT_ENTRY_SIZE,
+ { 12, MINUS_ONE, 16, FALSE },
+ FDPIC_PLT_LAZY_OFFSET,
+ &fdpic_sh2a_short_plt_be
+ },
+ {
+ /* Little-endian PIC. */
+ NULL,
+ 0,
+ { MINUS_ONE, MINUS_ONE, MINUS_ONE },
+ fdpic_sh_plt_entry_le,
+ FDPIC_PLT_ENTRY_SIZE,
+ { 12, MINUS_ONE, 16, FALSE },
+ FDPIC_PLT_LAZY_OFFSET,
+ &fdpic_sh2a_short_plt_le
+ },
+};
+
+/* Return the type of PLT associated with ABFD. PIC_P is true if
+ the object is position-independent. */
+
+static const struct elf_sh_plt_info *
+get_plt_info (bfd *abfd, bfd_boolean pic_p)
+{
+ if (fdpic_object_p (abfd))
+ {
+ /* If any input file requires SH2A we can use a shorter PLT
+ sequence. */
+ if (sh_get_arch_from_bfd_mach (bfd_get_mach (abfd)) & arch_sh2a_base)
+ return &fdpic_sh2a_plts[!bfd_big_endian (abfd)];
+ else
+ return &fdpic_sh_plts[!bfd_big_endian (abfd)];
+ }
+ if (vxworks_object_p (abfd))
+ return &vxworks_sh_plts[pic_p][!bfd_big_endian (abfd)];
+ return &elf_sh_plts[pic_p][!bfd_big_endian (abfd)];
+}
+
+/* Install a 32-bit PLT field starting at ADDR, which occurs in OUTPUT_BFD.
+ VALUE is the field's value and CODE_P is true if VALUE refers to code,
+ not data. */
+
+inline static void
+install_plt_field (bfd *output_bfd, bfd_boolean code_p ATTRIBUTE_UNUSED,
+ unsigned long value, bfd_byte *addr)
+{
+ bfd_put_32 (output_bfd, value, addr);
+}
+#endif
+
+/* The number of PLT entries which can use a shorter PLT, if any.
+ Currently always 64K, since only SH-2A FDPIC uses this; a
+ 20-bit movi20 can address that many function descriptors below
+ _GLOBAL_OFFSET_TABLE_. */
+#define MAX_SHORT_PLT 65536
+
+/* Return the index of the PLT entry at byte offset OFFSET. */
+
+static bfd_vma
+get_plt_index (const struct elf_sh_plt_info *info, bfd_vma offset)
+{
+ bfd_vma plt_index = 0;
+
+ offset -= info->plt0_entry_size;
+ if (info->short_plt != NULL)
+ {
+ if (offset > MAX_SHORT_PLT * info->short_plt->symbol_entry_size)
+ {
+ plt_index = MAX_SHORT_PLT;
+ offset -= MAX_SHORT_PLT * info->short_plt->symbol_entry_size;
+ }
+ else
+ info = info->short_plt;
+ }
+ return plt_index + offset / info->symbol_entry_size;
+}
+
+/* Do the inverse operation. */
+
+static bfd_vma
+get_plt_offset (const struct elf_sh_plt_info *info, bfd_vma plt_index)
+{
+ bfd_vma offset = 0;
+
+ if (info->short_plt != NULL)
+ {
+ if (plt_index > MAX_SHORT_PLT)
+ {
+ offset = MAX_SHORT_PLT * info->short_plt->symbol_entry_size;
+ plt_index -= MAX_SHORT_PLT;
+ }
+ else
+ info = info->short_plt;
+ }
+ return (offset + info->plt0_entry_size
+ + (plt_index * info->symbol_entry_size));
+}
+
+/* The sh linker needs to keep track of the number of relocs that it
+ decides to copy as dynamic relocs in check_relocs for each symbol.
+ This is so that it can later discard them if they are found to be
+ unnecessary. We store the information in a field extending the
+ regular ELF linker hash table. */
+
+struct elf_sh_dyn_relocs
+{
+ struct elf_sh_dyn_relocs *next;
+
+ /* The input section of the reloc. */
+ asection *sec;
+
+ /* Total number of relocs copied for the input section. */
+ bfd_size_type count;
+
+ /* Number of pc-relative relocs copied for the input section. */
+ bfd_size_type pc_count;
+};
+
+union gotref
+{
+ bfd_signed_vma refcount;
+ bfd_vma offset;
+};
+
+/* sh ELF linker hash entry. */
+
+struct elf_sh_link_hash_entry
+{
+ struct elf_link_hash_entry root;
+
+#ifdef INCLUDE_SHMEDIA
+ union
+ {
+ bfd_signed_vma refcount;
+ bfd_vma offset;
+ } datalabel_got;
+#endif
+
+ /* Track dynamic relocs copied for this symbol. */
+ struct elf_sh_dyn_relocs *dyn_relocs;
+
+ bfd_signed_vma gotplt_refcount;
+
+ /* A local function descriptor, for FDPIC. The refcount counts
+ R_SH_FUNCDESC, R_SH_GOTOFFFUNCDESC, and R_SH_GOTOFFFUNCDESC20
+ relocations; the PLT and GOT entry are accounted
+ for separately. After adjust_dynamic_symbol, the offset is
+ MINUS_ONE if there is no local descriptor (dynamic linker
+ managed and no PLT entry, or undefined weak non-dynamic).
+ During check_relocs we do not yet know whether the local
+ descriptor will be canonical. */
+ union gotref funcdesc;
+
+ /* How many of the above refcounted relocations were R_SH_FUNCDESC,
+ and thus require fixups or relocations. */
+ bfd_signed_vma abs_funcdesc_refcount;
+
+ enum got_type {
+ GOT_UNKNOWN = 0, GOT_NORMAL, GOT_TLS_GD, GOT_TLS_IE, GOT_FUNCDESC
+ } got_type;
+};
+
+#define sh_elf_hash_entry(ent) ((struct elf_sh_link_hash_entry *)(ent))
+
+struct sh_elf_obj_tdata
+{
+ struct elf_obj_tdata root;
+
+ /* got_type for each local got entry. */
+ char *local_got_type;
+
+ /* Function descriptor refcount and offset for each local symbol. */
+ union gotref *local_funcdesc;
+};
+
+#define sh_elf_tdata(abfd) \
+ ((struct sh_elf_obj_tdata *) (abfd)->tdata.any)
+
+#define sh_elf_local_got_type(abfd) \
+ (sh_elf_tdata (abfd)->local_got_type)
+
+#define sh_elf_local_funcdesc(abfd) \
+ (sh_elf_tdata (abfd)->local_funcdesc)
+
+#define is_sh_elf(bfd) \
+ (bfd_get_flavour (bfd) == bfd_target_elf_flavour \
+ && elf_tdata (bfd) != NULL \
+ && elf_object_id (bfd) == SH_ELF_DATA)
+
+/* Override the generic function because we need to store sh_elf_obj_tdata
+ as the specific tdata. */
+
+static bfd_boolean
+sh_elf_mkobject (bfd *abfd)
+{
+ return bfd_elf_allocate_object (abfd, sizeof (struct sh_elf_obj_tdata),
+ SH_ELF_DATA);
+}
+
+/* sh ELF linker hash table. */
+
+struct elf_sh_link_hash_table
+{
+ struct elf_link_hash_table root;
+
+ /* Short-cuts to get to dynamic linker sections. */
+ asection *sgot;
+ asection *sgotplt;
+ asection *srelgot;
+ asection *splt;
+ asection *srelplt;
+ asection *sdynbss;
+ asection *srelbss;
+ asection *sfuncdesc;
+ asection *srelfuncdesc;
+ asection *srofixup;
+
+ /* The (unloaded but important) VxWorks .rela.plt.unloaded section. */
+ asection *srelplt2;
+
+ /* Small local sym cache. */
+ struct sym_cache sym_cache;
+
+ /* A counter or offset to track a TLS got entry. */
+ union
+ {
+ bfd_signed_vma refcount;
+ bfd_vma offset;
+ } tls_ldm_got;
+
+ /* The type of PLT to use. */
+ const struct elf_sh_plt_info *plt_info;
+
+ /* True if the target system is VxWorks. */
+ bfd_boolean vxworks_p;
+
+ /* True if the target system uses FDPIC. */
+ bfd_boolean fdpic_p;
+};
+
+/* Traverse an sh ELF linker hash table. */
+
+#define sh_elf_link_hash_traverse(table, func, info) \
+ (elf_link_hash_traverse \
+ (&(table)->root, \
+ (bfd_boolean (*) (struct elf_link_hash_entry *, void *)) (func), \
+ (info)))
+
+/* Get the sh ELF linker hash table from a link_info structure. */
+
+#define sh_elf_hash_table(p) \
+ (elf_hash_table_id ((struct elf_link_hash_table *) ((p)->hash)) \
+ == SH_ELF_DATA ? ((struct elf_sh_link_hash_table *) ((p)->hash)) : NULL)
+
+/* Create an entry in an sh ELF linker hash table. */
+
+static struct bfd_hash_entry *
+sh_elf_link_hash_newfunc (struct bfd_hash_entry *entry,
+ struct bfd_hash_table *table,
+ const char *string)
+{
+ struct elf_sh_link_hash_entry *ret =
+ (struct elf_sh_link_hash_entry *) entry;
+
+ /* Allocate the structure if it has not already been allocated by a
+ subclass. */
+ if (ret == (struct elf_sh_link_hash_entry *) NULL)
+ ret = ((struct elf_sh_link_hash_entry *)
+ bfd_hash_allocate (table,
+ sizeof (struct elf_sh_link_hash_entry)));
+ if (ret == (struct elf_sh_link_hash_entry *) NULL)
+ return (struct bfd_hash_entry *) ret;
+
+ /* Call the allocation method of the superclass. */
+ ret = ((struct elf_sh_link_hash_entry *)
+ _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry *) ret,
+ table, string));
+ if (ret != (struct elf_sh_link_hash_entry *) NULL)
+ {
+ ret->dyn_relocs = NULL;
+ ret->gotplt_refcount = 0;
+#ifdef INCLUDE_SHMEDIA
+ ret->datalabel_got.refcount = ret->root.got.refcount;
+#endif
+ ret->funcdesc.refcount = 0;
+ ret->abs_funcdesc_refcount = 0;
+ ret->got_type = GOT_UNKNOWN;
+ }
+
+ return (struct bfd_hash_entry *) ret;
+}
+
+/* Create an sh ELF linker hash table. */
+
+static struct bfd_link_hash_table *
+sh_elf_link_hash_table_create (bfd *abfd)
+{
+ struct elf_sh_link_hash_table *ret;
+ bfd_size_type amt = sizeof (struct elf_sh_link_hash_table);
+
+ ret = (struct elf_sh_link_hash_table *) bfd_zmalloc (amt);
+ if (ret == (struct elf_sh_link_hash_table *) NULL)
+ return NULL;
+
+ if (!_bfd_elf_link_hash_table_init (&ret->root, abfd,
+ sh_elf_link_hash_newfunc,
+ sizeof (struct elf_sh_link_hash_entry),
+ SH_ELF_DATA))
+ {
+ free (ret);
+ return NULL;
+ }
+
+ ret->vxworks_p = vxworks_object_p (abfd);
+ ret->fdpic_p = fdpic_object_p (abfd);
+
+ return &ret->root.root;
+}
+
+static bfd_boolean
+sh_elf_omit_section_dynsym (bfd *output_bfd ATTRIBUTE_UNUSED,
+ struct bfd_link_info *info, asection *p)
+{
+ struct elf_sh_link_hash_table *htab = sh_elf_hash_table (info);
+
+ /* Non-FDPIC binaries do not need dynamic symbols for sections. */
+ if (!htab->fdpic_p)
+ return TRUE;
+
+ /* We need dynamic symbols for every section, since segments can
+ relocate independently. */
+ switch (elf_section_data (p)->this_hdr.sh_type)
+ {
+ case SHT_PROGBITS:
+ case SHT_NOBITS:
+ /* If sh_type is yet undecided, assume it could be
+ SHT_PROGBITS/SHT_NOBITS. */
+ case SHT_NULL:
+ return FALSE;
+
+ /* There shouldn't be section relative relocations
+ against any other section. */
+ default:
+ return TRUE;
+ }
+}
+
+/* Create .got, .gotplt, and .rela.got sections in DYNOBJ, and set up
+ shortcuts to them in our hash table. */
+
+static bfd_boolean
+create_got_section (bfd *dynobj, struct bfd_link_info *info)
+{
+ struct elf_sh_link_hash_table *htab;
+
+ if (! _bfd_elf_create_got_section (dynobj, info))
+ return FALSE;
+
+ htab = sh_elf_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ htab->sgot = bfd_get_linker_section (dynobj, ".got");
+ htab->sgotplt = bfd_get_linker_section (dynobj, ".got.plt");
+ htab->srelgot = bfd_get_linker_section (dynobj, ".rela.got");
+ if (! htab->sgot || ! htab->sgotplt || ! htab->srelgot)
+ abort ();
+
+ htab->sfuncdesc = bfd_make_section_anyway_with_flags (dynobj, ".got.funcdesc",
+ (SEC_ALLOC | SEC_LOAD
+ | SEC_HAS_CONTENTS
+ | SEC_IN_MEMORY
+ | SEC_LINKER_CREATED));
+ if (htab->sfuncdesc == NULL
+ || ! bfd_set_section_alignment (dynobj, htab->sfuncdesc, 2))
+ return FALSE;
+
+ htab->srelfuncdesc = bfd_make_section_anyway_with_flags (dynobj,
+ ".rela.got.funcdesc",
+ (SEC_ALLOC | SEC_LOAD
+ | SEC_HAS_CONTENTS
+ | SEC_IN_MEMORY
+ | SEC_LINKER_CREATED
+ | SEC_READONLY));
+ if (htab->srelfuncdesc == NULL
+ || ! bfd_set_section_alignment (dynobj, htab->srelfuncdesc, 2))
+ return FALSE;
+
+ /* Also create .rofixup. */
+ htab->srofixup = bfd_make_section_anyway_with_flags (dynobj, ".rofixup",
+ (SEC_ALLOC | SEC_LOAD
+ | SEC_HAS_CONTENTS
+ | SEC_IN_MEMORY
+ | SEC_LINKER_CREATED
+ | SEC_READONLY));
+ if (htab->srofixup == NULL
+ || ! bfd_set_section_alignment (dynobj, htab->srofixup, 2))
+ return FALSE;
+
+ return TRUE;
+}
+
+/* Create dynamic sections when linking against a dynamic object. */
+
+static bfd_boolean
+sh_elf_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
+{
+ struct elf_sh_link_hash_table *htab;
+ flagword flags, pltflags;
+ asection *s;
+ const struct elf_backend_data *bed = get_elf_backend_data (abfd);
+ int ptralign = 0;
+
+ switch (bed->s->arch_size)
+ {
+ case 32:
+ ptralign = 2;
+ break;
+
+ case 64:
+ ptralign = 3;
+ break;
+
+ default:
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+
+ htab = sh_elf_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ if (htab->root.dynamic_sections_created)
+ return TRUE;
+
+ /* 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_anyway_with_flags (abfd, ".plt", pltflags);
+ htab->splt = s;
+ if (s == NULL
+ || ! 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;
+ struct bfd_link_hash_entry *bh = 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, &bh)))
+ return FALSE;
+
+ h = (struct elf_link_hash_entry *) bh;
+ h->def_regular = 1;
+ h->type = STT_OBJECT;
+ htab->root.hplt = h;
+
+ if (info->shared
+ && ! bfd_elf_link_record_dynamic_symbol (info, h))
+ return FALSE;
+ }
+
+ s = bfd_make_section_anyway_with_flags (abfd,
+ bed->default_use_rela_p
+ ? ".rela.plt" : ".rel.plt",
+ flags | SEC_READONLY);
+ htab->srelplt = s;
+ if (s == NULL
+ || ! bfd_set_section_alignment (abfd, s, ptralign))
+ return FALSE;
+
+ if (htab->sgot == NULL
+ && !create_got_section (abfd, info))
+ return FALSE;
+
+ if (bed->want_dynbss)
+ {
+ /* 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_anyway_with_flags (abfd, ".dynbss",
+ SEC_ALLOC | SEC_LINKER_CREATED);
+ htab->sdynbss = s;
+ if (s == NULL)
+ 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_anyway_with_flags (abfd,
+ (bed->default_use_rela_p
+ ? ".rela.bss" : ".rel.bss"),
+ flags | SEC_READONLY);
+ htab->srelbss = s;
+ if (s == NULL
+ || ! bfd_set_section_alignment (abfd, s, ptralign))
+ return FALSE;
+ }
+ }
+
+ if (htab->vxworks_p)
+ {
+ if (!elf_vxworks_create_dynamic_sections (abfd, info, &htab->srelplt2))
+ 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 bfd_boolean
+sh_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
+ struct elf_link_hash_entry *h)
+{
+ struct elf_sh_link_hash_table *htab;
+ struct elf_sh_link_hash_entry *eh;
+ struct elf_sh_dyn_relocs *p;
+ asection *s;
+
+ htab = sh_elf_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ /* Make sure we know what is going on here. */
+ BFD_ASSERT (htab->root.dynobj != NULL
+ && (h->needs_plt
+ || h->u.weakdef != NULL
+ || (h->def_dynamic
+ && h->ref_regular
+ && !h->def_regular)));
+
+ /* 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->needs_plt)
+ {
+ if (h->plt.refcount <= 0
+ || SYMBOL_CALLS_LOCAL (info, h)
+ || (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
+ && h->root.type == bfd_link_hash_undefweak))
+ {
+ /* This case can occur if we saw a PLT 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 REL32
+ reloc instead. */
+ h->plt.offset = (bfd_vma) -1;
+ h->needs_plt = 0;
+ }
+
+ return TRUE;
+ }
+ else
+ 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->u.weakdef != NULL)
+ {
+ BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
+ || h->u.weakdef->root.type == bfd_link_hash_defweak);
+ h->root.u.def.section = h->u.weakdef->root.u.def.section;
+ h->root.u.def.value = h->u.weakdef->root.u.def.value;
+ if (info->nocopyreloc)
+ h->non_got_ref = h->u.weakdef->non_got_ref;
+ 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;
+
+ /* If there are no references to this symbol that do not use the
+ GOT, we don't need to generate a copy reloc. */
+ if (!h->non_got_ref)
+ return TRUE;
+
+ /* If -z nocopyreloc was given, we won't generate them either. */
+ if (info->nocopyreloc)
+ {
+ h->non_got_ref = 0;
+ return TRUE;
+ }
+
+ eh = (struct elf_sh_link_hash_entry *) h;
+ for (p = eh->dyn_relocs; p != NULL; p = p->next)
+ {
+ s = p->sec->output_section;
+ if (s != NULL && (s->flags & (SEC_READONLY | SEC_HAS_CONTENTS)) != 0)
+ break;
+ }
+
+ /* If we didn't find any dynamic relocs in sections which needs the
+ copy reloc, then we'll be keeping the dynamic relocs and avoiding
+ the copy reloc. */
+ if (p == NULL)
+ {
+ h->non_got_ref = 0;
+ 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 = htab->sdynbss;
+ BFD_ASSERT (s != NULL);
+
+ /* We must generate a R_SH_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 && h->size != 0)
+ {
+ asection *srel;
+
+ srel = htab->srelbss;
+ BFD_ASSERT (srel != NULL);
+ srel->size += sizeof (Elf32_External_Rela);
+ h->needs_copy = 1;
+ }
+
+ return _bfd_elf_adjust_dynamic_copy (h, s);
+}
+
+/* Allocate space in .plt, .got and associated reloc sections for
+ dynamic relocs. */
+
+static bfd_boolean
+allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
+{
+ struct bfd_link_info *info;
+ struct elf_sh_link_hash_table *htab;
+ struct elf_sh_link_hash_entry *eh;
+ struct elf_sh_dyn_relocs *p;
+
+ if (h->root.type == bfd_link_hash_indirect)
+ return TRUE;
+
+ info = (struct bfd_link_info *) inf;
+ htab = sh_elf_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ eh = (struct elf_sh_link_hash_entry *) h;
+ if ((h->got.refcount > 0
+ || h->forced_local)
+ && eh->gotplt_refcount > 0)
+ {
+ /* The symbol has been forced local, or we have some direct got refs,
+ so treat all the gotplt refs as got refs. */
+ h->got.refcount += eh->gotplt_refcount;
+ if (h->plt.refcount >= eh->gotplt_refcount)
+ h->plt.refcount -= eh->gotplt_refcount;
+ }
+
+ if (htab->root.dynamic_sections_created
+ && h->plt.refcount > 0
+ && (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
+ || h->root.type != bfd_link_hash_undefweak))
+ {
+ /* Make sure this symbol is output as a dynamic symbol.
+ Undefined weak syms won't yet be marked as dynamic. */
+ if (h->dynindx == -1
+ && !h->forced_local)
+ {
+ if (! bfd_elf_link_record_dynamic_symbol (info, h))
+ return FALSE;
+ }
+
+ if (info->shared
+ || WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, 0, h))
+ {
+ asection *s = htab->splt;
+ const struct elf_sh_plt_info *plt_info;
+
+ /* If this is the first .plt entry, make room for the special
+ first entry. */
+ if (s->size == 0)
+ s->size += htab->plt_info->plt0_entry_size;
+
+ h->plt.offset = s->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. Skip this for FDPIC, since the
+ function's address will be the address of the canonical
+ function descriptor. */
+ if (!htab->fdpic_p && !info->shared && !h->def_regular)
+ {
+ h->root.u.def.section = s;
+ h->root.u.def.value = h->plt.offset;
+ }
+
+ /* Make room for this entry. */
+ plt_info = htab->plt_info;
+ if (plt_info->short_plt != NULL
+ && (get_plt_index (plt_info->short_plt, s->size) < MAX_SHORT_PLT))
+ plt_info = plt_info->short_plt;
+ s->size += plt_info->symbol_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. */
+ if (!htab->fdpic_p)
+ htab->sgotplt->size += 4;
+ else
+ htab->sgotplt->size += 8;
+
+ /* We also need to make an entry in the .rel.plt section. */
+ htab->srelplt->size += sizeof (Elf32_External_Rela);
+
+ if (htab->vxworks_p && !info->shared)
+ {
+ /* VxWorks executables have a second set of relocations
+ for each PLT entry. They go in a separate relocation
+ section, which is processed by the kernel loader. */
+
+ /* There is a relocation for the initial PLT entry:
+ an R_SH_DIR32 relocation for _GLOBAL_OFFSET_TABLE_. */
+ if (h->plt.offset == htab->plt_info->plt0_entry_size)
+ htab->srelplt2->size += sizeof (Elf32_External_Rela);
+
+ /* There are two extra relocations for each subsequent
+ PLT entry: an R_SH_DIR32 relocation for the GOT entry,
+ and an R_SH_DIR32 relocation for the PLT entry. */
+ htab->srelplt2->size += sizeof (Elf32_External_Rela) * 2;
+ }
+ }
+ else
+ {
+ h->plt.offset = (bfd_vma) -1;
+ h->needs_plt = 0;
+ }
+ }
+ else
+ {
+ h->plt.offset = (bfd_vma) -1;
+ h->needs_plt = 0;
+ }
+
+ if (h->got.refcount > 0)
+ {
+ asection *s;
+ bfd_boolean dyn;
+ enum got_type got_type = sh_elf_hash_entry (h)->got_type;
+
+ /* Make sure this symbol is output as a dynamic symbol.
+ Undefined weak syms won't yet be marked as dynamic. */
+ if (h->dynindx == -1
+ && !h->forced_local)
+ {
+ if (! bfd_elf_link_record_dynamic_symbol (info, h))
+ return FALSE;
+ }
+
+ s = htab->sgot;
+ h->got.offset = s->size;
+ s->size += 4;
+ /* R_SH_TLS_GD needs 2 consecutive GOT slots. */
+ if (got_type == GOT_TLS_GD)
+ s->size += 4;
+ dyn = htab->root.dynamic_sections_created;
+ if (!dyn)
+ {
+ /* No dynamic relocations required. */
+ if (htab->fdpic_p && !info->shared
+ && h->root.type != bfd_link_hash_undefweak
+ && (got_type == GOT_NORMAL || got_type == GOT_FUNCDESC))
+ htab->srofixup->size += 4;
+ }
+ /* No dynamic relocations required when IE->LE conversion happens. */
+ else if (got_type == GOT_TLS_IE && !h->def_dynamic && !info->shared)
+ ;
+ /* R_SH_TLS_IE_32 needs one dynamic relocation if dynamic,
+ R_SH_TLS_GD needs one if local symbol and two if global. */
+ else if ((got_type == GOT_TLS_GD && h->dynindx == -1)
+ || got_type == GOT_TLS_IE)
+ htab->srelgot->size += sizeof (Elf32_External_Rela);
+ else if (got_type == GOT_TLS_GD)
+ htab->srelgot->size += 2 * sizeof (Elf32_External_Rela);
+ else if (got_type == GOT_FUNCDESC)
+ {
+ if (!info->shared && SYMBOL_FUNCDESC_LOCAL (info, h))
+ htab->srofixup->size += 4;
+ else
+ htab->srelgot->size += sizeof (Elf32_External_Rela);
+ }
+ else if ((ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
+ || h->root.type != bfd_link_hash_undefweak)
+ && (info->shared
+ || WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, 0, h)))
+ htab->srelgot->size += sizeof (Elf32_External_Rela);
+ else if (htab->fdpic_p && !info->shared && got_type == GOT_NORMAL
+ && (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
+ || h->root.type != bfd_link_hash_undefweak))
+ htab->srofixup->size += 4;
+ }
+ else
+ h->got.offset = (bfd_vma) -1;
+
+#ifdef INCLUDE_SHMEDIA
+ if (eh->datalabel_got.refcount > 0)
+ {
+ asection *s;
+ bfd_boolean dyn;
+
+ /* Make sure this symbol is output as a dynamic symbol.
+ Undefined weak syms won't yet be marked as dynamic. */
+ if (h->dynindx == -1
+ && !h->forced_local)
+ {
+ if (! bfd_elf_link_record_dynamic_symbol (info, h))
+ return FALSE;
+ }
+
+ s = htab->sgot;
+ eh->datalabel_got.offset = s->size;
+ s->size += 4;
+ dyn = htab->root.dynamic_sections_created;
+ if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h))
+ htab->srelgot->size += sizeof (Elf32_External_Rela);
+ }
+ else
+ eh->datalabel_got.offset = (bfd_vma) -1;
+#endif
+
+ /* Allocate space for any dynamic relocations to function
+ descriptors, canonical or otherwise. We need to relocate the
+ reference unless it resolves to zero, which only happens for
+ undefined weak symbols (either non-default visibility, or when
+ static linking). Any GOT slot is accounted for elsewhere. */
+ if (eh->abs_funcdesc_refcount > 0
+ && (h->root.type != bfd_link_hash_undefweak
+ || (htab->root.dynamic_sections_created
+ && ! SYMBOL_CALLS_LOCAL (info, h))))
+ {
+ if (!info->shared && SYMBOL_FUNCDESC_LOCAL (info, h))
+ htab->srofixup->size += eh->abs_funcdesc_refcount * 4;
+ else
+ htab->srelgot->size
+ += eh->abs_funcdesc_refcount * sizeof (Elf32_External_Rela);
+ }
+
+ /* We must allocate a function descriptor if there are references to
+ a canonical descriptor (R_SH_GOTFUNCDESC or R_SH_FUNCDESC) and
+ the dynamic linker isn't going to allocate it. None of this
+ applies if we already created one in .got.plt, but if the
+ canonical function descriptor can be in this object, there
+ won't be a PLT entry at all. */
+ if ((eh->funcdesc.refcount > 0
+ || (h->got.offset != MINUS_ONE && eh->got_type == GOT_FUNCDESC))
+ && h->root.type != bfd_link_hash_undefweak
+ && SYMBOL_FUNCDESC_LOCAL (info, h))
+ {
+ /* Make room for this function descriptor. */
+ eh->funcdesc.offset = htab->sfuncdesc->size;
+ htab->sfuncdesc->size += 8;
+
+ /* We will need a relocation or two fixups to initialize the
+ function descriptor, so allocate those too. */
+ if (!info->shared && SYMBOL_CALLS_LOCAL (info, h))
+ htab->srofixup->size += 8;
+ else
+ htab->srelfuncdesc->size += sizeof (Elf32_External_Rela);
+ }
+
+ if (eh->dyn_relocs == NULL)
+ return TRUE;
+
+ /* In the shared -Bsymbolic case, discard space allocated for
+ dynamic pc-relative relocs against symbols which turn out to be
+ defined in regular objects. For the normal shared case, discard
+ space for pc-relative relocs that have become local due to symbol
+ visibility changes. */
+
+ if (info->shared)
+ {
+ if (SYMBOL_CALLS_LOCAL (info, h))
+ {
+ struct elf_sh_dyn_relocs **pp;
+
+ for (pp = &eh->dyn_relocs; (p = *pp) != NULL; )
+ {
+ p->count -= p->pc_count;
+ p->pc_count = 0;
+ if (p->count == 0)
+ *pp = p->next;
+ else
+ pp = &p->next;
+ }
+ }
+
+ if (htab->vxworks_p)
+ {
+ struct elf_sh_dyn_relocs **pp;
+
+ for (pp = &eh->dyn_relocs; (p = *pp) != NULL; )
+ {
+ if (strcmp (p->sec->output_section->name, ".tls_vars") == 0)
+ *pp = p->next;
+ else
+ pp = &p->next;
+ }
+ }
+
+ /* Also discard relocs on undefined weak syms with non-default
+ visibility. */
+ if (eh->dyn_relocs != NULL
+ && h->root.type == bfd_link_hash_undefweak)
+ {
+ if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
+ eh->dyn_relocs = NULL;
+
+ /* Make sure undefined weak symbols are output as a dynamic
+ symbol in PIEs. */
+ else if (h->dynindx == -1
+ && !h->forced_local)
+ {
+ if (! bfd_elf_link_record_dynamic_symbol (info, h))
+ return FALSE;
+ }
+ }
+ }
+ else
+ {
+ /* For the non-shared case, discard space for relocs against
+ symbols which turn out to need copy relocs or are not
+ dynamic. */
+
+ if (!h->non_got_ref
+ && ((h->def_dynamic
+ && !h->def_regular)
+ || (htab->root.dynamic_sections_created
+ && (h->root.type == bfd_link_hash_undefweak
+ || h->root.type == bfd_link_hash_undefined))))
+ {
+ /* Make sure this symbol is output as a dynamic symbol.
+ Undefined weak syms won't yet be marked as dynamic. */
+ if (h->dynindx == -1
+ && !h->forced_local)
+ {
+ if (! bfd_elf_link_record_dynamic_symbol (info, h))
+ return FALSE;
+ }
+
+ /* If that succeeded, we know we'll be keeping all the
+ relocs. */
+ if (h->dynindx != -1)
+ goto keep;
+ }
+
+ eh->dyn_relocs = NULL;
+
+ keep: ;
+ }
+
+ /* Finally, allocate space. */
+ for (p = eh->dyn_relocs; p != NULL; p = p->next)
+ {
+ asection *sreloc = elf_section_data (p->sec)->sreloc;
+ sreloc->size += p->count * sizeof (Elf32_External_Rela);
+
+ /* If we need relocations, we do not need fixups. */
+ if (htab->fdpic_p && !info->shared)
+ htab->srofixup->size -= 4 * (p->count - p->pc_count);
+ }
+
+ return TRUE;
+}
+
+/* Find any dynamic relocs that apply to read-only sections. */
+
+static bfd_boolean
+readonly_dynrelocs (struct elf_link_hash_entry *h, void *inf)
+{
+ struct elf_sh_link_hash_entry *eh;
+ struct elf_sh_dyn_relocs *p;
+
+ eh = (struct elf_sh_link_hash_entry *) h;
+ for (p = eh->dyn_relocs; p != NULL; p = p->next)
+ {
+ asection *s = p->sec->output_section;
+
+ if (s != NULL && (s->flags & SEC_READONLY) != 0)
+ {
+ struct bfd_link_info *info = (struct bfd_link_info *) inf;
+
+ info->flags |= DF_TEXTREL;
+
+ /* Not an error, just cut short the traversal. */
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+/* This function is called after all the input files have been read,
+ and the input sections have been assigned to output sections.
+ It's a convenient place to determine the PLT style. */
+
+static bfd_boolean
+sh_elf_always_size_sections (bfd *output_bfd, struct bfd_link_info *info)
+{
+ sh_elf_hash_table (info)->plt_info = get_plt_info (output_bfd, info->shared);
+
+ if (sh_elf_hash_table (info)->fdpic_p && !info->relocatable
+ && !bfd_elf_stack_segment_size (output_bfd, info,
+ "__stacksize", DEFAULT_STACK_SIZE))
+ return FALSE;
+ return TRUE;
+}
+
+/* Set the sizes of the dynamic sections. */
+
+static bfd_boolean
+sh_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
+ struct bfd_link_info *info)
+{
+ struct elf_sh_link_hash_table *htab;
+ bfd *dynobj;
+ asection *s;
+ bfd_boolean relocs;
+ bfd *ibfd;
+
+ htab = sh_elf_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ dynobj = htab->root.dynobj;
+ BFD_ASSERT (dynobj != NULL);
+
+ if (htab->root.dynamic_sections_created)
+ {
+ /* Set the contents of the .interp section to the interpreter. */
+ if (info->executable)
+ {
+ s = bfd_get_linker_section (dynobj, ".interp");
+ BFD_ASSERT (s != NULL);
+ s->size = sizeof ELF_DYNAMIC_INTERPRETER;
+ s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
+ }
+ }
+
+ /* Set up .got offsets for local syms, and space for local dynamic
+ relocs. */
+ for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next)
+ {
+ bfd_signed_vma *local_got;
+ bfd_signed_vma *end_local_got;
+ union gotref *local_funcdesc, *end_local_funcdesc;
+ char *local_got_type;
+ bfd_size_type locsymcount;
+ Elf_Internal_Shdr *symtab_hdr;
+ asection *srel;
+
+ if (! is_sh_elf (ibfd))
+ continue;
+
+ for (s = ibfd->sections; s != NULL; s = s->next)
+ {
+ struct elf_sh_dyn_relocs *p;
+
+ for (p = ((struct elf_sh_dyn_relocs *)
+ elf_section_data (s)->local_dynrel);
+ p != NULL;
+ p = p->next)
+ {
+ if (! bfd_is_abs_section (p->sec)
+ && bfd_is_abs_section (p->sec->output_section))
+ {
+ /* Input section has been discarded, either because
+ it is a copy of a linkonce section or due to
+ linker script /DISCARD/, so we'll be discarding
+ the relocs too. */
+ }
+ else if (htab->vxworks_p
+ && strcmp (p->sec->output_section->name,
+ ".tls_vars") == 0)
+ {
+ /* Relocations in vxworks .tls_vars sections are
+ handled specially by the loader. */
+ }
+ else if (p->count != 0)
+ {
+ srel = elf_section_data (p->sec)->sreloc;
+ srel->size += p->count * sizeof (Elf32_External_Rela);
+ if ((p->sec->output_section->flags & SEC_READONLY) != 0)
+ info->flags |= DF_TEXTREL;
+
+ /* If we need relocations, we do not need fixups. */
+ if (htab->fdpic_p && !info->shared)
+ htab->srofixup->size -= 4 * (p->count - p->pc_count);
+ }
+ }
+ }
+
+ symtab_hdr = &elf_symtab_hdr (ibfd);
+ locsymcount = symtab_hdr->sh_info;
+#ifdef INCLUDE_SHMEDIA
+ /* Count datalabel local GOT. */
+ locsymcount *= 2;
+#endif
+ s = htab->sgot;
+ srel = htab->srelgot;
+
+ local_got = elf_local_got_refcounts (ibfd);
+ if (local_got)
+ {
+ end_local_got = local_got + locsymcount;
+ local_got_type = sh_elf_local_got_type (ibfd);
+ local_funcdesc = sh_elf_local_funcdesc (ibfd);
+ for (; local_got < end_local_got; ++local_got)
+ {
+ if (*local_got > 0)
+ {
+ *local_got = s->size;
+ s->size += 4;
+ if (*local_got_type == GOT_TLS_GD)
+ s->size += 4;
+ if (info->shared)
+ srel->size += sizeof (Elf32_External_Rela);
+ else
+ htab->srofixup->size += 4;
+
+ if (*local_got_type == GOT_FUNCDESC)
+ {
+ if (local_funcdesc == NULL)
+ {
+ bfd_size_type size;
+
+ size = locsymcount * sizeof (union gotref);
+ local_funcdesc = (union gotref *) bfd_zalloc (ibfd,
+ size);
+ if (local_funcdesc == NULL)
+ return FALSE;
+ sh_elf_local_funcdesc (ibfd) = local_funcdesc;
+ local_funcdesc += (local_got
+ - elf_local_got_refcounts (ibfd));
+ }
+ local_funcdesc->refcount++;
+ ++local_funcdesc;
+ }
+ }
+ else
+ *local_got = (bfd_vma) -1;
+ ++local_got_type;
+ }
+ }
+
+ local_funcdesc = sh_elf_local_funcdesc (ibfd);
+ if (local_funcdesc)
+ {
+ end_local_funcdesc = local_funcdesc + locsymcount;
+
+ for (; local_funcdesc < end_local_funcdesc; ++local_funcdesc)
+ {
+ if (local_funcdesc->refcount > 0)
+ {
+ local_funcdesc->offset = htab->sfuncdesc->size;
+ htab->sfuncdesc->size += 8;
+ if (!info->shared)
+ htab->srofixup->size += 8;
+ else
+ htab->srelfuncdesc->size += sizeof (Elf32_External_Rela);
+ }
+ else
+ local_funcdesc->offset = MINUS_ONE;
+ }
+ }
+
+ }
+
+ if (htab->tls_ldm_got.refcount > 0)
+ {
+ /* Allocate 2 got entries and 1 dynamic reloc for R_SH_TLS_LD_32
+ relocs. */
+ htab->tls_ldm_got.offset = htab->sgot->size;
+ htab->sgot->size += 8;
+ htab->srelgot->size += sizeof (Elf32_External_Rela);
+ }
+ else
+ htab->tls_ldm_got.offset = -1;
+
+ /* Only the reserved entries should be present. For FDPIC, they go at
+ the end of .got.plt. */
+ if (htab->fdpic_p)
+ {
+ BFD_ASSERT (htab->sgotplt && htab->sgotplt->size == 12);
+ htab->sgotplt->size = 0;
+ }
+
+ /* Allocate global sym .plt and .got entries, and space for global
+ sym dynamic relocs. */
+ elf_link_hash_traverse (&htab->root, allocate_dynrelocs, info);
+
+ /* Move the reserved entries and the _GLOBAL_OFFSET_TABLE_ symbol to the
+ end of the FDPIC .got.plt. */
+ if (htab->fdpic_p)
+ {
+ htab->root.hgot->root.u.def.value = htab->sgotplt->size;
+ htab->sgotplt->size += 12;
+ }
+
+ /* At the very end of the .rofixup section is a pointer to the GOT. */
+ if (htab->fdpic_p && htab->srofixup != NULL)
+ htab->srofixup->size += 4;
+
+ /* We now have determined the sizes of the various dynamic sections.
+ Allocate memory for them. */
+ relocs = FALSE;
+ for (s = dynobj->sections; s != NULL; s = s->next)
+ {
+ if ((s->flags & SEC_LINKER_CREATED) == 0)
+ continue;
+
+ if (s == htab->splt
+ || s == htab->sgot
+ || s == htab->sgotplt
+ || s == htab->sfuncdesc
+ || s == htab->srofixup
+ || s == htab->sdynbss)
+ {
+ /* Strip this section if we don't need it; see the
+ comment below. */
+ }
+ else if (CONST_STRNEQ (bfd_get_section_name (dynobj, s), ".rela"))
+ {
+ if (s->size != 0 && s != htab->srelplt && s != htab->srelplt2)
+ relocs = 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
+ {
+ /* It's not one of our sections, so don't allocate space. */
+ continue;
+ }
+
+ if (s->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. */
+
+ s->flags |= SEC_EXCLUDE;
+ continue;
+ }
+
+ if ((s->flags & SEC_HAS_CONTENTS) == 0)
+ continue;
+
+ /* Allocate memory for the section contents. We use bfd_zalloc
+ here in case unused entries are not reclaimed before the
+ section's contents are written out. This should not happen,
+ but this way if it does, we get a R_SH_NONE reloc instead
+ of garbage. */
+ s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->size);
+ if (s->contents == NULL)
+ return FALSE;
+ }
+
+ if (htab->root.dynamic_sections_created)
+ {
+ /* Add some entries to the .dynamic section. We fill in the
+ values later, in sh_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. */
+#define add_dynamic_entry(TAG, VAL) \
+ _bfd_elf_add_dynamic_entry (info, TAG, VAL)
+
+ if (info->executable)
+ {
+ if (! add_dynamic_entry (DT_DEBUG, 0))
+ return FALSE;
+ }
+
+ if (htab->splt->size != 0)
+ {
+ if (! add_dynamic_entry (DT_PLTGOT, 0)
+ || ! add_dynamic_entry (DT_PLTRELSZ, 0)
+ || ! add_dynamic_entry (DT_PLTREL, DT_RELA)
+ || ! add_dynamic_entry (DT_JMPREL, 0))
+ return FALSE;
+ }
+ else if ((elf_elfheader (output_bfd)->e_flags & EF_SH_FDPIC)
+ && htab->sgot->size != 0)
+ {
+ if (! add_dynamic_entry (DT_PLTGOT, 0))
+ return FALSE;
+ }
+
+ if (relocs)
+ {
+ if (! add_dynamic_entry (DT_RELA, 0)
+ || ! add_dynamic_entry (DT_RELASZ, 0)
+ || ! add_dynamic_entry (DT_RELAENT,
+ sizeof (Elf32_External_Rela)))
+ return FALSE;
+
+ /* If any dynamic relocs apply to a read-only section,
+ then we need a DT_TEXTREL entry. */
+ if ((info->flags & DF_TEXTREL) == 0)
+ elf_link_hash_traverse (&htab->root, readonly_dynrelocs, info);
+
+ if ((info->flags & DF_TEXTREL) != 0)
+ {
+ if (! add_dynamic_entry (DT_TEXTREL, 0))
+ return FALSE;
+ }
+ }
+ if (htab->vxworks_p
+ && !elf_vxworks_add_dynamic_entries (output_bfd, info))
+ return FALSE;
+ }
+#undef add_dynamic_entry
+
+ return TRUE;
+}
+
+/* Add a dynamic relocation to the SRELOC section. */
+
+inline static bfd_vma
+sh_elf_add_dyn_reloc (bfd *output_bfd, asection *sreloc, bfd_vma offset,
+ int reloc_type, long dynindx, bfd_vma addend)
+{
+ Elf_Internal_Rela outrel;
+ bfd_vma reloc_offset;
+
+ outrel.r_offset = offset;
+ outrel.r_info = ELF32_R_INFO (dynindx, reloc_type);
+ outrel.r_addend = addend;
+
+ reloc_offset = sreloc->reloc_count * sizeof (Elf32_External_Rela);
+ BFD_ASSERT (reloc_offset < sreloc->size);
+ bfd_elf32_swap_reloca_out (output_bfd, &outrel,
+ sreloc->contents + reloc_offset);
+ sreloc->reloc_count++;
+
+ return reloc_offset;
+}
+
+/* Add an FDPIC read-only fixup. */
+
+inline static void
+sh_elf_add_rofixup (bfd *output_bfd, asection *srofixup, bfd_vma offset)
+{
+ bfd_vma fixup_offset;
+
+ fixup_offset = srofixup->reloc_count++ * 4;
+ BFD_ASSERT (fixup_offset < srofixup->size);
+ bfd_put_32 (output_bfd, offset, srofixup->contents + fixup_offset);
+}
+
+/* Return the offset of the generated .got section from the
+ _GLOBAL_OFFSET_TABLE_ symbol. */
+
+static bfd_signed_vma
+sh_elf_got_offset (struct elf_sh_link_hash_table *htab)
+{
+ return (htab->sgot->output_offset - htab->sgotplt->output_offset
+ - htab->root.hgot->root.u.def.value);
+}
+
+/* Find the segment number in which OSEC, and output section, is
+ located. */
+
+static unsigned
+sh_elf_osec_to_segment (bfd *output_bfd, asection *osec)
+{
+ Elf_Internal_Phdr *p = NULL;
+
+ if (output_bfd->xvec->flavour == bfd_target_elf_flavour
+ /* PR ld/17110: Do not look for output segments in an input bfd. */
+ && output_bfd->direction != read_direction)
+ p = _bfd_elf_find_segment_containing_section (output_bfd, osec);
+
+ /* FIXME: Nothing ever says what this index is relative to. The kernel
+ supplies data in terms of the number of load segments but this is
+ a phdr index and the first phdr may not be a load segment. */
+ return (p != NULL) ? p - elf_tdata (output_bfd)->phdr : -1;
+}
+
+static bfd_boolean
+sh_elf_osec_readonly_p (bfd *output_bfd, asection *osec)
+{
+ unsigned seg = sh_elf_osec_to_segment (output_bfd, osec);
+
+ return (seg != (unsigned) -1
+ && ! (elf_tdata (output_bfd)->phdr[seg].p_flags & PF_W));
+}
+
+/* Generate the initial contents of a local function descriptor, along
+ with any relocations or fixups required. */
+static bfd_boolean
+sh_elf_initialize_funcdesc (bfd *output_bfd,
+ struct bfd_link_info *info,
+ struct elf_link_hash_entry *h,
+ bfd_vma offset,
+ asection *section,
+ bfd_vma value)
+{
+ struct elf_sh_link_hash_table *htab;
+ int dynindx;
+ bfd_vma addr, seg;
+
+ htab = sh_elf_hash_table (info);
+
+ /* FIXME: The ABI says that the offset to the function goes in the
+ descriptor, along with the segment index. We're RELA, so it could
+ go in the reloc instead... */
+
+ if (h != NULL && SYMBOL_CALLS_LOCAL (info, h))
+ {
+ section = h->root.u.def.section;
+ value = h->root.u.def.value;
+ }
+
+ if (h == NULL || SYMBOL_CALLS_LOCAL (info, h))
+ {
+ dynindx = elf_section_data (section->output_section)->dynindx;
+ addr = value + section->output_offset;
+ seg = sh_elf_osec_to_segment (output_bfd, section->output_section);
+ }
+ else
+ {
+ BFD_ASSERT (h->dynindx != -1);
+ dynindx = h->dynindx;
+ addr = seg = 0;
+ }
+
+ if (!info->shared && SYMBOL_CALLS_LOCAL (info, h))
+ {
+ if (h == NULL || h->root.type != bfd_link_hash_undefweak)
+ {
+ sh_elf_add_rofixup (output_bfd, htab->srofixup,
+ offset
+ + htab->sfuncdesc->output_section->vma
+ + htab->sfuncdesc->output_offset);
+ sh_elf_add_rofixup (output_bfd, htab->srofixup,
+ offset + 4
+ + htab->sfuncdesc->output_section->vma
+ + htab->sfuncdesc->output_offset);
+ }
+
+ /* There are no dynamic relocations so fill in the final
+ address and gp value (barring fixups). */
+ addr += section->output_section->vma;
+ seg = htab->root.hgot->root.u.def.value
+ + htab->root.hgot->root.u.def.section->output_section->vma
+ + htab->root.hgot->root.u.def.section->output_offset;
+ }
+ else
+ sh_elf_add_dyn_reloc (output_bfd, htab->srelfuncdesc,
+ offset
+ + htab->sfuncdesc->output_section->vma
+ + htab->sfuncdesc->output_offset,
+ R_SH_FUNCDESC_VALUE, dynindx, 0);
+
+ bfd_put_32 (output_bfd, addr, htab->sfuncdesc->contents + offset);
+ bfd_put_32 (output_bfd, seg, htab->sfuncdesc->contents + offset + 4);
+
+ return TRUE;
+}
+
+/* Install a 20-bit movi20 field starting at ADDR, which occurs in OUTPUT_BFD.
+ VALUE is the field's value. Return bfd_reloc_ok if successful or an error
+ otherwise. */
+
+static bfd_reloc_status_type
+install_movi20_field (bfd *output_bfd, unsigned long relocation,
+ bfd *input_bfd, asection *input_section,
+ bfd_byte *contents, bfd_vma offset)
+{
+ unsigned long cur_val;
+ bfd_byte *addr;
+ bfd_reloc_status_type r;
+
+ if (offset > bfd_get_section_limit (input_bfd, input_section))
+ return bfd_reloc_outofrange;
+
+ r = bfd_check_overflow (complain_overflow_signed, 20, 0,
+ bfd_arch_bits_per_address (input_bfd), relocation);
+ if (r != bfd_reloc_ok)
+ return r;
+
+ addr = contents + offset;
+ cur_val = bfd_get_16 (output_bfd, addr);
+ bfd_put_16 (output_bfd, cur_val | ((relocation & 0xf0000) >> 12), addr);
+ bfd_put_16 (output_bfd, relocation & 0xffff, addr + 2);
+
+ return bfd_reloc_ok;
+}
+
+/* Relocate an SH ELF section. */
+
+static bfd_boolean
+sh_elf_relocate_section (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)
+{
+ struct elf_sh_link_hash_table *htab;
+ Elf_Internal_Shdr *symtab_hdr;
+ struct elf_link_hash_entry **sym_hashes;
+ Elf_Internal_Rela *rel, *relend;
+ bfd *dynobj = NULL;
+ bfd_vma *local_got_offsets;
+ asection *sgot = NULL;
+ asection *sgotplt = NULL;
+ asection *splt = NULL;
+ asection *sreloc = NULL;
+ asection *srelgot = NULL;
+ bfd_boolean is_vxworks_tls;
+ unsigned isec_segment, got_segment, plt_segment, check_segment[2];
+ bfd_boolean fdpic_p = FALSE;
+
+ BFD_ASSERT (is_sh_elf (input_bfd));
+
+ htab = sh_elf_hash_table (info);
+ if (htab != NULL)
+ {
+ dynobj = htab->root.dynobj;
+ sgot = htab->sgot;
+ sgotplt = htab->sgotplt;
+ splt = htab->splt;
+ fdpic_p = htab->fdpic_p;
+ }
+ symtab_hdr = &elf_symtab_hdr (input_bfd);
+ sym_hashes = elf_sym_hashes (input_bfd);
+ local_got_offsets = elf_local_got_offsets (input_bfd);
+
+ isec_segment = sh_elf_osec_to_segment (output_bfd,
+ input_section->output_section);
+ if (fdpic_p && sgot)
+ got_segment = sh_elf_osec_to_segment (output_bfd,
+ sgot->output_section);
+ else
+ got_segment = -1;
+ if (fdpic_p && splt)
+ plt_segment = sh_elf_osec_to_segment (output_bfd,
+ splt->output_section);
+ else
+ plt_segment = -1;
+
+ /* We have to handle relocations in vxworks .tls_vars sections
+ specially, because the dynamic loader is 'weird'. */
+ is_vxworks_tls = (htab && htab->vxworks_p && info->shared
+ && !strcmp (input_section->output_section->name,
+ ".tls_vars"));
+
+ 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;
+ int seen_stt_datalabel = 0;
+ bfd_vma off;
+ enum got_type got_type;
+ const char *symname = NULL;
+
+ r_symndx = ELF32_R_SYM (rel->r_info);
+
+ 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_GNU_VTINHERIT
+ && r_type <= (int) R_SH_LABEL)
+ continue;
+ if (r_type == (int) R_SH_NONE)
+ continue;
+
+ if (r_type < 0
+ || r_type >= R_SH_max
+ || (r_type >= (int) R_SH_FIRST_INVALID_RELOC
+ && r_type <= (int) R_SH_LAST_INVALID_RELOC)
+ || (r_type >= (int) R_SH_FIRST_INVALID_RELOC_2
+ && r_type <= (int) R_SH_LAST_INVALID_RELOC_2)
+ || ( r_type >= (int) R_SH_FIRST_INVALID_RELOC_3
+ && r_type <= (int) R_SH_LAST_INVALID_RELOC_3)
+ || ( r_type >= (int) R_SH_FIRST_INVALID_RELOC_4
+ && r_type <= (int) R_SH_LAST_INVALID_RELOC_4)
+ || ( r_type >= (int) R_SH_FIRST_INVALID_RELOC_5
+ && r_type <= (int) R_SH_LAST_INVALID_RELOC_5)
+ || ( r_type >= (int) R_SH_FIRST_INVALID_RELOC_6
+ && r_type <= (int) R_SH_LAST_INVALID_RELOC_6))
+ {
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+
+ howto = get_howto_table (output_bfd) + r_type;
+
+ /* For relocs that aren't partial_inplace, we get the addend from
+ the relocation. */
+ if (! howto->partial_inplace)
+ addend = rel->r_addend;
+
+ h = NULL;
+ sym = NULL;
+ sec = NULL;
+ check_segment[0] = -1;
+ check_segment[1] = -1;
+ if (r_symndx < symtab_hdr->sh_info)
+ {
+ sym = local_syms + r_symndx;
+ sec = local_sections[r_symndx];
+
+ symname = bfd_elf_string_from_elf_section
+ (input_bfd, symtab_hdr->sh_link, sym->st_name);
+ if (symname == NULL || *symname == '\0')
+ symname = bfd_section_name (input_bfd, sec);
+
+ relocation = (sec->output_section->vma
+ + sec->output_offset
+ + sym->st_value);
+ /* A local symbol never has STO_SH5_ISA32, so we don't need
+ datalabel processing here. Make sure this does not change
+ without notice. */
+ if ((sym->st_other & STO_SH5_ISA32) != 0)
+ ((*info->callbacks->reloc_dangerous)
+ (info,
+ _("Unexpected STO_SH5_ISA32 on local symbol is not handled"),
+ input_bfd, input_section, rel->r_offset));
+
+ if (sec != NULL && discarded_section (sec))
+ /* Handled below. */
+ ;
+ else if (info->relocatable)
+ {
+ /* This is a relocatable 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 (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
+ {
+ if (! howto->partial_inplace)
+ {
+ /* For relocations with the addend in the
+ relocation, we need just to update the addend.
+ All real relocs are of type partial_inplace; this
+ code is mostly for completeness. */
+ rel->r_addend += sec->output_offset;
+
+ continue;
+ }
+
+ /* Relocs of type partial_inplace need to pick up the
+ contents in the contents and add the offset resulting
+ from the changed location of the section symbol.
+ Using _bfd_final_link_relocate (e.g. goto
+ final_link_relocate) here would be wrong, because
+ relocations marked pc_relative would get the current
+ location subtracted, and we must only do that at the
+ final link. */
+ r = _bfd_relocate_contents (howto, input_bfd,
+ sec->output_offset
+ + sym->st_value,
+ contents + rel->r_offset);
+ goto relocation_done;
+ }
+
+ continue;
+ }
+ else if (! howto->partial_inplace)
+ {
+ relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
+ addend = rel->r_addend;
+ }
+ else if ((sec->flags & SEC_MERGE)
+ && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
+ {
+ asection *msec;
+
+ if (howto->rightshift || howto->src_mask != 0xffffffff)
+ {
+ (*_bfd_error_handler)
+ (_("%B(%A+0x%lx): %s relocation against SEC_MERGE section"),
+ input_bfd, input_section,
+ (long) rel->r_offset, howto->name);
+ return FALSE;
+ }
+
+ addend = bfd_get_32 (input_bfd, contents + rel->r_offset);
+ msec = sec;
+ addend =
+ _bfd_elf_rel_local_sym (output_bfd, sym, &msec, addend)
+ - relocation;
+ addend += msec->output_section->vma + msec->output_offset;
+ bfd_put_32 (input_bfd, addend, contents + rel->r_offset);
+ addend = 0;
+ }
+ }
+ else
+ {
+ /* FIXME: Ought to make use of the RELOC_FOR_GLOBAL_SYMBOL macro. */
+
+ relocation = 0;
+ h = sym_hashes[r_symndx - symtab_hdr->sh_info];
+ symname = h->root.root.string;
+ while (h->root.type == bfd_link_hash_indirect
+ || h->root.type == bfd_link_hash_warning)
+ {
+#ifdef INCLUDE_SHMEDIA
+ /* If the reference passes a symbol marked with
+ STT_DATALABEL, then any STO_SH5_ISA32 on the final value
+ doesn't count. */
+ seen_stt_datalabel |= h->type == STT_DATALABEL;
+#endif
+ 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)
+ {
+ bfd_boolean dyn;
+
+ dyn = htab ? htab->root.dynamic_sections_created : FALSE;
+ sec = h->root.u.def.section;
+ /* In these cases, we don't need the relocation value.
+ We check specially because in some obscure cases
+ sec->output_section will be NULL. */
+ if (r_type == R_SH_GOTPC
+ || r_type == R_SH_GOTPC_LOW16
+ || r_type == R_SH_GOTPC_MEDLOW16
+ || r_type == R_SH_GOTPC_MEDHI16
+ || r_type == R_SH_GOTPC_HI16
+ || ((r_type == R_SH_PLT32
+ || r_type == R_SH_PLT_LOW16
+ || r_type == R_SH_PLT_MEDLOW16
+ || r_type == R_SH_PLT_MEDHI16
+ || r_type == R_SH_PLT_HI16)
+ && h->plt.offset != (bfd_vma) -1)
+ || ((r_type == R_SH_GOT32
+ || r_type == R_SH_GOT20
+ || r_type == R_SH_GOTFUNCDESC
+ || r_type == R_SH_GOTFUNCDESC20
+ || r_type == R_SH_GOTOFFFUNCDESC
+ || r_type == R_SH_GOTOFFFUNCDESC20
+ || r_type == R_SH_FUNCDESC
+ || r_type == R_SH_GOT_LOW16
+ || r_type == R_SH_GOT_MEDLOW16
+ || r_type == R_SH_GOT_MEDHI16
+ || r_type == R_SH_GOT_HI16)
+ && WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h)
+ && (! info->shared
+ || (! info->symbolic && h->dynindx != -1)
+ || !h->def_regular))
+ /* The cases above are those in which relocation is
+ overwritten in the switch block below. The cases
+ below are those in which we must defer relocation
+ to run-time, because we can't resolve absolute
+ addresses when creating a shared library. */
+ || (info->shared
+ && ((! info->symbolic && h->dynindx != -1)
+ || !h->def_regular)
+ && ((r_type == R_SH_DIR32
+ && !h->forced_local)
+ || (r_type == R_SH_REL32
+ && !SYMBOL_CALLS_LOCAL (info, h)))
+ && ((input_section->flags & SEC_ALLOC) != 0
+ /* DWARF will emit R_SH_DIR32 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
+ && h->def_dynamic)))
+ /* Dynamic relocs are not propagated for SEC_DEBUGGING
+ sections because such sections are not SEC_ALLOC and
+ thus ld.so will not process them. */
+ || (sec->output_section == NULL
+ && ((input_section->flags & SEC_DEBUGGING) != 0
+ && h->def_dynamic))
+ || (sec->output_section == NULL
+ && (sh_elf_hash_entry (h)->got_type == GOT_TLS_IE
+ || sh_elf_hash_entry (h)->got_type == GOT_TLS_GD)))
+ ;
+ else if (sec->output_section != NULL)
+ relocation = ((h->root.u.def.value
+ + sec->output_section->vma
+ + sec->output_offset)
+ /* A STO_SH5_ISA32 causes a "bitor 1" to the
+ symbol value, unless we've seen
+ STT_DATALABEL on the way to it. */
+ | ((h->other & STO_SH5_ISA32) != 0
+ && ! seen_stt_datalabel));
+ else if (!info->relocatable
+ && (_bfd_elf_section_offset (output_bfd, info,
+ input_section,
+ rel->r_offset)
+ != (bfd_vma) -1))
+ {
+ (*_bfd_error_handler)
+ (_("%B(%A+0x%lx): unresolvable %s relocation against symbol `%s'"),
+ input_bfd,
+ input_section,
+ (long) rel->r_offset,
+ howto->name,
+ h->root.root.string);
+ return FALSE;
+ }
+ }
+ else if (h->root.type == bfd_link_hash_undefweak)
+ ;
+ else if (info->unresolved_syms_in_objects == RM_IGNORE
+ && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)
+ ;
+ else if (!info->relocatable)
+ {
+ if (! info->callbacks->undefined_symbol
+ (info, h->root.root.string, input_bfd,
+ input_section, rel->r_offset,
+ (info->unresolved_syms_in_objects == RM_GENERATE_ERROR
+ || ELF_ST_VISIBILITY (h->other))))
+ return FALSE;
+ }
+ }
+
+ if (sec != NULL && discarded_section (sec))
+ RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+ rel, 1, relend, howto, 0, contents);
+
+ if (info->relocatable)
+ continue;
+
+ /* Check for inter-segment relocations in FDPIC files. Most
+ relocations connect the relocation site to the location of
+ the target symbol, but there are some exceptions below. */
+ check_segment[0] = isec_segment;
+ if (sec != NULL)
+ check_segment[1] = sh_elf_osec_to_segment (output_bfd,
+ sec->output_section);
+ else
+ check_segment[1] = -1;
+
+ switch ((int) r_type)
+ {
+ final_link_relocate:
+ /* 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);
+ break;
+
+ case R_SH_IND12W:
+ goto final_link_relocate;
+
+ case R_SH_DIR8WPN:
+ case R_SH_DIR8WPZ:
+ case R_SH_DIR8WPL:
+ /* If the reloc is against the start of this section, then
+ the assembler has already taken care of it and the reloc
+ is here only to assist in relaxing. If the reloc is not
+ against the start of this section, then it's against an
+ external symbol and we must deal with it ourselves. */
+ if (input_section->output_section->vma + input_section->output_offset
+ != relocation)
+ {
+ int disp = (relocation
+ - input_section->output_section->vma
+ - input_section->output_offset
+ - rel->r_offset);
+ int mask = 0;
+ switch (r_type)
+ {
+ case R_SH_DIR8WPN:
+ case R_SH_DIR8WPZ: mask = 1; break;
+ case R_SH_DIR8WPL: mask = 3; break;
+ default: mask = 0; break;
+ }
+ if (disp & mask)
+ {
+ ((*_bfd_error_handler)
+ (_("%B: 0x%lx: fatal: unaligned branch target for relax-support relocation"),
+ input_section->owner,
+ (unsigned long) rel->r_offset));
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+ relocation -= 4;
+ goto final_link_relocate;
+ }
+ r = bfd_reloc_ok;
+ break;
+
+ default:
+#ifdef INCLUDE_SHMEDIA
+ if (shmedia_prepare_reloc (info, input_bfd, input_section,
+ contents, rel, &relocation))
+ goto final_link_relocate;
+#endif
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+
+ case R_SH_DIR16:
+ case R_SH_DIR8:
+ case R_SH_DIR8U:
+ case R_SH_DIR8S:
+ case R_SH_DIR4U:
+ goto final_link_relocate;
+
+ case R_SH_DIR8UL:
+ case R_SH_DIR4UL:
+ if (relocation & 3)
+ {
+ ((*_bfd_error_handler)
+ (_("%B: 0x%lx: fatal: unaligned %s relocation 0x%lx"),
+ input_section->owner,
+ (unsigned long) rel->r_offset, howto->name,
+ (unsigned long) relocation));
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+ goto final_link_relocate;
+
+ case R_SH_DIR8UW:
+ case R_SH_DIR8SW:
+ case R_SH_DIR4UW:
+ if (relocation & 1)
+ {
+ ((*_bfd_error_handler)
+ (_("%B: 0x%lx: fatal: unaligned %s relocation 0x%lx"),
+ input_section->owner,
+ (unsigned long) rel->r_offset, howto->name,
+ (unsigned long) relocation));
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+ goto final_link_relocate;
+
+ case R_SH_PSHA:
+ if ((signed int)relocation < -32
+ || (signed int)relocation > 32)
+ {
+ ((*_bfd_error_handler)
+ (_("%B: 0x%lx: fatal: R_SH_PSHA relocation %d not in range -32..32"),
+ input_section->owner,
+ (unsigned long) rel->r_offset,
+ (unsigned long) relocation));
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+ goto final_link_relocate;
+
+ case R_SH_PSHL:
+ if ((signed int)relocation < -16
+ || (signed int)relocation > 16)
+ {
+ ((*_bfd_error_handler)
+ (_("%B: 0x%lx: fatal: R_SH_PSHL relocation %d not in range -32..32"),
+ input_section->owner,
+ (unsigned long) rel->r_offset,
+ (unsigned long) relocation));
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+ goto final_link_relocate;
+
+ case R_SH_DIR32:
+ case R_SH_REL32:
+#ifdef INCLUDE_SHMEDIA
+ case R_SH_IMM_LOW16_PCREL:
+ case R_SH_IMM_MEDLOW16_PCREL:
+ case R_SH_IMM_MEDHI16_PCREL:
+ case R_SH_IMM_HI16_PCREL:
+#endif
+ if (info->shared
+ && (h == NULL
+ || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
+ || h->root.type != bfd_link_hash_undefweak)
+ && r_symndx != STN_UNDEF
+ && (input_section->flags & SEC_ALLOC) != 0
+ && !is_vxworks_tls
+ && (r_type == R_SH_DIR32
+ || !SYMBOL_CALLS_LOCAL (info, h)))
+ {
+ Elf_Internal_Rela outrel;
+ bfd_byte *loc;
+ bfd_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)
+ {
+ sreloc = _bfd_elf_get_dynamic_reloc_section
+ (input_bfd, input_section, /*rela?*/ TRUE);
+ if (sreloc == NULL)
+ return FALSE;
+ }
+
+ skip = FALSE;
+ relocate = FALSE;
+
+ outrel.r_offset =
+ _bfd_elf_section_offset (output_bfd, info, input_section,
+ rel->r_offset);
+ if (outrel.r_offset == (bfd_vma) -1)
+ skip = TRUE;
+ else if (outrel.r_offset == (bfd_vma) -2)
+ skip = TRUE, relocate = TRUE;
+ outrel.r_offset += (input_section->output_section->vma
+ + input_section->output_offset);
+
+ if (skip)
+ memset (&outrel, 0, sizeof outrel);
+ else if (r_type == R_SH_REL32)
+ {
+ BFD_ASSERT (h != NULL && h->dynindx != -1);
+ outrel.r_info = ELF32_R_INFO (h->dynindx, R_SH_REL32);
+ outrel.r_addend
+ = (howto->partial_inplace
+ ? bfd_get_32 (input_bfd, contents + rel->r_offset)
+ : addend);
+ }
+#ifdef INCLUDE_SHMEDIA
+ else if (r_type == R_SH_IMM_LOW16_PCREL
+ || r_type == R_SH_IMM_MEDLOW16_PCREL
+ || r_type == R_SH_IMM_MEDHI16_PCREL
+ || r_type == R_SH_IMM_HI16_PCREL)
+ {
+ BFD_ASSERT (h != NULL && h->dynindx != -1);
+ outrel.r_info = ELF32_R_INFO (h->dynindx, r_type);
+ outrel.r_addend = addend;
+ }
+#endif
+ else if (fdpic_p
+ && (h == NULL
+ || ((info->symbolic || h->dynindx == -1)
+ && h->def_regular)))
+ {
+ int dynindx;
+
+ BFD_ASSERT (sec != NULL);
+ BFD_ASSERT (sec->output_section != NULL);
+ dynindx = elf_section_data (sec->output_section)->dynindx;
+ outrel.r_info = ELF32_R_INFO (dynindx, R_SH_DIR32);
+ outrel.r_addend = relocation;
+ outrel.r_addend
+ += (howto->partial_inplace
+ ? bfd_get_32 (input_bfd, contents + rel->r_offset)
+ : addend);
+ outrel.r_addend -= sec->output_section->vma;
+ }
+ else
+ {
+ /* h->dynindx may be -1 if this symbol was marked to
+ become local. */
+ if (h == NULL
+ || ((info->symbolic || h->dynindx == -1)
+ && h->def_regular))
+ {
+ relocate = howto->partial_inplace;
+ outrel.r_info = ELF32_R_INFO (0, R_SH_RELATIVE);
+ }
+ else
+ {
+ BFD_ASSERT (h->dynindx != -1);
+ outrel.r_info = ELF32_R_INFO (h->dynindx, R_SH_DIR32);
+ }
+ outrel.r_addend = relocation;
+ outrel.r_addend
+ += (howto->partial_inplace
+ ? bfd_get_32 (input_bfd, contents + rel->r_offset)
+ : addend);
+ }
+
+ loc = sreloc->contents;
+ loc += sreloc->reloc_count++ * sizeof (Elf32_External_Rela);
+ bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
+
+ check_segment[0] = check_segment[1] = -1;
+
+ /* 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;
+ }
+ else if (fdpic_p && !info->shared
+ && r_type == R_SH_DIR32
+ && (input_section->flags & SEC_ALLOC) != 0)
+ {
+ bfd_vma offset;
+
+ BFD_ASSERT (htab);
+
+ if (sh_elf_osec_readonly_p (output_bfd,
+ input_section->output_section))
+ {
+ (*_bfd_error_handler)
+ (_("%B(%A+0x%lx): cannot emit fixup to `%s' in read-only section"),
+ input_bfd,
+ input_section,
+ (long) rel->r_offset,
+ symname);
+ return FALSE;
+ }
+
+ offset = _bfd_elf_section_offset (output_bfd, info,
+ input_section, rel->r_offset);
+ if (offset != (bfd_vma)-1)
+ sh_elf_add_rofixup (output_bfd, htab->srofixup,
+ input_section->output_section->vma
+ + input_section->output_offset
+ + rel->r_offset);
+
+ check_segment[0] = check_segment[1] = -1;
+ }
+ /* We don't want warnings for non-NULL tests on undefined weak
+ symbols. */
+ else if (r_type == R_SH_REL32
+ && h
+ && h->root.type == bfd_link_hash_undefweak)
+ check_segment[0] = check_segment[1] = -1;
+ goto final_link_relocate;
+
+ case R_SH_GOTPLT32:
+#ifdef INCLUDE_SHMEDIA
+ case R_SH_GOTPLT_LOW16:
+ case R_SH_GOTPLT_MEDLOW16:
+ case R_SH_GOTPLT_MEDHI16:
+ case R_SH_GOTPLT_HI16:
+ case R_SH_GOTPLT10BY4:
+ case R_SH_GOTPLT10BY8:
+#endif
+ /* Relocation is to the entry for this symbol in the
+ procedure linkage table. */
+
+ if (h == NULL
+ || h->forced_local
+ || ! info->shared
+ || info->symbolic
+ || h->dynindx == -1
+ || h->plt.offset == (bfd_vma) -1
+ || h->got.offset != (bfd_vma) -1)
+ goto force_got;
+
+ /* Relocation is to the entry for this symbol in the global
+ offset table extension for the procedure linkage table. */
+
+ BFD_ASSERT (htab);
+ BFD_ASSERT (sgotplt != NULL);
+ relocation = (sgotplt->output_offset
+ + (get_plt_index (htab->plt_info, h->plt.offset)
+ + 3) * 4);
+
+#ifdef GOT_BIAS
+ relocation -= GOT_BIAS;
+#endif
+
+ goto final_link_relocate;
+
+ force_got:
+ case R_SH_GOT32:
+ case R_SH_GOT20:
+#ifdef INCLUDE_SHMEDIA
+ case R_SH_GOT_LOW16:
+ case R_SH_GOT_MEDLOW16:
+ case R_SH_GOT_MEDHI16:
+ case R_SH_GOT_HI16:
+ case R_SH_GOT10BY4:
+ case R_SH_GOT10BY8:
+#endif
+ /* Relocation is to the entry for this symbol in the global
+ offset table. */
+
+ BFD_ASSERT (htab);
+ BFD_ASSERT (sgot != NULL);
+ check_segment[0] = check_segment[1] = -1;
+
+ if (h != NULL)
+ {
+ bfd_boolean dyn;
+
+ off = h->got.offset;
+#ifdef INCLUDE_SHMEDIA
+ if (seen_stt_datalabel)
+ {
+ struct elf_sh_link_hash_entry *hsh;
+
+ hsh = (struct elf_sh_link_hash_entry *)h;
+ off = hsh->datalabel_got.offset;
+ }
+#endif
+ BFD_ASSERT (off != (bfd_vma) -1);
+
+ dyn = htab->root.dynamic_sections_created;
+ if (! WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h)
+ || (info->shared
+ && SYMBOL_REFERENCES_LOCAL (info, h))
+ || (ELF_ST_VISIBILITY (h->other)
+ && h->root.type == bfd_link_hash_undefweak))
+ {
+ /* 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);
+#ifdef INCLUDE_SHMEDIA
+ if (seen_stt_datalabel)
+ {
+ struct elf_sh_link_hash_entry *hsh;
+
+ hsh = (struct elf_sh_link_hash_entry *)h;
+ hsh->datalabel_got.offset |= 1;
+ }
+ else
+#endif
+ h->got.offset |= 1;
+
+ /* If we initialize the GOT entry here with a valid
+ symbol address, also add a fixup. */
+ if (fdpic_p && !info->shared
+ && sh_elf_hash_entry (h)->got_type == GOT_NORMAL
+ && (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
+ || h->root.type != bfd_link_hash_undefweak))
+ sh_elf_add_rofixup (output_bfd, htab->srofixup,
+ sgot->output_section->vma
+ + sgot->output_offset
+ + off);
+ }
+ }
+
+ relocation = sh_elf_got_offset (htab) + off;
+ }
+ else
+ {
+#ifdef INCLUDE_SHMEDIA
+ if (rel->r_addend)
+ {
+ BFD_ASSERT (local_got_offsets != NULL
+ && (local_got_offsets[symtab_hdr->sh_info
+ + r_symndx]
+ != (bfd_vma) -1));
+
+ off = local_got_offsets[symtab_hdr->sh_info
+ + r_symndx];
+ }
+ else
+ {
+#endif
+ BFD_ASSERT (local_got_offsets != NULL
+ && local_got_offsets[r_symndx] != (bfd_vma) -1);
+
+ off = local_got_offsets[r_symndx];
+#ifdef INCLUDE_SHMEDIA
+ }
+#endif
+
+ /* 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)
+ {
+ Elf_Internal_Rela outrel;
+ bfd_byte *loc;
+
+ if (srelgot == NULL)
+ {
+ srelgot = bfd_get_linker_section (dynobj,
+ ".rela.got");
+ BFD_ASSERT (srelgot != NULL);
+ }
+
+ outrel.r_offset = (sgot->output_section->vma
+ + sgot->output_offset
+ + off);
+ if (fdpic_p)
+ {
+ int dynindx
+ = elf_section_data (sec->output_section)->dynindx;
+ outrel.r_info = ELF32_R_INFO (dynindx, R_SH_DIR32);
+ outrel.r_addend = relocation;
+ outrel.r_addend -= sec->output_section->vma;
+ }
+ else
+ {
+ outrel.r_info = ELF32_R_INFO (0, R_SH_RELATIVE);
+ outrel.r_addend = relocation;
+ }
+ loc = srelgot->contents;
+ loc += srelgot->reloc_count++ * sizeof (Elf32_External_Rela);
+ bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
+ }
+ else if (fdpic_p
+ && (sh_elf_local_got_type (input_bfd) [r_symndx]
+ == GOT_NORMAL))
+ sh_elf_add_rofixup (output_bfd, htab->srofixup,
+ sgot->output_section->vma
+ + sgot->output_offset
+ + off);
+
+#ifdef INCLUDE_SHMEDIA
+ if (rel->r_addend)
+ local_got_offsets[symtab_hdr->sh_info + r_symndx] |= 1;
+ else
+#endif
+ local_got_offsets[r_symndx] |= 1;
+ }
+
+ relocation = sh_elf_got_offset (htab) + off;
+ }
+
+#ifdef GOT_BIAS
+ relocation -= GOT_BIAS;
+#endif
+
+ if (r_type == R_SH_GOT20)
+ {
+ r = install_movi20_field (output_bfd, relocation + addend,
+ input_bfd, input_section, contents,
+ rel->r_offset);
+ break;
+ }
+ else
+ goto final_link_relocate;
+
+ case R_SH_GOTOFF:
+ case R_SH_GOTOFF20:
+#ifdef INCLUDE_SHMEDIA
+ case R_SH_GOTOFF_LOW16:
+ case R_SH_GOTOFF_MEDLOW16:
+ case R_SH_GOTOFF_MEDHI16:
+ case R_SH_GOTOFF_HI16:
+#endif
+ /* GOTOFF relocations are relative to _GLOBAL_OFFSET_TABLE_, which
+ we place at the start of the .got.plt section. This is the same
+ as the start of the output .got section, unless there are function
+ descriptors in front of it. */
+ BFD_ASSERT (htab);
+ BFD_ASSERT (sgotplt != NULL);
+ check_segment[0] = got_segment;
+ relocation -= sgotplt->output_section->vma + sgotplt->output_offset
+ + htab->root.hgot->root.u.def.value;
+
+#ifdef GOT_BIAS
+ relocation -= GOT_BIAS;
+#endif
+
+ addend = rel->r_addend;
+
+ if (r_type == R_SH_GOTOFF20)
+ {
+ r = install_movi20_field (output_bfd, relocation + addend,
+ input_bfd, input_section, contents,
+ rel->r_offset);
+ break;
+ }
+ else
+ goto final_link_relocate;
+
+ case R_SH_GOTPC:
+#ifdef INCLUDE_SHMEDIA
+ case R_SH_GOTPC_LOW16:
+ case R_SH_GOTPC_MEDLOW16:
+ case R_SH_GOTPC_MEDHI16:
+ case R_SH_GOTPC_HI16:
+#endif
+ /* Use global offset table as symbol value. */
+
+ BFD_ASSERT (sgotplt != NULL);
+ relocation = sgotplt->output_section->vma + sgotplt->output_offset;
+
+#ifdef GOT_BIAS
+ relocation += GOT_BIAS;
+#endif
+
+ addend = rel->r_addend;
+
+ goto final_link_relocate;
+
+ case R_SH_PLT32:
+#ifdef INCLUDE_SHMEDIA
+ case R_SH_PLT_LOW16:
+ case R_SH_PLT_MEDLOW16:
+ case R_SH_PLT_MEDHI16:
+ case R_SH_PLT_HI16:
+#endif
+ /* Relocation is to the entry for this symbol in the
+ procedure linkage table. */
+
+ /* Resolve a PLT reloc against a local symbol directly,
+ without using the procedure linkage table. */
+ if (h == NULL)
+ goto final_link_relocate;
+
+ /* We don't want to warn on calls to undefined weak symbols,
+ as calls to them must be protected by non-NULL tests
+ anyway, and unprotected calls would invoke undefined
+ behavior. */
+ if (h->root.type == bfd_link_hash_undefweak)
+ check_segment[0] = check_segment[1] = -1;
+
+ if (h->forced_local)
+ goto final_link_relocate;
+
+ 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 final_link_relocate;
+ }
+
+ BFD_ASSERT (splt != NULL);
+ check_segment[1] = plt_segment;
+ relocation = (splt->output_section->vma
+ + splt->output_offset
+ + h->plt.offset);
+
+#ifdef INCLUDE_SHMEDIA
+ relocation++;
+#endif
+
+ addend = rel->r_addend;
+
+ goto final_link_relocate;
+
+ /* Relocation is to the canonical function descriptor for this
+ symbol, possibly via the GOT. Initialize the GOT
+ entry and function descriptor if necessary. */
+ case R_SH_GOTFUNCDESC:
+ case R_SH_GOTFUNCDESC20:
+ case R_SH_FUNCDESC:
+ {
+ int dynindx = -1;
+ asection *reloc_section;
+ bfd_vma reloc_offset;
+ int reloc_type = R_SH_FUNCDESC;
+
+ BFD_ASSERT (htab);
+
+ check_segment[0] = check_segment[1] = -1;
+
+ /* FIXME: See what FRV does for global symbols in the
+ executable, with --export-dynamic. Do they need ld.so
+ to allocate official descriptors? See what this code
+ does. */
+
+ relocation = 0;
+ addend = 0;
+
+ if (r_type == R_SH_FUNCDESC)
+ {
+ reloc_section = input_section;
+ reloc_offset = rel->r_offset;
+ }
+ else
+ {
+ reloc_section = sgot;
+
+ if (h != NULL)
+ reloc_offset = h->got.offset;
+ else
+ {
+ BFD_ASSERT (local_got_offsets != NULL);
+ reloc_offset = local_got_offsets[r_symndx];
+ }
+ BFD_ASSERT (reloc_offset != MINUS_ONE);
+
+ if (reloc_offset & 1)
+ {
+ reloc_offset &= ~1;
+ goto funcdesc_done_got;
+ }
+ }
+
+ if (h && h->root.type == bfd_link_hash_undefweak
+ && (SYMBOL_CALLS_LOCAL (info, h)
+ || !htab->root.dynamic_sections_created))
+ /* Undefined weak symbol which will not be dynamically
+ resolved later; leave it at zero. */
+ goto funcdesc_leave_zero;
+ else if (SYMBOL_CALLS_LOCAL (info, h)
+ && ! SYMBOL_FUNCDESC_LOCAL (info, h))
+ {
+ /* If the symbol needs a non-local function descriptor
+ but binds locally (i.e., its visibility is
+ protected), emit a dynamic relocation decayed to
+ section+offset. This is an optimization; the dynamic
+ linker would resolve our function descriptor request
+ to our copy of the function anyway. */
+ dynindx = elf_section_data (h->root.u.def.section
+ ->output_section)->dynindx;
+ relocation += h->root.u.def.section->output_offset
+ + h->root.u.def.value;
+ }
+ else if (! SYMBOL_FUNCDESC_LOCAL (info, h))
+ {
+ /* If the symbol is dynamic and there will be dynamic
+ symbol resolution because we are or are linked with a
+ shared library, emit a FUNCDESC relocation such that
+ the dynamic linker will allocate the function
+ descriptor. */
+ BFD_ASSERT (h->dynindx != -1);
+ dynindx = h->dynindx;
+ }
+ else
+ {
+ bfd_vma offset;
+
+ /* Otherwise, we know we have a private function
+ descriptor, so reference it directly. */
+ reloc_type = R_SH_DIR32;
+ dynindx = elf_section_data (htab->sfuncdesc
+ ->output_section)->dynindx;
+
+ if (h)
+ {
+ offset = sh_elf_hash_entry (h)->funcdesc.offset;
+ BFD_ASSERT (offset != MINUS_ONE);
+ if ((offset & 1) == 0)
+ {
+ if (!sh_elf_initialize_funcdesc (output_bfd, info, h,
+ offset, NULL, 0))
+ return FALSE;
+ sh_elf_hash_entry (h)->funcdesc.offset |= 1;
+ }
+ }
+ else
+ {
+ union gotref *local_funcdesc;
+
+ local_funcdesc = sh_elf_local_funcdesc (input_bfd);
+ offset = local_funcdesc[r_symndx].offset;
+ BFD_ASSERT (offset != MINUS_ONE);
+ if ((offset & 1) == 0)
+ {
+ if (!sh_elf_initialize_funcdesc (output_bfd, info, NULL,
+ offset, sec,
+ sym->st_value))
+ return FALSE;
+ local_funcdesc[r_symndx].offset |= 1;
+ }
+ }
+
+ relocation = htab->sfuncdesc->output_offset + (offset & ~1);
+ }
+
+ if (!info->shared && SYMBOL_FUNCDESC_LOCAL (info, h))
+ {
+ bfd_vma offset;
+
+ if (sh_elf_osec_readonly_p (output_bfd,
+ reloc_section->output_section))
+ {
+ (*_bfd_error_handler)
+ (_("%B(%A+0x%lx): cannot emit fixup to `%s' in read-only section"),
+ input_bfd,
+ input_section,
+ (long) rel->r_offset,
+ symname);
+ return FALSE;
+ }
+
+ offset = _bfd_elf_section_offset (output_bfd, info,
+ reloc_section, reloc_offset);
+
+ if (offset != (bfd_vma)-1)
+ sh_elf_add_rofixup (output_bfd, htab->srofixup,
+ offset
+ + reloc_section->output_section->vma
+ + reloc_section->output_offset);
+ }
+ else if ((reloc_section->output_section->flags
+ & (SEC_ALLOC | SEC_LOAD)) == (SEC_ALLOC | SEC_LOAD))
+ {
+ bfd_vma offset;
+
+ if (sh_elf_osec_readonly_p (output_bfd,
+ reloc_section->output_section))
+ {
+ info->callbacks->warning
+ (info,
+ _("cannot emit dynamic relocations in read-only section"),
+ symname, input_bfd, reloc_section, reloc_offset);
+ return FALSE;
+ }
+
+ if (srelgot == NULL)
+ {
+ srelgot = bfd_get_linker_section (dynobj, ".rela.got");
+ BFD_ASSERT (srelgot != NULL);
+ }
+
+ offset = _bfd_elf_section_offset (output_bfd, info,
+ reloc_section, reloc_offset);
+
+ if (offset != (bfd_vma)-1)
+ sh_elf_add_dyn_reloc (output_bfd, srelgot,
+ offset
+ + reloc_section->output_section->vma
+ + reloc_section->output_offset,
+ reloc_type, dynindx, relocation);
+
+ if (r_type == R_SH_FUNCDESC)
+ {
+ r = bfd_reloc_ok;
+ break;
+ }
+ else
+ {
+ relocation = 0;
+ goto funcdesc_leave_zero;
+ }
+ }
+
+ if (SYMBOL_FUNCDESC_LOCAL (info, h))
+ relocation += htab->sfuncdesc->output_section->vma;
+ funcdesc_leave_zero:
+ if (r_type != R_SH_FUNCDESC)
+ {
+ bfd_put_32 (output_bfd, relocation,
+ reloc_section->contents + reloc_offset);
+ if (h != NULL)
+ h->got.offset |= 1;
+ else
+ local_got_offsets[r_symndx] |= 1;
+
+ funcdesc_done_got:
+
+ relocation = sh_elf_got_offset (htab) + reloc_offset;
+#ifdef GOT_BIAS
+ relocation -= GOT_BIAS;
+#endif
+ }
+ if (r_type == R_SH_GOTFUNCDESC20)
+ {
+ r = install_movi20_field (output_bfd, relocation + addend,
+ input_bfd, input_section, contents,
+ rel->r_offset);
+ break;
+ }
+ else
+ goto final_link_relocate;
+ }
+ break;
+
+ case R_SH_GOTOFFFUNCDESC:
+ case R_SH_GOTOFFFUNCDESC20:
+ /* FIXME: See R_SH_FUNCDESC comment about global symbols in the
+ executable and --export-dynamic. If such symbols get
+ ld.so-allocated descriptors we can not use R_SH_GOTOFFFUNCDESC
+ for them. */
+ BFD_ASSERT (htab);
+
+ check_segment[0] = check_segment[1] = -1;
+ relocation = 0;
+ addend = rel->r_addend;
+
+ if (h && (h->root.type == bfd_link_hash_undefweak
+ || !SYMBOL_FUNCDESC_LOCAL (info, h)))
+ {
+ _bfd_error_handler
+ (_("%B(%A+0x%lx): %s relocation against external symbol \"%s\""),
+ input_bfd, input_section, (long) rel->r_offset, howto->name,
+ h->root.root.string);
+ return FALSE;
+ }
+ else
+ {
+ bfd_vma offset;
+
+ /* Otherwise, we know we have a private function
+ descriptor, so reference it directly. */
+ if (h)
+ {
+ offset = sh_elf_hash_entry (h)->funcdesc.offset;
+ BFD_ASSERT (offset != MINUS_ONE);
+ if ((offset & 1) == 0)
+ {
+ if (!sh_elf_initialize_funcdesc (output_bfd, info, h,
+ offset, NULL, 0))
+ return FALSE;
+ sh_elf_hash_entry (h)->funcdesc.offset |= 1;
+ }
+ }
+ else
+ {
+ union gotref *local_funcdesc;
+
+ local_funcdesc = sh_elf_local_funcdesc (input_bfd);
+ offset = local_funcdesc[r_symndx].offset;
+ BFD_ASSERT (offset != MINUS_ONE);
+ if ((offset & 1) == 0)
+ {
+ if (!sh_elf_initialize_funcdesc (output_bfd, info, NULL,
+ offset, sec,
+ sym->st_value))
+ return FALSE;
+ local_funcdesc[r_symndx].offset |= 1;
+ }
+ }
+
+ relocation = htab->sfuncdesc->output_offset + (offset & ~1);
+ }
+
+ relocation -= (htab->root.hgot->root.u.def.value
+ + sgotplt->output_offset);
+#ifdef GOT_BIAS
+ relocation -= GOT_BIAS;
+#endif
+
+ if (r_type == R_SH_GOTOFFFUNCDESC20)
+ {
+ r = install_movi20_field (output_bfd, relocation + addend,
+ input_bfd, input_section, contents,
+ rel->r_offset);
+ break;
+ }
+ else
+ goto final_link_relocate;
+
+ case R_SH_LOOP_START:
+ {
+ static bfd_vma start, end;
+
+ start = (relocation + rel->r_addend
+ - (sec->output_section->vma + sec->output_offset));
+ r = sh_elf_reloc_loop (r_type, input_bfd, input_section, contents,
+ rel->r_offset, sec, start, end);
+ break;
+
+ case R_SH_LOOP_END:
+ end = (relocation + rel->r_addend
+ - (sec->output_section->vma + sec->output_offset));
+ r = sh_elf_reloc_loop (r_type, input_bfd, input_section, contents,
+ rel->r_offset, sec, start, end);
+ break;
+ }
+
+ case R_SH_TLS_GD_32:
+ case R_SH_TLS_IE_32:
+ BFD_ASSERT (htab);
+ check_segment[0] = check_segment[1] = -1;
+ r_type = sh_elf_optimized_tls_reloc (info, r_type, h == NULL);
+ got_type = GOT_UNKNOWN;
+ if (h == NULL && local_got_offsets)
+ got_type = sh_elf_local_got_type (input_bfd) [r_symndx];
+ else if (h != NULL)
+ {
+ got_type = sh_elf_hash_entry (h)->got_type;
+ if (! info->shared
+ && (h->dynindx == -1
+ || h->def_regular))
+ r_type = R_SH_TLS_LE_32;
+ }
+
+ if (r_type == R_SH_TLS_GD_32 && got_type == GOT_TLS_IE)
+ r_type = R_SH_TLS_IE_32;
+
+ if (r_type == R_SH_TLS_LE_32)
+ {
+ bfd_vma offset;
+ unsigned short insn;
+
+ if (ELF32_R_TYPE (rel->r_info) == R_SH_TLS_GD_32)
+ {
+ /* GD->LE transition:
+ mov.l 1f,r4; mova 2f,r0; mov.l 2f,r1; add r0,r1;
+ jsr @r1; add r12,r4; bra 3f; nop; .align 2;
+ 1: .long x$TLSGD; 2: .long __tls_get_addr@PLT; 3:
+ We change it into:
+ mov.l 1f,r4; stc gbr,r0; add r4,r0; nop;
+ nop; nop; ...
+ 1: .long x@TPOFF; 2: .long __tls_get_addr@PLT; 3:. */
+
+ offset = rel->r_offset;
+ BFD_ASSERT (offset >= 16);
+ /* Size of GD instructions is 16 or 18. */
+ offset -= 16;
+ insn = bfd_get_16 (input_bfd, contents + offset + 0);
+ if ((insn & 0xff00) == 0xc700)
+ {
+ BFD_ASSERT (offset >= 2);
+ offset -= 2;
+ insn = bfd_get_16 (input_bfd, contents + offset + 0);
+ }
+
+ BFD_ASSERT ((insn & 0xff00) == 0xd400);
+ insn = bfd_get_16 (input_bfd, contents + offset + 2);
+ BFD_ASSERT ((insn & 0xff00) == 0xc700);
+ insn = bfd_get_16 (input_bfd, contents + offset + 4);
+ BFD_ASSERT ((insn & 0xff00) == 0xd100);
+ insn = bfd_get_16 (input_bfd, contents + offset + 6);
+ BFD_ASSERT (insn == 0x310c);
+ insn = bfd_get_16 (input_bfd, contents + offset + 8);
+ BFD_ASSERT (insn == 0x410b);
+ insn = bfd_get_16 (input_bfd, contents + offset + 10);
+ BFD_ASSERT (insn == 0x34cc);
+
+ bfd_put_16 (output_bfd, 0x0012, contents + offset + 2);
+ bfd_put_16 (output_bfd, 0x304c, contents + offset + 4);
+ bfd_put_16 (output_bfd, 0x0009, contents + offset + 6);
+ bfd_put_16 (output_bfd, 0x0009, contents + offset + 8);
+ bfd_put_16 (output_bfd, 0x0009, contents + offset + 10);
+ }
+ else
+ {
+ int target;
+
+ /* IE->LE transition:
+ mov.l 1f,r0; stc gbr,rN; mov.l @(r0,r12),rM;
+ bra 2f; add ...; .align 2; 1: x@GOTTPOFF; 2:
+ We change it into:
+ mov.l .Ln,rM; stc gbr,rN; nop; ...;
+ 1: x@TPOFF; 2:. */
+
+ offset = rel->r_offset;
+ BFD_ASSERT (offset >= 16);
+ /* Size of IE instructions is 10 or 12. */
+ offset -= 10;
+ insn = bfd_get_16 (input_bfd, contents + offset + 0);
+ if ((insn & 0xf0ff) == 0x0012)
+ {
+ BFD_ASSERT (offset >= 2);
+ offset -= 2;
+ insn = bfd_get_16 (input_bfd, contents + offset + 0);
+ }
+
+ BFD_ASSERT ((insn & 0xff00) == 0xd000);
+ target = insn & 0x00ff;
+ insn = bfd_get_16 (input_bfd, contents + offset + 2);
+ BFD_ASSERT ((insn & 0xf0ff) == 0x0012);
+ insn = bfd_get_16 (input_bfd, contents + offset + 4);
+ BFD_ASSERT ((insn & 0xf0ff) == 0x00ce);
+ insn = 0xd000 | (insn & 0x0f00) | target;
+ bfd_put_16 (output_bfd, insn, contents + offset + 0);
+ bfd_put_16 (output_bfd, 0x0009, contents + offset + 4);
+ }
+
+ bfd_put_32 (output_bfd, tpoff (info, relocation),
+ contents + rel->r_offset);
+ continue;
+ }
+
+ if (sgot == NULL || sgotplt == NULL)
+ abort ();
+
+ if (h != NULL)
+ off = h->got.offset;
+ else
+ {
+ if (local_got_offsets == NULL)
+ abort ();
+
+ off = local_got_offsets[r_symndx];
+ }
+
+ /* Relocate R_SH_TLS_IE_32 directly when statically linking. */
+ if (r_type == R_SH_TLS_IE_32
+ && ! htab->root.dynamic_sections_created)
+ {
+ off &= ~1;
+ bfd_put_32 (output_bfd, tpoff (info, relocation),
+ sgot->contents + off);
+ bfd_put_32 (output_bfd, sh_elf_got_offset (htab) + off,
+ contents + rel->r_offset);
+ continue;
+ }
+
+ if ((off & 1) != 0)
+ off &= ~1;
+ else
+ {
+ Elf_Internal_Rela outrel;
+ bfd_byte *loc;
+ int dr_type, indx;
+
+ if (srelgot == NULL)
+ {
+ srelgot = bfd_get_linker_section (dynobj, ".rela.got");
+ BFD_ASSERT (srelgot != NULL);
+ }
+
+ outrel.r_offset = (sgot->output_section->vma
+ + sgot->output_offset + off);
+
+ if (h == NULL || h->dynindx == -1)
+ indx = 0;
+ else
+ indx = h->dynindx;
+
+ dr_type = (r_type == R_SH_TLS_GD_32 ? R_SH_TLS_DTPMOD32 :
+ R_SH_TLS_TPOFF32);
+ if (dr_type == R_SH_TLS_TPOFF32 && indx == 0)
+ outrel.r_addend = relocation - dtpoff_base (info);
+ else
+ outrel.r_addend = 0;
+ outrel.r_info = ELF32_R_INFO (indx, dr_type);
+ loc = srelgot->contents;
+ loc += srelgot->reloc_count++ * sizeof (Elf32_External_Rela);
+ bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
+
+ if (r_type == R_SH_TLS_GD_32)
+ {
+ if (indx == 0)
+ {
+ bfd_put_32 (output_bfd,
+ relocation - dtpoff_base (info),
+ sgot->contents + off + 4);
+ }
+ else
+ {
+ outrel.r_info = ELF32_R_INFO (indx,
+ R_SH_TLS_DTPOFF32);
+ outrel.r_offset += 4;
+ outrel.r_addend = 0;
+ srelgot->reloc_count++;
+ loc += sizeof (Elf32_External_Rela);
+ bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
+ }
+ }
+
+ if (h != NULL)
+ h->got.offset |= 1;
+ else
+ local_got_offsets[r_symndx] |= 1;
+ }
+
+ if (off >= (bfd_vma) -2)
+ abort ();
+
+ if (r_type == (int) ELF32_R_TYPE (rel->r_info))
+ relocation = sh_elf_got_offset (htab) + off;
+ else
+ {
+ bfd_vma offset;
+ unsigned short insn;
+
+ /* GD->IE transition:
+ mov.l 1f,r4; mova 2f,r0; mov.l 2f,r1; add r0,r1;
+ jsr @r1; add r12,r4; bra 3f; nop; .align 2;
+ 1: .long x$TLSGD; 2: .long __tls_get_addr@PLT; 3:
+ We change it into:
+ mov.l 1f,r0; stc gbr,r4; mov.l @(r0,r12),r0; add r4,r0;
+ nop; nop; bra 3f; nop; .align 2;
+ 1: .long x@TPOFF; 2:...; 3:. */
+
+ offset = rel->r_offset;
+ BFD_ASSERT (offset >= 16);
+ /* Size of GD instructions is 16 or 18. */
+ offset -= 16;
+ insn = bfd_get_16 (input_bfd, contents + offset + 0);
+ if ((insn & 0xff00) == 0xc700)
+ {
+ BFD_ASSERT (offset >= 2);
+ offset -= 2;
+ insn = bfd_get_16 (input_bfd, contents + offset + 0);
+ }
+
+ BFD_ASSERT ((insn & 0xff00) == 0xd400);
+
+ /* Replace mov.l 1f,R4 with mov.l 1f,r0. */
+ bfd_put_16 (output_bfd, insn & 0xf0ff, contents + offset);
+
+ insn = bfd_get_16 (input_bfd, contents + offset + 2);
+ BFD_ASSERT ((insn & 0xff00) == 0xc700);
+ insn = bfd_get_16 (input_bfd, contents + offset + 4);
+ BFD_ASSERT ((insn & 0xff00) == 0xd100);
+ insn = bfd_get_16 (input_bfd, contents + offset + 6);
+ BFD_ASSERT (insn == 0x310c);
+ insn = bfd_get_16 (input_bfd, contents + offset + 8);
+ BFD_ASSERT (insn == 0x410b);
+ insn = bfd_get_16 (input_bfd, contents + offset + 10);
+ BFD_ASSERT (insn == 0x34cc);
+
+ bfd_put_16 (output_bfd, 0x0412, contents + offset + 2);
+ bfd_put_16 (output_bfd, 0x00ce, contents + offset + 4);
+ bfd_put_16 (output_bfd, 0x304c, contents + offset + 6);
+ bfd_put_16 (output_bfd, 0x0009, contents + offset + 8);
+ bfd_put_16 (output_bfd, 0x0009, contents + offset + 10);
+
+ bfd_put_32 (output_bfd, sh_elf_got_offset (htab) + off,
+ contents + rel->r_offset);
+
+ continue;
+ }
+
+ addend = rel->r_addend;
+
+ goto final_link_relocate;
+
+ case R_SH_TLS_LD_32:
+ BFD_ASSERT (htab);
+ check_segment[0] = check_segment[1] = -1;
+ if (! info->shared)
+ {
+ bfd_vma offset;
+ unsigned short insn;
+
+ /* LD->LE transition:
+ mov.l 1f,r4; mova 2f,r0; mov.l 2f,r1; add r0,r1;
+ jsr @r1; add r12,r4; bra 3f; nop; .align 2;
+ 1: .long x$TLSLD; 2: .long __tls_get_addr@PLT; 3:
+ We change it into:
+ stc gbr,r0; nop; nop; nop;
+ nop; nop; bra 3f; ...; 3:. */
+
+ offset = rel->r_offset;
+ BFD_ASSERT (offset >= 16);
+ /* Size of LD instructions is 16 or 18. */
+ offset -= 16;
+ insn = bfd_get_16 (input_bfd, contents + offset + 0);
+ if ((insn & 0xff00) == 0xc700)
+ {
+ BFD_ASSERT (offset >= 2);
+ offset -= 2;
+ insn = bfd_get_16 (input_bfd, contents + offset + 0);
+ }
+
+ BFD_ASSERT ((insn & 0xff00) == 0xd400);
+ insn = bfd_get_16 (input_bfd, contents + offset + 2);
+ BFD_ASSERT ((insn & 0xff00) == 0xc700);
+ insn = bfd_get_16 (input_bfd, contents + offset + 4);
+ BFD_ASSERT ((insn & 0xff00) == 0xd100);
+ insn = bfd_get_16 (input_bfd, contents + offset + 6);
+ BFD_ASSERT (insn == 0x310c);
+ insn = bfd_get_16 (input_bfd, contents + offset + 8);
+ BFD_ASSERT (insn == 0x410b);
+ insn = bfd_get_16 (input_bfd, contents + offset + 10);
+ BFD_ASSERT (insn == 0x34cc);
+
+ bfd_put_16 (output_bfd, 0x0012, contents + offset + 0);
+ bfd_put_16 (output_bfd, 0x0009, contents + offset + 2);
+ bfd_put_16 (output_bfd, 0x0009, contents + offset + 4);
+ bfd_put_16 (output_bfd, 0x0009, contents + offset + 6);
+ bfd_put_16 (output_bfd, 0x0009, contents + offset + 8);
+ bfd_put_16 (output_bfd, 0x0009, contents + offset + 10);
+
+ continue;
+ }
+
+ if (sgot == NULL || sgotplt == NULL)
+ abort ();
+
+ off = htab->tls_ldm_got.offset;
+ if (off & 1)
+ off &= ~1;
+ else
+ {
+ Elf_Internal_Rela outrel;
+ bfd_byte *loc;
+
+ srelgot = htab->srelgot;
+ if (srelgot == NULL)
+ abort ();
+
+ outrel.r_offset = (sgot->output_section->vma
+ + sgot->output_offset + off);
+ outrel.r_addend = 0;
+ outrel.r_info = ELF32_R_INFO (0, R_SH_TLS_DTPMOD32);
+ loc = srelgot->contents;
+ loc += srelgot->reloc_count++ * sizeof (Elf32_External_Rela);
+ bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
+ htab->tls_ldm_got.offset |= 1;
+ }
+
+ relocation = sh_elf_got_offset (htab) + off;
+ addend = rel->r_addend;
+
+ goto final_link_relocate;
+
+ case R_SH_TLS_LDO_32:
+ check_segment[0] = check_segment[1] = -1;
+ if (! info->shared)
+ relocation = tpoff (info, relocation);
+ else
+ relocation -= dtpoff_base (info);
+
+ addend = rel->r_addend;
+ goto final_link_relocate;
+
+ case R_SH_TLS_LE_32:
+ {
+ int indx;
+ Elf_Internal_Rela outrel;
+ bfd_byte *loc;
+
+ check_segment[0] = check_segment[1] = -1;
+
+ if (! info->shared || info->pie)
+ {
+ relocation = tpoff (info, relocation);
+ addend = rel->r_addend;
+ goto final_link_relocate;
+ }
+
+ if (sreloc == NULL)
+ {
+ sreloc = _bfd_elf_get_dynamic_reloc_section
+ (input_bfd, input_section, /*rela?*/ TRUE);
+ if (sreloc == NULL)
+ return FALSE;
+ }
+
+ if (h == NULL || h->dynindx == -1)
+ indx = 0;
+ else
+ indx = h->dynindx;
+
+ outrel.r_offset = (input_section->output_section->vma
+ + input_section->output_offset
+ + rel->r_offset);
+ outrel.r_info = ELF32_R_INFO (indx, R_SH_TLS_TPOFF32);
+ if (indx == 0)
+ outrel.r_addend = relocation - dtpoff_base (info);
+ else
+ outrel.r_addend = 0;
+
+ loc = sreloc->contents;
+ loc += sreloc->reloc_count++ * sizeof (Elf32_External_Rela);
+ bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
+ continue;
+ }
+ }
+
+ relocation_done:
+ if (fdpic_p && check_segment[0] != (unsigned) -1
+ && check_segment[0] != check_segment[1])
+ {
+ /* We don't want duplicate errors for undefined symbols. */
+ if (!h || h->root.type != bfd_link_hash_undefined)
+ {
+ if (info->shared)
+ {
+ info->callbacks->einfo
+ (_("%X%C: relocation to \"%s\" references a different segment\n"),
+ input_bfd, input_section, rel->r_offset, symname);
+ return FALSE;
+ }
+ else
+ info->callbacks->einfo
+ (_("%C: warning: relocation to \"%s\" references a different segment\n"),
+ input_bfd, input_section, rel->r_offset, symname);
+ }
+
+ elf_elfheader (output_bfd)->e_flags &= ~EF_SH_PIC;
+ }
+
+ if (r != bfd_reloc_ok)
+ {
+ switch (r)
+ {
+ default:
+ case bfd_reloc_outofrange:
+ abort ();
+ case bfd_reloc_overflow:
+ {
+ const char *name;
+
+ if (h != NULL)
+ name = NULL;
+ 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, (h ? &h->root : NULL), 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 (bfd *output_bfd,
+ struct bfd_link_info *link_info,
+ struct bfd_link_order *link_order,
+ bfd_byte *data,
+ bfd_boolean relocatable,
+ 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;
+ Elf_Internal_Sym *isymbuf = NULL;
+
+ /* We only need to handle the case of relaxing, or of having a
+ particular set of section contents, specially. */
+ if (relocatable
+ || elf_section_data (input_section)->this_hdr.contents == NULL)
+ return bfd_generic_get_relocated_section_contents (output_bfd, link_info,
+ link_order, data,
+ relocatable,
+ symbols);
+
+ symtab_hdr = &elf_symtab_hdr (input_bfd);
+
+ memcpy (data, elf_section_data (input_section)->this_hdr.contents,
+ (size_t) input_section->size);
+
+ if ((input_section->flags & SEC_RELOC) != 0
+ && input_section->reloc_count > 0)
+ {
+ asection **secpp;
+ Elf_Internal_Sym *isym, *isymend;
+ bfd_size_type amt;
+
+ internal_relocs = (_bfd_elf_link_read_relocs
+ (input_bfd, input_section, NULL,
+ (Elf_Internal_Rela *) NULL, FALSE));
+ if (internal_relocs == NULL)
+ goto error_return;
+
+ if (symtab_hdr->sh_info != 0)
+ {
+ isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
+ if (isymbuf == NULL)
+ isymbuf = bfd_elf_get_elf_syms (input_bfd, symtab_hdr,
+ symtab_hdr->sh_info, 0,
+ NULL, NULL, NULL);
+ if (isymbuf == NULL)
+ goto error_return;
+ }
+
+ amt = symtab_hdr->sh_info;
+ amt *= sizeof (asection *);
+ sections = (asection **) bfd_malloc (amt);
+ if (sections == NULL && amt != 0)
+ goto error_return;
+
+ isymend = isymbuf + symtab_hdr->sh_info;
+ for (isym = isymbuf, secpp = sections; isym < isymend; ++isym, ++secpp)
+ {
+ asection *isec;
+
+ if (isym->st_shndx == SHN_UNDEF)
+ isec = bfd_und_section_ptr;
+ 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
+ isec = bfd_section_from_elf_index (input_bfd, isym->st_shndx);
+
+ *secpp = isec;
+ }
+
+ if (! sh_elf_relocate_section (output_bfd, link_info, input_bfd,
+ input_section, data, internal_relocs,
+ isymbuf, sections))
+ goto error_return;
+
+ if (sections != NULL)
+ free (sections);
+ if (isymbuf != NULL
+ && symtab_hdr->contents != (unsigned char *) isymbuf)
+ free (isymbuf);
+ if (elf_section_data (input_section)->relocs != internal_relocs)
+ free (internal_relocs);
+ }
+
+ return data;
+
+ error_return:
+ if (sections != NULL)
+ free (sections);
+ if (isymbuf != NULL
+ && symtab_hdr->contents != (unsigned char *) isymbuf)
+ free (isymbuf);
+ if (internal_relocs != NULL
+ && elf_section_data (input_section)->relocs != internal_relocs)
+ free (internal_relocs);
+ return NULL;
+}
+
+/* Return the base VMA address which should be subtracted from real addresses
+ when resolving @dtpoff relocation.
+ This is PT_TLS segment p_vaddr. */
+
+static bfd_vma
+dtpoff_base (struct bfd_link_info *info)
+{
+ /* If tls_sec is NULL, we should have signalled an error already. */
+ if (elf_hash_table (info)->tls_sec == NULL)
+ return 0;
+ return elf_hash_table (info)->tls_sec->vma;
+}
+
+/* Return the relocation value for R_SH_TLS_TPOFF32.. */
+
+static bfd_vma
+tpoff (struct bfd_link_info *info, bfd_vma address)
+{
+ /* If tls_sec is NULL, we should have signalled an error already. */
+ if (elf_hash_table (info)->tls_sec == NULL)
+ return 0;
+ /* SH TLS ABI is variant I and static TLS block start just after tcbhead
+ structure which has 2 pointer fields. */
+ return (address - elf_hash_table (info)->tls_sec->vma
+ + align_power ((bfd_vma) 8,
+ elf_hash_table (info)->tls_sec->alignment_power));
+}
+
+static asection *
+sh_elf_gc_mark_hook (asection *sec,
+ 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:
+ return NULL;
+ }
+
+ return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
+}
+
+/* Update the got entry reference counts for the section being removed. */
+
+static bfd_boolean
+sh_elf_gc_sweep_hook (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;
+ union gotref *local_funcdesc;
+ const Elf_Internal_Rela *rel, *relend;
+
+ if (info->relocatable)
+ return TRUE;
+
+ elf_section_data (sec)->local_dynrel = NULL;
+
+ symtab_hdr = &elf_symtab_hdr (abfd);
+ sym_hashes = elf_sym_hashes (abfd);
+ local_got_refcounts = elf_local_got_refcounts (abfd);
+ local_funcdesc = sh_elf_local_funcdesc (abfd);
+
+ relend = relocs + sec->reloc_count;
+ for (rel = relocs; rel < relend; rel++)
+ {
+ unsigned long r_symndx;
+ unsigned int r_type;
+ struct elf_link_hash_entry *h = NULL;
+#ifdef INCLUDE_SHMEDIA
+ int seen_stt_datalabel = 0;
+#endif
+
+ r_symndx = ELF32_R_SYM (rel->r_info);
+ if (r_symndx >= symtab_hdr->sh_info)
+ {
+ struct elf_sh_link_hash_entry *eh;
+ struct elf_sh_dyn_relocs **pp;
+ struct elf_sh_dyn_relocs *p;
+
+ h = sym_hashes[r_symndx - symtab_hdr->sh_info];
+ while (h->root.type == bfd_link_hash_indirect
+ || h->root.type == bfd_link_hash_warning)
+ {
+#ifdef INCLUDE_SHMEDIA
+ seen_stt_datalabel |= h->type == STT_DATALABEL;
+#endif
+ h = (struct elf_link_hash_entry *) h->root.u.i.link;
+ }
+ eh = (struct elf_sh_link_hash_entry *) h;
+ for (pp = &eh->dyn_relocs; (p = *pp) != NULL; pp = &p->next)
+ if (p->sec == sec)
+ {
+ /* Everything must go for SEC. */
+ *pp = p->next;
+ break;
+ }
+ }
+
+ r_type = ELF32_R_TYPE (rel->r_info);
+ switch (sh_elf_optimized_tls_reloc (info, r_type, h != NULL))
+ {
+ case R_SH_TLS_LD_32:
+ if (sh_elf_hash_table (info)->tls_ldm_got.refcount > 0)
+ sh_elf_hash_table (info)->tls_ldm_got.refcount -= 1;
+ break;
+
+ case R_SH_GOT32:
+ case R_SH_GOT20:
+ case R_SH_GOTOFF:
+ case R_SH_GOTOFF20:
+ case R_SH_GOTPC:
+#ifdef INCLUDE_SHMEDIA
+ case R_SH_GOT_LOW16:
+ case R_SH_GOT_MEDLOW16:
+ case R_SH_GOT_MEDHI16:
+ case R_SH_GOT_HI16:
+ case R_SH_GOT10BY4:
+ case R_SH_GOT10BY8:
+ case R_SH_GOTOFF_LOW16:
+ case R_SH_GOTOFF_MEDLOW16:
+ case R_SH_GOTOFF_MEDHI16:
+ case R_SH_GOTOFF_HI16:
+ case R_SH_GOTPC_LOW16:
+ case R_SH_GOTPC_MEDLOW16:
+ case R_SH_GOTPC_MEDHI16:
+ case R_SH_GOTPC_HI16:
+#endif
+ case R_SH_TLS_GD_32:
+ case R_SH_TLS_IE_32:
+ case R_SH_GOTFUNCDESC:
+ case R_SH_GOTFUNCDESC20:
+ if (h != NULL)
+ {
+#ifdef INCLUDE_SHMEDIA
+ if (seen_stt_datalabel)
+ {
+ struct elf_sh_link_hash_entry *eh;
+ eh = (struct elf_sh_link_hash_entry *) h;
+ if (eh->datalabel_got.refcount > 0)
+ eh->datalabel_got.refcount -= 1;
+ }
+ else
+#endif
+ if (h->got.refcount > 0)
+ h->got.refcount -= 1;
+ }
+ else if (local_got_refcounts != NULL)
+ {
+#ifdef INCLUDE_SHMEDIA
+ if (rel->r_addend & 1)
+ {
+ if (local_got_refcounts[symtab_hdr->sh_info + r_symndx] > 0)
+ local_got_refcounts[symtab_hdr->sh_info + r_symndx] -= 1;
+ }
+ else
+#endif
+ if (local_got_refcounts[r_symndx] > 0)
+ local_got_refcounts[r_symndx] -= 1;
+ }
+ break;
+
+ case R_SH_FUNCDESC:
+ if (h != NULL)
+ sh_elf_hash_entry (h)->abs_funcdesc_refcount -= 1;
+ else if (sh_elf_hash_table (info)->fdpic_p && !info->shared)
+ sh_elf_hash_table (info)->srofixup->size -= 4;
+
+ /* Fall through. */
+
+ case R_SH_GOTOFFFUNCDESC:
+ case R_SH_GOTOFFFUNCDESC20:
+ if (h != NULL)
+ sh_elf_hash_entry (h)->funcdesc.refcount -= 1;
+ else
+ local_funcdesc[r_symndx].refcount -= 1;
+ break;
+
+ case R_SH_DIR32:
+ if (sh_elf_hash_table (info)->fdpic_p && !info->shared
+ && (sec->flags & SEC_ALLOC) != 0)
+ sh_elf_hash_table (info)->srofixup->size -= 4;
+ /* Fall thru */
+
+ case R_SH_REL32:
+ if (info->shared)
+ break;
+ /* Fall thru */
+
+ case R_SH_PLT32:
+#ifdef INCLUDE_SHMEDIA
+ case R_SH_PLT_LOW16:
+ case R_SH_PLT_MEDLOW16:
+ case R_SH_PLT_MEDHI16:
+ case R_SH_PLT_HI16:
+#endif
+ if (h != NULL)
+ {
+ if (h->plt.refcount > 0)
+ h->plt.refcount -= 1;
+ }
+ break;
+
+ case R_SH_GOTPLT32:
+#ifdef INCLUDE_SHMEDIA
+ case R_SH_GOTPLT_LOW16:
+ case R_SH_GOTPLT_MEDLOW16:
+ case R_SH_GOTPLT_MEDHI16:
+ case R_SH_GOTPLT_HI16:
+ case R_SH_GOTPLT10BY4:
+ case R_SH_GOTPLT10BY8:
+#endif
+ if (h != NULL)
+ {
+ struct elf_sh_link_hash_entry *eh;
+ eh = (struct elf_sh_link_hash_entry *) h;
+ if (eh->gotplt_refcount > 0)
+ {
+ eh->gotplt_refcount -= 1;
+ if (h->plt.refcount > 0)
+ h->plt.refcount -= 1;
+ }
+#ifdef INCLUDE_SHMEDIA
+ else if (seen_stt_datalabel)
+ {
+ if (eh->datalabel_got.refcount > 0)
+ eh->datalabel_got.refcount -= 1;
+ }
+#endif
+ else if (h->got.refcount > 0)
+ h->got.refcount -= 1;
+ }
+ else if (local_got_refcounts != NULL)
+ {
+#ifdef INCLUDE_SHMEDIA
+ if (rel->r_addend & 1)
+ {
+ if (local_got_refcounts[symtab_hdr->sh_info + r_symndx] > 0)
+ local_got_refcounts[symtab_hdr->sh_info + r_symndx] -= 1;
+ }
+ else
+#endif
+ if (local_got_refcounts[r_symndx] > 0)
+ local_got_refcounts[r_symndx] -= 1;
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ return TRUE;
+}
+
+/* Copy the extra info we tack onto an elf_link_hash_entry. */
+
+static void
+sh_elf_copy_indirect_symbol (struct bfd_link_info *info,
+ struct elf_link_hash_entry *dir,
+ struct elf_link_hash_entry *ind)
+{
+ struct elf_sh_link_hash_entry *edir, *eind;
+
+ edir = (struct elf_sh_link_hash_entry *) dir;
+ eind = (struct elf_sh_link_hash_entry *) ind;
+
+ if (eind->dyn_relocs != NULL)
+ {
+ if (edir->dyn_relocs != NULL)
+ {
+ struct elf_sh_dyn_relocs **pp;
+ struct elf_sh_dyn_relocs *p;
+
+ /* Add reloc counts against the indirect sym to the direct sym
+ list. Merge any entries against the same section. */
+ for (pp = &eind->dyn_relocs; (p = *pp) != NULL; )
+ {
+ struct elf_sh_dyn_relocs *q;
+
+ for (q = edir->dyn_relocs; q != NULL; q = q->next)
+ if (q->sec == p->sec)
+ {
+ q->pc_count += p->pc_count;
+ q->count += p->count;
+ *pp = p->next;
+ break;
+ }
+ if (q == NULL)
+ pp = &p->next;
+ }
+ *pp = edir->dyn_relocs;
+ }
+
+ edir->dyn_relocs = eind->dyn_relocs;
+ eind->dyn_relocs = NULL;
+ }
+ edir->gotplt_refcount = eind->gotplt_refcount;
+ eind->gotplt_refcount = 0;
+#ifdef INCLUDE_SHMEDIA
+ edir->datalabel_got.refcount += eind->datalabel_got.refcount;
+ eind->datalabel_got.refcount = 0;
+#endif
+ edir->funcdesc.refcount += eind->funcdesc.refcount;
+ eind->funcdesc.refcount = 0;
+ edir->abs_funcdesc_refcount += eind->abs_funcdesc_refcount;
+ eind->abs_funcdesc_refcount = 0;
+
+ if (ind->root.type == bfd_link_hash_indirect
+ && dir->got.refcount <= 0)
+ {
+ edir->got_type = eind->got_type;
+ eind->got_type = GOT_UNKNOWN;
+ }
+
+ if (ind->root.type != bfd_link_hash_indirect
+ && dir->dynamic_adjusted)
+ {
+ /* If called to transfer flags for a weakdef during processing
+ of elf_adjust_dynamic_symbol, don't copy non_got_ref.
+ We clear it ourselves for ELIMINATE_COPY_RELOCS. */
+ dir->ref_dynamic |= ind->ref_dynamic;
+ dir->ref_regular |= ind->ref_regular;
+ dir->ref_regular_nonweak |= ind->ref_regular_nonweak;
+ dir->needs_plt |= ind->needs_plt;
+ }
+ else
+ _bfd_elf_link_hash_copy_indirect (info, dir, ind);
+}
+
+static int
+sh_elf_optimized_tls_reloc (struct bfd_link_info *info, int r_type,
+ int is_local)
+{
+ if (info->shared)
+ return r_type;
+
+ switch (r_type)
+ {
+ case R_SH_TLS_GD_32:
+ case R_SH_TLS_IE_32:
+ if (is_local)
+ return R_SH_TLS_LE_32;
+ return R_SH_TLS_IE_32;
+ case R_SH_TLS_LD_32:
+ return R_SH_TLS_LE_32;
+ }
+
+ return 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 bfd_boolean
+sh_elf_check_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_sh_link_hash_table *htab;
+ const Elf_Internal_Rela *rel;
+ const Elf_Internal_Rela *rel_end;
+ asection *sreloc;
+ unsigned int r_type;
+ enum got_type got_type, old_got_type;
+
+ sreloc = NULL;
+
+ if (info->relocatable)
+ return TRUE;
+
+ BFD_ASSERT (is_sh_elf (abfd));
+
+ symtab_hdr = &elf_symtab_hdr (abfd);
+ sym_hashes = elf_sym_hashes (abfd);
+
+ htab = sh_elf_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ rel_end = relocs + sec->reloc_count;
+ for (rel = relocs; rel < rel_end; rel++)
+ {
+ struct elf_link_hash_entry *h;
+ unsigned long r_symndx;
+#ifdef INCLUDE_SHMEDIA
+ int seen_stt_datalabel = 0;
+#endif
+
+ r_symndx = ELF32_R_SYM (rel->r_info);
+ r_type = ELF32_R_TYPE (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.type == bfd_link_hash_indirect
+ || h->root.type == bfd_link_hash_warning)
+ {
+#ifdef INCLUDE_SHMEDIA
+ seen_stt_datalabel |= h->type == STT_DATALABEL;
+#endif
+ h = (struct elf_link_hash_entry *) h->root.u.i.link;
+ }
+
+ /* PR15323, ref flags aren't set for references in the same
+ object. */
+ h->root.non_ir_ref = 1;
+ }
+
+ r_type = sh_elf_optimized_tls_reloc (info, r_type, h == NULL);
+ if (! info->shared
+ && r_type == R_SH_TLS_IE_32
+ && h != NULL
+ && h->root.type != bfd_link_hash_undefined
+ && h->root.type != bfd_link_hash_undefweak
+ && (h->dynindx == -1
+ || h->def_regular))
+ r_type = R_SH_TLS_LE_32;
+
+ if (htab->fdpic_p)
+ switch (r_type)
+ {
+ case R_SH_GOTOFFFUNCDESC:
+ case R_SH_GOTOFFFUNCDESC20:
+ case R_SH_FUNCDESC:
+ case R_SH_GOTFUNCDESC:
+ case R_SH_GOTFUNCDESC20:
+ if (h != NULL)
+ {
+ if (h->dynindx == -1)
+ switch (ELF_ST_VISIBILITY (h->other))
+ {
+ case STV_INTERNAL:
+ case STV_HIDDEN:
+ break;
+ default:
+ bfd_elf_link_record_dynamic_symbol (info, h);
+ break;
+ }
+ }
+ break;
+ }
+
+ /* Some relocs require a global offset table. */
+ if (htab->sgot == NULL)
+ {
+ switch (r_type)
+ {
+ case R_SH_DIR32:
+ /* This may require an rofixup. */
+ if (!htab->fdpic_p)
+ break;
+ case R_SH_GOTPLT32:
+ case R_SH_GOT32:
+ case R_SH_GOT20:
+ case R_SH_GOTOFF:
+ case R_SH_GOTOFF20:
+ case R_SH_FUNCDESC:
+ case R_SH_GOTFUNCDESC:
+ case R_SH_GOTFUNCDESC20:
+ case R_SH_GOTOFFFUNCDESC:
+ case R_SH_GOTOFFFUNCDESC20:
+ case R_SH_GOTPC:
+#ifdef INCLUDE_SHMEDIA
+ case R_SH_GOTPLT_LOW16:
+ case R_SH_GOTPLT_MEDLOW16:
+ case R_SH_GOTPLT_MEDHI16:
+ case R_SH_GOTPLT_HI16:
+ case R_SH_GOTPLT10BY4:
+ case R_SH_GOTPLT10BY8:
+ case R_SH_GOT_LOW16:
+ case R_SH_GOT_MEDLOW16:
+ case R_SH_GOT_MEDHI16:
+ case R_SH_GOT_HI16:
+ case R_SH_GOT10BY4:
+ case R_SH_GOT10BY8:
+ case R_SH_GOTOFF_LOW16:
+ case R_SH_GOTOFF_MEDLOW16:
+ case R_SH_GOTOFF_MEDHI16:
+ case R_SH_GOTOFF_HI16:
+ case R_SH_GOTPC_LOW16:
+ case R_SH_GOTPC_MEDLOW16:
+ case R_SH_GOTPC_MEDHI16:
+ case R_SH_GOTPC_HI16:
+#endif
+ case R_SH_TLS_GD_32:
+ case R_SH_TLS_LD_32:
+ case R_SH_TLS_IE_32:
+ if (htab->root.dynobj == NULL)
+ htab->root.dynobj = abfd;
+ if (!create_got_section (htab->root.dynobj, info))
+ return FALSE;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ switch (r_type)
+ {
+ /* This relocation describes the C++ object vtable hierarchy.
+ Reconstruct it for later use during GC. */
+ case R_SH_GNU_VTINHERIT:
+ if (!bfd_elf_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:
+ BFD_ASSERT (h != NULL);
+ if (h != NULL
+ && !bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
+ return FALSE;
+ break;
+
+ case R_SH_TLS_IE_32:
+ if (info->shared)
+ info->flags |= DF_STATIC_TLS;
+
+ /* FALLTHROUGH */
+ force_got:
+ case R_SH_TLS_GD_32:
+ case R_SH_GOT32:
+ case R_SH_GOT20:
+#ifdef INCLUDE_SHMEDIA
+ case R_SH_GOT_LOW16:
+ case R_SH_GOT_MEDLOW16:
+ case R_SH_GOT_MEDHI16:
+ case R_SH_GOT_HI16:
+ case R_SH_GOT10BY4:
+ case R_SH_GOT10BY8:
+#endif
+ case R_SH_GOTFUNCDESC:
+ case R_SH_GOTFUNCDESC20:
+ switch (r_type)
+ {
+ default:
+ got_type = GOT_NORMAL;
+ break;
+ case R_SH_TLS_GD_32:
+ got_type = GOT_TLS_GD;
+ break;
+ case R_SH_TLS_IE_32:
+ got_type = GOT_TLS_IE;
+ break;
+ case R_SH_GOTFUNCDESC:
+ case R_SH_GOTFUNCDESC20:
+ got_type = GOT_FUNCDESC;
+ break;
+ }
+
+ if (h != NULL)
+ {
+#ifdef INCLUDE_SHMEDIA
+ if (seen_stt_datalabel)
+ {
+ struct elf_sh_link_hash_entry *eh
+ = (struct elf_sh_link_hash_entry *) h;
+
+ eh->datalabel_got.refcount += 1;
+ }
+ else
+#endif
+ h->got.refcount += 1;
+ old_got_type = sh_elf_hash_entry (h)->got_type;
+ }
+ else
+ {
+ bfd_signed_vma *local_got_refcounts;
+
+ /* This is a global offset table entry for a local
+ symbol. */
+ local_got_refcounts = elf_local_got_refcounts (abfd);
+ if (local_got_refcounts == NULL)
+ {
+ bfd_size_type size;
+
+ size = symtab_hdr->sh_info;
+ size *= sizeof (bfd_signed_vma);
+#ifdef INCLUDE_SHMEDIA
+ /* Reserve space for both the datalabel and
+ codelabel local GOT offsets. */
+ size *= 2;
+#endif
+ size += symtab_hdr->sh_info;
+ local_got_refcounts = ((bfd_signed_vma *)
+ bfd_zalloc (abfd, size));
+ if (local_got_refcounts == NULL)
+ return FALSE;
+ elf_local_got_refcounts (abfd) = local_got_refcounts;
+#ifdef INCLUDE_SHMEDIA
+ /* Take care of both the datalabel and codelabel local
+ GOT offsets. */
+ sh_elf_local_got_type (abfd)
+ = (char *) (local_got_refcounts + 2 * symtab_hdr->sh_info);
+#else
+ sh_elf_local_got_type (abfd)
+ = (char *) (local_got_refcounts + symtab_hdr->sh_info);
+#endif
+ }
+#ifdef INCLUDE_SHMEDIA
+ if (rel->r_addend & 1)
+ local_got_refcounts[symtab_hdr->sh_info + r_symndx] += 1;
+ else
+#endif
+ local_got_refcounts[r_symndx] += 1;
+ old_got_type = sh_elf_local_got_type (abfd) [r_symndx];
+ }
+
+ /* If a TLS symbol is accessed using IE at least once,
+ there is no point to use dynamic model for it. */
+ if (old_got_type != got_type && old_got_type != GOT_UNKNOWN
+ && (old_got_type != GOT_TLS_GD || got_type != GOT_TLS_IE))
+ {
+ if (old_got_type == GOT_TLS_IE && got_type == GOT_TLS_GD)
+ got_type = GOT_TLS_IE;
+ else
+ {
+ if ((old_got_type == GOT_FUNCDESC || got_type == GOT_FUNCDESC)
+ && (old_got_type == GOT_NORMAL || got_type == GOT_NORMAL))
+ (*_bfd_error_handler)
+ (_("%B: `%s' accessed both as normal and FDPIC symbol"),
+ abfd, h->root.root.string);
+ else if (old_got_type == GOT_FUNCDESC
+ || got_type == GOT_FUNCDESC)
+ (*_bfd_error_handler)
+ (_("%B: `%s' accessed both as FDPIC and thread local symbol"),
+ abfd, h->root.root.string);
+ else
+ (*_bfd_error_handler)
+ (_("%B: `%s' accessed both as normal and thread local symbol"),
+ abfd, h->root.root.string);
+ return FALSE;
+ }
+ }
+
+ if (old_got_type != got_type)
+ {
+ if (h != NULL)
+ sh_elf_hash_entry (h)->got_type = got_type;
+ else
+ sh_elf_local_got_type (abfd) [r_symndx] = got_type;
+ }
+
+ break;
+
+ case R_SH_TLS_LD_32:
+ sh_elf_hash_table(info)->tls_ldm_got.refcount += 1;
+ break;
+
+ case R_SH_FUNCDESC:
+ case R_SH_GOTOFFFUNCDESC:
+ case R_SH_GOTOFFFUNCDESC20:
+ if (rel->r_addend)
+ {
+ (*_bfd_error_handler)
+ (_("%B: Function descriptor relocation with non-zero addend"),
+ abfd);
+ return FALSE;
+ }
+
+ if (h == NULL)
+ {
+ union gotref *local_funcdesc;
+
+ /* We need a function descriptor for a local symbol. */
+ local_funcdesc = sh_elf_local_funcdesc (abfd);
+ if (local_funcdesc == NULL)
+ {
+ bfd_size_type size;
+
+ size = symtab_hdr->sh_info * sizeof (union gotref);
+#ifdef INCLUDE_SHMEDIA
+ /* Count datalabel local GOT. */
+ size *= 2;
+#endif
+ local_funcdesc = (union gotref *) bfd_zalloc (abfd, size);
+ if (local_funcdesc == NULL)
+ return FALSE;
+ sh_elf_local_funcdesc (abfd) = local_funcdesc;
+ }
+ local_funcdesc[r_symndx].refcount += 1;
+
+ if (r_type == R_SH_FUNCDESC)
+ {
+ if (!info->shared)
+ htab->srofixup->size += 4;
+ else
+ htab->srelgot->size += sizeof (Elf32_External_Rela);
+ }
+ }
+ else
+ {
+ sh_elf_hash_entry (h)->funcdesc.refcount++;
+ if (r_type == R_SH_FUNCDESC)
+ sh_elf_hash_entry (h)->abs_funcdesc_refcount++;
+
+ /* If there is a function descriptor reference, then
+ there should not be any non-FDPIC references. */
+ old_got_type = sh_elf_hash_entry (h)->got_type;
+ if (old_got_type != GOT_FUNCDESC && old_got_type != GOT_UNKNOWN)
+ {
+ if (old_got_type == GOT_NORMAL)
+ (*_bfd_error_handler)
+ (_("%B: `%s' accessed both as normal and FDPIC symbol"),
+ abfd, h->root.root.string);
+ else
+ (*_bfd_error_handler)
+ (_("%B: `%s' accessed both as FDPIC and thread local symbol"),
+ abfd, h->root.root.string);
+ }
+ }
+ break;
+
+ case R_SH_GOTPLT32:
+#ifdef INCLUDE_SHMEDIA
+ case R_SH_GOTPLT_LOW16:
+ case R_SH_GOTPLT_MEDLOW16:
+ case R_SH_GOTPLT_MEDHI16:
+ case R_SH_GOTPLT_HI16:
+ case R_SH_GOTPLT10BY4:
+ case R_SH_GOTPLT10BY8:
+#endif
+ /* If this is a local symbol, we resolve it directly without
+ creating a procedure linkage table entry. */
+
+ if (h == NULL
+ || h->forced_local
+ || ! info->shared
+ || info->symbolic
+ || h->dynindx == -1)
+ goto force_got;
+
+ h->needs_plt = 1;
+ h->plt.refcount += 1;
+ ((struct elf_sh_link_hash_entry *) h)->gotplt_refcount += 1;
+
+ break;
+
+ case R_SH_PLT32:
+#ifdef INCLUDE_SHMEDIA
+ case R_SH_PLT_LOW16:
+ case R_SH_PLT_MEDLOW16:
+ case R_SH_PLT_MEDHI16:
+ case R_SH_PLT_HI16:
+#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 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;
+
+ if (h->forced_local)
+ break;
+
+ h->needs_plt = 1;
+ h->plt.refcount += 1;
+ break;
+
+ case R_SH_DIR32:
+ case R_SH_REL32:
+#ifdef INCLUDE_SHMEDIA
+ case R_SH_IMM_LOW16_PCREL:
+ case R_SH_IMM_MEDLOW16_PCREL:
+ case R_SH_IMM_MEDHI16_PCREL:
+ case R_SH_IMM_HI16_PCREL:
+#endif
+ if (h != NULL && ! info->shared)
+ {
+ h->non_got_ref = 1;
+ h->plt.refcount += 1;
+ }
+
+ /* 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
+ dyn_relocs field of the hash table entry. A similar
+ situation occurs when creating shared libraries and symbol
+ visibility changes render the symbol local.
+
+ If on the other hand, we are creating an executable, we
+ may need to keep relocations for symbols satisfied by a
+ dynamic library if we manage to avoid copy relocs for the
+ symbol. */
+ if ((info->shared
+ && (sec->flags & SEC_ALLOC) != 0
+ && (r_type != R_SH_REL32
+ || (h != NULL
+ && (! info->symbolic
+ || h->root.type == bfd_link_hash_defweak
+ || !h->def_regular))))
+ || (! info->shared
+ && (sec->flags & SEC_ALLOC) != 0
+ && h != NULL
+ && (h->root.type == bfd_link_hash_defweak
+ || !h->def_regular)))
+ {
+ struct elf_sh_dyn_relocs *p;
+ struct elf_sh_dyn_relocs **head;
+
+ if (htab->root.dynobj == NULL)
+ htab->root.dynobj = abfd;
+
+ /* 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)
+ {
+ sreloc = _bfd_elf_make_dynamic_reloc_section
+ (sec, htab->root.dynobj, 2, abfd, /*rela?*/ TRUE);
+
+ if (sreloc == NULL)
+ return FALSE;
+ }
+
+ /* If this is a global symbol, we count the number of
+ relocations we need for this symbol. */
+ if (h != NULL)
+ head = &((struct elf_sh_link_hash_entry *) h)->dyn_relocs;
+ else
+ {
+ /* Track dynamic relocs needed for local syms too. */
+ asection *s;
+ void *vpp;
+ Elf_Internal_Sym *isym;
+
+ isym = bfd_sym_from_r_symndx (&htab->sym_cache,
+ abfd, r_symndx);
+ if (isym == NULL)
+ return FALSE;
+
+ s = bfd_section_from_elf_index (abfd, isym->st_shndx);
+ if (s == NULL)
+ s = sec;
+
+ vpp = &elf_section_data (s)->local_dynrel;
+ head = (struct elf_sh_dyn_relocs **) vpp;
+ }
+
+ p = *head;
+ if (p == NULL || p->sec != sec)
+ {
+ bfd_size_type amt = sizeof (*p);
+ p = bfd_alloc (htab->root.dynobj, amt);
+ if (p == NULL)
+ return FALSE;
+ p->next = *head;
+ *head = p;
+ p->sec = sec;
+ p->count = 0;
+ p->pc_count = 0;
+ }
+
+ p->count += 1;
+ if (r_type == R_SH_REL32
+#ifdef INCLUDE_SHMEDIA
+ || r_type == R_SH_IMM_LOW16_PCREL
+ || r_type == R_SH_IMM_MEDLOW16_PCREL
+ || r_type == R_SH_IMM_MEDHI16_PCREL
+ || r_type == R_SH_IMM_HI16_PCREL
+#endif
+ )
+ p->pc_count += 1;
+ }
+
+ /* Allocate the fixup regardless of whether we need a relocation.
+ If we end up generating the relocation, we'll unallocate the
+ fixup. */
+ if (htab->fdpic_p && !info->shared
+ && r_type == R_SH_DIR32
+ && (sec->flags & SEC_ALLOC) != 0)
+ htab->srofixup->size += 4;
+ break;
+
+ case R_SH_TLS_LE_32:
+ if (info->shared && !info->pie)
+ {
+ (*_bfd_error_handler)
+ (_("%B: TLS local exec code cannot be linked into shared objects"),
+ abfd);
+ return FALSE;
+ }
+
+ break;
+
+ case R_SH_TLS_LDO_32:
+ /* Nothing to do. */
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ return TRUE;
+}
+
+#ifndef sh_elf_set_mach_from_flags
+static unsigned int sh_ef_bfd_table[] = { EF_SH_BFD_TABLE };
+
+static bfd_boolean
+sh_elf_set_mach_from_flags (bfd *abfd)
+{
+ flagword flags = elf_elfheader (abfd)->e_flags & EF_SH_MACH_MASK;
+
+ if (flags >= sizeof(sh_ef_bfd_table))
+ return FALSE;
+
+ if (sh_ef_bfd_table[flags] == 0)
+ return FALSE;
+
+ bfd_default_set_arch_mach (abfd, bfd_arch_sh, sh_ef_bfd_table[flags]);
+
+ return TRUE;
+}
+
+
+/* Reverse table lookup for sh_ef_bfd_table[].
+ Given a bfd MACH value from archures.c
+ return the equivalent ELF flags from the table.
+ Return -1 if no match is found. */
+
+int
+sh_elf_get_flags_from_mach (unsigned long mach)
+{
+ int i = ARRAY_SIZE (sh_ef_bfd_table) - 1;
+
+ for (; i>0; i--)
+ if (sh_ef_bfd_table[i] == mach)
+ return i;
+
+ /* shouldn't get here */
+ BFD_FAIL();
+
+ return -1;
+}
+#endif /* not sh_elf_set_mach_from_flags */
+
+#ifndef sh_elf_copy_private_data
+/* Copy backend specific data from one object module to another */
+
+static bfd_boolean
+sh_elf_copy_private_data (bfd * ibfd, bfd * obfd)
+{
+ if (! is_sh_elf (ibfd) || ! is_sh_elf (obfd))
+ return TRUE;
+
+ if (! _bfd_elf_copy_private_bfd_data (ibfd, obfd))
+ return FALSE;
+
+ return sh_elf_set_mach_from_flags (obfd);
+}
+#endif /* not sh_elf_copy_private_data */
+
+#ifndef sh_elf_merge_private_data
+
+/* This function returns the ELF architecture number that
+ corresponds to the given arch_sh* flags. */
+
+int
+sh_find_elf_flags (unsigned int arch_set)
+{
+ extern unsigned long sh_get_bfd_mach_from_arch_set (unsigned int);
+ unsigned long bfd_mach = sh_get_bfd_mach_from_arch_set (arch_set);
+
+ return sh_elf_get_flags_from_mach (bfd_mach);
+}
+
+/* This routine initialises the elf flags when required and
+ calls sh_merge_bfd_arch() to check dsp/fpu compatibility. */
+
+static bfd_boolean
+sh_elf_merge_private_data (bfd *ibfd, bfd *obfd)
+{
+ extern bfd_boolean sh_merge_bfd_arch (bfd *, bfd *);
+
+ if (! is_sh_elf (ibfd) || ! is_sh_elf (obfd))
+ return TRUE;
+
+ if (! elf_flags_init (obfd))
+ {
+ /* This happens when ld starts out with a 'blank' output file. */
+ elf_flags_init (obfd) = TRUE;
+ elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags;
+ sh_elf_set_mach_from_flags (obfd);
+ if (elf_elfheader (obfd)->e_flags & EF_SH_FDPIC)
+ elf_elfheader (obfd)->e_flags |= EF_SH_PIC;
+ }
+
+ if (! sh_merge_bfd_arch (ibfd, obfd))
+ {
+ _bfd_error_handler ("%B: uses instructions which are incompatible "
+ "with instructions used in previous modules",
+ ibfd);
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+
+ elf_elfheader (obfd)->e_flags &= ~EF_SH_MACH_MASK;
+ elf_elfheader (obfd)->e_flags |=
+ sh_elf_get_flags_from_mach (bfd_get_mach (obfd));
+
+ if (fdpic_object_p (ibfd) != fdpic_object_p (obfd))
+ {
+ _bfd_error_handler ("%B: attempt to mix FDPIC and non-FDPIC objects",
+ ibfd);
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+#endif /* not sh_elf_merge_private_data */
+
+/* Override the generic function because we need to store sh_elf_obj_tdata
+ as the specific tdata. We set also the machine architecture from flags
+ here. */
+
+static bfd_boolean
+sh_elf_object_p (bfd *abfd)
+{
+ if (! sh_elf_set_mach_from_flags (abfd))
+ return FALSE;
+
+ return (((elf_elfheader (abfd)->e_flags & EF_SH_FDPIC) != 0)
+ == fdpic_object_p (abfd));
+}
+
+/* Finish up dynamic symbol handling. We set the contents of various
+ dynamic sections here. */
+
+static bfd_boolean
+sh_elf_finish_dynamic_symbol (bfd *output_bfd, struct bfd_link_info *info,
+ struct elf_link_hash_entry *h,
+ Elf_Internal_Sym *sym)
+{
+ struct elf_sh_link_hash_table *htab;
+
+ htab = sh_elf_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ if (h->plt.offset != (bfd_vma) -1)
+ {
+ asection *splt;
+ asection *sgotplt;
+ asection *srelplt;
+
+ bfd_vma plt_index;
+ bfd_vma got_offset;
+ Elf_Internal_Rela rel;
+ bfd_byte *loc;
+ const struct elf_sh_plt_info *plt_info;
+
+ /* This symbol has an entry in the procedure linkage table. Set
+ it up. */
+
+ BFD_ASSERT (h->dynindx != -1);
+
+ splt = htab->splt;
+ sgotplt = htab->sgotplt;
+ srelplt = htab->srelplt;
+ BFD_ASSERT (splt != NULL && sgotplt != NULL && srelplt != 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 = get_plt_index (htab->plt_info, h->plt.offset);
+
+ plt_info = htab->plt_info;
+ if (plt_info->short_plt != NULL && plt_index <= MAX_SHORT_PLT)
+ plt_info = plt_info->short_plt;
+
+ /* Get the offset into the .got table of the entry that
+ corresponds to this function. */
+ if (htab->fdpic_p)
+ /* The offset must be relative to the GOT symbol, twelve bytes
+ before the end of .got.plt. Each descriptor is eight
+ bytes. */
+ got_offset = plt_index * 8 + 12 - sgotplt->size;
+ else
+ /* Each .got entry is 4 bytes. The first three are
+ reserved. */
+ got_offset = (plt_index + 3) * 4;
+
+#ifdef GOT_BIAS
+ if (info->shared)
+ got_offset -= GOT_BIAS;
+#endif
+
+ /* Fill in the entry in the procedure linkage table. */
+ memcpy (splt->contents + h->plt.offset,
+ plt_info->symbol_entry,
+ plt_info->symbol_entry_size);
+
+ if (info->shared || htab->fdpic_p)
+ {
+ if (plt_info->symbol_fields.got20)
+ {
+ bfd_reloc_status_type r;
+ r = install_movi20_field (output_bfd, got_offset,
+ splt->owner, splt, splt->contents,
+ h->plt.offset
+ + plt_info->symbol_fields.got_entry);
+ BFD_ASSERT (r == bfd_reloc_ok);
+ }
+ else
+ install_plt_field (output_bfd, FALSE, got_offset,
+ (splt->contents
+ + h->plt.offset
+ + plt_info->symbol_fields.got_entry));
+ }
+ else
+ {
+ BFD_ASSERT (!plt_info->symbol_fields.got20);
+
+ install_plt_field (output_bfd, FALSE,
+ (sgotplt->output_section->vma
+ + sgotplt->output_offset
+ + got_offset),
+ (splt->contents
+ + h->plt.offset
+ + plt_info->symbol_fields.got_entry));
+ if (htab->vxworks_p)
+ {
+ unsigned int reachable_plts, plts_per_4k;
+ int distance;
+
+ /* Divide the PLT into groups. The first group contains
+ REACHABLE_PLTS entries and the other groups contain
+ PLTS_PER_4K entries. Entries in the first group can
+ branch directly to .plt; those in later groups branch
+ to the last element of the previous group. */
+ /* ??? It would be better to create multiple copies of
+ the common resolver stub. */
+ reachable_plts = ((4096
+ - plt_info->plt0_entry_size
+ - (plt_info->symbol_fields.plt + 4))
+ / plt_info->symbol_entry_size) + 1;
+ plts_per_4k = (4096 / plt_info->symbol_entry_size);
+ if (plt_index < reachable_plts)
+ distance = -(h->plt.offset
+ + plt_info->symbol_fields.plt);
+ else
+ distance = -(((plt_index - reachable_plts) % plts_per_4k + 1)
+ * plt_info->symbol_entry_size);
+
+ /* Install the 'bra' with this offset. */
+ bfd_put_16 (output_bfd,
+ 0xa000 | (0x0fff & ((distance - 4) / 2)),
+ (splt->contents
+ + h->plt.offset
+ + plt_info->symbol_fields.plt));
+ }
+ else
+ install_plt_field (output_bfd, TRUE,
+ splt->output_section->vma + splt->output_offset,
+ (splt->contents
+ + h->plt.offset
+ + plt_info->symbol_fields.plt));
+ }
+
+ /* Make got_offset relative to the start of .got.plt. */
+#ifdef GOT_BIAS
+ if (info->shared)
+ got_offset += GOT_BIAS;
+#endif
+ if (htab->fdpic_p)
+ got_offset = plt_index * 8;
+
+ if (plt_info->symbol_fields.reloc_offset != MINUS_ONE)
+ install_plt_field (output_bfd, FALSE,
+ plt_index * sizeof (Elf32_External_Rela),
+ (splt->contents
+ + h->plt.offset
+ + plt_info->symbol_fields.reloc_offset));
+
+ /* Fill in the entry in the global offset table. */
+ bfd_put_32 (output_bfd,
+ (splt->output_section->vma
+ + splt->output_offset
+ + h->plt.offset
+ + plt_info->symbol_resolve_offset),
+ sgotplt->contents + got_offset);
+ if (htab->fdpic_p)
+ bfd_put_32 (output_bfd,
+ sh_elf_osec_to_segment (output_bfd,
+ htab->splt->output_section),
+ sgotplt->contents + got_offset + 4);
+
+ /* Fill in the entry in the .rela.plt section. */
+ rel.r_offset = (sgotplt->output_section->vma
+ + sgotplt->output_offset
+ + got_offset);
+ if (htab->fdpic_p)
+ rel.r_info = ELF32_R_INFO (h->dynindx, R_SH_FUNCDESC_VALUE);
+ else
+ rel.r_info = ELF32_R_INFO (h->dynindx, R_SH_JMP_SLOT);
+ rel.r_addend = 0;
+#ifdef GOT_BIAS
+ rel.r_addend = GOT_BIAS;
+#endif
+ loc = srelplt->contents + plt_index * sizeof (Elf32_External_Rela);
+ bfd_elf32_swap_reloca_out (output_bfd, &rel, loc);
+
+ if (htab->vxworks_p && !info->shared)
+ {
+ /* Create the .rela.plt.unloaded relocations for this PLT entry.
+ Begin by pointing LOC to the first such relocation. */
+ loc = (htab->srelplt2->contents
+ + (plt_index * 2 + 1) * sizeof (Elf32_External_Rela));
+
+ /* Create a .rela.plt.unloaded R_SH_DIR32 relocation
+ for the PLT entry's pointer to the .got.plt entry. */
+ rel.r_offset = (htab->splt->output_section->vma
+ + htab->splt->output_offset
+ + h->plt.offset
+ + plt_info->symbol_fields.got_entry);
+ rel.r_info = ELF32_R_INFO (htab->root.hgot->indx, R_SH_DIR32);
+ rel.r_addend = got_offset;
+ bfd_elf32_swap_reloca_out (output_bfd, &rel, loc);
+ loc += sizeof (Elf32_External_Rela);
+
+ /* Create a .rela.plt.unloaded R_SH_DIR32 relocation for
+ the .got.plt entry, which initially points to .plt. */
+ rel.r_offset = (sgotplt->output_section->vma
+ + sgotplt->output_offset
+ + got_offset);
+ rel.r_info = ELF32_R_INFO (htab->root.hplt->indx, R_SH_DIR32);
+ rel.r_addend = 0;
+ bfd_elf32_swap_reloc_out (output_bfd, &rel, loc);
+ }
+
+ if (!h->def_regular)
+ {
+ /* 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
+ && sh_elf_hash_entry (h)->got_type != GOT_TLS_GD
+ && sh_elf_hash_entry (h)->got_type != GOT_TLS_IE
+ && sh_elf_hash_entry (h)->got_type != GOT_FUNCDESC)
+ {
+ asection *sgot;
+ asection *srelgot;
+ Elf_Internal_Rela rel;
+ bfd_byte *loc;
+
+ /* This symbol has an entry in the global offset table. Set it
+ up. */
+
+ sgot = htab->sgot;
+ srelgot = htab->srelgot;
+ BFD_ASSERT (sgot != NULL && srelgot != NULL);
+
+ rel.r_offset = (sgot->output_section->vma
+ + sgot->output_offset
+ + (h->got.offset &~ (bfd_vma) 1));
+
+ /* If this is a static link, or it is a -Bsymbolic link and the
+ symbol is defined locally or was forced to be local because
+ of a version file, 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
+ && SYMBOL_REFERENCES_LOCAL (info, h))
+ {
+ if (htab->fdpic_p)
+ {
+ asection *sec = h->root.u.def.section;
+ int dynindx
+ = elf_section_data (sec->output_section)->dynindx;
+
+ rel.r_info = ELF32_R_INFO (dynindx, R_SH_DIR32);
+ rel.r_addend = (h->root.u.def.value
+ + h->root.u.def.section->output_offset);
+ }
+ else
+ {
+ rel.r_info = ELF32_R_INFO (0, R_SH_RELATIVE);
+ rel.r_addend = (h->root.u.def.value
+ + h->root.u.def.section->output_section->vma
+ + h->root.u.def.section->output_offset);
+ }
+ }
+ else
+ {
+ bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents + h->got.offset);
+ rel.r_info = ELF32_R_INFO (h->dynindx, R_SH_GLOB_DAT);
+ rel.r_addend = 0;
+ }
+
+ loc = srelgot->contents;
+ loc += srelgot->reloc_count++ * sizeof (Elf32_External_Rela);
+ bfd_elf32_swap_reloca_out (output_bfd, &rel, loc);
+ }
+
+#ifdef INCLUDE_SHMEDIA
+ {
+ struct elf_sh_link_hash_entry *eh;
+
+ eh = (struct elf_sh_link_hash_entry *) h;
+ if (eh->datalabel_got.offset != (bfd_vma) -1)
+ {
+ asection *sgot;
+ asection *srelgot;
+ Elf_Internal_Rela rel;
+ bfd_byte *loc;
+
+ /* This symbol has a datalabel entry in the global offset table.
+ Set it up. */
+
+ sgot = htab->sgot;
+ srelgot = htab->srelgot;
+ BFD_ASSERT (sgot != NULL && srelgot != NULL);
+
+ rel.r_offset = (sgot->output_section->vma
+ + sgot->output_offset
+ + (eh->datalabel_got.offset &~ (bfd_vma) 1));
+
+ /* If this is a static link, or it is a -Bsymbolic link and the
+ symbol is defined locally or was forced to be local because
+ of a version file, 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
+ && SYMBOL_REFERENCES_LOCAL (info, h))
+ {
+ if (htab->fdpic_p)
+ {
+ asection *sec = h->root.u.def.section;
+ int dynindx
+ = elf_section_data (sec->output_section)->dynindx;
+
+ rel.r_info = ELF32_R_INFO (dynindx, R_SH_DIR32);
+ rel.r_addend = (h->root.u.def.value
+ + h->root.u.def.section->output_offset);
+ }
+ else
+ {
+ rel.r_info = ELF32_R_INFO (0, R_SH_RELATIVE);
+ rel.r_addend = (h->root.u.def.value
+ + h->root.u.def.section->output_section->vma
+ + h->root.u.def.section->output_offset);
+ }
+ }
+ else
+ {
+ bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents
+ + eh->datalabel_got.offset);
+ rel.r_info = ELF32_R_INFO (h->dynindx, R_SH_GLOB_DAT);
+ rel.r_addend = 0;
+ }
+
+ loc = srelgot->contents;
+ loc += srelgot->reloc_count++ * sizeof (Elf32_External_Rela);
+ bfd_elf32_swap_reloca_out (output_bfd, &rel, loc);
+ }
+ }
+#endif
+
+ if (h->needs_copy)
+ {
+ asection *s;
+ Elf_Internal_Rela rel;
+ bfd_byte *loc;
+
+ /* 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_linker_section (htab->root.dynobj, ".rela.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_SH_COPY);
+ rel.r_addend = 0;
+ loc = s->contents + s->reloc_count++ * sizeof (Elf32_External_Rela);
+ bfd_elf32_swap_reloca_out (output_bfd, &rel, loc);
+ }
+
+ /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute. On VxWorks,
+ _GLOBAL_OFFSET_TABLE_ is not absolute: it is relative to the
+ ".got" section. */
+ if (h == htab->root.hdynamic
+ || (!htab->vxworks_p && h == htab->root.hgot))
+ sym->st_shndx = SHN_ABS;
+
+ return TRUE;
+}
+
+/* Finish up the dynamic sections. */
+
+static bfd_boolean
+sh_elf_finish_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
+{
+ struct elf_sh_link_hash_table *htab;
+ asection *sgotplt;
+ asection *sdyn;
+
+ htab = sh_elf_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ sgotplt = htab->sgotplt;
+ sdyn = bfd_get_linker_section (htab->root.dynobj, ".dynamic");
+
+ if (htab->root.dynamic_sections_created)
+ {
+ asection *splt;
+ Elf32_External_Dyn *dyncon, *dynconend;
+
+ BFD_ASSERT (sgotplt != NULL && sdyn != NULL);
+
+ dyncon = (Elf32_External_Dyn *) sdyn->contents;
+ dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->size);
+ for (; dyncon < dynconend; dyncon++)
+ {
+ Elf_Internal_Dyn dyn;
+ asection *s;
+#ifdef INCLUDE_SHMEDIA
+ const char *name;
+#endif
+
+ bfd_elf32_swap_dyn_in (htab->root.dynobj, dyncon, &dyn);
+
+ switch (dyn.d_tag)
+ {
+ default:
+ if (htab->vxworks_p
+ && elf_vxworks_finish_dynamic_entry (output_bfd, &dyn))
+ bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
+ break;
+
+#ifdef INCLUDE_SHMEDIA
+ case DT_INIT:
+ name = info->init_function;
+ goto get_sym;
+
+ case DT_FINI:
+ name = info->fini_function;
+ get_sym:
+ if (dyn.d_un.d_val != 0)
+ {
+ struct elf_link_hash_entry *h;
+
+ h = elf_link_hash_lookup (&htab->root, name,
+ FALSE, FALSE, TRUE);
+ if (h != NULL && (h->other & STO_SH5_ISA32))
+ {
+ dyn.d_un.d_val |= 1;
+ bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
+ }
+ }
+ break;
+#endif
+
+ case DT_PLTGOT:
+ BFD_ASSERT (htab->root.hgot != NULL);
+ s = htab->root.hgot->root.u.def.section;
+ dyn.d_un.d_ptr = htab->root.hgot->root.u.def.value
+ + s->output_section->vma + s->output_offset;
+ bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
+ break;
+
+ case DT_JMPREL:
+ s = htab->srelplt->output_section;
+ 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 = htab->srelplt->output_section;
+ BFD_ASSERT (s != NULL);
+ dyn.d_un.d_val = s->size;
+ bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
+ break;
+
+ case DT_RELASZ:
+ /* My reading of the SVR4 ABI indicates that the
+ procedure linkage table relocs (DT_JMPREL) should be
+ included in the overall relocs (DT_RELA). This is
+ what Solaris does. However, UnixWare can not handle
+ that case. 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. */
+ if (htab->srelplt != NULL)
+ {
+ s = htab->srelplt->output_section;
+ dyn.d_un.d_val -= s->size;
+ }
+ bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
+ break;
+ }
+ }
+
+ /* Fill in the first entry in the procedure linkage table. */
+ splt = htab->splt;
+ if (splt && splt->size > 0 && htab->plt_info->plt0_entry)
+ {
+ unsigned int i;
+
+ memcpy (splt->contents,
+ htab->plt_info->plt0_entry,
+ htab->plt_info->plt0_entry_size);
+ for (i = 0; i < ARRAY_SIZE (htab->plt_info->plt0_got_fields); i++)
+ if (htab->plt_info->plt0_got_fields[i] != MINUS_ONE)
+ install_plt_field (output_bfd, FALSE,
+ (sgotplt->output_section->vma
+ + sgotplt->output_offset
+ + (i * 4)),
+ (splt->contents
+ + htab->plt_info->plt0_got_fields[i]));
+
+ if (htab->vxworks_p)
+ {
+ /* Finalize the .rela.plt.unloaded contents. */
+ Elf_Internal_Rela rel;
+ bfd_byte *loc;
+
+ /* Create a .rela.plt.unloaded R_SH_DIR32 relocation for the
+ first PLT entry's pointer to _GLOBAL_OFFSET_TABLE_ + 8. */
+ loc = htab->srelplt2->contents;
+ rel.r_offset = (splt->output_section->vma
+ + splt->output_offset
+ + htab->plt_info->plt0_got_fields[2]);
+ rel.r_info = ELF32_R_INFO (htab->root.hgot->indx, R_SH_DIR32);
+ rel.r_addend = 8;
+ bfd_elf32_swap_reloca_out (output_bfd, &rel, loc);
+ loc += sizeof (Elf32_External_Rela);
+
+ /* Fix up the remaining .rela.plt.unloaded relocations.
+ They may have the wrong symbol index for _G_O_T_ or
+ _P_L_T_ depending on the order in which symbols were
+ output. */
+ while (loc < htab->srelplt2->contents + htab->srelplt2->size)
+ {
+ /* The PLT entry's pointer to the .got.plt slot. */
+ bfd_elf32_swap_reloc_in (output_bfd, loc, &rel);
+ rel.r_info = ELF32_R_INFO (htab->root.hgot->indx,
+ R_SH_DIR32);
+ bfd_elf32_swap_reloc_out (output_bfd, &rel, loc);
+ loc += sizeof (Elf32_External_Rela);
+
+ /* The .got.plt slot's pointer to .plt. */
+ bfd_elf32_swap_reloc_in (output_bfd, loc, &rel);
+ rel.r_info = ELF32_R_INFO (htab->root.hplt->indx,
+ R_SH_DIR32);
+ bfd_elf32_swap_reloc_out (output_bfd, &rel, loc);
+ loc += sizeof (Elf32_External_Rela);
+ }
+ }
+
+ /* 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 (sgotplt && sgotplt->size > 0 && !htab->fdpic_p)
+ {
+ if (sdyn == NULL)
+ bfd_put_32 (output_bfd, (bfd_vma) 0, sgotplt->contents);
+ else
+ bfd_put_32 (output_bfd,
+ sdyn->output_section->vma + sdyn->output_offset,
+ sgotplt->contents);
+ bfd_put_32 (output_bfd, (bfd_vma) 0, sgotplt->contents + 4);
+ bfd_put_32 (output_bfd, (bfd_vma) 0, sgotplt->contents + 8);
+ }
+
+ if (sgotplt && sgotplt->size > 0)
+ elf_section_data (sgotplt->output_section)->this_hdr.sh_entsize = 4;
+
+ /* At the very end of the .rofixup section is a pointer to the GOT. */
+ if (htab->fdpic_p && htab->srofixup != NULL)
+ {
+ struct elf_link_hash_entry *hgot = htab->root.hgot;
+ bfd_vma got_value = hgot->root.u.def.value
+ + hgot->root.u.def.section->output_section->vma
+ + hgot->root.u.def.section->output_offset;
+
+ sh_elf_add_rofixup (output_bfd, htab->srofixup, got_value);
+
+ /* Make sure we allocated and generated the same number of fixups. */
+ BFD_ASSERT (htab->srofixup->reloc_count * 4 == htab->srofixup->size);
+ }
+
+ if (htab->srelfuncdesc)
+ BFD_ASSERT (htab->srelfuncdesc->reloc_count * sizeof (Elf32_External_Rela)
+ == htab->srelfuncdesc->size);
+
+ if (htab->srelgot)
+ BFD_ASSERT (htab->srelgot->reloc_count * sizeof (Elf32_External_Rela)
+ == htab->srelgot->size);
+
+ return TRUE;
+}
+
+static enum elf_reloc_type_class
+sh_elf_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ const asection *rel_sec ATTRIBUTE_UNUSED,
+ const Elf_Internal_Rela *rela)
+{
+ switch ((int) ELF32_R_TYPE (rela->r_info))
+ {
+ case R_SH_RELATIVE:
+ return reloc_class_relative;
+ case R_SH_JMP_SLOT:
+ return reloc_class_plt;
+ case R_SH_COPY:
+ return reloc_class_copy;
+ default:
+ return reloc_class_normal;
+ }
+}
+
+#if !defined SH_TARGET_ALREADY_DEFINED
+/* Support for Linux core dump NOTE sections. */
+
+static bfd_boolean
+elf32_shlin_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
+{
+ int offset;
+ unsigned int size;
+
+ switch (note->descsz)
+ {
+ default:
+ return FALSE;
+
+ case 168: /* Linux/SH */
+ /* pr_cursig */
+ elf_tdata (abfd)->core->signal = bfd_get_16 (abfd, note->descdata + 12);
+
+ /* pr_pid */
+ elf_tdata (abfd)->core->lwpid = bfd_get_32 (abfd, note->descdata + 24);
+
+ /* pr_reg */
+ offset = 72;
+ size = 92;
+
+ break;
+ }
+
+ /* Make a ".reg/999" section. */
+ return _bfd_elfcore_make_pseudosection (abfd, ".reg",
+ size, note->descpos + offset);
+}
+
+static bfd_boolean
+elf32_shlin_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
+{
+ switch (note->descsz)
+ {
+ default:
+ return FALSE;
+
+ case 124: /* Linux/SH elf_prpsinfo */
+ elf_tdata (abfd)->core->program
+ = _bfd_elfcore_strndup (abfd, note->descdata + 28, 16);
+ elf_tdata (abfd)->core->command
+ = _bfd_elfcore_strndup (abfd, note->descdata + 44, 80);
+ }
+
+ /* 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 /* not SH_TARGET_ALREADY_DEFINED */
+
+
+/* Return address for Ith PLT stub in section PLT, for relocation REL
+ or (bfd_vma) -1 if it should not be included. */
+
+static bfd_vma
+sh_elf_plt_sym_val (bfd_vma i, const asection *plt,
+ const arelent *rel ATTRIBUTE_UNUSED)
+{
+ const struct elf_sh_plt_info *plt_info;
+
+ plt_info = get_plt_info (plt->owner, (plt->owner->flags & DYNAMIC) != 0);
+ return plt->vma + get_plt_offset (plt_info, i);
+}
+
+/* Decide whether to attempt to turn absptr or lsda encodings in
+ shared libraries into pcrel within the given input section. */
+
+static bfd_boolean
+sh_elf_use_relative_eh_frame (bfd *input_bfd ATTRIBUTE_UNUSED,
+ struct bfd_link_info *info,
+ asection *eh_frame_section ATTRIBUTE_UNUSED)
+{
+ struct elf_sh_link_hash_table *htab = sh_elf_hash_table (info);
+
+ /* We can't use PC-relative encodings in FDPIC binaries, in general. */
+ if (htab->fdpic_p)
+ return FALSE;
+
+ return TRUE;
+}
+
+/* Adjust the contents of an eh_frame_hdr section before they're output. */
+
+static bfd_byte
+sh_elf_encode_eh_address (bfd *abfd,
+ struct bfd_link_info *info,
+ asection *osec, bfd_vma offset,
+ asection *loc_sec, bfd_vma loc_offset,
+ bfd_vma *encoded)
+{
+ struct elf_sh_link_hash_table *htab = sh_elf_hash_table (info);
+ struct elf_link_hash_entry *h;
+
+ if (!htab->fdpic_p)
+ return _bfd_elf_encode_eh_address (abfd, info, osec, offset, loc_sec,
+ loc_offset, encoded);
+
+ h = htab->root.hgot;
+ BFD_ASSERT (h && h->root.type == bfd_link_hash_defined);
+
+ if (! h || (sh_elf_osec_to_segment (abfd, osec)
+ == sh_elf_osec_to_segment (abfd, loc_sec->output_section)))
+ return _bfd_elf_encode_eh_address (abfd, info, osec, offset,
+ loc_sec, loc_offset, encoded);
+
+ BFD_ASSERT (sh_elf_osec_to_segment (abfd, osec)
+ == (sh_elf_osec_to_segment
+ (abfd, h->root.u.def.section->output_section)));
+
+ *encoded = osec->vma + offset
+ - (h->root.u.def.value
+ + h->root.u.def.section->output_section->vma
+ + h->root.u.def.section->output_offset);
+
+ return DW_EH_PE_datarel | DW_EH_PE_sdata4;
+}
+
+#if !defined SH_TARGET_ALREADY_DEFINED
+#define TARGET_BIG_SYM sh_elf32_vec
+#define TARGET_BIG_NAME "elf32-sh"
+#define TARGET_LITTLE_SYM sh_elf32_le_vec
+#define TARGET_LITTLE_NAME "elf32-shl"
+#endif
+
+#define ELF_ARCH bfd_arch_sh
+#define ELF_TARGET_ID SH_ELF_DATA
+#define ELF_MACHINE_CODE EM_SH
+#ifdef __QNXTARGET__
+#define ELF_MAXPAGESIZE 0x1000
+#else
+#define ELF_MAXPAGESIZE 0x80
+#endif
+
+#define elf_symbol_leading_char '_'
+
+#define bfd_elf32_bfd_reloc_type_lookup sh_elf_reloc_type_lookup
+#define bfd_elf32_bfd_reloc_name_lookup \
+ sh_elf_reloc_name_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 bfd_elf32_mkobject sh_elf_mkobject
+#define elf_backend_object_p sh_elf_object_p
+#define bfd_elf32_bfd_copy_private_bfd_data \
+ sh_elf_copy_private_data
+#define bfd_elf32_bfd_merge_private_bfd_data \
+ sh_elf_merge_private_data
+
+#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_copy_indirect_symbol \
+ sh_elf_copy_indirect_symbol
+#define elf_backend_create_dynamic_sections \
+ sh_elf_create_dynamic_sections
+#define bfd_elf32_bfd_link_hash_table_create \
+ sh_elf_link_hash_table_create
+#define elf_backend_adjust_dynamic_symbol \
+ sh_elf_adjust_dynamic_symbol
+#define elf_backend_always_size_sections \
+ sh_elf_always_size_sections
+#define elf_backend_size_dynamic_sections \
+ sh_elf_size_dynamic_sections
+#define elf_backend_omit_section_dynsym sh_elf_omit_section_dynsym
+#define elf_backend_finish_dynamic_symbol \
+ sh_elf_finish_dynamic_symbol
+#define elf_backend_finish_dynamic_sections \
+ sh_elf_finish_dynamic_sections
+#define elf_backend_reloc_type_class sh_elf_reloc_type_class
+#define elf_backend_plt_sym_val sh_elf_plt_sym_val
+#define elf_backend_can_make_relative_eh_frame \
+ sh_elf_use_relative_eh_frame
+#define elf_backend_can_make_lsda_relative_eh_frame \
+ sh_elf_use_relative_eh_frame
+#define elf_backend_encode_eh_address \
+ sh_elf_encode_eh_address
+
+#define elf_backend_stack_align 8
+#define elf_backend_can_gc_sections 1
+#define elf_backend_can_refcount 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
+
+#if !defined INCLUDE_SHMEDIA && !defined SH_TARGET_ALREADY_DEFINED
+
+#include "elf32-target.h"
+
+/* NetBSD support. */
+#undef TARGET_BIG_SYM
+#define TARGET_BIG_SYM sh_elf32_nbsd_vec
+#undef TARGET_BIG_NAME
+#define TARGET_BIG_NAME "elf32-sh-nbsd"
+#undef TARGET_LITTLE_SYM
+#define TARGET_LITTLE_SYM sh_elf32_nbsd_le_vec
+#undef TARGET_LITTLE_NAME
+#define TARGET_LITTLE_NAME "elf32-shl-nbsd"
+#undef ELF_MAXPAGESIZE
+#define ELF_MAXPAGESIZE 0x10000
+#undef ELF_COMMONPAGESIZE
+#undef elf_symbol_leading_char
+#define elf_symbol_leading_char 0
+#undef elf32_bed
+#define elf32_bed elf32_sh_nbsd_bed
+
+#include "elf32-target.h"
+
+
+/* Linux support. */
+#undef TARGET_BIG_SYM
+#define TARGET_BIG_SYM sh_elf32_linux_be_vec
+#undef TARGET_BIG_NAME
+#define TARGET_BIG_NAME "elf32-shbig-linux"
+#undef TARGET_LITTLE_SYM
+#define TARGET_LITTLE_SYM sh_elf32_linux_vec
+#undef TARGET_LITTLE_NAME
+#define TARGET_LITTLE_NAME "elf32-sh-linux"
+#undef ELF_COMMONPAGESIZE
+#define ELF_COMMONPAGESIZE 0x1000
+
+#undef elf_backend_grok_prstatus
+#define elf_backend_grok_prstatus elf32_shlin_grok_prstatus
+#undef elf_backend_grok_psinfo
+#define elf_backend_grok_psinfo elf32_shlin_grok_psinfo
+#undef elf32_bed
+#define elf32_bed elf32_sh_lin_bed
+
+#include "elf32-target.h"
+
+
+/* FDPIC support. */
+#undef TARGET_BIG_SYM
+#define TARGET_BIG_SYM sh_elf32_fdpic_be_vec
+#undef TARGET_BIG_NAME
+#define TARGET_BIG_NAME "elf32-shbig-fdpic"
+#undef TARGET_LITTLE_SYM
+#define TARGET_LITTLE_SYM sh_elf32_fdpic_le_vec
+#undef TARGET_LITTLE_NAME
+#define TARGET_LITTLE_NAME "elf32-sh-fdpic"
+
+#undef elf32_bed
+#define elf32_bed elf32_sh_fd_bed
+
+#include "elf32-target.h"
+
+#undef elf_backend_modify_program_headers
+
+/* VxWorks support. */
+#undef TARGET_BIG_SYM
+#define TARGET_BIG_SYM sh_elf32_vxworks_vec
+#undef TARGET_BIG_NAME
+#define TARGET_BIG_NAME "elf32-sh-vxworks"
+#undef TARGET_LITTLE_SYM
+#define TARGET_LITTLE_SYM sh_elf32_vxworks_le_vec
+#undef TARGET_LITTLE_NAME
+#define TARGET_LITTLE_NAME "elf32-shl-vxworks"
+#undef elf32_bed
+#define elf32_bed elf32_sh_vxworks_bed
+
+#undef elf_backend_want_plt_sym
+#define elf_backend_want_plt_sym 1
+#undef elf_symbol_leading_char
+#define elf_symbol_leading_char '_'
+#define elf_backend_want_got_underscore 1
+#undef elf_backend_grok_prstatus
+#undef elf_backend_grok_psinfo
+#undef elf_backend_add_symbol_hook
+#define elf_backend_add_symbol_hook elf_vxworks_add_symbol_hook
+#undef elf_backend_link_output_symbol_hook
+#define elf_backend_link_output_symbol_hook \
+ elf_vxworks_link_output_symbol_hook
+#undef elf_backend_emit_relocs
+#define elf_backend_emit_relocs elf_vxworks_emit_relocs
+#undef elf_backend_final_write_processing
+#define elf_backend_final_write_processing \
+ elf_vxworks_final_write_processing
+#undef ELF_MAXPAGESIZE
+#define ELF_MAXPAGESIZE 0x1000
+#undef ELF_COMMONPAGESIZE
+
+#include "elf32-target.h"
+
+#endif /* neither INCLUDE_SHMEDIA nor SH_TARGET_ALREADY_DEFINED */
diff --git a/bfd/elf32-sh64-com.c b/bfd/elf32-sh64-com.c
new file mode 100644
index 0000000..5000506
--- /dev/null
+++ b/bfd/elf32-sh64-com.c
@@ -0,0 +1,245 @@
+/* SuperH SH64-specific support for 32-bit ELF
+ Copyright (C) 2000-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#define SH64_ELF
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+#include "elf-bfd.h"
+#include "elf/sh.h"
+#include "elf32-sh64.h"
+#include "../opcodes/sh64-opc.h"
+
+static bfd_boolean sh64_address_in_cranges
+ (asection *cranges, bfd_vma, sh64_elf_crange *);
+
+/* Ordering functions of a crange, for the qsort and bsearch calls and for
+ different endianness. */
+
+int
+_bfd_sh64_crange_qsort_cmpb (const void *p1, const void *p2)
+{
+ bfd_vma a1 = bfd_getb32 (p1);
+ bfd_vma a2 = bfd_getb32 (p2);
+
+ /* Preserve order if there's ambiguous contents. */
+ if (a1 == a2)
+ return (char *) p1 - (char *) p2;
+
+ return a1 - a2;
+}
+
+int
+_bfd_sh64_crange_qsort_cmpl (const void *p1, const void *p2)
+{
+ bfd_vma a1 = (bfd_vma) bfd_getl32 (p1);
+ bfd_vma a2 = (bfd_vma) bfd_getl32 (p2);
+
+ /* Preserve order if there's ambiguous contents. */
+ if (a1 == a2)
+ return (char *) p1 - (char *) p2;
+
+ return a1 - a2;
+}
+
+int
+_bfd_sh64_crange_bsearch_cmpb (const void *p1, const void *p2)
+{
+ bfd_vma a1 = *(bfd_vma *) p1;
+ bfd_vma a2 = (bfd_vma) bfd_getb32 (p2);
+ bfd_size_type size
+ = (bfd_size_type) bfd_getb32 (SH64_CRANGE_CR_SIZE_OFFSET + (char *) p2);
+
+ if (a1 >= a2 + size)
+ return 1;
+ if (a1 < a2)
+ return -1;
+ return 0;
+}
+
+int
+_bfd_sh64_crange_bsearch_cmpl (const void *p1, const void *p2)
+{
+ bfd_vma a1 = *(bfd_vma *) p1;
+ bfd_vma a2 = (bfd_vma) bfd_getl32 (p2);
+ bfd_size_type size
+ = (bfd_size_type) bfd_getl32 (SH64_CRANGE_CR_SIZE_OFFSET + (char *) p2);
+
+ if (a1 >= a2 + size)
+ return 1;
+ if (a1 < a2)
+ return -1;
+ return 0;
+}
+
+/* Check whether a specific address is specified within a .cranges
+ section. Return FALSE if not found, and TRUE if found, and the region
+ filled into RANGEP if non-NULL. */
+
+static bfd_boolean
+sh64_address_in_cranges (asection *cranges, bfd_vma addr,
+ sh64_elf_crange *rangep)
+{
+ bfd_byte *cranges_contents;
+ bfd_byte *found_rangep;
+ bfd_size_type cranges_size = cranges->size;
+
+ /* If the size is not a multiple of the cranges entry size, then
+ something is badly wrong. */
+ if ((cranges_size % SH64_CRANGE_SIZE) != 0)
+ return FALSE;
+
+ /* If this section has relocations, then we can't do anything sane. */
+ if (bfd_get_section_flags (cranges->owner, cranges) & SEC_RELOC)
+ return FALSE;
+
+ /* Has some kind soul (or previous call) left processed, sorted contents
+ for us? */
+ if ((bfd_get_section_flags (cranges->owner, cranges) & SEC_IN_MEMORY)
+ && elf_section_data (cranges)->this_hdr.sh_type == SHT_SH5_CR_SORTED)
+ cranges_contents = cranges->contents;
+ else
+ {
+ if (!bfd_malloc_and_get_section (cranges->owner, cranges,
+ &cranges_contents))
+ goto error_return;
+
+ /* Is it sorted? */
+ if (elf_section_data (cranges)->this_hdr.sh_type
+ != SHT_SH5_CR_SORTED)
+ /* Nope. Lets sort it. */
+ qsort (cranges_contents, cranges_size / SH64_CRANGE_SIZE,
+ SH64_CRANGE_SIZE,
+ bfd_big_endian (cranges->owner)
+ ? _bfd_sh64_crange_qsort_cmpb : _bfd_sh64_crange_qsort_cmpl);
+
+ /* Let's keep it around. */
+ cranges->contents = cranges_contents;
+ bfd_set_section_flags (cranges->owner, cranges,
+ bfd_get_section_flags (cranges->owner, cranges)
+ | SEC_IN_MEMORY);
+
+ /* It's sorted now. */
+ elf_section_data (cranges)->this_hdr.sh_type = SHT_SH5_CR_SORTED;
+ }
+
+ /* Try and find a matching range. */
+ found_rangep
+ = bsearch (&addr, cranges_contents, cranges_size / SH64_CRANGE_SIZE,
+ SH64_CRANGE_SIZE,
+ bfd_big_endian (cranges->owner)
+ ? _bfd_sh64_crange_bsearch_cmpb
+ : _bfd_sh64_crange_bsearch_cmpl);
+
+ /* Fill in a few return values if we found a matching range. */
+ if (found_rangep)
+ {
+ enum sh64_elf_cr_type cr_type
+ = bfd_get_16 (cranges->owner,
+ SH64_CRANGE_CR_TYPE_OFFSET + found_rangep);
+ bfd_vma cr_addr
+ = bfd_get_32 (cranges->owner,
+ SH64_CRANGE_CR_ADDR_OFFSET
+ + (char *) found_rangep);
+ bfd_size_type cr_size
+ = bfd_get_32 (cranges->owner,
+ SH64_CRANGE_CR_SIZE_OFFSET
+ + (char *) found_rangep);
+
+ rangep->cr_addr = cr_addr;
+ rangep->cr_size = cr_size;
+ rangep->cr_type = cr_type;
+
+ return TRUE;
+ }
+
+ /* There is a .cranges section, but it does not have a descriptor
+ matching this address. */
+ return FALSE;
+
+error_return:
+ if (cranges_contents != NULL)
+ free (cranges_contents);
+ return FALSE;
+}
+
+/* Determine what ADDR points to in SEC, and fill in a range descriptor in
+ *RANGEP if it's non-NULL. */
+
+enum sh64_elf_cr_type
+sh64_get_contents_type (asection *sec, bfd_vma addr, sh64_elf_crange *rangep)
+{
+ asection *cranges;
+
+ /* Fill in the range with the boundaries of the section as a default. */
+ if (bfd_get_flavour (sec->owner) == bfd_target_elf_flavour
+ && elf_elfheader (sec->owner)->e_type == ET_EXEC)
+ {
+ rangep->cr_addr = bfd_get_section_vma (sec->owner, sec);
+ rangep->cr_size = sec->size;
+ rangep->cr_type = CRT_NONE;
+ }
+ else
+ return FALSE;
+
+ /* If none of the pertinent bits are set, then it's a SHcompact (or at
+ least not SHmedia). */
+ if ((elf_section_data (sec)->this_hdr.sh_flags
+ & (SHF_SH5_ISA32 | SHF_SH5_ISA32_MIXED)) == 0)
+ {
+ enum sh64_elf_cr_type cr_type
+ = ((bfd_get_section_flags (sec->owner, sec) & SEC_CODE) != 0
+ ? CRT_SH5_ISA16 : CRT_DATA);
+ rangep->cr_type = cr_type;
+ return cr_type;
+ }
+
+ /* If only the SHF_SH5_ISA32 bit is set, then we have SHmedia. */
+ if ((elf_section_data (sec)->this_hdr.sh_flags
+ & (SHF_SH5_ISA32 | SHF_SH5_ISA32_MIXED)) == SHF_SH5_ISA32)
+ {
+ rangep->cr_type = CRT_SH5_ISA32;
+ return CRT_SH5_ISA32;
+ }
+
+ /* Otherwise, we have to look up the .cranges section. */
+ cranges = bfd_get_section_by_name (sec->owner, SH64_CRANGES_SECTION_NAME);
+
+ if (cranges == NULL)
+ /* A mixed section but there's no .cranges section. This is probably
+ bad input; it does not comply to specs. */
+ return CRT_NONE;
+
+ /* If this call fails, we will still have CRT_NONE in rangep->cr_type
+ and that will be suitable to return. */
+ sh64_address_in_cranges (cranges, addr, rangep);
+
+ return rangep->cr_type;
+}
+
+/* This is a simpler exported interface for the benefit of gdb et al. */
+
+bfd_boolean
+sh64_address_is_shmedia (asection *sec, bfd_vma addr)
+{
+ sh64_elf_crange dummy;
+ return sh64_get_contents_type (sec, addr, &dummy) == CRT_SH5_ISA32;
+}
diff --git a/bfd/elf32-sh64.c b/bfd/elf32-sh64.c
new file mode 100644
index 0000000..9042081
--- /dev/null
+++ b/bfd/elf32-sh64.c
@@ -0,0 +1,813 @@
+/* SuperH SH64-specific support for 32-bit ELF
+ Copyright (C) 2000-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#define SH64_ELF
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "elf-bfd.h"
+#include "../opcodes/sh64-opc.h"
+#include "elf32-sh64.h"
+
+/* Add a suffix for datalabel indirection symbols. It must not match any
+ other symbols; user symbols with or without version or other
+ decoration. It must only be used internally and not emitted by any
+ means. */
+#define DATALABEL_SUFFIX " DL"
+
+/* Used to hold data for function called through bfd_map_over_sections. */
+struct sh64_find_section_vma_data
+ {
+ asection *section;
+ bfd_vma addr;
+ };
+
+static bfd_boolean sh64_elf_new_section_hook
+ (bfd *, asection *);
+static bfd_boolean sh64_elf_copy_private_data
+ (bfd *, bfd *);
+static bfd_boolean sh64_elf_merge_private_data
+ (bfd *, bfd *);
+static bfd_boolean sh64_elf_fake_sections
+ (bfd *, Elf_Internal_Shdr *, asection *);
+static bfd_boolean sh64_elf_set_private_flags
+ (bfd *, flagword);
+static bfd_boolean sh64_elf_set_mach_from_flags
+ (bfd *);
+static bfd_boolean shmedia_prepare_reloc
+ (struct bfd_link_info *, bfd *, asection *, bfd_byte *,
+ const Elf_Internal_Rela *, bfd_vma *);
+static int sh64_elf_get_symbol_type
+ (Elf_Internal_Sym *, int);
+static bfd_boolean sh64_elf_add_symbol_hook
+ (bfd *, struct bfd_link_info *, Elf_Internal_Sym *, const char **,
+ flagword *, asection **, bfd_vma *);
+static int sh64_elf_link_output_symbol_hook
+ (struct bfd_link_info *, const char *, Elf_Internal_Sym *, asection *,
+ struct elf_link_hash_entry *);
+static bfd_boolean sh64_backend_section_from_shdr
+ (bfd *, Elf_Internal_Shdr *, const char *, int);
+static void sh64_elf_final_write_processing
+ (bfd *, bfd_boolean);
+static bfd_boolean sh64_bfd_elf_copy_private_section_data
+ (bfd *, asection *, bfd *, asection *);
+static void sh64_find_section_for_address
+ (bfd *, asection *, void *);
+
+/* Let elf32-sh.c handle the "bfd_" definitions, so we only have to
+ intrude with an #ifndef around the function definition. */
+#define sh_elf_copy_private_data sh64_elf_copy_private_data
+#define sh_elf_merge_private_data sh64_elf_merge_private_data
+#define sh_elf_set_private_flags sh64_elf_set_private_flags
+/* Typo in elf32-sh.c (and unlinear name). */
+#define bfd_elf32_bfd_set_private_flags sh64_elf_set_private_flags
+#define sh_elf_set_mach_from_flags sh64_elf_set_mach_from_flags
+
+#define elf_backend_sign_extend_vma 1
+#define elf_backend_fake_sections sh64_elf_fake_sections
+#define elf_backend_get_symbol_type sh64_elf_get_symbol_type
+#define elf_backend_add_symbol_hook sh64_elf_add_symbol_hook
+#define elf_backend_link_output_symbol_hook \
+ sh64_elf_link_output_symbol_hook
+#define elf_backend_merge_symbol_attribute sh64_elf_merge_symbol_attribute
+#define elf_backend_final_write_processing sh64_elf_final_write_processing
+#define elf_backend_section_from_shdr sh64_backend_section_from_shdr
+#define elf_backend_special_sections sh64_elf_special_sections
+#define elf_backend_section_flags sh64_elf_section_flags
+
+#define bfd_elf32_new_section_hook sh64_elf_new_section_hook
+
+/* For objcopy, we need to set up sh64_elf_section_data (asection *) from
+ incoming section flags. This is otherwise done in sh64elf.em when
+ linking or tc-sh64.c when assembling. */
+#define bfd_elf32_bfd_copy_private_section_data \
+ sh64_bfd_elf_copy_private_section_data
+
+/* This COFF-only function (only compiled with COFF support, making
+ ELF-only chains problematic) returns TRUE early for SH4, so let's just
+ define it TRUE here. */
+#define _bfd_sh_align_load_span(a,b,c,d,e,f,g,h,i,j) \
+ ((void) f, (void) h, (void) i, TRUE)
+
+#define GOT_BIAS (-((long)-32768))
+#define INCLUDE_SHMEDIA
+#define SH_TARGET_ALREADY_DEFINED
+#include "elf32-sh.c"
+
+/* Tack some extra info on struct bfd_elf_section_data. */
+
+static bfd_boolean
+sh64_elf_new_section_hook (bfd *abfd, asection *sec)
+{
+ if (!sec->used_by_bfd)
+ {
+ struct _sh64_elf_section_data *sdata;
+ bfd_size_type amt = sizeof (*sdata);
+
+ sdata = bfd_zalloc (abfd, amt);
+ if (sdata == NULL)
+ return FALSE;
+ sec->used_by_bfd = sdata;
+ }
+
+ return _bfd_elf_new_section_hook (abfd, sec);
+}
+
+/* Set the SHF_SH5_ISA32 flag for ISA SHmedia code sections, and pass
+ through SHT_SH5_CR_SORTED on a sorted .cranges section. */
+
+bfd_boolean
+sh64_elf_fake_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
+ Elf_Internal_Shdr *elf_section_hdr,
+ asection *asect)
+{
+ if (sh64_elf_section_data (asect)->sh64_info != NULL)
+ elf_section_hdr->sh_flags
+ |= sh64_elf_section_data (asect)->sh64_info->contents_flags;
+
+ /* If this section has the SEC_SORT_ENTRIES flag set, it is a sorted
+ .cranges section passing through objcopy. */
+ if ((bfd_get_section_flags (output_bfd, asect) & SEC_SORT_ENTRIES) != 0
+ && strcmp (bfd_get_section_name (output_bfd, asect),
+ SH64_CRANGES_SECTION_NAME) == 0)
+ elf_section_hdr->sh_type = SHT_SH5_CR_SORTED;
+
+ return TRUE;
+}
+
+static bfd_boolean
+sh64_elf_set_mach_from_flags (bfd *abfd)
+{
+ flagword flags = elf_elfheader (abfd)->e_flags;
+
+ switch (flags & EF_SH_MACH_MASK)
+ {
+ case EF_SH5:
+ /* These are fit to execute on SH5. Just one but keep the switch
+ construct to make additions easy. */
+ bfd_default_set_arch_mach (abfd, bfd_arch_sh, bfd_mach_sh5);
+ break;
+
+ default:
+ bfd_set_error (bfd_error_wrong_format);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static bfd_boolean
+sh64_elf_section_flags (flagword *flags,
+ const Elf_Internal_Shdr *hdr)
+{
+ if (hdr->bfd_section == NULL)
+ return FALSE;
+
+ if (strcmp (hdr->bfd_section->name, SH64_CRANGES_SECTION_NAME) == 0)
+ *flags |= SEC_DEBUGGING;
+
+ return TRUE;
+}
+
+static bfd_boolean
+sh64_elf_copy_private_data (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;
+
+ return _bfd_elf_copy_private_bfd_data (ibfd, obfd);
+}
+
+static bfd_boolean
+sh64_elf_merge_private_data (bfd *ibfd, bfd *obfd)
+{
+ flagword old_flags, new_flags;
+
+ if (! _bfd_generic_verify_endian_match (ibfd, obfd))
+ return FALSE;
+
+ if ( bfd_get_flavour (ibfd) != bfd_target_elf_flavour
+ || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
+ return TRUE;
+
+ if (bfd_get_arch_size (ibfd) != bfd_get_arch_size (obfd))
+ {
+ const char *msg;
+
+ if (bfd_get_arch_size (ibfd) == 32
+ && bfd_get_arch_size (obfd) == 64)
+ msg = _("%s: compiled as 32-bit object and %s is 64-bit");
+ else if (bfd_get_arch_size (ibfd) == 64
+ && bfd_get_arch_size (obfd) == 32)
+ msg = _("%s: compiled as 64-bit object and %s is 32-bit");
+ else
+ msg = _("%s: object size does not match that of target %s");
+
+ (*_bfd_error_handler) (msg, bfd_get_filename (ibfd),
+ bfd_get_filename (obfd));
+ bfd_set_error (bfd_error_wrong_format);
+ return FALSE;
+ }
+
+ old_flags = elf_elfheader (obfd)->e_flags;
+ new_flags = elf_elfheader (ibfd)->e_flags;
+ if (! elf_flags_init (obfd))
+ {
+ /* This happens when ld starts out with a 'blank' output file. */
+ elf_flags_init (obfd) = TRUE;
+ elf_elfheader (obfd)->e_flags = old_flags = new_flags;
+ }
+ /* We don't allow linking in non-SH64 code. */
+ else if ((new_flags & EF_SH_MACH_MASK) != EF_SH5)
+ {
+ (*_bfd_error_handler)
+ ("%s: uses non-SH64 instructions while previous modules use SH64 instructions",
+ bfd_get_filename (ibfd));
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+
+ /* I can't think of anything sane other than old_flags being EF_SH5 and
+ that we need to preserve that. */
+ elf_elfheader (obfd)->e_flags = old_flags;
+ return sh64_elf_set_mach_from_flags (obfd);
+}
+
+/* Handle a SH64-specific section when reading an object file. This
+ is called when bfd_section_from_shdr finds a section with an unknown
+ type.
+
+ We only recognize SHT_SH5_CR_SORTED, on the .cranges section. */
+
+bfd_boolean
+sh64_backend_section_from_shdr (bfd *abfd, Elf_Internal_Shdr *hdr,
+ const char *name, int shindex)
+{
+ flagword flags = 0;
+
+ /* We do like MIPS with a bit switch for recognized types, and returning
+ FALSE for a recognized section type with an unexpected name. Right
+ now we only have one recognized type, but that might change. */
+ switch (hdr->sh_type)
+ {
+ case SHT_SH5_CR_SORTED:
+ if (strcmp (name, SH64_CRANGES_SECTION_NAME) != 0)
+ return FALSE;
+
+ /* We set the SEC_SORT_ENTRIES flag so it can be passed on to
+ sh64_elf_fake_sections, keeping SHT_SH5_CR_SORTED if this object
+ passes through objcopy. Perhaps it is brittle; the flag can
+ suddenly be used by other BFD parts, but it seems not really used
+ anywhere at the moment. */
+ flags = SEC_DEBUGGING | SEC_SORT_ENTRIES;
+ break;
+
+ default:
+ return FALSE;
+ }
+
+ if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex))
+ return FALSE;
+
+ if (flags
+ && ! bfd_set_section_flags (abfd, hdr->bfd_section,
+ bfd_get_section_flags (abfd,
+ hdr->bfd_section)
+ | flags))
+ return FALSE;
+
+ return TRUE;
+}
+
+/* In contrast to sh64_backend_section_from_shdr, this is called for all
+ sections, but only when copying sections, not when linking or
+ assembling. We need to set up the sh64_elf_section_data (asection *)
+ structure for the SH64 ELF section flags to be copied correctly. */
+
+bfd_boolean
+sh64_bfd_elf_copy_private_section_data (bfd *ibfd, asection *isec,
+ bfd *obfd, asection *osec)
+{
+ struct sh64_section_data *sh64_sec_data;
+
+ if (ibfd->xvec->flavour != bfd_target_elf_flavour
+ || obfd->xvec->flavour != bfd_target_elf_flavour)
+ return TRUE;
+
+ if (! _bfd_elf_copy_private_section_data (ibfd, isec, obfd, osec))
+ return FALSE;
+
+ sh64_sec_data = sh64_elf_section_data (isec)->sh64_info;
+ if (sh64_sec_data == NULL)
+ {
+ sh64_sec_data = bfd_zmalloc (sizeof (struct sh64_section_data));
+
+ if (sh64_sec_data == NULL)
+ return FALSE;
+
+ sh64_sec_data->contents_flags
+ = (elf_section_data (isec)->this_hdr.sh_flags
+ & (SHF_SH5_ISA32 | SHF_SH5_ISA32_MIXED));
+
+ sh64_elf_section_data (osec)->sh64_info = sh64_sec_data;
+ }
+
+ return TRUE;
+}
+
+/* Function to keep SH64 specific file flags. */
+
+static bfd_boolean
+sh64_elf_set_private_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 sh64_elf_set_mach_from_flags (abfd);
+}
+
+/* Called when writing out an object file to decide the type of a symbol. */
+
+static int
+sh64_elf_get_symbol_type (Elf_Internal_Sym *elf_sym, int type)
+{
+ if (ELF_ST_TYPE (elf_sym->st_info) == STT_DATALABEL)
+ return STT_DATALABEL;
+
+ return type;
+}
+
+/* Hook called by the linker routine which adds symbols from an object
+ file. We must make indirect symbols for undefined symbols marked with
+ STT_DATALABEL, so relocations passing them will pick up that attribute
+ and neutralize STO_SH5_ISA32 found on the symbol definition.
+
+ There is a problem, though: We want to fill in the hash-table entry for
+ this symbol and signal to the caller that no further processing is
+ needed. But we don't have the index for this hash-table entry. We
+ rely here on that the current entry is the first hash-entry with NULL,
+ which seems brittle. Also, iterating over the hash-table to find that
+ entry is a linear operation on the number of symbols in this input
+ file, and this function should take constant time, so that's not good
+ too. Only comfort is that DataLabel references should only be found in
+ hand-written assembly code and thus be rare. FIXME: Talk maintainers
+ into adding an option to elf_add_symbol_hook (preferably) for the index
+ or the hash entry, alternatively adding the index to Elf_Internal_Sym
+ (not so good). */
+
+static bfd_boolean
+sh64_elf_add_symbol_hook (bfd *abfd, struct bfd_link_info *info,
+ Elf_Internal_Sym *sym, const char **namep,
+ flagword *flagsp ATTRIBUTE_UNUSED,
+ asection **secp, bfd_vma *valp)
+{
+ /* We want to do this for relocatable as well as final linking. */
+ if (ELF_ST_TYPE (sym->st_info) == STT_DATALABEL
+ && is_elf_hash_table (info->hash))
+ {
+ struct elf_link_hash_entry *h;
+
+ /* For relocatable links, we register the DataLabel sym in its own
+ right, and tweak the name when it's output. Otherwise, we make
+ an indirect symbol of it. */
+ flagword flags
+ = info->relocatable || info->emitrelocations
+ ? BSF_GLOBAL : BSF_GLOBAL | BSF_INDIRECT;
+
+ char *dl_name
+ = bfd_malloc (strlen (*namep) + sizeof (DATALABEL_SUFFIX));
+ struct elf_link_hash_entry ** sym_hash = elf_sym_hashes (abfd);
+
+ BFD_ASSERT (sym_hash != NULL);
+
+ /* Allocation may fail. */
+ if (dl_name == NULL)
+ return FALSE;
+
+ strcpy (dl_name, *namep);
+ strcat (dl_name, DATALABEL_SUFFIX);
+
+ h = (struct elf_link_hash_entry *)
+ bfd_link_hash_lookup (info->hash, dl_name, FALSE, FALSE, FALSE);
+
+ if (h == NULL)
+ {
+ /* No previous datalabel symbol. Make one. */
+ struct bfd_link_hash_entry *bh = NULL;
+ const struct elf_backend_data *bed = get_elf_backend_data (abfd);
+
+ if (! _bfd_generic_link_add_one_symbol (info, abfd, dl_name,
+ flags, *secp, *valp,
+ *namep, FALSE,
+ bed->collect, &bh))
+ {
+ free (dl_name);
+ return FALSE;
+ }
+
+ h = (struct elf_link_hash_entry *) bh;
+ h->non_elf = 0;
+ h->type = STT_DATALABEL;
+ }
+ else
+ /* If a new symbol was created, it holds the allocated name.
+ Otherwise, we don't need it anymore and should deallocate it. */
+ free (dl_name);
+
+ if (h->type != STT_DATALABEL
+ || ((info->relocatable || info->emitrelocations)
+ && h->root.type != bfd_link_hash_undefined)
+ || (! info->relocatable && !info->emitrelocations
+ && h->root.type != bfd_link_hash_indirect))
+ {
+ /* Make sure we don't get confused on invalid input. */
+ (*_bfd_error_handler)
+ (_("%s: encountered datalabel symbol in input"),
+ bfd_get_filename (abfd));
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+
+ /* Now find the hash-table slot for this entry and fill it in. */
+ while (*sym_hash != NULL)
+ sym_hash++;
+ *sym_hash = h;
+
+ /* Signal to caller to skip this symbol - we've handled it. */
+ *namep = NULL;
+ }
+
+ return TRUE;
+}
+
+/* This hook function is called before the linker writes out a global
+ symbol. For relocatable links, DataLabel symbols will be present in
+ linker output. We cut off the special suffix on those symbols, so the
+ right name appears in the output.
+
+ When linking and emitting relocations, there can appear global symbols
+ that are not referenced by relocs, but rather only implicitly through
+ DataLabel references, a relation that is not visible to the linker.
+ Since no stripping of global symbols in done when doing such linking,
+ we don't need to look up and make sure to emit the main symbol for each
+ DataLabel symbol. */
+
+static int
+sh64_elf_link_output_symbol_hook (struct bfd_link_info *info,
+ const char *cname,
+ Elf_Internal_Sym *sym,
+ asection *input_sec ATTRIBUTE_UNUSED,
+ struct elf_link_hash_entry *h ATTRIBUTE_UNUSED)
+{
+ char *name = (char *) cname;
+
+ if (info->relocatable || info->emitrelocations)
+ {
+ if (ELF_ST_TYPE (sym->st_info) == STT_DATALABEL)
+ name[strlen (name) - strlen (DATALABEL_SUFFIX)] = 0;
+ }
+
+ return 1;
+}
+
+/* Check a SH64-specific reloc and put the value to relocate to into
+ RELOCATION, ready to pass to _bfd_final_link_relocate. Return FALSE if
+ bad value, TRUE if ok. */
+
+static bfd_boolean
+shmedia_prepare_reloc (struct bfd_link_info *info, bfd *abfd,
+ asection *input_section, bfd_byte *contents,
+ const Elf_Internal_Rela *rel, bfd_vma *relocation)
+{
+ bfd_vma disp, dropped;
+
+ switch (ELF32_R_TYPE (rel->r_info))
+ {
+ case R_SH_PT_16:
+ /* Check the lowest bit of the destination field. If it is 1, we
+ check the ISA type of the destination (i.e. the low bit of the
+ "relocation" value, and emit an error if the instruction does not
+ match). If it is 0, we change a PTA to PTB. There should never
+ be a PTB that should change to a PTA; that indicates a toolchain
+ error; a mismatch with GAS. */
+ {
+ char *msg = NULL;
+ bfd_vma insn = bfd_get_32 (abfd, contents + rel->r_offset);
+
+ if (insn & (1 << 10))
+ {
+ /* Check matching insn and ISA (address of target). */
+ if ((insn & SHMEDIA_PTB_BIT) != 0
+ && ((*relocation + rel->r_addend) & 1) != 0)
+ msg = _("PTB mismatch: a SHmedia address (bit 0 == 1)");
+ else if ((insn & SHMEDIA_PTB_BIT) == 0
+ && ((*relocation + rel->r_addend) & 1) == 0)
+ msg = _("PTA mismatch: a SHcompact address (bit 0 == 0)");
+
+ if (msg != NULL
+ && ! ((*info->callbacks->reloc_dangerous)
+ (info, msg, abfd, input_section,
+ rel->r_offset)))
+ return FALSE;
+ }
+ else
+ {
+ /* We shouldn't get here with a PTB insn and a R_SH_PT_16. It
+ means GAS output does not match expectations; a PTA or PTB
+ expressed as such (or a PT found at assembly to be PTB)
+ would match the test above, and PT expansion with an
+ unknown destination (or when relaxing) will get us here. */
+ if ((insn & SHMEDIA_PTB_BIT) != 0)
+ {
+ (*_bfd_error_handler)
+ (_("%s: GAS error: unexpected PTB insn with R_SH_PT_16"),
+ bfd_get_filename (input_section->owner));
+ return FALSE;
+ }
+
+ /* Change the PTA to a PTB, if destination indicates so. */
+ if (((*relocation + rel->r_addend) & 1) == 0)
+ bfd_put_32 (abfd, insn | SHMEDIA_PTB_BIT,
+ contents + rel->r_offset);
+ }
+ }
+
+ case R_SH_SHMEDIA_CODE:
+ case R_SH_DIR5U:
+ case R_SH_DIR6S:
+ case R_SH_DIR6U:
+ case R_SH_DIR10S:
+ case R_SH_DIR10SW:
+ case R_SH_DIR10SL:
+ case R_SH_DIR10SQ:
+ case R_SH_IMMS16:
+ case R_SH_IMMU16:
+ case R_SH_IMM_LOW16:
+ case R_SH_IMM_LOW16_PCREL:
+ case R_SH_IMM_MEDLOW16:
+ case R_SH_IMM_MEDLOW16_PCREL:
+ case R_SH_IMM_MEDHI16:
+ case R_SH_IMM_MEDHI16_PCREL:
+ case R_SH_IMM_HI16:
+ case R_SH_IMM_HI16_PCREL:
+ case R_SH_64:
+ case R_SH_64_PCREL:
+ break;
+
+ default:
+ return FALSE;
+ }
+
+ disp = (*relocation & 0xf);
+ dropped = 0;
+ switch (ELF32_R_TYPE (rel->r_info))
+ {
+ case R_SH_DIR10SW: dropped = disp & 1; break;
+ case R_SH_DIR10SL: dropped = disp & 3; break;
+ case R_SH_DIR10SQ: dropped = disp & 7; break;
+ }
+ if (dropped != 0)
+ {
+ (*_bfd_error_handler)
+ (_("%B: error: unaligned relocation type %d at %08x reloc %p\n"),
+ input_section->owner, ELF32_R_TYPE (rel->r_info),
+ (unsigned) rel->r_offset, relocation);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/* Helper function to locate the section holding a certain address. This
+ is called via bfd_map_over_sections. */
+
+static void
+sh64_find_section_for_address (bfd *abfd ATTRIBUTE_UNUSED,
+ asection *section, void *data)
+{
+ bfd_vma vma;
+ bfd_size_type size;
+
+ struct sh64_find_section_vma_data *fsec_datap
+ = (struct sh64_find_section_vma_data *) data;
+
+ /* Return if already found. */
+ if (fsec_datap->section)
+ return;
+
+ /* If this section isn't part of the addressable contents, skip it. */
+ if ((bfd_get_section_flags (abfd, section) & SEC_ALLOC) == 0)
+ return;
+
+ vma = bfd_get_section_vma (abfd, section);
+ if (fsec_datap->addr < vma)
+ return;
+
+ size = section->size;
+ if (fsec_datap->addr >= vma + size)
+ return;
+
+ fsec_datap->section = section;
+}
+
+/* Make sure to write out the generated entries in the .cranges section
+ when doing partial linking, and set bit 0 on the entry address if it
+ points to SHmedia code and write sorted .cranges entries when writing
+ executables (final linking and objcopy). */
+
+static void
+sh64_elf_final_write_processing (bfd *abfd,
+ bfd_boolean linker ATTRIBUTE_UNUSED)
+{
+ bfd_vma ld_generated_cranges_size;
+ asection *cranges
+ = bfd_get_section_by_name (abfd, SH64_CRANGES_SECTION_NAME);
+
+ /* If no new .cranges were added, the generic ELF linker parts will
+ write it all out. If not, we need to write them out when doing
+ partial linking. For a final link, we will sort them and write them
+ all out further below. */
+ if (linker
+ && cranges != NULL
+ && elf_elfheader (abfd)->e_type != ET_EXEC
+ && (ld_generated_cranges_size
+ = sh64_elf_section_data (cranges)->sh64_info->cranges_growth) != 0)
+ {
+ bfd_vma incoming_cranges_size
+ = cranges->size - ld_generated_cranges_size;
+
+ if (! bfd_set_section_contents (abfd, cranges,
+ cranges->contents
+ + incoming_cranges_size,
+ cranges->output_offset
+ + incoming_cranges_size,
+ ld_generated_cranges_size))
+ {
+ bfd_set_error (bfd_error_file_truncated);
+ (*_bfd_error_handler)
+ (_("%s: could not write out added .cranges entries"),
+ bfd_get_filename (abfd));
+ }
+ }
+
+ /* Only set entry address bit 0 and sort .cranges when linking to an
+ executable; never with objcopy or strip. */
+ if (linker && elf_elfheader (abfd)->e_type == ET_EXEC)
+ {
+ struct sh64_find_section_vma_data fsec_data;
+ sh64_elf_crange dummy;
+
+ /* For a final link, set the low bit of the entry address to
+ reflect whether or not it is a SHmedia address.
+ FIXME: Perhaps we shouldn't do this if the entry address was
+ supplied numerically, but we currently lack the infrastructure to
+ recognize that: The entry symbol, and info whether it is numeric
+ or a symbol name is kept private in the linker. */
+ fsec_data.addr = elf_elfheader (abfd)->e_entry;
+ fsec_data.section = NULL;
+
+ bfd_map_over_sections (abfd, sh64_find_section_for_address,
+ &fsec_data);
+ if (fsec_data.section
+ && (sh64_get_contents_type (fsec_data.section,
+ elf_elfheader (abfd)->e_entry,
+ &dummy) == CRT_SH5_ISA32))
+ elf_elfheader (abfd)->e_entry |= 1;
+
+ /* If we have a .cranges section, sort the entries. */
+ if (cranges != NULL)
+ {
+ bfd_size_type cranges_size = cranges->size;
+
+ /* We know we always have these in memory at this time. */
+ BFD_ASSERT (cranges->contents != NULL);
+
+ /* The .cranges may already have been sorted in the process of
+ finding out the ISA-type of the entry address. If not, we do
+ it here. */
+ if (elf_section_data (cranges)->this_hdr.sh_type
+ != SHT_SH5_CR_SORTED)
+ {
+ qsort (cranges->contents, cranges_size / SH64_CRANGE_SIZE,
+ SH64_CRANGE_SIZE,
+ bfd_big_endian (cranges->owner)
+ ? _bfd_sh64_crange_qsort_cmpb
+ : _bfd_sh64_crange_qsort_cmpl);
+ elf_section_data (cranges)->this_hdr.sh_type
+ = SHT_SH5_CR_SORTED;
+ }
+
+ /* We need to write it out in whole as sorted. */
+ if (! bfd_set_section_contents (abfd, cranges,
+ cranges->contents,
+ cranges->output_offset,
+ cranges_size))
+ {
+ bfd_set_error (bfd_error_file_truncated);
+ (*_bfd_error_handler)
+ (_("%s: could not write out sorted .cranges entries"),
+ bfd_get_filename (abfd));
+ }
+ }
+ }
+}
+
+/* Merge non visibility st_other attribute when the symbol comes from
+ a dynamic object. */
+static void
+sh64_elf_merge_symbol_attribute (struct elf_link_hash_entry *h,
+ const Elf_Internal_Sym *isym,
+ bfd_boolean definition,
+ bfd_boolean dynamic ATTRIBUTE_UNUSED)
+{
+ if ((isym->st_other & ~ELF_ST_VISIBILITY (-1)) != 0)
+ {
+ unsigned char other;
+
+ /* Take the balance of OTHER from the definition. */
+ other = (definition ? isym->st_other : h->other);
+ other &= ~ ELF_ST_VISIBILITY (-1);
+ h->other = other | ELF_ST_VISIBILITY (h->other);
+ }
+
+ return;
+}
+
+static const struct bfd_elf_special_section sh64_elf_special_sections[] =
+{
+ { STRING_COMMA_LEN (".cranges"), 0, SHT_PROGBITS, 0 },
+ { NULL, 0, 0, 0, 0 }
+};
+
+#undef TARGET_BIG_SYM
+#define TARGET_BIG_SYM sh64_elf32_vec
+#undef TARGET_BIG_NAME
+#define TARGET_BIG_NAME "elf32-sh64"
+#undef TARGET_LITTLE_SYM
+#define TARGET_LITTLE_SYM sh64_elf32_le_vec
+#undef TARGET_LITTLE_NAME
+#define TARGET_LITTLE_NAME "elf32-sh64l"
+
+#include "elf32-target.h"
+
+/* NetBSD support. */
+#undef TARGET_BIG_SYM
+#define TARGET_BIG_SYM sh64_elf32_nbsd_vec
+#undef TARGET_BIG_NAME
+#define TARGET_BIG_NAME "elf32-sh64-nbsd"
+#undef TARGET_LITTLE_SYM
+#define TARGET_LITTLE_SYM sh64_elf32_nbsd_le_vec
+#undef TARGET_LITTLE_NAME
+#define TARGET_LITTLE_NAME "elf32-sh64l-nbsd"
+#undef ELF_MAXPAGESIZE
+#define ELF_MAXPAGESIZE 0x10000
+#undef ELF_COMMONPAGESIZE
+#undef elf_symbol_leading_char
+#define elf_symbol_leading_char 0
+#undef elf32_bed
+#define elf32_bed elf32_sh64_nbsd_bed
+
+#include "elf32-target.h"
+
+/* Linux support. */
+#undef TARGET_BIG_SYM
+#define TARGET_BIG_SYM sh64_elf32_linux_be_vec
+#undef TARGET_BIG_NAME
+#define TARGET_BIG_NAME "elf32-sh64big-linux"
+#undef TARGET_LITTLE_SYM
+#define TARGET_LITTLE_SYM sh64_elf32_linux_vec
+#undef TARGET_LITTLE_NAME
+#define TARGET_LITTLE_NAME "elf32-sh64-linux"
+#undef elf32_bed
+#define elf32_bed elf32_sh64_lin_bed
+#undef ELF_COMMONPAGESIZE
+#define ELF_COMMONPAGESIZE 0x1000
+
+#include "elf32-target.h"
+
diff --git a/bfd/elf32-sh64.h b/bfd/elf32-sh64.h
new file mode 100644
index 0000000..4aee0c5
--- /dev/null
+++ b/bfd/elf32-sh64.h
@@ -0,0 +1,88 @@
+/* SH ELF support for BFD.
+ Copyright (C) 2003-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#ifndef ELF32_SH64_H
+#define ELF32_SH64_H
+
+#define SH64_CRANGES_SECTION_NAME ".cranges"
+enum sh64_elf_cr_type {
+ CRT_NONE = 0,
+ CRT_DATA = 1,
+ CRT_SH5_ISA16 = 2,
+ CRT_SH5_ISA32 = 3
+};
+
+/* The official definition is this:
+
+ typedef struct {
+ Elf32_Addr cr_addr;
+ Elf32_Word cr_size;
+ Elf32_Half cr_type;
+ } Elf32_CRange;
+
+ but we have no use for that exact type. Instead we use this struct for
+ the internal representation. */
+typedef struct {
+ bfd_vma cr_addr;
+ bfd_size_type cr_size;
+ enum sh64_elf_cr_type cr_type;
+} sh64_elf_crange;
+
+#define SH64_CRANGE_SIZE (4 + 4 + 2)
+#define SH64_CRANGE_CR_ADDR_OFFSET 0
+#define SH64_CRANGE_CR_SIZE_OFFSET 4
+#define SH64_CRANGE_CR_TYPE_OFFSET (4 + 4)
+
+/* Get the contents type of an arbitrary address, or return CRT_NONE. */
+extern enum sh64_elf_cr_type sh64_get_contents_type
+ (asection *, bfd_vma, sh64_elf_crange *);
+
+/* Simpler interface.
+ FIXME: This seems redundant now that we export the interface above. */
+extern bfd_boolean sh64_address_is_shmedia
+ (asection *, bfd_vma);
+
+extern int _bfd_sh64_crange_qsort_cmpb
+ (const void *, const void *);
+extern int _bfd_sh64_crange_qsort_cmpl
+ (const void *, const void *);
+extern int _bfd_sh64_crange_bsearch_cmpb
+ (const void *, const void *);
+extern int _bfd_sh64_crange_bsearch_cmpl
+ (const void *, const void *);
+
+struct sh64_section_data
+{
+ flagword contents_flags;
+
+ /* Only used in the cranges section, but we don't have an official
+ backend-specific bfd field. */
+ bfd_size_type cranges_growth;
+};
+
+struct _sh64_elf_section_data
+{
+ struct bfd_elf_section_data elf;
+ struct sh64_section_data *sh64_info;
+};
+
+#define sh64_elf_section_data(sec) \
+ ((struct _sh64_elf_section_data *) elf_section_data (sec))
+
+#endif /* ELF32_SH64_H */
diff --git a/bfd/elf32-sparc.c b/bfd/elf32-sparc.c
new file mode 100644
index 0000000..b2a1f0f
--- /dev/null
+++ b/bfd/elf32-sparc.c
@@ -0,0 +1,330 @@
+/* SPARC-specific support for 32-bit ELF
+ Copyright (C) 1993-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "bfdlink.h"
+#include "libbfd.h"
+#include "elf-bfd.h"
+#include "elf/sparc.h"
+#include "opcode/sparc.h"
+#include "elfxx-sparc.h"
+#include "elf-vxworks.h"
+
+/* Support for core dump NOTE sections. */
+
+static bfd_boolean
+elf32_sparc_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
+{
+ switch (note->descsz)
+ {
+ default:
+ return FALSE;
+
+ case 260: /* Solaris prpsinfo_t. */
+ elf_tdata (abfd)->core->program
+ = _bfd_elfcore_strndup (abfd, note->descdata + 84, 16);
+ elf_tdata (abfd)->core->command
+ = _bfd_elfcore_strndup (abfd, note->descdata + 100, 80);
+ break;
+
+ case 336: /* Solaris psinfo_t. */
+ elf_tdata (abfd)->core->program
+ = _bfd_elfcore_strndup (abfd, note->descdata + 88, 16);
+ elf_tdata (abfd)->core->command
+ = _bfd_elfcore_strndup (abfd, note->descdata + 104, 80);
+ break;
+ }
+
+ 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 bfd_boolean
+elf32_sparc_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
+{
+ bfd_boolean error;
+ unsigned long ibfd_mach;
+ /* FIXME: This should not be static. */
+ static unsigned long previous_ibfd_e_flags = (unsigned long) -1;
+
+ if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
+ || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
+ return TRUE;
+
+ error = FALSE;
+
+ ibfd_mach = bfd_get_mach (ibfd);
+ if (bfd_mach_sparc_64bit_p (ibfd_mach))
+ {
+ error = TRUE;
+ (*_bfd_error_handler)
+ (_("%B: compiled for a 64 bit system and target is 32 bit"), ibfd);
+ }
+ else if ((ibfd->flags & DYNAMIC) == 0)
+ {
+ if (bfd_get_mach (obfd) < ibfd_mach)
+ bfd_set_arch_mach (obfd, bfd_arch_sparc, ibfd_mach);
+ }
+
+ if (((elf_elfheader (ibfd)->e_flags & EF_SPARC_LEDATA)
+ != previous_ibfd_e_flags)
+ && previous_ibfd_e_flags != (unsigned long) -1)
+ {
+ (*_bfd_error_handler)
+ (_("%B: linking little endian files with big endian files"), 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 _bfd_sparc_elf_merge_private_bfd_data (ibfd, obfd);
+}
+
+/* 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 (bfd *abfd,
+ bfd_boolean linker ATTRIBUTE_UNUSED)
+{
+ switch (bfd_get_mach (abfd))
+ {
+ case bfd_mach_sparc :
+ case bfd_mach_sparc_sparclet :
+ case bfd_mach_sparc_sparclite :
+ 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_v8plusb :
+ 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
+ | EF_SPARC_SUN_US3;
+ break;
+ case bfd_mach_sparc_sparclite_le :
+ elf_elfheader (abfd)->e_flags |= EF_SPARC_LEDATA;
+ break;
+ default :
+ abort ();
+ break;
+ }
+}
+
+static enum elf_reloc_type_class
+elf32_sparc_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ const asection *rel_sec ATTRIBUTE_UNUSED,
+ const Elf_Internal_Rela *rela)
+{
+ switch ((int) ELF32_R_TYPE (rela->r_info))
+ {
+ case R_SPARC_RELATIVE:
+ return reloc_class_relative;
+ case R_SPARC_JMP_SLOT:
+ return reloc_class_plt;
+ case R_SPARC_COPY:
+ return reloc_class_copy;
+ default:
+ return reloc_class_normal;
+ }
+}
+
+/* Hook called by the linker routine which adds symbols from an object
+ file. */
+
+static bfd_boolean
+elf32_sparc_add_symbol_hook (bfd * abfd,
+ struct bfd_link_info * info,
+ Elf_Internal_Sym * sym,
+ const char ** namep ATTRIBUTE_UNUSED,
+ flagword * flagsp ATTRIBUTE_UNUSED,
+ asection ** secp ATTRIBUTE_UNUSED,
+ bfd_vma * valp ATTRIBUTE_UNUSED)
+{
+ if ((ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC
+ || ELF_ST_BIND (sym->st_info) == STB_GNU_UNIQUE)
+ && (abfd->flags & DYNAMIC) == 0
+ && bfd_get_flavour (info->output_bfd) == bfd_target_elf_flavour)
+ elf_tdata (info->output_bfd)->has_gnu_symbols = TRUE;
+ return TRUE;
+}
+
+#define TARGET_BIG_SYM sparc_elf32_vec
+#define TARGET_BIG_NAME "elf32-sparc"
+#define ELF_ARCH bfd_arch_sparc
+#define ELF_TARGET_ID SPARC_ELF_DATA
+#define ELF_MACHINE_CODE EM_SPARC
+#define ELF_MACHINE_ALT1 EM_SPARC32PLUS
+#define ELF_MAXPAGESIZE 0x10000
+#define ELF_COMMONPAGESIZE 0x2000
+
+#define bfd_elf32_bfd_merge_private_bfd_data \
+ elf32_sparc_merge_private_bfd_data
+#define elf_backend_final_write_processing \
+ elf32_sparc_final_write_processing
+#define elf_backend_grok_psinfo elf32_sparc_grok_psinfo
+#define elf_backend_reloc_type_class elf32_sparc_reloc_type_class
+
+#define elf_info_to_howto _bfd_sparc_elf_info_to_howto
+#define bfd_elf32_bfd_reloc_type_lookup _bfd_sparc_elf_reloc_type_lookup
+#define bfd_elf32_bfd_reloc_name_lookup \
+ _bfd_sparc_elf_reloc_name_lookup
+#define bfd_elf32_bfd_link_hash_table_create \
+ _bfd_sparc_elf_link_hash_table_create
+#define bfd_elf32_bfd_relax_section _bfd_sparc_elf_relax_section
+#define bfd_elf32_new_section_hook _bfd_sparc_elf_new_section_hook
+#define elf_backend_copy_indirect_symbol \
+ _bfd_sparc_elf_copy_indirect_symbol
+#define elf_backend_create_dynamic_sections \
+ _bfd_sparc_elf_create_dynamic_sections
+#define elf_backend_check_relocs _bfd_sparc_elf_check_relocs
+#define elf_backend_adjust_dynamic_symbol \
+ _bfd_sparc_elf_adjust_dynamic_symbol
+#define elf_backend_omit_section_dynsym _bfd_sparc_elf_omit_section_dynsym
+#define elf_backend_size_dynamic_sections \
+ _bfd_sparc_elf_size_dynamic_sections
+#define elf_backend_relocate_section _bfd_sparc_elf_relocate_section
+#define elf_backend_finish_dynamic_symbol \
+ _bfd_sparc_elf_finish_dynamic_symbol
+#define elf_backend_finish_dynamic_sections \
+ _bfd_sparc_elf_finish_dynamic_sections
+#define bfd_elf32_mkobject _bfd_sparc_elf_mkobject
+#define elf_backend_object_p _bfd_sparc_elf_object_p
+#define elf_backend_gc_mark_hook _bfd_sparc_elf_gc_mark_hook
+#define elf_backend_gc_sweep_hook _bfd_sparc_elf_gc_sweep_hook
+#define elf_backend_plt_sym_val _bfd_sparc_elf_plt_sym_val
+#define elf_backend_init_index_section _bfd_elf_init_1_index_section
+
+#define elf_backend_can_gc_sections 1
+#define elf_backend_can_refcount 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_rela_normal 1
+
+#define elf_backend_add_symbol_hook elf32_sparc_add_symbol_hook
+
+#include "elf32-target.h"
+
+/* Solaris 2. */
+
+#undef TARGET_BIG_SYM
+#define TARGET_BIG_SYM sparc_elf32_sol2_vec
+#undef TARGET_BIG_NAME
+#define TARGET_BIG_NAME "elf32-sparc-sol2"
+
+#undef elf32_bed
+#define elf32_bed elf32_sparc_sol2_bed
+
+/* The 32-bit static TLS arena size is rounded to the nearest 8-byte
+ boundary. */
+#undef elf_backend_static_tls_alignment
+#define elf_backend_static_tls_alignment 8
+
+#include "elf32-target.h"
+
+/* A wrapper around _bfd_sparc_elf_link_hash_table_create that identifies
+ the target system as VxWorks. */
+
+static struct bfd_link_hash_table *
+elf32_sparc_vxworks_link_hash_table_create (bfd *abfd)
+{
+ struct bfd_link_hash_table *ret;
+
+ ret = _bfd_sparc_elf_link_hash_table_create (abfd);
+ if (ret)
+ {
+ struct _bfd_sparc_elf_link_hash_table *htab;
+
+ htab = (struct _bfd_sparc_elf_link_hash_table *) ret;
+ htab->is_vxworks = 1;
+ }
+ return ret;
+}
+
+/* A final_write_processing hook that does both the SPARC- and VxWorks-
+ specific handling. */
+
+static void
+elf32_sparc_vxworks_final_write_processing (bfd *abfd, bfd_boolean linker)
+{
+ elf32_sparc_final_write_processing (abfd, linker);
+ elf_vxworks_final_write_processing (abfd, linker);
+}
+
+#undef TARGET_BIG_SYM
+#define TARGET_BIG_SYM sparc_elf32_vxworks_vec
+#undef TARGET_BIG_NAME
+#define TARGET_BIG_NAME "elf32-sparc-vxworks"
+
+#undef ELF_MINPAGESIZE
+#define ELF_MINPAGESIZE 0x1000
+
+#undef bfd_elf32_bfd_link_hash_table_create
+#define bfd_elf32_bfd_link_hash_table_create \
+ elf32_sparc_vxworks_link_hash_table_create
+
+#undef elf_backend_want_got_plt
+#define elf_backend_want_got_plt 1
+#undef elf_backend_plt_readonly
+#define elf_backend_plt_readonly 1
+#undef elf_backend_got_header_size
+#define elf_backend_got_header_size 12
+#undef elf_backend_add_symbol_hook
+#define elf_backend_add_symbol_hook \
+ elf_vxworks_add_symbol_hook
+#undef elf_backend_link_output_symbol_hook
+#define elf_backend_link_output_symbol_hook \
+ elf_vxworks_link_output_symbol_hook
+#undef elf_backend_emit_relocs
+#define elf_backend_emit_relocs \
+ elf_vxworks_emit_relocs
+#undef elf_backend_final_write_processing
+#define elf_backend_final_write_processing \
+ elf32_sparc_vxworks_final_write_processing
+#undef elf_backend_static_tls_alignment
+
+#undef elf32_bed
+#define elf32_bed sparc_elf_vxworks_bed
+
+#include "elf32-target.h"
diff --git a/bfd/elf32-spu.c b/bfd/elf32-spu.c
new file mode 100644
index 0000000..13806ad
--- /dev/null
+++ b/bfd/elf32-spu.c
@@ -0,0 +1,5484 @@
+/* SPU specific support for 32-bit ELF
+
+ Copyright (C) 2006-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "libiberty.h"
+#include "bfd.h"
+#include "bfdlink.h"
+#include "libbfd.h"
+#include "elf-bfd.h"
+#include "elf/spu.h"
+#include "elf32-spu.h"
+
+/* We use RELA style relocs. Don't define USE_REL. */
+
+static bfd_reloc_status_type spu_elf_rel9 (bfd *, arelent *, asymbol *,
+ void *, asection *,
+ bfd *, char **);
+
+/* Values of type 'enum elf_spu_reloc_type' are used to index this
+ array, so it must be declared in the order of that type. */
+
+static reloc_howto_type elf_howto_table[] = {
+ HOWTO (R_SPU_NONE, 0, 0, 0, FALSE, 0, complain_overflow_dont,
+ bfd_elf_generic_reloc, "SPU_NONE",
+ FALSE, 0, 0x00000000, FALSE),
+ HOWTO (R_SPU_ADDR10, 4, 2, 10, FALSE, 14, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "SPU_ADDR10",
+ FALSE, 0, 0x00ffc000, FALSE),
+ HOWTO (R_SPU_ADDR16, 2, 2, 16, FALSE, 7, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "SPU_ADDR16",
+ FALSE, 0, 0x007fff80, FALSE),
+ HOWTO (R_SPU_ADDR16_HI, 16, 2, 16, FALSE, 7, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "SPU_ADDR16_HI",
+ FALSE, 0, 0x007fff80, FALSE),
+ HOWTO (R_SPU_ADDR16_LO, 0, 2, 16, FALSE, 7, complain_overflow_dont,
+ bfd_elf_generic_reloc, "SPU_ADDR16_LO",
+ FALSE, 0, 0x007fff80, FALSE),
+ HOWTO (R_SPU_ADDR18, 0, 2, 18, FALSE, 7, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "SPU_ADDR18",
+ FALSE, 0, 0x01ffff80, FALSE),
+ HOWTO (R_SPU_ADDR32, 0, 2, 32, FALSE, 0, complain_overflow_dont,
+ bfd_elf_generic_reloc, "SPU_ADDR32",
+ FALSE, 0, 0xffffffff, FALSE),
+ HOWTO (R_SPU_REL16, 2, 2, 16, TRUE, 7, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "SPU_REL16",
+ FALSE, 0, 0x007fff80, TRUE),
+ HOWTO (R_SPU_ADDR7, 0, 2, 7, FALSE, 14, complain_overflow_dont,
+ bfd_elf_generic_reloc, "SPU_ADDR7",
+ FALSE, 0, 0x001fc000, FALSE),
+ HOWTO (R_SPU_REL9, 2, 2, 9, TRUE, 0, complain_overflow_signed,
+ spu_elf_rel9, "SPU_REL9",
+ FALSE, 0, 0x0180007f, TRUE),
+ HOWTO (R_SPU_REL9I, 2, 2, 9, TRUE, 0, complain_overflow_signed,
+ spu_elf_rel9, "SPU_REL9I",
+ FALSE, 0, 0x0000c07f, TRUE),
+ HOWTO (R_SPU_ADDR10I, 0, 2, 10, FALSE, 14, complain_overflow_signed,
+ bfd_elf_generic_reloc, "SPU_ADDR10I",
+ FALSE, 0, 0x00ffc000, FALSE),
+ HOWTO (R_SPU_ADDR16I, 0, 2, 16, FALSE, 7, complain_overflow_signed,
+ bfd_elf_generic_reloc, "SPU_ADDR16I",
+ FALSE, 0, 0x007fff80, FALSE),
+ HOWTO (R_SPU_REL32, 0, 2, 32, TRUE, 0, complain_overflow_dont,
+ bfd_elf_generic_reloc, "SPU_REL32",
+ FALSE, 0, 0xffffffff, TRUE),
+ HOWTO (R_SPU_ADDR16X, 0, 2, 16, FALSE, 7, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "SPU_ADDR16X",
+ FALSE, 0, 0x007fff80, FALSE),
+ HOWTO (R_SPU_PPU32, 0, 2, 32, FALSE, 0, complain_overflow_dont,
+ bfd_elf_generic_reloc, "SPU_PPU32",
+ FALSE, 0, 0xffffffff, FALSE),
+ HOWTO (R_SPU_PPU64, 0, 4, 64, FALSE, 0, complain_overflow_dont,
+ bfd_elf_generic_reloc, "SPU_PPU64",
+ FALSE, 0, -1, FALSE),
+ HOWTO (R_SPU_ADD_PIC, 0, 0, 0, FALSE, 0, complain_overflow_dont,
+ bfd_elf_generic_reloc, "SPU_ADD_PIC",
+ FALSE, 0, 0x00000000, FALSE),
+};
+
+static struct bfd_elf_special_section const spu_elf_special_sections[] = {
+ { "._ea", 4, 0, SHT_PROGBITS, SHF_WRITE },
+ { ".toe", 4, 0, SHT_NOBITS, SHF_ALLOC },
+ { NULL, 0, 0, 0, 0 }
+};
+
+static enum elf_spu_reloc_type
+spu_elf_bfd_to_reloc_type (bfd_reloc_code_real_type code)
+{
+ switch (code)
+ {
+ default:
+ return R_SPU_NONE;
+ case BFD_RELOC_SPU_IMM10W:
+ return R_SPU_ADDR10;
+ case BFD_RELOC_SPU_IMM16W:
+ return R_SPU_ADDR16;
+ case BFD_RELOC_SPU_LO16:
+ return R_SPU_ADDR16_LO;
+ case BFD_RELOC_SPU_HI16:
+ return R_SPU_ADDR16_HI;
+ case BFD_RELOC_SPU_IMM18:
+ return R_SPU_ADDR18;
+ case BFD_RELOC_SPU_PCREL16:
+ return R_SPU_REL16;
+ case BFD_RELOC_SPU_IMM7:
+ return R_SPU_ADDR7;
+ case BFD_RELOC_SPU_IMM8:
+ return R_SPU_NONE;
+ case BFD_RELOC_SPU_PCREL9a:
+ return R_SPU_REL9;
+ case BFD_RELOC_SPU_PCREL9b:
+ return R_SPU_REL9I;
+ case BFD_RELOC_SPU_IMM10:
+ return R_SPU_ADDR10I;
+ case BFD_RELOC_SPU_IMM16:
+ return R_SPU_ADDR16I;
+ case BFD_RELOC_32:
+ return R_SPU_ADDR32;
+ case BFD_RELOC_32_PCREL:
+ return R_SPU_REL32;
+ case BFD_RELOC_SPU_PPU32:
+ return R_SPU_PPU32;
+ case BFD_RELOC_SPU_PPU64:
+ return R_SPU_PPU64;
+ case BFD_RELOC_SPU_ADD_PIC:
+ return R_SPU_ADD_PIC;
+ }
+}
+
+static void
+spu_elf_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED,
+ arelent *cache_ptr,
+ Elf_Internal_Rela *dst)
+{
+ enum elf_spu_reloc_type r_type;
+
+ r_type = (enum elf_spu_reloc_type) ELF32_R_TYPE (dst->r_info);
+ BFD_ASSERT (r_type < R_SPU_max);
+ cache_ptr->howto = &elf_howto_table[(int) r_type];
+}
+
+static reloc_howto_type *
+spu_elf_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ bfd_reloc_code_real_type code)
+{
+ enum elf_spu_reloc_type r_type = spu_elf_bfd_to_reloc_type (code);
+
+ if (r_type == R_SPU_NONE)
+ return NULL;
+
+ return elf_howto_table + r_type;
+}
+
+static reloc_howto_type *
+spu_elf_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ const char *r_name)
+{
+ unsigned int i;
+
+ for (i = 0; i < sizeof (elf_howto_table) / sizeof (elf_howto_table[0]); i++)
+ if (elf_howto_table[i].name != NULL
+ && strcasecmp (elf_howto_table[i].name, r_name) == 0)
+ return &elf_howto_table[i];
+
+ return NULL;
+}
+
+/* Apply R_SPU_REL9 and R_SPU_REL9I relocs. */
+
+static bfd_reloc_status_type
+spu_elf_rel9 (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
+ void *data, asection *input_section,
+ bfd *output_bfd, char **error_message)
+{
+ bfd_size_type octets;
+ bfd_vma val;
+ long insn;
+
+ /* If this is a relocatable link (output_bfd test tells us), just
+ call the generic function. Any adjustment will be done at final
+ link time. */
+ if (output_bfd != NULL)
+ return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
+ input_section, output_bfd, error_message);
+
+ if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
+ return bfd_reloc_outofrange;
+ octets = reloc_entry->address * bfd_octets_per_byte (abfd);
+
+ /* Get symbol value. */
+ val = 0;
+ if (!bfd_is_com_section (symbol->section))
+ val = symbol->value;
+ if (symbol->section->output_section)
+ val += symbol->section->output_section->vma;
+
+ val += reloc_entry->addend;
+
+ /* Make it pc-relative. */
+ val -= input_section->output_section->vma + input_section->output_offset;
+
+ val >>= 2;
+ if (val + 256 >= 512)
+ return bfd_reloc_overflow;
+
+ insn = bfd_get_32 (abfd, (bfd_byte *) data + octets);
+
+ /* Move two high bits of value to REL9I and REL9 position.
+ The mask will take care of selecting the right field. */
+ val = (val & 0x7f) | ((val & 0x180) << 7) | ((val & 0x180) << 16);
+ insn &= ~reloc_entry->howto->dst_mask;
+ insn |= val & reloc_entry->howto->dst_mask;
+ bfd_put_32 (abfd, insn, (bfd_byte *) data + octets);
+ return bfd_reloc_ok;
+}
+
+static bfd_boolean
+spu_elf_new_section_hook (bfd *abfd, asection *sec)
+{
+ if (!sec->used_by_bfd)
+ {
+ struct _spu_elf_section_data *sdata;
+
+ sdata = bfd_zalloc (abfd, sizeof (*sdata));
+ if (sdata == NULL)
+ return FALSE;
+ sec->used_by_bfd = sdata;
+ }
+
+ return _bfd_elf_new_section_hook (abfd, sec);
+}
+
+/* Set up overlay info for executables. */
+
+static bfd_boolean
+spu_elf_object_p (bfd *abfd)
+{
+ if ((abfd->flags & (EXEC_P | DYNAMIC)) != 0)
+ {
+ unsigned int i, num_ovl, num_buf;
+ Elf_Internal_Phdr *phdr = elf_tdata (abfd)->phdr;
+ Elf_Internal_Ehdr *ehdr = elf_elfheader (abfd);
+ Elf_Internal_Phdr *last_phdr = NULL;
+
+ for (num_buf = 0, num_ovl = 0, i = 0; i < ehdr->e_phnum; i++, phdr++)
+ if (phdr->p_type == PT_LOAD && (phdr->p_flags & PF_OVERLAY) != 0)
+ {
+ unsigned int j;
+
+ ++num_ovl;
+ if (last_phdr == NULL
+ || ((last_phdr->p_vaddr ^ phdr->p_vaddr) & 0x3ffff) != 0)
+ ++num_buf;
+ last_phdr = phdr;
+ for (j = 1; j < elf_numsections (abfd); j++)
+ {
+ Elf_Internal_Shdr *shdr = elf_elfsections (abfd)[j];
+
+ if (ELF_SECTION_SIZE (shdr, phdr) != 0
+ && ELF_SECTION_IN_SEGMENT (shdr, phdr))
+ {
+ asection *sec = shdr->bfd_section;
+ spu_elf_section_data (sec)->u.o.ovl_index = num_ovl;
+ spu_elf_section_data (sec)->u.o.ovl_buf = num_buf;
+ }
+ }
+ }
+ }
+ return TRUE;
+}
+
+/* Specially mark defined symbols named _EAR_* with BSF_KEEP so that
+ strip --strip-unneeded will not remove them. */
+
+static void
+spu_elf_backend_symbol_processing (bfd *abfd ATTRIBUTE_UNUSED, asymbol *sym)
+{
+ if (sym->name != NULL
+ && sym->section != bfd_abs_section_ptr
+ && strncmp (sym->name, "_EAR_", 5) == 0)
+ sym->flags |= BSF_KEEP;
+}
+
+/* SPU ELF linker hash table. */
+
+struct spu_link_hash_table
+{
+ struct elf_link_hash_table elf;
+
+ struct spu_elf_params *params;
+
+ /* Shortcuts to overlay sections. */
+ asection *ovtab;
+ asection *init;
+ asection *toe;
+ asection **ovl_sec;
+
+ /* Count of stubs in each overlay section. */
+ unsigned int *stub_count;
+
+ /* The stub section for each overlay section. */
+ asection **stub_sec;
+
+ struct elf_link_hash_entry *ovly_entry[2];
+
+ /* Number of overlay buffers. */
+ unsigned int num_buf;
+
+ /* Total number of overlays. */
+ unsigned int num_overlays;
+
+ /* For soft icache. */
+ unsigned int line_size_log2;
+ unsigned int num_lines_log2;
+ unsigned int fromelem_size_log2;
+
+ /* How much memory we have. */
+ unsigned int local_store;
+
+ /* Count of overlay stubs needed in non-overlay area. */
+ unsigned int non_ovly_stub;
+
+ /* Pointer to the fixup section */
+ asection *sfixup;
+
+ /* Set on error. */
+ unsigned int stub_err : 1;
+};
+
+/* Hijack the generic got fields for overlay stub accounting. */
+
+struct got_entry
+{
+ struct got_entry *next;
+ unsigned int ovl;
+ union {
+ bfd_vma addend;
+ bfd_vma br_addr;
+ };
+ bfd_vma stub_addr;
+};
+
+#define spu_hash_table(p) \
+ (elf_hash_table_id ((struct elf_link_hash_table *) ((p)->hash)) \
+ == SPU_ELF_DATA ? ((struct spu_link_hash_table *) ((p)->hash)) : NULL)
+
+struct call_info
+{
+ struct function_info *fun;
+ struct call_info *next;
+ unsigned int count;
+ unsigned int max_depth;
+ unsigned int is_tail : 1;
+ unsigned int is_pasted : 1;
+ unsigned int broken_cycle : 1;
+ unsigned int priority : 13;
+};
+
+struct function_info
+{
+ /* List of functions called. Also branches to hot/cold part of
+ function. */
+ struct call_info *call_list;
+ /* For hot/cold part of function, point to owner. */
+ struct function_info *start;
+ /* Symbol at start of function. */
+ union {
+ Elf_Internal_Sym *sym;
+ struct elf_link_hash_entry *h;
+ } u;
+ /* Function section. */
+ asection *sec;
+ asection *rodata;
+ /* Where last called from, and number of sections called from. */
+ asection *last_caller;
+ unsigned int call_count;
+ /* Address range of (this part of) function. */
+ bfd_vma lo, hi;
+ /* Offset where we found a store of lr, or -1 if none found. */
+ bfd_vma lr_store;
+ /* Offset where we found the stack adjustment insn. */
+ bfd_vma sp_adjust;
+ /* Stack usage. */
+ int stack;
+ /* Distance from root of call tree. Tail and hot/cold branches
+ count as one deeper. We aren't counting stack frames here. */
+ unsigned int depth;
+ /* Set if global symbol. */
+ unsigned int global : 1;
+ /* Set if known to be start of function (as distinct from a hunk
+ in hot/cold section. */
+ unsigned int is_func : 1;
+ /* Set if not a root node. */
+ unsigned int non_root : 1;
+ /* Flags used during call tree traversal. It's cheaper to replicate
+ the visit flags than have one which needs clearing after a traversal. */
+ unsigned int visit1 : 1;
+ unsigned int visit2 : 1;
+ unsigned int marking : 1;
+ unsigned int visit3 : 1;
+ unsigned int visit4 : 1;
+ unsigned int visit5 : 1;
+ unsigned int visit6 : 1;
+ unsigned int visit7 : 1;
+};
+
+struct spu_elf_stack_info
+{
+ int num_fun;
+ int max_fun;
+ /* Variable size array describing functions, one per contiguous
+ address range belonging to a function. */
+ struct function_info fun[1];
+};
+
+static struct function_info *find_function (asection *, bfd_vma,
+ struct bfd_link_info *);
+
+/* Create a spu ELF linker hash table. */
+
+static struct bfd_link_hash_table *
+spu_elf_link_hash_table_create (bfd *abfd)
+{
+ struct spu_link_hash_table *htab;
+
+ htab = bfd_zmalloc (sizeof (*htab));
+ if (htab == NULL)
+ return NULL;
+
+ if (!_bfd_elf_link_hash_table_init (&htab->elf, abfd,
+ _bfd_elf_link_hash_newfunc,
+ sizeof (struct elf_link_hash_entry),
+ SPU_ELF_DATA))
+ {
+ free (htab);
+ return NULL;
+ }
+
+ htab->elf.init_got_refcount.refcount = 0;
+ htab->elf.init_got_refcount.glist = NULL;
+ htab->elf.init_got_offset.offset = 0;
+ htab->elf.init_got_offset.glist = NULL;
+ return &htab->elf.root;
+}
+
+void
+spu_elf_setup (struct bfd_link_info *info, struct spu_elf_params *params)
+{
+ bfd_vma max_branch_log2;
+
+ struct spu_link_hash_table *htab = spu_hash_table (info);
+ htab->params = params;
+ htab->line_size_log2 = bfd_log2 (htab->params->line_size);
+ htab->num_lines_log2 = bfd_log2 (htab->params->num_lines);
+
+ /* For the software i-cache, we provide a "from" list whose size
+ is a power-of-two number of quadwords, big enough to hold one
+ byte per outgoing branch. Compute this number here. */
+ max_branch_log2 = bfd_log2 (htab->params->max_branch);
+ htab->fromelem_size_log2 = max_branch_log2 > 4 ? max_branch_log2 - 4 : 0;
+}
+
+/* Find the symbol for the given R_SYMNDX in IBFD and set *HP and *SYMP
+ to (hash, NULL) for global symbols, and (NULL, sym) for locals. Set
+ *SYMSECP to the symbol's section. *LOCSYMSP caches local syms. */
+
+static bfd_boolean
+get_sym_h (struct elf_link_hash_entry **hp,
+ Elf_Internal_Sym **symp,
+ asection **symsecp,
+ Elf_Internal_Sym **locsymsp,
+ unsigned long r_symndx,
+ bfd *ibfd)
+{
+ Elf_Internal_Shdr *symtab_hdr = &elf_tdata (ibfd)->symtab_hdr;
+
+ if (r_symndx >= symtab_hdr->sh_info)
+ {
+ struct elf_link_hash_entry **sym_hashes = elf_sym_hashes (ibfd);
+ struct elf_link_hash_entry *h;
+
+ 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 (hp != NULL)
+ *hp = h;
+
+ if (symp != NULL)
+ *symp = NULL;
+
+ if (symsecp != NULL)
+ {
+ asection *symsec = NULL;
+ if (h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak)
+ symsec = h->root.u.def.section;
+ *symsecp = symsec;
+ }
+ }
+ else
+ {
+ Elf_Internal_Sym *sym;
+ Elf_Internal_Sym *locsyms = *locsymsp;
+
+ if (locsyms == NULL)
+ {
+ locsyms = (Elf_Internal_Sym *) symtab_hdr->contents;
+ if (locsyms == NULL)
+ locsyms = bfd_elf_get_elf_syms (ibfd, symtab_hdr,
+ symtab_hdr->sh_info,
+ 0, NULL, NULL, NULL);
+ if (locsyms == NULL)
+ return FALSE;
+ *locsymsp = locsyms;
+ }
+ sym = locsyms + r_symndx;
+
+ if (hp != NULL)
+ *hp = NULL;
+
+ if (symp != NULL)
+ *symp = sym;
+
+ if (symsecp != NULL)
+ *symsecp = bfd_section_from_elf_index (ibfd, sym->st_shndx);
+ }
+
+ return TRUE;
+}
+
+/* Create the note section if not already present. This is done early so
+ that the linker maps the sections to the right place in the output. */
+
+bfd_boolean
+spu_elf_create_sections (struct bfd_link_info *info)
+{
+ struct spu_link_hash_table *htab = spu_hash_table (info);
+ bfd *ibfd;
+
+ for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next)
+ if (bfd_get_section_by_name (ibfd, SPU_PTNOTE_SPUNAME) != NULL)
+ break;
+
+ if (ibfd == NULL)
+ {
+ /* Make SPU_PTNOTE_SPUNAME section. */
+ asection *s;
+ size_t name_len;
+ size_t size;
+ bfd_byte *data;
+ flagword flags;
+
+ ibfd = info->input_bfds;
+ flags = SEC_LOAD | SEC_READONLY | SEC_HAS_CONTENTS | SEC_IN_MEMORY;
+ s = bfd_make_section_anyway_with_flags (ibfd, SPU_PTNOTE_SPUNAME, flags);
+ if (s == NULL
+ || !bfd_set_section_alignment (ibfd, s, 4))
+ return FALSE;
+
+ name_len = strlen (bfd_get_filename (info->output_bfd)) + 1;
+ size = 12 + ((sizeof (SPU_PLUGIN_NAME) + 3) & -4);
+ size += (name_len + 3) & -4;
+
+ if (!bfd_set_section_size (ibfd, s, size))
+ return FALSE;
+
+ data = bfd_zalloc (ibfd, size);
+ if (data == NULL)
+ return FALSE;
+
+ bfd_put_32 (ibfd, sizeof (SPU_PLUGIN_NAME), data + 0);
+ bfd_put_32 (ibfd, name_len, data + 4);
+ bfd_put_32 (ibfd, 1, data + 8);
+ memcpy (data + 12, SPU_PLUGIN_NAME, sizeof (SPU_PLUGIN_NAME));
+ memcpy (data + 12 + ((sizeof (SPU_PLUGIN_NAME) + 3) & -4),
+ bfd_get_filename (info->output_bfd), name_len);
+ s->contents = data;
+ }
+
+ if (htab->params->emit_fixups)
+ {
+ asection *s;
+ flagword flags;
+
+ if (htab->elf.dynobj == NULL)
+ htab->elf.dynobj = ibfd;
+ ibfd = htab->elf.dynobj;
+ flags = (SEC_LOAD | SEC_ALLOC | SEC_READONLY | SEC_HAS_CONTENTS
+ | SEC_IN_MEMORY | SEC_LINKER_CREATED);
+ s = bfd_make_section_anyway_with_flags (ibfd, ".fixup", flags);
+ if (s == NULL || !bfd_set_section_alignment (ibfd, s, 2))
+ return FALSE;
+ htab->sfixup = s;
+ }
+
+ return TRUE;
+}
+
+/* qsort predicate to sort sections by vma. */
+
+static int
+sort_sections (const void *a, const void *b)
+{
+ const asection *const *s1 = a;
+ const asection *const *s2 = b;
+ bfd_signed_vma delta = (*s1)->vma - (*s2)->vma;
+
+ if (delta != 0)
+ return delta < 0 ? -1 : 1;
+
+ return (*s1)->index - (*s2)->index;
+}
+
+/* Identify overlays in the output bfd, and number them.
+ Returns 0 on error, 1 if no overlays, 2 if overlays. */
+
+int
+spu_elf_find_overlays (struct bfd_link_info *info)
+{
+ struct spu_link_hash_table *htab = spu_hash_table (info);
+ asection **alloc_sec;
+ unsigned int i, n, ovl_index, num_buf;
+ asection *s;
+ bfd_vma ovl_end;
+ static const char *const entry_names[2][2] = {
+ { "__ovly_load", "__icache_br_handler" },
+ { "__ovly_return", "__icache_call_handler" }
+ };
+
+ if (info->output_bfd->section_count < 2)
+ return 1;
+
+ alloc_sec
+ = bfd_malloc (info->output_bfd->section_count * sizeof (*alloc_sec));
+ if (alloc_sec == NULL)
+ return 0;
+
+ /* Pick out all the alloced sections. */
+ for (n = 0, s = info->output_bfd->sections; s != NULL; s = s->next)
+ if ((s->flags & SEC_ALLOC) != 0
+ && (s->flags & (SEC_LOAD | SEC_THREAD_LOCAL)) != SEC_THREAD_LOCAL
+ && s->size != 0)
+ alloc_sec[n++] = s;
+
+ if (n == 0)
+ {
+ free (alloc_sec);
+ return 1;
+ }
+
+ /* Sort them by vma. */
+ qsort (alloc_sec, n, sizeof (*alloc_sec), sort_sections);
+
+ ovl_end = alloc_sec[0]->vma + alloc_sec[0]->size;
+ if (htab->params->ovly_flavour == ovly_soft_icache)
+ {
+ unsigned int prev_buf = 0, set_id = 0;
+
+ /* Look for an overlapping vma to find the first overlay section. */
+ bfd_vma vma_start = 0;
+
+ for (i = 1; i < n; i++)
+ {
+ s = alloc_sec[i];
+ if (s->vma < ovl_end)
+ {
+ asection *s0 = alloc_sec[i - 1];
+ vma_start = s0->vma;
+ ovl_end = (s0->vma
+ + ((bfd_vma) 1
+ << (htab->num_lines_log2 + htab->line_size_log2)));
+ --i;
+ break;
+ }
+ else
+ ovl_end = s->vma + s->size;
+ }
+
+ /* Now find any sections within the cache area. */
+ for (ovl_index = 0, num_buf = 0; i < n; i++)
+ {
+ s = alloc_sec[i];
+ if (s->vma >= ovl_end)
+ break;
+
+ /* A section in an overlay area called .ovl.init is not
+ an overlay, in the sense that it might be loaded in
+ by the overlay manager, but rather the initial
+ section contents for the overlay buffer. */
+ if (strncmp (s->name, ".ovl.init", 9) != 0)
+ {
+ num_buf = ((s->vma - vma_start) >> htab->line_size_log2) + 1;
+ set_id = (num_buf == prev_buf)? set_id + 1 : 0;
+ prev_buf = num_buf;
+
+ if ((s->vma - vma_start) & (htab->params->line_size - 1))
+ {
+ info->callbacks->einfo (_("%X%P: overlay section %A "
+ "does not start on a cache line.\n"),
+ s);
+ bfd_set_error (bfd_error_bad_value);
+ return 0;
+ }
+ else if (s->size > htab->params->line_size)
+ {
+ info->callbacks->einfo (_("%X%P: overlay section %A "
+ "is larger than a cache line.\n"),
+ s);
+ bfd_set_error (bfd_error_bad_value);
+ return 0;
+ }
+
+ alloc_sec[ovl_index++] = s;
+ spu_elf_section_data (s)->u.o.ovl_index
+ = (set_id << htab->num_lines_log2) + num_buf;
+ spu_elf_section_data (s)->u.o.ovl_buf = num_buf;
+ }
+ }
+
+ /* Ensure there are no more overlay sections. */
+ for ( ; i < n; i++)
+ {
+ s = alloc_sec[i];
+ if (s->vma < ovl_end)
+ {
+ info->callbacks->einfo (_("%X%P: overlay section %A "
+ "is not in cache area.\n"),
+ alloc_sec[i-1]);
+ bfd_set_error (bfd_error_bad_value);
+ return 0;
+ }
+ else
+ ovl_end = s->vma + s->size;
+ }
+ }
+ else
+ {
+ /* Look for overlapping vmas. Any with overlap must be overlays.
+ Count them. Also count the number of overlay regions. */
+ for (ovl_index = 0, num_buf = 0, i = 1; i < n; i++)
+ {
+ s = alloc_sec[i];
+ if (s->vma < ovl_end)
+ {
+ asection *s0 = alloc_sec[i - 1];
+
+ if (spu_elf_section_data (s0)->u.o.ovl_index == 0)
+ {
+ ++num_buf;
+ if (strncmp (s0->name, ".ovl.init", 9) != 0)
+ {
+ alloc_sec[ovl_index] = s0;
+ spu_elf_section_data (s0)->u.o.ovl_index = ++ovl_index;
+ spu_elf_section_data (s0)->u.o.ovl_buf = num_buf;
+ }
+ else
+ ovl_end = s->vma + s->size;
+ }
+ if (strncmp (s->name, ".ovl.init", 9) != 0)
+ {
+ alloc_sec[ovl_index] = s;
+ spu_elf_section_data (s)->u.o.ovl_index = ++ovl_index;
+ spu_elf_section_data (s)->u.o.ovl_buf = num_buf;
+ if (s0->vma != s->vma)
+ {
+ info->callbacks->einfo (_("%X%P: overlay sections %A "
+ "and %A do not start at the "
+ "same address.\n"),
+ s0, s);
+ bfd_set_error (bfd_error_bad_value);
+ return 0;
+ }
+ if (ovl_end < s->vma + s->size)
+ ovl_end = s->vma + s->size;
+ }
+ }
+ else
+ ovl_end = s->vma + s->size;
+ }
+ }
+
+ htab->num_overlays = ovl_index;
+ htab->num_buf = num_buf;
+ htab->ovl_sec = alloc_sec;
+
+ if (ovl_index == 0)
+ return 1;
+
+ for (i = 0; i < 2; i++)
+ {
+ const char *name;
+ struct elf_link_hash_entry *h;
+
+ name = entry_names[i][htab->params->ovly_flavour];
+ h = elf_link_hash_lookup (&htab->elf, name, TRUE, FALSE, FALSE);
+ if (h == NULL)
+ return 0;
+
+ if (h->root.type == bfd_link_hash_new)
+ {
+ h->root.type = bfd_link_hash_undefined;
+ h->ref_regular = 1;
+ h->ref_regular_nonweak = 1;
+ h->non_elf = 0;
+ }
+ htab->ovly_entry[i] = h;
+ }
+
+ return 2;
+}
+
+/* Non-zero to use bra in overlay stubs rather than br. */
+#define BRA_STUBS 0
+
+#define BRA 0x30000000
+#define BRASL 0x31000000
+#define BR 0x32000000
+#define BRSL 0x33000000
+#define NOP 0x40200000
+#define LNOP 0x00200000
+#define ILA 0x42000000
+
+/* Return true for all relative and absolute branch instructions.
+ bra 00110000 0..
+ brasl 00110001 0..
+ br 00110010 0..
+ brsl 00110011 0..
+ brz 00100000 0..
+ brnz 00100001 0..
+ brhz 00100010 0..
+ brhnz 00100011 0.. */
+
+static bfd_boolean
+is_branch (const unsigned char *insn)
+{
+ return (insn[0] & 0xec) == 0x20 && (insn[1] & 0x80) == 0;
+}
+
+/* Return true for all indirect branch instructions.
+ bi 00110101 000
+ bisl 00110101 001
+ iret 00110101 010
+ bisled 00110101 011
+ biz 00100101 000
+ binz 00100101 001
+ bihz 00100101 010
+ bihnz 00100101 011 */
+
+static bfd_boolean
+is_indirect_branch (const unsigned char *insn)
+{
+ return (insn[0] & 0xef) == 0x25 && (insn[1] & 0x80) == 0;
+}
+
+/* Return true for branch hint instructions.
+ hbra 0001000..
+ hbrr 0001001.. */
+
+static bfd_boolean
+is_hint (const unsigned char *insn)
+{
+ return (insn[0] & 0xfc) == 0x10;
+}
+
+/* True if INPUT_SECTION might need overlay stubs. */
+
+static bfd_boolean
+maybe_needs_stubs (asection *input_section)
+{
+ /* No stubs for debug sections and suchlike. */
+ if ((input_section->flags & SEC_ALLOC) == 0)
+ return FALSE;
+
+ /* No stubs for link-once sections that will be discarded. */
+ if (input_section->output_section == bfd_abs_section_ptr)
+ return FALSE;
+
+ /* Don't create stubs for .eh_frame references. */
+ if (strcmp (input_section->name, ".eh_frame") == 0)
+ return FALSE;
+
+ return TRUE;
+}
+
+enum _stub_type
+{
+ no_stub,
+ call_ovl_stub,
+ br000_ovl_stub,
+ br001_ovl_stub,
+ br010_ovl_stub,
+ br011_ovl_stub,
+ br100_ovl_stub,
+ br101_ovl_stub,
+ br110_ovl_stub,
+ br111_ovl_stub,
+ nonovl_stub,
+ stub_error
+};
+
+/* Return non-zero if this reloc symbol should go via an overlay stub.
+ Return 2 if the stub must be in non-overlay area. */
+
+static enum _stub_type
+needs_ovl_stub (struct elf_link_hash_entry *h,
+ Elf_Internal_Sym *sym,
+ asection *sym_sec,
+ asection *input_section,
+ Elf_Internal_Rela *irela,
+ bfd_byte *contents,
+ struct bfd_link_info *info)
+{
+ struct spu_link_hash_table *htab = spu_hash_table (info);
+ enum elf_spu_reloc_type r_type;
+ unsigned int sym_type;
+ bfd_boolean branch, hint, call;
+ enum _stub_type ret = no_stub;
+ bfd_byte insn[4];
+
+ if (sym_sec == NULL
+ || sym_sec->output_section == bfd_abs_section_ptr
+ || spu_elf_section_data (sym_sec->output_section) == NULL)
+ return ret;
+
+ if (h != NULL)
+ {
+ /* Ensure no stubs for user supplied overlay manager syms. */
+ if (h == htab->ovly_entry[0] || h == htab->ovly_entry[1])
+ return ret;
+
+ /* setjmp always goes via an overlay stub, because then the return
+ and hence the longjmp goes via __ovly_return. That magically
+ makes setjmp/longjmp between overlays work. */
+ if (strncmp (h->root.root.string, "setjmp", 6) == 0
+ && (h->root.root.string[6] == '\0' || h->root.root.string[6] == '@'))
+ ret = call_ovl_stub;
+ }
+
+ if (h != NULL)
+ sym_type = h->type;
+ else
+ sym_type = ELF_ST_TYPE (sym->st_info);
+
+ r_type = ELF32_R_TYPE (irela->r_info);
+ branch = FALSE;
+ hint = FALSE;
+ call = FALSE;
+ if (r_type == R_SPU_REL16 || r_type == R_SPU_ADDR16)
+ {
+ if (contents == NULL)
+ {
+ contents = insn;
+ if (!bfd_get_section_contents (input_section->owner,
+ input_section,
+ contents,
+ irela->r_offset, 4))
+ return stub_error;
+ }
+ else
+ contents += irela->r_offset;
+
+ branch = is_branch (contents);
+ hint = is_hint (contents);
+ if (branch || hint)
+ {
+ call = (contents[0] & 0xfd) == 0x31;
+ if (call
+ && sym_type != STT_FUNC
+ && contents != insn)
+ {
+ /* It's common for people to write assembly and forget
+ to give function symbols the right type. Handle
+ calls to such symbols, but warn so that (hopefully)
+ people will fix their code. We need the symbol
+ type to be correct to distinguish function pointer
+ initialisation from other pointer initialisations. */
+ const char *sym_name;
+
+ if (h != NULL)
+ sym_name = h->root.root.string;
+ else
+ {
+ Elf_Internal_Shdr *symtab_hdr;
+ symtab_hdr = &elf_tdata (input_section->owner)->symtab_hdr;
+ sym_name = bfd_elf_sym_name (input_section->owner,
+ symtab_hdr,
+ sym,
+ sym_sec);
+ }
+ (*_bfd_error_handler) (_("warning: call to non-function"
+ " symbol %s defined in %B"),
+ sym_sec->owner, sym_name);
+
+ }
+ }
+ }
+
+ if ((!branch && htab->params->ovly_flavour == ovly_soft_icache)
+ || (sym_type != STT_FUNC
+ && !(branch || hint)
+ && (sym_sec->flags & SEC_CODE) == 0))
+ return no_stub;
+
+ /* Usually, symbols in non-overlay sections don't need stubs. */
+ if (spu_elf_section_data (sym_sec->output_section)->u.o.ovl_index == 0
+ && !htab->params->non_overlay_stubs)
+ return ret;
+
+ /* A reference from some other section to a symbol in an overlay
+ section needs a stub. */
+ if (spu_elf_section_data (sym_sec->output_section)->u.o.ovl_index
+ != spu_elf_section_data (input_section->output_section)->u.o.ovl_index)
+ {
+ unsigned int lrlive = 0;
+ if (branch)
+ lrlive = (contents[1] & 0x70) >> 4;
+
+ if (!lrlive && (call || sym_type == STT_FUNC))
+ ret = call_ovl_stub;
+ else
+ ret = br000_ovl_stub + lrlive;
+ }
+
+ /* If this insn isn't a branch then we are possibly taking the
+ address of a function and passing it out somehow. Soft-icache code
+ always generates inline code to do indirect branches. */
+ if (!(branch || hint)
+ && sym_type == STT_FUNC
+ && htab->params->ovly_flavour != ovly_soft_icache)
+ ret = nonovl_stub;
+
+ return ret;
+}
+
+static bfd_boolean
+count_stub (struct spu_link_hash_table *htab,
+ bfd *ibfd,
+ asection *isec,
+ enum _stub_type stub_type,
+ struct elf_link_hash_entry *h,
+ const Elf_Internal_Rela *irela)
+{
+ unsigned int ovl = 0;
+ struct got_entry *g, **head;
+ bfd_vma addend;
+
+ /* If this instruction is a branch or call, we need a stub
+ for it. One stub per function per overlay.
+ If it isn't a branch, then we are taking the address of
+ this function so need a stub in the non-overlay area
+ for it. One stub per function. */
+ if (stub_type != nonovl_stub)
+ ovl = spu_elf_section_data (isec->output_section)->u.o.ovl_index;
+
+ if (h != NULL)
+ head = &h->got.glist;
+ else
+ {
+ if (elf_local_got_ents (ibfd) == NULL)
+ {
+ bfd_size_type amt = (elf_tdata (ibfd)->symtab_hdr.sh_info
+ * sizeof (*elf_local_got_ents (ibfd)));
+ elf_local_got_ents (ibfd) = bfd_zmalloc (amt);
+ if (elf_local_got_ents (ibfd) == NULL)
+ return FALSE;
+ }
+ head = elf_local_got_ents (ibfd) + ELF32_R_SYM (irela->r_info);
+ }
+
+ if (htab->params->ovly_flavour == ovly_soft_icache)
+ {
+ htab->stub_count[ovl] += 1;
+ return TRUE;
+ }
+
+ addend = 0;
+ if (irela != NULL)
+ addend = irela->r_addend;
+
+ if (ovl == 0)
+ {
+ struct got_entry *gnext;
+
+ for (g = *head; g != NULL; g = g->next)
+ if (g->addend == addend && g->ovl == 0)
+ break;
+
+ if (g == NULL)
+ {
+ /* Need a new non-overlay area stub. Zap other stubs. */
+ for (g = *head; g != NULL; g = gnext)
+ {
+ gnext = g->next;
+ if (g->addend == addend)
+ {
+ htab->stub_count[g->ovl] -= 1;
+ free (g);
+ }
+ }
+ }
+ }
+ else
+ {
+ for (g = *head; g != NULL; g = g->next)
+ if (g->addend == addend && (g->ovl == ovl || g->ovl == 0))
+ break;
+ }
+
+ if (g == NULL)
+ {
+ g = bfd_malloc (sizeof *g);
+ if (g == NULL)
+ return FALSE;
+ g->ovl = ovl;
+ g->addend = addend;
+ g->stub_addr = (bfd_vma) -1;
+ g->next = *head;
+ *head = g;
+
+ htab->stub_count[ovl] += 1;
+ }
+
+ return TRUE;
+}
+
+/* Support two sizes of overlay stubs, a slower more compact stub of two
+ instructions, and a faster stub of four instructions.
+ Soft-icache stubs are four or eight words. */
+
+static unsigned int
+ovl_stub_size (struct spu_elf_params *params)
+{
+ return 16 << params->ovly_flavour >> params->compact_stub;
+}
+
+static unsigned int
+ovl_stub_size_log2 (struct spu_elf_params *params)
+{
+ return 4 + params->ovly_flavour - params->compact_stub;
+}
+
+/* Two instruction overlay stubs look like:
+
+ brsl $75,__ovly_load
+ .word target_ovl_and_address
+
+ ovl_and_address is a word with the overlay number in the top 14 bits
+ and local store address in the bottom 18 bits.
+
+ Four instruction overlay stubs look like:
+
+ ila $78,ovl_number
+ lnop
+ ila $79,target_address
+ br __ovly_load
+
+ Software icache stubs are:
+
+ .word target_index
+ .word target_ia;
+ .word lrlive_branchlocalstoreaddr;
+ brasl $75,__icache_br_handler
+ .quad xor_pattern
+*/
+
+static bfd_boolean
+build_stub (struct bfd_link_info *info,
+ bfd *ibfd,
+ asection *isec,
+ enum _stub_type stub_type,
+ struct elf_link_hash_entry *h,
+ const Elf_Internal_Rela *irela,
+ bfd_vma dest,
+ asection *dest_sec)
+{
+ struct spu_link_hash_table *htab = spu_hash_table (info);
+ unsigned int ovl, dest_ovl, set_id;
+ struct got_entry *g, **head;
+ asection *sec;
+ bfd_vma addend, from, to, br_dest, patt;
+ unsigned int lrlive;
+
+ ovl = 0;
+ if (stub_type != nonovl_stub)
+ ovl = spu_elf_section_data (isec->output_section)->u.o.ovl_index;
+
+ if (h != NULL)
+ head = &h->got.glist;
+ else
+ head = elf_local_got_ents (ibfd) + ELF32_R_SYM (irela->r_info);
+
+ addend = 0;
+ if (irela != NULL)
+ addend = irela->r_addend;
+
+ if (htab->params->ovly_flavour == ovly_soft_icache)
+ {
+ g = bfd_malloc (sizeof *g);
+ if (g == NULL)
+ return FALSE;
+ g->ovl = ovl;
+ g->br_addr = 0;
+ if (irela != NULL)
+ g->br_addr = (irela->r_offset
+ + isec->output_offset
+ + isec->output_section->vma);
+ g->next = *head;
+ *head = g;
+ }
+ else
+ {
+ for (g = *head; g != NULL; g = g->next)
+ if (g->addend == addend && (g->ovl == ovl || g->ovl == 0))
+ break;
+ if (g == NULL)
+ abort ();
+
+ if (g->ovl == 0 && ovl != 0)
+ return TRUE;
+
+ if (g->stub_addr != (bfd_vma) -1)
+ return TRUE;
+ }
+
+ sec = htab->stub_sec[ovl];
+ dest += dest_sec->output_offset + dest_sec->output_section->vma;
+ from = sec->size + sec->output_offset + sec->output_section->vma;
+ g->stub_addr = from;
+ to = (htab->ovly_entry[0]->root.u.def.value
+ + htab->ovly_entry[0]->root.u.def.section->output_offset
+ + htab->ovly_entry[0]->root.u.def.section->output_section->vma);
+
+ if (((dest | to | from) & 3) != 0)
+ {
+ htab->stub_err = 1;
+ return FALSE;
+ }
+ dest_ovl = spu_elf_section_data (dest_sec->output_section)->u.o.ovl_index;
+
+ if (htab->params->ovly_flavour == ovly_normal
+ && !htab->params->compact_stub)
+ {
+ bfd_put_32 (sec->owner, ILA + ((dest_ovl << 7) & 0x01ffff80) + 78,
+ sec->contents + sec->size);
+ bfd_put_32 (sec->owner, LNOP,
+ sec->contents + sec->size + 4);
+ bfd_put_32 (sec->owner, ILA + ((dest << 7) & 0x01ffff80) + 79,
+ sec->contents + sec->size + 8);
+ if (!BRA_STUBS)
+ bfd_put_32 (sec->owner, BR + (((to - (from + 12)) << 5) & 0x007fff80),
+ sec->contents + sec->size + 12);
+ else
+ bfd_put_32 (sec->owner, BRA + ((to << 5) & 0x007fff80),
+ sec->contents + sec->size + 12);
+ }
+ else if (htab->params->ovly_flavour == ovly_normal
+ && htab->params->compact_stub)
+ {
+ if (!BRA_STUBS)
+ bfd_put_32 (sec->owner, BRSL + (((to - from) << 5) & 0x007fff80) + 75,
+ sec->contents + sec->size);
+ else
+ bfd_put_32 (sec->owner, BRASL + ((to << 5) & 0x007fff80) + 75,
+ sec->contents + sec->size);
+ bfd_put_32 (sec->owner, (dest & 0x3ffff) | (dest_ovl << 18),
+ sec->contents + sec->size + 4);
+ }
+ else if (htab->params->ovly_flavour == ovly_soft_icache
+ && htab->params->compact_stub)
+ {
+ lrlive = 0;
+ if (stub_type == nonovl_stub)
+ ;
+ else if (stub_type == call_ovl_stub)
+ /* A brsl makes lr live and *(*sp+16) is live.
+ Tail calls have the same liveness. */
+ lrlive = 5;
+ else if (!htab->params->lrlive_analysis)
+ /* Assume stack frame and lr save. */
+ lrlive = 1;
+ else if (irela != NULL)
+ {
+ /* Analyse branch instructions. */
+ struct function_info *caller;
+ bfd_vma off;
+
+ caller = find_function (isec, irela->r_offset, info);
+ if (caller->start == NULL)
+ off = irela->r_offset;
+ else
+ {
+ struct function_info *found = NULL;
+
+ /* Find the earliest piece of this function that
+ has frame adjusting instructions. We might
+ see dynamic frame adjustment (eg. for alloca)
+ in some later piece, but functions using
+ alloca always set up a frame earlier. Frame
+ setup instructions are always in one piece. */
+ if (caller->lr_store != (bfd_vma) -1
+ || caller->sp_adjust != (bfd_vma) -1)
+ found = caller;
+ while (caller->start != NULL)
+ {
+ caller = caller->start;
+ if (caller->lr_store != (bfd_vma) -1
+ || caller->sp_adjust != (bfd_vma) -1)
+ found = caller;
+ }
+ if (found != NULL)
+ caller = found;
+ off = (bfd_vma) -1;
+ }
+
+ if (off > caller->sp_adjust)
+ {
+ if (off > caller->lr_store)
+ /* Only *(*sp+16) is live. */
+ lrlive = 1;
+ else
+ /* If no lr save, then we must be in a
+ leaf function with a frame.
+ lr is still live. */
+ lrlive = 4;
+ }
+ else if (off > caller->lr_store)
+ {
+ /* Between lr save and stack adjust. */
+ lrlive = 3;
+ /* This should never happen since prologues won't
+ be split here. */
+ BFD_ASSERT (0);
+ }
+ else
+ /* On entry to function. */
+ lrlive = 5;
+
+ if (stub_type != br000_ovl_stub
+ && lrlive != stub_type - br000_ovl_stub)
+ info->callbacks->einfo (_("%A:0x%v lrlive .brinfo (%u) differs "
+ "from analysis (%u)\n"),
+ isec, irela->r_offset, lrlive,
+ stub_type - br000_ovl_stub);
+ }
+
+ /* If given lrlive info via .brinfo, use it. */
+ if (stub_type > br000_ovl_stub)
+ lrlive = stub_type - br000_ovl_stub;
+
+ if (ovl == 0)
+ to = (htab->ovly_entry[1]->root.u.def.value
+ + htab->ovly_entry[1]->root.u.def.section->output_offset
+ + htab->ovly_entry[1]->root.u.def.section->output_section->vma);
+
+ /* The branch that uses this stub goes to stub_addr + 4. We'll
+ set up an xor pattern that can be used by the icache manager
+ to modify this branch to go directly to its destination. */
+ g->stub_addr += 4;
+ br_dest = g->stub_addr;
+ if (irela == NULL)
+ {
+ /* Except in the case of _SPUEAR_ stubs, the branch in
+ question is the one in the stub itself. */
+ BFD_ASSERT (stub_type == nonovl_stub);
+ g->br_addr = g->stub_addr;
+ br_dest = to;
+ }
+
+ set_id = ((dest_ovl - 1) >> htab->num_lines_log2) + 1;
+ bfd_put_32 (sec->owner, (set_id << 18) | (dest & 0x3ffff),
+ sec->contents + sec->size);
+ bfd_put_32 (sec->owner, BRASL + ((to << 5) & 0x007fff80) + 75,
+ sec->contents + sec->size + 4);
+ bfd_put_32 (sec->owner, (lrlive << 29) | (g->br_addr & 0x3ffff),
+ sec->contents + sec->size + 8);
+ patt = dest ^ br_dest;
+ if (irela != NULL && ELF32_R_TYPE (irela->r_info) == R_SPU_REL16)
+ patt = (dest - g->br_addr) ^ (br_dest - g->br_addr);
+ bfd_put_32 (sec->owner, (patt << 5) & 0x007fff80,
+ sec->contents + sec->size + 12);
+
+ if (ovl == 0)
+ /* Extra space for linked list entries. */
+ sec->size += 16;
+ }
+ else
+ abort ();
+
+ sec->size += ovl_stub_size (htab->params);
+
+ if (htab->params->emit_stub_syms)
+ {
+ size_t len;
+ char *name;
+ int add;
+
+ len = 8 + sizeof (".ovl_call.") - 1;
+ if (h != NULL)
+ len += strlen (h->root.root.string);
+ else
+ len += 8 + 1 + 8;
+ add = 0;
+ if (irela != NULL)
+ add = (int) irela->r_addend & 0xffffffff;
+ if (add != 0)
+ len += 1 + 8;
+ name = bfd_malloc (len + 1);
+ if (name == NULL)
+ return FALSE;
+
+ sprintf (name, "%08x.ovl_call.", g->ovl);
+ if (h != NULL)
+ strcpy (name + 8 + sizeof (".ovl_call.") - 1, h->root.root.string);
+ else
+ sprintf (name + 8 + sizeof (".ovl_call.") - 1, "%x:%x",
+ dest_sec->id & 0xffffffff,
+ (int) ELF32_R_SYM (irela->r_info) & 0xffffffff);
+ if (add != 0)
+ sprintf (name + len - 9, "+%x", add);
+
+ h = elf_link_hash_lookup (&htab->elf, name, TRUE, TRUE, FALSE);
+ free (name);
+ if (h == NULL)
+ return FALSE;
+ if (h->root.type == bfd_link_hash_new)
+ {
+ h->root.type = bfd_link_hash_defined;
+ h->root.u.def.section = sec;
+ h->size = ovl_stub_size (htab->params);
+ h->root.u.def.value = sec->size - h->size;
+ h->type = STT_FUNC;
+ h->ref_regular = 1;
+ h->def_regular = 1;
+ h->ref_regular_nonweak = 1;
+ h->forced_local = 1;
+ h->non_elf = 0;
+ }
+ }
+
+ return TRUE;
+}
+
+/* Called via elf_link_hash_traverse to allocate stubs for any _SPUEAR_
+ symbols. */
+
+static bfd_boolean
+allocate_spuear_stubs (struct elf_link_hash_entry *h, void *inf)
+{
+ /* Symbols starting with _SPUEAR_ need a stub because they may be
+ invoked by the PPU. */
+ struct bfd_link_info *info = inf;
+ struct spu_link_hash_table *htab = spu_hash_table (info);
+ asection *sym_sec;
+
+ if ((h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak)
+ && h->def_regular
+ && strncmp (h->root.root.string, "_SPUEAR_", 8) == 0
+ && (sym_sec = h->root.u.def.section) != NULL
+ && sym_sec->output_section != bfd_abs_section_ptr
+ && spu_elf_section_data (sym_sec->output_section) != NULL
+ && (spu_elf_section_data (sym_sec->output_section)->u.o.ovl_index != 0
+ || htab->params->non_overlay_stubs))
+ {
+ return count_stub (htab, NULL, NULL, nonovl_stub, h, NULL);
+ }
+
+ return TRUE;
+}
+
+static bfd_boolean
+build_spuear_stubs (struct elf_link_hash_entry *h, void *inf)
+{
+ /* Symbols starting with _SPUEAR_ need a stub because they may be
+ invoked by the PPU. */
+ struct bfd_link_info *info = inf;
+ struct spu_link_hash_table *htab = spu_hash_table (info);
+ asection *sym_sec;
+
+ if ((h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak)
+ && h->def_regular
+ && strncmp (h->root.root.string, "_SPUEAR_", 8) == 0
+ && (sym_sec = h->root.u.def.section) != NULL
+ && sym_sec->output_section != bfd_abs_section_ptr
+ && spu_elf_section_data (sym_sec->output_section) != NULL
+ && (spu_elf_section_data (sym_sec->output_section)->u.o.ovl_index != 0
+ || htab->params->non_overlay_stubs))
+ {
+ return build_stub (info, NULL, NULL, nonovl_stub, h, NULL,
+ h->root.u.def.value, sym_sec);
+ }
+
+ return TRUE;
+}
+
+/* Size or build stubs. */
+
+static bfd_boolean
+process_stubs (struct bfd_link_info *info, bfd_boolean build)
+{
+ struct spu_link_hash_table *htab = spu_hash_table (info);
+ bfd *ibfd;
+
+ for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next)
+ {
+ extern const bfd_target spu_elf32_vec;
+ Elf_Internal_Shdr *symtab_hdr;
+ asection *isec;
+ Elf_Internal_Sym *local_syms = NULL;
+
+ if (ibfd->xvec != &spu_elf32_vec)
+ continue;
+
+ /* We'll need the symbol table in a second. */
+ symtab_hdr = &elf_tdata (ibfd)->symtab_hdr;
+ if (symtab_hdr->sh_info == 0)
+ continue;
+
+ /* Walk over each section attached to the input bfd. */
+ for (isec = ibfd->sections; isec != NULL; isec = isec->next)
+ {
+ Elf_Internal_Rela *internal_relocs, *irelaend, *irela;
+
+ /* If there aren't any relocs, then there's nothing more to do. */
+ if ((isec->flags & SEC_RELOC) == 0
+ || isec->reloc_count == 0)
+ continue;
+
+ if (!maybe_needs_stubs (isec))
+ continue;
+
+ /* Get the relocs. */
+ internal_relocs = _bfd_elf_link_read_relocs (ibfd, isec, NULL, NULL,
+ info->keep_memory);
+ if (internal_relocs == NULL)
+ goto error_ret_free_local;
+
+ /* Now examine each relocation. */
+ irela = internal_relocs;
+ irelaend = irela + isec->reloc_count;
+ for (; irela < irelaend; irela++)
+ {
+ enum elf_spu_reloc_type r_type;
+ unsigned int r_indx;
+ asection *sym_sec;
+ Elf_Internal_Sym *sym;
+ struct elf_link_hash_entry *h;
+ enum _stub_type stub_type;
+
+ r_type = ELF32_R_TYPE (irela->r_info);
+ r_indx = ELF32_R_SYM (irela->r_info);
+
+ if (r_type >= R_SPU_max)
+ {
+ bfd_set_error (bfd_error_bad_value);
+ error_ret_free_internal:
+ if (elf_section_data (isec)->relocs != internal_relocs)
+ free (internal_relocs);
+ error_ret_free_local:
+ if (local_syms != NULL
+ && (symtab_hdr->contents
+ != (unsigned char *) local_syms))
+ free (local_syms);
+ return FALSE;
+ }
+
+ /* Determine the reloc target section. */
+ if (!get_sym_h (&h, &sym, &sym_sec, &local_syms, r_indx, ibfd))
+ goto error_ret_free_internal;
+
+ stub_type = needs_ovl_stub (h, sym, sym_sec, isec, irela,
+ NULL, info);
+ if (stub_type == no_stub)
+ continue;
+ else if (stub_type == stub_error)
+ goto error_ret_free_internal;
+
+ if (htab->stub_count == NULL)
+ {
+ bfd_size_type amt;
+ amt = (htab->num_overlays + 1) * sizeof (*htab->stub_count);
+ htab->stub_count = bfd_zmalloc (amt);
+ if (htab->stub_count == NULL)
+ goto error_ret_free_internal;
+ }
+
+ if (!build)
+ {
+ if (!count_stub (htab, ibfd, isec, stub_type, h, irela))
+ goto error_ret_free_internal;
+ }
+ else
+ {
+ bfd_vma dest;
+
+ if (h != NULL)
+ dest = h->root.u.def.value;
+ else
+ dest = sym->st_value;
+ dest += irela->r_addend;
+ if (!build_stub (info, ibfd, isec, stub_type, h, irela,
+ dest, sym_sec))
+ goto error_ret_free_internal;
+ }
+ }
+
+ /* We're done with the internal relocs, free them. */
+ if (elf_section_data (isec)->relocs != internal_relocs)
+ free (internal_relocs);
+ }
+
+ if (local_syms != NULL
+ && symtab_hdr->contents != (unsigned char *) local_syms)
+ {
+ if (!info->keep_memory)
+ free (local_syms);
+ else
+ symtab_hdr->contents = (unsigned char *) local_syms;
+ }
+ }
+
+ return TRUE;
+}
+
+/* Allocate space for overlay call and return stubs.
+ Return 0 on error, 1 if no overlays, 2 otherwise. */
+
+int
+spu_elf_size_stubs (struct bfd_link_info *info)
+{
+ struct spu_link_hash_table *htab;
+ bfd *ibfd;
+ bfd_size_type amt;
+ flagword flags;
+ unsigned int i;
+ asection *stub;
+
+ if (!process_stubs (info, FALSE))
+ return 0;
+
+ htab = spu_hash_table (info);
+ elf_link_hash_traverse (&htab->elf, allocate_spuear_stubs, info);
+ if (htab->stub_err)
+ return 0;
+
+ ibfd = info->input_bfds;
+ if (htab->stub_count != NULL)
+ {
+ amt = (htab->num_overlays + 1) * sizeof (*htab->stub_sec);
+ htab->stub_sec = bfd_zmalloc (amt);
+ if (htab->stub_sec == NULL)
+ return 0;
+
+ flags = (SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_READONLY
+ | SEC_HAS_CONTENTS | SEC_IN_MEMORY);
+ stub = bfd_make_section_anyway_with_flags (ibfd, ".stub", flags);
+ htab->stub_sec[0] = stub;
+ if (stub == NULL
+ || !bfd_set_section_alignment (ibfd, stub,
+ ovl_stub_size_log2 (htab->params)))
+ return 0;
+ stub->size = htab->stub_count[0] * ovl_stub_size (htab->params);
+ if (htab->params->ovly_flavour == ovly_soft_icache)
+ /* Extra space for linked list entries. */
+ stub->size += htab->stub_count[0] * 16;
+
+ for (i = 0; i < htab->num_overlays; ++i)
+ {
+ asection *osec = htab->ovl_sec[i];
+ unsigned int ovl = spu_elf_section_data (osec)->u.o.ovl_index;
+ stub = bfd_make_section_anyway_with_flags (ibfd, ".stub", flags);
+ htab->stub_sec[ovl] = stub;
+ if (stub == NULL
+ || !bfd_set_section_alignment (ibfd, stub,
+ ovl_stub_size_log2 (htab->params)))
+ return 0;
+ stub->size = htab->stub_count[ovl] * ovl_stub_size (htab->params);
+ }
+ }
+
+ if (htab->params->ovly_flavour == ovly_soft_icache)
+ {
+ /* Space for icache manager tables.
+ a) Tag array, one quadword per cache line.
+ b) Rewrite "to" list, one quadword per cache line.
+ c) Rewrite "from" list, one byte per outgoing branch (rounded up to
+ a power-of-two number of full quadwords) per cache line. */
+
+ flags = SEC_ALLOC;
+ htab->ovtab = bfd_make_section_anyway_with_flags (ibfd, ".ovtab", flags);
+ if (htab->ovtab == NULL
+ || !bfd_set_section_alignment (ibfd, htab->ovtab, 4))
+ return 0;
+
+ htab->ovtab->size = (16 + 16 + (16 << htab->fromelem_size_log2))
+ << htab->num_lines_log2;
+
+ flags = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY;
+ htab->init = bfd_make_section_anyway_with_flags (ibfd, ".ovini", flags);
+ if (htab->init == NULL
+ || !bfd_set_section_alignment (ibfd, htab->init, 4))
+ return 0;
+
+ htab->init->size = 16;
+ }
+ else if (htab->stub_count == NULL)
+ return 1;
+ else
+ {
+ /* htab->ovtab consists of two arrays.
+ . struct {
+ . u32 vma;
+ . u32 size;
+ . u32 file_off;
+ . u32 buf;
+ . } _ovly_table[];
+ .
+ . struct {
+ . u32 mapped;
+ . } _ovly_buf_table[];
+ . */
+
+ flags = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY;
+ htab->ovtab = bfd_make_section_anyway_with_flags (ibfd, ".ovtab", flags);
+ if (htab->ovtab == NULL
+ || !bfd_set_section_alignment (ibfd, htab->ovtab, 4))
+ return 0;
+
+ htab->ovtab->size = htab->num_overlays * 16 + 16 + htab->num_buf * 4;
+ }
+
+ htab->toe = bfd_make_section_anyway_with_flags (ibfd, ".toe", SEC_ALLOC);
+ if (htab->toe == NULL
+ || !bfd_set_section_alignment (ibfd, htab->toe, 4))
+ return 0;
+ htab->toe->size = 16;
+
+ return 2;
+}
+
+/* Called from ld to place overlay manager data sections. This is done
+ after the overlay manager itself is loaded, mainly so that the
+ linker's htab->init section is placed after any other .ovl.init
+ sections. */
+
+void
+spu_elf_place_overlay_data (struct bfd_link_info *info)
+{
+ struct spu_link_hash_table *htab = spu_hash_table (info);
+ unsigned int i;
+
+ if (htab->stub_sec != NULL)
+ {
+ (*htab->params->place_spu_section) (htab->stub_sec[0], NULL, ".text");
+
+ for (i = 0; i < htab->num_overlays; ++i)
+ {
+ asection *osec = htab->ovl_sec[i];
+ unsigned int ovl = spu_elf_section_data (osec)->u.o.ovl_index;
+ (*htab->params->place_spu_section) (htab->stub_sec[ovl], osec, NULL);
+ }
+ }
+
+ if (htab->params->ovly_flavour == ovly_soft_icache)
+ (*htab->params->place_spu_section) (htab->init, NULL, ".ovl.init");
+
+ if (htab->ovtab != NULL)
+ {
+ const char *ovout = ".data";
+ if (htab->params->ovly_flavour == ovly_soft_icache)
+ ovout = ".bss";
+ (*htab->params->place_spu_section) (htab->ovtab, NULL, ovout);
+ }
+
+ if (htab->toe != NULL)
+ (*htab->params->place_spu_section) (htab->toe, NULL, ".toe");
+}
+
+/* Functions to handle embedded spu_ovl.o object. */
+
+static void *
+ovl_mgr_open (struct bfd *nbfd ATTRIBUTE_UNUSED, void *stream)
+{
+ return stream;
+}
+
+static file_ptr
+ovl_mgr_pread (struct bfd *abfd ATTRIBUTE_UNUSED,
+ void *stream,
+ void *buf,
+ file_ptr nbytes,
+ file_ptr offset)
+{
+ struct _ovl_stream *os;
+ size_t count;
+ size_t max;
+
+ os = (struct _ovl_stream *) stream;
+ max = (const char *) os->end - (const char *) os->start;
+
+ if ((ufile_ptr) offset >= max)
+ return 0;
+
+ count = nbytes;
+ if (count > max - offset)
+ count = max - offset;
+
+ memcpy (buf, (const char *) os->start + offset, count);
+ return count;
+}
+
+bfd_boolean
+spu_elf_open_builtin_lib (bfd **ovl_bfd, const struct _ovl_stream *stream)
+{
+ *ovl_bfd = bfd_openr_iovec ("builtin ovl_mgr",
+ "elf32-spu",
+ ovl_mgr_open,
+ (void *) stream,
+ ovl_mgr_pread,
+ NULL,
+ NULL);
+ return *ovl_bfd != NULL;
+}
+
+static unsigned int
+overlay_index (asection *sec)
+{
+ if (sec == NULL
+ || sec->output_section == bfd_abs_section_ptr)
+ return 0;
+ return spu_elf_section_data (sec->output_section)->u.o.ovl_index;
+}
+
+/* Define an STT_OBJECT symbol. */
+
+static struct elf_link_hash_entry *
+define_ovtab_symbol (struct spu_link_hash_table *htab, const char *name)
+{
+ struct elf_link_hash_entry *h;
+
+ h = elf_link_hash_lookup (&htab->elf, name, TRUE, FALSE, FALSE);
+ if (h == NULL)
+ return NULL;
+
+ if (h->root.type != bfd_link_hash_defined
+ || !h->def_regular)
+ {
+ h->root.type = bfd_link_hash_defined;
+ h->root.u.def.section = htab->ovtab;
+ h->type = STT_OBJECT;
+ h->ref_regular = 1;
+ h->def_regular = 1;
+ h->ref_regular_nonweak = 1;
+ h->non_elf = 0;
+ }
+ else if (h->root.u.def.section->owner != NULL)
+ {
+ (*_bfd_error_handler) (_("%B is not allowed to define %s"),
+ h->root.u.def.section->owner,
+ h->root.root.string);
+ bfd_set_error (bfd_error_bad_value);
+ return NULL;
+ }
+ else
+ {
+ (*_bfd_error_handler) (_("you are not allowed to define %s in a script"),
+ h->root.root.string);
+ bfd_set_error (bfd_error_bad_value);
+ return NULL;
+ }
+
+ return h;
+}
+
+/* Fill in all stubs and the overlay tables. */
+
+static bfd_boolean
+spu_elf_build_stubs (struct bfd_link_info *info)
+{
+ struct spu_link_hash_table *htab = spu_hash_table (info);
+ struct elf_link_hash_entry *h;
+ bfd_byte *p;
+ asection *s;
+ bfd *obfd;
+ unsigned int i;
+
+ if (htab->num_overlays != 0)
+ {
+ for (i = 0; i < 2; i++)
+ {
+ h = htab->ovly_entry[i];
+ if (h != NULL
+ && (h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak)
+ && h->def_regular)
+ {
+ s = h->root.u.def.section->output_section;
+ if (spu_elf_section_data (s)->u.o.ovl_index)
+ {
+ (*_bfd_error_handler) (_("%s in overlay section"),
+ h->root.root.string);
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+ }
+ }
+ }
+
+ if (htab->stub_sec != NULL)
+ {
+ for (i = 0; i <= htab->num_overlays; i++)
+ if (htab->stub_sec[i]->size != 0)
+ {
+ htab->stub_sec[i]->contents = bfd_zalloc (htab->stub_sec[i]->owner,
+ htab->stub_sec[i]->size);
+ if (htab->stub_sec[i]->contents == NULL)
+ return FALSE;
+ htab->stub_sec[i]->rawsize = htab->stub_sec[i]->size;
+ htab->stub_sec[i]->size = 0;
+ }
+
+ /* Fill in all the stubs. */
+ process_stubs (info, TRUE);
+ if (!htab->stub_err)
+ elf_link_hash_traverse (&htab->elf, build_spuear_stubs, info);
+
+ if (htab->stub_err)
+ {
+ (*_bfd_error_handler) (_("overlay stub relocation overflow"));
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+
+ for (i = 0; i <= htab->num_overlays; i++)
+ {
+ if (htab->stub_sec[i]->size != htab->stub_sec[i]->rawsize)
+ {
+ (*_bfd_error_handler) (_("stubs don't match calculated size"));
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+ htab->stub_sec[i]->rawsize = 0;
+ }
+ }
+
+ if (htab->ovtab == NULL || htab->ovtab->size == 0)
+ return TRUE;
+
+ htab->ovtab->contents = bfd_zalloc (htab->ovtab->owner, htab->ovtab->size);
+ if (htab->ovtab->contents == NULL)
+ return FALSE;
+
+ p = htab->ovtab->contents;
+ if (htab->params->ovly_flavour == ovly_soft_icache)
+ {
+ bfd_vma off;
+
+ h = define_ovtab_symbol (htab, "__icache_tag_array");
+ if (h == NULL)
+ return FALSE;
+ h->root.u.def.value = 0;
+ h->size = 16 << htab->num_lines_log2;
+ off = h->size;
+
+ h = define_ovtab_symbol (htab, "__icache_tag_array_size");
+ if (h == NULL)
+ return FALSE;
+ h->root.u.def.value = 16 << htab->num_lines_log2;
+ h->root.u.def.section = bfd_abs_section_ptr;
+
+ h = define_ovtab_symbol (htab, "__icache_rewrite_to");
+ if (h == NULL)
+ return FALSE;
+ h->root.u.def.value = off;
+ h->size = 16 << htab->num_lines_log2;
+ off += h->size;
+
+ h = define_ovtab_symbol (htab, "__icache_rewrite_to_size");
+ if (h == NULL)
+ return FALSE;
+ h->root.u.def.value = 16 << htab->num_lines_log2;
+ h->root.u.def.section = bfd_abs_section_ptr;
+
+ h = define_ovtab_symbol (htab, "__icache_rewrite_from");
+ if (h == NULL)
+ return FALSE;
+ h->root.u.def.value = off;
+ h->size = 16 << (htab->fromelem_size_log2 + htab->num_lines_log2);
+ off += h->size;
+
+ h = define_ovtab_symbol (htab, "__icache_rewrite_from_size");
+ if (h == NULL)
+ return FALSE;
+ h->root.u.def.value = 16 << (htab->fromelem_size_log2
+ + htab->num_lines_log2);
+ h->root.u.def.section = bfd_abs_section_ptr;
+
+ h = define_ovtab_symbol (htab, "__icache_log2_fromelemsize");
+ if (h == NULL)
+ return FALSE;
+ h->root.u.def.value = htab->fromelem_size_log2;
+ h->root.u.def.section = bfd_abs_section_ptr;
+
+ h = define_ovtab_symbol (htab, "__icache_base");
+ if (h == NULL)
+ return FALSE;
+ h->root.u.def.value = htab->ovl_sec[0]->vma;
+ h->root.u.def.section = bfd_abs_section_ptr;
+ h->size = htab->num_buf << htab->line_size_log2;
+
+ h = define_ovtab_symbol (htab, "__icache_linesize");
+ if (h == NULL)
+ return FALSE;
+ h->root.u.def.value = 1 << htab->line_size_log2;
+ h->root.u.def.section = bfd_abs_section_ptr;
+
+ h = define_ovtab_symbol (htab, "__icache_log2_linesize");
+ if (h == NULL)
+ return FALSE;
+ h->root.u.def.value = htab->line_size_log2;
+ h->root.u.def.section = bfd_abs_section_ptr;
+
+ h = define_ovtab_symbol (htab, "__icache_neg_log2_linesize");
+ if (h == NULL)
+ return FALSE;
+ h->root.u.def.value = -htab->line_size_log2;
+ h->root.u.def.section = bfd_abs_section_ptr;
+
+ h = define_ovtab_symbol (htab, "__icache_cachesize");
+ if (h == NULL)
+ return FALSE;
+ h->root.u.def.value = 1 << (htab->num_lines_log2 + htab->line_size_log2);
+ h->root.u.def.section = bfd_abs_section_ptr;
+
+ h = define_ovtab_symbol (htab, "__icache_log2_cachesize");
+ if (h == NULL)
+ return FALSE;
+ h->root.u.def.value = htab->num_lines_log2 + htab->line_size_log2;
+ h->root.u.def.section = bfd_abs_section_ptr;
+
+ h = define_ovtab_symbol (htab, "__icache_neg_log2_cachesize");
+ if (h == NULL)
+ return FALSE;
+ h->root.u.def.value = -(htab->num_lines_log2 + htab->line_size_log2);
+ h->root.u.def.section = bfd_abs_section_ptr;
+
+ if (htab->init != NULL && htab->init->size != 0)
+ {
+ htab->init->contents = bfd_zalloc (htab->init->owner,
+ htab->init->size);
+ if (htab->init->contents == NULL)
+ return FALSE;
+
+ h = define_ovtab_symbol (htab, "__icache_fileoff");
+ if (h == NULL)
+ return FALSE;
+ h->root.u.def.value = 0;
+ h->root.u.def.section = htab->init;
+ h->size = 8;
+ }
+ }
+ else
+ {
+ /* Write out _ovly_table. */
+ /* set low bit of .size to mark non-overlay area as present. */
+ p[7] = 1;
+ obfd = htab->ovtab->output_section->owner;
+ for (s = obfd->sections; s != NULL; s = s->next)
+ {
+ unsigned int ovl_index = spu_elf_section_data (s)->u.o.ovl_index;
+
+ if (ovl_index != 0)
+ {
+ unsigned long off = ovl_index * 16;
+ unsigned int ovl_buf = spu_elf_section_data (s)->u.o.ovl_buf;
+
+ bfd_put_32 (htab->ovtab->owner, s->vma, p + off);
+ bfd_put_32 (htab->ovtab->owner, (s->size + 15) & -16,
+ p + off + 4);
+ /* file_off written later in spu_elf_modify_program_headers. */
+ bfd_put_32 (htab->ovtab->owner, ovl_buf, p + off + 12);
+ }
+ }
+
+ h = define_ovtab_symbol (htab, "_ovly_table");
+ if (h == NULL)
+ return FALSE;
+ h->root.u.def.value = 16;
+ h->size = htab->num_overlays * 16;
+
+ h = define_ovtab_symbol (htab, "_ovly_table_end");
+ if (h == NULL)
+ return FALSE;
+ h->root.u.def.value = htab->num_overlays * 16 + 16;
+ h->size = 0;
+
+ h = define_ovtab_symbol (htab, "_ovly_buf_table");
+ if (h == NULL)
+ return FALSE;
+ h->root.u.def.value = htab->num_overlays * 16 + 16;
+ h->size = htab->num_buf * 4;
+
+ h = define_ovtab_symbol (htab, "_ovly_buf_table_end");
+ if (h == NULL)
+ return FALSE;
+ h->root.u.def.value = htab->num_overlays * 16 + 16 + htab->num_buf * 4;
+ h->size = 0;
+ }
+
+ h = define_ovtab_symbol (htab, "_EAR_");
+ if (h == NULL)
+ return FALSE;
+ h->root.u.def.section = htab->toe;
+ h->root.u.def.value = 0;
+ h->size = 16;
+
+ return TRUE;
+}
+
+/* Check that all loadable section VMAs lie in the range
+ LO .. HI inclusive, and stash some parameters for --auto-overlay. */
+
+asection *
+spu_elf_check_vma (struct bfd_link_info *info)
+{
+ struct elf_segment_map *m;
+ unsigned int i;
+ struct spu_link_hash_table *htab = spu_hash_table (info);
+ bfd *abfd = info->output_bfd;
+ bfd_vma hi = htab->params->local_store_hi;
+ bfd_vma lo = htab->params->local_store_lo;
+
+ htab->local_store = hi + 1 - lo;
+
+ for (m = elf_seg_map (abfd); m != NULL; m = m->next)
+ if (m->p_type == PT_LOAD)
+ for (i = 0; i < m->count; i++)
+ if (m->sections[i]->size != 0
+ && (m->sections[i]->vma < lo
+ || m->sections[i]->vma > hi
+ || m->sections[i]->vma + m->sections[i]->size - 1 > hi))
+ return m->sections[i];
+
+ return NULL;
+}
+
+/* OFFSET in SEC (presumably) is the beginning of a function prologue.
+ Search for stack adjusting insns, and return the sp delta.
+ If a store of lr is found save the instruction offset to *LR_STORE.
+ If a stack adjusting instruction is found, save that offset to
+ *SP_ADJUST. */
+
+static int
+find_function_stack_adjust (asection *sec,
+ bfd_vma offset,
+ bfd_vma *lr_store,
+ bfd_vma *sp_adjust)
+{
+ int reg[128];
+
+ memset (reg, 0, sizeof (reg));
+ for ( ; offset + 4 <= sec->size; offset += 4)
+ {
+ unsigned char buf[4];
+ int rt, ra;
+ int imm;
+
+ /* Assume no relocs on stack adjusing insns. */
+ if (!bfd_get_section_contents (sec->owner, sec, buf, offset, 4))
+ break;
+
+ rt = buf[3] & 0x7f;
+ ra = ((buf[2] & 0x3f) << 1) | (buf[3] >> 7);
+
+ if (buf[0] == 0x24 /* stqd */)
+ {
+ if (rt == 0 /* lr */ && ra == 1 /* sp */)
+ *lr_store = offset;
+ continue;
+ }
+
+ /* Partly decoded immediate field. */
+ imm = (buf[1] << 9) | (buf[2] << 1) | (buf[3] >> 7);
+
+ if (buf[0] == 0x1c /* ai */)
+ {
+ imm >>= 7;
+ imm = (imm ^ 0x200) - 0x200;
+ reg[rt] = reg[ra] + imm;
+
+ if (rt == 1 /* sp */)
+ {
+ if (reg[rt] > 0)
+ break;
+ *sp_adjust = offset;
+ return reg[rt];
+ }
+ }
+ else if (buf[0] == 0x18 && (buf[1] & 0xe0) == 0 /* a */)
+ {
+ int rb = ((buf[1] & 0x1f) << 2) | ((buf[2] & 0xc0) >> 6);
+
+ reg[rt] = reg[ra] + reg[rb];
+ if (rt == 1)
+ {
+ if (reg[rt] > 0)
+ break;
+ *sp_adjust = offset;
+ return reg[rt];
+ }
+ }
+ else if (buf[0] == 0x08 && (buf[1] & 0xe0) == 0 /* sf */)
+ {
+ int rb = ((buf[1] & 0x1f) << 2) | ((buf[2] & 0xc0) >> 6);
+
+ reg[rt] = reg[rb] - reg[ra];
+ if (rt == 1)
+ {
+ if (reg[rt] > 0)
+ break;
+ *sp_adjust = offset;
+ return reg[rt];
+ }
+ }
+ else if ((buf[0] & 0xfc) == 0x40 /* il, ilh, ilhu, ila */)
+ {
+ if (buf[0] >= 0x42 /* ila */)
+ imm |= (buf[0] & 1) << 17;
+ else
+ {
+ imm &= 0xffff;
+
+ if (buf[0] == 0x40 /* il */)
+ {
+ if ((buf[1] & 0x80) == 0)
+ continue;
+ imm = (imm ^ 0x8000) - 0x8000;
+ }
+ else if ((buf[1] & 0x80) == 0 /* ilhu */)
+ imm <<= 16;
+ }
+ reg[rt] = imm;
+ continue;
+ }
+ else if (buf[0] == 0x60 && (buf[1] & 0x80) != 0 /* iohl */)
+ {
+ reg[rt] |= imm & 0xffff;
+ continue;
+ }
+ else if (buf[0] == 0x04 /* ori */)
+ {
+ imm >>= 7;
+ imm = (imm ^ 0x200) - 0x200;
+ reg[rt] = reg[ra] | imm;
+ continue;
+ }
+ else if (buf[0] == 0x32 && (buf[1] & 0x80) != 0 /* fsmbi */)
+ {
+ reg[rt] = ( ((imm & 0x8000) ? 0xff000000 : 0)
+ | ((imm & 0x4000) ? 0x00ff0000 : 0)
+ | ((imm & 0x2000) ? 0x0000ff00 : 0)
+ | ((imm & 0x1000) ? 0x000000ff : 0));
+ continue;
+ }
+ else if (buf[0] == 0x16 /* andbi */)
+ {
+ imm >>= 7;
+ imm &= 0xff;
+ imm |= imm << 8;
+ imm |= imm << 16;
+ reg[rt] = reg[ra] & imm;
+ continue;
+ }
+ else if (buf[0] == 0x33 && imm == 1 /* brsl .+4 */)
+ {
+ /* Used in pic reg load. Say rt is trashed. Won't be used
+ in stack adjust, but we need to continue past this branch. */
+ reg[rt] = 0;
+ continue;
+ }
+ else if (is_branch (buf) || is_indirect_branch (buf))
+ /* If we hit a branch then we must be out of the prologue. */
+ break;
+ }
+
+ return 0;
+}
+
+/* qsort predicate to sort symbols by section and value. */
+
+static Elf_Internal_Sym *sort_syms_syms;
+static asection **sort_syms_psecs;
+
+static int
+sort_syms (const void *a, const void *b)
+{
+ Elf_Internal_Sym *const *s1 = a;
+ Elf_Internal_Sym *const *s2 = b;
+ asection *sec1,*sec2;
+ bfd_signed_vma delta;
+
+ sec1 = sort_syms_psecs[*s1 - sort_syms_syms];
+ sec2 = sort_syms_psecs[*s2 - sort_syms_syms];
+
+ if (sec1 != sec2)
+ return sec1->index - sec2->index;
+
+ delta = (*s1)->st_value - (*s2)->st_value;
+ if (delta != 0)
+ return delta < 0 ? -1 : 1;
+
+ delta = (*s2)->st_size - (*s1)->st_size;
+ if (delta != 0)
+ return delta < 0 ? -1 : 1;
+
+ return *s1 < *s2 ? -1 : 1;
+}
+
+/* Allocate a struct spu_elf_stack_info with MAX_FUN struct function_info
+ entries for section SEC. */
+
+static struct spu_elf_stack_info *
+alloc_stack_info (asection *sec, int max_fun)
+{
+ struct _spu_elf_section_data *sec_data = spu_elf_section_data (sec);
+ bfd_size_type amt;
+
+ amt = sizeof (struct spu_elf_stack_info);
+ amt += (max_fun - 1) * sizeof (struct function_info);
+ sec_data->u.i.stack_info = bfd_zmalloc (amt);
+ if (sec_data->u.i.stack_info != NULL)
+ sec_data->u.i.stack_info->max_fun = max_fun;
+ return sec_data->u.i.stack_info;
+}
+
+/* Add a new struct function_info describing a (part of a) function
+ starting at SYM_H. Keep the array sorted by address. */
+
+static struct function_info *
+maybe_insert_function (asection *sec,
+ void *sym_h,
+ bfd_boolean global,
+ bfd_boolean is_func)
+{
+ struct _spu_elf_section_data *sec_data = spu_elf_section_data (sec);
+ struct spu_elf_stack_info *sinfo = sec_data->u.i.stack_info;
+ int i;
+ bfd_vma off, size;
+
+ if (sinfo == NULL)
+ {
+ sinfo = alloc_stack_info (sec, 20);
+ if (sinfo == NULL)
+ return NULL;
+ }
+
+ if (!global)
+ {
+ Elf_Internal_Sym *sym = sym_h;
+ off = sym->st_value;
+ size = sym->st_size;
+ }
+ else
+ {
+ struct elf_link_hash_entry *h = sym_h;
+ off = h->root.u.def.value;
+ size = h->size;
+ }
+
+ for (i = sinfo->num_fun; --i >= 0; )
+ if (sinfo->fun[i].lo <= off)
+ break;
+
+ if (i >= 0)
+ {
+ /* Don't add another entry for an alias, but do update some
+ info. */
+ if (sinfo->fun[i].lo == off)
+ {
+ /* Prefer globals over local syms. */
+ if (global && !sinfo->fun[i].global)
+ {
+ sinfo->fun[i].global = TRUE;
+ sinfo->fun[i].u.h = sym_h;
+ }
+ if (is_func)
+ sinfo->fun[i].is_func = TRUE;
+ return &sinfo->fun[i];
+ }
+ /* Ignore a zero-size symbol inside an existing function. */
+ else if (sinfo->fun[i].hi > off && size == 0)
+ return &sinfo->fun[i];
+ }
+
+ if (sinfo->num_fun >= sinfo->max_fun)
+ {
+ bfd_size_type amt = sizeof (struct spu_elf_stack_info);
+ bfd_size_type old = amt;
+
+ old += (sinfo->max_fun - 1) * sizeof (struct function_info);
+ sinfo->max_fun += 20 + (sinfo->max_fun >> 1);
+ amt += (sinfo->max_fun - 1) * sizeof (struct function_info);
+ sinfo = bfd_realloc (sinfo, amt);
+ if (sinfo == NULL)
+ return NULL;
+ memset ((char *) sinfo + old, 0, amt - old);
+ sec_data->u.i.stack_info = sinfo;
+ }
+
+ if (++i < sinfo->num_fun)
+ memmove (&sinfo->fun[i + 1], &sinfo->fun[i],
+ (sinfo->num_fun - i) * sizeof (sinfo->fun[i]));
+ sinfo->fun[i].is_func = is_func;
+ sinfo->fun[i].global = global;
+ sinfo->fun[i].sec = sec;
+ if (global)
+ sinfo->fun[i].u.h = sym_h;
+ else
+ sinfo->fun[i].u.sym = sym_h;
+ sinfo->fun[i].lo = off;
+ sinfo->fun[i].hi = off + size;
+ sinfo->fun[i].lr_store = -1;
+ sinfo->fun[i].sp_adjust = -1;
+ sinfo->fun[i].stack = -find_function_stack_adjust (sec, off,
+ &sinfo->fun[i].lr_store,
+ &sinfo->fun[i].sp_adjust);
+ sinfo->num_fun += 1;
+ return &sinfo->fun[i];
+}
+
+/* Return the name of FUN. */
+
+static const char *
+func_name (struct function_info *fun)
+{
+ asection *sec;
+ bfd *ibfd;
+ Elf_Internal_Shdr *symtab_hdr;
+
+ while (fun->start != NULL)
+ fun = fun->start;
+
+ if (fun->global)
+ return fun->u.h->root.root.string;
+
+ sec = fun->sec;
+ if (fun->u.sym->st_name == 0)
+ {
+ size_t len = strlen (sec->name);
+ char *name = bfd_malloc (len + 10);
+ if (name == NULL)
+ return "(null)";
+ sprintf (name, "%s+%lx", sec->name,
+ (unsigned long) fun->u.sym->st_value & 0xffffffff);
+ return name;
+ }
+ ibfd = sec->owner;
+ symtab_hdr = &elf_tdata (ibfd)->symtab_hdr;
+ return bfd_elf_sym_name (ibfd, symtab_hdr, fun->u.sym, sec);
+}
+
+/* Read the instruction at OFF in SEC. Return true iff the instruction
+ is a nop, lnop, or stop 0 (all zero insn). */
+
+static bfd_boolean
+is_nop (asection *sec, bfd_vma off)
+{
+ unsigned char insn[4];
+
+ if (off + 4 > sec->size
+ || !bfd_get_section_contents (sec->owner, sec, insn, off, 4))
+ return FALSE;
+ if ((insn[0] & 0xbf) == 0 && (insn[1] & 0xe0) == 0x20)
+ return TRUE;
+ if (insn[0] == 0 && insn[1] == 0 && insn[2] == 0 && insn[3] == 0)
+ return TRUE;
+ return FALSE;
+}
+
+/* Extend the range of FUN to cover nop padding up to LIMIT.
+ Return TRUE iff some instruction other than a NOP was found. */
+
+static bfd_boolean
+insns_at_end (struct function_info *fun, bfd_vma limit)
+{
+ bfd_vma off = (fun->hi + 3) & -4;
+
+ while (off < limit && is_nop (fun->sec, off))
+ off += 4;
+ if (off < limit)
+ {
+ fun->hi = off;
+ return TRUE;
+ }
+ fun->hi = limit;
+ return FALSE;
+}
+
+/* Check and fix overlapping function ranges. Return TRUE iff there
+ are gaps in the current info we have about functions in SEC. */
+
+static bfd_boolean
+check_function_ranges (asection *sec, struct bfd_link_info *info)
+{
+ struct _spu_elf_section_data *sec_data = spu_elf_section_data (sec);
+ struct spu_elf_stack_info *sinfo = sec_data->u.i.stack_info;
+ int i;
+ bfd_boolean gaps = FALSE;
+
+ if (sinfo == NULL)
+ return FALSE;
+
+ for (i = 1; i < sinfo->num_fun; i++)
+ if (sinfo->fun[i - 1].hi > sinfo->fun[i].lo)
+ {
+ /* Fix overlapping symbols. */
+ const char *f1 = func_name (&sinfo->fun[i - 1]);
+ const char *f2 = func_name (&sinfo->fun[i]);
+
+ info->callbacks->einfo (_("warning: %s overlaps %s\n"), f1, f2);
+ sinfo->fun[i - 1].hi = sinfo->fun[i].lo;
+ }
+ else if (insns_at_end (&sinfo->fun[i - 1], sinfo->fun[i].lo))
+ gaps = TRUE;
+
+ if (sinfo->num_fun == 0)
+ gaps = TRUE;
+ else
+ {
+ if (sinfo->fun[0].lo != 0)
+ gaps = TRUE;
+ if (sinfo->fun[sinfo->num_fun - 1].hi > sec->size)
+ {
+ const char *f1 = func_name (&sinfo->fun[sinfo->num_fun - 1]);
+
+ info->callbacks->einfo (_("warning: %s exceeds section size\n"), f1);
+ sinfo->fun[sinfo->num_fun - 1].hi = sec->size;
+ }
+ else if (insns_at_end (&sinfo->fun[sinfo->num_fun - 1], sec->size))
+ gaps = TRUE;
+ }
+ return gaps;
+}
+
+/* Search current function info for a function that contains address
+ OFFSET in section SEC. */
+
+static struct function_info *
+find_function (asection *sec, bfd_vma offset, struct bfd_link_info *info)
+{
+ struct _spu_elf_section_data *sec_data = spu_elf_section_data (sec);
+ struct spu_elf_stack_info *sinfo = sec_data->u.i.stack_info;
+ int lo, hi, mid;
+
+ lo = 0;
+ hi = sinfo->num_fun;
+ while (lo < hi)
+ {
+ mid = (lo + hi) / 2;
+ if (offset < sinfo->fun[mid].lo)
+ hi = mid;
+ else if (offset >= sinfo->fun[mid].hi)
+ lo = mid + 1;
+ else
+ return &sinfo->fun[mid];
+ }
+ info->callbacks->einfo (_("%A:0x%v not found in function table\n"),
+ sec, offset);
+ bfd_set_error (bfd_error_bad_value);
+ return NULL;
+}
+
+/* Add CALLEE to CALLER call list if not already present. Return TRUE
+ if CALLEE was new. If this function return FALSE, CALLEE should
+ be freed. */
+
+static bfd_boolean
+insert_callee (struct function_info *caller, struct call_info *callee)
+{
+ struct call_info **pp, *p;
+
+ for (pp = &caller->call_list; (p = *pp) != NULL; pp = &p->next)
+ if (p->fun == callee->fun)
+ {
+ /* Tail calls use less stack than normal calls. Retain entry
+ for normal call over one for tail call. */
+ p->is_tail &= callee->is_tail;
+ if (!p->is_tail)
+ {
+ p->fun->start = NULL;
+ p->fun->is_func = TRUE;
+ }
+ p->count += callee->count;
+ /* Reorder list so most recent call is first. */
+ *pp = p->next;
+ p->next = caller->call_list;
+ caller->call_list = p;
+ return FALSE;
+ }
+ callee->next = caller->call_list;
+ caller->call_list = callee;
+ return TRUE;
+}
+
+/* Copy CALL and insert the copy into CALLER. */
+
+static bfd_boolean
+copy_callee (struct function_info *caller, const struct call_info *call)
+{
+ struct call_info *callee;
+ callee = bfd_malloc (sizeof (*callee));
+ if (callee == NULL)
+ return FALSE;
+ *callee = *call;
+ if (!insert_callee (caller, callee))
+ free (callee);
+ return TRUE;
+}
+
+/* We're only interested in code sections. Testing SEC_IN_MEMORY excludes
+ overlay stub sections. */
+
+static bfd_boolean
+interesting_section (asection *s)
+{
+ return (s->output_section != bfd_abs_section_ptr
+ && ((s->flags & (SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_IN_MEMORY))
+ == (SEC_ALLOC | SEC_LOAD | SEC_CODE))
+ && s->size != 0);
+}
+
+/* Rummage through the relocs for SEC, looking for function calls.
+ If CALL_TREE is true, fill in call graph. If CALL_TREE is false,
+ mark destination symbols on calls as being functions. Also
+ look at branches, which may be tail calls or go to hot/cold
+ section part of same function. */
+
+static bfd_boolean
+mark_functions_via_relocs (asection *sec,
+ struct bfd_link_info *info,
+ int call_tree)
+{
+ Elf_Internal_Rela *internal_relocs, *irelaend, *irela;
+ Elf_Internal_Shdr *symtab_hdr;
+ void *psyms;
+ unsigned int priority = 0;
+ static bfd_boolean warned;
+
+ if (!interesting_section (sec)
+ || sec->reloc_count == 0)
+ return TRUE;
+
+ internal_relocs = _bfd_elf_link_read_relocs (sec->owner, sec, NULL, NULL,
+ info->keep_memory);
+ if (internal_relocs == NULL)
+ return FALSE;
+
+ symtab_hdr = &elf_tdata (sec->owner)->symtab_hdr;
+ psyms = &symtab_hdr->contents;
+ irela = internal_relocs;
+ irelaend = irela + sec->reloc_count;
+ for (; irela < irelaend; irela++)
+ {
+ enum elf_spu_reloc_type r_type;
+ unsigned int r_indx;
+ asection *sym_sec;
+ Elf_Internal_Sym *sym;
+ struct elf_link_hash_entry *h;
+ bfd_vma val;
+ bfd_boolean nonbranch, is_call;
+ struct function_info *caller;
+ struct call_info *callee;
+
+ r_type = ELF32_R_TYPE (irela->r_info);
+ nonbranch = r_type != R_SPU_REL16 && r_type != R_SPU_ADDR16;
+
+ r_indx = ELF32_R_SYM (irela->r_info);
+ if (!get_sym_h (&h, &sym, &sym_sec, psyms, r_indx, sec->owner))
+ return FALSE;
+
+ if (sym_sec == NULL
+ || sym_sec->output_section == bfd_abs_section_ptr)
+ continue;
+
+ is_call = FALSE;
+ if (!nonbranch)
+ {
+ unsigned char insn[4];
+
+ if (!bfd_get_section_contents (sec->owner, sec, insn,
+ irela->r_offset, 4))
+ return FALSE;
+ if (is_branch (insn))
+ {
+ is_call = (insn[0] & 0xfd) == 0x31;
+ priority = insn[1] & 0x0f;
+ priority <<= 8;
+ priority |= insn[2];
+ priority <<= 8;
+ priority |= insn[3];
+ priority >>= 7;
+ if ((sym_sec->flags & (SEC_ALLOC | SEC_LOAD | SEC_CODE))
+ != (SEC_ALLOC | SEC_LOAD | SEC_CODE))
+ {
+ if (!warned)
+ info->callbacks->einfo
+ (_("%B(%A+0x%v): call to non-code section"
+ " %B(%A), analysis incomplete\n"),
+ sec->owner, sec, irela->r_offset,
+ sym_sec->owner, sym_sec);
+ warned = TRUE;
+ continue;
+ }
+ }
+ else
+ {
+ nonbranch = TRUE;
+ if (is_hint (insn))
+ continue;
+ }
+ }
+
+ if (nonbranch)
+ {
+ /* For --auto-overlay, count possible stubs we need for
+ function pointer references. */
+ unsigned int sym_type;
+ if (h)
+ sym_type = h->type;
+ else
+ sym_type = ELF_ST_TYPE (sym->st_info);
+ if (sym_type == STT_FUNC)
+ {
+ if (call_tree && spu_hash_table (info)->params->auto_overlay)
+ spu_hash_table (info)->non_ovly_stub += 1;
+ /* If the symbol type is STT_FUNC then this must be a
+ function pointer initialisation. */
+ continue;
+ }
+ /* Ignore data references. */
+ if ((sym_sec->flags & (SEC_ALLOC | SEC_LOAD | SEC_CODE))
+ != (SEC_ALLOC | SEC_LOAD | SEC_CODE))
+ continue;
+ /* Otherwise we probably have a jump table reloc for
+ a switch statement or some other reference to a
+ code label. */
+ }
+
+ if (h)
+ val = h->root.u.def.value;
+ else
+ val = sym->st_value;
+ val += irela->r_addend;
+
+ if (!call_tree)
+ {
+ struct function_info *fun;
+
+ if (irela->r_addend != 0)
+ {
+ Elf_Internal_Sym *fake = bfd_zmalloc (sizeof (*fake));
+ if (fake == NULL)
+ return FALSE;
+ fake->st_value = val;
+ fake->st_shndx
+ = _bfd_elf_section_from_bfd_section (sym_sec->owner, sym_sec);
+ sym = fake;
+ }
+ if (sym)
+ fun = maybe_insert_function (sym_sec, sym, FALSE, is_call);
+ else
+ fun = maybe_insert_function (sym_sec, h, TRUE, is_call);
+ if (fun == NULL)
+ return FALSE;
+ if (irela->r_addend != 0
+ && fun->u.sym != sym)
+ free (sym);
+ continue;
+ }
+
+ caller = find_function (sec, irela->r_offset, info);
+ if (caller == NULL)
+ return FALSE;
+ callee = bfd_malloc (sizeof *callee);
+ if (callee == NULL)
+ return FALSE;
+
+ callee->fun = find_function (sym_sec, val, info);
+ if (callee->fun == NULL)
+ return FALSE;
+ callee->is_tail = !is_call;
+ callee->is_pasted = FALSE;
+ callee->broken_cycle = FALSE;
+ callee->priority = priority;
+ callee->count = nonbranch? 0 : 1;
+ if (callee->fun->last_caller != sec)
+ {
+ callee->fun->last_caller = sec;
+ callee->fun->call_count += 1;
+ }
+ if (!insert_callee (caller, callee))
+ free (callee);
+ else if (!is_call
+ && !callee->fun->is_func
+ && callee->fun->stack == 0)
+ {
+ /* This is either a tail call or a branch from one part of
+ the function to another, ie. hot/cold section. If the
+ destination has been called by some other function then
+ it is a separate function. We also assume that functions
+ are not split across input files. */
+ if (sec->owner != sym_sec->owner)
+ {
+ callee->fun->start = NULL;
+ callee->fun->is_func = TRUE;
+ }
+ else if (callee->fun->start == NULL)
+ {
+ struct function_info *caller_start = caller;
+ while (caller_start->start)
+ caller_start = caller_start->start;
+
+ if (caller_start != callee->fun)
+ callee->fun->start = caller_start;
+ }
+ else
+ {
+ struct function_info *callee_start;
+ struct function_info *caller_start;
+ callee_start = callee->fun;
+ while (callee_start->start)
+ callee_start = callee_start->start;
+ caller_start = caller;
+ while (caller_start->start)
+ caller_start = caller_start->start;
+ if (caller_start != callee_start)
+ {
+ callee->fun->start = NULL;
+ callee->fun->is_func = TRUE;
+ }
+ }
+ }
+ }
+
+ return TRUE;
+}
+
+/* Handle something like .init or .fini, which has a piece of a function.
+ These sections are pasted together to form a single function. */
+
+static bfd_boolean
+pasted_function (asection *sec)
+{
+ struct bfd_link_order *l;
+ struct _spu_elf_section_data *sec_data;
+ struct spu_elf_stack_info *sinfo;
+ Elf_Internal_Sym *fake;
+ struct function_info *fun, *fun_start;
+
+ fake = bfd_zmalloc (sizeof (*fake));
+ if (fake == NULL)
+ return FALSE;
+ fake->st_value = 0;
+ fake->st_size = sec->size;
+ fake->st_shndx
+ = _bfd_elf_section_from_bfd_section (sec->owner, sec);
+ fun = maybe_insert_function (sec, fake, FALSE, FALSE);
+ if (!fun)
+ return FALSE;
+
+ /* Find a function immediately preceding this section. */
+ fun_start = NULL;
+ for (l = sec->output_section->map_head.link_order; l != NULL; l = l->next)
+ {
+ if (l->u.indirect.section == sec)
+ {
+ if (fun_start != NULL)
+ {
+ struct call_info *callee = bfd_malloc (sizeof *callee);
+ if (callee == NULL)
+ return FALSE;
+
+ fun->start = fun_start;
+ callee->fun = fun;
+ callee->is_tail = TRUE;
+ callee->is_pasted = TRUE;
+ callee->broken_cycle = FALSE;
+ callee->priority = 0;
+ callee->count = 1;
+ if (!insert_callee (fun_start, callee))
+ free (callee);
+ return TRUE;
+ }
+ break;
+ }
+ if (l->type == bfd_indirect_link_order
+ && (sec_data = spu_elf_section_data (l->u.indirect.section)) != NULL
+ && (sinfo = sec_data->u.i.stack_info) != NULL
+ && sinfo->num_fun != 0)
+ fun_start = &sinfo->fun[sinfo->num_fun - 1];
+ }
+
+ /* Don't return an error if we did not find a function preceding this
+ section. The section may have incorrect flags. */
+ return TRUE;
+}
+
+/* Map address ranges in code sections to functions. */
+
+static bfd_boolean
+discover_functions (struct bfd_link_info *info)
+{
+ bfd *ibfd;
+ int bfd_idx;
+ Elf_Internal_Sym ***psym_arr;
+ asection ***sec_arr;
+ bfd_boolean gaps = FALSE;
+
+ bfd_idx = 0;
+ for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next)
+ bfd_idx++;
+
+ psym_arr = bfd_zmalloc (bfd_idx * sizeof (*psym_arr));
+ if (psym_arr == NULL)
+ return FALSE;
+ sec_arr = bfd_zmalloc (bfd_idx * sizeof (*sec_arr));
+ if (sec_arr == NULL)
+ return FALSE;
+
+ for (ibfd = info->input_bfds, bfd_idx = 0;
+ ibfd != NULL;
+ ibfd = ibfd->link.next, bfd_idx++)
+ {
+ extern const bfd_target spu_elf32_vec;
+ Elf_Internal_Shdr *symtab_hdr;
+ asection *sec;
+ size_t symcount;
+ Elf_Internal_Sym *syms, *sy, **psyms, **psy;
+ asection **psecs, **p;
+
+ if (ibfd->xvec != &spu_elf32_vec)
+ continue;
+
+ /* Read all the symbols. */
+ symtab_hdr = &elf_tdata (ibfd)->symtab_hdr;
+ symcount = symtab_hdr->sh_size / symtab_hdr->sh_entsize;
+ if (symcount == 0)
+ {
+ if (!gaps)
+ for (sec = ibfd->sections; sec != NULL && !gaps; sec = sec->next)
+ if (interesting_section (sec))
+ {
+ gaps = TRUE;
+ break;
+ }
+ continue;
+ }
+
+ if (symtab_hdr->contents != NULL)
+ {
+ /* Don't use cached symbols since the generic ELF linker
+ code only reads local symbols, and we need globals too. */
+ free (symtab_hdr->contents);
+ symtab_hdr->contents = NULL;
+ }
+ syms = bfd_elf_get_elf_syms (ibfd, symtab_hdr, symcount, 0,
+ NULL, NULL, NULL);
+ symtab_hdr->contents = (void *) syms;
+ if (syms == NULL)
+ return FALSE;
+
+ /* Select defined function symbols that are going to be output. */
+ psyms = bfd_malloc ((symcount + 1) * sizeof (*psyms));
+ if (psyms == NULL)
+ return FALSE;
+ psym_arr[bfd_idx] = psyms;
+ psecs = bfd_malloc (symcount * sizeof (*psecs));
+ if (psecs == NULL)
+ return FALSE;
+ sec_arr[bfd_idx] = psecs;
+ for (psy = psyms, p = psecs, sy = syms; sy < syms + symcount; ++p, ++sy)
+ if (ELF_ST_TYPE (sy->st_info) == STT_NOTYPE
+ || ELF_ST_TYPE (sy->st_info) == STT_FUNC)
+ {
+ asection *s;
+
+ *p = s = bfd_section_from_elf_index (ibfd, sy->st_shndx);
+ if (s != NULL && interesting_section (s))
+ *psy++ = sy;
+ }
+ symcount = psy - psyms;
+ *psy = NULL;
+
+ /* Sort them by section and offset within section. */
+ sort_syms_syms = syms;
+ sort_syms_psecs = psecs;
+ qsort (psyms, symcount, sizeof (*psyms), sort_syms);
+
+ /* Now inspect the function symbols. */
+ for (psy = psyms; psy < psyms + symcount; )
+ {
+ asection *s = psecs[*psy - syms];
+ Elf_Internal_Sym **psy2;
+
+ for (psy2 = psy; ++psy2 < psyms + symcount; )
+ if (psecs[*psy2 - syms] != s)
+ break;
+
+ if (!alloc_stack_info (s, psy2 - psy))
+ return FALSE;
+ psy = psy2;
+ }
+
+ /* First install info about properly typed and sized functions.
+ In an ideal world this will cover all code sections, except
+ when partitioning functions into hot and cold sections,
+ and the horrible pasted together .init and .fini functions. */
+ for (psy = psyms; psy < psyms + symcount; ++psy)
+ {
+ sy = *psy;
+ if (ELF_ST_TYPE (sy->st_info) == STT_FUNC)
+ {
+ asection *s = psecs[sy - syms];
+ if (!maybe_insert_function (s, sy, FALSE, TRUE))
+ return FALSE;
+ }
+ }
+
+ for (sec = ibfd->sections; sec != NULL && !gaps; sec = sec->next)
+ if (interesting_section (sec))
+ gaps |= check_function_ranges (sec, info);
+ }
+
+ if (gaps)
+ {
+ /* See if we can discover more function symbols by looking at
+ relocations. */
+ for (ibfd = info->input_bfds, bfd_idx = 0;
+ ibfd != NULL;
+ ibfd = ibfd->link.next, bfd_idx++)
+ {
+ asection *sec;
+
+ if (psym_arr[bfd_idx] == NULL)
+ continue;
+
+ for (sec = ibfd->sections; sec != NULL; sec = sec->next)
+ if (!mark_functions_via_relocs (sec, info, FALSE))
+ return FALSE;
+ }
+
+ for (ibfd = info->input_bfds, bfd_idx = 0;
+ ibfd != NULL;
+ ibfd = ibfd->link.next, bfd_idx++)
+ {
+ Elf_Internal_Shdr *symtab_hdr;
+ asection *sec;
+ Elf_Internal_Sym *syms, *sy, **psyms, **psy;
+ asection **psecs;
+
+ if ((psyms = psym_arr[bfd_idx]) == NULL)
+ continue;
+
+ psecs = sec_arr[bfd_idx];
+
+ symtab_hdr = &elf_tdata (ibfd)->symtab_hdr;
+ syms = (Elf_Internal_Sym *) symtab_hdr->contents;
+
+ gaps = FALSE;
+ for (sec = ibfd->sections; sec != NULL && !gaps; sec = sec->next)
+ if (interesting_section (sec))
+ gaps |= check_function_ranges (sec, info);
+ if (!gaps)
+ continue;
+
+ /* Finally, install all globals. */
+ for (psy = psyms; (sy = *psy) != NULL; ++psy)
+ {
+ asection *s;
+
+ s = psecs[sy - syms];
+
+ /* Global syms might be improperly typed functions. */
+ if (ELF_ST_TYPE (sy->st_info) != STT_FUNC
+ && ELF_ST_BIND (sy->st_info) == STB_GLOBAL)
+ {
+ if (!maybe_insert_function (s, sy, FALSE, FALSE))
+ return FALSE;
+ }
+ }
+ }
+
+ for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next)
+ {
+ extern const bfd_target spu_elf32_vec;
+ asection *sec;
+
+ if (ibfd->xvec != &spu_elf32_vec)
+ continue;
+
+ /* Some of the symbols we've installed as marking the
+ beginning of functions may have a size of zero. Extend
+ the range of such functions to the beginning of the
+ next symbol of interest. */
+ for (sec = ibfd->sections; sec != NULL; sec = sec->next)
+ if (interesting_section (sec))
+ {
+ struct _spu_elf_section_data *sec_data;
+ struct spu_elf_stack_info *sinfo;
+
+ sec_data = spu_elf_section_data (sec);
+ sinfo = sec_data->u.i.stack_info;
+ if (sinfo != NULL && sinfo->num_fun != 0)
+ {
+ int fun_idx;
+ bfd_vma hi = sec->size;
+
+ for (fun_idx = sinfo->num_fun; --fun_idx >= 0; )
+ {
+ sinfo->fun[fun_idx].hi = hi;
+ hi = sinfo->fun[fun_idx].lo;
+ }
+
+ sinfo->fun[0].lo = 0;
+ }
+ /* No symbols in this section. Must be .init or .fini
+ or something similar. */
+ else if (!pasted_function (sec))
+ return FALSE;
+ }
+ }
+ }
+
+ for (ibfd = info->input_bfds, bfd_idx = 0;
+ ibfd != NULL;
+ ibfd = ibfd->link.next, bfd_idx++)
+ {
+ if (psym_arr[bfd_idx] == NULL)
+ continue;
+
+ free (psym_arr[bfd_idx]);
+ free (sec_arr[bfd_idx]);
+ }
+
+ free (psym_arr);
+ free (sec_arr);
+
+ return TRUE;
+}
+
+/* Iterate over all function_info we have collected, calling DOIT on
+ each node if ROOT_ONLY is false. Only call DOIT on root nodes
+ if ROOT_ONLY. */
+
+static bfd_boolean
+for_each_node (bfd_boolean (*doit) (struct function_info *,
+ struct bfd_link_info *,
+ void *),
+ struct bfd_link_info *info,
+ void *param,
+ int root_only)
+{
+ bfd *ibfd;
+
+ for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next)
+ {
+ extern const bfd_target spu_elf32_vec;
+ asection *sec;
+
+ if (ibfd->xvec != &spu_elf32_vec)
+ continue;
+
+ for (sec = ibfd->sections; sec != NULL; sec = sec->next)
+ {
+ struct _spu_elf_section_data *sec_data;
+ struct spu_elf_stack_info *sinfo;
+
+ if ((sec_data = spu_elf_section_data (sec)) != NULL
+ && (sinfo = sec_data->u.i.stack_info) != NULL)
+ {
+ int i;
+ for (i = 0; i < sinfo->num_fun; ++i)
+ if (!root_only || !sinfo->fun[i].non_root)
+ if (!doit (&sinfo->fun[i], info, param))
+ return FALSE;
+ }
+ }
+ }
+ return TRUE;
+}
+
+/* Transfer call info attached to struct function_info entries for
+ all of a given function's sections to the first entry. */
+
+static bfd_boolean
+transfer_calls (struct function_info *fun,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ void *param ATTRIBUTE_UNUSED)
+{
+ struct function_info *start = fun->start;
+
+ if (start != NULL)
+ {
+ struct call_info *call, *call_next;
+
+ while (start->start != NULL)
+ start = start->start;
+ for (call = fun->call_list; call != NULL; call = call_next)
+ {
+ call_next = call->next;
+ if (!insert_callee (start, call))
+ free (call);
+ }
+ fun->call_list = NULL;
+ }
+ return TRUE;
+}
+
+/* Mark nodes in the call graph that are called by some other node. */
+
+static bfd_boolean
+mark_non_root (struct function_info *fun,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ void *param ATTRIBUTE_UNUSED)
+{
+ struct call_info *call;
+
+ if (fun->visit1)
+ return TRUE;
+ fun->visit1 = TRUE;
+ for (call = fun->call_list; call; call = call->next)
+ {
+ call->fun->non_root = TRUE;
+ mark_non_root (call->fun, 0, 0);
+ }
+ return TRUE;
+}
+
+/* Remove cycles from the call graph. Set depth of nodes. */
+
+static bfd_boolean
+remove_cycles (struct function_info *fun,
+ struct bfd_link_info *info,
+ void *param)
+{
+ struct call_info **callp, *call;
+ unsigned int depth = *(unsigned int *) param;
+ unsigned int max_depth = depth;
+
+ fun->depth = depth;
+ fun->visit2 = TRUE;
+ fun->marking = TRUE;
+
+ callp = &fun->call_list;
+ while ((call = *callp) != NULL)
+ {
+ call->max_depth = depth + !call->is_pasted;
+ if (!call->fun->visit2)
+ {
+ if (!remove_cycles (call->fun, info, &call->max_depth))
+ return FALSE;
+ if (max_depth < call->max_depth)
+ max_depth = call->max_depth;
+ }
+ else if (call->fun->marking)
+ {
+ struct spu_link_hash_table *htab = spu_hash_table (info);
+
+ if (!htab->params->auto_overlay
+ && htab->params->stack_analysis)
+ {
+ const char *f1 = func_name (fun);
+ const char *f2 = func_name (call->fun);
+
+ info->callbacks->info (_("Stack analysis will ignore the call "
+ "from %s to %s\n"),
+ f1, f2);
+ }
+
+ call->broken_cycle = TRUE;
+ }
+ callp = &call->next;
+ }
+ fun->marking = FALSE;
+ *(unsigned int *) param = max_depth;
+ return TRUE;
+}
+
+/* Check that we actually visited all nodes in remove_cycles. If we
+ didn't, then there is some cycle in the call graph not attached to
+ any root node. Arbitrarily choose a node in the cycle as a new
+ root and break the cycle. */
+
+static bfd_boolean
+mark_detached_root (struct function_info *fun,
+ struct bfd_link_info *info,
+ void *param)
+{
+ if (fun->visit2)
+ return TRUE;
+ fun->non_root = FALSE;
+ *(unsigned int *) param = 0;
+ return remove_cycles (fun, info, param);
+}
+
+/* Populate call_list for each function. */
+
+static bfd_boolean
+build_call_tree (struct bfd_link_info *info)
+{
+ bfd *ibfd;
+ unsigned int depth;
+
+ for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next)
+ {
+ extern const bfd_target spu_elf32_vec;
+ asection *sec;
+
+ if (ibfd->xvec != &spu_elf32_vec)
+ continue;
+
+ for (sec = ibfd->sections; sec != NULL; sec = sec->next)
+ if (!mark_functions_via_relocs (sec, info, TRUE))
+ return FALSE;
+ }
+
+ /* Transfer call info from hot/cold section part of function
+ to main entry. */
+ if (!spu_hash_table (info)->params->auto_overlay
+ && !for_each_node (transfer_calls, info, 0, FALSE))
+ return FALSE;
+
+ /* Find the call graph root(s). */
+ if (!for_each_node (mark_non_root, info, 0, FALSE))
+ return FALSE;
+
+ /* Remove cycles from the call graph. We start from the root node(s)
+ so that we break cycles in a reasonable place. */
+ depth = 0;
+ if (!for_each_node (remove_cycles, info, &depth, TRUE))
+ return FALSE;
+
+ return for_each_node (mark_detached_root, info, &depth, FALSE);
+}
+
+/* qsort predicate to sort calls by priority, max_depth then count. */
+
+static int
+sort_calls (const void *a, const void *b)
+{
+ struct call_info *const *c1 = a;
+ struct call_info *const *c2 = b;
+ int delta;
+
+ delta = (*c2)->priority - (*c1)->priority;
+ if (delta != 0)
+ return delta;
+
+ delta = (*c2)->max_depth - (*c1)->max_depth;
+ if (delta != 0)
+ return delta;
+
+ delta = (*c2)->count - (*c1)->count;
+ if (delta != 0)
+ return delta;
+
+ return (char *) c1 - (char *) c2;
+}
+
+struct _mos_param {
+ unsigned int max_overlay_size;
+};
+
+/* Set linker_mark and gc_mark on any sections that we will put in
+ overlays. These flags are used by the generic ELF linker, but we
+ won't be continuing on to bfd_elf_final_link so it is OK to use
+ them. linker_mark is clear before we get here. Set segment_mark
+ on sections that are part of a pasted function (excluding the last
+ section).
+
+ Set up function rodata section if --overlay-rodata. We don't
+ currently include merged string constant rodata sections since
+
+ Sort the call graph so that the deepest nodes will be visited
+ first. */
+
+static bfd_boolean
+mark_overlay_section (struct function_info *fun,
+ struct bfd_link_info *info,
+ void *param)
+{
+ struct call_info *call;
+ unsigned int count;
+ struct _mos_param *mos_param = param;
+ struct spu_link_hash_table *htab = spu_hash_table (info);
+
+ if (fun->visit4)
+ return TRUE;
+
+ fun->visit4 = TRUE;
+ if (!fun->sec->linker_mark
+ && (htab->params->ovly_flavour != ovly_soft_icache
+ || htab->params->non_ia_text
+ || strncmp (fun->sec->name, ".text.ia.", 9) == 0
+ || strcmp (fun->sec->name, ".init") == 0
+ || strcmp (fun->sec->name, ".fini") == 0))
+ {
+ unsigned int size;
+
+ fun->sec->linker_mark = 1;
+ fun->sec->gc_mark = 1;
+ fun->sec->segment_mark = 0;
+ /* Ensure SEC_CODE is set on this text section (it ought to
+ be!), and SEC_CODE is clear on rodata sections. We use
+ this flag to differentiate the two overlay section types. */
+ fun->sec->flags |= SEC_CODE;
+
+ size = fun->sec->size;
+ if (htab->params->auto_overlay & OVERLAY_RODATA)
+ {
+ char *name = NULL;
+
+ /* Find the rodata section corresponding to this function's
+ text section. */
+ if (strcmp (fun->sec->name, ".text") == 0)
+ {
+ name = bfd_malloc (sizeof (".rodata"));
+ if (name == NULL)
+ return FALSE;
+ memcpy (name, ".rodata", sizeof (".rodata"));
+ }
+ else if (strncmp (fun->sec->name, ".text.", 6) == 0)
+ {
+ size_t len = strlen (fun->sec->name);
+ name = bfd_malloc (len + 3);
+ if (name == NULL)
+ return FALSE;
+ memcpy (name, ".rodata", sizeof (".rodata"));
+ memcpy (name + 7, fun->sec->name + 5, len - 4);
+ }
+ else if (strncmp (fun->sec->name, ".gnu.linkonce.t.", 16) == 0)
+ {
+ size_t len = strlen (fun->sec->name) + 1;
+ name = bfd_malloc (len);
+ if (name == NULL)
+ return FALSE;
+ memcpy (name, fun->sec->name, len);
+ name[14] = 'r';
+ }
+
+ if (name != NULL)
+ {
+ asection *rodata = NULL;
+ asection *group_sec = elf_section_data (fun->sec)->next_in_group;
+ if (group_sec == NULL)
+ rodata = bfd_get_section_by_name (fun->sec->owner, name);
+ else
+ while (group_sec != NULL && group_sec != fun->sec)
+ {
+ if (strcmp (group_sec->name, name) == 0)
+ {
+ rodata = group_sec;
+ break;
+ }
+ group_sec = elf_section_data (group_sec)->next_in_group;
+ }
+ fun->rodata = rodata;
+ if (fun->rodata)
+ {
+ size += fun->rodata->size;
+ if (htab->params->line_size != 0
+ && size > htab->params->line_size)
+ {
+ size -= fun->rodata->size;
+ fun->rodata = NULL;
+ }
+ else
+ {
+ fun->rodata->linker_mark = 1;
+ fun->rodata->gc_mark = 1;
+ fun->rodata->flags &= ~SEC_CODE;
+ }
+ }
+ free (name);
+ }
+ }
+ if (mos_param->max_overlay_size < size)
+ mos_param->max_overlay_size = size;
+ }
+
+ for (count = 0, call = fun->call_list; call != NULL; call = call->next)
+ count += 1;
+
+ if (count > 1)
+ {
+ struct call_info **calls = bfd_malloc (count * sizeof (*calls));
+ if (calls == NULL)
+ return FALSE;
+
+ for (count = 0, call = fun->call_list; call != NULL; call = call->next)
+ calls[count++] = call;
+
+ qsort (calls, count, sizeof (*calls), sort_calls);
+
+ fun->call_list = NULL;
+ while (count != 0)
+ {
+ --count;
+ calls[count]->next = fun->call_list;
+ fun->call_list = calls[count];
+ }
+ free (calls);
+ }
+
+ for (call = fun->call_list; call != NULL; call = call->next)
+ {
+ if (call->is_pasted)
+ {
+ /* There can only be one is_pasted call per function_info. */
+ BFD_ASSERT (!fun->sec->segment_mark);
+ fun->sec->segment_mark = 1;
+ }
+ if (!call->broken_cycle
+ && !mark_overlay_section (call->fun, info, param))
+ return FALSE;
+ }
+
+ /* Don't put entry code into an overlay. The overlay manager needs
+ a stack! Also, don't mark .ovl.init as an overlay. */
+ if (fun->lo + fun->sec->output_offset + fun->sec->output_section->vma
+ == info->output_bfd->start_address
+ || strncmp (fun->sec->output_section->name, ".ovl.init", 9) == 0)
+ {
+ fun->sec->linker_mark = 0;
+ if (fun->rodata != NULL)
+ fun->rodata->linker_mark = 0;
+ }
+ return TRUE;
+}
+
+/* If non-zero then unmark functions called from those within sections
+ that we need to unmark. Unfortunately this isn't reliable since the
+ call graph cannot know the destination of function pointer calls. */
+#define RECURSE_UNMARK 0
+
+struct _uos_param {
+ asection *exclude_input_section;
+ asection *exclude_output_section;
+ unsigned long clearing;
+};
+
+/* Undo some of mark_overlay_section's work. */
+
+static bfd_boolean
+unmark_overlay_section (struct function_info *fun,
+ struct bfd_link_info *info,
+ void *param)
+{
+ struct call_info *call;
+ struct _uos_param *uos_param = param;
+ unsigned int excluded = 0;
+
+ if (fun->visit5)
+ return TRUE;
+
+ fun->visit5 = TRUE;
+
+ excluded = 0;
+ if (fun->sec == uos_param->exclude_input_section
+ || fun->sec->output_section == uos_param->exclude_output_section)
+ excluded = 1;
+
+ if (RECURSE_UNMARK)
+ uos_param->clearing += excluded;
+
+ if (RECURSE_UNMARK ? uos_param->clearing : excluded)
+ {
+ fun->sec->linker_mark = 0;
+ if (fun->rodata)
+ fun->rodata->linker_mark = 0;
+ }
+
+ for (call = fun->call_list; call != NULL; call = call->next)
+ if (!call->broken_cycle
+ && !unmark_overlay_section (call->fun, info, param))
+ return FALSE;
+
+ if (RECURSE_UNMARK)
+ uos_param->clearing -= excluded;
+ return TRUE;
+}
+
+struct _cl_param {
+ unsigned int lib_size;
+ asection **lib_sections;
+};
+
+/* Add sections we have marked as belonging to overlays to an array
+ for consideration as non-overlay sections. The array consist of
+ pairs of sections, (text,rodata), for functions in the call graph. */
+
+static bfd_boolean
+collect_lib_sections (struct function_info *fun,
+ struct bfd_link_info *info,
+ void *param)
+{
+ struct _cl_param *lib_param = param;
+ struct call_info *call;
+ unsigned int size;
+
+ if (fun->visit6)
+ return TRUE;
+
+ fun->visit6 = TRUE;
+ if (!fun->sec->linker_mark || !fun->sec->gc_mark || fun->sec->segment_mark)
+ return TRUE;
+
+ size = fun->sec->size;
+ if (fun->rodata)
+ size += fun->rodata->size;
+
+ if (size <= lib_param->lib_size)
+ {
+ *lib_param->lib_sections++ = fun->sec;
+ fun->sec->gc_mark = 0;
+ if (fun->rodata && fun->rodata->linker_mark && fun->rodata->gc_mark)
+ {
+ *lib_param->lib_sections++ = fun->rodata;
+ fun->rodata->gc_mark = 0;
+ }
+ else
+ *lib_param->lib_sections++ = NULL;
+ }
+
+ for (call = fun->call_list; call != NULL; call = call->next)
+ if (!call->broken_cycle)
+ collect_lib_sections (call->fun, info, param);
+
+ return TRUE;
+}
+
+/* qsort predicate to sort sections by call count. */
+
+static int
+sort_lib (const void *a, const void *b)
+{
+ asection *const *s1 = a;
+ asection *const *s2 = b;
+ struct _spu_elf_section_data *sec_data;
+ struct spu_elf_stack_info *sinfo;
+ int delta;
+
+ delta = 0;
+ if ((sec_data = spu_elf_section_data (*s1)) != NULL
+ && (sinfo = sec_data->u.i.stack_info) != NULL)
+ {
+ int i;
+ for (i = 0; i < sinfo->num_fun; ++i)
+ delta -= sinfo->fun[i].call_count;
+ }
+
+ if ((sec_data = spu_elf_section_data (*s2)) != NULL
+ && (sinfo = sec_data->u.i.stack_info) != NULL)
+ {
+ int i;
+ for (i = 0; i < sinfo->num_fun; ++i)
+ delta += sinfo->fun[i].call_count;
+ }
+
+ if (delta != 0)
+ return delta;
+
+ return s1 - s2;
+}
+
+/* Remove some sections from those marked to be in overlays. Choose
+ those that are called from many places, likely library functions. */
+
+static unsigned int
+auto_ovl_lib_functions (struct bfd_link_info *info, unsigned int lib_size)
+{
+ bfd *ibfd;
+ asection **lib_sections;
+ unsigned int i, lib_count;
+ struct _cl_param collect_lib_param;
+ struct function_info dummy_caller;
+ struct spu_link_hash_table *htab;
+
+ memset (&dummy_caller, 0, sizeof (dummy_caller));
+ lib_count = 0;
+ for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next)
+ {
+ extern const bfd_target spu_elf32_vec;
+ asection *sec;
+
+ if (ibfd->xvec != &spu_elf32_vec)
+ continue;
+
+ for (sec = ibfd->sections; sec != NULL; sec = sec->next)
+ if (sec->linker_mark
+ && sec->size < lib_size
+ && (sec->flags & SEC_CODE) != 0)
+ lib_count += 1;
+ }
+ lib_sections = bfd_malloc (lib_count * 2 * sizeof (*lib_sections));
+ if (lib_sections == NULL)
+ return (unsigned int) -1;
+ collect_lib_param.lib_size = lib_size;
+ collect_lib_param.lib_sections = lib_sections;
+ if (!for_each_node (collect_lib_sections, info, &collect_lib_param,
+ TRUE))
+ return (unsigned int) -1;
+ lib_count = (collect_lib_param.lib_sections - lib_sections) / 2;
+
+ /* Sort sections so that those with the most calls are first. */
+ if (lib_count > 1)
+ qsort (lib_sections, lib_count, 2 * sizeof (*lib_sections), sort_lib);
+
+ htab = spu_hash_table (info);
+ for (i = 0; i < lib_count; i++)
+ {
+ unsigned int tmp, stub_size;
+ asection *sec;
+ struct _spu_elf_section_data *sec_data;
+ struct spu_elf_stack_info *sinfo;
+
+ sec = lib_sections[2 * i];
+ /* If this section is OK, its size must be less than lib_size. */
+ tmp = sec->size;
+ /* If it has a rodata section, then add that too. */
+ if (lib_sections[2 * i + 1])
+ tmp += lib_sections[2 * i + 1]->size;
+ /* Add any new overlay call stubs needed by the section. */
+ stub_size = 0;
+ if (tmp < lib_size
+ && (sec_data = spu_elf_section_data (sec)) != NULL
+ && (sinfo = sec_data->u.i.stack_info) != NULL)
+ {
+ int k;
+ struct call_info *call;
+
+ for (k = 0; k < sinfo->num_fun; ++k)
+ for (call = sinfo->fun[k].call_list; call; call = call->next)
+ if (call->fun->sec->linker_mark)
+ {
+ struct call_info *p;
+ for (p = dummy_caller.call_list; p; p = p->next)
+ if (p->fun == call->fun)
+ break;
+ if (!p)
+ stub_size += ovl_stub_size (htab->params);
+ }
+ }
+ if (tmp + stub_size < lib_size)
+ {
+ struct call_info **pp, *p;
+
+ /* This section fits. Mark it as non-overlay. */
+ lib_sections[2 * i]->linker_mark = 0;
+ if (lib_sections[2 * i + 1])
+ lib_sections[2 * i + 1]->linker_mark = 0;
+ lib_size -= tmp + stub_size;
+ /* Call stubs to the section we just added are no longer
+ needed. */
+ pp = &dummy_caller.call_list;
+ while ((p = *pp) != NULL)
+ if (!p->fun->sec->linker_mark)
+ {
+ lib_size += ovl_stub_size (htab->params);
+ *pp = p->next;
+ free (p);
+ }
+ else
+ pp = &p->next;
+ /* Add new call stubs to dummy_caller. */
+ if ((sec_data = spu_elf_section_data (sec)) != NULL
+ && (sinfo = sec_data->u.i.stack_info) != NULL)
+ {
+ int k;
+ struct call_info *call;
+
+ for (k = 0; k < sinfo->num_fun; ++k)
+ for (call = sinfo->fun[k].call_list;
+ call;
+ call = call->next)
+ if (call->fun->sec->linker_mark)
+ {
+ struct call_info *callee;
+ callee = bfd_malloc (sizeof (*callee));
+ if (callee == NULL)
+ return (unsigned int) -1;
+ *callee = *call;
+ if (!insert_callee (&dummy_caller, callee))
+ free (callee);
+ }
+ }
+ }
+ }
+ while (dummy_caller.call_list != NULL)
+ {
+ struct call_info *call = dummy_caller.call_list;
+ dummy_caller.call_list = call->next;
+ free (call);
+ }
+ for (i = 0; i < 2 * lib_count; i++)
+ if (lib_sections[i])
+ lib_sections[i]->gc_mark = 1;
+ free (lib_sections);
+ return lib_size;
+}
+
+/* Build an array of overlay sections. The deepest node's section is
+ added first, then its parent node's section, then everything called
+ from the parent section. The idea being to group sections to
+ minimise calls between different overlays. */
+
+static bfd_boolean
+collect_overlays (struct function_info *fun,
+ struct bfd_link_info *info,
+ void *param)
+{
+ struct call_info *call;
+ bfd_boolean added_fun;
+ asection ***ovly_sections = param;
+
+ if (fun->visit7)
+ return TRUE;
+
+ fun->visit7 = TRUE;
+ for (call = fun->call_list; call != NULL; call = call->next)
+ if (!call->is_pasted && !call->broken_cycle)
+ {
+ if (!collect_overlays (call->fun, info, ovly_sections))
+ return FALSE;
+ break;
+ }
+
+ added_fun = FALSE;
+ if (fun->sec->linker_mark && fun->sec->gc_mark)
+ {
+ fun->sec->gc_mark = 0;
+ *(*ovly_sections)++ = fun->sec;
+ if (fun->rodata && fun->rodata->linker_mark && fun->rodata->gc_mark)
+ {
+ fun->rodata->gc_mark = 0;
+ *(*ovly_sections)++ = fun->rodata;
+ }
+ else
+ *(*ovly_sections)++ = NULL;
+ added_fun = TRUE;
+
+ /* Pasted sections must stay with the first section. We don't
+ put pasted sections in the array, just the first section.
+ Mark subsequent sections as already considered. */
+ if (fun->sec->segment_mark)
+ {
+ struct function_info *call_fun = fun;
+ do
+ {
+ for (call = call_fun->call_list; call != NULL; call = call->next)
+ if (call->is_pasted)
+ {
+ call_fun = call->fun;
+ call_fun->sec->gc_mark = 0;
+ if (call_fun->rodata)
+ call_fun->rodata->gc_mark = 0;
+ break;
+ }
+ if (call == NULL)
+ abort ();
+ }
+ while (call_fun->sec->segment_mark);
+ }
+ }
+
+ for (call = fun->call_list; call != NULL; call = call->next)
+ if (!call->broken_cycle
+ && !collect_overlays (call->fun, info, ovly_sections))
+ return FALSE;
+
+ if (added_fun)
+ {
+ struct _spu_elf_section_data *sec_data;
+ struct spu_elf_stack_info *sinfo;
+
+ if ((sec_data = spu_elf_section_data (fun->sec)) != NULL
+ && (sinfo = sec_data->u.i.stack_info) != NULL)
+ {
+ int i;
+ for (i = 0; i < sinfo->num_fun; ++i)
+ if (!collect_overlays (&sinfo->fun[i], info, ovly_sections))
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+struct _sum_stack_param {
+ size_t cum_stack;
+ size_t overall_stack;
+ bfd_boolean emit_stack_syms;
+};
+
+/* Descend the call graph for FUN, accumulating total stack required. */
+
+static bfd_boolean
+sum_stack (struct function_info *fun,
+ struct bfd_link_info *info,
+ void *param)
+{
+ struct call_info *call;
+ struct function_info *max;
+ size_t stack, cum_stack;
+ const char *f1;
+ bfd_boolean has_call;
+ struct _sum_stack_param *sum_stack_param = param;
+ struct spu_link_hash_table *htab;
+
+ cum_stack = fun->stack;
+ sum_stack_param->cum_stack = cum_stack;
+ if (fun->visit3)
+ return TRUE;
+
+ has_call = FALSE;
+ max = NULL;
+ for (call = fun->call_list; call; call = call->next)
+ {
+ if (call->broken_cycle)
+ continue;
+ if (!call->is_pasted)
+ has_call = TRUE;
+ if (!sum_stack (call->fun, info, sum_stack_param))
+ return FALSE;
+ stack = sum_stack_param->cum_stack;
+ /* Include caller stack for normal calls, don't do so for
+ tail calls. fun->stack here is local stack usage for
+ this function. */
+ if (!call->is_tail || call->is_pasted || call->fun->start != NULL)
+ stack += fun->stack;
+ if (cum_stack < stack)
+ {
+ cum_stack = stack;
+ max = call->fun;
+ }
+ }
+
+ sum_stack_param->cum_stack = cum_stack;
+ stack = fun->stack;
+ /* Now fun->stack holds cumulative stack. */
+ fun->stack = cum_stack;
+ fun->visit3 = TRUE;
+
+ if (!fun->non_root
+ && sum_stack_param->overall_stack < cum_stack)
+ sum_stack_param->overall_stack = cum_stack;
+
+ htab = spu_hash_table (info);
+ if (htab->params->auto_overlay)
+ return TRUE;
+
+ f1 = func_name (fun);
+ if (htab->params->stack_analysis)
+ {
+ if (!fun->non_root)
+ info->callbacks->info (_(" %s: 0x%v\n"), f1, (bfd_vma) cum_stack);
+ info->callbacks->minfo (_("%s: 0x%v 0x%v\n"),
+ f1, (bfd_vma) stack, (bfd_vma) cum_stack);
+
+ if (has_call)
+ {
+ info->callbacks->minfo (_(" calls:\n"));
+ for (call = fun->call_list; call; call = call->next)
+ if (!call->is_pasted && !call->broken_cycle)
+ {
+ const char *f2 = func_name (call->fun);
+ const char *ann1 = call->fun == max ? "*" : " ";
+ const char *ann2 = call->is_tail ? "t" : " ";
+
+ info->callbacks->minfo (_(" %s%s %s\n"), ann1, ann2, f2);
+ }
+ }
+ }
+
+ if (sum_stack_param->emit_stack_syms)
+ {
+ char *name = bfd_malloc (18 + strlen (f1));
+ struct elf_link_hash_entry *h;
+
+ if (name == NULL)
+ return FALSE;
+
+ if (fun->global || ELF_ST_BIND (fun->u.sym->st_info) == STB_GLOBAL)
+ sprintf (name, "__stack_%s", f1);
+ else
+ sprintf (name, "__stack_%x_%s", fun->sec->id & 0xffffffff, f1);
+
+ h = elf_link_hash_lookup (&htab->elf, name, TRUE, TRUE, FALSE);
+ free (name);
+ if (h != NULL
+ && (h->root.type == bfd_link_hash_new
+ || h->root.type == bfd_link_hash_undefined
+ || h->root.type == bfd_link_hash_undefweak))
+ {
+ h->root.type = bfd_link_hash_defined;
+ h->root.u.def.section = bfd_abs_section_ptr;
+ h->root.u.def.value = cum_stack;
+ h->size = 0;
+ h->type = 0;
+ h->ref_regular = 1;
+ h->def_regular = 1;
+ h->ref_regular_nonweak = 1;
+ h->forced_local = 1;
+ h->non_elf = 0;
+ }
+ }
+
+ return TRUE;
+}
+
+/* SEC is part of a pasted function. Return the call_info for the
+ next section of this function. */
+
+static struct call_info *
+find_pasted_call (asection *sec)
+{
+ struct _spu_elf_section_data *sec_data = spu_elf_section_data (sec);
+ struct spu_elf_stack_info *sinfo = sec_data->u.i.stack_info;
+ struct call_info *call;
+ int k;
+
+ for (k = 0; k < sinfo->num_fun; ++k)
+ for (call = sinfo->fun[k].call_list; call != NULL; call = call->next)
+ if (call->is_pasted)
+ return call;
+ abort ();
+ return 0;
+}
+
+/* qsort predicate to sort bfds by file name. */
+
+static int
+sort_bfds (const void *a, const void *b)
+{
+ bfd *const *abfd1 = a;
+ bfd *const *abfd2 = b;
+
+ return filename_cmp ((*abfd1)->filename, (*abfd2)->filename);
+}
+
+static unsigned int
+print_one_overlay_section (FILE *script,
+ unsigned int base,
+ unsigned int count,
+ unsigned int ovlynum,
+ unsigned int *ovly_map,
+ asection **ovly_sections,
+ struct bfd_link_info *info)
+{
+ unsigned int j;
+
+ for (j = base; j < count && ovly_map[j] == ovlynum; j++)
+ {
+ asection *sec = ovly_sections[2 * j];
+
+ if (fprintf (script, " %s%c%s (%s)\n",
+ (sec->owner->my_archive != NULL
+ ? sec->owner->my_archive->filename : ""),
+ info->path_separator,
+ sec->owner->filename,
+ sec->name) <= 0)
+ return -1;
+ if (sec->segment_mark)
+ {
+ struct call_info *call = find_pasted_call (sec);
+ while (call != NULL)
+ {
+ struct function_info *call_fun = call->fun;
+ sec = call_fun->sec;
+ if (fprintf (script, " %s%c%s (%s)\n",
+ (sec->owner->my_archive != NULL
+ ? sec->owner->my_archive->filename : ""),
+ info->path_separator,
+ sec->owner->filename,
+ sec->name) <= 0)
+ return -1;
+ for (call = call_fun->call_list; call; call = call->next)
+ if (call->is_pasted)
+ break;
+ }
+ }
+ }
+
+ for (j = base; j < count && ovly_map[j] == ovlynum; j++)
+ {
+ asection *sec = ovly_sections[2 * j + 1];
+ if (sec != NULL
+ && fprintf (script, " %s%c%s (%s)\n",
+ (sec->owner->my_archive != NULL
+ ? sec->owner->my_archive->filename : ""),
+ info->path_separator,
+ sec->owner->filename,
+ sec->name) <= 0)
+ return -1;
+
+ sec = ovly_sections[2 * j];
+ if (sec->segment_mark)
+ {
+ struct call_info *call = find_pasted_call (sec);
+ while (call != NULL)
+ {
+ struct function_info *call_fun = call->fun;
+ sec = call_fun->rodata;
+ if (sec != NULL
+ && fprintf (script, " %s%c%s (%s)\n",
+ (sec->owner->my_archive != NULL
+ ? sec->owner->my_archive->filename : ""),
+ info->path_separator,
+ sec->owner->filename,
+ sec->name) <= 0)
+ return -1;
+ for (call = call_fun->call_list; call; call = call->next)
+ if (call->is_pasted)
+ break;
+ }
+ }
+ }
+
+ return j;
+}
+
+/* Handle --auto-overlay. */
+
+static void
+spu_elf_auto_overlay (struct bfd_link_info *info)
+{
+ bfd *ibfd;
+ bfd **bfd_arr;
+ struct elf_segment_map *m;
+ unsigned int fixed_size, lo, hi;
+ unsigned int reserved;
+ struct spu_link_hash_table *htab;
+ unsigned int base, i, count, bfd_count;
+ unsigned int region, ovlynum;
+ asection **ovly_sections, **ovly_p;
+ unsigned int *ovly_map;
+ FILE *script;
+ unsigned int total_overlay_size, overlay_size;
+ const char *ovly_mgr_entry;
+ struct elf_link_hash_entry *h;
+ struct _mos_param mos_param;
+ struct _uos_param uos_param;
+ struct function_info dummy_caller;
+
+ /* Find the extents of our loadable image. */
+ lo = (unsigned int) -1;
+ hi = 0;
+ for (m = elf_seg_map (info->output_bfd); m != NULL; m = m->next)
+ if (m->p_type == PT_LOAD)
+ for (i = 0; i < m->count; i++)
+ if (m->sections[i]->size != 0)
+ {
+ if (m->sections[i]->vma < lo)
+ lo = m->sections[i]->vma;
+ if (m->sections[i]->vma + m->sections[i]->size - 1 > hi)
+ hi = m->sections[i]->vma + m->sections[i]->size - 1;
+ }
+ fixed_size = hi + 1 - lo;
+
+ if (!discover_functions (info))
+ goto err_exit;
+
+ if (!build_call_tree (info))
+ goto err_exit;
+
+ htab = spu_hash_table (info);
+ reserved = htab->params->auto_overlay_reserved;
+ if (reserved == 0)
+ {
+ struct _sum_stack_param sum_stack_param;
+
+ sum_stack_param.emit_stack_syms = 0;
+ sum_stack_param.overall_stack = 0;
+ if (!for_each_node (sum_stack, info, &sum_stack_param, TRUE))
+ goto err_exit;
+ reserved = (sum_stack_param.overall_stack
+ + htab->params->extra_stack_space);
+ }
+
+ /* No need for overlays if everything already fits. */
+ if (fixed_size + reserved <= htab->local_store
+ && htab->params->ovly_flavour != ovly_soft_icache)
+ {
+ htab->params->auto_overlay = 0;
+ return;
+ }
+
+ uos_param.exclude_input_section = 0;
+ uos_param.exclude_output_section
+ = bfd_get_section_by_name (info->output_bfd, ".interrupt");
+
+ ovly_mgr_entry = "__ovly_load";
+ if (htab->params->ovly_flavour == ovly_soft_icache)
+ ovly_mgr_entry = "__icache_br_handler";
+ h = elf_link_hash_lookup (&htab->elf, ovly_mgr_entry,
+ FALSE, FALSE, FALSE);
+ if (h != NULL
+ && (h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak)
+ && h->def_regular)
+ {
+ /* We have a user supplied overlay manager. */
+ uos_param.exclude_input_section = h->root.u.def.section;
+ }
+ else
+ {
+ /* If no user overlay manager, spu_elf_load_ovl_mgr will add our
+ builtin version to .text, and will adjust .text size. */
+ fixed_size += (*htab->params->spu_elf_load_ovl_mgr) ();
+ }
+
+ /* Mark overlay sections, and find max overlay section size. */
+ mos_param.max_overlay_size = 0;
+ if (!for_each_node (mark_overlay_section, info, &mos_param, TRUE))
+ goto err_exit;
+
+ /* We can't put the overlay manager or interrupt routines in
+ overlays. */
+ uos_param.clearing = 0;
+ if ((uos_param.exclude_input_section
+ || uos_param.exclude_output_section)
+ && !for_each_node (unmark_overlay_section, info, &uos_param, TRUE))
+ goto err_exit;
+
+ bfd_count = 0;
+ for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next)
+ ++bfd_count;
+ bfd_arr = bfd_malloc (bfd_count * sizeof (*bfd_arr));
+ if (bfd_arr == NULL)
+ goto err_exit;
+
+ /* Count overlay sections, and subtract their sizes from "fixed_size". */
+ count = 0;
+ bfd_count = 0;
+ total_overlay_size = 0;
+ for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next)
+ {
+ extern const bfd_target spu_elf32_vec;
+ asection *sec;
+ unsigned int old_count;
+
+ if (ibfd->xvec != &spu_elf32_vec)
+ continue;
+
+ old_count = count;
+ for (sec = ibfd->sections; sec != NULL; sec = sec->next)
+ if (sec->linker_mark)
+ {
+ if ((sec->flags & SEC_CODE) != 0)
+ count += 1;
+ fixed_size -= sec->size;
+ total_overlay_size += sec->size;
+ }
+ else if ((sec->flags & (SEC_ALLOC | SEC_LOAD)) == (SEC_ALLOC | SEC_LOAD)
+ && sec->output_section->owner == info->output_bfd
+ && strncmp (sec->output_section->name, ".ovl.init", 9) == 0)
+ fixed_size -= sec->size;
+ if (count != old_count)
+ bfd_arr[bfd_count++] = ibfd;
+ }
+
+ /* Since the overlay link script selects sections by file name and
+ section name, ensure that file names are unique. */
+ if (bfd_count > 1)
+ {
+ bfd_boolean ok = TRUE;
+
+ qsort (bfd_arr, bfd_count, sizeof (*bfd_arr), sort_bfds);
+ for (i = 1; i < bfd_count; ++i)
+ if (filename_cmp (bfd_arr[i - 1]->filename, bfd_arr[i]->filename) == 0)
+ {
+ if (bfd_arr[i - 1]->my_archive == bfd_arr[i]->my_archive)
+ {
+ if (bfd_arr[i - 1]->my_archive && bfd_arr[i]->my_archive)
+ info->callbacks->einfo (_("%s duplicated in %s\n"),
+ bfd_arr[i]->filename,
+ bfd_arr[i]->my_archive->filename);
+ else
+ info->callbacks->einfo (_("%s duplicated\n"),
+ bfd_arr[i]->filename);
+ ok = FALSE;
+ }
+ }
+ if (!ok)
+ {
+ info->callbacks->einfo (_("sorry, no support for duplicate "
+ "object files in auto-overlay script\n"));
+ bfd_set_error (bfd_error_bad_value);
+ goto err_exit;
+ }
+ }
+ free (bfd_arr);
+
+ fixed_size += reserved;
+ fixed_size += htab->non_ovly_stub * ovl_stub_size (htab->params);
+ if (fixed_size + mos_param.max_overlay_size <= htab->local_store)
+ {
+ if (htab->params->ovly_flavour == ovly_soft_icache)
+ {
+ /* Stubs in the non-icache area are bigger. */
+ fixed_size += htab->non_ovly_stub * 16;
+ /* Space for icache manager tables.
+ a) Tag array, one quadword per cache line.
+ - word 0: ia address of present line, init to zero. */
+ fixed_size += 16 << htab->num_lines_log2;
+ /* b) Rewrite "to" list, one quadword per cache line. */
+ fixed_size += 16 << htab->num_lines_log2;
+ /* c) Rewrite "from" list, one byte per outgoing branch (rounded up
+ to a power-of-two number of full quadwords) per cache line. */
+ fixed_size += 16 << (htab->fromelem_size_log2
+ + htab->num_lines_log2);
+ /* d) Pointer to __ea backing store (toe), 1 quadword. */
+ fixed_size += 16;
+ }
+ else
+ {
+ /* Guess number of overlays. Assuming overlay buffer is on
+ average only half full should be conservative. */
+ ovlynum = (total_overlay_size * 2 * htab->params->num_lines
+ / (htab->local_store - fixed_size));
+ /* Space for _ovly_table[], _ovly_buf_table[] and toe. */
+ fixed_size += ovlynum * 16 + 16 + 4 + 16;
+ }
+ }
+
+ if (fixed_size + mos_param.max_overlay_size > htab->local_store)
+ info->callbacks->einfo (_("non-overlay size of 0x%v plus maximum overlay "
+ "size of 0x%v exceeds local store\n"),
+ (bfd_vma) fixed_size,
+ (bfd_vma) mos_param.max_overlay_size);
+
+ /* Now see if we should put some functions in the non-overlay area. */
+ else if (fixed_size < htab->params->auto_overlay_fixed)
+ {
+ unsigned int max_fixed, lib_size;
+
+ max_fixed = htab->local_store - mos_param.max_overlay_size;
+ if (max_fixed > htab->params->auto_overlay_fixed)
+ max_fixed = htab->params->auto_overlay_fixed;
+ lib_size = max_fixed - fixed_size;
+ lib_size = auto_ovl_lib_functions (info, lib_size);
+ if (lib_size == (unsigned int) -1)
+ goto err_exit;
+ fixed_size = max_fixed - lib_size;
+ }
+
+ /* Build an array of sections, suitably sorted to place into
+ overlays. */
+ ovly_sections = bfd_malloc (2 * count * sizeof (*ovly_sections));
+ if (ovly_sections == NULL)
+ goto err_exit;
+ ovly_p = ovly_sections;
+ if (!for_each_node (collect_overlays, info, &ovly_p, TRUE))
+ goto err_exit;
+ count = (size_t) (ovly_p - ovly_sections) / 2;
+ ovly_map = bfd_malloc (count * sizeof (*ovly_map));
+ if (ovly_map == NULL)
+ goto err_exit;
+
+ memset (&dummy_caller, 0, sizeof (dummy_caller));
+ overlay_size = (htab->local_store - fixed_size) / htab->params->num_lines;
+ if (htab->params->line_size != 0)
+ overlay_size = htab->params->line_size;
+ base = 0;
+ ovlynum = 0;
+ while (base < count)
+ {
+ unsigned int size = 0, rosize = 0, roalign = 0;
+
+ for (i = base; i < count; i++)
+ {
+ asection *sec, *rosec;
+ unsigned int tmp, rotmp;
+ unsigned int num_stubs;
+ struct call_info *call, *pasty;
+ struct _spu_elf_section_data *sec_data;
+ struct spu_elf_stack_info *sinfo;
+ unsigned int k;
+
+ /* See whether we can add this section to the current
+ overlay without overflowing our overlay buffer. */
+ sec = ovly_sections[2 * i];
+ tmp = align_power (size, sec->alignment_power) + sec->size;
+ rotmp = rosize;
+ rosec = ovly_sections[2 * i + 1];
+ if (rosec != NULL)
+ {
+ rotmp = align_power (rotmp, rosec->alignment_power) + rosec->size;
+ if (roalign < rosec->alignment_power)
+ roalign = rosec->alignment_power;
+ }
+ if (align_power (tmp, roalign) + rotmp > overlay_size)
+ break;
+ if (sec->segment_mark)
+ {
+ /* Pasted sections must stay together, so add their
+ sizes too. */
+ pasty = find_pasted_call (sec);
+ while (pasty != NULL)
+ {
+ struct function_info *call_fun = pasty->fun;
+ tmp = (align_power (tmp, call_fun->sec->alignment_power)
+ + call_fun->sec->size);
+ if (call_fun->rodata)
+ {
+ rotmp = (align_power (rotmp,
+ call_fun->rodata->alignment_power)
+ + call_fun->rodata->size);
+ if (roalign < rosec->alignment_power)
+ roalign = rosec->alignment_power;
+ }
+ for (pasty = call_fun->call_list; pasty; pasty = pasty->next)
+ if (pasty->is_pasted)
+ break;
+ }
+ }
+ if (align_power (tmp, roalign) + rotmp > overlay_size)
+ break;
+
+ /* If we add this section, we might need new overlay call
+ stubs. Add any overlay section calls to dummy_call. */
+ pasty = NULL;
+ sec_data = spu_elf_section_data (sec);
+ sinfo = sec_data->u.i.stack_info;
+ for (k = 0; k < (unsigned) sinfo->num_fun; ++k)
+ for (call = sinfo->fun[k].call_list; call; call = call->next)
+ if (call->is_pasted)
+ {
+ BFD_ASSERT (pasty == NULL);
+ pasty = call;
+ }
+ else if (call->fun->sec->linker_mark)
+ {
+ if (!copy_callee (&dummy_caller, call))
+ goto err_exit;
+ }
+ while (pasty != NULL)
+ {
+ struct function_info *call_fun = pasty->fun;
+ pasty = NULL;
+ for (call = call_fun->call_list; call; call = call->next)
+ if (call->is_pasted)
+ {
+ BFD_ASSERT (pasty == NULL);
+ pasty = call;
+ }
+ else if (!copy_callee (&dummy_caller, call))
+ goto err_exit;
+ }
+
+ /* Calculate call stub size. */
+ num_stubs = 0;
+ for (call = dummy_caller.call_list; call; call = call->next)
+ {
+ unsigned int stub_delta = 1;
+
+ if (htab->params->ovly_flavour == ovly_soft_icache)
+ stub_delta = call->count;
+ num_stubs += stub_delta;
+
+ /* If the call is within this overlay, we won't need a
+ stub. */
+ for (k = base; k < i + 1; k++)
+ if (call->fun->sec == ovly_sections[2 * k])
+ {
+ num_stubs -= stub_delta;
+ break;
+ }
+ }
+ if (htab->params->ovly_flavour == ovly_soft_icache
+ && num_stubs > htab->params->max_branch)
+ break;
+ if (align_power (tmp, roalign) + rotmp
+ + num_stubs * ovl_stub_size (htab->params) > overlay_size)
+ break;
+ size = tmp;
+ rosize = rotmp;
+ }
+
+ if (i == base)
+ {
+ info->callbacks->einfo (_("%B:%A%s exceeds overlay size\n"),
+ ovly_sections[2 * i]->owner,
+ ovly_sections[2 * i],
+ ovly_sections[2 * i + 1] ? " + rodata" : "");
+ bfd_set_error (bfd_error_bad_value);
+ goto err_exit;
+ }
+
+ while (dummy_caller.call_list != NULL)
+ {
+ struct call_info *call = dummy_caller.call_list;
+ dummy_caller.call_list = call->next;
+ free (call);
+ }
+
+ ++ovlynum;
+ while (base < i)
+ ovly_map[base++] = ovlynum;
+ }
+
+ script = htab->params->spu_elf_open_overlay_script ();
+
+ if (htab->params->ovly_flavour == ovly_soft_icache)
+ {
+ if (fprintf (script, "SECTIONS\n{\n") <= 0)
+ goto file_err;
+
+ if (fprintf (script,
+ " . = ALIGN (%u);\n"
+ " .ovl.init : { *(.ovl.init) }\n"
+ " . = ABSOLUTE (ADDR (.ovl.init));\n",
+ htab->params->line_size) <= 0)
+ goto file_err;
+
+ base = 0;
+ ovlynum = 1;
+ while (base < count)
+ {
+ unsigned int indx = ovlynum - 1;
+ unsigned int vma, lma;
+
+ vma = (indx & (htab->params->num_lines - 1)) << htab->line_size_log2;
+ lma = vma + (((indx >> htab->num_lines_log2) + 1) << 18);
+
+ if (fprintf (script, " .ovly%u ABSOLUTE (ADDR (.ovl.init)) + %u "
+ ": AT (LOADADDR (.ovl.init) + %u) {\n",
+ ovlynum, vma, lma) <= 0)
+ goto file_err;
+
+ base = print_one_overlay_section (script, base, count, ovlynum,
+ ovly_map, ovly_sections, info);
+ if (base == (unsigned) -1)
+ goto file_err;
+
+ if (fprintf (script, " }\n") <= 0)
+ goto file_err;
+
+ ovlynum++;
+ }
+
+ if (fprintf (script, " . = ABSOLUTE (ADDR (.ovl.init)) + %u;\n",
+ 1 << (htab->num_lines_log2 + htab->line_size_log2)) <= 0)
+ goto file_err;
+
+ if (fprintf (script, "}\nINSERT AFTER .toe;\n") <= 0)
+ goto file_err;
+ }
+ else
+ {
+ if (fprintf (script, "SECTIONS\n{\n") <= 0)
+ goto file_err;
+
+ if (fprintf (script,
+ " . = ALIGN (16);\n"
+ " .ovl.init : { *(.ovl.init) }\n"
+ " . = ABSOLUTE (ADDR (.ovl.init));\n") <= 0)
+ goto file_err;
+
+ for (region = 1; region <= htab->params->num_lines; region++)
+ {
+ ovlynum = region;
+ base = 0;
+ while (base < count && ovly_map[base] < ovlynum)
+ base++;
+
+ if (base == count)
+ break;
+
+ if (region == 1)
+ {
+ /* We need to set lma since we are overlaying .ovl.init. */
+ if (fprintf (script,
+ " OVERLAY : AT (ALIGN (LOADADDR (.ovl.init) + SIZEOF (.ovl.init), 16))\n {\n") <= 0)
+ goto file_err;
+ }
+ else
+ {
+ if (fprintf (script, " OVERLAY :\n {\n") <= 0)
+ goto file_err;
+ }
+
+ while (base < count)
+ {
+ if (fprintf (script, " .ovly%u {\n", ovlynum) <= 0)
+ goto file_err;
+
+ base = print_one_overlay_section (script, base, count, ovlynum,
+ ovly_map, ovly_sections, info);
+ if (base == (unsigned) -1)
+ goto file_err;
+
+ if (fprintf (script, " }\n") <= 0)
+ goto file_err;
+
+ ovlynum += htab->params->num_lines;
+ while (base < count && ovly_map[base] < ovlynum)
+ base++;
+ }
+
+ if (fprintf (script, " }\n") <= 0)
+ goto file_err;
+ }
+
+ if (fprintf (script, "}\nINSERT BEFORE .text;\n") <= 0)
+ goto file_err;
+ }
+
+ free (ovly_map);
+ free (ovly_sections);
+
+ if (fclose (script) != 0)
+ goto file_err;
+
+ if (htab->params->auto_overlay & AUTO_RELINK)
+ (*htab->params->spu_elf_relink) ();
+
+ xexit (0);
+
+ file_err:
+ bfd_set_error (bfd_error_system_call);
+ err_exit:
+ info->callbacks->einfo ("%F%P: auto overlay error: %E\n");
+ xexit (1);
+}
+
+/* Provide an estimate of total stack required. */
+
+static bfd_boolean
+spu_elf_stack_analysis (struct bfd_link_info *info)
+{
+ struct spu_link_hash_table *htab;
+ struct _sum_stack_param sum_stack_param;
+
+ if (!discover_functions (info))
+ return FALSE;
+
+ if (!build_call_tree (info))
+ return FALSE;
+
+ htab = spu_hash_table (info);
+ if (htab->params->stack_analysis)
+ {
+ info->callbacks->info (_("Stack size for call graph root nodes.\n"));
+ info->callbacks->minfo (_("\nStack size for functions. "
+ "Annotations: '*' max stack, 't' tail call\n"));
+ }
+
+ sum_stack_param.emit_stack_syms = htab->params->emit_stack_syms;
+ sum_stack_param.overall_stack = 0;
+ if (!for_each_node (sum_stack, info, &sum_stack_param, TRUE))
+ return FALSE;
+
+ if (htab->params->stack_analysis)
+ info->callbacks->info (_("Maximum stack required is 0x%v\n"),
+ (bfd_vma) sum_stack_param.overall_stack);
+ return TRUE;
+}
+
+/* Perform a final link. */
+
+static bfd_boolean
+spu_elf_final_link (bfd *output_bfd, struct bfd_link_info *info)
+{
+ struct spu_link_hash_table *htab = spu_hash_table (info);
+
+ if (htab->params->auto_overlay)
+ spu_elf_auto_overlay (info);
+
+ if ((htab->params->stack_analysis
+ || (htab->params->ovly_flavour == ovly_soft_icache
+ && htab->params->lrlive_analysis))
+ && !spu_elf_stack_analysis (info))
+ info->callbacks->einfo ("%X%P: stack/lrlive analysis error: %E\n");
+
+ if (!spu_elf_build_stubs (info))
+ info->callbacks->einfo ("%F%P: can not build overlay stubs: %E\n");
+
+ return bfd_elf_final_link (output_bfd, info);
+}
+
+/* Called when not normally emitting relocs, ie. !info->relocatable
+ and !info->emitrelocations. Returns a count of special relocs
+ that need to be emitted. */
+
+static unsigned int
+spu_elf_count_relocs (struct bfd_link_info *info, asection *sec)
+{
+ Elf_Internal_Rela *relocs;
+ unsigned int count = 0;
+
+ relocs = _bfd_elf_link_read_relocs (sec->owner, sec, NULL, NULL,
+ info->keep_memory);
+ if (relocs != NULL)
+ {
+ Elf_Internal_Rela *rel;
+ Elf_Internal_Rela *relend = relocs + sec->reloc_count;
+
+ for (rel = relocs; rel < relend; rel++)
+ {
+ int r_type = ELF32_R_TYPE (rel->r_info);
+ if (r_type == R_SPU_PPU32 || r_type == R_SPU_PPU64)
+ ++count;
+ }
+
+ if (elf_section_data (sec)->relocs != relocs)
+ free (relocs);
+ }
+
+ return count;
+}
+
+/* Functions for adding fixup records to .fixup */
+
+#define FIXUP_RECORD_SIZE 4
+
+#define FIXUP_PUT(output_bfd,htab,index,addr) \
+ bfd_put_32 (output_bfd, addr, \
+ htab->sfixup->contents + FIXUP_RECORD_SIZE * (index))
+#define FIXUP_GET(output_bfd,htab,index) \
+ bfd_get_32 (output_bfd, \
+ htab->sfixup->contents + FIXUP_RECORD_SIZE * (index))
+
+/* Store OFFSET in .fixup. This assumes it will be called with an
+ increasing OFFSET. When this OFFSET fits with the last base offset,
+ it just sets a bit, otherwise it adds a new fixup record. */
+static void
+spu_elf_emit_fixup (bfd * output_bfd, struct bfd_link_info *info,
+ bfd_vma offset)
+{
+ struct spu_link_hash_table *htab = spu_hash_table (info);
+ asection *sfixup = htab->sfixup;
+ bfd_vma qaddr = offset & ~(bfd_vma) 15;
+ bfd_vma bit = ((bfd_vma) 8) >> ((offset & 15) >> 2);
+ if (sfixup->reloc_count == 0)
+ {
+ FIXUP_PUT (output_bfd, htab, 0, qaddr | bit);
+ sfixup->reloc_count++;
+ }
+ else
+ {
+ bfd_vma base = FIXUP_GET (output_bfd, htab, sfixup->reloc_count - 1);
+ if (qaddr != (base & ~(bfd_vma) 15))
+ {
+ if ((sfixup->reloc_count + 1) * FIXUP_RECORD_SIZE > sfixup->size)
+ (*_bfd_error_handler) (_("fatal error while creating .fixup"));
+ FIXUP_PUT (output_bfd, htab, sfixup->reloc_count, qaddr | bit);
+ sfixup->reloc_count++;
+ }
+ else
+ FIXUP_PUT (output_bfd, htab, sfixup->reloc_count - 1, base | bit);
+ }
+}
+
+/* Apply RELOCS to CONTENTS of INPUT_SECTION from INPUT_BFD. */
+
+static int
+spu_elf_relocate_section (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;
+ struct spu_link_hash_table *htab;
+ asection *ea;
+ int ret = TRUE;
+ bfd_boolean emit_these_relocs = FALSE;
+ bfd_boolean is_ea_sym;
+ bfd_boolean stubs;
+ unsigned int iovl = 0;
+
+ htab = spu_hash_table (info);
+ stubs = (htab->stub_sec != NULL
+ && maybe_needs_stubs (input_section));
+ iovl = overlay_index (input_section);
+ ea = bfd_get_section_by_name (output_bfd, "._ea");
+ symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
+ sym_hashes = (struct elf_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 int r_symndx;
+ Elf_Internal_Sym *sym;
+ asection *sec;
+ struct elf_link_hash_entry *h;
+ const char *sym_name;
+ bfd_vma relocation;
+ bfd_vma addend;
+ bfd_reloc_status_type r;
+ bfd_boolean unresolved_reloc;
+ enum _stub_type stub_type;
+
+ r_symndx = ELF32_R_SYM (rel->r_info);
+ r_type = ELF32_R_TYPE (rel->r_info);
+ howto = elf_howto_table + r_type;
+ unresolved_reloc = FALSE;
+ h = NULL;
+ sym = NULL;
+ sec = NULL;
+ if (r_symndx < symtab_hdr->sh_info)
+ {
+ sym = local_syms + r_symndx;
+ sec = local_sections[r_symndx];
+ sym_name = bfd_elf_sym_name (input_bfd, symtab_hdr, sym, sec);
+ relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
+ }
+ else
+ {
+ if (sym_hashes == NULL)
+ return FALSE;
+
+ h = sym_hashes[r_symndx - symtab_hdr->sh_info];
+
+ if (info->wrap_hash != NULL
+ && (input_section->flags & SEC_DEBUGGING) != 0)
+ h = ((struct elf_link_hash_entry *)
+ unwrap_hash_lookup (info, input_bfd, &h->root));
+
+ 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;
+
+ relocation = 0;
+ if (h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak)
+ {
+ sec = h->root.u.def.section;
+ if (sec == NULL
+ || sec->output_section == NULL)
+ /* Set a flag that will be cleared later if we find a
+ relocation value for this symbol. output_section
+ is typically NULL for symbols satisfied by a shared
+ library. */
+ unresolved_reloc = TRUE;
+ else
+ relocation = (h->root.u.def.value
+ + sec->output_section->vma
+ + sec->output_offset);
+ }
+ else if (h->root.type == bfd_link_hash_undefweak)
+ ;
+ else if (info->unresolved_syms_in_objects == RM_IGNORE
+ && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)
+ ;
+ else if (!info->relocatable
+ && !(r_type == R_SPU_PPU32 || r_type == R_SPU_PPU64))
+ {
+ bfd_boolean err;
+ err = (info->unresolved_syms_in_objects == RM_GENERATE_ERROR
+ || ELF_ST_VISIBILITY (h->other) != STV_DEFAULT);
+ if (!info->callbacks->undefined_symbol (info,
+ h->root.root.string,
+ input_bfd,
+ input_section,
+ rel->r_offset, err))
+ return FALSE;
+ }
+ sym_name = h->root.root.string;
+ }
+
+ if (sec != NULL && discarded_section (sec))
+ RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+ rel, 1, relend, howto, 0, contents);
+
+ if (info->relocatable)
+ continue;
+
+ /* Change "a rt,ra,rb" to "ai rt,ra,0". */
+ if (r_type == R_SPU_ADD_PIC
+ && h != NULL
+ && !(h->def_regular || ELF_COMMON_DEF_P (h)))
+ {
+ bfd_byte *loc = contents + rel->r_offset;
+ loc[0] = 0x1c;
+ loc[1] = 0x00;
+ loc[2] &= 0x3f;
+ }
+
+ is_ea_sym = (ea != NULL
+ && sec != NULL
+ && sec->output_section == ea);
+
+ /* If this symbol is in an overlay area, we may need to relocate
+ to the overlay stub. */
+ addend = rel->r_addend;
+ if (stubs
+ && !is_ea_sym
+ && (stub_type = needs_ovl_stub (h, sym, sec, input_section, rel,
+ contents, info)) != no_stub)
+ {
+ unsigned int ovl = 0;
+ struct got_entry *g, **head;
+
+ if (stub_type != nonovl_stub)
+ ovl = iovl;
+
+ if (h != NULL)
+ head = &h->got.glist;
+ else
+ head = elf_local_got_ents (input_bfd) + r_symndx;
+
+ for (g = *head; g != NULL; g = g->next)
+ if (htab->params->ovly_flavour == ovly_soft_icache
+ ? (g->ovl == ovl
+ && g->br_addr == (rel->r_offset
+ + input_section->output_offset
+ + input_section->output_section->vma))
+ : g->addend == addend && (g->ovl == ovl || g->ovl == 0))
+ break;
+ if (g == NULL)
+ abort ();
+
+ relocation = g->stub_addr;
+ addend = 0;
+ }
+ else
+ {
+ /* For soft icache, encode the overlay index into addresses. */
+ if (htab->params->ovly_flavour == ovly_soft_icache
+ && (r_type == R_SPU_ADDR16_HI
+ || r_type == R_SPU_ADDR32 || r_type == R_SPU_REL32)
+ && !is_ea_sym)
+ {
+ unsigned int ovl = overlay_index (sec);
+ if (ovl != 0)
+ {
+ unsigned int set_id = ((ovl - 1) >> htab->num_lines_log2) + 1;
+ relocation += set_id << 18;
+ }
+ }
+ }
+
+ if (htab->params->emit_fixups && !info->relocatable
+ && (input_section->flags & SEC_ALLOC) != 0
+ && r_type == R_SPU_ADDR32)
+ {
+ bfd_vma offset;
+ offset = rel->r_offset + input_section->output_section->vma
+ + input_section->output_offset;
+ spu_elf_emit_fixup (output_bfd, info, offset);
+ }
+
+ if (unresolved_reloc)
+ ;
+ else if (r_type == R_SPU_PPU32 || r_type == R_SPU_PPU64)
+ {
+ if (is_ea_sym)
+ {
+ /* ._ea is a special section that isn't allocated in SPU
+ memory, but rather occupies space in PPU memory as
+ part of an embedded ELF image. If this reloc is
+ against a symbol defined in ._ea, then transform the
+ reloc into an equivalent one without a symbol
+ relative to the start of the ELF image. */
+ rel->r_addend += (relocation
+ - ea->vma
+ + elf_section_data (ea)->this_hdr.sh_offset);
+ rel->r_info = ELF32_R_INFO (0, r_type);
+ }
+ emit_these_relocs = TRUE;
+ continue;
+ }
+ else if (is_ea_sym)
+ unresolved_reloc = TRUE;
+
+ if (unresolved_reloc
+ && _bfd_elf_section_offset (output_bfd, info, input_section,
+ rel->r_offset) != (bfd_vma) -1)
+ {
+ (*_bfd_error_handler)
+ (_("%B(%s+0x%lx): unresolvable %s relocation against symbol `%s'"),
+ input_bfd,
+ bfd_get_section_name (input_bfd, input_section),
+ (long) rel->r_offset,
+ howto->name,
+ sym_name);
+ ret = FALSE;
+ }
+
+ r = _bfd_final_link_relocate (howto,
+ input_bfd,
+ input_section,
+ contents,
+ rel->r_offset, relocation, addend);
+
+ if (r != bfd_reloc_ok)
+ {
+ const char *msg = (const char *) 0;
+
+ switch (r)
+ {
+ case bfd_reloc_overflow:
+ if (!((*info->callbacks->reloc_overflow)
+ (info, (h ? &h->root : NULL), sym_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, sym_name, input_bfd, input_section,
+ rel->r_offset, TRUE)))
+ 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:
+ ret = FALSE;
+ if (!((*info->callbacks->warning)
+ (info, msg, sym_name, input_bfd, input_section,
+ rel->r_offset)))
+ return FALSE;
+ break;
+ }
+ }
+ }
+
+ if (ret
+ && emit_these_relocs
+ && !info->emitrelocations)
+ {
+ Elf_Internal_Rela *wrel;
+ Elf_Internal_Shdr *rel_hdr;
+
+ wrel = rel = relocs;
+ relend = relocs + input_section->reloc_count;
+ for (; rel < relend; rel++)
+ {
+ int r_type;
+
+ r_type = ELF32_R_TYPE (rel->r_info);
+ if (r_type == R_SPU_PPU32 || r_type == R_SPU_PPU64)
+ *wrel++ = *rel;
+ }
+ input_section->reloc_count = wrel - relocs;
+ /* Backflips for _bfd_elf_link_output_relocs. */
+ rel_hdr = _bfd_elf_single_rel_hdr (input_section);
+ rel_hdr->sh_size = input_section->reloc_count * rel_hdr->sh_entsize;
+ ret = 2;
+ }
+
+ return ret;
+}
+
+static bfd_boolean
+spu_elf_finish_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED)
+{
+ return TRUE;
+}
+
+/* Adjust _SPUEAR_ syms to point at their overlay stubs. */
+
+static int
+spu_elf_output_symbol_hook (struct bfd_link_info *info,
+ const char *sym_name ATTRIBUTE_UNUSED,
+ Elf_Internal_Sym *sym,
+ asection *sym_sec ATTRIBUTE_UNUSED,
+ struct elf_link_hash_entry *h)
+{
+ struct spu_link_hash_table *htab = spu_hash_table (info);
+
+ if (!info->relocatable
+ && htab->stub_sec != NULL
+ && h != NULL
+ && (h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak)
+ && h->def_regular
+ && strncmp (h->root.root.string, "_SPUEAR_", 8) == 0)
+ {
+ struct got_entry *g;
+
+ for (g = h->got.glist; g != NULL; g = g->next)
+ if (htab->params->ovly_flavour == ovly_soft_icache
+ ? g->br_addr == g->stub_addr
+ : g->addend == 0 && g->ovl == 0)
+ {
+ sym->st_shndx = (_bfd_elf_section_from_bfd_section
+ (htab->stub_sec[0]->output_section->owner,
+ htab->stub_sec[0]->output_section));
+ sym->st_value = g->stub_addr;
+ break;
+ }
+ }
+
+ return 1;
+}
+
+static int spu_plugin = 0;
+
+void
+spu_elf_plugin (int val)
+{
+ spu_plugin = val;
+}
+
+/* Set ELF header e_type for plugins. */
+
+static void
+spu_elf_post_process_headers (bfd *abfd, struct bfd_link_info *info)
+{
+ if (spu_plugin)
+ {
+ Elf_Internal_Ehdr *i_ehdrp = elf_elfheader (abfd);
+
+ i_ehdrp->e_type = ET_DYN;
+ }
+
+ _bfd_elf_post_process_headers (abfd, info);
+}
+
+/* We may add an extra PT_LOAD segment for .toe. We also need extra
+ segments for overlays. */
+
+static int
+spu_elf_additional_program_headers (bfd *abfd, struct bfd_link_info *info)
+{
+ int extra = 0;
+ asection *sec;
+
+ if (info != NULL)
+ {
+ struct spu_link_hash_table *htab = spu_hash_table (info);
+ extra = htab->num_overlays;
+ }
+
+ if (extra)
+ ++extra;
+
+ sec = bfd_get_section_by_name (abfd, ".toe");
+ if (sec != NULL && (sec->flags & SEC_LOAD) != 0)
+ ++extra;
+
+ return extra;
+}
+
+/* Remove .toe section from other PT_LOAD segments and put it in
+ a segment of its own. Put overlays in separate segments too. */
+
+static bfd_boolean
+spu_elf_modify_segment_map (bfd *abfd, struct bfd_link_info *info)
+{
+ asection *toe, *s;
+ struct elf_segment_map *m, *m_overlay;
+ struct elf_segment_map **p, **p_overlay;
+ unsigned int i;
+
+ if (info == NULL)
+ return TRUE;
+
+ toe = bfd_get_section_by_name (abfd, ".toe");
+ for (m = elf_seg_map (abfd); m != NULL; m = m->next)
+ if (m->p_type == PT_LOAD && m->count > 1)
+ for (i = 0; i < m->count; i++)
+ if ((s = m->sections[i]) == toe
+ || spu_elf_section_data (s)->u.o.ovl_index != 0)
+ {
+ struct elf_segment_map *m2;
+ bfd_vma amt;
+
+ if (i + 1 < m->count)
+ {
+ amt = sizeof (struct elf_segment_map);
+ amt += (m->count - (i + 2)) * sizeof (m->sections[0]);
+ m2 = bfd_zalloc (abfd, amt);
+ if (m2 == NULL)
+ return FALSE;
+ m2->count = m->count - (i + 1);
+ memcpy (m2->sections, m->sections + i + 1,
+ m2->count * sizeof (m->sections[0]));
+ m2->p_type = PT_LOAD;
+ m2->next = m->next;
+ m->next = m2;
+ }
+ m->count = 1;
+ if (i != 0)
+ {
+ m->count = i;
+ amt = sizeof (struct elf_segment_map);
+ m2 = bfd_zalloc (abfd, amt);
+ if (m2 == NULL)
+ return FALSE;
+ m2->p_type = PT_LOAD;
+ m2->count = 1;
+ m2->sections[0] = s;
+ m2->next = m->next;
+ m->next = m2;
+ }
+ break;
+ }
+
+
+ /* Some SPU ELF loaders ignore the PF_OVERLAY flag and just load all
+ PT_LOAD segments. This can cause the .ovl.init section to be
+ overwritten with the contents of some overlay segment. To work
+ around this issue, we ensure that all PF_OVERLAY segments are
+ sorted first amongst the program headers; this ensures that even
+ with a broken loader, the .ovl.init section (which is not marked
+ as PF_OVERLAY) will be placed into SPU local store on startup. */
+
+ /* Move all overlay segments onto a separate list. */
+ p = &elf_seg_map (abfd);
+ p_overlay = &m_overlay;
+ while (*p != NULL)
+ {
+ if ((*p)->p_type == PT_LOAD && (*p)->count == 1
+ && spu_elf_section_data ((*p)->sections[0])->u.o.ovl_index != 0)
+ {
+ m = *p;
+ *p = m->next;
+ *p_overlay = m;
+ p_overlay = &m->next;
+ continue;
+ }
+
+ p = &((*p)->next);
+ }
+
+ /* Re-insert overlay segments at the head of the segment map. */
+ *p_overlay = elf_seg_map (abfd);
+ elf_seg_map (abfd) = m_overlay;
+
+ return TRUE;
+}
+
+/* Tweak the section type of .note.spu_name. */
+
+static bfd_boolean
+spu_elf_fake_sections (bfd *obfd ATTRIBUTE_UNUSED,
+ Elf_Internal_Shdr *hdr,
+ asection *sec)
+{
+ if (strcmp (sec->name, SPU_PTNOTE_SPUNAME) == 0)
+ hdr->sh_type = SHT_NOTE;
+ return TRUE;
+}
+
+/* Tweak phdrs before writing them out. */
+
+static int
+spu_elf_modify_program_headers (bfd *abfd, struct bfd_link_info *info)
+{
+ const struct elf_backend_data *bed;
+ struct elf_obj_tdata *tdata;
+ Elf_Internal_Phdr *phdr, *last;
+ struct spu_link_hash_table *htab;
+ unsigned int count;
+ unsigned int i;
+
+ if (info == NULL)
+ return TRUE;
+
+ bed = get_elf_backend_data (abfd);
+ tdata = elf_tdata (abfd);
+ phdr = tdata->phdr;
+ count = elf_program_header_size (abfd) / bed->s->sizeof_phdr;
+ htab = spu_hash_table (info);
+ if (htab->num_overlays != 0)
+ {
+ struct elf_segment_map *m;
+ unsigned int o;
+
+ for (i = 0, m = elf_seg_map (abfd); m; ++i, m = m->next)
+ if (m->count != 0
+ && (o = spu_elf_section_data (m->sections[0])->u.o.ovl_index) != 0)
+ {
+ /* Mark this as an overlay header. */
+ phdr[i].p_flags |= PF_OVERLAY;
+
+ if (htab->ovtab != NULL && htab->ovtab->size != 0
+ && htab->params->ovly_flavour != ovly_soft_icache)
+ {
+ bfd_byte *p = htab->ovtab->contents;
+ unsigned int off = o * 16 + 8;
+
+ /* Write file_off into _ovly_table. */
+ bfd_put_32 (htab->ovtab->owner, phdr[i].p_offset, p + off);
+ }
+ }
+ /* Soft-icache has its file offset put in .ovl.init. */
+ if (htab->init != NULL && htab->init->size != 0)
+ {
+ bfd_vma val = elf_section_data (htab->ovl_sec[0])->this_hdr.sh_offset;
+
+ bfd_put_32 (htab->init->owner, val, htab->init->contents + 4);
+ }
+ }
+
+ /* Round up p_filesz and p_memsz of PT_LOAD segments to multiples
+ of 16. This should always be possible when using the standard
+ linker scripts, but don't create overlapping segments if
+ someone is playing games with linker scripts. */
+ last = NULL;
+ for (i = count; i-- != 0; )
+ if (phdr[i].p_type == PT_LOAD)
+ {
+ unsigned adjust;
+
+ adjust = -phdr[i].p_filesz & 15;
+ if (adjust != 0
+ && last != NULL
+ && phdr[i].p_offset + phdr[i].p_filesz > last->p_offset - adjust)
+ break;
+
+ adjust = -phdr[i].p_memsz & 15;
+ if (adjust != 0
+ && last != NULL
+ && phdr[i].p_filesz != 0
+ && phdr[i].p_vaddr + phdr[i].p_memsz > last->p_vaddr - adjust
+ && phdr[i].p_vaddr + phdr[i].p_memsz <= last->p_vaddr)
+ break;
+
+ if (phdr[i].p_filesz != 0)
+ last = &phdr[i];
+ }
+
+ if (i == (unsigned int) -1)
+ for (i = count; i-- != 0; )
+ if (phdr[i].p_type == PT_LOAD)
+ {
+ unsigned adjust;
+
+ adjust = -phdr[i].p_filesz & 15;
+ phdr[i].p_filesz += adjust;
+
+ adjust = -phdr[i].p_memsz & 15;
+ phdr[i].p_memsz += adjust;
+ }
+
+ return TRUE;
+}
+
+bfd_boolean
+spu_elf_size_sections (bfd * output_bfd, struct bfd_link_info *info)
+{
+ struct spu_link_hash_table *htab = spu_hash_table (info);
+ if (htab->params->emit_fixups)
+ {
+ asection *sfixup = htab->sfixup;
+ int fixup_count = 0;
+ bfd *ibfd;
+ size_t size;
+
+ for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next)
+ {
+ asection *isec;
+
+ if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour)
+ continue;
+
+ /* Walk over each section attached to the input bfd. */
+ for (isec = ibfd->sections; isec != NULL; isec = isec->next)
+ {
+ Elf_Internal_Rela *internal_relocs, *irelaend, *irela;
+ bfd_vma base_end;
+
+ /* If there aren't any relocs, then there's nothing more
+ to do. */
+ if ((isec->flags & SEC_ALLOC) == 0
+ || (isec->flags & SEC_RELOC) == 0
+ || isec->reloc_count == 0)
+ continue;
+
+ /* Get the relocs. */
+ internal_relocs =
+ _bfd_elf_link_read_relocs (ibfd, isec, NULL, NULL,
+ info->keep_memory);
+ if (internal_relocs == NULL)
+ return FALSE;
+
+ /* 1 quadword can contain up to 4 R_SPU_ADDR32
+ relocations. They are stored in a single word by
+ saving the upper 28 bits of the address and setting the
+ lower 4 bits to a bit mask of the words that have the
+ relocation. BASE_END keeps track of the next quadword. */
+ irela = internal_relocs;
+ irelaend = irela + isec->reloc_count;
+ base_end = 0;
+ for (; irela < irelaend; irela++)
+ if (ELF32_R_TYPE (irela->r_info) == R_SPU_ADDR32
+ && irela->r_offset >= base_end)
+ {
+ base_end = (irela->r_offset & ~(bfd_vma) 15) + 16;
+ fixup_count++;
+ }
+ }
+ }
+
+ /* We always have a NULL fixup as a sentinel */
+ size = (fixup_count + 1) * FIXUP_RECORD_SIZE;
+ if (!bfd_set_section_size (output_bfd, sfixup, size))
+ return FALSE;
+ sfixup->contents = (bfd_byte *) bfd_zalloc (info->input_bfds, size);
+ if (sfixup->contents == NULL)
+ return FALSE;
+ }
+ return TRUE;
+}
+
+#define TARGET_BIG_SYM spu_elf32_vec
+#define TARGET_BIG_NAME "elf32-spu"
+#define ELF_ARCH bfd_arch_spu
+#define ELF_TARGET_ID SPU_ELF_DATA
+#define ELF_MACHINE_CODE EM_SPU
+/* This matches the alignment need for DMA. */
+#define ELF_MAXPAGESIZE 0x80
+#define elf_backend_rela_normal 1
+#define elf_backend_can_gc_sections 1
+
+#define bfd_elf32_bfd_reloc_type_lookup spu_elf_reloc_type_lookup
+#define bfd_elf32_bfd_reloc_name_lookup spu_elf_reloc_name_lookup
+#define elf_info_to_howto spu_elf_info_to_howto
+#define elf_backend_count_relocs spu_elf_count_relocs
+#define elf_backend_relocate_section spu_elf_relocate_section
+#define elf_backend_finish_dynamic_sections spu_elf_finish_dynamic_sections
+#define elf_backend_symbol_processing spu_elf_backend_symbol_processing
+#define elf_backend_link_output_symbol_hook spu_elf_output_symbol_hook
+#define elf_backend_object_p spu_elf_object_p
+#define bfd_elf32_new_section_hook spu_elf_new_section_hook
+#define bfd_elf32_bfd_link_hash_table_create spu_elf_link_hash_table_create
+
+#define elf_backend_additional_program_headers spu_elf_additional_program_headers
+#define elf_backend_modify_segment_map spu_elf_modify_segment_map
+#define elf_backend_modify_program_headers spu_elf_modify_program_headers
+#define elf_backend_post_process_headers spu_elf_post_process_headers
+#define elf_backend_fake_sections spu_elf_fake_sections
+#define elf_backend_special_sections spu_elf_special_sections
+#define bfd_elf32_bfd_final_link spu_elf_final_link
+
+#include "elf32-target.h"
diff --git a/bfd/elf32-spu.h b/bfd/elf32-spu.h
new file mode 100644
index 0000000..2330e13
--- /dev/null
+++ b/bfd/elf32-spu.h
@@ -0,0 +1,124 @@
+/* SPU specific support for 32-bit ELF.
+
+ Copyright (C) 2006-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public 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 spu_elf_params
+{
+ /* Stash various callbacks for --auto-overlay. */
+ void (*place_spu_section) (asection *, asection *, const char *);
+ bfd_size_type (*spu_elf_load_ovl_mgr) (void);
+ FILE *(*spu_elf_open_overlay_script) (void);
+ void (*spu_elf_relink) (void);
+
+ /* Bit 0 set if --auto-overlay.
+ Bit 1 set if --auto-relink.
+ Bit 2 set if --overlay-rodata. */
+ unsigned int auto_overlay : 3;
+#define AUTO_OVERLAY 1
+#define AUTO_RELINK 2
+#define OVERLAY_RODATA 4
+
+ /* Type of overlays, enum _ovly_flavour. */
+ unsigned int ovly_flavour : 1;
+ unsigned int compact_stub : 1;
+
+ /* Set if we should emit symbols for stubs. */
+ unsigned int emit_stub_syms : 1;
+
+ /* Set if we want stubs on calls out of overlay regions to
+ non-overlay regions. */
+ unsigned int non_overlay_stubs : 1;
+
+ /* Set if lr liveness analysis should be done. */
+ unsigned int lrlive_analysis : 1;
+
+ /* Set if stack size analysis should be done. */
+ unsigned int stack_analysis : 1;
+
+ /* Set if __stack_* syms will be emitted. */
+ unsigned int emit_stack_syms : 1;
+
+ /* Set if non-icache code should be allowed in icache lines. */
+ unsigned int non_ia_text : 1;
+
+ /* Set when the .fixup section should be generated. */
+ unsigned int emit_fixups : 1;
+
+ /* Range of valid addresses for loadable sections. */
+ bfd_vma local_store_lo;
+ bfd_vma local_store_hi;
+
+ /* Control --auto-overlay feature. */
+ unsigned int num_lines;
+ unsigned int line_size;
+ unsigned int max_branch;
+ unsigned int auto_overlay_fixed;
+ unsigned int auto_overlay_reserved;
+ int extra_stack_space;
+};
+
+/* Extra info kept for SPU sections. */
+
+struct spu_elf_stack_info;
+
+struct _spu_elf_section_data
+{
+ struct bfd_elf_section_data elf;
+
+ union {
+ /* Info kept for input sections. */
+ struct {
+ /* Stack analysis info kept for this section. */
+ struct spu_elf_stack_info *stack_info;
+ } i;
+
+ /* Info kept for output sections. */
+ struct {
+ /* Non-zero for overlay output sections. */
+ unsigned int ovl_index;
+ unsigned int ovl_buf;
+ } o;
+ } u;
+};
+
+#define spu_elf_section_data(sec) \
+ ((struct _spu_elf_section_data *) elf_section_data (sec))
+
+enum _ovly_flavour
+{
+ ovly_normal,
+ ovly_soft_icache
+};
+
+struct _ovl_stream
+{
+ const void *start;
+ const void *end;
+};
+
+extern void spu_elf_setup (struct bfd_link_info *, struct spu_elf_params *);
+extern void spu_elf_plugin (int);
+extern bfd_boolean spu_elf_open_builtin_lib (bfd **,
+ const struct _ovl_stream *);
+extern bfd_boolean spu_elf_create_sections (struct bfd_link_info *);
+extern bfd_boolean spu_elf_size_sections (bfd *, struct bfd_link_info *);
+extern int spu_elf_find_overlays (struct bfd_link_info *);
+extern int spu_elf_size_stubs (struct bfd_link_info *);
+extern void spu_elf_place_overlay_data (struct bfd_link_info *);
+extern asection *spu_elf_check_vma (struct bfd_link_info *);
diff --git a/bfd/elf32-tic6x.c b/bfd/elf32-tic6x.c
new file mode 100644
index 0000000..8381cfa
--- /dev/null
+++ b/bfd/elf32-tic6x.c
@@ -0,0 +1,4445 @@
+/* 32-bit ELF support for TI C6X
+ Copyright (C) 2010-2014 Free Software Foundation, Inc.
+ Contributed by Joseph Myers <joseph@codesourcery.com>
+ Bernd Schmidt <bernds@codesourcery.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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include <limits.h>
+#include "bfd.h"
+#include "libbfd.h"
+#include "libiberty.h"
+#include "elf-bfd.h"
+#include "elf/tic6x.h"
+#include "elf32-tic6x.h"
+
+#define ELF_DYNAMIC_INTERPRETER "/lib/ld-uClibc.so.0"
+
+/* DSBT binaries have a default 128K stack. */
+#define DEFAULT_STACK_SIZE 0x20000
+
+/* The size in bytes of an entry in the procedure linkage table. */
+#define PLT_ENTRY_SIZE 24
+
+/* TI C6X ELF linker hash table. */
+
+struct elf32_tic6x_link_hash_table
+{
+ struct elf_link_hash_table elf;
+
+ /* Short-cuts to get to dynamic linker sections. */
+ asection *sdynbss;
+ asection *srelbss;
+
+ /* C6X specific command line arguments. */
+ struct elf32_tic6x_params params;
+
+ /* Small local sym cache. */
+ struct sym_cache sym_cache;
+
+ /* The output BFD, for convenience. */
+ bfd *obfd;
+
+ /* The .dsbt section. */
+ asection *dsbt;
+};
+
+/* Get the TI C6X ELF linker hash table from a link_info structure. */
+
+#define elf32_tic6x_hash_table(p) \
+ ((struct elf32_tic6x_link_hash_table *) ((p)->hash))
+
+/* TI C6X ELF linker hash entry. */
+
+struct elf32_tic6x_link_hash_entry
+{
+ struct elf_link_hash_entry elf;
+
+ /* Track dynamic relocs copied for this symbol. */
+ struct elf_dyn_relocs *dyn_relocs;
+};
+
+typedef enum
+{
+ DELETE_EXIDX_ENTRY,
+ INSERT_EXIDX_CANTUNWIND_AT_END
+}
+tic6x_unwind_edit_type;
+
+/* A (sorted) list of edits to apply to an unwind table. */
+typedef struct tic6x_unwind_table_edit
+{
+ tic6x_unwind_edit_type type;
+ /* Note: we sometimes want to insert an unwind entry corresponding to a
+ section different from the one we're currently writing out, so record the
+ (text) section this edit relates to here. */
+ asection *linked_section;
+ unsigned int index;
+ struct tic6x_unwind_table_edit *next;
+}
+tic6x_unwind_table_edit;
+
+typedef struct _tic6x_elf_section_data
+{
+ /* Information about mapping symbols. */
+ struct bfd_elf_section_data elf;
+ /* Information about unwind tables. */
+ union
+ {
+ /* Unwind info attached to a text section. */
+ struct
+ {
+ asection *tic6x_exidx_sec;
+ } text;
+
+ /* Unwind info attached to an .c6xabi.exidx section. */
+ struct
+ {
+ tic6x_unwind_table_edit *unwind_edit_list;
+ tic6x_unwind_table_edit *unwind_edit_tail;
+ } exidx;
+ } u;
+}
+_tic6x_elf_section_data;
+
+#define elf32_tic6x_section_data(sec) \
+ ((_tic6x_elf_section_data *) elf_section_data (sec))
+
+struct elf32_tic6x_obj_tdata
+{
+ struct elf_obj_tdata root;
+
+ /* Whether to use RELA relocations when generating relocations.
+ This is a per-object flag to allow the assembler to generate REL
+ relocations for use in linker testcases. */
+ bfd_boolean use_rela_p;
+};
+
+#define elf32_tic6x_tdata(abfd) \
+ ((struct elf32_tic6x_obj_tdata *) (abfd)->tdata.any)
+
+#define is_tic6x_elf(bfd) \
+ (bfd_get_flavour (bfd) == bfd_target_elf_flavour \
+ && elf_tdata (bfd) != NULL \
+ && elf_object_id (bfd) == TIC6X_ELF_DATA)
+
+/* C6X 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 tic6x_elf_scom_section;
+static asymbol tic6x_elf_scom_symbol;
+static asymbol *tic6x_elf_scom_symbol_ptr;
+
+static reloc_howto_type elf32_tic6x_howto_table[] =
+{
+ HOWTO (R_C6000_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_C6000_NONE", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ HOWTO (R_C6000_ABS32, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_C6000_ABS32", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ HOWTO (R_C6000_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_C6000_ABS16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ HOWTO (R_C6000_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_C6000_ABS8", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x000000ff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ HOWTO (R_C6000_PCR_S21, /* type */
+ 2, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 21, /* bitsize */
+ TRUE, /* pc_relative */
+ 7, /* bitpos */
+ complain_overflow_signed,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_C6000_PCR_S21", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0fffff80, /* dst_mask */
+ TRUE), /* pcrel_offset */
+ HOWTO (R_C6000_PCR_S12, /* type */
+ 2, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 12, /* bitsize */
+ TRUE, /* pc_relative */
+ 16, /* bitpos */
+ complain_overflow_signed,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_C6000_PCR_S12", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0fff0000, /* dst_mask */
+ TRUE), /* pcrel_offset */
+ HOWTO (R_C6000_PCR_S10, /* type */
+ 2, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 10, /* bitsize */
+ TRUE, /* pc_relative */
+ 13, /* bitpos */
+ complain_overflow_signed,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_C6000_PCR_S10", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x007fe000, /* dst_mask */
+ TRUE), /* pcrel_offset */
+ HOWTO (R_C6000_PCR_S7, /* type */
+ 2, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 7, /* bitsize */
+ TRUE, /* pc_relative */
+ 16, /* bitpos */
+ complain_overflow_signed,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_C6000_PCR_S7", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x007f0000, /* dst_mask */
+ TRUE), /* pcrel_offset */
+ HOWTO (R_C6000_ABS_S16, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 7, /* bitpos */
+ complain_overflow_signed,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_C6000_ABS_S16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x007fff80, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ HOWTO (R_C6000_ABS_L16, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 7, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_C6000_ABS_L16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x007fff80, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ HOWTO (R_C6000_ABS_H16, /* type */
+ 16, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 7, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_C6000_ABS_H16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x007fff80, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ HOWTO (R_C6000_SBR_U15_B, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 15, /* bitsize */
+ FALSE, /* pc_relative */
+ 8, /* bitpos */
+ complain_overflow_unsigned,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_C6000_SBR_U15_B", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x007fff00, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ HOWTO (R_C6000_SBR_U15_H, /* type */
+ 1, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 15, /* bitsize */
+ FALSE, /* pc_relative */
+ 8, /* bitpos */
+ complain_overflow_unsigned,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_C6000_SBR_U15_H", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x007fff00, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ HOWTO (R_C6000_SBR_U15_W, /* type */
+ 2, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 15, /* bitsize */
+ FALSE, /* pc_relative */
+ 8, /* bitpos */
+ complain_overflow_unsigned,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_C6000_SBR_U15_W", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x007fff00, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ HOWTO (R_C6000_SBR_S16, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 7, /* bitpos */
+ complain_overflow_signed,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_C6000_SBR_S16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x007fff80, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ HOWTO (R_C6000_SBR_L16_B, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 7, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_C6000_SBR_L16_B", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x007fff80, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ HOWTO (R_C6000_SBR_L16_H, /* type */
+ 1, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 7, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_C6000_SBR_L16_H", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x007fff80, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ HOWTO (R_C6000_SBR_L16_W, /* type */
+ 2, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 7, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_C6000_SBR_L16_W", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x007fff80, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ HOWTO (R_C6000_SBR_H16_B, /* type */
+ 16, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 7, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_C6000_SBR_H16_B", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x007fff80, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ HOWTO (R_C6000_SBR_H16_H, /* type */
+ 17, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 7, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_C6000_SBR_H16_H", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x007fff80, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ HOWTO (R_C6000_SBR_H16_W, /* type */
+ 18, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 7, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_C6000_SBR_H16_W", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x007fff80, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ HOWTO (R_C6000_SBR_GOT_U15_W, /* type */
+ 2, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 15, /* bitsize */
+ FALSE, /* pc_relative */
+ 8, /* bitpos */
+ complain_overflow_unsigned,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_C6000_SBR_GOT_U15_W",/* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x007fff00, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ HOWTO (R_C6000_SBR_GOT_L16_W, /* type */
+ 2, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 7, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_C6000_SBR_GOT_L16_W",/* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x007fff80, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ HOWTO (R_C6000_SBR_GOT_H16_W, /* type */
+ 18, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 7, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_C6000_SBR_GOT_H16_W",/* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x007fff80, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ HOWTO (R_C6000_DSBT_INDEX, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 15, /* bitsize */
+ FALSE, /* pc_relative */
+ 8, /* bitpos */
+ complain_overflow_unsigned,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_C6000_DSBT_INDEX", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x007fff00, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ HOWTO (R_C6000_PREL31, /* type */
+ 1, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 31, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_C6000_PREL31", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x7fffffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+ HOWTO (R_C6000_COPY, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_C6000_COPY", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ HOWTO (R_C6000_JUMP_SLOT, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_C6000_JUMP_SLOT", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ HOWTO (R_C6000_EHTYPE, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_C6000_EHTYPE", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ HOWTO (R_C6000_PCR_H16, /* type */
+ 16, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ TRUE, /* pc_relative */
+ 7, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_C6000_PCR_H16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x007fff80, /* dst_mask */
+ TRUE), /* pcrel_offset */
+ HOWTO (R_C6000_PCR_L16, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ TRUE, /* pc_relative */
+ 7, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_C6000_PCR_L16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x007fff80, /* dst_mask */
+ TRUE), /* pcrel_offset */
+ EMPTY_HOWTO (31),
+ EMPTY_HOWTO (32),
+ EMPTY_HOWTO (33),
+ EMPTY_HOWTO (34),
+ EMPTY_HOWTO (35),
+ EMPTY_HOWTO (36),
+ EMPTY_HOWTO (37),
+ EMPTY_HOWTO (38),
+ EMPTY_HOWTO (39),
+ EMPTY_HOWTO (40),
+ EMPTY_HOWTO (41),
+ EMPTY_HOWTO (42),
+ EMPTY_HOWTO (43),
+ EMPTY_HOWTO (44),
+ EMPTY_HOWTO (45),
+ EMPTY_HOWTO (46),
+ EMPTY_HOWTO (47),
+ EMPTY_HOWTO (48),
+ EMPTY_HOWTO (49),
+ EMPTY_HOWTO (50),
+ EMPTY_HOWTO (51),
+ EMPTY_HOWTO (52),
+ EMPTY_HOWTO (53),
+ EMPTY_HOWTO (54),
+ EMPTY_HOWTO (55),
+ EMPTY_HOWTO (56),
+ EMPTY_HOWTO (57),
+ EMPTY_HOWTO (58),
+ EMPTY_HOWTO (59),
+ EMPTY_HOWTO (60),
+ EMPTY_HOWTO (61),
+ EMPTY_HOWTO (62),
+ EMPTY_HOWTO (63),
+ EMPTY_HOWTO (64),
+ EMPTY_HOWTO (65),
+ EMPTY_HOWTO (66),
+ EMPTY_HOWTO (67),
+ EMPTY_HOWTO (68),
+ EMPTY_HOWTO (69),
+ EMPTY_HOWTO (70),
+ EMPTY_HOWTO (71),
+ EMPTY_HOWTO (72),
+ EMPTY_HOWTO (73),
+ EMPTY_HOWTO (74),
+ EMPTY_HOWTO (75),
+ EMPTY_HOWTO (76),
+ EMPTY_HOWTO (77),
+ EMPTY_HOWTO (78),
+ EMPTY_HOWTO (79),
+ EMPTY_HOWTO (80),
+ EMPTY_HOWTO (81),
+ EMPTY_HOWTO (82),
+ EMPTY_HOWTO (83),
+ EMPTY_HOWTO (84),
+ EMPTY_HOWTO (85),
+ EMPTY_HOWTO (86),
+ EMPTY_HOWTO (87),
+ EMPTY_HOWTO (88),
+ EMPTY_HOWTO (89),
+ EMPTY_HOWTO (90),
+ EMPTY_HOWTO (91),
+ EMPTY_HOWTO (92),
+ EMPTY_HOWTO (93),
+ EMPTY_HOWTO (94),
+ EMPTY_HOWTO (95),
+ EMPTY_HOWTO (96),
+ EMPTY_HOWTO (97),
+ EMPTY_HOWTO (98),
+ EMPTY_HOWTO (99),
+ EMPTY_HOWTO (100),
+ EMPTY_HOWTO (101),
+ EMPTY_HOWTO (102),
+ EMPTY_HOWTO (103),
+ EMPTY_HOWTO (104),
+ EMPTY_HOWTO (105),
+ EMPTY_HOWTO (106),
+ EMPTY_HOWTO (107),
+ EMPTY_HOWTO (108),
+ EMPTY_HOWTO (109),
+ EMPTY_HOWTO (110),
+ EMPTY_HOWTO (111),
+ EMPTY_HOWTO (112),
+ EMPTY_HOWTO (113),
+ EMPTY_HOWTO (114),
+ EMPTY_HOWTO (115),
+ EMPTY_HOWTO (116),
+ EMPTY_HOWTO (117),
+ EMPTY_HOWTO (118),
+ EMPTY_HOWTO (119),
+ EMPTY_HOWTO (120),
+ EMPTY_HOWTO (121),
+ EMPTY_HOWTO (122),
+ EMPTY_HOWTO (123),
+ EMPTY_HOWTO (124),
+ EMPTY_HOWTO (125),
+ EMPTY_HOWTO (126),
+ EMPTY_HOWTO (127),
+ EMPTY_HOWTO (128),
+ EMPTY_HOWTO (129),
+ EMPTY_HOWTO (130),
+ EMPTY_HOWTO (131),
+ EMPTY_HOWTO (132),
+ EMPTY_HOWTO (133),
+ EMPTY_HOWTO (134),
+ EMPTY_HOWTO (135),
+ EMPTY_HOWTO (136),
+ EMPTY_HOWTO (137),
+ EMPTY_HOWTO (138),
+ EMPTY_HOWTO (139),
+ EMPTY_HOWTO (140),
+ EMPTY_HOWTO (141),
+ EMPTY_HOWTO (142),
+ EMPTY_HOWTO (143),
+ EMPTY_HOWTO (144),
+ EMPTY_HOWTO (145),
+ EMPTY_HOWTO (146),
+ EMPTY_HOWTO (147),
+ EMPTY_HOWTO (148),
+ EMPTY_HOWTO (149),
+ EMPTY_HOWTO (150),
+ EMPTY_HOWTO (151),
+ EMPTY_HOWTO (152),
+ EMPTY_HOWTO (153),
+ EMPTY_HOWTO (154),
+ EMPTY_HOWTO (155),
+ EMPTY_HOWTO (156),
+ EMPTY_HOWTO (157),
+ EMPTY_HOWTO (158),
+ EMPTY_HOWTO (159),
+ EMPTY_HOWTO (160),
+ EMPTY_HOWTO (161),
+ EMPTY_HOWTO (162),
+ EMPTY_HOWTO (163),
+ EMPTY_HOWTO (164),
+ EMPTY_HOWTO (165),
+ EMPTY_HOWTO (166),
+ EMPTY_HOWTO (167),
+ EMPTY_HOWTO (168),
+ EMPTY_HOWTO (169),
+ EMPTY_HOWTO (170),
+ EMPTY_HOWTO (171),
+ EMPTY_HOWTO (172),
+ EMPTY_HOWTO (173),
+ EMPTY_HOWTO (174),
+ EMPTY_HOWTO (175),
+ EMPTY_HOWTO (176),
+ EMPTY_HOWTO (177),
+ EMPTY_HOWTO (178),
+ EMPTY_HOWTO (179),
+ EMPTY_HOWTO (180),
+ EMPTY_HOWTO (181),
+ EMPTY_HOWTO (182),
+ EMPTY_HOWTO (183),
+ EMPTY_HOWTO (184),
+ EMPTY_HOWTO (185),
+ EMPTY_HOWTO (186),
+ EMPTY_HOWTO (187),
+ EMPTY_HOWTO (188),
+ EMPTY_HOWTO (189),
+ EMPTY_HOWTO (190),
+ EMPTY_HOWTO (191),
+ EMPTY_HOWTO (192),
+ EMPTY_HOWTO (193),
+ EMPTY_HOWTO (194),
+ EMPTY_HOWTO (195),
+ EMPTY_HOWTO (196),
+ EMPTY_HOWTO (197),
+ EMPTY_HOWTO (198),
+ EMPTY_HOWTO (199),
+ EMPTY_HOWTO (200),
+ EMPTY_HOWTO (201),
+ EMPTY_HOWTO (202),
+ EMPTY_HOWTO (203),
+ EMPTY_HOWTO (204),
+ EMPTY_HOWTO (205),
+ EMPTY_HOWTO (206),
+ EMPTY_HOWTO (207),
+ EMPTY_HOWTO (208),
+ EMPTY_HOWTO (209),
+ EMPTY_HOWTO (210),
+ EMPTY_HOWTO (211),
+ EMPTY_HOWTO (212),
+ EMPTY_HOWTO (213),
+ EMPTY_HOWTO (214),
+ EMPTY_HOWTO (215),
+ EMPTY_HOWTO (216),
+ EMPTY_HOWTO (217),
+ EMPTY_HOWTO (218),
+ EMPTY_HOWTO (219),
+ EMPTY_HOWTO (220),
+ EMPTY_HOWTO (221),
+ EMPTY_HOWTO (222),
+ EMPTY_HOWTO (223),
+ EMPTY_HOWTO (224),
+ EMPTY_HOWTO (225),
+ EMPTY_HOWTO (226),
+ EMPTY_HOWTO (227),
+ EMPTY_HOWTO (228),
+ EMPTY_HOWTO (229),
+ EMPTY_HOWTO (230),
+ EMPTY_HOWTO (231),
+ EMPTY_HOWTO (232),
+ EMPTY_HOWTO (233),
+ EMPTY_HOWTO (234),
+ EMPTY_HOWTO (235),
+ EMPTY_HOWTO (236),
+ EMPTY_HOWTO (237),
+ EMPTY_HOWTO (238),
+ EMPTY_HOWTO (239),
+ EMPTY_HOWTO (240),
+ EMPTY_HOWTO (241),
+ EMPTY_HOWTO (242),
+ EMPTY_HOWTO (243),
+ EMPTY_HOWTO (244),
+ EMPTY_HOWTO (245),
+ EMPTY_HOWTO (246),
+ EMPTY_HOWTO (247),
+ EMPTY_HOWTO (248),
+ EMPTY_HOWTO (249),
+ EMPTY_HOWTO (250),
+ EMPTY_HOWTO (251),
+ EMPTY_HOWTO (252),
+ HOWTO (R_C6000_ALIGN, /* 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_C6000_ALIGN", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ HOWTO (R_C6000_FPHEAD, /* 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_C6000_FPHEAD", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ HOWTO (R_C6000_NOCMP, /* 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_C6000_NOCMP", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ FALSE) /* pcrel_offset */
+};
+
+static reloc_howto_type elf32_tic6x_howto_table_rel[] =
+{
+ HOWTO (R_C6000_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_C6000_NONE", /* name */
+ TRUE, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ HOWTO (R_C6000_ABS32, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_C6000_ABS32", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ HOWTO (R_C6000_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_C6000_ABS16", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ HOWTO (R_C6000_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_C6000_ABS8", /* name */
+ TRUE, /* partial_inplace */
+ 0x000000ff, /* src_mask */
+ 0x000000ff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ HOWTO (R_C6000_PCR_S21, /* type */
+ 2, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 21, /* bitsize */
+ TRUE, /* pc_relative */
+ 7, /* bitpos */
+ complain_overflow_signed,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_C6000_PCR_S21", /* name */
+ TRUE, /* partial_inplace */
+ 0x0fffff80, /* src_mask */
+ 0x0fffff80, /* dst_mask */
+ TRUE), /* pcrel_offset */
+ HOWTO (R_C6000_PCR_S12, /* type */
+ 2, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 12, /* bitsize */
+ TRUE, /* pc_relative */
+ 16, /* bitpos */
+ complain_overflow_signed,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_C6000_PCR_S12", /* name */
+ TRUE, /* partial_inplace */
+ 0x0fff0000, /* src_mask */
+ 0x0fff0000, /* dst_mask */
+ TRUE), /* pcrel_offset */
+ HOWTO (R_C6000_PCR_S10, /* type */
+ 2, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 10, /* bitsize */
+ TRUE, /* pc_relative */
+ 13, /* bitpos */
+ complain_overflow_signed,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_C6000_PCR_S10", /* name */
+ TRUE, /* partial_inplace */
+ 0x007fe000, /* src_mask */
+ 0x007fe000, /* dst_mask */
+ TRUE), /* pcrel_offset */
+ HOWTO (R_C6000_PCR_S7, /* type */
+ 2, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 7, /* bitsize */
+ TRUE, /* pc_relative */
+ 16, /* bitpos */
+ complain_overflow_signed,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_C6000_PCR_S7", /* name */
+ TRUE, /* partial_inplace */
+ 0x007f0000, /* src_mask */
+ 0x007f0000, /* dst_mask */
+ TRUE), /* pcrel_offset */
+ HOWTO (R_C6000_ABS_S16, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 7, /* bitpos */
+ complain_overflow_signed,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_C6000_ABS_S16", /* name */
+ TRUE, /* partial_inplace */
+ 0x007fff80, /* src_mask */
+ 0x007fff80, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ HOWTO (R_C6000_ABS_L16, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 7, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_C6000_ABS_L16", /* name */
+ TRUE, /* partial_inplace */
+ 0x007fff80, /* src_mask */
+ 0x007fff80, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ EMPTY_HOWTO (R_C6000_ABS_H16),
+ HOWTO (R_C6000_SBR_U15_B, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 15, /* bitsize */
+ FALSE, /* pc_relative */
+ 8, /* bitpos */
+ complain_overflow_unsigned,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_C6000_SBR_U15_B", /* name */
+ TRUE, /* partial_inplace */
+ 0x007fff00, /* src_mask */
+ 0x007fff00, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ HOWTO (R_C6000_SBR_U15_H, /* type */
+ 1, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 15, /* bitsize */
+ FALSE, /* pc_relative */
+ 8, /* bitpos */
+ complain_overflow_unsigned,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_C6000_SBR_U15_H", /* name */
+ TRUE, /* partial_inplace */
+ 0x007fff00, /* src_mask */
+ 0x007fff00, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ HOWTO (R_C6000_SBR_U15_W, /* type */
+ 2, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 15, /* bitsize */
+ FALSE, /* pc_relative */
+ 8, /* bitpos */
+ complain_overflow_unsigned,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_C6000_SBR_U15_W", /* name */
+ TRUE, /* partial_inplace */
+ 0x007fff00, /* src_mask */
+ 0x007fff00, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ HOWTO (R_C6000_SBR_S16, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 7, /* bitpos */
+ complain_overflow_signed,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_C6000_SBR_S16", /* name */
+ TRUE, /* partial_inplace */
+ 0x007fff80, /* src_mask */
+ 0x007fff80, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ HOWTO (R_C6000_SBR_L16_B, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 7, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_C6000_SBR_L16_B", /* name */
+ TRUE, /* partial_inplace */
+ 0x007fff80, /* src_mask */
+ 0x007fff80, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ HOWTO (R_C6000_SBR_L16_H, /* type */
+ 1, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 7, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_C6000_SBR_L16_H", /* name */
+ TRUE, /* partial_inplace */
+ 0x007fff80, /* src_mask */
+ 0x007fff80, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ HOWTO (R_C6000_SBR_L16_W, /* type */
+ 2, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 7, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_C6000_SBR_L16_W", /* name */
+ TRUE, /* partial_inplace */
+ 0x007fff80, /* src_mask */
+ 0x007fff80, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ EMPTY_HOWTO (R_C6000_SBR_H16_B),
+ EMPTY_HOWTO (R_C6000_SBR_H16_H),
+ EMPTY_HOWTO (R_C6000_SBR_H16_W),
+ HOWTO (R_C6000_SBR_GOT_U15_W, /* type */
+ 2, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 15, /* bitsize */
+ FALSE, /* pc_relative */
+ 8, /* bitpos */
+ complain_overflow_unsigned,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_C6000_SBR_GOT_U15_W",/* name */
+ TRUE, /* partial_inplace */
+ 0x007fff00, /* src_mask */
+ 0x007fff00, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ HOWTO (R_C6000_SBR_GOT_L16_W, /* type */
+ 2, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 7, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_C6000_SBR_GOT_L16_W",/* name */
+ TRUE, /* partial_inplace */
+ 0x007fff80, /* src_mask */
+ 0x007fff80, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ EMPTY_HOWTO (R_C6000_SBR_GOT_H16_W),
+ HOWTO (R_C6000_DSBT_INDEX, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 15, /* bitsize */
+ FALSE, /* pc_relative */
+ 8, /* bitpos */
+ complain_overflow_unsigned,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_C6000_DSBT_INDEX", /* name */
+ TRUE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x007fff00, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ HOWTO (R_C6000_PREL31, /* type */
+ 1, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 31, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_C6000_PREL31", /* name */
+ TRUE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x7fffffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+ HOWTO (R_C6000_COPY, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_C6000_COPY", /* name */
+ TRUE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ HOWTO (R_C6000_JUMP_SLOT, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_C6000_JUMP_SLOT", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ HOWTO (R_C6000_EHTYPE, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_C6000_EHTYPE", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ EMPTY_HOWTO (R_C6000_PCR_H16),
+ EMPTY_HOWTO (R_C6000_PCR_L16),
+ EMPTY_HOWTO (31),
+ EMPTY_HOWTO (32),
+ EMPTY_HOWTO (33),
+ EMPTY_HOWTO (34),
+ EMPTY_HOWTO (35),
+ EMPTY_HOWTO (36),
+ EMPTY_HOWTO (37),
+ EMPTY_HOWTO (38),
+ EMPTY_HOWTO (39),
+ EMPTY_HOWTO (40),
+ EMPTY_HOWTO (41),
+ EMPTY_HOWTO (42),
+ EMPTY_HOWTO (43),
+ EMPTY_HOWTO (44),
+ EMPTY_HOWTO (45),
+ EMPTY_HOWTO (46),
+ EMPTY_HOWTO (47),
+ EMPTY_HOWTO (48),
+ EMPTY_HOWTO (49),
+ EMPTY_HOWTO (50),
+ EMPTY_HOWTO (51),
+ EMPTY_HOWTO (52),
+ EMPTY_HOWTO (53),
+ EMPTY_HOWTO (54),
+ EMPTY_HOWTO (55),
+ EMPTY_HOWTO (56),
+ EMPTY_HOWTO (57),
+ EMPTY_HOWTO (58),
+ EMPTY_HOWTO (59),
+ EMPTY_HOWTO (60),
+ EMPTY_HOWTO (61),
+ EMPTY_HOWTO (62),
+ EMPTY_HOWTO (63),
+ EMPTY_HOWTO (64),
+ EMPTY_HOWTO (65),
+ EMPTY_HOWTO (66),
+ EMPTY_HOWTO (67),
+ EMPTY_HOWTO (68),
+ EMPTY_HOWTO (69),
+ EMPTY_HOWTO (70),
+ EMPTY_HOWTO (71),
+ EMPTY_HOWTO (72),
+ EMPTY_HOWTO (73),
+ EMPTY_HOWTO (74),
+ EMPTY_HOWTO (75),
+ EMPTY_HOWTO (76),
+ EMPTY_HOWTO (77),
+ EMPTY_HOWTO (78),
+ EMPTY_HOWTO (79),
+ EMPTY_HOWTO (80),
+ EMPTY_HOWTO (81),
+ EMPTY_HOWTO (82),
+ EMPTY_HOWTO (83),
+ EMPTY_HOWTO (84),
+ EMPTY_HOWTO (85),
+ EMPTY_HOWTO (86),
+ EMPTY_HOWTO (87),
+ EMPTY_HOWTO (88),
+ EMPTY_HOWTO (89),
+ EMPTY_HOWTO (90),
+ EMPTY_HOWTO (91),
+ EMPTY_HOWTO (92),
+ EMPTY_HOWTO (93),
+ EMPTY_HOWTO (94),
+ EMPTY_HOWTO (95),
+ EMPTY_HOWTO (96),
+ EMPTY_HOWTO (97),
+ EMPTY_HOWTO (98),
+ EMPTY_HOWTO (99),
+ EMPTY_HOWTO (100),
+ EMPTY_HOWTO (101),
+ EMPTY_HOWTO (102),
+ EMPTY_HOWTO (103),
+ EMPTY_HOWTO (104),
+ EMPTY_HOWTO (105),
+ EMPTY_HOWTO (106),
+ EMPTY_HOWTO (107),
+ EMPTY_HOWTO (108),
+ EMPTY_HOWTO (109),
+ EMPTY_HOWTO (110),
+ EMPTY_HOWTO (111),
+ EMPTY_HOWTO (112),
+ EMPTY_HOWTO (113),
+ EMPTY_HOWTO (114),
+ EMPTY_HOWTO (115),
+ EMPTY_HOWTO (116),
+ EMPTY_HOWTO (117),
+ EMPTY_HOWTO (118),
+ EMPTY_HOWTO (119),
+ EMPTY_HOWTO (120),
+ EMPTY_HOWTO (121),
+ EMPTY_HOWTO (122),
+ EMPTY_HOWTO (123),
+ EMPTY_HOWTO (124),
+ EMPTY_HOWTO (125),
+ EMPTY_HOWTO (126),
+ EMPTY_HOWTO (127),
+ EMPTY_HOWTO (128),
+ EMPTY_HOWTO (129),
+ EMPTY_HOWTO (130),
+ EMPTY_HOWTO (131),
+ EMPTY_HOWTO (132),
+ EMPTY_HOWTO (133),
+ EMPTY_HOWTO (134),
+ EMPTY_HOWTO (135),
+ EMPTY_HOWTO (136),
+ EMPTY_HOWTO (137),
+ EMPTY_HOWTO (138),
+ EMPTY_HOWTO (139),
+ EMPTY_HOWTO (140),
+ EMPTY_HOWTO (141),
+ EMPTY_HOWTO (142),
+ EMPTY_HOWTO (143),
+ EMPTY_HOWTO (144),
+ EMPTY_HOWTO (145),
+ EMPTY_HOWTO (146),
+ EMPTY_HOWTO (147),
+ EMPTY_HOWTO (148),
+ EMPTY_HOWTO (149),
+ EMPTY_HOWTO (150),
+ EMPTY_HOWTO (151),
+ EMPTY_HOWTO (152),
+ EMPTY_HOWTO (153),
+ EMPTY_HOWTO (154),
+ EMPTY_HOWTO (155),
+ EMPTY_HOWTO (156),
+ EMPTY_HOWTO (157),
+ EMPTY_HOWTO (158),
+ EMPTY_HOWTO (159),
+ EMPTY_HOWTO (160),
+ EMPTY_HOWTO (161),
+ EMPTY_HOWTO (162),
+ EMPTY_HOWTO (163),
+ EMPTY_HOWTO (164),
+ EMPTY_HOWTO (165),
+ EMPTY_HOWTO (166),
+ EMPTY_HOWTO (167),
+ EMPTY_HOWTO (168),
+ EMPTY_HOWTO (169),
+ EMPTY_HOWTO (170),
+ EMPTY_HOWTO (171),
+ EMPTY_HOWTO (172),
+ EMPTY_HOWTO (173),
+ EMPTY_HOWTO (174),
+ EMPTY_HOWTO (175),
+ EMPTY_HOWTO (176),
+ EMPTY_HOWTO (177),
+ EMPTY_HOWTO (178),
+ EMPTY_HOWTO (179),
+ EMPTY_HOWTO (180),
+ EMPTY_HOWTO (181),
+ EMPTY_HOWTO (182),
+ EMPTY_HOWTO (183),
+ EMPTY_HOWTO (184),
+ EMPTY_HOWTO (185),
+ EMPTY_HOWTO (186),
+ EMPTY_HOWTO (187),
+ EMPTY_HOWTO (188),
+ EMPTY_HOWTO (189),
+ EMPTY_HOWTO (190),
+ EMPTY_HOWTO (191),
+ EMPTY_HOWTO (192),
+ EMPTY_HOWTO (193),
+ EMPTY_HOWTO (194),
+ EMPTY_HOWTO (195),
+ EMPTY_HOWTO (196),
+ EMPTY_HOWTO (197),
+ EMPTY_HOWTO (198),
+ EMPTY_HOWTO (199),
+ EMPTY_HOWTO (200),
+ EMPTY_HOWTO (201),
+ EMPTY_HOWTO (202),
+ EMPTY_HOWTO (203),
+ EMPTY_HOWTO (204),
+ EMPTY_HOWTO (205),
+ EMPTY_HOWTO (206),
+ EMPTY_HOWTO (207),
+ EMPTY_HOWTO (208),
+ EMPTY_HOWTO (209),
+ EMPTY_HOWTO (210),
+ EMPTY_HOWTO (211),
+ EMPTY_HOWTO (212),
+ EMPTY_HOWTO (213),
+ EMPTY_HOWTO (214),
+ EMPTY_HOWTO (215),
+ EMPTY_HOWTO (216),
+ EMPTY_HOWTO (217),
+ EMPTY_HOWTO (218),
+ EMPTY_HOWTO (219),
+ EMPTY_HOWTO (220),
+ EMPTY_HOWTO (221),
+ EMPTY_HOWTO (222),
+ EMPTY_HOWTO (223),
+ EMPTY_HOWTO (224),
+ EMPTY_HOWTO (225),
+ EMPTY_HOWTO (226),
+ EMPTY_HOWTO (227),
+ EMPTY_HOWTO (228),
+ EMPTY_HOWTO (229),
+ EMPTY_HOWTO (230),
+ EMPTY_HOWTO (231),
+ EMPTY_HOWTO (232),
+ EMPTY_HOWTO (233),
+ EMPTY_HOWTO (234),
+ EMPTY_HOWTO (235),
+ EMPTY_HOWTO (236),
+ EMPTY_HOWTO (237),
+ EMPTY_HOWTO (238),
+ EMPTY_HOWTO (239),
+ EMPTY_HOWTO (240),
+ EMPTY_HOWTO (241),
+ EMPTY_HOWTO (242),
+ EMPTY_HOWTO (243),
+ EMPTY_HOWTO (244),
+ EMPTY_HOWTO (245),
+ EMPTY_HOWTO (246),
+ EMPTY_HOWTO (247),
+ EMPTY_HOWTO (248),
+ EMPTY_HOWTO (249),
+ EMPTY_HOWTO (250),
+ EMPTY_HOWTO (251),
+ EMPTY_HOWTO (252),
+ HOWTO (R_C6000_ALIGN, /* 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_C6000_ALIGN", /* name */
+ TRUE, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ HOWTO (R_C6000_FPHEAD, /* 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_C6000_FPHEAD", /* name */
+ TRUE, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ HOWTO (R_C6000_NOCMP, /* 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_C6000_NOCMP", /* name */
+ TRUE, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ FALSE) /* pcrel_offset */
+};
+
+/* Map BFD relocations to ELF relocations. */
+
+typedef struct
+{
+ bfd_reloc_code_real_type bfd_reloc_val;
+ enum elf_tic6x_reloc_type elf_reloc_val;
+} tic6x_reloc_map;
+
+static const tic6x_reloc_map elf32_tic6x_reloc_map[] =
+ {
+ { BFD_RELOC_NONE, R_C6000_NONE },
+ { BFD_RELOC_32, R_C6000_ABS32 },
+ { BFD_RELOC_16, R_C6000_ABS16 },
+ { BFD_RELOC_8, R_C6000_ABS8 },
+ { BFD_RELOC_C6000_PCR_S21, R_C6000_PCR_S21 },
+ { BFD_RELOC_C6000_PCR_S12, R_C6000_PCR_S12 },
+ { BFD_RELOC_C6000_PCR_S10, R_C6000_PCR_S10 },
+ { BFD_RELOC_C6000_PCR_S7, R_C6000_PCR_S7 },
+ { BFD_RELOC_C6000_ABS_S16, R_C6000_ABS_S16 },
+ { BFD_RELOC_C6000_ABS_L16, R_C6000_ABS_L16 },
+ { BFD_RELOC_C6000_ABS_H16, R_C6000_ABS_H16 },
+ { BFD_RELOC_C6000_SBR_U15_B, R_C6000_SBR_U15_B },
+ { BFD_RELOC_C6000_SBR_U15_H, R_C6000_SBR_U15_H },
+ { BFD_RELOC_C6000_SBR_U15_W, R_C6000_SBR_U15_W },
+ { BFD_RELOC_C6000_SBR_S16, R_C6000_SBR_S16 },
+ { BFD_RELOC_C6000_SBR_L16_B, R_C6000_SBR_L16_B },
+ { BFD_RELOC_C6000_SBR_L16_H, R_C6000_SBR_L16_H },
+ { BFD_RELOC_C6000_SBR_L16_W, R_C6000_SBR_L16_W },
+ { BFD_RELOC_C6000_SBR_H16_B, R_C6000_SBR_H16_B },
+ { BFD_RELOC_C6000_SBR_H16_H, R_C6000_SBR_H16_H },
+ { BFD_RELOC_C6000_SBR_H16_W, R_C6000_SBR_H16_W },
+ { BFD_RELOC_C6000_SBR_GOT_U15_W, R_C6000_SBR_GOT_U15_W },
+ { BFD_RELOC_C6000_SBR_GOT_L16_W, R_C6000_SBR_GOT_L16_W },
+ { BFD_RELOC_C6000_SBR_GOT_H16_W, R_C6000_SBR_GOT_H16_W },
+ { BFD_RELOC_C6000_DSBT_INDEX, R_C6000_DSBT_INDEX },
+ { BFD_RELOC_C6000_PREL31, R_C6000_PREL31 },
+ { BFD_RELOC_C6000_COPY, R_C6000_COPY },
+ { BFD_RELOC_C6000_JUMP_SLOT, R_C6000_JUMP_SLOT },
+ { BFD_RELOC_C6000_EHTYPE, R_C6000_EHTYPE },
+ { BFD_RELOC_C6000_PCR_H16, R_C6000_PCR_H16 },
+ { BFD_RELOC_C6000_PCR_L16, R_C6000_PCR_L16 },
+ { BFD_RELOC_C6000_ALIGN, R_C6000_ALIGN },
+ { BFD_RELOC_C6000_FPHEAD, R_C6000_FPHEAD },
+ { BFD_RELOC_C6000_NOCMP, R_C6000_NOCMP }
+ };
+
+static reloc_howto_type *
+elf32_tic6x_reloc_type_lookup (bfd *abfd, bfd_reloc_code_real_type code)
+{
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE (elf32_tic6x_reloc_map); i++)
+ if (elf32_tic6x_reloc_map[i].bfd_reloc_val == code)
+ {
+ enum elf_tic6x_reloc_type elf_reloc_val;
+ reloc_howto_type *howto;
+
+ elf_reloc_val = elf32_tic6x_reloc_map[i].elf_reloc_val;
+ if (elf32_tic6x_tdata (abfd)->use_rela_p)
+ howto = &elf32_tic6x_howto_table[elf_reloc_val];
+ else
+ howto = &elf32_tic6x_howto_table_rel[elf_reloc_val];
+
+ /* Some relocations are RELA-only; do not return them for
+ REL. */
+ if (howto->name == NULL)
+ howto = NULL;
+
+ return howto;
+ }
+
+ return NULL;
+}
+
+static reloc_howto_type *
+elf32_tic6x_reloc_name_lookup (bfd *abfd, const char *r_name)
+{
+ if (elf32_tic6x_tdata (abfd)->use_rela_p)
+ {
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE (elf32_tic6x_howto_table); i++)
+ if (elf32_tic6x_howto_table[i].name != NULL
+ && strcasecmp (elf32_tic6x_howto_table[i].name, r_name) == 0)
+ return &elf32_tic6x_howto_table[i];
+ }
+ else
+ {
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE (elf32_tic6x_howto_table_rel); i++)
+ if (elf32_tic6x_howto_table_rel[i].name != NULL
+ && strcasecmp (elf32_tic6x_howto_table_rel[i].name, r_name) == 0)
+ return &elf32_tic6x_howto_table_rel[i];
+ }
+
+ return NULL;
+}
+
+static void
+elf32_tic6x_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED, arelent *bfd_reloc,
+ Elf_Internal_Rela *elf_reloc)
+{
+ unsigned int r_type;
+
+ r_type = ELF32_R_TYPE (elf_reloc->r_info);
+ if (r_type >= ARRAY_SIZE (elf32_tic6x_howto_table))
+ bfd_reloc->howto = NULL;
+ else
+ bfd_reloc->howto = &elf32_tic6x_howto_table[r_type];
+}
+
+static void
+elf32_tic6x_info_to_howto_rel (bfd *abfd ATTRIBUTE_UNUSED, arelent *bfd_reloc,
+ Elf_Internal_Rela *elf_reloc)
+{
+ unsigned int r_type;
+
+ r_type = ELF32_R_TYPE (elf_reloc->r_info);
+ if (r_type >= ARRAY_SIZE (elf32_tic6x_howto_table_rel))
+ bfd_reloc->howto = NULL;
+ else
+ bfd_reloc->howto = &elf32_tic6x_howto_table_rel[r_type];
+}
+
+void
+elf32_tic6x_set_use_rela_p (bfd *abfd, bfd_boolean use_rela_p)
+{
+ elf32_tic6x_tdata (abfd)->use_rela_p = use_rela_p;
+}
+
+/* Create an entry in a C6X ELF linker hash table. */
+
+static struct bfd_hash_entry *
+elf32_tic6x_link_hash_newfunc (struct bfd_hash_entry *entry,
+ struct bfd_hash_table *table,
+ const char *string)
+{
+ /* Allocate the structure if it has not already been allocated by a
+ subclass. */
+ if (entry == NULL)
+ {
+ entry = bfd_hash_allocate (table,
+ sizeof (struct elf32_tic6x_link_hash_entry));
+ if (entry == NULL)
+ return entry;
+ }
+
+ /* Call the allocation method of the superclass. */
+ entry = _bfd_elf_link_hash_newfunc (entry, table, string);
+ if (entry != NULL)
+ {
+ struct elf32_tic6x_link_hash_entry *eh;
+
+ eh = (struct elf32_tic6x_link_hash_entry *) entry;
+ eh->dyn_relocs = NULL;
+ }
+
+ return entry;
+}
+
+/* Create a C6X ELF linker hash table. */
+
+static struct bfd_link_hash_table *
+elf32_tic6x_link_hash_table_create (bfd *abfd)
+{
+ struct elf32_tic6x_link_hash_table *ret;
+ bfd_size_type amt = sizeof (struct elf32_tic6x_link_hash_table);
+
+ ret = bfd_zmalloc (amt);
+ if (ret == NULL)
+ return NULL;
+
+ if (!_bfd_elf_link_hash_table_init (&ret->elf, abfd,
+ elf32_tic6x_link_hash_newfunc,
+ sizeof (struct elf32_tic6x_link_hash_entry),
+ TIC6X_ELF_DATA))
+ {
+ free (ret);
+ return NULL;
+ }
+
+ ret->obfd = abfd;
+ ret->elf.is_relocatable_executable = 1;
+
+ return &ret->elf.root;
+}
+
+static bfd_boolean
+elf32_tic6x_final_link (bfd *abfd, struct bfd_link_info *info)
+{
+ if (info->shared)
+ {
+ obj_attribute *out_attr;
+ out_attr = elf_known_obj_attributes_proc (abfd);
+ if (out_attr[Tag_ABI_PIC].i == 0)
+ {
+ _bfd_error_handler (_("warning: generating a shared library "
+ "containing non-PIC code"));
+ }
+ if (out_attr[Tag_ABI_PID].i == 0)
+ {
+ _bfd_error_handler (_("warning: generating a shared library "
+ "containing non-PID code"));
+ }
+ }
+ /* Invoke the regular ELF backend linker to do all the work. */
+ if (!bfd_elf_final_link (abfd, info))
+ return FALSE;
+
+ return TRUE;
+}
+
+/* Called to pass PARAMS to the backend. We store them in the hash table
+ associated with INFO. */
+
+void
+elf32_tic6x_setup (struct bfd_link_info *info,
+ struct elf32_tic6x_params *params)
+{
+ struct elf32_tic6x_link_hash_table *htab = elf32_tic6x_hash_table (info);
+ htab->params = *params;
+}
+
+/* Determine if we're dealing with a DSBT object. */
+
+static bfd_boolean
+elf32_tic6x_using_dsbt (bfd *abfd)
+{
+ return bfd_elf_get_obj_attr_int (abfd, OBJ_ATTR_PROC,
+ Tag_ABI_DSBT);
+}
+
+/* Create .plt, .rela.plt, .got, .got.plt, .rela.got and .dsbt
+ sections in DYNOBJ, and set up shortcuts to them in our hash
+ table. */
+
+static bfd_boolean
+elf32_tic6x_create_dynamic_sections (bfd *dynobj, struct bfd_link_info *info)
+{
+ struct elf32_tic6x_link_hash_table *htab;
+ flagword flags;
+
+ htab = elf32_tic6x_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ if (!_bfd_elf_create_dynamic_sections (dynobj, info))
+ return FALSE;
+
+ /* Create .dsbt */
+ flags = (SEC_ALLOC | SEC_LOAD
+ | SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_LINKER_CREATED);
+ htab->dsbt = bfd_make_section_anyway_with_flags (dynobj, ".dsbt",
+ flags);
+ if (htab->dsbt == NULL
+ || ! bfd_set_section_alignment (dynobj, htab->dsbt, 2)
+ || ! bfd_set_section_alignment (dynobj, htab->elf.splt, 5))
+ return FALSE;
+
+ htab->sdynbss = bfd_get_linker_section (dynobj, ".dynbss");
+ if (!info->shared)
+ htab->srelbss = bfd_get_linker_section (dynobj, ".rela.bss");
+
+ if (!htab->sdynbss
+ || (!info->shared && !htab->srelbss))
+ abort ();
+
+ return TRUE;
+}
+
+static bfd_boolean
+elf32_tic6x_mkobject (bfd *abfd)
+{
+ bfd_boolean ret;
+
+ ret = bfd_elf_allocate_object (abfd, sizeof (struct elf32_tic6x_obj_tdata),
+ TIC6X_ELF_DATA);
+ if (ret)
+ elf32_tic6x_set_use_rela_p (abfd, TRUE);
+ return ret;
+}
+
+/* Install relocation RELA into section SRELA, incrementing its
+ reloc_count. */
+
+static void
+elf32_tic6x_install_rela (bfd *output_bfd, asection *srela,
+ Elf_Internal_Rela *rela)
+{
+ bfd_byte *loc;
+ bfd_vma off = srela->reloc_count++ * sizeof (Elf32_External_Rela);
+ loc = srela->contents + off;
+ BFD_ASSERT (off < srela->size);
+ bfd_elf32_swap_reloca_out (output_bfd, rela, loc);
+}
+
+/* Create a dynamic reloc against the GOT at offset OFFSET. The contents
+ of the GOT at this offset have been initialized with the relocation. */
+
+static void
+elf32_tic6x_make_got_dynreloc (bfd *output_bfd,
+ struct elf32_tic6x_link_hash_table *htab,
+ asection *sym_sec, bfd_vma offset)
+{
+ asection *sgot = htab->elf.sgot;
+ Elf_Internal_Rela outrel;
+ int dynindx;
+
+ outrel.r_offset = sgot->output_section->vma + sgot->output_offset + offset;
+ outrel.r_addend = bfd_get_32 (output_bfd, sgot->contents + offset);
+ if (sym_sec && sym_sec->output_section
+ && ! bfd_is_abs_section (sym_sec->output_section)
+ && ! bfd_is_und_section (sym_sec->output_section))
+ {
+ dynindx = elf_section_data (sym_sec->output_section)->dynindx;
+ outrel.r_addend -= sym_sec->output_section->vma;
+ }
+ else
+ {
+ dynindx = 0;
+ }
+ outrel.r_info = ELF32_R_INFO (dynindx, R_C6000_ABS32);
+ elf32_tic6x_install_rela (output_bfd, htab->elf.srelgot, &outrel);
+}
+
+/* Finish up dynamic symbol handling. We set the contents of various
+ dynamic sections here. */
+
+static bfd_boolean
+elf32_tic6x_finish_dynamic_symbol (bfd * output_bfd,
+ struct bfd_link_info *info,
+ struct elf_link_hash_entry *h,
+ Elf_Internal_Sym * sym)
+{
+ bfd *dynobj;
+ struct elf32_tic6x_link_hash_table *htab;
+
+ htab = elf32_tic6x_hash_table (info);
+ dynobj = htab->elf.dynobj;
+
+ if (h->plt.offset != (bfd_vma) -1)
+ {
+ bfd_vma plt_index;
+ bfd_vma got_section_offset, got_dp_offset, rela_offset;
+ Elf_Internal_Rela rela;
+ bfd_byte *loc;
+ asection *plt, *gotplt, *relplt;
+ const struct elf_backend_data *bed;
+
+ bed = get_elf_backend_data (output_bfd);
+
+ BFD_ASSERT (htab->elf.splt != NULL);
+ plt = htab->elf.splt;
+ gotplt = htab->elf.sgotplt;
+ relplt = htab->elf.srelplt;
+
+ /* This symbol has an entry in the procedure linkage table. Set
+ it up. */
+
+ if ((h->dynindx == -1
+ && !((h->forced_local || info->executable)
+ && h->def_regular
+ && h->type == STT_GNU_IFUNC))
+ || plt == NULL
+ || gotplt == NULL
+ || relplt == NULL)
+ abort ();
+
+ /* 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.
+
+ 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.
+
+ For static executables, we don't reserve anything. */
+
+ plt_index = h->plt.offset / PLT_ENTRY_SIZE - 1;
+ got_section_offset = plt_index + bed->got_header_size / 4;
+ got_dp_offset = got_section_offset + htab->params.dsbt_size;
+ rela_offset = plt_index * sizeof (Elf32_External_Rela);
+
+ got_section_offset *= 4;
+
+ /* Fill in the entry in the procedure linkage table. */
+
+ /* ldw .d2t2 *+B14($GOT(f)), b2 */
+ bfd_put_32 (output_bfd, got_dp_offset << 8 | 0x0100006e,
+ plt->contents + h->plt.offset);
+ /* mvk .s2 low(rela_offset), b0 */
+ bfd_put_32 (output_bfd, (rela_offset & 0xffff) << 7 | 0x0000002a,
+ plt->contents + h->plt.offset + 4);
+ /* mvkh .s2 high(rela_offset), b0 */
+ bfd_put_32 (output_bfd, ((rela_offset >> 16) & 0xffff) << 7 | 0x0000006a,
+ plt->contents + h->plt.offset + 8);
+ /* nop 2 */
+ bfd_put_32 (output_bfd, 0x00002000,
+ plt->contents + h->plt.offset + 12);
+ /* b .s2 b2 */
+ bfd_put_32 (output_bfd, 0x00080362,
+ plt->contents + h->plt.offset + 16);
+ /* nop 5 */
+ bfd_put_32 (output_bfd, 0x00008000,
+ plt->contents + h->plt.offset + 20);
+
+ /* Fill in the entry in the global offset table. */
+ bfd_put_32 (output_bfd,
+ (plt->output_section->vma + plt->output_offset),
+ gotplt->contents + got_section_offset);
+
+ /* Fill in the entry in the .rel.plt section. */
+ rela.r_offset = (gotplt->output_section->vma
+ + gotplt->output_offset
+ + got_section_offset);
+ rela.r_info = ELF32_R_INFO (h->dynindx, R_C6000_JUMP_SLOT);
+ rela.r_addend = 0;
+ loc = relplt->contents + rela_offset;
+ bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
+
+ if (!h->def_regular)
+ {
+ /* Mark the symbol as undefined, rather than as defined in
+ the .plt section. */
+ sym->st_shndx = SHN_UNDEF;
+ sym->st_value = 0;
+ }
+ }
+
+ if (h->got.offset != (bfd_vma) -1)
+ {
+ asection *sgot;
+ asection *srela;
+
+ /* This symbol has an entry in the global offset table.
+ Set it up. */
+
+ sgot = bfd_get_linker_section (dynobj, ".got");
+ srela = bfd_get_linker_section (dynobj, ".rela.got");
+ BFD_ASSERT (sgot != NULL && srela != NULL);
+
+ /* 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->forced_local) && h->def_regular)
+ {
+ asection *s = h->root.u.def.section;
+ elf32_tic6x_make_got_dynreloc (output_bfd, htab, s,
+ h->got.offset & ~(bfd_vma) 1);
+ }
+ else
+ {
+ Elf_Internal_Rela outrel;
+ bfd_put_32 (output_bfd, (bfd_vma) 0,
+ sgot->contents + (h->got.offset & ~(bfd_vma) 1));
+ outrel.r_offset = (sgot->output_section->vma
+ + sgot->output_offset
+ + (h->got.offset & ~(bfd_vma) 1));
+ outrel.r_info = ELF32_R_INFO (h->dynindx, R_C6000_ABS32);
+ outrel.r_addend = 0;
+
+ elf32_tic6x_install_rela (output_bfd, srela, &outrel);
+ }
+ }
+
+ if (h->needs_copy)
+ {
+ Elf_Internal_Rela rel;
+
+ /* This symbol needs a copy reloc. Set it up. */
+
+ if (h->dynindx == -1
+ || (h->root.type != bfd_link_hash_defined
+ && h->root.type != bfd_link_hash_defweak)
+ || htab->srelbss == NULL)
+ abort ();
+
+ 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_C6000_COPY);
+ rel.r_addend = 0;
+
+ elf32_tic6x_install_rela (output_bfd, htab->srelbss, &rel);
+ }
+
+ /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute. */
+ if (h == elf_hash_table (info)->hdynamic
+ || h == elf_hash_table (info)->hgot)
+ sym->st_shndx = SHN_ABS;
+
+ return TRUE;
+}
+
+/* Unwinding tables are not referenced directly. This pass marks them as
+ required if the corresponding code section is marked. */
+
+static bfd_boolean
+elf32_tic6x_gc_mark_extra_sections (struct bfd_link_info *info,
+ elf_gc_mark_hook_fn gc_mark_hook)
+{
+ bfd *sub;
+ Elf_Internal_Shdr **elf_shdrp;
+ bfd_boolean again;
+
+ _bfd_elf_gc_mark_extra_sections (info, gc_mark_hook);
+
+ /* Marking EH data may cause additional code sections to be marked,
+ requiring multiple passes. */
+ again = TRUE;
+ while (again)
+ {
+ again = FALSE;
+ for (sub = info->input_bfds; sub != NULL; sub = sub->link.next)
+ {
+ asection *o;
+
+ if (! is_tic6x_elf (sub))
+ continue;
+
+ elf_shdrp = elf_elfsections (sub);
+ for (o = sub->sections; o != NULL; o = o->next)
+ {
+ Elf_Internal_Shdr *hdr;
+
+ hdr = &elf_section_data (o)->this_hdr;
+ if (hdr->sh_type == SHT_C6000_UNWIND
+ && hdr->sh_link
+ && hdr->sh_link < elf_numsections (sub)
+ && !o->gc_mark
+ && elf_shdrp[hdr->sh_link]->bfd_section->gc_mark)
+ {
+ again = TRUE;
+ if (!_bfd_elf_gc_mark (info, o, gc_mark_hook))
+ return FALSE;
+ }
+ }
+ }
+ }
+
+ return TRUE;
+}
+
+/* Return TRUE if this is an unwinding table index. */
+
+static bfd_boolean
+is_tic6x_elf_unwind_section_name (const char *name)
+{
+ return (CONST_STRNEQ (name, ELF_STRING_C6000_unwind)
+ || CONST_STRNEQ (name, ELF_STRING_C6000_unwind_once));
+}
+
+
+/* Set the type and flags for an unwinding index table. We do this by
+ the section name, which is a hack, but ought to work. */
+
+static bfd_boolean
+elf32_tic6x_fake_sections (bfd *abfd ATTRIBUTE_UNUSED,
+ Elf_Internal_Shdr *hdr, asection *sec)
+{
+ const char * name;
+
+ name = bfd_get_section_name (abfd, sec);
+
+ if (is_tic6x_elf_unwind_section_name (name))
+ {
+ hdr->sh_type = SHT_C6000_UNWIND;
+ hdr->sh_flags |= SHF_LINK_ORDER;
+ }
+
+ return TRUE;
+}
+
+/* Update the got entry reference counts for the section being removed. */
+
+static bfd_boolean
+elf32_tic6x_gc_sweep_hook (bfd *abfd,
+ struct bfd_link_info *info,
+ asection *sec,
+ const Elf_Internal_Rela *relocs)
+{
+ struct elf32_tic6x_link_hash_table *htab;
+ Elf_Internal_Shdr *symtab_hdr;
+ struct elf_link_hash_entry **sym_hashes;
+ bfd_signed_vma *local_got_refcounts;
+ const Elf_Internal_Rela *rel, *relend;
+
+ if (info->relocatable)
+ return TRUE;
+
+ htab = elf32_tic6x_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ elf_section_data (sec)->local_dynrel = NULL;
+
+ symtab_hdr = &elf_symtab_hdr (abfd);
+ 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++)
+ {
+ unsigned long r_symndx;
+ unsigned int r_type;
+ struct elf_link_hash_entry *h = NULL;
+
+ r_symndx = ELF32_R_SYM (rel->r_info);
+ if (r_symndx >= symtab_hdr->sh_info)
+ {
+ struct elf32_tic6x_link_hash_entry *eh;
+ struct elf_dyn_relocs **pp;
+ struct elf_dyn_relocs *p;
+
+ 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;
+ eh = (struct elf32_tic6x_link_hash_entry *) h;
+
+ for (pp = &eh->dyn_relocs; (p = *pp) != NULL; pp = &p->next)
+ if (p->sec == sec)
+ {
+ /* Everything must go for SEC. */
+ *pp = p->next;
+ break;
+ }
+ }
+
+ r_type = ELF32_R_TYPE (rel->r_info);
+
+ switch (r_type)
+ {
+ case R_C6000_SBR_GOT_U15_W:
+ case R_C6000_SBR_GOT_L16_W:
+ case R_C6000_SBR_GOT_H16_W:
+ case R_C6000_EHTYPE:
+ if (h != NULL)
+ {
+ if (h->got.refcount > 0)
+ h->got.refcount -= 1;
+ }
+ else if (local_got_refcounts != NULL)
+ {
+ if (local_got_refcounts[r_symndx] > 0)
+ local_got_refcounts[r_symndx] -= 1;
+ }
+ 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 bfd_boolean
+elf32_tic6x_adjust_dynamic_symbol (struct bfd_link_info *info,
+ struct elf_link_hash_entry *h)
+{
+ struct elf32_tic6x_link_hash_table *htab;
+ bfd *dynobj;
+ asection *s;
+
+ dynobj = elf_hash_table (info)->dynobj;
+
+ /* Make sure we know what is going on here. */
+ BFD_ASSERT (dynobj != NULL
+ && (h->needs_plt
+ || h->u.weakdef != NULL
+ || (h->def_dynamic && h->ref_regular && !h->def_regular)));
+
+ /* 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->needs_plt)
+ {
+ if (h->plt.refcount <= 0
+ || SYMBOL_CALLS_LOCAL (info, h)
+ || (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
+ && h->root.type == bfd_link_hash_undefweak))
+ {
+ /* 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, or if all references were garbage collected. In
+ such a case, we don't actually need to build a procedure
+ linkage table, and we can just do a PC32 reloc instead. */
+ h->plt.offset = (bfd_vma) -1;
+ h->needs_plt = 0;
+ }
+
+ 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->u.weakdef != NULL)
+ {
+ BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
+ || h->u.weakdef->root.type == bfd_link_hash_defweak);
+ h->root.u.def.section = h->u.weakdef->root.u.def.section;
+ h->root.u.def.value = h->u.weakdef->root.u.def.value;
+ h->non_got_ref = h->u.weakdef->non_got_ref;
+ 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;
+
+ /* If there are no references to this symbol that do not use the
+ GOT, we don't need to generate a copy reloc. */
+ if (!h->non_got_ref)
+ return TRUE;
+
+ /* If -z nocopyreloc was given, we won't generate them either. */
+ if (info->nocopyreloc)
+ {
+ h->non_got_ref = 0;
+ return TRUE;
+ }
+
+ htab = elf32_tic6x_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ /* 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. */
+
+ /* We must generate a R_C6000_COPY reloc to tell the dynamic linker to
+ copy the initial value out of the dynamic object and into the
+ runtime process image. */
+ if ((h->root.u.def.section->flags & SEC_ALLOC) != 0 && h->size != 0)
+ {
+ htab->srelbss->size += sizeof (Elf32_External_Rela);
+ h->needs_copy = 1;
+ }
+
+ s = htab->sdynbss;
+
+ return _bfd_elf_adjust_dynamic_copy (h, s);
+}
+
+static bfd_boolean
+elf32_tic6x_new_section_hook (bfd *abfd, asection *sec)
+{
+ bfd_boolean ret;
+
+ /* Allocate target specific section data. */
+ if (!sec->used_by_bfd)
+ {
+ _tic6x_elf_section_data *sdata;
+ bfd_size_type amt = sizeof (*sdata);
+
+ sdata = (_tic6x_elf_section_data *) bfd_zalloc (abfd, amt);
+ if (sdata == NULL)
+ return FALSE;
+ sec->used_by_bfd = sdata;
+ }
+
+ ret = _bfd_elf_new_section_hook (abfd, sec);
+ sec->use_rela_p = elf32_tic6x_tdata (abfd)->use_rela_p;
+
+ return ret;
+}
+
+/* Return true if relocation REL against section SEC is a REL rather
+ than RELA relocation. RELOCS is the first relocation in the
+ section and ABFD is the bfd that contains SEC. */
+
+static bfd_boolean
+elf32_tic6x_rel_relocation_p (bfd *abfd, asection *sec,
+ const Elf_Internal_Rela *relocs,
+ const Elf_Internal_Rela *rel)
+{
+ Elf_Internal_Shdr *rel_hdr;
+ const struct elf_backend_data *bed;
+
+ /* To determine which flavor of relocation this is, we depend on the
+ fact that the INPUT_SECTION's REL_HDR is read before RELA_HDR. */
+ rel_hdr = elf_section_data (sec)->rel.hdr;
+ if (rel_hdr == NULL)
+ return FALSE;
+ bed = get_elf_backend_data (abfd);
+ return ((size_t) (rel - relocs)
+ < NUM_SHDR_ENTRIES (rel_hdr) * bed->s->int_rels_per_ext_rel);
+}
+
+/* We need dynamic symbols for every section, since segments can
+ relocate independently. */
+static bfd_boolean
+elf32_tic6x_link_omit_section_dynsym (bfd *output_bfd ATTRIBUTE_UNUSED,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ asection *p)
+{
+ switch (elf_section_data (p)->this_hdr.sh_type)
+ {
+ case SHT_PROGBITS:
+ case SHT_NOBITS:
+ /* If sh_type is yet undecided, assume it could be
+ SHT_PROGBITS/SHT_NOBITS. */
+ case SHT_NULL:
+ return FALSE;
+
+ /* There shouldn't be section relative relocations
+ against any other section. */
+ default:
+ return TRUE;
+ }
+}
+
+static bfd_boolean
+elf32_tic6x_relocate_section (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)
+{
+ struct elf32_tic6x_link_hash_table *htab;
+ Elf_Internal_Shdr *symtab_hdr;
+ struct elf_link_hash_entry **sym_hashes;
+ bfd_vma *local_got_offsets;
+ Elf_Internal_Rela *rel;
+ Elf_Internal_Rela *relend;
+ bfd_boolean ok = TRUE;
+
+ htab = elf32_tic6x_hash_table (info);
+ symtab_hdr = & elf_symtab_hdr (input_bfd);
+ sym_hashes = elf_sym_hashes (input_bfd);
+ local_got_offsets = elf_local_got_offsets (input_bfd);
+
+ relend = relocs + input_section->reloc_count;
+
+ for (rel = relocs; rel < relend; rel ++)
+ {
+ int r_type;
+ unsigned long r_symndx;
+ arelent bfd_reloc;
+ reloc_howto_type *howto;
+ Elf_Internal_Sym *sym;
+ asection *sec;
+ struct elf_link_hash_entry *h;
+ bfd_vma off, off2, relocation;
+ bfd_boolean unresolved_reloc;
+ bfd_reloc_status_type r;
+ struct bfd_link_hash_entry *sbh;
+ bfd_boolean is_rel;
+
+ r_type = ELF32_R_TYPE (rel->r_info);
+ r_symndx = ELF32_R_SYM (rel->r_info);
+
+ is_rel = elf32_tic6x_rel_relocation_p (input_bfd, input_section,
+ relocs, rel);
+
+ if (is_rel)
+ elf32_tic6x_info_to_howto_rel (input_bfd, &bfd_reloc, rel);
+ else
+ elf32_tic6x_info_to_howto (input_bfd, &bfd_reloc, rel);
+ howto = bfd_reloc.howto;
+ if (howto == NULL)
+ {
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+
+ h = NULL;
+ sym = NULL;
+ sec = NULL;
+ unresolved_reloc = FALSE;
+
+ if (r_symndx < symtab_hdr->sh_info)
+ {
+ sym = local_syms + r_symndx;
+ sec = local_sections[r_symndx];
+ relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
+ }
+ else
+ {
+ bfd_boolean warned, ignored;
+
+ RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
+ r_symndx, symtab_hdr, sym_hashes,
+ h, sec, relocation,
+ unresolved_reloc, warned, ignored);
+ }
+
+ if (sec != NULL && discarded_section (sec))
+ RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+ rel, 1, relend, howto, 0, contents);
+
+ if (info->relocatable)
+ {
+ if (is_rel
+ && sym != NULL
+ && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
+ {
+ rel->r_addend = 0;
+ relocation = sec->output_offset + sym->st_value;
+ r = _bfd_relocate_contents (howto, input_bfd, relocation,
+ contents + rel->r_offset);
+ goto done_reloc;
+ }
+ continue;
+ }
+
+ switch (r_type)
+ {
+ case R_C6000_NONE:
+ case R_C6000_ALIGN:
+ case R_C6000_FPHEAD:
+ case R_C6000_NOCMP:
+ /* No action needed. */
+ continue;
+
+ case R_C6000_PCR_S21:
+ /* A branch to an undefined weak symbol is turned into a
+ "b .s2 B3" instruction if the existing insn is of the
+ form "b .s2 symbol". */
+ if (h ? h->root.type == bfd_link_hash_undefweak
+ && (htab->elf.splt == NULL || h->plt.offset == (bfd_vma) -1)
+ : r_symndx != STN_UNDEF && bfd_is_und_section (sec))
+ {
+ unsigned long oldval;
+ oldval = bfd_get_32 (input_bfd, contents + rel->r_offset);
+
+ if ((oldval & 0x7e) == 0x12)
+ {
+ oldval &= 0xF0000001;
+ bfd_put_32 (input_bfd, oldval | 0x000c0362,
+ contents + rel->r_offset);
+ r = bfd_reloc_ok;
+ goto done_reloc;
+ }
+ }
+
+ case R_C6000_PCR_S12:
+ case R_C6000_PCR_S10:
+ case R_C6000_PCR_S7:
+ if (h != NULL
+ && h->plt.offset != (bfd_vma) -1
+ && htab->elf.splt != NULL)
+ {
+ relocation = (htab->elf.splt->output_section->vma
+ + htab->elf.splt->output_offset
+ + h->plt.offset);
+ }
+
+ /* Generic PC-relative handling produces a value relative to
+ the exact location of the relocation. Adjust it to be
+ relative to the start of the fetch packet instead. */
+ relocation += (input_section->output_section->vma
+ + input_section->output_offset
+ + rel->r_offset) & 0x1f;
+ unresolved_reloc = FALSE;
+ break;
+
+ case R_C6000_PCR_H16:
+ case R_C6000_PCR_L16:
+ off = (input_section->output_section->vma
+ + input_section->output_offset
+ + rel->r_offset);
+ /* These must be calculated as R = S - FP(FP(PC) - A).
+ PC, here, is the value we just computed in OFF. RELOCATION
+ has the address of S + A. */
+ relocation -= rel->r_addend;
+ off2 = ((off & ~(bfd_vma)0x1f) - rel->r_addend) & (bfd_vma)~0x1f;
+ off2 = relocation - off2;
+ relocation = off + off2;
+ break;
+
+ case R_C6000_DSBT_INDEX:
+ relocation = elf32_tic6x_hash_table (info)->params.dsbt_index;
+ if (!info->shared || relocation != 0)
+ break;
+
+ /* fall through */
+ case R_C6000_ABS32:
+ case R_C6000_ABS16:
+ case R_C6000_ABS8:
+ case R_C6000_ABS_S16:
+ case R_C6000_ABS_L16:
+ case R_C6000_ABS_H16:
+ /* When generating a shared object or relocatable executable, these
+ relocations are copied into the output file to be resolved at
+ run time. */
+ if ((info->shared || elf32_tic6x_using_dsbt (output_bfd))
+ && (input_section->flags & SEC_ALLOC)
+ && (h == NULL
+ || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
+ || h->root.type != bfd_link_hash_undefweak))
+ {
+ Elf_Internal_Rela outrel;
+ bfd_boolean skip, relocate;
+ asection *sreloc;
+
+ unresolved_reloc = FALSE;
+
+ sreloc = elf_section_data (input_section)->sreloc;
+ BFD_ASSERT (sreloc != NULL && sreloc->contents != NULL);
+
+ skip = FALSE;
+ relocate = FALSE;
+
+ outrel.r_offset =
+ _bfd_elf_section_offset (output_bfd, info, input_section,
+ rel->r_offset);
+ if (outrel.r_offset == (bfd_vma) -1)
+ skip = TRUE;
+ else if (outrel.r_offset == (bfd_vma) -2)
+ skip = TRUE, relocate = TRUE;
+ outrel.r_offset += (input_section->output_section->vma
+ + input_section->output_offset);
+
+ if (skip)
+ memset (&outrel, 0, sizeof outrel);
+ else if (h != NULL
+ && h->dynindx != -1
+ && (!info->shared
+ || !info->symbolic
+ || !h->def_regular))
+ {
+ outrel.r_info = ELF32_R_INFO (h->dynindx, r_type);
+ outrel.r_addend = rel->r_addend;
+ }
+ else
+ {
+ long indx;
+
+ outrel.r_addend = relocation + rel->r_addend;
+
+ if (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;
+ outrel.r_addend -= osec->vma;
+ BFD_ASSERT (indx != 0);
+ }
+
+ outrel.r_info = ELF32_R_INFO (indx, r_type);
+ }
+
+ elf32_tic6x_install_rela (output_bfd, sreloc, &outrel);
+
+ /* 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;
+ }
+
+ /* Generic logic OK. */
+ break;
+
+ case R_C6000_SBR_U15_B:
+ case R_C6000_SBR_U15_H:
+ case R_C6000_SBR_U15_W:
+ case R_C6000_SBR_S16:
+ case R_C6000_SBR_L16_B:
+ case R_C6000_SBR_L16_H:
+ case R_C6000_SBR_L16_W:
+ case R_C6000_SBR_H16_B:
+ case R_C6000_SBR_H16_H:
+ case R_C6000_SBR_H16_W:
+ sbh = bfd_link_hash_lookup (info->hash, "__c6xabi_DSBT_BASE",
+ FALSE, FALSE, TRUE);
+ if (sbh != NULL
+ && (sbh->type == bfd_link_hash_defined
+ || sbh->type == bfd_link_hash_defweak))
+ {
+ if (h ? (h->root.type == bfd_link_hash_undefweak
+ && (htab->elf.splt == NULL
+ || h->plt.offset == (bfd_vma) -1))
+ : r_symndx != STN_UNDEF && bfd_is_und_section (sec))
+ relocation = 0;
+ else
+ relocation -= (sbh->u.def.value
+ + sbh->u.def.section->output_section->vma
+ + sbh->u.def.section->output_offset);
+ }
+ else
+ {
+ (*_bfd_error_handler) (_("%B: SB-relative relocation but "
+ "__c6xabi_DSBT_BASE not defined"),
+ input_bfd);
+ ok = FALSE;
+ continue;
+ }
+ break;
+
+ case R_C6000_SBR_GOT_U15_W:
+ case R_C6000_SBR_GOT_L16_W:
+ case R_C6000_SBR_GOT_H16_W:
+ case R_C6000_EHTYPE:
+ /* Relocation is to the entry for this symbol in the global
+ offset table. */
+ if (htab->elf.sgot == NULL)
+ abort ();
+
+ if (h != NULL)
+ {
+ bfd_boolean dyn;
+
+ off = h->got.offset;
+ dyn = htab->elf.dynamic_sections_created;
+ if (! WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h)
+ || (info->shared
+ && SYMBOL_REFERENCES_LOCAL (info, h))
+ || (ELF_ST_VISIBILITY (h->other)
+ && h->root.type == bfd_link_hash_undefweak))
+ {
+ /* 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,
+ htab->elf.sgot->contents + off);
+ h->got.offset |= 1;
+
+ if (!WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared,
+ h)
+ && !(ELF_ST_VISIBILITY (h->other)
+ && h->root.type == bfd_link_hash_undefweak))
+ elf32_tic6x_make_got_dynreloc (output_bfd, htab, sec,
+ off);
+ }
+ }
+ else
+ unresolved_reloc = FALSE;
+ }
+ else
+ {
+ if (local_got_offsets == NULL)
+ abort ();
+
+ 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,
+ htab->elf.sgot->contents + off);
+
+ if (info->shared || elf32_tic6x_using_dsbt (output_bfd))
+ elf32_tic6x_make_got_dynreloc (output_bfd, htab, sec, off);
+
+ local_got_offsets[r_symndx] |= 1;
+ }
+ }
+
+ if (off >= (bfd_vma) -2)
+ abort ();
+
+ if (htab->dsbt)
+ relocation = (htab->elf.sgot->output_section->vma
+ + htab->elf.sgot->output_offset + off
+ - htab->dsbt->output_section->vma
+ - htab->dsbt->output_offset);
+ else
+ relocation = (htab->elf.sgot->output_section->vma
+ + htab->elf.sgot->output_offset + off
+ - htab->elf.sgotplt->output_section->vma
+ - htab->elf.sgotplt->output_offset);
+
+ if (rel->r_addend != 0)
+ {
+ /* We can't do anything for a relocation which is against
+ a symbol *plus offset*. GOT holds relocations for
+ symbols. Make this an error; the compiler isn't
+ allowed to pass us these kinds of things. */
+ if (h == NULL)
+ (*_bfd_error_handler)
+ (_("%B, section %A: relocation %s with non-zero addend %d"
+ " against local symbol"),
+ input_bfd,
+ input_section,
+ elf32_tic6x_howto_table[r_type].name,
+ rel->r_addend);
+ else
+ (*_bfd_error_handler)
+ (_("%B, section %A: relocation %s with non-zero addend %d"
+ " against symbol `%s'"),
+ input_bfd,
+ input_section,
+ elf32_tic6x_howto_table[r_type].name,
+ rel->r_addend,
+ h->root.root.string[0] != '\0' ? h->root.root.string
+ : _("[whose name is lost]"));
+
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+ break;
+
+ case R_C6000_PREL31:
+ if (h != NULL
+ && h->plt.offset != (bfd_vma) -1
+ && htab->elf.splt != NULL)
+ {
+ relocation = (htab->elf.splt->output_section->vma
+ + htab->elf.splt->output_offset
+ + h->plt.offset);
+ }
+ break;
+
+ case R_C6000_COPY:
+ /* Invalid in relocatable object. */
+ default:
+ /* Unknown relocation. */
+ (*_bfd_error_handler) (_("%B: invalid relocation type %d"),
+ input_bfd, r_type);
+ ok = FALSE;
+ continue;
+ }
+
+ r = _bfd_final_link_relocate (howto, input_bfd, input_section,
+ contents, rel->r_offset,
+ relocation, rel->r_addend);
+
+ done_reloc:
+ if (r == bfd_reloc_ok
+ && howto->complain_on_overflow == complain_overflow_bitfield)
+ {
+ /* Generic overflow handling accepts cases the ABI says
+ should be rejected for R_C6000_ABS16 and
+ R_C6000_ABS8. */
+ bfd_vma value = (relocation + rel->r_addend) & 0xffffffff;
+ bfd_vma sbit = 1 << (howto->bitsize - 1);
+ bfd_vma sbits = (-(bfd_vma) sbit) & 0xffffffff;
+ bfd_vma value_sbits = value & sbits;
+
+ if (value_sbits != 0
+ && value_sbits != sbit
+ && value_sbits != sbits)
+ r = bfd_reloc_overflow;
+ }
+
+ if (r != bfd_reloc_ok)
+ {
+ const char *name;
+ const char *error_message;
+
+ 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);
+ }
+
+ switch (r)
+ {
+ case bfd_reloc_overflow:
+ /* If the overflowing reloc was to an undefined symbol,
+ we have already printed one error message and there
+ is no point complaining again. */
+ if ((! h ||
+ h->root.type != bfd_link_hash_undefined)
+ && (!((*info->callbacks->reloc_overflow)
+ (info, (h ? &h->root : NULL), 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, TRUE)))
+ return FALSE;
+ break;
+
+ case bfd_reloc_outofrange:
+ error_message = _("out of range");
+ goto common_error;
+
+ case bfd_reloc_notsupported:
+ error_message = _("unsupported relocation");
+ goto common_error;
+
+ case bfd_reloc_dangerous:
+ error_message = _("dangerous relocation");
+ goto common_error;
+
+ default:
+ error_message = _("unknown error");
+ /* Fall through. */
+
+ common_error:
+ BFD_ASSERT (error_message != NULL);
+ if (!((*info->callbacks->reloc_dangerous)
+ (info, error_message, input_bfd, input_section,
+ rel->r_offset)))
+ return FALSE;
+ break;
+ }
+ }
+ }
+
+ return ok;
+}
+
+
+/* Look through the relocs for a section during the first phase, and
+ calculate needed space in the global offset table, procedure linkage
+ table, and dynamic reloc sections. */
+
+static bfd_boolean
+elf32_tic6x_check_relocs (bfd *abfd, struct bfd_link_info *info,
+ asection *sec, const Elf_Internal_Rela *relocs)
+{
+ struct elf32_tic6x_link_hash_table *htab;
+ 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;
+
+ if (info->relocatable)
+ return TRUE;
+
+ htab = elf32_tic6x_hash_table (info);
+ symtab_hdr = &elf_symtab_hdr (abfd);
+ sym_hashes = elf_sym_hashes (abfd);
+
+ /* Create dynamic sections for relocatable executables so that we can
+ copy relocations. */
+ if ((info->shared || elf32_tic6x_using_dsbt (abfd))
+ && ! htab->elf.dynamic_sections_created)
+ {
+ if (! _bfd_elf_link_create_dynamic_sections (abfd, info))
+ return FALSE;
+ }
+
+ sreloc = NULL;
+
+ rel_end = relocs + sec->reloc_count;
+ for (rel = relocs; rel < rel_end; rel++)
+ {
+ unsigned int r_type;
+ unsigned long r_symndx;
+ struct elf_link_hash_entry *h;
+ Elf_Internal_Sym *isym;
+
+ r_symndx = ELF32_R_SYM (rel->r_info);
+ r_type = ELF32_R_TYPE (rel->r_info);
+
+ if (r_symndx >= NUM_SHDR_ENTRIES (symtab_hdr))
+ {
+ (*_bfd_error_handler) (_("%B: bad symbol index: %d"),
+ abfd,
+ r_symndx);
+ return FALSE;
+ }
+
+ if (r_symndx < symtab_hdr->sh_info)
+ {
+ /* A local symbol. */
+ isym = bfd_sym_from_r_symndx (&htab->sym_cache,
+ abfd, r_symndx);
+ if (isym == NULL)
+ return FALSE;
+ h = NULL;
+ }
+ else
+ {
+ isym = NULL;
+ 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;
+
+ /* PR15323, ref flags aren't set for references in the same
+ object. */
+ h->root.non_ir_ref = 1;
+ }
+
+ switch (r_type)
+ {
+ case R_C6000_PCR_S21:
+ case R_C6000_PREL31:
+ /* 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->needs_plt = 1;
+ h->plt.refcount += 1;
+ break;
+
+ case R_C6000_SBR_GOT_U15_W:
+ case R_C6000_SBR_GOT_L16_W:
+ case R_C6000_SBR_GOT_H16_W:
+ case R_C6000_EHTYPE:
+ /* This symbol requires a global offset table entry. */
+ if (h != NULL)
+ {
+ h->got.refcount += 1;
+ }
+ else
+ {
+ bfd_signed_vma *local_got_refcounts;
+
+ /* This is a global offset table entry for a local symbol. */
+ local_got_refcounts = elf_local_got_refcounts (abfd);
+ if (local_got_refcounts == NULL)
+ {
+ bfd_size_type size;
+
+ size = symtab_hdr->sh_info;
+ size *= (sizeof (bfd_signed_vma)
+ + sizeof (bfd_vma) + sizeof(char));
+ local_got_refcounts = bfd_zalloc (abfd, size);
+ if (local_got_refcounts == NULL)
+ return FALSE;
+ elf_local_got_refcounts (abfd) = local_got_refcounts;
+ }
+ local_got_refcounts[r_symndx] += 1;
+ }
+
+ if (htab->elf.sgot == NULL)
+ {
+ if (htab->elf.dynobj == NULL)
+ htab->elf.dynobj = abfd;
+ if (!_bfd_elf_create_got_section (htab->elf.dynobj, info))
+ return FALSE;
+ }
+ break;
+
+ case R_C6000_DSBT_INDEX:
+ /* We'd like to check for nonzero dsbt_index here, but it's
+ set up only after check_relocs is called. Instead, we
+ store the number of R_C6000_DSBT_INDEX relocs in the
+ pc_count field, and potentially discard the extra space
+ in elf32_tic6x_allocate_dynrelocs. */
+ if (!info->shared)
+ break;
+
+ /* fall through */
+ case R_C6000_ABS32:
+ case R_C6000_ABS16:
+ case R_C6000_ABS8:
+ case R_C6000_ABS_S16:
+ case R_C6000_ABS_L16:
+ case R_C6000_ABS_H16:
+ /* 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). In case of a weak definition,
+ DEF_REGULAR may be cleared later by a strong definition in
+ a shared library. We account for that possibility below by
+ storing information in the relocs_copied field of the hash
+ table entry. A similar situation occurs when creating
+ shared libraries and symbol visibility changes render the
+ symbol local.
+
+ If on the other hand, we are creating an executable, we
+ may need to keep relocations for symbols satisfied by a
+ dynamic library if we manage to avoid copy relocs for the
+ symbol. */
+ if ((info->shared || elf32_tic6x_using_dsbt (abfd))
+ && (sec->flags & SEC_ALLOC) != 0)
+ {
+ struct elf_dyn_relocs *p;
+ struct elf_dyn_relocs **head;
+
+ /* We must copy these reloc types into the output file.
+ Create a reloc section in dynobj and make room for
+ this reloc. */
+ if (sreloc == NULL)
+ {
+ if (htab->elf.dynobj == NULL)
+ htab->elf.dynobj = abfd;
+
+ sreloc = _bfd_elf_make_dynamic_reloc_section
+ (sec, htab->elf.dynobj, 2, abfd, /*rela? */ TRUE);
+
+ if (sreloc == NULL)
+ return FALSE;
+ }
+
+ /* If this is a global symbol, we count the number of
+ relocations we need for this symbol. */
+ if (h != NULL)
+ {
+ head = &((struct elf32_tic6x_link_hash_entry *) h)->dyn_relocs;
+ }
+ else
+ {
+ /* Track dynamic relocs needed for local syms too.
+ We really need local syms available to do this
+ easily. Oh well. */
+ void **vpp;
+ asection *s;
+
+ s = bfd_section_from_elf_index (abfd, isym->st_shndx);
+ if (s == NULL)
+ s = sec;
+
+ vpp = &elf_section_data (s)->local_dynrel;
+ head = (struct elf_dyn_relocs **)vpp;
+ }
+
+ p = *head;
+ if (p == NULL || p->sec != sec)
+ {
+ bfd_size_type amt = sizeof *p;
+ p = bfd_alloc (htab->elf.dynobj, amt);
+ if (p == NULL)
+ return FALSE;
+ p->next = *head;
+ *head = p;
+ p->sec = sec;
+ p->count = 0;
+ p->pc_count = 0;
+ }
+
+ p->count += 1;
+ if (r_type == R_C6000_DSBT_INDEX)
+ p->pc_count += 1;
+ }
+ break;
+
+ case R_C6000_SBR_U15_B:
+ case R_C6000_SBR_U15_H:
+ case R_C6000_SBR_U15_W:
+ case R_C6000_SBR_S16:
+ case R_C6000_SBR_L16_B:
+ case R_C6000_SBR_L16_H:
+ case R_C6000_SBR_L16_W:
+ case R_C6000_SBR_H16_B:
+ case R_C6000_SBR_H16_H:
+ case R_C6000_SBR_H16_W:
+ if (h != NULL && info->executable)
+ {
+ /* For B14-relative addresses, we might need a copy
+ reloc. */
+ h->non_got_ref = 1;
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ return TRUE;
+}
+
+static bfd_boolean
+elf32_tic6x_add_symbol_hook (bfd *abfd,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ Elf_Internal_Sym *sym,
+ const char **namep ATTRIBUTE_UNUSED,
+ flagword *flagsp ATTRIBUTE_UNUSED,
+ asection **secp,
+ bfd_vma *valp)
+{
+ switch (sym->st_shndx)
+ {
+ case SHN_TIC6X_SCOMMON:
+ *secp = bfd_make_section_old_way (abfd, ".scommon");
+ (*secp)->flags |= SEC_IS_COMMON;
+ *valp = sym->st_size;
+ (void) bfd_set_section_alignment (abfd, *secp, bfd_log2 (sym->st_value));
+ break;
+ }
+
+ return TRUE;
+}
+
+static void
+elf32_tic6x_symbol_processing (bfd *abfd ATTRIBUTE_UNUSED, asymbol *asym)
+{
+ elf_symbol_type *elfsym;
+
+ elfsym = (elf_symbol_type *) asym;
+ switch (elfsym->internal_elf_sym.st_shndx)
+ {
+ case SHN_TIC6X_SCOMMON:
+ if (tic6x_elf_scom_section.name == NULL)
+ {
+ /* Initialize the small common section. */
+ tic6x_elf_scom_section.name = ".scommon";
+ tic6x_elf_scom_section.flags = SEC_IS_COMMON;
+ tic6x_elf_scom_section.output_section = &tic6x_elf_scom_section;
+ tic6x_elf_scom_section.symbol = &tic6x_elf_scom_symbol;
+ tic6x_elf_scom_section.symbol_ptr_ptr = &tic6x_elf_scom_symbol_ptr;
+ tic6x_elf_scom_symbol.name = ".scommon";
+ tic6x_elf_scom_symbol.flags = BSF_SECTION_SYM;
+ tic6x_elf_scom_symbol.section = &tic6x_elf_scom_section;
+ tic6x_elf_scom_symbol_ptr = &tic6x_elf_scom_symbol;
+ }
+ asym->section = &tic6x_elf_scom_section;
+ asym->value = elfsym->internal_elf_sym.st_size;
+ break;
+ }
+}
+
+static int
+elf32_tic6x_link_output_symbol_hook (struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ const char *name ATTRIBUTE_UNUSED,
+ Elf_Internal_Sym *sym,
+ asection *input_sec,
+ struct elf_link_hash_entry *h ATTRIBUTE_UNUSED)
+{
+ /* 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_TIC6X_SCOMMON;
+
+ return 1;
+}
+
+static bfd_boolean
+elf32_tic6x_section_from_bfd_section (bfd *abfd ATTRIBUTE_UNUSED,
+ asection *sec,
+ int *retval)
+{
+ if (strcmp (bfd_get_section_name (abfd, sec), ".scommon") == 0)
+ {
+ *retval = SHN_TIC6X_SCOMMON;
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/* Allocate space in .plt, .got and associated reloc sections for
+ dynamic relocs. */
+
+static bfd_boolean
+elf32_tic6x_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
+{
+ struct bfd_link_info *info;
+ struct elf32_tic6x_link_hash_table *htab;
+ struct elf32_tic6x_link_hash_entry *eh;
+ struct elf_dyn_relocs *p;
+
+ if (h->root.type == bfd_link_hash_indirect)
+ return TRUE;
+
+ eh = (struct elf32_tic6x_link_hash_entry *) h;
+ info = (struct bfd_link_info *) inf;
+ htab = elf32_tic6x_hash_table (info);
+
+ if (htab->elf.dynamic_sections_created && h->plt.refcount > 0)
+ {
+ /* Make sure this symbol is output as a dynamic symbol.
+ Undefined weak syms won't yet be marked as dynamic. */
+ if (h->dynindx == -1 && !h->forced_local)
+ {
+ if (! bfd_elf_link_record_dynamic_symbol (info, h))
+ return FALSE;
+ }
+
+ if (info->shared
+ || WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, 0, h))
+ {
+ asection *s = htab->elf.splt;
+
+ /* If this is the first .plt entry, make room for the special
+ first entry. */
+ if (s->size == 0)
+ s->size += PLT_ENTRY_SIZE;
+
+ h->plt.offset = s->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->def_regular)
+ {
+ h->root.u.def.section = s;
+ h->root.u.def.value = h->plt.offset;
+ }
+
+ /* Make room for this entry. */
+ s->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. */
+ htab->elf.sgotplt->size += 4;
+ /* We also need to make an entry in the .rel.plt section. */
+ htab->elf.srelplt->size += sizeof (Elf32_External_Rela);
+ }
+ else
+ {
+ h->plt.offset = (bfd_vma) -1;
+ h->needs_plt = 0;
+ }
+ }
+ else
+ {
+ h->plt.offset = (bfd_vma) -1;
+ h->needs_plt = 0;
+ }
+
+ if (h->got.refcount > 0)
+ {
+ asection *s;
+
+ /* Make sure this symbol is output as a dynamic symbol.
+ Undefined weak syms won't yet be marked as dynamic. */
+ if (h->dynindx == -1
+ && !h->forced_local)
+ {
+ if (! bfd_elf_link_record_dynamic_symbol (info, h))
+ return FALSE;
+ }
+
+ s = htab->elf.sgot;
+ h->got.offset = s->size;
+ s->size += 4;
+
+ if (!(ELF_ST_VISIBILITY (h->other)
+ && h->root.type == bfd_link_hash_undefweak))
+ htab->elf.srelgot->size += sizeof (Elf32_External_Rela);
+ }
+ else
+ h->got.offset = (bfd_vma) -1;
+
+ if (eh->dyn_relocs == NULL)
+ return TRUE;
+
+ /* Discard relocs on undefined weak syms with non-default
+ visibility. */
+ if (info->shared || elf32_tic6x_using_dsbt (htab->obfd))
+ {
+ /* We use the pc_count field to hold the number of
+ R_C6000_DSBT_INDEX relocs. */
+ if (htab->params.dsbt_index != 0)
+ {
+ struct elf_dyn_relocs **pp;
+
+ for (pp = &eh->dyn_relocs; (p = *pp) != NULL; )
+ {
+ p->count -= p->pc_count;
+ p->pc_count = 0;
+ if (p->count == 0)
+ *pp = p->next;
+ else
+ pp = &p->next;
+ }
+ }
+
+ if (eh->dyn_relocs != NULL
+ && h->root.type == bfd_link_hash_undefweak)
+ {
+ if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
+ eh->dyn_relocs = NULL;
+
+ /* Make sure undefined weak symbols are output as a dynamic
+ symbol in PIEs. */
+ else if (h->dynindx == -1
+ && !h->forced_local)
+ {
+ if (! bfd_elf_link_record_dynamic_symbol (info, h))
+ return FALSE;
+ }
+ }
+ }
+
+ /* Finally, allocate space. */
+ for (p = eh->dyn_relocs; p != NULL; p = p->next)
+ {
+ asection *sreloc;
+
+ sreloc = elf_section_data (p->sec)->sreloc;
+
+ BFD_ASSERT (sreloc != NULL);
+ sreloc->size += p->count * sizeof (Elf32_External_Rela);
+ }
+
+ return TRUE;
+}
+
+/* Find any dynamic relocs that apply to read-only sections. */
+
+static bfd_boolean
+elf32_tic6x_readonly_dynrelocs (struct elf_link_hash_entry *h, void *inf)
+{
+ struct elf32_tic6x_link_hash_entry *eh;
+ struct elf_dyn_relocs *p;
+
+ eh = (struct elf32_tic6x_link_hash_entry *) h;
+ for (p = eh->dyn_relocs; p != NULL; p = p->next)
+ {
+ asection *s = p->sec->output_section;
+
+ if (s != NULL && (s->flags & SEC_READONLY) != 0)
+ {
+ struct bfd_link_info *info = (struct bfd_link_info *) inf;
+
+ info->flags |= DF_TEXTREL;
+
+ /* Not an error, just cut short the traversal. */
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+/* Set the sizes of the dynamic sections. */
+
+static bfd_boolean
+elf32_tic6x_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
+{
+ struct elf32_tic6x_link_hash_table *htab;
+ bfd *dynobj;
+ asection *s;
+ bfd_boolean relocs;
+ bfd *ibfd;
+
+ htab = elf32_tic6x_hash_table (info);
+ dynobj = htab->elf.dynobj;
+ if (dynobj == NULL)
+ abort ();
+
+ if (htab->elf.dynamic_sections_created)
+ {
+ /* Set the contents of the .interp section to the interpreter. */
+ if (info->executable)
+ {
+ s = bfd_get_linker_section (dynobj, ".interp");
+ if (s == NULL)
+ abort ();
+ s->size = sizeof ELF_DYNAMIC_INTERPRETER;
+ s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
+ }
+ }
+
+ /* Set up .got offsets for local syms, and space for local dynamic
+ relocs. */
+ for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next)
+ {
+ bfd_signed_vma *local_got;
+ bfd_signed_vma *end_local_got;
+ bfd_size_type locsymcount;
+ Elf_Internal_Shdr *symtab_hdr;
+ asection *srel;
+
+ for (s = ibfd->sections; s != NULL; s = s->next)
+ {
+ struct elf_dyn_relocs *p;
+
+ for (p = ((struct elf_dyn_relocs *)
+ elf_section_data (s)->local_dynrel);
+ p != NULL;
+ p = p->next)
+ {
+ if (!bfd_is_abs_section (p->sec)
+ && bfd_is_abs_section (p->sec->output_section))
+ {
+ /* Input section has been discarded, either because
+ it is a copy of a linkonce section or due to
+ linker script /DISCARD/, so we'll be discarding
+ the relocs too. */
+ }
+ else if (p->count != 0)
+ {
+ srel = elf_section_data (p->sec)->sreloc;
+ srel->size += p->count * sizeof (Elf32_External_Rela);
+ if ((p->sec->output_section->flags & SEC_READONLY) != 0)
+ info->flags |= DF_TEXTREL;
+ }
+ }
+ }
+
+ local_got = elf_local_got_refcounts (ibfd);
+ if (!local_got)
+ continue;
+
+ symtab_hdr = &elf_symtab_hdr (ibfd);
+ locsymcount = symtab_hdr->sh_info;
+ end_local_got = local_got + locsymcount;
+ s = htab->elf.sgot;
+ srel = htab->elf.srelgot;
+ for (; local_got < end_local_got; ++local_got)
+ {
+ if (*local_got > 0)
+ {
+ *local_got = s->size;
+ s->size += 4;
+
+ if (info->shared || elf32_tic6x_using_dsbt (output_bfd))
+ {
+ srel->size += sizeof (Elf32_External_Rela);
+ }
+ }
+ else
+ *local_got = (bfd_vma) -1;
+ }
+ }
+
+ /* Allocate global sym .plt and .got entries, and space for global
+ sym dynamic relocs. */
+ elf_link_hash_traverse (&htab->elf, elf32_tic6x_allocate_dynrelocs, info);
+
+ /* We now have determined the sizes of the various dynamic sections.
+ Allocate memory for them. */
+ relocs = FALSE;
+ for (s = dynobj->sections; s != NULL; s = s->next)
+ {
+ bfd_boolean strip_section = TRUE;
+
+ if ((s->flags & SEC_LINKER_CREATED) == 0)
+ continue;
+
+ if (s == htab->dsbt)
+ s->size = 4 * htab->params.dsbt_size;
+ else if (s == htab->elf.splt
+ || s == htab->elf.sgot
+ || s == htab->elf.sgotplt
+ || s == htab->sdynbss)
+ {
+ /* Strip this section if we don't need it; see the
+ comment below. */
+ /* We'd like to strip these sections if they aren't needed, but if
+ we've exported dynamic symbols from them we must leave them.
+ It's too late to tell BFD to get rid of the symbols. */
+
+ if (htab->elf.hplt != NULL)
+ strip_section = FALSE;
+
+ /* Round up the size of the PLT section to a multiple of 32. */
+ if (s == htab->elf.splt && s->size > 0)
+ s->size = (s->size + 31) & ~(bfd_vma)31;
+ }
+ else if (CONST_STRNEQ (bfd_get_section_name (dynobj, s), ".rela"))
+ {
+ if (s->size != 0
+ && s != htab->elf.srelplt)
+ relocs = 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
+ {
+ /* It's not one of our sections, so don't allocate space. */
+ continue;
+ }
+
+ if (s->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. */
+ if (strip_section)
+ s->flags |= SEC_EXCLUDE;
+ continue;
+ }
+
+ if ((s->flags & SEC_HAS_CONTENTS) == 0)
+ continue;
+
+ /* Allocate memory for the section contents. We use bfd_zalloc
+ here in case unused entries are not reclaimed before the
+ section's contents are written out. This should not happen,
+ but this way if it does, we get a R_C6000_NONE reloc instead
+ of garbage. */
+ s->contents = bfd_zalloc (dynobj, s->size);
+ if (s->contents == NULL)
+ return FALSE;
+ }
+
+ if (htab->elf.dynamic_sections_created)
+ {
+ /* Add some entries to the .dynamic section. We fill in the
+ values later, in elf32_tic6x_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. */
+#define add_dynamic_entry(TAG, VAL) \
+ _bfd_elf_add_dynamic_entry (info, TAG, VAL)
+
+ if (info->executable)
+ {
+ if (!add_dynamic_entry (DT_DEBUG, 0))
+ return FALSE;
+ }
+
+ if (!add_dynamic_entry (DT_C6000_DSBT_BASE, 0)
+ || !add_dynamic_entry (DT_C6000_DSBT_SIZE, htab->params.dsbt_size)
+ || !add_dynamic_entry (DT_C6000_DSBT_INDEX,
+ htab->params.dsbt_index))
+ return FALSE;
+
+ if (htab->elf.splt->size != 0)
+ {
+ if (!add_dynamic_entry (DT_PLTGOT, 0)
+ || !add_dynamic_entry (DT_PLTRELSZ, 0)
+ || !add_dynamic_entry (DT_PLTREL, DT_RELA)
+ || !add_dynamic_entry (DT_JMPREL, 0))
+ return FALSE;
+ }
+
+ if (relocs)
+ {
+ if (!add_dynamic_entry (DT_RELA, 0)
+ || !add_dynamic_entry (DT_RELASZ, 0)
+ || !add_dynamic_entry (DT_RELAENT, sizeof (Elf32_External_Rela)))
+ return FALSE;
+
+ /* If any dynamic relocs apply to a read-only section,
+ then we need a DT_TEXTREL entry. */
+ if ((info->flags & DF_TEXTREL) == 0)
+ elf_link_hash_traverse (&htab->elf,
+ elf32_tic6x_readonly_dynrelocs, info);
+
+ if ((info->flags & DF_TEXTREL) != 0)
+ {
+ if (!add_dynamic_entry (DT_TEXTREL, 0))
+ return FALSE;
+ }
+ }
+ }
+#undef add_dynamic_entry
+
+ return TRUE;
+}
+
+/* This function is called after all the input files have been read,
+ and the input sections have been assigned to output sections. */
+
+static bfd_boolean
+elf32_tic6x_always_size_sections (bfd *output_bfd, struct bfd_link_info *info)
+{
+ if (elf32_tic6x_using_dsbt (output_bfd) && !info->relocatable
+ && !bfd_elf_stack_segment_size (output_bfd, info,
+ "__stacksize", DEFAULT_STACK_SIZE))
+ return FALSE;
+
+ return TRUE;
+}
+
+static bfd_boolean
+elf32_tic6x_finish_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
+ struct bfd_link_info *info)
+{
+ struct elf32_tic6x_link_hash_table *htab;
+ bfd *dynobj;
+ asection *sdyn;
+
+ htab = elf32_tic6x_hash_table (info);
+ dynobj = htab->elf.dynobj;
+ sdyn = bfd_get_linker_section (dynobj, ".dynamic");
+
+ if (elf_hash_table (info)->dynamic_sections_created)
+ {
+ Elf32_External_Dyn * dyncon;
+ Elf32_External_Dyn * dynconend;
+
+ BFD_ASSERT (sdyn != NULL);
+
+ dyncon = (Elf32_External_Dyn *) sdyn->contents;
+ dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->size);
+
+ for (; dyncon < dynconend; dyncon++)
+ {
+ Elf_Internal_Dyn dyn;
+ asection *s;
+
+ bfd_elf32_swap_dyn_in (dynobj, dyncon, &dyn);
+
+ switch (dyn.d_tag)
+ {
+ default:
+ break;
+
+ case DT_C6000_DSBT_BASE:
+ s = htab->dsbt;
+ dyn.d_un.d_ptr = (s->output_section->vma + s->output_offset);
+ break;
+
+ case DT_PLTGOT:
+ s = htab->elf.sgotplt;
+ dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
+ break;
+
+ case DT_JMPREL:
+ s = htab->elf.srelplt;
+ dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
+ break;
+
+ case DT_PLTRELSZ:
+ s = htab->elf.srelplt;
+ dyn.d_un.d_val = s->size;
+ break;
+ }
+ bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
+ }
+
+ /* Fill in the first entry in the procedure linkage table. */
+ if (htab->elf.splt && htab->elf.splt->size > 0)
+ {
+ bfd_vma got_offs = (htab->elf.sgotplt->output_section->vma
+ + htab->elf.sgotplt->output_offset
+ - htab->dsbt->output_section->vma
+ - htab->dsbt->output_offset) / 4;
+
+ /* ldw .D2T2 *+b14[$GOT(0)],b2 */
+ bfd_put_32 (output_bfd, got_offs << 8 | 0x0100006e,
+ htab->elf.splt->contents);
+ /* ldw .D2T2 *+b14[$GOT(4)],b1 */
+ bfd_put_32 (output_bfd, (got_offs + 1) << 8 | 0x0080006e,
+ htab->elf.splt->contents + 4);
+ /* nop 3 */
+ bfd_put_32 (output_bfd, 0x00004000,
+ htab->elf.splt->contents + 8);
+ /* b .s2 b2 */
+ bfd_put_32 (output_bfd, 0x00080362,
+ htab->elf.splt->contents + 12);
+ /* nop 5 */
+ bfd_put_32 (output_bfd, 0x00008000,
+ htab->elf.splt->contents + 16);
+
+ elf_section_data (htab->elf.splt->output_section)
+ ->this_hdr.sh_entsize = PLT_ENTRY_SIZE;
+ }
+ }
+
+ return TRUE;
+}
+
+/* Return address for Ith PLT stub in section PLT, for relocation REL
+ or (bfd_vma) -1 if it should not be included. */
+
+static bfd_vma
+elf32_tic6x_plt_sym_val (bfd_vma i, const asection *plt,
+ const arelent *rel ATTRIBUTE_UNUSED)
+{
+ return plt->vma + (i + 1) * PLT_ENTRY_SIZE;
+}
+
+static int
+elf32_tic6x_obj_attrs_arg_type (int tag)
+{
+ if (tag == Tag_ABI_compatibility)
+ return ATTR_TYPE_FLAG_INT_VAL | ATTR_TYPE_FLAG_STR_VAL;
+ else if (tag & 1)
+ return ATTR_TYPE_FLAG_STR_VAL;
+ else
+ return ATTR_TYPE_FLAG_INT_VAL;
+}
+
+static int
+elf32_tic6x_obj_attrs_order (int num)
+{
+ if (num == LEAST_KNOWN_OBJ_ATTRIBUTE)
+ return Tag_ABI_conformance;
+ if ((num - 1) < Tag_ABI_conformance)
+ return num - 1;
+ return num;
+}
+
+static bfd_boolean
+elf32_tic6x_obj_attrs_handle_unknown (bfd *abfd, int tag)
+{
+ if ((tag & 127) < 64)
+ {
+ _bfd_error_handler
+ (_("%B: error: unknown mandatory EABI object attribute %d"),
+ abfd, tag);
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+ else
+ {
+ _bfd_error_handler
+ (_("%B: warning: unknown EABI object attribute %d"),
+ abfd, tag);
+ return TRUE;
+ }
+}
+
+/* Merge the Tag_ISA attribute values ARCH1 and ARCH2
+ and return the merged value. At present, all merges succeed, so no
+ return value for errors is defined. */
+
+int
+elf32_tic6x_merge_arch_attributes (int arch1, int arch2)
+{
+ int min_arch, max_arch;
+
+ min_arch = (arch1 < arch2 ? arch1 : arch2);
+ max_arch = (arch1 > arch2 ? arch1 : arch2);
+
+ /* In most cases, the numerically greatest value is the correct
+ merged value, but merging C64 and C67 results in C674X. */
+ if ((min_arch == C6XABI_Tag_ISA_C67X
+ || min_arch == C6XABI_Tag_ISA_C67XP)
+ && (max_arch == C6XABI_Tag_ISA_C64X
+ || max_arch == C6XABI_Tag_ISA_C64XP))
+ return C6XABI_Tag_ISA_C674X;
+
+ return max_arch;
+}
+
+/* Convert a Tag_ABI_array_object_alignment or
+ Tag_ABI_array_object_align_expected tag value TAG to a
+ corresponding alignment value; return the alignment, or -1 for an
+ unknown tag value. */
+
+static int
+elf32_tic6x_tag_to_array_alignment (int tag)
+{
+ switch (tag)
+ {
+ case 0:
+ return 8;
+
+ case 1:
+ return 4;
+
+ case 2:
+ return 16;
+
+ default:
+ return -1;
+ }
+}
+
+/* Convert a Tag_ABI_array_object_alignment or
+ Tag_ABI_array_object_align_expected alignment ALIGN to a
+ corresponding tag value; return the tag value. */
+
+static int
+elf32_tic6x_array_alignment_to_tag (int align)
+{
+ switch (align)
+ {
+ case 8:
+ return 0;
+
+ case 4:
+ return 1;
+
+ case 16:
+ return 2;
+
+ default:
+ abort ();
+ }
+}
+
+/* Merge attributes from IBFD and OBFD, returning TRUE if the merge
+ succeeded, FALSE otherwise. */
+
+static bfd_boolean
+elf32_tic6x_merge_attributes (bfd *ibfd, bfd *obfd)
+{
+ bfd_boolean result = TRUE;
+ obj_attribute *in_attr;
+ obj_attribute *out_attr;
+ int i;
+ int array_align_in, array_align_out, array_expect_in, array_expect_out;
+
+ if (!elf_known_obj_attributes_proc (obfd)[0].i)
+ {
+ /* This is the first object. Copy the attributes. */
+ _bfd_elf_copy_obj_attributes (ibfd, obfd);
+
+ out_attr = elf_known_obj_attributes_proc (obfd);
+
+ /* Use the Tag_null value to indicate the attributes have been
+ initialized. */
+ out_attr[0].i = 1;
+
+ return TRUE;
+ }
+
+ in_attr = elf_known_obj_attributes_proc (ibfd);
+ out_attr = elf_known_obj_attributes_proc (obfd);
+
+ /* No specification yet for handling of unknown attributes, so just
+ ignore them and handle known ones. */
+
+ if (out_attr[Tag_ABI_stack_align_preserved].i
+ < in_attr[Tag_ABI_stack_align_needed].i)
+ {
+ _bfd_error_handler
+ (_("error: %B requires more stack alignment than %B preserves"),
+ ibfd, obfd);
+ result = FALSE;
+ }
+ if (in_attr[Tag_ABI_stack_align_preserved].i
+ < out_attr[Tag_ABI_stack_align_needed].i)
+ {
+ _bfd_error_handler
+ (_("error: %B requires more stack alignment than %B preserves"),
+ obfd, ibfd);
+ result = FALSE;
+ }
+
+ array_align_in = elf32_tic6x_tag_to_array_alignment
+ (in_attr[Tag_ABI_array_object_alignment].i);
+ if (array_align_in == -1)
+ {
+ _bfd_error_handler
+ (_("error: unknown Tag_ABI_array_object_alignment value in %B"),
+ ibfd);
+ result = FALSE;
+ }
+ array_align_out = elf32_tic6x_tag_to_array_alignment
+ (out_attr[Tag_ABI_array_object_alignment].i);
+ if (array_align_out == -1)
+ {
+ _bfd_error_handler
+ (_("error: unknown Tag_ABI_array_object_alignment value in %B"),
+ obfd);
+ result = FALSE;
+ }
+ array_expect_in = elf32_tic6x_tag_to_array_alignment
+ (in_attr[Tag_ABI_array_object_align_expected].i);
+ if (array_expect_in == -1)
+ {
+ _bfd_error_handler
+ (_("error: unknown Tag_ABI_array_object_align_expected value in %B"),
+ ibfd);
+ result = FALSE;
+ }
+ array_expect_out = elf32_tic6x_tag_to_array_alignment
+ (out_attr[Tag_ABI_array_object_align_expected].i);
+ if (array_expect_out == -1)
+ {
+ _bfd_error_handler
+ (_("error: unknown Tag_ABI_array_object_align_expected value in %B"),
+ obfd);
+ result = FALSE;
+ }
+
+ if (array_align_out < array_expect_in)
+ {
+ _bfd_error_handler
+ (_("error: %B requires more array alignment than %B preserves"),
+ ibfd, obfd);
+ result = FALSE;
+ }
+ if (array_align_in < array_expect_out)
+ {
+ _bfd_error_handler
+ (_("error: %B requires more array alignment than %B preserves"),
+ obfd, ibfd);
+ result = FALSE;
+ }
+
+ for (i = LEAST_KNOWN_OBJ_ATTRIBUTE; i < NUM_KNOWN_OBJ_ATTRIBUTES; i++)
+ {
+ switch (i)
+ {
+ case Tag_ISA:
+ out_attr[i].i = elf32_tic6x_merge_arch_attributes (in_attr[i].i,
+ out_attr[i].i);
+ break;
+
+ case Tag_ABI_wchar_t:
+ if (out_attr[i].i == 0)
+ out_attr[i].i = in_attr[i].i;
+ if (out_attr[i].i != 0
+ && in_attr[i].i != 0
+ && out_attr[i].i != in_attr[i].i)
+ {
+ _bfd_error_handler
+ (_("warning: %B and %B differ in wchar_t size"), obfd, ibfd);
+ }
+ break;
+
+ case Tag_ABI_stack_align_needed:
+ if (out_attr[i].i < in_attr[i].i)
+ out_attr[i].i = in_attr[i].i;
+ break;
+
+ case Tag_ABI_stack_align_preserved:
+ if (out_attr[i].i > in_attr[i].i)
+ out_attr[i].i = in_attr[i].i;
+ break;
+
+ case Tag_ABI_DSBT:
+ if (out_attr[i].i != in_attr[i].i)
+ {
+ _bfd_error_handler
+ (_("warning: %B and %B differ in whether code is "
+ "compiled for DSBT"),
+ obfd, ibfd);
+ }
+ break;
+
+ case Tag_ABI_PIC:
+ case Tag_ABI_PID:
+ if (out_attr[i].i > in_attr[i].i)
+ out_attr[i].i = in_attr[i].i;
+ break;
+
+ case Tag_ABI_array_object_alignment:
+ if (array_align_out != -1
+ && array_align_in != -1
+ && array_align_out > array_align_in)
+ out_attr[i].i
+ = elf32_tic6x_array_alignment_to_tag (array_align_in);
+ break;
+
+ case Tag_ABI_array_object_align_expected:
+ if (array_expect_out != -1
+ && array_expect_in != -1
+ && array_expect_out < array_expect_in)
+ out_attr[i].i
+ = elf32_tic6x_array_alignment_to_tag (array_expect_in);
+ break;
+
+ case Tag_ABI_conformance:
+ /* Merging for this attribute is not specified. As on ARM,
+ treat a missing attribute as no claim to conform and only
+ merge identical values. */
+ if (out_attr[i].s == NULL
+ || in_attr[i].s == NULL
+ || strcmp (out_attr[i].s,
+ in_attr[i].s) != 0)
+ out_attr[i].s = NULL;
+ break;
+
+ case Tag_ABI_compatibility:
+ /* Merged in _bfd_elf_merge_object_attributes. */
+ break;
+
+ default:
+ result
+ = result && _bfd_elf_merge_unknown_attribute_low (ibfd, obfd, i);
+ break;
+ }
+
+ if (in_attr[i].type && !out_attr[i].type)
+ out_attr[i].type = in_attr[i].type;
+ }
+
+ /* Merge Tag_ABI_compatibility attributes and any common GNU ones. */
+ if (!_bfd_elf_merge_object_attributes (ibfd, obfd))
+ return FALSE;
+
+ result &= _bfd_elf_merge_unknown_attribute_list (ibfd, obfd);
+
+ return result;
+}
+
+static bfd_boolean
+elf32_tic6x_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
+{
+ if (!_bfd_generic_verify_endian_match (ibfd, obfd))
+ return FALSE;
+
+ if (! is_tic6x_elf (ibfd) || ! is_tic6x_elf (obfd))
+ return TRUE;
+
+ if (!elf32_tic6x_merge_attributes (ibfd, obfd))
+ return FALSE;
+
+ return TRUE;
+}
+
+/* Add a new unwind edit to the list described by HEAD, TAIL. If TINDEX is zero,
+ adds the edit to the start of the list. (The list must be built in order of
+ ascending TINDEX: the function's callers are primarily responsible for
+ maintaining that condition). */
+
+static void
+elf32_tic6x_add_unwind_table_edit (tic6x_unwind_table_edit **head,
+ tic6x_unwind_table_edit **tail,
+ tic6x_unwind_edit_type type,
+ asection *linked_section,
+ unsigned int tindex)
+{
+ tic6x_unwind_table_edit *new_edit = (tic6x_unwind_table_edit *)
+ xmalloc (sizeof (tic6x_unwind_table_edit));
+
+ new_edit->type = type;
+ new_edit->linked_section = linked_section;
+ new_edit->index = tindex;
+
+ if (tindex > 0)
+ {
+ new_edit->next = NULL;
+
+ if (*tail)
+ (*tail)->next = new_edit;
+
+ (*tail) = new_edit;
+
+ if (!*head)
+ (*head) = new_edit;
+ }
+ else
+ {
+ new_edit->next = *head;
+
+ if (!*tail)
+ *tail = new_edit;
+
+ *head = new_edit;
+ }
+}
+
+static _tic6x_elf_section_data *
+get_tic6x_elf_section_data (asection * sec)
+{
+ if (sec && sec->owner && is_tic6x_elf (sec->owner))
+ return elf32_tic6x_section_data (sec);
+ else
+ return NULL;
+}
+
+
+/* Increase the size of EXIDX_SEC by ADJUST bytes. ADJUST must be negative. */
+static void
+elf32_tic6x_adjust_exidx_size (asection *exidx_sec, int adjust)
+{
+ asection *out_sec;
+
+ if (!exidx_sec->rawsize)
+ exidx_sec->rawsize = exidx_sec->size;
+
+ bfd_set_section_size (exidx_sec->owner, exidx_sec, exidx_sec->size + adjust);
+ out_sec = exidx_sec->output_section;
+ /* Adjust size of output section. */
+ bfd_set_section_size (out_sec->owner, out_sec, out_sec->size +adjust);
+}
+
+/* Insert an EXIDX_CANTUNWIND marker at the end of a section. */
+static void
+elf32_tic6x_insert_cantunwind_after (asection *text_sec, asection *exidx_sec)
+{
+ struct _tic6x_elf_section_data *exidx_data;
+
+ exidx_data = get_tic6x_elf_section_data (exidx_sec);
+ elf32_tic6x_add_unwind_table_edit (
+ &exidx_data->u.exidx.unwind_edit_list,
+ &exidx_data->u.exidx.unwind_edit_tail,
+ INSERT_EXIDX_CANTUNWIND_AT_END, text_sec, UINT_MAX);
+
+ elf32_tic6x_adjust_exidx_size (exidx_sec, 8);
+}
+
+/* Scan .cx6abi.exidx tables, and create a list describing edits which
+ should be made to those tables, such that:
+
+ 1. Regions without unwind data are marked with EXIDX_CANTUNWIND entries.
+ 2. Duplicate entries are merged together (EXIDX_CANTUNWIND, or unwind
+ codes which have been inlined into the index).
+
+ If MERGE_EXIDX_ENTRIES is false, duplicate entries are not merged.
+
+ The edits are applied when the tables are written
+ (in elf32_tic6x_write_section).
+*/
+
+bfd_boolean
+elf32_tic6x_fix_exidx_coverage (asection **text_section_order,
+ unsigned int num_text_sections,
+ struct bfd_link_info *info,
+ bfd_boolean merge_exidx_entries)
+{
+ bfd *inp;
+ unsigned int last_second_word = 0, i;
+ asection *last_exidx_sec = NULL;
+ asection *last_text_sec = NULL;
+ int last_unwind_type = -1;
+
+ /* Walk over all EXIDX sections, and create backlinks from the corrsponding
+ text sections. */
+ for (inp = info->input_bfds; inp != NULL; inp = inp->link.next)
+ {
+ asection *sec;
+
+ for (sec = inp->sections; sec != NULL; sec = sec->next)
+ {
+ struct bfd_elf_section_data *elf_sec = elf_section_data (sec);
+ Elf_Internal_Shdr *hdr = &elf_sec->this_hdr;
+
+ if (!hdr || hdr->sh_type != SHT_C6000_UNWIND)
+ continue;
+
+ if (elf_sec->linked_to)
+ {
+ Elf_Internal_Shdr *linked_hdr
+ = &elf_section_data (elf_sec->linked_to)->this_hdr;
+ struct _tic6x_elf_section_data *linked_sec_tic6x_data
+ = get_tic6x_elf_section_data (linked_hdr->bfd_section);
+
+ if (linked_sec_tic6x_data == NULL)
+ continue;
+
+ /* Link this .c6xabi.exidx section back from the
+ text section it describes. */
+ linked_sec_tic6x_data->u.text.tic6x_exidx_sec = sec;
+ }
+ }
+ }
+
+ /* Walk all text sections in order of increasing VMA. Eilminate duplicate
+ index table entries (EXIDX_CANTUNWIND and inlined unwind opcodes),
+ and add EXIDX_CANTUNWIND entries for sections with no unwind table data. */
+
+ for (i = 0; i < num_text_sections; i++)
+ {
+ asection *sec = text_section_order[i];
+ asection *exidx_sec;
+ struct _tic6x_elf_section_data *tic6x_data
+ = get_tic6x_elf_section_data (sec);
+ struct _tic6x_elf_section_data *exidx_data;
+ bfd_byte *contents = NULL;
+ int deleted_exidx_bytes = 0;
+ bfd_vma j;
+ tic6x_unwind_table_edit *unwind_edit_head = NULL;
+ tic6x_unwind_table_edit *unwind_edit_tail = NULL;
+ Elf_Internal_Shdr *hdr;
+ bfd *ibfd;
+
+ if (tic6x_data == NULL)
+ continue;
+
+ exidx_sec = tic6x_data->u.text.tic6x_exidx_sec;
+ if (exidx_sec == NULL)
+ {
+ /* Section has no unwind data. */
+ if (last_unwind_type == 0 || !last_exidx_sec)
+ continue;
+
+ /* Ignore zero sized sections. */
+ if (sec->size == 0)
+ continue;
+
+ elf32_tic6x_insert_cantunwind_after (last_text_sec, last_exidx_sec);
+ last_unwind_type = 0;
+ continue;
+ }
+
+ /* Skip /DISCARD/ sections. */
+ if (bfd_is_abs_section (exidx_sec->output_section))
+ continue;
+
+ hdr = &elf_section_data (exidx_sec)->this_hdr;
+ if (hdr->sh_type != SHT_C6000_UNWIND)
+ continue;
+
+ exidx_data = get_tic6x_elf_section_data (exidx_sec);
+ if (exidx_data == NULL)
+ continue;
+
+ ibfd = exidx_sec->owner;
+
+ if (hdr->contents != NULL)
+ contents = hdr->contents;
+ else if (! bfd_malloc_and_get_section (ibfd, exidx_sec, &contents))
+ /* An error? */
+ continue;
+
+ for (j = 0; j < hdr->sh_size; j += 8)
+ {
+ unsigned int second_word = bfd_get_32 (ibfd, contents + j + 4);
+ int unwind_type;
+ int elide = 0;
+
+ /* An EXIDX_CANTUNWIND entry. */
+ if (second_word == 1)
+ {
+ if (last_unwind_type == 0)
+ elide = 1;
+ unwind_type = 0;
+ }
+ /* Inlined unwinding data. Merge if equal to previous. */
+ else if ((second_word & 0x80000000) != 0)
+ {
+ if (merge_exidx_entries
+ && last_second_word == second_word
+ && last_unwind_type == 1)
+ elide = 1;
+ unwind_type = 1;
+ last_second_word = second_word;
+ }
+ /* Normal table entry. In theory we could merge these too,
+ but duplicate entries are likely to be much less common. */
+ else
+ unwind_type = 2;
+
+ if (elide)
+ {
+ elf32_tic6x_add_unwind_table_edit (&unwind_edit_head,
+ &unwind_edit_tail, DELETE_EXIDX_ENTRY, NULL, j / 8);
+
+ deleted_exidx_bytes += 8;
+ }
+
+ last_unwind_type = unwind_type;
+ }
+
+ /* Free contents if we allocated it ourselves. */
+ if (contents != hdr->contents)
+ free (contents);
+
+ /* Record edits to be applied later (in elf32_tic6x_write_section). */
+ exidx_data->u.exidx.unwind_edit_list = unwind_edit_head;
+ exidx_data->u.exidx.unwind_edit_tail = unwind_edit_tail;
+
+ if (deleted_exidx_bytes > 0)
+ elf32_tic6x_adjust_exidx_size (exidx_sec, -deleted_exidx_bytes);
+
+ last_exidx_sec = exidx_sec;
+ last_text_sec = sec;
+ }
+
+ /* Add terminating CANTUNWIND entry. */
+ if (last_exidx_sec && last_unwind_type != 0)
+ elf32_tic6x_insert_cantunwind_after (last_text_sec, last_exidx_sec);
+
+ return TRUE;
+}
+
+/* Add ADDEND to lower 31 bits of VAL, leaving other bits unmodified. */
+
+static unsigned long
+elf32_tic6x_add_low31 (unsigned long val, bfd_vma addend)
+{
+ return (val & ~0x7ffffffful) | ((val + addend) & 0x7ffffffful);
+}
+
+/* Copy an .c6xabi.exidx table entry, adding OFFSET to (applied) PREL31
+ relocations. OFFSET is in bytes, and will be scaled before encoding. */
+
+
+static void
+elf32_tic6x_copy_exidx_entry (bfd *output_bfd, bfd_byte *to, bfd_byte *from,
+ bfd_vma offset)
+{
+ unsigned long first_word = bfd_get_32 (output_bfd, from);
+ unsigned long second_word = bfd_get_32 (output_bfd, from + 4);
+
+ offset >>= 1;
+ /* High bit of first word is supposed to be zero. */
+ if ((first_word & 0x80000000ul) == 0)
+ first_word = elf32_tic6x_add_low31 (first_word, offset);
+
+ /* If the high bit of the first word is clear, and the bit pattern is not 0x1
+ (EXIDX_CANTUNWIND), this is an offset to an .c6xabi.extab entry. */
+ if ((second_word != 0x1) && ((second_word & 0x80000000ul) == 0))
+ second_word = elf32_tic6x_add_low31 (second_word, offset);
+
+ bfd_put_32 (output_bfd, first_word, to);
+ bfd_put_32 (output_bfd, second_word, to + 4);
+}
+
+/* Do the actual mangling of exception index tables. */
+
+static bfd_boolean
+elf32_tic6x_write_section (bfd *output_bfd,
+ struct bfd_link_info *link_info,
+ asection *sec,
+ bfd_byte *contents)
+{
+ _tic6x_elf_section_data *tic6x_data;
+ struct elf32_tic6x_link_hash_table *globals
+ = elf32_tic6x_hash_table (link_info);
+ bfd_vma offset = sec->output_section->vma + sec->output_offset;
+
+ if (globals == NULL)
+ return FALSE;
+
+ /* If this section has not been allocated an _tic6x_elf_section_data
+ structure then we cannot record anything. */
+ tic6x_data = get_tic6x_elf_section_data (sec);
+ if (tic6x_data == NULL)
+ return FALSE;
+
+ if (tic6x_data->elf.this_hdr.sh_type != SHT_C6000_UNWIND)
+ return FALSE;
+
+ tic6x_unwind_table_edit *edit_node
+ = tic6x_data->u.exidx.unwind_edit_list;
+ /* Now, sec->size is the size of the section we will write. The original
+ size (before we merged duplicate entries and inserted EXIDX_CANTUNWIND
+ markers) was sec->rawsize. (This isn't the case if we perform no
+ edits, then rawsize will be zero and we should use size). */
+ bfd_byte *edited_contents = (bfd_byte *) bfd_malloc (sec->size);
+ unsigned int input_size = sec->rawsize ? sec->rawsize : sec->size;
+ unsigned int in_index, out_index;
+ bfd_vma add_to_offsets = 0;
+
+ for (in_index = 0, out_index = 0; in_index * 8 < input_size || edit_node;)
+ {
+ if (edit_node)
+ {
+ unsigned int edit_index = edit_node->index;
+
+ if (in_index < edit_index && in_index * 8 < input_size)
+ {
+ elf32_tic6x_copy_exidx_entry (output_bfd,
+ edited_contents + out_index * 8,
+ contents + in_index * 8, add_to_offsets);
+ out_index++;
+ in_index++;
+ }
+ else if (in_index == edit_index
+ || (in_index * 8 >= input_size
+ && edit_index == UINT_MAX))
+ {
+ switch (edit_node->type)
+ {
+ case DELETE_EXIDX_ENTRY:
+ in_index++;
+ add_to_offsets += 8;
+ break;
+
+ case INSERT_EXIDX_CANTUNWIND_AT_END:
+ {
+ asection *text_sec = edit_node->linked_section;
+ bfd_vma text_offset = text_sec->output_section->vma
+ + text_sec->output_offset
+ + text_sec->size;
+ bfd_vma exidx_offset = offset + out_index * 8;
+ unsigned long prel31_offset;
+
+ /* Note: this is meant to be equivalent to an
+ R_C6000_PREL31 relocation. These synthetic
+ EXIDX_CANTUNWIND markers are not relocated by the
+ usual BFD method. */
+ prel31_offset = ((text_offset - exidx_offset) >> 1)
+ & 0x7ffffffful;
+
+ /* First address we can't unwind. */
+ bfd_put_32 (output_bfd, prel31_offset,
+ &edited_contents[out_index * 8]);
+
+ /* Code for EXIDX_CANTUNWIND. */
+ bfd_put_32 (output_bfd, 0x1,
+ &edited_contents[out_index * 8 + 4]);
+
+ out_index++;
+ add_to_offsets -= 8;
+ }
+ break;
+ }
+
+ edit_node = edit_node->next;
+ }
+ }
+ else
+ {
+ /* No more edits, copy remaining entries verbatim. */
+ elf32_tic6x_copy_exidx_entry (output_bfd,
+ edited_contents + out_index * 8,
+ contents + in_index * 8, add_to_offsets);
+ out_index++;
+ in_index++;
+ }
+ }
+
+ if (!(sec->flags & SEC_EXCLUDE) && !(sec->flags & SEC_NEVER_LOAD))
+ bfd_set_section_contents (output_bfd, sec->output_section,
+ edited_contents,
+ (file_ptr) sec->output_offset, sec->size);
+
+ return TRUE;
+}
+
+#define TARGET_LITTLE_SYM tic6x_elf32_le_vec
+#define TARGET_LITTLE_NAME "elf32-tic6x-le"
+#define TARGET_BIG_SYM tic6x_elf32_be_vec
+#define TARGET_BIG_NAME "elf32-tic6x-be"
+#define ELF_ARCH bfd_arch_tic6x
+#define ELF_TARGET_ID TIC6X_ELF_DATA
+#define ELF_MACHINE_CODE EM_TI_C6000
+#define ELF_MAXPAGESIZE 0x1000
+#define bfd_elf32_bfd_reloc_type_lookup elf32_tic6x_reloc_type_lookup
+#define bfd_elf32_bfd_reloc_name_lookup elf32_tic6x_reloc_name_lookup
+#define bfd_elf32_bfd_merge_private_bfd_data elf32_tic6x_merge_private_bfd_data
+#define bfd_elf32_mkobject elf32_tic6x_mkobject
+#define bfd_elf32_bfd_link_hash_table_create elf32_tic6x_link_hash_table_create
+#define bfd_elf32_new_section_hook elf32_tic6x_new_section_hook
+#define elf_backend_stack_align 8
+#define elf_backend_can_gc_sections 1
+#define elf_backend_default_use_rela_p 1
+#define elf_backend_may_use_rel_p 1
+#define elf_backend_may_use_rela_p 1
+#define elf_backend_obj_attrs_arg_type elf32_tic6x_obj_attrs_arg_type
+#define elf_backend_obj_attrs_handle_unknown elf32_tic6x_obj_attrs_handle_unknown
+#define elf_backend_obj_attrs_order elf32_tic6x_obj_attrs_order
+#define elf_backend_obj_attrs_section ".c6xabi.attributes"
+#define elf_backend_obj_attrs_section_type SHT_C6000_ATTRIBUTES
+#define elf_backend_obj_attrs_vendor "c6xabi"
+#define elf_backend_can_refcount 1
+#define elf_backend_want_got_plt 1
+#define elf_backend_want_dynbss 1
+#define elf_backend_plt_readonly 1
+#define elf_backend_rela_normal 1
+#define elf_backend_got_header_size 8
+#define elf_backend_fake_sections elf32_tic6x_fake_sections
+#define elf_backend_gc_sweep_hook elf32_tic6x_gc_sweep_hook
+#define elf_backend_gc_mark_extra_sections elf32_tic6x_gc_mark_extra_sections
+#define elf_backend_create_dynamic_sections \
+ elf32_tic6x_create_dynamic_sections
+#define elf_backend_adjust_dynamic_symbol \
+ elf32_tic6x_adjust_dynamic_symbol
+#define elf_backend_check_relocs elf32_tic6x_check_relocs
+#define elf_backend_add_symbol_hook elf32_tic6x_add_symbol_hook
+#define elf_backend_symbol_processing elf32_tic6x_symbol_processing
+#define elf_backend_link_output_symbol_hook \
+ elf32_tic6x_link_output_symbol_hook
+#define elf_backend_section_from_bfd_section \
+ elf32_tic6x_section_from_bfd_section
+#define elf_backend_relocate_section elf32_tic6x_relocate_section
+#define elf_backend_relocs_compatible _bfd_elf_relocs_compatible
+#define elf_backend_finish_dynamic_symbol \
+ elf32_tic6x_finish_dynamic_symbol
+#define elf_backend_always_size_sections \
+ elf32_tic6x_always_size_sections
+#define elf_backend_size_dynamic_sections \
+ elf32_tic6x_size_dynamic_sections
+#define elf_backend_finish_dynamic_sections \
+ elf32_tic6x_finish_dynamic_sections
+#define bfd_elf32_bfd_final_link \
+ elf32_tic6x_final_link
+#define elf_backend_write_section elf32_tic6x_write_section
+#define elf_info_to_howto elf32_tic6x_info_to_howto
+#define elf_info_to_howto_rel elf32_tic6x_info_to_howto_rel
+
+#undef elf_backend_omit_section_dynsym
+#define elf_backend_omit_section_dynsym elf32_tic6x_link_omit_section_dynsym
+#define elf_backend_plt_sym_val elf32_tic6x_plt_sym_val
+
+#include "elf32-target.h"
+
+#undef elf32_bed
+#define elf32_bed elf32_tic6x_linux_bed
+
+#undef TARGET_LITTLE_SYM
+#define TARGET_LITTLE_SYM tic6x_elf32_linux_le_vec
+#undef TARGET_LITTLE_NAME
+#define TARGET_LITTLE_NAME "elf32-tic6x-linux-le"
+#undef TARGET_BIG_SYM
+#define TARGET_BIG_SYM tic6x_elf32_linux_be_vec
+#undef TARGET_BIG_NAME
+#define TARGET_BIG_NAME "elf32-tic6x-linux-be"
+#undef ELF_OSABI
+#define ELF_OSABI ELFOSABI_C6000_LINUX
+
+#include "elf32-target.h"
+
+#undef elf32_bed
+#define elf32_bed elf32_tic6x_elf_bed
+
+#undef TARGET_LITTLE_SYM
+#define TARGET_LITTLE_SYM tic6x_elf32_c6000_le_vec
+#undef TARGET_LITTLE_NAME
+#define TARGET_LITTLE_NAME "elf32-tic6x-elf-le"
+#undef TARGET_BIG_SYM
+#define TARGET_BIG_SYM tic6x_elf32_c6000_be_vec
+#undef TARGET_BIG_NAME
+#define TARGET_BIG_NAME "elf32-tic6x-elf-be"
+#undef ELF_OSABI
+#define ELF_OSABI ELFOSABI_C6000_ELFABI
+
+#include "elf32-target.h"
diff --git a/bfd/elf32-tic6x.h b/bfd/elf32-tic6x.h
new file mode 100644
index 0000000..12024b8
--- /dev/null
+++ b/bfd/elf32-tic6x.h
@@ -0,0 +1,34 @@
+/* 32-bit ELF support for TI C6X
+ Copyright (C) 2010-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+extern int elf32_tic6x_merge_arch_attributes (int, int);
+
+/* This function is provided for use from the assembler. */
+
+extern void elf32_tic6x_set_use_rela_p (bfd *, bfd_boolean);
+
+struct elf32_tic6x_params
+{
+ int dsbt_index;
+ int dsbt_size;
+};
+
+extern void elf32_tic6x_setup (struct bfd_link_info *,
+ struct elf32_tic6x_params *);
diff --git a/bfd/elf32-tilegx.c b/bfd/elf32-tilegx.c
new file mode 100644
index 0000000..bc5752c
--- /dev/null
+++ b/bfd/elf32-tilegx.c
@@ -0,0 +1,134 @@
+/* TILE-Gx-specific support for 32-bit ELF.
+ Copyright (C) 2011-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+#include "elf-bfd.h"
+#include "elfxx-tilegx.h"
+#include "elf32-tilegx.h"
+
+
+/* Support for core dump NOTE sections. */
+
+static bfd_boolean
+tilegx_elf_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
+{
+ int offset;
+ size_t size;
+
+ if (note->descsz != TILEGX_PRSTATUS_SIZEOF)
+ return FALSE;
+
+ /* pr_cursig */
+ elf_tdata (abfd)->core->signal =
+ bfd_get_16 (abfd, note->descdata + TILEGX_PRSTATUS_OFFSET_PR_CURSIG);
+
+ /* pr_pid */
+ elf_tdata (abfd)->core->pid =
+ bfd_get_32 (abfd, note->descdata + TILEGX_PRSTATUS_OFFSET_PR_PID);
+
+ /* pr_reg */
+ offset = TILEGX_PRSTATUS_OFFSET_PR_REG;
+ size = TILEGX_GREGSET_T_SIZE;
+
+ /* Make a ".reg/999" section. */
+ return _bfd_elfcore_make_pseudosection (abfd, ".reg",
+ size, note->descpos + offset);
+}
+
+static bfd_boolean
+tilegx_elf_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
+{
+ if (note->descsz != TILEGX_PRPSINFO_SIZEOF)
+ return FALSE;
+
+ elf_tdata (abfd)->core->program
+ = _bfd_elfcore_strndup (abfd, note->descdata + TILEGX_PRPSINFO_OFFSET_PR_FNAME, 16);
+ elf_tdata (abfd)->core->command
+ = _bfd_elfcore_strndup (abfd, note->descdata + TILEGX_PRPSINFO_OFFSET_PR_PSARGS, ELF_PR_PSARGS_SIZE);
+
+
+ /* 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;
+}
+
+
+#define ELF_ARCH bfd_arch_tilegx
+#define ELF_TARGET_ID TILEGX_ELF_DATA
+#define ELF_MACHINE_CODE EM_TILEGX
+#define ELF_MAXPAGESIZE 0x10000
+#define ELF_COMMONPAGESIZE 0x10000
+
+#define TARGET_BIG_SYM tilegx_elf32_be_vec
+#define TARGET_BIG_NAME "elf32-tilegx-be"
+#define TARGET_LITTLE_SYM tilegx_elf32_le_vec
+#define TARGET_LITTLE_NAME "elf32-tilegx-le"
+
+#define elf_backend_reloc_type_class tilegx_reloc_type_class
+
+#define bfd_elf32_bfd_reloc_name_lookup tilegx_reloc_name_lookup
+#define bfd_elf32_bfd_link_hash_table_create tilegx_elf_link_hash_table_create
+#define bfd_elf32_bfd_reloc_type_lookup tilegx_reloc_type_lookup
+#define bfd_elf32_bfd_merge_private_bfd_data \
+ _bfd_tilegx_elf_merge_private_bfd_data
+
+#define elf_backend_copy_indirect_symbol tilegx_elf_copy_indirect_symbol
+#define elf_backend_create_dynamic_sections tilegx_elf_create_dynamic_sections
+#define elf_backend_check_relocs tilegx_elf_check_relocs
+#define elf_backend_adjust_dynamic_symbol tilegx_elf_adjust_dynamic_symbol
+#define elf_backend_omit_section_dynsym tilegx_elf_omit_section_dynsym
+#define elf_backend_size_dynamic_sections tilegx_elf_size_dynamic_sections
+#define elf_backend_relocate_section tilegx_elf_relocate_section
+#define elf_backend_finish_dynamic_symbol tilegx_elf_finish_dynamic_symbol
+#define elf_backend_finish_dynamic_sections tilegx_elf_finish_dynamic_sections
+#define elf_backend_gc_mark_hook tilegx_elf_gc_mark_hook
+#define elf_backend_gc_sweep_hook tilegx_elf_gc_sweep_hook
+#define elf_backend_plt_sym_val tilegx_elf_plt_sym_val
+#define elf_info_to_howto_rel NULL
+#define elf_info_to_howto tilegx_info_to_howto_rela
+#define elf_backend_grok_prstatus tilegx_elf_grok_prstatus
+#define elf_backend_grok_psinfo tilegx_elf_grok_psinfo
+#define elf_backend_additional_program_headers tilegx_additional_program_headers
+
+#define elf_backend_init_index_section _bfd_elf_init_1_index_section
+
+#define elf_backend_can_gc_sections 1
+#define elf_backend_can_refcount 1
+#define elf_backend_want_got_plt 1
+#define elf_backend_plt_readonly 1
+/* Align PLT mod 64 byte L2 line size. */
+#define elf_backend_plt_alignment 6
+#define elf_backend_want_plt_sym 1
+#define elf_backend_got_header_size 4
+#define elf_backend_rela_normal 1
+#define elf_backend_default_execstack 0
+
+#include "elf32-target.h"
diff --git a/bfd/elf32-tilegx.h b/bfd/elf32-tilegx.h
new file mode 100644
index 0000000..abcec80
--- /dev/null
+++ b/bfd/elf32-tilegx.h
@@ -0,0 +1,38 @@
+/* TILE-Gx-specific support for 32-bit ELF.
+ Copyright (C) 2011-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#ifndef _ELF32_TILEGX_H
+#define _ELF32_TILEGX_H
+
+/* This file contains sizes and offsets of Linux data structures. */
+
+#define TILEGX_PRSTATUS_SIZEOF 592
+#define TILEGX_PRSTATUS_OFFSET_PR_CURSIG 12
+#define TILEGX_PRSTATUS_OFFSET_PR_PID 24
+#define TILEGX_PRSTATUS_OFFSET_PR_REG 72
+
+#define TILEGX_PRPSINFO_SIZEOF 128
+#define TILEGX_PRPSINFO_OFFSET_PR_FNAME 32
+#define TILEGX_PRPSINFO_OFFSET_PR_PSARGS 48
+#define ELF_PR_PSARGS_SIZE 80
+
+#define TILEGX_GREGSET_T_SIZE 512
+
+#endif /* _ELF32_TILEGX_H */
diff --git a/bfd/elf32-tilepro.c b/bfd/elf32-tilepro.c
new file mode 100644
index 0000000..b9a31d5
--- /dev/null
+++ b/bfd/elf32-tilepro.c
@@ -0,0 +1,4066 @@
+/* TILEPro-specific support for 32-bit ELF.
+ Copyright (C) 2011-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+#include "elf-bfd.h"
+#include "elf/tilepro.h"
+#include "opcode/tilepro.h"
+#include "libiberty.h"
+#include "elf32-tilepro.h"
+
+#define TILEPRO_BYTES_PER_WORD 4
+
+static reloc_howto_type tilepro_elf_howto_table [] =
+{
+ /* This reloc does nothing. */
+ HOWTO (R_TILEPRO_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_TILEPRO_NONE", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A 32 bit absolute relocation. */
+ HOWTO (R_TILEPRO_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 */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_TILEPRO_32", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A 16 bit absolute relocation. */
+ HOWTO (R_TILEPRO_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_TILEPRO_16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* An 8 bit absolute relocation. */
+ HOWTO (R_TILEPRO_8, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 8, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_unsigned, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_TILEPRO_8", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A 32 bit pc-relative relocation. */
+ HOWTO (R_TILEPRO_32_PCREL,/* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_TILEPRO_32_PCREL", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* A 16 bit pc-relative relocation. */
+ HOWTO (R_TILEPRO_16_PCREL,/* 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_TILEPRO_16_PCREL", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* An 8 bit pc-relative relocation. */
+ HOWTO (R_TILEPRO_8_PCREL, /* type */
+ 0, /* rightshift */
+ 0, /* 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_TILEPRO_8_PCREL",/* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* A 16 bit relocation without overflow. */
+ HOWTO (R_TILEPRO_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 */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_TILEPRO_LO16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* The high order 16 bits of an address. */
+ HOWTO (R_TILEPRO_HI16, /* 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_TILEPRO_HI16", /* 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_TILEPRO_HA16, /* 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_TILEPRO_HA16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_TILEPRO_COPY, /* 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_TILEPRO_COPY", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_TILEPRO_GLOB_DAT, /* 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_TILEPRO_GLOB_DAT", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_TILEPRO_JMP_SLOT, /* 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_TILEPRO_JMP_SLOT", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_TILEPRO_RELATIVE, /* 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_TILEPRO_RELATIVE", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_TILEPRO_BROFF_X1, /* type */
+ TILEPRO_LOG2_BUNDLE_ALIGNMENT_IN_BYTES, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 17, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_TILEPRO_BROFF_X1", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ -1, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_TILEPRO_JOFFLONG_X1, /* type */
+ TILEPRO_LOG2_BUNDLE_ALIGNMENT_IN_BYTES, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 29, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_TILEPRO_JOFFLONG_X1", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ -1, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_TILEPRO_JOFFLONG_X1_PLT, /* type */
+ TILEPRO_LOG2_BUNDLE_ALIGNMENT_IN_BYTES, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 29, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_TILEPRO_JOFFLONG_X1_PLT", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ -1, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+#define TILEPRO_IMM_HOWTO(name, size, bitsize) \
+ HOWTO (name, 0, size, bitsize, FALSE, 0, \
+ complain_overflow_signed, bfd_elf_generic_reloc, \
+ #name, FALSE, 0, -1, FALSE)
+
+#define TILEPRO_UIMM_HOWTO(name, size, bitsize) \
+ HOWTO (name, 0, size, bitsize, FALSE, 0, \
+ complain_overflow_unsigned, bfd_elf_generic_reloc, \
+ #name, FALSE, 0, -1, FALSE)
+
+ TILEPRO_IMM_HOWTO(R_TILEPRO_IMM8_X0, 0, 8),
+ TILEPRO_IMM_HOWTO(R_TILEPRO_IMM8_Y0, 0, 8),
+ TILEPRO_IMM_HOWTO(R_TILEPRO_IMM8_X1, 0, 8),
+ TILEPRO_IMM_HOWTO(R_TILEPRO_IMM8_Y1, 0, 8),
+ TILEPRO_UIMM_HOWTO(R_TILEPRO_MT_IMM15_X1, 1, 15),
+ TILEPRO_UIMM_HOWTO(R_TILEPRO_MF_IMM15_X1, 1, 15),
+ TILEPRO_IMM_HOWTO(R_TILEPRO_IMM16_X0, 1, 16),
+ TILEPRO_IMM_HOWTO(R_TILEPRO_IMM16_X1, 1, 16),
+
+#define TILEPRO_IMM16_HOWTO(name, rshift) \
+ HOWTO (name, rshift, 1, 16, FALSE, 0, \
+ complain_overflow_dont, bfd_elf_generic_reloc, \
+ #name, FALSE, 0, 0xffff, FALSE)
+
+ TILEPRO_IMM16_HOWTO (R_TILEPRO_IMM16_X0_LO, 0),
+ TILEPRO_IMM16_HOWTO (R_TILEPRO_IMM16_X1_LO, 0),
+ TILEPRO_IMM16_HOWTO (R_TILEPRO_IMM16_X0_HI, 16),
+ TILEPRO_IMM16_HOWTO (R_TILEPRO_IMM16_X1_HI, 16),
+ TILEPRO_IMM16_HOWTO (R_TILEPRO_IMM16_X0_HA, 16),
+ TILEPRO_IMM16_HOWTO (R_TILEPRO_IMM16_X1_HA, 16),
+
+ /* PC-relative offsets. */
+
+ HOWTO (R_TILEPRO_IMM16_X0_PCREL, /* 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_TILEPRO_IMM16_X0_PCREL",/* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ -1, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_TILEPRO_IMM16_X1_PCREL, /* 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_TILEPRO_IMM16_X1_PCREL",/* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ -1, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+#define TILEPRO_IMM16_HOWTO_PCREL(name, rshift) \
+ HOWTO (name, rshift, 1, 16, TRUE, 0, \
+ complain_overflow_dont, bfd_elf_generic_reloc, \
+ #name, FALSE, 0, 0xffff, TRUE)
+
+ TILEPRO_IMM16_HOWTO_PCREL (R_TILEPRO_IMM16_X0_LO_PCREL, 0),
+ TILEPRO_IMM16_HOWTO_PCREL (R_TILEPRO_IMM16_X1_LO_PCREL, 0),
+ TILEPRO_IMM16_HOWTO_PCREL (R_TILEPRO_IMM16_X0_HI_PCREL, 16),
+ TILEPRO_IMM16_HOWTO_PCREL (R_TILEPRO_IMM16_X1_HI_PCREL, 16),
+ TILEPRO_IMM16_HOWTO_PCREL (R_TILEPRO_IMM16_X0_HA_PCREL, 16),
+ TILEPRO_IMM16_HOWTO_PCREL (R_TILEPRO_IMM16_X1_HA_PCREL, 16),
+
+ /* Byte offset into GOT for a particular symbol. */
+ TILEPRO_IMM_HOWTO(R_TILEPRO_IMM16_X0_GOT, 1, 16),
+ TILEPRO_IMM_HOWTO(R_TILEPRO_IMM16_X1_GOT, 1, 16),
+ TILEPRO_IMM16_HOWTO (R_TILEPRO_IMM16_X0_GOT_LO, 0),
+ TILEPRO_IMM16_HOWTO (R_TILEPRO_IMM16_X1_GOT_LO, 0),
+ TILEPRO_IMM16_HOWTO (R_TILEPRO_IMM16_X0_GOT_HI, 16),
+ TILEPRO_IMM16_HOWTO (R_TILEPRO_IMM16_X1_GOT_HI, 16),
+ TILEPRO_IMM16_HOWTO (R_TILEPRO_IMM16_X0_GOT_HA, 16),
+ TILEPRO_IMM16_HOWTO (R_TILEPRO_IMM16_X1_GOT_HA, 16),
+
+ TILEPRO_UIMM_HOWTO(R_TILEPRO_MMSTART_X0, 0, 5),
+ TILEPRO_UIMM_HOWTO(R_TILEPRO_MMEND_X0, 0, 5),
+ TILEPRO_UIMM_HOWTO(R_TILEPRO_MMSTART_X1, 0, 5),
+ TILEPRO_UIMM_HOWTO(R_TILEPRO_MMEND_X1, 0, 5),
+
+ TILEPRO_UIMM_HOWTO(R_TILEPRO_SHAMT_X0, 0, 5),
+ TILEPRO_UIMM_HOWTO(R_TILEPRO_SHAMT_X1, 0, 5),
+ TILEPRO_UIMM_HOWTO(R_TILEPRO_SHAMT_Y0, 0, 5),
+ TILEPRO_UIMM_HOWTO(R_TILEPRO_SHAMT_Y1, 0, 5),
+
+ TILEPRO_IMM_HOWTO(R_TILEPRO_DEST_IMM8_X1, 0, 8),
+
+ /* These relocs are currently not defined. */
+ EMPTY_HOWTO (56),
+ EMPTY_HOWTO (57),
+ EMPTY_HOWTO (58),
+ EMPTY_HOWTO (59),
+
+ HOWTO (R_TILEPRO_TLS_GD_CALL, /* type */
+ TILEPRO_LOG2_BUNDLE_ALIGNMENT_IN_BYTES, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 29, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_TILEPRO_TLS_GD_CALL", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ -1, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ TILEPRO_IMM_HOWTO(R_TILEPRO_IMM8_X0_TLS_GD_ADD, 0, 8),
+ TILEPRO_IMM_HOWTO(R_TILEPRO_IMM8_X1_TLS_GD_ADD, 0, 8),
+ TILEPRO_IMM_HOWTO(R_TILEPRO_IMM8_Y0_TLS_GD_ADD, 0, 8),
+ TILEPRO_IMM_HOWTO(R_TILEPRO_IMM8_Y1_TLS_GD_ADD, 0, 8),
+ TILEPRO_IMM_HOWTO(R_TILEPRO_TLS_IE_LOAD, 0, 8),
+
+ /* Offsets into the GOT of TLS Descriptors. */
+
+ HOWTO (R_TILEPRO_IMM16_X0_TLS_GD,/* 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_TILEPRO_IMM16_X0_TLS_GD",/* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_TILEPRO_IMM16_X1_TLS_GD,/* 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_TILEPRO_IMM16_X1_TLS_GD",/* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ TILEPRO_IMM16_HOWTO (R_TILEPRO_IMM16_X0_TLS_GD_LO, 0),
+ TILEPRO_IMM16_HOWTO (R_TILEPRO_IMM16_X1_TLS_GD_LO, 0),
+ TILEPRO_IMM16_HOWTO (R_TILEPRO_IMM16_X0_TLS_GD_HI, 16),
+ TILEPRO_IMM16_HOWTO (R_TILEPRO_IMM16_X1_TLS_GD_HI, 16),
+ TILEPRO_IMM16_HOWTO (R_TILEPRO_IMM16_X0_TLS_GD_HA, 16),
+ TILEPRO_IMM16_HOWTO (R_TILEPRO_IMM16_X1_TLS_GD_HA, 16),
+
+ /* Offsets into the GOT of TLS Descriptors. */
+
+ HOWTO (R_TILEPRO_IMM16_X0_TLS_IE,/* 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_TILEPRO_IMM16_X0_TLS_IE",/* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ -1, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_TILEPRO_IMM16_X1_TLS_IE,/* 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_TILEPRO_IMM16_X1_TLS_IE",/* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ -1, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ TILEPRO_IMM16_HOWTO (R_TILEPRO_IMM16_X0_TLS_IE_LO, 0),
+ TILEPRO_IMM16_HOWTO (R_TILEPRO_IMM16_X1_TLS_IE_LO, 0),
+ TILEPRO_IMM16_HOWTO (R_TILEPRO_IMM16_X0_TLS_IE_HI, 16),
+ TILEPRO_IMM16_HOWTO (R_TILEPRO_IMM16_X1_TLS_IE_HI, 16),
+ TILEPRO_IMM16_HOWTO (R_TILEPRO_IMM16_X0_TLS_IE_HA, 16),
+ TILEPRO_IMM16_HOWTO (R_TILEPRO_IMM16_X1_TLS_IE_HA, 16),
+
+ /* These are common with the Solaris TLS implementation. */
+ HOWTO(R_TILEPRO_TLS_DTPMOD32, 0, 0, 0, FALSE, 0, complain_overflow_dont,
+ bfd_elf_generic_reloc, "R_TILEPRO_TLS_DTPMOD32",
+ FALSE, 0, 0, TRUE),
+ HOWTO(R_TILEPRO_TLS_DTPOFF32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_TILEPRO_TLS_DTPOFF32",
+ FALSE, 0, 0xFFFFFFFF, TRUE),
+ HOWTO(R_TILEPRO_TLS_TPOFF32, 0, 0, 0, FALSE, 0, complain_overflow_dont,
+ bfd_elf_generic_reloc, "R_TILEPRO_TLS_TPOFF32",
+ FALSE, 0, 0, TRUE),
+
+ HOWTO (R_TILEPRO_IMM16_X0_TLS_LE,/* 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_TILEPRO_IMM16_X0_TLS_LE",/* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ -1, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_TILEPRO_IMM16_X1_TLS_LE,/* 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_TILEPRO_IMM16_X1_TLS_LE",/* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ -1, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ TILEPRO_IMM16_HOWTO (R_TILEPRO_IMM16_X0_TLS_LE_LO, 0),
+ TILEPRO_IMM16_HOWTO (R_TILEPRO_IMM16_X1_TLS_LE_LO, 0),
+ TILEPRO_IMM16_HOWTO (R_TILEPRO_IMM16_X0_TLS_LE_HI, 16),
+ TILEPRO_IMM16_HOWTO (R_TILEPRO_IMM16_X1_TLS_LE_HI, 16),
+ TILEPRO_IMM16_HOWTO (R_TILEPRO_IMM16_X0_TLS_LE_HA, 16),
+ TILEPRO_IMM16_HOWTO (R_TILEPRO_IMM16_X1_TLS_LE_HA, 16),
+};
+
+static reloc_howto_type tilepro_elf_howto_table2 [] =
+{
+ /* GNU extension to record C++ vtable hierarchy */
+ HOWTO (R_TILEPRO_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_TILEPRO_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_TILEPRO_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_TILEPRO_GNU_VTENTRY", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+};
+
+/* Map BFD reloc types to TILEPRO ELF reloc types. */
+
+typedef struct tilepro_reloc_map
+{
+ bfd_reloc_code_real_type bfd_reloc_val;
+ unsigned int tilepro_reloc_val;
+ reloc_howto_type * table;
+} reloc_map;
+
+static const reloc_map tilepro_reloc_map [] =
+{
+#define TH_REMAP(bfd, tilepro) \
+ { bfd, tilepro, tilepro_elf_howto_table },
+
+ /* Standard relocations. */
+ TH_REMAP (BFD_RELOC_NONE, R_TILEPRO_NONE)
+ TH_REMAP (BFD_RELOC_32, R_TILEPRO_32)
+ TH_REMAP (BFD_RELOC_16, R_TILEPRO_16)
+ TH_REMAP (BFD_RELOC_8, R_TILEPRO_8)
+ TH_REMAP (BFD_RELOC_32_PCREL, R_TILEPRO_32_PCREL)
+ TH_REMAP (BFD_RELOC_16_PCREL, R_TILEPRO_16_PCREL)
+ TH_REMAP (BFD_RELOC_8_PCREL, R_TILEPRO_8_PCREL)
+ TH_REMAP (BFD_RELOC_LO16, R_TILEPRO_LO16)
+ TH_REMAP (BFD_RELOC_HI16, R_TILEPRO_HI16)
+ TH_REMAP (BFD_RELOC_HI16_S, R_TILEPRO_HA16)
+
+ /* Custom relocations. */
+ TH_REMAP (BFD_RELOC_TILEPRO_COPY, R_TILEPRO_COPY)
+ TH_REMAP (BFD_RELOC_TILEPRO_GLOB_DAT, R_TILEPRO_GLOB_DAT)
+ TH_REMAP (BFD_RELOC_TILEPRO_JMP_SLOT, R_TILEPRO_JMP_SLOT)
+ TH_REMAP (BFD_RELOC_TILEPRO_RELATIVE, R_TILEPRO_RELATIVE)
+ TH_REMAP (BFD_RELOC_TILEPRO_BROFF_X1, R_TILEPRO_BROFF_X1)
+ TH_REMAP (BFD_RELOC_TILEPRO_JOFFLONG_X1, R_TILEPRO_JOFFLONG_X1)
+ TH_REMAP (BFD_RELOC_TILEPRO_JOFFLONG_X1_PLT, R_TILEPRO_JOFFLONG_X1_PLT)
+ TH_REMAP (BFD_RELOC_TILEPRO_IMM8_X0, R_TILEPRO_IMM8_X0)
+ TH_REMAP (BFD_RELOC_TILEPRO_IMM8_Y0, R_TILEPRO_IMM8_Y0)
+ TH_REMAP (BFD_RELOC_TILEPRO_IMM8_X1, R_TILEPRO_IMM8_X1)
+ TH_REMAP (BFD_RELOC_TILEPRO_IMM8_Y1, R_TILEPRO_IMM8_Y1)
+ TH_REMAP (BFD_RELOC_TILEPRO_DEST_IMM8_X1, R_TILEPRO_DEST_IMM8_X1)
+ TH_REMAP (BFD_RELOC_TILEPRO_MT_IMM15_X1, R_TILEPRO_MT_IMM15_X1)
+ TH_REMAP (BFD_RELOC_TILEPRO_MF_IMM15_X1, R_TILEPRO_MF_IMM15_X1)
+ TH_REMAP (BFD_RELOC_TILEPRO_IMM16_X0, R_TILEPRO_IMM16_X0)
+ TH_REMAP (BFD_RELOC_TILEPRO_IMM16_X1, R_TILEPRO_IMM16_X1)
+ TH_REMAP (BFD_RELOC_TILEPRO_IMM16_X0_LO, R_TILEPRO_IMM16_X0_LO)
+ TH_REMAP (BFD_RELOC_TILEPRO_IMM16_X1_LO, R_TILEPRO_IMM16_X1_LO)
+ TH_REMAP (BFD_RELOC_TILEPRO_IMM16_X0_HI, R_TILEPRO_IMM16_X0_HI)
+ TH_REMAP (BFD_RELOC_TILEPRO_IMM16_X1_HI, R_TILEPRO_IMM16_X1_HI)
+ TH_REMAP (BFD_RELOC_TILEPRO_IMM16_X0_HA, R_TILEPRO_IMM16_X0_HA)
+ TH_REMAP (BFD_RELOC_TILEPRO_IMM16_X1_HA, R_TILEPRO_IMM16_X1_HA)
+
+ TH_REMAP (BFD_RELOC_TILEPRO_IMM16_X0_PCREL, R_TILEPRO_IMM16_X0_PCREL)
+ TH_REMAP (BFD_RELOC_TILEPRO_IMM16_X1_PCREL, R_TILEPRO_IMM16_X1_PCREL)
+ TH_REMAP (BFD_RELOC_TILEPRO_IMM16_X0_LO_PCREL, R_TILEPRO_IMM16_X0_LO_PCREL)
+ TH_REMAP (BFD_RELOC_TILEPRO_IMM16_X1_LO_PCREL, R_TILEPRO_IMM16_X1_LO_PCREL)
+ TH_REMAP (BFD_RELOC_TILEPRO_IMM16_X0_HI_PCREL, R_TILEPRO_IMM16_X0_HI_PCREL)
+ TH_REMAP (BFD_RELOC_TILEPRO_IMM16_X1_HI_PCREL, R_TILEPRO_IMM16_X1_HI_PCREL)
+ TH_REMAP (BFD_RELOC_TILEPRO_IMM16_X0_HA_PCREL, R_TILEPRO_IMM16_X0_HA_PCREL)
+ TH_REMAP (BFD_RELOC_TILEPRO_IMM16_X1_HA_PCREL, R_TILEPRO_IMM16_X1_HA_PCREL)
+
+ TH_REMAP (BFD_RELOC_TILEPRO_IMM16_X0_GOT, R_TILEPRO_IMM16_X0_GOT)
+ TH_REMAP (BFD_RELOC_TILEPRO_IMM16_X1_GOT, R_TILEPRO_IMM16_X1_GOT)
+ TH_REMAP (BFD_RELOC_TILEPRO_IMM16_X0_GOT_LO, R_TILEPRO_IMM16_X0_GOT_LO)
+ TH_REMAP (BFD_RELOC_TILEPRO_IMM16_X1_GOT_LO, R_TILEPRO_IMM16_X1_GOT_LO)
+ TH_REMAP (BFD_RELOC_TILEPRO_IMM16_X0_GOT_HI, R_TILEPRO_IMM16_X0_GOT_HI)
+ TH_REMAP (BFD_RELOC_TILEPRO_IMM16_X1_GOT_HI, R_TILEPRO_IMM16_X1_GOT_HI)
+ TH_REMAP (BFD_RELOC_TILEPRO_IMM16_X0_GOT_HA, R_TILEPRO_IMM16_X0_GOT_HA)
+ TH_REMAP (BFD_RELOC_TILEPRO_IMM16_X1_GOT_HA, R_TILEPRO_IMM16_X1_GOT_HA)
+
+ TH_REMAP (BFD_RELOC_TILEPRO_MMSTART_X0, R_TILEPRO_MMSTART_X0)
+ TH_REMAP (BFD_RELOC_TILEPRO_MMEND_X0, R_TILEPRO_MMEND_X0)
+ TH_REMAP (BFD_RELOC_TILEPRO_MMSTART_X1, R_TILEPRO_MMSTART_X1)
+ TH_REMAP (BFD_RELOC_TILEPRO_MMEND_X1, R_TILEPRO_MMEND_X1)
+ TH_REMAP (BFD_RELOC_TILEPRO_SHAMT_X0, R_TILEPRO_SHAMT_X0)
+ TH_REMAP (BFD_RELOC_TILEPRO_SHAMT_X1, R_TILEPRO_SHAMT_X1)
+ TH_REMAP (BFD_RELOC_TILEPRO_SHAMT_Y0, R_TILEPRO_SHAMT_Y0)
+ TH_REMAP (BFD_RELOC_TILEPRO_SHAMT_Y1, R_TILEPRO_SHAMT_Y1)
+
+ TH_REMAP (BFD_RELOC_TILEPRO_TLS_GD_CALL, R_TILEPRO_TLS_GD_CALL)
+ TH_REMAP (BFD_RELOC_TILEPRO_IMM8_X0_TLS_GD_ADD, R_TILEPRO_IMM8_X0_TLS_GD_ADD)
+ TH_REMAP (BFD_RELOC_TILEPRO_IMM8_X1_TLS_GD_ADD, R_TILEPRO_IMM8_X1_TLS_GD_ADD)
+ TH_REMAP (BFD_RELOC_TILEPRO_IMM8_Y0_TLS_GD_ADD, R_TILEPRO_IMM8_Y0_TLS_GD_ADD)
+ TH_REMAP (BFD_RELOC_TILEPRO_IMM8_Y1_TLS_GD_ADD, R_TILEPRO_IMM8_Y1_TLS_GD_ADD)
+ TH_REMAP (BFD_RELOC_TILEPRO_TLS_IE_LOAD, R_TILEPRO_TLS_IE_LOAD)
+
+ TH_REMAP (BFD_RELOC_TILEPRO_IMM16_X0_TLS_GD, R_TILEPRO_IMM16_X0_TLS_GD)
+ TH_REMAP (BFD_RELOC_TILEPRO_IMM16_X1_TLS_GD, R_TILEPRO_IMM16_X1_TLS_GD)
+ TH_REMAP (BFD_RELOC_TILEPRO_IMM16_X0_TLS_GD_LO, R_TILEPRO_IMM16_X0_TLS_GD_LO)
+ TH_REMAP (BFD_RELOC_TILEPRO_IMM16_X1_TLS_GD_LO, R_TILEPRO_IMM16_X1_TLS_GD_LO)
+ TH_REMAP (BFD_RELOC_TILEPRO_IMM16_X0_TLS_GD_HI, R_TILEPRO_IMM16_X0_TLS_GD_HI)
+ TH_REMAP (BFD_RELOC_TILEPRO_IMM16_X1_TLS_GD_HI, R_TILEPRO_IMM16_X1_TLS_GD_HI)
+ TH_REMAP (BFD_RELOC_TILEPRO_IMM16_X0_TLS_GD_HA, R_TILEPRO_IMM16_X0_TLS_GD_HA)
+ TH_REMAP (BFD_RELOC_TILEPRO_IMM16_X1_TLS_GD_HA, R_TILEPRO_IMM16_X1_TLS_GD_HA)
+
+ TH_REMAP (BFD_RELOC_TILEPRO_IMM16_X0_TLS_IE, R_TILEPRO_IMM16_X0_TLS_IE)
+ TH_REMAP (BFD_RELOC_TILEPRO_IMM16_X1_TLS_IE, R_TILEPRO_IMM16_X1_TLS_IE)
+ TH_REMAP (BFD_RELOC_TILEPRO_IMM16_X0_TLS_IE_LO, R_TILEPRO_IMM16_X0_TLS_IE_LO)
+ TH_REMAP (BFD_RELOC_TILEPRO_IMM16_X1_TLS_IE_LO, R_TILEPRO_IMM16_X1_TLS_IE_LO)
+ TH_REMAP (BFD_RELOC_TILEPRO_IMM16_X0_TLS_IE_HI, R_TILEPRO_IMM16_X0_TLS_IE_HI)
+ TH_REMAP (BFD_RELOC_TILEPRO_IMM16_X1_TLS_IE_HI, R_TILEPRO_IMM16_X1_TLS_IE_HI)
+ TH_REMAP (BFD_RELOC_TILEPRO_IMM16_X0_TLS_IE_HA, R_TILEPRO_IMM16_X0_TLS_IE_HA)
+ TH_REMAP (BFD_RELOC_TILEPRO_IMM16_X1_TLS_IE_HA, R_TILEPRO_IMM16_X1_TLS_IE_HA)
+
+ TH_REMAP (BFD_RELOC_TILEPRO_TLS_DTPMOD32, R_TILEPRO_TLS_DTPMOD32)
+ TH_REMAP (BFD_RELOC_TILEPRO_TLS_DTPOFF32, R_TILEPRO_TLS_DTPOFF32)
+ TH_REMAP (BFD_RELOC_TILEPRO_TLS_TPOFF32, R_TILEPRO_TLS_TPOFF32)
+
+ TH_REMAP (BFD_RELOC_TILEPRO_IMM16_X0_TLS_LE, R_TILEPRO_IMM16_X0_TLS_LE)
+ TH_REMAP (BFD_RELOC_TILEPRO_IMM16_X1_TLS_LE, R_TILEPRO_IMM16_X1_TLS_LE)
+ TH_REMAP (BFD_RELOC_TILEPRO_IMM16_X0_TLS_LE_LO, R_TILEPRO_IMM16_X0_TLS_LE_LO)
+ TH_REMAP (BFD_RELOC_TILEPRO_IMM16_X1_TLS_LE_LO, R_TILEPRO_IMM16_X1_TLS_LE_LO)
+ TH_REMAP (BFD_RELOC_TILEPRO_IMM16_X0_TLS_LE_HI, R_TILEPRO_IMM16_X0_TLS_LE_HI)
+ TH_REMAP (BFD_RELOC_TILEPRO_IMM16_X1_TLS_LE_HI, R_TILEPRO_IMM16_X1_TLS_LE_HI)
+ TH_REMAP (BFD_RELOC_TILEPRO_IMM16_X0_TLS_LE_HA, R_TILEPRO_IMM16_X0_TLS_LE_HA)
+ TH_REMAP (BFD_RELOC_TILEPRO_IMM16_X1_TLS_LE_HA, R_TILEPRO_IMM16_X1_TLS_LE_HA)
+
+#undef TH_REMAP
+
+ { BFD_RELOC_VTABLE_INHERIT, R_TILEPRO_GNU_VTINHERIT, tilepro_elf_howto_table2 },
+ { BFD_RELOC_VTABLE_ENTRY, R_TILEPRO_GNU_VTENTRY, tilepro_elf_howto_table2 },
+};
+
+
+
+/* The TILEPro linker needs to keep track of the number of relocs that it
+ decides to copy as dynamic relocs in check_relocs for each symbol.
+ This is so that it can later discard them if they are found to be
+ unnecessary. We store the information in a field extending the
+ regular ELF linker hash table. */
+
+struct tilepro_elf_dyn_relocs
+{
+ struct tilepro_elf_dyn_relocs *next;
+
+ /* The input section of the reloc. */
+ asection *sec;
+
+ /* Total number of relocs copied for the input section. */
+ bfd_size_type count;
+
+ /* Number of pc-relative relocs copied for the input section. */
+ bfd_size_type pc_count;
+};
+
+/* TILEPRO ELF linker hash entry. */
+
+struct tilepro_elf_link_hash_entry
+{
+ struct elf_link_hash_entry elf;
+
+ /* Track dynamic relocs copied for this symbol. */
+ struct tilepro_elf_dyn_relocs *dyn_relocs;
+
+#define GOT_UNKNOWN 0
+#define GOT_NORMAL 1
+#define GOT_TLS_GD 2
+#define GOT_TLS_IE 4
+ unsigned char tls_type;
+};
+
+#define tilepro_elf_hash_entry(ent) \
+ ((struct tilepro_elf_link_hash_entry *)(ent))
+
+struct _bfd_tilepro_elf_obj_tdata
+{
+ struct elf_obj_tdata root;
+
+ /* tls_type for each local got entry. */
+ char *local_got_tls_type;
+};
+
+#define _bfd_tilepro_elf_tdata(abfd) \
+ ((struct _bfd_tilepro_elf_obj_tdata *) (abfd)->tdata.any)
+
+#define _bfd_tilepro_elf_local_got_tls_type(abfd) \
+ (_bfd_tilepro_elf_tdata (abfd)->local_got_tls_type)
+
+#define is_tilepro_elf(bfd) \
+ (bfd_get_flavour (bfd) == bfd_target_elf_flavour \
+ && elf_tdata (bfd) != NULL \
+ && elf_object_id (bfd) == TILEPRO_ELF_DATA)
+
+/* Allocate TILEPro ELF private object data. */
+
+static bfd_boolean
+tilepro_elf_mkobject (bfd *abfd)
+{
+ return bfd_elf_allocate_object (abfd,
+ sizeof (struct _bfd_tilepro_elf_obj_tdata),
+ TILEPRO_ELF_DATA);
+}
+
+#include "elf/common.h"
+#include "elf/internal.h"
+
+struct tilepro_elf_link_hash_table
+{
+ struct elf_link_hash_table elf;
+
+ /* Short-cuts to get to dynamic linker sections. */
+ asection *sdynbss;
+ asection *srelbss;
+
+ /* Small local sym to section mapping cache. */
+ struct sym_cache sym_cache;
+};
+
+/* Get the Tilepro ELF linker hash table from a link_info structure. */
+#define tilepro_elf_hash_table(p) \
+ (elf_hash_table_id ((struct elf_link_hash_table *) ((p)->hash)) \
+ == TILEPRO_ELF_DATA \
+ ? ((struct tilepro_elf_link_hash_table *) ((p)->hash)) : NULL)
+
+static reloc_howto_type *
+tilepro_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED,
+ bfd_reloc_code_real_type code)
+{
+ unsigned int i;
+
+ for (i = ARRAY_SIZE (tilepro_reloc_map); --i;)
+ {
+ const reloc_map * entry;
+
+ entry = tilepro_reloc_map + i;
+
+ if (entry->bfd_reloc_val == code)
+ return entry->table + (entry->tilepro_reloc_val
+ - entry->table[0].type);
+ }
+
+ return NULL;
+}
+
+static reloc_howto_type *
+tilepro_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ const char *r_name)
+{
+ unsigned int i;
+
+ for (i = 0;
+ i < (sizeof (tilepro_elf_howto_table)
+ / sizeof (tilepro_elf_howto_table[0]));
+ i++)
+ if (tilepro_elf_howto_table[i].name != NULL
+ && strcasecmp (tilepro_elf_howto_table[i].name, r_name) == 0)
+ return &tilepro_elf_howto_table[i];
+
+ return NULL;
+}
+
+/* Set the howto pointer for an TILEPro ELF reloc. */
+
+static void
+tilepro_info_to_howto_rela (bfd * abfd ATTRIBUTE_UNUSED,
+ arelent * cache_ptr,
+ Elf_Internal_Rela * dst)
+{
+ unsigned int r_type = ELF32_R_TYPE (dst->r_info);
+
+ if (r_type <= (unsigned int) R_TILEPRO_IMM16_X1_TLS_LE_HA)
+ cache_ptr->howto = &tilepro_elf_howto_table [r_type];
+ else if (r_type - R_TILEPRO_GNU_VTINHERIT
+ <= (unsigned int) R_TILEPRO_GNU_VTENTRY)
+ cache_ptr->howto
+ = &tilepro_elf_howto_table2 [r_type - R_TILEPRO_GNU_VTINHERIT];
+ else
+ abort ();
+}
+
+typedef tilepro_bundle_bits (*tilepro_create_func)(int);
+
+static const tilepro_create_func reloc_to_create_func[] =
+{
+ /* The first fourteen relocation types don't correspond to operands */
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+
+ /* The remaining relocations are used for immediate operands */
+ create_BrOff_X1,
+ create_JOffLong_X1,
+ create_JOffLong_X1,
+ create_Imm8_X0,
+ create_Imm8_Y0,
+ create_Imm8_X1,
+ create_Imm8_Y1,
+ create_MT_Imm15_X1,
+ create_MF_Imm15_X1,
+ create_Imm16_X0,
+ create_Imm16_X1,
+ create_Imm16_X0,
+ create_Imm16_X1,
+ create_Imm16_X0,
+ create_Imm16_X1,
+ create_Imm16_X0,
+ create_Imm16_X1,
+ create_Imm16_X0,
+ create_Imm16_X1,
+ create_Imm16_X0,
+ create_Imm16_X1,
+ create_Imm16_X0,
+ create_Imm16_X1,
+ create_Imm16_X0,
+ create_Imm16_X1,
+ create_Imm16_X0,
+ create_Imm16_X1,
+ create_Imm16_X0,
+ create_Imm16_X1,
+ create_Imm16_X0,
+ create_Imm16_X1,
+ create_Imm16_X0,
+ create_Imm16_X1,
+ create_MMStart_X0,
+ create_MMEnd_X0,
+ create_MMStart_X1,
+ create_MMEnd_X1,
+ create_ShAmt_X0,
+ create_ShAmt_X1,
+ create_ShAmt_Y0,
+ create_ShAmt_Y1,
+
+ create_Dest_Imm8_X1,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+
+ create_Imm16_X0,
+ create_Imm16_X1,
+ create_Imm16_X0,
+ create_Imm16_X1,
+ create_Imm16_X0,
+ create_Imm16_X1,
+ create_Imm16_X0,
+ create_Imm16_X1,
+ create_Imm16_X0,
+ create_Imm16_X1,
+ create_Imm16_X0,
+ create_Imm16_X1,
+ create_Imm16_X0,
+ create_Imm16_X1,
+ create_Imm16_X0,
+ create_Imm16_X1,
+
+ NULL,
+ NULL,
+ NULL,
+
+ create_Imm16_X0,
+ create_Imm16_X1,
+ create_Imm16_X0,
+ create_Imm16_X1,
+ create_Imm16_X0,
+ create_Imm16_X1,
+ create_Imm16_X0,
+ create_Imm16_X1,
+};
+
+#define NELEMS(a) ((int) (sizeof (a) / sizeof ((a)[0])))
+
+/* Support for core dump NOTE sections. */
+
+static bfd_boolean
+tilepro_elf_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
+{
+ int offset;
+ size_t size;
+
+ if (note->descsz != TILEPRO_PRSTATUS_SIZEOF)
+ return FALSE;
+
+ /* pr_cursig */
+ elf_tdata (abfd)->core->signal =
+ bfd_get_16 (abfd, note->descdata + TILEPRO_PRSTATUS_OFFSET_PR_CURSIG);
+
+ /* pr_pid */
+ elf_tdata (abfd)->core->pid =
+ bfd_get_32 (abfd, note->descdata + TILEPRO_PRSTATUS_OFFSET_PR_PID);
+
+ /* pr_reg */
+ offset = TILEPRO_PRSTATUS_OFFSET_PR_REG;
+ size = TILEPRO_GREGSET_T_SIZE;
+
+ /* Make a ".reg/999" section. */
+ return _bfd_elfcore_make_pseudosection (abfd, ".reg",
+ size, note->descpos + offset);
+}
+
+static bfd_boolean
+tilepro_elf_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
+{
+ if (note->descsz != TILEPRO_PRPSINFO_SIZEOF)
+ return FALSE;
+
+ elf_tdata (abfd)->core->program
+ = _bfd_elfcore_strndup (abfd,
+ note->descdata + TILEPRO_PRPSINFO_OFFSET_PR_FNAME,
+ 16);
+ elf_tdata (abfd)->core->command
+ = _bfd_elfcore_strndup (abfd,
+ note->descdata + TILEPRO_PRPSINFO_OFFSET_PR_PSARGS,
+ ELF_PR_PSARGS_SIZE);
+
+
+ /* 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;
+}
+
+
+static void
+tilepro_elf_append_rela_32 (bfd *abfd, asection *s, Elf_Internal_Rela *rel)
+{
+ Elf32_External_Rela *loc32;
+
+ loc32 = (Elf32_External_Rela *) s->contents;
+ loc32 += s->reloc_count++;
+ bfd_elf32_swap_reloca_out (abfd, rel, (bfd_byte *) loc32);
+}
+
+/* PLT/GOT stuff */
+
+/* The procedure linkage table starts with the following header:
+
+ {
+ rli r29, r29, 16
+ lwadd r28, r27, 4
+ }
+ lw r27, r27
+ {
+ info 10 ## SP not offset, return PC in LR
+ jr r27
+ }
+
+ Subsequent entries are the following, jumping to the header at the end:
+
+ lnk r28
+1:
+ {
+ auli r28, r28, <_GLOBAL_OFFSET_TABLE_ - 1b + MY_GOT_OFFSET>
+ auli r27, r28, <_GLOBAL_OFFSET_TABLE_ - 1b>
+ }
+ {
+ addli r28, r28, <_GLOBAL_OFFSET_TABLE_ - 1b + MY_GOT_OFFSET>
+ addli r27, r27, <_GLOBAL_OFFSET_TABLE_ - 1b>
+ }
+ {
+ auli r29, zero, MY_PLT_INDEX
+ lw r28, r28
+ }
+ {
+ info 10 ## SP not offset, return PC in LR
+ jr r28
+ }
+
+ We initially store MY_PLT_INDEX in the high bits so that we can use the all
+ 16 bits as an unsigned offset; if we use the low bits we would get an
+ unwanted sign extension. The PLT header then rotates the index to get the
+ right value, before calling the resolution routine. This computation can
+ fit in unused bundle slots so it's free.
+
+ This code sequence lets the code at at the start of the PLT determine
+ which PLT entry was executed by examining 'r29'.
+
+ Note that MY_PLT_INDEX skips over the header entries, so the first
+ actual jump table entry has index zero.
+*/
+
+#define PLT_HEADER_SIZE_IN_BUNDLES 3
+#define PLT_ENTRY_SIZE_IN_BUNDLES 5
+
+#define PLT_HEADER_SIZE \
+ (PLT_HEADER_SIZE_IN_BUNDLES * TILEPRO_BUNDLE_SIZE_IN_BYTES)
+#define PLT_ENTRY_SIZE \
+ (PLT_ENTRY_SIZE_IN_BUNDLES * TILEPRO_BUNDLE_SIZE_IN_BYTES)
+
+/* The size in bytes of an entry in the global offset table. */
+
+#define GOT_ENTRY_SIZE TILEPRO_BYTES_PER_WORD
+
+#define GOTPLT_HEADER_SIZE (2 * GOT_ENTRY_SIZE)
+
+
+static const bfd_byte
+tilepro_plt0_entry[PLT_HEADER_SIZE] =
+{
+ 0x5d, 0x07, 0x03, 0x70,
+ 0x6e, 0x23, 0xd0, 0x30, /* { rli r29, r29, 16 ; lwadd r28, r27, 4 } */
+ 0x00, 0x50, 0xba, 0x6d,
+ 0x00, 0x08, 0x6d, 0xdc, /* { lw r27, r27 } */
+ 0xff, 0xaf, 0x10, 0x50,
+ 0x60, 0x03, 0x18, 0x08, /* { info 10 ; jr r27 } */
+};
+
+static const bfd_byte
+tilepro_short_plt_entry[PLT_ENTRY_SIZE] =
+{
+ 0x00, 0x50, 0x16, 0x70,
+ 0x0e, 0x00, 0x1a, 0x08, /* { lnk r28 } */
+ 0x1c, 0x07, 0x00, 0xa0,
+ 0x8d, 0x03, 0x00, 0x18, /* { addli r28, r28, 0 ; addli r27, r28, 0 } */
+ 0xdd, 0x0f, 0x00, 0x30,
+ 0x8e, 0x73, 0x0b, 0x40, /* { auli r29, zero, 0 ; lw r28, r28 } */
+ 0xff, 0xaf, 0x10, 0x50,
+ 0x80, 0x03, 0x18, 0x08, /* { info 10 ; jr r28 } */
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+};
+
+static const bfd_byte
+tilepro_long_plt_entry[PLT_ENTRY_SIZE] =
+{
+ 0x00, 0x50, 0x16, 0x70,
+ 0x0e, 0x00, 0x1a, 0x08, /* { lnk r28 } */
+ 0x1c, 0x07, 0x00, 0xb0,
+ 0x8d, 0x03, 0x00, 0x20, /* { auli r28, r28, 0 ; auli r27, r28, 0 } */
+ 0x1c, 0x07, 0x00, 0xa0,
+ 0x6d, 0x03, 0x00, 0x18, /* { addli r28, r28, 0 ; addli r27, r27, 0 } */
+ 0xdd, 0x0f, 0x00, 0x30,
+ 0x8e, 0x73, 0x0b, 0x40, /* { auli r29, zero, 0 ; lw r28, r28 } */
+ 0xff, 0xaf, 0x10, 0x50,
+ 0x80, 0x03, 0x18, 0x08, /* { info 10 ; jr r28 } */
+};
+
+static bfd_vma
+tilepro_ha16(bfd_vma vma)
+{
+ return ((vma >> 16) + ((vma >> 15) & 1)) & 0xffff;
+}
+
+static int
+tilepro_plt_entry_build (asection *splt, asection *sgotplt, bfd_vma offset,
+ bfd_vma *r_offset)
+{
+ int plt_index = (offset - PLT_ENTRY_SIZE) / PLT_ENTRY_SIZE;
+ int got_offset = plt_index * GOT_ENTRY_SIZE + GOTPLT_HEADER_SIZE;
+ tilepro_bundle_bits *pc;
+
+ /* Compute the distance from the got entry to the lnk. */
+ bfd_signed_vma dist_got_entry = sgotplt->output_section->vma
+ + sgotplt->output_offset
+ + got_offset
+ - splt->output_section->vma
+ - splt->output_offset
+ - offset
+ - TILEPRO_BUNDLE_SIZE_IN_BYTES;
+
+ /* Compute the distance to GOTPLT[0]. */
+ bfd_signed_vma dist_got0 = dist_got_entry - got_offset;
+
+ /* Check whether we can use the short plt entry with 16-bit offset. */
+ bfd_boolean short_plt_entry =
+ (dist_got_entry <= 0x7fff && dist_got0 >= -0x8000);
+
+ /* Copy the plt entry template. */
+ memcpy (splt->contents + offset,
+ short_plt_entry ? tilepro_short_plt_entry : tilepro_long_plt_entry,
+ PLT_ENTRY_SIZE);
+
+ /* Write the immediate offsets. */
+ pc = (tilepro_bundle_bits *)(splt->contents + offset);
+ pc++;
+
+ if (!short_plt_entry)
+ {
+ /* { auli r28, r28, &GOTPLT[MY_GOT_INDEX] ; auli r27, r28, &GOTPLT[0] } */
+ *pc++ |= create_Imm16_X0 (tilepro_ha16 (dist_got_entry))
+ | create_Imm16_X1 (tilepro_ha16 (dist_got0));
+ }
+
+ /* { addli r28, r28, &GOTPLT[MY_GOT_INDEX] ; addli r27, r28, &GOTPLT[0] } or
+ { addli r28, r28, &GOTPLT[MY_GOT_INDEX] ; addli r27, r27, &GOTPLT[0] } */
+ *pc++ |= create_Imm16_X0 (dist_got_entry)
+ | create_Imm16_X1 (dist_got0);
+
+ /* { auli r29, zero, MY_PLT_INDEX ; lw r28, r28 } */
+ *pc |= create_Imm16_X0 (plt_index);
+
+ /* Set the relocation offset. */
+ *r_offset = got_offset;
+
+ return plt_index;
+}
+
+#define TILEPRO_ELF_RELA_BYTES (sizeof(Elf32_External_Rela))
+
+
+/* Create an entry in an TILEPro ELF linker hash table. */
+
+static struct bfd_hash_entry *
+link_hash_newfunc (struct bfd_hash_entry *entry,
+ struct bfd_hash_table *table, const char *string)
+{
+ /* Allocate the structure if it has not already been allocated by a
+ subclass. */
+ if (entry == NULL)
+ {
+ entry =
+ bfd_hash_allocate (table,
+ sizeof (struct tilepro_elf_link_hash_entry));
+ if (entry == NULL)
+ return entry;
+ }
+
+ /* Call the allocation method of the superclass. */
+ entry = _bfd_elf_link_hash_newfunc (entry, table, string);
+ if (entry != NULL)
+ {
+ struct tilepro_elf_link_hash_entry *eh;
+
+ eh = (struct tilepro_elf_link_hash_entry *) entry;
+ eh->dyn_relocs = NULL;
+ eh->tls_type = GOT_UNKNOWN;
+ }
+
+ return entry;
+}
+
+/* Create a TILEPRO ELF linker hash table. */
+
+static struct bfd_link_hash_table *
+tilepro_elf_link_hash_table_create (bfd *abfd)
+{
+ struct tilepro_elf_link_hash_table *ret;
+ bfd_size_type amt = sizeof (struct tilepro_elf_link_hash_table);
+
+ ret = (struct tilepro_elf_link_hash_table *) bfd_zmalloc (amt);
+ if (ret == NULL)
+ return NULL;
+
+ if (!_bfd_elf_link_hash_table_init (&ret->elf, abfd, link_hash_newfunc,
+ sizeof (struct tilepro_elf_link_hash_entry),
+ TILEPRO_ELF_DATA))
+ {
+ free (ret);
+ return NULL;
+ }
+
+ return &ret->elf.root;
+}
+
+/* Create the .got section. */
+
+static bfd_boolean
+tilepro_elf_create_got_section (bfd *abfd, struct bfd_link_info *info)
+{
+ flagword flags;
+ asection *s, *s_got;
+ struct elf_link_hash_entry *h;
+ const struct elf_backend_data *bed = get_elf_backend_data (abfd);
+ struct elf_link_hash_table *htab = elf_hash_table (info);
+
+ /* This function may be called more than once. */
+ s = bfd_get_linker_section (abfd, ".got");
+ if (s != NULL)
+ return TRUE;
+
+ flags = bed->dynamic_sec_flags;
+
+ s = bfd_make_section_with_flags (abfd,
+ (bed->rela_plts_and_copies_p
+ ? ".rela.got" : ".rel.got"),
+ (bed->dynamic_sec_flags
+ | SEC_READONLY));
+ if (s == NULL
+ || ! bfd_set_section_alignment (abfd, s, bed->s->log_file_align))
+ return FALSE;
+ htab->srelgot = s;
+
+ s = s_got = bfd_make_section_with_flags (abfd, ".got", flags);
+ if (s == NULL
+ || !bfd_set_section_alignment (abfd, s, bed->s->log_file_align))
+ return FALSE;
+ htab->sgot = s;
+
+ /* The first bit of the global offset table is the header. */
+ s->size += bed->got_header_size;
+
+ if (bed->want_got_plt)
+ {
+ s = bfd_make_section_with_flags (abfd, ".got.plt", flags);
+ if (s == NULL
+ || !bfd_set_section_alignment (abfd, s,
+ bed->s->log_file_align))
+ return FALSE;
+ htab->sgotplt = s;
+
+ /* Reserve room for the header. */
+ s->size += GOTPLT_HEADER_SIZE;
+ }
+
+ if (bed->want_got_sym)
+ {
+ /* Define the symbol _GLOBAL_OFFSET_TABLE_ at the start of the .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 = _bfd_elf_define_linkage_sym (abfd, info, s_got,
+ "_GLOBAL_OFFSET_TABLE_");
+ elf_hash_table (info)->hgot = h;
+ if (h == NULL)
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/* Create .plt, .rela.plt, .got, .got.plt, .rela.got, .dynbss, and
+ .rela.bss sections in DYNOBJ, and set up shortcuts to them in our
+ hash table. */
+
+static bfd_boolean
+tilepro_elf_create_dynamic_sections (bfd *dynobj,
+ struct bfd_link_info *info)
+{
+ struct tilepro_elf_link_hash_table *htab;
+
+ htab = tilepro_elf_hash_table (info);
+ BFD_ASSERT (htab != NULL);
+
+ if (!tilepro_elf_create_got_section (dynobj, info))
+ return FALSE;
+
+ if (!_bfd_elf_create_dynamic_sections (dynobj, info))
+ return FALSE;
+
+ htab->sdynbss = bfd_get_linker_section (dynobj, ".dynbss");
+ if (!info->shared)
+ htab->srelbss = bfd_get_linker_section (dynobj, ".rela.bss");
+
+ if (!htab->elf.splt || !htab->elf.srelplt || !htab->sdynbss
+ || (!info->shared && !htab->srelbss))
+ abort ();
+
+ return TRUE;
+}
+
+/* Copy the extra info we tack onto an elf_link_hash_entry. */
+
+static void
+tilepro_elf_copy_indirect_symbol (struct bfd_link_info *info,
+ struct elf_link_hash_entry *dir,
+ struct elf_link_hash_entry *ind)
+{
+ struct tilepro_elf_link_hash_entry *edir, *eind;
+
+ edir = (struct tilepro_elf_link_hash_entry *) dir;
+ eind = (struct tilepro_elf_link_hash_entry *) ind;
+
+ if (eind->dyn_relocs != NULL)
+ {
+ if (edir->dyn_relocs != NULL)
+ {
+ struct tilepro_elf_dyn_relocs **pp;
+ struct tilepro_elf_dyn_relocs *p;
+
+ /* Add reloc counts against the indirect sym to the direct sym
+ list. Merge any entries against the same section. */
+ for (pp = &eind->dyn_relocs; (p = *pp) != NULL; )
+ {
+ struct tilepro_elf_dyn_relocs *q;
+
+ for (q = edir->dyn_relocs; q != NULL; q = q->next)
+ if (q->sec == p->sec)
+ {
+ q->pc_count += p->pc_count;
+ q->count += p->count;
+ *pp = p->next;
+ break;
+ }
+ if (q == NULL)
+ pp = &p->next;
+ }
+ *pp = edir->dyn_relocs;
+ }
+
+ edir->dyn_relocs = eind->dyn_relocs;
+ eind->dyn_relocs = NULL;
+ }
+
+ if (ind->root.type == bfd_link_hash_indirect
+ && dir->got.refcount <= 0)
+ {
+ edir->tls_type = eind->tls_type;
+ eind->tls_type = GOT_UNKNOWN;
+ }
+ _bfd_elf_link_hash_copy_indirect (info, dir, ind);
+}
+
+static int
+tilepro_tls_translate_to_le (int r_type)
+{
+ switch (r_type)
+ {
+ case R_TILEPRO_IMM16_X0_TLS_GD:
+ case R_TILEPRO_IMM16_X0_TLS_IE:
+ return R_TILEPRO_IMM16_X0_TLS_LE;
+
+ case R_TILEPRO_IMM16_X1_TLS_GD:
+ case R_TILEPRO_IMM16_X1_TLS_IE:
+ return R_TILEPRO_IMM16_X1_TLS_LE;
+
+ case R_TILEPRO_IMM16_X0_TLS_GD_LO:
+ case R_TILEPRO_IMM16_X0_TLS_IE_LO:
+ return R_TILEPRO_IMM16_X0_TLS_LE_LO;
+
+ case R_TILEPRO_IMM16_X1_TLS_GD_LO:
+ case R_TILEPRO_IMM16_X1_TLS_IE_LO:
+ return R_TILEPRO_IMM16_X1_TLS_LE_LO;
+
+ case R_TILEPRO_IMM16_X0_TLS_GD_HI:
+ case R_TILEPRO_IMM16_X0_TLS_IE_HI:
+ return R_TILEPRO_IMM16_X0_TLS_LE_HI;
+
+ case R_TILEPRO_IMM16_X1_TLS_GD_HI:
+ case R_TILEPRO_IMM16_X1_TLS_IE_HI:
+ return R_TILEPRO_IMM16_X1_TLS_LE_HI;
+
+ case R_TILEPRO_IMM16_X0_TLS_GD_HA:
+ case R_TILEPRO_IMM16_X0_TLS_IE_HA:
+ return R_TILEPRO_IMM16_X0_TLS_LE_HA;
+
+ case R_TILEPRO_IMM16_X1_TLS_GD_HA:
+ case R_TILEPRO_IMM16_X1_TLS_IE_HA:
+ return R_TILEPRO_IMM16_X1_TLS_LE_HA;
+ }
+ return r_type;
+}
+
+static int
+tilepro_tls_translate_to_ie (int r_type)
+{
+ switch (r_type)
+ {
+ case R_TILEPRO_IMM16_X0_TLS_GD:
+ case R_TILEPRO_IMM16_X0_TLS_IE:
+ return R_TILEPRO_IMM16_X0_TLS_IE;
+
+ case R_TILEPRO_IMM16_X1_TLS_GD:
+ case R_TILEPRO_IMM16_X1_TLS_IE:
+ return R_TILEPRO_IMM16_X1_TLS_IE;
+
+ case R_TILEPRO_IMM16_X0_TLS_GD_LO:
+ case R_TILEPRO_IMM16_X0_TLS_IE_LO:
+ return R_TILEPRO_IMM16_X0_TLS_IE_LO;
+
+ case R_TILEPRO_IMM16_X1_TLS_GD_LO:
+ case R_TILEPRO_IMM16_X1_TLS_IE_LO:
+ return R_TILEPRO_IMM16_X1_TLS_IE_LO;
+
+ case R_TILEPRO_IMM16_X0_TLS_GD_HI:
+ case R_TILEPRO_IMM16_X0_TLS_IE_HI:
+ return R_TILEPRO_IMM16_X0_TLS_IE_HI;
+
+ case R_TILEPRO_IMM16_X1_TLS_GD_HI:
+ case R_TILEPRO_IMM16_X1_TLS_IE_HI:
+ return R_TILEPRO_IMM16_X1_TLS_IE_HI;
+
+ case R_TILEPRO_IMM16_X0_TLS_GD_HA:
+ case R_TILEPRO_IMM16_X0_TLS_IE_HA:
+ return R_TILEPRO_IMM16_X0_TLS_IE_HA;
+
+ case R_TILEPRO_IMM16_X1_TLS_GD_HA:
+ case R_TILEPRO_IMM16_X1_TLS_IE_HA:
+ return R_TILEPRO_IMM16_X1_TLS_IE_HA;
+ }
+ return r_type;
+}
+
+static int
+tilepro_elf_tls_transition (struct bfd_link_info *info, int r_type,
+ int is_local)
+{
+ if (info->shared)
+ return r_type;
+
+ if (is_local)
+ return tilepro_tls_translate_to_le (r_type);
+ else
+ return tilepro_tls_translate_to_ie (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 bfd_boolean
+tilepro_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
+ asection *sec, const Elf_Internal_Rela *relocs)
+{
+ struct tilepro_elf_link_hash_table *htab;
+ 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;
+ int num_relocs;
+
+ if (info->relocatable)
+ return TRUE;
+
+ htab = tilepro_elf_hash_table (info);
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+ sym_hashes = elf_sym_hashes (abfd);
+
+ sreloc = NULL;
+
+ num_relocs = sec->reloc_count;
+
+ BFD_ASSERT (is_tilepro_elf (abfd) || num_relocs == 0);
+
+ if (htab->elf.dynobj == NULL)
+ htab->elf.dynobj = abfd;
+
+ rel_end = relocs + num_relocs;
+ for (rel = relocs; rel < rel_end; rel++)
+ {
+ unsigned int r_type;
+ unsigned long r_symndx;
+ struct elf_link_hash_entry *h;
+ int tls_type;
+
+ r_symndx = ELF32_R_SYM (rel->r_info);
+ r_type = ELF32_R_TYPE (rel->r_info);
+
+ if (r_symndx >= NUM_SHDR_ENTRIES (symtab_hdr))
+ {
+ (*_bfd_error_handler) (_("%B: bad symbol index: %d"),
+ abfd, r_symndx);
+ return FALSE;
+ }
+
+ if (r_symndx < symtab_hdr->sh_info)
+ h = NULL;
+ 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;
+
+ /* PR15323, ref flags aren't set for references in the same
+ object. */
+ h->root.non_ir_ref = 1;
+ }
+
+ r_type = tilepro_elf_tls_transition (info, r_type, h == NULL);
+ switch (r_type)
+ {
+ case R_TILEPRO_IMM16_X0_TLS_LE:
+ case R_TILEPRO_IMM16_X1_TLS_LE:
+ case R_TILEPRO_IMM16_X0_TLS_LE_LO:
+ case R_TILEPRO_IMM16_X1_TLS_LE_LO:
+ case R_TILEPRO_IMM16_X0_TLS_LE_HI:
+ case R_TILEPRO_IMM16_X1_TLS_LE_HI:
+ case R_TILEPRO_IMM16_X0_TLS_LE_HA:
+ case R_TILEPRO_IMM16_X1_TLS_LE_HA:
+ if (info->shared)
+ goto r_tilepro_plt32;
+ break;
+
+ case R_TILEPRO_IMM16_X0_TLS_GD:
+ case R_TILEPRO_IMM16_X1_TLS_GD:
+ case R_TILEPRO_IMM16_X0_TLS_GD_LO:
+ case R_TILEPRO_IMM16_X1_TLS_GD_LO:
+ case R_TILEPRO_IMM16_X0_TLS_GD_HI:
+ case R_TILEPRO_IMM16_X1_TLS_GD_HI:
+ case R_TILEPRO_IMM16_X0_TLS_GD_HA:
+ case R_TILEPRO_IMM16_X1_TLS_GD_HA:
+ BFD_ASSERT (info->shared);
+ tls_type = GOT_TLS_GD;
+ goto have_got_reference;
+
+ case R_TILEPRO_IMM16_X0_TLS_IE:
+ case R_TILEPRO_IMM16_X1_TLS_IE:
+ case R_TILEPRO_IMM16_X0_TLS_IE_LO:
+ case R_TILEPRO_IMM16_X1_TLS_IE_LO:
+ case R_TILEPRO_IMM16_X0_TLS_IE_HI:
+ case R_TILEPRO_IMM16_X1_TLS_IE_HI:
+ case R_TILEPRO_IMM16_X0_TLS_IE_HA:
+ case R_TILEPRO_IMM16_X1_TLS_IE_HA:
+ tls_type = GOT_TLS_IE;
+ if (info->shared)
+ info->flags |= DF_STATIC_TLS;
+ goto have_got_reference;
+
+ case R_TILEPRO_IMM16_X0_GOT:
+ case R_TILEPRO_IMM16_X1_GOT:
+ case R_TILEPRO_IMM16_X0_GOT_LO:
+ case R_TILEPRO_IMM16_X1_GOT_LO:
+ case R_TILEPRO_IMM16_X0_GOT_HI:
+ case R_TILEPRO_IMM16_X1_GOT_HI:
+ case R_TILEPRO_IMM16_X0_GOT_HA:
+ case R_TILEPRO_IMM16_X1_GOT_HA:
+ tls_type = GOT_NORMAL;
+ /* Fall Through */
+
+ have_got_reference:
+ /* This symbol requires a global offset table entry. */
+ {
+ int old_tls_type;
+
+ if (h != NULL)
+ {
+ h->got.refcount += 1;
+ old_tls_type = tilepro_elf_hash_entry(h)->tls_type;
+ }
+ else
+ {
+ bfd_signed_vma *local_got_refcounts;
+
+ /* This is a global offset table entry for a local symbol. */
+ local_got_refcounts = elf_local_got_refcounts (abfd);
+ if (local_got_refcounts == NULL)
+ {
+ bfd_size_type size;
+
+ size = symtab_hdr->sh_info;
+ size *= (sizeof (bfd_signed_vma) + sizeof(char));
+ local_got_refcounts = ((bfd_signed_vma *)
+ bfd_zalloc (abfd, size));
+ if (local_got_refcounts == NULL)
+ return FALSE;
+ elf_local_got_refcounts (abfd) = local_got_refcounts;
+ _bfd_tilepro_elf_local_got_tls_type (abfd)
+ = (char *) (local_got_refcounts + symtab_hdr->sh_info);
+ }
+ local_got_refcounts[r_symndx] += 1;
+ old_tls_type =
+ _bfd_tilepro_elf_local_got_tls_type (abfd) [r_symndx];
+ }
+
+ /* If a TLS symbol is accessed using IE at least once,
+ there is no point to use dynamic model for it. */
+ if (old_tls_type != tls_type && old_tls_type != GOT_UNKNOWN
+ && (old_tls_type != GOT_TLS_GD
+ || tls_type != GOT_TLS_IE))
+ {
+ if (old_tls_type == GOT_TLS_IE && tls_type == GOT_TLS_GD)
+ tls_type = old_tls_type;
+ else
+ {
+ (*_bfd_error_handler)
+ (_("%B: `%s' accessed both as normal and thread local symbol"),
+ abfd, h ? h->root.root.string : "<local>");
+ return FALSE;
+ }
+ }
+
+ if (old_tls_type != tls_type)
+ {
+ if (h != NULL)
+ tilepro_elf_hash_entry (h)->tls_type = tls_type;
+ else
+ _bfd_tilepro_elf_local_got_tls_type (abfd) [r_symndx] =
+ tls_type;
+ }
+ }
+
+ if (htab->elf.sgot == NULL)
+ {
+ if (!tilepro_elf_create_got_section (htab->elf.dynobj, info))
+ return FALSE;
+ }
+ break;
+
+ case R_TILEPRO_TLS_GD_CALL:
+ if (info->shared)
+ {
+ /* These are basically R_TILEPRO_JOFFLONG_X1_PLT relocs
+ against __tls_get_addr. */
+ struct bfd_link_hash_entry *bh = NULL;
+ if (! _bfd_generic_link_add_one_symbol (info, abfd,
+ "__tls_get_addr", 0,
+ bfd_und_section_ptr, 0,
+ NULL, FALSE, FALSE,
+ &bh))
+ return FALSE;
+ h = (struct elf_link_hash_entry *) bh;
+ }
+ else
+ break;
+ /* Fall through */
+
+ case R_TILEPRO_JOFFLONG_X1_PLT:
+ /* 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)
+ {
+ h->needs_plt = 1;
+ h->plt.refcount += 1;
+ }
+ break;
+
+ case R_TILEPRO_32_PCREL:
+ case R_TILEPRO_16_PCREL:
+ case R_TILEPRO_8_PCREL:
+ case R_TILEPRO_IMM16_X0_PCREL:
+ case R_TILEPRO_IMM16_X1_PCREL:
+ case R_TILEPRO_IMM16_X0_LO_PCREL:
+ case R_TILEPRO_IMM16_X1_LO_PCREL:
+ case R_TILEPRO_IMM16_X0_HI_PCREL:
+ case R_TILEPRO_IMM16_X1_HI_PCREL:
+ case R_TILEPRO_IMM16_X0_HA_PCREL:
+ case R_TILEPRO_IMM16_X1_HA_PCREL:
+ if (h != NULL)
+ h->non_got_ref = 1;
+
+ if (h != NULL
+ && strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0)
+ break;
+ /* Fall through. */
+
+ case R_TILEPRO_32:
+ case R_TILEPRO_16:
+ case R_TILEPRO_8:
+ case R_TILEPRO_LO16:
+ case R_TILEPRO_HI16:
+ case R_TILEPRO_HA16:
+ case R_TILEPRO_COPY:
+ case R_TILEPRO_GLOB_DAT:
+ case R_TILEPRO_JMP_SLOT:
+ case R_TILEPRO_RELATIVE:
+ case R_TILEPRO_BROFF_X1:
+ case R_TILEPRO_JOFFLONG_X1:
+ case R_TILEPRO_IMM8_X0:
+ case R_TILEPRO_IMM8_Y0:
+ case R_TILEPRO_IMM8_X1:
+ case R_TILEPRO_IMM8_Y1:
+ case R_TILEPRO_DEST_IMM8_X1:
+ case R_TILEPRO_MT_IMM15_X1:
+ case R_TILEPRO_MF_IMM15_X1:
+ case R_TILEPRO_IMM16_X0:
+ case R_TILEPRO_IMM16_X1:
+ case R_TILEPRO_IMM16_X0_LO:
+ case R_TILEPRO_IMM16_X1_LO:
+ case R_TILEPRO_IMM16_X0_HI:
+ case R_TILEPRO_IMM16_X1_HI:
+ case R_TILEPRO_IMM16_X0_HA:
+ case R_TILEPRO_IMM16_X1_HA:
+ case R_TILEPRO_MMSTART_X0:
+ case R_TILEPRO_MMEND_X0:
+ case R_TILEPRO_MMSTART_X1:
+ case R_TILEPRO_MMEND_X1:
+ case R_TILEPRO_SHAMT_X0:
+ case R_TILEPRO_SHAMT_X1:
+ case R_TILEPRO_SHAMT_Y0:
+ case R_TILEPRO_SHAMT_Y1:
+ if (h != NULL)
+ h->non_got_ref = 1;
+
+ r_tilepro_plt32:
+ if (h != NULL && !info->shared)
+ {
+ /* We may need a .plt entry if the function this reloc
+ refers to is in a shared lib. */
+ h->plt.refcount += 1;
+ }
+
+ /* 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). In case of a weak definition,
+ DEF_REGULAR may be cleared later by a strong definition in
+ a shared library. We account for that possibility below by
+ storing information in the relocs_copied field of the hash
+ table entry. A similar situation occurs when creating
+ shared libraries and symbol visibility changes render the
+ symbol local.
+
+ If on the other hand, we are creating an executable, we
+ may need to keep relocations for symbols satisfied by a
+ dynamic library if we manage to avoid copy relocs for the
+ symbol. */
+ if ((info->shared
+ && (sec->flags & SEC_ALLOC) != 0
+ && (! tilepro_elf_howto_table[r_type].pc_relative
+ || (h != NULL
+ && (! info->symbolic
+ || h->root.type == bfd_link_hash_defweak
+ || !h->def_regular))))
+ || (!info->shared
+ && (sec->flags & SEC_ALLOC) != 0
+ && h != NULL
+ && (h->root.type == bfd_link_hash_defweak
+ || !h->def_regular)))
+ {
+ struct tilepro_elf_dyn_relocs *p;
+ struct tilepro_elf_dyn_relocs **head;
+
+ /* 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)
+ {
+ sreloc = _bfd_elf_make_dynamic_reloc_section
+ (sec, htab->elf.dynobj, 2, abfd, /*rela?*/ TRUE);
+
+ if (sreloc == NULL)
+ return FALSE;
+ }
+
+ /* If this is a global symbol, we count the number of
+ relocations we need for this symbol. */
+ if (h != NULL)
+ head =
+ &((struct tilepro_elf_link_hash_entry *) h)->dyn_relocs;
+ else
+ {
+ /* Track dynamic relocs needed for local syms too.
+ We really need local syms available to do this
+ easily. Oh well. */
+
+ asection *s;
+ void *vpp;
+ Elf_Internal_Sym *isym;
+
+ isym = bfd_sym_from_r_symndx (&htab->sym_cache,
+ abfd, r_symndx);
+ if (isym == NULL)
+ return FALSE;
+
+ s = bfd_section_from_elf_index (abfd, isym->st_shndx);
+ if (s == NULL)
+ s = sec;
+
+ vpp = &elf_section_data (s)->local_dynrel;
+ head = (struct tilepro_elf_dyn_relocs **) vpp;
+ }
+
+ p = *head;
+ if (p == NULL || p->sec != sec)
+ {
+ bfd_size_type amt = sizeof *p;
+ p = ((struct tilepro_elf_dyn_relocs *)
+ bfd_alloc (htab->elf.dynobj, amt));
+ if (p == NULL)
+ return FALSE;
+ p->next = *head;
+ *head = p;
+ p->sec = sec;
+ p->count = 0;
+ p->pc_count = 0;
+ }
+
+ p->count += 1;
+ if (tilepro_elf_howto_table[r_type].pc_relative)
+ p->pc_count += 1;
+ }
+
+ break;
+
+ case R_TILEPRO_GNU_VTINHERIT:
+ if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
+ return FALSE;
+ break;
+
+ case R_TILEPRO_GNU_VTENTRY:
+ if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
+ return FALSE;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ return TRUE;
+}
+
+
+static asection *
+tilepro_elf_gc_mark_hook (asection *sec,
+ 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_TILEPRO_GNU_VTINHERIT:
+ case R_TILEPRO_GNU_VTENTRY:
+ return NULL;
+ }
+ }
+
+ /* FIXME: The test here, in check_relocs and in relocate_section
+ dealing with TLS optimization, ought to be !info->executable. */
+ if (info->shared)
+ {
+ switch (ELF32_R_TYPE (rel->r_info))
+ {
+ case R_TILEPRO_TLS_GD_CALL:
+ /* This reloc implicitly references __tls_get_addr. We know
+ another reloc will reference the same symbol as the one
+ on this reloc, so the real symbol and section will be
+ gc marked when processing the other reloc. That lets
+ us handle __tls_get_addr here. */
+ h = elf_link_hash_lookup (elf_hash_table (info), "__tls_get_addr",
+ FALSE, FALSE, TRUE);
+ BFD_ASSERT (h != NULL);
+ h->mark = 1;
+ if (h->u.weakdef != NULL)
+ h->u.weakdef->mark = 1;
+ sym = NULL;
+ }
+ }
+
+ return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
+}
+
+/* Update the got entry reference counts for the section being removed. */
+static bfd_boolean
+tilepro_elf_gc_sweep_hook (bfd *abfd, struct bfd_link_info *info,
+ asection *sec, const Elf_Internal_Rela *relocs)
+{
+ struct tilepro_elf_link_hash_table *htab;
+ Elf_Internal_Shdr *symtab_hdr;
+ struct elf_link_hash_entry **sym_hashes;
+ bfd_signed_vma *local_got_refcounts;
+ const Elf_Internal_Rela *rel, *relend;
+
+ if (info->relocatable)
+ return TRUE;
+
+ BFD_ASSERT (is_tilepro_elf (abfd) || sec->reloc_count == 0);
+
+ elf_section_data (sec)->local_dynrel = NULL;
+
+ htab = tilepro_elf_hash_table (info);
+ BFD_ASSERT (htab != NULL);
+ symtab_hdr = &elf_symtab_hdr (abfd);
+ 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++)
+ {
+ unsigned long r_symndx;
+ unsigned int r_type;
+ struct elf_link_hash_entry *h = NULL;
+
+ r_symndx = ELF32_R_SYM (rel->r_info);
+ if (r_symndx >= symtab_hdr->sh_info)
+ {
+ struct tilepro_elf_link_hash_entry *eh;
+ struct tilepro_elf_dyn_relocs **pp;
+ struct tilepro_elf_dyn_relocs *p;
+
+ 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;
+ eh = (struct tilepro_elf_link_hash_entry *) h;
+ for (pp = &eh->dyn_relocs; (p = *pp) != NULL; pp = &p->next)
+ if (p->sec == sec)
+ {
+ /* Everything must go for SEC. */
+ *pp = p->next;
+ break;
+ }
+ }
+
+ r_type = ELF32_R_TYPE (rel->r_info);
+ r_type = tilepro_elf_tls_transition (info, r_type, h != NULL);
+ switch (r_type)
+ {
+ case R_TILEPRO_IMM16_X0_GOT:
+ case R_TILEPRO_IMM16_X1_GOT:
+ case R_TILEPRO_IMM16_X0_GOT_LO:
+ case R_TILEPRO_IMM16_X1_GOT_LO:
+ case R_TILEPRO_IMM16_X0_GOT_HI:
+ case R_TILEPRO_IMM16_X1_GOT_HI:
+ case R_TILEPRO_IMM16_X0_GOT_HA:
+ case R_TILEPRO_IMM16_X1_GOT_HA:
+ case R_TILEPRO_IMM16_X0_TLS_GD:
+ case R_TILEPRO_IMM16_X1_TLS_GD:
+ case R_TILEPRO_IMM16_X0_TLS_GD_LO:
+ case R_TILEPRO_IMM16_X1_TLS_GD_LO:
+ case R_TILEPRO_IMM16_X0_TLS_GD_HI:
+ case R_TILEPRO_IMM16_X1_TLS_GD_HI:
+ case R_TILEPRO_IMM16_X0_TLS_GD_HA:
+ case R_TILEPRO_IMM16_X1_TLS_GD_HA:
+ case R_TILEPRO_IMM16_X0_TLS_IE:
+ case R_TILEPRO_IMM16_X1_TLS_IE:
+ case R_TILEPRO_IMM16_X0_TLS_IE_LO:
+ case R_TILEPRO_IMM16_X1_TLS_IE_LO:
+ case R_TILEPRO_IMM16_X0_TLS_IE_HI:
+ case R_TILEPRO_IMM16_X1_TLS_IE_HI:
+ case R_TILEPRO_IMM16_X0_TLS_IE_HA:
+ case R_TILEPRO_IMM16_X1_TLS_IE_HA:
+ if (h != NULL)
+ {
+ if (h->got.refcount > 0)
+ h->got.refcount--;
+ }
+ else
+ {
+ if (local_got_refcounts &&
+ local_got_refcounts[r_symndx] > 0)
+ local_got_refcounts[r_symndx]--;
+ }
+ break;
+
+ case R_TILEPRO_32_PCREL:
+ case R_TILEPRO_16_PCREL:
+ case R_TILEPRO_8_PCREL:
+ case R_TILEPRO_IMM16_X0_PCREL:
+ case R_TILEPRO_IMM16_X1_PCREL:
+ case R_TILEPRO_IMM16_X0_LO_PCREL:
+ case R_TILEPRO_IMM16_X1_LO_PCREL:
+ case R_TILEPRO_IMM16_X0_HI_PCREL:
+ case R_TILEPRO_IMM16_X1_HI_PCREL:
+ case R_TILEPRO_IMM16_X0_HA_PCREL:
+ case R_TILEPRO_IMM16_X1_HA_PCREL:
+ if (h != NULL
+ && strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0)
+ break;
+ /* Fall through. */
+
+ case R_TILEPRO_32:
+ case R_TILEPRO_16:
+ case R_TILEPRO_8:
+ case R_TILEPRO_LO16:
+ case R_TILEPRO_HI16:
+ case R_TILEPRO_HA16:
+ case R_TILEPRO_COPY:
+ case R_TILEPRO_GLOB_DAT:
+ case R_TILEPRO_JMP_SLOT:
+ case R_TILEPRO_RELATIVE:
+ case R_TILEPRO_BROFF_X1:
+ case R_TILEPRO_JOFFLONG_X1:
+ case R_TILEPRO_IMM8_X0:
+ case R_TILEPRO_IMM8_Y0:
+ case R_TILEPRO_IMM8_X1:
+ case R_TILEPRO_IMM8_Y1:
+ case R_TILEPRO_DEST_IMM8_X1:
+ case R_TILEPRO_MT_IMM15_X1:
+ case R_TILEPRO_MF_IMM15_X1:
+ case R_TILEPRO_IMM16_X0:
+ case R_TILEPRO_IMM16_X1:
+ case R_TILEPRO_IMM16_X0_LO:
+ case R_TILEPRO_IMM16_X1_LO:
+ case R_TILEPRO_IMM16_X0_HI:
+ case R_TILEPRO_IMM16_X1_HI:
+ case R_TILEPRO_IMM16_X0_HA:
+ case R_TILEPRO_IMM16_X1_HA:
+ case R_TILEPRO_MMSTART_X0:
+ case R_TILEPRO_MMEND_X0:
+ case R_TILEPRO_MMSTART_X1:
+ case R_TILEPRO_MMEND_X1:
+ case R_TILEPRO_SHAMT_X0:
+ case R_TILEPRO_SHAMT_X1:
+ case R_TILEPRO_SHAMT_Y0:
+ case R_TILEPRO_SHAMT_Y1:
+ if (info->shared)
+ break;
+ /* Fall through. */
+
+ case R_TILEPRO_JOFFLONG_X1_PLT:
+ if (h != NULL)
+ {
+ 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 bfd_boolean
+tilepro_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
+ struct elf_link_hash_entry *h)
+{
+ struct tilepro_elf_link_hash_table *htab;
+ struct tilepro_elf_link_hash_entry * eh;
+ struct tilepro_elf_dyn_relocs *p;
+ asection *s;
+
+ htab = tilepro_elf_hash_table (info);
+ BFD_ASSERT (htab != NULL);
+
+ /* Make sure we know what is going on here. */
+ BFD_ASSERT (htab->elf.dynobj != NULL
+ && (h->needs_plt
+ || h->u.weakdef != NULL
+ || (h->def_dynamic
+ && h->ref_regular
+ && !h->def_regular)));
+
+ /* 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). */
+ if (h->type == STT_FUNC || h->needs_plt)
+ {
+ if (h->plt.refcount <= 0
+ || SYMBOL_CALLS_LOCAL (info, h)
+ || (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
+ && h->root.type == bfd_link_hash_undefweak))
+ {
+ /* This case can occur if we saw a R_TILEPRO_JOFFLONG_X1_PLT
+ reloc in an input file, but the symbol was never referred
+ to by a dynamic object, or if all references were garbage
+ collected. In such a case, we don't actually need to build
+ a procedure linkage table, and we can just do a
+ R_TILEPRO_JOFFLONG_X1 relocation instead. */
+ h->plt.offset = (bfd_vma) -1;
+ h->needs_plt = 0;
+ }
+
+ return TRUE;
+ }
+ else
+ 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->u.weakdef != NULL)
+ {
+ BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
+ || h->u.weakdef->root.type == bfd_link_hash_defweak);
+ h->root.u.def.section = h->u.weakdef->root.u.def.section;
+ h->root.u.def.value = h->u.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;
+
+ /* If there are no references to this symbol that do not use the
+ GOT, we don't need to generate a copy reloc. */
+ if (!h->non_got_ref)
+ return TRUE;
+
+ /* If -z nocopyreloc was given, we won't generate them either. */
+ if (info->nocopyreloc)
+ {
+ h->non_got_ref = 0;
+ return TRUE;
+ }
+
+ eh = (struct tilepro_elf_link_hash_entry *) h;
+ for (p = eh->dyn_relocs; p != NULL; p = p->next)
+ {
+ s = p->sec->output_section;
+ if (s != NULL && (s->flags & SEC_READONLY) != 0)
+ break;
+ }
+
+ /* If we didn't find any dynamic relocs in read-only sections, then
+ we'll be keeping the dynamic relocs and avoiding the copy reloc. */
+ if (p == NULL)
+ {
+ h->non_got_ref = 0;
+ 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. */
+
+ /* We must generate a R_TILEPRO_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 && h->size != 0)
+ {
+ htab->srelbss->size += TILEPRO_ELF_RELA_BYTES;
+ h->needs_copy = 1;
+ }
+
+ return _bfd_elf_adjust_dynamic_copy (h, htab->sdynbss);
+}
+
+/* Allocate space in .plt, .got and associated reloc sections for
+ dynamic relocs. */
+
+static bfd_boolean
+allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
+{
+ struct bfd_link_info *info;
+ struct tilepro_elf_link_hash_table *htab;
+ struct tilepro_elf_link_hash_entry *eh;
+ struct tilepro_elf_dyn_relocs *p;
+
+ if (h->root.type == bfd_link_hash_indirect)
+ return TRUE;
+
+ info = (struct bfd_link_info *) inf;
+ htab = tilepro_elf_hash_table (info);
+ BFD_ASSERT (htab != NULL);
+
+ if (htab->elf.dynamic_sections_created
+ && h->plt.refcount > 0)
+ {
+ /* Make sure this symbol is output as a dynamic symbol.
+ Undefined weak syms won't yet be marked as dynamic. */
+ if (h->dynindx == -1
+ && !h->forced_local)
+ {
+ if (! bfd_elf_link_record_dynamic_symbol (info, h))
+ return FALSE;
+ }
+
+ if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, info->shared, h))
+ {
+ asection *s = htab->elf.splt;
+
+ /* Allocate room for the header. */
+ if (s->size == 0)
+ {
+ s->size = PLT_ENTRY_SIZE;
+ }
+
+ h->plt.offset = s->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->def_regular)
+ {
+ h->root.u.def.section = s;
+ h->root.u.def.value = h->plt.offset;
+ }
+
+ /* Make room for this entry. */
+ s->size += PLT_ENTRY_SIZE;
+
+ /* We also need to make an entry in the .got.plt section. */
+ htab->elf.sgotplt->size += GOT_ENTRY_SIZE;
+
+ /* We also need to make an entry in the .rela.plt section. */
+ htab->elf.srelplt->size += TILEPRO_ELF_RELA_BYTES;
+ }
+ else
+ {
+ h->plt.offset = (bfd_vma) -1;
+ h->needs_plt = 0;
+ }
+ }
+ else
+ {
+ h->plt.offset = (bfd_vma) -1;
+ h->needs_plt = 0;
+ }
+
+ /* If a TLS_IE symbol is now local to the binary, make it a TLS_LE
+ requiring no TLS entry. */
+ if (h->got.refcount > 0
+ && !info->shared
+ && h->dynindx == -1
+ && tilepro_elf_hash_entry(h)->tls_type == GOT_TLS_IE)
+ h->got.offset = (bfd_vma) -1;
+ else if (h->got.refcount > 0)
+ {
+ asection *s;
+ bfd_boolean dyn;
+ int tls_type = tilepro_elf_hash_entry(h)->tls_type;
+
+ /* Make sure this symbol is output as a dynamic symbol.
+ Undefined weak syms won't yet be marked as dynamic. */
+ if (h->dynindx == -1
+ && !h->forced_local)
+ {
+ if (! bfd_elf_link_record_dynamic_symbol (info, h))
+ return FALSE;
+ }
+
+ s = htab->elf.sgot;
+ h->got.offset = s->size;
+ s->size += TILEPRO_BYTES_PER_WORD;
+ /* R_TILEPRO_IMM16_Xn_TLS_GD entries need 2 consecutive GOT slots. */
+ if (tls_type == GOT_TLS_GD)
+ s->size += TILEPRO_BYTES_PER_WORD;
+ dyn = htab->elf.dynamic_sections_created;
+ /* R_TILEPRO_IMM16_Xn_TLS_IE_xxx needs one dynamic relocation,
+ R_TILEPRO_IMM16_Xn_TLS_GD_xxx needs two if local symbol and two if
+ global. */
+ if (tls_type == GOT_TLS_GD || tls_type == GOT_TLS_IE)
+ htab->elf.srelgot->size += 2 * TILEPRO_ELF_RELA_BYTES;
+ else if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h))
+ htab->elf.srelgot->size += TILEPRO_ELF_RELA_BYTES;
+ }
+ else
+ h->got.offset = (bfd_vma) -1;
+
+ eh = (struct tilepro_elf_link_hash_entry *) h;
+ if (eh->dyn_relocs == NULL)
+ return TRUE;
+
+ /* In the shared -Bsymbolic case, discard space allocated for
+ dynamic pc-relative relocs against symbols which turn out to be
+ defined in regular objects. For the normal shared case, discard
+ space for pc-relative relocs that have become local due to symbol
+ visibility changes. */
+
+ if (info->shared)
+ {
+ if (SYMBOL_CALLS_LOCAL (info, h))
+ {
+ struct tilepro_elf_dyn_relocs **pp;
+
+ for (pp = &eh->dyn_relocs; (p = *pp) != NULL; )
+ {
+ p->count -= p->pc_count;
+ p->pc_count = 0;
+ if (p->count == 0)
+ *pp = p->next;
+ else
+ pp = &p->next;
+ }
+ }
+
+ /* Also discard relocs on undefined weak syms with non-default
+ visibility. */
+ if (eh->dyn_relocs != NULL
+ && h->root.type == bfd_link_hash_undefweak)
+ {
+ if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
+ eh->dyn_relocs = NULL;
+
+ /* Make sure undefined weak symbols are output as a dynamic
+ symbol in PIEs. */
+ else if (h->dynindx == -1
+ && !h->forced_local)
+ {
+ if (! bfd_elf_link_record_dynamic_symbol (info, h))
+ return FALSE;
+ }
+ }
+ }
+ else
+ {
+ /* For the non-shared case, discard space for relocs against
+ symbols which turn out to need copy relocs or are not
+ dynamic. */
+
+ if (!h->non_got_ref
+ && ((h->def_dynamic
+ && !h->def_regular)
+ || (htab->elf.dynamic_sections_created
+ && (h->root.type == bfd_link_hash_undefweak
+ || h->root.type == bfd_link_hash_undefined))))
+ {
+ /* Make sure this symbol is output as a dynamic symbol.
+ Undefined weak syms won't yet be marked as dynamic. */
+ if (h->dynindx == -1
+ && !h->forced_local)
+ {
+ if (! bfd_elf_link_record_dynamic_symbol (info, h))
+ return FALSE;
+ }
+
+ /* If that succeeded, we know we'll be keeping all the
+ relocs. */
+ if (h->dynindx != -1)
+ goto keep;
+ }
+
+ eh->dyn_relocs = NULL;
+
+ keep: ;
+ }
+
+ /* Finally, allocate space. */
+ for (p = eh->dyn_relocs; p != NULL; p = p->next)
+ {
+ asection *sreloc = elf_section_data (p->sec)->sreloc;
+ sreloc->size += p->count * TILEPRO_ELF_RELA_BYTES;
+ }
+
+ return TRUE;
+}
+
+/* Find any dynamic relocs that apply to read-only sections. */
+
+static bfd_boolean
+readonly_dynrelocs (struct elf_link_hash_entry *h, void *inf)
+{
+ struct tilepro_elf_link_hash_entry *eh;
+ struct tilepro_elf_dyn_relocs *p;
+
+ eh = (struct tilepro_elf_link_hash_entry *) h;
+ for (p = eh->dyn_relocs; p != NULL; p = p->next)
+ {
+ asection *s = p->sec->output_section;
+
+ if (s != NULL && (s->flags & SEC_READONLY) != 0)
+ {
+ struct bfd_link_info *info = (struct bfd_link_info *) inf;
+
+ info->flags |= DF_TEXTREL;
+
+ /* Not an error, just cut short the traversal. */
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+/* Return true if the dynamic symbol for a given section should be
+ omitted when creating a shared library. */
+
+static bfd_boolean
+tilepro_elf_omit_section_dynsym (bfd *output_bfd,
+ struct bfd_link_info *info,
+ asection *p)
+{
+ /* We keep the .got section symbol so that explicit relocations
+ against the _GLOBAL_OFFSET_TABLE_ symbol emitted in PIC mode
+ can be turned into relocations against the .got symbol. */
+ if (strcmp (p->name, ".got") == 0)
+ return FALSE;
+
+ return _bfd_elf_link_omit_section_dynsym (output_bfd, info, p);
+}
+
+/* Set the sizes of the dynamic sections. */
+
+#define ELF32_DYNAMIC_INTERPRETER "/lib/ld.so.1"
+
+static bfd_boolean
+tilepro_elf_size_dynamic_sections (bfd *output_bfd,
+ struct bfd_link_info *info)
+{
+ (void)output_bfd;
+
+ struct tilepro_elf_link_hash_table *htab;
+ bfd *dynobj;
+ asection *s;
+ bfd *ibfd;
+
+ htab = tilepro_elf_hash_table (info);
+ BFD_ASSERT (htab != NULL);
+ dynobj = htab->elf.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->executable)
+ {
+ s = bfd_get_linker_section (dynobj, ".interp");
+ BFD_ASSERT (s != NULL);
+ s->size = sizeof ELF32_DYNAMIC_INTERPRETER;
+ s->contents = (unsigned char *) ELF32_DYNAMIC_INTERPRETER;
+ }
+ }
+
+ /* Set up .got offsets for local syms, and space for local dynamic
+ relocs. */
+ for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next)
+ {
+ bfd_signed_vma *local_got;
+ bfd_signed_vma *end_local_got;
+ char *local_tls_type;
+ bfd_size_type locsymcount;
+ Elf_Internal_Shdr *symtab_hdr;
+ asection *srel;
+
+ if (! is_tilepro_elf (ibfd))
+ continue;
+
+ for (s = ibfd->sections; s != NULL; s = s->next)
+ {
+ struct tilepro_elf_dyn_relocs *p;
+
+ for (p = elf_section_data (s)->local_dynrel; p != NULL; p = p->next)
+ {
+ if (!bfd_is_abs_section (p->sec)
+ && bfd_is_abs_section (p->sec->output_section))
+ {
+ /* Input section has been discarded, either because
+ it is a copy of a linkonce section or due to
+ linker script /DISCARD/, so we'll be discarding
+ the relocs too. */
+ }
+ else if (p->count != 0)
+ {
+ srel = elf_section_data (p->sec)->sreloc;
+ srel->size += p->count * TILEPRO_ELF_RELA_BYTES;
+ if ((p->sec->output_section->flags & SEC_READONLY) != 0)
+ info->flags |= DF_TEXTREL;
+ }
+ }
+ }
+
+ local_got = elf_local_got_refcounts (ibfd);
+ if (!local_got)
+ continue;
+
+ symtab_hdr = &elf_symtab_hdr (ibfd);
+ locsymcount = symtab_hdr->sh_info;
+ end_local_got = local_got + locsymcount;
+ local_tls_type = _bfd_tilepro_elf_local_got_tls_type (ibfd);
+ s = htab->elf.sgot;
+ srel = htab->elf.srelgot;
+ for (; local_got < end_local_got; ++local_got, ++local_tls_type)
+ {
+ if (*local_got > 0)
+ {
+ *local_got = s->size;
+ s->size += TILEPRO_BYTES_PER_WORD;
+ if (*local_tls_type == GOT_TLS_GD)
+ s->size += TILEPRO_BYTES_PER_WORD;
+ if (info->shared
+ || *local_tls_type == GOT_TLS_GD
+ || *local_tls_type == GOT_TLS_IE)
+ srel->size += TILEPRO_ELF_RELA_BYTES;
+ }
+ else
+ *local_got = (bfd_vma) -1;
+ }
+ }
+
+ /* Allocate global sym .plt and .got entries, and space for global
+ sym dynamic relocs. */
+ elf_link_hash_traverse (&htab->elf, allocate_dynrelocs, info);
+
+ if (elf_hash_table (info)->dynamic_sections_created)
+ {
+ /* If the .got section is more than 0x8000 bytes, we add
+ 0x8000 to the value of _GLOBAL_OFFSET_TABLE_, so that 16
+ bit relocations have a greater chance of working. */
+ if (htab->elf.sgot->size >= 0x8000
+ && elf_hash_table (info)->hgot->root.u.def.value == 0)
+ elf_hash_table (info)->hgot->root.u.def.value = 0x8000;
+ }
+
+ if (htab->elf.sgotplt)
+ {
+ struct elf_link_hash_entry *got;
+ got = elf_link_hash_lookup (elf_hash_table (info),
+ "_GLOBAL_OFFSET_TABLE_",
+ FALSE, FALSE, FALSE);
+
+ /* Don't allocate .got.plt section if there are no GOT nor PLT
+ entries and there is no refeence to _GLOBAL_OFFSET_TABLE_. */
+ if ((got == NULL
+ || !got->ref_regular_nonweak)
+ && (htab->elf.sgotplt->size
+ == GOTPLT_HEADER_SIZE)
+ && (htab->elf.splt == NULL
+ || htab->elf.splt->size == 0)
+ && (htab->elf.sgot == NULL
+ || (htab->elf.sgot->size
+ == get_elf_backend_data (output_bfd)->got_header_size)))
+ htab->elf.sgotplt->size = 0;
+ }
+
+ /* The check_relocs and adjust_dynamic_symbol entry points have
+ determined the sizes of the various dynamic sections. Allocate
+ memory for them. */
+ for (s = dynobj->sections; s != NULL; s = s->next)
+ {
+ if ((s->flags & SEC_LINKER_CREATED) == 0)
+ continue;
+
+ if (s == htab->elf.splt
+ || s == htab->elf.sgot
+ || s == htab->elf.sgotplt
+ || s == htab->sdynbss)
+ {
+ /* Strip this section if we don't need it; see the
+ comment below. */
+ }
+ else if (strncmp (s->name, ".rela", 5) == 0)
+ {
+ if (s->size != 0)
+ {
+ /* We use the reloc_count field as a counter if we need
+ to copy relocs into the output file. */
+ s->reloc_count = 0;
+ }
+ }
+ else
+ {
+ /* It's not one of our sections. */
+ continue;
+ }
+
+ if (s->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. */
+ s->flags |= SEC_EXCLUDE;
+ continue;
+ }
+
+ if ((s->flags & SEC_HAS_CONTENTS) == 0)
+ 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->size);
+ if (s->contents == NULL)
+ return FALSE;
+ }
+
+ if (elf_hash_table (info)->dynamic_sections_created)
+ {
+ /* Add some entries to the .dynamic section. We fill in the
+ values later, in tilepro_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. */
+#define add_dynamic_entry(TAG, VAL) \
+ _bfd_elf_add_dynamic_entry (info, TAG, VAL)
+
+ if (info->executable)
+ {
+ if (!add_dynamic_entry (DT_DEBUG, 0))
+ return FALSE;
+ }
+
+ if (htab->elf.srelplt->size != 0)
+ {
+ if (!add_dynamic_entry (DT_PLTGOT, 0)
+ || !add_dynamic_entry (DT_PLTRELSZ, 0)
+ || !add_dynamic_entry (DT_PLTREL, DT_RELA)
+ || !add_dynamic_entry (DT_JMPREL, 0))
+ return FALSE;
+ }
+
+ if (!add_dynamic_entry (DT_RELA, 0)
+ || !add_dynamic_entry (DT_RELASZ, 0)
+ || !add_dynamic_entry (DT_RELAENT, TILEPRO_ELF_RELA_BYTES))
+ return FALSE;
+
+ /* If any dynamic relocs apply to a read-only section,
+ then we need a DT_TEXTREL entry. */
+ if ((info->flags & DF_TEXTREL) == 0)
+ elf_link_hash_traverse (&htab->elf, readonly_dynrelocs, info);
+
+ if (info->flags & DF_TEXTREL)
+ {
+ if (!add_dynamic_entry (DT_TEXTREL, 0))
+ return FALSE;
+ }
+ }
+#undef add_dynamic_entry
+
+ return TRUE;
+}
+
+/* Return the base VMA address which should be subtracted from real addresses
+ when resolving @dtpoff relocation.
+ This is PT_TLS segment p_vaddr. */
+
+static bfd_vma
+dtpoff_base (struct bfd_link_info *info)
+{
+ /* If tls_sec is NULL, we should have signalled an error already. */
+ if (elf_hash_table (info)->tls_sec == NULL)
+ return 0;
+ return elf_hash_table (info)->tls_sec->vma;
+}
+
+/* Return the relocation value for R_TILEPRO_TLS_TPOFF32. */
+
+static bfd_vma
+tpoff (struct bfd_link_info *info, bfd_vma address)
+{
+ struct elf_link_hash_table *htab = elf_hash_table (info);
+
+ /* If tls_sec is NULL, we should have signalled an error already. */
+ if (htab->tls_sec == NULL)
+ return 0;
+
+ return (address - htab->tls_sec->vma);
+}
+
+/* Replace the MASK bits in ADDR with those in INSN, for the next
+ TILEPRO_BUNDLE_SIZE_IN_BYTES bytes. */
+
+static void
+tilepro_replace_insn (bfd_byte *addr, const bfd_byte *mask,
+ const bfd_byte *insn)
+{
+ int i;
+ for (i = 0; i < TILEPRO_BUNDLE_SIZE_IN_BYTES; i++)
+ {
+ addr[i] = (addr[i] & ~mask[i]) | (insn[i] & mask[i]);
+ }
+}
+
+/* Mask to extract the bits corresponding to an instruction in a
+ specific pipe of a bundle. */
+static const bfd_byte insn_mask_X1[] = {
+ 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0x7f
+};
+
+/* Mask to extract the bits corresponding to an instruction in a
+ specific pipe of a bundle, minus the destination operand and the
+ first source operand. */
+static const bfd_byte insn_mask_X0_no_dest_no_srca[] = {
+ 0x00, 0xf0, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00
+};
+
+static const bfd_byte insn_mask_X1_no_dest_no_srca[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0x7f
+};
+
+static const bfd_byte insn_mask_Y0_no_dest_no_srca[] = {
+ 0x00, 0xf0, 0x0f, 0x78, 0x00, 0x00, 0x00, 0x00
+};
+
+static const bfd_byte insn_mask_Y1_no_dest_no_srca[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x07, 0x78
+};
+
+/* Mask to extract the first source operand of an instruction. */
+static const bfd_byte srca_mask_X0[] = {
+ 0xc0, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+static const bfd_byte srca_mask_X1[] = {
+ 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00
+};
+
+/* Various instructions synthesized to support tls references. */
+
+/* move r0, r0 in the X1 pipe, used for tls le. */
+static const bfd_byte insn_tls_le_move_X1[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x33, 0x08
+};
+
+/* move r0, zero in the X0 and X1 pipe, used for tls le. */
+static const bfd_byte insn_tls_le_move_zero_X0X1[] = {
+ 0xc0, 0xff, 0xcf, 0x00, 0xe0, 0xff, 0x33, 0x08
+};
+
+/* lw r0, r0 in the X1 pipe, used for tls ie. */
+static const bfd_byte insn_tls_ie_lw_X1[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x0b, 0x40
+};
+
+/* add r0, r0, tp in various pipes, used for tls ie. */
+static const bfd_byte insn_tls_ie_add_X0X1[] = {
+ 0x00, 0x50, 0x0f, 0x00, 0x00, 0xa8, 0x07, 0x08
+};
+static const bfd_byte insn_tls_ie_add_Y0Y1[] = {
+ 0x00, 0x50, 0x03, 0x08, 0x00, 0xa8, 0x01, 0x8c
+};
+
+/* move r0, r0 in various pipes, used for tls gd. */
+static const bfd_byte insn_tls_gd_add_X0X1[] = {
+ 0x00, 0xf0, 0xcf, 0x00, 0x00, 0xf8, 0x33, 0x08
+};
+static const bfd_byte insn_tls_gd_add_Y0Y1[] = {
+ 0x00, 0xf0, 0x0b, 0x18, 0x00, 0xf8, 0x05, 0x9c
+};
+
+/* Relocate an TILEPRO ELF section.
+
+ 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.
+
+ This function is responsible for adjusting the section contents as
+ necessary, and (if generating a relocatable 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 relocatable 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 bfd_boolean
+tilepro_elf_relocate_section (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)
+{
+ struct tilepro_elf_link_hash_table *htab;
+ Elf_Internal_Shdr *symtab_hdr;
+ struct elf_link_hash_entry **sym_hashes;
+ bfd_vma *local_got_offsets;
+ bfd_vma got_base;
+ asection *sreloc;
+ Elf_Internal_Rela *rel;
+ Elf_Internal_Rela *relend;
+ int num_relocs;
+
+ htab = tilepro_elf_hash_table (info);
+ BFD_ASSERT (htab != NULL);
+ symtab_hdr = &elf_symtab_hdr (input_bfd);
+ 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;
+
+ sreloc = elf_section_data (input_section)->sreloc;
+
+ rel = relocs;
+ num_relocs = input_section->reloc_count;
+ relend = relocs + num_relocs;
+ for (; rel < relend; rel++)
+ {
+ int r_type, tls_type;
+ bfd_boolean is_tls_iele, is_tls_le;
+ reloc_howto_type *howto;
+ unsigned long r_symndx;
+ struct elf_link_hash_entry *h;
+ Elf_Internal_Sym *sym;
+ tilepro_create_func create_func;
+ asection *sec;
+ bfd_vma relocation;
+ bfd_reloc_status_type r;
+ const char *name;
+ bfd_vma off;
+ bfd_boolean is_plt = FALSE;
+
+ bfd_boolean unresolved_reloc;
+
+ r_type = ELF32_R_TYPE (rel->r_info);
+ if (r_type == R_TILEPRO_GNU_VTINHERIT
+ || r_type == R_TILEPRO_GNU_VTENTRY)
+ continue;
+
+ if ((unsigned int)r_type >= NELEMS(tilepro_elf_howto_table))
+ {
+ /* Not clear if we need to check here, but just be paranoid. */
+ (*_bfd_error_handler)
+ (_("%B: unrecognized relocation (0x%x) in section `%A'"),
+ input_bfd, r_type, input_section);
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+
+ howto = tilepro_elf_howto_table + r_type;
+
+ /* This is a final link. */
+ r_symndx = ELF32_R_SYM (rel->r_info);
+ h = NULL;
+ sym = NULL;
+ sec = NULL;
+ unresolved_reloc = FALSE;
+ if (r_symndx < symtab_hdr->sh_info)
+ {
+ sym = local_syms + r_symndx;
+ sec = local_sections[r_symndx];
+ relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
+ }
+ else
+ {
+ bfd_boolean warned ATTRIBUTE_UNUSED;
+ bfd_boolean ignored ATTRIBUTE_UNUSED;
+
+ RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
+ r_symndx, symtab_hdr, sym_hashes,
+ h, sec, relocation,
+ unresolved_reloc, warned, ignored);
+ if (warned)
+ {
+ /* To avoid generating warning messages about truncated
+ relocations, set the relocation's address to be the same as
+ the start of this section. */
+ if (input_section->output_section != NULL)
+ relocation = input_section->output_section->vma;
+ else
+ relocation = 0;
+ }
+ }
+
+ if (sec != NULL && discarded_section (sec))
+ RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+ rel, 1, relend, howto, 0, contents);
+
+ if (info->relocatable)
+ continue;
+
+ 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_type)
+ {
+ case R_TILEPRO_TLS_GD_CALL:
+ case R_TILEPRO_IMM8_X0_TLS_GD_ADD:
+ case R_TILEPRO_IMM8_Y0_TLS_GD_ADD:
+ case R_TILEPRO_IMM8_X1_TLS_GD_ADD:
+ case R_TILEPRO_IMM8_Y1_TLS_GD_ADD:
+ case R_TILEPRO_IMM16_X0_TLS_GD_HA:
+ case R_TILEPRO_IMM16_X1_TLS_GD_HA:
+ case R_TILEPRO_IMM16_X0_TLS_IE_HA:
+ case R_TILEPRO_IMM16_X1_TLS_IE_HA:
+ tls_type = GOT_UNKNOWN;
+ if (h == NULL && local_got_offsets)
+ tls_type =
+ _bfd_tilepro_elf_local_got_tls_type (input_bfd) [r_symndx];
+ else if (h != NULL)
+ tls_type = tilepro_elf_hash_entry(h)->tls_type;
+
+ is_tls_iele = (! info->shared || tls_type == GOT_TLS_IE);
+ is_tls_le = is_tls_iele && (!info->shared
+ && (h == NULL || h->dynindx == -1));
+
+ if (r_type == R_TILEPRO_TLS_GD_CALL)
+ {
+ if (is_tls_le)
+ {
+ /* GD -> LE */
+ tilepro_replace_insn (contents + rel->r_offset,
+ insn_mask_X1, insn_tls_le_move_X1);
+ continue;
+ }
+ else if (is_tls_iele)
+ {
+ /* GD -> IE */
+ tilepro_replace_insn (contents + rel->r_offset,
+ insn_mask_X1, insn_tls_ie_lw_X1);
+ continue;
+ }
+
+ /* GD -> GD */
+ h = (struct elf_link_hash_entry *)
+ bfd_link_hash_lookup (info->hash, "__tls_get_addr", FALSE,
+ FALSE, TRUE);
+ BFD_ASSERT (h != NULL);
+ r_type = R_TILEPRO_JOFFLONG_X1_PLT;
+ howto = tilepro_elf_howto_table + r_type;
+ }
+ else if (r_type == R_TILEPRO_IMM16_X0_TLS_GD_HA
+ || r_type == R_TILEPRO_IMM16_X0_TLS_IE_HA)
+ {
+ if (is_tls_le)
+ tilepro_replace_insn (contents + rel->r_offset, srca_mask_X0,
+ insn_tls_le_move_zero_X0X1);
+ }
+ else if (r_type == R_TILEPRO_IMM16_X1_TLS_GD_HA
+ || r_type == R_TILEPRO_IMM16_X1_TLS_IE_HA)
+ {
+ if (is_tls_le)
+ tilepro_replace_insn (contents + rel->r_offset, srca_mask_X1,
+ insn_tls_le_move_zero_X0X1);
+ }
+ else
+ {
+ const bfd_byte *mask = NULL;
+ const bfd_byte *add_insn = NULL;
+
+ switch (r_type)
+ {
+ case R_TILEPRO_IMM8_X0_TLS_GD_ADD:
+ add_insn = is_tls_iele ? insn_tls_ie_add_X0X1
+ : insn_tls_gd_add_X0X1;
+ mask = insn_mask_X0_no_dest_no_srca;
+ break;
+ case R_TILEPRO_IMM8_X1_TLS_GD_ADD:
+ add_insn = is_tls_iele ? insn_tls_ie_add_X0X1
+ : insn_tls_gd_add_X0X1;
+ mask = insn_mask_X1_no_dest_no_srca;
+ break;
+ case R_TILEPRO_IMM8_Y0_TLS_GD_ADD:
+ add_insn = is_tls_iele ? insn_tls_ie_add_Y0Y1
+ : insn_tls_gd_add_Y0Y1;
+ mask = insn_mask_Y0_no_dest_no_srca;
+ break;
+ case R_TILEPRO_IMM8_Y1_TLS_GD_ADD:
+ add_insn = is_tls_iele ? insn_tls_ie_add_Y0Y1
+ : insn_tls_gd_add_Y0Y1;
+ mask = insn_mask_Y1_no_dest_no_srca;
+ break;
+ }
+
+ tilepro_replace_insn (contents + rel->r_offset, mask, add_insn);
+
+ continue;
+ }
+ break;
+ case R_TILEPRO_TLS_IE_LOAD:
+ if (!info->shared && (h == NULL || h->dynindx == -1))
+ /* IE -> LE */
+ tilepro_replace_insn (contents + rel->r_offset,
+ insn_mask_X1_no_dest_no_srca,
+ insn_tls_le_move_X1);
+ else
+ /* IE -> IE */
+ tilepro_replace_insn (contents + rel->r_offset,
+ insn_mask_X1_no_dest_no_srca,
+ insn_tls_ie_lw_X1);
+ continue;
+ break;
+ default:
+ break;
+ }
+
+ switch (r_type)
+ {
+ case R_TILEPRO_IMM16_X0_GOT:
+ case R_TILEPRO_IMM16_X1_GOT:
+ case R_TILEPRO_IMM16_X0_GOT_LO:
+ case R_TILEPRO_IMM16_X1_GOT_LO:
+ case R_TILEPRO_IMM16_X0_GOT_HI:
+ case R_TILEPRO_IMM16_X1_GOT_HI:
+ case R_TILEPRO_IMM16_X0_GOT_HA:
+ case R_TILEPRO_IMM16_X1_GOT_HA:
+ /* Relocation is to the entry for this symbol in the global
+ offset table. */
+ if (htab->elf.sgot == NULL)
+ abort ();
+
+ if (h != NULL)
+ {
+ bfd_boolean dyn;
+
+ off = h->got.offset;
+ BFD_ASSERT (off != (bfd_vma) -1);
+ dyn = elf_hash_table (info)->dynamic_sections_created;
+
+ if (! WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h)
+ || (info->shared
+ && SYMBOL_REFERENCES_LOCAL (info, h)))
+ {
+ /* 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 for 32-bit, 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,
+ htab->elf.sgot->contents + off);
+ h->got.offset |= 1;
+ }
+ }
+ else
+ unresolved_reloc = FALSE;
+ }
+ 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 on 32-bit.
+ We use the least significant bit to record
+ whether we have already processed this entry. */
+ if ((off & 1) != 0)
+ off &= ~1;
+ else
+ {
+ if (info->shared)
+ {
+ asection *s;
+ Elf_Internal_Rela outrel;
+
+ /* We need to generate a R_TILEPRO_RELATIVE reloc
+ for the dynamic linker. */
+ s = htab->elf.srelgot;
+ BFD_ASSERT (s != NULL);
+
+ outrel.r_offset = (htab->elf.sgot->output_section->vma
+ + htab->elf.sgot->output_offset
+ + off);
+ outrel.r_info = ELF32_R_INFO (0, R_TILEPRO_RELATIVE);
+ outrel.r_addend = relocation;
+ relocation = 0;
+ tilepro_elf_append_rela_32 (output_bfd, s, &outrel);
+ }
+
+ bfd_put_32 (output_bfd, relocation,
+ htab->elf.sgot->contents + off);
+ local_got_offsets[r_symndx] |= 1;
+ }
+ }
+ relocation = off - got_base;
+ break;
+
+ case R_TILEPRO_JOFFLONG_X1_PLT:
+ /* Relocation is to the entry for this symbol in the
+ procedure linkage table. */
+ BFD_ASSERT (h != NULL);
+
+ if (h->plt.offset == (bfd_vma) -1 || htab->elf.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 = (htab->elf.splt->output_section->vma
+ + htab->elf.splt->output_offset
+ + h->plt.offset);
+ unresolved_reloc = FALSE;
+ break;
+
+ case R_TILEPRO_32_PCREL:
+ case R_TILEPRO_16_PCREL:
+ case R_TILEPRO_8_PCREL:
+ case R_TILEPRO_IMM16_X0_PCREL:
+ case R_TILEPRO_IMM16_X1_PCREL:
+ case R_TILEPRO_IMM16_X0_LO_PCREL:
+ case R_TILEPRO_IMM16_X1_LO_PCREL:
+ case R_TILEPRO_IMM16_X0_HI_PCREL:
+ case R_TILEPRO_IMM16_X1_HI_PCREL:
+ case R_TILEPRO_IMM16_X0_HA_PCREL:
+ case R_TILEPRO_IMM16_X1_HA_PCREL:
+ if (h != NULL
+ && strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0)
+ break;
+ /* Fall through. */
+ case R_TILEPRO_32:
+ case R_TILEPRO_16:
+ case R_TILEPRO_8:
+ case R_TILEPRO_LO16:
+ case R_TILEPRO_HI16:
+ case R_TILEPRO_HA16:
+ case R_TILEPRO_COPY:
+ case R_TILEPRO_GLOB_DAT:
+ case R_TILEPRO_JMP_SLOT:
+ case R_TILEPRO_RELATIVE:
+ case R_TILEPRO_BROFF_X1:
+ case R_TILEPRO_JOFFLONG_X1:
+ case R_TILEPRO_IMM8_X0:
+ case R_TILEPRO_IMM8_Y0:
+ case R_TILEPRO_IMM8_X1:
+ case R_TILEPRO_IMM8_Y1:
+ case R_TILEPRO_DEST_IMM8_X1:
+ case R_TILEPRO_MT_IMM15_X1:
+ case R_TILEPRO_MF_IMM15_X1:
+ case R_TILEPRO_IMM16_X0:
+ case R_TILEPRO_IMM16_X1:
+ case R_TILEPRO_IMM16_X0_LO:
+ case R_TILEPRO_IMM16_X1_LO:
+ case R_TILEPRO_IMM16_X0_HI:
+ case R_TILEPRO_IMM16_X1_HI:
+ case R_TILEPRO_IMM16_X0_HA:
+ case R_TILEPRO_IMM16_X1_HA:
+ case R_TILEPRO_MMSTART_X0:
+ case R_TILEPRO_MMEND_X0:
+ case R_TILEPRO_MMSTART_X1:
+ case R_TILEPRO_MMEND_X1:
+ case R_TILEPRO_SHAMT_X0:
+ case R_TILEPRO_SHAMT_X1:
+ case R_TILEPRO_SHAMT_Y0:
+ case R_TILEPRO_SHAMT_Y1:
+ if ((input_section->flags & SEC_ALLOC) == 0)
+ break;
+
+ if ((info->shared
+ && (h == NULL
+ || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
+ || h->root.type != bfd_link_hash_undefweak)
+ && (! howto->pc_relative
+ || !SYMBOL_CALLS_LOCAL (info, h)))
+ || (!info->shared
+ && h != NULL
+ && h->dynindx != -1
+ && !h->non_got_ref
+ && ((h->def_dynamic
+ && !h->def_regular)
+ || h->root.type == bfd_link_hash_undefweak
+ || h->root.type == bfd_link_hash_undefined)))
+ {
+ Elf_Internal_Rela outrel;
+ bfd_boolean skip, relocate = FALSE;
+
+ /* When generating a shared object, these relocations
+ are copied into the output file to be resolved at run
+ time. */
+
+ BFD_ASSERT (sreloc != NULL);
+
+ skip = FALSE;
+
+ outrel.r_offset =
+ _bfd_elf_section_offset (output_bfd, info, input_section,
+ rel->r_offset);
+ if (outrel.r_offset == (bfd_vma) -1)
+ skip = TRUE;
+ else if (outrel.r_offset == (bfd_vma) -2)
+ skip = TRUE, relocate = TRUE;
+ outrel.r_offset += (input_section->output_section->vma
+ + input_section->output_offset);
+
+ switch (r_type)
+ {
+ case R_TILEPRO_32_PCREL:
+ case R_TILEPRO_16_PCREL:
+ case R_TILEPRO_8_PCREL:
+ /* If the symbol is not dynamic, we should not keep
+ a dynamic relocation. But an .rela.* slot has been
+ allocated for it, output R_TILEPRO_NONE.
+ FIXME: Add code tracking needed dynamic relocs as
+ e.g. i386 has. */
+ if (h->dynindx == -1)
+ skip = TRUE, relocate = TRUE;
+ 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 &&
+ h->dynindx != -1
+ && (! is_plt
+ || !info->shared
+ || !SYMBOLIC_BIND (info, h)
+ || !h->def_regular))
+ {
+ 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_TILEPRO_32)
+ {
+ outrel.r_info = ELF32_R_INFO (0, R_TILEPRO_RELATIVE);
+ outrel.r_addend = relocation + rel->r_addend;
+ }
+ else
+ {
+ long indx;
+
+ outrel.r_addend = relocation + rel->r_addend;
+
+ if (is_plt)
+ sec = htab->elf.splt;
+
+ if (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;
+
+ /* We are turning this relocation into one
+ against a section symbol. It would be
+ proper to subtract the symbol's value,
+ osec->vma, from the emitted reloc addend,
+ but ld.so expects buggy relocs. */
+ osec = sec->output_section;
+ indx = elf_section_data (osec)->dynindx;
+
+ if (indx == 0)
+ {
+ osec = htab->elf.text_index_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)
+ (_("%B: probably compiled without -fPIC?"),
+ input_bfd);
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+ }
+
+ outrel.r_info = ELF32_R_INFO (indx, r_type);
+ }
+ }
+
+ tilepro_elf_append_rela_32 (output_bfd, sreloc, &outrel);
+
+ /* This reloc will be computed at runtime, so there's no
+ need to do anything now. */
+ if (! relocate)
+ continue;
+ }
+ break;
+
+ case R_TILEPRO_IMM16_X0_TLS_LE:
+ case R_TILEPRO_IMM16_X1_TLS_LE:
+ case R_TILEPRO_IMM16_X0_TLS_LE_LO:
+ case R_TILEPRO_IMM16_X1_TLS_LE_LO:
+ case R_TILEPRO_IMM16_X0_TLS_LE_HI:
+ case R_TILEPRO_IMM16_X1_TLS_LE_HI:
+ case R_TILEPRO_IMM16_X0_TLS_LE_HA:
+ case R_TILEPRO_IMM16_X1_TLS_LE_HA:
+ if (info->shared)
+ {
+ Elf_Internal_Rela outrel;
+ bfd_boolean skip;
+
+ BFD_ASSERT (sreloc != NULL);
+ skip = FALSE;
+ outrel.r_offset =
+ _bfd_elf_section_offset (output_bfd, info, input_section,
+ rel->r_offset);
+ if (outrel.r_offset == (bfd_vma) -1)
+ skip = TRUE;
+ else if (outrel.r_offset == (bfd_vma) -2)
+ skip = TRUE;
+ outrel.r_offset += (input_section->output_section->vma
+ + input_section->output_offset);
+ if (skip)
+ memset (&outrel, 0, sizeof outrel);
+ else
+ {
+ outrel.r_info = ELF32_R_INFO (0, r_type);
+ outrel.r_addend = relocation - dtpoff_base (info)
+ + rel->r_addend;
+ }
+
+ tilepro_elf_append_rela_32 (output_bfd, sreloc, &outrel);
+ continue;
+ }
+ relocation = tpoff (info, relocation);
+ break;
+
+ case R_TILEPRO_IMM16_X0_TLS_GD:
+ case R_TILEPRO_IMM16_X1_TLS_GD:
+ case R_TILEPRO_IMM16_X0_TLS_GD_LO:
+ case R_TILEPRO_IMM16_X1_TLS_GD_LO:
+ case R_TILEPRO_IMM16_X0_TLS_GD_HI:
+ case R_TILEPRO_IMM16_X1_TLS_GD_HI:
+ case R_TILEPRO_IMM16_X0_TLS_GD_HA:
+ case R_TILEPRO_IMM16_X1_TLS_GD_HA:
+ case R_TILEPRO_IMM16_X0_TLS_IE:
+ case R_TILEPRO_IMM16_X1_TLS_IE:
+ case R_TILEPRO_IMM16_X0_TLS_IE_LO:
+ case R_TILEPRO_IMM16_X1_TLS_IE_LO:
+ case R_TILEPRO_IMM16_X0_TLS_IE_HI:
+ case R_TILEPRO_IMM16_X1_TLS_IE_HI:
+ case R_TILEPRO_IMM16_X0_TLS_IE_HA:
+ case R_TILEPRO_IMM16_X1_TLS_IE_HA:
+ r_type = tilepro_elf_tls_transition (info, r_type, h == NULL);
+ tls_type = GOT_UNKNOWN;
+ if (h == NULL && local_got_offsets)
+ tls_type
+ = _bfd_tilepro_elf_local_got_tls_type (input_bfd) [r_symndx];
+ else if (h != NULL)
+ {
+ tls_type = tilepro_elf_hash_entry(h)->tls_type;
+ if (!info->shared && h->dynindx == -1 && tls_type == GOT_TLS_IE)
+ r_type = tilepro_tls_translate_to_le (r_type);
+ }
+ if (tls_type == GOT_TLS_IE)
+ r_type = tilepro_tls_translate_to_ie (r_type);
+
+ if (r_type == R_TILEPRO_IMM16_X0_TLS_LE
+ || r_type == R_TILEPRO_IMM16_X1_TLS_LE
+ || r_type == R_TILEPRO_IMM16_X0_TLS_LE_LO
+ || r_type == R_TILEPRO_IMM16_X1_TLS_LE_LO
+ || r_type == R_TILEPRO_IMM16_X0_TLS_LE_HI
+ || r_type == R_TILEPRO_IMM16_X1_TLS_LE_HI
+ || r_type == R_TILEPRO_IMM16_X0_TLS_LE_HA
+ || r_type == R_TILEPRO_IMM16_X1_TLS_LE_HA)
+ {
+ relocation = tpoff (info, relocation);
+ break;
+ }
+
+ if (h != NULL)
+ {
+ off = h->got.offset;
+ h->got.offset |= 1;
+ }
+ else
+ {
+ BFD_ASSERT (local_got_offsets != NULL);
+ off = local_got_offsets[r_symndx];
+ local_got_offsets[r_symndx] |= 1;
+ }
+
+ if (htab->elf.sgot == NULL)
+ abort ();
+
+ if ((off & 1) != 0)
+ off &= ~1;
+ else
+ {
+ Elf_Internal_Rela outrel;
+ int indx = 0;
+ bfd_boolean need_relocs = FALSE;
+
+ if (htab->elf.srelgot == NULL)
+ abort ();
+
+ if (h != NULL)
+ {
+ bfd_boolean dyn;
+ dyn = htab->elf.dynamic_sections_created;
+
+ if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h)
+ && (!info->shared
+ || !SYMBOL_REFERENCES_LOCAL (info, h)))
+ {
+ indx = h->dynindx;
+ }
+ }
+
+ /* The GOT entries have not been initialized yet. Do it
+ now, and emit any relocations. */
+ if ((info->shared || indx != 0)
+ && (h == NULL
+ || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
+ || h->root.type != bfd_link_hash_undefweak))
+ need_relocs = TRUE;
+
+ switch (r_type)
+ {
+ case R_TILEPRO_IMM16_X0_TLS_IE:
+ case R_TILEPRO_IMM16_X1_TLS_IE:
+ case R_TILEPRO_IMM16_X0_TLS_IE_LO:
+ case R_TILEPRO_IMM16_X1_TLS_IE_LO:
+ case R_TILEPRO_IMM16_X0_TLS_IE_HI:
+ case R_TILEPRO_IMM16_X1_TLS_IE_HI:
+ case R_TILEPRO_IMM16_X0_TLS_IE_HA:
+ case R_TILEPRO_IMM16_X1_TLS_IE_HA:
+ if (need_relocs) {
+ bfd_put_32 (output_bfd, 0, htab->elf.sgot->contents + off);
+ outrel.r_offset = (htab->elf.sgot->output_section->vma
+ + htab->elf.sgot->output_offset + off);
+ outrel.r_addend = 0;
+ if (indx == 0)
+ outrel.r_addend = relocation - dtpoff_base (info);
+ outrel.r_info = ELF32_R_INFO (indx, R_TILEPRO_TLS_TPOFF32);
+ tilepro_elf_append_rela_32 (output_bfd, htab->elf.srelgot,
+ &outrel);
+ } else {
+ bfd_put_32 (output_bfd, tpoff (info, relocation),
+ htab->elf.sgot->contents + off);
+ }
+ break;
+
+ case R_TILEPRO_IMM16_X0_TLS_GD:
+ case R_TILEPRO_IMM16_X1_TLS_GD:
+ case R_TILEPRO_IMM16_X0_TLS_GD_LO:
+ case R_TILEPRO_IMM16_X1_TLS_GD_LO:
+ case R_TILEPRO_IMM16_X0_TLS_GD_HI:
+ case R_TILEPRO_IMM16_X1_TLS_GD_HI:
+ case R_TILEPRO_IMM16_X0_TLS_GD_HA:
+ case R_TILEPRO_IMM16_X1_TLS_GD_HA:
+ if (need_relocs) {
+ outrel.r_offset = (htab->elf.sgot->output_section->vma
+ + htab->elf.sgot->output_offset + off);
+ outrel.r_addend = 0;
+ outrel.r_info = ELF32_R_INFO (indx, R_TILEPRO_TLS_DTPMOD32);
+ bfd_put_32 (output_bfd, 0, htab->elf.sgot->contents + off);
+ tilepro_elf_append_rela_32 (output_bfd, htab->elf.srelgot,
+ &outrel);
+ if (indx == 0)
+ {
+ BFD_ASSERT (! unresolved_reloc);
+ bfd_put_32 (output_bfd,
+ relocation - dtpoff_base (info),
+ (htab->elf.sgot->contents + off +
+ TILEPRO_BYTES_PER_WORD));
+ }
+ else
+ {
+ bfd_put_32 (output_bfd, 0,
+ (htab->elf.sgot->contents + off +
+ TILEPRO_BYTES_PER_WORD));
+ outrel.r_info = ELF32_R_INFO (indx,
+ R_TILEPRO_TLS_DTPOFF32);
+ outrel.r_offset += TILEPRO_BYTES_PER_WORD;
+ tilepro_elf_append_rela_32 (output_bfd,
+ htab->elf.srelgot, &outrel);
+ }
+ }
+
+ else {
+ /* If we are not emitting relocations for a
+ general dynamic reference, then we must be in a
+ static link or an executable link with the
+ symbol binding locally. Mark it as belonging
+ to module 1, the executable. */
+ bfd_put_32 (output_bfd, 1,
+ htab->elf.sgot->contents + off );
+ bfd_put_32 (output_bfd, relocation - dtpoff_base (info),
+ htab->elf.sgot->contents + off +
+ TILEPRO_BYTES_PER_WORD);
+ }
+ break;
+ }
+ }
+
+ if (off >= (bfd_vma) -2)
+ abort ();
+
+ relocation = off - got_base;
+ unresolved_reloc = FALSE;
+ howto = tilepro_elf_howto_table + r_type;
+ break;
+
+ default:
+ break;
+ }
+
+ /* Dynamic relocs are not propagated for SEC_DEBUGGING sections
+ because such sections are not SEC_ALLOC and thus ld.so will
+ not process them. */
+ if (unresolved_reloc
+ && !((input_section->flags & SEC_DEBUGGING) != 0
+ && h->def_dynamic)
+ && _bfd_elf_section_offset (output_bfd, info, input_section,
+ rel->r_offset) != (bfd_vma) -1)
+ (*_bfd_error_handler)
+ (_("%B(%A+0x%lx): unresolvable %s relocation against symbol `%s'"),
+ input_bfd,
+ input_section,
+ (long) rel->r_offset,
+ howto->name,
+ h->root.root.string);
+
+ r = bfd_reloc_continue;
+
+ /* For the _HA types, we add 0x8000 so that if bit 15 is set,
+ * we will increment bit 16. The howto->rightshift takes care
+ * of the rest for us. */
+ switch (r_type)
+ {
+ case R_TILEPRO_HA16:
+ case R_TILEPRO_IMM16_X0_HA:
+ case R_TILEPRO_IMM16_X1_HA:
+ case R_TILEPRO_IMM16_X0_HA_PCREL:
+ case R_TILEPRO_IMM16_X1_HA_PCREL:
+ case R_TILEPRO_IMM16_X0_GOT_HA:
+ case R_TILEPRO_IMM16_X1_GOT_HA:
+ case R_TILEPRO_IMM16_X0_TLS_GD_HA:
+ case R_TILEPRO_IMM16_X1_TLS_GD_HA:
+ case R_TILEPRO_IMM16_X0_TLS_IE_HA:
+ case R_TILEPRO_IMM16_X1_TLS_IE_HA:
+ relocation += 0x8000;
+ break;
+ }
+
+ /* Get the operand creation function, if any. */
+ create_func = reloc_to_create_func[r_type];
+ if (create_func == NULL)
+ {
+ r = _bfd_final_link_relocate (howto, input_bfd, input_section,
+ contents, rel->r_offset,
+ relocation, rel->r_addend);
+ }
+ else
+ {
+ if (howto->pc_relative)
+ {
+ relocation -=
+ input_section->output_section->vma + input_section->output_offset;
+ if (howto->pcrel_offset)
+ relocation -= rel->r_offset;
+ }
+
+ bfd_byte *data;
+
+ /* Add the relocation addend if any to the final target value */
+ relocation += rel->r_addend;
+
+ /* Do basic range checking */
+ r = bfd_check_overflow (howto->complain_on_overflow,
+ howto->bitsize,
+ howto->rightshift,
+ 32,
+ relocation);
+
+ /*
+ * Write the relocated value out into the raw section data.
+ * Don't put a relocation out in the .rela section.
+ */
+ tilepro_bundle_bits mask = create_func(-1);
+ tilepro_bundle_bits value = create_func(relocation >> howto->rightshift);
+
+ /* Only touch bytes while the mask is not 0, so we
+ don't write to out of bounds memory if this is actually
+ a 16-bit switch instruction. */
+ for (data = contents + rel->r_offset; mask != 0; data++)
+ {
+ bfd_byte byte_mask = (bfd_byte)mask;
+ *data = (*data & ~byte_mask) | ((bfd_byte)value & byte_mask);
+ mask >>= 8;
+ value >>= 8;
+ }
+ }
+
+ if (r != bfd_reloc_ok)
+ {
+ const char *msg = NULL;
+
+ switch (r)
+ {
+ case bfd_reloc_overflow:
+ r = info->callbacks->reloc_overflow
+ (info, (h ? &h->root : NULL), 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,
+ TRUE);
+ 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;
+}
+
+/* Finish up dynamic symbol handling. We set the contents of various
+ dynamic sections here. */
+
+static bfd_boolean
+tilepro_elf_finish_dynamic_symbol (bfd *output_bfd,
+ struct bfd_link_info *info,
+ struct elf_link_hash_entry *h,
+ Elf_Internal_Sym *sym)
+{
+ struct tilepro_elf_link_hash_table *htab;
+
+ htab = tilepro_elf_hash_table (info);
+ BFD_ASSERT (htab != NULL);
+
+ if (h->plt.offset != (bfd_vma) -1)
+ {
+ asection *splt;
+ asection *srela;
+ asection *sgotplt;
+ Elf_Internal_Rela rela;
+ bfd_byte *loc;
+ bfd_vma r_offset;
+
+ int rela_index;
+
+ /* This symbol has an entry in the PLT. Set it up. */
+
+ BFD_ASSERT (h->dynindx != -1);
+
+ splt = htab->elf.splt;
+ srela = htab->elf.srelplt;
+ sgotplt = htab->elf.sgotplt;
+
+ if (splt == NULL || srela == NULL)
+ abort ();
+
+ /* Fill in the entry in the procedure linkage table. */
+ rela_index = tilepro_plt_entry_build (splt, sgotplt, h->plt.offset,
+ &r_offset);
+
+ /* Fill in the entry in the global offset table, which initially points
+ to the beginning of the plt. */
+ bfd_put_32 (output_bfd, splt->output_section->vma + splt->output_offset,
+ sgotplt->contents + r_offset);
+
+ /* Fill in the entry in the .rela.plt section. */
+ rela.r_offset = (sgotplt->output_section->vma
+ + sgotplt->output_offset
+ + r_offset);
+ rela.r_addend = 0;
+ rela.r_info = ELF32_R_INFO (h->dynindx, R_TILEPRO_JMP_SLOT);
+
+ loc = srela->contents + rela_index * sizeof (Elf32_External_Rela);
+ bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
+
+ if (!h->def_regular)
+ {
+ /* Mark the symbol as undefined, rather than as defined in
+ the .plt section. Leave the value alone. */
+ sym->st_shndx = SHN_UNDEF;
+ /* If the symbol is weak, we do need to clear the value.
+ Otherwise, the PLT entry would provide a definition for
+ the symbol even if the symbol wasn't defined anywhere,
+ and so the symbol would never be NULL. */
+ if (!h->ref_regular_nonweak)
+ sym->st_value = 0;
+ }
+ }
+
+ if (h->got.offset != (bfd_vma) -1
+ && tilepro_elf_hash_entry(h)->tls_type != GOT_TLS_GD
+ && tilepro_elf_hash_entry(h)->tls_type != GOT_TLS_IE)
+ {
+ asection *sgot;
+ asection *srela;
+ Elf_Internal_Rela rela;
+
+ /* This symbol has an entry in the GOT. Set it up. */
+
+ sgot = htab->elf.sgot;
+ srela = htab->elf.srelgot;
+ BFD_ASSERT (sgot != NULL && srela != NULL);
+
+ rela.r_offset = (sgot->output_section->vma
+ + sgot->output_offset
+ + (h->got.offset &~ (bfd_vma) 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->def_regular)
+ {
+ asection *sec = h->root.u.def.section;
+ rela.r_info = ELF32_R_INFO (0, R_TILEPRO_RELATIVE);
+ rela.r_addend = (h->root.u.def.value
+ + sec->output_section->vma
+ + sec->output_offset);
+ }
+ else
+ {
+ rela.r_info = ELF32_R_INFO (h->dynindx, R_TILEPRO_GLOB_DAT);
+ rela.r_addend = 0;
+ }
+
+ bfd_put_32 (output_bfd, 0,
+ sgot->contents + (h->got.offset & ~(bfd_vma) 1));
+ tilepro_elf_append_rela_32 (output_bfd, srela, &rela);
+ }
+
+ if (h->needs_copy)
+ {
+ asection *s;
+ Elf_Internal_Rela rela;
+
+ /* This symbols needs a copy reloc. Set it up. */
+ BFD_ASSERT (h->dynindx != -1);
+
+ s = htab->srelbss;
+ 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_TILEPRO_COPY);
+ rela.r_addend = 0;
+ tilepro_elf_append_rela_32 (output_bfd, s, &rela);
+ }
+
+ /* Mark some specially defined symbols as absolute. */
+ if (h == htab->elf.hdynamic
+ || (h == htab->elf.hgot || h == htab->elf.hplt))
+ sym->st_shndx = SHN_ABS;
+
+ return TRUE;
+}
+
+/* Finish up the dynamic sections. */
+
+static bfd_boolean
+tilepro_finish_dyn (bfd *output_bfd, struct bfd_link_info *info,
+ bfd *dynobj, asection *sdyn,
+ asection *splt ATTRIBUTE_UNUSED)
+{
+ Elf32_External_Dyn *dyncon, *dynconend;
+ struct tilepro_elf_link_hash_table *htab;
+
+ htab = tilepro_elf_hash_table (info);
+ BFD_ASSERT (htab != NULL);
+ dyncon = (Elf32_External_Dyn *) sdyn->contents;
+ dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->size);
+ for (; dyncon < dynconend; dyncon++)
+ {
+ Elf_Internal_Dyn dyn;
+ asection *s;
+
+ bfd_elf32_swap_dyn_in (dynobj, dyncon, &dyn);
+
+ switch (dyn.d_tag)
+ {
+ case DT_PLTGOT:
+ s = htab->elf.sgotplt;
+ dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
+ break;
+ case DT_JMPREL:
+ s = htab->elf.srelplt;
+ dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
+ break;
+ case DT_PLTRELSZ:
+ s = htab->elf.srelplt;
+ dyn.d_un.d_val = s->size;
+ break;
+ default:
+ continue;
+ }
+
+ bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
+ }
+ return TRUE;
+}
+
+static bfd_boolean
+tilepro_elf_finish_dynamic_sections (bfd *output_bfd,
+ struct bfd_link_info *info)
+{
+ bfd *dynobj;
+ asection *sdyn;
+ struct tilepro_elf_link_hash_table *htab;
+
+ htab = tilepro_elf_hash_table (info);
+ BFD_ASSERT (htab != NULL);
+ dynobj = htab->elf.dynobj;
+
+ sdyn = bfd_get_linker_section (dynobj, ".dynamic");
+
+ if (elf_hash_table (info)->dynamic_sections_created)
+ {
+ asection *splt;
+ bfd_boolean ret;
+
+ splt = htab->elf.splt;
+ BFD_ASSERT (splt != NULL && sdyn != NULL);
+
+ ret = tilepro_finish_dyn (output_bfd, info, dynobj, sdyn, splt);
+
+ if (ret != TRUE)
+ return ret;
+
+ /* Fill in the first entry in the procedure linkage table. */
+ if (splt->size > 0)
+ {
+ memcpy (splt->contents, tilepro_plt0_entry, PLT_HEADER_SIZE);
+ memset (splt->contents + PLT_HEADER_SIZE, 0,
+ PLT_ENTRY_SIZE - PLT_HEADER_SIZE);
+ }
+
+ if (elf_section_data (splt->output_section) != NULL)
+ elf_section_data (splt->output_section)->this_hdr.sh_entsize
+ = PLT_ENTRY_SIZE;
+ }
+
+ if (htab->elf.sgotplt)
+ {
+ if (bfd_is_abs_section (htab->elf.sgotplt->output_section))
+ {
+ (*_bfd_error_handler)
+ (_("discarded output section: `%A'"), htab->elf.sgotplt);
+ return FALSE;
+ }
+
+ if (htab->elf.sgotplt->size > 0)
+ {
+ /* Write the first two entries in .got.plt, needed for the dynamic
+ linker. */
+ bfd_put_32 (output_bfd, (bfd_vma) -1,
+ htab->elf.sgotplt->contents);
+ bfd_put_32 (output_bfd, (bfd_vma) 0,
+ htab->elf.sgotplt->contents + GOT_ENTRY_SIZE);
+ }
+
+ elf_section_data (htab->elf.sgotplt->output_section)->this_hdr.sh_entsize
+ = GOT_ENTRY_SIZE;
+ }
+
+ if (htab->elf.sgot)
+ {
+ if (htab->elf.sgot->size > 0)
+ {
+ /* Set the first entry in the global offset table to the address of
+ the dynamic section. */
+ bfd_vma val = (sdyn ?
+ sdyn->output_section->vma + sdyn->output_offset :
+ 0);
+ bfd_put_32 (output_bfd, val, htab->elf.sgot->contents);
+ }
+
+ elf_section_data (htab->elf.sgot->output_section)->this_hdr.sh_entsize
+ = GOT_ENTRY_SIZE;
+ }
+
+ return TRUE;
+}
+
+
+
+/* Return address for Ith PLT stub in section PLT, for relocation REL
+ or (bfd_vma) -1 if it should not be included. */
+
+static bfd_vma
+tilepro_elf_plt_sym_val (bfd_vma i, const asection *plt,
+ const arelent *rel ATTRIBUTE_UNUSED)
+{
+ return plt->vma + (i + 1) * PLT_ENTRY_SIZE;
+}
+
+static enum elf_reloc_type_class
+tilepro_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ const asection *rel_sec ATTRIBUTE_UNUSED,
+ const Elf_Internal_Rela *rela)
+{
+ switch ((int) ELF32_R_TYPE (rela->r_info))
+ {
+ case R_TILEPRO_RELATIVE:
+ return reloc_class_relative;
+ case R_TILEPRO_JMP_SLOT:
+ return reloc_class_plt;
+ case R_TILEPRO_COPY:
+ return reloc_class_copy;
+ default:
+ return reloc_class_normal;
+ }
+}
+
+static int
+tilepro_additional_program_headers (bfd *abfd,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED)
+{
+ /* Each .intrpt section specified by the user adds another PT_LOAD
+ header since the sections are discontiguous. */
+ static const char intrpt_sections[4][9] =
+ {
+ ".intrpt0", ".intrpt1", ".intrpt2", ".intrpt3"
+ };
+ int count = 0;
+ int i;
+
+ for (i = 0; i < 4; i++)
+ {
+ asection *sec = bfd_get_section_by_name (abfd, intrpt_sections[i]);
+ if (sec != NULL && (sec->flags & SEC_LOAD) != 0)
+ ++count;
+ }
+
+ /* Add four "padding" headers in to leave room in case a custom linker
+ script does something fancy. Otherwise ld complains that it ran
+ out of program headers and refuses to link. */
+ count += 4;
+
+ return count;
+}
+
+#define ELF_ARCH bfd_arch_tilepro
+#define ELF_TARGET_ID TILEPRO_ELF_DATA
+#define ELF_MACHINE_CODE EM_TILEPRO
+#define ELF_MAXPAGESIZE 0x10000
+#define ELF_COMMONPAGESIZE 0x10000
+
+#define TARGET_LITTLE_SYM tilepro_elf32_vec
+#define TARGET_LITTLE_NAME "elf32-tilepro"
+
+#define elf_backend_reloc_type_class tilepro_reloc_type_class
+
+#define bfd_elf32_bfd_reloc_name_lookup tilepro_reloc_name_lookup
+#define bfd_elf32_bfd_link_hash_table_create tilepro_elf_link_hash_table_create
+#define bfd_elf32_bfd_reloc_type_lookup tilepro_reloc_type_lookup
+
+#define elf_backend_copy_indirect_symbol tilepro_elf_copy_indirect_symbol
+#define elf_backend_create_dynamic_sections tilepro_elf_create_dynamic_sections
+#define elf_backend_check_relocs tilepro_elf_check_relocs
+#define elf_backend_adjust_dynamic_symbol tilepro_elf_adjust_dynamic_symbol
+#define elf_backend_omit_section_dynsym tilepro_elf_omit_section_dynsym
+#define elf_backend_size_dynamic_sections tilepro_elf_size_dynamic_sections
+#define elf_backend_relocate_section tilepro_elf_relocate_section
+#define elf_backend_finish_dynamic_symbol tilepro_elf_finish_dynamic_symbol
+#define elf_backend_finish_dynamic_sections tilepro_elf_finish_dynamic_sections
+#define elf_backend_gc_mark_hook tilepro_elf_gc_mark_hook
+#define elf_backend_gc_sweep_hook tilepro_elf_gc_sweep_hook
+#define elf_backend_plt_sym_val tilepro_elf_plt_sym_val
+#define elf_info_to_howto_rel NULL
+#define elf_info_to_howto tilepro_info_to_howto_rela
+#define elf_backend_grok_prstatus tilepro_elf_grok_prstatus
+#define elf_backend_grok_psinfo tilepro_elf_grok_psinfo
+#define elf_backend_additional_program_headers tilepro_additional_program_headers
+
+#define bfd_elf32_mkobject tilepro_elf_mkobject
+
+#define elf_backend_init_index_section _bfd_elf_init_1_index_section
+
+#define elf_backend_can_gc_sections 1
+#define elf_backend_can_refcount 1
+#define elf_backend_want_got_plt 1
+#define elf_backend_plt_readonly 1
+/* Align PLT mod 64 byte L2 line size. */
+#define elf_backend_plt_alignment 6
+#define elf_backend_want_plt_sym 1
+#define elf_backend_got_header_size GOT_ENTRY_SIZE
+#define elf_backend_rela_normal 1
+#define elf_backend_default_execstack 0
+
+#include "elf32-target.h"
diff --git a/bfd/elf32-tilepro.h b/bfd/elf32-tilepro.h
new file mode 100644
index 0000000..3d2aa87
--- /dev/null
+++ b/bfd/elf32-tilepro.h
@@ -0,0 +1,38 @@
+/* TILEPro-specific support for 32-bit ELF.
+ Copyright (C) 2011-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#ifndef _ELF32_TILEPRO_H
+#define _ELF32_TILEPRO_H
+
+/* This file contains sizes and offsets of Linux data structures. */
+
+#define TILEPRO_PRSTATUS_SIZEOF 332
+#define TILEPRO_PRSTATUS_OFFSET_PR_CURSIG 12
+#define TILEPRO_PRSTATUS_OFFSET_PR_PID 24
+#define TILEPRO_PRSTATUS_OFFSET_PR_REG 72
+
+#define TILEPRO_PRPSINFO_SIZEOF 128
+#define TILEPRO_PRPSINFO_OFFSET_PR_FNAME 32
+#define TILEPRO_PRPSINFO_OFFSET_PR_PSARGS 48
+#define ELF_PR_PSARGS_SIZE 80
+
+#define TILEPRO_GREGSET_T_SIZE 256
+
+#endif /* _ELF32_TILEPRO_H */
diff --git a/bfd/elf32-v850.c b/bfd/elf32-v850.c
new file mode 100644
index 0000000..2589a25
--- /dev/null
+++ b/bfd/elf32-v850.c
@@ -0,0 +1,3929 @@
+/* V850-specific support for 32-bit ELF
+ Copyright (C) 1996-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+
+/* XXX FIXME: This code is littered with 32bit int, 16bit short, 8bit char
+ dependencies. As is the gas & simulator code for the v850. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "bfdlink.h"
+#include "libbfd.h"
+#include "elf-bfd.h"
+#include "elf/v850.h"
+#include "libiberty.h"
+
+/* Sign-extend a 17-bit number. */
+#define SEXT17(x) ((((x) & 0x1ffff) ^ 0x10000) - 0x10000)
+
+/* Sign-extend a 22-bit number. */
+#define SEXT22(x) ((((x) & 0x3fffff) ^ 0x200000) - 0x200000)
+
+static reloc_howto_type v850_elf_howto_table[];
+
+/* Look through the relocs for a section during the first phase, and
+ allocate space in the global offset table or procedure linkage
+ table. */
+
+static bfd_boolean
+v850_elf_check_relocs (bfd *abfd,
+ struct bfd_link_info *info,
+ asection *sec,
+ const Elf_Internal_Rela *relocs)
+{
+ bfd_boolean ret = TRUE;
+ Elf_Internal_Shdr *symtab_hdr;
+ struct elf_link_hash_entry **sym_hashes;
+ const Elf_Internal_Rela *rel;
+ const Elf_Internal_Rela *rel_end;
+ unsigned int r_type;
+ int other = 0;
+ const char *common = NULL;
+
+ if (info->relocatable)
+ return TRUE;
+
+#ifdef DEBUG
+ _bfd_error_handler ("v850_elf_check_relocs called for section %A in %B",
+ sec, abfd);
+#endif
+
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+ sym_hashes = elf_sym_hashes (abfd);
+
+ 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];
+ 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;
+
+ /* PR15323, ref flags aren't set for references in the same
+ object. */
+ h->root.non_ir_ref = 1;
+ }
+
+ r_type = ELF32_R_TYPE (rel->r_info);
+ switch (r_type)
+ {
+ default:
+ break;
+
+ /* This relocation describes the C++ object vtable hierarchy.
+ Reconstruct it for later use during GC. */
+ case R_V850_GNU_VTINHERIT:
+ if (!bfd_elf_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:
+ BFD_ASSERT (h != NULL);
+ if (h != NULL
+ && !bfd_elf_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:
+ case R_V810_GPWLO_1:
+ case R_V850_HWLO:
+ case R_V850_HWLO_1:
+ 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_4_OFFSET:
+ case R_V850_TDA_4_5_OFFSET:
+ case R_V850_TDA_7_7_OFFSET:
+ case R_V850_TDA_6_8_OFFSET:
+ case R_V850_TDA_7_8_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)
+ {
+ /* Flag which type of relocation was used. */
+ h->other |= other;
+ 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,
+ (bfd_vma) 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;
+
+ 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;
+ bfd_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 (bfd *abfd, bfd_vma addend, bfd_byte *address)
+{
+ hi16s_location * entry = NULL;
+ bfd_size_type amt = sizeof (* free_hi16s);
+
+ /* Find a free structure. */
+ if (free_hi16s == NULL)
+ free_hi16s = bfd_zalloc (abfd, amt);
+
+ 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;
+ }
+}
+
+static bfd_byte *
+find_remembered_hi16s_reloc (bfd_vma addend, bfd_boolean *already_found)
+{
+ hi16s_location *match = NULL;
+ hi16s_location *entry;
+ 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))
+ {
+ match = entry;
+ }
+ }
+
+ if (match == NULL)
+ return NULL;
+
+ /* Extract the address. */
+ addr = match->address;
+
+ /* Remember 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;
+}
+
+/* Calculate the final operand value for a R_V850_LO16 or
+ R_V850_LO16_SPLIT_OFFSET. *INSN is the current operand value and
+ ADDEND is the sum of the relocation symbol and offset. Store the
+ operand value in *INSN and return true on success.
+
+ 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). */
+
+static bfd_boolean
+v850_elf_perform_lo16_relocation (bfd *abfd, unsigned long *insn,
+ unsigned long addend)
+{
+#define BIT15_SET(x) ((x) & 0x8000)
+#define OVERFLOWS(a,i) ((((a) & 0xffff) + (i)) > 0xffff)
+
+ if ((BIT15_SET (*insn + addend) && ! BIT15_SET (addend))
+ || (OVERFLOWS (addend, *insn)
+ && ((! BIT15_SET (*insn)) || (BIT15_SET (addend)))))
+ {
+ bfd_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)
+ {
+ unsigned long hi_insn = bfd_get_16 (abfd, hi16s_address);
+ hi_insn += 1;
+ bfd_put_16 (abfd, hi_insn, hi16s_address);
+ }
+ }
+ else
+ {
+ (*_bfd_error_handler) (_("FAILED to find previous HI16 reloc"));
+ return FALSE;
+ }
+ }
+#undef OVERFLOWS
+#undef BIT15_SET
+
+ /* Do not complain if value has top bit set, as this has been
+ anticipated. */
+ *insn = (*insn + addend) & 0xffff;
+ return TRUE;
+}
+
+/* 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, anyway. */
+
+static bfd_reloc_status_type
+v850_elf_perform_relocation (bfd *abfd,
+ unsigned int r_type,
+ bfd_vma addend,
+ bfd_byte *address)
+{
+ unsigned long insn;
+ unsigned long result;
+ bfd_signed_vma saddend = (bfd_signed_vma) addend;
+
+ switch (r_type)
+ {
+ default:
+#ifdef DEBUG
+ fprintf (stderr, "reloc number %d not recognised\n", r_type);
+#endif
+ return bfd_reloc_notsupported;
+
+ case R_V850_REL32:
+ case R_V850_ABS32:
+ case R_V810_WORD:
+ case R_V850_PC32:
+ bfd_put_32 (abfd, addend, address);
+ return bfd_reloc_ok;
+
+ case R_V850_WLO23:
+ case R_V850_23:
+ insn = bfd_get_32 (abfd, address);
+ insn &= ~((0x7f << 4) | (0x7fff80 << (16-7)));
+ insn |= ((addend & 0x7f) << 4) | ((addend & 0x7fff80) << (16-7));
+ bfd_put_32 (abfd, (bfd_vma) insn, address);
+ return bfd_reloc_ok;
+
+ case R_V850_PCR22:
+ 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, (bfd_vma) insn, address);
+ return bfd_reloc_ok;
+
+ case R_V850_PC17:
+ case R_V850_17_PCREL:
+ if (saddend > 0xffff || saddend < -0x10000)
+ return bfd_reloc_overflow;
+
+ if ((addend % 2) != 0)
+ return bfd_reloc_dangerous;
+
+ insn = bfd_get_32 (abfd, address);
+ insn &= ~ 0xfffe0010;
+ insn |= ((addend & 0xfffe) << 16) | ((addend & 0x10000) >> (16-4));
+ break;
+
+ case R_V850_PC16U:
+ case R_V850_16_PCREL:
+ if ((saddend < -0xffff) || (saddend > 0))
+ return bfd_reloc_overflow;
+
+ if ((addend % 2) != 0)
+ return bfd_reloc_dangerous;
+
+ insn = bfd_get_16 (abfd, address);
+ insn &= ~0xfffe;
+ insn |= (-addend & 0xfffe);
+ break;
+
+ case R_V850_PC9:
+ 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_V810_WHI:
+ case R_V850_HI16:
+ addend += (bfd_get_16 (abfd, address) << 16);
+ addend = (addend >> 16);
+ insn = addend;
+ break;
+
+ case R_V810_WHI1:
+ 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 > 0xffff)
+ addend = 0;
+
+ insn = addend;
+ break;
+
+ case R_V810_WLO:
+ case R_V850_LO16:
+ insn = bfd_get_16 (abfd, address);
+ if (! v850_elf_perform_lo16_relocation (abfd, &insn, addend))
+ return bfd_reloc_overflow;
+ break;
+
+ case R_V810_BYTE:
+ 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_CALLT_15_16_OFFSET:
+ insn = bfd_get_16 (abfd, address);
+
+ addend += insn & 0xfffe;
+
+ saddend = (bfd_signed_vma) addend;
+
+ if (saddend > 0xffff || saddend < 0)
+ return bfd_reloc_overflow;
+
+ insn = (0xfffe & addend)
+ | (insn & ~0xfffe);
+ break;
+
+ 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_16:
+ case R_V810_HWORD:
+ 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_16_S1:
+ case R_V850_SDA_15_16_OFFSET:
+ case R_V850_ZDA_15_16_OFFSET:
+ case R_V810_GPWLO_1:
+ 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 &~ (bfd_vma) 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_V810_WLO_1:
+ case R_V850_HWLO:
+ case R_V850_HWLO_1:
+ case R_V850_LO16_S1:
+ insn = bfd_get_16 (abfd, address);
+ result = insn & 0xfffe;
+ if (! v850_elf_perform_lo16_relocation (abfd, &result, addend))
+ return bfd_reloc_overflow;
+ if (result & 1)
+ return bfd_reloc_overflow;
+ insn = (result & 0xfffe)
+ | (insn & ~0xfffe);
+ bfd_put_16 (abfd, insn, address);
+ return bfd_reloc_ok;
+
+ case R_V850_BLO:
+ case R_V850_LO16_SPLIT_OFFSET:
+ insn = bfd_get_32 (abfd, address);
+ result = ((insn & 0xfffe0000) >> 16) | ((insn & 0x20) >> 5);
+ if (! v850_elf_perform_lo16_relocation (abfd, &result, addend))
+ return bfd_reloc_overflow;
+ insn = (((result << 16) & 0xfffe0000)
+ | ((result << 5) & 0x20)
+ | (insn & ~0xfffe0020));
+ bfd_put_32 (abfd, insn, address);
+ return bfd_reloc_ok;
+
+ case R_V850_16_SPLIT_OFFSET:
+ case R_V850_SDA_16_16_SPLIT_OFFSET:
+ case R_V850_ZDA_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 &~ (bfd_vma) 1) << 16;
+
+ bfd_put_32 (abfd, (bfd_vma) insn, address);
+ return bfd_reloc_ok;
+
+ case R_V850_GNU_VTINHERIT:
+ case R_V850_GNU_VTENTRY:
+ return bfd_reloc_ok;
+
+ }
+
+ bfd_put_16 (abfd, (bfd_vma) insn, address);
+ return bfd_reloc_ok;
+}
+
+/* Insert the addend into the instruction. */
+
+static bfd_reloc_status_type
+v850_elf_reloc (bfd *abfd ATTRIBUTE_UNUSED,
+ arelent *reloc,
+ asymbol *symbol,
+ void * data ATTRIBUTE_UNUSED,
+ asection *isection,
+ bfd *obfd,
+ char **err ATTRIBUTE_UNUSED)
+{
+ 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 != NULL
+ && (symbol->flags & BSF_SECTION_SYM) == 0
+ && (! reloc->howto->partial_inplace
+ || reloc->addend == 0))
+ {
+ reloc->address += isection->output_offset;
+ return bfd_reloc_ok;
+ }
+
+ /* 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 > bfd_get_section_limit (abfd, isection))
+ return bfd_reloc_outofrange;
+
+ /* Work out which section the relocation is targeted at and the
+ initial relocation command value. */
+
+ if (reloc->howto->pc_relative)
+ return bfd_reloc_ok;
+
+ /* 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;
+
+ reloc->addend = relocation;
+ 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
+v850_elf_ignore_reloc (bfd *abfd ATTRIBUTE_UNUSED,
+ arelent *reloc_entry,
+ asymbol *symbol ATTRIBUTE_UNUSED,
+ void * data ATTRIBUTE_UNUSED,
+ asection *input_section,
+ bfd *output_bfd,
+ char **error_message ATTRIBUTE_UNUSED)
+{
+ if (output_bfd != NULL)
+ reloc_entry->address += input_section->output_offset;
+
+ return bfd_reloc_ok;
+}
+/* Note: It is REQUIRED that the 'type' value of each entry
+ in this array match the index of the entry in the array.
+ SeeAlso: RELOC_NUBMER in include/elf/v850.h. */
+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. */
+ 0, /* Rightshift. */
+ 1, /* Size (0 = byte, 1 = short, 2 = long). */
+ 9, /* 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. */
+ 0, /* Rightshift. */
+ 2, /* Size (0 = byte, 1 = short, 2 = long). */
+ 22, /* Bitsize. */
+ TRUE, /* PC_relative. */
+ 0, /* 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. */
+ FALSE, /* 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. */
+ FALSE, /* 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. */
+ FALSE, /* Partial_inplace. */
+ 0xffff, /* Src_mask. */
+ 0xffff, /* Dst_mask. */
+ FALSE), /* PCrel_offset. */
+
+ /* Simple 32bit reloc. */
+ HOWTO (R_V850_ABS32, /* 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_ABS32", /* Name. */
+ FALSE, /* 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. */
+ FALSE, /* 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. */
+ FALSE, /* 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. */
+
+ /* Indicates a .longcall pseudo-op. The compiler will generate a .longcall
+ pseudo-op when it finds a function call which can be relaxed. */
+ HOWTO (R_V850_LONGCALL, /* Type. */
+ 0, /* Rightshift. */
+ 2, /* Size (0 = byte, 1 = short, 2 = long). */
+ 32, /* Bitsize. */
+ TRUE, /* PC_relative. */
+ 0, /* Bitpos. */
+ complain_overflow_signed, /* Complain_on_overflow. */
+ v850_elf_ignore_reloc, /* Special_function. */
+ "R_V850_LONGCALL", /* Name. */
+ FALSE, /* Partial_inplace. */
+ 0, /* Src_mask. */
+ 0, /* Dst_mask. */
+ TRUE), /* PCrel_offset. */
+
+ /* Indicates a .longjump pseudo-op. The compiler will generate a
+ .longjump pseudo-op when it finds a branch which can be relaxed. */
+ HOWTO (R_V850_LONGJUMP, /* Type. */
+ 0, /* Rightshift. */
+ 2, /* Size (0 = byte, 1 = short, 2 = long). */
+ 32, /* Bitsize. */
+ TRUE, /* PC_relative. */
+ 0, /* Bitpos. */
+ complain_overflow_signed, /* Complain_on_overflow. */
+ v850_elf_ignore_reloc, /* Special_function. */
+ "R_V850_LONGJUMP", /* Name. */
+ FALSE, /* Partial_inplace. */
+ 0, /* Src_mask. */
+ 0, /* Dst_mask. */
+ TRUE), /* PCrel_offset. */
+
+ HOWTO (R_V850_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. */
+ v850_elf_ignore_reloc, /* Special_function. */
+ "R_V850_ALIGN", /* Name. */
+ FALSE, /* Partial_inplace. */
+ 0, /* Src_mask. */
+ 0, /* Dst_mask. */
+ TRUE), /* PCrel_offset. */
+
+ /* Simple pc-relative 32bit reloc. */
+ HOWTO (R_V850_REL32, /* Type. */
+ 0, /* Rightshift. */
+ 2, /* Size (0 = byte, 1 = short, 2 = long). */
+ 32, /* Bitsize. */
+ TRUE, /* PC_relative. */
+ 0, /* Bitpos. */
+ complain_overflow_dont, /* Complain_on_overflow. */
+ v850_elf_reloc, /* Special_function. */
+ "R_V850_REL32", /* Name. */
+ FALSE, /* Partial_inplace. */
+ 0xffffffff, /* Src_mask. */
+ 0xffffffff, /* Dst_mask. */
+ FALSE), /* PCrel_offset. */
+
+ /* An ld.bu version of R_V850_LO16. */
+ HOWTO (R_V850_LO16_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_LO16_SPLIT_OFFSET", /* Name. */
+ FALSE, /* Partial_inplace. */
+ 0xfffe0020, /* Src_mask. */
+ 0xfffe0020, /* Dst_mask. */
+ FALSE), /* PCrel_offset. */
+
+ /* A unsigned PC relative 16 bit loop. */
+ HOWTO (R_V850_16_PCREL, /* Type. */
+ 0, /* Rightshift. */
+ 1, /* Size (0 = byte, 1 = short, 2 = long). */
+ 16, /* Bitsize. */
+ TRUE, /* PC_relative. */
+ 0, /* Bitpos. */
+ complain_overflow_bitfield, /* Complain_on_overflow. */
+ v850_elf_reloc, /* Special_function. */
+ "R_V850_16_PCREL", /* Name. */
+ FALSE, /* Partial_inplace. */
+ 0xfffe, /* Src_mask. */
+ 0xfffe, /* Dst_mask. */
+ TRUE), /* PCrel_offset. */
+
+ /* A PC relative 17 bit branch. */
+ HOWTO (R_V850_17_PCREL, /* Type. */
+ 0, /* Rightshift. */
+ 2, /* Size (0 = byte, 1 = short, 2 = long). */
+ 17, /* Bitsize. */
+ TRUE, /* PC_relative. */
+ 0, /* Bitpos. */
+ complain_overflow_bitfield, /* Complain_on_overflow. */
+ v850_elf_reloc, /* Special_function. */
+ "R_V850_17_PCREL", /* Name. */
+ FALSE, /* Partial_inplace. */
+ 0x0010fffe, /* Src_mask. */
+ 0x0010fffe, /* Dst_mask. */
+ TRUE), /* PCrel_offset. */
+
+ /* A 23bit offset ld/st. */
+ HOWTO (R_V850_23, /* type. */
+ 0, /* rightshift. */
+ 2, /* size (0 = byte, 1 = short, 2 = long). */
+ 23, /* bitsize. */
+ FALSE, /* pc_relative. */
+ 0, /* bitpos. */
+ complain_overflow_dont, /* complain_on_overflow. */
+ v850_elf_reloc, /* special_function. */
+ "R_V850_23", /* name. */
+ FALSE, /* partial_inplace. */
+ 0xffff07f0, /* src_mask. */
+ 0xffff07f0, /* dst_mask. */
+ FALSE), /* pcrel_offset. */
+
+ /* A PC relative 32 bit branch. */
+ HOWTO (R_V850_32_PCREL, /* type. */
+ 1, /* rightshift. */
+ 2, /* size (0 = byte, 1 = short, 2 = long). */
+ 32, /* bitsize. */
+ TRUE, /* pc_relative. */
+ 1, /* bitpos. */
+ complain_overflow_signed, /* complain_on_overflow. */
+ v850_elf_reloc, /* special_function. */
+ "R_V850_32_PCREL", /* name. */
+ FALSE, /* partial_inplace. */
+ 0xfffffffe, /* src_mask. */
+ 0xfffffffe, /* dst_mask. */
+ TRUE), /* pcrel_offset. */
+
+ /* A absolute 32 bit branch. */
+ HOWTO (R_V850_32_ABS, /* type. */
+ 1, /* rightshift. */
+ 2, /* size (0 = byte, 1 = short, 2 = long). */
+ 32, /* bitsize. */
+ TRUE, /* pc_relative. */
+ 1, /* bitpos. */
+ complain_overflow_signed, /* complain_on_overflow. */
+ v850_elf_reloc, /* special_function. */
+ "R_V850_32_ABS", /* name. */
+ FALSE, /* partial_inplace. */
+ 0xfffffffe, /* src_mask. */
+ 0xfffffffe, /* 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. */
+ FALSE, /* Partial_inplace. */
+ 0xffff, /* Src_mask. */
+ 0xffff, /* Dst_mask. */
+ FALSE), /* PCrel_offset. */
+
+ /* Low 16 bits of symbol value. */
+ HOWTO (R_V850_16_S1, /* 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_16_S1", /* name. */
+ FALSE, /* partial_inplace. */
+ 0xfffe, /* src_mask. */
+ 0xfffe, /* dst_mask. */
+ FALSE), /* pcrel_offset. */
+
+ /* Low 16 bits of symbol value. */
+ HOWTO (R_V850_LO16_S1, /* 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_LO16_S1", /* name. */
+ FALSE, /* partial_inplace. */
+ 0xfffe, /* src_mask. */
+ 0xfffe, /* dst_mask. */
+ FALSE), /* pcrel_offset. */
+
+ /* 16 bit offset from the call table base pointer. */
+ HOWTO (R_V850_CALLT_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_CALLT_15_16_OFFSET", /* name. */
+ FALSE, /* partial_inplace. */
+ 0xfffe, /* src_mask. */
+ 0xfffe, /* dst_mask. */
+ FALSE), /* pcrel_offset. */
+
+ /* Like R_V850_32 PCREL, but referring to the GOT table entry for
+ the symbol. */
+ HOWTO (R_V850_32_GOTPCREL, /* type. */
+ 0, /* rightshift. */
+ 2, /* size (0 = byte, 1 = short, 2 = long). */
+ 32, /* bitsize. */
+ TRUE, /* pc_relative. */
+ 0, /* bitpos. */
+ complain_overflow_unsigned, /* complain_on_overflow. */
+ v850_elf_reloc, /* special_function. */
+ "R_V850_32_GOTPCREL", /* name. */
+ FALSE, /* partial_inplace. */
+ 0xffffffff, /* src_mask. */
+ 0xffffffff, /* dst_mask. */
+ TRUE), /* pcrel_offset. */
+
+ /* Like R_V850_SDA_, but referring to the GOT table entry for
+ the symbol. */
+ HOWTO (R_V850_16_GOT, /* type. */
+ 0, /* rightshift. */
+ 2, /* size (0 = byte, 1 = short, 2 = long). */
+ 16, /* bitsize. */
+ FALSE, /* pc_relative. */
+ 0, /* bitpos. */
+ complain_overflow_unsigned, /* complain_on_overflow. */
+ bfd_elf_generic_reloc, /* special_function. */
+ "R_V850_16_GOT", /* name. */
+ FALSE, /* partial_inplace. */
+ 0xffff, /* src_mask. */
+ 0xffff, /* dst_mask. */
+ FALSE), /* pcrel_offset. */
+
+ HOWTO (R_V850_32_GOT, /* type. */
+ 0, /* rightshift. */
+ 2, /* size (0 = byte, 1 = short, 2 = long). */
+ 32, /* bitsize. */
+ FALSE, /* pc_relative. */
+ 0, /* bitpos. */
+ complain_overflow_unsigned, /* complain_on_overflow. */
+ bfd_elf_generic_reloc, /* special_function. */
+ "R_V850_32_GOT", /* name. */
+ FALSE, /* partial_inplace. */
+ 0xffffffff, /* src_mask. */
+ 0xffffffff, /* dst_mask. */
+ FALSE), /* pcrel_offset. */
+
+ /* Like R_V850_22_PCREL, but referring to the procedure linkage table
+ entry for the symbol. */
+ HOWTO (R_V850_22_PLT, /* type. */
+ 1, /* 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_V850_22_PLT", /* name. */
+ FALSE, /* partial_inplace. */
+ 0x07ffff80, /* src_mask. */
+ 0x07ffff80, /* dst_mask. */
+ TRUE), /* pcrel_offset. */
+
+ HOWTO (R_V850_32_PLT, /* type. */
+ 1, /* rightshift. */
+ 2, /* size (0 = byte, 1 = short, 2 = long). */
+ 32, /* bitsize. */
+ TRUE, /* pc_relative. */
+ 1, /* bitpos. */
+ complain_overflow_signed, /* complain_on_overflow. */
+ bfd_elf_generic_reloc, /* special_function. */
+ "R_V850_32_PLT", /* name. */
+ FALSE, /* partial_inplace. */
+ 0xffffffff, /* src_mask. */
+ 0xffffffff, /* 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_V850_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_V850_COPY", /* name. */
+ FALSE, /* partial_inplace. */
+ 0xffffffff, /* src_mask. */
+ 0xffffffff, /* dst_mask. */
+ FALSE), /* pcrel_offset. */
+
+ /* Like R_M32R_24, but used when setting global offset table
+ entries. */
+ HOWTO (R_V850_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_V850_GLOB_DAT", /* name. */
+ FALSE, /* partial_inplace. */
+ 0xffffffff, /* src_mask. */
+ 0xffffffff, /* dst_mask. */
+ FALSE), /* pcrel_offset. */
+
+ /* Marks a procedure linkage table entry for a symbol. */
+ HOWTO (R_V850_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_V850_JMP_SLOT", /* name. */
+ FALSE, /* partial_inplace. */
+ 0xffffffff, /* src_mask. */
+ 0xffffffff, /* 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_V850_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_V850_RELATIVE", /* name. */
+ FALSE, /* partial_inplace. */
+ 0xffffffff, /* src_mask. */
+ 0xffffffff, /* dst_mask. */
+ FALSE), /* pcrel_offset. */
+
+ HOWTO (R_V850_16_GOTOFF, /* 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_V850_16_GOTOFF", /* name. */
+ FALSE, /* partial_inplace. */
+ 0xffff, /* src_mask. */
+ 0xffff, /* dst_mask. */
+ FALSE), /* pcrel_offset. */
+
+ HOWTO (R_V850_32_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_V850_32_GOTOFF", /* name. */
+ FALSE, /* partial_inplace. */
+ 0xffffffff, /* src_mask. */
+ 0xffffffff, /* dst_mask. */
+ FALSE), /* pcrel_offset. */
+
+ HOWTO (R_V850_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. */
+ v850_elf_ignore_reloc, /* special_function. */
+ "R_V850_CODE", /* name. */
+ FALSE, /* partial_inplace. */
+ 0, /* src_mask. */
+ 0, /* dst_mask. */
+ TRUE), /* pcrel_offset. */
+
+ HOWTO (R_V850_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. */
+ v850_elf_ignore_reloc, /* special_function. */
+ "R_V850_DATA", /* name. */
+ FALSE, /* partial_inplace. */
+ 0, /* src_mask. */
+ 0, /* dst_mask. */
+ TRUE), /* 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 int 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_ABS32 },
+ { BFD_RELOC_32_PCREL, R_V850_REL32 },
+ { 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_LO16_SPLIT_OFFSET, R_V850_LO16_SPLIT_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 },
+ { BFD_RELOC_V850_LONGCALL, R_V850_LONGCALL },
+ { BFD_RELOC_V850_LONGJUMP, R_V850_LONGJUMP },
+ { BFD_RELOC_V850_ALIGN, R_V850_ALIGN },
+ { BFD_RELOC_V850_16_PCREL, R_V850_16_PCREL },
+ { BFD_RELOC_V850_17_PCREL, R_V850_17_PCREL },
+ { BFD_RELOC_V850_23, R_V850_23 },
+ { BFD_RELOC_V850_32_PCREL, R_V850_32_PCREL },
+ { BFD_RELOC_V850_32_ABS, R_V850_32_ABS },
+ { BFD_RELOC_V850_16_SPLIT_OFFSET, R_V850_HI16 },
+ { BFD_RELOC_V850_16_S1, R_V850_16_S1 },
+ { BFD_RELOC_V850_LO16_S1, R_V850_LO16_S1 },
+ { BFD_RELOC_V850_CALLT_15_16_OFFSET, R_V850_CALLT_15_16_OFFSET },
+ { BFD_RELOC_V850_32_GOTPCREL, R_V850_32_GOTPCREL },
+ { BFD_RELOC_V850_16_GOT, R_V850_16_GOT },
+ { BFD_RELOC_V850_32_GOT, R_V850_32_GOT },
+ { BFD_RELOC_V850_22_PLT_PCREL, R_V850_22_PLT },
+ { BFD_RELOC_V850_32_PLT_PCREL, R_V850_32_PLT },
+ { BFD_RELOC_V850_COPY, R_V850_COPY },
+ { BFD_RELOC_V850_GLOB_DAT, R_V850_GLOB_DAT },
+ { BFD_RELOC_V850_JMP_SLOT, R_V850_JMP_SLOT },
+ { BFD_RELOC_V850_RELATIVE, R_V850_RELATIVE },
+ { BFD_RELOC_V850_16_GOTOFF, R_V850_16_GOTOFF },
+ { BFD_RELOC_V850_32_GOTOFF, R_V850_32_GOTOFF },
+ { BFD_RELOC_V850_CODE, R_V850_CODE },
+ { BFD_RELOC_V850_DATA, R_V850_DATA },
+};
+
+#define V800_RELOC(name,sz,bit,shift,complain,pcrel,resolver) \
+ HOWTO (name, shift, sz, bit, pcrel, 0, complain_overflow_ ## complain, \
+ bfd_elf_ ## resolver ## _reloc, #name, FALSE, 0, ~0, FALSE)
+
+#define V800_EMPTY(name) EMPTY_HOWTO (name - R_V810_NONE)
+
+#define bfd_elf_v850_reloc v850_elf_reloc
+
+/* Note: It is REQUIRED that the 'type' value (R_V810_...) of each entry
+ in this array match the index of the entry in the array minus 0x30.
+ See: bfd_elf_v850_relocate_section(), v800_elf_reloc_type_lookup()
+ and v800_elf_info_to_howto(). */
+
+static reloc_howto_type v800_elf_howto_table[] =
+{
+ V800_RELOC (R_V810_NONE, 0, 0, 0, dont, FALSE, generic), /* Type = 0x30 */
+ V800_RELOC (R_V810_BYTE, 0, 8, 0, dont, FALSE, generic),
+ V800_RELOC (R_V810_HWORD, 1, 16, 0, dont, FALSE, generic),
+ V800_RELOC (R_V810_WORD, 2, 32, 0, dont, FALSE, generic),
+ V800_RELOC (R_V810_WLO, 1, 16, 0, dont, FALSE, generic),
+ V800_RELOC (R_V810_WHI, 1, 16, 0, dont, FALSE, generic),
+ V800_RELOC (R_V810_WHI1, 1, 16, 0, dont, FALSE, generic),
+ V800_RELOC (R_V810_GPBYTE, 0, 8, 0, dont, FALSE, v850),
+ V800_RELOC (R_V810_GPHWORD, 1, 16, 0, dont, FALSE, v850),
+ V800_RELOC (R_V810_GPWORD, 2, 32, 0, dont, FALSE, v850),
+ V800_RELOC (R_V810_GPWLO, 1, 16, 0, dont, FALSE, v850),
+ V800_RELOC (R_V810_GPWHI, 1, 16, 0, dont, FALSE, v850),
+ V800_RELOC (R_V810_GPWHI1, 1, 16, 0, dont, FALSE, v850),
+ V800_RELOC (R_V850_HWLO, 1, 16, 0, dont, FALSE, generic),
+ V800_EMPTY (R_V810_reserved1),
+ V800_RELOC (R_V850_EP7BIT, 0, 7, 0, unsigned, FALSE, v850),
+ V800_RELOC (R_V850_EPHBYTE, 0, 8, 1, unsigned, FALSE, v850),
+ V800_RELOC (R_V850_EPWBYTE, 0, 8, 2, unsigned, FALSE, v850),
+ V800_RELOC (R_V850_REGHWLO, 1, 16, 0, dont, FALSE, v850),
+ V800_EMPTY (R_V810_reserved2),
+ V800_RELOC (R_V850_GPHWLO, 1, 16, 0, dont, FALSE, v850),
+ V800_EMPTY (R_V810_reserved3),
+ V800_RELOC (R_V850_PCR22, 2, 22, 0, signed, TRUE, generic),
+ V800_RELOC (R_V850_BLO, 2, 24, 0, dont, FALSE, v850),
+ V800_RELOC (R_V850_EP4BIT, 0, 4, 0, unsigned, FALSE, v850),
+ V800_RELOC (R_V850_EP5BIT, 0, 5, 0, unsigned, FALSE, v850),
+ V800_RELOC (R_V850_REGBLO, 2, 24, 0, dont, FALSE, v850),
+ V800_RELOC (R_V850_GPBLO, 2, 24, 0, dont, FALSE, v850),
+ V800_RELOC (R_V810_WLO_1, 1, 16, 0, dont, FALSE, v850),
+ V800_RELOC (R_V810_GPWLO_1, 1, 16, 0, signed, FALSE, v850),
+ V800_RELOC (R_V850_BLO_1, 2, 16, 0, signed, FALSE, v850),
+ V800_RELOC (R_V850_HWLO_1, 1, 16, 0, signed, FALSE, v850),
+ V800_EMPTY (R_V810_reserved4),
+ V800_RELOC (R_V850_GPBLO_1, 2, 16, 1, signed, FALSE, v850),
+ V800_RELOC (R_V850_GPHWLO_1, 1, 16, 1, signed, FALSE, v850),
+ V800_EMPTY (R_V810_reserved5),
+ V800_RELOC (R_V850_EPBLO, 2, 16, 1, signed, FALSE, v850),
+ V800_RELOC (R_V850_EPHWLO, 1, 16, 1, signed, FALSE, v850),
+ V800_EMPTY (R_V810_reserved6),
+ V800_RELOC (R_V850_EPWLO_N, 1, 16, 1, signed, FALSE, v850),
+ V800_RELOC (R_V850_PC32, 2, 32, 1, signed, TRUE, v850),
+ V800_RELOC (R_V850_W23BIT, 2, 23, 1, signed, FALSE, v850),
+ V800_RELOC (R_V850_GPW23BIT, 2, 23, 1, signed, FALSE, v850),
+ V800_RELOC (R_V850_EPW23BIT, 2, 23, 1, signed, FALSE, v850),
+ V800_RELOC (R_V850_B23BIT, 2, 23, 1, signed, FALSE, v850),
+ V800_RELOC (R_V850_GPB23BIT, 2, 23, 1, signed, FALSE, v850),
+ V800_RELOC (R_V850_EPB23BIT, 2, 23, 1, signed, FALSE, v850),
+ V800_RELOC (R_V850_PC16U, 1, 16, 1, unsigned, TRUE, generic),
+ V800_RELOC (R_V850_PC17, 2, 17, 1, signed, TRUE, generic),
+ V800_RELOC (R_V850_DW8, 2, 8, 2, signed, FALSE, v850),
+ V800_RELOC (R_V850_GPDW8, 2, 8, 2, signed, FALSE, v850),
+ V800_RELOC (R_V850_EPDW8, 2, 8, 2, signed, FALSE, v850),
+ V800_RELOC (R_V850_PC9, 1, 9, 3, signed, TRUE, v850),
+ V800_RELOC (R_V810_REGBYTE, 0, 8, 0, dont, FALSE, v850),
+ V800_RELOC (R_V810_REGHWORD, 1, 16, 0, dont, FALSE, v850),
+ V800_RELOC (R_V810_REGWORD, 2, 32, 0, dont, FALSE, v850),
+ V800_RELOC (R_V810_REGWLO, 1, 16, 0, dont, FALSE, v850),
+ V800_RELOC (R_V810_REGWHI, 1, 16, 0, dont, FALSE, v850),
+ V800_RELOC (R_V810_REGWHI1, 1, 16, 0, dont, FALSE, v850),
+ V800_RELOC (R_V850_REGW23BIT, 2, 23, 1, signed, FALSE, v850),
+ V800_RELOC (R_V850_REGB23BIT, 2, 23, 1, signed, FALSE, v850),
+ V800_RELOC (R_V850_REGDW8, 2, 8, 2, signed, FALSE, v850),
+ V800_RELOC (R_V810_EPBYTE, 0, 8, 0, dont, FALSE, v850),
+ V800_RELOC (R_V810_EPHWORD, 1, 16, 0, dont, FALSE, v850),
+ V800_RELOC (R_V810_EPWORD, 2, 32, 0, dont, FALSE, v850),
+ V800_RELOC (R_V850_WLO23, 2, 32, 1, dont, FALSE, v850),
+ V800_RELOC (R_V850_WORD_E, 2, 32, 1, dont, FALSE, v850),
+ V800_RELOC (R_V850_REGWORD_E, 2, 32, 1, dont, FALSE, v850),
+ V800_RELOC (R_V850_WORD, 2, 32, 0, dont, FALSE, v850),
+ V800_RELOC (R_V850_GPWORD, 2, 32, 0, dont, FALSE, v850),
+ V800_RELOC (R_V850_REGWORD, 2, 32, 0, dont, FALSE, v850),
+ V800_RELOC (R_V850_EPWORD, 2, 32, 0, dont, FALSE, v850),
+ V800_RELOC (R_V810_TPBYTE, 0, 8, 0, dont, FALSE, v850),
+ V800_RELOC (R_V810_TPHWORD, 1, 16, 0, dont, FALSE, v850),
+ V800_RELOC (R_V810_TPWORD, 2, 32, 0, dont, FALSE, v850),
+ V800_RELOC (R_V810_TPWLO, 1, 16, 0, dont, FALSE, v850),
+ V800_RELOC (R_V810_TPWHI, 1, 16, 0, dont, FALSE, v850),
+ V800_RELOC (R_V810_TPWHI1, 1, 16, 0, dont, FALSE, v850),
+ V800_RELOC (R_V850_TPHWLO, 1, 16, 1, dont, FALSE, v850),
+ V800_RELOC (R_V850_TPBLO, 2, 24, 0, dont, FALSE, v850),
+ V800_RELOC (R_V810_TPWLO_1, 1, 16, 0, signed, FALSE, v850),
+ V800_RELOC (R_V850_TPBLO_1, 2, 16, 0, signed, FALSE, v850),
+ V800_RELOC (R_V850_TPHWLO_1, 1, 16, 0, signed, FALSE, v850),
+ V800_RELOC (R_V850_TP23BIT, 2, 23, 0, signed, FALSE, v850),
+ V800_RELOC (R_V850_TPW23BIT, 2, 23, 0, signed, FALSE, v850),
+ V800_RELOC (R_V850_TPDW8, 2, 8, 0, signed, FALSE, v850)
+};
+
+/* Map a bfd relocation into the appropriate howto structure. */
+
+static reloc_howto_type *
+v850_elf_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ bfd_reloc_code_real_type code)
+{
+ unsigned int i;
+
+ for (i = ARRAY_SIZE (v850_elf_reloc_map); i --;)
+ if (v850_elf_reloc_map[i].bfd_reloc_val == code)
+ {
+ unsigned int elf_reloc_val = v850_elf_reloc_map[i].elf_reloc_val;
+
+ BFD_ASSERT (v850_elf_howto_table[elf_reloc_val].type == elf_reloc_val);
+
+ return v850_elf_howto_table + elf_reloc_val;
+ }
+
+ return NULL;
+}
+
+static reloc_howto_type *
+v850_elf_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ const char *r_name)
+{
+ unsigned int i;
+
+ for (i = 0;
+ i < sizeof (v850_elf_howto_table) / sizeof (v850_elf_howto_table[0]);
+ i++)
+ if (v850_elf_howto_table[i].name != NULL
+ && strcasecmp (v850_elf_howto_table[i].name, r_name) == 0)
+ return &v850_elf_howto_table[i];
+
+ return NULL;
+}
+
+/* Set the howto pointer for an V850 ELF reloc. */
+
+static void
+v850_elf_info_to_howto_rel (bfd *abfd ATTRIBUTE_UNUSED,
+ arelent *cache_ptr,
+ Elf_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];
+}
+
+/* Set the howto pointer for a V850 ELF reloc (type RELA). */
+
+static void
+v850_elf_info_to_howto_rela (bfd *abfd ATTRIBUTE_UNUSED,
+ arelent * cache_ptr,
+ Elf_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];
+}
+
+static bfd_boolean
+v850_elf_is_local_label_name (bfd *abfd ATTRIBUTE_UNUSED, const char *name)
+{
+ return ( (name[0] == '.' && (name[1] == 'L' || name[1] == '.'))
+ || (name[0] == '_' && name[1] == '.' && name[2] == 'L' && name[3] == '_'));
+}
+
+static bfd_boolean
+v850_elf_is_target_special_symbol (bfd *abfd, asymbol *sym)
+{
+ return v850_elf_is_local_label_name (abfd, sym->name);
+}
+
+/* We overload some of the bfd_reloc error codes for own purposes. */
+#define bfd_reloc_gp_not_found bfd_reloc_other
+#define bfd_reloc_ep_not_found bfd_reloc_continue
+#define bfd_reloc_ctbp_not_found (bfd_reloc_dangerous + 1)
+
+/* Perform a relocation as part of a final link. */
+
+static bfd_reloc_status_type
+v850_elf_final_link_relocate (reloc_howto_type *howto,
+ bfd *input_bfd,
+ bfd *output_bfd ATTRIBUTE_UNUSED,
+ 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 ATTRIBUTE_UNUSED)
+{
+ unsigned int r_type = howto->type;
+ bfd_byte *hit_data = contents + offset;
+
+ /* Adjust the value according to the relocation. */
+ switch (r_type)
+ {
+ case R_V850_PC9:
+ case R_V850_9_PCREL:
+ value -= (input_section->output_section->vma
+ + input_section->output_offset);
+ value -= offset;
+ break;
+
+ case R_V850_PC16U:
+ case R_V850_16_PCREL:
+ value -= (input_section->output_section->vma
+ + input_section->output_offset
+ + offset);
+
+ /* If the sign extension will corrupt the value then we have overflowed. */
+ if ((value & 0xffff0000) != 0xffff0000)
+ return bfd_reloc_overflow;
+
+ break;
+
+ case R_V850_PC17:
+ case R_V850_17_PCREL:
+ value -= (input_section->output_section->vma
+ + input_section->output_offset
+ + offset);
+
+ /* If the sign extension will corrupt the value then we have overflowed. */
+ if (((value & 0xffff0000) != 0x0) && ((value & 0xffff0000) != 0xffff0000))
+ return bfd_reloc_overflow;
+
+ value = SEXT17 (value);
+ break;
+
+ case R_V850_PCR22:
+ case R_V850_22_PCREL:
+ value -= (input_section->output_section->vma
+ + input_section->output_offset
+ + offset);
+
+ /* If the sign extension will corrupt the value then we have overflowed. */
+ if (((value & 0xffe00000) != 0x0) && ((value & 0xffe00000) != 0xffe00000))
+ return bfd_reloc_overflow;
+
+ /* Only the bottom 22 bits of the PC are valid. */
+ value = SEXT22 (value);
+ break;
+
+ case R_V850_PC32:
+ case R_V850_32_PCREL:
+ value -= (input_section->output_section->vma
+ + input_section->output_offset
+ + offset);
+ break;
+
+ case R_V850_32_ABS:
+ case R_V850_23:
+ case R_V850_HI16_S:
+ case R_V850_HI16:
+ case R_V850_LO16:
+ case R_V850_LO16_S1:
+ case R_V850_LO16_SPLIT_OFFSET:
+ case R_V850_16:
+ case R_V850_ABS32:
+ case R_V850_8:
+ case R_V810_BYTE:
+ case R_V810_HWORD:
+ case R_V810_WORD:
+ case R_V810_WLO:
+ case R_V810_WHI:
+ case R_V810_WHI1:
+ case R_V810_WLO_1:
+ case R_V850_WLO23:
+ case R_V850_BLO:
+ 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:
+ case R_V810_GPWLO_1:
+ {
+ 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 == NULL
+ || h->type != bfd_link_hash_defined)
+ return bfd_reloc_gp_not_found;
+
+ 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_7_7_OFFSET:
+ case R_V850_TDA_7_8_OFFSET:
+ case R_V850_TDA_6_8_OFFSET:
+ case R_V850_TDA_16_16_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 == NULL
+ || h->type != bfd_link_hash_defined)
+ return bfd_reloc_ep_not_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 == NULL
+ || h->type != bfd_link_hash_defined)
+ return bfd_reloc_ctbp_not_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_15_16_OFFSET:
+ 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 == NULL
+ || h->type != bfd_link_hash_defined)
+ return bfd_reloc_ctbp_not_found;
+
+ 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_V810_NONE:
+ case R_V850_GNU_VTINHERIT:
+ case R_V850_GNU_VTENTRY:
+ case R_V850_LONGCALL:
+ case R_V850_LONGJUMP:
+ case R_V850_ALIGN:
+ return bfd_reloc_ok;
+
+ default:
+#ifdef DEBUG
+ fprintf (stderr, "reloc number %d not recognised\n", r_type);
+#endif
+ 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 bfd_boolean
+v850_elf_relocate_section (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);
+
+ /* 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++)
+ {
+ unsigned 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;
+
+ if (bfd_get_arch (input_bfd) == bfd_arch_v850_rh850)
+ howto = v800_elf_howto_table + (r_type - R_V810_NONE);
+ else
+ howto = v850_elf_howto_table + r_type;
+
+ BFD_ASSERT (r_type == howto->type);
+
+ h = NULL;
+ sym = NULL;
+ sec = NULL;
+ if (r_symndx < symtab_hdr->sh_info)
+ {
+ sym = local_syms + r_symndx;
+ sec = local_sections[r_symndx];
+ relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
+ }
+ else
+ {
+ bfd_boolean unresolved_reloc, warned, ignored;
+
+ /* Note - this check is delayed until now as it is possible and
+ valid to have a file without any symbols but with relocs that
+ can be processed. */
+ if (sym_hashes == NULL)
+ {
+ info->callbacks->warning
+ (info, "no hash table available",
+ NULL, input_bfd, input_section, (bfd_vma) 0);
+
+ return FALSE;
+ }
+
+ RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
+ r_symndx, symtab_hdr, sym_hashes,
+ h, sec, relocation,
+ unresolved_reloc, warned, ignored);
+ }
+
+ if (sec != NULL && discarded_section (sec))
+ RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+ rel, 1, relend, howto, 0, contents);
+
+ if (info->relocatable)
+ continue;
+
+ /* 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 = NULL;
+
+ 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 ((int) r)
+ {
+ case bfd_reloc_overflow:
+ if (! ((*info->callbacks->reloc_overflow)
+ (info, (h ? &h->root : NULL), 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, TRUE)))
+ 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_gp_not_found:
+ msg = _("could not locate special linker symbol __gp");
+ goto common_error;
+
+ case bfd_reloc_ep_not_found:
+ msg = _("could not locate special linker symbol __ep");
+ goto common_error;
+
+ case bfd_reloc_ctbp_not_found:
+ 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 asection *
+v850_elf_gc_mark_hook (asection *sec,
+ 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:
+ return NULL;
+ }
+
+ return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
+}
+
+/* Set the right machine number and architecture. */
+
+static bfd_boolean
+v850_elf_object_p (bfd *abfd)
+{
+ enum bfd_architecture arch;
+ unsigned long mach;
+
+ switch (elf_elfheader (abfd)->e_machine)
+ {
+ case EM_V800:
+ arch = bfd_arch_v850_rh850;
+ mach = (elf_elfheader (abfd)->e_flags & EF_V800_850E3)
+ ? bfd_mach_v850e3v5 : bfd_mach_v850e2v3;
+ break;
+
+ case EM_CYGNUS_V850:
+ case EM_V850:
+ arch = bfd_arch_v850;
+ switch (elf_elfheader (abfd)->e_flags & EF_V850_ARCH)
+ {
+ default:
+ case E_V850_ARCH: mach = bfd_mach_v850; break;
+ case E_V850E_ARCH: mach = bfd_mach_v850e; break;
+ case E_V850E1_ARCH: mach = bfd_mach_v850e1; break;
+ case E_V850E2_ARCH: mach = bfd_mach_v850e2; break;
+ case E_V850E2V3_ARCH: mach = bfd_mach_v850e2v3; break;
+ case E_V850E3V5_ARCH: mach = bfd_mach_v850e3v5; break;
+ }
+ break;
+
+ default:
+ return FALSE;
+ }
+
+ return bfd_default_set_arch_mach (abfd, arch, mach);
+}
+
+/* Store the machine number in the flags field. */
+
+static void
+v850_elf_final_write_processing (bfd *abfd,
+ bfd_boolean linker ATTRIBUTE_UNUSED)
+{
+ unsigned long val;
+
+ switch (bfd_get_arch (abfd))
+ {
+ case bfd_arch_v850_rh850:
+ val = EF_RH850_ABI;
+ if (bfd_get_mach (abfd) == bfd_mach_v850e3v5)
+ val |= EF_V800_850E3;
+ elf_elfheader (abfd)->e_flags |= val;
+ break;
+
+ case bfd_arch_v850:
+ switch (bfd_get_mach (abfd))
+ {
+ default:
+ case bfd_mach_v850: val = E_V850_ARCH; break;
+ case bfd_mach_v850e: val = E_V850E_ARCH; break;
+ case bfd_mach_v850e1: val = E_V850E1_ARCH; break;
+ case bfd_mach_v850e2: val = E_V850E2_ARCH; break;
+ case bfd_mach_v850e2v3: val = E_V850E2V3_ARCH; break;
+ case bfd_mach_v850e3v5: val = E_V850E3V5_ARCH; break;
+ }
+ elf_elfheader (abfd)->e_flags &=~ EF_V850_ARCH;
+ elf_elfheader (abfd)->e_flags |= val;
+ break;
+ default:
+ break;
+ }
+}
+
+/* Function to keep V850 specific file flags. */
+
+static bfd_boolean
+v850_elf_set_private_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;
+}
+
+/* Merge backend specific data from an object file
+ to the output object file when linking. */
+
+static bfd_boolean
+v850_elf_merge_private_bfd_data (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 (bfd_get_arch (obfd) == bfd_arch_v850_rh850)
+ {
+ if ((in_flags & EF_V800_850E3) != (out_flags & EF_V800_850E3))
+ {
+ _bfd_error_handler (_("%B: Architecture mismatch with previous modules"),
+ ibfd);
+ elf_elfheader (obfd)->e_flags |= EF_V800_850E3;
+ }
+
+ if ((in_flags & EF_RH850_DATA_ALIGN8) != (out_flags & EF_RH850_DATA_ALIGN8))
+ {
+ _bfd_error_handler (_("%B: Alignment mismatch with previous modules"),
+ ibfd);
+ elf_elfheader (obfd)->e_flags |= EF_RH850_DATA_ALIGN8;
+ }
+
+ return TRUE;
+ }
+
+ if ((in_flags & EF_V850_ARCH) != (out_flags & EF_V850_ARCH)
+ && (in_flags & EF_V850_ARCH) != E_V850_ARCH)
+ {
+ /* Allow earlier architecture binaries to be linked with later binaries.
+ Set the output binary to the later architecture, except for v850e1,
+ which we set to v850e. */
+ if ( (in_flags & EF_V850_ARCH) == E_V850E1_ARCH
+ && (out_flags & EF_V850_ARCH) == E_V850E_ARCH)
+ return TRUE;
+
+ if ( (in_flags & EF_V850_ARCH) == E_V850_ARCH
+ && (out_flags & EF_V850_ARCH) == E_V850E_ARCH)
+ {
+ elf_elfheader (obfd)->e_flags =
+ ((out_flags & ~ EF_V850_ARCH) | E_V850E_ARCH);
+ return TRUE;
+ }
+
+ if (( (in_flags & EF_V850_ARCH) == E_V850_ARCH
+ || (in_flags & EF_V850_ARCH) == E_V850E_ARCH)
+ && (out_flags & EF_V850_ARCH) == E_V850E2_ARCH)
+ {
+ elf_elfheader (obfd)->e_flags =
+ ((out_flags & ~ EF_V850_ARCH) | E_V850E2_ARCH);
+ return TRUE;
+ }
+
+ if (( (in_flags & EF_V850_ARCH) == E_V850_ARCH
+ || (in_flags & EF_V850_ARCH) == E_V850E_ARCH
+ || (in_flags & EF_V850_ARCH) == E_V850E2_ARCH)
+ && (out_flags & EF_V850_ARCH) == E_V850E2V3_ARCH)
+ {
+ elf_elfheader (obfd)->e_flags =
+ ((out_flags & ~ EF_V850_ARCH) | E_V850E2V3_ARCH);
+ return TRUE;
+ }
+
+ if (( (in_flags & EF_V850_ARCH) == E_V850_ARCH
+ || (in_flags & EF_V850_ARCH) == E_V850E_ARCH
+ || (in_flags & EF_V850_ARCH) == E_V850E2_ARCH
+ || (in_flags & EF_V850_ARCH) == E_V850E2V3_ARCH)
+ && (out_flags & EF_V850_ARCH) == E_V850E3V5_ARCH)
+ {
+ elf_elfheader (obfd)->e_flags =
+ ((out_flags & ~ EF_V850_ARCH) | E_V850E3V5_ARCH);
+ return TRUE;
+ }
+
+ _bfd_error_handler (_("%B: Architecture mismatch with previous modules"),
+ ibfd);
+ }
+
+ return TRUE;
+}
+
+/* Display the flags field. */
+
+static bfd_boolean
+v850_elf_print_private_bfd_data (bfd *abfd, void * 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);
+
+ if (bfd_get_arch (abfd) == bfd_arch_v850_rh850)
+ {
+ if ((elf_elfheader (abfd)->e_flags & EF_RH850_ABI) != EF_RH850_ABI)
+ fprintf (file, _("unknown v850 architecture"));
+ else if (elf_elfheader (abfd)->e_flags & EF_V800_850E3)
+ fprintf (file, _("v850 E3 architecture"));
+ else
+ fprintf (file, _("v850 architecture"));
+
+ if (elf_elfheader (abfd)->e_flags & EF_RH850_DATA_ALIGN8)
+ fprintf (file, _(", 8-byte data alignment"));
+ }
+ else
+ {
+ 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_V850E1_ARCH: fprintf (file, _("v850e1 architecture")); break;
+ case E_V850E2_ARCH: fprintf (file, _("v850e2 architecture")); break;
+ case E_V850E2V3_ARCH: fprintf (file, _("v850e2v3 architecture")); break;
+ case E_V850E3V5_ARCH: fprintf (file, _("v850e3v5 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 bfd_boolean
+v850_elf_section_from_bfd_section (bfd *abfd ATTRIBUTE_UNUSED,
+ 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 (bfd *abfd, asymbol *asym)
+{
+ elf_symbol_type * elfsym = (elf_symbol_type *) asym;
+ unsigned int indx;
+
+ indx = 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 (indx < elf_numsections (abfd))
+ switch (elf_elfsections (abfd)[indx]->sh_type)
+ {
+ case SHT_V850_SCOMMON:
+ indx = SHN_V850_SCOMMON;
+ break;
+
+ case SHT_V850_TCOMMON:
+ indx = SHN_V850_TCOMMON;
+ break;
+
+ case SHT_V850_ZCOMMON:
+ indx = SHN_V850_ZCOMMON;
+ break;
+
+ default:
+ break;
+ }
+
+ switch (indx)
+ {
+ 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. */
+
+static bfd_boolean
+v850_elf_add_symbol_hook (bfd *abfd,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ Elf_Internal_Sym *sym,
+ const char **namep ATTRIBUTE_UNUSED,
+ flagword *flagsp ATTRIBUTE_UNUSED,
+ asection **secp,
+ bfd_vma *valp)
+{
+ unsigned int indx = 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 (indx < elf_numsections (abfd))
+ switch (elf_elfsections (abfd)[indx]->sh_type)
+ {
+ case SHT_V850_SCOMMON:
+ indx = SHN_V850_SCOMMON;
+ break;
+
+ case SHT_V850_TCOMMON:
+ indx = SHN_V850_TCOMMON;
+ break;
+
+ case SHT_V850_ZCOMMON:
+ indx = SHN_V850_ZCOMMON;
+ break;
+
+ default:
+ break;
+ }
+
+ switch (indx)
+ {
+ 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;
+}
+
+static int
+v850_elf_link_output_symbol_hook (struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ const char *name ATTRIBUTE_UNUSED,
+ Elf_Internal_Sym *sym,
+ asection *input_sec,
+ struct elf_link_hash_entry *h ATTRIBUTE_UNUSED)
+{
+ /* 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;
+ }
+
+ /* The price we pay for using h->other unused bits as flags in the
+ linker is cleaning up after ourselves. */
+
+ sym->st_other &= ~(V850_OTHER_SDA | V850_OTHER_ZDA | V850_OTHER_TDA
+ | V850_OTHER_ERROR);
+
+ return 1;
+}
+
+static bfd_boolean
+v850_elf_section_from_shdr (bfd *abfd,
+ Elf_Internal_Shdr *hdr,
+ const char *name,
+ int shindex)
+{
+ /* 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, shindex))
+ 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 bfd_boolean
+v850_elf_fake_sections (bfd *abfd ATTRIBUTE_UNUSED,
+ Elf_Internal_Shdr *hdr,
+ asection *sec)
+{
+ 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;
+}
+
+/* Delete some bytes from a section while relaxing. */
+
+static bfd_boolean
+v850_elf_relax_delete_bytes (bfd *abfd,
+ asection *sec,
+ bfd_vma addr,
+ bfd_vma toaddr,
+ int count)
+{
+ Elf_Internal_Shdr *symtab_hdr;
+ Elf32_External_Sym *extsyms;
+ Elf32_External_Sym *esym;
+ Elf32_External_Sym *esymend;
+ int sym_index;
+ unsigned int sec_shndx;
+ bfd_byte *contents;
+ Elf_Internal_Rela *irel;
+ Elf_Internal_Rela *irelend;
+ struct elf_link_hash_entry *sym_hash;
+ Elf_Internal_Shdr *shndx_hdr;
+ Elf_External_Sym_Shndx *shndx;
+
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+ extsyms = (Elf32_External_Sym *) symtab_hdr->contents;
+
+ sec_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 alignment
+ power larger than the number of bytes we are deleting. */
+
+ /* Actually delete the bytes. */
+#if (DEBUG_RELAX & 2)
+ fprintf (stderr, "relax_delete: contents: sec: %s %p .. %p %x\n",
+ sec->name, addr, toaddr, count );
+#endif
+ memmove (contents + addr, contents + addr + count,
+ toaddr - addr - count);
+ memset (contents + toaddr-count, 0, count);
+
+ /* Adjust all the relocs. */
+ irel = elf_section_data (sec)->relocs;
+ irelend = irel + sec->reloc_count;
+ shndx_hdr = &elf_tdata (abfd)->symtab_shndx_hdr;
+ shndx = (Elf_External_Sym_Shndx *) shndx_hdr->contents;
+
+ for (; irel < irelend; irel++)
+ {
+ bfd_vma raddr, paddr, symval;
+ Elf_Internal_Sym isym;
+
+ /* Get the new reloc address. */
+ raddr = irel->r_offset;
+ if ((raddr >= (addr + count) && raddr < toaddr))
+ irel->r_offset -= count;
+
+ if (raddr >= addr && raddr < addr + count)
+ {
+ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
+ (int) R_V850_NONE);
+ continue;
+ }
+
+ if (ELF32_R_TYPE (irel->r_info) == (int) R_V850_ALIGN)
+ continue;
+
+ bfd_elf32_swap_symbol_in (abfd,
+ extsyms + ELF32_R_SYM (irel->r_info),
+ shndx ? shndx + ELF32_R_SYM (irel->r_info) : NULL,
+ & isym);
+
+ if (isym.st_shndx != sec_shndx)
+ continue;
+
+ /* Get the value of the symbol referred to by the reloc. */
+ if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
+ {
+ symval = isym.st_value;
+#if (DEBUG_RELAX & 2)
+ {
+ char * name = bfd_elf_string_from_elf_section
+ (abfd, symtab_hdr->sh_link, isym.st_name);
+ fprintf (stderr,
+ "relax_delete: local: sec: %s, sym: %s (%d), value: %x + %x + %x addend %x\n",
+ sec->name, name, isym.st_name,
+ sec->output_section->vma, sec->output_offset,
+ isym.st_value, irel->r_addend);
+ }
+#endif
+ }
+ 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);
+
+ symval = h->root.u.def.value;
+#if (DEBUG_RELAX & 2)
+ fprintf (stderr,
+ "relax_delete: defined: sec: %s, name: %s, value: %x + %x + %x addend %x\n",
+ sec->name, h->root.root.string, h->root.u.def.value,
+ sec->output_section->vma, sec->output_offset, irel->r_addend);
+#endif
+ }
+
+ paddr = symval + irel->r_addend;
+
+ if ( (symval >= addr + count && symval < toaddr)
+ && (paddr < addr + count || paddr >= toaddr))
+ irel->r_addend += count;
+ else if ( (symval < addr + count || symval >= toaddr)
+ && (paddr >= addr + count && paddr < toaddr))
+ irel->r_addend -= count;
+ }
+
+ /* Adjust the local symbols defined in this section. */
+ esym = extsyms;
+ esymend = esym + symtab_hdr->sh_info;
+
+ for (; esym < esymend; esym++, shndx = (shndx ? shndx + 1 : NULL))
+ {
+ Elf_Internal_Sym isym;
+
+ bfd_elf32_swap_symbol_in (abfd, esym, shndx, & isym);
+
+ if (isym.st_shndx == sec_shndx
+ && isym.st_value >= addr + count
+ && isym.st_value < toaddr)
+ {
+ isym.st_value -= count;
+
+ if (isym.st_value + isym.st_size >= toaddr)
+ isym.st_size += count;
+
+ bfd_elf32_swap_symbol_out (abfd, & isym, esym, shndx);
+ }
+ else if (isym.st_shndx == sec_shndx
+ && isym.st_value < addr + count)
+ {
+ if (isym.st_value+isym.st_size >= addr + count
+ && isym.st_value+isym.st_size < toaddr)
+ isym.st_size -= count;
+
+ if (isym.st_value >= addr
+ && isym.st_value < addr + count)
+ isym.st_value = addr;
+
+ bfd_elf32_swap_symbol_out (abfd, & isym, esym, shndx);
+ }
+ }
+
+ /* 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 (sym_index = 0; esym < esymend; esym ++, sym_index ++)
+ {
+ Elf_Internal_Sym isym;
+
+ bfd_elf32_swap_symbol_in (abfd, esym, shndx, & isym);
+ sym_hash = elf_sym_hashes (abfd) [sym_index];
+
+ if (isym.st_shndx == sec_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 + count
+ && (sym_hash)->root.u.def.value < toaddr)
+ {
+ if ((sym_hash)->root.u.def.value + isym.st_size >= toaddr)
+ {
+ isym.st_size += count;
+ bfd_elf32_swap_symbol_out (abfd, & isym, esym, shndx);
+ }
+
+ (sym_hash)->root.u.def.value -= count;
+ }
+ else if (isym.st_shndx == sec_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 + count)
+ {
+ if ((sym_hash)->root.u.def.value+isym.st_size >= addr + count
+ && (sym_hash)->root.u.def.value+isym.st_size < toaddr)
+ isym.st_size -= count;
+
+ if ((sym_hash)->root.u.def.value >= addr
+ && (sym_hash)->root.u.def.value < addr + count)
+ (sym_hash)->root.u.def.value = addr;
+
+ bfd_elf32_swap_symbol_out (abfd, & isym, esym, shndx);
+ }
+
+ if (shndx)
+ ++ shndx;
+ }
+
+ return TRUE;
+}
+
+#define NOP_OPCODE (0x0000)
+#define MOVHI 0x0640 /* 4byte. */
+#define MOVHI_MASK 0x07e0
+#define MOVHI_R1(insn) ((insn) & 0x1f) /* 4byte. */
+#define MOVHI_R2(insn) ((insn) >> 11)
+#define MOVEA 0x0620 /* 2byte. */
+#define MOVEA_MASK 0x07e0
+#define MOVEA_R1(insn) ((insn) & 0x1f)
+#define MOVEA_R2(insn) ((insn) >> 11)
+#define JARL_4 0x00040780 /* 4byte. */
+#define JARL_4_MASK 0xFFFF07FF
+#define JARL_R2(insn) (int)(((insn) & (~JARL_4_MASK)) >> 11)
+#define ADD_I 0x0240 /* 2byte. */
+#define ADD_I_MASK 0x07e0
+#define ADD_I5(insn) ((((insn) & 0x001f) << 11) >> 11) /* 2byte. */
+#define ADD_R2(insn) ((insn) >> 11)
+#define JMP_R 0x0060 /* 2byte. */
+#define JMP_R_MASK 0xFFE0
+#define JMP_R1(insn) ((insn) & 0x1f)
+
+static bfd_boolean
+v850_elf_relax_section (bfd *abfd,
+ asection *sec,
+ struct bfd_link_info *link_info,
+ bfd_boolean *again)
+{
+ Elf_Internal_Shdr *symtab_hdr;
+ Elf_Internal_Rela *internal_relocs;
+ Elf_Internal_Rela *irel;
+ Elf_Internal_Rela *irelend;
+ Elf_Internal_Rela *irelalign = NULL;
+ Elf_Internal_Sym *isymbuf = NULL;
+ bfd_byte *contents = NULL;
+ bfd_vma addr = 0;
+ bfd_vma toaddr;
+ int align_pad_size = 0;
+ bfd_boolean result = TRUE;
+
+ *again = FALSE;
+
+ if (link_info->relocatable
+ || (sec->flags & SEC_RELOC) == 0
+ || sec->reloc_count == 0)
+ return TRUE;
+
+ symtab_hdr = & elf_tdata (abfd)->symtab_hdr;
+
+ internal_relocs = (_bfd_elf_link_read_relocs
+ (abfd, sec, NULL, NULL, link_info->keep_memory));
+ if (internal_relocs == NULL)
+ goto error_return;
+
+ irelend = internal_relocs + sec->reloc_count;
+
+ while (addr < sec->size)
+ {
+ toaddr = sec->size;
+
+ for (irel = internal_relocs; irel < irelend; irel ++)
+ if (ELF32_R_TYPE (irel->r_info) == (int) R_V850_ALIGN
+ && irel->r_offset > addr
+ && irel->r_offset < toaddr)
+ toaddr = irel->r_offset;
+
+#ifdef DEBUG_RELAX
+ fprintf (stderr, "relax region 0x%x to 0x%x align pad %d\n",
+ addr, toaddr, align_pad_size);
+#endif
+ if (irelalign)
+ {
+ bfd_vma alignto;
+ bfd_vma alignmoveto;
+
+ alignmoveto = BFD_ALIGN (addr - align_pad_size, 1 << irelalign->r_addend);
+ alignto = BFD_ALIGN (addr, 1 << irelalign->r_addend);
+
+ if (alignmoveto < alignto)
+ {
+ bfd_vma i;
+
+ align_pad_size = alignto - alignmoveto;
+#ifdef DEBUG_RELAX
+ fprintf (stderr, "relax move region 0x%x to 0x%x delete size 0x%x\n",
+ alignmoveto, toaddr, align_pad_size);
+#endif
+ if (!v850_elf_relax_delete_bytes (abfd, sec, alignmoveto,
+ toaddr, align_pad_size))
+ goto error_return;
+
+ for (i = BFD_ALIGN (toaddr - align_pad_size, 1);
+ (i + 1) < toaddr; i += 2)
+ bfd_put_16 (abfd, NOP_OPCODE, contents + i);
+
+ addr = alignmoveto;
+ }
+ else
+ align_pad_size = 0;
+ }
+
+ for (irel = internal_relocs; irel < irelend; irel++)
+ {
+ bfd_vma laddr;
+ bfd_vma addend;
+ bfd_vma symval;
+ int insn[5];
+ int no_match = -1;
+ Elf_Internal_Rela *hi_irelfn;
+ Elf_Internal_Rela *lo_irelfn;
+ Elf_Internal_Rela *irelcall;
+ bfd_signed_vma foff;
+ unsigned int r_type;
+
+ if (! (irel->r_offset >= addr && irel->r_offset < toaddr
+ && (ELF32_R_TYPE (irel->r_info) == (int) R_V850_LONGCALL
+ || ELF32_R_TYPE (irel->r_info) == (int) R_V850_LONGJUMP)))
+ continue;
+
+#ifdef DEBUG_RELAX
+ fprintf (stderr, "relax check r_info 0x%x r_offset 0x%x r_addend 0x%x\n",
+ irel->r_info,
+ irel->r_offset,
+ irel->r_addend );
+#endif
+
+ /* 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
+ {
+ if (! bfd_malloc_and_get_section (abfd, sec, &contents))
+ goto error_return;
+ }
+ }
+
+ /* Read this BFD's local symbols if we haven't done so already. */
+ if (isymbuf == NULL && symtab_hdr->sh_info != 0)
+ {
+ isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
+ if (isymbuf == NULL)
+ isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
+ symtab_hdr->sh_info, 0,
+ NULL, NULL, NULL);
+ if (isymbuf == NULL)
+ goto error_return;
+ }
+
+ laddr = irel->r_offset;
+
+ if (ELF32_R_TYPE (irel->r_info) == (int) R_V850_LONGCALL)
+ {
+ /* Check code for -mlong-calls output. */
+ if (laddr + 16 <= (bfd_vma) sec->size)
+ {
+ insn[0] = bfd_get_16 (abfd, contents + laddr);
+ insn[1] = bfd_get_16 (abfd, contents + laddr + 4);
+ insn[2] = bfd_get_32 (abfd, contents + laddr + 8);
+ insn[3] = bfd_get_16 (abfd, contents + laddr + 12);
+ insn[4] = bfd_get_16 (abfd, contents + laddr + 14);
+
+ if ((insn[0] & MOVHI_MASK) != MOVHI
+ || MOVHI_R1 (insn[0]) != 0)
+ no_match = 0;
+
+ if (no_match < 0
+ && ((insn[1] & MOVEA_MASK) != MOVEA
+ || MOVHI_R2 (insn[0]) != MOVEA_R1 (insn[1])))
+ no_match = 1;
+
+ if (no_match < 0
+ && (insn[2] & JARL_4_MASK) != JARL_4)
+ no_match = 2;
+
+ if (no_match < 0
+ && ((insn[3] & ADD_I_MASK) != ADD_I
+ || ADD_I5 (insn[3]) != 4
+ || JARL_R2 (insn[2]) != ADD_R2 (insn[3])))
+ no_match = 3;
+
+ if (no_match < 0
+ && ((insn[4] & JMP_R_MASK) != JMP_R
+ || MOVEA_R2 (insn[1]) != JMP_R1 (insn[4])))
+ no_match = 4;
+ }
+ else
+ {
+ ((*_bfd_error_handler)
+ ("%s: 0x%lx: warning: R_V850_LONGCALL points to unrecognized insns",
+ bfd_get_filename (abfd), (unsigned long) irel->r_offset));
+
+ continue;
+ }
+
+ if (no_match >= 0)
+ {
+ ((*_bfd_error_handler)
+ ("%s: 0x%lx: warning: R_V850_LONGCALL points to unrecognized insn 0x%x",
+ bfd_get_filename (abfd), (unsigned long) irel->r_offset+no_match, insn[no_match]));
+
+ 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 (hi_irelfn = internal_relocs; hi_irelfn < irelend; hi_irelfn ++)
+ {
+ r_type = ELF32_R_TYPE (hi_irelfn->r_info);
+
+ if (hi_irelfn->r_offset == laddr + 2
+ && (r_type == (int) R_V850_HI16_S || r_type == (int) R_V810_WHI1))
+ break;
+ }
+
+ for (lo_irelfn = internal_relocs; lo_irelfn < irelend; lo_irelfn ++)
+ {
+ r_type = ELF32_R_TYPE (lo_irelfn->r_info);
+
+ if (lo_irelfn->r_offset == laddr + 6
+ && (r_type == (int) R_V850_LO16 || r_type == (int) R_V810_WLO))
+ break;
+ }
+
+ for (irelcall = internal_relocs; irelcall < irelend; irelcall ++)
+ {
+ r_type = ELF32_R_TYPE (irelcall->r_info);
+
+ if (irelcall->r_offset == laddr + 8
+ && (r_type == (int) R_V850_22_PCREL || r_type == (int) R_V850_PCR22))
+ break;
+ }
+
+ if ( hi_irelfn == irelend
+ || lo_irelfn == irelend
+ || irelcall == irelend)
+ {
+ ((*_bfd_error_handler)
+ ("%s: 0x%lx: warning: R_V850_LONGCALL points to unrecognized reloc",
+ bfd_get_filename (abfd), (unsigned long) irel->r_offset ));
+
+ continue;
+ }
+
+ if (ELF32_R_SYM (irelcall->r_info) < symtab_hdr->sh_info)
+ {
+ Elf_Internal_Sym * isym;
+
+ /* A local symbol. */
+ isym = isymbuf + ELF32_R_SYM (irelcall->r_info);
+
+ symval = isym->st_value;
+ }
+ else
+ {
+ unsigned long indx;
+ struct elf_link_hash_entry * h;
+
+ /* An external symbol. */
+ indx = ELF32_R_SYM (irelcall->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;
+ }
+
+ if (symval + irelcall->r_addend != irelcall->r_offset + 4)
+ {
+ ((*_bfd_error_handler)
+ ("%s: 0x%lx: warning: R_V850_LONGCALL points to unrecognized reloc 0x%lx",
+ bfd_get_filename (abfd), (unsigned long) irel->r_offset, irelcall->r_offset ));
+
+ continue;
+ }
+
+ /* Get the value of the symbol referred to by the reloc. */
+ if (ELF32_R_SYM (hi_irelfn->r_info) < symtab_hdr->sh_info)
+ {
+ Elf_Internal_Sym *isym;
+ asection *sym_sec;
+
+ /* A local symbol. */
+ isym = isymbuf + ELF32_R_SYM (hi_irelfn->r_info);
+
+ if (isym->st_shndx == SHN_UNDEF)
+ sym_sec = bfd_und_section_ptr;
+ 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;
+ else
+ 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 (hi_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);
+ }
+
+ addend = irel->r_addend;
+
+ foff = (symval + addend
+ - (irel->r_offset
+ + sec->output_section->vma
+ + sec->output_offset
+ + 4));
+#ifdef DEBUG_RELAX
+ fprintf (stderr, "relax longcall r_offset 0x%x ptr 0x%x symbol 0x%x addend 0x%x distance 0x%x\n",
+ irel->r_offset,
+ (irel->r_offset
+ + sec->output_section->vma
+ + sec->output_offset),
+ symval, addend, foff);
+#endif
+
+ if (foff < -0x100000 || foff >= 0x100000)
+ /* After all that work, we can't shorten this function call. */
+ continue;
+
+ /* 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;
+ elf_section_data (sec)->this_hdr.contents = contents;
+ symtab_hdr->contents = (bfd_byte *) isymbuf;
+
+ /* Replace the long call with a jarl. */
+ if (bfd_get_arch (abfd) == bfd_arch_v850_rh850)
+ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (hi_irelfn->r_info), R_V850_PCR22);
+ else
+ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (hi_irelfn->r_info), R_V850_22_PCREL);
+
+ addend = 0;
+
+ if (ELF32_R_SYM (hi_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_32 (abfd,
+ 0x00000780 | (JARL_R2 (insn[2])<<11) | ((addend << 16) & 0xffff) | ((addend >> 16) & 0xf),
+ 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_32 (abfd, 0x00000780 | (JARL_R2 (insn[2])<<11),
+ contents + irel->r_offset);
+
+ hi_irelfn->r_info =
+ ELF32_R_INFO (ELF32_R_SYM (hi_irelfn->r_info), R_V850_NONE);
+ lo_irelfn->r_info =
+ ELF32_R_INFO (ELF32_R_SYM (lo_irelfn->r_info), R_V850_NONE);
+ irelcall->r_info =
+ ELF32_R_INFO (ELF32_R_SYM (irelcall->r_info), R_V850_NONE);
+
+ if (! v850_elf_relax_delete_bytes (abfd, sec,
+ irel->r_offset + 4, toaddr, 12))
+ goto error_return;
+
+ align_pad_size += 12;
+ }
+ else if (ELF32_R_TYPE (irel->r_info) == (int) R_V850_LONGJUMP)
+ {
+ /* Check code for -mlong-jumps output. */
+ if (laddr + 10 <= (bfd_vma) sec->size)
+ {
+ insn[0] = bfd_get_16 (abfd, contents + laddr);
+ insn[1] = bfd_get_16 (abfd, contents + laddr + 4);
+ insn[2] = bfd_get_16 (abfd, contents + laddr + 8);
+
+ if ((insn[0] & MOVHI_MASK) != MOVHI
+ || MOVHI_R1 (insn[0]) != 0)
+ no_match = 0;
+
+ if (no_match < 0
+ && ((insn[1] & MOVEA_MASK) != MOVEA
+ || MOVHI_R2 (insn[0]) != MOVEA_R1 (insn[1])))
+ no_match = 1;
+
+ if (no_match < 0
+ && ((insn[2] & JMP_R_MASK) != JMP_R
+ || MOVEA_R2 (insn[1]) != JMP_R1 (insn[2])))
+ no_match = 4;
+ }
+ else
+ {
+ ((*_bfd_error_handler)
+ ("%s: 0x%lx: warning: R_V850_LONGJUMP points to unrecognized insns",
+ bfd_get_filename (abfd), (unsigned long) irel->r_offset));
+
+ continue;
+ }
+
+ if (no_match >= 0)
+ {
+ ((*_bfd_error_handler)
+ ("%s: 0x%lx: warning: R_V850_LONGJUMP points to unrecognized insn 0x%x",
+ bfd_get_filename (abfd), (unsigned long) irel->r_offset+no_match, insn[no_match]));
+
+ 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 (hi_irelfn = internal_relocs; hi_irelfn < irelend; hi_irelfn ++)
+ {
+ r_type = ELF32_R_TYPE (hi_irelfn->r_info);
+
+ if (hi_irelfn->r_offset == laddr + 2
+ && ((r_type == (int) R_V850_HI16_S) || r_type == (int) R_V810_WHI1))
+ break;
+ }
+
+ for (lo_irelfn = internal_relocs; lo_irelfn < irelend; lo_irelfn ++)
+ {
+ r_type = ELF32_R_TYPE (lo_irelfn->r_info);
+
+ if (lo_irelfn->r_offset == laddr + 6
+ && (r_type == (int) R_V850_LO16 || r_type == (int) R_V810_WLO))
+ break;
+ }
+
+ if ( hi_irelfn == irelend
+ || lo_irelfn == irelend)
+ {
+ ((*_bfd_error_handler)
+ ("%s: 0x%lx: warning: R_V850_LONGJUMP points to unrecognized reloc",
+ bfd_get_filename (abfd), (unsigned long) irel->r_offset ));
+
+ continue;
+ }
+
+ /* Get the value of the symbol referred to by the reloc. */
+ if (ELF32_R_SYM (hi_irelfn->r_info) < symtab_hdr->sh_info)
+ {
+ Elf_Internal_Sym * isym;
+ asection * sym_sec;
+
+ /* A local symbol. */
+ isym = isymbuf + ELF32_R_SYM (hi_irelfn->r_info);
+
+ if (isym->st_shndx == SHN_UNDEF)
+ sym_sec = bfd_und_section_ptr;
+ 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;
+ else
+ sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
+ symval = (isym->st_value
+ + sym_sec->output_section->vma
+ + sym_sec->output_offset);
+#ifdef DEBUG_RELAX
+ {
+ char * name = bfd_elf_string_from_elf_section
+ (abfd, symtab_hdr->sh_link, isym->st_name);
+
+ fprintf (stderr, "relax long jump local: sec: %s, sym: %s (%d), value: %x + %x + %x addend %x\n",
+ sym_sec->name, name, isym->st_name,
+ sym_sec->output_section->vma,
+ sym_sec->output_offset,
+ isym->st_value, irel->r_addend);
+ }
+#endif
+ }
+ 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);
+#ifdef DEBUG_RELAX
+ fprintf (stderr,
+ "relax longjump defined: sec: %s, name: %s, value: %x + %x + %x addend %x\n",
+ sec->name, h->root.root.string, h->root.u.def.value,
+ sec->output_section->vma, sec->output_offset, irel->r_addend);
+#endif
+ }
+
+ addend = irel->r_addend;
+
+ foff = (symval + addend
+ - (irel->r_offset
+ + sec->output_section->vma
+ + sec->output_offset
+ + 4));
+#ifdef DEBUG_RELAX
+ fprintf (stderr, "relax longjump r_offset 0x%x ptr 0x%x symbol 0x%x addend 0x%x distance 0x%x\n",
+ irel->r_offset,
+ (irel->r_offset
+ + sec->output_section->vma
+ + sec->output_offset),
+ symval, addend, foff);
+#endif
+ if (foff < -0x100000 || foff >= 0x100000)
+ /* After all that work, we can't shorten this function call. */
+ continue;
+
+ /* 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;
+ elf_section_data (sec)->this_hdr.contents = contents;
+ symtab_hdr->contents = (bfd_byte *) isymbuf;
+
+ if (foff < -0x100 || foff >= 0x100)
+ {
+ /* Replace the long jump with a jr. */
+
+ if (bfd_get_arch (abfd) == bfd_arch_v850_rh850)
+ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info), R_V850_PCR22);
+ else
+ irel->r_info =
+ ELF32_R_INFO (ELF32_R_SYM (irel->r_info), R_V850_22_PCREL);
+
+ irel->r_addend = addend;
+ addend = 0;
+
+ if (ELF32_R_SYM (hi_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_32 (abfd,
+ 0x00000780 | ((addend << 15) & 0xffff0000) | ((addend >> 17) & 0xf),
+ 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_32 (abfd, 0x00000780, contents + irel->r_offset);
+
+ hi_irelfn->r_info =
+ ELF32_R_INFO (ELF32_R_SYM (hi_irelfn->r_info), R_V850_NONE);
+ lo_irelfn->r_info =
+ ELF32_R_INFO (ELF32_R_SYM (lo_irelfn->r_info), R_V850_NONE);
+ if (!v850_elf_relax_delete_bytes (abfd, sec,
+ irel->r_offset + 4, toaddr, 6))
+ goto error_return;
+
+ align_pad_size += 6;
+ }
+ else
+ {
+ /* Replace the long jump with a br. */
+
+ if (bfd_get_arch (abfd) == bfd_arch_v850_rh850)
+ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info), R_V850_PC9);
+ else
+ irel->r_info =
+ ELF32_R_INFO (ELF32_R_SYM (irel->r_info), R_V850_9_PCREL);
+
+ irel->r_addend = addend;
+ addend = 0;
+
+ if (ELF32_R_SYM (hi_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,
+ 0x0585 | ((addend << 10) & 0xf800) | ((addend << 3) & 0x0070),
+ 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, 0x0585, contents + irel->r_offset);
+
+ hi_irelfn->r_info =
+ ELF32_R_INFO (ELF32_R_SYM (hi_irelfn->r_info), R_V850_NONE);
+ lo_irelfn->r_info =
+ ELF32_R_INFO (ELF32_R_SYM (lo_irelfn->r_info), R_V850_NONE);
+ if (!v850_elf_relax_delete_bytes (abfd, sec,
+ irel->r_offset + 2, toaddr, 8))
+ goto error_return;
+
+ align_pad_size += 8;
+ }
+ }
+ }
+
+ irelalign = NULL;
+ for (irel = internal_relocs; irel < irelend; irel++)
+ {
+ if (ELF32_R_TYPE (irel->r_info) == (int) R_V850_ALIGN
+ && irel->r_offset == toaddr)
+ {
+ irel->r_offset -= align_pad_size;
+
+ if (irelalign == NULL || irelalign->r_addend > irel->r_addend)
+ irelalign = irel;
+ }
+ }
+
+ addr = toaddr;
+ }
+
+ if (!irelalign)
+ {
+#ifdef DEBUG_RELAX
+ fprintf (stderr, "relax pad %d shorten %d -> %d\n",
+ align_pad_size,
+ sec->size,
+ sec->size - align_pad_size);
+#endif
+ sec->size -= align_pad_size;
+ }
+
+ finish:
+ if (internal_relocs != NULL
+ && elf_section_data (sec)->relocs != internal_relocs)
+ free (internal_relocs);
+
+ if (contents != NULL
+ && elf_section_data (sec)->this_hdr.contents != (unsigned char *) contents)
+ free (contents);
+
+ if (isymbuf != NULL
+ && symtab_hdr->contents != (bfd_byte *) isymbuf)
+ free (isymbuf);
+
+ return result;
+
+ error_return:
+ result = FALSE;
+ goto finish;
+}
+
+static const struct bfd_elf_special_section v850_elf_special_sections[] =
+{
+ { STRING_COMMA_LEN (".call_table_data"), 0, SHT_PROGBITS, (SHF_ALLOC + SHF_WRITE) },
+ { STRING_COMMA_LEN (".call_table_text"), 0, SHT_PROGBITS, (SHF_ALLOC + SHF_WRITE
+ + SHF_EXECINSTR) },
+ { STRING_COMMA_LEN (".rosdata"), -2, SHT_PROGBITS, (SHF_ALLOC
+ + SHF_V850_GPREL) },
+ { STRING_COMMA_LEN (".rozdata"), -2, SHT_PROGBITS, (SHF_ALLOC
+ + SHF_V850_R0REL) },
+ { STRING_COMMA_LEN (".sbss"), -2, SHT_NOBITS, (SHF_ALLOC + SHF_WRITE
+ + SHF_V850_GPREL) },
+ { STRING_COMMA_LEN (".scommon"), -2, SHT_V850_SCOMMON, (SHF_ALLOC + SHF_WRITE
+ + SHF_V850_GPREL) },
+ { STRING_COMMA_LEN (".sdata"), -2, SHT_PROGBITS, (SHF_ALLOC + SHF_WRITE
+ + SHF_V850_GPREL) },
+ { STRING_COMMA_LEN (".tbss"), -2, SHT_NOBITS, (SHF_ALLOC + SHF_WRITE
+ + SHF_V850_EPREL) },
+ { STRING_COMMA_LEN (".tcommon"), -2, SHT_V850_TCOMMON, (SHF_ALLOC + SHF_WRITE
+ + SHF_V850_R0REL) },
+ { STRING_COMMA_LEN (".tdata"), -2, SHT_PROGBITS, (SHF_ALLOC + SHF_WRITE
+ + SHF_V850_EPREL) },
+ { STRING_COMMA_LEN (".zbss"), -2, SHT_NOBITS, (SHF_ALLOC + SHF_WRITE
+ + SHF_V850_R0REL) },
+ { STRING_COMMA_LEN (".zcommon"), -2, SHT_V850_ZCOMMON, (SHF_ALLOC + SHF_WRITE
+ + SHF_V850_R0REL) },
+ { STRING_COMMA_LEN (".zdata"), -2, SHT_PROGBITS, (SHF_ALLOC + SHF_WRITE
+ + SHF_V850_R0REL) },
+ { NULL, 0, 0, 0, 0 }
+};
+
+#define TARGET_LITTLE_SYM v850_elf32_vec
+#define TARGET_LITTLE_NAME "elf32-v850"
+#define ELF_ARCH bfd_arch_v850
+#define ELF_MACHINE_CODE EM_V850
+#define ELF_MACHINE_ALT1 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_special_sections v850_elf_special_sections
+
+#define elf_backend_can_gc_sections 1
+#define elf_backend_rela_normal 1
+
+#define bfd_elf32_bfd_is_local_label_name v850_elf_is_local_label_name
+#define bfd_elf32_bfd_is_target_special_symbol v850_elf_is_target_special_symbol
+
+#define bfd_elf32_bfd_reloc_type_lookup v850_elf_reloc_type_lookup
+#define bfd_elf32_bfd_reloc_name_lookup v850_elf_reloc_name_lookup
+#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 bfd_elf32_bfd_relax_section v850_elf_relax_section
+
+#define elf_symbol_leading_char '_'
+
+#undef elf32_bed
+#define elf32_bed elf32_v850_bed
+
+#include "elf32-target.h"
+
+/* Map BFD reloc types to V800 ELF reloc types. */
+
+static const struct v850_elf_reloc_map v800_elf_reloc_map[] =
+{
+ { BFD_RELOC_NONE, R_V810_NONE },
+ { BFD_RELOC_8, R_V810_BYTE },
+ { BFD_RELOC_16, R_V810_HWORD },
+ { BFD_RELOC_32, R_V810_WORD },
+ { BFD_RELOC_LO16, R_V810_WLO },
+ { BFD_RELOC_HI16, R_V810_WHI },
+ { BFD_RELOC_HI16_S, R_V810_WHI1 },
+ { BFD_RELOC_V850_32_PCREL, R_V850_PC32 },
+ { BFD_RELOC_V850_22_PCREL, R_V850_PCR22 },
+ { BFD_RELOC_V850_17_PCREL, R_V850_PC17 },
+ { BFD_RELOC_V850_16_PCREL, R_V850_PC16U },
+ { BFD_RELOC_V850_9_PCREL, R_V850_PC9 },
+ { BFD_RELOC_V850_LO16_S1, R_V810_WLO_1 }, /* Or R_V850_HWLO or R_V850_HWLO_1. */
+ { BFD_RELOC_V850_23, R_V850_WLO23 },
+ { BFD_RELOC_V850_LO16_SPLIT_OFFSET, R_V850_BLO },
+ { BFD_RELOC_V850_ZDA_16_16_OFFSET, R_V810_HWORD },
+ { BFD_RELOC_V850_TDA_16_16_OFFSET, R_V810_HWORD },
+ { BFD_RELOC_V850_SDA_16_16_OFFSET, R_V810_HWORD },
+ { BFD_RELOC_V850_SDA_15_16_OFFSET, R_V810_GPWLO_1 }
+};
+
+/* Map a bfd relocation into the appropriate howto structure. */
+
+static reloc_howto_type *
+v800_elf_reloc_type_lookup (bfd * abfd, bfd_reloc_code_real_type code)
+{
+ unsigned int i;
+
+ BFD_ASSERT (bfd_get_arch (abfd) == bfd_arch_v850_rh850);
+
+ for (i = ARRAY_SIZE (v800_elf_reloc_map); i --;)
+ if (v800_elf_reloc_map[i].bfd_reloc_val == code)
+ {
+ unsigned int elf_reloc_val = v800_elf_reloc_map[i].elf_reloc_val;
+ unsigned int idx = elf_reloc_val - R_V810_NONE;
+
+ BFD_ASSERT (v800_elf_howto_table[idx].type == elf_reloc_val);
+
+ return v800_elf_howto_table + idx;
+ }
+
+#ifdef DEBUG
+ fprintf (stderr, "failed to find v800 equiv of bfd reloc code %d\n", code);
+#endif
+ return NULL;
+}
+
+static reloc_howto_type *
+v800_elf_reloc_name_lookup (bfd * abfd, const char * r_name)
+{
+ unsigned int i;
+
+ BFD_ASSERT (bfd_get_arch (abfd) == bfd_arch_v850_rh850);
+
+ for (i = ARRAY_SIZE (v800_elf_howto_table); i--;)
+ if (v800_elf_howto_table[i].name != NULL
+ && strcasecmp (v800_elf_howto_table[i].name, r_name) == 0)
+ return v800_elf_howto_table + i;
+
+ return NULL;
+}
+
+
+/* Set the howto pointer in CACHE_PTR for a V800 ELF reloc. */
+
+static void
+v800_elf_info_to_howto (bfd * abfd,
+ arelent * cache_ptr,
+ Elf_Internal_Rela * dst)
+{
+ unsigned int r_type = ELF32_R_TYPE (dst->r_info);
+
+ BFD_ASSERT (bfd_get_arch (abfd) == bfd_arch_v850_rh850);
+
+ BFD_ASSERT (r_type < (unsigned int) R_V800_max);
+
+ if (r_type == R_V800_NONE)
+ r_type = R_V810_NONE;
+
+ BFD_ASSERT (r_type >= (unsigned int) R_V810_NONE);
+ r_type -= R_V810_NONE;
+ BFD_ASSERT (r_type < ARRAY_SIZE (v800_elf_howto_table));
+
+ cache_ptr->howto = v800_elf_howto_table + r_type;
+}
+
+
+#undef TARGET_LITTLE_SYM
+#define TARGET_LITTLE_SYM v800_elf32_vec
+#undef TARGET_LITTLE_NAME
+#define TARGET_LITTLE_NAME "elf32-v850-rh850"
+#undef ELF_ARCH
+#define ELF_ARCH bfd_arch_v850_rh850
+#undef ELF_MACHINE_CODE
+#define ELF_MACHINE_CODE EM_V800
+#undef ELF_MACHINE_ALT1
+
+#undef elf32_bed
+#define elf32_bed elf32_v850_rh850_bed
+
+#undef elf_info_to_howto
+#define elf_info_to_howto v800_elf_info_to_howto
+#undef elf_info_to_howto_rel
+#define elf_info_to_howto_rel NULL
+#undef bfd_elf32_bfd_reloc_type_lookup
+#define bfd_elf32_bfd_reloc_type_lookup v800_elf_reloc_type_lookup
+#undef bfd_elf32_bfd_reloc_name_lookup
+#define bfd_elf32_bfd_reloc_name_lookup v800_elf_reloc_name_lookup
+
+#include "elf32-target.h"
diff --git a/bfd/elf32-vax.c b/bfd/elf32-vax.c
new file mode 100644
index 0000000..1f41867
--- /dev/null
+++ b/bfd/elf32-vax.c
@@ -0,0 +1,2063 @@
+/* VAX series support for 32-bit ELF
+ Copyright (C) 1993-2014 Free Software Foundation, Inc.
+ Contributed by Matt Thomas <matt@3am-software.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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "bfdlink.h"
+#include "libbfd.h"
+#include "elf-bfd.h"
+#include "elf/vax.h"
+
+static reloc_howto_type *reloc_type_lookup (bfd *, bfd_reloc_code_real_type);
+static void rtype_to_howto (bfd *, arelent *, Elf_Internal_Rela *);
+static struct bfd_hash_entry *elf_vax_link_hash_newfunc (struct bfd_hash_entry *,
+ struct bfd_hash_table *,
+ const char *);
+static struct bfd_link_hash_table *elf_vax_link_hash_table_create (bfd *);
+static bfd_boolean elf_vax_check_relocs (bfd *, struct bfd_link_info *,
+ asection *, const Elf_Internal_Rela *);
+static bfd_boolean elf_vax_adjust_dynamic_symbol (struct bfd_link_info *,
+ struct elf_link_hash_entry *);
+static bfd_boolean elf_vax_size_dynamic_sections (bfd *, struct bfd_link_info *);
+static bfd_boolean elf_vax_relocate_section (bfd *, struct bfd_link_info *,
+ bfd *, asection *, bfd_byte *,
+ Elf_Internal_Rela *,
+ Elf_Internal_Sym *, asection **);
+static bfd_boolean elf_vax_finish_dynamic_symbol (bfd *, struct bfd_link_info *,
+ struct elf_link_hash_entry *,
+ Elf_Internal_Sym *);
+static bfd_boolean elf_vax_finish_dynamic_sections (bfd *,
+ struct bfd_link_info *);
+static bfd_vma elf_vax_plt_sym_val (bfd_vma, const asection *,
+ const arelent *);
+
+static bfd_boolean elf32_vax_set_private_flags (bfd *, flagword);
+static bfd_boolean elf32_vax_merge_private_bfd_data (bfd *, bfd *);
+static bfd_boolean elf32_vax_print_private_bfd_data (bfd *, void *);
+
+static reloc_howto_type howto_table[] = {
+ HOWTO (R_VAX_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_VAX_NONE", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x00000000, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_VAX_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_VAX_32", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_VAX_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_VAX_16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_VAX_8, /* 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_VAX_8", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x000000ff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_VAX_PC32, /* 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_VAX_PC32", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_VAX_PC16, /* 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_VAX_PC16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_VAX_PC8, /* type */
+ 0, /* rightshift */
+ 0, /* 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_VAX_PC8", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x000000ff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_VAX_GOT32, /* 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_VAX_GOT32", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ EMPTY_HOWTO (-1),
+ EMPTY_HOWTO (-1),
+ EMPTY_HOWTO (-1),
+ EMPTY_HOWTO (-1),
+ EMPTY_HOWTO (-1),
+
+ HOWTO (R_VAX_PLT32, /* 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_VAX_PLT32", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ EMPTY_HOWTO (-1),
+ EMPTY_HOWTO (-1),
+ EMPTY_HOWTO (-1),
+ EMPTY_HOWTO (-1),
+ EMPTY_HOWTO (-1),
+
+ HOWTO (R_VAX_COPY, /* 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_VAX_COPY", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_VAX_GLOB_DAT, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_VAX_GLOB_DAT", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_VAX_JMP_SLOT, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_VAX_JMP_SLOT", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_VAX_RELATIVE, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_VAX_RELATIVE", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* GNU extension to record C++ vtable hierarchy */
+ HOWTO (R_VAX_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_VAX_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_VAX_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_VAX_GNU_VTENTRY", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ FALSE), /* pcrel_offset */
+};
+
+static void
+rtype_to_howto (bfd *abfd ATTRIBUTE_UNUSED, arelent *cache_ptr,
+ Elf_Internal_Rela *dst)
+{
+ BFD_ASSERT (ELF32_R_TYPE(dst->r_info) < (unsigned int) R_VAX_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_VAX_NONE },
+ { BFD_RELOC_32, R_VAX_32 },
+ { BFD_RELOC_16, R_VAX_16 },
+ { BFD_RELOC_8, R_VAX_8 },
+ { BFD_RELOC_32_PCREL, R_VAX_PC32 },
+ { BFD_RELOC_16_PCREL, R_VAX_PC16 },
+ { BFD_RELOC_8_PCREL, R_VAX_PC8 },
+ { BFD_RELOC_32_GOT_PCREL, R_VAX_GOT32 },
+ { BFD_RELOC_32_PLT_PCREL, R_VAX_PLT32 },
+ { BFD_RELOC_NONE, R_VAX_COPY },
+ { BFD_RELOC_VAX_GLOB_DAT, R_VAX_GLOB_DAT },
+ { BFD_RELOC_VAX_JMP_SLOT, R_VAX_JMP_SLOT },
+ { BFD_RELOC_VAX_RELATIVE, R_VAX_RELATIVE },
+ { BFD_RELOC_CTOR, R_VAX_32 },
+ { BFD_RELOC_VTABLE_INHERIT, R_VAX_GNU_VTINHERIT },
+ { BFD_RELOC_VTABLE_ENTRY, R_VAX_GNU_VTENTRY },
+};
+
+static reloc_howto_type *
+reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, 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;
+}
+
+static reloc_howto_type *
+reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ const char *r_name)
+{
+ unsigned int i;
+
+ for (i = 0; i < sizeof (howto_table) / sizeof (howto_table[0]); i++)
+ if (howto_table[i].name != NULL
+ && strcasecmp (howto_table[i].name, r_name) == 0)
+ return &howto_table[i];
+
+ return NULL;
+}
+
+#define bfd_elf32_bfd_reloc_type_lookup reloc_type_lookup
+#define bfd_elf32_bfd_reloc_name_lookup reloc_name_lookup
+#define ELF_ARCH bfd_arch_vax
+/* end code generated by elf.el */
+
+/* Functions for the VAX ELF linker. */
+
+/* The name of the dynamic interpreter. This is put in the .interp
+ section. */
+
+#define ELF_DYNAMIC_INTERPRETER "/usr/libexec/ld.elf_so"
+
+/* The size in bytes of an entry in the procedure linkage table. */
+
+#define PLT_ENTRY_SIZE 12
+
+/* The first entry in a procedure linkage table looks like this. See
+ the SVR4 ABI VAX supplement to see how this works. */
+
+static const bfd_byte elf_vax_plt0_entry[PLT_ENTRY_SIZE] =
+{
+ 0xdd, 0xef, /* pushl l^ */
+ 0, 0, 0, 0, /* offset to .plt.got + 4 */
+ 0x17, 0xff, /* jmp @L^(pc) */
+ 0, 0, 0, 0, /* offset to .plt.got + 8 */
+};
+
+/* Subsequent entries in a procedure linkage table look like this. */
+
+static const bfd_byte elf_vax_plt_entry[PLT_ENTRY_SIZE] =
+{
+ 0xfc, 0x0f, /* .word ^M<r11:r2> */
+ 0x16, 0xef, /* jsb L^(pc) */
+ 0, 0, 0, 0, /* replaced with offset to start of .plt */
+ 0, 0, 0, 0, /* index into .rela.plt */
+};
+
+/* The VAX 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_vax_pcrel_relocs_copied
+{
+ /* Next section. */
+ struct elf_vax_pcrel_relocs_copied *next;
+ /* A section in dynobj. */
+ asection *section;
+ /* Number of relocs copied in this section. */
+ bfd_size_type count;
+};
+
+/* VAX ELF linker hash entry. */
+
+struct elf_vax_link_hash_entry
+{
+ struct elf_link_hash_entry root;
+
+ /* Number of PC relative relocs copied for this symbol. */
+ struct elf_vax_pcrel_relocs_copied *pcrel_relocs_copied;
+
+ bfd_vma got_addend;
+};
+
+/* Declare this now that the above structures are defined. */
+
+static bfd_boolean elf_vax_discard_copies (struct elf_vax_link_hash_entry *,
+ void *);
+
+/* Declare this now that the above structures are defined. */
+
+static bfd_boolean elf_vax_instantiate_got_entries (struct elf_link_hash_entry *,
+ void *);
+
+/* Traverse an VAX ELF linker hash table. */
+
+#define elf_vax_link_hash_traverse(table, func, info) \
+ (elf_link_hash_traverse \
+ ((table), \
+ (bfd_boolean (*) (struct elf_link_hash_entry *, void *)) (func), \
+ (info)))
+
+/* Create an entry in an VAX ELF linker hash table. */
+
+static struct bfd_hash_entry *
+elf_vax_link_hash_newfunc (struct bfd_hash_entry *entry,
+ struct bfd_hash_table *table,
+ const char *string)
+{
+ struct elf_vax_link_hash_entry *ret =
+ (struct elf_vax_link_hash_entry *) entry;
+
+ /* Allocate the structure if it has not already been allocated by a
+ subclass. */
+ if (ret == NULL)
+ ret = ((struct elf_vax_link_hash_entry *)
+ bfd_hash_allocate (table,
+ sizeof (struct elf_vax_link_hash_entry)));
+ if (ret == NULL)
+ return (struct bfd_hash_entry *) ret;
+
+ /* Call the allocation method of the superclass. */
+ ret = ((struct elf_vax_link_hash_entry *)
+ _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry *) ret,
+ table, string));
+ if (ret != NULL)
+ {
+ ret->pcrel_relocs_copied = NULL;
+ }
+
+ return (struct bfd_hash_entry *) ret;
+}
+
+/* Create an VAX ELF linker hash table. */
+
+static struct bfd_link_hash_table *
+elf_vax_link_hash_table_create (bfd *abfd)
+{
+ struct elf_link_hash_table *ret;
+ bfd_size_type amt = sizeof (struct elf_link_hash_table);
+
+ ret = bfd_zmalloc (amt);
+ if (ret == NULL)
+ return NULL;
+
+ if (!_bfd_elf_link_hash_table_init (ret, abfd,
+ elf_vax_link_hash_newfunc,
+ sizeof (struct elf_vax_link_hash_entry),
+ GENERIC_ELF_DATA))
+ {
+ free (ret);
+ return NULL;
+ }
+
+ return &ret->root;
+}
+
+/* Keep vax-specific flags in the ELF header */
+static bfd_boolean
+elf32_vax_set_private_flags (bfd *abfd, flagword flags)
+{
+ elf_elfheader (abfd)->e_flags = flags;
+ elf_flags_init (abfd) = TRUE;
+ return TRUE;
+}
+
+/* Merge backend specific data from an object file to the output
+ object file when linking. */
+static bfd_boolean
+elf32_vax_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
+{
+ 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;
+
+ if (!elf_flags_init (obfd))
+ {
+ elf_flags_init (obfd) = TRUE;
+ elf_elfheader (obfd)->e_flags = in_flags;
+ }
+
+ return TRUE;
+}
+
+/* Display the flags field */
+static bfd_boolean
+elf32_vax_print_private_bfd_data (bfd *abfd, void * 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_VAX_NONPIC)
+ fprintf (file, _(" [nonpic]"));
+
+ if (elf_elfheader (abfd)->e_flags & EF_VAX_DFLOAT)
+ fprintf (file, _(" [d-float]"));
+
+ if (elf_elfheader (abfd)->e_flags & EF_VAX_GFLOAT)
+ fprintf (file, _(" [g-float]"));
+
+ fputc ('\n', file);
+
+ 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 bfd_boolean
+elf_vax_check_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;
+ const Elf_Internal_Rela *rel;
+ const Elf_Internal_Rela *rel_end;
+ asection *sgot;
+ asection *srelgot;
+ asection *sreloc;
+
+ if (info->relocatable)
+ return TRUE;
+
+ dynobj = elf_hash_table (info)->dynobj;
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+ sym_hashes = elf_sym_hashes (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];
+ 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;
+
+ /* PR15323, ref flags aren't set for references in the same
+ object. */
+ h->root.non_ir_ref = 1;
+ }
+
+ switch (ELF32_R_TYPE (rel->r_info))
+ {
+ case R_VAX_GOT32:
+ BFD_ASSERT (h != NULL);
+
+ /* If this is a local symbol, we resolve it directly without
+ creating a global offset table entry. */
+ if (h->forced_local
+ || h == elf_hash_table (info)->hgot
+ || h == elf_hash_table (info)->hplt)
+ break;
+
+ /* 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_linker_section (dynobj, ".got");
+ BFD_ASSERT (sgot != NULL);
+ }
+
+ if (srelgot == NULL
+ && (h != NULL || info->shared))
+ {
+ srelgot = bfd_get_linker_section (dynobj, ".rela.got");
+ if (srelgot == NULL)
+ {
+ flagword flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS
+ | SEC_IN_MEMORY | SEC_LINKER_CREATED
+ | SEC_READONLY);
+
+ srelgot = bfd_make_section_anyway_with_flags (dynobj,
+ ".rela.got",
+ flags);
+ if (srelgot == NULL
+ || !bfd_set_section_alignment (dynobj, srelgot, 2))
+ return FALSE;
+ }
+ }
+
+ if (h != NULL)
+ {
+ struct elf_vax_link_hash_entry *eh;
+
+ eh = (struct elf_vax_link_hash_entry *) h;
+ if (h->got.refcount == -1)
+ {
+ h->got.refcount = 1;
+ eh->got_addend = rel->r_addend;
+ }
+ else
+ {
+ h->got.refcount++;
+ if (eh->got_addend != (bfd_vma) rel->r_addend)
+ (*_bfd_error_handler)
+ (_("%s: warning: GOT addend of %ld to `%s' does"
+ " not match previous GOT addend of %ld"),
+ bfd_get_filename (abfd), rel->r_addend,
+ h->root.root.string,
+ eh->got_addend);
+
+ }
+ }
+ break;
+
+ case R_VAX_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. */
+ BFD_ASSERT (h != NULL);
+
+ /* If this is a local symbol, we resolve it directly without
+ creating a procedure linkage table entry. */
+ if (h->forced_local)
+ break;
+
+ h->needs_plt = 1;
+ if (h->plt.refcount == -1)
+ h->plt.refcount = 1;
+ else
+ h->plt.refcount++;
+ break;
+
+ case R_VAX_PC8:
+ case R_VAX_PC16:
+ case R_VAX_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->def_regular)))
+ {
+ if (h != NULL
+ && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
+ && !h->forced_local)
+ {
+ /* 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;
+ }
+ /* If this is a local symbol, we can resolve it directly. */
+ if (h != NULL
+ && (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
+ || h->forced_local))
+ break;
+
+ /* Fall through. */
+ case R_VAX_8:
+ case R_VAX_16:
+ case R_VAX_32:
+ if (h != NULL && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)
+ {
+ /* 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)
+ {
+ sreloc = _bfd_elf_make_dynamic_reloc_section
+ (sec, dynobj, 2, abfd, /*rela?*/ TRUE);
+
+ if (sreloc == NULL)
+ return FALSE;
+
+ if (sec->flags & SEC_READONLY)
+ info->flags |= DF_TEXTREL;
+ }
+
+ sreloc->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 a vaxelf linker hash table,
+ which means that h is really a pointer to an
+ elf_vax_link_hash_entry. */
+ if ((ELF32_R_TYPE (rel->r_info) == R_VAX_PC8
+ || ELF32_R_TYPE (rel->r_info) == R_VAX_PC16
+ || ELF32_R_TYPE (rel->r_info) == R_VAX_PC32)
+ && info->symbolic)
+ {
+ struct elf_vax_link_hash_entry *eh;
+ struct elf_vax_pcrel_relocs_copied *p;
+
+ eh = (struct elf_vax_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_vax_pcrel_relocs_copied *)
+ bfd_alloc (dynobj, (bfd_size_type) 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_VAX_GNU_VTINHERIT:
+ if (!bfd_elf_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_VAX_GNU_VTENTRY:
+ BFD_ASSERT (h != NULL);
+ if (h != NULL
+ && !bfd_elf_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_vax_gc_mark_hook (asection *sec,
+ 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_VAX_GNU_VTINHERIT:
+ case R_VAX_GNU_VTENTRY:
+ return NULL;
+ }
+
+ return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
+}
+
+/* Update the got entry reference counts for the section being removed. */
+
+static bfd_boolean
+elf_vax_gc_sweep_hook (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;
+ const Elf_Internal_Rela *rel, *relend;
+ bfd *dynobj;
+
+ if (info->relocatable)
+ return TRUE;
+
+ dynobj = elf_hash_table (info)->dynobj;
+ if (dynobj == NULL)
+ return TRUE;
+
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+ sym_hashes = elf_sym_hashes (abfd);
+
+ relend = relocs + sec->reloc_count;
+ for (rel = relocs; rel < relend; rel++)
+ {
+ unsigned long r_symndx;
+ struct elf_link_hash_entry *h = NULL;
+
+ r_symndx = ELF32_R_SYM (rel->r_info);
+ if (r_symndx >= symtab_hdr->sh_info)
+ {
+ 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;
+ }
+
+ switch (ELF32_R_TYPE (rel->r_info))
+ {
+ case R_VAX_GOT32:
+ if (h != NULL && h->got.refcount > 0)
+ --h->got.refcount;
+ break;
+
+ case R_VAX_PLT32:
+ case R_VAX_PC8:
+ case R_VAX_PC16:
+ case R_VAX_PC32:
+ case R_VAX_8:
+ case R_VAX_16:
+ case R_VAX_32:
+ if (h != NULL && 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 bfd_boolean
+elf_vax_adjust_dynamic_symbol (struct bfd_link_info *info,
+ struct elf_link_hash_entry *h)
+{
+ bfd *dynobj;
+ asection *s;
+
+ dynobj = elf_hash_table (info)->dynobj;
+
+ /* Make sure we know what is going on here. */
+ BFD_ASSERT (dynobj != NULL
+ && (h->needs_plt
+ || h->u.weakdef != NULL
+ || (h->def_dynamic
+ && h->ref_regular
+ && !h->def_regular)));
+
+ /* 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->needs_plt)
+ {
+ if (h->plt.refcount <= 0
+ || SYMBOL_CALLS_LOCAL (info, h)
+ || (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
+ && h->root.type == bfd_link_hash_undefweak))
+ {
+ /* 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, or if all references were garbage collected. In
+ such a case, we don't actually need to build a procedure
+ linkage table, and we can just do a PCxx reloc instead. */
+ h->plt.offset = (bfd_vma) -1;
+ h->needs_plt = 0;
+ return TRUE;
+ }
+
+ s = bfd_get_linker_section (dynobj, ".plt");
+ BFD_ASSERT (s != NULL);
+
+ /* If this is the first .plt entry, make room for the special
+ first entry. */
+ if (s->size == 0)
+ {
+ s->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->def_regular)
+ {
+ h->root.u.def.section = s;
+ h->root.u.def.value = s->size;
+ }
+
+ h->plt.offset = s->size;
+
+ /* Make room for this entry. */
+ s->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_linker_section (dynobj, ".got.plt");
+ BFD_ASSERT (s != NULL);
+ s->size += 4;
+
+ /* We also need to make an entry in the .rela.plt section. */
+
+ s = bfd_get_linker_section (dynobj, ".rela.plt");
+ BFD_ASSERT (s != NULL);
+ s->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->u.weakdef != NULL)
+ {
+ BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
+ || h->u.weakdef->root.type == bfd_link_hash_defweak);
+ h->root.u.def.section = h->u.weakdef->root.u.def.section;
+ h->root.u.def.value = h->u.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_linker_section (dynobj, ".dynbss");
+ BFD_ASSERT (s != NULL);
+
+ /* We must generate a R_VAX_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 && h->size != 0)
+ {
+ asection *srel;
+
+ srel = bfd_get_linker_section (dynobj, ".rela.bss");
+ BFD_ASSERT (srel != NULL);
+ srel->size += sizeof (Elf32_External_Rela);
+ h->needs_copy = 1;
+ }
+
+ return _bfd_elf_adjust_dynamic_copy (h, s);
+}
+
+/* This function is called via elf_link_hash_traverse. It resets GOT
+ and PLT (.GOT) reference counts back to -1 so normal PC32 relocation
+ will be done. */
+
+static bfd_boolean
+elf_vax_discard_got_entries (struct elf_link_hash_entry *h,
+ void *infoptr ATTRIBUTE_UNUSED)
+{
+ h->got.refcount = -1;
+ h->plt.refcount = -1;
+
+ return TRUE;
+}
+
+/* Discard unused dynamic data if this is a static link. */
+
+static bfd_boolean
+elf_vax_always_size_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
+ struct bfd_link_info *info)
+{
+ bfd *dynobj;
+ asection *s;
+
+ dynobj = elf_hash_table (info)->dynobj;
+
+ if (dynobj && !elf_hash_table (info)->dynamic_sections_created)
+ {
+ /* We may have created entries in the .rela.got and .got sections.
+ However, if we are not creating the dynamic sections, we will
+ not actually use these entries. Reset the size of .rela.got
+ and .got, which will cause them to get stripped from the output
+ file below. */
+ s = bfd_get_linker_section (dynobj, ".rela.got");
+ if (s != NULL)
+ s->size = 0;
+ s = bfd_get_linker_section (dynobj, ".got.plt");
+ if (s != NULL)
+ s->size = 0;
+ s = bfd_get_linker_section (dynobj, ".got");
+ if (s != NULL)
+ s->size = 0;
+ }
+
+ /* If this is a static link, we need to discard all the got entries we've
+ recorded. */
+ if (!dynobj || !elf_hash_table (info)->dynamic_sections_created)
+ elf_link_hash_traverse (elf_hash_table (info),
+ elf_vax_discard_got_entries,
+ info);
+
+ return TRUE;
+}
+
+/* Set the sizes of the dynamic sections. */
+
+static bfd_boolean
+elf_vax_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
+{
+ bfd *dynobj;
+ asection *s;
+ bfd_boolean plt;
+ bfd_boolean relocs;
+ bfd_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->executable)
+ {
+ s = bfd_get_linker_section (dynobj, ".interp");
+ BFD_ASSERT (s != NULL);
+ s->size = sizeof ELF_DYNAMIC_INTERPRETER;
+ s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
+ }
+ }
+
+ /* 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_vax_link_hash_traverse (elf_hash_table (info),
+ elf_vax_discard_copies,
+ NULL);
+
+ /* If this is a -Bsymbolic shared link, we need to discard all the got
+ entries we've recorded. Otherwise, we need to instantiate (allocate
+ space for them). */
+ elf_link_hash_traverse (elf_hash_table (info),
+ elf_vax_instantiate_got_entries,
+ info);
+
+ /* 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;
+
+ 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);
+
+ if (strcmp (name, ".plt") == 0)
+ {
+ /* Remember whether there is a PLT. */
+ plt = s->size != 0;
+ }
+ else if (CONST_STRNEQ (name, ".rela"))
+ {
+ if (s->size != 0)
+ {
+ 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 (! CONST_STRNEQ (name, ".got")
+ && strcmp (name, ".dynbss") != 0)
+ {
+ /* It's not one of our sections, so don't allocate space. */
+ continue;
+ }
+
+ if (s->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. */
+ s->flags |= SEC_EXCLUDE;
+ continue;
+ }
+
+ if ((s->flags & SEC_HAS_CONTENTS) == 0)
+ continue;
+
+ /* Allocate memory for the section contents. */
+ s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->size);
+ if (s->contents == NULL)
+ 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_vax_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. */
+#define add_dynamic_entry(TAG, VAL) \
+ _bfd_elf_add_dynamic_entry (info, TAG, VAL)
+
+ if (!info->shared)
+ {
+ if (!add_dynamic_entry (DT_DEBUG, 0))
+ return FALSE;
+ }
+
+ if (plt)
+ {
+ if (!add_dynamic_entry (DT_PLTGOT, 0)
+ || !add_dynamic_entry (DT_PLTRELSZ, 0)
+ || !add_dynamic_entry (DT_PLTREL, DT_RELA)
+ || !add_dynamic_entry (DT_JMPREL, 0))
+ return FALSE;
+ }
+
+ if (relocs)
+ {
+ if (!add_dynamic_entry (DT_RELA, 0)
+ || !add_dynamic_entry (DT_RELASZ, 0)
+ || !add_dynamic_entry (DT_RELAENT, sizeof (Elf32_External_Rela)))
+ return FALSE;
+ }
+
+ if (reltext || (info->flags & DF_TEXTREL) != 0)
+ {
+ if (!add_dynamic_entry (DT_TEXTREL, 0))
+ return FALSE;
+ }
+ }
+#undef add_dynamic_entry
+
+ return TRUE;
+}
+
+/* This function is called via elf_vax_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 bfd_boolean
+elf_vax_discard_copies (struct elf_vax_link_hash_entry *h,
+ void * ignore ATTRIBUTE_UNUSED)
+{
+ struct elf_vax_pcrel_relocs_copied *s;
+
+ /* We only discard relocs for symbols defined in a regular object. */
+ if (!h->root.def_regular)
+ return TRUE;
+
+ for (s = h->pcrel_relocs_copied; s != NULL; s = s->next)
+ s->section->size -= s->count * sizeof (Elf32_External_Rela);
+
+ return TRUE;
+}
+
+/* This function is called via elf_link_hash_traverse. It looks for
+ entries that have GOT or PLT (.GOT) references. If creating a shared
+ object with -Bsymbolic, or the symbol has been forced local, then it
+ resets the reference count back to -1 so normal PC32 relocation will
+ be done. Otherwise space in the .got and .rela.got will be reserved
+ for the symbol. */
+
+static bfd_boolean
+elf_vax_instantiate_got_entries (struct elf_link_hash_entry *h, void * infoptr)
+{
+ struct bfd_link_info *info = (struct bfd_link_info *) infoptr;
+ bfd *dynobj;
+ asection *sgot;
+ asection *srelgot;
+
+ /* We don't care about non-GOT (and non-PLT) entries. */
+ if (h->got.refcount <= 0 && h->plt.refcount <= 0)
+ return TRUE;
+
+ dynobj = elf_hash_table (info)->dynobj;
+ BFD_ASSERT (dynobj != NULL);
+
+ sgot = bfd_get_linker_section (dynobj, ".got");
+ srelgot = bfd_get_linker_section (dynobj, ".rela.got");
+
+ if (SYMBOL_REFERENCES_LOCAL (info, h))
+ {
+ h->got.refcount = -1;
+ h->plt.refcount = -1;
+ }
+ else if (h->got.refcount > 0)
+ {
+ /* Make sure this symbol is output as a dynamic symbol. */
+ if (h->dynindx == -1)
+ {
+ if (!bfd_elf_link_record_dynamic_symbol (info, h))
+ return FALSE;
+ }
+
+ /* Allocate space in the .got and .rela.got sections. */
+ sgot->size += 4;
+ srelgot->size += sizeof (Elf32_External_Rela);
+ }
+
+ return TRUE;
+}
+
+/* Relocate an VAX ELF section. */
+
+static bfd_boolean
+elf_vax_relocate_section (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 plt_index;
+ bfd_vma got_offset;
+ asection *sgot;
+ asection *splt;
+ asection *sgotplt;
+ 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);
+
+ sgot = NULL;
+ splt = NULL;
+ sgotplt = 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_VAX_max)
+ {
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+ howto = howto_table + r_type;
+
+ r_symndx = ELF32_R_SYM (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 = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
+ }
+ else
+ {
+ bfd_boolean unresolved_reloc;
+ bfd_boolean warned, ignored;
+
+ RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
+ r_symndx, symtab_hdr, sym_hashes,
+ h, sec, relocation,
+ unresolved_reloc, warned, ignored);
+
+ if ((h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak)
+ && ((r_type == R_VAX_PLT32
+ && h->plt.offset != (bfd_vma) -1
+ && !h->forced_local
+ && elf_hash_table (info)->dynamic_sections_created)
+ || (r_type == R_VAX_GOT32
+ && h->got.offset != (bfd_vma) -1
+ && !h->forced_local
+ && elf_hash_table (info)->dynamic_sections_created
+ && (! info->shared
+ || (! info->symbolic && h->dynindx != -1)
+ || !h->def_regular))
+ || (info->shared
+ && ((! info->symbolic && h->dynindx != -1)
+ || !h->def_regular)
+ && ((input_section->flags & SEC_ALLOC) != 0
+ /* DWARF will emit R_VAX_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
+ && h->def_dynamic))
+ && (r_type == R_VAX_8
+ || r_type == R_VAX_16
+ || r_type == R_VAX_32))))
+ /* 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;
+ }
+
+ if (sec != NULL && discarded_section (sec))
+ RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+ rel, 1, relend, howto, 0, contents);
+
+ if (info->relocatable)
+ continue;
+
+ switch (r_type)
+ {
+ case R_VAX_GOT32:
+ /* Relocation is to the address of the entry for this symbol
+ in the global offset table. */
+
+ /* Resolve a GOTxx reloc against a local symbol directly,
+ without using the global offset table. */
+ if (h == NULL
+ || h->got.offset == (bfd_vma) -1)
+ break;
+
+ {
+ bfd_vma off;
+
+ if (sgot == NULL)
+ {
+ sgot = bfd_get_linker_section (dynobj, ".got");
+ BFD_ASSERT (sgot != NULL);
+ }
+
+ off = h->got.offset;
+ BFD_ASSERT (off < sgot->size);
+
+ bfd_put_32 (output_bfd, rel->r_addend, sgot->contents + off);
+
+ relocation = sgot->output_offset + off;
+ /* The GOT relocation uses the addend. */
+ rel->r_addend = 0;
+
+ /* Change the reference to be indirect. */
+ contents[rel->r_offset - 1] |= 0x10;
+ relocation += sgot->output_section->vma;
+ }
+ break;
+
+ case R_VAX_PC32:
+ /* If we are creating an executable and the function this
+ reloc refers to is in a shared lib, then we made a PLT
+ entry for this symbol and need to handle the reloc like
+ a PLT reloc. */
+ if (info->shared)
+ goto r_vax_pc32_shared;
+ /* Fall through. */
+ case R_VAX_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
+ || h->plt.offset == (bfd_vma) -1)
+ break;
+
+ if (splt == NULL)
+ {
+ splt = bfd_get_linker_section (dynobj, ".plt");
+ BFD_ASSERT (splt != NULL);
+ }
+
+ if (sgotplt == NULL)
+ {
+ sgotplt = bfd_get_linker_section (dynobj, ".got.plt");
+ BFD_ASSERT (sgotplt != NULL);
+ }
+
+ 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 two are reserved. */
+ got_offset = (plt_index + 3) * 4;
+
+ /* We want the relocation to point into the .got.plt instead
+ of the plt itself. */
+ relocation = (sgotplt->output_section->vma
+ + sgotplt->output_offset
+ + got_offset);
+ contents[rel->r_offset-1] |= 0x10; /* make indirect */
+ if (rel->r_addend == 2)
+ {
+ h->plt.offset |= 1;
+ }
+ else if (rel->r_addend != 0)
+ (*_bfd_error_handler)
+ (_("%s: warning: PLT addend of %d to `%s' from %s section ignored"),
+ bfd_get_filename (input_bfd), rel->r_addend,
+ h->root.root.string,
+ bfd_get_section_name (input_bfd, input_section));
+ rel->r_addend = 0;
+
+ break;
+
+ case R_VAX_PC8:
+ case R_VAX_PC16:
+ r_vax_pc32_shared:
+ if (h == NULL
+ || ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
+ || h->forced_local)
+ break;
+ /* Fall through. */
+ case R_VAX_8:
+ case R_VAX_16:
+ case R_VAX_32:
+ if (info->shared
+ && r_symndx != STN_UNDEF
+ && (input_section->flags & SEC_ALLOC) != 0
+ && ((r_type != R_VAX_PC8
+ && r_type != R_VAX_PC16
+ && r_type != R_VAX_PC32)
+ || ((input_section->flags & SEC_CODE)
+ && (!info->symbolic
+ || (!h->def_regular && h->type != STT_SECTION)))))
+ {
+ Elf_Internal_Rela outrel;
+ bfd_byte *loc;
+ bfd_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)
+ {
+ sreloc = _bfd_elf_get_dynamic_reloc_section
+ (input_bfd, input_section, /*rela?*/ TRUE);
+ if (sreloc == NULL)
+ return FALSE;
+ }
+
+ skip = FALSE;
+ relocate = FALSE;
+
+ outrel.r_offset =
+ _bfd_elf_section_offset (output_bfd, info, input_section,
+ rel->r_offset);
+ if (outrel.r_offset == (bfd_vma) -1)
+ skip = TRUE;
+ if (outrel.r_offset == (bfd_vma) -2)
+ skip = TRUE, relocate = TRUE;
+ 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->def_regular))
+ {
+ BFD_ASSERT (h->dynindx != -1);
+ outrel.r_info = ELF32_R_INFO (h->dynindx, r_type);
+ outrel.r_addend = relocation + rel->r_addend;
+ }
+ else
+ {
+ if (r_type == R_VAX_32)
+ {
+ relocate = TRUE;
+ outrel.r_info = ELF32_R_INFO (0, R_VAX_RELATIVE);
+ BFD_ASSERT (bfd_get_signed_32 (input_bfd,
+ &contents[rel->r_offset]) == 0);
+ outrel.r_addend = relocation + rel->r_addend;
+ }
+ else
+ {
+ long indx;
+
+ if (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;
+
+ /* We are turning this relocation into one
+ against a section symbol. It would be
+ proper to subtract the symbol's value,
+ osec->vma, from the emitted reloc addend,
+ but ld.so expects buggy relocs. */
+ osec = sec->output_section;
+ indx = elf_section_data (osec)->dynindx;
+ if (indx == 0)
+ {
+ struct elf_link_hash_table *htab;
+ htab = elf_hash_table (info);
+ osec = htab->text_index_section;
+ indx = elf_section_data (osec)->dynindx;
+ }
+ BFD_ASSERT (indx != 0);
+ }
+
+ outrel.r_info = ELF32_R_INFO (indx, r_type);
+ outrel.r_addend = relocation + rel->r_addend;
+ }
+ }
+
+ if ((input_section->flags & SEC_CODE) != 0
+ || (ELF32_R_TYPE (outrel.r_info) != R_VAX_32
+ && ELF32_R_TYPE (outrel.r_info) != R_VAX_RELATIVE
+ && ELF32_R_TYPE (outrel.r_info) != R_VAX_COPY
+ && ELF32_R_TYPE (outrel.r_info) != R_VAX_JMP_SLOT
+ && ELF32_R_TYPE (outrel.r_info) != R_VAX_GLOB_DAT))
+ {
+ if (h != NULL)
+ (*_bfd_error_handler)
+ (_("%s: warning: %s relocation against symbol `%s' from %s section"),
+ bfd_get_filename (input_bfd), howto->name,
+ h->root.root.string,
+ bfd_get_section_name (input_bfd, input_section));
+ else
+ (*_bfd_error_handler)
+ (_("%s: warning: %s relocation to 0x%x from %s section"),
+ bfd_get_filename (input_bfd), howto->name,
+ outrel.r_addend,
+ bfd_get_section_name (input_bfd, input_section));
+ }
+ loc = sreloc->contents;
+ loc += sreloc->reloc_count++ * sizeof (Elf32_External_Rela);
+ bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
+
+ /* This reloc will be computed at runtime, so there's no
+ need to do anything now, except for R_VAX_32
+ relocations that have been turned into
+ R_VAX_RELATIVE. */
+ if (!relocate)
+ continue;
+ }
+
+ break;
+
+ case R_VAX_GNU_VTINHERIT:
+ case R_VAX_GNU_VTENTRY:
+ /* These are no-ops in the end. */
+ continue;
+
+ default:
+ break;
+ }
+
+ /* VAX PCREL relocations are from the end of relocation, not the start.
+ So subtract the difference from the relocation amount since we can't
+ add it to the offset. */
+ if (howto->pc_relative && howto->pcrel_offset)
+ relocation -= bfd_get_reloc_size(howto);
+
+ 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 = NULL;
+ 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, (h ? &h->root : NULL), 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 bfd_boolean
+elf_vax_finish_dynamic_symbol (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;
+ bfd_vma addend;
+ Elf_Internal_Rela rela;
+ bfd_byte *loc;
+
+ /* This symbol has an entry in the procedure linkage table. Set
+ it up. */
+ BFD_ASSERT (h->dynindx != -1);
+
+ splt = bfd_get_linker_section (dynobj, ".plt");
+ sgot = bfd_get_linker_section (dynobj, ".got.plt");
+ srela = bfd_get_linker_section (dynobj, ".rela.plt");
+ BFD_ASSERT (splt != NULL && sgot != NULL && srela != NULL);
+
+ addend = 2 * (h->plt.offset & 1);
+ h->plt.offset &= ~1;
+
+ /* 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 two are reserved. */
+ got_offset = (plt_index + 3) * 4;
+
+ /* Fill in the entry in the procedure linkage table. */
+ memcpy (splt->contents + h->plt.offset, elf_vax_plt_entry,
+ PLT_ENTRY_SIZE);
+
+ /* The offset is relative to the first extension word. */
+ bfd_put_32 (output_bfd,
+ -(h->plt.offset + 8),
+ splt->contents + h->plt.offset + 4);
+
+ bfd_put_32 (output_bfd, plt_index * sizeof (Elf32_External_Rela),
+ splt->contents + h->plt.offset + 8);
+
+ /* Fill in the entry in the global offset table. */
+ bfd_put_32 (output_bfd,
+ (splt->output_section->vma
+ + splt->output_offset
+ + h->plt.offset) + addend,
+ 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_VAX_JMP_SLOT);
+ rela.r_addend = addend;
+ loc = srela->contents + plt_index * sizeof (Elf32_External_Rela);
+ bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
+
+ if (!h->def_regular)
+ {
+ /* 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;
+ bfd_byte *loc;
+
+ /* This symbol has an entry in the global offset table. Set it
+ up. */
+ sgot = bfd_get_linker_section (dynobj, ".got");
+ srela = bfd_get_linker_section (dynobj, ".rela.got");
+ BFD_ASSERT (sgot != NULL && srela != NULL);
+
+ rela.r_offset = (sgot->output_section->vma
+ + sgot->output_offset
+ + h->got.offset);
+ rela.r_info = ELF32_R_INFO (h->dynindx, R_VAX_GLOB_DAT);
+ rela.r_addend = bfd_get_signed_32 (output_bfd,
+ sgot->contents + h->got.offset);
+
+ loc = srela->contents;
+ loc += srela->reloc_count++ * sizeof (Elf32_External_Rela);
+ bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
+ }
+
+ if (h->needs_copy)
+ {
+ asection *s;
+ Elf_Internal_Rela rela;
+ bfd_byte *loc;
+
+ /* 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_linker_section (dynobj, ".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_VAX_COPY);
+ rela.r_addend = 0;
+ loc = s->contents + s->reloc_count++ * sizeof (Elf32_External_Rela);
+ bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
+ }
+
+ /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute. */
+ if (h == elf_hash_table (info)->hdynamic
+ || h == elf_hash_table (info)->hgot)
+ sym->st_shndx = SHN_ABS;
+
+ return TRUE;
+}
+
+/* Finish up the dynamic sections. */
+
+static bfd_boolean
+elf_vax_finish_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
+{
+ bfd *dynobj;
+ asection *sgot;
+ asection *sdyn;
+
+ dynobj = elf_hash_table (info)->dynobj;
+
+ sgot = bfd_get_linker_section (dynobj, ".got.plt");
+ BFD_ASSERT (sgot != NULL);
+ sdyn = bfd_get_linker_section (dynobj, ".dynamic");
+
+ if (elf_hash_table (info)->dynamic_sections_created)
+ {
+ asection *splt;
+ Elf32_External_Dyn *dyncon, *dynconend;
+
+ splt = bfd_get_linker_section (dynobj, ".plt");
+ BFD_ASSERT (splt != NULL && sdyn != NULL);
+
+ dyncon = (Elf32_External_Dyn *) sdyn->contents;
+ dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->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);
+ dyn.d_un.d_val = s->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)
+ dyn.d_un.d_val -= s->size;
+ bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
+ break;
+ }
+ }
+
+ /* Fill in the first entry in the procedure linkage table. */
+ if (splt->size > 0)
+ {
+ memcpy (splt->contents, elf_vax_plt0_entry, PLT_ENTRY_SIZE);
+ bfd_put_32 (output_bfd,
+ (sgot->output_section->vma
+ + sgot->output_offset + 4
+ - (splt->output_section->vma + 6)),
+ splt->contents + 2);
+ bfd_put_32 (output_bfd,
+ (sgot->output_section->vma
+ + sgot->output_offset + 8
+ - (splt->output_section->vma + 12)),
+ splt->contents + 8);
+ 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->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);
+ }
+
+ if (elf_section_data (sgot->output_section) != NULL)
+ elf_section_data (sgot->output_section)->this_hdr.sh_entsize = 4;
+
+ return TRUE;
+}
+
+static enum elf_reloc_type_class
+elf_vax_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ const asection *rel_sec ATTRIBUTE_UNUSED,
+ const Elf_Internal_Rela *rela)
+{
+ switch ((int) ELF32_R_TYPE (rela->r_info))
+ {
+ case R_VAX_RELATIVE:
+ return reloc_class_relative;
+ case R_VAX_JMP_SLOT:
+ return reloc_class_plt;
+ case R_VAX_COPY:
+ return reloc_class_copy;
+ default:
+ return reloc_class_normal;
+ }
+}
+
+static bfd_vma
+elf_vax_plt_sym_val (bfd_vma i, const asection *plt,
+ const arelent *rel ATTRIBUTE_UNUSED)
+{
+ return plt->vma + (i + 1) * PLT_ENTRY_SIZE;
+}
+
+#define TARGET_LITTLE_SYM vax_elf32_vec
+#define TARGET_LITTLE_NAME "elf32-vax"
+#define ELF_MACHINE_CODE EM_VAX
+#define ELF_MAXPAGESIZE 0x1000
+
+#define elf_backend_create_dynamic_sections \
+ _bfd_elf_create_dynamic_sections
+#define bfd_elf32_bfd_link_hash_table_create \
+ elf_vax_link_hash_table_create
+#define bfd_elf32_bfd_final_link bfd_elf_gc_common_final_link
+
+#define elf_backend_check_relocs elf_vax_check_relocs
+#define elf_backend_adjust_dynamic_symbol \
+ elf_vax_adjust_dynamic_symbol
+#define elf_backend_always_size_sections \
+ elf_vax_always_size_sections
+#define elf_backend_size_dynamic_sections \
+ elf_vax_size_dynamic_sections
+#define elf_backend_init_index_section _bfd_elf_init_1_index_section
+#define elf_backend_relocate_section elf_vax_relocate_section
+#define elf_backend_finish_dynamic_symbol \
+ elf_vax_finish_dynamic_symbol
+#define elf_backend_finish_dynamic_sections \
+ elf_vax_finish_dynamic_sections
+#define elf_backend_reloc_type_class elf_vax_reloc_type_class
+#define elf_backend_gc_mark_hook elf_vax_gc_mark_hook
+#define elf_backend_gc_sweep_hook elf_vax_gc_sweep_hook
+#define elf_backend_plt_sym_val elf_vax_plt_sym_val
+#define bfd_elf32_bfd_merge_private_bfd_data \
+ elf32_vax_merge_private_bfd_data
+#define bfd_elf32_bfd_set_private_flags \
+ elf32_vax_set_private_flags
+#define bfd_elf32_bfd_print_private_bfd_data \
+ elf32_vax_print_private_bfd_data
+
+#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 16
+#define elf_backend_rela_normal 1
+
+#include "elf32-target.h"
diff --git a/bfd/elf32-xc16x.c b/bfd/elf32-xc16x.c
new file mode 100644
index 0000000..9e7deca
--- /dev/null
+++ b/bfd/elf32-xc16x.c
@@ -0,0 +1,477 @@
+/* Infineon XC16X-specific support for 16-bit ELF.
+ Copyright (C) 2006-2014 Free Software Foundation, Inc.
+ Contributed by KPIT Cummins Infosystems
+
+ This file is part of BFD, the Binary File Descriptor library.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+#include "elf-bfd.h"
+#include "elf/xc16x.h"
+#include "dwarf2.h"
+#include "libiberty.h"
+
+static reloc_howto_type xc16x_elf_howto_table [] =
+{
+ /* This reloc does nothing. */
+ HOWTO (R_XC16X_NONE, /* 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_XC16X_NONE", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* An 8 bit absolute relocation. */
+ HOWTO (R_XC16X_ABS_8, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 8, /* bitsize */
+ FALSE, /* pc_relative */
+ 8, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_XC16X_ABS_8", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000, /* src_mask */
+ 0x00ff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A 16 bit absolute relocation. */
+ HOWTO (R_XC16X_ABS_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_XC16X_ABS_16", /* name */
+ TRUE, /* partial_inplace */
+ 0x00000000, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_XC16X_ABS_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_XC16X_ABS_32", /* name */
+ TRUE, /* partial_inplace */
+ 0x00000000, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+
+ /* A PC relative 8 bit relocation. */
+ HOWTO (R_XC16X_8_PCREL, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 8, /* bitsize */
+ TRUE, /* pc_relative */
+ 8, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_XC16X_8_PCREL", /* name */
+ FALSE, /* partial_inplace */
+ 0x0000, /* src_mask */
+ 0x00ff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* Relocation regarding page number. */
+ HOWTO (R_XC16X_PAG, /* 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_XC16X_PAG", /* name */
+ TRUE, /* partial_inplace */
+ 0x00000000, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+
+ /* Relocation regarding page number. */
+ HOWTO (R_XC16X_POF, /* 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_XC16X_POF", /* name */
+ TRUE, /* partial_inplace */
+ 0x00000000, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+
+ /* Relocation regarding segment number. */
+ HOWTO (R_XC16X_SEG, /* 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_XC16X_SEG", /* name */
+ TRUE, /* partial_inplace */
+ 0x00000000, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Relocation regarding segment offset. */
+ HOWTO (R_XC16X_SOF, /* 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_XC16X_SOF", /* name */
+ TRUE, /* partial_inplace */
+ 0x00000000, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE) /* pcrel_offset */
+};
+
+
+/* Map BFD reloc types to XC16X ELF reloc types. */
+
+struct xc16x_reloc_map
+{
+ bfd_reloc_code_real_type bfd_reloc_val;
+ unsigned int xc16x_reloc_val;
+};
+
+static const struct xc16x_reloc_map xc16x_reloc_map [] =
+{
+ { BFD_RELOC_NONE, R_XC16X_NONE },
+ { BFD_RELOC_8, R_XC16X_ABS_8 },
+ { BFD_RELOC_16, R_XC16X_ABS_16 },
+ { BFD_RELOC_32, R_XC16X_ABS_32 },
+ { BFD_RELOC_8_PCREL, R_XC16X_8_PCREL },
+ { BFD_RELOC_XC16X_PAG, R_XC16X_PAG},
+ { BFD_RELOC_XC16X_POF, R_XC16X_POF},
+ { BFD_RELOC_XC16X_SEG, R_XC16X_SEG},
+ { BFD_RELOC_XC16X_SOF, R_XC16X_SOF},
+};
+
+
+/* This function is used to search for correct relocation type from
+ howto structure. */
+
+static reloc_howto_type *
+xc16x_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ bfd_reloc_code_real_type code)
+{
+ unsigned int i;
+
+ for (i = ARRAY_SIZE (xc16x_reloc_map); --i;)
+ if (xc16x_reloc_map [i].bfd_reloc_val == code)
+ return & xc16x_elf_howto_table [xc16x_reloc_map[i].xc16x_reloc_val];
+
+ return NULL;
+}
+
+static reloc_howto_type *
+xc16x_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ const char *r_name)
+{
+ unsigned int i;
+
+ for (i = 0;
+ i < sizeof (xc16x_elf_howto_table) / sizeof (xc16x_elf_howto_table[0]);
+ i++)
+ if (xc16x_elf_howto_table[i].name != NULL
+ && strcasecmp (xc16x_elf_howto_table[i].name, r_name) == 0)
+ return &xc16x_elf_howto_table[i];
+
+ return NULL;
+}
+
+/* For a particular operand this function is
+ called to finalise the type of relocation. */
+
+static void
+elf32_xc16x_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED, arelent *bfd_reloc,
+ Elf_Internal_Rela *elf_reloc)
+{
+ unsigned int r;
+ unsigned int i;
+
+ r = ELF32_R_TYPE (elf_reloc->r_info);
+ for (i = 0; i < ARRAY_SIZE (xc16x_elf_howto_table); i++)
+ if (xc16x_elf_howto_table[i].type == r)
+ {
+ bfd_reloc->howto = &xc16x_elf_howto_table[i];
+ return;
+ }
+ abort ();
+}
+
+static bfd_reloc_status_type
+elf32_xc16x_final_link_relocate (unsigned long r_type,
+ bfd *input_bfd,
+ bfd *output_bfd ATTRIBUTE_UNUSED,
+ asection *input_section ATTRIBUTE_UNUSED,
+ bfd_byte *contents,
+ bfd_vma offset,
+ bfd_vma value,
+ bfd_vma addend,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ asection *sym_sec ATTRIBUTE_UNUSED,
+ int is_local ATTRIBUTE_UNUSED)
+{
+ bfd_byte *hit_data = contents + offset;
+ bfd_vma val1;
+
+ switch (r_type)
+ {
+ case R_XC16X_NONE:
+ return bfd_reloc_ok;
+
+ case R_XC16X_ABS_16:
+ value += addend;
+ bfd_put_16 (input_bfd, value, hit_data);
+ return bfd_reloc_ok;
+
+ case R_XC16X_8_PCREL:
+ bfd_put_8 (input_bfd, value, hit_data);
+ return bfd_reloc_ok;
+
+ /* Following case is to find page number from actual
+ address for this divide value by 16k i.e. page size. */
+
+ case R_XC16X_PAG:
+ value += addend;
+ value /= 0x4000;
+ bfd_put_16 (input_bfd, value, hit_data);
+ return bfd_reloc_ok;
+
+ /* Following case is to find page offset from actual address
+ for this take modulo of value by 16k i.e. page size. */
+
+ case R_XC16X_POF:
+ value += addend;
+ value %= 0x4000;
+ bfd_put_16 (input_bfd, value, hit_data);
+ return bfd_reloc_ok;
+
+ /* Following case is to find segment number from actual
+ address for this divide value by 64k i.e. segment size. */
+
+ case R_XC16X_SEG:
+ value += addend;
+ value /= 0x10000;
+ bfd_put_16 (input_bfd, value, hit_data);
+ return bfd_reloc_ok;
+
+ /* Following case is to find segment offset from actual address
+ for this take modulo of value by 64k i.e. segment size. */
+
+ case R_XC16X_SOF:
+ value += addend;
+ value %= 0x10000;
+ bfd_put_16 (input_bfd, value, hit_data);
+ return bfd_reloc_ok;
+
+ case R_XC16X_ABS_32:
+ if (!strstr (input_section->name,".debug"))
+ {
+ value += addend;
+ val1 = value;
+ value %= 0x4000;
+ val1 /= 0x4000;
+ val1 = val1 << 16;
+ value += val1;
+ bfd_put_32 (input_bfd, value, hit_data);
+ }
+ else
+ {
+ value += addend;
+ bfd_put_32 (input_bfd, value, hit_data);
+ }
+ return bfd_reloc_ok;
+
+ default:
+ return bfd_reloc_notsupported;
+ }
+}
+
+static bfd_boolean
+elf32_xc16x_relocate_section (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++)
+ {
+ unsigned int r_type;
+ unsigned long r_symndx;
+ Elf_Internal_Sym *sym;
+ asection *sec;
+ struct elf_link_hash_entry *h;
+ bfd_vma relocation;
+
+ /* This is a final link. */
+ r_symndx = ELF32_R_SYM (rel->r_info);
+ r_type = 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 = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
+ }
+ else
+ {
+ bfd_boolean unresolved_reloc, warned, ignored;
+
+ RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
+ r_symndx, symtab_hdr, sym_hashes,
+ h, sec, relocation,
+ unresolved_reloc, warned, ignored);
+ }
+
+ if (sec != NULL && discarded_section (sec))
+ {
+ /* For relocs against symbols from removed linkonce sections,
+ or sections discarded by a linker script, we just want the
+ section contents cleared. Avoid any special processing. */
+ reloc_howto_type *howto;
+ howto = xc16x_reloc_type_lookup (input_bfd, r_type);
+ RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+ rel, 1, relend, howto, 0, contents);
+ }
+
+ if (info->relocatable)
+ continue;
+
+ elf32_xc16x_final_link_relocate (r_type, input_bfd, output_bfd,
+ input_section,
+ contents, rel->r_offset,
+ relocation, rel->r_addend,
+ info, sec, h == NULL);
+ }
+
+ return TRUE;
+}
+
+
+static void
+elf32_xc16x_final_write_processing (bfd *abfd,
+ bfd_boolean linker ATTRIBUTE_UNUSED)
+{
+ unsigned long val;
+
+ switch (bfd_get_mach (abfd))
+ {
+ default:
+ case bfd_mach_xc16x:
+ val = 0x1000;
+ break;
+
+ case bfd_mach_xc16xl:
+ val = 0x1001;
+ break;
+
+ case bfd_mach_xc16xs:
+ val = 0x1002;
+ break;
+ }
+
+ elf_elfheader (abfd)->e_flags |= val;
+}
+
+static unsigned long
+elf32_xc16x_mach (flagword flags)
+{
+ switch (flags)
+ {
+ case 0x1000:
+ default:
+ return bfd_mach_xc16x;
+
+ case 0x1001:
+ return bfd_mach_xc16xl;
+
+ case 0x1002:
+ return bfd_mach_xc16xs;
+ }
+}
+
+
+static bfd_boolean
+elf32_xc16x_object_p (bfd *abfd)
+{
+ bfd_default_set_arch_mach (abfd, bfd_arch_xc16x,
+ elf32_xc16x_mach (elf_elfheader (abfd)->e_flags));
+ return TRUE;
+}
+
+
+#define ELF_ARCH bfd_arch_xc16x
+#define ELF_MACHINE_CODE EM_XC16X
+#define ELF_MAXPAGESIZE 0x100
+
+#define TARGET_LITTLE_SYM xc16x_elf32_vec
+#define TARGET_LITTLE_NAME "elf32-xc16x"
+#define elf_backend_final_write_processing elf32_xc16x_final_write_processing
+#define elf_backend_object_p elf32_xc16x_object_p
+#define elf_backend_can_gc_sections 1
+#define bfd_elf32_bfd_reloc_type_lookup xc16x_reloc_type_lookup
+#define bfd_elf32_bfd_reloc_name_lookup xc16x_reloc_name_lookup
+#define elf_info_to_howto elf32_xc16x_info_to_howto
+#define elf_info_to_howto_rel elf32_xc16x_info_to_howto
+#define elf_backend_relocate_section elf32_xc16x_relocate_section
+#define elf_backend_rela_normal 1
+
+#include "elf32-target.h"
diff --git a/bfd/elf32-xgate.c b/bfd/elf32-xgate.c
new file mode 100644
index 0000000..01f39fa
--- /dev/null
+++ b/bfd/elf32-xgate.c
@@ -0,0 +1,729 @@
+/* Freescale XGATE-specific support for 32-bit ELF
+ Copyright (C) 2010-2014 Free Software Foundation, Inc.
+ Contributed by Sean Keys(skeys@ipdatasys.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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "bfdlink.h"
+#include "libbfd.h"
+#include "elf-bfd.h"
+#include "elf32-xgate.h"
+#include "elf/xgate.h"
+#include "opcode/xgate.h"
+#include "libiberty.h"
+
+/* Relocation functions. */
+static reloc_howto_type *
+bfd_elf32_bfd_reloc_type_lookup (bfd *, bfd_reloc_code_real_type);
+static reloc_howto_type *
+bfd_elf32_bfd_reloc_name_lookup (bfd *, const char *);
+static void
+xgate_info_to_howto_rel (bfd *, arelent *, Elf_Internal_Rela *);
+static bfd_boolean
+xgate_elf_set_mach_from_flags (bfd *);
+static struct bfd_hash_entry *
+stub_hash_newfunc (struct bfd_hash_entry *, struct bfd_hash_table *,
+ const char *);
+static struct bfd_link_hash_table*
+xgate_elf_bfd_link_hash_table_create (bfd *);
+
+/* Use REL instead of RELA to save space */
+#define USE_REL 1
+
+static reloc_howto_type elf_xgate_howto_table[] =
+{
+ /* This reloc does nothing. */
+ HOWTO (R_XGATE_NONE, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_XGATE_NONE", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A 8 bit absolute relocation. */
+ HOWTO (R_XGATE_8, /* 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_XGATE_8", /* name */
+ FALSE, /* partial_inplace */
+ 0x00ff, /* src_mask */
+ 0x00ff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A 8 bit PC-rel relocation. */
+ HOWTO (R_XGATE_PCREL_8, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 8, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_XGATE_PCREL_8", /* name */
+ FALSE, /* partial_inplace */
+ 0x00ff, /* src_mask */
+ 0x00ff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* A 16 bit absolute relocation. */
+ HOWTO (R_XGATE_16, /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont /*bitfield */, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_XGATE_16", /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A 32 bit absolute relocation. This one is never used for the
+ code relocation. It's used by gas for -gstabs generation. */
+ HOWTO (R_XGATE_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_XGATE_32", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A 16 bit PC-rel relocation. */
+ HOWTO (R_XGATE_PCREL_16, /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_XGATE_PCREL_16", /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* GNU extension to record C++ vtable hierarchy. */
+ HOWTO (R_XGATE_GNU_VTINHERIT, /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 0, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ NULL, /* special_function */
+ "R_XGATE_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_XGATE_GNU_VTENTRY, /* type */
+ 0, /* rightshift */
+ 1, /* 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_XGATE_GNU_VTENTRY", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A 24 bit relocation. */
+ HOWTO (R_XGATE_24, /* 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_XGATE_IMM8_LO", /* name */
+ FALSE, /* partial_inplace */
+ 0x00ff, /* src_mask */
+ 0x00ff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A 16-bit low relocation. */
+ HOWTO (R_XGATE_LO16, /* type */
+ 8, /* 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_XGATE_IMM8_HI", /* name */
+ FALSE, /* partial_inplace */
+ 0x00ff, /* src_mask */
+ 0x00ff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A page relocation. */
+ HOWTO (R_XGATE_GPAGE, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 8, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ xgate_elf_special_reloc,/* special_function */
+ "R_XGATE_GPAGE", /* name */
+ FALSE, /* partial_inplace */
+ 0x00ff, /* src_mask */
+ 0x00ff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A 9 bit absolute relocation. */
+ HOWTO (R_XGATE_PCREL_9, /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 9, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_XGATE_PCREL_9", /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* A 8 bit absolute relocation (upper address). */
+ HOWTO (R_XGATE_PCREL_10, /* type */
+ 8, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 10, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_XGATE_PCREL_10", /* name */
+ FALSE, /* partial_inplace */
+ 0x00ff, /* src_mask */
+ 0x00ff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* A 8 bit absolute relocation. */
+ HOWTO (R_XGATE_IMM8_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_XGATE_IMM8_LO", /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A 16 bit absolute relocation (upper address). */
+ HOWTO (R_XGATE_IMM8_HI, /* type */
+ 8, /* 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_XGATE_IMM8_HI", /* name */
+ FALSE, /* partial_inplace */
+ 0x00ff, /* src_mask */
+ 0x00ff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A 3 bit absolute relocation. */
+ HOWTO (R_XGATE_IMM3, /* type */
+ 8, /* 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_XGATE_IMM3", /* name */
+ FALSE, /* partial_inplace */
+ 0x00ff, /* src_mask */
+ 0x00ff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A 4 bit absolute relocation. */
+ HOWTO (R_XGATE_IMM4, /* type */
+ 8, /* 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_XGATE_IMM4", /* name */
+ FALSE, /* partial_inplace */
+ 0x00ff, /* src_mask */
+ 0x00ff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A 5 bit absolute relocation. */
+ HOWTO (R_XGATE_IMM5, /* type */
+ 8, /* 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_XGATE_IMM5", /* name */
+ FALSE, /* partial_inplace */
+ 0x00ff, /* src_mask */
+ 0x00ff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Mark beginning of a jump instruction (any form). */
+ HOWTO (R_XGATE_RL_JUMP, /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 0, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ xgate_elf_ignore_reloc, /* special_function */
+ "R_XGATE_RL_JUMP", /* name */
+ TRUE, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* Mark beginning of Gcc relaxation group instruction. */
+ HOWTO (R_XGATE_RL_GROUP, /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 0, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ xgate_elf_ignore_reloc, /* special_function */
+ "R_XGATE_RL_GROUP", /* name */
+ TRUE, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ TRUE), /* pcrel_offset */
+};
+
+/* Map BFD reloc types to XGATE ELF reloc types. */
+
+struct xgate_reloc_map
+{
+ bfd_reloc_code_real_type bfd_reloc_val;
+ unsigned char elf_reloc_val;
+};
+
+static const struct xgate_reloc_map xgate_reloc_map[] =
+{
+ {BFD_RELOC_NONE, R_XGATE_NONE},
+ {BFD_RELOC_8, R_XGATE_8},
+ {BFD_RELOC_8_PCREL, R_XGATE_PCREL_8},
+ {BFD_RELOC_16_PCREL, R_XGATE_PCREL_16},
+ {BFD_RELOC_16, R_XGATE_16},
+ {BFD_RELOC_32, R_XGATE_32},
+
+ {BFD_RELOC_VTABLE_INHERIT, R_XGATE_GNU_VTINHERIT},
+ {BFD_RELOC_VTABLE_ENTRY, R_XGATE_GNU_VTENTRY},
+
+ {BFD_RELOC_XGATE_LO16, R_XGATE_LO16},
+ {BFD_RELOC_XGATE_GPAGE, R_XGATE_GPAGE},
+ {BFD_RELOC_XGATE_24, R_XGATE_24},
+ {BFD_RELOC_XGATE_PCREL_9, R_XGATE_PCREL_9},
+ {BFD_RELOC_XGATE_PCREL_10, R_XGATE_PCREL_10},
+ {BFD_RELOC_XGATE_IMM8_LO, R_XGATE_IMM8_LO},
+ {BFD_RELOC_XGATE_IMM8_HI, R_XGATE_IMM8_HI},
+ {BFD_RELOC_XGATE_IMM3, R_XGATE_IMM3},
+ {BFD_RELOC_XGATE_IMM4, R_XGATE_IMM4},
+ {BFD_RELOC_XGATE_IMM5, R_XGATE_IMM5},
+
+ {BFD_RELOC_XGATE_RL_JUMP, R_XGATE_RL_JUMP},
+ {BFD_RELOC_XGATE_RL_GROUP, R_XGATE_RL_GROUP},
+};
+
+static reloc_howto_type *
+bfd_elf32_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ bfd_reloc_code_real_type code)
+{
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE (xgate_reloc_map); i++)
+ if (xgate_reloc_map[i].bfd_reloc_val == code)
+ return &elf_xgate_howto_table[xgate_reloc_map[i].elf_reloc_val];
+
+ return NULL;
+}
+
+static reloc_howto_type *
+bfd_elf32_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, const char *r_name)
+{
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE (elf_xgate_howto_table); i++)
+ if (elf_xgate_howto_table[i].name != NULL
+ && strcasecmp (elf_xgate_howto_table[i].name, r_name) == 0)
+ return &elf_xgate_howto_table[i];
+
+ return NULL;
+}
+
+/* Set the howto pointer for an XGATE ELF reloc. */
+
+static void
+xgate_info_to_howto_rel (bfd *abfd ATTRIBUTE_UNUSED,
+ arelent *cache_ptr,
+ Elf_Internal_Rela *dst)
+{
+ unsigned int r_type;
+
+ r_type = ELF32_R_TYPE (dst->r_info);
+ BFD_ASSERT(r_type < (unsigned int) R_XGATE_max);
+ cache_ptr->howto = &elf_xgate_howto_table[r_type];
+}
+
+/* Destroy an XGATE ELF linker hash table. */
+
+static void
+xgate_elf_bfd_link_hash_table_free (bfd *obfd)
+{
+ struct xgate_elf_link_hash_table *ret =
+ (struct xgate_elf_link_hash_table *) obfd->link.hash;
+
+ bfd_hash_table_free (ret->stub_hash_table);
+ free (ret->stub_hash_table);
+ _bfd_elf_link_hash_table_free (obfd);
+}
+
+/* Create an XGATE ELF linker hash table. */
+
+static struct bfd_link_hash_table*
+xgate_elf_bfd_link_hash_table_create (bfd *abfd)
+{
+ struct xgate_elf_link_hash_table *ret;
+ bfd_size_type amt = sizeof(struct xgate_elf_link_hash_table);
+
+ ret = (struct xgate_elf_link_hash_table *) bfd_zmalloc (amt);
+ if (ret == (struct xgate_elf_link_hash_table *) NULL)
+ return NULL;
+
+ if (!_bfd_elf_link_hash_table_init (&ret->root, abfd,
+ _bfd_elf_link_hash_newfunc, sizeof(struct elf_link_hash_entry),
+ XGATE_ELF_DATA))
+ {
+ free (ret);
+ return NULL;
+ }
+
+ /* Init the stub hash table too. */
+ amt = sizeof(struct bfd_hash_table);
+ ret->stub_hash_table = (struct bfd_hash_table*) bfd_zmalloc (amt);
+ if (ret->stub_hash_table == NULL)
+ {
+ _bfd_elf_link_hash_table_free (abfd);
+ return NULL;
+ }
+
+ if (!bfd_hash_table_init (ret->stub_hash_table, stub_hash_newfunc,
+ sizeof(struct elf32_xgate_stub_hash_entry)))
+ {
+ free (ret->stub_hash_table);
+ _bfd_elf_link_hash_table_free (abfd);
+ return NULL;
+ }
+ ret->root.root.hash_table_free = xgate_elf_bfd_link_hash_table_free;
+
+ return &ret->root.root;
+}
+
+static bfd_boolean
+xgate_elf_set_mach_from_flags (bfd *abfd ATTRIBUTE_UNUSED)
+{
+ return TRUE;
+}
+
+/* Specific sections:
+ - The .page0 is a data section that is mapped in [0x0000..0x00FF].
+ Page0 accesses are faster on the M68HC12.
+ - The .vectors is the section that represents the interrupt
+ vectors.
+ - The .xgate section is starts in 0xE08800 or as xgate sees it 0x0800. */
+static const struct bfd_elf_special_section elf32_xgate_special_sections[] =
+{
+ { STRING_COMMA_LEN (".eeprom"), 0, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE },
+ { STRING_COMMA_LEN (".page0"), 0, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE },
+ { STRING_COMMA_LEN (".softregs"), 0, SHT_NOBITS, SHF_ALLOC + SHF_WRITE },
+ { STRING_COMMA_LEN (".vectors"), 0, SHT_PROGBITS, SHF_ALLOC },
+/*{ STRING_COMMA_LEN (".xgate"), 0, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE },
+ TODO finish this implementation */
+ { NULL, 0, 0, 0, 0 }
+};
+
+struct xgate_scan_param
+{
+ struct xgate_page_info* pinfo;
+ bfd_boolean use_memory_banks;
+};
+
+/* Assorted hash table functions. */
+
+/* Initialize an entry in the stub hash table. */
+
+static struct bfd_hash_entry *
+stub_hash_newfunc (struct bfd_hash_entry *entry,
+ struct bfd_hash_table *table ATTRIBUTE_UNUSED,
+ const char *string ATTRIBUTE_UNUSED)
+{
+ return entry;
+}
+
+/* Hook called by the linker routine which adds symbols from an object
+ file. */
+
+bfd_boolean
+elf32_xgate_add_symbol_hook (bfd *abfd ATTRIBUTE_UNUSED,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ Elf_Internal_Sym *sym,
+ const char **namep ATTRIBUTE_UNUSED,
+ flagword *flagsp ATTRIBUTE_UNUSED,
+ asection **secp ATTRIBUTE_UNUSED,
+ bfd_vma *valp ATTRIBUTE_UNUSED)
+{
+ /* For some reason the st_target_internal value is not retained
+ after xgate_frob_symbol is called, hence this temp hack. */
+ sym->st_target_internal = 1;
+ return TRUE;
+}
+
+/* External entry points for sizing and building linker stubs. */
+
+/* Set up various things so that we can make a list of input sections
+ for each output section included in the link. Returns -1 on error,
+ 0 when no stubs will be needed, and 1 on success. */
+
+int
+elf32_xgate_setup_section_lists (bfd *output_bfd ATTRIBUTE_UNUSED,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED)
+{
+ return 1;
+}
+
+/* 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 any "9-bit PC-REL"
+ instruction. */
+
+bfd_boolean
+elf32_xgate_size_stubs (bfd *output_bfd ATTRIBUTE_UNUSED,
+ bfd *stub_bfd ATTRIBUTE_UNUSED,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ asection * (*add_stub_section) (const char*, asection*) ATTRIBUTE_UNUSED)
+{
+ return FALSE;
+}
+
+/* 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 function is called via xgateelf_finish in the
+ linker. */
+
+bfd_boolean
+elf32_xgate_build_stubs (bfd *abfd ATTRIBUTE_UNUSED,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED)
+{
+ return TRUE;
+}
+
+void
+xgate_elf_get_bank_parameters (struct bfd_link_info *info ATTRIBUTE_UNUSED)
+{
+ return;
+}
+
+/* This function is used for relocs which are only used for relaxing,
+ which the linker should otherwise ignore. */
+
+bfd_reloc_status_type
+xgate_elf_ignore_reloc (bfd *abfd ATTRIBUTE_UNUSED,
+ arelent *reloc_entry,
+ asymbol *symbol ATTRIBUTE_UNUSED,
+ void *data ATTRIBUTE_UNUSED,
+ asection *input_section,
+ bfd *output_bfd,
+ char **error_message ATTRIBUTE_UNUSED)
+{
+ if (output_bfd != NULL)
+ reloc_entry->address += input_section->output_offset;
+ return bfd_reloc_ok;
+}
+
+bfd_reloc_status_type
+xgate_elf_special_reloc (bfd *abfd ATTRIBUTE_UNUSED,
+ arelent *reloc_entry ATTRIBUTE_UNUSED,
+ asymbol *symbol ATTRIBUTE_UNUSED,
+ void *data ATTRIBUTE_UNUSED,
+ asection *input_section ATTRIBUTE_UNUSED,
+ bfd *output_bfd ATTRIBUTE_UNUSED,
+ char **error_message ATTRIBUTE_UNUSED)
+{
+ abort ();
+}
+
+/* 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. */
+
+bfd_boolean
+elf32_xgate_check_relocs (bfd *abfd ATTRIBUTE_UNUSED,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ asection *sec ATTRIBUTE_UNUSED,
+ const Elf_Internal_Rela *relocs ATTRIBUTE_UNUSED)
+{
+ return TRUE;
+}
+
+/* Relocate a XGATE/S12x ELF section. */
+
+bfd_boolean
+elf32_xgate_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ bfd *input_bfd ATTRIBUTE_UNUSED,
+ asection *input_section ATTRIBUTE_UNUSED,
+ bfd_byte *contents ATTRIBUTE_UNUSED,
+ Elf_Internal_Rela *relocs ATTRIBUTE_UNUSED,
+ Elf_Internal_Sym *local_syms ATTRIBUTE_UNUSED,
+ asection **local_sections ATTRIBUTE_UNUSED)
+{
+ return TRUE;
+}
+
+/* Set and control ELF flags in ELF header. */
+
+bfd_boolean
+_bfd_xgate_elf_set_private_flags (bfd *abfd ATTRIBUTE_UNUSED,
+ flagword flags ATTRIBUTE_UNUSED)
+{
+ return TRUE;
+}
+
+/* Merge backend specific data from an object file to the output
+ object file when linking. */
+
+bfd_boolean
+_bfd_xgate_elf_merge_private_bfd_data (bfd *ibfd ATTRIBUTE_UNUSED,
+ bfd *obfd ATTRIBUTE_UNUSED)
+{
+ return TRUE;
+}
+
+bfd_boolean
+_bfd_xgate_elf_print_private_bfd_data (bfd *abfd, void *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 & E_XGATE_I32)
+ fprintf (file, _("[abi=32-bit int, "));
+ else
+ fprintf (file, _("[abi=16-bit int, "));
+
+ if (elf_elfheader (abfd)->e_flags & E_XGATE_F64)
+ fprintf (file, _("64-bit double, "));
+ else
+ fprintf (file, _("32-bit double, "));
+ if (elf_elfheader (abfd)->e_flags & EF_XGATE_MACH)
+ fprintf (file, _("cpu=XGATE]"));
+ else
+ fprintf (file, _("error reading cpu type from elf private data"));
+ fputc ('\n', file);
+
+ return TRUE;
+}
+
+void
+elf32_xgate_post_process_headers (bfd *abfd ATTRIBUTE_UNUSED, struct bfd_link_info *link_info ATTRIBUTE_UNUSED)
+{
+
+}
+
+#define ELF_ARCH bfd_arch_xgate
+#define ELF_MACHINE_CODE EM_XGATE
+#define ELF_TARGET_ID XGATE_ELF_DATA
+
+#define ELF_MAXPAGESIZE 0x1000
+
+#define TARGET_BIG_SYM xgate_elf32_vec
+#define TARGET_BIG_NAME "elf32-xgate"
+
+#define elf_info_to_howto 0
+#define elf_info_to_howto_rel xgate_info_to_howto_rel
+#define elf_backend_check_relocs elf32_xgate_check_relocs
+#define elf_backend_relocate_section elf32_xgate_relocate_section
+#define elf_backend_object_p xgate_elf_set_mach_from_flags
+#define elf_backend_final_write_processing 0
+#define elf_backend_can_gc_sections 1
+#define elf_backend_special_sections elf32_xgate_special_sections
+#define elf_backend_post_process_headers elf32_xgate_post_process_headers
+#define elf_backend_add_symbol_hook elf32_xgate_add_symbol_hook
+
+#define bfd_elf32_bfd_link_hash_table_create xgate_elf_bfd_link_hash_table_create
+#define bfd_elf32_bfd_merge_private_bfd_data _bfd_xgate_elf_merge_private_bfd_data
+#define bfd_elf32_bfd_set_private_flags _bfd_xgate_elf_set_private_flags
+#define bfd_elf32_bfd_print_private_bfd_data _bfd_xgate_elf_print_private_bfd_data
+
+#define xgate_stub_hash_lookup(table, string, create, copy) \
+ ((struct elf32_xgate_stub_hash_entry *) \
+ bfd_hash_lookup ((table), (string), (create), (copy)))
+
+#include "elf32-target.h"
diff --git a/bfd/elf32-xgate.h b/bfd/elf32-xgate.h
new file mode 100644
index 0000000..f130001
--- /dev/null
+++ b/bfd/elf32-xgate.h
@@ -0,0 +1,143 @@
+/* Freescale XGATE-specific support for 32-bit ELF
+ Copyright (C) 2012-2014 Free Software Foundation, Inc.
+
+ Contributed by Sean Keys (skeys@ipdatasys.com)
+ (Heavily copied from the HC11 port by Stephane Carrez (stcarrez@nerim.fr))
+
+ This file is part of BFD, the Binary File Descriptor library.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#ifndef _ELF32_XGATE_H
+#define _ELF32_XGATE_H
+
+#include "elf-bfd.h"
+#include "bfdlink.h"
+#include "elf/xgate.h"
+
+/* Set and control ELF flags in ELF header. */
+extern bfd_boolean _bfd_xgate_elf_merge_private_bfd_data (bfd*,bfd*);
+extern bfd_boolean _bfd_xgate_elf_set_private_flags (bfd*,flagword);
+extern bfd_boolean _bfd_xgate_elf_print_private_bfd_data (bfd*, void*);
+
+struct elf32_xgate_stub_hash_entry
+{
+ /* Base hash table entry structure. */
+ struct bfd_hash_entry root;
+
+ /* The stub section. */
+ asection *stub_sec;
+
+ /* Offset within stub_sec of the beginning of this stub. */
+ bfd_vma stub_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. */
+ bfd_vma target_value;
+ asection *target_section;
+};
+
+struct xgate_page_info
+{
+ bfd_vma bank_virtual;
+ bfd_vma bank_physical;
+ bfd_vma bank_physical_end;
+ bfd_vma bank_mask;
+ bfd_vma bank_size;
+ int bank_shift;
+ int bank_param_initialized;
+ bfd_vma trampoline_addr;
+};
+
+struct xgate_elf_link_hash_table
+{
+ struct elf_link_hash_table root;
+ struct xgate_page_info pinfo;
+
+ /* The stub hash table. */
+ struct bfd_hash_table* stub_hash_table;
+
+ /* Linker stub bfd. */
+ bfd *stub_bfd;
+
+ asection* stub_section;
+ asection* tramp_section;
+
+ /* Linker call-backs. */
+ asection * (*add_stub_section) (const char *, asection *);
+
+ /* Assorted information used by elf32_hppa_size_stubs. */
+ unsigned int bfd_count;
+ int top_index;
+ asection ** input_list;
+
+ /* Small local sym cache. */
+ struct sym_cache sym_cache;
+
+ bfd_boolean (*size_one_stub) (struct bfd_hash_entry*, void*);
+ bfd_boolean (*build_one_stub) (struct bfd_hash_entry*, void*);
+};
+
+/* Get the XGate ELF linker hash table from a link_info structure. */
+
+#define xgate_elf_hash_table(p) \
+ ((struct xgate_elf_link_hash_table *) ((p)->hash))
+
+/* Create a XGATE ELF linker hash table. */
+
+extern struct xgate_elf_link_hash_table* xgate_elf_hash_table_create
+ (bfd *);
+
+extern void xgate_elf_get_bank_parameters (struct bfd_link_info *);
+
+/* Return 1 if the address is in banked memory.
+ This can be applied to a virtual address and to a physical address. */
+extern int xgate_addr_is_banked (struct xgate_page_info *, bfd_vma);
+
+/* Return the physical address seen by the processor, taking
+ into account banked memory. */
+extern bfd_vma xgate_phys_addr (struct xgate_page_info *, bfd_vma);
+
+/* Return the page number corresponding to an address in banked memory. */
+extern bfd_vma xgate_phys_page (struct xgate_page_info *, bfd_vma);
+
+bfd_reloc_status_type xgate_elf_ignore_reloc
+ (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
+bfd_reloc_status_type xgate_elf_special_reloc
+ (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
+
+bfd_boolean elf32_xgate_check_relocs
+ (bfd *, struct bfd_link_info *, asection *, const Elf_Internal_Rela *);
+bfd_boolean elf32_xgate_relocate_section
+ (bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
+ Elf_Internal_Rela *, Elf_Internal_Sym *, asection **);
+
+bfd_boolean elf32_xgate_add_symbol_hook
+ (bfd *, struct bfd_link_info *, Elf_Internal_Sym *, const char **,
+ flagword *, asection **, bfd_vma *);
+
+/* Tweak the OSABI field of the elf header. */
+extern void elf32_xgate_post_process_headers (bfd *, struct bfd_link_info *);
+
+int elf32_xgate_setup_section_lists (bfd *, struct bfd_link_info *);
+
+bfd_boolean elf32_xgate_size_stubs
+ (bfd *, bfd *, struct bfd_link_info *,
+ asection * (*) (const char *, asection *));
+
+bfd_boolean elf32_xgate_build_stubs (bfd * abfd, struct bfd_link_info *);
+
+#endif /* _ELF32_XGATE_H */
diff --git a/bfd/elf32-xstormy16.c b/bfd/elf32-xstormy16.c
new file mode 100644
index 0000000..f918a1e
--- /dev/null
+++ b/bfd/elf32-xstormy16.c
@@ -0,0 +1,1040 @@
+/* Xstormy16-specific support for 32-bit ELF.
+ Copyright (C) 2000-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+#include "elf-bfd.h"
+#include "elf/xstormy16.h"
+#include "libiberty.h"
+
+/* Handle the R_XSTORMY16_24 reloc, which has an odd bit arrangement. */
+
+static bfd_reloc_status_type
+xstormy16_elf_24_reloc (bfd *abfd,
+ arelent *reloc_entry,
+ asymbol *symbol,
+ void * data,
+ asection *input_section,
+ bfd *output_bfd,
+ char **error_message ATTRIBUTE_UNUSED)
+{
+ bfd_vma relocation, x;
+
+ if (output_bfd != NULL)
+ {
+ reloc_entry->address += input_section->output_offset;
+ return bfd_reloc_ok;
+ }
+
+ if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
+ 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;
+
+ x = bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
+ x &= 0x0000ff00;
+ x |= relocation & 0xff;
+ x |= (relocation << 8) & 0xffff0000;
+ bfd_put_32 (abfd, x, (bfd_byte *) data + reloc_entry->address);
+
+ if (relocation & ~ (bfd_vma) 0xffffff)
+ return bfd_reloc_overflow;
+
+ return bfd_reloc_ok;
+}
+
+static reloc_howto_type xstormy16_elf_howto_table [] =
+{
+ /* This reloc does nothing. */
+ HOWTO (R_XSTORMY16_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_XSTORMY16_NONE", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A 32 bit absolute relocation. */
+ HOWTO (R_XSTORMY16_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 */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_XSTORMY16_32", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A 16 bit absolute relocation. */
+ HOWTO (R_XSTORMY16_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_XSTORMY16_16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* An 8 bit absolute relocation. */
+ HOWTO (R_XSTORMY16_8, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 8, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_unsigned, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_XSTORMY16_8", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A 32 bit pc-relative relocation. */
+ HOWTO (R_XSTORMY16_PC32, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_XSTORMY16_PC32", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* A 16 bit pc-relative relocation. */
+ HOWTO (R_XSTORMY16_PC16, /* 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_XSTORMY16_PC16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* An 8 bit pc-relative relocation. */
+ HOWTO (R_XSTORMY16_PC8, /* type */
+ 0, /* rightshift */
+ 0, /* 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_XSTORMY16_PC8", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* A 12-bit pc-relative relocation suitable for the branch instructions. */
+ HOWTO (R_XSTORMY16_REL_12, /* type */
+ 1, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 11, /* bitsize */
+ TRUE, /* pc_relative */
+ 1, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_XSTORMY16_REL_12", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0ffe, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* A 24-bit absolute relocation suitable for the jump instructions. */
+ HOWTO (R_XSTORMY16_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 */
+ xstormy16_elf_24_reloc, /* special_function */
+ "R_XSTORMY16_24", /* name */
+ TRUE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff00ff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* A 16 bit absolute relocation to a function pointer. */
+ HOWTO (R_XSTORMY16_FPTR16, /* 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_XSTORMY16_FPTR16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Low order 16 bit value of a high memory address. */
+ HOWTO (R_XSTORMY16_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 */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_XSTORMY16_LO16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* High order 16 bit value of a high memory address. */
+ HOWTO (R_XSTORMY16_HI16, /* 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_XSTORMY16_HI16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A 12 bit absolute relocation. */
+ HOWTO (R_XSTORMY16_12, /* type */
+ 0, /* rightshift */
+ 1, /* 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_XSTORMY16_12", /* name */
+ FALSE, /* partial_inplace */
+ 0x0000, /* src_mask */
+ 0x0fff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+};
+
+static reloc_howto_type xstormy16_elf_howto_table2 [] =
+{
+ /* GNU extension to record C++ vtable hierarchy */
+ HOWTO (R_XSTORMY16_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_XSTORMY16_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_XSTORMY16_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_XSTORMY16_GNU_VTENTRY", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+};
+
+/* Map BFD reloc types to XSTORMY16 ELF reloc types. */
+
+typedef struct xstormy16_reloc_map
+{
+ bfd_reloc_code_real_type bfd_reloc_val;
+ unsigned int xstormy16_reloc_val;
+ reloc_howto_type * table;
+} reloc_map;
+
+static const reloc_map xstormy16_reloc_map [] =
+{
+ { BFD_RELOC_NONE, R_XSTORMY16_NONE, xstormy16_elf_howto_table },
+ { BFD_RELOC_32, R_XSTORMY16_32, xstormy16_elf_howto_table },
+ { BFD_RELOC_16, R_XSTORMY16_16, xstormy16_elf_howto_table },
+ { BFD_RELOC_8, R_XSTORMY16_8, xstormy16_elf_howto_table },
+ { BFD_RELOC_32_PCREL, R_XSTORMY16_PC32, xstormy16_elf_howto_table },
+ { BFD_RELOC_16_PCREL, R_XSTORMY16_PC16, xstormy16_elf_howto_table },
+ { BFD_RELOC_8_PCREL, R_XSTORMY16_PC8, xstormy16_elf_howto_table },
+ { BFD_RELOC_XSTORMY16_REL_12, R_XSTORMY16_REL_12, xstormy16_elf_howto_table },
+ { BFD_RELOC_XSTORMY16_24, R_XSTORMY16_24, xstormy16_elf_howto_table },
+ { BFD_RELOC_XSTORMY16_FPTR16, R_XSTORMY16_FPTR16, xstormy16_elf_howto_table },
+ { BFD_RELOC_LO16, R_XSTORMY16_LO16, xstormy16_elf_howto_table },
+ { BFD_RELOC_HI16, R_XSTORMY16_HI16, xstormy16_elf_howto_table },
+ { BFD_RELOC_XSTORMY16_12, R_XSTORMY16_12, xstormy16_elf_howto_table },
+ { BFD_RELOC_VTABLE_INHERIT, R_XSTORMY16_GNU_VTINHERIT, xstormy16_elf_howto_table2 },
+ { BFD_RELOC_VTABLE_ENTRY, R_XSTORMY16_GNU_VTENTRY, xstormy16_elf_howto_table2 },
+};
+
+static reloc_howto_type *
+xstormy16_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED,
+ bfd_reloc_code_real_type code)
+{
+ unsigned int i;
+
+ for (i = ARRAY_SIZE (xstormy16_reloc_map); --i;)
+ {
+ const reloc_map * entry;
+
+ entry = xstormy16_reloc_map + i;
+
+ if (entry->bfd_reloc_val == code)
+ return entry->table + (entry->xstormy16_reloc_val
+ - entry->table[0].type);
+ }
+
+ return NULL;
+}
+
+static reloc_howto_type *
+xstormy16_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ const char *r_name)
+{
+ unsigned int i;
+
+ for (i = 0;
+ i < (sizeof (xstormy16_elf_howto_table)
+ / sizeof (xstormy16_elf_howto_table[0]));
+ i++)
+ if (xstormy16_elf_howto_table[i].name != NULL
+ && strcasecmp (xstormy16_elf_howto_table[i].name, r_name) == 0)
+ return &xstormy16_elf_howto_table[i];
+
+ for (i = 0;
+ i < (sizeof (xstormy16_elf_howto_table2)
+ / sizeof (xstormy16_elf_howto_table2[0]));
+ i++)
+ if (xstormy16_elf_howto_table2[i].name != NULL
+ && strcasecmp (xstormy16_elf_howto_table2[i].name, r_name) == 0)
+ return &xstormy16_elf_howto_table2[i];
+
+ return NULL;
+}
+
+/* Set the howto pointer for an XSTORMY16 ELF reloc. */
+
+static void
+xstormy16_info_to_howto_rela (bfd * abfd ATTRIBUTE_UNUSED,
+ arelent * cache_ptr,
+ Elf_Internal_Rela * dst)
+{
+ unsigned int r_type = ELF32_R_TYPE (dst->r_info);
+
+ if (r_type <= (unsigned int) R_XSTORMY16_12)
+ cache_ptr->howto = &xstormy16_elf_howto_table [r_type];
+ else if (r_type - R_XSTORMY16_GNU_VTINHERIT
+ <= (unsigned int) R_XSTORMY16_GNU_VTENTRY)
+ cache_ptr->howto
+ = &xstormy16_elf_howto_table2 [r_type - R_XSTORMY16_GNU_VTINHERIT];
+ else
+ abort ();
+}
+
+/* We support 16-bit pointers to code above 64k by generating a thunk
+ below 64k containing a JMPF instruction to the final address. We
+ cannot, unfortunately, minimize the number of thunks unless the
+ -relax switch is given, as otherwise we have no idea where the
+ sections will fall in the address space. */
+
+static bfd_boolean
+xstormy16_elf_check_relocs (bfd *abfd,
+ struct bfd_link_info *info,
+ asection *sec,
+ const Elf_Internal_Rela *relocs)
+{
+ const Elf_Internal_Rela *rel, *relend;
+ struct elf_link_hash_entry **sym_hashes;
+ Elf_Internal_Shdr *symtab_hdr;
+ bfd_vma *local_plt_offsets;
+ asection *splt;
+ bfd *dynobj;
+
+ if (info->relocatable)
+ return TRUE;
+
+ symtab_hdr = &elf_tdata(abfd)->symtab_hdr;
+ sym_hashes = elf_sym_hashes (abfd);
+ local_plt_offsets = elf_local_got_offsets (abfd);
+ splt = NULL;
+ dynobj = elf_hash_table(info)->dynobj;
+
+ relend = relocs + sec->reloc_count;
+ for (rel = relocs; rel < relend; ++rel)
+ {
+ unsigned long r_symndx;
+ struct elf_link_hash_entry *h;
+ bfd_vma *offset;
+
+ 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];
+ 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;
+
+ /* PR15323, ref flags aren't set for references in the same
+ object. */
+ h->root.non_ir_ref = 1;
+ }
+
+ switch (ELF32_R_TYPE (rel->r_info))
+ {
+ /* This relocation describes a 16-bit pointer to a function.
+ We may need to allocate a thunk in low memory; reserve memory
+ for it now. */
+ case R_XSTORMY16_FPTR16:
+ if (rel->r_addend != 0)
+ {
+ (*info->callbacks->warning)
+ (info, _("non-zero addend in @fptr reloc"), 0,
+ abfd, 0, 0);
+ }
+
+ if (dynobj == NULL)
+ elf_hash_table (info)->dynobj = dynobj = abfd;
+ if (splt == NULL)
+ {
+ splt = bfd_get_linker_section (dynobj, ".plt");
+ if (splt == NULL)
+ {
+ flagword flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS
+ | SEC_IN_MEMORY | SEC_LINKER_CREATED
+ | SEC_READONLY | SEC_CODE);
+
+ splt = bfd_make_section_anyway_with_flags (dynobj, ".plt",
+ flags);
+ if (splt == NULL
+ || ! bfd_set_section_alignment (dynobj, splt, 1))
+ return FALSE;
+ }
+ }
+
+ if (h != NULL)
+ offset = &h->plt.offset;
+ else
+ {
+ if (local_plt_offsets == NULL)
+ {
+ size_t size;
+ unsigned int i;
+
+ size = symtab_hdr->sh_info * sizeof (bfd_vma);
+ local_plt_offsets = bfd_alloc (abfd, size);
+ if (local_plt_offsets == NULL)
+ return FALSE;
+ elf_local_got_offsets (abfd) = local_plt_offsets;
+
+ for (i = 0; i < symtab_hdr->sh_info; i++)
+ local_plt_offsets[i] = (bfd_vma) -1;
+ }
+ offset = &local_plt_offsets[r_symndx];
+ }
+
+ if (*offset == (bfd_vma) -1)
+ {
+ *offset = splt->size;
+ splt->size += 4;
+ }
+ break;
+
+ /* This relocation describes the C++ object vtable hierarchy.
+ Reconstruct it for later use during GC. */
+ case R_XSTORMY16_GNU_VTINHERIT:
+ if (!bfd_elf_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_XSTORMY16_GNU_VTENTRY:
+ BFD_ASSERT (h != NULL);
+ if (h != NULL
+ && !bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
+ return FALSE;
+ break;
+ }
+ }
+
+ return TRUE;
+}
+
+/* A subroutine of xstormy16_elf_relax_section. If the global symbol H
+ is within the low 64k, remove any entry for it in the plt. */
+
+struct relax_plt_data
+{
+ asection *splt;
+ bfd_boolean *again;
+};
+
+static bfd_boolean
+xstormy16_relax_plt_check (struct elf_link_hash_entry *h, void * xdata)
+{
+ struct relax_plt_data *data = (struct relax_plt_data *) xdata;
+
+ if (h->plt.offset != (bfd_vma) -1)
+ {
+ bfd_vma address;
+
+ if (h->root.type == bfd_link_hash_undefined
+ || h->root.type == bfd_link_hash_undefweak)
+ address = 0;
+ else
+ address = (h->root.u.def.section->output_section->vma
+ + h->root.u.def.section->output_offset
+ + h->root.u.def.value);
+
+ if (address <= 0xffff)
+ {
+ h->plt.offset = -1;
+ data->splt->size -= 4;
+ *data->again = TRUE;
+ }
+ }
+
+ return TRUE;
+}
+
+/* A subroutine of xstormy16_elf_relax_section. If the global symbol H
+ previously had a plt entry, give it a new entry offset. */
+
+static bfd_boolean
+xstormy16_relax_plt_realloc (struct elf_link_hash_entry *h, void * xdata)
+{
+ bfd_vma *entry = (bfd_vma *) xdata;
+
+ if (h->plt.offset != (bfd_vma) -1)
+ {
+ h->plt.offset = *entry;
+ *entry += 4;
+ }
+
+ return TRUE;
+}
+
+static bfd_boolean
+xstormy16_elf_relax_section (bfd *dynobj,
+ asection *splt,
+ struct bfd_link_info *info,
+ bfd_boolean *again)
+{
+ struct relax_plt_data relax_plt_data;
+ bfd *ibfd;
+
+ /* Assume nothing changes. */
+ *again = FALSE;
+
+ if (info->relocatable)
+ return TRUE;
+
+ /* We only relax the .plt section at the moment. */
+ if (dynobj != elf_hash_table (info)->dynobj
+ || strcmp (splt->name, ".plt") != 0)
+ return TRUE;
+
+ /* Quick check for an empty plt. */
+ if (splt->size == 0)
+ return TRUE;
+
+ /* Map across all global symbols; see which ones happen to
+ fall in the low 64k. */
+ relax_plt_data.splt = splt;
+ relax_plt_data.again = again;
+ elf_link_hash_traverse (elf_hash_table (info), xstormy16_relax_plt_check,
+ &relax_plt_data);
+
+ /* Likewise for local symbols, though that's somewhat less convenient
+ as we have to walk the list of input bfds and swap in symbol data. */
+ for (ibfd = info->input_bfds; ibfd ; ibfd = ibfd->link.next)
+ {
+ bfd_vma *local_plt_offsets = elf_local_got_offsets (ibfd);
+ Elf_Internal_Shdr *symtab_hdr;
+ Elf_Internal_Sym *isymbuf = NULL;
+ unsigned int idx;
+
+ if (! local_plt_offsets)
+ continue;
+
+ symtab_hdr = &elf_tdata (ibfd)->symtab_hdr;
+ if (symtab_hdr->sh_info != 0)
+ {
+ isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
+ if (isymbuf == NULL)
+ isymbuf = bfd_elf_get_elf_syms (ibfd, symtab_hdr,
+ symtab_hdr->sh_info, 0,
+ NULL, NULL, NULL);
+ if (isymbuf == NULL)
+ return FALSE;
+ }
+
+ for (idx = 0; idx < symtab_hdr->sh_info; ++idx)
+ {
+ Elf_Internal_Sym *isym;
+ asection *tsec;
+ bfd_vma address;
+
+ if (local_plt_offsets[idx] == (bfd_vma) -1)
+ continue;
+
+ isym = &isymbuf[idx];
+ if (isym->st_shndx == SHN_UNDEF)
+ continue;
+ else if (isym->st_shndx == SHN_ABS)
+ tsec = bfd_abs_section_ptr;
+ else if (isym->st_shndx == SHN_COMMON)
+ tsec = bfd_com_section_ptr;
+ else
+ tsec = bfd_section_from_elf_index (ibfd, isym->st_shndx);
+
+ address = (tsec->output_section->vma
+ + tsec->output_offset
+ + isym->st_value);
+ if (address <= 0xffff)
+ {
+ local_plt_offsets[idx] = -1;
+ splt->size -= 4;
+ *again = TRUE;
+ }
+ }
+
+ if (isymbuf != NULL
+ && symtab_hdr->contents != (unsigned char *) isymbuf)
+ {
+ if (! info->keep_memory)
+ free (isymbuf);
+ else
+ {
+ /* Cache the symbols for elf_link_input_bfd. */
+ symtab_hdr->contents = (unsigned char *) isymbuf;
+ }
+ }
+ }
+
+ /* If we changed anything, walk the symbols again to reallocate
+ .plt entry addresses. */
+ if (*again && splt->size > 0)
+ {
+ bfd_vma entry = 0;
+
+ elf_link_hash_traverse (elf_hash_table (info),
+ xstormy16_relax_plt_realloc, &entry);
+
+ for (ibfd = info->input_bfds; ibfd ; ibfd = ibfd->link.next)
+ {
+ bfd_vma *local_plt_offsets = elf_local_got_offsets (ibfd);
+ unsigned int nlocals = elf_tdata (ibfd)->symtab_hdr.sh_info;
+ unsigned int idx;
+
+ if (! local_plt_offsets)
+ continue;
+
+ for (idx = 0; idx < nlocals; ++idx)
+ if (local_plt_offsets[idx] != (bfd_vma) -1)
+ {
+ local_plt_offsets[idx] = entry;
+ entry += 4;
+ }
+ }
+ }
+
+ return TRUE;
+}
+
+static bfd_boolean
+xstormy16_elf_always_size_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
+ struct bfd_link_info *info)
+{
+ bfd *dynobj;
+ asection *splt;
+
+ if (info->relocatable)
+ return TRUE;
+
+ dynobj = elf_hash_table (info)->dynobj;
+ if (dynobj == NULL)
+ return TRUE;
+
+ splt = bfd_get_linker_section (dynobj, ".plt");
+ BFD_ASSERT (splt != NULL);
+
+ splt->contents = bfd_zalloc (dynobj, splt->size);
+ if (splt->contents == NULL)
+ return FALSE;
+
+ return TRUE;
+}
+
+/* Relocate an XSTORMY16 ELF section.
+
+ 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 relocatable
+ 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 relocatable 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 bfd_boolean
+xstormy16_elf_relocate_section (bfd * output_bfd ATTRIBUTE_UNUSED,
+ 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;
+ bfd *dynobj;
+ asection *splt;
+
+ symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
+ sym_hashes = elf_sym_hashes (input_bfd);
+ relend = relocs + input_section->reloc_count;
+
+ dynobj = elf_hash_table (info)->dynobj;
+ splt = NULL;
+ if (dynobj != NULL)
+ splt = bfd_get_linker_section (dynobj, ".plt");
+
+ 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_XSTORMY16_GNU_VTINHERIT
+ || r_type == R_XSTORMY16_GNU_VTENTRY)
+ continue;
+
+ r_symndx = ELF32_R_SYM (rel->r_info);
+ howto = xstormy16_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 = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
+ }
+ else
+ {
+ bfd_boolean unresolved_reloc, warned, ignored;
+
+ RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
+ r_symndx, symtab_hdr, sym_hashes,
+ h, sec, relocation,
+ unresolved_reloc, warned, ignored);
+ }
+
+ if (sec != NULL && discarded_section (sec))
+ RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+ rel, 1, relend, howto, 0, contents);
+
+ if (info->relocatable)
+ continue;
+
+ 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 (ELF32_R_TYPE (rel->r_info))
+ {
+ case R_XSTORMY16_24:
+ {
+ bfd_vma reloc = relocation + rel->r_addend;
+ unsigned int x;
+
+ x = bfd_get_32 (input_bfd, contents + rel->r_offset);
+ x &= 0x0000ff00;
+ x |= reloc & 0xff;
+ x |= (reloc << 8) & 0xffff0000;
+ bfd_put_32 (input_bfd, x, contents + rel->r_offset);
+
+ if (reloc & ~0xffffff)
+ r = bfd_reloc_overflow;
+ else
+ r = bfd_reloc_ok;
+ break;
+ }
+
+ case R_XSTORMY16_FPTR16:
+ {
+ bfd_vma *plt_offset;
+
+ if (h != NULL)
+ plt_offset = &h->plt.offset;
+ else
+ plt_offset = elf_local_got_offsets (input_bfd) + r_symndx;
+
+ if (relocation <= 0xffff)
+ {
+ /* If the symbol is in range for a 16-bit address, we should
+ have deallocated the plt entry in relax_section. */
+ BFD_ASSERT (*plt_offset == (bfd_vma) -1);
+ }
+ else
+ {
+ /* If the symbol is out of range for a 16-bit address,
+ we must have allocated a plt entry. */
+ BFD_ASSERT (*plt_offset != (bfd_vma) -1);
+
+ /* If this is the first time we've processed this symbol,
+ fill in the plt entry with the correct symbol address. */
+ if ((*plt_offset & 1) == 0)
+ {
+ unsigned int x;
+
+ x = 0x00000200; /* jmpf */
+ x |= relocation & 0xff;
+ x |= (relocation << 8) & 0xffff0000;
+ bfd_put_32 (input_bfd, x, splt->contents + *plt_offset);
+ *plt_offset |= 1;
+ }
+
+ relocation = (splt->output_section->vma
+ + splt->output_offset
+ + (*plt_offset & -2));
+ }
+ r = _bfd_final_link_relocate (howto, input_bfd, input_section,
+ contents, rel->r_offset,
+ relocation, 0);
+ break;
+ }
+
+ default:
+ r = _bfd_final_link_relocate (howto, input_bfd, input_section,
+ contents, rel->r_offset,
+ relocation, rel->r_addend);
+ break;
+ }
+
+ if (r != bfd_reloc_ok)
+ {
+ const char * msg = NULL;
+
+ switch (r)
+ {
+ case bfd_reloc_overflow:
+ r = info->callbacks->reloc_overflow
+ (info, (h ? &h->root : NULL), 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,
+ TRUE);
+ 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;
+}
+
+/* This must exist if dynobj is ever set. */
+
+static bfd_boolean
+xstormy16_elf_finish_dynamic_sections (bfd *abfd ATTRIBUTE_UNUSED,
+ struct bfd_link_info *info)
+{
+ bfd *dynobj;
+ asection *splt;
+
+ /* As an extra sanity check, verify that all plt entries have
+ been filled in. */
+
+ if ((dynobj = elf_hash_table (info)->dynobj) != NULL
+ && (splt = bfd_get_linker_section (dynobj, ".plt")) != NULL)
+ {
+ bfd_byte *contents = splt->contents;
+ unsigned int i, size = splt->size;
+
+ for (i = 0; i < size; i += 4)
+ {
+ unsigned int x = bfd_get_32 (dynobj, contents + i);
+
+ BFD_ASSERT (x != 0);
+ }
+ }
+
+ return TRUE;
+}
+
+/* Return the section that should be marked against GC for a given
+ relocation. */
+
+static asection *
+xstormy16_elf_gc_mark_hook (asection *sec,
+ 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_XSTORMY16_GNU_VTINHERIT:
+ case R_XSTORMY16_GNU_VTENTRY:
+ return NULL;
+ }
+
+ return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
+}
+
+#define ELF_ARCH bfd_arch_xstormy16
+#define ELF_MACHINE_CODE EM_XSTORMY16
+#define ELF_MAXPAGESIZE 0x100
+
+#define TARGET_LITTLE_SYM xstormy16_elf32_vec
+#define TARGET_LITTLE_NAME "elf32-xstormy16"
+
+#define elf_info_to_howto_rel NULL
+#define elf_info_to_howto xstormy16_info_to_howto_rela
+#define elf_backend_relocate_section xstormy16_elf_relocate_section
+#define elf_backend_gc_mark_hook xstormy16_elf_gc_mark_hook
+#define elf_backend_check_relocs xstormy16_elf_check_relocs
+#define elf_backend_always_size_sections \
+ xstormy16_elf_always_size_sections
+#define elf_backend_omit_section_dynsym \
+ ((bfd_boolean (*) (bfd *, struct bfd_link_info *, asection *)) bfd_true)
+#define elf_backend_finish_dynamic_sections \
+ xstormy16_elf_finish_dynamic_sections
+
+#define elf_backend_can_gc_sections 1
+#define elf_backend_rela_normal 1
+
+#define bfd_elf32_bfd_reloc_type_lookup xstormy16_reloc_type_lookup
+#define bfd_elf32_bfd_reloc_name_lookup \
+ xstormy16_reloc_name_lookup
+#define bfd_elf32_bfd_relax_section xstormy16_elf_relax_section
+
+#include "elf32-target.h"
diff --git a/bfd/elf32-xtensa.c b/bfd/elf32-xtensa.c
new file mode 100644
index 0000000..e32496a
--- /dev/null
+++ b/bfd/elf32-xtensa.c
@@ -0,0 +1,10857 @@
+/* Xtensa-specific support for 32-bit ELF.
+ Copyright (C) 2003-2014 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 3 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
+ 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+
+#include <stdarg.h>
+#include <strings.h>
+
+#include "bfdlink.h"
+#include "libbfd.h"
+#include "elf-bfd.h"
+#include "elf/xtensa.h"
+#include "xtensa-isa.h"
+#include "xtensa-config.h"
+
+#define XTENSA_NO_NOP_REMOVAL 0
+
+/* Local helper functions. */
+
+static bfd_boolean add_extra_plt_sections (struct bfd_link_info *, int);
+static char *vsprint_msg (const char *, const char *, int, ...) ATTRIBUTE_PRINTF(2,4);
+static bfd_reloc_status_type bfd_elf_xtensa_reloc
+ (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
+static bfd_boolean do_fix_for_relocatable_link
+ (Elf_Internal_Rela *, bfd *, asection *, bfd_byte *);
+static void do_fix_for_final_link
+ (Elf_Internal_Rela *, bfd *, asection *, bfd_byte *, bfd_vma *);
+
+/* Local functions to handle Xtensa configurability. */
+
+static bfd_boolean is_indirect_call_opcode (xtensa_opcode);
+static bfd_boolean is_direct_call_opcode (xtensa_opcode);
+static bfd_boolean is_windowed_call_opcode (xtensa_opcode);
+static xtensa_opcode get_const16_opcode (void);
+static xtensa_opcode get_l32r_opcode (void);
+static bfd_vma l32r_offset (bfd_vma, bfd_vma);
+static int get_relocation_opnd (xtensa_opcode, int);
+static int get_relocation_slot (int);
+static xtensa_opcode get_relocation_opcode
+ (bfd *, asection *, bfd_byte *, Elf_Internal_Rela *);
+static bfd_boolean is_l32r_relocation
+ (bfd *, asection *, bfd_byte *, Elf_Internal_Rela *);
+static bfd_boolean is_alt_relocation (int);
+static bfd_boolean is_operand_relocation (int);
+static bfd_size_type insn_decode_len
+ (bfd_byte *, bfd_size_type, bfd_size_type);
+static xtensa_opcode insn_decode_opcode
+ (bfd_byte *, bfd_size_type, bfd_size_type, int);
+static bfd_boolean check_branch_target_aligned
+ (bfd_byte *, bfd_size_type, bfd_vma, bfd_vma);
+static bfd_boolean check_loop_aligned
+ (bfd_byte *, bfd_size_type, bfd_vma, bfd_vma);
+static bfd_boolean check_branch_target_aligned_address (bfd_vma, int);
+static bfd_size_type get_asm_simplify_size
+ (bfd_byte *, bfd_size_type, bfd_size_type);
+
+/* Functions for link-time code simplifications. */
+
+static bfd_reloc_status_type elf_xtensa_do_asm_simplify
+ (bfd_byte *, bfd_vma, bfd_vma, char **);
+static bfd_reloc_status_type contract_asm_expansion
+ (bfd_byte *, bfd_vma, Elf_Internal_Rela *, char **);
+static xtensa_opcode swap_callx_for_call_opcode (xtensa_opcode);
+static xtensa_opcode get_expanded_call_opcode (bfd_byte *, int, bfd_boolean *);
+
+/* Access to internal relocations, section contents and symbols. */
+
+static Elf_Internal_Rela *retrieve_internal_relocs
+ (bfd *, asection *, bfd_boolean);
+static void pin_internal_relocs (asection *, Elf_Internal_Rela *);
+static void release_internal_relocs (asection *, Elf_Internal_Rela *);
+static bfd_byte *retrieve_contents (bfd *, asection *, bfd_boolean);
+static void pin_contents (asection *, bfd_byte *);
+static void release_contents (asection *, bfd_byte *);
+static Elf_Internal_Sym *retrieve_local_syms (bfd *);
+
+/* Miscellaneous utility functions. */
+
+static asection *elf_xtensa_get_plt_section (struct bfd_link_info *, int);
+static asection *elf_xtensa_get_gotplt_section (struct bfd_link_info *, int);
+static asection *get_elf_r_symndx_section (bfd *, unsigned long);
+static struct elf_link_hash_entry *get_elf_r_symndx_hash_entry
+ (bfd *, unsigned long);
+static bfd_vma get_elf_r_symndx_offset (bfd *, unsigned long);
+static bfd_boolean is_reloc_sym_weak (bfd *, Elf_Internal_Rela *);
+static bfd_boolean pcrel_reloc_fits (xtensa_opcode, int, bfd_vma, bfd_vma);
+static bfd_boolean xtensa_is_property_section (asection *);
+static bfd_boolean xtensa_is_insntable_section (asection *);
+static bfd_boolean xtensa_is_littable_section (asection *);
+static bfd_boolean xtensa_is_proptable_section (asection *);
+static int internal_reloc_compare (const void *, const void *);
+static int internal_reloc_matches (const void *, const void *);
+static asection *xtensa_get_property_section (asection *, const char *);
+extern asection *xtensa_make_property_section (asection *, const char *);
+static flagword xtensa_get_property_predef_flags (asection *);
+
+/* Other functions called directly by the linker. */
+
+typedef void (*deps_callback_t)
+ (asection *, bfd_vma, asection *, bfd_vma, void *);
+extern bfd_boolean xtensa_callback_required_dependence
+ (bfd *, asection *, struct bfd_link_info *, deps_callback_t, void *);
+
+
+/* Globally visible flag for choosing size optimization of NOP removal
+ instead of branch-target-aware minimization for NOP removal.
+ When nonzero, narrow all instructions and remove all NOPs possible
+ around longcall expansions. */
+
+int elf32xtensa_size_opt;
+
+
+/* The "new_section_hook" is used to set up a per-section
+ "xtensa_relax_info" data structure with additional information used
+ during relaxation. */
+
+typedef struct xtensa_relax_info_struct xtensa_relax_info;
+
+
+/* The GNU tools do not easily allow extending interfaces to pass around
+ the pointer to the Xtensa ISA information, so instead we add a global
+ variable here (in BFD) that can be used by any of the tools that need
+ this information. */
+
+xtensa_isa xtensa_default_isa;
+
+
+/* When this is true, relocations may have been modified to refer to
+ symbols from other input files. The per-section list of "fix"
+ records needs to be checked when resolving relocations. */
+
+static bfd_boolean relaxing_section = FALSE;
+
+/* When this is true, during final links, literals that cannot be
+ coalesced and their relocations may be moved to other sections. */
+
+int elf32xtensa_no_literal_movement = 1;
+
+/* Rename one of the generic section flags to better document how it
+ is used here. */
+/* Whether relocations have been processed. */
+#define reloc_done sec_flg0
+
+static reloc_howto_type elf_howto_table[] =
+{
+ HOWTO (R_XTENSA_NONE, 0, 0, 0, FALSE, 0, complain_overflow_dont,
+ bfd_elf_xtensa_reloc, "R_XTENSA_NONE",
+ FALSE, 0, 0, FALSE),
+ HOWTO (R_XTENSA_32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_xtensa_reloc, "R_XTENSA_32",
+ TRUE, 0xffffffff, 0xffffffff, FALSE),
+
+ /* Replace a 32-bit value with a value from the runtime linker (only
+ used by linker-generated stub functions). The r_addend value is
+ special: 1 means to substitute a pointer to the runtime linker's
+ dynamic resolver function; 2 means to substitute the link map for
+ the shared object. */
+ HOWTO (R_XTENSA_RTLD, 0, 2, 32, FALSE, 0, complain_overflow_dont,
+ NULL, "R_XTENSA_RTLD", FALSE, 0, 0, FALSE),
+
+ HOWTO (R_XTENSA_GLOB_DAT, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_XTENSA_GLOB_DAT",
+ FALSE, 0, 0xffffffff, FALSE),
+ HOWTO (R_XTENSA_JMP_SLOT, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_XTENSA_JMP_SLOT",
+ FALSE, 0, 0xffffffff, FALSE),
+ HOWTO (R_XTENSA_RELATIVE, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_XTENSA_RELATIVE",
+ FALSE, 0, 0xffffffff, FALSE),
+ HOWTO (R_XTENSA_PLT, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_xtensa_reloc, "R_XTENSA_PLT",
+ FALSE, 0, 0xffffffff, FALSE),
+
+ EMPTY_HOWTO (7),
+
+ /* Old relocations for backward compatibility. */
+ HOWTO (R_XTENSA_OP0, 0, 0, 0, TRUE, 0, complain_overflow_dont,
+ bfd_elf_xtensa_reloc, "R_XTENSA_OP0", FALSE, 0, 0, TRUE),
+ HOWTO (R_XTENSA_OP1, 0, 0, 0, TRUE, 0, complain_overflow_dont,
+ bfd_elf_xtensa_reloc, "R_XTENSA_OP1", FALSE, 0, 0, TRUE),
+ HOWTO (R_XTENSA_OP2, 0, 0, 0, TRUE, 0, complain_overflow_dont,
+ bfd_elf_xtensa_reloc, "R_XTENSA_OP2", FALSE, 0, 0, TRUE),
+
+ /* Assembly auto-expansion. */
+ HOWTO (R_XTENSA_ASM_EXPAND, 0, 0, 0, TRUE, 0, complain_overflow_dont,
+ bfd_elf_xtensa_reloc, "R_XTENSA_ASM_EXPAND", FALSE, 0, 0, TRUE),
+ /* Relax assembly auto-expansion. */
+ HOWTO (R_XTENSA_ASM_SIMPLIFY, 0, 0, 0, TRUE, 0, complain_overflow_dont,
+ bfd_elf_xtensa_reloc, "R_XTENSA_ASM_SIMPLIFY", FALSE, 0, 0, TRUE),
+
+ EMPTY_HOWTO (13),
+
+ HOWTO (R_XTENSA_32_PCREL, 0, 2, 32, TRUE, 0, complain_overflow_bitfield,
+ bfd_elf_xtensa_reloc, "R_XTENSA_32_PCREL",
+ FALSE, 0, 0xffffffff, TRUE),
+
+ /* GNU extension to record C++ vtable hierarchy. */
+ HOWTO (R_XTENSA_GNU_VTINHERIT, 0, 2, 0, FALSE, 0, complain_overflow_dont,
+ NULL, "R_XTENSA_GNU_VTINHERIT",
+ FALSE, 0, 0, FALSE),
+ /* GNU extension to record C++ vtable member usage. */
+ HOWTO (R_XTENSA_GNU_VTENTRY, 0, 2, 0, FALSE, 0, complain_overflow_dont,
+ _bfd_elf_rel_vtable_reloc_fn, "R_XTENSA_GNU_VTENTRY",
+ FALSE, 0, 0, FALSE),
+
+ /* Relocations for supporting difference of symbols. */
+ HOWTO (R_XTENSA_DIFF8, 0, 0, 8, FALSE, 0, complain_overflow_signed,
+ bfd_elf_xtensa_reloc, "R_XTENSA_DIFF8", FALSE, 0, 0xff, FALSE),
+ HOWTO (R_XTENSA_DIFF16, 0, 1, 16, FALSE, 0, complain_overflow_signed,
+ bfd_elf_xtensa_reloc, "R_XTENSA_DIFF16", FALSE, 0, 0xffff, FALSE),
+ HOWTO (R_XTENSA_DIFF32, 0, 2, 32, FALSE, 0, complain_overflow_signed,
+ bfd_elf_xtensa_reloc, "R_XTENSA_DIFF32", FALSE, 0, 0xffffffff, FALSE),
+
+ /* General immediate operand relocations. */
+ HOWTO (R_XTENSA_SLOT0_OP, 0, 0, 0, TRUE, 0, complain_overflow_dont,
+ bfd_elf_xtensa_reloc, "R_XTENSA_SLOT0_OP", FALSE, 0, 0, TRUE),
+ HOWTO (R_XTENSA_SLOT1_OP, 0, 0, 0, TRUE, 0, complain_overflow_dont,
+ bfd_elf_xtensa_reloc, "R_XTENSA_SLOT1_OP", FALSE, 0, 0, TRUE),
+ HOWTO (R_XTENSA_SLOT2_OP, 0, 0, 0, TRUE, 0, complain_overflow_dont,
+ bfd_elf_xtensa_reloc, "R_XTENSA_SLOT2_OP", FALSE, 0, 0, TRUE),
+ HOWTO (R_XTENSA_SLOT3_OP, 0, 0, 0, TRUE, 0, complain_overflow_dont,
+ bfd_elf_xtensa_reloc, "R_XTENSA_SLOT3_OP", FALSE, 0, 0, TRUE),
+ HOWTO (R_XTENSA_SLOT4_OP, 0, 0, 0, TRUE, 0, complain_overflow_dont,
+ bfd_elf_xtensa_reloc, "R_XTENSA_SLOT4_OP", FALSE, 0, 0, TRUE),
+ HOWTO (R_XTENSA_SLOT5_OP, 0, 0, 0, TRUE, 0, complain_overflow_dont,
+ bfd_elf_xtensa_reloc, "R_XTENSA_SLOT5_OP", FALSE, 0, 0, TRUE),
+ HOWTO (R_XTENSA_SLOT6_OP, 0, 0, 0, TRUE, 0, complain_overflow_dont,
+ bfd_elf_xtensa_reloc, "R_XTENSA_SLOT6_OP", FALSE, 0, 0, TRUE),
+ HOWTO (R_XTENSA_SLOT7_OP, 0, 0, 0, TRUE, 0, complain_overflow_dont,
+ bfd_elf_xtensa_reloc, "R_XTENSA_SLOT7_OP", FALSE, 0, 0, TRUE),
+ HOWTO (R_XTENSA_SLOT8_OP, 0, 0, 0, TRUE, 0, complain_overflow_dont,
+ bfd_elf_xtensa_reloc, "R_XTENSA_SLOT8_OP", FALSE, 0, 0, TRUE),
+ HOWTO (R_XTENSA_SLOT9_OP, 0, 0, 0, TRUE, 0, complain_overflow_dont,
+ bfd_elf_xtensa_reloc, "R_XTENSA_SLOT9_OP", FALSE, 0, 0, TRUE),
+ HOWTO (R_XTENSA_SLOT10_OP, 0, 0, 0, TRUE, 0, complain_overflow_dont,
+ bfd_elf_xtensa_reloc, "R_XTENSA_SLOT10_OP", FALSE, 0, 0, TRUE),
+ HOWTO (R_XTENSA_SLOT11_OP, 0, 0, 0, TRUE, 0, complain_overflow_dont,
+ bfd_elf_xtensa_reloc, "R_XTENSA_SLOT11_OP", FALSE, 0, 0, TRUE),
+ HOWTO (R_XTENSA_SLOT12_OP, 0, 0, 0, TRUE, 0, complain_overflow_dont,
+ bfd_elf_xtensa_reloc, "R_XTENSA_SLOT12_OP", FALSE, 0, 0, TRUE),
+ HOWTO (R_XTENSA_SLOT13_OP, 0, 0, 0, TRUE, 0, complain_overflow_dont,
+ bfd_elf_xtensa_reloc, "R_XTENSA_SLOT13_OP", FALSE, 0, 0, TRUE),
+ HOWTO (R_XTENSA_SLOT14_OP, 0, 0, 0, TRUE, 0, complain_overflow_dont,
+ bfd_elf_xtensa_reloc, "R_XTENSA_SLOT14_OP", FALSE, 0, 0, TRUE),
+
+ /* "Alternate" relocations. The meaning of these is opcode-specific. */
+ HOWTO (R_XTENSA_SLOT0_ALT, 0, 0, 0, TRUE, 0, complain_overflow_dont,
+ bfd_elf_xtensa_reloc, "R_XTENSA_SLOT0_ALT", FALSE, 0, 0, TRUE),
+ HOWTO (R_XTENSA_SLOT1_ALT, 0, 0, 0, TRUE, 0, complain_overflow_dont,
+ bfd_elf_xtensa_reloc, "R_XTENSA_SLOT1_ALT", FALSE, 0, 0, TRUE),
+ HOWTO (R_XTENSA_SLOT2_ALT, 0, 0, 0, TRUE, 0, complain_overflow_dont,
+ bfd_elf_xtensa_reloc, "R_XTENSA_SLOT2_ALT", FALSE, 0, 0, TRUE),
+ HOWTO (R_XTENSA_SLOT3_ALT, 0, 0, 0, TRUE, 0, complain_overflow_dont,
+ bfd_elf_xtensa_reloc, "R_XTENSA_SLOT3_ALT", FALSE, 0, 0, TRUE),
+ HOWTO (R_XTENSA_SLOT4_ALT, 0, 0, 0, TRUE, 0, complain_overflow_dont,
+ bfd_elf_xtensa_reloc, "R_XTENSA_SLOT4_ALT", FALSE, 0, 0, TRUE),
+ HOWTO (R_XTENSA_SLOT5_ALT, 0, 0, 0, TRUE, 0, complain_overflow_dont,
+ bfd_elf_xtensa_reloc, "R_XTENSA_SLOT5_ALT", FALSE, 0, 0, TRUE),
+ HOWTO (R_XTENSA_SLOT6_ALT, 0, 0, 0, TRUE, 0, complain_overflow_dont,
+ bfd_elf_xtensa_reloc, "R_XTENSA_SLOT6_ALT", FALSE, 0, 0, TRUE),
+ HOWTO (R_XTENSA_SLOT7_ALT, 0, 0, 0, TRUE, 0, complain_overflow_dont,
+ bfd_elf_xtensa_reloc, "R_XTENSA_SLOT7_ALT", FALSE, 0, 0, TRUE),
+ HOWTO (R_XTENSA_SLOT8_ALT, 0, 0, 0, TRUE, 0, complain_overflow_dont,
+ bfd_elf_xtensa_reloc, "R_XTENSA_SLOT8_ALT", FALSE, 0, 0, TRUE),
+ HOWTO (R_XTENSA_SLOT9_ALT, 0, 0, 0, TRUE, 0, complain_overflow_dont,
+ bfd_elf_xtensa_reloc, "R_XTENSA_SLOT9_ALT", FALSE, 0, 0, TRUE),
+ HOWTO (R_XTENSA_SLOT10_ALT, 0, 0, 0, TRUE, 0, complain_overflow_dont,
+ bfd_elf_xtensa_reloc, "R_XTENSA_SLOT10_ALT", FALSE, 0, 0, TRUE),
+ HOWTO (R_XTENSA_SLOT11_ALT, 0, 0, 0, TRUE, 0, complain_overflow_dont,
+ bfd_elf_xtensa_reloc, "R_XTENSA_SLOT11_ALT", FALSE, 0, 0, TRUE),
+ HOWTO (R_XTENSA_SLOT12_ALT, 0, 0, 0, TRUE, 0, complain_overflow_dont,
+ bfd_elf_xtensa_reloc, "R_XTENSA_SLOT12_ALT", FALSE, 0, 0, TRUE),
+ HOWTO (R_XTENSA_SLOT13_ALT, 0, 0, 0, TRUE, 0, complain_overflow_dont,
+ bfd_elf_xtensa_reloc, "R_XTENSA_SLOT13_ALT", FALSE, 0, 0, TRUE),
+ HOWTO (R_XTENSA_SLOT14_ALT, 0, 0, 0, TRUE, 0, complain_overflow_dont,
+ bfd_elf_xtensa_reloc, "R_XTENSA_SLOT14_ALT", FALSE, 0, 0, TRUE),
+
+ /* TLS relocations. */
+ HOWTO (R_XTENSA_TLSDESC_FN, 0, 2, 32, FALSE, 0, complain_overflow_dont,
+ bfd_elf_xtensa_reloc, "R_XTENSA_TLSDESC_FN",
+ FALSE, 0, 0xffffffff, FALSE),
+ HOWTO (R_XTENSA_TLSDESC_ARG, 0, 2, 32, FALSE, 0, complain_overflow_dont,
+ bfd_elf_xtensa_reloc, "R_XTENSA_TLSDESC_ARG",
+ FALSE, 0, 0xffffffff, FALSE),
+ HOWTO (R_XTENSA_TLS_DTPOFF, 0, 2, 32, FALSE, 0, complain_overflow_dont,
+ bfd_elf_xtensa_reloc, "R_XTENSA_TLS_DTPOFF",
+ FALSE, 0, 0xffffffff, FALSE),
+ HOWTO (R_XTENSA_TLS_TPOFF, 0, 2, 32, FALSE, 0, complain_overflow_dont,
+ bfd_elf_xtensa_reloc, "R_XTENSA_TLS_TPOFF",
+ FALSE, 0, 0xffffffff, FALSE),
+ HOWTO (R_XTENSA_TLS_FUNC, 0, 0, 0, FALSE, 0, complain_overflow_dont,
+ bfd_elf_xtensa_reloc, "R_XTENSA_TLS_FUNC",
+ FALSE, 0, 0, FALSE),
+ HOWTO (R_XTENSA_TLS_ARG, 0, 0, 0, FALSE, 0, complain_overflow_dont,
+ bfd_elf_xtensa_reloc, "R_XTENSA_TLS_ARG",
+ FALSE, 0, 0, FALSE),
+ HOWTO (R_XTENSA_TLS_CALL, 0, 0, 0, FALSE, 0, complain_overflow_dont,
+ bfd_elf_xtensa_reloc, "R_XTENSA_TLS_CALL",
+ FALSE, 0, 0, FALSE),
+};
+
+#if DEBUG_GEN_RELOC
+#define TRACE(str) \
+ fprintf (stderr, "Xtensa bfd reloc lookup %d (%s)\n", code, str)
+#else
+#define TRACE(str)
+#endif
+
+static reloc_howto_type *
+elf_xtensa_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ bfd_reloc_code_real_type code)
+{
+ switch (code)
+ {
+ case BFD_RELOC_NONE:
+ TRACE ("BFD_RELOC_NONE");
+ return &elf_howto_table[(unsigned) R_XTENSA_NONE ];
+
+ case BFD_RELOC_32:
+ TRACE ("BFD_RELOC_32");
+ return &elf_howto_table[(unsigned) R_XTENSA_32 ];
+
+ case BFD_RELOC_32_PCREL:
+ TRACE ("BFD_RELOC_32_PCREL");
+ return &elf_howto_table[(unsigned) R_XTENSA_32_PCREL ];
+
+ case BFD_RELOC_XTENSA_DIFF8:
+ TRACE ("BFD_RELOC_XTENSA_DIFF8");
+ return &elf_howto_table[(unsigned) R_XTENSA_DIFF8 ];
+
+ case BFD_RELOC_XTENSA_DIFF16:
+ TRACE ("BFD_RELOC_XTENSA_DIFF16");
+ return &elf_howto_table[(unsigned) R_XTENSA_DIFF16 ];
+
+ case BFD_RELOC_XTENSA_DIFF32:
+ TRACE ("BFD_RELOC_XTENSA_DIFF32");
+ return &elf_howto_table[(unsigned) R_XTENSA_DIFF32 ];
+
+ case BFD_RELOC_XTENSA_RTLD:
+ TRACE ("BFD_RELOC_XTENSA_RTLD");
+ return &elf_howto_table[(unsigned) R_XTENSA_RTLD ];
+
+ case BFD_RELOC_XTENSA_GLOB_DAT:
+ TRACE ("BFD_RELOC_XTENSA_GLOB_DAT");
+ return &elf_howto_table[(unsigned) R_XTENSA_GLOB_DAT ];
+
+ case BFD_RELOC_XTENSA_JMP_SLOT:
+ TRACE ("BFD_RELOC_XTENSA_JMP_SLOT");
+ return &elf_howto_table[(unsigned) R_XTENSA_JMP_SLOT ];
+
+ case BFD_RELOC_XTENSA_RELATIVE:
+ TRACE ("BFD_RELOC_XTENSA_RELATIVE");
+ return &elf_howto_table[(unsigned) R_XTENSA_RELATIVE ];
+
+ case BFD_RELOC_XTENSA_PLT:
+ TRACE ("BFD_RELOC_XTENSA_PLT");
+ return &elf_howto_table[(unsigned) R_XTENSA_PLT ];
+
+ case BFD_RELOC_XTENSA_OP0:
+ TRACE ("BFD_RELOC_XTENSA_OP0");
+ return &elf_howto_table[(unsigned) R_XTENSA_OP0 ];
+
+ case BFD_RELOC_XTENSA_OP1:
+ TRACE ("BFD_RELOC_XTENSA_OP1");
+ return &elf_howto_table[(unsigned) R_XTENSA_OP1 ];
+
+ case BFD_RELOC_XTENSA_OP2:
+ TRACE ("BFD_RELOC_XTENSA_OP2");
+ return &elf_howto_table[(unsigned) R_XTENSA_OP2 ];
+
+ case BFD_RELOC_XTENSA_ASM_EXPAND:
+ TRACE ("BFD_RELOC_XTENSA_ASM_EXPAND");
+ return &elf_howto_table[(unsigned) R_XTENSA_ASM_EXPAND ];
+
+ case BFD_RELOC_XTENSA_ASM_SIMPLIFY:
+ TRACE ("BFD_RELOC_XTENSA_ASM_SIMPLIFY");
+ return &elf_howto_table[(unsigned) R_XTENSA_ASM_SIMPLIFY ];
+
+ case BFD_RELOC_VTABLE_INHERIT:
+ TRACE ("BFD_RELOC_VTABLE_INHERIT");
+ return &elf_howto_table[(unsigned) R_XTENSA_GNU_VTINHERIT ];
+
+ case BFD_RELOC_VTABLE_ENTRY:
+ TRACE ("BFD_RELOC_VTABLE_ENTRY");
+ return &elf_howto_table[(unsigned) R_XTENSA_GNU_VTENTRY ];
+
+ case BFD_RELOC_XTENSA_TLSDESC_FN:
+ TRACE ("BFD_RELOC_XTENSA_TLSDESC_FN");
+ return &elf_howto_table[(unsigned) R_XTENSA_TLSDESC_FN ];
+
+ case BFD_RELOC_XTENSA_TLSDESC_ARG:
+ TRACE ("BFD_RELOC_XTENSA_TLSDESC_ARG");
+ return &elf_howto_table[(unsigned) R_XTENSA_TLSDESC_ARG ];
+
+ case BFD_RELOC_XTENSA_TLS_DTPOFF:
+ TRACE ("BFD_RELOC_XTENSA_TLS_DTPOFF");
+ return &elf_howto_table[(unsigned) R_XTENSA_TLS_DTPOFF ];
+
+ case BFD_RELOC_XTENSA_TLS_TPOFF:
+ TRACE ("BFD_RELOC_XTENSA_TLS_TPOFF");
+ return &elf_howto_table[(unsigned) R_XTENSA_TLS_TPOFF ];
+
+ case BFD_RELOC_XTENSA_TLS_FUNC:
+ TRACE ("BFD_RELOC_XTENSA_TLS_FUNC");
+ return &elf_howto_table[(unsigned) R_XTENSA_TLS_FUNC ];
+
+ case BFD_RELOC_XTENSA_TLS_ARG:
+ TRACE ("BFD_RELOC_XTENSA_TLS_ARG");
+ return &elf_howto_table[(unsigned) R_XTENSA_TLS_ARG ];
+
+ case BFD_RELOC_XTENSA_TLS_CALL:
+ TRACE ("BFD_RELOC_XTENSA_TLS_CALL");
+ return &elf_howto_table[(unsigned) R_XTENSA_TLS_CALL ];
+
+ default:
+ if (code >= BFD_RELOC_XTENSA_SLOT0_OP
+ && code <= BFD_RELOC_XTENSA_SLOT14_OP)
+ {
+ unsigned n = (R_XTENSA_SLOT0_OP +
+ (code - BFD_RELOC_XTENSA_SLOT0_OP));
+ return &elf_howto_table[n];
+ }
+
+ if (code >= BFD_RELOC_XTENSA_SLOT0_ALT
+ && code <= BFD_RELOC_XTENSA_SLOT14_ALT)
+ {
+ unsigned n = (R_XTENSA_SLOT0_ALT +
+ (code - BFD_RELOC_XTENSA_SLOT0_ALT));
+ return &elf_howto_table[n];
+ }
+
+ break;
+ }
+
+ TRACE ("Unknown");
+ return NULL;
+}
+
+static reloc_howto_type *
+elf_xtensa_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ const char *r_name)
+{
+ unsigned int i;
+
+ for (i = 0; i < sizeof (elf_howto_table) / sizeof (elf_howto_table[0]); i++)
+ if (elf_howto_table[i].name != NULL
+ && strcasecmp (elf_howto_table[i].name, r_name) == 0)
+ return &elf_howto_table[i];
+
+ return NULL;
+}
+
+
+/* Given an ELF "rela" relocation, find the corresponding howto and record
+ it in the BFD internal arelent representation of the relocation. */
+
+static void
+elf_xtensa_info_to_howto_rela (bfd *abfd ATTRIBUTE_UNUSED,
+ arelent *cache_ptr,
+ Elf_Internal_Rela *dst)
+{
+ unsigned int r_type = ELF32_R_TYPE (dst->r_info);
+
+ BFD_ASSERT (r_type < (unsigned int) R_XTENSA_max);
+ cache_ptr->howto = &elf_howto_table[r_type];
+}
+
+
+/* Functions for the Xtensa ELF linker. */
+
+/* The name of the dynamic interpreter. This is put in the .interp
+ section. */
+
+#define ELF_DYNAMIC_INTERPRETER "/lib/ld.so"
+
+/* The size in bytes of an entry in the procedure linkage table.
+ (This does _not_ include the space for the literals associated with
+ the PLT entry.) */
+
+#define PLT_ENTRY_SIZE 16
+
+/* For _really_ large PLTs, we may need to alternate between literals
+ and code to keep the literals within the 256K range of the L32R
+ instructions in the code. It's unlikely that anyone would ever need
+ such a big PLT, but an arbitrary limit on the PLT size would be bad.
+ Thus, we split the PLT into chunks. Since there's very little
+ overhead (2 extra literals) for each chunk, the chunk size is kept
+ small so that the code for handling multiple chunks get used and
+ tested regularly. With 254 entries, there are 1K of literals for
+ each chunk, and that seems like a nice round number. */
+
+#define PLT_ENTRIES_PER_CHUNK 254
+
+/* PLT entries are actually used as stub functions for lazy symbol
+ resolution. Once the symbol is resolved, the stub function is never
+ invoked. Note: the 32-byte frame size used here cannot be changed
+ without a corresponding change in the runtime linker. */
+
+static const bfd_byte elf_xtensa_be_plt_entry[PLT_ENTRY_SIZE] =
+{
+ 0x6c, 0x10, 0x04, /* entry sp, 32 */
+ 0x18, 0x00, 0x00, /* l32r a8, [got entry for rtld's resolver] */
+ 0x1a, 0x00, 0x00, /* l32r a10, [got entry for rtld's link map] */
+ 0x1b, 0x00, 0x00, /* l32r a11, [literal for reloc index] */
+ 0x0a, 0x80, 0x00, /* jx a8 */
+ 0 /* unused */
+};
+
+static const bfd_byte elf_xtensa_le_plt_entry[PLT_ENTRY_SIZE] =
+{
+ 0x36, 0x41, 0x00, /* entry sp, 32 */
+ 0x81, 0x00, 0x00, /* l32r a8, [got entry for rtld's resolver] */
+ 0xa1, 0x00, 0x00, /* l32r a10, [got entry for rtld's link map] */
+ 0xb1, 0x00, 0x00, /* l32r a11, [literal for reloc index] */
+ 0xa0, 0x08, 0x00, /* jx a8 */
+ 0 /* unused */
+};
+
+/* The size of the thread control block. */
+#define TCB_SIZE 8
+
+struct elf_xtensa_link_hash_entry
+{
+ struct elf_link_hash_entry elf;
+
+ bfd_signed_vma tlsfunc_refcount;
+
+#define GOT_UNKNOWN 0
+#define GOT_NORMAL 1
+#define GOT_TLS_GD 2 /* global or local dynamic */
+#define GOT_TLS_IE 4 /* initial or local exec */
+#define GOT_TLS_ANY (GOT_TLS_GD | GOT_TLS_IE)
+ unsigned char tls_type;
+};
+
+#define elf_xtensa_hash_entry(ent) ((struct elf_xtensa_link_hash_entry *)(ent))
+
+struct elf_xtensa_obj_tdata
+{
+ struct elf_obj_tdata root;
+
+ /* tls_type for each local got entry. */
+ char *local_got_tls_type;
+
+ bfd_signed_vma *local_tlsfunc_refcounts;
+};
+
+#define elf_xtensa_tdata(abfd) \
+ ((struct elf_xtensa_obj_tdata *) (abfd)->tdata.any)
+
+#define elf_xtensa_local_got_tls_type(abfd) \
+ (elf_xtensa_tdata (abfd)->local_got_tls_type)
+
+#define elf_xtensa_local_tlsfunc_refcounts(abfd) \
+ (elf_xtensa_tdata (abfd)->local_tlsfunc_refcounts)
+
+#define is_xtensa_elf(bfd) \
+ (bfd_get_flavour (bfd) == bfd_target_elf_flavour \
+ && elf_tdata (bfd) != NULL \
+ && elf_object_id (bfd) == XTENSA_ELF_DATA)
+
+static bfd_boolean
+elf_xtensa_mkobject (bfd *abfd)
+{
+ return bfd_elf_allocate_object (abfd, sizeof (struct elf_xtensa_obj_tdata),
+ XTENSA_ELF_DATA);
+}
+
+/* Xtensa ELF linker hash table. */
+
+struct elf_xtensa_link_hash_table
+{
+ struct elf_link_hash_table elf;
+
+ /* Short-cuts to get to dynamic linker sections. */
+ asection *sgot;
+ asection *sgotplt;
+ asection *srelgot;
+ asection *splt;
+ asection *srelplt;
+ asection *sgotloc;
+ asection *spltlittbl;
+
+ /* Total count of PLT relocations seen during check_relocs.
+ The actual PLT code must be split into multiple sections and all
+ the sections have to be created before size_dynamic_sections,
+ where we figure out the exact number of PLT entries that will be
+ needed. It is OK if this count is an overestimate, e.g., some
+ relocations may be removed by GC. */
+ int plt_reloc_count;
+
+ struct elf_xtensa_link_hash_entry *tlsbase;
+};
+
+/* Get the Xtensa ELF linker hash table from a link_info structure. */
+
+#define elf_xtensa_hash_table(p) \
+ (elf_hash_table_id ((struct elf_link_hash_table *) ((p)->hash)) \
+ == XTENSA_ELF_DATA ? ((struct elf_xtensa_link_hash_table *) ((p)->hash)) : NULL)
+
+/* Create an entry in an Xtensa ELF linker hash table. */
+
+static struct bfd_hash_entry *
+elf_xtensa_link_hash_newfunc (struct bfd_hash_entry *entry,
+ struct bfd_hash_table *table,
+ const char *string)
+{
+ /* Allocate the structure if it has not already been allocated by a
+ subclass. */
+ if (entry == NULL)
+ {
+ entry = bfd_hash_allocate (table,
+ sizeof (struct elf_xtensa_link_hash_entry));
+ if (entry == NULL)
+ return entry;
+ }
+
+ /* Call the allocation method of the superclass. */
+ entry = _bfd_elf_link_hash_newfunc (entry, table, string);
+ if (entry != NULL)
+ {
+ struct elf_xtensa_link_hash_entry *eh = elf_xtensa_hash_entry (entry);
+ eh->tlsfunc_refcount = 0;
+ eh->tls_type = GOT_UNKNOWN;
+ }
+
+ return entry;
+}
+
+/* Create an Xtensa ELF linker hash table. */
+
+static struct bfd_link_hash_table *
+elf_xtensa_link_hash_table_create (bfd *abfd)
+{
+ struct elf_link_hash_entry *tlsbase;
+ struct elf_xtensa_link_hash_table *ret;
+ bfd_size_type amt = sizeof (struct elf_xtensa_link_hash_table);
+
+ ret = bfd_zmalloc (amt);
+ if (ret == NULL)
+ return NULL;
+
+ if (!_bfd_elf_link_hash_table_init (&ret->elf, abfd,
+ elf_xtensa_link_hash_newfunc,
+ sizeof (struct elf_xtensa_link_hash_entry),
+ XTENSA_ELF_DATA))
+ {
+ free (ret);
+ return NULL;
+ }
+
+ /* Create a hash entry for "_TLS_MODULE_BASE_" to speed up checking
+ for it later. */
+ tlsbase = elf_link_hash_lookup (&ret->elf, "_TLS_MODULE_BASE_",
+ TRUE, FALSE, FALSE);
+ tlsbase->root.type = bfd_link_hash_new;
+ tlsbase->root.u.undef.abfd = NULL;
+ tlsbase->non_elf = 0;
+ ret->tlsbase = elf_xtensa_hash_entry (tlsbase);
+ ret->tlsbase->tls_type = GOT_UNKNOWN;
+
+ return &ret->elf.root;
+}
+
+/* Copy the extra info we tack onto an elf_link_hash_entry. */
+
+static void
+elf_xtensa_copy_indirect_symbol (struct bfd_link_info *info,
+ struct elf_link_hash_entry *dir,
+ struct elf_link_hash_entry *ind)
+{
+ struct elf_xtensa_link_hash_entry *edir, *eind;
+
+ edir = elf_xtensa_hash_entry (dir);
+ eind = elf_xtensa_hash_entry (ind);
+
+ if (ind->root.type == bfd_link_hash_indirect)
+ {
+ edir->tlsfunc_refcount += eind->tlsfunc_refcount;
+ eind->tlsfunc_refcount = 0;
+
+ if (dir->got.refcount <= 0)
+ {
+ edir->tls_type = eind->tls_type;
+ eind->tls_type = GOT_UNKNOWN;
+ }
+ }
+
+ _bfd_elf_link_hash_copy_indirect (info, dir, ind);
+}
+
+static inline bfd_boolean
+elf_xtensa_dynamic_symbol_p (struct elf_link_hash_entry *h,
+ struct bfd_link_info *info)
+{
+ /* Check if we should do dynamic things to this symbol. The
+ "ignore_protected" argument need not be set, because Xtensa code
+ does not require special handling of STV_PROTECTED to make function
+ pointer comparisons work properly. The PLT addresses are never
+ used for function pointers. */
+
+ return _bfd_elf_dynamic_symbol_p (h, info, 0);
+}
+
+
+static int
+property_table_compare (const void *ap, const void *bp)
+{
+ const property_table_entry *a = (const property_table_entry *) ap;
+ const property_table_entry *b = (const property_table_entry *) bp;
+
+ if (a->address == b->address)
+ {
+ if (a->size != b->size)
+ return (a->size - b->size);
+
+ if ((a->flags & XTENSA_PROP_ALIGN) != (b->flags & XTENSA_PROP_ALIGN))
+ return ((b->flags & XTENSA_PROP_ALIGN)
+ - (a->flags & XTENSA_PROP_ALIGN));
+
+ if ((a->flags & XTENSA_PROP_ALIGN)
+ && (GET_XTENSA_PROP_ALIGNMENT (a->flags)
+ != GET_XTENSA_PROP_ALIGNMENT (b->flags)))
+ return (GET_XTENSA_PROP_ALIGNMENT (a->flags)
+ - GET_XTENSA_PROP_ALIGNMENT (b->flags));
+
+ if ((a->flags & XTENSA_PROP_UNREACHABLE)
+ != (b->flags & XTENSA_PROP_UNREACHABLE))
+ return ((b->flags & XTENSA_PROP_UNREACHABLE)
+ - (a->flags & XTENSA_PROP_UNREACHABLE));
+
+ return (a->flags - b->flags);
+ }
+
+ return (a->address - b->address);
+}
+
+
+static int
+property_table_matches (const void *ap, const void *bp)
+{
+ const property_table_entry *a = (const property_table_entry *) ap;
+ const property_table_entry *b = (const property_table_entry *) bp;
+
+ /* Check if one entry overlaps with the other. */
+ if ((b->address >= a->address && b->address < (a->address + a->size))
+ || (a->address >= b->address && a->address < (b->address + b->size)))
+ return 0;
+
+ return (a->address - b->address);
+}
+
+
+/* Get the literal table or property table entries for the given
+ section. Sets TABLE_P and returns the number of entries. On
+ error, returns a negative value. */
+
+static int
+xtensa_read_table_entries (bfd *abfd,
+ asection *section,
+ property_table_entry **table_p,
+ const char *sec_name,
+ bfd_boolean output_addr)
+{
+ asection *table_section;
+ bfd_size_type table_size = 0;
+ bfd_byte *table_data;
+ property_table_entry *blocks;
+ int blk, block_count;
+ bfd_size_type num_records;
+ Elf_Internal_Rela *internal_relocs, *irel, *rel_end;
+ bfd_vma section_addr, off;
+ flagword predef_flags;
+ bfd_size_type table_entry_size, section_limit;
+
+ if (!section
+ || !(section->flags & SEC_ALLOC)
+ || (section->flags & SEC_DEBUGGING))
+ {
+ *table_p = NULL;
+ return 0;
+ }
+
+ table_section = xtensa_get_property_section (section, sec_name);
+ if (table_section)
+ table_size = table_section->size;
+
+ if (table_size == 0)
+ {
+ *table_p = NULL;
+ return 0;
+ }
+
+ predef_flags = xtensa_get_property_predef_flags (table_section);
+ table_entry_size = 12;
+ if (predef_flags)
+ table_entry_size -= 4;
+
+ num_records = table_size / table_entry_size;
+ table_data = retrieve_contents (abfd, table_section, TRUE);
+ blocks = (property_table_entry *)
+ bfd_malloc (num_records * sizeof (property_table_entry));
+ block_count = 0;
+
+ if (output_addr)
+ section_addr = section->output_section->vma + section->output_offset;
+ else
+ section_addr = section->vma;
+
+ internal_relocs = retrieve_internal_relocs (abfd, table_section, TRUE);
+ if (internal_relocs && !table_section->reloc_done)
+ {
+ qsort (internal_relocs, table_section->reloc_count,
+ sizeof (Elf_Internal_Rela), internal_reloc_compare);
+ irel = internal_relocs;
+ }
+ else
+ irel = NULL;
+
+ section_limit = bfd_get_section_limit (abfd, section);
+ rel_end = internal_relocs + table_section->reloc_count;
+
+ for (off = 0; off < table_size; off += table_entry_size)
+ {
+ bfd_vma address = bfd_get_32 (abfd, table_data + off);
+
+ /* Skip any relocations before the current offset. This should help
+ avoid confusion caused by unexpected relocations for the preceding
+ table entry. */
+ while (irel &&
+ (irel->r_offset < off
+ || (irel->r_offset == off
+ && ELF32_R_TYPE (irel->r_info) == R_XTENSA_NONE)))
+ {
+ irel += 1;
+ if (irel >= rel_end)
+ irel = 0;
+ }
+
+ if (irel && irel->r_offset == off)
+ {
+ bfd_vma sym_off;
+ unsigned long r_symndx = ELF32_R_SYM (irel->r_info);
+ BFD_ASSERT (ELF32_R_TYPE (irel->r_info) == R_XTENSA_32);
+
+ if (get_elf_r_symndx_section (abfd, r_symndx) != section)
+ continue;
+
+ sym_off = get_elf_r_symndx_offset (abfd, r_symndx);
+ BFD_ASSERT (sym_off == 0);
+ address += (section_addr + sym_off + irel->r_addend);
+ }
+ else
+ {
+ if (address < section_addr
+ || address >= section_addr + section_limit)
+ continue;
+ }
+
+ blocks[block_count].address = address;
+ blocks[block_count].size = bfd_get_32 (abfd, table_data + off + 4);
+ if (predef_flags)
+ blocks[block_count].flags = predef_flags;
+ else
+ blocks[block_count].flags = bfd_get_32 (abfd, table_data + off + 8);
+ block_count++;
+ }
+
+ release_contents (table_section, table_data);
+ release_internal_relocs (table_section, internal_relocs);
+
+ if (block_count > 0)
+ {
+ /* Now sort them into address order for easy reference. */
+ qsort (blocks, block_count, sizeof (property_table_entry),
+ property_table_compare);
+
+ /* Check that the table contents are valid. Problems may occur,
+ for example, if an unrelocated object file is stripped. */
+ for (blk = 1; blk < block_count; blk++)
+ {
+ /* The only circumstance where two entries may legitimately
+ have the same address is when one of them is a zero-size
+ placeholder to mark a place where fill can be inserted.
+ The zero-size entry should come first. */
+ if (blocks[blk - 1].address == blocks[blk].address &&
+ blocks[blk - 1].size != 0)
+ {
+ (*_bfd_error_handler) (_("%B(%A): invalid property table"),
+ abfd, section);
+ bfd_set_error (bfd_error_bad_value);
+ free (blocks);
+ return -1;
+ }
+ }
+ }
+
+ *table_p = blocks;
+ return block_count;
+}
+
+
+static property_table_entry *
+elf_xtensa_find_property_entry (property_table_entry *property_table,
+ int property_table_size,
+ bfd_vma addr)
+{
+ property_table_entry entry;
+ property_table_entry *rv;
+
+ if (property_table_size == 0)
+ return NULL;
+
+ entry.address = addr;
+ entry.size = 1;
+ entry.flags = 0;
+
+ rv = bsearch (&entry, property_table, property_table_size,
+ sizeof (property_table_entry), property_table_matches);
+ return rv;
+}
+
+
+static bfd_boolean
+elf_xtensa_in_literal_pool (property_table_entry *lit_table,
+ int lit_table_size,
+ bfd_vma addr)
+{
+ if (elf_xtensa_find_property_entry (lit_table, lit_table_size, addr))
+ return TRUE;
+
+ return FALSE;
+}
+
+
+/* Look through the relocs for a section during the first phase, and
+ calculate needed space in the dynamic reloc sections. */
+
+static bfd_boolean
+elf_xtensa_check_relocs (bfd *abfd,
+ struct bfd_link_info *info,
+ asection *sec,
+ const Elf_Internal_Rela *relocs)
+{
+ struct elf_xtensa_link_hash_table *htab;
+ Elf_Internal_Shdr *symtab_hdr;
+ struct elf_link_hash_entry **sym_hashes;
+ const Elf_Internal_Rela *rel;
+ const Elf_Internal_Rela *rel_end;
+
+ if (info->relocatable || (sec->flags & SEC_ALLOC) == 0)
+ return TRUE;
+
+ BFD_ASSERT (is_xtensa_elf (abfd));
+
+ htab = elf_xtensa_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+ sym_hashes = elf_sym_hashes (abfd);
+
+ rel_end = relocs + sec->reloc_count;
+ for (rel = relocs; rel < rel_end; rel++)
+ {
+ unsigned int r_type;
+ unsigned long r_symndx;
+ struct elf_link_hash_entry *h = NULL;
+ struct elf_xtensa_link_hash_entry *eh;
+ int tls_type, old_tls_type;
+ bfd_boolean is_got = FALSE;
+ bfd_boolean is_plt = FALSE;
+ bfd_boolean is_tlsfunc = FALSE;
+
+ r_symndx = ELF32_R_SYM (rel->r_info);
+ r_type = ELF32_R_TYPE (rel->r_info);
+
+ if (r_symndx >= NUM_SHDR_ENTRIES (symtab_hdr))
+ {
+ (*_bfd_error_handler) (_("%B: bad symbol index: %d"),
+ abfd, r_symndx);
+ return FALSE;
+ }
+
+ if (r_symndx >= symtab_hdr->sh_info)
+ {
+ 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;
+
+ /* PR15323, ref flags aren't set for references in the same
+ object. */
+ h->root.non_ir_ref = 1;
+ }
+ eh = elf_xtensa_hash_entry (h);
+
+ switch (r_type)
+ {
+ case R_XTENSA_TLSDESC_FN:
+ if (info->shared)
+ {
+ tls_type = GOT_TLS_GD;
+ is_got = TRUE;
+ is_tlsfunc = TRUE;
+ }
+ else
+ tls_type = GOT_TLS_IE;
+ break;
+
+ case R_XTENSA_TLSDESC_ARG:
+ if (info->shared)
+ {
+ tls_type = GOT_TLS_GD;
+ is_got = TRUE;
+ }
+ else
+ {
+ tls_type = GOT_TLS_IE;
+ if (h && elf_xtensa_hash_entry (h) != htab->tlsbase)
+ is_got = TRUE;
+ }
+ break;
+
+ case R_XTENSA_TLS_DTPOFF:
+ if (info->shared)
+ tls_type = GOT_TLS_GD;
+ else
+ tls_type = GOT_TLS_IE;
+ break;
+
+ case R_XTENSA_TLS_TPOFF:
+ tls_type = GOT_TLS_IE;
+ if (info->shared)
+ info->flags |= DF_STATIC_TLS;
+ if (info->shared || h)
+ is_got = TRUE;
+ break;
+
+ case R_XTENSA_32:
+ tls_type = GOT_NORMAL;
+ is_got = TRUE;
+ break;
+
+ case R_XTENSA_PLT:
+ tls_type = GOT_NORMAL;
+ is_plt = TRUE;
+ break;
+
+ case R_XTENSA_GNU_VTINHERIT:
+ /* This relocation describes the C++ object vtable hierarchy.
+ Reconstruct it for later use during GC. */
+ if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
+ return FALSE;
+ continue;
+
+ case R_XTENSA_GNU_VTENTRY:
+ /* This relocation describes which C++ vtable entries are actually
+ used. Record for later use during GC. */
+ BFD_ASSERT (h != NULL);
+ if (h != NULL
+ && !bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
+ return FALSE;
+ continue;
+
+ default:
+ /* Nothing to do for any other relocations. */
+ continue;
+ }
+
+ if (h)
+ {
+ if (is_plt)
+ {
+ if (h->plt.refcount <= 0)
+ {
+ h->needs_plt = 1;
+ h->plt.refcount = 1;
+ }
+ else
+ h->plt.refcount += 1;
+
+ /* Keep track of the total PLT relocation count even if we
+ don't yet know whether the dynamic sections will be
+ created. */
+ htab->plt_reloc_count += 1;
+
+ if (elf_hash_table (info)->dynamic_sections_created)
+ {
+ if (! add_extra_plt_sections (info, htab->plt_reloc_count))
+ return FALSE;
+ }
+ }
+ else if (is_got)
+ {
+ if (h->got.refcount <= 0)
+ h->got.refcount = 1;
+ else
+ h->got.refcount += 1;
+ }
+
+ if (is_tlsfunc)
+ eh->tlsfunc_refcount += 1;
+
+ old_tls_type = eh->tls_type;
+ }
+ else
+ {
+ /* Allocate storage the first time. */
+ if (elf_local_got_refcounts (abfd) == NULL)
+ {
+ bfd_size_type size = symtab_hdr->sh_info;
+ void *mem;
+
+ mem = bfd_zalloc (abfd, size * sizeof (bfd_signed_vma));
+ if (mem == NULL)
+ return FALSE;
+ elf_local_got_refcounts (abfd) = (bfd_signed_vma *) mem;
+
+ mem = bfd_zalloc (abfd, size);
+ if (mem == NULL)
+ return FALSE;
+ elf_xtensa_local_got_tls_type (abfd) = (char *) mem;
+
+ mem = bfd_zalloc (abfd, size * sizeof (bfd_signed_vma));
+ if (mem == NULL)
+ return FALSE;
+ elf_xtensa_local_tlsfunc_refcounts (abfd)
+ = (bfd_signed_vma *) mem;
+ }
+
+ /* This is a global offset table entry for a local symbol. */
+ if (is_got || is_plt)
+ elf_local_got_refcounts (abfd) [r_symndx] += 1;
+
+ if (is_tlsfunc)
+ elf_xtensa_local_tlsfunc_refcounts (abfd) [r_symndx] += 1;
+
+ old_tls_type = elf_xtensa_local_got_tls_type (abfd) [r_symndx];
+ }
+
+ if ((old_tls_type & GOT_TLS_IE) && (tls_type & GOT_TLS_IE))
+ tls_type |= old_tls_type;
+ /* If a TLS symbol is accessed using IE at least once,
+ there is no point to use a dynamic model for it. */
+ else if (old_tls_type != tls_type && old_tls_type != GOT_UNKNOWN
+ && ((old_tls_type & GOT_TLS_GD) == 0
+ || (tls_type & GOT_TLS_IE) == 0))
+ {
+ if ((old_tls_type & GOT_TLS_IE) && (tls_type & GOT_TLS_GD))
+ tls_type = old_tls_type;
+ else if ((old_tls_type & GOT_TLS_GD) && (tls_type & GOT_TLS_GD))
+ tls_type |= old_tls_type;
+ else
+ {
+ (*_bfd_error_handler)
+ (_("%B: `%s' accessed both as normal and thread local symbol"),
+ abfd,
+ h ? h->root.root.string : "<local>");
+ return FALSE;
+ }
+ }
+
+ if (old_tls_type != tls_type)
+ {
+ if (eh)
+ eh->tls_type = tls_type;
+ else
+ elf_xtensa_local_got_tls_type (abfd) [r_symndx] = tls_type;
+ }
+ }
+
+ return TRUE;
+}
+
+
+static void
+elf_xtensa_make_sym_local (struct bfd_link_info *info,
+ struct elf_link_hash_entry *h)
+{
+ if (info->shared)
+ {
+ if (h->plt.refcount > 0)
+ {
+ /* For shared objects, there's no need for PLT entries for local
+ symbols (use RELATIVE relocs instead of JMP_SLOT relocs). */
+ if (h->got.refcount < 0)
+ h->got.refcount = 0;
+ h->got.refcount += h->plt.refcount;
+ h->plt.refcount = 0;
+ }
+ }
+ else
+ {
+ /* Don't need any dynamic relocations at all. */
+ h->plt.refcount = 0;
+ h->got.refcount = 0;
+ }
+}
+
+
+static void
+elf_xtensa_hide_symbol (struct bfd_link_info *info,
+ struct elf_link_hash_entry *h,
+ bfd_boolean force_local)
+{
+ /* For a shared link, move the plt refcount to the got refcount to leave
+ space for RELATIVE relocs. */
+ elf_xtensa_make_sym_local (info, h);
+
+ _bfd_elf_link_hash_hide_symbol (info, h, force_local);
+}
+
+
+/* Return the section that should be marked against GC for a given
+ relocation. */
+
+static asection *
+elf_xtensa_gc_mark_hook (asection *sec,
+ struct bfd_link_info *info,
+ Elf_Internal_Rela *rel,
+ struct elf_link_hash_entry *h,
+ Elf_Internal_Sym *sym)
+{
+ /* Property sections are marked "KEEP" in the linker scripts, but they
+ should not cause other sections to be marked. (This approach relies
+ on elf_xtensa_discard_info to remove property table entries that
+ describe discarded sections. Alternatively, it might be more
+ efficient to avoid using "KEEP" in the linker scripts and instead use
+ the gc_mark_extra_sections hook to mark only the property sections
+ that describe marked sections. That alternative does not work well
+ with the current property table sections, which do not correspond
+ one-to-one with the sections they describe, but that should be fixed
+ someday.) */
+ if (xtensa_is_property_section (sec))
+ return NULL;
+
+ if (h != NULL)
+ switch (ELF32_R_TYPE (rel->r_info))
+ {
+ case R_XTENSA_GNU_VTINHERIT:
+ case R_XTENSA_GNU_VTENTRY:
+ return NULL;
+ }
+
+ return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
+}
+
+
+/* Update the GOT & PLT entry reference counts
+ for the section being removed. */
+
+static bfd_boolean
+elf_xtensa_gc_sweep_hook (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;
+ const Elf_Internal_Rela *rel, *relend;
+ struct elf_xtensa_link_hash_table *htab;
+
+ htab = elf_xtensa_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ if (info->relocatable)
+ return TRUE;
+
+ if ((sec->flags & SEC_ALLOC) == 0)
+ return TRUE;
+
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+ sym_hashes = elf_sym_hashes (abfd);
+
+ relend = relocs + sec->reloc_count;
+ for (rel = relocs; rel < relend; rel++)
+ {
+ unsigned long r_symndx;
+ unsigned int r_type;
+ struct elf_link_hash_entry *h = NULL;
+ struct elf_xtensa_link_hash_entry *eh;
+ bfd_boolean is_got = FALSE;
+ bfd_boolean is_plt = FALSE;
+ bfd_boolean is_tlsfunc = FALSE;
+
+ r_symndx = ELF32_R_SYM (rel->r_info);
+ if (r_symndx >= symtab_hdr->sh_info)
+ {
+ 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;
+ }
+ eh = elf_xtensa_hash_entry (h);
+
+ r_type = ELF32_R_TYPE (rel->r_info);
+ switch (r_type)
+ {
+ case R_XTENSA_TLSDESC_FN:
+ if (info->shared)
+ {
+ is_got = TRUE;
+ is_tlsfunc = TRUE;
+ }
+ break;
+
+ case R_XTENSA_TLSDESC_ARG:
+ if (info->shared)
+ is_got = TRUE;
+ else
+ {
+ if (h && elf_xtensa_hash_entry (h) != htab->tlsbase)
+ is_got = TRUE;
+ }
+ break;
+
+ case R_XTENSA_TLS_TPOFF:
+ if (info->shared || h)
+ is_got = TRUE;
+ break;
+
+ case R_XTENSA_32:
+ is_got = TRUE;
+ break;
+
+ case R_XTENSA_PLT:
+ is_plt = TRUE;
+ break;
+
+ default:
+ continue;
+ }
+
+ if (h)
+ {
+ if (is_plt)
+ {
+ if (h->plt.refcount > 0)
+ h->plt.refcount--;
+ }
+ else if (is_got)
+ {
+ if (h->got.refcount > 0)
+ h->got.refcount--;
+ }
+ if (is_tlsfunc)
+ {
+ if (eh->tlsfunc_refcount > 0)
+ eh->tlsfunc_refcount--;
+ }
+ }
+ else
+ {
+ if (is_got || is_plt)
+ {
+ bfd_signed_vma *got_refcount
+ = &elf_local_got_refcounts (abfd) [r_symndx];
+ if (*got_refcount > 0)
+ *got_refcount -= 1;
+ }
+ if (is_tlsfunc)
+ {
+ bfd_signed_vma *tlsfunc_refcount
+ = &elf_xtensa_local_tlsfunc_refcounts (abfd) [r_symndx];
+ if (*tlsfunc_refcount > 0)
+ *tlsfunc_refcount -= 1;
+ }
+ }
+ }
+
+ return TRUE;
+}
+
+
+/* Create all the dynamic sections. */
+
+static bfd_boolean
+elf_xtensa_create_dynamic_sections (bfd *dynobj, struct bfd_link_info *info)
+{
+ struct elf_xtensa_link_hash_table *htab;
+ flagword flags, noalloc_flags;
+
+ htab = elf_xtensa_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ /* First do all the standard stuff. */
+ if (! _bfd_elf_create_dynamic_sections (dynobj, info))
+ return FALSE;
+ htab->splt = bfd_get_linker_section (dynobj, ".plt");
+ htab->srelplt = bfd_get_linker_section (dynobj, ".rela.plt");
+ htab->sgot = bfd_get_linker_section (dynobj, ".got");
+ htab->sgotplt = bfd_get_linker_section (dynobj, ".got.plt");
+ htab->srelgot = bfd_get_linker_section (dynobj, ".rela.got");
+
+ /* Create any extra PLT sections in case check_relocs has already
+ been called on all the non-dynamic input files. */
+ if (! add_extra_plt_sections (info, htab->plt_reloc_count))
+ return FALSE;
+
+ noalloc_flags = (SEC_HAS_CONTENTS | SEC_IN_MEMORY
+ | SEC_LINKER_CREATED | SEC_READONLY);
+ flags = noalloc_flags | SEC_ALLOC | SEC_LOAD;
+
+ /* Mark the ".got.plt" section READONLY. */
+ if (htab->sgotplt == NULL
+ || ! bfd_set_section_flags (dynobj, htab->sgotplt, flags))
+ return FALSE;
+
+ /* Create ".got.loc" (literal tables for use by dynamic linker). */
+ htab->sgotloc = bfd_make_section_anyway_with_flags (dynobj, ".got.loc",
+ flags);
+ if (htab->sgotloc == NULL
+ || ! bfd_set_section_alignment (dynobj, htab->sgotloc, 2))
+ return FALSE;
+
+ /* Create ".xt.lit.plt" (literal table for ".got.plt*"). */
+ htab->spltlittbl = bfd_make_section_anyway_with_flags (dynobj, ".xt.lit.plt",
+ noalloc_flags);
+ if (htab->spltlittbl == NULL
+ || ! bfd_set_section_alignment (dynobj, htab->spltlittbl, 2))
+ return FALSE;
+
+ return TRUE;
+}
+
+
+static bfd_boolean
+add_extra_plt_sections (struct bfd_link_info *info, int count)
+{
+ bfd *dynobj = elf_hash_table (info)->dynobj;
+ int chunk;
+
+ /* Iterate over all chunks except 0 which uses the standard ".plt" and
+ ".got.plt" sections. */
+ for (chunk = count / PLT_ENTRIES_PER_CHUNK; chunk > 0; chunk--)
+ {
+ char *sname;
+ flagword flags;
+ asection *s;
+
+ /* Stop when we find a section has already been created. */
+ if (elf_xtensa_get_plt_section (info, chunk))
+ break;
+
+ flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
+ | SEC_LINKER_CREATED | SEC_READONLY);
+
+ sname = (char *) bfd_malloc (10);
+ sprintf (sname, ".plt.%u", chunk);
+ s = bfd_make_section_anyway_with_flags (dynobj, sname, flags | SEC_CODE);
+ if (s == NULL
+ || ! bfd_set_section_alignment (dynobj, s, 2))
+ return FALSE;
+
+ sname = (char *) bfd_malloc (14);
+ sprintf (sname, ".got.plt.%u", chunk);
+ s = bfd_make_section_anyway_with_flags (dynobj, sname, flags);
+ if (s == NULL
+ || ! bfd_set_section_alignment (dynobj, 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 bfd_boolean
+elf_xtensa_adjust_dynamic_symbol (struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ struct elf_link_hash_entry *h)
+{
+ /* 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->u.weakdef)
+ {
+ BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
+ || h->u.weakdef->root.type == bfd_link_hash_defweak);
+ h->root.u.def.section = h->u.weakdef->root.u.def.section;
+ h->root.u.def.value = h->u.weakdef->root.u.def.value;
+ return TRUE;
+ }
+
+ /* This is a reference to a symbol defined by a dynamic object. The
+ reference must go through the GOT, so there's no need for COPY relocs,
+ .dynbss, etc. */
+
+ return TRUE;
+}
+
+
+static bfd_boolean
+elf_xtensa_allocate_dynrelocs (struct elf_link_hash_entry *h, void *arg)
+{
+ struct bfd_link_info *info;
+ struct elf_xtensa_link_hash_table *htab;
+ struct elf_xtensa_link_hash_entry *eh = elf_xtensa_hash_entry (h);
+
+ if (h->root.type == bfd_link_hash_indirect)
+ return TRUE;
+
+ info = (struct bfd_link_info *) arg;
+ htab = elf_xtensa_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ /* If we saw any use of an IE model for this symbol, we can then optimize
+ away GOT entries for any TLSDESC_FN relocs. */
+ if ((eh->tls_type & GOT_TLS_IE) != 0)
+ {
+ BFD_ASSERT (h->got.refcount >= eh->tlsfunc_refcount);
+ h->got.refcount -= eh->tlsfunc_refcount;
+ }
+
+ if (! elf_xtensa_dynamic_symbol_p (h, info))
+ elf_xtensa_make_sym_local (info, h);
+
+ if (h->plt.refcount > 0)
+ htab->srelplt->size += (h->plt.refcount * sizeof (Elf32_External_Rela));
+
+ if (h->got.refcount > 0)
+ htab->srelgot->size += (h->got.refcount * sizeof (Elf32_External_Rela));
+
+ return TRUE;
+}
+
+
+static void
+elf_xtensa_allocate_local_got_size (struct bfd_link_info *info)
+{
+ struct elf_xtensa_link_hash_table *htab;
+ bfd *i;
+
+ htab = elf_xtensa_hash_table (info);
+ if (htab == NULL)
+ return;
+
+ for (i = info->input_bfds; i; i = i->link.next)
+ {
+ bfd_signed_vma *local_got_refcounts;
+ bfd_size_type j, cnt;
+ Elf_Internal_Shdr *symtab_hdr;
+
+ local_got_refcounts = elf_local_got_refcounts (i);
+ if (!local_got_refcounts)
+ continue;
+
+ symtab_hdr = &elf_tdata (i)->symtab_hdr;
+ cnt = symtab_hdr->sh_info;
+
+ for (j = 0; j < cnt; ++j)
+ {
+ /* If we saw any use of an IE model for this symbol, we can
+ then optimize away GOT entries for any TLSDESC_FN relocs. */
+ if ((elf_xtensa_local_got_tls_type (i) [j] & GOT_TLS_IE) != 0)
+ {
+ bfd_signed_vma *tlsfunc_refcount
+ = &elf_xtensa_local_tlsfunc_refcounts (i) [j];
+ BFD_ASSERT (local_got_refcounts[j] >= *tlsfunc_refcount);
+ local_got_refcounts[j] -= *tlsfunc_refcount;
+ }
+
+ if (local_got_refcounts[j] > 0)
+ htab->srelgot->size += (local_got_refcounts[j]
+ * sizeof (Elf32_External_Rela));
+ }
+ }
+}
+
+
+/* Set the sizes of the dynamic sections. */
+
+static bfd_boolean
+elf_xtensa_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
+ struct bfd_link_info *info)
+{
+ struct elf_xtensa_link_hash_table *htab;
+ bfd *dynobj, *abfd;
+ asection *s, *srelplt, *splt, *sgotplt, *srelgot, *spltlittbl, *sgotloc;
+ bfd_boolean relplt, relgot;
+ int plt_entries, plt_chunks, chunk;
+
+ plt_entries = 0;
+ plt_chunks = 0;
+
+ htab = elf_xtensa_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ dynobj = elf_hash_table (info)->dynobj;
+ if (dynobj == NULL)
+ abort ();
+ srelgot = htab->srelgot;
+ srelplt = htab->srelplt;
+
+ if (elf_hash_table (info)->dynamic_sections_created)
+ {
+ BFD_ASSERT (htab->srelgot != NULL
+ && htab->srelplt != NULL
+ && htab->sgot != NULL
+ && htab->spltlittbl != NULL
+ && htab->sgotloc != NULL);
+
+ /* Set the contents of the .interp section to the interpreter. */
+ if (info->executable)
+ {
+ s = bfd_get_linker_section (dynobj, ".interp");
+ if (s == NULL)
+ abort ();
+ s->size = sizeof ELF_DYNAMIC_INTERPRETER;
+ s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
+ }
+
+ /* Allocate room for one word in ".got". */
+ htab->sgot->size = 4;
+
+ /* Allocate space in ".rela.got" for literals that reference global
+ symbols and space in ".rela.plt" for literals that have PLT
+ entries. */
+ elf_link_hash_traverse (elf_hash_table (info),
+ elf_xtensa_allocate_dynrelocs,
+ (void *) info);
+
+ /* If we are generating a shared object, we also need space in
+ ".rela.got" for R_XTENSA_RELATIVE relocs for literals that
+ reference local symbols. */
+ if (info->shared)
+ elf_xtensa_allocate_local_got_size (info);
+
+ /* Allocate space in ".plt" to match the size of ".rela.plt". For
+ each PLT entry, we need the PLT code plus a 4-byte literal.
+ For each chunk of ".plt", we also need two more 4-byte
+ literals, two corresponding entries in ".rela.got", and an
+ 8-byte entry in ".xt.lit.plt". */
+ spltlittbl = htab->spltlittbl;
+ plt_entries = srelplt->size / sizeof (Elf32_External_Rela);
+ plt_chunks =
+ (plt_entries + PLT_ENTRIES_PER_CHUNK - 1) / PLT_ENTRIES_PER_CHUNK;
+
+ /* Iterate over all the PLT chunks, including any extra sections
+ created earlier because the initial count of PLT relocations
+ was an overestimate. */
+ for (chunk = 0;
+ (splt = elf_xtensa_get_plt_section (info, chunk)) != NULL;
+ chunk++)
+ {
+ int chunk_entries;
+
+ sgotplt = elf_xtensa_get_gotplt_section (info, chunk);
+ BFD_ASSERT (sgotplt != NULL);
+
+ if (chunk < plt_chunks - 1)
+ chunk_entries = PLT_ENTRIES_PER_CHUNK;
+ else if (chunk == plt_chunks - 1)
+ chunk_entries = plt_entries - (chunk * PLT_ENTRIES_PER_CHUNK);
+ else
+ chunk_entries = 0;
+
+ if (chunk_entries != 0)
+ {
+ sgotplt->size = 4 * (chunk_entries + 2);
+ splt->size = PLT_ENTRY_SIZE * chunk_entries;
+ srelgot->size += 2 * sizeof (Elf32_External_Rela);
+ spltlittbl->size += 8;
+ }
+ else
+ {
+ sgotplt->size = 0;
+ splt->size = 0;
+ }
+ }
+
+ /* Allocate space in ".got.loc" to match the total size of all the
+ literal tables. */
+ sgotloc = htab->sgotloc;
+ sgotloc->size = spltlittbl->size;
+ for (abfd = info->input_bfds; abfd != NULL; abfd = abfd->link.next)
+ {
+ if (abfd->flags & DYNAMIC)
+ continue;
+ for (s = abfd->sections; s != NULL; s = s->next)
+ {
+ if (! discarded_section (s)
+ && xtensa_is_littable_section (s)
+ && s != spltlittbl)
+ sgotloc->size += s->size;
+ }
+ }
+ }
+
+ /* Allocate memory for dynamic sections. */
+ relplt = FALSE;
+ relgot = FALSE;
+ for (s = dynobj->sections; s != NULL; s = s->next)
+ {
+ const char *name;
+
+ 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);
+
+ if (CONST_STRNEQ (name, ".rela"))
+ {
+ if (s->size != 0)
+ {
+ if (strcmp (name, ".rela.plt") == 0)
+ relplt = TRUE;
+ else if (strcmp (name, ".rela.got") == 0)
+ relgot = 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 (! CONST_STRNEQ (name, ".plt.")
+ && ! CONST_STRNEQ (name, ".got.plt.")
+ && strcmp (name, ".got") != 0
+ && strcmp (name, ".plt") != 0
+ && strcmp (name, ".got.plt") != 0
+ && strcmp (name, ".xt.lit.plt") != 0
+ && strcmp (name, ".got.loc") != 0)
+ {
+ /* It's not one of our sections, so don't allocate space. */
+ continue;
+ }
+
+ if (s->size == 0)
+ {
+ /* If we don't need this section, strip it from the output
+ file. We must create the ".plt*" and ".got.plt*"
+ sections in create_dynamic_sections and/or check_relocs
+ based on a conservative estimate of the PLT relocation
+ count, because the sections must be created before the
+ linker maps input sections to output sections. The
+ linker does that before size_dynamic_sections, where we
+ compute the exact size of the PLT, so there may be more
+ of these sections than are actually needed. */
+ s->flags |= SEC_EXCLUDE;
+ }
+ else if ((s->flags & SEC_HAS_CONTENTS) != 0)
+ {
+ /* Allocate memory for the section contents. */
+ s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->size);
+ if (s->contents == NULL)
+ return FALSE;
+ }
+ }
+
+ if (elf_hash_table (info)->dynamic_sections_created)
+ {
+ /* Add the special XTENSA_RTLD relocations now. The offsets won't be
+ known until finish_dynamic_sections, but we need to get the relocs
+ in place before they are sorted. */
+ for (chunk = 0; chunk < plt_chunks; chunk++)
+ {
+ Elf_Internal_Rela irela;
+ bfd_byte *loc;
+
+ irela.r_offset = 0;
+ irela.r_info = ELF32_R_INFO (0, R_XTENSA_RTLD);
+ irela.r_addend = 0;
+
+ loc = (srelgot->contents
+ + srelgot->reloc_count * sizeof (Elf32_External_Rela));
+ bfd_elf32_swap_reloca_out (output_bfd, &irela, loc);
+ bfd_elf32_swap_reloca_out (output_bfd, &irela,
+ loc + sizeof (Elf32_External_Rela));
+ srelgot->reloc_count += 2;
+ }
+
+ /* Add some entries to the .dynamic section. We fill in the
+ values later, in elf_xtensa_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. */
+#define add_dynamic_entry(TAG, VAL) \
+ _bfd_elf_add_dynamic_entry (info, TAG, VAL)
+
+ if (info->executable)
+ {
+ if (!add_dynamic_entry (DT_DEBUG, 0))
+ return FALSE;
+ }
+
+ if (relplt)
+ {
+ if (!add_dynamic_entry (DT_PLTRELSZ, 0)
+ || !add_dynamic_entry (DT_PLTREL, DT_RELA)
+ || !add_dynamic_entry (DT_JMPREL, 0))
+ return FALSE;
+ }
+
+ if (relgot)
+ {
+ if (!add_dynamic_entry (DT_RELA, 0)
+ || !add_dynamic_entry (DT_RELASZ, 0)
+ || !add_dynamic_entry (DT_RELAENT, sizeof (Elf32_External_Rela)))
+ return FALSE;
+ }
+
+ if (!add_dynamic_entry (DT_PLTGOT, 0)
+ || !add_dynamic_entry (DT_XTENSA_GOT_LOC_OFF, 0)
+ || !add_dynamic_entry (DT_XTENSA_GOT_LOC_SZ, 0))
+ return FALSE;
+ }
+#undef add_dynamic_entry
+
+ return TRUE;
+}
+
+static bfd_boolean
+elf_xtensa_always_size_sections (bfd *output_bfd,
+ struct bfd_link_info *info)
+{
+ struct elf_xtensa_link_hash_table *htab;
+ asection *tls_sec;
+
+ htab = elf_xtensa_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ tls_sec = htab->elf.tls_sec;
+
+ if (tls_sec && (htab->tlsbase->tls_type & GOT_TLS_ANY) != 0)
+ {
+ struct elf_link_hash_entry *tlsbase = &htab->tlsbase->elf;
+ struct bfd_link_hash_entry *bh = &tlsbase->root;
+ const struct elf_backend_data *bed = get_elf_backend_data (output_bfd);
+
+ tlsbase->type = STT_TLS;
+ if (!(_bfd_generic_link_add_one_symbol
+ (info, output_bfd, "_TLS_MODULE_BASE_", BSF_LOCAL,
+ tls_sec, 0, NULL, FALSE,
+ bed->collect, &bh)))
+ return FALSE;
+ tlsbase->def_regular = 1;
+ tlsbase->other = STV_HIDDEN;
+ (*bed->elf_backend_hide_symbol) (info, tlsbase, TRUE);
+ }
+
+ return TRUE;
+}
+
+
+/* Return the base VMA address which should be subtracted from real addresses
+ when resolving @dtpoff relocation.
+ This is PT_TLS segment p_vaddr. */
+
+static bfd_vma
+dtpoff_base (struct bfd_link_info *info)
+{
+ /* If tls_sec is NULL, we should have signalled an error already. */
+ if (elf_hash_table (info)->tls_sec == NULL)
+ return 0;
+ return elf_hash_table (info)->tls_sec->vma;
+}
+
+/* Return the relocation value for @tpoff relocation
+ if STT_TLS virtual address is ADDRESS. */
+
+static bfd_vma
+tpoff (struct bfd_link_info *info, bfd_vma address)
+{
+ struct elf_link_hash_table *htab = elf_hash_table (info);
+ bfd_vma base;
+
+ /* If tls_sec is NULL, we should have signalled an error already. */
+ if (htab->tls_sec == NULL)
+ return 0;
+ base = align_power ((bfd_vma) TCB_SIZE, htab->tls_sec->alignment_power);
+ return address - htab->tls_sec->vma + base;
+}
+
+/* Perform the specified relocation. The instruction at (contents + address)
+ is modified to set one operand to represent the value in "relocation". The
+ operand position is determined by the relocation type recorded in the
+ howto. */
+
+#define CALL_SEGMENT_BITS (30)
+#define CALL_SEGMENT_SIZE (1 << CALL_SEGMENT_BITS)
+
+static bfd_reloc_status_type
+elf_xtensa_do_reloc (reloc_howto_type *howto,
+ bfd *abfd,
+ asection *input_section,
+ bfd_vma relocation,
+ bfd_byte *contents,
+ bfd_vma address,
+ bfd_boolean is_weak_undef,
+ char **error_message)
+{
+ xtensa_format fmt;
+ xtensa_opcode opcode;
+ xtensa_isa isa = xtensa_default_isa;
+ static xtensa_insnbuf ibuff = NULL;
+ static xtensa_insnbuf sbuff = NULL;
+ bfd_vma self_address;
+ bfd_size_type input_size;
+ int opnd, slot;
+ uint32 newval;
+
+ if (!ibuff)
+ {
+ ibuff = xtensa_insnbuf_alloc (isa);
+ sbuff = xtensa_insnbuf_alloc (isa);
+ }
+
+ input_size = bfd_get_section_limit (abfd, input_section);
+
+ /* Calculate the PC address for this instruction. */
+ self_address = (input_section->output_section->vma
+ + input_section->output_offset
+ + address);
+
+ switch (howto->type)
+ {
+ case R_XTENSA_NONE:
+ case R_XTENSA_DIFF8:
+ case R_XTENSA_DIFF16:
+ case R_XTENSA_DIFF32:
+ case R_XTENSA_TLS_FUNC:
+ case R_XTENSA_TLS_ARG:
+ case R_XTENSA_TLS_CALL:
+ return bfd_reloc_ok;
+
+ case R_XTENSA_ASM_EXPAND:
+ if (!is_weak_undef)
+ {
+ /* Check for windowed CALL across a 1GB boundary. */
+ opcode = get_expanded_call_opcode (contents + address,
+ input_size - address, 0);
+ if (is_windowed_call_opcode (opcode))
+ {
+ if ((self_address >> CALL_SEGMENT_BITS)
+ != (relocation >> CALL_SEGMENT_BITS))
+ {
+ *error_message = "windowed longcall crosses 1GB boundary; "
+ "return may fail";
+ return bfd_reloc_dangerous;
+ }
+ }
+ }
+ return bfd_reloc_ok;
+
+ case R_XTENSA_ASM_SIMPLIFY:
+ {
+ /* Convert the L32R/CALLX to CALL. */
+ bfd_reloc_status_type retval =
+ elf_xtensa_do_asm_simplify (contents, address, input_size,
+ error_message);
+ if (retval != bfd_reloc_ok)
+ return bfd_reloc_dangerous;
+
+ /* The CALL needs to be relocated. Continue below for that part. */
+ address += 3;
+ self_address += 3;
+ howto = &elf_howto_table[(unsigned) R_XTENSA_SLOT0_OP ];
+ }
+ break;
+
+ case R_XTENSA_32:
+ {
+ bfd_vma x;
+ x = bfd_get_32 (abfd, contents + address);
+ x = x + relocation;
+ bfd_put_32 (abfd, x, contents + address);
+ }
+ return bfd_reloc_ok;
+
+ case R_XTENSA_32_PCREL:
+ bfd_put_32 (abfd, relocation - self_address, contents + address);
+ return bfd_reloc_ok;
+
+ case R_XTENSA_PLT:
+ case R_XTENSA_TLSDESC_FN:
+ case R_XTENSA_TLSDESC_ARG:
+ case R_XTENSA_TLS_DTPOFF:
+ case R_XTENSA_TLS_TPOFF:
+ bfd_put_32 (abfd, relocation, contents + address);
+ return bfd_reloc_ok;
+ }
+
+ /* Only instruction slot-specific relocations handled below.... */
+ slot = get_relocation_slot (howto->type);
+ if (slot == XTENSA_UNDEFINED)
+ {
+ *error_message = "unexpected relocation";
+ return bfd_reloc_dangerous;
+ }
+
+ /* Read the instruction into a buffer and decode the opcode. */
+ xtensa_insnbuf_from_chars (isa, ibuff, contents + address,
+ input_size - address);
+ fmt = xtensa_format_decode (isa, ibuff);
+ if (fmt == XTENSA_UNDEFINED)
+ {
+ *error_message = "cannot decode instruction format";
+ return bfd_reloc_dangerous;
+ }
+
+ xtensa_format_get_slot (isa, fmt, slot, ibuff, sbuff);
+
+ opcode = xtensa_opcode_decode (isa, fmt, slot, sbuff);
+ if (opcode == XTENSA_UNDEFINED)
+ {
+ *error_message = "cannot decode instruction opcode";
+ return bfd_reloc_dangerous;
+ }
+
+ /* Check for opcode-specific "alternate" relocations. */
+ if (is_alt_relocation (howto->type))
+ {
+ if (opcode == get_l32r_opcode ())
+ {
+ /* Handle the special-case of non-PC-relative L32R instructions. */
+ bfd *output_bfd = input_section->output_section->owner;
+ asection *lit4_sec = bfd_get_section_by_name (output_bfd, ".lit4");
+ if (!lit4_sec)
+ {
+ *error_message = "relocation references missing .lit4 section";
+ return bfd_reloc_dangerous;
+ }
+ self_address = ((lit4_sec->vma & ~0xfff)
+ + 0x40000 - 3); /* -3 to compensate for do_reloc */
+ newval = relocation;
+ opnd = 1;
+ }
+ else if (opcode == get_const16_opcode ())
+ {
+ /* ALT used for high 16 bits. */
+ newval = relocation >> 16;
+ opnd = 1;
+ }
+ else
+ {
+ /* No other "alternate" relocations currently defined. */
+ *error_message = "unexpected relocation";
+ return bfd_reloc_dangerous;
+ }
+ }
+ else /* Not an "alternate" relocation.... */
+ {
+ if (opcode == get_const16_opcode ())
+ {
+ newval = relocation & 0xffff;
+ opnd = 1;
+ }
+ else
+ {
+ /* ...normal PC-relative relocation.... */
+
+ /* Determine which operand is being relocated. */
+ opnd = get_relocation_opnd (opcode, howto->type);
+ if (opnd == XTENSA_UNDEFINED)
+ {
+ *error_message = "unexpected relocation";
+ return bfd_reloc_dangerous;
+ }
+
+ if (!howto->pc_relative)
+ {
+ *error_message = "expected PC-relative relocation";
+ return bfd_reloc_dangerous;
+ }
+
+ newval = relocation;
+ }
+ }
+
+ /* Apply the relocation. */
+ if (xtensa_operand_do_reloc (isa, opcode, opnd, &newval, self_address)
+ || xtensa_operand_encode (isa, opcode, opnd, &newval)
+ || xtensa_operand_set_field (isa, opcode, opnd, fmt, slot,
+ sbuff, newval))
+ {
+ const char *opname = xtensa_opcode_name (isa, opcode);
+ const char *msg;
+
+ msg = "cannot encode";
+ if (is_direct_call_opcode (opcode))
+ {
+ if ((relocation & 0x3) != 0)
+ msg = "misaligned call target";
+ else
+ msg = "call target out of range";
+ }
+ else if (opcode == get_l32r_opcode ())
+ {
+ if ((relocation & 0x3) != 0)
+ msg = "misaligned literal target";
+ else if (is_alt_relocation (howto->type))
+ msg = "literal target out of range (too many literals)";
+ else if (self_address > relocation)
+ msg = "literal target out of range (try using text-section-literals)";
+ else
+ msg = "literal placed after use";
+ }
+
+ *error_message = vsprint_msg (opname, ": %s", strlen (msg) + 2, msg);
+ return bfd_reloc_dangerous;
+ }
+
+ /* Check for calls across 1GB boundaries. */
+ if (is_direct_call_opcode (opcode)
+ && is_windowed_call_opcode (opcode))
+ {
+ if ((self_address >> CALL_SEGMENT_BITS)
+ != (relocation >> CALL_SEGMENT_BITS))
+ {
+ *error_message =
+ "windowed call crosses 1GB boundary; return may fail";
+ return bfd_reloc_dangerous;
+ }
+ }
+
+ /* Write the modified instruction back out of the buffer. */
+ xtensa_format_set_slot (isa, fmt, slot, ibuff, sbuff);
+ xtensa_insnbuf_to_chars (isa, ibuff, contents + address,
+ input_size - address);
+ return bfd_reloc_ok;
+}
+
+
+static char *
+vsprint_msg (const char *origmsg, const char *fmt, int arglen, ...)
+{
+ /* To reduce the size of the memory leak,
+ we only use a single message buffer. */
+ static bfd_size_type alloc_size = 0;
+ static char *message = NULL;
+ bfd_size_type orig_len, len = 0;
+ bfd_boolean is_append;
+ va_list ap;
+
+ va_start (ap, arglen);
+
+ is_append = (origmsg == message);
+
+ orig_len = strlen (origmsg);
+ len = orig_len + strlen (fmt) + arglen + 20;
+ if (len > alloc_size)
+ {
+ message = (char *) bfd_realloc_or_free (message, len);
+ alloc_size = len;
+ }
+ if (message != NULL)
+ {
+ if (!is_append)
+ memcpy (message, origmsg, orig_len);
+ vsprintf (message + orig_len, fmt, ap);
+ }
+ va_end (ap);
+ return message;
+}
+
+
+/* This function is registered as the "special_function" in the
+ Xtensa howto for handling simplify operations.
+ bfd_perform_relocation / bfd_install_relocation use it to
+ perform (install) the specified relocation. Since this replaces the code
+ in bfd_perform_relocation, it is basically an Xtensa-specific,
+ stripped-down version of bfd_perform_relocation. */
+
+static bfd_reloc_status_type
+bfd_elf_xtensa_reloc (bfd *abfd,
+ arelent *reloc_entry,
+ asymbol *symbol,
+ void *data,
+ asection *input_section,
+ bfd *output_bfd,
+ char **error_message)
+{
+ bfd_vma relocation;
+ bfd_reloc_status_type flag;
+ bfd_size_type octets = reloc_entry->address * bfd_octets_per_byte (abfd);
+ bfd_vma output_base = 0;
+ reloc_howto_type *howto = reloc_entry->howto;
+ asection *reloc_target_output_section;
+ bfd_boolean is_weak_undef;
+
+ if (!xtensa_default_isa)
+ xtensa_default_isa = xtensa_isa_init (0, 0);
+
+ /* ELF relocs are against symbols. If we are producing relocatable
+ output, and the reloc is against an external symbol, 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. This test is similar
+ to what bfd_elf_generic_reloc does except that it lets relocs with
+ howto->partial_inplace go through even if the addend is non-zero.
+ (The real problem is that partial_inplace is set for XTENSA_32
+ relocs to begin with, but that's a long story and there's little we
+ can do about it now....) */
+
+ if (output_bfd && (symbol->flags & BSF_SECTION_SYM) == 0)
+ {
+ reloc_entry->address += input_section->output_offset;
+ return bfd_reloc_ok;
+ }
+
+ /* Is the address of the relocation really within the section? */
+ if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
+ return bfd_reloc_outofrange;
+
+ /* Work out which section the relocation is targeted 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)
+ || reloc_target_output_section == NULL)
+ 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 (output_bfd)
+ {
+ if (!howto->partial_inplace)
+ {
+ /* This is a partial relocation, and we want to apply the relocation
+ to the reloc entry rather than the raw data. Everything except
+ relocations against section symbols has already been handled
+ above. */
+
+ BFD_ASSERT (symbol->flags & BSF_SECTION_SYM);
+ reloc_entry->addend = relocation;
+ reloc_entry->address += input_section->output_offset;
+ return bfd_reloc_ok;
+ }
+ else
+ {
+ reloc_entry->address += input_section->output_offset;
+ reloc_entry->addend = 0;
+ }
+ }
+
+ is_weak_undef = (bfd_is_und_section (symbol->section)
+ && (symbol->flags & BSF_WEAK) != 0);
+ flag = elf_xtensa_do_reloc (howto, abfd, input_section, relocation,
+ (bfd_byte *) data, (bfd_vma) octets,
+ is_weak_undef, error_message);
+
+ if (flag == bfd_reloc_dangerous)
+ {
+ /* Add the symbol name to the error message. */
+ if (! *error_message)
+ *error_message = "";
+ *error_message = vsprint_msg (*error_message, ": (%s + 0x%lx)",
+ strlen (symbol->name) + 17,
+ symbol->name,
+ (unsigned long) reloc_entry->addend);
+ }
+
+ return flag;
+}
+
+
+/* Set up an entry in the procedure linkage table. */
+
+static bfd_vma
+elf_xtensa_create_plt_entry (struct bfd_link_info *info,
+ bfd *output_bfd,
+ unsigned reloc_index)
+{
+ asection *splt, *sgotplt;
+ bfd_vma plt_base, got_base;
+ bfd_vma code_offset, lit_offset;
+ int chunk;
+
+ chunk = reloc_index / PLT_ENTRIES_PER_CHUNK;
+ splt = elf_xtensa_get_plt_section (info, chunk);
+ sgotplt = elf_xtensa_get_gotplt_section (info, chunk);
+ BFD_ASSERT (splt != NULL && sgotplt != NULL);
+
+ plt_base = splt->output_section->vma + splt->output_offset;
+ got_base = sgotplt->output_section->vma + sgotplt->output_offset;
+
+ lit_offset = 8 + (reloc_index % PLT_ENTRIES_PER_CHUNK) * 4;
+ code_offset = (reloc_index % PLT_ENTRIES_PER_CHUNK) * PLT_ENTRY_SIZE;
+
+ /* Fill in the literal entry. This is the offset of the dynamic
+ relocation entry. */
+ bfd_put_32 (output_bfd, reloc_index * sizeof (Elf32_External_Rela),
+ sgotplt->contents + lit_offset);
+
+ /* Fill in the entry in the procedure linkage table. */
+ memcpy (splt->contents + code_offset,
+ (bfd_big_endian (output_bfd)
+ ? elf_xtensa_be_plt_entry
+ : elf_xtensa_le_plt_entry),
+ PLT_ENTRY_SIZE);
+ bfd_put_16 (output_bfd, l32r_offset (got_base + 0,
+ plt_base + code_offset + 3),
+ splt->contents + code_offset + 4);
+ bfd_put_16 (output_bfd, l32r_offset (got_base + 4,
+ plt_base + code_offset + 6),
+ splt->contents + code_offset + 7);
+ bfd_put_16 (output_bfd, l32r_offset (got_base + lit_offset,
+ plt_base + code_offset + 9),
+ splt->contents + code_offset + 10);
+
+ return plt_base + code_offset;
+}
+
+
+static bfd_boolean get_indirect_call_dest_reg (xtensa_opcode, unsigned *);
+
+static bfd_boolean
+replace_tls_insn (Elf_Internal_Rela *rel,
+ bfd *abfd,
+ asection *input_section,
+ bfd_byte *contents,
+ bfd_boolean is_ld_model,
+ char **error_message)
+{
+ static xtensa_insnbuf ibuff = NULL;
+ static xtensa_insnbuf sbuff = NULL;
+ xtensa_isa isa = xtensa_default_isa;
+ xtensa_format fmt;
+ xtensa_opcode old_op, new_op;
+ bfd_size_type input_size;
+ int r_type;
+ unsigned dest_reg, src_reg;
+
+ if (ibuff == NULL)
+ {
+ ibuff = xtensa_insnbuf_alloc (isa);
+ sbuff = xtensa_insnbuf_alloc (isa);
+ }
+
+ input_size = bfd_get_section_limit (abfd, input_section);
+
+ /* Read the instruction into a buffer and decode the opcode. */
+ xtensa_insnbuf_from_chars (isa, ibuff, contents + rel->r_offset,
+ input_size - rel->r_offset);
+ fmt = xtensa_format_decode (isa, ibuff);
+ if (fmt == XTENSA_UNDEFINED)
+ {
+ *error_message = "cannot decode instruction format";
+ return FALSE;
+ }
+
+ BFD_ASSERT (xtensa_format_num_slots (isa, fmt) == 1);
+ xtensa_format_get_slot (isa, fmt, 0, ibuff, sbuff);
+
+ old_op = xtensa_opcode_decode (isa, fmt, 0, sbuff);
+ if (old_op == XTENSA_UNDEFINED)
+ {
+ *error_message = "cannot decode instruction opcode";
+ return FALSE;
+ }
+
+ r_type = ELF32_R_TYPE (rel->r_info);
+ switch (r_type)
+ {
+ case R_XTENSA_TLS_FUNC:
+ case R_XTENSA_TLS_ARG:
+ if (old_op != get_l32r_opcode ()
+ || xtensa_operand_get_field (isa, old_op, 0, fmt, 0,
+ sbuff, &dest_reg) != 0)
+ {
+ *error_message = "cannot extract L32R destination for TLS access";
+ return FALSE;
+ }
+ break;
+
+ case R_XTENSA_TLS_CALL:
+ if (! get_indirect_call_dest_reg (old_op, &dest_reg)
+ || xtensa_operand_get_field (isa, old_op, 0, fmt, 0,
+ sbuff, &src_reg) != 0)
+ {
+ *error_message = "cannot extract CALLXn operands for TLS access";
+ return FALSE;
+ }
+ break;
+
+ default:
+ abort ();
+ }
+
+ if (is_ld_model)
+ {
+ switch (r_type)
+ {
+ case R_XTENSA_TLS_FUNC:
+ case R_XTENSA_TLS_ARG:
+ /* Change the instruction to a NOP (or "OR a1, a1, a1" for older
+ versions of Xtensa). */
+ new_op = xtensa_opcode_lookup (isa, "nop");
+ if (new_op == XTENSA_UNDEFINED)
+ {
+ new_op = xtensa_opcode_lookup (isa, "or");
+ if (new_op == XTENSA_UNDEFINED
+ || xtensa_opcode_encode (isa, fmt, 0, sbuff, new_op) != 0
+ || xtensa_operand_set_field (isa, new_op, 0, fmt, 0,
+ sbuff, 1) != 0
+ || xtensa_operand_set_field (isa, new_op, 1, fmt, 0,
+ sbuff, 1) != 0
+ || xtensa_operand_set_field (isa, new_op, 2, fmt, 0,
+ sbuff, 1) != 0)
+ {
+ *error_message = "cannot encode OR for TLS access";
+ return FALSE;
+ }
+ }
+ else
+ {
+ if (xtensa_opcode_encode (isa, fmt, 0, sbuff, new_op) != 0)
+ {
+ *error_message = "cannot encode NOP for TLS access";
+ return FALSE;
+ }
+ }
+ break;
+
+ case R_XTENSA_TLS_CALL:
+ /* Read THREADPTR into the CALLX's return value register. */
+ new_op = xtensa_opcode_lookup (isa, "rur.threadptr");
+ if (new_op == XTENSA_UNDEFINED
+ || xtensa_opcode_encode (isa, fmt, 0, sbuff, new_op) != 0
+ || xtensa_operand_set_field (isa, new_op, 0, fmt, 0,
+ sbuff, dest_reg + 2) != 0)
+ {
+ *error_message = "cannot encode RUR.THREADPTR for TLS access";
+ return FALSE;
+ }
+ break;
+ }
+ }
+ else
+ {
+ switch (r_type)
+ {
+ case R_XTENSA_TLS_FUNC:
+ new_op = xtensa_opcode_lookup (isa, "rur.threadptr");
+ if (new_op == XTENSA_UNDEFINED
+ || xtensa_opcode_encode (isa, fmt, 0, sbuff, new_op) != 0
+ || xtensa_operand_set_field (isa, new_op, 0, fmt, 0,
+ sbuff, dest_reg) != 0)
+ {
+ *error_message = "cannot encode RUR.THREADPTR for TLS access";
+ return FALSE;
+ }
+ break;
+
+ case R_XTENSA_TLS_ARG:
+ /* Nothing to do. Keep the original L32R instruction. */
+ return TRUE;
+
+ case R_XTENSA_TLS_CALL:
+ /* Add the CALLX's src register (holding the THREADPTR value)
+ to the first argument register (holding the offset) and put
+ the result in the CALLX's return value register. */
+ new_op = xtensa_opcode_lookup (isa, "add");
+ if (new_op == XTENSA_UNDEFINED
+ || xtensa_opcode_encode (isa, fmt, 0, sbuff, new_op) != 0
+ || xtensa_operand_set_field (isa, new_op, 0, fmt, 0,
+ sbuff, dest_reg + 2) != 0
+ || xtensa_operand_set_field (isa, new_op, 1, fmt, 0,
+ sbuff, dest_reg + 2) != 0
+ || xtensa_operand_set_field (isa, new_op, 2, fmt, 0,
+ sbuff, src_reg) != 0)
+ {
+ *error_message = "cannot encode ADD for TLS access";
+ return FALSE;
+ }
+ break;
+ }
+ }
+
+ xtensa_format_set_slot (isa, fmt, 0, ibuff, sbuff);
+ xtensa_insnbuf_to_chars (isa, ibuff, contents + rel->r_offset,
+ input_size - rel->r_offset);
+
+ return TRUE;
+}
+
+
+#define IS_XTENSA_TLS_RELOC(R_TYPE) \
+ ((R_TYPE) == R_XTENSA_TLSDESC_FN \
+ || (R_TYPE) == R_XTENSA_TLSDESC_ARG \
+ || (R_TYPE) == R_XTENSA_TLS_DTPOFF \
+ || (R_TYPE) == R_XTENSA_TLS_TPOFF \
+ || (R_TYPE) == R_XTENSA_TLS_FUNC \
+ || (R_TYPE) == R_XTENSA_TLS_ARG \
+ || (R_TYPE) == R_XTENSA_TLS_CALL)
+
+/* Relocate an Xtensa ELF section. This is invoked by the linker for
+ both relocatable and final links. */
+
+static bfd_boolean
+elf_xtensa_relocate_section (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)
+{
+ struct elf_xtensa_link_hash_table *htab;
+ Elf_Internal_Shdr *symtab_hdr;
+ Elf_Internal_Rela *rel;
+ Elf_Internal_Rela *relend;
+ struct elf_link_hash_entry **sym_hashes;
+ property_table_entry *lit_table = 0;
+ int ltblsize = 0;
+ char *local_got_tls_types;
+ char *error_message = NULL;
+ bfd_size_type input_size;
+ int tls_type;
+
+ if (!xtensa_default_isa)
+ xtensa_default_isa = xtensa_isa_init (0, 0);
+
+ BFD_ASSERT (is_xtensa_elf (input_bfd));
+
+ htab = elf_xtensa_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
+ sym_hashes = elf_sym_hashes (input_bfd);
+ local_got_tls_types = elf_xtensa_local_got_tls_type (input_bfd);
+
+ if (elf_hash_table (info)->dynamic_sections_created)
+ {
+ ltblsize = xtensa_read_table_entries (input_bfd, input_section,
+ &lit_table, XTENSA_LIT_SEC_NAME,
+ TRUE);
+ if (ltblsize < 0)
+ return FALSE;
+ }
+
+ input_size = bfd_get_section_limit (input_bfd, input_section);
+
+ 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;
+ char sym_type;
+ const char *name;
+ asection *sec;
+ bfd_vma relocation;
+ bfd_reloc_status_type r;
+ bfd_boolean is_weak_undef;
+ bfd_boolean unresolved_reloc;
+ bfd_boolean warned;
+ bfd_boolean dynamic_symbol;
+
+ r_type = ELF32_R_TYPE (rel->r_info);
+ if (r_type == (int) R_XTENSA_GNU_VTINHERIT
+ || r_type == (int) R_XTENSA_GNU_VTENTRY)
+ continue;
+
+ if (r_type < 0 || r_type >= (int) R_XTENSA_max)
+ {
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+ howto = &elf_howto_table[r_type];
+
+ r_symndx = ELF32_R_SYM (rel->r_info);
+
+ h = NULL;
+ sym = NULL;
+ sec = NULL;
+ is_weak_undef = FALSE;
+ unresolved_reloc = FALSE;
+ warned = FALSE;
+
+ if (howto->partial_inplace && !info->relocatable)
+ {
+ /* Because R_XTENSA_32 was made partial_inplace to fix some
+ problems with DWARF info in partial links, there may be
+ an addend stored in the contents. Take it out of there
+ and move it back into the addend field of the reloc. */
+ rel->r_addend += bfd_get_32 (input_bfd, contents + rel->r_offset);
+ bfd_put_32 (input_bfd, 0, contents + rel->r_offset);
+ }
+
+ if (r_symndx < symtab_hdr->sh_info)
+ {
+ sym = local_syms + r_symndx;
+ sym_type = ELF32_ST_TYPE (sym->st_info);
+ sec = local_sections[r_symndx];
+ relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
+ }
+ else
+ {
+ bfd_boolean ignored;
+
+ RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
+ r_symndx, symtab_hdr, sym_hashes,
+ h, sec, relocation,
+ unresolved_reloc, warned, ignored);
+
+ if (relocation == 0
+ && !unresolved_reloc
+ && h->root.type == bfd_link_hash_undefweak)
+ is_weak_undef = TRUE;
+
+ sym_type = h->type;
+ }
+
+ if (sec != NULL && discarded_section (sec))
+ RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+ rel, 1, relend, howto, 0, contents);
+
+ if (info->relocatable)
+ {
+ bfd_vma dest_addr;
+ asection * sym_sec = get_elf_r_symndx_section (input_bfd, r_symndx);
+
+ /* This is a relocatable link.
+ 1) If the reloc is against a section symbol, adjust
+ according to the output section.
+ 2) If there is a new target for this relocation,
+ the new target will be in the same output section.
+ We adjust the relocation by the output section
+ difference. */
+
+ if (relaxing_section)
+ {
+ /* Check if this references a section in another input file. */
+ if (!do_fix_for_relocatable_link (rel, input_bfd, input_section,
+ contents))
+ return FALSE;
+ }
+
+ dest_addr = sym_sec->output_section->vma + sym_sec->output_offset
+ + get_elf_r_symndx_offset (input_bfd, r_symndx) + rel->r_addend;
+
+ if (r_type == R_XTENSA_ASM_SIMPLIFY)
+ {
+ error_message = NULL;
+ /* Convert ASM_SIMPLIFY into the simpler relocation
+ so that they never escape a relaxing link. */
+ r = contract_asm_expansion (contents, input_size, rel,
+ &error_message);
+ if (r != bfd_reloc_ok)
+ {
+ if (!((*info->callbacks->reloc_dangerous)
+ (info, error_message, input_bfd, input_section,
+ rel->r_offset)))
+ return FALSE;
+ }
+ r_type = ELF32_R_TYPE (rel->r_info);
+ }
+
+ /* This is a relocatable link, so 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;
+ }
+ }
+
+ /* If there is an addend with a partial_inplace howto,
+ then move the addend to the contents. This is a hack
+ to work around problems with DWARF in relocatable links
+ with some previous version of BFD. Now we can't easily get
+ rid of the hack without breaking backward compatibility.... */
+ r = bfd_reloc_ok;
+ howto = &elf_howto_table[r_type];
+ if (howto->partial_inplace && rel->r_addend)
+ {
+ r = elf_xtensa_do_reloc (howto, input_bfd, input_section,
+ rel->r_addend, contents,
+ rel->r_offset, FALSE,
+ &error_message);
+ rel->r_addend = 0;
+ }
+ else
+ {
+ /* Put the correct bits in the target instruction, even
+ though the relocation will still be present in the output
+ file. This makes disassembly clearer, as well as
+ allowing loadable kernel modules to work without needing
+ relocations on anything other than calls and l32r's. */
+
+ /* If it is not in the same section, there is nothing we can do. */
+ if (r_type >= R_XTENSA_SLOT0_OP && r_type <= R_XTENSA_SLOT14_OP &&
+ sym_sec->output_section == input_section->output_section)
+ {
+ r = elf_xtensa_do_reloc (howto, input_bfd, input_section,
+ dest_addr, contents,
+ rel->r_offset, FALSE,
+ &error_message);
+ }
+ }
+ if (r != bfd_reloc_ok)
+ {
+ if (!((*info->callbacks->reloc_dangerous)
+ (info, error_message, input_bfd, input_section,
+ rel->r_offset)))
+ return FALSE;
+ }
+
+ /* Done with work for relocatable link; continue with next reloc. */
+ continue;
+ }
+
+ /* This is a final link. */
+
+ if (relaxing_section)
+ {
+ /* Check if this references a section in another input file. */
+ do_fix_for_final_link (rel, input_bfd, input_section, contents,
+ &relocation);
+ }
+
+ /* Sanity check the address. */
+ if (rel->r_offset >= input_size
+ && ELF32_R_TYPE (rel->r_info) != R_XTENSA_NONE)
+ {
+ (*_bfd_error_handler)
+ (_("%B(%A+0x%lx): relocation offset out of range (size=0x%x)"),
+ input_bfd, input_section, rel->r_offset, input_size);
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+
+ 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 (r_symndx != STN_UNDEF
+ && r_type != R_XTENSA_NONE
+ && (h == NULL
+ || h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak)
+ && IS_XTENSA_TLS_RELOC (r_type) != (sym_type == STT_TLS))
+ {
+ (*_bfd_error_handler)
+ ((sym_type == STT_TLS
+ ? _("%B(%A+0x%lx): %s used with TLS symbol %s")
+ : _("%B(%A+0x%lx): %s used with non-TLS symbol %s")),
+ input_bfd,
+ input_section,
+ (long) rel->r_offset,
+ howto->name,
+ name);
+ }
+
+ dynamic_symbol = elf_xtensa_dynamic_symbol_p (h, info);
+
+ tls_type = GOT_UNKNOWN;
+ if (h)
+ tls_type = elf_xtensa_hash_entry (h)->tls_type;
+ else if (local_got_tls_types)
+ tls_type = local_got_tls_types [r_symndx];
+
+ switch (r_type)
+ {
+ case R_XTENSA_32:
+ case R_XTENSA_PLT:
+ if (elf_hash_table (info)->dynamic_sections_created
+ && (input_section->flags & SEC_ALLOC) != 0
+ && (dynamic_symbol || info->shared))
+ {
+ Elf_Internal_Rela outrel;
+ bfd_byte *loc;
+ asection *srel;
+
+ if (dynamic_symbol && r_type == R_XTENSA_PLT)
+ srel = htab->srelplt;
+ else
+ srel = htab->srelgot;
+
+ BFD_ASSERT (srel != NULL);
+
+ outrel.r_offset =
+ _bfd_elf_section_offset (output_bfd, info,
+ input_section, rel->r_offset);
+
+ if ((outrel.r_offset | 1) == (bfd_vma) -1)
+ memset (&outrel, 0, sizeof outrel);
+ else
+ {
+ outrel.r_offset += (input_section->output_section->vma
+ + input_section->output_offset);
+
+ /* Complain if the relocation is in a read-only section
+ and not in a literal pool. */
+ if ((input_section->flags & SEC_READONLY) != 0
+ && !elf_xtensa_in_literal_pool (lit_table, ltblsize,
+ outrel.r_offset))
+ {
+ error_message =
+ _("dynamic relocation in read-only section");
+ if (!((*info->callbacks->reloc_dangerous)
+ (info, error_message, input_bfd, input_section,
+ rel->r_offset)))
+ return FALSE;
+ }
+
+ if (dynamic_symbol)
+ {
+ outrel.r_addend = rel->r_addend;
+ rel->r_addend = 0;
+
+ if (r_type == R_XTENSA_32)
+ {
+ outrel.r_info =
+ ELF32_R_INFO (h->dynindx, R_XTENSA_GLOB_DAT);
+ relocation = 0;
+ }
+ else /* r_type == R_XTENSA_PLT */
+ {
+ outrel.r_info =
+ ELF32_R_INFO (h->dynindx, R_XTENSA_JMP_SLOT);
+
+ /* Create the PLT entry and set the initial
+ contents of the literal entry to the address of
+ the PLT entry. */
+ relocation =
+ elf_xtensa_create_plt_entry (info, output_bfd,
+ srel->reloc_count);
+ }
+ unresolved_reloc = FALSE;
+ }
+ else
+ {
+ /* Generate a RELATIVE relocation. */
+ outrel.r_info = ELF32_R_INFO (0, R_XTENSA_RELATIVE);
+ outrel.r_addend = 0;
+ }
+ }
+
+ loc = (srel->contents
+ + srel->reloc_count++ * sizeof (Elf32_External_Rela));
+ bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
+ BFD_ASSERT (sizeof (Elf32_External_Rela) * srel->reloc_count
+ <= srel->size);
+ }
+ else if (r_type == R_XTENSA_ASM_EXPAND && dynamic_symbol)
+ {
+ /* This should only happen for non-PIC code, which is not
+ supposed to be used on systems with dynamic linking.
+ Just ignore these relocations. */
+ continue;
+ }
+ break;
+
+ case R_XTENSA_TLS_TPOFF:
+ /* Switch to LE model for local symbols in an executable. */
+ if (! info->shared && ! dynamic_symbol)
+ {
+ relocation = tpoff (info, relocation);
+ break;
+ }
+ /* fall through */
+
+ case R_XTENSA_TLSDESC_FN:
+ case R_XTENSA_TLSDESC_ARG:
+ {
+ if (r_type == R_XTENSA_TLSDESC_FN)
+ {
+ if (! info->shared || (tls_type & GOT_TLS_IE) != 0)
+ r_type = R_XTENSA_NONE;
+ }
+ else if (r_type == R_XTENSA_TLSDESC_ARG)
+ {
+ if (info->shared)
+ {
+ if ((tls_type & GOT_TLS_IE) != 0)
+ r_type = R_XTENSA_TLS_TPOFF;
+ }
+ else
+ {
+ r_type = R_XTENSA_TLS_TPOFF;
+ if (! dynamic_symbol)
+ {
+ relocation = tpoff (info, relocation);
+ break;
+ }
+ }
+ }
+
+ if (r_type == R_XTENSA_NONE)
+ /* Nothing to do here; skip to the next reloc. */
+ continue;
+
+ if (! elf_hash_table (info)->dynamic_sections_created)
+ {
+ error_message =
+ _("TLS relocation invalid without dynamic sections");
+ if (!((*info->callbacks->reloc_dangerous)
+ (info, error_message, input_bfd, input_section,
+ rel->r_offset)))
+ return FALSE;
+ }
+ else
+ {
+ Elf_Internal_Rela outrel;
+ bfd_byte *loc;
+ asection *srel = htab->srelgot;
+ int indx;
+
+ outrel.r_offset = (input_section->output_section->vma
+ + input_section->output_offset
+ + rel->r_offset);
+
+ /* Complain if the relocation is in a read-only section
+ and not in a literal pool. */
+ if ((input_section->flags & SEC_READONLY) != 0
+ && ! elf_xtensa_in_literal_pool (lit_table, ltblsize,
+ outrel.r_offset))
+ {
+ error_message =
+ _("dynamic relocation in read-only section");
+ if (!((*info->callbacks->reloc_dangerous)
+ (info, error_message, input_bfd, input_section,
+ rel->r_offset)))
+ return FALSE;
+ }
+
+ indx = h && h->dynindx != -1 ? h->dynindx : 0;
+ if (indx == 0)
+ outrel.r_addend = relocation - dtpoff_base (info);
+ else
+ outrel.r_addend = 0;
+ rel->r_addend = 0;
+
+ outrel.r_info = ELF32_R_INFO (indx, r_type);
+ relocation = 0;
+ unresolved_reloc = FALSE;
+
+ BFD_ASSERT (srel);
+ loc = (srel->contents
+ + srel->reloc_count++ * sizeof (Elf32_External_Rela));
+ bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
+ BFD_ASSERT (sizeof (Elf32_External_Rela) * srel->reloc_count
+ <= srel->size);
+ }
+ }
+ break;
+
+ case R_XTENSA_TLS_DTPOFF:
+ if (! info->shared)
+ /* Switch from LD model to LE model. */
+ relocation = tpoff (info, relocation);
+ else
+ relocation -= dtpoff_base (info);
+ break;
+
+ case R_XTENSA_TLS_FUNC:
+ case R_XTENSA_TLS_ARG:
+ case R_XTENSA_TLS_CALL:
+ /* Check if optimizing to IE or LE model. */
+ if ((tls_type & GOT_TLS_IE) != 0)
+ {
+ bfd_boolean is_ld_model =
+ (h && elf_xtensa_hash_entry (h) == htab->tlsbase);
+ if (! replace_tls_insn (rel, input_bfd, input_section, contents,
+ is_ld_model, &error_message))
+ {
+ if (!((*info->callbacks->reloc_dangerous)
+ (info, error_message, input_bfd, input_section,
+ rel->r_offset)))
+ return FALSE;
+ }
+
+ if (r_type != R_XTENSA_TLS_ARG || is_ld_model)
+ {
+ /* Skip subsequent relocations on the same instruction. */
+ while (rel + 1 < relend && rel[1].r_offset == rel->r_offset)
+ rel++;
+ }
+ }
+ continue;
+
+ default:
+ if (elf_hash_table (info)->dynamic_sections_created
+ && dynamic_symbol && (is_operand_relocation (r_type)
+ || r_type == R_XTENSA_32_PCREL))
+ {
+ error_message =
+ vsprint_msg ("invalid relocation for dynamic symbol", ": %s",
+ strlen (name) + 2, name);
+ if (!((*info->callbacks->reloc_dangerous)
+ (info, error_message, input_bfd, input_section,
+ rel->r_offset)))
+ return FALSE;
+ continue;
+ }
+ break;
+ }
+
+ /* Dynamic relocs are not propagated for SEC_DEBUGGING sections
+ because such sections are not SEC_ALLOC and thus ld.so will
+ not process them. */
+ if (unresolved_reloc
+ && !((input_section->flags & SEC_DEBUGGING) != 0
+ && h->def_dynamic)
+ && _bfd_elf_section_offset (output_bfd, info, input_section,
+ rel->r_offset) != (bfd_vma) -1)
+ {
+ (*_bfd_error_handler)
+ (_("%B(%A+0x%lx): unresolvable %s relocation against symbol `%s'"),
+ input_bfd,
+ input_section,
+ (long) rel->r_offset,
+ howto->name,
+ name);
+ return FALSE;
+ }
+
+ /* TLS optimizations may have changed r_type; update "howto". */
+ howto = &elf_howto_table[r_type];
+
+ /* There's no point in calling bfd_perform_relocation here.
+ Just go directly to our "special function". */
+ r = elf_xtensa_do_reloc (howto, input_bfd, input_section,
+ relocation + rel->r_addend,
+ contents, rel->r_offset, is_weak_undef,
+ &error_message);
+
+ if (r != bfd_reloc_ok && !warned)
+ {
+ BFD_ASSERT (r == bfd_reloc_dangerous || r == bfd_reloc_other);
+ BFD_ASSERT (error_message != NULL);
+
+ if (rel->r_addend == 0)
+ error_message = vsprint_msg (error_message, ": %s",
+ strlen (name) + 2, name);
+ else
+ error_message = vsprint_msg (error_message, ": (%s+0x%x)",
+ strlen (name) + 22,
+ name, (int) rel->r_addend);
+
+ if (!((*info->callbacks->reloc_dangerous)
+ (info, error_message, input_bfd, input_section,
+ rel->r_offset)))
+ return FALSE;
+ }
+ }
+
+ if (lit_table)
+ free (lit_table);
+
+ input_section->reloc_done = TRUE;
+
+ return TRUE;
+}
+
+
+/* Finish up dynamic symbol handling. There's not much to do here since
+ the PLT and GOT entries are all set up by relocate_section. */
+
+static bfd_boolean
+elf_xtensa_finish_dynamic_symbol (bfd *output_bfd ATTRIBUTE_UNUSED,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ struct elf_link_hash_entry *h,
+ Elf_Internal_Sym *sym)
+{
+ if (h->needs_plt && !h->def_regular)
+ {
+ /* Mark the symbol as undefined, rather than as defined in
+ the .plt section. Leave the value alone. */
+ sym->st_shndx = SHN_UNDEF;
+ /* If the symbol is weak, we do need to clear the value.
+ Otherwise, the PLT entry would provide a definition for
+ the symbol even if the symbol wasn't defined anywhere,
+ and so the symbol would never be NULL. */
+ if (!h->ref_regular_nonweak)
+ sym->st_value = 0;
+ }
+
+ /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute. */
+ if (h == elf_hash_table (info)->hdynamic
+ || h == elf_hash_table (info)->hgot)
+ sym->st_shndx = SHN_ABS;
+
+ return TRUE;
+}
+
+
+/* Combine adjacent literal table entries in the output. Adjacent
+ entries within each input section may have been removed during
+ relaxation, but we repeat the process here, even though it's too late
+ to shrink the output section, because it's important to minimize the
+ number of literal table entries to reduce the start-up work for the
+ runtime linker. Returns the number of remaining table entries or -1
+ on error. */
+
+static int
+elf_xtensa_combine_prop_entries (bfd *output_bfd,
+ asection *sxtlit,
+ asection *sgotloc)
+{
+ bfd_byte *contents;
+ property_table_entry *table;
+ bfd_size_type section_size, sgotloc_size;
+ bfd_vma offset;
+ int n, m, num;
+
+ section_size = sxtlit->size;
+ BFD_ASSERT (section_size % 8 == 0);
+ num = section_size / 8;
+
+ sgotloc_size = sgotloc->size;
+ if (sgotloc_size != section_size)
+ {
+ (*_bfd_error_handler)
+ (_("internal inconsistency in size of .got.loc section"));
+ return -1;
+ }
+
+ table = bfd_malloc (num * sizeof (property_table_entry));
+ if (table == 0)
+ return -1;
+
+ /* The ".xt.lit.plt" section has the SEC_IN_MEMORY flag set and this
+ propagates to the output section, where it doesn't really apply and
+ where it breaks the following call to bfd_malloc_and_get_section. */
+ sxtlit->flags &= ~SEC_IN_MEMORY;
+
+ if (!bfd_malloc_and_get_section (output_bfd, sxtlit, &contents))
+ {
+ if (contents != 0)
+ free (contents);
+ free (table);
+ return -1;
+ }
+
+ /* There should never be any relocations left at this point, so this
+ is quite a bit easier than what is done during relaxation. */
+
+ /* Copy the raw contents into a property table array and sort it. */
+ offset = 0;
+ for (n = 0; n < num; n++)
+ {
+ table[n].address = bfd_get_32 (output_bfd, &contents[offset]);
+ table[n].size = bfd_get_32 (output_bfd, &contents[offset + 4]);
+ offset += 8;
+ }
+ qsort (table, num, sizeof (property_table_entry), property_table_compare);
+
+ for (n = 0; n < num; n++)
+ {
+ bfd_boolean remove_entry = FALSE;
+
+ if (table[n].size == 0)
+ remove_entry = TRUE;
+ else if (n > 0
+ && (table[n-1].address + table[n-1].size == table[n].address))
+ {
+ table[n-1].size += table[n].size;
+ remove_entry = TRUE;
+ }
+
+ if (remove_entry)
+ {
+ for (m = n; m < num - 1; m++)
+ {
+ table[m].address = table[m+1].address;
+ table[m].size = table[m+1].size;
+ }
+
+ n--;
+ num--;
+ }
+ }
+
+ /* Copy the data back to the raw contents. */
+ offset = 0;
+ for (n = 0; n < num; n++)
+ {
+ bfd_put_32 (output_bfd, table[n].address, &contents[offset]);
+ bfd_put_32 (output_bfd, table[n].size, &contents[offset + 4]);
+ offset += 8;
+ }
+
+ /* Clear the removed bytes. */
+ if ((bfd_size_type) (num * 8) < section_size)
+ memset (&contents[num * 8], 0, section_size - num * 8);
+
+ if (! bfd_set_section_contents (output_bfd, sxtlit, contents, 0,
+ section_size))
+ return -1;
+
+ /* Copy the contents to ".got.loc". */
+ memcpy (sgotloc->contents, contents, section_size);
+
+ free (contents);
+ free (table);
+ return num;
+}
+
+
+/* Finish up the dynamic sections. */
+
+static bfd_boolean
+elf_xtensa_finish_dynamic_sections (bfd *output_bfd,
+ struct bfd_link_info *info)
+{
+ struct elf_xtensa_link_hash_table *htab;
+ bfd *dynobj;
+ asection *sdyn, *srelplt, *sgot, *sxtlit, *sgotloc;
+ Elf32_External_Dyn *dyncon, *dynconend;
+ int num_xtlit_entries = 0;
+
+ if (! elf_hash_table (info)->dynamic_sections_created)
+ return TRUE;
+
+ htab = elf_xtensa_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ dynobj = elf_hash_table (info)->dynobj;
+ sdyn = bfd_get_linker_section (dynobj, ".dynamic");
+ BFD_ASSERT (sdyn != NULL);
+
+ /* Set the first entry in the global offset table to the address of
+ the dynamic section. */
+ sgot = htab->sgot;
+ if (sgot)
+ {
+ BFD_ASSERT (sgot->size == 4);
+ if (sdyn == NULL)
+ bfd_put_32 (output_bfd, 0, sgot->contents);
+ else
+ bfd_put_32 (output_bfd,
+ sdyn->output_section->vma + sdyn->output_offset,
+ sgot->contents);
+ }
+
+ srelplt = htab->srelplt;
+ if (srelplt && srelplt->size != 0)
+ {
+ asection *sgotplt, *srelgot, *spltlittbl;
+ int chunk, plt_chunks, plt_entries;
+ Elf_Internal_Rela irela;
+ bfd_byte *loc;
+ unsigned rtld_reloc;
+
+ srelgot = htab->srelgot;
+ spltlittbl = htab->spltlittbl;
+ BFD_ASSERT (srelgot != NULL && spltlittbl != NULL);
+
+ /* Find the first XTENSA_RTLD relocation. Presumably the rest
+ of them follow immediately after.... */
+ for (rtld_reloc = 0; rtld_reloc < srelgot->reloc_count; rtld_reloc++)
+ {
+ loc = srelgot->contents + rtld_reloc * sizeof (Elf32_External_Rela);
+ bfd_elf32_swap_reloca_in (output_bfd, loc, &irela);
+ if (ELF32_R_TYPE (irela.r_info) == R_XTENSA_RTLD)
+ break;
+ }
+ BFD_ASSERT (rtld_reloc < srelgot->reloc_count);
+
+ plt_entries = srelplt->size / sizeof (Elf32_External_Rela);
+ plt_chunks =
+ (plt_entries + PLT_ENTRIES_PER_CHUNK - 1) / PLT_ENTRIES_PER_CHUNK;
+
+ for (chunk = 0; chunk < plt_chunks; chunk++)
+ {
+ int chunk_entries = 0;
+
+ sgotplt = elf_xtensa_get_gotplt_section (info, chunk);
+ BFD_ASSERT (sgotplt != NULL);
+
+ /* Emit special RTLD relocations for the first two entries in
+ each chunk of the .got.plt section. */
+
+ loc = srelgot->contents + rtld_reloc * sizeof (Elf32_External_Rela);
+ bfd_elf32_swap_reloca_in (output_bfd, loc, &irela);
+ BFD_ASSERT (ELF32_R_TYPE (irela.r_info) == R_XTENSA_RTLD);
+ irela.r_offset = (sgotplt->output_section->vma
+ + sgotplt->output_offset);
+ irela.r_addend = 1; /* tell rtld to set value to resolver function */
+ bfd_elf32_swap_reloca_out (output_bfd, &irela, loc);
+ rtld_reloc += 1;
+ BFD_ASSERT (rtld_reloc <= srelgot->reloc_count);
+
+ /* Next literal immediately follows the first. */
+ loc += sizeof (Elf32_External_Rela);
+ bfd_elf32_swap_reloca_in (output_bfd, loc, &irela);
+ BFD_ASSERT (ELF32_R_TYPE (irela.r_info) == R_XTENSA_RTLD);
+ irela.r_offset = (sgotplt->output_section->vma
+ + sgotplt->output_offset + 4);
+ /* Tell rtld to set value to object's link map. */
+ irela.r_addend = 2;
+ bfd_elf32_swap_reloca_out (output_bfd, &irela, loc);
+ rtld_reloc += 1;
+ BFD_ASSERT (rtld_reloc <= srelgot->reloc_count);
+
+ /* Fill in the literal table. */
+ if (chunk < plt_chunks - 1)
+ chunk_entries = PLT_ENTRIES_PER_CHUNK;
+ else
+ chunk_entries = plt_entries - (chunk * PLT_ENTRIES_PER_CHUNK);
+
+ BFD_ASSERT ((unsigned) (chunk + 1) * 8 <= spltlittbl->size);
+ bfd_put_32 (output_bfd,
+ sgotplt->output_section->vma + sgotplt->output_offset,
+ spltlittbl->contents + (chunk * 8) + 0);
+ bfd_put_32 (output_bfd,
+ 8 + (chunk_entries * 4),
+ spltlittbl->contents + (chunk * 8) + 4);
+ }
+
+ /* All the dynamic relocations have been emitted at this point.
+ Make sure the relocation sections are the correct size. */
+ if (srelgot->size != (sizeof (Elf32_External_Rela)
+ * srelgot->reloc_count)
+ || srelplt->size != (sizeof (Elf32_External_Rela)
+ * srelplt->reloc_count))
+ abort ();
+
+ /* The .xt.lit.plt section has just been modified. This must
+ happen before the code below which combines adjacent literal
+ table entries, and the .xt.lit.plt contents have to be forced to
+ the output here. */
+ if (! bfd_set_section_contents (output_bfd,
+ spltlittbl->output_section,
+ spltlittbl->contents,
+ spltlittbl->output_offset,
+ spltlittbl->size))
+ return FALSE;
+ /* Clear SEC_HAS_CONTENTS so the contents won't be output again. */
+ spltlittbl->flags &= ~SEC_HAS_CONTENTS;
+ }
+
+ /* Combine adjacent literal table entries. */
+ BFD_ASSERT (! info->relocatable);
+ sxtlit = bfd_get_section_by_name (output_bfd, ".xt.lit");
+ sgotloc = htab->sgotloc;
+ BFD_ASSERT (sgotloc);
+ if (sxtlit)
+ {
+ num_xtlit_entries =
+ elf_xtensa_combine_prop_entries (output_bfd, sxtlit, sgotloc);
+ if (num_xtlit_entries < 0)
+ return FALSE;
+ }
+
+ dyncon = (Elf32_External_Dyn *) sdyn->contents;
+ dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->size);
+ for (; dyncon < dynconend; dyncon++)
+ {
+ Elf_Internal_Dyn dyn;
+
+ bfd_elf32_swap_dyn_in (dynobj, dyncon, &dyn);
+
+ switch (dyn.d_tag)
+ {
+ default:
+ break;
+
+ case DT_XTENSA_GOT_LOC_SZ:
+ dyn.d_un.d_val = num_xtlit_entries;
+ break;
+
+ case DT_XTENSA_GOT_LOC_OFF:
+ dyn.d_un.d_ptr = htab->sgotloc->output_section->vma;
+ break;
+
+ case DT_PLTGOT:
+ dyn.d_un.d_ptr = htab->sgot->output_section->vma;
+ break;
+
+ case DT_JMPREL:
+ dyn.d_un.d_ptr = htab->srelplt->output_section->vma;
+ break;
+
+ case DT_PLTRELSZ:
+ dyn.d_un.d_val = htab->srelplt->output_section->size;
+ break;
+
+ case DT_RELASZ:
+ /* Adjust RELASZ to not include JMPREL. This matches what
+ glibc expects and what is done for several other ELF
+ targets (e.g., i386, alpha), but the "correct" behavior
+ seems to be unresolved. 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. */
+ if (htab->srelplt)
+ dyn.d_un.d_val -= htab->srelplt->output_section->size;
+ break;
+ }
+
+ bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
+ }
+
+ 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 bfd_boolean
+elf_xtensa_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
+{
+ unsigned out_mach, in_mach;
+ flagword out_flag, in_flag;
+
+ /* Check if we have the same endianness. */
+ if (!_bfd_generic_verify_endian_match (ibfd, obfd))
+ return FALSE;
+
+ /* Don't even pretend to support mixed-format linking. */
+ if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
+ || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
+ return FALSE;
+
+ out_flag = elf_elfheader (obfd)->e_flags;
+ in_flag = elf_elfheader (ibfd)->e_flags;
+
+ out_mach = out_flag & EF_XTENSA_MACH;
+ in_mach = in_flag & EF_XTENSA_MACH;
+ if (out_mach != in_mach)
+ {
+ (*_bfd_error_handler)
+ (_("%B: incompatible machine type. Output is 0x%x. Input is 0x%x"),
+ ibfd, out_mach, in_mach);
+ bfd_set_error (bfd_error_wrong_format);
+ return FALSE;
+ }
+
+ if (! elf_flags_init (obfd))
+ {
+ elf_flags_init (obfd) = TRUE;
+ elf_elfheader (obfd)->e_flags = in_flag;
+
+ 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;
+ }
+
+ if ((out_flag & EF_XTENSA_XT_INSN) != (in_flag & EF_XTENSA_XT_INSN))
+ elf_elfheader (obfd)->e_flags &= (~ EF_XTENSA_XT_INSN);
+
+ if ((out_flag & EF_XTENSA_XT_LIT) != (in_flag & EF_XTENSA_XT_LIT))
+ elf_elfheader (obfd)->e_flags &= (~ EF_XTENSA_XT_LIT);
+
+ return TRUE;
+}
+
+
+static bfd_boolean
+elf_xtensa_set_private_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;
+}
+
+
+static bfd_boolean
+elf_xtensa_print_private_bfd_data (bfd *abfd, void *farg)
+{
+ FILE *f = (FILE *) farg;
+ flagword e_flags = elf_elfheader (abfd)->e_flags;
+
+ fprintf (f, "\nXtensa header:\n");
+ if ((e_flags & EF_XTENSA_MACH) == E_XTENSA_MACH)
+ fprintf (f, "\nMachine = Base\n");
+ else
+ fprintf (f, "\nMachine Id = 0x%x\n", e_flags & EF_XTENSA_MACH);
+
+ fprintf (f, "Insn tables = %s\n",
+ (e_flags & EF_XTENSA_XT_INSN) ? "true" : "false");
+
+ fprintf (f, "Literal tables = %s\n",
+ (e_flags & EF_XTENSA_XT_LIT) ? "true" : "false");
+
+ return _bfd_elf_print_private_bfd_data (abfd, farg);
+}
+
+
+/* Set the right machine number for an Xtensa ELF file. */
+
+static bfd_boolean
+elf_xtensa_object_p (bfd *abfd)
+{
+ int mach;
+ unsigned long arch = elf_elfheader (abfd)->e_flags & EF_XTENSA_MACH;
+
+ switch (arch)
+ {
+ case E_XTENSA_MACH:
+ mach = bfd_mach_xtensa;
+ break;
+ default:
+ return FALSE;
+ }
+
+ (void) bfd_default_set_arch_mach (abfd, bfd_arch_xtensa, mach);
+ return TRUE;
+}
+
+
+/* The final processing done just before writing out an Xtensa ELF object
+ file. This gets the Xtensa architecture right based on the machine
+ number. */
+
+static void
+elf_xtensa_final_write_processing (bfd *abfd,
+ bfd_boolean linker ATTRIBUTE_UNUSED)
+{
+ int mach;
+ unsigned long val;
+
+ switch (mach = bfd_get_mach (abfd))
+ {
+ case bfd_mach_xtensa:
+ val = E_XTENSA_MACH;
+ break;
+ default:
+ return;
+ }
+
+ elf_elfheader (abfd)->e_flags &= (~ EF_XTENSA_MACH);
+ elf_elfheader (abfd)->e_flags |= val;
+}
+
+
+static enum elf_reloc_type_class
+elf_xtensa_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ const asection *rel_sec ATTRIBUTE_UNUSED,
+ const Elf_Internal_Rela *rela)
+{
+ switch ((int) ELF32_R_TYPE (rela->r_info))
+ {
+ case R_XTENSA_RELATIVE:
+ return reloc_class_relative;
+ case R_XTENSA_JMP_SLOT:
+ return reloc_class_plt;
+ default:
+ return reloc_class_normal;
+ }
+}
+
+
+static bfd_boolean
+elf_xtensa_discard_info_for_section (bfd *abfd,
+ struct elf_reloc_cookie *cookie,
+ struct bfd_link_info *info,
+ asection *sec)
+{
+ bfd_byte *contents;
+ bfd_vma offset, actual_offset;
+ bfd_size_type removed_bytes = 0;
+ bfd_size_type entry_size;
+
+ if (sec->output_section
+ && bfd_is_abs_section (sec->output_section))
+ return FALSE;
+
+ if (xtensa_is_proptable_section (sec))
+ entry_size = 12;
+ else
+ entry_size = 8;
+
+ if (sec->size == 0 || sec->size % entry_size != 0)
+ return FALSE;
+
+ contents = retrieve_contents (abfd, sec, info->keep_memory);
+ if (!contents)
+ return FALSE;
+
+ cookie->rels = retrieve_internal_relocs (abfd, sec, info->keep_memory);
+ if (!cookie->rels)
+ {
+ release_contents (sec, contents);
+ return FALSE;
+ }
+
+ /* Sort the relocations. They should already be in order when
+ relaxation is enabled, but it might not be. */
+ qsort (cookie->rels, sec->reloc_count, sizeof (Elf_Internal_Rela),
+ internal_reloc_compare);
+
+ cookie->rel = cookie->rels;
+ cookie->relend = cookie->rels + sec->reloc_count;
+
+ for (offset = 0; offset < sec->size; offset += entry_size)
+ {
+ actual_offset = offset - removed_bytes;
+
+ /* The ...symbol_deleted_p function will skip over relocs but it
+ won't adjust their offsets, so do that here. */
+ while (cookie->rel < cookie->relend
+ && cookie->rel->r_offset < offset)
+ {
+ cookie->rel->r_offset -= removed_bytes;
+ cookie->rel++;
+ }
+
+ while (cookie->rel < cookie->relend
+ && cookie->rel->r_offset == offset)
+ {
+ if (bfd_elf_reloc_symbol_deleted_p (offset, cookie))
+ {
+ /* Remove the table entry. (If the reloc type is NONE, then
+ the entry has already been merged with another and deleted
+ during relaxation.) */
+ if (ELF32_R_TYPE (cookie->rel->r_info) != R_XTENSA_NONE)
+ {
+ /* Shift the contents up. */
+ if (offset + entry_size < sec->size)
+ memmove (&contents[actual_offset],
+ &contents[actual_offset + entry_size],
+ sec->size - offset - entry_size);
+ removed_bytes += entry_size;
+ }
+
+ /* Remove this relocation. */
+ cookie->rel->r_info = ELF32_R_INFO (0, R_XTENSA_NONE);
+ }
+
+ /* Adjust the relocation offset for previous removals. This
+ should not be done before calling ...symbol_deleted_p
+ because it might mess up the offset comparisons there.
+ Make sure the offset doesn't underflow in the case where
+ the first entry is removed. */
+ if (cookie->rel->r_offset >= removed_bytes)
+ cookie->rel->r_offset -= removed_bytes;
+ else
+ cookie->rel->r_offset = 0;
+
+ cookie->rel++;
+ }
+ }
+
+ if (removed_bytes != 0)
+ {
+ /* Adjust any remaining relocs (shouldn't be any). */
+ for (; cookie->rel < cookie->relend; cookie->rel++)
+ {
+ if (cookie->rel->r_offset >= removed_bytes)
+ cookie->rel->r_offset -= removed_bytes;
+ else
+ cookie->rel->r_offset = 0;
+ }
+
+ /* Clear the removed bytes. */
+ memset (&contents[sec->size - removed_bytes], 0, removed_bytes);
+
+ pin_contents (sec, contents);
+ pin_internal_relocs (sec, cookie->rels);
+
+ /* Shrink size. */
+ if (sec->rawsize == 0)
+ sec->rawsize = sec->size;
+ sec->size -= removed_bytes;
+
+ if (xtensa_is_littable_section (sec))
+ {
+ asection *sgotloc = elf_xtensa_hash_table (info)->sgotloc;
+ if (sgotloc)
+ sgotloc->size -= removed_bytes;
+ }
+ }
+ else
+ {
+ release_contents (sec, contents);
+ release_internal_relocs (sec, cookie->rels);
+ }
+
+ return (removed_bytes != 0);
+}
+
+
+static bfd_boolean
+elf_xtensa_discard_info (bfd *abfd,
+ struct elf_reloc_cookie *cookie,
+ struct bfd_link_info *info)
+{
+ asection *sec;
+ bfd_boolean changed = FALSE;
+
+ for (sec = abfd->sections; sec != NULL; sec = sec->next)
+ {
+ if (xtensa_is_property_section (sec))
+ {
+ if (elf_xtensa_discard_info_for_section (abfd, cookie, info, sec))
+ changed = TRUE;
+ }
+ }
+
+ return changed;
+}
+
+
+static bfd_boolean
+elf_xtensa_ignore_discarded_relocs (asection *sec)
+{
+ return xtensa_is_property_section (sec);
+}
+
+
+static unsigned int
+elf_xtensa_action_discarded (asection *sec)
+{
+ if (strcmp (".xt_except_table", sec->name) == 0)
+ return 0;
+
+ if (strcmp (".xt_except_desc", sec->name) == 0)
+ return 0;
+
+ return _bfd_elf_default_action_discarded (sec);
+}
+
+
+/* Support for core dump NOTE sections. */
+
+static bfd_boolean
+elf_xtensa_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
+{
+ int offset;
+ unsigned int size;
+
+ /* The size for Xtensa is variable, so don't try to recognize the format
+ based on the size. Just assume this is GNU/Linux. */
+
+ /* pr_cursig */
+ elf_tdata (abfd)->core->signal = bfd_get_16 (abfd, note->descdata + 12);
+
+ /* pr_pid */
+ elf_tdata (abfd)->core->lwpid = bfd_get_32 (abfd, note->descdata + 24);
+
+ /* pr_reg */
+ offset = 72;
+ size = note->descsz - offset - 4;
+
+ /* Make a ".reg/999" section. */
+ return _bfd_elfcore_make_pseudosection (abfd, ".reg",
+ size, note->descpos + offset);
+}
+
+
+static bfd_boolean
+elf_xtensa_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
+{
+ switch (note->descsz)
+ {
+ default:
+ return FALSE;
+
+ case 128: /* GNU/Linux elf_prpsinfo */
+ elf_tdata (abfd)->core->program
+ = _bfd_elfcore_strndup (abfd, note->descdata + 32, 16);
+ elf_tdata (abfd)->core->command
+ = _bfd_elfcore_strndup (abfd, note->descdata + 48, 80);
+ }
+
+ /* 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;
+}
+
+
+/* Generic Xtensa configurability stuff. */
+
+static xtensa_opcode callx0_op = XTENSA_UNDEFINED;
+static xtensa_opcode callx4_op = XTENSA_UNDEFINED;
+static xtensa_opcode callx8_op = XTENSA_UNDEFINED;
+static xtensa_opcode callx12_op = XTENSA_UNDEFINED;
+static xtensa_opcode call0_op = XTENSA_UNDEFINED;
+static xtensa_opcode call4_op = XTENSA_UNDEFINED;
+static xtensa_opcode call8_op = XTENSA_UNDEFINED;
+static xtensa_opcode call12_op = XTENSA_UNDEFINED;
+
+static void
+init_call_opcodes (void)
+{
+ if (callx0_op == XTENSA_UNDEFINED)
+ {
+ callx0_op = xtensa_opcode_lookup (xtensa_default_isa, "callx0");
+ callx4_op = xtensa_opcode_lookup (xtensa_default_isa, "callx4");
+ callx8_op = xtensa_opcode_lookup (xtensa_default_isa, "callx8");
+ callx12_op = xtensa_opcode_lookup (xtensa_default_isa, "callx12");
+ call0_op = xtensa_opcode_lookup (xtensa_default_isa, "call0");
+ call4_op = xtensa_opcode_lookup (xtensa_default_isa, "call4");
+ call8_op = xtensa_opcode_lookup (xtensa_default_isa, "call8");
+ call12_op = xtensa_opcode_lookup (xtensa_default_isa, "call12");
+ }
+}
+
+
+static bfd_boolean
+is_indirect_call_opcode (xtensa_opcode opcode)
+{
+ init_call_opcodes ();
+ return (opcode == callx0_op
+ || opcode == callx4_op
+ || opcode == callx8_op
+ || opcode == callx12_op);
+}
+
+
+static bfd_boolean
+is_direct_call_opcode (xtensa_opcode opcode)
+{
+ init_call_opcodes ();
+ return (opcode == call0_op
+ || opcode == call4_op
+ || opcode == call8_op
+ || opcode == call12_op);
+}
+
+
+static bfd_boolean
+is_windowed_call_opcode (xtensa_opcode opcode)
+{
+ init_call_opcodes ();
+ return (opcode == call4_op
+ || opcode == call8_op
+ || opcode == call12_op
+ || opcode == callx4_op
+ || opcode == callx8_op
+ || opcode == callx12_op);
+}
+
+
+static bfd_boolean
+get_indirect_call_dest_reg (xtensa_opcode opcode, unsigned *pdst)
+{
+ unsigned dst = (unsigned) -1;
+
+ init_call_opcodes ();
+ if (opcode == callx0_op)
+ dst = 0;
+ else if (opcode == callx4_op)
+ dst = 4;
+ else if (opcode == callx8_op)
+ dst = 8;
+ else if (opcode == callx12_op)
+ dst = 12;
+
+ if (dst == (unsigned) -1)
+ return FALSE;
+
+ *pdst = dst;
+ return TRUE;
+}
+
+
+static xtensa_opcode
+get_const16_opcode (void)
+{
+ static bfd_boolean done_lookup = FALSE;
+ static xtensa_opcode const16_opcode = XTENSA_UNDEFINED;
+ if (!done_lookup)
+ {
+ const16_opcode = xtensa_opcode_lookup (xtensa_default_isa, "const16");
+ done_lookup = TRUE;
+ }
+ return const16_opcode;
+}
+
+
+static xtensa_opcode
+get_l32r_opcode (void)
+{
+ static xtensa_opcode l32r_opcode = XTENSA_UNDEFINED;
+ static bfd_boolean done_lookup = FALSE;
+
+ if (!done_lookup)
+ {
+ l32r_opcode = xtensa_opcode_lookup (xtensa_default_isa, "l32r");
+ done_lookup = TRUE;
+ }
+ return l32r_opcode;
+}
+
+
+static bfd_vma
+l32r_offset (bfd_vma addr, bfd_vma pc)
+{
+ bfd_vma offset;
+
+ offset = addr - ((pc+3) & -4);
+ BFD_ASSERT ((offset & ((1 << 2) - 1)) == 0);
+ offset = (signed int) offset >> 2;
+ BFD_ASSERT ((signed int) offset >> 16 == -1);
+ return offset;
+}
+
+
+static int
+get_relocation_opnd (xtensa_opcode opcode, int r_type)
+{
+ xtensa_isa isa = xtensa_default_isa;
+ int last_immed, last_opnd, opi;
+
+ if (opcode == XTENSA_UNDEFINED)
+ return XTENSA_UNDEFINED;
+
+ /* Find the last visible PC-relative immediate operand for the opcode.
+ If there are no PC-relative immediates, then choose the last visible
+ immediate; otherwise, fail and return XTENSA_UNDEFINED. */
+ last_immed = XTENSA_UNDEFINED;
+ last_opnd = xtensa_opcode_num_operands (isa, opcode);
+ for (opi = last_opnd - 1; opi >= 0; opi--)
+ {
+ if (xtensa_operand_is_visible (isa, opcode, opi) == 0)
+ continue;
+ if (xtensa_operand_is_PCrelative (isa, opcode, opi) == 1)
+ {
+ last_immed = opi;
+ break;
+ }
+ if (last_immed == XTENSA_UNDEFINED
+ && xtensa_operand_is_register (isa, opcode, opi) == 0)
+ last_immed = opi;
+ }
+ if (last_immed < 0)
+ return XTENSA_UNDEFINED;
+
+ /* If the operand number was specified in an old-style relocation,
+ check for consistency with the operand computed above. */
+ if (r_type >= R_XTENSA_OP0 && r_type <= R_XTENSA_OP2)
+ {
+ int reloc_opnd = r_type - R_XTENSA_OP0;
+ if (reloc_opnd != last_immed)
+ return XTENSA_UNDEFINED;
+ }
+
+ return last_immed;
+}
+
+
+int
+get_relocation_slot (int r_type)
+{
+ switch (r_type)
+ {
+ case R_XTENSA_OP0:
+ case R_XTENSA_OP1:
+ case R_XTENSA_OP2:
+ return 0;
+
+ default:
+ if (r_type >= R_XTENSA_SLOT0_OP && r_type <= R_XTENSA_SLOT14_OP)
+ return r_type - R_XTENSA_SLOT0_OP;
+ if (r_type >= R_XTENSA_SLOT0_ALT && r_type <= R_XTENSA_SLOT14_ALT)
+ return r_type - R_XTENSA_SLOT0_ALT;
+ break;
+ }
+
+ return XTENSA_UNDEFINED;
+}
+
+
+/* Get the opcode for a relocation. */
+
+static xtensa_opcode
+get_relocation_opcode (bfd *abfd,
+ asection *sec,
+ bfd_byte *contents,
+ Elf_Internal_Rela *irel)
+{
+ static xtensa_insnbuf ibuff = NULL;
+ static xtensa_insnbuf sbuff = NULL;
+ xtensa_isa isa = xtensa_default_isa;
+ xtensa_format fmt;
+ int slot;
+
+ if (contents == NULL)
+ return XTENSA_UNDEFINED;
+
+ if (bfd_get_section_limit (abfd, sec) <= irel->r_offset)
+ return XTENSA_UNDEFINED;
+
+ if (ibuff == NULL)
+ {
+ ibuff = xtensa_insnbuf_alloc (isa);
+ sbuff = xtensa_insnbuf_alloc (isa);
+ }
+
+ /* Decode the instruction. */
+ xtensa_insnbuf_from_chars (isa, ibuff, &contents[irel->r_offset],
+ sec->size - irel->r_offset);
+ fmt = xtensa_format_decode (isa, ibuff);
+ slot = get_relocation_slot (ELF32_R_TYPE (irel->r_info));
+ if (slot == XTENSA_UNDEFINED)
+ return XTENSA_UNDEFINED;
+ xtensa_format_get_slot (isa, fmt, slot, ibuff, sbuff);
+ return xtensa_opcode_decode (isa, fmt, slot, sbuff);
+}
+
+
+bfd_boolean
+is_l32r_relocation (bfd *abfd,
+ asection *sec,
+ bfd_byte *contents,
+ Elf_Internal_Rela *irel)
+{
+ xtensa_opcode opcode;
+ if (!is_operand_relocation (ELF32_R_TYPE (irel->r_info)))
+ return FALSE;
+ opcode = get_relocation_opcode (abfd, sec, contents, irel);
+ return (opcode == get_l32r_opcode ());
+}
+
+
+static bfd_size_type
+get_asm_simplify_size (bfd_byte *contents,
+ bfd_size_type content_len,
+ bfd_size_type offset)
+{
+ bfd_size_type insnlen, size = 0;
+
+ /* Decode the size of the next two instructions. */
+ insnlen = insn_decode_len (contents, content_len, offset);
+ if (insnlen == 0)
+ return 0;
+
+ size += insnlen;
+
+ insnlen = insn_decode_len (contents, content_len, offset + size);
+ if (insnlen == 0)
+ return 0;
+
+ size += insnlen;
+ return size;
+}
+
+
+bfd_boolean
+is_alt_relocation (int r_type)
+{
+ return (r_type >= R_XTENSA_SLOT0_ALT
+ && r_type <= R_XTENSA_SLOT14_ALT);
+}
+
+
+bfd_boolean
+is_operand_relocation (int r_type)
+{
+ switch (r_type)
+ {
+ case R_XTENSA_OP0:
+ case R_XTENSA_OP1:
+ case R_XTENSA_OP2:
+ return TRUE;
+
+ default:
+ if (r_type >= R_XTENSA_SLOT0_OP && r_type <= R_XTENSA_SLOT14_OP)
+ return TRUE;
+ if (r_type >= R_XTENSA_SLOT0_ALT && r_type <= R_XTENSA_SLOT14_ALT)
+ return TRUE;
+ break;
+ }
+
+ return FALSE;
+}
+
+
+#define MIN_INSN_LENGTH 2
+
+/* Return 0 if it fails to decode. */
+
+bfd_size_type
+insn_decode_len (bfd_byte *contents,
+ bfd_size_type content_len,
+ bfd_size_type offset)
+{
+ int insn_len;
+ xtensa_isa isa = xtensa_default_isa;
+ xtensa_format fmt;
+ static xtensa_insnbuf ibuff = NULL;
+
+ if (offset + MIN_INSN_LENGTH > content_len)
+ return 0;
+
+ if (ibuff == NULL)
+ ibuff = xtensa_insnbuf_alloc (isa);
+ xtensa_insnbuf_from_chars (isa, ibuff, &contents[offset],
+ content_len - offset);
+ fmt = xtensa_format_decode (isa, ibuff);
+ if (fmt == XTENSA_UNDEFINED)
+ return 0;
+ insn_len = xtensa_format_length (isa, fmt);
+ if (insn_len == XTENSA_UNDEFINED)
+ return 0;
+ return insn_len;
+}
+
+
+/* Decode the opcode for a single slot instruction.
+ Return 0 if it fails to decode or the instruction is multi-slot. */
+
+xtensa_opcode
+insn_decode_opcode (bfd_byte *contents,
+ bfd_size_type content_len,
+ bfd_size_type offset,
+ int slot)
+{
+ xtensa_isa isa = xtensa_default_isa;
+ xtensa_format fmt;
+ static xtensa_insnbuf insnbuf = NULL;
+ static xtensa_insnbuf slotbuf = NULL;
+
+ if (offset + MIN_INSN_LENGTH > content_len)
+ return XTENSA_UNDEFINED;
+
+ if (insnbuf == NULL)
+ {
+ insnbuf = xtensa_insnbuf_alloc (isa);
+ slotbuf = xtensa_insnbuf_alloc (isa);
+ }
+
+ xtensa_insnbuf_from_chars (isa, insnbuf, &contents[offset],
+ content_len - offset);
+ fmt = xtensa_format_decode (isa, insnbuf);
+ if (fmt == XTENSA_UNDEFINED)
+ return XTENSA_UNDEFINED;
+
+ if (slot >= xtensa_format_num_slots (isa, fmt))
+ return XTENSA_UNDEFINED;
+
+ xtensa_format_get_slot (isa, fmt, slot, insnbuf, slotbuf);
+ return xtensa_opcode_decode (isa, fmt, slot, slotbuf);
+}
+
+
+/* The offset is the offset in the contents.
+ The address is the address of that offset. */
+
+static bfd_boolean
+check_branch_target_aligned (bfd_byte *contents,
+ bfd_size_type content_length,
+ bfd_vma offset,
+ bfd_vma address)
+{
+ bfd_size_type insn_len = insn_decode_len (contents, content_length, offset);
+ if (insn_len == 0)
+ return FALSE;
+ return check_branch_target_aligned_address (address, insn_len);
+}
+
+
+static bfd_boolean
+check_loop_aligned (bfd_byte *contents,
+ bfd_size_type content_length,
+ bfd_vma offset,
+ bfd_vma address)
+{
+ bfd_size_type loop_len, insn_len;
+ xtensa_opcode opcode;
+
+ opcode = insn_decode_opcode (contents, content_length, offset, 0);
+ if (opcode == XTENSA_UNDEFINED
+ || xtensa_opcode_is_loop (xtensa_default_isa, opcode) != 1)
+ {
+ BFD_ASSERT (FALSE);
+ return FALSE;
+ }
+
+ loop_len = insn_decode_len (contents, content_length, offset);
+ insn_len = insn_decode_len (contents, content_length, offset + loop_len);
+ if (loop_len == 0 || insn_len == 0)
+ {
+ BFD_ASSERT (FALSE);
+ return FALSE;
+ }
+
+ return check_branch_target_aligned_address (address + loop_len, insn_len);
+}
+
+
+static bfd_boolean
+check_branch_target_aligned_address (bfd_vma addr, int len)
+{
+ if (len == 8)
+ return (addr % 8 == 0);
+ return ((addr >> 2) == ((addr + len - 1) >> 2));
+}
+
+
+/* Instruction widening and narrowing. */
+
+/* When FLIX is available we need to access certain instructions only
+ when they are 16-bit or 24-bit instructions. This table caches
+ information about such instructions by walking through all the
+ opcodes and finding the smallest single-slot format into which each
+ can be encoded. */
+
+static xtensa_format *op_single_fmt_table = NULL;
+
+
+static void
+init_op_single_format_table (void)
+{
+ xtensa_isa isa = xtensa_default_isa;
+ xtensa_insnbuf ibuf;
+ xtensa_opcode opcode;
+ xtensa_format fmt;
+ int num_opcodes;
+
+ if (op_single_fmt_table)
+ return;
+
+ ibuf = xtensa_insnbuf_alloc (isa);
+ num_opcodes = xtensa_isa_num_opcodes (isa);
+
+ op_single_fmt_table = (xtensa_format *)
+ bfd_malloc (sizeof (xtensa_format) * num_opcodes);
+ for (opcode = 0; opcode < num_opcodes; opcode++)
+ {
+ op_single_fmt_table[opcode] = XTENSA_UNDEFINED;
+ for (fmt = 0; fmt < xtensa_isa_num_formats (isa); fmt++)
+ {
+ if (xtensa_format_num_slots (isa, fmt) == 1
+ && xtensa_opcode_encode (isa, fmt, 0, ibuf, opcode) == 0)
+ {
+ xtensa_opcode old_fmt = op_single_fmt_table[opcode];
+ int fmt_length = xtensa_format_length (isa, fmt);
+ if (old_fmt == XTENSA_UNDEFINED
+ || fmt_length < xtensa_format_length (isa, old_fmt))
+ op_single_fmt_table[opcode] = fmt;
+ }
+ }
+ }
+ xtensa_insnbuf_free (isa, ibuf);
+}
+
+
+static xtensa_format
+get_single_format (xtensa_opcode opcode)
+{
+ init_op_single_format_table ();
+ return op_single_fmt_table[opcode];
+}
+
+
+/* For the set of narrowable instructions we do NOT include the
+ narrowings beqz -> beqz.n or bnez -> bnez.n because of complexities
+ involved during linker relaxation that may require these to
+ re-expand in some conditions. Also, the narrowing "or" -> mov.n
+ requires special case code to ensure it only works when op1 == op2. */
+
+struct string_pair
+{
+ const char *wide;
+ const char *narrow;
+};
+
+struct string_pair narrowable[] =
+{
+ { "add", "add.n" },
+ { "addi", "addi.n" },
+ { "addmi", "addi.n" },
+ { "l32i", "l32i.n" },
+ { "movi", "movi.n" },
+ { "ret", "ret.n" },
+ { "retw", "retw.n" },
+ { "s32i", "s32i.n" },
+ { "or", "mov.n" } /* special case only when op1 == op2 */
+};
+
+struct string_pair widenable[] =
+{
+ { "add", "add.n" },
+ { "addi", "addi.n" },
+ { "addmi", "addi.n" },
+ { "beqz", "beqz.n" },
+ { "bnez", "bnez.n" },
+ { "l32i", "l32i.n" },
+ { "movi", "movi.n" },
+ { "ret", "ret.n" },
+ { "retw", "retw.n" },
+ { "s32i", "s32i.n" },
+ { "or", "mov.n" } /* special case only when op1 == op2 */
+};
+
+
+/* Check if an instruction can be "narrowed", i.e., changed from a standard
+ 3-byte instruction to a 2-byte "density" instruction. If it is valid,
+ return the instruction buffer holding the narrow instruction. Otherwise,
+ return 0. The set of valid narrowing are specified by a string table
+ but require some special case operand checks in some cases. */
+
+static xtensa_insnbuf
+can_narrow_instruction (xtensa_insnbuf slotbuf,
+ xtensa_format fmt,
+ xtensa_opcode opcode)
+{
+ xtensa_isa isa = xtensa_default_isa;
+ xtensa_format o_fmt;
+ unsigned opi;
+
+ static xtensa_insnbuf o_insnbuf = NULL;
+ static xtensa_insnbuf o_slotbuf = NULL;
+
+ if (o_insnbuf == NULL)
+ {
+ o_insnbuf = xtensa_insnbuf_alloc (isa);
+ o_slotbuf = xtensa_insnbuf_alloc (isa);
+ }
+
+ for (opi = 0; opi < (sizeof (narrowable)/sizeof (struct string_pair)); opi++)
+ {
+ bfd_boolean is_or = (strcmp ("or", narrowable[opi].wide) == 0);
+
+ if (opcode == xtensa_opcode_lookup (isa, narrowable[opi].wide))
+ {
+ uint32 value, newval;
+ int i, operand_count, o_operand_count;
+ xtensa_opcode o_opcode;
+
+ /* Address does not matter in this case. We might need to
+ fix it to handle branches/jumps. */
+ bfd_vma self_address = 0;
+
+ o_opcode = xtensa_opcode_lookup (isa, narrowable[opi].narrow);
+ if (o_opcode == XTENSA_UNDEFINED)
+ return 0;
+ o_fmt = get_single_format (o_opcode);
+ if (o_fmt == XTENSA_UNDEFINED)
+ return 0;
+
+ if (xtensa_format_length (isa, fmt) != 3
+ || xtensa_format_length (isa, o_fmt) != 2)
+ return 0;
+
+ xtensa_format_encode (isa, o_fmt, o_insnbuf);
+ operand_count = xtensa_opcode_num_operands (isa, opcode);
+ o_operand_count = xtensa_opcode_num_operands (isa, o_opcode);
+
+ if (xtensa_opcode_encode (isa, o_fmt, 0, o_slotbuf, o_opcode) != 0)
+ return 0;
+
+ if (!is_or)
+ {
+ if (xtensa_opcode_num_operands (isa, o_opcode) != operand_count)
+ return 0;
+ }
+ else
+ {
+ uint32 rawval0, rawval1, rawval2;
+
+ if (o_operand_count + 1 != operand_count
+ || xtensa_operand_get_field (isa, opcode, 0,
+ fmt, 0, slotbuf, &rawval0) != 0
+ || xtensa_operand_get_field (isa, opcode, 1,
+ fmt, 0, slotbuf, &rawval1) != 0
+ || xtensa_operand_get_field (isa, opcode, 2,
+ fmt, 0, slotbuf, &rawval2) != 0
+ || rawval1 != rawval2
+ || rawval0 == rawval1 /* it is a nop */)
+ return 0;
+ }
+
+ for (i = 0; i < o_operand_count; ++i)
+ {
+ if (xtensa_operand_get_field (isa, opcode, i, fmt, 0,
+ slotbuf, &value)
+ || xtensa_operand_decode (isa, opcode, i, &value))
+ return 0;
+
+ /* PC-relative branches need adjustment, but
+ the PC-rel operand will always have a relocation. */
+ newval = value;
+ if (xtensa_operand_do_reloc (isa, o_opcode, i, &newval,
+ self_address)
+ || xtensa_operand_encode (isa, o_opcode, i, &newval)
+ || xtensa_operand_set_field (isa, o_opcode, i, o_fmt, 0,
+ o_slotbuf, newval))
+ return 0;
+ }
+
+ if (xtensa_format_set_slot (isa, o_fmt, 0, o_insnbuf, o_slotbuf))
+ return 0;
+
+ return o_insnbuf;
+ }
+ }
+ return 0;
+}
+
+
+/* Attempt to narrow an instruction. If the narrowing is valid, perform
+ the action in-place directly into the contents and return TRUE. Otherwise,
+ the return value is FALSE and the contents are not modified. */
+
+static bfd_boolean
+narrow_instruction (bfd_byte *contents,
+ bfd_size_type content_length,
+ bfd_size_type offset)
+{
+ xtensa_opcode opcode;
+ bfd_size_type insn_len;
+ xtensa_isa isa = xtensa_default_isa;
+ xtensa_format fmt;
+ xtensa_insnbuf o_insnbuf;
+
+ static xtensa_insnbuf insnbuf = NULL;
+ static xtensa_insnbuf slotbuf = NULL;
+
+ if (insnbuf == NULL)
+ {
+ insnbuf = xtensa_insnbuf_alloc (isa);
+ slotbuf = xtensa_insnbuf_alloc (isa);
+ }
+
+ BFD_ASSERT (offset < content_length);
+
+ if (content_length < 2)
+ return FALSE;
+
+ /* We will hand-code a few of these for a little while.
+ These have all been specified in the assembler aleady. */
+ xtensa_insnbuf_from_chars (isa, insnbuf, &contents[offset],
+ content_length - offset);
+ fmt = xtensa_format_decode (isa, insnbuf);
+ if (xtensa_format_num_slots (isa, fmt) != 1)
+ return FALSE;
+
+ if (xtensa_format_get_slot (isa, fmt, 0, insnbuf, slotbuf) != 0)
+ return FALSE;
+
+ opcode = xtensa_opcode_decode (isa, fmt, 0, slotbuf);
+ if (opcode == XTENSA_UNDEFINED)
+ return FALSE;
+ insn_len = xtensa_format_length (isa, fmt);
+ if (insn_len > content_length)
+ return FALSE;
+
+ o_insnbuf = can_narrow_instruction (slotbuf, fmt, opcode);
+ if (o_insnbuf)
+ {
+ xtensa_insnbuf_to_chars (isa, o_insnbuf, contents + offset,
+ content_length - offset);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+
+/* Check if an instruction can be "widened", i.e., changed from a 2-byte
+ "density" instruction to a standard 3-byte instruction. If it is valid,
+ return the instruction buffer holding the wide instruction. Otherwise,
+ return 0. The set of valid widenings are specified by a string table
+ but require some special case operand checks in some cases. */
+
+static xtensa_insnbuf
+can_widen_instruction (xtensa_insnbuf slotbuf,
+ xtensa_format fmt,
+ xtensa_opcode opcode)
+{
+ xtensa_isa isa = xtensa_default_isa;
+ xtensa_format o_fmt;
+ unsigned opi;
+
+ static xtensa_insnbuf o_insnbuf = NULL;
+ static xtensa_insnbuf o_slotbuf = NULL;
+
+ if (o_insnbuf == NULL)
+ {
+ o_insnbuf = xtensa_insnbuf_alloc (isa);
+ o_slotbuf = xtensa_insnbuf_alloc (isa);
+ }
+
+ for (opi = 0; opi < (sizeof (widenable)/sizeof (struct string_pair)); opi++)
+ {
+ bfd_boolean is_or = (strcmp ("or", widenable[opi].wide) == 0);
+ bfd_boolean is_branch = (strcmp ("beqz", widenable[opi].wide) == 0
+ || strcmp ("bnez", widenable[opi].wide) == 0);
+
+ if (opcode == xtensa_opcode_lookup (isa, widenable[opi].narrow))
+ {
+ uint32 value, newval;
+ int i, operand_count, o_operand_count, check_operand_count;
+ xtensa_opcode o_opcode;
+
+ /* Address does not matter in this case. We might need to fix it
+ to handle branches/jumps. */
+ bfd_vma self_address = 0;
+
+ o_opcode = xtensa_opcode_lookup (isa, widenable[opi].wide);
+ if (o_opcode == XTENSA_UNDEFINED)
+ return 0;
+ o_fmt = get_single_format (o_opcode);
+ if (o_fmt == XTENSA_UNDEFINED)
+ return 0;
+
+ if (xtensa_format_length (isa, fmt) != 2
+ || xtensa_format_length (isa, o_fmt) != 3)
+ return 0;
+
+ xtensa_format_encode (isa, o_fmt, o_insnbuf);
+ operand_count = xtensa_opcode_num_operands (isa, opcode);
+ o_operand_count = xtensa_opcode_num_operands (isa, o_opcode);
+ check_operand_count = o_operand_count;
+
+ if (xtensa_opcode_encode (isa, o_fmt, 0, o_slotbuf, o_opcode) != 0)
+ return 0;
+
+ if (!is_or)
+ {
+ if (xtensa_opcode_num_operands (isa, o_opcode) != operand_count)
+ return 0;
+ }
+ else
+ {
+ uint32 rawval0, rawval1;
+
+ if (o_operand_count != operand_count + 1
+ || xtensa_operand_get_field (isa, opcode, 0,
+ fmt, 0, slotbuf, &rawval0) != 0
+ || xtensa_operand_get_field (isa, opcode, 1,
+ fmt, 0, slotbuf, &rawval1) != 0
+ || rawval0 == rawval1 /* it is a nop */)
+ return 0;
+ }
+ if (is_branch)
+ check_operand_count--;
+
+ for (i = 0; i < check_operand_count; i++)
+ {
+ int new_i = i;
+ if (is_or && i == o_operand_count - 1)
+ new_i = i - 1;
+ if (xtensa_operand_get_field (isa, opcode, new_i, fmt, 0,
+ slotbuf, &value)
+ || xtensa_operand_decode (isa, opcode, new_i, &value))
+ return 0;
+
+ /* PC-relative branches need adjustment, but
+ the PC-rel operand will always have a relocation. */
+ newval = value;
+ if (xtensa_operand_do_reloc (isa, o_opcode, i, &newval,
+ self_address)
+ || xtensa_operand_encode (isa, o_opcode, i, &newval)
+ || xtensa_operand_set_field (isa, o_opcode, i, o_fmt, 0,
+ o_slotbuf, newval))
+ return 0;
+ }
+
+ if (xtensa_format_set_slot (isa, o_fmt, 0, o_insnbuf, o_slotbuf))
+ return 0;
+
+ return o_insnbuf;
+ }
+ }
+ return 0;
+}
+
+
+/* Attempt to widen an instruction. If the widening is valid, perform
+ the action in-place directly into the contents and return TRUE. Otherwise,
+ the return value is FALSE and the contents are not modified. */
+
+static bfd_boolean
+widen_instruction (bfd_byte *contents,
+ bfd_size_type content_length,
+ bfd_size_type offset)
+{
+ xtensa_opcode opcode;
+ bfd_size_type insn_len;
+ xtensa_isa isa = xtensa_default_isa;
+ xtensa_format fmt;
+ xtensa_insnbuf o_insnbuf;
+
+ static xtensa_insnbuf insnbuf = NULL;
+ static xtensa_insnbuf slotbuf = NULL;
+
+ if (insnbuf == NULL)
+ {
+ insnbuf = xtensa_insnbuf_alloc (isa);
+ slotbuf = xtensa_insnbuf_alloc (isa);
+ }
+
+ BFD_ASSERT (offset < content_length);
+
+ if (content_length < 2)
+ return FALSE;
+
+ /* We will hand-code a few of these for a little while.
+ These have all been specified in the assembler aleady. */
+ xtensa_insnbuf_from_chars (isa, insnbuf, &contents[offset],
+ content_length - offset);
+ fmt = xtensa_format_decode (isa, insnbuf);
+ if (xtensa_format_num_slots (isa, fmt) != 1)
+ return FALSE;
+
+ if (xtensa_format_get_slot (isa, fmt, 0, insnbuf, slotbuf) != 0)
+ return FALSE;
+
+ opcode = xtensa_opcode_decode (isa, fmt, 0, slotbuf);
+ if (opcode == XTENSA_UNDEFINED)
+ return FALSE;
+ insn_len = xtensa_format_length (isa, fmt);
+ if (insn_len > content_length)
+ return FALSE;
+
+ o_insnbuf = can_widen_instruction (slotbuf, fmt, opcode);
+ if (o_insnbuf)
+ {
+ xtensa_insnbuf_to_chars (isa, o_insnbuf, contents + offset,
+ content_length - offset);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+/* Code for transforming CALLs at link-time. */
+
+static bfd_reloc_status_type
+elf_xtensa_do_asm_simplify (bfd_byte *contents,
+ bfd_vma address,
+ bfd_vma content_length,
+ char **error_message)
+{
+ static xtensa_insnbuf insnbuf = NULL;
+ static xtensa_insnbuf slotbuf = NULL;
+ xtensa_format core_format = XTENSA_UNDEFINED;
+ xtensa_opcode opcode;
+ xtensa_opcode direct_call_opcode;
+ xtensa_isa isa = xtensa_default_isa;
+ bfd_byte *chbuf = contents + address;
+ int opn;
+
+ if (insnbuf == NULL)
+ {
+ insnbuf = xtensa_insnbuf_alloc (isa);
+ slotbuf = xtensa_insnbuf_alloc (isa);
+ }
+
+ if (content_length < address)
+ {
+ *error_message = _("Attempt to convert L32R/CALLX to CALL failed");
+ return bfd_reloc_other;
+ }
+
+ opcode = get_expanded_call_opcode (chbuf, content_length - address, 0);
+ direct_call_opcode = swap_callx_for_call_opcode (opcode);
+ if (direct_call_opcode == XTENSA_UNDEFINED)
+ {
+ *error_message = _("Attempt to convert L32R/CALLX to CALL failed");
+ return bfd_reloc_other;
+ }
+
+ /* Assemble a NOP ("or a1, a1, a1") into the 0 byte offset. */
+ core_format = xtensa_format_lookup (isa, "x24");
+ opcode = xtensa_opcode_lookup (isa, "or");
+ xtensa_opcode_encode (isa, core_format, 0, slotbuf, opcode);
+ for (opn = 0; opn < 3; opn++)
+ {
+ uint32 regno = 1;
+ xtensa_operand_encode (isa, opcode, opn, &regno);
+ xtensa_operand_set_field (isa, opcode, opn, core_format, 0,
+ slotbuf, regno);
+ }
+ xtensa_format_encode (isa, core_format, insnbuf);
+ xtensa_format_set_slot (isa, core_format, 0, insnbuf, slotbuf);
+ xtensa_insnbuf_to_chars (isa, insnbuf, chbuf, content_length - address);
+
+ /* Assemble a CALL ("callN 0") into the 3 byte offset. */
+ xtensa_opcode_encode (isa, core_format, 0, slotbuf, direct_call_opcode);
+ xtensa_operand_set_field (isa, opcode, 0, core_format, 0, slotbuf, 0);
+
+ xtensa_format_encode (isa, core_format, insnbuf);
+ xtensa_format_set_slot (isa, core_format, 0, insnbuf, slotbuf);
+ xtensa_insnbuf_to_chars (isa, insnbuf, chbuf + 3,
+ content_length - address - 3);
+
+ return bfd_reloc_ok;
+}
+
+
+static bfd_reloc_status_type
+contract_asm_expansion (bfd_byte *contents,
+ bfd_vma content_length,
+ Elf_Internal_Rela *irel,
+ char **error_message)
+{
+ bfd_reloc_status_type retval =
+ elf_xtensa_do_asm_simplify (contents, irel->r_offset, content_length,
+ error_message);
+
+ if (retval != bfd_reloc_ok)
+ return bfd_reloc_dangerous;
+
+ /* Update the irel->r_offset field so that the right immediate and
+ the right instruction are modified during the relocation. */
+ irel->r_offset += 3;
+ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info), R_XTENSA_SLOT0_OP);
+ return bfd_reloc_ok;
+}
+
+
+static xtensa_opcode
+swap_callx_for_call_opcode (xtensa_opcode opcode)
+{
+ init_call_opcodes ();
+
+ if (opcode == callx0_op) return call0_op;
+ if (opcode == callx4_op) return call4_op;
+ if (opcode == callx8_op) return call8_op;
+ if (opcode == callx12_op) return call12_op;
+
+ /* Return XTENSA_UNDEFINED if the opcode is not an indirect call. */
+ return XTENSA_UNDEFINED;
+}
+
+
+/* Check if "buf" is pointing to a "L32R aN; CALLX aN" or "CONST16 aN;
+ CONST16 aN; CALLX aN" sequence, and if so, return the CALLX opcode.
+ If not, return XTENSA_UNDEFINED. */
+
+#define L32R_TARGET_REG_OPERAND 0
+#define CONST16_TARGET_REG_OPERAND 0
+#define CALLN_SOURCE_OPERAND 0
+
+static xtensa_opcode
+get_expanded_call_opcode (bfd_byte *buf, int bufsize, bfd_boolean *p_uses_l32r)
+{
+ static xtensa_insnbuf insnbuf = NULL;
+ static xtensa_insnbuf slotbuf = NULL;
+ xtensa_format fmt;
+ xtensa_opcode opcode;
+ xtensa_isa isa = xtensa_default_isa;
+ uint32 regno, const16_regno, call_regno;
+ int offset = 0;
+
+ if (insnbuf == NULL)
+ {
+ insnbuf = xtensa_insnbuf_alloc (isa);
+ slotbuf = xtensa_insnbuf_alloc (isa);
+ }
+
+ xtensa_insnbuf_from_chars (isa, insnbuf, buf, bufsize);
+ fmt = xtensa_format_decode (isa, insnbuf);
+ if (fmt == XTENSA_UNDEFINED
+ || xtensa_format_get_slot (isa, fmt, 0, insnbuf, slotbuf))
+ return XTENSA_UNDEFINED;
+
+ opcode = xtensa_opcode_decode (isa, fmt, 0, slotbuf);
+ if (opcode == XTENSA_UNDEFINED)
+ return XTENSA_UNDEFINED;
+
+ if (opcode == get_l32r_opcode ())
+ {
+ if (p_uses_l32r)
+ *p_uses_l32r = TRUE;
+ if (xtensa_operand_get_field (isa, opcode, L32R_TARGET_REG_OPERAND,
+ fmt, 0, slotbuf, &regno)
+ || xtensa_operand_decode (isa, opcode, L32R_TARGET_REG_OPERAND,
+ &regno))
+ return XTENSA_UNDEFINED;
+ }
+ else if (opcode == get_const16_opcode ())
+ {
+ if (p_uses_l32r)
+ *p_uses_l32r = FALSE;
+ if (xtensa_operand_get_field (isa, opcode, CONST16_TARGET_REG_OPERAND,
+ fmt, 0, slotbuf, &regno)
+ || xtensa_operand_decode (isa, opcode, CONST16_TARGET_REG_OPERAND,
+ &regno))
+ return XTENSA_UNDEFINED;
+
+ /* Check that the next instruction is also CONST16. */
+ offset += xtensa_format_length (isa, fmt);
+ xtensa_insnbuf_from_chars (isa, insnbuf, buf + offset, bufsize - offset);
+ fmt = xtensa_format_decode (isa, insnbuf);
+ if (fmt == XTENSA_UNDEFINED
+ || xtensa_format_get_slot (isa, fmt, 0, insnbuf, slotbuf))
+ return XTENSA_UNDEFINED;
+ opcode = xtensa_opcode_decode (isa, fmt, 0, slotbuf);
+ if (opcode != get_const16_opcode ())
+ return XTENSA_UNDEFINED;
+
+ if (xtensa_operand_get_field (isa, opcode, CONST16_TARGET_REG_OPERAND,
+ fmt, 0, slotbuf, &const16_regno)
+ || xtensa_operand_decode (isa, opcode, CONST16_TARGET_REG_OPERAND,
+ &const16_regno)
+ || const16_regno != regno)
+ return XTENSA_UNDEFINED;
+ }
+ else
+ return XTENSA_UNDEFINED;
+
+ /* Next instruction should be an CALLXn with operand 0 == regno. */
+ offset += xtensa_format_length (isa, fmt);
+ xtensa_insnbuf_from_chars (isa, insnbuf, buf + offset, bufsize - offset);
+ fmt = xtensa_format_decode (isa, insnbuf);
+ if (fmt == XTENSA_UNDEFINED
+ || xtensa_format_get_slot (isa, fmt, 0, insnbuf, slotbuf))
+ return XTENSA_UNDEFINED;
+ opcode = xtensa_opcode_decode (isa, fmt, 0, slotbuf);
+ if (opcode == XTENSA_UNDEFINED
+ || !is_indirect_call_opcode (opcode))
+ return XTENSA_UNDEFINED;
+
+ if (xtensa_operand_get_field (isa, opcode, CALLN_SOURCE_OPERAND,
+ fmt, 0, slotbuf, &call_regno)
+ || xtensa_operand_decode (isa, opcode, CALLN_SOURCE_OPERAND,
+ &call_regno))
+ return XTENSA_UNDEFINED;
+
+ if (call_regno != regno)
+ return XTENSA_UNDEFINED;
+
+ return opcode;
+}
+
+
+/* Data structures used during relaxation. */
+
+/* r_reloc: relocation values. */
+
+/* Through the relaxation process, we need to keep track of the values
+ that will result from evaluating relocations. The standard ELF
+ relocation structure is not sufficient for this purpose because we're
+ operating on multiple input files at once, so we need to know which
+ input file a relocation refers to. The r_reloc structure thus
+ records both the input file (bfd) and ELF relocation.
+
+ For efficiency, an r_reloc also contains a "target_offset" field to
+ cache the target-section-relative offset value that is represented by
+ the relocation.
+
+ The r_reloc also contains a virtual offset that allows multiple
+ inserted literals to be placed at the same "address" with
+ different offsets. */
+
+typedef struct r_reloc_struct r_reloc;
+
+struct r_reloc_struct
+{
+ bfd *abfd;
+ Elf_Internal_Rela rela;
+ bfd_vma target_offset;
+ bfd_vma virtual_offset;
+};
+
+
+/* The r_reloc structure is included by value in literal_value, but not
+ every literal_value has an associated relocation -- some are simple
+ constants. In such cases, we set all the fields in the r_reloc
+ struct to zero. The r_reloc_is_const function should be used to
+ detect this case. */
+
+static bfd_boolean
+r_reloc_is_const (const r_reloc *r_rel)
+{
+ return (r_rel->abfd == NULL);
+}
+
+
+static bfd_vma
+r_reloc_get_target_offset (const r_reloc *r_rel)
+{
+ bfd_vma target_offset;
+ unsigned long r_symndx;
+
+ BFD_ASSERT (!r_reloc_is_const (r_rel));
+ r_symndx = ELF32_R_SYM (r_rel->rela.r_info);
+ target_offset = get_elf_r_symndx_offset (r_rel->abfd, r_symndx);
+ return (target_offset + r_rel->rela.r_addend);
+}
+
+
+static struct elf_link_hash_entry *
+r_reloc_get_hash_entry (const r_reloc *r_rel)
+{
+ unsigned long r_symndx = ELF32_R_SYM (r_rel->rela.r_info);
+ return get_elf_r_symndx_hash_entry (r_rel->abfd, r_symndx);
+}
+
+
+static asection *
+r_reloc_get_section (const r_reloc *r_rel)
+{
+ unsigned long r_symndx = ELF32_R_SYM (r_rel->rela.r_info);
+ return get_elf_r_symndx_section (r_rel->abfd, r_symndx);
+}
+
+
+static bfd_boolean
+r_reloc_is_defined (const r_reloc *r_rel)
+{
+ asection *sec;
+ if (r_rel == NULL)
+ return FALSE;
+
+ sec = r_reloc_get_section (r_rel);
+ if (sec == bfd_abs_section_ptr
+ || sec == bfd_com_section_ptr
+ || sec == bfd_und_section_ptr)
+ return FALSE;
+ return TRUE;
+}
+
+
+static void
+r_reloc_init (r_reloc *r_rel,
+ bfd *abfd,
+ Elf_Internal_Rela *irel,
+ bfd_byte *contents,
+ bfd_size_type content_length)
+{
+ int r_type;
+ reloc_howto_type *howto;
+
+ if (irel)
+ {
+ r_rel->rela = *irel;
+ r_rel->abfd = abfd;
+ r_rel->target_offset = r_reloc_get_target_offset (r_rel);
+ r_rel->virtual_offset = 0;
+ r_type = ELF32_R_TYPE (r_rel->rela.r_info);
+ howto = &elf_howto_table[r_type];
+ if (howto->partial_inplace)
+ {
+ bfd_vma inplace_val;
+ BFD_ASSERT (r_rel->rela.r_offset < content_length);
+
+ inplace_val = bfd_get_32 (abfd, &contents[r_rel->rela.r_offset]);
+ r_rel->target_offset += inplace_val;
+ }
+ }
+ else
+ memset (r_rel, 0, sizeof (r_reloc));
+}
+
+
+#if DEBUG
+
+static void
+print_r_reloc (FILE *fp, const r_reloc *r_rel)
+{
+ if (r_reloc_is_defined (r_rel))
+ {
+ asection *sec = r_reloc_get_section (r_rel);
+ fprintf (fp, " %s(%s + ", sec->owner->filename, sec->name);
+ }
+ else if (r_reloc_get_hash_entry (r_rel))
+ fprintf (fp, " %s + ", r_reloc_get_hash_entry (r_rel)->root.root.string);
+ else
+ fprintf (fp, " ?? + ");
+
+ fprintf_vma (fp, r_rel->target_offset);
+ if (r_rel->virtual_offset)
+ {
+ fprintf (fp, " + ");
+ fprintf_vma (fp, r_rel->virtual_offset);
+ }
+
+ fprintf (fp, ")");
+}
+
+#endif /* DEBUG */
+
+
+/* source_reloc: relocations that reference literals. */
+
+/* To determine whether literals can be coalesced, we need to first
+ record all the relocations that reference the literals. The
+ source_reloc structure below is used for this purpose. The
+ source_reloc entries are kept in a per-literal-section array, sorted
+ by offset within the literal section (i.e., target offset).
+
+ The source_sec and r_rel.rela.r_offset fields identify the source of
+ the relocation. The r_rel field records the relocation value, i.e.,
+ the offset of the literal being referenced. The opnd field is needed
+ to determine the range of the immediate field to which the relocation
+ applies, so we can determine whether another literal with the same
+ value is within range. The is_null field is true when the relocation
+ is being removed (e.g., when an L32R is being removed due to a CALLX
+ that is converted to a direct CALL). */
+
+typedef struct source_reloc_struct source_reloc;
+
+struct source_reloc_struct
+{
+ asection *source_sec;
+ r_reloc r_rel;
+ xtensa_opcode opcode;
+ int opnd;
+ bfd_boolean is_null;
+ bfd_boolean is_abs_literal;
+};
+
+
+static void
+init_source_reloc (source_reloc *reloc,
+ asection *source_sec,
+ const r_reloc *r_rel,
+ xtensa_opcode opcode,
+ int opnd,
+ bfd_boolean is_abs_literal)
+{
+ reloc->source_sec = source_sec;
+ reloc->r_rel = *r_rel;
+ reloc->opcode = opcode;
+ reloc->opnd = opnd;
+ reloc->is_null = FALSE;
+ reloc->is_abs_literal = is_abs_literal;
+}
+
+
+/* Find the source_reloc for a particular source offset and relocation
+ type. Note that the array is sorted by _target_ offset, so this is
+ just a linear search. */
+
+static source_reloc *
+find_source_reloc (source_reloc *src_relocs,
+ int src_count,
+ asection *sec,
+ Elf_Internal_Rela *irel)
+{
+ int i;
+
+ for (i = 0; i < src_count; i++)
+ {
+ if (src_relocs[i].source_sec == sec
+ && src_relocs[i].r_rel.rela.r_offset == irel->r_offset
+ && (ELF32_R_TYPE (src_relocs[i].r_rel.rela.r_info)
+ == ELF32_R_TYPE (irel->r_info)))
+ return &src_relocs[i];
+ }
+
+ return NULL;
+}
+
+
+static int
+source_reloc_compare (const void *ap, const void *bp)
+{
+ const source_reloc *a = (const source_reloc *) ap;
+ const source_reloc *b = (const source_reloc *) bp;
+
+ if (a->r_rel.target_offset != b->r_rel.target_offset)
+ return (a->r_rel.target_offset - b->r_rel.target_offset);
+
+ /* We don't need to sort on these criteria for correctness,
+ but enforcing a more strict ordering prevents unstable qsort
+ from behaving differently with different implementations.
+ Without the code below we get correct but different results
+ on Solaris 2.7 and 2.8. We would like to always produce the
+ same results no matter the host. */
+
+ if ((!a->is_null) - (!b->is_null))
+ return ((!a->is_null) - (!b->is_null));
+ return internal_reloc_compare (&a->r_rel.rela, &b->r_rel.rela);
+}
+
+
+/* Literal values and value hash tables. */
+
+/* Literals with the same value can be coalesced. The literal_value
+ structure records the value of a literal: the "r_rel" field holds the
+ information from the relocation on the literal (if there is one) and
+ the "value" field holds the contents of the literal word itself.
+
+ The value_map structure records a literal value along with the
+ location of a literal holding that value. The value_map hash table
+ is indexed by the literal value, so that we can quickly check if a
+ particular literal value has been seen before and is thus a candidate
+ for coalescing. */
+
+typedef struct literal_value_struct literal_value;
+typedef struct value_map_struct value_map;
+typedef struct value_map_hash_table_struct value_map_hash_table;
+
+struct literal_value_struct
+{
+ r_reloc r_rel;
+ unsigned long value;
+ bfd_boolean is_abs_literal;
+};
+
+struct value_map_struct
+{
+ literal_value val; /* The literal value. */
+ r_reloc loc; /* Location of the literal. */
+ value_map *next;
+};
+
+struct value_map_hash_table_struct
+{
+ unsigned bucket_count;
+ value_map **buckets;
+ unsigned count;
+ bfd_boolean has_last_loc;
+ r_reloc last_loc;
+};
+
+
+static void
+init_literal_value (literal_value *lit,
+ const r_reloc *r_rel,
+ unsigned long value,
+ bfd_boolean is_abs_literal)
+{
+ lit->r_rel = *r_rel;
+ lit->value = value;
+ lit->is_abs_literal = is_abs_literal;
+}
+
+
+static bfd_boolean
+literal_value_equal (const literal_value *src1,
+ const literal_value *src2,
+ bfd_boolean final_static_link)
+{
+ struct elf_link_hash_entry *h1, *h2;
+
+ if (r_reloc_is_const (&src1->r_rel) != r_reloc_is_const (&src2->r_rel))
+ return FALSE;
+
+ if (r_reloc_is_const (&src1->r_rel))
+ return (src1->value == src2->value);
+
+ if (ELF32_R_TYPE (src1->r_rel.rela.r_info)
+ != ELF32_R_TYPE (src2->r_rel.rela.r_info))
+ return FALSE;
+
+ if (src1->r_rel.target_offset != src2->r_rel.target_offset)
+ return FALSE;
+
+ if (src1->r_rel.virtual_offset != src2->r_rel.virtual_offset)
+ return FALSE;
+
+ if (src1->value != src2->value)
+ return FALSE;
+
+ /* Now check for the same section (if defined) or the same elf_hash
+ (if undefined or weak). */
+ h1 = r_reloc_get_hash_entry (&src1->r_rel);
+ h2 = r_reloc_get_hash_entry (&src2->r_rel);
+ if (r_reloc_is_defined (&src1->r_rel)
+ && (final_static_link
+ || ((!h1 || h1->root.type != bfd_link_hash_defweak)
+ && (!h2 || h2->root.type != bfd_link_hash_defweak))))
+ {
+ if (r_reloc_get_section (&src1->r_rel)
+ != r_reloc_get_section (&src2->r_rel))
+ return FALSE;
+ }
+ else
+ {
+ /* Require that the hash entries (i.e., symbols) be identical. */
+ if (h1 != h2 || h1 == 0)
+ return FALSE;
+ }
+
+ if (src1->is_abs_literal != src2->is_abs_literal)
+ return FALSE;
+
+ return TRUE;
+}
+
+
+/* Must be power of 2. */
+#define INITIAL_HASH_RELOC_BUCKET_COUNT 1024
+
+static value_map_hash_table *
+value_map_hash_table_init (void)
+{
+ value_map_hash_table *values;
+
+ values = (value_map_hash_table *)
+ bfd_zmalloc (sizeof (value_map_hash_table));
+ values->bucket_count = INITIAL_HASH_RELOC_BUCKET_COUNT;
+ values->count = 0;
+ values->buckets = (value_map **)
+ bfd_zmalloc (sizeof (value_map *) * values->bucket_count);
+ if (values->buckets == NULL)
+ {
+ free (values);
+ return NULL;
+ }
+ values->has_last_loc = FALSE;
+
+ return values;
+}
+
+
+static void
+value_map_hash_table_delete (value_map_hash_table *table)
+{
+ free (table->buckets);
+ free (table);
+}
+
+
+static unsigned
+hash_bfd_vma (bfd_vma val)
+{
+ return (val >> 2) + (val >> 10);
+}
+
+
+static unsigned
+literal_value_hash (const literal_value *src)
+{
+ unsigned hash_val;
+
+ hash_val = hash_bfd_vma (src->value);
+ if (!r_reloc_is_const (&src->r_rel))
+ {
+ void *sec_or_hash;
+
+ hash_val += hash_bfd_vma (src->is_abs_literal * 1000);
+ hash_val += hash_bfd_vma (src->r_rel.target_offset);
+ hash_val += hash_bfd_vma (src->r_rel.virtual_offset);
+
+ /* Now check for the same section and the same elf_hash. */
+ if (r_reloc_is_defined (&src->r_rel))
+ sec_or_hash = r_reloc_get_section (&src->r_rel);
+ else
+ sec_or_hash = r_reloc_get_hash_entry (&src->r_rel);
+ hash_val += hash_bfd_vma ((bfd_vma) (size_t) sec_or_hash);
+ }
+ return hash_val;
+}
+
+
+/* Check if the specified literal_value has been seen before. */
+
+static value_map *
+value_map_get_cached_value (value_map_hash_table *map,
+ const literal_value *val,
+ bfd_boolean final_static_link)
+{
+ value_map *map_e;
+ value_map *bucket;
+ unsigned idx;
+
+ idx = literal_value_hash (val);
+ idx = idx & (map->bucket_count - 1);
+ bucket = map->buckets[idx];
+ for (map_e = bucket; map_e; map_e = map_e->next)
+ {
+ if (literal_value_equal (&map_e->val, val, final_static_link))
+ return map_e;
+ }
+ return NULL;
+}
+
+
+/* Record a new literal value. It is illegal to call this if VALUE
+ already has an entry here. */
+
+static value_map *
+add_value_map (value_map_hash_table *map,
+ const literal_value *val,
+ const r_reloc *loc,
+ bfd_boolean final_static_link)
+{
+ value_map **bucket_p;
+ unsigned idx;
+
+ value_map *val_e = (value_map *) bfd_zmalloc (sizeof (value_map));
+ if (val_e == NULL)
+ {
+ bfd_set_error (bfd_error_no_memory);
+ return NULL;
+ }
+
+ BFD_ASSERT (!value_map_get_cached_value (map, val, final_static_link));
+ val_e->val = *val;
+ val_e->loc = *loc;
+
+ idx = literal_value_hash (val);
+ idx = idx & (map->bucket_count - 1);
+ bucket_p = &map->buckets[idx];
+
+ val_e->next = *bucket_p;
+ *bucket_p = val_e;
+ map->count++;
+ /* FIXME: Consider resizing the hash table if we get too many entries. */
+
+ return val_e;
+}
+
+
+/* Lists of text actions (ta_) for narrowing, widening, longcall
+ conversion, space fill, code & literal removal, etc. */
+
+/* The following text actions are generated:
+
+ "ta_remove_insn" remove an instruction or instructions
+ "ta_remove_longcall" convert longcall to call
+ "ta_convert_longcall" convert longcall to nop/call
+ "ta_narrow_insn" narrow a wide instruction
+ "ta_widen" widen a narrow instruction
+ "ta_fill" add fill or remove fill
+ removed < 0 is a fill; branches to the fill address will be
+ changed to address + fill size (e.g., address - removed)
+ removed >= 0 branches to the fill address will stay unchanged
+ "ta_remove_literal" remove a literal; this action is
+ indicated when a literal is removed
+ or replaced.
+ "ta_add_literal" insert a new literal; this action is
+ indicated when a literal has been moved.
+ It may use a virtual_offset because
+ multiple literals can be placed at the
+ same location.
+
+ For each of these text actions, we also record the number of bytes
+ removed by performing the text action. In the case of a "ta_widen"
+ or a "ta_fill" that adds space, the removed_bytes will be negative. */
+
+typedef struct text_action_struct text_action;
+typedef struct text_action_list_struct text_action_list;
+typedef enum text_action_enum_t text_action_t;
+
+enum text_action_enum_t
+{
+ ta_none,
+ ta_remove_insn, /* removed = -size */
+ ta_remove_longcall, /* removed = -size */
+ ta_convert_longcall, /* removed = 0 */
+ ta_narrow_insn, /* removed = -1 */
+ ta_widen_insn, /* removed = +1 */
+ ta_fill, /* removed = +size */
+ ta_remove_literal,
+ ta_add_literal
+};
+
+
+/* Structure for a text action record. */
+struct text_action_struct
+{
+ text_action_t action;
+ asection *sec; /* Optional */
+ bfd_vma offset;
+ bfd_vma virtual_offset; /* Zero except for adding literals. */
+ int removed_bytes;
+ literal_value value; /* Only valid when adding literals. */
+
+ text_action *next;
+};
+
+
+/* List of all of the actions taken on a text section. */
+struct text_action_list_struct
+{
+ text_action *head;
+};
+
+
+static text_action *
+find_fill_action (text_action_list *l, asection *sec, bfd_vma offset)
+{
+ text_action **m_p;
+
+ /* It is not necessary to fill at the end of a section. */
+ if (sec->size == offset)
+ return NULL;
+
+ for (m_p = &l->head; *m_p && (*m_p)->offset <= offset; m_p = &(*m_p)->next)
+ {
+ text_action *t = *m_p;
+ /* When the action is another fill at the same address,
+ just increase the size. */
+ if (t->offset == offset && t->action == ta_fill)
+ return t;
+ }
+ return NULL;
+}
+
+
+static int
+compute_removed_action_diff (const text_action *ta,
+ asection *sec,
+ bfd_vma offset,
+ int removed,
+ int removable_space)
+{
+ int new_removed;
+ int current_removed = 0;
+
+ if (ta)
+ current_removed = ta->removed_bytes;
+
+ BFD_ASSERT (ta == NULL || ta->offset == offset);
+ BFD_ASSERT (ta == NULL || ta->action == ta_fill);
+
+ /* It is not necessary to fill at the end of a section. Clean this up. */
+ if (sec->size == offset)
+ new_removed = removable_space - 0;
+ else
+ {
+ int space;
+ int added = -removed - current_removed;
+ /* Ignore multiples of the section alignment. */
+ added = ((1 << sec->alignment_power) - 1) & added;
+ new_removed = (-added);
+
+ /* Modify for removable. */
+ space = removable_space - new_removed;
+ new_removed = (removable_space
+ - (((1 << sec->alignment_power) - 1) & space));
+ }
+ return (new_removed - current_removed);
+}
+
+
+static void
+adjust_fill_action (text_action *ta, int fill_diff)
+{
+ ta->removed_bytes += fill_diff;
+}
+
+
+/* Add a modification action to the text. For the case of adding or
+ removing space, modify any current fill and assume that
+ "unreachable_space" bytes can be freely contracted. Note that a
+ negative removed value is a fill. */
+
+static void
+text_action_add (text_action_list *l,
+ text_action_t action,
+ asection *sec,
+ bfd_vma offset,
+ int removed)
+{
+ text_action **m_p;
+ text_action *ta;
+
+ /* It is not necessary to fill at the end of a section. */
+ if (action == ta_fill && sec->size == offset)
+ return;
+
+ /* It is not necessary to fill 0 bytes. */
+ if (action == ta_fill && removed == 0)
+ return;
+
+ for (m_p = &l->head; *m_p && (*m_p)->offset <= offset; m_p = &(*m_p)->next)
+ {
+ text_action *t = *m_p;
+
+ if (action == ta_fill)
+ {
+ /* When the action is another fill at the same address,
+ just increase the size. */
+ if (t->offset == offset && t->action == ta_fill)
+ {
+ t->removed_bytes += removed;
+ return;
+ }
+ /* Fills need to happen before widens so that we don't
+ insert fill bytes into the instruction stream. */
+ if (t->offset == offset && t->action == ta_widen_insn)
+ break;
+ }
+ }
+
+ /* Create a new record and fill it up. */
+ ta = (text_action *) bfd_zmalloc (sizeof (text_action));
+ ta->action = action;
+ ta->sec = sec;
+ ta->offset = offset;
+ ta->removed_bytes = removed;
+ ta->next = (*m_p);
+ *m_p = ta;
+}
+
+
+static void
+text_action_add_literal (text_action_list *l,
+ text_action_t action,
+ const r_reloc *loc,
+ const literal_value *value,
+ int removed)
+{
+ text_action **m_p;
+ text_action *ta;
+ asection *sec = r_reloc_get_section (loc);
+ bfd_vma offset = loc->target_offset;
+ bfd_vma virtual_offset = loc->virtual_offset;
+
+ BFD_ASSERT (action == ta_add_literal);
+
+ for (m_p = &l->head; *m_p != NULL; m_p = &(*m_p)->next)
+ {
+ if ((*m_p)->offset > offset
+ && ((*m_p)->offset != offset
+ || (*m_p)->virtual_offset > virtual_offset))
+ break;
+ }
+
+ /* Create a new record and fill it up. */
+ ta = (text_action *) bfd_zmalloc (sizeof (text_action));
+ ta->action = action;
+ ta->sec = sec;
+ ta->offset = offset;
+ ta->virtual_offset = virtual_offset;
+ ta->value = *value;
+ ta->removed_bytes = removed;
+ ta->next = (*m_p);
+ *m_p = ta;
+}
+
+
+/* Find the total offset adjustment for the relaxations specified by
+ text_actions, beginning from a particular starting action. This is
+ typically used from offset_with_removed_text to search an entire list of
+ actions, but it may also be called directly when adjusting adjacent offsets
+ so that each search may begin where the previous one left off. */
+
+static int
+removed_by_actions (text_action **p_start_action,
+ bfd_vma offset,
+ bfd_boolean before_fill)
+{
+ text_action *r;
+ int removed = 0;
+
+ r = *p_start_action;
+ while (r)
+ {
+ if (r->offset > offset)
+ break;
+
+ if (r->offset == offset
+ && (before_fill || r->action != ta_fill || r->removed_bytes >= 0))
+ break;
+
+ removed += r->removed_bytes;
+
+ r = r->next;
+ }
+
+ *p_start_action = r;
+ return removed;
+}
+
+
+static bfd_vma
+offset_with_removed_text (text_action_list *action_list, bfd_vma offset)
+{
+ text_action *r = action_list->head;
+ return offset - removed_by_actions (&r, offset, FALSE);
+}
+
+
+static unsigned
+action_list_count (text_action_list *action_list)
+{
+ text_action *r = action_list->head;
+ unsigned count = 0;
+ for (r = action_list->head; r != NULL; r = r->next)
+ {
+ count++;
+ }
+ return count;
+}
+
+
+/* The find_insn_action routine will only find non-fill actions. */
+
+static text_action *
+find_insn_action (text_action_list *action_list, bfd_vma offset)
+{
+ text_action *t;
+ for (t = action_list->head; t; t = t->next)
+ {
+ if (t->offset == offset)
+ {
+ switch (t->action)
+ {
+ case ta_none:
+ case ta_fill:
+ break;
+ case ta_remove_insn:
+ case ta_remove_longcall:
+ case ta_convert_longcall:
+ case ta_narrow_insn:
+ case ta_widen_insn:
+ return t;
+ case ta_remove_literal:
+ case ta_add_literal:
+ BFD_ASSERT (0);
+ break;
+ }
+ }
+ }
+ return NULL;
+}
+
+
+#if DEBUG
+
+static void
+print_action_list (FILE *fp, text_action_list *action_list)
+{
+ text_action *r;
+
+ fprintf (fp, "Text Action\n");
+ for (r = action_list->head; r != NULL; r = r->next)
+ {
+ const char *t = "unknown";
+ switch (r->action)
+ {
+ case ta_remove_insn:
+ t = "remove_insn"; break;
+ case ta_remove_longcall:
+ t = "remove_longcall"; break;
+ case ta_convert_longcall:
+ t = "convert_longcall"; break;
+ case ta_narrow_insn:
+ t = "narrow_insn"; break;
+ case ta_widen_insn:
+ t = "widen_insn"; break;
+ case ta_fill:
+ t = "fill"; break;
+ case ta_none:
+ t = "none"; break;
+ case ta_remove_literal:
+ t = "remove_literal"; break;
+ case ta_add_literal:
+ t = "add_literal"; break;
+ }
+
+ fprintf (fp, "%s: %s[0x%lx] \"%s\" %d\n",
+ r->sec->owner->filename,
+ r->sec->name, (unsigned long) r->offset, t, r->removed_bytes);
+ }
+}
+
+#endif /* DEBUG */
+
+
+/* Lists of literals being coalesced or removed. */
+
+/* In the usual case, the literal identified by "from" is being
+ coalesced with another literal identified by "to". If the literal is
+ unused and is being removed altogether, "to.abfd" will be NULL.
+ The removed_literal entries are kept on a per-section list, sorted
+ by the "from" offset field. */
+
+typedef struct removed_literal_struct removed_literal;
+typedef struct removed_literal_list_struct removed_literal_list;
+
+struct removed_literal_struct
+{
+ r_reloc from;
+ r_reloc to;
+ removed_literal *next;
+};
+
+struct removed_literal_list_struct
+{
+ removed_literal *head;
+ removed_literal *tail;
+};
+
+
+/* Record that the literal at "from" is being removed. If "to" is not
+ NULL, the "from" literal is being coalesced with the "to" literal. */
+
+static void
+add_removed_literal (removed_literal_list *removed_list,
+ const r_reloc *from,
+ const r_reloc *to)
+{
+ removed_literal *r, *new_r, *next_r;
+
+ new_r = (removed_literal *) bfd_zmalloc (sizeof (removed_literal));
+
+ new_r->from = *from;
+ if (to)
+ new_r->to = *to;
+ else
+ new_r->to.abfd = NULL;
+ new_r->next = NULL;
+
+ r = removed_list->head;
+ if (r == NULL)
+ {
+ removed_list->head = new_r;
+ removed_list->tail = new_r;
+ }
+ /* Special check for common case of append. */
+ else if (removed_list->tail->from.target_offset < from->target_offset)
+ {
+ removed_list->tail->next = new_r;
+ removed_list->tail = new_r;
+ }
+ else
+ {
+ while (r->from.target_offset < from->target_offset && r->next)
+ {
+ r = r->next;
+ }
+ next_r = r->next;
+ r->next = new_r;
+ new_r->next = next_r;
+ if (next_r == NULL)
+ removed_list->tail = new_r;
+ }
+}
+
+
+/* Check if the list of removed literals contains an entry for the
+ given address. Return the entry if found. */
+
+static removed_literal *
+find_removed_literal (removed_literal_list *removed_list, bfd_vma addr)
+{
+ removed_literal *r = removed_list->head;
+ while (r && r->from.target_offset < addr)
+ r = r->next;
+ if (r && r->from.target_offset == addr)
+ return r;
+ return NULL;
+}
+
+
+#if DEBUG
+
+static void
+print_removed_literals (FILE *fp, removed_literal_list *removed_list)
+{
+ removed_literal *r;
+ r = removed_list->head;
+ if (r)
+ fprintf (fp, "Removed Literals\n");
+ for (; r != NULL; r = r->next)
+ {
+ print_r_reloc (fp, &r->from);
+ fprintf (fp, " => ");
+ if (r->to.abfd == NULL)
+ fprintf (fp, "REMOVED");
+ else
+ print_r_reloc (fp, &r->to);
+ fprintf (fp, "\n");
+ }
+}
+
+#endif /* DEBUG */
+
+
+/* Per-section data for relaxation. */
+
+typedef struct reloc_bfd_fix_struct reloc_bfd_fix;
+
+struct xtensa_relax_info_struct
+{
+ bfd_boolean is_relaxable_literal_section;
+ bfd_boolean is_relaxable_asm_section;
+ int visited; /* Number of times visited. */
+
+ source_reloc *src_relocs; /* Array[src_count]. */
+ int src_count;
+ int src_next; /* Next src_relocs entry to assign. */
+
+ removed_literal_list removed_list;
+ text_action_list action_list;
+
+ reloc_bfd_fix *fix_list;
+ reloc_bfd_fix *fix_array;
+ unsigned fix_array_count;
+
+ /* Support for expanding the reloc array that is stored
+ in the section structure. If the relocations have been
+ reallocated, the newly allocated relocations will be referenced
+ here along with the actual size allocated. The relocation
+ count will always be found in the section structure. */
+ Elf_Internal_Rela *allocated_relocs;
+ unsigned relocs_count;
+ unsigned allocated_relocs_count;
+};
+
+struct elf_xtensa_section_data
+{
+ struct bfd_elf_section_data elf;
+ xtensa_relax_info relax_info;
+};
+
+
+static bfd_boolean
+elf_xtensa_new_section_hook (bfd *abfd, asection *sec)
+{
+ if (!sec->used_by_bfd)
+ {
+ struct elf_xtensa_section_data *sdata;
+ bfd_size_type amt = sizeof (*sdata);
+
+ sdata = bfd_zalloc (abfd, amt);
+ if (sdata == NULL)
+ return FALSE;
+ sec->used_by_bfd = sdata;
+ }
+
+ return _bfd_elf_new_section_hook (abfd, sec);
+}
+
+
+static xtensa_relax_info *
+get_xtensa_relax_info (asection *sec)
+{
+ struct elf_xtensa_section_data *section_data;
+
+ /* No info available if no section or if it is an output section. */
+ if (!sec || sec == sec->output_section)
+ return NULL;
+
+ section_data = (struct elf_xtensa_section_data *) elf_section_data (sec);
+ return &section_data->relax_info;
+}
+
+
+static void
+init_xtensa_relax_info (asection *sec)
+{
+ xtensa_relax_info *relax_info = get_xtensa_relax_info (sec);
+
+ relax_info->is_relaxable_literal_section = FALSE;
+ relax_info->is_relaxable_asm_section = FALSE;
+ relax_info->visited = 0;
+
+ relax_info->src_relocs = NULL;
+ relax_info->src_count = 0;
+ relax_info->src_next = 0;
+
+ relax_info->removed_list.head = NULL;
+ relax_info->removed_list.tail = NULL;
+
+ relax_info->action_list.head = NULL;
+
+ relax_info->fix_list = NULL;
+ relax_info->fix_array = NULL;
+ relax_info->fix_array_count = 0;
+
+ relax_info->allocated_relocs = NULL;
+ relax_info->relocs_count = 0;
+ relax_info->allocated_relocs_count = 0;
+}
+
+
+/* Coalescing literals may require a relocation to refer to a section in
+ a different input file, but the standard relocation information
+ cannot express that. Instead, the reloc_bfd_fix structures are used
+ to "fix" the relocations that refer to sections in other input files.
+ These structures are kept on per-section lists. The "src_type" field
+ records the relocation type in case there are multiple relocations on
+ the same location. FIXME: This is ugly; an alternative might be to
+ add new symbols with the "owner" field to some other input file. */
+
+struct reloc_bfd_fix_struct
+{
+ asection *src_sec;
+ bfd_vma src_offset;
+ unsigned src_type; /* Relocation type. */
+
+ asection *target_sec;
+ bfd_vma target_offset;
+ bfd_boolean translated;
+
+ reloc_bfd_fix *next;
+};
+
+
+static reloc_bfd_fix *
+reloc_bfd_fix_init (asection *src_sec,
+ bfd_vma src_offset,
+ unsigned src_type,
+ asection *target_sec,
+ bfd_vma target_offset,
+ bfd_boolean translated)
+{
+ reloc_bfd_fix *fix;
+
+ fix = (reloc_bfd_fix *) bfd_malloc (sizeof (reloc_bfd_fix));
+ fix->src_sec = src_sec;
+ fix->src_offset = src_offset;
+ fix->src_type = src_type;
+ fix->target_sec = target_sec;
+ fix->target_offset = target_offset;
+ fix->translated = translated;
+
+ return fix;
+}
+
+
+static void
+add_fix (asection *src_sec, reloc_bfd_fix *fix)
+{
+ xtensa_relax_info *relax_info;
+
+ relax_info = get_xtensa_relax_info (src_sec);
+ fix->next = relax_info->fix_list;
+ relax_info->fix_list = fix;
+}
+
+
+static int
+fix_compare (const void *ap, const void *bp)
+{
+ const reloc_bfd_fix *a = (const reloc_bfd_fix *) ap;
+ const reloc_bfd_fix *b = (const reloc_bfd_fix *) bp;
+
+ if (a->src_offset != b->src_offset)
+ return (a->src_offset - b->src_offset);
+ return (a->src_type - b->src_type);
+}
+
+
+static void
+cache_fix_array (asection *sec)
+{
+ unsigned i, count = 0;
+ reloc_bfd_fix *r;
+ xtensa_relax_info *relax_info = get_xtensa_relax_info (sec);
+
+ if (relax_info == NULL)
+ return;
+ if (relax_info->fix_list == NULL)
+ return;
+
+ for (r = relax_info->fix_list; r != NULL; r = r->next)
+ count++;
+
+ relax_info->fix_array =
+ (reloc_bfd_fix *) bfd_malloc (sizeof (reloc_bfd_fix) * count);
+ relax_info->fix_array_count = count;
+
+ r = relax_info->fix_list;
+ for (i = 0; i < count; i++, r = r->next)
+ {
+ relax_info->fix_array[count - 1 - i] = *r;
+ relax_info->fix_array[count - 1 - i].next = NULL;
+ }
+
+ qsort (relax_info->fix_array, relax_info->fix_array_count,
+ sizeof (reloc_bfd_fix), fix_compare);
+}
+
+
+static reloc_bfd_fix *
+get_bfd_fix (asection *sec, bfd_vma offset, unsigned type)
+{
+ xtensa_relax_info *relax_info = get_xtensa_relax_info (sec);
+ reloc_bfd_fix *rv;
+ reloc_bfd_fix key;
+
+ if (relax_info == NULL)
+ return NULL;
+ if (relax_info->fix_list == NULL)
+ return NULL;
+
+ if (relax_info->fix_array == NULL)
+ cache_fix_array (sec);
+
+ key.src_offset = offset;
+ key.src_type = type;
+ rv = bsearch (&key, relax_info->fix_array, relax_info->fix_array_count,
+ sizeof (reloc_bfd_fix), fix_compare);
+ return rv;
+}
+
+
+/* Section caching. */
+
+typedef struct section_cache_struct section_cache_t;
+
+struct section_cache_struct
+{
+ asection *sec;
+
+ bfd_byte *contents; /* Cache of the section contents. */
+ bfd_size_type content_length;
+
+ property_table_entry *ptbl; /* Cache of the section property table. */
+ unsigned pte_count;
+
+ Elf_Internal_Rela *relocs; /* Cache of the section relocations. */
+ unsigned reloc_count;
+};
+
+
+static void
+init_section_cache (section_cache_t *sec_cache)
+{
+ memset (sec_cache, 0, sizeof (*sec_cache));
+}
+
+
+static void
+free_section_cache (section_cache_t *sec_cache)
+{
+ if (sec_cache->sec)
+ {
+ release_contents (sec_cache->sec, sec_cache->contents);
+ release_internal_relocs (sec_cache->sec, sec_cache->relocs);
+ if (sec_cache->ptbl)
+ free (sec_cache->ptbl);
+ }
+}
+
+
+static bfd_boolean
+section_cache_section (section_cache_t *sec_cache,
+ asection *sec,
+ struct bfd_link_info *link_info)
+{
+ bfd *abfd;
+ property_table_entry *prop_table = NULL;
+ int ptblsize = 0;
+ bfd_byte *contents = NULL;
+ Elf_Internal_Rela *internal_relocs = NULL;
+ bfd_size_type sec_size;
+
+ if (sec == NULL)
+ return FALSE;
+ if (sec == sec_cache->sec)
+ return TRUE;
+
+ abfd = sec->owner;
+ sec_size = bfd_get_section_limit (abfd, sec);
+
+ /* Get the contents. */
+ contents = retrieve_contents (abfd, sec, link_info->keep_memory);
+ if (contents == NULL && sec_size != 0)
+ goto err;
+
+ /* Get the relocations. */
+ internal_relocs = retrieve_internal_relocs (abfd, sec,
+ link_info->keep_memory);
+
+ /* Get the entry table. */
+ ptblsize = xtensa_read_table_entries (abfd, sec, &prop_table,
+ XTENSA_PROP_SEC_NAME, FALSE);
+ if (ptblsize < 0)
+ goto err;
+
+ /* Fill in the new section cache. */
+ free_section_cache (sec_cache);
+ init_section_cache (sec_cache);
+
+ sec_cache->sec = sec;
+ sec_cache->contents = contents;
+ sec_cache->content_length = sec_size;
+ sec_cache->relocs = internal_relocs;
+ sec_cache->reloc_count = sec->reloc_count;
+ sec_cache->pte_count = ptblsize;
+ sec_cache->ptbl = prop_table;
+
+ return TRUE;
+
+ err:
+ release_contents (sec, contents);
+ release_internal_relocs (sec, internal_relocs);
+ if (prop_table)
+ free (prop_table);
+ return FALSE;
+}
+
+
+/* Extended basic blocks. */
+
+/* An ebb_struct represents an Extended Basic Block. Within this
+ range, we guarantee that all instructions are decodable, the
+ property table entries are contiguous, and no property table
+ specifies a segment that cannot have instructions moved. This
+ structure contains caches of the contents, property table and
+ relocations for the specified section for easy use. The range is
+ specified by ranges of indices for the byte offset, property table
+ offsets and relocation offsets. These must be consistent. */
+
+typedef struct ebb_struct ebb_t;
+
+struct ebb_struct
+{
+ asection *sec;
+
+ bfd_byte *contents; /* Cache of the section contents. */
+ bfd_size_type content_length;
+
+ property_table_entry *ptbl; /* Cache of the section property table. */
+ unsigned pte_count;
+
+ Elf_Internal_Rela *relocs; /* Cache of the section relocations. */
+ unsigned reloc_count;
+
+ bfd_vma start_offset; /* Offset in section. */
+ unsigned start_ptbl_idx; /* Offset in the property table. */
+ unsigned start_reloc_idx; /* Offset in the relocations. */
+
+ bfd_vma end_offset;
+ unsigned end_ptbl_idx;
+ unsigned end_reloc_idx;
+
+ bfd_boolean ends_section; /* Is this the last ebb in a section? */
+
+ /* The unreachable property table at the end of this set of blocks;
+ NULL if the end is not an unreachable block. */
+ property_table_entry *ends_unreachable;
+};
+
+
+enum ebb_target_enum
+{
+ EBB_NO_ALIGN = 0,
+ EBB_DESIRE_TGT_ALIGN,
+ EBB_REQUIRE_TGT_ALIGN,
+ EBB_REQUIRE_LOOP_ALIGN,
+ EBB_REQUIRE_ALIGN
+};
+
+
+/* proposed_action_struct is similar to the text_action_struct except
+ that is represents a potential transformation, not one that will
+ occur. We build a list of these for an extended basic block
+ and use them to compute the actual actions desired. We must be
+ careful that the entire set of actual actions we perform do not
+ break any relocations that would fit if the actions were not
+ performed. */
+
+typedef struct proposed_action_struct proposed_action;
+
+struct proposed_action_struct
+{
+ enum ebb_target_enum align_type; /* for the target alignment */
+ bfd_vma alignment_pow;
+ text_action_t action;
+ bfd_vma offset;
+ int removed_bytes;
+ bfd_boolean do_action; /* If false, then we will not perform the action. */
+};
+
+
+/* The ebb_constraint_struct keeps a set of proposed actions for an
+ extended basic block. */
+
+typedef struct ebb_constraint_struct ebb_constraint;
+
+struct ebb_constraint_struct
+{
+ ebb_t ebb;
+ bfd_boolean start_movable;
+
+ /* Bytes of extra space at the beginning if movable. */
+ int start_extra_space;
+
+ enum ebb_target_enum start_align;
+
+ bfd_boolean end_movable;
+
+ /* Bytes of extra space at the end if movable. */
+ int end_extra_space;
+
+ unsigned action_count;
+ unsigned action_allocated;
+
+ /* Array of proposed actions. */
+ proposed_action *actions;
+
+ /* Action alignments -- one for each proposed action. */
+ enum ebb_target_enum *action_aligns;
+};
+
+
+static void
+init_ebb_constraint (ebb_constraint *c)
+{
+ memset (c, 0, sizeof (ebb_constraint));
+}
+
+
+static void
+free_ebb_constraint (ebb_constraint *c)
+{
+ if (c->actions)
+ free (c->actions);
+}
+
+
+static void
+init_ebb (ebb_t *ebb,
+ asection *sec,
+ bfd_byte *contents,
+ bfd_size_type content_length,
+ property_table_entry *prop_table,
+ unsigned ptblsize,
+ Elf_Internal_Rela *internal_relocs,
+ unsigned reloc_count)
+{
+ memset (ebb, 0, sizeof (ebb_t));
+ ebb->sec = sec;
+ ebb->contents = contents;
+ ebb->content_length = content_length;
+ ebb->ptbl = prop_table;
+ ebb->pte_count = ptblsize;
+ ebb->relocs = internal_relocs;
+ ebb->reloc_count = reloc_count;
+ ebb->start_offset = 0;
+ ebb->end_offset = ebb->content_length - 1;
+ ebb->start_ptbl_idx = 0;
+ ebb->end_ptbl_idx = ptblsize;
+ ebb->start_reloc_idx = 0;
+ ebb->end_reloc_idx = reloc_count;
+}
+
+
+/* Extend the ebb to all decodable contiguous sections. The algorithm
+ for building a basic block around an instruction is to push it
+ forward until we hit the end of a section, an unreachable block or
+ a block that cannot be transformed. Then we push it backwards
+ searching for similar conditions. */
+
+static bfd_boolean extend_ebb_bounds_forward (ebb_t *);
+static bfd_boolean extend_ebb_bounds_backward (ebb_t *);
+static bfd_size_type insn_block_decodable_len
+ (bfd_byte *, bfd_size_type, bfd_vma, bfd_size_type);
+
+static bfd_boolean
+extend_ebb_bounds (ebb_t *ebb)
+{
+ if (!extend_ebb_bounds_forward (ebb))
+ return FALSE;
+ if (!extend_ebb_bounds_backward (ebb))
+ return FALSE;
+ return TRUE;
+}
+
+
+static bfd_boolean
+extend_ebb_bounds_forward (ebb_t *ebb)
+{
+ property_table_entry *the_entry, *new_entry;
+
+ the_entry = &ebb->ptbl[ebb->end_ptbl_idx];
+
+ /* Stop when (1) we cannot decode an instruction, (2) we are at
+ the end of the property tables, (3) we hit a non-contiguous property
+ table entry, (4) we hit a NO_TRANSFORM region. */
+
+ while (1)
+ {
+ bfd_vma entry_end;
+ bfd_size_type insn_block_len;
+
+ entry_end = the_entry->address - ebb->sec->vma + the_entry->size;
+ insn_block_len =
+ insn_block_decodable_len (ebb->contents, ebb->content_length,
+ ebb->end_offset,
+ entry_end - ebb->end_offset);
+ if (insn_block_len != (entry_end - ebb->end_offset))
+ {
+ (*_bfd_error_handler)
+ (_("%B(%A+0x%lx): could not decode instruction; possible configuration mismatch"),
+ ebb->sec->owner, ebb->sec, ebb->end_offset + insn_block_len);
+ return FALSE;
+ }
+ ebb->end_offset += insn_block_len;
+
+ if (ebb->end_offset == ebb->sec->size)
+ ebb->ends_section = TRUE;
+
+ /* Update the reloc counter. */
+ while (ebb->end_reloc_idx + 1 < ebb->reloc_count
+ && (ebb->relocs[ebb->end_reloc_idx + 1].r_offset
+ < ebb->end_offset))
+ {
+ ebb->end_reloc_idx++;
+ }
+
+ if (ebb->end_ptbl_idx + 1 == ebb->pte_count)
+ return TRUE;
+
+ new_entry = &ebb->ptbl[ebb->end_ptbl_idx + 1];
+ if (((new_entry->flags & XTENSA_PROP_INSN) == 0)
+ || ((new_entry->flags & XTENSA_PROP_NO_TRANSFORM) != 0)
+ || ((the_entry->flags & XTENSA_PROP_ALIGN) != 0))
+ break;
+
+ if (the_entry->address + the_entry->size != new_entry->address)
+ break;
+
+ the_entry = new_entry;
+ ebb->end_ptbl_idx++;
+ }
+
+ /* Quick check for an unreachable or end of file just at the end. */
+ if (ebb->end_ptbl_idx + 1 == ebb->pte_count)
+ {
+ if (ebb->end_offset == ebb->content_length)
+ ebb->ends_section = TRUE;
+ }
+ else
+ {
+ new_entry = &ebb->ptbl[ebb->end_ptbl_idx + 1];
+ if ((new_entry->flags & XTENSA_PROP_UNREACHABLE) != 0
+ && the_entry->address + the_entry->size == new_entry->address)
+ ebb->ends_unreachable = new_entry;
+ }
+
+ /* Any other ending requires exact alignment. */
+ return TRUE;
+}
+
+
+static bfd_boolean
+extend_ebb_bounds_backward (ebb_t *ebb)
+{
+ property_table_entry *the_entry, *new_entry;
+
+ the_entry = &ebb->ptbl[ebb->start_ptbl_idx];
+
+ /* Stop when (1) we cannot decode the instructions in the current entry.
+ (2) we are at the beginning of the property tables, (3) we hit a
+ non-contiguous property table entry, (4) we hit a NO_TRANSFORM region. */
+
+ while (1)
+ {
+ bfd_vma block_begin;
+ bfd_size_type insn_block_len;
+
+ block_begin = the_entry->address - ebb->sec->vma;
+ insn_block_len =
+ insn_block_decodable_len (ebb->contents, ebb->content_length,
+ block_begin,
+ ebb->start_offset - block_begin);
+ if (insn_block_len != ebb->start_offset - block_begin)
+ {
+ (*_bfd_error_handler)
+ (_("%B(%A+0x%lx): could not decode instruction; possible configuration mismatch"),
+ ebb->sec->owner, ebb->sec, ebb->end_offset + insn_block_len);
+ return FALSE;
+ }
+ ebb->start_offset -= insn_block_len;
+
+ /* Update the reloc counter. */
+ while (ebb->start_reloc_idx > 0
+ && (ebb->relocs[ebb->start_reloc_idx - 1].r_offset
+ >= ebb->start_offset))
+ {
+ ebb->start_reloc_idx--;
+ }
+
+ if (ebb->start_ptbl_idx == 0)
+ return TRUE;
+
+ new_entry = &ebb->ptbl[ebb->start_ptbl_idx - 1];
+ if ((new_entry->flags & XTENSA_PROP_INSN) == 0
+ || ((new_entry->flags & XTENSA_PROP_NO_TRANSFORM) != 0)
+ || ((new_entry->flags & XTENSA_PROP_ALIGN) != 0))
+ return TRUE;
+ if (new_entry->address + new_entry->size != the_entry->address)
+ return TRUE;
+
+ the_entry = new_entry;
+ ebb->start_ptbl_idx--;
+ }
+ return TRUE;
+}
+
+
+static bfd_size_type
+insn_block_decodable_len (bfd_byte *contents,
+ bfd_size_type content_len,
+ bfd_vma block_offset,
+ bfd_size_type block_len)
+{
+ bfd_vma offset = block_offset;
+
+ while (offset < block_offset + block_len)
+ {
+ bfd_size_type insn_len = 0;
+
+ insn_len = insn_decode_len (contents, content_len, offset);
+ if (insn_len == 0)
+ return (offset - block_offset);
+ offset += insn_len;
+ }
+ return (offset - block_offset);
+}
+
+
+static void
+ebb_propose_action (ebb_constraint *c,
+ enum ebb_target_enum align_type,
+ bfd_vma alignment_pow,
+ text_action_t action,
+ bfd_vma offset,
+ int removed_bytes,
+ bfd_boolean do_action)
+{
+ proposed_action *act;
+
+ if (c->action_allocated <= c->action_count)
+ {
+ unsigned new_allocated, i;
+ proposed_action *new_actions;
+
+ new_allocated = (c->action_count + 2) * 2;
+ new_actions = (proposed_action *)
+ bfd_zmalloc (sizeof (proposed_action) * new_allocated);
+
+ for (i = 0; i < c->action_count; i++)
+ new_actions[i] = c->actions[i];
+ if (c->actions)
+ free (c->actions);
+ c->actions = new_actions;
+ c->action_allocated = new_allocated;
+ }
+
+ act = &c->actions[c->action_count];
+ act->align_type = align_type;
+ act->alignment_pow = alignment_pow;
+ act->action = action;
+ act->offset = offset;
+ act->removed_bytes = removed_bytes;
+ act->do_action = do_action;
+
+ c->action_count++;
+}
+
+
+/* Access to internal relocations, section contents and symbols. */
+
+/* During relaxation, we need to modify relocations, section contents,
+ and symbol definitions, and we need to keep the original values from
+ being reloaded from the input files, i.e., we need to "pin" the
+ modified values in memory. We also want to continue to observe the
+ setting of the "keep-memory" flag. The following functions wrap the
+ standard BFD functions to take care of this for us. */
+
+static Elf_Internal_Rela *
+retrieve_internal_relocs (bfd *abfd, asection *sec, bfd_boolean keep_memory)
+{
+ Elf_Internal_Rela *internal_relocs;
+
+ if ((sec->flags & SEC_LINKER_CREATED) != 0)
+ return NULL;
+
+ internal_relocs = elf_section_data (sec)->relocs;
+ if (internal_relocs == NULL)
+ internal_relocs = (_bfd_elf_link_read_relocs
+ (abfd, sec, NULL, NULL, keep_memory));
+ return internal_relocs;
+}
+
+
+static void
+pin_internal_relocs (asection *sec, Elf_Internal_Rela *internal_relocs)
+{
+ elf_section_data (sec)->relocs = internal_relocs;
+}
+
+
+static void
+release_internal_relocs (asection *sec, Elf_Internal_Rela *internal_relocs)
+{
+ if (internal_relocs
+ && elf_section_data (sec)->relocs != internal_relocs)
+ free (internal_relocs);
+}
+
+
+static bfd_byte *
+retrieve_contents (bfd *abfd, asection *sec, bfd_boolean keep_memory)
+{
+ bfd_byte *contents;
+ bfd_size_type sec_size;
+
+ sec_size = bfd_get_section_limit (abfd, sec);
+ contents = elf_section_data (sec)->this_hdr.contents;
+
+ if (contents == NULL && sec_size != 0)
+ {
+ if (!bfd_malloc_and_get_section (abfd, sec, &contents))
+ {
+ if (contents)
+ free (contents);
+ return NULL;
+ }
+ if (keep_memory)
+ elf_section_data (sec)->this_hdr.contents = contents;
+ }
+ return contents;
+}
+
+
+static void
+pin_contents (asection *sec, bfd_byte *contents)
+{
+ elf_section_data (sec)->this_hdr.contents = contents;
+}
+
+
+static void
+release_contents (asection *sec, bfd_byte *contents)
+{
+ if (contents && elf_section_data (sec)->this_hdr.contents != contents)
+ free (contents);
+}
+
+
+static Elf_Internal_Sym *
+retrieve_local_syms (bfd *input_bfd)
+{
+ Elf_Internal_Shdr *symtab_hdr;
+ Elf_Internal_Sym *isymbuf;
+ size_t locsymcount;
+
+ symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
+ locsymcount = symtab_hdr->sh_info;
+
+ isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
+ if (isymbuf == NULL && locsymcount != 0)
+ isymbuf = bfd_elf_get_elf_syms (input_bfd, symtab_hdr, locsymcount, 0,
+ NULL, NULL, NULL);
+
+ /* Save the symbols for this input file so they won't be read again. */
+ if (isymbuf && isymbuf != (Elf_Internal_Sym *) symtab_hdr->contents)
+ symtab_hdr->contents = (unsigned char *) isymbuf;
+
+ return isymbuf;
+}
+
+
+/* Code for link-time relaxation. */
+
+/* Initialization for relaxation: */
+static bfd_boolean analyze_relocations (struct bfd_link_info *);
+static bfd_boolean find_relaxable_sections
+ (bfd *, asection *, struct bfd_link_info *, bfd_boolean *);
+static bfd_boolean collect_source_relocs
+ (bfd *, asection *, struct bfd_link_info *);
+static bfd_boolean is_resolvable_asm_expansion
+ (bfd *, asection *, bfd_byte *, Elf_Internal_Rela *, struct bfd_link_info *,
+ bfd_boolean *);
+static Elf_Internal_Rela *find_associated_l32r_irel
+ (bfd *, asection *, bfd_byte *, Elf_Internal_Rela *, Elf_Internal_Rela *);
+static bfd_boolean compute_text_actions
+ (bfd *, asection *, struct bfd_link_info *);
+static bfd_boolean compute_ebb_proposed_actions (ebb_constraint *);
+static bfd_boolean compute_ebb_actions (ebb_constraint *);
+static bfd_boolean check_section_ebb_pcrels_fit
+ (bfd *, asection *, bfd_byte *, Elf_Internal_Rela *, const ebb_constraint *,
+ const xtensa_opcode *);
+static bfd_boolean check_section_ebb_reduces (const ebb_constraint *);
+static void text_action_add_proposed
+ (text_action_list *, const ebb_constraint *, asection *);
+static int compute_fill_extra_space (property_table_entry *);
+
+/* First pass: */
+static bfd_boolean compute_removed_literals
+ (bfd *, asection *, struct bfd_link_info *, value_map_hash_table *);
+static Elf_Internal_Rela *get_irel_at_offset
+ (asection *, Elf_Internal_Rela *, bfd_vma);
+static bfd_boolean is_removable_literal
+ (const source_reloc *, int, const source_reloc *, int, asection *,
+ property_table_entry *, int);
+static bfd_boolean remove_dead_literal
+ (bfd *, asection *, struct bfd_link_info *, Elf_Internal_Rela *,
+ Elf_Internal_Rela *, source_reloc *, property_table_entry *, int);
+static bfd_boolean identify_literal_placement
+ (bfd *, asection *, bfd_byte *, struct bfd_link_info *,
+ value_map_hash_table *, bfd_boolean *, Elf_Internal_Rela *, int,
+ source_reloc *, property_table_entry *, int, section_cache_t *,
+ bfd_boolean);
+static bfd_boolean relocations_reach (source_reloc *, int, const r_reloc *);
+static bfd_boolean coalesce_shared_literal
+ (asection *, source_reloc *, property_table_entry *, int, value_map *);
+static bfd_boolean move_shared_literal
+ (asection *, struct bfd_link_info *, source_reloc *, property_table_entry *,
+ int, const r_reloc *, const literal_value *, section_cache_t *);
+
+/* Second pass: */
+static bfd_boolean relax_section (bfd *, asection *, struct bfd_link_info *);
+static bfd_boolean translate_section_fixes (asection *);
+static bfd_boolean translate_reloc_bfd_fix (reloc_bfd_fix *);
+static asection *translate_reloc (const r_reloc *, r_reloc *, asection *);
+static void shrink_dynamic_reloc_sections
+ (struct bfd_link_info *, bfd *, asection *, Elf_Internal_Rela *);
+static bfd_boolean move_literal
+ (bfd *, struct bfd_link_info *, asection *, bfd_vma, bfd_byte *,
+ xtensa_relax_info *, Elf_Internal_Rela **, const literal_value *);
+static bfd_boolean relax_property_section
+ (bfd *, asection *, struct bfd_link_info *);
+
+/* Third pass: */
+static bfd_boolean relax_section_symbols (bfd *, asection *);
+
+
+static bfd_boolean
+elf_xtensa_relax_section (bfd *abfd,
+ asection *sec,
+ struct bfd_link_info *link_info,
+ bfd_boolean *again)
+{
+ static value_map_hash_table *values = NULL;
+ static bfd_boolean relocations_analyzed = FALSE;
+ xtensa_relax_info *relax_info;
+
+ if (!relocations_analyzed)
+ {
+ /* Do some overall initialization for relaxation. */
+ values = value_map_hash_table_init ();
+ if (values == NULL)
+ return FALSE;
+ relaxing_section = TRUE;
+ if (!analyze_relocations (link_info))
+ return FALSE;
+ relocations_analyzed = TRUE;
+ }
+ *again = FALSE;
+
+ /* Don't mess with linker-created sections. */
+ if ((sec->flags & SEC_LINKER_CREATED) != 0)
+ return TRUE;
+
+ relax_info = get_xtensa_relax_info (sec);
+ BFD_ASSERT (relax_info != NULL);
+
+ switch (relax_info->visited)
+ {
+ case 0:
+ /* Note: It would be nice to fold this pass into
+ analyze_relocations, but it is important for this step that the
+ sections be examined in link order. */
+ if (!compute_removed_literals (abfd, sec, link_info, values))
+ return FALSE;
+ *again = TRUE;
+ break;
+
+ case 1:
+ if (values)
+ value_map_hash_table_delete (values);
+ values = NULL;
+ if (!relax_section (abfd, sec, link_info))
+ return FALSE;
+ *again = TRUE;
+ break;
+
+ case 2:
+ if (!relax_section_symbols (abfd, sec))
+ return FALSE;
+ break;
+ }
+
+ relax_info->visited++;
+ return TRUE;
+}
+
+
+/* Initialization for relaxation. */
+
+/* This function is called once at the start of relaxation. It scans
+ all the input sections and marks the ones that are relaxable (i.e.,
+ literal sections with L32R relocations against them), and then
+ collects source_reloc information for all the relocations against
+ those relaxable sections. During this process, it also detects
+ longcalls, i.e., calls relaxed by the assembler into indirect
+ calls, that can be optimized back into direct calls. Within each
+ extended basic block (ebb) containing an optimized longcall, it
+ computes a set of "text actions" that can be performed to remove
+ the L32R associated with the longcall while optionally preserving
+ branch target alignments. */
+
+static bfd_boolean
+analyze_relocations (struct bfd_link_info *link_info)
+{
+ bfd *abfd;
+ asection *sec;
+ bfd_boolean is_relaxable = FALSE;
+
+ /* Initialize the per-section relaxation info. */
+ for (abfd = link_info->input_bfds; abfd != NULL; abfd = abfd->link.next)
+ for (sec = abfd->sections; sec != NULL; sec = sec->next)
+ {
+ init_xtensa_relax_info (sec);
+ }
+
+ /* Mark relaxable sections (and count relocations against each one). */
+ for (abfd = link_info->input_bfds; abfd != NULL; abfd = abfd->link.next)
+ for (sec = abfd->sections; sec != NULL; sec = sec->next)
+ {
+ if (!find_relaxable_sections (abfd, sec, link_info, &is_relaxable))
+ return FALSE;
+ }
+
+ /* Bail out if there are no relaxable sections. */
+ if (!is_relaxable)
+ return TRUE;
+
+ /* Allocate space for source_relocs. */
+ for (abfd = link_info->input_bfds; abfd != NULL; abfd = abfd->link.next)
+ for (sec = abfd->sections; sec != NULL; sec = sec->next)
+ {
+ xtensa_relax_info *relax_info;
+
+ relax_info = get_xtensa_relax_info (sec);
+ if (relax_info->is_relaxable_literal_section
+ || relax_info->is_relaxable_asm_section)
+ {
+ relax_info->src_relocs = (source_reloc *)
+ bfd_malloc (relax_info->src_count * sizeof (source_reloc));
+ }
+ else
+ relax_info->src_count = 0;
+ }
+
+ /* Collect info on relocations against each relaxable section. */
+ for (abfd = link_info->input_bfds; abfd != NULL; abfd = abfd->link.next)
+ for (sec = abfd->sections; sec != NULL; sec = sec->next)
+ {
+ if (!collect_source_relocs (abfd, sec, link_info))
+ return FALSE;
+ }
+
+ /* Compute the text actions. */
+ for (abfd = link_info->input_bfds; abfd != NULL; abfd = abfd->link.next)
+ for (sec = abfd->sections; sec != NULL; sec = sec->next)
+ {
+ if (!compute_text_actions (abfd, sec, link_info))
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+/* Find all the sections that might be relaxed. The motivation for
+ this pass is that collect_source_relocs() needs to record _all_ the
+ relocations that target each relaxable section. That is expensive
+ and unnecessary unless the target section is actually going to be
+ relaxed. This pass identifies all such sections by checking if
+ they have L32Rs pointing to them. In the process, the total number
+ of relocations targeting each section is also counted so that we
+ know how much space to allocate for source_relocs against each
+ relaxable literal section. */
+
+static bfd_boolean
+find_relaxable_sections (bfd *abfd,
+ asection *sec,
+ struct bfd_link_info *link_info,
+ bfd_boolean *is_relaxable_p)
+{
+ Elf_Internal_Rela *internal_relocs;
+ bfd_byte *contents;
+ bfd_boolean ok = TRUE;
+ unsigned i;
+ xtensa_relax_info *source_relax_info;
+ bfd_boolean is_l32r_reloc;
+
+ internal_relocs = retrieve_internal_relocs (abfd, sec,
+ link_info->keep_memory);
+ if (internal_relocs == NULL)
+ return ok;
+
+ contents = retrieve_contents (abfd, sec, link_info->keep_memory);
+ if (contents == NULL && sec->size != 0)
+ {
+ ok = FALSE;
+ goto error_return;
+ }
+
+ source_relax_info = get_xtensa_relax_info (sec);
+ for (i = 0; i < sec->reloc_count; i++)
+ {
+ Elf_Internal_Rela *irel = &internal_relocs[i];
+ r_reloc r_rel;
+ asection *target_sec;
+ xtensa_relax_info *target_relax_info;
+
+ /* If this section has not already been marked as "relaxable", and
+ if it contains any ASM_EXPAND relocations (marking expanded
+ longcalls) that can be optimized into direct calls, then mark
+ the section as "relaxable". */
+ if (source_relax_info
+ && !source_relax_info->is_relaxable_asm_section
+ && ELF32_R_TYPE (irel->r_info) == R_XTENSA_ASM_EXPAND)
+ {
+ bfd_boolean is_reachable = FALSE;
+ if (is_resolvable_asm_expansion (abfd, sec, contents, irel,
+ link_info, &is_reachable)
+ && is_reachable)
+ {
+ source_relax_info->is_relaxable_asm_section = TRUE;
+ *is_relaxable_p = TRUE;
+ }
+ }
+
+ r_reloc_init (&r_rel, abfd, irel, contents,
+ bfd_get_section_limit (abfd, sec));
+
+ target_sec = r_reloc_get_section (&r_rel);
+ target_relax_info = get_xtensa_relax_info (target_sec);
+ if (!target_relax_info)
+ continue;
+
+ /* Count PC-relative operand relocations against the target section.
+ Note: The conditions tested here must match the conditions under
+ which init_source_reloc is called in collect_source_relocs(). */
+ is_l32r_reloc = FALSE;
+ if (is_operand_relocation (ELF32_R_TYPE (irel->r_info)))
+ {
+ xtensa_opcode opcode =
+ get_relocation_opcode (abfd, sec, contents, irel);
+ if (opcode != XTENSA_UNDEFINED)
+ {
+ is_l32r_reloc = (opcode == get_l32r_opcode ());
+ if (!is_alt_relocation (ELF32_R_TYPE (irel->r_info))
+ || is_l32r_reloc)
+ target_relax_info->src_count++;
+ }
+ }
+
+ if (is_l32r_reloc && r_reloc_is_defined (&r_rel))
+ {
+ /* Mark the target section as relaxable. */
+ target_relax_info->is_relaxable_literal_section = TRUE;
+ *is_relaxable_p = TRUE;
+ }
+ }
+
+ error_return:
+ release_contents (sec, contents);
+ release_internal_relocs (sec, internal_relocs);
+ return ok;
+}
+
+
+/* Record _all_ the relocations that point to relaxable sections, and
+ get rid of ASM_EXPAND relocs by either converting them to
+ ASM_SIMPLIFY or by removing them. */
+
+static bfd_boolean
+collect_source_relocs (bfd *abfd,
+ asection *sec,
+ struct bfd_link_info *link_info)
+{
+ Elf_Internal_Rela *internal_relocs;
+ bfd_byte *contents;
+ bfd_boolean ok = TRUE;
+ unsigned i;
+ bfd_size_type sec_size;
+
+ internal_relocs = retrieve_internal_relocs (abfd, sec,
+ link_info->keep_memory);
+ if (internal_relocs == NULL)
+ return ok;
+
+ sec_size = bfd_get_section_limit (abfd, sec);
+ contents = retrieve_contents (abfd, sec, link_info->keep_memory);
+ if (contents == NULL && sec_size != 0)
+ {
+ ok = FALSE;
+ goto error_return;
+ }
+
+ /* Record relocations against relaxable literal sections. */
+ for (i = 0; i < sec->reloc_count; i++)
+ {
+ Elf_Internal_Rela *irel = &internal_relocs[i];
+ r_reloc r_rel;
+ asection *target_sec;
+ xtensa_relax_info *target_relax_info;
+
+ r_reloc_init (&r_rel, abfd, irel, contents, sec_size);
+
+ target_sec = r_reloc_get_section (&r_rel);
+ target_relax_info = get_xtensa_relax_info (target_sec);
+
+ if (target_relax_info
+ && (target_relax_info->is_relaxable_literal_section
+ || target_relax_info->is_relaxable_asm_section))
+ {
+ xtensa_opcode opcode = XTENSA_UNDEFINED;
+ int opnd = -1;
+ bfd_boolean is_abs_literal = FALSE;
+
+ if (is_alt_relocation (ELF32_R_TYPE (irel->r_info)))
+ {
+ /* None of the current alternate relocs are PC-relative,
+ and only PC-relative relocs matter here. However, we
+ still need to record the opcode for literal
+ coalescing. */
+ opcode = get_relocation_opcode (abfd, sec, contents, irel);
+ if (opcode == get_l32r_opcode ())
+ {
+ is_abs_literal = TRUE;
+ opnd = 1;
+ }
+ else
+ opcode = XTENSA_UNDEFINED;
+ }
+ else if (is_operand_relocation (ELF32_R_TYPE (irel->r_info)))
+ {
+ opcode = get_relocation_opcode (abfd, sec, contents, irel);
+ opnd = get_relocation_opnd (opcode, ELF32_R_TYPE (irel->r_info));
+ }
+
+ if (opcode != XTENSA_UNDEFINED)
+ {
+ int src_next = target_relax_info->src_next++;
+ source_reloc *s_reloc = &target_relax_info->src_relocs[src_next];
+
+ init_source_reloc (s_reloc, sec, &r_rel, opcode, opnd,
+ is_abs_literal);
+ }
+ }
+ }
+
+ /* Now get rid of ASM_EXPAND relocations. At this point, the
+ src_relocs array for the target literal section may still be
+ incomplete, but it must at least contain the entries for the L32R
+ relocations associated with ASM_EXPANDs because they were just
+ added in the preceding loop over the relocations. */
+
+ for (i = 0; i < sec->reloc_count; i++)
+ {
+ Elf_Internal_Rela *irel = &internal_relocs[i];
+ bfd_boolean is_reachable;
+
+ if (!is_resolvable_asm_expansion (abfd, sec, contents, irel, link_info,
+ &is_reachable))
+ continue;
+
+ if (is_reachable)
+ {
+ Elf_Internal_Rela *l32r_irel;
+ r_reloc r_rel;
+ asection *target_sec;
+ xtensa_relax_info *target_relax_info;
+
+ /* Mark the source_reloc for the L32R so that it will be
+ removed in compute_removed_literals(), along with the
+ associated literal. */
+ l32r_irel = find_associated_l32r_irel (abfd, sec, contents,
+ irel, internal_relocs);
+ if (l32r_irel == NULL)
+ continue;
+
+ r_reloc_init (&r_rel, abfd, l32r_irel, contents, sec_size);
+
+ target_sec = r_reloc_get_section (&r_rel);
+ target_relax_info = get_xtensa_relax_info (target_sec);
+
+ if (target_relax_info
+ && (target_relax_info->is_relaxable_literal_section
+ || target_relax_info->is_relaxable_asm_section))
+ {
+ source_reloc *s_reloc;
+
+ /* Search the source_relocs for the entry corresponding to
+ the l32r_irel. Note: The src_relocs array is not yet
+ sorted, but it wouldn't matter anyway because we're
+ searching by source offset instead of target offset. */
+ s_reloc = find_source_reloc (target_relax_info->src_relocs,
+ target_relax_info->src_next,
+ sec, l32r_irel);
+ BFD_ASSERT (s_reloc);
+ s_reloc->is_null = TRUE;
+ }
+
+ /* Convert this reloc to ASM_SIMPLIFY. */
+ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
+ R_XTENSA_ASM_SIMPLIFY);
+ l32r_irel->r_info = ELF32_R_INFO (0, R_XTENSA_NONE);
+
+ pin_internal_relocs (sec, internal_relocs);
+ }
+ else
+ {
+ /* It is resolvable but doesn't reach. We resolve now
+ by eliminating the relocation -- the call will remain
+ expanded into L32R/CALLX. */
+ irel->r_info = ELF32_R_INFO (0, R_XTENSA_NONE);
+ pin_internal_relocs (sec, internal_relocs);
+ }
+ }
+
+ error_return:
+ release_contents (sec, contents);
+ release_internal_relocs (sec, internal_relocs);
+ return ok;
+}
+
+
+/* Return TRUE if the asm expansion can be resolved. Generally it can
+ be resolved on a final link or when a partial link locates it in the
+ same section as the target. Set "is_reachable" flag if the target of
+ the call is within the range of a direct call, given the current VMA
+ for this section and the target section. */
+
+bfd_boolean
+is_resolvable_asm_expansion (bfd *abfd,
+ asection *sec,
+ bfd_byte *contents,
+ Elf_Internal_Rela *irel,
+ struct bfd_link_info *link_info,
+ bfd_boolean *is_reachable_p)
+{
+ asection *target_sec;
+ bfd_vma target_offset;
+ r_reloc r_rel;
+ xtensa_opcode opcode, direct_call_opcode;
+ bfd_vma self_address;
+ bfd_vma dest_address;
+ bfd_boolean uses_l32r;
+ bfd_size_type sec_size;
+
+ *is_reachable_p = FALSE;
+
+ if (contents == NULL)
+ return FALSE;
+
+ if (ELF32_R_TYPE (irel->r_info) != R_XTENSA_ASM_EXPAND)
+ return FALSE;
+
+ sec_size = bfd_get_section_limit (abfd, sec);
+ opcode = get_expanded_call_opcode (contents + irel->r_offset,
+ sec_size - irel->r_offset, &uses_l32r);
+ /* Optimization of longcalls that use CONST16 is not yet implemented. */
+ if (!uses_l32r)
+ return FALSE;
+
+ direct_call_opcode = swap_callx_for_call_opcode (opcode);
+ if (direct_call_opcode == XTENSA_UNDEFINED)
+ return FALSE;
+
+ /* Check and see that the target resolves. */
+ r_reloc_init (&r_rel, abfd, irel, contents, sec_size);
+ if (!r_reloc_is_defined (&r_rel))
+ return FALSE;
+
+ target_sec = r_reloc_get_section (&r_rel);
+ target_offset = r_rel.target_offset;
+
+ /* If the target is in a shared library, then it doesn't reach. This
+ isn't supposed to come up because the compiler should never generate
+ non-PIC calls on systems that use shared libraries, but the linker
+ shouldn't crash regardless. */
+ if (!target_sec->output_section)
+ return FALSE;
+
+ /* For relocatable sections, we can only simplify when the output
+ section of the target is the same as the output section of the
+ source. */
+ if (link_info->relocatable
+ && (target_sec->output_section != sec->output_section
+ || is_reloc_sym_weak (abfd, irel)))
+ return FALSE;
+
+ if (target_sec->output_section != sec->output_section)
+ {
+ /* If the two sections are sufficiently far away that relaxation
+ might take the call out of range, we can't simplify. For
+ example, a positive displacement call into another memory
+ could get moved to a lower address due to literal removal,
+ but the destination won't move, and so the displacment might
+ get larger.
+
+ If the displacement is negative, assume the destination could
+ move as far back as the start of the output section. The
+ self_address will be at least as far into the output section
+ as it is prior to relaxation.
+
+ If the displacement is postive, assume the destination will be in
+ it's pre-relaxed location (because relaxation only makes sections
+ smaller). The self_address could go all the way to the beginning
+ of the output section. */
+
+ dest_address = target_sec->output_section->vma;
+ self_address = sec->output_section->vma;
+
+ if (sec->output_section->vma > target_sec->output_section->vma)
+ self_address += sec->output_offset + irel->r_offset + 3;
+ else
+ dest_address += bfd_get_section_limit (abfd, target_sec->output_section);
+ /* Call targets should be four-byte aligned. */
+ dest_address = (dest_address + 3) & ~3;
+ }
+ else
+ {
+
+ self_address = (sec->output_section->vma
+ + sec->output_offset + irel->r_offset + 3);
+ dest_address = (target_sec->output_section->vma
+ + target_sec->output_offset + target_offset);
+ }
+
+ *is_reachable_p = pcrel_reloc_fits (direct_call_opcode, 0,
+ self_address, dest_address);
+
+ if ((self_address >> CALL_SEGMENT_BITS) !=
+ (dest_address >> CALL_SEGMENT_BITS))
+ return FALSE;
+
+ return TRUE;
+}
+
+
+static Elf_Internal_Rela *
+find_associated_l32r_irel (bfd *abfd,
+ asection *sec,
+ bfd_byte *contents,
+ Elf_Internal_Rela *other_irel,
+ Elf_Internal_Rela *internal_relocs)
+{
+ unsigned i;
+
+ for (i = 0; i < sec->reloc_count; i++)
+ {
+ Elf_Internal_Rela *irel = &internal_relocs[i];
+
+ if (irel == other_irel)
+ continue;
+ if (irel->r_offset != other_irel->r_offset)
+ continue;
+ if (is_l32r_relocation (abfd, sec, contents, irel))
+ return irel;
+ }
+
+ return NULL;
+}
+
+
+static xtensa_opcode *
+build_reloc_opcodes (bfd *abfd,
+ asection *sec,
+ bfd_byte *contents,
+ Elf_Internal_Rela *internal_relocs)
+{
+ unsigned i;
+ xtensa_opcode *reloc_opcodes =
+ (xtensa_opcode *) bfd_malloc (sizeof (xtensa_opcode) * sec->reloc_count);
+ for (i = 0; i < sec->reloc_count; i++)
+ {
+ Elf_Internal_Rela *irel = &internal_relocs[i];
+ reloc_opcodes[i] = get_relocation_opcode (abfd, sec, contents, irel);
+ }
+ return reloc_opcodes;
+}
+
+
+/* The compute_text_actions function will build a list of potential
+ transformation actions for code in the extended basic block of each
+ longcall that is optimized to a direct call. From this list we
+ generate a set of actions to actually perform that optimizes for
+ space and, if not using size_opt, maintains branch target
+ alignments.
+
+ These actions to be performed are placed on a per-section list.
+ The actual changes are performed by relax_section() in the second
+ pass. */
+
+bfd_boolean
+compute_text_actions (bfd *abfd,
+ asection *sec,
+ struct bfd_link_info *link_info)
+{
+ xtensa_opcode *reloc_opcodes = NULL;
+ xtensa_relax_info *relax_info;
+ bfd_byte *contents;
+ Elf_Internal_Rela *internal_relocs;
+ bfd_boolean ok = TRUE;
+ unsigned i;
+ property_table_entry *prop_table = 0;
+ int ptblsize = 0;
+ bfd_size_type sec_size;
+
+ relax_info = get_xtensa_relax_info (sec);
+ BFD_ASSERT (relax_info);
+ BFD_ASSERT (relax_info->src_next == relax_info->src_count);
+
+ /* Do nothing if the section contains no optimized longcalls. */
+ if (!relax_info->is_relaxable_asm_section)
+ return ok;
+
+ internal_relocs = retrieve_internal_relocs (abfd, sec,
+ link_info->keep_memory);
+
+ if (internal_relocs)
+ qsort (internal_relocs, sec->reloc_count, sizeof (Elf_Internal_Rela),
+ internal_reloc_compare);
+
+ sec_size = bfd_get_section_limit (abfd, sec);
+ contents = retrieve_contents (abfd, sec, link_info->keep_memory);
+ if (contents == NULL && sec_size != 0)
+ {
+ ok = FALSE;
+ goto error_return;
+ }
+
+ ptblsize = xtensa_read_table_entries (abfd, sec, &prop_table,
+ XTENSA_PROP_SEC_NAME, FALSE);
+ if (ptblsize < 0)
+ {
+ ok = FALSE;
+ goto error_return;
+ }
+
+ for (i = 0; i < sec->reloc_count; i++)
+ {
+ Elf_Internal_Rela *irel = &internal_relocs[i];
+ bfd_vma r_offset;
+ property_table_entry *the_entry;
+ int ptbl_idx;
+ ebb_t *ebb;
+ ebb_constraint ebb_table;
+ bfd_size_type simplify_size;
+
+ if (irel && ELF32_R_TYPE (irel->r_info) != R_XTENSA_ASM_SIMPLIFY)
+ continue;
+ r_offset = irel->r_offset;
+
+ simplify_size = get_asm_simplify_size (contents, sec_size, r_offset);
+ if (simplify_size == 0)
+ {
+ (*_bfd_error_handler)
+ (_("%B(%A+0x%lx): could not decode instruction for XTENSA_ASM_SIMPLIFY relocation; possible configuration mismatch"),
+ sec->owner, sec, r_offset);
+ continue;
+ }
+
+ /* If the instruction table is not around, then don't do this
+ relaxation. */
+ the_entry = elf_xtensa_find_property_entry (prop_table, ptblsize,
+ sec->vma + irel->r_offset);
+ if (the_entry == NULL || XTENSA_NO_NOP_REMOVAL)
+ {
+ text_action_add (&relax_info->action_list,
+ ta_convert_longcall, sec, r_offset,
+ 0);
+ continue;
+ }
+
+ /* If the next longcall happens to be at the same address as an
+ unreachable section of size 0, then skip forward. */
+ ptbl_idx = the_entry - prop_table;
+ while ((the_entry->flags & XTENSA_PROP_UNREACHABLE)
+ && the_entry->size == 0
+ && ptbl_idx + 1 < ptblsize
+ && (prop_table[ptbl_idx + 1].address
+ == prop_table[ptbl_idx].address))
+ {
+ ptbl_idx++;
+ the_entry++;
+ }
+
+ if (the_entry->flags & XTENSA_PROP_NO_TRANSFORM)
+ /* NO_REORDER is OK */
+ continue;
+
+ init_ebb_constraint (&ebb_table);
+ ebb = &ebb_table.ebb;
+ init_ebb (ebb, sec, contents, sec_size, prop_table, ptblsize,
+ internal_relocs, sec->reloc_count);
+ ebb->start_offset = r_offset + simplify_size;
+ ebb->end_offset = r_offset + simplify_size;
+ ebb->start_ptbl_idx = ptbl_idx;
+ ebb->end_ptbl_idx = ptbl_idx;
+ ebb->start_reloc_idx = i;
+ ebb->end_reloc_idx = i;
+
+ /* Precompute the opcode for each relocation. */
+ if (reloc_opcodes == NULL)
+ reloc_opcodes = build_reloc_opcodes (abfd, sec, contents,
+ internal_relocs);
+
+ if (!extend_ebb_bounds (ebb)
+ || !compute_ebb_proposed_actions (&ebb_table)
+ || !compute_ebb_actions (&ebb_table)
+ || !check_section_ebb_pcrels_fit (abfd, sec, contents,
+ internal_relocs, &ebb_table,
+ reloc_opcodes)
+ || !check_section_ebb_reduces (&ebb_table))
+ {
+ /* If anything goes wrong or we get unlucky and something does
+ not fit, with our plan because of expansion between
+ critical branches, just convert to a NOP. */
+
+ text_action_add (&relax_info->action_list,
+ ta_convert_longcall, sec, r_offset, 0);
+ i = ebb_table.ebb.end_reloc_idx;
+ free_ebb_constraint (&ebb_table);
+ continue;
+ }
+
+ text_action_add_proposed (&relax_info->action_list, &ebb_table, sec);
+
+ /* Update the index so we do not go looking at the relocations
+ we have already processed. */
+ i = ebb_table.ebb.end_reloc_idx;
+ free_ebb_constraint (&ebb_table);
+ }
+
+#if DEBUG
+ if (relax_info->action_list.head)
+ print_action_list (stderr, &relax_info->action_list);
+#endif
+
+error_return:
+ release_contents (sec, contents);
+ release_internal_relocs (sec, internal_relocs);
+ if (prop_table)
+ free (prop_table);
+ if (reloc_opcodes)
+ free (reloc_opcodes);
+
+ return ok;
+}
+
+
+/* Do not widen an instruction if it is preceeded by a
+ loop opcode. It might cause misalignment. */
+
+static bfd_boolean
+prev_instr_is_a_loop (bfd_byte *contents,
+ bfd_size_type content_length,
+ bfd_size_type offset)
+{
+ xtensa_opcode prev_opcode;
+
+ if (offset < 3)
+ return FALSE;
+ prev_opcode = insn_decode_opcode (contents, content_length, offset-3, 0);
+ return (xtensa_opcode_is_loop (xtensa_default_isa, prev_opcode) == 1);
+}
+
+
+/* Find all of the possible actions for an extended basic block. */
+
+bfd_boolean
+compute_ebb_proposed_actions (ebb_constraint *ebb_table)
+{
+ const ebb_t *ebb = &ebb_table->ebb;
+ unsigned rel_idx = ebb->start_reloc_idx;
+ property_table_entry *entry, *start_entry, *end_entry;
+ bfd_vma offset = 0;
+ xtensa_isa isa = xtensa_default_isa;
+ xtensa_format fmt;
+ static xtensa_insnbuf insnbuf = NULL;
+ static xtensa_insnbuf slotbuf = NULL;
+
+ if (insnbuf == NULL)
+ {
+ insnbuf = xtensa_insnbuf_alloc (isa);
+ slotbuf = xtensa_insnbuf_alloc (isa);
+ }
+
+ start_entry = &ebb->ptbl[ebb->start_ptbl_idx];
+ end_entry = &ebb->ptbl[ebb->end_ptbl_idx];
+
+ for (entry = start_entry; entry <= end_entry; entry++)
+ {
+ bfd_vma start_offset, end_offset;
+ bfd_size_type insn_len;
+
+ start_offset = entry->address - ebb->sec->vma;
+ end_offset = entry->address + entry->size - ebb->sec->vma;
+
+ if (entry == start_entry)
+ start_offset = ebb->start_offset;
+ if (entry == end_entry)
+ end_offset = ebb->end_offset;
+ offset = start_offset;
+
+ if (offset == entry->address - ebb->sec->vma
+ && (entry->flags & XTENSA_PROP_INSN_BRANCH_TARGET) != 0)
+ {
+ enum ebb_target_enum align_type = EBB_DESIRE_TGT_ALIGN;
+ BFD_ASSERT (offset != end_offset);
+ if (offset == end_offset)
+ return FALSE;
+
+ insn_len = insn_decode_len (ebb->contents, ebb->content_length,
+ offset);
+ if (insn_len == 0)
+ goto decode_error;
+
+ if (check_branch_target_aligned_address (offset, insn_len))
+ align_type = EBB_REQUIRE_TGT_ALIGN;
+
+ ebb_propose_action (ebb_table, align_type, 0,
+ ta_none, offset, 0, TRUE);
+ }
+
+ while (offset != end_offset)
+ {
+ Elf_Internal_Rela *irel;
+ xtensa_opcode opcode;
+
+ while (rel_idx < ebb->end_reloc_idx
+ && (ebb->relocs[rel_idx].r_offset < offset
+ || (ebb->relocs[rel_idx].r_offset == offset
+ && (ELF32_R_TYPE (ebb->relocs[rel_idx].r_info)
+ != R_XTENSA_ASM_SIMPLIFY))))
+ rel_idx++;
+
+ /* Check for longcall. */
+ irel = &ebb->relocs[rel_idx];
+ if (irel->r_offset == offset
+ && ELF32_R_TYPE (irel->r_info) == R_XTENSA_ASM_SIMPLIFY)
+ {
+ bfd_size_type simplify_size;
+
+ simplify_size = get_asm_simplify_size (ebb->contents,
+ ebb->content_length,
+ irel->r_offset);
+ if (simplify_size == 0)
+ goto decode_error;
+
+ ebb_propose_action (ebb_table, EBB_NO_ALIGN, 0,
+ ta_convert_longcall, offset, 0, TRUE);
+
+ offset += simplify_size;
+ continue;
+ }
+
+ if (offset + MIN_INSN_LENGTH > ebb->content_length)
+ goto decode_error;
+ xtensa_insnbuf_from_chars (isa, insnbuf, &ebb->contents[offset],
+ ebb->content_length - offset);
+ fmt = xtensa_format_decode (isa, insnbuf);
+ if (fmt == XTENSA_UNDEFINED)
+ goto decode_error;
+ insn_len = xtensa_format_length (isa, fmt);
+ if (insn_len == (bfd_size_type) XTENSA_UNDEFINED)
+ goto decode_error;
+
+ if (xtensa_format_num_slots (isa, fmt) != 1)
+ {
+ offset += insn_len;
+ continue;
+ }
+
+ xtensa_format_get_slot (isa, fmt, 0, insnbuf, slotbuf);
+ opcode = xtensa_opcode_decode (isa, fmt, 0, slotbuf);
+ if (opcode == XTENSA_UNDEFINED)
+ goto decode_error;
+
+ if ((entry->flags & XTENSA_PROP_INSN_NO_DENSITY) == 0
+ && (entry->flags & XTENSA_PROP_NO_TRANSFORM) == 0
+ && can_narrow_instruction (slotbuf, fmt, opcode) != 0)
+ {
+ /* Add an instruction narrow action. */
+ ebb_propose_action (ebb_table, EBB_NO_ALIGN, 0,
+ ta_narrow_insn, offset, 0, FALSE);
+ }
+ else if ((entry->flags & XTENSA_PROP_NO_TRANSFORM) == 0
+ && can_widen_instruction (slotbuf, fmt, opcode) != 0
+ && ! prev_instr_is_a_loop (ebb->contents,
+ ebb->content_length, offset))
+ {
+ /* Add an instruction widen action. */
+ ebb_propose_action (ebb_table, EBB_NO_ALIGN, 0,
+ ta_widen_insn, offset, 0, FALSE);
+ }
+ else if (xtensa_opcode_is_loop (xtensa_default_isa, opcode) == 1)
+ {
+ /* Check for branch targets. */
+ ebb_propose_action (ebb_table, EBB_REQUIRE_LOOP_ALIGN, 0,
+ ta_none, offset, 0, TRUE);
+ }
+
+ offset += insn_len;
+ }
+ }
+
+ if (ebb->ends_unreachable)
+ {
+ ebb_propose_action (ebb_table, EBB_NO_ALIGN, 0,
+ ta_fill, ebb->end_offset, 0, TRUE);
+ }
+
+ return TRUE;
+
+ decode_error:
+ (*_bfd_error_handler)
+ (_("%B(%A+0x%lx): could not decode instruction; possible configuration mismatch"),
+ ebb->sec->owner, ebb->sec, offset);
+ return FALSE;
+}
+
+
+/* After all of the information has collected about the
+ transformations possible in an EBB, compute the appropriate actions
+ here in compute_ebb_actions. We still must check later to make
+ sure that the actions do not break any relocations. The algorithm
+ used here is pretty greedy. Basically, it removes as many no-ops
+ as possible so that the end of the EBB has the same alignment
+ characteristics as the original. First, it uses narrowing, then
+ fill space at the end of the EBB, and finally widenings. If that
+ does not work, it tries again with one fewer no-op removed. The
+ optimization will only be performed if all of the branch targets
+ that were aligned before transformation are also aligned after the
+ transformation.
+
+ When the size_opt flag is set, ignore the branch target alignments,
+ narrow all wide instructions, and remove all no-ops unless the end
+ of the EBB prevents it. */
+
+bfd_boolean
+compute_ebb_actions (ebb_constraint *ebb_table)
+{
+ unsigned i = 0;
+ unsigned j;
+ int removed_bytes = 0;
+ ebb_t *ebb = &ebb_table->ebb;
+ unsigned seg_idx_start = 0;
+ unsigned seg_idx_end = 0;
+
+ /* We perform this like the assembler relaxation algorithm: Start by
+ assuming all instructions are narrow and all no-ops removed; then
+ walk through.... */
+
+ /* For each segment of this that has a solid constraint, check to
+ see if there are any combinations that will keep the constraint.
+ If so, use it. */
+ for (seg_idx_end = 0; seg_idx_end < ebb_table->action_count; seg_idx_end++)
+ {
+ bfd_boolean requires_text_end_align = FALSE;
+ unsigned longcall_count = 0;
+ unsigned longcall_convert_count = 0;
+ unsigned narrowable_count = 0;
+ unsigned narrowable_convert_count = 0;
+ unsigned widenable_count = 0;
+ unsigned widenable_convert_count = 0;
+
+ proposed_action *action = NULL;
+ int align = (1 << ebb_table->ebb.sec->alignment_power);
+
+ seg_idx_start = seg_idx_end;
+
+ for (i = seg_idx_start; i < ebb_table->action_count; i++)
+ {
+ action = &ebb_table->actions[i];
+ if (action->action == ta_convert_longcall)
+ longcall_count++;
+ if (action->action == ta_narrow_insn)
+ narrowable_count++;
+ if (action->action == ta_widen_insn)
+ widenable_count++;
+ if (action->action == ta_fill)
+ break;
+ if (action->align_type == EBB_REQUIRE_LOOP_ALIGN)
+ break;
+ if (action->align_type == EBB_REQUIRE_TGT_ALIGN
+ && !elf32xtensa_size_opt)
+ break;
+ }
+ seg_idx_end = i;
+
+ if (seg_idx_end == ebb_table->action_count && !ebb->ends_unreachable)
+ requires_text_end_align = TRUE;
+
+ if (elf32xtensa_size_opt && !requires_text_end_align
+ && action->align_type != EBB_REQUIRE_LOOP_ALIGN
+ && action->align_type != EBB_REQUIRE_TGT_ALIGN)
+ {
+ longcall_convert_count = longcall_count;
+ narrowable_convert_count = narrowable_count;
+ widenable_convert_count = 0;
+ }
+ else
+ {
+ /* There is a constraint. Convert the max number of longcalls. */
+ narrowable_convert_count = 0;
+ longcall_convert_count = 0;
+ widenable_convert_count = 0;
+
+ for (j = 0; j < longcall_count; j++)
+ {
+ int removed = (longcall_count - j) * 3 & (align - 1);
+ unsigned desire_narrow = (align - removed) & (align - 1);
+ unsigned desire_widen = removed;
+ if (desire_narrow <= narrowable_count)
+ {
+ narrowable_convert_count = desire_narrow;
+ narrowable_convert_count +=
+ (align * ((narrowable_count - narrowable_convert_count)
+ / align));
+ longcall_convert_count = (longcall_count - j);
+ widenable_convert_count = 0;
+ break;
+ }
+ if (desire_widen <= widenable_count && !elf32xtensa_size_opt)
+ {
+ narrowable_convert_count = 0;
+ longcall_convert_count = longcall_count - j;
+ widenable_convert_count = desire_widen;
+ break;
+ }
+ }
+ }
+
+ /* Now the number of conversions are saved. Do them. */
+ for (i = seg_idx_start; i < seg_idx_end; i++)
+ {
+ action = &ebb_table->actions[i];
+ switch (action->action)
+ {
+ case ta_convert_longcall:
+ if (longcall_convert_count != 0)
+ {
+ action->action = ta_remove_longcall;
+ action->do_action = TRUE;
+ action->removed_bytes += 3;
+ longcall_convert_count--;
+ }
+ break;
+ case ta_narrow_insn:
+ if (narrowable_convert_count != 0)
+ {
+ action->do_action = TRUE;
+ action->removed_bytes += 1;
+ narrowable_convert_count--;
+ }
+ break;
+ case ta_widen_insn:
+ if (widenable_convert_count != 0)
+ {
+ action->do_action = TRUE;
+ action->removed_bytes -= 1;
+ widenable_convert_count--;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ /* Now we move on to some local opts. Try to remove each of the
+ remaining longcalls. */
+
+ if (ebb_table->ebb.ends_section || ebb_table->ebb.ends_unreachable)
+ {
+ removed_bytes = 0;
+ for (i = 0; i < ebb_table->action_count; i++)
+ {
+ int old_removed_bytes = removed_bytes;
+ proposed_action *action = &ebb_table->actions[i];
+
+ if (action->do_action && action->action == ta_convert_longcall)
+ {
+ bfd_boolean bad_alignment = FALSE;
+ removed_bytes += 3;
+ for (j = i + 1; j < ebb_table->action_count; j++)
+ {
+ proposed_action *new_action = &ebb_table->actions[j];
+ bfd_vma offset = new_action->offset;
+ if (new_action->align_type == EBB_REQUIRE_TGT_ALIGN)
+ {
+ if (!check_branch_target_aligned
+ (ebb_table->ebb.contents,
+ ebb_table->ebb.content_length,
+ offset, offset - removed_bytes))
+ {
+ bad_alignment = TRUE;
+ break;
+ }
+ }
+ if (new_action->align_type == EBB_REQUIRE_LOOP_ALIGN)
+ {
+ if (!check_loop_aligned (ebb_table->ebb.contents,
+ ebb_table->ebb.content_length,
+ offset,
+ offset - removed_bytes))
+ {
+ bad_alignment = TRUE;
+ break;
+ }
+ }
+ if (new_action->action == ta_narrow_insn
+ && !new_action->do_action
+ && ebb_table->ebb.sec->alignment_power == 2)
+ {
+ /* Narrow an instruction and we are done. */
+ new_action->do_action = TRUE;
+ new_action->removed_bytes += 1;
+ bad_alignment = FALSE;
+ break;
+ }
+ if (new_action->action == ta_widen_insn
+ && new_action->do_action
+ && ebb_table->ebb.sec->alignment_power == 2)
+ {
+ /* Narrow an instruction and we are done. */
+ new_action->do_action = FALSE;
+ new_action->removed_bytes += 1;
+ bad_alignment = FALSE;
+ break;
+ }
+ if (new_action->do_action)
+ removed_bytes += new_action->removed_bytes;
+ }
+ if (!bad_alignment)
+ {
+ action->removed_bytes += 3;
+ action->action = ta_remove_longcall;
+ action->do_action = TRUE;
+ }
+ }
+ removed_bytes = old_removed_bytes;
+ if (action->do_action)
+ removed_bytes += action->removed_bytes;
+ }
+ }
+
+ removed_bytes = 0;
+ for (i = 0; i < ebb_table->action_count; ++i)
+ {
+ proposed_action *action = &ebb_table->actions[i];
+ if (action->do_action)
+ removed_bytes += action->removed_bytes;
+ }
+
+ if ((removed_bytes % (1 << ebb_table->ebb.sec->alignment_power)) != 0
+ && ebb->ends_unreachable)
+ {
+ proposed_action *action;
+ int br;
+ int extra_space;
+
+ BFD_ASSERT (ebb_table->action_count != 0);
+ action = &ebb_table->actions[ebb_table->action_count - 1];
+ BFD_ASSERT (action->action == ta_fill);
+ BFD_ASSERT (ebb->ends_unreachable->flags & XTENSA_PROP_UNREACHABLE);
+
+ extra_space = compute_fill_extra_space (ebb->ends_unreachable);
+ br = action->removed_bytes + removed_bytes + extra_space;
+ br = br & ((1 << ebb->sec->alignment_power ) - 1);
+
+ action->removed_bytes = extra_space - br;
+ }
+ return TRUE;
+}
+
+
+/* The xlate_map is a sorted array of address mappings designed to
+ answer the offset_with_removed_text() query with a binary search instead
+ of a linear search through the section's action_list. */
+
+typedef struct xlate_map_entry xlate_map_entry_t;
+typedef struct xlate_map xlate_map_t;
+
+struct xlate_map_entry
+{
+ unsigned orig_address;
+ unsigned new_address;
+ unsigned size;
+};
+
+struct xlate_map
+{
+ unsigned entry_count;
+ xlate_map_entry_t *entry;
+};
+
+
+static int
+xlate_compare (const void *a_v, const void *b_v)
+{
+ const xlate_map_entry_t *a = (const xlate_map_entry_t *) a_v;
+ const xlate_map_entry_t *b = (const xlate_map_entry_t *) b_v;
+ if (a->orig_address < b->orig_address)
+ return -1;
+ if (a->orig_address > (b->orig_address + b->size - 1))
+ return 1;
+ return 0;
+}
+
+
+static bfd_vma
+xlate_offset_with_removed_text (const xlate_map_t *map,
+ text_action_list *action_list,
+ bfd_vma offset)
+{
+ void *r;
+ xlate_map_entry_t *e;
+
+ if (map == NULL)
+ return offset_with_removed_text (action_list, offset);
+
+ if (map->entry_count == 0)
+ return offset;
+
+ r = bsearch (&offset, map->entry, map->entry_count,
+ sizeof (xlate_map_entry_t), &xlate_compare);
+ e = (xlate_map_entry_t *) r;
+
+ BFD_ASSERT (e != NULL);
+ if (e == NULL)
+ return offset;
+ return e->new_address - e->orig_address + offset;
+}
+
+
+/* Build a binary searchable offset translation map from a section's
+ action list. */
+
+static xlate_map_t *
+build_xlate_map (asection *sec, xtensa_relax_info *relax_info)
+{
+ xlate_map_t *map = (xlate_map_t *) bfd_malloc (sizeof (xlate_map_t));
+ text_action_list *action_list = &relax_info->action_list;
+ unsigned num_actions = 0;
+ text_action *r;
+ int removed;
+ xlate_map_entry_t *current_entry;
+
+ if (map == NULL)
+ return NULL;
+
+ num_actions = action_list_count (action_list);
+ map->entry = (xlate_map_entry_t *)
+ bfd_malloc (sizeof (xlate_map_entry_t) * (num_actions + 1));
+ if (map->entry == NULL)
+ {
+ free (map);
+ return NULL;
+ }
+ map->entry_count = 0;
+
+ removed = 0;
+ current_entry = &map->entry[0];
+
+ current_entry->orig_address = 0;
+ current_entry->new_address = 0;
+ current_entry->size = 0;
+
+ for (r = action_list->head; r != NULL; r = r->next)
+ {
+ unsigned orig_size = 0;
+ switch (r->action)
+ {
+ case ta_none:
+ case ta_remove_insn:
+ case ta_convert_longcall:
+ case ta_remove_literal:
+ case ta_add_literal:
+ break;
+ case ta_remove_longcall:
+ orig_size = 6;
+ break;
+ case ta_narrow_insn:
+ orig_size = 3;
+ break;
+ case ta_widen_insn:
+ orig_size = 2;
+ break;
+ case ta_fill:
+ break;
+ }
+ current_entry->size =
+ r->offset + orig_size - current_entry->orig_address;
+ if (current_entry->size != 0)
+ {
+ current_entry++;
+ map->entry_count++;
+ }
+ current_entry->orig_address = r->offset + orig_size;
+ removed += r->removed_bytes;
+ current_entry->new_address = r->offset + orig_size - removed;
+ current_entry->size = 0;
+ }
+
+ current_entry->size = (bfd_get_section_limit (sec->owner, sec)
+ - current_entry->orig_address);
+ if (current_entry->size != 0)
+ map->entry_count++;
+
+ return map;
+}
+
+
+/* Free an offset translation map. */
+
+static void
+free_xlate_map (xlate_map_t *map)
+{
+ if (map && map->entry)
+ free (map->entry);
+ if (map)
+ free (map);
+}
+
+
+/* Use check_section_ebb_pcrels_fit to make sure that all of the
+ relocations in a section will fit if a proposed set of actions
+ are performed. */
+
+static bfd_boolean
+check_section_ebb_pcrels_fit (bfd *abfd,
+ asection *sec,
+ bfd_byte *contents,
+ Elf_Internal_Rela *internal_relocs,
+ const ebb_constraint *constraint,
+ const xtensa_opcode *reloc_opcodes)
+{
+ unsigned i, j;
+ Elf_Internal_Rela *irel;
+ xlate_map_t *xmap = NULL;
+ bfd_boolean ok = TRUE;
+ xtensa_relax_info *relax_info;
+
+ relax_info = get_xtensa_relax_info (sec);
+
+ if (relax_info && sec->reloc_count > 100)
+ {
+ xmap = build_xlate_map (sec, relax_info);
+ /* NULL indicates out of memory, but the slow version
+ can still be used. */
+ }
+
+ for (i = 0; i < sec->reloc_count; i++)
+ {
+ r_reloc r_rel;
+ bfd_vma orig_self_offset, orig_target_offset;
+ bfd_vma self_offset, target_offset;
+ int r_type;
+ reloc_howto_type *howto;
+ int self_removed_bytes, target_removed_bytes;
+
+ irel = &internal_relocs[i];
+ r_type = ELF32_R_TYPE (irel->r_info);
+
+ howto = &elf_howto_table[r_type];
+ /* We maintain the required invariant: PC-relative relocations
+ that fit before linking must fit after linking. Thus we only
+ need to deal with relocations to the same section that are
+ PC-relative. */
+ if (r_type == R_XTENSA_ASM_SIMPLIFY
+ || r_type == R_XTENSA_32_PCREL
+ || !howto->pc_relative)
+ continue;
+
+ r_reloc_init (&r_rel, abfd, irel, contents,
+ bfd_get_section_limit (abfd, sec));
+
+ if (r_reloc_get_section (&r_rel) != sec)
+ continue;
+
+ orig_self_offset = irel->r_offset;
+ orig_target_offset = r_rel.target_offset;
+
+ self_offset = orig_self_offset;
+ target_offset = orig_target_offset;
+
+ if (relax_info)
+ {
+ self_offset =
+ xlate_offset_with_removed_text (xmap, &relax_info->action_list,
+ orig_self_offset);
+ target_offset =
+ xlate_offset_with_removed_text (xmap, &relax_info->action_list,
+ orig_target_offset);
+ }
+
+ self_removed_bytes = 0;
+ target_removed_bytes = 0;
+
+ for (j = 0; j < constraint->action_count; ++j)
+ {
+ proposed_action *action = &constraint->actions[j];
+ bfd_vma offset = action->offset;
+ int removed_bytes = action->removed_bytes;
+ if (offset < orig_self_offset
+ || (offset == orig_self_offset && action->action == ta_fill
+ && action->removed_bytes < 0))
+ self_removed_bytes += removed_bytes;
+ if (offset < orig_target_offset
+ || (offset == orig_target_offset && action->action == ta_fill
+ && action->removed_bytes < 0))
+ target_removed_bytes += removed_bytes;
+ }
+ self_offset -= self_removed_bytes;
+ target_offset -= target_removed_bytes;
+
+ /* Try to encode it. Get the operand and check. */
+ if (is_alt_relocation (ELF32_R_TYPE (irel->r_info)))
+ {
+ /* None of the current alternate relocs are PC-relative,
+ and only PC-relative relocs matter here. */
+ }
+ else
+ {
+ xtensa_opcode opcode;
+ int opnum;
+
+ if (reloc_opcodes)
+ opcode = reloc_opcodes[i];
+ else
+ opcode = get_relocation_opcode (abfd, sec, contents, irel);
+ if (opcode == XTENSA_UNDEFINED)
+ {
+ ok = FALSE;
+ break;
+ }
+
+ opnum = get_relocation_opnd (opcode, ELF32_R_TYPE (irel->r_info));
+ if (opnum == XTENSA_UNDEFINED)
+ {
+ ok = FALSE;
+ break;
+ }
+
+ if (!pcrel_reloc_fits (opcode, opnum, self_offset, target_offset))
+ {
+ ok = FALSE;
+ break;
+ }
+ }
+ }
+
+ if (xmap)
+ free_xlate_map (xmap);
+
+ return ok;
+}
+
+
+static bfd_boolean
+check_section_ebb_reduces (const ebb_constraint *constraint)
+{
+ int removed = 0;
+ unsigned i;
+
+ for (i = 0; i < constraint->action_count; i++)
+ {
+ const proposed_action *action = &constraint->actions[i];
+ if (action->do_action)
+ removed += action->removed_bytes;
+ }
+ if (removed < 0)
+ return FALSE;
+
+ return TRUE;
+}
+
+
+void
+text_action_add_proposed (text_action_list *l,
+ const ebb_constraint *ebb_table,
+ asection *sec)
+{
+ unsigned i;
+
+ for (i = 0; i < ebb_table->action_count; i++)
+ {
+ proposed_action *action = &ebb_table->actions[i];
+
+ if (!action->do_action)
+ continue;
+ switch (action->action)
+ {
+ case ta_remove_insn:
+ case ta_remove_longcall:
+ case ta_convert_longcall:
+ case ta_narrow_insn:
+ case ta_widen_insn:
+ case ta_fill:
+ case ta_remove_literal:
+ text_action_add (l, action->action, sec, action->offset,
+ action->removed_bytes);
+ break;
+ case ta_none:
+ break;
+ default:
+ BFD_ASSERT (0);
+ break;
+ }
+ }
+}
+
+
+int
+compute_fill_extra_space (property_table_entry *entry)
+{
+ int fill_extra_space;
+
+ if (!entry)
+ return 0;
+
+ if ((entry->flags & XTENSA_PROP_UNREACHABLE) == 0)
+ return 0;
+
+ fill_extra_space = entry->size;
+ if ((entry->flags & XTENSA_PROP_ALIGN) != 0)
+ {
+ /* Fill bytes for alignment:
+ (2**n)-1 - (addr + (2**n)-1) & (2**n -1) */
+ int pow = GET_XTENSA_PROP_ALIGNMENT (entry->flags);
+ int nsm = (1 << pow) - 1;
+ bfd_vma addr = entry->address + entry->size;
+ bfd_vma align_fill = nsm - ((addr + nsm) & nsm);
+ fill_extra_space += align_fill;
+ }
+ return fill_extra_space;
+}
+
+
+/* First relaxation pass. */
+
+/* If the section contains relaxable literals, check each literal to
+ see if it has the same value as another literal that has already
+ been seen, either in the current section or a previous one. If so,
+ add an entry to the per-section list of removed literals. The
+ actual changes are deferred until the next pass. */
+
+static bfd_boolean
+compute_removed_literals (bfd *abfd,
+ asection *sec,
+ struct bfd_link_info *link_info,
+ value_map_hash_table *values)
+{
+ xtensa_relax_info *relax_info;
+ bfd_byte *contents;
+ Elf_Internal_Rela *internal_relocs;
+ source_reloc *src_relocs, *rel;
+ bfd_boolean ok = TRUE;
+ property_table_entry *prop_table = NULL;
+ int ptblsize;
+ int i, prev_i;
+ bfd_boolean last_loc_is_prev = FALSE;
+ bfd_vma last_target_offset = 0;
+ section_cache_t target_sec_cache;
+ bfd_size_type sec_size;
+
+ init_section_cache (&target_sec_cache);
+
+ /* Do nothing if it is not a relaxable literal section. */
+ relax_info = get_xtensa_relax_info (sec);
+ BFD_ASSERT (relax_info);
+ if (!relax_info->is_relaxable_literal_section)
+ return ok;
+
+ internal_relocs = retrieve_internal_relocs (abfd, sec,
+ link_info->keep_memory);
+
+ sec_size = bfd_get_section_limit (abfd, sec);
+ contents = retrieve_contents (abfd, sec, link_info->keep_memory);
+ if (contents == NULL && sec_size != 0)
+ {
+ ok = FALSE;
+ goto error_return;
+ }
+
+ /* Sort the source_relocs by target offset. */
+ src_relocs = relax_info->src_relocs;
+ qsort (src_relocs, relax_info->src_count,
+ sizeof (source_reloc), source_reloc_compare);
+ qsort (internal_relocs, sec->reloc_count, sizeof (Elf_Internal_Rela),
+ internal_reloc_compare);
+
+ ptblsize = xtensa_read_table_entries (abfd, sec, &prop_table,
+ XTENSA_PROP_SEC_NAME, FALSE);
+ if (ptblsize < 0)
+ {
+ ok = FALSE;
+ goto error_return;
+ }
+
+ prev_i = -1;
+ for (i = 0; i < relax_info->src_count; i++)
+ {
+ Elf_Internal_Rela *irel = NULL;
+
+ rel = &src_relocs[i];
+ if (get_l32r_opcode () != rel->opcode)
+ continue;
+ irel = get_irel_at_offset (sec, internal_relocs,
+ rel->r_rel.target_offset);
+
+ /* If the relocation on this is not a simple R_XTENSA_32 or
+ R_XTENSA_PLT then do not consider it. This may happen when
+ the difference of two symbols is used in a literal. */
+ if (irel && (ELF32_R_TYPE (irel->r_info) != R_XTENSA_32
+ && ELF32_R_TYPE (irel->r_info) != R_XTENSA_PLT))
+ continue;
+
+ /* If the target_offset for this relocation is the same as the
+ previous relocation, then we've already considered whether the
+ literal can be coalesced. Skip to the next one.... */
+ if (i != 0 && prev_i != -1
+ && src_relocs[i-1].r_rel.target_offset == rel->r_rel.target_offset)
+ continue;
+ prev_i = i;
+
+ if (last_loc_is_prev &&
+ last_target_offset + 4 != rel->r_rel.target_offset)
+ last_loc_is_prev = FALSE;
+
+ /* Check if the relocation was from an L32R that is being removed
+ because a CALLX was converted to a direct CALL, and check if
+ there are no other relocations to the literal. */
+ if (is_removable_literal (rel, i, src_relocs, relax_info->src_count,
+ sec, prop_table, ptblsize))
+ {
+ if (!remove_dead_literal (abfd, sec, link_info, internal_relocs,
+ irel, rel, prop_table, ptblsize))
+ {
+ ok = FALSE;
+ goto error_return;
+ }
+ last_target_offset = rel->r_rel.target_offset;
+ continue;
+ }
+
+ if (!identify_literal_placement (abfd, sec, contents, link_info,
+ values,
+ &last_loc_is_prev, irel,
+ relax_info->src_count - i, rel,
+ prop_table, ptblsize,
+ &target_sec_cache, rel->is_abs_literal))
+ {
+ ok = FALSE;
+ goto error_return;
+ }
+ last_target_offset = rel->r_rel.target_offset;
+ }
+
+#if DEBUG
+ print_removed_literals (stderr, &relax_info->removed_list);
+ print_action_list (stderr, &relax_info->action_list);
+#endif /* DEBUG */
+
+error_return:
+ if (prop_table)
+ free (prop_table);
+ free_section_cache (&target_sec_cache);
+
+ release_contents (sec, contents);
+ release_internal_relocs (sec, internal_relocs);
+ return ok;
+}
+
+
+static Elf_Internal_Rela *
+get_irel_at_offset (asection *sec,
+ Elf_Internal_Rela *internal_relocs,
+ bfd_vma offset)
+{
+ unsigned i;
+ Elf_Internal_Rela *irel;
+ unsigned r_type;
+ Elf_Internal_Rela key;
+
+ if (!internal_relocs)
+ return NULL;
+
+ key.r_offset = offset;
+ irel = bsearch (&key, internal_relocs, sec->reloc_count,
+ sizeof (Elf_Internal_Rela), internal_reloc_matches);
+ if (!irel)
+ return NULL;
+
+ /* bsearch does not guarantee which will be returned if there are
+ multiple matches. We need the first that is not an alignment. */
+ i = irel - internal_relocs;
+ while (i > 0)
+ {
+ if (internal_relocs[i-1].r_offset != offset)
+ break;
+ i--;
+ }
+ for ( ; i < sec->reloc_count; i++)
+ {
+ irel = &internal_relocs[i];
+ r_type = ELF32_R_TYPE (irel->r_info);
+ if (irel->r_offset == offset && r_type != R_XTENSA_NONE)
+ return irel;
+ }
+
+ return NULL;
+}
+
+
+bfd_boolean
+is_removable_literal (const source_reloc *rel,
+ int i,
+ const source_reloc *src_relocs,
+ int src_count,
+ asection *sec,
+ property_table_entry *prop_table,
+ int ptblsize)
+{
+ const source_reloc *curr_rel;
+ property_table_entry *entry;
+
+ if (!rel->is_null)
+ return FALSE;
+
+ entry = elf_xtensa_find_property_entry (prop_table, ptblsize,
+ sec->vma + rel->r_rel.target_offset);
+ if (entry && (entry->flags & XTENSA_PROP_NO_TRANSFORM))
+ return FALSE;
+
+ for (++i; i < src_count; ++i)
+ {
+ curr_rel = &src_relocs[i];
+ /* If all others have the same target offset.... */
+ if (curr_rel->r_rel.target_offset != rel->r_rel.target_offset)
+ return TRUE;
+
+ if (!curr_rel->is_null
+ && !xtensa_is_property_section (curr_rel->source_sec)
+ && !(curr_rel->source_sec->flags & SEC_DEBUGGING))
+ return FALSE;
+ }
+ return TRUE;
+}
+
+
+bfd_boolean
+remove_dead_literal (bfd *abfd,
+ asection *sec,
+ struct bfd_link_info *link_info,
+ Elf_Internal_Rela *internal_relocs,
+ Elf_Internal_Rela *irel,
+ source_reloc *rel,
+ property_table_entry *prop_table,
+ int ptblsize)
+{
+ property_table_entry *entry;
+ xtensa_relax_info *relax_info;
+
+ relax_info = get_xtensa_relax_info (sec);
+ if (!relax_info)
+ return FALSE;
+
+ entry = elf_xtensa_find_property_entry (prop_table, ptblsize,
+ sec->vma + rel->r_rel.target_offset);
+
+ /* Mark the unused literal so that it will be removed. */
+ add_removed_literal (&relax_info->removed_list, &rel->r_rel, NULL);
+
+ text_action_add (&relax_info->action_list,
+ ta_remove_literal, sec, rel->r_rel.target_offset, 4);
+
+ /* If the section is 4-byte aligned, do not add fill. */
+ if (sec->alignment_power > 2)
+ {
+ int fill_extra_space;
+ bfd_vma entry_sec_offset;
+ text_action *fa;
+ property_table_entry *the_add_entry;
+ int removed_diff;
+
+ if (entry)
+ entry_sec_offset = entry->address - sec->vma + entry->size;
+ else
+ entry_sec_offset = rel->r_rel.target_offset + 4;
+
+ /* If the literal range is at the end of the section,
+ do not add fill. */
+ the_add_entry = elf_xtensa_find_property_entry (prop_table, ptblsize,
+ entry_sec_offset);
+ fill_extra_space = compute_fill_extra_space (the_add_entry);
+
+ fa = find_fill_action (&relax_info->action_list, sec, entry_sec_offset);
+ removed_diff = compute_removed_action_diff (fa, sec, entry_sec_offset,
+ -4, fill_extra_space);
+ if (fa)
+ adjust_fill_action (fa, removed_diff);
+ else
+ text_action_add (&relax_info->action_list,
+ ta_fill, sec, entry_sec_offset, removed_diff);
+ }
+
+ /* Zero out the relocation on this literal location. */
+ if (irel)
+ {
+ if (elf_hash_table (link_info)->dynamic_sections_created)
+ shrink_dynamic_reloc_sections (link_info, abfd, sec, irel);
+
+ irel->r_info = ELF32_R_INFO (0, R_XTENSA_NONE);
+ pin_internal_relocs (sec, internal_relocs);
+ }
+
+ /* Do not modify "last_loc_is_prev". */
+ return TRUE;
+}
+
+
+bfd_boolean
+identify_literal_placement (bfd *abfd,
+ asection *sec,
+ bfd_byte *contents,
+ struct bfd_link_info *link_info,
+ value_map_hash_table *values,
+ bfd_boolean *last_loc_is_prev_p,
+ Elf_Internal_Rela *irel,
+ int remaining_src_rels,
+ source_reloc *rel,
+ property_table_entry *prop_table,
+ int ptblsize,
+ section_cache_t *target_sec_cache,
+ bfd_boolean is_abs_literal)
+{
+ literal_value val;
+ value_map *val_map;
+ xtensa_relax_info *relax_info;
+ bfd_boolean literal_placed = FALSE;
+ r_reloc r_rel;
+ unsigned long value;
+ bfd_boolean final_static_link;
+ bfd_size_type sec_size;
+
+ relax_info = get_xtensa_relax_info (sec);
+ if (!relax_info)
+ return FALSE;
+
+ sec_size = bfd_get_section_limit (abfd, sec);
+
+ final_static_link =
+ (!link_info->relocatable
+ && !elf_hash_table (link_info)->dynamic_sections_created);
+
+ /* The placement algorithm first checks to see if the literal is
+ already in the value map. If so and the value map is reachable
+ from all uses, then the literal is moved to that location. If
+ not, then we identify the last location where a fresh literal was
+ placed. If the literal can be safely moved there, then we do so.
+ If not, then we assume that the literal is not to move and leave
+ the literal where it is, marking it as the last literal
+ location. */
+
+ /* Find the literal value. */
+ value = 0;
+ r_reloc_init (&r_rel, abfd, irel, contents, sec_size);
+ if (!irel)
+ {
+ BFD_ASSERT (rel->r_rel.target_offset < sec_size);
+ value = bfd_get_32 (abfd, contents + rel->r_rel.target_offset);
+ }
+ init_literal_value (&val, &r_rel, value, is_abs_literal);
+
+ /* Check if we've seen another literal with the same value that
+ is in the same output section. */
+ val_map = value_map_get_cached_value (values, &val, final_static_link);
+
+ if (val_map
+ && (r_reloc_get_section (&val_map->loc)->output_section
+ == sec->output_section)
+ && relocations_reach (rel, remaining_src_rels, &val_map->loc)
+ && coalesce_shared_literal (sec, rel, prop_table, ptblsize, val_map))
+ {
+ /* No change to last_loc_is_prev. */
+ literal_placed = TRUE;
+ }
+
+ /* For relocatable links, do not try to move literals. To do it
+ correctly might increase the number of relocations in an input
+ section making the default relocatable linking fail. */
+ if (!link_info->relocatable && !literal_placed
+ && values->has_last_loc && !(*last_loc_is_prev_p))
+ {
+ asection *target_sec = r_reloc_get_section (&values->last_loc);
+ if (target_sec && target_sec->output_section == sec->output_section)
+ {
+ /* Increment the virtual offset. */
+ r_reloc try_loc = values->last_loc;
+ try_loc.virtual_offset += 4;
+
+ /* There is a last loc that was in the same output section. */
+ if (relocations_reach (rel, remaining_src_rels, &try_loc)
+ && move_shared_literal (sec, link_info, rel,
+ prop_table, ptblsize,
+ &try_loc, &val, target_sec_cache))
+ {
+ values->last_loc.virtual_offset += 4;
+ literal_placed = TRUE;
+ if (!val_map)
+ val_map = add_value_map (values, &val, &try_loc,
+ final_static_link);
+ else
+ val_map->loc = try_loc;
+ }
+ }
+ }
+
+ if (!literal_placed)
+ {
+ /* Nothing worked, leave the literal alone but update the last loc. */
+ values->has_last_loc = TRUE;
+ values->last_loc = rel->r_rel;
+ if (!val_map)
+ val_map = add_value_map (values, &val, &rel->r_rel, final_static_link);
+ else
+ val_map->loc = rel->r_rel;
+ *last_loc_is_prev_p = TRUE;
+ }
+
+ return TRUE;
+}
+
+
+/* Check if the original relocations (presumably on L32R instructions)
+ identified by reloc[0..N] can be changed to reference the literal
+ identified by r_rel. If r_rel is out of range for any of the
+ original relocations, then we don't want to coalesce the original
+ literal with the one at r_rel. We only check reloc[0..N], where the
+ offsets are all the same as for reloc[0] (i.e., they're all
+ referencing the same literal) and where N is also bounded by the
+ number of remaining entries in the "reloc" array. The "reloc" array
+ is sorted by target offset so we know all the entries for the same
+ literal will be contiguous. */
+
+static bfd_boolean
+relocations_reach (source_reloc *reloc,
+ int remaining_relocs,
+ const r_reloc *r_rel)
+{
+ bfd_vma from_offset, source_address, dest_address;
+ asection *sec;
+ int i;
+
+ if (!r_reloc_is_defined (r_rel))
+ return FALSE;
+
+ sec = r_reloc_get_section (r_rel);
+ from_offset = reloc[0].r_rel.target_offset;
+
+ for (i = 0; i < remaining_relocs; i++)
+ {
+ if (reloc[i].r_rel.target_offset != from_offset)
+ break;
+
+ /* Ignore relocations that have been removed. */
+ if (reloc[i].is_null)
+ continue;
+
+ /* The original and new output section for these must be the same
+ in order to coalesce. */
+ if (r_reloc_get_section (&reloc[i].r_rel)->output_section
+ != sec->output_section)
+ return FALSE;
+
+ /* Absolute literals in the same output section can always be
+ combined. */
+ if (reloc[i].is_abs_literal)
+ continue;
+
+ /* A literal with no PC-relative relocations can be moved anywhere. */
+ if (reloc[i].opnd != -1)
+ {
+ /* Otherwise, check to see that it fits. */
+ source_address = (reloc[i].source_sec->output_section->vma
+ + reloc[i].source_sec->output_offset
+ + reloc[i].r_rel.rela.r_offset);
+ dest_address = (sec->output_section->vma
+ + sec->output_offset
+ + r_rel->target_offset);
+
+ if (!pcrel_reloc_fits (reloc[i].opcode, reloc[i].opnd,
+ source_address, dest_address))
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+
+/* Move a literal to another literal location because it is
+ the same as the other literal value. */
+
+static bfd_boolean
+coalesce_shared_literal (asection *sec,
+ source_reloc *rel,
+ property_table_entry *prop_table,
+ int ptblsize,
+ value_map *val_map)
+{
+ property_table_entry *entry;
+ text_action *fa;
+ property_table_entry *the_add_entry;
+ int removed_diff;
+ xtensa_relax_info *relax_info;
+
+ relax_info = get_xtensa_relax_info (sec);
+ if (!relax_info)
+ return FALSE;
+
+ entry = elf_xtensa_find_property_entry
+ (prop_table, ptblsize, sec->vma + rel->r_rel.target_offset);
+ if (entry && (entry->flags & XTENSA_PROP_NO_TRANSFORM))
+ return TRUE;
+
+ /* Mark that the literal will be coalesced. */
+ add_removed_literal (&relax_info->removed_list, &rel->r_rel, &val_map->loc);
+
+ text_action_add (&relax_info->action_list,
+ ta_remove_literal, sec, rel->r_rel.target_offset, 4);
+
+ /* If the section is 4-byte aligned, do not add fill. */
+ if (sec->alignment_power > 2)
+ {
+ int fill_extra_space;
+ bfd_vma entry_sec_offset;
+
+ if (entry)
+ entry_sec_offset = entry->address - sec->vma + entry->size;
+ else
+ entry_sec_offset = rel->r_rel.target_offset + 4;
+
+ /* If the literal range is at the end of the section,
+ do not add fill. */
+ fill_extra_space = 0;
+ the_add_entry = elf_xtensa_find_property_entry (prop_table, ptblsize,
+ entry_sec_offset);
+ if (the_add_entry && (the_add_entry->flags & XTENSA_PROP_UNREACHABLE))
+ fill_extra_space = the_add_entry->size;
+
+ fa = find_fill_action (&relax_info->action_list, sec, entry_sec_offset);
+ removed_diff = compute_removed_action_diff (fa, sec, entry_sec_offset,
+ -4, fill_extra_space);
+ if (fa)
+ adjust_fill_action (fa, removed_diff);
+ else
+ text_action_add (&relax_info->action_list,
+ ta_fill, sec, entry_sec_offset, removed_diff);
+ }
+
+ return TRUE;
+}
+
+
+/* Move a literal to another location. This may actually increase the
+ total amount of space used because of alignments so we need to do
+ this carefully. Also, it may make a branch go out of range. */
+
+static bfd_boolean
+move_shared_literal (asection *sec,
+ struct bfd_link_info *link_info,
+ source_reloc *rel,
+ property_table_entry *prop_table,
+ int ptblsize,
+ const r_reloc *target_loc,
+ const literal_value *lit_value,
+ section_cache_t *target_sec_cache)
+{
+ property_table_entry *the_add_entry, *src_entry, *target_entry = NULL;
+ text_action *fa, *target_fa;
+ int removed_diff;
+ xtensa_relax_info *relax_info, *target_relax_info;
+ asection *target_sec;
+ ebb_t *ebb;
+ ebb_constraint ebb_table;
+ bfd_boolean relocs_fit;
+
+ /* If this routine always returns FALSE, the literals that cannot be
+ coalesced will not be moved. */
+ if (elf32xtensa_no_literal_movement)
+ return FALSE;
+
+ relax_info = get_xtensa_relax_info (sec);
+ if (!relax_info)
+ return FALSE;
+
+ target_sec = r_reloc_get_section (target_loc);
+ target_relax_info = get_xtensa_relax_info (target_sec);
+
+ /* Literals to undefined sections may not be moved because they
+ must report an error. */
+ if (bfd_is_und_section (target_sec))
+ return FALSE;
+
+ src_entry = elf_xtensa_find_property_entry
+ (prop_table, ptblsize, sec->vma + rel->r_rel.target_offset);
+
+ if (!section_cache_section (target_sec_cache, target_sec, link_info))
+ return FALSE;
+
+ target_entry = elf_xtensa_find_property_entry
+ (target_sec_cache->ptbl, target_sec_cache->pte_count,
+ target_sec->vma + target_loc->target_offset);
+
+ if (!target_entry)
+ return FALSE;
+
+ /* Make sure that we have not broken any branches. */
+ relocs_fit = FALSE;
+
+ init_ebb_constraint (&ebb_table);
+ ebb = &ebb_table.ebb;
+ init_ebb (ebb, target_sec_cache->sec, target_sec_cache->contents,
+ target_sec_cache->content_length,
+ target_sec_cache->ptbl, target_sec_cache->pte_count,
+ target_sec_cache->relocs, target_sec_cache->reloc_count);
+
+ /* Propose to add 4 bytes + worst-case alignment size increase to
+ destination. */
+ ebb_propose_action (&ebb_table, EBB_NO_ALIGN, 0,
+ ta_fill, target_loc->target_offset,
+ -4 - (1 << target_sec->alignment_power), TRUE);
+
+ /* Check all of the PC-relative relocations to make sure they still fit. */
+ relocs_fit = check_section_ebb_pcrels_fit (target_sec->owner, target_sec,
+ target_sec_cache->contents,
+ target_sec_cache->relocs,
+ &ebb_table, NULL);
+
+ if (!relocs_fit)
+ return FALSE;
+
+ text_action_add_literal (&target_relax_info->action_list,
+ ta_add_literal, target_loc, lit_value, -4);
+
+ if (target_sec->alignment_power > 2 && target_entry != src_entry)
+ {
+ /* May need to add or remove some fill to maintain alignment. */
+ int fill_extra_space;
+ bfd_vma entry_sec_offset;
+
+ entry_sec_offset =
+ target_entry->address - target_sec->vma + target_entry->size;
+
+ /* If the literal range is at the end of the section,
+ do not add fill. */
+ fill_extra_space = 0;
+ the_add_entry =
+ elf_xtensa_find_property_entry (target_sec_cache->ptbl,
+ target_sec_cache->pte_count,
+ entry_sec_offset);
+ if (the_add_entry && (the_add_entry->flags & XTENSA_PROP_UNREACHABLE))
+ fill_extra_space = the_add_entry->size;
+
+ target_fa = find_fill_action (&target_relax_info->action_list,
+ target_sec, entry_sec_offset);
+ removed_diff = compute_removed_action_diff (target_fa, target_sec,
+ entry_sec_offset, 4,
+ fill_extra_space);
+ if (target_fa)
+ adjust_fill_action (target_fa, removed_diff);
+ else
+ text_action_add (&target_relax_info->action_list,
+ ta_fill, target_sec, entry_sec_offset, removed_diff);
+ }
+
+ /* Mark that the literal will be moved to the new location. */
+ add_removed_literal (&relax_info->removed_list, &rel->r_rel, target_loc);
+
+ /* Remove the literal. */
+ text_action_add (&relax_info->action_list,
+ ta_remove_literal, sec, rel->r_rel.target_offset, 4);
+
+ /* If the section is 4-byte aligned, do not add fill. */
+ if (sec->alignment_power > 2 && target_entry != src_entry)
+ {
+ int fill_extra_space;
+ bfd_vma entry_sec_offset;
+
+ if (src_entry)
+ entry_sec_offset = src_entry->address - sec->vma + src_entry->size;
+ else
+ entry_sec_offset = rel->r_rel.target_offset+4;
+
+ /* If the literal range is at the end of the section,
+ do not add fill. */
+ fill_extra_space = 0;
+ the_add_entry = elf_xtensa_find_property_entry (prop_table, ptblsize,
+ entry_sec_offset);
+ if (the_add_entry && (the_add_entry->flags & XTENSA_PROP_UNREACHABLE))
+ fill_extra_space = the_add_entry->size;
+
+ fa = find_fill_action (&relax_info->action_list, sec, entry_sec_offset);
+ removed_diff = compute_removed_action_diff (fa, sec, entry_sec_offset,
+ -4, fill_extra_space);
+ if (fa)
+ adjust_fill_action (fa, removed_diff);
+ else
+ text_action_add (&relax_info->action_list,
+ ta_fill, sec, entry_sec_offset, removed_diff);
+ }
+
+ return TRUE;
+}
+
+
+/* Second relaxation pass. */
+
+/* Modify all of the relocations to point to the right spot, and if this
+ is a relaxable section, delete the unwanted literals and fix the
+ section size. */
+
+bfd_boolean
+relax_section (bfd *abfd, asection *sec, struct bfd_link_info *link_info)
+{
+ Elf_Internal_Rela *internal_relocs;
+ xtensa_relax_info *relax_info;
+ bfd_byte *contents;
+ bfd_boolean ok = TRUE;
+ unsigned i;
+ bfd_boolean rv = FALSE;
+ bfd_boolean virtual_action;
+ bfd_size_type sec_size;
+
+ sec_size = bfd_get_section_limit (abfd, sec);
+ relax_info = get_xtensa_relax_info (sec);
+ BFD_ASSERT (relax_info);
+
+ /* First translate any of the fixes that have been added already. */
+ translate_section_fixes (sec);
+
+ /* Handle property sections (e.g., literal tables) specially. */
+ if (xtensa_is_property_section (sec))
+ {
+ BFD_ASSERT (!relax_info->is_relaxable_literal_section);
+ return relax_property_section (abfd, sec, link_info);
+ }
+
+ internal_relocs = retrieve_internal_relocs (abfd, sec,
+ link_info->keep_memory);
+ if (!internal_relocs && !relax_info->action_list.head)
+ return TRUE;
+
+ contents = retrieve_contents (abfd, sec, link_info->keep_memory);
+ if (contents == NULL && sec_size != 0)
+ {
+ ok = FALSE;
+ goto error_return;
+ }
+
+ if (internal_relocs)
+ {
+ for (i = 0; i < sec->reloc_count; i++)
+ {
+ Elf_Internal_Rela *irel;
+ xtensa_relax_info *target_relax_info;
+ bfd_vma source_offset, old_source_offset;
+ r_reloc r_rel;
+ unsigned r_type;
+ asection *target_sec;
+
+ /* Locally change the source address.
+ Translate the target to the new target address.
+ If it points to this section and has been removed,
+ NULLify it.
+ Write it back. */
+
+ irel = &internal_relocs[i];
+ source_offset = irel->r_offset;
+ old_source_offset = source_offset;
+
+ r_type = ELF32_R_TYPE (irel->r_info);
+ r_reloc_init (&r_rel, abfd, irel, contents,
+ bfd_get_section_limit (abfd, sec));
+
+ /* If this section could have changed then we may need to
+ change the relocation's offset. */
+
+ if (relax_info->is_relaxable_literal_section
+ || relax_info->is_relaxable_asm_section)
+ {
+ pin_internal_relocs (sec, internal_relocs);
+
+ if (r_type != R_XTENSA_NONE
+ && find_removed_literal (&relax_info->removed_list,
+ irel->r_offset))
+ {
+ /* Remove this relocation. */
+ if (elf_hash_table (link_info)->dynamic_sections_created)
+ shrink_dynamic_reloc_sections (link_info, abfd, sec, irel);
+ irel->r_info = ELF32_R_INFO (0, R_XTENSA_NONE);
+ irel->r_offset = offset_with_removed_text
+ (&relax_info->action_list, irel->r_offset);
+ continue;
+ }
+
+ if (r_type == R_XTENSA_ASM_SIMPLIFY)
+ {
+ text_action *action =
+ find_insn_action (&relax_info->action_list,
+ irel->r_offset);
+ if (action && (action->action == ta_convert_longcall
+ || action->action == ta_remove_longcall))
+ {
+ bfd_reloc_status_type retval;
+ char *error_message = NULL;
+
+ retval = contract_asm_expansion (contents, sec_size,
+ irel, &error_message);
+ if (retval != bfd_reloc_ok)
+ {
+ (*link_info->callbacks->reloc_dangerous)
+ (link_info, error_message, abfd, sec,
+ irel->r_offset);
+ goto error_return;
+ }
+ /* Update the action so that the code that moves
+ the contents will do the right thing. */
+ if (action->action == ta_remove_longcall)
+ action->action = ta_remove_insn;
+ else
+ action->action = ta_none;
+ /* Refresh the info in the r_rel. */
+ r_reloc_init (&r_rel, abfd, irel, contents, sec_size);
+ r_type = ELF32_R_TYPE (irel->r_info);
+ }
+ }
+
+ source_offset = offset_with_removed_text
+ (&relax_info->action_list, irel->r_offset);
+ irel->r_offset = source_offset;
+ }
+
+ /* If the target section could have changed then
+ we may need to change the relocation's target offset. */
+
+ target_sec = r_reloc_get_section (&r_rel);
+
+ /* For a reference to a discarded section from a DWARF section,
+ i.e., where action_discarded is PRETEND, the symbol will
+ eventually be modified to refer to the kept section (at least if
+ the kept and discarded sections are the same size). Anticipate
+ that here and adjust things accordingly. */
+ if (! elf_xtensa_ignore_discarded_relocs (sec)
+ && elf_xtensa_action_discarded (sec) == PRETEND
+ && sec->sec_info_type != SEC_INFO_TYPE_STABS
+ && target_sec != NULL
+ && discarded_section (target_sec))
+ {
+ /* It would be natural to call _bfd_elf_check_kept_section
+ here, but it's not exported from elflink.c. It's also a
+ fairly expensive check. Adjusting the relocations to the
+ discarded section is fairly harmless; it will only adjust
+ some addends and difference values. If it turns out that
+ _bfd_elf_check_kept_section fails later, it won't matter,
+ so just compare the section names to find the right group
+ member. */
+ asection *kept = target_sec->kept_section;
+ if (kept != NULL)
+ {
+ if ((kept->flags & SEC_GROUP) != 0)
+ {
+ asection *first = elf_next_in_group (kept);
+ asection *s = first;
+
+ kept = NULL;
+ while (s != NULL)
+ {
+ if (strcmp (s->name, target_sec->name) == 0)
+ {
+ kept = s;
+ break;
+ }
+ s = elf_next_in_group (s);
+ if (s == first)
+ break;
+ }
+ }
+ }
+ if (kept != NULL
+ && ((target_sec->rawsize != 0
+ ? target_sec->rawsize : target_sec->size)
+ == (kept->rawsize != 0 ? kept->rawsize : kept->size)))
+ target_sec = kept;
+ }
+
+ target_relax_info = get_xtensa_relax_info (target_sec);
+ if (target_relax_info
+ && (target_relax_info->is_relaxable_literal_section
+ || target_relax_info->is_relaxable_asm_section))
+ {
+ r_reloc new_reloc;
+ target_sec = translate_reloc (&r_rel, &new_reloc, target_sec);
+
+ if (r_type == R_XTENSA_DIFF8
+ || r_type == R_XTENSA_DIFF16
+ || r_type == R_XTENSA_DIFF32)
+ {
+ bfd_signed_vma diff_value = 0;
+ bfd_vma new_end_offset, diff_mask = 0;
+
+ if (bfd_get_section_limit (abfd, sec) < old_source_offset)
+ {
+ (*link_info->callbacks->reloc_dangerous)
+ (link_info, _("invalid relocation address"),
+ abfd, sec, old_source_offset);
+ goto error_return;
+ }
+
+ switch (r_type)
+ {
+ case R_XTENSA_DIFF8:
+ diff_value =
+ bfd_get_signed_8 (abfd, &contents[old_source_offset]);
+ break;
+ case R_XTENSA_DIFF16:
+ diff_value =
+ bfd_get_signed_16 (abfd, &contents[old_source_offset]);
+ break;
+ case R_XTENSA_DIFF32:
+ diff_value =
+ bfd_get_signed_32 (abfd, &contents[old_source_offset]);
+ break;
+ }
+
+ new_end_offset = offset_with_removed_text
+ (&target_relax_info->action_list,
+ r_rel.target_offset + diff_value);
+ diff_value = new_end_offset - new_reloc.target_offset;
+
+ switch (r_type)
+ {
+ case R_XTENSA_DIFF8:
+ diff_mask = 0x7f;
+ bfd_put_signed_8 (abfd, diff_value,
+ &contents[old_source_offset]);
+ break;
+ case R_XTENSA_DIFF16:
+ diff_mask = 0x7fff;
+ bfd_put_signed_16 (abfd, diff_value,
+ &contents[old_source_offset]);
+ break;
+ case R_XTENSA_DIFF32:
+ diff_mask = 0x7fffffff;
+ bfd_put_signed_32 (abfd, diff_value,
+ &contents[old_source_offset]);
+ break;
+ }
+
+ /* Check for overflow. Sign bits must be all zeroes or all ones */
+ if ((diff_value & ~diff_mask) != 0 &&
+ (diff_value & ~diff_mask) != (-1 & ~diff_mask))
+ {
+ (*link_info->callbacks->reloc_dangerous)
+ (link_info, _("overflow after relaxation"),
+ abfd, sec, old_source_offset);
+ goto error_return;
+ }
+
+ pin_contents (sec, contents);
+ }
+
+ /* If the relocation still references a section in the same
+ input file, modify the relocation directly instead of
+ adding a "fix" record. */
+ if (target_sec->owner == abfd)
+ {
+ unsigned r_symndx = ELF32_R_SYM (new_reloc.rela.r_info);
+ irel->r_info = ELF32_R_INFO (r_symndx, r_type);
+ irel->r_addend = new_reloc.rela.r_addend;
+ pin_internal_relocs (sec, internal_relocs);
+ }
+ else
+ {
+ bfd_vma addend_displacement;
+ reloc_bfd_fix *fix;
+
+ addend_displacement =
+ new_reloc.target_offset + new_reloc.virtual_offset;
+ fix = reloc_bfd_fix_init (sec, source_offset, r_type,
+ target_sec,
+ addend_displacement, TRUE);
+ add_fix (sec, fix);
+ }
+ }
+ }
+ }
+
+ if ((relax_info->is_relaxable_literal_section
+ || relax_info->is_relaxable_asm_section)
+ && relax_info->action_list.head)
+ {
+ /* Walk through the planned actions and build up a table
+ of move, copy and fill records. Use the move, copy and
+ fill records to perform the actions once. */
+
+ int removed = 0;
+ bfd_size_type final_size, copy_size, orig_insn_size;
+ bfd_byte *scratch = NULL;
+ bfd_byte *dup_contents = NULL;
+ bfd_size_type orig_size = sec->size;
+ bfd_vma orig_dot = 0;
+ bfd_vma orig_dot_copied = 0; /* Byte copied already from
+ orig dot in physical memory. */
+ bfd_vma orig_dot_vo = 0; /* Virtual offset from orig_dot. */
+ bfd_vma dup_dot = 0;
+
+ text_action *action = relax_info->action_list.head;
+
+ final_size = sec->size;
+ for (action = relax_info->action_list.head; action;
+ action = action->next)
+ {
+ final_size -= action->removed_bytes;
+ }
+
+ scratch = (bfd_byte *) bfd_zmalloc (final_size);
+ dup_contents = (bfd_byte *) bfd_zmalloc (final_size);
+
+ /* The dot is the current fill location. */
+#if DEBUG
+ print_action_list (stderr, &relax_info->action_list);
+#endif
+
+ for (action = relax_info->action_list.head; action;
+ action = action->next)
+ {
+ virtual_action = FALSE;
+ if (action->offset > orig_dot)
+ {
+ orig_dot += orig_dot_copied;
+ orig_dot_copied = 0;
+ orig_dot_vo = 0;
+ /* Out of the virtual world. */
+ }
+
+ if (action->offset > orig_dot)
+ {
+ copy_size = action->offset - orig_dot;
+ memmove (&dup_contents[dup_dot], &contents[orig_dot], copy_size);
+ orig_dot += copy_size;
+ dup_dot += copy_size;
+ BFD_ASSERT (action->offset == orig_dot);
+ }
+ else if (action->offset < orig_dot)
+ {
+ if (action->action == ta_fill
+ && action->offset - action->removed_bytes == orig_dot)
+ {
+ /* This is OK because the fill only effects the dup_dot. */
+ }
+ else if (action->action == ta_add_literal)
+ {
+ /* TBD. Might need to handle this. */
+ }
+ }
+ if (action->offset == orig_dot)
+ {
+ if (action->virtual_offset > orig_dot_vo)
+ {
+ if (orig_dot_vo == 0)
+ {
+ /* Need to copy virtual_offset bytes. Probably four. */
+ copy_size = action->virtual_offset - orig_dot_vo;
+ memmove (&dup_contents[dup_dot],
+ &contents[orig_dot], copy_size);
+ orig_dot_copied = copy_size;
+ dup_dot += copy_size;
+ }
+ virtual_action = TRUE;
+ }
+ else
+ BFD_ASSERT (action->virtual_offset <= orig_dot_vo);
+ }
+ switch (action->action)
+ {
+ case ta_remove_literal:
+ case ta_remove_insn:
+ BFD_ASSERT (action->removed_bytes >= 0);
+ orig_dot += action->removed_bytes;
+ break;
+
+ case ta_narrow_insn:
+ orig_insn_size = 3;
+ copy_size = 2;
+ memmove (scratch, &contents[orig_dot], orig_insn_size);
+ BFD_ASSERT (action->removed_bytes == 1);
+ rv = narrow_instruction (scratch, final_size, 0);
+ BFD_ASSERT (rv);
+ memmove (&dup_contents[dup_dot], scratch, copy_size);
+ orig_dot += orig_insn_size;
+ dup_dot += copy_size;
+ break;
+
+ case ta_fill:
+ if (action->removed_bytes >= 0)
+ orig_dot += action->removed_bytes;
+ else
+ {
+ /* Already zeroed in dup_contents. Just bump the
+ counters. */
+ dup_dot += (-action->removed_bytes);
+ }
+ break;
+
+ case ta_none:
+ BFD_ASSERT (action->removed_bytes == 0);
+ break;
+
+ case ta_convert_longcall:
+ case ta_remove_longcall:
+ /* These will be removed or converted before we get here. */
+ BFD_ASSERT (0);
+ break;
+
+ case ta_widen_insn:
+ orig_insn_size = 2;
+ copy_size = 3;
+ memmove (scratch, &contents[orig_dot], orig_insn_size);
+ BFD_ASSERT (action->removed_bytes == -1);
+ rv = widen_instruction (scratch, final_size, 0);
+ BFD_ASSERT (rv);
+ memmove (&dup_contents[dup_dot], scratch, copy_size);
+ orig_dot += orig_insn_size;
+ dup_dot += copy_size;
+ break;
+
+ case ta_add_literal:
+ orig_insn_size = 0;
+ copy_size = 4;
+ BFD_ASSERT (action->removed_bytes == -4);
+ /* TBD -- place the literal value here and insert
+ into the table. */
+ memset (&dup_contents[dup_dot], 0, 4);
+ pin_internal_relocs (sec, internal_relocs);
+ pin_contents (sec, contents);
+
+ if (!move_literal (abfd, link_info, sec, dup_dot, dup_contents,
+ relax_info, &internal_relocs, &action->value))
+ goto error_return;
+
+ if (virtual_action)
+ orig_dot_vo += copy_size;
+
+ orig_dot += orig_insn_size;
+ dup_dot += copy_size;
+ break;
+
+ default:
+ /* Not implemented yet. */
+ BFD_ASSERT (0);
+ break;
+ }
+
+ removed += action->removed_bytes;
+ BFD_ASSERT (dup_dot <= final_size);
+ BFD_ASSERT (orig_dot <= orig_size);
+ }
+
+ orig_dot += orig_dot_copied;
+ orig_dot_copied = 0;
+
+ if (orig_dot != orig_size)
+ {
+ copy_size = orig_size - orig_dot;
+ BFD_ASSERT (orig_size > orig_dot);
+ BFD_ASSERT (dup_dot + copy_size == final_size);
+ memmove (&dup_contents[dup_dot], &contents[orig_dot], copy_size);
+ orig_dot += copy_size;
+ dup_dot += copy_size;
+ }
+ BFD_ASSERT (orig_size == orig_dot);
+ BFD_ASSERT (final_size == dup_dot);
+
+ /* Move the dup_contents back. */
+ if (final_size > orig_size)
+ {
+ /* Contents need to be reallocated. Swap the dup_contents into
+ contents. */
+ sec->contents = dup_contents;
+ free (contents);
+ contents = dup_contents;
+ pin_contents (sec, contents);
+ }
+ else
+ {
+ BFD_ASSERT (final_size <= orig_size);
+ memset (contents, 0, orig_size);
+ memcpy (contents, dup_contents, final_size);
+ free (dup_contents);
+ }
+ free (scratch);
+ pin_contents (sec, contents);
+
+ if (sec->rawsize == 0)
+ sec->rawsize = sec->size;
+ sec->size = final_size;
+ }
+
+ error_return:
+ release_internal_relocs (sec, internal_relocs);
+ release_contents (sec, contents);
+ return ok;
+}
+
+
+static bfd_boolean
+translate_section_fixes (asection *sec)
+{
+ xtensa_relax_info *relax_info;
+ reloc_bfd_fix *r;
+
+ relax_info = get_xtensa_relax_info (sec);
+ if (!relax_info)
+ return TRUE;
+
+ for (r = relax_info->fix_list; r != NULL; r = r->next)
+ if (!translate_reloc_bfd_fix (r))
+ return FALSE;
+
+ return TRUE;
+}
+
+
+/* Translate a fix given the mapping in the relax info for the target
+ section. If it has already been translated, no work is required. */
+
+static bfd_boolean
+translate_reloc_bfd_fix (reloc_bfd_fix *fix)
+{
+ reloc_bfd_fix new_fix;
+ asection *sec;
+ xtensa_relax_info *relax_info;
+ removed_literal *removed;
+ bfd_vma new_offset, target_offset;
+
+ if (fix->translated)
+ return TRUE;
+
+ sec = fix->target_sec;
+ target_offset = fix->target_offset;
+
+ relax_info = get_xtensa_relax_info (sec);
+ if (!relax_info)
+ {
+ fix->translated = TRUE;
+ return TRUE;
+ }
+
+ new_fix = *fix;
+
+ /* The fix does not need to be translated if the section cannot change. */
+ if (!relax_info->is_relaxable_literal_section
+ && !relax_info->is_relaxable_asm_section)
+ {
+ fix->translated = TRUE;
+ return TRUE;
+ }
+
+ /* If the literal has been moved and this relocation was on an
+ opcode, then the relocation should move to the new literal
+ location. Otherwise, the relocation should move within the
+ section. */
+
+ removed = FALSE;
+ if (is_operand_relocation (fix->src_type))
+ {
+ /* Check if the original relocation is against a literal being
+ removed. */
+ removed = find_removed_literal (&relax_info->removed_list,
+ target_offset);
+ }
+
+ if (removed)
+ {
+ asection *new_sec;
+
+ /* The fact that there is still a relocation to this literal indicates
+ that the literal is being coalesced, not simply removed. */
+ BFD_ASSERT (removed->to.abfd != NULL);
+
+ /* This was moved to some other address (possibly another section). */
+ new_sec = r_reloc_get_section (&removed->to);
+ if (new_sec != sec)
+ {
+ sec = new_sec;
+ relax_info = get_xtensa_relax_info (sec);
+ if (!relax_info ||
+ (!relax_info->is_relaxable_literal_section
+ && !relax_info->is_relaxable_asm_section))
+ {
+ target_offset = removed->to.target_offset;
+ new_fix.target_sec = new_sec;
+ new_fix.target_offset = target_offset;
+ new_fix.translated = TRUE;
+ *fix = new_fix;
+ return TRUE;
+ }
+ }
+ target_offset = removed->to.target_offset;
+ new_fix.target_sec = new_sec;
+ }
+
+ /* The target address may have been moved within its section. */
+ new_offset = offset_with_removed_text (&relax_info->action_list,
+ target_offset);
+
+ new_fix.target_offset = new_offset;
+ new_fix.target_offset = new_offset;
+ new_fix.translated = TRUE;
+ *fix = new_fix;
+ return TRUE;
+}
+
+
+/* Fix up a relocation to take account of removed literals. */
+
+static asection *
+translate_reloc (const r_reloc *orig_rel, r_reloc *new_rel, asection *sec)
+{
+ xtensa_relax_info *relax_info;
+ removed_literal *removed;
+ bfd_vma target_offset, base_offset;
+ text_action *act;
+
+ *new_rel = *orig_rel;
+
+ if (!r_reloc_is_defined (orig_rel))
+ return sec ;
+
+ relax_info = get_xtensa_relax_info (sec);
+ BFD_ASSERT (relax_info && (relax_info->is_relaxable_literal_section
+ || relax_info->is_relaxable_asm_section));
+
+ target_offset = orig_rel->target_offset;
+
+ removed = FALSE;
+ if (is_operand_relocation (ELF32_R_TYPE (orig_rel->rela.r_info)))
+ {
+ /* Check if the original relocation is against a literal being
+ removed. */
+ removed = find_removed_literal (&relax_info->removed_list,
+ target_offset);
+ }
+ if (removed && removed->to.abfd)
+ {
+ asection *new_sec;
+
+ /* The fact that there is still a relocation to this literal indicates
+ that the literal is being coalesced, not simply removed. */
+ BFD_ASSERT (removed->to.abfd != NULL);
+
+ /* This was moved to some other address
+ (possibly in another section). */
+ *new_rel = removed->to;
+ new_sec = r_reloc_get_section (new_rel);
+ if (new_sec != sec)
+ {
+ sec = new_sec;
+ relax_info = get_xtensa_relax_info (sec);
+ if (!relax_info
+ || (!relax_info->is_relaxable_literal_section
+ && !relax_info->is_relaxable_asm_section))
+ return sec;
+ }
+ target_offset = new_rel->target_offset;
+ }
+
+ /* Find the base offset of the reloc symbol, excluding any addend from the
+ reloc or from the section contents (for a partial_inplace reloc). Then
+ find the adjusted values of the offsets due to relaxation. The base
+ offset is needed to determine the change to the reloc's addend; the reloc
+ addend should not be adjusted due to relaxations located before the base
+ offset. */
+
+ base_offset = r_reloc_get_target_offset (new_rel) - new_rel->rela.r_addend;
+ act = relax_info->action_list.head;
+ if (base_offset <= target_offset)
+ {
+ int base_removed = removed_by_actions (&act, base_offset, FALSE);
+ int addend_removed = removed_by_actions (&act, target_offset, FALSE);
+ new_rel->target_offset = target_offset - base_removed - addend_removed;
+ new_rel->rela.r_addend -= addend_removed;
+ }
+ else
+ {
+ /* Handle a negative addend. The base offset comes first. */
+ int tgt_removed = removed_by_actions (&act, target_offset, FALSE);
+ int addend_removed = removed_by_actions (&act, base_offset, FALSE);
+ new_rel->target_offset = target_offset - tgt_removed;
+ new_rel->rela.r_addend += addend_removed;
+ }
+
+ return sec;
+}
+
+
+/* For dynamic links, there may be a dynamic relocation for each
+ literal. The number of dynamic relocations must be computed in
+ size_dynamic_sections, which occurs before relaxation. When a
+ literal is removed, this function checks if there is a corresponding
+ dynamic relocation and shrinks the size of the appropriate dynamic
+ relocation section accordingly. At this point, the contents of the
+ dynamic relocation sections have not yet been filled in, so there's
+ nothing else that needs to be done. */
+
+static void
+shrink_dynamic_reloc_sections (struct bfd_link_info *info,
+ bfd *abfd,
+ asection *input_section,
+ Elf_Internal_Rela *rel)
+{
+ struct elf_xtensa_link_hash_table *htab;
+ Elf_Internal_Shdr *symtab_hdr;
+ struct elf_link_hash_entry **sym_hashes;
+ unsigned long r_symndx;
+ int r_type;
+ struct elf_link_hash_entry *h;
+ bfd_boolean dynamic_symbol;
+
+ htab = elf_xtensa_hash_table (info);
+ if (htab == NULL)
+ return;
+
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+ sym_hashes = elf_sym_hashes (abfd);
+
+ r_type = ELF32_R_TYPE (rel->r_info);
+ 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];
+
+ dynamic_symbol = elf_xtensa_dynamic_symbol_p (h, info);
+
+ if ((r_type == R_XTENSA_32 || r_type == R_XTENSA_PLT)
+ && (input_section->flags & SEC_ALLOC) != 0
+ && (dynamic_symbol || info->shared))
+ {
+ asection *srel;
+ bfd_boolean is_plt = FALSE;
+
+ if (dynamic_symbol && r_type == R_XTENSA_PLT)
+ {
+ srel = htab->srelplt;
+ is_plt = TRUE;
+ }
+ else
+ srel = htab->srelgot;
+
+ /* Reduce size of the .rela.* section by one reloc. */
+ BFD_ASSERT (srel != NULL);
+ BFD_ASSERT (srel->size >= sizeof (Elf32_External_Rela));
+ srel->size -= sizeof (Elf32_External_Rela);
+
+ if (is_plt)
+ {
+ asection *splt, *sgotplt, *srelgot;
+ int reloc_index, chunk;
+
+ /* Find the PLT reloc index of the entry being removed. This
+ is computed from the size of ".rela.plt". It is needed to
+ figure out which PLT chunk to resize. Usually "last index
+ = size - 1" since the index starts at zero, but in this
+ context, the size has just been decremented so there's no
+ need to subtract one. */
+ reloc_index = srel->size / sizeof (Elf32_External_Rela);
+
+ chunk = reloc_index / PLT_ENTRIES_PER_CHUNK;
+ splt = elf_xtensa_get_plt_section (info, chunk);
+ sgotplt = elf_xtensa_get_gotplt_section (info, chunk);
+ BFD_ASSERT (splt != NULL && sgotplt != NULL);
+
+ /* Check if an entire PLT chunk has just been eliminated. */
+ if (reloc_index % PLT_ENTRIES_PER_CHUNK == 0)
+ {
+ /* The two magic GOT entries for that chunk can go away. */
+ srelgot = htab->srelgot;
+ BFD_ASSERT (srelgot != NULL);
+ srelgot->reloc_count -= 2;
+ srelgot->size -= 2 * sizeof (Elf32_External_Rela);
+ sgotplt->size -= 8;
+
+ /* There should be only one entry left (and it will be
+ removed below). */
+ BFD_ASSERT (sgotplt->size == 4);
+ BFD_ASSERT (splt->size == PLT_ENTRY_SIZE);
+ }
+
+ BFD_ASSERT (sgotplt->size >= 4);
+ BFD_ASSERT (splt->size >= PLT_ENTRY_SIZE);
+
+ sgotplt->size -= 4;
+ splt->size -= PLT_ENTRY_SIZE;
+ }
+ }
+}
+
+
+/* Take an r_rel and move it to another section. This usually
+ requires extending the interal_relocation array and pinning it. If
+ the original r_rel is from the same BFD, we can complete this here.
+ Otherwise, we add a fix record to let the final link fix the
+ appropriate address. Contents and internal relocations for the
+ section must be pinned after calling this routine. */
+
+static bfd_boolean
+move_literal (bfd *abfd,
+ struct bfd_link_info *link_info,
+ asection *sec,
+ bfd_vma offset,
+ bfd_byte *contents,
+ xtensa_relax_info *relax_info,
+ Elf_Internal_Rela **internal_relocs_p,
+ const literal_value *lit)
+{
+ Elf_Internal_Rela *new_relocs = NULL;
+ size_t new_relocs_count = 0;
+ Elf_Internal_Rela this_rela;
+ const r_reloc *r_rel;
+
+ r_rel = &lit->r_rel;
+ BFD_ASSERT (elf_section_data (sec)->relocs == *internal_relocs_p);
+
+ if (r_reloc_is_const (r_rel))
+ bfd_put_32 (abfd, lit->value, contents + offset);
+ else
+ {
+ int r_type;
+ unsigned i;
+ reloc_bfd_fix *fix;
+ unsigned insert_at;
+
+ r_type = ELF32_R_TYPE (r_rel->rela.r_info);
+
+ /* This is the difficult case. We have to create a fix up. */
+ this_rela.r_offset = offset;
+ this_rela.r_info = ELF32_R_INFO (0, r_type);
+ this_rela.r_addend =
+ r_rel->target_offset - r_reloc_get_target_offset (r_rel);
+ bfd_put_32 (abfd, lit->value, contents + offset);
+
+ /* Currently, we cannot move relocations during a relocatable link. */
+ BFD_ASSERT (!link_info->relocatable);
+ fix = reloc_bfd_fix_init (sec, offset, r_type,
+ r_reloc_get_section (r_rel),
+ r_rel->target_offset + r_rel->virtual_offset,
+ FALSE);
+ /* We also need to mark that relocations are needed here. */
+ sec->flags |= SEC_RELOC;
+
+ translate_reloc_bfd_fix (fix);
+ /* This fix has not yet been translated. */
+ add_fix (sec, fix);
+
+ /* Add the relocation. If we have already allocated our own
+ space for the relocations and we have room for more, then use
+ it. Otherwise, allocate new space and move the literals. */
+ insert_at = sec->reloc_count;
+ for (i = 0; i < sec->reloc_count; ++i)
+ {
+ if (this_rela.r_offset < (*internal_relocs_p)[i].r_offset)
+ {
+ insert_at = i;
+ break;
+ }
+ }
+
+ if (*internal_relocs_p != relax_info->allocated_relocs
+ || sec->reloc_count + 1 > relax_info->allocated_relocs_count)
+ {
+ BFD_ASSERT (relax_info->allocated_relocs == NULL
+ || sec->reloc_count == relax_info->relocs_count);
+
+ if (relax_info->allocated_relocs_count == 0)
+ new_relocs_count = (sec->reloc_count + 2) * 2;
+ else
+ new_relocs_count = (relax_info->allocated_relocs_count + 2) * 2;
+
+ new_relocs = (Elf_Internal_Rela *)
+ bfd_zmalloc (sizeof (Elf_Internal_Rela) * (new_relocs_count));
+ if (!new_relocs)
+ return FALSE;
+
+ /* We could handle this more quickly by finding the split point. */
+ if (insert_at != 0)
+ memcpy (new_relocs, *internal_relocs_p,
+ insert_at * sizeof (Elf_Internal_Rela));
+
+ new_relocs[insert_at] = this_rela;
+
+ if (insert_at != sec->reloc_count)
+ memcpy (new_relocs + insert_at + 1,
+ (*internal_relocs_p) + insert_at,
+ (sec->reloc_count - insert_at)
+ * sizeof (Elf_Internal_Rela));
+
+ if (*internal_relocs_p != relax_info->allocated_relocs)
+ {
+ /* The first time we re-allocate, we can only free the
+ old relocs if they were allocated with bfd_malloc.
+ This is not true when keep_memory is in effect. */
+ if (!link_info->keep_memory)
+ free (*internal_relocs_p);
+ }
+ else
+ free (*internal_relocs_p);
+ relax_info->allocated_relocs = new_relocs;
+ relax_info->allocated_relocs_count = new_relocs_count;
+ elf_section_data (sec)->relocs = new_relocs;
+ sec->reloc_count++;
+ relax_info->relocs_count = sec->reloc_count;
+ *internal_relocs_p = new_relocs;
+ }
+ else
+ {
+ if (insert_at != sec->reloc_count)
+ {
+ unsigned idx;
+ for (idx = sec->reloc_count; idx > insert_at; idx--)
+ (*internal_relocs_p)[idx] = (*internal_relocs_p)[idx-1];
+ }
+ (*internal_relocs_p)[insert_at] = this_rela;
+ sec->reloc_count++;
+ if (relax_info->allocated_relocs)
+ relax_info->relocs_count = sec->reloc_count;
+ }
+ }
+ return TRUE;
+}
+
+
+/* This is similar to relax_section except that when a target is moved,
+ we shift addresses up. We also need to modify the size. This
+ algorithm does NOT allow for relocations into the middle of the
+ property sections. */
+
+static bfd_boolean
+relax_property_section (bfd *abfd,
+ asection *sec,
+ struct bfd_link_info *link_info)
+{
+ Elf_Internal_Rela *internal_relocs;
+ bfd_byte *contents;
+ unsigned i;
+ bfd_boolean ok = TRUE;
+ bfd_boolean is_full_prop_section;
+ size_t last_zfill_target_offset = 0;
+ asection *last_zfill_target_sec = NULL;
+ bfd_size_type sec_size;
+ bfd_size_type entry_size;
+
+ sec_size = bfd_get_section_limit (abfd, sec);
+ internal_relocs = retrieve_internal_relocs (abfd, sec,
+ link_info->keep_memory);
+ contents = retrieve_contents (abfd, sec, link_info->keep_memory);
+ if (contents == NULL && sec_size != 0)
+ {
+ ok = FALSE;
+ goto error_return;
+ }
+
+ is_full_prop_section = xtensa_is_proptable_section (sec);
+ if (is_full_prop_section)
+ entry_size = 12;
+ else
+ entry_size = 8;
+
+ if (internal_relocs)
+ {
+ for (i = 0; i < sec->reloc_count; i++)
+ {
+ Elf_Internal_Rela *irel;
+ xtensa_relax_info *target_relax_info;
+ unsigned r_type;
+ asection *target_sec;
+ literal_value val;
+ bfd_byte *size_p, *flags_p;
+
+ /* Locally change the source address.
+ Translate the target to the new target address.
+ If it points to this section and has been removed, MOVE IT.
+ Also, don't forget to modify the associated SIZE at
+ (offset + 4). */
+
+ irel = &internal_relocs[i];
+ r_type = ELF32_R_TYPE (irel->r_info);
+ if (r_type == R_XTENSA_NONE)
+ continue;
+
+ /* Find the literal value. */
+ r_reloc_init (&val.r_rel, abfd, irel, contents, sec_size);
+ size_p = &contents[irel->r_offset + 4];
+ flags_p = NULL;
+ if (is_full_prop_section)
+ flags_p = &contents[irel->r_offset + 8];
+ BFD_ASSERT (irel->r_offset + entry_size <= sec_size);
+
+ target_sec = r_reloc_get_section (&val.r_rel);
+ target_relax_info = get_xtensa_relax_info (target_sec);
+
+ if (target_relax_info
+ && (target_relax_info->is_relaxable_literal_section
+ || target_relax_info->is_relaxable_asm_section ))
+ {
+ /* Translate the relocation's destination. */
+ bfd_vma old_offset = val.r_rel.target_offset;
+ bfd_vma new_offset;
+ long old_size, new_size;
+ text_action *act = target_relax_info->action_list.head;
+ new_offset = old_offset -
+ removed_by_actions (&act, old_offset, FALSE);
+
+ /* Assert that we are not out of bounds. */
+ old_size = bfd_get_32 (abfd, size_p);
+ new_size = old_size;
+
+ if (old_size == 0)
+ {
+ /* Only the first zero-sized unreachable entry is
+ allowed to expand. In this case the new offset
+ should be the offset before the fill and the new
+ size is the expansion size. For other zero-sized
+ entries the resulting size should be zero with an
+ offset before or after the fill address depending
+ on whether the expanding unreachable entry
+ preceeds it. */
+ if (last_zfill_target_sec == 0
+ || last_zfill_target_sec != target_sec
+ || last_zfill_target_offset != old_offset)
+ {
+ bfd_vma new_end_offset = new_offset;
+
+ /* Recompute the new_offset, but this time don't
+ include any fill inserted by relaxation. */
+ act = target_relax_info->action_list.head;
+ new_offset = old_offset -
+ removed_by_actions (&act, old_offset, TRUE);
+
+ /* If it is not unreachable and we have not yet
+ seen an unreachable at this address, place it
+ before the fill address. */
+ if (flags_p && (bfd_get_32 (abfd, flags_p)
+ & XTENSA_PROP_UNREACHABLE) != 0)
+ {
+ new_size = new_end_offset - new_offset;
+
+ last_zfill_target_sec = target_sec;
+ last_zfill_target_offset = old_offset;
+ }
+ }
+ }
+ else
+ new_size -=
+ removed_by_actions (&act, old_offset + old_size, TRUE);
+
+ if (new_size != old_size)
+ {
+ bfd_put_32 (abfd, new_size, size_p);
+ pin_contents (sec, contents);
+ }
+
+ if (new_offset != old_offset)
+ {
+ bfd_vma diff = new_offset - old_offset;
+ irel->r_addend += diff;
+ pin_internal_relocs (sec, internal_relocs);
+ }
+ }
+ }
+ }
+
+ /* Combine adjacent property table entries. This is also done in
+ finish_dynamic_sections() but at that point it's too late to
+ reclaim the space in the output section, so we do this twice. */
+
+ if (internal_relocs && (!link_info->relocatable
+ || xtensa_is_littable_section (sec)))
+ {
+ Elf_Internal_Rela *last_irel = NULL;
+ Elf_Internal_Rela *irel, *next_rel, *rel_end;
+ int removed_bytes = 0;
+ bfd_vma offset;
+ flagword predef_flags;
+
+ predef_flags = xtensa_get_property_predef_flags (sec);
+
+ /* Walk over memory and relocations at the same time.
+ This REQUIRES that the internal_relocs be sorted by offset. */
+ qsort (internal_relocs, sec->reloc_count, sizeof (Elf_Internal_Rela),
+ internal_reloc_compare);
+
+ pin_internal_relocs (sec, internal_relocs);
+ pin_contents (sec, contents);
+
+ next_rel = internal_relocs;
+ rel_end = internal_relocs + sec->reloc_count;
+
+ BFD_ASSERT (sec->size % entry_size == 0);
+
+ for (offset = 0; offset < sec->size; offset += entry_size)
+ {
+ Elf_Internal_Rela *offset_rel, *extra_rel;
+ bfd_vma bytes_to_remove, size, actual_offset;
+ bfd_boolean remove_this_rel;
+ flagword flags;
+
+ /* Find the first relocation for the entry at the current offset.
+ Adjust the offsets of any extra relocations for the previous
+ entry. */
+ offset_rel = NULL;
+ if (next_rel)
+ {
+ for (irel = next_rel; irel < rel_end; irel++)
+ {
+ if ((irel->r_offset == offset
+ && ELF32_R_TYPE (irel->r_info) != R_XTENSA_NONE)
+ || irel->r_offset > offset)
+ {
+ offset_rel = irel;
+ break;
+ }
+ irel->r_offset -= removed_bytes;
+ }
+ }
+
+ /* Find the next relocation (if there are any left). */
+ extra_rel = NULL;
+ if (offset_rel)
+ {
+ for (irel = offset_rel + 1; irel < rel_end; irel++)
+ {
+ if (ELF32_R_TYPE (irel->r_info) != R_XTENSA_NONE)
+ {
+ extra_rel = irel;
+ break;
+ }
+ }
+ }
+
+ /* Check if there are relocations on the current entry. There
+ should usually be a relocation on the offset field. If there
+ are relocations on the size or flags, then we can't optimize
+ this entry. Also, find the next relocation to examine on the
+ next iteration. */
+ if (offset_rel)
+ {
+ if (offset_rel->r_offset >= offset + entry_size)
+ {
+ next_rel = offset_rel;
+ /* There are no relocations on the current entry, but we
+ might still be able to remove it if the size is zero. */
+ offset_rel = NULL;
+ }
+ else if (offset_rel->r_offset > offset
+ || (extra_rel
+ && extra_rel->r_offset < offset + entry_size))
+ {
+ /* There is a relocation on the size or flags, so we can't
+ do anything with this entry. Continue with the next. */
+ next_rel = offset_rel;
+ continue;
+ }
+ else
+ {
+ BFD_ASSERT (offset_rel->r_offset == offset);
+ offset_rel->r_offset -= removed_bytes;
+ next_rel = offset_rel + 1;
+ }
+ }
+ else
+ next_rel = NULL;
+
+ remove_this_rel = FALSE;
+ bytes_to_remove = 0;
+ actual_offset = offset - removed_bytes;
+ size = bfd_get_32 (abfd, &contents[actual_offset + 4]);
+
+ if (is_full_prop_section)
+ flags = bfd_get_32 (abfd, &contents[actual_offset + 8]);
+ else
+ flags = predef_flags;
+
+ if (size == 0
+ && (flags & XTENSA_PROP_ALIGN) == 0
+ && (flags & XTENSA_PROP_UNREACHABLE) == 0)
+ {
+ /* Always remove entries with zero size and no alignment. */
+ bytes_to_remove = entry_size;
+ if (offset_rel)
+ remove_this_rel = TRUE;
+ }
+ else if (offset_rel
+ && ELF32_R_TYPE (offset_rel->r_info) == R_XTENSA_32)
+ {
+ if (last_irel)
+ {
+ flagword old_flags;
+ bfd_vma old_size =
+ bfd_get_32 (abfd, &contents[last_irel->r_offset + 4]);
+ bfd_vma old_address =
+ (last_irel->r_addend
+ + bfd_get_32 (abfd, &contents[last_irel->r_offset]));
+ bfd_vma new_address =
+ (offset_rel->r_addend
+ + bfd_get_32 (abfd, &contents[actual_offset]));
+ if (is_full_prop_section)
+ old_flags = bfd_get_32
+ (abfd, &contents[last_irel->r_offset + 8]);
+ else
+ old_flags = predef_flags;
+
+ if ((ELF32_R_SYM (offset_rel->r_info)
+ == ELF32_R_SYM (last_irel->r_info))
+ && old_address + old_size == new_address
+ && old_flags == flags
+ && (old_flags & XTENSA_PROP_INSN_BRANCH_TARGET) == 0
+ && (old_flags & XTENSA_PROP_INSN_LOOP_TARGET) == 0)
+ {
+ /* Fix the old size. */
+ bfd_put_32 (abfd, old_size + size,
+ &contents[last_irel->r_offset + 4]);
+ bytes_to_remove = entry_size;
+ remove_this_rel = TRUE;
+ }
+ else
+ last_irel = offset_rel;
+ }
+ else
+ last_irel = offset_rel;
+ }
+
+ if (remove_this_rel)
+ {
+ offset_rel->r_info = ELF32_R_INFO (0, R_XTENSA_NONE);
+ offset_rel->r_offset = 0;
+ }
+
+ if (bytes_to_remove != 0)
+ {
+ removed_bytes += bytes_to_remove;
+ if (offset + bytes_to_remove < sec->size)
+ memmove (&contents[actual_offset],
+ &contents[actual_offset + bytes_to_remove],
+ sec->size - offset - bytes_to_remove);
+ }
+ }
+
+ if (removed_bytes)
+ {
+ /* Fix up any extra relocations on the last entry. */
+ for (irel = next_rel; irel < rel_end; irel++)
+ irel->r_offset -= removed_bytes;
+
+ /* Clear the removed bytes. */
+ memset (&contents[sec->size - removed_bytes], 0, removed_bytes);
+
+ if (sec->rawsize == 0)
+ sec->rawsize = sec->size;
+ sec->size -= removed_bytes;
+
+ if (xtensa_is_littable_section (sec))
+ {
+ asection *sgotloc = elf_xtensa_hash_table (link_info)->sgotloc;
+ if (sgotloc)
+ sgotloc->size -= removed_bytes;
+ }
+ }
+ }
+
+ error_return:
+ release_internal_relocs (sec, internal_relocs);
+ release_contents (sec, contents);
+ return ok;
+}
+
+
+/* Third relaxation pass. */
+
+/* Change symbol values to account for removed literals. */
+
+bfd_boolean
+relax_section_symbols (bfd *abfd, asection *sec)
+{
+ xtensa_relax_info *relax_info;
+ unsigned int sec_shndx;
+ Elf_Internal_Shdr *symtab_hdr;
+ Elf_Internal_Sym *isymbuf;
+ unsigned i, num_syms, num_locals;
+
+ relax_info = get_xtensa_relax_info (sec);
+ BFD_ASSERT (relax_info);
+
+ if (!relax_info->is_relaxable_literal_section
+ && !relax_info->is_relaxable_asm_section)
+ return TRUE;
+
+ sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
+
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+ isymbuf = retrieve_local_syms (abfd);
+
+ num_syms = symtab_hdr->sh_size / sizeof (Elf32_External_Sym);
+ num_locals = symtab_hdr->sh_info;
+
+ /* Adjust the local symbols defined in this section. */
+ for (i = 0; i < num_locals; i++)
+ {
+ Elf_Internal_Sym *isym = &isymbuf[i];
+
+ if (isym->st_shndx == sec_shndx)
+ {
+ text_action *act = relax_info->action_list.head;
+ bfd_vma orig_addr = isym->st_value;
+
+ isym->st_value -= removed_by_actions (&act, orig_addr, FALSE);
+
+ if (ELF32_ST_TYPE (isym->st_info) == STT_FUNC)
+ isym->st_size -=
+ removed_by_actions (&act, orig_addr + isym->st_size, FALSE);
+ }
+ }
+
+ /* Now adjust the global symbols defined in this section. */
+ for (i = 0; i < (num_syms - num_locals); i++)
+ {
+ struct elf_link_hash_entry *sym_hash;
+
+ sym_hash = elf_sym_hashes (abfd)[i];
+
+ if (sym_hash->root.type == bfd_link_hash_warning)
+ sym_hash = (struct elf_link_hash_entry *) sym_hash->root.u.i.link;
+
+ if ((sym_hash->root.type == bfd_link_hash_defined
+ || sym_hash->root.type == bfd_link_hash_defweak)
+ && sym_hash->root.u.def.section == sec)
+ {
+ text_action *act = relax_info->action_list.head;
+ bfd_vma orig_addr = sym_hash->root.u.def.value;
+
+ sym_hash->root.u.def.value -=
+ removed_by_actions (&act, orig_addr, FALSE);
+
+ if (sym_hash->type == STT_FUNC)
+ sym_hash->size -=
+ removed_by_actions (&act, orig_addr + sym_hash->size, FALSE);
+ }
+ }
+
+ return TRUE;
+}
+
+
+/* "Fix" handling functions, called while performing relocations. */
+
+static bfd_boolean
+do_fix_for_relocatable_link (Elf_Internal_Rela *rel,
+ bfd *input_bfd,
+ asection *input_section,
+ bfd_byte *contents)
+{
+ r_reloc r_rel;
+ asection *sec, *old_sec;
+ bfd_vma old_offset;
+ int r_type = ELF32_R_TYPE (rel->r_info);
+ reloc_bfd_fix *fix;
+
+ if (r_type == R_XTENSA_NONE)
+ return TRUE;
+
+ fix = get_bfd_fix (input_section, rel->r_offset, r_type);
+ if (!fix)
+ return TRUE;
+
+ r_reloc_init (&r_rel, input_bfd, rel, contents,
+ bfd_get_section_limit (input_bfd, input_section));
+ old_sec = r_reloc_get_section (&r_rel);
+ old_offset = r_rel.target_offset;
+
+ if (!old_sec || !r_reloc_is_defined (&r_rel))
+ {
+ if (r_type != R_XTENSA_ASM_EXPAND)
+ {
+ (*_bfd_error_handler)
+ (_("%B(%A+0x%lx): unexpected fix for %s relocation"),
+ input_bfd, input_section, rel->r_offset,
+ elf_howto_table[r_type].name);
+ return FALSE;
+ }
+ /* Leave it be. Resolution will happen in a later stage. */
+ }
+ else
+ {
+ sec = fix->target_sec;
+ rel->r_addend += ((sec->output_offset + fix->target_offset)
+ - (old_sec->output_offset + old_offset));
+ }
+ return TRUE;
+}
+
+
+static void
+do_fix_for_final_link (Elf_Internal_Rela *rel,
+ bfd *input_bfd,
+ asection *input_section,
+ bfd_byte *contents,
+ bfd_vma *relocationp)
+{
+ asection *sec;
+ int r_type = ELF32_R_TYPE (rel->r_info);
+ reloc_bfd_fix *fix;
+ bfd_vma fixup_diff;
+
+ if (r_type == R_XTENSA_NONE)
+ return;
+
+ fix = get_bfd_fix (input_section, rel->r_offset, r_type);
+ if (!fix)
+ return;
+
+ sec = fix->target_sec;
+
+ fixup_diff = rel->r_addend;
+ if (elf_howto_table[fix->src_type].partial_inplace)
+ {
+ bfd_vma inplace_val;
+ BFD_ASSERT (fix->src_offset
+ < bfd_get_section_limit (input_bfd, input_section));
+ inplace_val = bfd_get_32 (input_bfd, &contents[fix->src_offset]);
+ fixup_diff += inplace_val;
+ }
+
+ *relocationp = (sec->output_section->vma
+ + sec->output_offset
+ + fix->target_offset - fixup_diff);
+}
+
+
+/* Miscellaneous utility functions.... */
+
+static asection *
+elf_xtensa_get_plt_section (struct bfd_link_info *info, int chunk)
+{
+ struct elf_xtensa_link_hash_table *htab;
+ bfd *dynobj;
+ char plt_name[10];
+
+ if (chunk == 0)
+ {
+ htab = elf_xtensa_hash_table (info);
+ if (htab == NULL)
+ return NULL;
+
+ return htab->splt;
+ }
+
+ dynobj = elf_hash_table (info)->dynobj;
+ sprintf (plt_name, ".plt.%u", chunk);
+ return bfd_get_linker_section (dynobj, plt_name);
+}
+
+
+static asection *
+elf_xtensa_get_gotplt_section (struct bfd_link_info *info, int chunk)
+{
+ struct elf_xtensa_link_hash_table *htab;
+ bfd *dynobj;
+ char got_name[14];
+
+ if (chunk == 0)
+ {
+ htab = elf_xtensa_hash_table (info);
+ if (htab == NULL)
+ return NULL;
+ return htab->sgotplt;
+ }
+
+ dynobj = elf_hash_table (info)->dynobj;
+ sprintf (got_name, ".got.plt.%u", chunk);
+ return bfd_get_linker_section (dynobj, got_name);
+}
+
+
+/* Get the input section for a given symbol index.
+ If the symbol is:
+ . a section symbol, return the section;
+ . a common symbol, return the common section;
+ . an undefined symbol, return the undefined section;
+ . an indirect symbol, follow the links;
+ . an absolute value, return the absolute section. */
+
+static asection *
+get_elf_r_symndx_section (bfd *abfd, unsigned long r_symndx)
+{
+ Elf_Internal_Shdr *symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+ asection *target_sec = NULL;
+ if (r_symndx < symtab_hdr->sh_info)
+ {
+ Elf_Internal_Sym *isymbuf;
+ unsigned int section_index;
+
+ isymbuf = retrieve_local_syms (abfd);
+ section_index = isymbuf[r_symndx].st_shndx;
+
+ if (section_index == SHN_UNDEF)
+ target_sec = bfd_und_section_ptr;
+ else if (section_index == SHN_ABS)
+ target_sec = bfd_abs_section_ptr;
+ else if (section_index == SHN_COMMON)
+ target_sec = bfd_com_section_ptr;
+ else
+ target_sec = bfd_section_from_elf_index (abfd, section_index);
+ }
+ else
+ {
+ unsigned long indx = r_symndx - symtab_hdr->sh_info;
+ struct elf_link_hash_entry *h = elf_sym_hashes (abfd)[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;
+
+ switch (h->root.type)
+ {
+ case bfd_link_hash_defined:
+ case bfd_link_hash_defweak:
+ target_sec = h->root.u.def.section;
+ break;
+ case bfd_link_hash_common:
+ target_sec = bfd_com_section_ptr;
+ break;
+ case bfd_link_hash_undefined:
+ case bfd_link_hash_undefweak:
+ target_sec = bfd_und_section_ptr;
+ break;
+ default: /* New indirect warning. */
+ target_sec = bfd_und_section_ptr;
+ break;
+ }
+ }
+ return target_sec;
+}
+
+
+static struct elf_link_hash_entry *
+get_elf_r_symndx_hash_entry (bfd *abfd, unsigned long r_symndx)
+{
+ unsigned long indx;
+ struct elf_link_hash_entry *h;
+ Elf_Internal_Shdr *symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+
+ if (r_symndx < symtab_hdr->sh_info)
+ return NULL;
+
+ indx = r_symndx - symtab_hdr->sh_info;
+ h = elf_sym_hashes (abfd)[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;
+ return h;
+}
+
+
+/* Get the section-relative offset for a symbol number. */
+
+static bfd_vma
+get_elf_r_symndx_offset (bfd *abfd, unsigned long r_symndx)
+{
+ Elf_Internal_Shdr *symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+ bfd_vma offset = 0;
+
+ if (r_symndx < symtab_hdr->sh_info)
+ {
+ Elf_Internal_Sym *isymbuf;
+ isymbuf = retrieve_local_syms (abfd);
+ offset = isymbuf[r_symndx].st_value;
+ }
+ else
+ {
+ unsigned long indx = r_symndx - symtab_hdr->sh_info;
+ struct elf_link_hash_entry *h =
+ elf_sym_hashes (abfd)[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)
+ offset = h->root.u.def.value;
+ }
+ return offset;
+}
+
+
+static bfd_boolean
+is_reloc_sym_weak (bfd *abfd, Elf_Internal_Rela *rel)
+{
+ unsigned long r_symndx = ELF32_R_SYM (rel->r_info);
+ struct elf_link_hash_entry *h;
+
+ h = get_elf_r_symndx_hash_entry (abfd, r_symndx);
+ if (h && h->root.type == bfd_link_hash_defweak)
+ return TRUE;
+ return FALSE;
+}
+
+
+static bfd_boolean
+pcrel_reloc_fits (xtensa_opcode opc,
+ int opnd,
+ bfd_vma self_address,
+ bfd_vma dest_address)
+{
+ xtensa_isa isa = xtensa_default_isa;
+ uint32 valp = dest_address;
+ if (xtensa_operand_do_reloc (isa, opc, opnd, &valp, self_address)
+ || xtensa_operand_encode (isa, opc, opnd, &valp))
+ return FALSE;
+ return TRUE;
+}
+
+
+static bfd_boolean
+xtensa_is_property_section (asection *sec)
+{
+ if (xtensa_is_insntable_section (sec)
+ || xtensa_is_littable_section (sec)
+ || xtensa_is_proptable_section (sec))
+ return TRUE;
+
+ return FALSE;
+}
+
+
+static bfd_boolean
+xtensa_is_insntable_section (asection *sec)
+{
+ if (CONST_STRNEQ (sec->name, XTENSA_INSN_SEC_NAME)
+ || CONST_STRNEQ (sec->name, ".gnu.linkonce.x."))
+ return TRUE;
+
+ return FALSE;
+}
+
+
+static bfd_boolean
+xtensa_is_littable_section (asection *sec)
+{
+ if (CONST_STRNEQ (sec->name, XTENSA_LIT_SEC_NAME)
+ || CONST_STRNEQ (sec->name, ".gnu.linkonce.p."))
+ return TRUE;
+
+ return FALSE;
+}
+
+
+static bfd_boolean
+xtensa_is_proptable_section (asection *sec)
+{
+ if (CONST_STRNEQ (sec->name, XTENSA_PROP_SEC_NAME)
+ || CONST_STRNEQ (sec->name, ".gnu.linkonce.prop."))
+ return TRUE;
+
+ return FALSE;
+}
+
+
+static int
+internal_reloc_compare (const void *ap, const void *bp)
+{
+ const Elf_Internal_Rela *a = (const Elf_Internal_Rela *) ap;
+ const Elf_Internal_Rela *b = (const Elf_Internal_Rela *) bp;
+
+ if (a->r_offset != b->r_offset)
+ return (a->r_offset - b->r_offset);
+
+ /* We don't need to sort on these criteria for correctness,
+ but enforcing a more strict ordering prevents unstable qsort
+ from behaving differently with different implementations.
+ Without the code below we get correct but different results
+ on Solaris 2.7 and 2.8. We would like to always produce the
+ same results no matter the host. */
+
+ if (a->r_info != b->r_info)
+ return (a->r_info - b->r_info);
+
+ return (a->r_addend - b->r_addend);
+}
+
+
+static int
+internal_reloc_matches (const void *ap, const void *bp)
+{
+ const Elf_Internal_Rela *a = (const Elf_Internal_Rela *) ap;
+ const Elf_Internal_Rela *b = (const Elf_Internal_Rela *) bp;
+
+ /* Check if one entry overlaps with the other; this shouldn't happen
+ except when searching for a match. */
+ return (a->r_offset - b->r_offset);
+}
+
+
+/* Predicate function used to look up a section in a particular group. */
+
+static bfd_boolean
+match_section_group (bfd *abfd ATTRIBUTE_UNUSED, asection *sec, void *inf)
+{
+ const char *gname = inf;
+ const char *group_name = elf_group_name (sec);
+
+ return (group_name == gname
+ || (group_name != NULL
+ && gname != NULL
+ && strcmp (group_name, gname) == 0));
+}
+
+
+static int linkonce_len = sizeof (".gnu.linkonce.") - 1;
+
+static char *
+xtensa_property_section_name (asection *sec, const char *base_name)
+{
+ const char *suffix, *group_name;
+ char *prop_sec_name;
+
+ group_name = elf_group_name (sec);
+ if (group_name)
+ {
+ suffix = strrchr (sec->name, '.');
+ if (suffix == sec->name)
+ suffix = 0;
+ prop_sec_name = (char *) bfd_malloc (strlen (base_name) + 1
+ + (suffix ? strlen (suffix) : 0));
+ strcpy (prop_sec_name, base_name);
+ if (suffix)
+ strcat (prop_sec_name, suffix);
+ }
+ else if (strncmp (sec->name, ".gnu.linkonce.", linkonce_len) == 0)
+ {
+ char *linkonce_kind = 0;
+
+ if (strcmp (base_name, XTENSA_INSN_SEC_NAME) == 0)
+ linkonce_kind = "x.";
+ else if (strcmp (base_name, XTENSA_LIT_SEC_NAME) == 0)
+ linkonce_kind = "p.";
+ else if (strcmp (base_name, XTENSA_PROP_SEC_NAME) == 0)
+ linkonce_kind = "prop.";
+ else
+ abort ();
+
+ prop_sec_name = (char *) bfd_malloc (strlen (sec->name)
+ + strlen (linkonce_kind) + 1);
+ memcpy (prop_sec_name, ".gnu.linkonce.", linkonce_len);
+ strcpy (prop_sec_name + linkonce_len, linkonce_kind);
+
+ suffix = sec->name + linkonce_len;
+ /* For backward compatibility, replace "t." instead of inserting
+ the new linkonce_kind (but not for "prop" sections). */
+ if (CONST_STRNEQ (suffix, "t.") && linkonce_kind[1] == '.')
+ suffix += 2;
+ strcat (prop_sec_name + linkonce_len, suffix);
+ }
+ else
+ prop_sec_name = strdup (base_name);
+
+ return prop_sec_name;
+}
+
+
+static asection *
+xtensa_get_property_section (asection *sec, const char *base_name)
+{
+ char *prop_sec_name;
+ asection *prop_sec;
+
+ prop_sec_name = xtensa_property_section_name (sec, base_name);
+ prop_sec = bfd_get_section_by_name_if (sec->owner, prop_sec_name,
+ match_section_group,
+ (void *) elf_group_name (sec));
+ free (prop_sec_name);
+ return prop_sec;
+}
+
+
+asection *
+xtensa_make_property_section (asection *sec, const char *base_name)
+{
+ char *prop_sec_name;
+ asection *prop_sec;
+
+ /* Check if the section already exists. */
+ prop_sec_name = xtensa_property_section_name (sec, base_name);
+ prop_sec = bfd_get_section_by_name_if (sec->owner, prop_sec_name,
+ match_section_group,
+ (void *) elf_group_name (sec));
+ /* If not, create it. */
+ if (! prop_sec)
+ {
+ flagword flags = (SEC_RELOC | SEC_HAS_CONTENTS | SEC_READONLY);
+ flags |= (bfd_get_section_flags (sec->owner, sec)
+ & (SEC_LINK_ONCE | SEC_LINK_DUPLICATES));
+
+ prop_sec = bfd_make_section_anyway_with_flags
+ (sec->owner, strdup (prop_sec_name), flags);
+ if (! prop_sec)
+ return 0;
+
+ elf_group_name (prop_sec) = elf_group_name (sec);
+ }
+
+ free (prop_sec_name);
+ return prop_sec;
+}
+
+
+flagword
+xtensa_get_property_predef_flags (asection *sec)
+{
+ if (xtensa_is_insntable_section (sec))
+ return (XTENSA_PROP_INSN
+ | XTENSA_PROP_NO_TRANSFORM
+ | XTENSA_PROP_INSN_NO_REORDER);
+
+ if (xtensa_is_littable_section (sec))
+ return (XTENSA_PROP_LITERAL
+ | XTENSA_PROP_NO_TRANSFORM
+ | XTENSA_PROP_INSN_NO_REORDER);
+
+ return 0;
+}
+
+
+/* Other functions called directly by the linker. */
+
+bfd_boolean
+xtensa_callback_required_dependence (bfd *abfd,
+ asection *sec,
+ struct bfd_link_info *link_info,
+ deps_callback_t callback,
+ void *closure)
+{
+ Elf_Internal_Rela *internal_relocs;
+ bfd_byte *contents;
+ unsigned i;
+ bfd_boolean ok = TRUE;
+ bfd_size_type sec_size;
+
+ sec_size = bfd_get_section_limit (abfd, sec);
+
+ /* ".plt*" sections have no explicit relocations but they contain L32R
+ instructions that reference the corresponding ".got.plt*" sections. */
+ if ((sec->flags & SEC_LINKER_CREATED) != 0
+ && CONST_STRNEQ (sec->name, ".plt"))
+ {
+ asection *sgotplt;
+
+ /* Find the corresponding ".got.plt*" section. */
+ if (sec->name[4] == '\0')
+ sgotplt = bfd_get_linker_section (sec->owner, ".got.plt");
+ else
+ {
+ char got_name[14];
+ int chunk = 0;
+
+ BFD_ASSERT (sec->name[4] == '.');
+ chunk = strtol (&sec->name[5], NULL, 10);
+
+ sprintf (got_name, ".got.plt.%u", chunk);
+ sgotplt = bfd_get_linker_section (sec->owner, got_name);
+ }
+ BFD_ASSERT (sgotplt);
+
+ /* Assume worst-case offsets: L32R at the very end of the ".plt"
+ section referencing a literal at the very beginning of
+ ".got.plt". This is very close to the real dependence, anyway. */
+ (*callback) (sec, sec_size, sgotplt, 0, closure);
+ }
+
+ /* Only ELF files are supported for Xtensa. Check here to avoid a segfault
+ when building uclibc, which runs "ld -b binary /dev/null". */
+ if (bfd_get_flavour (abfd) != bfd_target_elf_flavour)
+ return ok;
+
+ internal_relocs = retrieve_internal_relocs (abfd, sec,
+ link_info->keep_memory);
+ if (internal_relocs == NULL
+ || sec->reloc_count == 0)
+ return ok;
+
+ /* Cache the contents for the duration of this scan. */
+ contents = retrieve_contents (abfd, sec, link_info->keep_memory);
+ if (contents == NULL && sec_size != 0)
+ {
+ ok = FALSE;
+ goto error_return;
+ }
+
+ if (!xtensa_default_isa)
+ xtensa_default_isa = xtensa_isa_init (0, 0);
+
+ for (i = 0; i < sec->reloc_count; i++)
+ {
+ Elf_Internal_Rela *irel = &internal_relocs[i];
+ if (is_l32r_relocation (abfd, sec, contents, irel))
+ {
+ r_reloc l32r_rel;
+ asection *target_sec;
+ bfd_vma target_offset;
+
+ r_reloc_init (&l32r_rel, abfd, irel, contents, sec_size);
+ target_sec = NULL;
+ target_offset = 0;
+ /* L32Rs must be local to the input file. */
+ if (r_reloc_is_defined (&l32r_rel))
+ {
+ target_sec = r_reloc_get_section (&l32r_rel);
+ target_offset = l32r_rel.target_offset;
+ }
+ (*callback) (sec, irel->r_offset, target_sec, target_offset,
+ closure);
+ }
+ }
+
+ error_return:
+ release_internal_relocs (sec, internal_relocs);
+ release_contents (sec, contents);
+ return ok;
+}
+
+/* The default literal sections should always be marked as "code" (i.e.,
+ SHF_EXECINSTR). This is particularly important for the Linux kernel
+ module loader so that the literals are not placed after the text. */
+static const struct bfd_elf_special_section elf_xtensa_special_sections[] =
+{
+ { STRING_COMMA_LEN (".fini.literal"), 0, SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR },
+ { STRING_COMMA_LEN (".init.literal"), 0, SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR },
+ { STRING_COMMA_LEN (".literal"), 0, SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR },
+ { STRING_COMMA_LEN (".xtensa.info"), 0, SHT_NOTE, 0 },
+ { NULL, 0, 0, 0, 0 }
+};
+
+#define ELF_TARGET_ID XTENSA_ELF_DATA
+#ifndef ELF_ARCH
+#define TARGET_LITTLE_SYM xtensa_elf32_le_vec
+#define TARGET_LITTLE_NAME "elf32-xtensa-le"
+#define TARGET_BIG_SYM xtensa_elf32_be_vec
+#define TARGET_BIG_NAME "elf32-xtensa-be"
+#define ELF_ARCH bfd_arch_xtensa
+
+#define ELF_MACHINE_CODE EM_XTENSA
+#define ELF_MACHINE_ALT1 EM_XTENSA_OLD
+
+#if XCHAL_HAVE_MMU
+#define ELF_MAXPAGESIZE (1 << XCHAL_MMU_MIN_PTE_PAGE_SIZE)
+#else /* !XCHAL_HAVE_MMU */
+#define ELF_MAXPAGESIZE 1
+#endif /* !XCHAL_HAVE_MMU */
+#endif /* ELF_ARCH */
+
+#define elf_backend_can_gc_sections 1
+#define elf_backend_can_refcount 1
+#define elf_backend_plt_readonly 1
+#define elf_backend_got_header_size 4
+#define elf_backend_want_dynbss 0
+#define elf_backend_want_got_plt 1
+
+#define elf_info_to_howto elf_xtensa_info_to_howto_rela
+
+#define bfd_elf32_mkobject elf_xtensa_mkobject
+
+#define bfd_elf32_bfd_merge_private_bfd_data elf_xtensa_merge_private_bfd_data
+#define bfd_elf32_new_section_hook elf_xtensa_new_section_hook
+#define bfd_elf32_bfd_print_private_bfd_data elf_xtensa_print_private_bfd_data
+#define bfd_elf32_bfd_relax_section elf_xtensa_relax_section
+#define bfd_elf32_bfd_reloc_type_lookup elf_xtensa_reloc_type_lookup
+#define bfd_elf32_bfd_reloc_name_lookup \
+ elf_xtensa_reloc_name_lookup
+#define bfd_elf32_bfd_set_private_flags elf_xtensa_set_private_flags
+#define bfd_elf32_bfd_link_hash_table_create elf_xtensa_link_hash_table_create
+
+#define elf_backend_adjust_dynamic_symbol elf_xtensa_adjust_dynamic_symbol
+#define elf_backend_check_relocs elf_xtensa_check_relocs
+#define elf_backend_create_dynamic_sections elf_xtensa_create_dynamic_sections
+#define elf_backend_discard_info elf_xtensa_discard_info
+#define elf_backend_ignore_discarded_relocs elf_xtensa_ignore_discarded_relocs
+#define elf_backend_final_write_processing elf_xtensa_final_write_processing
+#define elf_backend_finish_dynamic_sections elf_xtensa_finish_dynamic_sections
+#define elf_backend_finish_dynamic_symbol elf_xtensa_finish_dynamic_symbol
+#define elf_backend_gc_mark_hook elf_xtensa_gc_mark_hook
+#define elf_backend_gc_sweep_hook elf_xtensa_gc_sweep_hook
+#define elf_backend_grok_prstatus elf_xtensa_grok_prstatus
+#define elf_backend_grok_psinfo elf_xtensa_grok_psinfo
+#define elf_backend_hide_symbol elf_xtensa_hide_symbol
+#define elf_backend_object_p elf_xtensa_object_p
+#define elf_backend_reloc_type_class elf_xtensa_reloc_type_class
+#define elf_backend_relocate_section elf_xtensa_relocate_section
+#define elf_backend_size_dynamic_sections elf_xtensa_size_dynamic_sections
+#define elf_backend_always_size_sections elf_xtensa_always_size_sections
+#define elf_backend_omit_section_dynsym \
+ ((bfd_boolean (*) (bfd *, struct bfd_link_info *, asection *)) bfd_true)
+#define elf_backend_special_sections elf_xtensa_special_sections
+#define elf_backend_action_discarded elf_xtensa_action_discarded
+#define elf_backend_copy_indirect_symbol elf_xtensa_copy_indirect_symbol
+
+#include "elf32-target.h"
diff --git a/bfd/elf32.c b/bfd/elf32.c
new file mode 100644
index 0000000..1e6ae4a
--- /dev/null
+++ b/bfd/elf32.c
@@ -0,0 +1,23 @@
+/* ELF 32-bit executable support for BFD.
+ Copyright (C) 1993-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, 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 0000000..1a4fc23
--- /dev/null
+++ b/bfd/elf64-alpha.c
@@ -0,0 +1,5598 @@
+/* Alpha specific support for 64-bit ELF
+ Copyright (C) 1996-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+
+/* We need a published ABI spec for this. Until one comes out, don't
+ assume this'll remain unchanged forever. */
+
+#include "sysdep.h"
+#include "bfd.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"
+
+
+/* Instruction data for plt generation and relaxation. */
+
+#define OP_LDA 0x08
+#define OP_LDAH 0x09
+#define OP_LDQ 0x29
+#define OP_BR 0x30
+#define OP_BSR 0x34
+
+#define INSN_LDA (OP_LDA << 26)
+#define INSN_LDAH (OP_LDAH << 26)
+#define INSN_LDQ (OP_LDQ << 26)
+#define INSN_BR (OP_BR << 26)
+
+#define INSN_ADDQ 0x40000400
+#define INSN_RDUNIQ 0x0000009e
+#define INSN_SUBQ 0x40000520
+#define INSN_S4SUBQ 0x40000560
+#define INSN_UNOP 0x2ffe0000
+
+#define INSN_JSR 0x68004000
+#define INSN_JMP 0x68000000
+#define INSN_JSR_MASK 0xfc00c000
+
+#define INSN_A(I,A) (I | (A << 21))
+#define INSN_AB(I,A,B) (I | (A << 21) | (B << 16))
+#define INSN_ABC(I,A,B,C) (I | (A << 21) | (B << 16) | C)
+#define INSN_ABO(I,A,B,O) (I | (A << 21) | (B << 16) | ((O) & 0xffff))
+#define INSN_AD(I,A,D) (I | (A << 21) | (((D) >> 2) & 0x1fffff))
+
+/* PLT/GOT Stuff */
+
+/* Set by ld emulation. Putting this into the link_info or hash structure
+ is simply working too hard. */
+#ifdef USE_SECUREPLT
+bfd_boolean elf64_alpha_use_secureplt = TRUE;
+#else
+bfd_boolean elf64_alpha_use_secureplt = FALSE;
+#endif
+
+#define OLD_PLT_HEADER_SIZE 32
+#define OLD_PLT_ENTRY_SIZE 12
+#define NEW_PLT_HEADER_SIZE 36
+#define NEW_PLT_ENTRY_SIZE 4
+
+#define PLT_HEADER_SIZE \
+ (elf64_alpha_use_secureplt ? NEW_PLT_HEADER_SIZE : OLD_PLT_HEADER_SIZE)
+#define PLT_ENTRY_SIZE \
+ (elf64_alpha_use_secureplt ? NEW_PLT_ENTRY_SIZE : OLD_PLT_ENTRY_SIZE)
+
+#define MAX_GOT_SIZE (64*1024)
+
+#define ELF_DYNAMIC_INTERPRETER "/usr/lib/ld.so"
+
+
+/* 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;
+
+ /* The .plt offset for this entry. */
+ int plt_offset;
+
+ /* How many references to this entry? */
+ int use_count;
+
+ /* The relocation type of this entry. */
+ unsigned char reloc_type;
+
+ /* How a LITERAL is used. */
+ unsigned char flags;
+
+ /* Have we initialized the dynamic relocation for this entry? */
+ unsigned char reloc_done;
+
+ /* Have we adjusted this entry for SEC_MERGE? */
+ unsigned char reloc_xlated;
+};
+
+struct alpha_elf_reloc_entry
+{
+ struct alpha_elf_reloc_entry *next;
+
+ /* Which .reloc section? */
+ asection *srel;
+
+ /* What kind of relocation? */
+ unsigned int rtype;
+
+ /* Is this against read-only section? */
+ unsigned int reltext : 1;
+
+ /* How many did we find? */
+ unsigned long count;
+};
+
+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 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_JSR 0x08
+#define ALPHA_ELF_LINK_HASH_LU_TLSGD 0x10
+#define ALPHA_ELF_LINK_HASH_LU_TLSLDM 0x20
+#define ALPHA_ELF_LINK_HASH_LU_JSRDIRECT 0x40
+#define ALPHA_ELF_LINK_HASH_LU_PLT 0x38
+#define ALPHA_ELF_LINK_HASH_TLS_IE 0x80
+
+ /* Used to implement multiple .got subsections. */
+ struct alpha_elf_got_entry *got_entries;
+
+ /* Used to count non-got, non-plt relocations for delayed sizing
+ of relocation sections. */
+ struct alpha_elf_reloc_entry *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;
+
+ /* The most recent relax pass that we've seen. The GOTs
+ should be regenerated if this doesn't match. */
+ int relax_trip;
+};
+
+/* 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, \
+ (bfd_boolean (*) (struct elf_link_hash_entry *, void *)) (func), \
+ (info)))
+
+/* Get the Alpha ELF linker hash table from a link_info structure. */
+
+#define alpha_elf_hash_table(p) \
+ (elf_hash_table_id ((struct elf_link_hash_table *) ((p)->hash)) \
+ == ALPHA_ELF_DATA ? ((struct alpha_elf_link_hash_table *) ((p)->hash)) : NULL)
+
+/* 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? This differs from the
+ generic version in that we never need to consider function pointer
+ equality wrt PLT entries -- we don't create a PLT entry if a symbol's
+ address is ever taken. */
+
+static inline bfd_boolean
+alpha_elf_dynamic_symbol_p (struct elf_link_hash_entry *h,
+ struct bfd_link_info *info)
+{
+ return _bfd_elf_dynamic_symbol_p (h, info, 0);
+}
+
+/* Create an entry in a Alpha ELF linker hash table. */
+
+static struct bfd_hash_entry *
+elf64_alpha_link_hash_newfunc (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 (bfd *abfd)
+{
+ struct alpha_elf_link_hash_table *ret;
+ bfd_size_type amt = sizeof (struct alpha_elf_link_hash_table);
+
+ ret = (struct alpha_elf_link_hash_table *) bfd_zmalloc (amt);
+ 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,
+ sizeof (struct alpha_elf_link_hash_entry),
+ ALPHA_ELF_DATA))
+ {
+ free (ret);
+ return NULL;
+ }
+
+ return &ret->root.root;
+}
+
+/* Alpha ELF follows MIPS ELF in using a special find_nearest_line
+ routine in order to handle the ECOFF debugging information. */
+
+struct alpha_elf_find_line
+{
+ struct ecoff_debug_info d;
+ struct ecoff_find_line i;
+};
+
+/* 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 words. */
+ int total_got_size;
+
+ /* For every got, this is the sum of the number of words required
+ to hold all of the member object's local got. */
+ int local_got_size;
+
+ /* Used by elf64_alpha_find_nearest_line entry point. */
+ struct alpha_elf_find_line *find_line_info;
+
+};
+
+#define alpha_elf_tdata(abfd) \
+ ((struct alpha_elf_obj_tdata *) (abfd)->tdata.any)
+
+#define is_alpha_elf(bfd) \
+ (bfd_get_flavour (bfd) == bfd_target_elf_flavour \
+ && elf_tdata (bfd) != NULL \
+ && elf_object_id (bfd) == ALPHA_ELF_DATA)
+
+static bfd_boolean
+elf64_alpha_mkobject (bfd *abfd)
+{
+ return bfd_elf_allocate_object (abfd, sizeof (struct alpha_elf_obj_tdata),
+ ALPHA_ELF_DATA);
+}
+
+static bfd_boolean
+elf64_alpha_object_p (bfd *abfd)
+{
+ /* Set the right machine number for an Alpha ELF file. */
+ return bfd_default_set_arch_mach (abfd, bfd_arch_alpha, 0);
+}
+
+/* A relocation function which doesn't do anything. */
+
+static bfd_reloc_status_type
+elf64_alpha_reloc_nil (bfd *abfd ATTRIBUTE_UNUSED, arelent *reloc,
+ asymbol *sym ATTRIBUTE_UNUSED,
+ void * data ATTRIBUTE_UNUSED, asection *sec,
+ bfd *output_bfd, char **error_message ATTRIBUTE_UNUSED)
+{
+ 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 (bfd *abfd ATTRIBUTE_UNUSED, arelent *reloc,
+ asymbol *sym ATTRIBUTE_UNUSED,
+ void * data ATTRIBUTE_UNUSED, asection *sec,
+ bfd *output_bfd, char **error_message ATTRIBUTE_UNUSED)
+{
+ 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 (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, (bfd_vma) i_ldah, p_ldah);
+ bfd_put_32 (abfd, (bfd_vma) i_lda, p_lda);
+
+ return ret;
+}
+
+/* The special function for the GPDISP reloc. */
+
+static bfd_reloc_status_type
+elf64_alpha_reloc_gpdisp (bfd *abfd, arelent *reloc_entry,
+ asymbol *sym ATTRIBUTE_UNUSED, void * data,
+ asection *input_section, bfd *output_bfd,
+ char **err_msg)
+{
+ bfd_reloc_status_type ret;
+ bfd_vma gp, relocation;
+ bfd_vma high_address;
+ 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;
+ }
+
+ high_address = bfd_get_section_limit (abfd, input_section);
+ if (reloc_entry->address > high_address
+ || reloc_entry->address + reloc_entry->addend > high_address)
+ 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;
+}
+
+/* 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)
+
+
+#define SKIP_HOWTO(N) \
+ HOWTO(N, 0, 0, 0, 0, 0, complain_overflow_dont, elf64_alpha_reloc_bad, 0, 0, 0, 0, 0)
+
+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 */
+ bfd_elf_generic_reloc, /* 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 */
+ bfd_elf_generic_reloc, /* 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 */
+ bfd_elf_generic_reloc, /* 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 */
+ 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 */
+ "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 */
+ 1, /* 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 */
+ bfd_elf_generic_reloc, /* 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 */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 14, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* 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 */
+ bfd_elf_generic_reloc, /* special_function */
+ "SREL16", /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ TRUE), /* 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 */
+ bfd_elf_generic_reloc, /* special_function */
+ "SREL32", /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ TRUE), /* 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 */
+ bfd_elf_generic_reloc, /* special_function */
+ "SREL64", /* name */
+ FALSE, /* partial_inplace */
+ MINUS_ONE, /* src_mask */
+ MINUS_ONE, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* Skip 12 - 16; deprecated ECOFF relocs. */
+ SKIP_HOWTO (12),
+ SKIP_HOWTO (13),
+ SKIP_HOWTO (14),
+ SKIP_HOWTO (15),
+ SKIP_HOWTO (16),
+
+ /* The high 16 bits of the displacement from GP to the target. */
+ HOWTO (R_ALPHA_GPRELHIGH,
+ 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 */
+ "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 */
+ 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 */
+ "GPRELLOW", /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A 16-bit displacement from the GP to the target. */
+ HOWTO (R_ALPHA_GPREL16,
+ 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 */
+ "GPREL16", /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Skip 20 - 23; deprecated ECOFF relocs. */
+ SKIP_HOWTO (20),
+ SKIP_HOWTO (21),
+ SKIP_HOWTO (22),
+ SKIP_HOWTO (23),
+
+ /* 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 21 bit branch that adjusts for gp loads. */
+ HOWTO (R_ALPHA_BRSGP, /* type */
+ 2, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 21, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "BRSGP", /* name */
+ FALSE, /* partial_inplace */
+ 0x1fffff, /* src_mask */
+ 0x1fffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* Creates a tls_index for the symbol in the got. */
+ HOWTO (R_ALPHA_TLSGD, /* 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 */
+ "TLSGD", /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Creates a tls_index for the (current) module in the got. */
+ HOWTO (R_ALPHA_TLSLDM, /* 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 */
+ "TLSLDM", /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A dynamic relocation for a DTP module entry. */
+ HOWTO (R_ALPHA_DTPMOD64, /* 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 */
+ "DTPMOD64", /* name */
+ FALSE, /* partial_inplace */
+ MINUS_ONE, /* src_mask */
+ MINUS_ONE, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Creates a 64-bit offset in the got for the displacement
+ from DTP to the target. */
+ HOWTO (R_ALPHA_GOTDTPREL, /* 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 */
+ "GOTDTPREL", /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A dynamic relocation for a displacement from DTP to the target. */
+ HOWTO (R_ALPHA_DTPREL64, /* 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 */
+ "DTPREL64", /* name */
+ FALSE, /* partial_inplace */
+ MINUS_ONE, /* src_mask */
+ MINUS_ONE, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* The high 16 bits of the displacement from DTP to the target. */
+ HOWTO (R_ALPHA_DTPRELHI, /* 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 */
+ "DTPRELHI", /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* The low 16 bits of the displacement from DTP to the target. */
+ HOWTO (R_ALPHA_DTPRELLO, /* 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 */
+ "DTPRELLO", /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A 16-bit displacement from DTP to the target. */
+ HOWTO (R_ALPHA_DTPREL16, /* 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 */
+ "DTPREL16", /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Creates a 64-bit offset in the got for the displacement
+ from TP to the target. */
+ HOWTO (R_ALPHA_GOTTPREL, /* 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 */
+ "GOTTPREL", /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A dynamic relocation for a displacement from TP to the target. */
+ HOWTO (R_ALPHA_TPREL64, /* 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 */
+ "TPREL64", /* name */
+ FALSE, /* partial_inplace */
+ MINUS_ONE, /* src_mask */
+ MINUS_ONE, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* The high 16 bits of the displacement from TP to the target. */
+ HOWTO (R_ALPHA_TPRELHI, /* 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 */
+ "TPRELHI", /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* The low 16 bits of the displacement from TP to the target. */
+ HOWTO (R_ALPHA_TPRELLO, /* 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 */
+ "TPRELLO", /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A 16-bit displacement from TP to the target. */
+ HOWTO (R_ALPHA_TPREL16, /* 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 */
+ "TPREL16", /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+};
+
+/* 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},
+ {BFD_RELOC_ALPHA_GPREL_HI16, R_ALPHA_GPRELHIGH},
+ {BFD_RELOC_ALPHA_GPREL_LO16, R_ALPHA_GPRELLOW},
+ {BFD_RELOC_GPREL16, R_ALPHA_GPREL16},
+ {BFD_RELOC_ALPHA_BRSGP, R_ALPHA_BRSGP},
+ {BFD_RELOC_ALPHA_TLSGD, R_ALPHA_TLSGD},
+ {BFD_RELOC_ALPHA_TLSLDM, R_ALPHA_TLSLDM},
+ {BFD_RELOC_ALPHA_DTPMOD64, R_ALPHA_DTPMOD64},
+ {BFD_RELOC_ALPHA_GOTDTPREL16, R_ALPHA_GOTDTPREL},
+ {BFD_RELOC_ALPHA_DTPREL64, R_ALPHA_DTPREL64},
+ {BFD_RELOC_ALPHA_DTPREL_HI16, R_ALPHA_DTPRELHI},
+ {BFD_RELOC_ALPHA_DTPREL_LO16, R_ALPHA_DTPRELLO},
+ {BFD_RELOC_ALPHA_DTPREL16, R_ALPHA_DTPREL16},
+ {BFD_RELOC_ALPHA_GOTTPREL16, R_ALPHA_GOTTPREL},
+ {BFD_RELOC_ALPHA_TPREL64, R_ALPHA_TPREL64},
+ {BFD_RELOC_ALPHA_TPREL_HI16, R_ALPHA_TPRELHI},
+ {BFD_RELOC_ALPHA_TPREL_LO16, R_ALPHA_TPRELLO},
+ {BFD_RELOC_ALPHA_TPREL16, R_ALPHA_TPREL16},
+};
+
+/* Given a BFD reloc type, return a HOWTO structure. */
+
+static reloc_howto_type *
+elf64_alpha_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ 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;
+}
+
+static reloc_howto_type *
+elf64_alpha_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ const char *r_name)
+{
+ unsigned int i;
+
+ for (i = 0;
+ i < (sizeof (elf64_alpha_howto_table)
+ / sizeof (elf64_alpha_howto_table[0]));
+ i++)
+ if (elf64_alpha_howto_table[i].name != NULL
+ && strcasecmp (elf64_alpha_howto_table[i].name, r_name) == 0)
+ return &elf64_alpha_howto_table[i];
+
+ return NULL;
+}
+
+/* Given an Alpha ELF reloc type, fill in an arelent structure. */
+
+static void
+elf64_alpha_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED, arelent *cache_ptr,
+ Elf_Internal_Rela *dst)
+{
+ unsigned 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 two relocations create a two-word entry in the got. */
+#define alpha_got_entry_size(r_type) \
+ (r_type == R_ALPHA_TLSGD || r_type == R_ALPHA_TLSLDM ? 16 : 8)
+
+/* This is PT_TLS segment p_vaddr. */
+#define alpha_get_dtprel_base(info) \
+ (elf_hash_table (info)->tls_sec->vma)
+
+/* Main program TLS (whose template starts at PT_TLS p_vaddr)
+ is assigned offset round(16, PT_TLS p_align). */
+#define alpha_get_tprel_base(info) \
+ (elf_hash_table (info)->tls_sec->vma \
+ - align_power ((bfd_vma) 16, \
+ elf_hash_table (info)->tls_sec->alignment_power))
+
+/* Handle an Alpha specific section when reading an object file. This
+ is called when bfd_section_from_shdr 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 bfd_boolean
+elf64_alpha_section_from_shdr (bfd *abfd,
+ Elf_Internal_Shdr *hdr,
+ const char *name,
+ int shindex)
+{
+ 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;
+ default:
+ return FALSE;
+ }
+
+ if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex))
+ 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;
+ }
+
+ return TRUE;
+}
+
+/* Convert Alpha specific section flags to bfd internal section flags. */
+
+static bfd_boolean
+elf64_alpha_section_flags (flagword *flags, const Elf_Internal_Shdr *hdr)
+{
+ if (hdr->sh_flags & SHF_ALPHA_GPREL)
+ *flags |= SEC_SMALL_DATA;
+
+ 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 bfd_boolean
+elf64_alpha_fake_sections (bfd *abfd, Elf_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;
+ }
+ else if ((sec->flags & SEC_SMALL_DATA)
+ || 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 bfd_boolean
+elf64_alpha_add_symbol_hook (bfd *abfd, struct bfd_link_info *info,
+ Elf_Internal_Sym *sym,
+ const char **namep ATTRIBUTE_UNUSED,
+ flagword *flagsp ATTRIBUTE_UNUSED,
+ asection **secp, bfd_vma *valp)
+{
+ if (sym->st_shndx == SHN_COMMON
+ && !info->relocatable
+ && sym->st_size <= elf_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_with_flags (abfd, ".scommon",
+ (SEC_ALLOC
+ | SEC_IS_COMMON
+ | SEC_LINKER_CREATED));
+ if (scomm == NULL)
+ return FALSE;
+ }
+
+ *secp = scomm;
+ *valp = sym->st_size;
+ }
+
+ return TRUE;
+}
+
+/* Create the .got section. */
+
+static bfd_boolean
+elf64_alpha_create_got_section (bfd *abfd,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED)
+{
+ flagword flags;
+ asection *s;
+
+ if (! is_alpha_elf (abfd))
+ return FALSE;
+
+ flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
+ | SEC_LINKER_CREATED);
+ s = bfd_make_section_anyway_with_flags (abfd, ".got", flags);
+ if (s == NULL
+ || !bfd_set_section_alignment (abfd, s, 3))
+ return FALSE;
+
+ alpha_elf_tdata (abfd)->got = s;
+
+ /* 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;
+
+ return TRUE;
+}
+
+/* Create all the dynamic sections. */
+
+static bfd_boolean
+elf64_alpha_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
+{
+ asection *s;
+ flagword flags;
+ struct elf_link_hash_entry *h;
+
+ if (! is_alpha_elf (abfd))
+ return FALSE;
+
+ /* We need to create .plt, .rela.plt, .got, and .rela.got sections. */
+
+ flags = (SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS | SEC_IN_MEMORY
+ | SEC_LINKER_CREATED
+ | (elf64_alpha_use_secureplt ? SEC_READONLY : 0));
+ s = bfd_make_section_anyway_with_flags (abfd, ".plt", flags);
+ if (s == NULL || ! bfd_set_section_alignment (abfd, s, 4))
+ return FALSE;
+
+ /* Define the symbol _PROCEDURE_LINKAGE_TABLE_ at the start of the
+ .plt section. */
+ h = _bfd_elf_define_linkage_sym (abfd, info, s,
+ "_PROCEDURE_LINKAGE_TABLE_");
+ elf_hash_table (info)->hplt = h;
+ if (h == NULL)
+ return FALSE;
+
+ flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
+ | SEC_LINKER_CREATED | SEC_READONLY);
+ s = bfd_make_section_anyway_with_flags (abfd, ".rela.plt", flags);
+ if (s == NULL || ! bfd_set_section_alignment (abfd, s, 3))
+ return FALSE;
+
+ if (elf64_alpha_use_secureplt)
+ {
+ flags = SEC_ALLOC | SEC_LINKER_CREATED;
+ s = bfd_make_section_anyway_with_flags (abfd, ".got.plt", flags);
+ if (s == NULL || ! 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 (alpha_elf_tdata(abfd)->gotobj == NULL)
+ {
+ if (!elf64_alpha_create_got_section (abfd, info))
+ return FALSE;
+ }
+
+ flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
+ | SEC_LINKER_CREATED | SEC_READONLY);
+ s = bfd_make_section_anyway_with_flags (abfd, ".rela.got", flags);
+ if (s == NULL
+ || !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 = _bfd_elf_define_linkage_sym (abfd, info, alpha_elf_tdata(abfd)->got,
+ "_GLOBAL_OFFSET_TABLE_");
+ elf_hash_table (info)->hgot = h;
+ if (h == NULL)
+ return FALSE;
+
+ return TRUE;
+}
+
+/* Read ECOFF debugging information from a .mdebug section into a
+ ecoff_debug_info structure. */
+
+static bfd_boolean
+elf64_alpha_read_ecoff_info (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 (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))
+ 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 \
+ { \
+ bfd_size_type amt = (bfd_size_type) size * symhdr->count; \
+ debug->ptr = (type) bfd_malloc (amt); \
+ if (debug->ptr == NULL) \
+ goto error_return; \
+ if (bfd_seek (abfd, (file_ptr) symhdr->offset, SEEK_SET) != 0 \
+ || bfd_bread (debug->ptr, amt, abfd) != amt) \
+ goto error_return; \
+ }
+
+ READ (line, cbLineOffset, cbLine, sizeof (unsigned char), unsigned char *);
+ READ (external_dnr, cbDnOffset, idnMax, swap->external_dnr_size, void *);
+ READ (external_pdr, cbPdOffset, ipdMax, swap->external_pdr_size, void *);
+ READ (external_sym, cbSymOffset, isymMax, swap->external_sym_size, void *);
+ READ (external_opt, cbOptOffset, ioptMax, swap->external_opt_size, void *);
+ 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, void *);
+ READ (external_rfd, cbRfdOffset, crfd, swap->external_rfd_size, void *);
+ READ (external_ext, cbExtOffset, iextMax, swap->external_ext_size, void *);
+#undef READ
+
+ debug->fdr = 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 bfd_boolean
+elf64_alpha_is_local_label_name (bfd *abfd ATTRIBUTE_UNUSED, const char *name)
+{
+ return name[0] == '$';
+}
+
+static bfd_boolean
+elf64_alpha_find_nearest_line (bfd *abfd, asymbol **symbols,
+ asection *section, bfd_vma offset,
+ const char **filename_ptr,
+ const char **functionname_ptr,
+ unsigned int *line_ptr,
+ unsigned int *discriminator_ptr)
+{
+ asection *msec;
+
+ if (_bfd_dwarf2_find_nearest_line (abfd, symbols, NULL, section, offset,
+ filename_ptr, functionname_ptr,
+ line_ptr, discriminator_ptr,
+ dwarf_debug_sections, 0,
+ &elf_tdata (abfd)->dwarf2_find_line_info))
+ return TRUE;
+
+ msec = bfd_get_section_by_name (abfd, ".mdebug");
+ if (msec != NULL)
+ {
+ flagword origflags;
+ struct alpha_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 = alpha_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;
+ bfd_size_type amt = sizeof (struct alpha_elf_find_line);
+
+ fi = (struct alpha_elf_find_line *) bfd_zalloc (abfd, amt);
+ 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. */
+ amt = fi->d.symbolic_header.ifdMax * sizeof (struct fdr);
+ fi->d.fdr = (struct fdr *) bfd_alloc (abfd, amt);
+ 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, fraw_src, fdr_ptr);
+
+ alpha_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, symbols, section, offset,
+ filename_ptr, functionname_ptr,
+ line_ptr, discriminator_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;
+ bfd_boolean failed;
+};
+
+static bfd_boolean
+elf64_alpha_output_extsym (struct alpha_elf_link_hash_entry *h, void * data)
+{
+ struct extsym_info *einfo = (struct extsym_info *) data;
+ bfd_boolean strip;
+ asection *sec, *output_section;
+
+ if (h->root.indx == -2)
+ strip = FALSE;
+ else if ((h->root.def_dynamic
+ || h->root.ref_dynamic
+ || h->root.root.type == bfd_link_hash_new)
+ && !h->root.def_regular
+ && !h->root.ref_regular)
+ 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;
+ }
+
+ 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;
+}
+
+/* Search for and possibly create a got entry. */
+
+static struct alpha_elf_got_entry *
+get_got_entry (bfd *abfd, struct alpha_elf_link_hash_entry *h,
+ unsigned long r_type, unsigned long r_symndx,
+ bfd_vma r_addend)
+{
+ struct alpha_elf_got_entry *gotent;
+ struct alpha_elf_got_entry **slot;
+
+ if (h)
+ slot = &h->got_entries;
+ else
+ {
+ /* This is a local .got entry -- record for merge. */
+
+ struct alpha_elf_got_entry **local_got_entries;
+
+ local_got_entries = alpha_elf_tdata(abfd)->local_got_entries;
+ if (!local_got_entries)
+ {
+ bfd_size_type size;
+ Elf_Internal_Shdr *symtab_hdr;
+
+ symtab_hdr = &elf_tdata(abfd)->symtab_hdr;
+ size = symtab_hdr->sh_info;
+ size *= sizeof (struct alpha_elf_got_entry *);
+
+ local_got_entries
+ = (struct alpha_elf_got_entry **) bfd_zalloc (abfd, size);
+ if (!local_got_entries)
+ return NULL;
+
+ alpha_elf_tdata (abfd)->local_got_entries = local_got_entries;
+ }
+
+ slot = &local_got_entries[r_symndx];
+ }
+
+ for (gotent = *slot; gotent ; gotent = gotent->next)
+ if (gotent->gotobj == abfd
+ && gotent->reloc_type == r_type
+ && gotent->addend == r_addend)
+ break;
+
+ if (!gotent)
+ {
+ int entry_size;
+ bfd_size_type amt;
+
+ amt = sizeof (struct alpha_elf_got_entry);
+ gotent = (struct alpha_elf_got_entry *) bfd_alloc (abfd, amt);
+ if (!gotent)
+ return NULL;
+
+ gotent->gotobj = abfd;
+ gotent->addend = r_addend;
+ gotent->got_offset = -1;
+ gotent->plt_offset = -1;
+ gotent->use_count = 1;
+ gotent->reloc_type = r_type;
+ gotent->reloc_done = 0;
+ gotent->reloc_xlated = 0;
+
+ gotent->next = *slot;
+ *slot = gotent;
+
+ entry_size = alpha_got_entry_size (r_type);
+ alpha_elf_tdata (abfd)->total_got_size += entry_size;
+ if (!h)
+ alpha_elf_tdata(abfd)->local_got_size += entry_size;
+ }
+ else
+ gotent->use_count += 1;
+
+ return gotent;
+}
+
+static bfd_boolean
+elf64_alpha_want_plt (struct alpha_elf_link_hash_entry *ah)
+{
+ return ((ah->root.type == STT_FUNC
+ || ah->root.root.type == bfd_link_hash_undefweak
+ || ah->root.root.type == bfd_link_hash_undefined)
+ && (ah->flags & ALPHA_ELF_LINK_HASH_LU_PLT) != 0
+ && (ah->flags & ~ALPHA_ELF_LINK_HASH_LU_PLT) == 0);
+}
+
+/* Handle dynamic relocations when doing an Alpha ELF link. */
+
+static bfd_boolean
+elf64_alpha_check_relocs (bfd *abfd, struct bfd_link_info *info,
+ asection *sec, const Elf_Internal_Rela *relocs)
+{
+ bfd *dynobj;
+ asection *sreloc;
+ Elf_Internal_Shdr *symtab_hdr;
+ struct alpha_elf_link_hash_entry **sym_hashes;
+ const Elf_Internal_Rela *rel, *relend;
+ bfd_size_type amt;
+
+ if (info->relocatable)
+ return TRUE;
+
+ /* Don't do anything special with non-loaded, non-alloced sections.
+ In particular, any relocs in such sections should not affect GOT
+ and PLT reference counting (ie. we don't allow them to create GOT
+ or PLT entries), there's no possibility or desire to optimize TLS
+ relocs, and there's not much point in propagating relocs to shared
+ libs that the dynamic linker won't relocate. */
+ if ((sec->flags & SEC_ALLOC) == 0)
+ return TRUE;
+
+ BFD_ASSERT (is_alpha_elf (abfd));
+
+ dynobj = elf_hash_table (info)->dynobj;
+ if (dynobj == NULL)
+ elf_hash_table (info)->dynobj = dynobj = abfd;
+
+ sreloc = NULL;
+ symtab_hdr = &elf_symtab_hdr (abfd);
+ sym_hashes = alpha_elf_sym_hashes (abfd);
+
+ relend = relocs + sec->reloc_count;
+ for (rel = relocs; rel < relend; ++rel)
+ {
+ enum {
+ NEED_GOT = 1,
+ NEED_GOT_ENTRY = 2,
+ NEED_DYNREL = 4
+ };
+
+ unsigned long r_symndx, r_type;
+ struct alpha_elf_link_hash_entry *h;
+ unsigned int gotent_flags;
+ bfd_boolean maybe_dynamic;
+ unsigned int need;
+ bfd_vma addend;
+
+ 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;
+
+ /* PR15323, ref flags aren't set for references in the same
+ object. */
+ h->root.root.non_ir_ref = 1;
+ h->root.ref_regular = 1;
+ }
+
+ /* We can only get preliminary data on whether a symbol is
+ locally or externally defined, as not all of the input files
+ have yet been processed. Do something with what we know, as
+ this may help reduce memory usage and processing time later. */
+ maybe_dynamic = FALSE;
+ if (h && ((info->shared
+ && (!info->symbolic
+ || info->unresolved_syms_in_shared_libs == RM_IGNORE))
+ || !h->root.def_regular
+ || h->root.root.type == bfd_link_hash_defweak))
+ maybe_dynamic = TRUE;
+
+ need = 0;
+ gotent_flags = 0;
+ r_type = ELF64_R_TYPE (rel->r_info);
+ addend = rel->r_addend;
+
+ switch (r_type)
+ {
+ case R_ALPHA_LITERAL:
+ need = NEED_GOT | NEED_GOT_ENTRY;
+
+ /* 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. */
+ while (++rel < relend && ELF64_R_TYPE (rel->r_info) == R_ALPHA_LITUSE)
+ if (rel->r_addend >= 1 && rel->r_addend <= 6)
+ gotent_flags |= 1 << rel->r_addend;
+ --rel;
+
+ /* No LITUSEs -- presumably the address is used somehow. */
+ if (gotent_flags == 0)
+ gotent_flags = ALPHA_ELF_LINK_HASH_LU_ADDR;
+ break;
+
+ case R_ALPHA_GPDISP:
+ case R_ALPHA_GPREL16:
+ case R_ALPHA_GPREL32:
+ case R_ALPHA_GPRELHIGH:
+ case R_ALPHA_GPRELLOW:
+ case R_ALPHA_BRSGP:
+ need = NEED_GOT;
+ break;
+
+ case R_ALPHA_REFLONG:
+ case R_ALPHA_REFQUAD:
+ if (info->shared || maybe_dynamic)
+ need = NEED_DYNREL;
+ break;
+
+ case R_ALPHA_TLSLDM:
+ /* The symbol for a TLSLDM reloc is ignored. Collapse the
+ reloc to the STN_UNDEF (0) symbol so that they all match. */
+ r_symndx = STN_UNDEF;
+ h = 0;
+ maybe_dynamic = FALSE;
+ /* FALLTHRU */
+
+ case R_ALPHA_TLSGD:
+ case R_ALPHA_GOTDTPREL:
+ need = NEED_GOT | NEED_GOT_ENTRY;
+ break;
+
+ case R_ALPHA_GOTTPREL:
+ need = NEED_GOT | NEED_GOT_ENTRY;
+ gotent_flags = ALPHA_ELF_LINK_HASH_TLS_IE;
+ if (info->shared)
+ info->flags |= DF_STATIC_TLS;
+ break;
+
+ case R_ALPHA_TPREL64:
+ if (info->shared && !info->pie)
+ {
+ info->flags |= DF_STATIC_TLS;
+ need = NEED_DYNREL;
+ }
+ else if (maybe_dynamic)
+ need = NEED_DYNREL;
+ break;
+ }
+
+ if (need & NEED_GOT)
+ {
+ if (alpha_elf_tdata(abfd)->gotobj == NULL)
+ {
+ if (!elf64_alpha_create_got_section (abfd, info))
+ return FALSE;
+ }
+ }
+
+ if (need & NEED_GOT_ENTRY)
+ {
+ struct alpha_elf_got_entry *gotent;
+
+ gotent = get_got_entry (abfd, h, r_type, r_symndx, addend);
+ if (!gotent)
+ return FALSE;
+
+ if (gotent_flags)
+ {
+ gotent->flags |= gotent_flags;
+ if (h)
+ {
+ gotent_flags |= h->flags;
+ h->flags = gotent_flags;
+
+ /* Make a guess as to whether a .plt entry is needed. */
+ /* ??? It appears that we won't make it into
+ adjust_dynamic_symbol for symbols that remain
+ totally undefined. Copying this check here means
+ we can create a plt entry for them too. */
+ h->root.needs_plt
+ = (maybe_dynamic && elf64_alpha_want_plt (h));
+ }
+ }
+ }
+
+ if (need & NEED_DYNREL)
+ {
+ /* 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_elf_make_dynamic_reloc_section
+ (sec, dynobj, 3, abfd, /*rela?*/ TRUE);
+
+ if (sreloc == NULL)
+ 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)
+ {
+ amt = sizeof (struct alpha_elf_reloc_entry);
+ rent = (struct alpha_elf_reloc_entry *) bfd_alloc (abfd, amt);
+ if (!rent)
+ return FALSE;
+
+ rent->srel = sreloc;
+ rent->rtype = r_type;
+ rent->count = 1;
+ rent->reltext = (sec->flags & SEC_READONLY) != 0;
+
+ rent->next = h->reloc_entries;
+ h->reloc_entries = rent;
+ }
+ else
+ rent->count++;
+ }
+ else if (info->shared)
+ {
+ /* If this is a shared library, and the section is to be
+ loaded into memory, we need a RELATIVE reloc. */
+ sreloc->size += sizeof (Elf64_External_Rela);
+ if (sec->flags & SEC_READONLY)
+ info->flags |= DF_TEXTREL;
+ }
+ }
+ }
+
+ return TRUE;
+}
+
+/* Return the section that should be marked against GC for a given
+ relocation. */
+
+static asection *
+elf64_alpha_gc_mark_hook (asection *sec, struct bfd_link_info *info,
+ Elf_Internal_Rela *rel,
+ struct elf_link_hash_entry *h, Elf_Internal_Sym *sym)
+{
+ /* These relocations don't really reference a symbol. Instead we store
+ extra data in their addend slot. Ignore the symbol. */
+ switch (ELF64_R_TYPE (rel->r_info))
+ {
+ case R_ALPHA_LITUSE:
+ case R_ALPHA_GPDISP:
+ case R_ALPHA_HINT:
+ return NULL;
+ }
+
+ return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
+}
+
+/* Update the got entry reference counts for the section being removed. */
+
+static bfd_boolean
+elf64_alpha_gc_sweep_hook (bfd *abfd, struct bfd_link_info *info,
+ asection *sec, const Elf_Internal_Rela *relocs)
+{
+ Elf_Internal_Shdr *symtab_hdr;
+ struct alpha_elf_link_hash_entry **sym_hashes;
+ const Elf_Internal_Rela *rel, *relend;
+
+ if (info->relocatable)
+ return TRUE;
+
+ symtab_hdr = &elf_symtab_hdr (abfd);
+ sym_hashes = alpha_elf_sym_hashes (abfd);
+
+ relend = relocs + sec->reloc_count;
+ for (rel = relocs; rel < relend; rel++)
+ {
+ unsigned long r_symndx, r_type;
+ struct alpha_elf_link_hash_entry *h = NULL;
+ struct alpha_elf_got_entry *gotent;
+
+ r_symndx = ELF64_R_SYM (rel->r_info);
+ if (r_symndx >= symtab_hdr->sh_info)
+ {
+ 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;
+ }
+
+ r_type = ELF64_R_TYPE (rel->r_info);
+ switch (r_type)
+ {
+ case R_ALPHA_LITERAL:
+ /* ??? Ignore re-computation of gotent_flags. We're not
+ carrying a use-count for each bit in that mask. */
+
+ case R_ALPHA_TLSGD:
+ case R_ALPHA_GOTDTPREL:
+ case R_ALPHA_GOTTPREL:
+ /* Fetch the got entry from the tables. */
+ gotent = get_got_entry (abfd, h, r_type, r_symndx, rel->r_addend);
+
+ /* The got entry *must* exist, since we should have created it
+ before during check_relocs. Also note that get_got_entry
+ assumed this was going to be another use, and so incremented
+ the use count again. Thus the use count must be at least the
+ one real use and the "use" we just added. */
+ if (gotent == NULL || gotent->use_count < 2)
+ {
+ abort ();
+ return FALSE;
+ }
+ gotent->use_count -= 2;
+ 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 bfd_boolean
+elf64_alpha_adjust_dynamic_symbol (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. Irritatingly, it
+ is common for folk to leave undefined symbols in shared libraries,
+ and they still expect lazy binding; accept undefined symbols in lieu
+ of STT_FUNC. */
+ if (alpha_elf_dynamic_symbol_p (h, info) && elf64_alpha_want_plt (ah))
+ {
+ h->needs_plt = TRUE;
+
+ s = bfd_get_linker_section (dynobj, ".plt");
+ if (!s && !elf64_alpha_create_dynamic_sections (dynobj, info))
+ return FALSE;
+
+ /* We need one plt entry per got subsection. Delay allocation of
+ the actual plt entries until size_plt_section, called from
+ size_dynamic_sections or during relaxation. */
+
+ return TRUE;
+ }
+ else
+ h->needs_plt = FALSE;
+
+ /* 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->u.weakdef != NULL)
+ {
+ BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
+ || h->u.weakdef->root.type == bfd_link_hash_defweak);
+ h->root.u.def.section = h->u.weakdef->root.u.def.section;
+ h->root.u.def.value = h->u.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;
+}
+
+/* Record STO_ALPHA_NOPV and STO_ALPHA_STD_GPLOAD. */
+
+static void
+elf64_alpha_merge_symbol_attribute (struct elf_link_hash_entry *h,
+ const Elf_Internal_Sym *isym,
+ bfd_boolean definition,
+ bfd_boolean dynamic)
+{
+ if (!dynamic && definition)
+ h->other = ((h->other & ELF_ST_VISIBILITY (-1))
+ | (isym->st_other & ~ELF_ST_VISIBILITY (-1)));
+}
+
+/* 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 void
+elf64_alpha_copy_indirect_symbol (struct bfd_link_info *info,
+ struct elf_link_hash_entry *dir,
+ struct elf_link_hash_entry *ind)
+{
+ struct alpha_elf_link_hash_entry *hi
+ = (struct alpha_elf_link_hash_entry *) ind;
+ struct alpha_elf_link_hash_entry *hs
+ = (struct alpha_elf_link_hash_entry *) dir;
+
+ /* Do the merging in the superclass. */
+ _bfd_elf_link_hash_copy_indirect(info, dir, ind);
+
+ /* Merge the flags. Whee. */
+ hs->flags |= hi->flags;
+
+ /* ??? It's unclear to me what's really supposed to happen when
+ "merging" defweak and defined symbols, given that we don't
+ actually throw away the defweak. This more-or-less copies
+ the logic related to got and plt entries in the superclass. */
+ if (ind->root.type != bfd_link_hash_indirect)
+ return;
+
+ /* 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->reloc_type == gs->reloc_type
+ && gi->addend == gs->addend)
+ {
+ gi->use_count += gs->use_count;
+ 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 && ri->srel == rs->srel)
+ {
+ rs->count += ri->count;
+ goto found_reloc;
+ }
+ ri->next = hs->reloc_entries;
+ hs->reloc_entries = ri;
+ found_reloc:;
+ }
+ }
+ hi->reloc_entries = NULL;
+}
+
+/* Is it possible to merge two object file's .got tables? */
+
+static bfd_boolean
+elf64_alpha_can_merge_gots (bfd *a, bfd *b)
+{
+ int total = alpha_elf_tdata (a)->total_got_size;
+ bfd *bsub;
+
+ /* Trivial quick fallout test. */
+ if (total + alpha_elf_tdata (b)->total_got_size <= MAX_GOT_SIZE)
+ return TRUE;
+
+ /* By their nature, local .got entries cannot be merged. */
+ if ((total += alpha_elf_tdata (b)->local_got_size) > MAX_GOT_SIZE)
+ 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 = NUM_SHDR_ENTRIES (symtab_hdr) - 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->reloc_type == be->reloc_type
+ && ae->addend == be->addend)
+ goto global_found;
+
+ total += alpha_got_entry_size (be->reloc_type);
+ if (total > MAX_GOT_SIZE)
+ return FALSE;
+ global_found:;
+ }
+ }
+ }
+
+ return TRUE;
+}
+
+/* Actually merge two .got tables. */
+
+static void
+elf64_alpha_merge_gots (bfd *a, bfd *b)
+{
+ int total = alpha_elf_tdata (a)->total_got_size;
+ bfd *bsub;
+
+ /* Remember local expansion. */
+ {
+ int e = alpha_elf_tdata (b)->local_got_size;
+ total += e;
+ alpha_elf_tdata (a)->local_got_size += 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 = NUM_SHDR_ENTRIES (symtab_hdr) - 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;
+
+ pbe = start = &h->got_entries;
+ while ((be = *pbe) != NULL)
+ {
+ if (be->use_count == 0)
+ {
+ *pbe = be->next;
+ memset (be, 0xa5, sizeof (*be));
+ goto kill;
+ }
+ if (be->gotobj != b)
+ goto next;
+
+ for (ae = *start; ae ; ae = ae->next)
+ if (ae->gotobj == a
+ && ae->reloc_type == be->reloc_type
+ && ae->addend == be->addend)
+ {
+ ae->flags |= be->flags;
+ ae->use_count += be->use_count;
+ *pbe = be->next;
+ memset (be, 0xa5, sizeof (*be));
+ goto kill;
+ }
+ be->gotobj = a;
+ total += alpha_got_entry_size (be->reloc_type);
+
+ next:;
+ pbe = &be->next;
+ kill:;
+ }
+ }
+
+ alpha_elf_tdata (bsub)->gotobj = a;
+ }
+ alpha_elf_tdata (a)->total_got_size = 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 bfd_boolean
+elf64_alpha_calc_got_offsets_for_symbol (struct alpha_elf_link_hash_entry *h,
+ void * arg ATTRIBUTE_UNUSED)
+{
+ struct alpha_elf_got_entry *gotent;
+
+ for (gotent = h->got_entries; gotent; gotent = gotent->next)
+ if (gotent->use_count > 0)
+ {
+ struct alpha_elf_obj_tdata *td;
+ bfd_size_type *plge;
+
+ td = alpha_elf_tdata (gotent->gotobj);
+ plge = &td->got->size;
+ gotent->got_offset = *plge;
+ *plge += alpha_got_entry_size (gotent->reloc_type);
+ }
+
+ return TRUE;
+}
+
+static void
+elf64_alpha_calc_got_offsets (struct bfd_link_info *info)
+{
+ bfd *i, *got_list;
+ struct alpha_elf_link_hash_table * htab;
+
+ htab = alpha_elf_hash_table (info);
+ if (htab == NULL)
+ return;
+ got_list = htab->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->size = 0;
+
+ /* Next, fill in the offsets for all the global entries. */
+ alpha_elf_link_hash_traverse (htab,
+ 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->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 += alpha_got_entry_size (gotent->reloc_type);
+ }
+ }
+
+ alpha_elf_tdata(i)->got->size = got_offset;
+ }
+}
+
+/* Constructs the gots. */
+
+static bfd_boolean
+elf64_alpha_size_got_sections (struct bfd_link_info *info,
+ bfd_boolean may_merge)
+{
+ bfd *i, *got_list, *cur_got_obj = NULL;
+ struct alpha_elf_link_hash_table * htab;
+
+ htab = alpha_elf_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+ got_list = htab->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;
+
+ if (! is_alpha_elf (i))
+ continue;
+
+ this_got = alpha_elf_tdata (i)->gotobj;
+ if (this_got == NULL)
+ continue;
+
+ /* We are assuming no merging has yet occurred. */
+ BFD_ASSERT (this_got == i);
+
+ if (alpha_elf_tdata (this_got)->total_got_size > MAX_GOT_SIZE)
+ {
+ /* Yikes! A single object file has too many entries. */
+ (*_bfd_error_handler)
+ (_("%B: .got subsegment exceeds 64K (size %d)"),
+ i, alpha_elf_tdata (this_got)->total_got_size);
+ 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;
+
+ htab->got_list = got_list;
+ }
+
+ cur_got_obj = got_list;
+ if (cur_got_obj == NULL)
+ return FALSE;
+
+ if (may_merge)
+ {
+ 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);
+
+ alpha_elf_tdata(i)->got->size = 0;
+ i = alpha_elf_tdata(i)->got_link_next;
+ alpha_elf_tdata(cur_got_obj)->got_link_next = i;
+ }
+ 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. */
+ elf64_alpha_calc_got_offsets (info);
+
+ return TRUE;
+}
+
+static bfd_boolean
+elf64_alpha_size_plt_section_1 (struct alpha_elf_link_hash_entry *h,
+ void * data)
+{
+ asection *splt = (asection *) data;
+ struct alpha_elf_got_entry *gotent;
+ bfd_boolean saw_one = FALSE;
+
+ /* If we didn't need an entry before, we still don't. */
+ if (!h->root.needs_plt)
+ return TRUE;
+
+ /* For each LITERAL got entry still in use, allocate a plt entry. */
+ for (gotent = h->got_entries; gotent ; gotent = gotent->next)
+ if (gotent->reloc_type == R_ALPHA_LITERAL
+ && gotent->use_count > 0)
+ {
+ if (splt->size == 0)
+ splt->size = PLT_HEADER_SIZE;
+ gotent->plt_offset = splt->size;
+ splt->size += PLT_ENTRY_SIZE;
+ saw_one = TRUE;
+ }
+
+ /* If there weren't any, there's no longer a need for the PLT entry. */
+ if (!saw_one)
+ h->root.needs_plt = FALSE;
+
+ return TRUE;
+}
+
+/* Called from relax_section to rebuild the PLT in light of potential changes
+ in the function's status. */
+
+static void
+elf64_alpha_size_plt_section (struct bfd_link_info *info)
+{
+ asection *splt, *spltrel, *sgotplt;
+ unsigned long entries;
+ bfd *dynobj;
+ struct alpha_elf_link_hash_table * htab;
+
+ htab = alpha_elf_hash_table (info);
+ if (htab == NULL)
+ return;
+
+ dynobj = elf_hash_table(info)->dynobj;
+ splt = bfd_get_linker_section (dynobj, ".plt");
+ if (splt == NULL)
+ return;
+
+ splt->size = 0;
+
+ alpha_elf_link_hash_traverse (htab,
+ elf64_alpha_size_plt_section_1, splt);
+
+ /* Every plt entry requires a JMP_SLOT relocation. */
+ spltrel = bfd_get_linker_section (dynobj, ".rela.plt");
+ entries = 0;
+ if (splt->size)
+ {
+ if (elf64_alpha_use_secureplt)
+ entries = (splt->size - NEW_PLT_HEADER_SIZE) / NEW_PLT_ENTRY_SIZE;
+ else
+ entries = (splt->size - OLD_PLT_HEADER_SIZE) / OLD_PLT_ENTRY_SIZE;
+ }
+ spltrel->size = entries * sizeof (Elf64_External_Rela);
+
+ /* When using the secureplt, we need two words somewhere in the data
+ segment for the dynamic linker to tell us where to go. This is the
+ entire contents of the .got.plt section. */
+ if (elf64_alpha_use_secureplt)
+ {
+ sgotplt = bfd_get_linker_section (dynobj, ".got.plt");
+ sgotplt->size = entries ? 16 : 0;
+ }
+}
+
+static bfd_boolean
+elf64_alpha_always_size_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
+ struct bfd_link_info *info)
+{
+ bfd *i;
+ struct alpha_elf_link_hash_table * htab;
+
+ if (info->relocatable)
+ return TRUE;
+
+ htab = alpha_elf_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ if (!elf64_alpha_size_got_sections (info, TRUE))
+ return FALSE;
+
+ /* Allocate space for all of the .got subsections. */
+ i = htab->got_list;
+ for ( ; i ; i = alpha_elf_tdata(i)->got_link_next)
+ {
+ asection *s = alpha_elf_tdata(i)->got;
+ if (s->size > 0)
+ {
+ s->contents = (bfd_byte *) bfd_zalloc (i, s->size);
+ if (s->contents == NULL)
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+/* The number of dynamic relocations required by a static relocation. */
+
+static int
+alpha_dynamic_entries_for_reloc (int r_type, int dynamic, int shared, int pie)
+{
+ switch (r_type)
+ {
+ /* May appear in GOT entries. */
+ case R_ALPHA_TLSGD:
+ return (dynamic ? 2 : shared ? 1 : 0);
+ case R_ALPHA_TLSLDM:
+ return shared;
+ case R_ALPHA_LITERAL:
+ return dynamic || shared;
+ case R_ALPHA_GOTTPREL:
+ return dynamic || (shared && !pie);
+ case R_ALPHA_GOTDTPREL:
+ return dynamic;
+
+ /* May appear in data sections. */
+ case R_ALPHA_REFLONG:
+ case R_ALPHA_REFQUAD:
+ return dynamic || shared;
+ case R_ALPHA_TPREL64:
+ return dynamic || (shared && !pie);
+
+ /* Everything else is illegal. We'll issue an error during
+ relocate_section. */
+ default:
+ return 0;
+ }
+}
+
+/* Work out the sizes of the dynamic relocation entries. */
+
+static bfd_boolean
+elf64_alpha_calc_dynrel_sizes (struct alpha_elf_link_hash_entry *h,
+ struct bfd_link_info *info)
+{
+ bfd_boolean dynamic;
+ struct alpha_elf_reloc_entry *relent;
+ unsigned long entries;
+
+ /* 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.def_regular
+ && h->root.ref_regular
+ && !h->root.def_dynamic
+ && (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.def_regular = 1;
+
+ /* 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. */
+ dynamic = alpha_elf_dynamic_symbol_p (&h->root, info);
+
+ /* If the symbol is a hidden undefined weak, then we never have any
+ relocations. Avoid the loop which may want to add RELATIVE relocs
+ based on info->shared. */
+ if (h->root.root.type == bfd_link_hash_undefweak && !dynamic)
+ return TRUE;
+
+ for (relent = h->reloc_entries; relent; relent = relent->next)
+ {
+ entries = alpha_dynamic_entries_for_reloc (relent->rtype, dynamic,
+ info->shared, info->pie);
+ if (entries)
+ {
+ relent->srel->size +=
+ entries * sizeof (Elf64_External_Rela) * relent->count;
+ if (relent->reltext)
+ info->flags |= DT_TEXTREL;
+ }
+ }
+
+ return TRUE;
+}
+
+/* Subroutine of elf64_alpha_size_rela_got_section for doing the
+ global symbols. */
+
+static bfd_boolean
+elf64_alpha_size_rela_got_1 (struct alpha_elf_link_hash_entry *h,
+ struct bfd_link_info *info)
+{
+ bfd_boolean dynamic;
+ struct alpha_elf_got_entry *gotent;
+ unsigned long entries;
+
+ /* If we're using a plt for this symbol, then all of its relocations
+ for its got entries go into .rela.plt. */
+ if (h->root.needs_plt)
+ return TRUE;
+
+ /* 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. */
+ dynamic = alpha_elf_dynamic_symbol_p (&h->root, info);
+
+ /* If the symbol is a hidden undefined weak, then we never have any
+ relocations. Avoid the loop which may want to add RELATIVE relocs
+ based on info->shared. */
+ if (h->root.root.type == bfd_link_hash_undefweak && !dynamic)
+ return TRUE;
+
+ entries = 0;
+ for (gotent = h->got_entries; gotent ; gotent = gotent->next)
+ if (gotent->use_count > 0)
+ entries += alpha_dynamic_entries_for_reloc (gotent->reloc_type, dynamic,
+ info->shared, info->pie);
+
+ if (entries > 0)
+ {
+ bfd *dynobj = elf_hash_table(info)->dynobj;
+ asection *srel = bfd_get_linker_section (dynobj, ".rela.got");
+ BFD_ASSERT (srel != NULL);
+ srel->size += sizeof (Elf64_External_Rela) * entries;
+ }
+
+ return TRUE;
+}
+
+/* Set the sizes of the dynamic relocation sections. */
+
+static void
+elf64_alpha_size_rela_got_section (struct bfd_link_info *info)
+{
+ unsigned long entries;
+ bfd *i, *dynobj;
+ asection *srel;
+ struct alpha_elf_link_hash_table * htab;
+
+ htab = alpha_elf_hash_table (info);
+ if (htab == NULL)
+ return;
+
+ /* Shared libraries often require RELATIVE relocs, and some relocs
+ require attention for the main application as well. */
+
+ entries = 0;
+ for (i = htab->got_list;
+ i ; i = alpha_elf_tdata(i)->got_link_next)
+ {
+ 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)
+ entries += (alpha_dynamic_entries_for_reloc
+ (gotent->reloc_type, 0, info->shared, info->pie));
+ }
+ }
+
+ dynobj = elf_hash_table(info)->dynobj;
+ srel = bfd_get_linker_section (dynobj, ".rela.got");
+ if (!srel)
+ {
+ BFD_ASSERT (entries == 0);
+ return;
+ }
+ srel->size = sizeof (Elf64_External_Rela) * entries;
+
+ /* Now do the non-local symbols. */
+ alpha_elf_link_hash_traverse (htab,
+ elf64_alpha_size_rela_got_1, info);
+}
+
+/* Set the sizes of the dynamic sections. */
+
+static bfd_boolean
+elf64_alpha_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
+ struct bfd_link_info *info)
+{
+ bfd *dynobj;
+ asection *s;
+ bfd_boolean relplt;
+ struct alpha_elf_link_hash_table * htab;
+
+ htab = alpha_elf_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ 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->executable)
+ {
+ s = bfd_get_linker_section (dynobj, ".interp");
+ BFD_ASSERT (s != NULL);
+ s->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 (htab,
+ elf64_alpha_calc_dynrel_sizes, info);
+
+ elf64_alpha_size_rela_got_section (info);
+ elf64_alpha_size_plt_section (info);
+ }
+ /* 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. */
+ relplt = FALSE;
+ for (s = dynobj->sections; s != NULL; s = s->next)
+ {
+ const char *name;
+
+ 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 (CONST_STRNEQ (name, ".rela"))
+ {
+ if (s->size != 0)
+ {
+ 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 (! CONST_STRNEQ (name, ".got")
+ && strcmp (name, ".plt") != 0
+ && strcmp (name, ".dynbss") != 0)
+ {
+ /* It's not one of our dynamic sections, so don't allocate space. */
+ continue;
+ }
+
+ if (s->size == 0)
+ {
+ /* 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. */
+ if (!CONST_STRNEQ (name, ".got"))
+ s->flags |= SEC_EXCLUDE;
+ }
+ else if ((s->flags & SEC_HAS_CONTENTS) != 0)
+ {
+ /* Allocate memory for the section contents. */
+ s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->size);
+ if (s->contents == NULL)
+ return FALSE;
+ }
+ }
+
+ 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. */
+#define add_dynamic_entry(TAG, VAL) \
+ _bfd_elf_add_dynamic_entry (info, TAG, VAL)
+
+ if (info->executable)
+ {
+ if (!add_dynamic_entry (DT_DEBUG, 0))
+ return FALSE;
+ }
+
+ if (relplt)
+ {
+ if (!add_dynamic_entry (DT_PLTGOT, 0)
+ || !add_dynamic_entry (DT_PLTRELSZ, 0)
+ || !add_dynamic_entry (DT_PLTREL, DT_RELA)
+ || !add_dynamic_entry (DT_JMPREL, 0))
+ return FALSE;
+
+ if (elf64_alpha_use_secureplt
+ && !add_dynamic_entry (DT_ALPHA_PLTRO, 1))
+ return FALSE;
+ }
+
+ if (!add_dynamic_entry (DT_RELA, 0)
+ || !add_dynamic_entry (DT_RELASZ, 0)
+ || !add_dynamic_entry (DT_RELAENT, sizeof (Elf64_External_Rela)))
+ return FALSE;
+
+ if (info->flags & DF_TEXTREL)
+ {
+ if (!add_dynamic_entry (DT_TEXTREL, 0))
+ return FALSE;
+ }
+ }
+#undef add_dynamic_entry
+
+ return TRUE;
+}
+
+/* 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. */
+
+struct alpha_relax_info
+{
+ bfd *abfd;
+ asection *sec;
+ bfd_byte *contents;
+ Elf_Internal_Shdr *symtab_hdr;
+ Elf_Internal_Rela *relocs, *relend;
+ struct bfd_link_info *link_info;
+ bfd_vma gp;
+ bfd *gotobj;
+ asection *tsec;
+ struct alpha_elf_link_hash_entry *h;
+ struct alpha_elf_got_entry **first_gotent;
+ struct alpha_elf_got_entry *gotent;
+ bfd_boolean changed_contents;
+ bfd_boolean changed_relocs;
+ unsigned char other;
+};
+
+static Elf_Internal_Rela *
+elf64_alpha_find_reloc_at_ofs (Elf_Internal_Rela *rel,
+ Elf_Internal_Rela *relend,
+ bfd_vma offset, int type)
+{
+ while (rel < relend)
+ {
+ if (rel->r_offset == offset
+ && ELF64_R_TYPE (rel->r_info) == (unsigned int) type)
+ return rel;
+ ++rel;
+ }
+ return NULL;
+}
+
+static bfd_boolean
+elf64_alpha_relax_got_load (struct alpha_relax_info *info, bfd_vma symval,
+ Elf_Internal_Rela *irel, unsigned long r_type)
+{
+ 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)
+ {
+ reloc_howto_type *howto = elf64_alpha_howto_table + r_type;
+ ((*_bfd_error_handler)
+ ("%B: %A+0x%lx: warning: %s relocation against unexpected insn",
+ info->abfd, info->sec,
+ (unsigned long) irel->r_offset, howto->name));
+ return TRUE;
+ }
+
+ /* Can't relax dynamic symbols. */
+ if (alpha_elf_dynamic_symbol_p (&info->h->root, info->link_info))
+ return TRUE;
+
+ /* Can't use local-exec relocations in shared libraries. */
+ if (r_type == R_ALPHA_GOTTPREL
+ && (info->link_info->shared && !info->link_info->pie))
+ return TRUE;
+
+ if (r_type == R_ALPHA_LITERAL)
+ {
+ /* Look for nice constant addresses. This includes the not-uncommon
+ special case of 0 for undefweak symbols. */
+ if ((info->h && info->h->root.root.type == bfd_link_hash_undefweak)
+ || (!info->link_info->shared
+ && (symval >= (bfd_vma)-0x8000 || symval < 0x8000)))
+ {
+ disp = 0;
+ insn = (OP_LDA << 26) | (insn & (31 << 21)) | (31 << 16);
+ insn |= (symval & 0xffff);
+ r_type = R_ALPHA_NONE;
+ }
+ else
+ {
+ /* We may only create GPREL relocs during the second pass. */
+ if (info->link_info->relax_pass == 0)
+ return TRUE;
+
+ disp = symval - info->gp;
+ insn = (OP_LDA << 26) | (insn & 0x03ff0000);
+ r_type = R_ALPHA_GPREL16;
+ }
+ }
+ else
+ {
+ bfd_vma dtp_base, tp_base;
+
+ BFD_ASSERT (elf_hash_table (info->link_info)->tls_sec != NULL);
+ dtp_base = alpha_get_dtprel_base (info->link_info);
+ tp_base = alpha_get_tprel_base (info->link_info);
+ disp = symval - (r_type == R_ALPHA_GOTDTPREL ? dtp_base : tp_base);
+
+ insn = (OP_LDA << 26) | (insn & (31 << 21)) | (31 << 16);
+
+ switch (r_type)
+ {
+ case R_ALPHA_GOTDTPREL:
+ r_type = R_ALPHA_DTPREL16;
+ break;
+ case R_ALPHA_GOTTPREL:
+ r_type = R_ALPHA_TPREL16;
+ break;
+ default:
+ BFD_ASSERT (0);
+ return FALSE;
+ }
+ }
+
+ if (disp < -0x8000 || disp >= 0x8000)
+ return TRUE;
+
+ bfd_put_32 (info->abfd, (bfd_vma) insn, info->contents + irel->r_offset);
+ info->changed_contents = TRUE;
+
+ /* Reduce the use count on this got entry by one, possibly
+ eliminating it. */
+ if (--info->gotent->use_count == 0)
+ {
+ int sz = alpha_got_entry_size (r_type);
+ alpha_elf_tdata (info->gotobj)->total_got_size -= sz;
+ if (!info->h)
+ alpha_elf_tdata (info->gotobj)->local_got_size -= sz;
+ }
+
+ /* Smash the existing GOT relocation for its 16-bit immediate pair. */
+ irel->r_info = ELF64_R_INFO (ELF64_R_SYM (irel->r_info), r_type);
+ info->changed_relocs = TRUE;
+
+ /* ??? 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 bfd_vma
+elf64_alpha_relax_opt_call (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_STD_GPLOAD) == 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) == 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_elf_link_read_relocs
+ (info->abfd, info->tsec, 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->output_bfd->xvec != info->tsec->owner->xvec
+ || info->gotobj != alpha_elf_tdata (info->tsec->owner)->gotobj)
+ return 0;
+
+ return symval + 8;
+}
+
+static bfd_boolean
+elf64_alpha_relax_with_lituse (struct alpha_relax_info *info,
+ bfd_vma symval, Elf_Internal_Rela *irel)
+{
+ Elf_Internal_Rela *urel, *erel, *irelend = info->relend;
+ int flags;
+ bfd_signed_vma disp;
+ bfd_boolean fits16;
+ bfd_boolean fits32;
+ bfd_boolean lit_reused = FALSE;
+ bfd_boolean all_optimized = TRUE;
+ bfd_boolean changed_contents;
+ bfd_boolean changed_relocs;
+ bfd_byte *contents = info->contents;
+ bfd *abfd = info->abfd;
+ bfd_vma sec_output_vma;
+ unsigned int lit_insn;
+ int relax_pass;
+
+ lit_insn = bfd_get_32 (abfd, contents + irel->r_offset);
+ if (lit_insn >> 26 != OP_LDQ)
+ {
+ ((*_bfd_error_handler)
+ ("%B: %A+0x%lx: warning: LITERAL relocation against unexpected insn",
+ abfd, info->sec,
+ (unsigned long) irel->r_offset));
+ return TRUE;
+ }
+
+ /* Can't relax dynamic symbols. */
+ if (alpha_elf_dynamic_symbol_p (&info->h->root, info->link_info))
+ return TRUE;
+
+ changed_contents = info->changed_contents;
+ changed_relocs = info->changed_relocs;
+ sec_output_vma = info->sec->output_section->vma + info->sec->output_offset;
+ relax_pass = info->link_info->relax_pass;
+
+ /* Summarize how this particular LITERAL is used. */
+ for (erel = irel+1, flags = 0; erel < irelend; ++erel)
+ {
+ if (ELF64_R_TYPE (erel->r_info) != R_ALPHA_LITUSE)
+ break;
+ if (erel->r_addend <= 6)
+ flags |= 1 << erel->r_addend;
+ }
+
+ /* A little preparation for the loop... */
+ disp = symval - info->gp;
+
+ for (urel = irel+1; urel < erel; ++urel)
+ {
+ bfd_vma urel_r_offset = urel->r_offset;
+ unsigned int insn;
+ int insn_disp;
+ bfd_signed_vma xdisp;
+ Elf_Internal_Rela nrel;
+
+ insn = bfd_get_32 (abfd, contents + urel_r_offset);
+
+ switch (urel->r_addend)
+ {
+ case LITUSE_ALPHA_ADDR:
+ default:
+ /* 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 LITUSE_ALPHA_BASE:
+ /* We may only create GPREL relocs during the second pass. */
+ if (relax_pass == 0)
+ {
+ all_optimized = FALSE;
+ break;
+ }
+
+ /* We can always optimize 16-bit displacements. */
+
+ /* Extract the displacement from the instruction, sign-extending
+ it if necessary, then test whether it is within 16 or 32 bits
+ displacement from GP. */
+ insn_disp = ((insn & 0xffff) ^ 0x8000) - 0x8000;
+
+ xdisp = disp + insn_disp;
+ fits16 = (xdisp >= - (bfd_signed_vma) 0x8000 && xdisp < 0x8000);
+ fits32 = (xdisp >= - (bfd_signed_vma) 0x80000000
+ && xdisp < 0x7fff8000);
+
+ if (fits16)
+ {
+ /* Take the op code and dest from this insn, take the base
+ register from the literal insn. Leave the offset alone. */
+ insn = (insn & 0xffe0ffff) | (lit_insn & 0x001f0000);
+ bfd_put_32 (abfd, (bfd_vma) insn, contents + urel_r_offset);
+ changed_contents = TRUE;
+
+ nrel = *urel;
+ nrel.r_info = ELF64_R_INFO (ELF64_R_SYM (irel->r_info),
+ R_ALPHA_GPREL16);
+ nrel.r_addend = irel->r_addend;
+
+ /* As we adjust, move the reloc to the end so that we don't
+ break the LITERAL+LITUSE chain. */
+ if (urel < --erel)
+ *urel-- = *erel;
+ *erel = nrel;
+ changed_relocs = 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. */
+
+ 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 (abfd, (bfd_vma) lit_insn, contents + irel->r_offset);
+ lit_reused = TRUE;
+ changed_contents = TRUE;
+
+ /* Since all relocs must be optimized, don't bother swapping
+ this relocation to the end. */
+ urel->r_info = ELF64_R_INFO (ELF64_R_SYM (irel->r_info),
+ R_ALPHA_GPRELLOW);
+ urel->r_addend = irel->r_addend;
+ changed_relocs = TRUE;
+ }
+ else
+ all_optimized = FALSE;
+ break;
+
+ case LITUSE_ALPHA_BYTOFF:
+ /* 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 &= ~ (unsigned) 0x001ff000;
+ insn |= ((symval & 7) << 13) | 0x1000;
+ bfd_put_32 (abfd, (bfd_vma) insn, contents + urel_r_offset);
+ changed_contents = TRUE;
+
+ nrel = *urel;
+ nrel.r_info = ELF64_R_INFO (0, R_ALPHA_NONE);
+ nrel.r_addend = 0;
+
+ /* As we adjust, move the reloc to the end so that we don't
+ break the LITERAL+LITUSE chain. */
+ if (urel < --erel)
+ *urel-- = *erel;
+ *erel = nrel;
+ changed_relocs = TRUE;
+ break;
+
+ case LITUSE_ALPHA_JSR:
+ case LITUSE_ALPHA_TLSGD:
+ case LITUSE_ALPHA_TLSLDM:
+ case LITUSE_ALPHA_JSRDIRECT:
+ {
+ bfd_vma optdest, org;
+ bfd_signed_vma odisp;
+
+ /* For undefined weak symbols, we're mostly interested in getting
+ rid of the got entry whenever possible, so optimize this to a
+ use of the zero register. */
+ if (info->h && info->h->root.root.type == bfd_link_hash_undefweak)
+ {
+ insn |= 31 << 16;
+ bfd_put_32 (abfd, (bfd_vma) insn, contents + urel_r_offset);
+
+ changed_contents = TRUE;
+ break;
+ }
+
+ /* If not zero, place to jump without needing pv. */
+ optdest = elf64_alpha_relax_opt_call (info, symval);
+ org = sec_output_vma + urel_r_offset + 4;
+ 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);
+ bfd_put_32 (abfd, (bfd_vma) insn, contents + urel_r_offset);
+ changed_contents = TRUE;
+
+ nrel = *urel;
+ nrel.r_info = ELF64_R_INFO (ELF64_R_SYM (irel->r_info),
+ R_ALPHA_BRADDR);
+ nrel.r_addend = irel->r_addend;
+
+ if (optdest)
+ nrel.r_addend += optdest - symval;
+ else
+ all_optimized = FALSE;
+
+ /* 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);
+
+ /* As we adjust, move the reloc to the end so that we don't
+ break the LITERAL+LITUSE chain. */
+ if (urel < --erel)
+ *urel-- = *erel;
+ *erel = nrel;
+
+ info->changed_relocs = TRUE;
+ }
+ else
+ all_optimized = FALSE;
+
+ /* Even if the target is not in range for a direct branch,
+ if we share a GP, we can eliminate the gp reload. */
+ if (optdest)
+ {
+ Elf_Internal_Rela *gpdisp
+ = (elf64_alpha_find_reloc_at_ofs
+ (info->relocs, irelend, urel_r_offset + 4,
+ R_ALPHA_GPDISP));
+ if (gpdisp)
+ {
+ bfd_byte *p_ldah = contents + gpdisp->r_offset;
+ bfd_byte *p_lda = p_ldah + gpdisp->r_addend;
+ unsigned int ldah = bfd_get_32 (abfd, p_ldah);
+ unsigned int lda = bfd_get_32 (abfd, p_lda);
+
+ /* Verify that the instruction is "ldah $29,0($26)".
+ Consider a function that ends in a noreturn call,
+ and that the next function begins with an ldgp,
+ and that by accident there is no padding between.
+ In that case the insn would use $27 as the base. */
+ if (ldah == 0x27ba0000 && lda == 0x23bd0000)
+ {
+ bfd_put_32 (abfd, (bfd_vma) INSN_UNOP, p_ldah);
+ bfd_put_32 (abfd, (bfd_vma) INSN_UNOP, p_lda);
+
+ gpdisp->r_info = ELF64_R_INFO (0, R_ALPHA_NONE);
+ changed_contents = TRUE;
+ changed_relocs = TRUE;
+ }
+ }
+ }
+ }
+ break;
+ }
+ }
+
+ /* If we reused the literal instruction, we must have optimized all. */
+ BFD_ASSERT(!lit_reused || all_optimized);
+
+ /* If all cases were optimized, we can reduce the use count on this
+ got entry by one, possibly eliminating it. */
+ if (all_optimized)
+ {
+ if (--info->gotent->use_count == 0)
+ {
+ int sz = alpha_got_entry_size (R_ALPHA_LITERAL);
+ alpha_elf_tdata (info->gotobj)->total_got_size -= sz;
+ if (!info->h)
+ alpha_elf_tdata (info->gotobj)->local_got_size -= sz;
+ }
+
+ /* 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);
+ changed_relocs = TRUE;
+
+ bfd_put_32 (abfd, (bfd_vma) INSN_UNOP, contents + irel->r_offset);
+ changed_contents = TRUE;
+ }
+ }
+
+ info->changed_contents = changed_contents;
+ info->changed_relocs = changed_relocs;
+
+ if (all_optimized || relax_pass == 0)
+ return TRUE;
+ return elf64_alpha_relax_got_load (info, symval, irel, R_ALPHA_LITERAL);
+}
+
+static bfd_boolean
+elf64_alpha_relax_tls_get_addr (struct alpha_relax_info *info, bfd_vma symval,
+ Elf_Internal_Rela *irel, bfd_boolean is_gd)
+{
+ bfd_byte *pos[5];
+ unsigned int insn, tlsgd_reg;
+ Elf_Internal_Rela *gpdisp, *hint;
+ bfd_boolean dynamic, use_gottprel;
+ unsigned long new_symndx;
+
+ dynamic = alpha_elf_dynamic_symbol_p (&info->h->root, info->link_info);
+
+ /* If a TLS symbol is accessed using IE at least once, there is no point
+ to use dynamic model for it. */
+ if (is_gd && info->h && (info->h->flags & ALPHA_ELF_LINK_HASH_TLS_IE))
+ ;
+
+ /* If the symbol is local, and we've already committed to DF_STATIC_TLS,
+ then we might as well relax to IE. */
+ else if (info->link_info->shared && !dynamic
+ && (info->link_info->flags & DF_STATIC_TLS))
+ ;
+
+ /* Otherwise we must be building an executable to do anything. */
+ else if (info->link_info->shared)
+ return TRUE;
+
+ /* The TLSGD/TLSLDM relocation must be followed by a LITERAL and
+ the matching LITUSE_TLS relocations. */
+ if (irel + 2 >= info->relend)
+ return TRUE;
+ if (ELF64_R_TYPE (irel[1].r_info) != R_ALPHA_LITERAL
+ || ELF64_R_TYPE (irel[2].r_info) != R_ALPHA_LITUSE
+ || irel[2].r_addend != (is_gd ? LITUSE_ALPHA_TLSGD : LITUSE_ALPHA_TLSLDM))
+ return TRUE;
+
+ /* There must be a GPDISP relocation positioned immediately after the
+ LITUSE relocation. */
+ gpdisp = elf64_alpha_find_reloc_at_ofs (info->relocs, info->relend,
+ irel[2].r_offset + 4, R_ALPHA_GPDISP);
+ if (!gpdisp)
+ return TRUE;
+
+ pos[0] = info->contents + irel[0].r_offset;
+ pos[1] = info->contents + irel[1].r_offset;
+ pos[2] = info->contents + irel[2].r_offset;
+ pos[3] = info->contents + gpdisp->r_offset;
+ pos[4] = pos[3] + gpdisp->r_addend;
+
+ /* Beware of the compiler hoisting part of the sequence out a loop
+ and adjusting the destination register for the TLSGD insn. If this
+ happens, there will be a move into $16 before the JSR insn, so only
+ transformations of the first insn pair should use this register. */
+ tlsgd_reg = bfd_get_32 (info->abfd, pos[0]);
+ tlsgd_reg = (tlsgd_reg >> 21) & 31;
+
+ /* Generally, the positions are not allowed to be out of order, lest the
+ modified insn sequence have different register lifetimes. We can make
+ an exception when pos 1 is adjacent to pos 0. */
+ if (pos[1] + 4 == pos[0])
+ {
+ bfd_byte *tmp = pos[0];
+ pos[0] = pos[1];
+ pos[1] = tmp;
+ }
+ if (pos[1] >= pos[2] || pos[2] >= pos[3])
+ return TRUE;
+
+ /* Reduce the use count on the LITERAL relocation. Do this before we
+ smash the symndx when we adjust the relocations below. */
+ {
+ struct alpha_elf_got_entry *lit_gotent;
+ struct alpha_elf_link_hash_entry *lit_h;
+ unsigned long indx;
+
+ BFD_ASSERT (ELF64_R_SYM (irel[1].r_info) >= info->symtab_hdr->sh_info);
+ indx = ELF64_R_SYM (irel[1].r_info) - info->symtab_hdr->sh_info;
+ lit_h = alpha_elf_sym_hashes (info->abfd)[indx];
+
+ while (lit_h->root.root.type == bfd_link_hash_indirect
+ || lit_h->root.root.type == bfd_link_hash_warning)
+ lit_h = (struct alpha_elf_link_hash_entry *) lit_h->root.root.u.i.link;
+
+ for (lit_gotent = lit_h->got_entries; lit_gotent ;
+ lit_gotent = lit_gotent->next)
+ if (lit_gotent->gotobj == info->gotobj
+ && lit_gotent->reloc_type == R_ALPHA_LITERAL
+ && lit_gotent->addend == irel[1].r_addend)
+ break;
+ BFD_ASSERT (lit_gotent);
+
+ if (--lit_gotent->use_count == 0)
+ {
+ int sz = alpha_got_entry_size (R_ALPHA_LITERAL);
+ alpha_elf_tdata (info->gotobj)->total_got_size -= sz;
+ }
+ }
+
+ /* Change
+
+ lda $16,x($gp) !tlsgd!1
+ ldq $27,__tls_get_addr($gp) !literal!1
+ jsr $26,($27),__tls_get_addr !lituse_tlsgd!1
+ ldah $29,0($26) !gpdisp!2
+ lda $29,0($29) !gpdisp!2
+ to
+ ldq $16,x($gp) !gottprel
+ unop
+ call_pal rduniq
+ addq $16,$0,$0
+ unop
+ or the first pair to
+ lda $16,x($gp) !tprel
+ unop
+ or
+ ldah $16,x($gp) !tprelhi
+ lda $16,x($16) !tprello
+
+ as appropriate. */
+
+ use_gottprel = FALSE;
+ new_symndx = is_gd ? ELF64_R_SYM (irel->r_info) : STN_UNDEF;
+
+ /* Some compilers warn about a Boolean-looking expression being
+ used in a switch. The explicit cast silences them. */
+ switch ((int) (!dynamic && !info->link_info->shared))
+ {
+ case 1:
+ {
+ bfd_vma tp_base;
+ bfd_signed_vma disp;
+
+ BFD_ASSERT (elf_hash_table (info->link_info)->tls_sec != NULL);
+ tp_base = alpha_get_tprel_base (info->link_info);
+ disp = symval - tp_base;
+
+ if (disp >= -0x8000 && disp < 0x8000)
+ {
+ insn = (OP_LDA << 26) | (tlsgd_reg << 21) | (31 << 16);
+ bfd_put_32 (info->abfd, (bfd_vma) insn, pos[0]);
+ bfd_put_32 (info->abfd, (bfd_vma) INSN_UNOP, pos[1]);
+
+ irel[0].r_offset = pos[0] - info->contents;
+ irel[0].r_info = ELF64_R_INFO (new_symndx, R_ALPHA_TPREL16);
+ irel[1].r_info = ELF64_R_INFO (0, R_ALPHA_NONE);
+ break;
+ }
+ else if (disp >= -(bfd_signed_vma) 0x80000000
+ && disp < (bfd_signed_vma) 0x7fff8000
+ && pos[0] + 4 == pos[1])
+ {
+ insn = (OP_LDAH << 26) | (tlsgd_reg << 21) | (31 << 16);
+ bfd_put_32 (info->abfd, (bfd_vma) insn, pos[0]);
+ insn = (OP_LDA << 26) | (tlsgd_reg << 21) | (tlsgd_reg << 16);
+ bfd_put_32 (info->abfd, (bfd_vma) insn, pos[1]);
+
+ irel[0].r_offset = pos[0] - info->contents;
+ irel[0].r_info = ELF64_R_INFO (new_symndx, R_ALPHA_TPRELHI);
+ irel[1].r_offset = pos[1] - info->contents;
+ irel[1].r_info = ELF64_R_INFO (new_symndx, R_ALPHA_TPRELLO);
+ break;
+ }
+ }
+ /* FALLTHRU */
+
+ default:
+ use_gottprel = TRUE;
+
+ insn = (OP_LDQ << 26) | (tlsgd_reg << 21) | (29 << 16);
+ bfd_put_32 (info->abfd, (bfd_vma) insn, pos[0]);
+ bfd_put_32 (info->abfd, (bfd_vma) INSN_UNOP, pos[1]);
+
+ irel[0].r_offset = pos[0] - info->contents;
+ irel[0].r_info = ELF64_R_INFO (new_symndx, R_ALPHA_GOTTPREL);
+ irel[1].r_info = ELF64_R_INFO (0, R_ALPHA_NONE);
+ break;
+ }
+
+ bfd_put_32 (info->abfd, (bfd_vma) INSN_RDUNIQ, pos[2]);
+
+ insn = INSN_ADDQ | (16 << 21) | (0 << 16) | (0 << 0);
+ bfd_put_32 (info->abfd, (bfd_vma) insn, pos[3]);
+
+ bfd_put_32 (info->abfd, (bfd_vma) INSN_UNOP, pos[4]);
+
+ irel[2].r_info = ELF64_R_INFO (0, R_ALPHA_NONE);
+ gpdisp->r_info = ELF64_R_INFO (0, R_ALPHA_NONE);
+
+ hint = elf64_alpha_find_reloc_at_ofs (info->relocs, info->relend,
+ irel[2].r_offset, R_ALPHA_HINT);
+ if (hint)
+ hint->r_info = ELF64_R_INFO (0, R_ALPHA_NONE);
+
+ info->changed_contents = TRUE;
+ info->changed_relocs = TRUE;
+
+ /* Reduce the use count on the TLSGD/TLSLDM relocation. */
+ if (--info->gotent->use_count == 0)
+ {
+ int sz = alpha_got_entry_size (info->gotent->reloc_type);
+ alpha_elf_tdata (info->gotobj)->total_got_size -= sz;
+ if (!info->h)
+ alpha_elf_tdata (info->gotobj)->local_got_size -= sz;
+ }
+
+ /* If we've switched to a GOTTPREL relocation, increment the reference
+ count on that got entry. */
+ if (use_gottprel)
+ {
+ struct alpha_elf_got_entry *tprel_gotent;
+
+ for (tprel_gotent = *info->first_gotent; tprel_gotent ;
+ tprel_gotent = tprel_gotent->next)
+ if (tprel_gotent->gotobj == info->gotobj
+ && tprel_gotent->reloc_type == R_ALPHA_GOTTPREL
+ && tprel_gotent->addend == irel->r_addend)
+ break;
+ if (tprel_gotent)
+ tprel_gotent->use_count++;
+ else
+ {
+ if (info->gotent->use_count == 0)
+ tprel_gotent = info->gotent;
+ else
+ {
+ tprel_gotent = (struct alpha_elf_got_entry *)
+ bfd_alloc (info->abfd, sizeof (struct alpha_elf_got_entry));
+ if (!tprel_gotent)
+ return FALSE;
+
+ tprel_gotent->next = *info->first_gotent;
+ *info->first_gotent = tprel_gotent;
+
+ tprel_gotent->gotobj = info->gotobj;
+ tprel_gotent->addend = irel->r_addend;
+ tprel_gotent->got_offset = -1;
+ tprel_gotent->reloc_done = 0;
+ tprel_gotent->reloc_xlated = 0;
+ }
+
+ tprel_gotent->use_count = 1;
+ tprel_gotent->reloc_type = R_ALPHA_GOTTPREL;
+ }
+ }
+
+ return TRUE;
+}
+
+static bfd_boolean
+elf64_alpha_relax_section (bfd *abfd, asection *sec,
+ struct bfd_link_info *link_info, bfd_boolean *again)
+{
+ Elf_Internal_Shdr *symtab_hdr;
+ Elf_Internal_Rela *internal_relocs;
+ Elf_Internal_Rela *irel, *irelend;
+ Elf_Internal_Sym *isymbuf = NULL;
+ struct alpha_elf_got_entry **local_got_entries;
+ struct alpha_relax_info info;
+ struct alpha_elf_link_hash_table * htab;
+ int relax_pass;
+
+ htab = alpha_elf_hash_table (link_info);
+ if (htab == NULL)
+ return FALSE;
+
+ /* There's nothing to change, yet. */
+ *again = FALSE;
+
+ if (link_info->relocatable
+ || ((sec->flags & (SEC_CODE | SEC_RELOC | SEC_ALLOC))
+ != (SEC_CODE | SEC_RELOC | SEC_ALLOC))
+ || sec->reloc_count == 0)
+ return TRUE;
+
+ BFD_ASSERT (is_alpha_elf (abfd));
+ relax_pass = link_info->relax_pass;
+
+ /* Make sure our GOT and PLT tables are up-to-date. */
+ if (htab->relax_trip != link_info->relax_trip)
+ {
+ htab->relax_trip = link_info->relax_trip;
+
+ /* This should never fail after the initial round, since the only error
+ is GOT overflow, and relaxation only shrinks the table. However, we
+ may only merge got sections during the first pass. If we merge
+ sections after we've created GPREL relocs, the GP for the merged
+ section backs up which may put the relocs out of range. */
+ if (!elf64_alpha_size_got_sections (link_info, relax_pass == 0))
+ abort ();
+ if (elf_hash_table (link_info)->dynamic_sections_created)
+ {
+ elf64_alpha_size_plt_section (link_info);
+ elf64_alpha_size_rela_got_section (link_info);
+ }
+ }
+
+ symtab_hdr = &elf_symtab_hdr (abfd);
+ local_got_entries = alpha_elf_tdata(abfd)->local_got_entries;
+
+ /* Load the relocations for this section. */
+ internal_relocs = (_bfd_elf_link_read_relocs
+ (abfd, sec, NULL, (Elf_Internal_Rela *) NULL,
+ link_info->keep_memory));
+ if (internal_relocs == NULL)
+ return FALSE;
+
+ memset(&info, 0, sizeof (info));
+ info.abfd = abfd;
+ info.sec = sec;
+ info.link_info = link_info;
+ info.symtab_hdr = symtab_hdr;
+ info.relocs = internal_relocs;
+ info.relend = irelend = internal_relocs + sec->reloc_count;
+
+ /* Find the GP for this object. Do not store the result back via
+ _bfd_set_gp_value, since this could change again before final. */
+ info.gotobj = alpha_elf_tdata (abfd)->gotobj;
+ if (info.gotobj)
+ {
+ asection *sgot = alpha_elf_tdata (info.gotobj)->got;
+ info.gp = (sgot->output_section->vma
+ + sgot->output_offset
+ + 0x8000);
+ }
+
+ /* Get the section contents. */
+ if (elf_section_data (sec)->this_hdr.contents != NULL)
+ info.contents = elf_section_data (sec)->this_hdr.contents;
+ else
+ {
+ if (!bfd_malloc_and_get_section (abfd, sec, &info.contents))
+ goto error_return;
+ }
+
+ for (irel = internal_relocs; irel < irelend; irel++)
+ {
+ bfd_vma symval;
+ struct alpha_elf_got_entry *gotent;
+ unsigned long r_type = ELF64_R_TYPE (irel->r_info);
+ unsigned long r_symndx = ELF64_R_SYM (irel->r_info);
+
+ /* Early exit for unhandled or unrelaxable relocations. */
+ if (r_type != R_ALPHA_LITERAL)
+ {
+ /* We complete everything except LITERAL in the first pass. */
+ if (relax_pass != 0)
+ continue;
+ if (r_type == R_ALPHA_TLSLDM)
+ {
+ /* The symbol for a TLSLDM reloc is ignored. Collapse the
+ reloc to the STN_UNDEF (0) symbol so that they all match. */
+ r_symndx = STN_UNDEF;
+ }
+ else if (r_type != R_ALPHA_GOTDTPREL
+ && r_type != R_ALPHA_GOTTPREL
+ && r_type != R_ALPHA_TLSGD)
+ continue;
+ }
+
+ /* Get the value of the symbol referred to by the reloc. */
+ if (r_symndx < symtab_hdr->sh_info)
+ {
+ /* A local symbol. */
+ Elf_Internal_Sym *isym;
+
+ /* Read this BFD's local symbols. */
+ if (isymbuf == NULL)
+ {
+ isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
+ if (isymbuf == NULL)
+ isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
+ symtab_hdr->sh_info, 0,
+ NULL, NULL, NULL);
+ if (isymbuf == NULL)
+ goto error_return;
+ }
+
+ isym = isymbuf + r_symndx;
+
+ /* Given the symbol for a TLSLDM reloc is ignored, this also
+ means forcing the symbol value to the tp base. */
+ if (r_type == R_ALPHA_TLSLDM)
+ {
+ info.tsec = bfd_abs_section_ptr;
+ symval = alpha_get_tprel_base (info.link_info);
+ }
+ else
+ {
+ symval = isym->st_value;
+ if (isym->st_shndx == SHN_UNDEF)
+ continue;
+ 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
+ info.tsec = bfd_section_from_elf_index (abfd, isym->st_shndx);
+ }
+
+ info.h = NULL;
+ info.other = isym->st_other;
+ if (local_got_entries)
+ info.first_gotent = &local_got_entries[r_symndx];
+ else
+ {
+ info.first_gotent = &info.gotent;
+ info.gotent = NULL;
+ }
+ }
+ else
+ {
+ unsigned long indx;
+ struct alpha_elf_link_hash_entry *h;
+
+ indx = r_symndx - 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;
+
+ /* If the symbol is undefined, we can't do anything with it. */
+ if (h->root.root.type == bfd_link_hash_undefined)
+ continue;
+
+ /* If the symbol isn't defined in the current module,
+ again we can't do anything. */
+ if (h->root.root.type == bfd_link_hash_undefweak)
+ {
+ info.tsec = bfd_abs_section_ptr;
+ symval = 0;
+ }
+ else if (!h->root.def_regular)
+ {
+ /* Except for TLSGD relocs, which can sometimes be
+ relaxed to GOTTPREL relocs. */
+ if (r_type != R_ALPHA_TLSGD)
+ continue;
+ info.tsec = bfd_abs_section_ptr;
+ symval = 0;
+ }
+ else
+ {
+ info.tsec = h->root.root.u.def.section;
+ symval = h->root.root.u.def.value;
+ }
+
+ info.h = h;
+ info.other = h->root.other;
+ info.first_gotent = &h->got_entries;
+ }
+
+ /* Search for the got entry to be used by this relocation. */
+ for (gotent = *info.first_gotent; gotent ; gotent = gotent->next)
+ if (gotent->gotobj == info.gotobj
+ && gotent->reloc_type == r_type
+ && gotent->addend == irel->r_addend)
+ break;
+ info.gotent = gotent;
+
+ symval += info.tsec->output_section->vma + info.tsec->output_offset;
+ symval += irel->r_addend;
+
+ switch (r_type)
+ {
+ case R_ALPHA_LITERAL:
+ 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)
+ {
+ if (!elf64_alpha_relax_with_lituse (&info, symval, irel))
+ goto error_return;
+ }
+ else
+ {
+ if (!elf64_alpha_relax_got_load (&info, symval, irel, r_type))
+ goto error_return;
+ }
+ break;
+
+ case R_ALPHA_GOTDTPREL:
+ case R_ALPHA_GOTTPREL:
+ BFD_ASSERT(info.gotent != NULL);
+ if (!elf64_alpha_relax_got_load (&info, symval, irel, r_type))
+ goto error_return;
+ break;
+
+ case R_ALPHA_TLSGD:
+ case R_ALPHA_TLSLDM:
+ BFD_ASSERT(info.gotent != NULL);
+ if (!elf64_alpha_relax_tls_get_addr (&info, symval, irel,
+ r_type == R_ALPHA_TLSGD))
+ goto error_return;
+ break;
+ }
+ }
+
+ if (isymbuf != NULL
+ && symtab_hdr->contents != (unsigned char *) isymbuf)
+ {
+ if (!link_info->keep_memory)
+ free (isymbuf);
+ else
+ {
+ /* Cache the symbols for elf_link_input_bfd. */
+ symtab_hdr->contents = (unsigned char *) isymbuf;
+ }
+ }
+
+ if (info.contents != NULL
+ && elf_section_data (sec)->this_hdr.contents != info.contents)
+ {
+ if (!info.changed_contents && !link_info->keep_memory)
+ free (info.contents);
+ else
+ {
+ /* Cache the section contents for elf_link_input_bfd. */
+ elf_section_data (sec)->this_hdr.contents = info.contents;
+ }
+ }
+
+ if (elf_section_data (sec)->relocs != internal_relocs)
+ {
+ if (!info.changed_relocs)
+ free (internal_relocs);
+ else
+ elf_section_data (sec)->relocs = internal_relocs;
+ }
+
+ *again = info.changed_contents || info.changed_relocs;
+
+ return TRUE;
+
+ error_return:
+ if (isymbuf != NULL
+ && symtab_hdr->contents != (unsigned char *) isymbuf)
+ free (isymbuf);
+ if (info.contents != NULL
+ && elf_section_data (sec)->this_hdr.contents != info.contents)
+ free (info.contents);
+ if (internal_relocs != NULL
+ && elf_section_data (sec)->relocs != internal_relocs)
+ free (internal_relocs);
+ return FALSE;
+}
+
+/* Emit a dynamic relocation for (DYNINDX, RTYPE, ADDEND) at (SEC, OFFSET)
+ into the next available slot in SREL. */
+
+static void
+elf64_alpha_emit_dynrel (bfd *abfd, struct bfd_link_info *info,
+ asection *sec, asection *srel, bfd_vma offset,
+ long dynindx, long rtype, bfd_vma addend)
+{
+ Elf_Internal_Rela outrel;
+ bfd_byte *loc;
+
+ BFD_ASSERT (srel != NULL);
+
+ outrel.r_info = ELF64_R_INFO (dynindx, rtype);
+ outrel.r_addend = addend;
+
+ offset = _bfd_elf_section_offset (abfd, info, sec, offset);
+ if ((offset | 1) != (bfd_vma) -1)
+ outrel.r_offset = sec->output_section->vma + sec->output_offset + offset;
+ else
+ memset (&outrel, 0, sizeof (outrel));
+
+ loc = srel->contents;
+ loc += srel->reloc_count++ * sizeof (Elf64_External_Rela);
+ bfd_elf64_swap_reloca_out (abfd, &outrel, loc);
+ BFD_ASSERT (sizeof (Elf64_External_Rela) * srel->reloc_count <= srel->size);
+}
+
+/* Relocate an Alpha ELF section for a relocatable 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. */
+
+static bfd_boolean
+elf64_alpha_relocate_section_r (bfd *output_bfd ATTRIBUTE_UNUSED,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ bfd *input_bfd, asection *input_section,
+ bfd_byte *contents ATTRIBUTE_UNUSED,
+ Elf_Internal_Rela *relocs,
+ Elf_Internal_Sym *local_syms,
+ asection **local_sections)
+{
+ unsigned long symtab_hdr_sh_info;
+ Elf_Internal_Rela *rel;
+ Elf_Internal_Rela *relend;
+ struct elf_link_hash_entry **sym_hashes;
+ bfd_boolean ret_val = TRUE;
+
+ symtab_hdr_sh_info = elf_symtab_hdr (input_bfd).sh_info;
+ sym_hashes = elf_sym_hashes (input_bfd);
+
+ relend = relocs + input_section->reloc_count;
+ for (rel = relocs; rel < relend; rel++)
+ {
+ unsigned long r_symndx;
+ Elf_Internal_Sym *sym;
+ asection *sec;
+ unsigned long r_type;
+
+ r_type = ELF64_R_TYPE (rel->r_info);
+ if (r_type >= R_ALPHA_max)
+ {
+ (*_bfd_error_handler)
+ (_("%B: unknown relocation type %d"),
+ input_bfd, (int) r_type);
+ bfd_set_error (bfd_error_bad_value);
+ ret_val = FALSE;
+ continue;
+ }
+
+ /* The symbol associated with GPDISP and LITUSE is
+ immaterial. Only the addend is significant. */
+ if (r_type == R_ALPHA_GPDISP || r_type == R_ALPHA_LITUSE)
+ continue;
+
+ r_symndx = ELF64_R_SYM (rel->r_info);
+ if (r_symndx < symtab_hdr_sh_info)
+ {
+ sym = local_syms + r_symndx;
+ sec = local_sections[r_symndx];
+ }
+ else
+ {
+ struct elf_link_hash_entry *h;
+
+ 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)
+ continue;
+
+ sym = NULL;
+ sec = h->root.u.def.section;
+ }
+
+ if (sec != NULL && discarded_section (sec))
+ RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+ rel, 1, relend,
+ elf64_alpha_howto_table + r_type, 0,
+ contents);
+
+ if (sym != NULL && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
+ rel->r_addend += sec->output_offset;
+ }
+
+ return ret_val;
+}
+
+/* Relocate an Alpha ELF section. */
+
+static bfd_boolean
+elf64_alpha_relocate_section (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 *sgot, *srel, *srelgot;
+ bfd *dynobj, *gotobj;
+ bfd_vma gp, tp_base, dtp_base;
+ struct alpha_elf_got_entry **local_got_entries;
+ bfd_boolean ret_val;
+
+ BFD_ASSERT (is_alpha_elf (input_bfd));
+
+ /* Handle relocatable links with a smaller loop. */
+ if (info->relocatable)
+ return elf64_alpha_relocate_section_r (output_bfd, info, input_bfd,
+ input_section, contents, relocs,
+ local_syms, local_sections);
+
+ /* This is a final link. */
+
+ ret_val = TRUE;
+
+ symtab_hdr = &elf_symtab_hdr (input_bfd);
+
+ dynobj = elf_hash_table (info)->dynobj;
+ if (dynobj)
+ srelgot = bfd_get_linker_section (dynobj, ".rela.got");
+ else
+ srelgot = NULL;
+
+ if (input_section->flags & SEC_ALLOC)
+ {
+ const char *section_name;
+ section_name = (bfd_elf_string_from_elf_section
+ (input_bfd, elf_elfheader(input_bfd)->e_shstrndx,
+ _bfd_elf_single_rel_hdr (input_section)->sh_name));
+ BFD_ASSERT(section_name != NULL);
+ srel = bfd_get_linker_section (dynobj, section_name);
+ }
+ else
+ srel = NULL;
+
+ /* Find the gp value for this input bfd. */
+ 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);
+ }
+ }
+ else
+ {
+ sgot = NULL;
+ gp = 0;
+ }
+
+ local_got_entries = alpha_elf_tdata(input_bfd)->local_got_entries;
+
+ if (elf_hash_table (info)->tls_sec != NULL)
+ {
+ dtp_base = alpha_get_dtprel_base (info);
+ tp_base = alpha_get_tprel_base (info);
+ }
+ else
+ dtp_base = tp_base = 0;
+
+ relend = relocs + input_section->reloc_count;
+ for (rel = relocs; rel < relend; rel++)
+ {
+ struct alpha_elf_link_hash_entry *h = NULL;
+ struct alpha_elf_got_entry *gotent;
+ bfd_reloc_status_type r;
+ reloc_howto_type *howto;
+ unsigned long r_symndx;
+ Elf_Internal_Sym *sym = NULL;
+ asection *sec = NULL;
+ bfd_vma value;
+ bfd_vma addend;
+ bfd_boolean dynamic_symbol_p;
+ bfd_boolean unresolved_reloc = FALSE;
+ bfd_boolean undef_weak_ref = FALSE;
+ unsigned long r_type;
+
+ r_type = ELF64_R_TYPE(rel->r_info);
+ if (r_type >= R_ALPHA_max)
+ {
+ (*_bfd_error_handler)
+ (_("%B: unknown relocation type %d"),
+ input_bfd, (int) r_type);
+ bfd_set_error (bfd_error_bad_value);
+ ret_val = FALSE;
+ continue;
+ }
+
+ howto = elf64_alpha_howto_table + r_type;
+ r_symndx = ELF64_R_SYM(rel->r_info);
+
+ /* The symbol for a TLSLDM reloc is ignored. Collapse the
+ reloc to the STN_UNDEF (0) symbol so that they all match. */
+ if (r_type == R_ALPHA_TLSLDM)
+ r_symndx = STN_UNDEF;
+
+ if (r_symndx < symtab_hdr->sh_info)
+ {
+ asection *msec;
+ sym = local_syms + r_symndx;
+ sec = local_sections[r_symndx];
+ msec = sec;
+ value = _bfd_elf_rela_local_sym (output_bfd, sym, &msec, rel);
+
+ /* If this is a tp-relative relocation against sym STN_UNDEF (0),
+ this is hackery from relax_section. Force the value to
+ be the tls module base. */
+ if (r_symndx == STN_UNDEF
+ && (r_type == R_ALPHA_TLSLDM
+ || r_type == R_ALPHA_GOTTPREL
+ || r_type == R_ALPHA_TPREL64
+ || r_type == R_ALPHA_TPRELHI
+ || r_type == R_ALPHA_TPRELLO
+ || r_type == R_ALPHA_TPREL16))
+ value = dtp_base;
+
+ if (local_got_entries)
+ gotent = local_got_entries[r_symndx];
+ else
+ gotent = NULL;
+
+ /* Need to adjust local GOT entries' addends for SEC_MERGE
+ unless it has been done already. */
+ if ((sec->flags & SEC_MERGE)
+ && ELF_ST_TYPE (sym->st_info) == STT_SECTION
+ && sec->sec_info_type == SEC_INFO_TYPE_MERGE
+ && gotent
+ && !gotent->reloc_xlated)
+ {
+ struct alpha_elf_got_entry *ent;
+
+ for (ent = gotent; ent; ent = ent->next)
+ {
+ ent->reloc_xlated = 1;
+ if (ent->use_count == 0)
+ continue;
+ msec = sec;
+ ent->addend =
+ _bfd_merged_section_offset (output_bfd, &msec,
+ elf_section_data (sec)->
+ sec_info,
+ sym->st_value + ent->addend);
+ ent->addend -= sym->st_value;
+ ent->addend += msec->output_section->vma
+ + msec->output_offset
+ - sec->output_section->vma
+ - sec->output_offset;
+ }
+ }
+
+ dynamic_symbol_p = FALSE;
+ }
+ else
+ {
+ bfd_boolean warned, ignored;
+ struct elf_link_hash_entry *hh;
+ struct elf_link_hash_entry **sym_hashes = elf_sym_hashes (input_bfd);
+
+ RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
+ r_symndx, symtab_hdr, sym_hashes,
+ hh, sec, value,
+ unresolved_reloc, warned, ignored);
+
+ if (warned)
+ continue;
+
+ if (value == 0
+ && ! unresolved_reloc
+ && hh->root.type == bfd_link_hash_undefweak)
+ undef_weak_ref = TRUE;
+
+ h = (struct alpha_elf_link_hash_entry *) hh;
+ dynamic_symbol_p = alpha_elf_dynamic_symbol_p (&h->root, info);
+ gotent = h->got_entries;
+ }
+
+ if (sec != NULL && discarded_section (sec))
+ RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+ rel, 1, relend, howto, 0, contents);
+
+ addend = rel->r_addend;
+ value += addend;
+
+ /* Search for the proper got entry. */
+ for (; gotent ; gotent = gotent->next)
+ if (gotent->gotobj == gotobj
+ && gotent->reloc_type == r_type
+ && gotent->addend == addend)
+ break;
+
+ switch (r_type)
+ {
+ case R_ALPHA_GPDISP:
+ {
+ bfd_byte *p_ldah, *p_lda;
+
+ BFD_ASSERT(gp != 0);
+
+ value = (input_section->output_section->vma
+ + input_section->output_offset
+ + rel->r_offset);
+
+ p_ldah = contents + rel->r_offset;
+ p_lda = p_ldah + rel->r_addend;
+
+ r = elf64_alpha_do_reloc_gpdisp (input_bfd, gp - value,
+ p_ldah, p_lda);
+ }
+ break;
+
+ case R_ALPHA_LITERAL:
+ BFD_ASSERT(sgot != NULL);
+ BFD_ASSERT(gp != 0);
+ BFD_ASSERT(gotent != NULL);
+ BFD_ASSERT(gotent->use_count >= 1);
+
+ if (!gotent->reloc_done)
+ {
+ gotent->reloc_done = 1;
+
+ bfd_put_64 (output_bfd, value,
+ 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_p && !undef_weak_ref)
+ elf64_alpha_emit_dynrel (output_bfd, info, sgot, srelgot,
+ gotent->got_offset, 0,
+ R_ALPHA_RELATIVE, value);
+ }
+
+ value = (sgot->output_section->vma
+ + sgot->output_offset
+ + gotent->got_offset);
+ value -= gp;
+ goto default_reloc;
+
+ case R_ALPHA_GPREL32:
+ case R_ALPHA_GPREL16:
+ case R_ALPHA_GPRELLOW:
+ if (dynamic_symbol_p)
+ {
+ (*_bfd_error_handler)
+ (_("%B: gp-relative relocation against dynamic symbol %s"),
+ input_bfd, h->root.root.root.string);
+ ret_val = FALSE;
+ }
+ BFD_ASSERT(gp != 0);
+ value -= gp;
+ goto default_reloc;
+
+ case R_ALPHA_GPRELHIGH:
+ if (dynamic_symbol_p)
+ {
+ (*_bfd_error_handler)
+ (_("%B: gp-relative relocation against dynamic symbol %s"),
+ input_bfd, h->root.root.root.string);
+ ret_val = FALSE;
+ }
+ BFD_ASSERT(gp != 0);
+ value -= gp;
+ value = ((bfd_signed_vma) value >> 16) + ((value >> 15) & 1);
+ goto default_reloc;
+
+ case R_ALPHA_HINT:
+ /* A call to a dynamic symbol is definitely out of range of
+ the 16-bit displacement. Don't bother writing anything. */
+ if (dynamic_symbol_p)
+ {
+ r = bfd_reloc_ok;
+ break;
+ }
+ /* The regular PC-relative stuff measures from the start of
+ the instruction rather than the end. */
+ value -= 4;
+ goto default_reloc;
+
+ case R_ALPHA_BRADDR:
+ if (dynamic_symbol_p)
+ {
+ (*_bfd_error_handler)
+ (_("%B: pc-relative relocation against dynamic symbol %s"),
+ input_bfd, h->root.root.root.string);
+ ret_val = FALSE;
+ }
+ /* The regular PC-relative stuff measures from the start of
+ the instruction rather than the end. */
+ value -= 4;
+ goto default_reloc;
+
+ case R_ALPHA_BRSGP:
+ {
+ int other;
+ const char *name;
+
+ /* The regular PC-relative stuff measures from the start of
+ the instruction rather than the end. */
+ value -= 4;
+
+ /* The source and destination gp must be the same. Note that
+ the source will always have an assigned gp, since we forced
+ one in check_relocs, but that the destination may not, as
+ it might not have had any relocations at all. Also take
+ care not to crash if H is an undefined symbol. */
+ if (h != NULL && sec != NULL
+ && alpha_elf_tdata (sec->owner)->gotobj
+ && gotobj != alpha_elf_tdata (sec->owner)->gotobj)
+ {
+ (*_bfd_error_handler)
+ (_("%B: change in gp: BRSGP %s"),
+ input_bfd, h->root.root.root.string);
+ ret_val = FALSE;
+ }
+
+ /* The symbol should be marked either NOPV or STD_GPLOAD. */
+ if (h != NULL)
+ other = h->root.other;
+ else
+ other = sym->st_other;
+ switch (other & STO_ALPHA_STD_GPLOAD)
+ {
+ case STO_ALPHA_NOPV:
+ break;
+ case STO_ALPHA_STD_GPLOAD:
+ value += 8;
+ break;
+ default:
+ 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 = _("<unknown>");
+ else if (name[0] == 0)
+ name = bfd_section_name (input_bfd, sec);
+ }
+ (*_bfd_error_handler)
+ (_("%B: !samegp reloc against symbol without .prologue: %s"),
+ input_bfd, name);
+ ret_val = FALSE;
+ break;
+ }
+
+ goto default_reloc;
+ }
+
+ case R_ALPHA_REFLONG:
+ case R_ALPHA_REFQUAD:
+ case R_ALPHA_DTPREL64:
+ case R_ALPHA_TPREL64:
+ {
+ long dynindx, dyntype = r_type;
+ bfd_vma dynaddend;
+
+ /* Careful here to remember RELATIVE relocations for global
+ variables for symbolic shared objects. */
+
+ if (dynamic_symbol_p)
+ {
+ BFD_ASSERT(h->root.dynindx != -1);
+ dynindx = h->root.dynindx;
+ dynaddend = addend;
+ addend = 0, value = 0;
+ }
+ else if (r_type == R_ALPHA_DTPREL64)
+ {
+ BFD_ASSERT (elf_hash_table (info)->tls_sec != NULL);
+ value -= dtp_base;
+ goto default_reloc;
+ }
+ else if (r_type == R_ALPHA_TPREL64)
+ {
+ BFD_ASSERT (elf_hash_table (info)->tls_sec != NULL);
+ if (!info->shared || info->pie)
+ {
+ value -= tp_base;
+ goto default_reloc;
+ }
+ dynindx = 0;
+ dynaddend = value - dtp_base;
+ }
+ else if (info->shared
+ && r_symndx != STN_UNDEF
+ && (input_section->flags & SEC_ALLOC)
+ && !undef_weak_ref
+ && !(unresolved_reloc
+ && (_bfd_elf_section_offset (output_bfd, info,
+ input_section,
+ rel->r_offset)
+ == (bfd_vma) -1)))
+ {
+ if (r_type == R_ALPHA_REFLONG)
+ {
+ (*_bfd_error_handler)
+ (_("%B: unhandled dynamic relocation against %s"),
+ input_bfd,
+ h->root.root.root.string);
+ ret_val = FALSE;
+ }
+ dynindx = 0;
+ dyntype = R_ALPHA_RELATIVE;
+ dynaddend = value;
+ }
+ else
+ goto default_reloc;
+
+ if (input_section->flags & SEC_ALLOC)
+ elf64_alpha_emit_dynrel (output_bfd, info, input_section,
+ srel, rel->r_offset, dynindx,
+ dyntype, dynaddend);
+ }
+ goto default_reloc;
+
+ case R_ALPHA_SREL16:
+ case R_ALPHA_SREL32:
+ case R_ALPHA_SREL64:
+ if (dynamic_symbol_p)
+ {
+ (*_bfd_error_handler)
+ (_("%B: pc-relative relocation against dynamic symbol %s"),
+ input_bfd, h->root.root.root.string);
+ ret_val = FALSE;
+ }
+ else if ((info->shared || info->pie) && undef_weak_ref)
+ {
+ (*_bfd_error_handler)
+ (_("%B: pc-relative relocation against undefined weak symbol %s"),
+ input_bfd, h->root.root.root.string);
+ ret_val = FALSE;
+ }
+
+
+ /* ??? .eh_frame references to discarded sections will be smashed
+ to relocations against SHN_UNDEF. The .eh_frame format allows
+ NULL to be encoded as 0 in any format, so this works here. */
+ if (r_symndx == STN_UNDEF
+ || (unresolved_reloc
+ && _bfd_elf_section_offset (output_bfd, info,
+ input_section,
+ rel->r_offset) == (bfd_vma) -1))
+ howto = (elf64_alpha_howto_table
+ + (r_type - R_ALPHA_SREL32 + R_ALPHA_REFLONG));
+ goto default_reloc;
+
+ case R_ALPHA_TLSLDM:
+ /* Ignore the symbol for the relocation. The result is always
+ the current module. */
+ dynamic_symbol_p = 0;
+ /* FALLTHRU */
+
+ case R_ALPHA_TLSGD:
+ if (!gotent->reloc_done)
+ {
+ gotent->reloc_done = 1;
+
+ /* Note that the module index for the main program is 1. */
+ bfd_put_64 (output_bfd, !info->shared && !dynamic_symbol_p,
+ sgot->contents + gotent->got_offset);
+
+ /* If the symbol has been forced local, output a
+ DTPMOD64 reloc, otherwise it will be handled in
+ finish_dynamic_symbol. */
+ if (info->shared && !dynamic_symbol_p)
+ elf64_alpha_emit_dynrel (output_bfd, info, sgot, srelgot,
+ gotent->got_offset, 0,
+ R_ALPHA_DTPMOD64, 0);
+
+ if (dynamic_symbol_p || r_type == R_ALPHA_TLSLDM)
+ value = 0;
+ else
+ {
+ BFD_ASSERT (elf_hash_table (info)->tls_sec != NULL);
+ value -= dtp_base;
+ }
+ bfd_put_64 (output_bfd, value,
+ sgot->contents + gotent->got_offset + 8);
+ }
+
+ value = (sgot->output_section->vma
+ + sgot->output_offset
+ + gotent->got_offset);
+ value -= gp;
+ goto default_reloc;
+
+ case R_ALPHA_DTPRELHI:
+ case R_ALPHA_DTPRELLO:
+ case R_ALPHA_DTPREL16:
+ if (dynamic_symbol_p)
+ {
+ (*_bfd_error_handler)
+ (_("%B: dtp-relative relocation against dynamic symbol %s"),
+ input_bfd, h->root.root.root.string);
+ ret_val = FALSE;
+ }
+ BFD_ASSERT (elf_hash_table (info)->tls_sec != NULL);
+ value -= dtp_base;
+ if (r_type == R_ALPHA_DTPRELHI)
+ value = ((bfd_signed_vma) value >> 16) + ((value >> 15) & 1);
+ goto default_reloc;
+
+ case R_ALPHA_TPRELHI:
+ case R_ALPHA_TPRELLO:
+ case R_ALPHA_TPREL16:
+ if (info->shared && !info->pie)
+ {
+ (*_bfd_error_handler)
+ (_("%B: TLS local exec code cannot be linked into shared objects"),
+ input_bfd);
+ ret_val = FALSE;
+ }
+ else if (dynamic_symbol_p)
+ {
+ (*_bfd_error_handler)
+ (_("%B: tp-relative relocation against dynamic symbol %s"),
+ input_bfd, h->root.root.root.string);
+ ret_val = FALSE;
+ }
+ BFD_ASSERT (elf_hash_table (info)->tls_sec != NULL);
+ value -= tp_base;
+ if (r_type == R_ALPHA_TPRELHI)
+ value = ((bfd_signed_vma) value >> 16) + ((value >> 15) & 1);
+ goto default_reloc;
+
+ case R_ALPHA_GOTDTPREL:
+ case R_ALPHA_GOTTPREL:
+ BFD_ASSERT(sgot != NULL);
+ BFD_ASSERT(gp != 0);
+ BFD_ASSERT(gotent != NULL);
+ BFD_ASSERT(gotent->use_count >= 1);
+
+ if (!gotent->reloc_done)
+ {
+ gotent->reloc_done = 1;
+
+ if (dynamic_symbol_p)
+ value = 0;
+ else
+ {
+ BFD_ASSERT (elf_hash_table (info)->tls_sec != NULL);
+ if (r_type == R_ALPHA_GOTDTPREL)
+ value -= dtp_base;
+ else if (!info->shared)
+ value -= tp_base;
+ else
+ {
+ elf64_alpha_emit_dynrel (output_bfd, info, sgot, srelgot,
+ gotent->got_offset, 0,
+ R_ALPHA_TPREL64,
+ value - dtp_base);
+ value = 0;
+ }
+ }
+ bfd_put_64 (output_bfd, value,
+ sgot->contents + gotent->got_offset);
+ }
+
+ value = (sgot->output_section->vma
+ + sgot->output_offset
+ + gotent->got_offset);
+ value -= gp;
+ goto default_reloc;
+
+ default:
+ default_reloc:
+ r = _bfd_final_link_relocate (howto, input_bfd, input_section,
+ contents, rel->r_offset, value, 0);
+ break;
+ }
+
+ switch (r)
+ {
+ case bfd_reloc_ok:
+ break;
+
+ case bfd_reloc_overflow:
+ {
+ const char *name;
+
+ /* Don't warn if the overflow is due to pc relative reloc
+ against discarded section. Section optimization code should
+ handle it. */
+
+ if (r_symndx < symtab_hdr->sh_info
+ && sec != NULL && howto->pc_relative
+ && discarded_section (sec))
+ break;
+
+ if (h != NULL)
+ name = NULL;
+ 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, (h ? &h->root.root : NULL), name, howto->name,
+ (bfd_vma) 0, input_bfd, input_section,
+ rel->r_offset)))
+ ret_val = FALSE;
+ }
+ break;
+
+ default:
+ case bfd_reloc_outofrange:
+ abort ();
+ }
+ }
+
+ return ret_val;
+}
+
+/* Finish up dynamic symbol handling. We set the contents of various
+ dynamic sections here. */
+
+static bfd_boolean
+elf64_alpha_finish_dynamic_symbol (bfd *output_bfd, struct bfd_link_info *info,
+ struct elf_link_hash_entry *h,
+ Elf_Internal_Sym *sym)
+{
+ struct alpha_elf_link_hash_entry *ah = (struct alpha_elf_link_hash_entry *)h;
+ bfd *dynobj = elf_hash_table(info)->dynobj;
+
+ if (h->needs_plt)
+ {
+ /* Fill in the .plt entry for this symbol. */
+ asection *splt, *sgot, *srel;
+ Elf_Internal_Rela outrel;
+ bfd_byte *loc;
+ bfd_vma got_addr, plt_addr;
+ bfd_vma plt_index;
+ struct alpha_elf_got_entry *gotent;
+
+ BFD_ASSERT (h->dynindx != -1);
+
+ splt = bfd_get_linker_section (dynobj, ".plt");
+ BFD_ASSERT (splt != NULL);
+ srel = bfd_get_linker_section (dynobj, ".rela.plt");
+ BFD_ASSERT (srel != NULL);
+
+ for (gotent = ah->got_entries; gotent ; gotent = gotent->next)
+ if (gotent->reloc_type == R_ALPHA_LITERAL
+ && gotent->use_count > 0)
+ {
+ unsigned int insn;
+ int disp;
+
+ sgot = alpha_elf_tdata (gotent->gotobj)->got;
+ BFD_ASSERT (sgot != NULL);
+
+ BFD_ASSERT (gotent->got_offset != -1);
+ BFD_ASSERT (gotent->plt_offset != -1);
+
+ got_addr = (sgot->output_section->vma
+ + sgot->output_offset
+ + gotent->got_offset);
+ plt_addr = (splt->output_section->vma
+ + splt->output_offset
+ + gotent->plt_offset);
+
+ plt_index = (gotent->plt_offset-PLT_HEADER_SIZE) / PLT_ENTRY_SIZE;
+
+ /* Fill in the entry in the procedure linkage table. */
+ if (elf64_alpha_use_secureplt)
+ {
+ disp = (PLT_HEADER_SIZE - 4) - (gotent->plt_offset + 4);
+ insn = INSN_AD (INSN_BR, 31, disp);
+ bfd_put_32 (output_bfd, insn,
+ splt->contents + gotent->plt_offset);
+
+ plt_index = ((gotent->plt_offset - NEW_PLT_HEADER_SIZE)
+ / NEW_PLT_ENTRY_SIZE);
+ }
+ else
+ {
+ disp = -(gotent->plt_offset + 4);
+ insn = INSN_AD (INSN_BR, 28, disp);
+ bfd_put_32 (output_bfd, insn,
+ splt->contents + gotent->plt_offset);
+ bfd_put_32 (output_bfd, INSN_UNOP,
+ splt->contents + gotent->plt_offset + 4);
+ bfd_put_32 (output_bfd, INSN_UNOP,
+ splt->contents + gotent->plt_offset + 8);
+
+ plt_index = ((gotent->plt_offset - OLD_PLT_HEADER_SIZE)
+ / OLD_PLT_ENTRY_SIZE);
+ }
+
+ /* 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;
+
+ loc = srel->contents + plt_index * sizeof (Elf64_External_Rela);
+ bfd_elf64_swap_reloca_out (output_bfd, &outrel, loc);
+
+ /* Fill in the entry in the .got. */
+ bfd_put_64 (output_bfd, plt_addr,
+ sgot->contents + gotent->got_offset);
+ }
+ }
+ else if (alpha_elf_dynamic_symbol_p (h, info))
+ {
+ /* Fill in the dynamic relocations for this symbol's .got entries. */
+ asection *srel;
+ struct alpha_elf_got_entry *gotent;
+
+ srel = bfd_get_linker_section (dynobj, ".rela.got");
+ BFD_ASSERT (srel != NULL);
+
+ for (gotent = ((struct alpha_elf_link_hash_entry *) h)->got_entries;
+ gotent != NULL;
+ gotent = gotent->next)
+ {
+ asection *sgot;
+ long r_type;
+
+ if (gotent->use_count == 0)
+ continue;
+
+ sgot = alpha_elf_tdata (gotent->gotobj)->got;
+
+ r_type = gotent->reloc_type;
+ switch (r_type)
+ {
+ case R_ALPHA_LITERAL:
+ r_type = R_ALPHA_GLOB_DAT;
+ break;
+ case R_ALPHA_TLSGD:
+ r_type = R_ALPHA_DTPMOD64;
+ break;
+ case R_ALPHA_GOTDTPREL:
+ r_type = R_ALPHA_DTPREL64;
+ break;
+ case R_ALPHA_GOTTPREL:
+ r_type = R_ALPHA_TPREL64;
+ break;
+ case R_ALPHA_TLSLDM:
+ default:
+ abort ();
+ }
+
+ elf64_alpha_emit_dynrel (output_bfd, info, sgot, srel,
+ gotent->got_offset, h->dynindx,
+ r_type, gotent->addend);
+
+ if (gotent->reloc_type == R_ALPHA_TLSGD)
+ elf64_alpha_emit_dynrel (output_bfd, info, sgot, srel,
+ gotent->got_offset + 8, h->dynindx,
+ R_ALPHA_DTPREL64, gotent->addend);
+ }
+ }
+
+ /* Mark some specially defined symbols as absolute. */
+ if (h == elf_hash_table (info)->hdynamic
+ || h == elf_hash_table (info)->hgot
+ || h == elf_hash_table (info)->hplt)
+ sym->st_shndx = SHN_ABS;
+
+ return TRUE;
+}
+
+/* Finish up the dynamic sections. */
+
+static bfd_boolean
+elf64_alpha_finish_dynamic_sections (bfd *output_bfd,
+ struct bfd_link_info *info)
+{
+ bfd *dynobj;
+ asection *sdyn;
+
+ dynobj = elf_hash_table (info)->dynobj;
+ sdyn = bfd_get_linker_section (dynobj, ".dynamic");
+
+ if (elf_hash_table (info)->dynamic_sections_created)
+ {
+ asection *splt, *sgotplt, *srelaplt;
+ Elf64_External_Dyn *dyncon, *dynconend;
+ bfd_vma plt_vma, gotplt_vma;
+
+ splt = bfd_get_linker_section (dynobj, ".plt");
+ srelaplt = bfd_get_linker_section (output_bfd, ".rela.plt");
+ BFD_ASSERT (splt != NULL && sdyn != NULL);
+
+ plt_vma = splt->output_section->vma + splt->output_offset;
+
+ gotplt_vma = 0;
+ if (elf64_alpha_use_secureplt)
+ {
+ sgotplt = bfd_get_linker_section (dynobj, ".got.plt");
+ BFD_ASSERT (sgotplt != NULL);
+ if (sgotplt->size > 0)
+ gotplt_vma = sgotplt->output_section->vma + sgotplt->output_offset;
+ }
+
+ dyncon = (Elf64_External_Dyn *) sdyn->contents;
+ dynconend = (Elf64_External_Dyn *) (sdyn->contents + sdyn->size);
+ for (; dyncon < dynconend; dyncon++)
+ {
+ Elf_Internal_Dyn dyn;
+
+ bfd_elf64_swap_dyn_in (dynobj, dyncon, &dyn);
+
+ switch (dyn.d_tag)
+ {
+ case DT_PLTGOT:
+ dyn.d_un.d_ptr
+ = elf64_alpha_use_secureplt ? gotplt_vma : plt_vma;
+ break;
+ case DT_PLTRELSZ:
+ dyn.d_un.d_val = srelaplt ? srelaplt->size : 0;
+ break;
+ case DT_JMPREL:
+ dyn.d_un.d_ptr = srelaplt ? srelaplt->vma : 0;
+ break;
+
+ 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. */
+ if (srelaplt)
+ dyn.d_un.d_val -= srelaplt->size;
+ break;
+ }
+
+ bfd_elf64_swap_dyn_out (output_bfd, &dyn, dyncon);
+ }
+
+ /* Initialize the plt header. */
+ if (splt->size > 0)
+ {
+ unsigned int insn;
+ int ofs;
+
+ if (elf64_alpha_use_secureplt)
+ {
+ ofs = gotplt_vma - (plt_vma + PLT_HEADER_SIZE);
+
+ insn = INSN_ABC (INSN_SUBQ, 27, 28, 25);
+ bfd_put_32 (output_bfd, insn, splt->contents);
+
+ insn = INSN_ABO (INSN_LDAH, 28, 28, (ofs + 0x8000) >> 16);
+ bfd_put_32 (output_bfd, insn, splt->contents + 4);
+
+ insn = INSN_ABC (INSN_S4SUBQ, 25, 25, 25);
+ bfd_put_32 (output_bfd, insn, splt->contents + 8);
+
+ insn = INSN_ABO (INSN_LDA, 28, 28, ofs);
+ bfd_put_32 (output_bfd, insn, splt->contents + 12);
+
+ insn = INSN_ABO (INSN_LDQ, 27, 28, 0);
+ bfd_put_32 (output_bfd, insn, splt->contents + 16);
+
+ insn = INSN_ABC (INSN_ADDQ, 25, 25, 25);
+ bfd_put_32 (output_bfd, insn, splt->contents + 20);
+
+ insn = INSN_ABO (INSN_LDQ, 28, 28, 8);
+ bfd_put_32 (output_bfd, insn, splt->contents + 24);
+
+ insn = INSN_AB (INSN_JMP, 31, 27);
+ bfd_put_32 (output_bfd, insn, splt->contents + 28);
+
+ insn = INSN_AD (INSN_BR, 28, -PLT_HEADER_SIZE);
+ bfd_put_32 (output_bfd, insn, splt->contents + 32);
+ }
+ else
+ {
+ insn = INSN_AD (INSN_BR, 27, 0); /* br $27, .+4 */
+ bfd_put_32 (output_bfd, insn, splt->contents);
+
+ insn = INSN_ABO (INSN_LDQ, 27, 27, 12);
+ bfd_put_32 (output_bfd, insn, splt->contents + 4);
+
+ insn = INSN_UNOP;
+ bfd_put_32 (output_bfd, insn, splt->contents + 8);
+
+ insn = INSN_AB (INSN_JMP, 27, 27);
+ bfd_put_32 (output_bfd, insn, 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 = 0;
+ }
+ }
+
+ return TRUE;
+}
+
+/* We need to use a special link routine to handle the .mdebug section.
+ We need to merge all instances of these sections together, not write
+ them all out sequentially. */
+
+static bfd_boolean
+elf64_alpha_final_link (bfd *abfd, struct bfd_link_info *info)
+{
+ asection *o;
+ struct bfd_link_order *p;
+ asection *mdebug_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;
+ void * mdebug_handle = NULL;
+ struct alpha_elf_link_hash_table * htab;
+
+ htab = alpha_elf_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ /* Go through the sections and collect the mdebug information. */
+ mdebug_sec = NULL;
+ for (o = abfd->sections; o != (asection *) NULL; o = o->next)
+ {
+ 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 == NULL)
+ return FALSE;
+
+ if (1)
+ {
+ asection *s;
+ EXTR esym;
+ bfd_vma last = 0;
+ 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->size;
+ }
+ else
+ esym.asym.value = last;
+
+ if (! bfd_ecoff_debug_one_external (abfd, &debug, swap,
+ name[i], &esym))
+ return FALSE;
+ }
+ }
+
+ for (p = o->map_head.link_order;
+ 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_data_link_order)
+ continue;
+ abort ();
+ }
+
+ input_section = p->u.indirect.section;
+ input_bfd = input_section->owner;
+
+ if (! is_alpha_elf (input_bfd))
+ /* 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->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 = (char *) 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, 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 (htab, 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;
+ }
+
+ /* 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,
+ &einfo);
+ if (einfo.failed)
+ return FALSE;
+
+ /* Set the size of the .mdebug section. */
+ o->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->map_head.link_order = (struct bfd_link_order *) NULL;
+
+ mdebug_sec = o;
+ }
+ }
+
+ /* Invoke the regular ELF backend linker to do all the work. */
+ if (! bfd_elf_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 = htab->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,
+ (file_ptr) sgot->output_offset,
+ sgot->size))
+ 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);
+ }
+
+ return TRUE;
+}
+
+static enum elf_reloc_type_class
+elf64_alpha_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ const asection *rel_sec ATTRIBUTE_UNUSED,
+ const Elf_Internal_Rela *rela)
+{
+ switch ((int) ELF64_R_TYPE (rela->r_info))
+ {
+ case R_ALPHA_RELATIVE:
+ return reloc_class_relative;
+ case R_ALPHA_JMP_SLOT:
+ return reloc_class_plt;
+ case R_ALPHA_COPY:
+ return reloc_class_copy;
+ default:
+ return reloc_class_normal;
+ }
+}
+
+static const struct bfd_elf_special_section elf64_alpha_special_sections[] =
+{
+ { STRING_COMMA_LEN (".sbss"), -2, SHT_NOBITS, SHF_ALLOC + SHF_WRITE + SHF_ALPHA_GPREL },
+ { STRING_COMMA_LEN (".sdata"), -2, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE + SHF_ALPHA_GPREL },
+ { NULL, 0, 0, 0, 0 }
+};
+
+/* 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
+};
+
+/* Use a non-standard hash bucket size of 8. */
+
+static const struct elf_size_info alpha_elf_size_info =
+{
+ sizeof (Elf64_External_Ehdr),
+ sizeof (Elf64_External_Phdr),
+ sizeof (Elf64_External_Shdr),
+ sizeof (Elf64_External_Rel),
+ sizeof (Elf64_External_Rela),
+ sizeof (Elf64_External_Sym),
+ sizeof (Elf64_External_Dyn),
+ sizeof (Elf_External_Note),
+ 8,
+ 1,
+ 64, 3,
+ ELFCLASS64, EV_CURRENT,
+ bfd_elf64_write_out_phdrs,
+ bfd_elf64_write_shdrs_and_ehdr,
+ bfd_elf64_checksum_contents,
+ bfd_elf64_write_relocs,
+ bfd_elf64_swap_symbol_in,
+ bfd_elf64_swap_symbol_out,
+ bfd_elf64_slurp_reloc_table,
+ bfd_elf64_slurp_symbol_table,
+ bfd_elf64_swap_dyn_in,
+ bfd_elf64_swap_dyn_out,
+ bfd_elf64_swap_reloc_in,
+ bfd_elf64_swap_reloc_out,
+ bfd_elf64_swap_reloca_in,
+ bfd_elf64_swap_reloca_out
+};
+
+#define TARGET_LITTLE_SYM alpha_elf64_vec
+#define TARGET_LITTLE_NAME "elf64-alpha"
+#define ELF_ARCH bfd_arch_alpha
+#define ELF_TARGET_ID ALPHA_ELF_DATA
+#define ELF_MACHINE_CODE EM_ALPHA
+#define ELF_MAXPAGESIZE 0x10000
+#define ELF_COMMONPAGESIZE 0x2000
+
+#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 bfd_elf64_bfd_reloc_name_lookup \
+ elf64_alpha_bfd_reloc_name_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_section_flags \
+ elf64_alpha_section_flags
+#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_relocs_compatible \
+ _bfd_elf_relocs_compatible
+#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_merge_symbol_attribute \
+ elf64_alpha_merge_symbol_attribute
+#define elf_backend_copy_indirect_symbol \
+ elf64_alpha_copy_indirect_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_omit_section_dynsym \
+ ((bfd_boolean (*) (bfd *, struct bfd_link_info *, asection *)) bfd_true)
+#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_reloc_type_class \
+ elf64_alpha_reloc_type_class
+
+#define elf_backend_can_gc_sections 1
+#define elf_backend_gc_mark_hook elf64_alpha_gc_mark_hook
+#define elf_backend_gc_sweep_hook elf64_alpha_gc_sweep_hook
+
+#define elf_backend_ecoff_debug_swap \
+ &elf64_alpha_ecoff_debug_swap
+
+#define elf_backend_size_info \
+ alpha_elf_size_info
+
+#define elf_backend_special_sections \
+ elf64_alpha_special_sections
+
+/* 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
+
+#include "elf64-target.h"
+
+/* FreeBSD support. */
+
+#undef TARGET_LITTLE_SYM
+#define TARGET_LITTLE_SYM alpha_elf64_fbsd_vec
+#undef TARGET_LITTLE_NAME
+#define TARGET_LITTLE_NAME "elf64-alpha-freebsd"
+#undef ELF_OSABI
+#define ELF_OSABI ELFOSABI_FREEBSD
+
+/* The kernel recognizes executables as valid only if they carry a
+ "FreeBSD" label in the ELF header. So we put this label on all
+ executables and (for simplicity) also all other object files. */
+
+static void
+elf64_alpha_fbsd_post_process_headers (bfd * abfd,
+ struct bfd_link_info * link_info ATTRIBUTE_UNUSED)
+{
+ Elf_Internal_Ehdr * i_ehdrp; /* ELF file header, internal form. */
+
+ i_ehdrp = elf_elfheader (abfd);
+
+ /* Put an ABI label supported by FreeBSD >= 4.1. */
+ i_ehdrp->e_ident[EI_OSABI] = get_elf_backend_data (abfd)->elf_osabi;
+#ifdef OLD_FREEBSD_ABI_LABEL
+ /* The ABI label supported by FreeBSD <= 4.0 is quite nonstandard. */
+ memcpy (&i_ehdrp->e_ident[EI_ABIVERSION], "FreeBSD", 8);
+#endif
+}
+
+#undef elf_backend_post_process_headers
+#define elf_backend_post_process_headers \
+ elf64_alpha_fbsd_post_process_headers
+
+#undef elf64_bed
+#define elf64_bed elf64_alpha_fbsd_bed
+
+#include "elf64-target.h"
diff --git a/bfd/elf64-gen.c b/bfd/elf64-gen.c
new file mode 100644
index 0000000..d8afcfa
--- /dev/null
+++ b/bfd/elf64-gen.c
@@ -0,0 +1,102 @@
+/* Generic support for 64-bit ELF
+ Copyright (C) 1993-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.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 (bfd *abfd ATTRIBUTE_UNUSED,
+ arelent *bfd_reloc,
+ Elf_Internal_Rela *elf_reloc ATTRIBUTE_UNUSED)
+{
+ bfd_reloc->howto = &dummy;
+}
+
+static void
+elf_generic_info_to_howto_rel (bfd *abfd ATTRIBUTE_UNUSED,
+ arelent *bfd_reloc,
+ Elf_Internal_Rela *elf_reloc ATTRIBUTE_UNUSED)
+{
+ bfd_reloc->howto = &dummy;
+}
+
+static void
+check_for_relocs (bfd * abfd, asection * o, void * failed)
+{
+ if ((o->flags & SEC_RELOC) != 0)
+ {
+ Elf_Internal_Ehdr *ehdrp;
+
+ ehdrp = elf_elfheader (abfd);
+ _bfd_error_handler (_("%B: Relocations in generic ELF (EM: %d)"),
+ abfd, ehdrp->e_machine);
+
+ bfd_set_error (bfd_error_wrong_format);
+ * (bfd_boolean *) failed = TRUE;
+ }
+}
+
+static bfd_boolean
+elf64_generic_link_add_symbols (bfd *abfd, struct bfd_link_info *info)
+{
+ bfd_boolean failed = FALSE;
+
+ /* Check if there are any relocations. */
+ bfd_map_over_sections (abfd, check_for_relocs, & failed);
+
+ if (failed)
+ return FALSE;
+ return bfd_elf_link_add_symbols (abfd, info);
+}
+
+#define TARGET_LITTLE_SYM elf64_le_vec
+#define TARGET_LITTLE_NAME "elf64-little"
+#define TARGET_BIG_SYM elf64_be_vec
+#define TARGET_BIG_NAME "elf64-big"
+#define ELF_ARCH bfd_arch_unknown
+#define ELF_MACHINE_CODE EM_NONE
+#define ELF_MAXPAGESIZE 0x1
+#define bfd_elf64_bfd_reloc_type_lookup bfd_default_reloc_type_lookup
+#define bfd_elf64_bfd_reloc_name_lookup _bfd_norelocs_bfd_reloc_name_lookup
+#define bfd_elf64_bfd_link_add_symbols elf64_generic_link_add_symbols
+#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-hppa.c b/bfd/elf64-hppa.c
new file mode 100644
index 0000000..86f652d
--- /dev/null
+++ b/bfd/elf64-hppa.c
@@ -0,0 +1,4112 @@
+/* Support for HPPA 64-bit ELF
+ Copyright (C) 1999-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "alloca-conf.h"
+#include "bfd.h"
+#include "libbfd.h"
+#include "elf-bfd.h"
+#include "elf/hppa.h"
+#include "libhppa.h"
+#include "elf64-hppa.h"
+
+
+#define ARCH_SIZE 64
+
+#define PLT_ENTRY_SIZE 0x10
+#define DLT_ENTRY_SIZE 0x8
+#define OPD_ENTRY_SIZE 0x20
+
+#define ELF_DYNAMIC_INTERPRETER "/usr/lib/pa20_64/dld.sl"
+
+/* The stub is supposed to load the target address and target's DP
+ value out of the PLT, then do an external branch to the target
+ address.
+
+ LDD PLTOFF(%r27),%r1
+ BVE (%r1)
+ LDD PLTOFF+8(%r27),%r27
+
+ Note that we must use the LDD with a 14 bit displacement, not the one
+ with a 5 bit displacement. */
+static char plt_stub[] = {0x53, 0x61, 0x00, 0x00, 0xe8, 0x20, 0xd0, 0x00,
+ 0x53, 0x7b, 0x00, 0x00 };
+
+struct elf64_hppa_link_hash_entry
+{
+ struct elf_link_hash_entry eh;
+
+ /* Offsets for this symbol in various linker sections. */
+ bfd_vma dlt_offset;
+ bfd_vma plt_offset;
+ bfd_vma opd_offset;
+ bfd_vma stub_offset;
+
+ /* The index of the (possibly local) symbol in the input bfd and its
+ associated BFD. Needed so that we can have relocs against local
+ symbols in shared libraries. */
+ long sym_indx;
+ bfd *owner;
+
+ /* Dynamic symbols may need to have two different values. One for
+ the dynamic symbol table, one for the normal symbol table.
+
+ In such cases we store the symbol's real value and section
+ index here so we can restore the real value before we write
+ the normal symbol table. */
+ bfd_vma st_value;
+ int st_shndx;
+
+ /* Used to count non-got, non-plt relocations for delayed sizing
+ of relocation sections. */
+ struct elf64_hppa_dyn_reloc_entry
+ {
+ /* Next relocation in the chain. */
+ struct elf64_hppa_dyn_reloc_entry *next;
+
+ /* The type of the relocation. */
+ int type;
+
+ /* The input section of the relocation. */
+ asection *sec;
+
+ /* Number of relocs copied in this section. */
+ bfd_size_type count;
+
+ /* The index of the section symbol for the input section of
+ the relocation. Only needed when building shared libraries. */
+ int sec_symndx;
+
+ /* The offset within the input section of the relocation. */
+ bfd_vma offset;
+
+ /* The addend for the relocation. */
+ bfd_vma addend;
+
+ } *reloc_entries;
+
+ /* Nonzero if this symbol needs an entry in one of the linker
+ sections. */
+ unsigned want_dlt;
+ unsigned want_plt;
+ unsigned want_opd;
+ unsigned want_stub;
+};
+
+struct elf64_hppa_link_hash_table
+{
+ struct elf_link_hash_table root;
+
+ /* Shortcuts to get to the various linker defined sections. */
+ asection *dlt_sec;
+ asection *dlt_rel_sec;
+ asection *plt_sec;
+ asection *plt_rel_sec;
+ asection *opd_sec;
+ asection *opd_rel_sec;
+ asection *other_rel_sec;
+
+ /* Offset of __gp within .plt section. When the PLT gets large we want
+ to slide __gp into the PLT section so that we can continue to use
+ single DP relative instructions to load values out of the PLT. */
+ bfd_vma gp_offset;
+
+ /* Note this is not strictly correct. We should create a stub section for
+ each input section with calls. The stub section should be placed before
+ the section with the call. */
+ asection *stub_sec;
+
+ bfd_vma text_segment_base;
+ bfd_vma data_segment_base;
+
+ /* We build tables to map from an input section back to its
+ symbol index. This is the BFD for which we currently have
+ a map. */
+ bfd *section_syms_bfd;
+
+ /* Array of symbol numbers for each input section attached to the
+ current BFD. */
+ int *section_syms;
+};
+
+#define hppa_link_hash_table(p) \
+ (elf_hash_table_id ((struct elf_link_hash_table *) ((p)->hash)) \
+ == HPPA64_ELF_DATA ? ((struct elf64_hppa_link_hash_table *) ((p)->hash)) : NULL)
+
+#define hppa_elf_hash_entry(ent) \
+ ((struct elf64_hppa_link_hash_entry *)(ent))
+
+#define eh_name(eh) \
+ (eh ? eh->root.root.string : "<undef>")
+
+typedef struct bfd_hash_entry *(*new_hash_entry_func)
+ (struct bfd_hash_entry *, struct bfd_hash_table *, const char *);
+
+static struct bfd_link_hash_table *elf64_hppa_hash_table_create
+ (bfd *abfd);
+
+/* This must follow the definitions of the various derived linker
+ hash tables and shared functions. */
+#include "elf-hppa.h"
+
+static bfd_boolean elf64_hppa_object_p
+ (bfd *);
+
+static void elf64_hppa_post_process_headers
+ (bfd *, struct bfd_link_info *);
+
+static bfd_boolean elf64_hppa_create_dynamic_sections
+ (bfd *, struct bfd_link_info *);
+
+static bfd_boolean elf64_hppa_adjust_dynamic_symbol
+ (struct bfd_link_info *, struct elf_link_hash_entry *);
+
+static bfd_boolean elf64_hppa_mark_milli_and_exported_functions
+ (struct elf_link_hash_entry *, void *);
+
+static bfd_boolean elf64_hppa_size_dynamic_sections
+ (bfd *, struct bfd_link_info *);
+
+static int elf64_hppa_link_output_symbol_hook
+ (struct bfd_link_info *, const char *, Elf_Internal_Sym *,
+ asection *, struct elf_link_hash_entry *);
+
+static bfd_boolean elf64_hppa_finish_dynamic_symbol
+ (bfd *, struct bfd_link_info *,
+ struct elf_link_hash_entry *, Elf_Internal_Sym *);
+
+static bfd_boolean elf64_hppa_finish_dynamic_sections
+ (bfd *, struct bfd_link_info *);
+
+static bfd_boolean elf64_hppa_check_relocs
+ (bfd *, struct bfd_link_info *,
+ asection *, const Elf_Internal_Rela *);
+
+static bfd_boolean elf64_hppa_dynamic_symbol_p
+ (struct elf_link_hash_entry *, struct bfd_link_info *);
+
+static bfd_boolean elf64_hppa_mark_exported_functions
+ (struct elf_link_hash_entry *, void *);
+
+static bfd_boolean elf64_hppa_finalize_opd
+ (struct elf_link_hash_entry *, void *);
+
+static bfd_boolean elf64_hppa_finalize_dlt
+ (struct elf_link_hash_entry *, void *);
+
+static bfd_boolean allocate_global_data_dlt
+ (struct elf_link_hash_entry *, void *);
+
+static bfd_boolean allocate_global_data_plt
+ (struct elf_link_hash_entry *, void *);
+
+static bfd_boolean allocate_global_data_stub
+ (struct elf_link_hash_entry *, void *);
+
+static bfd_boolean allocate_global_data_opd
+ (struct elf_link_hash_entry *, void *);
+
+static bfd_boolean get_reloc_section
+ (bfd *, struct elf64_hppa_link_hash_table *, asection *);
+
+static bfd_boolean count_dyn_reloc
+ (bfd *, struct elf64_hppa_link_hash_entry *,
+ int, asection *, int, bfd_vma, bfd_vma);
+
+static bfd_boolean allocate_dynrel_entries
+ (struct elf_link_hash_entry *, void *);
+
+static bfd_boolean elf64_hppa_finalize_dynreloc
+ (struct elf_link_hash_entry *, void *);
+
+static bfd_boolean get_opd
+ (bfd *, struct bfd_link_info *, struct elf64_hppa_link_hash_table *);
+
+static bfd_boolean get_plt
+ (bfd *, struct bfd_link_info *, struct elf64_hppa_link_hash_table *);
+
+static bfd_boolean get_dlt
+ (bfd *, struct bfd_link_info *, struct elf64_hppa_link_hash_table *);
+
+static bfd_boolean get_stub
+ (bfd *, struct bfd_link_info *, struct elf64_hppa_link_hash_table *);
+
+static int elf64_hppa_elf_get_symbol_type
+ (Elf_Internal_Sym *, int);
+
+/* Initialize an entry in the link hash table. */
+
+static struct bfd_hash_entry *
+hppa64_link_hash_newfunc (struct bfd_hash_entry *entry,
+ struct bfd_hash_table *table,
+ const char *string)
+{
+ /* Allocate the structure if it has not already been allocated by a
+ subclass. */
+ if (entry == NULL)
+ {
+ entry = bfd_hash_allocate (table,
+ sizeof (struct elf64_hppa_link_hash_entry));
+ if (entry == NULL)
+ return entry;
+ }
+
+ /* Call the allocation method of the superclass. */
+ entry = _bfd_elf_link_hash_newfunc (entry, table, string);
+ if (entry != NULL)
+ {
+ struct elf64_hppa_link_hash_entry *hh;
+
+ /* Initialize our local data. All zeros. */
+ hh = hppa_elf_hash_entry (entry);
+ memset (&hh->dlt_offset, 0,
+ (sizeof (struct elf64_hppa_link_hash_entry)
+ - offsetof (struct elf64_hppa_link_hash_entry, dlt_offset)));
+ }
+
+ return entry;
+}
+
+/* Create the derived linker hash table. The PA64 ELF port uses this
+ derived hash table to keep information specific to the PA ElF
+ linker (without using static variables). */
+
+static struct bfd_link_hash_table*
+elf64_hppa_hash_table_create (bfd *abfd)
+{
+ struct elf64_hppa_link_hash_table *htab;
+ bfd_size_type amt = sizeof (*htab);
+
+ htab = bfd_zmalloc (amt);
+ if (htab == NULL)
+ return NULL;
+
+ if (!_bfd_elf_link_hash_table_init (&htab->root, abfd,
+ hppa64_link_hash_newfunc,
+ sizeof (struct elf64_hppa_link_hash_entry),
+ HPPA64_ELF_DATA))
+ {
+ free (htab);
+ return NULL;
+ }
+
+ htab->text_segment_base = (bfd_vma) -1;
+ htab->data_segment_base = (bfd_vma) -1;
+
+ return &htab->root.root;
+}
+
+/* Return nonzero if ABFD represents a PA2.0 ELF64 file.
+
+ Additionally we set the default architecture and machine. */
+static bfd_boolean
+elf64_hppa_object_p (bfd *abfd)
+{
+ Elf_Internal_Ehdr * i_ehdrp;
+ unsigned int flags;
+
+ i_ehdrp = elf_elfheader (abfd);
+ if (strcmp (bfd_get_target (abfd), "elf64-hppa-linux") == 0)
+ {
+ /* GCC on hppa-linux produces binaries with OSABI=GNU,
+ but the kernel produces corefiles with OSABI=SysV. */
+ if (i_ehdrp->e_ident[EI_OSABI] != ELFOSABI_GNU
+ && i_ehdrp->e_ident[EI_OSABI] != ELFOSABI_NONE) /* aka SYSV */
+ return FALSE;
+ }
+ else
+ {
+ /* HPUX produces binaries with OSABI=HPUX,
+ but the kernel produces corefiles with OSABI=SysV. */
+ if (i_ehdrp->e_ident[EI_OSABI] != ELFOSABI_HPUX
+ && i_ehdrp->e_ident[EI_OSABI] != ELFOSABI_NONE) /* aka SYSV */
+ return FALSE;
+ }
+
+ flags = i_ehdrp->e_flags;
+ switch (flags & (EF_PARISC_ARCH | EF_PARISC_WIDE))
+ {
+ case EFA_PARISC_1_0:
+ return bfd_default_set_arch_mach (abfd, bfd_arch_hppa, 10);
+ case EFA_PARISC_1_1:
+ return bfd_default_set_arch_mach (abfd, bfd_arch_hppa, 11);
+ case EFA_PARISC_2_0:
+ if (i_ehdrp->e_ident[EI_CLASS] == ELFCLASS64)
+ return bfd_default_set_arch_mach (abfd, bfd_arch_hppa, 25);
+ else
+ return bfd_default_set_arch_mach (abfd, bfd_arch_hppa, 20);
+ case EFA_PARISC_2_0 | EF_PARISC_WIDE:
+ return bfd_default_set_arch_mach (abfd, bfd_arch_hppa, 25);
+ }
+ /* Don't be fussy. */
+ return TRUE;
+}
+
+/* Given section type (hdr->sh_type), return a boolean indicating
+ whether or not the section is an elf64-hppa specific section. */
+static bfd_boolean
+elf64_hppa_section_from_shdr (bfd *abfd,
+ Elf_Internal_Shdr *hdr,
+ const char *name,
+ int shindex)
+{
+ switch (hdr->sh_type)
+ {
+ case SHT_PARISC_EXT:
+ if (strcmp (name, ".PARISC.archext") != 0)
+ return FALSE;
+ break;
+ case SHT_PARISC_UNWIND:
+ if (strcmp (name, ".PARISC.unwind") != 0)
+ return FALSE;
+ break;
+ case SHT_PARISC_DOC:
+ case SHT_PARISC_ANNOT:
+ default:
+ return FALSE;
+ }
+
+ if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex))
+ return FALSE;
+
+ return TRUE;
+}
+
+/* SEC is a section containing relocs for an input BFD when linking; return
+ a suitable section for holding relocs in the output BFD for a link. */
+
+static bfd_boolean
+get_reloc_section (bfd *abfd,
+ struct elf64_hppa_link_hash_table *hppa_info,
+ asection *sec)
+{
+ const char *srel_name;
+ asection *srel;
+ bfd *dynobj;
+
+ srel_name = (bfd_elf_string_from_elf_section
+ (abfd, elf_elfheader(abfd)->e_shstrndx,
+ _bfd_elf_single_rel_hdr(sec)->sh_name));
+ if (srel_name == NULL)
+ return FALSE;
+
+ dynobj = hppa_info->root.dynobj;
+ if (!dynobj)
+ hppa_info->root.dynobj = dynobj = abfd;
+
+ srel = bfd_get_linker_section (dynobj, srel_name);
+ if (srel == NULL)
+ {
+ srel = bfd_make_section_anyway_with_flags (dynobj, srel_name,
+ (SEC_ALLOC
+ | SEC_LOAD
+ | SEC_HAS_CONTENTS
+ | SEC_IN_MEMORY
+ | SEC_LINKER_CREATED
+ | SEC_READONLY));
+ if (srel == NULL
+ || !bfd_set_section_alignment (dynobj, srel, 3))
+ return FALSE;
+ }
+
+ hppa_info->other_rel_sec = srel;
+ return TRUE;
+}
+
+/* Add a new entry to the list of dynamic relocations against DYN_H.
+
+ We use this to keep a record of all the FPTR relocations against a
+ particular symbol so that we can create FPTR relocations in the
+ output file. */
+
+static bfd_boolean
+count_dyn_reloc (bfd *abfd,
+ struct elf64_hppa_link_hash_entry *hh,
+ int type,
+ asection *sec,
+ int sec_symndx,
+ bfd_vma offset,
+ bfd_vma addend)
+{
+ struct elf64_hppa_dyn_reloc_entry *rent;
+
+ rent = (struct elf64_hppa_dyn_reloc_entry *)
+ bfd_alloc (abfd, (bfd_size_type) sizeof (*rent));
+ if (!rent)
+ return FALSE;
+
+ rent->next = hh->reloc_entries;
+ rent->type = type;
+ rent->sec = sec;
+ rent->sec_symndx = sec_symndx;
+ rent->offset = offset;
+ rent->addend = addend;
+ hh->reloc_entries = rent;
+
+ return TRUE;
+}
+
+/* Return a pointer to the local DLT, PLT and OPD reference counts
+ for ABFD. Returns NULL if the storage allocation fails. */
+
+static bfd_signed_vma *
+hppa64_elf_local_refcounts (bfd *abfd)
+{
+ Elf_Internal_Shdr *symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+ bfd_signed_vma *local_refcounts;
+
+ local_refcounts = elf_local_got_refcounts (abfd);
+ if (local_refcounts == NULL)
+ {
+ bfd_size_type size;
+
+ /* Allocate space for local DLT, PLT and OPD reference
+ counts. Done this way to save polluting elf_obj_tdata
+ with another target specific pointer. */
+ size = symtab_hdr->sh_info;
+ size *= 3 * sizeof (bfd_signed_vma);
+ local_refcounts = bfd_zalloc (abfd, size);
+ elf_local_got_refcounts (abfd) = local_refcounts;
+ }
+ return local_refcounts;
+}
+
+/* Scan the RELOCS and record the type of dynamic entries that each
+ referenced symbol needs. */
+
+static bfd_boolean
+elf64_hppa_check_relocs (bfd *abfd,
+ struct bfd_link_info *info,
+ asection *sec,
+ const Elf_Internal_Rela *relocs)
+{
+ struct elf64_hppa_link_hash_table *hppa_info;
+ const Elf_Internal_Rela *relend;
+ Elf_Internal_Shdr *symtab_hdr;
+ const Elf_Internal_Rela *rel;
+ unsigned int sec_symndx;
+
+ if (info->relocatable)
+ return TRUE;
+
+ /* 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 (! _bfd_elf_link_create_dynamic_sections (abfd, info))
+ return FALSE;
+ }
+
+ hppa_info = hppa_link_hash_table (info);
+ if (hppa_info == NULL)
+ return FALSE;
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+
+ /* If necessary, build a new table holding section symbols indices
+ for this BFD. */
+
+ if (info->shared && hppa_info->section_syms_bfd != abfd)
+ {
+ unsigned long i;
+ unsigned int highest_shndx;
+ Elf_Internal_Sym *local_syms = NULL;
+ Elf_Internal_Sym *isym, *isymend;
+ bfd_size_type amt;
+
+ /* We're done with the old cache of section index to section symbol
+ index information. Free it.
+
+ ?!? Note we leak the last section_syms array. Presumably we
+ could free it in one of the later routines in this file. */
+ if (hppa_info->section_syms)
+ free (hppa_info->section_syms);
+
+ /* Read this BFD's local symbols. */
+ if (symtab_hdr->sh_info != 0)
+ {
+ local_syms = (Elf_Internal_Sym *) symtab_hdr->contents;
+ if (local_syms == NULL)
+ local_syms = bfd_elf_get_elf_syms (abfd, symtab_hdr,
+ symtab_hdr->sh_info, 0,
+ NULL, NULL, NULL);
+ if (local_syms == NULL)
+ return FALSE;
+ }
+
+ /* Record the highest section index referenced by the local symbols. */
+ highest_shndx = 0;
+ isymend = local_syms + symtab_hdr->sh_info;
+ for (isym = local_syms; isym < isymend; isym++)
+ {
+ if (isym->st_shndx > highest_shndx
+ && isym->st_shndx < SHN_LORESERVE)
+ highest_shndx = isym->st_shndx;
+ }
+
+ /* Allocate an array to hold the section index to section symbol index
+ mapping. Bump by one since we start counting at zero. */
+ highest_shndx++;
+ amt = highest_shndx;
+ amt *= sizeof (int);
+ hppa_info->section_syms = (int *) bfd_malloc (amt);
+
+ /* Now walk the local symbols again. If we find a section symbol,
+ record the index of the symbol into the section_syms array. */
+ for (i = 0, isym = local_syms; isym < isymend; i++, isym++)
+ {
+ if (ELF_ST_TYPE (isym->st_info) == STT_SECTION)
+ hppa_info->section_syms[isym->st_shndx] = i;
+ }
+
+ /* We are finished with the local symbols. */
+ if (local_syms != NULL
+ && symtab_hdr->contents != (unsigned char *) local_syms)
+ {
+ if (! info->keep_memory)
+ free (local_syms);
+ else
+ {
+ /* Cache the symbols for elf_link_input_bfd. */
+ symtab_hdr->contents = (unsigned char *) local_syms;
+ }
+ }
+
+ /* Record which BFD we built the section_syms mapping for. */
+ hppa_info->section_syms_bfd = abfd;
+ }
+
+ /* Record the symbol index for this input section. We may need it for
+ relocations when building shared libraries. When not building shared
+ libraries this value is never really used, but assign it to zero to
+ prevent out of bounds memory accesses in other routines. */
+ if (info->shared)
+ {
+ sec_symndx = _bfd_elf_section_from_bfd_section (abfd, sec);
+
+ /* If we did not find a section symbol for this section, then
+ something went terribly wrong above. */
+ if (sec_symndx == SHN_BAD)
+ return FALSE;
+
+ if (sec_symndx < SHN_LORESERVE)
+ sec_symndx = hppa_info->section_syms[sec_symndx];
+ else
+ sec_symndx = 0;
+ }
+ else
+ sec_symndx = 0;
+
+ relend = relocs + sec->reloc_count;
+ for (rel = relocs; rel < relend; ++rel)
+ {
+ enum
+ {
+ NEED_DLT = 1,
+ NEED_PLT = 2,
+ NEED_STUB = 4,
+ NEED_OPD = 8,
+ NEED_DYNREL = 16,
+ };
+
+ unsigned long r_symndx = ELF64_R_SYM (rel->r_info);
+ struct elf64_hppa_link_hash_entry *hh;
+ int need_entry;
+ bfd_boolean maybe_dynamic;
+ int dynrel_type = R_PARISC_NONE;
+ static reloc_howto_type *howto;
+
+ if (r_symndx >= symtab_hdr->sh_info)
+ {
+ /* We're dealing with a global symbol -- find its hash entry
+ and mark it as being referenced. */
+ long indx = r_symndx - symtab_hdr->sh_info;
+ hh = hppa_elf_hash_entry (elf_sym_hashes (abfd)[indx]);
+ while (hh->eh.root.type == bfd_link_hash_indirect
+ || hh->eh.root.type == bfd_link_hash_warning)
+ hh = hppa_elf_hash_entry (hh->eh.root.u.i.link);
+
+ /* PR15323, ref flags aren't set for references in the same
+ object. */
+ hh->eh.root.non_ir_ref = 1;
+ hh->eh.ref_regular = 1;
+ }
+ else
+ hh = NULL;
+
+ /* We can only get preliminary data on whether a symbol is
+ locally or externally defined, as not all of the input files
+ have yet been processed. Do something with what we know, as
+ this may help reduce memory usage and processing time later. */
+ maybe_dynamic = FALSE;
+ if (hh && ((info->shared
+ && (!info->symbolic
+ || info->unresolved_syms_in_shared_libs == RM_IGNORE))
+ || !hh->eh.def_regular
+ || hh->eh.root.type == bfd_link_hash_defweak))
+ maybe_dynamic = TRUE;
+
+ howto = elf_hppa_howto_table + ELF64_R_TYPE (rel->r_info);
+ need_entry = 0;
+ switch (howto->type)
+ {
+ /* These are simple indirect references to symbols through the
+ DLT. We need to create a DLT entry for any symbols which
+ appears in a DLTIND relocation. */
+ case R_PARISC_DLTIND21L:
+ case R_PARISC_DLTIND14R:
+ case R_PARISC_DLTIND14F:
+ case R_PARISC_DLTIND14WR:
+ case R_PARISC_DLTIND14DR:
+ need_entry = NEED_DLT;
+ break;
+
+ /* ?!? These need a DLT entry. But I have no idea what to do with
+ the "link time TP value. */
+ case R_PARISC_LTOFF_TP21L:
+ case R_PARISC_LTOFF_TP14R:
+ case R_PARISC_LTOFF_TP14F:
+ case R_PARISC_LTOFF_TP64:
+ case R_PARISC_LTOFF_TP14WR:
+ case R_PARISC_LTOFF_TP14DR:
+ case R_PARISC_LTOFF_TP16F:
+ case R_PARISC_LTOFF_TP16WF:
+ case R_PARISC_LTOFF_TP16DF:
+ need_entry = NEED_DLT;
+ break;
+
+ /* These are function calls. Depending on their precise target we
+ may need to make a stub for them. The stub uses the PLT, so we
+ need to create PLT entries for these symbols too. */
+ case R_PARISC_PCREL12F:
+ case R_PARISC_PCREL17F:
+ case R_PARISC_PCREL22F:
+ case R_PARISC_PCREL32:
+ case R_PARISC_PCREL64:
+ case R_PARISC_PCREL21L:
+ case R_PARISC_PCREL17R:
+ case R_PARISC_PCREL17C:
+ case R_PARISC_PCREL14R:
+ case R_PARISC_PCREL14F:
+ case R_PARISC_PCREL22C:
+ case R_PARISC_PCREL14WR:
+ case R_PARISC_PCREL14DR:
+ case R_PARISC_PCREL16F:
+ case R_PARISC_PCREL16WF:
+ case R_PARISC_PCREL16DF:
+ /* Function calls might need to go through the .plt, and
+ might need a long branch stub. */
+ if (hh != NULL && hh->eh.type != STT_PARISC_MILLI)
+ need_entry = (NEED_PLT | NEED_STUB);
+ else
+ need_entry = 0;
+ break;
+
+ case R_PARISC_PLTOFF21L:
+ case R_PARISC_PLTOFF14R:
+ case R_PARISC_PLTOFF14F:
+ case R_PARISC_PLTOFF14WR:
+ case R_PARISC_PLTOFF14DR:
+ case R_PARISC_PLTOFF16F:
+ case R_PARISC_PLTOFF16WF:
+ case R_PARISC_PLTOFF16DF:
+ need_entry = (NEED_PLT);
+ break;
+
+ case R_PARISC_DIR64:
+ if (info->shared || maybe_dynamic)
+ need_entry = (NEED_DYNREL);
+ dynrel_type = R_PARISC_DIR64;
+ break;
+
+ /* This is an indirect reference through the DLT to get the address
+ of a OPD descriptor. Thus we need to make a DLT entry that points
+ to an OPD entry. */
+ case R_PARISC_LTOFF_FPTR21L:
+ case R_PARISC_LTOFF_FPTR14R:
+ case R_PARISC_LTOFF_FPTR14WR:
+ case R_PARISC_LTOFF_FPTR14DR:
+ case R_PARISC_LTOFF_FPTR32:
+ case R_PARISC_LTOFF_FPTR64:
+ case R_PARISC_LTOFF_FPTR16F:
+ case R_PARISC_LTOFF_FPTR16WF:
+ case R_PARISC_LTOFF_FPTR16DF:
+ if (info->shared || maybe_dynamic)
+ need_entry = (NEED_DLT | NEED_OPD | NEED_PLT);
+ else
+ need_entry = (NEED_DLT | NEED_OPD | NEED_PLT);
+ dynrel_type = R_PARISC_FPTR64;
+ break;
+
+ /* This is a simple OPD entry. */
+ case R_PARISC_FPTR64:
+ if (info->shared || maybe_dynamic)
+ need_entry = (NEED_OPD | NEED_PLT | NEED_DYNREL);
+ else
+ need_entry = (NEED_OPD | NEED_PLT);
+ dynrel_type = R_PARISC_FPTR64;
+ break;
+
+ /* Add more cases as needed. */
+ }
+
+ if (!need_entry)
+ continue;
+
+ if (hh)
+ {
+ /* Stash away enough information to be able to find this symbol
+ regardless of whether or not it is local or global. */
+ hh->owner = abfd;
+ hh->sym_indx = r_symndx;
+ }
+
+ /* Create what's needed. */
+ if (need_entry & NEED_DLT)
+ {
+ /* Allocate space for a DLT entry, as well as a dynamic
+ relocation for this entry. */
+ if (! hppa_info->dlt_sec
+ && ! get_dlt (abfd, info, hppa_info))
+ goto err_out;
+
+ if (hh != NULL)
+ {
+ hh->want_dlt = 1;
+ hh->eh.got.refcount += 1;
+ }
+ else
+ {
+ bfd_signed_vma *local_dlt_refcounts;
+
+ /* This is a DLT entry for a local symbol. */
+ local_dlt_refcounts = hppa64_elf_local_refcounts (abfd);
+ if (local_dlt_refcounts == NULL)
+ return FALSE;
+ local_dlt_refcounts[r_symndx] += 1;
+ }
+ }
+
+ if (need_entry & NEED_PLT)
+ {
+ if (! hppa_info->plt_sec
+ && ! get_plt (abfd, info, hppa_info))
+ goto err_out;
+
+ if (hh != NULL)
+ {
+ hh->want_plt = 1;
+ hh->eh.needs_plt = 1;
+ hh->eh.plt.refcount += 1;
+ }
+ else
+ {
+ bfd_signed_vma *local_dlt_refcounts;
+ bfd_signed_vma *local_plt_refcounts;
+
+ /* This is a PLT entry for a local symbol. */
+ local_dlt_refcounts = hppa64_elf_local_refcounts (abfd);
+ if (local_dlt_refcounts == NULL)
+ return FALSE;
+ local_plt_refcounts = local_dlt_refcounts + symtab_hdr->sh_info;
+ local_plt_refcounts[r_symndx] += 1;
+ }
+ }
+
+ if (need_entry & NEED_STUB)
+ {
+ if (! hppa_info->stub_sec
+ && ! get_stub (abfd, info, hppa_info))
+ goto err_out;
+ if (hh)
+ hh->want_stub = 1;
+ }
+
+ if (need_entry & NEED_OPD)
+ {
+ if (! hppa_info->opd_sec
+ && ! get_opd (abfd, info, hppa_info))
+ goto err_out;
+
+ /* FPTRs are not allocated by the dynamic linker for PA64,
+ though it is possible that will change in the future. */
+
+ if (hh != NULL)
+ hh->want_opd = 1;
+ else
+ {
+ bfd_signed_vma *local_dlt_refcounts;
+ bfd_signed_vma *local_opd_refcounts;
+
+ /* This is a OPD for a local symbol. */
+ local_dlt_refcounts = hppa64_elf_local_refcounts (abfd);
+ if (local_dlt_refcounts == NULL)
+ return FALSE;
+ local_opd_refcounts = (local_dlt_refcounts
+ + 2 * symtab_hdr->sh_info);
+ local_opd_refcounts[r_symndx] += 1;
+ }
+ }
+
+ /* Add a new dynamic relocation to the chain of dynamic
+ relocations for this symbol. */
+ if ((need_entry & NEED_DYNREL) && (sec->flags & SEC_ALLOC))
+ {
+ if (! hppa_info->other_rel_sec
+ && ! get_reloc_section (abfd, hppa_info, sec))
+ goto err_out;
+
+ /* Count dynamic relocations against global symbols. */
+ if (hh != NULL
+ && !count_dyn_reloc (abfd, hh, dynrel_type, sec,
+ sec_symndx, rel->r_offset, rel->r_addend))
+ goto err_out;
+
+ /* If we are building a shared library and we just recorded
+ a dynamic R_PARISC_FPTR64 relocation, then make sure the
+ section symbol for this section ends up in the dynamic
+ symbol table. */
+ if (info->shared && dynrel_type == R_PARISC_FPTR64
+ && ! (bfd_elf_link_record_local_dynamic_symbol
+ (info, abfd, sec_symndx)))
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+
+ err_out:
+ return FALSE;
+}
+
+struct elf64_hppa_allocate_data
+{
+ struct bfd_link_info *info;
+ bfd_size_type ofs;
+};
+
+/* Should we do dynamic things to this symbol? */
+
+static bfd_boolean
+elf64_hppa_dynamic_symbol_p (struct elf_link_hash_entry *eh,
+ struct bfd_link_info *info)
+{
+ /* ??? What, if anything, needs to happen wrt STV_PROTECTED symbols
+ and relocations that retrieve a function descriptor? Assume the
+ worst for now. */
+ if (_bfd_elf_dynamic_symbol_p (eh, info, 1))
+ {
+ /* ??? Why is this here and not elsewhere is_local_label_name. */
+ if (eh->root.root.string[0] == '$' && eh->root.root.string[1] == '$')
+ return FALSE;
+
+ return TRUE;
+ }
+ else
+ return FALSE;
+}
+
+/* Mark all functions exported by this file so that we can later allocate
+ entries in .opd for them. */
+
+static bfd_boolean
+elf64_hppa_mark_exported_functions (struct elf_link_hash_entry *eh, void *data)
+{
+ struct elf64_hppa_link_hash_entry *hh = hppa_elf_hash_entry (eh);
+ struct bfd_link_info *info = (struct bfd_link_info *)data;
+ struct elf64_hppa_link_hash_table *hppa_info;
+
+ hppa_info = hppa_link_hash_table (info);
+ if (hppa_info == NULL)
+ return FALSE;
+
+ if (eh
+ && (eh->root.type == bfd_link_hash_defined
+ || eh->root.type == bfd_link_hash_defweak)
+ && eh->root.u.def.section->output_section != NULL
+ && eh->type == STT_FUNC)
+ {
+ if (! hppa_info->opd_sec
+ && ! get_opd (hppa_info->root.dynobj, info, hppa_info))
+ return FALSE;
+
+ hh->want_opd = 1;
+
+ /* Put a flag here for output_symbol_hook. */
+ hh->st_shndx = -1;
+ eh->needs_plt = 1;
+ }
+
+ return TRUE;
+}
+
+/* Allocate space for a DLT entry. */
+
+static bfd_boolean
+allocate_global_data_dlt (struct elf_link_hash_entry *eh, void *data)
+{
+ struct elf64_hppa_link_hash_entry *hh = hppa_elf_hash_entry (eh);
+ struct elf64_hppa_allocate_data *x = (struct elf64_hppa_allocate_data *)data;
+
+ if (hh->want_dlt)
+ {
+ if (x->info->shared)
+ {
+ /* Possibly add the symbol to the local dynamic symbol
+ table since we might need to create a dynamic relocation
+ against it. */
+ if (eh->dynindx == -1 && eh->type != STT_PARISC_MILLI)
+ {
+ bfd *owner = eh->root.u.def.section->owner;
+
+ if (! (bfd_elf_link_record_local_dynamic_symbol
+ (x->info, owner, hh->sym_indx)))
+ return FALSE;
+ }
+ }
+
+ hh->dlt_offset = x->ofs;
+ x->ofs += DLT_ENTRY_SIZE;
+ }
+ return TRUE;
+}
+
+/* Allocate space for a DLT.PLT entry. */
+
+static bfd_boolean
+allocate_global_data_plt (struct elf_link_hash_entry *eh, void *data)
+{
+ struct elf64_hppa_link_hash_entry *hh = hppa_elf_hash_entry (eh);
+ struct elf64_hppa_allocate_data *x = (struct elf64_hppa_allocate_data *) data;
+
+ if (hh->want_plt
+ && elf64_hppa_dynamic_symbol_p (eh, x->info)
+ && !((eh->root.type == bfd_link_hash_defined
+ || eh->root.type == bfd_link_hash_defweak)
+ && eh->root.u.def.section->output_section != NULL))
+ {
+ hh->plt_offset = x->ofs;
+ x->ofs += PLT_ENTRY_SIZE;
+ if (hh->plt_offset < 0x2000)
+ {
+ struct elf64_hppa_link_hash_table *hppa_info;
+
+ hppa_info = hppa_link_hash_table (x->info);
+ if (hppa_info == NULL)
+ return FALSE;
+
+ hppa_info->gp_offset = hh->plt_offset;
+ }
+ }
+ else
+ hh->want_plt = 0;
+
+ return TRUE;
+}
+
+/* Allocate space for a STUB entry. */
+
+static bfd_boolean
+allocate_global_data_stub (struct elf_link_hash_entry *eh, void *data)
+{
+ struct elf64_hppa_link_hash_entry *hh = hppa_elf_hash_entry (eh);
+ struct elf64_hppa_allocate_data *x = (struct elf64_hppa_allocate_data *)data;
+
+ if (hh->want_stub
+ && elf64_hppa_dynamic_symbol_p (eh, x->info)
+ && !((eh->root.type == bfd_link_hash_defined
+ || eh->root.type == bfd_link_hash_defweak)
+ && eh->root.u.def.section->output_section != NULL))
+ {
+ hh->stub_offset = x->ofs;
+ x->ofs += sizeof (plt_stub);
+ }
+ else
+ hh->want_stub = 0;
+ return TRUE;
+}
+
+/* Allocate space for a FPTR entry. */
+
+static bfd_boolean
+allocate_global_data_opd (struct elf_link_hash_entry *eh, void *data)
+{
+ struct elf64_hppa_link_hash_entry *hh = hppa_elf_hash_entry (eh);
+ struct elf64_hppa_allocate_data *x = (struct elf64_hppa_allocate_data *)data;
+
+ if (hh && hh->want_opd)
+ {
+ /* We never need an opd entry for a symbol which is not
+ defined by this output file. */
+ if (hh && (hh->eh.root.type == bfd_link_hash_undefined
+ || hh->eh.root.type == bfd_link_hash_undefweak
+ || hh->eh.root.u.def.section->output_section == NULL))
+ hh->want_opd = 0;
+
+ /* If we are creating a shared library, took the address of a local
+ function or might export this function from this object file, then
+ we have to create an opd descriptor. */
+ else if (x->info->shared
+ || hh == NULL
+ || (hh->eh.dynindx == -1 && hh->eh.type != STT_PARISC_MILLI)
+ || (hh->eh.root.type == bfd_link_hash_defined
+ || hh->eh.root.type == bfd_link_hash_defweak))
+ {
+ /* If we are creating a shared library, then we will have to
+ create a runtime relocation for the symbol to properly
+ initialize the .opd entry. Make sure the symbol gets
+ added to the dynamic symbol table. */
+ if (x->info->shared
+ && (hh == NULL || (hh->eh.dynindx == -1)))
+ {
+ bfd *owner;
+ /* PR 6511: Default to using the dynamic symbol table. */
+ owner = (hh->owner ? hh->owner: eh->root.u.def.section->owner);
+
+ if (!bfd_elf_link_record_local_dynamic_symbol
+ (x->info, owner, hh->sym_indx))
+ return FALSE;
+ }
+
+ /* This may not be necessary or desirable anymore now that
+ we have some support for dealing with section symbols
+ in dynamic relocs. But name munging does make the result
+ much easier to debug. ie, the EPLT reloc will reference
+ a symbol like .foobar, instead of .text + offset. */
+ if (x->info->shared && eh)
+ {
+ char *new_name;
+ struct elf_link_hash_entry *nh;
+
+ new_name = alloca (strlen (eh->root.root.string) + 2);
+ new_name[0] = '.';
+ strcpy (new_name + 1, eh->root.root.string);
+
+ nh = elf_link_hash_lookup (elf_hash_table (x->info),
+ new_name, TRUE, TRUE, TRUE);
+
+ nh->root.type = eh->root.type;
+ nh->root.u.def.value = eh->root.u.def.value;
+ nh->root.u.def.section = eh->root.u.def.section;
+
+ if (! bfd_elf_link_record_dynamic_symbol (x->info, nh))
+ return FALSE;
+
+ }
+ hh->opd_offset = x->ofs;
+ x->ofs += OPD_ENTRY_SIZE;
+ }
+
+ /* Otherwise we do not need an opd entry. */
+ else
+ hh->want_opd = 0;
+ }
+ return TRUE;
+}
+
+/* HP requires the EI_OSABI field to be filled in. The assignment to
+ EI_ABIVERSION may not be strictly necessary. */
+
+static void
+elf64_hppa_post_process_headers (bfd *abfd,
+ struct bfd_link_info *link_info ATTRIBUTE_UNUSED)
+{
+ Elf_Internal_Ehdr * i_ehdrp;
+
+ i_ehdrp = elf_elfheader (abfd);
+
+ i_ehdrp->e_ident[EI_OSABI] = get_elf_backend_data (abfd)->elf_osabi;
+ i_ehdrp->e_ident[EI_ABIVERSION] = 1;
+}
+
+/* Create function descriptor section (.opd). This section is called .opd
+ because it contains "official procedure descriptors". The "official"
+ refers to the fact that these descriptors are used when taking the address
+ of a procedure, thus ensuring a unique address for each procedure. */
+
+static bfd_boolean
+get_opd (bfd *abfd,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ struct elf64_hppa_link_hash_table *hppa_info)
+{
+ asection *opd;
+ bfd *dynobj;
+
+ opd = hppa_info->opd_sec;
+ if (!opd)
+ {
+ dynobj = hppa_info->root.dynobj;
+ if (!dynobj)
+ hppa_info->root.dynobj = dynobj = abfd;
+
+ opd = bfd_make_section_anyway_with_flags (dynobj, ".opd",
+ (SEC_ALLOC
+ | SEC_LOAD
+ | SEC_HAS_CONTENTS
+ | SEC_IN_MEMORY
+ | SEC_LINKER_CREATED));
+ if (!opd
+ || !bfd_set_section_alignment (abfd, opd, 3))
+ {
+ BFD_ASSERT (0);
+ return FALSE;
+ }
+
+ hppa_info->opd_sec = opd;
+ }
+
+ return TRUE;
+}
+
+/* Create the PLT section. */
+
+static bfd_boolean
+get_plt (bfd *abfd,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ struct elf64_hppa_link_hash_table *hppa_info)
+{
+ asection *plt;
+ bfd *dynobj;
+
+ plt = hppa_info->plt_sec;
+ if (!plt)
+ {
+ dynobj = hppa_info->root.dynobj;
+ if (!dynobj)
+ hppa_info->root.dynobj = dynobj = abfd;
+
+ plt = bfd_make_section_anyway_with_flags (dynobj, ".plt",
+ (SEC_ALLOC
+ | SEC_LOAD
+ | SEC_HAS_CONTENTS
+ | SEC_IN_MEMORY
+ | SEC_LINKER_CREATED));
+ if (!plt
+ || !bfd_set_section_alignment (abfd, plt, 3))
+ {
+ BFD_ASSERT (0);
+ return FALSE;
+ }
+
+ hppa_info->plt_sec = plt;
+ }
+
+ return TRUE;
+}
+
+/* Create the DLT section. */
+
+static bfd_boolean
+get_dlt (bfd *abfd,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ struct elf64_hppa_link_hash_table *hppa_info)
+{
+ asection *dlt;
+ bfd *dynobj;
+
+ dlt = hppa_info->dlt_sec;
+ if (!dlt)
+ {
+ dynobj = hppa_info->root.dynobj;
+ if (!dynobj)
+ hppa_info->root.dynobj = dynobj = abfd;
+
+ dlt = bfd_make_section_anyway_with_flags (dynobj, ".dlt",
+ (SEC_ALLOC
+ | SEC_LOAD
+ | SEC_HAS_CONTENTS
+ | SEC_IN_MEMORY
+ | SEC_LINKER_CREATED));
+ if (!dlt
+ || !bfd_set_section_alignment (abfd, dlt, 3))
+ {
+ BFD_ASSERT (0);
+ return FALSE;
+ }
+
+ hppa_info->dlt_sec = dlt;
+ }
+
+ return TRUE;
+}
+
+/* Create the stubs section. */
+
+static bfd_boolean
+get_stub (bfd *abfd,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ struct elf64_hppa_link_hash_table *hppa_info)
+{
+ asection *stub;
+ bfd *dynobj;
+
+ stub = hppa_info->stub_sec;
+ if (!stub)
+ {
+ dynobj = hppa_info->root.dynobj;
+ if (!dynobj)
+ hppa_info->root.dynobj = dynobj = abfd;
+
+ stub = bfd_make_section_anyway_with_flags (dynobj, ".stub",
+ (SEC_ALLOC | SEC_LOAD
+ | SEC_HAS_CONTENTS
+ | SEC_IN_MEMORY
+ | SEC_READONLY
+ | SEC_LINKER_CREATED));
+ if (!stub
+ || !bfd_set_section_alignment (abfd, stub, 3))
+ {
+ BFD_ASSERT (0);
+ return FALSE;
+ }
+
+ hppa_info->stub_sec = stub;
+ }
+
+ return TRUE;
+}
+
+/* Create sections necessary for dynamic linking. This is only a rough
+ cut and will likely change as we learn more about the somewhat
+ unusual dynamic linking scheme HP uses.
+
+ .stub:
+ Contains code to implement cross-space calls. The first time one
+ of the stubs is used it will call into the dynamic linker, later
+ calls will go straight to the target.
+
+ The only stub we support right now looks like
+
+ ldd OFFSET(%dp),%r1
+ bve %r0(%r1)
+ ldd OFFSET+8(%dp),%dp
+
+ Other stubs may be needed in the future. We may want the remove
+ the break/nop instruction. It is only used right now to keep the
+ offset of a .plt entry and a .stub entry in sync.
+
+ .dlt:
+ This is what most people call the .got. HP used a different name.
+ Losers.
+
+ .rela.dlt:
+ Relocations for the DLT.
+
+ .plt:
+ Function pointers as address,gp pairs.
+
+ .rela.plt:
+ Should contain dynamic IPLT (and EPLT?) relocations.
+
+ .opd:
+ FPTRS
+
+ .rela.opd:
+ EPLT relocations for symbols exported from shared libraries. */
+
+static bfd_boolean
+elf64_hppa_create_dynamic_sections (bfd *abfd,
+ struct bfd_link_info *info)
+{
+ asection *s;
+ struct elf64_hppa_link_hash_table *hppa_info;
+
+ hppa_info = hppa_link_hash_table (info);
+ if (hppa_info == NULL)
+ return FALSE;
+
+ if (! get_stub (abfd, info, hppa_info))
+ return FALSE;
+
+ if (! get_dlt (abfd, info, hppa_info))
+ return FALSE;
+
+ if (! get_plt (abfd, info, hppa_info))
+ return FALSE;
+
+ if (! get_opd (abfd, info, hppa_info))
+ return FALSE;
+
+ s = bfd_make_section_anyway_with_flags (abfd, ".rela.dlt",
+ (SEC_ALLOC | SEC_LOAD
+ | SEC_HAS_CONTENTS
+ | SEC_IN_MEMORY
+ | SEC_READONLY
+ | SEC_LINKER_CREATED));
+ if (s == NULL
+ || !bfd_set_section_alignment (abfd, s, 3))
+ return FALSE;
+ hppa_info->dlt_rel_sec = s;
+
+ s = bfd_make_section_anyway_with_flags (abfd, ".rela.plt",
+ (SEC_ALLOC | SEC_LOAD
+ | SEC_HAS_CONTENTS
+ | SEC_IN_MEMORY
+ | SEC_READONLY
+ | SEC_LINKER_CREATED));
+ if (s == NULL
+ || !bfd_set_section_alignment (abfd, s, 3))
+ return FALSE;
+ hppa_info->plt_rel_sec = s;
+
+ s = bfd_make_section_anyway_with_flags (abfd, ".rela.data",
+ (SEC_ALLOC | SEC_LOAD
+ | SEC_HAS_CONTENTS
+ | SEC_IN_MEMORY
+ | SEC_READONLY
+ | SEC_LINKER_CREATED));
+ if (s == NULL
+ || !bfd_set_section_alignment (abfd, s, 3))
+ return FALSE;
+ hppa_info->other_rel_sec = s;
+
+ s = bfd_make_section_anyway_with_flags (abfd, ".rela.opd",
+ (SEC_ALLOC | SEC_LOAD
+ | SEC_HAS_CONTENTS
+ | SEC_IN_MEMORY
+ | SEC_READONLY
+ | SEC_LINKER_CREATED));
+ if (s == NULL
+ || !bfd_set_section_alignment (abfd, s, 3))
+ return FALSE;
+ hppa_info->opd_rel_sec = s;
+
+ return TRUE;
+}
+
+/* Allocate dynamic relocations for those symbols that turned out
+ to be dynamic. */
+
+static bfd_boolean
+allocate_dynrel_entries (struct elf_link_hash_entry *eh, void *data)
+{
+ struct elf64_hppa_link_hash_entry *hh = hppa_elf_hash_entry (eh);
+ struct elf64_hppa_allocate_data *x = (struct elf64_hppa_allocate_data *)data;
+ struct elf64_hppa_link_hash_table *hppa_info;
+ struct elf64_hppa_dyn_reloc_entry *rent;
+ bfd_boolean dynamic_symbol, shared;
+
+ hppa_info = hppa_link_hash_table (x->info);
+ if (hppa_info == NULL)
+ return FALSE;
+
+ dynamic_symbol = elf64_hppa_dynamic_symbol_p (eh, x->info);
+ shared = x->info->shared;
+
+ /* We may need to allocate relocations for a non-dynamic symbol
+ when creating a shared library. */
+ if (!dynamic_symbol && !shared)
+ return TRUE;
+
+ /* Take care of the normal data relocations. */
+
+ for (rent = hh->reloc_entries; rent; rent = rent->next)
+ {
+ /* Allocate one iff we are building a shared library, the relocation
+ isn't a R_PARISC_FPTR64, or we don't want an opd entry. */
+ if (!shared && rent->type == R_PARISC_FPTR64 && hh->want_opd)
+ continue;
+
+ hppa_info->other_rel_sec->size += sizeof (Elf64_External_Rela);
+
+ /* Make sure this symbol gets into the dynamic symbol table if it is
+ not already recorded. ?!? This should not be in the loop since
+ the symbol need only be added once. */
+ if (eh->dynindx == -1 && eh->type != STT_PARISC_MILLI)
+ if (!bfd_elf_link_record_local_dynamic_symbol
+ (x->info, rent->sec->owner, hh->sym_indx))
+ return FALSE;
+ }
+
+ /* Take care of the GOT and PLT relocations. */
+
+ if ((dynamic_symbol || shared) && hh->want_dlt)
+ hppa_info->dlt_rel_sec->size += sizeof (Elf64_External_Rela);
+
+ /* If we are building a shared library, then every symbol that has an
+ opd entry will need an EPLT relocation to relocate the symbol's address
+ and __gp value based on the runtime load address. */
+ if (shared && hh->want_opd)
+ hppa_info->opd_rel_sec->size += sizeof (Elf64_External_Rela);
+
+ if (hh->want_plt && dynamic_symbol)
+ {
+ bfd_size_type t = 0;
+
+ /* Dynamic symbols get one IPLT relocation. Local symbols in
+ shared libraries get two REL relocations. Local symbols in
+ main applications get nothing. */
+ if (dynamic_symbol)
+ t = sizeof (Elf64_External_Rela);
+ else if (shared)
+ t = 2 * sizeof (Elf64_External_Rela);
+
+ hppa_info->plt_rel_sec->size += t;
+ }
+
+ return TRUE;
+}
+
+/* Adjust a symbol defined by a dynamic object and referenced by a
+ regular object. */
+
+static bfd_boolean
+elf64_hppa_adjust_dynamic_symbol (struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ struct elf_link_hash_entry *eh)
+{
+ /* ??? Undefined symbols with PLT entries should be re-defined
+ to be the PLT entry. */
+
+ /* 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 (eh->u.weakdef != NULL)
+ {
+ BFD_ASSERT (eh->u.weakdef->root.type == bfd_link_hash_defined
+ || eh->u.weakdef->root.type == bfd_link_hash_defweak);
+ eh->root.u.def.section = eh->u.weakdef->root.u.def.section;
+ eh->root.u.def.value = eh->u.weakdef->root.u.def.value;
+ return TRUE;
+ }
+
+ /* If this is a reference to a symbol defined by a dynamic object which
+ is not a function, we might allocate the symbol in our .dynbss section
+ and allocate a COPY dynamic relocation.
+
+ But PA64 code is canonically PIC, so as a rule we can avoid this sort
+ of hackery. */
+
+ return TRUE;
+}
+
+/* This function is called via elf_link_hash_traverse to mark millicode
+ symbols with a dynindx of -1 and to remove the string table reference
+ from the dynamic symbol table. If the symbol is not a millicode symbol,
+ elf64_hppa_mark_exported_functions is called. */
+
+static bfd_boolean
+elf64_hppa_mark_milli_and_exported_functions (struct elf_link_hash_entry *eh,
+ void *data)
+{
+ struct bfd_link_info *info = (struct bfd_link_info *) data;
+
+ if (eh->type == STT_PARISC_MILLI)
+ {
+ if (eh->dynindx != -1)
+ {
+ eh->dynindx = -1;
+ _bfd_elf_strtab_delref (elf_hash_table (info)->dynstr,
+ eh->dynstr_index);
+ }
+ return TRUE;
+ }
+
+ return elf64_hppa_mark_exported_functions (eh, data);
+}
+
+/* Set the final sizes of the dynamic sections and allocate memory for
+ the contents of our special sections. */
+
+static bfd_boolean
+elf64_hppa_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
+{
+ struct elf64_hppa_link_hash_table *hppa_info;
+ struct elf64_hppa_allocate_data data;
+ bfd *dynobj;
+ bfd *ibfd;
+ asection *sec;
+ bfd_boolean plt;
+ bfd_boolean relocs;
+ bfd_boolean reltext;
+
+ hppa_info = hppa_link_hash_table (info);
+ if (hppa_info == NULL)
+ return FALSE;
+
+ dynobj = elf_hash_table (info)->dynobj;
+ BFD_ASSERT (dynobj != NULL);
+
+ /* Mark each function this program exports so that we will allocate
+ space in the .opd section for each function's FPTR. If we are
+ creating dynamic sections, change the dynamic index of millicode
+ symbols to -1 and remove them from the string table for .dynstr.
+
+ We have to traverse the main linker hash table since we have to
+ find functions which may not have been mentioned in any relocs. */
+ elf_link_hash_traverse (elf_hash_table (info),
+ (elf_hash_table (info)->dynamic_sections_created
+ ? elf64_hppa_mark_milli_and_exported_functions
+ : elf64_hppa_mark_exported_functions),
+ info);
+
+ if (elf_hash_table (info)->dynamic_sections_created)
+ {
+ /* Set the contents of the .interp section to the interpreter. */
+ if (info->executable)
+ {
+ sec = bfd_get_linker_section (dynobj, ".interp");
+ BFD_ASSERT (sec != NULL);
+ sec->size = sizeof ELF_DYNAMIC_INTERPRETER;
+ sec->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.dlt,
+ which will cause it to get stripped from the output file
+ below. */
+ sec = bfd_get_linker_section (dynobj, ".rela.dlt");
+ if (sec != NULL)
+ sec->size = 0;
+ }
+
+ /* Set up DLT, PLT and OPD offsets for local syms, and space for local
+ dynamic relocs. */
+ for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next)
+ {
+ bfd_signed_vma *local_dlt;
+ bfd_signed_vma *end_local_dlt;
+ bfd_signed_vma *local_plt;
+ bfd_signed_vma *end_local_plt;
+ bfd_signed_vma *local_opd;
+ bfd_signed_vma *end_local_opd;
+ bfd_size_type locsymcount;
+ Elf_Internal_Shdr *symtab_hdr;
+ asection *srel;
+
+ if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour)
+ continue;
+
+ for (sec = ibfd->sections; sec != NULL; sec = sec->next)
+ {
+ struct elf64_hppa_dyn_reloc_entry *hdh_p;
+
+ for (hdh_p = ((struct elf64_hppa_dyn_reloc_entry *)
+ elf_section_data (sec)->local_dynrel);
+ hdh_p != NULL;
+ hdh_p = hdh_p->next)
+ {
+ if (!bfd_is_abs_section (hdh_p->sec)
+ && bfd_is_abs_section (hdh_p->sec->output_section))
+ {
+ /* Input section has been discarded, either because
+ it is a copy of a linkonce section or due to
+ linker script /DISCARD/, so we'll be discarding
+ the relocs too. */
+ }
+ else if (hdh_p->count != 0)
+ {
+ srel = elf_section_data (hdh_p->sec)->sreloc;
+ srel->size += hdh_p->count * sizeof (Elf64_External_Rela);
+ if ((hdh_p->sec->output_section->flags & SEC_READONLY) != 0)
+ info->flags |= DF_TEXTREL;
+ }
+ }
+ }
+
+ local_dlt = elf_local_got_refcounts (ibfd);
+ if (!local_dlt)
+ continue;
+
+ symtab_hdr = &elf_tdata (ibfd)->symtab_hdr;
+ locsymcount = symtab_hdr->sh_info;
+ end_local_dlt = local_dlt + locsymcount;
+ sec = hppa_info->dlt_sec;
+ srel = hppa_info->dlt_rel_sec;
+ for (; local_dlt < end_local_dlt; ++local_dlt)
+ {
+ if (*local_dlt > 0)
+ {
+ *local_dlt = sec->size;
+ sec->size += DLT_ENTRY_SIZE;
+ if (info->shared)
+ {
+ srel->size += sizeof (Elf64_External_Rela);
+ }
+ }
+ else
+ *local_dlt = (bfd_vma) -1;
+ }
+
+ local_plt = end_local_dlt;
+ end_local_plt = local_plt + locsymcount;
+ if (! hppa_info->root.dynamic_sections_created)
+ {
+ /* Won't be used, but be safe. */
+ for (; local_plt < end_local_plt; ++local_plt)
+ *local_plt = (bfd_vma) -1;
+ }
+ else
+ {
+ sec = hppa_info->plt_sec;
+ srel = hppa_info->plt_rel_sec;
+ for (; local_plt < end_local_plt; ++local_plt)
+ {
+ if (*local_plt > 0)
+ {
+ *local_plt = sec->size;
+ sec->size += PLT_ENTRY_SIZE;
+ if (info->shared)
+ srel->size += sizeof (Elf64_External_Rela);
+ }
+ else
+ *local_plt = (bfd_vma) -1;
+ }
+ }
+
+ local_opd = end_local_plt;
+ end_local_opd = local_opd + locsymcount;
+ if (! hppa_info->root.dynamic_sections_created)
+ {
+ /* Won't be used, but be safe. */
+ for (; local_opd < end_local_opd; ++local_opd)
+ *local_opd = (bfd_vma) -1;
+ }
+ else
+ {
+ sec = hppa_info->opd_sec;
+ srel = hppa_info->opd_rel_sec;
+ for (; local_opd < end_local_opd; ++local_opd)
+ {
+ if (*local_opd > 0)
+ {
+ *local_opd = sec->size;
+ sec->size += OPD_ENTRY_SIZE;
+ if (info->shared)
+ srel->size += sizeof (Elf64_External_Rela);
+ }
+ else
+ *local_opd = (bfd_vma) -1;
+ }
+ }
+ }
+
+ /* Allocate the GOT entries. */
+
+ data.info = info;
+ if (hppa_info->dlt_sec)
+ {
+ data.ofs = hppa_info->dlt_sec->size;
+ elf_link_hash_traverse (elf_hash_table (info),
+ allocate_global_data_dlt, &data);
+ hppa_info->dlt_sec->size = data.ofs;
+ }
+
+ if (hppa_info->plt_sec)
+ {
+ data.ofs = hppa_info->plt_sec->size;
+ elf_link_hash_traverse (elf_hash_table (info),
+ allocate_global_data_plt, &data);
+ hppa_info->plt_sec->size = data.ofs;
+ }
+
+ if (hppa_info->stub_sec)
+ {
+ data.ofs = 0x0;
+ elf_link_hash_traverse (elf_hash_table (info),
+ allocate_global_data_stub, &data);
+ hppa_info->stub_sec->size = data.ofs;
+ }
+
+ /* Allocate space for entries in the .opd section. */
+ if (hppa_info->opd_sec)
+ {
+ data.ofs = hppa_info->opd_sec->size;
+ elf_link_hash_traverse (elf_hash_table (info),
+ allocate_global_data_opd, &data);
+ hppa_info->opd_sec->size = data.ofs;
+ }
+
+ /* Now allocate space for dynamic relocations, if necessary. */
+ if (hppa_info->root.dynamic_sections_created)
+ elf_link_hash_traverse (elf_hash_table (info),
+ allocate_dynrel_entries, &data);
+
+ /* The sizes of all the sections are set. Allocate memory for them. */
+ plt = FALSE;
+ relocs = FALSE;
+ reltext = FALSE;
+ for (sec = dynobj->sections; sec != NULL; sec = sec->next)
+ {
+ const char *name;
+
+ if ((sec->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, sec);
+
+ if (strcmp (name, ".plt") == 0)
+ {
+ /* Remember whether there is a PLT. */
+ plt = sec->size != 0;
+ }
+ else if (strcmp (name, ".opd") == 0
+ || CONST_STRNEQ (name, ".dlt")
+ || strcmp (name, ".stub") == 0
+ || strcmp (name, ".got") == 0)
+ {
+ /* Strip this section if we don't need it; see the comment below. */
+ }
+ else if (CONST_STRNEQ (name, ".rela"))
+ {
+ if (sec->size != 0)
+ {
+ 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. The entries in the .rela.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,
+ sec->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. */
+ sec->reloc_count = 0;
+ }
+ }
+ else
+ {
+ /* It's not one of our sections, so don't allocate space. */
+ continue;
+ }
+
+ if (sec->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. */
+ sec->flags |= SEC_EXCLUDE;
+ continue;
+ }
+
+ if ((sec->flags & SEC_HAS_CONTENTS) == 0)
+ continue;
+
+ /* Allocate memory for the section contents if it has not
+ been allocated already. We use bfd_zalloc here in case
+ unused entries are not reclaimed before the section's
+ contents are written out. This should not happen, but this
+ way if it does, we get a R_PARISC_NONE reloc instead of
+ garbage. */
+ if (sec->contents == NULL)
+ {
+ sec->contents = (bfd_byte *) bfd_zalloc (dynobj, sec->size);
+ if (sec->contents == NULL)
+ return FALSE;
+ }
+ }
+
+ if (elf_hash_table (info)->dynamic_sections_created)
+ {
+ /* Always create a DT_PLTGOT. It actually has nothing to do with
+ the PLT, it is how we communicate the __gp value of a load
+ module to the dynamic linker. */
+#define add_dynamic_entry(TAG, VAL) \
+ _bfd_elf_add_dynamic_entry (info, TAG, VAL)
+
+ if (!add_dynamic_entry (DT_HP_DLD_FLAGS, 0)
+ || !add_dynamic_entry (DT_PLTGOT, 0))
+ return FALSE;
+
+ /* Add some entries to the .dynamic section. We fill in the
+ values later, in elf64_hppa_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 (!add_dynamic_entry (DT_DEBUG, 0)
+ || !add_dynamic_entry (DT_HP_DLD_HOOK, 0)
+ || !add_dynamic_entry (DT_HP_LOAD_MAP, 0))
+ return FALSE;
+ }
+
+ /* Force DT_FLAGS to always be set.
+ Required by HPUX 11.00 patch PHSS_26559. */
+ if (!add_dynamic_entry (DT_FLAGS, (info)->flags))
+ return FALSE;
+
+ if (plt)
+ {
+ if (!add_dynamic_entry (DT_PLTRELSZ, 0)
+ || !add_dynamic_entry (DT_PLTREL, DT_RELA)
+ || !add_dynamic_entry (DT_JMPREL, 0))
+ return FALSE;
+ }
+
+ if (relocs)
+ {
+ if (!add_dynamic_entry (DT_RELA, 0)
+ || !add_dynamic_entry (DT_RELASZ, 0)
+ || !add_dynamic_entry (DT_RELAENT, sizeof (Elf64_External_Rela)))
+ return FALSE;
+ }
+
+ if (reltext)
+ {
+ if (!add_dynamic_entry (DT_TEXTREL, 0))
+ return FALSE;
+ info->flags |= DF_TEXTREL;
+ }
+ }
+#undef add_dynamic_entry
+
+ return TRUE;
+}
+
+/* Called after we have output the symbol into the dynamic symbol
+ table, but before we output the symbol into the normal symbol
+ table.
+
+ For some symbols we had to change their address when outputting
+ the dynamic symbol table. We undo that change here so that
+ the symbols have their expected value in the normal symbol
+ table. Ick. */
+
+static int
+elf64_hppa_link_output_symbol_hook (struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ const char *name,
+ Elf_Internal_Sym *sym,
+ asection *input_sec ATTRIBUTE_UNUSED,
+ struct elf_link_hash_entry *eh)
+{
+ struct elf64_hppa_link_hash_entry *hh = hppa_elf_hash_entry (eh);
+
+ /* We may be called with the file symbol or section symbols.
+ They never need munging, so it is safe to ignore them. */
+ if (!name || !eh)
+ return 1;
+
+ /* Function symbols for which we created .opd entries *may* have been
+ munged by finish_dynamic_symbol and have to be un-munged here.
+
+ Note that finish_dynamic_symbol sometimes turns dynamic symbols
+ into non-dynamic ones, so we initialize st_shndx to -1 in
+ mark_exported_functions and check to see if it was overwritten
+ here instead of just checking eh->dynindx. */
+ if (hh->want_opd && hh->st_shndx != -1)
+ {
+ /* Restore the saved value and section index. */
+ sym->st_value = hh->st_value;
+ sym->st_shndx = hh->st_shndx;
+ }
+
+ return 1;
+}
+
+/* Finish up dynamic symbol handling. We set the contents of various
+ dynamic sections here. */
+
+static bfd_boolean
+elf64_hppa_finish_dynamic_symbol (bfd *output_bfd,
+ struct bfd_link_info *info,
+ struct elf_link_hash_entry *eh,
+ Elf_Internal_Sym *sym)
+{
+ struct elf64_hppa_link_hash_entry *hh = hppa_elf_hash_entry (eh);
+ asection *stub, *splt, *sopd, *spltrel;
+ struct elf64_hppa_link_hash_table *hppa_info;
+
+ hppa_info = hppa_link_hash_table (info);
+ if (hppa_info == NULL)
+ return FALSE;
+
+ stub = hppa_info->stub_sec;
+ splt = hppa_info->plt_sec;
+ sopd = hppa_info->opd_sec;
+ spltrel = hppa_info->plt_rel_sec;
+
+ /* Incredible. It is actually necessary to NOT use the symbol's real
+ value when building the dynamic symbol table for a shared library.
+ At least for symbols that refer to functions.
+
+ We will store a new value and section index into the symbol long
+ enough to output it into the dynamic symbol table, then we restore
+ the original values (in elf64_hppa_link_output_symbol_hook). */
+ if (hh->want_opd)
+ {
+ BFD_ASSERT (sopd != NULL);
+
+ /* Save away the original value and section index so that we
+ can restore them later. */
+ hh->st_value = sym->st_value;
+ hh->st_shndx = sym->st_shndx;
+
+ /* For the dynamic symbol table entry, we want the value to be
+ address of this symbol's entry within the .opd section. */
+ sym->st_value = (hh->opd_offset
+ + sopd->output_offset
+ + sopd->output_section->vma);
+ sym->st_shndx = _bfd_elf_section_from_bfd_section (output_bfd,
+ sopd->output_section);
+ }
+
+ /* Initialize a .plt entry if requested. */
+ if (hh->want_plt
+ && elf64_hppa_dynamic_symbol_p (eh, info))
+ {
+ bfd_vma value;
+ Elf_Internal_Rela rel;
+ bfd_byte *loc;
+
+ BFD_ASSERT (splt != NULL && spltrel != NULL);
+
+ /* We do not actually care about the value in the PLT entry
+ if we are creating a shared library and the symbol is
+ still undefined, we create a dynamic relocation to fill
+ in the correct value. */
+ if (info->shared && eh->root.type == bfd_link_hash_undefined)
+ value = 0;
+ else
+ value = (eh->root.u.def.value + eh->root.u.def.section->vma);
+
+ /* Fill in the entry in the procedure linkage table.
+
+ The format of a plt entry is
+ <funcaddr> <__gp>.
+
+ plt_offset is the offset within the PLT section at which to
+ install the PLT entry.
+
+ We are modifying the in-memory PLT contents here, so we do not add
+ in the output_offset of the PLT section. */
+
+ bfd_put_64 (splt->owner, value, splt->contents + hh->plt_offset);
+ value = _bfd_get_gp_value (splt->output_section->owner);
+ bfd_put_64 (splt->owner, value, splt->contents + hh->plt_offset + 0x8);
+
+ /* Create a dynamic IPLT relocation for this entry.
+
+ We are creating a relocation in the output file's PLT section,
+ which is included within the DLT secton. So we do need to include
+ the PLT's output_offset in the computation of the relocation's
+ address. */
+ rel.r_offset = (hh->plt_offset + splt->output_offset
+ + splt->output_section->vma);
+ rel.r_info = ELF64_R_INFO (hh->eh.dynindx, R_PARISC_IPLT);
+ rel.r_addend = 0;
+
+ loc = spltrel->contents;
+ loc += spltrel->reloc_count++ * sizeof (Elf64_External_Rela);
+ bfd_elf64_swap_reloca_out (splt->output_section->owner, &rel, loc);
+ }
+
+ /* Initialize an external call stub entry if requested. */
+ if (hh->want_stub
+ && elf64_hppa_dynamic_symbol_p (eh, info))
+ {
+ bfd_vma value;
+ int insn;
+ unsigned int max_offset;
+
+ BFD_ASSERT (stub != NULL);
+
+ /* Install the generic stub template.
+
+ We are modifying the contents of the stub section, so we do not
+ need to include the stub section's output_offset here. */
+ memcpy (stub->contents + hh->stub_offset, plt_stub, sizeof (plt_stub));
+
+ /* Fix up the first ldd instruction.
+
+ We are modifying the contents of the STUB section in memory,
+ so we do not need to include its output offset in this computation.
+
+ Note the plt_offset value is the value of the PLT entry relative to
+ the start of the PLT section. These instructions will reference
+ data relative to the value of __gp, which may not necessarily have
+ the same address as the start of the PLT section.
+
+ gp_offset contains the offset of __gp within the PLT section. */
+ value = hh->plt_offset - hppa_info->gp_offset;
+
+ insn = bfd_get_32 (stub->owner, stub->contents + hh->stub_offset);
+ if (output_bfd->arch_info->mach >= 25)
+ {
+ /* Wide mode allows 16 bit offsets. */
+ max_offset = 32768;
+ insn &= ~ 0xfff1;
+ insn |= re_assemble_16 ((int) value);
+ }
+ else
+ {
+ max_offset = 8192;
+ insn &= ~ 0x3ff1;
+ insn |= re_assemble_14 ((int) value);
+ }
+
+ if ((value & 7) || value + max_offset >= 2*max_offset - 8)
+ {
+ (*_bfd_error_handler) (_("stub entry for %s cannot load .plt, dp offset = %ld"),
+ hh->eh.root.root.string,
+ (long) value);
+ return FALSE;
+ }
+
+ bfd_put_32 (stub->owner, (bfd_vma) insn,
+ stub->contents + hh->stub_offset);
+
+ /* Fix up the second ldd instruction. */
+ value += 8;
+ insn = bfd_get_32 (stub->owner, stub->contents + hh->stub_offset + 8);
+ if (output_bfd->arch_info->mach >= 25)
+ {
+ insn &= ~ 0xfff1;
+ insn |= re_assemble_16 ((int) value);
+ }
+ else
+ {
+ insn &= ~ 0x3ff1;
+ insn |= re_assemble_14 ((int) value);
+ }
+ bfd_put_32 (stub->owner, (bfd_vma) insn,
+ stub->contents + hh->stub_offset + 8);
+ }
+
+ return TRUE;
+}
+
+/* The .opd section contains FPTRs for each function this file
+ exports. Initialize the FPTR entries. */
+
+static bfd_boolean
+elf64_hppa_finalize_opd (struct elf_link_hash_entry *eh, void *data)
+{
+ struct elf64_hppa_link_hash_entry *hh = hppa_elf_hash_entry (eh);
+ struct bfd_link_info *info = (struct bfd_link_info *)data;
+ struct elf64_hppa_link_hash_table *hppa_info;
+ asection *sopd;
+ asection *sopdrel;
+
+ hppa_info = hppa_link_hash_table (info);
+ if (hppa_info == NULL)
+ return FALSE;
+
+ sopd = hppa_info->opd_sec;
+ sopdrel = hppa_info->opd_rel_sec;
+
+ if (hh->want_opd)
+ {
+ bfd_vma value;
+
+ /* The first two words of an .opd entry are zero.
+
+ We are modifying the contents of the OPD section in memory, so we
+ do not need to include its output offset in this computation. */
+ memset (sopd->contents + hh->opd_offset, 0, 16);
+
+ value = (eh->root.u.def.value
+ + eh->root.u.def.section->output_section->vma
+ + eh->root.u.def.section->output_offset);
+
+ /* The next word is the address of the function. */
+ bfd_put_64 (sopd->owner, value, sopd->contents + hh->opd_offset + 16);
+
+ /* The last word is our local __gp value. */
+ value = _bfd_get_gp_value (sopd->output_section->owner);
+ bfd_put_64 (sopd->owner, value, sopd->contents + hh->opd_offset + 24);
+ }
+
+ /* If we are generating a shared library, we must generate EPLT relocations
+ for each entry in the .opd, even for static functions (they may have
+ had their address taken). */
+ if (info->shared && hh->want_opd)
+ {
+ Elf_Internal_Rela rel;
+ bfd_byte *loc;
+ int dynindx;
+
+ /* We may need to do a relocation against a local symbol, in
+ which case we have to look up it's dynamic symbol index off
+ the local symbol hash table. */
+ if (eh->dynindx != -1)
+ dynindx = eh->dynindx;
+ else
+ dynindx
+ = _bfd_elf_link_lookup_local_dynindx (info, hh->owner,
+ hh->sym_indx);
+
+ /* The offset of this relocation is the absolute address of the
+ .opd entry for this symbol. */
+ rel.r_offset = (hh->opd_offset + sopd->output_offset
+ + sopd->output_section->vma);
+
+ /* If H is non-null, then we have an external symbol.
+
+ It is imperative that we use a different dynamic symbol for the
+ EPLT relocation if the symbol has global scope.
+
+ In the dynamic symbol table, the function symbol will have a value
+ which is address of the function's .opd entry.
+
+ Thus, we can not use that dynamic symbol for the EPLT relocation
+ (if we did, the data in the .opd would reference itself rather
+ than the actual address of the function). Instead we have to use
+ a new dynamic symbol which has the same value as the original global
+ function symbol.
+
+ We prefix the original symbol with a "." and use the new symbol in
+ the EPLT relocation. This new symbol has already been recorded in
+ the symbol table, we just have to look it up and use it.
+
+ We do not have such problems with static functions because we do
+ not make their addresses in the dynamic symbol table point to
+ the .opd entry. Ultimately this should be safe since a static
+ function can not be directly referenced outside of its shared
+ library.
+
+ We do have to play similar games for FPTR relocations in shared
+ libraries, including those for static symbols. See the FPTR
+ handling in elf64_hppa_finalize_dynreloc. */
+ if (eh)
+ {
+ char *new_name;
+ struct elf_link_hash_entry *nh;
+
+ new_name = alloca (strlen (eh->root.root.string) + 2);
+ new_name[0] = '.';
+ strcpy (new_name + 1, eh->root.root.string);
+
+ nh = elf_link_hash_lookup (elf_hash_table (info),
+ new_name, TRUE, TRUE, FALSE);
+
+ /* All we really want from the new symbol is its dynamic
+ symbol index. */
+ if (nh)
+ dynindx = nh->dynindx;
+ }
+
+ rel.r_addend = 0;
+ rel.r_info = ELF64_R_INFO (dynindx, R_PARISC_EPLT);
+
+ loc = sopdrel->contents;
+ loc += sopdrel->reloc_count++ * sizeof (Elf64_External_Rela);
+ bfd_elf64_swap_reloca_out (sopd->output_section->owner, &rel, loc);
+ }
+ return TRUE;
+}
+
+/* The .dlt section contains addresses for items referenced through the
+ dlt. Note that we can have a DLTIND relocation for a local symbol, thus
+ we can not depend on finish_dynamic_symbol to initialize the .dlt. */
+
+static bfd_boolean
+elf64_hppa_finalize_dlt (struct elf_link_hash_entry *eh, void *data)
+{
+ struct elf64_hppa_link_hash_entry *hh = hppa_elf_hash_entry (eh);
+ struct bfd_link_info *info = (struct bfd_link_info *)data;
+ struct elf64_hppa_link_hash_table *hppa_info;
+ asection *sdlt, *sdltrel;
+
+ hppa_info = hppa_link_hash_table (info);
+ if (hppa_info == NULL)
+ return FALSE;
+
+ sdlt = hppa_info->dlt_sec;
+ sdltrel = hppa_info->dlt_rel_sec;
+
+ /* H/DYN_H may refer to a local variable and we know it's
+ address, so there is no need to create a relocation. Just install
+ the proper value into the DLT, note this shortcut can not be
+ skipped when building a shared library. */
+ if (! info->shared && hh && hh->want_dlt)
+ {
+ bfd_vma value;
+
+ /* If we had an LTOFF_FPTR style relocation we want the DLT entry
+ to point to the FPTR entry in the .opd section.
+
+ We include the OPD's output offset in this computation as
+ we are referring to an absolute address in the resulting
+ object file. */
+ if (hh->want_opd)
+ {
+ value = (hh->opd_offset
+ + hppa_info->opd_sec->output_offset
+ + hppa_info->opd_sec->output_section->vma);
+ }
+ else if ((eh->root.type == bfd_link_hash_defined
+ || eh->root.type == bfd_link_hash_defweak)
+ && eh->root.u.def.section)
+ {
+ value = eh->root.u.def.value + eh->root.u.def.section->output_offset;
+ if (eh->root.u.def.section->output_section)
+ value += eh->root.u.def.section->output_section->vma;
+ else
+ value += eh->root.u.def.section->vma;
+ }
+ else
+ /* We have an undefined function reference. */
+ value = 0;
+
+ /* We do not need to include the output offset of the DLT section
+ here because we are modifying the in-memory contents. */
+ bfd_put_64 (sdlt->owner, value, sdlt->contents + hh->dlt_offset);
+ }
+
+ /* Create a relocation for the DLT entry associated with this symbol.
+ When building a shared library the symbol does not have to be dynamic. */
+ if (hh->want_dlt
+ && (elf64_hppa_dynamic_symbol_p (eh, info) || info->shared))
+ {
+ Elf_Internal_Rela rel;
+ bfd_byte *loc;
+ int dynindx;
+
+ /* We may need to do a relocation against a local symbol, in
+ which case we have to look up it's dynamic symbol index off
+ the local symbol hash table. */
+ if (eh && eh->dynindx != -1)
+ dynindx = eh->dynindx;
+ else
+ dynindx
+ = _bfd_elf_link_lookup_local_dynindx (info, hh->owner,
+ hh->sym_indx);
+
+ /* Create a dynamic relocation for this entry. Do include the output
+ offset of the DLT entry since we need an absolute address in the
+ resulting object file. */
+ rel.r_offset = (hh->dlt_offset + sdlt->output_offset
+ + sdlt->output_section->vma);
+ if (eh && eh->type == STT_FUNC)
+ rel.r_info = ELF64_R_INFO (dynindx, R_PARISC_FPTR64);
+ else
+ rel.r_info = ELF64_R_INFO (dynindx, R_PARISC_DIR64);
+ rel.r_addend = 0;
+
+ loc = sdltrel->contents;
+ loc += sdltrel->reloc_count++ * sizeof (Elf64_External_Rela);
+ bfd_elf64_swap_reloca_out (sdlt->output_section->owner, &rel, loc);
+ }
+ return TRUE;
+}
+
+/* Finalize the dynamic relocations. Specifically the FPTR relocations
+ for dynamic functions used to initialize static data. */
+
+static bfd_boolean
+elf64_hppa_finalize_dynreloc (struct elf_link_hash_entry *eh,
+ void *data)
+{
+ struct elf64_hppa_link_hash_entry *hh = hppa_elf_hash_entry (eh);
+ struct bfd_link_info *info = (struct bfd_link_info *)data;
+ struct elf64_hppa_link_hash_table *hppa_info;
+ int dynamic_symbol;
+
+ dynamic_symbol = elf64_hppa_dynamic_symbol_p (eh, info);
+
+ if (!dynamic_symbol && !info->shared)
+ return TRUE;
+
+ if (hh->reloc_entries)
+ {
+ struct elf64_hppa_dyn_reloc_entry *rent;
+ int dynindx;
+
+ hppa_info = hppa_link_hash_table (info);
+ if (hppa_info == NULL)
+ return FALSE;
+
+ /* We may need to do a relocation against a local symbol, in
+ which case we have to look up it's dynamic symbol index off
+ the local symbol hash table. */
+ if (eh->dynindx != -1)
+ dynindx = eh->dynindx;
+ else
+ dynindx
+ = _bfd_elf_link_lookup_local_dynindx (info, hh->owner,
+ hh->sym_indx);
+
+ for (rent = hh->reloc_entries; rent; rent = rent->next)
+ {
+ Elf_Internal_Rela rel;
+ bfd_byte *loc;
+
+ /* Allocate one iff we are building a shared library, the relocation
+ isn't a R_PARISC_FPTR64, or we don't want an opd entry. */
+ if (!info->shared && rent->type == R_PARISC_FPTR64 && hh->want_opd)
+ continue;
+
+ /* Create a dynamic relocation for this entry.
+
+ We need the output offset for the reloc's section because
+ we are creating an absolute address in the resulting object
+ file. */
+ rel.r_offset = (rent->offset + rent->sec->output_offset
+ + rent->sec->output_section->vma);
+
+ /* An FPTR64 relocation implies that we took the address of
+ a function and that the function has an entry in the .opd
+ section. We want the FPTR64 relocation to reference the
+ entry in .opd.
+
+ We could munge the symbol value in the dynamic symbol table
+ (in fact we already do for functions with global scope) to point
+ to the .opd entry. Then we could use that dynamic symbol in
+ this relocation.
+
+ Or we could do something sensible, not munge the symbol's
+ address and instead just use a different symbol to reference
+ the .opd entry. At least that seems sensible until you
+ realize there's no local dynamic symbols we can use for that
+ purpose. Thus the hair in the check_relocs routine.
+
+ We use a section symbol recorded by check_relocs as the
+ base symbol for the relocation. The addend is the difference
+ between the section symbol and the address of the .opd entry. */
+ if (info->shared && rent->type == R_PARISC_FPTR64 && hh->want_opd)
+ {
+ bfd_vma value, value2;
+
+ /* First compute the address of the opd entry for this symbol. */
+ value = (hh->opd_offset
+ + hppa_info->opd_sec->output_section->vma
+ + hppa_info->opd_sec->output_offset);
+
+ /* Compute the value of the start of the section with
+ the relocation. */
+ value2 = (rent->sec->output_section->vma
+ + rent->sec->output_offset);
+
+ /* Compute the difference between the start of the section
+ with the relocation and the opd entry. */
+ value -= value2;
+
+ /* The result becomes the addend of the relocation. */
+ rel.r_addend = value;
+
+ /* The section symbol becomes the symbol for the dynamic
+ relocation. */
+ dynindx
+ = _bfd_elf_link_lookup_local_dynindx (info,
+ rent->sec->owner,
+ rent->sec_symndx);
+ }
+ else
+ rel.r_addend = rent->addend;
+
+ rel.r_info = ELF64_R_INFO (dynindx, rent->type);
+
+ loc = hppa_info->other_rel_sec->contents;
+ loc += (hppa_info->other_rel_sec->reloc_count++
+ * sizeof (Elf64_External_Rela));
+ bfd_elf64_swap_reloca_out (hppa_info->other_rel_sec->output_section->owner,
+ &rel, loc);
+ }
+ }
+
+ return TRUE;
+}
+
+/* Used to decide how to sort relocs in an optimal manner for the
+ dynamic linker, before writing them out. */
+
+static enum elf_reloc_type_class
+elf64_hppa_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ const asection *rel_sec ATTRIBUTE_UNUSED,
+ const Elf_Internal_Rela *rela)
+{
+ if (ELF64_R_SYM (rela->r_info) == STN_UNDEF)
+ return reloc_class_relative;
+
+ switch ((int) ELF64_R_TYPE (rela->r_info))
+ {
+ case R_PARISC_IPLT:
+ return reloc_class_plt;
+ case R_PARISC_COPY:
+ return reloc_class_copy;
+ default:
+ return reloc_class_normal;
+ }
+}
+
+/* Finish up the dynamic sections. */
+
+static bfd_boolean
+elf64_hppa_finish_dynamic_sections (bfd *output_bfd,
+ struct bfd_link_info *info)
+{
+ bfd *dynobj;
+ asection *sdyn;
+ struct elf64_hppa_link_hash_table *hppa_info;
+
+ hppa_info = hppa_link_hash_table (info);
+ if (hppa_info == NULL)
+ return FALSE;
+
+ /* Finalize the contents of the .opd section. */
+ elf_link_hash_traverse (elf_hash_table (info),
+ elf64_hppa_finalize_opd,
+ info);
+
+ elf_link_hash_traverse (elf_hash_table (info),
+ elf64_hppa_finalize_dynreloc,
+ info);
+
+ /* Finalize the contents of the .dlt section. */
+ dynobj = elf_hash_table (info)->dynobj;
+ /* Finalize the contents of the .dlt section. */
+ elf_link_hash_traverse (elf_hash_table (info),
+ elf64_hppa_finalize_dlt,
+ info);
+
+ sdyn = bfd_get_linker_section (dynobj, ".dynamic");
+
+ if (elf_hash_table (info)->dynamic_sections_created)
+ {
+ Elf64_External_Dyn *dyncon, *dynconend;
+
+ BFD_ASSERT (sdyn != NULL);
+
+ dyncon = (Elf64_External_Dyn *) sdyn->contents;
+ dynconend = (Elf64_External_Dyn *) (sdyn->contents + sdyn->size);
+ for (; dyncon < dynconend; dyncon++)
+ {
+ Elf_Internal_Dyn dyn;
+ asection *s;
+
+ bfd_elf64_swap_dyn_in (dynobj, dyncon, &dyn);
+
+ switch (dyn.d_tag)
+ {
+ default:
+ break;
+
+ case DT_HP_LOAD_MAP:
+ /* Compute the absolute address of 16byte scratchpad area
+ for the dynamic linker.
+
+ By convention the linker script will allocate the scratchpad
+ area at the start of the .data section. So all we have to
+ to is find the start of the .data section. */
+ s = bfd_get_section_by_name (output_bfd, ".data");
+ if (!s)
+ return FALSE;
+ dyn.d_un.d_ptr = s->vma;
+ bfd_elf64_swap_dyn_out (output_bfd, &dyn, dyncon);
+ break;
+
+ case DT_PLTGOT:
+ /* HP's use PLTGOT to set the GOT register. */
+ dyn.d_un.d_ptr = _bfd_get_gp_value (output_bfd);
+ bfd_elf64_swap_dyn_out (output_bfd, &dyn, dyncon);
+ break;
+
+ case DT_JMPREL:
+ s = hppa_info->plt_rel_sec;
+ dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
+ bfd_elf64_swap_dyn_out (output_bfd, &dyn, dyncon);
+ break;
+
+ case DT_PLTRELSZ:
+ s = hppa_info->plt_rel_sec;
+ dyn.d_un.d_val = s->size;
+ bfd_elf64_swap_dyn_out (output_bfd, &dyn, dyncon);
+ break;
+
+ case DT_RELA:
+ s = hppa_info->other_rel_sec;
+ if (! s || ! s->size)
+ s = hppa_info->dlt_rel_sec;
+ if (! s || ! s->size)
+ s = hppa_info->opd_rel_sec;
+ dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
+ bfd_elf64_swap_dyn_out (output_bfd, &dyn, dyncon);
+ break;
+
+ case DT_RELASZ:
+ s = hppa_info->other_rel_sec;
+ dyn.d_un.d_val = s->size;
+ s = hppa_info->dlt_rel_sec;
+ dyn.d_un.d_val += s->size;
+ s = hppa_info->opd_rel_sec;
+ dyn.d_un.d_val += s->size;
+ /* There is some question about whether or not the size of
+ the PLT relocs should be included here. HP's tools do
+ it, so we'll emulate them. */
+ s = hppa_info->plt_rel_sec;
+ dyn.d_un.d_val += s->size;
+ bfd_elf64_swap_dyn_out (output_bfd, &dyn, dyncon);
+ break;
+
+ }
+ }
+ }
+
+ return TRUE;
+}
+
+/* Support for core dump NOTE sections. */
+
+static bfd_boolean
+elf64_hppa_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
+{
+ int offset;
+ size_t size;
+
+ switch (note->descsz)
+ {
+ default:
+ return FALSE;
+
+ case 760: /* Linux/hppa */
+ /* pr_cursig */
+ elf_tdata (abfd)->core->signal = bfd_get_16 (abfd, note->descdata + 12);
+
+ /* pr_pid */
+ elf_tdata (abfd)->core->lwpid = bfd_get_32 (abfd, note->descdata + 32);
+
+ /* pr_reg */
+ offset = 112;
+ size = 640;
+
+ break;
+ }
+
+ /* Make a ".reg/999" section. */
+ return _bfd_elfcore_make_pseudosection (abfd, ".reg",
+ size, note->descpos + offset);
+}
+
+static bfd_boolean
+elf64_hppa_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
+{
+ char * command;
+ int n;
+
+ switch (note->descsz)
+ {
+ default:
+ return FALSE;
+
+ case 136: /* Linux/hppa elf_prpsinfo. */
+ elf_tdata (abfd)->core->program
+ = _bfd_elfcore_strndup (abfd, note->descdata + 40, 16);
+ elf_tdata (abfd)->core->command
+ = _bfd_elfcore_strndup (abfd, note->descdata + 56, 80);
+ }
+
+ /* 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. */
+ command = elf_tdata (abfd)->core->command;
+ n = strlen (command);
+
+ if (0 < n && command[n - 1] == ' ')
+ command[n - 1] = '\0';
+
+ return TRUE;
+}
+
+/* Return the number of additional phdrs we will need.
+
+ The generic ELF code only creates PT_PHDRs for executables. The HP
+ dynamic linker requires PT_PHDRs for dynamic libraries too.
+
+ This routine indicates that the backend needs one additional program
+ header for that case.
+
+ Note we do not have access to the link info structure here, so we have
+ to guess whether or not we are building a shared library based on the
+ existence of a .interp section. */
+
+static int
+elf64_hppa_additional_program_headers (bfd *abfd,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED)
+{
+ asection *s;
+
+ /* If we are creating a shared library, then we have to create a
+ PT_PHDR segment. HP's dynamic linker chokes without it. */
+ s = bfd_get_section_by_name (abfd, ".interp");
+ if (! s)
+ return 1;
+ return 0;
+}
+
+/* Allocate and initialize any program headers required by this
+ specific backend.
+
+ The generic ELF code only creates PT_PHDRs for executables. The HP
+ dynamic linker requires PT_PHDRs for dynamic libraries too.
+
+ This allocates the PT_PHDR and initializes it in a manner suitable
+ for the HP linker.
+
+ Note we do not have access to the link info structure here, so we have
+ to guess whether or not we are building a shared library based on the
+ existence of a .interp section. */
+
+static bfd_boolean
+elf64_hppa_modify_segment_map (bfd *abfd,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED)
+{
+ struct elf_segment_map *m;
+ asection *s;
+
+ s = bfd_get_section_by_name (abfd, ".interp");
+ if (! s)
+ {
+ for (m = elf_seg_map (abfd); m != NULL; m = m->next)
+ if (m->p_type == PT_PHDR)
+ break;
+ if (m == NULL)
+ {
+ m = ((struct elf_segment_map *)
+ bfd_zalloc (abfd, (bfd_size_type) sizeof *m));
+ if (m == NULL)
+ return FALSE;
+
+ m->p_type = PT_PHDR;
+ m->p_flags = PF_R | PF_X;
+ m->p_flags_valid = 1;
+ m->p_paddr_valid = 1;
+ m->includes_phdrs = 1;
+
+ m->next = elf_seg_map (abfd);
+ elf_seg_map (abfd) = m;
+ }
+ }
+
+ for (m = elf_seg_map (abfd); m != NULL; m = m->next)
+ if (m->p_type == PT_LOAD)
+ {
+ unsigned int i;
+
+ for (i = 0; i < m->count; i++)
+ {
+ /* The code "hint" is not really a hint. It is a requirement
+ for certain versions of the HP dynamic linker. Worse yet,
+ it must be set even if the shared library does not have
+ any code in its "text" segment (thus the check for .hash
+ to catch this situation). */
+ if (m->sections[i]->flags & SEC_CODE
+ || (strcmp (m->sections[i]->name, ".hash") == 0))
+ m->p_flags |= (PF_X | PF_HP_CODE);
+ }
+ }
+
+ return TRUE;
+}
+
+/* Called when writing out an object file to decide the type of a
+ symbol. */
+static int
+elf64_hppa_elf_get_symbol_type (Elf_Internal_Sym *elf_sym,
+ int type)
+{
+ if (ELF_ST_TYPE (elf_sym->st_info) == STT_PARISC_MILLI)
+ return STT_PARISC_MILLI;
+ else
+ return type;
+}
+
+/* Support HP specific sections for core files. */
+
+static bfd_boolean
+elf64_hppa_section_from_phdr (bfd *abfd, Elf_Internal_Phdr *hdr, int sec_index,
+ const char *typename)
+{
+ if (hdr->p_type == PT_HP_CORE_KERNEL)
+ {
+ asection *sect;
+
+ if (!_bfd_elf_make_section_from_phdr (abfd, hdr, sec_index, typename))
+ return FALSE;
+
+ sect = bfd_make_section_anyway (abfd, ".kernel");
+ if (sect == NULL)
+ return FALSE;
+ sect->size = hdr->p_filesz;
+ sect->filepos = hdr->p_offset;
+ sect->flags = SEC_HAS_CONTENTS | SEC_READONLY;
+ return TRUE;
+ }
+
+ if (hdr->p_type == PT_HP_CORE_PROC)
+ {
+ int sig;
+
+ if (bfd_seek (abfd, hdr->p_offset, SEEK_SET) != 0)
+ return FALSE;
+ if (bfd_bread (&sig, 4, abfd) != 4)
+ return FALSE;
+
+ elf_tdata (abfd)->core->signal = sig;
+
+ if (!_bfd_elf_make_section_from_phdr (abfd, hdr, sec_index, typename))
+ return FALSE;
+
+ /* GDB uses the ".reg" section to read register contents. */
+ return _bfd_elfcore_make_pseudosection (abfd, ".reg", hdr->p_filesz,
+ hdr->p_offset);
+ }
+
+ if (hdr->p_type == PT_HP_CORE_LOADABLE
+ || hdr->p_type == PT_HP_CORE_STACK
+ || hdr->p_type == PT_HP_CORE_MMF)
+ hdr->p_type = PT_LOAD;
+
+ return _bfd_elf_make_section_from_phdr (abfd, hdr, sec_index, typename);
+}
+
+/* Hook called by the linker routine which adds symbols from an object
+ file. HP's libraries define symbols with HP specific section
+ indices, which we have to handle. */
+
+static bfd_boolean
+elf_hppa_add_symbol_hook (bfd *abfd,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ Elf_Internal_Sym *sym,
+ const char **namep ATTRIBUTE_UNUSED,
+ flagword *flagsp ATTRIBUTE_UNUSED,
+ asection **secp,
+ bfd_vma *valp)
+{
+ unsigned int sec_index = sym->st_shndx;
+
+ switch (sec_index)
+ {
+ case SHN_PARISC_ANSI_COMMON:
+ *secp = bfd_make_section_old_way (abfd, ".PARISC.ansi.common");
+ (*secp)->flags |= SEC_IS_COMMON;
+ *valp = sym->st_size;
+ break;
+
+ case SHN_PARISC_HUGE_COMMON:
+ *secp = bfd_make_section_old_way (abfd, ".PARISC.huge.common");
+ (*secp)->flags |= SEC_IS_COMMON;
+ *valp = sym->st_size;
+ break;
+ }
+
+ return TRUE;
+}
+
+static bfd_boolean
+elf_hppa_unmark_useless_dynamic_symbols (struct elf_link_hash_entry *h,
+ void *data)
+{
+ struct bfd_link_info *info = data;
+
+ /* If we are not creating a shared library, and this symbol is
+ referenced by a shared library but is not defined anywhere, then
+ the generic code will warn that it is undefined.
+
+ This behavior is undesirable on HPs since the standard shared
+ libraries contain references to undefined symbols.
+
+ So we twiddle the flags associated with such symbols so that they
+ will not trigger the warning. ?!? FIXME. This is horribly fragile.
+
+ Ultimately we should have better controls over the generic ELF BFD
+ linker code. */
+ if (! info->relocatable
+ && info->unresolved_syms_in_shared_libs != RM_IGNORE
+ && h->root.type == bfd_link_hash_undefined
+ && h->ref_dynamic
+ && !h->ref_regular)
+ {
+ h->ref_dynamic = 0;
+ h->pointer_equality_needed = 1;
+ }
+
+ return TRUE;
+}
+
+static bfd_boolean
+elf_hppa_remark_useless_dynamic_symbols (struct elf_link_hash_entry *h,
+ void *data)
+{
+ struct bfd_link_info *info = data;
+
+ /* If we are not creating a shared library, and this symbol is
+ referenced by a shared library but is not defined anywhere, then
+ the generic code will warn that it is undefined.
+
+ This behavior is undesirable on HPs since the standard shared
+ libraries contain references to undefined symbols.
+
+ So we twiddle the flags associated with such symbols so that they
+ will not trigger the warning. ?!? FIXME. This is horribly fragile.
+
+ Ultimately we should have better controls over the generic ELF BFD
+ linker code. */
+ if (! info->relocatable
+ && info->unresolved_syms_in_shared_libs != RM_IGNORE
+ && h->root.type == bfd_link_hash_undefined
+ && !h->ref_dynamic
+ && !h->ref_regular
+ && h->pointer_equality_needed)
+ {
+ h->ref_dynamic = 1;
+ h->pointer_equality_needed = 0;
+ }
+
+ return TRUE;
+}
+
+static bfd_boolean
+elf_hppa_is_dynamic_loader_symbol (const char *name)
+{
+ return (! strcmp (name, "__CPU_REVISION")
+ || ! strcmp (name, "__CPU_KEYBITS_1")
+ || ! strcmp (name, "__SYSTEM_ID_D")
+ || ! strcmp (name, "__FPU_MODEL")
+ || ! strcmp (name, "__FPU_REVISION")
+ || ! strcmp (name, "__ARGC")
+ || ! strcmp (name, "__ARGV")
+ || ! strcmp (name, "__ENVP")
+ || ! strcmp (name, "__TLS_SIZE_D")
+ || ! strcmp (name, "__LOAD_INFO")
+ || ! strcmp (name, "__systab"));
+}
+
+/* Record the lowest address for the data and text segments. */
+static void
+elf_hppa_record_segment_addrs (bfd *abfd,
+ asection *section,
+ void *data)
+{
+ struct elf64_hppa_link_hash_table *hppa_info = data;
+
+ if ((section->flags & (SEC_ALLOC | SEC_LOAD)) == (SEC_ALLOC | SEC_LOAD))
+ {
+ bfd_vma value;
+ Elf_Internal_Phdr *p;
+
+ p = _bfd_elf_find_segment_containing_section (abfd, section->output_section);
+ BFD_ASSERT (p != NULL);
+ value = p->p_vaddr;
+
+ if (section->flags & SEC_READONLY)
+ {
+ if (value < hppa_info->text_segment_base)
+ hppa_info->text_segment_base = value;
+ }
+ else
+ {
+ if (value < hppa_info->data_segment_base)
+ hppa_info->data_segment_base = value;
+ }
+ }
+}
+
+/* Called after we have seen all the input files/sections, but before
+ final symbol resolution and section placement has been determined.
+
+ We use this hook to (possibly) provide a value for __gp, then we
+ fall back to the generic ELF final link routine. */
+
+static bfd_boolean
+elf_hppa_final_link (bfd *abfd, struct bfd_link_info *info)
+{
+ bfd_boolean retval;
+ struct elf64_hppa_link_hash_table *hppa_info = hppa_link_hash_table (info);
+
+ if (hppa_info == NULL)
+ return FALSE;
+
+ if (! info->relocatable)
+ {
+ struct elf_link_hash_entry *gp;
+ bfd_vma gp_val;
+
+ /* The linker script defines a value for __gp iff it was referenced
+ by one of the objects being linked. First try to find the symbol
+ in the hash table. If that fails, just compute the value __gp
+ should have had. */
+ gp = elf_link_hash_lookup (elf_hash_table (info), "__gp", FALSE,
+ FALSE, FALSE);
+
+ if (gp)
+ {
+
+ /* Adjust the value of __gp as we may want to slide it into the
+ .plt section so that the stubs can access PLT entries without
+ using an addil sequence. */
+ gp->root.u.def.value += hppa_info->gp_offset;
+
+ gp_val = (gp->root.u.def.section->output_section->vma
+ + gp->root.u.def.section->output_offset
+ + gp->root.u.def.value);
+ }
+ else
+ {
+ asection *sec;
+
+ /* First look for a .plt section. If found, then __gp is the
+ address of the .plt + gp_offset.
+
+ If no .plt is found, then look for .dlt, .opd and .data (in
+ that order) and set __gp to the base address of whichever
+ section is found first. */
+
+ sec = hppa_info->plt_sec;
+ if (sec && ! (sec->flags & SEC_EXCLUDE))
+ gp_val = (sec->output_offset
+ + sec->output_section->vma
+ + hppa_info->gp_offset);
+ else
+ {
+ sec = hppa_info->dlt_sec;
+ if (!sec || (sec->flags & SEC_EXCLUDE))
+ sec = hppa_info->opd_sec;
+ if (!sec || (sec->flags & SEC_EXCLUDE))
+ sec = bfd_get_section_by_name (abfd, ".data");
+ if (!sec || (sec->flags & SEC_EXCLUDE))
+ gp_val = 0;
+ else
+ gp_val = sec->output_offset + sec->output_section->vma;
+ }
+ }
+
+ /* Install whatever value we found/computed for __gp. */
+ _bfd_set_gp_value (abfd, gp_val);
+ }
+
+ /* We need to know the base of the text and data segments so that we
+ can perform SEGREL relocations. We will record the base addresses
+ when we encounter the first SEGREL relocation. */
+ hppa_info->text_segment_base = (bfd_vma)-1;
+ hppa_info->data_segment_base = (bfd_vma)-1;
+
+ /* HP's shared libraries have references to symbols that are not
+ defined anywhere. The generic ELF BFD linker code will complain
+ about such symbols.
+
+ So we detect the losing case and arrange for the flags on the symbol
+ to indicate that it was never referenced. This keeps the generic
+ ELF BFD link code happy and appears to not create any secondary
+ problems. Ultimately we need a way to control the behavior of the
+ generic ELF BFD link code better. */
+ elf_link_hash_traverse (elf_hash_table (info),
+ elf_hppa_unmark_useless_dynamic_symbols,
+ info);
+
+ /* Invoke the regular ELF backend linker to do all the work. */
+ retval = bfd_elf_final_link (abfd, info);
+
+ elf_link_hash_traverse (elf_hash_table (info),
+ elf_hppa_remark_useless_dynamic_symbols,
+ info);
+
+ /* If we're producing a final executable, sort the contents of the
+ unwind section. */
+ if (retval && !info->relocatable)
+ retval = elf_hppa_sort_unwind (abfd);
+
+ return retval;
+}
+
+/* Relocate the given INSN. VALUE should be the actual value we want
+ to insert into the instruction, ie by this point we should not be
+ concerned with computing an offset relative to the DLT, PC, etc.
+ Instead this routine is meant to handle the bit manipulations needed
+ to insert the relocation into the given instruction. */
+
+static int
+elf_hppa_relocate_insn (int insn, int sym_value, unsigned int r_type)
+{
+ switch (r_type)
+ {
+ /* This is any 22 bit branch. In PA2.0 syntax it corresponds to
+ the "B" instruction. */
+ case R_PARISC_PCREL22F:
+ case R_PARISC_PCREL22C:
+ return (insn & ~0x3ff1ffd) | re_assemble_22 (sym_value);
+
+ /* This is any 12 bit branch. */
+ case R_PARISC_PCREL12F:
+ return (insn & ~0x1ffd) | re_assemble_12 (sym_value);
+
+ /* This is any 17 bit branch. In PA2.0 syntax it also corresponds
+ to the "B" instruction as well as BE. */
+ case R_PARISC_PCREL17F:
+ case R_PARISC_DIR17F:
+ case R_PARISC_DIR17R:
+ case R_PARISC_PCREL17C:
+ case R_PARISC_PCREL17R:
+ return (insn & ~0x1f1ffd) | re_assemble_17 (sym_value);
+
+ /* ADDIL or LDIL instructions. */
+ case R_PARISC_DLTREL21L:
+ case R_PARISC_DLTIND21L:
+ case R_PARISC_LTOFF_FPTR21L:
+ case R_PARISC_PCREL21L:
+ case R_PARISC_LTOFF_TP21L:
+ case R_PARISC_DPREL21L:
+ case R_PARISC_PLTOFF21L:
+ case R_PARISC_DIR21L:
+ return (insn & ~0x1fffff) | re_assemble_21 (sym_value);
+
+ /* LDO and integer loads/stores with 14 bit displacements. */
+ case R_PARISC_DLTREL14R:
+ case R_PARISC_DLTREL14F:
+ case R_PARISC_DLTIND14R:
+ case R_PARISC_DLTIND14F:
+ case R_PARISC_LTOFF_FPTR14R:
+ case R_PARISC_PCREL14R:
+ case R_PARISC_PCREL14F:
+ case R_PARISC_LTOFF_TP14R:
+ case R_PARISC_LTOFF_TP14F:
+ case R_PARISC_DPREL14R:
+ case R_PARISC_DPREL14F:
+ case R_PARISC_PLTOFF14R:
+ case R_PARISC_PLTOFF14F:
+ case R_PARISC_DIR14R:
+ case R_PARISC_DIR14F:
+ return (insn & ~0x3fff) | low_sign_unext (sym_value, 14);
+
+ /* PA2.0W LDO and integer loads/stores with 16 bit displacements. */
+ case R_PARISC_LTOFF_FPTR16F:
+ case R_PARISC_PCREL16F:
+ case R_PARISC_LTOFF_TP16F:
+ case R_PARISC_GPREL16F:
+ case R_PARISC_PLTOFF16F:
+ case R_PARISC_DIR16F:
+ case R_PARISC_LTOFF16F:
+ return (insn & ~0xffff) | re_assemble_16 (sym_value);
+
+ /* Doubleword loads and stores with a 14 bit displacement. */
+ case R_PARISC_DLTREL14DR:
+ case R_PARISC_DLTIND14DR:
+ case R_PARISC_LTOFF_FPTR14DR:
+ case R_PARISC_LTOFF_FPTR16DF:
+ case R_PARISC_PCREL14DR:
+ case R_PARISC_PCREL16DF:
+ case R_PARISC_LTOFF_TP14DR:
+ case R_PARISC_LTOFF_TP16DF:
+ case R_PARISC_DPREL14DR:
+ case R_PARISC_GPREL16DF:
+ case R_PARISC_PLTOFF14DR:
+ case R_PARISC_PLTOFF16DF:
+ case R_PARISC_DIR14DR:
+ case R_PARISC_DIR16DF:
+ case R_PARISC_LTOFF16DF:
+ return (insn & ~0x3ff1) | (((sym_value & 0x2000) >> 13)
+ | ((sym_value & 0x1ff8) << 1));
+
+ /* Floating point single word load/store instructions. */
+ case R_PARISC_DLTREL14WR:
+ case R_PARISC_DLTIND14WR:
+ case R_PARISC_LTOFF_FPTR14WR:
+ case R_PARISC_LTOFF_FPTR16WF:
+ case R_PARISC_PCREL14WR:
+ case R_PARISC_PCREL16WF:
+ case R_PARISC_LTOFF_TP14WR:
+ case R_PARISC_LTOFF_TP16WF:
+ case R_PARISC_DPREL14WR:
+ case R_PARISC_GPREL16WF:
+ case R_PARISC_PLTOFF14WR:
+ case R_PARISC_PLTOFF16WF:
+ case R_PARISC_DIR16WF:
+ case R_PARISC_DIR14WR:
+ case R_PARISC_LTOFF16WF:
+ return (insn & ~0x3ff9) | (((sym_value & 0x2000) >> 13)
+ | ((sym_value & 0x1ffc) << 1));
+
+ default:
+ return insn;
+ }
+}
+
+/* Compute the value for a relocation (REL) during a final link stage,
+ then insert the value into the proper location in CONTENTS.
+
+ VALUE is a tentative value for the relocation and may be overridden
+ and modified here based on the specific relocation to be performed.
+
+ For example we do conversions for PC-relative branches in this routine
+ or redirection of calls to external routines to stubs.
+
+ The work of actually applying the relocation is left to a helper
+ routine in an attempt to reduce the complexity and size of this
+ function. */
+
+static bfd_reloc_status_type
+elf_hppa_final_link_relocate (Elf_Internal_Rela *rel,
+ bfd *input_bfd,
+ bfd *output_bfd,
+ asection *input_section,
+ bfd_byte *contents,
+ bfd_vma value,
+ struct bfd_link_info *info,
+ asection *sym_sec,
+ struct elf_link_hash_entry *eh)
+{
+ struct elf64_hppa_link_hash_table *hppa_info = hppa_link_hash_table (info);
+ struct elf64_hppa_link_hash_entry *hh = hppa_elf_hash_entry (eh);
+ bfd_vma *local_offsets;
+ Elf_Internal_Shdr *symtab_hdr;
+ int insn;
+ bfd_vma max_branch_offset = 0;
+ bfd_vma offset = rel->r_offset;
+ bfd_signed_vma addend = rel->r_addend;
+ reloc_howto_type *howto = elf_hppa_howto_table + ELF_R_TYPE (rel->r_info);
+ unsigned int r_symndx = ELF_R_SYM (rel->r_info);
+ unsigned int r_type = howto->type;
+ bfd_byte *hit_data = contents + offset;
+
+ if (hppa_info == NULL)
+ return bfd_reloc_notsupported;
+
+ symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
+ local_offsets = elf_local_got_offsets (input_bfd);
+ insn = bfd_get_32 (input_bfd, hit_data);
+
+ switch (r_type)
+ {
+ case R_PARISC_NONE:
+ break;
+
+ /* Basic function call support.
+
+ Note for a call to a function defined in another dynamic library
+ we want to redirect the call to a stub. */
+
+ /* PC relative relocs without an implicit offset. */
+ case R_PARISC_PCREL21L:
+ case R_PARISC_PCREL14R:
+ case R_PARISC_PCREL14F:
+ case R_PARISC_PCREL14WR:
+ case R_PARISC_PCREL14DR:
+ case R_PARISC_PCREL16F:
+ case R_PARISC_PCREL16WF:
+ case R_PARISC_PCREL16DF:
+ {
+ /* If this is a call to a function defined in another dynamic
+ library, then redirect the call to the local stub for this
+ function. */
+ if (sym_sec == NULL || sym_sec->output_section == NULL)
+ value = (hh->stub_offset + hppa_info->stub_sec->output_offset
+ + hppa_info->stub_sec->output_section->vma);
+
+ /* Turn VALUE into a proper PC relative address. */
+ value -= (offset + input_section->output_offset
+ + input_section->output_section->vma);
+
+ /* Adjust for any field selectors. */
+ if (r_type == R_PARISC_PCREL21L)
+ value = hppa_field_adjust (value, -8 + addend, e_lsel);
+ else if (r_type == R_PARISC_PCREL14F
+ || r_type == R_PARISC_PCREL16F
+ || r_type == R_PARISC_PCREL16WF
+ || r_type == R_PARISC_PCREL16DF)
+ value = hppa_field_adjust (value, -8 + addend, e_fsel);
+ else
+ value = hppa_field_adjust (value, -8 + addend, e_rsel);
+
+ /* Apply the relocation to the given instruction. */
+ insn = elf_hppa_relocate_insn (insn, (int) value, r_type);
+ break;
+ }
+
+ case R_PARISC_PCREL12F:
+ case R_PARISC_PCREL22F:
+ case R_PARISC_PCREL17F:
+ case R_PARISC_PCREL22C:
+ case R_PARISC_PCREL17C:
+ case R_PARISC_PCREL17R:
+ {
+ /* If this is a call to a function defined in another dynamic
+ library, then redirect the call to the local stub for this
+ function. */
+ if (sym_sec == NULL || sym_sec->output_section == NULL)
+ value = (hh->stub_offset + hppa_info->stub_sec->output_offset
+ + hppa_info->stub_sec->output_section->vma);
+
+ /* Turn VALUE into a proper PC relative address. */
+ value -= (offset + input_section->output_offset
+ + input_section->output_section->vma);
+ addend -= 8;
+
+ if (r_type == (unsigned int) R_PARISC_PCREL22F)
+ max_branch_offset = (1 << (22-1)) << 2;
+ else if (r_type == (unsigned int) R_PARISC_PCREL17F)
+ max_branch_offset = (1 << (17-1)) << 2;
+ else if (r_type == (unsigned int) R_PARISC_PCREL12F)
+ max_branch_offset = (1 << (12-1)) << 2;
+
+ /* Make sure we can reach the branch target. */
+ if (max_branch_offset != 0
+ && value + addend + max_branch_offset >= 2*max_branch_offset)
+ {
+ (*_bfd_error_handler)
+ (_("%B(%A+0x%" BFD_VMA_FMT "x): cannot reach %s"),
+ input_bfd,
+ input_section,
+ offset,
+ eh ? eh->root.root.string : "unknown");
+ bfd_set_error (bfd_error_bad_value);
+ return bfd_reloc_overflow;
+ }
+
+ /* Adjust for any field selectors. */
+ if (r_type == R_PARISC_PCREL17R)
+ value = hppa_field_adjust (value, addend, e_rsel);
+ else
+ value = hppa_field_adjust (value, addend, e_fsel);
+
+ /* All branches are implicitly shifted by 2 places. */
+ value >>= 2;
+
+ /* Apply the relocation to the given instruction. */
+ insn = elf_hppa_relocate_insn (insn, (int) value, r_type);
+ break;
+ }
+
+ /* Indirect references to data through the DLT. */
+ case R_PARISC_DLTIND14R:
+ case R_PARISC_DLTIND14F:
+ case R_PARISC_DLTIND14DR:
+ case R_PARISC_DLTIND14WR:
+ case R_PARISC_DLTIND21L:
+ case R_PARISC_LTOFF_FPTR14R:
+ case R_PARISC_LTOFF_FPTR14DR:
+ case R_PARISC_LTOFF_FPTR14WR:
+ case R_PARISC_LTOFF_FPTR21L:
+ case R_PARISC_LTOFF_FPTR16F:
+ case R_PARISC_LTOFF_FPTR16WF:
+ case R_PARISC_LTOFF_FPTR16DF:
+ case R_PARISC_LTOFF_TP21L:
+ case R_PARISC_LTOFF_TP14R:
+ case R_PARISC_LTOFF_TP14F:
+ case R_PARISC_LTOFF_TP14WR:
+ case R_PARISC_LTOFF_TP14DR:
+ case R_PARISC_LTOFF_TP16F:
+ case R_PARISC_LTOFF_TP16WF:
+ case R_PARISC_LTOFF_TP16DF:
+ case R_PARISC_LTOFF16F:
+ case R_PARISC_LTOFF16WF:
+ case R_PARISC_LTOFF16DF:
+ {
+ bfd_vma off;
+
+ /* If this relocation was against a local symbol, then we still
+ have not set up the DLT entry (it's not convenient to do so
+ in the "finalize_dlt" routine because it is difficult to get
+ to the local symbol's value).
+
+ So, if this is a local symbol (h == NULL), then we need to
+ fill in its DLT entry.
+
+ Similarly we may still need to set up an entry in .opd for
+ a local function which had its address taken. */
+ if (hh == NULL)
+ {
+ bfd_vma *local_opd_offsets, *local_dlt_offsets;
+
+ if (local_offsets == NULL)
+ abort ();
+
+ /* Now do .opd creation if needed. */
+ if (r_type == R_PARISC_LTOFF_FPTR14R
+ || r_type == R_PARISC_LTOFF_FPTR14DR
+ || r_type == R_PARISC_LTOFF_FPTR14WR
+ || r_type == R_PARISC_LTOFF_FPTR21L
+ || r_type == R_PARISC_LTOFF_FPTR16F
+ || r_type == R_PARISC_LTOFF_FPTR16WF
+ || r_type == R_PARISC_LTOFF_FPTR16DF)
+ {
+ local_opd_offsets = local_offsets + 2 * symtab_hdr->sh_info;
+ off = local_opd_offsets[r_symndx];
+
+ /* The last bit records whether we've already initialised
+ this local .opd entry. */
+ if ((off & 1) != 0)
+ {
+ BFD_ASSERT (off != (bfd_vma) -1);
+ off &= ~1;
+ }
+ else
+ {
+ local_opd_offsets[r_symndx] |= 1;
+
+ /* The first two words of an .opd entry are zero. */
+ memset (hppa_info->opd_sec->contents + off, 0, 16);
+
+ /* The next word is the address of the function. */
+ bfd_put_64 (hppa_info->opd_sec->owner, value + addend,
+ (hppa_info->opd_sec->contents + off + 16));
+
+ /* The last word is our local __gp value. */
+ value = _bfd_get_gp_value
+ (hppa_info->opd_sec->output_section->owner);
+ bfd_put_64 (hppa_info->opd_sec->owner, value,
+ (hppa_info->opd_sec->contents + off + 24));
+ }
+
+ /* The DLT value is the address of the .opd entry. */
+ value = (off
+ + hppa_info->opd_sec->output_offset
+ + hppa_info->opd_sec->output_section->vma);
+ addend = 0;
+ }
+
+ local_dlt_offsets = local_offsets;
+ off = local_dlt_offsets[r_symndx];
+
+ if ((off & 1) != 0)
+ {
+ BFD_ASSERT (off != (bfd_vma) -1);
+ off &= ~1;
+ }
+ else
+ {
+ local_dlt_offsets[r_symndx] |= 1;
+ bfd_put_64 (hppa_info->dlt_sec->owner,
+ value + addend,
+ hppa_info->dlt_sec->contents + off);
+ }
+ }
+ else
+ off = hh->dlt_offset;
+
+ /* We want the value of the DLT offset for this symbol, not
+ the symbol's actual address. Note that __gp may not point
+ to the start of the DLT, so we have to compute the absolute
+ address, then subtract out the value of __gp. */
+ value = (off
+ + hppa_info->dlt_sec->output_offset
+ + hppa_info->dlt_sec->output_section->vma);
+ value -= _bfd_get_gp_value (output_bfd);
+
+ /* All DLTIND relocations are basically the same at this point,
+ except that we need different field selectors for the 21bit
+ version vs the 14bit versions. */
+ if (r_type == R_PARISC_DLTIND21L
+ || r_type == R_PARISC_LTOFF_FPTR21L
+ || r_type == R_PARISC_LTOFF_TP21L)
+ value = hppa_field_adjust (value, 0, e_lsel);
+ else if (r_type == R_PARISC_DLTIND14F
+ || r_type == R_PARISC_LTOFF_FPTR16F
+ || r_type == R_PARISC_LTOFF_FPTR16WF
+ || r_type == R_PARISC_LTOFF_FPTR16DF
+ || r_type == R_PARISC_LTOFF16F
+ || r_type == R_PARISC_LTOFF16DF
+ || r_type == R_PARISC_LTOFF16WF
+ || r_type == R_PARISC_LTOFF_TP16F
+ || r_type == R_PARISC_LTOFF_TP16WF
+ || r_type == R_PARISC_LTOFF_TP16DF)
+ value = hppa_field_adjust (value, 0, e_fsel);
+ else
+ value = hppa_field_adjust (value, 0, e_rsel);
+
+ insn = elf_hppa_relocate_insn (insn, (int) value, r_type);
+ break;
+ }
+
+ case R_PARISC_DLTREL14R:
+ case R_PARISC_DLTREL14F:
+ case R_PARISC_DLTREL14DR:
+ case R_PARISC_DLTREL14WR:
+ case R_PARISC_DLTREL21L:
+ case R_PARISC_DPREL21L:
+ case R_PARISC_DPREL14WR:
+ case R_PARISC_DPREL14DR:
+ case R_PARISC_DPREL14R:
+ case R_PARISC_DPREL14F:
+ case R_PARISC_GPREL16F:
+ case R_PARISC_GPREL16WF:
+ case R_PARISC_GPREL16DF:
+ {
+ /* Subtract out the global pointer value to make value a DLT
+ relative address. */
+ value -= _bfd_get_gp_value (output_bfd);
+
+ /* All DLTREL relocations are basically the same at this point,
+ except that we need different field selectors for the 21bit
+ version vs the 14bit versions. */
+ if (r_type == R_PARISC_DLTREL21L
+ || r_type == R_PARISC_DPREL21L)
+ value = hppa_field_adjust (value, addend, e_lrsel);
+ else if (r_type == R_PARISC_DLTREL14F
+ || r_type == R_PARISC_DPREL14F
+ || r_type == R_PARISC_GPREL16F
+ || r_type == R_PARISC_GPREL16WF
+ || r_type == R_PARISC_GPREL16DF)
+ value = hppa_field_adjust (value, addend, e_fsel);
+ else
+ value = hppa_field_adjust (value, addend, e_rrsel);
+
+ insn = elf_hppa_relocate_insn (insn, (int) value, r_type);
+ break;
+ }
+
+ case R_PARISC_DIR21L:
+ case R_PARISC_DIR17R:
+ case R_PARISC_DIR17F:
+ case R_PARISC_DIR14R:
+ case R_PARISC_DIR14F:
+ case R_PARISC_DIR14WR:
+ case R_PARISC_DIR14DR:
+ case R_PARISC_DIR16F:
+ case R_PARISC_DIR16WF:
+ case R_PARISC_DIR16DF:
+ {
+ /* All DIR relocations are basically the same at this point,
+ except that branch offsets need to be divided by four, and
+ we need different field selectors. Note that we don't
+ redirect absolute calls to local stubs. */
+
+ if (r_type == R_PARISC_DIR21L)
+ value = hppa_field_adjust (value, addend, e_lrsel);
+ else if (r_type == R_PARISC_DIR17F
+ || r_type == R_PARISC_DIR16F
+ || r_type == R_PARISC_DIR16WF
+ || r_type == R_PARISC_DIR16DF
+ || r_type == R_PARISC_DIR14F)
+ value = hppa_field_adjust (value, addend, e_fsel);
+ else
+ value = hppa_field_adjust (value, addend, e_rrsel);
+
+ if (r_type == R_PARISC_DIR17R || r_type == R_PARISC_DIR17F)
+ /* All branches are implicitly shifted by 2 places. */
+ value >>= 2;
+
+ insn = elf_hppa_relocate_insn (insn, (int) value, r_type);
+ break;
+ }
+
+ case R_PARISC_PLTOFF21L:
+ case R_PARISC_PLTOFF14R:
+ case R_PARISC_PLTOFF14F:
+ case R_PARISC_PLTOFF14WR:
+ case R_PARISC_PLTOFF14DR:
+ case R_PARISC_PLTOFF16F:
+ case R_PARISC_PLTOFF16WF:
+ case R_PARISC_PLTOFF16DF:
+ {
+ /* We want the value of the PLT offset for this symbol, not
+ the symbol's actual address. Note that __gp may not point
+ to the start of the DLT, so we have to compute the absolute
+ address, then subtract out the value of __gp. */
+ value = (hh->plt_offset
+ + hppa_info->plt_sec->output_offset
+ + hppa_info->plt_sec->output_section->vma);
+ value -= _bfd_get_gp_value (output_bfd);
+
+ /* All PLTOFF relocations are basically the same at this point,
+ except that we need different field selectors for the 21bit
+ version vs the 14bit versions. */
+ if (r_type == R_PARISC_PLTOFF21L)
+ value = hppa_field_adjust (value, addend, e_lrsel);
+ else if (r_type == R_PARISC_PLTOFF14F
+ || r_type == R_PARISC_PLTOFF16F
+ || r_type == R_PARISC_PLTOFF16WF
+ || r_type == R_PARISC_PLTOFF16DF)
+ value = hppa_field_adjust (value, addend, e_fsel);
+ else
+ value = hppa_field_adjust (value, addend, e_rrsel);
+
+ insn = elf_hppa_relocate_insn (insn, (int) value, r_type);
+ break;
+ }
+
+ case R_PARISC_LTOFF_FPTR32:
+ {
+ /* We may still need to create the FPTR itself if it was for
+ a local symbol. */
+ if (hh == NULL)
+ {
+ /* The first two words of an .opd entry are zero. */
+ memset (hppa_info->opd_sec->contents + hh->opd_offset, 0, 16);
+
+ /* The next word is the address of the function. */
+ bfd_put_64 (hppa_info->opd_sec->owner, value + addend,
+ (hppa_info->opd_sec->contents
+ + hh->opd_offset + 16));
+
+ /* The last word is our local __gp value. */
+ value = _bfd_get_gp_value
+ (hppa_info->opd_sec->output_section->owner);
+ bfd_put_64 (hppa_info->opd_sec->owner, value,
+ hppa_info->opd_sec->contents + hh->opd_offset + 24);
+
+ /* The DLT value is the address of the .opd entry. */
+ value = (hh->opd_offset
+ + hppa_info->opd_sec->output_offset
+ + hppa_info->opd_sec->output_section->vma);
+
+ bfd_put_64 (hppa_info->dlt_sec->owner,
+ value,
+ hppa_info->dlt_sec->contents + hh->dlt_offset);
+ }
+
+ /* We want the value of the DLT offset for this symbol, not
+ the symbol's actual address. Note that __gp may not point
+ to the start of the DLT, so we have to compute the absolute
+ address, then subtract out the value of __gp. */
+ value = (hh->dlt_offset
+ + hppa_info->dlt_sec->output_offset
+ + hppa_info->dlt_sec->output_section->vma);
+ value -= _bfd_get_gp_value (output_bfd);
+ bfd_put_32 (input_bfd, value, hit_data);
+ return bfd_reloc_ok;
+ }
+
+ case R_PARISC_LTOFF_FPTR64:
+ case R_PARISC_LTOFF_TP64:
+ {
+ /* We may still need to create the FPTR itself if it was for
+ a local symbol. */
+ if (eh == NULL && r_type == R_PARISC_LTOFF_FPTR64)
+ {
+ /* The first two words of an .opd entry are zero. */
+ memset (hppa_info->opd_sec->contents + hh->opd_offset, 0, 16);
+
+ /* The next word is the address of the function. */
+ bfd_put_64 (hppa_info->opd_sec->owner, value + addend,
+ (hppa_info->opd_sec->contents
+ + hh->opd_offset + 16));
+
+ /* The last word is our local __gp value. */
+ value = _bfd_get_gp_value
+ (hppa_info->opd_sec->output_section->owner);
+ bfd_put_64 (hppa_info->opd_sec->owner, value,
+ hppa_info->opd_sec->contents + hh->opd_offset + 24);
+
+ /* The DLT value is the address of the .opd entry. */
+ value = (hh->opd_offset
+ + hppa_info->opd_sec->output_offset
+ + hppa_info->opd_sec->output_section->vma);
+
+ bfd_put_64 (hppa_info->dlt_sec->owner,
+ value,
+ hppa_info->dlt_sec->contents + hh->dlt_offset);
+ }
+
+ /* We want the value of the DLT offset for this symbol, not
+ the symbol's actual address. Note that __gp may not point
+ to the start of the DLT, so we have to compute the absolute
+ address, then subtract out the value of __gp. */
+ value = (hh->dlt_offset
+ + hppa_info->dlt_sec->output_offset
+ + hppa_info->dlt_sec->output_section->vma);
+ value -= _bfd_get_gp_value (output_bfd);
+ bfd_put_64 (input_bfd, value, hit_data);
+ return bfd_reloc_ok;
+ }
+
+ case R_PARISC_DIR32:
+ bfd_put_32 (input_bfd, value + addend, hit_data);
+ return bfd_reloc_ok;
+
+ case R_PARISC_DIR64:
+ bfd_put_64 (input_bfd, value + addend, hit_data);
+ return bfd_reloc_ok;
+
+ case R_PARISC_GPREL64:
+ /* Subtract out the global pointer value to make value a DLT
+ relative address. */
+ value -= _bfd_get_gp_value (output_bfd);
+
+ bfd_put_64 (input_bfd, value + addend, hit_data);
+ return bfd_reloc_ok;
+
+ case R_PARISC_LTOFF64:
+ /* We want the value of the DLT offset for this symbol, not
+ the symbol's actual address. Note that __gp may not point
+ to the start of the DLT, so we have to compute the absolute
+ address, then subtract out the value of __gp. */
+ value = (hh->dlt_offset
+ + hppa_info->dlt_sec->output_offset
+ + hppa_info->dlt_sec->output_section->vma);
+ value -= _bfd_get_gp_value (output_bfd);
+
+ bfd_put_64 (input_bfd, value + addend, hit_data);
+ return bfd_reloc_ok;
+
+ case R_PARISC_PCREL32:
+ {
+ /* If this is a call to a function defined in another dynamic
+ library, then redirect the call to the local stub for this
+ function. */
+ if (sym_sec == NULL || sym_sec->output_section == NULL)
+ value = (hh->stub_offset + hppa_info->stub_sec->output_offset
+ + hppa_info->stub_sec->output_section->vma);
+
+ /* Turn VALUE into a proper PC relative address. */
+ value -= (offset + input_section->output_offset
+ + input_section->output_section->vma);
+
+ value += addend;
+ value -= 8;
+ bfd_put_32 (input_bfd, value, hit_data);
+ return bfd_reloc_ok;
+ }
+
+ case R_PARISC_PCREL64:
+ {
+ /* If this is a call to a function defined in another dynamic
+ library, then redirect the call to the local stub for this
+ function. */
+ if (sym_sec == NULL || sym_sec->output_section == NULL)
+ value = (hh->stub_offset + hppa_info->stub_sec->output_offset
+ + hppa_info->stub_sec->output_section->vma);
+
+ /* Turn VALUE into a proper PC relative address. */
+ value -= (offset + input_section->output_offset
+ + input_section->output_section->vma);
+
+ value += addend;
+ value -= 8;
+ bfd_put_64 (input_bfd, value, hit_data);
+ return bfd_reloc_ok;
+ }
+
+ case R_PARISC_FPTR64:
+ {
+ bfd_vma off;
+
+ /* We may still need to create the FPTR itself if it was for
+ a local symbol. */
+ if (hh == NULL)
+ {
+ bfd_vma *local_opd_offsets;
+
+ if (local_offsets == NULL)
+ abort ();
+
+ local_opd_offsets = local_offsets + 2 * symtab_hdr->sh_info;
+ off = local_opd_offsets[r_symndx];
+
+ /* The last bit records whether we've already initialised
+ this local .opd entry. */
+ if ((off & 1) != 0)
+ {
+ BFD_ASSERT (off != (bfd_vma) -1);
+ off &= ~1;
+ }
+ else
+ {
+ /* The first two words of an .opd entry are zero. */
+ memset (hppa_info->opd_sec->contents + off, 0, 16);
+
+ /* The next word is the address of the function. */
+ bfd_put_64 (hppa_info->opd_sec->owner, value + addend,
+ (hppa_info->opd_sec->contents + off + 16));
+
+ /* The last word is our local __gp value. */
+ value = _bfd_get_gp_value
+ (hppa_info->opd_sec->output_section->owner);
+ bfd_put_64 (hppa_info->opd_sec->owner, value,
+ hppa_info->opd_sec->contents + off + 24);
+ }
+ }
+ else
+ off = hh->opd_offset;
+
+ if (hh == NULL || hh->want_opd)
+ /* We want the value of the OPD offset for this symbol. */
+ value = (off
+ + hppa_info->opd_sec->output_offset
+ + hppa_info->opd_sec->output_section->vma);
+ else
+ /* We want the address of the symbol. */
+ value += addend;
+
+ bfd_put_64 (input_bfd, value, hit_data);
+ return bfd_reloc_ok;
+ }
+
+ case R_PARISC_SECREL32:
+ if (sym_sec)
+ value -= sym_sec->output_section->vma;
+ bfd_put_32 (input_bfd, value + addend, hit_data);
+ return bfd_reloc_ok;
+
+ case R_PARISC_SEGREL32:
+ case R_PARISC_SEGREL64:
+ {
+ /* If this is the first SEGREL relocation, then initialize
+ the segment base values. */
+ if (hppa_info->text_segment_base == (bfd_vma) -1)
+ bfd_map_over_sections (output_bfd, elf_hppa_record_segment_addrs,
+ hppa_info);
+
+ /* VALUE holds the absolute address. We want to include the
+ addend, then turn it into a segment relative address.
+
+ The segment is derived from SYM_SEC. We assume that there are
+ only two segments of note in the resulting executable/shlib.
+ A readonly segment (.text) and a readwrite segment (.data). */
+ value += addend;
+
+ if (sym_sec->flags & SEC_CODE)
+ value -= hppa_info->text_segment_base;
+ else
+ value -= hppa_info->data_segment_base;
+
+ if (r_type == R_PARISC_SEGREL32)
+ bfd_put_32 (input_bfd, value, hit_data);
+ else
+ bfd_put_64 (input_bfd, value, hit_data);
+ return bfd_reloc_ok;
+ }
+
+ /* Something we don't know how to handle. */
+ default:
+ return bfd_reloc_notsupported;
+ }
+
+ /* Update the instruction word. */
+ bfd_put_32 (input_bfd, (bfd_vma) insn, hit_data);
+ return bfd_reloc_ok;
+}
+
+/* Relocate an HPPA ELF section. */
+
+static bfd_boolean
+elf64_hppa_relocate_section (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;
+ struct elf64_hppa_link_hash_table *hppa_info;
+
+ hppa_info = hppa_link_hash_table (info);
+ if (hppa_info == NULL)
+ return FALSE;
+
+ 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 = elf_hppa_howto_table + ELF_R_TYPE (rel->r_info);
+ unsigned long r_symndx;
+ struct elf_link_hash_entry *eh;
+ Elf_Internal_Sym *sym;
+ asection *sym_sec;
+ bfd_vma relocation;
+ bfd_reloc_status_type r;
+
+ r_type = ELF_R_TYPE (rel->r_info);
+ if (r_type < 0 || r_type >= (int) R_PARISC_UNIMPLEMENTED)
+ {
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+ if (r_type == (unsigned int) R_PARISC_GNU_VTENTRY
+ || r_type == (unsigned int) R_PARISC_GNU_VTINHERIT)
+ continue;
+
+ /* This is a final link. */
+ r_symndx = ELF_R_SYM (rel->r_info);
+ eh = NULL;
+ sym = NULL;
+ sym_sec = NULL;
+ if (r_symndx < symtab_hdr->sh_info)
+ {
+ /* This is a local symbol, hh defaults to NULL. */
+ sym = local_syms + r_symndx;
+ sym_sec = local_sections[r_symndx];
+ relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sym_sec, rel);
+ }
+ else
+ {
+ /* This is not a local symbol. */
+ struct elf_link_hash_entry **sym_hashes = elf_sym_hashes (input_bfd);
+
+ /* It seems this can happen with erroneous or unsupported
+ input (mixing a.out and elf in an archive, for example.) */
+ if (sym_hashes == NULL)
+ return FALSE;
+
+ eh = sym_hashes[r_symndx - symtab_hdr->sh_info];
+
+ if (info->wrap_hash != NULL
+ && (input_section->flags & SEC_DEBUGGING) != 0)
+ eh = ((struct elf_link_hash_entry *)
+ unwrap_hash_lookup (info, input_bfd, &eh->root));
+
+ while (eh->root.type == bfd_link_hash_indirect
+ || eh->root.type == bfd_link_hash_warning)
+ eh = (struct elf_link_hash_entry *) eh->root.u.i.link;
+
+ relocation = 0;
+ if (eh->root.type == bfd_link_hash_defined
+ || eh->root.type == bfd_link_hash_defweak)
+ {
+ sym_sec = eh->root.u.def.section;
+ if (sym_sec != NULL
+ && sym_sec->output_section != NULL)
+ relocation = (eh->root.u.def.value
+ + sym_sec->output_section->vma
+ + sym_sec->output_offset);
+ }
+ else if (eh->root.type == bfd_link_hash_undefweak)
+ ;
+ else if (info->unresolved_syms_in_objects == RM_IGNORE
+ && ELF_ST_VISIBILITY (eh->other) == STV_DEFAULT)
+ ;
+ else if (!info->relocatable
+ && elf_hppa_is_dynamic_loader_symbol (eh->root.root.string))
+ continue;
+ else if (!info->relocatable)
+ {
+ bfd_boolean err;
+ err = (info->unresolved_syms_in_objects == RM_GENERATE_ERROR
+ || ELF_ST_VISIBILITY (eh->other) != STV_DEFAULT);
+ if (!info->callbacks->undefined_symbol (info,
+ eh->root.root.string,
+ input_bfd,
+ input_section,
+ rel->r_offset, err))
+ return FALSE;
+ }
+
+ if (!info->relocatable
+ && relocation == 0
+ && eh->root.type != bfd_link_hash_defined
+ && eh->root.type != bfd_link_hash_defweak
+ && eh->root.type != bfd_link_hash_undefweak)
+ {
+ if (info->unresolved_syms_in_objects == RM_IGNORE
+ && ELF_ST_VISIBILITY (eh->other) == STV_DEFAULT
+ && eh->type == STT_PARISC_MILLI)
+ {
+ if (! info->callbacks->undefined_symbol
+ (info, eh_name (eh), input_bfd,
+ input_section, rel->r_offset, FALSE))
+ return FALSE;
+ }
+ }
+ }
+
+ if (sym_sec != NULL && discarded_section (sym_sec))
+ RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+ rel, 1, relend, howto, 0, contents);
+
+ if (info->relocatable)
+ continue;
+
+ r = elf_hppa_final_link_relocate (rel, input_bfd, output_bfd,
+ input_section, contents,
+ relocation, info, sym_sec,
+ eh);
+
+ if (r != bfd_reloc_ok)
+ {
+ switch (r)
+ {
+ default:
+ abort ();
+ case bfd_reloc_overflow:
+ {
+ const char *sym_name;
+
+ if (eh != NULL)
+ sym_name = NULL;
+ 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 (!((*info->callbacks->reloc_overflow)
+ (info, (eh ? &eh->root : NULL), sym_name,
+ howto->name, (bfd_vma) 0, input_bfd,
+ input_section, rel->r_offset)))
+ return FALSE;
+ }
+ break;
+ }
+ }
+ }
+ return TRUE;
+}
+
+static const struct bfd_elf_special_section elf64_hppa_special_sections[] =
+{
+ { STRING_COMMA_LEN (".fini"), 0, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE },
+ { STRING_COMMA_LEN (".init"), 0, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE },
+ { STRING_COMMA_LEN (".plt"), 0, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE + SHF_PARISC_SHORT },
+ { STRING_COMMA_LEN (".dlt"), 0, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE + SHF_PARISC_SHORT },
+ { STRING_COMMA_LEN (".sdata"), 0, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE + SHF_PARISC_SHORT },
+ { STRING_COMMA_LEN (".sbss"), 0, SHT_NOBITS, SHF_ALLOC + SHF_WRITE + SHF_PARISC_SHORT },
+ { STRING_COMMA_LEN (".tbss"), 0, SHT_NOBITS, SHF_ALLOC + SHF_WRITE + SHF_HP_TLS },
+ { NULL, 0, 0, 0, 0 }
+};
+
+/* The hash bucket size is the standard one, namely 4. */
+
+const struct elf_size_info hppa64_elf_size_info =
+{
+ sizeof (Elf64_External_Ehdr),
+ sizeof (Elf64_External_Phdr),
+ sizeof (Elf64_External_Shdr),
+ sizeof (Elf64_External_Rel),
+ sizeof (Elf64_External_Rela),
+ sizeof (Elf64_External_Sym),
+ sizeof (Elf64_External_Dyn),
+ sizeof (Elf_External_Note),
+ 4,
+ 1,
+ 64, 3,
+ ELFCLASS64, EV_CURRENT,
+ bfd_elf64_write_out_phdrs,
+ bfd_elf64_write_shdrs_and_ehdr,
+ bfd_elf64_checksum_contents,
+ bfd_elf64_write_relocs,
+ bfd_elf64_swap_symbol_in,
+ bfd_elf64_swap_symbol_out,
+ bfd_elf64_slurp_reloc_table,
+ bfd_elf64_slurp_symbol_table,
+ bfd_elf64_swap_dyn_in,
+ bfd_elf64_swap_dyn_out,
+ bfd_elf64_swap_reloc_in,
+ bfd_elf64_swap_reloc_out,
+ bfd_elf64_swap_reloca_in,
+ bfd_elf64_swap_reloca_out
+};
+
+#define TARGET_BIG_SYM hppa_elf64_vec
+#define TARGET_BIG_NAME "elf64-hppa"
+#define ELF_ARCH bfd_arch_hppa
+#define ELF_TARGET_ID HPPA64_ELF_DATA
+#define ELF_MACHINE_CODE EM_PARISC
+/* This is not strictly correct. The maximum page size for PA2.0 is
+ 64M. But everything still uses 4k. */
+#define ELF_MAXPAGESIZE 0x1000
+#define ELF_OSABI ELFOSABI_HPUX
+
+#define bfd_elf64_bfd_reloc_type_lookup elf_hppa_reloc_type_lookup
+#define bfd_elf64_bfd_reloc_name_lookup elf_hppa_reloc_name_lookup
+#define bfd_elf64_bfd_is_local_label_name elf_hppa_is_local_label_name
+#define elf_info_to_howto elf_hppa_info_to_howto
+#define elf_info_to_howto_rel elf_hppa_info_to_howto_rel
+
+#define elf_backend_section_from_shdr elf64_hppa_section_from_shdr
+#define elf_backend_object_p elf64_hppa_object_p
+#define elf_backend_final_write_processing \
+ elf_hppa_final_write_processing
+#define elf_backend_fake_sections elf_hppa_fake_sections
+#define elf_backend_add_symbol_hook elf_hppa_add_symbol_hook
+
+#define elf_backend_relocate_section elf_hppa_relocate_section
+
+#define bfd_elf64_bfd_final_link elf_hppa_final_link
+
+#define elf_backend_create_dynamic_sections \
+ elf64_hppa_create_dynamic_sections
+#define elf_backend_post_process_headers elf64_hppa_post_process_headers
+
+#define elf_backend_omit_section_dynsym \
+ ((bfd_boolean (*) (bfd *, struct bfd_link_info *, asection *)) bfd_true)
+#define elf_backend_adjust_dynamic_symbol \
+ elf64_hppa_adjust_dynamic_symbol
+
+#define elf_backend_size_dynamic_sections \
+ elf64_hppa_size_dynamic_sections
+
+#define elf_backend_finish_dynamic_symbol \
+ elf64_hppa_finish_dynamic_symbol
+#define elf_backend_finish_dynamic_sections \
+ elf64_hppa_finish_dynamic_sections
+#define elf_backend_grok_prstatus elf64_hppa_grok_prstatus
+#define elf_backend_grok_psinfo elf64_hppa_grok_psinfo
+
+/* Stuff for the BFD linker: */
+#define bfd_elf64_bfd_link_hash_table_create \
+ elf64_hppa_hash_table_create
+
+#define elf_backend_check_relocs \
+ elf64_hppa_check_relocs
+
+#define elf_backend_size_info \
+ hppa64_elf_size_info
+
+#define elf_backend_additional_program_headers \
+ elf64_hppa_additional_program_headers
+
+#define elf_backend_modify_segment_map \
+ elf64_hppa_modify_segment_map
+
+#define elf_backend_link_output_symbol_hook \
+ elf64_hppa_link_output_symbol_hook
+
+#define elf_backend_want_got_plt 0
+#define elf_backend_plt_readonly 0
+#define elf_backend_want_plt_sym 0
+#define elf_backend_got_header_size 0
+#define elf_backend_type_change_ok TRUE
+#define elf_backend_get_symbol_type elf64_hppa_elf_get_symbol_type
+#define elf_backend_reloc_type_class elf64_hppa_reloc_type_class
+#define elf_backend_rela_normal 1
+#define elf_backend_special_sections elf64_hppa_special_sections
+#define elf_backend_action_discarded elf_hppa_action_discarded
+#define elf_backend_section_from_phdr elf64_hppa_section_from_phdr
+
+#define elf64_bed elf64_hppa_hpux_bed
+
+#include "elf64-target.h"
+
+#undef TARGET_BIG_SYM
+#define TARGET_BIG_SYM hppa_elf64_linux_vec
+#undef TARGET_BIG_NAME
+#define TARGET_BIG_NAME "elf64-hppa-linux"
+#undef ELF_OSABI
+#define ELF_OSABI ELFOSABI_GNU
+#undef elf64_bed
+#define elf64_bed elf64_hppa_linux_bed
+
+#include "elf64-target.h"
diff --git a/bfd/elf64-hppa.h b/bfd/elf64-hppa.h
new file mode 100644
index 0000000..198b446
--- /dev/null
+++ b/bfd/elf64-hppa.h
@@ -0,0 +1,51 @@
+/* ELF64/HPPA support
+
+ Copyright (C) 1999-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#ifndef _ELF64_HPPA_H
+#define _ELF64_HPPA_H
+
+#include "elf-bfd.h"
+#include "libhppa.h"
+#include "elf/hppa.h"
+
+extern elf_hppa_reloc_type elf64_hppa_reloc_final_type
+ (bfd *, elf_hppa_reloc_type, int, unsigned int);
+
+extern elf_hppa_reloc_type ** _bfd_elf64_hppa_gen_reloc_type
+ (bfd *, elf_hppa_reloc_type, int, unsigned int, int, asymbol *);
+
+/* 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_DIR64
+#define R_HPPA_GOTOFF R_PARISC_DLTREL21L
+#define R_HPPA_PCREL_CALL R_PARISC_PCREL21L
+#define R_HPPA_ABS_CALL R_PARISC_DIR17F
+#define R_HPPA_COMPLEX R_PARISC_UNIMPLEMENTED
+
+#endif /* _ELF64_HPPA_H */
diff --git a/bfd/elf64-ia64-vms.c b/bfd/elf64-ia64-vms.c
new file mode 100644
index 0000000..dd86e3c
--- /dev/null
+++ b/bfd/elf64-ia64-vms.c
@@ -0,0 +1,5608 @@
+/* IA-64 support for OpenVMS
+ Copyright (C) 1998-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+#include "elf-bfd.h"
+#include "opcode/ia64.h"
+#include "elf/ia64.h"
+#include "objalloc.h"
+#include "hashtab.h"
+#include "elfxx-ia64.h"
+#include "vms.h"
+#include "bfdver.h"
+
+/* THE RULES for all the stuff the linker creates --
+
+ GOT Entries created in response to LTOFF or LTOFF_FPTR
+ relocations. Dynamic relocs created for dynamic
+ symbols in an application; REL relocs for locals
+ in a shared library.
+
+ FPTR The canonical function descriptor. Created for local
+ symbols in applications. Descriptors for dynamic symbols
+ and local symbols in shared libraries are created by
+ ld.so. Thus there are no dynamic relocs against these
+ objects. The FPTR relocs for such _are_ passed through
+ to the dynamic relocation tables.
+
+ FULL_PLT Created for a PCREL21B relocation against a dynamic symbol.
+ Requires the creation of a PLTOFF entry. This does not
+ require any dynamic relocations.
+
+ PLTOFF Created by PLTOFF relocations. For local symbols, this
+ is an alternate function descriptor, and in shared libraries
+ requires two REL relocations. Note that this cannot be
+ transformed into an FPTR relocation, since it must be in
+ range of the GP. For dynamic symbols, this is a function
+ descriptor. */
+
+typedef struct bfd_hash_entry *(*new_hash_entry_func)
+ (struct bfd_hash_entry *, struct bfd_hash_table *, const char *);
+
+/* In dynamically (linker-) created sections, we generally need to keep track
+ of the place a symbol or expression got allocated to. This is done via hash
+ tables that store entries of the following type. */
+
+struct elf64_ia64_dyn_sym_info
+{
+ /* The addend for which this entry is relevant. */
+ bfd_vma addend;
+
+ bfd_vma got_offset;
+ bfd_vma fptr_offset;
+ bfd_vma pltoff_offset;
+ bfd_vma plt_offset;
+ bfd_vma plt2_offset;
+
+ /* The symbol table entry, if any, that this was derived from. */
+ struct elf_link_hash_entry *h;
+
+ /* Used to count non-got, non-plt relocations for delayed sizing
+ of relocation sections. */
+ struct elf64_ia64_dyn_reloc_entry
+ {
+ struct elf64_ia64_dyn_reloc_entry *next;
+ asection *srel;
+ int type;
+ int count;
+ } *reloc_entries;
+
+ /* TRUE when the section contents have been updated. */
+ unsigned got_done : 1;
+ unsigned fptr_done : 1;
+ unsigned pltoff_done : 1;
+
+ /* TRUE for the different kinds of linker data we want created. */
+ unsigned want_got : 1;
+ unsigned want_gotx : 1;
+ unsigned want_fptr : 1;
+ unsigned want_ltoff_fptr : 1;
+ unsigned want_plt : 1; /* A MIN_PLT entry. */
+ unsigned want_plt2 : 1; /* A FULL_PLT. */
+ unsigned want_pltoff : 1;
+};
+
+struct elf64_ia64_local_hash_entry
+{
+ int id;
+ unsigned int r_sym;
+ /* The number of elements in elf64_ia64_dyn_sym_info array. */
+ unsigned int count;
+ /* The number of sorted elements in elf64_ia64_dyn_sym_info array. */
+ unsigned int sorted_count;
+ /* The size of elf64_ia64_dyn_sym_info array. */
+ unsigned int size;
+ /* The array of elf64_ia64_dyn_sym_info. */
+ struct elf64_ia64_dyn_sym_info *info;
+
+ /* TRUE if this hash entry's addends was translated for
+ SHF_MERGE optimization. */
+ unsigned sec_merge_done : 1;
+};
+
+struct elf64_ia64_link_hash_entry
+{
+ struct elf_link_hash_entry root;
+
+ /* Set if this symbol is defined in a shared library.
+ We can't use root.u.def.section->owner as the symbol is an absolute
+ symbol. */
+ bfd *shl;
+
+ /* The number of elements in elf64_ia64_dyn_sym_info array. */
+ unsigned int count;
+ /* The number of sorted elements in elf64_ia64_dyn_sym_info array. */
+ unsigned int sorted_count;
+ /* The size of elf64_ia64_dyn_sym_info array. */
+ unsigned int size;
+ /* The array of elf64_ia64_dyn_sym_info. */
+ struct elf64_ia64_dyn_sym_info *info;
+};
+
+struct elf64_ia64_link_hash_table
+{
+ /* The main hash table. */
+ struct elf_link_hash_table root;
+
+ asection *fptr_sec; /* Function descriptor table (or NULL). */
+ asection *rel_fptr_sec; /* Dynamic relocation section for same. */
+ asection *pltoff_sec; /* Private descriptors for plt (or NULL). */
+ asection *fixups_sec; /* Fixups section. */
+ asection *transfer_sec; /* Transfer vector section. */
+ asection *note_sec; /* .note section. */
+
+ /* There are maybe R_IA64_GPREL22 relocations, including those
+ optimized from R_IA64_LTOFF22X, against non-SHF_IA_64_SHORT
+ sections. We need to record those sections so that we can choose
+ a proper GP to cover all R_IA64_GPREL22 relocations. */
+ asection *max_short_sec; /* Maximum short output section. */
+ bfd_vma max_short_offset; /* Maximum short offset. */
+ asection *min_short_sec; /* Minimum short output section. */
+ bfd_vma min_short_offset; /* Minimum short offset. */
+
+ htab_t loc_hash_table;
+ void *loc_hash_memory;
+};
+
+struct elf64_ia64_allocate_data
+{
+ struct bfd_link_info *info;
+ bfd_size_type ofs;
+};
+
+#define elf64_ia64_hash_table(p) \
+ (elf_hash_table_id ((struct elf_link_hash_table *) ((p)->hash)) \
+ == IA64_ELF_DATA ? ((struct elf64_ia64_link_hash_table *) ((p)->hash)) : NULL)
+
+struct elf64_ia64_vms_obj_tdata
+{
+ struct elf_obj_tdata root;
+
+ /* Ident for shared library. */
+ bfd_uint64_t ident;
+
+ /* Used only during link: offset in the .fixups section for this bfd. */
+ bfd_vma fixups_off;
+
+ /* Max number of shared libraries. */
+ unsigned int needed_count;
+};
+
+#define elf_ia64_vms_tdata(abfd) \
+ ((struct elf64_ia64_vms_obj_tdata *)((abfd)->tdata.any))
+#define elf_ia64_vms_ident(abfd) (elf_ia64_vms_tdata(abfd)->ident)
+
+struct elf64_vms_transfer
+{
+ unsigned char size[4];
+ unsigned char spare[4];
+ unsigned char tfradr1[8];
+ unsigned char tfradr2[8];
+ unsigned char tfradr3[8];
+ unsigned char tfradr4[8];
+ unsigned char tfradr5[8];
+
+ /* Local function descriptor for tfr3. */
+ unsigned char tfr3_func[8];
+ unsigned char tfr3_gp[8];
+};
+
+typedef struct
+{
+ Elf64_External_Ehdr ehdr;
+ unsigned char vms_needed_count[8];
+} Elf64_External_VMS_Ehdr;
+
+static struct elf64_ia64_dyn_sym_info * get_dyn_sym_info
+ (struct elf64_ia64_link_hash_table *,
+ struct elf_link_hash_entry *,
+ bfd *, const Elf_Internal_Rela *, bfd_boolean);
+static bfd_boolean elf64_ia64_dynamic_symbol_p
+ (struct elf_link_hash_entry *);
+static bfd_boolean elf64_ia64_choose_gp
+ (bfd *, struct bfd_link_info *, bfd_boolean);
+static void elf64_ia64_dyn_sym_traverse
+ (struct elf64_ia64_link_hash_table *,
+ bfd_boolean (*) (struct elf64_ia64_dyn_sym_info *, void *),
+ void *);
+static bfd_boolean allocate_global_data_got
+ (struct elf64_ia64_dyn_sym_info *, void *);
+static bfd_boolean allocate_global_fptr_got
+ (struct elf64_ia64_dyn_sym_info *, void *);
+static bfd_boolean allocate_local_got
+ (struct elf64_ia64_dyn_sym_info *, void *);
+static bfd_boolean allocate_dynrel_entries
+ (struct elf64_ia64_dyn_sym_info *, void *);
+static asection *get_pltoff
+ (bfd *, struct elf64_ia64_link_hash_table *);
+static asection *get_got
+ (bfd *, struct elf64_ia64_link_hash_table *);
+
+
+/* Given a ELF reloc, return the matching HOWTO structure. */
+
+static void
+elf64_ia64_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED,
+ arelent *bfd_reloc,
+ Elf_Internal_Rela *elf_reloc)
+{
+ bfd_reloc->howto
+ = ia64_elf_lookup_howto ((unsigned int) ELF64_R_TYPE (elf_reloc->r_info));
+}
+
+
+#define PLT_FULL_ENTRY_SIZE (2 * 16)
+
+static const bfd_byte plt_full_entry[PLT_FULL_ENTRY_SIZE] =
+{
+ 0x0b, 0x78, 0x00, 0x02, 0x00, 0x24, /* [MMI] addl r15=0,r1;; */
+ 0x00, 0x41, 0x3c, 0x70, 0x29, 0xc0, /* ld8.acq r16=[r15],8*/
+ 0x01, 0x08, 0x00, 0x84, /* mov r14=r1;; */
+ 0x11, 0x08, 0x00, 0x1e, 0x18, 0x10, /* [MIB] ld8 r1=[r15] */
+ 0x60, 0x80, 0x04, 0x80, 0x03, 0x00, /* mov b6=r16 */
+ 0x60, 0x00, 0x80, 0x00 /* br.few b6;; */
+};
+
+static const bfd_byte oor_brl[16] =
+{
+ 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MLX] nop.m 0 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* brl.sptk.few tgt;;*/
+ 0x00, 0x00, 0x00, 0xc0
+};
+
+
+/* These functions do relaxation for IA-64 ELF. */
+
+/* Rename some of the generic section flags to better document how they
+ are used here. */
+#define skip_relax_pass_0 sec_flg0
+#define skip_relax_pass_1 sec_flg1
+
+static void
+elf64_ia64_update_short_info (asection *sec, bfd_vma offset,
+ struct elf64_ia64_link_hash_table *ia64_info)
+{
+ /* Skip ABS and SHF_IA_64_SHORT sections. */
+ if (sec == bfd_abs_section_ptr
+ || (sec->flags & SEC_SMALL_DATA) != 0)
+ return;
+
+ if (!ia64_info->min_short_sec)
+ {
+ ia64_info->max_short_sec = sec;
+ ia64_info->max_short_offset = offset;
+ ia64_info->min_short_sec = sec;
+ ia64_info->min_short_offset = offset;
+ }
+ else if (sec == ia64_info->max_short_sec
+ && offset > ia64_info->max_short_offset)
+ ia64_info->max_short_offset = offset;
+ else if (sec == ia64_info->min_short_sec
+ && offset < ia64_info->min_short_offset)
+ ia64_info->min_short_offset = offset;
+ else if (sec->output_section->vma
+ > ia64_info->max_short_sec->vma)
+ {
+ ia64_info->max_short_sec = sec;
+ ia64_info->max_short_offset = offset;
+ }
+ else if (sec->output_section->vma
+ < ia64_info->min_short_sec->vma)
+ {
+ ia64_info->min_short_sec = sec;
+ ia64_info->min_short_offset = offset;
+ }
+}
+
+/* Use a two passes algorithm. In the first pass, branches are relaxed
+ (which may increase the size of the section). In the second pass,
+ the other relaxations are done.
+*/
+
+static bfd_boolean
+elf64_ia64_relax_section (bfd *abfd, asection *sec,
+ struct bfd_link_info *link_info,
+ bfd_boolean *again)
+{
+ struct one_fixup
+ {
+ struct one_fixup *next;
+ asection *tsec;
+ bfd_vma toff;
+ bfd_vma trampoff;
+ };
+
+ Elf_Internal_Shdr *symtab_hdr;
+ Elf_Internal_Rela *internal_relocs;
+ Elf_Internal_Rela *irel, *irelend;
+ bfd_byte *contents;
+ Elf_Internal_Sym *isymbuf = NULL;
+ struct elf64_ia64_link_hash_table *ia64_info;
+ struct one_fixup *fixups = NULL;
+ bfd_boolean changed_contents = FALSE;
+ bfd_boolean changed_relocs = FALSE;
+ bfd_boolean skip_relax_pass_0 = TRUE;
+ bfd_boolean skip_relax_pass_1 = TRUE;
+ bfd_vma gp = 0;
+
+ /* Assume we're not going to change any sizes, and we'll only need
+ one pass. */
+ *again = FALSE;
+
+ if (link_info->relocatable)
+ (*link_info->callbacks->einfo)
+ (_("%P%F: --relax and -r may not be used together\n"));
+
+ /* Don't even try to relax for non-ELF outputs. */
+ if (!is_elf_hash_table (link_info->hash))
+ return FALSE;
+
+ /* Nothing to do if there are no relocations or there is no need for
+ the current pass. */
+ if ((sec->flags & SEC_RELOC) == 0
+ || sec->reloc_count == 0
+ || (link_info->relax_pass == 0 && sec->skip_relax_pass_0)
+ || (link_info->relax_pass == 1 && sec->skip_relax_pass_1))
+ return TRUE;
+
+ ia64_info = elf64_ia64_hash_table (link_info);
+ if (ia64_info == NULL)
+ return FALSE;
+
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+
+ /* Load the relocations for this section. */
+ internal_relocs = (_bfd_elf_link_read_relocs
+ (abfd, sec, NULL, (Elf_Internal_Rela *) NULL,
+ link_info->keep_memory));
+ if (internal_relocs == NULL)
+ return FALSE;
+
+ irelend = internal_relocs + sec->reloc_count;
+
+ /* Get the section contents. */
+ if (elf_section_data (sec)->this_hdr.contents != NULL)
+ contents = elf_section_data (sec)->this_hdr.contents;
+ else
+ {
+ if (!bfd_malloc_and_get_section (abfd, sec, &contents))
+ goto error_return;
+ }
+
+ for (irel = internal_relocs; irel < irelend; irel++)
+ {
+ unsigned long r_type = ELF64_R_TYPE (irel->r_info);
+ bfd_vma symaddr, reladdr, trampoff, toff, roff;
+ asection *tsec;
+ struct one_fixup *f;
+ bfd_size_type amt;
+ bfd_boolean is_branch;
+ struct elf64_ia64_dyn_sym_info *dyn_i;
+
+ switch (r_type)
+ {
+ case R_IA64_PCREL21B:
+ case R_IA64_PCREL21BI:
+ case R_IA64_PCREL21M:
+ case R_IA64_PCREL21F:
+ /* In pass 1, all br relaxations are done. We can skip it. */
+ if (link_info->relax_pass == 1)
+ continue;
+ skip_relax_pass_0 = FALSE;
+ is_branch = TRUE;
+ break;
+
+ case R_IA64_PCREL60B:
+ /* We can't optimize brl to br in pass 0 since br relaxations
+ will increase the code size. Defer it to pass 1. */
+ if (link_info->relax_pass == 0)
+ {
+ skip_relax_pass_1 = FALSE;
+ continue;
+ }
+ is_branch = TRUE;
+ break;
+
+ case R_IA64_GPREL22:
+ /* Update max_short_sec/min_short_sec. */
+
+ case R_IA64_LTOFF22X:
+ case R_IA64_LDXMOV:
+ /* We can't relax ldx/mov in pass 0 since br relaxations will
+ increase the code size. Defer it to pass 1. */
+ if (link_info->relax_pass == 0)
+ {
+ skip_relax_pass_1 = FALSE;
+ continue;
+ }
+ is_branch = FALSE;
+ break;
+
+ default:
+ continue;
+ }
+
+ /* 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. */
+ Elf_Internal_Sym *isym;
+
+ /* Read this BFD's local symbols. */
+ if (isymbuf == NULL)
+ {
+ isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
+ if (isymbuf == NULL)
+ isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
+ symtab_hdr->sh_info, 0,
+ NULL, NULL, NULL);
+ if (isymbuf == 0)
+ goto error_return;
+ }
+
+ isym = isymbuf + ELF64_R_SYM (irel->r_info);
+ if (isym->st_shndx == SHN_UNDEF)
+ continue; /* We can't do anything with undefined symbols. */
+ else if (isym->st_shndx == SHN_ABS)
+ tsec = bfd_abs_section_ptr;
+ else if (isym->st_shndx == SHN_COMMON)
+ tsec = bfd_com_section_ptr;
+ else if (isym->st_shndx == SHN_IA_64_ANSI_COMMON)
+ tsec = bfd_com_section_ptr;
+ else
+ tsec = bfd_section_from_elf_index (abfd, isym->st_shndx);
+
+ toff = isym->st_value;
+ dyn_i = get_dyn_sym_info (ia64_info, NULL, abfd, irel, FALSE);
+ }
+ else
+ {
+ unsigned long indx;
+ struct elf_link_hash_entry *h;
+
+ indx = ELF64_R_SYM (irel->r_info) - symtab_hdr->sh_info;
+ h = elf_sym_hashes (abfd)[indx];
+ BFD_ASSERT (h != NULL);
+
+ 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;
+
+ dyn_i = get_dyn_sym_info (ia64_info, h, abfd, irel, FALSE);
+
+ /* For branches to dynamic symbols, we're interested instead
+ in a branch to the PLT entry. */
+ if (is_branch && dyn_i && dyn_i->want_plt2)
+ {
+ /* Internal branches shouldn't be sent to the PLT.
+ Leave this for now and we'll give an error later. */
+ if (r_type != R_IA64_PCREL21B)
+ continue;
+
+ tsec = ia64_info->root.splt;
+ toff = dyn_i->plt2_offset;
+ BFD_ASSERT (irel->r_addend == 0);
+ }
+
+ /* Can't do anything else with dynamic symbols. */
+ else if (elf64_ia64_dynamic_symbol_p (h))
+ continue;
+
+ else
+ {
+ /* We can't do anything with undefined symbols. */
+ if (h->root.type == bfd_link_hash_undefined
+ || h->root.type == bfd_link_hash_undefweak)
+ continue;
+
+ tsec = h->root.u.def.section;
+ toff = h->root.u.def.value;
+ }
+ }
+
+ toff += irel->r_addend;
+
+ symaddr = tsec->output_section->vma + tsec->output_offset + toff;
+
+ roff = irel->r_offset;
+
+ if (is_branch)
+ {
+ bfd_signed_vma offset;
+
+ reladdr = (sec->output_section->vma
+ + sec->output_offset
+ + roff) & (bfd_vma) -4;
+
+ /* The .plt section is aligned at 32byte and the .text section
+ is aligned at 64byte. The .text section is right after the
+ .plt section. After the first relaxation pass, linker may
+ increase the gap between the .plt and .text sections up
+ to 32byte. We assume linker will always insert 32byte
+ between the .plt and .text sections after the first
+ relaxation pass. */
+ if (tsec == ia64_info->root.splt)
+ offset = -0x1000000 + 32;
+ else
+ offset = -0x1000000;
+
+ /* If the branch is in range, no need to do anything. */
+ if ((bfd_signed_vma) (symaddr - reladdr) >= offset
+ && (bfd_signed_vma) (symaddr - reladdr) <= 0x0FFFFF0)
+ {
+ /* If the 60-bit branch is in 21-bit range, optimize it. */
+ if (r_type == R_IA64_PCREL60B)
+ {
+ ia64_elf_relax_brl (contents, roff);
+
+ irel->r_info = ELF64_R_INFO (ELF64_R_SYM (irel->r_info),
+ R_IA64_PCREL21B);
+
+ /* If the original relocation offset points to slot
+ 1, change it to slot 2. */
+ if ((irel->r_offset & 3) == 1)
+ irel->r_offset += 1;
+ }
+
+ continue;
+ }
+ else if (r_type == R_IA64_PCREL60B)
+ continue;
+ else if (ia64_elf_relax_br (contents, roff))
+ {
+ irel->r_info = ELF64_R_INFO (ELF64_R_SYM (irel->r_info),
+ R_IA64_PCREL60B);
+
+ /* Make the relocation offset point to slot 1. */
+ irel->r_offset = (irel->r_offset & ~((bfd_vma) 0x3)) + 1;
+ continue;
+ }
+
+ /* We can't put a trampoline in a .init/.fini section. Issue
+ an error. */
+ if (strcmp (sec->output_section->name, ".init") == 0
+ || strcmp (sec->output_section->name, ".fini") == 0)
+ {
+ (*_bfd_error_handler)
+ (_("%B: Can't relax br at 0x%lx in section `%A'. Please use brl or indirect branch."),
+ sec->owner, sec, (unsigned long) roff);
+ bfd_set_error (bfd_error_bad_value);
+ goto error_return;
+ }
+
+ /* If the branch and target are in the same section, you've
+ got one honking big section and we can't help you unless
+ you are branching backwards. You'll get an error message
+ later. */
+ if (tsec == sec && toff > roff)
+ continue;
+
+ /* Look for an existing fixup to this address. */
+ for (f = fixups; f ; f = f->next)
+ if (f->tsec == tsec && f->toff == toff)
+ break;
+
+ if (f == NULL)
+ {
+ /* Two alternatives: If it's a branch to a PLT entry, we can
+ make a copy of the FULL_PLT entry. Otherwise, we'll have
+ to use a `brl' insn to get where we're going. */
+
+ size_t size;
+
+ if (tsec == ia64_info->root.splt)
+ size = sizeof (plt_full_entry);
+ else
+ size = sizeof (oor_brl);
+
+ /* Resize the current section to make room for the new branch. */
+ trampoff = (sec->size + 15) & (bfd_vma) -16;
+
+ /* If trampoline is out of range, there is nothing we
+ can do. */
+ offset = trampoff - (roff & (bfd_vma) -4);
+ if (offset < -0x1000000 || offset > 0x0FFFFF0)
+ continue;
+
+ amt = trampoff + size;
+ contents = (bfd_byte *) bfd_realloc (contents, amt);
+ if (contents == NULL)
+ goto error_return;
+ sec->size = amt;
+
+ if (tsec == ia64_info->root.splt)
+ {
+ memcpy (contents + trampoff, plt_full_entry, size);
+
+ /* Hijack the old relocation for use as the PLTOFF reloc. */
+ irel->r_info = ELF64_R_INFO (ELF64_R_SYM (irel->r_info),
+ R_IA64_PLTOFF22);
+ irel->r_offset = trampoff;
+ }
+ else
+ {
+ memcpy (contents + trampoff, oor_brl, size);
+ irel->r_info = ELF64_R_INFO (ELF64_R_SYM (irel->r_info),
+ R_IA64_PCREL60B);
+ irel->r_offset = trampoff + 2;
+ }
+
+ /* Record the fixup so we don't do it again this section. */
+ f = (struct one_fixup *)
+ bfd_malloc ((bfd_size_type) sizeof (*f));
+ f->next = fixups;
+ f->tsec = tsec;
+ f->toff = toff;
+ f->trampoff = trampoff;
+ fixups = f;
+ }
+ else
+ {
+ /* If trampoline is out of range, there is nothing we
+ can do. */
+ offset = f->trampoff - (roff & (bfd_vma) -4);
+ if (offset < -0x1000000 || offset > 0x0FFFFF0)
+ continue;
+
+ /* Nop out the reloc, since we're finalizing things here. */
+ irel->r_info = ELF64_R_INFO (0, R_IA64_NONE);
+ }
+
+ /* Fix up the existing branch to hit the trampoline. */
+ if (ia64_elf_install_value (contents + roff, offset, r_type)
+ != bfd_reloc_ok)
+ goto error_return;
+
+ changed_contents = TRUE;
+ changed_relocs = TRUE;
+ }
+ else
+ {
+ /* Fetch the gp. */
+ if (gp == 0)
+ {
+ bfd *obfd = sec->output_section->owner;
+ gp = _bfd_get_gp_value (obfd);
+ if (gp == 0)
+ {
+ if (!elf64_ia64_choose_gp (obfd, link_info, FALSE))
+ goto error_return;
+ gp = _bfd_get_gp_value (obfd);
+ }
+ }
+
+ /* If the data is out of range, do nothing. */
+ if ((bfd_signed_vma) (symaddr - gp) >= 0x200000
+ ||(bfd_signed_vma) (symaddr - gp) < -0x200000)
+ continue;
+
+ if (r_type == R_IA64_GPREL22)
+ elf64_ia64_update_short_info (tsec->output_section,
+ tsec->output_offset + toff,
+ ia64_info);
+ else if (r_type == R_IA64_LTOFF22X)
+ {
+ /* Can't deal yet correctly with ABS symbols. */
+ if (bfd_is_abs_section (tsec))
+ continue;
+
+ irel->r_info = ELF64_R_INFO (ELF64_R_SYM (irel->r_info),
+ R_IA64_GPREL22);
+ changed_relocs = TRUE;
+
+ elf64_ia64_update_short_info (tsec->output_section,
+ tsec->output_offset + toff,
+ ia64_info);
+ }
+ else
+ {
+ ia64_elf_relax_ldxmov (contents, roff);
+ irel->r_info = ELF64_R_INFO (0, R_IA64_NONE);
+ changed_contents = TRUE;
+ changed_relocs = TRUE;
+ }
+ }
+ }
+
+ /* ??? If we created fixups, this may push the code segment large
+ enough that the data segment moves, which will change the GP.
+ Reset the GP so that we re-calculate next round. We need to
+ do this at the _beginning_ of the next round; now will not do. */
+
+ /* Clean up and go home. */
+ while (fixups)
+ {
+ struct one_fixup *f = fixups;
+ fixups = fixups->next;
+ free (f);
+ }
+
+ if (isymbuf != NULL
+ && symtab_hdr->contents != (unsigned char *) isymbuf)
+ {
+ if (! link_info->keep_memory)
+ free (isymbuf);
+ else
+ {
+ /* Cache the symbols for elf_link_input_bfd. */
+ symtab_hdr->contents = (unsigned char *) isymbuf;
+ }
+ }
+
+ if (contents != NULL
+ && elf_section_data (sec)->this_hdr.contents != contents)
+ {
+ if (!changed_contents && !link_info->keep_memory)
+ free (contents);
+ else
+ {
+ /* Cache the section contents for elf_link_input_bfd. */
+ elf_section_data (sec)->this_hdr.contents = contents;
+ }
+ }
+
+ if (elf_section_data (sec)->relocs != internal_relocs)
+ {
+ if (!changed_relocs)
+ free (internal_relocs);
+ else
+ elf_section_data (sec)->relocs = internal_relocs;
+ }
+
+ if (link_info->relax_pass == 0)
+ {
+ /* Pass 0 is only needed to relax br. */
+ sec->skip_relax_pass_0 = skip_relax_pass_0;
+ sec->skip_relax_pass_1 = skip_relax_pass_1;
+ }
+
+ *again = changed_contents || changed_relocs;
+ return TRUE;
+
+ error_return:
+ if (isymbuf != NULL && (unsigned char *) isymbuf != symtab_hdr->contents)
+ free (isymbuf);
+ if (contents != NULL
+ && elf_section_data (sec)->this_hdr.contents != contents)
+ free (contents);
+ if (internal_relocs != NULL
+ && elf_section_data (sec)->relocs != internal_relocs)
+ free (internal_relocs);
+ return FALSE;
+}
+#undef skip_relax_pass_0
+#undef skip_relax_pass_1
+
+/* Return TRUE if NAME is an unwind table section name. */
+
+static inline bfd_boolean
+is_unwind_section_name (bfd *abfd ATTRIBUTE_UNUSED, const char *name)
+{
+ return ((CONST_STRNEQ (name, ELF_STRING_ia64_unwind)
+ && ! CONST_STRNEQ (name, ELF_STRING_ia64_unwind_info))
+ || CONST_STRNEQ (name, ELF_STRING_ia64_unwind_once));
+}
+
+
+/* Convert IA-64 specific section flags to bfd internal section flags. */
+
+/* ??? There is no bfd internal flag equivalent to the SHF_IA_64_NORECOV
+ flag. */
+
+static bfd_boolean
+elf64_ia64_section_flags (flagword *flags,
+ const Elf_Internal_Shdr *hdr)
+{
+ if (hdr->sh_flags & SHF_IA_64_SHORT)
+ *flags |= SEC_SMALL_DATA;
+
+ return TRUE;
+}
+
+/* Set the correct type for an IA-64 ELF section. We do this by the
+ section name, which is a hack, but ought to work. */
+
+static bfd_boolean
+elf64_ia64_fake_sections (bfd *abfd, Elf_Internal_Shdr *hdr,
+ asection *sec)
+{
+ const char *name;
+
+ name = bfd_get_section_name (abfd, sec);
+
+ if (is_unwind_section_name (abfd, name))
+ {
+ /* We don't have the sections numbered at this point, so sh_info
+ is set later, in elf64_ia64_final_write_processing. */
+ hdr->sh_type = SHT_IA_64_UNWIND;
+ hdr->sh_flags |= SHF_LINK_ORDER;
+ }
+ else if (strcmp (name, ELF_STRING_ia64_archext) == 0)
+ hdr->sh_type = SHT_IA_64_EXT;
+
+ if (sec->flags & SEC_SMALL_DATA)
+ hdr->sh_flags |= SHF_IA_64_SHORT;
+
+ 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 bfd_boolean
+elf64_ia64_add_symbol_hook (bfd *abfd,
+ struct bfd_link_info *info,
+ Elf_Internal_Sym *sym,
+ const char **namep ATTRIBUTE_UNUSED,
+ flagword *flagsp ATTRIBUTE_UNUSED,
+ asection **secp,
+ bfd_vma *valp)
+{
+ if (sym->st_shndx == SHN_COMMON
+ && !info->relocatable
+ && sym->st_size <= elf_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_with_flags (abfd, ".scommon",
+ (SEC_ALLOC
+ | SEC_IS_COMMON
+ | SEC_LINKER_CREATED));
+ if (scomm == NULL)
+ return FALSE;
+ }
+
+ *secp = scomm;
+ *valp = sym->st_size;
+ }
+
+ return TRUE;
+}
+
+/* According to the Tahoe assembler spec, all labels starting with a
+ '.' are local. */
+
+static bfd_boolean
+elf64_ia64_is_local_label_name (bfd *abfd ATTRIBUTE_UNUSED,
+ const char *name)
+{
+ return name[0] == '.';
+}
+
+/* Should we do dynamic things to this symbol? */
+
+static bfd_boolean
+elf64_ia64_dynamic_symbol_p (struct elf_link_hash_entry *h)
+{
+ return h != NULL && h->def_dynamic;
+}
+
+static struct bfd_hash_entry*
+elf64_ia64_new_elf_hash_entry (struct bfd_hash_entry *entry,
+ struct bfd_hash_table *table,
+ const char *string)
+{
+ struct elf64_ia64_link_hash_entry *ret;
+ ret = (struct elf64_ia64_link_hash_entry *) entry;
+
+ /* Allocate the structure if it has not already been allocated by a
+ subclass. */
+ if (!ret)
+ ret = bfd_hash_allocate (table, sizeof (*ret));
+
+ if (!ret)
+ return 0;
+
+ /* Call the allocation method of the superclass. */
+ ret = ((struct elf64_ia64_link_hash_entry *)
+ _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry *) ret,
+ table, string));
+
+ ret->info = NULL;
+ ret->count = 0;
+ ret->sorted_count = 0;
+ ret->size = 0;
+ return (struct bfd_hash_entry *) ret;
+}
+
+static void
+elf64_ia64_hash_hide_symbol (struct bfd_link_info *info,
+ struct elf_link_hash_entry *xh,
+ bfd_boolean force_local)
+{
+ struct elf64_ia64_link_hash_entry *h;
+ struct elf64_ia64_dyn_sym_info *dyn_i;
+ unsigned int count;
+
+ h = (struct elf64_ia64_link_hash_entry *)xh;
+
+ _bfd_elf_link_hash_hide_symbol (info, &h->root, force_local);
+
+ for (count = h->count, dyn_i = h->info;
+ count != 0;
+ count--, dyn_i++)
+ {
+ dyn_i->want_plt2 = 0;
+ dyn_i->want_plt = 0;
+ }
+}
+
+/* Compute a hash of a local hash entry. */
+
+static hashval_t
+elf64_ia64_local_htab_hash (const void *ptr)
+{
+ struct elf64_ia64_local_hash_entry *entry
+ = (struct elf64_ia64_local_hash_entry *) ptr;
+
+ return ELF_LOCAL_SYMBOL_HASH (entry->id, entry->r_sym);
+}
+
+/* Compare local hash entries. */
+
+static int
+elf64_ia64_local_htab_eq (const void *ptr1, const void *ptr2)
+{
+ struct elf64_ia64_local_hash_entry *entry1
+ = (struct elf64_ia64_local_hash_entry *) ptr1;
+ struct elf64_ia64_local_hash_entry *entry2
+ = (struct elf64_ia64_local_hash_entry *) ptr2;
+
+ return entry1->id == entry2->id && entry1->r_sym == entry2->r_sym;
+}
+
+/* Free the global elf64_ia64_dyn_sym_info array. */
+
+static bfd_boolean
+elf64_ia64_global_dyn_info_free (void **xentry,
+ void * unused ATTRIBUTE_UNUSED)
+{
+ struct elf64_ia64_link_hash_entry *entry
+ = (struct elf64_ia64_link_hash_entry *) xentry;
+
+ if (entry->root.root.type == bfd_link_hash_warning)
+ entry = (struct elf64_ia64_link_hash_entry *) entry->root.root.u.i.link;
+
+ if (entry->info)
+ {
+ free (entry->info);
+ entry->info = NULL;
+ entry->count = 0;
+ entry->sorted_count = 0;
+ entry->size = 0;
+ }
+
+ return TRUE;
+}
+
+/* Free the local elf64_ia64_dyn_sym_info array. */
+
+static bfd_boolean
+elf64_ia64_local_dyn_info_free (void **slot,
+ void * unused ATTRIBUTE_UNUSED)
+{
+ struct elf64_ia64_local_hash_entry *entry
+ = (struct elf64_ia64_local_hash_entry *) *slot;
+
+ if (entry->info)
+ {
+ free (entry->info);
+ entry->info = NULL;
+ entry->count = 0;
+ entry->sorted_count = 0;
+ entry->size = 0;
+ }
+
+ return TRUE;
+}
+
+/* Destroy IA-64 linker hash table. */
+
+static void
+elf64_ia64_link_hash_table_free (bfd *obfd)
+{
+ struct elf64_ia64_link_hash_table *ia64_info
+ = (struct elf64_ia64_link_hash_table *) obfd->link.hash;
+ if (ia64_info->loc_hash_table)
+ {
+ htab_traverse (ia64_info->loc_hash_table,
+ elf64_ia64_local_dyn_info_free, NULL);
+ htab_delete (ia64_info->loc_hash_table);
+ }
+ if (ia64_info->loc_hash_memory)
+ objalloc_free ((struct objalloc *) ia64_info->loc_hash_memory);
+ elf_link_hash_traverse (&ia64_info->root,
+ elf64_ia64_global_dyn_info_free, NULL);
+ _bfd_elf_link_hash_table_free (obfd);
+}
+
+/* Create the derived linker hash table. The IA-64 ELF port uses this
+ derived hash table to keep information specific to the IA-64 ElF
+ linker (without using static variables). */
+
+static struct bfd_link_hash_table *
+elf64_ia64_hash_table_create (bfd *abfd)
+{
+ struct elf64_ia64_link_hash_table *ret;
+
+ ret = bfd_zmalloc ((bfd_size_type) sizeof (*ret));
+ if (!ret)
+ return NULL;
+
+ if (!_bfd_elf_link_hash_table_init (&ret->root, abfd,
+ elf64_ia64_new_elf_hash_entry,
+ sizeof (struct elf64_ia64_link_hash_entry),
+ IA64_ELF_DATA))
+ {
+ free (ret);
+ return NULL;
+ }
+
+ ret->loc_hash_table = htab_try_create (1024, elf64_ia64_local_htab_hash,
+ elf64_ia64_local_htab_eq, NULL);
+ ret->loc_hash_memory = objalloc_create ();
+ if (!ret->loc_hash_table || !ret->loc_hash_memory)
+ {
+ elf64_ia64_link_hash_table_free (abfd);
+ return NULL;
+ }
+ ret->root.root.hash_table_free = elf64_ia64_link_hash_table_free;
+
+ return &ret->root.root;
+}
+
+/* Traverse both local and global hash tables. */
+
+struct elf64_ia64_dyn_sym_traverse_data
+{
+ bfd_boolean (*func) (struct elf64_ia64_dyn_sym_info *, void *);
+ void * data;
+};
+
+static bfd_boolean
+elf64_ia64_global_dyn_sym_thunk (struct bfd_hash_entry *xentry,
+ void * xdata)
+{
+ struct elf64_ia64_link_hash_entry *entry
+ = (struct elf64_ia64_link_hash_entry *) xentry;
+ struct elf64_ia64_dyn_sym_traverse_data *data
+ = (struct elf64_ia64_dyn_sym_traverse_data *) xdata;
+ struct elf64_ia64_dyn_sym_info *dyn_i;
+ unsigned int count;
+
+ if (entry->root.root.type == bfd_link_hash_warning)
+ entry = (struct elf64_ia64_link_hash_entry *) entry->root.root.u.i.link;
+
+ for (count = entry->count, dyn_i = entry->info;
+ count != 0;
+ count--, dyn_i++)
+ if (! (*data->func) (dyn_i, data->data))
+ return FALSE;
+ return TRUE;
+}
+
+static bfd_boolean
+elf64_ia64_local_dyn_sym_thunk (void **slot, void * xdata)
+{
+ struct elf64_ia64_local_hash_entry *entry
+ = (struct elf64_ia64_local_hash_entry *) *slot;
+ struct elf64_ia64_dyn_sym_traverse_data *data
+ = (struct elf64_ia64_dyn_sym_traverse_data *) xdata;
+ struct elf64_ia64_dyn_sym_info *dyn_i;
+ unsigned int count;
+
+ for (count = entry->count, dyn_i = entry->info;
+ count != 0;
+ count--, dyn_i++)
+ if (! (*data->func) (dyn_i, data->data))
+ return FALSE;
+ return TRUE;
+}
+
+static void
+elf64_ia64_dyn_sym_traverse (struct elf64_ia64_link_hash_table *ia64_info,
+ bfd_boolean (*func) (struct elf64_ia64_dyn_sym_info *, void *),
+ void * data)
+{
+ struct elf64_ia64_dyn_sym_traverse_data xdata;
+
+ xdata.func = func;
+ xdata.data = data;
+
+ elf_link_hash_traverse (&ia64_info->root,
+ elf64_ia64_global_dyn_sym_thunk, &xdata);
+ htab_traverse (ia64_info->loc_hash_table,
+ elf64_ia64_local_dyn_sym_thunk, &xdata);
+}
+
+#define NOTE_NAME "IPF/VMS"
+
+static bfd_boolean
+create_ia64_vms_notes (bfd *abfd, struct bfd_link_info *info,
+ unsigned int time_hi, unsigned int time_lo)
+{
+#define NBR_NOTES 7
+ Elf_Internal_Note notes[NBR_NOTES];
+ char *module_name;
+ int module_name_len;
+ unsigned char cur_time[8];
+ Elf64_External_VMS_ORIG_DYN_Note *orig_dyn;
+ unsigned int orig_dyn_size;
+ unsigned int note_size;
+ int i;
+ unsigned char *noteptr;
+ unsigned char *note_contents;
+ struct elf64_ia64_link_hash_table *ia64_info;
+
+ ia64_info = elf64_ia64_hash_table (info);
+
+ module_name = vms_get_module_name (bfd_get_filename (abfd), TRUE);
+ module_name_len = strlen (module_name) + 1;
+
+ bfd_putl32 (time_lo, cur_time + 0);
+ bfd_putl32 (time_hi, cur_time + 4);
+
+ /* Note 0: IMGNAM. */
+ notes[0].type = NT_VMS_IMGNAM;
+ notes[0].descdata = module_name;
+ notes[0].descsz = module_name_len;
+
+ /* Note 1: GSTNAM. */
+ notes[1].type = NT_VMS_GSTNAM;
+ notes[1].descdata = module_name;
+ notes[1].descsz = module_name_len;
+
+ /* Note 2: IMGID. */
+#define IMG_ID "V1.0"
+ notes[2].type = NT_VMS_IMGID;
+ notes[2].descdata = IMG_ID;
+ notes[2].descsz = sizeof (IMG_ID);
+
+ /* Note 3: Linktime. */
+ notes[3].type = NT_VMS_LINKTIME;
+ notes[3].descdata = (char *)cur_time;
+ notes[3].descsz = sizeof (cur_time);
+
+ /* Note 4: Linker id. */
+ notes[4].type = NT_VMS_LINKID;
+ notes[4].descdata = "GNU ld " BFD_VERSION_STRING;
+ notes[4].descsz = strlen (notes[4].descdata) + 1;
+
+ /* Note 5: Original dyn. */
+ orig_dyn_size = (sizeof (*orig_dyn) + sizeof (IMG_ID) - 1 + 7) & ~7;
+ orig_dyn = bfd_zalloc (abfd, orig_dyn_size);
+ if (orig_dyn == NULL)
+ return FALSE;
+ bfd_putl32 (1, orig_dyn->major_id);
+ bfd_putl32 (3, orig_dyn->minor_id);
+ memcpy (orig_dyn->manipulation_date, cur_time, sizeof (cur_time));
+ bfd_putl64 (VMS_LF_IMGSTA | VMS_LF_MAIN, orig_dyn->link_flags);
+ bfd_putl32 (EF_IA_64_ABI64, orig_dyn->elf_flags);
+ memcpy (orig_dyn->imgid, IMG_ID, sizeof (IMG_ID));
+ notes[5].type = NT_VMS_ORIG_DYN;
+ notes[5].descdata = (char *)orig_dyn;
+ notes[5].descsz = orig_dyn_size;
+
+ /* Note 3: Patchtime. */
+ notes[6].type = NT_VMS_PATCHTIME;
+ notes[6].descdata = (char *)cur_time;
+ notes[6].descsz = sizeof (cur_time);
+
+ /* Compute notes size. */
+ note_size = 0;
+ for (i = 0; i < NBR_NOTES; i++)
+ note_size += sizeof (Elf64_External_VMS_Note) - 1
+ + ((sizeof (NOTE_NAME) - 1 + 7) & ~7)
+ + ((notes[i].descsz + 7) & ~7);
+
+ /* Malloc a temporary buffer large enough for most notes */
+ note_contents = (unsigned char *) bfd_zalloc (abfd, note_size);
+ if (note_contents == NULL)
+ return FALSE;
+ noteptr = note_contents;
+
+ /* Fill notes. */
+ for (i = 0; i < NBR_NOTES; i++)
+ {
+ Elf64_External_VMS_Note *enote = (Elf64_External_VMS_Note *) noteptr;
+
+ bfd_putl64 (sizeof (NOTE_NAME) - 1, enote->namesz);
+ bfd_putl64 (notes[i].descsz, enote->descsz);
+ bfd_putl64 (notes[i].type, enote->type);
+
+ noteptr = (unsigned char *)enote->name;
+ memcpy (noteptr, NOTE_NAME, sizeof (NOTE_NAME) - 1);
+ noteptr += (sizeof (NOTE_NAME) - 1 + 7) & ~7;
+ memcpy (noteptr, notes[i].descdata, notes[i].descsz);
+ noteptr += (notes[i].descsz + 7) & ~7;
+ }
+
+ ia64_info->note_sec->contents = note_contents;
+ ia64_info->note_sec->size = note_size;
+
+ free (module_name);
+
+ return TRUE;
+}
+
+static bfd_boolean
+elf64_ia64_create_dynamic_sections (bfd *abfd,
+ struct bfd_link_info *info)
+{
+ struct elf64_ia64_link_hash_table *ia64_info;
+ asection *s;
+ flagword flags;
+ const struct elf_backend_data *bed;
+
+ ia64_info = elf64_ia64_hash_table (info);
+ if (ia64_info == NULL)
+ return FALSE;
+
+ if (elf_hash_table (info)->dynamic_sections_created)
+ return TRUE;
+
+ abfd = elf_hash_table (info)->dynobj;
+ bed = get_elf_backend_data (abfd);
+
+ flags = bed->dynamic_sec_flags;
+
+ s = bfd_make_section_anyway_with_flags (abfd, ".dynamic",
+ flags | SEC_READONLY);
+ if (s == NULL
+ || ! bfd_set_section_alignment (abfd, s, bed->s->log_file_align))
+ return FALSE;
+
+ s = bfd_make_section_anyway_with_flags (abfd, ".plt", flags | SEC_READONLY);
+ if (s == NULL
+ || ! bfd_set_section_alignment (abfd, s, bed->plt_alignment))
+ return FALSE;
+ ia64_info->root.splt = s;
+
+ if (!get_got (abfd, ia64_info))
+ return FALSE;
+
+ if (!get_pltoff (abfd, ia64_info))
+ return FALSE;
+
+ s = bfd_make_section_anyway_with_flags (abfd, ".vmsdynstr",
+ (SEC_ALLOC
+ | SEC_HAS_CONTENTS
+ | SEC_IN_MEMORY
+ | SEC_LINKER_CREATED));
+ if (s == NULL
+ || !bfd_set_section_alignment (abfd, s, 0))
+ return FALSE;
+
+ /* Create a fixup section. */
+ s = bfd_make_section_anyway_with_flags (abfd, ".fixups",
+ (SEC_ALLOC
+ | SEC_HAS_CONTENTS
+ | SEC_IN_MEMORY
+ | SEC_LINKER_CREATED));
+ if (s == NULL
+ || !bfd_set_section_alignment (abfd, s, 3))
+ return FALSE;
+ ia64_info->fixups_sec = s;
+
+ /* Create the transfer fixup section. */
+ s = bfd_make_section_anyway_with_flags (abfd, ".transfer",
+ (SEC_ALLOC
+ | SEC_HAS_CONTENTS
+ | SEC_IN_MEMORY
+ | SEC_LINKER_CREATED));
+ if (s == NULL
+ || !bfd_set_section_alignment (abfd, s, 3))
+ return FALSE;
+ s->size = sizeof (struct elf64_vms_transfer);
+ ia64_info->transfer_sec = s;
+
+ /* Create note section. */
+ s = bfd_make_section_anyway_with_flags (abfd, ".vms.note",
+ (SEC_LINKER_CREATED
+ | SEC_HAS_CONTENTS
+ | SEC_IN_MEMORY
+ | SEC_READONLY));
+ if (s == NULL
+ || !bfd_set_section_alignment (abfd, s, 3))
+ return FALSE;
+ ia64_info->note_sec = s;
+
+ elf_hash_table (info)->dynamic_sections_created = TRUE;
+ return TRUE;
+}
+
+/* Find and/or create a hash entry for local symbol. */
+static struct elf64_ia64_local_hash_entry *
+get_local_sym_hash (struct elf64_ia64_link_hash_table *ia64_info,
+ bfd *abfd, const Elf_Internal_Rela *rel,
+ bfd_boolean create)
+{
+ struct elf64_ia64_local_hash_entry e, *ret;
+ asection *sec = abfd->sections;
+ hashval_t h = ELF_LOCAL_SYMBOL_HASH (sec->id,
+ ELF64_R_SYM (rel->r_info));
+ void **slot;
+
+ e.id = sec->id;
+ e.r_sym = ELF64_R_SYM (rel->r_info);
+ slot = htab_find_slot_with_hash (ia64_info->loc_hash_table, &e, h,
+ create ? INSERT : NO_INSERT);
+
+ if (!slot)
+ return NULL;
+
+ if (*slot)
+ return (struct elf64_ia64_local_hash_entry *) *slot;
+
+ ret = (struct elf64_ia64_local_hash_entry *)
+ objalloc_alloc ((struct objalloc *) ia64_info->loc_hash_memory,
+ sizeof (struct elf64_ia64_local_hash_entry));
+ if (ret)
+ {
+ memset (ret, 0, sizeof (*ret));
+ ret->id = sec->id;
+ ret->r_sym = ELF64_R_SYM (rel->r_info);
+ *slot = ret;
+ }
+ return ret;
+}
+
+/* Used to sort elf64_ia64_dyn_sym_info array. */
+
+static int
+addend_compare (const void *xp, const void *yp)
+{
+ const struct elf64_ia64_dyn_sym_info *x
+ = (const struct elf64_ia64_dyn_sym_info *) xp;
+ const struct elf64_ia64_dyn_sym_info *y
+ = (const struct elf64_ia64_dyn_sym_info *) yp;
+
+ return x->addend < y->addend ? -1 : x->addend > y->addend ? 1 : 0;
+}
+
+/* Sort elf64_ia64_dyn_sym_info array and remove duplicates. */
+
+static unsigned int
+sort_dyn_sym_info (struct elf64_ia64_dyn_sym_info *info,
+ unsigned int count)
+{
+ bfd_vma curr, prev, got_offset;
+ unsigned int i, kept, dupes, diff, dest, src, len;
+
+ qsort (info, count, sizeof (*info), addend_compare);
+
+ /* Find the first duplicate. */
+ prev = info [0].addend;
+ got_offset = info [0].got_offset;
+ for (i = 1; i < count; i++)
+ {
+ curr = info [i].addend;
+ if (curr == prev)
+ {
+ /* For duplicates, make sure that GOT_OFFSET is valid. */
+ if (got_offset == (bfd_vma) -1)
+ got_offset = info [i].got_offset;
+ break;
+ }
+ got_offset = info [i].got_offset;
+ prev = curr;
+ }
+
+ /* We may move a block of elements to here. */
+ dest = i++;
+
+ /* Remove duplicates. */
+ if (i < count)
+ {
+ while (i < count)
+ {
+ /* For duplicates, make sure that the kept one has a valid
+ got_offset. */
+ kept = dest - 1;
+ if (got_offset != (bfd_vma) -1)
+ info [kept].got_offset = got_offset;
+
+ curr = info [i].addend;
+ got_offset = info [i].got_offset;
+
+ /* Move a block of elements whose first one is different from
+ the previous. */
+ if (curr == prev)
+ {
+ for (src = i + 1; src < count; src++)
+ {
+ if (info [src].addend != curr)
+ break;
+ /* For duplicates, make sure that GOT_OFFSET is
+ valid. */
+ if (got_offset == (bfd_vma) -1)
+ got_offset = info [src].got_offset;
+ }
+
+ /* Make sure that the kept one has a valid got_offset. */
+ if (got_offset != (bfd_vma) -1)
+ info [kept].got_offset = got_offset;
+ }
+ else
+ src = i;
+
+ if (src >= count)
+ break;
+
+ /* Find the next duplicate. SRC will be kept. */
+ prev = info [src].addend;
+ got_offset = info [src].got_offset;
+ for (dupes = src + 1; dupes < count; dupes ++)
+ {
+ curr = info [dupes].addend;
+ if (curr == prev)
+ {
+ /* Make sure that got_offset is valid. */
+ if (got_offset == (bfd_vma) -1)
+ got_offset = info [dupes].got_offset;
+
+ /* For duplicates, make sure that the kept one has
+ a valid got_offset. */
+ if (got_offset != (bfd_vma) -1)
+ info [dupes - 1].got_offset = got_offset;
+ break;
+ }
+ got_offset = info [dupes].got_offset;
+ prev = curr;
+ }
+
+ /* How much to move. */
+ len = dupes - src;
+ i = dupes + 1;
+
+ if (len == 1 && dupes < count)
+ {
+ /* If we only move 1 element, we combine it with the next
+ one. There must be at least a duplicate. Find the
+ next different one. */
+ for (diff = dupes + 1, src++; diff < count; diff++, src++)
+ {
+ if (info [diff].addend != curr)
+ break;
+ /* Make sure that got_offset is valid. */
+ if (got_offset == (bfd_vma) -1)
+ got_offset = info [diff].got_offset;
+ }
+
+ /* Makre sure that the last duplicated one has an valid
+ offset. */
+ BFD_ASSERT (curr == prev);
+ if (got_offset != (bfd_vma) -1)
+ info [diff - 1].got_offset = got_offset;
+
+ if (diff < count)
+ {
+ /* Find the next duplicate. Track the current valid
+ offset. */
+ prev = info [diff].addend;
+ got_offset = info [diff].got_offset;
+ for (dupes = diff + 1; dupes < count; dupes ++)
+ {
+ curr = info [dupes].addend;
+ if (curr == prev)
+ {
+ /* For duplicates, make sure that GOT_OFFSET
+ is valid. */
+ if (got_offset == (bfd_vma) -1)
+ got_offset = info [dupes].got_offset;
+ break;
+ }
+ got_offset = info [dupes].got_offset;
+ prev = curr;
+ diff++;
+ }
+
+ len = diff - src + 1;
+ i = diff + 1;
+ }
+ }
+
+ memmove (&info [dest], &info [src], len * sizeof (*info));
+
+ dest += len;
+ }
+
+ count = dest;
+ }
+ else
+ {
+ /* When we get here, either there is no duplicate at all or
+ the only duplicate is the last element. */
+ if (dest < count)
+ {
+ /* If the last element is a duplicate, make sure that the
+ kept one has a valid got_offset. We also update count. */
+ if (got_offset != (bfd_vma) -1)
+ info [dest - 1].got_offset = got_offset;
+ count = dest;
+ }
+ }
+
+ return count;
+}
+
+/* Find and/or create a descriptor for dynamic symbol info. This will
+ vary based on global or local symbol, and the addend to the reloc.
+
+ We don't sort when inserting. Also, we sort and eliminate
+ duplicates if there is an unsorted section. Typically, this will
+ only happen once, because we do all insertions before lookups. We
+ then use bsearch to do a lookup. This also allows lookups to be
+ fast. So we have fast insertion (O(log N) due to duplicate check),
+ fast lookup (O(log N)) and one sort (O(N log N) expected time).
+ Previously, all lookups were O(N) because of the use of the linked
+ list and also all insertions were O(N) because of the check for
+ duplicates. There are some complications here because the array
+ size grows occasionally, which may add an O(N) factor, but this
+ should be rare. Also, we free the excess array allocation, which
+ requires a copy which is O(N), but this only happens once. */
+
+static struct elf64_ia64_dyn_sym_info *
+get_dyn_sym_info (struct elf64_ia64_link_hash_table *ia64_info,
+ struct elf_link_hash_entry *h, bfd *abfd,
+ const Elf_Internal_Rela *rel, bfd_boolean create)
+{
+ struct elf64_ia64_dyn_sym_info **info_p, *info, *dyn_i, key;
+ unsigned int *count_p, *sorted_count_p, *size_p;
+ unsigned int count, sorted_count, size;
+ bfd_vma addend = rel ? rel->r_addend : 0;
+ bfd_size_type amt;
+
+ if (h)
+ {
+ struct elf64_ia64_link_hash_entry *global_h;
+
+ global_h = (struct elf64_ia64_link_hash_entry *) h;
+ info_p = &global_h->info;
+ count_p = &global_h->count;
+ sorted_count_p = &global_h->sorted_count;
+ size_p = &global_h->size;
+ }
+ else
+ {
+ struct elf64_ia64_local_hash_entry *loc_h;
+
+ loc_h = get_local_sym_hash (ia64_info, abfd, rel, create);
+ if (!loc_h)
+ {
+ BFD_ASSERT (!create);
+ return NULL;
+ }
+
+ info_p = &loc_h->info;
+ count_p = &loc_h->count;
+ sorted_count_p = &loc_h->sorted_count;
+ size_p = &loc_h->size;
+ }
+
+ count = *count_p;
+ sorted_count = *sorted_count_p;
+ size = *size_p;
+ info = *info_p;
+ if (create)
+ {
+ /* When we create the array, we don't check for duplicates,
+ except in the previously sorted section if one exists, and
+ against the last inserted entry. This allows insertions to
+ be fast. */
+ if (info)
+ {
+ if (sorted_count)
+ {
+ /* Try bsearch first on the sorted section. */
+ key.addend = addend;
+ dyn_i = bsearch (&key, info, sorted_count,
+ sizeof (*info), addend_compare);
+
+ if (dyn_i)
+ {
+ return dyn_i;
+ }
+ }
+
+ /* Do a quick check for the last inserted entry. */
+ dyn_i = info + count - 1;
+ if (dyn_i->addend == addend)
+ {
+ return dyn_i;
+ }
+ }
+
+ if (size == 0)
+ {
+ /* It is the very first element. We create the array of size
+ 1. */
+ size = 1;
+ amt = size * sizeof (*info);
+ info = bfd_malloc (amt);
+ }
+ else if (size <= count)
+ {
+ /* We double the array size every time when we reach the
+ size limit. */
+ size += size;
+ amt = size * sizeof (*info);
+ info = bfd_realloc (info, amt);
+ }
+ else
+ goto has_space;
+
+ if (info == NULL)
+ return NULL;
+ *size_p = size;
+ *info_p = info;
+
+has_space:
+ /* Append the new one to the array. */
+ dyn_i = info + count;
+ memset (dyn_i, 0, sizeof (*dyn_i));
+ dyn_i->got_offset = (bfd_vma) -1;
+ dyn_i->addend = addend;
+
+ /* We increment count only since the new ones are unsorted and
+ may have duplicate. */
+ (*count_p)++;
+ }
+ else
+ {
+ /* It is a lookup without insertion. Sort array if part of the
+ array isn't sorted. */
+ if (count != sorted_count)
+ {
+ count = sort_dyn_sym_info (info, count);
+ *count_p = count;
+ *sorted_count_p = count;
+ }
+
+ /* Free unused memory. */
+ if (size != count)
+ {
+ amt = count * sizeof (*info);
+ info = bfd_malloc (amt);
+ if (info != NULL)
+ {
+ memcpy (info, *info_p, amt);
+ free (*info_p);
+ *size_p = count;
+ *info_p = info;
+ }
+ }
+
+ key.addend = addend;
+ dyn_i = bsearch (&key, info, count,
+ sizeof (*info), addend_compare);
+ }
+
+ return dyn_i;
+}
+
+static asection *
+get_got (bfd *abfd, struct elf64_ia64_link_hash_table *ia64_info)
+{
+ asection *got;
+ bfd *dynobj;
+
+ got = ia64_info->root.sgot;
+ if (!got)
+ {
+ flagword flags;
+
+ dynobj = ia64_info->root.dynobj;
+ if (!dynobj)
+ ia64_info->root.dynobj = dynobj = abfd;
+
+ /* The .got section is always aligned at 8 bytes. */
+ flags = get_elf_backend_data (dynobj)->dynamic_sec_flags;
+ got = bfd_make_section_anyway_with_flags (dynobj, ".got",
+ flags | SEC_SMALL_DATA);
+ if (got == NULL
+ || !bfd_set_section_alignment (dynobj, got, 3))
+ return NULL;
+ ia64_info->root.sgot = got;
+ }
+
+ return got;
+}
+
+/* Create function descriptor section (.opd). This section is called .opd
+ because it contains "official procedure descriptors". The "official"
+ refers to the fact that these descriptors are used when taking the address
+ of a procedure, thus ensuring a unique address for each procedure. */
+
+static asection *
+get_fptr (bfd *abfd, struct bfd_link_info *info,
+ struct elf64_ia64_link_hash_table *ia64_info)
+{
+ asection *fptr;
+ bfd *dynobj;
+
+ fptr = ia64_info->fptr_sec;
+ if (!fptr)
+ {
+ dynobj = ia64_info->root.dynobj;
+ if (!dynobj)
+ ia64_info->root.dynobj = dynobj = abfd;
+
+ fptr = bfd_make_section_anyway_with_flags (dynobj, ".opd",
+ (SEC_ALLOC
+ | SEC_LOAD
+ | SEC_HAS_CONTENTS
+ | SEC_IN_MEMORY
+ | (info->pie ? 0
+ : SEC_READONLY)
+ | SEC_LINKER_CREATED));
+ if (!fptr
+ || !bfd_set_section_alignment (dynobj, fptr, 4))
+ {
+ BFD_ASSERT (0);
+ return NULL;
+ }
+
+ ia64_info->fptr_sec = fptr;
+
+ if (info->pie)
+ {
+ asection *fptr_rel;
+ fptr_rel = bfd_make_section_anyway_with_flags (dynobj, ".rela.opd",
+ (SEC_ALLOC | SEC_LOAD
+ | SEC_HAS_CONTENTS
+ | SEC_IN_MEMORY
+ | SEC_LINKER_CREATED
+ | SEC_READONLY));
+ if (fptr_rel == NULL
+ || !bfd_set_section_alignment (dynobj, fptr_rel, 3))
+ {
+ BFD_ASSERT (0);
+ return NULL;
+ }
+
+ ia64_info->rel_fptr_sec = fptr_rel;
+ }
+ }
+
+ return fptr;
+}
+
+static asection *
+get_pltoff (bfd *abfd, struct elf64_ia64_link_hash_table *ia64_info)
+{
+ asection *pltoff;
+ bfd *dynobj;
+
+ pltoff = ia64_info->pltoff_sec;
+ if (!pltoff)
+ {
+ dynobj = ia64_info->root.dynobj;
+ if (!dynobj)
+ ia64_info->root.dynobj = dynobj = abfd;
+
+ pltoff = bfd_make_section_anyway_with_flags (dynobj,
+ ELF_STRING_ia64_pltoff,
+ (SEC_ALLOC
+ | SEC_LOAD
+ | SEC_HAS_CONTENTS
+ | SEC_IN_MEMORY
+ | SEC_SMALL_DATA
+ | SEC_LINKER_CREATED));
+ if (!pltoff
+ || !bfd_set_section_alignment (dynobj, pltoff, 4))
+ {
+ BFD_ASSERT (0);
+ return NULL;
+ }
+
+ ia64_info->pltoff_sec = pltoff;
+ }
+
+ return pltoff;
+}
+
+static asection *
+get_reloc_section (bfd *abfd,
+ struct elf64_ia64_link_hash_table *ia64_info,
+ asection *sec, bfd_boolean create)
+{
+ const char *srel_name;
+ asection *srel;
+ bfd *dynobj;
+
+ srel_name = (bfd_elf_string_from_elf_section
+ (abfd, elf_elfheader(abfd)->e_shstrndx,
+ _bfd_elf_single_rel_hdr (sec)->sh_name));
+ if (srel_name == NULL)
+ return NULL;
+
+ BFD_ASSERT ((CONST_STRNEQ (srel_name, ".rela")
+ && strcmp (bfd_get_section_name (abfd, sec),
+ srel_name+5) == 0)
+ || (CONST_STRNEQ (srel_name, ".rel")
+ && strcmp (bfd_get_section_name (abfd, sec),
+ srel_name+4) == 0));
+
+ dynobj = ia64_info->root.dynobj;
+ if (!dynobj)
+ ia64_info->root.dynobj = dynobj = abfd;
+
+ srel = bfd_get_linker_section (dynobj, srel_name);
+ if (srel == NULL && create)
+ {
+ srel = bfd_make_section_anyway_with_flags (dynobj, srel_name,
+ (SEC_ALLOC | SEC_LOAD
+ | SEC_HAS_CONTENTS
+ | SEC_IN_MEMORY
+ | SEC_LINKER_CREATED
+ | SEC_READONLY));
+ if (srel == NULL
+ || !bfd_set_section_alignment (dynobj, srel, 3))
+ return NULL;
+ }
+
+ return srel;
+}
+
+static bfd_boolean
+count_dyn_reloc (bfd *abfd, struct elf64_ia64_dyn_sym_info *dyn_i,
+ asection *srel, int type)
+{
+ struct elf64_ia64_dyn_reloc_entry *rent;
+
+ for (rent = dyn_i->reloc_entries; rent; rent = rent->next)
+ if (rent->srel == srel && rent->type == type)
+ break;
+
+ if (!rent)
+ {
+ rent = ((struct elf64_ia64_dyn_reloc_entry *)
+ bfd_alloc (abfd, (bfd_size_type) sizeof (*rent)));
+ if (!rent)
+ return FALSE;
+
+ rent->next = dyn_i->reloc_entries;
+ rent->srel = srel;
+ rent->type = type;
+ rent->count = 0;
+ dyn_i->reloc_entries = rent;
+ }
+ rent->count++;
+
+ return TRUE;
+}
+
+static bfd_boolean
+elf64_ia64_check_relocs (bfd *abfd, struct bfd_link_info *info,
+ asection *sec,
+ const Elf_Internal_Rela *relocs)
+{
+ struct elf64_ia64_link_hash_table *ia64_info;
+ const Elf_Internal_Rela *relend;
+ Elf_Internal_Shdr *symtab_hdr;
+ const Elf_Internal_Rela *rel;
+ asection *got, *fptr, *srel, *pltoff;
+ enum {
+ NEED_GOT = 1,
+ NEED_GOTX = 2,
+ NEED_FPTR = 4,
+ NEED_PLTOFF = 8,
+ NEED_MIN_PLT = 16,
+ NEED_FULL_PLT = 32,
+ NEED_DYNREL = 64,
+ NEED_LTOFF_FPTR = 128
+ };
+ int need_entry;
+ struct elf_link_hash_entry *h;
+ unsigned long r_symndx;
+ bfd_boolean maybe_dynamic;
+
+ if (info->relocatable)
+ return TRUE;
+
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+ ia64_info = elf64_ia64_hash_table (info);
+ if (ia64_info == NULL)
+ return FALSE;
+
+ got = fptr = srel = pltoff = NULL;
+
+ relend = relocs + sec->reloc_count;
+
+ /* We scan relocations first to create dynamic relocation arrays. We
+ modified get_dyn_sym_info to allow fast insertion and support fast
+ lookup in the next loop. */
+ for (rel = relocs; rel < relend; ++rel)
+ {
+ r_symndx = ELF64_R_SYM (rel->r_info);
+ if (r_symndx >= symtab_hdr->sh_info)
+ {
+ long indx = r_symndx - symtab_hdr->sh_info;
+ h = elf_sym_hashes (abfd)[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;
+ }
+ else
+ h = NULL;
+
+ /* We can only get preliminary data on whether a symbol is
+ locally or externally defined, as not all of the input files
+ have yet been processed. Do something with what we know, as
+ this may help reduce memory usage and processing time later. */
+ maybe_dynamic = (h && ((!info->executable
+ && (!SYMBOLIC_BIND (info, h)
+ || info->unresolved_syms_in_shared_libs == RM_IGNORE))
+ || !h->def_regular
+ || h->root.type == bfd_link_hash_defweak));
+
+ need_entry = 0;
+ switch (ELF64_R_TYPE (rel->r_info))
+ {
+ case R_IA64_TPREL64MSB:
+ case R_IA64_TPREL64LSB:
+ case R_IA64_LTOFF_TPREL22:
+ case R_IA64_DTPREL32MSB:
+ case R_IA64_DTPREL32LSB:
+ case R_IA64_DTPREL64MSB:
+ case R_IA64_DTPREL64LSB:
+ case R_IA64_LTOFF_DTPREL22:
+ case R_IA64_DTPMOD64MSB:
+ case R_IA64_DTPMOD64LSB:
+ case R_IA64_LTOFF_DTPMOD22:
+ abort ();
+ break;
+
+ case R_IA64_IPLTMSB:
+ case R_IA64_IPLTLSB:
+ break;
+
+ case R_IA64_LTOFF_FPTR22:
+ case R_IA64_LTOFF_FPTR64I:
+ case R_IA64_LTOFF_FPTR32MSB:
+ case R_IA64_LTOFF_FPTR32LSB:
+ case R_IA64_LTOFF_FPTR64MSB:
+ case R_IA64_LTOFF_FPTR64LSB:
+ need_entry = NEED_FPTR | NEED_GOT | NEED_LTOFF_FPTR;
+ break;
+
+ case R_IA64_FPTR64I:
+ case R_IA64_FPTR32MSB:
+ case R_IA64_FPTR32LSB:
+ case R_IA64_FPTR64MSB:
+ case R_IA64_FPTR64LSB:
+ if (info->shared || h)
+ need_entry = NEED_FPTR | NEED_DYNREL;
+ else
+ need_entry = NEED_FPTR;
+ break;
+
+ case R_IA64_LTOFF22:
+ case R_IA64_LTOFF64I:
+ need_entry = NEED_GOT;
+ break;
+
+ case R_IA64_LTOFF22X:
+ need_entry = NEED_GOTX;
+ break;
+
+ case R_IA64_PLTOFF22:
+ case R_IA64_PLTOFF64I:
+ case R_IA64_PLTOFF64MSB:
+ case R_IA64_PLTOFF64LSB:
+ need_entry = NEED_PLTOFF;
+ if (h)
+ {
+ if (maybe_dynamic)
+ need_entry |= NEED_MIN_PLT;
+ }
+ else
+ {
+ (*info->callbacks->warning)
+ (info, _("@pltoff reloc against local symbol"), 0,
+ abfd, 0, (bfd_vma) 0);
+ }
+ break;
+
+ case R_IA64_PCREL21B:
+ case R_IA64_PCREL60B:
+ /* Depending on where this symbol is defined, we may or may not
+ need a full plt entry. Only skip if we know we'll not need
+ the entry -- static or symbolic, and the symbol definition
+ has already been seen. */
+ if (maybe_dynamic && rel->r_addend == 0)
+ need_entry = NEED_FULL_PLT;
+ break;
+
+ case R_IA64_IMM14:
+ case R_IA64_IMM22:
+ case R_IA64_IMM64:
+ case R_IA64_DIR32MSB:
+ case R_IA64_DIR32LSB:
+ case R_IA64_DIR64MSB:
+ case R_IA64_DIR64LSB:
+ /* Shared objects will always need at least a REL relocation. */
+ if (info->shared || maybe_dynamic)
+ need_entry = NEED_DYNREL;
+ break;
+
+ case R_IA64_PCREL22:
+ case R_IA64_PCREL64I:
+ case R_IA64_PCREL32MSB:
+ case R_IA64_PCREL32LSB:
+ case R_IA64_PCREL64MSB:
+ case R_IA64_PCREL64LSB:
+ if (maybe_dynamic)
+ need_entry = NEED_DYNREL;
+ break;
+ }
+
+ if (!need_entry)
+ continue;
+
+ if ((need_entry & NEED_FPTR) != 0
+ && rel->r_addend)
+ {
+ (*info->callbacks->warning)
+ (info, _("non-zero addend in @fptr reloc"), 0,
+ abfd, 0, (bfd_vma) 0);
+ }
+
+ if (get_dyn_sym_info (ia64_info, h, abfd, rel, TRUE) == NULL)
+ return FALSE;
+ }
+
+ /* Now, we only do lookup without insertion, which is very fast
+ with the modified get_dyn_sym_info. */
+ for (rel = relocs; rel < relend; ++rel)
+ {
+ struct elf64_ia64_dyn_sym_info *dyn_i;
+ int dynrel_type = R_IA64_NONE;
+
+ r_symndx = ELF64_R_SYM (rel->r_info);
+ if (r_symndx >= symtab_hdr->sh_info)
+ {
+ /* We're dealing with a global symbol -- find its hash entry
+ and mark it as being referenced. */
+ long indx = r_symndx - symtab_hdr->sh_info;
+ h = elf_sym_hashes (abfd)[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;
+
+ /* PR15323, ref flags aren't set for references in the same
+ object. */
+ h->root.non_ir_ref = 1;
+ h->ref_regular = 1;
+ }
+ else
+ h = NULL;
+
+ /* We can only get preliminary data on whether a symbol is
+ locally or externally defined, as not all of the input files
+ have yet been processed. Do something with what we know, as
+ this may help reduce memory usage and processing time later. */
+ maybe_dynamic = (h && ((!info->executable
+ && (!SYMBOLIC_BIND (info, h)
+ || info->unresolved_syms_in_shared_libs == RM_IGNORE))
+ || !h->def_regular
+ || h->root.type == bfd_link_hash_defweak));
+
+ need_entry = 0;
+ switch (ELF64_R_TYPE (rel->r_info))
+ {
+ case R_IA64_TPREL64MSB:
+ case R_IA64_TPREL64LSB:
+ case R_IA64_LTOFF_TPREL22:
+ case R_IA64_DTPREL32MSB:
+ case R_IA64_DTPREL32LSB:
+ case R_IA64_DTPREL64MSB:
+ case R_IA64_DTPREL64LSB:
+ case R_IA64_LTOFF_DTPREL22:
+ case R_IA64_DTPMOD64MSB:
+ case R_IA64_DTPMOD64LSB:
+ case R_IA64_LTOFF_DTPMOD22:
+ abort ();
+ break;
+
+ case R_IA64_LTOFF_FPTR22:
+ case R_IA64_LTOFF_FPTR64I:
+ case R_IA64_LTOFF_FPTR32MSB:
+ case R_IA64_LTOFF_FPTR32LSB:
+ case R_IA64_LTOFF_FPTR64MSB:
+ case R_IA64_LTOFF_FPTR64LSB:
+ need_entry = NEED_FPTR | NEED_GOT | NEED_LTOFF_FPTR;
+ break;
+
+ case R_IA64_FPTR64I:
+ case R_IA64_FPTR32MSB:
+ case R_IA64_FPTR32LSB:
+ case R_IA64_FPTR64MSB:
+ case R_IA64_FPTR64LSB:
+ if (info->shared || h)
+ need_entry = NEED_FPTR | NEED_DYNREL;
+ else
+ need_entry = NEED_FPTR;
+ dynrel_type = R_IA64_FPTR64LSB;
+ break;
+
+ case R_IA64_LTOFF22:
+ case R_IA64_LTOFF64I:
+ need_entry = NEED_GOT;
+ break;
+
+ case R_IA64_LTOFF22X:
+ need_entry = NEED_GOTX;
+ break;
+
+ case R_IA64_PLTOFF22:
+ case R_IA64_PLTOFF64I:
+ case R_IA64_PLTOFF64MSB:
+ case R_IA64_PLTOFF64LSB:
+ need_entry = NEED_PLTOFF;
+ if (h)
+ {
+ if (maybe_dynamic)
+ need_entry |= NEED_MIN_PLT;
+ }
+ break;
+
+ case R_IA64_PCREL21B:
+ case R_IA64_PCREL60B:
+ /* Depending on where this symbol is defined, we may or may not
+ need a full plt entry. Only skip if we know we'll not need
+ the entry -- static or symbolic, and the symbol definition
+ has already been seen. */
+ if (maybe_dynamic && rel->r_addend == 0)
+ need_entry = NEED_FULL_PLT;
+ break;
+
+ case R_IA64_IMM14:
+ case R_IA64_IMM22:
+ case R_IA64_IMM64:
+ case R_IA64_DIR32MSB:
+ case R_IA64_DIR32LSB:
+ case R_IA64_DIR64MSB:
+ case R_IA64_DIR64LSB:
+ /* Shared objects will always need at least a REL relocation. */
+ if (info->shared || maybe_dynamic)
+ need_entry = NEED_DYNREL;
+ dynrel_type = R_IA64_DIR64LSB;
+ break;
+
+ case R_IA64_IPLTMSB:
+ case R_IA64_IPLTLSB:
+ break;
+
+ case R_IA64_PCREL22:
+ case R_IA64_PCREL64I:
+ case R_IA64_PCREL32MSB:
+ case R_IA64_PCREL32LSB:
+ case R_IA64_PCREL64MSB:
+ case R_IA64_PCREL64LSB:
+ if (maybe_dynamic)
+ need_entry = NEED_DYNREL;
+ dynrel_type = R_IA64_PCREL64LSB;
+ break;
+ }
+
+ if (!need_entry)
+ continue;
+
+ dyn_i = get_dyn_sym_info (ia64_info, h, abfd, rel, FALSE);
+
+ /* Record whether or not this is a local symbol. */
+ dyn_i->h = h;
+
+ /* Create what's needed. */
+ if (need_entry & (NEED_GOT | NEED_GOTX))
+ {
+ if (!got)
+ {
+ got = get_got (abfd, ia64_info);
+ if (!got)
+ return FALSE;
+ }
+ if (need_entry & NEED_GOT)
+ dyn_i->want_got = 1;
+ if (need_entry & NEED_GOTX)
+ dyn_i->want_gotx = 1;
+ }
+ if (need_entry & NEED_FPTR)
+ {
+ /* Create the .opd section. */
+ if (!fptr)
+ {
+ fptr = get_fptr (abfd, info, ia64_info);
+ if (!fptr)
+ return FALSE;
+ }
+ dyn_i->want_fptr = 1;
+ }
+ if (need_entry & NEED_LTOFF_FPTR)
+ dyn_i->want_ltoff_fptr = 1;
+ if (need_entry & (NEED_MIN_PLT | NEED_FULL_PLT))
+ {
+ if (!ia64_info->root.dynobj)
+ ia64_info->root.dynobj = abfd;
+ h->needs_plt = 1;
+ dyn_i->want_plt = 1;
+ }
+ if (need_entry & NEED_FULL_PLT)
+ dyn_i->want_plt2 = 1;
+ if (need_entry & NEED_PLTOFF)
+ {
+ /* This is needed here, in case @pltoff is used in a non-shared
+ link. */
+ if (!pltoff)
+ {
+ pltoff = get_pltoff (abfd, ia64_info);
+ if (!pltoff)
+ return FALSE;
+ }
+
+ dyn_i->want_pltoff = 1;
+ }
+ if ((need_entry & NEED_DYNREL) && (sec->flags & SEC_ALLOC))
+ {
+ if (!srel)
+ {
+ srel = get_reloc_section (abfd, ia64_info, sec, TRUE);
+ if (!srel)
+ return FALSE;
+ }
+ if (!count_dyn_reloc (abfd, dyn_i, srel, dynrel_type))
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+/* For cleanliness, and potentially faster dynamic loading, allocate
+ external GOT entries first. */
+
+static bfd_boolean
+allocate_global_data_got (struct elf64_ia64_dyn_sym_info *dyn_i,
+ void * data)
+{
+ struct elf64_ia64_allocate_data *x = (struct elf64_ia64_allocate_data *)data;
+
+ if ((dyn_i->want_got || dyn_i->want_gotx)
+ && ! dyn_i->want_fptr
+ && elf64_ia64_dynamic_symbol_p (dyn_i->h))
+ {
+ /* GOT entry with FPTR is done by allocate_global_fptr_got. */
+ dyn_i->got_offset = x->ofs;
+ x->ofs += 8;
+ }
+ return TRUE;
+}
+
+/* Next, allocate all the GOT entries used by LTOFF_FPTR relocs. */
+
+static bfd_boolean
+allocate_global_fptr_got (struct elf64_ia64_dyn_sym_info *dyn_i,
+ void * data)
+{
+ struct elf64_ia64_allocate_data *x = (struct elf64_ia64_allocate_data *)data;
+
+ if (dyn_i->want_got
+ && dyn_i->want_fptr
+ && elf64_ia64_dynamic_symbol_p (dyn_i->h))
+ {
+ dyn_i->got_offset = x->ofs;
+ x->ofs += 8;
+ }
+ return TRUE;
+}
+
+/* Lastly, allocate all the GOT entries for local data. */
+
+static bfd_boolean
+allocate_local_got (struct elf64_ia64_dyn_sym_info *dyn_i,
+ void * data)
+{
+ struct elf64_ia64_allocate_data *x = (struct elf64_ia64_allocate_data *) data;
+
+ if ((dyn_i->want_got || dyn_i->want_gotx)
+ && !elf64_ia64_dynamic_symbol_p (dyn_i->h))
+ {
+ dyn_i->got_offset = x->ofs;
+ x->ofs += 8;
+ }
+ return TRUE;
+}
+
+/* Allocate function descriptors. We can do these for every function
+ in a main executable that is not exported. */
+
+static bfd_boolean
+allocate_fptr (struct elf64_ia64_dyn_sym_info *dyn_i, void * data)
+{
+ struct elf64_ia64_allocate_data *x = (struct elf64_ia64_allocate_data *) data;
+
+ if (dyn_i->want_fptr)
+ {
+ struct elf_link_hash_entry *h = dyn_i->h;
+
+ if (h)
+ 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 == NULL || !h->def_dynamic)
+ {
+ /* A non dynamic symbol. */
+ dyn_i->fptr_offset = x->ofs;
+ x->ofs += 16;
+ }
+ else
+ dyn_i->want_fptr = 0;
+ }
+ return TRUE;
+}
+
+/* Allocate all the minimal PLT entries. */
+
+static bfd_boolean
+allocate_plt_entries (struct elf64_ia64_dyn_sym_info *dyn_i,
+ void * data ATTRIBUTE_UNUSED)
+{
+ if (dyn_i->want_plt)
+ {
+ struct elf_link_hash_entry *h = dyn_i->h;
+
+ if (h)
+ 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;
+
+ /* ??? Versioned symbols seem to lose NEEDS_PLT. */
+ if (elf64_ia64_dynamic_symbol_p (h))
+ {
+ dyn_i->want_pltoff = 1;
+ }
+ else
+ {
+ dyn_i->want_plt = 0;
+ dyn_i->want_plt2 = 0;
+ }
+ }
+ return TRUE;
+}
+
+/* Allocate all the full PLT entries. */
+
+static bfd_boolean
+allocate_plt2_entries (struct elf64_ia64_dyn_sym_info *dyn_i,
+ void * data)
+{
+ struct elf64_ia64_allocate_data *x = (struct elf64_ia64_allocate_data *)data;
+
+ if (dyn_i->want_plt2)
+ {
+ struct elf_link_hash_entry *h = dyn_i->h;
+ bfd_size_type ofs = x->ofs;
+
+ dyn_i->plt2_offset = ofs;
+ x->ofs = ofs + PLT_FULL_ENTRY_SIZE;
+
+ 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;
+ dyn_i->h->plt.offset = ofs;
+ }
+ return TRUE;
+}
+
+/* Allocate all the PLTOFF entries requested by relocations and
+ plt entries. We can't share space with allocated FPTR entries,
+ because the latter are not necessarily addressable by the GP.
+ ??? Relaxation might be able to determine that they are. */
+
+static bfd_boolean
+allocate_pltoff_entries (struct elf64_ia64_dyn_sym_info *dyn_i,
+ void * data)
+{
+ struct elf64_ia64_allocate_data *x = (struct elf64_ia64_allocate_data *)data;
+
+ if (dyn_i->want_pltoff)
+ {
+ dyn_i->pltoff_offset = x->ofs;
+ x->ofs += 16;
+ }
+ return TRUE;
+}
+
+/* Allocate dynamic relocations for those symbols that turned out
+ to be dynamic. */
+
+static bfd_boolean
+allocate_dynrel_entries (struct elf64_ia64_dyn_sym_info *dyn_i,
+ void * data)
+{
+ struct elf64_ia64_allocate_data *x = (struct elf64_ia64_allocate_data *)data;
+ struct elf64_ia64_link_hash_table *ia64_info;
+ struct elf64_ia64_dyn_reloc_entry *rent;
+ bfd_boolean dynamic_symbol, shared, resolved_zero;
+ struct elf64_ia64_link_hash_entry *h_ia64;
+
+ ia64_info = elf64_ia64_hash_table (x->info);
+ if (ia64_info == NULL)
+ return FALSE;
+
+ /* Note that this can't be used in relation to FPTR relocs below. */
+ dynamic_symbol = elf64_ia64_dynamic_symbol_p (dyn_i->h);
+
+ shared = x->info->shared;
+ resolved_zero = (dyn_i->h
+ && ELF_ST_VISIBILITY (dyn_i->h->other)
+ && dyn_i->h->root.type == bfd_link_hash_undefweak);
+
+ /* Take care of the GOT and PLT relocations. */
+
+ if ((!resolved_zero
+ && (dynamic_symbol || shared)
+ && (dyn_i->want_got || dyn_i->want_gotx))
+ || (dyn_i->want_ltoff_fptr
+ && dyn_i->h
+ && dyn_i->h->def_dynamic))
+ {
+ /* VMS: FIX64. */
+ if (dyn_i->h != NULL && dyn_i->h->def_dynamic)
+ {
+ h_ia64 = (struct elf64_ia64_link_hash_entry *) dyn_i->h;
+ elf_ia64_vms_tdata (h_ia64->shl)->fixups_off +=
+ sizeof (Elf64_External_VMS_IMAGE_FIXUP);
+ ia64_info->fixups_sec->size +=
+ sizeof (Elf64_External_VMS_IMAGE_FIXUP);
+ }
+ }
+
+ if (ia64_info->rel_fptr_sec && dyn_i->want_fptr)
+ {
+ /* VMS: only image reloc. */
+ if (dyn_i->h == NULL || dyn_i->h->root.type != bfd_link_hash_undefweak)
+ ia64_info->rel_fptr_sec->size += sizeof (Elf64_External_Rela);
+ }
+
+ if (!resolved_zero && dyn_i->want_pltoff)
+ {
+ /* VMS: FIXFD. */
+ if (dyn_i->h != NULL && dyn_i->h->def_dynamic)
+ {
+ h_ia64 = (struct elf64_ia64_link_hash_entry *) dyn_i->h;
+ elf_ia64_vms_tdata (h_ia64->shl)->fixups_off +=
+ sizeof (Elf64_External_VMS_IMAGE_FIXUP);
+ ia64_info->fixups_sec->size +=
+ sizeof (Elf64_External_VMS_IMAGE_FIXUP);
+ }
+ }
+
+ /* Take care of the normal data relocations. */
+
+ for (rent = dyn_i->reloc_entries; rent; rent = rent->next)
+ {
+ int count = rent->count;
+
+ switch (rent->type)
+ {
+ case R_IA64_FPTR32LSB:
+ case R_IA64_FPTR64LSB:
+ /* Allocate one iff !want_fptr and not PIE, which by this point
+ will be true only if we're actually allocating one statically
+ in the main executable. Position independent executables
+ need a relative reloc. */
+ if (dyn_i->want_fptr && !x->info->pie)
+ continue;
+ break;
+ case R_IA64_PCREL32LSB:
+ case R_IA64_PCREL64LSB:
+ if (!dynamic_symbol)
+ continue;
+ break;
+ case R_IA64_DIR32LSB:
+ case R_IA64_DIR64LSB:
+ if (!dynamic_symbol && !shared)
+ continue;
+ break;
+ case R_IA64_IPLTLSB:
+ if (!dynamic_symbol && !shared)
+ continue;
+ /* Use two REL relocations for IPLT relocations
+ against local symbols. */
+ if (!dynamic_symbol)
+ count *= 2;
+ break;
+ case R_IA64_DTPREL32LSB:
+ case R_IA64_TPREL64LSB:
+ case R_IA64_DTPREL64LSB:
+ case R_IA64_DTPMOD64LSB:
+ break;
+ default:
+ abort ();
+ }
+
+ /* Add a fixup. */
+ if (!dynamic_symbol)
+ abort ();
+
+ h_ia64 = (struct elf64_ia64_link_hash_entry *) dyn_i->h;
+ elf_ia64_vms_tdata (h_ia64->shl)->fixups_off +=
+ sizeof (Elf64_External_VMS_IMAGE_FIXUP);
+ ia64_info->fixups_sec->size +=
+ sizeof (Elf64_External_VMS_IMAGE_FIXUP);
+ }
+
+ return TRUE;
+}
+
+static bfd_boolean
+elf64_ia64_adjust_dynamic_symbol (struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ struct elf_link_hash_entry *h)
+{
+ /* ??? Undefined symbols with PLT entries should be re-defined
+ to be the PLT entry. */
+
+ /* 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->u.weakdef != NULL)
+ {
+ BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
+ || h->u.weakdef->root.type == bfd_link_hash_defweak);
+ h->root.u.def.section = h->u.weakdef->root.u.def.section;
+ h->root.u.def.value = h->u.weakdef->root.u.def.value;
+ return TRUE;
+ }
+
+ /* If this is a reference to a symbol defined by a dynamic object which
+ is not a function, we might allocate the symbol in our .dynbss section
+ and allocate a COPY dynamic relocation.
+
+ But IA-64 code is canonically PIC, so as a rule we can avoid this sort
+ of hackery. */
+
+ return TRUE;
+}
+
+static bfd_boolean
+elf64_ia64_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
+ struct bfd_link_info *info)
+{
+ struct elf64_ia64_allocate_data data;
+ struct elf64_ia64_link_hash_table *ia64_info;
+ asection *sec;
+ bfd *dynobj;
+ struct elf_link_hash_table *hash_table;
+
+ hash_table = elf_hash_table (info);
+ dynobj = hash_table->dynobj;
+ ia64_info = elf64_ia64_hash_table (info);
+ if (ia64_info == NULL)
+ return FALSE;
+ BFD_ASSERT(dynobj != NULL);
+ data.info = info;
+
+ /* Allocate the GOT entries. */
+
+ if (ia64_info->root.sgot)
+ {
+ data.ofs = 0;
+ elf64_ia64_dyn_sym_traverse (ia64_info, allocate_global_data_got, &data);
+ elf64_ia64_dyn_sym_traverse (ia64_info, allocate_global_fptr_got, &data);
+ elf64_ia64_dyn_sym_traverse (ia64_info, allocate_local_got, &data);
+ ia64_info->root.sgot->size = data.ofs;
+ }
+
+ /* Allocate the FPTR entries. */
+
+ if (ia64_info->fptr_sec)
+ {
+ data.ofs = 0;
+ elf64_ia64_dyn_sym_traverse (ia64_info, allocate_fptr, &data);
+ ia64_info->fptr_sec->size = data.ofs;
+ }
+
+ /* Now that we've seen all of the input files, we can decide which
+ symbols need plt entries. Allocate the minimal PLT entries first.
+ We do this even though dynamic_sections_created may be FALSE, because
+ this has the side-effect of clearing want_plt and want_plt2. */
+
+ data.ofs = 0;
+ elf64_ia64_dyn_sym_traverse (ia64_info, allocate_plt_entries, &data);
+
+ /* Align the pointer for the plt2 entries. */
+ data.ofs = (data.ofs + 31) & (bfd_vma) -32;
+
+ elf64_ia64_dyn_sym_traverse (ia64_info, allocate_plt2_entries, &data);
+ if (data.ofs != 0 || ia64_info->root.dynamic_sections_created)
+ {
+ /* FIXME: we always reserve the memory for dynamic linker even if
+ there are no PLT entries since dynamic linker may assume the
+ reserved memory always exists. */
+
+ BFD_ASSERT (ia64_info->root.dynamic_sections_created);
+
+ ia64_info->root.splt->size = data.ofs;
+ }
+
+ /* Allocate the PLTOFF entries. */
+
+ if (ia64_info->pltoff_sec)
+ {
+ data.ofs = 0;
+ elf64_ia64_dyn_sym_traverse (ia64_info, allocate_pltoff_entries, &data);
+ ia64_info->pltoff_sec->size = data.ofs;
+ }
+
+ if (ia64_info->root.dynamic_sections_created)
+ {
+ /* Allocate space for the dynamic relocations that turned out to be
+ required. */
+ elf64_ia64_dyn_sym_traverse (ia64_info, allocate_dynrel_entries, &data);
+ }
+
+ /* We have now determined the sizes of the various dynamic sections.
+ Allocate memory for them. */
+ for (sec = dynobj->sections; sec != NULL; sec = sec->next)
+ {
+ bfd_boolean strip;
+
+ if (!(sec->flags & SEC_LINKER_CREATED))
+ continue;
+
+ /* If we don't need this section, strip it from the output file.
+ There were several sections primarily related to dynamic
+ linking that must be create before the linker maps input
+ sections to output sections. The linker does that before
+ bfd_elf_size_dynamic_sections is called, and it is that
+ function which decides whether anything needs to go into
+ these sections. */
+
+ strip = (sec->size == 0);
+
+ if (sec == ia64_info->root.sgot)
+ strip = FALSE;
+ else if (sec == ia64_info->root.srelgot)
+ {
+ if (strip)
+ ia64_info->root.srelgot = NULL;
+ else
+ /* We use the reloc_count field as a counter if we need to
+ copy relocs into the output file. */
+ sec->reloc_count = 0;
+ }
+ else if (sec == ia64_info->fptr_sec)
+ {
+ if (strip)
+ ia64_info->fptr_sec = NULL;
+ }
+ else if (sec == ia64_info->rel_fptr_sec)
+ {
+ if (strip)
+ ia64_info->rel_fptr_sec = NULL;
+ else
+ /* We use the reloc_count field as a counter if we need to
+ copy relocs into the output file. */
+ sec->reloc_count = 0;
+ }
+ else if (sec == ia64_info->root.splt)
+ {
+ if (strip)
+ ia64_info->root.splt = NULL;
+ }
+ else if (sec == ia64_info->pltoff_sec)
+ {
+ if (strip)
+ ia64_info->pltoff_sec = NULL;
+ }
+ else if (sec == ia64_info->fixups_sec)
+ {
+ if (strip)
+ ia64_info->fixups_sec = NULL;
+ }
+ else if (sec == ia64_info->transfer_sec)
+ {
+ ;
+ }
+ else
+ {
+ const char *name;
+
+ /* 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, sec);
+
+ if (strcmp (name, ".got.plt") == 0)
+ strip = FALSE;
+ else if (CONST_STRNEQ (name, ".rel"))
+ {
+ if (!strip)
+ {
+ /* We use the reloc_count field as a counter if we need to
+ copy relocs into the output file. */
+ sec->reloc_count = 0;
+ }
+ }
+ else
+ continue;
+ }
+
+ if (strip)
+ sec->flags |= SEC_EXCLUDE;
+ else
+ {
+ /* Allocate memory for the section contents. */
+ sec->contents = (bfd_byte *) bfd_zalloc (dynobj, sec->size);
+ if (sec->contents == NULL && sec->size != 0)
+ return FALSE;
+ }
+ }
+
+ if (elf_hash_table (info)->dynamic_sections_created)
+ {
+ bfd *abfd;
+ asection *dynsec;
+ asection *dynstrsec;
+ Elf_Internal_Dyn dyn;
+ const struct elf_backend_data *bed;
+ unsigned int shl_num = 0;
+ bfd_vma fixups_off = 0;
+ bfd_vma strdyn_off;
+ unsigned int time_hi, time_lo;
+
+ /* The .dynamic section must exist and be empty. */
+ dynsec = bfd_get_linker_section (hash_table->dynobj, ".dynamic");
+ BFD_ASSERT (dynsec != NULL);
+ BFD_ASSERT (dynsec->size == 0);
+
+ dynstrsec = bfd_get_linker_section (hash_table->dynobj, ".vmsdynstr");
+ BFD_ASSERT (dynstrsec != NULL);
+ BFD_ASSERT (dynstrsec->size == 0);
+ dynstrsec->size = 1; /* Initial blank. */
+
+ /* Ident + link time. */
+ vms_get_time (&time_hi, &time_lo);
+
+ if (!_bfd_elf_add_dynamic_entry (info, DT_IA_64_VMS_IDENT, 0))
+ return FALSE;
+ if (!_bfd_elf_add_dynamic_entry (info, DT_IA_64_VMS_LINKTIME,
+ (((bfd_uint64_t)time_hi) << 32)
+ + time_lo))
+ return FALSE;
+
+ /* Strtab. */
+ strdyn_off = dynsec->size;
+ if (!_bfd_elf_add_dynamic_entry (info, DT_IA_64_VMS_STRTAB_OFFSET, 0))
+ return FALSE;
+ if (!_bfd_elf_add_dynamic_entry (info, DT_STRSZ, 0))
+ return FALSE;
+
+ /* PLTGOT */
+ if (!_bfd_elf_add_dynamic_entry (info, DT_IA_64_VMS_PLTGOT_SEG, 0))
+ return FALSE;
+ if (!_bfd_elf_add_dynamic_entry (info, DT_IA_64_VMS_PLTGOT_OFFSET, 0))
+ return FALSE;
+
+ /* Misc. */
+ if (!_bfd_elf_add_dynamic_entry (info, DT_IA_64_VMS_FPMODE, 0x9800000))
+ return FALSE;
+ if (!_bfd_elf_add_dynamic_entry (info, DT_IA_64_VMS_LNKFLAGS,
+ VMS_LF_IMGSTA | VMS_LF_MAIN))
+ return FALSE;
+
+ /* Add entries for shared libraries. */
+ for (abfd = info->input_bfds; abfd; abfd = abfd->link.next)
+ {
+ char *soname;
+ size_t soname_len;
+ bfd_size_type strindex;
+ bfd_byte *newcontents;
+ bfd_vma fixups_shl_off;
+
+ if (!(abfd->flags & DYNAMIC))
+ continue;
+ BFD_ASSERT (abfd->xvec == output_bfd->xvec);
+
+ if (!_bfd_elf_add_dynamic_entry (info, DT_IA_64_VMS_NEEDED_IDENT,
+ elf_ia64_vms_ident (abfd)))
+ return FALSE;
+
+ soname = vms_get_module_name (abfd->filename, TRUE);
+ if (soname == NULL)
+ return FALSE;
+ strindex = dynstrsec->size;
+ soname_len = strlen (soname) + 1;
+ newcontents = (bfd_byte *) bfd_realloc (dynstrsec->contents,
+ strindex + soname_len);
+ if (newcontents == NULL)
+ return FALSE;
+ memcpy (newcontents + strindex, soname, soname_len);
+ dynstrsec->size += soname_len;
+ dynstrsec->contents = newcontents;
+
+ if (!_bfd_elf_add_dynamic_entry (info, DT_NEEDED, strindex))
+ return FALSE;
+
+ if (!_bfd_elf_add_dynamic_entry (info, DT_IA_64_VMS_FIXUP_NEEDED,
+ shl_num))
+ return FALSE;
+ shl_num++;
+
+ /* The fixups_off was in fact containing the size of the fixup
+ section. Remap into the offset. */
+ fixups_shl_off = elf_ia64_vms_tdata (abfd)->fixups_off;
+ elf_ia64_vms_tdata (abfd)->fixups_off = fixups_off;
+
+ if (!_bfd_elf_add_dynamic_entry
+ (info, DT_IA_64_VMS_FIXUP_RELA_CNT,
+ fixups_shl_off / sizeof (Elf64_External_VMS_IMAGE_FIXUP)))
+ return FALSE;
+ if (!_bfd_elf_add_dynamic_entry (info, DT_IA_64_VMS_FIXUP_RELA_OFF,
+ fixups_off))
+ return FALSE;
+ fixups_off += fixups_shl_off;
+ }
+
+ /* Unwind. */
+ if (!_bfd_elf_add_dynamic_entry (info, DT_IA_64_VMS_UNWINDSZ, 0))
+ return FALSE;
+ if (!_bfd_elf_add_dynamic_entry (info, DT_IA_64_VMS_UNWIND_CODSEG, 0))
+ return FALSE;
+ if (!_bfd_elf_add_dynamic_entry (info, DT_IA_64_VMS_UNWIND_INFOSEG, 0))
+ return FALSE;
+ if (!_bfd_elf_add_dynamic_entry (info, DT_IA_64_VMS_UNWIND_OFFSET, 0))
+ return FALSE;
+ if (!_bfd_elf_add_dynamic_entry (info, DT_IA_64_VMS_UNWIND_SEG, 0))
+ return FALSE;
+
+ if (!_bfd_elf_add_dynamic_entry (info, DT_NULL, 0xdead))
+ return FALSE;
+
+ /* Fix the strtab entries. */
+ bed = get_elf_backend_data (hash_table->dynobj);
+
+ if (dynstrsec->size > 1)
+ dynstrsec->contents[0] = 0;
+ else
+ dynstrsec->size = 0;
+
+ /* Note: one 'spare' (ie DT_NULL) entry is added by
+ bfd_elf_size_dynsym_hash_dynstr. */
+ dyn.d_tag = DT_IA_64_VMS_STRTAB_OFFSET;
+ dyn.d_un.d_val = dynsec->size /* + sizeof (Elf64_External_Dyn) */;
+ bed->s->swap_dyn_out (hash_table->dynobj, &dyn,
+ dynsec->contents + strdyn_off);
+
+ dyn.d_tag = DT_STRSZ;
+ dyn.d_un.d_val = dynstrsec->size;
+ bed->s->swap_dyn_out (hash_table->dynobj, &dyn,
+ dynsec->contents + strdyn_off + bed->s->sizeof_dyn);
+
+ elf_ia64_vms_tdata (output_bfd)->needed_count = shl_num;
+
+ /* Note section. */
+ if (!create_ia64_vms_notes (output_bfd, info, time_hi, time_lo))
+ return FALSE;
+ }
+
+ /* ??? Perhaps force __gp local. */
+
+ return TRUE;
+}
+
+static void
+elf64_ia64_install_fixup (bfd *output_bfd,
+ struct elf64_ia64_link_hash_table *ia64_info,
+ struct elf_link_hash_entry *h,
+ unsigned int type, asection *sec, bfd_vma offset,
+ bfd_vma addend)
+{
+ asection *relsec;
+ Elf64_External_VMS_IMAGE_FIXUP *fixup;
+ struct elf64_ia64_link_hash_entry *h_ia64;
+ bfd_vma fixoff;
+ Elf_Internal_Phdr *phdr;
+
+ if (h == NULL || !h->def_dynamic)
+ abort ();
+
+ h_ia64 = (struct elf64_ia64_link_hash_entry *) h;
+ fixoff = elf_ia64_vms_tdata (h_ia64->shl)->fixups_off;
+ elf_ia64_vms_tdata (h_ia64->shl)->fixups_off +=
+ sizeof (Elf64_External_VMS_IMAGE_FIXUP);
+ relsec = ia64_info->fixups_sec;
+
+ fixup = (Elf64_External_VMS_IMAGE_FIXUP *)(relsec->contents + fixoff);
+ offset += sec->output_section->vma + sec->output_offset;
+
+ /* FIXME: this is slow. We should cache the last one used, or create a
+ map. */
+ phdr = _bfd_elf_find_segment_containing_section
+ (output_bfd, sec->output_section);
+ BFD_ASSERT (phdr != NULL);
+
+ bfd_putl64 (offset - phdr->p_vaddr, fixup->fixup_offset);
+ bfd_putl32 (type, fixup->type);
+ bfd_putl32 (phdr - elf_tdata (output_bfd)->phdr, fixup->fixup_seg);
+ bfd_putl64 (addend, fixup->addend);
+ bfd_putl32 (h->root.u.def.value, fixup->symvec_index);
+ bfd_putl32 (2, fixup->data_type);
+}
+
+/* Store an entry for target address TARGET_ADDR in the linkage table
+ and return the gp-relative address of the linkage table entry. */
+
+static bfd_vma
+set_got_entry (bfd *abfd, struct bfd_link_info *info,
+ struct elf64_ia64_dyn_sym_info *dyn_i,
+ bfd_vma addend, bfd_vma value, unsigned int dyn_r_type)
+{
+ struct elf64_ia64_link_hash_table *ia64_info;
+ asection *got_sec;
+ bfd_boolean done;
+ bfd_vma got_offset;
+
+ ia64_info = elf64_ia64_hash_table (info);
+ if (ia64_info == NULL)
+ return 0;
+
+ got_sec = ia64_info->root.sgot;
+
+ switch (dyn_r_type)
+ {
+ case R_IA64_TPREL64LSB:
+ case R_IA64_DTPMOD64LSB:
+ case R_IA64_DTPREL32LSB:
+ case R_IA64_DTPREL64LSB:
+ abort ();
+ break;
+ default:
+ done = dyn_i->got_done;
+ dyn_i->got_done = TRUE;
+ got_offset = dyn_i->got_offset;
+ break;
+ }
+
+ BFD_ASSERT ((got_offset & 7) == 0);
+
+ if (! done)
+ {
+ /* Store the target address in the linkage table entry. */
+ bfd_put_64 (abfd, value, got_sec->contents + got_offset);
+
+ /* Install a dynamic relocation if needed. */
+ if (((info->shared
+ && (!dyn_i->h
+ || ELF_ST_VISIBILITY (dyn_i->h->other) == STV_DEFAULT
+ || dyn_i->h->root.type != bfd_link_hash_undefweak))
+ || elf64_ia64_dynamic_symbol_p (dyn_i->h))
+ && (!dyn_i->want_ltoff_fptr
+ || !info->pie
+ || !dyn_i->h
+ || dyn_i->h->root.type != bfd_link_hash_undefweak))
+ {
+ if (!dyn_i->h || !dyn_i->h->def_dynamic)
+ {
+ dyn_r_type = R_IA64_REL64LSB;
+ addend = value;
+ }
+
+ /* VMS: install a FIX32 or FIX64. */
+ switch (dyn_r_type)
+ {
+ case R_IA64_DIR32LSB:
+ case R_IA64_FPTR32LSB:
+ dyn_r_type = R_IA64_VMS_FIX32;
+ break;
+ case R_IA64_DIR64LSB:
+ case R_IA64_FPTR64LSB:
+ dyn_r_type = R_IA64_VMS_FIX64;
+ break;
+ default:
+ BFD_ASSERT (FALSE);
+ break;
+ }
+ elf64_ia64_install_fixup
+ (info->output_bfd, ia64_info, dyn_i->h,
+ dyn_r_type, got_sec, got_offset, addend);
+ }
+ }
+
+ /* Return the address of the linkage table entry. */
+ value = (got_sec->output_section->vma
+ + got_sec->output_offset
+ + got_offset);
+
+ return value;
+}
+
+/* Fill in a function descriptor consisting of the function's code
+ address and its global pointer. Return the descriptor's address. */
+
+static bfd_vma
+set_fptr_entry (bfd *abfd, struct bfd_link_info *info,
+ struct elf64_ia64_dyn_sym_info *dyn_i,
+ bfd_vma value)
+{
+ struct elf64_ia64_link_hash_table *ia64_info;
+ asection *fptr_sec;
+
+ ia64_info = elf64_ia64_hash_table (info);
+ if (ia64_info == NULL)
+ return 0;
+
+ fptr_sec = ia64_info->fptr_sec;
+
+ if (!dyn_i->fptr_done)
+ {
+ dyn_i->fptr_done = 1;
+
+ /* Fill in the function descriptor. */
+ bfd_put_64 (abfd, value, fptr_sec->contents + dyn_i->fptr_offset);
+ bfd_put_64 (abfd, _bfd_get_gp_value (abfd),
+ fptr_sec->contents + dyn_i->fptr_offset + 8);
+ }
+
+ /* Return the descriptor's address. */
+ value = (fptr_sec->output_section->vma
+ + fptr_sec->output_offset
+ + dyn_i->fptr_offset);
+
+ return value;
+}
+
+/* Fill in a PLTOFF entry consisting of the function's code address
+ and its global pointer. Return the descriptor's address. */
+
+static bfd_vma
+set_pltoff_entry (bfd *abfd, struct bfd_link_info *info,
+ struct elf64_ia64_dyn_sym_info *dyn_i,
+ bfd_vma value, bfd_boolean is_plt)
+{
+ struct elf64_ia64_link_hash_table *ia64_info;
+ asection *pltoff_sec;
+
+ ia64_info = elf64_ia64_hash_table (info);
+ if (ia64_info == NULL)
+ return 0;
+
+ pltoff_sec = ia64_info->pltoff_sec;
+
+ /* Don't do anything if this symbol uses a real PLT entry. In
+ that case, we'll fill this in during finish_dynamic_symbol. */
+ if ((! dyn_i->want_plt || is_plt)
+ && !dyn_i->pltoff_done)
+ {
+ bfd_vma gp = _bfd_get_gp_value (abfd);
+
+ /* Fill in the function descriptor. */
+ bfd_put_64 (abfd, value, pltoff_sec->contents + dyn_i->pltoff_offset);
+ bfd_put_64 (abfd, gp, pltoff_sec->contents + dyn_i->pltoff_offset + 8);
+
+ /* Install dynamic relocations if needed. */
+ if (!is_plt
+ && info->shared
+ && (!dyn_i->h
+ || ELF_ST_VISIBILITY (dyn_i->h->other) == STV_DEFAULT
+ || dyn_i->h->root.type != bfd_link_hash_undefweak))
+ {
+ /* VMS: */
+ abort ();
+ }
+
+ dyn_i->pltoff_done = 1;
+ }
+
+ /* Return the descriptor's address. */
+ value = (pltoff_sec->output_section->vma
+ + pltoff_sec->output_offset
+ + dyn_i->pltoff_offset);
+
+ return value;
+}
+
+/* Called through qsort to sort the .IA_64.unwind section during a
+ non-relocatable link. Set elf64_ia64_unwind_entry_compare_bfd
+ to the output bfd so we can do proper endianness frobbing. */
+
+static bfd *elf64_ia64_unwind_entry_compare_bfd;
+
+static int
+elf64_ia64_unwind_entry_compare (const void * a, const void * b)
+{
+ bfd_vma av, bv;
+
+ av = bfd_get_64 (elf64_ia64_unwind_entry_compare_bfd, a);
+ bv = bfd_get_64 (elf64_ia64_unwind_entry_compare_bfd, b);
+
+ return (av < bv ? -1 : av > bv ? 1 : 0);
+}
+
+/* Make sure we've got ourselves a nice fat __gp value. */
+static bfd_boolean
+elf64_ia64_choose_gp (bfd *abfd, struct bfd_link_info *info, bfd_boolean final)
+{
+ bfd_vma min_vma = (bfd_vma) -1, max_vma = 0;
+ bfd_vma min_short_vma = min_vma, max_short_vma = 0;
+ struct elf_link_hash_entry *gp;
+ bfd_vma gp_val;
+ asection *os;
+ struct elf64_ia64_link_hash_table *ia64_info;
+
+ ia64_info = elf64_ia64_hash_table (info);
+ if (ia64_info == NULL)
+ return FALSE;
+
+ /* Find the min and max vma of all sections marked short. Also collect
+ min and max vma of any type, for use in selecting a nice gp. */
+ for (os = abfd->sections; os ; os = os->next)
+ {
+ bfd_vma lo, hi;
+
+ if ((os->flags & SEC_ALLOC) == 0)
+ continue;
+
+ lo = os->vma;
+ /* When this function is called from elfNN_ia64_final_link
+ the correct value to use is os->size. When called from
+ elfNN_ia64_relax_section we are in the middle of section
+ sizing; some sections will already have os->size set, others
+ will have os->size zero and os->rawsize the previous size. */
+ hi = os->vma + (!final && os->rawsize ? os->rawsize : os->size);
+ if (hi < lo)
+ hi = (bfd_vma) -1;
+
+ if (min_vma > lo)
+ min_vma = lo;
+ if (max_vma < hi)
+ max_vma = hi;
+ if (os->flags & SEC_SMALL_DATA)
+ {
+ if (min_short_vma > lo)
+ min_short_vma = lo;
+ if (max_short_vma < hi)
+ max_short_vma = hi;
+ }
+ }
+
+ if (ia64_info->min_short_sec)
+ {
+ if (min_short_vma
+ > (ia64_info->min_short_sec->vma
+ + ia64_info->min_short_offset))
+ min_short_vma = (ia64_info->min_short_sec->vma
+ + ia64_info->min_short_offset);
+ if (max_short_vma
+ < (ia64_info->max_short_sec->vma
+ + ia64_info->max_short_offset))
+ max_short_vma = (ia64_info->max_short_sec->vma
+ + ia64_info->max_short_offset);
+ }
+
+ /* See if the user wants to force a value. */
+ gp = elf_link_hash_lookup (elf_hash_table (info), "__gp", FALSE,
+ FALSE, FALSE);
+
+ if (gp
+ && (gp->root.type == bfd_link_hash_defined
+ || gp->root.type == bfd_link_hash_defweak))
+ {
+ asection *gp_sec = gp->root.u.def.section;
+ gp_val = (gp->root.u.def.value
+ + gp_sec->output_section->vma
+ + gp_sec->output_offset);
+ }
+ else
+ {
+ /* Pick a sensible value. */
+
+ if (ia64_info->min_short_sec)
+ {
+ bfd_vma short_range = max_short_vma - min_short_vma;
+
+ /* If min_short_sec is set, pick one in the middle bewteen
+ min_short_vma and max_short_vma. */
+ if (short_range >= 0x400000)
+ goto overflow;
+ gp_val = min_short_vma + short_range / 2;
+ }
+ else
+ {
+ asection *got_sec = ia64_info->root.sgot;
+
+ /* Start with just the address of the .got. */
+ if (got_sec)
+ gp_val = got_sec->output_section->vma;
+ else if (max_short_vma != 0)
+ gp_val = min_short_vma;
+ else if (max_vma - min_vma < 0x200000)
+ gp_val = min_vma;
+ else
+ gp_val = max_vma - 0x200000 + 8;
+ }
+
+ /* If it is possible to address the entire image, but we
+ don't with the choice above, adjust. */
+ if (max_vma - min_vma < 0x400000
+ && (max_vma - gp_val >= 0x200000
+ || gp_val - min_vma > 0x200000))
+ gp_val = min_vma + 0x200000;
+ else if (max_short_vma != 0)
+ {
+ /* If we don't cover all the short data, adjust. */
+ if (max_short_vma - gp_val >= 0x200000)
+ gp_val = min_short_vma + 0x200000;
+
+ /* If we're addressing stuff past the end, adjust back. */
+ if (gp_val > max_vma)
+ gp_val = max_vma - 0x200000 + 8;
+ }
+ }
+
+ /* Validate whether all SHF_IA_64_SHORT sections are within
+ range of the chosen GP. */
+
+ if (max_short_vma != 0)
+ {
+ if (max_short_vma - min_short_vma >= 0x400000)
+ {
+overflow:
+ (*_bfd_error_handler)
+ (_("%s: short data segment overflowed (0x%lx >= 0x400000)"),
+ bfd_get_filename (abfd),
+ (unsigned long) (max_short_vma - min_short_vma));
+ return FALSE;
+ }
+ else if ((gp_val > min_short_vma
+ && gp_val - min_short_vma > 0x200000)
+ || (gp_val < max_short_vma
+ && max_short_vma - gp_val >= 0x200000))
+ {
+ (*_bfd_error_handler)
+ (_("%s: __gp does not cover short data segment"),
+ bfd_get_filename (abfd));
+ return FALSE;
+ }
+ }
+
+ _bfd_set_gp_value (abfd, gp_val);
+
+ return TRUE;
+}
+
+static bfd_boolean
+elf64_ia64_final_link (bfd *abfd, struct bfd_link_info *info)
+{
+ struct elf64_ia64_link_hash_table *ia64_info;
+ asection *unwind_output_sec;
+
+ ia64_info = elf64_ia64_hash_table (info);
+ if (ia64_info == NULL)
+ return FALSE;
+
+ /* Make sure we've got ourselves a nice fat __gp value. */
+ if (!info->relocatable)
+ {
+ bfd_vma gp_val;
+ struct elf_link_hash_entry *gp;
+
+ /* We assume after gp is set, section size will only decrease. We
+ need to adjust gp for it. */
+ _bfd_set_gp_value (abfd, 0);
+ if (! elf64_ia64_choose_gp (abfd, info, TRUE))
+ return FALSE;
+ gp_val = _bfd_get_gp_value (abfd);
+
+ gp = elf_link_hash_lookup (elf_hash_table (info), "__gp", FALSE,
+ FALSE, FALSE);
+ if (gp)
+ {
+ gp->root.type = bfd_link_hash_defined;
+ gp->root.u.def.value = gp_val;
+ gp->root.u.def.section = bfd_abs_section_ptr;
+ }
+ }
+
+ /* If we're producing a final executable, we need to sort the contents
+ of the .IA_64.unwind section. Force this section to be relocated
+ into memory rather than written immediately to the output file. */
+ unwind_output_sec = NULL;
+ if (!info->relocatable)
+ {
+ asection *s = bfd_get_section_by_name (abfd, ELF_STRING_ia64_unwind);
+ if (s)
+ {
+ unwind_output_sec = s->output_section;
+ unwind_output_sec->contents
+ = bfd_malloc (unwind_output_sec->size);
+ if (unwind_output_sec->contents == NULL)
+ return FALSE;
+ }
+ }
+
+ /* Invoke the regular ELF backend linker to do all the work. */
+ if (!bfd_elf_final_link (abfd, info))
+ return FALSE;
+
+ if (unwind_output_sec)
+ {
+ elf64_ia64_unwind_entry_compare_bfd = abfd;
+ qsort (unwind_output_sec->contents,
+ (size_t) (unwind_output_sec->size / 24),
+ 24,
+ elf64_ia64_unwind_entry_compare);
+
+ if (! bfd_set_section_contents (abfd, unwind_output_sec,
+ unwind_output_sec->contents, (bfd_vma) 0,
+ unwind_output_sec->size))
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static bfd_boolean
+elf64_ia64_relocate_section (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)
+{
+ struct elf64_ia64_link_hash_table *ia64_info;
+ Elf_Internal_Shdr *symtab_hdr;
+ Elf_Internal_Rela *rel;
+ Elf_Internal_Rela *relend;
+ bfd_boolean ret_val = TRUE; /* for non-fatal errors */
+ bfd_vma gp_val;
+
+ symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
+ ia64_info = elf64_ia64_hash_table (info);
+ if (ia64_info == NULL)
+ return FALSE;
+
+ /* Infect various flags from the input section to the output section. */
+ if (info->relocatable)
+ {
+ bfd_vma flags;
+
+ flags = elf_section_data(input_section)->this_hdr.sh_flags;
+ flags &= SHF_IA_64_NORECOV;
+
+ elf_section_data(input_section->output_section)
+ ->this_hdr.sh_flags |= flags;
+ }
+
+ gp_val = _bfd_get_gp_value (output_bfd);
+
+ rel = relocs;
+ relend = relocs + input_section->reloc_count;
+ for (; rel < relend; ++rel)
+ {
+ struct elf_link_hash_entry *h;
+ struct elf64_ia64_dyn_sym_info *dyn_i;
+ bfd_reloc_status_type r;
+ reloc_howto_type *howto;
+ unsigned long r_symndx;
+ Elf_Internal_Sym *sym;
+ unsigned int r_type;
+ bfd_vma value;
+ asection *sym_sec;
+ bfd_byte *hit_addr;
+ bfd_boolean dynamic_symbol_p;
+ bfd_boolean undef_weak_ref;
+
+ r_type = ELF64_R_TYPE (rel->r_info);
+ if (r_type > R_IA64_MAX_RELOC_CODE)
+ {
+ (*_bfd_error_handler)
+ (_("%B: unknown relocation type %d"),
+ input_bfd, (int) r_type);
+ bfd_set_error (bfd_error_bad_value);
+ ret_val = FALSE;
+ continue;
+ }
+
+ howto = ia64_elf_lookup_howto (r_type);
+ r_symndx = ELF64_R_SYM (rel->r_info);
+ h = NULL;
+ sym = NULL;
+ sym_sec = NULL;
+ undef_weak_ref = FALSE;
+
+ if (r_symndx < symtab_hdr->sh_info)
+ {
+ /* Reloc against local symbol. */
+ asection *msec;
+ sym = local_syms + r_symndx;
+ sym_sec = local_sections[r_symndx];
+ msec = sym_sec;
+ value = _bfd_elf_rela_local_sym (output_bfd, sym, &msec, rel);
+ if (!info->relocatable
+ && (sym_sec->flags & SEC_MERGE) != 0
+ && ELF_ST_TYPE (sym->st_info) == STT_SECTION
+ && sym_sec->sec_info_type == SEC_INFO_TYPE_MERGE)
+ {
+ struct elf64_ia64_local_hash_entry *loc_h;
+
+ loc_h = get_local_sym_hash (ia64_info, input_bfd, rel, FALSE);
+ if (loc_h && ! loc_h->sec_merge_done)
+ {
+ struct elf64_ia64_dyn_sym_info *dynent;
+ unsigned int count;
+
+ for (count = loc_h->count, dynent = loc_h->info;
+ count != 0;
+ count--, dynent++)
+ {
+ msec = sym_sec;
+ dynent->addend =
+ _bfd_merged_section_offset (output_bfd, &msec,
+ elf_section_data (msec)->
+ sec_info,
+ sym->st_value
+ + dynent->addend);
+ dynent->addend -= sym->st_value;
+ dynent->addend += msec->output_section->vma
+ + msec->output_offset
+ - sym_sec->output_section->vma
+ - sym_sec->output_offset;
+ }
+
+ /* We may have introduced duplicated entries. We need
+ to remove them properly. */
+ count = sort_dyn_sym_info (loc_h->info, loc_h->count);
+ if (count != loc_h->count)
+ {
+ loc_h->count = count;
+ loc_h->sorted_count = count;
+ }
+
+ loc_h->sec_merge_done = 1;
+ }
+ }
+ }
+ else
+ {
+ bfd_boolean unresolved_reloc;
+ bfd_boolean warned, ignored;
+ struct elf_link_hash_entry **sym_hashes = elf_sym_hashes (input_bfd);
+
+ RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
+ r_symndx, symtab_hdr, sym_hashes,
+ h, sym_sec, value,
+ unresolved_reloc, warned, ignored);
+
+ if (h->root.type == bfd_link_hash_undefweak)
+ undef_weak_ref = TRUE;
+ else if (warned)
+ continue;
+ }
+
+ /* For relocs against symbols from removed linkonce sections,
+ or sections discarded by a linker script, we just want the
+ section contents zeroed. Avoid any special processing. */
+ if (sym_sec != NULL && discarded_section (sym_sec))
+ RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+ rel, 1, relend, howto, 0, contents);
+
+ if (info->relocatable)
+ continue;
+
+ hit_addr = contents + rel->r_offset;
+ value += rel->r_addend;
+ dynamic_symbol_p = elf64_ia64_dynamic_symbol_p (h);
+
+ switch (r_type)
+ {
+ case R_IA64_NONE:
+ case R_IA64_LDXMOV:
+ continue;
+
+ case R_IA64_IMM14:
+ case R_IA64_IMM22:
+ case R_IA64_IMM64:
+ case R_IA64_DIR32MSB:
+ case R_IA64_DIR32LSB:
+ case R_IA64_DIR64MSB:
+ case R_IA64_DIR64LSB:
+ /* Install a dynamic relocation for this reloc. */
+ if ((dynamic_symbol_p || info->shared)
+ && r_symndx != 0
+ && (input_section->flags & SEC_ALLOC) != 0)
+ {
+ unsigned int dyn_r_type;
+ bfd_vma addend;
+
+ switch (r_type)
+ {
+ case R_IA64_IMM14:
+ case R_IA64_IMM22:
+ case R_IA64_IMM64:
+ /* ??? People shouldn't be doing non-pic code in
+ shared libraries nor dynamic executables. */
+ (*_bfd_error_handler)
+ (_("%B: non-pic code with imm relocation against dynamic symbol `%s'"),
+ input_bfd,
+ h ? h->root.root.string
+ : bfd_elf_sym_name (input_bfd, symtab_hdr, sym,
+ sym_sec));
+ ret_val = FALSE;
+ continue;
+
+ default:
+ break;
+ }
+
+ /* If we don't need dynamic symbol lookup, find a
+ matching RELATIVE relocation. */
+ dyn_r_type = r_type;
+ if (dynamic_symbol_p)
+ {
+ addend = rel->r_addend;
+ value = 0;
+ }
+ else
+ {
+ addend = value;
+ }
+
+ /* VMS: install a FIX64. */
+ switch (dyn_r_type)
+ {
+ case R_IA64_DIR32LSB:
+ dyn_r_type = R_IA64_VMS_FIX32;
+ break;
+ case R_IA64_DIR64LSB:
+ dyn_r_type = R_IA64_VMS_FIX64;
+ break;
+ default:
+ BFD_ASSERT (FALSE);
+ break;
+ }
+ elf64_ia64_install_fixup
+ (output_bfd, ia64_info, h,
+ dyn_r_type, input_section, rel->r_offset, addend);
+ r = bfd_reloc_ok;
+ break;
+ }
+ /* Fall through. */
+
+ case R_IA64_LTV32MSB:
+ case R_IA64_LTV32LSB:
+ case R_IA64_LTV64MSB:
+ case R_IA64_LTV64LSB:
+ r = ia64_elf_install_value (hit_addr, value, r_type);
+ break;
+
+ case R_IA64_GPREL22:
+ case R_IA64_GPREL64I:
+ case R_IA64_GPREL32MSB:
+ case R_IA64_GPREL32LSB:
+ case R_IA64_GPREL64MSB:
+ case R_IA64_GPREL64LSB:
+ if (dynamic_symbol_p)
+ {
+ (*_bfd_error_handler)
+ (_("%B: @gprel relocation against dynamic symbol %s"),
+ input_bfd,
+ h ? h->root.root.string
+ : bfd_elf_sym_name (input_bfd, symtab_hdr, sym,
+ sym_sec));
+ ret_val = FALSE;
+ continue;
+ }
+ value -= gp_val;
+ r = ia64_elf_install_value (hit_addr, value, r_type);
+ break;
+
+ case R_IA64_LTOFF22:
+ case R_IA64_LTOFF22X:
+ case R_IA64_LTOFF64I:
+ dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, FALSE);
+ value = set_got_entry (input_bfd, info, dyn_i,
+ rel->r_addend, value, R_IA64_DIR64LSB);
+ value -= gp_val;
+ r = ia64_elf_install_value (hit_addr, value, r_type);
+ break;
+
+ case R_IA64_PLTOFF22:
+ case R_IA64_PLTOFF64I:
+ case R_IA64_PLTOFF64MSB:
+ case R_IA64_PLTOFF64LSB:
+ dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, FALSE);
+ value = set_pltoff_entry (output_bfd, info, dyn_i, value, FALSE);
+ value -= gp_val;
+ r = ia64_elf_install_value (hit_addr, value, r_type);
+ break;
+
+ case R_IA64_FPTR64I:
+ case R_IA64_FPTR32MSB:
+ case R_IA64_FPTR32LSB:
+ case R_IA64_FPTR64MSB:
+ case R_IA64_FPTR64LSB:
+ dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, FALSE);
+ if (dyn_i->want_fptr)
+ {
+ if (!undef_weak_ref)
+ value = set_fptr_entry (output_bfd, info, dyn_i, value);
+ }
+ if (!dyn_i->want_fptr || info->pie)
+ {
+ /* Otherwise, we expect the dynamic linker to create
+ the entry. */
+
+ if (dyn_i->want_fptr)
+ {
+ if (r_type == R_IA64_FPTR64I)
+ {
+ /* We can't represent this without a dynamic symbol.
+ Adjust the relocation to be against an output
+ section symbol, which are always present in the
+ dynamic symbol table. */
+ /* ??? People shouldn't be doing non-pic code in
+ shared libraries. Hork. */
+ (*_bfd_error_handler)
+ (_("%B: linking non-pic code in a position independent executable"),
+ input_bfd);
+ ret_val = FALSE;
+ continue;
+ }
+ }
+ else
+ {
+ value = 0;
+ }
+
+ /* VMS: FIXFD. */
+ elf64_ia64_install_fixup
+ (output_bfd, ia64_info, h, R_IA64_VMS_FIXFD,
+ input_section, rel->r_offset, 0);
+ r = bfd_reloc_ok;
+ break;
+ }
+
+ r = ia64_elf_install_value (hit_addr, value, r_type);
+ break;
+
+ case R_IA64_LTOFF_FPTR22:
+ case R_IA64_LTOFF_FPTR64I:
+ case R_IA64_LTOFF_FPTR32MSB:
+ case R_IA64_LTOFF_FPTR32LSB:
+ case R_IA64_LTOFF_FPTR64MSB:
+ case R_IA64_LTOFF_FPTR64LSB:
+ dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, FALSE);
+ if (dyn_i->want_fptr)
+ {
+ BFD_ASSERT (h == NULL || !h->def_dynamic);
+ if (!undef_weak_ref)
+ value = set_fptr_entry (output_bfd, info, dyn_i, value);
+ }
+ else
+ value = 0;
+
+ value = set_got_entry (output_bfd, info, dyn_i,
+ rel->r_addend, value, R_IA64_FPTR64LSB);
+ value -= gp_val;
+ r = ia64_elf_install_value (hit_addr, value, r_type);
+ break;
+
+ case R_IA64_PCREL32MSB:
+ case R_IA64_PCREL32LSB:
+ case R_IA64_PCREL64MSB:
+ case R_IA64_PCREL64LSB:
+ /* Install a dynamic relocation for this reloc. */
+ if (dynamic_symbol_p && r_symndx != 0)
+ {
+ /* VMS: doesn't exist ??? */
+ abort ();
+ }
+ goto finish_pcrel;
+
+ case R_IA64_PCREL21B:
+ case R_IA64_PCREL60B:
+ /* We should have created a PLT entry for any dynamic symbol. */
+ dyn_i = NULL;
+ if (h)
+ dyn_i = get_dyn_sym_info (ia64_info, h, NULL, NULL, FALSE);
+
+ if (dyn_i && dyn_i->want_plt2)
+ {
+ /* Should have caught this earlier. */
+ BFD_ASSERT (rel->r_addend == 0);
+
+ value = (ia64_info->root.splt->output_section->vma
+ + ia64_info->root.splt->output_offset
+ + dyn_i->plt2_offset);
+ }
+ else
+ {
+ /* Since there's no PLT entry, Validate that this is
+ locally defined. */
+ BFD_ASSERT (undef_weak_ref || sym_sec->output_section != NULL);
+
+ /* If the symbol is undef_weak, we shouldn't be trying
+ to call it. There's every chance that we'd wind up
+ with an out-of-range fixup here. Don't bother setting
+ any value at all. */
+ if (undef_weak_ref)
+ continue;
+ }
+ goto finish_pcrel;
+
+ case R_IA64_PCREL21BI:
+ case R_IA64_PCREL21F:
+ case R_IA64_PCREL21M:
+ case R_IA64_PCREL22:
+ case R_IA64_PCREL64I:
+ /* The PCREL21BI reloc is specifically not intended for use with
+ dynamic relocs. PCREL21F and PCREL21M are used for speculation
+ fixup code, and thus probably ought not be dynamic. The
+ PCREL22 and PCREL64I relocs aren't emitted as dynamic relocs. */
+ if (dynamic_symbol_p)
+ {
+ const char *msg;
+
+ if (r_type == R_IA64_PCREL21BI)
+ msg = _("%B: @internal branch to dynamic symbol %s");
+ else if (r_type == R_IA64_PCREL21F || r_type == R_IA64_PCREL21M)
+ msg = _("%B: speculation fixup to dynamic symbol %s");
+ else
+ msg = _("%B: @pcrel relocation against dynamic symbol %s");
+ (*_bfd_error_handler) (msg, input_bfd,
+ h ? h->root.root.string
+ : bfd_elf_sym_name (input_bfd,
+ symtab_hdr,
+ sym,
+ sym_sec));
+ ret_val = FALSE;
+ continue;
+ }
+ goto finish_pcrel;
+
+ finish_pcrel:
+ /* Make pc-relative. */
+ value -= (input_section->output_section->vma
+ + input_section->output_offset
+ + rel->r_offset) & ~ (bfd_vma) 0x3;
+ r = ia64_elf_install_value (hit_addr, value, r_type);
+ break;
+
+ case R_IA64_SEGREL32MSB:
+ case R_IA64_SEGREL32LSB:
+ case R_IA64_SEGREL64MSB:
+ case R_IA64_SEGREL64LSB:
+ {
+ /* Find the segment that contains the output_section. */
+ Elf_Internal_Phdr *p = _bfd_elf_find_segment_containing_section
+ (output_bfd, sym_sec->output_section);
+
+ if (p == NULL)
+ {
+ r = bfd_reloc_notsupported;
+ }
+ else
+ {
+ /* The VMA of the segment is the vaddr of the associated
+ program header. */
+ if (value > p->p_vaddr)
+ value -= p->p_vaddr;
+ else
+ value = 0;
+ r = ia64_elf_install_value (hit_addr, value, r_type);
+ }
+ break;
+ }
+
+ case R_IA64_SECREL32MSB:
+ case R_IA64_SECREL32LSB:
+ case R_IA64_SECREL64MSB:
+ case R_IA64_SECREL64LSB:
+ /* Make output-section relative to section where the symbol
+ is defined. PR 475 */
+ if (sym_sec)
+ value -= sym_sec->output_section->vma;
+ r = ia64_elf_install_value (hit_addr, value, r_type);
+ break;
+
+ case R_IA64_IPLTMSB:
+ case R_IA64_IPLTLSB:
+ /* Install a dynamic relocation for this reloc. */
+ if ((dynamic_symbol_p || info->shared)
+ && (input_section->flags & SEC_ALLOC) != 0)
+ {
+ /* VMS: FIXFD ?? */
+ abort ();
+ }
+
+ if (r_type == R_IA64_IPLTMSB)
+ r_type = R_IA64_DIR64MSB;
+ else
+ r_type = R_IA64_DIR64LSB;
+ ia64_elf_install_value (hit_addr, value, r_type);
+ r = ia64_elf_install_value (hit_addr + 8, gp_val, r_type);
+ break;
+
+ case R_IA64_TPREL14:
+ case R_IA64_TPREL22:
+ case R_IA64_TPREL64I:
+ r = bfd_reloc_notsupported;
+ break;
+
+ case R_IA64_DTPREL14:
+ case R_IA64_DTPREL22:
+ case R_IA64_DTPREL64I:
+ case R_IA64_DTPREL32LSB:
+ case R_IA64_DTPREL32MSB:
+ case R_IA64_DTPREL64LSB:
+ case R_IA64_DTPREL64MSB:
+ r = bfd_reloc_notsupported;
+ break;
+
+ case R_IA64_LTOFF_TPREL22:
+ case R_IA64_LTOFF_DTPMOD22:
+ case R_IA64_LTOFF_DTPREL22:
+ r = bfd_reloc_notsupported;
+ break;
+
+ default:
+ r = bfd_reloc_notsupported;
+ break;
+ }
+
+ switch (r)
+ {
+ case bfd_reloc_ok:
+ break;
+
+ case bfd_reloc_undefined:
+ /* This can happen for global table relative relocs if
+ __gp is undefined. This is a panic situation so we
+ don't try to continue. */
+ (*info->callbacks->undefined_symbol)
+ (info, "__gp", input_bfd, input_section, rel->r_offset, 1);
+ return FALSE;
+
+ case bfd_reloc_notsupported:
+ {
+ const char *name;
+
+ if (h)
+ name = h->root.root.string;
+ else
+ name = bfd_elf_sym_name (input_bfd, symtab_hdr, sym,
+ sym_sec);
+ if (!(*info->callbacks->warning) (info, _("unsupported reloc"),
+ name, input_bfd,
+ input_section, rel->r_offset))
+ return FALSE;
+ ret_val = FALSE;
+ }
+ break;
+
+ case bfd_reloc_dangerous:
+ case bfd_reloc_outofrange:
+ case bfd_reloc_overflow:
+ default:
+ {
+ const char *name;
+
+ if (h)
+ name = h->root.root.string;
+ else
+ name = bfd_elf_sym_name (input_bfd, symtab_hdr, sym,
+ sym_sec);
+
+ switch (r_type)
+ {
+ case R_IA64_TPREL14:
+ case R_IA64_TPREL22:
+ case R_IA64_TPREL64I:
+ case R_IA64_DTPREL14:
+ case R_IA64_DTPREL22:
+ case R_IA64_DTPREL64I:
+ case R_IA64_DTPREL32LSB:
+ case R_IA64_DTPREL32MSB:
+ case R_IA64_DTPREL64LSB:
+ case R_IA64_DTPREL64MSB:
+ case R_IA64_LTOFF_TPREL22:
+ case R_IA64_LTOFF_DTPMOD22:
+ case R_IA64_LTOFF_DTPREL22:
+ (*_bfd_error_handler)
+ (_("%B: missing TLS section for relocation %s against `%s' at 0x%lx in section `%A'."),
+ input_bfd, input_section, howto->name, name,
+ rel->r_offset);
+ break;
+
+ case R_IA64_PCREL21B:
+ case R_IA64_PCREL21BI:
+ case R_IA64_PCREL21M:
+ case R_IA64_PCREL21F:
+ if (is_elf_hash_table (info->hash))
+ {
+ /* Relaxtion is always performed for ELF output.
+ Overflow failures for those relocations mean
+ that the section is too big to relax. */
+ (*_bfd_error_handler)
+ (_("%B: Can't relax br (%s) to `%s' at 0x%lx in section `%A' with size 0x%lx (> 0x1000000)."),
+ input_bfd, input_section, howto->name, name,
+ rel->r_offset, input_section->size);
+ break;
+ }
+ default:
+ if (!(*info->callbacks->reloc_overflow) (info,
+ &h->root,
+ name,
+ howto->name,
+ (bfd_vma) 0,
+ input_bfd,
+ input_section,
+ rel->r_offset))
+ return FALSE;
+ break;
+ }
+
+ ret_val = FALSE;
+ }
+ break;
+ }
+ }
+
+ return ret_val;
+}
+
+static bfd_boolean
+elf64_ia64_finish_dynamic_symbol (bfd *output_bfd,
+ struct bfd_link_info *info,
+ struct elf_link_hash_entry *h,
+ Elf_Internal_Sym *sym)
+{
+ struct elf64_ia64_link_hash_table *ia64_info;
+ struct elf64_ia64_dyn_sym_info *dyn_i;
+
+ ia64_info = elf64_ia64_hash_table (info);
+ if (ia64_info == NULL)
+ return FALSE;
+
+ dyn_i = get_dyn_sym_info (ia64_info, h, NULL, NULL, FALSE);
+
+ /* Fill in the PLT data, if required. */
+ if (dyn_i && dyn_i->want_plt)
+ {
+ bfd_byte *loc;
+ asection *plt_sec;
+ bfd_vma plt_addr, pltoff_addr, gp_val;
+
+ gp_val = _bfd_get_gp_value (output_bfd);
+
+ plt_sec = ia64_info->root.splt;
+ plt_addr = 0; /* Not used as overriden by FIXUPs. */
+ pltoff_addr = set_pltoff_entry (output_bfd, info, dyn_i, plt_addr, TRUE);
+
+ /* Initialize the FULL PLT entry, if needed. */
+ if (dyn_i->want_plt2)
+ {
+ loc = plt_sec->contents + dyn_i->plt2_offset;
+
+ memcpy (loc, plt_full_entry, PLT_FULL_ENTRY_SIZE);
+ ia64_elf_install_value (loc, pltoff_addr - gp_val, R_IA64_IMM22);
+
+ /* Mark the symbol as undefined, rather than as defined in the
+ plt section. Leave the value alone. */
+ /* ??? We didn't redefine it in adjust_dynamic_symbol in the
+ first place. But perhaps elflink.c did some for us. */
+ if (!h->def_regular)
+ sym->st_shndx = SHN_UNDEF;
+ }
+
+ /* VMS: FIXFD. */
+ elf64_ia64_install_fixup
+ (output_bfd, ia64_info, h, R_IA64_VMS_FIXFD, ia64_info->pltoff_sec,
+ pltoff_addr - (ia64_info->pltoff_sec->output_section->vma
+ + ia64_info->pltoff_sec->output_offset), 0);
+ }
+
+ /* Mark some specially defined symbols as absolute. */
+ if (h == ia64_info->root.hdynamic
+ || h == ia64_info->root.hgot
+ || h == ia64_info->root.hplt)
+ sym->st_shndx = SHN_ABS;
+
+ return TRUE;
+}
+
+static bfd_boolean
+elf64_ia64_finish_dynamic_sections (bfd *abfd,
+ struct bfd_link_info *info)
+{
+ struct elf64_ia64_link_hash_table *ia64_info;
+ bfd *dynobj;
+
+ ia64_info = elf64_ia64_hash_table (info);
+ if (ia64_info == NULL)
+ return FALSE;
+
+ dynobj = ia64_info->root.dynobj;
+
+ if (elf_hash_table (info)->dynamic_sections_created)
+ {
+ Elf64_External_Dyn *dyncon, *dynconend;
+ asection *sdyn;
+ asection *unwind_sec;
+ bfd_vma gp_val;
+ unsigned int gp_seg;
+ bfd_vma gp_off;
+ Elf_Internal_Phdr *phdr;
+ Elf_Internal_Phdr *base_phdr;
+ unsigned int unwind_seg = 0;
+ unsigned int code_seg = 0;
+
+ sdyn = bfd_get_linker_section (dynobj, ".dynamic");
+ BFD_ASSERT (sdyn != NULL);
+ dyncon = (Elf64_External_Dyn *) sdyn->contents;
+ dynconend = (Elf64_External_Dyn *) (sdyn->contents + sdyn->size);
+
+ gp_val = _bfd_get_gp_value (abfd);
+ phdr = _bfd_elf_find_segment_containing_section
+ (info->output_bfd, ia64_info->pltoff_sec->output_section);
+ BFD_ASSERT (phdr != NULL);
+ base_phdr = elf_tdata (info->output_bfd)->phdr;
+ gp_seg = phdr - base_phdr;
+ gp_off = gp_val - phdr->p_vaddr;
+
+ unwind_sec = bfd_get_section_by_name (abfd, ELF_STRING_ia64_unwind);
+ if (unwind_sec != NULL)
+ {
+ asection *code_sec;
+
+ phdr = _bfd_elf_find_segment_containing_section (abfd, unwind_sec);
+ BFD_ASSERT (phdr != NULL);
+ unwind_seg = phdr - base_phdr;
+
+ code_sec = bfd_get_section_by_name (abfd, "$CODE$");
+ phdr = _bfd_elf_find_segment_containing_section (abfd, code_sec);
+ BFD_ASSERT (phdr != NULL);
+ code_seg = phdr - base_phdr;
+ }
+
+ for (; dyncon < dynconend; dyncon++)
+ {
+ Elf_Internal_Dyn dyn;
+
+ bfd_elf64_swap_dyn_in (dynobj, dyncon, &dyn);
+
+ switch (dyn.d_tag)
+ {
+ case DT_IA_64_VMS_FIXUP_RELA_OFF:
+ dyn.d_un.d_val +=
+ (ia64_info->fixups_sec->output_section->vma
+ + ia64_info->fixups_sec->output_offset)
+ - (sdyn->output_section->vma + sdyn->output_offset);
+ break;
+
+ case DT_IA_64_VMS_PLTGOT_OFFSET:
+ dyn.d_un.d_val = gp_off;
+ break;
+
+ case DT_IA_64_VMS_PLTGOT_SEG:
+ dyn.d_un.d_val = gp_seg;
+ break;
+
+ case DT_IA_64_VMS_UNWINDSZ:
+ if (unwind_sec == NULL)
+ {
+ dyn.d_tag = DT_NULL;
+ dyn.d_un.d_val = 0xdead;
+ }
+ else
+ dyn.d_un.d_val = unwind_sec->size;
+ break;
+
+ case DT_IA_64_VMS_UNWIND_CODSEG:
+ dyn.d_un.d_val = code_seg;
+ break;
+
+ case DT_IA_64_VMS_UNWIND_INFOSEG:
+ case DT_IA_64_VMS_UNWIND_SEG:
+ dyn.d_un.d_val = unwind_seg;
+ break;
+
+ case DT_IA_64_VMS_UNWIND_OFFSET:
+ break;
+
+ default:
+ /* No need to rewrite the entry. */
+ continue;
+ }
+
+ bfd_elf64_swap_dyn_out (abfd, &dyn, dyncon);
+ }
+ }
+
+ /* Handle transfer addresses. */
+ {
+ asection *tfr_sec = ia64_info->transfer_sec;
+ struct elf64_vms_transfer *tfr;
+ struct elf_link_hash_entry *tfr3;
+
+ tfr = (struct elf64_vms_transfer *)tfr_sec->contents;
+ bfd_putl32 (6 * 8, tfr->size);
+ bfd_putl64 (tfr_sec->output_section->vma
+ + tfr_sec->output_offset
+ + 6 * 8, tfr->tfradr3);
+
+ tfr3 = elf_link_hash_lookup (elf_hash_table (info), "ELF$TFRADR", FALSE,
+ FALSE, FALSE);
+
+ if (tfr3
+ && (tfr3->root.type == bfd_link_hash_defined
+ || tfr3->root.type == bfd_link_hash_defweak))
+ {
+ asection *tfr3_sec = tfr3->root.u.def.section;
+ bfd_vma tfr3_val;
+
+ tfr3_val = (tfr3->root.u.def.value
+ + tfr3_sec->output_section->vma
+ + tfr3_sec->output_offset);
+
+ bfd_putl64 (tfr3_val, tfr->tfr3_func);
+ bfd_putl64 (_bfd_get_gp_value (info->output_bfd), tfr->tfr3_gp);
+ }
+
+ /* FIXME: set linker flags,
+ handle lib$initialize. */
+ }
+
+ return TRUE;
+}
+
+/* ELF file flag handling: */
+
+/* Function to keep IA-64 specific file flags. */
+static bfd_boolean
+elf64_ia64_set_private_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;
+}
+
+/* Merge backend specific data from an object file to the output
+ object file when linking. */
+static bfd_boolean
+elf64_ia64_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
+{
+ flagword out_flags;
+ flagword in_flags;
+ bfd_boolean ok = TRUE;
+
+ /* Don't even pretend to support mixed-format linking. */
+ if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
+ || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
+ return FALSE;
+
+ in_flags = elf_elfheader (ibfd)->e_flags;
+ out_flags = elf_elfheader (obfd)->e_flags;
+
+ if (! elf_flags_init (obfd))
+ {
+ 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;
+
+ /* Output has EF_IA_64_REDUCEDFP set only if all inputs have it set. */
+ if (!(in_flags & EF_IA_64_REDUCEDFP) && (out_flags & EF_IA_64_REDUCEDFP))
+ elf_elfheader (obfd)->e_flags &= ~EF_IA_64_REDUCEDFP;
+
+ if ((in_flags & EF_IA_64_TRAPNIL) != (out_flags & EF_IA_64_TRAPNIL))
+ {
+ (*_bfd_error_handler)
+ (_("%B: linking trap-on-NULL-dereference with non-trapping files"),
+ ibfd);
+
+ bfd_set_error (bfd_error_bad_value);
+ ok = FALSE;
+ }
+ if ((in_flags & EF_IA_64_BE) != (out_flags & EF_IA_64_BE))
+ {
+ (*_bfd_error_handler)
+ (_("%B: linking big-endian files with little-endian files"),
+ ibfd);
+
+ bfd_set_error (bfd_error_bad_value);
+ ok = FALSE;
+ }
+ if ((in_flags & EF_IA_64_ABI64) != (out_flags & EF_IA_64_ABI64))
+ {
+ (*_bfd_error_handler)
+ (_("%B: linking 64-bit files with 32-bit files"),
+ ibfd);
+
+ bfd_set_error (bfd_error_bad_value);
+ ok = FALSE;
+ }
+ if ((in_flags & EF_IA_64_CONS_GP) != (out_flags & EF_IA_64_CONS_GP))
+ {
+ (*_bfd_error_handler)
+ (_("%B: linking constant-gp files with non-constant-gp files"),
+ ibfd);
+
+ bfd_set_error (bfd_error_bad_value);
+ ok = FALSE;
+ }
+ if ((in_flags & EF_IA_64_NOFUNCDESC_CONS_GP)
+ != (out_flags & EF_IA_64_NOFUNCDESC_CONS_GP))
+ {
+ (*_bfd_error_handler)
+ (_("%B: linking auto-pic files with non-auto-pic files"),
+ ibfd);
+
+ bfd_set_error (bfd_error_bad_value);
+ ok = FALSE;
+ }
+
+ return ok;
+}
+
+static bfd_boolean
+elf64_ia64_print_private_bfd_data (bfd *abfd, void * ptr)
+{
+ FILE *file = (FILE *) ptr;
+ flagword flags = elf_elfheader (abfd)->e_flags;
+
+ BFD_ASSERT (abfd != NULL && ptr != NULL);
+
+ fprintf (file, "private flags = %s%s%s%s%s%s%s%s\n",
+ (flags & EF_IA_64_TRAPNIL) ? "TRAPNIL, " : "",
+ (flags & EF_IA_64_EXT) ? "EXT, " : "",
+ (flags & EF_IA_64_BE) ? "BE, " : "LE, ",
+ (flags & EF_IA_64_REDUCEDFP) ? "REDUCEDFP, " : "",
+ (flags & EF_IA_64_CONS_GP) ? "CONS_GP, " : "",
+ (flags & EF_IA_64_NOFUNCDESC_CONS_GP) ? "NOFUNCDESC_CONS_GP, " : "",
+ (flags & EF_IA_64_ABSOLUTE) ? "ABSOLUTE, " : "",
+ (flags & EF_IA_64_ABI64) ? "ABI64" : "ABI32");
+
+ _bfd_elf_print_private_bfd_data (abfd, ptr);
+ return TRUE;
+}
+
+static enum elf_reloc_type_class
+elf64_ia64_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ const asection *rel_sec ATTRIBUTE_UNUSED,
+ const Elf_Internal_Rela *rela)
+{
+ switch ((int) ELF64_R_TYPE (rela->r_info))
+ {
+ case R_IA64_REL32MSB:
+ case R_IA64_REL32LSB:
+ case R_IA64_REL64MSB:
+ case R_IA64_REL64LSB:
+ return reloc_class_relative;
+ case R_IA64_IPLTMSB:
+ case R_IA64_IPLTLSB:
+ return reloc_class_plt;
+ case R_IA64_COPY:
+ return reloc_class_copy;
+ default:
+ return reloc_class_normal;
+ }
+}
+
+static const struct bfd_elf_special_section elf64_ia64_special_sections[] =
+{
+ { STRING_COMMA_LEN (".sbss"), -1, SHT_NOBITS, SHF_ALLOC + SHF_WRITE + SHF_IA_64_SHORT },
+ { STRING_COMMA_LEN (".sdata"), -1, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE + SHF_IA_64_SHORT },
+ { NULL, 0, 0, 0, 0 }
+};
+
+static bfd_boolean
+elf64_ia64_object_p (bfd *abfd)
+{
+ asection *sec;
+ asection *group, *unwi, *unw;
+ flagword flags;
+ const char *name;
+ char *unwi_name, *unw_name;
+ bfd_size_type amt;
+
+ if (abfd->flags & DYNAMIC)
+ return TRUE;
+
+ /* Flags for fake group section. */
+ flags = (SEC_LINKER_CREATED | SEC_GROUP | SEC_LINK_ONCE
+ | SEC_EXCLUDE);
+
+ /* We add a fake section group for each .gnu.linkonce.t.* section,
+ which isn't in a section group, and its unwind sections. */
+ for (sec = abfd->sections; sec != NULL; sec = sec->next)
+ {
+ if (elf_sec_group (sec) == NULL
+ && ((sec->flags & (SEC_LINK_ONCE | SEC_CODE | SEC_GROUP))
+ == (SEC_LINK_ONCE | SEC_CODE))
+ && CONST_STRNEQ (sec->name, ".gnu.linkonce.t."))
+ {
+ name = sec->name + 16;
+
+ amt = strlen (name) + sizeof (".gnu.linkonce.ia64unwi.");
+ unwi_name = bfd_alloc (abfd, amt);
+ if (!unwi_name)
+ return FALSE;
+
+ strcpy (stpcpy (unwi_name, ".gnu.linkonce.ia64unwi."), name);
+ unwi = bfd_get_section_by_name (abfd, unwi_name);
+
+ amt = strlen (name) + sizeof (".gnu.linkonce.ia64unw.");
+ unw_name = bfd_alloc (abfd, amt);
+ if (!unw_name)
+ return FALSE;
+
+ strcpy (stpcpy (unw_name, ".gnu.linkonce.ia64unw."), name);
+ unw = bfd_get_section_by_name (abfd, unw_name);
+
+ /* We need to create a fake group section for it and its
+ unwind sections. */
+ group = bfd_make_section_anyway_with_flags (abfd, name,
+ flags);
+ if (group == NULL)
+ return FALSE;
+
+ /* Move the fake group section to the beginning. */
+ bfd_section_list_remove (abfd, group);
+ bfd_section_list_prepend (abfd, group);
+
+ elf_next_in_group (group) = sec;
+
+ elf_group_name (sec) = name;
+ elf_next_in_group (sec) = sec;
+ elf_sec_group (sec) = group;
+
+ if (unwi)
+ {
+ elf_group_name (unwi) = name;
+ elf_next_in_group (unwi) = sec;
+ elf_next_in_group (sec) = unwi;
+ elf_sec_group (unwi) = group;
+ }
+
+ if (unw)
+ {
+ elf_group_name (unw) = name;
+ if (unwi)
+ {
+ elf_next_in_group (unw) = elf_next_in_group (unwi);
+ elf_next_in_group (unwi) = unw;
+ }
+ else
+ {
+ elf_next_in_group (unw) = sec;
+ elf_next_in_group (sec) = unw;
+ }
+ elf_sec_group (unw) = group;
+ }
+
+ /* Fake SHT_GROUP section header. */
+ elf_section_data (group)->this_hdr.bfd_section = group;
+ elf_section_data (group)->this_hdr.sh_type = SHT_GROUP;
+ }
+ }
+ return TRUE;
+}
+
+/* Handle an IA-64 specific section when reading an object file. This
+ is called when bfd_section_from_shdr finds a section with an unknown
+ type. */
+
+static bfd_boolean
+elf64_vms_section_from_shdr (bfd *abfd,
+ Elf_Internal_Shdr *hdr,
+ const char *name,
+ int shindex)
+{
+ flagword secflags = 0;
+
+ switch (hdr->sh_type)
+ {
+ case SHT_IA_64_VMS_TRACE:
+ case SHT_IA_64_VMS_DEBUG:
+ case SHT_IA_64_VMS_DEBUG_STR:
+ secflags = SEC_DEBUGGING;
+ break;
+
+ case SHT_IA_64_UNWIND:
+ case SHT_IA_64_HP_OPT_ANOT:
+ break;
+
+ case SHT_IA_64_EXT:
+ if (strcmp (name, ELF_STRING_ia64_archext) != 0)
+ return FALSE;
+ break;
+
+ default:
+ return FALSE;
+ }
+
+ if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex))
+ return FALSE;
+
+ if (secflags != 0)
+ {
+ asection *newsect = hdr->bfd_section;
+
+ if (! bfd_set_section_flags
+ (abfd, newsect, bfd_get_section_flags (abfd, newsect) | secflags))
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static bfd_boolean
+elf64_vms_object_p (bfd *abfd)
+{
+ Elf_Internal_Ehdr *i_ehdrp = elf_elfheader (abfd);
+ Elf_Internal_Phdr *i_phdr = elf_tdata (abfd)->phdr;
+ unsigned int i;
+ unsigned int num_text = 0;
+ unsigned int num_data = 0;
+ unsigned int num_rodata = 0;
+ char name[16];
+
+ if (!elf64_ia64_object_p (abfd))
+ return FALSE;
+
+ /* Many VMS compilers do not generate sections for the corresponding
+ segment. This is boring as binutils tools won't be able to disassemble
+ the code. So we simply create all the missing sections. */
+ for (i = 0; i < i_ehdrp->e_phnum; i++, i_phdr++)
+ {
+ /* Is there a section for this segment? */
+ bfd_vma base_vma = i_phdr->p_vaddr;
+ bfd_vma limit_vma = base_vma + i_phdr->p_filesz;
+
+ if (i_phdr->p_type != PT_LOAD)
+ continue;
+
+ /* We need to cover from base_vms to limit_vma. */
+ again:
+ while (base_vma < limit_vma)
+ {
+ bfd_vma next_vma = limit_vma;
+ asection *nsec;
+ asection *sec;
+ flagword flags;
+ char *nname = NULL;
+
+ /* Find a section covering [base_vma;limit_vma) */
+ for (sec = abfd->sections; sec != NULL; sec = sec->next)
+ {
+ /* Skip uninteresting sections (either not in memory or
+ below base_vma. */
+ if ((sec->flags & (SEC_ALLOC | SEC_LOAD)) == 0
+ || sec->vma + sec->size <= base_vma)
+ continue;
+ if (sec->vma <= base_vma)
+ {
+ /* This section covers (maybe partially) the beginning
+ of the range. */
+ base_vma = sec->vma + sec->size;
+ goto again;
+ }
+ if (sec->vma < next_vma)
+ {
+ /* This section partially covers the end of the range.
+ Used to compute the size of the hole. */
+ next_vma = sec->vma;
+ }
+ }
+
+ /* No section covering [base_vma; next_vma). Create a fake one. */
+ flags = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS;
+ if (i_phdr->p_flags & PF_X)
+ {
+ flags |= SEC_CODE;
+ if (num_text++ == 0)
+ nname = ".text";
+ else
+ sprintf (name, ".text$%u", num_text);
+ }
+ else if ((i_phdr->p_flags & (PF_R | PF_W)) == PF_R)
+ {
+ flags |= SEC_READONLY;
+ sprintf (name, ".rodata$%u", num_rodata++);
+ }
+ else
+ {
+ flags |= SEC_DATA;
+ sprintf (name, ".data$%u", num_data++);
+ }
+
+ /* Allocate name. */
+ if (nname == NULL)
+ {
+ size_t name_len = strlen (name) + 1;
+ nname = bfd_alloc (abfd, name_len);
+ if (nname == NULL)
+ return FALSE;
+ memcpy (nname, name, name_len);
+ }
+
+ /* Create and fill new section. */
+ nsec = bfd_make_section_anyway_with_flags (abfd, nname, flags);
+ if (nsec == NULL)
+ return FALSE;
+ nsec->vma = base_vma;
+ nsec->size = next_vma - base_vma;
+ nsec->filepos = i_phdr->p_offset + (base_vma - i_phdr->p_vaddr);
+
+ base_vma = next_vma;
+ }
+ }
+ return TRUE;
+}
+
+static void
+elf64_vms_post_process_headers (bfd *abfd,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED)
+{
+ Elf_Internal_Ehdr *i_ehdrp = elf_elfheader (abfd);
+
+ i_ehdrp->e_ident[EI_OSABI] = ELFOSABI_OPENVMS;
+ i_ehdrp->e_ident[EI_ABIVERSION] = 2;
+}
+
+static bfd_boolean
+elf64_vms_section_processing (bfd *abfd ATTRIBUTE_UNUSED,
+ Elf_Internal_Shdr *hdr)
+{
+ if (hdr->bfd_section != NULL)
+ {
+ const char *name = bfd_get_section_name (abfd, hdr->bfd_section);
+
+ if (strcmp (name, ".text") == 0)
+ hdr->sh_flags |= SHF_IA_64_VMS_SHARED;
+ else if ((strcmp (name, ".debug") == 0)
+ || (strcmp (name, ".debug_abbrev") == 0)
+ || (strcmp (name, ".debug_aranges") == 0)
+ || (strcmp (name, ".debug_frame") == 0)
+ || (strcmp (name, ".debug_info") == 0)
+ || (strcmp (name, ".debug_loc") == 0)
+ || (strcmp (name, ".debug_macinfo") == 0)
+ || (strcmp (name, ".debug_pubnames") == 0)
+ || (strcmp (name, ".debug_pubtypes") == 0))
+ hdr->sh_type = SHT_IA_64_VMS_DEBUG;
+ else if ((strcmp (name, ".debug_line") == 0)
+ || (strcmp (name, ".debug_ranges") == 0)
+ || (strcmp (name, ".trace_info") == 0)
+ || (strcmp (name, ".trace_abbrev") == 0)
+ || (strcmp (name, ".trace_aranges") == 0))
+ hdr->sh_type = SHT_IA_64_VMS_TRACE;
+ else if (strcmp (name, ".debug_str") == 0)
+ hdr->sh_type = SHT_IA_64_VMS_DEBUG_STR;
+ }
+
+ return TRUE;
+}
+
+/* The final processing done just before writing out a VMS IA-64 ELF
+ object file. */
+
+static void
+elf64_vms_final_write_processing (bfd *abfd,
+ bfd_boolean linker ATTRIBUTE_UNUSED)
+{
+ Elf_Internal_Shdr *hdr;
+ asection *s;
+ int unwind_info_sect_idx = 0;
+
+ for (s = abfd->sections; s; s = s->next)
+ {
+ hdr = &elf_section_data (s)->this_hdr;
+
+ if (strcmp (bfd_get_section_name (abfd, hdr->bfd_section),
+ ".IA_64.unwind_info") == 0)
+ unwind_info_sect_idx = elf_section_data (s)->this_idx;
+
+ switch (hdr->sh_type)
+ {
+ case SHT_IA_64_UNWIND:
+ /* VMS requires sh_info to point to the unwind info section. */
+ hdr->sh_info = unwind_info_sect_idx;
+ break;
+ }
+ }
+
+ if (! elf_flags_init (abfd))
+ {
+ unsigned long flags = 0;
+
+ if (abfd->xvec->byteorder == BFD_ENDIAN_BIG)
+ flags |= EF_IA_64_BE;
+ if (bfd_get_mach (abfd) == bfd_mach_ia64_elf64)
+ flags |= EF_IA_64_ABI64;
+
+ elf_elfheader (abfd)->e_flags = flags;
+ elf_flags_init (abfd) = TRUE;
+ }
+}
+
+static bfd_boolean
+elf64_vms_write_shdrs_and_ehdr (bfd *abfd)
+{
+ unsigned char needed_count[8];
+
+ if (!bfd_elf64_write_shdrs_and_ehdr (abfd))
+ return FALSE;
+
+ bfd_putl64 (elf_ia64_vms_tdata (abfd)->needed_count, needed_count);
+
+ if (bfd_seek (abfd, sizeof (Elf64_External_Ehdr), SEEK_SET) != 0
+ || bfd_bwrite (needed_count, 8, abfd) != 8)
+ return FALSE;
+
+ return TRUE;
+}
+
+static bfd_boolean
+elf64_vms_close_and_cleanup (bfd *abfd)
+{
+ if (bfd_get_format (abfd) == bfd_object)
+ {
+ long isize;
+
+ /* Pad to 8 byte boundary for IPF/VMS. */
+ isize = bfd_get_size (abfd);
+ if ((isize & 7) != 0)
+ {
+ int ishort = 8 - (isize & 7);
+ bfd_uint64_t pad = 0;
+
+ bfd_seek (abfd, isize, SEEK_SET);
+ bfd_bwrite (&pad, ishort, abfd);
+ }
+ }
+
+ return _bfd_elf_close_and_cleanup (abfd);
+}
+
+/* Add symbols from an ELF object file to the linker hash table. */
+
+static bfd_boolean
+elf64_vms_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info)
+{
+ Elf_Internal_Shdr *hdr;
+ bfd_size_type symcount;
+ bfd_size_type extsymcount;
+ bfd_size_type extsymoff;
+ struct elf_link_hash_entry **sym_hash;
+ bfd_boolean dynamic;
+ Elf_Internal_Sym *isymbuf = NULL;
+ Elf_Internal_Sym *isym;
+ Elf_Internal_Sym *isymend;
+ const struct elf_backend_data *bed;
+ struct elf_link_hash_table *htab;
+ bfd_size_type amt;
+
+ htab = elf_hash_table (info);
+ bed = get_elf_backend_data (abfd);
+
+ 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->relocatable
+ || !is_elf_hash_table (htab)
+ || info->output_bfd->xvec != abfd->xvec)
+ {
+ if (info->relocatable)
+ bfd_set_error (bfd_error_invalid_operation);
+ else
+ bfd_set_error (bfd_error_wrong_format);
+ goto error_return;
+ }
+ }
+
+ 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
+ && is_elf_hash_table (htab)
+ && info->output_bfd->xvec == abfd->xvec
+ && !htab->dynamic_sections_created)
+ {
+ if (! elf64_ia64_create_dynamic_sections (abfd, info))
+ goto error_return;
+ }
+ }
+ else if (!is_elf_hash_table (htab))
+ goto error_return;
+ else
+ {
+ asection *s;
+ bfd_byte *dynbuf;
+ bfd_byte *extdyn;
+
+ /* ld --just-symbols and dynamic objects don't mix very well.
+ ld shouldn't allow it. */
+ if ((s = abfd->sections) != NULL
+ && s->sec_info_type == SEC_INFO_TYPE_JUST_SYMS)
+ abort ();
+
+ /* Be sure there are dynamic sections. */
+ if (! elf64_ia64_create_dynamic_sections (htab->dynobj, info))
+ goto error_return;
+
+ s = bfd_get_section_by_name (abfd, ".dynamic");
+ if (s == NULL)
+ {
+ /* VMS libraries do not have dynamic sections. Create one from
+ the segment. */
+ Elf_Internal_Phdr *phdr;
+ unsigned int i, phnum;
+
+ phdr = elf_tdata (abfd)->phdr;
+ if (phdr == NULL)
+ goto error_return;
+ phnum = elf_elfheader (abfd)->e_phnum;
+ for (i = 0; i < phnum; phdr++)
+ if (phdr->p_type == PT_DYNAMIC)
+ {
+ s = bfd_make_section (abfd, ".dynamic");
+ if (s == NULL)
+ goto error_return;
+ s->vma = phdr->p_vaddr;
+ s->lma = phdr->p_paddr;
+ s->size = phdr->p_filesz;
+ s->filepos = phdr->p_offset;
+ s->flags |= SEC_HAS_CONTENTS;
+ s->alignment_power = bfd_log2 (phdr->p_align);
+ break;
+ }
+ if (s == NULL)
+ goto error_return;
+ }
+
+ /* Extract IDENT. */
+ if (!bfd_malloc_and_get_section (abfd, s, &dynbuf))
+ {
+error_free_dyn:
+ free (dynbuf);
+ goto error_return;
+ }
+
+ for (extdyn = dynbuf;
+ extdyn < dynbuf + s->size;
+ extdyn += bed->s->sizeof_dyn)
+ {
+ Elf_Internal_Dyn dyn;
+
+ bed->s->swap_dyn_in (abfd, extdyn, &dyn);
+ if (dyn.d_tag == DT_IA_64_VMS_IDENT)
+ {
+ bfd_uint64_t tagv = dyn.d_un.d_val;
+ elf_ia64_vms_ident (abfd) = tagv;
+ break;
+ }
+ }
+ if (extdyn >= dynbuf + s->size)
+ {
+ /* Ident not found. */
+ goto error_free_dyn;
+ }
+ free (dynbuf);
+
+ /* 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. */
+ bfd_section_list_clear (abfd);
+
+ /* FIXME: should we detect if this library is already included ?
+ This should be harmless and shouldn't happen in practice. */
+ }
+
+ hdr = &elf_tdata (abfd)->symtab_hdr;
+ symcount = hdr->sh_size / bed->s->sizeof_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. */
+ extsymcount = symcount - hdr->sh_info;
+ extsymoff = hdr->sh_info;
+
+ sym_hash = NULL;
+ if (extsymcount != 0)
+ {
+ isymbuf = bfd_elf_get_elf_syms (abfd, hdr, extsymcount, extsymoff,
+ NULL, NULL, NULL);
+ if (isymbuf == NULL)
+ goto error_return;
+
+ /* We store a pointer to the hash table entry for each external
+ symbol. */
+ amt = extsymcount * sizeof (struct elf_link_hash_entry *);
+ sym_hash = (struct elf_link_hash_entry **) bfd_alloc (abfd, amt);
+ if (sym_hash == NULL)
+ goto error_free_sym;
+ elf_sym_hashes (abfd) = sym_hash;
+ }
+
+ for (isym = isymbuf, isymend = isymbuf + extsymcount;
+ isym < isymend;
+ isym++, sym_hash++)
+ {
+ int bind;
+ bfd_vma value;
+ asection *sec, *new_sec;
+ flagword flags;
+ const char *name;
+ struct elf_link_hash_entry *h;
+ bfd_boolean definition;
+ bfd_boolean size_change_ok;
+ bfd_boolean type_change_ok;
+ bfd_boolean common;
+ unsigned int old_alignment;
+ bfd *old_bfd;
+
+ flags = BSF_NO_FLAGS;
+ sec = NULL;
+ value = isym->st_value;
+ *sym_hash = NULL;
+ common = bed->common_definition (isym);
+
+ bind = ELF_ST_BIND (isym->st_info);
+ switch (bind)
+ {
+ case 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. Unfortunately, Irix 5
+ screws this up. */
+ continue;
+
+ case STB_GLOBAL:
+ if (isym->st_shndx != SHN_UNDEF && !common)
+ flags = BSF_GLOBAL;
+ break;
+
+ case STB_WEAK:
+ flags = BSF_WEAK;
+ break;
+
+ case STB_GNU_UNIQUE:
+ flags = BSF_GNU_UNIQUE;
+ break;
+
+ default:
+ /* Leave it up to the processor backend. */
+ break;
+ }
+
+ if (isym->st_shndx == SHN_UNDEF)
+ sec = bfd_und_section_ptr;
+ else if (isym->st_shndx == SHN_ABS)
+ sec = bfd_abs_section_ptr;
+ else if (isym->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 = isym->st_size;
+ }
+ else
+ {
+ sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
+ if (sec == NULL)
+ sec = bfd_abs_section_ptr;
+ else if (sec->kept_section)
+ {
+ /* Symbols from discarded section are undefined. We keep
+ its visibility. */
+ sec = bfd_und_section_ptr;
+ isym->st_shndx = SHN_UNDEF;
+ }
+ else if ((abfd->flags & (EXEC_P | DYNAMIC)) != 0)
+ value -= sec->vma;
+ }
+
+ name = bfd_elf_string_from_elf_section (abfd, hdr->sh_link,
+ isym->st_name);
+ if (name == NULL)
+ goto error_free_vers;
+
+ if (bed->elf_add_symbol_hook)
+ {
+ if (! (*bed->elf_add_symbol_hook) (abfd, info, isym, &name, &flags,
+ &sec, &value))
+ goto error_free_vers;
+
+ /* The hook function sets the name to NULL if this symbol
+ should be skipped for some reason. */
+ if (name == NULL)
+ continue;
+ }
+
+ /* Sanity check that all possibilities were handled. */
+ if (sec == NULL)
+ {
+ bfd_set_error (bfd_error_bad_value);
+ goto error_free_vers;
+ }
+
+ if (bfd_is_und_section (sec)
+ || bfd_is_com_section (sec))
+ definition = FALSE;
+ else
+ definition = TRUE;
+
+ size_change_ok = FALSE;
+ type_change_ok = bed->type_change_ok;
+ old_alignment = 0;
+ old_bfd = NULL;
+ new_sec = sec;
+
+ if (! bfd_is_und_section (sec))
+ h = elf_link_hash_lookup (htab, 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)
+ goto error_free_sym;
+
+ *sym_hash = h;
+
+ if (is_elf_hash_table (htab))
+ {
+ 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. We also remember the old bfd where the existing
+ definition comes from. */
+ switch (h->root.type)
+ {
+ default:
+ break;
+
+ case bfd_link_hash_defined:
+ if (abfd->selective_search)
+ continue;
+ /* Fall-through. */
+ case bfd_link_hash_defweak:
+ old_bfd = h->root.u.def.section->owner;
+ break;
+
+ case bfd_link_hash_common:
+ old_bfd = h->root.u.c.p->section->owner;
+ old_alignment = h->root.u.c.p->alignment_power;
+ break;
+ }
+ }
+
+ if (! (_bfd_generic_link_add_one_symbol
+ (info, abfd, name, flags, sec, value, NULL, FALSE, bed->collect,
+ (struct bfd_link_hash_entry **) sym_hash)))
+ goto error_free_vers;
+
+ 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;
+ if (definition)
+ h->unique_global = (flags & BSF_GNU_UNIQUE) != 0;
+
+ /* Set the alignment of a common symbol. */
+ if ((common || bfd_is_com_section (sec))
+ && h->root.type == bfd_link_hash_common)
+ {
+ unsigned int align;
+
+ if (common)
+ align = bfd_log2 (isym->st_value);
+ else
+ {
+ /* The new symbol is a common symbol in a shared object.
+ We need to get the alignment from the section. */
+ align = new_sec->alignment_power;
+ }
+ if (align > old_alignment
+ /* Permit an alignment power of zero if an alignment of one
+ is specified and no other alignments have been specified. */
+ || (isym->st_value == 1 && old_alignment == 0))
+ h->root.u.c.p->alignment_power = align;
+ else
+ h->root.u.c.p->alignment_power = old_alignment;
+ }
+
+ if (is_elf_hash_table (htab))
+ {
+ /* Check the alignment when a common symbol is involved. This
+ can change when a common symbol is overridden by a normal
+ definition or a common symbol is ignored due to the old
+ normal definition. We need to make sure the maximum
+ alignment is maintained. */
+ if ((old_alignment || common)
+ && h->root.type != bfd_link_hash_common)
+ {
+ unsigned int common_align;
+ unsigned int normal_align;
+ unsigned int symbol_align;
+ bfd *normal_bfd;
+ bfd *common_bfd;
+
+ symbol_align = ffs (h->root.u.def.value) - 1;
+ if (h->root.u.def.section->owner != NULL
+ && (h->root.u.def.section->owner->flags & DYNAMIC) == 0)
+ {
+ normal_align = h->root.u.def.section->alignment_power;
+ if (normal_align > symbol_align)
+ normal_align = symbol_align;
+ }
+ else
+ normal_align = symbol_align;
+
+ if (old_alignment)
+ {
+ common_align = old_alignment;
+ common_bfd = old_bfd;
+ normal_bfd = abfd;
+ }
+ else
+ {
+ common_align = bfd_log2 (isym->st_value);
+ common_bfd = abfd;
+ normal_bfd = old_bfd;
+ }
+
+ if (normal_align < common_align)
+ {
+ /* PR binutils/2735 */
+ if (normal_bfd == NULL)
+ (*_bfd_error_handler)
+ (_("Warning: alignment %u of common symbol `%s' in %B"
+ " is greater than the alignment (%u) of its section %A"),
+ common_bfd, h->root.u.def.section,
+ 1 << common_align, name, 1 << normal_align);
+ else
+ (*_bfd_error_handler)
+ (_("Warning: alignment %u of symbol `%s' in %B"
+ " is smaller than %u in %B"),
+ normal_bfd, common_bfd,
+ 1 << normal_align, name, 1 << common_align);
+ }
+ }
+
+ /* Remember the symbol size if it isn't undefined. */
+ if ((isym->st_size != 0 && isym->st_shndx != SHN_UNDEF)
+ && (definition || h->size == 0))
+ {
+ if (h->size != 0
+ && h->size != isym->st_size
+ && ! size_change_ok)
+ (*_bfd_error_handler)
+ (_("Warning: size of symbol `%s' changed"
+ " from %lu in %B to %lu in %B"),
+ old_bfd, abfd,
+ name, (unsigned long) h->size,
+ (unsigned long) isym->st_size);
+
+ h->size = isym->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. Allow changed between different
+ function types. */
+ if (h->root.type == bfd_link_hash_common)
+ h->size = h->root.u.c.size;
+
+ if (ELF_ST_TYPE (isym->st_info) != STT_NOTYPE
+ && (definition || h->type == STT_NOTYPE))
+ {
+ unsigned int type = ELF_ST_TYPE (isym->st_info);
+
+ if (h->type != type)
+ {
+ if (h->type != STT_NOTYPE && ! type_change_ok)
+ (*_bfd_error_handler)
+ (_("Warning: type of symbol `%s' changed"
+ " from %d to %d in %B"),
+ abfd, name, h->type, type);
+
+ h->type = type;
+ }
+ }
+
+ /* 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 (! dynamic)
+ {
+ if (! definition)
+ {
+ h->ref_regular = 1;
+ if (bind != STB_WEAK)
+ h->ref_regular_nonweak = 1;
+ }
+ else
+ {
+ BFD_ASSERT (!h->def_dynamic);
+ h->def_regular = 1;
+ }
+ }
+ else
+ {
+ BFD_ASSERT (definition);
+ h->def_dynamic = 1;
+ h->dynindx = -2;
+ ((struct elf64_ia64_link_hash_entry *)h)->shl = abfd;
+ }
+ }
+ }
+
+ if (isymbuf != NULL)
+ {
+ free (isymbuf);
+ isymbuf = 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. */
+ if (! dynamic
+ && is_elf_hash_table (htab)
+ && bed->check_relocs != NULL
+ && (*bed->relocs_compatible) (abfd->xvec, info->output_bfd->xvec))
+ {
+ asection *o;
+
+ for (o = abfd->sections; o != NULL; o = o->next)
+ {
+ Elf_Internal_Rela *internal_relocs;
+ bfd_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 = _bfd_elf_link_read_relocs (abfd, o, NULL, NULL,
+ info->keep_memory);
+ if (internal_relocs == NULL)
+ goto error_return;
+
+ ok = (*bed->check_relocs) (abfd, info, o, internal_relocs);
+
+ if (elf_section_data (o)->relocs != internal_relocs)
+ free (internal_relocs);
+
+ if (! ok)
+ goto error_return;
+ }
+ }
+
+ return TRUE;
+
+ error_free_vers:
+ error_free_sym:
+ if (isymbuf != NULL)
+ free (isymbuf);
+ error_return:
+ return FALSE;
+}
+
+static bfd_boolean
+elf64_vms_link_add_archive_symbols (bfd *abfd, struct bfd_link_info *info)
+{
+ int pass;
+ struct bfd_link_hash_entry **pundef;
+ struct bfd_link_hash_entry **next_pundef;
+
+ /* We only accept VMS libraries. */
+ if (info->output_bfd->xvec != abfd->xvec)
+ {
+ bfd_set_error (bfd_error_wrong_format);
+ return FALSE;
+ }
+
+ /* The archive_pass field in the archive itself is used to
+ initialize PASS, since we may search the same archive multiple
+ times. */
+ pass = ++abfd->archive_pass;
+
+ /* Look through the list of undefined symbols. */
+ for (pundef = &info->hash->undefs; *pundef != NULL; pundef = next_pundef)
+ {
+ struct bfd_link_hash_entry *h;
+ symindex symidx;
+ bfd *element;
+ bfd *orig_element;
+
+ h = *pundef;
+ next_pundef = &(*pundef)->u.undef.next;
+
+ /* 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 = *next_pundef;
+ next_pundef = pundef;
+ }
+ continue;
+ }
+
+ /* Look for this symbol in the archive hash table. */
+ symidx = _bfd_vms_lib_find_symbol (abfd, h->root.string);
+ if (symidx == BFD_NO_MORE_SYMBOLS)
+ {
+ /* Nothing in this slot. */
+ continue;
+ }
+
+ element = bfd_get_elt_at_index (abfd, symidx);
+ if (element == NULL)
+ return FALSE;
+
+ if (element->archive_pass == -1 || element->archive_pass == pass)
+ {
+ /* Next symbol if this archive is wrong or already handled. */
+ continue;
+ }
+
+ orig_element = element;
+ if (bfd_is_thin_archive (abfd))
+ {
+ element = _bfd_vms_lib_get_imagelib_file (element);
+ if (element == NULL || !bfd_check_format (element, bfd_object))
+ {
+ orig_element->archive_pass = -1;
+ return FALSE;
+ }
+ }
+ else if (! bfd_check_format (element, bfd_object))
+ {
+ element->archive_pass = -1;
+ 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,
+ h->root.string, &element))
+ return FALSE;
+ if (! elf64_vms_link_add_object_symbols (element, info))
+ return FALSE;
+
+ orig_element->archive_pass = pass;
+ }
+
+ return TRUE;
+}
+
+static bfd_boolean
+elf64_vms_bfd_link_add_symbols (bfd *abfd, struct bfd_link_info *info)
+{
+ switch (bfd_get_format (abfd))
+ {
+ case bfd_object:
+ return elf64_vms_link_add_object_symbols (abfd, info);
+ break;
+ case bfd_archive:
+ return elf64_vms_link_add_archive_symbols (abfd, info);
+ break;
+ default:
+ bfd_set_error (bfd_error_wrong_format);
+ return FALSE;
+ }
+}
+
+static bfd_boolean
+elf64_ia64_vms_mkobject (bfd *abfd)
+{
+ return bfd_elf_allocate_object
+ (abfd, sizeof (struct elf64_ia64_vms_obj_tdata), IA64_ELF_DATA);
+}
+
+
+/* Size-dependent data and functions. */
+static const struct elf_size_info elf64_ia64_vms_size_info = {
+ sizeof (Elf64_External_VMS_Ehdr),
+ sizeof (Elf64_External_Phdr),
+ sizeof (Elf64_External_Shdr),
+ sizeof (Elf64_External_Rel),
+ sizeof (Elf64_External_Rela),
+ sizeof (Elf64_External_Sym),
+ sizeof (Elf64_External_Dyn),
+ sizeof (Elf_External_Note),
+ 4,
+ 1,
+ 64, 3, /* ARCH_SIZE, LOG_FILE_ALIGN */
+ ELFCLASS64, EV_CURRENT,
+ bfd_elf64_write_out_phdrs,
+ elf64_vms_write_shdrs_and_ehdr,
+ bfd_elf64_checksum_contents,
+ bfd_elf64_write_relocs,
+ bfd_elf64_swap_symbol_in,
+ bfd_elf64_swap_symbol_out,
+ bfd_elf64_slurp_reloc_table,
+ bfd_elf64_slurp_symbol_table,
+ bfd_elf64_swap_dyn_in,
+ bfd_elf64_swap_dyn_out,
+ bfd_elf64_swap_reloc_in,
+ bfd_elf64_swap_reloc_out,
+ bfd_elf64_swap_reloca_in,
+ bfd_elf64_swap_reloca_out
+};
+
+#define ELF_ARCH bfd_arch_ia64
+#define ELF_MACHINE_CODE EM_IA_64
+#define ELF_MAXPAGESIZE 0x10000 /* 64KB */
+#define ELF_COMMONPAGESIZE 0x200 /* 16KB */
+
+#define elf_backend_section_from_shdr \
+ elf64_ia64_section_from_shdr
+#define elf_backend_section_flags \
+ elf64_ia64_section_flags
+#define elf_backend_fake_sections \
+ elf64_ia64_fake_sections
+#define elf_backend_final_write_processing \
+ elf64_ia64_final_write_processing
+#define elf_backend_add_symbol_hook \
+ elf64_ia64_add_symbol_hook
+#define elf_info_to_howto \
+ elf64_ia64_info_to_howto
+
+#define bfd_elf64_bfd_reloc_type_lookup \
+ ia64_elf_reloc_type_lookup
+#define bfd_elf64_bfd_reloc_name_lookup \
+ ia64_elf_reloc_name_lookup
+#define bfd_elf64_bfd_is_local_label_name \
+ elf64_ia64_is_local_label_name
+#define bfd_elf64_bfd_relax_section \
+ elf64_ia64_relax_section
+
+#define elf_backend_object_p \
+ elf64_ia64_object_p
+
+/* Stuff for the BFD linker: */
+#define bfd_elf64_bfd_link_hash_table_create \
+ elf64_ia64_hash_table_create
+#define elf_backend_create_dynamic_sections \
+ elf64_ia64_create_dynamic_sections
+#define elf_backend_check_relocs \
+ elf64_ia64_check_relocs
+#define elf_backend_adjust_dynamic_symbol \
+ elf64_ia64_adjust_dynamic_symbol
+#define elf_backend_size_dynamic_sections \
+ elf64_ia64_size_dynamic_sections
+#define elf_backend_omit_section_dynsym \
+ ((bfd_boolean (*) (bfd *, struct bfd_link_info *, asection *)) bfd_true)
+#define elf_backend_relocate_section \
+ elf64_ia64_relocate_section
+#define elf_backend_finish_dynamic_symbol \
+ elf64_ia64_finish_dynamic_symbol
+#define elf_backend_finish_dynamic_sections \
+ elf64_ia64_finish_dynamic_sections
+#define bfd_elf64_bfd_final_link \
+ elf64_ia64_final_link
+
+#define bfd_elf64_bfd_merge_private_bfd_data \
+ elf64_ia64_merge_private_bfd_data
+#define bfd_elf64_bfd_set_private_flags \
+ elf64_ia64_set_private_flags
+#define bfd_elf64_bfd_print_private_bfd_data \
+ elf64_ia64_print_private_bfd_data
+
+#define elf_backend_plt_readonly 1
+#define elf_backend_want_plt_sym 0
+#define elf_backend_plt_alignment 5
+#define elf_backend_got_header_size 0
+#define elf_backend_want_got_plt 1
+#define elf_backend_may_use_rel_p 1
+#define elf_backend_may_use_rela_p 1
+#define elf_backend_default_use_rela_p 1
+#define elf_backend_want_dynbss 0
+#define elf_backend_hide_symbol elf64_ia64_hash_hide_symbol
+#define elf_backend_fixup_symbol _bfd_elf_link_hash_fixup_symbol
+#define elf_backend_reloc_type_class elf64_ia64_reloc_type_class
+#define elf_backend_rela_normal 1
+#define elf_backend_special_sections elf64_ia64_special_sections
+#define elf_backend_default_execstack 0
+
+/* FIXME: PR 290: The Intel C compiler generates SHT_IA_64_UNWIND with
+ SHF_LINK_ORDER. But it doesn't set the sh_link or sh_info fields.
+ We don't want to flood users with so many error messages. We turn
+ off the warning for now. It will be turned on later when the Intel
+ compiler is fixed. */
+#define elf_backend_link_order_error_handler NULL
+
+/* VMS-specific vectors. */
+
+#undef TARGET_LITTLE_SYM
+#define TARGET_LITTLE_SYM ia64_elf64_vms_vec
+#undef TARGET_LITTLE_NAME
+#define TARGET_LITTLE_NAME "elf64-ia64-vms"
+#undef TARGET_BIG_SYM
+#undef TARGET_BIG_NAME
+
+/* These are VMS specific functions. */
+
+#undef elf_backend_object_p
+#define elf_backend_object_p elf64_vms_object_p
+
+#undef elf_backend_section_from_shdr
+#define elf_backend_section_from_shdr elf64_vms_section_from_shdr
+
+#undef elf_backend_post_process_headers
+#define elf_backend_post_process_headers elf64_vms_post_process_headers
+
+#undef elf_backend_section_processing
+#define elf_backend_section_processing elf64_vms_section_processing
+
+#undef elf_backend_final_write_processing
+#define elf_backend_final_write_processing elf64_vms_final_write_processing
+
+#undef bfd_elf64_close_and_cleanup
+#define bfd_elf64_close_and_cleanup elf64_vms_close_and_cleanup
+
+#undef elf_backend_section_from_bfd_section
+
+#undef elf_backend_symbol_processing
+
+#undef elf_backend_want_p_paddr_set_to_zero
+
+#undef ELF_OSABI
+#define ELF_OSABI ELFOSABI_OPENVMS
+
+#undef ELF_MAXPAGESIZE
+#define ELF_MAXPAGESIZE 0x10000 /* 64KB */
+
+#undef elf64_bed
+#define elf64_bed elf64_ia64_vms_bed
+
+#define elf_backend_size_info elf64_ia64_vms_size_info
+
+/* Use VMS-style archives (in particular, don't use the standard coff
+ archive format). */
+#define bfd_elf64_archive_functions
+
+#undef bfd_elf64_archive_p
+#define bfd_elf64_archive_p _bfd_vms_lib_ia64_archive_p
+#undef bfd_elf64_write_archive_contents
+#define bfd_elf64_write_archive_contents _bfd_vms_lib_write_archive_contents
+#undef bfd_elf64_mkarchive
+#define bfd_elf64_mkarchive _bfd_vms_lib_ia64_mkarchive
+
+#define bfd_elf64_archive_slurp_armap \
+ _bfd_vms_lib_slurp_armap
+#define bfd_elf64_archive_slurp_extended_name_table \
+ _bfd_vms_lib_slurp_extended_name_table
+#define bfd_elf64_archive_construct_extended_name_table \
+ _bfd_vms_lib_construct_extended_name_table
+#define bfd_elf64_archive_truncate_arname \
+ _bfd_vms_lib_truncate_arname
+#define bfd_elf64_archive_write_armap \
+ _bfd_vms_lib_write_armap
+#define bfd_elf64_archive_read_ar_hdr \
+ _bfd_vms_lib_read_ar_hdr
+#define bfd_elf64_archive_write_ar_hdr \
+ _bfd_vms_lib_write_ar_hdr
+#define bfd_elf64_archive_openr_next_archived_file \
+ _bfd_vms_lib_openr_next_archived_file
+#define bfd_elf64_archive_get_elt_at_index \
+ _bfd_vms_lib_get_elt_at_index
+#define bfd_elf64_archive_generic_stat_arch_elt \
+ _bfd_vms_lib_generic_stat_arch_elt
+#define bfd_elf64_archive_update_armap_timestamp \
+ _bfd_vms_lib_update_armap_timestamp
+
+/* VMS link methods. */
+#undef bfd_elf64_bfd_link_add_symbols
+#define bfd_elf64_bfd_link_add_symbols elf64_vms_bfd_link_add_symbols
+
+#undef elf_backend_want_got_sym
+#define elf_backend_want_got_sym 0
+
+#undef bfd_elf64_mkobject
+#define bfd_elf64_mkobject elf64_ia64_vms_mkobject
+
+/* Redefine to align segments on block size. */
+#undef ELF_MAXPAGESIZE
+#define ELF_MAXPAGESIZE 0x200 /* 512B */
+
+#undef elf_backend_want_got_plt
+#define elf_backend_want_got_plt 0
+
+#include "elf64-target.h"
diff --git a/bfd/elf64-mips.c b/bfd/elf64-mips.c
new file mode 100644
index 0000000..2f323c6
--- /dev/null
+++ b/bfd/elf64-mips.c
@@ -0,0 +1,4549 @@
+/* MIPS-specific support for 64-bit ELF
+ Copyright (C) 1996-2014 Free Software Foundation, Inc.
+ Ian Lance Taylor, Cygnus Support
+ Linker support added by Mark Mitchell, CodeSourcery, LLC.
+ <mark@codesourcery.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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, 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. */
+
+/* TODO: Many things are unsupported, even if there is some code for it
+ . (which was mostly stolen from elf32-mips.c and slightly adapted).
+ .
+ . - Relocation handling for REL relocs is wrong in many cases and
+ . generally untested.
+ . - Relocation handling for RELA relocs related to GOT support are
+ . also likely to be wrong.
+ . - Support for MIPS16 is untested.
+ . - Combined relocs with RSS_* entries are unsupported.
+ . - The whole GOT handling for NewABI is missing, some parts of
+ . the OldABI version is still lying around and should be removed.
+ */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+#include "aout/ar.h"
+#include "bfdlink.h"
+#include "genlink.h"
+#include "elf-bfd.h"
+#include "elfxx-mips.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_SIGNED_64
+#include "ecoffswap.h"
+
+static void mips_elf64_swap_reloc_in
+ (bfd *, const Elf64_Mips_External_Rel *, Elf64_Mips_Internal_Rela *);
+static void mips_elf64_swap_reloca_in
+ (bfd *, const Elf64_Mips_External_Rela *, Elf64_Mips_Internal_Rela *);
+static void mips_elf64_swap_reloc_out
+ (bfd *, const Elf64_Mips_Internal_Rela *, Elf64_Mips_External_Rel *);
+static void mips_elf64_swap_reloca_out
+ (bfd *, const Elf64_Mips_Internal_Rela *, Elf64_Mips_External_Rela *);
+static void mips_elf64_be_swap_reloc_in
+ (bfd *, const bfd_byte *, Elf_Internal_Rela *);
+static void mips_elf64_be_swap_reloc_out
+ (bfd *, const Elf_Internal_Rela *, bfd_byte *);
+static void mips_elf64_be_swap_reloca_in
+ (bfd *, const bfd_byte *, Elf_Internal_Rela *);
+static void mips_elf64_be_swap_reloca_out
+ (bfd *, const Elf_Internal_Rela *, bfd_byte *);
+static reloc_howto_type *bfd_elf64_bfd_reloc_type_lookup
+ (bfd *, bfd_reloc_code_real_type);
+static reloc_howto_type *mips_elf64_rtype_to_howto
+ (unsigned int, bfd_boolean);
+static void mips_elf64_info_to_howto_rel
+ (bfd *, arelent *, Elf_Internal_Rela *);
+static void mips_elf64_info_to_howto_rela
+ (bfd *, arelent *, Elf_Internal_Rela *);
+static long mips_elf64_get_reloc_upper_bound
+ (bfd *, asection *);
+static long mips_elf64_canonicalize_reloc
+ (bfd *, asection *, arelent **, asymbol **);
+static long mips_elf64_get_dynamic_reloc_upper_bound
+ (bfd *);
+static long mips_elf64_canonicalize_dynamic_reloc
+ (bfd *, arelent **, asymbol **);
+static bfd_boolean mips_elf64_slurp_one_reloc_table
+ (bfd *, asection *, Elf_Internal_Shdr *, bfd_size_type, arelent *,
+ asymbol **, bfd_boolean);
+static bfd_boolean mips_elf64_slurp_reloc_table
+ (bfd *, asection *, asymbol **, bfd_boolean);
+static void mips_elf64_write_relocs
+ (bfd *, asection *, void *);
+static void mips_elf64_write_rel
+ (bfd *, asection *, Elf_Internal_Shdr *, int *, void *);
+static void mips_elf64_write_rela
+ (bfd *, asection *, Elf_Internal_Shdr *, int *, void *);
+static bfd_reloc_status_type mips_elf64_gprel16_reloc
+ (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
+static bfd_reloc_status_type mips_elf64_literal_reloc
+ (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
+static bfd_reloc_status_type mips_elf64_gprel32_reloc
+ (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
+static bfd_reloc_status_type mips_elf64_shift6_reloc
+ (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
+static bfd_reloc_status_type mips16_gprel_reloc
+ (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
+static bfd_boolean mips_elf64_assign_gp
+ (bfd *, bfd_vma *);
+static bfd_reloc_status_type mips_elf64_final_gp
+ (bfd *, asymbol *, bfd_boolean, char **, bfd_vma *);
+static bfd_boolean mips_elf64_object_p
+ (bfd *);
+static irix_compat_t elf64_mips_irix_compat
+ (bfd *);
+static bfd_boolean elf64_mips_grok_prstatus
+ (bfd *, Elf_Internal_Note *);
+static bfd_boolean elf64_mips_grok_psinfo
+ (bfd *, Elf_Internal_Note *);
+
+extern const bfd_target mips_elf64_be_vec;
+extern const bfd_target mips_elf64_le_vec;
+
+/* 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 number of local .got entries we reserve. */
+#define MIPS_RESERVED_GOTNO (2)
+
+/* 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_mips_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 */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_16", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* 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_dont, /* complain_on_overflow */
+ _bfd_mips_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_dont, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_REL32", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* 26 bit jump 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 36
+ bits must match the PC + 4. */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_26", /* name */
+ TRUE, /* partial_inplace */
+ 0x03ffffff, /* src_mask */
+ 0x03ffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* R_MIPS_HI16 and R_MIPS_LO16 are unsupported for NewABI REL.
+ However, the native IRIX6 tools use them, so we try our best. */
+
+ /* High 16 bits of symbol value. */
+ HOWTO (R_MIPS_HI16, /* type */
+ 16, /* 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 */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* 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 */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* 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 */
+ mips_elf64_gprel16_reloc, /* special_function */
+ "R_MIPS_GPREL16", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* 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 */
+ mips_elf64_literal_reloc, /* special_function */
+ "R_MIPS_LITERAL", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* 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 */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* 16 bit PC relative reference. Note that the ABI document has a typo
+ and claims R_MIPS_PC16 to be not rightshifted, rendering it useless.
+ We do the right thing here. */
+ HOWTO (R_MIPS_PC16, /* 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_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_PC16", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* 16 bit call through global offset table. */
+ 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_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_CALL16", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* 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_dont, /* complain_on_overflow */
+ mips_elf64_gprel32_reloc, /* special_function */
+ "R_MIPS_GPREL32", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ EMPTY_HOWTO (13),
+ EMPTY_HOWTO (14),
+ EMPTY_HOWTO (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_mips_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. */
+ 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 */
+ mips_elf64_shift6_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_dont, /* complain_on_overflow */
+ _bfd_mips_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. */
+ 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_signed, /* complain_on_overflow */
+ _bfd_mips_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. */
+ 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_signed, /* complain_on_overflow */
+ _bfd_mips_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. */
+ 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_signed, /* complain_on_overflow */
+ _bfd_mips_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. */
+ 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_mips_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. */
+ 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_mips_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. */
+ HOWTO (R_MIPS_SUB, /* type */
+ 0, /* rightshift */
+ 4, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ _bfd_mips_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 */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_INSERT_A", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* 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 */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_INSERT_B", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Delete a 32 bit instruction. */
+ /* FIXME: Not handled correctly. */
+ HOWTO (R_MIPS_DELETE, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_DELETE", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* The MIPS ELF64 ABI Draft wants us to support these for REL relocations.
+ We don't, because
+ a) It means building the addend from a R_MIPS_HIGHEST/R_MIPS_HIGHER/
+ R_MIPS_HI16/R_MIPS_LO16 sequence with varying ordering, using
+ fallable heuristics.
+ b) No other NewABI toolchain actually emits such relocations. */
+ EMPTY_HOWTO (R_MIPS_HIGHER),
+ EMPTY_HOWTO (R_MIPS_HIGHEST),
+
+ /* High 16 bits of displacement in global offset table. */
+ 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_mips_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. */
+ 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_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_CALL_LO16", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Section displacement, used by an associated event location section. */
+ HOWTO (R_MIPS_SCN_DISP, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_SCN_DISP", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_MIPS_REL16, /* 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_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_REL16", /* name */
+ TRUE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* These two are obsolete. */
+ EMPTY_HOWTO (R_MIPS_ADD_IMMEDIATE),
+ EMPTY_HOWTO (R_MIPS_PJUMP),
+
+ /* Similiar to R_MIPS_REL32, but used for relocations in a GOT section.
+ It must be used for multigot GOT's (and only there). */
+ HOWTO (R_MIPS_RELGOT, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_RELGOT", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Protected jump conversion. This is an optimization hint. No
+ relocation is required for correctness. */
+ HOWTO (R_MIPS_JALR, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_JALR", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x00000000, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* TLS relocations. */
+ EMPTY_HOWTO (R_MIPS_TLS_DTPMOD32),
+ EMPTY_HOWTO (R_MIPS_TLS_DTPREL32),
+
+ HOWTO (R_MIPS_TLS_DTPMOD64, /* type */
+ 0, /* rightshift */
+ 4, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_TLS_DTPMOD64", /* name */
+ TRUE, /* partial_inplace */
+ MINUS_ONE, /* src_mask */
+ MINUS_ONE, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_MIPS_TLS_DTPREL64, /* type */
+ 0, /* rightshift */
+ 4, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_TLS_DTPREL64", /* name */
+ TRUE, /* partial_inplace */
+ MINUS_ONE, /* src_mask */
+ MINUS_ONE, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* TLS general dynamic variable reference. */
+ HOWTO (R_MIPS_TLS_GD, /* 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_generic_reloc, /* special_function */
+ "R_MIPS_TLS_GD", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* TLS local dynamic variable reference. */
+ HOWTO (R_MIPS_TLS_LDM, /* 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_generic_reloc, /* special_function */
+ "R_MIPS_TLS_LDM", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* TLS local dynamic offset. */
+ HOWTO (R_MIPS_TLS_DTPREL_HI16, /* 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_generic_reloc, /* special_function */
+ "R_MIPS_TLS_DTPREL_HI16", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* TLS local dynamic offset. */
+ HOWTO (R_MIPS_TLS_DTPREL_LO16, /* 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_generic_reloc, /* special_function */
+ "R_MIPS_TLS_DTPREL_LO16", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* TLS thread pointer offset. */
+ HOWTO (R_MIPS_TLS_GOTTPREL, /* 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_generic_reloc, /* special_function */
+ "R_MIPS_TLS_GOTTPREL", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* TLS IE dynamic relocations. */
+ EMPTY_HOWTO (R_MIPS_TLS_TPREL32),
+
+ HOWTO (R_MIPS_TLS_TPREL64, /* type */
+ 0, /* rightshift */
+ 4, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_TLS_TPREL64", /* name */
+ TRUE, /* partial_inplace */
+ MINUS_ONE, /* src_mask */
+ MINUS_ONE, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* TLS thread pointer offset. */
+ HOWTO (R_MIPS_TLS_TPREL_HI16, /* 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_generic_reloc, /* special_function */
+ "R_MIPS_TLS_TPREL_HI16", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* TLS thread pointer offset. */
+ HOWTO (R_MIPS_TLS_TPREL_LO16, /* 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_generic_reloc, /* special_function */
+ "R_MIPS_TLS_TPREL_LO16", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* 32 bit relocation with no addend. */
+ HOWTO (R_MIPS_GLOB_DAT, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_GLOB_DAT", /* name */
+ FALSE, /* partial_inplace */
+ 0x0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ EMPTY_HOWTO (52),
+ EMPTY_HOWTO (53),
+ EMPTY_HOWTO (54),
+ EMPTY_HOWTO (55),
+ EMPTY_HOWTO (56),
+ EMPTY_HOWTO (57),
+ EMPTY_HOWTO (58),
+ EMPTY_HOWTO (59),
+
+ HOWTO (R_MIPS_PC21_S2, /* type */
+ 2, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 21, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_PC21_S2", /* name */
+ TRUE, /* partial_inplace */
+ 0x001fffff, /* src_mask */
+ 0x001fffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_MIPS_PC26_S2, /* 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_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_PC26_S2", /* name */
+ TRUE, /* partial_inplace */
+ 0x03ffffff, /* src_mask */
+ 0x03ffffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_MIPS_PC18_S3, /* 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_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_PC18_S3", /* name */
+ TRUE, /* partial_inplace */
+ 0x0003ffff, /* src_mask */
+ 0x0003ffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_MIPS_PC19_S2, /* type */
+ 2, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 19, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_PC19_S2", /* name */
+ TRUE, /* partial_inplace */
+ 0x0007ffff, /* src_mask */
+ 0x0007ffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_MIPS_PCHI16, /* type */
+ 16, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_PCHI16", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_MIPS_PCLO16, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_PCLO16", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ TRUE), /* 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_mips_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 */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* 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_dont, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_32", /* name */
+ FALSE, /* 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_dont, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_REL32", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* 26 bit jump 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 36
+ bits must match the PC + 4. */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_26", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x03ffffff, /* 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_generic_reloc, /* special_function */
+ "R_MIPS_HI16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* 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_generic_reloc, /* special_function */
+ "R_MIPS_LO16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* 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 */
+ mips_elf64_gprel16_reloc, /* special_function */
+ "R_MIPS_GPREL16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* 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 */
+ mips_elf64_literal_reloc, /* special_function */
+ "R_MIPS_LITERAL", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* 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_generic_reloc, /* special_function */
+ "R_MIPS_GOT16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* 16 bit PC relative reference. Note that the ABI document has a typo
+ and claims R_MIPS_PC16 to be not rightshifted, rendering it useless.
+ We do the right thing here. */
+ HOWTO (R_MIPS_PC16, /* 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_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_PC16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* 16 bit call through global offset table. */
+ 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_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_CALL16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* 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_dont, /* complain_on_overflow */
+ mips_elf64_gprel32_reloc, /* special_function */
+ "R_MIPS_GPREL32", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ EMPTY_HOWTO (13),
+ EMPTY_HOWTO (14),
+ EMPTY_HOWTO (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_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_SHIFT5", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x000007c0, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A 6 bit shift field. */
+ 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 */
+ mips_elf64_shift6_reloc, /* special_function */
+ "R_MIPS_SHIFT6", /* name */
+ FALSE, /* 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_dont, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_64", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ MINUS_ONE, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Displacement in the global offset table. */
+ 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_signed, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_GOT_DISP", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Displacement to page pointer in the global offset table. */
+ 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_signed, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_GOT_PAGE", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Offset from page pointer in the global offset table. */
+ 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_signed, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_GOT_OFST", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* High 16 bits of displacement in global offset table. */
+ 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_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_GOT_HI16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Low 16 bits of displacement in global offset table. */
+ 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_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_GOT_LO16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* 64 bit subtraction. */
+ HOWTO (R_MIPS_SUB, /* type */
+ 0, /* rightshift */
+ 4, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_SUB", /* name */
+ FALSE, /* 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 */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_INSERT_A", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffffffff, /* 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 */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_INSERT_B", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Delete a 32 bit instruction. */
+ /* FIXME: Not handled correctly. */
+ HOWTO (R_MIPS_DELETE, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_DELETE", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Get the higher value of a 64 bit addend. */
+ 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_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_HIGHER", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Get the highest value of a 64 bit addend. */
+ 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_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_HIGHEST", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* High 16 bits of displacement in global offset table. */
+ 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_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_CALL_HI16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Low 16 bits of displacement in global offset table. */
+ 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_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_CALL_LO16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Section displacement, used by an associated event location section. */
+ HOWTO (R_MIPS_SCN_DISP, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_SCN_DISP", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_MIPS_REL16, /* 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_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_REL16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* These two are obsolete. */
+ EMPTY_HOWTO (R_MIPS_ADD_IMMEDIATE),
+ EMPTY_HOWTO (R_MIPS_PJUMP),
+
+ /* Similiar to R_MIPS_REL32, but used for relocations in a GOT section.
+ It must be used for multigot GOT's (and only there). */
+ HOWTO (R_MIPS_RELGOT, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_RELGOT", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Protected jump conversion. This is an optimization hint. No
+ relocation is required for correctness. */
+ HOWTO (R_MIPS_JALR, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_JALR", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x00000000, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* TLS relocations. */
+ EMPTY_HOWTO (R_MIPS_TLS_DTPMOD32),
+ EMPTY_HOWTO (R_MIPS_TLS_DTPREL32),
+
+ HOWTO (R_MIPS_TLS_DTPMOD64, /* type */
+ 0, /* rightshift */
+ 4, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_TLS_DTPMOD64", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ MINUS_ONE, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_MIPS_TLS_DTPREL64, /* type */
+ 0, /* rightshift */
+ 4, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_TLS_DTPREL64", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ MINUS_ONE, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* TLS general dynamic variable reference. */
+ HOWTO (R_MIPS_TLS_GD, /* 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_generic_reloc, /* special_function */
+ "R_MIPS_TLS_GD", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* TLS local dynamic variable reference. */
+ HOWTO (R_MIPS_TLS_LDM, /* 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_generic_reloc, /* special_function */
+ "R_MIPS_TLS_LDM", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* TLS local dynamic offset. */
+ HOWTO (R_MIPS_TLS_DTPREL_HI16, /* 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_generic_reloc, /* special_function */
+ "R_MIPS_TLS_DTPREL_HI16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* TLS local dynamic offset. */
+ HOWTO (R_MIPS_TLS_DTPREL_LO16, /* 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_generic_reloc, /* special_function */
+ "R_MIPS_TLS_DTPREL_LO16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* TLS thread pointer offset. */
+ HOWTO (R_MIPS_TLS_GOTTPREL, /* 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_generic_reloc, /* special_function */
+ "R_MIPS_TLS_GOTTPREL", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* TLS IE dynamic relocations. */
+ EMPTY_HOWTO (R_MIPS_TLS_TPREL32),
+
+ HOWTO (R_MIPS_TLS_TPREL64, /* type */
+ 0, /* rightshift */
+ 4, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_TLS_TPREL64", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ MINUS_ONE, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* TLS thread pointer offset. */
+ HOWTO (R_MIPS_TLS_TPREL_HI16, /* 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_generic_reloc, /* special_function */
+ "R_MIPS_TLS_TPREL_HI16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* TLS thread pointer offset. */
+ HOWTO (R_MIPS_TLS_TPREL_LO16, /* 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_generic_reloc, /* special_function */
+ "R_MIPS_TLS_TPREL_LO16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* 32 bit relocation with no addend. */
+ HOWTO (R_MIPS_GLOB_DAT, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_GLOB_DAT", /* name */
+ FALSE, /* partial_inplace */
+ 0x0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ EMPTY_HOWTO (52),
+ EMPTY_HOWTO (53),
+ EMPTY_HOWTO (54),
+ EMPTY_HOWTO (55),
+ EMPTY_HOWTO (56),
+ EMPTY_HOWTO (57),
+ EMPTY_HOWTO (58),
+ EMPTY_HOWTO (59),
+
+ HOWTO (R_MIPS_PC21_S2, /* type */
+ 2, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 21, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_PC21_S2", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x001fffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_MIPS_PC26_S2, /* 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_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_PC26_S2", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x03ffffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_MIPS_PC18_S3, /* 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_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_PC18_S3", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0003ffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_MIPS_PC19_S2, /* type */
+ 2, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 19, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_PC19_S2", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0007ffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_MIPS_PCHI16, /* type */
+ 16, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_PCHI16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_MIPS_PCLO16, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_PCLO16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+};
+
+static reloc_howto_type mips16_elf64_howto_table_rel[] =
+{
+ /* The reloc used for the mips16 jump instruction. */
+ 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. */
+ _bfd_mips_elf_generic_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. */
+ 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 */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A MIPS16 reference to the global offset table. */
+ HOWTO (R_MIPS16_GOT16, /* 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_got16_reloc, /* special_function */
+ "R_MIPS16_GOT16", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A MIPS16 call through the global offset table. */
+ HOWTO (R_MIPS16_CALL16, /* 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_generic_reloc, /* special_function */
+ "R_MIPS16_CALL16", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* MIPS16 high 16 bits of symbol value. */
+ HOWTO (R_MIPS16_HI16, /* type */
+ 16, /* 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_MIPS16_HI16", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* MIPS16 low 16 bits of symbol value. */
+ HOWTO (R_MIPS16_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_MIPS16_LO16", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* MIPS16 TLS general dynamic variable reference. */
+ HOWTO (R_MIPS16_TLS_GD, /* 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_generic_reloc, /* special_function */
+ "R_MIPS16_TLS_GD", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* MIPS16 TLS local dynamic variable reference. */
+ HOWTO (R_MIPS16_TLS_LDM, /* 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_generic_reloc, /* special_function */
+ "R_MIPS16_TLS_LDM", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* MIPS16 TLS local dynamic offset. */
+ HOWTO (R_MIPS16_TLS_DTPREL_HI16, /* 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_generic_reloc, /* special_function */
+ "R_MIPS16_TLS_DTPREL_HI16", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* MIPS16 TLS local dynamic offset. */
+ HOWTO (R_MIPS16_TLS_DTPREL_LO16, /* 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_generic_reloc, /* special_function */
+ "R_MIPS16_TLS_DTPREL_LO16", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* MIPS16 TLS thread pointer offset. */
+ HOWTO (R_MIPS16_TLS_GOTTPREL, /* 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_generic_reloc, /* special_function */
+ "R_MIPS16_TLS_GOTTPREL", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* MIPS16 TLS thread pointer offset. */
+ HOWTO (R_MIPS16_TLS_TPREL_HI16, /* 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_generic_reloc, /* special_function */
+ "R_MIPS16_TLS_TPREL_HI16", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* MIPS16 TLS thread pointer offset. */
+ HOWTO (R_MIPS16_TLS_TPREL_LO16, /* 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_generic_reloc, /* special_function */
+ "R_MIPS16_TLS_TPREL_LO16", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+};
+
+static reloc_howto_type mips16_elf64_howto_table_rela[] =
+{
+ /* The reloc used for the mips16 jump instruction. */
+ 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. */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS16_26", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x3ffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* The reloc used for the mips16 gprel instruction. */
+ 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 */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A MIPS16 reference to the global offset table. */
+ HOWTO (R_MIPS16_GOT16, /* 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_got16_reloc, /* special_function */
+ "R_MIPS16_GOT16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A MIPS16 call through the global offset table. */
+ HOWTO (R_MIPS16_CALL16, /* 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_generic_reloc, /* special_function */
+ "R_MIPS16_CALL16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* MIPS16 high 16 bits of symbol value. */
+ HOWTO (R_MIPS16_HI16, /* type */
+ 16, /* 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_MIPS16_HI16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* MIPS16 low 16 bits of symbol value. */
+ HOWTO (R_MIPS16_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_MIPS16_LO16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* MIPS16 TLS general dynamic variable reference. */
+ HOWTO (R_MIPS16_TLS_GD, /* 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_generic_reloc, /* special_function */
+ "R_MIPS16_TLS_GD", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* MIPS16 TLS local dynamic variable reference. */
+ HOWTO (R_MIPS16_TLS_LDM, /* 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_generic_reloc, /* special_function */
+ "R_MIPS16_TLS_LDM", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* MIPS16 TLS local dynamic offset. */
+ HOWTO (R_MIPS16_TLS_DTPREL_HI16, /* 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_generic_reloc, /* special_function */
+ "R_MIPS16_TLS_DTPREL_HI16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* MIPS16 TLS local dynamic offset. */
+ HOWTO (R_MIPS16_TLS_DTPREL_LO16, /* 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_generic_reloc, /* special_function */
+ "R_MIPS16_TLS_DTPREL_LO16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* MIPS16 TLS thread pointer offset. */
+ HOWTO (R_MIPS16_TLS_GOTTPREL, /* 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_generic_reloc, /* special_function */
+ "R_MIPS16_TLS_GOTTPREL", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* MIPS16 TLS thread pointer offset. */
+ HOWTO (R_MIPS16_TLS_TPREL_HI16, /* 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_generic_reloc, /* special_function */
+ "R_MIPS16_TLS_TPREL_HI16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* MIPS16 TLS thread pointer offset. */
+ HOWTO (R_MIPS16_TLS_TPREL_LO16, /* 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_generic_reloc, /* special_function */
+ "R_MIPS16_TLS_TPREL_LO16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+};
+
+static reloc_howto_type micromips_elf64_howto_table_rel[] =
+{
+ EMPTY_HOWTO (130),
+ EMPTY_HOWTO (131),
+ EMPTY_HOWTO (132),
+
+ /* 26 bit jump address. */
+ HOWTO (R_MICROMIPS_26_S1, /* type */
+ 1, /* 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_mips_elf_generic_reloc, /* special_function */
+ "R_MICROMIPS_26_S1", /* name */
+ TRUE, /* partial_inplace */
+ 0x3ffffff, /* src_mask */
+ 0x3ffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* High 16 bits of symbol value. */
+ HOWTO (R_MICROMIPS_HI16, /* type */
+ 16, /* 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_MICROMIPS_HI16", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Low 16 bits of symbol value. */
+ HOWTO (R_MICROMIPS_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_MICROMIPS_LO16", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* GP relative reference. */
+ HOWTO (R_MICROMIPS_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_elf32_gprel16_reloc, /* special_function */
+ "R_MICROMIPS_GPREL16", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Reference to literal section. */
+ HOWTO (R_MICROMIPS_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_elf32_gprel16_reloc, /* special_function */
+ "R_MICROMIPS_LITERAL", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Reference to global offset table. */
+ HOWTO (R_MICROMIPS_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_MICROMIPS_GOT16", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* This is for microMIPS branches. */
+ HOWTO (R_MICROMIPS_PC7_S1, /* type */
+ 1, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 7, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MICROMIPS_PC7_S1", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000007f, /* src_mask */
+ 0x0000007f, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_MICROMIPS_PC10_S1, /* type */
+ 1, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 10, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MICROMIPS_PC10_S1", /* name */
+ TRUE, /* partial_inplace */
+ 0x000003ff, /* src_mask */
+ 0x000003ff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_MICROMIPS_PC16_S1, /* type */
+ 1, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MICROMIPS_PC16_S1", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* 16 bit call through global offset table. */
+ HOWTO (R_MICROMIPS_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_mips_elf_generic_reloc, /* special_function */
+ "R_MICROMIPS_CALL16", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ EMPTY_HOWTO (143),
+ EMPTY_HOWTO (144),
+
+ /* Displacement in the global offset table. */
+ HOWTO (R_MICROMIPS_GOT_DISP, /* 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_generic_reloc, /* special_function */
+ "R_MICROMIPS_GOT_DISP",/* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Displacement to page pointer in the global offset table. */
+ HOWTO (R_MICROMIPS_GOT_PAGE, /* 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_generic_reloc, /* special_function */
+ "R_MICROMIPS_GOT_PAGE",/* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Offset from page pointer in the global offset table. */
+ HOWTO (R_MICROMIPS_GOT_OFST, /* 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_generic_reloc, /* special_function */
+ "R_MICROMIPS_GOT_OFST",/* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* High 16 bits of displacement in global offset table. */
+ HOWTO (R_MICROMIPS_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_mips_elf_generic_reloc, /* special_function */
+ "R_MICROMIPS_GOT_HI16",/* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Low 16 bits of displacement in global offset table. */
+ HOWTO (R_MICROMIPS_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_mips_elf_generic_reloc, /* special_function */
+ "R_MICROMIPS_GOT_LO16",/* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* 64 bit subtraction. Used in the N32 ABI. */
+ HOWTO (R_MICROMIPS_SUB, /* type */
+ 0, /* rightshift */
+ 4, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MICROMIPS_SUB", /* name */
+ TRUE, /* partial_inplace */
+ MINUS_ONE, /* src_mask */
+ MINUS_ONE, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* We don't support these for REL relocations, because it means building
+ the addend from a R_MICROMIPS_HIGHEST/R_MICROMIPS_HIGHER/
+ R_MICROMIPS_HI16/R_MICROMIPS_LO16 sequence with varying ordering,
+ using fallable heuristics. */
+ EMPTY_HOWTO (R_MICROMIPS_HIGHER),
+ EMPTY_HOWTO (R_MICROMIPS_HIGHEST),
+
+ /* High 16 bits of displacement in global offset table. */
+ HOWTO (R_MICROMIPS_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_mips_elf_generic_reloc, /* special_function */
+ "R_MICROMIPS_CALL_HI16",/* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Low 16 bits of displacement in global offset table. */
+ HOWTO (R_MICROMIPS_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_mips_elf_generic_reloc, /* special_function */
+ "R_MICROMIPS_CALL_LO16",/* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Section displacement. */
+ HOWTO (R_MICROMIPS_SCN_DISP, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MICROMIPS_SCN_DISP", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Protected jump conversion. This is an optimization hint. No
+ relocation is required for correctness. */
+ HOWTO (R_MICROMIPS_JALR, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MICROMIPS_JALR", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x00000000, /* dst_mask */
+ FALSE), /* pcrel_offset */
+};
+
+static reloc_howto_type micromips_elf64_howto_table_rela[] =
+{
+ EMPTY_HOWTO (130),
+ EMPTY_HOWTO (131),
+ EMPTY_HOWTO (132),
+
+ /* 26 bit jump address. */
+ HOWTO (R_MICROMIPS_26_S1, /* type */
+ 1, /* 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_mips_elf_generic_reloc, /* special_function */
+ "R_MICROMIPS_26_S1", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x3ffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* High 16 bits of symbol value. */
+ HOWTO (R_MICROMIPS_HI16, /* type */
+ 16, /* 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_MICROMIPS_HI16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Low 16 bits of symbol value. */
+ HOWTO (R_MICROMIPS_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_MICROMIPS_LO16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* GP relative reference. */
+ HOWTO (R_MICROMIPS_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_elf32_gprel16_reloc, /* special_function */
+ "R_MICROMIPS_GPREL16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Reference to literal section. */
+ HOWTO (R_MICROMIPS_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_elf32_gprel16_reloc, /* special_function */
+ "R_MICROMIPS_LITERAL", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Reference to global offset table. */
+ HOWTO (R_MICROMIPS_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_MICROMIPS_GOT16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* This is for microMIPS branches. */
+ HOWTO (R_MICROMIPS_PC7_S1, /* type */
+ 1, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 7, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MICROMIPS_PC7_S1", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000007f, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_MICROMIPS_PC10_S1, /* type */
+ 1, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 10, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MICROMIPS_PC10_S1", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x000003ff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_MICROMIPS_PC16_S1, /* type */
+ 1, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MICROMIPS_PC16_S1", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* 16 bit call through global offset table. */
+ HOWTO (R_MICROMIPS_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_mips_elf_generic_reloc, /* special_function */
+ "R_MICROMIPS_CALL16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ EMPTY_HOWTO (143),
+ EMPTY_HOWTO (144),
+
+ /* Displacement in the global offset table. */
+ HOWTO (R_MICROMIPS_GOT_DISP, /* 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_generic_reloc, /* special_function */
+ "R_MICROMIPS_GOT_DISP",/* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Displacement to page pointer in the global offset table. */
+ HOWTO (R_MICROMIPS_GOT_PAGE, /* 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_generic_reloc, /* special_function */
+ "R_MICROMIPS_GOT_PAGE",/* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Offset from page pointer in the global offset table. */
+ HOWTO (R_MICROMIPS_GOT_OFST, /* 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_generic_reloc, /* special_function */
+ "R_MICROMIPS_GOT_OFST",/* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* High 16 bits of displacement in global offset table. */
+ HOWTO (R_MICROMIPS_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_mips_elf_generic_reloc, /* special_function */
+ "R_MICROMIPS_GOT_HI16",/* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Low 16 bits of displacement in global offset table. */
+ HOWTO (R_MICROMIPS_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_mips_elf_generic_reloc, /* special_function */
+ "R_MICROMIPS_GOT_LO16",/* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* 64 bit subtraction. Used in the N32 ABI. */
+ HOWTO (R_MICROMIPS_SUB, /* type */
+ 0, /* rightshift */
+ 4, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MICROMIPS_SUB", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ MINUS_ONE, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Get the higher value of a 64 bit addend. */
+ HOWTO (R_MICROMIPS_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_mips_elf_generic_reloc, /* special_function */
+ "R_MICROMIPS_HIGHER", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Get the highest value of a 64 bit addend. */
+ HOWTO (R_MICROMIPS_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_mips_elf_generic_reloc, /* special_function */
+ "R_MICROMIPS_HIGHEST", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* High 16 bits of displacement in global offset table. */
+ HOWTO (R_MICROMIPS_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_mips_elf_generic_reloc, /* special_function */
+ "R_MICROMIPS_CALL_HI16",/* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Low 16 bits of displacement in global offset table. */
+ HOWTO (R_MICROMIPS_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_mips_elf_generic_reloc, /* special_function */
+ "R_MICROMIPS_CALL_LO16",/* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Section displacement. */
+ HOWTO (R_MICROMIPS_SCN_DISP, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MICROMIPS_SCN_DISP", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Protected jump conversion. This is an optimization hint. No
+ relocation is required for correctness. */
+ HOWTO (R_MICROMIPS_JALR, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MICROMIPS_JALR", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x00000000, /* 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 */
+
+/* 16 bit offset for pc-relative branches. */
+static reloc_howto_type elf_mips_gnu_rel16_s2 =
+ HOWTO (R_MIPS_GNU_REL16_S2, /* 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_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_GNU_REL16_S2", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ TRUE); /* pcrel_offset */
+
+/* 16 bit offset for pc-relative branches. */
+static reloc_howto_type elf_mips_gnu_rela16_s2 =
+ HOWTO (R_MIPS_GNU_REL16_S2, /* 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_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_GNU_REL16_S2", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ TRUE); /* pcrel_offset */
+
+/* 32 bit pc-relative. Used for compact EH tables. */
+static reloc_howto_type elf_mips_gnu_pcrel32 =
+ HOWTO (R_MIPS_PC32, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_PC32", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ TRUE); /* pcrel_offset */
+
+
+/* Originally a VxWorks extension, but now used for other systems too. */
+static reloc_howto_type elf_mips_copy_howto =
+ HOWTO (R_MIPS_COPY, /* type */
+ 0, /* rightshift */
+ 0, /* this one is variable size */
+ 0, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_COPY", /* name */
+ FALSE, /* partial_inplace */
+ 0x0, /* src_mask */
+ 0x0, /* dst_mask */
+ FALSE); /* pcrel_offset */
+
+/* Originally a VxWorks extension, but now used for other systems too. */
+static reloc_howto_type elf_mips_jump_slot_howto =
+ HOWTO (R_MIPS_JUMP_SLOT, /* 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_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_JUMP_SLOT", /* name */
+ FALSE, /* partial_inplace */
+ 0x0, /* src_mask */
+ 0x0, /* dst_mask */
+ FALSE); /* pcrel_offset */
+
+/* Used in EH tables. */
+static reloc_howto_type elf_mips_eh_howto =
+ HOWTO (R_MIPS_EH, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_EH", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE); /* pcrel_offset */
+
+
+/* Swap in a MIPS 64-bit Rel reloc. */
+
+static void
+mips_elf64_swap_reloc_in (bfd *abfd, const Elf64_Mips_External_Rel *src,
+ Elf64_Mips_Internal_Rela *dst)
+{
+ dst->r_offset = H_GET_64 (abfd, src->r_offset);
+ dst->r_sym = H_GET_32 (abfd, src->r_sym);
+ dst->r_ssym = H_GET_8 (abfd, src->r_ssym);
+ dst->r_type3 = H_GET_8 (abfd, src->r_type3);
+ dst->r_type2 = H_GET_8 (abfd, src->r_type2);
+ dst->r_type = H_GET_8 (abfd, src->r_type);
+ dst->r_addend = 0;
+}
+
+/* Swap in a MIPS 64-bit Rela reloc. */
+
+static void
+mips_elf64_swap_reloca_in (bfd *abfd, const Elf64_Mips_External_Rela *src,
+ Elf64_Mips_Internal_Rela *dst)
+{
+ dst->r_offset = H_GET_64 (abfd, src->r_offset);
+ dst->r_sym = H_GET_32 (abfd, src->r_sym);
+ dst->r_ssym = H_GET_8 (abfd, src->r_ssym);
+ dst->r_type3 = H_GET_8 (abfd, src->r_type3);
+ dst->r_type2 = H_GET_8 (abfd, src->r_type2);
+ dst->r_type = H_GET_8 (abfd, src->r_type);
+ dst->r_addend = H_GET_S64 (abfd, src->r_addend);
+}
+
+/* Swap out a MIPS 64-bit Rel reloc. */
+
+static void
+mips_elf64_swap_reloc_out (bfd *abfd, const Elf64_Mips_Internal_Rela *src,
+ Elf64_Mips_External_Rel *dst)
+{
+ H_PUT_64 (abfd, src->r_offset, dst->r_offset);
+ H_PUT_32 (abfd, src->r_sym, dst->r_sym);
+ H_PUT_8 (abfd, src->r_ssym, dst->r_ssym);
+ H_PUT_8 (abfd, src->r_type3, dst->r_type3);
+ H_PUT_8 (abfd, src->r_type2, dst->r_type2);
+ H_PUT_8 (abfd, src->r_type, dst->r_type);
+}
+
+/* Swap out a MIPS 64-bit Rela reloc. */
+
+static void
+mips_elf64_swap_reloca_out (bfd *abfd, const Elf64_Mips_Internal_Rela *src,
+ Elf64_Mips_External_Rela *dst)
+{
+ H_PUT_64 (abfd, src->r_offset, dst->r_offset);
+ H_PUT_32 (abfd, src->r_sym, dst->r_sym);
+ H_PUT_8 (abfd, src->r_ssym, dst->r_ssym);
+ H_PUT_8 (abfd, src->r_type3, dst->r_type3);
+ H_PUT_8 (abfd, src->r_type2, dst->r_type2);
+ H_PUT_8 (abfd, src->r_type, dst->r_type);
+ H_PUT_S64 (abfd, src->r_addend, dst->r_addend);
+}
+
+/* Swap in a MIPS 64-bit Rel reloc. */
+
+static void
+mips_elf64_be_swap_reloc_in (bfd *abfd, const bfd_byte *src,
+ Elf_Internal_Rela *dst)
+{
+ Elf64_Mips_Internal_Rela mirel;
+
+ mips_elf64_swap_reloc_in (abfd,
+ (const Elf64_Mips_External_Rel *) src,
+ &mirel);
+
+ dst[0].r_offset = mirel.r_offset;
+ dst[0].r_info = ELF64_R_INFO (mirel.r_sym, mirel.r_type);
+ dst[0].r_addend = 0;
+ dst[1].r_offset = mirel.r_offset;
+ dst[1].r_info = ELF64_R_INFO (mirel.r_ssym, mirel.r_type2);
+ dst[1].r_addend = 0;
+ dst[2].r_offset = mirel.r_offset;
+ dst[2].r_info = ELF64_R_INFO (STN_UNDEF, mirel.r_type3);
+ dst[2].r_addend = 0;
+}
+
+/* Swap in a MIPS 64-bit Rela reloc. */
+
+static void
+mips_elf64_be_swap_reloca_in (bfd *abfd, const bfd_byte *src,
+ Elf_Internal_Rela *dst)
+{
+ Elf64_Mips_Internal_Rela mirela;
+
+ mips_elf64_swap_reloca_in (abfd,
+ (const Elf64_Mips_External_Rela *) src,
+ &mirela);
+
+ dst[0].r_offset = mirela.r_offset;
+ dst[0].r_info = ELF64_R_INFO (mirela.r_sym, mirela.r_type);
+ dst[0].r_addend = mirela.r_addend;
+ dst[1].r_offset = mirela.r_offset;
+ dst[1].r_info = ELF64_R_INFO (mirela.r_ssym, mirela.r_type2);
+ dst[1].r_addend = 0;
+ dst[2].r_offset = mirela.r_offset;
+ dst[2].r_info = ELF64_R_INFO (STN_UNDEF, mirela.r_type3);
+ dst[2].r_addend = 0;
+}
+
+/* Swap out a MIPS 64-bit Rel reloc. */
+
+static void
+mips_elf64_be_swap_reloc_out (bfd *abfd, const Elf_Internal_Rela *src,
+ bfd_byte *dst)
+{
+ Elf64_Mips_Internal_Rela mirel;
+
+ mirel.r_offset = src[0].r_offset;
+ BFD_ASSERT(src[0].r_offset == src[1].r_offset);
+ BFD_ASSERT(src[0].r_offset == src[2].r_offset);
+
+ mirel.r_type = ELF64_MIPS_R_TYPE (src[0].r_info);
+ mirel.r_sym = ELF64_R_SYM (src[0].r_info);
+ mirel.r_type2 = ELF64_MIPS_R_TYPE (src[1].r_info);
+ mirel.r_ssym = ELF64_MIPS_R_SSYM (src[1].r_info);
+ mirel.r_type3 = ELF64_MIPS_R_TYPE (src[2].r_info);
+
+ mips_elf64_swap_reloc_out (abfd, &mirel,
+ (Elf64_Mips_External_Rel *) dst);
+}
+
+/* Swap out a MIPS 64-bit Rela reloc. */
+
+static void
+mips_elf64_be_swap_reloca_out (bfd *abfd, const Elf_Internal_Rela *src,
+ bfd_byte *dst)
+{
+ Elf64_Mips_Internal_Rela mirela;
+
+ mirela.r_offset = src[0].r_offset;
+ BFD_ASSERT(src[0].r_offset == src[1].r_offset);
+ BFD_ASSERT(src[0].r_offset == src[2].r_offset);
+
+ mirela.r_type = ELF64_MIPS_R_TYPE (src[0].r_info);
+ mirela.r_sym = ELF64_R_SYM (src[0].r_info);
+ mirela.r_addend = src[0].r_addend;
+ BFD_ASSERT(src[1].r_addend == 0);
+ BFD_ASSERT(src[2].r_addend == 0);
+
+ mirela.r_type2 = ELF64_MIPS_R_TYPE (src[1].r_info);
+ mirela.r_ssym = ELF64_MIPS_R_SSYM (src[1].r_info);
+ mirela.r_type3 = ELF64_MIPS_R_TYPE (src[2].r_info);
+
+ mips_elf64_swap_reloca_out (abfd, &mirela,
+ (Elf64_Mips_External_Rela *) dst);
+}
+
+/* Set the GP value for OUTPUT_BFD. Returns FALSE if this is a
+ dangerous relocation. */
+
+static bfd_boolean
+mips_elf64_assign_gp (bfd *output_bfd, bfd_vma *pgp)
+{
+ unsigned int count;
+ asymbol **sym;
+ unsigned int i;
+
+ /* If we've already figured out what GP will be, just return it. */
+ *pgp = _bfd_get_gp_value (output_bfd);
+ if (*pgp)
+ return TRUE;
+
+ count = bfd_get_symcount (output_bfd);
+ sym = bfd_get_outsymbols (output_bfd);
+
+ /* The linker script will have created a symbol named `_gp' with the
+ appropriate value. */
+ if (sym == 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);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/* 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 relocatable output. */
+
+static bfd_reloc_status_type
+mips_elf64_final_gp (bfd *output_bfd, asymbol *symbol, bfd_boolean relocatable,
+ char **error_message, bfd_vma *pgp)
+{
+ if (bfd_is_und_section (symbol->section)
+ && ! relocatable)
+ {
+ *pgp = 0;
+ return bfd_reloc_undefined;
+ }
+
+ *pgp = _bfd_get_gp_value (output_bfd);
+ if (*pgp == 0
+ && (! relocatable
+ || (symbol->flags & BSF_SECTION_SYM) != 0))
+ {
+ if (relocatable)
+ {
+ /* Make up a value. */
+ *pgp = symbol->section->output_section->vma /*+ 0x4000*/;
+ _bfd_set_gp_value (output_bfd, *pgp);
+ }
+ else if (!mips_elf64_assign_gp (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. */
+
+static bfd_reloc_status_type
+mips_elf64_gprel16_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
+ void *data, asection *input_section, bfd *output_bfd,
+ char **error_message)
+{
+ bfd_boolean relocatable;
+ bfd_reloc_status_type ret;
+ bfd_vma gp;
+
+ /* If we're relocating, and this is an external symbol, we don't want
+ to change anything. */
+ if (output_bfd != NULL
+ && (symbol->flags & BSF_SECTION_SYM) == 0
+ && (symbol->flags & BSF_LOCAL) != 0)
+ {
+ reloc_entry->address += input_section->output_offset;
+ return bfd_reloc_ok;
+ }
+
+ if (output_bfd != NULL)
+ relocatable = TRUE;
+ else
+ {
+ relocatable = FALSE;
+ output_bfd = symbol->section->output_section->owner;
+ }
+
+ ret = mips_elf64_final_gp (output_bfd, symbol, relocatable, error_message,
+ &gp);
+ if (ret != bfd_reloc_ok)
+ return ret;
+
+ return _bfd_mips_elf_gprel16_with_gp (abfd, symbol, reloc_entry,
+ input_section, relocatable,
+ data, gp);
+}
+
+/* Do a R_MIPS_LITERAL relocation. */
+
+static bfd_reloc_status_type
+mips_elf64_literal_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
+ void *data, asection *input_section, bfd *output_bfd,
+ char **error_message)
+{
+ bfd_boolean relocatable;
+ bfd_reloc_status_type ret;
+ bfd_vma gp;
+
+ /* R_MIPS_LITERAL relocations are defined for local symbols only. */
+ if (output_bfd != NULL
+ && (symbol->flags & BSF_SECTION_SYM) == 0
+ && (symbol->flags & BSF_LOCAL) != 0)
+ {
+ *error_message = (char *)
+ _("literal relocation occurs for an external symbol");
+ return bfd_reloc_outofrange;
+ }
+
+ /* FIXME: The entries in the .lit8 and .lit4 sections should be merged. */
+ if (output_bfd != NULL)
+ relocatable = TRUE;
+ else
+ {
+ relocatable = FALSE;
+ output_bfd = symbol->section->output_section->owner;
+ }
+
+ ret = mips_elf64_final_gp (output_bfd, symbol, relocatable, error_message,
+ &gp);
+ if (ret != bfd_reloc_ok)
+ return ret;
+
+ return _bfd_mips_elf_gprel16_with_gp (abfd, symbol, reloc_entry,
+ input_section, relocatable,
+ data, gp);
+}
+
+/* Do a R_MIPS_GPREL32 relocation. This is a 32 bit value which must
+ become the offset from the gp register. */
+
+static bfd_reloc_status_type
+mips_elf64_gprel32_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
+ void *data, asection *input_section, bfd *output_bfd,
+ char **error_message)
+{
+ bfd_boolean relocatable;
+ bfd_reloc_status_type ret;
+ bfd_vma gp;
+ bfd_vma relocation;
+ bfd_vma val;
+
+ /* R_MIPS_GPREL32 relocations are defined for local symbols only. */
+ if (output_bfd != NULL
+ && (symbol->flags & BSF_SECTION_SYM) == 0
+ && (symbol->flags & BSF_LOCAL) != 0)
+ {
+ *error_message = (char *)
+ _("32bits gp relative relocation occurs for an external symbol");
+ return bfd_reloc_outofrange;
+ }
+
+ if (output_bfd != NULL)
+ relocatable = TRUE;
+ else
+ {
+ relocatable = FALSE;
+ output_bfd = symbol->section->output_section->owner;
+ }
+
+ ret = mips_elf64_final_gp (output_bfd, symbol, relocatable,
+ error_message, &gp);
+ if (ret != bfd_reloc_ok)
+ return ret;
+
+ 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 > bfd_get_section_limit (abfd, input_section))
+ return bfd_reloc_outofrange;
+
+ /* Set val to the offset into the section or symbol. */
+ val = reloc_entry->addend;
+
+ if (reloc_entry->howto->partial_inplace)
+ val += bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
+
+ /* Adjust val for the final section location and GP value. If we
+ are producing relocatable output, we don't want to do this for
+ an external symbol. */
+ if (! relocatable
+ || (symbol->flags & BSF_SECTION_SYM) != 0)
+ val += relocation - gp;
+
+ if (reloc_entry->howto->partial_inplace)
+ bfd_put_32 (abfd, val, (bfd_byte *) data + reloc_entry->address);
+ else
+ reloc_entry->addend = val;
+
+ if (relocatable)
+ reloc_entry->address += input_section->output_offset;
+
+ return bfd_reloc_ok;
+}
+
+/* Do a R_MIPS_SHIFT6 relocation. The MSB of the shift is stored at bit 2,
+ the rest is at bits 6-10. The bitpos already got right by the howto. */
+
+static bfd_reloc_status_type
+mips_elf64_shift6_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
+ void *data, asection *input_section, bfd *output_bfd,
+ char **error_message)
+{
+ if (reloc_entry->howto->partial_inplace)
+ {
+ reloc_entry->addend = ((reloc_entry->addend & 0x00007c0)
+ | (reloc_entry->addend & 0x00000800) >> 9);
+ }
+
+ return _bfd_mips_elf_generic_reloc (abfd, reloc_entry, symbol, data,
+ input_section, output_bfd,
+ error_message);
+}
+
+/* Handle a mips16 GP relative reloc. */
+
+static bfd_reloc_status_type
+mips16_gprel_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
+ void *data, asection *input_section, bfd *output_bfd,
+ char **error_message)
+{
+ bfd_boolean relocatable;
+ bfd_reloc_status_type ret;
+ bfd_byte *location;
+ bfd_vma gp;
+
+ /* If we're relocating, and this is an external symbol, we don't want
+ to change anything. */
+ if (output_bfd != NULL
+ && (symbol->flags & BSF_SECTION_SYM) == 0
+ && (symbol->flags & BSF_LOCAL) != 0)
+ {
+ reloc_entry->address += input_section->output_offset;
+ return bfd_reloc_ok;
+ }
+
+ if (output_bfd != NULL)
+ relocatable = TRUE;
+ else
+ {
+ relocatable = FALSE;
+ output_bfd = symbol->section->output_section->owner;
+ }
+
+ ret = mips_elf64_final_gp (output_bfd, symbol, relocatable, error_message,
+ &gp);
+ if (ret != bfd_reloc_ok)
+ return ret;
+
+ location = (bfd_byte *) data + reloc_entry->address;
+ _bfd_mips_elf_reloc_unshuffle (abfd, reloc_entry->howto->type, FALSE,
+ location);
+ ret = _bfd_mips_elf_gprel16_with_gp (abfd, symbol, reloc_entry,
+ input_section, relocatable,
+ data, gp);
+ _bfd_mips_elf_reloc_shuffle (abfd, reloc_entry->howto->type, !relocatable,
+ location);
+
+ return ret;
+}
+
+/* A mapping from BFD reloc types to MIPS ELF reloc types. */
+
+struct elf_reloc_map {
+ bfd_reloc_code_real_type bfd_val;
+ enum elf_mips_reloc_type elf_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 },
+ /* There is no BFD reloc for R_MIPS_REL32. */
+ { BFD_RELOC_64, R_MIPS_64 },
+ { BFD_RELOC_CTOR, R_MIPS_64 },
+ { BFD_RELOC_16_PCREL_S2, R_MIPS_PC16 },
+ { BFD_RELOC_HI16_S, R_MIPS_HI16 },
+ { BFD_RELOC_LO16, R_MIPS_LO16 },
+ { BFD_RELOC_GPREL16, R_MIPS_GPREL16 },
+ { BFD_RELOC_GPREL32, R_MIPS_GPREL32 },
+ { BFD_RELOC_MIPS_JMP, R_MIPS_26 },
+ { BFD_RELOC_MIPS_LITERAL, R_MIPS_LITERAL },
+ { BFD_RELOC_MIPS_GOT16, R_MIPS_GOT16 },
+ { BFD_RELOC_MIPS_CALL16, R_MIPS_CALL16 },
+ { BFD_RELOC_MIPS_SHIFT5, R_MIPS_SHIFT5 },
+ { BFD_RELOC_MIPS_SHIFT6, R_MIPS_SHIFT6 },
+ { BFD_RELOC_MIPS_GOT_DISP, R_MIPS_GOT_DISP },
+ { BFD_RELOC_MIPS_GOT_PAGE, R_MIPS_GOT_PAGE },
+ { BFD_RELOC_MIPS_GOT_OFST, R_MIPS_GOT_OFST },
+ { BFD_RELOC_MIPS_GOT_HI16, R_MIPS_GOT_HI16 },
+ { BFD_RELOC_MIPS_GOT_LO16, R_MIPS_GOT_LO16 },
+ { BFD_RELOC_MIPS_SUB, R_MIPS_SUB },
+ { BFD_RELOC_MIPS_INSERT_A, R_MIPS_INSERT_A },
+ { BFD_RELOC_MIPS_INSERT_B, R_MIPS_INSERT_B },
+ { BFD_RELOC_MIPS_DELETE, R_MIPS_DELETE },
+ { BFD_RELOC_MIPS_HIGHEST, R_MIPS_HIGHEST },
+ { BFD_RELOC_MIPS_HIGHER, R_MIPS_HIGHER },
+ { BFD_RELOC_MIPS_CALL_HI16, R_MIPS_CALL_HI16 },
+ { BFD_RELOC_MIPS_CALL_LO16, R_MIPS_CALL_LO16 },
+ { BFD_RELOC_MIPS_SCN_DISP, R_MIPS_SCN_DISP },
+ { BFD_RELOC_MIPS_REL16, R_MIPS_REL16 },
+ /* Use of R_MIPS_ADD_IMMEDIATE and R_MIPS_PJUMP is deprecated. */
+ { BFD_RELOC_MIPS_RELGOT, R_MIPS_RELGOT },
+ { BFD_RELOC_MIPS_JALR, R_MIPS_JALR },
+ { BFD_RELOC_MIPS_TLS_DTPMOD32, R_MIPS_TLS_DTPMOD32 },
+ { BFD_RELOC_MIPS_TLS_DTPREL32, R_MIPS_TLS_DTPREL32 },
+ { BFD_RELOC_MIPS_TLS_DTPMOD64, R_MIPS_TLS_DTPMOD64 },
+ { BFD_RELOC_MIPS_TLS_DTPREL64, R_MIPS_TLS_DTPREL64 },
+ { BFD_RELOC_MIPS_TLS_GD, R_MIPS_TLS_GD },
+ { BFD_RELOC_MIPS_TLS_LDM, R_MIPS_TLS_LDM },
+ { BFD_RELOC_MIPS_TLS_DTPREL_HI16, R_MIPS_TLS_DTPREL_HI16 },
+ { BFD_RELOC_MIPS_TLS_DTPREL_LO16, R_MIPS_TLS_DTPREL_LO16 },
+ { BFD_RELOC_MIPS_TLS_GOTTPREL, R_MIPS_TLS_GOTTPREL },
+ { BFD_RELOC_MIPS_TLS_TPREL32, R_MIPS_TLS_TPREL32 },
+ { BFD_RELOC_MIPS_TLS_TPREL64, R_MIPS_TLS_TPREL64 },
+ { BFD_RELOC_MIPS_TLS_TPREL_HI16, R_MIPS_TLS_TPREL_HI16 },
+ { BFD_RELOC_MIPS_TLS_TPREL_LO16, R_MIPS_TLS_TPREL_LO16 },
+ { BFD_RELOC_MIPS_21_PCREL_S2, R_MIPS_PC21_S2 },
+ { BFD_RELOC_MIPS_26_PCREL_S2, R_MIPS_PC26_S2 },
+ { BFD_RELOC_MIPS_18_PCREL_S3, R_MIPS_PC18_S3 },
+ { BFD_RELOC_MIPS_19_PCREL_S2, R_MIPS_PC19_S2 },
+ { BFD_RELOC_HI16_S_PCREL, R_MIPS_PCHI16 },
+ { BFD_RELOC_LO16_PCREL, R_MIPS_PCLO16 }
+};
+
+static const struct elf_reloc_map mips16_reloc_map[] =
+{
+ { BFD_RELOC_MIPS16_JMP, R_MIPS16_26 - R_MIPS16_min },
+ { BFD_RELOC_MIPS16_GPREL, R_MIPS16_GPREL - R_MIPS16_min },
+ { BFD_RELOC_MIPS16_GOT16, R_MIPS16_GOT16 - R_MIPS16_min },
+ { BFD_RELOC_MIPS16_CALL16, R_MIPS16_CALL16 - R_MIPS16_min },
+ { BFD_RELOC_MIPS16_HI16_S, R_MIPS16_HI16 - R_MIPS16_min },
+ { BFD_RELOC_MIPS16_LO16, R_MIPS16_LO16 - R_MIPS16_min },
+ { BFD_RELOC_MIPS16_TLS_GD, R_MIPS16_TLS_GD - R_MIPS16_min },
+ { BFD_RELOC_MIPS16_TLS_LDM, R_MIPS16_TLS_LDM - R_MIPS16_min },
+ { BFD_RELOC_MIPS16_TLS_DTPREL_HI16,
+ R_MIPS16_TLS_DTPREL_HI16 - R_MIPS16_min },
+ { BFD_RELOC_MIPS16_TLS_DTPREL_LO16,
+ R_MIPS16_TLS_DTPREL_LO16 - R_MIPS16_min },
+ { BFD_RELOC_MIPS16_TLS_GOTTPREL, R_MIPS16_TLS_GOTTPREL - R_MIPS16_min },
+ { BFD_RELOC_MIPS16_TLS_TPREL_HI16, R_MIPS16_TLS_TPREL_HI16 - R_MIPS16_min },
+ { BFD_RELOC_MIPS16_TLS_TPREL_LO16, R_MIPS16_TLS_TPREL_LO16 - R_MIPS16_min }
+};
+
+static const struct elf_reloc_map micromips_reloc_map[] =
+{
+ { BFD_RELOC_MICROMIPS_JMP, R_MICROMIPS_26_S1 - R_MICROMIPS_min },
+ { BFD_RELOC_MICROMIPS_HI16_S, R_MICROMIPS_HI16 - R_MICROMIPS_min },
+ { BFD_RELOC_MICROMIPS_LO16, R_MICROMIPS_LO16 - R_MICROMIPS_min },
+ { BFD_RELOC_MICROMIPS_GPREL16, R_MICROMIPS_GPREL16 - R_MICROMIPS_min },
+ { BFD_RELOC_MICROMIPS_LITERAL, R_MICROMIPS_LITERAL - R_MICROMIPS_min },
+ { BFD_RELOC_MICROMIPS_GOT16, R_MICROMIPS_GOT16 - R_MICROMIPS_min },
+ { BFD_RELOC_MICROMIPS_7_PCREL_S1, R_MICROMIPS_PC7_S1 - R_MICROMIPS_min },
+ { BFD_RELOC_MICROMIPS_10_PCREL_S1, R_MICROMIPS_PC10_S1 - R_MICROMIPS_min },
+ { BFD_RELOC_MICROMIPS_16_PCREL_S1, R_MICROMIPS_PC16_S1 - R_MICROMIPS_min },
+ { BFD_RELOC_MICROMIPS_CALL16, R_MICROMIPS_CALL16 - R_MICROMIPS_min },
+ { BFD_RELOC_MICROMIPS_GOT_DISP, R_MICROMIPS_GOT_DISP - R_MICROMIPS_min },
+ { BFD_RELOC_MICROMIPS_GOT_PAGE, R_MICROMIPS_GOT_PAGE - R_MICROMIPS_min },
+ { BFD_RELOC_MICROMIPS_GOT_OFST, R_MICROMIPS_GOT_OFST - R_MICROMIPS_min },
+ { BFD_RELOC_MICROMIPS_GOT_HI16, R_MICROMIPS_GOT_HI16 - R_MICROMIPS_min },
+ { BFD_RELOC_MICROMIPS_GOT_LO16, R_MICROMIPS_GOT_LO16 - R_MICROMIPS_min },
+ { BFD_RELOC_MICROMIPS_SUB, R_MICROMIPS_SUB - R_MICROMIPS_min },
+ { BFD_RELOC_MICROMIPS_HIGHER, R_MICROMIPS_HIGHER - R_MICROMIPS_min },
+ { BFD_RELOC_MICROMIPS_HIGHEST, R_MICROMIPS_HIGHEST - R_MICROMIPS_min },
+ { BFD_RELOC_MICROMIPS_CALL_HI16, R_MICROMIPS_CALL_HI16 - R_MICROMIPS_min },
+ { BFD_RELOC_MICROMIPS_CALL_LO16, R_MICROMIPS_CALL_LO16 - R_MICROMIPS_min },
+ { BFD_RELOC_MICROMIPS_SCN_DISP, R_MICROMIPS_SCN_DISP - R_MICROMIPS_min },
+ { BFD_RELOC_MICROMIPS_JALR, R_MICROMIPS_JALR - R_MICROMIPS_min },
+};
+/* Given a BFD reloc type, return a howto structure. */
+
+static reloc_howto_type *
+bfd_elf64_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ bfd_reloc_code_real_type code)
+{
+ unsigned int i;
+ /* FIXME: We default to RELA here instead of choosing the right
+ relocation variant. */
+ reloc_howto_type *howto_table = mips_elf64_howto_table_rela;
+ reloc_howto_type *howto16_table = mips16_elf64_howto_table_rela;
+ reloc_howto_type *howto_micromips_table = micromips_elf64_howto_table_rela;
+
+ for (i = 0; i < sizeof (mips_reloc_map) / sizeof (struct elf_reloc_map);
+ i++)
+ {
+ if (mips_reloc_map[i].bfd_val == code)
+ return &howto_table[(int) mips_reloc_map[i].elf_val];
+ }
+
+ for (i = 0; i < sizeof (mips16_reloc_map) / sizeof (struct elf_reloc_map);
+ i++)
+ {
+ if (mips16_reloc_map[i].bfd_val == code)
+ return &howto16_table[(int) mips16_reloc_map[i].elf_val];
+ }
+
+ for (i = 0; i < sizeof (micromips_reloc_map) / sizeof (struct elf_reloc_map);
+ i++)
+ {
+ if (micromips_reloc_map[i].bfd_val == code)
+ return &howto_micromips_table[(int) micromips_reloc_map[i].elf_val];
+ }
+
+ switch (code)
+ {
+ case BFD_RELOC_VTABLE_INHERIT:
+ return &elf_mips_gnu_vtinherit_howto;
+ case BFD_RELOC_VTABLE_ENTRY:
+ return &elf_mips_gnu_vtentry_howto;
+ case BFD_RELOC_32_PCREL:
+ return &elf_mips_gnu_pcrel32;
+ case BFD_RELOC_MIPS_EH:
+ return &elf_mips_eh_howto;
+ case BFD_RELOC_MIPS_COPY:
+ return &elf_mips_copy_howto;
+ case BFD_RELOC_MIPS_JUMP_SLOT:
+ return &elf_mips_jump_slot_howto;
+ default:
+ bfd_set_error (bfd_error_bad_value);
+ return NULL;
+ }
+}
+
+static reloc_howto_type *
+bfd_elf64_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ const char *r_name)
+{
+ unsigned int i;
+
+ for (i = 0;
+ i < (sizeof (mips_elf64_howto_table_rela)
+ / sizeof (mips_elf64_howto_table_rela[0])); i++)
+ if (mips_elf64_howto_table_rela[i].name != NULL
+ && strcasecmp (mips_elf64_howto_table_rela[i].name, r_name) == 0)
+ return &mips_elf64_howto_table_rela[i];
+
+ for (i = 0;
+ i < (sizeof (mips16_elf64_howto_table_rela)
+ / sizeof (mips16_elf64_howto_table_rela[0]));
+ i++)
+ if (mips16_elf64_howto_table_rela[i].name != NULL
+ && strcasecmp (mips16_elf64_howto_table_rela[i].name, r_name) == 0)
+ return &mips16_elf64_howto_table_rela[i];
+
+ for (i = 0;
+ i < (sizeof (micromips_elf64_howto_table_rela)
+ / sizeof (micromips_elf64_howto_table_rela[0]));
+ i++)
+ if (micromips_elf64_howto_table_rela[i].name != NULL
+ && strcasecmp (micromips_elf64_howto_table_rela[i].name, r_name) == 0)
+ return &micromips_elf64_howto_table_rela[i];
+
+ if (strcasecmp (elf_mips_gnu_vtinherit_howto.name, r_name) == 0)
+ return &elf_mips_gnu_vtinherit_howto;
+ if (strcasecmp (elf_mips_gnu_vtentry_howto.name, r_name) == 0)
+ return &elf_mips_gnu_vtentry_howto;
+ if (strcasecmp (elf_mips_gnu_rel16_s2.name, r_name) == 0)
+ return &elf_mips_gnu_rel16_s2;
+ if (strcasecmp (elf_mips_gnu_rela16_s2.name, r_name) == 0)
+ return &elf_mips_gnu_rela16_s2;
+ if (strcasecmp (elf_mips_gnu_pcrel32.name, r_name) == 0)
+ return &elf_mips_gnu_pcrel32;
+ if (strcasecmp (elf_mips_eh_howto.name, r_name) == 0)
+ return &elf_mips_eh_howto;
+ if (strcasecmp (elf_mips_copy_howto.name, r_name) == 0)
+ return &elf_mips_copy_howto;
+ if (strcasecmp (elf_mips_jump_slot_howto.name, r_name) == 0)
+ return &elf_mips_jump_slot_howto;
+
+ return NULL;
+}
+
+/* Given a MIPS Elf_Internal_Rel, fill in an arelent structure. */
+
+static reloc_howto_type *
+mips_elf64_rtype_to_howto (unsigned int r_type, bfd_boolean rela_p)
+{
+ switch (r_type)
+ {
+ case R_MIPS_GNU_VTINHERIT:
+ return &elf_mips_gnu_vtinherit_howto;
+ case R_MIPS_GNU_VTENTRY:
+ return &elf_mips_gnu_vtentry_howto;
+ case R_MIPS_GNU_REL16_S2:
+ if (rela_p)
+ return &elf_mips_gnu_rela16_s2;
+ else
+ return &elf_mips_gnu_rel16_s2;
+ case R_MIPS_PC32:
+ return &elf_mips_gnu_pcrel32;
+ case R_MIPS_EH:
+ return &elf_mips_eh_howto;
+ case R_MIPS_COPY:
+ return &elf_mips_copy_howto;
+ case R_MIPS_JUMP_SLOT:
+ return &elf_mips_jump_slot_howto;
+ default:
+ if (r_type >= R_MICROMIPS_min && r_type < R_MICROMIPS_max)
+ {
+ if (rela_p)
+ return &micromips_elf64_howto_table_rela[r_type - R_MICROMIPS_min];
+ else
+ return &micromips_elf64_howto_table_rel[r_type - R_MICROMIPS_min];
+ }
+ if (r_type >= R_MIPS16_min && r_type < R_MIPS16_max)
+ {
+ if (rela_p)
+ return &mips16_elf64_howto_table_rela[r_type - R_MIPS16_min];
+ else
+ return &mips16_elf64_howto_table_rel[r_type - R_MIPS16_min];
+ }
+ BFD_ASSERT (r_type < (unsigned int) R_MIPS_max);
+ if (rela_p)
+ return &mips_elf64_howto_table_rela[r_type];
+ else
+ return &mips_elf64_howto_table_rel[r_type];
+ break;
+ }
+}
+
+/* Prevent relocation handling by bfd for MIPS ELF64. */
+
+static void
+mips_elf64_info_to_howto_rel (bfd *abfd ATTRIBUTE_UNUSED,
+ arelent *cache_ptr ATTRIBUTE_UNUSED,
+ Elf_Internal_Rela *dst ATTRIBUTE_UNUSED)
+{
+ BFD_ASSERT (0);
+}
+
+static void
+mips_elf64_info_to_howto_rela (bfd *abfd ATTRIBUTE_UNUSED,
+ arelent *cache_ptr ATTRIBUTE_UNUSED,
+ Elf_Internal_Rela *dst ATTRIBUTE_UNUSED)
+{
+ BFD_ASSERT (0);
+}
+
+/* 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 (bfd *abfd ATTRIBUTE_UNUSED, asection *sec)
+{
+ return (sec->reloc_count * 3 + 1) * sizeof (arelent *);
+}
+
+static long
+mips_elf64_get_dynamic_reloc_upper_bound (bfd *abfd)
+{
+ return _bfd_elf_get_dynamic_reloc_upper_bound (abfd) * 3;
+}
+
+/* We must also copy more relocations than the corresponding functions
+ in elf.c would, so the two following functions are slightly
+ modified from elf.c, that multiply the external relocation count by
+ 3 to obtain the internal relocation count. */
+
+static long
+mips_elf64_canonicalize_reloc (bfd *abfd, sec_ptr section,
+ arelent **relptr, asymbol **symbols)
+{
+ arelent *tblptr;
+ unsigned int i;
+ const struct elf_backend_data *bed = get_elf_backend_data (abfd);
+
+ if (! bed->s->slurp_reloc_table (abfd, section, symbols, FALSE))
+ return -1;
+
+ tblptr = section->relocation;
+ for (i = 0; i < section->reloc_count * 3; i++)
+ *relptr++ = tblptr++;
+
+ *relptr = NULL;
+
+ return section->reloc_count * 3;
+}
+
+static long
+mips_elf64_canonicalize_dynamic_reloc (bfd *abfd, arelent **storage,
+ asymbol **syms)
+{
+ bfd_boolean (*slurp_relocs) (bfd *, asection *, asymbol **, bfd_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->size / elf_section_data (s)->this_hdr.sh_entsize * 3;
+ p = s->relocation;
+ for (i = 0; i < count; i++)
+ *storage++ = p++;
+ ret += count;
+ }
+ }
+
+ *storage = NULL;
+
+ return ret;
+}
+
+/* Read the relocations from one reloc section. This is mostly copied
+ from elfcode.h, except for the changes to expand one external
+ relocation to 3 internal ones. We must unfortunately set
+ reloc_count to the number of external relocations, because a lot of
+ generic code seems to depend on this. */
+
+static bfd_boolean
+mips_elf64_slurp_one_reloc_table (bfd *abfd, asection *asect,
+ Elf_Internal_Shdr *rel_hdr,
+ bfd_size_type reloc_count,
+ arelent *relents, asymbol **symbols,
+ bfd_boolean dynamic)
+{
+ void *allocated;
+ bfd_byte *native_relocs;
+ arelent *relent;
+ bfd_vma i;
+ int entsize;
+ bfd_boolean rela_p;
+
+ allocated = bfd_malloc (rel_hdr->sh_size);
+ if (allocated == NULL)
+ return FALSE;
+
+ if (bfd_seek (abfd, rel_hdr->sh_offset, SEEK_SET) != 0
+ || (bfd_bread (allocated, rel_hdr->sh_size, abfd)
+ != rel_hdr->sh_size))
+ goto error_return;
+
+ native_relocs = allocated;
+
+ entsize = rel_hdr->sh_entsize;
+ BFD_ASSERT (entsize == sizeof (Elf64_Mips_External_Rel)
+ || entsize == sizeof (Elf64_Mips_External_Rela));
+
+ if (entsize == sizeof (Elf64_Mips_External_Rel))
+ rela_p = FALSE;
+ else
+ rela_p = TRUE;
+
+ for (i = 0, relent = relents;
+ i < reloc_count;
+ i++, native_relocs += entsize)
+ {
+ Elf64_Mips_Internal_Rela rela;
+ bfd_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
+ mips_elf64_swap_reloc_in (abfd,
+ (Elf64_Mips_External_Rel *) native_relocs,
+ &rela);
+
+ /* Each entry represents exactly 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;
+ }
+
+ /* 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 == STN_UNDEF)
+ 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 || dynamic)
+ relent->address = rela.r_offset;
+ else
+ relent->address = rela.r_offset - asect->vma;
+
+ relent->addend = rela.r_addend;
+
+ relent->howto = mips_elf64_rtype_to_howto (type, rela_p);
+
+ ++relent;
+ }
+ }
+
+ asect->reloc_count += (relent - relents) / 3;
+
+ 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. This is copied from
+ elfcode.h as well, with changes as small as accounting for 3
+ internal relocs per external reloc and resetting reloc_count to
+ zero before processing the relocs of a section. */
+
+static bfd_boolean
+mips_elf64_slurp_reloc_table (bfd *abfd, asection *asect,
+ asymbol **symbols, bfd_boolean dynamic)
+{
+ struct bfd_elf_section_data * const d = elf_section_data (asect);
+ Elf_Internal_Shdr *rel_hdr;
+ Elf_Internal_Shdr *rel_hdr2;
+ bfd_size_type reloc_count;
+ bfd_size_type reloc_count2;
+ arelent *relents;
+ bfd_size_type amt;
+
+ 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 = rel_hdr ? NUM_SHDR_ENTRIES (rel_hdr) : 0;
+ rel_hdr2 = d->rela.hdr;
+ reloc_count2 = (rel_hdr2 ? NUM_SHDR_ENTRIES (rel_hdr2) : 0);
+
+ BFD_ASSERT (asect->reloc_count == reloc_count + reloc_count2);
+ BFD_ASSERT ((rel_hdr && asect->rel_filepos == rel_hdr->sh_offset)
+ || (rel_hdr2 && asect->rel_filepos == rel_hdr2->sh_offset));
+
+ }
+ else
+ {
+ /* Note that ASECT->RELOC_COUNT tends not to be accurate in this
+ case because relocations against this section may use the
+ dynamic symbol table, and in that case bfd_section_from_shdr
+ in elf.c does not update the RELOC_COUNT. */
+ if (asect->size == 0)
+ return TRUE;
+
+ rel_hdr = &d->this_hdr;
+ reloc_count = NUM_SHDR_ENTRIES (rel_hdr);
+ rel_hdr2 = NULL;
+ reloc_count2 = 0;
+ }
+
+ /* Allocate space for 3 arelent structures for each Rel structure. */
+ amt = (reloc_count + reloc_count2) * 3 * sizeof (arelent);
+ relents = bfd_alloc (abfd, amt);
+ if (relents == NULL)
+ return FALSE;
+
+ /* The slurp_one_reloc_table routine increments reloc_count. */
+ asect->reloc_count = 0;
+
+ if (rel_hdr != NULL
+ && ! mips_elf64_slurp_one_reloc_table (abfd, asect,
+ rel_hdr, reloc_count,
+ relents,
+ symbols, dynamic))
+ return FALSE;
+ if (rel_hdr2 != NULL
+ && ! mips_elf64_slurp_one_reloc_table (abfd, asect,
+ rel_hdr2, reloc_count2,
+ relents + reloc_count * 3,
+ symbols, dynamic))
+ return FALSE;
+
+ asect->relocation = relents;
+ return TRUE;
+}
+
+/* Write out the relocations. */
+
+static void
+mips_elf64_write_relocs (bfd *abfd, asection *sec, void *data)
+{
+ bfd_boolean *failedp = data;
+ int count;
+ Elf_Internal_Shdr *rel_hdr;
+ unsigned int idx;
+
+ /* 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;
+ }
+ }
+
+ rel_hdr = _bfd_elf_single_rel_hdr (sec);
+
+ /* Do the actual relocation. */
+
+ if (rel_hdr->sh_entsize == sizeof(Elf64_Mips_External_Rel))
+ mips_elf64_write_rel (abfd, sec, rel_hdr, &count, data);
+ else if (rel_hdr->sh_entsize == sizeof(Elf64_Mips_External_Rela))
+ mips_elf64_write_rela (abfd, sec, rel_hdr, &count, data);
+ else
+ BFD_ASSERT (0);
+}
+
+static void
+mips_elf64_write_rel (bfd *abfd, asection *sec,
+ Elf_Internal_Shdr *rel_hdr,
+ int *count, void *data)
+{
+ bfd_boolean *failedp = data;
+ Elf64_Mips_External_Rel *ext_rel;
+ unsigned int idx;
+ asymbol *last_sym = 0;
+ int last_sym_idx = 0;
+
+ rel_hdr->sh_size = rel_hdr->sh_entsize * *count;
+ rel_hdr->contents = bfd_alloc (abfd, rel_hdr->sh_size);
+ if (rel_hdr->contents == NULL)
+ {
+ *failedp = TRUE;
+ return;
+ }
+
+ ext_rel = (Elf64_Mips_External_Rel *) rel_hdr->contents;
+ for (idx = 0; idx < sec->reloc_count; idx++, ext_rel++)
+ {
+ arelent *ptr;
+ Elf64_Mips_Internal_Rela int_rel;
+ 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_rel.r_offset = ptr->address;
+ else
+ int_rel.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;
+ }
+
+ int_rel.r_sym = n;
+ int_rel.r_ssym = RSS_UNDEF;
+
+ if ((*ptr->sym_ptr_ptr)->the_bfd->xvec != abfd->xvec
+ && ! _bfd_elf_validate_reloc (abfd, ptr))
+ {
+ *failedp = TRUE;
+ return;
+ }
+
+ int_rel.r_type = ptr->howto->type;
+ int_rel.r_type2 = (int) R_MIPS_NONE;
+ int_rel.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_rel.r_type2 = r->howto->type;
+ else
+ int_rel.r_type3 = r->howto->type;
+
+ ++idx;
+ }
+
+ mips_elf64_swap_reloc_out (abfd, &int_rel, ext_rel);
+ }
+
+ BFD_ASSERT (ext_rel - (Elf64_Mips_External_Rel *) rel_hdr->contents
+ == *count);
+}
+
+static void
+mips_elf64_write_rela (bfd *abfd, asection *sec,
+ Elf_Internal_Shdr *rela_hdr,
+ int *count, void *data)
+{
+ bfd_boolean *failedp = data;
+ Elf64_Mips_External_Rela *ext_rela;
+ unsigned int idx;
+ asymbol *last_sym = 0;
+ int last_sym_idx = 0;
+
+ rela_hdr->sh_size = rela_hdr->sh_entsize * *count;
+ rela_hdr->contents = 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 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;
+ }
+
+ 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);
+}
+
+/* Set the right machine number for a MIPS ELF file. */
+
+static bfd_boolean
+mips_elf64_object_p (bfd *abfd)
+{
+ unsigned long mach;
+
+ /* Irix 6 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. */
+ if (elf64_mips_irix_compat (abfd) != ict_none)
+ elf_bad_symtab (abfd) = TRUE;
+
+ mach = _bfd_elf_mips_mach (elf_elfheader (abfd)->e_flags);
+ bfd_default_set_arch_mach (abfd, bfd_arch_mips, mach);
+ return TRUE;
+}
+
+/* Depending on the target vector we generate some version of Irix
+ executables or "normal" MIPS ELF ABI executables. */
+static irix_compat_t
+elf64_mips_irix_compat (bfd *abfd)
+{
+ if ((abfd->xvec == &mips_elf64_be_vec)
+ || (abfd->xvec == &mips_elf64_le_vec))
+ return ict_irix6;
+ else
+ return ict_none;
+}
+
+/* Support for core dump NOTE sections. */
+static bfd_boolean
+elf64_mips_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
+{
+ int offset;
+ unsigned int size;
+
+ switch (note->descsz)
+ {
+ default:
+ return FALSE;
+
+ case 480: /* Linux/MIPS - N64 kernel */
+ /* pr_cursig */
+ elf_tdata (abfd)->core->signal = bfd_get_16 (abfd, note->descdata + 12);
+
+ /* pr_pid */
+ elf_tdata (abfd)->core->lwpid = bfd_get_32 (abfd, note->descdata + 32);
+
+ /* pr_reg */
+ offset = 112;
+ size = 360;
+
+ break;
+ }
+
+ /* Make a ".reg/999" section. */
+ return _bfd_elfcore_make_pseudosection (abfd, ".reg",
+ size, note->descpos + offset);
+}
+
+static bfd_boolean
+elf64_mips_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
+{
+ switch (note->descsz)
+ {
+ default:
+ return FALSE;
+
+ case 136: /* Linux/MIPS - N64 kernel elf_prpsinfo */
+ elf_tdata (abfd)->core->program
+ = _bfd_elfcore_strndup (abfd, note->descdata + 40, 16);
+ elf_tdata (abfd)->core->command
+ = _bfd_elfcore_strndup (abfd, note->descdata + 56, 80);
+ }
+
+ /* 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;
+}
+
+/* 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),
+ 4, /* hash-table entry size */
+ 3, /* internal relocations per external relocations */
+ 64, /* arch_size */
+ 3, /* log_file_align */
+ ELFCLASS64,
+ EV_CURRENT,
+ bfd_elf64_write_out_phdrs,
+ bfd_elf64_write_shdrs_and_ehdr,
+ bfd_elf64_checksum_contents,
+ mips_elf64_write_relocs,
+ bfd_elf64_swap_symbol_in,
+ bfd_elf64_swap_symbol_out,
+ mips_elf64_slurp_reloc_table,
+ bfd_elf64_slurp_symbol_table,
+ bfd_elf64_swap_dyn_in,
+ bfd_elf64_swap_dyn_out,
+ mips_elf64_be_swap_reloc_in,
+ mips_elf64_be_swap_reloc_out,
+ mips_elf64_be_swap_reloca_in,
+ mips_elf64_be_swap_reloca_out
+};
+
+#define ELF_ARCH bfd_arch_mips
+#define ELF_TARGET_ID MIPS_ELF_DATA
+#define ELF_MACHINE_CODE EM_MIPS
+
+#define elf_backend_collect TRUE
+#define elf_backend_type_change_ok TRUE
+#define elf_backend_can_gc_sections TRUE
+#define elf_backend_gc_mark_extra_sections \
+ _bfd_mips_elf_gc_mark_extra_sections
+#define elf_info_to_howto mips_elf64_info_to_howto_rela
+#define elf_info_to_howto_rel mips_elf64_info_to_howto_rel
+#define elf_backend_object_p mips_elf64_object_p
+#define elf_backend_symbol_processing _bfd_mips_elf_symbol_processing
+#define elf_backend_section_processing _bfd_mips_elf_section_processing
+#define elf_backend_section_from_shdr _bfd_mips_elf_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_add_symbol_hook _bfd_mips_elf_add_symbol_hook
+#define elf_backend_link_output_symbol_hook \
+ _bfd_mips_elf_link_output_symbol_hook
+#define elf_backend_create_dynamic_sections \
+ _bfd_mips_elf_create_dynamic_sections
+#define elf_backend_check_relocs _bfd_mips_elf_check_relocs
+#define elf_backend_merge_symbol_attribute \
+ _bfd_mips_elf_merge_symbol_attribute
+#define elf_backend_get_target_dtag _bfd_mips_elf_get_target_dtag
+#define elf_backend_adjust_dynamic_symbol \
+ _bfd_mips_elf_adjust_dynamic_symbol
+#define elf_backend_always_size_sections \
+ _bfd_mips_elf_always_size_sections
+#define elf_backend_size_dynamic_sections \
+ _bfd_mips_elf_size_dynamic_sections
+#define elf_backend_init_index_section _bfd_elf_init_1_index_section
+#define elf_backend_relocate_section _bfd_mips_elf_relocate_section
+#define elf_backend_finish_dynamic_symbol \
+ _bfd_mips_elf_finish_dynamic_symbol
+#define elf_backend_finish_dynamic_sections \
+ _bfd_mips_elf_finish_dynamic_sections
+#define elf_backend_final_write_processing \
+ _bfd_mips_elf_final_write_processing
+#define elf_backend_additional_program_headers \
+ _bfd_mips_elf_additional_program_headers
+#define elf_backend_modify_segment_map _bfd_mips_elf_modify_segment_map
+#define elf_backend_gc_mark_hook _bfd_mips_elf_gc_mark_hook
+#define elf_backend_gc_sweep_hook _bfd_mips_elf_gc_sweep_hook
+#define elf_backend_copy_indirect_symbol \
+ _bfd_mips_elf_copy_indirect_symbol
+#define elf_backend_ignore_discarded_relocs \
+ _bfd_mips_elf_ignore_discarded_relocs
+#define elf_backend_mips_irix_compat elf64_mips_irix_compat
+#define elf_backend_mips_rtype_to_howto mips_elf64_rtype_to_howto
+#define elf_backend_ecoff_debug_swap &mips_elf64_ecoff_debug_swap
+#define elf_backend_size_info mips_elf64_size_info
+
+#define elf_backend_grok_prstatus elf64_mips_grok_prstatus
+#define elf_backend_grok_psinfo elf64_mips_grok_psinfo
+
+#define elf_backend_got_header_size (8 * MIPS_RESERVED_GOTNO)
+
+/* MIPS ELF64 can use a mixture of REL and RELA, but some Relocations
+ work better/work only in RELA, so we default to this. */
+#define elf_backend_may_use_rel_p 1
+#define elf_backend_may_use_rela_p 1
+#define elf_backend_default_use_rela_p 1
+#define elf_backend_rela_plts_and_copies_p 0
+#define elf_backend_plt_readonly 1
+#define elf_backend_plt_sym_val _bfd_mips_elf_plt_sym_val
+
+#define elf_backend_sign_extend_vma TRUE
+
+#define elf_backend_write_section _bfd_mips_elf_write_section
+
+/* We don't set bfd_elf64_bfd_is_local_label_name because the 32-bit
+ MIPS-specific function only applies to IRIX5, which had no 64-bit
+ ABI. */
+#define bfd_elf64_bfd_is_target_special_symbol \
+ _bfd_mips_elf_is_target_special_symbol
+#define bfd_elf64_find_nearest_line _bfd_mips_elf_find_nearest_line
+#define bfd_elf64_find_inliner_info _bfd_mips_elf_find_inliner_info
+#define bfd_elf64_new_section_hook _bfd_mips_elf_new_section_hook
+#define bfd_elf64_set_section_contents _bfd_mips_elf_set_section_contents
+#define bfd_elf64_bfd_get_relocated_section_contents \
+ _bfd_elf_mips_get_relocated_section_contents
+#define bfd_elf64_bfd_link_hash_table_create \
+ _bfd_mips_elf_link_hash_table_create
+#define bfd_elf64_bfd_final_link _bfd_mips_elf_final_link
+#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_bfd_print_private_bfd_data \
+ _bfd_mips_elf_print_private_bfd_data
+
+#define bfd_elf64_get_reloc_upper_bound mips_elf64_get_reloc_upper_bound
+#define bfd_elf64_canonicalize_reloc mips_elf64_canonicalize_reloc
+#define bfd_elf64_get_dynamic_reloc_upper_bound mips_elf64_get_dynamic_reloc_upper_bound
+#define bfd_elf64_canonicalize_dynamic_reloc mips_elf64_canonicalize_dynamic_reloc
+#define bfd_elf64_bfd_relax_section _bfd_mips_relax_section
+#define bfd_elf64_mkobject _bfd_mips_elf_mkobject
+
+/* MIPS ELF64 archive functions. */
+#define bfd_elf64_archive_functions
+extern bfd_boolean bfd_elf64_archive_slurp_armap
+ (bfd *);
+extern bfd_boolean bfd_elf64_archive_write_armap
+ (bfd *, unsigned int, struct orl *, unsigned int, int);
+#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_read_ar_hdr _bfd_archive_coff_read_ar_hdr
+#define bfd_elf64_archive_write_ar_hdr _bfd_archive_coff_write_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
+
+/* The SGI style (n)64 NewABI. */
+#define TARGET_LITTLE_SYM mips_elf64_le_vec
+#define TARGET_LITTLE_NAME "elf64-littlemips"
+#define TARGET_BIG_SYM mips_elf64_be_vec
+#define TARGET_BIG_NAME "elf64-bigmips"
+
+#define ELF_MAXPAGESIZE 0x10000
+#define ELF_COMMONPAGESIZE 0x1000
+
+#include "elf64-target.h"
+
+/* The SYSV-style 'traditional' (n)64 NewABI. */
+#undef TARGET_LITTLE_SYM
+#undef TARGET_LITTLE_NAME
+#undef TARGET_BIG_SYM
+#undef TARGET_BIG_NAME
+
+#undef ELF_MAXPAGESIZE
+#undef ELF_COMMONPAGESIZE
+
+#define TARGET_LITTLE_SYM mips_elf64_trad_le_vec
+#define TARGET_LITTLE_NAME "elf64-tradlittlemips"
+#define TARGET_BIG_SYM mips_elf64_trad_be_vec
+#define TARGET_BIG_NAME "elf64-tradbigmips"
+
+#define ELF_MAXPAGESIZE 0x10000
+#define ELF_COMMONPAGESIZE 0x1000
+#define elf64_bed elf64_tradbed
+
+/* Include the target file again for this target. */
+#include "elf64-target.h"
+
+
+/* FreeBSD support. */
+
+#undef TARGET_LITTLE_SYM
+#undef TARGET_LITTLE_NAME
+#undef TARGET_BIG_SYM
+#undef TARGET_BIG_NAME
+
+#define TARGET_LITTLE_SYM mips_elf64_tradfbsd_le_vec
+#define TARGET_LITTLE_NAME "elf64-tradlittlemips-freebsd"
+#define TARGET_BIG_SYM mips_elf64_tradfbsd_be_vec
+#define TARGET_BIG_NAME "elf64-tradbigmips-freebsd"
+
+#undef ELF_OSABI
+#define ELF_OSABI ELFOSABI_FREEBSD
+
+#undef elf64_bed
+#define elf64_bed elf64_fbsd_tradbed
+
+#include "elf64-target.h"
diff --git a/bfd/elf64-mmix.c b/bfd/elf64-mmix.c
new file mode 100644
index 0000000..58fca92
--- /dev/null
+++ b/bfd/elf64-mmix.c
@@ -0,0 +1,2938 @@
+/* MMIX-specific support for 64-bit ELF.
+ Copyright (C) 2001-2014 Free Software Foundation, Inc.
+ Contributed by Hans-Peter Nilsson <hp@bitrange.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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+
+/* No specific ABI or "processor-specific supplement" defined. */
+
+/* TODO:
+ - "Traditional" linker relaxation (shrinking whole sections).
+ - Merge reloc stubs jumping to same location.
+ - GETA stub relaxation (call a stub for out of range new
+ R_MMIX_GETA_STUBBABLE). */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+#include "elf-bfd.h"
+#include "elf/mmix.h"
+#include "opcode/mmix.h"
+
+#define MINUS_ONE (((bfd_vma) 0) - 1)
+
+#define MAX_PUSHJ_STUB_SIZE (5 * 4)
+
+/* Put these everywhere in new code. */
+#define FATAL_DEBUG \
+ _bfd_abort (__FILE__, __LINE__, \
+ "Internal: Non-debugged code (test-case missing)")
+
+#define BAD_CASE(x) \
+ _bfd_abort (__FILE__, __LINE__, \
+ "bad case for " #x)
+
+struct _mmix_elf_section_data
+{
+ struct bfd_elf_section_data elf;
+ union
+ {
+ struct bpo_reloc_section_info *reloc;
+ struct bpo_greg_section_info *greg;
+ } bpo;
+
+ struct pushj_stub_info
+ {
+ /* Maximum number of stubs needed for this section. */
+ bfd_size_type n_pushj_relocs;
+
+ /* Size of stubs after a mmix_elf_relax_section round. */
+ bfd_size_type stubs_size_sum;
+
+ /* Per-reloc stubs_size_sum information. The stubs_size_sum member is the sum
+ of these. Allocated in mmix_elf_check_common_relocs. */
+ bfd_size_type *stub_size;
+
+ /* Offset of next stub during relocation. Somewhat redundant with the
+ above: error coverage is easier and we don't have to reset the
+ stubs_size_sum for relocation. */
+ bfd_size_type stub_offset;
+ } pjs;
+
+ /* Whether there has been a warning that this section could not be
+ linked due to a specific cause. FIXME: a way to access the
+ linker info or output section, then stuff the limiter guard
+ there. */
+ bfd_boolean has_warned_bpo;
+ bfd_boolean has_warned_pushj;
+};
+
+#define mmix_elf_section_data(sec) \
+ ((struct _mmix_elf_section_data *) elf_section_data (sec))
+
+/* For each section containing a base-plus-offset (BPO) reloc, we attach
+ this struct as mmix_elf_section_data (section)->bpo, which is otherwise
+ NULL. */
+struct bpo_reloc_section_info
+ {
+ /* The base is 1; this is the first number in this section. */
+ size_t first_base_plus_offset_reloc;
+
+ /* Number of BPO-relocs in this section. */
+ size_t n_bpo_relocs_this_section;
+
+ /* Running index, used at relocation time. */
+ size_t bpo_index;
+
+ /* We don't have access to the bfd_link_info struct in
+ mmix_final_link_relocate. What we really want to get at is the
+ global single struct greg_relocation, so we stash it here. */
+ asection *bpo_greg_section;
+ };
+
+/* Helper struct (in global context) for the one below.
+ There's one of these created for every BPO reloc. */
+struct bpo_reloc_request
+ {
+ bfd_vma value;
+
+ /* Valid after relaxation. The base is 0; the first register number
+ must be added. The offset is in range 0..255. */
+ size_t regindex;
+ size_t offset;
+
+ /* The order number for this BPO reloc, corresponding to the order in
+ which BPO relocs were found. Used to create an index after reloc
+ requests are sorted. */
+ size_t bpo_reloc_no;
+
+ /* Set when the value is computed. Better than coding "guard values"
+ into the other members. Is FALSE only for BPO relocs in a GC:ed
+ section. */
+ bfd_boolean valid;
+ };
+
+/* We attach this as mmix_elf_section_data (sec)->bpo in the linker-allocated
+ greg contents section (MMIX_LD_ALLOCATED_REG_CONTENTS_SECTION_NAME),
+ which is linked into the register contents section
+ (MMIX_REG_CONTENTS_SECTION_NAME). This section is created by the
+ linker; using the same hook as for usual with BPO relocs does not
+ collide. */
+struct bpo_greg_section_info
+ {
+ /* After GC, this reflects the number of remaining, non-excluded
+ BPO-relocs. */
+ size_t n_bpo_relocs;
+
+ /* This is the number of allocated bpo_reloc_requests; the size of
+ sorted_indexes. Valid after the check.*relocs functions are called
+ for all incoming sections. It includes the number of BPO relocs in
+ sections that were GC:ed. */
+ size_t n_max_bpo_relocs;
+
+ /* A counter used to find out when to fold the BPO gregs, since we
+ don't have a single "after-relaxation" hook. */
+ size_t n_remaining_bpo_relocs_this_relaxation_round;
+
+ /* The number of linker-allocated GREGs resulting from BPO relocs.
+ This is an approximation after _bfd_mmix_before_linker_allocation
+ and supposedly accurate after mmix_elf_relax_section is called for
+ all incoming non-collected sections. */
+ size_t n_allocated_bpo_gregs;
+
+ /* Index into reloc_request[], sorted on increasing "value", secondary
+ by increasing index for strict sorting order. */
+ size_t *bpo_reloc_indexes;
+
+ /* An array of all relocations, with the "value" member filled in by
+ the relaxation function. */
+ struct bpo_reloc_request *reloc_request;
+ };
+
+
+extern bfd_boolean mmix_elf_final_link (bfd *, struct bfd_link_info *);
+
+extern void mmix_elf_symbol_processing (bfd *, asymbol *);
+
+/* Only intended to be called from a debugger. */
+extern void mmix_dump_bpo_gregs
+ (struct bfd_link_info *, bfd_error_handler_type);
+
+static void
+mmix_set_relaxable_size (bfd *, asection *, void *);
+static bfd_reloc_status_type
+mmix_elf_reloc (bfd *, arelent *, asymbol *, void *,
+ asection *, bfd *, char **);
+static bfd_reloc_status_type
+mmix_final_link_relocate (reloc_howto_type *, asection *, bfd_byte *, bfd_vma,
+ bfd_signed_vma, bfd_vma, const char *, asection *,
+ char **);
+
+
+/* Watch out: this currently needs to have elements with the same index as
+ their R_MMIX_ number. */
+static reloc_howto_type elf_mmix_howto_table[] =
+ {
+ /* This reloc does nothing. */
+ HOWTO (R_MMIX_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_MMIX_NONE", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* An 8 bit absolute relocation. */
+ HOWTO (R_MMIX_8, /* 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_MMIX_8", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* An 16 bit absolute relocation. */
+ HOWTO (R_MMIX_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_MMIX_16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* An 24 bit absolute relocation. */
+ HOWTO (R_MMIX_24, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 24, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MMIX_24", /* name */
+ FALSE, /* partial_inplace */
+ ~0xffffff, /* src_mask */
+ 0xffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A 32 bit absolute relocation. */
+ HOWTO (R_MMIX_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_MMIX_32", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* 64 bit relocation. */
+ HOWTO (R_MMIX_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_MMIX_64", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ MINUS_ONE, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* An 8 bit PC-relative relocation. */
+ HOWTO (R_MMIX_PC_8, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 8, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MMIX_PC_8", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* An 16 bit PC-relative relocation. */
+ HOWTO (R_MMIX_PC_16, /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MMIX_PC_16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* An 24 bit PC-relative relocation. */
+ HOWTO (R_MMIX_PC_24, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 24, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MMIX_PC_24", /* name */
+ FALSE, /* partial_inplace */
+ ~0xffffff, /* src_mask */
+ 0xffffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* A 32 bit absolute PC-relative relocation. */
+ HOWTO (R_MMIX_PC_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 */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MMIX_PC_32", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* 64 bit PC-relative relocation. */
+ HOWTO (R_MMIX_PC_64, /* type */
+ 0, /* rightshift */
+ 4, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_MMIX_PC_64", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ MINUS_ONE, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* GNU extension to record C++ vtable hierarchy. */
+ HOWTO (R_MMIX_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_MMIX_GNU_VTINHERIT", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* GNU extension to record C++ vtable member usage. */
+ HOWTO (R_MMIX_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 */
+ _bfd_elf_rel_vtable_reloc_fn, /* special_function */
+ "R_MMIX_GNU_VTENTRY", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* The GETA relocation is supposed to get any address that could
+ possibly be reached by the GETA instruction. It can silently expand
+ to get a 64-bit operand, but will complain if any of the two least
+ significant bits are set. The howto members reflect a simple GETA. */
+ HOWTO (R_MMIX_GETA, /* type */
+ 2, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 19, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ mmix_elf_reloc, /* special_function */
+ "R_MMIX_GETA", /* name */
+ FALSE, /* partial_inplace */
+ ~0x0100ffff, /* src_mask */
+ 0x0100ffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_MMIX_GETA_1, /* type */
+ 2, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 19, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ mmix_elf_reloc, /* special_function */
+ "R_MMIX_GETA_1", /* name */
+ FALSE, /* partial_inplace */
+ ~0x0100ffff, /* src_mask */
+ 0x0100ffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_MMIX_GETA_2, /* type */
+ 2, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 19, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ mmix_elf_reloc, /* special_function */
+ "R_MMIX_GETA_2", /* name */
+ FALSE, /* partial_inplace */
+ ~0x0100ffff, /* src_mask */
+ 0x0100ffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_MMIX_GETA_3, /* type */
+ 2, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 19, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ mmix_elf_reloc, /* special_function */
+ "R_MMIX_GETA_3", /* name */
+ FALSE, /* partial_inplace */
+ ~0x0100ffff, /* src_mask */
+ 0x0100ffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* The conditional branches are supposed to reach any (code) address.
+ It can silently expand to a 64-bit operand, but will emit an error if
+ any of the two least significant bits are set. The howto members
+ reflect a simple branch. */
+ HOWTO (R_MMIX_CBRANCH, /* type */
+ 2, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 19, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ mmix_elf_reloc, /* special_function */
+ "R_MMIX_CBRANCH", /* name */
+ FALSE, /* partial_inplace */
+ ~0x0100ffff, /* src_mask */
+ 0x0100ffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_MMIX_CBRANCH_J, /* type */
+ 2, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 19, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ mmix_elf_reloc, /* special_function */
+ "R_MMIX_CBRANCH_J", /* name */
+ FALSE, /* partial_inplace */
+ ~0x0100ffff, /* src_mask */
+ 0x0100ffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_MMIX_CBRANCH_1, /* type */
+ 2, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 19, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ mmix_elf_reloc, /* special_function */
+ "R_MMIX_CBRANCH_1", /* name */
+ FALSE, /* partial_inplace */
+ ~0x0100ffff, /* src_mask */
+ 0x0100ffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_MMIX_CBRANCH_2, /* type */
+ 2, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 19, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ mmix_elf_reloc, /* special_function */
+ "R_MMIX_CBRANCH_2", /* name */
+ FALSE, /* partial_inplace */
+ ~0x0100ffff, /* src_mask */
+ 0x0100ffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_MMIX_CBRANCH_3, /* type */
+ 2, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 19, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ mmix_elf_reloc, /* special_function */
+ "R_MMIX_CBRANCH_3", /* name */
+ FALSE, /* partial_inplace */
+ ~0x0100ffff, /* src_mask */
+ 0x0100ffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* The PUSHJ instruction can reach any (code) address, as long as it's
+ the beginning of a function (no usable restriction). It can silently
+ expand to a 64-bit operand, but will emit an error if any of the two
+ least significant bits are set. It can also expand into a call to a
+ stub; see R_MMIX_PUSHJ_STUBBABLE. The howto members reflect a simple
+ PUSHJ. */
+ HOWTO (R_MMIX_PUSHJ, /* type */
+ 2, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 19, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ mmix_elf_reloc, /* special_function */
+ "R_MMIX_PUSHJ", /* name */
+ FALSE, /* partial_inplace */
+ ~0x0100ffff, /* src_mask */
+ 0x0100ffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_MMIX_PUSHJ_1, /* type */
+ 2, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 19, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ mmix_elf_reloc, /* special_function */
+ "R_MMIX_PUSHJ_1", /* name */
+ FALSE, /* partial_inplace */
+ ~0x0100ffff, /* src_mask */
+ 0x0100ffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_MMIX_PUSHJ_2, /* type */
+ 2, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 19, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ mmix_elf_reloc, /* special_function */
+ "R_MMIX_PUSHJ_2", /* name */
+ FALSE, /* partial_inplace */
+ ~0x0100ffff, /* src_mask */
+ 0x0100ffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_MMIX_PUSHJ_3, /* type */
+ 2, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 19, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ mmix_elf_reloc, /* special_function */
+ "R_MMIX_PUSHJ_3", /* name */
+ FALSE, /* partial_inplace */
+ ~0x0100ffff, /* src_mask */
+ 0x0100ffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* A JMP is supposed to reach any (code) address. By itself, it can
+ reach +-64M; the expansion can reach all 64 bits. Note that the 64M
+ limit is soon reached if you link the program in wildly different
+ memory segments. The howto members reflect a trivial JMP. */
+ HOWTO (R_MMIX_JMP, /* type */
+ 2, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 27, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ mmix_elf_reloc, /* special_function */
+ "R_MMIX_JMP", /* name */
+ FALSE, /* partial_inplace */
+ ~0x1ffffff, /* src_mask */
+ 0x1ffffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_MMIX_JMP_1, /* type */
+ 2, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 27, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ mmix_elf_reloc, /* special_function */
+ "R_MMIX_JMP_1", /* name */
+ FALSE, /* partial_inplace */
+ ~0x1ffffff, /* src_mask */
+ 0x1ffffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_MMIX_JMP_2, /* type */
+ 2, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 27, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ mmix_elf_reloc, /* special_function */
+ "R_MMIX_JMP_2", /* name */
+ FALSE, /* partial_inplace */
+ ~0x1ffffff, /* src_mask */
+ 0x1ffffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_MMIX_JMP_3, /* type */
+ 2, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 27, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ mmix_elf_reloc, /* special_function */
+ "R_MMIX_JMP_3", /* name */
+ FALSE, /* partial_inplace */
+ ~0x1ffffff, /* src_mask */
+ 0x1ffffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* When we don't emit link-time-relaxable code from the assembler, or
+ when relaxation has done all it can do, these relocs are used. For
+ GETA/PUSHJ/branches. */
+ HOWTO (R_MMIX_ADDR19, /* type */
+ 2, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 19, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ mmix_elf_reloc, /* special_function */
+ "R_MMIX_ADDR19", /* name */
+ FALSE, /* partial_inplace */
+ ~0x0100ffff, /* src_mask */
+ 0x0100ffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* For JMP. */
+ HOWTO (R_MMIX_ADDR27, /* type */
+ 2, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 27, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ mmix_elf_reloc, /* special_function */
+ "R_MMIX_ADDR27", /* name */
+ FALSE, /* partial_inplace */
+ ~0x1ffffff, /* src_mask */
+ 0x1ffffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* A general register or the value 0..255. If a value, then the
+ instruction (offset -3) needs adjusting. */
+ HOWTO (R_MMIX_REG_OR_BYTE, /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 8, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ mmix_elf_reloc, /* special_function */
+ "R_MMIX_REG_OR_BYTE", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A general register. */
+ HOWTO (R_MMIX_REG, /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 8, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ mmix_elf_reloc, /* special_function */
+ "R_MMIX_REG", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A register plus an index, corresponding to the relocation expression.
+ The sizes must correspond to the valid range of the expression, while
+ the bitmasks correspond to what we store in the image. */
+ HOWTO (R_MMIX_BASE_PLUS_OFFSET, /* type */
+ 0, /* rightshift */
+ 4, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ mmix_elf_reloc, /* special_function */
+ "R_MMIX_BASE_PLUS_OFFSET", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A "magic" relocation for a LOCAL expression, asserting that the
+ expression is less than the number of global registers. No actual
+ modification of the contents is done. Implementing this as a
+ relocation was less intrusive than e.g. putting such expressions in a
+ section to discard *after* relocation. */
+ HOWTO (R_MMIX_LOCAL, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 0, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ mmix_elf_reloc, /* special_function */
+ "R_MMIX_LOCAL", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_MMIX_PUSHJ_STUBBABLE, /* type */
+ 2, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 19, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ mmix_elf_reloc, /* special_function */
+ "R_MMIX_PUSHJ_STUBBABLE", /* name */
+ FALSE, /* partial_inplace */
+ ~0x0100ffff, /* src_mask */
+ 0x0100ffff, /* dst_mask */
+ TRUE) /* pcrel_offset */
+ };
+
+
+/* Map BFD reloc types to MMIX ELF reloc types. */
+
+struct mmix_reloc_map
+ {
+ bfd_reloc_code_real_type bfd_reloc_val;
+ enum elf_mmix_reloc_type elf_reloc_val;
+ };
+
+
+static const struct mmix_reloc_map mmix_reloc_map[] =
+ {
+ {BFD_RELOC_NONE, R_MMIX_NONE},
+ {BFD_RELOC_8, R_MMIX_8},
+ {BFD_RELOC_16, R_MMIX_16},
+ {BFD_RELOC_24, R_MMIX_24},
+ {BFD_RELOC_32, R_MMIX_32},
+ {BFD_RELOC_64, R_MMIX_64},
+ {BFD_RELOC_8_PCREL, R_MMIX_PC_8},
+ {BFD_RELOC_16_PCREL, R_MMIX_PC_16},
+ {BFD_RELOC_24_PCREL, R_MMIX_PC_24},
+ {BFD_RELOC_32_PCREL, R_MMIX_PC_32},
+ {BFD_RELOC_64_PCREL, R_MMIX_PC_64},
+ {BFD_RELOC_VTABLE_INHERIT, R_MMIX_GNU_VTINHERIT},
+ {BFD_RELOC_VTABLE_ENTRY, R_MMIX_GNU_VTENTRY},
+ {BFD_RELOC_MMIX_GETA, R_MMIX_GETA},
+ {BFD_RELOC_MMIX_CBRANCH, R_MMIX_CBRANCH},
+ {BFD_RELOC_MMIX_PUSHJ, R_MMIX_PUSHJ},
+ {BFD_RELOC_MMIX_JMP, R_MMIX_JMP},
+ {BFD_RELOC_MMIX_ADDR19, R_MMIX_ADDR19},
+ {BFD_RELOC_MMIX_ADDR27, R_MMIX_ADDR27},
+ {BFD_RELOC_MMIX_REG_OR_BYTE, R_MMIX_REG_OR_BYTE},
+ {BFD_RELOC_MMIX_REG, R_MMIX_REG},
+ {BFD_RELOC_MMIX_BASE_PLUS_OFFSET, R_MMIX_BASE_PLUS_OFFSET},
+ {BFD_RELOC_MMIX_LOCAL, R_MMIX_LOCAL},
+ {BFD_RELOC_MMIX_PUSHJ_STUBBABLE, R_MMIX_PUSHJ_STUBBABLE}
+ };
+
+static reloc_howto_type *
+bfd_elf64_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ bfd_reloc_code_real_type code)
+{
+ unsigned int i;
+
+ for (i = 0;
+ i < sizeof (mmix_reloc_map) / sizeof (mmix_reloc_map[0]);
+ i++)
+ {
+ if (mmix_reloc_map[i].bfd_reloc_val == code)
+ return &elf_mmix_howto_table[mmix_reloc_map[i].elf_reloc_val];
+ }
+
+ return NULL;
+}
+
+static reloc_howto_type *
+bfd_elf64_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ const char *r_name)
+{
+ unsigned int i;
+
+ for (i = 0;
+ i < sizeof (elf_mmix_howto_table) / sizeof (elf_mmix_howto_table[0]);
+ i++)
+ if (elf_mmix_howto_table[i].name != NULL
+ && strcasecmp (elf_mmix_howto_table[i].name, r_name) == 0)
+ return &elf_mmix_howto_table[i];
+
+ return NULL;
+}
+
+static bfd_boolean
+mmix_elf_new_section_hook (bfd *abfd, asection *sec)
+{
+ if (!sec->used_by_bfd)
+ {
+ struct _mmix_elf_section_data *sdata;
+ bfd_size_type amt = sizeof (*sdata);
+
+ sdata = bfd_zalloc (abfd, amt);
+ if (sdata == NULL)
+ return FALSE;
+ sec->used_by_bfd = sdata;
+ }
+
+ return _bfd_elf_new_section_hook (abfd, sec);
+}
+
+
+/* This function performs the actual bitfiddling and sanity check for a
+ final relocation. Each relocation gets its *worst*-case expansion
+ in size when it arrives here; any reduction in size should have been
+ caught in linker relaxation earlier. When we get here, the relocation
+ looks like the smallest instruction with SWYM:s (nop:s) appended to the
+ max size. We fill in those nop:s.
+
+ R_MMIX_GETA: (FIXME: Relaxation should break this up in 1, 2, 3 tetra)
+ GETA $N,foo
+ ->
+ SETL $N,foo & 0xffff
+ INCML $N,(foo >> 16) & 0xffff
+ INCMH $N,(foo >> 32) & 0xffff
+ INCH $N,(foo >> 48) & 0xffff
+
+ R_MMIX_CBRANCH: (FIXME: Relaxation should break this up, but
+ condbranches needing relaxation might be rare enough to not be
+ worthwhile.)
+ [P]Bcc $N,foo
+ ->
+ [~P]B~cc $N,.+20
+ SETL $255,foo & ...
+ INCML ...
+ INCMH ...
+ INCH ...
+ GO $255,$255,0
+
+ R_MMIX_PUSHJ: (FIXME: Relaxation...)
+ PUSHJ $N,foo
+ ->
+ SETL $255,foo & ...
+ INCML ...
+ INCMH ...
+ INCH ...
+ PUSHGO $N,$255,0
+
+ R_MMIX_JMP: (FIXME: Relaxation...)
+ JMP foo
+ ->
+ SETL $255,foo & ...
+ INCML ...
+ INCMH ...
+ INCH ...
+ GO $255,$255,0
+
+ R_MMIX_ADDR19 and R_MMIX_ADDR27 are just filled in. */
+
+static bfd_reloc_status_type
+mmix_elf_perform_relocation (asection *isec, reloc_howto_type *howto,
+ void *datap, bfd_vma addr, bfd_vma value,
+ char **error_message)
+{
+ bfd *abfd = isec->owner;
+ bfd_reloc_status_type flag = bfd_reloc_ok;
+ bfd_reloc_status_type r;
+ int offs = 0;
+ int reg = 255;
+
+ /* The worst case bits are all similar SETL/INCML/INCMH/INCH sequences.
+ We handle the differences here and the common sequence later. */
+ switch (howto->type)
+ {
+ case R_MMIX_GETA:
+ offs = 0;
+ reg = bfd_get_8 (abfd, (bfd_byte *) datap + 1);
+
+ /* We change to an absolute value. */
+ value += addr;
+ break;
+
+ case R_MMIX_CBRANCH:
+ {
+ int in1 = bfd_get_16 (abfd, (bfd_byte *) datap) << 16;
+
+ /* Invert the condition and prediction bit, and set the offset
+ to five instructions ahead.
+
+ We *can* do better if we want to. If the branch is found to be
+ within limits, we could leave the branch as is; there'll just
+ be a bunch of NOP:s after it. But we shouldn't see this
+ sequence often enough that it's worth doing it. */
+
+ bfd_put_32 (abfd,
+ (((in1 ^ ((PRED_INV_BIT | COND_INV_BIT) << 24)) & ~0xffff)
+ | (24/4)),
+ (bfd_byte *) datap);
+
+ /* Put a "GO $255,$255,0" after the common sequence. */
+ bfd_put_32 (abfd,
+ ((GO_INSN_BYTE | IMM_OFFSET_BIT) << 24) | 0xffff00,
+ (bfd_byte *) datap + 20);
+
+ /* Common sequence starts at offset 4. */
+ offs = 4;
+
+ /* We change to an absolute value. */
+ value += addr;
+ }
+ break;
+
+ case R_MMIX_PUSHJ_STUBBABLE:
+ /* If the address fits, we're fine. */
+ if ((value & 3) == 0
+ /* Note rightshift 0; see R_MMIX_JMP case below. */
+ && (r = bfd_check_overflow (complain_overflow_signed,
+ howto->bitsize,
+ 0,
+ bfd_arch_bits_per_address (abfd),
+ value)) == bfd_reloc_ok)
+ goto pcrel_mmix_reloc_fits;
+ else
+ {
+ bfd_size_type size = isec->rawsize ? isec->rawsize : isec->size;
+
+ /* We have the bytes at the PUSHJ insn and need to get the
+ position for the stub. There's supposed to be room allocated
+ for the stub. */
+ bfd_byte *stubcontents
+ = ((bfd_byte *) datap
+ - (addr - (isec->output_section->vma + isec->output_offset))
+ + size
+ + mmix_elf_section_data (isec)->pjs.stub_offset);
+ bfd_vma stubaddr;
+
+ if (mmix_elf_section_data (isec)->pjs.n_pushj_relocs == 0)
+ {
+ /* This shouldn't happen when linking to ELF or mmo, so
+ this is an attempt to link to "binary", right? We
+ can't access the output bfd, so we can't verify that
+ assumption. We only know that the critical
+ mmix_elf_check_common_relocs has not been called,
+ which happens when the output format is different
+ from the input format (and is not mmo). */
+ if (! mmix_elf_section_data (isec)->has_warned_pushj)
+ {
+ /* For the first such error per input section, produce
+ a verbose message. */
+ *error_message
+ = _("invalid input relocation when producing"
+ " non-ELF, non-mmo format output."
+ "\n Please use the objcopy program to convert from"
+ " ELF or mmo,"
+ "\n or assemble using"
+ " \"-no-expand\" (for gcc, \"-Wa,-no-expand\"");
+ mmix_elf_section_data (isec)->has_warned_pushj = TRUE;
+ return bfd_reloc_dangerous;
+ }
+
+ /* For subsequent errors, return this one, which is
+ rate-limited but looks a little bit different,
+ hopefully without affecting user-friendliness. */
+ return bfd_reloc_overflow;
+ }
+
+ /* The address doesn't fit, so redirect the PUSHJ to the
+ location of the stub. */
+ r = mmix_elf_perform_relocation (isec,
+ &elf_mmix_howto_table
+ [R_MMIX_ADDR19],
+ datap,
+ addr,
+ isec->output_section->vma
+ + isec->output_offset
+ + size
+ + (mmix_elf_section_data (isec)
+ ->pjs.stub_offset)
+ - addr,
+ error_message);
+ if (r != bfd_reloc_ok)
+ return r;
+
+ stubaddr
+ = (isec->output_section->vma
+ + isec->output_offset
+ + size
+ + mmix_elf_section_data (isec)->pjs.stub_offset);
+
+ /* We generate a simple JMP if that suffices, else the whole 5
+ insn stub. */
+ if (bfd_check_overflow (complain_overflow_signed,
+ elf_mmix_howto_table[R_MMIX_ADDR27].bitsize,
+ 0,
+ bfd_arch_bits_per_address (abfd),
+ addr + value - stubaddr) == bfd_reloc_ok)
+ {
+ bfd_put_32 (abfd, JMP_INSN_BYTE << 24, stubcontents);
+ r = mmix_elf_perform_relocation (isec,
+ &elf_mmix_howto_table
+ [R_MMIX_ADDR27],
+ stubcontents,
+ stubaddr,
+ value + addr - stubaddr,
+ error_message);
+ mmix_elf_section_data (isec)->pjs.stub_offset += 4;
+
+ if (size + mmix_elf_section_data (isec)->pjs.stub_offset
+ > isec->size)
+ abort ();
+
+ return r;
+ }
+ else
+ {
+ /* Put a "GO $255,0" after the common sequence. */
+ bfd_put_32 (abfd,
+ ((GO_INSN_BYTE | IMM_OFFSET_BIT) << 24)
+ | 0xff00, (bfd_byte *) stubcontents + 16);
+
+ /* Prepare for the general code to set the first part of the
+ linker stub, and */
+ value += addr;
+ datap = stubcontents;
+ mmix_elf_section_data (isec)->pjs.stub_offset
+ += MAX_PUSHJ_STUB_SIZE;
+ }
+ }
+ break;
+
+ case R_MMIX_PUSHJ:
+ {
+ int inreg = bfd_get_8 (abfd, (bfd_byte *) datap + 1);
+
+ /* Put a "PUSHGO $N,$255,0" after the common sequence. */
+ bfd_put_32 (abfd,
+ ((PUSHGO_INSN_BYTE | IMM_OFFSET_BIT) << 24)
+ | (inreg << 16)
+ | 0xff00,
+ (bfd_byte *) datap + 16);
+
+ /* We change to an absolute value. */
+ value += addr;
+ }
+ break;
+
+ case R_MMIX_JMP:
+ /* This one is a little special. If we get here on a non-relaxing
+ link, and the destination is actually in range, we don't need to
+ execute the nops.
+ If so, we fall through to the bit-fiddling relocs.
+
+ FIXME: bfd_check_overflow seems broken; the relocation is
+ rightshifted before testing, so supply a zero rightshift. */
+
+ if (! ((value & 3) == 0
+ && (r = bfd_check_overflow (complain_overflow_signed,
+ howto->bitsize,
+ 0,
+ bfd_arch_bits_per_address (abfd),
+ value)) == bfd_reloc_ok))
+ {
+ /* If the relocation doesn't fit in a JMP, we let the NOP:s be
+ modified below, and put a "GO $255,$255,0" after the
+ address-loading sequence. */
+ bfd_put_32 (abfd,
+ ((GO_INSN_BYTE | IMM_OFFSET_BIT) << 24)
+ | 0xffff00,
+ (bfd_byte *) datap + 16);
+
+ /* We change to an absolute value. */
+ value += addr;
+ break;
+ }
+ /* FALLTHROUGH. */
+ case R_MMIX_ADDR19:
+ case R_MMIX_ADDR27:
+ pcrel_mmix_reloc_fits:
+ /* These must be in range, or else we emit an error. */
+ if ((value & 3) == 0
+ /* Note rightshift 0; see above. */
+ && (r = bfd_check_overflow (complain_overflow_signed,
+ howto->bitsize,
+ 0,
+ bfd_arch_bits_per_address (abfd),
+ value)) == bfd_reloc_ok)
+ {
+ bfd_vma in1
+ = bfd_get_32 (abfd, (bfd_byte *) datap);
+ bfd_vma highbit;
+
+ if ((bfd_signed_vma) value < 0)
+ {
+ highbit = 1 << 24;
+ value += (1 << (howto->bitsize - 1));
+ }
+ else
+ highbit = 0;
+
+ value >>= 2;
+
+ bfd_put_32 (abfd,
+ (in1 & howto->src_mask)
+ | highbit
+ | (value & howto->dst_mask),
+ (bfd_byte *) datap);
+
+ return bfd_reloc_ok;
+ }
+ else
+ return bfd_reloc_overflow;
+
+ case R_MMIX_BASE_PLUS_OFFSET:
+ {
+ struct bpo_reloc_section_info *bpodata
+ = mmix_elf_section_data (isec)->bpo.reloc;
+ asection *bpo_greg_section;
+ struct bpo_greg_section_info *gregdata;
+ size_t bpo_index;
+
+ if (bpodata == NULL)
+ {
+ /* This shouldn't happen when linking to ELF or mmo, so
+ this is an attempt to link to "binary", right? We
+ can't access the output bfd, so we can't verify that
+ assumption. We only know that the critical
+ mmix_elf_check_common_relocs has not been called, which
+ happens when the output format is different from the
+ input format (and is not mmo). */
+ if (! mmix_elf_section_data (isec)->has_warned_bpo)
+ {
+ /* For the first such error per input section, produce
+ a verbose message. */
+ *error_message
+ = _("invalid input relocation when producing"
+ " non-ELF, non-mmo format output."
+ "\n Please use the objcopy program to convert from"
+ " ELF or mmo,"
+ "\n or compile using the gcc-option"
+ " \"-mno-base-addresses\".");
+ mmix_elf_section_data (isec)->has_warned_bpo = TRUE;
+ return bfd_reloc_dangerous;
+ }
+
+ /* For subsequent errors, return this one, which is
+ rate-limited but looks a little bit different,
+ hopefully without affecting user-friendliness. */
+ return bfd_reloc_overflow;
+ }
+
+ bpo_greg_section = bpodata->bpo_greg_section;
+ gregdata = mmix_elf_section_data (bpo_greg_section)->bpo.greg;
+ bpo_index = gregdata->bpo_reloc_indexes[bpodata->bpo_index++];
+
+ /* A consistency check: The value we now have in "relocation" must
+ be the same as the value we stored for that relocation. It
+ doesn't cost much, so can be left in at all times. */
+ if (value != gregdata->reloc_request[bpo_index].value)
+ {
+ (*_bfd_error_handler)
+ (_("%s: Internal inconsistency error for value for\n\
+ linker-allocated global register: linked: 0x%lx%08lx != relaxed: 0x%lx%08lx\n"),
+ bfd_get_filename (isec->owner),
+ (unsigned long) (value >> 32), (unsigned long) value,
+ (unsigned long) (gregdata->reloc_request[bpo_index].value
+ >> 32),
+ (unsigned long) gregdata->reloc_request[bpo_index].value);
+ bfd_set_error (bfd_error_bad_value);
+ return bfd_reloc_overflow;
+ }
+
+ /* Then store the register number and offset for that register
+ into datap and datap + 1 respectively. */
+ bfd_put_8 (abfd,
+ gregdata->reloc_request[bpo_index].regindex
+ + bpo_greg_section->output_section->vma / 8,
+ datap);
+ bfd_put_8 (abfd,
+ gregdata->reloc_request[bpo_index].offset,
+ ((unsigned char *) datap) + 1);
+ return bfd_reloc_ok;
+ }
+
+ case R_MMIX_REG_OR_BYTE:
+ case R_MMIX_REG:
+ if (value > 255)
+ return bfd_reloc_overflow;
+ bfd_put_8 (abfd, value, datap);
+ return bfd_reloc_ok;
+
+ default:
+ BAD_CASE (howto->type);
+ }
+
+ /* This code adds the common SETL/INCML/INCMH/INCH worst-case
+ sequence. */
+
+ /* Lowest two bits must be 0. We return bfd_reloc_overflow for
+ everything that looks strange. */
+ if (value & 3)
+ flag = bfd_reloc_overflow;
+
+ bfd_put_32 (abfd,
+ (SETL_INSN_BYTE << 24) | (value & 0xffff) | (reg << 16),
+ (bfd_byte *) datap + offs);
+ bfd_put_32 (abfd,
+ (INCML_INSN_BYTE << 24) | ((value >> 16) & 0xffff) | (reg << 16),
+ (bfd_byte *) datap + offs + 4);
+ bfd_put_32 (abfd,
+ (INCMH_INSN_BYTE << 24) | ((value >> 32) & 0xffff) | (reg << 16),
+ (bfd_byte *) datap + offs + 8);
+ bfd_put_32 (abfd,
+ (INCH_INSN_BYTE << 24) | ((value >> 48) & 0xffff) | (reg << 16),
+ (bfd_byte *) datap + offs + 12);
+
+ return flag;
+}
+
+/* Set the howto pointer for an MMIX ELF reloc (type RELA). */
+
+static void
+mmix_info_to_howto_rela (bfd *abfd ATTRIBUTE_UNUSED,
+ arelent *cache_ptr,
+ Elf_Internal_Rela *dst)
+{
+ unsigned int r_type;
+
+ r_type = ELF64_R_TYPE (dst->r_info);
+ BFD_ASSERT (r_type < (unsigned int) R_MMIX_max);
+ cache_ptr->howto = &elf_mmix_howto_table[r_type];
+}
+
+/* Any MMIX-specific relocation gets here at assembly time or when linking
+ to other formats (such as mmo); this is the relocation function from
+ the reloc_table. We don't get here for final pure ELF linking. */
+
+static bfd_reloc_status_type
+mmix_elf_reloc (bfd *abfd,
+ arelent *reloc_entry,
+ asymbol *symbol,
+ void * data,
+ asection *input_section,
+ bfd *output_bfd,
+ char **error_message)
+{
+ bfd_vma relocation;
+ bfd_reloc_status_type r;
+ asection *reloc_target_output_section;
+ bfd_reloc_status_type flag = bfd_reloc_ok;
+ bfd_vma output_base = 0;
+
+ r = bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
+ input_section, output_bfd, error_message);
+
+ /* If that was all that was needed (i.e. this isn't a final link, only
+ some segment adjustments), we're done. */
+ if (r != bfd_reloc_continue)
+ return r;
+
+ if (bfd_is_und_section (symbol->section)
+ && (symbol->flags & BSF_WEAK) == 0
+ && output_bfd == (bfd *) NULL)
+ return bfd_reloc_undefined;
+
+ /* Is the address of the relocation really within the section? */
+ if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
+ return bfd_reloc_outofrange;
+
+ /* Work out which section the relocation is targeted 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 = bfd_get_output_section (symbol);
+
+ /* Here the variable relocation holds the final address of the symbol we
+ are relocating against, plus any addend. */
+ if (output_bfd)
+ output_base = 0;
+ else
+ output_base = reloc_target_output_section->vma;
+
+ relocation += output_base + symbol->section->output_offset;
+
+ if (output_bfd != (bfd *) NULL)
+ {
+ /* Add in supplied addend. */
+ relocation += reloc_entry->addend;
+
+ /* 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;
+ }
+
+ return mmix_final_link_relocate (reloc_entry->howto, input_section,
+ data, reloc_entry->address,
+ reloc_entry->addend, relocation,
+ bfd_asymbol_name (symbol),
+ reloc_target_output_section,
+ error_message);
+}
+
+/* Relocate an MMIX ELF section. Modified from elf32-fr30.c; look to it
+ for guidance if you're thinking of copying this. */
+
+static bfd_boolean
+mmix_elf_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
+ 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;
+ bfd_size_type size;
+ size_t pjsno = 0;
+
+ size = input_section->rawsize ? input_section->rawsize : input_section->size;
+ symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
+ sym_hashes = elf_sym_hashes (input_bfd);
+ relend = relocs + input_section->reloc_count;
+
+ /* Zero the stub area before we start. */
+ if (input_section->rawsize != 0
+ && input_section->size > input_section->rawsize)
+ memset (contents + input_section->rawsize, 0,
+ input_section->size - input_section->rawsize);
+
+ 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;
+ bfd_boolean undefined_signalled = FALSE;
+
+ r_type = ELF64_R_TYPE (rel->r_info);
+
+ if (r_type == R_MMIX_GNU_VTINHERIT
+ || r_type == R_MMIX_GNU_VTENTRY)
+ continue;
+
+ r_symndx = ELF64_R_SYM (rel->r_info);
+
+ howto = elf_mmix_howto_table + ELF64_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 = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
+
+ name = bfd_elf_string_from_elf_section (input_bfd,
+ symtab_hdr->sh_link,
+ sym->st_name);
+ if (name == NULL)
+ name = bfd_section_name (input_bfd, sec);
+ }
+ else
+ {
+ bfd_boolean unresolved_reloc, ignored;
+
+ RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
+ r_symndx, symtab_hdr, sym_hashes,
+ h, sec, relocation,
+ unresolved_reloc, undefined_signalled,
+ ignored);
+ name = h->root.root.string;
+ }
+
+ if (sec != NULL && discarded_section (sec))
+ RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+ rel, 1, relend, howto, 0, contents);
+
+ if (info->relocatable)
+ {
+ /* This is a relocatable link. For most relocs 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 (sym != NULL && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
+ rel->r_addend += sec->output_offset;
+
+ /* For PUSHJ stub relocs however, we may need to change the
+ reloc and the section contents, if the reloc doesn't reach
+ beyond the end of the output section and previous stubs.
+ Then we change the section contents to be a PUSHJ to the end
+ of the input section plus stubs (we can do that without using
+ a reloc), and then we change the reloc to be a R_MMIX_PUSHJ
+ at the stub location. */
+ if (r_type == R_MMIX_PUSHJ_STUBBABLE)
+ {
+ /* We've already checked whether we need a stub; use that
+ knowledge. */
+ if (mmix_elf_section_data (input_section)->pjs.stub_size[pjsno]
+ != 0)
+ {
+ Elf_Internal_Rela relcpy;
+
+ if (mmix_elf_section_data (input_section)
+ ->pjs.stub_size[pjsno] != MAX_PUSHJ_STUB_SIZE)
+ abort ();
+
+ /* There's already a PUSHJ insn there, so just fill in
+ the offset bits to the stub. */
+ if (mmix_final_link_relocate (elf_mmix_howto_table
+ + R_MMIX_ADDR19,
+ input_section,
+ contents,
+ rel->r_offset,
+ 0,
+ input_section
+ ->output_section->vma
+ + input_section->output_offset
+ + size
+ + mmix_elf_section_data (input_section)
+ ->pjs.stub_offset,
+ NULL, NULL, NULL) != bfd_reloc_ok)
+ return FALSE;
+
+ /* Put a JMP insn at the stub; it goes with the
+ R_MMIX_JMP reloc. */
+ bfd_put_32 (output_bfd, JMP_INSN_BYTE << 24,
+ contents
+ + size
+ + mmix_elf_section_data (input_section)
+ ->pjs.stub_offset);
+
+ /* Change the reloc to be at the stub, and to a full
+ R_MMIX_JMP reloc. */
+ rel->r_info = ELF64_R_INFO (r_symndx, R_MMIX_JMP);
+ rel->r_offset
+ = (size
+ + mmix_elf_section_data (input_section)
+ ->pjs.stub_offset);
+
+ mmix_elf_section_data (input_section)->pjs.stub_offset
+ += MAX_PUSHJ_STUB_SIZE;
+
+ /* Shift this reloc to the end of the relocs to maintain
+ the r_offset sorted reloc order. */
+ relcpy = *rel;
+ memmove (rel, rel + 1, (char *) relend - (char *) rel);
+ relend[-1] = relcpy;
+
+ /* Back up one reloc, or else we'd skip the next reloc
+ in turn. */
+ rel--;
+ }
+
+ pjsno++;
+ }
+ continue;
+ }
+
+ r = mmix_final_link_relocate (howto, input_section,
+ contents, rel->r_offset,
+ rel->r_addend, relocation, name, sec, NULL);
+
+ if (r != bfd_reloc_ok)
+ {
+ bfd_boolean check_ok = TRUE;
+ const char * msg = (const char *) NULL;
+
+ switch (r)
+ {
+ case bfd_reloc_overflow:
+ check_ok = info->callbacks->reloc_overflow
+ (info, (h ? &h->root : NULL), name, howto->name,
+ (bfd_vma) 0, input_bfd, input_section, rel->r_offset);
+ break;
+
+ case bfd_reloc_undefined:
+ /* We may have sent this message above. */
+ if (! undefined_signalled)
+ check_ok = info->callbacks->undefined_symbol
+ (info, name, input_bfd, input_section, rel->r_offset,
+ TRUE);
+ undefined_signalled = TRUE;
+ 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)
+ check_ok = info->callbacks->warning
+ (info, msg, name, input_bfd, input_section, rel->r_offset);
+
+ if (! check_ok)
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+/* Perform a single relocation. By default we use the standard BFD
+ routines. A few relocs we have to do ourselves. */
+
+static bfd_reloc_status_type
+mmix_final_link_relocate (reloc_howto_type *howto, asection *input_section,
+ bfd_byte *contents, bfd_vma r_offset,
+ bfd_signed_vma r_addend, bfd_vma relocation,
+ const char *symname, asection *symsec,
+ char **error_message)
+{
+ bfd_reloc_status_type r = bfd_reloc_ok;
+ bfd_vma addr
+ = (input_section->output_section->vma
+ + input_section->output_offset
+ + r_offset);
+ bfd_signed_vma srel
+ = (bfd_signed_vma) relocation + r_addend;
+
+ switch (howto->type)
+ {
+ /* All these are PC-relative. */
+ case R_MMIX_PUSHJ_STUBBABLE:
+ case R_MMIX_PUSHJ:
+ case R_MMIX_CBRANCH:
+ case R_MMIX_ADDR19:
+ case R_MMIX_GETA:
+ case R_MMIX_ADDR27:
+ case R_MMIX_JMP:
+ contents += r_offset;
+
+ srel -= (input_section->output_section->vma
+ + input_section->output_offset
+ + r_offset);
+
+ r = mmix_elf_perform_relocation (input_section, howto, contents,
+ addr, srel, error_message);
+ break;
+
+ case R_MMIX_BASE_PLUS_OFFSET:
+ if (symsec == NULL)
+ return bfd_reloc_undefined;
+
+ /* Check that we're not relocating against a register symbol. */
+ if (strcmp (bfd_get_section_name (symsec->owner, symsec),
+ MMIX_REG_CONTENTS_SECTION_NAME) == 0
+ || strcmp (bfd_get_section_name (symsec->owner, symsec),
+ MMIX_REG_SECTION_NAME) == 0)
+ {
+ /* Note: This is separated out into two messages in order
+ to ease the translation into other languages. */
+ if (symname == NULL || *symname == 0)
+ (*_bfd_error_handler)
+ (_("%s: base-plus-offset relocation against register symbol: (unknown) in %s"),
+ bfd_get_filename (input_section->owner),
+ bfd_get_section_name (symsec->owner, symsec));
+ else
+ (*_bfd_error_handler)
+ (_("%s: base-plus-offset relocation against register symbol: %s in %s"),
+ bfd_get_filename (input_section->owner), symname,
+ bfd_get_section_name (symsec->owner, symsec));
+ return bfd_reloc_overflow;
+ }
+ goto do_mmix_reloc;
+
+ case R_MMIX_REG_OR_BYTE:
+ case R_MMIX_REG:
+ /* For now, we handle these alike. They must refer to an register
+ symbol, which is either relative to the register section and in
+ the range 0..255, or is in the register contents section with vma
+ regno * 8. */
+
+ /* FIXME: A better way to check for reg contents section?
+ FIXME: Postpone section->scaling to mmix_elf_perform_relocation? */
+ if (symsec == NULL)
+ return bfd_reloc_undefined;
+
+ if (strcmp (bfd_get_section_name (symsec->owner, symsec),
+ MMIX_REG_CONTENTS_SECTION_NAME) == 0)
+ {
+ if ((srel & 7) != 0 || srel < 32*8 || srel > 255*8)
+ {
+ /* The bfd_reloc_outofrange return value, though intuitively
+ a better value, will not get us an error. */
+ return bfd_reloc_overflow;
+ }
+ srel /= 8;
+ }
+ else if (strcmp (bfd_get_section_name (symsec->owner, symsec),
+ MMIX_REG_SECTION_NAME) == 0)
+ {
+ if (srel < 0 || srel > 255)
+ /* The bfd_reloc_outofrange return value, though intuitively a
+ better value, will not get us an error. */
+ return bfd_reloc_overflow;
+ }
+ else
+ {
+ /* Note: This is separated out into two messages in order
+ to ease the translation into other languages. */
+ if (symname == NULL || *symname == 0)
+ (*_bfd_error_handler)
+ (_("%s: register relocation against non-register symbol: (unknown) in %s"),
+ bfd_get_filename (input_section->owner),
+ bfd_get_section_name (symsec->owner, symsec));
+ else
+ (*_bfd_error_handler)
+ (_("%s: register relocation against non-register symbol: %s in %s"),
+ bfd_get_filename (input_section->owner), symname,
+ bfd_get_section_name (symsec->owner, symsec));
+
+ /* The bfd_reloc_outofrange return value, though intuitively a
+ better value, will not get us an error. */
+ return bfd_reloc_overflow;
+ }
+ do_mmix_reloc:
+ contents += r_offset;
+ r = mmix_elf_perform_relocation (input_section, howto, contents,
+ addr, srel, error_message);
+ break;
+
+ case R_MMIX_LOCAL:
+ /* This isn't a real relocation, it's just an assertion that the
+ final relocation value corresponds to a local register. We
+ ignore the actual relocation; nothing is changed. */
+ {
+ asection *regsec
+ = bfd_get_section_by_name (input_section->output_section->owner,
+ MMIX_REG_CONTENTS_SECTION_NAME);
+ bfd_vma first_global;
+
+ /* Check that this is an absolute value, or a reference to the
+ register contents section or the register (symbol) section.
+ Absolute numbers can get here as undefined section. Undefined
+ symbols are signalled elsewhere, so there's no conflict in us
+ accidentally handling it. */
+ if (!bfd_is_abs_section (symsec)
+ && !bfd_is_und_section (symsec)
+ && strcmp (bfd_get_section_name (symsec->owner, symsec),
+ MMIX_REG_CONTENTS_SECTION_NAME) != 0
+ && strcmp (bfd_get_section_name (symsec->owner, symsec),
+ MMIX_REG_SECTION_NAME) != 0)
+ {
+ (*_bfd_error_handler)
+ (_("%s: directive LOCAL valid only with a register or absolute value"),
+ bfd_get_filename (input_section->owner));
+
+ return bfd_reloc_overflow;
+ }
+
+ /* If we don't have a register contents section, then $255 is the
+ first global register. */
+ if (regsec == NULL)
+ first_global = 255;
+ else
+ {
+ first_global
+ = bfd_get_section_vma (input_section->output_section->owner,
+ regsec) / 8;
+ if (strcmp (bfd_get_section_name (symsec->owner, symsec),
+ MMIX_REG_CONTENTS_SECTION_NAME) == 0)
+ {
+ if ((srel & 7) != 0 || srel < 32*8 || srel > 255*8)
+ /* The bfd_reloc_outofrange return value, though
+ intuitively a better value, will not get us an error. */
+ return bfd_reloc_overflow;
+ srel /= 8;
+ }
+ }
+
+ if ((bfd_vma) srel >= first_global)
+ {
+ /* FIXME: Better error message. */
+ (*_bfd_error_handler)
+ (_("%s: LOCAL directive: Register $%ld is not a local register. First global register is $%ld."),
+ bfd_get_filename (input_section->owner), (long) srel, (long) first_global);
+
+ return bfd_reloc_overflow;
+ }
+ }
+ r = bfd_reloc_ok;
+ break;
+
+ default:
+ r = _bfd_final_link_relocate (howto, input_section->owner, input_section,
+ contents, r_offset,
+ relocation, r_addend);
+ }
+
+ return r;
+}
+
+/* Return the section that should be marked against GC for a given
+ relocation. */
+
+static asection *
+mmix_elf_gc_mark_hook (asection *sec,
+ struct bfd_link_info *info,
+ Elf_Internal_Rela *rel,
+ struct elf_link_hash_entry *h,
+ Elf_Internal_Sym *sym)
+{
+ if (h != NULL)
+ switch (ELF64_R_TYPE (rel->r_info))
+ {
+ case R_MMIX_GNU_VTINHERIT:
+ case R_MMIX_GNU_VTENTRY:
+ return NULL;
+ }
+
+ return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
+}
+
+/* Update relocation info for a GC-excluded section. We could supposedly
+ perform the allocation after GC, but there's no suitable hook between
+ GC (or section merge) and the point when all input sections must be
+ present. Better to waste some memory and (perhaps) a little time. */
+
+static bfd_boolean
+mmix_elf_gc_sweep_hook (bfd *abfd ATTRIBUTE_UNUSED,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ asection *sec,
+ const Elf_Internal_Rela *relocs ATTRIBUTE_UNUSED)
+{
+ struct bpo_reloc_section_info *bpodata
+ = mmix_elf_section_data (sec)->bpo.reloc;
+ asection *allocated_gregs_section;
+
+ /* If no bpodata here, we have nothing to do. */
+ if (bpodata == NULL)
+ return TRUE;
+
+ allocated_gregs_section = bpodata->bpo_greg_section;
+
+ mmix_elf_section_data (allocated_gregs_section)->bpo.greg->n_bpo_relocs
+ -= bpodata->n_bpo_relocs_this_section;
+
+ return TRUE;
+}
+
+/* Sort register relocs to come before expanding relocs. */
+
+static int
+mmix_elf_sort_relocs (const void * p1, const void * p2)
+{
+ const Elf_Internal_Rela *r1 = (const Elf_Internal_Rela *) p1;
+ const Elf_Internal_Rela *r2 = (const Elf_Internal_Rela *) p2;
+ int r1_is_reg, r2_is_reg;
+
+ /* Sort primarily on r_offset & ~3, so relocs are done to consecutive
+ insns. */
+ if ((r1->r_offset & ~(bfd_vma) 3) > (r2->r_offset & ~(bfd_vma) 3))
+ return 1;
+ else if ((r1->r_offset & ~(bfd_vma) 3) < (r2->r_offset & ~(bfd_vma) 3))
+ return -1;
+
+ r1_is_reg
+ = (ELF64_R_TYPE (r1->r_info) == R_MMIX_REG_OR_BYTE
+ || ELF64_R_TYPE (r1->r_info) == R_MMIX_REG);
+ r2_is_reg
+ = (ELF64_R_TYPE (r2->r_info) == R_MMIX_REG_OR_BYTE
+ || ELF64_R_TYPE (r2->r_info) == R_MMIX_REG);
+ if (r1_is_reg != r2_is_reg)
+ return r2_is_reg - r1_is_reg;
+
+ /* Neither or both are register relocs. Then sort on full offset. */
+ if (r1->r_offset > r2->r_offset)
+ return 1;
+ else if (r1->r_offset < r2->r_offset)
+ return -1;
+ return 0;
+}
+
+/* Subset of mmix_elf_check_relocs, common to ELF and mmo linking. */
+
+static bfd_boolean
+mmix_elf_check_common_relocs (bfd *abfd,
+ struct bfd_link_info *info,
+ asection *sec,
+ const Elf_Internal_Rela *relocs)
+{
+ bfd *bpo_greg_owner = NULL;
+ asection *allocated_gregs_section = NULL;
+ struct bpo_greg_section_info *gregdata = NULL;
+ struct bpo_reloc_section_info *bpodata = NULL;
+ const Elf_Internal_Rela *rel;
+ const Elf_Internal_Rela *rel_end;
+
+ /* We currently have to abuse this COFF-specific member, since there's
+ no target-machine-dedicated member. There's no alternative outside
+ the bfd_link_info struct; we can't specialize a hash-table since
+ they're different between ELF and mmo. */
+ bpo_greg_owner = (bfd *) info->base_file;
+
+ rel_end = relocs + sec->reloc_count;
+ for (rel = relocs; rel < rel_end; rel++)
+ {
+ switch (ELF64_R_TYPE (rel->r_info))
+ {
+ /* This relocation causes a GREG allocation. We need to count
+ them, and we need to create a section for them, so we need an
+ object to fake as the owner of that section. We can't use
+ the ELF dynobj for this, since the ELF bits assume lots of
+ DSO-related stuff if that member is non-NULL. */
+ case R_MMIX_BASE_PLUS_OFFSET:
+ /* We don't do anything with this reloc for a relocatable link. */
+ if (info->relocatable)
+ break;
+
+ if (bpo_greg_owner == NULL)
+ {
+ bpo_greg_owner = abfd;
+ info->base_file = bpo_greg_owner;
+ }
+
+ if (allocated_gregs_section == NULL)
+ allocated_gregs_section
+ = bfd_get_section_by_name (bpo_greg_owner,
+ MMIX_LD_ALLOCATED_REG_CONTENTS_SECTION_NAME);
+
+ if (allocated_gregs_section == NULL)
+ {
+ allocated_gregs_section
+ = bfd_make_section_with_flags (bpo_greg_owner,
+ MMIX_LD_ALLOCATED_REG_CONTENTS_SECTION_NAME,
+ (SEC_HAS_CONTENTS
+ | SEC_IN_MEMORY
+ | SEC_LINKER_CREATED));
+ /* Setting both SEC_ALLOC and SEC_LOAD means the section is
+ treated like any other section, and we'd get errors for
+ address overlap with the text section. Let's set none of
+ those flags, as that is what currently happens for usual
+ GREG allocations, and that works. */
+ if (allocated_gregs_section == NULL
+ || !bfd_set_section_alignment (bpo_greg_owner,
+ allocated_gregs_section,
+ 3))
+ return FALSE;
+
+ gregdata = (struct bpo_greg_section_info *)
+ bfd_zalloc (bpo_greg_owner, sizeof (struct bpo_greg_section_info));
+ if (gregdata == NULL)
+ return FALSE;
+ mmix_elf_section_data (allocated_gregs_section)->bpo.greg
+ = gregdata;
+ }
+ else if (gregdata == NULL)
+ gregdata
+ = mmix_elf_section_data (allocated_gregs_section)->bpo.greg;
+
+ /* Get ourselves some auxiliary info for the BPO-relocs. */
+ if (bpodata == NULL)
+ {
+ /* No use doing a separate iteration pass to find the upper
+ limit - just use the number of relocs. */
+ bpodata = (struct bpo_reloc_section_info *)
+ bfd_alloc (bpo_greg_owner,
+ sizeof (struct bpo_reloc_section_info)
+ * (sec->reloc_count + 1));
+ if (bpodata == NULL)
+ return FALSE;
+ mmix_elf_section_data (sec)->bpo.reloc = bpodata;
+ bpodata->first_base_plus_offset_reloc
+ = bpodata->bpo_index
+ = gregdata->n_max_bpo_relocs;
+ bpodata->bpo_greg_section
+ = allocated_gregs_section;
+ bpodata->n_bpo_relocs_this_section = 0;
+ }
+
+ bpodata->n_bpo_relocs_this_section++;
+ gregdata->n_max_bpo_relocs++;
+
+ /* We don't get another chance to set this before GC; we've not
+ set up any hook that runs before GC. */
+ gregdata->n_bpo_relocs
+ = gregdata->n_max_bpo_relocs;
+ break;
+
+ case R_MMIX_PUSHJ_STUBBABLE:
+ mmix_elf_section_data (sec)->pjs.n_pushj_relocs++;
+ break;
+ }
+ }
+
+ /* Allocate per-reloc stub storage and initialize it to the max stub
+ size. */
+ if (mmix_elf_section_data (sec)->pjs.n_pushj_relocs != 0)
+ {
+ size_t i;
+
+ mmix_elf_section_data (sec)->pjs.stub_size
+ = bfd_alloc (abfd, mmix_elf_section_data (sec)->pjs.n_pushj_relocs
+ * sizeof (mmix_elf_section_data (sec)
+ ->pjs.stub_size[0]));
+ if (mmix_elf_section_data (sec)->pjs.stub_size == NULL)
+ return FALSE;
+
+ for (i = 0; i < mmix_elf_section_data (sec)->pjs.n_pushj_relocs; i++)
+ mmix_elf_section_data (sec)->pjs.stub_size[i] = MAX_PUSHJ_STUB_SIZE;
+ }
+
+ return TRUE;
+}
+
+/* Look through the relocs for a section during the first phase. */
+
+static bfd_boolean
+mmix_elf_check_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;
+ const Elf_Internal_Rela *rel;
+ const Elf_Internal_Rela *rel_end;
+
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+ sym_hashes = elf_sym_hashes (abfd);
+
+ /* First we sort the relocs so that any register relocs come before
+ expansion-relocs to the same insn. FIXME: Not done for mmo. */
+ qsort ((void *) relocs, sec->reloc_count, sizeof (Elf_Internal_Rela),
+ mmix_elf_sort_relocs);
+
+ /* Do the common part. */
+ if (!mmix_elf_check_common_relocs (abfd, info, sec, relocs))
+ return FALSE;
+
+ if (info->relocatable)
+ return TRUE;
+
+ 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 = 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.type == bfd_link_hash_indirect
+ || h->root.type == bfd_link_hash_warning)
+ h = (struct elf_link_hash_entry *) h->root.u.i.link;
+
+ /* PR15323, ref flags aren't set for references in the same
+ object. */
+ h->root.non_ir_ref = 1;
+ }
+
+ switch (ELF64_R_TYPE (rel->r_info))
+ {
+ /* This relocation describes the C++ object vtable hierarchy.
+ Reconstruct it for later use during GC. */
+ case R_MMIX_GNU_VTINHERIT:
+ if (!bfd_elf_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_MMIX_GNU_VTENTRY:
+ BFD_ASSERT (h != NULL);
+ if (h != NULL
+ && !bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
+ return FALSE;
+ break;
+ }
+ }
+
+ return TRUE;
+}
+
+/* Wrapper for mmix_elf_check_common_relocs, called when linking to mmo.
+ Copied from elf_link_add_object_symbols. */
+
+bfd_boolean
+_bfd_mmix_check_all_relocs (bfd *abfd, struct bfd_link_info *info)
+{
+ asection *o;
+
+ for (o = abfd->sections; o != NULL; o = o->next)
+ {
+ Elf_Internal_Rela *internal_relocs;
+ bfd_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
+ = _bfd_elf_link_read_relocs (abfd, o, NULL,
+ (Elf_Internal_Rela *) NULL,
+ info->keep_memory);
+ if (internal_relocs == NULL)
+ return FALSE;
+
+ ok = mmix_elf_check_common_relocs (abfd, info, o, internal_relocs);
+
+ if (! info->keep_memory)
+ free (internal_relocs);
+
+ if (! ok)
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/* Change symbols relative to the reg contents section to instead be to
+ the register section, and scale them down to correspond to the register
+ number. */
+
+static int
+mmix_elf_link_output_symbol_hook (struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ const char *name ATTRIBUTE_UNUSED,
+ Elf_Internal_Sym *sym,
+ asection *input_sec,
+ struct elf_link_hash_entry *h ATTRIBUTE_UNUSED)
+{
+ if (input_sec != NULL
+ && input_sec->name != NULL
+ && ELF_ST_TYPE (sym->st_info) != STT_SECTION
+ && strcmp (input_sec->name, MMIX_REG_CONTENTS_SECTION_NAME) == 0)
+ {
+ sym->st_value /= 8;
+ sym->st_shndx = SHN_REGISTER;
+ }
+
+ return 1;
+}
+
+/* We fake a register section that holds values that are register numbers.
+ Having a SHN_REGISTER and register section translates better to other
+ formats (e.g. mmo) than for example a STT_REGISTER attribute.
+ This section faking is based on a construct in elf32-mips.c. */
+static asection mmix_elf_reg_section;
+static asymbol mmix_elf_reg_section_symbol;
+static asymbol *mmix_elf_reg_section_symbol_ptr;
+
+/* Handle the special section numbers that a symbol may use. */
+
+void
+mmix_elf_symbol_processing (abfd, asym)
+ bfd *abfd ATTRIBUTE_UNUSED;
+ asymbol *asym;
+{
+ elf_symbol_type *elfsym;
+
+ elfsym = (elf_symbol_type *) asym;
+ switch (elfsym->internal_elf_sym.st_shndx)
+ {
+ case SHN_REGISTER:
+ if (mmix_elf_reg_section.name == NULL)
+ {
+ /* Initialize the register section. */
+ mmix_elf_reg_section.name = MMIX_REG_SECTION_NAME;
+ mmix_elf_reg_section.flags = SEC_NO_FLAGS;
+ mmix_elf_reg_section.output_section = &mmix_elf_reg_section;
+ mmix_elf_reg_section.symbol = &mmix_elf_reg_section_symbol;
+ mmix_elf_reg_section.symbol_ptr_ptr = &mmix_elf_reg_section_symbol_ptr;
+ mmix_elf_reg_section_symbol.name = MMIX_REG_SECTION_NAME;
+ mmix_elf_reg_section_symbol.flags = BSF_SECTION_SYM;
+ mmix_elf_reg_section_symbol.section = &mmix_elf_reg_section;
+ mmix_elf_reg_section_symbol_ptr = &mmix_elf_reg_section_symbol;
+ }
+ asym->section = &mmix_elf_reg_section;
+ break;
+
+ default:
+ break;
+ }
+}
+
+/* Given a BFD section, try to locate the corresponding ELF section
+ index. */
+
+static bfd_boolean
+mmix_elf_section_from_bfd_section (bfd * abfd ATTRIBUTE_UNUSED,
+ asection * sec,
+ int * retval)
+{
+ if (strcmp (bfd_get_section_name (abfd, sec), MMIX_REG_SECTION_NAME) == 0)
+ *retval = SHN_REGISTER;
+ else
+ return FALSE;
+
+ return TRUE;
+}
+
+/* Hook called by the linker routine which adds symbols from an object
+ file. We must handle the special SHN_REGISTER section number here.
+
+ We also check that we only have *one* each of the section-start
+ symbols, since otherwise having two with the same value would cause
+ them to be "merged", but with the contents serialized. */
+
+static bfd_boolean
+mmix_elf_add_symbol_hook (bfd *abfd,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ Elf_Internal_Sym *sym,
+ const char **namep ATTRIBUTE_UNUSED,
+ flagword *flagsp ATTRIBUTE_UNUSED,
+ asection **secp,
+ bfd_vma *valp ATTRIBUTE_UNUSED)
+{
+ if (sym->st_shndx == SHN_REGISTER)
+ {
+ *secp = bfd_make_section_old_way (abfd, MMIX_REG_SECTION_NAME);
+ (*secp)->flags |= SEC_LINKER_CREATED;
+ }
+ else if ((*namep)[0] == '_' && (*namep)[1] == '_' && (*namep)[2] == '.'
+ && CONST_STRNEQ (*namep, MMIX_LOC_SECTION_START_SYMBOL_PREFIX))
+ {
+ /* See if we have another one. */
+ struct bfd_link_hash_entry *h = bfd_link_hash_lookup (info->hash,
+ *namep,
+ FALSE,
+ FALSE,
+ FALSE);
+
+ if (h != NULL && h->type != bfd_link_hash_undefined)
+ {
+ /* How do we get the asymbol (or really: the filename) from h?
+ h->u.def.section->owner is NULL. */
+ ((*_bfd_error_handler)
+ (_("%s: Error: multiple definition of `%s'; start of %s is set in a earlier linked file\n"),
+ bfd_get_filename (abfd), *namep,
+ *namep + strlen (MMIX_LOC_SECTION_START_SYMBOL_PREFIX)));
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+/* We consider symbols matching "L.*:[0-9]+" to be local symbols. */
+
+static bfd_boolean
+mmix_elf_is_local_label_name (bfd *abfd, const char *name)
+{
+ const char *colpos;
+ int digits;
+
+ /* Also include the default local-label definition. */
+ if (_bfd_elf_is_local_label_name (abfd, name))
+ return TRUE;
+
+ if (*name != 'L')
+ return FALSE;
+
+ /* If there's no ":", or more than one, it's not a local symbol. */
+ colpos = strchr (name, ':');
+ if (colpos == NULL || strchr (colpos + 1, ':') != NULL)
+ return FALSE;
+
+ /* Check that there are remaining characters and that they are digits. */
+ if (colpos[1] == 0)
+ return FALSE;
+
+ digits = strspn (colpos + 1, "0123456789");
+ return digits != 0 && colpos[1 + digits] == 0;
+}
+
+/* We get rid of the register section here. */
+
+bfd_boolean
+mmix_elf_final_link (bfd *abfd, struct bfd_link_info *info)
+{
+ /* We never output a register section, though we create one for
+ temporary measures. Check that nobody entered contents into it. */
+ asection *reg_section;
+
+ reg_section = bfd_get_section_by_name (abfd, MMIX_REG_SECTION_NAME);
+
+ if (reg_section != NULL)
+ {
+ /* FIXME: Pass error state gracefully. */
+ if (bfd_get_section_flags (abfd, reg_section) & SEC_HAS_CONTENTS)
+ _bfd_abort (__FILE__, __LINE__, _("Register section has contents\n"));
+
+ /* Really remove the section, if it hasn't already been done. */
+ if (!bfd_section_removed_from_list (abfd, reg_section))
+ {
+ bfd_section_list_remove (abfd, reg_section);
+ --abfd->section_count;
+ }
+ }
+
+ if (! bfd_elf_final_link (abfd, info))
+ return FALSE;
+
+ /* Since this section is marked SEC_LINKER_CREATED, it isn't output by
+ the regular linker machinery. We do it here, like other targets with
+ special sections. */
+ if (info->base_file != NULL)
+ {
+ asection *greg_section
+ = bfd_get_section_by_name ((bfd *) info->base_file,
+ MMIX_LD_ALLOCATED_REG_CONTENTS_SECTION_NAME);
+ if (!bfd_set_section_contents (abfd,
+ greg_section->output_section,
+ greg_section->contents,
+ (file_ptr) greg_section->output_offset,
+ greg_section->size))
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/* We need to include the maximum size of PUSHJ-stubs in the initial
+ section size. This is expected to shrink during linker relaxation. */
+
+static void
+mmix_set_relaxable_size (bfd *abfd ATTRIBUTE_UNUSED,
+ asection *sec,
+ void *ptr)
+{
+ struct bfd_link_info *info = ptr;
+
+ /* Make sure we only do this for section where we know we want this,
+ otherwise we might end up resetting the size of COMMONs. */
+ if (mmix_elf_section_data (sec)->pjs.n_pushj_relocs == 0)
+ return;
+
+ sec->rawsize = sec->size;
+ sec->size += (mmix_elf_section_data (sec)->pjs.n_pushj_relocs
+ * MAX_PUSHJ_STUB_SIZE);
+
+ /* For use in relocatable link, we start with a max stubs size. See
+ mmix_elf_relax_section. */
+ if (info->relocatable && sec->output_section)
+ mmix_elf_section_data (sec->output_section)->pjs.stubs_size_sum
+ += (mmix_elf_section_data (sec)->pjs.n_pushj_relocs
+ * MAX_PUSHJ_STUB_SIZE);
+}
+
+/* Initialize stuff for the linker-generated GREGs to match
+ R_MMIX_BASE_PLUS_OFFSET relocs seen by the linker. */
+
+bfd_boolean
+_bfd_mmix_before_linker_allocation (bfd *abfd ATTRIBUTE_UNUSED,
+ struct bfd_link_info *info)
+{
+ asection *bpo_gregs_section;
+ bfd *bpo_greg_owner;
+ struct bpo_greg_section_info *gregdata;
+ size_t n_gregs;
+ bfd_vma gregs_size;
+ size_t i;
+ size_t *bpo_reloc_indexes;
+ bfd *ibfd;
+
+ /* Set the initial size of sections. */
+ for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next)
+ bfd_map_over_sections (ibfd, mmix_set_relaxable_size, info);
+
+ /* The bpo_greg_owner bfd is supposed to have been set by
+ mmix_elf_check_relocs when the first R_MMIX_BASE_PLUS_OFFSET is seen.
+ If there is no such object, there was no R_MMIX_BASE_PLUS_OFFSET. */
+ bpo_greg_owner = (bfd *) info->base_file;
+ if (bpo_greg_owner == NULL)
+ return TRUE;
+
+ bpo_gregs_section
+ = bfd_get_section_by_name (bpo_greg_owner,
+ MMIX_LD_ALLOCATED_REG_CONTENTS_SECTION_NAME);
+
+ if (bpo_gregs_section == NULL)
+ return TRUE;
+
+ /* We use the target-data handle in the ELF section data. */
+ gregdata = mmix_elf_section_data (bpo_gregs_section)->bpo.greg;
+ if (gregdata == NULL)
+ return FALSE;
+
+ n_gregs = gregdata->n_bpo_relocs;
+ gregdata->n_allocated_bpo_gregs = n_gregs;
+
+ /* When this reaches zero during relaxation, all entries have been
+ filled in and the size of the linker gregs can be calculated. */
+ gregdata->n_remaining_bpo_relocs_this_relaxation_round = n_gregs;
+
+ /* Set the zeroth-order estimate for the GREGs size. */
+ gregs_size = n_gregs * 8;
+
+ if (!bfd_set_section_size (bpo_greg_owner, bpo_gregs_section, gregs_size))
+ return FALSE;
+
+ /* Allocate and set up the GREG arrays. They're filled in at relaxation
+ time. Note that we must use the max number ever noted for the array,
+ since the index numbers were created before GC. */
+ gregdata->reloc_request
+ = bfd_zalloc (bpo_greg_owner,
+ sizeof (struct bpo_reloc_request)
+ * gregdata->n_max_bpo_relocs);
+
+ gregdata->bpo_reloc_indexes
+ = bpo_reloc_indexes
+ = bfd_alloc (bpo_greg_owner,
+ gregdata->n_max_bpo_relocs
+ * sizeof (size_t));
+ if (bpo_reloc_indexes == NULL)
+ return FALSE;
+
+ /* The default order is an identity mapping. */
+ for (i = 0; i < gregdata->n_max_bpo_relocs; i++)
+ {
+ bpo_reloc_indexes[i] = i;
+ gregdata->reloc_request[i].bpo_reloc_no = i;
+ }
+
+ return TRUE;
+}
+
+/* Fill in contents in the linker allocated gregs. Everything is
+ calculated at this point; we just move the contents into place here. */
+
+bfd_boolean
+_bfd_mmix_after_linker_allocation (bfd *abfd ATTRIBUTE_UNUSED,
+ struct bfd_link_info *link_info)
+{
+ asection *bpo_gregs_section;
+ bfd *bpo_greg_owner;
+ struct bpo_greg_section_info *gregdata;
+ size_t n_gregs;
+ size_t i, j;
+ size_t lastreg;
+ bfd_byte *contents;
+
+ /* The bpo_greg_owner bfd is supposed to have been set by mmix_elf_check_relocs
+ when the first R_MMIX_BASE_PLUS_OFFSET is seen. If there is no such
+ object, there was no R_MMIX_BASE_PLUS_OFFSET. */
+ bpo_greg_owner = (bfd *) link_info->base_file;
+ if (bpo_greg_owner == NULL)
+ return TRUE;
+
+ bpo_gregs_section
+ = bfd_get_section_by_name (bpo_greg_owner,
+ MMIX_LD_ALLOCATED_REG_CONTENTS_SECTION_NAME);
+
+ /* This can't happen without DSO handling. When DSOs are handled
+ without any R_MMIX_BASE_PLUS_OFFSET seen, there will be no such
+ section. */
+ if (bpo_gregs_section == NULL)
+ return TRUE;
+
+ /* We use the target-data handle in the ELF section data. */
+
+ gregdata = mmix_elf_section_data (bpo_gregs_section)->bpo.greg;
+ if (gregdata == NULL)
+ return FALSE;
+
+ n_gregs = gregdata->n_allocated_bpo_gregs;
+
+ bpo_gregs_section->contents
+ = contents = bfd_alloc (bpo_greg_owner, bpo_gregs_section->size);
+ if (contents == NULL)
+ return FALSE;
+
+ /* Sanity check: If these numbers mismatch, some relocation has not been
+ accounted for and the rest of gregdata is probably inconsistent.
+ It's a bug, but it's more helpful to identify it than segfaulting
+ below. */
+ if (gregdata->n_remaining_bpo_relocs_this_relaxation_round
+ != gregdata->n_bpo_relocs)
+ {
+ (*_bfd_error_handler)
+ (_("Internal inconsistency: remaining %u != max %u.\n\
+ Please report this bug."),
+ gregdata->n_remaining_bpo_relocs_this_relaxation_round,
+ gregdata->n_bpo_relocs);
+ return FALSE;
+ }
+
+ for (lastreg = 255, i = 0, j = 0; j < n_gregs; i++)
+ if (gregdata->reloc_request[i].regindex != lastreg)
+ {
+ bfd_put_64 (bpo_greg_owner, gregdata->reloc_request[i].value,
+ contents + j * 8);
+ lastreg = gregdata->reloc_request[i].regindex;
+ j++;
+ }
+
+ return TRUE;
+}
+
+/* Sort valid relocs to come before non-valid relocs, then on increasing
+ value. */
+
+static int
+bpo_reloc_request_sort_fn (const void * p1, const void * p2)
+{
+ const struct bpo_reloc_request *r1 = (const struct bpo_reloc_request *) p1;
+ const struct bpo_reloc_request *r2 = (const struct bpo_reloc_request *) p2;
+
+ /* Primary function is validity; non-valid relocs sorted after valid
+ ones. */
+ if (r1->valid != r2->valid)
+ return r2->valid - r1->valid;
+
+ /* Then sort on value. Don't simplify and return just the difference of
+ the values: the upper bits of the 64-bit value would be truncated on
+ a host with 32-bit ints. */
+ if (r1->value != r2->value)
+ return r1->value > r2->value ? 1 : -1;
+
+ /* As a last re-sort, use the relocation number, so we get a stable
+ sort. The *addresses* aren't stable since items are swapped during
+ sorting. It depends on the qsort implementation if this actually
+ happens. */
+ return r1->bpo_reloc_no > r2->bpo_reloc_no
+ ? 1 : (r1->bpo_reloc_no < r2->bpo_reloc_no ? -1 : 0);
+}
+
+/* For debug use only. Dumps the global register allocations resulting
+ from base-plus-offset relocs. */
+
+void
+mmix_dump_bpo_gregs (link_info, pf)
+ struct bfd_link_info *link_info;
+ bfd_error_handler_type pf;
+{
+ bfd *bpo_greg_owner;
+ asection *bpo_gregs_section;
+ struct bpo_greg_section_info *gregdata;
+ unsigned int i;
+
+ if (link_info == NULL || link_info->base_file == NULL)
+ return;
+
+ bpo_greg_owner = (bfd *) link_info->base_file;
+
+ bpo_gregs_section
+ = bfd_get_section_by_name (bpo_greg_owner,
+ MMIX_LD_ALLOCATED_REG_CONTENTS_SECTION_NAME);
+
+ if (bpo_gregs_section == NULL)
+ return;
+
+ gregdata = mmix_elf_section_data (bpo_gregs_section)->bpo.greg;
+ if (gregdata == NULL)
+ return;
+
+ if (pf == NULL)
+ pf = _bfd_error_handler;
+
+ /* These format strings are not translated. They are for debug purposes
+ only and never displayed to an end user. Should they escape, we
+ surely want them in original. */
+ (*pf) (" n_bpo_relocs: %u\n n_max_bpo_relocs: %u\n n_remain...round: %u\n\
+ n_allocated_bpo_gregs: %u\n", gregdata->n_bpo_relocs,
+ gregdata->n_max_bpo_relocs,
+ gregdata->n_remaining_bpo_relocs_this_relaxation_round,
+ gregdata->n_allocated_bpo_gregs);
+
+ if (gregdata->reloc_request)
+ for (i = 0; i < gregdata->n_max_bpo_relocs; i++)
+ (*pf) ("%4u (%4u)/%4u#%u: 0x%08lx%08lx r: %3u o: %3u\n",
+ i,
+ (gregdata->bpo_reloc_indexes != NULL
+ ? gregdata->bpo_reloc_indexes[i] : (size_t) -1),
+ gregdata->reloc_request[i].bpo_reloc_no,
+ gregdata->reloc_request[i].valid,
+
+ (unsigned long) (gregdata->reloc_request[i].value >> 32),
+ (unsigned long) gregdata->reloc_request[i].value,
+ gregdata->reloc_request[i].regindex,
+ gregdata->reloc_request[i].offset);
+}
+
+/* This links all R_MMIX_BASE_PLUS_OFFSET relocs into a special array, and
+ when the last such reloc is done, an index-array is sorted according to
+ the values and iterated over to produce register numbers (indexed by 0
+ from the first allocated register number) and offsets for use in real
+ relocation. (N.B.: Relocatable runs are handled, not just punted.)
+
+ PUSHJ stub accounting is also done here.
+
+ Symbol- and reloc-reading infrastructure copied from elf-m10200.c. */
+
+static bfd_boolean
+mmix_elf_relax_section (bfd *abfd,
+ asection *sec,
+ struct bfd_link_info *link_info,
+ bfd_boolean *again)
+{
+ Elf_Internal_Shdr *symtab_hdr;
+ Elf_Internal_Rela *internal_relocs;
+ Elf_Internal_Rela *irel, *irelend;
+ asection *bpo_gregs_section = NULL;
+ struct bpo_greg_section_info *gregdata;
+ struct bpo_reloc_section_info *bpodata
+ = mmix_elf_section_data (sec)->bpo.reloc;
+ /* The initialization is to quiet compiler warnings. The value is to
+ spot a missing actual initialization. */
+ size_t bpono = (size_t) -1;
+ size_t pjsno = 0;
+ Elf_Internal_Sym *isymbuf = NULL;
+ bfd_size_type size = sec->rawsize ? sec->rawsize : sec->size;
+
+ mmix_elf_section_data (sec)->pjs.stubs_size_sum = 0;
+
+ /* Assume nothing changes. */
+ *again = FALSE;
+
+ /* We don't have to do anything if this section does not have relocs, or
+ if this is not a code section. */
+ if ((sec->flags & SEC_RELOC) == 0
+ || sec->reloc_count == 0
+ || (sec->flags & SEC_CODE) == 0
+ || (sec->flags & SEC_LINKER_CREATED) != 0
+ /* If no R_MMIX_BASE_PLUS_OFFSET relocs and no PUSHJ-stub relocs,
+ then nothing to do. */
+ || (bpodata == NULL
+ && mmix_elf_section_data (sec)->pjs.n_pushj_relocs == 0))
+ return TRUE;
+
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+
+ if (bpodata != NULL)
+ {
+ bpo_gregs_section = bpodata->bpo_greg_section;
+ gregdata = mmix_elf_section_data (bpo_gregs_section)->bpo.greg;
+ bpono = bpodata->first_base_plus_offset_reloc;
+ }
+ else
+ gregdata = NULL;
+
+ /* Get a copy of the native relocations. */
+ internal_relocs
+ = _bfd_elf_link_read_relocs (abfd, sec, NULL,
+ (Elf_Internal_Rela *) NULL,
+ link_info->keep_memory);
+ if (internal_relocs == NULL)
+ goto error_return;
+
+ /* Walk through them looking for relaxing opportunities. */
+ irelend = internal_relocs + sec->reloc_count;
+ for (irel = internal_relocs; irel < irelend; irel++)
+ {
+ bfd_vma symval;
+ struct elf_link_hash_entry *h = NULL;
+
+ /* We only process two relocs. */
+ if (ELF64_R_TYPE (irel->r_info) != (int) R_MMIX_BASE_PLUS_OFFSET
+ && ELF64_R_TYPE (irel->r_info) != (int) R_MMIX_PUSHJ_STUBBABLE)
+ continue;
+
+ /* We process relocs in a distinctly different way when this is a
+ relocatable link (for one, we don't look at symbols), so we avoid
+ mixing its code with that for the "normal" relaxation. */
+ if (link_info->relocatable)
+ {
+ /* The only transformation in a relocatable link is to generate
+ a full stub at the location of the stub calculated for the
+ input section, if the relocated stub location, the end of the
+ output section plus earlier stubs, cannot be reached. Thus
+ relocatable linking can only lead to worse code, but it still
+ works. */
+ if (ELF64_R_TYPE (irel->r_info) == R_MMIX_PUSHJ_STUBBABLE)
+ {
+ /* If we can reach the end of the output-section and beyond
+ any current stubs, then we don't need a stub for this
+ reloc. The relaxed order of output stub allocation may
+ not exactly match the straightforward order, so we always
+ assume presence of output stubs, which will allow
+ relaxation only on relocations indifferent to the
+ presence of output stub allocations for other relocations
+ and thus the order of output stub allocation. */
+ if (bfd_check_overflow (complain_overflow_signed,
+ 19,
+ 0,
+ bfd_arch_bits_per_address (abfd),
+ /* Output-stub location. */
+ sec->output_section->rawsize
+ + (mmix_elf_section_data (sec
+ ->output_section)
+ ->pjs.stubs_size_sum)
+ /* Location of this PUSHJ reloc. */
+ - (sec->output_offset + irel->r_offset)
+ /* Don't count *this* stub twice. */
+ - (mmix_elf_section_data (sec)
+ ->pjs.stub_size[pjsno]
+ + MAX_PUSHJ_STUB_SIZE))
+ == bfd_reloc_ok)
+ mmix_elf_section_data (sec)->pjs.stub_size[pjsno] = 0;
+
+ mmix_elf_section_data (sec)->pjs.stubs_size_sum
+ += mmix_elf_section_data (sec)->pjs.stub_size[pjsno];
+
+ pjsno++;
+ }
+
+ continue;
+ }
+
+ /* 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. */
+ Elf_Internal_Sym *isym;
+ asection *sym_sec;
+
+ /* Read this BFD's local symbols if we haven't already. */
+ if (isymbuf == NULL)
+ {
+ isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
+ if (isymbuf == NULL)
+ isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
+ symtab_hdr->sh_info, 0,
+ NULL, NULL, NULL);
+ if (isymbuf == 0)
+ goto error_return;
+ }
+
+ isym = isymbuf + ELF64_R_SYM (irel->r_info);
+ if (isym->st_shndx == SHN_UNDEF)
+ sym_sec = bfd_und_section_ptr;
+ 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;
+ else
+ 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;
+
+ /* An external symbol. */
+ indx = ELF64_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.
+ We need to keep BPO reloc accounting consistent, though
+ else we'll abort instead of emitting an error message. */
+ if (ELF64_R_TYPE (irel->r_info) == R_MMIX_BASE_PLUS_OFFSET
+ && gregdata != NULL)
+ {
+ gregdata->n_remaining_bpo_relocs_this_relaxation_round--;
+ bpono++;
+ }
+ continue;
+ }
+
+ symval = (h->root.u.def.value
+ + h->root.u.def.section->output_section->vma
+ + h->root.u.def.section->output_offset);
+ }
+
+ if (ELF64_R_TYPE (irel->r_info) == (int) R_MMIX_PUSHJ_STUBBABLE)
+ {
+ bfd_vma value = symval + irel->r_addend;
+ bfd_vma dot
+ = (sec->output_section->vma
+ + sec->output_offset
+ + irel->r_offset);
+ bfd_vma stubaddr
+ = (sec->output_section->vma
+ + sec->output_offset
+ + size
+ + mmix_elf_section_data (sec)->pjs.stubs_size_sum);
+
+ if ((value & 3) == 0
+ && bfd_check_overflow (complain_overflow_signed,
+ 19,
+ 0,
+ bfd_arch_bits_per_address (abfd),
+ value - dot
+ - (value > dot
+ ? mmix_elf_section_data (sec)
+ ->pjs.stub_size[pjsno]
+ : 0))
+ == bfd_reloc_ok)
+ /* If the reloc fits, no stub is needed. */
+ mmix_elf_section_data (sec)->pjs.stub_size[pjsno] = 0;
+ else
+ /* Maybe we can get away with just a JMP insn? */
+ if ((value & 3) == 0
+ && bfd_check_overflow (complain_overflow_signed,
+ 27,
+ 0,
+ bfd_arch_bits_per_address (abfd),
+ value - stubaddr
+ - (value > dot
+ ? mmix_elf_section_data (sec)
+ ->pjs.stub_size[pjsno] - 4
+ : 0))
+ == bfd_reloc_ok)
+ /* Yep, account for a stub consisting of a single JMP insn. */
+ mmix_elf_section_data (sec)->pjs.stub_size[pjsno] = 4;
+ else
+ /* Nope, go for the full insn stub. It doesn't seem useful to
+ emit the intermediate sizes; those will only be useful for
+ a >64M program assuming contiguous code. */
+ mmix_elf_section_data (sec)->pjs.stub_size[pjsno]
+ = MAX_PUSHJ_STUB_SIZE;
+
+ mmix_elf_section_data (sec)->pjs.stubs_size_sum
+ += mmix_elf_section_data (sec)->pjs.stub_size[pjsno];
+ pjsno++;
+ continue;
+ }
+
+ /* We're looking at a R_MMIX_BASE_PLUS_OFFSET reloc. */
+
+ gregdata->reloc_request[gregdata->bpo_reloc_indexes[bpono]].value
+ = symval + irel->r_addend;
+ gregdata->reloc_request[gregdata->bpo_reloc_indexes[bpono++]].valid = TRUE;
+ gregdata->n_remaining_bpo_relocs_this_relaxation_round--;
+ }
+
+ /* Check if that was the last BPO-reloc. If so, sort the values and
+ calculate how many registers we need to cover them. Set the size of
+ the linker gregs, and if the number of registers changed, indicate
+ that we need to relax some more because we have more work to do. */
+ if (gregdata != NULL
+ && gregdata->n_remaining_bpo_relocs_this_relaxation_round == 0)
+ {
+ size_t i;
+ bfd_vma prev_base;
+ size_t regindex;
+
+ /* First, reset the remaining relocs for the next round. */
+ gregdata->n_remaining_bpo_relocs_this_relaxation_round
+ = gregdata->n_bpo_relocs;
+
+ qsort (gregdata->reloc_request,
+ gregdata->n_max_bpo_relocs,
+ sizeof (struct bpo_reloc_request),
+ bpo_reloc_request_sort_fn);
+
+ /* Recalculate indexes. When we find a change (however unlikely
+ after the initial iteration), we know we need to relax again,
+ since items in the GREG-array are sorted by increasing value and
+ stored in the relaxation phase. */
+ for (i = 0; i < gregdata->n_max_bpo_relocs; i++)
+ if (gregdata->bpo_reloc_indexes[gregdata->reloc_request[i].bpo_reloc_no]
+ != i)
+ {
+ gregdata->bpo_reloc_indexes[gregdata->reloc_request[i].bpo_reloc_no]
+ = i;
+ *again = TRUE;
+ }
+
+ /* Allocate register numbers (indexing from 0). Stop at the first
+ non-valid reloc. */
+ for (i = 0, regindex = 0, prev_base = gregdata->reloc_request[0].value;
+ i < gregdata->n_bpo_relocs;
+ i++)
+ {
+ if (gregdata->reloc_request[i].value > prev_base + 255)
+ {
+ regindex++;
+ prev_base = gregdata->reloc_request[i].value;
+ }
+ gregdata->reloc_request[i].regindex = regindex;
+ gregdata->reloc_request[i].offset
+ = gregdata->reloc_request[i].value - prev_base;
+ }
+
+ /* If it's not the same as the last time, we need to relax again,
+ because the size of the section has changed. I'm not sure we
+ actually need to do any adjustments since the shrinking happens
+ at the start of this section, but better safe than sorry. */
+ if (gregdata->n_allocated_bpo_gregs != regindex + 1)
+ {
+ gregdata->n_allocated_bpo_gregs = regindex + 1;
+ *again = TRUE;
+ }
+
+ bpo_gregs_section->size = (regindex + 1) * 8;
+ }
+
+ if (isymbuf != NULL && (unsigned char *) isymbuf != symtab_hdr->contents)
+ {
+ if (! link_info->keep_memory)
+ free (isymbuf);
+ else
+ {
+ /* Cache the symbols for elf_link_input_bfd. */
+ symtab_hdr->contents = (unsigned char *) isymbuf;
+ }
+ }
+
+ if (internal_relocs != NULL
+ && elf_section_data (sec)->relocs != internal_relocs)
+ free (internal_relocs);
+
+ if (sec->size < size + mmix_elf_section_data (sec)->pjs.stubs_size_sum)
+ abort ();
+
+ if (sec->size > size + mmix_elf_section_data (sec)->pjs.stubs_size_sum)
+ {
+ sec->size = size + mmix_elf_section_data (sec)->pjs.stubs_size_sum;
+ *again = TRUE;
+ }
+
+ return TRUE;
+
+ error_return:
+ if (isymbuf != NULL && (unsigned char *) isymbuf != symtab_hdr->contents)
+ free (isymbuf);
+ if (internal_relocs != NULL
+ && elf_section_data (sec)->relocs != internal_relocs)
+ free (internal_relocs);
+ return FALSE;
+}
+
+#define ELF_ARCH bfd_arch_mmix
+#define ELF_MACHINE_CODE EM_MMIX
+
+/* According to mmix-doc page 36 (paragraph 45), this should be (1LL << 48LL).
+ However, that's too much for something somewhere in the linker part of
+ BFD; perhaps the start-address has to be a non-zero multiple of this
+ number, or larger than this number. The symptom is that the linker
+ complains: "warning: allocated section `.text' not in segment". We
+ settle for 64k; the page-size used in examples is 8k.
+ #define ELF_MAXPAGESIZE 0x10000
+
+ Unfortunately, this causes excessive padding in the supposedly small
+ for-education programs that are the expected usage (where people would
+ inspect output). We stick to 256 bytes just to have *some* default
+ alignment. */
+#define ELF_MAXPAGESIZE 0x100
+
+#define TARGET_BIG_SYM mmix_elf64_vec
+#define TARGET_BIG_NAME "elf64-mmix"
+
+#define elf_info_to_howto_rel NULL
+#define elf_info_to_howto mmix_info_to_howto_rela
+#define elf_backend_relocate_section mmix_elf_relocate_section
+#define elf_backend_gc_mark_hook mmix_elf_gc_mark_hook
+#define elf_backend_gc_sweep_hook mmix_elf_gc_sweep_hook
+
+#define elf_backend_link_output_symbol_hook \
+ mmix_elf_link_output_symbol_hook
+#define elf_backend_add_symbol_hook mmix_elf_add_symbol_hook
+
+#define elf_backend_check_relocs mmix_elf_check_relocs
+#define elf_backend_symbol_processing mmix_elf_symbol_processing
+#define elf_backend_omit_section_dynsym \
+ ((bfd_boolean (*) (bfd *, struct bfd_link_info *, asection *)) bfd_true)
+
+#define bfd_elf64_bfd_is_local_label_name \
+ mmix_elf_is_local_label_name
+
+#define elf_backend_may_use_rel_p 0
+#define elf_backend_may_use_rela_p 1
+#define elf_backend_default_use_rela_p 1
+
+#define elf_backend_can_gc_sections 1
+#define elf_backend_section_from_bfd_section \
+ mmix_elf_section_from_bfd_section
+
+#define bfd_elf64_new_section_hook mmix_elf_new_section_hook
+#define bfd_elf64_bfd_final_link mmix_elf_final_link
+#define bfd_elf64_bfd_relax_section mmix_elf_relax_section
+
+#include "elf64-target.h"
diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c
new file mode 100644
index 0000000..c1029df
--- /dev/null
+++ b/bfd/elf64-ppc.c
@@ -0,0 +1,15261 @@
+/* PowerPC64-specific support for 64-bit ELF.
+ Copyright (C) 1999-2014 Free Software Foundation, Inc.
+ Written by Linus Nordberg, Swox AB <info@swox.com>,
+ based on elf32-ppc.c by Ian Lance Taylor.
+ Largely rewritten by Alan Modra.
+
+ This file is part of BFD, the Binary File Descriptor library.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
+
+
+/* The 64-bit PowerPC ELF ABI may be found at
+ http://www.linuxbase.org/spec/ELF/ppc64/PPC-elf64abi.txt, and
+ http://www.linuxbase.org/spec/ELF/ppc64/spec/book1.html */
+
+#include "sysdep.h"
+#include <stdarg.h>
+#include "bfd.h"
+#include "bfdlink.h"
+#include "libbfd.h"
+#include "elf-bfd.h"
+#include "elf/ppc64.h"
+#include "elf64-ppc.h"
+#include "dwarf2.h"
+
+static bfd_reloc_status_type ppc64_elf_ha_reloc
+ (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
+static bfd_reloc_status_type ppc64_elf_branch_reloc
+ (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
+static bfd_reloc_status_type ppc64_elf_brtaken_reloc
+ (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
+static bfd_reloc_status_type ppc64_elf_sectoff_reloc
+ (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
+static bfd_reloc_status_type ppc64_elf_sectoff_ha_reloc
+ (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
+static bfd_reloc_status_type ppc64_elf_toc_reloc
+ (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
+static bfd_reloc_status_type ppc64_elf_toc_ha_reloc
+ (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
+static bfd_reloc_status_type ppc64_elf_toc64_reloc
+ (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
+static bfd_reloc_status_type ppc64_elf_unhandled_reloc
+ (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
+static bfd_vma opd_entry_value
+ (asection *, bfd_vma, asection **, bfd_vma *, bfd_boolean);
+
+#define TARGET_LITTLE_SYM powerpc_elf64_le_vec
+#define TARGET_LITTLE_NAME "elf64-powerpcle"
+#define TARGET_BIG_SYM powerpc_elf64_vec
+#define TARGET_BIG_NAME "elf64-powerpc"
+#define ELF_ARCH bfd_arch_powerpc
+#define ELF_TARGET_ID PPC64_ELF_DATA
+#define ELF_MACHINE_CODE EM_PPC64
+#define ELF_MAXPAGESIZE 0x10000
+#define ELF_COMMONPAGESIZE 0x1000
+#define elf_info_to_howto ppc64_elf_info_to_howto
+
+#define elf_backend_want_got_sym 0
+#define elf_backend_want_plt_sym 0
+#define elf_backend_plt_alignment 3
+#define elf_backend_plt_not_loaded 1
+#define elf_backend_got_header_size 8
+#define elf_backend_can_gc_sections 1
+#define elf_backend_can_refcount 1
+#define elf_backend_rela_normal 1
+#define elf_backend_default_execstack 0
+
+#define bfd_elf64_mkobject ppc64_elf_mkobject
+#define bfd_elf64_bfd_reloc_type_lookup ppc64_elf_reloc_type_lookup
+#define bfd_elf64_bfd_reloc_name_lookup ppc64_elf_reloc_name_lookup
+#define bfd_elf64_bfd_merge_private_bfd_data ppc64_elf_merge_private_bfd_data
+#define bfd_elf64_bfd_print_private_bfd_data ppc64_elf_print_private_bfd_data
+#define bfd_elf64_new_section_hook ppc64_elf_new_section_hook
+#define bfd_elf64_bfd_link_hash_table_create ppc64_elf_link_hash_table_create
+#define bfd_elf64_get_synthetic_symtab ppc64_elf_get_synthetic_symtab
+#define bfd_elf64_bfd_link_just_syms ppc64_elf_link_just_syms
+
+#define elf_backend_object_p ppc64_elf_object_p
+#define elf_backend_grok_prstatus ppc64_elf_grok_prstatus
+#define elf_backend_grok_psinfo ppc64_elf_grok_psinfo
+#define elf_backend_write_core_note ppc64_elf_write_core_note
+#define elf_backend_create_dynamic_sections ppc64_elf_create_dynamic_sections
+#define elf_backend_copy_indirect_symbol ppc64_elf_copy_indirect_symbol
+#define elf_backend_add_symbol_hook ppc64_elf_add_symbol_hook
+#define elf_backend_check_directives ppc64_elf_before_check_relocs
+#define elf_backend_notice_as_needed ppc64_elf_notice_as_needed
+#define elf_backend_archive_symbol_lookup ppc64_elf_archive_symbol_lookup
+#define elf_backend_check_relocs ppc64_elf_check_relocs
+#define elf_backend_gc_keep ppc64_elf_gc_keep
+#define elf_backend_gc_mark_dynamic_ref ppc64_elf_gc_mark_dynamic_ref
+#define elf_backend_gc_mark_hook ppc64_elf_gc_mark_hook
+#define elf_backend_gc_sweep_hook ppc64_elf_gc_sweep_hook
+#define elf_backend_adjust_dynamic_symbol ppc64_elf_adjust_dynamic_symbol
+#define elf_backend_hide_symbol ppc64_elf_hide_symbol
+#define elf_backend_maybe_function_sym ppc64_elf_maybe_function_sym
+#define elf_backend_always_size_sections ppc64_elf_func_desc_adjust
+#define elf_backend_size_dynamic_sections ppc64_elf_size_dynamic_sections
+#define elf_backend_hash_symbol ppc64_elf_hash_symbol
+#define elf_backend_init_index_section _bfd_elf_init_2_index_sections
+#define elf_backend_action_discarded ppc64_elf_action_discarded
+#define elf_backend_relocate_section ppc64_elf_relocate_section
+#define elf_backend_finish_dynamic_symbol ppc64_elf_finish_dynamic_symbol
+#define elf_backend_reloc_type_class ppc64_elf_reloc_type_class
+#define elf_backend_finish_dynamic_sections ppc64_elf_finish_dynamic_sections
+#define elf_backend_link_output_symbol_hook ppc64_elf_output_symbol_hook
+#define elf_backend_special_sections ppc64_elf_special_sections
+#define elf_backend_merge_symbol_attribute ppc64_elf_merge_symbol_attribute
+
+/* 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(htab) (htab->opd_abi ? 24 : 8)
+
+/* The initial size of the plt reserved for the dynamic linker. */
+#define PLT_INITIAL_ENTRY_SIZE(htab) (htab->opd_abi ? 24 : 16)
+
+/* Offsets to some stack save slots. */
+#define STK_LR 16
+#define STK_TOC(htab) (htab->opd_abi ? 40 : 24)
+/* This one is dodgy. ELFv2 does not have a linker word, so use the
+ CR save slot. Used only by optimised __tls_get_addr call stub,
+ relying on __tls_get_addr_opt not saving CR.. */
+#define STK_LINKER(htab) (htab->opd_abi ? 32 : 8)
+
+/* TOC base pointers offset from start of TOC. */
+#define TOC_BASE_OFF 0x8000
+
+/* Offset of tp and dtp pointers from start of TLS block. */
+#define TP_OFFSET 0x7000
+#define DTP_OFFSET 0x8000
+
+/* .plt call stub instructions. The normal stub is like this, but
+ sometimes the .plt entry crosses a 64k boundary and we need to
+ insert an addi to adjust r11. */
+#define STD_R2_0R1 0xf8410000 /* std %r2,0+40(%r1) */
+#define ADDIS_R11_R2 0x3d620000 /* addis %r11,%r2,xxx@ha */
+#define LD_R12_0R11 0xe98b0000 /* ld %r12,xxx+0@l(%r11) */
+#define MTCTR_R12 0x7d8903a6 /* mtctr %r12 */
+#define LD_R2_0R11 0xe84b0000 /* ld %r2,xxx+8@l(%r11) */
+#define LD_R11_0R11 0xe96b0000 /* ld %r11,xxx+16@l(%r11) */
+#define BCTR 0x4e800420 /* bctr */
+
+#define ADDI_R11_R11 0x396b0000 /* addi %r11,%r11,off@l */
+#define ADDIS_R2_R2 0x3c420000 /* addis %r2,%r2,off@ha */
+#define ADDI_R2_R2 0x38420000 /* addi %r2,%r2,off@l */
+
+#define XOR_R2_R12_R12 0x7d826278 /* xor %r2,%r12,%r12 */
+#define ADD_R11_R11_R2 0x7d6b1214 /* add %r11,%r11,%r2 */
+#define XOR_R11_R12_R12 0x7d8b6278 /* xor %r11,%r12,%r12 */
+#define ADD_R2_R2_R11 0x7c425a14 /* add %r2,%r2,%r11 */
+#define CMPLDI_R2_0 0x28220000 /* cmpldi %r2,0 */
+#define BNECTR 0x4ca20420 /* bnectr+ */
+#define BNECTR_P4 0x4ce20420 /* bnectr+ */
+
+#define LD_R12_0R2 0xe9820000 /* ld %r12,xxx+0(%r2) */
+#define LD_R11_0R2 0xe9620000 /* ld %r11,xxx+0(%r2) */
+#define LD_R2_0R2 0xe8420000 /* ld %r2,xxx+0(%r2) */
+
+#define LD_R2_0R1 0xe8410000 /* ld %r2,0(%r1) */
+
+#define ADDIS_R12_R2 0x3d820000 /* addis %r12,%r2,xxx@ha */
+#define ADDIS_R12_R12 0x3d8c0000 /* addis %r12,%r12,xxx@ha */
+#define LD_R12_0R12 0xe98c0000 /* ld %r12,xxx@l(%r12) */
+
+/* glink call stub instructions. We enter with the index in R0. */
+#define GLINK_CALL_STUB_SIZE (16*4)
+ /* 0: */
+ /* .quad plt0-1f */
+ /* __glink: */
+#define MFLR_R12 0x7d8802a6 /* mflr %12 */
+#define BCL_20_31 0x429f0005 /* bcl 20,31,1f */
+ /* 1: */
+#define MFLR_R11 0x7d6802a6 /* mflr %11 */
+ /* ld %2,(0b-1b)(%11) */
+#define MTLR_R12 0x7d8803a6 /* mtlr %12 */
+#define ADD_R11_R2_R11 0x7d625a14 /* add %11,%2,%11 */
+ /* ld %12,0(%11) */
+ /* ld %2,8(%11) */
+ /* mtctr %12 */
+ /* ld %11,16(%11) */
+ /* bctr */
+#define MFLR_R0 0x7c0802a6 /* mflr %r0 */
+#define MTLR_R0 0x7c0803a6 /* mtlr %r0 */
+#define SUB_R12_R12_R11 0x7d8b6050 /* subf %r12,%r11,%r12 */
+#define ADDI_R0_R12 0x380c0000 /* addi %r0,%r12,0 */
+#define SRDI_R0_R0_2 0x7800f082 /* rldicl %r0,%r0,62,2 */
+
+/* Pad with this. */
+#define NOP 0x60000000
+
+/* Some other nops. */
+#define CROR_151515 0x4def7b82
+#define CROR_313131 0x4ffffb82
+
+/* .glink entries for the first 32k functions are two instructions. */
+#define LI_R0_0 0x38000000 /* li %r0,0 */
+#define B_DOT 0x48000000 /* b . */
+
+/* After that, we need two instructions to load the index, followed by
+ a branch. */
+#define LIS_R0_0 0x3c000000 /* lis %r0,0 */
+#define ORI_R0_R0_0 0x60000000 /* ori %r0,%r0,0 */
+
+/* Instructions used by the save and restore reg functions. */
+#define STD_R0_0R1 0xf8010000 /* std %r0,0(%r1) */
+#define STD_R0_0R12 0xf80c0000 /* std %r0,0(%r12) */
+#define LD_R0_0R1 0xe8010000 /* ld %r0,0(%r1) */
+#define LD_R0_0R12 0xe80c0000 /* ld %r0,0(%r12) */
+#define STFD_FR0_0R1 0xd8010000 /* stfd %fr0,0(%r1) */
+#define LFD_FR0_0R1 0xc8010000 /* lfd %fr0,0(%r1) */
+#define LI_R12_0 0x39800000 /* li %r12,0 */
+#define STVX_VR0_R12_R0 0x7c0c01ce /* stvx %v0,%r12,%r0 */
+#define LVX_VR0_R12_R0 0x7c0c00ce /* lvx %v0,%r12,%r0 */
+#define MTLR_R0 0x7c0803a6 /* mtlr %r0 */
+#define BLR 0x4e800020 /* blr */
+
+/* Since .opd is an array of descriptors and each entry will end up
+ with identical R_PPC64_RELATIVE relocs, there is really no need to
+ propagate .opd relocs; The dynamic linker should be taught to
+ relocate .opd without reloc entries. */
+#ifndef NO_OPD_RELOCS
+#define NO_OPD_RELOCS 0
+#endif
+
+static inline int
+abiversion (bfd *abfd)
+{
+ return elf_elfheader (abfd)->e_flags & EF_PPC64_ABI;
+}
+
+static inline void
+set_abiversion (bfd *abfd, int ver)
+{
+ elf_elfheader (abfd)->e_flags &= ~EF_PPC64_ABI;
+ elf_elfheader (abfd)->e_flags |= ver & EF_PPC64_ABI;
+}
+
+#define ONES(n) (((bfd_vma) 1 << ((n) - 1) << 1) - 1)
+
+/* Relocation HOWTO's. */
+static reloc_howto_type *ppc64_elf_howto_table[(int) R_PPC64_max];
+
+static reloc_howto_type ppc64_elf_howto_raw[] = {
+ /* This reloc does nothing. */
+ HOWTO (R_PPC64_NONE, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_PPC64_NONE", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A standard 32 bit relocation. */
+ HOWTO (R_PPC64_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_PPC64_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_PPC64_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_PPC64_ADDR24", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x03fffffc, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A standard 16 bit relocation. */
+ HOWTO (R_PPC64_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_PPC64_ADDR16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A 16 bit relocation without overflow. */
+ HOWTO (R_PPC64_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_PPC64_ADDR16_LO", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Bits 16-31 of an address. */
+ HOWTO (R_PPC64_ADDR16_HI, /* type */
+ 16, /* 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_PPC64_ADDR16_HI", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Bits 16-31 of an address, plus 1 if the contents of the low 16
+ bits, treated as a signed number, is negative. */
+ HOWTO (R_PPC64_ADDR16_HA, /* type */
+ 16, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ ppc64_elf_ha_reloc, /* special_function */
+ "R_PPC64_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_PPC64_ADDR14, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ ppc64_elf_branch_reloc, /* special_function */
+ "R_PPC64_ADDR14", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000fffc, /* 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_PPC64_ADDR14_BRTAKEN, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ ppc64_elf_brtaken_reloc, /* special_function */
+ "R_PPC64_ADDR14_BRTAKEN",/* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000fffc, /* 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_PPC64_ADDR14_BRNTAKEN, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ ppc64_elf_brtaken_reloc, /* special_function */
+ "R_PPC64_ADDR14_BRNTAKEN",/* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000fffc, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A relative 26 bit branch; the lower two bits must be zero. */
+ HOWTO (R_PPC64_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 */
+ ppc64_elf_branch_reloc, /* special_function */
+ "R_PPC64_REL24", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x03fffffc, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* A relative 16 bit branch; the lower two bits must be zero. */
+ HOWTO (R_PPC64_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 */
+ ppc64_elf_branch_reloc, /* special_function */
+ "R_PPC64_REL14", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000fffc, /* 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_PPC64_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 */
+ ppc64_elf_brtaken_reloc, /* special_function */
+ "R_PPC64_REL14_BRTAKEN", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000fffc, /* 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_PPC64_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 */
+ ppc64_elf_brtaken_reloc, /* special_function */
+ "R_PPC64_REL14_BRNTAKEN",/* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000fffc, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* Like R_PPC64_ADDR16, but referring to the GOT table entry for the
+ symbol. */
+ HOWTO (R_PPC64_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 */
+ ppc64_elf_unhandled_reloc, /* special_function */
+ "R_PPC64_GOT16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Like R_PPC64_ADDR16_LO, but referring to the GOT table entry for
+ the symbol. */
+ HOWTO (R_PPC64_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 */
+ ppc64_elf_unhandled_reloc, /* special_function */
+ "R_PPC64_GOT16_LO", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Like R_PPC64_ADDR16_HI, but referring to the GOT table entry for
+ the symbol. */
+ HOWTO (R_PPC64_GOT16_HI, /* type */
+ 16, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed,/* complain_on_overflow */
+ ppc64_elf_unhandled_reloc, /* special_function */
+ "R_PPC64_GOT16_HI", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Like R_PPC64_ADDR16_HA, but referring to the GOT table entry for
+ the symbol. */
+ HOWTO (R_PPC64_GOT16_HA, /* type */
+ 16, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed,/* complain_on_overflow */
+ ppc64_elf_unhandled_reloc, /* special_function */
+ "R_PPC64_GOT16_HA", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* 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_PPC64_COPY, /* type */
+ 0, /* rightshift */
+ 0, /* this one is variable size */
+ 0, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ ppc64_elf_unhandled_reloc, /* special_function */
+ "R_PPC64_COPY", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Like R_PPC64_ADDR64, but used when setting global offset table
+ entries. */
+ HOWTO (R_PPC64_GLOB_DAT, /* type */
+ 0, /* rightshift */
+ 4, /* size (0=byte, 1=short, 2=long, 4=64 bits) */
+ 64, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ ppc64_elf_unhandled_reloc, /* special_function */
+ "R_PPC64_GLOB_DAT", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ ONES (64), /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Created by the link editor. Marks a procedure linkage table
+ entry for a symbol. */
+ HOWTO (R_PPC64_JMP_SLOT, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 0, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ ppc64_elf_unhandled_reloc, /* special_function */
+ "R_PPC64_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
+ doubleword64 is set to the load address of the object, plus the
+ addend. */
+ HOWTO (R_PPC64_RELATIVE, /* type */
+ 0, /* rightshift */
+ 4, /* size (0=byte, 1=short, 2=long, 4=64 bits) */
+ 64, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_PPC64_RELATIVE", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ ONES (64), /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Like R_PPC64_ADDR32, but may be unaligned. */
+ HOWTO (R_PPC64_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_PPC64_UADDR32", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Like R_PPC64_ADDR16, but may be unaligned. */
+ HOWTO (R_PPC64_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_PPC64_UADDR16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* 32-bit PC relative. */
+ HOWTO (R_PPC64_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 */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_PPC64_REL32", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* 32-bit relocation to the symbol's procedure linkage table. */
+ HOWTO (R_PPC64_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 */
+ ppc64_elf_unhandled_reloc, /* special_function */
+ "R_PPC64_PLT32", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* 32-bit PC relative relocation to the symbol's procedure linkage table.
+ FIXME: R_PPC64_PLTREL32 not supported. */
+ HOWTO (R_PPC64_PLTREL32, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_PPC64_PLTREL32", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* Like R_PPC64_ADDR16_LO, but referring to the PLT table entry for
+ the symbol. */
+ HOWTO (R_PPC64_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 */
+ ppc64_elf_unhandled_reloc, /* special_function */
+ "R_PPC64_PLT16_LO", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Like R_PPC64_ADDR16_HI, but referring to the PLT table entry for
+ the symbol. */
+ HOWTO (R_PPC64_PLT16_HI, /* type */
+ 16, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ ppc64_elf_unhandled_reloc, /* special_function */
+ "R_PPC64_PLT16_HI", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Like R_PPC64_ADDR16_HA, but referring to the PLT table entry for
+ the symbol. */
+ HOWTO (R_PPC64_PLT16_HA, /* type */
+ 16, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ ppc64_elf_unhandled_reloc, /* special_function */
+ "R_PPC64_PLT16_HA", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* 16-bit section relative relocation. */
+ HOWTO (R_PPC64_SECTOFF, /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ ppc64_elf_sectoff_reloc, /* special_function */
+ "R_PPC64_SECTOFF", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Like R_PPC64_SECTOFF, but no overflow warning. */
+ HOWTO (R_PPC64_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 */
+ ppc64_elf_sectoff_reloc, /* special_function */
+ "R_PPC64_SECTOFF_LO", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* 16-bit upper half section relative relocation. */
+ HOWTO (R_PPC64_SECTOFF_HI, /* type */
+ 16, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ ppc64_elf_sectoff_reloc, /* special_function */
+ "R_PPC64_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_PPC64_SECTOFF_HA, /* type */
+ 16, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ ppc64_elf_sectoff_ha_reloc, /* special_function */
+ "R_PPC64_SECTOFF_HA", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Like R_PPC64_REL24 without touching the two least significant bits. */
+ HOWTO (R_PPC64_REL30, /* type */
+ 2, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 30, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_PPC64_REL30", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xfffffffc, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* Relocs in the 64-bit PowerPC ELF ABI, not in the 32-bit ABI. */
+
+ /* A standard 64-bit relocation. */
+ HOWTO (R_PPC64_ADDR64, /* type */
+ 0, /* rightshift */
+ 4, /* size (0=byte, 1=short, 2=long, 4=64 bits) */
+ 64, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_PPC64_ADDR64", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ ONES (64), /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* The bits 32-47 of an address. */
+ HOWTO (R_PPC64_ADDR16_HIGHER, /* type */
+ 32, /* 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_PPC64_ADDR16_HIGHER", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* The bits 32-47 of an address, plus 1 if the contents of the low
+ 16 bits, treated as a signed number, is negative. */
+ HOWTO (R_PPC64_ADDR16_HIGHERA, /* type */
+ 32, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ ppc64_elf_ha_reloc, /* special_function */
+ "R_PPC64_ADDR16_HIGHERA", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* The bits 48-63 of an address. */
+ HOWTO (R_PPC64_ADDR16_HIGHEST,/* type */
+ 48, /* 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_PPC64_ADDR16_HIGHEST", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* The bits 48-63 of an address, plus 1 if the contents of the low
+ 16 bits, treated as a signed number, is negative. */
+ HOWTO (R_PPC64_ADDR16_HIGHESTA,/* type */
+ 48, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ ppc64_elf_ha_reloc, /* special_function */
+ "R_PPC64_ADDR16_HIGHESTA", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Like ADDR64, but may be unaligned. */
+ HOWTO (R_PPC64_UADDR64, /* type */
+ 0, /* rightshift */
+ 4, /* size (0=byte, 1=short, 2=long, 4=64 bits) */
+ 64, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_PPC64_UADDR64", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ ONES (64), /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* 64-bit relative relocation. */
+ HOWTO (R_PPC64_REL64, /* type */
+ 0, /* rightshift */
+ 4, /* size (0=byte, 1=short, 2=long, 4=64 bits) */
+ 64, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_PPC64_REL64", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ ONES (64), /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* 64-bit relocation to the symbol's procedure linkage table. */
+ HOWTO (R_PPC64_PLT64, /* type */
+ 0, /* rightshift */
+ 4, /* size (0=byte, 1=short, 2=long, 4=64 bits) */
+ 64, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ ppc64_elf_unhandled_reloc, /* special_function */
+ "R_PPC64_PLT64", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ ONES (64), /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* 64-bit PC relative relocation to the symbol's procedure linkage
+ table. */
+ /* FIXME: R_PPC64_PLTREL64 not supported. */
+ HOWTO (R_PPC64_PLTREL64, /* type */
+ 0, /* rightshift */
+ 4, /* size (0=byte, 1=short, 2=long, 4=64 bits) */
+ 64, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ ppc64_elf_unhandled_reloc, /* special_function */
+ "R_PPC64_PLTREL64", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ ONES (64), /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* 16 bit TOC-relative relocation. */
+
+ /* R_PPC64_TOC16 47 half16* S + A - .TOC. */
+ HOWTO (R_PPC64_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 */
+ ppc64_elf_toc_reloc, /* special_function */
+ "R_PPC64_TOC16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* 16 bit TOC-relative relocation without overflow. */
+
+ /* R_PPC64_TOC16_LO 48 half16 #lo (S + A - .TOC.) */
+ HOWTO (R_PPC64_TOC16_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 */
+ ppc64_elf_toc_reloc, /* special_function */
+ "R_PPC64_TOC16_LO", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* 16 bit TOC-relative relocation, high 16 bits. */
+
+ /* R_PPC64_TOC16_HI 49 half16 #hi (S + A - .TOC.) */
+ HOWTO (R_PPC64_TOC16_HI, /* type */
+ 16, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ ppc64_elf_toc_reloc, /* special_function */
+ "R_PPC64_TOC16_HI", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* 16 bit TOC-relative relocation, high 16 bits, plus 1 if the
+ contents of the low 16 bits, treated as a signed number, is
+ negative. */
+
+ /* R_PPC64_TOC16_HA 50 half16 #ha (S + A - .TOC.) */
+ HOWTO (R_PPC64_TOC16_HA, /* type */
+ 16, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ ppc64_elf_toc_ha_reloc, /* special_function */
+ "R_PPC64_TOC16_HA", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* 64-bit relocation; insert value of TOC base (.TOC.). */
+
+ /* R_PPC64_TOC 51 doubleword64 .TOC. */
+ HOWTO (R_PPC64_TOC, /* type */
+ 0, /* rightshift */
+ 4, /* size (0=byte, 1=short, 2=long, 4=64 bits) */
+ 64, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ ppc64_elf_toc64_reloc, /* special_function */
+ "R_PPC64_TOC", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ ONES (64), /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Like R_PPC64_GOT16, but also informs the link editor that the
+ value to relocate may (!) refer to a PLT entry which the link
+ editor (a) may replace with the symbol value. If the link editor
+ is unable to fully resolve the symbol, it may (b) create a PLT
+ entry and store the address to the new PLT entry in the GOT.
+ This permits lazy resolution of function symbols at run time.
+ The link editor may also skip all of this and just (c) emit a
+ R_PPC64_GLOB_DAT to tie the symbol to the GOT entry. */
+ /* FIXME: R_PPC64_PLTGOT16 not implemented. */
+ HOWTO (R_PPC64_PLTGOT16, /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ ppc64_elf_unhandled_reloc, /* special_function */
+ "R_PPC64_PLTGOT16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Like R_PPC64_PLTGOT16, but without overflow. */
+ /* FIXME: R_PPC64_PLTGOT16_LO not implemented. */
+ HOWTO (R_PPC64_PLTGOT16_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 */
+ ppc64_elf_unhandled_reloc, /* special_function */
+ "R_PPC64_PLTGOT16_LO", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Like R_PPC64_PLT_GOT16, but using bits 16-31 of the address. */
+ /* FIXME: R_PPC64_PLTGOT16_HI not implemented. */
+ HOWTO (R_PPC64_PLTGOT16_HI, /* type */
+ 16, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ ppc64_elf_unhandled_reloc, /* special_function */
+ "R_PPC64_PLTGOT16_HI", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Like R_PPC64_PLT_GOT16, but using bits 16-31 of the address, plus
+ 1 if the contents of the low 16 bits, treated as a signed number,
+ is negative. */
+ /* FIXME: R_PPC64_PLTGOT16_HA not implemented. */
+ HOWTO (R_PPC64_PLTGOT16_HA, /* type */
+ 16, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ ppc64_elf_unhandled_reloc, /* special_function */
+ "R_PPC64_PLTGOT16_HA", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Like R_PPC64_ADDR16, but for instructions with a DS field. */
+ HOWTO (R_PPC64_ADDR16_DS, /* 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_PPC64_ADDR16_DS", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xfffc, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Like R_PPC64_ADDR16_LO, but for instructions with a DS field. */
+ HOWTO (R_PPC64_ADDR16_LO_DS, /* 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_PPC64_ADDR16_LO_DS",/* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xfffc, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Like R_PPC64_GOT16, but for instructions with a DS field. */
+ HOWTO (R_PPC64_GOT16_DS, /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ ppc64_elf_unhandled_reloc, /* special_function */
+ "R_PPC64_GOT16_DS", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xfffc, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Like R_PPC64_GOT16_LO, but for instructions with a DS field. */
+ HOWTO (R_PPC64_GOT16_LO_DS, /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ ppc64_elf_unhandled_reloc, /* special_function */
+ "R_PPC64_GOT16_LO_DS", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xfffc, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Like R_PPC64_PLT16_LO, but for instructions with a DS field. */
+ HOWTO (R_PPC64_PLT16_LO_DS, /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ ppc64_elf_unhandled_reloc, /* special_function */
+ "R_PPC64_PLT16_LO_DS", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xfffc, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Like R_PPC64_SECTOFF, but for instructions with a DS field. */
+ HOWTO (R_PPC64_SECTOFF_DS, /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ ppc64_elf_sectoff_reloc, /* special_function */
+ "R_PPC64_SECTOFF_DS", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xfffc, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Like R_PPC64_SECTOFF_LO, but for instructions with a DS field. */
+ HOWTO (R_PPC64_SECTOFF_LO_DS, /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ ppc64_elf_sectoff_reloc, /* special_function */
+ "R_PPC64_SECTOFF_LO_DS",/* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xfffc, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Like R_PPC64_TOC16, but for instructions with a DS field. */
+ HOWTO (R_PPC64_TOC16_DS, /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ ppc64_elf_toc_reloc, /* special_function */
+ "R_PPC64_TOC16_DS", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xfffc, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Like R_PPC64_TOC16_LO, but for instructions with a DS field. */
+ HOWTO (R_PPC64_TOC16_LO_DS, /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ ppc64_elf_toc_reloc, /* special_function */
+ "R_PPC64_TOC16_LO_DS", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xfffc, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Like R_PPC64_PLTGOT16, but for instructions with a DS field. */
+ /* FIXME: R_PPC64_PLTGOT16_DS not implemented. */
+ HOWTO (R_PPC64_PLTGOT16_DS, /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ ppc64_elf_unhandled_reloc, /* special_function */
+ "R_PPC64_PLTGOT16_DS", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xfffc, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Like R_PPC64_PLTGOT16_LO, but for instructions with a DS field. */
+ /* FIXME: R_PPC64_PLTGOT16_LO not implemented. */
+ HOWTO (R_PPC64_PLTGOT16_LO_DS,/* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ ppc64_elf_unhandled_reloc, /* special_function */
+ "R_PPC64_PLTGOT16_LO_DS",/* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xfffc, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Marker relocs for TLS. */
+ HOWTO (R_PPC64_TLS,
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_PPC64_TLS", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_PPC64_TLSGD,
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_PPC64_TLSGD", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_PPC64_TLSLD,
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_PPC64_TLSLD", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_PPC64_TOCSAVE,
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_PPC64_TOCSAVE", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Computes the load module index of the load module that contains the
+ definition of its TLS sym. */
+ HOWTO (R_PPC64_DTPMOD64,
+ 0, /* rightshift */
+ 4, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ ppc64_elf_unhandled_reloc, /* special_function */
+ "R_PPC64_DTPMOD64", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ ONES (64), /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Computes a dtv-relative displacement, the difference between the value
+ of sym+add and the base address of the thread-local storage block that
+ contains the definition of sym, minus 0x8000. */
+ HOWTO (R_PPC64_DTPREL64,
+ 0, /* rightshift */
+ 4, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ ppc64_elf_unhandled_reloc, /* special_function */
+ "R_PPC64_DTPREL64", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ ONES (64), /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A 16 bit dtprel reloc. */
+ HOWTO (R_PPC64_DTPREL16,
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ ppc64_elf_unhandled_reloc, /* special_function */
+ "R_PPC64_DTPREL16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Like DTPREL16, but no overflow. */
+ HOWTO (R_PPC64_DTPREL16_LO,
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ ppc64_elf_unhandled_reloc, /* special_function */
+ "R_PPC64_DTPREL16_LO", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Like DTPREL16_LO, but next higher group of 16 bits. */
+ HOWTO (R_PPC64_DTPREL16_HI,
+ 16, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ ppc64_elf_unhandled_reloc, /* special_function */
+ "R_PPC64_DTPREL16_HI", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Like DTPREL16_HI, but adjust for low 16 bits. */
+ HOWTO (R_PPC64_DTPREL16_HA,
+ 16, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ ppc64_elf_unhandled_reloc, /* special_function */
+ "R_PPC64_DTPREL16_HA", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Like DTPREL16_HI, but next higher group of 16 bits. */
+ HOWTO (R_PPC64_DTPREL16_HIGHER,
+ 32, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ ppc64_elf_unhandled_reloc, /* special_function */
+ "R_PPC64_DTPREL16_HIGHER", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Like DTPREL16_HIGHER, but adjust for low 16 bits. */
+ HOWTO (R_PPC64_DTPREL16_HIGHERA,
+ 32, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ ppc64_elf_unhandled_reloc, /* special_function */
+ "R_PPC64_DTPREL16_HIGHERA", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Like DTPREL16_HIGHER, but next higher group of 16 bits. */
+ HOWTO (R_PPC64_DTPREL16_HIGHEST,
+ 48, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ ppc64_elf_unhandled_reloc, /* special_function */
+ "R_PPC64_DTPREL16_HIGHEST", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Like DTPREL16_HIGHEST, but adjust for low 16 bits. */
+ HOWTO (R_PPC64_DTPREL16_HIGHESTA,
+ 48, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ ppc64_elf_unhandled_reloc, /* special_function */
+ "R_PPC64_DTPREL16_HIGHESTA", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Like DTPREL16, but for insns with a DS field. */
+ HOWTO (R_PPC64_DTPREL16_DS,
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ ppc64_elf_unhandled_reloc, /* special_function */
+ "R_PPC64_DTPREL16_DS", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xfffc, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Like DTPREL16_DS, but no overflow. */
+ HOWTO (R_PPC64_DTPREL16_LO_DS,
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ ppc64_elf_unhandled_reloc, /* special_function */
+ "R_PPC64_DTPREL16_LO_DS", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xfffc, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Computes a tp-relative displacement, the difference between the value of
+ sym+add and the value of the thread pointer (r13). */
+ HOWTO (R_PPC64_TPREL64,
+ 0, /* rightshift */
+ 4, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ ppc64_elf_unhandled_reloc, /* special_function */
+ "R_PPC64_TPREL64", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ ONES (64), /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A 16 bit tprel reloc. */
+ HOWTO (R_PPC64_TPREL16,
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ ppc64_elf_unhandled_reloc, /* special_function */
+ "R_PPC64_TPREL16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Like TPREL16, but no overflow. */
+ HOWTO (R_PPC64_TPREL16_LO,
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ ppc64_elf_unhandled_reloc, /* special_function */
+ "R_PPC64_TPREL16_LO", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Like TPREL16_LO, but next higher group of 16 bits. */
+ HOWTO (R_PPC64_TPREL16_HI,
+ 16, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ ppc64_elf_unhandled_reloc, /* special_function */
+ "R_PPC64_TPREL16_HI", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Like TPREL16_HI, but adjust for low 16 bits. */
+ HOWTO (R_PPC64_TPREL16_HA,
+ 16, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ ppc64_elf_unhandled_reloc, /* special_function */
+ "R_PPC64_TPREL16_HA", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Like TPREL16_HI, but next higher group of 16 bits. */
+ HOWTO (R_PPC64_TPREL16_HIGHER,
+ 32, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ ppc64_elf_unhandled_reloc, /* special_function */
+ "R_PPC64_TPREL16_HIGHER", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Like TPREL16_HIGHER, but adjust for low 16 bits. */
+ HOWTO (R_PPC64_TPREL16_HIGHERA,
+ 32, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ ppc64_elf_unhandled_reloc, /* special_function */
+ "R_PPC64_TPREL16_HIGHERA", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Like TPREL16_HIGHER, but next higher group of 16 bits. */
+ HOWTO (R_PPC64_TPREL16_HIGHEST,
+ 48, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ ppc64_elf_unhandled_reloc, /* special_function */
+ "R_PPC64_TPREL16_HIGHEST", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Like TPREL16_HIGHEST, but adjust for low 16 bits. */
+ HOWTO (R_PPC64_TPREL16_HIGHESTA,
+ 48, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ ppc64_elf_unhandled_reloc, /* special_function */
+ "R_PPC64_TPREL16_HIGHESTA", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Like TPREL16, but for insns with a DS field. */
+ HOWTO (R_PPC64_TPREL16_DS,
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ ppc64_elf_unhandled_reloc, /* special_function */
+ "R_PPC64_TPREL16_DS", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xfffc, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Like TPREL16_DS, but no overflow. */
+ HOWTO (R_PPC64_TPREL16_LO_DS,
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ ppc64_elf_unhandled_reloc, /* special_function */
+ "R_PPC64_TPREL16_LO_DS", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xfffc, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Allocates two contiguous entries in the GOT to hold a tls_index structure,
+ with values (sym+add)@dtpmod and (sym+add)@dtprel, and computes the offset
+ to the first entry relative to the TOC base (r2). */
+ HOWTO (R_PPC64_GOT_TLSGD16,
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ ppc64_elf_unhandled_reloc, /* special_function */
+ "R_PPC64_GOT_TLSGD16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Like GOT_TLSGD16, but no overflow. */
+ HOWTO (R_PPC64_GOT_TLSGD16_LO,
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ ppc64_elf_unhandled_reloc, /* special_function */
+ "R_PPC64_GOT_TLSGD16_LO", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Like GOT_TLSGD16_LO, but next higher group of 16 bits. */
+ HOWTO (R_PPC64_GOT_TLSGD16_HI,
+ 16, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ ppc64_elf_unhandled_reloc, /* special_function */
+ "R_PPC64_GOT_TLSGD16_HI", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Like GOT_TLSGD16_HI, but adjust for low 16 bits. */
+ HOWTO (R_PPC64_GOT_TLSGD16_HA,
+ 16, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ ppc64_elf_unhandled_reloc, /* special_function */
+ "R_PPC64_GOT_TLSGD16_HA", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Allocates two contiguous entries in the GOT to hold a tls_index structure,
+ with values (sym+add)@dtpmod and zero, and computes the offset to the
+ first entry relative to the TOC base (r2). */
+ HOWTO (R_PPC64_GOT_TLSLD16,
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ ppc64_elf_unhandled_reloc, /* special_function */
+ "R_PPC64_GOT_TLSLD16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Like GOT_TLSLD16, but no overflow. */
+ HOWTO (R_PPC64_GOT_TLSLD16_LO,
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ ppc64_elf_unhandled_reloc, /* special_function */
+ "R_PPC64_GOT_TLSLD16_LO", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Like GOT_TLSLD16_LO, but next higher group of 16 bits. */
+ HOWTO (R_PPC64_GOT_TLSLD16_HI,
+ 16, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ ppc64_elf_unhandled_reloc, /* special_function */
+ "R_PPC64_GOT_TLSLD16_HI", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Like GOT_TLSLD16_HI, but adjust for low 16 bits. */
+ HOWTO (R_PPC64_GOT_TLSLD16_HA,
+ 16, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ ppc64_elf_unhandled_reloc, /* special_function */
+ "R_PPC64_GOT_TLSLD16_HA", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Allocates an entry in the GOT with value (sym+add)@dtprel, and computes
+ the offset to the entry relative to the TOC base (r2). */
+ HOWTO (R_PPC64_GOT_DTPREL16_DS,
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ ppc64_elf_unhandled_reloc, /* special_function */
+ "R_PPC64_GOT_DTPREL16_DS", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xfffc, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Like GOT_DTPREL16_DS, but no overflow. */
+ HOWTO (R_PPC64_GOT_DTPREL16_LO_DS,
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ ppc64_elf_unhandled_reloc, /* special_function */
+ "R_PPC64_GOT_DTPREL16_LO_DS", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xfffc, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Like GOT_DTPREL16_LO_DS, but next higher group of 16 bits. */
+ HOWTO (R_PPC64_GOT_DTPREL16_HI,
+ 16, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ ppc64_elf_unhandled_reloc, /* special_function */
+ "R_PPC64_GOT_DTPREL16_HI", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Like GOT_DTPREL16_HI, but adjust for low 16 bits. */
+ HOWTO (R_PPC64_GOT_DTPREL16_HA,
+ 16, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ ppc64_elf_unhandled_reloc, /* special_function */
+ "R_PPC64_GOT_DTPREL16_HA", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Allocates an entry in the GOT with value (sym+add)@tprel, and computes the
+ offset to the entry relative to the TOC base (r2). */
+ HOWTO (R_PPC64_GOT_TPREL16_DS,
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ ppc64_elf_unhandled_reloc, /* special_function */
+ "R_PPC64_GOT_TPREL16_DS", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xfffc, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Like GOT_TPREL16_DS, but no overflow. */
+ HOWTO (R_PPC64_GOT_TPREL16_LO_DS,
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ ppc64_elf_unhandled_reloc, /* special_function */
+ "R_PPC64_GOT_TPREL16_LO_DS", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xfffc, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Like GOT_TPREL16_LO_DS, but next higher group of 16 bits. */
+ HOWTO (R_PPC64_GOT_TPREL16_HI,
+ 16, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ ppc64_elf_unhandled_reloc, /* special_function */
+ "R_PPC64_GOT_TPREL16_HI", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Like GOT_TPREL16_HI, but adjust for low 16 bits. */
+ HOWTO (R_PPC64_GOT_TPREL16_HA,
+ 16, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ ppc64_elf_unhandled_reloc, /* special_function */
+ "R_PPC64_GOT_TPREL16_HA", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_PPC64_JMP_IREL, /* type */
+ 0, /* rightshift */
+ 0, /* size (0=byte, 1=short, 2=long, 4=64 bits) */
+ 0, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ ppc64_elf_unhandled_reloc, /* special_function */
+ "R_PPC64_JMP_IREL", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_PPC64_IRELATIVE, /* type */
+ 0, /* rightshift */
+ 4, /* size (0=byte, 1=short, 2=long, 4=64 bits) */
+ 64, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_PPC64_IRELATIVE", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ ONES (64), /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A 16 bit relative relocation. */
+ HOWTO (R_PPC64_REL16, /* 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_PPC64_REL16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* A 16 bit relative relocation without overflow. */
+ HOWTO (R_PPC64_REL16_LO, /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_PPC64_REL16_LO", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* The high order 16 bits of a relative address. */
+ HOWTO (R_PPC64_REL16_HI, /* type */
+ 16, /* 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_PPC64_REL16_HI", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* The high order 16 bits of a relative address, plus 1 if the contents of
+ the low 16 bits, treated as a signed number, is negative. */
+ HOWTO (R_PPC64_REL16_HA, /* type */
+ 16, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ ppc64_elf_ha_reloc, /* special_function */
+ "R_PPC64_REL16_HA", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* Like R_PPC64_ADDR16_HI, but no overflow. */
+ HOWTO (R_PPC64_ADDR16_HIGH, /* 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_PPC64_ADDR16_HIGH", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Like R_PPC64_ADDR16_HA, but no overflow. */
+ HOWTO (R_PPC64_ADDR16_HIGHA, /* type */
+ 16, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ ppc64_elf_ha_reloc, /* special_function */
+ "R_PPC64_ADDR16_HIGHA", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Like R_PPC64_DTPREL16_HI, but no overflow. */
+ HOWTO (R_PPC64_DTPREL16_HIGH,
+ 16, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ ppc64_elf_unhandled_reloc, /* special_function */
+ "R_PPC64_DTPREL16_HIGH", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Like R_PPC64_DTPREL16_HA, but no overflow. */
+ HOWTO (R_PPC64_DTPREL16_HIGHA,
+ 16, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ ppc64_elf_unhandled_reloc, /* special_function */
+ "R_PPC64_DTPREL16_HIGHA", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Like R_PPC64_TPREL16_HI, but no overflow. */
+ HOWTO (R_PPC64_TPREL16_HIGH,
+ 16, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ ppc64_elf_unhandled_reloc, /* special_function */
+ "R_PPC64_TPREL16_HIGH", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Like R_PPC64_TPREL16_HA, but no overflow. */
+ HOWTO (R_PPC64_TPREL16_HIGHA,
+ 16, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ ppc64_elf_unhandled_reloc, /* special_function */
+ "R_PPC64_TPREL16_HIGHA", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Like ADDR64, but use local entry point of function. */
+ HOWTO (R_PPC64_ADDR64_LOCAL, /* type */
+ 0, /* rightshift */
+ 4, /* size (0=byte, 1=short, 2=long, 4=64 bits) */
+ 64, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_PPC64_ADDR64_LOCAL", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ ONES (64), /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* GNU extension to record C++ vtable hierarchy. */
+ HOWTO (R_PPC64_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_PPC64_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_PPC64_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_PPC64_GNU_VTENTRY", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ FALSE), /* pcrel_offset */
+};
+
+
+/* Initialize the ppc64_elf_howto_table, so that linear accesses can
+ be done. */
+
+static void
+ppc_howto_init (void)
+{
+ unsigned int i, type;
+
+ for (i = 0;
+ i < sizeof (ppc64_elf_howto_raw) / sizeof (ppc64_elf_howto_raw[0]);
+ i++)
+ {
+ type = ppc64_elf_howto_raw[i].type;
+ BFD_ASSERT (type < (sizeof (ppc64_elf_howto_table)
+ / sizeof (ppc64_elf_howto_table[0])));
+ ppc64_elf_howto_table[type] = &ppc64_elf_howto_raw[i];
+ }
+}
+
+static reloc_howto_type *
+ppc64_elf_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ bfd_reloc_code_real_type code)
+{
+ enum elf_ppc64_reloc_type r = R_PPC64_NONE;
+
+ if (!ppc64_elf_howto_table[R_PPC64_ADDR32])
+ /* Initialize howto table if needed. */
+ ppc_howto_init ();
+
+ switch (code)
+ {
+ default:
+ return NULL;
+
+ case BFD_RELOC_NONE: r = R_PPC64_NONE;
+ break;
+ case BFD_RELOC_32: r = R_PPC64_ADDR32;
+ break;
+ case BFD_RELOC_PPC_BA26: r = R_PPC64_ADDR24;
+ break;
+ case BFD_RELOC_16: r = R_PPC64_ADDR16;
+ break;
+ case BFD_RELOC_LO16: r = R_PPC64_ADDR16_LO;
+ break;
+ case BFD_RELOC_HI16: r = R_PPC64_ADDR16_HI;
+ break;
+ case BFD_RELOC_PPC64_ADDR16_HIGH: r = R_PPC64_ADDR16_HIGH;
+ break;
+ case BFD_RELOC_HI16_S: r = R_PPC64_ADDR16_HA;
+ break;
+ case BFD_RELOC_PPC64_ADDR16_HIGHA: r = R_PPC64_ADDR16_HIGHA;
+ break;
+ case BFD_RELOC_PPC_BA16: r = R_PPC64_ADDR14;
+ break;
+ case BFD_RELOC_PPC_BA16_BRTAKEN: r = R_PPC64_ADDR14_BRTAKEN;
+ break;
+ case BFD_RELOC_PPC_BA16_BRNTAKEN: r = R_PPC64_ADDR14_BRNTAKEN;
+ break;
+ case BFD_RELOC_PPC_B26: r = R_PPC64_REL24;
+ break;
+ case BFD_RELOC_PPC_B16: r = R_PPC64_REL14;
+ break;
+ case BFD_RELOC_PPC_B16_BRTAKEN: r = R_PPC64_REL14_BRTAKEN;
+ break;
+ case BFD_RELOC_PPC_B16_BRNTAKEN: r = R_PPC64_REL14_BRNTAKEN;
+ break;
+ case BFD_RELOC_16_GOTOFF: r = R_PPC64_GOT16;
+ break;
+ case BFD_RELOC_LO16_GOTOFF: r = R_PPC64_GOT16_LO;
+ break;
+ case BFD_RELOC_HI16_GOTOFF: r = R_PPC64_GOT16_HI;
+ break;
+ case BFD_RELOC_HI16_S_GOTOFF: r = R_PPC64_GOT16_HA;
+ break;
+ case BFD_RELOC_PPC_COPY: r = R_PPC64_COPY;
+ break;
+ case BFD_RELOC_PPC_GLOB_DAT: r = R_PPC64_GLOB_DAT;
+ break;
+ case BFD_RELOC_32_PCREL: r = R_PPC64_REL32;
+ break;
+ case BFD_RELOC_32_PLTOFF: r = R_PPC64_PLT32;
+ break;
+ case BFD_RELOC_32_PLT_PCREL: r = R_PPC64_PLTREL32;
+ break;
+ case BFD_RELOC_LO16_PLTOFF: r = R_PPC64_PLT16_LO;
+ break;
+ case BFD_RELOC_HI16_PLTOFF: r = R_PPC64_PLT16_HI;
+ break;
+ case BFD_RELOC_HI16_S_PLTOFF: r = R_PPC64_PLT16_HA;
+ break;
+ case BFD_RELOC_16_BASEREL: r = R_PPC64_SECTOFF;
+ break;
+ case BFD_RELOC_LO16_BASEREL: r = R_PPC64_SECTOFF_LO;
+ break;
+ case BFD_RELOC_HI16_BASEREL: r = R_PPC64_SECTOFF_HI;
+ break;
+ case BFD_RELOC_HI16_S_BASEREL: r = R_PPC64_SECTOFF_HA;
+ break;
+ case BFD_RELOC_CTOR: r = R_PPC64_ADDR64;
+ break;
+ case BFD_RELOC_64: r = R_PPC64_ADDR64;
+ break;
+ case BFD_RELOC_PPC64_HIGHER: r = R_PPC64_ADDR16_HIGHER;
+ break;
+ case BFD_RELOC_PPC64_HIGHER_S: r = R_PPC64_ADDR16_HIGHERA;
+ break;
+ case BFD_RELOC_PPC64_HIGHEST: r = R_PPC64_ADDR16_HIGHEST;
+ break;
+ case BFD_RELOC_PPC64_HIGHEST_S: r = R_PPC64_ADDR16_HIGHESTA;
+ break;
+ case BFD_RELOC_64_PCREL: r = R_PPC64_REL64;
+ break;
+ case BFD_RELOC_64_PLTOFF: r = R_PPC64_PLT64;
+ break;
+ case BFD_RELOC_64_PLT_PCREL: r = R_PPC64_PLTREL64;
+ break;
+ case BFD_RELOC_PPC_TOC16: r = R_PPC64_TOC16;
+ break;
+ case BFD_RELOC_PPC64_TOC16_LO: r = R_PPC64_TOC16_LO;
+ break;
+ case BFD_RELOC_PPC64_TOC16_HI: r = R_PPC64_TOC16_HI;
+ break;
+ case BFD_RELOC_PPC64_TOC16_HA: r = R_PPC64_TOC16_HA;
+ break;
+ case BFD_RELOC_PPC64_TOC: r = R_PPC64_TOC;
+ break;
+ case BFD_RELOC_PPC64_PLTGOT16: r = R_PPC64_PLTGOT16;
+ break;
+ case BFD_RELOC_PPC64_PLTGOT16_LO: r = R_PPC64_PLTGOT16_LO;
+ break;
+ case BFD_RELOC_PPC64_PLTGOT16_HI: r = R_PPC64_PLTGOT16_HI;
+ break;
+ case BFD_RELOC_PPC64_PLTGOT16_HA: r = R_PPC64_PLTGOT16_HA;
+ break;
+ case BFD_RELOC_PPC64_ADDR16_DS: r = R_PPC64_ADDR16_DS;
+ break;
+ case BFD_RELOC_PPC64_ADDR16_LO_DS: r = R_PPC64_ADDR16_LO_DS;
+ break;
+ case BFD_RELOC_PPC64_GOT16_DS: r = R_PPC64_GOT16_DS;
+ break;
+ case BFD_RELOC_PPC64_GOT16_LO_DS: r = R_PPC64_GOT16_LO_DS;
+ break;
+ case BFD_RELOC_PPC64_PLT16_LO_DS: r = R_PPC64_PLT16_LO_DS;
+ break;
+ case BFD_RELOC_PPC64_SECTOFF_DS: r = R_PPC64_SECTOFF_DS;
+ break;
+ case BFD_RELOC_PPC64_SECTOFF_LO_DS: r = R_PPC64_SECTOFF_LO_DS;
+ break;
+ case BFD_RELOC_PPC64_TOC16_DS: r = R_PPC64_TOC16_DS;
+ break;
+ case BFD_RELOC_PPC64_TOC16_LO_DS: r = R_PPC64_TOC16_LO_DS;
+ break;
+ case BFD_RELOC_PPC64_PLTGOT16_DS: r = R_PPC64_PLTGOT16_DS;
+ break;
+ case BFD_RELOC_PPC64_PLTGOT16_LO_DS: r = R_PPC64_PLTGOT16_LO_DS;
+ break;
+ case BFD_RELOC_PPC_TLS: r = R_PPC64_TLS;
+ break;
+ case BFD_RELOC_PPC_TLSGD: r = R_PPC64_TLSGD;
+ break;
+ case BFD_RELOC_PPC_TLSLD: r = R_PPC64_TLSLD;
+ break;
+ case BFD_RELOC_PPC_DTPMOD: r = R_PPC64_DTPMOD64;
+ break;
+ case BFD_RELOC_PPC_TPREL16: r = R_PPC64_TPREL16;
+ break;
+ case BFD_RELOC_PPC_TPREL16_LO: r = R_PPC64_TPREL16_LO;
+ break;
+ case BFD_RELOC_PPC_TPREL16_HI: r = R_PPC64_TPREL16_HI;
+ break;
+ case BFD_RELOC_PPC64_TPREL16_HIGH: r = R_PPC64_TPREL16_HIGH;
+ break;
+ case BFD_RELOC_PPC_TPREL16_HA: r = R_PPC64_TPREL16_HA;
+ break;
+ case BFD_RELOC_PPC64_TPREL16_HIGHA: r = R_PPC64_TPREL16_HIGHA;
+ break;
+ case BFD_RELOC_PPC_TPREL: r = R_PPC64_TPREL64;
+ break;
+ case BFD_RELOC_PPC_DTPREL16: r = R_PPC64_DTPREL16;
+ break;
+ case BFD_RELOC_PPC_DTPREL16_LO: r = R_PPC64_DTPREL16_LO;
+ break;
+ case BFD_RELOC_PPC_DTPREL16_HI: r = R_PPC64_DTPREL16_HI;
+ break;
+ case BFD_RELOC_PPC64_DTPREL16_HIGH: r = R_PPC64_DTPREL16_HIGH;
+ break;
+ case BFD_RELOC_PPC_DTPREL16_HA: r = R_PPC64_DTPREL16_HA;
+ break;
+ case BFD_RELOC_PPC64_DTPREL16_HIGHA: r = R_PPC64_DTPREL16_HIGHA;
+ break;
+ case BFD_RELOC_PPC_DTPREL: r = R_PPC64_DTPREL64;
+ break;
+ case BFD_RELOC_PPC_GOT_TLSGD16: r = R_PPC64_GOT_TLSGD16;
+ break;
+ case BFD_RELOC_PPC_GOT_TLSGD16_LO: r = R_PPC64_GOT_TLSGD16_LO;
+ break;
+ case BFD_RELOC_PPC_GOT_TLSGD16_HI: r = R_PPC64_GOT_TLSGD16_HI;
+ break;
+ case BFD_RELOC_PPC_GOT_TLSGD16_HA: r = R_PPC64_GOT_TLSGD16_HA;
+ break;
+ case BFD_RELOC_PPC_GOT_TLSLD16: r = R_PPC64_GOT_TLSLD16;
+ break;
+ case BFD_RELOC_PPC_GOT_TLSLD16_LO: r = R_PPC64_GOT_TLSLD16_LO;
+ break;
+ case BFD_RELOC_PPC_GOT_TLSLD16_HI: r = R_PPC64_GOT_TLSLD16_HI;
+ break;
+ case BFD_RELOC_PPC_GOT_TLSLD16_HA: r = R_PPC64_GOT_TLSLD16_HA;
+ break;
+ case BFD_RELOC_PPC_GOT_TPREL16: r = R_PPC64_GOT_TPREL16_DS;
+ break;
+ case BFD_RELOC_PPC_GOT_TPREL16_LO: r = R_PPC64_GOT_TPREL16_LO_DS;
+ break;
+ case BFD_RELOC_PPC_GOT_TPREL16_HI: r = R_PPC64_GOT_TPREL16_HI;
+ break;
+ case BFD_RELOC_PPC_GOT_TPREL16_HA: r = R_PPC64_GOT_TPREL16_HA;
+ break;
+ case BFD_RELOC_PPC_GOT_DTPREL16: r = R_PPC64_GOT_DTPREL16_DS;
+ break;
+ case BFD_RELOC_PPC_GOT_DTPREL16_LO: r = R_PPC64_GOT_DTPREL16_LO_DS;
+ break;
+ case BFD_RELOC_PPC_GOT_DTPREL16_HI: r = R_PPC64_GOT_DTPREL16_HI;
+ break;
+ case BFD_RELOC_PPC_GOT_DTPREL16_HA: r = R_PPC64_GOT_DTPREL16_HA;
+ break;
+ case BFD_RELOC_PPC64_TPREL16_DS: r = R_PPC64_TPREL16_DS;
+ break;
+ case BFD_RELOC_PPC64_TPREL16_LO_DS: r = R_PPC64_TPREL16_LO_DS;
+ break;
+ case BFD_RELOC_PPC64_TPREL16_HIGHER: r = R_PPC64_TPREL16_HIGHER;
+ break;
+ case BFD_RELOC_PPC64_TPREL16_HIGHERA: r = R_PPC64_TPREL16_HIGHERA;
+ break;
+ case BFD_RELOC_PPC64_TPREL16_HIGHEST: r = R_PPC64_TPREL16_HIGHEST;
+ break;
+ case BFD_RELOC_PPC64_TPREL16_HIGHESTA: r = R_PPC64_TPREL16_HIGHESTA;
+ break;
+ case BFD_RELOC_PPC64_DTPREL16_DS: r = R_PPC64_DTPREL16_DS;
+ break;
+ case BFD_RELOC_PPC64_DTPREL16_LO_DS: r = R_PPC64_DTPREL16_LO_DS;
+ break;
+ case BFD_RELOC_PPC64_DTPREL16_HIGHER: r = R_PPC64_DTPREL16_HIGHER;
+ break;
+ case BFD_RELOC_PPC64_DTPREL16_HIGHERA: r = R_PPC64_DTPREL16_HIGHERA;
+ break;
+ case BFD_RELOC_PPC64_DTPREL16_HIGHEST: r = R_PPC64_DTPREL16_HIGHEST;
+ break;
+ case BFD_RELOC_PPC64_DTPREL16_HIGHESTA: r = R_PPC64_DTPREL16_HIGHESTA;
+ break;
+ case BFD_RELOC_16_PCREL: r = R_PPC64_REL16;
+ break;
+ case BFD_RELOC_LO16_PCREL: r = R_PPC64_REL16_LO;
+ break;
+ case BFD_RELOC_HI16_PCREL: r = R_PPC64_REL16_HI;
+ break;
+ case BFD_RELOC_HI16_S_PCREL: r = R_PPC64_REL16_HA;
+ break;
+ case BFD_RELOC_PPC64_ADDR64_LOCAL: r = R_PPC64_ADDR64_LOCAL;
+ break;
+ case BFD_RELOC_VTABLE_INHERIT: r = R_PPC64_GNU_VTINHERIT;
+ break;
+ case BFD_RELOC_VTABLE_ENTRY: r = R_PPC64_GNU_VTENTRY;
+ break;
+ }
+
+ return ppc64_elf_howto_table[r];
+};
+
+static reloc_howto_type *
+ppc64_elf_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ const char *r_name)
+{
+ unsigned int i;
+
+ for (i = 0;
+ i < sizeof (ppc64_elf_howto_raw) / sizeof (ppc64_elf_howto_raw[0]);
+ i++)
+ if (ppc64_elf_howto_raw[i].name != NULL
+ && strcasecmp (ppc64_elf_howto_raw[i].name, r_name) == 0)
+ return &ppc64_elf_howto_raw[i];
+
+ return NULL;
+}
+
+/* Set the howto pointer for a PowerPC ELF reloc. */
+
+static void
+ppc64_elf_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED, arelent *cache_ptr,
+ Elf_Internal_Rela *dst)
+{
+ unsigned int type;
+
+ /* Initialize howto table if needed. */
+ if (!ppc64_elf_howto_table[R_PPC64_ADDR32])
+ ppc_howto_init ();
+
+ type = ELF64_R_TYPE (dst->r_info);
+ if (type >= (sizeof (ppc64_elf_howto_table)
+ / sizeof (ppc64_elf_howto_table[0])))
+ {
+ (*_bfd_error_handler) (_("%B: invalid relocation type %d"),
+ abfd, (int) type);
+ type = R_PPC64_NONE;
+ }
+ cache_ptr->howto = ppc64_elf_howto_table[type];
+}
+
+/* Handle the R_PPC64_ADDR16_HA and similar relocs. */
+
+static bfd_reloc_status_type
+ppc64_elf_ha_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
+ void *data, asection *input_section,
+ bfd *output_bfd, char **error_message)
+{
+ /* If this is a relocatable link (output_bfd test tells us), just
+ call the generic function. Any adjustment will be done at final
+ link time. */
+ if (output_bfd != NULL)
+ return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
+ input_section, output_bfd, error_message);
+
+ /* Adjust the addend for sign extension of the low 16 bits.
+ We won't actually be using the low 16 bits, so trashing them
+ doesn't matter. */
+ reloc_entry->addend += 0x8000;
+ return bfd_reloc_continue;
+}
+
+static bfd_reloc_status_type
+ppc64_elf_branch_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
+ void *data, asection *input_section,
+ bfd *output_bfd, char **error_message)
+{
+ if (output_bfd != NULL)
+ return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
+ input_section, output_bfd, error_message);
+
+ if (strcmp (symbol->section->name, ".opd") == 0
+ && (symbol->section->owner->flags & DYNAMIC) == 0)
+ {
+ bfd_vma dest = opd_entry_value (symbol->section,
+ symbol->value + reloc_entry->addend,
+ NULL, NULL, FALSE);
+ if (dest != (bfd_vma) -1)
+ reloc_entry->addend = dest - (symbol->value
+ + symbol->section->output_section->vma
+ + symbol->section->output_offset);
+ }
+ else
+ {
+ elf_symbol_type *elfsym = (elf_symbol_type *) symbol;
+
+ if (symbol->section->owner != abfd
+ && abiversion (symbol->section->owner) >= 2)
+ {
+ unsigned int i;
+
+ for (i = 0; i < symbol->section->owner->symcount; ++i)
+ {
+ asymbol *symdef = symbol->section->owner->outsymbols[i];
+
+ if (strcmp (symdef->name, symbol->name) == 0)
+ {
+ elfsym = (elf_symbol_type *) symdef;
+ break;
+ }
+ }
+ }
+ reloc_entry->addend
+ += PPC64_LOCAL_ENTRY_OFFSET (elfsym->internal_elf_sym.st_other);
+ }
+ return bfd_reloc_continue;
+}
+
+static bfd_reloc_status_type
+ppc64_elf_brtaken_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
+ void *data, asection *input_section,
+ bfd *output_bfd, char **error_message)
+{
+ long insn;
+ enum elf_ppc64_reloc_type r_type;
+ bfd_size_type octets;
+ /* Assume 'at' branch hints. */
+ bfd_boolean is_isa_v2 = TRUE;
+
+ /* If this is a relocatable link (output_bfd test tells us), just
+ call the generic function. Any adjustment will be done at final
+ link time. */
+ if (output_bfd != NULL)
+ return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
+ input_section, output_bfd, error_message);
+
+ octets = reloc_entry->address * bfd_octets_per_byte (abfd);
+ insn = bfd_get_32 (abfd, (bfd_byte *) data + octets);
+ insn &= ~(0x01 << 21);
+ r_type = reloc_entry->howto->type;
+ if (r_type == R_PPC64_ADDR14_BRTAKEN
+ || r_type == R_PPC64_REL14_BRTAKEN)
+ insn |= 0x01 << 21; /* 'y' or 't' bit, lowest bit of BO field. */
+
+ if (is_isa_v2)
+ {
+ /* Set 'a' bit. This is 0b00010 in BO field for branch
+ on CR(BI) insns (BO == 001at or 011at), and 0b01000
+ for branch on CTR insns (BO == 1a00t or 1a01t). */
+ if ((insn & (0x14 << 21)) == (0x04 << 21))
+ insn |= 0x02 << 21;
+ else if ((insn & (0x14 << 21)) == (0x10 << 21))
+ insn |= 0x08 << 21;
+ else
+ goto out;
+ }
+ else
+ {
+ bfd_vma target = 0;
+ bfd_vma from;
+
+ if (!bfd_is_com_section (symbol->section))
+ target = symbol->value;
+ target += symbol->section->output_section->vma;
+ target += symbol->section->output_offset;
+ target += reloc_entry->addend;
+
+ from = (reloc_entry->address
+ + input_section->output_offset
+ + input_section->output_section->vma);
+
+ /* Invert 'y' bit if not the default. */
+ if ((bfd_signed_vma) (target - from) < 0)
+ insn ^= 0x01 << 21;
+ }
+ bfd_put_32 (abfd, insn, (bfd_byte *) data + octets);
+ out:
+ return ppc64_elf_branch_reloc (abfd, reloc_entry, symbol, data,
+ input_section, output_bfd, error_message);
+}
+
+static bfd_reloc_status_type
+ppc64_elf_sectoff_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
+ void *data, asection *input_section,
+ bfd *output_bfd, char **error_message)
+{
+ /* If this is a relocatable link (output_bfd test tells us), just
+ call the generic function. Any adjustment will be done at final
+ link time. */
+ if (output_bfd != NULL)
+ return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
+ input_section, output_bfd, error_message);
+
+ /* Subtract the symbol section base address. */
+ reloc_entry->addend -= symbol->section->output_section->vma;
+ return bfd_reloc_continue;
+}
+
+static bfd_reloc_status_type
+ppc64_elf_sectoff_ha_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
+ void *data, asection *input_section,
+ bfd *output_bfd, char **error_message)
+{
+ /* If this is a relocatable link (output_bfd test tells us), just
+ call the generic function. Any adjustment will be done at final
+ link time. */
+ if (output_bfd != NULL)
+ return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
+ input_section, output_bfd, error_message);
+
+ /* Subtract the symbol section base address. */
+ reloc_entry->addend -= symbol->section->output_section->vma;
+
+ /* Adjust the addend for sign extension of the low 16 bits. */
+ reloc_entry->addend += 0x8000;
+ return bfd_reloc_continue;
+}
+
+static bfd_reloc_status_type
+ppc64_elf_toc_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
+ void *data, asection *input_section,
+ bfd *output_bfd, char **error_message)
+{
+ bfd_vma TOCstart;
+
+ /* If this is a relocatable link (output_bfd test tells us), just
+ call the generic function. Any adjustment will be done at final
+ link time. */
+ if (output_bfd != NULL)
+ return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
+ input_section, output_bfd, error_message);
+
+ TOCstart = _bfd_get_gp_value (input_section->output_section->owner);
+ if (TOCstart == 0)
+ TOCstart = ppc64_elf_set_toc (NULL, input_section->output_section->owner);
+
+ /* Subtract the TOC base address. */
+ reloc_entry->addend -= TOCstart + TOC_BASE_OFF;
+ return bfd_reloc_continue;
+}
+
+static bfd_reloc_status_type
+ppc64_elf_toc_ha_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
+ void *data, asection *input_section,
+ bfd *output_bfd, char **error_message)
+{
+ bfd_vma TOCstart;
+
+ /* If this is a relocatable link (output_bfd test tells us), just
+ call the generic function. Any adjustment will be done at final
+ link time. */
+ if (output_bfd != NULL)
+ return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
+ input_section, output_bfd, error_message);
+
+ TOCstart = _bfd_get_gp_value (input_section->output_section->owner);
+ if (TOCstart == 0)
+ TOCstart = ppc64_elf_set_toc (NULL, input_section->output_section->owner);
+
+ /* Subtract the TOC base address. */
+ reloc_entry->addend -= TOCstart + TOC_BASE_OFF;
+
+ /* Adjust the addend for sign extension of the low 16 bits. */
+ reloc_entry->addend += 0x8000;
+ return bfd_reloc_continue;
+}
+
+static bfd_reloc_status_type
+ppc64_elf_toc64_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
+ void *data, asection *input_section,
+ bfd *output_bfd, char **error_message)
+{
+ bfd_vma TOCstart;
+ bfd_size_type octets;
+
+ /* If this is a relocatable link (output_bfd test tells us), just
+ call the generic function. Any adjustment will be done at final
+ link time. */
+ if (output_bfd != NULL)
+ return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
+ input_section, output_bfd, error_message);
+
+ TOCstart = _bfd_get_gp_value (input_section->output_section->owner);
+ if (TOCstart == 0)
+ TOCstart = ppc64_elf_set_toc (NULL, input_section->output_section->owner);
+
+ octets = reloc_entry->address * bfd_octets_per_byte (abfd);
+ bfd_put_64 (abfd, TOCstart + TOC_BASE_OFF, (bfd_byte *) data + octets);
+ return bfd_reloc_ok;
+}
+
+static bfd_reloc_status_type
+ppc64_elf_unhandled_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
+ void *data, asection *input_section,
+ bfd *output_bfd, char **error_message)
+{
+ /* If this is a relocatable link (output_bfd test tells us), just
+ call the generic function. Any adjustment will be done at final
+ link time. */
+ if (output_bfd != NULL)
+ return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
+ input_section, output_bfd, error_message);
+
+ if (error_message != NULL)
+ {
+ static char buf[60];
+ sprintf (buf, "generic linker can't handle %s",
+ reloc_entry->howto->name);
+ *error_message = buf;
+ }
+ return bfd_reloc_dangerous;
+}
+
+/* Track GOT entries needed for a given symbol. We might need more
+ than one got entry per symbol. */
+struct got_entry
+{
+ struct got_entry *next;
+
+ /* The symbol addend that we'll be placing in the GOT. */
+ bfd_vma addend;
+
+ /* Unlike other ELF targets, we use separate GOT entries for the same
+ symbol referenced from different input files. This is to support
+ automatic multiple TOC/GOT sections, where the TOC base can vary
+ from one input file to another. After partitioning into TOC groups
+ we merge entries within the group.
+
+ Point to the BFD owning this GOT entry. */
+ bfd *owner;
+
+ /* Zero for non-tls entries, or TLS_TLS and one of TLS_GD, TLS_LD,
+ TLS_TPREL or TLS_DTPREL for tls entries. */
+ unsigned char tls_type;
+
+ /* Non-zero if got.ent points to real entry. */
+ unsigned char is_indirect;
+
+ /* Reference count until size_dynamic_sections, GOT offset thereafter. */
+ union
+ {
+ bfd_signed_vma refcount;
+ bfd_vma offset;
+ struct got_entry *ent;
+ } got;
+};
+
+/* The same for PLT. */
+struct plt_entry
+{
+ struct plt_entry *next;
+
+ bfd_vma addend;
+
+ union
+ {
+ bfd_signed_vma refcount;
+ bfd_vma offset;
+ } plt;
+};
+
+struct ppc64_elf_obj_tdata
+{
+ struct elf_obj_tdata elf;
+
+ /* Shortcuts to dynamic linker sections. */
+ asection *got;
+ asection *relgot;
+
+ /* Used during garbage collection. We attach global symbols defined
+ on removed .opd entries to this section so that the sym is removed. */
+ asection *deleted_section;
+
+ /* TLS local dynamic got entry handling. Support for multiple GOT
+ sections means we potentially need one of these for each input bfd. */
+ struct got_entry tlsld_got;
+
+ union {
+ /* A copy of relocs before they are modified for --emit-relocs. */
+ Elf_Internal_Rela *relocs;
+
+ /* Section contents. */
+ bfd_byte *contents;
+ } opd;
+
+ /* Nonzero if this bfd has small toc/got relocs, ie. that expect
+ the reloc to be in the range -32768 to 32767. */
+ unsigned int has_small_toc_reloc : 1;
+
+ /* Set if toc/got ha relocs detected not using r2, or lo reloc
+ instruction not one we handle. */
+ unsigned int unexpected_toc_insn : 1;
+};
+
+#define ppc64_elf_tdata(bfd) \
+ ((struct ppc64_elf_obj_tdata *) (bfd)->tdata.any)
+
+#define ppc64_tlsld_got(bfd) \
+ (&ppc64_elf_tdata (bfd)->tlsld_got)
+
+#define is_ppc64_elf(bfd) \
+ (bfd_get_flavour (bfd) == bfd_target_elf_flavour \
+ && elf_object_id (bfd) == PPC64_ELF_DATA)
+
+/* Override the generic function because we store some extras. */
+
+static bfd_boolean
+ppc64_elf_mkobject (bfd *abfd)
+{
+ return bfd_elf_allocate_object (abfd, sizeof (struct ppc64_elf_obj_tdata),
+ PPC64_ELF_DATA);
+}
+
+/* Fix bad default arch selected for a 64 bit input bfd when the
+ default is 32 bit. */
+
+static bfd_boolean
+ppc64_elf_object_p (bfd *abfd)
+{
+ if (abfd->arch_info->the_default && abfd->arch_info->bits_per_word == 32)
+ {
+ Elf_Internal_Ehdr *i_ehdr = elf_elfheader (abfd);
+
+ if (i_ehdr->e_ident[EI_CLASS] == ELFCLASS64)
+ {
+ /* Relies on arch after 32 bit default being 64 bit default. */
+ abfd->arch_info = abfd->arch_info->next;
+ BFD_ASSERT (abfd->arch_info->bits_per_word == 64);
+ }
+ }
+ return TRUE;
+}
+
+/* Support for core dump NOTE sections. */
+
+static bfd_boolean
+ppc64_elf_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
+{
+ size_t offset, size;
+
+ if (note->descsz != 504)
+ return FALSE;
+
+ /* pr_cursig */
+ elf_tdata (abfd)->core->signal = bfd_get_16 (abfd, note->descdata + 12);
+
+ /* pr_pid */
+ elf_tdata (abfd)->core->lwpid = bfd_get_32 (abfd, note->descdata + 32);
+
+ /* pr_reg */
+ offset = 112;
+ size = 384;
+
+ /* Make a ".reg/999" section. */
+ return _bfd_elfcore_make_pseudosection (abfd, ".reg",
+ size, note->descpos + offset);
+}
+
+static bfd_boolean
+ppc64_elf_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
+{
+ if (note->descsz != 136)
+ return FALSE;
+
+ elf_tdata (abfd)->core->pid
+ = bfd_get_32 (abfd, note->descdata + 24);
+ elf_tdata (abfd)->core->program
+ = _bfd_elfcore_strndup (abfd, note->descdata + 40, 16);
+ elf_tdata (abfd)->core->command
+ = _bfd_elfcore_strndup (abfd, note->descdata + 56, 80);
+
+ return TRUE;
+}
+
+static char *
+ppc64_elf_write_core_note (bfd *abfd, char *buf, int *bufsiz, int note_type,
+ ...)
+{
+ switch (note_type)
+ {
+ default:
+ return NULL;
+
+ case NT_PRPSINFO:
+ {
+ char data[136];
+ va_list ap;
+
+ va_start (ap, note_type);
+ memset (data, 0, sizeof (data));
+ strncpy (data + 40, va_arg (ap, const char *), 16);
+ strncpy (data + 56, va_arg (ap, const char *), 80);
+ va_end (ap);
+ return elfcore_write_note (abfd, buf, bufsiz,
+ "CORE", note_type, data, sizeof (data));
+ }
+
+ case NT_PRSTATUS:
+ {
+ char data[504];
+ va_list ap;
+ long pid;
+ int cursig;
+ const void *greg;
+
+ va_start (ap, note_type);
+ memset (data, 0, 112);
+ pid = va_arg (ap, long);
+ bfd_put_32 (abfd, pid, data + 32);
+ cursig = va_arg (ap, int);
+ bfd_put_16 (abfd, cursig, data + 12);
+ greg = va_arg (ap, const void *);
+ memcpy (data + 112, greg, 384);
+ memset (data + 496, 0, 8);
+ va_end (ap);
+ return elfcore_write_note (abfd, buf, bufsiz,
+ "CORE", note_type, data, sizeof (data));
+ }
+ }
+}
+
+/* Add extra PPC sections. */
+
+static const struct bfd_elf_special_section ppc64_elf_special_sections[]=
+{
+ { STRING_COMMA_LEN (".plt"), 0, SHT_NOBITS, 0 },
+ { STRING_COMMA_LEN (".sbss"), -2, SHT_NOBITS, SHF_ALLOC + SHF_WRITE },
+ { STRING_COMMA_LEN (".sdata"), -2, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE },
+ { STRING_COMMA_LEN (".toc"), 0, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE },
+ { STRING_COMMA_LEN (".toc1"), 0, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE },
+ { STRING_COMMA_LEN (".tocbss"), 0, SHT_NOBITS, SHF_ALLOC + SHF_WRITE },
+ { NULL, 0, 0, 0, 0 }
+};
+
+enum _ppc64_sec_type {
+ sec_normal = 0,
+ sec_opd = 1,
+ sec_toc = 2
+};
+
+struct _ppc64_elf_section_data
+{
+ struct bfd_elf_section_data elf;
+
+ union
+ {
+ /* An array with one entry for each opd function descriptor. */
+ struct _opd_sec_data
+ {
+ /* Points to the function code section for local opd entries. */
+ asection **func_sec;
+
+ /* After editing .opd, adjust references to opd local syms. */
+ long *adjust;
+ } opd;
+
+ /* An array for toc sections, indexed by offset/8. */
+ struct _toc_sec_data
+ {
+ /* Specifies the relocation symbol index used at a given toc offset. */
+ unsigned *symndx;
+
+ /* And the relocation addend. */
+ bfd_vma *add;
+ } toc;
+ } u;
+
+ enum _ppc64_sec_type sec_type:2;
+
+ /* Flag set when small branches are detected. Used to
+ select suitable defaults for the stub group size. */
+ unsigned int has_14bit_branch:1;
+};
+
+#define ppc64_elf_section_data(sec) \
+ ((struct _ppc64_elf_section_data *) elf_section_data (sec))
+
+static bfd_boolean
+ppc64_elf_new_section_hook (bfd *abfd, asection *sec)
+{
+ if (!sec->used_by_bfd)
+ {
+ struct _ppc64_elf_section_data *sdata;
+ bfd_size_type amt = sizeof (*sdata);
+
+ sdata = bfd_zalloc (abfd, amt);
+ if (sdata == NULL)
+ return FALSE;
+ sec->used_by_bfd = sdata;
+ }
+
+ return _bfd_elf_new_section_hook (abfd, sec);
+}
+
+static struct _opd_sec_data *
+get_opd_info (asection * sec)
+{
+ if (sec != NULL
+ && ppc64_elf_section_data (sec) != NULL
+ && ppc64_elf_section_data (sec)->sec_type == sec_opd)
+ return &ppc64_elf_section_data (sec)->u.opd;
+ return NULL;
+}
+
+/* Parameters for the qsort hook. */
+static bfd_boolean synthetic_relocatable;
+
+/* qsort comparison function for ppc64_elf_get_synthetic_symtab. */
+
+static int
+compare_symbols (const void *ap, const void *bp)
+{
+ const asymbol *a = * (const asymbol **) ap;
+ const asymbol *b = * (const asymbol **) bp;
+
+ /* Section symbols first. */
+ if ((a->flags & BSF_SECTION_SYM) && !(b->flags & BSF_SECTION_SYM))
+ return -1;
+ if (!(a->flags & BSF_SECTION_SYM) && (b->flags & BSF_SECTION_SYM))
+ return 1;
+
+ /* then .opd symbols. */
+ if (strcmp (a->section->name, ".opd") == 0
+ && strcmp (b->section->name, ".opd") != 0)
+ return -1;
+ if (strcmp (a->section->name, ".opd") != 0
+ && strcmp (b->section->name, ".opd") == 0)
+ return 1;
+
+ /* then other code symbols. */
+ if ((a->section->flags & (SEC_CODE | SEC_ALLOC | SEC_THREAD_LOCAL))
+ == (SEC_CODE | SEC_ALLOC)
+ && (b->section->flags & (SEC_CODE | SEC_ALLOC | SEC_THREAD_LOCAL))
+ != (SEC_CODE | SEC_ALLOC))
+ return -1;
+
+ if ((a->section->flags & (SEC_CODE | SEC_ALLOC | SEC_THREAD_LOCAL))
+ != (SEC_CODE | SEC_ALLOC)
+ && (b->section->flags & (SEC_CODE | SEC_ALLOC | SEC_THREAD_LOCAL))
+ == (SEC_CODE | SEC_ALLOC))
+ return 1;
+
+ if (synthetic_relocatable)
+ {
+ if (a->section->id < b->section->id)
+ return -1;
+
+ if (a->section->id > b->section->id)
+ return 1;
+ }
+
+ if (a->value + a->section->vma < b->value + b->section->vma)
+ return -1;
+
+ if (a->value + a->section->vma > b->value + b->section->vma)
+ return 1;
+
+ /* For syms with the same value, prefer strong dynamic global function
+ syms over other syms. */
+ if ((a->flags & BSF_GLOBAL) != 0 && (b->flags & BSF_GLOBAL) == 0)
+ return -1;
+
+ if ((a->flags & BSF_GLOBAL) == 0 && (b->flags & BSF_GLOBAL) != 0)
+ return 1;
+
+ if ((a->flags & BSF_FUNCTION) != 0 && (b->flags & BSF_FUNCTION) == 0)
+ return -1;
+
+ if ((a->flags & BSF_FUNCTION) == 0 && (b->flags & BSF_FUNCTION) != 0)
+ return 1;
+
+ if ((a->flags & BSF_WEAK) == 0 && (b->flags & BSF_WEAK) != 0)
+ return -1;
+
+ if ((a->flags & BSF_WEAK) != 0 && (b->flags & BSF_WEAK) == 0)
+ return 1;
+
+ if ((a->flags & BSF_DYNAMIC) != 0 && (b->flags & BSF_DYNAMIC) == 0)
+ return -1;
+
+ if ((a->flags & BSF_DYNAMIC) == 0 && (b->flags & BSF_DYNAMIC) != 0)
+ return 1;
+
+ return 0;
+}
+
+/* Search SYMS for a symbol of the given VALUE. */
+
+static asymbol *
+sym_exists_at (asymbol **syms, long lo, long hi, int id, bfd_vma value)
+{
+ long mid;
+
+ if (id == -1)
+ {
+ while (lo < hi)
+ {
+ mid = (lo + hi) >> 1;
+ if (syms[mid]->value + syms[mid]->section->vma < value)
+ lo = mid + 1;
+ else if (syms[mid]->value + syms[mid]->section->vma > value)
+ hi = mid;
+ else
+ return syms[mid];
+ }
+ }
+ else
+ {
+ while (lo < hi)
+ {
+ mid = (lo + hi) >> 1;
+ if (syms[mid]->section->id < id)
+ lo = mid + 1;
+ else if (syms[mid]->section->id > id)
+ hi = mid;
+ else if (syms[mid]->value < value)
+ lo = mid + 1;
+ else if (syms[mid]->value > value)
+ hi = mid;
+ else
+ return syms[mid];
+ }
+ }
+ return NULL;
+}
+
+static bfd_boolean
+section_covers_vma (bfd *abfd ATTRIBUTE_UNUSED, asection *section, void *ptr)
+{
+ bfd_vma vma = *(bfd_vma *) ptr;
+ return ((section->flags & SEC_ALLOC) != 0
+ && section->vma <= vma
+ && vma < section->vma + section->size);
+}
+
+/* Create synthetic symbols, effectively restoring "dot-symbol" function
+ entry syms. Also generate @plt symbols for the glink branch table. */
+
+static long
+ppc64_elf_get_synthetic_symtab (bfd *abfd,
+ long static_count, asymbol **static_syms,
+ long dyn_count, asymbol **dyn_syms,
+ asymbol **ret)
+{
+ asymbol *s;
+ long i;
+ long count;
+ char *names;
+ long symcount, codesecsym, codesecsymend, secsymend, opdsymend;
+ asection *opd = NULL;
+ bfd_boolean relocatable = (abfd->flags & (EXEC_P | DYNAMIC)) == 0;
+ asymbol **syms;
+ int abi = abiversion (abfd);
+
+ *ret = NULL;
+
+ if (abi < 2)
+ {
+ opd = bfd_get_section_by_name (abfd, ".opd");
+ if (opd == NULL && abi == 1)
+ return 0;
+ }
+
+ symcount = static_count;
+ if (!relocatable)
+ symcount += dyn_count;
+ if (symcount == 0)
+ return 0;
+
+ syms = bfd_malloc ((symcount + 1) * sizeof (*syms));
+ if (syms == NULL)
+ return -1;
+
+ if (!relocatable && static_count != 0 && dyn_count != 0)
+ {
+ /* Use both symbol tables. */
+ memcpy (syms, static_syms, static_count * sizeof (*syms));
+ memcpy (syms + static_count, dyn_syms, (dyn_count + 1) * sizeof (*syms));
+ }
+ else if (!relocatable && static_count == 0)
+ memcpy (syms, dyn_syms, (symcount + 1) * sizeof (*syms));
+ else
+ memcpy (syms, static_syms, (symcount + 1) * sizeof (*syms));
+
+ synthetic_relocatable = relocatable;
+ qsort (syms, symcount, sizeof (*syms), compare_symbols);
+
+ if (!relocatable && symcount > 1)
+ {
+ long j;
+ /* Trim duplicate syms, since we may have merged the normal and
+ dynamic symbols. Actually, we only care about syms that have
+ different values, so trim any with the same value. */
+ for (i = 1, j = 1; i < symcount; ++i)
+ if (syms[i - 1]->value + syms[i - 1]->section->vma
+ != syms[i]->value + syms[i]->section->vma)
+ syms[j++] = syms[i];
+ symcount = j;
+ }
+
+ i = 0;
+ if (strcmp (syms[i]->section->name, ".opd") == 0)
+ ++i;
+ codesecsym = i;
+
+ for (; i < symcount; ++i)
+ if (((syms[i]->section->flags & (SEC_CODE | SEC_ALLOC | SEC_THREAD_LOCAL))
+ != (SEC_CODE | SEC_ALLOC))
+ || (syms[i]->flags & BSF_SECTION_SYM) == 0)
+ break;
+ codesecsymend = i;
+
+ for (; i < symcount; ++i)
+ if ((syms[i]->flags & BSF_SECTION_SYM) == 0)
+ break;
+ secsymend = i;
+
+ for (; i < symcount; ++i)
+ if (strcmp (syms[i]->section->name, ".opd") != 0)
+ break;
+ opdsymend = i;
+
+ for (; i < symcount; ++i)
+ if ((syms[i]->section->flags & (SEC_CODE | SEC_ALLOC | SEC_THREAD_LOCAL))
+ != (SEC_CODE | SEC_ALLOC))
+ break;
+ symcount = i;
+
+ count = 0;
+
+ if (relocatable)
+ {
+ bfd_boolean (*slurp_relocs) (bfd *, asection *, asymbol **, bfd_boolean);
+ arelent *r;
+ size_t size;
+ long relcount;
+
+ if (opdsymend == secsymend)
+ goto done;
+
+ slurp_relocs = get_elf_backend_data (abfd)->s->slurp_reloc_table;
+ relcount = (opd->flags & SEC_RELOC) ? opd->reloc_count : 0;
+ if (relcount == 0)
+ goto done;
+
+ if (!(*slurp_relocs) (abfd, opd, static_syms, FALSE))
+ {
+ count = -1;
+ goto done;
+ }
+
+ size = 0;
+ for (i = secsymend, r = opd->relocation; i < opdsymend; ++i)
+ {
+ asymbol *sym;
+
+ while (r < opd->relocation + relcount
+ && r->address < syms[i]->value + opd->vma)
+ ++r;
+
+ if (r == opd->relocation + relcount)
+ break;
+
+ if (r->address != syms[i]->value + opd->vma)
+ continue;
+
+ if (r->howto->type != R_PPC64_ADDR64)
+ continue;
+
+ sym = *r->sym_ptr_ptr;
+ if (!sym_exists_at (syms, opdsymend, symcount,
+ sym->section->id, sym->value + r->addend))
+ {
+ ++count;
+ size += sizeof (asymbol);
+ size += strlen (syms[i]->name) + 2;
+ }
+ }
+
+ s = *ret = bfd_malloc (size);
+ if (s == NULL)
+ {
+ count = -1;
+ goto done;
+ }
+
+ names = (char *) (s + count);
+
+ for (i = secsymend, r = opd->relocation; i < opdsymend; ++i)
+ {
+ asymbol *sym;
+
+ while (r < opd->relocation + relcount
+ && r->address < syms[i]->value + opd->vma)
+ ++r;
+
+ if (r == opd->relocation + relcount)
+ break;
+
+ if (r->address != syms[i]->value + opd->vma)
+ continue;
+
+ if (r->howto->type != R_PPC64_ADDR64)
+ continue;
+
+ sym = *r->sym_ptr_ptr;
+ if (!sym_exists_at (syms, opdsymend, symcount,
+ sym->section->id, sym->value + r->addend))
+ {
+ size_t len;
+
+ *s = *syms[i];
+ s->flags |= BSF_SYNTHETIC;
+ s->section = sym->section;
+ s->value = sym->value + r->addend;
+ s->name = names;
+ *names++ = '.';
+ len = strlen (syms[i]->name);
+ memcpy (names, syms[i]->name, len + 1);
+ names += len + 1;
+ /* Have udata.p point back to the original symbol this
+ synthetic symbol was derived from. */
+ s->udata.p = syms[i];
+ s++;
+ }
+ }
+ }
+ else
+ {
+ bfd_boolean (*slurp_relocs) (bfd *, asection *, asymbol **, bfd_boolean);
+ bfd_byte *contents = NULL;
+ size_t size;
+ long plt_count = 0;
+ bfd_vma glink_vma = 0, resolv_vma = 0;
+ asection *dynamic, *glink = NULL, *relplt = NULL;
+ arelent *p;
+
+ if (opd != NULL && !bfd_malloc_and_get_section (abfd, opd, &contents))
+ {
+ free_contents_and_exit:
+ if (contents)
+ free (contents);
+ count = -1;
+ goto done;
+ }
+
+ size = 0;
+ for (i = secsymend; i < opdsymend; ++i)
+ {
+ bfd_vma ent;
+
+ /* Ignore bogus symbols. */
+ if (syms[i]->value > opd->size - 8)
+ continue;
+
+ ent = bfd_get_64 (abfd, contents + syms[i]->value);
+ if (!sym_exists_at (syms, opdsymend, symcount, -1, ent))
+ {
+ ++count;
+ size += sizeof (asymbol);
+ size += strlen (syms[i]->name) + 2;
+ }
+ }
+
+ /* Get start of .glink stubs from DT_PPC64_GLINK. */
+ if (dyn_count != 0
+ && (dynamic = bfd_get_section_by_name (abfd, ".dynamic")) != NULL)
+ {
+ bfd_byte *dynbuf, *extdyn, *extdynend;
+ size_t extdynsize;
+ void (*swap_dyn_in) (bfd *, const void *, Elf_Internal_Dyn *);
+
+ if (!bfd_malloc_and_get_section (abfd, dynamic, &dynbuf))
+ goto free_contents_and_exit;
+
+ 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 + dynamic->size;
+ for (; extdyn < extdynend; extdyn += extdynsize)
+ {
+ Elf_Internal_Dyn dyn;
+ (*swap_dyn_in) (abfd, extdyn, &dyn);
+
+ if (dyn.d_tag == DT_NULL)
+ break;
+
+ if (dyn.d_tag == DT_PPC64_GLINK)
+ {
+ /* The first glink stub starts at offset 32; see
+ comment in ppc64_elf_finish_dynamic_sections. */
+ glink_vma = dyn.d_un.d_val + GLINK_CALL_STUB_SIZE - 8 * 4;
+ /* The .glink section usually does not survive the final
+ link; search for the section (usually .text) where the
+ glink stubs now reside. */
+ glink = bfd_sections_find_if (abfd, section_covers_vma,
+ &glink_vma);
+ break;
+ }
+ }
+
+ free (dynbuf);
+ }
+
+ if (glink != NULL)
+ {
+ /* Determine __glink trampoline by reading the relative branch
+ from the first glink stub. */
+ bfd_byte buf[4];
+ unsigned int off = 0;
+
+ while (bfd_get_section_contents (abfd, glink, buf,
+ glink_vma + off - glink->vma, 4))
+ {
+ unsigned int insn = bfd_get_32 (abfd, buf);
+ insn ^= B_DOT;
+ if ((insn & ~0x3fffffc) == 0)
+ {
+ resolv_vma = glink_vma + off + (insn ^ 0x2000000) - 0x2000000;
+ break;
+ }
+ off += 4;
+ if (off > 4)
+ break;
+ }
+
+ if (resolv_vma)
+ size += sizeof (asymbol) + sizeof ("__glink_PLTresolve");
+
+ relplt = bfd_get_section_by_name (abfd, ".rela.plt");
+ if (relplt != NULL)
+ {
+ slurp_relocs = get_elf_backend_data (abfd)->s->slurp_reloc_table;
+ if (! (*slurp_relocs) (abfd, relplt, dyn_syms, TRUE))
+ goto free_contents_and_exit;
+
+ plt_count = relplt->size / sizeof (Elf64_External_Rela);
+ size += plt_count * sizeof (asymbol);
+
+ p = relplt->relocation;
+ for (i = 0; i < plt_count; i++, p++)
+ {
+ size += strlen ((*p->sym_ptr_ptr)->name) + sizeof ("@plt");
+ if (p->addend != 0)
+ size += sizeof ("+0x") - 1 + 16;
+ }
+ }
+ }
+
+ s = *ret = bfd_malloc (size);
+ if (s == NULL)
+ goto free_contents_and_exit;
+
+ names = (char *) (s + count + plt_count + (resolv_vma != 0));
+
+ for (i = secsymend; i < opdsymend; ++i)
+ {
+ bfd_vma ent;
+
+ if (syms[i]->value > opd->size - 8)
+ continue;
+
+ ent = bfd_get_64 (abfd, contents + syms[i]->value);
+ if (!sym_exists_at (syms, opdsymend, symcount, -1, ent))
+ {
+ long lo, hi;
+ size_t len;
+ asection *sec = abfd->sections;
+
+ *s = *syms[i];
+ lo = codesecsym;
+ hi = codesecsymend;
+ while (lo < hi)
+ {
+ long mid = (lo + hi) >> 1;
+ if (syms[mid]->section->vma < ent)
+ lo = mid + 1;
+ else if (syms[mid]->section->vma > ent)
+ hi = mid;
+ else
+ {
+ sec = syms[mid]->section;
+ break;
+ }
+ }
+
+ if (lo >= hi && lo > codesecsym)
+ sec = syms[lo - 1]->section;
+
+ for (; sec != NULL; sec = sec->next)
+ {
+ if (sec->vma > ent)
+ break;
+ /* SEC_LOAD may not be set if SEC is from a separate debug
+ info file. */
+ if ((sec->flags & SEC_ALLOC) == 0)
+ break;
+ if ((sec->flags & SEC_CODE) != 0)
+ s->section = sec;
+ }
+ s->flags |= BSF_SYNTHETIC;
+ s->value = ent - s->section->vma;
+ s->name = names;
+ *names++ = '.';
+ len = strlen (syms[i]->name);
+ memcpy (names, syms[i]->name, len + 1);
+ names += len + 1;
+ /* Have udata.p point back to the original symbol this
+ synthetic symbol was derived from. */
+ s->udata.p = syms[i];
+ s++;
+ }
+ }
+ free (contents);
+
+ if (glink != NULL && relplt != NULL)
+ {
+ if (resolv_vma)
+ {
+ /* Add a symbol for the main glink trampoline. */
+ memset (s, 0, sizeof *s);
+ s->the_bfd = abfd;
+ s->flags = BSF_GLOBAL | BSF_SYNTHETIC;
+ s->section = glink;
+ s->value = resolv_vma - glink->vma;
+ s->name = names;
+ memcpy (names, "__glink_PLTresolve", sizeof ("__glink_PLTresolve"));
+ names += sizeof ("__glink_PLTresolve");
+ s++;
+ count++;
+ }
+
+ /* FIXME: It would be very much nicer to put sym@plt on the
+ stub rather than on the glink branch table entry. The
+ objdump disassembler would then use a sensible symbol
+ name on plt calls. The difficulty in doing so is
+ a) finding the stubs, and,
+ b) matching stubs against plt entries, and,
+ c) there can be multiple stubs for a given plt entry.
+
+ Solving (a) could be done by code scanning, but older
+ ppc64 binaries used different stubs to current code.
+ (b) is the tricky one since you need to known the toc
+ pointer for at least one function that uses a pic stub to
+ be able to calculate the plt address referenced.
+ (c) means gdb would need to set multiple breakpoints (or
+ find the glink branch itself) when setting breakpoints
+ for pending shared library loads. */
+ p = relplt->relocation;
+ for (i = 0; i < plt_count; i++, p++)
+ {
+ size_t len;
+
+ *s = **p->sym_ptr_ptr;
+ /* Undefined syms won't have BSF_LOCAL or BSF_GLOBAL set. Since
+ we are defining a symbol, ensure one of them is set. */
+ if ((s->flags & BSF_LOCAL) == 0)
+ s->flags |= BSF_GLOBAL;
+ s->flags |= BSF_SYNTHETIC;
+ s->section = glink;
+ s->value = glink_vma - glink->vma;
+ s->name = names;
+ s->udata.p = NULL;
+ len = strlen ((*p->sym_ptr_ptr)->name);
+ memcpy (names, (*p->sym_ptr_ptr)->name, len);
+ names += len;
+ if (p->addend != 0)
+ {
+ memcpy (names, "+0x", sizeof ("+0x") - 1);
+ names += sizeof ("+0x") - 1;
+ bfd_sprintf_vma (abfd, names, p->addend);
+ names += strlen (names);
+ }
+ memcpy (names, "@plt", sizeof ("@plt"));
+ names += sizeof ("@plt");
+ s++;
+ if (abi < 2)
+ {
+ glink_vma += 8;
+ if (i >= 0x8000)
+ glink_vma += 4;
+ }
+ else
+ glink_vma += 4;
+ }
+ count += plt_count;
+ }
+ }
+
+ done:
+ free (syms);
+ return count;
+}
+
+/* The following functions are specific to the ELF linker, while
+ functions above are used generally. Those named ppc64_elf_* are
+ called by the main ELF linker code. They appear in this file more
+ or less in the order in which they are called. eg.
+ ppc64_elf_check_relocs is called early in the link process,
+ ppc64_elf_finish_dynamic_sections is one of the last functions
+ called.
+
+ PowerPC64-ELF uses a similar scheme to PowerPC64-XCOFF in that
+ functions have both a function code symbol and a function descriptor
+ symbol. A call to foo in a relocatable object file looks like:
+
+ . .text
+ . x:
+ . bl .foo
+ . nop
+
+ The function definition in another object file might be:
+
+ . .section .opd
+ . foo: .quad .foo
+ . .quad .TOC.@tocbase
+ . .quad 0
+ .
+ . .text
+ . .foo: blr
+
+ When the linker resolves the call during a static link, the branch
+ unsurprisingly just goes to .foo and the .opd information is unused.
+ If the function definition is in a shared library, things are a little
+ different: The call goes via a plt call stub, the opd information gets
+ copied to the plt, and the linker patches the nop.
+
+ . x:
+ . bl .foo_stub
+ . ld 2,40(1)
+ .
+ .
+ . .foo_stub:
+ . std 2,40(1) # in practice, the call stub
+ . addis 11,2,Lfoo@toc@ha # is slightly optimized, but
+ . addi 11,11,Lfoo@toc@l # this is the general idea
+ . ld 12,0(11)
+ . ld 2,8(11)
+ . mtctr 12
+ . ld 11,16(11)
+ . bctr
+ .
+ . .section .plt
+ . Lfoo: reloc (R_PPC64_JMP_SLOT, foo)
+
+ The "reloc ()" notation is supposed to indicate that the linker emits
+ an R_PPC64_JMP_SLOT reloc against foo. The dynamic linker does the opd
+ copying.
+
+ What are the difficulties here? Well, firstly, the relocations
+ examined by the linker in check_relocs are against the function code
+ sym .foo, while the dynamic relocation in the plt is emitted against
+ the function descriptor symbol, foo. Somewhere along the line, we need
+ to carefully copy dynamic link information from one symbol to the other.
+ Secondly, the generic part of the elf linker will make .foo a dynamic
+ symbol as is normal for most other backends. We need foo dynamic
+ instead, at least for an application final link. However, when
+ creating a shared library containing foo, we need to have both symbols
+ dynamic so that references to .foo are satisfied during the early
+ stages of linking. Otherwise the linker might decide to pull in a
+ definition from some other object, eg. a static library.
+
+ Update: As of August 2004, we support a new convention. Function
+ calls may use the function descriptor symbol, ie. "bl foo". This
+ behaves exactly as "bl .foo". */
+
+/* Of those relocs that might be copied as dynamic relocs, this function
+ selects those that must be copied when linking a shared library,
+ even when the symbol is local. */
+
+static int
+must_be_dyn_reloc (struct bfd_link_info *info,
+ enum elf_ppc64_reloc_type r_type)
+{
+ switch (r_type)
+ {
+ default:
+ return 1;
+
+ case R_PPC64_REL32:
+ case R_PPC64_REL64:
+ case R_PPC64_REL30:
+ return 0;
+
+ case R_PPC64_TPREL16:
+ case R_PPC64_TPREL16_LO:
+ case R_PPC64_TPREL16_HI:
+ case R_PPC64_TPREL16_HA:
+ case R_PPC64_TPREL16_DS:
+ case R_PPC64_TPREL16_LO_DS:
+ case R_PPC64_TPREL16_HIGH:
+ case R_PPC64_TPREL16_HIGHA:
+ case R_PPC64_TPREL16_HIGHER:
+ case R_PPC64_TPREL16_HIGHERA:
+ case R_PPC64_TPREL16_HIGHEST:
+ case R_PPC64_TPREL16_HIGHESTA:
+ case R_PPC64_TPREL64:
+ return !info->executable;
+ }
+}
+
+/* If ELIMINATE_COPY_RELOCS is non-zero, the linker will try to avoid
+ copying dynamic variables from a shared lib into an app's dynbss
+ section, and instead use a dynamic relocation to point into the
+ shared lib. With code that gcc generates, it's vital that this be
+ enabled; In the PowerPC64 ABI, the address of a function is actually
+ the address of a function descriptor, which resides in the .opd
+ section. gcc uses the descriptor directly rather than going via the
+ GOT as some other ABI's do, which means that initialized function
+ pointers must reference the descriptor. Thus, a function pointer
+ initialized to the address of a function in a shared library will
+ either require a copy reloc, or a dynamic reloc. Using a copy reloc
+ redefines the function descriptor symbol to point to the copy. This
+ presents a problem as a plt entry for that function is also
+ initialized from the function descriptor symbol and the copy reloc
+ may not be initialized first. */
+#define ELIMINATE_COPY_RELOCS 1
+
+/* Section name for stubs is the associated section name plus this
+ string. */
+#define STUB_SUFFIX ".stub"
+
+/* Linker stubs.
+ ppc_stub_long_branch:
+ Used when a 14 bit branch (or even a 24 bit branch) can't reach its
+ destination, but a 24 bit branch in a stub section will reach.
+ . b dest
+
+ ppc_stub_plt_branch:
+ Similar to the above, but a 24 bit branch in the stub section won't
+ reach its destination.
+ . addis %r11,%r2,xxx@toc@ha
+ . ld %r12,xxx@toc@l(%r11)
+ . mtctr %r12
+ . bctr
+
+ ppc_stub_plt_call:
+ Used to call a function in a shared library. If it so happens that
+ the plt entry referenced crosses a 64k boundary, then an extra
+ "addi %r11,%r11,xxx@toc@l" will be inserted before the "mtctr".
+ . std %r2,40(%r1)
+ . addis %r11,%r2,xxx@toc@ha
+ . ld %r12,xxx+0@toc@l(%r11)
+ . mtctr %r12
+ . ld %r2,xxx+8@toc@l(%r11)
+ . ld %r11,xxx+16@toc@l(%r11)
+ . bctr
+
+ ppc_stub_long_branch and ppc_stub_plt_branch may also have additional
+ code to adjust the value and save r2 to support multiple toc sections.
+ A ppc_stub_long_branch with an r2 offset looks like:
+ . std %r2,40(%r1)
+ . addis %r2,%r2,off@ha
+ . addi %r2,%r2,off@l
+ . b dest
+
+ A ppc_stub_plt_branch with an r2 offset looks like:
+ . std %r2,40(%r1)
+ . addis %r11,%r2,xxx@toc@ha
+ . ld %r12,xxx@toc@l(%r11)
+ . addis %r2,%r2,off@ha
+ . addi %r2,%r2,off@l
+ . mtctr %r12
+ . bctr
+
+ In cases where the "addis" instruction would add zero, the "addis" is
+ omitted and following instructions modified slightly in some cases.
+*/
+
+enum ppc_stub_type {
+ ppc_stub_none,
+ ppc_stub_long_branch,
+ ppc_stub_long_branch_r2off,
+ ppc_stub_plt_branch,
+ ppc_stub_plt_branch_r2off,
+ ppc_stub_plt_call,
+ ppc_stub_plt_call_r2save,
+ ppc_stub_global_entry
+};
+
+struct ppc_stub_hash_entry {
+
+ /* Base hash table entry structure. */
+ struct bfd_hash_entry root;
+
+ enum ppc_stub_type stub_type;
+
+ /* The stub section. */
+ asection *stub_sec;
+
+ /* Offset within stub_sec of the beginning of this stub. */
+ bfd_vma stub_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. */
+ bfd_vma target_value;
+ asection *target_section;
+
+ /* The symbol table entry, if any, that this was derived from. */
+ struct ppc_link_hash_entry *h;
+ struct plt_entry *plt_ent;
+
+ /* Where this stub is being called from, or, in the case of combined
+ stub sections, the first input section in the group. */
+ asection *id_sec;
+
+ /* Symbol st_other. */
+ unsigned char other;
+};
+
+struct ppc_branch_hash_entry {
+
+ /* Base hash table entry structure. */
+ struct bfd_hash_entry root;
+
+ /* Offset within branch lookup table. */
+ unsigned int offset;
+
+ /* Generation marker. */
+ unsigned int iter;
+};
+
+/* Used to track dynamic relocations for local symbols. */
+struct ppc_dyn_relocs
+{
+ struct ppc_dyn_relocs *next;
+
+ /* The input section of the reloc. */
+ asection *sec;
+
+ /* Total number of relocs copied for the input section. */
+ unsigned int count : 31;
+
+ /* Whether this entry is for STT_GNU_IFUNC symbols. */
+ unsigned int ifunc : 1;
+};
+
+struct ppc_link_hash_entry
+{
+ struct elf_link_hash_entry elf;
+
+ union {
+ /* A pointer to the most recently used stub hash entry against this
+ symbol. */
+ struct ppc_stub_hash_entry *stub_cache;
+
+ /* A pointer to the next symbol starting with a '.' */
+ struct ppc_link_hash_entry *next_dot_sym;
+ } u;
+
+ /* Track dynamic relocs copied for this symbol. */
+ struct elf_dyn_relocs *dyn_relocs;
+
+ /* Link between function code and descriptor symbols. */
+ struct ppc_link_hash_entry *oh;
+
+ /* Flag function code and descriptor symbols. */
+ unsigned int is_func:1;
+ unsigned int is_func_descriptor:1;
+ unsigned int fake:1;
+
+ /* Whether global opd/toc sym has been adjusted or not.
+ After ppc64_elf_edit_opd/ppc64_elf_edit_toc has run, this flag
+ should be set for all globals defined in any opd/toc section. */
+ unsigned int adjust_done:1;
+
+ /* Set if we twiddled this symbol to weak at some stage. */
+ unsigned int was_undefined:1;
+
+ /* Contexts in which symbol is used in the GOT (or TOC).
+ TLS_GD .. TLS_EXPLICIT bits are or'd into the mask as the
+ corresponding relocs are encountered during check_relocs.
+ tls_optimize clears TLS_GD .. TLS_TPREL when optimizing to
+ indicate the corresponding GOT entry type is not needed.
+ tls_optimize may also set TLS_TPRELGD when a GD reloc turns into
+ a TPREL one. We use a separate flag rather than setting TPREL
+ just for convenience in distinguishing the two cases. */
+#define TLS_GD 1 /* GD reloc. */
+#define TLS_LD 2 /* LD reloc. */
+#define TLS_TPREL 4 /* TPREL reloc, => IE. */
+#define TLS_DTPREL 8 /* DTPREL reloc, => LD. */
+#define TLS_TLS 16 /* Any TLS reloc. */
+#define TLS_EXPLICIT 32 /* Marks TOC section TLS relocs. */
+#define TLS_TPRELGD 64 /* TPREL reloc resulting from GD->IE. */
+#define PLT_IFUNC 128 /* STT_GNU_IFUNC. */
+ unsigned char tls_mask;
+};
+
+/* ppc64 ELF linker hash table. */
+
+struct ppc_link_hash_table
+{
+ struct elf_link_hash_table elf;
+
+ /* The stub hash table. */
+ struct bfd_hash_table stub_hash_table;
+
+ /* Another hash table for plt_branch stubs. */
+ struct bfd_hash_table branch_hash_table;
+
+ /* Hash table for function prologue tocsave. */
+ htab_t tocsave_htab;
+
+ /* Various options and other info passed from the linker. */
+ struct ppc64_elf_params *params;
+
+ /* Array to keep track of which stub sections have been created, and
+ information on stub grouping. */
+ struct map_stub {
+ /* This is the section to which stubs in the group will be attached. */
+ asection *link_sec;
+ /* The stub section. */
+ asection *stub_sec;
+ /* Along with elf_gp, specifies the TOC pointer used in this group. */
+ bfd_vma toc_off;
+ } *stub_group;
+
+ /* Temp used when calculating TOC pointers. */
+ bfd_vma toc_curr;
+ bfd *toc_bfd;
+ asection *toc_first_sec;
+
+ /* Highest input section id. */
+ int top_id;
+
+ /* Highest output section index. */
+ int top_index;
+
+ /* Used when adding symbols. */
+ struct ppc_link_hash_entry *dot_syms;
+
+ /* List of input sections for each output section. */
+ asection **input_list;
+
+ /* Shortcuts to get to dynamic linker sections. */
+ asection *dynbss;
+ asection *relbss;
+ asection *glink;
+ asection *sfpr;
+ asection *brlt;
+ asection *relbrlt;
+ asection *glink_eh_frame;
+
+ /* Shortcut to .__tls_get_addr and __tls_get_addr. */
+ struct ppc_link_hash_entry *tls_get_addr;
+ struct ppc_link_hash_entry *tls_get_addr_fd;
+
+ /* The size of reliplt used by got entry relocs. */
+ bfd_size_type got_reli_size;
+
+ /* Statistics. */
+ unsigned long stub_count[ppc_stub_global_entry];
+
+ /* Number of stubs against global syms. */
+ unsigned long stub_globals;
+
+ /* Set if we're linking code with function descriptors. */
+ unsigned int opd_abi:1;
+
+ /* Support for multiple toc sections. */
+ unsigned int do_multi_toc:1;
+ unsigned int multi_toc_needed:1;
+ unsigned int second_toc_pass:1;
+ unsigned int do_toc_opt:1;
+
+ /* Set on error. */
+ unsigned int stub_error:1;
+
+ /* Temp used by ppc64_elf_before_check_relocs. */
+ unsigned int twiddled_syms:1;
+
+ /* Incremented every time we size stubs. */
+ unsigned int stub_iteration;
+
+ /* Small local sym cache. */
+ struct sym_cache sym_cache;
+};
+
+/* Rename some of the generic section flags to better document how they
+ are used here. */
+
+/* Nonzero if this section has TLS related relocations. */
+#define has_tls_reloc sec_flg0
+
+/* Nonzero if this section has a call to __tls_get_addr. */
+#define has_tls_get_addr_call sec_flg1
+
+/* Nonzero if this section has any toc or got relocs. */
+#define has_toc_reloc sec_flg2
+
+/* Nonzero if this section has a call to another section that uses
+ the toc or got. */
+#define makes_toc_func_call sec_flg3
+
+/* Recursion protection when determining above flag. */
+#define call_check_in_progress sec_flg4
+#define call_check_done sec_flg5
+
+/* Get the ppc64 ELF linker hash table from a link_info structure. */
+
+#define ppc_hash_table(p) \
+ (elf_hash_table_id ((struct elf_link_hash_table *) ((p)->hash)) \
+ == PPC64_ELF_DATA ? ((struct ppc_link_hash_table *) ((p)->hash)) : NULL)
+
+#define ppc_stub_hash_lookup(table, string, create, copy) \
+ ((struct ppc_stub_hash_entry *) \
+ bfd_hash_lookup ((table), (string), (create), (copy)))
+
+#define ppc_branch_hash_lookup(table, string, create, copy) \
+ ((struct ppc_branch_hash_entry *) \
+ bfd_hash_lookup ((table), (string), (create), (copy)))
+
+/* Create an entry in the stub hash table. */
+
+static struct bfd_hash_entry *
+stub_hash_newfunc (struct bfd_hash_entry *entry,
+ struct bfd_hash_table *table,
+ const char *string)
+{
+ /* Allocate the structure if it has not already been allocated by a
+ subclass. */
+ if (entry == NULL)
+ {
+ entry = bfd_hash_allocate (table, sizeof (struct ppc_stub_hash_entry));
+ if (entry == NULL)
+ return entry;
+ }
+
+ /* Call the allocation method of the superclass. */
+ entry = bfd_hash_newfunc (entry, table, string);
+ if (entry != NULL)
+ {
+ struct ppc_stub_hash_entry *eh;
+
+ /* Initialize the local fields. */
+ eh = (struct ppc_stub_hash_entry *) entry;
+ eh->stub_type = ppc_stub_none;
+ eh->stub_sec = NULL;
+ eh->stub_offset = 0;
+ eh->target_value = 0;
+ eh->target_section = NULL;
+ eh->h = NULL;
+ eh->plt_ent = NULL;
+ eh->id_sec = NULL;
+ eh->other = 0;
+ }
+
+ return entry;
+}
+
+/* Create an entry in the branch hash table. */
+
+static struct bfd_hash_entry *
+branch_hash_newfunc (struct bfd_hash_entry *entry,
+ struct bfd_hash_table *table,
+ const char *string)
+{
+ /* Allocate the structure if it has not already been allocated by a
+ subclass. */
+ if (entry == NULL)
+ {
+ entry = bfd_hash_allocate (table, sizeof (struct ppc_branch_hash_entry));
+ if (entry == NULL)
+ return entry;
+ }
+
+ /* Call the allocation method of the superclass. */
+ entry = bfd_hash_newfunc (entry, table, string);
+ if (entry != NULL)
+ {
+ struct ppc_branch_hash_entry *eh;
+
+ /* Initialize the local fields. */
+ eh = (struct ppc_branch_hash_entry *) entry;
+ eh->offset = 0;
+ eh->iter = 0;
+ }
+
+ return entry;
+}
+
+/* Create an entry in a ppc64 ELF linker hash table. */
+
+static struct bfd_hash_entry *
+link_hash_newfunc (struct bfd_hash_entry *entry,
+ struct bfd_hash_table *table,
+ const char *string)
+{
+ /* Allocate the structure if it has not already been allocated by a
+ subclass. */
+ if (entry == NULL)
+ {
+ entry = bfd_hash_allocate (table, sizeof (struct ppc_link_hash_entry));
+ if (entry == NULL)
+ return entry;
+ }
+
+ /* Call the allocation method of the superclass. */
+ entry = _bfd_elf_link_hash_newfunc (entry, table, string);
+ if (entry != NULL)
+ {
+ struct ppc_link_hash_entry *eh = (struct ppc_link_hash_entry *) entry;
+
+ memset (&eh->u.stub_cache, 0,
+ (sizeof (struct ppc_link_hash_entry)
+ - offsetof (struct ppc_link_hash_entry, u.stub_cache)));
+
+ /* When making function calls, old ABI code references function entry
+ points (dot symbols), while new ABI code references the function
+ descriptor symbol. We need to make any combination of reference and
+ definition work together, without breaking archive linking.
+
+ For a defined function "foo" and an undefined call to "bar":
+ An old object defines "foo" and ".foo", references ".bar" (possibly
+ "bar" too).
+ A new object defines "foo" and references "bar".
+
+ A new object thus has no problem with its undefined symbols being
+ satisfied by definitions in an old object. On the other hand, the
+ old object won't have ".bar" satisfied by a new object.
+
+ Keep a list of newly added dot-symbols. */
+
+ if (string[0] == '.')
+ {
+ struct ppc_link_hash_table *htab;
+
+ htab = (struct ppc_link_hash_table *) table;
+ eh->u.next_dot_sym = htab->dot_syms;
+ htab->dot_syms = eh;
+ }
+ }
+
+ return entry;
+}
+
+struct tocsave_entry {
+ asection *sec;
+ bfd_vma offset;
+};
+
+static hashval_t
+tocsave_htab_hash (const void *p)
+{
+ const struct tocsave_entry *e = (const struct tocsave_entry *) p;
+ return ((bfd_vma)(intptr_t) e->sec ^ e->offset) >> 3;
+}
+
+static int
+tocsave_htab_eq (const void *p1, const void *p2)
+{
+ const struct tocsave_entry *e1 = (const struct tocsave_entry *) p1;
+ const struct tocsave_entry *e2 = (const struct tocsave_entry *) p2;
+ return e1->sec == e2->sec && e1->offset == e2->offset;
+}
+
+/* Destroy a ppc64 ELF linker hash table. */
+
+static void
+ppc64_elf_link_hash_table_free (bfd *obfd)
+{
+ struct ppc_link_hash_table *htab;
+
+ htab = (struct ppc_link_hash_table *) obfd->link.hash;
+ if (htab->tocsave_htab)
+ htab_delete (htab->tocsave_htab);
+ bfd_hash_table_free (&htab->branch_hash_table);
+ bfd_hash_table_free (&htab->stub_hash_table);
+ _bfd_elf_link_hash_table_free (obfd);
+}
+
+/* Create a ppc64 ELF linker hash table. */
+
+static struct bfd_link_hash_table *
+ppc64_elf_link_hash_table_create (bfd *abfd)
+{
+ struct ppc_link_hash_table *htab;
+ bfd_size_type amt = sizeof (struct ppc_link_hash_table);
+
+ htab = bfd_zmalloc (amt);
+ if (htab == NULL)
+ return NULL;
+
+ if (!_bfd_elf_link_hash_table_init (&htab->elf, abfd, link_hash_newfunc,
+ sizeof (struct ppc_link_hash_entry),
+ PPC64_ELF_DATA))
+ {
+ free (htab);
+ return NULL;
+ }
+
+ /* Init the stub hash table too. */
+ if (!bfd_hash_table_init (&htab->stub_hash_table, stub_hash_newfunc,
+ sizeof (struct ppc_stub_hash_entry)))
+ {
+ _bfd_elf_link_hash_table_free (abfd);
+ return NULL;
+ }
+
+ /* And the branch hash table. */
+ if (!bfd_hash_table_init (&htab->branch_hash_table, branch_hash_newfunc,
+ sizeof (struct ppc_branch_hash_entry)))
+ {
+ bfd_hash_table_free (&htab->stub_hash_table);
+ _bfd_elf_link_hash_table_free (abfd);
+ return NULL;
+ }
+
+ htab->tocsave_htab = htab_try_create (1024,
+ tocsave_htab_hash,
+ tocsave_htab_eq,
+ NULL);
+ if (htab->tocsave_htab == NULL)
+ {
+ ppc64_elf_link_hash_table_free (abfd);
+ return NULL;
+ }
+ htab->elf.root.hash_table_free = ppc64_elf_link_hash_table_free;
+
+ /* Initializing two fields of the union is just cosmetic. We really
+ only care about glist, but when compiled on a 32-bit host the
+ bfd_vma fields are larger. Setting the bfd_vma to zero makes
+ debugger inspection of these fields look nicer. */
+ htab->elf.init_got_refcount.refcount = 0;
+ htab->elf.init_got_refcount.glist = NULL;
+ htab->elf.init_plt_refcount.refcount = 0;
+ htab->elf.init_plt_refcount.glist = NULL;
+ htab->elf.init_got_offset.offset = 0;
+ htab->elf.init_got_offset.glist = NULL;
+ htab->elf.init_plt_offset.offset = 0;
+ htab->elf.init_plt_offset.glist = NULL;
+
+ return &htab->elf.root;
+}
+
+/* Create sections for linker generated code. */
+
+static bfd_boolean
+create_linkage_sections (bfd *dynobj, struct bfd_link_info *info)
+{
+ struct ppc_link_hash_table *htab;
+ flagword flags;
+
+ htab = ppc_hash_table (info);
+
+ /* Create .sfpr for code to save and restore fp regs. */
+ flags = (SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_READONLY
+ | SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_LINKER_CREATED);
+ htab->sfpr = bfd_make_section_anyway_with_flags (dynobj, ".sfpr",
+ flags);
+ if (htab->sfpr == NULL
+ || ! bfd_set_section_alignment (dynobj, htab->sfpr, 2))
+ return FALSE;
+
+ /* Create .glink for lazy dynamic linking support. */
+ htab->glink = bfd_make_section_anyway_with_flags (dynobj, ".glink",
+ flags);
+ if (htab->glink == NULL
+ || ! bfd_set_section_alignment (dynobj, htab->glink, 3))
+ return FALSE;
+
+ if (!info->no_ld_generated_unwind_info)
+ {
+ flags = (SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_HAS_CONTENTS
+ | SEC_IN_MEMORY | SEC_LINKER_CREATED);
+ htab->glink_eh_frame = bfd_make_section_anyway_with_flags (dynobj,
+ ".eh_frame",
+ flags);
+ if (htab->glink_eh_frame == NULL
+ || !bfd_set_section_alignment (dynobj, htab->glink_eh_frame, 2))
+ return FALSE;
+ }
+
+ flags = SEC_ALLOC | SEC_LINKER_CREATED;
+ htab->elf.iplt = bfd_make_section_anyway_with_flags (dynobj, ".iplt", flags);
+ if (htab->elf.iplt == NULL
+ || ! bfd_set_section_alignment (dynobj, htab->elf.iplt, 3))
+ return FALSE;
+
+ flags = (SEC_ALLOC | SEC_LOAD | SEC_READONLY
+ | SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_LINKER_CREATED);
+ htab->elf.irelplt
+ = bfd_make_section_anyway_with_flags (dynobj, ".rela.iplt", flags);
+ if (htab->elf.irelplt == NULL
+ || ! bfd_set_section_alignment (dynobj, htab->elf.irelplt, 3))
+ return FALSE;
+
+ /* Create branch lookup table for plt_branch stubs. */
+ flags = (SEC_ALLOC | SEC_LOAD
+ | SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_LINKER_CREATED);
+ htab->brlt = bfd_make_section_anyway_with_flags (dynobj, ".branch_lt",
+ flags);
+ if (htab->brlt == NULL
+ || ! bfd_set_section_alignment (dynobj, htab->brlt, 3))
+ return FALSE;
+
+ if (!info->shared)
+ return TRUE;
+
+ flags = (SEC_ALLOC | SEC_LOAD | SEC_READONLY
+ | SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_LINKER_CREATED);
+ htab->relbrlt = bfd_make_section_anyway_with_flags (dynobj,
+ ".rela.branch_lt",
+ flags);
+ if (htab->relbrlt == NULL
+ || ! bfd_set_section_alignment (dynobj, htab->relbrlt, 3))
+ return FALSE;
+
+ return TRUE;
+}
+
+/* Satisfy the ELF linker by filling in some fields in our fake bfd. */
+
+bfd_boolean
+ppc64_elf_init_stub_bfd (struct bfd_link_info *info,
+ struct ppc64_elf_params *params)
+{
+ struct ppc_link_hash_table *htab;
+
+ elf_elfheader (params->stub_bfd)->e_ident[EI_CLASS] = ELFCLASS64;
+
+/* Always hook our dynamic sections into the first bfd, which is the
+ linker created stub bfd. This ensures that the GOT header is at
+ the start of the output TOC section. */
+ htab = ppc_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+ htab->elf.dynobj = params->stub_bfd;
+ htab->params = params;
+
+ if (info->relocatable)
+ return TRUE;
+
+ return create_linkage_sections (htab->elf.dynobj, info);
+}
+
+/* Build a name for an entry in the stub hash table. */
+
+static char *
+ppc_stub_name (const asection *input_section,
+ const asection *sym_sec,
+ const struct ppc_link_hash_entry *h,
+ const Elf_Internal_Rela *rel)
+{
+ char *stub_name;
+ ssize_t len;
+
+ /* rel->r_addend is actually 64 bit, but who uses more than +/- 2^31
+ offsets from a sym as a branch target? In fact, we could
+ probably assume the addend is always zero. */
+ BFD_ASSERT (((int) rel->r_addend & 0xffffffff) == rel->r_addend);
+
+ if (h)
+ {
+ len = 8 + 1 + strlen (h->elf.root.root.string) + 1 + 8 + 1;
+ stub_name = bfd_malloc (len);
+ if (stub_name == NULL)
+ return stub_name;
+
+ len = sprintf (stub_name, "%08x.%s+%x",
+ input_section->id & 0xffffffff,
+ h->elf.root.root.string,
+ (int) rel->r_addend & 0xffffffff);
+ }
+ else
+ {
+ len = 8 + 1 + 8 + 1 + 8 + 1 + 8 + 1;
+ stub_name = bfd_malloc (len);
+ if (stub_name == NULL)
+ return stub_name;
+
+ len = sprintf (stub_name, "%08x.%x:%x+%x",
+ input_section->id & 0xffffffff,
+ sym_sec->id & 0xffffffff,
+ (int) ELF64_R_SYM (rel->r_info) & 0xffffffff,
+ (int) rel->r_addend & 0xffffffff);
+ }
+ if (len > 2 && stub_name[len - 2] == '+' && stub_name[len - 1] == '0')
+ stub_name[len - 2] = 0;
+ return stub_name;
+}
+
+/* Look up an entry in the stub hash. Stub entries are cached because
+ creating the stub name takes a bit of time. */
+
+static struct ppc_stub_hash_entry *
+ppc_get_stub_entry (const asection *input_section,
+ const asection *sym_sec,
+ struct ppc_link_hash_entry *h,
+ const Elf_Internal_Rela *rel,
+ struct ppc_link_hash_table *htab)
+{
+ struct ppc_stub_hash_entry *stub_entry;
+ const asection *id_sec;
+
+ /* If this input section is part of a group of sections sharing one
+ stub section, then use the id of the first section in the group.
+ Stub names need to include a section id, as there may well be
+ more than one stub used to reach say, printf, and we need to
+ distinguish between them. */
+ id_sec = htab->stub_group[input_section->id].link_sec;
+
+ if (h != NULL && h->u.stub_cache != NULL
+ && h->u.stub_cache->h == h
+ && h->u.stub_cache->id_sec == id_sec)
+ {
+ stub_entry = h->u.stub_cache;
+ }
+ else
+ {
+ char *stub_name;
+
+ stub_name = ppc_stub_name (id_sec, sym_sec, h, rel);
+ if (stub_name == NULL)
+ return NULL;
+
+ stub_entry = ppc_stub_hash_lookup (&htab->stub_hash_table,
+ stub_name, FALSE, FALSE);
+ if (h != NULL)
+ h->u.stub_cache = stub_entry;
+
+ free (stub_name);
+ }
+
+ return stub_entry;
+}
+
+/* Add a new stub entry to the stub hash. Not all fields of the new
+ stub entry are initialised. */
+
+static struct ppc_stub_hash_entry *
+ppc_add_stub (const char *stub_name,
+ asection *section,
+ struct bfd_link_info *info)
+{
+ struct ppc_link_hash_table *htab = ppc_hash_table (info);
+ asection *link_sec;
+ asection *stub_sec;
+ struct ppc_stub_hash_entry *stub_entry;
+
+ link_sec = htab->stub_group[section->id].link_sec;
+ stub_sec = htab->stub_group[section->id].stub_sec;
+ if (stub_sec == NULL)
+ {
+ stub_sec = htab->stub_group[link_sec->id].stub_sec;
+ if (stub_sec == NULL)
+ {
+ size_t namelen;
+ bfd_size_type len;
+ char *s_name;
+
+ namelen = strlen (link_sec->name);
+ len = namelen + sizeof (STUB_SUFFIX);
+ s_name = bfd_alloc (htab->params->stub_bfd, len);
+ if (s_name == NULL)
+ return NULL;
+
+ memcpy (s_name, link_sec->name, namelen);
+ memcpy (s_name + namelen, STUB_SUFFIX, sizeof (STUB_SUFFIX));
+ stub_sec = (*htab->params->add_stub_section) (s_name, link_sec);
+ if (stub_sec == NULL)
+ return NULL;
+ htab->stub_group[link_sec->id].stub_sec = stub_sec;
+ }
+ htab->stub_group[section->id].stub_sec = stub_sec;
+ }
+
+ /* Enter this entry into the linker stub hash table. */
+ stub_entry = ppc_stub_hash_lookup (&htab->stub_hash_table, stub_name,
+ TRUE, FALSE);
+ if (stub_entry == NULL)
+ {
+ info->callbacks->einfo (_("%P: %B: cannot create stub entry %s\n"),
+ section->owner, stub_name);
+ return NULL;
+ }
+
+ stub_entry->stub_sec = stub_sec;
+ stub_entry->stub_offset = 0;
+ stub_entry->id_sec = link_sec;
+ return stub_entry;
+}
+
+/* Create .got and .rela.got sections in ABFD, and .got in dynobj if
+ not already done. */
+
+static bfd_boolean
+create_got_section (bfd *abfd, struct bfd_link_info *info)
+{
+ asection *got, *relgot;
+ flagword flags;
+ struct ppc_link_hash_table *htab = ppc_hash_table (info);
+
+ if (!is_ppc64_elf (abfd))
+ return FALSE;
+ if (htab == NULL)
+ return FALSE;
+
+ if (!htab->elf.sgot
+ && !_bfd_elf_create_got_section (htab->elf.dynobj, info))
+ return FALSE;
+
+ flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
+ | SEC_LINKER_CREATED);
+
+ got = bfd_make_section_anyway_with_flags (abfd, ".got", flags);
+ if (!got
+ || !bfd_set_section_alignment (abfd, got, 3))
+ return FALSE;
+
+ relgot = bfd_make_section_anyway_with_flags (abfd, ".rela.got",
+ flags | SEC_READONLY);
+ if (!relgot
+ || ! bfd_set_section_alignment (abfd, relgot, 3))
+ return FALSE;
+
+ ppc64_elf_tdata (abfd)->got = got;
+ ppc64_elf_tdata (abfd)->relgot = relgot;
+ return TRUE;
+}
+
+/* Create the dynamic sections, and set up shortcuts. */
+
+static bfd_boolean
+ppc64_elf_create_dynamic_sections (bfd *dynobj, struct bfd_link_info *info)
+{
+ struct ppc_link_hash_table *htab;
+
+ if (!_bfd_elf_create_dynamic_sections (dynobj, info))
+ return FALSE;
+
+ htab = ppc_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ htab->dynbss = bfd_get_linker_section (dynobj, ".dynbss");
+ if (!info->shared)
+ htab->relbss = bfd_get_linker_section (dynobj, ".rela.bss");
+
+ if (!htab->elf.sgot || !htab->elf.splt || !htab->elf.srelplt || !htab->dynbss
+ || (!info->shared && !htab->relbss))
+ abort ();
+
+ return TRUE;
+}
+
+/* Follow indirect and warning symbol links. */
+
+static inline struct bfd_link_hash_entry *
+follow_link (struct bfd_link_hash_entry *h)
+{
+ while (h->type == bfd_link_hash_indirect
+ || h->type == bfd_link_hash_warning)
+ h = h->u.i.link;
+ return h;
+}
+
+static inline struct elf_link_hash_entry *
+elf_follow_link (struct elf_link_hash_entry *h)
+{
+ return (struct elf_link_hash_entry *) follow_link (&h->root);
+}
+
+static inline struct ppc_link_hash_entry *
+ppc_follow_link (struct ppc_link_hash_entry *h)
+{
+ return (struct ppc_link_hash_entry *) follow_link (&h->elf.root);
+}
+
+/* Merge PLT info on FROM with that on TO. */
+
+static void
+move_plt_plist (struct ppc_link_hash_entry *from,
+ struct ppc_link_hash_entry *to)
+{
+ if (from->elf.plt.plist != NULL)
+ {
+ if (to->elf.plt.plist != NULL)
+ {
+ struct plt_entry **entp;
+ struct plt_entry *ent;
+
+ for (entp = &from->elf.plt.plist; (ent = *entp) != NULL; )
+ {
+ struct plt_entry *dent;
+
+ for (dent = to->elf.plt.plist; dent != NULL; dent = dent->next)
+ if (dent->addend == ent->addend)
+ {
+ dent->plt.refcount += ent->plt.refcount;
+ *entp = ent->next;
+ break;
+ }
+ if (dent == NULL)
+ entp = &ent->next;
+ }
+ *entp = to->elf.plt.plist;
+ }
+
+ to->elf.plt.plist = from->elf.plt.plist;
+ from->elf.plt.plist = NULL;
+ }
+}
+
+/* Copy the extra info we tack onto an elf_link_hash_entry. */
+
+static void
+ppc64_elf_copy_indirect_symbol (struct bfd_link_info *info,
+ struct elf_link_hash_entry *dir,
+ struct elf_link_hash_entry *ind)
+{
+ struct ppc_link_hash_entry *edir, *eind;
+
+ edir = (struct ppc_link_hash_entry *) dir;
+ eind = (struct ppc_link_hash_entry *) ind;
+
+ edir->is_func |= eind->is_func;
+ edir->is_func_descriptor |= eind->is_func_descriptor;
+ edir->tls_mask |= eind->tls_mask;
+ if (eind->oh != NULL)
+ edir->oh = ppc_follow_link (eind->oh);
+
+ /* If called to transfer flags for a weakdef during processing
+ of elf_adjust_dynamic_symbol, don't copy NON_GOT_REF.
+ We clear it ourselves for ELIMINATE_COPY_RELOCS. */
+ if (!(ELIMINATE_COPY_RELOCS
+ && eind->elf.root.type != bfd_link_hash_indirect
+ && edir->elf.dynamic_adjusted))
+ edir->elf.non_got_ref |= eind->elf.non_got_ref;
+
+ edir->elf.ref_dynamic |= eind->elf.ref_dynamic;
+ edir->elf.ref_regular |= eind->elf.ref_regular;
+ edir->elf.ref_regular_nonweak |= eind->elf.ref_regular_nonweak;
+ edir->elf.needs_plt |= eind->elf.needs_plt;
+ edir->elf.pointer_equality_needed |= eind->elf.pointer_equality_needed;
+
+ /* Copy over any dynamic relocs we may have on the indirect sym. */
+ if (eind->dyn_relocs != NULL)
+ {
+ if (edir->dyn_relocs != NULL)
+ {
+ struct elf_dyn_relocs **pp;
+ struct elf_dyn_relocs *p;
+
+ /* Add reloc counts against the indirect sym to the direct sym
+ list. Merge any entries against the same section. */
+ for (pp = &eind->dyn_relocs; (p = *pp) != NULL; )
+ {
+ struct elf_dyn_relocs *q;
+
+ for (q = edir->dyn_relocs; q != NULL; q = q->next)
+ if (q->sec == p->sec)
+ {
+ q->pc_count += p->pc_count;
+ q->count += p->count;
+ *pp = p->next;
+ break;
+ }
+ if (q == NULL)
+ pp = &p->next;
+ }
+ *pp = edir->dyn_relocs;
+ }
+
+ edir->dyn_relocs = eind->dyn_relocs;
+ eind->dyn_relocs = NULL;
+ }
+
+ /* If we were called to copy over info for a weak sym, that's all.
+ You might think dyn_relocs need not be copied over; After all,
+ both syms will be dynamic or both non-dynamic so we're just
+ moving reloc accounting around. However, ELIMINATE_COPY_RELOCS
+ code in ppc64_elf_adjust_dynamic_symbol needs to check for
+ dyn_relocs in read-only sections, and it does so on what is the
+ DIR sym here. */
+ if (eind->elf.root.type != bfd_link_hash_indirect)
+ return;
+
+ /* Copy over got entries that we may have already seen to the
+ symbol which just became indirect. */
+ if (eind->elf.got.glist != NULL)
+ {
+ if (edir->elf.got.glist != NULL)
+ {
+ struct got_entry **entp;
+ struct got_entry *ent;
+
+ for (entp = &eind->elf.got.glist; (ent = *entp) != NULL; )
+ {
+ struct got_entry *dent;
+
+ for (dent = edir->elf.got.glist; dent != NULL; dent = dent->next)
+ if (dent->addend == ent->addend
+ && dent->owner == ent->owner
+ && dent->tls_type == ent->tls_type)
+ {
+ dent->got.refcount += ent->got.refcount;
+ *entp = ent->next;
+ break;
+ }
+ if (dent == NULL)
+ entp = &ent->next;
+ }
+ *entp = edir->elf.got.glist;
+ }
+
+ edir->elf.got.glist = eind->elf.got.glist;
+ eind->elf.got.glist = NULL;
+ }
+
+ /* And plt entries. */
+ move_plt_plist (eind, edir);
+
+ if (eind->elf.dynindx != -1)
+ {
+ if (edir->elf.dynindx != -1)
+ _bfd_elf_strtab_delref (elf_hash_table (info)->dynstr,
+ edir->elf.dynstr_index);
+ edir->elf.dynindx = eind->elf.dynindx;
+ edir->elf.dynstr_index = eind->elf.dynstr_index;
+ eind->elf.dynindx = -1;
+ eind->elf.dynstr_index = 0;
+ }
+}
+
+/* Find the function descriptor hash entry from the given function code
+ hash entry FH. Link the entries via their OH fields. */
+
+static struct ppc_link_hash_entry *
+lookup_fdh (struct ppc_link_hash_entry *fh, struct ppc_link_hash_table *htab)
+{
+ struct ppc_link_hash_entry *fdh = fh->oh;
+
+ if (fdh == NULL)
+ {
+ const char *fd_name = fh->elf.root.root.string + 1;
+
+ fdh = (struct ppc_link_hash_entry *)
+ elf_link_hash_lookup (&htab->elf, fd_name, FALSE, FALSE, FALSE);
+ if (fdh == NULL)
+ return fdh;
+
+ fdh->is_func_descriptor = 1;
+ fdh->oh = fh;
+ fh->is_func = 1;
+ fh->oh = fdh;
+ }
+
+ return ppc_follow_link (fdh);
+}
+
+/* Make a fake function descriptor sym for the code sym FH. */
+
+static struct ppc_link_hash_entry *
+make_fdh (struct bfd_link_info *info,
+ struct ppc_link_hash_entry *fh)
+{
+ bfd *abfd;
+ asymbol *newsym;
+ struct bfd_link_hash_entry *bh;
+ struct ppc_link_hash_entry *fdh;
+
+ abfd = fh->elf.root.u.undef.abfd;
+ newsym = bfd_make_empty_symbol (abfd);
+ newsym->name = fh->elf.root.root.string + 1;
+ newsym->section = bfd_und_section_ptr;
+ newsym->value = 0;
+ newsym->flags = BSF_WEAK;
+
+ bh = NULL;
+ if (!_bfd_generic_link_add_one_symbol (info, abfd, newsym->name,
+ newsym->flags, newsym->section,
+ newsym->value, NULL, FALSE, FALSE,
+ &bh))
+ return NULL;
+
+ fdh = (struct ppc_link_hash_entry *) bh;
+ fdh->elf.non_elf = 0;
+ fdh->fake = 1;
+ fdh->is_func_descriptor = 1;
+ fdh->oh = fh;
+ fh->is_func = 1;
+ fh->oh = fdh;
+ return fdh;
+}
+
+/* Fix function descriptor symbols defined in .opd sections to be
+ function type. */
+
+static bfd_boolean
+ppc64_elf_add_symbol_hook (bfd *ibfd,
+ struct bfd_link_info *info,
+ Elf_Internal_Sym *isym,
+ const char **name,
+ flagword *flags ATTRIBUTE_UNUSED,
+ asection **sec,
+ bfd_vma *value)
+{
+ if ((ELF_ST_TYPE (isym->st_info) == STT_GNU_IFUNC
+ || ELF_ST_BIND (isym->st_info) == STB_GNU_UNIQUE)
+ && (ibfd->flags & DYNAMIC) == 0
+ && bfd_get_flavour (info->output_bfd) == bfd_target_elf_flavour)
+ elf_tdata (info->output_bfd)->has_gnu_symbols = TRUE;
+
+ if (*sec != NULL
+ && strcmp ((*sec)->name, ".opd") == 0)
+ {
+ asection *code_sec;
+
+ if (!(ELF_ST_TYPE (isym->st_info) == STT_GNU_IFUNC
+ || ELF_ST_TYPE (isym->st_info) == STT_FUNC))
+ isym->st_info = ELF_ST_INFO (ELF_ST_BIND (isym->st_info), STT_FUNC);
+
+ /* If the symbol is a function defined in .opd, and the function
+ code is in a discarded group, let it appear to be undefined. */
+ if (!info->relocatable
+ && (*sec)->reloc_count != 0
+ && opd_entry_value (*sec, *value, &code_sec, NULL,
+ FALSE) != (bfd_vma) -1
+ && discarded_section (code_sec))
+ {
+ *sec = bfd_und_section_ptr;
+ isym->st_shndx = SHN_UNDEF;
+ }
+ }
+
+ if ((STO_PPC64_LOCAL_MASK & isym->st_other) != 0)
+ {
+ if (abiversion (ibfd) == 0)
+ set_abiversion (ibfd, 2);
+ else if (abiversion (ibfd) == 1)
+ {
+ info->callbacks->einfo (_("%P: symbol '%s' has invalid st_other"
+ " for ABI version 1\n"), name);
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+/* Merge non-visibility st_other attributes: local entry point. */
+
+static void
+ppc64_elf_merge_symbol_attribute (struct elf_link_hash_entry *h,
+ const Elf_Internal_Sym *isym,
+ bfd_boolean definition,
+ bfd_boolean dynamic)
+{
+ if (definition && !dynamic)
+ h->other = ((isym->st_other & ~ELF_ST_VISIBILITY (-1))
+ | ELF_ST_VISIBILITY (h->other));
+}
+
+/* This function makes an old ABI object reference to ".bar" cause the
+ inclusion of a new ABI object archive that defines "bar".
+ NAME is a symbol defined in an archive. Return a symbol in the hash
+ table that might be satisfied by the archive symbols. */
+
+static struct elf_link_hash_entry *
+ppc64_elf_archive_symbol_lookup (bfd *abfd,
+ struct bfd_link_info *info,
+ const char *name)
+{
+ struct elf_link_hash_entry *h;
+ char *dot_name;
+ size_t len;
+
+ h = _bfd_elf_archive_symbol_lookup (abfd, info, name);
+ if (h != NULL
+ /* Don't return this sym if it is a fake function descriptor
+ created by add_symbol_adjust. */
+ && !(h->root.type == bfd_link_hash_undefweak
+ && ((struct ppc_link_hash_entry *) h)->fake))
+ return h;
+
+ if (name[0] == '.')
+ return h;
+
+ len = strlen (name);
+ dot_name = bfd_alloc (abfd, len + 2);
+ if (dot_name == NULL)
+ return (struct elf_link_hash_entry *) 0 - 1;
+ dot_name[0] = '.';
+ memcpy (dot_name + 1, name, len + 1);
+ h = _bfd_elf_archive_symbol_lookup (abfd, info, dot_name);
+ bfd_release (abfd, dot_name);
+ return h;
+}
+
+/* This function satisfies all old ABI object references to ".bar" if a
+ new ABI object defines "bar". Well, at least, undefined dot symbols
+ are made weak. This stops later archive searches from including an
+ object if we already have a function descriptor definition. It also
+ prevents the linker complaining about undefined symbols.
+ We also check and correct mismatched symbol visibility here. The
+ most restrictive visibility of the function descriptor and the
+ function entry symbol is used. */
+
+static bfd_boolean
+add_symbol_adjust (struct ppc_link_hash_entry *eh, struct bfd_link_info *info)
+{
+ struct ppc_link_hash_table *htab;
+ struct ppc_link_hash_entry *fdh;
+
+ if (eh->elf.root.type == bfd_link_hash_indirect)
+ return TRUE;
+
+ if (eh->elf.root.type == bfd_link_hash_warning)
+ eh = (struct ppc_link_hash_entry *) eh->elf.root.u.i.link;
+
+ if (eh->elf.root.root.string[0] != '.')
+ abort ();
+
+ htab = ppc_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ fdh = lookup_fdh (eh, htab);
+ if (fdh == NULL)
+ {
+ if (!info->relocatable
+ && (eh->elf.root.type == bfd_link_hash_undefined
+ || eh->elf.root.type == bfd_link_hash_undefweak)
+ && eh->elf.ref_regular)
+ {
+ /* Make an undefweak function descriptor sym, which is enough to
+ pull in an --as-needed shared lib, but won't cause link
+ errors. Archives are handled elsewhere. */
+ fdh = make_fdh (info, eh);
+ if (fdh == NULL)
+ return FALSE;
+ fdh->elf.ref_regular = 1;
+ }
+ }
+ else
+ {
+ unsigned entry_vis = ELF_ST_VISIBILITY (eh->elf.other) - 1;
+ unsigned descr_vis = ELF_ST_VISIBILITY (fdh->elf.other) - 1;
+ if (entry_vis < descr_vis)
+ fdh->elf.other += entry_vis - descr_vis;
+ else if (entry_vis > descr_vis)
+ eh->elf.other += descr_vis - entry_vis;
+
+ if ((fdh->elf.root.type == bfd_link_hash_defined
+ || fdh->elf.root.type == bfd_link_hash_defweak)
+ && eh->elf.root.type == bfd_link_hash_undefined)
+ {
+ eh->elf.root.type = bfd_link_hash_undefweak;
+ eh->was_undefined = 1;
+ htab->twiddled_syms = 1;
+ }
+ }
+
+ return TRUE;
+}
+
+/* Set up opd section info and abiversion for IBFD, and process list
+ of dot-symbols we made in link_hash_newfunc. */
+
+static bfd_boolean
+ppc64_elf_before_check_relocs (bfd *ibfd, struct bfd_link_info *info)
+{
+ struct ppc_link_hash_table *htab;
+ struct ppc_link_hash_entry **p, *eh;
+ asection *opd = bfd_get_section_by_name (ibfd, ".opd");
+
+ if (opd != NULL && opd->size != 0)
+ {
+ if (abiversion (ibfd) == 0)
+ set_abiversion (ibfd, 1);
+ else if (abiversion (ibfd) == 2)
+ {
+ info->callbacks->einfo (_("%P: %B .opd not allowed in ABI"
+ " version %d\n"),
+ ibfd, abiversion (ibfd));
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+
+ if ((ibfd->flags & DYNAMIC) == 0
+ && (opd->flags & SEC_RELOC) != 0
+ && opd->reloc_count != 0
+ && !bfd_is_abs_section (opd->output_section))
+ {
+ /* Garbage collection needs some extra help with .opd sections.
+ We don't want to necessarily keep everything referenced by
+ relocs in .opd, as that would keep all functions. Instead,
+ if we reference an .opd symbol (a function descriptor), we
+ want to keep the function code symbol's section. This is
+ easy for global symbols, but for local syms we need to keep
+ information about the associated function section. */
+ bfd_size_type amt;
+ asection **opd_sym_map;
+
+ amt = opd->size * sizeof (*opd_sym_map) / 8;
+ opd_sym_map = bfd_zalloc (ibfd, amt);
+ if (opd_sym_map == NULL)
+ return FALSE;
+ ppc64_elf_section_data (opd)->u.opd.func_sec = opd_sym_map;
+ BFD_ASSERT (ppc64_elf_section_data (opd)->sec_type == sec_normal);
+ ppc64_elf_section_data (opd)->sec_type = sec_opd;
+ }
+ }
+
+ if (!is_ppc64_elf (info->output_bfd))
+ return TRUE;
+ htab = ppc_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ /* For input files without an explicit abiversion in e_flags
+ we should have flagged any with symbol st_other bits set
+ as ELFv1 and above flagged those with .opd as ELFv2.
+ Set the output abiversion if not yet set, and for any input
+ still ambiguous, take its abiversion from the output.
+ Differences in ABI are reported later. */
+ if (abiversion (info->output_bfd) == 0)
+ set_abiversion (info->output_bfd, abiversion (ibfd));
+ else if (abiversion (ibfd) == 0)
+ set_abiversion (ibfd, abiversion (info->output_bfd));
+
+ p = &htab->dot_syms;
+ while ((eh = *p) != NULL)
+ {
+ *p = NULL;
+ if (&eh->elf == htab->elf.hgot)
+ ;
+ else if (htab->elf.hgot == NULL
+ && strcmp (eh->elf.root.root.string, ".TOC.") == 0)
+ htab->elf.hgot = &eh->elf;
+ else if (!add_symbol_adjust (eh, info))
+ return FALSE;
+ p = &eh->u.next_dot_sym;
+ }
+
+ /* Clear the list for non-ppc64 input files. */
+ p = &htab->dot_syms;
+ while ((eh = *p) != NULL)
+ {
+ *p = NULL;
+ p = &eh->u.next_dot_sym;
+ }
+
+ /* We need to fix the undefs list for any syms we have twiddled to
+ undef_weak. */
+ if (htab->twiddled_syms)
+ {
+ bfd_link_repair_undef_list (&htab->elf.root);
+ htab->twiddled_syms = 0;
+ }
+ return TRUE;
+}
+
+/* Undo hash table changes when an --as-needed input file is determined
+ not to be needed. */
+
+static bfd_boolean
+ppc64_elf_notice_as_needed (bfd *ibfd,
+ struct bfd_link_info *info,
+ enum notice_asneeded_action act)
+{
+ if (act == notice_not_needed)
+ {
+ struct ppc_link_hash_table *htab = ppc_hash_table (info);
+
+ if (htab == NULL)
+ return FALSE;
+
+ htab->dot_syms = NULL;
+ }
+ return _bfd_elf_notice_as_needed (ibfd, info, act);
+}
+
+/* If --just-symbols against a final linked binary, then assume we need
+ toc adjusting stubs when calling functions defined there. */
+
+static void
+ppc64_elf_link_just_syms (asection *sec, struct bfd_link_info *info)
+{
+ if ((sec->flags & SEC_CODE) != 0
+ && (sec->owner->flags & (EXEC_P | DYNAMIC)) != 0
+ && is_ppc64_elf (sec->owner))
+ {
+ if (abiversion (sec->owner) >= 2
+ || bfd_get_section_by_name (sec->owner, ".opd") != NULL)
+ sec->has_toc_reloc = 1;
+ }
+ _bfd_elf_link_just_syms (sec, info);
+}
+
+static struct plt_entry **
+update_local_sym_info (bfd *abfd, Elf_Internal_Shdr *symtab_hdr,
+ unsigned long r_symndx, bfd_vma r_addend, int tls_type)
+{
+ struct got_entry **local_got_ents = elf_local_got_ents (abfd);
+ struct plt_entry **local_plt;
+ unsigned char *local_got_tls_masks;
+
+ if (local_got_ents == NULL)
+ {
+ bfd_size_type size = symtab_hdr->sh_info;
+
+ size *= (sizeof (*local_got_ents)
+ + sizeof (*local_plt)
+ + sizeof (*local_got_tls_masks));
+ local_got_ents = bfd_zalloc (abfd, size);
+ if (local_got_ents == NULL)
+ return NULL;
+ elf_local_got_ents (abfd) = local_got_ents;
+ }
+
+ if ((tls_type & (PLT_IFUNC | TLS_EXPLICIT)) == 0)
+ {
+ struct got_entry *ent;
+
+ for (ent = local_got_ents[r_symndx]; ent != NULL; ent = ent->next)
+ if (ent->addend == r_addend
+ && ent->owner == abfd
+ && ent->tls_type == tls_type)
+ break;
+ if (ent == NULL)
+ {
+ bfd_size_type amt = sizeof (*ent);
+ ent = bfd_alloc (abfd, amt);
+ if (ent == NULL)
+ return FALSE;
+ ent->next = local_got_ents[r_symndx];
+ ent->addend = r_addend;
+ ent->owner = abfd;
+ ent->tls_type = tls_type;
+ ent->is_indirect = FALSE;
+ ent->got.refcount = 0;
+ local_got_ents[r_symndx] = ent;
+ }
+ ent->got.refcount += 1;
+ }
+
+ local_plt = (struct plt_entry **) (local_got_ents + symtab_hdr->sh_info);
+ local_got_tls_masks = (unsigned char *) (local_plt + symtab_hdr->sh_info);
+ local_got_tls_masks[r_symndx] |= tls_type;
+
+ return local_plt + r_symndx;
+}
+
+static bfd_boolean
+update_plt_info (bfd *abfd, struct plt_entry **plist, bfd_vma addend)
+{
+ struct plt_entry *ent;
+
+ for (ent = *plist; ent != NULL; ent = ent->next)
+ if (ent->addend == addend)
+ break;
+ if (ent == NULL)
+ {
+ bfd_size_type amt = sizeof (*ent);
+ ent = bfd_alloc (abfd, amt);
+ if (ent == NULL)
+ return FALSE;
+ ent->next = *plist;
+ ent->addend = addend;
+ ent->plt.refcount = 0;
+ *plist = ent;
+ }
+ ent->plt.refcount += 1;
+ return TRUE;
+}
+
+static bfd_boolean
+is_branch_reloc (enum elf_ppc64_reloc_type r_type)
+{
+ return (r_type == R_PPC64_REL24
+ || r_type == R_PPC64_REL14
+ || r_type == R_PPC64_REL14_BRTAKEN
+ || r_type == R_PPC64_REL14_BRNTAKEN
+ || r_type == R_PPC64_ADDR24
+ || r_type == R_PPC64_ADDR14
+ || r_type == R_PPC64_ADDR14_BRTAKEN
+ || r_type == R_PPC64_ADDR14_BRNTAKEN);
+}
+
+/* Look through the relocs for a section during the first phase, and
+ calculate needed space in the global offset table, procedure
+ linkage table, and dynamic reloc sections. */
+
+static bfd_boolean
+ppc64_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
+ asection *sec, const Elf_Internal_Rela *relocs)
+{
+ struct ppc_link_hash_table *htab;
+ 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;
+ asection **opd_sym_map;
+ struct elf_link_hash_entry *tga, *dottga;
+
+ if (info->relocatable)
+ return TRUE;
+
+ /* Don't do anything special with non-loaded, non-alloced sections.
+ In particular, any relocs in such sections should not affect GOT
+ and PLT reference counting (ie. we don't allow them to create GOT
+ or PLT entries), there's no possibility or desire to optimize TLS
+ relocs, and there's not much point in propagating relocs to shared
+ libs that the dynamic linker won't relocate. */
+ if ((sec->flags & SEC_ALLOC) == 0)
+ return TRUE;
+
+ BFD_ASSERT (is_ppc64_elf (abfd));
+
+ htab = ppc_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ tga = elf_link_hash_lookup (&htab->elf, "__tls_get_addr",
+ FALSE, FALSE, TRUE);
+ dottga = elf_link_hash_lookup (&htab->elf, ".__tls_get_addr",
+ FALSE, FALSE, TRUE);
+ symtab_hdr = &elf_symtab_hdr (abfd);
+ sym_hashes = elf_sym_hashes (abfd);
+ sreloc = NULL;
+ opd_sym_map = NULL;
+ if (ppc64_elf_section_data (sec) != NULL
+ && ppc64_elf_section_data (sec)->sec_type == sec_opd)
+ opd_sym_map = ppc64_elf_section_data (sec)->u.opd.func_sec;
+
+ rel_end = relocs + sec->reloc_count;
+ for (rel = relocs; rel < rel_end; rel++)
+ {
+ unsigned long r_symndx;
+ struct elf_link_hash_entry *h;
+ enum elf_ppc64_reloc_type r_type;
+ int tls_type;
+ struct _ppc64_elf_section_data *ppc64_sec;
+ struct plt_entry **ifunc;
+
+ 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];
+ h = elf_follow_link (h);
+
+ /* PR15323, ref flags aren't set for references in the same
+ object. */
+ h->root.non_ir_ref = 1;
+
+ if (h == htab->elf.hgot)
+ sec->has_toc_reloc = 1;
+ }
+
+ tls_type = 0;
+ ifunc = NULL;
+ if (h != NULL)
+ {
+ if (h->type == STT_GNU_IFUNC)
+ {
+ h->needs_plt = 1;
+ ifunc = &h->plt.plist;
+ }
+ }
+ else
+ {
+ Elf_Internal_Sym *isym = bfd_sym_from_r_symndx (&htab->sym_cache,
+ abfd, r_symndx);
+ if (isym == NULL)
+ return FALSE;
+
+ if (ELF_ST_TYPE (isym->st_info) == STT_GNU_IFUNC)
+ {
+ ifunc = update_local_sym_info (abfd, symtab_hdr, r_symndx,
+ rel->r_addend, PLT_IFUNC);
+ if (ifunc == NULL)
+ return FALSE;
+ }
+ }
+ r_type = ELF64_R_TYPE (rel->r_info);
+ if (is_branch_reloc (r_type))
+ {
+ if (h != NULL && (h == tga || h == dottga))
+ {
+ if (rel != relocs
+ && (ELF64_R_TYPE (rel[-1].r_info) == R_PPC64_TLSGD
+ || ELF64_R_TYPE (rel[-1].r_info) == R_PPC64_TLSLD))
+ /* We have a new-style __tls_get_addr call with a marker
+ reloc. */
+ ;
+ else
+ /* Mark this section as having an old-style call. */
+ sec->has_tls_get_addr_call = 1;
+ }
+
+ /* STT_GNU_IFUNC symbols must have a PLT entry. */
+ if (ifunc != NULL
+ && !update_plt_info (abfd, ifunc, rel->r_addend))
+ return FALSE;
+ }
+
+ switch (r_type)
+ {
+ case R_PPC64_TLSGD:
+ case R_PPC64_TLSLD:
+ /* These special tls relocs tie a call to __tls_get_addr with
+ its parameter symbol. */
+ break;
+
+ case R_PPC64_GOT_TLSLD16:
+ case R_PPC64_GOT_TLSLD16_LO:
+ case R_PPC64_GOT_TLSLD16_HI:
+ case R_PPC64_GOT_TLSLD16_HA:
+ tls_type = TLS_TLS | TLS_LD;
+ goto dogottls;
+
+ case R_PPC64_GOT_TLSGD16:
+ case R_PPC64_GOT_TLSGD16_LO:
+ case R_PPC64_GOT_TLSGD16_HI:
+ case R_PPC64_GOT_TLSGD16_HA:
+ tls_type = TLS_TLS | TLS_GD;
+ goto dogottls;
+
+ case R_PPC64_GOT_TPREL16_DS:
+ case R_PPC64_GOT_TPREL16_LO_DS:
+ case R_PPC64_GOT_TPREL16_HI:
+ case R_PPC64_GOT_TPREL16_HA:
+ if (info->shared)
+ info->flags |= DF_STATIC_TLS;
+ tls_type = TLS_TLS | TLS_TPREL;
+ goto dogottls;
+
+ case R_PPC64_GOT_DTPREL16_DS:
+ case R_PPC64_GOT_DTPREL16_LO_DS:
+ case R_PPC64_GOT_DTPREL16_HI:
+ case R_PPC64_GOT_DTPREL16_HA:
+ tls_type = TLS_TLS | TLS_DTPREL;
+ dogottls:
+ sec->has_tls_reloc = 1;
+ /* Fall thru */
+
+ case R_PPC64_GOT16:
+ case R_PPC64_GOT16_DS:
+ case R_PPC64_GOT16_HA:
+ case R_PPC64_GOT16_HI:
+ case R_PPC64_GOT16_LO:
+ case R_PPC64_GOT16_LO_DS:
+ /* This symbol requires a global offset table entry. */
+ sec->has_toc_reloc = 1;
+ if (r_type == R_PPC64_GOT_TLSLD16
+ || r_type == R_PPC64_GOT_TLSGD16
+ || r_type == R_PPC64_GOT_TPREL16_DS
+ || r_type == R_PPC64_GOT_DTPREL16_DS
+ || r_type == R_PPC64_GOT16
+ || r_type == R_PPC64_GOT16_DS)
+ {
+ htab->do_multi_toc = 1;
+ ppc64_elf_tdata (abfd)->has_small_toc_reloc = 1;
+ }
+
+ if (ppc64_elf_tdata (abfd)->got == NULL
+ && !create_got_section (abfd, info))
+ return FALSE;
+
+ if (h != NULL)
+ {
+ struct ppc_link_hash_entry *eh;
+ struct got_entry *ent;
+
+ eh = (struct ppc_link_hash_entry *) h;
+ for (ent = eh->elf.got.glist; ent != NULL; ent = ent->next)
+ if (ent->addend == rel->r_addend
+ && ent->owner == abfd
+ && ent->tls_type == tls_type)
+ break;
+ if (ent == NULL)
+ {
+ bfd_size_type amt = sizeof (*ent);
+ ent = bfd_alloc (abfd, amt);
+ if (ent == NULL)
+ return FALSE;
+ ent->next = eh->elf.got.glist;
+ ent->addend = rel->r_addend;
+ ent->owner = abfd;
+ ent->tls_type = tls_type;
+ ent->is_indirect = FALSE;
+ ent->got.refcount = 0;
+ eh->elf.got.glist = ent;
+ }
+ ent->got.refcount += 1;
+ eh->tls_mask |= tls_type;
+ }
+ else
+ /* This is a global offset table entry for a local symbol. */
+ if (!update_local_sym_info (abfd, symtab_hdr, r_symndx,
+ rel->r_addend, tls_type))
+ return FALSE;
+
+ /* We may also need a plt entry if the symbol turns out to be
+ an ifunc. */
+ if (h != NULL && !info->shared && abiversion (abfd) != 1)
+ {
+ if (!update_plt_info (abfd, &h->plt.plist, rel->r_addend))
+ return FALSE;
+ }
+ break;
+
+ case R_PPC64_PLT16_HA:
+ case R_PPC64_PLT16_HI:
+ case R_PPC64_PLT16_LO:
+ case R_PPC64_PLT32:
+ case R_PPC64_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;
+ }
+ else
+ {
+ if (!update_plt_info (abfd, &h->plt.plist, rel->r_addend))
+ return FALSE;
+ h->needs_plt = 1;
+ if (h->root.root.string[0] == '.'
+ && h->root.root.string[1] != '\0')
+ ((struct ppc_link_hash_entry *) h)->is_func = 1;
+ }
+ break;
+
+ /* The following relocations don't need to propagate the
+ relocation if linking a shared object since they are
+ section relative. */
+ case R_PPC64_SECTOFF:
+ case R_PPC64_SECTOFF_LO:
+ case R_PPC64_SECTOFF_HI:
+ case R_PPC64_SECTOFF_HA:
+ case R_PPC64_SECTOFF_DS:
+ case R_PPC64_SECTOFF_LO_DS:
+ case R_PPC64_DTPREL16:
+ case R_PPC64_DTPREL16_LO:
+ case R_PPC64_DTPREL16_HI:
+ case R_PPC64_DTPREL16_HA:
+ case R_PPC64_DTPREL16_DS:
+ case R_PPC64_DTPREL16_LO_DS:
+ case R_PPC64_DTPREL16_HIGH:
+ case R_PPC64_DTPREL16_HIGHA:
+ case R_PPC64_DTPREL16_HIGHER:
+ case R_PPC64_DTPREL16_HIGHERA:
+ case R_PPC64_DTPREL16_HIGHEST:
+ case R_PPC64_DTPREL16_HIGHESTA:
+ break;
+
+ /* Nor do these. */
+ case R_PPC64_REL16:
+ case R_PPC64_REL16_LO:
+ case R_PPC64_REL16_HI:
+ case R_PPC64_REL16_HA:
+ break;
+
+ /* Not supported as a dynamic relocation. */
+ case R_PPC64_ADDR64_LOCAL:
+ if (info->shared)
+ {
+ if (!ppc64_elf_howto_table[R_PPC64_ADDR32])
+ ppc_howto_init ();
+ info->callbacks->einfo (_("%P: %H: %s reloc unsupported "
+ "in shared libraries and PIEs.\n"),
+ abfd, sec, rel->r_offset,
+ ppc64_elf_howto_table[r_type]->name);
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+ break;
+
+ case R_PPC64_TOC16:
+ case R_PPC64_TOC16_DS:
+ htab->do_multi_toc = 1;
+ ppc64_elf_tdata (abfd)->has_small_toc_reloc = 1;
+ case R_PPC64_TOC16_LO:
+ case R_PPC64_TOC16_HI:
+ case R_PPC64_TOC16_HA:
+ case R_PPC64_TOC16_LO_DS:
+ sec->has_toc_reloc = 1;
+ break;
+
+ /* This relocation describes the C++ object vtable hierarchy.
+ Reconstruct it for later use during GC. */
+ case R_PPC64_GNU_VTINHERIT:
+ if (!bfd_elf_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_PPC64_GNU_VTENTRY:
+ BFD_ASSERT (h != NULL);
+ if (h != NULL
+ && !bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
+ return FALSE;
+ break;
+
+ case R_PPC64_REL14:
+ case R_PPC64_REL14_BRTAKEN:
+ case R_PPC64_REL14_BRNTAKEN:
+ {
+ asection *dest = NULL;
+
+ /* Heuristic: If jumping outside our section, chances are
+ we are going to need a stub. */
+ if (h != NULL)
+ {
+ /* If the sym is weak it may be overridden later, so
+ don't assume we know where a weak sym lives. */
+ if (h->root.type == bfd_link_hash_defined)
+ dest = h->root.u.def.section;
+ }
+ else
+ {
+ Elf_Internal_Sym *isym;
+
+ isym = bfd_sym_from_r_symndx (&htab->sym_cache,
+ abfd, r_symndx);
+ if (isym == NULL)
+ return FALSE;
+
+ dest = bfd_section_from_elf_index (abfd, isym->st_shndx);
+ }
+
+ if (dest != sec)
+ ppc64_elf_section_data (sec)->has_14bit_branch = 1;
+ }
+ /* Fall through. */
+
+ case R_PPC64_REL24:
+ if (h != NULL && ifunc == NULL)
+ {
+ /* We may need a .plt entry if the function this reloc
+ refers to is in a shared lib. */
+ if (!update_plt_info (abfd, &h->plt.plist, rel->r_addend))
+ return FALSE;
+ h->needs_plt = 1;
+ if (h->root.root.string[0] == '.'
+ && h->root.root.string[1] != '\0')
+ ((struct ppc_link_hash_entry *) h)->is_func = 1;
+ if (h == tga || h == dottga)
+ sec->has_tls_reloc = 1;
+ }
+ break;
+
+ case R_PPC64_TPREL64:
+ tls_type = TLS_EXPLICIT | TLS_TLS | TLS_TPREL;
+ if (info->shared)
+ info->flags |= DF_STATIC_TLS;
+ goto dotlstoc;
+
+ case R_PPC64_DTPMOD64:
+ if (rel + 1 < rel_end
+ && rel[1].r_info == ELF64_R_INFO (r_symndx, R_PPC64_DTPREL64)
+ && rel[1].r_offset == rel->r_offset + 8)
+ tls_type = TLS_EXPLICIT | TLS_TLS | TLS_GD;
+ else
+ tls_type = TLS_EXPLICIT | TLS_TLS | TLS_LD;
+ goto dotlstoc;
+
+ case R_PPC64_DTPREL64:
+ tls_type = TLS_EXPLICIT | TLS_TLS | TLS_DTPREL;
+ if (rel != relocs
+ && rel[-1].r_info == ELF64_R_INFO (r_symndx, R_PPC64_DTPMOD64)
+ && rel[-1].r_offset == rel->r_offset - 8)
+ /* This is the second reloc of a dtpmod, dtprel pair.
+ Don't mark with TLS_DTPREL. */
+ goto dodyn;
+
+ dotlstoc:
+ sec->has_tls_reloc = 1;
+ if (h != NULL)
+ {
+ struct ppc_link_hash_entry *eh;
+ eh = (struct ppc_link_hash_entry *) h;
+ eh->tls_mask |= tls_type;
+ }
+ else
+ if (!update_local_sym_info (abfd, symtab_hdr, r_symndx,
+ rel->r_addend, tls_type))
+ return FALSE;
+
+ ppc64_sec = ppc64_elf_section_data (sec);
+ if (ppc64_sec->sec_type != sec_toc)
+ {
+ bfd_size_type amt;
+
+ /* One extra to simplify get_tls_mask. */
+ amt = sec->size * sizeof (unsigned) / 8 + sizeof (unsigned);
+ ppc64_sec->u.toc.symndx = bfd_zalloc (abfd, amt);
+ if (ppc64_sec->u.toc.symndx == NULL)
+ return FALSE;
+ amt = sec->size * sizeof (bfd_vma) / 8;
+ ppc64_sec->u.toc.add = bfd_zalloc (abfd, amt);
+ if (ppc64_sec->u.toc.add == NULL)
+ return FALSE;
+ BFD_ASSERT (ppc64_sec->sec_type == sec_normal);
+ ppc64_sec->sec_type = sec_toc;
+ }
+ BFD_ASSERT (rel->r_offset % 8 == 0);
+ ppc64_sec->u.toc.symndx[rel->r_offset / 8] = r_symndx;
+ ppc64_sec->u.toc.add[rel->r_offset / 8] = rel->r_addend;
+
+ /* Mark the second slot of a GD or LD entry.
+ -1 to indicate GD and -2 to indicate LD. */
+ if (tls_type == (TLS_EXPLICIT | TLS_TLS | TLS_GD))
+ ppc64_sec->u.toc.symndx[rel->r_offset / 8 + 1] = -1;
+ else if (tls_type == (TLS_EXPLICIT | TLS_TLS | TLS_LD))
+ ppc64_sec->u.toc.symndx[rel->r_offset / 8 + 1] = -2;
+ goto dodyn;
+
+ case R_PPC64_TPREL16:
+ case R_PPC64_TPREL16_LO:
+ case R_PPC64_TPREL16_HI:
+ case R_PPC64_TPREL16_HA:
+ case R_PPC64_TPREL16_DS:
+ case R_PPC64_TPREL16_LO_DS:
+ case R_PPC64_TPREL16_HIGH:
+ case R_PPC64_TPREL16_HIGHA:
+ case R_PPC64_TPREL16_HIGHER:
+ case R_PPC64_TPREL16_HIGHERA:
+ case R_PPC64_TPREL16_HIGHEST:
+ case R_PPC64_TPREL16_HIGHESTA:
+ if (info->shared)
+ {
+ info->flags |= DF_STATIC_TLS;
+ goto dodyn;
+ }
+ break;
+
+ case R_PPC64_ADDR64:
+ if (opd_sym_map != NULL
+ && rel + 1 < rel_end
+ && ELF64_R_TYPE ((rel + 1)->r_info) == R_PPC64_TOC)
+ {
+ if (h != NULL)
+ {
+ if (h->root.root.string[0] == '.'
+ && h->root.root.string[1] != 0
+ && lookup_fdh ((struct ppc_link_hash_entry *) h, htab))
+ ;
+ else
+ ((struct ppc_link_hash_entry *) h)->is_func = 1;
+ }
+ else
+ {
+ asection *s;
+ Elf_Internal_Sym *isym;
+
+ isym = bfd_sym_from_r_symndx (&htab->sym_cache,
+ abfd, r_symndx);
+ if (isym == NULL)
+ return FALSE;
+
+ s = bfd_section_from_elf_index (abfd, isym->st_shndx);
+ if (s != NULL && s != sec)
+ opd_sym_map[rel->r_offset / 8] = s;
+ }
+ }
+ /* Fall through. */
+
+ case R_PPC64_ADDR16:
+ case R_PPC64_ADDR16_DS:
+ case R_PPC64_ADDR16_HA:
+ case R_PPC64_ADDR16_HI:
+ case R_PPC64_ADDR16_HIGH:
+ case R_PPC64_ADDR16_HIGHA:
+ case R_PPC64_ADDR16_HIGHER:
+ case R_PPC64_ADDR16_HIGHERA:
+ case R_PPC64_ADDR16_HIGHEST:
+ case R_PPC64_ADDR16_HIGHESTA:
+ case R_PPC64_ADDR16_LO:
+ case R_PPC64_ADDR16_LO_DS:
+ if (h != NULL && !info->shared && abiversion (abfd) != 1
+ && rel->r_addend == 0)
+ {
+ /* We may need a .plt entry if this reloc refers to a
+ function in a shared lib. */
+ if (!update_plt_info (abfd, &h->plt.plist, rel->r_addend))
+ return FALSE;
+ h->pointer_equality_needed = 1;
+ }
+ /* Fall through. */
+
+ case R_PPC64_REL30:
+ case R_PPC64_REL32:
+ case R_PPC64_REL64:
+ case R_PPC64_ADDR14:
+ case R_PPC64_ADDR14_BRNTAKEN:
+ case R_PPC64_ADDR14_BRTAKEN:
+ case R_PPC64_ADDR24:
+ case R_PPC64_ADDR32:
+ case R_PPC64_UADDR16:
+ case R_PPC64_UADDR32:
+ case R_PPC64_UADDR64:
+ case R_PPC64_TOC:
+ if (h != NULL && !info->shared)
+ /* We may need a copy reloc. */
+ h->non_got_ref = 1;
+
+ /* Don't propagate .opd relocs. */
+ if (NO_OPD_RELOCS && opd_sym_map != NULL)
+ break;
+
+ /* 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). In case of a weak definition,
+ DEF_REGULAR may be cleared later by a strong definition in
+ a shared library. We account for that possibility below by
+ storing information in the dyn_relocs field of the hash
+ table entry. A similar situation occurs when creating
+ shared libraries and symbol visibility changes render the
+ symbol local.
+
+ If on the other hand, we are creating an executable, we
+ may need to keep relocations for symbols satisfied by a
+ dynamic library if we manage to avoid copy relocs for the
+ symbol. */
+ dodyn:
+ if ((info->shared
+ && (must_be_dyn_reloc (info, r_type)
+ || (h != NULL
+ && (!SYMBOLIC_BIND (info, h)
+ || h->root.type == bfd_link_hash_defweak
+ || !h->def_regular))))
+ || (ELIMINATE_COPY_RELOCS
+ && !info->shared
+ && h != NULL
+ && (h->root.type == bfd_link_hash_defweak
+ || !h->def_regular))
+ || (!info->shared
+ && ifunc != NULL))
+ {
+ /* We must copy these reloc types into the output file.
+ Create a reloc section in dynobj and make room for
+ this reloc. */
+ if (sreloc == NULL)
+ {
+ sreloc = _bfd_elf_make_dynamic_reloc_section
+ (sec, htab->elf.dynobj, 3, abfd, /*rela?*/ TRUE);
+
+ if (sreloc == NULL)
+ return FALSE;
+ }
+
+ /* If this is a global symbol, we count the number of
+ relocations we need for this symbol. */
+ if (h != NULL)
+ {
+ struct elf_dyn_relocs *p;
+ struct elf_dyn_relocs **head;
+
+ head = &((struct ppc_link_hash_entry *) h)->dyn_relocs;
+ p = *head;
+ if (p == NULL || p->sec != sec)
+ {
+ p = bfd_alloc (htab->elf.dynobj, sizeof *p);
+ if (p == NULL)
+ return FALSE;
+ p->next = *head;
+ *head = p;
+ p->sec = sec;
+ p->count = 0;
+ p->pc_count = 0;
+ }
+ p->count += 1;
+ if (!must_be_dyn_reloc (info, r_type))
+ p->pc_count += 1;
+ }
+ else
+ {
+ /* Track dynamic relocs needed for local syms too.
+ We really need local syms available to do this
+ easily. Oh well. */
+ struct ppc_dyn_relocs *p;
+ struct ppc_dyn_relocs **head;
+ bfd_boolean is_ifunc;
+ asection *s;
+ void *vpp;
+ Elf_Internal_Sym *isym;
+
+ isym = bfd_sym_from_r_symndx (&htab->sym_cache,
+ abfd, r_symndx);
+ if (isym == NULL)
+ return FALSE;
+
+ s = bfd_section_from_elf_index (abfd, isym->st_shndx);
+ if (s == NULL)
+ s = sec;
+
+ vpp = &elf_section_data (s)->local_dynrel;
+ head = (struct ppc_dyn_relocs **) vpp;
+ is_ifunc = ELF_ST_TYPE (isym->st_info) == STT_GNU_IFUNC;
+ p = *head;
+ if (p != NULL && p->sec == sec && p->ifunc != is_ifunc)
+ p = p->next;
+ if (p == NULL || p->sec != sec || p->ifunc != is_ifunc)
+ {
+ p = bfd_alloc (htab->elf.dynobj, sizeof *p);
+ if (p == NULL)
+ return FALSE;
+ p->next = *head;
+ *head = p;
+ p->sec = sec;
+ p->ifunc = is_ifunc;
+ p->count = 0;
+ }
+ p->count += 1;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ return TRUE;
+}
+
+/* Merge backend specific data from an object file to the output
+ object file when linking. */
+
+static bfd_boolean
+ppc64_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
+{
+ unsigned long iflags, oflags;
+
+ if ((ibfd->flags & BFD_LINKER_CREATED) != 0)
+ return TRUE;
+
+ if (!is_ppc64_elf (ibfd) || !is_ppc64_elf (obfd))
+ return TRUE;
+
+ if (!_bfd_generic_verify_endian_match (ibfd, obfd))
+ return FALSE;
+
+ iflags = elf_elfheader (ibfd)->e_flags;
+ oflags = elf_elfheader (obfd)->e_flags;
+
+ if (iflags & ~EF_PPC64_ABI)
+ {
+ (*_bfd_error_handler)
+ (_("%B uses unknown e_flags 0x%lx"), ibfd, iflags);
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+ else if (iflags != oflags && iflags != 0)
+ {
+ (*_bfd_error_handler)
+ (_("%B: ABI version %ld is not compatible with ABI version %ld output"),
+ ibfd, iflags, oflags);
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+
+ /* Merge Tag_compatibility attributes and any common GNU ones. */
+ _bfd_elf_merge_object_attributes (ibfd, obfd);
+
+ return TRUE;
+}
+
+static bfd_boolean
+ppc64_elf_print_private_bfd_data (bfd *abfd, void *ptr)
+{
+ /* Print normal ELF private data. */
+ _bfd_elf_print_private_bfd_data (abfd, ptr);
+
+ if (elf_elfheader (abfd)->e_flags != 0)
+ {
+ FILE *file = ptr;
+
+ /* xgettext:c-format */
+ fprintf (file, _("private flags = 0x%lx:"),
+ elf_elfheader (abfd)->e_flags);
+
+ if ((elf_elfheader (abfd)->e_flags & EF_PPC64_ABI) != 0)
+ fprintf (file, _(" [abiv%ld]"),
+ elf_elfheader (abfd)->e_flags & EF_PPC64_ABI);
+ fputc ('\n', file);
+ }
+
+ return TRUE;
+}
+
+/* OFFSET in OPD_SEC specifies a function descriptor. Return the address
+ of the code entry point, and its section, which must be in the same
+ object as OPD_SEC. Returns (bfd_vma) -1 on error. */
+
+static bfd_vma
+opd_entry_value (asection *opd_sec,
+ bfd_vma offset,
+ asection **code_sec,
+ bfd_vma *code_off,
+ bfd_boolean in_code_sec)
+{
+ bfd *opd_bfd = opd_sec->owner;
+ Elf_Internal_Rela *relocs;
+ Elf_Internal_Rela *lo, *hi, *look;
+ bfd_vma val;
+
+ /* No relocs implies we are linking a --just-symbols object, or looking
+ at a final linked executable with addr2line or somesuch. */
+ if (opd_sec->reloc_count == 0)
+ {
+ bfd_byte *contents = ppc64_elf_tdata (opd_bfd)->opd.contents;
+
+ if (contents == NULL)
+ {
+ if (!bfd_malloc_and_get_section (opd_bfd, opd_sec, &contents))
+ return (bfd_vma) -1;
+ ppc64_elf_tdata (opd_bfd)->opd.contents = contents;
+ }
+
+ val = bfd_get_64 (opd_bfd, contents + offset);
+ if (code_sec != NULL)
+ {
+ asection *sec, *likely = NULL;
+
+ if (in_code_sec)
+ {
+ sec = *code_sec;
+ if (sec->vma <= val
+ && val < sec->vma + sec->size)
+ likely = sec;
+ else
+ val = -1;
+ }
+ else
+ for (sec = opd_bfd->sections; sec != NULL; sec = sec->next)
+ if (sec->vma <= val
+ && (sec->flags & SEC_LOAD) != 0
+ && (sec->flags & SEC_ALLOC) != 0)
+ likely = sec;
+ if (likely != NULL)
+ {
+ *code_sec = likely;
+ if (code_off != NULL)
+ *code_off = val - likely->vma;
+ }
+ }
+ return val;
+ }
+
+ BFD_ASSERT (is_ppc64_elf (opd_bfd));
+
+ relocs = ppc64_elf_tdata (opd_bfd)->opd.relocs;
+ if (relocs == NULL)
+ relocs = _bfd_elf_link_read_relocs (opd_bfd, opd_sec, NULL, NULL, TRUE);
+
+ /* Go find the opd reloc at the sym address. */
+ lo = relocs;
+ BFD_ASSERT (lo != NULL);
+ hi = lo + opd_sec->reloc_count - 1; /* ignore last reloc */
+ val = (bfd_vma) -1;
+ while (lo < hi)
+ {
+ look = lo + (hi - lo) / 2;
+ if (look->r_offset < offset)
+ lo = look + 1;
+ else if (look->r_offset > offset)
+ hi = look;
+ else
+ {
+ Elf_Internal_Shdr *symtab_hdr = &elf_symtab_hdr (opd_bfd);
+
+ if (ELF64_R_TYPE (look->r_info) == R_PPC64_ADDR64
+ && ELF64_R_TYPE ((look + 1)->r_info) == R_PPC64_TOC)
+ {
+ unsigned long symndx = ELF64_R_SYM (look->r_info);
+ asection *sec = NULL;
+
+ if (symndx >= symtab_hdr->sh_info
+ && elf_sym_hashes (opd_bfd) != NULL)
+ {
+ struct elf_link_hash_entry **sym_hashes;
+ struct elf_link_hash_entry *rh;
+
+ sym_hashes = elf_sym_hashes (opd_bfd);
+ rh = sym_hashes[symndx - symtab_hdr->sh_info];
+ if (rh != NULL)
+ {
+ rh = elf_follow_link (rh);
+ BFD_ASSERT (rh->root.type == bfd_link_hash_defined
+ || rh->root.type == bfd_link_hash_defweak);
+ val = rh->root.u.def.value;
+ sec = rh->root.u.def.section;
+ if (sec->owner != opd_bfd)
+ {
+ sec = NULL;
+ val = (bfd_vma) -1;
+ }
+ }
+ }
+
+ if (sec == NULL)
+ {
+ Elf_Internal_Sym *sym;
+
+ if (symndx < symtab_hdr->sh_info)
+ {
+ sym = (Elf_Internal_Sym *) symtab_hdr->contents;
+ if (sym == NULL)
+ {
+ size_t symcnt = symtab_hdr->sh_info;
+ sym = bfd_elf_get_elf_syms (opd_bfd, symtab_hdr,
+ symcnt, 0,
+ NULL, NULL, NULL);
+ if (sym == NULL)
+ break;
+ symtab_hdr->contents = (bfd_byte *) sym;
+ }
+ sym += symndx;
+ }
+ else
+ {
+ sym = bfd_elf_get_elf_syms (opd_bfd, symtab_hdr,
+ 1, symndx,
+ NULL, NULL, NULL);
+ if (sym == NULL)
+ break;
+ }
+ sec = bfd_section_from_elf_index (opd_bfd, sym->st_shndx);
+ if (sec == NULL)
+ break;
+ BFD_ASSERT ((sec->flags & SEC_MERGE) == 0);
+ val = sym->st_value;
+ }
+
+ val += look->r_addend;
+ if (code_off != NULL)
+ *code_off = val;
+ if (code_sec != NULL)
+ {
+ if (in_code_sec && *code_sec != sec)
+ return -1;
+ else
+ *code_sec = sec;
+ }
+ if (sec->output_section != NULL)
+ val += sec->output_section->vma + sec->output_offset;
+ }
+ break;
+ }
+ }
+
+ return val;
+}
+
+/* If the ELF symbol SYM might be a function in SEC, return the
+ function size and set *CODE_OFF to the function's entry point,
+ otherwise return zero. */
+
+static bfd_size_type
+ppc64_elf_maybe_function_sym (const asymbol *sym, asection *sec,
+ bfd_vma *code_off)
+{
+ bfd_size_type size;
+
+ if ((sym->flags & (BSF_SECTION_SYM | BSF_FILE | BSF_OBJECT
+ | BSF_THREAD_LOCAL | BSF_RELC | BSF_SRELC)) != 0)
+ return 0;
+
+ size = 0;
+ if (!(sym->flags & BSF_SYNTHETIC))
+ size = ((elf_symbol_type *) sym)->internal_elf_sym.st_size;
+
+ if (strcmp (sym->section->name, ".opd") == 0)
+ {
+ if (opd_entry_value (sym->section, sym->value,
+ &sec, code_off, TRUE) == (bfd_vma) -1)
+ return 0;
+ /* An old ABI binary with dot-syms has a size of 24 on the .opd
+ symbol. This size has nothing to do with the code size of the
+ function, which is what we're supposed to return, but the
+ code size isn't available without looking up the dot-sym.
+ However, doing that would be a waste of time particularly
+ since elf_find_function will look at the dot-sym anyway.
+ Now, elf_find_function will keep the largest size of any
+ function sym found at the code address of interest, so return
+ 1 here to avoid it incorrectly caching a larger function size
+ for a small function. This does mean we return the wrong
+ size for a new-ABI function of size 24, but all that does is
+ disable caching for such functions. */
+ if (size == 24)
+ size = 1;
+ }
+ else
+ {
+ if (sym->section != sec)
+ return 0;
+ *code_off = sym->value;
+ }
+ if (size == 0)
+ size = 1;
+ return size;
+}
+
+/* Return true if symbol is defined in a regular object file. */
+
+static bfd_boolean
+is_static_defined (struct elf_link_hash_entry *h)
+{
+ return ((h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak)
+ && h->root.u.def.section != NULL
+ && h->root.u.def.section->output_section != NULL);
+}
+
+/* If FDH is a function descriptor symbol, return the associated code
+ entry symbol if it is defined. Return NULL otherwise. */
+
+static struct ppc_link_hash_entry *
+defined_code_entry (struct ppc_link_hash_entry *fdh)
+{
+ if (fdh->is_func_descriptor)
+ {
+ struct ppc_link_hash_entry *fh = ppc_follow_link (fdh->oh);
+ if (fh->elf.root.type == bfd_link_hash_defined
+ || fh->elf.root.type == bfd_link_hash_defweak)
+ return fh;
+ }
+ return NULL;
+}
+
+/* If FH is a function code entry symbol, return the associated
+ function descriptor symbol if it is defined. Return NULL otherwise. */
+
+static struct ppc_link_hash_entry *
+defined_func_desc (struct ppc_link_hash_entry *fh)
+{
+ if (fh->oh != NULL
+ && fh->oh->is_func_descriptor)
+ {
+ struct ppc_link_hash_entry *fdh = ppc_follow_link (fh->oh);
+ if (fdh->elf.root.type == bfd_link_hash_defined
+ || fdh->elf.root.type == bfd_link_hash_defweak)
+ return fdh;
+ }
+ return NULL;
+}
+
+/* Mark all our entry sym sections, both opd and code section. */
+
+static void
+ppc64_elf_gc_keep (struct bfd_link_info *info)
+{
+ struct ppc_link_hash_table *htab = ppc_hash_table (info);
+ struct bfd_sym_chain *sym;
+
+ if (htab == NULL)
+ return;
+
+ for (sym = info->gc_sym_list; sym != NULL; sym = sym->next)
+ {
+ struct ppc_link_hash_entry *eh, *fh;
+ asection *sec;
+
+ eh = (struct ppc_link_hash_entry *)
+ elf_link_hash_lookup (&htab->elf, sym->name, FALSE, FALSE, TRUE);
+ if (eh == NULL)
+ continue;
+ if (eh->elf.root.type != bfd_link_hash_defined
+ && eh->elf.root.type != bfd_link_hash_defweak)
+ continue;
+
+ fh = defined_code_entry (eh);
+ if (fh != NULL)
+ {
+ sec = fh->elf.root.u.def.section;
+ sec->flags |= SEC_KEEP;
+ }
+ else if (get_opd_info (eh->elf.root.u.def.section) != NULL
+ && opd_entry_value (eh->elf.root.u.def.section,
+ eh->elf.root.u.def.value,
+ &sec, NULL, FALSE) != (bfd_vma) -1)
+ sec->flags |= SEC_KEEP;
+
+ sec = eh->elf.root.u.def.section;
+ sec->flags |= SEC_KEEP;
+ }
+}
+
+/* Mark sections containing dynamically referenced symbols. When
+ building shared libraries, we must assume that any visible symbol is
+ referenced. */
+
+static bfd_boolean
+ppc64_elf_gc_mark_dynamic_ref (struct elf_link_hash_entry *h, void *inf)
+{
+ struct bfd_link_info *info = (struct bfd_link_info *) inf;
+ struct ppc_link_hash_entry *eh = (struct ppc_link_hash_entry *) h;
+ struct ppc_link_hash_entry *fdh;
+ struct bfd_elf_dynamic_list *d = info->dynamic_list;
+
+ /* Dynamic linking info is on the func descriptor sym. */
+ fdh = defined_func_desc (eh);
+ if (fdh != NULL)
+ eh = fdh;
+
+ if ((eh->elf.root.type == bfd_link_hash_defined
+ || eh->elf.root.type == bfd_link_hash_defweak)
+ && (eh->elf.ref_dynamic
+ || (eh->elf.def_regular
+ && ELF_ST_VISIBILITY (eh->elf.other) != STV_INTERNAL
+ && ELF_ST_VISIBILITY (eh->elf.other) != STV_HIDDEN
+ && (!info->executable
+ || info->export_dynamic
+ || (eh->elf.dynamic
+ && d != NULL
+ && (*d->match) (&d->head, NULL, eh->elf.root.root.string)))
+ && (strchr (eh->elf.root.root.string, ELF_VER_CHR) != NULL
+ || !bfd_hide_sym_by_version (info->version_info,
+ eh->elf.root.root.string)))))
+ {
+ asection *code_sec;
+ struct ppc_link_hash_entry *fh;
+
+ eh->elf.root.u.def.section->flags |= SEC_KEEP;
+
+ /* Function descriptor syms cause the associated
+ function code sym section to be marked. */
+ fh = defined_code_entry (eh);
+ if (fh != NULL)
+ {
+ code_sec = fh->elf.root.u.def.section;
+ code_sec->flags |= SEC_KEEP;
+ }
+ else if (get_opd_info (eh->elf.root.u.def.section) != NULL
+ && opd_entry_value (eh->elf.root.u.def.section,
+ eh->elf.root.u.def.value,
+ &code_sec, NULL, FALSE) != (bfd_vma) -1)
+ code_sec->flags |= SEC_KEEP;
+ }
+
+ return TRUE;
+}
+
+/* Return the section that should be marked against GC for a given
+ relocation. */
+
+static asection *
+ppc64_elf_gc_mark_hook (asection *sec,
+ struct bfd_link_info *info,
+ Elf_Internal_Rela *rel,
+ struct elf_link_hash_entry *h,
+ Elf_Internal_Sym *sym)
+{
+ asection *rsec;
+
+ /* Syms return NULL if we're marking .opd, so we avoid marking all
+ function sections, as all functions are referenced in .opd. */
+ rsec = NULL;
+ if (get_opd_info (sec) != NULL)
+ return rsec;
+
+ if (h != NULL)
+ {
+ enum elf_ppc64_reloc_type r_type;
+ struct ppc_link_hash_entry *eh, *fh, *fdh;
+
+ r_type = ELF64_R_TYPE (rel->r_info);
+ switch (r_type)
+ {
+ case R_PPC64_GNU_VTINHERIT:
+ case R_PPC64_GNU_VTENTRY:
+ break;
+
+ default:
+ switch (h->root.type)
+ {
+ case bfd_link_hash_defined:
+ case bfd_link_hash_defweak:
+ eh = (struct ppc_link_hash_entry *) h;
+ fdh = defined_func_desc (eh);
+ if (fdh != NULL)
+ eh = fdh;
+
+ /* Function descriptor syms cause the associated
+ function code sym section to be marked. */
+ fh = defined_code_entry (eh);
+ if (fh != NULL)
+ {
+ /* They also mark their opd section. */
+ eh->elf.root.u.def.section->gc_mark = 1;
+
+ rsec = fh->elf.root.u.def.section;
+ }
+ else if (get_opd_info (eh->elf.root.u.def.section) != NULL
+ && opd_entry_value (eh->elf.root.u.def.section,
+ eh->elf.root.u.def.value,
+ &rsec, NULL, FALSE) != (bfd_vma) -1)
+ eh->elf.root.u.def.section->gc_mark = 1;
+ else
+ rsec = h->root.u.def.section;
+ break;
+
+ case bfd_link_hash_common:
+ rsec = h->root.u.c.p->section;
+ break;
+
+ default:
+ return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
+ }
+ }
+ }
+ else
+ {
+ struct _opd_sec_data *opd;
+
+ rsec = bfd_section_from_elf_index (sec->owner, sym->st_shndx);
+ opd = get_opd_info (rsec);
+ if (opd != NULL && opd->func_sec != NULL)
+ {
+ rsec->gc_mark = 1;
+
+ rsec = opd->func_sec[(sym->st_value + rel->r_addend) / 8];
+ }
+ }
+
+ return rsec;
+}
+
+/* Update the .got, .plt. and dynamic reloc reference counts for the
+ section being removed. */
+
+static bfd_boolean
+ppc64_elf_gc_sweep_hook (bfd *abfd, struct bfd_link_info *info,
+ asection *sec, const Elf_Internal_Rela *relocs)
+{
+ struct ppc_link_hash_table *htab;
+ Elf_Internal_Shdr *symtab_hdr;
+ struct elf_link_hash_entry **sym_hashes;
+ struct got_entry **local_got_ents;
+ const Elf_Internal_Rela *rel, *relend;
+
+ if (info->relocatable)
+ return TRUE;
+
+ if ((sec->flags & SEC_ALLOC) == 0)
+ return TRUE;
+
+ elf_section_data (sec)->local_dynrel = NULL;
+
+ htab = ppc_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ symtab_hdr = &elf_symtab_hdr (abfd);
+ sym_hashes = elf_sym_hashes (abfd);
+ local_got_ents = elf_local_got_ents (abfd);
+
+ relend = relocs + sec->reloc_count;
+ for (rel = relocs; rel < relend; rel++)
+ {
+ unsigned long r_symndx;
+ enum elf_ppc64_reloc_type r_type;
+ struct elf_link_hash_entry *h = NULL;
+ unsigned char tls_type = 0;
+
+ r_symndx = ELF64_R_SYM (rel->r_info);
+ r_type = ELF64_R_TYPE (rel->r_info);
+ if (r_symndx >= symtab_hdr->sh_info)
+ {
+ struct ppc_link_hash_entry *eh;
+ struct elf_dyn_relocs **pp;
+ struct elf_dyn_relocs *p;
+
+ h = sym_hashes[r_symndx - symtab_hdr->sh_info];
+ h = elf_follow_link (h);
+ eh = (struct ppc_link_hash_entry *) h;
+
+ for (pp = &eh->dyn_relocs; (p = *pp) != NULL; pp = &p->next)
+ if (p->sec == sec)
+ {
+ /* Everything must go for SEC. */
+ *pp = p->next;
+ break;
+ }
+ }
+
+ if (is_branch_reloc (r_type))
+ {
+ struct plt_entry **ifunc = NULL;
+ if (h != NULL)
+ {
+ if (h->type == STT_GNU_IFUNC)
+ ifunc = &h->plt.plist;
+ }
+ else if (local_got_ents != NULL)
+ {
+ struct plt_entry **local_plt = (struct plt_entry **)
+ (local_got_ents + symtab_hdr->sh_info);
+ unsigned char *local_got_tls_masks = (unsigned char *)
+ (local_plt + symtab_hdr->sh_info);
+ if ((local_got_tls_masks[r_symndx] & PLT_IFUNC) != 0)
+ ifunc = local_plt + r_symndx;
+ }
+ if (ifunc != NULL)
+ {
+ struct plt_entry *ent;
+
+ for (ent = *ifunc; ent != NULL; ent = ent->next)
+ if (ent->addend == rel->r_addend)
+ break;
+ if (ent == NULL)
+ abort ();
+ if (ent->plt.refcount > 0)
+ ent->plt.refcount -= 1;
+ continue;
+ }
+ }
+
+ switch (r_type)
+ {
+ case R_PPC64_GOT_TLSLD16:
+ case R_PPC64_GOT_TLSLD16_LO:
+ case R_PPC64_GOT_TLSLD16_HI:
+ case R_PPC64_GOT_TLSLD16_HA:
+ tls_type = TLS_TLS | TLS_LD;
+ goto dogot;
+
+ case R_PPC64_GOT_TLSGD16:
+ case R_PPC64_GOT_TLSGD16_LO:
+ case R_PPC64_GOT_TLSGD16_HI:
+ case R_PPC64_GOT_TLSGD16_HA:
+ tls_type = TLS_TLS | TLS_GD;
+ goto dogot;
+
+ case R_PPC64_GOT_TPREL16_DS:
+ case R_PPC64_GOT_TPREL16_LO_DS:
+ case R_PPC64_GOT_TPREL16_HI:
+ case R_PPC64_GOT_TPREL16_HA:
+ tls_type = TLS_TLS | TLS_TPREL;
+ goto dogot;
+
+ case R_PPC64_GOT_DTPREL16_DS:
+ case R_PPC64_GOT_DTPREL16_LO_DS:
+ case R_PPC64_GOT_DTPREL16_HI:
+ case R_PPC64_GOT_DTPREL16_HA:
+ tls_type = TLS_TLS | TLS_DTPREL;
+ goto dogot;
+
+ case R_PPC64_GOT16:
+ case R_PPC64_GOT16_DS:
+ case R_PPC64_GOT16_HA:
+ case R_PPC64_GOT16_HI:
+ case R_PPC64_GOT16_LO:
+ case R_PPC64_GOT16_LO_DS:
+ dogot:
+ {
+ struct got_entry *ent;
+
+ if (h != NULL)
+ ent = h->got.glist;
+ else
+ ent = local_got_ents[r_symndx];
+
+ for (; ent != NULL; ent = ent->next)
+ if (ent->addend == rel->r_addend
+ && ent->owner == abfd
+ && ent->tls_type == tls_type)
+ break;
+ if (ent == NULL)
+ abort ();
+ if (ent->got.refcount > 0)
+ ent->got.refcount -= 1;
+ }
+ break;
+
+ case R_PPC64_PLT16_HA:
+ case R_PPC64_PLT16_HI:
+ case R_PPC64_PLT16_LO:
+ case R_PPC64_PLT32:
+ case R_PPC64_PLT64:
+ case R_PPC64_REL14:
+ case R_PPC64_REL14_BRNTAKEN:
+ case R_PPC64_REL14_BRTAKEN:
+ case R_PPC64_REL24:
+ if (h != NULL)
+ {
+ struct plt_entry *ent;
+
+ for (ent = h->plt.plist; ent != NULL; ent = ent->next)
+ if (ent->addend == rel->r_addend)
+ break;
+ if (ent != NULL && ent->plt.refcount > 0)
+ ent->plt.refcount -= 1;
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ return TRUE;
+}
+
+/* The maximum size of .sfpr. */
+#define SFPR_MAX (218*4)
+
+struct sfpr_def_parms
+{
+ const char name[12];
+ unsigned char lo, hi;
+ bfd_byte * (*write_ent) (bfd *, bfd_byte *, int);
+ bfd_byte * (*write_tail) (bfd *, bfd_byte *, int);
+};
+
+/* Auto-generate _save*, _rest* functions in .sfpr. */
+
+static bfd_boolean
+sfpr_define (struct bfd_link_info *info, const struct sfpr_def_parms *parm)
+{
+ struct ppc_link_hash_table *htab = ppc_hash_table (info);
+ unsigned int i;
+ size_t len = strlen (parm->name);
+ bfd_boolean writing = FALSE;
+ char sym[16];
+
+ if (htab == NULL)
+ return FALSE;
+
+ memcpy (sym, parm->name, len);
+ sym[len + 2] = 0;
+
+ for (i = parm->lo; i <= parm->hi; i++)
+ {
+ struct elf_link_hash_entry *h;
+
+ sym[len + 0] = i / 10 + '0';
+ sym[len + 1] = i % 10 + '0';
+ h = elf_link_hash_lookup (&htab->elf, sym, FALSE, FALSE, TRUE);
+ if (h != NULL
+ && !h->def_regular)
+ {
+ h->root.type = bfd_link_hash_defined;
+ h->root.u.def.section = htab->sfpr;
+ h->root.u.def.value = htab->sfpr->size;
+ h->type = STT_FUNC;
+ h->def_regular = 1;
+ _bfd_elf_link_hash_hide_symbol (info, h, TRUE);
+ writing = TRUE;
+ if (htab->sfpr->contents == NULL)
+ {
+ htab->sfpr->contents = bfd_alloc (htab->elf.dynobj, SFPR_MAX);
+ if (htab->sfpr->contents == NULL)
+ return FALSE;
+ }
+ }
+ if (writing)
+ {
+ bfd_byte *p = htab->sfpr->contents + htab->sfpr->size;
+ if (i != parm->hi)
+ p = (*parm->write_ent) (htab->elf.dynobj, p, i);
+ else
+ p = (*parm->write_tail) (htab->elf.dynobj, p, i);
+ htab->sfpr->size = p - htab->sfpr->contents;
+ }
+ }
+
+ return TRUE;
+}
+
+static bfd_byte *
+savegpr0 (bfd *abfd, bfd_byte *p, int r)
+{
+ bfd_put_32 (abfd, STD_R0_0R1 + (r << 21) + (1 << 16) - (32 - r) * 8, p);
+ return p + 4;
+}
+
+static bfd_byte *
+savegpr0_tail (bfd *abfd, bfd_byte *p, int r)
+{
+ p = savegpr0 (abfd, p, r);
+ bfd_put_32 (abfd, STD_R0_0R1 + STK_LR, p);
+ p = p + 4;
+ bfd_put_32 (abfd, BLR, p);
+ return p + 4;
+}
+
+static bfd_byte *
+restgpr0 (bfd *abfd, bfd_byte *p, int r)
+{
+ bfd_put_32 (abfd, LD_R0_0R1 + (r << 21) + (1 << 16) - (32 - r) * 8, p);
+ return p + 4;
+}
+
+static bfd_byte *
+restgpr0_tail (bfd *abfd, bfd_byte *p, int r)
+{
+ bfd_put_32 (abfd, LD_R0_0R1 + STK_LR, p);
+ p = p + 4;
+ p = restgpr0 (abfd, p, r);
+ bfd_put_32 (abfd, MTLR_R0, p);
+ p = p + 4;
+ if (r == 29)
+ {
+ p = restgpr0 (abfd, p, 30);
+ p = restgpr0 (abfd, p, 31);
+ }
+ bfd_put_32 (abfd, BLR, p);
+ return p + 4;
+}
+
+static bfd_byte *
+savegpr1 (bfd *abfd, bfd_byte *p, int r)
+{
+ bfd_put_32 (abfd, STD_R0_0R12 + (r << 21) + (1 << 16) - (32 - r) * 8, p);
+ return p + 4;
+}
+
+static bfd_byte *
+savegpr1_tail (bfd *abfd, bfd_byte *p, int r)
+{
+ p = savegpr1 (abfd, p, r);
+ bfd_put_32 (abfd, BLR, p);
+ return p + 4;
+}
+
+static bfd_byte *
+restgpr1 (bfd *abfd, bfd_byte *p, int r)
+{
+ bfd_put_32 (abfd, LD_R0_0R12 + (r << 21) + (1 << 16) - (32 - r) * 8, p);
+ return p + 4;
+}
+
+static bfd_byte *
+restgpr1_tail (bfd *abfd, bfd_byte *p, int r)
+{
+ p = restgpr1 (abfd, p, r);
+ bfd_put_32 (abfd, BLR, p);
+ return p + 4;
+}
+
+static bfd_byte *
+savefpr (bfd *abfd, bfd_byte *p, int r)
+{
+ bfd_put_32 (abfd, STFD_FR0_0R1 + (r << 21) + (1 << 16) - (32 - r) * 8, p);
+ return p + 4;
+}
+
+static bfd_byte *
+savefpr0_tail (bfd *abfd, bfd_byte *p, int r)
+{
+ p = savefpr (abfd, p, r);
+ bfd_put_32 (abfd, STD_R0_0R1 + STK_LR, p);
+ p = p + 4;
+ bfd_put_32 (abfd, BLR, p);
+ return p + 4;
+}
+
+static bfd_byte *
+restfpr (bfd *abfd, bfd_byte *p, int r)
+{
+ bfd_put_32 (abfd, LFD_FR0_0R1 + (r << 21) + (1 << 16) - (32 - r) * 8, p);
+ return p + 4;
+}
+
+static bfd_byte *
+restfpr0_tail (bfd *abfd, bfd_byte *p, int r)
+{
+ bfd_put_32 (abfd, LD_R0_0R1 + STK_LR, p);
+ p = p + 4;
+ p = restfpr (abfd, p, r);
+ bfd_put_32 (abfd, MTLR_R0, p);
+ p = p + 4;
+ if (r == 29)
+ {
+ p = restfpr (abfd, p, 30);
+ p = restfpr (abfd, p, 31);
+ }
+ bfd_put_32 (abfd, BLR, p);
+ return p + 4;
+}
+
+static bfd_byte *
+savefpr1_tail (bfd *abfd, bfd_byte *p, int r)
+{
+ p = savefpr (abfd, p, r);
+ bfd_put_32 (abfd, BLR, p);
+ return p + 4;
+}
+
+static bfd_byte *
+restfpr1_tail (bfd *abfd, bfd_byte *p, int r)
+{
+ p = restfpr (abfd, p, r);
+ bfd_put_32 (abfd, BLR, p);
+ return p + 4;
+}
+
+static bfd_byte *
+savevr (bfd *abfd, bfd_byte *p, int r)
+{
+ bfd_put_32 (abfd, LI_R12_0 + (1 << 16) - (32 - r) * 16, p);
+ p = p + 4;
+ bfd_put_32 (abfd, STVX_VR0_R12_R0 + (r << 21), p);
+ return p + 4;
+}
+
+static bfd_byte *
+savevr_tail (bfd *abfd, bfd_byte *p, int r)
+{
+ p = savevr (abfd, p, r);
+ bfd_put_32 (abfd, BLR, p);
+ return p + 4;
+}
+
+static bfd_byte *
+restvr (bfd *abfd, bfd_byte *p, int r)
+{
+ bfd_put_32 (abfd, LI_R12_0 + (1 << 16) - (32 - r) * 16, p);
+ p = p + 4;
+ bfd_put_32 (abfd, LVX_VR0_R12_R0 + (r << 21), p);
+ return p + 4;
+}
+
+static bfd_byte *
+restvr_tail (bfd *abfd, bfd_byte *p, int r)
+{
+ p = restvr (abfd, p, r);
+ bfd_put_32 (abfd, BLR, p);
+ return p + 4;
+}
+
+/* Called via elf_link_hash_traverse to transfer dynamic linking
+ information on function code symbol entries to their corresponding
+ function descriptor symbol entries. */
+
+static bfd_boolean
+func_desc_adjust (struct elf_link_hash_entry *h, void *inf)
+{
+ struct bfd_link_info *info;
+ struct ppc_link_hash_table *htab;
+ struct plt_entry *ent;
+ struct ppc_link_hash_entry *fh;
+ struct ppc_link_hash_entry *fdh;
+ bfd_boolean force_local;
+
+ fh = (struct ppc_link_hash_entry *) h;
+ if (fh->elf.root.type == bfd_link_hash_indirect)
+ return TRUE;
+
+ info = inf;
+ htab = ppc_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ /* Resolve undefined references to dot-symbols as the value
+ in the function descriptor, if we have one in a regular object.
+ This is to satisfy cases like ".quad .foo". Calls to functions
+ in dynamic objects are handled elsewhere. */
+ if (fh->elf.root.type == bfd_link_hash_undefweak
+ && fh->was_undefined
+ && (fdh = defined_func_desc (fh)) != NULL
+ && get_opd_info (fdh->elf.root.u.def.section) != NULL
+ && opd_entry_value (fdh->elf.root.u.def.section,
+ fdh->elf.root.u.def.value,
+ &fh->elf.root.u.def.section,
+ &fh->elf.root.u.def.value, FALSE) != (bfd_vma) -1)
+ {
+ fh->elf.root.type = fdh->elf.root.type;
+ fh->elf.forced_local = 1;
+ fh->elf.def_regular = fdh->elf.def_regular;
+ fh->elf.def_dynamic = fdh->elf.def_dynamic;
+ }
+
+ /* If this is a function code symbol, transfer dynamic linking
+ information to the function descriptor symbol. */
+ if (!fh->is_func)
+ return TRUE;
+
+ for (ent = fh->elf.plt.plist; ent != NULL; ent = ent->next)
+ if (ent->plt.refcount > 0)
+ break;
+ if (ent == NULL
+ || fh->elf.root.root.string[0] != '.'
+ || fh->elf.root.root.string[1] == '\0')
+ return TRUE;
+
+ /* Find the corresponding function descriptor symbol. Create it
+ as undefined if necessary. */
+
+ fdh = lookup_fdh (fh, htab);
+ if (fdh == NULL
+ && !info->executable
+ && (fh->elf.root.type == bfd_link_hash_undefined
+ || fh->elf.root.type == bfd_link_hash_undefweak))
+ {
+ fdh = make_fdh (info, fh);
+ if (fdh == NULL)
+ return FALSE;
+ }
+
+ /* Fake function descriptors are made undefweak. If the function
+ code symbol is strong undefined, make the fake sym the same.
+ If the function code symbol is defined, then force the fake
+ descriptor local; We can't support overriding of symbols in a
+ shared library on a fake descriptor. */
+
+ if (fdh != NULL
+ && fdh->fake
+ && fdh->elf.root.type == bfd_link_hash_undefweak)
+ {
+ if (fh->elf.root.type == bfd_link_hash_undefined)
+ {
+ fdh->elf.root.type = bfd_link_hash_undefined;
+ bfd_link_add_undef (&htab->elf.root, &fdh->elf.root);
+ }
+ else if (fh->elf.root.type == bfd_link_hash_defined
+ || fh->elf.root.type == bfd_link_hash_defweak)
+ {
+ _bfd_elf_link_hash_hide_symbol (info, &fdh->elf, TRUE);
+ }
+ }
+
+ if (fdh != NULL
+ && !fdh->elf.forced_local
+ && (!info->executable
+ || fdh->elf.def_dynamic
+ || fdh->elf.ref_dynamic
+ || (fdh->elf.root.type == bfd_link_hash_undefweak
+ && ELF_ST_VISIBILITY (fdh->elf.other) == STV_DEFAULT)))
+ {
+ if (fdh->elf.dynindx == -1)
+ if (! bfd_elf_link_record_dynamic_symbol (info, &fdh->elf))
+ return FALSE;
+ fdh->elf.ref_regular |= fh->elf.ref_regular;
+ fdh->elf.ref_dynamic |= fh->elf.ref_dynamic;
+ fdh->elf.ref_regular_nonweak |= fh->elf.ref_regular_nonweak;
+ fdh->elf.non_got_ref |= fh->elf.non_got_ref;
+ if (ELF_ST_VISIBILITY (fh->elf.other) == STV_DEFAULT)
+ {
+ move_plt_plist (fh, fdh);
+ fdh->elf.needs_plt = 1;
+ }
+ fdh->is_func_descriptor = 1;
+ fdh->oh = fh;
+ fh->oh = fdh;
+ }
+
+ /* Now that the info is on the function descriptor, clear the
+ function code sym info. Any function code syms for which we
+ don't have a definition in a regular file, we force local.
+ This prevents a shared library from exporting syms that have
+ been imported from another library. Function code syms that
+ are really in the library we must leave global to prevent the
+ linker dragging in a definition from a static library. */
+ force_local = (!fh->elf.def_regular
+ || fdh == NULL
+ || !fdh->elf.def_regular
+ || fdh->elf.forced_local);
+ _bfd_elf_link_hash_hide_symbol (info, &fh->elf, force_local);
+
+ return TRUE;
+}
+
+/* Called near the start of bfd_elf_size_dynamic_sections. We use
+ this hook to a) provide some gcc support functions, and b) transfer
+ dynamic linking information gathered so far on function code symbol
+ entries, to their corresponding function descriptor symbol entries. */
+
+static bfd_boolean
+ppc64_elf_func_desc_adjust (bfd *obfd ATTRIBUTE_UNUSED,
+ struct bfd_link_info *info)
+{
+ struct ppc_link_hash_table *htab;
+ unsigned int i;
+ static const struct sfpr_def_parms funcs[] =
+ {
+ { "_savegpr0_", 14, 31, savegpr0, savegpr0_tail },
+ { "_restgpr0_", 14, 29, restgpr0, restgpr0_tail },
+ { "_restgpr0_", 30, 31, restgpr0, restgpr0_tail },
+ { "_savegpr1_", 14, 31, savegpr1, savegpr1_tail },
+ { "_restgpr1_", 14, 31, restgpr1, restgpr1_tail },
+ { "_savefpr_", 14, 31, savefpr, savefpr0_tail },
+ { "_restfpr_", 14, 29, restfpr, restfpr0_tail },
+ { "_restfpr_", 30, 31, restfpr, restfpr0_tail },
+ { "._savef", 14, 31, savefpr, savefpr1_tail },
+ { "._restf", 14, 31, restfpr, restfpr1_tail },
+ { "_savevr_", 20, 31, savevr, savevr_tail },
+ { "_restvr_", 20, 31, restvr, restvr_tail }
+ };
+
+ htab = ppc_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ if (!info->relocatable
+ && htab->elf.hgot != NULL)
+ {
+ _bfd_elf_link_hash_hide_symbol (info, htab->elf.hgot, TRUE);
+ /* Make .TOC. defined so as to prevent it being made dynamic.
+ The wrong value here is fixed later in ppc64_elf_set_toc. */
+ htab->elf.hgot->type = STT_OBJECT;
+ htab->elf.hgot->root.type = bfd_link_hash_defined;
+ htab->elf.hgot->root.u.def.value = 0;
+ htab->elf.hgot->root.u.def.section = bfd_abs_section_ptr;
+ htab->elf.hgot->def_regular = 1;
+ htab->elf.hgot->other = ((htab->elf.hgot->other & ~ELF_ST_VISIBILITY (-1))
+ | STV_HIDDEN);
+ }
+
+ if (htab->sfpr == NULL)
+ /* We don't have any relocs. */
+ return TRUE;
+
+ /* Provide any missing _save* and _rest* functions. */
+ htab->sfpr->size = 0;
+ if (htab->params->save_restore_funcs)
+ for (i = 0; i < sizeof (funcs) / sizeof (funcs[0]); i++)
+ if (!sfpr_define (info, &funcs[i]))
+ return FALSE;
+
+ elf_link_hash_traverse (&htab->elf, func_desc_adjust, info);
+
+ if (htab->sfpr->size == 0)
+ htab->sfpr->flags |= SEC_EXCLUDE;
+
+ return TRUE;
+}
+
+/* Return true if we have dynamic relocs that apply to read-only sections. */
+
+static bfd_boolean
+readonly_dynrelocs (struct elf_link_hash_entry *h)
+{
+ struct ppc_link_hash_entry *eh;
+ struct elf_dyn_relocs *p;
+
+ eh = (struct ppc_link_hash_entry *) h;
+ for (p = eh->dyn_relocs; p != NULL; p = p->next)
+ {
+ asection *s = p->sec->output_section;
+
+ if (s != NULL && (s->flags & SEC_READONLY) != 0)
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/* 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 bfd_boolean
+ppc64_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
+ struct elf_link_hash_entry *h)
+{
+ struct ppc_link_hash_table *htab;
+ asection *s;
+
+ htab = ppc_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ /* Deal with function syms. */
+ if (h->type == STT_FUNC
+ || h->type == STT_GNU_IFUNC
+ || h->needs_plt)
+ {
+ /* Clear procedure linkage table information for any symbol that
+ won't need a .plt entry. */
+ struct plt_entry *ent;
+ for (ent = h->plt.plist; ent != NULL; ent = ent->next)
+ if (ent->plt.refcount > 0)
+ break;
+ if (ent == NULL
+ || (h->type != STT_GNU_IFUNC
+ && (SYMBOL_CALLS_LOCAL (info, h)
+ || (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
+ && h->root.type == bfd_link_hash_undefweak))))
+ {
+ h->plt.plist = NULL;
+ h->needs_plt = 0;
+ h->pointer_equality_needed = 0;
+ }
+ else if (abiversion (info->output_bfd) == 2)
+ {
+ /* Taking a function's address in a read/write section
+ doesn't require us to define the function symbol in the
+ executable on a global entry stub. A dynamic reloc can
+ be used instead. */
+ if (h->pointer_equality_needed
+ && h->type != STT_GNU_IFUNC
+ && !readonly_dynrelocs (h))
+ {
+ h->pointer_equality_needed = 0;
+ h->non_got_ref = 0;
+ }
+
+ /* After adjust_dynamic_symbol, non_got_ref set in the
+ non-shared case means that we have allocated space in
+ .dynbss for the symbol and thus dyn_relocs for this
+ symbol should be discarded.
+ If we get here we know we are making a PLT entry for this
+ symbol, and in an executable we'd normally resolve
+ relocations against this symbol to the PLT entry. Allow
+ dynamic relocs if the reference is weak, and the dynamic
+ relocs will not cause text relocation. */
+ else if (!h->ref_regular_nonweak
+ && h->non_got_ref
+ && h->type != STT_GNU_IFUNC
+ && !readonly_dynrelocs (h))
+ h->non_got_ref = 0;
+
+ /* If making a plt entry, then we don't need copy relocs. */
+ return TRUE;
+ }
+ }
+ else
+ h->plt.plist = NULL;
+
+ /* 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->u.weakdef != NULL)
+ {
+ BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
+ || h->u.weakdef->root.type == bfd_link_hash_defweak);
+ h->root.u.def.section = h->u.weakdef->root.u.def.section;
+ h->root.u.def.value = h->u.weakdef->root.u.def.value;
+ if (ELIMINATE_COPY_RELOCS)
+ h->non_got_ref = h->u.weakdef->non_got_ref;
+ return TRUE;
+ }
+
+ /* 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;
+
+ /* If there are no references to this symbol that do not use the
+ GOT, we don't need to generate a copy reloc. */
+ if (!h->non_got_ref)
+ return TRUE;
+
+ /* Don't generate a copy reloc for symbols defined in the executable. */
+ if (!h->def_dynamic || !h->ref_regular || h->def_regular)
+ return TRUE;
+
+ /* If we didn't find any dynamic relocs in read-only sections, then
+ we'll be keeping the dynamic relocs and avoiding the copy reloc. */
+ if (ELIMINATE_COPY_RELOCS && !readonly_dynrelocs (h))
+ {
+ h->non_got_ref = 0;
+ return TRUE;
+ }
+
+ if (h->plt.plist != NULL)
+ {
+ /* We should never get here, but unfortunately there are versions
+ of gcc out there that improperly (for this ABI) put initialized
+ function pointers, vtable refs and suchlike in read-only
+ sections. Allow them to proceed, but warn that this might
+ break at runtime. */
+ info->callbacks->einfo
+ (_("%P: copy reloc against `%T' requires lazy plt linking; "
+ "avoid setting LD_BIND_NOW=1 or upgrade gcc\n"),
+ h->root.root.string);
+ }
+
+ /* This is a reference to a symbol defined by a dynamic object which
+ is not a function. */
+
+ /* 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. */
+
+ /* We must generate a R_PPC64_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 && h->size != 0)
+ {
+ htab->relbss->size += sizeof (Elf64_External_Rela);
+ h->needs_copy = 1;
+ }
+
+ s = htab->dynbss;
+
+ return _bfd_elf_adjust_dynamic_copy (h, s);
+}
+
+/* If given a function descriptor symbol, hide both the function code
+ sym and the descriptor. */
+static void
+ppc64_elf_hide_symbol (struct bfd_link_info *info,
+ struct elf_link_hash_entry *h,
+ bfd_boolean force_local)
+{
+ struct ppc_link_hash_entry *eh;
+ _bfd_elf_link_hash_hide_symbol (info, h, force_local);
+
+ eh = (struct ppc_link_hash_entry *) h;
+ if (eh->is_func_descriptor)
+ {
+ struct ppc_link_hash_entry *fh = eh->oh;
+
+ if (fh == NULL)
+ {
+ const char *p, *q;
+ struct ppc_link_hash_table *htab;
+ char save;
+
+ /* We aren't supposed to use alloca in BFD because on
+ systems which do not have alloca the version in libiberty
+ calls xmalloc, which might cause the program to crash
+ when it runs out of memory. This function doesn't have a
+ return status, so there's no way to gracefully return an
+ error. So cheat. We know that string[-1] can be safely
+ accessed; It's either a string in an ELF string table,
+ or allocated in an objalloc structure. */
+
+ p = eh->elf.root.root.string - 1;
+ save = *p;
+ *(char *) p = '.';
+ htab = ppc_hash_table (info);
+ if (htab == NULL)
+ return;
+
+ fh = (struct ppc_link_hash_entry *)
+ elf_link_hash_lookup (&htab->elf, p, FALSE, FALSE, FALSE);
+ *(char *) p = save;
+
+ /* Unfortunately, if it so happens that the string we were
+ looking for was allocated immediately before this string,
+ then we overwrote the string terminator. That's the only
+ reason the lookup should fail. */
+ if (fh == NULL)
+ {
+ q = eh->elf.root.root.string + strlen (eh->elf.root.root.string);
+ while (q >= eh->elf.root.root.string && *q == *p)
+ --q, --p;
+ if (q < eh->elf.root.root.string && *p == '.')
+ fh = (struct ppc_link_hash_entry *)
+ elf_link_hash_lookup (&htab->elf, p, FALSE, FALSE, FALSE);
+ }
+ if (fh != NULL)
+ {
+ eh->oh = fh;
+ fh->oh = eh;
+ }
+ }
+ if (fh != NULL)
+ _bfd_elf_link_hash_hide_symbol (info, &fh->elf, force_local);
+ }
+}
+
+static bfd_boolean
+get_sym_h (struct elf_link_hash_entry **hp,
+ Elf_Internal_Sym **symp,
+ asection **symsecp,
+ unsigned char **tls_maskp,
+ Elf_Internal_Sym **locsymsp,
+ unsigned long r_symndx,
+ bfd *ibfd)
+{
+ Elf_Internal_Shdr *symtab_hdr = &elf_symtab_hdr (ibfd);
+
+ if (r_symndx >= symtab_hdr->sh_info)
+ {
+ struct elf_link_hash_entry **sym_hashes = elf_sym_hashes (ibfd);
+ struct elf_link_hash_entry *h;
+
+ h = sym_hashes[r_symndx - symtab_hdr->sh_info];
+ h = elf_follow_link (h);
+
+ if (hp != NULL)
+ *hp = h;
+
+ if (symp != NULL)
+ *symp = NULL;
+
+ if (symsecp != NULL)
+ {
+ asection *symsec = NULL;
+ if (h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak)
+ symsec = h->root.u.def.section;
+ *symsecp = symsec;
+ }
+
+ if (tls_maskp != NULL)
+ {
+ struct ppc_link_hash_entry *eh;
+
+ eh = (struct ppc_link_hash_entry *) h;
+ *tls_maskp = &eh->tls_mask;
+ }
+ }
+ else
+ {
+ Elf_Internal_Sym *sym;
+ Elf_Internal_Sym *locsyms = *locsymsp;
+
+ if (locsyms == NULL)
+ {
+ locsyms = (Elf_Internal_Sym *) symtab_hdr->contents;
+ if (locsyms == NULL)
+ locsyms = bfd_elf_get_elf_syms (ibfd, symtab_hdr,
+ symtab_hdr->sh_info,
+ 0, NULL, NULL, NULL);
+ if (locsyms == NULL)
+ return FALSE;
+ *locsymsp = locsyms;
+ }
+ sym = locsyms + r_symndx;
+
+ if (hp != NULL)
+ *hp = NULL;
+
+ if (symp != NULL)
+ *symp = sym;
+
+ if (symsecp != NULL)
+ *symsecp = bfd_section_from_elf_index (ibfd, sym->st_shndx);
+
+ if (tls_maskp != NULL)
+ {
+ struct got_entry **lgot_ents;
+ unsigned char *tls_mask;
+
+ tls_mask = NULL;
+ lgot_ents = elf_local_got_ents (ibfd);
+ if (lgot_ents != NULL)
+ {
+ struct plt_entry **local_plt = (struct plt_entry **)
+ (lgot_ents + symtab_hdr->sh_info);
+ unsigned char *lgot_masks = (unsigned char *)
+ (local_plt + symtab_hdr->sh_info);
+ tls_mask = &lgot_masks[r_symndx];
+ }
+ *tls_maskp = tls_mask;
+ }
+ }
+ return TRUE;
+}
+
+/* Returns TLS_MASKP for the given REL symbol. Function return is 0 on
+ error, 2 on a toc GD type suitable for optimization, 3 on a toc LD
+ type suitable for optimization, and 1 otherwise. */
+
+static int
+get_tls_mask (unsigned char **tls_maskp,
+ unsigned long *toc_symndx,
+ bfd_vma *toc_addend,
+ Elf_Internal_Sym **locsymsp,
+ const Elf_Internal_Rela *rel,
+ bfd *ibfd)
+{
+ unsigned long r_symndx;
+ int next_r;
+ struct elf_link_hash_entry *h;
+ Elf_Internal_Sym *sym;
+ asection *sec;
+ bfd_vma off;
+
+ r_symndx = ELF64_R_SYM (rel->r_info);
+ if (!get_sym_h (&h, &sym, &sec, tls_maskp, locsymsp, r_symndx, ibfd))
+ return 0;
+
+ if ((*tls_maskp != NULL && **tls_maskp != 0)
+ || sec == NULL
+ || ppc64_elf_section_data (sec) == NULL
+ || ppc64_elf_section_data (sec)->sec_type != sec_toc)
+ return 1;
+
+ /* Look inside a TOC section too. */
+ if (h != NULL)
+ {
+ BFD_ASSERT (h->root.type == bfd_link_hash_defined);
+ off = h->root.u.def.value;
+ }
+ else
+ off = sym->st_value;
+ off += rel->r_addend;
+ BFD_ASSERT (off % 8 == 0);
+ r_symndx = ppc64_elf_section_data (sec)->u.toc.symndx[off / 8];
+ next_r = ppc64_elf_section_data (sec)->u.toc.symndx[off / 8 + 1];
+ if (toc_symndx != NULL)
+ *toc_symndx = r_symndx;
+ if (toc_addend != NULL)
+ *toc_addend = ppc64_elf_section_data (sec)->u.toc.add[off / 8];
+ if (!get_sym_h (&h, &sym, &sec, tls_maskp, locsymsp, r_symndx, ibfd))
+ return 0;
+ if ((h == NULL || is_static_defined (h))
+ && (next_r == -1 || next_r == -2))
+ return 1 - next_r;
+ return 1;
+}
+
+/* Find (or create) an entry in the tocsave hash table. */
+
+static struct tocsave_entry *
+tocsave_find (struct ppc_link_hash_table *htab,
+ enum insert_option insert,
+ Elf_Internal_Sym **local_syms,
+ const Elf_Internal_Rela *irela,
+ bfd *ibfd)
+{
+ unsigned long r_indx;
+ struct elf_link_hash_entry *h;
+ Elf_Internal_Sym *sym;
+ struct tocsave_entry ent, *p;
+ hashval_t hash;
+ struct tocsave_entry **slot;
+
+ r_indx = ELF64_R_SYM (irela->r_info);
+ if (!get_sym_h (&h, &sym, &ent.sec, NULL, local_syms, r_indx, ibfd))
+ return NULL;
+ if (ent.sec == NULL || ent.sec->output_section == NULL)
+ {
+ (*_bfd_error_handler)
+ (_("%B: undefined symbol on R_PPC64_TOCSAVE relocation"));
+ return NULL;
+ }
+
+ if (h != NULL)
+ ent.offset = h->root.u.def.value;
+ else
+ ent.offset = sym->st_value;
+ ent.offset += irela->r_addend;
+
+ hash = tocsave_htab_hash (&ent);
+ slot = ((struct tocsave_entry **)
+ htab_find_slot_with_hash (htab->tocsave_htab, &ent, hash, insert));
+ if (slot == NULL)
+ return NULL;
+
+ if (*slot == NULL)
+ {
+ p = (struct tocsave_entry *) bfd_alloc (ibfd, sizeof (*p));
+ if (p == NULL)
+ return NULL;
+ *p = ent;
+ *slot = p;
+ }
+ return *slot;
+}
+
+/* Adjust all global syms defined in opd sections. In gcc generated
+ code for the old ABI, these will already have been done. */
+
+static bfd_boolean
+adjust_opd_syms (struct elf_link_hash_entry *h, void *inf ATTRIBUTE_UNUSED)
+{
+ struct ppc_link_hash_entry *eh;
+ asection *sym_sec;
+ struct _opd_sec_data *opd;
+
+ if (h->root.type == bfd_link_hash_indirect)
+ return TRUE;
+
+ if (h->root.type != bfd_link_hash_defined
+ && h->root.type != bfd_link_hash_defweak)
+ return TRUE;
+
+ eh = (struct ppc_link_hash_entry *) h;
+ if (eh->adjust_done)
+ return TRUE;
+
+ sym_sec = eh->elf.root.u.def.section;
+ opd = get_opd_info (sym_sec);
+ if (opd != NULL && opd->adjust != NULL)
+ {
+ long adjust = opd->adjust[eh->elf.root.u.def.value / 8];
+ if (adjust == -1)
+ {
+ /* This entry has been deleted. */
+ asection *dsec = ppc64_elf_tdata (sym_sec->owner)->deleted_section;
+ if (dsec == NULL)
+ {
+ for (dsec = sym_sec->owner->sections; dsec; dsec = dsec->next)
+ if (discarded_section (dsec))
+ {
+ ppc64_elf_tdata (sym_sec->owner)->deleted_section = dsec;
+ break;
+ }
+ }
+ eh->elf.root.u.def.value = 0;
+ eh->elf.root.u.def.section = dsec;
+ }
+ else
+ eh->elf.root.u.def.value += adjust;
+ eh->adjust_done = 1;
+ }
+ return TRUE;
+}
+
+/* Handles decrementing dynamic reloc counts for the reloc specified by
+ R_INFO in section SEC. If LOCAL_SYMS is NULL, then H and SYM
+ have already been determined. */
+
+static bfd_boolean
+dec_dynrel_count (bfd_vma r_info,
+ asection *sec,
+ struct bfd_link_info *info,
+ Elf_Internal_Sym **local_syms,
+ struct elf_link_hash_entry *h,
+ Elf_Internal_Sym *sym)
+{
+ enum elf_ppc64_reloc_type r_type;
+ asection *sym_sec = NULL;
+
+ /* Can this reloc be dynamic? This switch, and later tests here
+ should be kept in sync with the code in check_relocs. */
+ r_type = ELF64_R_TYPE (r_info);
+ switch (r_type)
+ {
+ default:
+ return TRUE;
+
+ case R_PPC64_TPREL16:
+ case R_PPC64_TPREL16_LO:
+ case R_PPC64_TPREL16_HI:
+ case R_PPC64_TPREL16_HA:
+ case R_PPC64_TPREL16_DS:
+ case R_PPC64_TPREL16_LO_DS:
+ case R_PPC64_TPREL16_HIGH:
+ case R_PPC64_TPREL16_HIGHA:
+ case R_PPC64_TPREL16_HIGHER:
+ case R_PPC64_TPREL16_HIGHERA:
+ case R_PPC64_TPREL16_HIGHEST:
+ case R_PPC64_TPREL16_HIGHESTA:
+ if (!info->shared)
+ return TRUE;
+
+ case R_PPC64_TPREL64:
+ case R_PPC64_DTPMOD64:
+ case R_PPC64_DTPREL64:
+ case R_PPC64_ADDR64:
+ case R_PPC64_REL30:
+ case R_PPC64_REL32:
+ case R_PPC64_REL64:
+ case R_PPC64_ADDR14:
+ case R_PPC64_ADDR14_BRNTAKEN:
+ case R_PPC64_ADDR14_BRTAKEN:
+ case R_PPC64_ADDR16:
+ case R_PPC64_ADDR16_DS:
+ case R_PPC64_ADDR16_HA:
+ case R_PPC64_ADDR16_HI:
+ case R_PPC64_ADDR16_HIGH:
+ case R_PPC64_ADDR16_HIGHA:
+ case R_PPC64_ADDR16_HIGHER:
+ case R_PPC64_ADDR16_HIGHERA:
+ case R_PPC64_ADDR16_HIGHEST:
+ case R_PPC64_ADDR16_HIGHESTA:
+ case R_PPC64_ADDR16_LO:
+ case R_PPC64_ADDR16_LO_DS:
+ case R_PPC64_ADDR24:
+ case R_PPC64_ADDR32:
+ case R_PPC64_UADDR16:
+ case R_PPC64_UADDR32:
+ case R_PPC64_UADDR64:
+ case R_PPC64_TOC:
+ break;
+ }
+
+ if (local_syms != NULL)
+ {
+ unsigned long r_symndx;
+ bfd *ibfd = sec->owner;
+
+ r_symndx = ELF64_R_SYM (r_info);
+ if (!get_sym_h (&h, &sym, &sym_sec, NULL, local_syms, r_symndx, ibfd))
+ return FALSE;
+ }
+
+ if ((info->shared
+ && (must_be_dyn_reloc (info, r_type)
+ || (h != NULL
+ && (!SYMBOLIC_BIND (info, h)
+ || h->root.type == bfd_link_hash_defweak
+ || !h->def_regular))))
+ || (ELIMINATE_COPY_RELOCS
+ && !info->shared
+ && h != NULL
+ && (h->root.type == bfd_link_hash_defweak
+ || !h->def_regular)))
+ ;
+ else
+ return TRUE;
+
+ if (h != NULL)
+ {
+ struct elf_dyn_relocs *p;
+ struct elf_dyn_relocs **pp;
+ pp = &((struct ppc_link_hash_entry *) h)->dyn_relocs;
+
+ /* elf_gc_sweep may have already removed all dyn relocs associated
+ with local syms for a given section. Also, symbol flags are
+ changed by elf_gc_sweep_symbol, confusing the test above. Don't
+ report a dynreloc miscount. */
+ if (*pp == NULL && info->gc_sections)
+ return TRUE;
+
+ while ((p = *pp) != NULL)
+ {
+ if (p->sec == sec)
+ {
+ if (!must_be_dyn_reloc (info, r_type))
+ p->pc_count -= 1;
+ p->count -= 1;
+ if (p->count == 0)
+ *pp = p->next;
+ return TRUE;
+ }
+ pp = &p->next;
+ }
+ }
+ else
+ {
+ struct ppc_dyn_relocs *p;
+ struct ppc_dyn_relocs **pp;
+ void *vpp;
+ bfd_boolean is_ifunc;
+
+ if (local_syms == NULL)
+ sym_sec = bfd_section_from_elf_index (sec->owner, sym->st_shndx);
+ if (sym_sec == NULL)
+ sym_sec = sec;
+
+ vpp = &elf_section_data (sym_sec)->local_dynrel;
+ pp = (struct ppc_dyn_relocs **) vpp;
+
+ if (*pp == NULL && info->gc_sections)
+ return TRUE;
+
+ is_ifunc = ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC;
+ while ((p = *pp) != NULL)
+ {
+ if (p->sec == sec && p->ifunc == is_ifunc)
+ {
+ p->count -= 1;
+ if (p->count == 0)
+ *pp = p->next;
+ return TRUE;
+ }
+ pp = &p->next;
+ }
+ }
+
+ info->callbacks->einfo (_("%P: dynreloc miscount for %B, section %A\n"),
+ sec->owner, sec);
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+}
+
+/* Remove unused Official Procedure Descriptor entries. Currently we
+ only remove those associated with functions in discarded link-once
+ sections, or weakly defined functions that have been overridden. It
+ would be possible to remove many more entries for statically linked
+ applications. */
+
+bfd_boolean
+ppc64_elf_edit_opd (struct bfd_link_info *info)
+{
+ bfd *ibfd;
+ bfd_boolean some_edited = FALSE;
+ asection *need_pad = NULL;
+ struct ppc_link_hash_table *htab;
+
+ htab = ppc_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next)
+ {
+ asection *sec;
+ Elf_Internal_Rela *relstart, *rel, *relend;
+ Elf_Internal_Shdr *symtab_hdr;
+ Elf_Internal_Sym *local_syms;
+ bfd_vma offset;
+ struct _opd_sec_data *opd;
+ bfd_boolean need_edit, add_aux_fields;
+ bfd_size_type cnt_16b = 0;
+
+ if (!is_ppc64_elf (ibfd))
+ continue;
+
+ sec = bfd_get_section_by_name (ibfd, ".opd");
+ if (sec == NULL || sec->size == 0)
+ continue;
+
+ if (sec->sec_info_type == SEC_INFO_TYPE_JUST_SYMS)
+ continue;
+
+ if (sec->output_section == bfd_abs_section_ptr)
+ continue;
+
+ /* Look through the section relocs. */
+ if ((sec->flags & SEC_RELOC) == 0 || sec->reloc_count == 0)
+ continue;
+
+ local_syms = NULL;
+ symtab_hdr = &elf_symtab_hdr (ibfd);
+
+ /* Read the relocations. */
+ relstart = _bfd_elf_link_read_relocs (ibfd, sec, NULL, NULL,
+ info->keep_memory);
+ if (relstart == NULL)
+ return FALSE;
+
+ /* First run through the relocs to check they are sane, and to
+ determine whether we need to edit this opd section. */
+ need_edit = FALSE;
+ need_pad = sec;
+ offset = 0;
+ relend = relstart + sec->reloc_count;
+ for (rel = relstart; rel < relend; )
+ {
+ enum elf_ppc64_reloc_type r_type;
+ unsigned long r_symndx;
+ asection *sym_sec;
+ struct elf_link_hash_entry *h;
+ Elf_Internal_Sym *sym;
+
+ /* .opd contains a regular array of 16 or 24 byte entries. We're
+ only interested in the reloc pointing to a function entry
+ point. */
+ if (rel->r_offset != offset
+ || rel + 1 >= relend
+ || (rel + 1)->r_offset != offset + 8)
+ {
+ /* If someone messes with .opd alignment then after a
+ "ld -r" we might have padding in the middle of .opd.
+ Also, there's nothing to prevent someone putting
+ something silly in .opd with the assembler. No .opd
+ optimization for them! */
+ broken_opd:
+ (*_bfd_error_handler)
+ (_("%B: .opd is not a regular array of opd entries"), ibfd);
+ need_edit = FALSE;
+ break;
+ }
+
+ if ((r_type = ELF64_R_TYPE (rel->r_info)) != R_PPC64_ADDR64
+ || (r_type = ELF64_R_TYPE ((rel + 1)->r_info)) != R_PPC64_TOC)
+ {
+ (*_bfd_error_handler)
+ (_("%B: unexpected reloc type %u in .opd section"),
+ ibfd, r_type);
+ need_edit = FALSE;
+ break;
+ }
+
+ r_symndx = ELF64_R_SYM (rel->r_info);
+ if (!get_sym_h (&h, &sym, &sym_sec, NULL, &local_syms,
+ r_symndx, ibfd))
+ goto error_ret;
+
+ if (sym_sec == NULL || sym_sec->owner == NULL)
+ {
+ const char *sym_name;
+ if (h != NULL)
+ sym_name = h->root.root.string;
+ else
+ sym_name = bfd_elf_sym_name (ibfd, symtab_hdr, sym,
+ sym_sec);
+
+ (*_bfd_error_handler)
+ (_("%B: undefined sym `%s' in .opd section"),
+ ibfd, sym_name);
+ need_edit = FALSE;
+ break;
+ }
+
+ /* opd entries are always for functions defined in the
+ current input bfd. If the symbol isn't defined in the
+ input bfd, then we won't be using the function in this
+ bfd; It must be defined in a linkonce section in another
+ bfd, or is weak. It's also possible that we are
+ discarding the function due to a linker script /DISCARD/,
+ which we test for via the output_section. */
+ if (sym_sec->owner != ibfd
+ || sym_sec->output_section == bfd_abs_section_ptr)
+ need_edit = TRUE;
+
+ rel += 2;
+ if (rel == relend
+ || (rel + 1 == relend && rel->r_offset == offset + 16))
+ {
+ if (sec->size == offset + 24)
+ {
+ need_pad = NULL;
+ break;
+ }
+ if (rel == relend && sec->size == offset + 16)
+ {
+ cnt_16b++;
+ break;
+ }
+ goto broken_opd;
+ }
+
+ if (rel->r_offset == offset + 24)
+ offset += 24;
+ else if (rel->r_offset != offset + 16)
+ goto broken_opd;
+ else if (rel + 1 < relend
+ && ELF64_R_TYPE (rel[0].r_info) == R_PPC64_ADDR64
+ && ELF64_R_TYPE (rel[1].r_info) == R_PPC64_TOC)
+ {
+ offset += 16;
+ cnt_16b++;
+ }
+ else if (rel + 2 < relend
+ && ELF64_R_TYPE (rel[1].r_info) == R_PPC64_ADDR64
+ && ELF64_R_TYPE (rel[2].r_info) == R_PPC64_TOC)
+ {
+ offset += 24;
+ rel += 1;
+ }
+ else
+ goto broken_opd;
+ }
+
+ add_aux_fields = htab->params->non_overlapping_opd && cnt_16b > 0;
+
+ if (need_edit || add_aux_fields)
+ {
+ Elf_Internal_Rela *write_rel;
+ Elf_Internal_Shdr *rel_hdr;
+ bfd_byte *rptr, *wptr;
+ bfd_byte *new_contents;
+ bfd_boolean skip;
+ long opd_ent_size;
+ bfd_size_type amt;
+
+ new_contents = NULL;
+ amt = sec->size * sizeof (long) / 8;
+ opd = &ppc64_elf_section_data (sec)->u.opd;
+ opd->adjust = bfd_zalloc (sec->owner, amt);
+ if (opd->adjust == NULL)
+ return FALSE;
+ ppc64_elf_section_data (sec)->sec_type = sec_opd;
+
+ /* This seems a waste of time as input .opd sections are all
+ zeros as generated by gcc, but I suppose there's no reason
+ this will always be so. We might start putting something in
+ the third word of .opd entries. */
+ if ((sec->flags & SEC_IN_MEMORY) == 0)
+ {
+ bfd_byte *loc;
+ if (!bfd_malloc_and_get_section (ibfd, sec, &loc))
+ {
+ if (loc != NULL)
+ free (loc);
+ error_ret:
+ if (local_syms != NULL
+ && symtab_hdr->contents != (unsigned char *) local_syms)
+ free (local_syms);
+ if (elf_section_data (sec)->relocs != relstart)
+ free (relstart);
+ return FALSE;
+ }
+ sec->contents = loc;
+ sec->flags |= (SEC_IN_MEMORY | SEC_HAS_CONTENTS);
+ }
+
+ elf_section_data (sec)->relocs = relstart;
+
+ new_contents = sec->contents;
+ if (add_aux_fields)
+ {
+ new_contents = bfd_malloc (sec->size + cnt_16b * 8);
+ if (new_contents == NULL)
+ return FALSE;
+ need_pad = FALSE;
+ }
+ wptr = new_contents;
+ rptr = sec->contents;
+
+ write_rel = relstart;
+ skip = FALSE;
+ offset = 0;
+ opd_ent_size = 0;
+ for (rel = relstart; rel < relend; rel++)
+ {
+ unsigned long r_symndx;
+ asection *sym_sec;
+ struct elf_link_hash_entry *h;
+ Elf_Internal_Sym *sym;
+
+ r_symndx = ELF64_R_SYM (rel->r_info);
+ if (!get_sym_h (&h, &sym, &sym_sec, NULL, &local_syms,
+ r_symndx, ibfd))
+ goto error_ret;
+
+ if (rel->r_offset == offset)
+ {
+ struct ppc_link_hash_entry *fdh = NULL;
+
+ /* See if the .opd entry is full 24 byte or
+ 16 byte (with fd_aux entry overlapped with next
+ fd_func). */
+ opd_ent_size = 24;
+ if ((rel + 2 == relend && sec->size == offset + 16)
+ || (rel + 3 < relend
+ && rel[2].r_offset == offset + 16
+ && rel[3].r_offset == offset + 24
+ && ELF64_R_TYPE (rel[2].r_info) == R_PPC64_ADDR64
+ && ELF64_R_TYPE (rel[3].r_info) == R_PPC64_TOC))
+ opd_ent_size = 16;
+
+ if (h != NULL
+ && h->root.root.string[0] == '.')
+ {
+ fdh = lookup_fdh ((struct ppc_link_hash_entry *) h, htab);
+ if (fdh != NULL
+ && fdh->elf.root.type != bfd_link_hash_defined
+ && fdh->elf.root.type != bfd_link_hash_defweak)
+ fdh = NULL;
+ }
+
+ skip = (sym_sec->owner != ibfd
+ || sym_sec->output_section == bfd_abs_section_ptr);
+ if (skip)
+ {
+ if (fdh != NULL && sym_sec->owner == ibfd)
+ {
+ /* Arrange for the function descriptor sym
+ to be dropped. */
+ fdh->elf.root.u.def.value = 0;
+ fdh->elf.root.u.def.section = sym_sec;
+ }
+ opd->adjust[rel->r_offset / 8] = -1;
+ }
+ else
+ {
+ /* We'll be keeping this opd entry. */
+
+ if (fdh != NULL)
+ {
+ /* Redefine the function descriptor symbol to
+ this location in the opd section. It is
+ necessary to update the value here rather
+ than using an array of adjustments as we do
+ for local symbols, because various places
+ in the generic ELF code use the value
+ stored in u.def.value. */
+ fdh->elf.root.u.def.value = wptr - new_contents;
+ fdh->adjust_done = 1;
+ }
+
+ /* Local syms are a bit tricky. We could
+ tweak them as they can be cached, but
+ we'd need to look through the local syms
+ for the function descriptor sym which we
+ don't have at the moment. So keep an
+ array of adjustments. */
+ opd->adjust[rel->r_offset / 8]
+ = (wptr - new_contents) - (rptr - sec->contents);
+
+ if (wptr != rptr)
+ memcpy (wptr, rptr, opd_ent_size);
+ wptr += opd_ent_size;
+ if (add_aux_fields && opd_ent_size == 16)
+ {
+ memset (wptr, '\0', 8);
+ wptr += 8;
+ }
+ }
+ rptr += opd_ent_size;
+ offset += opd_ent_size;
+ }
+
+ if (skip)
+ {
+ if (!NO_OPD_RELOCS
+ && !info->relocatable
+ && !dec_dynrel_count (rel->r_info, sec, info,
+ NULL, h, sym))
+ goto error_ret;
+ }
+ else
+ {
+ /* We need to adjust any reloc offsets to point to the
+ new opd entries. While we're at it, we may as well
+ remove redundant relocs. */
+ rel->r_offset += opd->adjust[(offset - opd_ent_size) / 8];
+ if (write_rel != rel)
+ memcpy (write_rel, rel, sizeof (*rel));
+ ++write_rel;
+ }
+ }
+
+ sec->size = wptr - new_contents;
+ sec->reloc_count = write_rel - relstart;
+ if (add_aux_fields)
+ {
+ free (sec->contents);
+ sec->contents = new_contents;
+ }
+
+ /* Fudge the header size too, as this is used later in
+ elf_bfd_final_link if we are emitting relocs. */
+ rel_hdr = _bfd_elf_single_rel_hdr (sec);
+ rel_hdr->sh_size = sec->reloc_count * rel_hdr->sh_entsize;
+ some_edited = TRUE;
+ }
+ else if (elf_section_data (sec)->relocs != relstart)
+ free (relstart);
+
+ if (local_syms != NULL
+ && symtab_hdr->contents != (unsigned char *) local_syms)
+ {
+ if (!info->keep_memory)
+ free (local_syms);
+ else
+ symtab_hdr->contents = (unsigned char *) local_syms;
+ }
+ }
+
+ if (some_edited)
+ elf_link_hash_traverse (elf_hash_table (info), adjust_opd_syms, NULL);
+
+ /* If we are doing a final link and the last .opd entry is just 16 byte
+ long, add a 8 byte padding after it. */
+ if (need_pad != NULL && !info->relocatable)
+ {
+ bfd_byte *p;
+
+ if ((need_pad->flags & SEC_IN_MEMORY) == 0)
+ {
+ BFD_ASSERT (need_pad->size > 0);
+
+ p = bfd_malloc (need_pad->size + 8);
+ if (p == NULL)
+ return FALSE;
+
+ if (! bfd_get_section_contents (need_pad->owner, need_pad,
+ p, 0, need_pad->size))
+ return FALSE;
+
+ need_pad->contents = p;
+ need_pad->flags |= (SEC_IN_MEMORY | SEC_HAS_CONTENTS);
+ }
+ else
+ {
+ p = bfd_realloc (need_pad->contents, need_pad->size + 8);
+ if (p == NULL)
+ return FALSE;
+
+ need_pad->contents = p;
+ }
+
+ memset (need_pad->contents + need_pad->size, 0, 8);
+ need_pad->size += 8;
+ }
+
+ return TRUE;
+}
+
+/* Set htab->tls_get_addr and call the generic ELF tls_setup function. */
+
+asection *
+ppc64_elf_tls_setup (struct bfd_link_info *info)
+{
+ struct ppc_link_hash_table *htab;
+
+ htab = ppc_hash_table (info);
+ if (htab == NULL)
+ return NULL;
+
+ if (abiversion (info->output_bfd) == 1)
+ htab->opd_abi = 1;
+
+ if (htab->params->no_multi_toc)
+ htab->do_multi_toc = 0;
+ else if (!htab->do_multi_toc)
+ htab->params->no_multi_toc = 1;
+
+ htab->tls_get_addr = ((struct ppc_link_hash_entry *)
+ elf_link_hash_lookup (&htab->elf, ".__tls_get_addr",
+ FALSE, FALSE, TRUE));
+ /* Move dynamic linking info to the function descriptor sym. */
+ if (htab->tls_get_addr != NULL)
+ func_desc_adjust (&htab->tls_get_addr->elf, info);
+ htab->tls_get_addr_fd = ((struct ppc_link_hash_entry *)
+ elf_link_hash_lookup (&htab->elf, "__tls_get_addr",
+ FALSE, FALSE, TRUE));
+ if (!htab->params->no_tls_get_addr_opt)
+ {
+ struct elf_link_hash_entry *opt, *opt_fd, *tga, *tga_fd;
+
+ opt = elf_link_hash_lookup (&htab->elf, ".__tls_get_addr_opt",
+ FALSE, FALSE, TRUE);
+ if (opt != NULL)
+ func_desc_adjust (opt, info);
+ opt_fd = elf_link_hash_lookup (&htab->elf, "__tls_get_addr_opt",
+ FALSE, FALSE, TRUE);
+ if (opt_fd != NULL
+ && (opt_fd->root.type == bfd_link_hash_defined
+ || opt_fd->root.type == bfd_link_hash_defweak))
+ {
+ /* If glibc supports an optimized __tls_get_addr call stub,
+ signalled by the presence of __tls_get_addr_opt, and we'll
+ be calling __tls_get_addr via a plt call stub, then
+ make __tls_get_addr point to __tls_get_addr_opt. */
+ tga_fd = &htab->tls_get_addr_fd->elf;
+ if (htab->elf.dynamic_sections_created
+ && tga_fd != NULL
+ && (tga_fd->type == STT_FUNC
+ || tga_fd->needs_plt)
+ && !(SYMBOL_CALLS_LOCAL (info, tga_fd)
+ || (ELF_ST_VISIBILITY (tga_fd->other) != STV_DEFAULT
+ && tga_fd->root.type == bfd_link_hash_undefweak)))
+ {
+ struct plt_entry *ent;
+
+ for (ent = tga_fd->plt.plist; ent != NULL; ent = ent->next)
+ if (ent->plt.refcount > 0)
+ break;
+ if (ent != NULL)
+ {
+ tga_fd->root.type = bfd_link_hash_indirect;
+ tga_fd->root.u.i.link = &opt_fd->root;
+ ppc64_elf_copy_indirect_symbol (info, opt_fd, tga_fd);
+ if (opt_fd->dynindx != -1)
+ {
+ /* Use __tls_get_addr_opt in dynamic relocations. */
+ opt_fd->dynindx = -1;
+ _bfd_elf_strtab_delref (elf_hash_table (info)->dynstr,
+ opt_fd->dynstr_index);
+ if (!bfd_elf_link_record_dynamic_symbol (info, opt_fd))
+ return NULL;
+ }
+ htab->tls_get_addr_fd = (struct ppc_link_hash_entry *) opt_fd;
+ tga = &htab->tls_get_addr->elf;
+ if (opt != NULL && tga != NULL)
+ {
+ tga->root.type = bfd_link_hash_indirect;
+ tga->root.u.i.link = &opt->root;
+ ppc64_elf_copy_indirect_symbol (info, opt, tga);
+ _bfd_elf_link_hash_hide_symbol (info, opt,
+ tga->forced_local);
+ htab->tls_get_addr = (struct ppc_link_hash_entry *) opt;
+ }
+ htab->tls_get_addr_fd->oh = htab->tls_get_addr;
+ htab->tls_get_addr_fd->is_func_descriptor = 1;
+ if (htab->tls_get_addr != NULL)
+ {
+ htab->tls_get_addr->oh = htab->tls_get_addr_fd;
+ htab->tls_get_addr->is_func = 1;
+ }
+ }
+ }
+ }
+ else
+ htab->params->no_tls_get_addr_opt = TRUE;
+ }
+ return _bfd_elf_tls_setup (info->output_bfd, info);
+}
+
+/* Return TRUE iff REL is a branch reloc with a global symbol matching
+ HASH1 or HASH2. */
+
+static bfd_boolean
+branch_reloc_hash_match (const bfd *ibfd,
+ const Elf_Internal_Rela *rel,
+ const struct ppc_link_hash_entry *hash1,
+ const struct ppc_link_hash_entry *hash2)
+{
+ Elf_Internal_Shdr *symtab_hdr = &elf_symtab_hdr (ibfd);
+ enum elf_ppc64_reloc_type r_type = ELF64_R_TYPE (rel->r_info);
+ unsigned int r_symndx = ELF64_R_SYM (rel->r_info);
+
+ if (r_symndx >= symtab_hdr->sh_info && is_branch_reloc (r_type))
+ {
+ struct elf_link_hash_entry **sym_hashes = elf_sym_hashes (ibfd);
+ struct elf_link_hash_entry *h;
+
+ h = sym_hashes[r_symndx - symtab_hdr->sh_info];
+ h = elf_follow_link (h);
+ if (h == &hash1->elf || h == &hash2->elf)
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/* Run through all the TLS relocs looking for optimization
+ opportunities. The linker has been hacked (see ppc64elf.em) to do
+ a preliminary section layout so that we know the TLS segment
+ offsets. We can't optimize earlier because some optimizations need
+ to know the tp offset, and we need to optimize before allocating
+ dynamic relocations. */
+
+bfd_boolean
+ppc64_elf_tls_optimize (struct bfd_link_info *info)
+{
+ bfd *ibfd;
+ asection *sec;
+ struct ppc_link_hash_table *htab;
+ unsigned char *toc_ref;
+ int pass;
+
+ if (info->relocatable || !info->executable)
+ return TRUE;
+
+ htab = ppc_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ /* Make two passes over the relocs. On the first pass, mark toc
+ entries involved with tls relocs, and check that tls relocs
+ involved in setting up a tls_get_addr call are indeed followed by
+ such a call. If they are not, we can't do any tls optimization.
+ On the second pass twiddle tls_mask flags to notify
+ relocate_section that optimization can be done, and adjust got
+ and plt refcounts. */
+ toc_ref = NULL;
+ for (pass = 0; pass < 2; ++pass)
+ for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next)
+ {
+ Elf_Internal_Sym *locsyms = NULL;
+ asection *toc = bfd_get_section_by_name (ibfd, ".toc");
+
+ for (sec = ibfd->sections; sec != NULL; sec = sec->next)
+ if (sec->has_tls_reloc && !bfd_is_abs_section (sec->output_section))
+ {
+ Elf_Internal_Rela *relstart, *rel, *relend;
+ bfd_boolean found_tls_get_addr_arg = 0;
+
+ /* Read the relocations. */
+ relstart = _bfd_elf_link_read_relocs (ibfd, sec, NULL, NULL,
+ info->keep_memory);
+ if (relstart == NULL)
+ {
+ free (toc_ref);
+ return FALSE;
+ }
+
+ relend = relstart + sec->reloc_count;
+ for (rel = relstart; rel < relend; rel++)
+ {
+ enum elf_ppc64_reloc_type r_type;
+ unsigned long r_symndx;
+ struct elf_link_hash_entry *h;
+ Elf_Internal_Sym *sym;
+ asection *sym_sec;
+ unsigned char *tls_mask;
+ unsigned char tls_set, tls_clear, tls_type = 0;
+ bfd_vma value;
+ bfd_boolean ok_tprel, is_local;
+ long toc_ref_index = 0;
+ int expecting_tls_get_addr = 0;
+ bfd_boolean ret = FALSE;
+
+ r_symndx = ELF64_R_SYM (rel->r_info);
+ if (!get_sym_h (&h, &sym, &sym_sec, &tls_mask, &locsyms,
+ r_symndx, ibfd))
+ {
+ err_free_rel:
+ if (elf_section_data (sec)->relocs != relstart)
+ free (relstart);
+ if (toc_ref != NULL)
+ free (toc_ref);
+ if (locsyms != NULL
+ && (elf_symtab_hdr (ibfd).contents
+ != (unsigned char *) locsyms))
+ free (locsyms);
+ return ret;
+ }
+
+ if (h != NULL)
+ {
+ if (h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak)
+ value = h->root.u.def.value;
+ else if (h->root.type == bfd_link_hash_undefweak)
+ value = 0;
+ else
+ {
+ found_tls_get_addr_arg = 0;
+ continue;
+ }
+ }
+ else
+ /* Symbols referenced by TLS relocs must be of type
+ STT_TLS. So no need for .opd local sym adjust. */
+ value = sym->st_value;
+
+ ok_tprel = FALSE;
+ is_local = FALSE;
+ if (h == NULL
+ || !h->def_dynamic)
+ {
+ is_local = TRUE;
+ if (h != NULL
+ && h->root.type == bfd_link_hash_undefweak)
+ ok_tprel = TRUE;
+ else
+ {
+ value += sym_sec->output_offset;
+ value += sym_sec->output_section->vma;
+ value -= htab->elf.tls_sec->vma;
+ ok_tprel = (value + TP_OFFSET + ((bfd_vma) 1 << 31)
+ < (bfd_vma) 1 << 32);
+ }
+ }
+
+ r_type = ELF64_R_TYPE (rel->r_info);
+ /* If this section has old-style __tls_get_addr calls
+ without marker relocs, then check that each
+ __tls_get_addr call reloc is preceded by a reloc
+ that conceivably belongs to the __tls_get_addr arg
+ setup insn. If we don't find matching arg setup
+ relocs, don't do any tls optimization. */
+ if (pass == 0
+ && sec->has_tls_get_addr_call
+ && h != NULL
+ && (h == &htab->tls_get_addr->elf
+ || h == &htab->tls_get_addr_fd->elf)
+ && !found_tls_get_addr_arg
+ && is_branch_reloc (r_type))
+ {
+ info->callbacks->minfo (_("%H __tls_get_addr lost arg, "
+ "TLS optimization disabled\n"),
+ ibfd, sec, rel->r_offset);
+ ret = TRUE;
+ goto err_free_rel;
+ }
+
+ found_tls_get_addr_arg = 0;
+ switch (r_type)
+ {
+ case R_PPC64_GOT_TLSLD16:
+ case R_PPC64_GOT_TLSLD16_LO:
+ expecting_tls_get_addr = 1;
+ found_tls_get_addr_arg = 1;
+ /* Fall thru */
+
+ case R_PPC64_GOT_TLSLD16_HI:
+ case R_PPC64_GOT_TLSLD16_HA:
+ /* These relocs should never be against a symbol
+ defined in a shared lib. Leave them alone if
+ that turns out to be the case. */
+ if (!is_local)
+ continue;
+
+ /* LD -> LE */
+ tls_set = 0;
+ tls_clear = TLS_LD;
+ tls_type = TLS_TLS | TLS_LD;
+ break;
+
+ case R_PPC64_GOT_TLSGD16:
+ case R_PPC64_GOT_TLSGD16_LO:
+ expecting_tls_get_addr = 1;
+ found_tls_get_addr_arg = 1;
+ /* Fall thru */
+
+ case R_PPC64_GOT_TLSGD16_HI:
+ case R_PPC64_GOT_TLSGD16_HA:
+ if (ok_tprel)
+ /* GD -> LE */
+ tls_set = 0;
+ else
+ /* GD -> IE */
+ tls_set = TLS_TLS | TLS_TPRELGD;
+ tls_clear = TLS_GD;
+ tls_type = TLS_TLS | TLS_GD;
+ break;
+
+ case R_PPC64_GOT_TPREL16_DS:
+ case R_PPC64_GOT_TPREL16_LO_DS:
+ case R_PPC64_GOT_TPREL16_HI:
+ case R_PPC64_GOT_TPREL16_HA:
+ if (ok_tprel)
+ {
+ /* IE -> LE */
+ tls_set = 0;
+ tls_clear = TLS_TPREL;
+ tls_type = TLS_TLS | TLS_TPREL;
+ break;
+ }
+ continue;
+
+ case R_PPC64_TLSGD:
+ case R_PPC64_TLSLD:
+ found_tls_get_addr_arg = 1;
+ /* Fall thru */
+
+ case R_PPC64_TLS:
+ case R_PPC64_TOC16:
+ case R_PPC64_TOC16_LO:
+ if (sym_sec == NULL || sym_sec != toc)
+ continue;
+
+ /* Mark this toc entry as referenced by a TLS
+ code sequence. We can do that now in the
+ case of R_PPC64_TLS, and after checking for
+ tls_get_addr for the TOC16 relocs. */
+ if (toc_ref == NULL)
+ toc_ref = bfd_zmalloc (toc->output_section->rawsize / 8);
+ if (toc_ref == NULL)
+ goto err_free_rel;
+
+ if (h != NULL)
+ value = h->root.u.def.value;
+ else
+ value = sym->st_value;
+ value += rel->r_addend;
+ if (value % 8 != 0)
+ continue;
+ BFD_ASSERT (value < toc->size
+ && toc->output_offset % 8 == 0);
+ toc_ref_index = (value + toc->output_offset) / 8;
+ if (r_type == R_PPC64_TLS
+ || r_type == R_PPC64_TLSGD
+ || r_type == R_PPC64_TLSLD)
+ {
+ toc_ref[toc_ref_index] = 1;
+ continue;
+ }
+
+ if (pass != 0 && toc_ref[toc_ref_index] == 0)
+ continue;
+
+ tls_set = 0;
+ tls_clear = 0;
+ expecting_tls_get_addr = 2;
+ break;
+
+ case R_PPC64_TPREL64:
+ if (pass == 0
+ || sec != toc
+ || toc_ref == NULL
+ || !toc_ref[(rel->r_offset + toc->output_offset) / 8])
+ continue;
+ if (ok_tprel)
+ {
+ /* IE -> LE */
+ tls_set = TLS_EXPLICIT;
+ tls_clear = TLS_TPREL;
+ break;
+ }
+ continue;
+
+ case R_PPC64_DTPMOD64:
+ if (pass == 0
+ || sec != toc
+ || toc_ref == NULL
+ || !toc_ref[(rel->r_offset + toc->output_offset) / 8])
+ continue;
+ if (rel + 1 < relend
+ && (rel[1].r_info
+ == ELF64_R_INFO (r_symndx, R_PPC64_DTPREL64))
+ && rel[1].r_offset == rel->r_offset + 8)
+ {
+ if (ok_tprel)
+ /* GD -> LE */
+ tls_set = TLS_EXPLICIT | TLS_GD;
+ else
+ /* GD -> IE */
+ tls_set = TLS_EXPLICIT | TLS_GD | TLS_TPRELGD;
+ tls_clear = TLS_GD;
+ }
+ else
+ {
+ if (!is_local)
+ continue;
+
+ /* LD -> LE */
+ tls_set = TLS_EXPLICIT;
+ tls_clear = TLS_LD;
+ }
+ break;
+
+ default:
+ continue;
+ }
+
+ if (pass == 0)
+ {
+ if (!expecting_tls_get_addr
+ || !sec->has_tls_get_addr_call)
+ continue;
+
+ if (rel + 1 < relend
+ && branch_reloc_hash_match (ibfd, rel + 1,
+ htab->tls_get_addr,
+ htab->tls_get_addr_fd))
+ {
+ if (expecting_tls_get_addr == 2)
+ {
+ /* Check for toc tls entries. */
+ unsigned char *toc_tls;
+ int retval;
+
+ retval = get_tls_mask (&toc_tls, NULL, NULL,
+ &locsyms,
+ rel, ibfd);
+ if (retval == 0)
+ goto err_free_rel;
+ if (toc_tls != NULL)
+ {
+ if ((*toc_tls & (TLS_GD | TLS_LD)) != 0)
+ found_tls_get_addr_arg = 1;
+ if (retval > 1)
+ toc_ref[toc_ref_index] = 1;
+ }
+ }
+ continue;
+ }
+
+ if (expecting_tls_get_addr != 1)
+ continue;
+
+ /* Uh oh, we didn't find the expected call. We
+ could just mark this symbol to exclude it
+ from tls optimization but it's safer to skip
+ the entire optimization. */
+ info->callbacks->minfo (_("%H arg lost __tls_get_addr, "
+ "TLS optimization disabled\n"),
+ ibfd, sec, rel->r_offset);
+ ret = TRUE;
+ goto err_free_rel;
+ }
+
+ if (expecting_tls_get_addr && htab->tls_get_addr != NULL)
+ {
+ struct plt_entry *ent;
+ for (ent = htab->tls_get_addr->elf.plt.plist;
+ ent != NULL;
+ ent = ent->next)
+ if (ent->addend == 0)
+ {
+ if (ent->plt.refcount > 0)
+ {
+ ent->plt.refcount -= 1;
+ expecting_tls_get_addr = 0;
+ }
+ break;
+ }
+ }
+
+ if (expecting_tls_get_addr && htab->tls_get_addr_fd != NULL)
+ {
+ struct plt_entry *ent;
+ for (ent = htab->tls_get_addr_fd->elf.plt.plist;
+ ent != NULL;
+ ent = ent->next)
+ if (ent->addend == 0)
+ {
+ if (ent->plt.refcount > 0)
+ ent->plt.refcount -= 1;
+ break;
+ }
+ }
+
+ if (tls_clear == 0)
+ continue;
+
+ if ((tls_set & TLS_EXPLICIT) == 0)
+ {
+ struct got_entry *ent;
+
+ /* Adjust got entry for this reloc. */
+ if (h != NULL)
+ ent = h->got.glist;
+ else
+ ent = elf_local_got_ents (ibfd)[r_symndx];
+
+ for (; ent != NULL; ent = ent->next)
+ if (ent->addend == rel->r_addend
+ && ent->owner == ibfd
+ && ent->tls_type == tls_type)
+ break;
+ if (ent == NULL)
+ abort ();
+
+ if (tls_set == 0)
+ {
+ /* We managed to get rid of a got entry. */
+ if (ent->got.refcount > 0)
+ ent->got.refcount -= 1;
+ }
+ }
+ else
+ {
+ /* If we got rid of a DTPMOD/DTPREL reloc pair then
+ we'll lose one or two dyn relocs. */
+ if (!dec_dynrel_count (rel->r_info, sec, info,
+ NULL, h, sym))
+ return FALSE;
+
+ if (tls_set == (TLS_EXPLICIT | TLS_GD))
+ {
+ if (!dec_dynrel_count ((rel + 1)->r_info, sec, info,
+ NULL, h, sym))
+ return FALSE;
+ }
+ }
+
+ *tls_mask |= tls_set;
+ *tls_mask &= ~tls_clear;
+ }
+
+ if (elf_section_data (sec)->relocs != relstart)
+ free (relstart);
+ }
+
+ if (locsyms != NULL
+ && (elf_symtab_hdr (ibfd).contents != (unsigned char *) locsyms))
+ {
+ if (!info->keep_memory)
+ free (locsyms);
+ else
+ elf_symtab_hdr (ibfd).contents = (unsigned char *) locsyms;
+ }
+ }
+
+ if (toc_ref != NULL)
+ free (toc_ref);
+ return TRUE;
+}
+
+/* Called via elf_link_hash_traverse from ppc64_elf_edit_toc to adjust
+ the values of any global symbols in a toc section that has been
+ edited. Globals in toc sections should be a rarity, so this function
+ sets a flag if any are found in toc sections other than the one just
+ edited, so that futher hash table traversals can be avoided. */
+
+struct adjust_toc_info
+{
+ asection *toc;
+ unsigned long *skip;
+ bfd_boolean global_toc_syms;
+};
+
+enum toc_skip_enum { ref_from_discarded = 1, can_optimize = 2 };
+
+static bfd_boolean
+adjust_toc_syms (struct elf_link_hash_entry *h, void *inf)
+{
+ struct ppc_link_hash_entry *eh;
+ struct adjust_toc_info *toc_inf = (struct adjust_toc_info *) inf;
+ unsigned long i;
+
+ if (h->root.type != bfd_link_hash_defined
+ && h->root.type != bfd_link_hash_defweak)
+ return TRUE;
+
+ eh = (struct ppc_link_hash_entry *) h;
+ if (eh->adjust_done)
+ return TRUE;
+
+ if (eh->elf.root.u.def.section == toc_inf->toc)
+ {
+ if (eh->elf.root.u.def.value > toc_inf->toc->rawsize)
+ i = toc_inf->toc->rawsize >> 3;
+ else
+ i = eh->elf.root.u.def.value >> 3;
+
+ if ((toc_inf->skip[i] & (ref_from_discarded | can_optimize)) != 0)
+ {
+ (*_bfd_error_handler)
+ (_("%s defined on removed toc entry"), eh->elf.root.root.string);
+ do
+ ++i;
+ while ((toc_inf->skip[i] & (ref_from_discarded | can_optimize)) != 0);
+ eh->elf.root.u.def.value = (bfd_vma) i << 3;
+ }
+
+ eh->elf.root.u.def.value -= toc_inf->skip[i];
+ eh->adjust_done = 1;
+ }
+ else if (strcmp (eh->elf.root.u.def.section->name, ".toc") == 0)
+ toc_inf->global_toc_syms = TRUE;
+
+ return TRUE;
+}
+
+/* Return TRUE iff INSN is one we expect on a _LO variety toc/got reloc. */
+
+static bfd_boolean
+ok_lo_toc_insn (unsigned int insn)
+{
+ return ((insn & (0x3f << 26)) == 14u << 26 /* addi */
+ || (insn & (0x3f << 26)) == 32u << 26 /* lwz */
+ || (insn & (0x3f << 26)) == 34u << 26 /* lbz */
+ || (insn & (0x3f << 26)) == 36u << 26 /* stw */
+ || (insn & (0x3f << 26)) == 38u << 26 /* stb */
+ || (insn & (0x3f << 26)) == 40u << 26 /* lhz */
+ || (insn & (0x3f << 26)) == 42u << 26 /* lha */
+ || (insn & (0x3f << 26)) == 44u << 26 /* sth */
+ || (insn & (0x3f << 26)) == 46u << 26 /* lmw */
+ || (insn & (0x3f << 26)) == 47u << 26 /* stmw */
+ || (insn & (0x3f << 26)) == 48u << 26 /* lfs */
+ || (insn & (0x3f << 26)) == 50u << 26 /* lfd */
+ || (insn & (0x3f << 26)) == 52u << 26 /* stfs */
+ || (insn & (0x3f << 26)) == 54u << 26 /* stfd */
+ || ((insn & (0x3f << 26)) == 58u << 26 /* lwa,ld,lmd */
+ && (insn & 3) != 1)
+ || ((insn & (0x3f << 26)) == 62u << 26 /* std, stmd */
+ && ((insn & 3) == 0 || (insn & 3) == 3))
+ || (insn & (0x3f << 26)) == 12u << 26 /* addic */);
+}
+
+/* Examine all relocs referencing .toc sections in order to remove
+ unused .toc entries. */
+
+bfd_boolean
+ppc64_elf_edit_toc (struct bfd_link_info *info)
+{
+ bfd *ibfd;
+ struct adjust_toc_info toc_inf;
+ struct ppc_link_hash_table *htab = ppc_hash_table (info);
+
+ htab->do_toc_opt = 1;
+ toc_inf.global_toc_syms = TRUE;
+ for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next)
+ {
+ asection *toc, *sec;
+ Elf_Internal_Shdr *symtab_hdr;
+ Elf_Internal_Sym *local_syms;
+ Elf_Internal_Rela *relstart, *rel, *toc_relocs;
+ unsigned long *skip, *drop;
+ unsigned char *used;
+ unsigned char *keep, last, some_unused;
+
+ if (!is_ppc64_elf (ibfd))
+ continue;
+
+ toc = bfd_get_section_by_name (ibfd, ".toc");
+ if (toc == NULL
+ || toc->size == 0
+ || toc->sec_info_type == SEC_INFO_TYPE_JUST_SYMS
+ || discarded_section (toc))
+ continue;
+
+ toc_relocs = NULL;
+ local_syms = NULL;
+ symtab_hdr = &elf_symtab_hdr (ibfd);
+
+ /* Look at sections dropped from the final link. */
+ skip = NULL;
+ relstart = NULL;
+ for (sec = ibfd->sections; sec != NULL; sec = sec->next)
+ {
+ if (sec->reloc_count == 0
+ || !discarded_section (sec)
+ || get_opd_info (sec)
+ || (sec->flags & SEC_ALLOC) == 0
+ || (sec->flags & SEC_DEBUGGING) != 0)
+ continue;
+
+ relstart = _bfd_elf_link_read_relocs (ibfd, sec, NULL, NULL, FALSE);
+ if (relstart == NULL)
+ goto error_ret;
+
+ /* Run through the relocs to see which toc entries might be
+ unused. */
+ for (rel = relstart; rel < relstart + sec->reloc_count; ++rel)
+ {
+ enum elf_ppc64_reloc_type r_type;
+ unsigned long r_symndx;
+ asection *sym_sec;
+ struct elf_link_hash_entry *h;
+ Elf_Internal_Sym *sym;
+ bfd_vma val;
+
+ r_type = ELF64_R_TYPE (rel->r_info);
+ switch (r_type)
+ {
+ default:
+ continue;
+
+ case R_PPC64_TOC16:
+ case R_PPC64_TOC16_LO:
+ case R_PPC64_TOC16_HI:
+ case R_PPC64_TOC16_HA:
+ case R_PPC64_TOC16_DS:
+ case R_PPC64_TOC16_LO_DS:
+ break;
+ }
+
+ r_symndx = ELF64_R_SYM (rel->r_info);
+ if (!get_sym_h (&h, &sym, &sym_sec, NULL, &local_syms,
+ r_symndx, ibfd))
+ goto error_ret;
+
+ if (sym_sec != toc)
+ continue;
+
+ if (h != NULL)
+ val = h->root.u.def.value;
+ else
+ val = sym->st_value;
+ val += rel->r_addend;
+
+ if (val >= toc->size)
+ continue;
+
+ /* Anything in the toc ought to be aligned to 8 bytes.
+ If not, don't mark as unused. */
+ if (val & 7)
+ continue;
+
+ if (skip == NULL)
+ {
+ skip = bfd_zmalloc (sizeof (*skip) * (toc->size + 15) / 8);
+ if (skip == NULL)
+ goto error_ret;
+ }
+
+ skip[val >> 3] = ref_from_discarded;
+ }
+
+ if (elf_section_data (sec)->relocs != relstart)
+ free (relstart);
+ }
+
+ /* For largetoc loads of address constants, we can convert
+ . addis rx,2,addr@got@ha
+ . ld ry,addr@got@l(rx)
+ to
+ . addis rx,2,addr@toc@ha
+ . addi ry,rx,addr@toc@l
+ when addr is within 2G of the toc pointer. This then means
+ that the word storing "addr" in the toc is no longer needed. */
+
+ if (!ppc64_elf_tdata (ibfd)->has_small_toc_reloc
+ && toc->output_section->rawsize < (bfd_vma) 1 << 31
+ && toc->reloc_count != 0)
+ {
+ /* Read toc relocs. */
+ toc_relocs = _bfd_elf_link_read_relocs (ibfd, toc, NULL, NULL,
+ info->keep_memory);
+ if (toc_relocs == NULL)
+ goto error_ret;
+
+ for (rel = toc_relocs; rel < toc_relocs + toc->reloc_count; ++rel)
+ {
+ enum elf_ppc64_reloc_type r_type;
+ unsigned long r_symndx;
+ asection *sym_sec;
+ struct elf_link_hash_entry *h;
+ Elf_Internal_Sym *sym;
+ bfd_vma val, addr;
+
+ r_type = ELF64_R_TYPE (rel->r_info);
+ if (r_type != R_PPC64_ADDR64)
+ continue;
+
+ r_symndx = ELF64_R_SYM (rel->r_info);
+ if (!get_sym_h (&h, &sym, &sym_sec, NULL, &local_syms,
+ r_symndx, ibfd))
+ goto error_ret;
+
+ if (sym_sec == NULL
+ || discarded_section (sym_sec))
+ continue;
+
+ if (!SYMBOL_REFERENCES_LOCAL (info, h))
+ continue;
+
+ if (h != NULL)
+ {
+ if (h->type == STT_GNU_IFUNC)
+ continue;
+ val = h->root.u.def.value;
+ }
+ else
+ {
+ if (ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC)
+ continue;
+ val = sym->st_value;
+ }
+ val += rel->r_addend;
+ val += sym_sec->output_section->vma + sym_sec->output_offset;
+
+ /* We don't yet know the exact toc pointer value, but we
+ know it will be somewhere in the toc section. Don't
+ optimize if the difference from any possible toc
+ pointer is outside [ff..f80008000, 7fff7fff]. */
+ addr = toc->output_section->vma + TOC_BASE_OFF;
+ if (val - addr + (bfd_vma) 0x80008000 >= (bfd_vma) 1 << 32)
+ continue;
+
+ addr = toc->output_section->vma + toc->output_section->rawsize;
+ if (val - addr + (bfd_vma) 0x80008000 >= (bfd_vma) 1 << 32)
+ continue;
+
+ if (skip == NULL)
+ {
+ skip = bfd_zmalloc (sizeof (*skip) * (toc->size + 15) / 8);
+ if (skip == NULL)
+ goto error_ret;
+ }
+
+ skip[rel->r_offset >> 3]
+ |= can_optimize | ((rel - toc_relocs) << 2);
+ }
+ }
+
+ if (skip == NULL)
+ continue;
+
+ used = bfd_zmalloc (sizeof (*used) * (toc->size + 7) / 8);
+ if (used == NULL)
+ {
+ error_ret:
+ if (local_syms != NULL
+ && symtab_hdr->contents != (unsigned char *) local_syms)
+ free (local_syms);
+ if (sec != NULL
+ && relstart != NULL
+ && elf_section_data (sec)->relocs != relstart)
+ free (relstart);
+ if (toc_relocs != NULL
+ && elf_section_data (toc)->relocs != toc_relocs)
+ free (toc_relocs);
+ if (skip != NULL)
+ free (skip);
+ return FALSE;
+ }
+
+ /* Now check all kept sections that might reference the toc.
+ Check the toc itself last. */
+ for (sec = (ibfd->sections == toc && toc->next ? toc->next
+ : ibfd->sections);
+ sec != NULL;
+ sec = (sec == toc ? NULL
+ : sec->next == NULL ? toc
+ : sec->next == toc && toc->next ? toc->next
+ : sec->next))
+ {
+ int repeat;
+
+ if (sec->reloc_count == 0
+ || discarded_section (sec)
+ || get_opd_info (sec)
+ || (sec->flags & SEC_ALLOC) == 0
+ || (sec->flags & SEC_DEBUGGING) != 0)
+ continue;
+
+ relstart = _bfd_elf_link_read_relocs (ibfd, sec, NULL, NULL,
+ info->keep_memory);
+ if (relstart == NULL)
+ {
+ free (used);
+ goto error_ret;
+ }
+
+ /* Mark toc entries referenced as used. */
+ do
+ {
+ repeat = 0;
+ for (rel = relstart; rel < relstart + sec->reloc_count; ++rel)
+ {
+ enum elf_ppc64_reloc_type r_type;
+ unsigned long r_symndx;
+ asection *sym_sec;
+ struct elf_link_hash_entry *h;
+ Elf_Internal_Sym *sym;
+ bfd_vma val;
+ enum {no_check, check_lo, check_ha} insn_check;
+
+ r_type = ELF64_R_TYPE (rel->r_info);
+ switch (r_type)
+ {
+ default:
+ insn_check = no_check;
+ break;
+
+ case R_PPC64_GOT_TLSLD16_HA:
+ case R_PPC64_GOT_TLSGD16_HA:
+ case R_PPC64_GOT_TPREL16_HA:
+ case R_PPC64_GOT_DTPREL16_HA:
+ case R_PPC64_GOT16_HA:
+ case R_PPC64_TOC16_HA:
+ insn_check = check_ha;
+ break;
+
+ case R_PPC64_GOT_TLSLD16_LO:
+ case R_PPC64_GOT_TLSGD16_LO:
+ case R_PPC64_GOT_TPREL16_LO_DS:
+ case R_PPC64_GOT_DTPREL16_LO_DS:
+ case R_PPC64_GOT16_LO:
+ case R_PPC64_GOT16_LO_DS:
+ case R_PPC64_TOC16_LO:
+ case R_PPC64_TOC16_LO_DS:
+ insn_check = check_lo;
+ break;
+ }
+
+ if (insn_check != no_check)
+ {
+ bfd_vma off = rel->r_offset & ~3;
+ unsigned char buf[4];
+ unsigned int insn;
+
+ if (!bfd_get_section_contents (ibfd, sec, buf, off, 4))
+ {
+ free (used);
+ goto error_ret;
+ }
+ insn = bfd_get_32 (ibfd, buf);
+ if (insn_check == check_lo
+ ? !ok_lo_toc_insn (insn)
+ : ((insn & ((0x3f << 26) | 0x1f << 16))
+ != ((15u << 26) | (2 << 16)) /* addis rt,2,imm */))
+ {
+ char str[12];
+
+ ppc64_elf_tdata (ibfd)->unexpected_toc_insn = 1;
+ sprintf (str, "%#08x", insn);
+ info->callbacks->einfo
+ (_("%P: %H: toc optimization is not supported for"
+ " %s instruction.\n"),
+ ibfd, sec, rel->r_offset & ~3, str);
+ }
+ }
+
+ switch (r_type)
+ {
+ case R_PPC64_TOC16:
+ case R_PPC64_TOC16_LO:
+ case R_PPC64_TOC16_HI:
+ case R_PPC64_TOC16_HA:
+ case R_PPC64_TOC16_DS:
+ case R_PPC64_TOC16_LO_DS:
+ /* In case we're taking addresses of toc entries. */
+ case R_PPC64_ADDR64:
+ break;
+
+ default:
+ continue;
+ }
+
+ r_symndx = ELF64_R_SYM (rel->r_info);
+ if (!get_sym_h (&h, &sym, &sym_sec, NULL, &local_syms,
+ r_symndx, ibfd))
+ {
+ free (used);
+ goto error_ret;
+ }
+
+ if (sym_sec != toc)
+ continue;
+
+ if (h != NULL)
+ val = h->root.u.def.value;
+ else
+ val = sym->st_value;
+ val += rel->r_addend;
+
+ if (val >= toc->size)
+ continue;
+
+ if ((skip[val >> 3] & can_optimize) != 0)
+ {
+ bfd_vma off;
+ unsigned char opc;
+
+ switch (r_type)
+ {
+ case R_PPC64_TOC16_HA:
+ break;
+
+ case R_PPC64_TOC16_LO_DS:
+ off = rel->r_offset;
+ off += (bfd_big_endian (ibfd) ? -2 : 3);
+ if (!bfd_get_section_contents (ibfd, sec, &opc,
+ off, 1))
+ {
+ free (used);
+ goto error_ret;
+ }
+ if ((opc & (0x3f << 2)) == (58u << 2))
+ break;
+ /* Fall thru */
+
+ default:
+ /* Wrong sort of reloc, or not a ld. We may
+ as well clear ref_from_discarded too. */
+ skip[val >> 3] = 0;
+ }
+ }
+
+ if (sec != toc)
+ used[val >> 3] = 1;
+ /* For the toc section, we only mark as used if this
+ entry itself isn't unused. */
+ else if ((used[rel->r_offset >> 3]
+ || !(skip[rel->r_offset >> 3] & ref_from_discarded))
+ && !used[val >> 3])
+ {
+ /* Do all the relocs again, to catch reference
+ chains. */
+ repeat = 1;
+ used[val >> 3] = 1;
+ }
+ }
+ }
+ while (repeat);
+
+ if (elf_section_data (sec)->relocs != relstart)
+ free (relstart);
+ }
+
+ /* Merge the used and skip arrays. Assume that TOC
+ doublewords not appearing as either used or unused belong
+ to to an entry more than one doubleword in size. */
+ for (drop = skip, keep = used, last = 0, some_unused = 0;
+ drop < skip + (toc->size + 7) / 8;
+ ++drop, ++keep)
+ {
+ if (*keep)
+ {
+ *drop &= ~ref_from_discarded;
+ if ((*drop & can_optimize) != 0)
+ some_unused = 1;
+ last = 0;
+ }
+ else if ((*drop & ref_from_discarded) != 0)
+ {
+ some_unused = 1;
+ last = ref_from_discarded;
+ }
+ else
+ *drop = last;
+ }
+
+ free (used);
+
+ if (some_unused)
+ {
+ bfd_byte *contents, *src;
+ unsigned long off;
+ Elf_Internal_Sym *sym;
+ bfd_boolean local_toc_syms = FALSE;
+
+ /* Shuffle the toc contents, and at the same time convert the
+ skip array from booleans into offsets. */
+ if (!bfd_malloc_and_get_section (ibfd, toc, &contents))
+ goto error_ret;
+
+ elf_section_data (toc)->this_hdr.contents = contents;
+
+ for (src = contents, off = 0, drop = skip;
+ src < contents + toc->size;
+ src += 8, ++drop)
+ {
+ if ((*drop & (can_optimize | ref_from_discarded)) != 0)
+ off += 8;
+ else if (off != 0)
+ {
+ *drop = off;
+ memcpy (src - off, src, 8);
+ }
+ }
+ *drop = off;
+ toc->rawsize = toc->size;
+ toc->size = src - contents - off;
+
+ /* Adjust addends for relocs against the toc section sym,
+ and optimize any accesses we can. */
+ for (sec = ibfd->sections; sec != NULL; sec = sec->next)
+ {
+ if (sec->reloc_count == 0
+ || discarded_section (sec))
+ continue;
+
+ relstart = _bfd_elf_link_read_relocs (ibfd, sec, NULL, NULL,
+ info->keep_memory);
+ if (relstart == NULL)
+ goto error_ret;
+
+ for (rel = relstart; rel < relstart + sec->reloc_count; ++rel)
+ {
+ enum elf_ppc64_reloc_type r_type;
+ unsigned long r_symndx;
+ asection *sym_sec;
+ struct elf_link_hash_entry *h;
+ bfd_vma val;
+
+ r_type = ELF64_R_TYPE (rel->r_info);
+ switch (r_type)
+ {
+ default:
+ continue;
+
+ case R_PPC64_TOC16:
+ case R_PPC64_TOC16_LO:
+ case R_PPC64_TOC16_HI:
+ case R_PPC64_TOC16_HA:
+ case R_PPC64_TOC16_DS:
+ case R_PPC64_TOC16_LO_DS:
+ case R_PPC64_ADDR64:
+ break;
+ }
+
+ r_symndx = ELF64_R_SYM (rel->r_info);
+ if (!get_sym_h (&h, &sym, &sym_sec, NULL, &local_syms,
+ r_symndx, ibfd))
+ goto error_ret;
+
+ if (sym_sec != toc)
+ continue;
+
+ if (h != NULL)
+ val = h->root.u.def.value;
+ else
+ {
+ val = sym->st_value;
+ if (val != 0)
+ local_toc_syms = TRUE;
+ }
+
+ val += rel->r_addend;
+
+ if (val > toc->rawsize)
+ val = toc->rawsize;
+ else if ((skip[val >> 3] & ref_from_discarded) != 0)
+ continue;
+ else if ((skip[val >> 3] & can_optimize) != 0)
+ {
+ Elf_Internal_Rela *tocrel
+ = toc_relocs + (skip[val >> 3] >> 2);
+ unsigned long tsym = ELF64_R_SYM (tocrel->r_info);
+
+ switch (r_type)
+ {
+ case R_PPC64_TOC16_HA:
+ rel->r_info = ELF64_R_INFO (tsym, R_PPC64_TOC16_HA);
+ break;
+
+ case R_PPC64_TOC16_LO_DS:
+ rel->r_info = ELF64_R_INFO (tsym, R_PPC64_LO_DS_OPT);
+ break;
+
+ default:
+ if (!ppc64_elf_howto_table[R_PPC64_ADDR32])
+ ppc_howto_init ();
+ info->callbacks->einfo
+ (_("%P: %H: %s references "
+ "optimized away TOC entry\n"),
+ ibfd, sec, rel->r_offset,
+ ppc64_elf_howto_table[r_type]->name);
+ bfd_set_error (bfd_error_bad_value);
+ goto error_ret;
+ }
+ rel->r_addend = tocrel->r_addend;
+ elf_section_data (sec)->relocs = relstart;
+ continue;
+ }
+
+ if (h != NULL || sym->st_value != 0)
+ continue;
+
+ rel->r_addend -= skip[val >> 3];
+ elf_section_data (sec)->relocs = relstart;
+ }
+
+ if (elf_section_data (sec)->relocs != relstart)
+ free (relstart);
+ }
+
+ /* We shouldn't have local or global symbols defined in the TOC,
+ but handle them anyway. */
+ if (local_syms != NULL)
+ for (sym = local_syms;
+ sym < local_syms + symtab_hdr->sh_info;
+ ++sym)
+ if (sym->st_value != 0
+ && bfd_section_from_elf_index (ibfd, sym->st_shndx) == toc)
+ {
+ unsigned long i;
+
+ if (sym->st_value > toc->rawsize)
+ i = toc->rawsize >> 3;
+ else
+ i = sym->st_value >> 3;
+
+ if ((skip[i] & (ref_from_discarded | can_optimize)) != 0)
+ {
+ if (local_toc_syms)
+ (*_bfd_error_handler)
+ (_("%s defined on removed toc entry"),
+ bfd_elf_sym_name (ibfd, symtab_hdr, sym, NULL));
+ do
+ ++i;
+ while ((skip[i] & (ref_from_discarded | can_optimize)));
+ sym->st_value = (bfd_vma) i << 3;
+ }
+
+ sym->st_value -= skip[i];
+ symtab_hdr->contents = (unsigned char *) local_syms;
+ }
+
+ /* Adjust any global syms defined in this toc input section. */
+ if (toc_inf.global_toc_syms)
+ {
+ toc_inf.toc = toc;
+ toc_inf.skip = skip;
+ toc_inf.global_toc_syms = FALSE;
+ elf_link_hash_traverse (elf_hash_table (info), adjust_toc_syms,
+ &toc_inf);
+ }
+
+ if (toc->reloc_count != 0)
+ {
+ Elf_Internal_Shdr *rel_hdr;
+ Elf_Internal_Rela *wrel;
+ bfd_size_type sz;
+
+ /* Remove unused toc relocs, and adjust those we keep. */
+ if (toc_relocs == NULL)
+ toc_relocs = _bfd_elf_link_read_relocs (ibfd, toc, NULL, NULL,
+ info->keep_memory);
+ if (toc_relocs == NULL)
+ goto error_ret;
+
+ wrel = toc_relocs;
+ for (rel = toc_relocs; rel < toc_relocs + toc->reloc_count; ++rel)
+ if ((skip[rel->r_offset >> 3]
+ & (ref_from_discarded | can_optimize)) == 0)
+ {
+ wrel->r_offset = rel->r_offset - skip[rel->r_offset >> 3];
+ wrel->r_info = rel->r_info;
+ wrel->r_addend = rel->r_addend;
+ ++wrel;
+ }
+ else if (!dec_dynrel_count (rel->r_info, toc, info,
+ &local_syms, NULL, NULL))
+ goto error_ret;
+
+ elf_section_data (toc)->relocs = toc_relocs;
+ toc->reloc_count = wrel - toc_relocs;
+ rel_hdr = _bfd_elf_single_rel_hdr (toc);
+ sz = rel_hdr->sh_entsize;
+ rel_hdr->sh_size = toc->reloc_count * sz;
+ }
+ }
+ else if (toc_relocs != NULL
+ && elf_section_data (toc)->relocs != toc_relocs)
+ free (toc_relocs);
+
+ if (local_syms != NULL
+ && symtab_hdr->contents != (unsigned char *) local_syms)
+ {
+ if (!info->keep_memory)
+ free (local_syms);
+ else
+ symtab_hdr->contents = (unsigned char *) local_syms;
+ }
+ free (skip);
+ }
+
+ return TRUE;
+}
+
+/* Return true iff input section I references the TOC using
+ instructions limited to +/-32k offsets. */
+
+bfd_boolean
+ppc64_elf_has_small_toc_reloc (asection *i)
+{
+ return (is_ppc64_elf (i->owner)
+ && ppc64_elf_tdata (i->owner)->has_small_toc_reloc);
+}
+
+/* Allocate space for one GOT entry. */
+
+static void
+allocate_got (struct elf_link_hash_entry *h,
+ struct bfd_link_info *info,
+ struct got_entry *gent)
+{
+ struct ppc_link_hash_table *htab = ppc_hash_table (info);
+ bfd_boolean dyn;
+ struct ppc_link_hash_entry *eh = (struct ppc_link_hash_entry *) h;
+ int entsize = (gent->tls_type & eh->tls_mask & (TLS_GD | TLS_LD)
+ ? 16 : 8);
+ int rentsize = (gent->tls_type & eh->tls_mask & TLS_GD
+ ? 2 : 1) * sizeof (Elf64_External_Rela);
+ asection *got = ppc64_elf_tdata (gent->owner)->got;
+
+ gent->got.offset = got->size;
+ got->size += entsize;
+
+ dyn = htab->elf.dynamic_sections_created;
+ if (h->type == STT_GNU_IFUNC)
+ {
+ htab->elf.irelplt->size += rentsize;
+ htab->got_reli_size += rentsize;
+ }
+ else if ((info->shared
+ || WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, 0, h))
+ && (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
+ || h->root.type != bfd_link_hash_undefweak))
+ {
+ asection *relgot = ppc64_elf_tdata (gent->owner)->relgot;
+ relgot->size += rentsize;
+ }
+}
+
+/* This function merges got entries in the same toc group. */
+
+static void
+merge_got_entries (struct got_entry **pent)
+{
+ struct got_entry *ent, *ent2;
+
+ for (ent = *pent; ent != NULL; ent = ent->next)
+ if (!ent->is_indirect)
+ for (ent2 = ent->next; ent2 != NULL; ent2 = ent2->next)
+ if (!ent2->is_indirect
+ && ent2->addend == ent->addend
+ && ent2->tls_type == ent->tls_type
+ && elf_gp (ent2->owner) == elf_gp (ent->owner))
+ {
+ ent2->is_indirect = TRUE;
+ ent2->got.ent = ent;
+ }
+}
+
+/* Allocate space in .plt, .got and associated reloc sections for
+ dynamic relocs. */
+
+static bfd_boolean
+allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
+{
+ struct bfd_link_info *info;
+ struct ppc_link_hash_table *htab;
+ asection *s;
+ struct ppc_link_hash_entry *eh;
+ struct elf_dyn_relocs *p;
+ struct got_entry **pgent, *gent;
+
+ if (h->root.type == bfd_link_hash_indirect)
+ return TRUE;
+
+ info = (struct bfd_link_info *) inf;
+ htab = ppc_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ if ((htab->elf.dynamic_sections_created
+ && h->dynindx != -1
+ && WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, info->shared, h))
+ || h->type == STT_GNU_IFUNC)
+ {
+ struct plt_entry *pent;
+ bfd_boolean doneone = FALSE;
+ for (pent = h->plt.plist; pent != NULL; pent = pent->next)
+ if (pent->plt.refcount > 0)
+ {
+ if (!htab->elf.dynamic_sections_created
+ || h->dynindx == -1)
+ {
+ s = htab->elf.iplt;
+ pent->plt.offset = s->size;
+ s->size += PLT_ENTRY_SIZE (htab);
+ s = htab->elf.irelplt;
+ }
+ else
+ {
+ /* If this is the first .plt entry, make room for the special
+ first entry. */
+ s = htab->elf.splt;
+ if (s->size == 0)
+ s->size += PLT_INITIAL_ENTRY_SIZE (htab);
+
+ pent->plt.offset = s->size;
+
+ /* Make room for this entry. */
+ s->size += PLT_ENTRY_SIZE (htab);
+
+ /* Make room for the .glink code. */
+ s = htab->glink;
+ if (s->size == 0)
+ s->size += GLINK_CALL_STUB_SIZE;
+ if (htab->opd_abi)
+ {
+ /* We need bigger stubs past index 32767. */
+ if (s->size >= GLINK_CALL_STUB_SIZE + 32768*2*4)
+ s->size += 4;
+ s->size += 2*4;
+ }
+ else
+ s->size += 4;
+
+ /* We also need to make an entry in the .rela.plt section. */
+ s = htab->elf.srelplt;
+ }
+ s->size += sizeof (Elf64_External_Rela);
+ doneone = TRUE;
+ }
+ else
+ pent->plt.offset = (bfd_vma) -1;
+ if (!doneone)
+ {
+ h->plt.plist = NULL;
+ h->needs_plt = 0;
+ }
+ }
+ else
+ {
+ h->plt.plist = NULL;
+ h->needs_plt = 0;
+ }
+
+ eh = (struct ppc_link_hash_entry *) h;
+ /* Run through the TLS GD got entries first if we're changing them
+ to TPREL. */
+ if ((eh->tls_mask & TLS_TPRELGD) != 0)
+ for (gent = h->got.glist; gent != NULL; gent = gent->next)
+ if (gent->got.refcount > 0
+ && (gent->tls_type & TLS_GD) != 0)
+ {
+ /* This was a GD entry that has been converted to TPREL. If
+ there happens to be a TPREL entry we can use that one. */
+ struct got_entry *ent;
+ for (ent = h->got.glist; ent != NULL; ent = ent->next)
+ if (ent->got.refcount > 0
+ && (ent->tls_type & TLS_TPREL) != 0
+ && ent->addend == gent->addend
+ && ent->owner == gent->owner)
+ {
+ gent->got.refcount = 0;
+ break;
+ }
+
+ /* If not, then we'll be using our own TPREL entry. */
+ if (gent->got.refcount != 0)
+ gent->tls_type = TLS_TLS | TLS_TPREL;
+ }
+
+ /* Remove any list entry that won't generate a word in the GOT before
+ we call merge_got_entries. Otherwise we risk merging to empty
+ entries. */
+ pgent = &h->got.glist;
+ while ((gent = *pgent) != NULL)
+ if (gent->got.refcount > 0)
+ {
+ if ((gent->tls_type & TLS_LD) != 0
+ && !h->def_dynamic)
+ {
+ ppc64_tlsld_got (gent->owner)->got.refcount += 1;
+ *pgent = gent->next;
+ }
+ else
+ pgent = &gent->next;
+ }
+ else
+ *pgent = gent->next;
+
+ if (!htab->do_multi_toc)
+ merge_got_entries (&h->got.glist);
+
+ for (gent = h->got.glist; gent != NULL; gent = gent->next)
+ if (!gent->is_indirect)
+ {
+ /* Make sure this symbol is output as a dynamic symbol.
+ Undefined weak syms won't yet be marked as dynamic,
+ nor will all TLS symbols. */
+ if (h->dynindx == -1
+ && !h->forced_local
+ && h->type != STT_GNU_IFUNC
+ && htab->elf.dynamic_sections_created)
+ {
+ if (! bfd_elf_link_record_dynamic_symbol (info, h))
+ return FALSE;
+ }
+
+ if (!is_ppc64_elf (gent->owner))
+ abort ();
+
+ allocate_got (h, info, gent);
+ }
+
+ if (eh->dyn_relocs == NULL
+ || (!htab->elf.dynamic_sections_created
+ && h->type != STT_GNU_IFUNC))
+ return TRUE;
+
+ /* In the shared -Bsymbolic case, discard space allocated for
+ dynamic pc-relative relocs against symbols which turn out to be
+ defined in regular objects. For the normal shared case, discard
+ space for relocs that have become local due to symbol visibility
+ changes. */
+
+ if (info->shared)
+ {
+ /* Relocs that use pc_count are those that appear on a call insn,
+ or certain REL relocs (see must_be_dyn_reloc) that can be
+ generated via assembly. We want calls to protected symbols to
+ resolve directly to the function rather than going via the plt.
+ If people want function pointer comparisons to work as expected
+ then they should avoid writing weird assembly. */
+ if (SYMBOL_CALLS_LOCAL (info, h))
+ {
+ struct elf_dyn_relocs **pp;
+
+ for (pp = &eh->dyn_relocs; (p = *pp) != NULL; )
+ {
+ p->count -= p->pc_count;
+ p->pc_count = 0;
+ if (p->count == 0)
+ *pp = p->next;
+ else
+ pp = &p->next;
+ }
+ }
+
+ /* Also discard relocs on undefined weak syms with non-default
+ visibility. */
+ if (eh->dyn_relocs != NULL
+ && h->root.type == bfd_link_hash_undefweak)
+ {
+ if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
+ eh->dyn_relocs = NULL;
+
+ /* Make sure this symbol is output as a dynamic symbol.
+ Undefined weak syms won't yet be marked as dynamic. */
+ else if (h->dynindx == -1
+ && !h->forced_local)
+ {
+ if (! bfd_elf_link_record_dynamic_symbol (info, h))
+ return FALSE;
+ }
+ }
+ }
+ else if (h->type == STT_GNU_IFUNC)
+ {
+ if (!h->non_got_ref)
+ eh->dyn_relocs = NULL;
+ }
+ else if (ELIMINATE_COPY_RELOCS)
+ {
+ /* For the non-shared case, discard space for relocs against
+ symbols which turn out to need copy relocs or are not
+ dynamic. */
+
+ if (!h->non_got_ref
+ && !h->def_regular)
+ {
+ /* Make sure this symbol is output as a dynamic symbol.
+ Undefined weak syms won't yet be marked as dynamic. */
+ if (h->dynindx == -1
+ && !h->forced_local)
+ {
+ if (! bfd_elf_link_record_dynamic_symbol (info, h))
+ return FALSE;
+ }
+
+ /* If that succeeded, we know we'll be keeping all the
+ relocs. */
+ if (h->dynindx != -1)
+ goto keep;
+ }
+
+ eh->dyn_relocs = NULL;
+
+ keep: ;
+ }
+
+ /* Finally, allocate space. */
+ for (p = eh->dyn_relocs; p != NULL; p = p->next)
+ {
+ asection *sreloc = elf_section_data (p->sec)->sreloc;
+ if (eh->elf.type == STT_GNU_IFUNC)
+ sreloc = htab->elf.irelplt;
+ sreloc->size += p->count * sizeof (Elf64_External_Rela);
+ }
+
+ return TRUE;
+}
+
+/* Called via elf_link_hash_traverse from ppc64_elf_size_dynamic_sections
+ to set up space for global entry stubs. These are put in glink,
+ after the branch table. */
+
+static bfd_boolean
+size_global_entry_stubs (struct elf_link_hash_entry *h, void *inf)
+{
+ struct bfd_link_info *info;
+ struct ppc_link_hash_table *htab;
+ struct plt_entry *pent;
+ asection *s;
+
+ if (h->root.type == bfd_link_hash_indirect)
+ return TRUE;
+
+ if (!h->pointer_equality_needed)
+ return TRUE;
+
+ if (h->def_regular)
+ return TRUE;
+
+ info = inf;
+ htab = ppc_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ s = htab->glink;
+ for (pent = h->plt.plist; pent != NULL; pent = pent->next)
+ if (pent->plt.offset != (bfd_vma) -1
+ && pent->addend == 0)
+ {
+ /* For ELFv2, if this symbol is not defined in a regular file
+ and we are not generating a shared library or pie, then we
+ need to define the symbol in the executable on a call stub.
+ This is to avoid text relocations. */
+ s->size = (s->size + 15) & -16;
+ h->root.u.def.section = s;
+ h->root.u.def.value = s->size;
+ s->size += 16;
+ break;
+ }
+ return TRUE;
+}
+
+/* Set DF_TEXTREL if we find any dynamic relocs that apply to
+ read-only sections. */
+
+static bfd_boolean
+maybe_set_textrel (struct elf_link_hash_entry *h, void *info)
+{
+ if (h->root.type == bfd_link_hash_indirect)
+ return TRUE;
+
+ if (readonly_dynrelocs (h))
+ {
+ ((struct bfd_link_info *) info)->flags |= DF_TEXTREL;
+
+ /* Not an error, just cut short the traversal. */
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/* Set the sizes of the dynamic sections. */
+
+static bfd_boolean
+ppc64_elf_size_dynamic_sections (bfd *output_bfd,
+ struct bfd_link_info *info)
+{
+ struct ppc_link_hash_table *htab;
+ bfd *dynobj;
+ asection *s;
+ bfd_boolean relocs;
+ bfd *ibfd;
+ struct got_entry *first_tlsld;
+
+ htab = ppc_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ dynobj = htab->elf.dynobj;
+ if (dynobj == NULL)
+ abort ();
+
+ if (htab->elf.dynamic_sections_created)
+ {
+ /* Set the contents of the .interp section to the interpreter. */
+ if (info->executable)
+ {
+ s = bfd_get_linker_section (dynobj, ".interp");
+ if (s == NULL)
+ abort ();
+ s->size = sizeof ELF_DYNAMIC_INTERPRETER;
+ s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
+ }
+ }
+
+ /* Set up .got offsets for local syms, and space for local dynamic
+ relocs. */
+ for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next)
+ {
+ struct got_entry **lgot_ents;
+ struct got_entry **end_lgot_ents;
+ struct plt_entry **local_plt;
+ struct plt_entry **end_local_plt;
+ unsigned char *lgot_masks;
+ bfd_size_type locsymcount;
+ Elf_Internal_Shdr *symtab_hdr;
+
+ if (!is_ppc64_elf (ibfd))
+ continue;
+
+ for (s = ibfd->sections; s != NULL; s = s->next)
+ {
+ struct ppc_dyn_relocs *p;
+
+ for (p = elf_section_data (s)->local_dynrel; p != NULL; p = p->next)
+ {
+ if (!bfd_is_abs_section (p->sec)
+ && bfd_is_abs_section (p->sec->output_section))
+ {
+ /* Input section has been discarded, either because
+ it is a copy of a linkonce section or due to
+ linker script /DISCARD/, so we'll be discarding
+ the relocs too. */
+ }
+ else if (p->count != 0)
+ {
+ asection *srel = elf_section_data (p->sec)->sreloc;
+ if (p->ifunc)
+ srel = htab->elf.irelplt;
+ srel->size += p->count * sizeof (Elf64_External_Rela);
+ if ((p->sec->output_section->flags & SEC_READONLY) != 0)
+ info->flags |= DF_TEXTREL;
+ }
+ }
+ }
+
+ lgot_ents = elf_local_got_ents (ibfd);
+ if (!lgot_ents)
+ continue;
+
+ symtab_hdr = &elf_symtab_hdr (ibfd);
+ locsymcount = symtab_hdr->sh_info;
+ end_lgot_ents = lgot_ents + locsymcount;
+ local_plt = (struct plt_entry **) end_lgot_ents;
+ end_local_plt = local_plt + locsymcount;
+ lgot_masks = (unsigned char *) end_local_plt;
+ s = ppc64_elf_tdata (ibfd)->got;
+ for (; lgot_ents < end_lgot_ents; ++lgot_ents, ++lgot_masks)
+ {
+ struct got_entry **pent, *ent;
+
+ pent = lgot_ents;
+ while ((ent = *pent) != NULL)
+ if (ent->got.refcount > 0)
+ {
+ if ((ent->tls_type & *lgot_masks & TLS_LD) != 0)
+ {
+ ppc64_tlsld_got (ibfd)->got.refcount += 1;
+ *pent = ent->next;
+ }
+ else
+ {
+ unsigned int ent_size = 8;
+ unsigned int rel_size = sizeof (Elf64_External_Rela);
+
+ ent->got.offset = s->size;
+ if ((ent->tls_type & *lgot_masks & TLS_GD) != 0)
+ {
+ ent_size *= 2;
+ rel_size *= 2;
+ }
+ s->size += ent_size;
+ if ((*lgot_masks & PLT_IFUNC) != 0)
+ {
+ htab->elf.irelplt->size += rel_size;
+ htab->got_reli_size += rel_size;
+ }
+ else if (info->shared)
+ {
+ asection *srel = ppc64_elf_tdata (ibfd)->relgot;
+ srel->size += rel_size;
+ }
+ pent = &ent->next;
+ }
+ }
+ else
+ *pent = ent->next;
+ }
+
+ /* Allocate space for calls to local STT_GNU_IFUNC syms in .iplt. */
+ for (; local_plt < end_local_plt; ++local_plt)
+ {
+ struct plt_entry *ent;
+
+ for (ent = *local_plt; ent != NULL; ent = ent->next)
+ if (ent->plt.refcount > 0)
+ {
+ s = htab->elf.iplt;
+ ent->plt.offset = s->size;
+ s->size += PLT_ENTRY_SIZE (htab);
+
+ htab->elf.irelplt->size += sizeof (Elf64_External_Rela);
+ }
+ else
+ ent->plt.offset = (bfd_vma) -1;
+ }
+ }
+
+ /* Allocate global sym .plt and .got entries, and space for global
+ sym dynamic relocs. */
+ elf_link_hash_traverse (&htab->elf, allocate_dynrelocs, info);
+ /* Stash the end of glink branch table. */
+ if (htab->glink != NULL)
+ htab->glink->rawsize = htab->glink->size;
+
+ if (!htab->opd_abi && !info->shared)
+ elf_link_hash_traverse (&htab->elf, size_global_entry_stubs, info);
+
+ first_tlsld = NULL;
+ for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next)
+ {
+ struct got_entry *ent;
+
+ if (!is_ppc64_elf (ibfd))
+ continue;
+
+ ent = ppc64_tlsld_got (ibfd);
+ if (ent->got.refcount > 0)
+ {
+ if (!htab->do_multi_toc && first_tlsld != NULL)
+ {
+ ent->is_indirect = TRUE;
+ ent->got.ent = first_tlsld;
+ }
+ else
+ {
+ if (first_tlsld == NULL)
+ first_tlsld = ent;
+ s = ppc64_elf_tdata (ibfd)->got;
+ ent->got.offset = s->size;
+ ent->owner = ibfd;
+ s->size += 16;
+ if (info->shared)
+ {
+ asection *srel = ppc64_elf_tdata (ibfd)->relgot;
+ srel->size += sizeof (Elf64_External_Rela);
+ }
+ }
+ }
+ else
+ ent->got.offset = (bfd_vma) -1;
+ }
+
+ /* We now have determined the sizes of the various dynamic sections.
+ Allocate memory for them. */
+ relocs = FALSE;
+ for (s = dynobj->sections; s != NULL; s = s->next)
+ {
+ if ((s->flags & SEC_LINKER_CREATED) == 0)
+ continue;
+
+ if (s == htab->brlt || s == htab->relbrlt)
+ /* These haven't been allocated yet; don't strip. */
+ continue;
+ else if (s == htab->elf.sgot
+ || s == htab->elf.splt
+ || s == htab->elf.iplt
+ || s == htab->glink
+ || s == htab->dynbss)
+ {
+ /* Strip this section if we don't need it; see the
+ comment below. */
+ }
+ else if (s == htab->glink_eh_frame)
+ {
+ if (!bfd_is_abs_section (s->output_section))
+ /* Not sized yet. */
+ continue;
+ }
+ else if (CONST_STRNEQ (s->name, ".rela"))
+ {
+ if (s->size != 0)
+ {
+ if (s != htab->elf.srelplt)
+ relocs = 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
+ {
+ /* It's not one of our sections, so don't allocate space. */
+ continue;
+ }
+
+ if (s->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. */
+ s->flags |= SEC_EXCLUDE;
+ continue;
+ }
+
+ if ((s->flags & SEC_HAS_CONTENTS) == 0)
+ continue;
+
+ /* Allocate memory for the section contents. We use bfd_zalloc
+ here in case unused entries are not reclaimed before the
+ section's contents are written out. This should not happen,
+ but this way if it does we get a R_PPC64_NONE reloc in .rela
+ sections instead of garbage.
+ We also rely on the section contents being zero when writing
+ the GOT. */
+ s->contents = bfd_zalloc (dynobj, s->size);
+ if (s->contents == NULL)
+ return FALSE;
+ }
+
+ for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next)
+ {
+ if (!is_ppc64_elf (ibfd))
+ continue;
+
+ s = ppc64_elf_tdata (ibfd)->got;
+ if (s != NULL && s != htab->elf.sgot)
+ {
+ if (s->size == 0)
+ s->flags |= SEC_EXCLUDE;
+ else
+ {
+ s->contents = bfd_zalloc (ibfd, s->size);
+ if (s->contents == NULL)
+ return FALSE;
+ }
+ }
+ s = ppc64_elf_tdata (ibfd)->relgot;
+ if (s != NULL)
+ {
+ if (s->size == 0)
+ s->flags |= SEC_EXCLUDE;
+ else
+ {
+ s->contents = bfd_zalloc (ibfd, s->size);
+ if (s->contents == NULL)
+ return FALSE;
+ relocs = TRUE;
+ s->reloc_count = 0;
+ }
+ }
+ }
+
+ if (htab->elf.dynamic_sections_created)
+ {
+ bfd_boolean tls_opt;
+
+ /* Add some entries to the .dynamic section. We fill in the
+ values later, in ppc64_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. */
+#define add_dynamic_entry(TAG, VAL) \
+ _bfd_elf_add_dynamic_entry (info, TAG, VAL)
+
+ if (info->executable)
+ {
+ if (!add_dynamic_entry (DT_DEBUG, 0))
+ return FALSE;
+ }
+
+ if (htab->elf.splt != NULL && htab->elf.splt->size != 0)
+ {
+ if (!add_dynamic_entry (DT_PLTGOT, 0)
+ || !add_dynamic_entry (DT_PLTRELSZ, 0)
+ || !add_dynamic_entry (DT_PLTREL, DT_RELA)
+ || !add_dynamic_entry (DT_JMPREL, 0)
+ || !add_dynamic_entry (DT_PPC64_GLINK, 0))
+ return FALSE;
+ }
+
+ if (NO_OPD_RELOCS && abiversion (output_bfd) <= 1)
+ {
+ if (!add_dynamic_entry (DT_PPC64_OPD, 0)
+ || !add_dynamic_entry (DT_PPC64_OPDSZ, 0))
+ return FALSE;
+ }
+
+ tls_opt = (!htab->params->no_tls_get_addr_opt
+ && htab->tls_get_addr_fd != NULL
+ && htab->tls_get_addr_fd->elf.plt.plist != NULL);
+ if (tls_opt || !htab->opd_abi)
+ {
+ if (!add_dynamic_entry (DT_PPC64_OPT, tls_opt ? PPC64_OPT_TLS : 0))
+ return FALSE;
+ }
+
+ if (relocs)
+ {
+ if (!add_dynamic_entry (DT_RELA, 0)
+ || !add_dynamic_entry (DT_RELASZ, 0)
+ || !add_dynamic_entry (DT_RELAENT, sizeof (Elf64_External_Rela)))
+ return FALSE;
+
+ /* If any dynamic relocs apply to a read-only section,
+ then we need a DT_TEXTREL entry. */
+ if ((info->flags & DF_TEXTREL) == 0)
+ elf_link_hash_traverse (&htab->elf, maybe_set_textrel, info);
+
+ if ((info->flags & DF_TEXTREL) != 0)
+ {
+ if (!add_dynamic_entry (DT_TEXTREL, 0))
+ return FALSE;
+ }
+ }
+ }
+#undef add_dynamic_entry
+
+ return TRUE;
+}
+
+/* Return TRUE if symbol should be hashed in the `.gnu.hash' section. */
+
+static bfd_boolean
+ppc64_elf_hash_symbol (struct elf_link_hash_entry *h)
+{
+ if (h->plt.plist != NULL
+ && !h->def_regular
+ && !h->pointer_equality_needed)
+ return FALSE;
+
+ return _bfd_elf_hash_symbol (h);
+}
+
+/* Determine the type of stub needed, if any, for a call. */
+
+static inline enum ppc_stub_type
+ppc_type_of_stub (asection *input_sec,
+ const Elf_Internal_Rela *rel,
+ struct ppc_link_hash_entry **hash,
+ struct plt_entry **plt_ent,
+ bfd_vma destination,
+ unsigned long local_off)
+{
+ struct ppc_link_hash_entry *h = *hash;
+ bfd_vma location;
+ bfd_vma branch_offset;
+ bfd_vma max_branch_offset;
+ enum elf_ppc64_reloc_type r_type;
+
+ if (h != NULL)
+ {
+ struct plt_entry *ent;
+ struct ppc_link_hash_entry *fdh = h;
+ if (h->oh != NULL
+ && h->oh->is_func_descriptor)
+ {
+ fdh = ppc_follow_link (h->oh);
+ *hash = fdh;
+ }
+
+ for (ent = fdh->elf.plt.plist; ent != NULL; ent = ent->next)
+ if (ent->addend == rel->r_addend
+ && ent->plt.offset != (bfd_vma) -1)
+ {
+ *plt_ent = ent;
+ return ppc_stub_plt_call;
+ }
+
+ /* Here, we know we don't have a plt entry. If we don't have a
+ either a defined function descriptor or a defined entry symbol
+ in a regular object file, then it is pointless trying to make
+ any other type of stub. */
+ if (!is_static_defined (&fdh->elf)
+ && !is_static_defined (&h->elf))
+ return ppc_stub_none;
+ }
+ else if (elf_local_got_ents (input_sec->owner) != NULL)
+ {
+ Elf_Internal_Shdr *symtab_hdr = &elf_symtab_hdr (input_sec->owner);
+ struct plt_entry **local_plt = (struct plt_entry **)
+ elf_local_got_ents (input_sec->owner) + symtab_hdr->sh_info;
+ unsigned long r_symndx = ELF64_R_SYM (rel->r_info);
+
+ if (local_plt[r_symndx] != NULL)
+ {
+ struct plt_entry *ent;
+
+ for (ent = local_plt[r_symndx]; ent != NULL; ent = ent->next)
+ if (ent->addend == rel->r_addend
+ && ent->plt.offset != (bfd_vma) -1)
+ {
+ *plt_ent = ent;
+ return ppc_stub_plt_call;
+ }
+ }
+ }
+
+ /* Determine where the call point is. */
+ location = (input_sec->output_offset
+ + input_sec->output_section->vma
+ + rel->r_offset);
+
+ branch_offset = destination - location;
+ r_type = ELF64_R_TYPE (rel->r_info);
+
+ /* Determine if a long branch stub is needed. */
+ max_branch_offset = 1 << 25;
+ if (r_type != R_PPC64_REL24)
+ max_branch_offset = 1 << 15;
+
+ if (branch_offset + max_branch_offset >= 2 * max_branch_offset - local_off)
+ /* We need a stub. Figure out whether a long_branch or plt_branch
+ is needed later. */
+ return ppc_stub_long_branch;
+
+ return ppc_stub_none;
+}
+
+/* With power7 weakly ordered memory model, it is possible for ld.so
+ to update a plt entry in one thread and have another thread see a
+ stale zero toc entry. To avoid this we need some sort of acquire
+ barrier in the call stub. One solution is to make the load of the
+ toc word seem to appear to depend on the load of the function entry
+ word. Another solution is to test for r2 being zero, and branch to
+ the appropriate glink entry if so.
+
+ . fake dep barrier compare
+ . ld 12,xxx(2) ld 12,xxx(2)
+ . mtctr 12 mtctr 12
+ . xor 11,12,12 ld 2,xxx+8(2)
+ . add 2,2,11 cmpldi 2,0
+ . ld 2,xxx+8(2) bnectr+
+ . bctr b <glink_entry>
+
+ The solution involving the compare turns out to be faster, so
+ that's what we use unless the branch won't reach. */
+
+#define ALWAYS_USE_FAKE_DEP 0
+#define ALWAYS_EMIT_R2SAVE 0
+
+#define PPC_LO(v) ((v) & 0xffff)
+#define PPC_HI(v) (((v) >> 16) & 0xffff)
+#define PPC_HA(v) PPC_HI ((v) + 0x8000)
+
+static inline unsigned int
+plt_stub_size (struct ppc_link_hash_table *htab,
+ struct ppc_stub_hash_entry *stub_entry,
+ bfd_vma off)
+{
+ unsigned size = 12;
+
+ if (ALWAYS_EMIT_R2SAVE
+ || stub_entry->stub_type == ppc_stub_plt_call_r2save)
+ size += 4;
+ if (PPC_HA (off) != 0)
+ size += 4;
+ if (htab->opd_abi)
+ {
+ size += 4;
+ if (htab->params->plt_static_chain)
+ size += 4;
+ if (htab->params->plt_thread_safe)
+ size += 8;
+ if (PPC_HA (off + 8 + 8 * htab->params->plt_static_chain) != PPC_HA (off))
+ size += 4;
+ }
+ if (stub_entry->h != NULL
+ && (stub_entry->h == htab->tls_get_addr_fd
+ || stub_entry->h == htab->tls_get_addr)
+ && !htab->params->no_tls_get_addr_opt)
+ size += 13 * 4;
+ return size;
+}
+
+/* If this stub would cross fewer 2**plt_stub_align boundaries if we align,
+ then return the padding needed to do so. */
+static inline unsigned int
+plt_stub_pad (struct ppc_link_hash_table *htab,
+ struct ppc_stub_hash_entry *stub_entry,
+ bfd_vma plt_off)
+{
+ int stub_align = 1 << htab->params->plt_stub_align;
+ unsigned stub_size = plt_stub_size (htab, stub_entry, plt_off);
+ bfd_vma stub_off = stub_entry->stub_sec->size;
+
+ if (((stub_off + stub_size - 1) & -stub_align) - (stub_off & -stub_align)
+ > ((stub_size - 1) & -stub_align))
+ return stub_align - (stub_off & (stub_align - 1));
+ return 0;
+}
+
+/* Build a .plt call stub. */
+
+static inline bfd_byte *
+build_plt_stub (struct ppc_link_hash_table *htab,
+ struct ppc_stub_hash_entry *stub_entry,
+ bfd_byte *p, bfd_vma offset, Elf_Internal_Rela *r)
+{
+ bfd *obfd = htab->params->stub_bfd;
+ bfd_boolean plt_load_toc = htab->opd_abi;
+ bfd_boolean plt_static_chain = htab->params->plt_static_chain;
+ bfd_boolean plt_thread_safe = htab->params->plt_thread_safe;
+ bfd_boolean use_fake_dep = plt_thread_safe;
+ bfd_vma cmp_branch_off = 0;
+
+ if (!ALWAYS_USE_FAKE_DEP
+ && plt_load_toc
+ && plt_thread_safe
+ && !(stub_entry->h != NULL
+ && (stub_entry->h == htab->tls_get_addr_fd
+ || stub_entry->h == htab->tls_get_addr)
+ && !htab->params->no_tls_get_addr_opt))
+ {
+ bfd_vma pltoff = stub_entry->plt_ent->plt.offset & ~1;
+ bfd_vma pltindex = ((pltoff - PLT_INITIAL_ENTRY_SIZE (htab))
+ / PLT_ENTRY_SIZE (htab));
+ bfd_vma glinkoff = GLINK_CALL_STUB_SIZE + pltindex * 8;
+ bfd_vma to, from;
+
+ if (pltindex > 32768)
+ glinkoff += (pltindex - 32768) * 4;
+ to = (glinkoff
+ + htab->glink->output_offset
+ + htab->glink->output_section->vma);
+ from = (p - stub_entry->stub_sec->contents
+ + 4 * (ALWAYS_EMIT_R2SAVE
+ || stub_entry->stub_type == ppc_stub_plt_call_r2save)
+ + 4 * (PPC_HA (offset) != 0)
+ + 4 * (PPC_HA (offset + 8 + 8 * plt_static_chain)
+ != PPC_HA (offset))
+ + 4 * (plt_static_chain != 0)
+ + 20
+ + stub_entry->stub_sec->output_offset
+ + stub_entry->stub_sec->output_section->vma);
+ cmp_branch_off = to - from;
+ use_fake_dep = cmp_branch_off + (1 << 25) >= (1 << 26);
+ }
+
+ if (PPC_HA (offset) != 0)
+ {
+ if (r != NULL)
+ {
+ if (ALWAYS_EMIT_R2SAVE
+ || stub_entry->stub_type == ppc_stub_plt_call_r2save)
+ r[0].r_offset += 4;
+ r[0].r_info = ELF64_R_INFO (0, R_PPC64_TOC16_HA);
+ r[1].r_offset = r[0].r_offset + 4;
+ r[1].r_info = ELF64_R_INFO (0, R_PPC64_TOC16_LO_DS);
+ r[1].r_addend = r[0].r_addend;
+ if (plt_load_toc)
+ {
+ if (PPC_HA (offset + 8 + 8 * plt_static_chain) != PPC_HA (offset))
+ {
+ r[2].r_offset = r[1].r_offset + 4;
+ r[2].r_info = ELF64_R_INFO (0, R_PPC64_TOC16_LO);
+ r[2].r_addend = r[0].r_addend;
+ }
+ else
+ {
+ r[2].r_offset = r[1].r_offset + 8 + 8 * use_fake_dep;
+ r[2].r_info = ELF64_R_INFO (0, R_PPC64_TOC16_LO_DS);
+ r[2].r_addend = r[0].r_addend + 8;
+ if (plt_static_chain)
+ {
+ r[3].r_offset = r[2].r_offset + 4;
+ r[3].r_info = ELF64_R_INFO (0, R_PPC64_TOC16_LO_DS);
+ r[3].r_addend = r[0].r_addend + 16;
+ }
+ }
+ }
+ }
+ if (ALWAYS_EMIT_R2SAVE
+ || stub_entry->stub_type == ppc_stub_plt_call_r2save)
+ bfd_put_32 (obfd, STD_R2_0R1 + STK_TOC (htab), p), p += 4;
+ if (plt_load_toc)
+ {
+ bfd_put_32 (obfd, ADDIS_R11_R2 | PPC_HA (offset), p), p += 4;
+ bfd_put_32 (obfd, LD_R12_0R11 | PPC_LO (offset), p), p += 4;
+ }
+ else
+ {
+ bfd_put_32 (obfd, ADDIS_R12_R2 | PPC_HA (offset), p), p += 4;
+ bfd_put_32 (obfd, LD_R12_0R12 | PPC_LO (offset), p), p += 4;
+ }
+ if (plt_load_toc
+ && PPC_HA (offset + 8 + 8 * plt_static_chain) != PPC_HA (offset))
+ {
+ bfd_put_32 (obfd, ADDI_R11_R11 | PPC_LO (offset), p), p += 4;
+ offset = 0;
+ }
+ bfd_put_32 (obfd, MTCTR_R12, p), p += 4;
+ if (plt_load_toc)
+ {
+ if (use_fake_dep)
+ {
+ bfd_put_32 (obfd, XOR_R2_R12_R12, p), p += 4;
+ bfd_put_32 (obfd, ADD_R11_R11_R2, p), p += 4;
+ }
+ bfd_put_32 (obfd, LD_R2_0R11 | PPC_LO (offset + 8), p), p += 4;
+ if (plt_static_chain)
+ bfd_put_32 (obfd, LD_R11_0R11 | PPC_LO (offset + 16), p), p += 4;
+ }
+ }
+ else
+ {
+ if (r != NULL)
+ {
+ if (ALWAYS_EMIT_R2SAVE
+ || stub_entry->stub_type == ppc_stub_plt_call_r2save)
+ r[0].r_offset += 4;
+ r[0].r_info = ELF64_R_INFO (0, R_PPC64_TOC16_DS);
+ if (plt_load_toc)
+ {
+ if (PPC_HA (offset + 8 + 8 * plt_static_chain) != PPC_HA (offset))
+ {
+ r[1].r_offset = r[0].r_offset + 4;
+ r[1].r_info = ELF64_R_INFO (0, R_PPC64_TOC16);
+ r[1].r_addend = r[0].r_addend;
+ }
+ else
+ {
+ r[1].r_offset = r[0].r_offset + 8 + 8 * use_fake_dep;
+ r[1].r_info = ELF64_R_INFO (0, R_PPC64_TOC16_DS);
+ r[1].r_addend = r[0].r_addend + 8 + 8 * plt_static_chain;
+ if (plt_static_chain)
+ {
+ r[2].r_offset = r[1].r_offset + 4;
+ r[2].r_info = ELF64_R_INFO (0, R_PPC64_TOC16_DS);
+ r[2].r_addend = r[0].r_addend + 8;
+ }
+ }
+ }
+ }
+ if (ALWAYS_EMIT_R2SAVE
+ || stub_entry->stub_type == ppc_stub_plt_call_r2save)
+ bfd_put_32 (obfd, STD_R2_0R1 + STK_TOC (htab), p), p += 4;
+ bfd_put_32 (obfd, LD_R12_0R2 | PPC_LO (offset), p), p += 4;
+ if (plt_load_toc
+ && PPC_HA (offset + 8 + 8 * plt_static_chain) != PPC_HA (offset))
+ {
+ bfd_put_32 (obfd, ADDI_R2_R2 | PPC_LO (offset), p), p += 4;
+ offset = 0;
+ }
+ bfd_put_32 (obfd, MTCTR_R12, p), p += 4;
+ if (plt_load_toc)
+ {
+ if (use_fake_dep)
+ {
+ bfd_put_32 (obfd, XOR_R11_R12_R12, p), p += 4;
+ bfd_put_32 (obfd, ADD_R2_R2_R11, p), p += 4;
+ }
+ if (plt_static_chain)
+ bfd_put_32 (obfd, LD_R11_0R2 | PPC_LO (offset + 16), p), p += 4;
+ bfd_put_32 (obfd, LD_R2_0R2 | PPC_LO (offset + 8), p), p += 4;
+ }
+ }
+ if (plt_load_toc && plt_thread_safe && !use_fake_dep)
+ {
+ bfd_put_32 (obfd, CMPLDI_R2_0, p), p += 4;
+ bfd_put_32 (obfd, BNECTR_P4, p), p += 4;
+ bfd_put_32 (obfd, B_DOT | (cmp_branch_off & 0x3fffffc), p), p += 4;
+ }
+ else
+ bfd_put_32 (obfd, BCTR, p), p += 4;
+ return p;
+}
+
+/* Build a special .plt call stub for __tls_get_addr. */
+
+#define LD_R11_0R3 0xe9630000
+#define LD_R12_0R3 0xe9830000
+#define MR_R0_R3 0x7c601b78
+#define CMPDI_R11_0 0x2c2b0000
+#define ADD_R3_R12_R13 0x7c6c6a14
+#define BEQLR 0x4d820020
+#define MR_R3_R0 0x7c030378
+#define STD_R11_0R1 0xf9610000
+#define BCTRL 0x4e800421
+#define LD_R11_0R1 0xe9610000
+#define MTLR_R11 0x7d6803a6
+
+static inline bfd_byte *
+build_tls_get_addr_stub (struct ppc_link_hash_table *htab,
+ struct ppc_stub_hash_entry *stub_entry,
+ bfd_byte *p, bfd_vma offset, Elf_Internal_Rela *r)
+{
+ bfd *obfd = htab->params->stub_bfd;
+
+ bfd_put_32 (obfd, LD_R11_0R3 + 0, p), p += 4;
+ bfd_put_32 (obfd, LD_R12_0R3 + 8, p), p += 4;
+ bfd_put_32 (obfd, MR_R0_R3, p), p += 4;
+ bfd_put_32 (obfd, CMPDI_R11_0, p), p += 4;
+ bfd_put_32 (obfd, ADD_R3_R12_R13, p), p += 4;
+ bfd_put_32 (obfd, BEQLR, p), p += 4;
+ bfd_put_32 (obfd, MR_R3_R0, p), p += 4;
+ bfd_put_32 (obfd, MFLR_R11, p), p += 4;
+ bfd_put_32 (obfd, STD_R11_0R1 + STK_LINKER (htab), p), p += 4;
+
+ if (r != NULL)
+ r[0].r_offset += 9 * 4;
+ p = build_plt_stub (htab, stub_entry, p, offset, r);
+ bfd_put_32 (obfd, BCTRL, p - 4);
+
+ bfd_put_32 (obfd, LD_R11_0R1 + STK_LINKER (htab), p), p += 4;
+ bfd_put_32 (obfd, LD_R2_0R1 + STK_TOC (htab), p), p += 4;
+ bfd_put_32 (obfd, MTLR_R11, p), p += 4;
+ bfd_put_32 (obfd, BLR, p), p += 4;
+
+ return p;
+}
+
+static Elf_Internal_Rela *
+get_relocs (asection *sec, int count)
+{
+ Elf_Internal_Rela *relocs;
+ struct bfd_elf_section_data *elfsec_data;
+
+ elfsec_data = elf_section_data (sec);
+ relocs = elfsec_data->relocs;
+ if (relocs == NULL)
+ {
+ bfd_size_type relsize;
+ relsize = sec->reloc_count * sizeof (*relocs);
+ relocs = bfd_alloc (sec->owner, relsize);
+ if (relocs == NULL)
+ return NULL;
+ elfsec_data->relocs = relocs;
+ elfsec_data->rela.hdr = bfd_zalloc (sec->owner,
+ sizeof (Elf_Internal_Shdr));
+ if (elfsec_data->rela.hdr == NULL)
+ return NULL;
+ elfsec_data->rela.hdr->sh_size = (sec->reloc_count
+ * sizeof (Elf64_External_Rela));
+ elfsec_data->rela.hdr->sh_entsize = sizeof (Elf64_External_Rela);
+ sec->reloc_count = 0;
+ }
+ relocs += sec->reloc_count;
+ sec->reloc_count += count;
+ return relocs;
+}
+
+static bfd_vma
+get_r2off (struct bfd_link_info *info,
+ struct ppc_stub_hash_entry *stub_entry)
+{
+ struct ppc_link_hash_table *htab = ppc_hash_table (info);
+ bfd_vma r2off = htab->stub_group[stub_entry->target_section->id].toc_off;
+
+ if (r2off == 0)
+ {
+ /* Support linking -R objects. Get the toc pointer from the
+ opd entry. */
+ char buf[8];
+ if (!htab->opd_abi)
+ return r2off;
+ asection *opd = stub_entry->h->elf.root.u.def.section;
+ bfd_vma opd_off = stub_entry->h->elf.root.u.def.value;
+
+ if (strcmp (opd->name, ".opd") != 0
+ || opd->reloc_count != 0)
+ {
+ info->callbacks->einfo (_("%P: cannot find opd entry toc for `%T'\n"),
+ stub_entry->h->elf.root.root.string);
+ bfd_set_error (bfd_error_bad_value);
+ return 0;
+ }
+ if (!bfd_get_section_contents (opd->owner, opd, buf, opd_off + 8, 8))
+ return 0;
+ r2off = bfd_get_64 (opd->owner, buf);
+ r2off -= elf_gp (info->output_bfd);
+ }
+ r2off -= htab->stub_group[stub_entry->id_sec->id].toc_off;
+ return r2off;
+}
+
+static bfd_boolean
+ppc_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
+{
+ struct ppc_stub_hash_entry *stub_entry;
+ struct ppc_branch_hash_entry *br_entry;
+ struct bfd_link_info *info;
+ struct ppc_link_hash_table *htab;
+ bfd_byte *loc;
+ bfd_byte *p;
+ bfd_vma dest, off;
+ int size;
+ Elf_Internal_Rela *r;
+ asection *plt;
+
+ /* Massage our args to the form they really have. */
+ stub_entry = (struct ppc_stub_hash_entry *) gen_entry;
+ info = in_arg;
+
+ htab = ppc_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ /* Make a note of the offset within the stubs for this entry. */
+ stub_entry->stub_offset = stub_entry->stub_sec->size;
+ loc = stub_entry->stub_sec->contents + stub_entry->stub_offset;
+
+ htab->stub_count[stub_entry->stub_type - 1] += 1;
+ switch (stub_entry->stub_type)
+ {
+ case ppc_stub_long_branch:
+ case ppc_stub_long_branch_r2off:
+ /* Branches are relative. This is where we are going to. */
+ dest = (stub_entry->target_value
+ + stub_entry->target_section->output_offset
+ + stub_entry->target_section->output_section->vma);
+ dest += PPC64_LOCAL_ENTRY_OFFSET (stub_entry->other);
+ off = dest;
+
+ /* And this is where we are coming from. */
+ off -= (stub_entry->stub_offset
+ + stub_entry->stub_sec->output_offset
+ + stub_entry->stub_sec->output_section->vma);
+
+ size = 4;
+ if (stub_entry->stub_type == ppc_stub_long_branch_r2off)
+ {
+ bfd_vma r2off = get_r2off (info, stub_entry);
+
+ if (r2off == 0)
+ {
+ htab->stub_error = TRUE;
+ return FALSE;
+ }
+ bfd_put_32 (htab->params->stub_bfd, STD_R2_0R1 + STK_TOC (htab), loc);
+ loc += 4;
+ size = 12;
+ if (PPC_HA (r2off) != 0)
+ {
+ size = 16;
+ bfd_put_32 (htab->params->stub_bfd,
+ ADDIS_R2_R2 | PPC_HA (r2off), loc);
+ loc += 4;
+ }
+ bfd_put_32 (htab->params->stub_bfd, ADDI_R2_R2 | PPC_LO (r2off), loc);
+ loc += 4;
+ off -= size - 4;
+ }
+ bfd_put_32 (htab->params->stub_bfd, B_DOT | (off & 0x3fffffc), loc);
+
+ if (off + (1 << 25) >= (bfd_vma) (1 << 26))
+ {
+ info->callbacks->einfo
+ (_("%P: long branch stub `%s' offset overflow\n"),
+ stub_entry->root.string);
+ htab->stub_error = TRUE;
+ return FALSE;
+ }
+
+ if (info->emitrelocations)
+ {
+ r = get_relocs (stub_entry->stub_sec, 1);
+ if (r == NULL)
+ return FALSE;
+ r->r_offset = loc - stub_entry->stub_sec->contents;
+ r->r_info = ELF64_R_INFO (0, R_PPC64_REL24);
+ r->r_addend = dest;
+ if (stub_entry->h != NULL)
+ {
+ struct elf_link_hash_entry **hashes;
+ unsigned long symndx;
+ struct ppc_link_hash_entry *h;
+
+ hashes = elf_sym_hashes (htab->params->stub_bfd);
+ if (hashes == NULL)
+ {
+ bfd_size_type hsize;
+
+ hsize = (htab->stub_globals + 1) * sizeof (*hashes);
+ hashes = bfd_zalloc (htab->params->stub_bfd, hsize);
+ if (hashes == NULL)
+ return FALSE;
+ elf_sym_hashes (htab->params->stub_bfd) = hashes;
+ htab->stub_globals = 1;
+ }
+ symndx = htab->stub_globals++;
+ h = stub_entry->h;
+ hashes[symndx] = &h->elf;
+ r->r_info = ELF64_R_INFO (symndx, R_PPC64_REL24);
+ if (h->oh != NULL && h->oh->is_func)
+ h = ppc_follow_link (h->oh);
+ if (h->elf.root.u.def.section != stub_entry->target_section)
+ /* H is an opd symbol. The addend must be zero. */
+ r->r_addend = 0;
+ else
+ {
+ off = (h->elf.root.u.def.value
+ + h->elf.root.u.def.section->output_offset
+ + h->elf.root.u.def.section->output_section->vma);
+ r->r_addend -= off;
+ }
+ }
+ }
+ break;
+
+ case ppc_stub_plt_branch:
+ case ppc_stub_plt_branch_r2off:
+ br_entry = ppc_branch_hash_lookup (&htab->branch_hash_table,
+ stub_entry->root.string + 9,
+ FALSE, FALSE);
+ if (br_entry == NULL)
+ {
+ info->callbacks->einfo (_("%P: can't find branch stub `%s'\n"),
+ stub_entry->root.string);
+ htab->stub_error = TRUE;
+ return FALSE;
+ }
+
+ dest = (stub_entry->target_value
+ + stub_entry->target_section->output_offset
+ + stub_entry->target_section->output_section->vma);
+ if (stub_entry->stub_type != ppc_stub_plt_branch_r2off)
+ dest += PPC64_LOCAL_ENTRY_OFFSET (stub_entry->other);
+
+ bfd_put_64 (htab->brlt->owner, dest,
+ htab->brlt->contents + br_entry->offset);
+
+ if (br_entry->iter == htab->stub_iteration)
+ {
+ br_entry->iter = 0;
+
+ if (htab->relbrlt != NULL)
+ {
+ /* Create a reloc for the branch lookup table entry. */
+ Elf_Internal_Rela rela;
+ bfd_byte *rl;
+
+ rela.r_offset = (br_entry->offset
+ + htab->brlt->output_offset
+ + htab->brlt->output_section->vma);
+ rela.r_info = ELF64_R_INFO (0, R_PPC64_RELATIVE);
+ rela.r_addend = dest;
+
+ rl = htab->relbrlt->contents;
+ rl += (htab->relbrlt->reloc_count++
+ * sizeof (Elf64_External_Rela));
+ bfd_elf64_swap_reloca_out (htab->relbrlt->owner, &rela, rl);
+ }
+ else if (info->emitrelocations)
+ {
+ r = get_relocs (htab->brlt, 1);
+ if (r == NULL)
+ return FALSE;
+ /* brlt, being SEC_LINKER_CREATED does not go through the
+ normal reloc processing. Symbols and offsets are not
+ translated from input file to output file form, so
+ set up the offset per the output file. */
+ r->r_offset = (br_entry->offset
+ + htab->brlt->output_offset
+ + htab->brlt->output_section->vma);
+ r->r_info = ELF64_R_INFO (0, R_PPC64_RELATIVE);
+ r->r_addend = dest;
+ }
+ }
+
+ dest = (br_entry->offset
+ + htab->brlt->output_offset
+ + htab->brlt->output_section->vma);
+
+ off = (dest
+ - elf_gp (htab->brlt->output_section->owner)
+ - htab->stub_group[stub_entry->id_sec->id].toc_off);
+
+ if (off + 0x80008000 > 0xffffffff || (off & 7) != 0)
+ {
+ info->callbacks->einfo
+ (_("%P: linkage table error against `%T'\n"),
+ stub_entry->root.string);
+ bfd_set_error (bfd_error_bad_value);
+ htab->stub_error = TRUE;
+ return FALSE;
+ }
+
+ if (info->emitrelocations)
+ {
+ r = get_relocs (stub_entry->stub_sec, 1 + (PPC_HA (off) != 0));
+ if (r == NULL)
+ return FALSE;
+ r[0].r_offset = loc - stub_entry->stub_sec->contents;
+ if (bfd_big_endian (info->output_bfd))
+ r[0].r_offset += 2;
+ if (stub_entry->stub_type == ppc_stub_plt_branch_r2off)
+ r[0].r_offset += 4;
+ r[0].r_info = ELF64_R_INFO (0, R_PPC64_TOC16_DS);
+ r[0].r_addend = dest;
+ if (PPC_HA (off) != 0)
+ {
+ r[0].r_info = ELF64_R_INFO (0, R_PPC64_TOC16_HA);
+ r[1].r_offset = r[0].r_offset + 4;
+ r[1].r_info = ELF64_R_INFO (0, R_PPC64_TOC16_LO_DS);
+ r[1].r_addend = r[0].r_addend;
+ }
+ }
+
+ if (stub_entry->stub_type != ppc_stub_plt_branch_r2off)
+ {
+ if (PPC_HA (off) != 0)
+ {
+ size = 16;
+ bfd_put_32 (htab->params->stub_bfd,
+ ADDIS_R12_R2 | PPC_HA (off), loc);
+ loc += 4;
+ bfd_put_32 (htab->params->stub_bfd,
+ LD_R12_0R12 | PPC_LO (off), loc);
+ }
+ else
+ {
+ size = 12;
+ bfd_put_32 (htab->params->stub_bfd,
+ LD_R12_0R2 | PPC_LO (off), loc);
+ }
+ }
+ else
+ {
+ bfd_vma r2off = get_r2off (info, stub_entry);
+
+ if (r2off == 0 && htab->opd_abi)
+ {
+ htab->stub_error = TRUE;
+ return FALSE;
+ }
+
+ bfd_put_32 (htab->params->stub_bfd, STD_R2_0R1 + STK_TOC (htab), loc);
+ loc += 4;
+ size = 16;
+ if (PPC_HA (off) != 0)
+ {
+ size += 4;
+ bfd_put_32 (htab->params->stub_bfd,
+ ADDIS_R12_R2 | PPC_HA (off), loc);
+ loc += 4;
+ bfd_put_32 (htab->params->stub_bfd,
+ LD_R12_0R12 | PPC_LO (off), loc);
+ }
+ else
+ bfd_put_32 (htab->params->stub_bfd, LD_R12_0R2 | PPC_LO (off), loc);
+
+ if (PPC_HA (r2off) != 0)
+ {
+ size += 4;
+ loc += 4;
+ bfd_put_32 (htab->params->stub_bfd,
+ ADDIS_R2_R2 | PPC_HA (r2off), loc);
+ }
+ if (PPC_LO (r2off) != 0)
+ {
+ size += 4;
+ loc += 4;
+ bfd_put_32 (htab->params->stub_bfd,
+ ADDI_R2_R2 | PPC_LO (r2off), loc);
+ }
+ }
+ loc += 4;
+ bfd_put_32 (htab->params->stub_bfd, MTCTR_R12, loc);
+ loc += 4;
+ bfd_put_32 (htab->params->stub_bfd, BCTR, loc);
+ break;
+
+ case ppc_stub_plt_call:
+ case ppc_stub_plt_call_r2save:
+ if (stub_entry->h != NULL
+ && stub_entry->h->is_func_descriptor
+ && stub_entry->h->oh != NULL)
+ {
+ struct ppc_link_hash_entry *fh = ppc_follow_link (stub_entry->h->oh);
+
+ /* If the old-ABI "dot-symbol" is undefined make it weak so
+ we don't get a link error from RELOC_FOR_GLOBAL_SYMBOL.
+ FIXME: We used to define the symbol on one of the call
+ stubs instead, which is why we test symbol section id
+ against htab->top_id in various places. Likely all
+ these checks could now disappear. */
+ if (fh->elf.root.type == bfd_link_hash_undefined)
+ fh->elf.root.type = bfd_link_hash_undefweak;
+ /* Stop undo_symbol_twiddle changing it back to undefined. */
+ fh->was_undefined = 0;
+ }
+
+ /* Now build the stub. */
+ dest = stub_entry->plt_ent->plt.offset & ~1;
+ if (dest >= (bfd_vma) -2)
+ abort ();
+
+ plt = htab->elf.splt;
+ if (!htab->elf.dynamic_sections_created
+ || stub_entry->h == NULL
+ || stub_entry->h->elf.dynindx == -1)
+ plt = htab->elf.iplt;
+
+ dest += plt->output_offset + plt->output_section->vma;
+
+ if (stub_entry->h == NULL
+ && (stub_entry->plt_ent->plt.offset & 1) == 0)
+ {
+ Elf_Internal_Rela rela;
+ bfd_byte *rl;
+
+ rela.r_offset = dest;
+ if (htab->opd_abi)
+ rela.r_info = ELF64_R_INFO (0, R_PPC64_JMP_IREL);
+ else
+ rela.r_info = ELF64_R_INFO (0, R_PPC64_IRELATIVE);
+ rela.r_addend = (stub_entry->target_value
+ + stub_entry->target_section->output_offset
+ + stub_entry->target_section->output_section->vma);
+
+ rl = (htab->elf.irelplt->contents
+ + (htab->elf.irelplt->reloc_count++
+ * sizeof (Elf64_External_Rela)));
+ bfd_elf64_swap_reloca_out (info->output_bfd, &rela, rl);
+ stub_entry->plt_ent->plt.offset |= 1;
+ }
+
+ off = (dest
+ - elf_gp (plt->output_section->owner)
+ - htab->stub_group[stub_entry->id_sec->id].toc_off);
+
+ if (off + 0x80008000 > 0xffffffff || (off & 7) != 0)
+ {
+ info->callbacks->einfo
+ (_("%P: linkage table error against `%T'\n"),
+ stub_entry->h != NULL
+ ? stub_entry->h->elf.root.root.string
+ : "<local sym>");
+ bfd_set_error (bfd_error_bad_value);
+ htab->stub_error = TRUE;
+ return FALSE;
+ }
+
+ if (htab->params->plt_stub_align != 0)
+ {
+ unsigned pad = plt_stub_pad (htab, stub_entry, off);
+
+ stub_entry->stub_sec->size += pad;
+ stub_entry->stub_offset = stub_entry->stub_sec->size;
+ loc += pad;
+ }
+
+ r = NULL;
+ if (info->emitrelocations)
+ {
+ r = get_relocs (stub_entry->stub_sec,
+ ((PPC_HA (off) != 0)
+ + (htab->opd_abi
+ ? 2 + (htab->params->plt_static_chain
+ && PPC_HA (off + 16) == PPC_HA (off))
+ : 1)));
+ if (r == NULL)
+ return FALSE;
+ r[0].r_offset = loc - stub_entry->stub_sec->contents;
+ if (bfd_big_endian (info->output_bfd))
+ r[0].r_offset += 2;
+ r[0].r_addend = dest;
+ }
+ if (stub_entry->h != NULL
+ && (stub_entry->h == htab->tls_get_addr_fd
+ || stub_entry->h == htab->tls_get_addr)
+ && !htab->params->no_tls_get_addr_opt)
+ p = build_tls_get_addr_stub (htab, stub_entry, loc, off, r);
+ else
+ p = build_plt_stub (htab, stub_entry, loc, off, r);
+ size = p - loc;
+ break;
+
+ default:
+ BFD_FAIL ();
+ return FALSE;
+ }
+
+ stub_entry->stub_sec->size += size;
+
+ if (htab->params->emit_stub_syms)
+ {
+ struct elf_link_hash_entry *h;
+ size_t len1, len2;
+ char *name;
+ const char *const stub_str[] = { "long_branch",
+ "long_branch_r2off",
+ "plt_branch",
+ "plt_branch_r2off",
+ "plt_call",
+ "plt_call" };
+
+ len1 = strlen (stub_str[stub_entry->stub_type - 1]);
+ len2 = strlen (stub_entry->root.string);
+ name = bfd_malloc (len1 + len2 + 2);
+ if (name == NULL)
+ return FALSE;
+ memcpy (name, stub_entry->root.string, 9);
+ memcpy (name + 9, stub_str[stub_entry->stub_type - 1], len1);
+ memcpy (name + len1 + 9, stub_entry->root.string + 8, len2 - 8 + 1);
+ h = elf_link_hash_lookup (&htab->elf, name, TRUE, FALSE, FALSE);
+ if (h == NULL)
+ return FALSE;
+ if (h->root.type == bfd_link_hash_new)
+ {
+ h->root.type = bfd_link_hash_defined;
+ h->root.u.def.section = stub_entry->stub_sec;
+ h->root.u.def.value = stub_entry->stub_offset;
+ h->ref_regular = 1;
+ h->def_regular = 1;
+ h->ref_regular_nonweak = 1;
+ h->forced_local = 1;
+ h->non_elf = 0;
+ }
+ }
+
+ return TRUE;
+}
+
+/* As above, but don't actually build the stub. Just bump offset so
+ we know stub section sizes, and select plt_branch stubs where
+ long_branch stubs won't do. */
+
+static bfd_boolean
+ppc_size_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
+{
+ struct ppc_stub_hash_entry *stub_entry;
+ struct bfd_link_info *info;
+ struct ppc_link_hash_table *htab;
+ bfd_vma off;
+ int size;
+
+ /* Massage our args to the form they really have. */
+ stub_entry = (struct ppc_stub_hash_entry *) gen_entry;
+ info = in_arg;
+
+ htab = ppc_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ if (stub_entry->stub_type == ppc_stub_plt_call
+ || stub_entry->stub_type == ppc_stub_plt_call_r2save)
+ {
+ asection *plt;
+ off = stub_entry->plt_ent->plt.offset & ~(bfd_vma) 1;
+ if (off >= (bfd_vma) -2)
+ abort ();
+ plt = htab->elf.splt;
+ if (!htab->elf.dynamic_sections_created
+ || stub_entry->h == NULL
+ || stub_entry->h->elf.dynindx == -1)
+ plt = htab->elf.iplt;
+ off += (plt->output_offset
+ + plt->output_section->vma
+ - elf_gp (plt->output_section->owner)
+ - htab->stub_group[stub_entry->id_sec->id].toc_off);
+
+ size = plt_stub_size (htab, stub_entry, off);
+ if (htab->params->plt_stub_align)
+ size += plt_stub_pad (htab, stub_entry, off);
+ if (info->emitrelocations)
+ {
+ stub_entry->stub_sec->reloc_count
+ += ((PPC_HA (off) != 0)
+ + (htab->opd_abi
+ ? 2 + (htab->params->plt_static_chain
+ && PPC_HA (off + 16) == PPC_HA (off))
+ : 1));
+ stub_entry->stub_sec->flags |= SEC_RELOC;
+ }
+ }
+ else
+ {
+ /* ppc_stub_long_branch or ppc_stub_plt_branch, or their r2off
+ variants. */
+ bfd_vma r2off = 0;
+ bfd_vma local_off = 0;
+
+ off = (stub_entry->target_value
+ + stub_entry->target_section->output_offset
+ + stub_entry->target_section->output_section->vma);
+ off -= (stub_entry->stub_sec->size
+ + stub_entry->stub_sec->output_offset
+ + stub_entry->stub_sec->output_section->vma);
+
+ /* Reset the stub type from the plt variant in case we now
+ can reach with a shorter stub. */
+ if (stub_entry->stub_type >= ppc_stub_plt_branch)
+ stub_entry->stub_type += ppc_stub_long_branch - ppc_stub_plt_branch;
+
+ size = 4;
+ if (stub_entry->stub_type == ppc_stub_long_branch_r2off)
+ {
+ r2off = get_r2off (info, stub_entry);
+ if (r2off == 0 && htab->opd_abi)
+ {
+ htab->stub_error = TRUE;
+ return FALSE;
+ }
+ size = 12;
+ if (PPC_HA (r2off) != 0)
+ size = 16;
+ off -= size - 4;
+ }
+
+ local_off = PPC64_LOCAL_ENTRY_OFFSET (stub_entry->other);
+
+ /* If the branch offset if too big, use a ppc_stub_plt_branch.
+ Do the same for -R objects without function descriptors. */
+ if (off + (1 << 25) >= (bfd_vma) (1 << 26) - local_off
+ || (stub_entry->stub_type == ppc_stub_long_branch_r2off
+ && r2off == 0))
+ {
+ struct ppc_branch_hash_entry *br_entry;
+
+ br_entry = ppc_branch_hash_lookup (&htab->branch_hash_table,
+ stub_entry->root.string + 9,
+ TRUE, FALSE);
+ if (br_entry == NULL)
+ {
+ info->callbacks->einfo (_("%P: can't build branch stub `%s'\n"),
+ stub_entry->root.string);
+ htab->stub_error = TRUE;
+ return FALSE;
+ }
+
+ if (br_entry->iter != htab->stub_iteration)
+ {
+ br_entry->iter = htab->stub_iteration;
+ br_entry->offset = htab->brlt->size;
+ htab->brlt->size += 8;
+
+ if (htab->relbrlt != NULL)
+ htab->relbrlt->size += sizeof (Elf64_External_Rela);
+ else if (info->emitrelocations)
+ {
+ htab->brlt->reloc_count += 1;
+ htab->brlt->flags |= SEC_RELOC;
+ }
+ }
+
+ stub_entry->stub_type += ppc_stub_plt_branch - ppc_stub_long_branch;
+ off = (br_entry->offset
+ + htab->brlt->output_offset
+ + htab->brlt->output_section->vma
+ - elf_gp (htab->brlt->output_section->owner)
+ - htab->stub_group[stub_entry->id_sec->id].toc_off);
+
+ if (info->emitrelocations)
+ {
+ stub_entry->stub_sec->reloc_count += 1 + (PPC_HA (off) != 0);
+ stub_entry->stub_sec->flags |= SEC_RELOC;
+ }
+
+ if (stub_entry->stub_type != ppc_stub_plt_branch_r2off)
+ {
+ size = 12;
+ if (PPC_HA (off) != 0)
+ size = 16;
+ }
+ else
+ {
+ size = 16;
+ if (PPC_HA (off) != 0)
+ size += 4;
+
+ if (PPC_HA (r2off) != 0)
+ size += 4;
+ if (PPC_LO (r2off) != 0)
+ size += 4;
+ }
+ }
+ else if (info->emitrelocations)
+ {
+ stub_entry->stub_sec->reloc_count += 1;
+ stub_entry->stub_sec->flags |= SEC_RELOC;
+ }
+ }
+
+ stub_entry->stub_sec->size += size;
+ return TRUE;
+}
+
+/* Set up various things so that we can make a list of input sections
+ for each output section included in the link. Returns -1 on error,
+ 0 when no stubs will be needed, and 1 on success. */
+
+int
+ppc64_elf_setup_section_lists (struct bfd_link_info *info)
+{
+ bfd *input_bfd;
+ int top_id, top_index, id;
+ asection *section;
+ asection **input_list;
+ bfd_size_type amt;
+ struct ppc_link_hash_table *htab = ppc_hash_table (info);
+
+ if (htab == NULL)
+ return -1;
+
+ /* Find the top input section id. */
+ for (input_bfd = info->input_bfds, top_id = 3;
+ input_bfd != NULL;
+ input_bfd = input_bfd->link.next)
+ {
+ for (section = input_bfd->sections;
+ section != NULL;
+ section = section->next)
+ {
+ if (top_id < section->id)
+ top_id = section->id;
+ }
+ }
+
+ htab->top_id = top_id;
+ amt = sizeof (struct map_stub) * (top_id + 1);
+ htab->stub_group = bfd_zmalloc (amt);
+ if (htab->stub_group == NULL)
+ return -1;
+
+ /* Set toc_off for com, und, abs and ind sections. */
+ for (id = 0; id < 3; id++)
+ htab->stub_group[id].toc_off = TOC_BASE_OFF;
+
+ /* We can't use output_bfd->section_count here to find the top output
+ section index as some sections may have been removed, and
+ strip_excluded_output_sections doesn't renumber the indices. */
+ for (section = info->output_bfd->sections, top_index = 0;
+ section != NULL;
+ section = section->next)
+ {
+ if (top_index < section->index)
+ top_index = section->index;
+ }
+
+ htab->top_index = top_index;
+ amt = sizeof (asection *) * (top_index + 1);
+ input_list = bfd_zmalloc (amt);
+ htab->input_list = input_list;
+ if (input_list == NULL)
+ return -1;
+
+ return 1;
+}
+
+/* Set up for first pass at multitoc partitioning. */
+
+void
+ppc64_elf_start_multitoc_partition (struct bfd_link_info *info)
+{
+ struct ppc_link_hash_table *htab = ppc_hash_table (info);
+
+ htab->toc_curr = ppc64_elf_set_toc (info, info->output_bfd);
+ htab->toc_bfd = NULL;
+ htab->toc_first_sec = NULL;
+}
+
+/* The linker repeatedly calls this function for each TOC input section
+ and linker generated GOT section. Group input bfds such that the toc
+ within a group is less than 64k in size. */
+
+bfd_boolean
+ppc64_elf_next_toc_section (struct bfd_link_info *info, asection *isec)
+{
+ struct ppc_link_hash_table *htab = ppc_hash_table (info);
+ bfd_vma addr, off, limit;
+
+ if (htab == NULL)
+ return FALSE;
+
+ if (!htab->second_toc_pass)
+ {
+ /* Keep track of the first .toc or .got section for this input bfd. */
+ bfd_boolean new_bfd = htab->toc_bfd != isec->owner;
+
+ if (new_bfd)
+ {
+ htab->toc_bfd = isec->owner;
+ htab->toc_first_sec = isec;
+ }
+
+ addr = isec->output_offset + isec->output_section->vma;
+ off = addr - htab->toc_curr;
+ limit = 0x80008000;
+ if (ppc64_elf_tdata (isec->owner)->has_small_toc_reloc)
+ limit = 0x10000;
+ if (off + isec->size > limit)
+ {
+ addr = (htab->toc_first_sec->output_offset
+ + htab->toc_first_sec->output_section->vma);
+ htab->toc_curr = addr;
+ }
+
+ /* toc_curr is the base address of this toc group. Set elf_gp
+ for the input section to be the offset relative to the
+ output toc base plus 0x8000. Making the input elf_gp an
+ offset allows us to move the toc as a whole without
+ recalculating input elf_gp. */
+ off = htab->toc_curr - elf_gp (isec->output_section->owner);
+ off += TOC_BASE_OFF;
+
+ /* Die if someone uses a linker script that doesn't keep input
+ file .toc and .got together. */
+ if (new_bfd
+ && elf_gp (isec->owner) != 0
+ && elf_gp (isec->owner) != off)
+ return FALSE;
+
+ elf_gp (isec->owner) = off;
+ return TRUE;
+ }
+
+ /* During the second pass toc_first_sec points to the start of
+ a toc group, and toc_curr is used to track the old elf_gp.
+ We use toc_bfd to ensure we only look at each bfd once. */
+ if (htab->toc_bfd == isec->owner)
+ return TRUE;
+ htab->toc_bfd = isec->owner;
+
+ if (htab->toc_first_sec == NULL
+ || htab->toc_curr != elf_gp (isec->owner))
+ {
+ htab->toc_curr = elf_gp (isec->owner);
+ htab->toc_first_sec = isec;
+ }
+ addr = (htab->toc_first_sec->output_offset
+ + htab->toc_first_sec->output_section->vma);
+ off = addr - elf_gp (isec->output_section->owner) + TOC_BASE_OFF;
+ elf_gp (isec->owner) = off;
+
+ return TRUE;
+}
+
+/* Called via elf_link_hash_traverse to merge GOT entries for global
+ symbol H. */
+
+static bfd_boolean
+merge_global_got (struct elf_link_hash_entry *h, void *inf ATTRIBUTE_UNUSED)
+{
+ if (h->root.type == bfd_link_hash_indirect)
+ return TRUE;
+
+ merge_got_entries (&h->got.glist);
+
+ return TRUE;
+}
+
+/* Called via elf_link_hash_traverse to allocate GOT entries for global
+ symbol H. */
+
+static bfd_boolean
+reallocate_got (struct elf_link_hash_entry *h, void *inf)
+{
+ struct got_entry *gent;
+
+ if (h->root.type == bfd_link_hash_indirect)
+ return TRUE;
+
+ for (gent = h->got.glist; gent != NULL; gent = gent->next)
+ if (!gent->is_indirect)
+ allocate_got (h, (struct bfd_link_info *) inf, gent);
+ return TRUE;
+}
+
+/* Called on the first multitoc pass after the last call to
+ ppc64_elf_next_toc_section. This function removes duplicate GOT
+ entries. */
+
+bfd_boolean
+ppc64_elf_layout_multitoc (struct bfd_link_info *info)
+{
+ struct ppc_link_hash_table *htab = ppc_hash_table (info);
+ struct bfd *ibfd, *ibfd2;
+ bfd_boolean done_something;
+
+ htab->multi_toc_needed = htab->toc_curr != elf_gp (info->output_bfd);
+
+ if (!htab->do_multi_toc)
+ return FALSE;
+
+ /* Merge global sym got entries within a toc group. */
+ elf_link_hash_traverse (&htab->elf, merge_global_got, info);
+
+ /* And tlsld_got. */
+ for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next)
+ {
+ struct got_entry *ent, *ent2;
+
+ if (!is_ppc64_elf (ibfd))
+ continue;
+
+ ent = ppc64_tlsld_got (ibfd);
+ if (!ent->is_indirect
+ && ent->got.offset != (bfd_vma) -1)
+ {
+ for (ibfd2 = ibfd->link.next; ibfd2 != NULL; ibfd2 = ibfd2->link.next)
+ {
+ if (!is_ppc64_elf (ibfd2))
+ continue;
+
+ ent2 = ppc64_tlsld_got (ibfd2);
+ if (!ent2->is_indirect
+ && ent2->got.offset != (bfd_vma) -1
+ && elf_gp (ibfd2) == elf_gp (ibfd))
+ {
+ ent2->is_indirect = TRUE;
+ ent2->got.ent = ent;
+ }
+ }
+ }
+ }
+
+ /* Zap sizes of got sections. */
+ htab->elf.irelplt->rawsize = htab->elf.irelplt->size;
+ htab->elf.irelplt->size -= htab->got_reli_size;
+ htab->got_reli_size = 0;
+
+ for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next)
+ {
+ asection *got, *relgot;
+
+ if (!is_ppc64_elf (ibfd))
+ continue;
+
+ got = ppc64_elf_tdata (ibfd)->got;
+ if (got != NULL)
+ {
+ got->rawsize = got->size;
+ got->size = 0;
+ relgot = ppc64_elf_tdata (ibfd)->relgot;
+ relgot->rawsize = relgot->size;
+ relgot->size = 0;
+ }
+ }
+
+ /* Now reallocate the got, local syms first. We don't need to
+ allocate section contents again since we never increase size. */
+ for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next)
+ {
+ struct got_entry **lgot_ents;
+ struct got_entry **end_lgot_ents;
+ struct plt_entry **local_plt;
+ struct plt_entry **end_local_plt;
+ unsigned char *lgot_masks;
+ bfd_size_type locsymcount;
+ Elf_Internal_Shdr *symtab_hdr;
+ asection *s;
+
+ if (!is_ppc64_elf (ibfd))
+ continue;
+
+ lgot_ents = elf_local_got_ents (ibfd);
+ if (!lgot_ents)
+ continue;
+
+ symtab_hdr = &elf_symtab_hdr (ibfd);
+ locsymcount = symtab_hdr->sh_info;
+ end_lgot_ents = lgot_ents + locsymcount;
+ local_plt = (struct plt_entry **) end_lgot_ents;
+ end_local_plt = local_plt + locsymcount;
+ lgot_masks = (unsigned char *) end_local_plt;
+ s = ppc64_elf_tdata (ibfd)->got;
+ for (; lgot_ents < end_lgot_ents; ++lgot_ents, ++lgot_masks)
+ {
+ struct got_entry *ent;
+
+ for (ent = *lgot_ents; ent != NULL; ent = ent->next)
+ {
+ unsigned int ent_size = 8;
+ unsigned int rel_size = sizeof (Elf64_External_Rela);
+
+ ent->got.offset = s->size;
+ if ((ent->tls_type & *lgot_masks & TLS_GD) != 0)
+ {
+ ent_size *= 2;
+ rel_size *= 2;
+ }
+ s->size += ent_size;
+ if ((*lgot_masks & PLT_IFUNC) != 0)
+ {
+ htab->elf.irelplt->size += rel_size;
+ htab->got_reli_size += rel_size;
+ }
+ else if (info->shared)
+ {
+ asection *srel = ppc64_elf_tdata (ibfd)->relgot;
+ srel->size += rel_size;
+ }
+ }
+ }
+ }
+
+ elf_link_hash_traverse (&htab->elf, reallocate_got, info);
+
+ for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next)
+ {
+ struct got_entry *ent;
+
+ if (!is_ppc64_elf (ibfd))
+ continue;
+
+ ent = ppc64_tlsld_got (ibfd);
+ if (!ent->is_indirect
+ && ent->got.offset != (bfd_vma) -1)
+ {
+ asection *s = ppc64_elf_tdata (ibfd)->got;
+ ent->got.offset = s->size;
+ s->size += 16;
+ if (info->shared)
+ {
+ asection *srel = ppc64_elf_tdata (ibfd)->relgot;
+ srel->size += sizeof (Elf64_External_Rela);
+ }
+ }
+ }
+
+ done_something = htab->elf.irelplt->rawsize != htab->elf.irelplt->size;
+ if (!done_something)
+ for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next)
+ {
+ asection *got;
+
+ if (!is_ppc64_elf (ibfd))
+ continue;
+
+ got = ppc64_elf_tdata (ibfd)->got;
+ if (got != NULL)
+ {
+ done_something = got->rawsize != got->size;
+ if (done_something)
+ break;
+ }
+ }
+
+ if (done_something)
+ (*htab->params->layout_sections_again) ();
+
+ /* Set up for second pass over toc sections to recalculate elf_gp
+ on input sections. */
+ htab->toc_bfd = NULL;
+ htab->toc_first_sec = NULL;
+ htab->second_toc_pass = TRUE;
+ return done_something;
+}
+
+/* Called after second pass of multitoc partitioning. */
+
+void
+ppc64_elf_finish_multitoc_partition (struct bfd_link_info *info)
+{
+ struct ppc_link_hash_table *htab = ppc_hash_table (info);
+
+ /* After the second pass, toc_curr tracks the TOC offset used
+ for code sections below in ppc64_elf_next_input_section. */
+ htab->toc_curr = TOC_BASE_OFF;
+}
+
+/* No toc references were found in ISEC. If the code in ISEC makes no
+ calls, then there's no need to use toc adjusting stubs when branching
+ into ISEC. Actually, indirect calls from ISEC are OK as they will
+ load r2. Returns -1 on error, 0 for no stub needed, 1 for stub
+ needed, and 2 if a cyclical call-graph was found but no other reason
+ for a stub was detected. If called from the top level, a return of
+ 2 means the same as a return of 0. */
+
+static int
+toc_adjusting_stub_needed (struct bfd_link_info *info, asection *isec)
+{
+ int ret;
+
+ /* Mark this section as checked. */
+ isec->call_check_done = 1;
+
+ /* We know none of our code bearing sections will need toc stubs. */
+ if ((isec->flags & SEC_LINKER_CREATED) != 0)
+ return 0;
+
+ if (isec->size == 0)
+ return 0;
+
+ if (isec->output_section == NULL)
+ return 0;
+
+ ret = 0;
+ if (isec->reloc_count != 0)
+ {
+ Elf_Internal_Rela *relstart, *rel;
+ Elf_Internal_Sym *local_syms;
+ struct ppc_link_hash_table *htab;
+
+ relstart = _bfd_elf_link_read_relocs (isec->owner, isec, NULL, NULL,
+ info->keep_memory);
+ if (relstart == NULL)
+ return -1;
+
+ /* Look for branches to outside of this section. */
+ local_syms = NULL;
+ htab = ppc_hash_table (info);
+ if (htab == NULL)
+ return -1;
+
+ for (rel = relstart; rel < relstart + isec->reloc_count; ++rel)
+ {
+ enum elf_ppc64_reloc_type r_type;
+ unsigned long r_symndx;
+ struct elf_link_hash_entry *h;
+ struct ppc_link_hash_entry *eh;
+ Elf_Internal_Sym *sym;
+ asection *sym_sec;
+ struct _opd_sec_data *opd;
+ bfd_vma sym_value;
+ bfd_vma dest;
+
+ r_type = ELF64_R_TYPE (rel->r_info);
+ if (r_type != R_PPC64_REL24
+ && r_type != R_PPC64_REL14
+ && r_type != R_PPC64_REL14_BRTAKEN
+ && r_type != R_PPC64_REL14_BRNTAKEN)
+ continue;
+
+ r_symndx = ELF64_R_SYM (rel->r_info);
+ if (!get_sym_h (&h, &sym, &sym_sec, NULL, &local_syms, r_symndx,
+ isec->owner))
+ {
+ ret = -1;
+ break;
+ }
+
+ /* Calls to dynamic lib functions go through a plt call stub
+ that uses r2. */
+ eh = (struct ppc_link_hash_entry *) h;
+ if (eh != NULL
+ && (eh->elf.plt.plist != NULL
+ || (eh->oh != NULL
+ && ppc_follow_link (eh->oh)->elf.plt.plist != NULL)))
+ {
+ ret = 1;
+ break;
+ }
+
+ if (sym_sec == NULL)
+ /* Ignore other undefined symbols. */
+ continue;
+
+ /* Assume branches to other sections not included in the
+ link need stubs too, to cover -R and absolute syms. */
+ if (sym_sec->output_section == NULL)
+ {
+ ret = 1;
+ break;
+ }
+
+ if (h == NULL)
+ sym_value = sym->st_value;
+ else
+ {
+ if (h->root.type != bfd_link_hash_defined
+ && h->root.type != bfd_link_hash_defweak)
+ abort ();
+ sym_value = h->root.u.def.value;
+ }
+ sym_value += rel->r_addend;
+
+ /* If this branch reloc uses an opd sym, find the code section. */
+ opd = get_opd_info (sym_sec);
+ if (opd != NULL)
+ {
+ if (h == NULL && opd->adjust != NULL)
+ {
+ long adjust;
+
+ adjust = opd->adjust[sym->st_value / 8];
+ if (adjust == -1)
+ /* Assume deleted functions won't ever be called. */
+ continue;
+ sym_value += adjust;
+ }
+
+ dest = opd_entry_value (sym_sec, sym_value,
+ &sym_sec, NULL, FALSE);
+ if (dest == (bfd_vma) -1)
+ continue;
+ }
+ else
+ dest = (sym_value
+ + sym_sec->output_offset
+ + sym_sec->output_section->vma);
+
+ /* Ignore branch to self. */
+ if (sym_sec == isec)
+ continue;
+
+ /* If the called function uses the toc, we need a stub. */
+ if (sym_sec->has_toc_reloc
+ || sym_sec->makes_toc_func_call)
+ {
+ ret = 1;
+ break;
+ }
+
+ /* Assume any branch that needs a long branch stub might in fact
+ need a plt_branch stub. A plt_branch stub uses r2. */
+ else if (dest - (isec->output_offset
+ + isec->output_section->vma
+ + rel->r_offset) + (1 << 25)
+ >= (2u << 25) - PPC64_LOCAL_ENTRY_OFFSET (h
+ ? h->other
+ : sym->st_other))
+ {
+ ret = 1;
+ break;
+ }
+
+ /* If calling back to a section in the process of being
+ tested, we can't say for sure that no toc adjusting stubs
+ are needed, so don't return zero. */
+ else if (sym_sec->call_check_in_progress)
+ ret = 2;
+
+ /* Branches to another section that itself doesn't have any TOC
+ references are OK. Recursively call ourselves to check. */
+ else if (!sym_sec->call_check_done)
+ {
+ int recur;
+
+ /* Mark current section as indeterminate, so that other
+ sections that call back to current won't be marked as
+ known. */
+ isec->call_check_in_progress = 1;
+ recur = toc_adjusting_stub_needed (info, sym_sec);
+ isec->call_check_in_progress = 0;
+
+ if (recur != 0)
+ {
+ ret = recur;
+ if (recur != 2)
+ break;
+ }
+ }
+ }
+
+ if (local_syms != NULL
+ && (elf_symtab_hdr (isec->owner).contents
+ != (unsigned char *) local_syms))
+ free (local_syms);
+ if (elf_section_data (isec)->relocs != relstart)
+ free (relstart);
+ }
+
+ if ((ret & 1) == 0
+ && isec->map_head.s != NULL
+ && (strcmp (isec->output_section->name, ".init") == 0
+ || strcmp (isec->output_section->name, ".fini") == 0))
+ {
+ if (isec->map_head.s->has_toc_reloc
+ || isec->map_head.s->makes_toc_func_call)
+ ret = 1;
+ else if (!isec->map_head.s->call_check_done)
+ {
+ int recur;
+ isec->call_check_in_progress = 1;
+ recur = toc_adjusting_stub_needed (info, isec->map_head.s);
+ isec->call_check_in_progress = 0;
+ if (recur != 0)
+ ret = recur;
+ }
+ }
+
+ if (ret == 1)
+ isec->makes_toc_func_call = 1;
+
+ return ret;
+}
+
+/* The linker repeatedly calls this function for each input section,
+ in the order that input sections are linked into output sections.
+ Build lists of input sections to determine groupings between which
+ we may insert linker stubs. */
+
+bfd_boolean
+ppc64_elf_next_input_section (struct bfd_link_info *info, asection *isec)
+{
+ struct ppc_link_hash_table *htab = ppc_hash_table (info);
+
+ if (htab == NULL)
+ return FALSE;
+
+ if ((isec->output_section->flags & SEC_CODE) != 0
+ && isec->output_section->index <= htab->top_index)
+ {
+ asection **list = htab->input_list + isec->output_section->index;
+ /* Steal the link_sec pointer for our list. */
+#define PREV_SEC(sec) (htab->stub_group[(sec)->id].link_sec)
+ /* This happens to make the list in reverse order,
+ which is what we want. */
+ PREV_SEC (isec) = *list;
+ *list = isec;
+ }
+
+ if (htab->multi_toc_needed)
+ {
+ /* Analyse sections that aren't already flagged as needing a
+ valid toc pointer. Exclude .fixup for the linux kernel.
+ .fixup contains branches, but only back to the function that
+ hit an exception. */
+ if (!(isec->has_toc_reloc
+ || (isec->flags & SEC_CODE) == 0
+ || strcmp (isec->name, ".fixup") == 0
+ || isec->call_check_done))
+ {
+ if (toc_adjusting_stub_needed (info, isec) < 0)
+ return FALSE;
+ }
+ /* Make all sections use the TOC assigned for this object file.
+ This will be wrong for pasted sections; We fix that in
+ check_pasted_section(). */
+ if (elf_gp (isec->owner) != 0)
+ htab->toc_curr = elf_gp (isec->owner);
+ }
+
+ htab->stub_group[isec->id].toc_off = htab->toc_curr;
+ return TRUE;
+}
+
+/* Check that all .init and .fini sections use the same toc, if they
+ have toc relocs. */
+
+static bfd_boolean
+check_pasted_section (struct bfd_link_info *info, const char *name)
+{
+ asection *o = bfd_get_section_by_name (info->output_bfd, name);
+
+ if (o != NULL)
+ {
+ struct ppc_link_hash_table *htab = ppc_hash_table (info);
+ bfd_vma toc_off = 0;
+ asection *i;
+
+ for (i = o->map_head.s; i != NULL; i = i->map_head.s)
+ if (i->has_toc_reloc)
+ {
+ if (toc_off == 0)
+ toc_off = htab->stub_group[i->id].toc_off;
+ else if (toc_off != htab->stub_group[i->id].toc_off)
+ return FALSE;
+ }
+
+ if (toc_off == 0)
+ for (i = o->map_head.s; i != NULL; i = i->map_head.s)
+ if (i->makes_toc_func_call)
+ {
+ toc_off = htab->stub_group[i->id].toc_off;
+ break;
+ }
+
+ /* Make sure the whole pasted function uses the same toc offset. */
+ if (toc_off != 0)
+ for (i = o->map_head.s; i != NULL; i = i->map_head.s)
+ htab->stub_group[i->id].toc_off = toc_off;
+ }
+ return TRUE;
+}
+
+bfd_boolean
+ppc64_elf_check_init_fini (struct bfd_link_info *info)
+{
+ return (check_pasted_section (info, ".init")
+ & check_pasted_section (info, ".fini"));
+}
+
+/* See whether we can group stub sections together. Grouping stub
+ sections may result in fewer stubs. More importantly, we need to
+ put all .init* and .fini* stubs at the beginning of the .init or
+ .fini output sections respectively, because glibc splits the
+ _init and _fini functions into multiple parts. Putting a stub in
+ the middle of a function is not a good idea. */
+
+static void
+group_sections (struct ppc_link_hash_table *htab,
+ bfd_size_type stub_group_size,
+ bfd_boolean stubs_always_before_branch)
+{
+ asection **list;
+ bfd_size_type stub14_group_size;
+ bfd_boolean suppress_size_errors;
+
+ suppress_size_errors = FALSE;
+ stub14_group_size = stub_group_size >> 10;
+ if (stub_group_size == 1)
+ {
+ /* Default values. */
+ if (stubs_always_before_branch)
+ {
+ stub_group_size = 0x1e00000;
+ stub14_group_size = 0x7800;
+ }
+ else
+ {
+ stub_group_size = 0x1c00000;
+ stub14_group_size = 0x7000;
+ }
+ suppress_size_errors = TRUE;
+ }
+
+ list = htab->input_list + htab->top_index;
+ do
+ {
+ asection *tail = *list;
+ while (tail != NULL)
+ {
+ asection *curr;
+ asection *prev;
+ bfd_size_type total;
+ bfd_boolean big_sec;
+ bfd_vma curr_toc;
+
+ curr = tail;
+ total = tail->size;
+ big_sec = total > (ppc64_elf_section_data (tail) != NULL
+ && ppc64_elf_section_data (tail)->has_14bit_branch
+ ? stub14_group_size : stub_group_size);
+ if (big_sec && !suppress_size_errors)
+ (*_bfd_error_handler) (_("%B section %A exceeds stub group size"),
+ tail->owner, tail);
+ curr_toc = htab->stub_group[tail->id].toc_off;
+
+ while ((prev = PREV_SEC (curr)) != NULL
+ && ((total += curr->output_offset - prev->output_offset)
+ < (ppc64_elf_section_data (prev) != NULL
+ && ppc64_elf_section_data (prev)->has_14bit_branch
+ ? stub14_group_size : stub_group_size))
+ && htab->stub_group[prev->id].toc_off == curr_toc)
+ curr = prev;
+
+ /* OK, the size from the start of CURR to the end is less
+ than stub_group_size and thus can be handled by one stub
+ section. (or the tail section is itself larger than
+ stub_group_size, in which case we may be toast.) We
+ should really be keeping track of the total size of stubs
+ added here, as stubs contribute to the final output
+ section size. That's a little tricky, and this way will
+ only break if stubs added make the total size more than
+ 2^25, ie. for the default stub_group_size, if stubs total
+ more than 2097152 bytes, or nearly 75000 plt call stubs. */
+ do
+ {
+ prev = PREV_SEC (tail);
+ /* Set up this stub group. */
+ htab->stub_group[tail->id].link_sec = curr;
+ }
+ while (tail != curr && (tail = prev) != NULL);
+
+ /* But wait, there's more! Input sections up to stub_group_size
+ bytes before the stub section can be handled by it too.
+ Don't do this if we have a really large section after the
+ stubs, as adding more stubs increases the chance that
+ branches may not reach into the stub section. */
+ if (!stubs_always_before_branch && !big_sec)
+ {
+ total = 0;
+ while (prev != NULL
+ && ((total += tail->output_offset - prev->output_offset)
+ < (ppc64_elf_section_data (prev) != NULL
+ && ppc64_elf_section_data (prev)->has_14bit_branch
+ ? stub14_group_size : stub_group_size))
+ && htab->stub_group[prev->id].toc_off == curr_toc)
+ {
+ tail = prev;
+ prev = PREV_SEC (tail);
+ htab->stub_group[tail->id].link_sec = curr;
+ }
+ }
+ tail = prev;
+ }
+ }
+ while (list-- != htab->input_list);
+ free (htab->input_list);
+#undef PREV_SEC
+}
+
+static const unsigned char glink_eh_frame_cie[] =
+{
+ 0, 0, 0, 16, /* length. */
+ 0, 0, 0, 0, /* id. */
+ 1, /* CIE version. */
+ 'z', 'R', 0, /* Augmentation string. */
+ 4, /* Code alignment. */
+ 0x78, /* Data alignment. */
+ 65, /* RA reg. */
+ 1, /* Augmentation size. */
+ DW_EH_PE_pcrel | DW_EH_PE_sdata4, /* FDE encoding. */
+ DW_CFA_def_cfa, 1, 0, /* def_cfa: r1 offset 0. */
+ 0, 0, 0, 0
+};
+
+/* Stripping output sections is normally done before dynamic section
+ symbols have been allocated. This function is called later, and
+ handles cases like htab->brlt which is mapped to its own output
+ section. */
+
+static void
+maybe_strip_output (struct bfd_link_info *info, asection *isec)
+{
+ if (isec->size == 0
+ && isec->output_section->size == 0
+ && !(isec->output_section->flags & SEC_KEEP)
+ && !bfd_section_removed_from_list (info->output_bfd,
+ isec->output_section)
+ && elf_section_data (isec->output_section)->dynindx == 0)
+ {
+ isec->output_section->flags |= SEC_EXCLUDE;
+ bfd_section_list_remove (info->output_bfd, isec->output_section);
+ info->output_bfd->section_count--;
+ }
+}
+
+/* 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. */
+
+bfd_boolean
+ppc64_elf_size_stubs (struct bfd_link_info *info)
+{
+ bfd_size_type stub_group_size;
+ bfd_boolean stubs_always_before_branch;
+ struct ppc_link_hash_table *htab = ppc_hash_table (info);
+
+ if (htab == NULL)
+ return FALSE;
+
+ if (htab->params->plt_thread_safe == -1 && !info->executable)
+ htab->params->plt_thread_safe = 1;
+ if (!htab->opd_abi)
+ htab->params->plt_thread_safe = 0;
+ else if (htab->params->plt_thread_safe == -1)
+ {
+ static const char *const thread_starter[] =
+ {
+ "pthread_create",
+ /* libstdc++ */
+ "_ZNSt6thread15_M_start_threadESt10shared_ptrINS_10_Impl_baseEE",
+ /* librt */
+ "aio_init", "aio_read", "aio_write", "aio_fsync", "lio_listio",
+ "mq_notify", "create_timer",
+ /* libanl */
+ "getaddrinfo_a",
+ /* libgomp */
+ "GOMP_parallel",
+ "GOMP_parallel_start",
+ "GOMP_parallel_loop_static",
+ "GOMP_parallel_loop_static_start",
+ "GOMP_parallel_loop_dynamic",
+ "GOMP_parallel_loop_dynamic_start",
+ "GOMP_parallel_loop_guided",
+ "GOMP_parallel_loop_guided_start",
+ "GOMP_parallel_loop_runtime",
+ "GOMP_parallel_loop_runtime_start",
+ "GOMP_parallel_sections",
+ "GOMP_parallel_sections_start",
+ /* libgo */
+ "__go_go",
+ };
+ unsigned i;
+
+ for (i = 0; i < sizeof (thread_starter)/ sizeof (thread_starter[0]); i++)
+ {
+ struct elf_link_hash_entry *h;
+ h = elf_link_hash_lookup (&htab->elf, thread_starter[i],
+ FALSE, FALSE, TRUE);
+ htab->params->plt_thread_safe = h != NULL && h->ref_regular;
+ if (htab->params->plt_thread_safe)
+ break;
+ }
+ }
+ stubs_always_before_branch = htab->params->group_size < 0;
+ if (htab->params->group_size < 0)
+ stub_group_size = -htab->params->group_size;
+ else
+ stub_group_size = htab->params->group_size;
+
+ group_sections (htab, stub_group_size, stubs_always_before_branch);
+
+ while (1)
+ {
+ bfd *input_bfd;
+ unsigned int bfd_indx;
+ asection *stub_sec;
+
+ htab->stub_iteration += 1;
+
+ for (input_bfd = info->input_bfds, bfd_indx = 0;
+ input_bfd != NULL;
+ input_bfd = input_bfd->link.next, bfd_indx++)
+ {
+ Elf_Internal_Shdr *symtab_hdr;
+ asection *section;
+ Elf_Internal_Sym *local_syms = NULL;
+
+ if (!is_ppc64_elf (input_bfd))
+ continue;
+
+ /* We'll need the symbol table in a second. */
+ symtab_hdr = &elf_symtab_hdr (input_bfd);
+ if (symtab_hdr->sh_info == 0)
+ continue;
+
+ /* Walk over each section attached to the input bfd. */
+ for (section = input_bfd->sections;
+ section != NULL;
+ section = section->next)
+ {
+ Elf_Internal_Rela *internal_relocs, *irelaend, *irela;
+
+ /* If there aren't any relocs, then there's nothing more
+ to do. */
+ if ((section->flags & SEC_RELOC) == 0
+ || (section->flags & SEC_ALLOC) == 0
+ || (section->flags & SEC_LOAD) == 0
+ || (section->flags & SEC_CODE) == 0
+ || section->reloc_count == 0)
+ continue;
+
+ /* If this section is a link-once section that will be
+ discarded, then don't create any stubs. */
+ if (section->output_section == NULL
+ || section->output_section->owner != info->output_bfd)
+ continue;
+
+ /* Get the relocs. */
+ internal_relocs
+ = _bfd_elf_link_read_relocs (input_bfd, section, NULL, NULL,
+ info->keep_memory);
+ if (internal_relocs == NULL)
+ goto error_ret_free_local;
+
+ /* Now examine each relocation. */
+ irela = internal_relocs;
+ irelaend = irela + section->reloc_count;
+ for (; irela < irelaend; irela++)
+ {
+ enum elf_ppc64_reloc_type r_type;
+ unsigned int r_indx;
+ enum ppc_stub_type stub_type;
+ struct ppc_stub_hash_entry *stub_entry;
+ asection *sym_sec, *code_sec;
+ bfd_vma sym_value, code_value;
+ bfd_vma destination;
+ unsigned long local_off;
+ bfd_boolean ok_dest;
+ struct ppc_link_hash_entry *hash;
+ struct ppc_link_hash_entry *fdh;
+ struct elf_link_hash_entry *h;
+ Elf_Internal_Sym *sym;
+ char *stub_name;
+ const asection *id_sec;
+ struct _opd_sec_data *opd;
+ struct plt_entry *plt_ent;
+
+ r_type = ELF64_R_TYPE (irela->r_info);
+ r_indx = ELF64_R_SYM (irela->r_info);
+
+ if (r_type >= R_PPC64_max)
+ {
+ bfd_set_error (bfd_error_bad_value);
+ goto error_ret_free_internal;
+ }
+
+ /* Only look for stubs on branch instructions. */
+ if (r_type != R_PPC64_REL24
+ && r_type != R_PPC64_REL14
+ && r_type != R_PPC64_REL14_BRTAKEN
+ && r_type != R_PPC64_REL14_BRNTAKEN)
+ continue;
+
+ /* Now determine the call target, its name, value,
+ section. */
+ if (!get_sym_h (&h, &sym, &sym_sec, NULL, &local_syms,
+ r_indx, input_bfd))
+ goto error_ret_free_internal;
+ hash = (struct ppc_link_hash_entry *) h;
+
+ ok_dest = FALSE;
+ fdh = NULL;
+ sym_value = 0;
+ if (hash == NULL)
+ {
+ sym_value = sym->st_value;
+ ok_dest = TRUE;
+ }
+ else if (hash->elf.root.type == bfd_link_hash_defined
+ || hash->elf.root.type == bfd_link_hash_defweak)
+ {
+ sym_value = hash->elf.root.u.def.value;
+ if (sym_sec->output_section != NULL)
+ ok_dest = TRUE;
+ }
+ else if (hash->elf.root.type == bfd_link_hash_undefweak
+ || hash->elf.root.type == bfd_link_hash_undefined)
+ {
+ /* Recognise an old ABI func code entry sym, and
+ use the func descriptor sym instead if it is
+ defined. */
+ if (hash->elf.root.root.string[0] == '.'
+ && (fdh = lookup_fdh (hash, htab)) != NULL)
+ {
+ if (fdh->elf.root.type == bfd_link_hash_defined
+ || fdh->elf.root.type == bfd_link_hash_defweak)
+ {
+ sym_sec = fdh->elf.root.u.def.section;
+ sym_value = fdh->elf.root.u.def.value;
+ if (sym_sec->output_section != NULL)
+ ok_dest = TRUE;
+ }
+ else
+ fdh = NULL;
+ }
+ }
+ else
+ {
+ bfd_set_error (bfd_error_bad_value);
+ goto error_ret_free_internal;
+ }
+
+ destination = 0;
+ local_off = 0;
+ if (ok_dest)
+ {
+ sym_value += irela->r_addend;
+ destination = (sym_value
+ + sym_sec->output_offset
+ + sym_sec->output_section->vma);
+ local_off = PPC64_LOCAL_ENTRY_OFFSET (hash
+ ? hash->elf.other
+ : sym->st_other);
+ }
+
+ code_sec = sym_sec;
+ code_value = sym_value;
+ opd = get_opd_info (sym_sec);
+ if (opd != NULL)
+ {
+ bfd_vma dest;
+
+ if (hash == NULL && opd->adjust != NULL)
+ {
+ long adjust = opd->adjust[sym_value / 8];
+ if (adjust == -1)
+ continue;
+ code_value += adjust;
+ sym_value += adjust;
+ }
+ dest = opd_entry_value (sym_sec, sym_value,
+ &code_sec, &code_value, FALSE);
+ if (dest != (bfd_vma) -1)
+ {
+ destination = dest;
+ if (fdh != NULL)
+ {
+ /* Fixup old ABI sym to point at code
+ entry. */
+ hash->elf.root.type = bfd_link_hash_defweak;
+ hash->elf.root.u.def.section = code_sec;
+ hash->elf.root.u.def.value = code_value;
+ }
+ }
+ }
+
+ /* Determine what (if any) linker stub is needed. */
+ plt_ent = NULL;
+ stub_type = ppc_type_of_stub (section, irela, &hash,
+ &plt_ent, destination,
+ local_off);
+
+ if (stub_type != ppc_stub_plt_call)
+ {
+ /* Check whether we need a TOC adjusting stub.
+ Since the linker pastes together pieces from
+ different object files when creating the
+ _init and _fini functions, it may be that a
+ call to what looks like a local sym is in
+ fact a call needing a TOC adjustment. */
+ if (code_sec != NULL
+ && code_sec->output_section != NULL
+ && (htab->stub_group[code_sec->id].toc_off
+ != htab->stub_group[section->id].toc_off)
+ && (code_sec->has_toc_reloc
+ || code_sec->makes_toc_func_call))
+ stub_type = ppc_stub_long_branch_r2off;
+ }
+
+ if (stub_type == ppc_stub_none)
+ continue;
+
+ /* __tls_get_addr calls might be eliminated. */
+ if (stub_type != ppc_stub_plt_call
+ && hash != NULL
+ && (hash == htab->tls_get_addr
+ || hash == htab->tls_get_addr_fd)
+ && section->has_tls_reloc
+ && irela != internal_relocs)
+ {
+ /* Get tls info. */
+ unsigned char *tls_mask;
+
+ if (!get_tls_mask (&tls_mask, NULL, NULL, &local_syms,
+ irela - 1, input_bfd))
+ goto error_ret_free_internal;
+ if (*tls_mask != 0)
+ continue;
+ }
+
+ if (stub_type == ppc_stub_plt_call
+ && irela + 1 < irelaend
+ && irela[1].r_offset == irela->r_offset + 4
+ && ELF64_R_TYPE (irela[1].r_info) == R_PPC64_TOCSAVE)
+ {
+ if (!tocsave_find (htab, INSERT,
+ &local_syms, irela + 1, input_bfd))
+ goto error_ret_free_internal;
+ }
+ else if (stub_type == ppc_stub_plt_call)
+ stub_type = ppc_stub_plt_call_r2save;
+
+ /* Support for grouping stub sections. */
+ id_sec = htab->stub_group[section->id].link_sec;
+
+ /* Get the name of this stub. */
+ stub_name = ppc_stub_name (id_sec, sym_sec, hash, irela);
+ if (!stub_name)
+ goto error_ret_free_internal;
+
+ stub_entry = ppc_stub_hash_lookup (&htab->stub_hash_table,
+ stub_name, FALSE, FALSE);
+ if (stub_entry != NULL)
+ {
+ /* The proper stub has already been created. */
+ free (stub_name);
+ if (stub_type == ppc_stub_plt_call_r2save)
+ stub_entry->stub_type = stub_type;
+ continue;
+ }
+
+ stub_entry = ppc_add_stub (stub_name, section, info);
+ if (stub_entry == NULL)
+ {
+ free (stub_name);
+ error_ret_free_internal:
+ if (elf_section_data (section)->relocs == NULL)
+ free (internal_relocs);
+ error_ret_free_local:
+ if (local_syms != NULL
+ && (symtab_hdr->contents
+ != (unsigned char *) local_syms))
+ free (local_syms);
+ return FALSE;
+ }
+
+ stub_entry->stub_type = stub_type;
+ if (stub_type != ppc_stub_plt_call
+ && stub_type != ppc_stub_plt_call_r2save)
+ {
+ stub_entry->target_value = code_value;
+ stub_entry->target_section = code_sec;
+ }
+ else
+ {
+ stub_entry->target_value = sym_value;
+ stub_entry->target_section = sym_sec;
+ }
+ stub_entry->h = hash;
+ stub_entry->plt_ent = plt_ent;
+ stub_entry->other = hash ? hash->elf.other : sym->st_other;
+
+ if (stub_entry->h != NULL)
+ htab->stub_globals += 1;
+ }
+
+ /* We're done with the internal relocs, free them. */
+ if (elf_section_data (section)->relocs != internal_relocs)
+ free (internal_relocs);
+ }
+
+ if (local_syms != NULL
+ && symtab_hdr->contents != (unsigned char *) local_syms)
+ {
+ if (!info->keep_memory)
+ free (local_syms);
+ else
+ symtab_hdr->contents = (unsigned char *) local_syms;
+ }
+ }
+
+ /* We may have added some stubs. Find out the new size of the
+ stub sections. */
+ for (stub_sec = htab->params->stub_bfd->sections;
+ stub_sec != NULL;
+ stub_sec = stub_sec->next)
+ if ((stub_sec->flags & SEC_LINKER_CREATED) == 0)
+ {
+ stub_sec->rawsize = stub_sec->size;
+ stub_sec->size = 0;
+ stub_sec->reloc_count = 0;
+ stub_sec->flags &= ~SEC_RELOC;
+ }
+
+ htab->brlt->size = 0;
+ htab->brlt->reloc_count = 0;
+ htab->brlt->flags &= ~SEC_RELOC;
+ if (htab->relbrlt != NULL)
+ htab->relbrlt->size = 0;
+
+ bfd_hash_traverse (&htab->stub_hash_table, ppc_size_one_stub, info);
+
+ if (info->emitrelocations
+ && htab->glink != NULL && htab->glink->size != 0)
+ {
+ htab->glink->reloc_count = 1;
+ htab->glink->flags |= SEC_RELOC;
+ }
+
+ if (htab->glink_eh_frame != NULL
+ && !bfd_is_abs_section (htab->glink_eh_frame->output_section)
+ && htab->glink_eh_frame->output_section->size != 0)
+ {
+ size_t size = 0, align;
+
+ for (stub_sec = htab->params->stub_bfd->sections;
+ stub_sec != NULL;
+ stub_sec = stub_sec->next)
+ if ((stub_sec->flags & SEC_LINKER_CREATED) == 0)
+ size += 24;
+ if (htab->glink != NULL && htab->glink->size != 0)
+ size += 24;
+ if (size != 0)
+ size += sizeof (glink_eh_frame_cie);
+ align = 1;
+ align <<= htab->glink_eh_frame->output_section->alignment_power;
+ align -= 1;
+ size = (size + align) & ~align;
+ htab->glink_eh_frame->rawsize = htab->glink_eh_frame->size;
+ htab->glink_eh_frame->size = size;
+ }
+
+ if (htab->params->plt_stub_align != 0)
+ for (stub_sec = htab->params->stub_bfd->sections;
+ stub_sec != NULL;
+ stub_sec = stub_sec->next)
+ if ((stub_sec->flags & SEC_LINKER_CREATED) == 0)
+ stub_sec->size = ((stub_sec->size
+ + (1 << htab->params->plt_stub_align) - 1)
+ & (-1 << htab->params->plt_stub_align));
+
+ for (stub_sec = htab->params->stub_bfd->sections;
+ stub_sec != NULL;
+ stub_sec = stub_sec->next)
+ if ((stub_sec->flags & SEC_LINKER_CREATED) == 0
+ && stub_sec->rawsize != stub_sec->size)
+ break;
+
+ /* Exit from this loop when no stubs have been added, and no stubs
+ have changed size. */
+ if (stub_sec == NULL
+ && (htab->glink_eh_frame == NULL
+ || htab->glink_eh_frame->rawsize == htab->glink_eh_frame->size))
+ break;
+
+ /* Ask the linker to do its stuff. */
+ (*htab->params->layout_sections_again) ();
+ }
+
+ if (htab->glink_eh_frame != NULL
+ && htab->glink_eh_frame->size != 0)
+ {
+ bfd_vma val;
+ bfd_byte *p, *last_fde;
+ size_t last_fde_len, size, align, pad;
+ asection *stub_sec;
+
+ p = bfd_zalloc (htab->glink_eh_frame->owner, htab->glink_eh_frame->size);
+ if (p == NULL)
+ return FALSE;
+ htab->glink_eh_frame->contents = p;
+ last_fde = p;
+
+ memcpy (p, glink_eh_frame_cie, sizeof (glink_eh_frame_cie));
+ /* CIE length (rewrite in case little-endian). */
+ last_fde_len = sizeof (glink_eh_frame_cie) - 4;
+ bfd_put_32 (htab->elf.dynobj, last_fde_len, p);
+ p += sizeof (glink_eh_frame_cie);
+
+ for (stub_sec = htab->params->stub_bfd->sections;
+ stub_sec != NULL;
+ stub_sec = stub_sec->next)
+ if ((stub_sec->flags & SEC_LINKER_CREATED) == 0)
+ {
+ last_fde = p;
+ last_fde_len = 20;
+ /* FDE length. */
+ bfd_put_32 (htab->elf.dynobj, 20, p);
+ p += 4;
+ /* CIE pointer. */
+ val = p - htab->glink_eh_frame->contents;
+ bfd_put_32 (htab->elf.dynobj, val, p);
+ p += 4;
+ /* Offset to stub section, written later. */
+ p += 4;
+ /* stub section size. */
+ bfd_put_32 (htab->elf.dynobj, stub_sec->size, p);
+ p += 4;
+ /* Augmentation. */
+ p += 1;
+ /* Pad. */
+ p += 7;
+ }
+ if (htab->glink != NULL && htab->glink->size != 0)
+ {
+ last_fde = p;
+ last_fde_len = 20;
+ /* FDE length. */
+ bfd_put_32 (htab->elf.dynobj, 20, p);
+ p += 4;
+ /* CIE pointer. */
+ val = p - htab->glink_eh_frame->contents;
+ bfd_put_32 (htab->elf.dynobj, val, p);
+ p += 4;
+ /* Offset to .glink, written later. */
+ p += 4;
+ /* .glink size. */
+ bfd_put_32 (htab->elf.dynobj, htab->glink->size - 8, p);
+ p += 4;
+ /* Augmentation. */
+ p += 1;
+
+ *p++ = DW_CFA_advance_loc + 1;
+ *p++ = DW_CFA_register;
+ *p++ = 65;
+ *p++ = 12;
+ *p++ = DW_CFA_advance_loc + 4;
+ *p++ = DW_CFA_restore_extended;
+ *p++ = 65;
+ }
+ /* Subsume any padding into the last FDE if user .eh_frame
+ sections are aligned more than glink_eh_frame. Otherwise any
+ zero padding will be seen as a terminator. */
+ size = p - htab->glink_eh_frame->contents;
+ align = 1;
+ align <<= htab->glink_eh_frame->output_section->alignment_power;
+ align -= 1;
+ pad = ((size + align) & ~align) - size;
+ htab->glink_eh_frame->size = size + pad;
+ bfd_put_32 (htab->elf.dynobj, last_fde_len + pad, last_fde);
+ }
+
+ maybe_strip_output (info, htab->brlt);
+ if (htab->glink_eh_frame != NULL)
+ maybe_strip_output (info, htab->glink_eh_frame);
+
+ return TRUE;
+}
+
+/* Called after we have determined section placement. If sections
+ move, we'll be called again. Provide a value for TOCstart. */
+
+bfd_vma
+ppc64_elf_set_toc (struct bfd_link_info *info, bfd *obfd)
+{
+ asection *s;
+ bfd_vma TOCstart;
+
+ /* The TOC consists of sections .got, .toc, .tocbss, .plt in that
+ order. The TOC starts where the first of these sections starts. */
+ s = bfd_get_section_by_name (obfd, ".got");
+ if (s == NULL || (s->flags & SEC_EXCLUDE) != 0)
+ s = bfd_get_section_by_name (obfd, ".toc");
+ if (s == NULL || (s->flags & SEC_EXCLUDE) != 0)
+ s = bfd_get_section_by_name (obfd, ".tocbss");
+ if (s == NULL || (s->flags & SEC_EXCLUDE) != 0)
+ s = bfd_get_section_by_name (obfd, ".plt");
+ if (s == NULL || (s->flags & SEC_EXCLUDE) != 0)
+ {
+ /* This may happen for
+ o references to TOC base (SYM@toc / TOC[tc0]) without a
+ .toc directive
+ o bad linker script
+ o --gc-sections and empty TOC sections
+
+ FIXME: Warn user? */
+
+ /* Look for a likely section. We probably won't even be
+ using TOCstart. */
+ for (s = obfd->sections; s != NULL; s = s->next)
+ if ((s->flags & (SEC_ALLOC | SEC_SMALL_DATA | SEC_READONLY
+ | SEC_EXCLUDE))
+ == (SEC_ALLOC | SEC_SMALL_DATA))
+ break;
+ if (s == NULL)
+ for (s = obfd->sections; s != NULL; s = s->next)
+ if ((s->flags & (SEC_ALLOC | SEC_SMALL_DATA | SEC_EXCLUDE))
+ == (SEC_ALLOC | SEC_SMALL_DATA))
+ break;
+ if (s == NULL)
+ for (s = obfd->sections; s != NULL; s = s->next)
+ if ((s->flags & (SEC_ALLOC | SEC_READONLY | SEC_EXCLUDE))
+ == SEC_ALLOC)
+ break;
+ if (s == NULL)
+ for (s = obfd->sections; s != NULL; s = s->next)
+ if ((s->flags & (SEC_ALLOC | SEC_EXCLUDE)) == SEC_ALLOC)
+ break;
+ }
+
+ TOCstart = 0;
+ if (s != NULL)
+ TOCstart = s->output_section->vma + s->output_offset;
+
+ _bfd_set_gp_value (obfd, TOCstart);
+
+ if (info != NULL && s != NULL)
+ {
+ struct ppc_link_hash_table *htab = ppc_hash_table (info);
+
+ if (htab != NULL)
+ {
+ if (htab->elf.hgot != NULL)
+ {
+ htab->elf.hgot->root.u.def.value = TOC_BASE_OFF;
+ htab->elf.hgot->root.u.def.section = s;
+ }
+ }
+ else
+ {
+ struct bfd_link_hash_entry *bh = NULL;
+ _bfd_generic_link_add_one_symbol (info, obfd, ".TOC.", BSF_GLOBAL,
+ s, TOC_BASE_OFF, NULL, FALSE,
+ FALSE, &bh);
+ }
+ }
+ return TOCstart;
+}
+
+/* Called via elf_link_hash_traverse from ppc64_elf_build_stubs to
+ write out any global entry stubs. */
+
+static bfd_boolean
+build_global_entry_stubs (struct elf_link_hash_entry *h, void *inf)
+{
+ struct bfd_link_info *info;
+ struct ppc_link_hash_table *htab;
+ struct plt_entry *pent;
+ asection *s;
+
+ if (h->root.type == bfd_link_hash_indirect)
+ return TRUE;
+
+ if (!h->pointer_equality_needed)
+ return TRUE;
+
+ if (h->def_regular)
+ return TRUE;
+
+ info = inf;
+ htab = ppc_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ s = htab->glink;
+ for (pent = h->plt.plist; pent != NULL; pent = pent->next)
+ if (pent->plt.offset != (bfd_vma) -1
+ && pent->addend == 0)
+ {
+ bfd_byte *p;
+ asection *plt;
+ bfd_vma off;
+
+ p = s->contents + h->root.u.def.value;
+ plt = htab->elf.splt;
+ if (!htab->elf.dynamic_sections_created
+ || h->dynindx == -1)
+ plt = htab->elf.iplt;
+ off = pent->plt.offset + plt->output_offset + plt->output_section->vma;
+ off -= h->root.u.def.value + s->output_offset + s->output_section->vma;
+
+ if (off + 0x80008000 > 0xffffffff || (off & 3) != 0)
+ {
+ info->callbacks->einfo
+ (_("%P: linkage table error against `%T'\n"),
+ h->root.root.string);
+ bfd_set_error (bfd_error_bad_value);
+ htab->stub_error = TRUE;
+ }
+
+ htab->stub_count[ppc_stub_global_entry - 1] += 1;
+ if (htab->params->emit_stub_syms)
+ {
+ size_t len = strlen (h->root.root.string);
+ char *name = bfd_malloc (sizeof "12345678.global_entry." + len);
+
+ if (name == NULL)
+ return FALSE;
+
+ sprintf (name, "%08x.global_entry.%s", s->id, h->root.root.string);
+ h = elf_link_hash_lookup (&htab->elf, name, TRUE, FALSE, FALSE);
+ if (h == NULL)
+ return FALSE;
+ if (h->root.type == bfd_link_hash_new)
+ {
+ h->root.type = bfd_link_hash_defined;
+ h->root.u.def.section = s;
+ h->root.u.def.value = p - s->contents;
+ h->ref_regular = 1;
+ h->def_regular = 1;
+ h->ref_regular_nonweak = 1;
+ h->forced_local = 1;
+ h->non_elf = 0;
+ }
+ }
+
+ if (PPC_HA (off) != 0)
+ {
+ bfd_put_32 (s->owner, ADDIS_R12_R12 | PPC_HA (off), p);
+ p += 4;
+ }
+ bfd_put_32 (s->owner, LD_R12_0R12 | PPC_LO (off), p);
+ p += 4;
+ bfd_put_32 (s->owner, MTCTR_R12, p);
+ p += 4;
+ bfd_put_32 (s->owner, BCTR, p);
+ break;
+ }
+ return TRUE;
+}
+
+/* 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 function is called via gldelf64ppc_finish. */
+
+bfd_boolean
+ppc64_elf_build_stubs (struct bfd_link_info *info,
+ char **stats)
+{
+ struct ppc_link_hash_table *htab = ppc_hash_table (info);
+ asection *stub_sec;
+ bfd_byte *p;
+ int stub_sec_count = 0;
+
+ if (htab == NULL)
+ return FALSE;
+
+ /* Allocate memory to hold the linker stubs. */
+ for (stub_sec = htab->params->stub_bfd->sections;
+ stub_sec != NULL;
+ stub_sec = stub_sec->next)
+ if ((stub_sec->flags & SEC_LINKER_CREATED) == 0
+ && stub_sec->size != 0)
+ {
+ stub_sec->contents = bfd_zalloc (htab->params->stub_bfd, stub_sec->size);
+ if (stub_sec->contents == NULL)
+ return FALSE;
+ /* We want to check that built size is the same as calculated
+ size. rawsize is a convenient location to use. */
+ stub_sec->rawsize = stub_sec->size;
+ stub_sec->size = 0;
+ }
+
+ if (htab->glink != NULL && htab->glink->size != 0)
+ {
+ unsigned int indx;
+ bfd_vma plt0;
+
+ /* Build the .glink plt call stub. */
+ if (htab->params->emit_stub_syms)
+ {
+ struct elf_link_hash_entry *h;
+ h = elf_link_hash_lookup (&htab->elf, "__glink_PLTresolve",
+ TRUE, FALSE, FALSE);
+ if (h == NULL)
+ return FALSE;
+ if (h->root.type == bfd_link_hash_new)
+ {
+ h->root.type = bfd_link_hash_defined;
+ h->root.u.def.section = htab->glink;
+ h->root.u.def.value = 8;
+ h->ref_regular = 1;
+ h->def_regular = 1;
+ h->ref_regular_nonweak = 1;
+ h->forced_local = 1;
+ h->non_elf = 0;
+ }
+ }
+ plt0 = (htab->elf.splt->output_section->vma
+ + htab->elf.splt->output_offset
+ - 16);
+ if (info->emitrelocations)
+ {
+ Elf_Internal_Rela *r = get_relocs (htab->glink, 1);
+ if (r == NULL)
+ return FALSE;
+ r->r_offset = (htab->glink->output_offset
+ + htab->glink->output_section->vma);
+ r->r_info = ELF64_R_INFO (0, R_PPC64_REL64);
+ r->r_addend = plt0;
+ }
+ p = htab->glink->contents;
+ plt0 -= htab->glink->output_section->vma + htab->glink->output_offset;
+ bfd_put_64 (htab->glink->owner, plt0, p);
+ p += 8;
+ if (htab->opd_abi)
+ {
+ bfd_put_32 (htab->glink->owner, MFLR_R12, p);
+ p += 4;
+ bfd_put_32 (htab->glink->owner, BCL_20_31, p);
+ p += 4;
+ bfd_put_32 (htab->glink->owner, MFLR_R11, p);
+ p += 4;
+ bfd_put_32 (htab->glink->owner, LD_R2_0R11 | (-16 & 0xfffc), p);
+ p += 4;
+ bfd_put_32 (htab->glink->owner, MTLR_R12, p);
+ p += 4;
+ bfd_put_32 (htab->glink->owner, ADD_R11_R2_R11, p);
+ p += 4;
+ bfd_put_32 (htab->glink->owner, LD_R12_0R11, p);
+ p += 4;
+ bfd_put_32 (htab->glink->owner, LD_R2_0R11 | 8, p);
+ p += 4;
+ bfd_put_32 (htab->glink->owner, MTCTR_R12, p);
+ p += 4;
+ bfd_put_32 (htab->glink->owner, LD_R11_0R11 | 16, p);
+ p += 4;
+ }
+ else
+ {
+ bfd_put_32 (htab->glink->owner, MFLR_R0, p);
+ p += 4;
+ bfd_put_32 (htab->glink->owner, BCL_20_31, p);
+ p += 4;
+ bfd_put_32 (htab->glink->owner, MFLR_R11, p);
+ p += 4;
+ bfd_put_32 (htab->glink->owner, LD_R2_0R11 | (-16 & 0xfffc), p);
+ p += 4;
+ bfd_put_32 (htab->glink->owner, MTLR_R0, p);
+ p += 4;
+ bfd_put_32 (htab->glink->owner, SUB_R12_R12_R11, p);
+ p += 4;
+ bfd_put_32 (htab->glink->owner, ADD_R11_R2_R11, p);
+ p += 4;
+ bfd_put_32 (htab->glink->owner, ADDI_R0_R12 | (-48 & 0xffff), p);
+ p += 4;
+ bfd_put_32 (htab->glink->owner, LD_R12_0R11, p);
+ p += 4;
+ bfd_put_32 (htab->glink->owner, SRDI_R0_R0_2, p);
+ p += 4;
+ bfd_put_32 (htab->glink->owner, MTCTR_R12, p);
+ p += 4;
+ bfd_put_32 (htab->glink->owner, LD_R11_0R11 | 8, p);
+ p += 4;
+ }
+ bfd_put_32 (htab->glink->owner, BCTR, p);
+ p += 4;
+ while (p - htab->glink->contents < GLINK_CALL_STUB_SIZE)
+ {
+ bfd_put_32 (htab->glink->owner, NOP, p);
+ p += 4;
+ }
+
+ /* Build the .glink lazy link call stubs. */
+ indx = 0;
+ while (p < htab->glink->contents + htab->glink->rawsize)
+ {
+ if (htab->opd_abi)
+ {
+ if (indx < 0x8000)
+ {
+ bfd_put_32 (htab->glink->owner, LI_R0_0 | indx, p);
+ p += 4;
+ }
+ else
+ {
+ bfd_put_32 (htab->glink->owner, LIS_R0_0 | PPC_HI (indx), p);
+ p += 4;
+ bfd_put_32 (htab->glink->owner, ORI_R0_R0_0 | PPC_LO (indx),
+ p);
+ p += 4;
+ }
+ }
+ bfd_put_32 (htab->glink->owner,
+ B_DOT | ((htab->glink->contents - p + 8) & 0x3fffffc), p);
+ indx++;
+ p += 4;
+ }
+
+ /* Build .glink global entry stubs. */
+ if (htab->glink->size > htab->glink->rawsize)
+ elf_link_hash_traverse (&htab->elf, build_global_entry_stubs, info);
+ }
+
+ if (htab->brlt != NULL && htab->brlt->size != 0)
+ {
+ htab->brlt->contents = bfd_zalloc (htab->brlt->owner,
+ htab->brlt->size);
+ if (htab->brlt->contents == NULL)
+ return FALSE;
+ }
+ if (htab->relbrlt != NULL && htab->relbrlt->size != 0)
+ {
+ htab->relbrlt->contents = bfd_zalloc (htab->relbrlt->owner,
+ htab->relbrlt->size);
+ if (htab->relbrlt->contents == NULL)
+ return FALSE;
+ }
+
+ /* Build the stubs as directed by the stub hash table. */
+ bfd_hash_traverse (&htab->stub_hash_table, ppc_build_one_stub, info);
+
+ if (htab->relbrlt != NULL)
+ htab->relbrlt->reloc_count = 0;
+
+ if (htab->params->plt_stub_align != 0)
+ for (stub_sec = htab->params->stub_bfd->sections;
+ stub_sec != NULL;
+ stub_sec = stub_sec->next)
+ if ((stub_sec->flags & SEC_LINKER_CREATED) == 0)
+ stub_sec->size = ((stub_sec->size
+ + (1 << htab->params->plt_stub_align) - 1)
+ & (-1 << htab->params->plt_stub_align));
+
+ for (stub_sec = htab->params->stub_bfd->sections;
+ stub_sec != NULL;
+ stub_sec = stub_sec->next)
+ if ((stub_sec->flags & SEC_LINKER_CREATED) == 0)
+ {
+ stub_sec_count += 1;
+ if (stub_sec->rawsize != stub_sec->size)
+ break;
+ }
+
+ /* Note that the glink_eh_frame check here is not only testing that
+ the generated size matched the calculated size but also that
+ bfd_elf_discard_info didn't make any changes to the section. */
+ if (stub_sec != NULL
+ || (htab->glink_eh_frame != NULL
+ && htab->glink_eh_frame->rawsize != htab->glink_eh_frame->size))
+ {
+ htab->stub_error = TRUE;
+ info->callbacks->einfo (_("%P: stubs don't match calculated size\n"));
+ }
+
+ if (htab->stub_error)
+ return FALSE;
+
+ if (stats != NULL)
+ {
+ *stats = bfd_malloc (500);
+ if (*stats == NULL)
+ return FALSE;
+
+ sprintf (*stats, _("linker stubs in %u group%s\n"
+ " branch %lu\n"
+ " toc adjust %lu\n"
+ " long branch %lu\n"
+ " long toc adj %lu\n"
+ " plt call %lu\n"
+ " plt call toc %lu\n"
+ " global entry %lu"),
+ stub_sec_count,
+ stub_sec_count == 1 ? "" : "s",
+ htab->stub_count[ppc_stub_long_branch - 1],
+ htab->stub_count[ppc_stub_long_branch_r2off - 1],
+ htab->stub_count[ppc_stub_plt_branch - 1],
+ htab->stub_count[ppc_stub_plt_branch_r2off - 1],
+ htab->stub_count[ppc_stub_plt_call - 1],
+ htab->stub_count[ppc_stub_plt_call_r2save - 1],
+ htab->stub_count[ppc_stub_global_entry - 1]);
+ }
+ return TRUE;
+}
+
+/* This function undoes the changes made by add_symbol_adjust. */
+
+static bfd_boolean
+undo_symbol_twiddle (struct elf_link_hash_entry *h, void *inf ATTRIBUTE_UNUSED)
+{
+ struct ppc_link_hash_entry *eh;
+
+ if (h->root.type == bfd_link_hash_indirect)
+ return TRUE;
+
+ eh = (struct ppc_link_hash_entry *) h;
+ if (eh->elf.root.type != bfd_link_hash_undefweak || !eh->was_undefined)
+ return TRUE;
+
+ eh->elf.root.type = bfd_link_hash_undefined;
+ return TRUE;
+}
+
+void
+ppc64_elf_restore_symbols (struct bfd_link_info *info)
+{
+ struct ppc_link_hash_table *htab = ppc_hash_table (info);
+
+ if (htab != NULL)
+ elf_link_hash_traverse (&htab->elf, undo_symbol_twiddle, info);
+}
+
+/* What to do when ld finds relocations against symbols defined in
+ discarded sections. */
+
+static unsigned int
+ppc64_elf_action_discarded (asection *sec)
+{
+ if (strcmp (".opd", sec->name) == 0)
+ return 0;
+
+ if (strcmp (".toc", sec->name) == 0)
+ return 0;
+
+ if (strcmp (".toc1", sec->name) == 0)
+ return 0;
+
+ return _bfd_elf_default_action_discarded (sec);
+}
+
+/* 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
+ relocatable 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 relocatable 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 bfd_boolean
+ppc64_elf_relocate_section (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)
+{
+ struct ppc_link_hash_table *htab;
+ Elf_Internal_Shdr *symtab_hdr;
+ struct elf_link_hash_entry **sym_hashes;
+ Elf_Internal_Rela *rel;
+ Elf_Internal_Rela *relend;
+ Elf_Internal_Rela outrel;
+ bfd_byte *loc;
+ struct got_entry **local_got_ents;
+ bfd_vma TOCstart;
+ bfd_boolean ret = TRUE;
+ bfd_boolean is_opd;
+ /* Assume 'at' branch hints. */
+ bfd_boolean is_isa_v2 = TRUE;
+ bfd_vma d_offset = (bfd_big_endian (output_bfd) ? 2 : 0);
+
+ /* Initialize howto table if needed. */
+ if (!ppc64_elf_howto_table[R_PPC64_ADDR32])
+ ppc_howto_init ();
+
+ htab = ppc_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ /* Don't relocate stub sections. */
+ if (input_section->owner == htab->params->stub_bfd)
+ return TRUE;
+
+ BFD_ASSERT (is_ppc64_elf (input_bfd));
+
+ local_got_ents = elf_local_got_ents (input_bfd);
+ TOCstart = elf_gp (output_bfd);
+ symtab_hdr = &elf_symtab_hdr (input_bfd);
+ sym_hashes = elf_sym_hashes (input_bfd);
+ is_opd = ppc64_elf_section_data (input_section)->sec_type == sec_opd;
+
+ rel = relocs;
+ relend = relocs + input_section->reloc_count;
+ for (; rel < relend; rel++)
+ {
+ enum elf_ppc64_reloc_type r_type;
+ bfd_vma addend;
+ bfd_reloc_status_type r;
+ Elf_Internal_Sym *sym;
+ asection *sec;
+ struct elf_link_hash_entry *h_elf;
+ struct ppc_link_hash_entry *h;
+ struct ppc_link_hash_entry *fdh;
+ const char *sym_name;
+ unsigned long r_symndx, toc_symndx;
+ bfd_vma toc_addend;
+ unsigned char tls_mask, tls_gd, tls_type;
+ unsigned char sym_type;
+ bfd_vma relocation;
+ bfd_boolean unresolved_reloc;
+ bfd_boolean warned;
+ enum { DEST_NORMAL, DEST_OPD, DEST_STUB } reloc_dest;
+ unsigned int insn;
+ unsigned int mask;
+ struct ppc_stub_hash_entry *stub_entry;
+ bfd_vma max_br_offset;
+ bfd_vma from;
+ const Elf_Internal_Rela orig_rel = *rel;
+ reloc_howto_type *howto;
+ struct reloc_howto_struct alt_howto;
+
+ r_type = ELF64_R_TYPE (rel->r_info);
+ r_symndx = ELF64_R_SYM (rel->r_info);
+
+ /* For old style R_PPC64_TOC relocs with a zero symbol, use the
+ symbol of the previous ADDR64 reloc. The symbol gives us the
+ proper TOC base to use. */
+ if (rel->r_info == ELF64_R_INFO (0, R_PPC64_TOC)
+ && rel != relocs
+ && ELF64_R_TYPE (rel[-1].r_info) == R_PPC64_ADDR64
+ && is_opd)
+ r_symndx = ELF64_R_SYM (rel[-1].r_info);
+
+ sym = NULL;
+ sec = NULL;
+ h_elf = NULL;
+ sym_name = NULL;
+ unresolved_reloc = FALSE;
+ warned = FALSE;
+
+ if (r_symndx < symtab_hdr->sh_info)
+ {
+ /* It's a local symbol. */
+ struct _opd_sec_data *opd;
+
+ sym = local_syms + r_symndx;
+ sec = local_sections[r_symndx];
+ sym_name = bfd_elf_sym_name (input_bfd, symtab_hdr, sym, sec);
+ sym_type = ELF64_ST_TYPE (sym->st_info);
+ relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
+ opd = get_opd_info (sec);
+ if (opd != NULL && opd->adjust != NULL)
+ {
+ long adjust = opd->adjust[(sym->st_value + rel->r_addend) / 8];
+ if (adjust == -1)
+ relocation = 0;
+ else
+ {
+ /* If this is a relocation against the opd section sym
+ and we have edited .opd, adjust the reloc addend so
+ that ld -r and ld --emit-relocs output is correct.
+ If it is a reloc against some other .opd symbol,
+ then the symbol value will be adjusted later. */
+ if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
+ rel->r_addend += adjust;
+ else
+ relocation += adjust;
+ }
+ }
+ }
+ else
+ {
+ bfd_boolean ignored;
+
+ RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
+ r_symndx, symtab_hdr, sym_hashes,
+ h_elf, sec, relocation,
+ unresolved_reloc, warned, ignored);
+ sym_name = h_elf->root.root.string;
+ sym_type = h_elf->type;
+ if (sec != NULL
+ && sec->owner == output_bfd
+ && strcmp (sec->name, ".opd") == 0)
+ {
+ /* This is a symbol defined in a linker script. All
+ such are defined in output sections, even those
+ defined by simple assignment from a symbol defined in
+ an input section. Transfer the symbol to an
+ appropriate input .opd section, so that a branch to
+ this symbol will be mapped to the location specified
+ by the opd entry. */
+ struct bfd_link_order *lo;
+ for (lo = sec->map_head.link_order; lo != NULL; lo = lo->next)
+ if (lo->type == bfd_indirect_link_order)
+ {
+ asection *isec = lo->u.indirect.section;
+ if (h_elf->root.u.def.value >= isec->output_offset
+ && h_elf->root.u.def.value < (isec->output_offset
+ + isec->size))
+ {
+ h_elf->root.u.def.value -= isec->output_offset;
+ h_elf->root.u.def.section = isec;
+ sec = isec;
+ break;
+ }
+ }
+ }
+ }
+ h = (struct ppc_link_hash_entry *) h_elf;
+
+ if (sec != NULL && discarded_section (sec))
+ RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+ rel, 1, relend,
+ ppc64_elf_howto_table[r_type], 0,
+ contents);
+
+ if (info->relocatable)
+ continue;
+
+ if (h != NULL && &h->elf == htab->elf.hgot)
+ {
+ relocation = (TOCstart
+ + htab->stub_group[input_section->id].toc_off);
+ sec = bfd_abs_section_ptr;
+ unresolved_reloc = FALSE;
+ }
+
+ /* TLS optimizations. Replace instruction sequences and relocs
+ based on information we collected in tls_optimize. We edit
+ RELOCS so that --emit-relocs will output something sensible
+ for the final instruction stream. */
+ tls_mask = 0;
+ tls_gd = 0;
+ toc_symndx = 0;
+ if (h != NULL)
+ tls_mask = h->tls_mask;
+ else if (local_got_ents != NULL)
+ {
+ struct plt_entry **local_plt = (struct plt_entry **)
+ (local_got_ents + symtab_hdr->sh_info);
+ unsigned char *lgot_masks = (unsigned char *)
+ (local_plt + symtab_hdr->sh_info);
+ tls_mask = lgot_masks[r_symndx];
+ }
+ if (tls_mask == 0
+ && (r_type == R_PPC64_TLS
+ || r_type == R_PPC64_TLSGD
+ || r_type == R_PPC64_TLSLD))
+ {
+ /* Check for toc tls entries. */
+ unsigned char *toc_tls;
+
+ if (!get_tls_mask (&toc_tls, &toc_symndx, &toc_addend,
+ &local_syms, rel, input_bfd))
+ return FALSE;
+
+ if (toc_tls)
+ tls_mask = *toc_tls;
+ }
+
+ /* Check that tls relocs are used with tls syms, and non-tls
+ relocs are used with non-tls syms. */
+ if (r_symndx != STN_UNDEF
+ && r_type != R_PPC64_NONE
+ && (h == NULL
+ || h->elf.root.type == bfd_link_hash_defined
+ || h->elf.root.type == bfd_link_hash_defweak)
+ && (IS_PPC64_TLS_RELOC (r_type)
+ != (sym_type == STT_TLS
+ || (sym_type == STT_SECTION
+ && (sec->flags & SEC_THREAD_LOCAL) != 0))))
+ {
+ if (tls_mask != 0
+ && (r_type == R_PPC64_TLS
+ || r_type == R_PPC64_TLSGD
+ || r_type == R_PPC64_TLSLD))
+ /* R_PPC64_TLS is OK against a symbol in the TOC. */
+ ;
+ else
+ info->callbacks->einfo
+ (!IS_PPC64_TLS_RELOC (r_type)
+ ? _("%P: %H: %s used with TLS symbol `%T'\n")
+ : _("%P: %H: %s used with non-TLS symbol `%T'\n"),
+ input_bfd, input_section, rel->r_offset,
+ ppc64_elf_howto_table[r_type]->name,
+ sym_name);
+ }
+
+ /* Ensure reloc mapping code below stays sane. */
+ if (R_PPC64_TOC16_LO_DS != R_PPC64_TOC16_DS + 1
+ || R_PPC64_TOC16_LO != R_PPC64_TOC16 + 1
+ || (R_PPC64_GOT_TLSLD16 & 3) != (R_PPC64_GOT_TLSGD16 & 3)
+ || (R_PPC64_GOT_TLSLD16_LO & 3) != (R_PPC64_GOT_TLSGD16_LO & 3)
+ || (R_PPC64_GOT_TLSLD16_HI & 3) != (R_PPC64_GOT_TLSGD16_HI & 3)
+ || (R_PPC64_GOT_TLSLD16_HA & 3) != (R_PPC64_GOT_TLSGD16_HA & 3)
+ || (R_PPC64_GOT_TLSLD16 & 3) != (R_PPC64_GOT_TPREL16_DS & 3)
+ || (R_PPC64_GOT_TLSLD16_LO & 3) != (R_PPC64_GOT_TPREL16_LO_DS & 3)
+ || (R_PPC64_GOT_TLSLD16_HI & 3) != (R_PPC64_GOT_TPREL16_HI & 3)
+ || (R_PPC64_GOT_TLSLD16_HA & 3) != (R_PPC64_GOT_TPREL16_HA & 3))
+ abort ();
+
+ switch (r_type)
+ {
+ default:
+ break;
+
+ case R_PPC64_LO_DS_OPT:
+ insn = bfd_get_32 (output_bfd, contents + rel->r_offset - d_offset);
+ if ((insn & (0x3f << 26)) != 58u << 26)
+ abort ();
+ insn += (14u << 26) - (58u << 26);
+ bfd_put_32 (output_bfd, insn, contents + rel->r_offset - d_offset);
+ r_type = R_PPC64_TOC16_LO;
+ rel->r_info = ELF64_R_INFO (r_symndx, r_type);
+ break;
+
+ case R_PPC64_TOC16:
+ case R_PPC64_TOC16_LO:
+ case R_PPC64_TOC16_DS:
+ case R_PPC64_TOC16_LO_DS:
+ {
+ /* Check for toc tls entries. */
+ unsigned char *toc_tls;
+ int retval;
+
+ retval = get_tls_mask (&toc_tls, &toc_symndx, &toc_addend,
+ &local_syms, rel, input_bfd);
+ if (retval == 0)
+ return FALSE;
+
+ if (toc_tls)
+ {
+ tls_mask = *toc_tls;
+ if (r_type == R_PPC64_TOC16_DS
+ || r_type == R_PPC64_TOC16_LO_DS)
+ {
+ if (tls_mask != 0
+ && (tls_mask & (TLS_DTPREL | TLS_TPREL)) == 0)
+ goto toctprel;
+ }
+ else
+ {
+ /* If we found a GD reloc pair, then we might be
+ doing a GD->IE transition. */
+ if (retval == 2)
+ {
+ tls_gd = TLS_TPRELGD;
+ if (tls_mask != 0 && (tls_mask & TLS_GD) == 0)
+ goto tls_ldgd_opt;
+ }
+ else if (retval == 3)
+ {
+ if (tls_mask != 0 && (tls_mask & TLS_LD) == 0)
+ goto tls_ldgd_opt;
+ }
+ }
+ }
+ }
+ break;
+
+ case R_PPC64_GOT_TPREL16_HI:
+ case R_PPC64_GOT_TPREL16_HA:
+ if (tls_mask != 0
+ && (tls_mask & TLS_TPREL) == 0)
+ {
+ rel->r_offset -= d_offset;
+ bfd_put_32 (output_bfd, NOP, contents + rel->r_offset);
+ r_type = R_PPC64_NONE;
+ rel->r_info = ELF64_R_INFO (r_symndx, r_type);
+ }
+ break;
+
+ case R_PPC64_GOT_TPREL16_DS:
+ case R_PPC64_GOT_TPREL16_LO_DS:
+ if (tls_mask != 0
+ && (tls_mask & TLS_TPREL) == 0)
+ {
+ toctprel:
+ insn = bfd_get_32 (output_bfd, contents + rel->r_offset - d_offset);
+ insn &= 31 << 21;
+ insn |= 0x3c0d0000; /* addis 0,13,0 */
+ bfd_put_32 (output_bfd, insn, contents + rel->r_offset - d_offset);
+ r_type = R_PPC64_TPREL16_HA;
+ if (toc_symndx != 0)
+ {
+ rel->r_info = ELF64_R_INFO (toc_symndx, r_type);
+ rel->r_addend = toc_addend;
+ /* We changed the symbol. Start over in order to
+ get h, sym, sec etc. right. */
+ rel--;
+ continue;
+ }
+ else
+ rel->r_info = ELF64_R_INFO (r_symndx, r_type);
+ }
+ break;
+
+ case R_PPC64_TLS:
+ if (tls_mask != 0
+ && (tls_mask & TLS_TPREL) == 0)
+ {
+ insn = bfd_get_32 (output_bfd, contents + rel->r_offset);
+ insn = _bfd_elf_ppc_at_tls_transform (insn, 13);
+ if (insn == 0)
+ abort ();
+ bfd_put_32 (output_bfd, insn, contents + rel->r_offset);
+ /* Was PPC64_TLS which sits on insn boundary, now
+ PPC64_TPREL16_LO which is at low-order half-word. */
+ rel->r_offset += d_offset;
+ r_type = R_PPC64_TPREL16_LO;
+ if (toc_symndx != 0)
+ {
+ rel->r_info = ELF64_R_INFO (toc_symndx, r_type);
+ rel->r_addend = toc_addend;
+ /* We changed the symbol. Start over in order to
+ get h, sym, sec etc. right. */
+ rel--;
+ continue;
+ }
+ else
+ rel->r_info = ELF64_R_INFO (r_symndx, r_type);
+ }
+ break;
+
+ case R_PPC64_GOT_TLSGD16_HI:
+ case R_PPC64_GOT_TLSGD16_HA:
+ tls_gd = TLS_TPRELGD;
+ if (tls_mask != 0 && (tls_mask & TLS_GD) == 0)
+ goto tls_gdld_hi;
+ break;
+
+ case R_PPC64_GOT_TLSLD16_HI:
+ case R_PPC64_GOT_TLSLD16_HA:
+ if (tls_mask != 0 && (tls_mask & TLS_LD) == 0)
+ {
+ tls_gdld_hi:
+ if ((tls_mask & tls_gd) != 0)
+ r_type = (((r_type - (R_PPC64_GOT_TLSGD16 & 3)) & 3)
+ + R_PPC64_GOT_TPREL16_DS);
+ else
+ {
+ rel->r_offset -= d_offset;
+ bfd_put_32 (output_bfd, NOP, contents + rel->r_offset);
+ r_type = R_PPC64_NONE;
+ }
+ rel->r_info = ELF64_R_INFO (r_symndx, r_type);
+ }
+ break;
+
+ case R_PPC64_GOT_TLSGD16:
+ case R_PPC64_GOT_TLSGD16_LO:
+ tls_gd = TLS_TPRELGD;
+ if (tls_mask != 0 && (tls_mask & TLS_GD) == 0)
+ goto tls_ldgd_opt;
+ break;
+
+ case R_PPC64_GOT_TLSLD16:
+ case R_PPC64_GOT_TLSLD16_LO:
+ if (tls_mask != 0 && (tls_mask & TLS_LD) == 0)
+ {
+ unsigned int insn1, insn2, insn3;
+ bfd_vma offset;
+
+ tls_ldgd_opt:
+ offset = (bfd_vma) -1;
+ /* If not using the newer R_PPC64_TLSGD/LD to mark
+ __tls_get_addr calls, we must trust that the call
+ stays with its arg setup insns, ie. that the next
+ reloc is the __tls_get_addr call associated with
+ the current reloc. Edit both insns. */
+ if (input_section->has_tls_get_addr_call
+ && rel + 1 < relend
+ && branch_reloc_hash_match (input_bfd, rel + 1,
+ htab->tls_get_addr,
+ htab->tls_get_addr_fd))
+ offset = rel[1].r_offset;
+ if ((tls_mask & tls_gd) != 0)
+ {
+ /* IE */
+ insn1 = bfd_get_32 (output_bfd,
+ contents + rel->r_offset - d_offset);
+ insn1 &= (1 << 26) - (1 << 2);
+ insn1 |= 58 << 26; /* ld */
+ insn2 = 0x7c636a14; /* add 3,3,13 */
+ if (offset != (bfd_vma) -1)
+ rel[1].r_info = ELF64_R_INFO (STN_UNDEF, R_PPC64_NONE);
+ if ((tls_mask & TLS_EXPLICIT) == 0)
+ r_type = (((r_type - (R_PPC64_GOT_TLSGD16 & 3)) & 3)
+ + R_PPC64_GOT_TPREL16_DS);
+ else
+ r_type += R_PPC64_TOC16_DS - R_PPC64_TOC16;
+ rel->r_info = ELF64_R_INFO (r_symndx, r_type);
+ }
+ else
+ {
+ /* LE */
+ insn1 = 0x3c6d0000; /* addis 3,13,0 */
+ insn2 = 0x38630000; /* addi 3,3,0 */
+ if (tls_gd == 0)
+ {
+ /* Was an LD reloc. */
+ if (toc_symndx)
+ sec = local_sections[toc_symndx];
+ for (r_symndx = 0;
+ r_symndx < symtab_hdr->sh_info;
+ r_symndx++)
+ if (local_sections[r_symndx] == sec)
+ break;
+ if (r_symndx >= symtab_hdr->sh_info)
+ r_symndx = STN_UNDEF;
+ rel->r_addend = htab->elf.tls_sec->vma + DTP_OFFSET;
+ if (r_symndx != STN_UNDEF)
+ rel->r_addend -= (local_syms[r_symndx].st_value
+ + sec->output_offset
+ + sec->output_section->vma);
+ }
+ else if (toc_symndx != 0)
+ {
+ r_symndx = toc_symndx;
+ rel->r_addend = toc_addend;
+ }
+ r_type = R_PPC64_TPREL16_HA;
+ rel->r_info = ELF64_R_INFO (r_symndx, r_type);
+ if (offset != (bfd_vma) -1)
+ {
+ rel[1].r_info = ELF64_R_INFO (r_symndx,
+ R_PPC64_TPREL16_LO);
+ rel[1].r_offset = offset + d_offset;
+ rel[1].r_addend = rel->r_addend;
+ }
+ }
+ bfd_put_32 (output_bfd, insn1,
+ contents + rel->r_offset - d_offset);
+ if (offset != (bfd_vma) -1)
+ {
+ insn3 = bfd_get_32 (output_bfd,
+ contents + offset + 4);
+ if (insn3 == NOP
+ || insn3 == CROR_151515 || insn3 == CROR_313131)
+ {
+ rel[1].r_offset += 4;
+ bfd_put_32 (output_bfd, insn2, contents + offset + 4);
+ insn2 = NOP;
+ }
+ bfd_put_32 (output_bfd, insn2, contents + offset);
+ }
+ if ((tls_mask & tls_gd) == 0
+ && (tls_gd == 0 || toc_symndx != 0))
+ {
+ /* We changed the symbol. Start over in order
+ to get h, sym, sec etc. right. */
+ rel--;
+ continue;
+ }
+ }
+ break;
+
+ case R_PPC64_TLSGD:
+ if (tls_mask != 0 && (tls_mask & TLS_GD) == 0)
+ {
+ unsigned int insn2, insn3;
+ bfd_vma offset = rel->r_offset;
+
+ if ((tls_mask & TLS_TPRELGD) != 0)
+ {
+ /* IE */
+ r_type = R_PPC64_NONE;
+ insn2 = 0x7c636a14; /* add 3,3,13 */
+ }
+ else
+ {
+ /* LE */
+ if (toc_symndx != 0)
+ {
+ r_symndx = toc_symndx;
+ rel->r_addend = toc_addend;
+ }
+ r_type = R_PPC64_TPREL16_LO;
+ rel->r_offset = offset + d_offset;
+ insn2 = 0x38630000; /* addi 3,3,0 */
+ }
+ rel->r_info = ELF64_R_INFO (r_symndx, r_type);
+ /* Zap the reloc on the _tls_get_addr call too. */
+ BFD_ASSERT (offset == rel[1].r_offset);
+ rel[1].r_info = ELF64_R_INFO (STN_UNDEF, R_PPC64_NONE);
+ insn3 = bfd_get_32 (output_bfd,
+ contents + offset + 4);
+ if (insn3 == NOP
+ || insn3 == CROR_151515 || insn3 == CROR_313131)
+ {
+ rel->r_offset += 4;
+ bfd_put_32 (output_bfd, insn2, contents + offset + 4);
+ insn2 = NOP;
+ }
+ bfd_put_32 (output_bfd, insn2, contents + offset);
+ if ((tls_mask & TLS_TPRELGD) == 0 && toc_symndx != 0)
+ {
+ rel--;
+ continue;
+ }
+ }
+ break;
+
+ case R_PPC64_TLSLD:
+ if (tls_mask != 0 && (tls_mask & TLS_LD) == 0)
+ {
+ unsigned int insn2, insn3;
+ bfd_vma offset = rel->r_offset;
+
+ if (toc_symndx)
+ sec = local_sections[toc_symndx];
+ for (r_symndx = 0;
+ r_symndx < symtab_hdr->sh_info;
+ r_symndx++)
+ if (local_sections[r_symndx] == sec)
+ break;
+ if (r_symndx >= symtab_hdr->sh_info)
+ r_symndx = STN_UNDEF;
+ rel->r_addend = htab->elf.tls_sec->vma + DTP_OFFSET;
+ if (r_symndx != STN_UNDEF)
+ rel->r_addend -= (local_syms[r_symndx].st_value
+ + sec->output_offset
+ + sec->output_section->vma);
+
+ r_type = R_PPC64_TPREL16_LO;
+ rel->r_info = ELF64_R_INFO (r_symndx, r_type);
+ rel->r_offset = offset + d_offset;
+ /* Zap the reloc on the _tls_get_addr call too. */
+ BFD_ASSERT (offset == rel[1].r_offset);
+ rel[1].r_info = ELF64_R_INFO (STN_UNDEF, R_PPC64_NONE);
+ insn2 = 0x38630000; /* addi 3,3,0 */
+ insn3 = bfd_get_32 (output_bfd,
+ contents + offset + 4);
+ if (insn3 == NOP
+ || insn3 == CROR_151515 || insn3 == CROR_313131)
+ {
+ rel->r_offset += 4;
+ bfd_put_32 (output_bfd, insn2, contents + offset + 4);
+ insn2 = NOP;
+ }
+ bfd_put_32 (output_bfd, insn2, contents + offset);
+ rel--;
+ continue;
+ }
+ break;
+
+ case R_PPC64_DTPMOD64:
+ if (rel + 1 < relend
+ && rel[1].r_info == ELF64_R_INFO (r_symndx, R_PPC64_DTPREL64)
+ && rel[1].r_offset == rel->r_offset + 8)
+ {
+ if ((tls_mask & TLS_GD) == 0)
+ {
+ rel[1].r_info = ELF64_R_INFO (r_symndx, R_PPC64_NONE);
+ if ((tls_mask & TLS_TPRELGD) != 0)
+ r_type = R_PPC64_TPREL64;
+ else
+ {
+ bfd_put_64 (output_bfd, 1, contents + rel->r_offset);
+ r_type = R_PPC64_NONE;
+ }
+ rel->r_info = ELF64_R_INFO (r_symndx, r_type);
+ }
+ }
+ else
+ {
+ if ((tls_mask & TLS_LD) == 0)
+ {
+ bfd_put_64 (output_bfd, 1, contents + rel->r_offset);
+ r_type = R_PPC64_NONE;
+ rel->r_info = ELF64_R_INFO (r_symndx, r_type);
+ }
+ }
+ break;
+
+ case R_PPC64_TPREL64:
+ if ((tls_mask & TLS_TPREL) == 0)
+ {
+ r_type = R_PPC64_NONE;
+ rel->r_info = ELF64_R_INFO (r_symndx, r_type);
+ }
+ break;
+
+ case R_PPC64_REL16_HA:
+ /* If we are generating a non-PIC executable, edit
+ . 0: addis 2,12,.TOC.-0b@ha
+ . addi 2,2,.TOC.-0b@l
+ used by ELFv2 global entry points to set up r2, to
+ . lis 2,.TOC.@ha
+ . addi 2,2,.TOC.@l
+ if .TOC. is in range. */
+ if (!info->shared
+ && !info->traditional_format
+ && h != NULL && &h->elf == htab->elf.hgot
+ && rel + 1 < relend
+ && rel[1].r_info == ELF64_R_INFO (r_symndx, R_PPC64_REL16_LO)
+ && rel[1].r_offset == rel->r_offset + 4
+ && rel[1].r_addend == rel->r_addend + 4
+ && relocation + 0x80008000 <= 0xffffffff)
+ {
+ unsigned int insn1, insn2;
+ bfd_vma offset = rel->r_offset - d_offset;
+ insn1 = bfd_get_32 (output_bfd, contents + offset);
+ insn2 = bfd_get_32 (output_bfd, contents + offset + 4);
+ if ((insn1 & 0xffff0000) == 0x3c4c0000 /* addis 2,12 */
+ && (insn2 & 0xffff0000) == 0x38420000 /* addi 2,2 */)
+ {
+ r_type = R_PPC64_ADDR16_HA;
+ rel->r_info = ELF64_R_INFO (r_symndx, r_type);
+ rel->r_addend -= d_offset;
+ rel[1].r_info = ELF64_R_INFO (r_symndx, R_PPC64_ADDR16_LO);
+ rel[1].r_addend -= d_offset + 4;
+ bfd_put_32 (output_bfd, 0x3c400000, contents + offset);
+ }
+ }
+ break;
+ }
+
+ /* Handle other relocations that tweak non-addend part of insn. */
+ insn = 0;
+ max_br_offset = 1 << 25;
+ addend = rel->r_addend;
+ reloc_dest = DEST_NORMAL;
+ switch (r_type)
+ {
+ default:
+ break;
+
+ case R_PPC64_TOCSAVE:
+ if (relocation + addend == (rel->r_offset
+ + input_section->output_offset
+ + input_section->output_section->vma)
+ && tocsave_find (htab, NO_INSERT,
+ &local_syms, rel, input_bfd))
+ {
+ insn = bfd_get_32 (input_bfd, contents + rel->r_offset);
+ if (insn == NOP
+ || insn == CROR_151515 || insn == CROR_313131)
+ bfd_put_32 (input_bfd,
+ STD_R2_0R1 + STK_TOC (htab),
+ contents + rel->r_offset);
+ }
+ break;
+
+ /* Branch taken prediction relocations. */
+ case R_PPC64_ADDR14_BRTAKEN:
+ case R_PPC64_REL14_BRTAKEN:
+ insn = 0x01 << 21; /* 'y' or 't' bit, lowest bit of BO field. */
+ /* Fall thru. */
+
+ /* Branch not taken prediction relocations. */
+ case R_PPC64_ADDR14_BRNTAKEN:
+ case R_PPC64_REL14_BRNTAKEN:
+ insn |= bfd_get_32 (output_bfd,
+ contents + rel->r_offset) & ~(0x01 << 21);
+ /* Fall thru. */
+
+ case R_PPC64_REL14:
+ max_br_offset = 1 << 15;
+ /* Fall thru. */
+
+ case R_PPC64_REL24:
+ /* Calls to functions with a different TOC, such as calls to
+ shared objects, need to alter the TOC pointer. This is
+ done using a linkage stub. A REL24 branching to these
+ linkage stubs needs to be followed by a nop, as the nop
+ will be replaced with an instruction to restore the TOC
+ base pointer. */
+ fdh = h;
+ if (h != NULL
+ && h->oh != NULL
+ && h->oh->is_func_descriptor)
+ fdh = ppc_follow_link (h->oh);
+ stub_entry = ppc_get_stub_entry (input_section, sec, fdh, &orig_rel,
+ htab);
+ if (stub_entry != NULL
+ && (stub_entry->stub_type == ppc_stub_plt_call
+ || stub_entry->stub_type == ppc_stub_plt_call_r2save
+ || stub_entry->stub_type == ppc_stub_plt_branch_r2off
+ || stub_entry->stub_type == ppc_stub_long_branch_r2off))
+ {
+ bfd_boolean can_plt_call = FALSE;
+
+ /* All of these stubs will modify r2, so there must be a
+ branch and link followed by a nop. The nop is
+ replaced by an insn to restore r2. */
+ if (rel->r_offset + 8 <= input_section->size)
+ {
+ unsigned long br;
+
+ br = bfd_get_32 (input_bfd,
+ contents + rel->r_offset);
+ if ((br & 1) != 0)
+ {
+ unsigned long nop;
+
+ nop = bfd_get_32 (input_bfd,
+ contents + rel->r_offset + 4);
+ if (nop == NOP
+ || nop == CROR_151515 || nop == CROR_313131)
+ {
+ if (h != NULL
+ && (h == htab->tls_get_addr_fd
+ || h == htab->tls_get_addr)
+ && !htab->params->no_tls_get_addr_opt)
+ {
+ /* Special stub used, leave nop alone. */
+ }
+ else
+ bfd_put_32 (input_bfd,
+ LD_R2_0R1 + STK_TOC (htab),
+ contents + rel->r_offset + 4);
+ can_plt_call = TRUE;
+ }
+ }
+ }
+
+ if (!can_plt_call && h != NULL)
+ {
+ const char *name = h->elf.root.root.string;
+
+ if (*name == '.')
+ ++name;
+
+ if (strncmp (name, "__libc_start_main", 17) == 0
+ && (name[17] == 0 || name[17] == '@'))
+ {
+ /* Allow crt1 branch to go via a toc adjusting
+ stub. Other calls that never return could do
+ the same, if we could detect such. */
+ can_plt_call = TRUE;
+ }
+ }
+
+ if (!can_plt_call)
+ {
+ /* g++ as of 20130507 emits self-calls without a
+ following nop. This is arguably wrong since we
+ have conflicting information. On the one hand a
+ global symbol and on the other a local call
+ sequence, but don't error for this special case.
+ It isn't possible to cheaply verify we have
+ exactly such a call. Allow all calls to the same
+ section. */
+ asection *code_sec = sec;
+
+ if (get_opd_info (sec) != NULL)
+ {
+ bfd_vma off = (relocation + addend
+ - sec->output_section->vma
+ - sec->output_offset);
+
+ opd_entry_value (sec, off, &code_sec, NULL, FALSE);
+ }
+ if (code_sec == input_section)
+ can_plt_call = TRUE;
+ }
+
+ if (!can_plt_call)
+ {
+ if (stub_entry->stub_type == ppc_stub_plt_call
+ || stub_entry->stub_type == ppc_stub_plt_call_r2save)
+ info->callbacks->einfo
+ (_("%P: %H: call to `%T' lacks nop, can't restore toc; "
+ "recompile with -fPIC\n"),
+ input_bfd, input_section, rel->r_offset, sym_name);
+ else
+ info->callbacks->einfo
+ (_("%P: %H: call to `%T' lacks nop, can't restore toc; "
+ "(-mcmodel=small toc adjust stub)\n"),
+ input_bfd, input_section, rel->r_offset, sym_name);
+
+ bfd_set_error (bfd_error_bad_value);
+ ret = FALSE;
+ }
+
+ if (can_plt_call
+ && (stub_entry->stub_type == ppc_stub_plt_call
+ || stub_entry->stub_type == ppc_stub_plt_call_r2save))
+ unresolved_reloc = FALSE;
+ }
+
+ if ((stub_entry == NULL
+ || stub_entry->stub_type == ppc_stub_long_branch
+ || stub_entry->stub_type == ppc_stub_plt_branch)
+ && get_opd_info (sec) != NULL)
+ {
+ /* The branch destination is the value of the opd entry. */
+ bfd_vma off = (relocation + addend
+ - sec->output_section->vma
+ - sec->output_offset);
+ bfd_vma dest = opd_entry_value (sec, off, NULL, NULL, FALSE);
+ if (dest != (bfd_vma) -1)
+ {
+ relocation = dest;
+ addend = 0;
+ reloc_dest = DEST_OPD;
+ }
+ }
+
+ /* If the branch is out of reach we ought to have a long
+ branch stub. */
+ from = (rel->r_offset
+ + input_section->output_offset
+ + input_section->output_section->vma);
+
+ relocation += PPC64_LOCAL_ENTRY_OFFSET (fdh
+ ? fdh->elf.other
+ : sym->st_other);
+
+ if (stub_entry != NULL
+ && (stub_entry->stub_type == ppc_stub_long_branch
+ || stub_entry->stub_type == ppc_stub_plt_branch)
+ && (r_type == R_PPC64_ADDR14_BRTAKEN
+ || r_type == R_PPC64_ADDR14_BRNTAKEN
+ || (relocation + addend - from + max_br_offset
+ < 2 * max_br_offset)))
+ /* Don't use the stub if this branch is in range. */
+ stub_entry = NULL;
+
+ if (stub_entry != NULL)
+ {
+ /* Munge up the value and addend so that we call the stub
+ rather than the procedure directly. */
+ relocation = (stub_entry->stub_offset
+ + stub_entry->stub_sec->output_offset
+ + stub_entry->stub_sec->output_section->vma);
+ addend = 0;
+ reloc_dest = DEST_STUB;
+
+ if ((stub_entry->stub_type == ppc_stub_plt_call
+ || stub_entry->stub_type == ppc_stub_plt_call_r2save)
+ && (ALWAYS_EMIT_R2SAVE
+ || stub_entry->stub_type == ppc_stub_plt_call_r2save)
+ && rel + 1 < relend
+ && rel[1].r_offset == rel->r_offset + 4
+ && ELF64_R_TYPE (rel[1].r_info) == R_PPC64_TOCSAVE)
+ relocation += 4;
+ }
+
+ if (insn != 0)
+ {
+ if (is_isa_v2)
+ {
+ /* Set 'a' bit. This is 0b00010 in BO field for branch
+ on CR(BI) insns (BO == 001at or 011at), and 0b01000
+ for branch on CTR insns (BO == 1a00t or 1a01t). */
+ if ((insn & (0x14 << 21)) == (0x04 << 21))
+ insn |= 0x02 << 21;
+ else if ((insn & (0x14 << 21)) == (0x10 << 21))
+ insn |= 0x08 << 21;
+ else
+ break;
+ }
+ else
+ {
+ /* Invert 'y' bit if not the default. */
+ if ((bfd_signed_vma) (relocation + addend - from) < 0)
+ insn ^= 0x01 << 21;
+ }
+
+ bfd_put_32 (output_bfd, insn, contents + rel->r_offset);
+ }
+
+ /* NOP out calls to undefined weak functions.
+ We can thus call a weak function without first
+ checking whether the function is defined. */
+ else if (h != NULL
+ && h->elf.root.type == bfd_link_hash_undefweak
+ && h->elf.dynindx == -1
+ && r_type == R_PPC64_REL24
+ && relocation == 0
+ && addend == 0)
+ {
+ bfd_put_32 (output_bfd, NOP, contents + rel->r_offset);
+ continue;
+ }
+ break;
+ }
+
+ /* Set `addend'. */
+ tls_type = 0;
+ switch (r_type)
+ {
+ default:
+ info->callbacks->einfo
+ (_("%P: %B: unknown relocation type %d for `%T'\n"),
+ input_bfd, (int) r_type, sym_name);
+
+ bfd_set_error (bfd_error_bad_value);
+ ret = FALSE;
+ continue;
+
+ case R_PPC64_NONE:
+ case R_PPC64_TLS:
+ case R_PPC64_TLSGD:
+ case R_PPC64_TLSLD:
+ case R_PPC64_TOCSAVE:
+ case R_PPC64_GNU_VTINHERIT:
+ case R_PPC64_GNU_VTENTRY:
+ continue;
+
+ /* GOT16 relocations. Like an ADDR16 using the symbol's
+ address in the GOT as relocation value instead of the
+ symbol's value itself. Also, create a GOT entry for the
+ symbol and put the symbol value there. */
+ case R_PPC64_GOT_TLSGD16:
+ case R_PPC64_GOT_TLSGD16_LO:
+ case R_PPC64_GOT_TLSGD16_HI:
+ case R_PPC64_GOT_TLSGD16_HA:
+ tls_type = TLS_TLS | TLS_GD;
+ goto dogot;
+
+ case R_PPC64_GOT_TLSLD16:
+ case R_PPC64_GOT_TLSLD16_LO:
+ case R_PPC64_GOT_TLSLD16_HI:
+ case R_PPC64_GOT_TLSLD16_HA:
+ tls_type = TLS_TLS | TLS_LD;
+ goto dogot;
+
+ case R_PPC64_GOT_TPREL16_DS:
+ case R_PPC64_GOT_TPREL16_LO_DS:
+ case R_PPC64_GOT_TPREL16_HI:
+ case R_PPC64_GOT_TPREL16_HA:
+ tls_type = TLS_TLS | TLS_TPREL;
+ goto dogot;
+
+ case R_PPC64_GOT_DTPREL16_DS:
+ case R_PPC64_GOT_DTPREL16_LO_DS:
+ case R_PPC64_GOT_DTPREL16_HI:
+ case R_PPC64_GOT_DTPREL16_HA:
+ tls_type = TLS_TLS | TLS_DTPREL;
+ goto dogot;
+
+ case R_PPC64_GOT16:
+ case R_PPC64_GOT16_LO:
+ case R_PPC64_GOT16_HI:
+ case R_PPC64_GOT16_HA:
+ case R_PPC64_GOT16_DS:
+ case R_PPC64_GOT16_LO_DS:
+ dogot:
+ {
+ /* Relocation is to the entry for this symbol in the global
+ offset table. */
+ asection *got;
+ bfd_vma *offp;
+ bfd_vma off;
+ unsigned long indx = 0;
+ struct got_entry *ent;
+
+ if (tls_type == (TLS_TLS | TLS_LD)
+ && (h == NULL
+ || !h->elf.def_dynamic))
+ ent = ppc64_tlsld_got (input_bfd);
+ else
+ {
+
+ if (h != NULL)
+ {
+ bfd_boolean dyn = htab->elf.dynamic_sections_created;
+ if (!WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared,
+ &h->elf)
+ || (info->shared
+ && SYMBOL_REFERENCES_LOCAL (info, &h->elf)))
+ /* 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. */
+ ;
+ else
+ {
+ BFD_ASSERT (h->elf.dynindx != -1);
+ indx = h->elf.dynindx;
+ unresolved_reloc = FALSE;
+ }
+ ent = h->elf.got.glist;
+ }
+ else
+ {
+ if (local_got_ents == NULL)
+ abort ();
+ ent = local_got_ents[r_symndx];
+ }
+
+ for (; ent != NULL; ent = ent->next)
+ if (ent->addend == orig_rel.r_addend
+ && ent->owner == input_bfd
+ && ent->tls_type == tls_type)
+ break;
+ }
+
+ if (ent == NULL)
+ abort ();
+ if (ent->is_indirect)
+ ent = ent->got.ent;
+ offp = &ent->got.offset;
+ got = ppc64_elf_tdata (ent->owner)->got;
+ if (got == NULL)
+ abort ();
+
+ /* The offset must always be a multiple of 8. We use the
+ least significant bit to record whether we have already
+ processed this entry. */
+ off = *offp;
+ if ((off & 1) != 0)
+ off &= ~1;
+ else
+ {
+ /* Generate relocs for the dynamic linker, except in
+ the case of TLSLD where we'll use one entry per
+ module. */
+ asection *relgot;
+ bfd_boolean ifunc;
+
+ *offp = off | 1;
+ relgot = NULL;
+ ifunc = (h != NULL
+ ? h->elf.type == STT_GNU_IFUNC
+ : ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC);
+ if (ifunc)
+ relgot = htab->elf.irelplt;
+ else if ((info->shared || indx != 0)
+ && (h == NULL
+ || (tls_type == (TLS_TLS | TLS_LD)
+ && !h->elf.def_dynamic)
+ || ELF_ST_VISIBILITY (h->elf.other) == STV_DEFAULT
+ || h->elf.root.type != bfd_link_hash_undefweak))
+ relgot = ppc64_elf_tdata (ent->owner)->relgot;
+ if (relgot != NULL)
+ {
+ outrel.r_offset = (got->output_section->vma
+ + got->output_offset
+ + off);
+ outrel.r_addend = addend;
+ if (tls_type & (TLS_LD | TLS_GD))
+ {
+ outrel.r_addend = 0;
+ outrel.r_info = ELF64_R_INFO (indx, R_PPC64_DTPMOD64);
+ if (tls_type == (TLS_TLS | TLS_GD))
+ {
+ loc = relgot->contents;
+ loc += (relgot->reloc_count++
+ * sizeof (Elf64_External_Rela));
+ bfd_elf64_swap_reloca_out (output_bfd,
+ &outrel, loc);
+ outrel.r_offset += 8;
+ outrel.r_addend = addend;
+ outrel.r_info
+ = ELF64_R_INFO (indx, R_PPC64_DTPREL64);
+ }
+ }
+ else if (tls_type == (TLS_TLS | TLS_DTPREL))
+ outrel.r_info = ELF64_R_INFO (indx, R_PPC64_DTPREL64);
+ else if (tls_type == (TLS_TLS | TLS_TPREL))
+ outrel.r_info = ELF64_R_INFO (indx, R_PPC64_TPREL64);
+ else if (indx != 0)
+ outrel.r_info = ELF64_R_INFO (indx, R_PPC64_GLOB_DAT);
+ else
+ {
+ if (ifunc)
+ outrel.r_info = ELF64_R_INFO (0, R_PPC64_IRELATIVE);
+ else
+ outrel.r_info = ELF64_R_INFO (0, R_PPC64_RELATIVE);
+
+ /* Write the .got section contents for the sake
+ of prelink. */
+ loc = got->contents + off;
+ bfd_put_64 (output_bfd, outrel.r_addend + relocation,
+ loc);
+ }
+
+ if (indx == 0 && tls_type != (TLS_TLS | TLS_LD))
+ {
+ outrel.r_addend += relocation;
+ if (tls_type & (TLS_GD | TLS_DTPREL | TLS_TPREL))
+ outrel.r_addend -= htab->elf.tls_sec->vma;
+ }
+ loc = relgot->contents;
+ loc += (relgot->reloc_count++
+ * sizeof (Elf64_External_Rela));
+ bfd_elf64_swap_reloca_out (output_bfd, &outrel, loc);
+ }
+
+ /* Init the .got section contents here if we're not
+ emitting a reloc. */
+ else
+ {
+ relocation += addend;
+ if (tls_type == (TLS_TLS | TLS_LD))
+ relocation = 1;
+ else if (tls_type != 0)
+ {
+ relocation -= htab->elf.tls_sec->vma + DTP_OFFSET;
+ if (tls_type == (TLS_TLS | TLS_TPREL))
+ relocation += DTP_OFFSET - TP_OFFSET;
+
+ if (tls_type == (TLS_TLS | TLS_GD))
+ {
+ bfd_put_64 (output_bfd, relocation,
+ got->contents + off + 8);
+ relocation = 1;
+ }
+ }
+
+ bfd_put_64 (output_bfd, relocation,
+ got->contents + off);
+ }
+ }
+
+ if (off >= (bfd_vma) -2)
+ abort ();
+
+ relocation = got->output_section->vma + got->output_offset + off;
+ addend = -(TOCstart + htab->stub_group[input_section->id].toc_off);
+ }
+ break;
+
+ case R_PPC64_PLT16_HA:
+ case R_PPC64_PLT16_HI:
+ case R_PPC64_PLT16_LO:
+ case R_PPC64_PLT32:
+ case R_PPC64_PLT64:
+ /* Relocation is to the entry for this symbol in the
+ procedure linkage table. */
+
+ /* Resolve a PLT reloc against a local symbol directly,
+ without using the procedure linkage table. */
+ if (h == NULL)
+ break;
+
+ /* It's possible that we didn't make a PLT entry for this
+ symbol. This happens when statically linking PIC code,
+ or when using -Bsymbolic. Go find a match if there is a
+ PLT entry. */
+ if (htab->elf.splt != NULL)
+ {
+ struct plt_entry *ent;
+ for (ent = h->elf.plt.plist; ent != NULL; ent = ent->next)
+ if (ent->plt.offset != (bfd_vma) -1
+ && ent->addend == orig_rel.r_addend)
+ {
+ relocation = (htab->elf.splt->output_section->vma
+ + htab->elf.splt->output_offset
+ + ent->plt.offset);
+ unresolved_reloc = FALSE;
+ break;
+ }
+ }
+ break;
+
+ case R_PPC64_TOC:
+ /* Relocation value is TOC base. */
+ relocation = TOCstart;
+ if (r_symndx == STN_UNDEF)
+ relocation += htab->stub_group[input_section->id].toc_off;
+ else if (unresolved_reloc)
+ ;
+ else if (sec != NULL && sec->id <= htab->top_id)
+ relocation += htab->stub_group[sec->id].toc_off;
+ else
+ unresolved_reloc = TRUE;
+ goto dodyn;
+
+ /* TOC16 relocs. We want the offset relative to the TOC base,
+ which is the address of the start of the TOC plus 0x8000.
+ The TOC consists of sections .got, .toc, .tocbss, and .plt,
+ in this order. */
+ case R_PPC64_TOC16:
+ case R_PPC64_TOC16_LO:
+ case R_PPC64_TOC16_HI:
+ case R_PPC64_TOC16_DS:
+ case R_PPC64_TOC16_LO_DS:
+ case R_PPC64_TOC16_HA:
+ addend -= TOCstart + htab->stub_group[input_section->id].toc_off;
+ break;
+
+ /* Relocate against the beginning of the section. */
+ case R_PPC64_SECTOFF:
+ case R_PPC64_SECTOFF_LO:
+ case R_PPC64_SECTOFF_HI:
+ case R_PPC64_SECTOFF_DS:
+ case R_PPC64_SECTOFF_LO_DS:
+ case R_PPC64_SECTOFF_HA:
+ if (sec != NULL)
+ addend -= sec->output_section->vma;
+ break;
+
+ case R_PPC64_REL16:
+ case R_PPC64_REL16_LO:
+ case R_PPC64_REL16_HI:
+ case R_PPC64_REL16_HA:
+ break;
+
+ case R_PPC64_REL14:
+ case R_PPC64_REL14_BRNTAKEN:
+ case R_PPC64_REL14_BRTAKEN:
+ case R_PPC64_REL24:
+ break;
+
+ case R_PPC64_TPREL16:
+ case R_PPC64_TPREL16_LO:
+ case R_PPC64_TPREL16_HI:
+ case R_PPC64_TPREL16_HA:
+ case R_PPC64_TPREL16_DS:
+ case R_PPC64_TPREL16_LO_DS:
+ case R_PPC64_TPREL16_HIGH:
+ case R_PPC64_TPREL16_HIGHA:
+ case R_PPC64_TPREL16_HIGHER:
+ case R_PPC64_TPREL16_HIGHERA:
+ case R_PPC64_TPREL16_HIGHEST:
+ case R_PPC64_TPREL16_HIGHESTA:
+ if (h != NULL
+ && h->elf.root.type == bfd_link_hash_undefweak
+ && h->elf.dynindx == -1)
+ {
+ /* Make this relocation against an undefined weak symbol
+ resolve to zero. This is really just a tweak, since
+ code using weak externs ought to check that they are
+ defined before using them. */
+ bfd_byte *p = contents + rel->r_offset - d_offset;
+
+ insn = bfd_get_32 (output_bfd, p);
+ insn = _bfd_elf_ppc_at_tprel_transform (insn, 13);
+ if (insn != 0)
+ bfd_put_32 (output_bfd, insn, p);
+ break;
+ }
+ addend -= htab->elf.tls_sec->vma + TP_OFFSET;
+ if (info->shared)
+ /* The TPREL16 relocs shouldn't really be used in shared
+ libs as they will result in DT_TEXTREL being set, but
+ support them anyway. */
+ goto dodyn;
+ break;
+
+ case R_PPC64_DTPREL16:
+ case R_PPC64_DTPREL16_LO:
+ case R_PPC64_DTPREL16_HI:
+ case R_PPC64_DTPREL16_HA:
+ case R_PPC64_DTPREL16_DS:
+ case R_PPC64_DTPREL16_LO_DS:
+ case R_PPC64_DTPREL16_HIGH:
+ case R_PPC64_DTPREL16_HIGHA:
+ case R_PPC64_DTPREL16_HIGHER:
+ case R_PPC64_DTPREL16_HIGHERA:
+ case R_PPC64_DTPREL16_HIGHEST:
+ case R_PPC64_DTPREL16_HIGHESTA:
+ addend -= htab->elf.tls_sec->vma + DTP_OFFSET;
+ break;
+
+ case R_PPC64_ADDR64_LOCAL:
+ addend += PPC64_LOCAL_ENTRY_OFFSET (h != NULL
+ ? h->elf.other
+ : sym->st_other);
+ break;
+
+ case R_PPC64_DTPMOD64:
+ relocation = 1;
+ addend = 0;
+ goto dodyn;
+
+ case R_PPC64_TPREL64:
+ addend -= htab->elf.tls_sec->vma + TP_OFFSET;
+ goto dodyn;
+
+ case R_PPC64_DTPREL64:
+ addend -= htab->elf.tls_sec->vma + DTP_OFFSET;
+ /* Fall thru */
+
+ /* Relocations that may need to be propagated if this is a
+ dynamic object. */
+ case R_PPC64_REL30:
+ case R_PPC64_REL32:
+ case R_PPC64_REL64:
+ case R_PPC64_ADDR14:
+ case R_PPC64_ADDR14_BRNTAKEN:
+ case R_PPC64_ADDR14_BRTAKEN:
+ case R_PPC64_ADDR16:
+ case R_PPC64_ADDR16_DS:
+ case R_PPC64_ADDR16_HA:
+ case R_PPC64_ADDR16_HI:
+ case R_PPC64_ADDR16_HIGH:
+ case R_PPC64_ADDR16_HIGHA:
+ case R_PPC64_ADDR16_HIGHER:
+ case R_PPC64_ADDR16_HIGHERA:
+ case R_PPC64_ADDR16_HIGHEST:
+ case R_PPC64_ADDR16_HIGHESTA:
+ case R_PPC64_ADDR16_LO:
+ case R_PPC64_ADDR16_LO_DS:
+ case R_PPC64_ADDR24:
+ case R_PPC64_ADDR32:
+ case R_PPC64_ADDR64:
+ case R_PPC64_UADDR16:
+ case R_PPC64_UADDR32:
+ case R_PPC64_UADDR64:
+ dodyn:
+ if ((input_section->flags & SEC_ALLOC) == 0)
+ break;
+
+ if (NO_OPD_RELOCS && is_opd)
+ break;
+
+ if ((info->shared
+ && (h == NULL
+ || ELF_ST_VISIBILITY (h->elf.other) == STV_DEFAULT
+ || h->elf.root.type != bfd_link_hash_undefweak)
+ && (must_be_dyn_reloc (info, r_type)
+ || !SYMBOL_CALLS_LOCAL (info, &h->elf)))
+ || (ELIMINATE_COPY_RELOCS
+ && !info->shared
+ && h != NULL
+ && h->elf.dynindx != -1
+ && !h->elf.non_got_ref
+ && !h->elf.def_regular)
+ || (!info->shared
+ && (h != NULL
+ ? h->elf.type == STT_GNU_IFUNC
+ : ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC)))
+ {
+ bfd_boolean skip, relocate;
+ asection *sreloc;
+ bfd_vma out_off;
+
+ /* When generating a dynamic object, these relocations
+ are copied into the output file to be resolved at run
+ time. */
+
+ skip = FALSE;
+ relocate = FALSE;
+
+ out_off = _bfd_elf_section_offset (output_bfd, info,
+ input_section, rel->r_offset);
+ if (out_off == (bfd_vma) -1)
+ skip = TRUE;
+ else if (out_off == (bfd_vma) -2)
+ skip = TRUE, relocate = TRUE;
+ out_off += (input_section->output_section->vma
+ + input_section->output_offset);
+ outrel.r_offset = out_off;
+ outrel.r_addend = rel->r_addend;
+
+ /* Optimize unaligned reloc use. */
+ if ((r_type == R_PPC64_ADDR64 && (out_off & 7) != 0)
+ || (r_type == R_PPC64_UADDR64 && (out_off & 7) == 0))
+ r_type ^= R_PPC64_ADDR64 ^ R_PPC64_UADDR64;
+ else if ((r_type == R_PPC64_ADDR32 && (out_off & 3) != 0)
+ || (r_type == R_PPC64_UADDR32 && (out_off & 3) == 0))
+ r_type ^= R_PPC64_ADDR32 ^ R_PPC64_UADDR32;
+ else if ((r_type == R_PPC64_ADDR16 && (out_off & 1) != 0)
+ || (r_type == R_PPC64_UADDR16 && (out_off & 1) == 0))
+ r_type ^= R_PPC64_ADDR16 ^ R_PPC64_UADDR16;
+
+ if (skip)
+ memset (&outrel, 0, sizeof outrel);
+ else if (!SYMBOL_REFERENCES_LOCAL (info, &h->elf)
+ && !is_opd
+ && r_type != R_PPC64_TOC)
+ {
+ BFD_ASSERT (h->elf.dynindx != -1);
+ outrel.r_info = ELF64_R_INFO (h->elf.dynindx, r_type);
+ }
+ else
+ {
+ /* This symbol is local, or marked to become local,
+ or this is an opd section reloc which must point
+ at a local function. */
+ outrel.r_addend += relocation;
+ if (r_type == R_PPC64_ADDR64 || r_type == R_PPC64_TOC)
+ {
+ if (is_opd && h != NULL)
+ {
+ /* Lie about opd entries. This case occurs
+ when building shared libraries and we
+ reference a function in another shared
+ lib. The same thing happens for a weak
+ definition in an application that's
+ overridden by a strong definition in a
+ shared lib. (I believe this is a generic
+ bug in binutils handling of weak syms.)
+ In these cases we won't use the opd
+ entry in this lib. */
+ unresolved_reloc = FALSE;
+ }
+ if (!is_opd
+ && r_type == R_PPC64_ADDR64
+ && (h != NULL
+ ? h->elf.type == STT_GNU_IFUNC
+ : ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC))
+ outrel.r_info = ELF64_R_INFO (0, R_PPC64_IRELATIVE);
+ else
+ {
+ outrel.r_info = ELF64_R_INFO (0, R_PPC64_RELATIVE);
+
+ /* We need to relocate .opd contents for ld.so.
+ Prelink also wants simple and consistent rules
+ for relocs. This make all RELATIVE relocs have
+ *r_offset equal to r_addend. */
+ relocate = TRUE;
+ }
+ }
+ else
+ {
+ long indx = 0;
+
+ if (h != NULL
+ ? h->elf.type == STT_GNU_IFUNC
+ : ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC)
+ {
+ info->callbacks->einfo
+ (_("%P: %H: %s for indirect "
+ "function `%T' unsupported\n"),
+ input_bfd, input_section, rel->r_offset,
+ ppc64_elf_howto_table[r_type]->name,
+ sym_name);
+ ret = FALSE;
+ }
+ else if (r_symndx == STN_UNDEF || bfd_is_abs_section (sec))
+ ;
+ 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)
+ {
+ if ((osec->flags & SEC_READONLY) == 0
+ && htab->elf.data_index_section != NULL)
+ osec = htab->elf.data_index_section;
+ else
+ osec = htab->elf.text_index_section;
+ indx = elf_section_data (osec)->dynindx;
+ }
+ BFD_ASSERT (indx != 0);
+
+ /* We are turning this relocation into one
+ against a section symbol, so subtract out
+ the output section's address but not the
+ offset of the input section in the output
+ section. */
+ outrel.r_addend -= osec->vma;
+ }
+
+ outrel.r_info = ELF64_R_INFO (indx, r_type);
+ }
+ }
+
+ sreloc = elf_section_data (input_section)->sreloc;
+ if (h != NULL
+ ? h->elf.type == STT_GNU_IFUNC
+ : ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC)
+ sreloc = htab->elf.irelplt;
+ if (sreloc == NULL)
+ abort ();
+
+ if (sreloc->reloc_count * sizeof (Elf64_External_Rela)
+ >= sreloc->size)
+ abort ();
+ loc = sreloc->contents;
+ loc += sreloc->reloc_count++ * sizeof (Elf64_External_Rela);
+ bfd_elf64_swap_reloca_out (output_bfd, &outrel, loc);
+
+ /* If this reloc is against an external symbol, it will
+ be computed at runtime, so there's no need to do
+ anything now. However, for the sake of prelink ensure
+ that the section contents are a known value. */
+ if (! relocate)
+ {
+ unresolved_reloc = FALSE;
+ /* The value chosen here is quite arbitrary as ld.so
+ ignores section contents except for the special
+ case of .opd where the contents might be accessed
+ before relocation. Choose zero, as that won't
+ cause reloc overflow. */
+ relocation = 0;
+ addend = 0;
+ /* Use *r_offset == r_addend for R_PPC64_ADDR64 relocs
+ to improve backward compatibility with older
+ versions of ld. */
+ if (r_type == R_PPC64_ADDR64)
+ addend = outrel.r_addend;
+ /* Adjust pc_relative relocs to have zero in *r_offset. */
+ else if (ppc64_elf_howto_table[r_type]->pc_relative)
+ addend = (input_section->output_section->vma
+ + input_section->output_offset
+ + rel->r_offset);
+ }
+ }
+ break;
+
+ case R_PPC64_COPY:
+ case R_PPC64_GLOB_DAT:
+ case R_PPC64_JMP_SLOT:
+ case R_PPC64_JMP_IREL:
+ case R_PPC64_RELATIVE:
+ /* We shouldn't ever see these dynamic relocs in relocatable
+ files. */
+ /* Fall through. */
+
+ case R_PPC64_PLTGOT16:
+ case R_PPC64_PLTGOT16_DS:
+ case R_PPC64_PLTGOT16_HA:
+ case R_PPC64_PLTGOT16_HI:
+ case R_PPC64_PLTGOT16_LO:
+ case R_PPC64_PLTGOT16_LO_DS:
+ case R_PPC64_PLTREL32:
+ case R_PPC64_PLTREL64:
+ /* These ones haven't been implemented yet. */
+
+ info->callbacks->einfo
+ (_("%P: %B: %s is not supported for `%T'\n"),
+ input_bfd,
+ ppc64_elf_howto_table[r_type]->name, sym_name);
+
+ bfd_set_error (bfd_error_invalid_operation);
+ ret = FALSE;
+ continue;
+ }
+
+ /* Multi-instruction sequences that access the TOC can be
+ optimized, eg. addis ra,r2,0; addi rb,ra,x;
+ to nop; addi rb,r2,x; */
+ switch (r_type)
+ {
+ default:
+ break;
+
+ case R_PPC64_GOT_TLSLD16_HI:
+ case R_PPC64_GOT_TLSGD16_HI:
+ case R_PPC64_GOT_TPREL16_HI:
+ case R_PPC64_GOT_DTPREL16_HI:
+ case R_PPC64_GOT16_HI:
+ case R_PPC64_TOC16_HI:
+ /* These relocs would only be useful if building up an
+ offset to later add to r2, perhaps in an indexed
+ addressing mode instruction. Don't try to optimize.
+ Unfortunately, the possibility of someone building up an
+ offset like this or even with the HA relocs, means that
+ we need to check the high insn when optimizing the low
+ insn. */
+ break;
+
+ case R_PPC64_GOT_TLSLD16_HA:
+ case R_PPC64_GOT_TLSGD16_HA:
+ case R_PPC64_GOT_TPREL16_HA:
+ case R_PPC64_GOT_DTPREL16_HA:
+ case R_PPC64_GOT16_HA:
+ case R_PPC64_TOC16_HA:
+ if (htab->do_toc_opt && relocation + addend + 0x8000 < 0x10000
+ && !ppc64_elf_tdata (input_bfd)->unexpected_toc_insn)
+ {
+ bfd_byte *p = contents + (rel->r_offset & ~3);
+ bfd_put_32 (input_bfd, NOP, p);
+ }
+ break;
+
+ case R_PPC64_GOT_TLSLD16_LO:
+ case R_PPC64_GOT_TLSGD16_LO:
+ case R_PPC64_GOT_TPREL16_LO_DS:
+ case R_PPC64_GOT_DTPREL16_LO_DS:
+ case R_PPC64_GOT16_LO:
+ case R_PPC64_GOT16_LO_DS:
+ case R_PPC64_TOC16_LO:
+ case R_PPC64_TOC16_LO_DS:
+ if (htab->do_toc_opt && relocation + addend + 0x8000 < 0x10000
+ && !ppc64_elf_tdata (input_bfd)->unexpected_toc_insn)
+ {
+ bfd_byte *p = contents + (rel->r_offset & ~3);
+ insn = bfd_get_32 (input_bfd, p);
+ if ((insn & (0x3f << 26)) == 12u << 26 /* addic */)
+ {
+ /* Transform addic to addi when we change reg. */
+ insn &= ~((0x3f << 26) | (0x1f << 16));
+ insn |= (14u << 26) | (2 << 16);
+ }
+ else
+ {
+ insn &= ~(0x1f << 16);
+ insn |= 2 << 16;
+ }
+ bfd_put_32 (input_bfd, insn, p);
+ }
+ break;
+ }
+
+ /* Do any further special processing. */
+ howto = ppc64_elf_howto_table[(int) r_type];
+ switch (r_type)
+ {
+ default:
+ break;
+
+ case R_PPC64_REL16_HA:
+ case R_PPC64_ADDR16_HA:
+ case R_PPC64_ADDR16_HIGHA:
+ case R_PPC64_ADDR16_HIGHERA:
+ case R_PPC64_ADDR16_HIGHESTA:
+ case R_PPC64_TOC16_HA:
+ case R_PPC64_SECTOFF_HA:
+ case R_PPC64_TPREL16_HA:
+ case R_PPC64_TPREL16_HIGHA:
+ case R_PPC64_TPREL16_HIGHERA:
+ case R_PPC64_TPREL16_HIGHESTA:
+ case R_PPC64_DTPREL16_HA:
+ case R_PPC64_DTPREL16_HIGHA:
+ case R_PPC64_DTPREL16_HIGHERA:
+ case R_PPC64_DTPREL16_HIGHESTA:
+ /* 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). */
+ if (sec == NULL)
+ break;
+ /* Fall thru */
+
+ case R_PPC64_GOT16_HA:
+ case R_PPC64_PLTGOT16_HA:
+ case R_PPC64_PLT16_HA:
+ case R_PPC64_GOT_TLSGD16_HA:
+ case R_PPC64_GOT_TLSLD16_HA:
+ case R_PPC64_GOT_TPREL16_HA:
+ case R_PPC64_GOT_DTPREL16_HA:
+ /* Add 0x10000 if sign bit in 0:15 is set.
+ Bits 0:15 are not used. */
+ addend += 0x8000;
+ break;
+
+ case R_PPC64_ADDR16_DS:
+ case R_PPC64_ADDR16_LO_DS:
+ case R_PPC64_GOT16_DS:
+ case R_PPC64_GOT16_LO_DS:
+ case R_PPC64_PLT16_LO_DS:
+ case R_PPC64_SECTOFF_DS:
+ case R_PPC64_SECTOFF_LO_DS:
+ case R_PPC64_TOC16_DS:
+ case R_PPC64_TOC16_LO_DS:
+ case R_PPC64_PLTGOT16_DS:
+ case R_PPC64_PLTGOT16_LO_DS:
+ case R_PPC64_GOT_TPREL16_DS:
+ case R_PPC64_GOT_TPREL16_LO_DS:
+ case R_PPC64_GOT_DTPREL16_DS:
+ case R_PPC64_GOT_DTPREL16_LO_DS:
+ case R_PPC64_TPREL16_DS:
+ case R_PPC64_TPREL16_LO_DS:
+ case R_PPC64_DTPREL16_DS:
+ case R_PPC64_DTPREL16_LO_DS:
+ insn = bfd_get_32 (input_bfd, contents + (rel->r_offset & ~3));
+ mask = 3;
+ /* If this reloc is against an lq insn, then the value must be
+ a multiple of 16. This is somewhat of a hack, but the
+ "correct" way to do this by defining _DQ forms of all the
+ _DS relocs bloats all reloc switches in this file. It
+ doesn't seem to make much sense to use any of these relocs
+ in data, so testing the insn should be safe. */
+ if ((insn & (0x3f << 26)) == (56u << 26))
+ mask = 15;
+ if (((relocation + addend) & mask) != 0)
+ {
+ info->callbacks->einfo
+ (_("%P: %H: error: %s not a multiple of %u\n"),
+ input_bfd, input_section, rel->r_offset,
+ howto->name,
+ mask + 1);
+ bfd_set_error (bfd_error_bad_value);
+ ret = FALSE;
+ continue;
+ }
+ break;
+ }
+
+ /* Dynamic relocs are not propagated for SEC_DEBUGGING sections
+ because such sections are not SEC_ALLOC and thus ld.so will
+ not process them. */
+ if (unresolved_reloc
+ && !((input_section->flags & SEC_DEBUGGING) != 0
+ && h->elf.def_dynamic)
+ && _bfd_elf_section_offset (output_bfd, info, input_section,
+ rel->r_offset) != (bfd_vma) -1)
+ {
+ info->callbacks->einfo
+ (_("%P: %H: unresolvable %s against `%T'\n"),
+ input_bfd, input_section, rel->r_offset,
+ howto->name,
+ h->elf.root.root.string);
+ ret = FALSE;
+ }
+
+ /* 16-bit fields in insns mostly have signed values, but a
+ few insns have 16-bit unsigned values. Really, we should
+ have different reloc types. */
+ if (howto->complain_on_overflow != complain_overflow_dont
+ && howto->dst_mask == 0xffff
+ && (input_section->flags & SEC_CODE) != 0)
+ {
+ enum complain_overflow complain = complain_overflow_signed;
+
+ insn = bfd_get_32 (input_bfd, contents + (rel->r_offset & ~3));
+ if ((insn & (0x3f << 26)) == 10u << 26 /* cmpli */)
+ complain = complain_overflow_bitfield;
+ else if (howto->rightshift == 0
+ ? ((insn & (0x3f << 26)) == 28u << 26 /* andi */
+ || (insn & (0x3f << 26)) == 24u << 26 /* ori */
+ || (insn & (0x3f << 26)) == 26u << 26 /* xori */)
+ : ((insn & (0x3f << 26)) == 29u << 26 /* andis */
+ || (insn & (0x3f << 26)) == 25u << 26 /* oris */
+ || (insn & (0x3f << 26)) == 27u << 26 /* xoris */))
+ complain = complain_overflow_unsigned;
+ if (howto->complain_on_overflow != complain)
+ {
+ alt_howto = *howto;
+ alt_howto.complain_on_overflow = complain;
+ howto = &alt_howto;
+ }
+ }
+
+ r = _bfd_final_link_relocate (howto, input_bfd, input_section, contents,
+ rel->r_offset, relocation, addend);
+
+ if (r != bfd_reloc_ok)
+ {
+ char *more_info = NULL;
+ const char *reloc_name = howto->name;
+
+ if (reloc_dest != DEST_NORMAL)
+ {
+ more_info = bfd_malloc (strlen (reloc_name) + 8);
+ if (more_info != NULL)
+ {
+ strcpy (more_info, reloc_name);
+ strcat (more_info, (reloc_dest == DEST_OPD
+ ? " (OPD)" : " (stub)"));
+ reloc_name = more_info;
+ }
+ }
+
+ if (r == bfd_reloc_overflow)
+ {
+ if (warned)
+ continue;
+ if (h != NULL
+ && h->elf.root.type == bfd_link_hash_undefweak
+ && howto->pc_relative)
+ {
+ /* Assume this is a call protected by other code that
+ detects 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. */
+
+ continue;
+ }
+
+ if (!((*info->callbacks->reloc_overflow)
+ (info, &h->elf.root, sym_name,
+ reloc_name, orig_rel.r_addend,
+ input_bfd, input_section, rel->r_offset)))
+ return FALSE;
+ }
+ else
+ {
+ info->callbacks->einfo
+ (_("%P: %H: %s against `%T': error %d\n"),
+ input_bfd, input_section, rel->r_offset,
+ reloc_name, sym_name, (int) r);
+ ret = FALSE;
+ }
+ if (more_info != NULL)
+ free (more_info);
+ }
+ }
+
+ /* If we're emitting relocations, then shortly after this function
+ returns, reloc offsets and addends for this section will be
+ adjusted. Worse, reloc symbol indices will be for the output
+ file rather than the input. Save a copy of the relocs for
+ opd_entry_value. */
+ if (is_opd && (info->emitrelocations || info->relocatable))
+ {
+ bfd_size_type amt;
+ amt = input_section->reloc_count * sizeof (Elf_Internal_Rela);
+ rel = bfd_alloc (input_bfd, amt);
+ BFD_ASSERT (ppc64_elf_tdata (input_bfd)->opd.relocs == NULL);
+ ppc64_elf_tdata (input_bfd)->opd.relocs = rel;
+ if (rel == NULL)
+ return FALSE;
+ memcpy (rel, relocs, amt);
+ }
+ return ret;
+}
+
+/* Adjust the value of any local symbols in opd sections. */
+
+static int
+ppc64_elf_output_symbol_hook (struct bfd_link_info *info,
+ const char *name ATTRIBUTE_UNUSED,
+ Elf_Internal_Sym *elfsym,
+ asection *input_sec,
+ struct elf_link_hash_entry *h)
+{
+ struct _opd_sec_data *opd;
+ long adjust;
+ bfd_vma value;
+
+ if (h != NULL)
+ return 1;
+
+ opd = get_opd_info (input_sec);
+ if (opd == NULL || opd->adjust == NULL)
+ return 1;
+
+ value = elfsym->st_value - input_sec->output_offset;
+ if (!info->relocatable)
+ value -= input_sec->output_section->vma;
+
+ adjust = opd->adjust[value / 8];
+ if (adjust == -1)
+ return 2;
+
+ elfsym->st_value += adjust;
+ return 1;
+}
+
+/* Finish up dynamic symbol handling. We set the contents of various
+ dynamic sections here. */
+
+static bfd_boolean
+ppc64_elf_finish_dynamic_symbol (bfd *output_bfd,
+ struct bfd_link_info *info,
+ struct elf_link_hash_entry *h,
+ Elf_Internal_Sym *sym ATTRIBUTE_UNUSED)
+{
+ struct ppc_link_hash_table *htab;
+ struct plt_entry *ent;
+ Elf_Internal_Rela rela;
+ bfd_byte *loc;
+
+ htab = ppc_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ for (ent = h->plt.plist; ent != NULL; ent = ent->next)
+ if (ent->plt.offset != (bfd_vma) -1)
+ {
+ /* This symbol has an entry in the procedure linkage
+ table. Set it up. */
+ if (!htab->elf.dynamic_sections_created
+ || h->dynindx == -1)
+ {
+ BFD_ASSERT (h->type == STT_GNU_IFUNC
+ && h->def_regular
+ && (h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak));
+ rela.r_offset = (htab->elf.iplt->output_section->vma
+ + htab->elf.iplt->output_offset
+ + ent->plt.offset);
+ if (htab->opd_abi)
+ rela.r_info = ELF64_R_INFO (0, R_PPC64_JMP_IREL);
+ else
+ rela.r_info = ELF64_R_INFO (0, R_PPC64_IRELATIVE);
+ rela.r_addend = (h->root.u.def.value
+ + h->root.u.def.section->output_offset
+ + h->root.u.def.section->output_section->vma
+ + ent->addend);
+ loc = (htab->elf.irelplt->contents
+ + (htab->elf.irelplt->reloc_count++
+ * sizeof (Elf64_External_Rela)));
+ }
+ else
+ {
+ rela.r_offset = (htab->elf.splt->output_section->vma
+ + htab->elf.splt->output_offset
+ + ent->plt.offset);
+ rela.r_info = ELF64_R_INFO (h->dynindx, R_PPC64_JMP_SLOT);
+ rela.r_addend = ent->addend;
+ loc = (htab->elf.srelplt->contents
+ + ((ent->plt.offset - PLT_INITIAL_ENTRY_SIZE (htab))
+ / PLT_ENTRY_SIZE (htab) * sizeof (Elf64_External_Rela)));
+ }
+ bfd_elf64_swap_reloca_out (output_bfd, &rela, loc);
+
+ if (!htab->opd_abi)
+ {
+ if (!h->def_regular)
+ {
+ /* Mark the symbol as undefined, rather than as
+ defined in glink. Leave the value if there were
+ any relocations where pointer equality matters
+ (this is a clue for the dynamic linker, to make
+ function pointer comparisons work between an
+ application and shared library), otherwise set it
+ to zero. */
+ sym->st_shndx = SHN_UNDEF;
+ if (!h->pointer_equality_needed)
+ sym->st_value = 0;
+ else if (!h->ref_regular_nonweak)
+ {
+ /* This breaks function pointer comparisons, but
+ that is better than breaking tests for a NULL
+ function pointer. */
+ sym->st_value = 0;
+ }
+ }
+ }
+ }
+
+ if (h->needs_copy)
+ {
+ /* This symbol needs a copy reloc. Set it up. */
+
+ if (h->dynindx == -1
+ || (h->root.type != bfd_link_hash_defined
+ && h->root.type != bfd_link_hash_defweak)
+ || htab->relbss == NULL)
+ abort ();
+
+ 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_PPC64_COPY);
+ rela.r_addend = 0;
+ loc = htab->relbss->contents;
+ loc += htab->relbss->reloc_count++ * sizeof (Elf64_External_Rela);
+ bfd_elf64_swap_reloca_out (output_bfd, &rela, loc);
+ }
+
+ return TRUE;
+}
+
+/* Used to decide how to sort relocs in an optimal manner for the
+ dynamic linker, before writing them out. */
+
+static enum elf_reloc_type_class
+ppc64_elf_reloc_type_class (const struct bfd_link_info *info,
+ const asection *rel_sec,
+ const Elf_Internal_Rela *rela)
+{
+ enum elf_ppc64_reloc_type r_type;
+ struct ppc_link_hash_table *htab = ppc_hash_table (info);
+
+ if (rel_sec == htab->elf.irelplt)
+ return reloc_class_ifunc;
+
+ r_type = ELF64_R_TYPE (rela->r_info);
+ switch (r_type)
+ {
+ case R_PPC64_RELATIVE:
+ return reloc_class_relative;
+ case R_PPC64_JMP_SLOT:
+ return reloc_class_plt;
+ case R_PPC64_COPY:
+ return reloc_class_copy;
+ default:
+ return reloc_class_normal;
+ }
+}
+
+/* Finish up the dynamic sections. */
+
+static bfd_boolean
+ppc64_elf_finish_dynamic_sections (bfd *output_bfd,
+ struct bfd_link_info *info)
+{
+ struct ppc_link_hash_table *htab;
+ bfd *dynobj;
+ asection *sdyn;
+
+ htab = ppc_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ dynobj = htab->elf.dynobj;
+ sdyn = bfd_get_linker_section (dynobj, ".dynamic");
+
+ if (htab->elf.dynamic_sections_created)
+ {
+ Elf64_External_Dyn *dyncon, *dynconend;
+
+ if (sdyn == NULL || htab->elf.sgot == NULL)
+ abort ();
+
+ dyncon = (Elf64_External_Dyn *) sdyn->contents;
+ dynconend = (Elf64_External_Dyn *) (sdyn->contents + sdyn->size);
+ for (; dyncon < dynconend; dyncon++)
+ {
+ Elf_Internal_Dyn dyn;
+ asection *s;
+
+ bfd_elf64_swap_dyn_in (dynobj, dyncon, &dyn);
+
+ switch (dyn.d_tag)
+ {
+ default:
+ continue;
+
+ case DT_PPC64_GLINK:
+ s = htab->glink;
+ dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
+ /* We stupidly defined DT_PPC64_GLINK to be the start
+ of glink rather than the first entry point, which is
+ what ld.so needs, and now have a bigger stub to
+ support automatic multiple TOCs. */
+ dyn.d_un.d_ptr += GLINK_CALL_STUB_SIZE - 8 * 4;
+ break;
+
+ case DT_PPC64_OPD:
+ s = bfd_get_section_by_name (output_bfd, ".opd");
+ if (s == NULL)
+ continue;
+ dyn.d_un.d_ptr = s->vma;
+ break;
+
+ case DT_PPC64_OPT:
+ if (htab->do_multi_toc && htab->multi_toc_needed)
+ dyn.d_un.d_val |= PPC64_OPT_MULTI_TOC;
+ break;
+
+ case DT_PPC64_OPDSZ:
+ s = bfd_get_section_by_name (output_bfd, ".opd");
+ if (s == NULL)
+ continue;
+ dyn.d_un.d_val = s->size;
+ break;
+
+ case DT_PLTGOT:
+ s = htab->elf.splt;
+ dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
+ break;
+
+ case DT_JMPREL:
+ s = htab->elf.srelplt;
+ dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
+ break;
+
+ case DT_PLTRELSZ:
+ dyn.d_un.d_val = htab->elf.srelplt->size;
+ break;
+
+ case DT_RELASZ:
+ /* Don't count procedure linkage table relocs in the
+ overall reloc count. */
+ s = htab->elf.srelplt;
+ if (s == NULL)
+ continue;
+ dyn.d_un.d_val -= s->size;
+ break;
+
+ case DT_RELA:
+ /* We may not be using the standard ELF linker script.
+ If .rela.plt is the first .rela section, we adjust
+ DT_RELA to not include it. */
+ s = htab->elf.srelplt;
+ if (s == NULL)
+ continue;
+ if (dyn.d_un.d_ptr != s->output_section->vma + s->output_offset)
+ continue;
+ dyn.d_un.d_ptr += s->size;
+ break;
+ }
+
+ bfd_elf64_swap_dyn_out (output_bfd, &dyn, dyncon);
+ }
+ }
+
+ if (htab->elf.sgot != NULL && htab->elf.sgot->size != 0)
+ {
+ /* Fill in the first entry in the global offset table.
+ We use it to hold the link-time TOCbase. */
+ bfd_put_64 (output_bfd,
+ elf_gp (output_bfd) + TOC_BASE_OFF,
+ htab->elf.sgot->contents);
+
+ /* Set .got entry size. */
+ elf_section_data (htab->elf.sgot->output_section)->this_hdr.sh_entsize = 8;
+ }
+
+ if (htab->elf.splt != NULL && htab->elf.splt->size != 0)
+ {
+ /* Set .plt entry size. */
+ elf_section_data (htab->elf.splt->output_section)->this_hdr.sh_entsize
+ = PLT_ENTRY_SIZE (htab);
+ }
+
+ /* brlt is SEC_LINKER_CREATED, so we need to write out relocs for
+ brlt ourselves if emitrelocations. */
+ if (htab->brlt != NULL
+ && htab->brlt->reloc_count != 0
+ && !_bfd_elf_link_output_relocs (output_bfd,
+ htab->brlt,
+ elf_section_data (htab->brlt)->rela.hdr,
+ elf_section_data (htab->brlt)->relocs,
+ NULL))
+ return FALSE;
+
+ if (htab->glink != NULL
+ && htab->glink->reloc_count != 0
+ && !_bfd_elf_link_output_relocs (output_bfd,
+ htab->glink,
+ elf_section_data (htab->glink)->rela.hdr,
+ elf_section_data (htab->glink)->relocs,
+ NULL))
+ return FALSE;
+
+ if (htab->glink_eh_frame != NULL
+ && htab->glink_eh_frame->size != 0)
+ {
+ bfd_vma val;
+ bfd_byte *p;
+ asection *stub_sec;
+
+ p = htab->glink_eh_frame->contents + sizeof (glink_eh_frame_cie);
+ for (stub_sec = htab->params->stub_bfd->sections;
+ stub_sec != NULL;
+ stub_sec = stub_sec->next)
+ if ((stub_sec->flags & SEC_LINKER_CREATED) == 0)
+ {
+ /* FDE length. */
+ p += 4;
+ /* CIE pointer. */
+ p += 4;
+ /* Offset to stub section. */
+ val = (stub_sec->output_section->vma
+ + stub_sec->output_offset);
+ val -= (htab->glink_eh_frame->output_section->vma
+ + htab->glink_eh_frame->output_offset
+ + (p - htab->glink_eh_frame->contents));
+ if (val + 0x80000000 > 0xffffffff)
+ {
+ info->callbacks->einfo
+ (_("%P: %s offset too large for .eh_frame sdata4 encoding"),
+ stub_sec->name);
+ return FALSE;
+ }
+ bfd_put_32 (dynobj, val, p);
+ p += 4;
+ /* stub section size. */
+ p += 4;
+ /* Augmentation. */
+ p += 1;
+ /* Pad. */
+ p += 7;
+ }
+ if (htab->glink != NULL && htab->glink->size != 0)
+ {
+ /* FDE length. */
+ p += 4;
+ /* CIE pointer. */
+ p += 4;
+ /* Offset to .glink. */
+ val = (htab->glink->output_section->vma
+ + htab->glink->output_offset
+ + 8);
+ val -= (htab->glink_eh_frame->output_section->vma
+ + htab->glink_eh_frame->output_offset
+ + (p - htab->glink_eh_frame->contents));
+ if (val + 0x80000000 > 0xffffffff)
+ {
+ info->callbacks->einfo
+ (_("%P: %s offset too large for .eh_frame sdata4 encoding"),
+ htab->glink->name);
+ return FALSE;
+ }
+ bfd_put_32 (dynobj, val, p);
+ p += 4;
+ /* .glink size. */
+ p += 4;
+ /* Augmentation. */
+ p += 1;
+ /* Ops. */
+ p += 7;
+ }
+
+ if (htab->glink_eh_frame->sec_info_type == SEC_INFO_TYPE_EH_FRAME
+ && !_bfd_elf_write_section_eh_frame (output_bfd, info,
+ htab->glink_eh_frame,
+ htab->glink_eh_frame->contents))
+ return FALSE;
+ }
+
+ /* We need to handle writing out multiple GOT sections ourselves,
+ since we didn't add them to DYNOBJ. We know dynobj is the first
+ bfd. */
+ while ((dynobj = dynobj->link.next) != NULL)
+ {
+ asection *s;
+
+ if (!is_ppc64_elf (dynobj))
+ continue;
+
+ s = ppc64_elf_tdata (dynobj)->got;
+ if (s != NULL
+ && s->size != 0
+ && s->output_section != bfd_abs_section_ptr
+ && !bfd_set_section_contents (output_bfd, s->output_section,
+ s->contents, s->output_offset,
+ s->size))
+ return FALSE;
+ s = ppc64_elf_tdata (dynobj)->relgot;
+ if (s != NULL
+ && s->size != 0
+ && s->output_section != bfd_abs_section_ptr
+ && !bfd_set_section_contents (output_bfd, s->output_section,
+ s->contents, s->output_offset,
+ s->size))
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+#include "elf64-target.h"
+
+/* FreeBSD support */
+
+#undef TARGET_LITTLE_SYM
+#undef TARGET_LITTLE_NAME
+
+#undef TARGET_BIG_SYM
+#define TARGET_BIG_SYM powerpc_elf64_fbsd_vec
+#undef TARGET_BIG_NAME
+#define TARGET_BIG_NAME "elf64-powerpc-freebsd"
+
+#undef ELF_OSABI
+#define ELF_OSABI ELFOSABI_FREEBSD
+
+#undef elf64_bed
+#define elf64_bed elf64_powerpc_fbsd_bed
+
+#include "elf64-target.h"
+
diff --git a/bfd/elf64-ppc.h b/bfd/elf64-ppc.h
new file mode 100644
index 0000000..d05fee5
--- /dev/null
+++ b/bfd/elf64-ppc.h
@@ -0,0 +1,95 @@
+/* PowerPC64-specific support for 64-bit ELF.
+ Copyright (C) 2002-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+/* Used to pass info between ld and bfd. */
+struct ppc64_elf_params
+{
+ /* Linker stub bfd. */
+ bfd *stub_bfd;
+
+ /* Linker call-backs. */
+ asection * (*add_stub_section) (const char *, asection *);
+ void (*layout_sections_again) (void);
+
+ /* Maximum size of a group of input sections that can be handled by
+ one stub section. A value of +/-1 indicates the bfd back-end
+ should use a suitable default size. */
+ bfd_signed_vma group_size;
+
+ /* Whether to use a special call stub for __tls_get_addr. */
+ int no_tls_get_addr_opt;
+
+ /* Whether to allow multiple toc sections. */
+ int no_multi_toc;
+
+ /* Set if PLT call stubs should load r11. */
+ int plt_static_chain;
+
+ /* Set if PLT call stubs need to be thread safe on power7+. */
+ int plt_thread_safe;
+
+ /* Set if individual PLT call stubs should be aligned. */
+ int plt_stub_align;
+
+ /* Whether to canonicalize .opd so that there are no overlapping
+ .opd entries. */
+ int non_overlapping_opd;
+
+ /* Whether to emit symbols for stubs. */
+ int emit_stub_syms;
+
+ /* Whether to generate out-of-line register save/restore for gcc -Os code. */
+ int save_restore_funcs;
+};
+
+bfd_boolean ppc64_elf_init_stub_bfd
+ (struct bfd_link_info *, struct ppc64_elf_params *);
+bfd_boolean ppc64_elf_edit_opd
+ (struct bfd_link_info *);
+asection *ppc64_elf_tls_setup
+ (struct bfd_link_info *);
+bfd_boolean ppc64_elf_tls_optimize
+ (struct bfd_link_info *);
+bfd_boolean ppc64_elf_edit_toc
+ (struct bfd_link_info *);
+bfd_boolean ppc64_elf_has_small_toc_reloc
+ (asection *);
+bfd_vma ppc64_elf_set_toc
+ (struct bfd_link_info *, bfd *);
+int ppc64_elf_setup_section_lists
+ (struct bfd_link_info *);
+void ppc64_elf_start_multitoc_partition
+ (struct bfd_link_info *);
+bfd_boolean ppc64_elf_next_toc_section
+ (struct bfd_link_info *, asection *);
+bfd_boolean ppc64_elf_layout_multitoc
+ (struct bfd_link_info *);
+void ppc64_elf_finish_multitoc_partition
+ (struct bfd_link_info *);
+bfd_boolean ppc64_elf_check_init_fini
+ (struct bfd_link_info *);
+bfd_boolean ppc64_elf_next_input_section
+ (struct bfd_link_info *, asection *);
+bfd_boolean ppc64_elf_size_stubs
+(struct bfd_link_info *);
+bfd_boolean ppc64_elf_build_stubs
+ (struct bfd_link_info *, char **);
+void ppc64_elf_restore_symbols
+ (struct bfd_link_info *info);
diff --git a/bfd/elf64-s390.c b/bfd/elf64-s390.c
new file mode 100644
index 0000000..b2f1aa5
--- /dev/null
+++ b/bfd/elf64-s390.c
@@ -0,0 +1,3862 @@
+/* IBM S/390-specific support for 64-bit ELF
+ Copyright (C) 2000-2014 Free Software Foundation, Inc.
+ Contributed Martin Schwidefsky (schwidefsky@de.ibm.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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
+ 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "bfdlink.h"
+#include "libbfd.h"
+#include "elf-bfd.h"
+#include "elf/s390.h"
+
+/* 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 bfd_reloc_status_type
+s390_tls_reloc (bfd *, arelent *, asymbol *, void *,
+ asection *, bfd *, char **);
+static bfd_reloc_status_type
+s390_elf_ldisp_reloc (bfd *, arelent *, asymbol *, void *,
+ asection *, bfd *, char **);
+
+/* The relocation "howto" table. */
+static reloc_howto_type elf_howto_table[] =
+{
+ HOWTO (R_390_NONE, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = 2 byte, 2 = 4 byte) */
+ 0, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_390_NONE", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO(R_390_8, 0, 0, 8, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_390_8", FALSE, 0,0x000000ff, FALSE),
+ HOWTO(R_390_12, 0, 1, 12, FALSE, 0, complain_overflow_dont,
+ bfd_elf_generic_reloc, "R_390_12", FALSE, 0,0x00000fff, FALSE),
+ HOWTO(R_390_16, 0, 1, 16, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_390_16", FALSE, 0,0x0000ffff, FALSE),
+ HOWTO(R_390_32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_390_32", FALSE, 0,0xffffffff, FALSE),
+ HOWTO(R_390_PC32, 0, 2, 32, TRUE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_390_PC32", FALSE, 0,0xffffffff, TRUE),
+ HOWTO(R_390_GOT12, 0, 1, 12, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_390_GOT12", FALSE, 0,0x00000fff, FALSE),
+ HOWTO(R_390_GOT32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_390_GOT32", FALSE, 0,0xffffffff, FALSE),
+ HOWTO(R_390_PLT32, 0, 2, 32, TRUE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_390_PLT32", FALSE, 0,0xffffffff, TRUE),
+ HOWTO(R_390_COPY, 0, 4, 64, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_390_COPY", FALSE, 0,MINUS_ONE, FALSE),
+ HOWTO(R_390_GLOB_DAT, 0, 4, 64, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_390_GLOB_DAT", FALSE, 0,MINUS_ONE, FALSE),
+ HOWTO(R_390_JMP_SLOT, 0, 4, 64, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_390_JMP_SLOT", FALSE, 0,MINUS_ONE, FALSE),
+ HOWTO(R_390_RELATIVE, 0, 4, 64, TRUE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_390_RELATIVE", FALSE, 0,MINUS_ONE, FALSE),
+ HOWTO(R_390_GOTOFF32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_390_GOTOFF32", FALSE, 0,MINUS_ONE, FALSE),
+ HOWTO(R_390_GOTPC, 0, 4, 64, TRUE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_390_GOTPC", FALSE, 0,MINUS_ONE, TRUE),
+ HOWTO(R_390_GOT16, 0, 1, 16, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_390_GOT16", FALSE, 0,0x0000ffff, FALSE),
+ HOWTO(R_390_PC16, 0, 1, 16, TRUE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_390_PC16", FALSE, 0,0x0000ffff, TRUE),
+ HOWTO(R_390_PC16DBL, 1, 1, 16, TRUE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_390_PC16DBL", FALSE, 0,0x0000ffff, TRUE),
+ HOWTO(R_390_PLT16DBL, 1, 1, 16, TRUE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_390_PLT16DBL", FALSE, 0,0x0000ffff, TRUE),
+ HOWTO(R_390_PC32DBL, 1, 2, 32, TRUE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_390_PC32DBL", FALSE, 0,0xffffffff, TRUE),
+ HOWTO(R_390_PLT32DBL, 1, 2, 32, TRUE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_390_PLT32DBL", FALSE, 0,0xffffffff, TRUE),
+ HOWTO(R_390_GOTPCDBL, 1, 2, 32, TRUE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_390_GOTPCDBL", FALSE, 0,MINUS_ONE, TRUE),
+ HOWTO(R_390_64, 0, 4, 64, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_390_64", FALSE, 0,MINUS_ONE, FALSE),
+ HOWTO(R_390_PC64, 0, 4, 64, TRUE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_390_PC64", FALSE, 0,MINUS_ONE, TRUE),
+ HOWTO(R_390_GOT64, 0, 4, 64, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_390_GOT64", FALSE, 0,MINUS_ONE, FALSE),
+ HOWTO(R_390_PLT64, 0, 4, 64, TRUE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_390_PLT64", FALSE, 0,MINUS_ONE, TRUE),
+ HOWTO(R_390_GOTENT, 1, 2, 32, TRUE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_390_GOTENT", FALSE, 0,MINUS_ONE, TRUE),
+ HOWTO(R_390_GOTOFF16, 0, 1, 16, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_390_GOTOFF16", FALSE, 0,0x0000ffff, FALSE),
+ HOWTO(R_390_GOTOFF64, 0, 4, 64, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_390_GOTOFF64", FALSE, 0,MINUS_ONE, FALSE),
+ HOWTO(R_390_GOTPLT12, 0, 1, 12, FALSE, 0, complain_overflow_dont,
+ bfd_elf_generic_reloc, "R_390_GOTPLT12", FALSE, 0,0x00000fff, FALSE),
+ HOWTO(R_390_GOTPLT16, 0, 1, 16, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_390_GOTPLT16", FALSE, 0,0x0000ffff, FALSE),
+ HOWTO(R_390_GOTPLT32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_390_GOTPLT32", FALSE, 0,0xffffffff, FALSE),
+ HOWTO(R_390_GOTPLT64, 0, 4, 64, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_390_GOTPLT64", FALSE, 0,MINUS_ONE, FALSE),
+ HOWTO(R_390_GOTPLTENT, 1, 2, 32, TRUE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_390_GOTPLTENT",FALSE, 0,MINUS_ONE, TRUE),
+ HOWTO(R_390_PLTOFF16, 0, 1, 16, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_390_PLTOFF16", FALSE, 0,0x0000ffff, FALSE),
+ HOWTO(R_390_PLTOFF32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_390_PLTOFF32", FALSE, 0,0xffffffff, FALSE),
+ HOWTO(R_390_PLTOFF64, 0, 4, 64, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_390_PLTOFF64", FALSE, 0,MINUS_ONE, FALSE),
+ HOWTO(R_390_TLS_LOAD, 0, 0, 0, FALSE, 0, complain_overflow_dont,
+ s390_tls_reloc, "R_390_TLS_LOAD", FALSE, 0, 0, FALSE),
+ HOWTO(R_390_TLS_GDCALL, 0, 0, 0, FALSE, 0, complain_overflow_dont,
+ s390_tls_reloc, "R_390_TLS_GDCALL", FALSE, 0, 0, FALSE),
+ HOWTO(R_390_TLS_LDCALL, 0, 0, 0, FALSE, 0, complain_overflow_dont,
+ s390_tls_reloc, "R_390_TLS_LDCALL", FALSE, 0, 0, FALSE),
+ EMPTY_HOWTO (R_390_TLS_GD32), /* Empty entry for R_390_TLS_GD32. */
+ HOWTO(R_390_TLS_GD64, 0, 4, 64, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_390_TLS_GD64", FALSE, 0, MINUS_ONE, FALSE),
+ HOWTO(R_390_TLS_GOTIE12, 0, 1, 12, FALSE, 0, complain_overflow_dont,
+ bfd_elf_generic_reloc, "R_390_TLS_GOTIE12", FALSE, 0, 0x00000fff, FALSE),
+ EMPTY_HOWTO (R_390_TLS_GOTIE32), /* Empty entry for R_390_TLS_GOTIE32. */
+ HOWTO(R_390_TLS_GOTIE64, 0, 4, 64, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_390_TLS_GOTIE64", FALSE, 0, MINUS_ONE, FALSE),
+ EMPTY_HOWTO (R_390_TLS_LDM32), /* Empty entry for R_390_TLS_LDM32. */
+ HOWTO(R_390_TLS_LDM64, 0, 4, 64, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_390_TLS_LDM64", FALSE, 0, MINUS_ONE, FALSE),
+ EMPTY_HOWTO (R_390_TLS_IE32), /* Empty entry for R_390_TLS_IE32. */
+ HOWTO(R_390_TLS_IE64, 0, 4, 64, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_390_TLS_IE64", FALSE, 0, MINUS_ONE, FALSE),
+ HOWTO(R_390_TLS_IEENT, 1, 2, 32, TRUE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_390_TLS_IEENT", FALSE, 0, MINUS_ONE, TRUE),
+ EMPTY_HOWTO (R_390_TLS_LE32), /* Empty entry for R_390_TLS_LE32. */
+ HOWTO(R_390_TLS_LE64, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_390_TLS_LE64", FALSE, 0, MINUS_ONE, FALSE),
+ EMPTY_HOWTO (R_390_TLS_LDO32), /* Empty entry for R_390_TLS_LDO32. */
+ HOWTO(R_390_TLS_LDO64, 0, 4, 64, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_390_TLS_LDO64", FALSE, 0, MINUS_ONE, FALSE),
+ HOWTO(R_390_TLS_DTPMOD, 0, 4, 64, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_390_TLS_DTPMOD", FALSE, 0, MINUS_ONE, FALSE),
+ HOWTO(R_390_TLS_DTPOFF, 0, 4, 64, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_390_TLS_DTPOFF", FALSE, 0, MINUS_ONE, FALSE),
+ HOWTO(R_390_TLS_TPOFF, 0, 4, 64, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_390_TLS_TPOFF", FALSE, 0, MINUS_ONE, FALSE),
+ HOWTO(R_390_20, 0, 2, 20, FALSE, 8, complain_overflow_dont,
+ s390_elf_ldisp_reloc, "R_390_20", FALSE, 0,0x0fffff00, FALSE),
+ HOWTO(R_390_GOT20, 0, 2, 20, FALSE, 8, complain_overflow_dont,
+ s390_elf_ldisp_reloc, "R_390_GOT20", FALSE, 0,0x0fffff00, FALSE),
+ HOWTO(R_390_GOTPLT20, 0, 2, 20, FALSE, 8, complain_overflow_dont,
+ s390_elf_ldisp_reloc, "R_390_GOTPLT20", FALSE, 0,0x0fffff00, FALSE),
+ HOWTO(R_390_TLS_GOTIE20, 0, 2, 20, FALSE, 8, complain_overflow_dont,
+ s390_elf_ldisp_reloc, "R_390_TLS_GOTIE20", FALSE, 0,0x0fffff00, FALSE),
+ HOWTO(R_390_IRELATIVE, 0, 4, 64, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_390_IRELATIVE", FALSE, 0, MINUS_ONE, FALSE),
+ HOWTO(R_390_PC12DBL, 1, 1, 12, TRUE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_390_PC12DBL", FALSE, 0,0x00000fff, TRUE),
+ HOWTO(R_390_PLT12DBL, 1, 1, 12, TRUE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_390_PLT12DBL", FALSE, 0,0x00000fff, TRUE),
+ HOWTO(R_390_PC24DBL, 1, 2, 24, TRUE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_390_PC24DBL", FALSE, 0,0x00ffffff, TRUE),
+ HOWTO(R_390_PLT24DBL, 1, 2, 24, TRUE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_390_PLT24DBL", FALSE, 0,0x00ffffff, TRUE),
+};
+
+/* GNU extension to record C++ vtable hierarchy. */
+static reloc_howto_type elf64_s390_vtinherit_howto =
+ HOWTO (R_390_GNU_VTINHERIT, 0,4,0,FALSE,0,complain_overflow_dont, NULL, "R_390_GNU_VTINHERIT", FALSE,0, 0, FALSE);
+static reloc_howto_type elf64_s390_vtentry_howto =
+ HOWTO (R_390_GNU_VTENTRY, 0,4,0,FALSE,0,complain_overflow_dont, _bfd_elf_rel_vtable_reloc_fn,"R_390_GNU_VTENTRY", FALSE,0,0, FALSE);
+
+static reloc_howto_type *
+elf_s390_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ bfd_reloc_code_real_type code)
+{
+ switch (code)
+ {
+ case BFD_RELOC_NONE:
+ return &elf_howto_table[(int) R_390_NONE];
+ case BFD_RELOC_8:
+ return &elf_howto_table[(int) R_390_8];
+ case BFD_RELOC_390_12:
+ return &elf_howto_table[(int) R_390_12];
+ case BFD_RELOC_16:
+ return &elf_howto_table[(int) R_390_16];
+ case BFD_RELOC_32:
+ return &elf_howto_table[(int) R_390_32];
+ case BFD_RELOC_CTOR:
+ return &elf_howto_table[(int) R_390_32];
+ case BFD_RELOC_32_PCREL:
+ return &elf_howto_table[(int) R_390_PC32];
+ case BFD_RELOC_390_GOT12:
+ return &elf_howto_table[(int) R_390_GOT12];
+ case BFD_RELOC_32_GOT_PCREL:
+ return &elf_howto_table[(int) R_390_GOT32];
+ case BFD_RELOC_390_PLT32:
+ return &elf_howto_table[(int) R_390_PLT32];
+ case BFD_RELOC_390_COPY:
+ return &elf_howto_table[(int) R_390_COPY];
+ case BFD_RELOC_390_GLOB_DAT:
+ return &elf_howto_table[(int) R_390_GLOB_DAT];
+ case BFD_RELOC_390_JMP_SLOT:
+ return &elf_howto_table[(int) R_390_JMP_SLOT];
+ case BFD_RELOC_390_RELATIVE:
+ return &elf_howto_table[(int) R_390_RELATIVE];
+ case BFD_RELOC_32_GOTOFF:
+ return &elf_howto_table[(int) R_390_GOTOFF32];
+ case BFD_RELOC_390_GOTPC:
+ return &elf_howto_table[(int) R_390_GOTPC];
+ case BFD_RELOC_390_GOT16:
+ return &elf_howto_table[(int) R_390_GOT16];
+ case BFD_RELOC_16_PCREL:
+ return &elf_howto_table[(int) R_390_PC16];
+ case BFD_RELOC_390_PC12DBL:
+ return &elf_howto_table[(int) R_390_PC12DBL];
+ case BFD_RELOC_390_PLT12DBL:
+ return &elf_howto_table[(int) R_390_PLT12DBL];
+ case BFD_RELOC_390_PC16DBL:
+ return &elf_howto_table[(int) R_390_PC16DBL];
+ case BFD_RELOC_390_PLT16DBL:
+ return &elf_howto_table[(int) R_390_PLT16DBL];
+ case BFD_RELOC_390_PC24DBL:
+ return &elf_howto_table[(int) R_390_PC24DBL];
+ case BFD_RELOC_390_PLT24DBL:
+ return &elf_howto_table[(int) R_390_PLT24DBL];
+ case BFD_RELOC_390_PC32DBL:
+ return &elf_howto_table[(int) R_390_PC32DBL];
+ case BFD_RELOC_390_PLT32DBL:
+ return &elf_howto_table[(int) R_390_PLT32DBL];
+ case BFD_RELOC_390_GOTPCDBL:
+ return &elf_howto_table[(int) R_390_GOTPCDBL];
+ case BFD_RELOC_64:
+ return &elf_howto_table[(int) R_390_64];
+ case BFD_RELOC_64_PCREL:
+ return &elf_howto_table[(int) R_390_PC64];
+ case BFD_RELOC_390_GOT64:
+ return &elf_howto_table[(int) R_390_GOT64];
+ case BFD_RELOC_390_PLT64:
+ return &elf_howto_table[(int) R_390_PLT64];
+ case BFD_RELOC_390_GOTENT:
+ return &elf_howto_table[(int) R_390_GOTENT];
+ case BFD_RELOC_16_GOTOFF:
+ return &elf_howto_table[(int) R_390_GOTOFF16];
+ case BFD_RELOC_390_GOTOFF64:
+ return &elf_howto_table[(int) R_390_GOTOFF64];
+ case BFD_RELOC_390_GOTPLT12:
+ return &elf_howto_table[(int) R_390_GOTPLT12];
+ case BFD_RELOC_390_GOTPLT16:
+ return &elf_howto_table[(int) R_390_GOTPLT16];
+ case BFD_RELOC_390_GOTPLT32:
+ return &elf_howto_table[(int) R_390_GOTPLT32];
+ case BFD_RELOC_390_GOTPLT64:
+ return &elf_howto_table[(int) R_390_GOTPLT64];
+ case BFD_RELOC_390_GOTPLTENT:
+ return &elf_howto_table[(int) R_390_GOTPLTENT];
+ case BFD_RELOC_390_PLTOFF16:
+ return &elf_howto_table[(int) R_390_PLTOFF16];
+ case BFD_RELOC_390_PLTOFF32:
+ return &elf_howto_table[(int) R_390_PLTOFF32];
+ case BFD_RELOC_390_PLTOFF64:
+ return &elf_howto_table[(int) R_390_PLTOFF64];
+ case BFD_RELOC_390_TLS_LOAD:
+ return &elf_howto_table[(int) R_390_TLS_LOAD];
+ case BFD_RELOC_390_TLS_GDCALL:
+ return &elf_howto_table[(int) R_390_TLS_GDCALL];
+ case BFD_RELOC_390_TLS_LDCALL:
+ return &elf_howto_table[(int) R_390_TLS_LDCALL];
+ case BFD_RELOC_390_TLS_GD64:
+ return &elf_howto_table[(int) R_390_TLS_GD64];
+ case BFD_RELOC_390_TLS_GOTIE12:
+ return &elf_howto_table[(int) R_390_TLS_GOTIE12];
+ case BFD_RELOC_390_TLS_GOTIE64:
+ return &elf_howto_table[(int) R_390_TLS_GOTIE64];
+ case BFD_RELOC_390_TLS_LDM64:
+ return &elf_howto_table[(int) R_390_TLS_LDM64];
+ case BFD_RELOC_390_TLS_IE64:
+ return &elf_howto_table[(int) R_390_TLS_IE64];
+ case BFD_RELOC_390_TLS_IEENT:
+ return &elf_howto_table[(int) R_390_TLS_IEENT];
+ case BFD_RELOC_390_TLS_LE64:
+ return &elf_howto_table[(int) R_390_TLS_LE64];
+ case BFD_RELOC_390_TLS_LDO64:
+ return &elf_howto_table[(int) R_390_TLS_LDO64];
+ case BFD_RELOC_390_TLS_DTPMOD:
+ return &elf_howto_table[(int) R_390_TLS_DTPMOD];
+ case BFD_RELOC_390_TLS_DTPOFF:
+ return &elf_howto_table[(int) R_390_TLS_DTPOFF];
+ case BFD_RELOC_390_TLS_TPOFF:
+ return &elf_howto_table[(int) R_390_TLS_TPOFF];
+ case BFD_RELOC_390_20:
+ return &elf_howto_table[(int) R_390_20];
+ case BFD_RELOC_390_GOT20:
+ return &elf_howto_table[(int) R_390_GOT20];
+ case BFD_RELOC_390_GOTPLT20:
+ return &elf_howto_table[(int) R_390_GOTPLT20];
+ case BFD_RELOC_390_TLS_GOTIE20:
+ return &elf_howto_table[(int) R_390_TLS_GOTIE20];
+ case BFD_RELOC_390_IRELATIVE:
+ return &elf_howto_table[(int) R_390_IRELATIVE];
+ case BFD_RELOC_VTABLE_INHERIT:
+ return &elf64_s390_vtinherit_howto;
+ case BFD_RELOC_VTABLE_ENTRY:
+ return &elf64_s390_vtentry_howto;
+ default:
+ break;
+ }
+ return 0;
+}
+
+static reloc_howto_type *
+elf_s390_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ const char *r_name)
+{
+ unsigned int i;
+
+ for (i = 0;
+ i < sizeof (elf_howto_table) / sizeof (elf_howto_table[0]);
+ i++)
+ if (elf_howto_table[i].name != NULL
+ && strcasecmp (elf_howto_table[i].name, r_name) == 0)
+ return &elf_howto_table[i];
+
+ if (strcasecmp (elf64_s390_vtinherit_howto.name, r_name) == 0)
+ return &elf64_s390_vtinherit_howto;
+ if (strcasecmp (elf64_s390_vtentry_howto.name, r_name) == 0)
+ return &elf64_s390_vtentry_howto;
+
+ return NULL;
+}
+
+/* We need to use ELF64_R_TYPE so we have our own copy of this function,
+ and elf64-s390.c has its own copy. */
+
+static void
+elf_s390_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED,
+ arelent *cache_ptr,
+ Elf_Internal_Rela *dst)
+{
+ unsigned int r_type = ELF64_R_TYPE(dst->r_info);
+ switch (r_type)
+ {
+ case R_390_GNU_VTINHERIT:
+ cache_ptr->howto = &elf64_s390_vtinherit_howto;
+ break;
+
+ case R_390_GNU_VTENTRY:
+ cache_ptr->howto = &elf64_s390_vtentry_howto;
+ break;
+
+ default:
+ if (r_type >= sizeof (elf_howto_table) / sizeof (elf_howto_table[0]))
+ {
+ (*_bfd_error_handler) (_("%B: invalid relocation type %d"),
+ abfd, (int) r_type);
+ r_type = R_390_NONE;
+ }
+ cache_ptr->howto = &elf_howto_table[r_type];
+ }
+}
+
+/* A relocation function which doesn't do anything. */
+static bfd_reloc_status_type
+s390_tls_reloc (bfd *abfd ATTRIBUTE_UNUSED,
+ arelent *reloc_entry,
+ asymbol *symbol ATTRIBUTE_UNUSED,
+ void * data ATTRIBUTE_UNUSED,
+ asection *input_section,
+ bfd *output_bfd,
+ char **error_message ATTRIBUTE_UNUSED)
+{
+ if (output_bfd)
+ reloc_entry->address += input_section->output_offset;
+ return bfd_reloc_ok;
+}
+
+/* Handle the large displacement relocs. */
+static bfd_reloc_status_type
+s390_elf_ldisp_reloc (bfd *abfd,
+ arelent *reloc_entry,
+ asymbol *symbol,
+ void * data,
+ asection *input_section,
+ bfd *output_bfd,
+ char **error_message ATTRIBUTE_UNUSED)
+{
+ reloc_howto_type *howto = reloc_entry->howto;
+ bfd_vma relocation;
+ bfd_vma insn;
+
+ 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;
+ }
+ if (output_bfd != NULL)
+ return bfd_reloc_continue;
+
+ if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
+ 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;
+ }
+
+ insn = bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
+ insn |= (relocation & 0xfff) << 16 | (relocation & 0xff000) >> 4;
+ bfd_put_32 (abfd, insn, (bfd_byte *) data + reloc_entry->address);
+
+ if ((bfd_signed_vma) relocation < - 0x80000
+ || (bfd_signed_vma) relocation > 0x7ffff)
+ return bfd_reloc_overflow;
+ else
+ return bfd_reloc_ok;
+}
+
+static bfd_boolean
+elf_s390_is_local_label_name (bfd *abfd, const char *name)
+{
+ if (name[0] == '.' && (name[1] == 'X' || name[1] == 'L'))
+ return TRUE;
+
+ return _bfd_elf_is_local_label_name (abfd, name);
+}
+
+/* Functions for the 390 ELF linker. */
+
+/* The name of the dynamic interpreter. This is put in the .interp
+ section. */
+
+#define ELF_DYNAMIC_INTERPRETER "/lib/ld64.so.1"
+
+/* If ELIMINATE_COPY_RELOCS is non-zero, the linker will try to avoid
+ copying dynamic variables from a shared lib into an app's dynbss
+ section, and instead use a dynamic relocation to point into the
+ shared lib. */
+#define ELIMINATE_COPY_RELOCS 1
+
+/* The size in bytes of the first entry in the procedure linkage table. */
+#define PLT_FIRST_ENTRY_SIZE 32
+/* The size in bytes of an entry in the procedure linkage table. */
+#define PLT_ENTRY_SIZE 32
+
+#define GOT_ENTRY_SIZE 8
+
+#define RELA_ENTRY_SIZE sizeof (Elf64_External_Rela)
+
+/* The first three 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 386
+ supplement to see how this works. */
+
+/* For the s390, simple addr offset can only be 0 - 4096.
+ To use the full 16777216 TB address space, several instructions
+ are needed to load an address in a register and execute
+ a branch( or just saving the address)
+
+ Furthermore, only r 0 and 1 are free to use!!! */
+
+/* The first 3 words in the GOT are then reserved.
+ Word 0 is the address of the dynamic table.
+ Word 1 is a pointer to a structure describing the object
+ Word 2 is used to point to the loader entry address.
+
+ The code for PLT entries looks like this:
+
+ The GOT holds the address in the PLT to be executed.
+ The loader then gets:
+ 24(15) = Pointer to the structure describing the object.
+ 28(15) = Offset in symbol table
+ The loader must then find the module where the function is
+ and insert the address in the GOT.
+
+ PLT1: LARL 1,<fn>@GOTENT # 6 bytes Load address of GOT entry in r1
+ LG 1,0(1) # 6 bytes Load address from GOT in r1
+ BCR 15,1 # 2 bytes Jump to address
+ RET1: BASR 1,0 # 2 bytes Return from GOT 1st time
+ LGF 1,12(1) # 6 bytes Load offset in symbl table in r1
+ BRCL 15,-x # 6 bytes Jump to start of PLT
+ .long ? # 4 bytes offset into .rela.plt
+
+ Total = 32 bytes per PLT entry
+ Fixup at offset 2: relative address to GOT entry
+ Fixup at offset 22: relative branch to PLT0
+ Fixup at offset 28: 32 bit offset into .rela.plt
+
+ A 32 bit offset into the symbol table is enough. It allows for
+ .rela.plt sections up to a size of 2 gigabyte. A single dynamic
+ object (the main program, any shared library) is limited to 4GB in
+ size. Having a .rela.plt of 2GB would already make the .plt
+ section bigger than 8GB. */
+
+static const bfd_byte elf_s390x_plt_entry[PLT_ENTRY_SIZE] =
+ {
+ 0xc0, 0x10, 0x00, 0x00, 0x00, 0x00, /* larl %r1,. */
+ 0xe3, 0x10, 0x10, 0x00, 0x00, 0x04, /* lg %r1,0(%r1) */
+ 0x07, 0xf1, /* br %r1 */
+ 0x0d, 0x10, /* basr %r1,%r0 */
+ 0xe3, 0x10, 0x10, 0x0c, 0x00, 0x14, /* lgf %r1,12(%r1) */
+ 0xc0, 0xf4, 0x00, 0x00, 0x00, 0x00, /* jg first plt */
+ 0x00, 0x00, 0x00, 0x00 /* .long 0x00000000 */
+ };
+
+/* The first PLT entry pushes the offset into the symbol table
+ from R1 onto the stack at 56(15) and the loader object info
+ at 48(15), loads the loader address in R1 and jumps to it. */
+
+/* The first entry in the PLT:
+
+ PLT0:
+ STG 1,56(15) # r1 contains the offset into the symbol table
+ LARL 1,_GLOBAL_OFFSET_TABLE # load address of global offset table
+ MVC 48(8,15),8(1) # move loader ino (object struct address) to stack
+ LG 1,16(1) # get entry address of loader
+ BCR 15,1 # jump to loader
+
+ Fixup at offset 8: relative address to start of GOT. */
+
+static const bfd_byte elf_s390x_first_plt_entry[PLT_FIRST_ENTRY_SIZE] =
+ {
+ 0xe3, 0x10, 0xf0, 0x38, 0x00, 0x24, /* stg %r1,56(%r15) */
+ 0xc0, 0x10, 0x00, 0x00, 0x00, 0x00, /* larl %r1,. */
+ 0xd2, 0x07, 0xf0, 0x30, 0x10, 0x08, /* mvc 48(8,%r15),8(%r1) */
+ 0xe3, 0x10, 0x10, 0x10, 0x00, 0x04, /* lg %r1,16(%r1) */
+ 0x07, 0xf1, /* br %r1 */
+ 0x07, 0x00, /* nopr %r0 */
+ 0x07, 0x00, /* nopr %r0 */
+ 0x07, 0x00 /* nopr %r0 */
+ };
+
+
+/* s390 ELF linker hash entry. */
+
+struct elf_s390_link_hash_entry
+{
+ struct elf_link_hash_entry elf;
+
+ /* Track dynamic relocs copied for this symbol. */
+ struct elf_dyn_relocs *dyn_relocs;
+
+ /* Number of GOTPLT references for a function. */
+ bfd_signed_vma gotplt_refcount;
+
+#define GOT_UNKNOWN 0
+#define GOT_NORMAL 1
+#define GOT_TLS_GD 2
+#define GOT_TLS_IE 3
+#define GOT_TLS_IE_NLT 3
+ unsigned char tls_type;
+
+ /* For pointer equality reasons we might need to change the symbol
+ type from STT_GNU_IFUNC to STT_FUNC together with its value and
+ section entry. So after alloc_dynrelocs only these values should
+ be used. In order to check whether a symbol is IFUNC use
+ s390_is_ifunc_symbol_p. */
+ bfd_vma ifunc_resolver_address;
+ asection *ifunc_resolver_section;
+};
+
+#define elf_s390_hash_entry(ent) \
+ ((struct elf_s390_link_hash_entry *)(ent))
+
+/* This structure represents an entry in the local PLT list needed for
+ local IFUNC symbols. */
+struct plt_entry
+{
+ /* The section of the local symbol.
+ Set in relocate_section and used in finish_dynamic_sections. */
+ asection *sec;
+
+ union
+ {
+ bfd_signed_vma refcount;
+ bfd_vma offset;
+ } plt;
+};
+
+/* NOTE: Keep this structure in sync with
+ the one declared in elf32-s390.c. */
+struct elf_s390_obj_tdata
+{
+ struct elf_obj_tdata root;
+
+ /* A local PLT is needed for ifunc symbols. */
+ struct plt_entry *local_plt;
+
+ /* TLS type for each local got entry. */
+ char *local_got_tls_type;
+};
+
+#define elf_s390_tdata(abfd) \
+ ((struct elf_s390_obj_tdata *) (abfd)->tdata.any)
+
+#define elf_s390_local_plt(abfd) \
+ (elf_s390_tdata (abfd)->local_plt)
+
+#define elf_s390_local_got_tls_type(abfd) \
+ (elf_s390_tdata (abfd)->local_got_tls_type)
+
+#define is_s390_elf(bfd) \
+ (bfd_get_flavour (bfd) == bfd_target_elf_flavour \
+ && elf_tdata (bfd) != NULL \
+ && elf_object_id (bfd) == S390_ELF_DATA)
+
+static bfd_boolean
+elf_s390_mkobject (bfd *abfd)
+{
+ return bfd_elf_allocate_object (abfd, sizeof (struct elf_s390_obj_tdata),
+ S390_ELF_DATA);
+}
+
+static bfd_boolean
+elf_s390_object_p (bfd *abfd)
+{
+ /* Set the right machine number for an s390 elf32 file. */
+ return bfd_default_set_arch_mach (abfd, bfd_arch_s390, bfd_mach_s390_64);
+}
+
+/* s390 ELF linker hash table. */
+
+struct elf_s390_link_hash_table
+{
+ struct elf_link_hash_table elf;
+
+ /* Short-cuts to get to dynamic linker sections. */
+ asection *sdynbss;
+ asection *srelbss;
+ asection *irelifunc;
+
+ union {
+ bfd_signed_vma refcount;
+ bfd_vma offset;
+ } tls_ldm_got;
+
+ /* Small local sym cache. */
+ struct sym_cache sym_cache;
+};
+
+/* Get the s390 ELF linker hash table from a link_info structure. */
+
+#define elf_s390_hash_table(p) \
+ (elf_hash_table_id ((struct elf_link_hash_table *) ((p)->hash)) \
+ == S390_ELF_DATA ? ((struct elf_s390_link_hash_table *) ((p)->hash)) : NULL)
+
+#define ELF64 1
+#include "elf-s390-common.c"
+
+/* Create an entry in an s390 ELF linker hash table. */
+
+static struct bfd_hash_entry *
+link_hash_newfunc (struct bfd_hash_entry *entry,
+ struct bfd_hash_table *table,
+ const char *string)
+{
+ /* Allocate the structure if it has not already been allocated by a
+ subclass. */
+ if (entry == NULL)
+ {
+ entry = bfd_hash_allocate (table,
+ sizeof (struct elf_s390_link_hash_entry));
+ if (entry == NULL)
+ return entry;
+ }
+
+ /* Call the allocation method of the superclass. */
+ entry = _bfd_elf_link_hash_newfunc (entry, table, string);
+ if (entry != NULL)
+ {
+ struct elf_s390_link_hash_entry *eh;
+
+ eh = (struct elf_s390_link_hash_entry *) entry;
+ eh->dyn_relocs = NULL;
+ eh->gotplt_refcount = 0;
+ eh->tls_type = GOT_UNKNOWN;
+ eh->ifunc_resolver_address = 0;
+ eh->ifunc_resolver_section = NULL;
+ }
+
+ return entry;
+}
+
+/* Create an s390 ELF linker hash table. */
+
+static struct bfd_link_hash_table *
+elf_s390_link_hash_table_create (bfd *abfd)
+{
+ struct elf_s390_link_hash_table *ret;
+ bfd_size_type amt = sizeof (struct elf_s390_link_hash_table);
+
+ ret = (struct elf_s390_link_hash_table *) bfd_zmalloc (amt);
+ if (ret == NULL)
+ return NULL;
+
+ if (!_bfd_elf_link_hash_table_init (&ret->elf, abfd, link_hash_newfunc,
+ sizeof (struct elf_s390_link_hash_entry),
+ S390_ELF_DATA))
+ {
+ free (ret);
+ return NULL;
+ }
+
+ return &ret->elf.root;
+}
+
+/* Create .got, .gotplt, and .rela.got sections in DYNOBJ, and set up
+ shortcuts to them in our hash table. */
+
+static bfd_boolean
+create_got_section (bfd *dynobj,
+ struct bfd_link_info *info)
+{
+ struct elf_s390_link_hash_table *htab;
+
+ if (! _bfd_elf_create_got_section (dynobj, info))
+ return FALSE;
+
+ htab = elf_s390_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ htab->elf.sgot = bfd_get_linker_section (dynobj, ".got");
+ htab->elf.sgotplt = bfd_get_linker_section (dynobj, ".got.plt");
+ htab->elf.srelgot = bfd_get_linker_section (dynobj, ".rela.got");
+ if (!htab->elf.sgot || !htab->elf.sgotplt || !htab->elf.srelgot)
+ abort ();
+ return TRUE;
+}
+
+/* Create .plt, .rela.plt, .got, .got.plt, .rela.got, .dynbss, and
+ .rela.bss sections in DYNOBJ, and set up shortcuts to them in our
+ hash table. */
+
+static bfd_boolean
+elf_s390_create_dynamic_sections (bfd *dynobj,
+ struct bfd_link_info *info)
+{
+ struct elf_s390_link_hash_table *htab;
+
+ htab = elf_s390_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ if (!htab->elf.sgot && !create_got_section (dynobj, info))
+ return FALSE;
+
+ if (!_bfd_elf_create_dynamic_sections (dynobj, info))
+ return FALSE;
+
+ htab->elf.splt = bfd_get_linker_section (dynobj, ".plt");
+ htab->elf.srelplt = bfd_get_linker_section (dynobj, ".rela.plt");
+ htab->sdynbss = bfd_get_linker_section (dynobj, ".dynbss");
+ if (!info->shared)
+ htab->srelbss = bfd_get_linker_section (dynobj, ".rela.bss");
+
+ if (!htab->elf.splt || !htab->elf.srelplt || !htab->sdynbss
+ || (!info->shared && !htab->srelbss))
+ abort ();
+
+ return TRUE;
+}
+
+/* Copy the extra info we tack onto an elf_link_hash_entry. */
+
+static void
+elf_s390_copy_indirect_symbol (struct bfd_link_info *info,
+ struct elf_link_hash_entry *dir,
+ struct elf_link_hash_entry *ind)
+{
+ struct elf_s390_link_hash_entry *edir, *eind;
+
+ edir = (struct elf_s390_link_hash_entry *) dir;
+ eind = (struct elf_s390_link_hash_entry *) ind;
+
+ if (eind->dyn_relocs != NULL)
+ {
+ if (edir->dyn_relocs != NULL)
+ {
+ struct elf_dyn_relocs **pp;
+ struct elf_dyn_relocs *p;
+
+ /* Add reloc counts against the indirect sym to the direct sym
+ list. Merge any entries against the same section. */
+ for (pp = &eind->dyn_relocs; (p = *pp) != NULL; )
+ {
+ struct elf_dyn_relocs *q;
+
+ for (q = edir->dyn_relocs; q != NULL; q = q->next)
+ if (q->sec == p->sec)
+ {
+ q->pc_count += p->pc_count;
+ q->count += p->count;
+ *pp = p->next;
+ break;
+ }
+ if (q == NULL)
+ pp = &p->next;
+ }
+ *pp = edir->dyn_relocs;
+ }
+
+ edir->dyn_relocs = eind->dyn_relocs;
+ eind->dyn_relocs = NULL;
+ }
+
+ if (ind->root.type == bfd_link_hash_indirect
+ && dir->got.refcount <= 0)
+ {
+ edir->tls_type = eind->tls_type;
+ eind->tls_type = GOT_UNKNOWN;
+ }
+
+ if (ELIMINATE_COPY_RELOCS
+ && ind->root.type != bfd_link_hash_indirect
+ && dir->dynamic_adjusted)
+ {
+ /* If called to transfer flags for a weakdef during processing
+ of elf_adjust_dynamic_symbol, don't copy non_got_ref.
+ We clear it ourselves for ELIMINATE_COPY_RELOCS. */
+ dir->ref_dynamic |= ind->ref_dynamic;
+ dir->ref_regular |= ind->ref_regular;
+ dir->ref_regular_nonweak |= ind->ref_regular_nonweak;
+ dir->needs_plt |= ind->needs_plt;
+ }
+ else
+ _bfd_elf_link_hash_copy_indirect (info, dir, ind);
+}
+
+static int
+elf_s390_tls_transition (struct bfd_link_info *info,
+ int r_type,
+ int is_local)
+{
+ if (info->shared)
+ return r_type;
+
+ switch (r_type)
+ {
+ case R_390_TLS_GD64:
+ case R_390_TLS_IE64:
+ if (is_local)
+ return R_390_TLS_LE64;
+ return R_390_TLS_IE64;
+ case R_390_TLS_GOTIE64:
+ if (is_local)
+ return R_390_TLS_LE64;
+ return R_390_TLS_GOTIE64;
+ case R_390_TLS_LDM64:
+ return R_390_TLS_LE64;
+ }
+
+ return 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 bfd_boolean
+elf_s390_check_relocs (bfd *abfd,
+ struct bfd_link_info *info,
+ asection *sec,
+ const Elf_Internal_Rela *relocs)
+{
+ struct elf_s390_link_hash_table *htab;
+ 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;
+ bfd_signed_vma *local_got_refcounts;
+ int tls_type, old_tls_type;
+
+ if (info->relocatable)
+ return TRUE;
+
+ BFD_ASSERT (is_s390_elf (abfd));
+
+ htab = elf_s390_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ symtab_hdr = &elf_symtab_hdr (abfd);
+ sym_hashes = elf_sym_hashes (abfd);
+ local_got_refcounts = elf_local_got_refcounts (abfd);
+
+ sreloc = NULL;
+
+ rel_end = relocs + sec->reloc_count;
+ for (rel = relocs; rel < rel_end; rel++)
+ {
+ unsigned int r_type;
+ unsigned long r_symndx;
+ struct elf_link_hash_entry *h;
+ Elf_Internal_Sym *isym;
+
+ r_symndx = ELF64_R_SYM (rel->r_info);
+
+ if (r_symndx >= NUM_SHDR_ENTRIES (symtab_hdr))
+ {
+ (*_bfd_error_handler) (_("%B: bad symbol index: %d"),
+ abfd,
+ r_symndx);
+ return FALSE;
+ }
+
+ if (r_symndx < symtab_hdr->sh_info)
+ {
+ /* A local symbol. */
+ isym = bfd_sym_from_r_symndx (&htab->sym_cache,
+ abfd, r_symndx);
+ if (isym == NULL)
+ return FALSE;
+
+ if (ELF_ST_TYPE (isym->st_info) == STT_GNU_IFUNC)
+ {
+ struct plt_entry *plt;
+
+ if (htab->elf.dynobj == NULL)
+ htab->elf.dynobj = abfd;
+
+ if (!s390_elf_create_ifunc_sections (htab->elf.dynobj, info))
+ return FALSE;
+
+ if (local_got_refcounts == NULL)
+ {
+ if (!elf_s390_allocate_local_syminfo (abfd, symtab_hdr))
+ return FALSE;
+ local_got_refcounts = elf_local_got_refcounts (abfd);
+ }
+ plt = elf_s390_local_plt (abfd);
+ plt[r_symndx].plt.refcount++;
+ }
+ h = NULL;
+ }
+ 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;
+
+ /* PR15323, ref flags aren't set for references in the same
+ object. */
+ h->root.non_ir_ref = 1;
+ }
+
+ /* Create got section and local_got_refcounts array if they
+ are needed. */
+ r_type = elf_s390_tls_transition (info,
+ ELF64_R_TYPE (rel->r_info),
+ h == NULL);
+ switch (r_type)
+ {
+ case R_390_GOT12:
+ case R_390_GOT16:
+ case R_390_GOT20:
+ case R_390_GOT32:
+ case R_390_GOT64:
+ case R_390_GOTENT:
+ case R_390_GOTPLT12:
+ case R_390_GOTPLT16:
+ case R_390_GOTPLT20:
+ case R_390_GOTPLT32:
+ case R_390_GOTPLT64:
+ case R_390_GOTPLTENT:
+ case R_390_TLS_GD64:
+ case R_390_TLS_GOTIE12:
+ case R_390_TLS_GOTIE20:
+ case R_390_TLS_GOTIE64:
+ case R_390_TLS_IEENT:
+ case R_390_TLS_IE64:
+ case R_390_TLS_LDM64:
+ if (h == NULL
+ && local_got_refcounts == NULL)
+ {
+ if (!elf_s390_allocate_local_syminfo (abfd, symtab_hdr))
+ return FALSE;
+ local_got_refcounts = elf_local_got_refcounts (abfd);
+ }
+
+ /* Fall through. */
+ case R_390_GOTOFF16:
+ case R_390_GOTOFF32:
+ case R_390_GOTOFF64:
+ case R_390_GOTPC:
+ case R_390_GOTPCDBL:
+ if (htab->elf.sgot == NULL)
+ {
+ if (htab->elf.dynobj == NULL)
+ htab->elf.dynobj = abfd;
+ if (!create_got_section (htab->elf.dynobj, info))
+ return FALSE;
+ }
+ }
+
+ if (h != NULL)
+ {
+ if (htab->elf.dynobj == NULL)
+ htab->elf.dynobj = abfd;
+ if (!s390_elf_create_ifunc_sections (htab->elf.dynobj, info))
+ return FALSE;
+
+ /* Make sure an IFUNC symbol defined in a non-shared object
+ always gets a PLT slot. */
+ if (s390_is_ifunc_symbol_p (h) && h->def_regular)
+ {
+ /* The symbol is called by the dynamic loader in order
+ to resolve the relocation. So it is in fact also
+ referenced. */
+ h->ref_regular = 1;
+ h->needs_plt = 1;
+ }
+ }
+
+ switch (r_type)
+ {
+ case R_390_GOTOFF16:
+ case R_390_GOTOFF32:
+ case R_390_GOTOFF64:
+ case R_390_GOTPC:
+ case R_390_GOTPCDBL:
+ /* These relocs do not need a GOT slot. They just load the
+ GOT pointer itself or address something else relative to
+ the GOT. Since the GOT pointer has been set up above we
+ are done. */
+ break;
+
+ case R_390_PLT12DBL:
+ case R_390_PLT16DBL:
+ case R_390_PLT24DBL:
+ case R_390_PLT32:
+ case R_390_PLT32DBL:
+ case R_390_PLT64:
+ case R_390_PLTOFF16:
+ case R_390_PLTOFF32:
+ case R_390_PLTOFF64:
+ /* 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)
+ {
+ h->needs_plt = 1;
+ h->plt.refcount += 1;
+ }
+ break;
+
+ case R_390_GOTPLT12:
+ case R_390_GOTPLT16:
+ case R_390_GOTPLT20:
+ case R_390_GOTPLT32:
+ case R_390_GOTPLT64:
+ case R_390_GOTPLTENT:
+ /* This symbol requires either a procedure linkage table entry
+ or an entry in the local got. We actually build the entry
+ in adjust_dynamic_symbol because whether this is really a
+ global reference can change and with it the fact if we have
+ to create a plt entry or a local got entry. To be able to
+ make a once global symbol a local one we have to keep track
+ of the number of gotplt references that exist for this
+ symbol. */
+ if (h != NULL)
+ {
+ ((struct elf_s390_link_hash_entry *) h)->gotplt_refcount++;
+ h->needs_plt = 1;
+ h->plt.refcount += 1;
+ }
+ else
+ local_got_refcounts[r_symndx] += 1;
+ break;
+
+ case R_390_TLS_LDM64:
+ htab->tls_ldm_got.refcount += 1;
+ break;
+
+ case R_390_TLS_IE64:
+ case R_390_TLS_GOTIE12:
+ case R_390_TLS_GOTIE20:
+ case R_390_TLS_GOTIE64:
+ case R_390_TLS_IEENT:
+ if (info->shared)
+ info->flags |= DF_STATIC_TLS;
+ /* Fall through */
+
+ case R_390_GOT12:
+ case R_390_GOT16:
+ case R_390_GOT20:
+ case R_390_GOT32:
+ case R_390_GOT64:
+ case R_390_GOTENT:
+ case R_390_TLS_GD64:
+ /* This symbol requires a global offset table entry. */
+ switch (r_type)
+ {
+ default:
+ case R_390_GOT12:
+ case R_390_GOT16:
+ case R_390_GOT20:
+ case R_390_GOT32:
+ case R_390_GOTENT:
+ tls_type = GOT_NORMAL;
+ break;
+ case R_390_TLS_GD64:
+ tls_type = GOT_TLS_GD;
+ break;
+ case R_390_TLS_IE64:
+ case R_390_TLS_GOTIE64:
+ tls_type = GOT_TLS_IE;
+ break;
+ case R_390_TLS_GOTIE12:
+ case R_390_TLS_GOTIE20:
+ case R_390_TLS_IEENT:
+ tls_type = GOT_TLS_IE_NLT;
+ break;
+ }
+
+ if (h != NULL)
+ {
+ h->got.refcount += 1;
+ old_tls_type = elf_s390_hash_entry(h)->tls_type;
+ }
+ else
+ {
+ local_got_refcounts[r_symndx] += 1;
+ old_tls_type = elf_s390_local_got_tls_type (abfd) [r_symndx];
+ }
+ /* If a TLS symbol is accessed using IE at least once,
+ there is no point to use dynamic model for it. */
+ if (old_tls_type != tls_type && old_tls_type != GOT_UNKNOWN)
+ {
+ if (old_tls_type == GOT_NORMAL || tls_type == GOT_NORMAL)
+ {
+ (*_bfd_error_handler)
+ (_("%B: `%s' accessed both as normal and thread local symbol"),
+ abfd, h->root.root.string);
+ return FALSE;
+ }
+ if (old_tls_type > tls_type)
+ tls_type = old_tls_type;
+ }
+
+ if (old_tls_type != tls_type)
+ {
+ if (h != NULL)
+ elf_s390_hash_entry (h)->tls_type = tls_type;
+ else
+ elf_s390_local_got_tls_type (abfd) [r_symndx] = tls_type;
+ }
+
+ if (r_type != R_390_TLS_IE64)
+ break;
+ /* Fall through */
+
+ case R_390_TLS_LE64:
+ /* For static linking and executables this reloc will be
+ calculated at linktime otherwise a TLS_TPOFF runtime
+ reloc will be generated. */
+ if (r_type == R_390_TLS_LE64 && info->pie)
+ break;
+
+ if (!info->shared)
+ break;
+ info->flags |= DF_STATIC_TLS;
+ /* Fall through */
+
+ case R_390_8:
+ case R_390_16:
+ case R_390_32:
+ case R_390_64:
+ case R_390_PC12DBL:
+ case R_390_PC16:
+ case R_390_PC16DBL:
+ case R_390_PC24DBL:
+ case R_390_PC32:
+ case R_390_PC32DBL:
+ case R_390_PC64:
+ if (h != NULL)
+ {
+ /* If this reloc is in a read-only section, we might
+ need a copy reloc. We can't check reliably at this
+ stage whether the section is read-only, as input
+ sections have not yet been mapped to output sections.
+ Tentatively set the flag for now, and correct in
+ adjust_dynamic_symbol. */
+ h->non_got_ref = 1;
+
+ if (!info->shared)
+ {
+ /* We may need a .plt entry if the function this reloc
+ refers to is in a shared lib. */
+ h->plt.refcount += 1;
+ }
+ }
+
+ /* 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). In case of a weak definition,
+ DEF_REGULAR may be cleared later by a strong definition in
+ a shared library. We account for that possibility below by
+ storing information in the relocs_copied field of the hash
+ table entry. A similar situation occurs when creating
+ shared libraries and symbol visibility changes render the
+ symbol local.
+
+ If on the other hand, we are creating an executable, we
+ may need to keep relocations for symbols satisfied by a
+ dynamic library if we manage to avoid copy relocs for the
+ symbol. */
+ if ((info->shared
+ && (sec->flags & SEC_ALLOC) != 0
+ && ((ELF64_R_TYPE (rel->r_info) != R_390_PC16
+ && ELF64_R_TYPE (rel->r_info) != R_390_PC12DBL
+ && ELF64_R_TYPE (rel->r_info) != R_390_PC16DBL
+ && ELF64_R_TYPE (rel->r_info) != R_390_PC24DBL
+ && ELF64_R_TYPE (rel->r_info) != R_390_PC32
+ && ELF64_R_TYPE (rel->r_info) != R_390_PC32DBL
+ && ELF64_R_TYPE (rel->r_info) != R_390_PC64)
+ || (h != NULL
+ && (! SYMBOLIC_BIND (info, h)
+ || h->root.type == bfd_link_hash_defweak
+ || !h->def_regular))))
+ || (ELIMINATE_COPY_RELOCS
+ && !info->shared
+ && (sec->flags & SEC_ALLOC) != 0
+ && h != NULL
+ && (h->root.type == bfd_link_hash_defweak
+ || !h->def_regular)))
+ {
+ struct elf_dyn_relocs *p;
+ struct elf_dyn_relocs **head;
+
+ /* We must copy these reloc types into the output file.
+ Create a reloc section in dynobj and make room for
+ this reloc. */
+ if (sreloc == NULL)
+ {
+ if (htab->elf.dynobj == NULL)
+ htab->elf.dynobj = abfd;
+
+ sreloc = _bfd_elf_make_dynamic_reloc_section
+ (sec, htab->elf.dynobj, 3, abfd, /*rela?*/ TRUE);
+
+ if (sreloc == NULL)
+ return FALSE;
+ }
+
+ /* If this is a global symbol, we count the number of
+ relocations we need for this symbol. */
+ if (h != NULL)
+ {
+ head = &((struct elf_s390_link_hash_entry *) h)->dyn_relocs;
+ }
+ else
+ {
+ /* Track dynamic relocs needed for local syms too.
+ We really need local syms available to do this
+ easily. Oh well. */
+ asection *s;
+ void *vpp;
+
+ isym = bfd_sym_from_r_symndx (&htab->sym_cache,
+ abfd, r_symndx);
+ if (isym == NULL)
+ return FALSE;
+
+ s = bfd_section_from_elf_index (abfd, isym->st_shndx);
+ if (s == NULL)
+ s = sec;
+
+ vpp = &elf_section_data (s)->local_dynrel;
+ head = (struct elf_dyn_relocs **) vpp;
+ }
+
+ p = *head;
+ if (p == NULL || p->sec != sec)
+ {
+ bfd_size_type amt = sizeof *p;
+ p = ((struct elf_dyn_relocs *)
+ bfd_alloc (htab->elf.dynobj, amt));
+ if (p == NULL)
+ return FALSE;
+ p->next = *head;
+ *head = p;
+ p->sec = sec;
+ p->count = 0;
+ p->pc_count = 0;
+ }
+
+ p->count += 1;
+ if (ELF64_R_TYPE (rel->r_info) == R_390_PC16
+ || ELF64_R_TYPE (rel->r_info) == R_390_PC12DBL
+ || ELF64_R_TYPE (rel->r_info) == R_390_PC16DBL
+ || ELF64_R_TYPE (rel->r_info) == R_390_PC16DBL
+ || ELF64_R_TYPE (rel->r_info) == R_390_PC32
+ || ELF64_R_TYPE (rel->r_info) == R_390_PC32DBL
+ || ELF64_R_TYPE (rel->r_info) == R_390_PC64)
+ p->pc_count += 1;
+ }
+ break;
+
+ /* This relocation describes the C++ object vtable hierarchy.
+ Reconstruct it for later use during GC. */
+ case R_390_GNU_VTINHERIT:
+ if (!bfd_elf_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_390_GNU_VTENTRY:
+ BFD_ASSERT (h != NULL);
+ if (h != NULL
+ && !bfd_elf_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_s390_gc_mark_hook (asection *sec,
+ struct bfd_link_info *info,
+ Elf_Internal_Rela *rel,
+ struct elf_link_hash_entry *h,
+ Elf_Internal_Sym *sym)
+{
+ if (h != NULL)
+ switch (ELF64_R_TYPE (rel->r_info))
+ {
+ case R_390_GNU_VTINHERIT:
+ case R_390_GNU_VTENTRY:
+ return NULL;
+ }
+
+ return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
+}
+
+/* Update the got entry reference counts for the section being removed. */
+
+static bfd_boolean
+elf_s390_gc_sweep_hook (bfd *abfd,
+ struct bfd_link_info *info,
+ asection *sec,
+ const Elf_Internal_Rela *relocs)
+{
+ struct elf_s390_link_hash_table *htab;
+ Elf_Internal_Shdr *symtab_hdr;
+ struct elf_link_hash_entry **sym_hashes;
+ bfd_signed_vma *local_got_refcounts;
+ const Elf_Internal_Rela *rel, *relend;
+
+ if (info->relocatable)
+ return TRUE;
+
+ htab = elf_s390_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ elf_section_data (sec)->local_dynrel = NULL;
+
+ symtab_hdr = &elf_symtab_hdr (abfd);
+ 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++)
+ {
+ unsigned long r_symndx;
+ unsigned int r_type;
+ struct elf_link_hash_entry *h = NULL;
+
+ r_symndx = ELF64_R_SYM (rel->r_info);
+ if (r_symndx >= symtab_hdr->sh_info)
+ {
+ struct elf_s390_link_hash_entry *eh;
+ struct elf_dyn_relocs **pp;
+ struct elf_dyn_relocs *p;
+
+ 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;
+ eh = (struct elf_s390_link_hash_entry *) h;
+
+ for (pp = &eh->dyn_relocs; (p = *pp) != NULL; pp = &p->next)
+ if (p->sec == sec)
+ {
+ /* Everything must go for SEC. */
+ *pp = p->next;
+ break;
+ }
+ }
+ else
+ {
+ Elf_Internal_Sym *isym;
+
+ /* A local symbol. */
+ isym = bfd_sym_from_r_symndx (&htab->sym_cache,
+ abfd, r_symndx);
+ if (isym == NULL)
+ return FALSE;
+
+ if (ELF_ST_TYPE (isym->st_info) == STT_GNU_IFUNC)
+ {
+ struct plt_entry *plt = elf_s390_local_plt (abfd);
+ if (plt[r_symndx].plt.refcount > 0)
+ plt[r_symndx].plt.refcount--;
+ }
+ }
+
+ r_type = ELF64_R_TYPE (rel->r_info);
+ r_type = elf_s390_tls_transition (info, r_type, h != NULL);
+ switch (r_type)
+ {
+ case R_390_TLS_LDM64:
+ if (htab->tls_ldm_got.refcount > 0)
+ htab->tls_ldm_got.refcount -= 1;
+ break;
+
+ case R_390_TLS_GD64:
+ case R_390_TLS_IE64:
+ case R_390_TLS_GOTIE12:
+ case R_390_TLS_GOTIE20:
+ case R_390_TLS_GOTIE64:
+ case R_390_TLS_IEENT:
+ case R_390_GOT12:
+ case R_390_GOT16:
+ case R_390_GOT20:
+ case R_390_GOT32:
+ case R_390_GOT64:
+ case R_390_GOTOFF16:
+ case R_390_GOTOFF32:
+ case R_390_GOTOFF64:
+ case R_390_GOTPC:
+ case R_390_GOTPCDBL:
+ case R_390_GOTENT:
+ if (h != NULL)
+ {
+ if (h->got.refcount > 0)
+ h->got.refcount -= 1;
+ }
+ else if (local_got_refcounts != NULL)
+ {
+ if (local_got_refcounts[r_symndx] > 0)
+ local_got_refcounts[r_symndx] -= 1;
+ }
+ break;
+
+ case R_390_8:
+ case R_390_12:
+ case R_390_16:
+ case R_390_20:
+ case R_390_32:
+ case R_390_64:
+ case R_390_PC16:
+ case R_390_PC12DBL:
+ case R_390_PC16DBL:
+ case R_390_PC24DBL:
+ case R_390_PC32:
+ case R_390_PC32DBL:
+ case R_390_PC64:
+ if (info->shared)
+ break;
+ /* Fall through */
+
+ case R_390_PLT12DBL:
+ case R_390_PLT16DBL:
+ case R_390_PLT24DBL:
+ case R_390_PLT32:
+ case R_390_PLT32DBL:
+ case R_390_PLT64:
+ case R_390_PLTOFF16:
+ case R_390_PLTOFF32:
+ case R_390_PLTOFF64:
+ if (h != NULL)
+ {
+ if (h->plt.refcount > 0)
+ h->plt.refcount -= 1;
+ }
+ break;
+
+ case R_390_GOTPLT12:
+ case R_390_GOTPLT16:
+ case R_390_GOTPLT20:
+ case R_390_GOTPLT32:
+ case R_390_GOTPLT64:
+ case R_390_GOTPLTENT:
+ if (h != NULL)
+ {
+ if (h->plt.refcount > 0)
+ {
+ ((struct elf_s390_link_hash_entry *) h)->gotplt_refcount--;
+ h->plt.refcount -= 1;
+ }
+ }
+ else if (local_got_refcounts != NULL)
+ {
+ if (local_got_refcounts[r_symndx] > 0)
+ local_got_refcounts[r_symndx] -= 1;
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ return TRUE;
+}
+
+/* Make sure we emit a GOT entry if the symbol was supposed to have a PLT
+ entry but we found we will not create any. Called when we find we will
+ not have any PLT for this symbol, by for example
+ elf_s390_adjust_dynamic_symbol when we're doing a proper dynamic link,
+ or elf_s390_size_dynamic_sections if no dynamic sections will be
+ created (we're only linking static objects). */
+
+static void
+elf_s390_adjust_gotplt (struct elf_s390_link_hash_entry *h)
+{
+ if (h->elf.root.type == bfd_link_hash_warning)
+ h = (struct elf_s390_link_hash_entry *) h->elf.root.u.i.link;
+
+ if (h->gotplt_refcount <= 0)
+ return;
+
+ /* We simply add the number of gotplt references to the number
+ * of got references for this symbol. */
+ h->elf.got.refcount += h->gotplt_refcount;
+ h->gotplt_refcount = -1;
+}
+
+/* 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 bfd_boolean
+elf_s390_adjust_dynamic_symbol (struct bfd_link_info *info,
+ struct elf_link_hash_entry *h)
+{
+ struct elf_s390_link_hash_table *htab;
+ asection *s;
+
+ /* STT_GNU_IFUNC symbol must go through PLT. */
+ if (s390_is_ifunc_symbol_p (h))
+ return TRUE;
+
+ /* 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). */
+ if (h->type == STT_FUNC
+ || h->needs_plt)
+ {
+ if (h->plt.refcount <= 0
+ || SYMBOL_CALLS_LOCAL (info, h)
+ || (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
+ && h->root.type == bfd_link_hash_undefweak))
+ {
+ /* 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, or if all references were garbage collected. In
+ such a case, we don't actually need to build a procedure
+ linkage table, and we can just do a PC32 reloc instead. */
+ h->plt.offset = (bfd_vma) -1;
+ h->needs_plt = 0;
+ elf_s390_adjust_gotplt((struct elf_s390_link_hash_entry *) h);
+ }
+
+ return TRUE;
+ }
+ else
+ /* It's possible that we incorrectly decided a .plt reloc was
+ needed for an R_390_PC32 reloc to a non-function sym in
+ check_relocs. We can't decide accurately between function and
+ non-function syms in check-relocs; Objects loaded later in
+ the link may change h->type. So fix it now. */
+ 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->u.weakdef != NULL)
+ {
+ BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
+ || h->u.weakdef->root.type == bfd_link_hash_defweak);
+ h->root.u.def.section = h->u.weakdef->root.u.def.section;
+ h->root.u.def.value = h->u.weakdef->root.u.def.value;
+ if (ELIMINATE_COPY_RELOCS || info->nocopyreloc)
+ h->non_got_ref = h->u.weakdef->non_got_ref;
+ 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;
+
+ /* If there are no references to this symbol that do not use the
+ GOT, we don't need to generate a copy reloc. */
+ if (!h->non_got_ref)
+ return TRUE;
+
+ /* If -z nocopyreloc was given, we won't generate them either. */
+ if (info->nocopyreloc)
+ {
+ h->non_got_ref = 0;
+ return TRUE;
+ }
+
+ if (ELIMINATE_COPY_RELOCS)
+ {
+ struct elf_s390_link_hash_entry * eh;
+ struct elf_dyn_relocs *p;
+
+ eh = (struct elf_s390_link_hash_entry *) h;
+ for (p = eh->dyn_relocs; p != NULL; p = p->next)
+ {
+ s = p->sec->output_section;
+ if (s != NULL && (s->flags & SEC_READONLY) != 0)
+ break;
+ }
+
+ /* If we didn't find any dynamic relocs in read-only sections, then
+ we'll be keeping the dynamic relocs and avoiding the copy reloc. */
+ if (p == NULL)
+ {
+ h->non_got_ref = 0;
+ 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. */
+
+ htab = elf_s390_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ /* We must generate a R_390_COPY reloc to tell the dynamic linker to
+ copy the initial value out of the dynamic object and into the
+ runtime process image. */
+ if ((h->root.u.def.section->flags & SEC_ALLOC) != 0 && h->size != 0)
+ {
+ htab->srelbss->size += sizeof (Elf64_External_Rela);
+ h->needs_copy = 1;
+ }
+
+ s = htab->sdynbss;
+
+ return _bfd_elf_adjust_dynamic_copy (h, s);
+}
+
+/* Allocate space in .plt, .got and associated reloc sections for
+ dynamic relocs. */
+
+static bfd_boolean
+allocate_dynrelocs (struct elf_link_hash_entry *h,
+ void * inf)
+{
+ struct bfd_link_info *info;
+ struct elf_s390_link_hash_table *htab;
+ struct elf_s390_link_hash_entry *eh = (struct elf_s390_link_hash_entry *)h;
+ struct elf_dyn_relocs *p;
+
+ if (h->root.type == bfd_link_hash_indirect)
+ return TRUE;
+
+ info = (struct bfd_link_info *) inf;
+ htab = elf_s390_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ /* Since STT_GNU_IFUNC symbol must go through PLT, we handle it
+ here if it is defined and referenced in a non-shared object. */
+ if (s390_is_ifunc_symbol_p (h) && h->def_regular)
+ return s390_elf_allocate_ifunc_dyn_relocs (info, h,
+ &eh->dyn_relocs);
+ else if (htab->elf.dynamic_sections_created
+ && h->plt.refcount > 0)
+ {
+ /* Make sure this symbol is output as a dynamic symbol.
+ Undefined weak syms won't yet be marked as dynamic. */
+ if (h->dynindx == -1
+ && !h->forced_local)
+ {
+ if (! bfd_elf_link_record_dynamic_symbol (info, h))
+ return FALSE;
+ }
+
+ if (info->shared
+ || WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, 0, h))
+ {
+ asection *s = htab->elf.splt;
+
+ /* If this is the first .plt entry, make room for the special
+ first entry. */
+ if (s->size == 0)
+ s->size += PLT_FIRST_ENTRY_SIZE;
+
+ h->plt.offset = s->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->def_regular)
+ {
+ h->root.u.def.section = s;
+ h->root.u.def.value = h->plt.offset;
+ }
+
+ /* Make room for this entry. */
+ s->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. */
+ htab->elf.sgotplt->size += GOT_ENTRY_SIZE;
+
+ /* We also need to make an entry in the .rela.plt section. */
+ htab->elf.srelplt->size += sizeof (Elf64_External_Rela);
+ }
+ else
+ {
+ h->plt.offset = (bfd_vma) -1;
+ h->needs_plt = 0;
+ elf_s390_adjust_gotplt((struct elf_s390_link_hash_entry *) h);
+ }
+ }
+ else
+ {
+ h->plt.offset = (bfd_vma) -1;
+ h->needs_plt = 0;
+ elf_s390_adjust_gotplt((struct elf_s390_link_hash_entry *) h);
+ }
+
+ /* If R_390_TLS_{IE64,GOTIE64,GOTIE12,IEENT} symbol is now local to
+ the binary, we can optimize a bit. IE64 and GOTIE64 get converted
+ to R_390_TLS_LE64 requiring no TLS entry. For GOTIE12 and IEENT
+ we can save the dynamic TLS relocation. */
+ if (h->got.refcount > 0
+ && !info->shared
+ && h->dynindx == -1
+ && elf_s390_hash_entry(h)->tls_type >= GOT_TLS_IE)
+ {
+ if (elf_s390_hash_entry(h)->tls_type == GOT_TLS_IE_NLT)
+ /* For the GOTIE access without a literal pool entry the offset has
+ to be stored somewhere. The immediate value in the instruction
+ is not bit enough so the value is stored in the got. */
+ {
+ h->got.offset = htab->elf.sgot->size;
+ htab->elf.sgot->size += GOT_ENTRY_SIZE;
+ }
+ else
+ h->got.offset = (bfd_vma) -1;
+ }
+ else if (h->got.refcount > 0)
+ {
+ asection *s;
+ bfd_boolean dyn;
+ int tls_type = elf_s390_hash_entry(h)->tls_type;
+
+ /* Make sure this symbol is output as a dynamic symbol.
+ Undefined weak syms won't yet be marked as dynamic. */
+ if (h->dynindx == -1
+ && !h->forced_local)
+ {
+ if (! bfd_elf_link_record_dynamic_symbol (info, h))
+ return FALSE;
+ }
+
+ s = htab->elf.sgot;
+ h->got.offset = s->size;
+ s->size += GOT_ENTRY_SIZE;
+ /* R_390_TLS_GD64 needs 2 consecutive GOT slots. */
+ if (tls_type == GOT_TLS_GD)
+ s->size += GOT_ENTRY_SIZE;
+ dyn = htab->elf.dynamic_sections_created;
+ /* R_390_TLS_IE64 needs one dynamic relocation,
+ R_390_TLS_GD64 needs one if local symbol and two if global. */
+ if ((tls_type == GOT_TLS_GD && h->dynindx == -1)
+ || tls_type >= GOT_TLS_IE)
+ htab->elf.srelgot->size += sizeof (Elf64_External_Rela);
+ else if (tls_type == GOT_TLS_GD)
+ htab->elf.srelgot->size += 2 * sizeof (Elf64_External_Rela);
+ else if ((ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
+ || h->root.type != bfd_link_hash_undefweak)
+ && (info->shared
+ || WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, 0, h)))
+ htab->elf.srelgot->size += sizeof (Elf64_External_Rela);
+ }
+ else
+ h->got.offset = (bfd_vma) -1;
+
+ if (eh->dyn_relocs == NULL)
+ return TRUE;
+
+ /* In the shared -Bsymbolic case, discard space allocated for
+ dynamic pc-relative relocs against symbols which turn out to be
+ defined in regular objects. For the normal shared case, discard
+ space for pc-relative relocs that have become local due to symbol
+ visibility changes. */
+
+ if (info->shared)
+ {
+ if (SYMBOL_CALLS_LOCAL (info, h))
+ {
+ struct elf_dyn_relocs **pp;
+
+ for (pp = &eh->dyn_relocs; (p = *pp) != NULL; )
+ {
+ p->count -= p->pc_count;
+ p->pc_count = 0;
+ if (p->count == 0)
+ *pp = p->next;
+ else
+ pp = &p->next;
+ }
+ }
+
+ /* Also discard relocs on undefined weak syms with non-default
+ visibility. */
+ if (eh->dyn_relocs != NULL
+ && h->root.type == bfd_link_hash_undefweak)
+ {
+ if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
+ eh->dyn_relocs = NULL;
+
+ /* Make sure undefined weak symbols are output as a dynamic
+ symbol in PIEs. */
+ else if (h->dynindx == -1
+ && !h->forced_local)
+ {
+ if (! bfd_elf_link_record_dynamic_symbol (info, h))
+ return FALSE;
+ }
+ }
+ }
+ else if (ELIMINATE_COPY_RELOCS)
+ {
+ /* For the non-shared case, discard space for relocs against
+ symbols which turn out to need copy relocs or are not
+ dynamic. */
+
+ if (!h->non_got_ref
+ && ((h->def_dynamic
+ && !h->def_regular)
+ || (htab->elf.dynamic_sections_created
+ && (h->root.type == bfd_link_hash_undefweak
+ || h->root.type == bfd_link_hash_undefined))))
+ {
+ /* Make sure this symbol is output as a dynamic symbol.
+ Undefined weak syms won't yet be marked as dynamic. */
+ if (h->dynindx == -1
+ && !h->forced_local)
+ {
+ if (! bfd_elf_link_record_dynamic_symbol (info, h))
+ return FALSE;
+ }
+
+ /* If that succeeded, we know we'll be keeping all the
+ relocs. */
+ if (h->dynindx != -1)
+ goto keep;
+ }
+
+ eh->dyn_relocs = NULL;
+
+ keep: ;
+ }
+
+ /* Finally, allocate space. */
+ for (p = eh->dyn_relocs; p != NULL; p = p->next)
+ {
+ asection *sreloc = elf_section_data (p->sec)->sreloc;
+ sreloc->size += p->count * sizeof (Elf64_External_Rela);
+ }
+
+ return TRUE;
+}
+
+/* Find any dynamic relocs that apply to read-only sections. */
+
+static bfd_boolean
+readonly_dynrelocs (struct elf_link_hash_entry *h, void * inf)
+{
+ struct elf_s390_link_hash_entry *eh;
+ struct elf_dyn_relocs *p;
+
+ eh = (struct elf_s390_link_hash_entry *) h;
+ for (p = eh->dyn_relocs; p != NULL; p = p->next)
+ {
+ asection *s = p->sec->output_section;
+
+ if (s != NULL && (s->flags & SEC_READONLY) != 0)
+ {
+ struct bfd_link_info *info = (struct bfd_link_info *) inf;
+
+ info->flags |= DF_TEXTREL;
+
+ /* Not an error, just cut short the traversal. */
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+/* Set the sizes of the dynamic sections. */
+
+static bfd_boolean
+elf_s390_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
+ struct bfd_link_info *info)
+{
+ struct elf_s390_link_hash_table *htab;
+ bfd *dynobj;
+ asection *s;
+ bfd_boolean relocs;
+ bfd *ibfd;
+
+ htab = elf_s390_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ dynobj = htab->elf.dynobj;
+ if (dynobj == NULL)
+ abort ();
+
+ if (htab->elf.dynamic_sections_created)
+ {
+ /* Set the contents of the .interp section to the interpreter. */
+ if (info->executable)
+ {
+ s = bfd_get_linker_section (dynobj, ".interp");
+ if (s == NULL)
+ abort ();
+ s->size = sizeof ELF_DYNAMIC_INTERPRETER;
+ s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
+ }
+ }
+
+ /* Set up .got offsets for local syms, and space for local dynamic
+ relocs. */
+ for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next)
+ {
+ bfd_signed_vma *local_got;
+ bfd_signed_vma *end_local_got;
+ char *local_tls_type;
+ bfd_size_type locsymcount;
+ Elf_Internal_Shdr *symtab_hdr;
+ asection *srela;
+ struct plt_entry *local_plt;
+ unsigned int i;
+
+ if (! is_s390_elf (ibfd))
+ continue;
+
+ for (s = ibfd->sections; s != NULL; s = s->next)
+ {
+ struct elf_dyn_relocs *p;
+
+ for (p = elf_section_data (s)->local_dynrel; p != NULL; p = p->next)
+ {
+ if (!bfd_is_abs_section (p->sec)
+ && bfd_is_abs_section (p->sec->output_section))
+ {
+ /* Input section has been discarded, either because
+ it is a copy of a linkonce section or due to
+ linker script /DISCARD/, so we'll be discarding
+ the relocs too. */
+ }
+ else if (p->count != 0)
+ {
+ srela = elf_section_data (p->sec)->sreloc;
+ srela->size += p->count * sizeof (Elf64_External_Rela);
+ if ((p->sec->output_section->flags & SEC_READONLY) != 0)
+ info->flags |= DF_TEXTREL;
+ }
+ }
+ }
+
+ local_got = elf_local_got_refcounts (ibfd);
+ if (!local_got)
+ continue;
+
+ symtab_hdr = &elf_symtab_hdr (ibfd);
+ locsymcount = symtab_hdr->sh_info;
+ end_local_got = local_got + locsymcount;
+ local_tls_type = elf_s390_local_got_tls_type (ibfd);
+ s = htab->elf.sgot;
+ srela = htab->elf.srelgot;
+ for (; local_got < end_local_got; ++local_got, ++local_tls_type)
+ {
+ if (*local_got > 0)
+ {
+ *local_got = s->size;
+ s->size += GOT_ENTRY_SIZE;
+ if (*local_tls_type == GOT_TLS_GD)
+ s->size += GOT_ENTRY_SIZE;
+ if (info->shared)
+ srela->size += sizeof (Elf64_External_Rela);
+ }
+ else
+ *local_got = (bfd_vma) -1;
+ }
+
+ local_plt = elf_s390_local_plt (ibfd);
+ for (i = 0; i < symtab_hdr->sh_info; i++)
+ {
+ if (local_plt[i].plt.refcount > 0)
+ {
+ local_plt[i].plt.offset = htab->elf.iplt->size;
+ htab->elf.iplt->size += PLT_ENTRY_SIZE;
+ htab->elf.igotplt->size += GOT_ENTRY_SIZE;
+ htab->elf.irelplt->size += sizeof (Elf64_External_Rela);
+ }
+ else
+ local_plt[i].plt.offset = (bfd_vma) -1;
+ }
+ }
+
+ if (htab->tls_ldm_got.refcount > 0)
+ {
+ /* Allocate 2 got entries and 1 dynamic reloc for R_390_TLS_LDM64
+ relocs. */
+ htab->tls_ldm_got.offset = htab->elf.sgot->size;
+ htab->elf.sgot->size += 2 * GOT_ENTRY_SIZE;
+ htab->elf.srelgot->size += sizeof (Elf64_External_Rela);
+ }
+ else
+ htab->tls_ldm_got.offset = -1;
+
+ /* Allocate global sym .plt and .got entries, and space for global
+ sym dynamic relocs. */
+ elf_link_hash_traverse (&htab->elf, allocate_dynrelocs, info);
+
+ /* We now have determined the sizes of the various dynamic sections.
+ Allocate memory for them. */
+ relocs = FALSE;
+ for (s = dynobj->sections; s != NULL; s = s->next)
+ {
+ if ((s->flags & SEC_LINKER_CREATED) == 0)
+ continue;
+
+ if (s == htab->elf.splt
+ || s == htab->elf.sgot
+ || s == htab->elf.sgotplt
+ || s == htab->sdynbss
+ || s == htab->elf.iplt
+ || s == htab->elf.igotplt
+ || s == htab->irelifunc)
+ {
+ /* Strip this section if we don't need it; see the
+ comment below. */
+ }
+ else if (CONST_STRNEQ (bfd_get_section_name (dynobj, s), ".rela"))
+ {
+ if (s->size != 0 && s != htab->elf.srelplt)
+ relocs = 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
+ {
+ /* It's not one of our sections, so don't allocate space. */
+ continue;
+ }
+
+ if (s->size == 0)
+ {
+ /* 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. */
+
+ s->flags |= SEC_EXCLUDE;
+ continue;
+ }
+
+ if ((s->flags & SEC_HAS_CONTENTS) == 0)
+ continue;
+
+ /* Allocate memory for the section contents. We use bfd_zalloc
+ here in case unused entries are not reclaimed before the
+ section's contents are written out. This should not happen,
+ but this way if it does, we get a R_390_NONE reloc instead
+ of garbage. */
+ s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->size);
+ if (s->contents == NULL)
+ return FALSE;
+ }
+
+ if (htab->elf.dynamic_sections_created)
+ {
+ /* Add some entries to the .dynamic section. We fill in the
+ values later, in elf_s390_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. */
+#define add_dynamic_entry(TAG, VAL) \
+ _bfd_elf_add_dynamic_entry (info, TAG, VAL)
+
+ if (info->executable)
+ {
+ if (!add_dynamic_entry (DT_DEBUG, 0))
+ return FALSE;
+ }
+
+ if (htab->elf.splt->size != 0)
+ {
+ if (!add_dynamic_entry (DT_PLTGOT, 0)
+ || !add_dynamic_entry (DT_PLTRELSZ, 0)
+ || !add_dynamic_entry (DT_PLTREL, DT_RELA)
+ || !add_dynamic_entry (DT_JMPREL, 0))
+ return FALSE;
+ }
+
+ if (relocs)
+ {
+ if (!add_dynamic_entry (DT_RELA, 0)
+ || !add_dynamic_entry (DT_RELASZ, 0)
+ || !add_dynamic_entry (DT_RELAENT, sizeof (Elf64_External_Rela)))
+ return FALSE;
+
+ /* If any dynamic relocs apply to a read-only section,
+ then we need a DT_TEXTREL entry. */
+ if ((info->flags & DF_TEXTREL) == 0)
+ elf_link_hash_traverse (&htab->elf, readonly_dynrelocs,
+ info);
+
+ if ((info->flags & DF_TEXTREL) != 0)
+ {
+ if (!add_dynamic_entry (DT_TEXTREL, 0))
+ return FALSE;
+ }
+ }
+ }
+#undef add_dynamic_entry
+
+ return TRUE;
+}
+
+/* Return the base VMA address which should be subtracted from real addresses
+ when resolving @dtpoff relocation.
+ This is PT_TLS segment p_vaddr. */
+
+static bfd_vma
+dtpoff_base (struct bfd_link_info *info)
+{
+ /* If tls_sec is NULL, we should have signalled an error already. */
+ if (elf_hash_table (info)->tls_sec == NULL)
+ return 0;
+ return elf_hash_table (info)->tls_sec->vma;
+}
+
+/* Return the relocation value for @tpoff relocation
+ if STT_TLS virtual address is ADDRESS. */
+
+static bfd_vma
+tpoff (struct bfd_link_info *info, bfd_vma address)
+{
+ struct elf_link_hash_table *htab = elf_hash_table (info);
+
+ /* If tls_sec is NULL, we should have signalled an error already. */
+ if (htab->tls_sec == NULL)
+ return 0;
+ return htab->tls_size + htab->tls_sec->vma - address;
+}
+
+/* Complain if TLS instruction relocation is against an invalid
+ instruction. */
+
+static void
+invalid_tls_insn (bfd *input_bfd,
+ asection *input_section,
+ Elf_Internal_Rela *rel)
+{
+ reloc_howto_type *howto;
+
+ howto = elf_howto_table + ELF64_R_TYPE (rel->r_info);
+ (*_bfd_error_handler)
+ (_("%B(%A+0x%lx): invalid instruction for TLS relocation %s"),
+ input_bfd,
+ input_section,
+ (long) rel->r_offset,
+ howto->name);
+ bfd_set_error (bfd_error_bad_value);
+}
+
+/* Relocate a 390 ELF section. */
+
+static bfd_boolean
+elf_s390_relocate_section (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)
+{
+ struct elf_s390_link_hash_table *htab;
+ Elf_Internal_Shdr *symtab_hdr;
+ struct elf_link_hash_entry **sym_hashes;
+ bfd_vma *local_got_offsets;
+ Elf_Internal_Rela *rel;
+ Elf_Internal_Rela *relend;
+
+ BFD_ASSERT (is_s390_elf (input_bfd));
+
+ htab = elf_s390_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ symtab_hdr = &elf_symtab_hdr (input_bfd);
+ sym_hashes = elf_sym_hashes (input_bfd);
+ local_got_offsets = elf_local_got_offsets (input_bfd);
+
+ rel = relocs;
+ relend = relocs + input_section->reloc_count;
+ for (; rel < relend; rel++)
+ {
+ unsigned 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 off;
+ bfd_vma relocation;
+ bfd_boolean unresolved_reloc;
+ bfd_reloc_status_type r;
+ int tls_type;
+ asection *base_got = htab->elf.sgot;
+
+ r_type = ELF64_R_TYPE (rel->r_info);
+ if (r_type == (int) R_390_GNU_VTINHERIT
+ || r_type == (int) R_390_GNU_VTENTRY)
+ continue;
+ if (r_type >= (int) R_390_max)
+ {
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+
+ howto = elf_howto_table + r_type;
+ r_symndx = ELF64_R_SYM (rel->r_info);
+
+ h = NULL;
+ sym = NULL;
+ sec = NULL;
+ unresolved_reloc = FALSE;
+ if (r_symndx < symtab_hdr->sh_info)
+ {
+ sym = local_syms + r_symndx;
+ sec = local_sections[r_symndx];
+
+ if (ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC)
+ {
+ struct plt_entry *local_plt = elf_s390_local_plt (input_bfd);
+ if (local_plt == NULL)
+ return FALSE;
+
+ /* Address of the PLT slot. */
+ relocation = (htab->elf.iplt->output_section->vma
+ + htab->elf.iplt->output_offset
+ + local_plt[r_symndx].plt.offset);
+
+ switch (r_type)
+ {
+ case R_390_PLTOFF16:
+ case R_390_PLTOFF32:
+ case R_390_PLTOFF64:
+ relocation -= htab->elf.sgot->output_section->vma;
+ break;
+ case R_390_GOTPLT12:
+ case R_390_GOTPLT16:
+ case R_390_GOTPLT20:
+ case R_390_GOTPLT32:
+ case R_390_GOTPLT64:
+ case R_390_GOTPLTENT:
+ case R_390_GOT12:
+ case R_390_GOT16:
+ case R_390_GOT20:
+ case R_390_GOT32:
+ case R_390_GOT64:
+ case R_390_GOTENT:
+ {
+ /* Write the PLT slot address into the GOT slot. */
+ bfd_put_64 (output_bfd, relocation,
+ htab->elf.sgot->contents +
+ local_got_offsets[r_symndx]);
+ relocation = (local_got_offsets[r_symndx] +
+ htab->elf.sgot->output_offset);
+
+ if (r_type == R_390_GOTENT || r_type == R_390_GOTPLTENT)
+ relocation += htab->elf.sgot->output_section->vma;
+ break;
+ }
+ default:
+ break;
+ }
+ /* The output section is needed later in
+ finish_dynamic_section when creating the dynamic
+ relocation. */
+ local_plt[r_symndx].sec = sec;
+ goto do_relocation;
+ }
+ else
+ relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
+ }
+ else
+ {
+ bfd_boolean warned ATTRIBUTE_UNUSED;
+ bfd_boolean ignored ATTRIBUTE_UNUSED;
+
+ RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
+ r_symndx, symtab_hdr, sym_hashes,
+ h, sec, relocation,
+ unresolved_reloc, warned, ignored);
+ }
+
+ if (sec != NULL && discarded_section (sec))
+ RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+ rel, 1, relend, howto, 0, contents);
+
+ if (info->relocatable)
+ continue;
+
+ switch (r_type)
+ {
+ case R_390_GOTPLT12:
+ case R_390_GOTPLT16:
+ case R_390_GOTPLT20:
+ case R_390_GOTPLT32:
+ case R_390_GOTPLT64:
+ case R_390_GOTPLTENT:
+ /* There are three cases for a GOTPLT relocation. 1) The
+ relocation is against the jump slot entry of a plt that
+ will get emitted to the output file. 2) The relocation
+ is against the jump slot of a plt entry that has been
+ removed. elf_s390_adjust_gotplt has created a GOT entry
+ as replacement. 3) The relocation is against a local symbol.
+ Cases 2) and 3) are the same as the GOT relocation code
+ so we just have to test for case 1 and fall through for
+ the other two. */
+ if (h != NULL && h->plt.offset != (bfd_vma) -1)
+ {
+ bfd_vma plt_index;
+
+ if (s390_is_ifunc_symbol_p (h))
+ {
+ plt_index = h->plt.offset / PLT_ENTRY_SIZE;
+ relocation = (plt_index * GOT_ENTRY_SIZE +
+ htab->elf.igotplt->output_offset);
+ if (r_type == R_390_GOTPLTENT)
+ relocation += htab->elf.igotplt->output_section->vma;
+ }
+ else
+ {
+ /* Calc. index no.
+ Current offset - size first entry / entry size. */
+ plt_index = (h->plt.offset - PLT_FIRST_ENTRY_SIZE) /
+ PLT_ENTRY_SIZE;
+
+ /* Offset in GOT is PLT index plus GOT headers(3)
+ times 4, addr & GOT addr. */
+ relocation = (plt_index + 3) * GOT_ENTRY_SIZE;
+ if (r_type == R_390_GOTPLTENT)
+ relocation += htab->elf.sgot->output_section->vma;
+ }
+ unresolved_reloc = FALSE;
+ break;
+ }
+ /* Fall through. */
+
+ case R_390_GOT12:
+ case R_390_GOT16:
+ case R_390_GOT20:
+ case R_390_GOT32:
+ case R_390_GOT64:
+ case R_390_GOTENT:
+ /* Relocation is to the entry for this symbol in the global
+ offset table. */
+ if (base_got == NULL)
+ abort ();
+
+ if (h != NULL)
+ {
+ bfd_boolean dyn;
+
+ off = h->got.offset;
+ dyn = htab->elf.dynamic_sections_created;
+
+ if (s390_is_ifunc_symbol_p (h))
+ {
+ BFD_ASSERT (h->plt.offset != (bfd_vma) -1);
+ if (off == (bfd_vma)-1)
+ {
+ /* No explicit GOT usage so redirect to the
+ got.iplt slot. */
+ base_got = htab->elf.igotplt;
+ off = h->plt.offset / PLT_ENTRY_SIZE * GOT_ENTRY_SIZE;
+ }
+ else
+ {
+ /* Explicit GOT slots must contain the address
+ of the PLT slot. This will be handled in
+ finish_dynamic_symbol. */
+ }
+ }
+ else if (! WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h)
+ || (info->shared
+ && SYMBOL_REFERENCES_LOCAL (info, h))
+ || (ELF_ST_VISIBILITY (h->other)
+ && h->root.type == bfd_link_hash_undefweak))
+ {
+ /* 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 2, 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_64 (output_bfd, relocation,
+ base_got->contents + off);
+ h->got.offset |= 1;
+ }
+
+ if ((h->def_regular
+ && info->shared
+ && SYMBOL_REFERENCES_LOCAL (info, h))
+ /* lgrl rx,sym@GOTENT -> larl rx, sym */
+ && ((r_type == R_390_GOTENT
+ && (bfd_get_16 (input_bfd,
+ contents + rel->r_offset - 2)
+ & 0xff0f) == 0xc408)
+ /* lg rx, sym@GOT(r12) -> larl rx, sym */
+ || (r_type == R_390_GOT20
+ && (bfd_get_32 (input_bfd,
+ contents + rel->r_offset - 2)
+ & 0xff00f000) == 0xe300c000
+ && bfd_get_8 (input_bfd,
+ contents + rel->r_offset + 3) == 0x04)))
+
+ {
+ unsigned short new_insn =
+ (0xc000 | (bfd_get_8 (input_bfd,
+ contents + rel->r_offset - 1) & 0xf0));
+ bfd_put_16 (output_bfd, new_insn,
+ contents + rel->r_offset - 2);
+ r_type = R_390_PC32DBL;
+ rel->r_addend = 2;
+ howto = elf_howto_table + r_type;
+ relocation = h->root.u.def.value
+ + h->root.u.def.section->output_section->vma
+ + h->root.u.def.section->output_offset;
+ goto do_relocation;
+ }
+ }
+ else
+ unresolved_reloc = FALSE;
+ }
+ else
+ {
+ if (local_got_offsets == NULL)
+ abort ();
+
+ off = local_got_offsets[r_symndx];
+
+ /* The offset must always be a multiple of 8. 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_64 (output_bfd, relocation,
+ htab->elf.sgot->contents + off);
+
+ if (info->shared)
+ {
+ asection *s;
+ Elf_Internal_Rela outrel;
+ bfd_byte *loc;
+
+ s = htab->elf.srelgot;
+ if (s == NULL)
+ abort ();
+
+ outrel.r_offset = (htab->elf.sgot->output_section->vma
+ + htab->elf.sgot->output_offset
+ + off);
+ outrel.r_info = ELF64_R_INFO (0, R_390_RELATIVE);
+ outrel.r_addend = relocation;
+ loc = s->contents;
+ loc += s->reloc_count++ * sizeof (Elf64_External_Rela);
+ bfd_elf64_swap_reloca_out (output_bfd, &outrel, loc);
+ }
+
+ local_got_offsets[r_symndx] |= 1;
+ }
+ }
+
+ if (off >= (bfd_vma) -2)
+ abort ();
+
+ relocation = base_got->output_offset + off;
+
+ /* For @GOTENT the relocation is against the offset between
+ the instruction and the symbols entry in the GOT and not
+ between the start of the GOT and the symbols entry. We
+ add the vma of the GOT to get the correct value. */
+ if ( r_type == R_390_GOTENT
+ || r_type == R_390_GOTPLTENT)
+ relocation += base_got->output_section->vma;
+
+ break;
+
+ case R_390_GOTOFF16:
+ case R_390_GOTOFF32:
+ case R_390_GOTOFF64:
+ /* Relocation is relative to the start of the global offset
+ table. */
+
+ /* 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 -= htab->elf.sgot->output_section->vma;
+ break;
+
+ case R_390_GOTPC:
+ case R_390_GOTPCDBL:
+ /* Use global offset table as symbol value. */
+ relocation = htab->elf.sgot->output_section->vma;
+ unresolved_reloc = FALSE;
+ break;
+
+ case R_390_PLT12DBL:
+ case R_390_PLT16DBL:
+ case R_390_PLT24DBL:
+ case R_390_PLT32:
+ case R_390_PLT32DBL:
+ case R_390_PLT64:
+ /* 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)
+ break;
+
+ if (h->plt.offset == (bfd_vma) -1
+ || (htab->elf.splt == NULL && !s390_is_ifunc_symbol_p (h)))
+ {
+ /* We didn't make a PLT entry for this symbol. This
+ happens when statically linking PIC code, or when
+ using -Bsymbolic. */
+ break;
+ }
+ if (s390_is_ifunc_symbol_p (h))
+ relocation = (htab->elf.iplt->output_section->vma
+ + htab->elf.iplt->output_offset
+ + h->plt.offset);
+ else
+ relocation = (htab->elf.splt->output_section->vma
+ + htab->elf.splt->output_offset
+ + h->plt.offset);
+ unresolved_reloc = FALSE;
+ break;
+
+ case R_390_PLTOFF16:
+ case R_390_PLTOFF32:
+ case R_390_PLTOFF64:
+ /* Relocation is to the entry for this symbol in the
+ procedure linkage table relative to the start of the GOT. */
+
+ /* For local symbols or if we didn't make a PLT entry for
+ this symbol resolve the symbol directly. */
+ if (h == NULL
+ || h->plt.offset == (bfd_vma) -1
+ || (htab->elf.splt == NULL && !s390_is_ifunc_symbol_p (h)))
+ {
+ relocation -= htab->elf.sgot->output_section->vma;
+ break;
+ }
+
+ if (s390_is_ifunc_symbol_p (h))
+ relocation = (htab->elf.iplt->output_section->vma
+ + htab->elf.iplt->output_offset
+ + h->plt.offset
+ - htab->elf.sgot->output_section->vma);
+ else
+ relocation = (htab->elf.splt->output_section->vma
+ + htab->elf.splt->output_offset
+ + h->plt.offset
+ - htab->elf.sgot->output_section->vma);
+ unresolved_reloc = FALSE;
+ break;
+
+ case R_390_8:
+ case R_390_16:
+ case R_390_32:
+ case R_390_64:
+ case R_390_PC16:
+ case R_390_PC12DBL:
+ case R_390_PC16DBL:
+ case R_390_PC24DBL:
+ case R_390_PC32:
+ case R_390_PC32DBL:
+ case R_390_PC64:
+
+ if (h != NULL
+ && s390_is_ifunc_symbol_p (h)
+ && h->def_regular)
+ {
+ if (!info->shared || !h->non_got_ref)
+ {
+ /* For a non-shared object STT_GNU_IFUNC symbol must
+ go through PLT. */
+ relocation = (htab->elf.iplt->output_section->vma
+ + htab->elf.iplt->output_offset
+ + h ->plt.offset);
+ goto do_relocation;
+ }
+ else
+ {
+ /* For shared objects a runtime relocation is needed. */
+
+ Elf_Internal_Rela outrel;
+ asection *sreloc;
+
+ /* Need a dynamic relocation to get the real function
+ address. */
+ outrel.r_offset = _bfd_elf_section_offset (output_bfd,
+ info,
+ input_section,
+ rel->r_offset);
+ if (outrel.r_offset == (bfd_vma) -1
+ || outrel.r_offset == (bfd_vma) -2)
+ abort ();
+
+ outrel.r_offset += (input_section->output_section->vma
+ + input_section->output_offset);
+
+ if (h->dynindx == -1
+ || h->forced_local
+ || info->executable)
+ {
+ /* This symbol is resolved locally. */
+ outrel.r_info = ELF64_R_INFO (0, R_390_IRELATIVE);
+ outrel.r_addend = (h->root.u.def.value
+ + h->root.u.def.section->output_section->vma
+ + h->root.u.def.section->output_offset);
+ }
+ else
+ {
+ outrel.r_info = ELF64_R_INFO (h->dynindx, r_type);
+ outrel.r_addend = 0;
+ }
+
+ sreloc = htab->elf.irelifunc;
+ elf_append_rela (output_bfd, sreloc, &outrel);
+
+ /* 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. For an
+ internal symbol, we have updated addend. */
+ continue;
+ }
+ }
+
+ if ((input_section->flags & SEC_ALLOC) == 0)
+ break;
+
+ if ((info->shared
+ && (h == NULL
+ || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
+ || h->root.type != bfd_link_hash_undefweak)
+ && ((r_type != R_390_PC16
+ && r_type != R_390_PC12DBL
+ && r_type != R_390_PC16DBL
+ && r_type != R_390_PC24DBL
+ && r_type != R_390_PC32
+ && r_type != R_390_PC32DBL
+ && r_type != R_390_PC64)
+ || !SYMBOL_CALLS_LOCAL (info, h)))
+ || (ELIMINATE_COPY_RELOCS
+ && !info->shared
+ && h != NULL
+ && h->dynindx != -1
+ && !h->non_got_ref
+ && ((h->def_dynamic
+ && !h->def_regular)
+ || h->root.type == bfd_link_hash_undefweak
+ || h->root.type == bfd_link_hash_undefined)))
+ {
+ Elf_Internal_Rela outrel;
+ bfd_boolean skip, relocate;
+ asection *sreloc;
+ bfd_byte *loc;
+
+ /* When generating a shared object, these relocations
+ are copied into the output file to be resolved at run
+ time. */
+ skip = FALSE;
+ relocate = FALSE;
+
+ outrel.r_offset =
+ _bfd_elf_section_offset (output_bfd, info, input_section,
+ rel->r_offset);
+ if (outrel.r_offset == (bfd_vma) -1)
+ skip = TRUE;
+ else if (outrel.r_offset == (bfd_vma) -2)
+ skip = TRUE, relocate = TRUE;
+
+ outrel.r_offset += (input_section->output_section->vma
+ + input_section->output_offset);
+
+ if (skip)
+ memset (&outrel, 0, sizeof outrel);
+ else if (h != NULL
+ && h->dynindx != -1
+ && (r_type == R_390_PC16
+ || r_type == R_390_PC12DBL
+ || r_type == R_390_PC16DBL
+ || r_type == R_390_PC24DBL
+ || r_type == R_390_PC32
+ || r_type == R_390_PC32DBL
+ || r_type == R_390_PC64
+ || !info->shared
+ || !SYMBOLIC_BIND (info, h)
+ || !h->def_regular))
+ {
+ outrel.r_info = ELF64_R_INFO (h->dynindx, r_type);
+ outrel.r_addend = rel->r_addend;
+ }
+ else
+ {
+ /* This symbol is local, or marked to become local. */
+ outrel.r_addend = relocation + rel->r_addend;
+ if (r_type == R_390_64)
+ {
+ relocate = TRUE;
+ outrel.r_info = ELF64_R_INFO (0, R_390_RELATIVE);
+ }
+ else
+ {
+ long sindx;
+
+ if (bfd_is_abs_section (sec))
+ sindx = 0;
+ else if (sec == NULL || sec->owner == NULL)
+ {
+ bfd_set_error(bfd_error_bad_value);
+ return FALSE;
+ }
+ else
+ {
+ asection *osec;
+
+ osec = sec->output_section;
+ sindx = elf_section_data (osec)->dynindx;
+
+ if (sindx == 0)
+ {
+ osec = htab->elf.text_index_section;
+ sindx = elf_section_data (osec)->dynindx;
+ }
+ BFD_ASSERT (sindx != 0);
+
+ /* We are turning this relocation into one
+ against a section symbol, so subtract out
+ the output section's address but not the
+ offset of the input section in the output
+ section. */
+ outrel.r_addend -= osec->vma;
+ }
+ outrel.r_info = ELF64_R_INFO (sindx, r_type);
+ }
+ }
+
+ sreloc = elf_section_data (input_section)->sreloc;
+ if (sreloc == NULL)
+ abort ();
+
+ loc = sreloc->contents;
+ loc += sreloc->reloc_count++ * sizeof (Elf64_External_Rela);
+ bfd_elf64_swap_reloca_out (output_bfd, &outrel, loc);
+
+ /* 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;
+
+ /* Relocations for tls literal pool entries. */
+ case R_390_TLS_IE64:
+ if (info->shared)
+ {
+ Elf_Internal_Rela outrel;
+ asection *sreloc;
+ bfd_byte *loc;
+
+ outrel.r_offset = rel->r_offset
+ + input_section->output_section->vma
+ + input_section->output_offset;
+ outrel.r_info = ELF64_R_INFO (0, R_390_RELATIVE);
+ sreloc = elf_section_data (input_section)->sreloc;
+ if (sreloc == NULL)
+ abort ();
+ loc = sreloc->contents;
+ loc += sreloc->reloc_count++ * sizeof (Elf64_External_Rela);
+ bfd_elf64_swap_reloc_out (output_bfd, &outrel, loc);
+ }
+ /* Fall through. */
+
+ case R_390_TLS_GD64:
+ case R_390_TLS_GOTIE64:
+ r_type = elf_s390_tls_transition (info, r_type, h == NULL);
+ tls_type = GOT_UNKNOWN;
+ if (h == NULL && local_got_offsets)
+ tls_type = elf_s390_local_got_tls_type (input_bfd) [r_symndx];
+ else if (h != NULL)
+ {
+ tls_type = elf_s390_hash_entry(h)->tls_type;
+ if (!info->shared && h->dynindx == -1 && tls_type >= GOT_TLS_IE)
+ r_type = R_390_TLS_LE64;
+ }
+ if (r_type == R_390_TLS_GD64 && tls_type >= GOT_TLS_IE)
+ r_type = R_390_TLS_IE64;
+
+ if (r_type == R_390_TLS_LE64)
+ {
+ /* This relocation gets optimized away by the local exec
+ access optimization. */
+ BFD_ASSERT (! unresolved_reloc);
+ bfd_put_64 (output_bfd, -tpoff (info, relocation),
+ contents + rel->r_offset);
+ continue;
+ }
+
+ if (htab->elf.sgot == NULL)
+ abort ();
+
+ if (h != NULL)
+ off = h->got.offset;
+ else
+ {
+ if (local_got_offsets == NULL)
+ abort ();
+
+ off = local_got_offsets[r_symndx];
+ }
+
+ emit_tls_relocs:
+
+ if ((off & 1) != 0)
+ off &= ~1;
+ else
+ {
+ Elf_Internal_Rela outrel;
+ bfd_byte *loc;
+ int dr_type, indx;
+
+ if (htab->elf.srelgot == NULL)
+ abort ();
+
+ outrel.r_offset = (htab->elf.sgot->output_section->vma
+ + htab->elf.sgot->output_offset + off);
+
+ indx = h && h->dynindx != -1 ? h->dynindx : 0;
+ if (r_type == R_390_TLS_GD64)
+ dr_type = R_390_TLS_DTPMOD;
+ else
+ dr_type = R_390_TLS_TPOFF;
+ if (dr_type == R_390_TLS_TPOFF && indx == 0)
+ outrel.r_addend = relocation - dtpoff_base (info);
+ else
+ outrel.r_addend = 0;
+ outrel.r_info = ELF64_R_INFO (indx, dr_type);
+ loc = htab->elf.srelgot->contents;
+ loc += htab->elf.srelgot->reloc_count++
+ * sizeof (Elf64_External_Rela);
+ bfd_elf64_swap_reloca_out (output_bfd, &outrel, loc);
+
+ if (r_type == R_390_TLS_GD64)
+ {
+ if (indx == 0)
+ {
+ BFD_ASSERT (! unresolved_reloc);
+ bfd_put_64 (output_bfd,
+ relocation - dtpoff_base (info),
+ htab->elf.sgot->contents + off + GOT_ENTRY_SIZE);
+ }
+ else
+ {
+ outrel.r_info = ELF64_R_INFO (indx, R_390_TLS_DTPOFF);
+ outrel.r_offset += GOT_ENTRY_SIZE;
+ outrel.r_addend = 0;
+ htab->elf.srelgot->reloc_count++;
+ loc += sizeof (Elf64_External_Rela);
+ bfd_elf64_swap_reloca_out (output_bfd, &outrel, loc);
+ }
+ }
+
+ if (h != NULL)
+ h->got.offset |= 1;
+ else
+ local_got_offsets[r_symndx] |= 1;
+ }
+
+ if (off >= (bfd_vma) -2)
+ abort ();
+ if (r_type == ELF64_R_TYPE (rel->r_info))
+ {
+ relocation = htab->elf.sgot->output_offset + off;
+ if (r_type == R_390_TLS_IE64 || r_type == R_390_TLS_IEENT)
+ relocation += htab->elf.sgot->output_section->vma;
+ unresolved_reloc = FALSE;
+ }
+ else
+ {
+ bfd_put_64 (output_bfd, htab->elf.sgot->output_offset + off,
+ contents + rel->r_offset);
+ continue;
+ }
+ break;
+
+ case R_390_TLS_GOTIE12:
+ case R_390_TLS_GOTIE20:
+ case R_390_TLS_IEENT:
+ if (h == NULL)
+ {
+ if (local_got_offsets == NULL)
+ abort();
+ off = local_got_offsets[r_symndx];
+ if (info->shared)
+ goto emit_tls_relocs;
+ }
+ else
+ {
+ off = h->got.offset;
+ tls_type = elf_s390_hash_entry(h)->tls_type;
+ if (info->shared || h->dynindx != -1 || tls_type < GOT_TLS_IE)
+ goto emit_tls_relocs;
+ }
+
+ if (htab->elf.sgot == NULL)
+ abort ();
+
+ BFD_ASSERT (! unresolved_reloc);
+ bfd_put_64 (output_bfd, -tpoff (info, relocation),
+ htab->elf.sgot->contents + off);
+ relocation = htab->elf.sgot->output_offset + off;
+ if (r_type == R_390_TLS_IEENT)
+ relocation += htab->elf.sgot->output_section->vma;
+ unresolved_reloc = FALSE;
+ break;
+
+ case R_390_TLS_LDM64:
+ if (! info->shared)
+ /* The literal pool entry this relocation refers to gets ignored
+ by the optimized code of the local exec model. Do nothing
+ and the value will turn out zero. */
+ continue;
+
+ if (htab->elf.sgot == NULL)
+ abort ();
+
+ off = htab->tls_ldm_got.offset;
+ if (off & 1)
+ off &= ~1;
+ else
+ {
+ Elf_Internal_Rela outrel;
+ bfd_byte *loc;
+
+ if (htab->elf.srelgot == NULL)
+ abort ();
+
+ outrel.r_offset = (htab->elf.sgot->output_section->vma
+ + htab->elf.sgot->output_offset + off);
+
+ bfd_put_64 (output_bfd, 0,
+ htab->elf.sgot->contents + off + GOT_ENTRY_SIZE);
+ outrel.r_info = ELF64_R_INFO (0, R_390_TLS_DTPMOD);
+ outrel.r_addend = 0;
+ loc = htab->elf.srelgot->contents;
+ loc += htab->elf.srelgot->reloc_count++
+ * sizeof (Elf64_External_Rela);
+ bfd_elf64_swap_reloca_out (output_bfd, &outrel, loc);
+ htab->tls_ldm_got.offset |= 1;
+ }
+ relocation = htab->elf.sgot->output_offset + off;
+ unresolved_reloc = FALSE;
+ break;
+
+ case R_390_TLS_LE64:
+ if (info->shared && !info->pie)
+ {
+ /* Linking a shared library with non-fpic code requires
+ a R_390_TLS_TPOFF relocation. */
+ Elf_Internal_Rela outrel;
+ asection *sreloc;
+ bfd_byte *loc;
+ int indx;
+
+ outrel.r_offset = rel->r_offset
+ + input_section->output_section->vma
+ + input_section->output_offset;
+ if (h != NULL && h->dynindx != -1)
+ indx = h->dynindx;
+ else
+ indx = 0;
+ outrel.r_info = ELF64_R_INFO (indx, R_390_TLS_TPOFF);
+ if (indx == 0)
+ outrel.r_addend = relocation - dtpoff_base (info);
+ else
+ outrel.r_addend = 0;
+ sreloc = elf_section_data (input_section)->sreloc;
+ if (sreloc == NULL)
+ abort ();
+ loc = sreloc->contents;
+ loc += sreloc->reloc_count++ * sizeof (Elf64_External_Rela);
+ bfd_elf64_swap_reloca_out (output_bfd, &outrel, loc);
+ }
+ else
+ {
+ BFD_ASSERT (! unresolved_reloc);
+ bfd_put_64 (output_bfd, -tpoff (info, relocation),
+ contents + rel->r_offset);
+ }
+ continue;
+
+ case R_390_TLS_LDO64:
+ if (info->shared || (input_section->flags & SEC_DEBUGGING))
+ relocation -= dtpoff_base (info);
+ else
+ /* When converting LDO to LE, we must negate. */
+ relocation = -tpoff (info, relocation);
+ break;
+
+ /* Relocations for tls instructions. */
+ case R_390_TLS_LOAD:
+ case R_390_TLS_GDCALL:
+ case R_390_TLS_LDCALL:
+ tls_type = GOT_UNKNOWN;
+ if (h == NULL && local_got_offsets)
+ tls_type = elf_s390_local_got_tls_type (input_bfd) [r_symndx];
+ else if (h != NULL)
+ tls_type = elf_s390_hash_entry(h)->tls_type;
+
+ if (tls_type == GOT_TLS_GD)
+ continue;
+
+ if (r_type == R_390_TLS_LOAD)
+ {
+ if (!info->shared && (h == NULL || h->dynindx == -1))
+ {
+ /* IE->LE transition. Four valid cases:
+ lg %rx,(0,%ry) -> sllg %rx,%ry,0
+ lg %rx,(%ry,0) -> sllg %rx,%ry,0
+ lg %rx,(%ry,%r12) -> sllg %rx,%ry,0
+ lg %rx,(%r12,%ry) -> sllg %rx,%ry,0 */
+ unsigned int insn0, insn1, ry;
+
+ insn0 = bfd_get_32 (input_bfd, contents + rel->r_offset);
+ insn1 = bfd_get_16 (input_bfd, contents + rel->r_offset + 4);
+ if (insn1 != 0x0004)
+ invalid_tls_insn (input_bfd, input_section, rel);
+ ry = 0;
+ if ((insn0 & 0xff00f000) == 0xe3000000)
+ /* lg %rx,0(%ry,0) -> sllg %rx,%ry,0 */
+ ry = (insn0 & 0x000f0000);
+ else if ((insn0 & 0xff0f0000) == 0xe3000000)
+ /* lg %rx,0(0,%ry) -> sllg %rx,%ry,0 */
+ ry = (insn0 & 0x0000f000) << 4;
+ else if ((insn0 & 0xff00f000) == 0xe300c000)
+ /* lg %rx,0(%ry,%r12) -> sllg %rx,%ry,0 */
+ ry = (insn0 & 0x000f0000);
+ else if ((insn0 & 0xff0f0000) == 0xe30c0000)
+ /* lg %rx,0(%r12,%ry) -> sllg %rx,%ry,0 */
+ ry = (insn0 & 0x0000f000) << 4;
+ else
+ invalid_tls_insn (input_bfd, input_section, rel);
+ insn0 = 0xeb000000 | (insn0 & 0x00f00000) | ry;
+ insn1 = 0x000d;
+ bfd_put_32 (output_bfd, insn0, contents + rel->r_offset);
+ bfd_put_16 (output_bfd, insn1, contents + rel->r_offset + 4);
+ }
+ }
+ else if (r_type == R_390_TLS_GDCALL)
+ {
+ unsigned int insn0, insn1;
+
+ insn0 = bfd_get_32 (input_bfd, contents + rel->r_offset);
+ insn1 = bfd_get_16 (input_bfd, contents + rel->r_offset + 4);
+ if ((insn0 & 0xffff0000) != 0xc0e50000)
+ invalid_tls_insn (input_bfd, input_section, rel);
+ if (!info->shared && (h == NULL || h->dynindx == -1))
+ {
+ /* GD->LE transition.
+ brasl %r14,__tls_get_addr@plt -> brcl 0,. */
+ insn0 = 0xc0040000;
+ insn1 = 0x0000;
+ }
+ else
+ {
+ /* GD->IE transition.
+ brasl %r14,__tls_get_addr@plt -> lg %r2,0(%r2,%r12) */
+ insn0 = 0xe322c000;
+ insn1 = 0x0004;
+ }
+ bfd_put_32 (output_bfd, insn0, contents + rel->r_offset);
+ bfd_put_16 (output_bfd, insn1, contents + rel->r_offset + 4);
+ }
+ else if (r_type == R_390_TLS_LDCALL)
+ {
+ if (!info->shared)
+ {
+ unsigned int insn0, insn1;
+
+ insn0 = bfd_get_32 (input_bfd, contents + rel->r_offset);
+ insn1 = bfd_get_16 (input_bfd, contents + rel->r_offset + 4);
+ if ((insn0 & 0xffff0000) != 0xc0e50000)
+ invalid_tls_insn (input_bfd, input_section, rel);
+ /* LD->LE transition.
+ brasl %r14,__tls_get_addr@plt -> brcl 0,. */
+ insn0 = 0xc0040000;
+ insn1 = 0x0000;
+ bfd_put_32 (output_bfd, insn0, contents + rel->r_offset);
+ bfd_put_16 (output_bfd, insn1, contents + rel->r_offset + 4);
+ }
+ }
+ continue;
+
+ default:
+ break;
+ }
+
+ /* Dynamic relocs are not propagated for SEC_DEBUGGING sections
+ because such sections are not SEC_ALLOC and thus ld.so will
+ not process them. */
+ if (unresolved_reloc
+ && !((input_section->flags & SEC_DEBUGGING) != 0
+ && h->def_dynamic)
+ && _bfd_elf_section_offset (output_bfd, info, input_section,
+ rel->r_offset) != (bfd_vma) -1)
+ (*_bfd_error_handler)
+ (_("%B(%A+0x%lx): unresolvable %s relocation against symbol `%s'"),
+ input_bfd,
+ input_section,
+ (long) rel->r_offset,
+ howto->name,
+ h->root.root.string);
+
+ do_relocation:
+
+ /* When applying a 24 bit reloc we need to start one byte
+ earlier. Otherwise the 32 bit get/put bfd operations might
+ access a byte after the actual section. */
+ if (r_type == R_390_PC24DBL
+ || r_type == R_390_PLT24DBL)
+ rel->r_offset--;
+
+ if (r_type == R_390_20
+ || r_type == R_390_GOT20
+ || r_type == R_390_GOTPLT20
+ || r_type == R_390_TLS_GOTIE20)
+ {
+ relocation += rel->r_addend;
+ relocation = (relocation&0xfff) << 8 | (relocation&0xff000) >> 12;
+ r = _bfd_final_link_relocate (howto, input_bfd, input_section,
+ contents, rel->r_offset,
+ relocation, 0);
+ }
+ else
+ 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 *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 (r == bfd_reloc_overflow)
+ {
+
+ if (! ((*info->callbacks->reloc_overflow)
+ (info, (h ? &h->root : NULL), name, howto->name,
+ (bfd_vma) 0, input_bfd, input_section,
+ rel->r_offset)))
+ return FALSE;
+ }
+ else
+ {
+ (*_bfd_error_handler)
+ (_("%B(%A+0x%lx): reloc against `%s': error %d"),
+ input_bfd, input_section,
+ (long) rel->r_offset, name, (int) r);
+ return FALSE;
+ }
+ }
+ }
+
+ return TRUE;
+}
+
+/* Generate the PLT slots together with the dynamic relocations needed
+ for IFUNC symbols. */
+
+static void
+elf_s390_finish_ifunc_symbol (bfd *output_bfd,
+ struct bfd_link_info *info,
+ struct elf_link_hash_entry *h,
+ struct elf_s390_link_hash_table *htab,
+ bfd_vma plt_offset,
+ bfd_vma resolver_address)
+{
+ bfd_vma plt_index;
+ bfd_vma got_offset;
+ Elf_Internal_Rela rela;
+ bfd_byte *loc;
+ asection *plt, *gotplt, *relplt;
+
+ if (htab->elf.iplt == NULL
+ || htab->elf.igotplt == NULL
+ || htab->elf.irelplt == NULL)
+ abort ();
+
+ /* Index of the PLT slot within iplt section. */
+ plt_index = plt_offset / PLT_ENTRY_SIZE;
+ plt = htab->elf.iplt;
+ /* Offset into the igot.plt section. */
+ got_offset = plt_index * GOT_ENTRY_SIZE;
+ gotplt = htab->elf.igotplt;
+ relplt = htab->elf.irelplt;
+
+ /* Fill in the blueprint of a PLT. */
+ memcpy (plt->contents + plt_offset, elf_s390x_plt_entry,
+ PLT_ENTRY_SIZE);
+
+ /* Fixup the relative address to the GOT entry */
+ bfd_put_32 (output_bfd,
+ (gotplt->output_section->vma +
+ gotplt->output_offset + got_offset
+ - (plt->output_section->vma +
+ plt->output_offset +
+ plt_offset))/2,
+ plt->contents + plt_offset + 2);
+ /* Fixup the relative branch to PLT 0 */
+ bfd_put_32 (output_bfd, - (plt->output_offset +
+ (PLT_ENTRY_SIZE * plt_index) + 22)/2,
+ plt->contents + plt_offset + 24);
+ /* Fixup offset into .rela.plt section. */
+ bfd_put_32 (output_bfd, relplt->output_offset +
+ plt_index * sizeof (Elf64_External_Rela),
+ plt->contents + plt_offset + 28);
+
+ /* Fill in the entry in the global offset table.
+ Points to instruction after GOT offset. */
+ bfd_put_64 (output_bfd,
+ (plt->output_section->vma
+ + plt->output_offset
+ + plt_offset
+ + 14),
+ gotplt->contents + got_offset);
+
+ /* Fill in the entry in the .rela.plt section. */
+ rela.r_offset = (gotplt->output_section->vma
+ + gotplt->output_offset
+ + got_offset);
+
+ if (!h
+ || h->dynindx == -1
+ || ((info->executable
+ || ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
+ && h->def_regular))
+ {
+ /* The symbol can be locally resolved. */
+ rela.r_info = ELF64_R_INFO (0, R_390_IRELATIVE);
+ rela.r_addend = resolver_address;
+ }
+ else
+ {
+ rela.r_info = ELF64_R_INFO (h->dynindx, R_390_JMP_SLOT);
+ rela.r_addend = 0;
+ }
+
+ loc = relplt->contents + plt_index * sizeof (Elf64_External_Rela);
+ bfd_elf64_swap_reloca_out (output_bfd, &rela, loc);
+}
+
+
+/* Finish up dynamic symbol handling. We set the contents of various
+ dynamic sections here. */
+
+static bfd_boolean
+elf_s390_finish_dynamic_symbol (bfd *output_bfd,
+ struct bfd_link_info *info,
+ struct elf_link_hash_entry *h,
+ Elf_Internal_Sym *sym)
+{
+ struct elf_s390_link_hash_table *htab;
+ struct elf_s390_link_hash_entry *eh = (struct elf_s390_link_hash_entry*)h;
+
+ htab = elf_s390_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ if (h->plt.offset != (bfd_vma) -1)
+ {
+ bfd_vma plt_index;
+ bfd_vma got_offset;
+ Elf_Internal_Rela rela;
+ bfd_byte *loc;
+
+ /* This symbol has an entry in the procedure linkage table. Set
+ it up. */
+ if (s390_is_ifunc_symbol_p (h))
+ {
+ /* If we can resolve the IFUNC symbol locally we generate an
+ IRELATIVE reloc. */
+ elf_s390_finish_ifunc_symbol (output_bfd, info, h, htab, h->plt.offset,
+ eh->ifunc_resolver_address +
+ eh->ifunc_resolver_section->output_offset +
+ eh->ifunc_resolver_section->output_section->vma);
+ ;
+ /* Fallthrough. Handling of explicit GOT slots of IFUNC
+ symbols is below. */
+ }
+ else
+ {
+ if (h->dynindx == -1
+ || htab->elf.splt == NULL
+ || htab->elf.sgotplt == NULL
+ || htab->elf.srelplt == NULL)
+ abort ();
+
+ /* Calc. index no.
+ Current offset - size first entry / entry size. */
+ plt_index = (h->plt.offset - PLT_FIRST_ENTRY_SIZE) / PLT_ENTRY_SIZE;
+
+ /* Offset in GOT is PLT index plus GOT headers(3) times 8,
+ addr & GOT addr. */
+ got_offset = (plt_index + 3) * GOT_ENTRY_SIZE;
+
+ /* Fill in the blueprint of a PLT. */
+ memcpy (htab->elf.splt->contents + h->plt.offset, elf_s390x_plt_entry,
+ PLT_ENTRY_SIZE);
+
+ /* Fixup the relative address to the GOT entry */
+ bfd_put_32 (output_bfd,
+ (htab->elf.sgotplt->output_section->vma +
+ htab->elf.sgotplt->output_offset + got_offset
+ - (htab->elf.splt->output_section->vma +
+ htab->elf.splt->output_offset +
+ h->plt.offset))/2,
+ htab->elf.splt->contents + h->plt.offset + 2);
+ /* Fixup the relative branch to PLT 0 */
+ bfd_put_32 (output_bfd, - (PLT_FIRST_ENTRY_SIZE +
+ (PLT_ENTRY_SIZE * plt_index) + 22)/2,
+ htab->elf.splt->contents + h->plt.offset + 24);
+ /* Fixup offset into .rela.plt section. */
+ bfd_put_32 (output_bfd, plt_index * sizeof (Elf64_External_Rela),
+ htab->elf.splt->contents + h->plt.offset + 28);
+
+ /* Fill in the entry in the global offset table.
+ Points to instruction after GOT offset. */
+ bfd_put_64 (output_bfd,
+ (htab->elf.splt->output_section->vma
+ + htab->elf.splt->output_offset
+ + h->plt.offset
+ + 14),
+ htab->elf.sgotplt->contents + got_offset);
+
+ /* Fill in the entry in the .rela.plt section. */
+ rela.r_offset = (htab->elf.sgotplt->output_section->vma
+ + htab->elf.sgotplt->output_offset
+ + got_offset);
+ rela.r_info = ELF64_R_INFO (h->dynindx, R_390_JMP_SLOT);
+ rela.r_addend = 0;
+ loc = htab->elf.srelplt->contents + plt_index *
+ sizeof (Elf64_External_Rela);
+ bfd_elf64_swap_reloca_out (output_bfd, &rela, loc);
+
+ if (!h->def_regular)
+ {
+ /* Mark the symbol as undefined, rather than as defined in
+ the .plt section. Leave the value alone. This is a clue
+ for the dynamic linker, to make function pointer
+ comparisons work between an application and shared
+ library. */
+ sym->st_shndx = SHN_UNDEF;
+ }
+ }
+ }
+
+ if (h->got.offset != (bfd_vma) -1
+ && elf_s390_hash_entry(h)->tls_type != GOT_TLS_GD
+ && elf_s390_hash_entry(h)->tls_type != GOT_TLS_IE
+ && elf_s390_hash_entry(h)->tls_type != GOT_TLS_IE_NLT)
+ {
+ Elf_Internal_Rela rela;
+ bfd_byte *loc;
+
+ /* This symbol has an entry in the global offset table. Set it
+ up. */
+ if (htab->elf.sgot == NULL || htab->elf.srelgot == NULL)
+ abort ();
+
+ rela.r_offset = (htab->elf.sgot->output_section->vma
+ + htab->elf.sgot->output_offset
+ + (h->got.offset &~ (bfd_vma) 1));
+
+ if (h->def_regular && s390_is_ifunc_symbol_p (h))
+ {
+ if (info->shared)
+ {
+ /* An explicit GOT slot usage needs GLOB_DAT. If the
+ symbol references local the implicit got.iplt slot
+ will be used and the IRELATIVE reloc has been created
+ above. */
+ goto do_glob_dat;
+ }
+ else
+ {
+ /* For non-shared objects explicit GOT slots must be
+ filled with the PLT slot address for pointer
+ equality reasons. */
+ bfd_put_64 (output_bfd, (htab->elf.iplt->output_section->vma
+ + htab->elf.iplt->output_offset
+ + h->plt.offset),
+ htab->elf.sgot->contents + h->got.offset);
+ return TRUE;
+ }
+ }
+ else if (info->shared
+ && SYMBOL_REFERENCES_LOCAL (info, h))
+ {
+ /* If this is a static link, or it is a -Bsymbolic link and
+ the symbol is defined locally or was forced to be local
+ because of a version file, 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 (!h->def_regular)
+ return FALSE;
+ BFD_ASSERT((h->got.offset & 1) != 0);
+ rela.r_info = ELF64_R_INFO (0, R_390_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);
+do_glob_dat:
+ bfd_put_64 (output_bfd, (bfd_vma) 0, htab->elf.sgot->contents + h->got.offset);
+ rela.r_info = ELF64_R_INFO (h->dynindx, R_390_GLOB_DAT);
+ rela.r_addend = 0;
+ }
+
+ loc = htab->elf.srelgot->contents;
+ loc += htab->elf.srelgot->reloc_count++ * sizeof (Elf64_External_Rela);
+ bfd_elf64_swap_reloca_out (output_bfd, &rela, loc);
+ }
+
+ if (h->needs_copy)
+ {
+ Elf_Internal_Rela rela;
+ bfd_byte *loc;
+
+ /* This symbols needs a copy reloc. Set it up. */
+
+ if (h->dynindx == -1
+ || (h->root.type != bfd_link_hash_defined
+ && h->root.type != bfd_link_hash_defweak)
+ || htab->srelbss == NULL)
+ abort ();
+
+ 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_390_COPY);
+ rela.r_addend = 0;
+ loc = htab->srelbss->contents;
+ loc += htab->srelbss->reloc_count++ * sizeof (Elf64_External_Rela);
+ bfd_elf64_swap_reloca_out (output_bfd, &rela, loc);
+ }
+
+ /* Mark some specially defined symbols as absolute. */
+ if (h == htab->elf.hdynamic
+ || h == htab->elf.hgot
+ || h == htab->elf.hplt)
+ sym->st_shndx = SHN_ABS;
+
+ return TRUE;
+}
+
+/* Used to decide how to sort relocs in an optimal manner for the
+ dynamic linker, before writing them out. */
+
+static enum elf_reloc_type_class
+elf_s390_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ const asection *rel_sec ATTRIBUTE_UNUSED,
+ const Elf_Internal_Rela *rela)
+{
+ switch ((int) ELF64_R_TYPE (rela->r_info))
+ {
+ case R_390_RELATIVE:
+ return reloc_class_relative;
+ case R_390_JMP_SLOT:
+ return reloc_class_plt;
+ case R_390_COPY:
+ return reloc_class_copy;
+ default:
+ return reloc_class_normal;
+ }
+}
+
+/* Finish up the dynamic sections. */
+
+static bfd_boolean
+elf_s390_finish_dynamic_sections (bfd *output_bfd,
+ struct bfd_link_info *info)
+{
+ struct elf_s390_link_hash_table *htab;
+ bfd *dynobj;
+ asection *sdyn;
+ bfd *ibfd;
+ unsigned int i;
+
+ htab = elf_s390_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ dynobj = htab->elf.dynobj;
+ sdyn = bfd_get_linker_section (dynobj, ".dynamic");
+
+ if (htab->elf.dynamic_sections_created)
+ {
+ Elf64_External_Dyn *dyncon, *dynconend;
+
+ if (sdyn == NULL || htab->elf.sgot == NULL)
+ abort ();
+
+ dyncon = (Elf64_External_Dyn *) sdyn->contents;
+ dynconend = (Elf64_External_Dyn *) (sdyn->contents + sdyn->size);
+ for (; dyncon < dynconend; dyncon++)
+ {
+ Elf_Internal_Dyn dyn;
+ asection *s;
+
+ bfd_elf64_swap_dyn_in (dynobj, dyncon, &dyn);
+
+ switch (dyn.d_tag)
+ {
+ default:
+ continue;
+
+ case DT_PLTGOT:
+ dyn.d_un.d_ptr = htab->elf.sgot->output_section->vma;
+ break;
+
+ case DT_JMPREL:
+ dyn.d_un.d_ptr = htab->elf.srelplt->output_section->vma;
+ break;
+
+ case DT_PLTRELSZ:
+ s = htab->elf.srelplt->output_section;
+ dyn.d_un.d_val = s->size;
+ 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 = htab->elf.srelplt->output_section;
+ dyn.d_un.d_val -= s->size;
+ break;
+ }
+
+ bfd_elf64_swap_dyn_out (output_bfd, &dyn, dyncon);
+ }
+
+ /* Fill in the special first entry in the procedure linkage table. */
+ if (htab->elf.splt && htab->elf.splt->size > 0)
+ {
+ /* fill in blueprint for plt 0 entry */
+ memcpy (htab->elf.splt->contents, elf_s390x_first_plt_entry,
+ PLT_FIRST_ENTRY_SIZE);
+ /* Fixup relative address to start of GOT */
+ bfd_put_32 (output_bfd,
+ (htab->elf.sgotplt->output_section->vma +
+ htab->elf.sgotplt->output_offset
+ - htab->elf.splt->output_section->vma - 6)/2,
+ htab->elf.splt->contents + 8);
+ }
+ if (elf_section_data (htab->elf.splt->output_section) != NULL)
+ elf_section_data (htab->elf.splt->output_section)->this_hdr.sh_entsize
+ = PLT_ENTRY_SIZE;
+ }
+
+ if (htab->elf.sgotplt)
+ {
+ /* Fill in the first three entries in the global offset table. */
+ if (htab->elf.sgotplt->size > 0)
+ {
+ bfd_put_64 (output_bfd,
+ (sdyn == NULL ? (bfd_vma) 0
+ : sdyn->output_section->vma + sdyn->output_offset),
+ htab->elf.sgotplt->contents);
+ /* One entry for shared object struct ptr. */
+ bfd_put_64 (output_bfd, (bfd_vma) 0, htab->elf.sgotplt->contents + 8);
+ /* One entry for _dl_runtime_resolve. */
+ bfd_put_64 (output_bfd, (bfd_vma) 0, htab->elf.sgotplt->contents + 12);
+ }
+
+ elf_section_data (htab->elf.sgot->output_section)
+ ->this_hdr.sh_entsize = 8;
+ }
+
+ /* Finish dynamic symbol for local IFUNC symbols. */
+ for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next)
+ {
+ struct plt_entry *local_plt;
+ Elf_Internal_Sym *isym;
+ Elf_Internal_Shdr *symtab_hdr;
+
+ symtab_hdr = &elf_symtab_hdr (ibfd);
+
+ local_plt = elf_s390_local_plt (ibfd);
+ if (local_plt != NULL)
+ for (i = 0; i < symtab_hdr->sh_info; i++)
+ {
+ if (local_plt[i].plt.offset != (bfd_vma) -1)
+ {
+ asection *sec = local_plt[i].sec;
+ isym = bfd_sym_from_r_symndx (&htab->sym_cache, ibfd, i);
+ if (isym == NULL)
+ return FALSE;
+
+ if (ELF_ST_TYPE (isym->st_info) == STT_GNU_IFUNC)
+ elf_s390_finish_ifunc_symbol (output_bfd, info, NULL, htab,
+ local_plt[i].plt.offset,
+ isym->st_value
+ + sec->output_section->vma
+ + sec->output_offset);
+
+ }
+ }
+ }
+
+ return TRUE;
+}
+
+/* Return address for Ith PLT stub in section PLT, for relocation REL
+ or (bfd_vma) -1 if it should not be included. */
+
+static bfd_vma
+elf_s390_plt_sym_val (bfd_vma i, const asection *plt,
+ const arelent *rel ATTRIBUTE_UNUSED)
+{
+ return plt->vma + PLT_FIRST_ENTRY_SIZE + i * PLT_ENTRY_SIZE;
+}
+
+/* Why was the hash table entry size definition changed from
+ ARCH_SIZE/8 to 4? This breaks the 64 bit dynamic linker and
+ this is the only reason for the s390_elf64_size_info structure. */
+
+const struct elf_size_info s390_elf64_size_info =
+{
+ sizeof (Elf64_External_Ehdr),
+ sizeof (Elf64_External_Phdr),
+ sizeof (Elf64_External_Shdr),
+ sizeof (Elf64_External_Rel),
+ sizeof (Elf64_External_Rela),
+ sizeof (Elf64_External_Sym),
+ sizeof (Elf64_External_Dyn),
+ sizeof (Elf_External_Note),
+ 8, /* hash-table entry size. */
+ 1, /* internal relocations per external relocations. */
+ 64, /* arch_size. */
+ 3, /* log_file_align. */
+ ELFCLASS64, EV_CURRENT,
+ bfd_elf64_write_out_phdrs,
+ bfd_elf64_write_shdrs_and_ehdr,
+ bfd_elf64_checksum_contents,
+ bfd_elf64_write_relocs,
+ bfd_elf64_swap_symbol_in,
+ bfd_elf64_swap_symbol_out,
+ bfd_elf64_slurp_reloc_table,
+ bfd_elf64_slurp_symbol_table,
+ bfd_elf64_swap_dyn_in,
+ bfd_elf64_swap_dyn_out,
+ bfd_elf64_swap_reloc_in,
+ bfd_elf64_swap_reloc_out,
+ bfd_elf64_swap_reloca_in,
+ bfd_elf64_swap_reloca_out
+};
+
+#define TARGET_BIG_SYM s390_elf64_vec
+#define TARGET_BIG_NAME "elf64-s390"
+#define ELF_ARCH bfd_arch_s390
+#define ELF_TARGET_ID S390_ELF_DATA
+#define ELF_MACHINE_CODE EM_S390
+#define ELF_MACHINE_ALT1 EM_S390_OLD
+#define ELF_MAXPAGESIZE 0x1000
+
+#define elf_backend_size_info s390_elf64_size_info
+
+#define elf_backend_can_gc_sections 1
+#define elf_backend_can_refcount 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 24
+#define elf_backend_rela_normal 1
+
+#define elf_info_to_howto elf_s390_info_to_howto
+
+#define bfd_elf64_bfd_is_local_label_name elf_s390_is_local_label_name
+#define bfd_elf64_bfd_link_hash_table_create elf_s390_link_hash_table_create
+#define bfd_elf64_bfd_reloc_type_lookup elf_s390_reloc_type_lookup
+#define bfd_elf64_bfd_reloc_name_lookup elf_s390_reloc_name_lookup
+
+#define elf_backend_adjust_dynamic_symbol elf_s390_adjust_dynamic_symbol
+#define elf_backend_check_relocs elf_s390_check_relocs
+#define elf_backend_copy_indirect_symbol elf_s390_copy_indirect_symbol
+#define elf_backend_create_dynamic_sections elf_s390_create_dynamic_sections
+#define elf_backend_finish_dynamic_sections elf_s390_finish_dynamic_sections
+#define elf_backend_finish_dynamic_symbol elf_s390_finish_dynamic_symbol
+#define elf_backend_gc_mark_hook elf_s390_gc_mark_hook
+#define elf_backend_gc_sweep_hook elf_s390_gc_sweep_hook
+#define elf_backend_reloc_type_class elf_s390_reloc_type_class
+#define elf_backend_relocate_section elf_s390_relocate_section
+#define elf_backend_size_dynamic_sections elf_s390_size_dynamic_sections
+#define elf_backend_init_index_section _bfd_elf_init_1_index_section
+#define elf_backend_plt_sym_val elf_s390_plt_sym_val
+#define elf_backend_add_symbol_hook elf_s390_add_symbol_hook
+
+#define bfd_elf64_mkobject elf_s390_mkobject
+#define elf_backend_object_p elf_s390_object_p
+
+/* Enable ELF64 archive functions. */
+#define bfd_elf64_archive_functions
+extern bfd_boolean bfd_elf64_archive_slurp_armap (bfd *);
+extern bfd_boolean bfd_elf64_archive_write_armap (bfd *, unsigned int, struct orl *, unsigned int, int);
+
+#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_read_ar_hdr _bfd_archive_coff_read_ar_hdr
+#define bfd_elf64_archive_write_ar_hdr _bfd_archive_coff_write_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-sh64.c b/bfd/elf64-sh64.c
new file mode 100644
index 0000000..311d7c3
--- /dev/null
+++ b/bfd/elf64-sh64.c
@@ -0,0 +1,4060 @@
+/* SuperH SH64-specific support for 64-bit ELF
+ Copyright (C) 2000-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#define SH64_ELF64
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "bfdlink.h"
+#include "libbfd.h"
+#include "elf-bfd.h"
+#include "elf/sh.h"
+
+/* Add a suffix for datalabel indirection symbols. It must not match any
+ other symbols; user symbols with or without version or other
+ decoration. It must only be used internally and not emitted by any
+ means. */
+#define DATALABEL_SUFFIX " DL"
+
+#define GOT_BIAS (-((long)-32768))
+
+#define PLT_ENTRY_SIZE 64
+
+/* Return size of a PLT entry. */
+#define elf_sh64_sizeof_plt(info) PLT_ENTRY_SIZE
+
+/* Return offset of the PLT0 address in an absolute PLT entry. */
+#define elf_sh64_plt_plt0_offset(info) 32
+
+/* Return offset of the linker in PLT0 entry. */
+#define elf_sh64_plt0_gotplt_offset(info) 0
+
+/* Return offset of the trampoline in PLT entry */
+#define elf_sh64_plt_temp_offset(info) 33 /* Add one because it's SHmedia. */
+
+/* Return offset of the symbol in PLT entry. */
+#define elf_sh64_plt_symbol_offset(info) 0
+
+/* Return offset of the relocation in PLT entry. */
+#define elf_sh64_plt_reloc_offset(info) (info->shared ? 52 : 44)
+
+#define ELF_DYNAMIC_INTERPRETER "/usr/lib/libc.so.1"
+
+/* The sh 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_sh64_pcrel_relocs_copied
+{
+ /* Next section. */
+ struct elf_sh64_pcrel_relocs_copied *next;
+ /* A section in dynobj. */
+ asection *section;
+ /* Number of relocs copied in this section. */
+ bfd_size_type count;
+};
+
+/* sh ELF linker hash entry. */
+
+struct elf_sh64_link_hash_entry
+{
+ struct elf_link_hash_entry root;
+
+ bfd_vma datalabel_got_offset;
+
+ /* Number of PC relative relocs copied for this symbol. */
+ struct elf_sh64_pcrel_relocs_copied *pcrel_relocs_copied;
+};
+
+/* Traverse an sh ELF linker hash table. */
+
+#define sh64_elf64_link_hash_traverse(table, func, info) \
+ (elf_link_hash_traverse \
+ ((table), \
+ (bfd_boolean (*) (struct elf_link_hash_entry *, void *)) (func), \
+ (info)))
+
+static bfd_reloc_status_type sh_elf64_ignore_reloc
+ (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
+static bfd_reloc_status_type sh_elf64_reloc
+ (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
+
+static reloc_howto_type sh_elf64_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_elf64_ignore_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_elf64_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_elf64_ignore_reloc, /* special_function */
+ "R_SH_REL32", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* For 32-bit sh, this is R_SH_DIR8WPN. */
+ EMPTY_HOWTO (3),
+
+ /* For 32-bit sh, this is R_SH_IND12W. */
+ EMPTY_HOWTO (4),
+
+ /* For 32-bit sh, this is R_SH_DIR8WPL. */
+ EMPTY_HOWTO (5),
+
+ /* For 32-bit sh, this is R_SH_DIR8WPZ. */
+ EMPTY_HOWTO (6),
+
+ /* For 32-bit sh, this is R_SH_DIR8BP. */
+ EMPTY_HOWTO (7),
+
+ /* For 32-bit sh, this is R_SH_DIR8W. */
+ EMPTY_HOWTO (8),
+
+ /* For 32-bit sh, this is R_SH_DIR8L. */
+ EMPTY_HOWTO (9),
+
+ EMPTY_HOWTO (10),
+ EMPTY_HOWTO (11),
+ EMPTY_HOWTO (12),
+ EMPTY_HOWTO (13),
+ EMPTY_HOWTO (14),
+ EMPTY_HOWTO (15),
+ EMPTY_HOWTO (16),
+ EMPTY_HOWTO (17),
+ EMPTY_HOWTO (18),
+ EMPTY_HOWTO (19),
+ EMPTY_HOWTO (20),
+ EMPTY_HOWTO (21),
+ EMPTY_HOWTO (22),
+ EMPTY_HOWTO (23),
+ EMPTY_HOWTO (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_elf64_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_elf64_ignore_reloc, /* special_function */
+ "R_SH_SWITCH32", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* For 32-bit sh, this is R_SH_USES. */
+ EMPTY_HOWTO (27),
+
+ /* For 32-bit sh, this is R_SH_COUNT. */
+ EMPTY_HOWTO (28),
+
+ /* For 32-bit sh, this is R_SH_ALIGN. FIXME: For linker relaxation,
+ this might be emitted. When linker relaxation is implemented, we
+ might want to use it. */
+ EMPTY_HOWTO (29),
+
+ /* For 32-bit sh, this is R_SH_CODE. FIXME: For linker relaxation,
+ this might be emitted. When linker relaxation is implemented, we
+ might want to use it. */
+ EMPTY_HOWTO (30),
+
+ /* For 32-bit sh, this is R_SH_DATA. FIXME: For linker relaxation,
+ this might be emitted. When linker relaxation is implemented, we
+ might want to use it. */
+ EMPTY_HOWTO (31),
+
+ /* For 32-bit sh, this is R_SH_LABEL. FIXME: For linker relaxation,
+ this might be emitted. When linker relaxation is implemented, we
+ might want to use it. */
+ EMPTY_HOWTO (32),
+
+ /* 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_elf64_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 */
+
+ /* For 32-bit sh, this is R_SH_LOOP_START. */
+ EMPTY_HOWTO (36),
+
+ /* For 32-bit sh, this is R_SH_LOOP_END. */
+ EMPTY_HOWTO (37),
+
+ EMPTY_HOWTO (38),
+ EMPTY_HOWTO (39),
+ EMPTY_HOWTO (40),
+ EMPTY_HOWTO (41),
+ EMPTY_HOWTO (42),
+ EMPTY_HOWTO (43),
+ EMPTY_HOWTO (44),
+
+ /* Used in SHLLI.L and SHLRI.L. */
+ HOWTO (R_SH_DIR5U, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 5, /* bitsize */
+ FALSE, /* pc_relative */
+ 10, /* bitpos */
+ complain_overflow_unsigned, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SH_DIR5U", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xfc00, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Used in SHARI, SHLLI et al. */
+ HOWTO (R_SH_DIR6U, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 6, /* bitsize */
+ FALSE, /* pc_relative */
+ 10, /* bitpos */
+ complain_overflow_unsigned, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SH_DIR6U", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xfc00, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Used in BxxI, LDHI.L et al. */
+ HOWTO (R_SH_DIR6S, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 6, /* bitsize */
+ FALSE, /* pc_relative */
+ 10, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SH_DIR6S", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xfc00, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Used in ADDI, ANDI et al. */
+ HOWTO (R_SH_DIR10S, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 10, /* bitsize */
+ FALSE, /* pc_relative */
+ 10, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SH_DIR10S", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffc00, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Used in LD.UW, ST.W et al. */
+ HOWTO (R_SH_DIR10SW, /* type */
+ 1, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 11, /* bitsize */
+ FALSE, /* pc_relative */
+ 10, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SH_DIR10SW", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffc00, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Used in LD.L, FLD.S et al. */
+ HOWTO (R_SH_DIR10SL, /* type */
+ 2, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 12, /* bitsize */
+ FALSE, /* pc_relative */
+ 10, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SH_DIR10SL", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffc00, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Used in FLD.D, FST.P et al. */
+ HOWTO (R_SH_DIR10SQ, /* type */
+ 3, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 13, /* bitsize */
+ FALSE, /* pc_relative */
+ 10, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SH_DIR10SQ", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffc00, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ EMPTY_HOWTO (52),
+ EMPTY_HOWTO (53),
+ EMPTY_HOWTO (54),
+ EMPTY_HOWTO (55),
+ EMPTY_HOWTO (56),
+ EMPTY_HOWTO (57),
+ EMPTY_HOWTO (58),
+ EMPTY_HOWTO (59),
+ EMPTY_HOWTO (60),
+ EMPTY_HOWTO (61),
+ EMPTY_HOWTO (62),
+ EMPTY_HOWTO (63),
+ EMPTY_HOWTO (64),
+ EMPTY_HOWTO (65),
+ EMPTY_HOWTO (66),
+ EMPTY_HOWTO (67),
+ EMPTY_HOWTO (68),
+ EMPTY_HOWTO (69),
+ EMPTY_HOWTO (70),
+ EMPTY_HOWTO (71),
+ EMPTY_HOWTO (72),
+ EMPTY_HOWTO (73),
+ EMPTY_HOWTO (74),
+ EMPTY_HOWTO (75),
+ EMPTY_HOWTO (76),
+ EMPTY_HOWTO (77),
+ EMPTY_HOWTO (78),
+ EMPTY_HOWTO (79),
+ EMPTY_HOWTO (80),
+ EMPTY_HOWTO (81),
+ EMPTY_HOWTO (82),
+ EMPTY_HOWTO (83),
+ EMPTY_HOWTO (84),
+ EMPTY_HOWTO (85),
+ EMPTY_HOWTO (86),
+ EMPTY_HOWTO (87),
+ EMPTY_HOWTO (88),
+ EMPTY_HOWTO (89),
+ EMPTY_HOWTO (90),
+ EMPTY_HOWTO (91),
+ EMPTY_HOWTO (92),
+ EMPTY_HOWTO (93),
+ EMPTY_HOWTO (94),
+ EMPTY_HOWTO (95),
+ EMPTY_HOWTO (96),
+ EMPTY_HOWTO (97),
+ EMPTY_HOWTO (98),
+ EMPTY_HOWTO (99),
+ EMPTY_HOWTO (100),
+ EMPTY_HOWTO (101),
+ EMPTY_HOWTO (102),
+ EMPTY_HOWTO (103),
+ EMPTY_HOWTO (104),
+ EMPTY_HOWTO (105),
+ EMPTY_HOWTO (106),
+ EMPTY_HOWTO (107),
+ EMPTY_HOWTO (108),
+ EMPTY_HOWTO (109),
+ EMPTY_HOWTO (110),
+ EMPTY_HOWTO (111),
+ EMPTY_HOWTO (112),
+ EMPTY_HOWTO (113),
+ EMPTY_HOWTO (114),
+ EMPTY_HOWTO (115),
+ EMPTY_HOWTO (116),
+ EMPTY_HOWTO (117),
+ EMPTY_HOWTO (118),
+ EMPTY_HOWTO (119),
+ EMPTY_HOWTO (120),
+ EMPTY_HOWTO (121),
+ EMPTY_HOWTO (122),
+ EMPTY_HOWTO (123),
+ EMPTY_HOWTO (124),
+ EMPTY_HOWTO (125),
+ EMPTY_HOWTO (126),
+ EMPTY_HOWTO (127),
+ EMPTY_HOWTO (128),
+ EMPTY_HOWTO (129),
+ EMPTY_HOWTO (130),
+ EMPTY_HOWTO (131),
+ EMPTY_HOWTO (132),
+ EMPTY_HOWTO (133),
+ EMPTY_HOWTO (134),
+ EMPTY_HOWTO (135),
+ EMPTY_HOWTO (136),
+ EMPTY_HOWTO (137),
+ EMPTY_HOWTO (138),
+ EMPTY_HOWTO (139),
+ EMPTY_HOWTO (140),
+ EMPTY_HOWTO (141),
+ EMPTY_HOWTO (142),
+ EMPTY_HOWTO (143),
+ EMPTY_HOWTO (144),
+ EMPTY_HOWTO (145),
+ EMPTY_HOWTO (146),
+ EMPTY_HOWTO (147),
+ EMPTY_HOWTO (148),
+ EMPTY_HOWTO (149),
+ EMPTY_HOWTO (150),
+ EMPTY_HOWTO (151),
+ EMPTY_HOWTO (152),
+ EMPTY_HOWTO (153),
+ EMPTY_HOWTO (154),
+ EMPTY_HOWTO (155),
+ EMPTY_HOWTO (156),
+ EMPTY_HOWTO (157),
+ EMPTY_HOWTO (158),
+ EMPTY_HOWTO (159),
+
+ /* Relocs for dynamic linking for 32-bit SH would follow. We don't have
+ any dynamic linking support for 64-bit SH at present. */
+
+ EMPTY_HOWTO (160),
+ EMPTY_HOWTO (161),
+ EMPTY_HOWTO (162),
+ EMPTY_HOWTO (163),
+ EMPTY_HOWTO (164),
+ EMPTY_HOWTO (165),
+ EMPTY_HOWTO (166),
+ EMPTY_HOWTO (167),
+ EMPTY_HOWTO (168),
+
+ /* Back to SH5 relocations. */
+ /* Used in MOVI and SHORI (x & 65536). */
+ HOWTO (R_SH_GOT_LOW16, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ FALSE, /* pc_relative */
+ 10, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SH_GOT_LOW16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x3fffc00, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Used in MOVI and SHORI ((x >> 16) & 65536). */
+ HOWTO (R_SH_GOT_MEDLOW16, /* type */
+ 16, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ FALSE, /* pc_relative */
+ 10, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SH_GOT_MEDLOW16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x3fffc00, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Used in MOVI and SHORI ((x >> 32) & 65536). */
+ HOWTO (R_SH_GOT_MEDHI16, /* type */
+ 32, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ FALSE, /* pc_relative */
+ 10, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SH_GOT_MEDHI16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x3fffc00, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Used in MOVI and SHORI ((x >> 48) & 65536). */
+ HOWTO (R_SH_GOT_HI16, /* type */
+ 48, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ FALSE, /* pc_relative */
+ 10, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SH_GOT_HI16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x3fffc00, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Used in MOVI and SHORI (x & 65536). */
+ HOWTO (R_SH_GOTPLT_LOW16, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ FALSE, /* pc_relative */
+ 10, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SH_GOTPLT_LOW16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x3fffc00, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Used in MOVI and SHORI ((x >> 16) & 65536). */
+ HOWTO (R_SH_GOTPLT_MEDLOW16, /* type */
+ 16, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ FALSE, /* pc_relative */
+ 10, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SH_GOTPLT_MEDLOW16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x3fffc00, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Used in MOVI and SHORI ((x >> 32) & 65536). */
+ HOWTO (R_SH_GOTPLT_MEDHI16, /* type */
+ 32, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ FALSE, /* pc_relative */
+ 10, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SH_GOTPLT_MEDHI16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x3fffc00, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Used in MOVI and SHORI ((x >> 48) & 65536). */
+ HOWTO (R_SH_GOTPLT_HI16, /* type */
+ 48, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ FALSE, /* pc_relative */
+ 10, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SH_GOTPLT_HI16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x3fffc00, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Used in MOVI and SHORI (x & 65536). */
+ HOWTO (R_SH_PLT_LOW16, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ TRUE, /* pc_relative */
+ 10, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SH_PLT_LOW16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x3fffc00, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* Used in MOVI and SHORI ((x >> 16) & 65536). */
+ HOWTO (R_SH_PLT_MEDLOW16, /* type */
+ 16, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ TRUE, /* pc_relative */
+ 10, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SH_PLT_MEDLOW16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x3fffc00, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* Used in MOVI and SHORI ((x >> 32) & 65536). */
+ HOWTO (R_SH_PLT_MEDHI16, /* type */
+ 32, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ TRUE, /* pc_relative */
+ 10, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SH_PLT_MEDHI16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x3fffc00, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* Used in MOVI and SHORI ((x >> 48) & 65536). */
+ HOWTO (R_SH_PLT_HI16, /* type */
+ 48, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ TRUE, /* pc_relative */
+ 10, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SH_PLT_HI16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x3fffc00, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* Used in MOVI and SHORI (x & 65536). */
+ HOWTO (R_SH_GOTOFF_LOW16, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ FALSE, /* pc_relative */
+ 10, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SH_GOTOFF_LOW16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x3fffc00, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Used in MOVI and SHORI ((x >> 16) & 65536). */
+ HOWTO (R_SH_GOTOFF_MEDLOW16, /* type */
+ 16, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ FALSE, /* pc_relative */
+ 10, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SH_GOTOFF_MEDLOW16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x3fffc00, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Used in MOVI and SHORI ((x >> 32) & 65536). */
+ HOWTO (R_SH_GOTOFF_MEDHI16, /* type */
+ 32, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ FALSE, /* pc_relative */
+ 10, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SH_GOTOFF_MEDHI16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x3fffc00, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Used in MOVI and SHORI ((x >> 48) & 65536). */
+ HOWTO (R_SH_GOTOFF_HI16, /* type */
+ 48, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ FALSE, /* pc_relative */
+ 10, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SH_GOTOFF_HI16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x3fffc00, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Used in MOVI and SHORI (x & 65536). */
+ HOWTO (R_SH_GOTPC_LOW16, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ TRUE, /* pc_relative */
+ 10, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SH_GOTPC_LOW16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x3fffc00, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* Used in MOVI and SHORI ((x >> 16) & 65536). */
+ HOWTO (R_SH_GOTPC_MEDLOW16, /* type */
+ 16, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ TRUE, /* pc_relative */
+ 10, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SH_GOTPC_MEDLOW16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x3fffc00, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* Used in MOVI and SHORI ((x >> 32) & 65536). */
+ HOWTO (R_SH_GOTPC_MEDHI16, /* type */
+ 32, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ TRUE, /* pc_relative */
+ 10, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SH_GOTPC_MEDHI16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x3fffc00, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* Used in MOVI and SHORI ((x >> 48) & 65536). */
+ HOWTO (R_SH_GOTPC_HI16, /* type */
+ 48, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ TRUE, /* pc_relative */
+ 10, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SH_GOTPC_HI16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x3fffc00, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* Used in LD.L, FLD.S et al. */
+ HOWTO (R_SH_GOT10BY4, /* type */
+ 2, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 12, /* bitsize */
+ FALSE, /* pc_relative */
+ 10, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SH_GOT10BY4", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffc00, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Used in LD.L, FLD.S et al. */
+ HOWTO (R_SH_GOTPLT10BY4, /* type */
+ 2, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 12, /* bitsize */
+ FALSE, /* pc_relative */
+ 10, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SH_GOTPLT10BY4", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffc00, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Used in FLD.D, FST.P et al. */
+ HOWTO (R_SH_GOT10BY8, /* type */
+ 3, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 13, /* bitsize */
+ FALSE, /* pc_relative */
+ 10, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SH_GOT10BY8", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffc00, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Used in FLD.D, FST.P et al. */
+ HOWTO (R_SH_GOTPLT10BY8, /* type */
+ 3, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 13, /* bitsize */
+ FALSE, /* pc_relative */
+ 10, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SH_GOTPLT10BY8", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffc00, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_SH_COPY64, /* type */
+ 0, /* rightshift */
+ 4, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SH_COPY64", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ ((bfd_vma) 0) - 1, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_SH_GLOB_DAT64, /* type */
+ 0, /* rightshift */
+ 4, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SH_GLOB_DAT64", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ ((bfd_vma) 0) - 1, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_SH_JMP_SLOT64, /* type */
+ 0, /* rightshift */
+ 4, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SH_JMP_SLOT64", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ ((bfd_vma) 0) - 1, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_SH_RELATIVE64, /* type */
+ 0, /* rightshift */
+ 4, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SH_RELATIVE64", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ ((bfd_vma) 0) - 1, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ EMPTY_HOWTO (197),
+ EMPTY_HOWTO (198),
+ EMPTY_HOWTO (199),
+ EMPTY_HOWTO (200),
+ EMPTY_HOWTO (201),
+ EMPTY_HOWTO (202),
+ EMPTY_HOWTO (203),
+ EMPTY_HOWTO (204),
+ EMPTY_HOWTO (205),
+ EMPTY_HOWTO (206),
+ EMPTY_HOWTO (207),
+ EMPTY_HOWTO (208),
+ EMPTY_HOWTO (209),
+ EMPTY_HOWTO (210),
+ EMPTY_HOWTO (211),
+ EMPTY_HOWTO (212),
+ EMPTY_HOWTO (213),
+ EMPTY_HOWTO (214),
+ EMPTY_HOWTO (215),
+ EMPTY_HOWTO (216),
+ EMPTY_HOWTO (217),
+ EMPTY_HOWTO (218),
+ EMPTY_HOWTO (219),
+ EMPTY_HOWTO (220),
+ EMPTY_HOWTO (221),
+ EMPTY_HOWTO (222),
+ EMPTY_HOWTO (223),
+ EMPTY_HOWTO (224),
+ EMPTY_HOWTO (225),
+ EMPTY_HOWTO (226),
+ EMPTY_HOWTO (227),
+ EMPTY_HOWTO (228),
+ EMPTY_HOWTO (229),
+ EMPTY_HOWTO (230),
+ EMPTY_HOWTO (231),
+ EMPTY_HOWTO (232),
+ EMPTY_HOWTO (233),
+ EMPTY_HOWTO (234),
+ EMPTY_HOWTO (235),
+ EMPTY_HOWTO (236),
+ EMPTY_HOWTO (237),
+ EMPTY_HOWTO (238),
+ EMPTY_HOWTO (239),
+ EMPTY_HOWTO (240),
+ EMPTY_HOWTO (241),
+
+ /* Relocations for SHmedia code. None of these are partial_inplace or
+ use the field being relocated. */
+
+ /* The assembler will generate this reloc before a block of SHmedia
+ instructions. A section should be processed as assuming it contains
+ data, unless this reloc is seen. Note that a block of SHcompact
+ instructions are instead preceded by R_SH_CODE.
+ This is currently not implemented, but should be used for SHmedia
+ linker relaxation. */
+ HOWTO (R_SH_SHMEDIA_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_elf64_ignore_reloc, /* special_function */
+ "R_SH_SHMEDIA_CODE", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* The assembler will generate this reloc at a PTA or PTB instruction,
+ and the linker checks the right type of target, or changes a PTA to a
+ PTB, if the original insn was PT. */
+ HOWTO (R_SH_PT_16, /* type */
+ 2, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 18, /* bitsize */
+ TRUE, /* pc_relative */
+ 10, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SH_PT_16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x3fffc00, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* Used in unexpanded MOVI. */
+ HOWTO (R_SH_IMMS16, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 10, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SH_IMMS16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x3fffc00, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Used in SHORI. */
+ HOWTO (R_SH_IMMU16, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 10, /* bitpos */
+ complain_overflow_unsigned, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SH_IMMU16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x3fffc00, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Used in MOVI and SHORI (x & 65536). */
+ HOWTO (R_SH_IMM_LOW16, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ FALSE, /* pc_relative */
+ 10, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SH_IMM_LOW16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x3fffc00, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Used in MOVI and SHORI ((x - $) & 65536). */
+ HOWTO (R_SH_IMM_LOW16_PCREL, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ TRUE, /* pc_relative */
+ 10, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SH_IMM_LOW16_PCREL", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x3fffc00, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* Used in MOVI and SHORI ((x >> 16) & 65536). */
+ HOWTO (R_SH_IMM_MEDLOW16, /* type */
+ 16, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ FALSE, /* pc_relative */
+ 10, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SH_IMM_MEDLOW16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x3fffc00, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Used in MOVI and SHORI (((x - $) >> 16) & 65536). */
+ HOWTO (R_SH_IMM_MEDLOW16_PCREL, /* type */
+ 16, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ TRUE, /* pc_relative */
+ 10, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SH_IMM_MEDLOW16_PCREL", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x3fffc00, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* Used in MOVI and SHORI ((x >> 32) & 65536). */
+ HOWTO (R_SH_IMM_MEDHI16, /* type */
+ 32, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ FALSE, /* pc_relative */
+ 10, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SH_IMM_MEDHI16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x3fffc00, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Used in MOVI and SHORI (((x - $) >> 32) & 65536). */
+ HOWTO (R_SH_IMM_MEDHI16_PCREL, /* type */
+ 32, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ TRUE, /* pc_relative */
+ 10, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SH_IMM_MEDHI16_PCREL", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x3fffc00, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* Used in MOVI and SHORI ((x >> 48) & 65536). */
+ HOWTO (R_SH_IMM_HI16, /* type */
+ 48, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ FALSE, /* pc_relative */
+ 10, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SH_IMM_HI16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x3fffc00, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Used in MOVI and SHORI (((x - $) >> 48) & 65536). */
+ HOWTO (R_SH_IMM_HI16_PCREL, /* type */
+ 48, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ TRUE, /* pc_relative */
+ 10, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SH_IMM_HI16_PCREL", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x3fffc00, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* For the .uaquad pseudo. */
+ HOWTO (R_SH_64, /* type */
+ 0, /* rightshift */
+ 4, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SH_64", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ ((bfd_vma) 0) - 1, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* For the .uaquad pseudo, (x - $). */
+ HOWTO (R_SH_64_PCREL, /* type */
+ 48, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ TRUE, /* pc_relative */
+ 10, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_SH_64_PCREL", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ ((bfd_vma) 0) - 1, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+};
+
+/* This function is used for relocs which are only used for relaxing,
+ which the linker should otherwise ignore. */
+
+static bfd_reloc_status_type
+sh_elf64_ignore_reloc (bfd *abfd ATTRIBUTE_UNUSED, arelent *reloc_entry,
+ asymbol *symbol ATTRIBUTE_UNUSED,
+ void *data ATTRIBUTE_UNUSED, asection *input_section,
+ bfd *output_bfd,
+ char **error_message ATTRIBUTE_UNUSED)
+{
+ if (output_bfd != NULL)
+ reloc_entry->address += input_section->output_offset;
+ return bfd_reloc_ok;
+}
+
+/* This function is used for normal relocs. This used to be like the COFF
+ function, and is almost certainly incorrect for other ELF targets.
+
+ See sh_elf_reloc in elf32-sh.c for the original. */
+
+static bfd_reloc_status_type
+sh_elf64_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol_in,
+ void *data, asection *input_section, bfd *output_bfd,
+ char **error_message ATTRIBUTE_UNUSED)
+{
+ 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;
+ }
+
+ 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;
+
+ default:
+ abort ();
+ break;
+ }
+
+ 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 sh64_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_8_PCREL, R_SH_SWITCH8 },
+ { BFD_RELOC_SH_SWITCH16, R_SH_SWITCH16 },
+ { BFD_RELOC_SH_SWITCH32, R_SH_SWITCH32 },
+ { BFD_RELOC_VTABLE_INHERIT, R_SH_GNU_VTINHERIT },
+ { BFD_RELOC_VTABLE_ENTRY, R_SH_GNU_VTENTRY },
+ { BFD_RELOC_SH_GOT_LOW16, R_SH_GOT_LOW16 },
+ { BFD_RELOC_SH_GOT_MEDLOW16, R_SH_GOT_MEDLOW16 },
+ { BFD_RELOC_SH_GOT_MEDHI16, R_SH_GOT_MEDHI16 },
+ { BFD_RELOC_SH_GOT_HI16, R_SH_GOT_HI16 },
+ { BFD_RELOC_SH_GOTPLT_LOW16, R_SH_GOTPLT_LOW16 },
+ { BFD_RELOC_SH_GOTPLT_MEDLOW16, R_SH_GOTPLT_MEDLOW16 },
+ { BFD_RELOC_SH_GOTPLT_MEDHI16, R_SH_GOTPLT_MEDHI16 },
+ { BFD_RELOC_SH_GOTPLT_HI16, R_SH_GOTPLT_HI16 },
+ { BFD_RELOC_SH_PLT_LOW16, R_SH_PLT_LOW16 },
+ { BFD_RELOC_SH_PLT_MEDLOW16, R_SH_PLT_MEDLOW16 },
+ { BFD_RELOC_SH_PLT_MEDHI16, R_SH_PLT_MEDHI16 },
+ { BFD_RELOC_SH_PLT_HI16, R_SH_PLT_HI16 },
+ { BFD_RELOC_SH_GOTOFF_LOW16, R_SH_GOTOFF_LOW16 },
+ { BFD_RELOC_SH_GOTOFF_MEDLOW16, R_SH_GOTOFF_MEDLOW16 },
+ { BFD_RELOC_SH_GOTOFF_MEDHI16, R_SH_GOTOFF_MEDHI16 },
+ { BFD_RELOC_SH_GOTOFF_HI16, R_SH_GOTOFF_HI16 },
+ { BFD_RELOC_SH_GOTPC_LOW16, R_SH_GOTPC_LOW16 },
+ { BFD_RELOC_SH_GOTPC_MEDLOW16, R_SH_GOTPC_MEDLOW16 },
+ { BFD_RELOC_SH_GOTPC_MEDHI16, R_SH_GOTPC_MEDHI16 },
+ { BFD_RELOC_SH_GOTPC_HI16, R_SH_GOTPC_HI16 },
+ { BFD_RELOC_SH_COPY64, R_SH_COPY64 },
+ { BFD_RELOC_SH_GLOB_DAT64, R_SH_GLOB_DAT64 },
+ { BFD_RELOC_SH_JMP_SLOT64, R_SH_JMP_SLOT64 },
+ { BFD_RELOC_SH_RELATIVE64, R_SH_RELATIVE64 },
+ { BFD_RELOC_SH_GOT10BY4, R_SH_GOT10BY4 },
+ { BFD_RELOC_SH_GOT10BY8, R_SH_GOT10BY8 },
+ { BFD_RELOC_SH_GOTPLT10BY4, R_SH_GOTPLT10BY4 },
+ { BFD_RELOC_SH_GOTPLT10BY8, R_SH_GOTPLT10BY8 },
+ { BFD_RELOC_SH_PT_16, R_SH_PT_16 },
+ { BFD_RELOC_SH_SHMEDIA_CODE, R_SH_SHMEDIA_CODE },
+ { BFD_RELOC_SH_IMMU5, R_SH_DIR5U },
+ { BFD_RELOC_SH_IMMS6, R_SH_DIR6S },
+ { BFD_RELOC_SH_IMMU6, R_SH_DIR6U },
+ { BFD_RELOC_SH_IMMS10, R_SH_DIR10S },
+ { BFD_RELOC_SH_IMMS10BY2, R_SH_DIR10SW },
+ { BFD_RELOC_SH_IMMS10BY4, R_SH_DIR10SL },
+ { BFD_RELOC_SH_IMMS10BY8, R_SH_DIR10SQ },
+ { BFD_RELOC_SH_IMMS16, R_SH_IMMS16 },
+ { BFD_RELOC_SH_IMMU16, R_SH_IMMU16 },
+ { BFD_RELOC_SH_IMM_LOW16, R_SH_IMM_LOW16 },
+ { BFD_RELOC_SH_IMM_LOW16_PCREL, R_SH_IMM_LOW16_PCREL },
+ { BFD_RELOC_SH_IMM_MEDLOW16, R_SH_IMM_MEDLOW16 },
+ { BFD_RELOC_SH_IMM_MEDLOW16_PCREL, R_SH_IMM_MEDLOW16_PCREL },
+ { BFD_RELOC_SH_IMM_MEDHI16, R_SH_IMM_MEDHI16 },
+ { BFD_RELOC_SH_IMM_MEDHI16_PCREL, R_SH_IMM_MEDHI16_PCREL },
+ { BFD_RELOC_SH_IMM_HI16, R_SH_IMM_HI16 },
+ { BFD_RELOC_SH_IMM_HI16_PCREL, R_SH_IMM_HI16_PCREL },
+ { BFD_RELOC_64, R_SH_64 },
+ { BFD_RELOC_64_PCREL, R_SH_64_PCREL },
+};
+
+/* Given a BFD reloc code, return the howto structure for the
+ corresponding SH ELf reloc. */
+
+static reloc_howto_type *
+sh_elf64_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ bfd_reloc_code_real_type code)
+{
+ unsigned int i;
+
+ for (i = 0; i < sizeof (sh64_reloc_map) / sizeof (struct elf_reloc_map); i++)
+ {
+ if (sh64_reloc_map[i].bfd_reloc_val == code)
+ return &sh_elf64_howto_table[(int) sh64_reloc_map[i].elf_reloc_val];
+ }
+
+ return NULL;
+}
+
+static reloc_howto_type *
+sh_elf64_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ const char *r_name)
+{
+ unsigned int i;
+
+ for (i = 0;
+ i < sizeof (sh_elf64_howto_table) / sizeof (sh_elf64_howto_table[0]);
+ i++)
+ if (sh_elf64_howto_table[i].name != NULL
+ && strcasecmp (sh_elf64_howto_table[i].name, r_name) == 0)
+ return &sh_elf64_howto_table[i];
+
+ return NULL;
+}
+
+/* Given an ELF reloc, fill in the howto field of a relent.
+
+ See sh_elf_info_to_howto in elf32-sh.c for the original. */
+
+static void
+sh_elf64_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED, arelent *cache_ptr,
+ Elf_Internal_Rela *dst)
+{
+ unsigned int r;
+
+ r = ELF64_R_TYPE (dst->r_info);
+
+ BFD_ASSERT (r <= (unsigned int) R_SH_64_PCREL);
+ BFD_ASSERT (r < R_SH_FIRST_INVALID_RELOC || r > R_SH_LAST_INVALID_RELOC);
+ BFD_ASSERT (r < R_SH_DIR8WPN || r > R_SH_LAST_INVALID_RELOC_2);
+ BFD_ASSERT (r < R_SH_FIRST_INVALID_RELOC_3 || r > R_SH_GOTPLT32);
+ BFD_ASSERT (r < R_SH_FIRST_INVALID_RELOC_4 || r > R_SH_LAST_INVALID_RELOC_4);
+
+ cache_ptr->howto = &sh_elf64_howto_table[r];
+}
+
+/* Relocate an SH ELF section.
+
+ See sh_elf_info_to_howto in elf32-sh.c for the original. */
+
+static bfd_boolean
+sh_elf64_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
+ 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;
+ bfd *dynobj;
+ bfd_vma *local_got_offsets;
+ asection *sgot;
+ asection *sgotplt;
+ asection *splt;
+ asection *sreloc;
+ bfd_vma disp, dropped;
+
+ symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
+ sym_hashes = elf_sym_hashes (input_bfd);
+ dynobj = elf_hash_table (info)->dynobj;
+ local_got_offsets = elf_local_got_offsets (input_bfd);
+
+ sgot = NULL;
+ sgotplt = 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;
+ 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;
+ int seen_stt_datalabel = 0;
+
+ r_symndx = ELF64_R_SYM (rel->r_info);
+
+ r_type = ELF64_R_TYPE (rel->r_info);
+
+ if (r_type == (int) R_SH_NONE)
+ continue;
+
+ if (r_type < 0
+ || r_type > R_SH_64_PCREL
+ || (r_type >= (int) R_SH_FIRST_INVALID_RELOC
+ && r_type <= (int) R_SH_LAST_INVALID_RELOC)
+ || (r_type >= (int) R_SH_DIR8WPN
+ && r_type <= (int) R_SH_LAST_INVALID_RELOC)
+ || (r_type >= (int) R_SH_GNU_VTINHERIT
+ && r_type <= (int) R_SH_PSHL)
+ || (r_type >= (int) R_SH_FIRST_INVALID_RELOC_2
+ && r_type <= R_SH_GOTPLT32)
+ || (r_type >= (int) R_SH_FIRST_INVALID_RELOC_4
+ && r_type <= (int) R_SH_LAST_INVALID_RELOC_4))
+ {
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+
+ howto = sh_elf64_howto_table + r_type;
+
+ h = NULL;
+ sym = NULL;
+ sec = NULL;
+ relocation = 0;
+ 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)
+ | ((sym->st_other & STO_SH5_ISA32) != 0));
+
+ /* A local symbol never has STO_SH5_ISA32, so we don't need
+ datalabel processing here. Make sure this does not change
+ without notice. */
+ if ((sym->st_other & STO_SH5_ISA32) != 0)
+ ((*info->callbacks->reloc_dangerous)
+ (info,
+ _("Unexpected STO_SH5_ISA32 on local symbol is not handled"),
+ input_bfd, input_section, rel->r_offset));
+
+ if (sec != NULL && discarded_section (sec))
+ /* Handled below. */
+ ;
+ else if (info->relocatable)
+ {
+ /* This is a relocatable 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 (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
+ goto final_link_relocate;
+
+ continue;
+ }
+ else if (! howto->partial_inplace)
+ {
+ relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
+ relocation |= ((sym->st_other & STO_SH5_ISA32) != 0);
+ }
+ else if ((sec->flags & SEC_MERGE)
+ && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
+ {
+ asection *msec;
+
+ if (howto->rightshift || howto->src_mask != 0xffffffff)
+ {
+ (*_bfd_error_handler)
+ (_("%B(%A+0x%lx): %s relocation against SEC_MERGE section"),
+ input_bfd, input_section,
+ (long) rel->r_offset, howto->name);
+ return FALSE;
+ }
+
+ addend = bfd_get_32 (input_bfd, contents + rel->r_offset);
+ msec = sec;
+ addend =
+ _bfd_elf_rel_local_sym (output_bfd, sym, &msec, addend)
+ - relocation;
+ addend += msec->output_section->vma + msec->output_offset;
+ bfd_put_32 (input_bfd, addend, contents + rel->r_offset);
+ addend = 0;
+ }
+ }
+ else
+ {
+ /* ??? Could we use the RELOC_FOR_GLOBAL_SYMBOL macro here ? */
+
+ h = sym_hashes[r_symndx - symtab_hdr->sh_info];
+ while (h->root.type == bfd_link_hash_indirect
+ || h->root.type == bfd_link_hash_warning)
+ {
+ /* If the reference passes a symbol marked with
+ STT_DATALABEL, then any STO_SH5_ISA32 on the final value
+ doesn't count. */
+ seen_stt_datalabel |= h->type == STT_DATALABEL;
+ 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;
+ /* In these cases, we don't need the relocation value.
+ We check specially because in some obscure cases
+ sec->output_section will be NULL. */
+ if (r_type == R_SH_GOTPC_LOW16
+ || r_type == R_SH_GOTPC_MEDLOW16
+ || r_type == R_SH_GOTPC_MEDHI16
+ || r_type == R_SH_GOTPC_HI16
+ || ((r_type == R_SH_PLT_LOW16
+ || r_type == R_SH_PLT_MEDLOW16
+ || r_type == R_SH_PLT_MEDHI16
+ || r_type == R_SH_PLT_HI16)
+ && h->plt.offset != (bfd_vma) -1)
+ || ((r_type == R_SH_GOT_LOW16
+ || r_type == R_SH_GOT_MEDLOW16
+ || r_type == R_SH_GOT_MEDHI16
+ || r_type == R_SH_GOT_HI16)
+ && elf_hash_table (info)->dynamic_sections_created
+ && (! info->shared
+ || (! info->symbolic && h->dynindx != -1)
+ || !h->def_regular))
+ /* The cases above are those in which relocation is
+ overwritten in the switch block below. The cases
+ below are those in which we must defer relocation
+ to run-time, because we can't resolve absolute
+ addresses when creating a shared library. */
+ || (info->shared
+ && ((! info->symbolic && h->dynindx != -1)
+ || !h->def_regular)
+ && ((r_type == R_SH_64
+ && !(ELF_ST_VISIBILITY (h->other) == STV_INTERNAL
+ || ELF_ST_VISIBILITY (h->other) == STV_HIDDEN))
+ || r_type == R_SH_64_PCREL)
+ && ((input_section->flags & SEC_ALLOC) != 0
+ /* DWARF will emit R_SH_DIR32 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))
+ /* Dynamic relocs are not propagated for SEC_DEBUGGING
+ sections because such sections are not SEC_ALLOC and
+ thus ld.so will not process them. */
+ || (sec->output_section == NULL
+ && ((input_section->flags & SEC_DEBUGGING) != 0
+ && h->def_dynamic)))
+ ;
+ else if (sec->output_section != NULL)
+ relocation = ((h->root.u.def.value
+ + sec->output_section->vma
+ + sec->output_offset)
+ /* A STO_SH5_ISA32 causes a "bitor 1" to the
+ symbol value, unless we've seen
+ STT_DATALABEL on the way to it. */
+ | ((h->other & STO_SH5_ISA32) != 0
+ && ! seen_stt_datalabel));
+ else if (!info->relocatable
+ && (_bfd_elf_section_offset (output_bfd, info,
+ input_section,
+ rel->r_offset)
+ != (bfd_vma) -1))
+ {
+ (*_bfd_error_handler)
+ (_("%B(%A+0x%lx): unresolvable %s relocation against symbol `%s'"),
+ input_bfd,
+ input_section,
+ (long) rel->r_offset,
+ howto->name,
+ h->root.root.string);
+ }
+ }
+ else if (h->root.type == bfd_link_hash_undefweak)
+ ;
+ else if (info->unresolved_syms_in_objects == RM_IGNORE
+ && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)
+ ;
+ else if (!info->relocatable)
+ {
+ if (! ((*info->callbacks->undefined_symbol)
+ (info, h->root.root.string, input_bfd,
+ input_section, rel->r_offset,
+ (info->unresolved_syms_in_objects == RM_GENERATE_ERROR
+ || ELF_ST_VISIBILITY (h->other)))))
+ return FALSE;
+ }
+ }
+
+ if (sec != NULL && discarded_section (sec))
+ RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+ rel, 1, relend, howto, 0, contents);
+
+ if (info->relocatable)
+ continue;
+
+ disp = (relocation
+ - input_section->output_section->vma
+ - input_section->output_offset
+ - rel->r_offset);
+ dropped = 0;
+ switch ((int)r_type)
+ {
+ case R_SH_PT_16: dropped = disp & 2; break;
+ case R_SH_DIR10SW: dropped = disp & 1; break;
+ case R_SH_DIR10SL: dropped = disp & 3; break;
+ case R_SH_DIR10SQ: dropped = disp & 7; break;
+ }
+ if (dropped != 0)
+ {
+ (*_bfd_error_handler)
+ (_("%s: error: unaligned relocation type %d at %08x reloc %08x\n"),
+ bfd_get_filename (input_bfd), (int)r_type, (unsigned)rel->r_offset, (unsigned)relocation);
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+ switch ((int)r_type)
+ {
+ case R_SH_64:
+ case R_SH_64_PCREL:
+ if (info->shared
+ && (input_section->flags & SEC_ALLOC) != 0
+ && (r_type != R_SH_64_PCREL
+ || (h != NULL
+ && h->dynindx != -1
+ && (! info->symbolic
+ || !h->def_regular))))
+ {
+ Elf_Internal_Rela outrel;
+ bfd_byte *loc;
+ bfd_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)
+ {
+ sreloc = _bfd_elf_get_dynamic_reloc_section
+ (input_bfd, input_section, /*rela?*/ TRUE);
+ if (sreloc == NULL)
+ return FALSE;
+ }
+
+ skip = FALSE;
+ relocate = FALSE;
+
+ outrel.r_offset
+ = _bfd_elf_section_offset (output_bfd, info,
+ input_section, rel->r_offset);
+
+ if (outrel.r_offset == (bfd_vma) -1)
+ skip = TRUE;
+ else if (outrel.r_offset == (bfd_vma) -2)
+ skip = TRUE, relocate = TRUE;
+
+ outrel.r_offset += (input_section->output_section->vma
+ + input_section->output_offset);
+
+ if (skip)
+ memset (&outrel, 0, sizeof outrel);
+ else if (r_type == R_SH_64_PCREL)
+ {
+ BFD_ASSERT (h != NULL && h->dynindx != -1);
+ outrel.r_info = ELF64_R_INFO (h->dynindx, R_SH_64_PCREL);
+ outrel.r_addend = rel->r_addend;
+ }
+ else
+ {
+ /* h->dynindx may be -1 if this symbol was marked to
+ become local. */
+ if (h == NULL
+ || ((info->symbolic || h->dynindx == -1)
+ && h->def_regular))
+ {
+ relocate = TRUE;
+ outrel.r_info = ELF64_R_INFO (0, R_SH_RELATIVE64);
+ outrel.r_addend = relocation + rel->r_addend;
+ }
+ else
+ {
+ BFD_ASSERT (h->dynindx != -1);
+ outrel.r_info = ELF64_R_INFO (h->dynindx, R_SH_64);
+ outrel.r_addend = relocation + rel->r_addend;
+ }
+ }
+
+ loc = sreloc->contents;
+ loc += sreloc->reloc_count++ * sizeof (Elf64_External_Rela);
+ bfd_elf64_swap_reloca_out (output_bfd, &outrel, loc);
+
+ /* 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;
+ }
+ else if (r_type == R_SH_64)
+ addend = rel->r_addend;
+ goto final_link_relocate;
+
+ case R_SH_GOTPLT_LOW16:
+ case R_SH_GOTPLT_MEDLOW16:
+ case R_SH_GOTPLT_MEDHI16:
+ case R_SH_GOTPLT_HI16:
+ case R_SH_GOTPLT10BY4:
+ case R_SH_GOTPLT10BY8:
+ /* Relocation is to the entry for this symbol in the
+ procedure linkage table. */
+
+ if (h == NULL
+ || ELF_ST_VISIBILITY (h->other) == STV_INTERNAL
+ || ELF_ST_VISIBILITY (h->other) == STV_HIDDEN
+ || ! info->shared
+ || info->symbolic
+ || h->dynindx == -1
+ || h->plt.offset == (bfd_vma) -1
+ || h->got.offset != (bfd_vma) -1)
+ goto force_got;
+
+ /* Relocation is to the entry for this symbol in the global
+ offset table extension for the procedure linkage table. */
+ if (sgotplt == NULL)
+ {
+ sgotplt = bfd_get_linker_section (dynobj, ".got.plt");
+ BFD_ASSERT (sgotplt != NULL);
+ }
+
+ relocation = (sgotplt->output_offset
+ + ((h->plt.offset / elf_sh64_sizeof_plt (info)
+ - 1 + 3) * 8));
+
+ relocation -= GOT_BIAS;
+
+ goto final_link_relocate;
+
+ force_got:
+ case R_SH_GOT_LOW16:
+ case R_SH_GOT_MEDLOW16:
+ case R_SH_GOT_MEDHI16:
+ case R_SH_GOT_HI16:
+ case R_SH_GOT10BY4:
+ case R_SH_GOT10BY8:
+ /* Relocation is to the entry for this symbol in the global
+ offset table. */
+ if (sgot == NULL)
+ {
+ sgot = bfd_get_linker_section (dynobj, ".got");
+ BFD_ASSERT (sgot != NULL);
+ }
+
+ if (h != NULL)
+ {
+ bfd_vma off;
+
+ off = h->got.offset;
+ if (seen_stt_datalabel)
+ {
+ struct elf_sh64_link_hash_entry *hsh;
+
+ hsh = (struct elf_sh64_link_hash_entry *)h;
+ off = hsh->datalabel_got_offset;
+ }
+ BFD_ASSERT (off != (bfd_vma) -1);
+
+ if (! elf_hash_table (info)->dynamic_sections_created
+ || (info->shared
+ && (info->symbolic || h->dynindx == -1
+ || ELF_ST_VISIBILITY (h->other) == STV_INTERNAL
+ || ELF_ST_VISIBILITY (h->other) == STV_HIDDEN)
+ && h->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_64 (output_bfd, relocation,
+ sgot->contents + off);
+ if (seen_stt_datalabel)
+ {
+ struct elf_sh64_link_hash_entry *hsh;
+
+ hsh = (struct elf_sh64_link_hash_entry *)h;
+ hsh->datalabel_got_offset |= 1;
+ }
+ else
+ h->got.offset |= 1;
+ }
+ }
+
+ relocation = sgot->output_offset + off;
+ }
+ else
+ {
+ bfd_vma off;
+
+ if (rel->r_addend)
+ {
+ BFD_ASSERT (local_got_offsets != NULL
+ && (local_got_offsets[symtab_hdr->sh_info
+ + r_symndx]
+ != (bfd_vma) -1));
+
+ off = local_got_offsets[symtab_hdr->sh_info
+ + r_symndx];
+ }
+ 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 8. 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_64 (output_bfd, relocation, sgot->contents + off);
+
+ if (info->shared)
+ {
+ asection *s;
+ Elf_Internal_Rela outrel;
+ bfd_byte *loc;
+
+ s = bfd_get_linker_section (dynobj, ".rela.got");
+ BFD_ASSERT (s != NULL);
+
+ outrel.r_offset = (sgot->output_section->vma
+ + sgot->output_offset
+ + off);
+ outrel.r_info = ELF64_R_INFO (0, R_SH_RELATIVE64);
+ outrel.r_addend = relocation;
+ loc = s->contents;
+ loc += s->reloc_count++ * sizeof (Elf64_External_Rela);
+ bfd_elf64_swap_reloca_out (output_bfd, &outrel, loc);
+ }
+
+ if (rel->r_addend)
+ local_got_offsets[symtab_hdr->sh_info + r_symndx] |= 1;
+ else
+ local_got_offsets[r_symndx] |= 1;
+ }
+
+ relocation = sgot->output_offset + off;
+ }
+
+ relocation -= GOT_BIAS;
+
+ goto final_link_relocate;
+
+ case R_SH_GOTOFF_LOW16:
+ case R_SH_GOTOFF_MEDLOW16:
+ case R_SH_GOTOFF_MEDHI16:
+ case R_SH_GOTOFF_HI16:
+ /* Relocation is relative to the start of the global offset
+ table. */
+
+ if (sgot == NULL)
+ {
+ sgot = bfd_get_linker_section (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;
+
+ relocation -= GOT_BIAS;
+
+ addend = rel->r_addend;
+
+ goto final_link_relocate;
+
+ case R_SH_GOTPC_LOW16:
+ case R_SH_GOTPC_MEDLOW16:
+ case R_SH_GOTPC_MEDHI16:
+ case R_SH_GOTPC_HI16:
+ /* Use global offset table as symbol value. */
+
+ if (sgot == NULL)
+ {
+ sgot = bfd_get_linker_section (dynobj, ".got");
+ BFD_ASSERT (sgot != NULL);
+ }
+
+ relocation = sgot->output_section->vma;
+
+ relocation += GOT_BIAS;
+
+ addend = rel->r_addend;
+
+ goto final_link_relocate;
+
+ case R_SH_PLT_LOW16:
+ case R_SH_PLT_MEDLOW16:
+ case R_SH_PLT_MEDHI16:
+ case R_SH_PLT_HI16:
+ /* Relocation is to the entry for this symbol in the
+ procedure linkage table. */
+
+ /* Resolve a PLT reloc against a local symbol directly,
+ without using the procedure linkage table. */
+ if (h == NULL)
+ goto final_link_relocate;
+
+ if (ELF_ST_VISIBILITY (h->other) == STV_INTERNAL
+ || ELF_ST_VISIBILITY (h->other) == STV_HIDDEN)
+ goto final_link_relocate;
+
+ 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 final_link_relocate;
+ }
+
+ if (splt == NULL)
+ {
+ splt = bfd_get_linker_section (dynobj, ".plt");
+ BFD_ASSERT (splt != NULL);
+ }
+
+ relocation = (splt->output_section->vma
+ + splt->output_offset
+ + h->plt.offset);
+ relocation++;
+
+ addend = rel->r_addend;
+
+ goto final_link_relocate;
+
+ case R_SH_DIR32:
+ case R_SH_SHMEDIA_CODE:
+ case R_SH_PT_16:
+ case R_SH_DIR5U:
+ case R_SH_DIR6S:
+ case R_SH_DIR6U:
+ case R_SH_DIR10S:
+ case R_SH_DIR10SW:
+ case R_SH_DIR10SL:
+ case R_SH_DIR10SQ:
+ case R_SH_IMMS16:
+ case R_SH_IMMU16:
+ case R_SH_IMM_LOW16:
+ case R_SH_IMM_LOW16_PCREL:
+ case R_SH_IMM_MEDLOW16:
+ case R_SH_IMM_MEDLOW16_PCREL:
+ case R_SH_IMM_MEDHI16:
+ case R_SH_IMM_MEDHI16_PCREL:
+ case R_SH_IMM_HI16:
+ case R_SH_IMM_HI16_PCREL:
+ addend = rel->r_addend;
+ /* Fall through. */
+ case R_SH_REL32:
+ final_link_relocate:
+ r = _bfd_final_link_relocate (howto, input_bfd, input_section,
+ contents, rel->r_offset,
+ relocation, addend);
+ break;
+
+ default:
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+
+ }
+
+ if (r != bfd_reloc_ok)
+ {
+ switch (r)
+ {
+ default:
+ case bfd_reloc_outofrange:
+ abort ();
+ case bfd_reloc_overflow:
+ {
+ const char *name;
+
+ if (h != NULL)
+ name = NULL;
+ 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, (h ? &h->root : NULL), 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
+ that uses sh_elf64_relocate_section.
+
+ See sh_elf_relocate_section in elf32-sh.c for the original. */
+
+static bfd_byte *
+sh_elf64_get_relocated_section_contents (bfd *output_bfd,
+ struct bfd_link_info *link_info,
+ struct bfd_link_order *link_order,
+ bfd_byte *data,
+ bfd_boolean relocatable,
+ 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;
+ Elf_Internal_Sym *isymbuf = NULL;
+
+ /* We only need to handle the case of relaxing, or of having a
+ particular set of section contents, specially. */
+ if (relocatable
+ || elf_section_data (input_section)->this_hdr.contents == NULL)
+ return bfd_generic_get_relocated_section_contents (output_bfd, link_info,
+ link_order, data,
+ relocatable,
+ symbols);
+
+ symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
+
+ memcpy (data, elf_section_data (input_section)->this_hdr.contents,
+ input_section->size);
+
+ if ((input_section->flags & SEC_RELOC) != 0
+ && input_section->reloc_count > 0)
+ {
+ Elf_Internal_Sym *isymp;
+ Elf_Internal_Sym *isymend;
+ asection **secpp;
+
+ /* Read this BFD's local symbols. */
+ if (symtab_hdr->sh_info != 0)
+ {
+ isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
+ if (isymbuf == NULL)
+ isymbuf = bfd_elf_get_elf_syms (input_bfd, symtab_hdr,
+ symtab_hdr->sh_info, 0,
+ NULL, NULL, NULL);
+ if (isymbuf == NULL)
+ goto error_return;
+ }
+
+ internal_relocs = (_bfd_elf_link_read_relocs
+ (input_bfd, input_section, NULL,
+ (Elf_Internal_Rela *) NULL, FALSE));
+ if (internal_relocs == NULL)
+ goto error_return;
+
+ sections = (asection **) bfd_malloc (symtab_hdr->sh_info
+ * sizeof (asection *));
+ if (sections == NULL && symtab_hdr->sh_info > 0)
+ goto error_return;
+
+ secpp = sections;
+ isymend = isymbuf + symtab_hdr->sh_info;
+ for (isymp = isymbuf; isymp < isymend; ++isymp, ++secpp)
+ {
+ asection *isec;
+
+ if (isymp->st_shndx == SHN_UNDEF)
+ isec = bfd_und_section_ptr;
+ 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
+ isec = bfd_section_from_elf_index (input_bfd, isymp->st_shndx);
+
+ *secpp = isec;
+ }
+
+ if (! sh_elf64_relocate_section (output_bfd, link_info, input_bfd,
+ input_section, data, internal_relocs,
+ isymbuf, sections))
+ goto error_return;
+
+ if (sections != NULL)
+ free (sections);
+ if (internal_relocs != elf_section_data (input_section)->relocs)
+ free (internal_relocs);
+ if (isymbuf != NULL
+ && (unsigned char *) isymbuf != symtab_hdr->contents)
+ free (isymbuf);
+ }
+
+ return data;
+
+ error_return:
+ if (sections != NULL)
+ free (sections);
+ if (internal_relocs != NULL
+ && internal_relocs != elf_section_data (input_section)->relocs)
+ free (internal_relocs);
+ if (isymbuf != NULL
+ && (unsigned char *) isymbuf != symtab_hdr->contents)
+ free (isymbuf);
+ return NULL;
+}
+
+/* Set the SHF_SH5_ISA32 flag for ISA SHmedia code sections. */
+
+static bfd_boolean
+sh64_elf64_fake_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
+ Elf_Internal_Shdr *elf_section_hdr,
+ asection *asect)
+{
+ /* Code sections can only contain SH64 code, so mark them as such. */
+ if (bfd_get_section_flags (output_bfd, asect) & SEC_CODE)
+ elf_section_hdr->sh_flags |= SHF_SH5_ISA32;
+
+ return TRUE;
+}
+
+static bfd_boolean
+sh_elf64_set_mach_from_flags (bfd *abfd)
+{
+ flagword flags = elf_elfheader (abfd)->e_flags;
+
+ switch (flags & EF_SH_MACH_MASK)
+ {
+ case EF_SH5:
+ /* Just one, but keep the switch construct to make additions easy. */
+ bfd_default_set_arch_mach (abfd, bfd_arch_sh, bfd_mach_sh5);
+ break;
+
+ default:
+ bfd_set_error (bfd_error_wrong_format);
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/* Function to keep SH64 specific file flags.
+
+ See sh64_elf_set_private_flags in elf32-sh64.c for the original. */
+
+static bfd_boolean
+sh_elf64_set_private_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 sh_elf64_set_mach_from_flags (abfd);
+}
+
+/* Copy the SHF_SH5_ISA32 attribute that we keep on all sections with
+ code, to keep attributes the same as for SHmedia in 32-bit ELF. */
+
+static bfd_boolean
+sh_elf64_copy_private_data_internal (bfd *ibfd, bfd *obfd)
+{
+ Elf_Internal_Shdr **o_shdrp;
+ asection *isec;
+ asection *osec;
+
+ if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
+ || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
+ return TRUE;
+
+ o_shdrp = elf_elfsections (obfd);
+ for (osec = obfd->sections; osec; osec = osec->next)
+ {
+ int oIndex = ((struct bfd_elf_section_data *) elf_section_data (osec))->this_idx;
+ for (isec = ibfd->sections; isec; isec = isec->next)
+ {
+ if (strcmp (osec->name, isec->name) == 0)
+ {
+ /* Note that we're not disallowing mixing data and code. */
+ if ((elf_section_data (isec)->this_hdr.sh_flags
+ & SHF_SH5_ISA32) != 0)
+ o_shdrp[oIndex]->sh_flags |= SHF_SH5_ISA32;
+ break;
+ }
+ }
+ }
+
+ /* Copy object attributes. */
+ _bfd_elf_copy_private_bfd_data (ibfd, obfd);
+
+ return sh_elf64_set_private_flags (obfd, elf_elfheader (ibfd)->e_flags);
+}
+
+static bfd_boolean
+sh_elf64_copy_private_data (bfd *ibfd, bfd *obfd)
+{
+ return sh_elf64_copy_private_data_internal (ibfd, obfd);
+}
+
+static bfd_boolean
+sh_elf64_merge_private_data (bfd *ibfd, bfd *obfd)
+{
+ flagword old_flags, new_flags;
+
+ if (! _bfd_generic_verify_endian_match (ibfd, obfd))
+ return FALSE;
+
+ if ( bfd_get_flavour (ibfd) != bfd_target_elf_flavour
+ || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
+ return TRUE;
+
+ if (bfd_get_arch_size (ibfd) != bfd_get_arch_size (obfd))
+ {
+ const char *msg;
+
+ if (bfd_get_arch_size (ibfd) == 32
+ && bfd_get_arch_size (obfd) == 64)
+ msg = _("%s: compiled as 32-bit object and %s is 64-bit");
+ else if (bfd_get_arch_size (ibfd) == 64
+ && bfd_get_arch_size (obfd) == 32)
+ msg = _("%s: compiled as 64-bit object and %s is 32-bit");
+ else
+ msg = _("%s: object size does not match that of target %s");
+
+ (*_bfd_error_handler) (msg, bfd_get_filename (ibfd),
+ bfd_get_filename (obfd));
+ bfd_set_error (bfd_error_wrong_format);
+ return FALSE;
+ }
+
+ old_flags = elf_elfheader (obfd)->e_flags;
+ new_flags = elf_elfheader (ibfd)->e_flags;
+ if (! elf_flags_init (obfd))
+ {
+ /* This happens when ld starts out with a 'blank' output file. */
+ elf_flags_init (obfd) = TRUE;
+ elf_elfheader (obfd)->e_flags = old_flags = new_flags;
+ }
+ /* We don't allow linking in anything else than SH64 code, and since
+ this is a 64-bit ELF, we assume the 64-bit ABI is used. Add code
+ here as things change. */
+ else if ((new_flags & EF_SH_MACH_MASK) != EF_SH5)
+ {
+ (*_bfd_error_handler)
+ ("%s: does not use the SH64 64-bit ABI as previous modules do",
+ bfd_get_filename (ibfd));
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+
+ sh_elf64_copy_private_data_internal (ibfd, obfd);
+
+ /* I can't think of anything sane other than old_flags being EF_SH5 and
+ that we need to preserve that. */
+ elf_elfheader (obfd)->e_flags = old_flags;
+
+ return sh_elf64_set_mach_from_flags (obfd);
+}
+
+/* Return the section that should be marked against GC for a given
+ relocation. */
+
+static asection *
+sh_elf64_gc_mark_hook (asection *sec,
+ struct bfd_link_info *info,
+ Elf_Internal_Rela *rel,
+ struct elf_link_hash_entry *h,
+ Elf_Internal_Sym *sym)
+{
+ if (h != NULL)
+ switch (ELF64_R_TYPE (rel->r_info))
+ {
+ case R_SH_GNU_VTINHERIT:
+ case R_SH_GNU_VTENTRY:
+ return NULL;
+ }
+
+ return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
+}
+
+/* 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 bfd_boolean
+sh_elf64_check_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;
+ const Elf_Internal_Rela *rel;
+ const Elf_Internal_Rela *rel_end;
+ bfd *dynobj;
+ bfd_vma *local_got_offsets;
+ asection *sgot;
+ asection *srelgot;
+ asection *sreloc;
+
+ sgot = NULL;
+ srelgot = NULL;
+ sreloc = NULL;
+
+ if (info->relocatable)
+ return TRUE;
+
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+ sym_hashes = elf_sym_hashes (abfd);
+
+ dynobj = elf_hash_table (info)->dynobj;
+ local_got_offsets = elf_local_got_offsets (abfd);
+
+ 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 = 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.type == bfd_link_hash_indirect
+ || h->root.type == bfd_link_hash_warning)
+ h = (struct elf_link_hash_entry *) h->root.u.i.link;
+
+ /* PR15323, ref flags aren't set for references in the same
+ object. */
+ h->root.non_ir_ref = 1;
+ }
+
+ /* Some relocs require a global offset table. */
+ if (dynobj == NULL)
+ {
+ switch (ELF64_R_TYPE (rel->r_info))
+ {
+ case R_SH_GOTPLT_LOW16:
+ case R_SH_GOTPLT_MEDLOW16:
+ case R_SH_GOTPLT_MEDHI16:
+ case R_SH_GOTPLT_HI16:
+ case R_SH_GOTPLT10BY4:
+ case R_SH_GOTPLT10BY8:
+ case R_SH_GOT_LOW16:
+ case R_SH_GOT_MEDLOW16:
+ case R_SH_GOT_MEDHI16:
+ case R_SH_GOT_HI16:
+ case R_SH_GOT10BY4:
+ case R_SH_GOT10BY8:
+ case R_SH_GOTOFF_LOW16:
+ case R_SH_GOTOFF_MEDLOW16:
+ case R_SH_GOTOFF_MEDHI16:
+ case R_SH_GOTOFF_HI16:
+ case R_SH_GOTPC_LOW16:
+ case R_SH_GOTPC_MEDLOW16:
+ case R_SH_GOTPC_MEDHI16:
+ case R_SH_GOTPC_HI16:
+ elf_hash_table (info)->dynobj = dynobj = abfd;
+ if (! _bfd_elf_create_got_section (dynobj, info))
+ return FALSE;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ switch (ELF64_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_elf_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:
+ BFD_ASSERT (h != NULL);
+ if (h != NULL
+ && !bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
+ return FALSE;
+ break;
+
+ force_got:
+ case R_SH_GOT_LOW16:
+ case R_SH_GOT_MEDLOW16:
+ case R_SH_GOT_MEDHI16:
+ case R_SH_GOT_HI16:
+ case R_SH_GOT10BY4:
+ case R_SH_GOT10BY8:
+ /* This symbol requires a global offset table entry. */
+
+ if (sgot == NULL)
+ {
+ sgot = bfd_get_linker_section (dynobj, ".got");
+ BFD_ASSERT (sgot != NULL);
+ }
+
+ if (srelgot == NULL
+ && (h != NULL || info->shared))
+ {
+ srelgot = bfd_get_linker_section (dynobj, ".rela.got");
+ if (srelgot == NULL)
+ {
+ flagword flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS
+ | SEC_IN_MEMORY | SEC_LINKER_CREATED
+ | SEC_READONLY);
+ srelgot = bfd_make_section_anyway_with_flags (dynobj,
+ ".rela.got",
+ flags);
+ if (srelgot == NULL
+ || ! bfd_set_section_alignment (dynobj, srelgot, 2))
+ return FALSE;
+ }
+ }
+
+ if (h != NULL)
+ {
+ if (h->type == STT_DATALABEL)
+ {
+ struct elf_sh64_link_hash_entry *hsh;
+
+ h = (struct elf_link_hash_entry *) h->root.u.i.link;
+ hsh = (struct elf_sh64_link_hash_entry *)h;
+ if (hsh->datalabel_got_offset != (bfd_vma) -1)
+ break;
+
+ hsh->datalabel_got_offset = sgot->size;
+ }
+ else
+ {
+ if (h->got.offset != (bfd_vma) -1)
+ {
+ /* We have already allocated space in the .got. */
+ break;
+ }
+ h->got.offset = sgot->size;
+ }
+
+ /* Make sure this symbol is output as a dynamic symbol. */
+ if (h->dynindx == -1)
+ {
+ if (! bfd_elf_link_record_dynamic_symbol (info, h))
+ return FALSE;
+ }
+
+ srelgot->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);
+ /* Reserve space for both the datalabel and
+ codelabel local GOT offsets. */
+ size *= 2;
+ 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;
+ for (; i < 2 * symtab_hdr->sh_info; i++)
+ local_got_offsets[i] = (bfd_vma) -1;
+ }
+ if ((rel->r_addend & 1) != 0)
+ {
+ if (local_got_offsets[symtab_hdr->sh_info
+ + r_symndx] != (bfd_vma) -1)
+ {
+ /* We have already allocated space in the .got. */
+ break;
+ }
+ local_got_offsets[symtab_hdr->sh_info
+ + r_symndx] = sgot->size;
+ }
+ else
+ {
+ if (local_got_offsets[r_symndx] != (bfd_vma) -1)
+ {
+ /* We have already allocated space in the .got. */
+ break;
+ }
+ local_got_offsets[r_symndx] = sgot->size;
+ }
+
+ if (info->shared)
+ {
+ /* If we are generating a shared object, we need to
+ output a R_SH_RELATIVE reloc so that the dynamic
+ linker can adjust this GOT entry. */
+ srelgot->size += sizeof (Elf64_External_Rela);
+ }
+ }
+
+ sgot->size += 8;
+
+ break;
+
+ case R_SH_GOTPLT_LOW16:
+ case R_SH_GOTPLT_MEDLOW16:
+ case R_SH_GOTPLT_MEDHI16:
+ case R_SH_GOTPLT_HI16:
+ case R_SH_GOTPLT10BY4:
+ case R_SH_GOTPLT10BY8:
+ /* If this is a local symbol, we resolve it directly without
+ creating a procedure linkage table entry. */
+
+ if (h == NULL
+ || ELF_ST_VISIBILITY (h->other) == STV_INTERNAL
+ || ELF_ST_VISIBILITY (h->other) == STV_HIDDEN
+ || ! info->shared
+ || info->symbolic
+ || h->dynindx == -1
+ || h->got.offset != (bfd_vma) -1)
+ goto force_got;
+
+ /* Make sure this symbol is output as a dynamic symbol. */
+ if (h->dynindx == -1)
+ {
+ if (! bfd_elf_link_record_dynamic_symbol (info, h))
+ return FALSE;
+ }
+
+ h->needs_plt = 1;
+
+ break;
+
+ case R_SH_PLT_LOW16:
+ case R_SH_PLT_MEDLOW16:
+ case R_SH_PLT_MEDHI16:
+ case R_SH_PLT_HI16:
+ /* 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;
+
+ if (ELF_ST_VISIBILITY (h->other) == STV_INTERNAL
+ || ELF_ST_VISIBILITY (h->other) == STV_HIDDEN)
+ break;
+
+ h->needs_plt = 1;
+
+ break;
+
+ case R_SH_64:
+ case R_SH_64_PCREL:
+ if (h != NULL)
+ h->non_got_ref = 1;
+
+ /* 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_SH_64_PCREL
+ || (h != NULL
+ && (! info->symbolic
+ || !h->def_regular))))
+ {
+ /* 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)
+ {
+ sreloc = _bfd_elf_make_dynamic_reloc_section
+ (sec, dynobj, 2, abfd, /*rela?*/ TRUE);
+
+ if (sreloc == NULL)
+ return FALSE;
+ }
+
+ sreloc->size += sizeof (Elf64_External_Rela);
+
+ /* 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_sh linker
+ hash table, which means that h is really a pointer to
+ an elf_sh_link_hash_entry. */
+ if (h != NULL && info->symbolic
+ && ELF64_R_TYPE (rel->r_info) == R_SH_64_PCREL)
+ {
+ struct elf_sh64_link_hash_entry *eh;
+ struct elf_sh64_pcrel_relocs_copied *p;
+
+ eh = (struct elf_sh64_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_sh64_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;
+ }
+ }
+
+ return TRUE;
+}
+
+static int
+sh64_elf64_get_symbol_type (Elf_Internal_Sym * elf_sym, int type)
+{
+ if (ELF_ST_TYPE (elf_sym->st_info) == STT_DATALABEL)
+ return STT_DATALABEL;
+
+ return type;
+}
+
+/* FIXME: This is a copy of sh64_elf_add_symbol_hook in elf32-sh64.c.
+ Either file can presumably exist without the other, but do not differ
+ in elf-size-ness. How to share?
+
+ Hook called by the linker routine which adds symbols from an object
+ file. We must make indirect symbols for undefined symbols marked with
+ STT_DATALABEL, so relocations passing them will pick up that attribute
+ and neutralize STO_SH5_ISA32 found on the symbol definition.
+
+ There is a problem, though: We want to fill in the hash-table entry for
+ this symbol and signal to the caller that no further processing is
+ needed. But we don't have the index for this hash-table entry. We
+ rely here on that the current entry is the first hash-entry with NULL,
+ which seems brittle. Also, iterating over the hash-table to find that
+ entry is a linear operation on the number of symbols in this input
+ file, and this function should take constant time, so that's not good
+ too. Only comfort is that DataLabel references should only be found in
+ hand-written assembly code and thus be rare. FIXME: Talk maintainers
+ into adding an option to elf_add_symbol_hook (preferably) for the index
+ or the hash entry, alternatively adding the index to Elf_Internal_Sym
+ (not so good). */
+
+static bfd_boolean
+sh64_elf64_add_symbol_hook (bfd *abfd, struct bfd_link_info *info,
+ Elf_Internal_Sym *sym, const char **namep,
+ flagword *flagsp ATTRIBUTE_UNUSED,
+ asection **secp, bfd_vma *valp)
+{
+ /* We want to do this for relocatable as well as final linking. */
+ if (ELF_ST_TYPE (sym->st_info) == STT_DATALABEL
+ && is_elf_hash_table (info->hash))
+ {
+ struct elf_link_hash_entry *h;
+
+ /* For relocatable links, we register the DataLabel sym in its own
+ right, and tweak the name when it's output. Otherwise, we make
+ an indirect symbol of it. */
+ flagword flags
+ = info->relocatable || info->emitrelocations
+ ? BSF_GLOBAL : BSF_GLOBAL | BSF_INDIRECT;
+
+ char *dl_name
+ = bfd_malloc (strlen (*namep) + sizeof (DATALABEL_SUFFIX));
+ struct elf_link_hash_entry ** sym_hash = elf_sym_hashes (abfd);
+
+ BFD_ASSERT (sym_hash != NULL);
+
+ /* Allocation may fail. */
+ if (dl_name == NULL)
+ return FALSE;
+
+ strcpy (dl_name, *namep);
+ strcat (dl_name, DATALABEL_SUFFIX);
+
+ h = (struct elf_link_hash_entry *)
+ bfd_link_hash_lookup (info->hash, dl_name, FALSE, FALSE, FALSE);
+
+ if (h == NULL)
+ {
+ /* No previous datalabel symbol. Make one. */
+ struct bfd_link_hash_entry *bh = NULL;
+ const struct elf_backend_data *bed = get_elf_backend_data (abfd);
+
+ if (! _bfd_generic_link_add_one_symbol (info, abfd, dl_name,
+ flags, *secp, *valp,
+ *namep, FALSE,
+ bed->collect, &bh))
+ {
+ free (dl_name);
+ return FALSE;
+ }
+
+ h = (struct elf_link_hash_entry *) bh;
+ h->non_elf = 0;
+ h->type = STT_DATALABEL;
+ }
+ else
+ /* If a new symbol was created, it holds the allocated name.
+ Otherwise, we don't need it anymore and should deallocate it. */
+ free (dl_name);
+
+ if (h->type != STT_DATALABEL
+ || ((info->relocatable || info->emitrelocations)
+ && h->root.type != bfd_link_hash_undefined)
+ || (! info->relocatable && !info->emitrelocations
+ && h->root.type != bfd_link_hash_indirect))
+ {
+ /* Make sure we don't get confused on invalid input. */
+ (*_bfd_error_handler)
+ (_("%s: encountered datalabel symbol in input"),
+ bfd_get_filename (abfd));
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+
+ /* Now find the hash-table slot for this entry and fill it in. */
+ while (*sym_hash != NULL)
+ sym_hash++;
+ *sym_hash = h;
+
+ /* Signal to caller to skip this symbol - we've handled it. */
+ *namep = NULL;
+ }
+
+ return TRUE;
+}
+
+/* This hook function is called before the linker writes out a global
+ symbol. For relocatable links, DataLabel symbols will be present in
+ linker output. We cut off the special suffix on those symbols, so the
+ right name appears in the output.
+
+ When linking and emitting relocations, there can appear global symbols
+ that are not referenced by relocs, but rather only implicitly through
+ DataLabel references, a relation that is not visible to the linker.
+ Since no stripping of global symbols in done when doing such linking,
+ we don't need to look up and make sure to emit the main symbol for each
+ DataLabel symbol. */
+
+static int
+sh64_elf64_link_output_symbol_hook (struct bfd_link_info *info,
+ const char *cname,
+ Elf_Internal_Sym *sym,
+ asection *input_sec ATTRIBUTE_UNUSED,
+ struct elf_link_hash_entry *h ATTRIBUTE_UNUSED)
+{
+ char *name = (char *) cname;
+
+ if (info->relocatable || info->emitrelocations)
+ {
+ if (ELF_ST_TYPE (sym->st_info) == STT_DATALABEL)
+ name[strlen (name) - strlen (DATALABEL_SUFFIX)] = 0;
+ }
+
+ return 1;
+}
+
+/* Set bit 0 on the entry address; it always points to SHmedia code. This
+ is mostly for symmetry with the 32-bit format, where code can be
+ SHcompact and we need to make a distinction to make sure execution
+ starts in the right ISA mode. It is also convenient for a loader,
+ which would otherwise have to set this bit when loading a TR register
+ before jumping to the program entry. */
+
+static void
+sh64_elf64_final_write_processing (bfd *abfd,
+ bfd_boolean linker ATTRIBUTE_UNUSED)
+{
+ /* FIXME: Perhaps we shouldn't do this if the entry address was supplied
+ numerically, but we currently lack the infrastructure to recognize
+ that: The entry symbol, and info whether it is numeric or a symbol
+ name is kept private in the linker. */
+ if (elf_elfheader (abfd)->e_type == ET_EXEC)
+ elf_elfheader (abfd)->e_entry |= 1;
+}
+
+/* First entry in an absolute procedure linkage table look like this. */
+
+static const bfd_byte elf_sh64_plt0_entry_be[PLT_ENTRY_SIZE] =
+{
+ 0xcc, 0x00, 0x01, 0x10, /* movi .got.plt >> 48, r17 */
+ 0xc8, 0x00, 0x01, 0x10, /* shori (.got.plt >> 32) & 65535, r17 */
+ 0xc8, 0x00, 0x01, 0x10, /* shori (.got.plt >> 16) & 65535, r17 */
+ 0xc8, 0x00, 0x01, 0x10, /* shori .got.plt & 65535, r17 */
+ 0x8d, 0x10, 0x09, 0x90, /* ld.q r17, 16, r25 */
+ 0x6b, 0xf1, 0x66, 0x00, /* ptabs r25, tr0 */
+ 0x8d, 0x10, 0x05, 0x10, /* ld.q r17, 8, r17 */
+ 0x44, 0x01, 0xff, 0xf0, /* blink tr0, r63 */
+ 0x6f, 0xf0, 0xff, 0xf0, /* nop */
+ 0x6f, 0xf0, 0xff, 0xf0, /* nop */
+ 0x6f, 0xf0, 0xff, 0xf0, /* nop */
+ 0x6f, 0xf0, 0xff, 0xf0, /* nop */
+ 0x6f, 0xf0, 0xff, 0xf0, /* nop */
+ 0x6f, 0xf0, 0xff, 0xf0, /* nop */
+ 0x6f, 0xf0, 0xff, 0xf0, /* nop */
+ 0x6f, 0xf0, 0xff, 0xf0, /* nop */
+};
+
+static const bfd_byte elf_sh64_plt0_entry_le[PLT_ENTRY_SIZE] =
+{
+ 0x10, 0x01, 0x00, 0xcc, /* movi .got.plt >> 16, r17 */
+ 0x10, 0x01, 0x00, 0xc8, /* shori (.got.plt >> 32) & 65535, r17 */
+ 0x10, 0x01, 0x00, 0xc8, /* shori (.got.plt >> 16) & 65535, r17 */
+ 0x10, 0x01, 0x00, 0xc8, /* shori .got.plt & 65535, r17 */
+ 0x90, 0x09, 0x10, 0x8d, /* ld.q r17, 16, r25 */
+ 0x00, 0x66, 0xf1, 0x6b, /* ptabs r25, tr0 */
+ 0x10, 0x05, 0x10, 0x8d, /* ld.q r17, 8, r17 */
+ 0xf0, 0xff, 0x01, 0x44, /* blink tr0, r63 */
+ 0xf0, 0xff, 0xf0, 0x6f, /* nop */
+ 0xf0, 0xff, 0xf0, 0x6f, /* nop */
+ 0xf0, 0xff, 0xf0, 0x6f, /* nop */
+ 0xf0, 0xff, 0xf0, 0x6f, /* nop */
+ 0xf0, 0xff, 0xf0, 0x6f, /* nop */
+ 0xf0, 0xff, 0xf0, 0x6f, /* nop */
+ 0xf0, 0xff, 0xf0, 0x6f, /* nop */
+ 0xf0, 0xff, 0xf0, 0x6f, /* nop */
+};
+
+/* Sebsequent entries in an absolute procedure linkage table look like
+ this. */
+
+static const bfd_byte elf_sh64_plt_entry_be[PLT_ENTRY_SIZE] =
+{
+ 0xcc, 0x00, 0x01, 0x90, /* movi nameN-in-GOT >> 48, r25 */
+ 0xc8, 0x00, 0x01, 0x90, /* shori (nameN-in-GOT >> 32) & 65535, r25 */
+ 0xc8, 0x00, 0x01, 0x90, /* shori (nameN-in-GOT >> 16) & 65535, r25 */
+ 0xc8, 0x00, 0x01, 0x90, /* shori nameN-in-GOT & 65535, r25 */
+ 0x8d, 0x90, 0x01, 0x90, /* ld.q r25, 0, r25 */
+ 0x6b, 0xf1, 0x66, 0x00, /* ptabs r25, tr0 */
+ 0x44, 0x01, 0xff, 0xf0, /* blink tr0, r63 */
+ 0x6f, 0xf0, 0xff, 0xf0, /* nop */
+ 0xcc, 0x00, 0x01, 0x90, /* movi (.+8-.PLT0) >> 16, r25 */
+ 0xc8, 0x00, 0x01, 0x90, /* shori (.+4-.PLT0) & 65535, r25 */
+ 0x6b, 0xf5, 0x66, 0x00, /* ptrel r25, tr0 */
+ 0xcc, 0x00, 0x01, 0x50, /* movi reloc-offset >> 16, r21 */
+ 0xc8, 0x00, 0x01, 0x50, /* shori reloc-offset & 65535, r21 */
+ 0x44, 0x01, 0xff, 0xf0, /* blink tr0, r63 */
+ 0x6f, 0xf0, 0xff, 0xf0, /* nop */
+ 0x6f, 0xf0, 0xff, 0xf0, /* nop */
+};
+
+static const bfd_byte elf_sh64_plt_entry_le[PLT_ENTRY_SIZE] =
+{
+ 0x90, 0x01, 0x00, 0xcc, /* movi nameN-in-GOT >> 16, r25 */
+ 0x90, 0x01, 0x00, 0xc8, /* shori nameN-in-GOT & 65535, r25 */
+ 0x90, 0x01, 0x00, 0xc8, /* shori nameN-in-GOT & 65535, r25 */
+ 0x90, 0x01, 0x00, 0xc8, /* shori nameN-in-GOT & 65535, r25 */
+ 0x90, 0x01, 0x90, 0x8d, /* ld.q r25, 0, r25 */
+ 0x00, 0x66, 0xf1, 0x6b, /* ptabs r25, tr0 */
+ 0xf0, 0xff, 0x01, 0x44, /* blink tr0, r63 */
+ 0xf0, 0xff, 0xf0, 0x6f, /* nop */
+ 0x90, 0x01, 0x00, 0xcc, /* movi (.+8-.PLT0) >> 16, r25 */
+ 0x90, 0x01, 0x00, 0xc8, /* shori (.+4-.PLT0) & 65535, r25 */
+ 0x00, 0x66, 0xf5, 0x6b, /* ptrel r25, tr0 */
+ 0x50, 0x01, 0x00, 0xcc, /* movi reloc-offset >> 16, r21 */
+ 0x50, 0x01, 0x00, 0xc8, /* shori reloc-offset & 65535, r21 */
+ 0xf0, 0xff, 0x01, 0x44, /* blink tr0, r63 */
+ 0xf0, 0xff, 0xf0, 0x6f, /* nop */
+ 0xf0, 0xff, 0xf0, 0x6f, /* nop */
+};
+
+/* Entries in a PIC procedure linkage table look like this. */
+
+static const bfd_byte elf_sh64_pic_plt_entry_be[PLT_ENTRY_SIZE] =
+{
+ 0xcc, 0x00, 0x01, 0x90, /* movi nameN@GOT >> 16, r25 */
+ 0xc8, 0x00, 0x01, 0x90, /* shori nameN@GOT & 65535, r25 */
+ 0x40, 0xc3, 0x65, 0x90, /* ldx.q r12, r25, r25 */
+ 0x6b, 0xf1, 0x66, 0x00, /* ptabs r25, tr0 */
+ 0x44, 0x01, 0xff, 0xf0, /* blink tr0, r63 */
+ 0x6f, 0xf0, 0xff, 0xf0, /* nop */
+ 0x6f, 0xf0, 0xff, 0xf0, /* nop */
+ 0x6f, 0xf0, 0xff, 0xf0, /* nop */
+ 0xce, 0x00, 0x01, 0x10, /* movi -GOT_BIAS, r17 */
+ 0x00, 0xc9, 0x45, 0x10, /* add r12, r17, r17 */
+ 0x8d, 0x10, 0x09, 0x90, /* ld.q r17, 16, r25 */
+ 0x6b, 0xf1, 0x66, 0x00, /* ptabs r25, tr0 */
+ 0x8d, 0x10, 0x05, 0x10, /* ld.q r17, 8, r17 */
+ 0xcc, 0x00, 0x01, 0x50, /* movi reloc-offset >> 16, r21 */
+ 0xc8, 0x00, 0x01, 0x50, /* shori reloc-offset & 65535, r21 */
+ 0x44, 0x01, 0xff, 0xf0, /* blink tr0, r63 */
+};
+
+static const bfd_byte elf_sh64_pic_plt_entry_le[PLT_ENTRY_SIZE] =
+{
+ 0x90, 0x01, 0x00, 0xcc, /* movi nameN@GOT >> 16, r25 */
+ 0x90, 0x01, 0x00, 0xc8, /* shori nameN@GOT & 65535, r25 */
+ 0x90, 0x65, 0xc3, 0x40, /* ldx.q r12, r25, r25 */
+ 0x00, 0x66, 0xf1, 0x6b, /* ptabs r25, tr0 */
+ 0xf0, 0xff, 0x01, 0x44, /* blink tr0, r63 */
+ 0xf0, 0xff, 0xf0, 0x6f, /* nop */
+ 0xf0, 0xff, 0xf0, 0x6f, /* nop */
+ 0xf0, 0xff, 0xf0, 0x6f, /* nop */
+ 0x10, 0x01, 0x00, 0xce, /* movi -GOT_BIAS, r17 */
+ 0x10, 0x45, 0xc9, 0x00, /* add r12, r17, r17 */
+ 0x90, 0x09, 0x10, 0x8d, /* ld.q r17, 16, r25 */
+ 0x00, 0x66, 0xf1, 0x6b, /* ptabs r25, tr0 */
+ 0x10, 0x05, 0x10, 0x8d, /* ld.q r17, 8, r17 */
+ 0x50, 0x01, 0x00, 0xcc, /* movi reloc-offset >> 16, r21 */
+ 0x50, 0x01, 0x00, 0xc8, /* shori reloc-offset & 65535, r21 */
+ 0xf0, 0xff, 0x01, 0x44, /* blink tr0, r63 */
+};
+
+static const bfd_byte *elf_sh64_plt0_entry;
+static const bfd_byte *elf_sh64_plt_entry;
+static const bfd_byte *elf_sh64_pic_plt_entry;
+
+/* Create an entry in an sh ELF linker hash table. */
+
+static struct bfd_hash_entry *
+sh64_elf64_link_hash_newfunc (struct bfd_hash_entry *entry,
+ struct bfd_hash_table *table,
+ const char *string)
+{
+ struct elf_sh64_link_hash_entry *ret =
+ (struct elf_sh64_link_hash_entry *) entry;
+
+ /* Allocate the structure if it has not already been allocated by a
+ subclass. */
+ if (ret == (struct elf_sh64_link_hash_entry *) NULL)
+ ret = ((struct elf_sh64_link_hash_entry *)
+ bfd_hash_allocate (table,
+ sizeof (struct elf_sh64_link_hash_entry)));
+ if (ret == (struct elf_sh64_link_hash_entry *) NULL)
+ return (struct bfd_hash_entry *) ret;
+
+ /* Call the allocation method of the superclass. */
+ ret = ((struct elf_sh64_link_hash_entry *)
+ _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry *) ret,
+ table, string));
+ if (ret != (struct elf_sh64_link_hash_entry *) NULL)
+ {
+ ret->pcrel_relocs_copied = NULL;
+ ret->datalabel_got_offset = (bfd_vma) -1;
+ }
+
+ return (struct bfd_hash_entry *) ret;
+}
+
+/* Create an sh64 ELF linker hash table. */
+
+static struct bfd_link_hash_table *
+sh64_elf64_link_hash_table_create (bfd *abfd)
+{
+ struct elf_link_hash_table *ret;
+
+ ret = (struct elf_link_hash_table *) bfd_zmalloc (sizeof (* ret));
+ if (ret == (struct elf_link_hash_table *) NULL)
+ return NULL;
+
+ if (!_bfd_elf_link_hash_table_init (ret, abfd,
+ sh64_elf64_link_hash_newfunc,
+ sizeof (struct elf_sh64_link_hash_entry),
+ GENERIC_ELF_DATA))
+ {
+ free (ret);
+ return NULL;
+ }
+
+ return &ret->root;
+}
+
+inline static void
+movi_shori_putval (bfd *output_bfd, unsigned long value, bfd_byte *addr)
+{
+ bfd_put_32 (output_bfd,
+ bfd_get_32 (output_bfd, addr)
+ | ((value >> 6) & 0x3fffc00),
+ addr);
+ bfd_put_32 (output_bfd,
+ bfd_get_32 (output_bfd, addr + 4)
+ | ((value << 10) & 0x3fffc00),
+ addr + 4);
+}
+
+inline static void
+movi_3shori_putval (bfd *output_bfd, bfd_vma value, bfd_byte *addr)
+{
+ bfd_put_32 (output_bfd,
+ bfd_get_32 (output_bfd, addr)
+ | ((value >> 38) & 0x3fffc00),
+ addr);
+ bfd_put_32 (output_bfd,
+ bfd_get_32 (output_bfd, addr + 4)
+ | ((value >> 22) & 0x3fffc00),
+ addr + 4);
+ bfd_put_32 (output_bfd,
+ bfd_get_32 (output_bfd, addr + 8)
+ | ((value >> 6) & 0x3fffc00),
+ addr + 8);
+ bfd_put_32 (output_bfd,
+ bfd_get_32 (output_bfd, addr + 12)
+ | ((value << 10) & 0x3fffc00),
+ addr + 12);
+}
+
+/* Create dynamic sections when linking against a dynamic object. */
+
+static bfd_boolean
+sh64_elf64_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
+{
+ flagword flags, pltflags;
+ register asection *s;
+ const struct elf_backend_data *bed = get_elf_backend_data (abfd);
+ int ptralign = 0;
+
+ switch (bed->s->arch_size)
+ {
+ case 32:
+ ptralign = 2;
+ break;
+
+ case 64:
+ ptralign = 3;
+ break;
+
+ default:
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+
+ /* 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_anyway_with_flags (abfd, ".plt", pltflags);
+ if (s == NULL
+ || ! 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;
+ struct bfd_link_hash_entry *bh = NULL;
+
+ if (! (_bfd_generic_link_add_one_symbol
+ (info, abfd, "_PROCEDURE_LINKAGE_TABLE_", BSF_GLOBAL, s,
+ (bfd_vma) 0, (const char *) NULL, FALSE, bed->collect, &bh)))
+ return FALSE;
+
+ h = (struct elf_link_hash_entry *) bh;
+ h->def_regular = 1;
+ h->type = STT_OBJECT;
+ elf_hash_table (info)->hplt = h;
+
+ if (info->shared
+ && ! bfd_elf_link_record_dynamic_symbol (info, h))
+ return FALSE;
+ }
+
+ s = bfd_make_section_anyway_with_flags (abfd,
+ bed->default_use_rela_p
+ ? ".rela.plt" : ".rel.plt",
+ flags | SEC_READONLY);
+ if (s == NULL
+ || ! bfd_set_section_alignment (abfd, s, ptralign))
+ return FALSE;
+
+ if (! _bfd_elf_create_got_section (abfd, info))
+ return FALSE;
+
+ if (bed->want_dynbss)
+ {
+ /* 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_anyway_with_flags (abfd, ".dynbss",
+ SEC_ALLOC | SEC_LINKER_CREATED);
+ if (s == NULL)
+ 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_anyway_with_flags (abfd,
+ (bed->default_use_rela_p
+ ? ".rela.bss" : ".rel.bss"),
+ flags | SEC_READONLY);
+ if (s == NULL
+ || ! bfd_set_section_alignment (abfd, s, ptralign))
+ 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 bfd_boolean
+sh64_elf64_adjust_dynamic_symbol (struct bfd_link_info *info,
+ struct elf_link_hash_entry *h)
+{
+ bfd *dynobj;
+ asection *s;
+
+ dynobj = elf_hash_table (info)->dynobj;
+
+ /* Make sure we know what is going on here. */
+ BFD_ASSERT (dynobj != NULL
+ && (h->needs_plt
+ || h->u.weakdef != NULL
+ || (h->def_dynamic
+ && h->ref_regular
+ && !h->def_regular)));
+
+ /* 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->needs_plt)
+ {
+ if (! info->shared
+ && !h->def_dynamic
+ && !h->ref_dynamic)
+ {
+ /* This case can occur if we saw a PLT 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 REL64
+ reloc instead. */
+ BFD_ASSERT (h->needs_plt);
+ return TRUE;
+ }
+
+ /* Make sure this symbol is output as a dynamic symbol. */
+ if (h->dynindx == -1)
+ {
+ if (! bfd_elf_link_record_dynamic_symbol (info, h))
+ return FALSE;
+ }
+
+ s = bfd_get_linker_section (dynobj, ".plt");
+ BFD_ASSERT (s != NULL);
+
+ /* If this is the first .plt entry, make room for the special
+ first entry. */
+ if (s->size == 0)
+ s->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->def_regular)
+ {
+ h->root.u.def.section = s;
+ h->root.u.def.value = s->size;
+ }
+
+ h->plt.offset = s->size;
+
+ /* Make room for this entry. */
+ s->size += elf_sh64_sizeof_plt (info);
+
+ /* 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_linker_section (dynobj, ".got.plt");
+ BFD_ASSERT (s != NULL);
+ s->size += 8;
+
+ /* We also need to make an entry in the .rela.plt section. */
+
+ s = bfd_get_linker_section (dynobj, ".rela.plt");
+ BFD_ASSERT (s != NULL);
+ s->size += sizeof (Elf64_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->u.weakdef != NULL)
+ {
+ BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
+ || h->u.weakdef->root.type == bfd_link_hash_defweak);
+ h->root.u.def.section = h->u.weakdef->root.u.def.section;
+ h->root.u.def.value = h->u.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;
+
+ /* If there are no references to this symbol that do not use the
+ GOT, we don't need to generate a copy reloc. */
+ if (!h->non_got_ref)
+ 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_linker_section (dynobj, ".dynbss");
+ BFD_ASSERT (s != NULL);
+
+ /* We must generate a R_SH_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 && h->size != 0)
+ {
+ asection *srel;
+
+ srel = bfd_get_linker_section (dynobj, ".rela.bss");
+ BFD_ASSERT (srel != NULL);
+ srel->size += sizeof (Elf64_External_Rela);
+ h->needs_copy = 1;
+ }
+
+ return _bfd_elf_adjust_dynamic_copy (h, s);
+}
+
+/* This function is called via sh_elf_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 bfd_boolean
+sh64_elf64_discard_copies (struct elf_sh64_link_hash_entry *h,
+ void *ignore ATTRIBUTE_UNUSED)
+{
+ struct elf_sh64_pcrel_relocs_copied *s;
+
+ /* We only discard relocs for symbols defined in a regular object. */
+ if (!h->root.def_regular)
+ return TRUE;
+
+ for (s = h->pcrel_relocs_copied; s != NULL; s = s->next)
+ s->section->size -= s->count * sizeof (Elf64_External_Rela);
+
+ return TRUE;
+}
+
+/* Set the sizes of the dynamic sections. */
+
+static bfd_boolean
+sh64_elf64_size_dynamic_sections (bfd *output_bfd,
+ struct bfd_link_info *info)
+{
+ bfd *dynobj;
+ asection *s;
+ bfd_boolean plt;
+ bfd_boolean relocs;
+ bfd_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->executable)
+ {
+ s = bfd_get_linker_section (dynobj, ".interp");
+ BFD_ASSERT (s != NULL);
+ s->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_linker_section (dynobj, ".rela.got");
+ if (s != NULL)
+ s->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)
+ sh64_elf64_link_hash_traverse (elf_hash_table (info),
+ sh64_elf64_discard_copies, 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;
+
+ 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);
+
+ if (strcmp (name, ".plt") == 0)
+ {
+ /* Remember whether there is a PLT. */
+ plt = s->size != 0;
+ }
+ else if (CONST_STRNEQ (name, ".rela"))
+ {
+ if (s->size != 0)
+ {
+ 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. The entries in the .rela.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 + 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 (! CONST_STRNEQ (name, ".got")
+ && strcmp (name, ".dynbss") != 0)
+ {
+ /* It's not one of our sections, so don't allocate space. */
+ continue;
+ }
+
+ if (s->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. */
+ s->flags |= SEC_EXCLUDE;
+ continue;
+ }
+
+ if ((s->flags & SEC_HAS_CONTENTS) == 0)
+ continue;
+
+ /* Allocate memory for the section contents. */
+ s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->size);
+ if (s->contents == NULL)
+ return FALSE;
+ }
+
+ if (elf_hash_table (info)->dynamic_sections_created)
+ {
+ /* Add some entries to the .dynamic section. We fill in the
+ values later, in sh64_elf64_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->executable)
+ {
+ if (!_bfd_elf_add_dynamic_entry (info, DT_DEBUG, 0))
+ return FALSE;
+ }
+
+ if (plt)
+ {
+ if (!_bfd_elf_add_dynamic_entry (info, DT_PLTGOT, 0)
+ || !_bfd_elf_add_dynamic_entry (info, DT_PLTRELSZ, 0)
+ || !_bfd_elf_add_dynamic_entry (info, DT_PLTREL, DT_RELA)
+ || !_bfd_elf_add_dynamic_entry (info, DT_JMPREL, 0))
+ return FALSE;
+ }
+
+ if (relocs)
+ {
+ if (!_bfd_elf_add_dynamic_entry (info, DT_RELA, 0)
+ || !_bfd_elf_add_dynamic_entry (info, DT_RELASZ, 0)
+ || !_bfd_elf_add_dynamic_entry (info, DT_RELAENT,
+ sizeof (Elf64_External_Rela)))
+ return FALSE;
+ }
+
+ if (reltext)
+ {
+ if (!_bfd_elf_add_dynamic_entry (info, DT_TEXTREL, 0))
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+/* Finish up dynamic symbol handling. We set the contents of various
+ dynamic sections here. */
+
+static bfd_boolean
+sh64_elf64_finish_dynamic_symbol (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_Rela rel;
+ bfd_byte *loc;
+
+ /* This symbol has an entry in the procedure linkage table. Set
+ it up. */
+
+ BFD_ASSERT (h->dynindx != -1);
+
+ splt = bfd_get_linker_section (dynobj, ".plt");
+ sgot = bfd_get_linker_section (dynobj, ".got.plt");
+ srel = bfd_get_linker_section (dynobj, ".rela.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 / elf_sh64_sizeof_plt (info) - 1;
+
+ /* Get the offset into the .got table of the entry that
+ corresponds to this function. Each .got entry is 8 bytes.
+ The first three are reserved. */
+ got_offset = (plt_index + 3) * 8;
+
+ if (info->shared)
+ got_offset -= GOT_BIAS;
+
+ /* Fill in the entry in the procedure linkage table. */
+ if (! info->shared)
+ {
+ if (elf_sh64_plt_entry == NULL)
+ {
+ elf_sh64_plt_entry = (bfd_big_endian (output_bfd) ?
+ elf_sh64_plt_entry_be : elf_sh64_plt_entry_le);
+ }
+ memcpy (splt->contents + h->plt.offset, elf_sh64_plt_entry,
+ elf_sh64_sizeof_plt (info));
+ movi_3shori_putval (output_bfd,
+ (sgot->output_section->vma
+ + sgot->output_offset
+ + got_offset),
+ (splt->contents + h->plt.offset
+ + elf_sh64_plt_symbol_offset (info)));
+
+ /* Set bottom bit because its for a branch to SHmedia */
+ movi_shori_putval (output_bfd,
+ -(h->plt.offset
+ + elf_sh64_plt_plt0_offset (info) + 8)
+ | 1,
+ (splt->contents + h->plt.offset
+ + elf_sh64_plt_plt0_offset (info)));
+ }
+ else
+ {
+ if (elf_sh64_pic_plt_entry == NULL)
+ {
+ elf_sh64_pic_plt_entry = (bfd_big_endian (output_bfd) ?
+ elf_sh64_pic_plt_entry_be :
+ elf_sh64_pic_plt_entry_le);
+ }
+ memcpy (splt->contents + h->plt.offset, elf_sh64_pic_plt_entry,
+ elf_sh64_sizeof_plt (info));
+ movi_shori_putval (output_bfd, got_offset,
+ (splt->contents + h->plt.offset
+ + elf_sh64_plt_symbol_offset (info)));
+ }
+
+ if (info->shared)
+ got_offset += GOT_BIAS;
+
+ movi_shori_putval (output_bfd,
+ plt_index * sizeof (Elf64_External_Rela),
+ (splt->contents + h->plt.offset
+ + elf_sh64_plt_reloc_offset (info)));
+
+ /* Fill in the entry in the global offset table. */
+ bfd_put_64 (output_bfd,
+ (splt->output_section->vma
+ + splt->output_offset
+ + h->plt.offset
+ + elf_sh64_plt_temp_offset (info)),
+ sgot->contents + got_offset);
+
+ /* Fill in the entry in the .rela.plt section. */
+ rel.r_offset = (sgot->output_section->vma
+ + sgot->output_offset
+ + got_offset);
+ rel.r_info = ELF64_R_INFO (h->dynindx, R_SH_JMP_SLOT64);
+ rel.r_addend = 0;
+ rel.r_addend = GOT_BIAS;
+ loc = srel->contents + plt_index * sizeof (Elf64_External_Rela);
+ bfd_elf64_swap_reloca_out (output_bfd, &rel, loc);
+
+ if (!h->def_regular)
+ {
+ /* 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_Rela rel;
+ bfd_byte *loc;
+
+ /* This symbol has an entry in the global offset table. Set it
+ up. */
+
+ sgot = bfd_get_linker_section (dynobj, ".got");
+ srel = bfd_get_linker_section (dynobj, ".rela.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->def_regular)
+ {
+ rel.r_info = ELF64_R_INFO (0, R_SH_RELATIVE64);
+ rel.r_addend = (h->root.u.def.value
+ + h->root.u.def.section->output_section->vma
+ + h->root.u.def.section->output_offset);
+ }
+ else
+ {
+ bfd_put_64 (output_bfd, (bfd_vma) 0, sgot->contents + h->got.offset);
+ rel.r_info = ELF64_R_INFO (h->dynindx, R_SH_GLOB_DAT64);
+ rel.r_addend = 0;
+ }
+
+ loc = srel->contents;
+ loc += srel->reloc_count++ * sizeof (Elf64_External_Rela);
+ bfd_elf64_swap_reloca_out (output_bfd, &rel, loc);
+ }
+
+ if (h->needs_copy)
+ {
+ asection *s;
+ Elf_Internal_Rela rel;
+ bfd_byte *loc;
+
+ /* 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_linker_section (dynobj, ".rela.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 = ELF64_R_INFO (h->dynindx, R_SH_COPY64);
+ rel.r_addend = 0;
+ loc = s->contents;
+ loc += s->reloc_count++ * sizeof (Elf64_External_Rela);
+ bfd_elf64_swap_reloca_out (output_bfd, &rel, loc);
+ }
+
+ /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute. */
+ if (h == elf_hash_table (info)->hdynamic
+ || h == elf_hash_table (info)->hgot)
+ sym->st_shndx = SHN_ABS;
+
+ return TRUE;
+}
+
+/* Finish up the dynamic sections. */
+
+static bfd_boolean
+sh64_elf64_finish_dynamic_sections (bfd *output_bfd,
+ struct bfd_link_info *info)
+{
+ bfd *dynobj;
+ asection *sgot;
+ asection *sdyn;
+
+ dynobj = elf_hash_table (info)->dynobj;
+
+ sgot = bfd_get_linker_section (dynobj, ".got.plt");
+ BFD_ASSERT (sgot != NULL);
+ sdyn = bfd_get_linker_section (dynobj, ".dynamic");
+
+ if (elf_hash_table (info)->dynamic_sections_created)
+ {
+ asection *splt;
+ Elf64_External_Dyn *dyncon, *dynconend;
+
+ BFD_ASSERT (sdyn != NULL);
+
+ dyncon = (Elf64_External_Dyn *) sdyn->contents;
+ dynconend = (Elf64_External_Dyn *) (sdyn->contents + sdyn->size);
+ for (; dyncon < dynconend; dyncon++)
+ {
+ Elf_Internal_Dyn dyn;
+ const char *name;
+ asection *s;
+ struct elf_link_hash_entry *h;
+
+ bfd_elf64_swap_dyn_in (dynobj, dyncon, &dyn);
+
+ switch (dyn.d_tag)
+ {
+ default:
+ break;
+
+ case DT_INIT:
+ name = info->init_function;
+ goto get_sym;
+
+ case DT_FINI:
+ name = info->fini_function;
+ get_sym:
+ if (dyn.d_un.d_val != 0)
+ {
+ h = elf_link_hash_lookup (elf_hash_table (info), name,
+ FALSE, FALSE, TRUE);
+ if (h != NULL && (h->other & STO_SH5_ISA32))
+ {
+ dyn.d_un.d_val |= 1;
+ bfd_elf64_swap_dyn_out (output_bfd, &dyn, dyncon);
+ }
+ }
+ 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_elf64_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);
+ dyn.d_un.d_val = s->size;
+ bfd_elf64_swap_dyn_out (output_bfd, &dyn, dyncon);
+ break;
+
+ case DT_RELASZ:
+ /* My reading of the SVR4 ABI indicates that the
+ procedure linkage table relocs (DT_JMPREL) should be
+ included in the overall relocs (DT_RELA). This is
+ what Solaris does. However, UnixWare can not handle
+ that case. 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)
+ dyn.d_un.d_val -= s->size;
+ bfd_elf64_swap_dyn_out (output_bfd, &dyn, dyncon);
+ break;
+ }
+ }
+
+ /* Fill in the first entry in the procedure linkage table. */
+ splt = bfd_get_linker_section (dynobj, ".plt");
+ if (splt && splt->size > 0)
+ {
+ if (info->shared)
+ {
+ if (elf_sh64_pic_plt_entry == NULL)
+ {
+ elf_sh64_pic_plt_entry = (bfd_big_endian (output_bfd) ?
+ elf_sh64_pic_plt_entry_be :
+ elf_sh64_pic_plt_entry_le);
+ }
+ memcpy (splt->contents, elf_sh64_pic_plt_entry,
+ elf_sh64_sizeof_plt (info));
+ }
+ else
+ {
+ if (elf_sh64_plt0_entry == NULL)
+ {
+ elf_sh64_plt0_entry = (bfd_big_endian (output_bfd) ?
+ elf_sh64_plt0_entry_be :
+ elf_sh64_plt0_entry_le);
+ }
+ memcpy (splt->contents, elf_sh64_plt0_entry, PLT_ENTRY_SIZE);
+ movi_3shori_putval (output_bfd,
+ sgot->output_section->vma
+ + sgot->output_offset,
+ splt->contents
+ + elf_sh64_plt0_gotplt_offset (info));
+ }
+
+ /* UnixWare sets the entsize of .plt to 8, although that doesn't
+ really seem like the right value. */
+ elf_section_data (splt->output_section)->this_hdr.sh_entsize = 8;
+ }
+ }
+
+ /* Fill in the first three entries in the global offset table. */
+ if (sgot->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);
+ bfd_put_64 (output_bfd, (bfd_vma) 0, sgot->contents + 8);
+ bfd_put_64 (output_bfd, (bfd_vma) 0, sgot->contents + 16);
+ }
+
+ elf_section_data (sgot->output_section)->this_hdr.sh_entsize = 8;
+
+ return TRUE;
+}
+
+/* Merge non visibility st_other attribute when the symbol comes from
+ a dynamic object. */
+static void
+sh64_elf64_merge_symbol_attribute (struct elf_link_hash_entry *h,
+ const Elf_Internal_Sym *isym,
+ bfd_boolean definition,
+ bfd_boolean dynamic ATTRIBUTE_UNUSED)
+{
+ if ((isym->st_other & ~ELF_ST_VISIBILITY (-1)) != 0)
+ {
+ unsigned char other;
+
+ /* Take the balance of OTHER from the definition. */
+ other = (definition ? isym->st_other : h->other);
+ other &= ~ ELF_ST_VISIBILITY (-1);
+ h->other = other | ELF_ST_VISIBILITY (h->other);
+ }
+
+ return;
+}
+
+static const struct bfd_elf_special_section sh64_elf64_special_sections[]=
+{
+ { STRING_COMMA_LEN (".cranges"), 0, SHT_PROGBITS, 0 },
+ { NULL, 0, 0, 0, 0 }
+};
+
+#define TARGET_BIG_SYM sh64_elf64_vec
+#define TARGET_BIG_NAME "elf64-sh64"
+#define TARGET_LITTLE_SYM sh64_elf64_le_vec
+#define TARGET_LITTLE_NAME "elf64-sh64l"
+#define ELF_ARCH bfd_arch_sh
+#define ELF_MACHINE_CODE EM_SH
+#define ELF_MAXPAGESIZE 128
+
+#define elf_symbol_leading_char '_'
+
+#define bfd_elf64_bfd_reloc_type_lookup sh_elf64_reloc_type_lookup
+#define bfd_elf64_bfd_reloc_name_lookup \
+ sh_elf64_reloc_name_lookup
+#define elf_info_to_howto sh_elf64_info_to_howto
+
+/* Note: there's no relaxation at present. */
+
+#define elf_backend_relocate_section sh_elf64_relocate_section
+#define bfd_elf64_bfd_get_relocated_section_contents \
+ sh_elf64_get_relocated_section_contents
+#define elf_backend_object_p sh_elf64_set_mach_from_flags
+#define bfd_elf64_bfd_set_private_flags \
+ sh_elf64_set_private_flags
+#define bfd_elf64_bfd_copy_private_bfd_data \
+ sh_elf64_copy_private_data
+#define bfd_elf64_bfd_merge_private_bfd_data \
+ sh_elf64_merge_private_data
+#define elf_backend_fake_sections sh64_elf64_fake_sections
+
+#define elf_backend_gc_mark_hook sh_elf64_gc_mark_hook
+#define elf_backend_check_relocs sh_elf64_check_relocs
+
+#define elf_backend_can_gc_sections 1
+
+#define elf_backend_get_symbol_type sh64_elf64_get_symbol_type
+
+#define elf_backend_add_symbol_hook sh64_elf64_add_symbol_hook
+
+#define elf_backend_link_output_symbol_hook \
+ sh64_elf64_link_output_symbol_hook
+
+#define elf_backend_merge_symbol_attribute \
+ sh64_elf64_merge_symbol_attribute
+
+#define elf_backend_final_write_processing \
+ sh64_elf64_final_write_processing
+
+#define elf_backend_create_dynamic_sections \
+ sh64_elf64_create_dynamic_sections
+#define bfd_elf64_bfd_link_hash_table_create \
+ sh64_elf64_link_hash_table_create
+#define elf_backend_adjust_dynamic_symbol \
+ sh64_elf64_adjust_dynamic_symbol
+#define elf_backend_size_dynamic_sections \
+ sh64_elf64_size_dynamic_sections
+#define elf_backend_omit_section_dynsym \
+ ((bfd_boolean (*) (bfd *, struct bfd_link_info *, asection *)) bfd_true)
+#define elf_backend_finish_dynamic_symbol \
+ sh64_elf64_finish_dynamic_symbol
+#define elf_backend_finish_dynamic_sections \
+ sh64_elf64_finish_dynamic_sections
+#define elf_backend_special_sections sh64_elf64_special_sections
+
+#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 24
+
+#include "elf64-target.h"
+
+/* NetBSD support. */
+#undef TARGET_BIG_SYM
+#define TARGET_BIG_SYM sh64_elf64_nbsd_vec
+#undef TARGET_BIG_NAME
+#define TARGET_BIG_NAME "elf64-sh64-nbsd"
+#undef TARGET_LITTLE_SYM
+#define TARGET_LITTLE_SYM sh64_elf64_nbsd_le_vec
+#undef TARGET_LITTLE_NAME
+#define TARGET_LITTLE_NAME "elf64-sh64l-nbsd"
+#undef ELF_MAXPAGESIZE
+#define ELF_MAXPAGESIZE 0x10000
+#undef elf_symbol_leading_char
+#define elf_symbol_leading_char 0
+
+#define elf64_bed elf64_sh64_nbsd_bed
+
+#include "elf64-target.h"
+
+/* Linux support. */
+#undef TARGET_BIG_SYM
+#define TARGET_BIG_SYM sh64_elf64_linux_be_vec
+#undef TARGET_BIG_NAME
+#define TARGET_BIG_NAME "elf64-sh64big-linux"
+#undef TARGET_LITTLE_SYM
+#define TARGET_LITTLE_SYM sh64_elf64_linux_vec
+#undef TARGET_LITTLE_NAME
+#define TARGET_LITTLE_NAME "elf64-sh64-linux"
+#undef elf64_bed
+#define elf64_bed elf64_sh64_linux_bed
+
+#include "elf64-target.h"
diff --git a/bfd/elf64-sparc.c b/bfd/elf64-sparc.c
new file mode 100644
index 0000000..eeb94a9
--- /dev/null
+++ b/bfd/elf64-sparc.c
@@ -0,0 +1,956 @@
+/* SPARC-specific support for 64-bit ELF
+ Copyright (C) 1993-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+#include "elf-bfd.h"
+#include "elf/sparc.h"
+#include "opcode/sparc.h"
+#include "elfxx-sparc.h"
+
+/* In case we're on a 32-bit machine, construct a 64-bit "-1" value. */
+#define MINUS_ONE (~ (bfd_vma) 0)
+
+/* Due to the way how we handle R_SPARC_OLO10, each entry in a SHT_RELA
+ section can represent up to two relocs, we must tell the user to allocate
+ more space. */
+
+static long
+elf64_sparc_get_reloc_upper_bound (bfd *abfd ATTRIBUTE_UNUSED, asection *sec)
+{
+ return (sec->reloc_count * 2 + 1) * sizeof (arelent *);
+}
+
+static long
+elf64_sparc_get_dynamic_reloc_upper_bound (bfd *abfd)
+{
+ return _bfd_elf_get_dynamic_reloc_upper_bound (abfd) * 2;
+}
+
+/* Read relocations for ASECT from REL_HDR. There are RELOC_COUNT of
+ them. We cannot use generic elf routines for this, because R_SPARC_OLO10
+ has secondary addend in ELF64_R_TYPE_DATA. We handle it as two relocations
+ for the same location, R_SPARC_LO10 and R_SPARC_13. */
+
+static bfd_boolean
+elf64_sparc_slurp_one_reloc_table (bfd *abfd, asection *asect,
+ Elf_Internal_Shdr *rel_hdr,
+ asymbol **symbols, bfd_boolean dynamic)
+{
+ void * allocated = NULL;
+ bfd_byte *native_relocs;
+ arelent *relent;
+ unsigned int i;
+ int entsize;
+ bfd_size_type count;
+ arelent *relents;
+
+ allocated = bfd_malloc (rel_hdr->sh_size);
+ if (allocated == NULL)
+ goto error_return;
+
+ if (bfd_seek (abfd, rel_hdr->sh_offset, SEEK_SET) != 0
+ || bfd_bread (allocated, rel_hdr->sh_size, abfd) != rel_hdr->sh_size)
+ goto error_return;
+
+ native_relocs = (bfd_byte *) allocated;
+
+ relents = asect->relocation + canon_reloc_count (asect);
+
+ entsize = rel_hdr->sh_entsize;
+ BFD_ASSERT (entsize == sizeof (Elf64_External_Rela));
+
+ count = rel_hdr->sh_size / entsize;
+
+ for (i = 0, relent = relents; i < count;
+ i++, relent++, native_relocs += entsize)
+ {
+ Elf_Internal_Rela rela;
+ unsigned int r_type;
+
+ bfd_elf64_swap_reloca_in (abfd, native_relocs, &rela);
+
+ /* 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 (ELF64_R_SYM (rela.r_info) == STN_UNDEF)
+ relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
+ else
+ {
+ asymbol **ps, *s;
+
+ ps = symbols + ELF64_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;
+
+ r_type = ELF64_R_TYPE_ID (rela.r_info);
+ if (r_type == R_SPARC_OLO10)
+ {
+ relent->howto = _bfd_sparc_elf_info_to_howto_ptr (R_SPARC_LO10);
+ relent[1].address = relent->address;
+ relent++;
+ relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
+ relent->addend = ELF64_R_TYPE_DATA (rela.r_info);
+ relent->howto = _bfd_sparc_elf_info_to_howto_ptr (R_SPARC_13);
+ }
+ else
+ relent->howto = _bfd_sparc_elf_info_to_howto_ptr (r_type);
+ }
+
+ canon_reloc_count (asect) += relent - relents;
+
+ if (allocated != NULL)
+ free (allocated);
+
+ return TRUE;
+
+ error_return:
+ if (allocated != NULL)
+ free (allocated);
+ return FALSE;
+}
+
+/* Read in and swap the external relocs. */
+
+static bfd_boolean
+elf64_sparc_slurp_reloc_table (bfd *abfd, asection *asect,
+ asymbol **symbols, bfd_boolean dynamic)
+{
+ struct bfd_elf_section_data * const d = elf_section_data (asect);
+ Elf_Internal_Shdr *rel_hdr;
+ Elf_Internal_Shdr *rel_hdr2;
+ bfd_size_type amt;
+
+ 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;
+ rel_hdr2 = d->rela.hdr;
+
+ BFD_ASSERT ((rel_hdr && asect->rel_filepos == rel_hdr->sh_offset)
+ || (rel_hdr2 && asect->rel_filepos == rel_hdr2->sh_offset));
+ }
+ else
+ {
+ /* Note that ASECT->RELOC_COUNT tends not to be accurate in this
+ case because relocations against this section may use the
+ dynamic symbol table, and in that case bfd_section_from_shdr
+ in elf.c does not update the RELOC_COUNT. */
+ if (asect->size == 0)
+ return TRUE;
+
+ rel_hdr = &d->this_hdr;
+ asect->reloc_count = NUM_SHDR_ENTRIES (rel_hdr);
+ rel_hdr2 = NULL;
+ }
+
+ amt = asect->reloc_count;
+ amt *= 2 * sizeof (arelent);
+ asect->relocation = (arelent *) bfd_alloc (abfd, amt);
+ if (asect->relocation == NULL)
+ return FALSE;
+
+ /* The elf64_sparc_slurp_one_reloc_table routine increments
+ canon_reloc_count. */
+ canon_reloc_count (asect) = 0;
+
+ if (rel_hdr
+ && !elf64_sparc_slurp_one_reloc_table (abfd, asect, rel_hdr, symbols,
+ dynamic))
+ return FALSE;
+
+ if (rel_hdr2
+ && !elf64_sparc_slurp_one_reloc_table (abfd, asect, rel_hdr2, symbols,
+ dynamic))
+ return FALSE;
+
+ return TRUE;
+}
+
+/* Canonicalize the relocs. */
+
+static long
+elf64_sparc_canonicalize_reloc (bfd *abfd, sec_ptr section,
+ arelent **relptr, asymbol **symbols)
+{
+ arelent *tblptr;
+ unsigned int i;
+ const struct elf_backend_data *bed = get_elf_backend_data (abfd);
+
+ if (! bed->s->slurp_reloc_table (abfd, section, symbols, FALSE))
+ return -1;
+
+ tblptr = section->relocation;
+ for (i = 0; i < canon_reloc_count (section); i++)
+ *relptr++ = tblptr++;
+
+ *relptr = NULL;
+
+ return canon_reloc_count (section);
+}
+
+
+/* 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. */
+
+static long
+elf64_sparc_canonicalize_dynamic_reloc (bfd *abfd, arelent **storage,
+ asymbol **syms)
+{
+ asection *s;
+ long ret;
+
+ if (elf_dynsymtab (abfd) == 0)
+ {
+ bfd_set_error (bfd_error_invalid_operation);
+ return -1;
+ }
+
+ 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_RELA))
+ {
+ arelent *p;
+ long count, i;
+
+ if (! elf64_sparc_slurp_reloc_table (abfd, s, syms, TRUE))
+ return -1;
+ count = canon_reloc_count (s);
+ p = s->relocation;
+ for (i = 0; i < count; i++)
+ *storage++ = p++;
+ ret += count;
+ }
+ }
+
+ *storage = NULL;
+
+ return ret;
+}
+
+/* Write out the relocs. */
+
+static void
+elf64_sparc_write_relocs (bfd *abfd, asection *sec, void * data)
+{
+ bfd_boolean *failedp = (bfd_boolean *) data;
+ Elf_Internal_Shdr *rela_hdr;
+ bfd_vma addr_offset;
+ Elf64_External_Rela *outbound_relocas, *src_rela;
+ unsigned int idx, count;
+ 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 two relocs that refer to the same address
+ into R_SPARC_OLO10 if first one is R_SPARC_LO10 and the
+ latter is R_SPARC_13 with no associated symbol. */
+ count = 0;
+ for (idx = 0; idx < sec->reloc_count; idx++)
+ {
+ bfd_vma addr;
+
+ ++count;
+
+ addr = sec->orelocation[idx]->address;
+ if (sec->orelocation[idx]->howto->type == R_SPARC_LO10
+ && idx < sec->reloc_count - 1)
+ {
+ arelent *r = sec->orelocation[idx + 1];
+
+ if (r->howto->type == R_SPARC_13
+ && r->address == addr
+ && bfd_is_abs_section ((*r->sym_ptr_ptr)->section)
+ && (*r->sym_ptr_ptr)->value == 0)
+ ++idx;
+ }
+ }
+
+ rela_hdr = elf_section_data (sec)->rela.hdr;
+
+ rela_hdr->sh_size = rela_hdr->sh_entsize * count;
+ rela_hdr->contents = bfd_alloc (abfd, rela_hdr->sh_size);
+ if (rela_hdr->contents == NULL)
+ {
+ *failedp = TRUE;
+ return;
+ }
+
+ /* Figure out whether the relocations are RELA or REL relocations. */
+ if (rela_hdr->sh_type != SHT_RELA)
+ abort ();
+
+ /* 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. */
+ addr_offset = 0;
+ if ((abfd->flags & (EXEC_P | DYNAMIC)) != 0)
+ addr_offset = sec->vma;
+
+ /* orelocation has the data, reloc_count has the count... */
+ outbound_relocas = (Elf64_External_Rela *) rela_hdr->contents;
+ src_rela = outbound_relocas;
+
+ for (idx = 0; idx < sec->reloc_count; idx++)
+ {
+ Elf_Internal_Rela dst_rela;
+ arelent *ptr;
+ asymbol *sym;
+ int n;
+
+ ptr = sec->orelocation[idx];
+ 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;
+ }
+
+ if (ptr->howto->type == R_SPARC_LO10
+ && idx < sec->reloc_count - 1)
+ {
+ arelent *r = sec->orelocation[idx + 1];
+
+ if (r->howto->type == R_SPARC_13
+ && r->address == ptr->address
+ && bfd_is_abs_section ((*r->sym_ptr_ptr)->section)
+ && (*r->sym_ptr_ptr)->value == 0)
+ {
+ idx++;
+ dst_rela.r_info
+ = ELF64_R_INFO (n, ELF64_R_TYPE_INFO (r->addend,
+ R_SPARC_OLO10));
+ }
+ else
+ dst_rela.r_info = ELF64_R_INFO (n, R_SPARC_LO10);
+ }
+ else
+ dst_rela.r_info = ELF64_R_INFO (n, ptr->howto->type);
+
+ dst_rela.r_offset = ptr->address + addr_offset;
+ dst_rela.r_addend = ptr->addend;
+
+ bfd_elf64_swap_reloca_out (abfd, &dst_rela, (bfd_byte *) src_rela);
+ ++src_rela;
+ }
+}
+
+/* Hook called by the linker routine which adds symbols from an object
+ file. We use it for STT_REGISTER symbols. */
+
+static bfd_boolean
+elf64_sparc_add_symbol_hook (bfd *abfd, struct bfd_link_info *info,
+ Elf_Internal_Sym *sym, const char **namep,
+ flagword *flagsp ATTRIBUTE_UNUSED,
+ asection **secp ATTRIBUTE_UNUSED,
+ bfd_vma *valp ATTRIBUTE_UNUSED)
+{
+ static const char *const stt_types[] = { "NOTYPE", "OBJECT", "FUNCTION" };
+
+ if ((ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC
+ || ELF_ST_BIND (sym->st_info) == STB_GNU_UNIQUE)
+ && (abfd->flags & DYNAMIC) == 0
+ && bfd_get_flavour (info->output_bfd) == bfd_target_elf_flavour)
+ elf_tdata (info->output_bfd)->has_gnu_symbols = TRUE;
+
+ if (ELF_ST_TYPE (sym->st_info) == STT_REGISTER)
+ {
+ int reg;
+ struct _bfd_sparc_elf_app_reg *p;
+
+ reg = (int)sym->st_value;
+ switch (reg & ~1)
+ {
+ case 2: reg -= 2; break;
+ case 6: reg -= 4; break;
+ default:
+ (*_bfd_error_handler)
+ (_("%B: Only registers %%g[2367] can be declared using STT_REGISTER"),
+ abfd);
+ return FALSE;
+ }
+
+ if (info->output_bfd->xvec != abfd->xvec
+ || (abfd->flags & DYNAMIC) != 0)
+ {
+ /* STT_REGISTER only works when linking an elf64_sparc object.
+ If STT_REGISTER comes from a dynamic object, don't put it into
+ the output bfd. The dynamic linker will recheck it. */
+ *namep = NULL;
+ return TRUE;
+ }
+
+ p = _bfd_sparc_elf_hash_table(info)->app_regs + reg;
+
+ if (p->name != NULL && strcmp (p->name, *namep))
+ {
+ (*_bfd_error_handler)
+ (_("Register %%g%d used incompatibly: %s in %B, previously %s in %B"),
+ abfd, p->abfd, (int) sym->st_value,
+ **namep ? *namep : "#scratch",
+ *p->name ? p->name : "#scratch");
+ return FALSE;
+ }
+
+ if (p->name == NULL)
+ {
+ if (**namep)
+ {
+ struct elf_link_hash_entry *h;
+
+ h = (struct elf_link_hash_entry *)
+ bfd_link_hash_lookup (info->hash, *namep, FALSE, FALSE, FALSE);
+
+ if (h != NULL)
+ {
+ unsigned char type = h->type;
+
+ if (type > STT_FUNC)
+ type = 0;
+ (*_bfd_error_handler)
+ (_("Symbol `%s' has differing types: REGISTER in %B, previously %s in %B"),
+ abfd, p->abfd, *namep, stt_types[type]);
+ return FALSE;
+ }
+
+ p->name = bfd_hash_allocate (&info->hash->table,
+ strlen (*namep) + 1);
+ if (!p->name)
+ return FALSE;
+
+ strcpy (p->name, *namep);
+ }
+ else
+ p->name = "";
+ p->bind = ELF_ST_BIND (sym->st_info);
+ p->abfd = abfd;
+ p->shndx = sym->st_shndx;
+ }
+ else
+ {
+ if (p->bind == STB_WEAK
+ && ELF_ST_BIND (sym->st_info) == STB_GLOBAL)
+ {
+ p->bind = STB_GLOBAL;
+ p->abfd = abfd;
+ }
+ }
+ *namep = NULL;
+ return TRUE;
+ }
+ else if (*namep && **namep
+ && info->output_bfd->xvec == abfd->xvec)
+ {
+ int i;
+ struct _bfd_sparc_elf_app_reg *p;
+
+ p = _bfd_sparc_elf_hash_table(info)->app_regs;
+ for (i = 0; i < 4; i++, p++)
+ if (p->name != NULL && ! strcmp (p->name, *namep))
+ {
+ unsigned char type = ELF_ST_TYPE (sym->st_info);
+
+ if (type > STT_FUNC)
+ type = 0;
+ (*_bfd_error_handler)
+ (_("Symbol `%s' has differing types: %s in %B, previously REGISTER in %B"),
+ abfd, p->abfd, *namep, stt_types[type]);
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+/* This function takes care of emitting STT_REGISTER symbols
+ which we cannot easily keep in the symbol hash table. */
+
+static bfd_boolean
+elf64_sparc_output_arch_syms (bfd *output_bfd ATTRIBUTE_UNUSED,
+ struct bfd_link_info *info,
+ void * flaginfo,
+ int (*func) (void *, const char *,
+ Elf_Internal_Sym *,
+ asection *,
+ struct elf_link_hash_entry *))
+{
+ int reg;
+ struct _bfd_sparc_elf_app_reg *app_regs =
+ _bfd_sparc_elf_hash_table(info)->app_regs;
+ Elf_Internal_Sym sym;
+
+ /* We arranged in size_dynamic_sections to put the STT_REGISTER entries
+ at the end of the dynlocal list, so they came at the end of the local
+ symbols in the symtab. Except that they aren't STB_LOCAL, so we need
+ to back up symtab->sh_info. */
+ if (elf_hash_table (info)->dynlocal)
+ {
+ bfd * dynobj = elf_hash_table (info)->dynobj;
+ asection *dynsymsec = bfd_get_linker_section (dynobj, ".dynsym");
+ struct elf_link_local_dynamic_entry *e;
+
+ for (e = elf_hash_table (info)->dynlocal; e ; e = e->next)
+ if (e->input_indx == -1)
+ break;
+ if (e)
+ {
+ elf_section_data (dynsymsec->output_section)->this_hdr.sh_info
+ = e->dynindx;
+ }
+ }
+
+ if (info->strip == strip_all)
+ return TRUE;
+
+ for (reg = 0; reg < 4; reg++)
+ if (app_regs [reg].name != NULL)
+ {
+ if (info->strip == strip_some
+ && bfd_hash_lookup (info->keep_hash,
+ app_regs [reg].name,
+ FALSE, FALSE) == NULL)
+ continue;
+
+ sym.st_value = reg < 2 ? reg + 2 : reg + 4;
+ sym.st_size = 0;
+ sym.st_other = 0;
+ sym.st_info = ELF_ST_INFO (app_regs [reg].bind, STT_REGISTER);
+ sym.st_shndx = app_regs [reg].shndx;
+ sym.st_target_internal = 0;
+ if ((*func) (flaginfo, app_regs [reg].name, &sym,
+ sym.st_shndx == SHN_ABS
+ ? bfd_abs_section_ptr : bfd_und_section_ptr,
+ NULL) != 1)
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static int
+elf64_sparc_get_symbol_type (Elf_Internal_Sym *elf_sym, int type)
+{
+ if (ELF_ST_TYPE (elf_sym->st_info) == STT_REGISTER)
+ return STT_REGISTER;
+ else
+ return type;
+}
+
+/* A STB_GLOBAL,STT_REGISTER symbol should be BSF_GLOBAL
+ even in SHN_UNDEF section. */
+
+static void
+elf64_sparc_symbol_processing (bfd *abfd ATTRIBUTE_UNUSED, asymbol *asym)
+{
+ elf_symbol_type *elfsym;
+
+ elfsym = (elf_symbol_type *) asym;
+ if (elfsym->internal_elf_sym.st_info
+ == ELF_ST_INFO (STB_GLOBAL, STT_REGISTER))
+ {
+ asym->flags |= BSF_GLOBAL;
+ }
+}
+
+
+/* Functions for dealing with the e_flags field. */
+
+/* Merge backend specific data from an object file to the output
+ object file when linking. */
+
+static bfd_boolean
+elf64_sparc_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
+{
+ bfd_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;
+
+#define EF_SPARC_ISA_EXTENSIONS \
+ (EF_SPARC_SUN_US1 | EF_SPARC_SUN_US3 | EF_SPARC_HAL_R1)
+
+ if ((ibfd->flags & DYNAMIC) != 0)
+ {
+ /* We don't want dynamic objects memory ordering and
+ architecture to have any role. That's what dynamic linker
+ should do. */
+ new_flags &= ~(EF_SPARCV9_MM | EF_SPARC_ISA_EXTENSIONS);
+ new_flags |= (old_flags
+ & (EF_SPARCV9_MM | EF_SPARC_ISA_EXTENSIONS));
+ }
+ else
+ {
+ /* Choose the highest architecture requirements. */
+ old_flags |= (new_flags & EF_SPARC_ISA_EXTENSIONS);
+ new_flags |= (old_flags & EF_SPARC_ISA_EXTENSIONS);
+ if ((old_flags & (EF_SPARC_SUN_US1 | EF_SPARC_SUN_US3))
+ && (old_flags & EF_SPARC_HAL_R1))
+ {
+ error = TRUE;
+ (*_bfd_error_handler)
+ (_("%B: linking UltraSPARC specific with HAL specific code"),
+ 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)
+ (_("%B: uses different e_flags (0x%lx) fields than previous modules (0x%lx)"),
+ 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 _bfd_sparc_elf_merge_private_bfd_data (ibfd, obfd);
+}
+
+/* MARCO: Set the correct entry size for the .stab section. */
+
+static bfd_boolean
+elf64_sparc_fake_sections (bfd *abfd ATTRIBUTE_UNUSED,
+ Elf_Internal_Shdr *hdr ATTRIBUTE_UNUSED,
+ asection *sec)
+{
+ const char *name;
+
+ name = bfd_get_section_name (abfd, sec);
+
+ if (strcmp (name, ".stab") == 0)
+ {
+ /* Even in the 64bit case the stab entries are only 12 bytes long. */
+ elf_section_data (sec)->this_hdr.sh_entsize = 12;
+ }
+
+ return TRUE;
+}
+
+/* Print a STT_REGISTER symbol to file FILE. */
+
+static const char *
+elf64_sparc_print_symbol_all (bfd *abfd ATTRIBUTE_UNUSED, void * filep,
+ asymbol *symbol)
+{
+ FILE *file = (FILE *) filep;
+ int reg, type;
+
+ if (ELF_ST_TYPE (((elf_symbol_type *) symbol)->internal_elf_sym.st_info)
+ != STT_REGISTER)
+ return NULL;
+
+ reg = ((elf_symbol_type *) symbol)->internal_elf_sym.st_value;
+ type = symbol->flags;
+ fprintf (file, "REG_%c%c%11s%c%c R", "GOLI" [reg / 8], '0' + (reg & 7), "",
+ ((type & BSF_LOCAL)
+ ? (type & BSF_GLOBAL) ? '!' : 'l'
+ : (type & BSF_GLOBAL) ? 'g' : ' '),
+ (type & BSF_WEAK) ? 'w' : ' ');
+ if (symbol->name == NULL || symbol->name [0] == '\0')
+ return "#scratch";
+ else
+ return symbol->name;
+}
+
+static enum elf_reloc_type_class
+elf64_sparc_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ const asection *rel_sec ATTRIBUTE_UNUSED,
+ const Elf_Internal_Rela *rela)
+{
+ switch ((int) ELF64_R_TYPE (rela->r_info))
+ {
+ case R_SPARC_RELATIVE:
+ return reloc_class_relative;
+ case R_SPARC_JMP_SLOT:
+ return reloc_class_plt;
+ case R_SPARC_COPY:
+ return reloc_class_copy;
+ default:
+ return reloc_class_normal;
+ }
+}
+
+/* Relocations in the 64 bit SPARC ELF ABI are more complex than in
+ standard ELF, because R_SPARC_OLO10 has secondary addend in
+ ELF64_R_TYPE_DATA field. This structure is used to redirect the
+ relocation handling routines. */
+
+const struct elf_size_info elf64_sparc_size_info =
+{
+ sizeof (Elf64_External_Ehdr),
+ sizeof (Elf64_External_Phdr),
+ sizeof (Elf64_External_Shdr),
+ sizeof (Elf64_External_Rel),
+ sizeof (Elf64_External_Rela),
+ sizeof (Elf64_External_Sym),
+ sizeof (Elf64_External_Dyn),
+ sizeof (Elf_External_Note),
+ 4, /* hash-table entry size. */
+ /* Internal relocations per external relocations.
+ For link purposes we use just 1 internal per
+ 1 external, for assembly and slurp symbol table
+ we use 2. */
+ 1,
+ 64, /* arch_size. */
+ 3, /* log_file_align. */
+ ELFCLASS64,
+ EV_CURRENT,
+ bfd_elf64_write_out_phdrs,
+ bfd_elf64_write_shdrs_and_ehdr,
+ bfd_elf64_checksum_contents,
+ elf64_sparc_write_relocs,
+ bfd_elf64_swap_symbol_in,
+ bfd_elf64_swap_symbol_out,
+ elf64_sparc_slurp_reloc_table,
+ bfd_elf64_slurp_symbol_table,
+ bfd_elf64_swap_dyn_in,
+ bfd_elf64_swap_dyn_out,
+ bfd_elf64_swap_reloc_in,
+ bfd_elf64_swap_reloc_out,
+ bfd_elf64_swap_reloca_in,
+ bfd_elf64_swap_reloca_out
+};
+
+#define TARGET_BIG_SYM sparc_elf64_vec
+#define TARGET_BIG_NAME "elf64-sparc"
+#define ELF_ARCH bfd_arch_sparc
+#define ELF_MAXPAGESIZE 0x100000
+#define ELF_COMMONPAGESIZE 0x2000
+
+/* 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_backend_reloc_type_class \
+ elf64_sparc_reloc_type_class
+#define bfd_elf64_get_reloc_upper_bound \
+ elf64_sparc_get_reloc_upper_bound
+#define bfd_elf64_get_dynamic_reloc_upper_bound \
+ elf64_sparc_get_dynamic_reloc_upper_bound
+#define bfd_elf64_canonicalize_reloc \
+ elf64_sparc_canonicalize_reloc
+#define bfd_elf64_canonicalize_dynamic_reloc \
+ elf64_sparc_canonicalize_dynamic_reloc
+#define elf_backend_add_symbol_hook \
+ elf64_sparc_add_symbol_hook
+#define elf_backend_get_symbol_type \
+ elf64_sparc_get_symbol_type
+#define elf_backend_symbol_processing \
+ elf64_sparc_symbol_processing
+#define elf_backend_print_symbol_all \
+ elf64_sparc_print_symbol_all
+#define elf_backend_output_arch_syms \
+ elf64_sparc_output_arch_syms
+#define bfd_elf64_bfd_merge_private_bfd_data \
+ elf64_sparc_merge_private_bfd_data
+#define elf_backend_fake_sections \
+ elf64_sparc_fake_sections
+#define elf_backend_size_info \
+ elf64_sparc_size_info
+
+#define elf_backend_plt_sym_val \
+ _bfd_sparc_elf_plt_sym_val
+#define bfd_elf64_bfd_link_hash_table_create \
+ _bfd_sparc_elf_link_hash_table_create
+#define elf_info_to_howto \
+ _bfd_sparc_elf_info_to_howto
+#define elf_backend_copy_indirect_symbol \
+ _bfd_sparc_elf_copy_indirect_symbol
+#define bfd_elf64_bfd_reloc_type_lookup \
+ _bfd_sparc_elf_reloc_type_lookup
+#define bfd_elf64_bfd_reloc_name_lookup \
+ _bfd_sparc_elf_reloc_name_lookup
+#define bfd_elf64_bfd_relax_section \
+ _bfd_sparc_elf_relax_section
+#define bfd_elf64_new_section_hook \
+ _bfd_sparc_elf_new_section_hook
+
+#define elf_backend_create_dynamic_sections \
+ _bfd_sparc_elf_create_dynamic_sections
+#define elf_backend_relocs_compatible \
+ _bfd_elf_relocs_compatible
+#define elf_backend_check_relocs \
+ _bfd_sparc_elf_check_relocs
+#define elf_backend_adjust_dynamic_symbol \
+ _bfd_sparc_elf_adjust_dynamic_symbol
+#define elf_backend_omit_section_dynsym \
+ _bfd_sparc_elf_omit_section_dynsym
+#define elf_backend_size_dynamic_sections \
+ _bfd_sparc_elf_size_dynamic_sections
+#define elf_backend_relocate_section \
+ _bfd_sparc_elf_relocate_section
+#define elf_backend_finish_dynamic_symbol \
+ _bfd_sparc_elf_finish_dynamic_symbol
+#define elf_backend_finish_dynamic_sections \
+ _bfd_sparc_elf_finish_dynamic_sections
+
+#define bfd_elf64_mkobject \
+ _bfd_sparc_elf_mkobject
+#define elf_backend_object_p \
+ _bfd_sparc_elf_object_p
+#define elf_backend_gc_mark_hook \
+ _bfd_sparc_elf_gc_mark_hook
+#define elf_backend_gc_sweep_hook \
+ _bfd_sparc_elf_gc_sweep_hook
+#define elf_backend_init_index_section \
+ _bfd_elf_init_1_index_section
+
+#define elf_backend_can_gc_sections 1
+#define elf_backend_can_refcount 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 8
+#define elf_backend_rela_normal 1
+
+/* Section 5.2.4 of the ABI specifies a 256-byte boundary for the table. */
+#define elf_backend_plt_alignment 8
+
+#include "elf64-target.h"
+
+/* FreeBSD support */
+#undef TARGET_BIG_SYM
+#define TARGET_BIG_SYM sparc_elf64_fbsd_vec
+#undef TARGET_BIG_NAME
+#define TARGET_BIG_NAME "elf64-sparc-freebsd"
+#undef ELF_OSABI
+#define ELF_OSABI ELFOSABI_FREEBSD
+
+#undef elf64_bed
+#define elf64_bed elf64_sparc_fbsd_bed
+
+#include "elf64-target.h"
+
+/* Solaris 2. */
+
+#undef TARGET_BIG_SYM
+#define TARGET_BIG_SYM sparc_elf64_sol2_vec
+#undef TARGET_BIG_NAME
+#define TARGET_BIG_NAME "elf64-sparc-sol2"
+
+/* Restore default: we cannot use ELFOSABI_SOLARIS, otherwise ELFOSABI_NONE
+ objects won't be recognized. */
+#undef ELF_OSABI
+
+#undef elf64_bed
+#define elf64_bed elf64_sparc_sol2_bed
+
+/* The 64-bit static TLS arena size is rounded to the nearest 16-byte
+ boundary. */
+#undef elf_backend_static_tls_alignment
+#define elf_backend_static_tls_alignment 16
+
+#include "elf64-target.h"
diff --git a/bfd/elf64-tilegx.c b/bfd/elf64-tilegx.c
new file mode 100644
index 0000000..f388e72
--- /dev/null
+++ b/bfd/elf64-tilegx.c
@@ -0,0 +1,135 @@
+/* TILE-Gx-specific support for 64-bit ELF.
+ Copyright (C) 2011-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+#include "elf-bfd.h"
+#include "elfxx-tilegx.h"
+#include "elf64-tilegx.h"
+
+
+/* Support for core dump NOTE sections. */
+
+static bfd_boolean
+tilegx_elf_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
+{
+ int offset;
+ size_t size;
+
+ if (note->descsz != TILEGX_PRSTATUS_SIZEOF)
+ return FALSE;
+
+ /* pr_cursig */
+ elf_tdata (abfd)->core->signal =
+ bfd_get_16 (abfd, note->descdata + TILEGX_PRSTATUS_OFFSET_PR_CURSIG);
+
+ /* pr_pid */
+ elf_tdata (abfd)->core->pid =
+ bfd_get_32 (abfd, note->descdata + TILEGX_PRSTATUS_OFFSET_PR_PID);
+
+ /* pr_reg */
+ offset = TILEGX_PRSTATUS_OFFSET_PR_REG;
+ size = TILEGX_GREGSET_T_SIZE;
+
+ /* Make a ".reg/999" section. */
+ return _bfd_elfcore_make_pseudosection (abfd, ".reg",
+ size, note->descpos + offset);
+}
+
+static bfd_boolean
+tilegx_elf_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
+{
+ if (note->descsz != TILEGX_PRPSINFO_SIZEOF)
+ return FALSE;
+
+ elf_tdata (abfd)->core->program
+ = _bfd_elfcore_strndup (abfd, note->descdata + TILEGX_PRPSINFO_OFFSET_PR_FNAME, 16);
+ elf_tdata (abfd)->core->command
+ = _bfd_elfcore_strndup (abfd, note->descdata + TILEGX_PRPSINFO_OFFSET_PR_PSARGS, ELF_PR_PSARGS_SIZE);
+
+
+ /* 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;
+}
+
+
+#define ELF_ARCH bfd_arch_tilegx
+#define ELF_TARGET_ID TILEGX_ELF_DATA
+#define ELF_MACHINE_CODE EM_TILEGX
+#define ELF_MAXPAGESIZE 0x10000
+#define ELF_COMMONPAGESIZE 0x10000
+
+
+#define TARGET_BIG_SYM tilegx_elf64_be_vec
+#define TARGET_BIG_NAME "elf64-tilegx-be"
+#define TARGET_LITTLE_SYM tilegx_elf64_le_vec
+#define TARGET_LITTLE_NAME "elf64-tilegx-le"
+
+#define elf_backend_reloc_type_class tilegx_reloc_type_class
+
+#define bfd_elf64_bfd_reloc_name_lookup tilegx_reloc_name_lookup
+#define bfd_elf64_bfd_link_hash_table_create tilegx_elf_link_hash_table_create
+#define bfd_elf64_bfd_reloc_type_lookup tilegx_reloc_type_lookup
+#define bfd_elf64_bfd_merge_private_bfd_data \
+ _bfd_tilegx_elf_merge_private_bfd_data
+
+#define elf_backend_copy_indirect_symbol tilegx_elf_copy_indirect_symbol
+#define elf_backend_create_dynamic_sections tilegx_elf_create_dynamic_sections
+#define elf_backend_check_relocs tilegx_elf_check_relocs
+#define elf_backend_adjust_dynamic_symbol tilegx_elf_adjust_dynamic_symbol
+#define elf_backend_omit_section_dynsym tilegx_elf_omit_section_dynsym
+#define elf_backend_size_dynamic_sections tilegx_elf_size_dynamic_sections
+#define elf_backend_relocate_section tilegx_elf_relocate_section
+#define elf_backend_finish_dynamic_symbol tilegx_elf_finish_dynamic_symbol
+#define elf_backend_finish_dynamic_sections tilegx_elf_finish_dynamic_sections
+#define elf_backend_gc_mark_hook tilegx_elf_gc_mark_hook
+#define elf_backend_gc_sweep_hook tilegx_elf_gc_sweep_hook
+#define elf_backend_plt_sym_val tilegx_elf_plt_sym_val
+#define elf_info_to_howto_rel NULL
+#define elf_info_to_howto tilegx_info_to_howto_rela
+#define elf_backend_grok_prstatus tilegx_elf_grok_prstatus
+#define elf_backend_grok_psinfo tilegx_elf_grok_psinfo
+#define elf_backend_additional_program_headers tilegx_additional_program_headers
+
+#define elf_backend_init_index_section _bfd_elf_init_1_index_section
+
+#define elf_backend_can_gc_sections 1
+#define elf_backend_can_refcount 1
+#define elf_backend_want_got_plt 1
+#define elf_backend_plt_readonly 1
+/* Align PLT mod 64 byte L2 line size. */
+#define elf_backend_plt_alignment 6
+#define elf_backend_want_plt_sym 1
+#define elf_backend_got_header_size 8
+#define elf_backend_rela_normal 1
+#define elf_backend_default_execstack 0
+
+#include "elf64-target.h"
diff --git a/bfd/elf64-tilegx.h b/bfd/elf64-tilegx.h
new file mode 100644
index 0000000..12aec46
--- /dev/null
+++ b/bfd/elf64-tilegx.h
@@ -0,0 +1,38 @@
+/* TILE-Gx-specific support for 64-bit ELF.
+ Copyright (C) 2011-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#ifndef _ELF64_TILEGX_H
+#define _ELF64_TILEGX_H
+
+/* This file contains sizes and offsets of Linux data structures. */
+
+#define TILEGX_PRSTATUS_SIZEOF 632
+#define TILEGX_PRSTATUS_OFFSET_PR_CURSIG 12
+#define TILEGX_PRSTATUS_OFFSET_PR_PID 32
+#define TILEGX_PRSTATUS_OFFSET_PR_REG 112
+
+#define TILEGX_PRPSINFO_SIZEOF 136
+#define TILEGX_PRPSINFO_OFFSET_PR_FNAME 40
+#define TILEGX_PRPSINFO_OFFSET_PR_PSARGS 56
+#define ELF_PR_PSARGS_SIZE 80
+
+#define TILEGX_GREGSET_T_SIZE 512
+
+#endif /* _ELF64_TILEGX_H */
diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c
new file mode 100644
index 0000000..fefb08c
--- /dev/null
+++ b/bfd/elf64-x86-64.c
@@ -0,0 +1,6129 @@
+/* X86-64 specific support for ELF
+ Copyright (C) 2000-2014 Free Software Foundation, Inc.
+ Contributed by Jan Hubicka <jh@suse.cz>.
+
+ This file is part of BFD, the Binary File Descriptor library.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "bfdlink.h"
+#include "libbfd.h"
+#include "elf-bfd.h"
+#include "elf-nacl.h"
+#include "bfd_stdint.h"
+#include "objalloc.h"
+#include "hashtab.h"
+#include "dwarf2.h"
+#include "libiberty.h"
+
+#include "elf/x86-64.h"
+
+#ifdef CORE_HEADER
+#include <stdarg.h>
+#include CORE_HEADER
+#endif
+
+/* In case we're on a 32-bit machine, construct a 64-bit "-1" value. */
+#define MINUS_ONE (~ (bfd_vma) 0)
+
+/* Since both 32-bit and 64-bit x86-64 encode relocation type in the
+ identical manner, we use ELF32_R_TYPE instead of ELF64_R_TYPE to get
+ relocation type. We also use ELF_ST_TYPE instead of ELF64_ST_TYPE
+ since they are the same. */
+
+#define ABI_64_P(abfd) \
+ (get_elf_backend_data (abfd)->s->elfclass == ELFCLASS64)
+
+/* The relocation "howto" table. Order of fields:
+ type, rightshift, size, bitsize, pc_relative, bitpos, complain_on_overflow,
+ special_function, name, partial_inplace, src_mask, dst_mask, pcrel_offset. */
+static reloc_howto_type x86_64_elf_howto_table[] =
+{
+ HOWTO(R_X86_64_NONE, 0, 0, 0, FALSE, 0, complain_overflow_dont,
+ bfd_elf_generic_reloc, "R_X86_64_NONE", FALSE, 0x00000000, 0x00000000,
+ FALSE),
+ HOWTO(R_X86_64_64, 0, 4, 64, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_X86_64_64", FALSE, MINUS_ONE, MINUS_ONE,
+ FALSE),
+ HOWTO(R_X86_64_PC32, 0, 2, 32, TRUE, 0, complain_overflow_signed,
+ bfd_elf_generic_reloc, "R_X86_64_PC32", FALSE, 0xffffffff, 0xffffffff,
+ TRUE),
+ HOWTO(R_X86_64_GOT32, 0, 2, 32, FALSE, 0, complain_overflow_signed,
+ bfd_elf_generic_reloc, "R_X86_64_GOT32", FALSE, 0xffffffff, 0xffffffff,
+ FALSE),
+ HOWTO(R_X86_64_PLT32, 0, 2, 32, TRUE, 0, complain_overflow_signed,
+ bfd_elf_generic_reloc, "R_X86_64_PLT32", FALSE, 0xffffffff, 0xffffffff,
+ TRUE),
+ HOWTO(R_X86_64_COPY, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_X86_64_COPY", FALSE, 0xffffffff, 0xffffffff,
+ FALSE),
+ HOWTO(R_X86_64_GLOB_DAT, 0, 4, 64, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_X86_64_GLOB_DAT", FALSE, MINUS_ONE,
+ MINUS_ONE, FALSE),
+ HOWTO(R_X86_64_JUMP_SLOT, 0, 4, 64, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_X86_64_JUMP_SLOT", FALSE, MINUS_ONE,
+ MINUS_ONE, FALSE),
+ HOWTO(R_X86_64_RELATIVE, 0, 4, 64, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_X86_64_RELATIVE", FALSE, MINUS_ONE,
+ MINUS_ONE, FALSE),
+ HOWTO(R_X86_64_GOTPCREL, 0, 2, 32, TRUE, 0, complain_overflow_signed,
+ bfd_elf_generic_reloc, "R_X86_64_GOTPCREL", FALSE, 0xffffffff,
+ 0xffffffff, TRUE),
+ HOWTO(R_X86_64_32, 0, 2, 32, FALSE, 0, complain_overflow_unsigned,
+ bfd_elf_generic_reloc, "R_X86_64_32", FALSE, 0xffffffff, 0xffffffff,
+ FALSE),
+ HOWTO(R_X86_64_32S, 0, 2, 32, FALSE, 0, complain_overflow_signed,
+ bfd_elf_generic_reloc, "R_X86_64_32S", FALSE, 0xffffffff, 0xffffffff,
+ FALSE),
+ HOWTO(R_X86_64_16, 0, 1, 16, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_X86_64_16", FALSE, 0xffff, 0xffff, FALSE),
+ HOWTO(R_X86_64_PC16,0, 1, 16, TRUE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_X86_64_PC16", FALSE, 0xffff, 0xffff, TRUE),
+ HOWTO(R_X86_64_8, 0, 0, 8, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_X86_64_8", FALSE, 0xff, 0xff, FALSE),
+ HOWTO(R_X86_64_PC8, 0, 0, 8, TRUE, 0, complain_overflow_signed,
+ bfd_elf_generic_reloc, "R_X86_64_PC8", FALSE, 0xff, 0xff, TRUE),
+ HOWTO(R_X86_64_DTPMOD64, 0, 4, 64, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_X86_64_DTPMOD64", FALSE, MINUS_ONE,
+ MINUS_ONE, FALSE),
+ HOWTO(R_X86_64_DTPOFF64, 0, 4, 64, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_X86_64_DTPOFF64", FALSE, MINUS_ONE,
+ MINUS_ONE, FALSE),
+ HOWTO(R_X86_64_TPOFF64, 0, 4, 64, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_X86_64_TPOFF64", FALSE, MINUS_ONE,
+ MINUS_ONE, FALSE),
+ HOWTO(R_X86_64_TLSGD, 0, 2, 32, TRUE, 0, complain_overflow_signed,
+ bfd_elf_generic_reloc, "R_X86_64_TLSGD", FALSE, 0xffffffff,
+ 0xffffffff, TRUE),
+ HOWTO(R_X86_64_TLSLD, 0, 2, 32, TRUE, 0, complain_overflow_signed,
+ bfd_elf_generic_reloc, "R_X86_64_TLSLD", FALSE, 0xffffffff,
+ 0xffffffff, TRUE),
+ HOWTO(R_X86_64_DTPOFF32, 0, 2, 32, FALSE, 0, complain_overflow_signed,
+ bfd_elf_generic_reloc, "R_X86_64_DTPOFF32", FALSE, 0xffffffff,
+ 0xffffffff, FALSE),
+ HOWTO(R_X86_64_GOTTPOFF, 0, 2, 32, TRUE, 0, complain_overflow_signed,
+ bfd_elf_generic_reloc, "R_X86_64_GOTTPOFF", FALSE, 0xffffffff,
+ 0xffffffff, TRUE),
+ HOWTO(R_X86_64_TPOFF32, 0, 2, 32, FALSE, 0, complain_overflow_signed,
+ bfd_elf_generic_reloc, "R_X86_64_TPOFF32", FALSE, 0xffffffff,
+ 0xffffffff, FALSE),
+ HOWTO(R_X86_64_PC64, 0, 4, 64, TRUE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_X86_64_PC64", FALSE, MINUS_ONE, MINUS_ONE,
+ TRUE),
+ HOWTO(R_X86_64_GOTOFF64, 0, 4, 64, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_X86_64_GOTOFF64",
+ FALSE, MINUS_ONE, MINUS_ONE, FALSE),
+ HOWTO(R_X86_64_GOTPC32, 0, 2, 32, TRUE, 0, complain_overflow_signed,
+ bfd_elf_generic_reloc, "R_X86_64_GOTPC32",
+ FALSE, 0xffffffff, 0xffffffff, TRUE),
+ HOWTO(R_X86_64_GOT64, 0, 4, 64, FALSE, 0, complain_overflow_signed,
+ bfd_elf_generic_reloc, "R_X86_64_GOT64", FALSE, MINUS_ONE, MINUS_ONE,
+ FALSE),
+ HOWTO(R_X86_64_GOTPCREL64, 0, 4, 64, TRUE, 0, complain_overflow_signed,
+ bfd_elf_generic_reloc, "R_X86_64_GOTPCREL64", FALSE, MINUS_ONE,
+ MINUS_ONE, TRUE),
+ HOWTO(R_X86_64_GOTPC64, 0, 4, 64, TRUE, 0, complain_overflow_signed,
+ bfd_elf_generic_reloc, "R_X86_64_GOTPC64",
+ FALSE, MINUS_ONE, MINUS_ONE, TRUE),
+ HOWTO(R_X86_64_GOTPLT64, 0, 4, 64, FALSE, 0, complain_overflow_signed,
+ bfd_elf_generic_reloc, "R_X86_64_GOTPLT64", FALSE, MINUS_ONE,
+ MINUS_ONE, FALSE),
+ HOWTO(R_X86_64_PLTOFF64, 0, 4, 64, FALSE, 0, complain_overflow_signed,
+ bfd_elf_generic_reloc, "R_X86_64_PLTOFF64", FALSE, MINUS_ONE,
+ MINUS_ONE, FALSE),
+ HOWTO(R_X86_64_SIZE32, 0, 2, 32, FALSE, 0, complain_overflow_unsigned,
+ bfd_elf_generic_reloc, "R_X86_64_SIZE32", FALSE, 0xffffffff, 0xffffffff,
+ FALSE),
+ HOWTO(R_X86_64_SIZE64, 0, 4, 64, FALSE, 0, complain_overflow_unsigned,
+ bfd_elf_generic_reloc, "R_X86_64_SIZE64", FALSE, MINUS_ONE, MINUS_ONE,
+ FALSE),
+ HOWTO(R_X86_64_GOTPC32_TLSDESC, 0, 2, 32, TRUE, 0,
+ complain_overflow_bitfield, bfd_elf_generic_reloc,
+ "R_X86_64_GOTPC32_TLSDESC",
+ FALSE, 0xffffffff, 0xffffffff, TRUE),
+ HOWTO(R_X86_64_TLSDESC_CALL, 0, 0, 0, FALSE, 0,
+ complain_overflow_dont, bfd_elf_generic_reloc,
+ "R_X86_64_TLSDESC_CALL",
+ FALSE, 0, 0, FALSE),
+ HOWTO(R_X86_64_TLSDESC, 0, 4, 64, FALSE, 0,
+ complain_overflow_bitfield, bfd_elf_generic_reloc,
+ "R_X86_64_TLSDESC",
+ FALSE, MINUS_ONE, MINUS_ONE, FALSE),
+ HOWTO(R_X86_64_IRELATIVE, 0, 4, 64, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_X86_64_IRELATIVE", FALSE, MINUS_ONE,
+ MINUS_ONE, FALSE),
+ HOWTO(R_X86_64_RELATIVE64, 0, 4, 64, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_X86_64_RELATIVE64", FALSE, MINUS_ONE,
+ MINUS_ONE, FALSE),
+ HOWTO(R_X86_64_PC32_BND, 0, 2, 32, TRUE, 0, complain_overflow_signed,
+ bfd_elf_generic_reloc, "R_X86_64_PC32_BND", FALSE, 0xffffffff, 0xffffffff,
+ TRUE),
+ HOWTO(R_X86_64_PLT32_BND, 0, 2, 32, TRUE, 0, complain_overflow_signed,
+ bfd_elf_generic_reloc, "R_X86_64_PLT32_BND", FALSE, 0xffffffff, 0xffffffff,
+ TRUE),
+
+ /* We have a gap in the reloc numbers here.
+ R_X86_64_standard counts the number up to this point, and
+ R_X86_64_vt_offset is the value to subtract from a reloc type of
+ R_X86_64_GNU_VT* to form an index into this table. */
+#define R_X86_64_standard (R_X86_64_PLT32_BND + 1)
+#define R_X86_64_vt_offset (R_X86_64_GNU_VTINHERIT - R_X86_64_standard)
+
+/* GNU extension to record C++ vtable hierarchy. */
+ HOWTO (R_X86_64_GNU_VTINHERIT, 0, 4, 0, FALSE, 0, complain_overflow_dont,
+ NULL, "R_X86_64_GNU_VTINHERIT", FALSE, 0, 0, FALSE),
+
+/* GNU extension to record C++ vtable member usage. */
+ HOWTO (R_X86_64_GNU_VTENTRY, 0, 4, 0, FALSE, 0, complain_overflow_dont,
+ _bfd_elf_rel_vtable_reloc_fn, "R_X86_64_GNU_VTENTRY", FALSE, 0, 0,
+ FALSE),
+
+/* Use complain_overflow_bitfield on R_X86_64_32 for x32. */
+ HOWTO(R_X86_64_32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_X86_64_32", FALSE, 0xffffffff, 0xffffffff,
+ FALSE)
+};
+
+#define IS_X86_64_PCREL_TYPE(TYPE) \
+ ( ((TYPE) == R_X86_64_PC8) \
+ || ((TYPE) == R_X86_64_PC16) \
+ || ((TYPE) == R_X86_64_PC32) \
+ || ((TYPE) == R_X86_64_PC32_BND) \
+ || ((TYPE) == R_X86_64_PC64))
+
+/* Map BFD relocs to the x86_64 elf relocs. */
+struct elf_reloc_map
+{
+ bfd_reloc_code_real_type bfd_reloc_val;
+ unsigned char elf_reloc_val;
+};
+
+static const struct elf_reloc_map x86_64_reloc_map[] =
+{
+ { BFD_RELOC_NONE, R_X86_64_NONE, },
+ { BFD_RELOC_64, R_X86_64_64, },
+ { BFD_RELOC_32_PCREL, R_X86_64_PC32, },
+ { BFD_RELOC_X86_64_GOT32, R_X86_64_GOT32,},
+ { BFD_RELOC_X86_64_PLT32, R_X86_64_PLT32,},
+ { BFD_RELOC_X86_64_COPY, R_X86_64_COPY, },
+ { BFD_RELOC_X86_64_GLOB_DAT, R_X86_64_GLOB_DAT, },
+ { BFD_RELOC_X86_64_JUMP_SLOT, R_X86_64_JUMP_SLOT, },
+ { BFD_RELOC_X86_64_RELATIVE, R_X86_64_RELATIVE, },
+ { BFD_RELOC_X86_64_GOTPCREL, R_X86_64_GOTPCREL, },
+ { BFD_RELOC_32, R_X86_64_32, },
+ { BFD_RELOC_X86_64_32S, R_X86_64_32S, },
+ { BFD_RELOC_16, R_X86_64_16, },
+ { BFD_RELOC_16_PCREL, R_X86_64_PC16, },
+ { BFD_RELOC_8, R_X86_64_8, },
+ { BFD_RELOC_8_PCREL, R_X86_64_PC8, },
+ { BFD_RELOC_X86_64_DTPMOD64, R_X86_64_DTPMOD64, },
+ { BFD_RELOC_X86_64_DTPOFF64, R_X86_64_DTPOFF64, },
+ { BFD_RELOC_X86_64_TPOFF64, R_X86_64_TPOFF64, },
+ { BFD_RELOC_X86_64_TLSGD, R_X86_64_TLSGD, },
+ { BFD_RELOC_X86_64_TLSLD, R_X86_64_TLSLD, },
+ { BFD_RELOC_X86_64_DTPOFF32, R_X86_64_DTPOFF32, },
+ { BFD_RELOC_X86_64_GOTTPOFF, R_X86_64_GOTTPOFF, },
+ { BFD_RELOC_X86_64_TPOFF32, R_X86_64_TPOFF32, },
+ { BFD_RELOC_64_PCREL, R_X86_64_PC64, },
+ { BFD_RELOC_X86_64_GOTOFF64, R_X86_64_GOTOFF64, },
+ { BFD_RELOC_X86_64_GOTPC32, R_X86_64_GOTPC32, },
+ { BFD_RELOC_X86_64_GOT64, R_X86_64_GOT64, },
+ { BFD_RELOC_X86_64_GOTPCREL64,R_X86_64_GOTPCREL64, },
+ { BFD_RELOC_X86_64_GOTPC64, R_X86_64_GOTPC64, },
+ { BFD_RELOC_X86_64_GOTPLT64, R_X86_64_GOTPLT64, },
+ { BFD_RELOC_X86_64_PLTOFF64, R_X86_64_PLTOFF64, },
+ { BFD_RELOC_SIZE32, R_X86_64_SIZE32, },
+ { BFD_RELOC_SIZE64, R_X86_64_SIZE64, },
+ { BFD_RELOC_X86_64_GOTPC32_TLSDESC, R_X86_64_GOTPC32_TLSDESC, },
+ { BFD_RELOC_X86_64_TLSDESC_CALL, R_X86_64_TLSDESC_CALL, },
+ { BFD_RELOC_X86_64_TLSDESC, R_X86_64_TLSDESC, },
+ { BFD_RELOC_X86_64_IRELATIVE, R_X86_64_IRELATIVE, },
+ { BFD_RELOC_X86_64_PC32_BND, R_X86_64_PC32_BND,},
+ { BFD_RELOC_X86_64_PLT32_BND, R_X86_64_PLT32_BND,},
+ { BFD_RELOC_VTABLE_INHERIT, R_X86_64_GNU_VTINHERIT, },
+ { BFD_RELOC_VTABLE_ENTRY, R_X86_64_GNU_VTENTRY, },
+};
+
+static reloc_howto_type *
+elf_x86_64_rtype_to_howto (bfd *abfd, unsigned r_type)
+{
+ unsigned i;
+
+ if (r_type == (unsigned int) R_X86_64_32)
+ {
+ if (ABI_64_P (abfd))
+ i = r_type;
+ else
+ i = ARRAY_SIZE (x86_64_elf_howto_table) - 1;
+ }
+ else if (r_type < (unsigned int) R_X86_64_GNU_VTINHERIT
+ || r_type >= (unsigned int) R_X86_64_max)
+ {
+ if (r_type >= (unsigned int) R_X86_64_standard)
+ {
+ (*_bfd_error_handler) (_("%B: invalid relocation type %d"),
+ abfd, (int) r_type);
+ r_type = R_X86_64_NONE;
+ }
+ i = r_type;
+ }
+ else
+ i = r_type - (unsigned int) R_X86_64_vt_offset;
+ BFD_ASSERT (x86_64_elf_howto_table[i].type == r_type);
+ return &x86_64_elf_howto_table[i];
+}
+
+/* Given a BFD reloc type, return a HOWTO structure. */
+static reloc_howto_type *
+elf_x86_64_reloc_type_lookup (bfd *abfd,
+ bfd_reloc_code_real_type code)
+{
+ unsigned int i;
+
+ for (i = 0; i < sizeof (x86_64_reloc_map) / sizeof (struct elf_reloc_map);
+ i++)
+ {
+ if (x86_64_reloc_map[i].bfd_reloc_val == code)
+ return elf_x86_64_rtype_to_howto (abfd,
+ x86_64_reloc_map[i].elf_reloc_val);
+ }
+ return 0;
+}
+
+static reloc_howto_type *
+elf_x86_64_reloc_name_lookup (bfd *abfd,
+ const char *r_name)
+{
+ unsigned int i;
+
+ if (!ABI_64_P (abfd) && strcasecmp (r_name, "R_X86_64_32") == 0)
+ {
+ /* Get x32 R_X86_64_32. */
+ reloc_howto_type *reloc
+ = &x86_64_elf_howto_table[ARRAY_SIZE (x86_64_elf_howto_table) - 1];
+ BFD_ASSERT (reloc->type == (unsigned int) R_X86_64_32);
+ return reloc;
+ }
+
+ for (i = 0; i < ARRAY_SIZE (x86_64_elf_howto_table); i++)
+ if (x86_64_elf_howto_table[i].name != NULL
+ && strcasecmp (x86_64_elf_howto_table[i].name, r_name) == 0)
+ return &x86_64_elf_howto_table[i];
+
+ return NULL;
+}
+
+/* Given an x86_64 ELF reloc type, fill in an arelent structure. */
+
+static void
+elf_x86_64_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED, arelent *cache_ptr,
+ Elf_Internal_Rela *dst)
+{
+ unsigned r_type;
+
+ r_type = ELF32_R_TYPE (dst->r_info);
+ cache_ptr->howto = elf_x86_64_rtype_to_howto (abfd, r_type);
+ BFD_ASSERT (r_type == cache_ptr->howto->type);
+}
+
+/* Support for core dump NOTE sections. */
+static bfd_boolean
+elf_x86_64_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
+{
+ int offset;
+ size_t size;
+
+ switch (note->descsz)
+ {
+ default:
+ return FALSE;
+
+ case 296: /* sizeof(istruct elf_prstatus) on Linux/x32 */
+ /* pr_cursig */
+ elf_tdata (abfd)->core->signal = bfd_get_16 (abfd, note->descdata + 12);
+
+ /* pr_pid */
+ elf_tdata (abfd)->core->lwpid = bfd_get_32 (abfd, note->descdata + 24);
+
+ /* pr_reg */
+ offset = 72;
+ size = 216;
+
+ break;
+
+ case 336: /* sizeof(istruct elf_prstatus) on Linux/x86_64 */
+ /* pr_cursig */
+ elf_tdata (abfd)->core->signal
+ = bfd_get_16 (abfd, note->descdata + 12);
+
+ /* pr_pid */
+ elf_tdata (abfd)->core->lwpid
+ = bfd_get_32 (abfd, note->descdata + 32);
+
+ /* pr_reg */
+ offset = 112;
+ size = 216;
+
+ break;
+ }
+
+ /* Make a ".reg/999" section. */
+ return _bfd_elfcore_make_pseudosection (abfd, ".reg",
+ size, note->descpos + offset);
+}
+
+static bfd_boolean
+elf_x86_64_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
+{
+ switch (note->descsz)
+ {
+ default:
+ return FALSE;
+
+ case 124: /* sizeof(struct elf_prpsinfo) on Linux/x32 */
+ elf_tdata (abfd)->core->pid
+ = bfd_get_32 (abfd, note->descdata + 12);
+ elf_tdata (abfd)->core->program
+ = _bfd_elfcore_strndup (abfd, note->descdata + 28, 16);
+ elf_tdata (abfd)->core->command
+ = _bfd_elfcore_strndup (abfd, note->descdata + 44, 80);
+ break;
+
+ case 136: /* sizeof(struct elf_prpsinfo) on Linux/x86_64 */
+ elf_tdata (abfd)->core->pid
+ = bfd_get_32 (abfd, note->descdata + 24);
+ elf_tdata (abfd)->core->program
+ = _bfd_elfcore_strndup (abfd, note->descdata + 40, 16);
+ elf_tdata (abfd)->core->command
+ = _bfd_elfcore_strndup (abfd, note->descdata + 56, 80);
+ }
+
+ /* 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;
+}
+
+#ifdef CORE_HEADER
+static char *
+elf_x86_64_write_core_note (bfd *abfd, char *buf, int *bufsiz,
+ int note_type, ...)
+{
+ const struct elf_backend_data *bed = get_elf_backend_data (abfd);
+ va_list ap;
+ const char *fname, *psargs;
+ long pid;
+ int cursig;
+ const void *gregs;
+
+ switch (note_type)
+ {
+ default:
+ return NULL;
+
+ case NT_PRPSINFO:
+ va_start (ap, note_type);
+ fname = va_arg (ap, const char *);
+ psargs = va_arg (ap, const char *);
+ va_end (ap);
+
+ if (bed->s->elfclass == ELFCLASS32)
+ {
+ prpsinfo32_t data;
+ memset (&data, 0, sizeof (data));
+ strncpy (data.pr_fname, fname, sizeof (data.pr_fname));
+ strncpy (data.pr_psargs, psargs, sizeof (data.pr_psargs));
+ return elfcore_write_note (abfd, buf, bufsiz, "CORE", note_type,
+ &data, sizeof (data));
+ }
+ else
+ {
+ prpsinfo64_t data;
+ memset (&data, 0, sizeof (data));
+ strncpy (data.pr_fname, fname, sizeof (data.pr_fname));
+ strncpy (data.pr_psargs, psargs, sizeof (data.pr_psargs));
+ return elfcore_write_note (abfd, buf, bufsiz, "CORE", note_type,
+ &data, sizeof (data));
+ }
+ /* NOTREACHED */
+
+ case NT_PRSTATUS:
+ va_start (ap, note_type);
+ pid = va_arg (ap, long);
+ cursig = va_arg (ap, int);
+ gregs = va_arg (ap, const void *);
+ va_end (ap);
+
+ if (bed->s->elfclass == ELFCLASS32)
+ {
+ if (bed->elf_machine_code == EM_X86_64)
+ {
+ prstatusx32_t prstat;
+ memset (&prstat, 0, sizeof (prstat));
+ prstat.pr_pid = pid;
+ prstat.pr_cursig = cursig;
+ memcpy (&prstat.pr_reg, gregs, sizeof (prstat.pr_reg));
+ return elfcore_write_note (abfd, buf, bufsiz, "CORE", note_type,
+ &prstat, sizeof (prstat));
+ }
+ else
+ {
+ prstatus32_t prstat;
+ memset (&prstat, 0, sizeof (prstat));
+ prstat.pr_pid = pid;
+ prstat.pr_cursig = cursig;
+ memcpy (&prstat.pr_reg, gregs, sizeof (prstat.pr_reg));
+ return elfcore_write_note (abfd, buf, bufsiz, "CORE", note_type,
+ &prstat, sizeof (prstat));
+ }
+ }
+ else
+ {
+ prstatus64_t prstat;
+ memset (&prstat, 0, sizeof (prstat));
+ prstat.pr_pid = pid;
+ prstat.pr_cursig = cursig;
+ memcpy (&prstat.pr_reg, gregs, sizeof (prstat.pr_reg));
+ return elfcore_write_note (abfd, buf, bufsiz, "CORE", note_type,
+ &prstat, sizeof (prstat));
+ }
+ }
+ /* NOTREACHED */
+}
+#endif
+
+/* Functions for the x86-64 ELF linker. */
+
+/* The name of the dynamic interpreter. This is put in the .interp
+ section. */
+
+#define ELF64_DYNAMIC_INTERPRETER "/lib/ld64.so.1"
+#define ELF32_DYNAMIC_INTERPRETER "/lib/ldx32.so.1"
+
+/* If ELIMINATE_COPY_RELOCS is non-zero, the linker will try to avoid
+ copying dynamic variables from a shared lib into an app's dynbss
+ section, and instead use a dynamic relocation to point into the
+ shared lib. */
+#define ELIMINATE_COPY_RELOCS 1
+
+/* The size in bytes of an entry in the global offset table. */
+
+#define GOT_ENTRY_SIZE 8
+
+/* 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. See the
+ SVR4 ABI i386 supplement and the x86-64 ABI to see how this works. */
+
+static const bfd_byte elf_x86_64_plt0_entry[PLT_ENTRY_SIZE] =
+{
+ 0xff, 0x35, 8, 0, 0, 0, /* pushq GOT+8(%rip) */
+ 0xff, 0x25, 16, 0, 0, 0, /* jmpq *GOT+16(%rip) */
+ 0x0f, 0x1f, 0x40, 0x00 /* nopl 0(%rax) */
+};
+
+/* Subsequent entries in a procedure linkage table look like this. */
+
+static const bfd_byte elf_x86_64_plt_entry[PLT_ENTRY_SIZE] =
+{
+ 0xff, 0x25, /* jmpq *name@GOTPC(%rip) */
+ 0, 0, 0, 0, /* replaced with offset to this symbol in .got. */
+ 0x68, /* pushq immediate */
+ 0, 0, 0, 0, /* replaced with index into relocation table. */
+ 0xe9, /* jmp relative */
+ 0, 0, 0, 0 /* replaced with offset to start of .plt0. */
+};
+
+/* The first entry in a procedure linkage table with BND relocations
+ like this. */
+
+static const bfd_byte elf_x86_64_bnd_plt0_entry[PLT_ENTRY_SIZE] =
+{
+ 0xff, 0x35, 8, 0, 0, 0, /* pushq GOT+8(%rip) */
+ 0xf2, 0xff, 0x25, 16, 0, 0, 0, /* bnd jmpq *GOT+16(%rip) */
+ 0x0f, 0x1f, 0 /* nopl (%rax) */
+};
+
+/* Subsequent entries for legacy branches in a procedure linkage table
+ with BND relocations look like this. */
+
+static const bfd_byte elf_x86_64_legacy_plt_entry[PLT_ENTRY_SIZE] =
+{
+ 0x68, 0, 0, 0, 0, /* pushq immediate */
+ 0xe9, 0, 0, 0, 0, /* jmpq relative */
+ 0x66, 0x0f, 0x1f, 0x44, 0, 0 /* nopw (%rax,%rax,1) */
+};
+
+/* Subsequent entries for branches with BND prefx in a procedure linkage
+ table with BND relocations look like this. */
+
+static const bfd_byte elf_x86_64_bnd_plt_entry[PLT_ENTRY_SIZE] =
+{
+ 0x68, 0, 0, 0, 0, /* pushq immediate */
+ 0xf2, 0xe9, 0, 0, 0, 0, /* bnd jmpq relative */
+ 0x0f, 0x1f, 0x44, 0, 0 /* nopl 0(%rax,%rax,1) */
+};
+
+/* Entries for legacy branches in the second procedure linkage table
+ look like this. */
+
+static const bfd_byte elf_x86_64_legacy_plt2_entry[8] =
+{
+ 0xff, 0x25, /* jmpq *name@GOTPC(%rip) */
+ 0, 0, 0, 0, /* replaced with offset to this symbol in .got. */
+ 0x66, 0x90 /* xchg %ax,%ax */
+};
+
+/* Entries for branches with BND prefix in the second procedure linkage
+ table look like this. */
+
+static const bfd_byte elf_x86_64_bnd_plt2_entry[8] =
+{
+ 0xf2, 0xff, 0x25, /* bnd jmpq *name@GOTPC(%rip) */
+ 0, 0, 0, 0, /* replaced with offset to this symbol in .got. */
+ 0x90 /* nop */
+};
+
+/* .eh_frame covering the .plt section. */
+
+static const bfd_byte elf_x86_64_eh_frame_plt[] =
+{
+#define PLT_CIE_LENGTH 20
+#define PLT_FDE_LENGTH 36
+#define PLT_FDE_START_OFFSET 4 + PLT_CIE_LENGTH + 8
+#define PLT_FDE_LEN_OFFSET 4 + PLT_CIE_LENGTH + 12
+ PLT_CIE_LENGTH, 0, 0, 0, /* CIE length */
+ 0, 0, 0, 0, /* CIE ID */
+ 1, /* CIE version */
+ 'z', 'R', 0, /* Augmentation string */
+ 1, /* Code alignment factor */
+ 0x78, /* Data alignment factor */
+ 16, /* Return address column */
+ 1, /* Augmentation size */
+ DW_EH_PE_pcrel | DW_EH_PE_sdata4, /* FDE encoding */
+ DW_CFA_def_cfa, 7, 8, /* DW_CFA_def_cfa: r7 (rsp) ofs 8 */
+ DW_CFA_offset + 16, 1, /* DW_CFA_offset: r16 (rip) at cfa-8 */
+ DW_CFA_nop, DW_CFA_nop,
+
+ PLT_FDE_LENGTH, 0, 0, 0, /* FDE length */
+ PLT_CIE_LENGTH + 8, 0, 0, 0, /* CIE pointer */
+ 0, 0, 0, 0, /* R_X86_64_PC32 .plt goes here */
+ 0, 0, 0, 0, /* .plt size goes here */
+ 0, /* Augmentation size */
+ DW_CFA_def_cfa_offset, 16, /* DW_CFA_def_cfa_offset: 16 */
+ DW_CFA_advance_loc + 6, /* DW_CFA_advance_loc: 6 to __PLT__+6 */
+ DW_CFA_def_cfa_offset, 24, /* DW_CFA_def_cfa_offset: 24 */
+ DW_CFA_advance_loc + 10, /* DW_CFA_advance_loc: 10 to __PLT__+16 */
+ DW_CFA_def_cfa_expression, /* DW_CFA_def_cfa_expression */
+ 11, /* Block length */
+ DW_OP_breg7, 8, /* DW_OP_breg7 (rsp): 8 */
+ DW_OP_breg16, 0, /* DW_OP_breg16 (rip): 0 */
+ DW_OP_lit15, DW_OP_and, DW_OP_lit11, DW_OP_ge,
+ DW_OP_lit3, DW_OP_shl, DW_OP_plus,
+ DW_CFA_nop, DW_CFA_nop, DW_CFA_nop, DW_CFA_nop
+};
+
+/* Architecture-specific backend data for x86-64. */
+
+struct elf_x86_64_backend_data
+{
+ /* Templates for the initial PLT entry and for subsequent entries. */
+ const bfd_byte *plt0_entry;
+ const bfd_byte *plt_entry;
+ unsigned int plt_entry_size; /* Size of each PLT entry. */
+
+ /* Offsets into plt0_entry that are to be replaced with GOT[1] and GOT[2]. */
+ unsigned int plt0_got1_offset;
+ unsigned int plt0_got2_offset;
+
+ /* Offset of the end of the PC-relative instruction containing
+ plt0_got2_offset. */
+ unsigned int plt0_got2_insn_end;
+
+ /* Offsets into plt_entry that are to be replaced with... */
+ unsigned int plt_got_offset; /* ... address of this symbol in .got. */
+ unsigned int plt_reloc_offset; /* ... offset into relocation table. */
+ unsigned int plt_plt_offset; /* ... offset to start of .plt. */
+
+ /* Length of the PC-relative instruction containing plt_got_offset. */
+ unsigned int plt_got_insn_size;
+
+ /* Offset of the end of the PC-relative jump to plt0_entry. */
+ unsigned int plt_plt_insn_end;
+
+ /* Offset into plt_entry where the initial value of the GOT entry points. */
+ unsigned int plt_lazy_offset;
+
+ /* .eh_frame covering the .plt section. */
+ const bfd_byte *eh_frame_plt;
+ unsigned int eh_frame_plt_size;
+};
+
+#define get_elf_x86_64_arch_data(bed) \
+ ((const struct elf_x86_64_backend_data *) (bed)->arch_data)
+
+#define get_elf_x86_64_backend_data(abfd) \
+ get_elf_x86_64_arch_data (get_elf_backend_data (abfd))
+
+#define GET_PLT_ENTRY_SIZE(abfd) \
+ get_elf_x86_64_backend_data (abfd)->plt_entry_size
+
+/* These are the standard parameters. */
+static const struct elf_x86_64_backend_data elf_x86_64_arch_bed =
+ {
+ elf_x86_64_plt0_entry, /* plt0_entry */
+ elf_x86_64_plt_entry, /* plt_entry */
+ sizeof (elf_x86_64_plt_entry), /* plt_entry_size */
+ 2, /* plt0_got1_offset */
+ 8, /* plt0_got2_offset */
+ 12, /* plt0_got2_insn_end */
+ 2, /* plt_got_offset */
+ 7, /* plt_reloc_offset */
+ 12, /* plt_plt_offset */
+ 6, /* plt_got_insn_size */
+ PLT_ENTRY_SIZE, /* plt_plt_insn_end */
+ 6, /* plt_lazy_offset */
+ elf_x86_64_eh_frame_plt, /* eh_frame_plt */
+ sizeof (elf_x86_64_eh_frame_plt), /* eh_frame_plt_size */
+ };
+
+static const struct elf_x86_64_backend_data elf_x86_64_bnd_arch_bed =
+ {
+ elf_x86_64_bnd_plt0_entry, /* plt0_entry */
+ elf_x86_64_bnd_plt_entry, /* plt_entry */
+ sizeof (elf_x86_64_bnd_plt_entry), /* plt_entry_size */
+ 2, /* plt0_got1_offset */
+ 1+8, /* plt0_got2_offset */
+ 1+12, /* plt0_got2_insn_end */
+ 1+2, /* plt_got_offset */
+ 1, /* plt_reloc_offset */
+ 7, /* plt_plt_offset */
+ 1+6, /* plt_got_insn_size */
+ 11, /* plt_plt_insn_end */
+ 0, /* plt_lazy_offset */
+ elf_x86_64_eh_frame_plt, /* eh_frame_plt */
+ sizeof (elf_x86_64_eh_frame_plt), /* eh_frame_plt_size */
+ };
+
+#define elf_backend_arch_data &elf_x86_64_arch_bed
+
+/* x86-64 ELF linker hash entry. */
+
+struct elf_x86_64_link_hash_entry
+{
+ struct elf_link_hash_entry elf;
+
+ /* Track dynamic relocs copied for this symbol. */
+ struct elf_dyn_relocs *dyn_relocs;
+
+#define GOT_UNKNOWN 0
+#define GOT_NORMAL 1
+#define GOT_TLS_GD 2
+#define GOT_TLS_IE 3
+#define GOT_TLS_GDESC 4
+#define GOT_TLS_GD_BOTH_P(type) \
+ ((type) == (GOT_TLS_GD | GOT_TLS_GDESC))
+#define GOT_TLS_GD_P(type) \
+ ((type) == GOT_TLS_GD || GOT_TLS_GD_BOTH_P (type))
+#define GOT_TLS_GDESC_P(type) \
+ ((type) == GOT_TLS_GDESC || GOT_TLS_GD_BOTH_P (type))
+#define GOT_TLS_GD_ANY_P(type) \
+ (GOT_TLS_GD_P (type) || GOT_TLS_GDESC_P (type))
+ unsigned char tls_type;
+
+ /* TRUE if a weak symbol with a real definition needs a copy reloc.
+ When there is a weak symbol with a real definition, the processor
+ independent code will have arranged for us to see the real
+ definition first. We need to copy the needs_copy bit from the
+ real definition and check it when allowing copy reloc in PIE. */
+ unsigned int needs_copy : 1;
+
+ /* TRUE if symbol has at least one BND relocation. */
+ unsigned int has_bnd_reloc : 1;
+
+ /* Information about the second PLT entry. Filled when has_bnd_reloc is
+ set. */
+ union gotplt_union plt_bnd;
+
+ /* Offset of the GOTPLT entry reserved for the TLS descriptor,
+ starting at the end of the jump table. */
+ bfd_vma tlsdesc_got;
+};
+
+#define elf_x86_64_hash_entry(ent) \
+ ((struct elf_x86_64_link_hash_entry *)(ent))
+
+struct elf_x86_64_obj_tdata
+{
+ struct elf_obj_tdata root;
+
+ /* tls_type for each local got entry. */
+ char *local_got_tls_type;
+
+ /* GOTPLT entries for TLS descriptors. */
+ bfd_vma *local_tlsdesc_gotent;
+};
+
+#define elf_x86_64_tdata(abfd) \
+ ((struct elf_x86_64_obj_tdata *) (abfd)->tdata.any)
+
+#define elf_x86_64_local_got_tls_type(abfd) \
+ (elf_x86_64_tdata (abfd)->local_got_tls_type)
+
+#define elf_x86_64_local_tlsdesc_gotent(abfd) \
+ (elf_x86_64_tdata (abfd)->local_tlsdesc_gotent)
+
+#define is_x86_64_elf(bfd) \
+ (bfd_get_flavour (bfd) == bfd_target_elf_flavour \
+ && elf_tdata (bfd) != NULL \
+ && elf_object_id (bfd) == X86_64_ELF_DATA)
+
+static bfd_boolean
+elf_x86_64_mkobject (bfd *abfd)
+{
+ return bfd_elf_allocate_object (abfd, sizeof (struct elf_x86_64_obj_tdata),
+ X86_64_ELF_DATA);
+}
+
+/* x86-64 ELF linker hash table. */
+
+struct elf_x86_64_link_hash_table
+{
+ struct elf_link_hash_table elf;
+
+ /* Short-cuts to get to dynamic linker sections. */
+ asection *sdynbss;
+ asection *srelbss;
+ asection *plt_eh_frame;
+ asection *plt_bnd;
+
+ union
+ {
+ bfd_signed_vma refcount;
+ bfd_vma offset;
+ } tls_ld_got;
+
+ /* The amount of space used by the jump slots in the GOT. */
+ bfd_vma sgotplt_jump_table_size;
+
+ /* Small local sym cache. */
+ struct sym_cache sym_cache;
+
+ bfd_vma (*r_info) (bfd_vma, bfd_vma);
+ bfd_vma (*r_sym) (bfd_vma);
+ unsigned int pointer_r_type;
+ const char *dynamic_interpreter;
+ int dynamic_interpreter_size;
+
+ /* _TLS_MODULE_BASE_ symbol. */
+ struct bfd_link_hash_entry *tls_module_base;
+
+ /* Used by local STT_GNU_IFUNC symbols. */
+ htab_t loc_hash_table;
+ void * loc_hash_memory;
+
+ /* The offset into splt of the PLT entry for the TLS descriptor
+ resolver. Special values are 0, if not necessary (or not found
+ to be necessary yet), and -1 if needed but not determined
+ yet. */
+ bfd_vma tlsdesc_plt;
+ /* The offset into sgot of the GOT entry used by the PLT entry
+ above. */
+ bfd_vma tlsdesc_got;
+
+ /* The index of the next R_X86_64_JUMP_SLOT entry in .rela.plt. */
+ bfd_vma next_jump_slot_index;
+ /* The index of the next R_X86_64_IRELATIVE entry in .rela.plt. */
+ bfd_vma next_irelative_index;
+};
+
+/* Get the x86-64 ELF linker hash table from a link_info structure. */
+
+#define elf_x86_64_hash_table(p) \
+ (elf_hash_table_id ((struct elf_link_hash_table *) ((p)->hash)) \
+ == X86_64_ELF_DATA ? ((struct elf_x86_64_link_hash_table *) ((p)->hash)) : NULL)
+
+#define elf_x86_64_compute_jump_table_size(htab) \
+ ((htab)->elf.srelplt->reloc_count * GOT_ENTRY_SIZE)
+
+/* Create an entry in an x86-64 ELF linker hash table. */
+
+static struct bfd_hash_entry *
+elf_x86_64_link_hash_newfunc (struct bfd_hash_entry *entry,
+ struct bfd_hash_table *table,
+ const char *string)
+{
+ /* Allocate the structure if it has not already been allocated by a
+ subclass. */
+ if (entry == NULL)
+ {
+ entry = (struct bfd_hash_entry *)
+ bfd_hash_allocate (table,
+ sizeof (struct elf_x86_64_link_hash_entry));
+ if (entry == NULL)
+ return entry;
+ }
+
+ /* Call the allocation method of the superclass. */
+ entry = _bfd_elf_link_hash_newfunc (entry, table, string);
+ if (entry != NULL)
+ {
+ struct elf_x86_64_link_hash_entry *eh;
+
+ eh = (struct elf_x86_64_link_hash_entry *) entry;
+ eh->dyn_relocs = NULL;
+ eh->tls_type = GOT_UNKNOWN;
+ eh->needs_copy = 0;
+ eh->has_bnd_reloc = 0;
+ eh->plt_bnd.offset = (bfd_vma) -1;
+ eh->tlsdesc_got = (bfd_vma) -1;
+ }
+
+ return entry;
+}
+
+/* Compute a hash of a local hash entry. We use elf_link_hash_entry
+ for local symbol so that we can handle local STT_GNU_IFUNC symbols
+ as global symbol. We reuse indx and dynstr_index for local symbol
+ hash since they aren't used by global symbols in this backend. */
+
+static hashval_t
+elf_x86_64_local_htab_hash (const void *ptr)
+{
+ struct elf_link_hash_entry *h
+ = (struct elf_link_hash_entry *) ptr;
+ return ELF_LOCAL_SYMBOL_HASH (h->indx, h->dynstr_index);
+}
+
+/* Compare local hash entries. */
+
+static int
+elf_x86_64_local_htab_eq (const void *ptr1, const void *ptr2)
+{
+ struct elf_link_hash_entry *h1
+ = (struct elf_link_hash_entry *) ptr1;
+ struct elf_link_hash_entry *h2
+ = (struct elf_link_hash_entry *) ptr2;
+
+ return h1->indx == h2->indx && h1->dynstr_index == h2->dynstr_index;
+}
+
+/* Find and/or create a hash entry for local symbol. */
+
+static struct elf_link_hash_entry *
+elf_x86_64_get_local_sym_hash (struct elf_x86_64_link_hash_table *htab,
+ bfd *abfd, const Elf_Internal_Rela *rel,
+ bfd_boolean create)
+{
+ struct elf_x86_64_link_hash_entry e, *ret;
+ asection *sec = abfd->sections;
+ hashval_t h = ELF_LOCAL_SYMBOL_HASH (sec->id,
+ htab->r_sym (rel->r_info));
+ void **slot;
+
+ e.elf.indx = sec->id;
+ e.elf.dynstr_index = htab->r_sym (rel->r_info);
+ slot = htab_find_slot_with_hash (htab->loc_hash_table, &e, h,
+ create ? INSERT : NO_INSERT);
+
+ if (!slot)
+ return NULL;
+
+ if (*slot)
+ {
+ ret = (struct elf_x86_64_link_hash_entry *) *slot;
+ return &ret->elf;
+ }
+
+ ret = (struct elf_x86_64_link_hash_entry *)
+ objalloc_alloc ((struct objalloc *) htab->loc_hash_memory,
+ sizeof (struct elf_x86_64_link_hash_entry));
+ if (ret)
+ {
+ memset (ret, 0, sizeof (*ret));
+ ret->elf.indx = sec->id;
+ ret->elf.dynstr_index = htab->r_sym (rel->r_info);
+ ret->elf.dynindx = -1;
+ *slot = ret;
+ }
+ return &ret->elf;
+}
+
+/* Destroy an X86-64 ELF linker hash table. */
+
+static void
+elf_x86_64_link_hash_table_free (bfd *obfd)
+{
+ struct elf_x86_64_link_hash_table *htab
+ = (struct elf_x86_64_link_hash_table *) obfd->link.hash;
+
+ if (htab->loc_hash_table)
+ htab_delete (htab->loc_hash_table);
+ if (htab->loc_hash_memory)
+ objalloc_free ((struct objalloc *) htab->loc_hash_memory);
+ _bfd_elf_link_hash_table_free (obfd);
+}
+
+/* Create an X86-64 ELF linker hash table. */
+
+static struct bfd_link_hash_table *
+elf_x86_64_link_hash_table_create (bfd *abfd)
+{
+ struct elf_x86_64_link_hash_table *ret;
+ bfd_size_type amt = sizeof (struct elf_x86_64_link_hash_table);
+
+ ret = (struct elf_x86_64_link_hash_table *) bfd_zmalloc (amt);
+ if (ret == NULL)
+ return NULL;
+
+ if (!_bfd_elf_link_hash_table_init (&ret->elf, abfd,
+ elf_x86_64_link_hash_newfunc,
+ sizeof (struct elf_x86_64_link_hash_entry),
+ X86_64_ELF_DATA))
+ {
+ free (ret);
+ return NULL;
+ }
+
+ if (ABI_64_P (abfd))
+ {
+ ret->r_info = elf64_r_info;
+ ret->r_sym = elf64_r_sym;
+ ret->pointer_r_type = R_X86_64_64;
+ ret->dynamic_interpreter = ELF64_DYNAMIC_INTERPRETER;
+ ret->dynamic_interpreter_size = sizeof ELF64_DYNAMIC_INTERPRETER;
+ }
+ else
+ {
+ ret->r_info = elf32_r_info;
+ ret->r_sym = elf32_r_sym;
+ ret->pointer_r_type = R_X86_64_32;
+ ret->dynamic_interpreter = ELF32_DYNAMIC_INTERPRETER;
+ ret->dynamic_interpreter_size = sizeof ELF32_DYNAMIC_INTERPRETER;
+ }
+
+ ret->loc_hash_table = htab_try_create (1024,
+ elf_x86_64_local_htab_hash,
+ elf_x86_64_local_htab_eq,
+ NULL);
+ ret->loc_hash_memory = objalloc_create ();
+ if (!ret->loc_hash_table || !ret->loc_hash_memory)
+ {
+ elf_x86_64_link_hash_table_free (abfd);
+ return NULL;
+ }
+ ret->elf.root.hash_table_free = elf_x86_64_link_hash_table_free;
+
+ return &ret->elf.root;
+}
+
+/* Create .plt, .rela.plt, .got, .got.plt, .rela.got, .dynbss, and
+ .rela.bss sections in DYNOBJ, and set up shortcuts to them in our
+ hash table. */
+
+static bfd_boolean
+elf_x86_64_create_dynamic_sections (bfd *dynobj,
+ struct bfd_link_info *info)
+{
+ struct elf_x86_64_link_hash_table *htab;
+
+ if (!_bfd_elf_create_dynamic_sections (dynobj, info))
+ return FALSE;
+
+ htab = elf_x86_64_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ htab->sdynbss = bfd_get_linker_section (dynobj, ".dynbss");
+ if (!htab->sdynbss)
+ abort ();
+
+ if (info->executable)
+ {
+ /* Always allow copy relocs for building executables. */
+ asection *s = bfd_get_linker_section (dynobj, ".rela.bss");
+ if (s == NULL)
+ {
+ const struct elf_backend_data *bed = get_elf_backend_data (dynobj);
+ s = bfd_make_section_anyway_with_flags (dynobj,
+ ".rela.bss",
+ (bed->dynamic_sec_flags
+ | SEC_READONLY));
+ if (s == NULL
+ || ! bfd_set_section_alignment (dynobj, s,
+ bed->s->log_file_align))
+ return FALSE;
+ }
+ htab->srelbss = s;
+ }
+
+ if (!info->no_ld_generated_unwind_info
+ && htab->plt_eh_frame == NULL
+ && htab->elf.splt != NULL)
+ {
+ flagword flags = (SEC_ALLOC | SEC_LOAD | SEC_READONLY
+ | SEC_HAS_CONTENTS | SEC_IN_MEMORY
+ | SEC_LINKER_CREATED);
+ htab->plt_eh_frame
+ = bfd_make_section_anyway_with_flags (dynobj, ".eh_frame", flags);
+ if (htab->plt_eh_frame == NULL
+ || !bfd_set_section_alignment (dynobj, htab->plt_eh_frame, 3))
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/* Copy the extra info we tack onto an elf_link_hash_entry. */
+
+static void
+elf_x86_64_copy_indirect_symbol (struct bfd_link_info *info,
+ struct elf_link_hash_entry *dir,
+ struct elf_link_hash_entry *ind)
+{
+ struct elf_x86_64_link_hash_entry *edir, *eind;
+
+ edir = (struct elf_x86_64_link_hash_entry *) dir;
+ eind = (struct elf_x86_64_link_hash_entry *) ind;
+
+ if (!edir->has_bnd_reloc)
+ edir->has_bnd_reloc = eind->has_bnd_reloc;
+
+ if (eind->dyn_relocs != NULL)
+ {
+ if (edir->dyn_relocs != NULL)
+ {
+ struct elf_dyn_relocs **pp;
+ struct elf_dyn_relocs *p;
+
+ /* Add reloc counts against the indirect sym to the direct sym
+ list. Merge any entries against the same section. */
+ for (pp = &eind->dyn_relocs; (p = *pp) != NULL; )
+ {
+ struct elf_dyn_relocs *q;
+
+ for (q = edir->dyn_relocs; q != NULL; q = q->next)
+ if (q->sec == p->sec)
+ {
+ q->pc_count += p->pc_count;
+ q->count += p->count;
+ *pp = p->next;
+ break;
+ }
+ if (q == NULL)
+ pp = &p->next;
+ }
+ *pp = edir->dyn_relocs;
+ }
+
+ edir->dyn_relocs = eind->dyn_relocs;
+ eind->dyn_relocs = NULL;
+ }
+
+ if (ind->root.type == bfd_link_hash_indirect
+ && dir->got.refcount <= 0)
+ {
+ edir->tls_type = eind->tls_type;
+ eind->tls_type = GOT_UNKNOWN;
+ }
+
+ if (ELIMINATE_COPY_RELOCS
+ && ind->root.type != bfd_link_hash_indirect
+ && dir->dynamic_adjusted)
+ {
+ /* If called to transfer flags for a weakdef during processing
+ of elf_adjust_dynamic_symbol, don't copy non_got_ref.
+ We clear it ourselves for ELIMINATE_COPY_RELOCS. */
+ dir->ref_dynamic |= ind->ref_dynamic;
+ dir->ref_regular |= ind->ref_regular;
+ dir->ref_regular_nonweak |= ind->ref_regular_nonweak;
+ dir->needs_plt |= ind->needs_plt;
+ dir->pointer_equality_needed |= ind->pointer_equality_needed;
+ }
+ else
+ _bfd_elf_link_hash_copy_indirect (info, dir, ind);
+}
+
+static bfd_boolean
+elf64_x86_64_elf_object_p (bfd *abfd)
+{
+ /* Set the right machine number for an x86-64 elf64 file. */
+ bfd_default_set_arch_mach (abfd, bfd_arch_i386, bfd_mach_x86_64);
+ return TRUE;
+}
+
+static bfd_boolean
+elf32_x86_64_elf_object_p (bfd *abfd)
+{
+ /* Set the right machine number for an x86-64 elf32 file. */
+ bfd_default_set_arch_mach (abfd, bfd_arch_i386, bfd_mach_x64_32);
+ return TRUE;
+}
+
+/* Return TRUE if the TLS access code sequence support transition
+ from R_TYPE. */
+
+static bfd_boolean
+elf_x86_64_check_tls_transition (bfd *abfd,
+ struct bfd_link_info *info,
+ asection *sec,
+ bfd_byte *contents,
+ Elf_Internal_Shdr *symtab_hdr,
+ struct elf_link_hash_entry **sym_hashes,
+ unsigned int r_type,
+ const Elf_Internal_Rela *rel,
+ const Elf_Internal_Rela *relend)
+{
+ unsigned int val;
+ unsigned long r_symndx;
+ bfd_boolean largepic = FALSE;
+ struct elf_link_hash_entry *h;
+ bfd_vma offset;
+ struct elf_x86_64_link_hash_table *htab;
+
+ /* 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
+ {
+ /* FIXME: How to better handle error condition? */
+ if (!bfd_malloc_and_get_section (abfd, sec, &contents))
+ return FALSE;
+
+ /* Cache the section contents for elf_link_input_bfd. */
+ elf_section_data (sec)->this_hdr.contents = contents;
+ }
+ }
+
+ htab = elf_x86_64_hash_table (info);
+ offset = rel->r_offset;
+ switch (r_type)
+ {
+ case R_X86_64_TLSGD:
+ case R_X86_64_TLSLD:
+ if ((rel + 1) >= relend)
+ return FALSE;
+
+ if (r_type == R_X86_64_TLSGD)
+ {
+ /* Check transition from GD access model. For 64bit, only
+ .byte 0x66; leaq foo@tlsgd(%rip), %rdi
+ .word 0x6666; rex64; call __tls_get_addr
+ can transit to different access model. For 32bit, only
+ leaq foo@tlsgd(%rip), %rdi
+ .word 0x6666; rex64; call __tls_get_addr
+ can transit to different access model. For largepic
+ we also support:
+ leaq foo@tlsgd(%rip), %rdi
+ movabsq $__tls_get_addr@pltoff, %rax
+ addq $rbx, %rax
+ call *%rax. */
+
+ static const unsigned char call[] = { 0x66, 0x66, 0x48, 0xe8 };
+ static const unsigned char leaq[] = { 0x66, 0x48, 0x8d, 0x3d };
+
+ if ((offset + 12) > sec->size)
+ return FALSE;
+
+ if (memcmp (contents + offset + 4, call, 4) != 0)
+ {
+ if (!ABI_64_P (abfd)
+ || (offset + 19) > sec->size
+ || offset < 3
+ || memcmp (contents + offset - 3, leaq + 1, 3) != 0
+ || memcmp (contents + offset + 4, "\x48\xb8", 2) != 0
+ || memcmp (contents + offset + 14, "\x48\x01\xd8\xff\xd0", 5)
+ != 0)
+ return FALSE;
+ largepic = TRUE;
+ }
+ else if (ABI_64_P (abfd))
+ {
+ if (offset < 4
+ || memcmp (contents + offset - 4, leaq, 4) != 0)
+ return FALSE;
+ }
+ else
+ {
+ if (offset < 3
+ || memcmp (contents + offset - 3, leaq + 1, 3) != 0)
+ return FALSE;
+ }
+ }
+ else
+ {
+ /* Check transition from LD access model. Only
+ leaq foo@tlsld(%rip), %rdi;
+ call __tls_get_addr
+ can transit to different access model. For largepic
+ we also support:
+ leaq foo@tlsld(%rip), %rdi
+ movabsq $__tls_get_addr@pltoff, %rax
+ addq $rbx, %rax
+ call *%rax. */
+
+ static const unsigned char lea[] = { 0x48, 0x8d, 0x3d };
+
+ if (offset < 3 || (offset + 9) > sec->size)
+ return FALSE;
+
+ if (memcmp (contents + offset - 3, lea, 3) != 0)
+ return FALSE;
+
+ if (0xe8 != *(contents + offset + 4))
+ {
+ if (!ABI_64_P (abfd)
+ || (offset + 19) > sec->size
+ || memcmp (contents + offset + 4, "\x48\xb8", 2) != 0
+ || memcmp (contents + offset + 14, "\x48\x01\xd8\xff\xd0", 5)
+ != 0)
+ return FALSE;
+ largepic = TRUE;
+ }
+ }
+
+ r_symndx = htab->r_sym (rel[1].r_info);
+ if (r_symndx < symtab_hdr->sh_info)
+ return FALSE;
+
+ h = sym_hashes[r_symndx - symtab_hdr->sh_info];
+ /* Use strncmp to check __tls_get_addr since __tls_get_addr
+ may be versioned. */
+ return (h != NULL
+ && h->root.root.string != NULL
+ && (largepic
+ ? ELF32_R_TYPE (rel[1].r_info) == R_X86_64_PLTOFF64
+ : (ELF32_R_TYPE (rel[1].r_info) == R_X86_64_PC32
+ || ELF32_R_TYPE (rel[1].r_info) == R_X86_64_PLT32))
+ && (strncmp (h->root.root.string,
+ "__tls_get_addr", 14) == 0));
+
+ case R_X86_64_GOTTPOFF:
+ /* Check transition from IE access model:
+ mov foo@gottpoff(%rip), %reg
+ add foo@gottpoff(%rip), %reg
+ */
+
+ /* Check REX prefix first. */
+ if (offset >= 3 && (offset + 4) <= sec->size)
+ {
+ val = bfd_get_8 (abfd, contents + offset - 3);
+ if (val != 0x48 && val != 0x4c)
+ {
+ /* X32 may have 0x44 REX prefix or no REX prefix. */
+ if (ABI_64_P (abfd))
+ return FALSE;
+ }
+ }
+ else
+ {
+ /* X32 may not have any REX prefix. */
+ if (ABI_64_P (abfd))
+ return FALSE;
+ if (offset < 2 || (offset + 3) > sec->size)
+ return FALSE;
+ }
+
+ val = bfd_get_8 (abfd, contents + offset - 2);
+ if (val != 0x8b && val != 0x03)
+ return FALSE;
+
+ val = bfd_get_8 (abfd, contents + offset - 1);
+ return (val & 0xc7) == 5;
+
+ case R_X86_64_GOTPC32_TLSDESC:
+ /* Check transition from GDesc access model:
+ leaq x@tlsdesc(%rip), %rax
+
+ Make sure it's a leaq adding rip to a 32-bit offset
+ into any register, although it's probably almost always
+ going to be rax. */
+
+ if (offset < 3 || (offset + 4) > sec->size)
+ return FALSE;
+
+ val = bfd_get_8 (abfd, contents + offset - 3);
+ if ((val & 0xfb) != 0x48)
+ return FALSE;
+
+ if (bfd_get_8 (abfd, contents + offset - 2) != 0x8d)
+ return FALSE;
+
+ val = bfd_get_8 (abfd, contents + offset - 1);
+ return (val & 0xc7) == 0x05;
+
+ case R_X86_64_TLSDESC_CALL:
+ /* Check transition from GDesc access model:
+ call *x@tlsdesc(%rax)
+ */
+ if (offset + 2 <= sec->size)
+ {
+ /* Make sure that it's a call *x@tlsdesc(%rax). */
+ static const unsigned char call[] = { 0xff, 0x10 };
+ return memcmp (contents + offset, call, 2) == 0;
+ }
+
+ return FALSE;
+
+ default:
+ abort ();
+ }
+}
+
+/* Return TRUE if the TLS access transition is OK or no transition
+ will be performed. Update R_TYPE if there is a transition. */
+
+static bfd_boolean
+elf_x86_64_tls_transition (struct bfd_link_info *info, bfd *abfd,
+ asection *sec, bfd_byte *contents,
+ Elf_Internal_Shdr *symtab_hdr,
+ struct elf_link_hash_entry **sym_hashes,
+ unsigned int *r_type, int tls_type,
+ const Elf_Internal_Rela *rel,
+ const Elf_Internal_Rela *relend,
+ struct elf_link_hash_entry *h,
+ unsigned long r_symndx)
+{
+ unsigned int from_type = *r_type;
+ unsigned int to_type = from_type;
+ bfd_boolean check = TRUE;
+
+ /* Skip TLS transition for functions. */
+ if (h != NULL
+ && (h->type == STT_FUNC
+ || h->type == STT_GNU_IFUNC))
+ return TRUE;
+
+ switch (from_type)
+ {
+ case R_X86_64_TLSGD:
+ case R_X86_64_GOTPC32_TLSDESC:
+ case R_X86_64_TLSDESC_CALL:
+ case R_X86_64_GOTTPOFF:
+ if (info->executable)
+ {
+ if (h == NULL)
+ to_type = R_X86_64_TPOFF32;
+ else
+ to_type = R_X86_64_GOTTPOFF;
+ }
+
+ /* When we are called from elf_x86_64_relocate_section,
+ CONTENTS isn't NULL and there may be additional transitions
+ based on TLS_TYPE. */
+ if (contents != NULL)
+ {
+ unsigned int new_to_type = to_type;
+
+ if (info->executable
+ && h != NULL
+ && h->dynindx == -1
+ && tls_type == GOT_TLS_IE)
+ new_to_type = R_X86_64_TPOFF32;
+
+ if (to_type == R_X86_64_TLSGD
+ || to_type == R_X86_64_GOTPC32_TLSDESC
+ || to_type == R_X86_64_TLSDESC_CALL)
+ {
+ if (tls_type == GOT_TLS_IE)
+ new_to_type = R_X86_64_GOTTPOFF;
+ }
+
+ /* We checked the transition before when we were called from
+ elf_x86_64_check_relocs. We only want to check the new
+ transition which hasn't been checked before. */
+ check = new_to_type != to_type && from_type == to_type;
+ to_type = new_to_type;
+ }
+
+ break;
+
+ case R_X86_64_TLSLD:
+ if (info->executable)
+ to_type = R_X86_64_TPOFF32;
+ break;
+
+ default:
+ return TRUE;
+ }
+
+ /* Return TRUE if there is no transition. */
+ if (from_type == to_type)
+ return TRUE;
+
+ /* Check if the transition can be performed. */
+ if (check
+ && ! elf_x86_64_check_tls_transition (abfd, info, sec, contents,
+ symtab_hdr, sym_hashes,
+ from_type, rel, relend))
+ {
+ reloc_howto_type *from, *to;
+ const char *name;
+
+ from = elf_x86_64_rtype_to_howto (abfd, from_type);
+ to = elf_x86_64_rtype_to_howto (abfd, to_type);
+
+ if (h)
+ name = h->root.root.string;
+ else
+ {
+ struct elf_x86_64_link_hash_table *htab;
+
+ htab = elf_x86_64_hash_table (info);
+ if (htab == NULL)
+ name = "*unknown*";
+ else
+ {
+ Elf_Internal_Sym *isym;
+
+ isym = bfd_sym_from_r_symndx (&htab->sym_cache,
+ abfd, r_symndx);
+ name = bfd_elf_sym_name (abfd, symtab_hdr, isym, NULL);
+ }
+ }
+
+ (*_bfd_error_handler)
+ (_("%B: TLS transition from %s to %s against `%s' at 0x%lx "
+ "in section `%A' failed"),
+ abfd, sec, from->name, to->name, name,
+ (unsigned long) rel->r_offset);
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+
+ *r_type = to_type;
+ return TRUE;
+}
+
+/* Look through the relocs for a section during the first phase, and
+ calculate needed space in the global offset table, procedure
+ linkage table, and dynamic reloc sections. */
+
+static bfd_boolean
+elf_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info,
+ asection *sec,
+ const Elf_Internal_Rela *relocs)
+{
+ struct elf_x86_64_link_hash_table *htab;
+ 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;
+
+ if (info->relocatable)
+ return TRUE;
+
+ BFD_ASSERT (is_x86_64_elf (abfd));
+
+ htab = elf_x86_64_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ symtab_hdr = &elf_symtab_hdr (abfd);
+ sym_hashes = elf_sym_hashes (abfd);
+
+ sreloc = NULL;
+
+ rel_end = relocs + sec->reloc_count;
+ for (rel = relocs; rel < rel_end; rel++)
+ {
+ unsigned int r_type;
+ unsigned long r_symndx;
+ struct elf_link_hash_entry *h;
+ Elf_Internal_Sym *isym;
+ const char *name;
+ bfd_boolean size_reloc;
+
+ r_symndx = htab->r_sym (rel->r_info);
+ r_type = ELF32_R_TYPE (rel->r_info);
+
+ if (r_symndx >= NUM_SHDR_ENTRIES (symtab_hdr))
+ {
+ (*_bfd_error_handler) (_("%B: bad symbol index: %d"),
+ abfd, r_symndx);
+ return FALSE;
+ }
+
+ if (r_symndx < symtab_hdr->sh_info)
+ {
+ /* A local symbol. */
+ isym = bfd_sym_from_r_symndx (&htab->sym_cache,
+ abfd, r_symndx);
+ if (isym == NULL)
+ return FALSE;
+
+ /* Check relocation against local STT_GNU_IFUNC symbol. */
+ if (ELF_ST_TYPE (isym->st_info) == STT_GNU_IFUNC)
+ {
+ h = elf_x86_64_get_local_sym_hash (htab, abfd, rel,
+ TRUE);
+ if (h == NULL)
+ return FALSE;
+
+ /* Fake a STT_GNU_IFUNC symbol. */
+ h->type = STT_GNU_IFUNC;
+ h->def_regular = 1;
+ h->ref_regular = 1;
+ h->forced_local = 1;
+ h->root.type = bfd_link_hash_defined;
+ }
+ else
+ h = NULL;
+ }
+ else
+ {
+ isym = NULL;
+ 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;
+ }
+
+ /* Check invalid x32 relocations. */
+ if (!ABI_64_P (abfd))
+ switch (r_type)
+ {
+ default:
+ break;
+
+ case R_X86_64_DTPOFF64:
+ case R_X86_64_TPOFF64:
+ case R_X86_64_PC64:
+ case R_X86_64_GOTOFF64:
+ case R_X86_64_GOT64:
+ case R_X86_64_GOTPCREL64:
+ case R_X86_64_GOTPC64:
+ case R_X86_64_GOTPLT64:
+ case R_X86_64_PLTOFF64:
+ {
+ if (h)
+ name = h->root.root.string;
+ else
+ name = bfd_elf_sym_name (abfd, symtab_hdr, isym,
+ NULL);
+ (*_bfd_error_handler)
+ (_("%B: relocation %s against symbol `%s' isn't "
+ "supported in x32 mode"), abfd,
+ x86_64_elf_howto_table[r_type].name, name);
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+ break;
+ }
+
+ if (h != NULL)
+ {
+ /* Create the ifunc sections for static executables. If we
+ never see an indirect function symbol nor we are building
+ a static executable, those sections will be empty and
+ won't appear in output. */
+ switch (r_type)
+ {
+ default:
+ break;
+
+ case R_X86_64_PC32_BND:
+ case R_X86_64_PLT32_BND:
+ case R_X86_64_PC32:
+ case R_X86_64_PLT32:
+ case R_X86_64_32:
+ case R_X86_64_64:
+ /* MPX PLT is supported only if elf_x86_64_arch_bed
+ is used in 64-bit mode. */
+ if (ABI_64_P (abfd)
+ && info->bndplt
+ && (get_elf_x86_64_backend_data (abfd)
+ == &elf_x86_64_arch_bed))
+ {
+ elf_x86_64_hash_entry (h)->has_bnd_reloc = 1;
+
+ /* Create the second PLT for Intel MPX support. */
+ if (htab->plt_bnd == NULL)
+ {
+ unsigned int plt_bnd_align;
+ const struct elf_backend_data *bed;
+
+ bed = get_elf_backend_data (info->output_bfd);
+ switch (sizeof (elf_x86_64_bnd_plt2_entry))
+ {
+ case 8:
+ plt_bnd_align = 3;
+ break;
+ case 16:
+ plt_bnd_align = 4;
+ break;
+ default:
+ abort ();
+ }
+
+ if (htab->elf.dynobj == NULL)
+ htab->elf.dynobj = abfd;
+ htab->plt_bnd
+ = bfd_make_section_anyway_with_flags (htab->elf.dynobj,
+ ".plt.bnd",
+ (bed->dynamic_sec_flags
+ | SEC_ALLOC
+ | SEC_CODE
+ | SEC_LOAD
+ | SEC_READONLY));
+ if (htab->plt_bnd == NULL
+ || !bfd_set_section_alignment (htab->elf.dynobj,
+ htab->plt_bnd,
+ plt_bnd_align))
+ return FALSE;
+ }
+ }
+
+ case R_X86_64_32S:
+ case R_X86_64_PC64:
+ case R_X86_64_GOTPCREL:
+ case R_X86_64_GOTPCREL64:
+ if (htab->elf.dynobj == NULL)
+ htab->elf.dynobj = abfd;
+ if (!_bfd_elf_create_ifunc_sections (htab->elf.dynobj, info))
+ return FALSE;
+ break;
+ }
+
+ /* It is referenced by a non-shared object. */
+ h->ref_regular = 1;
+ h->root.non_ir_ref = 1;
+ }
+
+ if (! elf_x86_64_tls_transition (info, abfd, sec, NULL,
+ symtab_hdr, sym_hashes,
+ &r_type, GOT_UNKNOWN,
+ rel, rel_end, h, r_symndx))
+ return FALSE;
+
+ switch (r_type)
+ {
+ case R_X86_64_TLSLD:
+ htab->tls_ld_got.refcount += 1;
+ goto create_got;
+
+ case R_X86_64_TPOFF32:
+ if (!info->executable && ABI_64_P (abfd))
+ {
+ if (h)
+ name = h->root.root.string;
+ else
+ name = bfd_elf_sym_name (abfd, symtab_hdr, isym,
+ NULL);
+ (*_bfd_error_handler)
+ (_("%B: relocation %s against `%s' can not be used when making a shared object; recompile with -fPIC"),
+ abfd,
+ x86_64_elf_howto_table[r_type].name, name);
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+ break;
+
+ case R_X86_64_GOTTPOFF:
+ if (!info->executable)
+ info->flags |= DF_STATIC_TLS;
+ /* Fall through */
+
+ case R_X86_64_GOT32:
+ case R_X86_64_GOTPCREL:
+ case R_X86_64_TLSGD:
+ case R_X86_64_GOT64:
+ case R_X86_64_GOTPCREL64:
+ case R_X86_64_GOTPLT64:
+ case R_X86_64_GOTPC32_TLSDESC:
+ case R_X86_64_TLSDESC_CALL:
+ /* This symbol requires a global offset table entry. */
+ {
+ int tls_type, old_tls_type;
+
+ switch (r_type)
+ {
+ default: tls_type = GOT_NORMAL; break;
+ case R_X86_64_TLSGD: tls_type = GOT_TLS_GD; break;
+ case R_X86_64_GOTTPOFF: tls_type = GOT_TLS_IE; break;
+ case R_X86_64_GOTPC32_TLSDESC:
+ case R_X86_64_TLSDESC_CALL:
+ tls_type = GOT_TLS_GDESC; break;
+ }
+
+ if (h != NULL)
+ {
+ if (r_type == R_X86_64_GOTPLT64)
+ {
+ /* This relocation indicates that we also need
+ a PLT entry, as this is a function. We don't need
+ a PLT entry for local symbols. */
+ h->needs_plt = 1;
+ h->plt.refcount += 1;
+ }
+ h->got.refcount += 1;
+ old_tls_type = elf_x86_64_hash_entry (h)->tls_type;
+ }
+ else
+ {
+ bfd_signed_vma *local_got_refcounts;
+
+ /* This is a global offset table entry for a local symbol. */
+ local_got_refcounts = elf_local_got_refcounts (abfd);
+ if (local_got_refcounts == NULL)
+ {
+ bfd_size_type size;
+
+ size = symtab_hdr->sh_info;
+ size *= sizeof (bfd_signed_vma)
+ + sizeof (bfd_vma) + sizeof (char);
+ local_got_refcounts = ((bfd_signed_vma *)
+ bfd_zalloc (abfd, size));
+ if (local_got_refcounts == NULL)
+ return FALSE;
+ elf_local_got_refcounts (abfd) = local_got_refcounts;
+ elf_x86_64_local_tlsdesc_gotent (abfd)
+ = (bfd_vma *) (local_got_refcounts + symtab_hdr->sh_info);
+ elf_x86_64_local_got_tls_type (abfd)
+ = (char *) (local_got_refcounts + 2 * symtab_hdr->sh_info);
+ }
+ local_got_refcounts[r_symndx] += 1;
+ old_tls_type
+ = elf_x86_64_local_got_tls_type (abfd) [r_symndx];
+ }
+
+ /* If a TLS symbol is accessed using IE at least once,
+ there is no point to use dynamic model for it. */
+ if (old_tls_type != tls_type && old_tls_type != GOT_UNKNOWN
+ && (! GOT_TLS_GD_ANY_P (old_tls_type)
+ || tls_type != GOT_TLS_IE))
+ {
+ if (old_tls_type == GOT_TLS_IE && GOT_TLS_GD_ANY_P (tls_type))
+ tls_type = old_tls_type;
+ else if (GOT_TLS_GD_ANY_P (old_tls_type)
+ && GOT_TLS_GD_ANY_P (tls_type))
+ tls_type |= old_tls_type;
+ else
+ {
+ if (h)
+ name = h->root.root.string;
+ else
+ name = bfd_elf_sym_name (abfd, symtab_hdr,
+ isym, NULL);
+ (*_bfd_error_handler)
+ (_("%B: '%s' accessed both as normal and thread local symbol"),
+ abfd, name);
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+ }
+
+ if (old_tls_type != tls_type)
+ {
+ if (h != NULL)
+ elf_x86_64_hash_entry (h)->tls_type = tls_type;
+ else
+ elf_x86_64_local_got_tls_type (abfd) [r_symndx] = tls_type;
+ }
+ }
+ /* Fall through */
+
+ case R_X86_64_GOTOFF64:
+ case R_X86_64_GOTPC32:
+ case R_X86_64_GOTPC64:
+ create_got:
+ if (htab->elf.sgot == NULL)
+ {
+ if (htab->elf.dynobj == NULL)
+ htab->elf.dynobj = abfd;
+ if (!_bfd_elf_create_got_section (htab->elf.dynobj,
+ info))
+ return FALSE;
+ }
+ break;
+
+ case R_X86_64_PLT32:
+ case R_X86_64_PLT32_BND:
+ /* 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->needs_plt = 1;
+ h->plt.refcount += 1;
+ break;
+
+ case R_X86_64_PLTOFF64:
+ /* This tries to form the 'address' of a function relative
+ to GOT. For global symbols we need a PLT entry. */
+ if (h != NULL)
+ {
+ h->needs_plt = 1;
+ h->plt.refcount += 1;
+ }
+ goto create_got;
+
+ case R_X86_64_SIZE32:
+ case R_X86_64_SIZE64:
+ size_reloc = TRUE;
+ goto do_size;
+
+ case R_X86_64_32:
+ if (!ABI_64_P (abfd))
+ goto pointer;
+ case R_X86_64_8:
+ case R_X86_64_16:
+ case R_X86_64_32S:
+ /* Let's help debug shared library creation. These relocs
+ cannot be used in shared libs. Don't error out for
+ sections we don't care about, such as debug sections or
+ non-constant sections. */
+ if (info->shared
+ && (sec->flags & SEC_ALLOC) != 0
+ && (sec->flags & SEC_READONLY) != 0)
+ {
+ if (h)
+ name = h->root.root.string;
+ else
+ name = bfd_elf_sym_name (abfd, symtab_hdr, isym, NULL);
+ (*_bfd_error_handler)
+ (_("%B: relocation %s against `%s' can not be used when making a shared object; recompile with -fPIC"),
+ abfd, x86_64_elf_howto_table[r_type].name, name);
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+ /* Fall through. */
+
+ case R_X86_64_PC8:
+ case R_X86_64_PC16:
+ case R_X86_64_PC32:
+ case R_X86_64_PC32_BND:
+ case R_X86_64_PC64:
+ case R_X86_64_64:
+pointer:
+ if (h != NULL && info->executable)
+ {
+ /* If this reloc is in a read-only section, we might
+ need a copy reloc. We can't check reliably at this
+ stage whether the section is read-only, as input
+ sections have not yet been mapped to output sections.
+ Tentatively set the flag for now, and correct in
+ adjust_dynamic_symbol. */
+ h->non_got_ref = 1;
+
+ /* We may need a .plt entry if the function this reloc
+ refers to is in a shared lib. */
+ h->plt.refcount += 1;
+ if (r_type != R_X86_64_PC32
+ && r_type != R_X86_64_PC32_BND
+ && r_type != R_X86_64_PC64)
+ h->pointer_equality_needed = 1;
+ }
+
+ size_reloc = FALSE;
+do_size:
+ /* 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). In case of a weak definition,
+ DEF_REGULAR may be cleared later by a strong definition in
+ a shared library. We account for that possibility below by
+ storing information in the relocs_copied field of the hash
+ table entry. A similar situation occurs when creating
+ shared libraries and symbol visibility changes render the
+ symbol local.
+
+ If on the other hand, we are creating an executable, we
+ may need to keep relocations for symbols satisfied by a
+ dynamic library if we manage to avoid copy relocs for the
+ symbol. */
+ if ((info->shared
+ && (sec->flags & SEC_ALLOC) != 0
+ && (! IS_X86_64_PCREL_TYPE (r_type)
+ || (h != NULL
+ && (! SYMBOLIC_BIND (info, h)
+ || h->root.type == bfd_link_hash_defweak
+ || !h->def_regular))))
+ || (ELIMINATE_COPY_RELOCS
+ && !info->shared
+ && (sec->flags & SEC_ALLOC) != 0
+ && h != NULL
+ && (h->root.type == bfd_link_hash_defweak
+ || !h->def_regular)))
+ {
+ struct elf_dyn_relocs *p;
+ struct elf_dyn_relocs **head;
+
+ /* We must copy these reloc types into the output file.
+ Create a reloc section in dynobj and make room for
+ this reloc. */
+ if (sreloc == NULL)
+ {
+ if (htab->elf.dynobj == NULL)
+ htab->elf.dynobj = abfd;
+
+ sreloc = _bfd_elf_make_dynamic_reloc_section
+ (sec, htab->elf.dynobj, ABI_64_P (abfd) ? 3 : 2,
+ abfd, /*rela?*/ TRUE);
+
+ if (sreloc == NULL)
+ return FALSE;
+ }
+
+ /* If this is a global symbol, we count the number of
+ relocations we need for this symbol. */
+ if (h != NULL)
+ {
+ head = &((struct elf_x86_64_link_hash_entry *) h)->dyn_relocs;
+ }
+ else
+ {
+ /* Track dynamic relocs needed for local syms too.
+ We really need local syms available to do this
+ easily. Oh well. */
+ asection *s;
+ void **vpp;
+
+ isym = bfd_sym_from_r_symndx (&htab->sym_cache,
+ abfd, r_symndx);
+ if (isym == NULL)
+ return FALSE;
+
+ s = bfd_section_from_elf_index (abfd, isym->st_shndx);
+ if (s == NULL)
+ s = sec;
+
+ /* Beware of type punned pointers vs strict aliasing
+ rules. */
+ vpp = &(elf_section_data (s)->local_dynrel);
+ head = (struct elf_dyn_relocs **)vpp;
+ }
+
+ p = *head;
+ if (p == NULL || p->sec != sec)
+ {
+ bfd_size_type amt = sizeof *p;
+
+ p = ((struct elf_dyn_relocs *)
+ bfd_alloc (htab->elf.dynobj, amt));
+ if (p == NULL)
+ return FALSE;
+ p->next = *head;
+ *head = p;
+ p->sec = sec;
+ p->count = 0;
+ p->pc_count = 0;
+ }
+
+ p->count += 1;
+ /* Count size relocation as PC-relative relocation. */
+ if (IS_X86_64_PCREL_TYPE (r_type) || size_reloc)
+ p->pc_count += 1;
+ }
+ break;
+
+ /* This relocation describes the C++ object vtable hierarchy.
+ Reconstruct it for later use during GC. */
+ case R_X86_64_GNU_VTINHERIT:
+ if (!bfd_elf_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_X86_64_GNU_VTENTRY:
+ BFD_ASSERT (h != NULL);
+ if (h != NULL
+ && !bfd_elf_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_x86_64_gc_mark_hook (asection *sec,
+ 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_X86_64_GNU_VTINHERIT:
+ case R_X86_64_GNU_VTENTRY:
+ return NULL;
+ }
+
+ return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
+}
+
+/* Update the got entry reference counts for the section being removed. */
+
+static bfd_boolean
+elf_x86_64_gc_sweep_hook (bfd *abfd, struct bfd_link_info *info,
+ asection *sec,
+ const Elf_Internal_Rela *relocs)
+{
+ struct elf_x86_64_link_hash_table *htab;
+ Elf_Internal_Shdr *symtab_hdr;
+ struct elf_link_hash_entry **sym_hashes;
+ bfd_signed_vma *local_got_refcounts;
+ const Elf_Internal_Rela *rel, *relend;
+
+ if (info->relocatable)
+ return TRUE;
+
+ htab = elf_x86_64_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ elf_section_data (sec)->local_dynrel = NULL;
+
+ symtab_hdr = &elf_symtab_hdr (abfd);
+ sym_hashes = elf_sym_hashes (abfd);
+ local_got_refcounts = elf_local_got_refcounts (abfd);
+
+ htab = elf_x86_64_hash_table (info);
+ relend = relocs + sec->reloc_count;
+ for (rel = relocs; rel < relend; rel++)
+ {
+ unsigned long r_symndx;
+ unsigned int r_type;
+ struct elf_link_hash_entry *h = NULL;
+
+ r_symndx = htab->r_sym (rel->r_info);
+ if (r_symndx >= symtab_hdr->sh_info)
+ {
+ 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;
+ }
+ else
+ {
+ /* A local symbol. */
+ Elf_Internal_Sym *isym;
+
+ isym = bfd_sym_from_r_symndx (&htab->sym_cache,
+ abfd, r_symndx);
+
+ /* Check relocation against local STT_GNU_IFUNC symbol. */
+ if (isym != NULL
+ && ELF_ST_TYPE (isym->st_info) == STT_GNU_IFUNC)
+ {
+ h = elf_x86_64_get_local_sym_hash (htab, abfd, rel, FALSE);
+ if (h == NULL)
+ abort ();
+ }
+ }
+
+ if (h)
+ {
+ struct elf_x86_64_link_hash_entry *eh;
+ struct elf_dyn_relocs **pp;
+ struct elf_dyn_relocs *p;
+
+ eh = (struct elf_x86_64_link_hash_entry *) h;
+
+ for (pp = &eh->dyn_relocs; (p = *pp) != NULL; pp = &p->next)
+ if (p->sec == sec)
+ {
+ /* Everything must go for SEC. */
+ *pp = p->next;
+ break;
+ }
+ }
+
+ r_type = ELF32_R_TYPE (rel->r_info);
+ if (! elf_x86_64_tls_transition (info, abfd, sec, NULL,
+ symtab_hdr, sym_hashes,
+ &r_type, GOT_UNKNOWN,
+ rel, relend, h, r_symndx))
+ return FALSE;
+
+ switch (r_type)
+ {
+ case R_X86_64_TLSLD:
+ if (htab->tls_ld_got.refcount > 0)
+ htab->tls_ld_got.refcount -= 1;
+ break;
+
+ case R_X86_64_TLSGD:
+ case R_X86_64_GOTPC32_TLSDESC:
+ case R_X86_64_TLSDESC_CALL:
+ case R_X86_64_GOTTPOFF:
+ case R_X86_64_GOT32:
+ case R_X86_64_GOTPCREL:
+ case R_X86_64_GOT64:
+ case R_X86_64_GOTPCREL64:
+ case R_X86_64_GOTPLT64:
+ if (h != NULL)
+ {
+ if (r_type == R_X86_64_GOTPLT64 && h->plt.refcount > 0)
+ h->plt.refcount -= 1;
+ if (h->got.refcount > 0)
+ h->got.refcount -= 1;
+ if (h->type == STT_GNU_IFUNC)
+ {
+ if (h->plt.refcount > 0)
+ h->plt.refcount -= 1;
+ }
+ }
+ else if (local_got_refcounts != NULL)
+ {
+ if (local_got_refcounts[r_symndx] > 0)
+ local_got_refcounts[r_symndx] -= 1;
+ }
+ break;
+
+ case R_X86_64_8:
+ case R_X86_64_16:
+ case R_X86_64_32:
+ case R_X86_64_64:
+ case R_X86_64_32S:
+ case R_X86_64_PC8:
+ case R_X86_64_PC16:
+ case R_X86_64_PC32:
+ case R_X86_64_PC32_BND:
+ case R_X86_64_PC64:
+ case R_X86_64_SIZE32:
+ case R_X86_64_SIZE64:
+ if (info->shared
+ && (h == NULL || h->type != STT_GNU_IFUNC))
+ break;
+ /* Fall thru */
+
+ case R_X86_64_PLT32:
+ case R_X86_64_PLT32_BND:
+ case R_X86_64_PLTOFF64:
+ if (h != NULL)
+ {
+ if (h->plt.refcount > 0)
+ h->plt.refcount -= 1;
+ }
+ 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 bfd_boolean
+elf_x86_64_adjust_dynamic_symbol (struct bfd_link_info *info,
+ struct elf_link_hash_entry *h)
+{
+ struct elf_x86_64_link_hash_table *htab;
+ asection *s;
+ struct elf_x86_64_link_hash_entry *eh;
+ struct elf_dyn_relocs *p;
+
+ /* STT_GNU_IFUNC symbol must go through PLT. */
+ if (h->type == STT_GNU_IFUNC)
+ {
+ /* All local STT_GNU_IFUNC references must be treate as local
+ calls via local PLT. */
+ if (h->ref_regular
+ && SYMBOL_CALLS_LOCAL (info, h))
+ {
+ bfd_size_type pc_count = 0, count = 0;
+ struct elf_dyn_relocs **pp;
+
+ eh = (struct elf_x86_64_link_hash_entry *) h;
+ for (pp = &eh->dyn_relocs; (p = *pp) != NULL; )
+ {
+ pc_count += p->pc_count;
+ p->count -= p->pc_count;
+ p->pc_count = 0;
+ count += p->count;
+ if (p->count == 0)
+ *pp = p->next;
+ else
+ pp = &p->next;
+ }
+
+ if (pc_count || count)
+ {
+ h->needs_plt = 1;
+ h->non_got_ref = 1;
+ if (h->plt.refcount <= 0)
+ h->plt.refcount = 1;
+ else
+ h->plt.refcount += 1;
+ }
+ }
+
+ if (h->plt.refcount <= 0)
+ {
+ h->plt.offset = (bfd_vma) -1;
+ h->needs_plt = 0;
+ }
+ return TRUE;
+ }
+
+ /* 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->needs_plt)
+ {
+ if (h->plt.refcount <= 0
+ || SYMBOL_CALLS_LOCAL (info, h)
+ || (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
+ && h->root.type == bfd_link_hash_undefweak))
+ {
+ /* 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, or if all references were garbage collected. In
+ such a case, we don't actually need to build a procedure
+ linkage table, and we can just do a PC32 reloc instead. */
+ h->plt.offset = (bfd_vma) -1;
+ h->needs_plt = 0;
+ }
+
+ return TRUE;
+ }
+ else
+ /* It's possible that we incorrectly decided a .plt reloc was
+ needed for an R_X86_64_PC32 reloc to a non-function sym in
+ check_relocs. We can't decide accurately between function and
+ non-function syms in check-relocs; Objects loaded later in
+ the link may change h->type. So fix it now. */
+ 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->u.weakdef != NULL)
+ {
+ BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
+ || h->u.weakdef->root.type == bfd_link_hash_defweak);
+ h->root.u.def.section = h->u.weakdef->root.u.def.section;
+ h->root.u.def.value = h->u.weakdef->root.u.def.value;
+ if (ELIMINATE_COPY_RELOCS || info->nocopyreloc)
+ {
+ eh = (struct elf_x86_64_link_hash_entry *) h;
+ h->non_got_ref = h->u.weakdef->non_got_ref;
+ eh->needs_copy = h->u.weakdef->needs_copy;
+ }
+ 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->executable)
+ return TRUE;
+
+ /* If there are no references to this symbol that do not use the
+ GOT, we don't need to generate a copy reloc. */
+ if (!h->non_got_ref)
+ return TRUE;
+
+ /* If -z nocopyreloc was given, we won't generate them either. */
+ if (info->nocopyreloc)
+ {
+ h->non_got_ref = 0;
+ return TRUE;
+ }
+
+ if (ELIMINATE_COPY_RELOCS)
+ {
+ eh = (struct elf_x86_64_link_hash_entry *) h;
+ for (p = eh->dyn_relocs; p != NULL; p = p->next)
+ {
+ s = p->sec->output_section;
+ if (s != NULL && (s->flags & SEC_READONLY) != 0)
+ break;
+ }
+
+ /* If we didn't find any dynamic relocs in read-only sections, then
+ we'll be keeping the dynamic relocs and avoiding the copy reloc. */
+ if (p == NULL)
+ {
+ h->non_got_ref = 0;
+ 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. */
+
+ htab = elf_x86_64_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ /* We must generate a R_X86_64_COPY reloc to tell the dynamic linker
+ to copy the initial value out of the dynamic object and into the
+ runtime process image. */
+ if ((h->root.u.def.section->flags & SEC_ALLOC) != 0 && h->size != 0)
+ {
+ const struct elf_backend_data *bed;
+ bed = get_elf_backend_data (info->output_bfd);
+ htab->srelbss->size += bed->s->sizeof_rela;
+ h->needs_copy = 1;
+ }
+
+ s = htab->sdynbss;
+
+ return _bfd_elf_adjust_dynamic_copy (h, s);
+}
+
+/* Allocate space in .plt, .got and associated reloc sections for
+ dynamic relocs. */
+
+static bfd_boolean
+elf_x86_64_allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
+{
+ struct bfd_link_info *info;
+ struct elf_x86_64_link_hash_table *htab;
+ struct elf_x86_64_link_hash_entry *eh;
+ struct elf_dyn_relocs *p;
+ const struct elf_backend_data *bed;
+ unsigned int plt_entry_size;
+
+ if (h->root.type == bfd_link_hash_indirect)
+ return TRUE;
+
+ eh = (struct elf_x86_64_link_hash_entry *) h;
+
+ info = (struct bfd_link_info *) inf;
+ htab = elf_x86_64_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+ bed = get_elf_backend_data (info->output_bfd);
+ plt_entry_size = GET_PLT_ENTRY_SIZE (info->output_bfd);
+
+ /* Since STT_GNU_IFUNC symbol must go through PLT, we handle it
+ here if it is defined and referenced in a non-shared object. */
+ if (h->type == STT_GNU_IFUNC
+ && h->def_regular)
+ {
+ if (_bfd_elf_allocate_ifunc_dyn_relocs (info, h,
+ &eh->dyn_relocs,
+ plt_entry_size,
+ plt_entry_size,
+ GOT_ENTRY_SIZE))
+ {
+ asection *s = htab->plt_bnd;
+ if (h->plt.offset != (bfd_vma) -1 && s != NULL)
+ {
+ /* Use the .plt.bnd section if it is created. */
+ eh->plt_bnd.offset = s->size;
+
+ /* Make room for this entry in the .plt.bnd section. */
+ s->size += sizeof (elf_x86_64_legacy_plt2_entry);
+ }
+
+ return TRUE;
+ }
+ else
+ return FALSE;
+ }
+ else if (htab->elf.dynamic_sections_created
+ && h->plt.refcount > 0)
+ {
+ /* Make sure this symbol is output as a dynamic symbol.
+ Undefined weak syms won't yet be marked as dynamic. */
+ if (h->dynindx == -1
+ && !h->forced_local)
+ {
+ if (! bfd_elf_link_record_dynamic_symbol (info, h))
+ return FALSE;
+ }
+
+ if (info->shared
+ || WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, 0, h))
+ {
+ asection *s = htab->elf.splt;
+ asection *bnd_s = htab->plt_bnd;
+
+ /* If this is the first .plt entry, make room for the special
+ first entry. */
+ if (s->size == 0)
+ s->size = plt_entry_size;
+
+ h->plt.offset = s->size;
+ if (bnd_s)
+ eh->plt_bnd.offset = bnd_s->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->def_regular)
+ {
+ if (bnd_s)
+ {
+ /* We need to make a call to the entry of the second
+ PLT instead of regular PLT entry. */
+ h->root.u.def.section = bnd_s;
+ h->root.u.def.value = eh->plt_bnd.offset;
+ }
+ else
+ {
+ h->root.u.def.section = s;
+ h->root.u.def.value = h->plt.offset;
+ }
+ }
+
+ /* Make room for this entry. */
+ s->size += plt_entry_size;
+ if (bnd_s)
+ {
+ BFD_ASSERT (sizeof (elf_x86_64_bnd_plt2_entry)
+ == sizeof (elf_x86_64_legacy_plt2_entry));
+ bnd_s->size += sizeof (elf_x86_64_legacy_plt2_entry);
+ }
+
+ /* We also need to make an entry in the .got.plt section, which
+ will be placed in the .got section by the linker script. */
+ htab->elf.sgotplt->size += GOT_ENTRY_SIZE;
+
+ /* We also need to make an entry in the .rela.plt section. */
+ htab->elf.srelplt->size += bed->s->sizeof_rela;
+ htab->elf.srelplt->reloc_count++;
+ }
+ else
+ {
+ h->plt.offset = (bfd_vma) -1;
+ h->needs_plt = 0;
+ }
+ }
+ else
+ {
+ h->plt.offset = (bfd_vma) -1;
+ h->needs_plt = 0;
+ }
+
+ eh->tlsdesc_got = (bfd_vma) -1;
+
+ /* If R_X86_64_GOTTPOFF symbol is now local to the binary,
+ make it a R_X86_64_TPOFF32 requiring no GOT entry. */
+ if (h->got.refcount > 0
+ && info->executable
+ && h->dynindx == -1
+ && elf_x86_64_hash_entry (h)->tls_type == GOT_TLS_IE)
+ {
+ h->got.offset = (bfd_vma) -1;
+ }
+ else if (h->got.refcount > 0)
+ {
+ asection *s;
+ bfd_boolean dyn;
+ int tls_type = elf_x86_64_hash_entry (h)->tls_type;
+
+ /* Make sure this symbol is output as a dynamic symbol.
+ Undefined weak syms won't yet be marked as dynamic. */
+ if (h->dynindx == -1
+ && !h->forced_local)
+ {
+ if (! bfd_elf_link_record_dynamic_symbol (info, h))
+ return FALSE;
+ }
+
+ if (GOT_TLS_GDESC_P (tls_type))
+ {
+ eh->tlsdesc_got = htab->elf.sgotplt->size
+ - elf_x86_64_compute_jump_table_size (htab);
+ htab->elf.sgotplt->size += 2 * GOT_ENTRY_SIZE;
+ h->got.offset = (bfd_vma) -2;
+ }
+ if (! GOT_TLS_GDESC_P (tls_type)
+ || GOT_TLS_GD_P (tls_type))
+ {
+ s = htab->elf.sgot;
+ h->got.offset = s->size;
+ s->size += GOT_ENTRY_SIZE;
+ if (GOT_TLS_GD_P (tls_type))
+ s->size += GOT_ENTRY_SIZE;
+ }
+ dyn = htab->elf.dynamic_sections_created;
+ /* R_X86_64_TLSGD needs one dynamic relocation if local symbol
+ and two if global.
+ R_X86_64_GOTTPOFF needs one dynamic relocation. */
+ if ((GOT_TLS_GD_P (tls_type) && h->dynindx == -1)
+ || tls_type == GOT_TLS_IE)
+ htab->elf.srelgot->size += bed->s->sizeof_rela;
+ else if (GOT_TLS_GD_P (tls_type))
+ htab->elf.srelgot->size += 2 * bed->s->sizeof_rela;
+ else if (! GOT_TLS_GDESC_P (tls_type)
+ && (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
+ || h->root.type != bfd_link_hash_undefweak)
+ && (info->shared
+ || WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, 0, h)))
+ htab->elf.srelgot->size += bed->s->sizeof_rela;
+ if (GOT_TLS_GDESC_P (tls_type))
+ {
+ htab->elf.srelplt->size += bed->s->sizeof_rela;
+ htab->tlsdesc_plt = (bfd_vma) -1;
+ }
+ }
+ else
+ h->got.offset = (bfd_vma) -1;
+
+ if (eh->dyn_relocs == NULL)
+ return TRUE;
+
+ /* In the shared -Bsymbolic case, discard space allocated for
+ dynamic pc-relative relocs against symbols which turn out to be
+ defined in regular objects. For the normal shared case, discard
+ space for pc-relative relocs that have become local due to symbol
+ visibility changes. */
+
+ if (info->shared)
+ {
+ /* Relocs that use pc_count are those that appear on a call
+ insn, or certain REL relocs that can generated via assembly.
+ We want calls to protected symbols to resolve directly to the
+ function rather than going via the plt. If people want
+ function pointer comparisons to work as expected then they
+ should avoid writing weird assembly. */
+ if (SYMBOL_CALLS_LOCAL (info, h))
+ {
+ struct elf_dyn_relocs **pp;
+
+ for (pp = &eh->dyn_relocs; (p = *pp) != NULL; )
+ {
+ p->count -= p->pc_count;
+ p->pc_count = 0;
+ if (p->count == 0)
+ *pp = p->next;
+ else
+ pp = &p->next;
+ }
+ }
+
+ /* Also discard relocs on undefined weak syms with non-default
+ visibility. */
+ if (eh->dyn_relocs != NULL)
+ {
+ if (h->root.type == bfd_link_hash_undefweak)
+ {
+ if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
+ eh->dyn_relocs = NULL;
+
+ /* Make sure undefined weak symbols are output as a dynamic
+ symbol in PIEs. */
+ else if (h->dynindx == -1
+ && ! h->forced_local
+ && ! bfd_elf_link_record_dynamic_symbol (info, h))
+ return FALSE;
+ }
+ /* For PIE, discard space for relocs against symbols which
+ turn out to need copy relocs. */
+ else if (info->executable
+ && (h->needs_copy || eh->needs_copy)
+ && h->def_dynamic
+ && !h->def_regular)
+ eh->dyn_relocs = NULL;
+ }
+ }
+ else if (ELIMINATE_COPY_RELOCS)
+ {
+ /* For the non-shared case, discard space for relocs against
+ symbols which turn out to need copy relocs or are not
+ dynamic. */
+
+ if (!h->non_got_ref
+ && ((h->def_dynamic
+ && !h->def_regular)
+ || (htab->elf.dynamic_sections_created
+ && (h->root.type == bfd_link_hash_undefweak
+ || h->root.type == bfd_link_hash_undefined))))
+ {
+ /* Make sure this symbol is output as a dynamic symbol.
+ Undefined weak syms won't yet be marked as dynamic. */
+ if (h->dynindx == -1
+ && ! h->forced_local
+ && ! bfd_elf_link_record_dynamic_symbol (info, h))
+ return FALSE;
+
+ /* If that succeeded, we know we'll be keeping all the
+ relocs. */
+ if (h->dynindx != -1)
+ goto keep;
+ }
+
+ eh->dyn_relocs = NULL;
+
+ keep: ;
+ }
+
+ /* Finally, allocate space. */
+ for (p = eh->dyn_relocs; p != NULL; p = p->next)
+ {
+ asection * sreloc;
+
+ sreloc = elf_section_data (p->sec)->sreloc;
+
+ BFD_ASSERT (sreloc != NULL);
+
+ sreloc->size += p->count * bed->s->sizeof_rela;
+ }
+
+ return TRUE;
+}
+
+/* Allocate space in .plt, .got and associated reloc sections for
+ local dynamic relocs. */
+
+static bfd_boolean
+elf_x86_64_allocate_local_dynrelocs (void **slot, void *inf)
+{
+ struct elf_link_hash_entry *h
+ = (struct elf_link_hash_entry *) *slot;
+
+ if (h->type != STT_GNU_IFUNC
+ || !h->def_regular
+ || !h->ref_regular
+ || !h->forced_local
+ || h->root.type != bfd_link_hash_defined)
+ abort ();
+
+ return elf_x86_64_allocate_dynrelocs (h, inf);
+}
+
+/* Find any dynamic relocs that apply to read-only sections. */
+
+static bfd_boolean
+elf_x86_64_readonly_dynrelocs (struct elf_link_hash_entry *h,
+ void * inf)
+{
+ struct elf_x86_64_link_hash_entry *eh;
+ struct elf_dyn_relocs *p;
+
+ /* Skip local IFUNC symbols. */
+ if (h->forced_local && h->type == STT_GNU_IFUNC)
+ return TRUE;
+
+ eh = (struct elf_x86_64_link_hash_entry *) h;
+ for (p = eh->dyn_relocs; p != NULL; p = p->next)
+ {
+ asection *s = p->sec->output_section;
+
+ if (s != NULL && (s->flags & SEC_READONLY) != 0)
+ {
+ struct bfd_link_info *info = (struct bfd_link_info *) inf;
+
+ info->flags |= DF_TEXTREL;
+
+ if (info->warn_shared_textrel && info->shared)
+ info->callbacks->einfo (_("%P: %B: warning: relocation against `%s' in readonly section `%A'.\n"),
+ p->sec->owner, h->root.root.string,
+ p->sec);
+
+ /* Not an error, just cut short the traversal. */
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+/* Convert
+ mov foo@GOTPCREL(%rip), %reg
+ to
+ lea foo(%rip), %reg
+ with the local symbol, foo. */
+
+static bfd_boolean
+elf_x86_64_convert_mov_to_lea (bfd *abfd, asection *sec,
+ struct bfd_link_info *link_info)
+{
+ Elf_Internal_Shdr *symtab_hdr;
+ Elf_Internal_Rela *internal_relocs;
+ Elf_Internal_Rela *irel, *irelend;
+ bfd_byte *contents;
+ struct elf_x86_64_link_hash_table *htab;
+ bfd_boolean changed_contents;
+ bfd_boolean changed_relocs;
+ bfd_signed_vma *local_got_refcounts;
+
+ /* Don't even try to convert non-ELF outputs. */
+ if (!is_elf_hash_table (link_info->hash))
+ return FALSE;
+
+ /* Nothing to do if there are no codes, no relocations or no output. */
+ if ((sec->flags & (SEC_CODE | SEC_RELOC)) != (SEC_CODE | SEC_RELOC)
+ || sec->reloc_count == 0
+ || bfd_is_abs_section (sec->output_section))
+ return TRUE;
+
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+
+ /* Load the relocations for this section. */
+ internal_relocs = (_bfd_elf_link_read_relocs
+ (abfd, sec, NULL, (Elf_Internal_Rela *) NULL,
+ link_info->keep_memory));
+ if (internal_relocs == NULL)
+ return FALSE;
+
+ htab = elf_x86_64_hash_table (link_info);
+ changed_contents = FALSE;
+ changed_relocs = FALSE;
+ local_got_refcounts = elf_local_got_refcounts (abfd);
+
+ /* Get the section contents. */
+ if (elf_section_data (sec)->this_hdr.contents != NULL)
+ contents = elf_section_data (sec)->this_hdr.contents;
+ else
+ {
+ if (!bfd_malloc_and_get_section (abfd, sec, &contents))
+ goto error_return;
+ }
+
+ irelend = internal_relocs + sec->reloc_count;
+ for (irel = internal_relocs; irel < irelend; irel++)
+ {
+ unsigned int r_type = ELF32_R_TYPE (irel->r_info);
+ unsigned int r_symndx = htab->r_sym (irel->r_info);
+ unsigned int indx;
+ struct elf_link_hash_entry *h;
+
+ if (r_type != R_X86_64_GOTPCREL)
+ continue;
+
+ /* Get the symbol referred to by the reloc. */
+ if (r_symndx < symtab_hdr->sh_info)
+ {
+ Elf_Internal_Sym *isym;
+
+ isym = bfd_sym_from_r_symndx (&htab->sym_cache,
+ abfd, r_symndx);
+
+ /* STT_GNU_IFUNC must keep R_X86_64_GOTPCREL relocation. */
+ if (ELF_ST_TYPE (isym->st_info) != STT_GNU_IFUNC
+ && bfd_get_8 (input_bfd,
+ contents + irel->r_offset - 2) == 0x8b)
+ {
+ bfd_put_8 (output_bfd, 0x8d,
+ contents + irel->r_offset - 2);
+ irel->r_info = htab->r_info (r_symndx, R_X86_64_PC32);
+ if (local_got_refcounts != NULL
+ && local_got_refcounts[r_symndx] > 0)
+ local_got_refcounts[r_symndx] -= 1;
+ changed_contents = TRUE;
+ changed_relocs = TRUE;
+ }
+ continue;
+ }
+
+ indx = r_symndx - symtab_hdr->sh_info;
+ h = elf_sym_hashes (abfd)[indx];
+ BFD_ASSERT (h != NULL);
+
+ 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;
+
+ /* STT_GNU_IFUNC must keep R_X86_64_GOTPCREL relocation. We also
+ avoid optimizing _DYNAMIC since ld.so may use its link-time
+ address. */
+ if (h->def_regular
+ && h->type != STT_GNU_IFUNC
+ && h != htab->elf.hdynamic
+ && SYMBOL_REFERENCES_LOCAL (link_info, h)
+ && bfd_get_8 (input_bfd,
+ contents + irel->r_offset - 2) == 0x8b)
+ {
+ bfd_put_8 (output_bfd, 0x8d,
+ contents + irel->r_offset - 2);
+ irel->r_info = htab->r_info (r_symndx, R_X86_64_PC32);
+ if (h->got.refcount > 0)
+ h->got.refcount -= 1;
+ changed_contents = TRUE;
+ changed_relocs = TRUE;
+ }
+ }
+
+ if (contents != NULL
+ && elf_section_data (sec)->this_hdr.contents != contents)
+ {
+ if (!changed_contents && !link_info->keep_memory)
+ free (contents);
+ else
+ {
+ /* Cache the section contents for elf_link_input_bfd. */
+ elf_section_data (sec)->this_hdr.contents = contents;
+ }
+ }
+
+ if (elf_section_data (sec)->relocs != internal_relocs)
+ {
+ if (!changed_relocs)
+ free (internal_relocs);
+ else
+ elf_section_data (sec)->relocs = internal_relocs;
+ }
+
+ return TRUE;
+
+ error_return:
+ if (contents != NULL
+ && elf_section_data (sec)->this_hdr.contents != contents)
+ free (contents);
+ if (internal_relocs != NULL
+ && elf_section_data (sec)->relocs != internal_relocs)
+ free (internal_relocs);
+ return FALSE;
+}
+
+/* Set the sizes of the dynamic sections. */
+
+static bfd_boolean
+elf_x86_64_size_dynamic_sections (bfd *output_bfd,
+ struct bfd_link_info *info)
+{
+ struct elf_x86_64_link_hash_table *htab;
+ bfd *dynobj;
+ asection *s;
+ bfd_boolean relocs;
+ bfd *ibfd;
+ const struct elf_backend_data *bed;
+
+ htab = elf_x86_64_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+ bed = get_elf_backend_data (output_bfd);
+
+ dynobj = htab->elf.dynobj;
+ if (dynobj == NULL)
+ abort ();
+
+ if (htab->elf.dynamic_sections_created)
+ {
+ /* Set the contents of the .interp section to the interpreter. */
+ if (info->executable)
+ {
+ s = bfd_get_linker_section (dynobj, ".interp");
+ if (s == NULL)
+ abort ();
+ s->size = htab->dynamic_interpreter_size;
+ s->contents = (unsigned char *) htab->dynamic_interpreter;
+ }
+ }
+
+ /* Set up .got offsets for local syms, and space for local dynamic
+ relocs. */
+ for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next)
+ {
+ bfd_signed_vma *local_got;
+ bfd_signed_vma *end_local_got;
+ char *local_tls_type;
+ bfd_vma *local_tlsdesc_gotent;
+ bfd_size_type locsymcount;
+ Elf_Internal_Shdr *symtab_hdr;
+ asection *srel;
+
+ if (! is_x86_64_elf (ibfd))
+ continue;
+
+ for (s = ibfd->sections; s != NULL; s = s->next)
+ {
+ struct elf_dyn_relocs *p;
+
+ if (!elf_x86_64_convert_mov_to_lea (ibfd, s, info))
+ return FALSE;
+
+ for (p = (struct elf_dyn_relocs *)
+ (elf_section_data (s)->local_dynrel);
+ p != NULL;
+ p = p->next)
+ {
+ if (!bfd_is_abs_section (p->sec)
+ && bfd_is_abs_section (p->sec->output_section))
+ {
+ /* Input section has been discarded, either because
+ it is a copy of a linkonce section or due to
+ linker script /DISCARD/, so we'll be discarding
+ the relocs too. */
+ }
+ else if (p->count != 0)
+ {
+ srel = elf_section_data (p->sec)->sreloc;
+ srel->size += p->count * bed->s->sizeof_rela;
+ if ((p->sec->output_section->flags & SEC_READONLY) != 0
+ && (info->flags & DF_TEXTREL) == 0)
+ {
+ info->flags |= DF_TEXTREL;
+ if (info->warn_shared_textrel && info->shared)
+ info->callbacks->einfo (_("%P: %B: warning: relocation in readonly section `%A'.\n"),
+ p->sec->owner, p->sec);
+ }
+ }
+ }
+ }
+
+ local_got = elf_local_got_refcounts (ibfd);
+ if (!local_got)
+ continue;
+
+ symtab_hdr = &elf_symtab_hdr (ibfd);
+ locsymcount = symtab_hdr->sh_info;
+ end_local_got = local_got + locsymcount;
+ local_tls_type = elf_x86_64_local_got_tls_type (ibfd);
+ local_tlsdesc_gotent = elf_x86_64_local_tlsdesc_gotent (ibfd);
+ s = htab->elf.sgot;
+ srel = htab->elf.srelgot;
+ for (; local_got < end_local_got;
+ ++local_got, ++local_tls_type, ++local_tlsdesc_gotent)
+ {
+ *local_tlsdesc_gotent = (bfd_vma) -1;
+ if (*local_got > 0)
+ {
+ if (GOT_TLS_GDESC_P (*local_tls_type))
+ {
+ *local_tlsdesc_gotent = htab->elf.sgotplt->size
+ - elf_x86_64_compute_jump_table_size (htab);
+ htab->elf.sgotplt->size += 2 * GOT_ENTRY_SIZE;
+ *local_got = (bfd_vma) -2;
+ }
+ if (! GOT_TLS_GDESC_P (*local_tls_type)
+ || GOT_TLS_GD_P (*local_tls_type))
+ {
+ *local_got = s->size;
+ s->size += GOT_ENTRY_SIZE;
+ if (GOT_TLS_GD_P (*local_tls_type))
+ s->size += GOT_ENTRY_SIZE;
+ }
+ if (info->shared
+ || GOT_TLS_GD_ANY_P (*local_tls_type)
+ || *local_tls_type == GOT_TLS_IE)
+ {
+ if (GOT_TLS_GDESC_P (*local_tls_type))
+ {
+ htab->elf.srelplt->size
+ += bed->s->sizeof_rela;
+ htab->tlsdesc_plt = (bfd_vma) -1;
+ }
+ if (! GOT_TLS_GDESC_P (*local_tls_type)
+ || GOT_TLS_GD_P (*local_tls_type))
+ srel->size += bed->s->sizeof_rela;
+ }
+ }
+ else
+ *local_got = (bfd_vma) -1;
+ }
+ }
+
+ if (htab->tls_ld_got.refcount > 0)
+ {
+ /* Allocate 2 got entries and 1 dynamic reloc for R_X86_64_TLSLD
+ relocs. */
+ htab->tls_ld_got.offset = htab->elf.sgot->size;
+ htab->elf.sgot->size += 2 * GOT_ENTRY_SIZE;
+ htab->elf.srelgot->size += bed->s->sizeof_rela;
+ }
+ else
+ htab->tls_ld_got.offset = -1;
+
+ /* Allocate global sym .plt and .got entries, and space for global
+ sym dynamic relocs. */
+ elf_link_hash_traverse (&htab->elf, elf_x86_64_allocate_dynrelocs,
+ info);
+
+ /* Allocate .plt and .got entries, and space for local symbols. */
+ htab_traverse (htab->loc_hash_table,
+ elf_x86_64_allocate_local_dynrelocs,
+ info);
+
+ /* For every jump slot reserved in the sgotplt, reloc_count is
+ incremented. However, when we reserve space for TLS descriptors,
+ it's not incremented, so in order to compute the space reserved
+ for them, it suffices to multiply the reloc count by the jump
+ slot size.
+
+ PR ld/13302: We start next_irelative_index at the end of .rela.plt
+ so that R_X86_64_IRELATIVE entries come last. */
+ if (htab->elf.srelplt)
+ {
+ htab->sgotplt_jump_table_size
+ = elf_x86_64_compute_jump_table_size (htab);
+ htab->next_irelative_index = htab->elf.srelplt->reloc_count - 1;
+ }
+ else if (htab->elf.irelplt)
+ htab->next_irelative_index = htab->elf.irelplt->reloc_count - 1;
+
+ if (htab->tlsdesc_plt)
+ {
+ /* If we're not using lazy TLS relocations, don't generate the
+ PLT and GOT entries they require. */
+ if ((info->flags & DF_BIND_NOW))
+ htab->tlsdesc_plt = 0;
+ else
+ {
+ htab->tlsdesc_got = htab->elf.sgot->size;
+ htab->elf.sgot->size += GOT_ENTRY_SIZE;
+ /* Reserve room for the initial entry.
+ FIXME: we could probably do away with it in this case. */
+ if (htab->elf.splt->size == 0)
+ htab->elf.splt->size += GET_PLT_ENTRY_SIZE (output_bfd);
+ htab->tlsdesc_plt = htab->elf.splt->size;
+ htab->elf.splt->size += GET_PLT_ENTRY_SIZE (output_bfd);
+ }
+ }
+
+ if (htab->elf.sgotplt)
+ {
+ /* Don't allocate .got.plt section if there are no GOT nor PLT
+ entries and there is no refeence to _GLOBAL_OFFSET_TABLE_. */
+ if ((htab->elf.hgot == NULL
+ || !htab->elf.hgot->ref_regular_nonweak)
+ && (htab->elf.sgotplt->size
+ == get_elf_backend_data (output_bfd)->got_header_size)
+ && (htab->elf.splt == NULL
+ || htab->elf.splt->size == 0)
+ && (htab->elf.sgot == NULL
+ || htab->elf.sgot->size == 0)
+ && (htab->elf.iplt == NULL
+ || htab->elf.iplt->size == 0)
+ && (htab->elf.igotplt == NULL
+ || htab->elf.igotplt->size == 0))
+ htab->elf.sgotplt->size = 0;
+ }
+
+ if (htab->plt_eh_frame != NULL
+ && htab->elf.splt != NULL
+ && htab->elf.splt->size != 0
+ && !bfd_is_abs_section (htab->elf.splt->output_section)
+ && _bfd_elf_eh_frame_present (info))
+ {
+ const struct elf_x86_64_backend_data *arch_data
+ = get_elf_x86_64_arch_data (bed);
+ htab->plt_eh_frame->size = arch_data->eh_frame_plt_size;
+ }
+
+ /* We now have determined the sizes of the various dynamic sections.
+ Allocate memory for them. */
+ relocs = FALSE;
+ for (s = dynobj->sections; s != NULL; s = s->next)
+ {
+ if ((s->flags & SEC_LINKER_CREATED) == 0)
+ continue;
+
+ if (s == htab->elf.splt
+ || s == htab->elf.sgot
+ || s == htab->elf.sgotplt
+ || s == htab->elf.iplt
+ || s == htab->elf.igotplt
+ || s == htab->plt_bnd
+ || s == htab->plt_eh_frame
+ || s == htab->sdynbss)
+ {
+ /* Strip this section if we don't need it; see the
+ comment below. */
+ }
+ else if (CONST_STRNEQ (bfd_get_section_name (dynobj, s), ".rela"))
+ {
+ if (s->size != 0 && s != htab->elf.srelplt)
+ relocs = TRUE;
+
+ /* We use the reloc_count field as a counter if we need
+ to copy relocs into the output file. */
+ if (s != htab->elf.srelplt)
+ s->reloc_count = 0;
+ }
+ else
+ {
+ /* It's not one of our sections, so don't allocate space. */
+ continue;
+ }
+
+ if (s->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. */
+
+ s->flags |= SEC_EXCLUDE;
+ continue;
+ }
+
+ if ((s->flags & SEC_HAS_CONTENTS) == 0)
+ continue;
+
+ /* Allocate memory for the section contents. We use bfd_zalloc
+ here in case unused entries are not reclaimed before the
+ section's contents are written out. This should not happen,
+ but this way if it does, we get a R_X86_64_NONE reloc instead
+ of garbage. */
+ s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->size);
+ if (s->contents == NULL)
+ return FALSE;
+ }
+
+ if (htab->plt_eh_frame != NULL
+ && htab->plt_eh_frame->contents != NULL)
+ {
+ const struct elf_x86_64_backend_data *arch_data
+ = get_elf_x86_64_arch_data (bed);
+
+ memcpy (htab->plt_eh_frame->contents,
+ arch_data->eh_frame_plt, htab->plt_eh_frame->size);
+ bfd_put_32 (dynobj, htab->elf.splt->size,
+ htab->plt_eh_frame->contents + PLT_FDE_LEN_OFFSET);
+ }
+
+ if (htab->elf.dynamic_sections_created)
+ {
+ /* Add some entries to the .dynamic section. We fill in the
+ values later, in elf_x86_64_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. */
+#define add_dynamic_entry(TAG, VAL) \
+ _bfd_elf_add_dynamic_entry (info, TAG, VAL)
+
+ if (info->executable)
+ {
+ if (!add_dynamic_entry (DT_DEBUG, 0))
+ return FALSE;
+ }
+
+ if (htab->elf.splt->size != 0)
+ {
+ if (!add_dynamic_entry (DT_PLTGOT, 0)
+ || !add_dynamic_entry (DT_PLTRELSZ, 0)
+ || !add_dynamic_entry (DT_PLTREL, DT_RELA)
+ || !add_dynamic_entry (DT_JMPREL, 0))
+ return FALSE;
+
+ if (htab->tlsdesc_plt
+ && (!add_dynamic_entry (DT_TLSDESC_PLT, 0)
+ || !add_dynamic_entry (DT_TLSDESC_GOT, 0)))
+ return FALSE;
+ }
+
+ if (relocs)
+ {
+ if (!add_dynamic_entry (DT_RELA, 0)
+ || !add_dynamic_entry (DT_RELASZ, 0)
+ || !add_dynamic_entry (DT_RELAENT, bed->s->sizeof_rela))
+ return FALSE;
+
+ /* If any dynamic relocs apply to a read-only section,
+ then we need a DT_TEXTREL entry. */
+ if ((info->flags & DF_TEXTREL) == 0)
+ elf_link_hash_traverse (&htab->elf,
+ elf_x86_64_readonly_dynrelocs,
+ info);
+
+ if ((info->flags & DF_TEXTREL) != 0)
+ {
+ if (!add_dynamic_entry (DT_TEXTREL, 0))
+ return FALSE;
+ }
+ }
+ }
+#undef add_dynamic_entry
+
+ return TRUE;
+}
+
+static bfd_boolean
+elf_x86_64_always_size_sections (bfd *output_bfd,
+ struct bfd_link_info *info)
+{
+ asection *tls_sec = elf_hash_table (info)->tls_sec;
+
+ if (tls_sec)
+ {
+ struct elf_link_hash_entry *tlsbase;
+
+ tlsbase = elf_link_hash_lookup (elf_hash_table (info),
+ "_TLS_MODULE_BASE_",
+ FALSE, FALSE, FALSE);
+
+ if (tlsbase && tlsbase->type == STT_TLS)
+ {
+ struct elf_x86_64_link_hash_table *htab;
+ struct bfd_link_hash_entry *bh = NULL;
+ const struct elf_backend_data *bed
+ = get_elf_backend_data (output_bfd);
+
+ htab = elf_x86_64_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ if (!(_bfd_generic_link_add_one_symbol
+ (info, output_bfd, "_TLS_MODULE_BASE_", BSF_LOCAL,
+ tls_sec, 0, NULL, FALSE,
+ bed->collect, &bh)))
+ return FALSE;
+
+ htab->tls_module_base = bh;
+
+ tlsbase = (struct elf_link_hash_entry *)bh;
+ tlsbase->def_regular = 1;
+ tlsbase->other = STV_HIDDEN;
+ (*bed->elf_backend_hide_symbol) (info, tlsbase, TRUE);
+ }
+ }
+
+ return TRUE;
+}
+
+/* _TLS_MODULE_BASE_ needs to be treated especially when linking
+ executables. Rather than setting it to the beginning of the TLS
+ section, we have to set it to the end. This function may be called
+ multiple times, it is idempotent. */
+
+static void
+elf_x86_64_set_tls_module_base (struct bfd_link_info *info)
+{
+ struct elf_x86_64_link_hash_table *htab;
+ struct bfd_link_hash_entry *base;
+
+ if (!info->executable)
+ return;
+
+ htab = elf_x86_64_hash_table (info);
+ if (htab == NULL)
+ return;
+
+ base = htab->tls_module_base;
+ if (base == NULL)
+ return;
+
+ base->u.def.value = htab->elf.tls_size;
+}
+
+/* Return the base VMA address which should be subtracted from real addresses
+ when resolving @dtpoff relocation.
+ This is PT_TLS segment p_vaddr. */
+
+static bfd_vma
+elf_x86_64_dtpoff_base (struct bfd_link_info *info)
+{
+ /* If tls_sec is NULL, we should have signalled an error already. */
+ if (elf_hash_table (info)->tls_sec == NULL)
+ return 0;
+ return elf_hash_table (info)->tls_sec->vma;
+}
+
+/* Return the relocation value for @tpoff relocation
+ if STT_TLS virtual address is ADDRESS. */
+
+static bfd_vma
+elf_x86_64_tpoff (struct bfd_link_info *info, bfd_vma address)
+{
+ struct elf_link_hash_table *htab = elf_hash_table (info);
+ const struct elf_backend_data *bed = get_elf_backend_data (info->output_bfd);
+ bfd_vma static_tls_size;
+
+ /* If tls_segment is NULL, we should have signalled an error already. */
+ if (htab->tls_sec == NULL)
+ return 0;
+
+ /* Consider special static TLS alignment requirements. */
+ static_tls_size = BFD_ALIGN (htab->tls_size, bed->static_tls_alignment);
+ return address - static_tls_size - htab->tls_sec->vma;
+}
+
+/* Is the instruction before OFFSET in CONTENTS a 32bit relative
+ branch? */
+
+static bfd_boolean
+is_32bit_relative_branch (bfd_byte *contents, bfd_vma offset)
+{
+ /* Opcode Instruction
+ 0xe8 call
+ 0xe9 jump
+ 0x0f 0x8x conditional jump */
+ return ((offset > 0
+ && (contents [offset - 1] == 0xe8
+ || contents [offset - 1] == 0xe9))
+ || (offset > 1
+ && contents [offset - 2] == 0x0f
+ && (contents [offset - 1] & 0xf0) == 0x80));
+}
+
+/* Relocate an x86_64 ELF section. */
+
+static bfd_boolean
+elf_x86_64_relocate_section (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)
+{
+ struct elf_x86_64_link_hash_table *htab;
+ Elf_Internal_Shdr *symtab_hdr;
+ struct elf_link_hash_entry **sym_hashes;
+ bfd_vma *local_got_offsets;
+ bfd_vma *local_tlsdesc_gotents;
+ Elf_Internal_Rela *rel;
+ Elf_Internal_Rela *relend;
+ const unsigned int plt_entry_size = GET_PLT_ENTRY_SIZE (info->output_bfd);
+
+ BFD_ASSERT (is_x86_64_elf (input_bfd));
+
+ htab = elf_x86_64_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+ symtab_hdr = &elf_symtab_hdr (input_bfd);
+ sym_hashes = elf_sym_hashes (input_bfd);
+ local_got_offsets = elf_local_got_offsets (input_bfd);
+ local_tlsdesc_gotents = elf_x86_64_local_tlsdesc_gotent (input_bfd);
+
+ elf_x86_64_set_tls_module_base (info);
+
+ rel = relocs;
+ relend = relocs + input_section->reloc_count;
+ for (; rel < relend; rel++)
+ {
+ unsigned int r_type;
+ reloc_howto_type *howto;
+ unsigned long r_symndx;
+ struct elf_link_hash_entry *h;
+ struct elf_x86_64_link_hash_entry *eh;
+ Elf_Internal_Sym *sym;
+ asection *sec;
+ bfd_vma off, offplt, plt_offset;
+ bfd_vma relocation;
+ bfd_boolean unresolved_reloc;
+ bfd_reloc_status_type r;
+ int tls_type;
+ asection *base_got, *resolved_plt;
+ bfd_vma st_size;
+
+ r_type = ELF32_R_TYPE (rel->r_info);
+ if (r_type == (int) R_X86_64_GNU_VTINHERIT
+ || r_type == (int) R_X86_64_GNU_VTENTRY)
+ continue;
+
+ if (r_type >= (int) R_X86_64_standard)
+ {
+ (*_bfd_error_handler)
+ (_("%B: unrecognized relocation (0x%x) in section `%A'"),
+ input_bfd, input_section, r_type);
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+
+ if (r_type != (int) R_X86_64_32
+ || ABI_64_P (output_bfd))
+ howto = x86_64_elf_howto_table + r_type;
+ else
+ howto = (x86_64_elf_howto_table
+ + ARRAY_SIZE (x86_64_elf_howto_table) - 1);
+ r_symndx = htab->r_sym (rel->r_info);
+ h = NULL;
+ sym = NULL;
+ sec = NULL;
+ unresolved_reloc = FALSE;
+ if (r_symndx < symtab_hdr->sh_info)
+ {
+ sym = local_syms + r_symndx;
+ sec = local_sections[r_symndx];
+
+ relocation = _bfd_elf_rela_local_sym (output_bfd, sym,
+ &sec, rel);
+ st_size = sym->st_size;
+
+ /* Relocate against local STT_GNU_IFUNC symbol. */
+ if (!info->relocatable
+ && ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC)
+ {
+ h = elf_x86_64_get_local_sym_hash (htab, input_bfd,
+ rel, FALSE);
+ if (h == NULL)
+ abort ();
+
+ /* Set STT_GNU_IFUNC symbol value. */
+ h->root.u.def.value = sym->st_value;
+ h->root.u.def.section = sec;
+ }
+ }
+ else
+ {
+ bfd_boolean warned ATTRIBUTE_UNUSED;
+ bfd_boolean ignored ATTRIBUTE_UNUSED;
+
+ RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
+ r_symndx, symtab_hdr, sym_hashes,
+ h, sec, relocation,
+ unresolved_reloc, warned, ignored);
+ st_size = h->size;
+ }
+
+ if (sec != NULL && discarded_section (sec))
+ RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+ rel, 1, relend, howto, 0, contents);
+
+ if (info->relocatable)
+ continue;
+
+ if (rel->r_addend == 0 && !ABI_64_P (output_bfd))
+ {
+ if (r_type == R_X86_64_64)
+ {
+ /* For x32, treat R_X86_64_64 like R_X86_64_32 and
+ zero-extend it to 64bit if addend is zero. */
+ r_type = R_X86_64_32;
+ memset (contents + rel->r_offset + 4, 0, 4);
+ }
+ else if (r_type == R_X86_64_SIZE64)
+ {
+ /* For x32, treat R_X86_64_SIZE64 like R_X86_64_SIZE32 and
+ zero-extend it to 64bit if addend is zero. */
+ r_type = R_X86_64_SIZE32;
+ memset (contents + rel->r_offset + 4, 0, 4);
+ }
+ }
+
+ eh = (struct elf_x86_64_link_hash_entry *) h;
+
+ /* Since STT_GNU_IFUNC symbol must go through PLT, we handle
+ it here if it is defined in a non-shared object. */
+ if (h != NULL
+ && h->type == STT_GNU_IFUNC
+ && h->def_regular)
+ {
+ bfd_vma plt_index;
+ const char *name;
+
+ if ((input_section->flags & SEC_ALLOC) == 0
+ || h->plt.offset == (bfd_vma) -1)
+ abort ();
+
+ /* STT_GNU_IFUNC symbol must go through PLT. */
+ if (htab->elf.splt != NULL)
+ {
+ if (htab->plt_bnd != NULL)
+ {
+ resolved_plt = htab->plt_bnd;
+ plt_offset = eh->plt_bnd.offset;
+ }
+ else
+ {
+ resolved_plt = htab->elf.splt;
+ plt_offset = h->plt.offset;
+ }
+ }
+ else
+ {
+ resolved_plt = htab->elf.iplt;
+ plt_offset = h->plt.offset;
+ }
+
+ relocation = (resolved_plt->output_section->vma
+ + resolved_plt->output_offset + plt_offset);
+
+ switch (r_type)
+ {
+ default:
+ if (h->root.root.string)
+ name = h->root.root.string;
+ else
+ name = bfd_elf_sym_name (input_bfd, symtab_hdr, sym,
+ NULL);
+ (*_bfd_error_handler)
+ (_("%B: relocation %s against STT_GNU_IFUNC "
+ "symbol `%s' isn't handled by %s"), input_bfd,
+ x86_64_elf_howto_table[r_type].name,
+ name, __FUNCTION__);
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+
+ case R_X86_64_32S:
+ if (info->shared)
+ abort ();
+ goto do_relocation;
+
+ case R_X86_64_32:
+ if (ABI_64_P (output_bfd))
+ goto do_relocation;
+ /* FALLTHROUGH */
+ case R_X86_64_64:
+ if (rel->r_addend != 0)
+ {
+ if (h->root.root.string)
+ name = h->root.root.string;
+ else
+ name = bfd_elf_sym_name (input_bfd, symtab_hdr,
+ sym, NULL);
+ (*_bfd_error_handler)
+ (_("%B: relocation %s against STT_GNU_IFUNC "
+ "symbol `%s' has non-zero addend: %d"),
+ input_bfd, x86_64_elf_howto_table[r_type].name,
+ name, rel->r_addend);
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+
+ /* Generate dynamic relcoation only when there is a
+ non-GOT reference in a shared object. */
+ if (info->shared && h->non_got_ref)
+ {
+ Elf_Internal_Rela outrel;
+ asection *sreloc;
+
+ /* Need a dynamic relocation to get the real function
+ address. */
+ outrel.r_offset = _bfd_elf_section_offset (output_bfd,
+ info,
+ input_section,
+ rel->r_offset);
+ if (outrel.r_offset == (bfd_vma) -1
+ || outrel.r_offset == (bfd_vma) -2)
+ abort ();
+
+ outrel.r_offset += (input_section->output_section->vma
+ + input_section->output_offset);
+
+ if (h->dynindx == -1
+ || h->forced_local
+ || info->executable)
+ {
+ /* This symbol is resolved locally. */
+ outrel.r_info = htab->r_info (0, R_X86_64_IRELATIVE);
+ outrel.r_addend = (h->root.u.def.value
+ + h->root.u.def.section->output_section->vma
+ + h->root.u.def.section->output_offset);
+ }
+ else
+ {
+ outrel.r_info = htab->r_info (h->dynindx, r_type);
+ outrel.r_addend = 0;
+ }
+
+ sreloc = htab->elf.irelifunc;
+ elf_append_rela (output_bfd, sreloc, &outrel);
+
+ /* 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. For an
+ internal symbol, we have updated addend. */
+ continue;
+ }
+ /* FALLTHROUGH */
+ case R_X86_64_PC32:
+ case R_X86_64_PC32_BND:
+ case R_X86_64_PC64:
+ case R_X86_64_PLT32:
+ case R_X86_64_PLT32_BND:
+ goto do_relocation;
+
+ case R_X86_64_GOTPCREL:
+ case R_X86_64_GOTPCREL64:
+ base_got = htab->elf.sgot;
+ off = h->got.offset;
+
+ if (base_got == NULL)
+ abort ();
+
+ if (off == (bfd_vma) -1)
+ {
+ /* We can't use h->got.offset here to save state, or
+ even just remember the offset, as finish_dynamic_symbol
+ would use that as offset into .got. */
+
+ if (htab->elf.splt != NULL)
+ {
+ plt_index = h->plt.offset / plt_entry_size - 1;
+ off = (plt_index + 3) * GOT_ENTRY_SIZE;
+ base_got = htab->elf.sgotplt;
+ }
+ else
+ {
+ plt_index = h->plt.offset / plt_entry_size;
+ off = plt_index * GOT_ENTRY_SIZE;
+ base_got = htab->elf.igotplt;
+ }
+
+ if (h->dynindx == -1
+ || h->forced_local
+ || info->symbolic)
+ {
+ /* This references the local defitionion. 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,
+ base_got->contents + off);
+ /* Note that this is harmless for the GOTPLT64
+ case, as -1 | 1 still is -1. */
+ h->got.offset |= 1;
+ }
+ }
+ }
+
+ relocation = (base_got->output_section->vma
+ + base_got->output_offset + off);
+
+ goto do_relocation;
+ }
+ }
+
+ /* When generating a shared object, the relocations handled here are
+ copied into the output file to be resolved at run time. */
+ switch (r_type)
+ {
+ case R_X86_64_GOT32:
+ case R_X86_64_GOT64:
+ /* Relocation is to the entry for this symbol in the global
+ offset table. */
+ case R_X86_64_GOTPCREL:
+ case R_X86_64_GOTPCREL64:
+ /* Use global offset table entry as symbol value. */
+ case R_X86_64_GOTPLT64:
+ /* This is the same as GOT64 for relocation purposes, but
+ indicates the existence of a PLT entry. The difficulty is,
+ that we must calculate the GOT slot offset from the PLT
+ offset, if this symbol got a PLT entry (it was global).
+ Additionally if it's computed from the PLT entry, then that
+ GOT offset is relative to .got.plt, not to .got. */
+ base_got = htab->elf.sgot;
+
+ if (htab->elf.sgot == NULL)
+ abort ();
+
+ if (h != NULL)
+ {
+ bfd_boolean dyn;
+
+ off = h->got.offset;
+ if (h->needs_plt
+ && h->plt.offset != (bfd_vma)-1
+ && off == (bfd_vma)-1)
+ {
+ /* We can't use h->got.offset here to save
+ state, or even just remember the offset, as
+ finish_dynamic_symbol would use that as offset into
+ .got. */
+ bfd_vma plt_index = h->plt.offset / plt_entry_size - 1;
+ off = (plt_index + 3) * GOT_ENTRY_SIZE;
+ base_got = htab->elf.sgotplt;
+ }
+
+ dyn = htab->elf.dynamic_sections_created;
+
+ if (! WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h)
+ || (info->shared
+ && SYMBOL_REFERENCES_LOCAL (info, h))
+ || (ELF_ST_VISIBILITY (h->other)
+ && h->root.type == bfd_link_hash_undefweak))
+ {
+ /* 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,
+ base_got->contents + off);
+ /* Note that this is harmless for the GOTPLT64 case,
+ as -1 | 1 still is -1. */
+ h->got.offset |= 1;
+ }
+ }
+ else
+ unresolved_reloc = FALSE;
+ }
+ else
+ {
+ if (local_got_offsets == NULL)
+ abort ();
+
+ off = local_got_offsets[r_symndx];
+
+ /* The offset must always be a multiple of 8. 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_64 (output_bfd, relocation,
+ base_got->contents + off);
+
+ if (info->shared)
+ {
+ asection *s;
+ Elf_Internal_Rela outrel;
+
+ /* We need to generate a R_X86_64_RELATIVE reloc
+ for the dynamic linker. */
+ s = htab->elf.srelgot;
+ if (s == NULL)
+ abort ();
+
+ outrel.r_offset = (base_got->output_section->vma
+ + base_got->output_offset
+ + off);
+ outrel.r_info = htab->r_info (0, R_X86_64_RELATIVE);
+ outrel.r_addend = relocation;
+ elf_append_rela (output_bfd, s, &outrel);
+ }
+
+ local_got_offsets[r_symndx] |= 1;
+ }
+ }
+
+ if (off >= (bfd_vma) -2)
+ abort ();
+
+ relocation = base_got->output_section->vma
+ + base_got->output_offset + off;
+ if (r_type != R_X86_64_GOTPCREL && r_type != R_X86_64_GOTPCREL64)
+ relocation -= htab->elf.sgotplt->output_section->vma
+ - htab->elf.sgotplt->output_offset;
+
+ break;
+
+ case R_X86_64_GOTOFF64:
+ /* Relocation is relative to the start of the global offset
+ table. */
+
+ /* Check to make sure it isn't a protected function symbol
+ for shared library since it may not be local when used
+ as function address. */
+ if (!info->executable
+ && h
+ && !SYMBOLIC_BIND (info, h)
+ && h->def_regular
+ && h->type == STT_FUNC
+ && ELF_ST_VISIBILITY (h->other) == STV_PROTECTED)
+ {
+ (*_bfd_error_handler)
+ (_("%B: relocation R_X86_64_GOTOFF64 against protected function `%s' can not be used when making a shared object"),
+ input_bfd, h->root.root.string);
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+
+ /* Note that sgot is not involved in this
+ calculation. We always want the start of .got.plt. If we
+ defined _GLOBAL_OFFSET_TABLE_ in a different way, as is
+ permitted by the ABI, we might have to change this
+ calculation. */
+ relocation -= htab->elf.sgotplt->output_section->vma
+ + htab->elf.sgotplt->output_offset;
+ break;
+
+ case R_X86_64_GOTPC32:
+ case R_X86_64_GOTPC64:
+ /* Use global offset table as symbol value. */
+ relocation = htab->elf.sgotplt->output_section->vma
+ + htab->elf.sgotplt->output_offset;
+ unresolved_reloc = FALSE;
+ break;
+
+ case R_X86_64_PLTOFF64:
+ /* Relocation is PLT entry relative to GOT. For local
+ symbols it's the symbol itself relative to GOT. */
+ if (h != NULL
+ /* See PLT32 handling. */
+ && h->plt.offset != (bfd_vma) -1
+ && htab->elf.splt != NULL)
+ {
+ if (htab->plt_bnd != NULL)
+ {
+ resolved_plt = htab->plt_bnd;
+ plt_offset = eh->plt_bnd.offset;
+ }
+ else
+ {
+ resolved_plt = htab->elf.splt;
+ plt_offset = h->plt.offset;
+ }
+
+ relocation = (resolved_plt->output_section->vma
+ + resolved_plt->output_offset
+ + plt_offset);
+ unresolved_reloc = FALSE;
+ }
+
+ relocation -= htab->elf.sgotplt->output_section->vma
+ + htab->elf.sgotplt->output_offset;
+ break;
+
+ case R_X86_64_PLT32:
+ case R_X86_64_PLT32_BND:
+ /* 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)
+ break;
+
+ if (h->plt.offset == (bfd_vma) -1
+ || htab->elf.splt == NULL)
+ {
+ /* We didn't make a PLT entry for this symbol. This
+ happens when statically linking PIC code, or when
+ using -Bsymbolic. */
+ break;
+ }
+
+ if (htab->plt_bnd != NULL)
+ {
+ resolved_plt = htab->plt_bnd;
+ plt_offset = eh->plt_bnd.offset;
+ }
+ else
+ {
+ resolved_plt = htab->elf.splt;
+ plt_offset = h->plt.offset;
+ }
+
+ relocation = (resolved_plt->output_section->vma
+ + resolved_plt->output_offset
+ + plt_offset);
+ unresolved_reloc = FALSE;
+ break;
+
+ case R_X86_64_SIZE32:
+ case R_X86_64_SIZE64:
+ /* Set to symbol size. */
+ relocation = st_size;
+ goto direct;
+
+ case R_X86_64_PC8:
+ case R_X86_64_PC16:
+ case R_X86_64_PC32:
+ case R_X86_64_PC32_BND:
+ if (info->shared
+ && (input_section->flags & SEC_ALLOC) != 0
+ && (input_section->flags & SEC_READONLY) != 0
+ && h != NULL)
+ {
+ bfd_boolean fail = FALSE;
+ bfd_boolean branch
+ = ((r_type == R_X86_64_PC32
+ || r_type == R_X86_64_PC32_BND)
+ && is_32bit_relative_branch (contents, rel->r_offset));
+
+ if (SYMBOL_REFERENCES_LOCAL (info, h))
+ {
+ /* Symbol is referenced locally. Make sure it is
+ defined locally or for a branch. */
+ fail = !h->def_regular && !branch;
+ }
+ else if (!(info->executable
+ && (h->needs_copy || eh->needs_copy)))
+ {
+ /* Symbol doesn't need copy reloc and isn't referenced
+ locally. We only allow branch to symbol with
+ non-default visibility. */
+ fail = (!branch
+ || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT);
+ }
+
+ if (fail)
+ {
+ const char *fmt;
+ const char *v;
+ const char *pic = "";
+
+ switch (ELF_ST_VISIBILITY (h->other))
+ {
+ case STV_HIDDEN:
+ v = _("hidden symbol");
+ break;
+ case STV_INTERNAL:
+ v = _("internal symbol");
+ break;
+ case STV_PROTECTED:
+ v = _("protected symbol");
+ break;
+ default:
+ v = _("symbol");
+ pic = _("; recompile with -fPIC");
+ break;
+ }
+
+ if (h->def_regular)
+ fmt = _("%B: relocation %s against %s `%s' can not be used when making a shared object%s");
+ else
+ fmt = _("%B: relocation %s against undefined %s `%s' can not be used when making a shared object%s");
+
+ (*_bfd_error_handler) (fmt, input_bfd,
+ x86_64_elf_howto_table[r_type].name,
+ v, h->root.root.string, pic);
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+ }
+ /* Fall through. */
+
+ case R_X86_64_8:
+ case R_X86_64_16:
+ case R_X86_64_32:
+ case R_X86_64_PC64:
+ case R_X86_64_64:
+ /* FIXME: The ABI says the linker should make sure the value is
+ the same when it's zeroextended to 64 bit. */
+
+direct:
+ if ((input_section->flags & SEC_ALLOC) == 0)
+ break;
+
+ /* Don't copy a pc-relative relocation into the output file
+ if the symbol needs copy reloc. */
+ if ((info->shared
+ && !(info->executable
+ && h != NULL
+ && (h->needs_copy || eh->needs_copy)
+ && IS_X86_64_PCREL_TYPE (r_type))
+ && (h == NULL
+ || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
+ || h->root.type != bfd_link_hash_undefweak)
+ && ((! IS_X86_64_PCREL_TYPE (r_type)
+ && r_type != R_X86_64_SIZE32
+ && r_type != R_X86_64_SIZE64)
+ || ! SYMBOL_CALLS_LOCAL (info, h)))
+ || (ELIMINATE_COPY_RELOCS
+ && !info->shared
+ && h != NULL
+ && h->dynindx != -1
+ && !h->non_got_ref
+ && ((h->def_dynamic
+ && !h->def_regular)
+ || h->root.type == bfd_link_hash_undefweak
+ || h->root.type == bfd_link_hash_undefined)))
+ {
+ Elf_Internal_Rela outrel;
+ bfd_boolean skip, relocate;
+ asection *sreloc;
+
+ /* When generating a shared object, these relocations
+ are copied into the output file to be resolved at run
+ time. */
+ skip = FALSE;
+ relocate = FALSE;
+
+ outrel.r_offset =
+ _bfd_elf_section_offset (output_bfd, info, input_section,
+ rel->r_offset);
+ if (outrel.r_offset == (bfd_vma) -1)
+ skip = TRUE;
+ else if (outrel.r_offset == (bfd_vma) -2)
+ skip = TRUE, relocate = TRUE;
+
+ 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
+ && h->dynindx != -1
+ && (IS_X86_64_PCREL_TYPE (r_type)
+ || ! info->shared
+ || ! SYMBOLIC_BIND (info, h)
+ || ! h->def_regular))
+ {
+ outrel.r_info = htab->r_info (h->dynindx, r_type);
+ outrel.r_addend = rel->r_addend;
+ }
+ else
+ {
+ /* This symbol is local, or marked to become local. */
+ if (r_type == htab->pointer_r_type)
+ {
+ relocate = TRUE;
+ outrel.r_info = htab->r_info (0, R_X86_64_RELATIVE);
+ outrel.r_addend = relocation + rel->r_addend;
+ }
+ else if (r_type == R_X86_64_64
+ && !ABI_64_P (output_bfd))
+ {
+ relocate = TRUE;
+ outrel.r_info = htab->r_info (0,
+ R_X86_64_RELATIVE64);
+ outrel.r_addend = relocation + rel->r_addend;
+ /* Check addend overflow. */
+ if ((outrel.r_addend & 0x80000000)
+ != (rel->r_addend & 0x80000000))
+ {
+ const char *name;
+ int addend = rel->r_addend;
+ if (h && h->root.root.string)
+ name = h->root.root.string;
+ else
+ name = bfd_elf_sym_name (input_bfd, symtab_hdr,
+ sym, NULL);
+ if (addend < 0)
+ (*_bfd_error_handler)
+ (_("%B: addend -0x%x in relocation %s against "
+ "symbol `%s' at 0x%lx in section `%A' is "
+ "out of range"),
+ input_bfd, input_section, addend,
+ x86_64_elf_howto_table[r_type].name,
+ name, (unsigned long) rel->r_offset);
+ else
+ (*_bfd_error_handler)
+ (_("%B: addend 0x%x in relocation %s against "
+ "symbol `%s' at 0x%lx in section `%A' is "
+ "out of range"),
+ input_bfd, input_section, addend,
+ x86_64_elf_howto_table[r_type].name,
+ name, (unsigned long) rel->r_offset);
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+ }
+ else
+ {
+ long sindx;
+
+ if (bfd_is_abs_section (sec))
+ sindx = 0;
+ else if (sec == NULL || sec->owner == NULL)
+ {
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+ else
+ {
+ asection *osec;
+
+ /* We are turning this relocation into one
+ against a section symbol. It would be
+ proper to subtract the symbol's value,
+ osec->vma, from the emitted reloc addend,
+ but ld.so expects buggy relocs. */
+ osec = sec->output_section;
+ sindx = elf_section_data (osec)->dynindx;
+ if (sindx == 0)
+ {
+ asection *oi = htab->elf.text_index_section;
+ sindx = elf_section_data (oi)->dynindx;
+ }
+ BFD_ASSERT (sindx != 0);
+ }
+
+ outrel.r_info = htab->r_info (sindx, r_type);
+ outrel.r_addend = relocation + rel->r_addend;
+ }
+ }
+
+ sreloc = elf_section_data (input_section)->sreloc;
+
+ if (sreloc == NULL || sreloc->contents == NULL)
+ {
+ r = bfd_reloc_notsupported;
+ goto check_relocation_error;
+ }
+
+ elf_append_rela (output_bfd, sreloc, &outrel);
+
+ /* 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;
+
+ case R_X86_64_TLSGD:
+ case R_X86_64_GOTPC32_TLSDESC:
+ case R_X86_64_TLSDESC_CALL:
+ case R_X86_64_GOTTPOFF:
+ tls_type = GOT_UNKNOWN;
+ if (h == NULL && local_got_offsets)
+ tls_type = elf_x86_64_local_got_tls_type (input_bfd) [r_symndx];
+ else if (h != NULL)
+ tls_type = elf_x86_64_hash_entry (h)->tls_type;
+
+ if (! elf_x86_64_tls_transition (info, input_bfd,
+ input_section, contents,
+ symtab_hdr, sym_hashes,
+ &r_type, tls_type, rel,
+ relend, h, r_symndx))
+ return FALSE;
+
+ if (r_type == R_X86_64_TPOFF32)
+ {
+ bfd_vma roff = rel->r_offset;
+
+ BFD_ASSERT (! unresolved_reloc);
+
+ if (ELF32_R_TYPE (rel->r_info) == R_X86_64_TLSGD)
+ {
+ /* GD->LE transition. For 64bit, change
+ .byte 0x66; leaq foo@tlsgd(%rip), %rdi
+ .word 0x6666; rex64; call __tls_get_addr
+ into:
+ movq %fs:0, %rax
+ leaq foo@tpoff(%rax), %rax
+ For 32bit, change
+ leaq foo@tlsgd(%rip), %rdi
+ .word 0x6666; rex64; call __tls_get_addr
+ into:
+ movl %fs:0, %eax
+ leaq foo@tpoff(%rax), %rax
+ For largepic, change:
+ leaq foo@tlsgd(%rip), %rdi
+ movabsq $__tls_get_addr@pltoff, %rax
+ addq %rbx, %rax
+ call *%rax
+ into:
+ movq %fs:0, %rax
+ leaq foo@tpoff(%rax), %rax
+ nopw 0x0(%rax,%rax,1) */
+ int largepic = 0;
+ if (ABI_64_P (output_bfd)
+ && contents[roff + 5] == (bfd_byte) '\xb8')
+ {
+ memcpy (contents + roff - 3,
+ "\x64\x48\x8b\x04\x25\0\0\0\0\x48\x8d\x80"
+ "\0\0\0\0\x66\x0f\x1f\x44\0", 22);
+ largepic = 1;
+ }
+ else if (ABI_64_P (output_bfd))
+ memcpy (contents + roff - 4,
+ "\x64\x48\x8b\x04\x25\0\0\0\0\x48\x8d\x80\0\0\0",
+ 16);
+ else
+ memcpy (contents + roff - 3,
+ "\x64\x8b\x04\x25\0\0\0\0\x48\x8d\x80\0\0\0",
+ 15);
+ bfd_put_32 (output_bfd,
+ elf_x86_64_tpoff (info, relocation),
+ contents + roff + 8 + largepic);
+ /* Skip R_X86_64_PC32/R_X86_64_PLT32/R_X86_64_PLTOFF64. */
+ rel++;
+ continue;
+ }
+ else if (ELF32_R_TYPE (rel->r_info) == R_X86_64_GOTPC32_TLSDESC)
+ {
+ /* GDesc -> LE transition.
+ It's originally something like:
+ leaq x@tlsdesc(%rip), %rax
+
+ Change it to:
+ movl $x@tpoff, %rax. */
+
+ unsigned int val, type;
+
+ type = bfd_get_8 (input_bfd, contents + roff - 3);
+ val = bfd_get_8 (input_bfd, contents + roff - 1);
+ bfd_put_8 (output_bfd, 0x48 | ((type >> 2) & 1),
+ contents + roff - 3);
+ bfd_put_8 (output_bfd, 0xc7, contents + roff - 2);
+ bfd_put_8 (output_bfd, 0xc0 | ((val >> 3) & 7),
+ contents + roff - 1);
+ bfd_put_32 (output_bfd,
+ elf_x86_64_tpoff (info, relocation),
+ contents + roff);
+ continue;
+ }
+ else if (ELF32_R_TYPE (rel->r_info) == R_X86_64_TLSDESC_CALL)
+ {
+ /* GDesc -> LE transition.
+ It's originally:
+ call *(%rax)
+ Turn it into:
+ xchg %ax,%ax. */
+ bfd_put_8 (output_bfd, 0x66, contents + roff);
+ bfd_put_8 (output_bfd, 0x90, contents + roff + 1);
+ continue;
+ }
+ else if (ELF32_R_TYPE (rel->r_info) == R_X86_64_GOTTPOFF)
+ {
+ /* IE->LE transition:
+ For 64bit, originally it can be one of:
+ movq foo@gottpoff(%rip), %reg
+ addq foo@gottpoff(%rip), %reg
+ We change it into:
+ movq $foo, %reg
+ leaq foo(%reg), %reg
+ addq $foo, %reg.
+ For 32bit, originally it can be one of:
+ movq foo@gottpoff(%rip), %reg
+ addl foo@gottpoff(%rip), %reg
+ We change it into:
+ movq $foo, %reg
+ leal foo(%reg), %reg
+ addl $foo, %reg. */
+
+ unsigned int val, type, reg;
+
+ if (roff >= 3)
+ val = bfd_get_8 (input_bfd, contents + roff - 3);
+ else
+ val = 0;
+ type = bfd_get_8 (input_bfd, contents + roff - 2);
+ reg = bfd_get_8 (input_bfd, contents + roff - 1);
+ reg >>= 3;
+ if (type == 0x8b)
+ {
+ /* movq */
+ if (val == 0x4c)
+ bfd_put_8 (output_bfd, 0x49,
+ contents + roff - 3);
+ else if (!ABI_64_P (output_bfd) && val == 0x44)
+ bfd_put_8 (output_bfd, 0x41,
+ contents + roff - 3);
+ bfd_put_8 (output_bfd, 0xc7,
+ contents + roff - 2);
+ bfd_put_8 (output_bfd, 0xc0 | reg,
+ contents + roff - 1);
+ }
+ else if (reg == 4)
+ {
+ /* addq/addl -> addq/addl - addressing with %rsp/%r12
+ is special */
+ if (val == 0x4c)
+ bfd_put_8 (output_bfd, 0x49,
+ contents + roff - 3);
+ else if (!ABI_64_P (output_bfd) && val == 0x44)
+ bfd_put_8 (output_bfd, 0x41,
+ contents + roff - 3);
+ bfd_put_8 (output_bfd, 0x81,
+ contents + roff - 2);
+ bfd_put_8 (output_bfd, 0xc0 | reg,
+ contents + roff - 1);
+ }
+ else
+ {
+ /* addq/addl -> leaq/leal */
+ if (val == 0x4c)
+ bfd_put_8 (output_bfd, 0x4d,
+ contents + roff - 3);
+ else if (!ABI_64_P (output_bfd) && val == 0x44)
+ bfd_put_8 (output_bfd, 0x45,
+ contents + roff - 3);
+ bfd_put_8 (output_bfd, 0x8d,
+ contents + roff - 2);
+ bfd_put_8 (output_bfd, 0x80 | reg | (reg << 3),
+ contents + roff - 1);
+ }
+ bfd_put_32 (output_bfd,
+ elf_x86_64_tpoff (info, relocation),
+ contents + roff);
+ continue;
+ }
+ else
+ BFD_ASSERT (FALSE);
+ }
+
+ if (htab->elf.sgot == NULL)
+ abort ();
+
+ if (h != NULL)
+ {
+ off = h->got.offset;
+ offplt = elf_x86_64_hash_entry (h)->tlsdesc_got;
+ }
+ else
+ {
+ if (local_got_offsets == NULL)
+ abort ();
+
+ off = local_got_offsets[r_symndx];
+ offplt = local_tlsdesc_gotents[r_symndx];
+ }
+
+ if ((off & 1) != 0)
+ off &= ~1;
+ else
+ {
+ Elf_Internal_Rela outrel;
+ int dr_type, indx;
+ asection *sreloc;
+
+ if (htab->elf.srelgot == NULL)
+ abort ();
+
+ indx = h && h->dynindx != -1 ? h->dynindx : 0;
+
+ if (GOT_TLS_GDESC_P (tls_type))
+ {
+ outrel.r_info = htab->r_info (indx, R_X86_64_TLSDESC);
+ BFD_ASSERT (htab->sgotplt_jump_table_size + offplt
+ + 2 * GOT_ENTRY_SIZE <= htab->elf.sgotplt->size);
+ outrel.r_offset = (htab->elf.sgotplt->output_section->vma
+ + htab->elf.sgotplt->output_offset
+ + offplt
+ + htab->sgotplt_jump_table_size);
+ sreloc = htab->elf.srelplt;
+ if (indx == 0)
+ outrel.r_addend = relocation - elf_x86_64_dtpoff_base (info);
+ else
+ outrel.r_addend = 0;
+ elf_append_rela (output_bfd, sreloc, &outrel);
+ }
+
+ sreloc = htab->elf.srelgot;
+
+ outrel.r_offset = (htab->elf.sgot->output_section->vma
+ + htab->elf.sgot->output_offset + off);
+
+ if (GOT_TLS_GD_P (tls_type))
+ dr_type = R_X86_64_DTPMOD64;
+ else if (GOT_TLS_GDESC_P (tls_type))
+ goto dr_done;
+ else
+ dr_type = R_X86_64_TPOFF64;
+
+ bfd_put_64 (output_bfd, 0, htab->elf.sgot->contents + off);
+ outrel.r_addend = 0;
+ if ((dr_type == R_X86_64_TPOFF64
+ || dr_type == R_X86_64_TLSDESC) && indx == 0)
+ outrel.r_addend = relocation - elf_x86_64_dtpoff_base (info);
+ outrel.r_info = htab->r_info (indx, dr_type);
+
+ elf_append_rela (output_bfd, sreloc, &outrel);
+
+ if (GOT_TLS_GD_P (tls_type))
+ {
+ if (indx == 0)
+ {
+ BFD_ASSERT (! unresolved_reloc);
+ bfd_put_64 (output_bfd,
+ relocation - elf_x86_64_dtpoff_base (info),
+ htab->elf.sgot->contents + off + GOT_ENTRY_SIZE);
+ }
+ else
+ {
+ bfd_put_64 (output_bfd, 0,
+ htab->elf.sgot->contents + off + GOT_ENTRY_SIZE);
+ outrel.r_info = htab->r_info (indx,
+ R_X86_64_DTPOFF64);
+ outrel.r_offset += GOT_ENTRY_SIZE;
+ elf_append_rela (output_bfd, sreloc,
+ &outrel);
+ }
+ }
+
+ dr_done:
+ if (h != NULL)
+ h->got.offset |= 1;
+ else
+ local_got_offsets[r_symndx] |= 1;
+ }
+
+ if (off >= (bfd_vma) -2
+ && ! GOT_TLS_GDESC_P (tls_type))
+ abort ();
+ if (r_type == ELF32_R_TYPE (rel->r_info))
+ {
+ if (r_type == R_X86_64_GOTPC32_TLSDESC
+ || r_type == R_X86_64_TLSDESC_CALL)
+ relocation = htab->elf.sgotplt->output_section->vma
+ + htab->elf.sgotplt->output_offset
+ + offplt + htab->sgotplt_jump_table_size;
+ else
+ relocation = htab->elf.sgot->output_section->vma
+ + htab->elf.sgot->output_offset + off;
+ unresolved_reloc = FALSE;
+ }
+ else
+ {
+ bfd_vma roff = rel->r_offset;
+
+ if (ELF32_R_TYPE (rel->r_info) == R_X86_64_TLSGD)
+ {
+ /* GD->IE transition. For 64bit, change
+ .byte 0x66; leaq foo@tlsgd(%rip), %rdi
+ .word 0x6666; rex64; call __tls_get_addr@plt
+ into:
+ movq %fs:0, %rax
+ addq foo@gottpoff(%rip), %rax
+ For 32bit, change
+ leaq foo@tlsgd(%rip), %rdi
+ .word 0x6666; rex64; call __tls_get_addr@plt
+ into:
+ movl %fs:0, %eax
+ addq foo@gottpoff(%rip), %rax
+ For largepic, change:
+ leaq foo@tlsgd(%rip), %rdi
+ movabsq $__tls_get_addr@pltoff, %rax
+ addq %rbx, %rax
+ call *%rax
+ into:
+ movq %fs:0, %rax
+ addq foo@gottpoff(%rax), %rax
+ nopw 0x0(%rax,%rax,1) */
+ int largepic = 0;
+ if (ABI_64_P (output_bfd)
+ && contents[roff + 5] == (bfd_byte) '\xb8')
+ {
+ memcpy (contents + roff - 3,
+ "\x64\x48\x8b\x04\x25\0\0\0\0\x48\x03\x05"
+ "\0\0\0\0\x66\x0f\x1f\x44\0", 22);
+ largepic = 1;
+ }
+ else if (ABI_64_P (output_bfd))
+ memcpy (contents + roff - 4,
+ "\x64\x48\x8b\x04\x25\0\0\0\0\x48\x03\x05\0\0\0",
+ 16);
+ else
+ memcpy (contents + roff - 3,
+ "\x64\x8b\x04\x25\0\0\0\0\x48\x03\x05\0\0\0",
+ 15);
+
+ relocation = (htab->elf.sgot->output_section->vma
+ + htab->elf.sgot->output_offset + off
+ - roff
+ - largepic
+ - input_section->output_section->vma
+ - input_section->output_offset
+ - 12);
+ bfd_put_32 (output_bfd, relocation,
+ contents + roff + 8 + largepic);
+ /* Skip R_X86_64_PLT32/R_X86_64_PLTOFF64. */
+ rel++;
+ continue;
+ }
+ else if (ELF32_R_TYPE (rel->r_info) == R_X86_64_GOTPC32_TLSDESC)
+ {
+ /* GDesc -> IE transition.
+ It's originally something like:
+ leaq x@tlsdesc(%rip), %rax
+
+ Change it to:
+ movq x@gottpoff(%rip), %rax # before xchg %ax,%ax. */
+
+ /* Now modify the instruction as appropriate. To
+ turn a leaq into a movq in the form we use it, it
+ suffices to change the second byte from 0x8d to
+ 0x8b. */
+ bfd_put_8 (output_bfd, 0x8b, contents + roff - 2);
+
+ bfd_put_32 (output_bfd,
+ htab->elf.sgot->output_section->vma
+ + htab->elf.sgot->output_offset + off
+ - rel->r_offset
+ - input_section->output_section->vma
+ - input_section->output_offset
+ - 4,
+ contents + roff);
+ continue;
+ }
+ else if (ELF32_R_TYPE (rel->r_info) == R_X86_64_TLSDESC_CALL)
+ {
+ /* GDesc -> IE transition.
+ It's originally:
+ call *(%rax)
+
+ Change it to:
+ xchg %ax, %ax. */
+
+ bfd_put_8 (output_bfd, 0x66, contents + roff);
+ bfd_put_8 (output_bfd, 0x90, contents + roff + 1);
+ continue;
+ }
+ else
+ BFD_ASSERT (FALSE);
+ }
+ break;
+
+ case R_X86_64_TLSLD:
+ if (! elf_x86_64_tls_transition (info, input_bfd,
+ input_section, contents,
+ symtab_hdr, sym_hashes,
+ &r_type, GOT_UNKNOWN,
+ rel, relend, h, r_symndx))
+ return FALSE;
+
+ if (r_type != R_X86_64_TLSLD)
+ {
+ /* LD->LE transition:
+ leaq foo@tlsld(%rip), %rdi; call __tls_get_addr.
+ For 64bit, we change it into:
+ .word 0x6666; .byte 0x66; movq %fs:0, %rax.
+ For 32bit, we change it into:
+ nopl 0x0(%rax); movl %fs:0, %eax.
+ For largepic, change:
+ leaq foo@tlsgd(%rip), %rdi
+ movabsq $__tls_get_addr@pltoff, %rax
+ addq %rbx, %rax
+ call *%rax
+ into:
+ data32 data32 data32 nopw %cs:0x0(%rax,%rax,1)
+ movq %fs:0, %eax */
+
+ BFD_ASSERT (r_type == R_X86_64_TPOFF32);
+ if (ABI_64_P (output_bfd)
+ && contents[rel->r_offset + 5] == (bfd_byte) '\xb8')
+ memcpy (contents + rel->r_offset - 3,
+ "\x66\x66\x66\x66\x2e\x0f\x1f\x84\0\0\0\0\0"
+ "\x64\x48\x8b\x04\x25\0\0\0", 22);
+ else if (ABI_64_P (output_bfd))
+ memcpy (contents + rel->r_offset - 3,
+ "\x66\x66\x66\x64\x48\x8b\x04\x25\0\0\0", 12);
+ else
+ memcpy (contents + rel->r_offset - 3,
+ "\x0f\x1f\x40\x00\x64\x8b\x04\x25\0\0\0", 12);
+ /* Skip R_X86_64_PC32/R_X86_64_PLT32/R_X86_64_PLTOFF64. */
+ rel++;
+ continue;
+ }
+
+ if (htab->elf.sgot == NULL)
+ abort ();
+
+ off = htab->tls_ld_got.offset;
+ if (off & 1)
+ off &= ~1;
+ else
+ {
+ Elf_Internal_Rela outrel;
+
+ if (htab->elf.srelgot == NULL)
+ abort ();
+
+ outrel.r_offset = (htab->elf.sgot->output_section->vma
+ + htab->elf.sgot->output_offset + off);
+
+ bfd_put_64 (output_bfd, 0,
+ htab->elf.sgot->contents + off);
+ bfd_put_64 (output_bfd, 0,
+ htab->elf.sgot->contents + off + GOT_ENTRY_SIZE);
+ outrel.r_info = htab->r_info (0, R_X86_64_DTPMOD64);
+ outrel.r_addend = 0;
+ elf_append_rela (output_bfd, htab->elf.srelgot,
+ &outrel);
+ htab->tls_ld_got.offset |= 1;
+ }
+ relocation = htab->elf.sgot->output_section->vma
+ + htab->elf.sgot->output_offset + off;
+ unresolved_reloc = FALSE;
+ break;
+
+ case R_X86_64_DTPOFF32:
+ if (!info->executable|| (input_section->flags & SEC_CODE) == 0)
+ relocation -= elf_x86_64_dtpoff_base (info);
+ else
+ relocation = elf_x86_64_tpoff (info, relocation);
+ break;
+
+ case R_X86_64_TPOFF32:
+ case R_X86_64_TPOFF64:
+ BFD_ASSERT (info->executable);
+ relocation = elf_x86_64_tpoff (info, relocation);
+ break;
+
+ case R_X86_64_DTPOFF64:
+ BFD_ASSERT ((input_section->flags & SEC_CODE) == 0);
+ relocation -= elf_x86_64_dtpoff_base (info);
+ break;
+
+ default:
+ break;
+ }
+
+ /* Dynamic relocs are not propagated for SEC_DEBUGGING sections
+ because such sections are not SEC_ALLOC and thus ld.so will
+ not process them. */
+ if (unresolved_reloc
+ && !((input_section->flags & SEC_DEBUGGING) != 0
+ && h->def_dynamic)
+ && _bfd_elf_section_offset (output_bfd, info, input_section,
+ rel->r_offset) != (bfd_vma) -1)
+ {
+ (*_bfd_error_handler)
+ (_("%B(%A+0x%lx): unresolvable %s relocation against symbol `%s'"),
+ input_bfd,
+ input_section,
+ (long) rel->r_offset,
+ howto->name,
+ h->root.root.string);
+ return FALSE;
+ }
+
+do_relocation:
+ r = _bfd_final_link_relocate (howto, input_bfd, input_section,
+ contents, rel->r_offset,
+ relocation, rel->r_addend);
+
+check_relocation_error:
+ if (r != bfd_reloc_ok)
+ {
+ 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 (r == bfd_reloc_overflow)
+ {
+ if (! ((*info->callbacks->reloc_overflow)
+ (info, (h ? &h->root : NULL), name, howto->name,
+ (bfd_vma) 0, input_bfd, input_section,
+ rel->r_offset)))
+ return FALSE;
+ }
+ else
+ {
+ (*_bfd_error_handler)
+ (_("%B(%A+0x%lx): reloc against `%s': error %d"),
+ input_bfd, input_section,
+ (long) rel->r_offset, name, (int) r);
+ return FALSE;
+ }
+ }
+ }
+
+ return TRUE;
+}
+
+/* Finish up dynamic symbol handling. We set the contents of various
+ dynamic sections here. */
+
+static bfd_boolean
+elf_x86_64_finish_dynamic_symbol (bfd *output_bfd,
+ struct bfd_link_info *info,
+ struct elf_link_hash_entry *h,
+ Elf_Internal_Sym *sym ATTRIBUTE_UNUSED)
+{
+ struct elf_x86_64_link_hash_table *htab;
+ const struct elf_x86_64_backend_data *abed;
+ bfd_boolean use_plt_bnd;
+
+ htab = elf_x86_64_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ /* Use MPX backend data in case of BND relocation. Use .plt_bnd
+ section only if there is .plt section. */
+ use_plt_bnd = htab->elf.splt != NULL && htab->plt_bnd != NULL;
+ abed = (use_plt_bnd
+ ? &elf_x86_64_bnd_arch_bed
+ : get_elf_x86_64_backend_data (output_bfd));
+
+ if (h->plt.offset != (bfd_vma) -1)
+ {
+ bfd_vma plt_index;
+ bfd_vma got_offset, plt_offset, plt_plt_offset, plt_got_offset;
+ bfd_vma plt_plt_insn_end, plt_got_insn_size;
+ Elf_Internal_Rela rela;
+ bfd_byte *loc;
+ asection *plt, *gotplt, *relplt, *resolved_plt;
+ const struct elf_backend_data *bed;
+
+ /* When building a static executable, use .iplt, .igot.plt and
+ .rela.iplt sections for STT_GNU_IFUNC symbols. */
+ if (htab->elf.splt != NULL)
+ {
+ plt = htab->elf.splt;
+ gotplt = htab->elf.sgotplt;
+ relplt = htab->elf.srelplt;
+ }
+ else
+ {
+ plt = htab->elf.iplt;
+ gotplt = htab->elf.igotplt;
+ relplt = htab->elf.irelplt;
+ }
+
+ /* This symbol has an entry in the procedure linkage table. Set
+ it up. */
+ if ((h->dynindx == -1
+ && !((h->forced_local || info->executable)
+ && h->def_regular
+ && h->type == STT_GNU_IFUNC))
+ || plt == NULL
+ || gotplt == NULL
+ || relplt == NULL)
+ abort ();
+
+ /* 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.
+
+ Get the offset into the .got table of the entry that
+ corresponds to this function. Each .got entry is GOT_ENTRY_SIZE
+ bytes. The first three are reserved for the dynamic linker.
+
+ For static executables, we don't reserve anything. */
+
+ if (plt == htab->elf.splt)
+ {
+ got_offset = h->plt.offset / abed->plt_entry_size - 1;
+ got_offset = (got_offset + 3) * GOT_ENTRY_SIZE;
+ }
+ else
+ {
+ got_offset = h->plt.offset / abed->plt_entry_size;
+ got_offset = got_offset * GOT_ENTRY_SIZE;
+ }
+
+ plt_plt_insn_end = abed->plt_plt_insn_end;
+ plt_plt_offset = abed->plt_plt_offset;
+ plt_got_insn_size = abed->plt_got_insn_size;
+ plt_got_offset = abed->plt_got_offset;
+ if (use_plt_bnd)
+ {
+ /* Use the second PLT with BND relocations. */
+ const bfd_byte *plt_entry, *plt2_entry;
+ struct elf_x86_64_link_hash_entry *eh
+ = (struct elf_x86_64_link_hash_entry *) h;
+
+ if (eh->has_bnd_reloc)
+ {
+ plt_entry = elf_x86_64_bnd_plt_entry;
+ plt2_entry = elf_x86_64_bnd_plt2_entry;
+ }
+ else
+ {
+ plt_entry = elf_x86_64_legacy_plt_entry;
+ plt2_entry = elf_x86_64_legacy_plt2_entry;
+
+ /* Subtract 1 since there is no BND prefix. */
+ plt_plt_insn_end -= 1;
+ plt_plt_offset -= 1;
+ plt_got_insn_size -= 1;
+ plt_got_offset -= 1;
+ }
+
+ BFD_ASSERT (sizeof (elf_x86_64_bnd_plt_entry)
+ == sizeof (elf_x86_64_legacy_plt_entry));
+
+ /* Fill in the entry in the procedure linkage table. */
+ memcpy (plt->contents + h->plt.offset,
+ plt_entry, sizeof (elf_x86_64_legacy_plt_entry));
+ /* Fill in the entry in the second PLT. */
+ memcpy (htab->plt_bnd->contents + eh->plt_bnd.offset,
+ plt2_entry, sizeof (elf_x86_64_legacy_plt2_entry));
+
+ resolved_plt = htab->plt_bnd;
+ plt_offset = eh->plt_bnd.offset;
+ }
+ else
+ {
+ /* Fill in the entry in the procedure linkage table. */
+ memcpy (plt->contents + h->plt.offset, abed->plt_entry,
+ abed->plt_entry_size);
+
+ resolved_plt = plt;
+ plt_offset = h->plt.offset;
+ }
+
+ /* Insert the relocation positions of the plt section. */
+
+ /* Put offset the PC-relative instruction referring to the GOT entry,
+ subtracting the size of that instruction. */
+ bfd_put_32 (output_bfd,
+ (gotplt->output_section->vma
+ + gotplt->output_offset
+ + got_offset
+ - resolved_plt->output_section->vma
+ - resolved_plt->output_offset
+ - plt_offset
+ - plt_got_insn_size),
+ resolved_plt->contents + plt_offset + plt_got_offset);
+
+ /* Fill in the entry in the global offset table, initially this
+ points to the second part of the PLT entry. */
+ bfd_put_64 (output_bfd, (plt->output_section->vma
+ + plt->output_offset
+ + h->plt.offset + abed->plt_lazy_offset),
+ gotplt->contents + got_offset);
+
+ /* Fill in the entry in the .rela.plt section. */
+ rela.r_offset = (gotplt->output_section->vma
+ + gotplt->output_offset
+ + got_offset);
+ if (h->dynindx == -1
+ || ((info->executable
+ || ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
+ && h->def_regular
+ && h->type == STT_GNU_IFUNC))
+ {
+ /* If an STT_GNU_IFUNC symbol is locally defined, generate
+ R_X86_64_IRELATIVE instead of R_X86_64_JUMP_SLOT. */
+ rela.r_info = htab->r_info (0, R_X86_64_IRELATIVE);
+ rela.r_addend = (h->root.u.def.value
+ + h->root.u.def.section->output_section->vma
+ + h->root.u.def.section->output_offset);
+ /* R_X86_64_IRELATIVE comes last. */
+ plt_index = htab->next_irelative_index--;
+ }
+ else
+ {
+ rela.r_info = htab->r_info (h->dynindx, R_X86_64_JUMP_SLOT);
+ rela.r_addend = 0;
+ plt_index = htab->next_jump_slot_index++;
+ }
+
+ /* Don't fill PLT entry for static executables. */
+ if (plt == htab->elf.splt)
+ {
+ /* Put relocation index. */
+ bfd_put_32 (output_bfd, plt_index,
+ plt->contents + h->plt.offset + abed->plt_reloc_offset);
+ /* Put offset for jmp .PLT0. */
+ bfd_put_32 (output_bfd, - (h->plt.offset + plt_plt_insn_end),
+ plt->contents + h->plt.offset + plt_plt_offset);
+ }
+
+ bed = get_elf_backend_data (output_bfd);
+ loc = relplt->contents + plt_index * bed->s->sizeof_rela;
+ bed->s->swap_reloca_out (output_bfd, &rela, loc);
+
+ if (!h->def_regular)
+ {
+ /* Mark the symbol as undefined, rather than as defined in
+ the .plt section. Leave the value if there were any
+ relocations where pointer equality matters (this is a clue
+ for the dynamic linker, to make function pointer
+ comparisons work between an application and shared
+ library), otherwise set it to zero. If a function is only
+ called from a binary, there is no need to slow down
+ shared libraries because of that. */
+ sym->st_shndx = SHN_UNDEF;
+ if (!h->pointer_equality_needed)
+ sym->st_value = 0;
+ }
+ }
+
+ if (h->got.offset != (bfd_vma) -1
+ && ! GOT_TLS_GD_ANY_P (elf_x86_64_hash_entry (h)->tls_type)
+ && elf_x86_64_hash_entry (h)->tls_type != GOT_TLS_IE)
+ {
+ Elf_Internal_Rela rela;
+
+ /* This symbol has an entry in the global offset table. Set it
+ up. */
+ if (htab->elf.sgot == NULL || htab->elf.srelgot == NULL)
+ abort ();
+
+ rela.r_offset = (htab->elf.sgot->output_section->vma
+ + htab->elf.sgot->output_offset
+ + (h->got.offset &~ (bfd_vma) 1));
+
+ /* If this is a static link, or it is a -Bsymbolic link and the
+ symbol is defined locally or was forced to be local because
+ of a version file, 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 (h->def_regular
+ && h->type == STT_GNU_IFUNC)
+ {
+ if (info->shared)
+ {
+ /* Generate R_X86_64_GLOB_DAT. */
+ goto do_glob_dat;
+ }
+ else
+ {
+ asection *plt;
+
+ if (!h->pointer_equality_needed)
+ abort ();
+
+ /* For non-shared object, we can't use .got.plt, which
+ contains the real function addres if we need pointer
+ equality. We load the GOT entry with the PLT entry. */
+ plt = htab->elf.splt ? htab->elf.splt : htab->elf.iplt;
+ bfd_put_64 (output_bfd, (plt->output_section->vma
+ + plt->output_offset
+ + h->plt.offset),
+ htab->elf.sgot->contents + h->got.offset);
+ return TRUE;
+ }
+ }
+ else if (info->shared
+ && SYMBOL_REFERENCES_LOCAL (info, h))
+ {
+ if (!h->def_regular)
+ return FALSE;
+ BFD_ASSERT((h->got.offset & 1) != 0);
+ rela.r_info = htab->r_info (0, R_X86_64_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);
+do_glob_dat:
+ bfd_put_64 (output_bfd, (bfd_vma) 0,
+ htab->elf.sgot->contents + h->got.offset);
+ rela.r_info = htab->r_info (h->dynindx, R_X86_64_GLOB_DAT);
+ rela.r_addend = 0;
+ }
+
+ elf_append_rela (output_bfd, htab->elf.srelgot, &rela);
+ }
+
+ if (h->needs_copy)
+ {
+ Elf_Internal_Rela rela;
+
+ /* This symbol needs a copy reloc. Set it up. */
+
+ if (h->dynindx == -1
+ || (h->root.type != bfd_link_hash_defined
+ && h->root.type != bfd_link_hash_defweak)
+ || htab->srelbss == NULL)
+ abort ();
+
+ 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 = htab->r_info (h->dynindx, R_X86_64_COPY);
+ rela.r_addend = 0;
+ elf_append_rela (output_bfd, htab->srelbss, &rela);
+ }
+
+ return TRUE;
+}
+
+/* Finish up local dynamic symbol handling. We set the contents of
+ various dynamic sections here. */
+
+static bfd_boolean
+elf_x86_64_finish_local_dynamic_symbol (void **slot, void *inf)
+{
+ struct elf_link_hash_entry *h
+ = (struct elf_link_hash_entry *) *slot;
+ struct bfd_link_info *info
+ = (struct bfd_link_info *) inf;
+
+ return elf_x86_64_finish_dynamic_symbol (info->output_bfd,
+ info, h, NULL);
+}
+
+/* Used to decide how to sort relocs in an optimal manner for the
+ dynamic linker, before writing them out. */
+
+static enum elf_reloc_type_class
+elf_x86_64_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ const asection *rel_sec ATTRIBUTE_UNUSED,
+ const Elf_Internal_Rela *rela)
+{
+ switch ((int) ELF32_R_TYPE (rela->r_info))
+ {
+ case R_X86_64_RELATIVE:
+ case R_X86_64_RELATIVE64:
+ return reloc_class_relative;
+ case R_X86_64_JUMP_SLOT:
+ return reloc_class_plt;
+ case R_X86_64_COPY:
+ return reloc_class_copy;
+ default:
+ return reloc_class_normal;
+ }
+}
+
+/* Finish up the dynamic sections. */
+
+static bfd_boolean
+elf_x86_64_finish_dynamic_sections (bfd *output_bfd,
+ struct bfd_link_info *info)
+{
+ struct elf_x86_64_link_hash_table *htab;
+ bfd *dynobj;
+ asection *sdyn;
+ const struct elf_x86_64_backend_data *abed;
+
+ htab = elf_x86_64_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ /* Use MPX backend data in case of BND relocation. Use .plt_bnd
+ section only if there is .plt section. */
+ abed = (htab->elf.splt != NULL && htab->plt_bnd != NULL
+ ? &elf_x86_64_bnd_arch_bed
+ : get_elf_x86_64_backend_data (output_bfd));
+
+ dynobj = htab->elf.dynobj;
+ sdyn = bfd_get_linker_section (dynobj, ".dynamic");
+
+ if (htab->elf.dynamic_sections_created)
+ {
+ bfd_byte *dyncon, *dynconend;
+ const struct elf_backend_data *bed;
+ bfd_size_type sizeof_dyn;
+
+ if (sdyn == NULL || htab->elf.sgot == NULL)
+ abort ();
+
+ bed = get_elf_backend_data (dynobj);
+ sizeof_dyn = bed->s->sizeof_dyn;
+ dyncon = sdyn->contents;
+ dynconend = sdyn->contents + sdyn->size;
+ for (; dyncon < dynconend; dyncon += sizeof_dyn)
+ {
+ Elf_Internal_Dyn dyn;
+ asection *s;
+
+ (*bed->s->swap_dyn_in) (dynobj, dyncon, &dyn);
+
+ switch (dyn.d_tag)
+ {
+ default:
+ continue;
+
+ case DT_PLTGOT:
+ s = htab->elf.sgotplt;
+ dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
+ break;
+
+ case DT_JMPREL:
+ dyn.d_un.d_ptr = htab->elf.srelplt->output_section->vma;
+ break;
+
+ case DT_PLTRELSZ:
+ s = htab->elf.srelplt->output_section;
+ dyn.d_un.d_val = s->size;
+ 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. */
+ if (htab->elf.srelplt != NULL)
+ {
+ s = htab->elf.srelplt->output_section;
+ dyn.d_un.d_val -= s->size;
+ }
+ break;
+
+ case DT_TLSDESC_PLT:
+ s = htab->elf.splt;
+ dyn.d_un.d_ptr = s->output_section->vma + s->output_offset
+ + htab->tlsdesc_plt;
+ break;
+
+ case DT_TLSDESC_GOT:
+ s = htab->elf.sgot;
+ dyn.d_un.d_ptr = s->output_section->vma + s->output_offset
+ + htab->tlsdesc_got;
+ break;
+ }
+
+ (*bed->s->swap_dyn_out) (output_bfd, &dyn, dyncon);
+ }
+
+ /* Fill in the special first entry in the procedure linkage table. */
+ if (htab->elf.splt && htab->elf.splt->size > 0)
+ {
+ /* Fill in the first entry in the procedure linkage table. */
+ memcpy (htab->elf.splt->contents,
+ abed->plt0_entry, abed->plt_entry_size);
+ /* Add offset for pushq GOT+8(%rip), since the instruction
+ uses 6 bytes subtract this value. */
+ bfd_put_32 (output_bfd,
+ (htab->elf.sgotplt->output_section->vma
+ + htab->elf.sgotplt->output_offset
+ + 8
+ - htab->elf.splt->output_section->vma
+ - htab->elf.splt->output_offset
+ - 6),
+ htab->elf.splt->contents + abed->plt0_got1_offset);
+ /* Add offset for the PC-relative instruction accessing GOT+16,
+ subtracting the offset to the end of that instruction. */
+ bfd_put_32 (output_bfd,
+ (htab->elf.sgotplt->output_section->vma
+ + htab->elf.sgotplt->output_offset
+ + 16
+ - htab->elf.splt->output_section->vma
+ - htab->elf.splt->output_offset
+ - abed->plt0_got2_insn_end),
+ htab->elf.splt->contents + abed->plt0_got2_offset);
+
+ elf_section_data (htab->elf.splt->output_section)
+ ->this_hdr.sh_entsize = abed->plt_entry_size;
+
+ if (htab->tlsdesc_plt)
+ {
+ bfd_put_64 (output_bfd, (bfd_vma) 0,
+ htab->elf.sgot->contents + htab->tlsdesc_got);
+
+ memcpy (htab->elf.splt->contents + htab->tlsdesc_plt,
+ abed->plt0_entry, abed->plt_entry_size);
+
+ /* Add offset for pushq GOT+8(%rip), since the
+ instruction uses 6 bytes subtract this value. */
+ bfd_put_32 (output_bfd,
+ (htab->elf.sgotplt->output_section->vma
+ + htab->elf.sgotplt->output_offset
+ + 8
+ - htab->elf.splt->output_section->vma
+ - htab->elf.splt->output_offset
+ - htab->tlsdesc_plt
+ - 6),
+ htab->elf.splt->contents
+ + htab->tlsdesc_plt + abed->plt0_got1_offset);
+ /* Add offset for the PC-relative instruction accessing GOT+TDG,
+ where TGD stands for htab->tlsdesc_got, subtracting the offset
+ to the end of that instruction. */
+ bfd_put_32 (output_bfd,
+ (htab->elf.sgot->output_section->vma
+ + htab->elf.sgot->output_offset
+ + htab->tlsdesc_got
+ - htab->elf.splt->output_section->vma
+ - htab->elf.splt->output_offset
+ - htab->tlsdesc_plt
+ - abed->plt0_got2_insn_end),
+ htab->elf.splt->contents
+ + htab->tlsdesc_plt + abed->plt0_got2_offset);
+ }
+ }
+ }
+
+ if (htab->plt_bnd != NULL)
+ elf_section_data (htab->plt_bnd->output_section)
+ ->this_hdr.sh_entsize = sizeof (elf_x86_64_bnd_plt2_entry);
+
+ if (htab->elf.sgotplt)
+ {
+ if (bfd_is_abs_section (htab->elf.sgotplt->output_section))
+ {
+ (*_bfd_error_handler)
+ (_("discarded output section: `%A'"), htab->elf.sgotplt);
+ return FALSE;
+ }
+
+ /* Fill in the first three entries in the global offset table. */
+ if (htab->elf.sgotplt->size > 0)
+ {
+ /* Set the first entry in the global offset table to the address of
+ the dynamic section. */
+ if (sdyn == NULL)
+ bfd_put_64 (output_bfd, (bfd_vma) 0, htab->elf.sgotplt->contents);
+ else
+ bfd_put_64 (output_bfd,
+ sdyn->output_section->vma + sdyn->output_offset,
+ htab->elf.sgotplt->contents);
+ /* Write GOT[1] and GOT[2], needed for the dynamic linker. */
+ bfd_put_64 (output_bfd, (bfd_vma) 0, htab->elf.sgotplt->contents + GOT_ENTRY_SIZE);
+ bfd_put_64 (output_bfd, (bfd_vma) 0, htab->elf.sgotplt->contents + GOT_ENTRY_SIZE*2);
+ }
+
+ elf_section_data (htab->elf.sgotplt->output_section)->this_hdr.sh_entsize =
+ GOT_ENTRY_SIZE;
+ }
+
+ /* Adjust .eh_frame for .plt section. */
+ if (htab->plt_eh_frame != NULL
+ && htab->plt_eh_frame->contents != NULL)
+ {
+ if (htab->elf.splt != NULL
+ && htab->elf.splt->size != 0
+ && (htab->elf.splt->flags & SEC_EXCLUDE) == 0
+ && htab->elf.splt->output_section != NULL
+ && htab->plt_eh_frame->output_section != NULL)
+ {
+ bfd_vma plt_start = htab->elf.splt->output_section->vma;
+ bfd_vma eh_frame_start = htab->plt_eh_frame->output_section->vma
+ + htab->plt_eh_frame->output_offset
+ + PLT_FDE_START_OFFSET;
+ bfd_put_signed_32 (dynobj, plt_start - eh_frame_start,
+ htab->plt_eh_frame->contents
+ + PLT_FDE_START_OFFSET);
+ }
+ if (htab->plt_eh_frame->sec_info_type == SEC_INFO_TYPE_EH_FRAME)
+ {
+ if (! _bfd_elf_write_section_eh_frame (output_bfd, info,
+ htab->plt_eh_frame,
+ htab->plt_eh_frame->contents))
+ return FALSE;
+ }
+ }
+
+ if (htab->elf.sgot && htab->elf.sgot->size > 0)
+ elf_section_data (htab->elf.sgot->output_section)->this_hdr.sh_entsize
+ = GOT_ENTRY_SIZE;
+
+ /* Fill PLT and GOT entries for local STT_GNU_IFUNC symbols. */
+ htab_traverse (htab->loc_hash_table,
+ elf_x86_64_finish_local_dynamic_symbol,
+ info);
+
+ return TRUE;
+}
+
+/* Return an array of PLT entry symbol values. */
+
+static bfd_vma *
+elf_x86_64_get_plt_sym_val (bfd *abfd, asymbol **dynsyms, asection *plt,
+ asection *relplt)
+{
+ bfd_boolean (*slurp_relocs) (bfd *, asection *, asymbol **, bfd_boolean);
+ arelent *p;
+ long count, i;
+ bfd_vma *plt_sym_val;
+ bfd_vma plt_offset;
+ bfd_byte *plt_contents;
+ const struct elf_x86_64_backend_data *bed;
+ Elf_Internal_Shdr *hdr;
+ asection *plt_bnd;
+
+ /* Get the .plt section contents. PLT passed down may point to the
+ .plt.bnd section. Make sure that PLT always points to the .plt
+ section. */
+ plt_bnd = bfd_get_section_by_name (abfd, ".plt.bnd");
+ if (plt_bnd)
+ {
+ if (plt != plt_bnd)
+ abort ();
+ plt = bfd_get_section_by_name (abfd, ".plt");
+ if (plt == NULL)
+ abort ();
+ bed = &elf_x86_64_bnd_arch_bed;
+ }
+ else
+ bed = get_elf_x86_64_backend_data (abfd);
+
+ plt_contents = (bfd_byte *) bfd_malloc (plt->size);
+ if (plt_contents == NULL)
+ return NULL;
+ if (!bfd_get_section_contents (abfd, (asection *) plt,
+ plt_contents, 0, plt->size))
+ {
+bad_return:
+ free (plt_contents);
+ return NULL;
+ }
+
+ slurp_relocs = get_elf_backend_data (abfd)->s->slurp_reloc_table;
+ if (! (*slurp_relocs) (abfd, relplt, dynsyms, TRUE))
+ goto bad_return;
+
+ hdr = &elf_section_data (relplt)->this_hdr;
+ count = relplt->size / hdr->sh_entsize;
+
+ plt_sym_val = (bfd_vma *) bfd_malloc (sizeof (bfd_vma) * count);
+ if (plt_sym_val == NULL)
+ goto bad_return;
+
+ for (i = 0; i < count; i++, p++)
+ plt_sym_val[i] = -1;
+
+ plt_offset = bed->plt_entry_size;
+ p = relplt->relocation;
+ for (i = 0; i < count; i++, p++)
+ {
+ long reloc_index;
+
+ if (p->howto->type != R_X86_64_JUMP_SLOT
+ && p->howto->type != R_X86_64_IRELATIVE)
+ continue;
+
+ reloc_index = H_GET_32 (abfd, (plt_contents + plt_offset
+ + bed->plt_reloc_offset));
+ if (reloc_index >= count)
+ abort ();
+ if (plt_bnd)
+ {
+ /* This is the index in .plt section. */
+ long plt_index = plt_offset / bed->plt_entry_size;
+ /* Store VMA + the offset in .plt.bnd section. */
+ plt_sym_val[reloc_index] =
+ (plt_bnd->vma
+ + (plt_index - 1) * sizeof (elf_x86_64_legacy_plt2_entry));
+ }
+ else
+ plt_sym_val[reloc_index] = plt->vma + plt_offset;
+ plt_offset += bed->plt_entry_size;
+ }
+
+ free (plt_contents);
+
+ return plt_sym_val;
+}
+
+/* Similar to _bfd_elf_get_synthetic_symtab, with .plt.bnd section
+ support. */
+
+static long
+elf_x86_64_get_synthetic_symtab (bfd *abfd,
+ long symcount,
+ asymbol **syms,
+ long dynsymcount,
+ asymbol **dynsyms,
+ asymbol **ret)
+{
+ /* Pass the .plt.bnd section to _bfd_elf_ifunc_get_synthetic_symtab
+ as PLT if it exists. */
+ asection *plt = bfd_get_section_by_name (abfd, ".plt.bnd");
+ if (plt == NULL)
+ plt = bfd_get_section_by_name (abfd, ".plt");
+ return _bfd_elf_ifunc_get_synthetic_symtab (abfd, symcount, syms,
+ dynsymcount, dynsyms, ret,
+ plt,
+ elf_x86_64_get_plt_sym_val);
+}
+
+/* Handle an x86-64 specific section when reading an object file. This
+ is called when elfcode.h finds a section with an unknown type. */
+
+static bfd_boolean
+elf_x86_64_section_from_shdr (bfd *abfd, Elf_Internal_Shdr *hdr,
+ const char *name, int shindex)
+{
+ if (hdr->sh_type != SHT_X86_64_UNWIND)
+ return FALSE;
+
+ if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex))
+ return FALSE;
+
+ return TRUE;
+}
+
+/* Hook called by the linker routine which adds symbols from an object
+ file. We use it to put SHN_X86_64_LCOMMON items in .lbss, instead
+ of .bss. */
+
+static bfd_boolean
+elf_x86_64_add_symbol_hook (bfd *abfd,
+ struct bfd_link_info *info,
+ Elf_Internal_Sym *sym,
+ const char **namep ATTRIBUTE_UNUSED,
+ flagword *flagsp ATTRIBUTE_UNUSED,
+ asection **secp,
+ bfd_vma *valp)
+{
+ asection *lcomm;
+
+ switch (sym->st_shndx)
+ {
+ case SHN_X86_64_LCOMMON:
+ lcomm = bfd_get_section_by_name (abfd, "LARGE_COMMON");
+ if (lcomm == NULL)
+ {
+ lcomm = bfd_make_section_with_flags (abfd,
+ "LARGE_COMMON",
+ (SEC_ALLOC
+ | SEC_IS_COMMON
+ | SEC_LINKER_CREATED));
+ if (lcomm == NULL)
+ return FALSE;
+ elf_section_flags (lcomm) |= SHF_X86_64_LARGE;
+ }
+ *secp = lcomm;
+ *valp = sym->st_size;
+ return TRUE;
+ }
+
+ if ((ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC
+ || ELF_ST_BIND (sym->st_info) == STB_GNU_UNIQUE)
+ && (abfd->flags & DYNAMIC) == 0
+ && bfd_get_flavour (info->output_bfd) == bfd_target_elf_flavour)
+ elf_tdata (info->output_bfd)->has_gnu_symbols = TRUE;
+
+ return TRUE;
+}
+
+
+/* Given a BFD section, try to locate the corresponding ELF section
+ index. */
+
+static bfd_boolean
+elf_x86_64_elf_section_from_bfd_section (bfd *abfd ATTRIBUTE_UNUSED,
+ asection *sec, int *index_return)
+{
+ if (sec == &_bfd_elf_large_com_section)
+ {
+ *index_return = SHN_X86_64_LCOMMON;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/* Process a symbol. */
+
+static void
+elf_x86_64_symbol_processing (bfd *abfd ATTRIBUTE_UNUSED,
+ asymbol *asym)
+{
+ elf_symbol_type *elfsym = (elf_symbol_type *) asym;
+
+ switch (elfsym->internal_elf_sym.st_shndx)
+ {
+ case SHN_X86_64_LCOMMON:
+ asym->section = &_bfd_elf_large_com_section;
+ asym->value = elfsym->internal_elf_sym.st_size;
+ /* Common symbol doesn't set BSF_GLOBAL. */
+ asym->flags &= ~BSF_GLOBAL;
+ break;
+ }
+}
+
+static bfd_boolean
+elf_x86_64_common_definition (Elf_Internal_Sym *sym)
+{
+ return (sym->st_shndx == SHN_COMMON
+ || sym->st_shndx == SHN_X86_64_LCOMMON);
+}
+
+static unsigned int
+elf_x86_64_common_section_index (asection *sec)
+{
+ if ((elf_section_flags (sec) & SHF_X86_64_LARGE) == 0)
+ return SHN_COMMON;
+ else
+ return SHN_X86_64_LCOMMON;
+}
+
+static asection *
+elf_x86_64_common_section (asection *sec)
+{
+ if ((elf_section_flags (sec) & SHF_X86_64_LARGE) == 0)
+ return bfd_com_section_ptr;
+ else
+ return &_bfd_elf_large_com_section;
+}
+
+static bfd_boolean
+elf_x86_64_merge_symbol (struct elf_link_hash_entry *h,
+ const Elf_Internal_Sym *sym,
+ asection **psec,
+ bfd_boolean newdef,
+ bfd_boolean olddef,
+ bfd *oldbfd,
+ const asection *oldsec)
+{
+ /* A normal common symbol and a large common symbol result in a
+ normal common symbol. We turn the large common symbol into a
+ normal one. */
+ if (!olddef
+ && h->root.type == bfd_link_hash_common
+ && !newdef
+ && bfd_is_com_section (*psec)
+ && oldsec != *psec)
+ {
+ if (sym->st_shndx == SHN_COMMON
+ && (elf_section_flags (oldsec) & SHF_X86_64_LARGE) != 0)
+ {
+ h->root.u.c.p->section
+ = bfd_make_section_old_way (oldbfd, "COMMON");
+ h->root.u.c.p->section->flags = SEC_ALLOC;
+ }
+ else if (sym->st_shndx == SHN_X86_64_LCOMMON
+ && (elf_section_flags (oldsec) & SHF_X86_64_LARGE) == 0)
+ *psec = bfd_com_section_ptr;
+ }
+
+ return TRUE;
+}
+
+static int
+elf_x86_64_additional_program_headers (bfd *abfd,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED)
+{
+ asection *s;
+ int count = 0;
+
+ /* Check to see if we need a large readonly segment. */
+ s = bfd_get_section_by_name (abfd, ".lrodata");
+ if (s && (s->flags & SEC_LOAD))
+ count++;
+
+ /* Check to see if we need a large data segment. Since .lbss sections
+ is placed right after the .bss section, there should be no need for
+ a large data segment just because of .lbss. */
+ s = bfd_get_section_by_name (abfd, ".ldata");
+ if (s && (s->flags & SEC_LOAD))
+ count++;
+
+ return count;
+}
+
+/* Return TRUE if symbol should be hashed in the `.gnu.hash' section. */
+
+static bfd_boolean
+elf_x86_64_hash_symbol (struct elf_link_hash_entry *h)
+{
+ if (h->plt.offset != (bfd_vma) -1
+ && !h->def_regular
+ && !h->pointer_equality_needed)
+ return FALSE;
+
+ return _bfd_elf_hash_symbol (h);
+}
+
+/* Return TRUE iff relocations for INPUT are compatible with OUTPUT. */
+
+static bfd_boolean
+elf_x86_64_relocs_compatible (const bfd_target *input,
+ const bfd_target *output)
+{
+ return ((xvec_get_elf_backend_data (input)->s->elfclass
+ == xvec_get_elf_backend_data (output)->s->elfclass)
+ && _bfd_elf_relocs_compatible (input, output));
+}
+
+static const struct bfd_elf_special_section
+ elf_x86_64_special_sections[]=
+{
+ { STRING_COMMA_LEN (".gnu.linkonce.lb"), -2, SHT_NOBITS, SHF_ALLOC + SHF_WRITE + SHF_X86_64_LARGE},
+ { STRING_COMMA_LEN (".gnu.linkonce.lr"), -2, SHT_PROGBITS, SHF_ALLOC + SHF_X86_64_LARGE},
+ { STRING_COMMA_LEN (".gnu.linkonce.lt"), -2, SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR + SHF_X86_64_LARGE},
+ { STRING_COMMA_LEN (".lbss"), -2, SHT_NOBITS, SHF_ALLOC + SHF_WRITE + SHF_X86_64_LARGE},
+ { STRING_COMMA_LEN (".ldata"), -2, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE + SHF_X86_64_LARGE},
+ { STRING_COMMA_LEN (".lrodata"), -2, SHT_PROGBITS, SHF_ALLOC + SHF_X86_64_LARGE},
+ { NULL, 0, 0, 0, 0 }
+};
+
+#define TARGET_LITTLE_SYM x86_64_elf64_vec
+#define TARGET_LITTLE_NAME "elf64-x86-64"
+#define ELF_ARCH bfd_arch_i386
+#define ELF_TARGET_ID X86_64_ELF_DATA
+#define ELF_MACHINE_CODE EM_X86_64
+#define ELF_MAXPAGESIZE 0x200000
+#define ELF_MINPAGESIZE 0x1000
+#define ELF_COMMONPAGESIZE 0x1000
+
+#define elf_backend_can_gc_sections 1
+#define elf_backend_can_refcount 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 (GOT_ENTRY_SIZE*3)
+#define elf_backend_rela_normal 1
+#define elf_backend_plt_alignment 4
+
+#define elf_info_to_howto elf_x86_64_info_to_howto
+
+#define bfd_elf64_bfd_link_hash_table_create \
+ elf_x86_64_link_hash_table_create
+#define bfd_elf64_bfd_reloc_type_lookup elf_x86_64_reloc_type_lookup
+#define bfd_elf64_bfd_reloc_name_lookup \
+ elf_x86_64_reloc_name_lookup
+
+#define elf_backend_adjust_dynamic_symbol elf_x86_64_adjust_dynamic_symbol
+#define elf_backend_relocs_compatible elf_x86_64_relocs_compatible
+#define elf_backend_check_relocs elf_x86_64_check_relocs
+#define elf_backend_copy_indirect_symbol elf_x86_64_copy_indirect_symbol
+#define elf_backend_create_dynamic_sections elf_x86_64_create_dynamic_sections
+#define elf_backend_finish_dynamic_sections elf_x86_64_finish_dynamic_sections
+#define elf_backend_finish_dynamic_symbol elf_x86_64_finish_dynamic_symbol
+#define elf_backend_gc_mark_hook elf_x86_64_gc_mark_hook
+#define elf_backend_gc_sweep_hook elf_x86_64_gc_sweep_hook
+#define elf_backend_grok_prstatus elf_x86_64_grok_prstatus
+#define elf_backend_grok_psinfo elf_x86_64_grok_psinfo
+#ifdef CORE_HEADER
+#define elf_backend_write_core_note elf_x86_64_write_core_note
+#endif
+#define elf_backend_reloc_type_class elf_x86_64_reloc_type_class
+#define elf_backend_relocate_section elf_x86_64_relocate_section
+#define elf_backend_size_dynamic_sections elf_x86_64_size_dynamic_sections
+#define elf_backend_always_size_sections elf_x86_64_always_size_sections
+#define elf_backend_init_index_section _bfd_elf_init_1_index_section
+#define elf_backend_object_p elf64_x86_64_elf_object_p
+#define bfd_elf64_mkobject elf_x86_64_mkobject
+#define bfd_elf64_get_synthetic_symtab elf_x86_64_get_synthetic_symtab
+
+#define elf_backend_section_from_shdr \
+ elf_x86_64_section_from_shdr
+
+#define elf_backend_section_from_bfd_section \
+ elf_x86_64_elf_section_from_bfd_section
+#define elf_backend_add_symbol_hook \
+ elf_x86_64_add_symbol_hook
+#define elf_backend_symbol_processing \
+ elf_x86_64_symbol_processing
+#define elf_backend_common_section_index \
+ elf_x86_64_common_section_index
+#define elf_backend_common_section \
+ elf_x86_64_common_section
+#define elf_backend_common_definition \
+ elf_x86_64_common_definition
+#define elf_backend_merge_symbol \
+ elf_x86_64_merge_symbol
+#define elf_backend_special_sections \
+ elf_x86_64_special_sections
+#define elf_backend_additional_program_headers \
+ elf_x86_64_additional_program_headers
+#define elf_backend_hash_symbol \
+ elf_x86_64_hash_symbol
+
+#include "elf64-target.h"
+
+/* FreeBSD support. */
+
+#undef TARGET_LITTLE_SYM
+#define TARGET_LITTLE_SYM x86_64_elf64_fbsd_vec
+#undef TARGET_LITTLE_NAME
+#define TARGET_LITTLE_NAME "elf64-x86-64-freebsd"
+
+#undef ELF_OSABI
+#define ELF_OSABI ELFOSABI_FREEBSD
+
+#undef elf64_bed
+#define elf64_bed elf64_x86_64_fbsd_bed
+
+#include "elf64-target.h"
+
+/* Solaris 2 support. */
+
+#undef TARGET_LITTLE_SYM
+#define TARGET_LITTLE_SYM x86_64_elf64_sol2_vec
+#undef TARGET_LITTLE_NAME
+#define TARGET_LITTLE_NAME "elf64-x86-64-sol2"
+
+/* Restore default: we cannot use ELFOSABI_SOLARIS, otherwise ELFOSABI_NONE
+ objects won't be recognized. */
+#undef ELF_OSABI
+
+#undef elf64_bed
+#define elf64_bed elf64_x86_64_sol2_bed
+
+/* The 64-bit static TLS arena size is rounded to the nearest 16-byte
+ boundary. */
+#undef elf_backend_static_tls_alignment
+#define elf_backend_static_tls_alignment 16
+
+/* The Solaris 2 ABI requires a plt symbol on all platforms.
+
+ Cf. Linker and Libraries Guide, Ch. 2, Link-Editor, Generating the Output
+ File, p.63. */
+#undef elf_backend_want_plt_sym
+#define elf_backend_want_plt_sym 1
+
+#include "elf64-target.h"
+
+/* Native Client support. */
+
+static bfd_boolean
+elf64_x86_64_nacl_elf_object_p (bfd *abfd)
+{
+ /* Set the right machine number for a NaCl x86-64 ELF64 file. */
+ bfd_default_set_arch_mach (abfd, bfd_arch_i386, bfd_mach_x86_64_nacl);
+ return TRUE;
+}
+
+#undef TARGET_LITTLE_SYM
+#define TARGET_LITTLE_SYM x86_64_elf64_nacl_vec
+#undef TARGET_LITTLE_NAME
+#define TARGET_LITTLE_NAME "elf64-x86-64-nacl"
+#undef elf64_bed
+#define elf64_bed elf64_x86_64_nacl_bed
+
+#undef ELF_MAXPAGESIZE
+#undef ELF_MINPAGESIZE
+#undef ELF_COMMONPAGESIZE
+#define ELF_MAXPAGESIZE 0x10000
+#define ELF_MINPAGESIZE 0x10000
+#define ELF_COMMONPAGESIZE 0x10000
+
+/* Restore defaults. */
+#undef ELF_OSABI
+#undef elf_backend_static_tls_alignment
+#undef elf_backend_want_plt_sym
+#define elf_backend_want_plt_sym 0
+
+/* NaCl uses substantially different PLT entries for the same effects. */
+
+#undef elf_backend_plt_alignment
+#define elf_backend_plt_alignment 5
+#define NACL_PLT_ENTRY_SIZE 64
+#define NACLMASK 0xe0 /* 32-byte alignment mask. */
+
+static const bfd_byte elf_x86_64_nacl_plt0_entry[NACL_PLT_ENTRY_SIZE] =
+ {
+ 0xff, 0x35, 8, 0, 0, 0, /* pushq GOT+8(%rip) */
+ 0x4c, 0x8b, 0x1d, 16, 0, 0, 0, /* mov GOT+16(%rip), %r11 */
+ 0x41, 0x83, 0xe3, NACLMASK, /* and $-32, %r11d */
+ 0x4d, 0x01, 0xfb, /* add %r15, %r11 */
+ 0x41, 0xff, 0xe3, /* jmpq *%r11 */
+
+ /* 9-byte nop sequence to pad out to the next 32-byte boundary. */
+ 0x66, 0x0f, 0x1f, 0x84, 0, 0, 0, 0, 0, /* nopw 0x0(%rax,%rax,1) */
+
+ /* 32 bytes of nop to pad out to the standard size. */
+ 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, /* excess data32 prefixes */
+ 0x2e, 0x0f, 0x1f, 0x84, 0, 0, 0, 0, 0, /* nopw %cs:0x0(%rax,%rax,1) */
+ 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, /* excess data32 prefixes */
+ 0x2e, 0x0f, 0x1f, 0x84, 0, 0, 0, 0, 0, /* nopw %cs:0x0(%rax,%rax,1) */
+ 0x66, /* excess data32 prefix */
+ 0x90 /* nop */
+ };
+
+static const bfd_byte elf_x86_64_nacl_plt_entry[NACL_PLT_ENTRY_SIZE] =
+ {
+ 0x4c, 0x8b, 0x1d, 0, 0, 0, 0, /* mov name@GOTPCREL(%rip),%r11 */
+ 0x41, 0x83, 0xe3, NACLMASK, /* and $-32, %r11d */
+ 0x4d, 0x01, 0xfb, /* add %r15, %r11 */
+ 0x41, 0xff, 0xe3, /* jmpq *%r11 */
+
+ /* 15-byte nop sequence to pad out to the next 32-byte boundary. */
+ 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, /* excess data32 prefixes */
+ 0x2e, 0x0f, 0x1f, 0x84, 0, 0, 0, 0, 0, /* nopw %cs:0x0(%rax,%rax,1) */
+
+ /* Lazy GOT entries point here (32-byte aligned). */
+ 0x68, /* pushq immediate */
+ 0, 0, 0, 0, /* replaced with index into relocation table. */
+ 0xe9, /* jmp relative */
+ 0, 0, 0, 0, /* replaced with offset to start of .plt0. */
+
+ /* 22 bytes of nop to pad out to the standard size. */
+ 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, /* excess data32 prefixes */
+ 0x2e, 0x0f, 0x1f, 0x84, 0, 0, 0, 0, 0, /* nopw %cs:0x0(%rax,%rax,1) */
+ 0x0f, 0x1f, 0x80, 0, 0, 0, 0, /* nopl 0x0(%rax) */
+ };
+
+/* .eh_frame covering the .plt section. */
+
+static const bfd_byte elf_x86_64_nacl_eh_frame_plt[] =
+ {
+#if (PLT_CIE_LENGTH != 20 \
+ || PLT_FDE_LENGTH != 36 \
+ || PLT_FDE_START_OFFSET != 4 + PLT_CIE_LENGTH + 8 \
+ || PLT_FDE_LEN_OFFSET != 4 + PLT_CIE_LENGTH + 12)
+# error "Need elf_x86_64_backend_data parameters for eh_frame_plt offsets!"
+#endif
+ PLT_CIE_LENGTH, 0, 0, 0, /* CIE length */
+ 0, 0, 0, 0, /* CIE ID */
+ 1, /* CIE version */
+ 'z', 'R', 0, /* Augmentation string */
+ 1, /* Code alignment factor */
+ 0x78, /* Data alignment factor */
+ 16, /* Return address column */
+ 1, /* Augmentation size */
+ DW_EH_PE_pcrel | DW_EH_PE_sdata4, /* FDE encoding */
+ DW_CFA_def_cfa, 7, 8, /* DW_CFA_def_cfa: r7 (rsp) ofs 8 */
+ DW_CFA_offset + 16, 1, /* DW_CFA_offset: r16 (rip) at cfa-8 */
+ DW_CFA_nop, DW_CFA_nop,
+
+ PLT_FDE_LENGTH, 0, 0, 0, /* FDE length */
+ PLT_CIE_LENGTH + 8, 0, 0, 0,/* CIE pointer */
+ 0, 0, 0, 0, /* R_X86_64_PC32 .plt goes here */
+ 0, 0, 0, 0, /* .plt size goes here */
+ 0, /* Augmentation size */
+ DW_CFA_def_cfa_offset, 16, /* DW_CFA_def_cfa_offset: 16 */
+ DW_CFA_advance_loc + 6, /* DW_CFA_advance_loc: 6 to __PLT__+6 */
+ DW_CFA_def_cfa_offset, 24, /* DW_CFA_def_cfa_offset: 24 */
+ DW_CFA_advance_loc + 58, /* DW_CFA_advance_loc: 58 to __PLT__+64 */
+ DW_CFA_def_cfa_expression, /* DW_CFA_def_cfa_expression */
+ 13, /* Block length */
+ DW_OP_breg7, 8, /* DW_OP_breg7 (rsp): 8 */
+ DW_OP_breg16, 0, /* DW_OP_breg16 (rip): 0 */
+ DW_OP_const1u, 63, DW_OP_and, DW_OP_const1u, 37, DW_OP_ge,
+ DW_OP_lit3, DW_OP_shl, DW_OP_plus,
+ DW_CFA_nop, DW_CFA_nop
+ };
+
+static const struct elf_x86_64_backend_data elf_x86_64_nacl_arch_bed =
+ {
+ elf_x86_64_nacl_plt0_entry, /* plt0_entry */
+ elf_x86_64_nacl_plt_entry, /* plt_entry */
+ NACL_PLT_ENTRY_SIZE, /* plt_entry_size */
+ 2, /* plt0_got1_offset */
+ 9, /* plt0_got2_offset */
+ 13, /* plt0_got2_insn_end */
+ 3, /* plt_got_offset */
+ 33, /* plt_reloc_offset */
+ 38, /* plt_plt_offset */
+ 7, /* plt_got_insn_size */
+ 42, /* plt_plt_insn_end */
+ 32, /* plt_lazy_offset */
+ elf_x86_64_nacl_eh_frame_plt, /* eh_frame_plt */
+ sizeof (elf_x86_64_nacl_eh_frame_plt), /* eh_frame_plt_size */
+ };
+
+#undef elf_backend_arch_data
+#define elf_backend_arch_data &elf_x86_64_nacl_arch_bed
+
+#undef elf_backend_object_p
+#define elf_backend_object_p elf64_x86_64_nacl_elf_object_p
+#undef elf_backend_modify_segment_map
+#define elf_backend_modify_segment_map nacl_modify_segment_map
+#undef elf_backend_modify_program_headers
+#define elf_backend_modify_program_headers nacl_modify_program_headers
+#undef elf_backend_final_write_processing
+#define elf_backend_final_write_processing nacl_final_write_processing
+
+#include "elf64-target.h"
+
+/* Native Client x32 support. */
+
+static bfd_boolean
+elf32_x86_64_nacl_elf_object_p (bfd *abfd)
+{
+ /* Set the right machine number for a NaCl x86-64 ELF32 file. */
+ bfd_default_set_arch_mach (abfd, bfd_arch_i386, bfd_mach_x64_32_nacl);
+ return TRUE;
+}
+
+#undef TARGET_LITTLE_SYM
+#define TARGET_LITTLE_SYM x86_64_elf32_nacl_vec
+#undef TARGET_LITTLE_NAME
+#define TARGET_LITTLE_NAME "elf32-x86-64-nacl"
+#undef elf32_bed
+#define elf32_bed elf32_x86_64_nacl_bed
+
+#define bfd_elf32_bfd_link_hash_table_create \
+ elf_x86_64_link_hash_table_create
+#define bfd_elf32_bfd_reloc_type_lookup \
+ elf_x86_64_reloc_type_lookup
+#define bfd_elf32_bfd_reloc_name_lookup \
+ elf_x86_64_reloc_name_lookup
+#define bfd_elf32_mkobject \
+ elf_x86_64_mkobject
+#define bfd_elf32_get_synthetic_symtab \
+ elf_x86_64_get_synthetic_symtab
+
+#undef elf_backend_object_p
+#define elf_backend_object_p \
+ elf32_x86_64_nacl_elf_object_p
+
+#undef elf_backend_bfd_from_remote_memory
+#define elf_backend_bfd_from_remote_memory \
+ _bfd_elf32_bfd_from_remote_memory
+
+#undef elf_backend_size_info
+#define elf_backend_size_info \
+ _bfd_elf32_size_info
+
+#include "elf32-target.h"
+
+/* Restore defaults. */
+#undef elf_backend_object_p
+#define elf_backend_object_p elf64_x86_64_elf_object_p
+#undef elf_backend_bfd_from_remote_memory
+#undef elf_backend_size_info
+#undef elf_backend_modify_segment_map
+#undef elf_backend_modify_program_headers
+#undef elf_backend_final_write_processing
+
+/* Intel L1OM support. */
+
+static bfd_boolean
+elf64_l1om_elf_object_p (bfd *abfd)
+{
+ /* Set the right machine number for an L1OM elf64 file. */
+ bfd_default_set_arch_mach (abfd, bfd_arch_l1om, bfd_mach_l1om);
+ return TRUE;
+}
+
+#undef TARGET_LITTLE_SYM
+#define TARGET_LITTLE_SYM l1om_elf64_vec
+#undef TARGET_LITTLE_NAME
+#define TARGET_LITTLE_NAME "elf64-l1om"
+#undef ELF_ARCH
+#define ELF_ARCH bfd_arch_l1om
+
+#undef ELF_MACHINE_CODE
+#define ELF_MACHINE_CODE EM_L1OM
+
+#undef ELF_OSABI
+
+#undef elf64_bed
+#define elf64_bed elf64_l1om_bed
+
+#undef elf_backend_object_p
+#define elf_backend_object_p elf64_l1om_elf_object_p
+
+/* Restore defaults. */
+#undef ELF_MAXPAGESIZE
+#undef ELF_MINPAGESIZE
+#undef ELF_COMMONPAGESIZE
+#define ELF_MAXPAGESIZE 0x200000
+#define ELF_MINPAGESIZE 0x1000
+#define ELF_COMMONPAGESIZE 0x1000
+#undef elf_backend_plt_alignment
+#define elf_backend_plt_alignment 4
+#undef elf_backend_arch_data
+#define elf_backend_arch_data &elf_x86_64_arch_bed
+
+#include "elf64-target.h"
+
+/* FreeBSD L1OM support. */
+
+#undef TARGET_LITTLE_SYM
+#define TARGET_LITTLE_SYM l1om_elf64_fbsd_vec
+#undef TARGET_LITTLE_NAME
+#define TARGET_LITTLE_NAME "elf64-l1om-freebsd"
+
+#undef ELF_OSABI
+#define ELF_OSABI ELFOSABI_FREEBSD
+
+#undef elf64_bed
+#define elf64_bed elf64_l1om_fbsd_bed
+
+#include "elf64-target.h"
+
+/* Intel K1OM support. */
+
+static bfd_boolean
+elf64_k1om_elf_object_p (bfd *abfd)
+{
+ /* Set the right machine number for an K1OM elf64 file. */
+ bfd_default_set_arch_mach (abfd, bfd_arch_k1om, bfd_mach_k1om);
+ return TRUE;
+}
+
+#undef TARGET_LITTLE_SYM
+#define TARGET_LITTLE_SYM k1om_elf64_vec
+#undef TARGET_LITTLE_NAME
+#define TARGET_LITTLE_NAME "elf64-k1om"
+#undef ELF_ARCH
+#define ELF_ARCH bfd_arch_k1om
+
+#undef ELF_MACHINE_CODE
+#define ELF_MACHINE_CODE EM_K1OM
+
+#undef ELF_OSABI
+
+#undef elf64_bed
+#define elf64_bed elf64_k1om_bed
+
+#undef elf_backend_object_p
+#define elf_backend_object_p elf64_k1om_elf_object_p
+
+#undef elf_backend_static_tls_alignment
+
+#undef elf_backend_want_plt_sym
+#define elf_backend_want_plt_sym 0
+
+#include "elf64-target.h"
+
+/* FreeBSD K1OM support. */
+
+#undef TARGET_LITTLE_SYM
+#define TARGET_LITTLE_SYM k1om_elf64_fbsd_vec
+#undef TARGET_LITTLE_NAME
+#define TARGET_LITTLE_NAME "elf64-k1om-freebsd"
+
+#undef ELF_OSABI
+#define ELF_OSABI ELFOSABI_FREEBSD
+
+#undef elf64_bed
+#define elf64_bed elf64_k1om_fbsd_bed
+
+#include "elf64-target.h"
+
+/* 32bit x86-64 support. */
+
+#undef TARGET_LITTLE_SYM
+#define TARGET_LITTLE_SYM x86_64_elf32_vec
+#undef TARGET_LITTLE_NAME
+#define TARGET_LITTLE_NAME "elf32-x86-64"
+#undef elf32_bed
+
+#undef ELF_ARCH
+#define ELF_ARCH bfd_arch_i386
+
+#undef ELF_MACHINE_CODE
+#define ELF_MACHINE_CODE EM_X86_64
+
+#undef ELF_OSABI
+
+#undef elf_backend_object_p
+#define elf_backend_object_p \
+ elf32_x86_64_elf_object_p
+
+#undef elf_backend_bfd_from_remote_memory
+#define elf_backend_bfd_from_remote_memory \
+ _bfd_elf32_bfd_from_remote_memory
+
+#undef elf_backend_size_info
+#define elf_backend_size_info \
+ _bfd_elf32_size_info
+
+#include "elf32-target.h"
diff --git a/bfd/elf64.c b/bfd/elf64.c
new file mode 100644
index 0000000..975262d
--- /dev/null
+++ b/bfd/elf64.c
@@ -0,0 +1,23 @@
+/* ELF 64-bit executable support for BFD.
+ Copyright (C) 1993-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#define ARCH_SIZE 64
+
+#include "elfcode.h"
diff --git a/bfd/elfcode.h b/bfd/elfcode.h
new file mode 100644
index 0000000..ec53c3b
--- /dev/null
+++ b/bfd/elfcode.h
@@ -0,0 +1,1900 @@
+/* ELF executable support for BFD.
+ Copyright (C) 1991-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, 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 "sysdep.h"
+#include "bfd.h"
+#include "libiberty.h"
+#include "bfdlink.h"
+#include "libbfd.h"
+#include "elf-bfd.h"
+#include "libiberty.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_core_file_pid NAME(bfd_elf,core_file_pid)
+#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_canonicalize_symtab NAME(bfd_elf,canonicalize_symtab)
+#define elf_canonicalize_dynamic_symtab \
+ NAME(bfd_elf,canonicalize_dynamic_symtab)
+#define elf_get_synthetic_symtab \
+ NAME(bfd_elf,get_synthetic_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_write_shdrs_and_ehdr NAME(bfd_elf,write_shdrs_and_ehdr)
+#define elf_write_out_phdrs NAME(bfd_elf,write_out_phdrs)
+#define elf_checksum_contents NAME(bfd_elf,checksum_contents)
+#define elf_write_relocs NAME(bfd_elf,write_relocs)
+#define elf_slurp_reloc_table NAME(bfd_elf,slurp_reloc_table)
+
+#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
+
+#if DEBUG & 2
+static void elf_debug_section (int, Elf_Internal_Shdr *);
+#endif
+#if DEBUG & 1
+static void elf_debug_file (Elf_Internal_Ehdr *);
+#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 H_PUT_WORD H_PUT_64
+#define H_PUT_SIGNED_WORD H_PUT_S64
+#define H_GET_WORD H_GET_64
+#define H_GET_SIGNED_WORD H_GET_S64
+#endif
+#if ARCH_SIZE == 32
+#define H_PUT_WORD H_PUT_32
+#define H_PUT_SIGNED_WORD H_PUT_S32
+#define H_GET_WORD H_GET_32
+#define H_GET_SIGNED_WORD H_GET_S32
+#endif
+
+/* Translate an ELF symbol in external format into an ELF symbol in internal
+ format. */
+
+bfd_boolean
+elf_swap_symbol_in (bfd *abfd,
+ const void *psrc,
+ const void *pshn,
+ Elf_Internal_Sym *dst)
+{
+ const Elf_External_Sym *src = (const Elf_External_Sym *) psrc;
+ const Elf_External_Sym_Shndx *shndx = (const Elf_External_Sym_Shndx *) pshn;
+ int signed_vma = get_elf_backend_data (abfd)->sign_extend_vma;
+
+ dst->st_name = H_GET_32 (abfd, src->st_name);
+ if (signed_vma)
+ dst->st_value = H_GET_SIGNED_WORD (abfd, src->st_value);
+ else
+ dst->st_value = H_GET_WORD (abfd, src->st_value);
+ dst->st_size = H_GET_WORD (abfd, src->st_size);
+ dst->st_info = H_GET_8 (abfd, src->st_info);
+ dst->st_other = H_GET_8 (abfd, src->st_other);
+ dst->st_shndx = H_GET_16 (abfd, src->st_shndx);
+ if (dst->st_shndx == (SHN_XINDEX & 0xffff))
+ {
+ if (shndx == NULL)
+ return FALSE;
+ dst->st_shndx = H_GET_32 (abfd, shndx->est_shndx);
+ }
+ else if (dst->st_shndx >= (SHN_LORESERVE & 0xffff))
+ dst->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
+ dst->st_target_internal = 0;
+ return TRUE;
+}
+
+/* Translate an ELF symbol in internal format into an ELF symbol in external
+ format. */
+
+void
+elf_swap_symbol_out (bfd *abfd,
+ const Elf_Internal_Sym *src,
+ void *cdst,
+ void *shndx)
+{
+ unsigned int tmp;
+ Elf_External_Sym *dst = (Elf_External_Sym *) cdst;
+ H_PUT_32 (abfd, src->st_name, dst->st_name);
+ H_PUT_WORD (abfd, src->st_value, dst->st_value);
+ H_PUT_WORD (abfd, src->st_size, dst->st_size);
+ H_PUT_8 (abfd, src->st_info, dst->st_info);
+ H_PUT_8 (abfd, src->st_other, dst->st_other);
+ tmp = src->st_shndx;
+ if (tmp >= (SHN_LORESERVE & 0xffff) && tmp < SHN_LORESERVE)
+ {
+ if (shndx == NULL)
+ abort ();
+ H_PUT_32 (abfd, tmp, shndx);
+ tmp = SHN_XINDEX & 0xffff;
+ }
+ H_PUT_16 (abfd, tmp, 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 (bfd *abfd,
+ const Elf_External_Ehdr *src,
+ Elf_Internal_Ehdr *dst)
+{
+ int signed_vma = get_elf_backend_data (abfd)->sign_extend_vma;
+ memcpy (dst->e_ident, src->e_ident, EI_NIDENT);
+ dst->e_type = H_GET_16 (abfd, src->e_type);
+ dst->e_machine = H_GET_16 (abfd, src->e_machine);
+ dst->e_version = H_GET_32 (abfd, src->e_version);
+ if (signed_vma)
+ dst->e_entry = H_GET_SIGNED_WORD (abfd, src->e_entry);
+ else
+ dst->e_entry = H_GET_WORD (abfd, src->e_entry);
+ dst->e_phoff = H_GET_WORD (abfd, src->e_phoff);
+ dst->e_shoff = H_GET_WORD (abfd, src->e_shoff);
+ dst->e_flags = H_GET_32 (abfd, src->e_flags);
+ dst->e_ehsize = H_GET_16 (abfd, src->e_ehsize);
+ dst->e_phentsize = H_GET_16 (abfd, src->e_phentsize);
+ dst->e_phnum = H_GET_16 (abfd, src->e_phnum);
+ dst->e_shentsize = H_GET_16 (abfd, src->e_shentsize);
+ dst->e_shnum = H_GET_16 (abfd, src->e_shnum);
+ dst->e_shstrndx = H_GET_16 (abfd, 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 (bfd *abfd,
+ const Elf_Internal_Ehdr *src,
+ Elf_External_Ehdr *dst)
+{
+ unsigned int tmp;
+ int signed_vma = get_elf_backend_data (abfd)->sign_extend_vma;
+ memcpy (dst->e_ident, src->e_ident, EI_NIDENT);
+ /* note that all elements of dst are *arrays of unsigned char* already... */
+ H_PUT_16 (abfd, src->e_type, dst->e_type);
+ H_PUT_16 (abfd, src->e_machine, dst->e_machine);
+ H_PUT_32 (abfd, src->e_version, dst->e_version);
+ if (signed_vma)
+ H_PUT_SIGNED_WORD (abfd, src->e_entry, dst->e_entry);
+ else
+ H_PUT_WORD (abfd, src->e_entry, dst->e_entry);
+ H_PUT_WORD (abfd, src->e_phoff, dst->e_phoff);
+ H_PUT_WORD (abfd, src->e_shoff, dst->e_shoff);
+ H_PUT_32 (abfd, src->e_flags, dst->e_flags);
+ H_PUT_16 (abfd, src->e_ehsize, dst->e_ehsize);
+ H_PUT_16 (abfd, src->e_phentsize, dst->e_phentsize);
+ tmp = src->e_phnum;
+ if (tmp > PN_XNUM)
+ tmp = PN_XNUM;
+ H_PUT_16 (abfd, tmp, dst->e_phnum);
+ H_PUT_16 (abfd, src->e_shentsize, dst->e_shentsize);
+ tmp = src->e_shnum;
+ if (tmp >= (SHN_LORESERVE & 0xffff))
+ tmp = SHN_UNDEF;
+ H_PUT_16 (abfd, tmp, dst->e_shnum);
+ tmp = src->e_shstrndx;
+ if (tmp >= (SHN_LORESERVE & 0xffff))
+ tmp = SHN_XINDEX & 0xffff;
+ H_PUT_16 (abfd, tmp, 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 (bfd *abfd,
+ const Elf_External_Shdr *src,
+ Elf_Internal_Shdr *dst)
+{
+ int signed_vma = get_elf_backend_data (abfd)->sign_extend_vma;
+
+ dst->sh_name = H_GET_32 (abfd, src->sh_name);
+ dst->sh_type = H_GET_32 (abfd, src->sh_type);
+ dst->sh_flags = H_GET_WORD (abfd, src->sh_flags);
+ if (signed_vma)
+ dst->sh_addr = H_GET_SIGNED_WORD (abfd, src->sh_addr);
+ else
+ dst->sh_addr = H_GET_WORD (abfd, src->sh_addr);
+ dst->sh_offset = H_GET_WORD (abfd, src->sh_offset);
+ dst->sh_size = H_GET_WORD (abfd, src->sh_size);
+ dst->sh_link = H_GET_32 (abfd, src->sh_link);
+ dst->sh_info = H_GET_32 (abfd, src->sh_info);
+ dst->sh_addralign = H_GET_WORD (abfd, src->sh_addralign);
+ dst->sh_entsize = H_GET_WORD (abfd, 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 (bfd *abfd,
+ const Elf_Internal_Shdr *src,
+ Elf_External_Shdr *dst)
+{
+ /* note that all elements of dst are *arrays of unsigned char* already... */
+ H_PUT_32 (abfd, src->sh_name, dst->sh_name);
+ H_PUT_32 (abfd, src->sh_type, dst->sh_type);
+ H_PUT_WORD (abfd, src->sh_flags, dst->sh_flags);
+ H_PUT_WORD (abfd, src->sh_addr, dst->sh_addr);
+ H_PUT_WORD (abfd, src->sh_offset, dst->sh_offset);
+ H_PUT_WORD (abfd, src->sh_size, dst->sh_size);
+ H_PUT_32 (abfd, src->sh_link, dst->sh_link);
+ H_PUT_32 (abfd, src->sh_info, dst->sh_info);
+ H_PUT_WORD (abfd, src->sh_addralign, dst->sh_addralign);
+ H_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 (bfd *abfd,
+ const Elf_External_Phdr *src,
+ Elf_Internal_Phdr *dst)
+{
+ int signed_vma = get_elf_backend_data (abfd)->sign_extend_vma;
+
+ dst->p_type = H_GET_32 (abfd, src->p_type);
+ dst->p_flags = H_GET_32 (abfd, src->p_flags);
+ dst->p_offset = H_GET_WORD (abfd, src->p_offset);
+ if (signed_vma)
+ {
+ dst->p_vaddr = H_GET_SIGNED_WORD (abfd, src->p_vaddr);
+ dst->p_paddr = H_GET_SIGNED_WORD (abfd, src->p_paddr);
+ }
+ else
+ {
+ dst->p_vaddr = H_GET_WORD (abfd, src->p_vaddr);
+ dst->p_paddr = H_GET_WORD (abfd, src->p_paddr);
+ }
+ dst->p_filesz = H_GET_WORD (abfd, src->p_filesz);
+ dst->p_memsz = H_GET_WORD (abfd, src->p_memsz);
+ dst->p_align = H_GET_WORD (abfd, src->p_align);
+}
+
+void
+elf_swap_phdr_out (bfd *abfd,
+ const Elf_Internal_Phdr *src,
+ Elf_External_Phdr *dst)
+{
+ const struct elf_backend_data *bed;
+ bfd_vma p_paddr;
+
+ bed = get_elf_backend_data (abfd);
+ p_paddr = bed->want_p_paddr_set_to_zero ? 0 : src->p_paddr;
+
+ /* note that all elements of dst are *arrays of unsigned char* already... */
+ H_PUT_32 (abfd, src->p_type, dst->p_type);
+ H_PUT_WORD (abfd, src->p_offset, dst->p_offset);
+ H_PUT_WORD (abfd, src->p_vaddr, dst->p_vaddr);
+ H_PUT_WORD (abfd, p_paddr, dst->p_paddr);
+ H_PUT_WORD (abfd, src->p_filesz, dst->p_filesz);
+ H_PUT_WORD (abfd, src->p_memsz, dst->p_memsz);
+ H_PUT_32 (abfd, src->p_flags, dst->p_flags);
+ H_PUT_WORD (abfd, src->p_align, dst->p_align);
+}
+
+/* Translate an ELF reloc from external format to internal format. */
+void
+elf_swap_reloc_in (bfd *abfd,
+ const bfd_byte *s,
+ Elf_Internal_Rela *dst)
+{
+ const Elf_External_Rel *src = (const Elf_External_Rel *) s;
+ dst->r_offset = H_GET_WORD (abfd, src->r_offset);
+ dst->r_info = H_GET_WORD (abfd, src->r_info);
+ dst->r_addend = 0;
+}
+
+void
+elf_swap_reloca_in (bfd *abfd,
+ const bfd_byte *s,
+ Elf_Internal_Rela *dst)
+{
+ const Elf_External_Rela *src = (const Elf_External_Rela *) s;
+ dst->r_offset = H_GET_WORD (abfd, src->r_offset);
+ dst->r_info = H_GET_WORD (abfd, src->r_info);
+ dst->r_addend = H_GET_SIGNED_WORD (abfd, src->r_addend);
+}
+
+/* Translate an ELF reloc from internal format to external format. */
+void
+elf_swap_reloc_out (bfd *abfd,
+ const Elf_Internal_Rela *src,
+ bfd_byte *d)
+{
+ Elf_External_Rel *dst = (Elf_External_Rel *) d;
+ H_PUT_WORD (abfd, src->r_offset, dst->r_offset);
+ H_PUT_WORD (abfd, src->r_info, dst->r_info);
+}
+
+void
+elf_swap_reloca_out (bfd *abfd,
+ const Elf_Internal_Rela *src,
+ bfd_byte *d)
+{
+ Elf_External_Rela *dst = (Elf_External_Rela *) d;
+ H_PUT_WORD (abfd, src->r_offset, dst->r_offset);
+ H_PUT_WORD (abfd, src->r_info, dst->r_info);
+ H_PUT_SIGNED_WORD (abfd, src->r_addend, dst->r_addend);
+}
+
+void
+elf_swap_dyn_in (bfd *abfd,
+ const void *p,
+ Elf_Internal_Dyn *dst)
+{
+ const Elf_External_Dyn *src = (const Elf_External_Dyn *) p;
+
+ dst->d_tag = H_GET_WORD (abfd, src->d_tag);
+ dst->d_un.d_val = H_GET_WORD (abfd, src->d_un.d_val);
+}
+
+void
+elf_swap_dyn_out (bfd *abfd,
+ const Elf_Internal_Dyn *src,
+ void *p)
+{
+ Elf_External_Dyn *dst = (Elf_External_Dyn *) p;
+
+ H_PUT_WORD (abfd, src->d_tag, dst->d_tag);
+ H_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 bfd_boolean
+elf_file_p (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 (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_shdr;
+ Elf_Internal_Shdr *i_shdrp; /* Section header table, internal form */
+ unsigned int shindex;
+ const struct elf_backend_data *ebd;
+ asection *s;
+ bfd_size_type amt;
+ const bfd_target *target;
+
+ /* Read in the ELF header in external format. */
+
+ if (bfd_bread (&x_ehdr, sizeof (x_ehdr), 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)
+ || 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;
+ }
+
+ target = abfd->xvec;
+
+ /* Allocate an instance of the elf_obj_tdata structure and hook it up to
+ the tdata pointer in the bfd. */
+
+ if (! (*target->_bfd_set_format[bfd_object]) (abfd))
+ goto got_no_match;
+
+ /* 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 this is a relocatable file and there is no section header
+ table, then we're hosed. */
+ if (i_ehdrp->e_shoff == 0 && i_ehdrp->e_type == ET_REL)
+ goto got_wrong_format_error;
+
+ /* As a simple sanity check, verify that what BFD thinks is the
+ size of each section header table entry actually matches the size
+ recorded in the file, but only if there are any sections. */
+ if (i_ehdrp->e_shentsize != sizeof (x_shdr) && i_ehdrp->e_shnum != 0)
+ goto got_wrong_format_error;
+
+ /* Further sanity check. */
+ if (i_ehdrp->e_shoff == 0 && i_ehdrp->e_shnum != 0)
+ goto got_wrong_format_error;
+
+ ebd = get_elf_backend_data (abfd);
+ if (ebd->s->arch_size != ARCH_SIZE)
+ goto got_wrong_format_error;
+
+ /* 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)
+ && ebd->elf_machine_code != EM_NONE)
+ 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;
+ }
+
+ if (ebd->elf_machine_code != EM_NONE
+ && i_ehdrp->e_ident[EI_OSABI] != ebd->elf_osabi
+ && ebd->elf_osabi != ELFOSABI_NONE)
+ goto got_wrong_format_error;
+
+ if (i_ehdrp->e_shoff != 0)
+ {
+ bfd_signed_vma where = i_ehdrp->e_shoff;
+
+ if (where != (file_ptr) where)
+ goto got_wrong_format_error;
+
+ /* Seek to the section header table in the file. */
+ if (bfd_seek (abfd, (file_ptr) where, SEEK_SET) != 0)
+ goto got_no_match;
+
+ /* Read the first section header at index 0, and convert to internal
+ form. */
+ if (bfd_bread (&x_shdr, sizeof x_shdr, abfd) != sizeof (x_shdr))
+ goto got_no_match;
+ elf_swap_shdr_in (abfd, &x_shdr, &i_shdr);
+
+ /* If the section count is zero, the actual count is in the first
+ section header. */
+ if (i_ehdrp->e_shnum == SHN_UNDEF)
+ {
+ i_ehdrp->e_shnum = i_shdr.sh_size;
+ if (i_ehdrp->e_shnum >= SHN_LORESERVE
+ || i_ehdrp->e_shnum != i_shdr.sh_size
+ || i_ehdrp->e_shnum == 0)
+ goto got_wrong_format_error;
+ }
+
+ /* And similarly for the string table index. */
+ if (i_ehdrp->e_shstrndx == (SHN_XINDEX & 0xffff))
+ {
+ i_ehdrp->e_shstrndx = i_shdr.sh_link;
+ if (i_ehdrp->e_shstrndx != i_shdr.sh_link)
+ goto got_wrong_format_error;
+ }
+
+ /* And program headers. */
+ if (i_ehdrp->e_phnum == PN_XNUM && i_shdr.sh_info != 0)
+ {
+ i_ehdrp->e_phnum = i_shdr.sh_info;
+ if (i_ehdrp->e_phnum != i_shdr.sh_info)
+ goto got_wrong_format_error;
+ }
+
+ /* Sanity check that we can read all of the section headers.
+ It ought to be good enough to just read the last one. */
+ if (i_ehdrp->e_shnum != 1)
+ {
+ /* Check that we don't have a totally silly number of sections. */
+ if (i_ehdrp->e_shnum > (unsigned int) -1 / sizeof (x_shdr)
+ || i_ehdrp->e_shnum > (unsigned int) -1 / sizeof (i_shdr))
+ goto got_wrong_format_error;
+
+ where += (i_ehdrp->e_shnum - 1) * sizeof (x_shdr);
+ if (where != (file_ptr) where)
+ goto got_wrong_format_error;
+ if ((bfd_size_type) where <= i_ehdrp->e_shoff)
+ goto got_wrong_format_error;
+
+ if (bfd_seek (abfd, (file_ptr) where, SEEK_SET) != 0)
+ goto got_no_match;
+ if (bfd_bread (&x_shdr, sizeof x_shdr, abfd) != sizeof (x_shdr))
+ goto got_no_match;
+
+ /* Back to where we were. */
+ where = i_ehdrp->e_shoff + sizeof (x_shdr);
+ if (bfd_seek (abfd, (file_ptr) where, SEEK_SET) != 0)
+ goto got_no_match;
+ }
+ }
+
+ /* Allocate space for a copy of the section header table in
+ internal form. */
+ if (i_ehdrp->e_shnum != 0)
+ {
+ Elf_Internal_Shdr *shdrp;
+ unsigned int num_sec;
+
+ amt = sizeof (*i_shdrp) * i_ehdrp->e_shnum;
+ i_shdrp = (Elf_Internal_Shdr *) bfd_alloc (abfd, amt);
+ if (!i_shdrp)
+ goto got_no_match;
+ num_sec = i_ehdrp->e_shnum;
+ elf_numsections (abfd) = num_sec;
+ amt = sizeof (i_shdrp) * num_sec;
+ elf_elfsections (abfd) = (Elf_Internal_Shdr **) bfd_alloc (abfd, amt);
+ if (!elf_elfsections (abfd))
+ goto got_no_match;
+
+ memcpy (i_shdrp, &i_shdr, sizeof (*i_shdrp));
+ for (shdrp = i_shdrp, shindex = 0; shindex < num_sec; shindex++)
+ elf_elfsections (abfd)[shindex] = shdrp++;
+
+ /* Read in the rest of the section header table and convert it
+ to internal form. */
+ for (shindex = 1; shindex < i_ehdrp->e_shnum; shindex++)
+ {
+ if (bfd_bread (&x_shdr, sizeof x_shdr, abfd) != sizeof (x_shdr))
+ goto got_no_match;
+ elf_swap_shdr_in (abfd, &x_shdr, i_shdrp + shindex);
+
+ /* Sanity check sh_link and sh_info. */
+ if (i_shdrp[shindex].sh_link >= num_sec)
+ {
+ /* PR 10478: Accept Solaris binaries with a sh_link
+ field set to SHN_BEFORE or SHN_AFTER. */
+ switch (ebd->elf_machine_code)
+ {
+ case EM_386:
+ case EM_486:
+ case EM_X86_64:
+ case EM_OLD_SPARCV9:
+ case EM_SPARC32PLUS:
+ case EM_SPARCV9:
+ case EM_SPARC:
+ if (i_shdrp[shindex].sh_link == (SHN_LORESERVE & 0xffff) /* SHN_BEFORE */
+ || i_shdrp[shindex].sh_link == ((SHN_LORESERVE + 1) & 0xffff) /* SHN_AFTER */)
+ break;
+ /* Otherwise fall through. */
+ default:
+ goto got_wrong_format_error;
+ }
+ }
+
+ if (((i_shdrp[shindex].sh_flags & SHF_INFO_LINK)
+ || i_shdrp[shindex].sh_type == SHT_RELA
+ || i_shdrp[shindex].sh_type == SHT_REL)
+ && i_shdrp[shindex].sh_info >= num_sec)
+ goto got_wrong_format_error;
+
+ /* If the section is loaded, but not page aligned, clear
+ D_PAGED. */
+ if (i_shdrp[shindex].sh_size != 0
+ && (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->minpagesize)
+ != 0))
+ abfd->flags &= ~D_PAGED;
+ }
+ }
+
+ /* A further sanity check. */
+ if (i_ehdrp->e_shnum != 0)
+ {
+ if (i_ehdrp->e_shstrndx >= elf_numsections (abfd))
+ {
+ /* PR 2257:
+ We used to just goto got_wrong_format_error here
+ but there are binaries in existance for which this test
+ will prevent the binutils from working with them at all.
+ So we are kind, and reset the string index value to 0
+ so that at least some processing can be done. */
+ i_ehdrp->e_shstrndx = SHN_UNDEF;
+ _bfd_error_handler (_("warning: %s has a corrupt string table index - ignoring"), abfd->filename);
+ }
+ }
+ else if (i_ehdrp->e_shstrndx != SHN_UNDEF)
+ goto got_wrong_format_error;
+
+ /* 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;
+
+ amt = i_ehdrp->e_phnum * sizeof (Elf_Internal_Phdr);
+ elf_tdata (abfd)->phdr = (Elf_Internal_Phdr *) bfd_alloc (abfd, amt);
+ if (elf_tdata (abfd)->phdr == NULL)
+ goto got_no_match;
+ if (bfd_seek (abfd, (file_ptr) 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_bread (&x_phdr, sizeof x_phdr, abfd) != sizeof x_phdr)
+ goto got_no_match;
+ elf_swap_phdr_in (abfd, &x_phdr, i_phdr);
+ }
+ }
+
+ if (i_ehdrp->e_shstrndx != 0 && i_ehdrp->e_shoff != 0)
+ {
+ unsigned int num_sec;
+
+ /* 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. */
+ num_sec = elf_numsections (abfd);
+ for (shindex = 1; shindex < num_sec; shindex++)
+ if (!bfd_section_from_shdr (abfd, shindex))
+ goto got_no_match;
+
+ /* Set up ELF sections for SHF_GROUP and SHF_LINK_ORDER. */
+ if (! _bfd_elf_setup_sections (abfd))
+ goto got_wrong_format_error;
+ }
+
+ /* Let the backend double check the format and override global
+ information. */
+ if (ebd->elf_backend_object_p)
+ {
+ if (! (*ebd->elf_backend_object_p) (abfd))
+ goto got_wrong_format_error;
+ }
+
+ /* Remember the entry point specified in the ELF file header. */
+ bfd_set_start_address (abfd, i_ehdrp->e_entry);
+
+ /* 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 target;
+
+ got_wrong_format_error:
+ bfd_set_error (bfd_error_wrong_format);
+
+ got_no_match:
+ return NULL;
+}
+
+/* ELF .o/exec file writing */
+
+/* Write out the relocs. */
+
+void
+elf_write_relocs (bfd *abfd, asection *sec, void *data)
+{
+ bfd_boolean *failedp = (bfd_boolean *) data;
+ Elf_Internal_Shdr *rela_hdr;
+ bfd_vma addr_offset;
+ void (*swap_out) (bfd *, const Elf_Internal_Rela *, bfd_byte *);
+ size_t extsize;
+ bfd_byte *dst_rela;
+ unsigned int idx;
+ asymbol *last_sym;
+ int last_sym_idx;
+
+ /* 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;
+
+ /* If we have opened an existing file for update, reloc_count may be
+ set even though we are not linking. In that case we have nothing
+ to do. */
+ if (sec->orelocation == NULL)
+ return;
+
+ rela_hdr = elf_section_data (sec)->rela.hdr;
+ if (rela_hdr == NULL)
+ rela_hdr = elf_section_data (sec)->rel.hdr;
+
+ rela_hdr->sh_size = rela_hdr->sh_entsize * sec->reloc_count;
+ rela_hdr->contents = (unsigned char *) bfd_alloc (abfd, rela_hdr->sh_size);
+ if (rela_hdr->contents == NULL)
+ {
+ *failedp = TRUE;
+ return;
+ }
+
+ /* Figure out whether the relocations are RELA or REL relocations. */
+ if (rela_hdr->sh_type == SHT_RELA)
+ {
+ swap_out = elf_swap_reloca_out;
+ extsize = sizeof (Elf_External_Rela);
+ }
+ else if (rela_hdr->sh_type == SHT_REL)
+ {
+ swap_out = elf_swap_reloc_out;
+ extsize = sizeof (Elf_External_Rel);
+ }
+ else
+ /* Every relocation section should be either an SHT_RELA or an
+ SHT_REL section. */
+ abort ();
+
+ /* 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. */
+ addr_offset = 0;
+ if ((abfd->flags & (EXEC_P | DYNAMIC)) != 0)
+ addr_offset = sec->vma;
+
+ /* orelocation has the data, reloc_count has the count... */
+ last_sym = 0;
+ last_sym_idx = 0;
+ dst_rela = rela_hdr->contents;
+
+ for (idx = 0; idx < sec->reloc_count; idx++, dst_rela += extsize)
+ {
+ Elf_Internal_Rela src_rela;
+ arelent *ptr;
+ asymbol *sym;
+ int n;
+
+ ptr = sec->orelocation[idx];
+ 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;
+ }
+
+ src_rela.r_offset = ptr->address + addr_offset;
+ src_rela.r_info = ELF_R_INFO (n, ptr->howto->type);
+ src_rela.r_addend = ptr->addend;
+ (*swap_out) (abfd, &src_rela, dst_rela);
+ }
+}
+
+/* Write out the program headers. */
+
+int
+elf_write_out_phdrs (bfd *abfd,
+ const Elf_Internal_Phdr *phdr,
+ unsigned int count)
+{
+ while (count--)
+ {
+ Elf_External_Phdr extphdr;
+ elf_swap_phdr_out (abfd, phdr, &extphdr);
+ if (bfd_bwrite (&extphdr, sizeof (Elf_External_Phdr), abfd)
+ != sizeof (Elf_External_Phdr))
+ return -1;
+ phdr++;
+ }
+ return 0;
+}
+
+/* Write out the section headers and the ELF file header. */
+
+bfd_boolean
+elf_write_shdrs_and_ehdr (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;
+ bfd_size_type amt;
+
+ 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);
+ amt = sizeof (x_ehdr);
+ if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0
+ || bfd_bwrite (&x_ehdr, amt, abfd) != amt)
+ return FALSE;
+
+ /* Some fields in the first section header handle overflow of ehdr
+ fields. */
+ if (i_ehdrp->e_phnum >= PN_XNUM)
+ i_shdrp[0]->sh_info = i_ehdrp->e_phnum;
+ if (i_ehdrp->e_shnum >= (SHN_LORESERVE & 0xffff))
+ i_shdrp[0]->sh_size = i_ehdrp->e_shnum;
+ if (i_ehdrp->e_shstrndx >= (SHN_LORESERVE & 0xffff))
+ i_shdrp[0]->sh_link = i_ehdrp->e_shstrndx;
+
+ /* at this point we've concocted all the ELF sections... */
+ amt = i_ehdrp->e_shnum;
+ amt *= sizeof (*x_shdrp);
+ x_shdrp = (Elf_External_Shdr *) bfd_alloc (abfd, amt);
+ if (!x_shdrp)
+ return FALSE;
+
+ for (count = 0; count < i_ehdrp->e_shnum; i_shdrp++, count++)
+ {
+#if DEBUG & 2
+ elf_debug_section (count, *i_shdrp);
+#endif
+ elf_swap_shdr_out (abfd, *i_shdrp, x_shdrp + count);
+ }
+ if (bfd_seek (abfd, (file_ptr) i_ehdrp->e_shoff, SEEK_SET) != 0
+ || bfd_bwrite (x_shdrp, amt, abfd) != amt)
+ return FALSE;
+
+ /* need to dump the string table too... */
+
+ return TRUE;
+}
+
+bfd_boolean
+elf_checksum_contents (bfd *abfd,
+ void (*process) (const void *, size_t, void *),
+ void *arg)
+{
+ Elf_Internal_Ehdr *i_ehdrp = elf_elfheader (abfd);
+ Elf_Internal_Shdr **i_shdrp = elf_elfsections (abfd);
+ Elf_Internal_Phdr *i_phdrp = elf_tdata (abfd)->phdr;
+ unsigned int count, num;
+
+ {
+ Elf_External_Ehdr x_ehdr;
+ Elf_Internal_Ehdr i_ehdr;
+
+ i_ehdr = *i_ehdrp;
+ i_ehdr.e_phoff = i_ehdr.e_shoff = 0;
+ elf_swap_ehdr_out (abfd, &i_ehdr, &x_ehdr);
+ (*process) (&x_ehdr, sizeof x_ehdr, arg);
+ }
+
+ num = i_ehdrp->e_phnum;
+ for (count = 0; count < num; count++)
+ {
+ Elf_External_Phdr x_phdr;
+ elf_swap_phdr_out (abfd, &i_phdrp[count], &x_phdr);
+ (*process) (&x_phdr, sizeof x_phdr, arg);
+ }
+
+ num = elf_numsections (abfd);
+ for (count = 0; count < num; count++)
+ {
+ Elf_Internal_Shdr i_shdr;
+ Elf_External_Shdr x_shdr;
+ bfd_byte *contents, *free_contents;
+
+ i_shdr = *i_shdrp[count];
+ i_shdr.sh_offset = 0;
+
+ elf_swap_shdr_out (abfd, &i_shdr, &x_shdr);
+ (*process) (&x_shdr, sizeof x_shdr, arg);
+
+ /* Process the section's contents, if it has some.
+ PR ld/12451: Read them in if necessary. */
+ if (i_shdr.sh_type == SHT_NOBITS)
+ continue;
+ free_contents = NULL;
+ contents = i_shdr.contents;
+ if (contents == NULL)
+ {
+ asection *sec;
+
+ sec = bfd_section_from_elf_index (abfd, count);
+ if (sec != NULL)
+ {
+ contents = sec->contents;
+ if (contents == NULL)
+ {
+ /* Force rereading from file. */
+ sec->flags &= ~SEC_IN_MEMORY;
+ if (!bfd_malloc_and_get_section (abfd, sec, &free_contents))
+ continue;
+ contents = free_contents;
+ }
+ }
+ }
+ if (contents != NULL)
+ {
+ (*process) (contents, i_shdr.sh_size, arg);
+ if (free_contents != NULL)
+ free (free_contents);
+ }
+ }
+
+ return TRUE;
+}
+
+long
+elf_slurp_symbol_table (bfd *abfd, asymbol **symptrs, bfd_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 *isym;
+ Elf_Internal_Sym *isymend;
+ Elf_Internal_Sym *isymbuf = NULL;
+ Elf_External_Versym *xver;
+ Elf_External_Versym *xverbuf = NULL;
+ const struct elf_backend_data *ebd;
+ bfd_size_type amt;
+
+ /* 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_dynverdef (abfd) != 0
+ && elf_tdata (abfd)->verdef == NULL)
+ || (elf_dynverref (abfd) != 0
+ && elf_tdata (abfd)->verref == NULL))
+ {
+ if (!_bfd_elf_slurp_version_tables (abfd, FALSE))
+ return -1;
+ }
+ }
+
+ ebd = get_elf_backend_data (abfd);
+ symcount = hdr->sh_size / sizeof (Elf_External_Sym);
+ if (symcount == 0)
+ sym = symbase = NULL;
+ else
+ {
+ isymbuf = bfd_elf_get_elf_syms (abfd, hdr, symcount, 0,
+ NULL, NULL, NULL);
+ if (isymbuf == NULL)
+ return -1;
+
+ amt = symcount;
+ amt *= sizeof (elf_symbol_type);
+ symbase = (elf_symbol_type *) bfd_zalloc (abfd, amt);
+ if (symbase == (elf_symbol_type *) NULL)
+ 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;
+
+ xverbuf = (Elf_External_Versym *) bfd_malloc (verhdr->sh_size);
+ if (xverbuf == NULL && verhdr->sh_size != 0)
+ goto error_return;
+
+ if (bfd_bread (xverbuf, verhdr->sh_size, abfd) != verhdr->sh_size)
+ goto error_return;
+ }
+
+ /* Skip first symbol, which is a null dummy. */
+ xver = xverbuf;
+ if (xver != NULL)
+ ++xver;
+ isymend = isymbuf + symcount;
+ for (isym = isymbuf + 1, sym = symbase; isym < isymend; isym++, sym++)
+ {
+ memcpy (&sym->internal_elf_sym, isym, sizeof (Elf_Internal_Sym));
+ sym->symbol.the_bfd = abfd;
+
+ sym->symbol.name = bfd_elf_sym_name (abfd, hdr, isym, NULL);
+
+ sym->symbol.value = isym->st_value;
+
+ if (isym->st_shndx == SHN_UNDEF)
+ {
+ sym->symbol.section = bfd_und_section_ptr;
+ }
+ else if (isym->st_shndx == SHN_ABS)
+ {
+ sym->symbol.section = bfd_abs_section_ptr;
+ }
+ else if (isym->st_shndx == SHN_COMMON)
+ {
+ sym->symbol.section = bfd_com_section_ptr;
+ if ((abfd->flags & BFD_PLUGIN) != 0)
+ {
+ asection *xc = bfd_get_section_by_name (abfd, "COMMON");
+
+ if (xc == NULL)
+ {
+ flagword flags = (SEC_ALLOC | SEC_IS_COMMON | SEC_KEEP
+ | SEC_EXCLUDE);
+ xc = bfd_make_section_with_flags (abfd, "COMMON", flags);
+ if (xc == NULL)
+ goto error_return;
+ }
+ sym->symbol.section = xc;
+ }
+ /* 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 = isym->st_size;
+ }
+ else
+ {
+ sym->symbol.section
+ = bfd_section_from_elf_index (abfd, isym->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;
+ }
+ }
+
+ /* If this is a relocatable 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 (isym->st_info))
+ {
+ case STB_LOCAL:
+ sym->symbol.flags |= BSF_LOCAL;
+ break;
+ case STB_GLOBAL:
+ if (isym->st_shndx != SHN_UNDEF && isym->st_shndx != SHN_COMMON)
+ sym->symbol.flags |= BSF_GLOBAL;
+ break;
+ case STB_WEAK:
+ sym->symbol.flags |= BSF_WEAK;
+ break;
+ case STB_GNU_UNIQUE:
+ sym->symbol.flags |= BSF_GNU_UNIQUE;
+ break;
+ }
+
+ switch (ELF_ST_TYPE (isym->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_COMMON:
+ /* FIXME: Do we have to put the size field into the value field
+ as we do with symbols in SHN_COMMON sections (see above) ? */
+ /* Fall through. */
+ case STT_OBJECT:
+ sym->symbol.flags |= BSF_OBJECT;
+ break;
+ case STT_TLS:
+ sym->symbol.flags |= BSF_THREAD_LOCAL;
+ break;
+ case STT_RELC:
+ sym->symbol.flags |= BSF_RELC;
+ break;
+ case STT_SRELC:
+ sym->symbol.flags |= BSF_SRELC;
+ break;
+ case STT_GNU_IFUNC:
+ sym->symbol.flags |= BSF_GNU_INDIRECT_FUNCTION;
+ break;
+ }
+
+ if (dynamic)
+ sym->symbol.flags |= BSF_DYNAMIC;
+
+ if (xver != NULL)
+ {
+ Elf_Internal_Versym iversym;
+
+ _bfd_elf_swap_versym_in (abfd, xver, &iversym);
+ sym->version = iversym.vs_vers;
+ xver++;
+ }
+
+ /* Do some backend-specific processing on this symbol. */
+ if (ebd->elf_backend_symbol_processing)
+ (*ebd->elf_backend_symbol_processing) (abfd, &sym->symbol);
+ }
+ }
+
+ /* Do some backend-specific processing on this symbol table. */
+ 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 (xverbuf != NULL)
+ free (xverbuf);
+ if (isymbuf != NULL && hdr->contents != (unsigned char *) isymbuf)
+ free (isymbuf);
+ return symcount;
+
+error_return:
+ if (xverbuf != NULL)
+ free (xverbuf);
+ if (isymbuf != NULL && hdr->contents != (unsigned char *) isymbuf)
+ free (isymbuf);
+ return -1;
+}
+
+/* Read relocations for ASECT from REL_HDR. There are RELOC_COUNT of
+ them. */
+
+static bfd_boolean
+elf_slurp_reloc_table_from_section (bfd *abfd,
+ asection *asect,
+ Elf_Internal_Shdr *rel_hdr,
+ bfd_size_type reloc_count,
+ arelent *relents,
+ asymbol **symbols,
+ bfd_boolean dynamic)
+{
+ const struct elf_backend_data * const ebd = get_elf_backend_data (abfd);
+ void *allocated = NULL;
+ bfd_byte *native_relocs;
+ arelent *relent;
+ unsigned int i;
+ int entsize;
+ unsigned int symcount;
+
+ allocated = bfd_malloc (rel_hdr->sh_size);
+ if (allocated == NULL)
+ goto error_return;
+
+ if (bfd_seek (abfd, rel_hdr->sh_offset, SEEK_SET) != 0
+ || (bfd_bread (allocated, rel_hdr->sh_size, abfd)
+ != rel_hdr->sh_size))
+ goto error_return;
+
+ native_relocs = (bfd_byte *) allocated;
+
+ entsize = rel_hdr->sh_entsize;
+ BFD_ASSERT (entsize == sizeof (Elf_External_Rel)
+ || entsize == sizeof (Elf_External_Rela));
+
+ if (dynamic)
+ symcount = bfd_get_dynamic_symcount (abfd);
+ else
+ symcount = bfd_get_symcount (abfd);
+
+ for (i = 0, relent = relents;
+ i < reloc_count;
+ i++, relent++, native_relocs += entsize)
+ {
+ Elf_Internal_Rela rela;
+
+ if (entsize == sizeof (Elf_External_Rela))
+ elf_swap_reloca_in (abfd, native_relocs, &rela);
+ else
+ elf_swap_reloc_in (abfd, native_relocs, &rela);
+
+ /* 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) == STN_UNDEF)
+ relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
+ else if (ELF_R_SYM (rela.r_info) > symcount)
+ {
+ (*_bfd_error_handler)
+ (_("%s(%s): relocation %d has invalid symbol index %ld"),
+ abfd->filename, asect->name, i, ELF_R_SYM (rela.r_info));
+ relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
+ }
+ else
+ {
+ asymbol **ps;
+
+ ps = symbols + ELF_R_SYM (rela.r_info) - 1;
+
+ relent->sym_ptr_ptr = ps;
+ }
+
+ relent->addend = rela.r_addend;
+
+ if ((entsize == sizeof (Elf_External_Rela)
+ && ebd->elf_info_to_howto != NULL)
+ || ebd->elf_info_to_howto_rel == NULL)
+ (*ebd->elf_info_to_howto) (abfd, relent, &rela);
+ else
+ (*ebd->elf_info_to_howto_rel) (abfd, relent, &rela);
+ }
+
+ if (allocated != NULL)
+ free (allocated);
+
+ return TRUE;
+
+ error_return:
+ if (allocated != NULL)
+ free (allocated);
+ return FALSE;
+}
+
+/* Read in and swap the external relocs. */
+
+bfd_boolean
+elf_slurp_reloc_table (bfd *abfd,
+ asection *asect,
+ asymbol **symbols,
+ bfd_boolean dynamic)
+{
+ struct bfd_elf_section_data * const d = elf_section_data (asect);
+ Elf_Internal_Shdr *rel_hdr;
+ Elf_Internal_Shdr *rel_hdr2;
+ bfd_size_type reloc_count;
+ bfd_size_type reloc_count2;
+ arelent *relents;
+ bfd_size_type amt;
+
+ 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 = rel_hdr ? NUM_SHDR_ENTRIES (rel_hdr) : 0;
+ rel_hdr2 = d->rela.hdr;
+ reloc_count2 = rel_hdr2 ? NUM_SHDR_ENTRIES (rel_hdr2) : 0;
+
+ BFD_ASSERT (asect->reloc_count == reloc_count + reloc_count2);
+ BFD_ASSERT ((rel_hdr && asect->rel_filepos == rel_hdr->sh_offset)
+ || (rel_hdr2 && asect->rel_filepos == rel_hdr2->sh_offset));
+
+ }
+ else
+ {
+ /* Note that ASECT->RELOC_COUNT tends not to be accurate in this
+ case because relocations against this section may use the
+ dynamic symbol table, and in that case bfd_section_from_shdr
+ in elf.c does not update the RELOC_COUNT. */
+ if (asect->size == 0)
+ return TRUE;
+
+ rel_hdr = &d->this_hdr;
+ reloc_count = NUM_SHDR_ENTRIES (rel_hdr);
+ rel_hdr2 = NULL;
+ reloc_count2 = 0;
+ }
+
+ amt = (reloc_count + reloc_count2) * sizeof (arelent);
+ relents = (arelent *) bfd_alloc (abfd, amt);
+ if (relents == NULL)
+ return FALSE;
+
+ if (rel_hdr
+ && !elf_slurp_reloc_table_from_section (abfd, asect,
+ rel_hdr, reloc_count,
+ relents,
+ symbols, dynamic))
+ return FALSE;
+
+ if (rel_hdr2
+ && !elf_slurp_reloc_table_from_section (abfd, asect,
+ rel_hdr2, reloc_count2,
+ relents + reloc_count,
+ symbols, dynamic))
+ return FALSE;
+
+ asect->relocation = relents;
+ return TRUE;
+}
+
+#if DEBUG & 2
+static void
+elf_debug_section (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);
+}
+#endif
+
+#if DEBUG & 1
+static void
+elf_debug_file (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);
+}
+#endif
+
+/* Create a new BFD as if by bfd_openr. Rather than opening a file,
+ reconstruct an ELF file by reading the segments out of remote
+ memory based on the ELF file header at EHDR_VMA and the ELF program
+ headers it points to. If non-zero, SIZE is the known extent of the
+ object. If not null, *LOADBASEP is filled in with the difference
+ between the VMAs from which the segments were read, and the VMAs
+ the file headers (and hence BFD's idea of each section's VMA) put
+ them at.
+
+ The function TARGET_READ_MEMORY is called to copy LEN bytes from
+ the remote memory at target address VMA into the local buffer at
+ MYADDR; it should return zero on success or an `errno' code on
+ failure. TEMPL must be a BFD for a target with the word size and
+ byte order found in the remote memory. */
+
+bfd *
+NAME(_bfd_elf,bfd_from_remote_memory)
+ (bfd *templ,
+ bfd_vma ehdr_vma,
+ bfd_size_type size,
+ bfd_vma *loadbasep,
+ int (*target_read_memory) (bfd_vma, bfd_byte *, bfd_size_type))
+{
+ Elf_External_Ehdr x_ehdr; /* Elf file header, external form */
+ Elf_Internal_Ehdr i_ehdr; /* Elf file header, internal form */
+ Elf_External_Phdr *x_phdrs;
+ Elf_Internal_Phdr *i_phdrs, *last_phdr, *first_phdr;
+ bfd *nbfd;
+ struct bfd_in_memory *bim;
+ bfd_byte *contents;
+ int err;
+ unsigned int i;
+ bfd_vma high_offset;
+ bfd_vma shdr_end;
+ bfd_vma loadbase;
+
+ /* Read in the ELF header in external format. */
+ err = target_read_memory (ehdr_vma, (bfd_byte *) &x_ehdr, sizeof x_ehdr);
+ if (err)
+ {
+ bfd_set_error (bfd_error_system_call);
+ errno = err;
+ return NULL;
+ }
+
+ /* 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. */
+
+ if (! elf_file_p (&x_ehdr)
+ || x_ehdr.e_ident[EI_VERSION] != EV_CURRENT
+ || x_ehdr.e_ident[EI_CLASS] != ELFCLASS)
+ {
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+
+ /* 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 (templ))
+ {
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+ break;
+ case ELFDATA2LSB: /* Little-endian */
+ if (! bfd_header_little_endian (templ))
+ {
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+ break;
+ case ELFDATANONE: /* No data encoding specified */
+ default: /* Unknown data encoding specified */
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+
+ elf_swap_ehdr_in (templ, &x_ehdr, &i_ehdr);
+
+ /* The file header tells where to find the program headers.
+ These are what we use to actually choose what to read. */
+
+ if (i_ehdr.e_phentsize != sizeof (Elf_External_Phdr) || i_ehdr.e_phnum == 0)
+ {
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+
+ x_phdrs = (Elf_External_Phdr *)
+ bfd_malloc (i_ehdr.e_phnum * (sizeof *x_phdrs + sizeof *i_phdrs));
+ if (x_phdrs == NULL)
+ return NULL;
+ err = target_read_memory (ehdr_vma + i_ehdr.e_phoff, (bfd_byte *) x_phdrs,
+ i_ehdr.e_phnum * sizeof x_phdrs[0]);
+ if (err)
+ {
+ free (x_phdrs);
+ bfd_set_error (bfd_error_system_call);
+ errno = err;
+ return NULL;
+ }
+ i_phdrs = (Elf_Internal_Phdr *) &x_phdrs[i_ehdr.e_phnum];
+
+ high_offset = 0;
+ loadbase = 0;
+ first_phdr = NULL;
+ last_phdr = NULL;
+ for (i = 0; i < i_ehdr.e_phnum; ++i)
+ {
+ elf_swap_phdr_in (templ, &x_phdrs[i], &i_phdrs[i]);
+ if (i_phdrs[i].p_type == PT_LOAD)
+ {
+ bfd_vma segment_end = i_phdrs[i].p_offset + i_phdrs[i].p_filesz;
+
+ if (segment_end > high_offset)
+ {
+ high_offset = segment_end;
+ last_phdr = &i_phdrs[i];
+ }
+
+ /* If this program header covers offset zero, where the file
+ header sits, then we can figure out the loadbase. */
+ if (first_phdr == NULL)
+ {
+ bfd_vma p_offset = i_phdrs[i].p_offset;
+ bfd_vma p_vaddr = i_phdrs[i].p_vaddr;
+
+ if (i_phdrs[i].p_align > 1)
+ {
+ p_offset &= -i_phdrs[i].p_align;
+ p_vaddr &= -i_phdrs[i].p_align;
+ }
+ if (p_offset == 0)
+ {
+ loadbase = ehdr_vma - p_vaddr;
+ first_phdr = &i_phdrs[i];
+ }
+ }
+ }
+ }
+ if (high_offset == 0)
+ {
+ /* There were no PT_LOAD segments, so we don't have anything to read. */
+ free (x_phdrs);
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+
+ shdr_end = 0;
+ if (i_ehdr.e_shoff != 0 && i_ehdr.e_shnum != 0 && i_ehdr.e_shentsize != 0)
+ {
+ shdr_end = i_ehdr.e_shoff + i_ehdr.e_shnum * i_ehdr.e_shentsize;
+
+ if (last_phdr->p_filesz != last_phdr->p_memsz)
+ {
+ /* If the last PT_LOAD header has a bss area then ld.so will
+ have cleared anything past p_filesz, zapping the section
+ headers. */
+ }
+ else if (size >= shdr_end)
+ high_offset = size;
+ else
+ {
+ bfd_vma page_size = get_elf_backend_data (templ)->minpagesize;
+ bfd_vma segment_end = last_phdr->p_offset + last_phdr->p_filesz;
+
+ /* Assume we loaded full pages, allowing us to sometimes see
+ section headers. */
+ if (page_size > 1 && shdr_end > segment_end)
+ {
+ bfd_vma page_end = (segment_end + page_size - 1) & -page_size;
+
+ if (page_end >= shdr_end)
+ /* Whee, section headers covered. */
+ high_offset = shdr_end;
+ }
+ }
+ }
+
+ /* Now we know the size of the whole image we want read in. */
+ contents = (bfd_byte *) bfd_zmalloc (high_offset);
+ if (contents == NULL)
+ {
+ free (x_phdrs);
+ return NULL;
+ }
+
+ for (i = 0; i < i_ehdr.e_phnum; ++i)
+ if (i_phdrs[i].p_type == PT_LOAD)
+ {
+ bfd_vma start = i_phdrs[i].p_offset;
+ bfd_vma end = start + i_phdrs[i].p_filesz;
+ bfd_vma vaddr = i_phdrs[i].p_vaddr;
+
+ /* Extend the beginning of the first pt_load to cover file
+ header and program headers, if we proved earlier that its
+ aligned offset is 0. */
+ if (first_phdr == &i_phdrs[i])
+ {
+ vaddr -= start;
+ start = 0;
+ }
+ /* Extend the end of the last pt_load to cover section headers. */
+ if (last_phdr == &i_phdrs[i])
+ end = high_offset;
+ err = target_read_memory (loadbase + vaddr,
+ contents + start, end - start);
+ if (err)
+ {
+ free (x_phdrs);
+ free (contents);
+ bfd_set_error (bfd_error_system_call);
+ errno = err;
+ return NULL;
+ }
+ }
+ free (x_phdrs);
+
+ /* If the segments visible in memory didn't include the section headers,
+ then clear them from the file header. */
+ if (high_offset < shdr_end)
+ {
+ memset (&x_ehdr.e_shoff, 0, sizeof x_ehdr.e_shoff);
+ memset (&x_ehdr.e_shnum, 0, sizeof x_ehdr.e_shnum);
+ memset (&x_ehdr.e_shstrndx, 0, sizeof x_ehdr.e_shstrndx);
+ }
+
+ /* This will normally have been in the first PT_LOAD segment. But it
+ conceivably could be missing, and we might have just changed it. */
+ memcpy (contents, &x_ehdr, sizeof x_ehdr);
+
+ /* Now we have a memory image of the ELF file contents. Make a BFD. */
+ bim = (struct bfd_in_memory *) bfd_malloc (sizeof (struct bfd_in_memory));
+ if (bim == NULL)
+ {
+ free (contents);
+ return NULL;
+ }
+ nbfd = _bfd_new_bfd ();
+ if (nbfd == NULL)
+ {
+ free (bim);
+ free (contents);
+ return NULL;
+ }
+ nbfd->filename = xstrdup ("<in-memory>");
+ nbfd->xvec = templ->xvec;
+ bim->size = high_offset;
+ bim->buffer = contents;
+ nbfd->iostream = bim;
+ nbfd->flags = BFD_IN_MEMORY;
+ nbfd->iovec = &_bfd_memory_iovec;
+ nbfd->origin = 0;
+ nbfd->direction = read_direction;
+ nbfd->mtime = time (NULL);
+ nbfd->mtime_set = TRUE;
+
+ if (loadbasep)
+ *loadbasep = loadbase;
+ return nbfd;
+}
+
+/* Function for ELF_R_INFO. */
+
+bfd_vma
+NAME(elf,r_info) (bfd_vma sym, bfd_vma type)
+{
+ return ELF_R_INFO (sym, type);
+}
+
+/* Function for ELF_R_SYM. */
+
+bfd_vma
+NAME(elf,r_sym) (bfd_vma r_info)
+{
+ return ELF_R_SYM (r_info);
+}
+
+#include "elfcore.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),
+ 4,
+ 1,
+ ARCH_SIZE, LOG_FILE_ALIGN,
+ ELFCLASS, EV_CURRENT,
+ elf_write_out_phdrs,
+ elf_write_shdrs_and_ehdr,
+ elf_checksum_contents,
+ elf_write_relocs,
+ elf_swap_symbol_in,
+ elf_swap_symbol_out,
+ elf_slurp_reloc_table,
+ elf_slurp_symbol_table,
+ elf_swap_dyn_in,
+ elf_swap_dyn_out,
+ elf_swap_reloc_in,
+ elf_swap_reloc_out,
+ elf_swap_reloca_in,
+ elf_swap_reloca_out
+};
diff --git a/bfd/elfcore.h b/bfd/elfcore.h
new file mode 100644
index 0000000..97fd7ab
--- /dev/null
+++ b/bfd/elfcore.h
@@ -0,0 +1,319 @@
+/* ELF core file support for BFD.
+ Copyright (C) 1995-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+char*
+elf_core_file_failing_command (bfd *abfd)
+{
+ return elf_tdata (abfd)->core->command;
+}
+
+int
+elf_core_file_failing_signal (bfd *abfd)
+{
+ return elf_tdata (abfd)->core->signal;
+}
+
+int
+elf_core_file_pid (bfd *abfd)
+{
+ return elf_tdata (abfd)->core->pid;
+}
+
+bfd_boolean
+elf_core_file_matches_executable_p (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 (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;
+ const struct elf_backend_data *ebd;
+ bfd_size_type amt;
+
+ /* Read in the ELF header in external format. */
+ if (bfd_bread (&x_ehdr, sizeof (x_ehdr), abfd) != sizeof (x_ehdr))
+ {
+ if (bfd_get_error () != bfd_error_system_call)
+ goto wrong;
+ else
+ goto fail;
+ }
+
+ /* Check the magic number. */
+ if (! elf_file_p (&x_ehdr))
+ goto wrong;
+
+ /* 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. */
+ if (! (*abfd->xvec->_bfd_set_format[bfd_core]) (abfd))
+ goto fail;
+
+ /* 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++)
+ {
+ const struct elf_backend_data *back;
+
+ if ((*target_ptr)->flavour != bfd_target_elf_flavour)
+ continue;
+ back = xvec_get_elf_backend_data (*target_ptr);
+ if (back->s->arch_size != ARCH_SIZE)
+ continue;
+ if (back->elf_machine_code == i_ehdrp->e_machine
+ || (back->elf_machine_alt1 != 0
+ && i_ehdrp->e_machine == back->elf_machine_alt1)
+ || (back->elf_machine_alt2 != 0
+ && i_ehdrp->e_machine == back->elf_machine_alt2))
+ {
+ /* 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;
+
+ /* If the program header count is PN_XNUM(0xffff), the actual
+ count is in the first section header. */
+ if (i_ehdrp->e_shoff != 0 && i_ehdrp->e_phnum == PN_XNUM)
+ {
+ Elf_External_Shdr x_shdr;
+ Elf_Internal_Shdr i_shdr;
+ bfd_signed_vma where = i_ehdrp->e_shoff;
+
+ if (where != (file_ptr) where)
+ goto wrong;
+
+ /* Seek to the section header table in the file. */
+ if (bfd_seek (abfd, (file_ptr) where, SEEK_SET) != 0)
+ goto fail;
+
+ /* Read the first section header at index 0, and convert to internal
+ form. */
+ if (bfd_bread (&x_shdr, sizeof (x_shdr), abfd) != sizeof (x_shdr))
+ goto fail;
+ elf_swap_shdr_in (abfd, &x_shdr, &i_shdr);
+
+ if (i_shdr.sh_info != 0)
+ {
+ i_ehdrp->e_phnum = i_shdr.sh_info;
+ if (i_ehdrp->e_phnum != i_shdr.sh_info)
+ goto wrong;
+ }
+ }
+
+ /* Sanity check that we can read all of the program headers.
+ It ought to be good enough to just read the last one. */
+ if (i_ehdrp->e_phnum > 1)
+ {
+ Elf_External_Phdr x_phdr;
+ Elf_Internal_Phdr i_phdr;
+ bfd_signed_vma where;
+
+ /* Check that we don't have a totally silly number of
+ program headers. */
+ if (i_ehdrp->e_phnum > (unsigned int) -1 / sizeof (x_phdr)
+ || i_ehdrp->e_phnum > (unsigned int) -1 / sizeof (i_phdr))
+ goto wrong;
+
+ where = i_ehdrp->e_phoff + (i_ehdrp->e_phnum - 1) * sizeof (x_phdr);
+ if (where != (file_ptr) where)
+ goto wrong;
+ if ((bfd_size_type) where <= i_ehdrp->e_phoff)
+ goto wrong;
+
+ if (bfd_seek (abfd, (file_ptr) where, SEEK_SET) != 0)
+ goto fail;
+ if (bfd_bread (&x_phdr, sizeof (x_phdr), abfd) != sizeof (x_phdr))
+ goto fail;
+ }
+
+ /* Move to the start of the program headers. */
+ if (bfd_seek (abfd, (file_ptr) i_ehdrp->e_phoff, SEEK_SET) != 0)
+ goto wrong;
+
+ /* Allocate space for the program headers. */
+ amt = sizeof (*i_phdrp) * i_ehdrp->e_phnum;
+ i_phdrp = (Elf_Internal_Phdr *) bfd_alloc (abfd, amt);
+ if (!i_phdrp)
+ goto fail;
+
+ 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_bread (&x_phdr, sizeof (x_phdr), abfd) != sizeof (x_phdr))
+ goto fail;
+
+ elf_swap_phdr_in (abfd, &x_phdr, i_phdrp + phindex);
+ }
+
+ /* Set the machine architecture. Do this before processing the
+ program headers since we need to know the architecture type
+ when processing the notes of some systems' core files. */
+ if (! bfd_default_set_arch_mach (abfd, ebd->arch, 0)
+ /* It's OK if this fails for the generic target. */
+ && ebd->elf_machine_code != EM_NONE)
+ goto fail;
+
+ /* Let the backend double check the format and override global
+ information. We do this before processing the program headers
+ to allow the correct machine (as opposed to just the default
+ machine) to be set, making it possible for grok_prstatus and
+ grok_psinfo to rely on the mach setting. */
+ if (ebd->elf_backend_object_p != NULL
+ && ! ebd->elf_backend_object_p (abfd))
+ goto wrong;
+
+ /* Process each program header. */
+ for (phindex = 0; phindex < i_ehdrp->e_phnum; ++phindex)
+ if (! bfd_section_from_phdr (abfd, i_phdrp + phindex, (int) phindex))
+ goto fail;
+
+ /* Check for core truncation. */
+ {
+ bfd_size_type high = 0;
+ struct stat statbuf;
+ for (phindex = 0; phindex < i_ehdrp->e_phnum; ++phindex)
+ {
+ Elf_Internal_Phdr *p = i_phdrp + phindex;
+ if (p->p_filesz)
+ {
+ bfd_size_type current = p->p_offset + p->p_filesz;
+ if (high < current)
+ high = current;
+ }
+ }
+ if (bfd_stat (abfd, &statbuf) == 0)
+ {
+ if ((bfd_size_type) statbuf.st_size < high)
+ {
+ (*_bfd_error_handler)
+ (_("Warning: %B is truncated: expected core file "
+ "size >= %lu, found: %lu."),
+ abfd, (unsigned long) high, (unsigned long) statbuf.st_size);
+ }
+ }
+ }
+
+ /* Save the entry point from the ELF header. */
+ bfd_get_start_address (abfd) = i_ehdrp->e_entry;
+ return abfd->xvec;
+
+wrong:
+ bfd_set_error (bfd_error_wrong_format);
+fail:
+ return NULL;
+}
diff --git a/bfd/elflink.c b/bfd/elflink.c
new file mode 100644
index 0000000..94ab762
--- /dev/null
+++ b/bfd/elflink.c
@@ -0,0 +1,13064 @@
+/* ELF linking support for BFD.
+ Copyright (C) 1995-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "bfdlink.h"
+#include "libbfd.h"
+#define ARCH_SIZE 0
+#include "elf-bfd.h"
+#include "safe-ctype.h"
+#include "libiberty.h"
+#include "objalloc.h"
+
+/* This struct is used to pass information to routines called via
+ elf_link_hash_traverse which must return failure. */
+
+struct elf_info_failed
+{
+ struct bfd_link_info *info;
+ bfd_boolean failed;
+};
+
+/* This structure is used to pass information to
+ _bfd_elf_link_find_version_dependencies. */
+
+struct elf_find_verdep_info
+{
+ /* General link information. */
+ struct bfd_link_info *info;
+ /* The number of dependencies. */
+ unsigned int vers;
+ /* Whether we had a failure. */
+ bfd_boolean failed;
+};
+
+static bfd_boolean _bfd_elf_fix_symbol_flags
+ (struct elf_link_hash_entry *, struct elf_info_failed *);
+
+/* Define a symbol in a dynamic linkage section. */
+
+struct elf_link_hash_entry *
+_bfd_elf_define_linkage_sym (bfd *abfd,
+ struct bfd_link_info *info,
+ asection *sec,
+ const char *name)
+{
+ struct elf_link_hash_entry *h;
+ struct bfd_link_hash_entry *bh;
+ const struct elf_backend_data *bed;
+
+ h = elf_link_hash_lookup (elf_hash_table (info), name, FALSE, FALSE, FALSE);
+ if (h != NULL)
+ {
+ /* Zap symbol defined in an as-needed lib that wasn't linked.
+ This is a symptom of a larger problem: Absolute symbols
+ defined in shared libraries can't be overridden, because we
+ lose the link to the bfd which is via the symbol section. */
+ h->root.type = bfd_link_hash_new;
+ }
+
+ bh = &h->root;
+ if (!_bfd_generic_link_add_one_symbol (info, abfd, name, BSF_GLOBAL,
+ sec, 0, NULL, FALSE,
+ get_elf_backend_data (abfd)->collect,
+ &bh))
+ return NULL;
+ h = (struct elf_link_hash_entry *) bh;
+ h->def_regular = 1;
+ h->non_elf = 0;
+ h->type = STT_OBJECT;
+ if (ELF_ST_VISIBILITY (h->other) != STV_INTERNAL)
+ h->other = (h->other & ~ELF_ST_VISIBILITY (-1)) | STV_HIDDEN;
+
+ bed = get_elf_backend_data (abfd);
+ (*bed->elf_backend_hide_symbol) (info, h, TRUE);
+ return h;
+}
+
+bfd_boolean
+_bfd_elf_create_got_section (bfd *abfd, struct bfd_link_info *info)
+{
+ flagword flags;
+ asection *s;
+ struct elf_link_hash_entry *h;
+ const struct elf_backend_data *bed = get_elf_backend_data (abfd);
+ struct elf_link_hash_table *htab = elf_hash_table (info);
+
+ /* This function may be called more than once. */
+ s = bfd_get_linker_section (abfd, ".got");
+ if (s != NULL)
+ return TRUE;
+
+ flags = bed->dynamic_sec_flags;
+
+ s = bfd_make_section_anyway_with_flags (abfd,
+ (bed->rela_plts_and_copies_p
+ ? ".rela.got" : ".rel.got"),
+ (bed->dynamic_sec_flags
+ | SEC_READONLY));
+ if (s == NULL
+ || ! bfd_set_section_alignment (abfd, s, bed->s->log_file_align))
+ return FALSE;
+ htab->srelgot = s;
+
+ s = bfd_make_section_anyway_with_flags (abfd, ".got", flags);
+ if (s == NULL
+ || !bfd_set_section_alignment (abfd, s, bed->s->log_file_align))
+ return FALSE;
+ htab->sgot = s;
+
+ if (bed->want_got_plt)
+ {
+ s = bfd_make_section_anyway_with_flags (abfd, ".got.plt", flags);
+ if (s == NULL
+ || !bfd_set_section_alignment (abfd, s,
+ bed->s->log_file_align))
+ return FALSE;
+ htab->sgotplt = s;
+ }
+
+ /* The first bit of the global offset table is the header. */
+ s->size += bed->got_header_size;
+
+ if (bed->want_got_sym)
+ {
+ /* 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 = _bfd_elf_define_linkage_sym (abfd, info, s,
+ "_GLOBAL_OFFSET_TABLE_");
+ elf_hash_table (info)->hgot = h;
+ if (h == NULL)
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/* Create a strtab to hold the dynamic symbol names. */
+static bfd_boolean
+_bfd_elf_link_create_dynstrtab (bfd *abfd, struct bfd_link_info *info)
+{
+ struct elf_link_hash_table *hash_table;
+
+ hash_table = elf_hash_table (info);
+ if (hash_table->dynobj == NULL)
+ hash_table->dynobj = abfd;
+
+ if (hash_table->dynstr == NULL)
+ {
+ hash_table->dynstr = _bfd_elf_strtab_init ();
+ if (hash_table->dynstr == NULL)
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/* 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. */
+
+bfd_boolean
+_bfd_elf_link_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
+{
+ flagword flags;
+ asection *s;
+ const struct elf_backend_data *bed;
+ struct elf_link_hash_entry *h;
+
+ if (! is_elf_hash_table (info->hash))
+ return FALSE;
+
+ if (elf_hash_table (info)->dynamic_sections_created)
+ return TRUE;
+
+ if (!_bfd_elf_link_create_dynstrtab (abfd, info))
+ return FALSE;
+
+ abfd = elf_hash_table (info)->dynobj;
+ bed = get_elf_backend_data (abfd);
+
+ flags = bed->dynamic_sec_flags;
+
+ /* A dynamically linked executable has a .interp section, but a
+ shared library does not. */
+ if (info->executable)
+ {
+ s = bfd_make_section_anyway_with_flags (abfd, ".interp",
+ flags | SEC_READONLY);
+ if (s == NULL)
+ return FALSE;
+ }
+
+ /* Create sections to hold version informations. These are removed
+ if they are not needed. */
+ s = bfd_make_section_anyway_with_flags (abfd, ".gnu.version_d",
+ flags | SEC_READONLY);
+ if (s == NULL
+ || ! bfd_set_section_alignment (abfd, s, bed->s->log_file_align))
+ return FALSE;
+
+ s = bfd_make_section_anyway_with_flags (abfd, ".gnu.version",
+ flags | SEC_READONLY);
+ if (s == NULL
+ || ! bfd_set_section_alignment (abfd, s, 1))
+ return FALSE;
+
+ s = bfd_make_section_anyway_with_flags (abfd, ".gnu.version_r",
+ flags | SEC_READONLY);
+ if (s == NULL
+ || ! bfd_set_section_alignment (abfd, s, bed->s->log_file_align))
+ return FALSE;
+
+ s = bfd_make_section_anyway_with_flags (abfd, ".dynsym",
+ flags | SEC_READONLY);
+ if (s == NULL
+ || ! bfd_set_section_alignment (abfd, s, bed->s->log_file_align))
+ return FALSE;
+
+ s = bfd_make_section_anyway_with_flags (abfd, ".dynstr",
+ flags | SEC_READONLY);
+ if (s == NULL)
+ return FALSE;
+
+ s = bfd_make_section_anyway_with_flags (abfd, ".dynamic", flags);
+ if (s == NULL
+ || ! bfd_set_section_alignment (abfd, s, bed->s->log_file_align))
+ return FALSE;
+
+ /* The special symbol _DYNAMIC is always set to the start of the
+ .dynamic section. 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 = _bfd_elf_define_linkage_sym (abfd, info, s, "_DYNAMIC");
+ elf_hash_table (info)->hdynamic = h;
+ if (h == NULL)
+ return FALSE;
+
+ if (info->emit_hash)
+ {
+ s = bfd_make_section_anyway_with_flags (abfd, ".hash",
+ flags | SEC_READONLY);
+ if (s == NULL
+ || ! bfd_set_section_alignment (abfd, s, bed->s->log_file_align))
+ return FALSE;
+ elf_section_data (s)->this_hdr.sh_entsize = bed->s->sizeof_hash_entry;
+ }
+
+ if (info->emit_gnu_hash)
+ {
+ s = bfd_make_section_anyway_with_flags (abfd, ".gnu.hash",
+ flags | SEC_READONLY);
+ if (s == NULL
+ || ! bfd_set_section_alignment (abfd, s, bed->s->log_file_align))
+ return FALSE;
+ /* For 64-bit ELF, .gnu.hash is a non-uniform entity size section:
+ 4 32-bit words followed by variable count of 64-bit words, then
+ variable count of 32-bit words. */
+ if (bed->s->arch_size == 64)
+ elf_section_data (s)->this_hdr.sh_entsize = 0;
+ else
+ elf_section_data (s)->this_hdr.sh_entsize = 4;
+ }
+
+ /* 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. */
+ if (bed->elf_backend_create_dynamic_sections == NULL
+ || ! (*bed->elf_backend_create_dynamic_sections) (abfd, info))
+ return FALSE;
+
+ elf_hash_table (info)->dynamic_sections_created = TRUE;
+
+ return TRUE;
+}
+
+/* Create dynamic sections when linking against a dynamic object. */
+
+bfd_boolean
+_bfd_elf_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
+{
+ flagword flags, pltflags;
+ struct elf_link_hash_entry *h;
+ asection *s;
+ const struct elf_backend_data *bed = get_elf_backend_data (abfd);
+ struct elf_link_hash_table *htab = elf_hash_table (info);
+
+ /* We need to create .plt, .rel[a].plt, .got, .got.plt, .dynbss, and
+ .rel[a].bss sections. */
+ flags = bed->dynamic_sec_flags;
+
+ pltflags = flags;
+ if (bed->plt_not_loaded)
+ /* We do not clear SEC_ALLOC here because we still want the OS to
+ allocate space for the section; it's just that there's nothing
+ to read in from the object file. */
+ pltflags &= ~ (SEC_CODE | SEC_LOAD | SEC_HAS_CONTENTS);
+ else
+ pltflags |= SEC_ALLOC | SEC_CODE | SEC_LOAD;
+ if (bed->plt_readonly)
+ pltflags |= SEC_READONLY;
+
+ s = bfd_make_section_anyway_with_flags (abfd, ".plt", pltflags);
+ if (s == NULL
+ || ! bfd_set_section_alignment (abfd, s, bed->plt_alignment))
+ return FALSE;
+ htab->splt = s;
+
+ /* Define the symbol _PROCEDURE_LINKAGE_TABLE_ at the start of the
+ .plt section. */
+ if (bed->want_plt_sym)
+ {
+ h = _bfd_elf_define_linkage_sym (abfd, info, s,
+ "_PROCEDURE_LINKAGE_TABLE_");
+ elf_hash_table (info)->hplt = h;
+ if (h == NULL)
+ return FALSE;
+ }
+
+ s = bfd_make_section_anyway_with_flags (abfd,
+ (bed->rela_plts_and_copies_p
+ ? ".rela.plt" : ".rel.plt"),
+ flags | SEC_READONLY);
+ if (s == NULL
+ || ! bfd_set_section_alignment (abfd, s, bed->s->log_file_align))
+ return FALSE;
+ htab->srelplt = s;
+
+ if (! _bfd_elf_create_got_section (abfd, info))
+ return FALSE;
+
+ if (bed->want_dynbss)
+ {
+ /* 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_anyway_with_flags (abfd, ".dynbss",
+ (SEC_ALLOC | SEC_LINKER_CREATED));
+ if (s == NULL)
+ 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_anyway_with_flags (abfd,
+ (bed->rela_plts_and_copies_p
+ ? ".rela.bss" : ".rel.bss"),
+ flags | SEC_READONLY);
+ if (s == NULL
+ || ! bfd_set_section_alignment (abfd, s, bed->s->log_file_align))
+ 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. */
+
+bfd_boolean
+bfd_elf_link_record_dynamic_symbol (struct bfd_link_info *info,
+ struct elf_link_hash_entry *h)
+{
+ if (h->dynindx == -1)
+ {
+ struct elf_strtab_hash *dynstr;
+ char *p;
+ const char *name;
+ bfd_size_type indx;
+
+ /* XXX: The ABI draft says the linker must turn hidden and
+ internal symbols into STB_LOCAL symbols when producing the
+ DSO. However, if ld.so honors st_other in the dynamic table,
+ this would not be necessary. */
+ switch (ELF_ST_VISIBILITY (h->other))
+ {
+ case STV_INTERNAL:
+ case STV_HIDDEN:
+ if (h->root.type != bfd_link_hash_undefined
+ && h->root.type != bfd_link_hash_undefweak)
+ {
+ h->forced_local = 1;
+ if (!elf_hash_table (info)->is_relocatable_executable)
+ return TRUE;
+ }
+
+ default:
+ break;
+ }
+
+ 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_strtab_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)
+ /* We know that the p points into writable memory. In fact,
+ there are only a few symbols that have read-only names, being
+ those like _GLOBAL_OFFSET_TABLE_ that are created specially
+ by the backends. Most symbols will have names pointing into
+ an ELF string table read from a file, or to objalloc memory. */
+ *p = 0;
+
+ indx = _bfd_elf_strtab_add (dynstr, name, p != NULL);
+
+ if (p != NULL)
+ *p = ELF_VER_CHR;
+
+ if (indx == (bfd_size_type) -1)
+ return FALSE;
+ h->dynstr_index = indx;
+ }
+
+ return TRUE;
+}
+
+/* Mark a symbol dynamic. */
+
+static void
+bfd_elf_link_mark_dynamic_symbol (struct bfd_link_info *info,
+ struct elf_link_hash_entry *h,
+ Elf_Internal_Sym *sym)
+{
+ struct bfd_elf_dynamic_list *d = info->dynamic_list;
+
+ /* It may be called more than once on the same H. */
+ if(h->dynamic || info->relocatable)
+ return;
+
+ if ((info->dynamic_data
+ && (h->type == STT_OBJECT
+ || (sym != NULL
+ && ELF_ST_TYPE (sym->st_info) == STT_OBJECT)))
+ || (d != NULL
+ && h->root.type == bfd_link_hash_new
+ && (*d->match) (&d->head, NULL, h->root.root.string)))
+ h->dynamic = 1;
+}
+
+/* Record an assignment to a symbol made by a linker script. We need
+ this in case some dynamic object refers to this symbol. */
+
+bfd_boolean
+bfd_elf_record_link_assignment (bfd *output_bfd,
+ struct bfd_link_info *info,
+ const char *name,
+ bfd_boolean provide,
+ bfd_boolean hidden)
+{
+ struct elf_link_hash_entry *h, *hv;
+ struct elf_link_hash_table *htab;
+ const struct elf_backend_data *bed;
+
+ if (!is_elf_hash_table (info->hash))
+ return TRUE;
+
+ htab = elf_hash_table (info);
+ h = elf_link_hash_lookup (htab, name, !provide, TRUE, FALSE);
+ if (h == NULL)
+ return provide;
+
+ switch (h->root.type)
+ {
+ case bfd_link_hash_defined:
+ case bfd_link_hash_defweak:
+ case bfd_link_hash_common:
+ break;
+ case bfd_link_hash_undefweak:
+ case bfd_link_hash_undefined:
+ /* Since we're defining the symbol, don't let it seem to have not
+ been defined. record_dynamic_symbol and size_dynamic_sections
+ may depend on this. */
+ h->root.type = bfd_link_hash_new;
+ if (h->root.u.undef.next != NULL || htab->root.undefs_tail == &h->root)
+ bfd_link_repair_undef_list (&htab->root);
+ break;
+ case bfd_link_hash_new:
+ bfd_elf_link_mark_dynamic_symbol (info, h, NULL);
+ h->non_elf = 0;
+ break;
+ case bfd_link_hash_indirect:
+ /* We had a versioned symbol in a dynamic library. We make the
+ the versioned symbol point to this one. */
+ bed = get_elf_backend_data (output_bfd);
+ hv = h;
+ while (hv->root.type == bfd_link_hash_indirect
+ || hv->root.type == bfd_link_hash_warning)
+ hv = (struct elf_link_hash_entry *) hv->root.u.i.link;
+ /* We don't need to update h->root.u since linker will set them
+ later. */
+ h->root.type = bfd_link_hash_undefined;
+ hv->root.type = bfd_link_hash_indirect;
+ hv->root.u.i.link = (struct bfd_link_hash_entry *) h;
+ (*bed->elf_backend_copy_indirect_symbol) (info, h, hv);
+ break;
+ case bfd_link_hash_warning:
+ abort ();
+ break;
+ }
+
+ /* 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->def_dynamic
+ && !h->def_regular)
+ 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->def_dynamic
+ && !h->def_regular)
+ h->verinfo.verdef = NULL;
+
+ h->def_regular = 1;
+
+ if (hidden)
+ {
+ bed = get_elf_backend_data (output_bfd);
+ if (ELF_ST_VISIBILITY (h->other) != STV_INTERNAL)
+ h->other = (h->other & ~ELF_ST_VISIBILITY (-1)) | STV_HIDDEN;
+ (*bed->elf_backend_hide_symbol) (info, h, TRUE);
+ }
+
+ /* STV_HIDDEN and STV_INTERNAL symbols must be STB_LOCAL in shared objects
+ and executables. */
+ if (!info->relocatable
+ && h->dynindx != -1
+ && (ELF_ST_VISIBILITY (h->other) == STV_HIDDEN
+ || ELF_ST_VISIBILITY (h->other) == STV_INTERNAL))
+ h->forced_local = 1;
+
+ if ((h->def_dynamic
+ || h->ref_dynamic
+ || info->shared
+ || (info->executable && elf_hash_table (info)->is_relocatable_executable))
+ && 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->u.weakdef != NULL
+ && h->u.weakdef->dynindx == -1)
+ {
+ if (! bfd_elf_link_record_dynamic_symbol (info, h->u.weakdef))
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+/* Record a new local dynamic symbol. Returns 0 on failure, 1 on
+ success, and 2 on a failure caused by attempting to record a symbol
+ in a discarded section, eg. a discarded link-once section symbol. */
+
+int
+bfd_elf_link_record_local_dynamic_symbol (struct bfd_link_info *info,
+ bfd *input_bfd,
+ long input_indx)
+{
+ bfd_size_type amt;
+ struct elf_link_local_dynamic_entry *entry;
+ struct elf_link_hash_table *eht;
+ struct elf_strtab_hash *dynstr;
+ unsigned long dynstr_index;
+ char *name;
+ Elf_External_Sym_Shndx eshndx;
+ char esym[sizeof (Elf64_External_Sym)];
+
+ if (! is_elf_hash_table (info->hash))
+ return 0;
+
+ /* See if the entry exists already. */
+ for (entry = elf_hash_table (info)->dynlocal; entry ; entry = entry->next)
+ if (entry->input_bfd == input_bfd && entry->input_indx == input_indx)
+ return 1;
+
+ amt = sizeof (*entry);
+ entry = (struct elf_link_local_dynamic_entry *) bfd_alloc (input_bfd, amt);
+ if (entry == NULL)
+ return 0;
+
+ /* Go find the symbol, so that we can find it's name. */
+ if (!bfd_elf_get_elf_syms (input_bfd, &elf_tdata (input_bfd)->symtab_hdr,
+ 1, input_indx, &entry->isym, esym, &eshndx))
+ {
+ bfd_release (input_bfd, entry);
+ return 0;
+ }
+
+ if (entry->isym.st_shndx != SHN_UNDEF
+ && entry->isym.st_shndx < SHN_LORESERVE)
+ {
+ asection *s;
+
+ s = bfd_section_from_elf_index (input_bfd, entry->isym.st_shndx);
+ if (s == NULL || bfd_is_abs_section (s->output_section))
+ {
+ /* We can still bfd_release here as nothing has done another
+ bfd_alloc. We can't do this later in this function. */
+ bfd_release (input_bfd, entry);
+ return 2;
+ }
+ }
+
+ name = (bfd_elf_string_from_elf_section
+ (input_bfd, elf_tdata (input_bfd)->symtab_hdr.sh_link,
+ entry->isym.st_name));
+
+ 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_strtab_init ();
+ if (dynstr == NULL)
+ return 0;
+ }
+
+ dynstr_index = _bfd_elf_strtab_add (dynstr, name, FALSE);
+ if (dynstr_index == (unsigned long) -1)
+ return 0;
+ entry->isym.st_name = dynstr_index;
+
+ eht = elf_hash_table (info);
+
+ entry->next = eht->dynlocal;
+ eht->dynlocal = entry;
+ entry->input_bfd = input_bfd;
+ entry->input_indx = input_indx;
+ eht->dynsymcount++;
+
+ /* Whatever binding the symbol had before, it's now local. */
+ entry->isym.st_info
+ = ELF_ST_INFO (STB_LOCAL, ELF_ST_TYPE (entry->isym.st_info));
+
+ /* The dynindx will be set at the end of size_dynamic_sections. */
+
+ return 1;
+}
+
+/* Return the dynindex of a local dynamic symbol. */
+
+long
+_bfd_elf_link_lookup_local_dynindx (struct bfd_link_info *info,
+ bfd *input_bfd,
+ long input_indx)
+{
+ struct elf_link_local_dynamic_entry *e;
+
+ for (e = elf_hash_table (info)->dynlocal; e ; e = e->next)
+ if (e->input_bfd == input_bfd && e->input_indx == input_indx)
+ return e->dynindx;
+ return -1;
+}
+
+/* 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 bfd_boolean
+elf_link_renumber_hash_table_dynsyms (struct elf_link_hash_entry *h,
+ void *data)
+{
+ size_t *count = (size_t *) data;
+
+ if (h->forced_local)
+ return TRUE;
+
+ if (h->dynindx != -1)
+ h->dynindx = ++(*count);
+
+ return TRUE;
+}
+
+
+/* Like elf_link_renumber_hash_table_dynsyms, but just number symbols with
+ STB_LOCAL binding. */
+
+static bfd_boolean
+elf_link_renumber_local_hash_table_dynsyms (struct elf_link_hash_entry *h,
+ void *data)
+{
+ size_t *count = (size_t *) data;
+
+ if (!h->forced_local)
+ return TRUE;
+
+ if (h->dynindx != -1)
+ h->dynindx = ++(*count);
+
+ return TRUE;
+}
+
+/* Return true if the dynamic symbol for a given section should be
+ omitted when creating a shared library. */
+bfd_boolean
+_bfd_elf_link_omit_section_dynsym (bfd *output_bfd ATTRIBUTE_UNUSED,
+ struct bfd_link_info *info,
+ asection *p)
+{
+ struct elf_link_hash_table *htab;
+
+ switch (elf_section_data (p)->this_hdr.sh_type)
+ {
+ case SHT_PROGBITS:
+ case SHT_NOBITS:
+ /* If sh_type is yet undecided, assume it could be
+ SHT_PROGBITS/SHT_NOBITS. */
+ case SHT_NULL:
+ htab = elf_hash_table (info);
+ if (p == htab->tls_sec)
+ return FALSE;
+
+ if (htab->text_index_section != NULL)
+ return p != htab->text_index_section && p != htab->data_index_section;
+
+ if (strcmp (p->name, ".got") == 0
+ || strcmp (p->name, ".got.plt") == 0
+ || strcmp (p->name, ".plt") == 0)
+ {
+ asection *ip;
+
+ if (htab->dynobj != NULL
+ && (ip = bfd_get_linker_section (htab->dynobj, p->name)) != NULL
+ && ip->output_section == p)
+ return TRUE;
+ }
+ return FALSE;
+
+ /* There shouldn't be section relative relocations
+ against any other section. */
+ default:
+ return TRUE;
+ }
+}
+
+/* Assign dynsym indices. In a shared library we generate a section
+ symbol for each output section, which come first. Next come symbols
+ which have been forced to local binding. Then all of the back-end
+ allocated local dynamic syms, followed by the rest of the global
+ symbols. */
+
+static unsigned long
+_bfd_elf_link_renumber_dynsyms (bfd *output_bfd,
+ struct bfd_link_info *info,
+ unsigned long *section_sym_count)
+{
+ unsigned long dynsymcount = 0;
+
+ if (info->shared || elf_hash_table (info)->is_relocatable_executable)
+ {
+ const struct elf_backend_data *bed = get_elf_backend_data (output_bfd);
+ asection *p;
+ for (p = output_bfd->sections; p ; p = p->next)
+ if ((p->flags & SEC_EXCLUDE) == 0
+ && (p->flags & SEC_ALLOC) != 0
+ && !(*bed->elf_backend_omit_section_dynsym) (output_bfd, info, p))
+ elf_section_data (p)->dynindx = ++dynsymcount;
+ else
+ elf_section_data (p)->dynindx = 0;
+ }
+ *section_sym_count = dynsymcount;
+
+ elf_link_hash_traverse (elf_hash_table (info),
+ elf_link_renumber_local_hash_table_dynsyms,
+ &dynsymcount);
+
+ if (elf_hash_table (info)->dynlocal)
+ {
+ struct elf_link_local_dynamic_entry *p;
+ for (p = elf_hash_table (info)->dynlocal; p ; p = p->next)
+ p->dynindx = ++dynsymcount;
+ }
+
+ elf_link_hash_traverse (elf_hash_table (info),
+ elf_link_renumber_hash_table_dynsyms,
+ &dynsymcount);
+
+ /* There is an unused NULL entry at the head of the table which
+ we must account for in our count. Unless there weren't any
+ symbols, which means we'll have no table at all. */
+ if (dynsymcount != 0)
+ ++dynsymcount;
+
+ elf_hash_table (info)->dynsymcount = dynsymcount;
+ return dynsymcount;
+}
+
+/* Merge st_other field. */
+
+static void
+elf_merge_st_other (bfd *abfd, struct elf_link_hash_entry *h,
+ const Elf_Internal_Sym *isym,
+ bfd_boolean definition, bfd_boolean dynamic)
+{
+ const struct elf_backend_data *bed = get_elf_backend_data (abfd);
+
+ /* If st_other has a processor-specific meaning, specific
+ code might be needed here. */
+ if (bed->elf_backend_merge_symbol_attribute)
+ (*bed->elf_backend_merge_symbol_attribute) (h, isym, definition,
+ dynamic);
+
+ if (!dynamic)
+ {
+ unsigned symvis = ELF_ST_VISIBILITY (isym->st_other);
+ unsigned hvis = ELF_ST_VISIBILITY (h->other);
+
+ /* Keep the most constraining visibility. Leave the remainder
+ of the st_other field to elf_backend_merge_symbol_attribute. */
+ if (symvis - 1 < hvis - 1)
+ h->other = symvis | (h->other & ~ELF_ST_VISIBILITY (-1));
+ }
+}
+
+/* This function is called when we want to merge a new symbol with an
+ existing 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 POLDBFD to the old symbol's BFD. We set POLD_WEAK
+ if the old symbol was weak. We set POLD_ALIGNMENT to the alignment
+ of an old common symbol. 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 bfd_boolean
+_bfd_elf_merge_symbol (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,
+ bfd **poldbfd,
+ bfd_boolean *pold_weak,
+ unsigned int *pold_alignment,
+ bfd_boolean *skip,
+ bfd_boolean *override,
+ bfd_boolean *type_change_ok,
+ bfd_boolean *size_change_ok)
+{
+ asection *sec, *oldsec;
+ struct elf_link_hash_entry *h;
+ struct elf_link_hash_entry *hi;
+ struct elf_link_hash_entry *flip;
+ int bind;
+ bfd *oldbfd;
+ bfd_boolean newdyn, olddyn, olddef, newdef, newdyncommon, olddyncommon;
+ bfd_boolean newweak, oldweak, newfunc, oldfunc;
+ const struct elf_backend_data *bed;
+
+ *skip = FALSE;
+ *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;
+
+ bed = get_elf_backend_data (abfd);
+
+ /* For merging, we only care about real symbols. But we need to make
+ sure that indirect symbol dynamic flags are updated. */
+ hi = h;
+ 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;
+
+ /* OLDBFD and OLDSEC are a BFD and an ASECTION associated with the
+ existing symbol. */
+
+ oldbfd = NULL;
+ oldsec = NULL;
+ switch (h->root.type)
+ {
+ default:
+ 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;
+ oldsec = h->root.u.def.section;
+ break;
+
+ case bfd_link_hash_common:
+ oldbfd = h->root.u.c.p->section->owner;
+ oldsec = h->root.u.c.p->section;
+ if (pold_alignment)
+ *pold_alignment = h->root.u.c.p->alignment_power;
+ break;
+ }
+ if (poldbfd && *poldbfd == NULL)
+ *poldbfd = oldbfd;
+
+ /* Differentiate strong and weak symbols. */
+ newweak = bind == STB_WEAK;
+ oldweak = (h->root.type == bfd_link_hash_defweak
+ || h->root.type == bfd_link_hash_undefweak);
+ if (pold_weak)
+ *pold_weak = oldweak;
+
+ /* This code is for coping with dynamic objects, and is only useful
+ if we are doing an ELF link. */
+ if (!(*bed->relocs_compatible) (abfd->xvec, info->output_bfd->xvec))
+ return TRUE;
+
+ /* We have to check it for every instance since the first few may be
+ references and not all compilers emit symbol type for undefined
+ symbols. */
+ bfd_elf_link_mark_dynamic_symbol (info, h, sym);
+
+ /* NEWDYN and OLDDYN indicate whether the new or old symbol,
+ respectively, is from a dynamic object. */
+
+ newdyn = (abfd->flags & DYNAMIC) != 0;
+
+ /* ref_dynamic_nonweak and dynamic_def flags track actual undefined
+ syms and defined syms in dynamic libraries respectively.
+ ref_dynamic on the other hand can be set for a symbol defined in
+ a dynamic library, and def_dynamic may not be set; When the
+ definition in a dynamic lib is overridden by a definition in the
+ executable use of the symbol in the dynamic lib becomes a
+ reference to the executable symbol. */
+ if (newdyn)
+ {
+ if (bfd_is_und_section (sec))
+ {
+ if (bind != STB_WEAK)
+ {
+ h->ref_dynamic_nonweak = 1;
+ hi->ref_dynamic_nonweak = 1;
+ }
+ }
+ else
+ {
+ h->dynamic_def = 1;
+ hi->dynamic_def = 1;
+ }
+ }
+
+ /* 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->non_elf = 0;
+ return TRUE;
+ }
+
+ /* In cases involving weak versioned symbols, we may wind up trying
+ to merge a symbol with itself. Catch that here, to avoid the
+ confusion that results if we try to override a symbol with
+ itself. The additional tests catch cases like
+ _GLOBAL_OFFSET_TABLE_, which are regular symbols defined in a
+ dynamic object, which we do want to handle here. */
+ if (abfd == oldbfd
+ && (newweak || oldweak)
+ && ((abfd->flags & DYNAMIC) == 0
+ || !h->def_regular))
+ return TRUE;
+
+ olddyn = FALSE;
+ if (oldbfd != NULL)
+ olddyn = (oldbfd->flags & DYNAMIC) != 0;
+ else if (oldsec != NULL)
+ {
+ /* This handles the special SHN_MIPS_{TEXT,DATA} section
+ indices used by MIPS ELF. */
+ olddyn = (oldsec->symbol->flags & BSF_DYNAMIC) != 0;
+ }
+
+ /* NEWDEF and OLDDEF indicate whether the new or old symbol,
+ respectively, appear to be a definition rather than reference. */
+
+ newdef = !bfd_is_und_section (sec) && !bfd_is_com_section (sec);
+
+ olddef = (h->root.type != bfd_link_hash_undefined
+ && h->root.type != bfd_link_hash_undefweak
+ && h->root.type != bfd_link_hash_common);
+
+ /* NEWFUNC and OLDFUNC indicate whether the new or old symbol,
+ respectively, appear to be a function. */
+
+ newfunc = (ELF_ST_TYPE (sym->st_info) != STT_NOTYPE
+ && bed->is_function_type (ELF_ST_TYPE (sym->st_info)));
+
+ oldfunc = (h->type != STT_NOTYPE
+ && bed->is_function_type (h->type));
+
+ /* When we try to create a default indirect symbol from the dynamic
+ definition with the default version, we skip it if its type and
+ the type of existing regular definition mismatch. */
+ if (pold_alignment == NULL
+ && newdyn
+ && newdef
+ && !olddyn
+ && (((olddef || h->root.type == bfd_link_hash_common)
+ && ELF_ST_TYPE (sym->st_info) != h->type
+ && ELF_ST_TYPE (sym->st_info) != STT_NOTYPE
+ && h->type != STT_NOTYPE
+ && !(newfunc && oldfunc))
+ || (olddef
+ && ((h->type == STT_GNU_IFUNC)
+ != (ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC)))))
+ {
+ *skip = TRUE;
+ return TRUE;
+ }
+
+ /* Check TLS symbols. We don't check undefined symbols introduced
+ by "ld -u" which have no type (and oldbfd NULL), and we don't
+ check symbols from plugins because they also have no type. */
+ if (oldbfd != NULL
+ && (oldbfd->flags & BFD_PLUGIN) == 0
+ && (abfd->flags & BFD_PLUGIN) == 0
+ && ELF_ST_TYPE (sym->st_info) != h->type
+ && (ELF_ST_TYPE (sym->st_info) == STT_TLS || h->type == STT_TLS))
+ {
+ bfd *ntbfd, *tbfd;
+ bfd_boolean ntdef, tdef;
+ asection *ntsec, *tsec;
+
+ if (h->type == STT_TLS)
+ {
+ ntbfd = abfd;
+ ntsec = sec;
+ ntdef = newdef;
+ tbfd = oldbfd;
+ tsec = oldsec;
+ tdef = olddef;
+ }
+ else
+ {
+ ntbfd = oldbfd;
+ ntsec = oldsec;
+ ntdef = olddef;
+ tbfd = abfd;
+ tsec = sec;
+ tdef = newdef;
+ }
+
+ if (tdef && ntdef)
+ (*_bfd_error_handler)
+ (_("%s: TLS definition in %B section %A "
+ "mismatches non-TLS definition in %B section %A"),
+ tbfd, tsec, ntbfd, ntsec, h->root.root.string);
+ else if (!tdef && !ntdef)
+ (*_bfd_error_handler)
+ (_("%s: TLS reference in %B "
+ "mismatches non-TLS reference in %B"),
+ tbfd, ntbfd, h->root.root.string);
+ else if (tdef)
+ (*_bfd_error_handler)
+ (_("%s: TLS definition in %B section %A "
+ "mismatches non-TLS reference in %B"),
+ tbfd, tsec, ntbfd, h->root.root.string);
+ else
+ (*_bfd_error_handler)
+ (_("%s: TLS reference in %B "
+ "mismatches non-TLS definition in %B section %A"),
+ tbfd, ntbfd, ntsec, h->root.root.string);
+
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+
+ /* If the old symbol has non-default visibility, we ignore the new
+ definition from a dynamic object. */
+ if (newdyn
+ && ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
+ && !bfd_is_und_section (sec))
+ {
+ *skip = TRUE;
+ /* Make sure this symbol is dynamic. */
+ h->ref_dynamic = 1;
+ hi->ref_dynamic = 1;
+ /* A protected symbol has external availability. Make sure it is
+ recorded as dynamic.
+
+ FIXME: Should we check type and size for protected symbol? */
+ if (ELF_ST_VISIBILITY (h->other) == STV_PROTECTED)
+ return bfd_elf_link_record_dynamic_symbol (info, h);
+ else
+ return TRUE;
+ }
+ else if (!newdyn
+ && ELF_ST_VISIBILITY (sym->st_other) != STV_DEFAULT
+ && h->def_dynamic)
+ {
+ /* If the new symbol with non-default visibility comes from a
+ relocatable file and the old definition comes from a dynamic
+ object, we remove the old definition. */
+ if (hi->root.type == bfd_link_hash_indirect)
+ {
+ /* Handle the case where the old dynamic definition is
+ default versioned. We need to copy the symbol info from
+ the symbol with default version to the normal one if it
+ was referenced before. */
+ if (h->ref_regular)
+ {
+ hi->root.type = h->root.type;
+ h->root.type = bfd_link_hash_indirect;
+ (*bed->elf_backend_copy_indirect_symbol) (info, hi, h);
+
+ h->root.u.i.link = (struct bfd_link_hash_entry *) hi;
+ if (ELF_ST_VISIBILITY (sym->st_other) != STV_PROTECTED)
+ {
+ /* If the new symbol is hidden or internal, completely undo
+ any dynamic link state. */
+ (*bed->elf_backend_hide_symbol) (info, h, TRUE);
+ h->forced_local = 0;
+ h->ref_dynamic = 0;
+ }
+ else
+ h->ref_dynamic = 1;
+
+ h->def_dynamic = 0;
+ /* FIXME: Should we check type and size for protected symbol? */
+ h->size = 0;
+ h->type = 0;
+
+ h = hi;
+ }
+ else
+ h = hi;
+ }
+
+ /* If the old symbol was undefined before, then it will still be
+ on the undefs list. If the new symbol is undefined or
+ common, we can't make it bfd_link_hash_new here, because new
+ undefined or common symbols will be added to the undefs list
+ by _bfd_generic_link_add_one_symbol. Symbols may not be
+ added twice to the undefs list. Also, if the new symbol is
+ undefweak then we don't want to lose the strong undef. */
+ if (h->root.u.undef.next || info->hash->undefs_tail == &h->root)
+ {
+ h->root.type = bfd_link_hash_undefined;
+ h->root.u.undef.abfd = abfd;
+ }
+ else
+ {
+ h->root.type = bfd_link_hash_new;
+ h->root.u.undef.abfd = NULL;
+ }
+
+ if (ELF_ST_VISIBILITY (sym->st_other) != STV_PROTECTED)
+ {
+ /* If the new symbol is hidden or internal, completely undo
+ any dynamic link state. */
+ (*bed->elf_backend_hide_symbol) (info, h, TRUE);
+ h->forced_local = 0;
+ h->ref_dynamic = 0;
+ }
+ else
+ h->ref_dynamic = 1;
+ h->def_dynamic = 0;
+ /* FIXME: Should we check type and size for protected symbol? */
+ h->size = 0;
+ h->type = 0;
+ return TRUE;
+ }
+
+ /* If a new weak symbol definition comes from a regular file and the
+ old symbol comes from a dynamic library, we treat the new one as
+ strong. Similarly, an old weak symbol definition from a regular
+ file is treated as strong when the new symbol comes from a dynamic
+ library. Further, an old weak symbol from a dynamic library is
+ treated as strong if the new symbol is from a dynamic library.
+ This reflects the way glibc's ld.so works.
+
+ Do this before setting *type_change_ok or *size_change_ok so that
+ we warn properly when dynamic library symbols are overridden. */
+
+ if (newdef && !newdyn && olddyn)
+ newweak = FALSE;
+ if (olddef && newdyn)
+ oldweak = FALSE;
+
+ /* Allow changes between different types of function symbol. */
+ if (newfunc && oldfunc)
+ *type_change_ok = TRUE;
+
+ /* It's OK to change the type if either the existing symbol or the
+ new symbol is weak. A type change is also OK if the old symbol
+ is undefined and the new symbol is defined. */
+
+ if (oldweak
+ || newweak
+ || (newdef
+ && h->root.type == bfd_link_hash_undefined))
+ *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;
+
+ /* 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
+ && !newweak
+ && (sec->flags & SEC_ALLOC) != 0
+ && (sec->flags & SEC_LOAD) == 0
+ && sym->st_size > 0
+ && !newfunc)
+ newdyncommon = TRUE;
+ else
+ newdyncommon = FALSE;
+
+ if (olddyn
+ && olddef
+ && h->root.type == bfd_link_hash_defined
+ && h->def_dynamic
+ && (h->root.u.def.section->flags & SEC_ALLOC) != 0
+ && (h->root.u.def.section->flags & SEC_LOAD) == 0
+ && h->size > 0
+ && !oldfunc)
+ olddyncommon = TRUE;
+ else
+ olddyncommon = FALSE;
+
+ /* We now know everything about the old and new symbols. We ask the
+ backend to check if we can merge them. */
+ if (bed->merge_symbol != NULL)
+ {
+ if (!bed->merge_symbol (h, sym, psec, newdef, olddef, oldbfd, oldsec))
+ return FALSE;
+ sec = *psec;
+ }
+
+ /* 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, 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
+ && (newweak || newfunc))))
+ {
+ *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 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 = bed->common_section (oldsec);
+ *size_change_ok = TRUE;
+ }
+
+ /* Skip weak definitions of symbols that are already defined. */
+ if (newdef && olddef && newweak)
+ {
+ /* Don't skip new non-IR weak syms. */
+ if (!(oldbfd != NULL
+ && (oldbfd->flags & BFD_PLUGIN) != 0
+ && (abfd->flags & BFD_PLUGIN) == 0))
+ {
+ newdef = FALSE;
+ *skip = TRUE;
+ }
+
+ /* Merge st_other. If the symbol already has a dynamic index,
+ but visibility says it should not be visible, turn it into a
+ local symbol. */
+ elf_merge_st_other (abfd, h, sym, newdef, newdyn);
+ if (h->dynindx != -1)
+ switch (ELF_ST_VISIBILITY (h->other))
+ {
+ case STV_INTERNAL:
+ case STV_HIDDEN:
+ (*bed->elf_backend_hide_symbol) (info, h, TRUE);
+ break;
+ }
+ }
+
+ /* 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. */
+
+ flip = NULL;
+ if (!newdyn
+ && (newdef
+ || (bfd_is_com_section (sec)
+ && (oldweak || oldfunc)))
+ && olddyn
+ && olddef
+ && h->def_dynamic)
+ {
+ /* 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))
+ {
+ if (oldfunc)
+ {
+ /* If a common symbol overrides a function, make sure
+ that it isn't defined dynamically nor has type
+ function. */
+ h->def_dynamic = 0;
+ h->type = STT_NOTYPE;
+ }
+ *type_change_ok = TRUE;
+ }
+
+ if (hi->root.type == bfd_link_hash_indirect)
+ flip = hi;
+ else
+ /* 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;
+ }
+
+ /* 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, abfd, bfd_link_hash_common, sym->st_size)))
+ return FALSE;
+
+ /* If the presumed common symbol in the dynamic object is
+ larger, pretend that the new symbol has its size. */
+
+ if (h->size > *pvalue)
+ *pvalue = h->size;
+
+ /* We need to remember the alignment required by the symbol
+ in the dynamic object. */
+ BFD_ASSERT (pold_alignment);
+ *pold_alignment = h->root.u.def.section->alignment_power;
+
+ 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;
+
+ if (hi->root.type == bfd_link_hash_indirect)
+ flip = hi;
+ else
+ h->verinfo.vertree = NULL;
+ }
+
+ if (flip != NULL)
+ {
+ /* Handle the case where we had a versioned symbol in a dynamic
+ library and now find a definition in a normal object. In this
+ case, we make the versioned symbol point to the normal one. */
+ flip->root.type = h->root.type;
+ flip->root.u.undef.abfd = h->root.u.undef.abfd;
+ h->root.type = bfd_link_hash_indirect;
+ h->root.u.i.link = (struct bfd_link_hash_entry *) flip;
+ (*bed->elf_backend_copy_indirect_symbol) (info, flip, h);
+ if (h->def_dynamic)
+ {
+ h->def_dynamic = 0;
+ flip->ref_dynamic = 1;
+ }
+ }
+
+ return TRUE;
+}
+
+/* This function is called to create an indirect symbol from the
+ default for the symbol with the default version if needed. The
+ symbol is described by H, NAME, SYM, SEC, and VALUE. We
+ set DYNSYM if the new indirect symbol is dynamic. */
+
+static bfd_boolean
+_bfd_elf_add_default_symbol (bfd *abfd,
+ struct bfd_link_info *info,
+ struct elf_link_hash_entry *h,
+ const char *name,
+ Elf_Internal_Sym *sym,
+ asection *sec,
+ bfd_vma value,
+ bfd **poldbfd,
+ bfd_boolean *dynsym)
+{
+ bfd_boolean type_change_ok;
+ bfd_boolean size_change_ok;
+ bfd_boolean skip;
+ char *shortname;
+ struct elf_link_hash_entry *hi;
+ struct bfd_link_hash_entry *bh;
+ const struct elf_backend_data *bed;
+ bfd_boolean collect;
+ bfd_boolean dynamic;
+ bfd_boolean override;
+ char *p;
+ size_t len, shortlen;
+ asection *tmp_sec;
+
+ /* 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. */
+ p = strchr (name, ELF_VER_CHR);
+ if (p == NULL || p[1] != ELF_VER_CHR)
+ return TRUE;
+
+ bed = get_elf_backend_data (abfd);
+ collect = bed->collect;
+ dynamic = (abfd->flags & DYNAMIC) != 0;
+
+ shortlen = p - name;
+ shortname = (char *) bfd_hash_allocate (&info->hash->table, shortlen + 1);
+ if (shortname == NULL)
+ return FALSE;
+ memcpy (shortname, name, shortlen);
+ shortname[shortlen] = '\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;
+ tmp_sec = sec;
+ if (!_bfd_elf_merge_symbol (abfd, info, shortname, sym, &tmp_sec, &value,
+ &hi, poldbfd, NULL, NULL, &skip, &override,
+ &type_change_ok, &size_change_ok))
+ return FALSE;
+
+ if (skip)
+ goto nondefault;
+
+ if (! override)
+ {
+ bh = &hi->root;
+ if (! (_bfd_generic_link_add_one_symbol
+ (info, abfd, shortname, BSF_INDIRECT, bfd_ind_section_ptr,
+ 0, name, FALSE, collect, &bh)))
+ return FALSE;
+ hi = (struct elf_link_hash_entry *) bh;
+ }
+ 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->def_dynamic)
+ {
+ h->def_dynamic = 0;
+ hi->ref_dynamic = 1;
+ if (hi->ref_regular
+ || hi->def_regular)
+ {
+ if (! bfd_elf_link_record_dynamic_symbol (info, hi))
+ return FALSE;
+ }
+ }
+
+ /* Now set HI to H, so that the following code will set the
+ other fields correctly. */
+ hi = h;
+ }
+
+ /* Check if HI is a warning symbol. */
+ if (hi->root.type == bfd_link_hash_warning)
+ hi = (struct elf_link_hash_entry *) hi->root.u.i.link;
+
+ /* 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;
+
+ ht = (struct elf_link_hash_entry *) hi->root.u.i.link;
+ (*bed->elf_backend_copy_indirect_symbol) (info, ht, hi);
+
+ /* A reference to the SHORTNAME symbol from a dynamic library
+ will be satisfied by the versioned symbol at runtime. In
+ effect, we have a reference to the versioned symbol. */
+ ht->ref_dynamic_nonweak |= hi->ref_dynamic_nonweak;
+ hi->dynamic_def |= ht->dynamic_def;
+
+ /* See if the new flags lead us to realize that the symbol must
+ be dynamic. */
+ if (! *dynsym)
+ {
+ if (! dynamic)
+ {
+ if (! info->executable
+ || hi->def_dynamic
+ || hi->ref_dynamic)
+ *dynsym = TRUE;
+ }
+ else
+ {
+ if (hi->ref_regular)
+ *dynsym = TRUE;
+ }
+ }
+ }
+
+ /* We also need to define an indirection from the nondefault version
+ of the symbol. */
+
+nondefault:
+ len = strlen (name);
+ shortname = (char *) bfd_hash_allocate (&info->hash->table, len);
+ if (shortname == NULL)
+ return FALSE;
+ memcpy (shortname, name, shortlen);
+ memcpy (shortname + shortlen, p + 1, len - shortlen);
+
+ /* Once again, merge with any existing symbol. */
+ type_change_ok = FALSE;
+ size_change_ok = FALSE;
+ tmp_sec = sec;
+ if (!_bfd_elf_merge_symbol (abfd, info, shortname, sym, &tmp_sec, &value,
+ &hi, poldbfd, NULL, NULL, &skip, &override,
+ &type_change_ok, &size_change_ok))
+ return FALSE;
+
+ if (skip)
+ return TRUE;
+
+ 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 unless it is
+ overridden by a versioned definition. */
+ if (hi->root.type != bfd_link_hash_defined
+ && hi->root.type != bfd_link_hash_defweak)
+ (*_bfd_error_handler)
+ (_("%B: unexpected redefinition of indirect versioned symbol `%s'"),
+ abfd, shortname);
+ }
+ else
+ {
+ bh = &hi->root;
+ if (! (_bfd_generic_link_add_one_symbol
+ (info, abfd, shortname, BSF_INDIRECT,
+ bfd_ind_section_ptr, 0, name, FALSE, collect, &bh)))
+ return FALSE;
+ hi = (struct elf_link_hash_entry *) bh;
+
+ /* 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)
+ {
+ (*bed->elf_backend_copy_indirect_symbol) (info, h, hi);
+ h->ref_dynamic_nonweak |= hi->ref_dynamic_nonweak;
+ hi->dynamic_def |= h->dynamic_def;
+
+ /* See if the new flags lead us to realize that the symbol
+ must be dynamic. */
+ if (! *dynsym)
+ {
+ if (! dynamic)
+ {
+ if (! info->executable
+ || hi->ref_dynamic)
+ *dynsym = TRUE;
+ }
+ else
+ {
+ if (hi->ref_regular)
+ *dynsym = TRUE;
+ }
+ }
+ }
+ }
+
+ 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 bfd_boolean
+_bfd_elf_export_symbol (struct elf_link_hash_entry *h, void *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;
+
+ /* Ignore this if we won't export it. */
+ if (!eif->info->export_dynamic && !h->dynamic)
+ return TRUE;
+
+ if (h->dynindx == -1
+ && (h->def_regular || h->ref_regular)
+ && ! bfd_hide_sym_by_version (eif->info->version_info,
+ h->root.root.string))
+ {
+ 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 bfd_boolean
+_bfd_elf_link_find_version_dependencies (struct elf_link_hash_entry *h,
+ void *data)
+{
+ struct elf_find_verdep_info *rinfo = (struct elf_find_verdep_info *) data;
+ Elf_Internal_Verneed *t;
+ Elf_Internal_Vernaux *a;
+ bfd_size_type amt;
+
+ /* We only care about symbols defined in shared objects with version
+ information. */
+ if (!h->def_dynamic
+ || h->def_regular
+ || h->dynindx == -1
+ || h->verinfo.verdef == NULL
+ || (elf_dyn_lib_class (h->verinfo.verdef->vd_bfd)
+ & (DYN_AS_NEEDED | DYN_DT_NEEDED | DYN_NO_NEEDED)))
+ return TRUE;
+
+ /* See if we already know about this version. */
+ for (t = elf_tdata (rinfo->info->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)
+ {
+ amt = sizeof *t;
+ t = (Elf_Internal_Verneed *) bfd_zalloc (rinfo->info->output_bfd, amt);
+ if (t == NULL)
+ {
+ rinfo->failed = TRUE;
+ return FALSE;
+ }
+
+ t->vn_bfd = h->verinfo.verdef->vd_bfd;
+ t->vn_nextref = elf_tdata (rinfo->info->output_bfd)->verref;
+ elf_tdata (rinfo->info->output_bfd)->verref = t;
+ }
+
+ amt = sizeof *a;
+ a = (Elf_Internal_Vernaux *) bfd_zalloc (rinfo->info->output_bfd, amt);
+ if (a == NULL)
+ {
+ rinfo->failed = TRUE;
+ return FALSE;
+ }
+
+ /* 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 bfd_boolean
+_bfd_elf_link_assign_sym_version (struct elf_link_hash_entry *h, void *data)
+{
+ struct elf_info_failed *sinfo;
+ struct bfd_link_info *info;
+ const struct elf_backend_data *bed;
+ struct elf_info_failed eif;
+ char *p;
+ bfd_size_type amt;
+
+ sinfo = (struct elf_info_failed *) data;
+ info = sinfo->info;
+
+ /* Fix the symbol flags. */
+ eif.failed = FALSE;
+ eif.info = info;
+ if (! _bfd_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->def_regular)
+ return TRUE;
+
+ bed = get_elf_backend_data (info->output_bfd);
+ p = strchr (h->root.root.string, ELF_VER_CHR);
+ if (p != NULL && h->verinfo.vertree == NULL)
+ {
+ struct bfd_elf_version_tree *t;
+ bfd_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->hidden = 1;
+ return TRUE;
+ }
+
+ /* Look for the version. If we find it, it is no longer weak. */
+ for (t = sinfo->info->version_info; t != NULL; t = t->next)
+ {
+ if (strcmp (t->name, p) == 0)
+ {
+ size_t len;
+ char *alc;
+ struct bfd_elf_version_expr *d;
+
+ len = p - h->root.root.string;
+ alc = (char *) bfd_malloc (len);
+ if (alc == NULL)
+ {
+ sinfo->failed = TRUE;
+ return FALSE;
+ }
+ memcpy (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.list != NULL)
+ d = (*t->match) (&t->globals, NULL, alc);
+
+ /* See if there is anything to force this symbol to
+ local scope. */
+ if (d == NULL && t->locals.list != NULL)
+ {
+ d = (*t->match) (&t->locals, NULL, alc);
+ if (d != NULL
+ && h->dynindx != -1
+ && ! info->export_dynamic)
+ (*bed->elf_backend_hide_symbol) (info, h, TRUE);
+ }
+
+ free (alc);
+ break;
+ }
+ }
+
+ /* If we are building an application, we need to create a
+ version node for this version. */
+ if (t == NULL && info->executable)
+ {
+ 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;
+
+ amt = sizeof *t;
+ t = (struct bfd_elf_version_tree *) bfd_zalloc (info->output_bfd, amt);
+ if (t == NULL)
+ {
+ sinfo->failed = TRUE;
+ return FALSE;
+ }
+
+ t->name = p;
+ t->name_indx = (unsigned int) -1;
+ t->used = TRUE;
+
+ version_index = 1;
+ /* Don't count anonymous version tag. */
+ if (sinfo->info->version_info != NULL
+ && sinfo->info->version_info->vernum == 0)
+ version_index = 0;
+ for (pp = &sinfo->info->version_info;
+ *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)
+ (_("%B: version node not found for symbol %s"),
+ info->output_bfd, h->root.root.string);
+ bfd_set_error (bfd_error_bad_value);
+ sinfo->failed = TRUE;
+ return FALSE;
+ }
+
+ if (hidden)
+ h->hidden = 1;
+ }
+
+ /* If we don't have a version for this symbol, see if we can find
+ something. */
+ if (h->verinfo.vertree == NULL && sinfo->info->version_info != NULL)
+ {
+ bfd_boolean hide;
+
+ h->verinfo.vertree
+ = bfd_find_version_for_sym (sinfo->info->version_info,
+ h->root.root.string, &hide);
+ if (h->verinfo.vertree != NULL && hide)
+ (*bed->elf_backend_hide_symbol) (info, h, TRUE);
+ }
+
+ return TRUE;
+}
+
+/* Read and swap the relocs from the section indicated by SHDR. This
+ may be either a REL or a RELA section. The relocations are
+ translated into RELA relocations and stored in INTERNAL_RELOCS,
+ which should have already been allocated to contain enough space.
+ The EXTERNAL_RELOCS are a buffer where the external form of the
+ relocations should be stored.
+
+ Returns FALSE if something goes wrong. */
+
+static bfd_boolean
+elf_link_read_relocs_from_section (bfd *abfd,
+ asection *sec,
+ Elf_Internal_Shdr *shdr,
+ void *external_relocs,
+ Elf_Internal_Rela *internal_relocs)
+{
+ const struct elf_backend_data *bed;
+ void (*swap_in) (bfd *, const bfd_byte *, Elf_Internal_Rela *);
+ const bfd_byte *erela;
+ const bfd_byte *erelaend;
+ Elf_Internal_Rela *irela;
+ Elf_Internal_Shdr *symtab_hdr;
+ size_t nsyms;
+
+ /* Position ourselves at the start of the section. */
+ if (bfd_seek (abfd, shdr->sh_offset, SEEK_SET) != 0)
+ return FALSE;
+
+ /* Read the relocations. */
+ if (bfd_bread (external_relocs, shdr->sh_size, abfd) != shdr->sh_size)
+ return FALSE;
+
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+ nsyms = NUM_SHDR_ENTRIES (symtab_hdr);
+
+ bed = get_elf_backend_data (abfd);
+
+ /* Convert the external relocations to the internal format. */
+ if (shdr->sh_entsize == bed->s->sizeof_rel)
+ swap_in = bed->s->swap_reloc_in;
+ else if (shdr->sh_entsize == bed->s->sizeof_rela)
+ swap_in = bed->s->swap_reloca_in;
+ else
+ {
+ bfd_set_error (bfd_error_wrong_format);
+ return FALSE;
+ }
+
+ erela = (const bfd_byte *) external_relocs;
+ erelaend = erela + shdr->sh_size;
+ irela = internal_relocs;
+ while (erela < erelaend)
+ {
+ bfd_vma r_symndx;
+
+ (*swap_in) (abfd, erela, irela);
+ r_symndx = ELF32_R_SYM (irela->r_info);
+ if (bed->s->arch_size == 64)
+ r_symndx >>= 24;
+ if (nsyms > 0)
+ {
+ if ((size_t) r_symndx >= nsyms)
+ {
+ (*_bfd_error_handler)
+ (_("%B: bad reloc symbol index (0x%lx >= 0x%lx)"
+ " for offset 0x%lx in section `%A'"),
+ abfd, sec,
+ (unsigned long) r_symndx, (unsigned long) nsyms, irela->r_offset);
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+ }
+ else if (r_symndx != STN_UNDEF)
+ {
+ (*_bfd_error_handler)
+ (_("%B: non-zero symbol index (0x%lx) for offset 0x%lx in section `%A'"
+ " when the object file has no symbol table"),
+ abfd, sec,
+ (unsigned long) r_symndx, (unsigned long) nsyms, irela->r_offset);
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+ irela += bed->s->int_rels_per_ext_rel;
+ erela += shdr->sh_entsize;
+ }
+
+ return TRUE;
+}
+
+/* Read and swap the relocs for a section O. 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. If O has two relocation
+ sections (both REL and RELA relocations), then the REL_HDR
+ relocations will appear first in INTERNAL_RELOCS, followed by the
+ RELA_HDR relocations. */
+
+Elf_Internal_Rela *
+_bfd_elf_link_read_relocs (bfd *abfd,
+ asection *o,
+ void *external_relocs,
+ Elf_Internal_Rela *internal_relocs,
+ bfd_boolean keep_memory)
+{
+ void *alloc1 = NULL;
+ Elf_Internal_Rela *alloc2 = NULL;
+ const struct elf_backend_data *bed = get_elf_backend_data (abfd);
+ struct bfd_elf_section_data *esdo = elf_section_data (o);
+ Elf_Internal_Rela *internal_rela_relocs;
+
+ if (esdo->relocs != NULL)
+ return esdo->relocs;
+
+ if (o->reloc_count == 0)
+ return NULL;
+
+ if (internal_relocs == NULL)
+ {
+ bfd_size_type size;
+
+ size = o->reloc_count;
+ size *= bed->s->int_rels_per_ext_rel * sizeof (Elf_Internal_Rela);
+ if (keep_memory)
+ internal_relocs = alloc2 = (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)
+ {
+ bfd_size_type size = 0;
+
+ if (esdo->rel.hdr)
+ size += esdo->rel.hdr->sh_size;
+ if (esdo->rela.hdr)
+ size += esdo->rela.hdr->sh_size;
+
+ alloc1 = bfd_malloc (size);
+ if (alloc1 == NULL)
+ goto error_return;
+ external_relocs = alloc1;
+ }
+
+ internal_rela_relocs = internal_relocs;
+ if (esdo->rel.hdr)
+ {
+ if (!elf_link_read_relocs_from_section (abfd, o, esdo->rel.hdr,
+ external_relocs,
+ internal_relocs))
+ goto error_return;
+ external_relocs = (((bfd_byte *) external_relocs)
+ + esdo->rel.hdr->sh_size);
+ internal_rela_relocs += (NUM_SHDR_ENTRIES (esdo->rel.hdr)
+ * bed->s->int_rels_per_ext_rel);
+ }
+
+ if (esdo->rela.hdr
+ && (!elf_link_read_relocs_from_section (abfd, o, esdo->rela.hdr,
+ external_relocs,
+ internal_rela_relocs)))
+ goto error_return;
+
+ /* Cache the results for next time, if we can. */
+ if (keep_memory)
+ esdo->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)
+ {
+ if (keep_memory)
+ bfd_release (abfd, alloc2);
+ else
+ free (alloc2);
+ }
+ return NULL;
+}
+
+/* Compute the size of, and allocate space for, REL_HDR which is the
+ section header for a section containing relocations for O. */
+
+static bfd_boolean
+_bfd_elf_link_size_reloc_section (bfd *abfd,
+ struct bfd_elf_section_reloc_data *reldata)
+{
+ Elf_Internal_Shdr *rel_hdr = reldata->hdr;
+
+ /* That allows us to calculate the size of the section. */
+ rel_hdr->sh_size = rel_hdr->sh_entsize * reldata->count;
+
+ /* The contents field must last into write_object_contents, so we
+ allocate it with bfd_alloc rather than malloc. Also since we
+ cannot be sure that the contents will actually be filled in,
+ we zero the allocated space. */
+ rel_hdr->contents = (unsigned char *) bfd_zalloc (abfd, rel_hdr->sh_size);
+ if (rel_hdr->contents == NULL && rel_hdr->sh_size != 0)
+ return FALSE;
+
+ if (reldata->hashes == NULL && reldata->count)
+ {
+ struct elf_link_hash_entry **p;
+
+ p = (struct elf_link_hash_entry **)
+ bfd_zmalloc (reldata->count * sizeof (struct elf_link_hash_entry *));
+ if (p == NULL)
+ return FALSE;
+
+ reldata->hashes = p;
+ }
+
+ return TRUE;
+}
+
+/* Copy the relocations indicated by the INTERNAL_RELOCS (which
+ originated from the section given by INPUT_REL_HDR) to the
+ OUTPUT_BFD. */
+
+bfd_boolean
+_bfd_elf_link_output_relocs (bfd *output_bfd,
+ asection *input_section,
+ Elf_Internal_Shdr *input_rel_hdr,
+ Elf_Internal_Rela *internal_relocs,
+ struct elf_link_hash_entry **rel_hash
+ ATTRIBUTE_UNUSED)
+{
+ Elf_Internal_Rela *irela;
+ Elf_Internal_Rela *irelaend;
+ bfd_byte *erel;
+ struct bfd_elf_section_reloc_data *output_reldata;
+ asection *output_section;
+ const struct elf_backend_data *bed;
+ void (*swap_out) (bfd *, const Elf_Internal_Rela *, bfd_byte *);
+ struct bfd_elf_section_data *esdo;
+
+ output_section = input_section->output_section;
+
+ bed = get_elf_backend_data (output_bfd);
+ esdo = elf_section_data (output_section);
+ if (esdo->rel.hdr && esdo->rel.hdr->sh_entsize == input_rel_hdr->sh_entsize)
+ {
+ output_reldata = &esdo->rel;
+ swap_out = bed->s->swap_reloc_out;
+ }
+ else if (esdo->rela.hdr
+ && esdo->rela.hdr->sh_entsize == input_rel_hdr->sh_entsize)
+ {
+ output_reldata = &esdo->rela;
+ swap_out = bed->s->swap_reloca_out;
+ }
+ else
+ {
+ (*_bfd_error_handler)
+ (_("%B: relocation size mismatch in %B section %A"),
+ output_bfd, input_section->owner, input_section);
+ bfd_set_error (bfd_error_wrong_format);
+ return FALSE;
+ }
+
+ erel = output_reldata->hdr->contents;
+ erel += output_reldata->count * input_rel_hdr->sh_entsize;
+ irela = internal_relocs;
+ irelaend = irela + (NUM_SHDR_ENTRIES (input_rel_hdr)
+ * bed->s->int_rels_per_ext_rel);
+ while (irela < irelaend)
+ {
+ (*swap_out) (output_bfd, irela, erel);
+ irela += bed->s->int_rels_per_ext_rel;
+ erel += input_rel_hdr->sh_entsize;
+ }
+
+ /* Bump the counter, so that we know where to add the next set of
+ relocations. */
+ output_reldata->count += NUM_SHDR_ENTRIES (input_rel_hdr);
+
+ return TRUE;
+}
+
+/* Make weak undefined symbols in PIE dynamic. */
+
+bfd_boolean
+_bfd_elf_link_hash_fixup_symbol (struct bfd_link_info *info,
+ struct elf_link_hash_entry *h)
+{
+ if (info->pie
+ && h->dynindx == -1
+ && h->root.type == bfd_link_hash_undefweak)
+ return bfd_elf_link_record_dynamic_symbol (info, h);
+
+ 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 bfd_boolean
+_bfd_elf_fix_symbol_flags (struct elf_link_hash_entry *h,
+ struct elf_info_failed *eif)
+{
+ const struct elf_backend_data *bed;
+
+ /* 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->non_elf)
+ {
+ while (h->root.type == bfd_link_hash_indirect)
+ 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)
+ {
+ h->ref_regular = 1;
+ h->ref_regular_nonweak = 1;
+ }
+ else
+ {
+ if (h->root.u.def.section->owner != NULL
+ && (bfd_get_flavour (h->root.u.def.section->owner)
+ == bfd_target_elf_flavour))
+ {
+ h->ref_regular = 1;
+ h->ref_regular_nonweak = 1;
+ }
+ else
+ h->def_regular = 1;
+ }
+
+ if (h->dynindx == -1
+ && (h->def_dynamic
+ || h->ref_dynamic))
+ {
+ if (! bfd_elf_link_record_dynamic_symbol (eif->info, h))
+ {
+ eif->failed = TRUE;
+ return FALSE;
+ }
+ }
+ }
+ else
+ {
+ /* Unfortunately, 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->def_regular
+ && (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->def_dynamic)))
+ h->def_regular = 1;
+ }
+
+ /* Backend specific symbol fixup. */
+ bed = get_elf_backend_data (elf_hash_table (eif->info)->dynobj);
+ if (bed->elf_backend_fixup_symbol
+ && !(*bed->elf_backend_fixup_symbol) (eif->info, h))
+ return FALSE;
+
+ /* 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 DEF_REGULAR
+ flag will not have been set. */
+ if (h->root.type == bfd_link_hash_defined
+ && !h->def_regular
+ && h->ref_regular
+ && !h->def_dynamic
+ && (h->root.u.def.section->owner->flags & (DYNAMIC | BFD_PLUGIN)) == 0)
+ h->def_regular = 1;
+
+ /* 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. Likewise, if the symbol has non-default
+ visibility. If the symbol has hidden or internal visibility, we
+ will force it local. */
+ if (h->needs_plt
+ && eif->info->shared
+ && is_elf_hash_table (eif->info->hash)
+ && (SYMBOLIC_BIND (eif->info, h)
+ || ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
+ && h->def_regular)
+ {
+ bfd_boolean force_local;
+
+ force_local = (ELF_ST_VISIBILITY (h->other) == STV_INTERNAL
+ || ELF_ST_VISIBILITY (h->other) == STV_HIDDEN);
+ (*bed->elf_backend_hide_symbol) (eif->info, h, force_local);
+ }
+
+ /* If a weak undefined symbol has non-default visibility, we also
+ hide it from the dynamic linker. */
+ if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
+ && h->root.type == bfd_link_hash_undefweak)
+ (*bed->elf_backend_hide_symbol) (eif->info, h, TRUE);
+
+ /* If this is a weak defined symbol in a dynamic object, and we know
+ the real definition in the dynamic object, copy interesting flags
+ over to the real definition. */
+ if (h->u.weakdef != NULL)
+ {
+ /* If the real definition is defined by a regular object file,
+ don't do anything special. See the longer description in
+ _bfd_elf_adjust_dynamic_symbol, below. */
+ if (h->u.weakdef->def_regular)
+ h->u.weakdef = NULL;
+ else
+ {
+ struct elf_link_hash_entry *weakdef = h->u.weakdef;
+
+ while (h->root.type == bfd_link_hash_indirect)
+ h = (struct elf_link_hash_entry *) h->root.u.i.link;
+
+ BFD_ASSERT (h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak);
+ BFD_ASSERT (weakdef->def_dynamic);
+ BFD_ASSERT (weakdef->root.type == bfd_link_hash_defined
+ || weakdef->root.type == bfd_link_hash_defweak);
+ (*bed->elf_backend_copy_indirect_symbol) (eif->info, weakdef, h);
+ }
+ }
+
+ 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 bfd_boolean
+_bfd_elf_adjust_dynamic_symbol (struct elf_link_hash_entry *h, void *data)
+{
+ struct elf_info_failed *eif = (struct elf_info_failed *) data;
+ bfd *dynobj;
+ const struct elf_backend_data *bed;
+
+ if (! is_elf_hash_table (eif->info->hash))
+ return FALSE;
+
+ /* 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 (! _bfd_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->needs_plt
+ && h->type != STT_GNU_IFUNC
+ && (h->def_regular
+ || !h->def_dynamic
+ || (!h->ref_regular
+ && (h->u.weakdef == NULL || h->u.weakdef->dynindx == -1))))
+ {
+ h->plt = elf_hash_table (eif->info)->init_plt_offset;
+ return TRUE;
+ }
+
+ /* If we've already adjusted this symbol, don't do it again. This
+ can happen via a recursive call. */
+ if (h->dynamic_adjusted)
+ 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->dynamic_adjusted = 1;
+
+ /* 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->u.weakdef != NULL)
+ {
+ /* If we get to this point, there is an implicit reference to
+ H->U.WEAKDEF by a regular object file via the weak symbol H. */
+ h->u.weakdef->ref_regular = 1;
+
+ /* Ensure that the backend adjust_dynamic_symbol function sees
+ H->U.WEAKDEF before H by recursively calling ourselves. */
+ if (! _bfd_elf_adjust_dynamic_symbol (h->u.weakdef, 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->needs_plt)
+ (*_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;
+}
+
+/* Adjust the dynamic symbol, H, for copy in the dynamic bss section,
+ DYNBSS. */
+
+bfd_boolean
+_bfd_elf_adjust_dynamic_copy (struct elf_link_hash_entry *h,
+ asection *dynbss)
+{
+ unsigned int power_of_two;
+ bfd_vma mask;
+ asection *sec = h->root.u.def.section;
+
+ /* The section aligment of definition is the maximum alignment
+ requirement of symbols defined in the section. Since we don't
+ know the symbol alignment requirement, we start with the
+ maximum alignment and check low bits of the symbol address
+ for the minimum alignment. */
+ power_of_two = bfd_get_section_alignment (sec->owner, sec);
+ mask = ((bfd_vma) 1 << power_of_two) - 1;
+ while ((h->root.u.def.value & mask) != 0)
+ {
+ mask >>= 1;
+ --power_of_two;
+ }
+
+ if (power_of_two > bfd_get_section_alignment (dynbss->owner,
+ dynbss))
+ {
+ /* Adjust the section alignment if needed. */
+ if (! bfd_set_section_alignment (dynbss->owner, dynbss,
+ power_of_two))
+ return FALSE;
+ }
+
+ /* We make sure that the symbol will be aligned properly. */
+ dynbss->size = BFD_ALIGN (dynbss->size, mask + 1);
+
+ /* Define the symbol as being at this point in DYNBSS. */
+ h->root.u.def.section = dynbss;
+ h->root.u.def.value = dynbss->size;
+
+ /* Increment the size of DYNBSS to make room for the symbol. */
+ dynbss->size += h->size;
+
+ return TRUE;
+}
+
+/* Adjust all external symbols pointing into SEC_MERGE sections
+ to reflect the object merging within the sections. */
+
+static bfd_boolean
+_bfd_elf_link_sec_merge_syms (struct elf_link_hash_entry *h, void *data)
+{
+ asection *sec;
+
+ if ((h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak)
+ && ((sec = h->root.u.def.section)->flags & SEC_MERGE)
+ && sec->sec_info_type == SEC_INFO_TYPE_MERGE)
+ {
+ bfd *output_bfd = (bfd *) data;
+
+ h->root.u.def.value =
+ _bfd_merged_section_offset (output_bfd,
+ &h->root.u.def.section,
+ elf_section_data (sec)->sec_info,
+ h->root.u.def.value);
+ }
+
+ return TRUE;
+}
+
+/* Returns false if the symbol referred to by H should be considered
+ to resolve local to the current module, and true if it should be
+ considered to bind dynamically. */
+
+bfd_boolean
+_bfd_elf_dynamic_symbol_p (struct elf_link_hash_entry *h,
+ struct bfd_link_info *info,
+ bfd_boolean not_local_protected)
+{
+ bfd_boolean binding_stays_local_p;
+ const struct elf_backend_data *bed;
+ struct elf_link_hash_table *hash_table;
+
+ if (h == NULL)
+ return FALSE;
+
+ 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 it was forced local, then clearly it's not dynamic. */
+ if (h->dynindx == -1)
+ return FALSE;
+ if (h->forced_local)
+ return FALSE;
+
+ /* Identify the cases where name binding rules say that a
+ visible symbol resolves locally. */
+ binding_stays_local_p = info->executable || SYMBOLIC_BIND (info, h);
+
+ switch (ELF_ST_VISIBILITY (h->other))
+ {
+ case STV_INTERNAL:
+ case STV_HIDDEN:
+ return FALSE;
+
+ case STV_PROTECTED:
+ hash_table = elf_hash_table (info);
+ if (!is_elf_hash_table (hash_table))
+ return FALSE;
+
+ bed = get_elf_backend_data (hash_table->dynobj);
+
+ /* Proper resolution for function pointer equality may require
+ that these symbols perhaps be resolved dynamically, even though
+ we should be resolving them to the current module. */
+ if (!not_local_protected || !bed->is_function_type (h->type))
+ binding_stays_local_p = TRUE;
+ break;
+
+ default:
+ break;
+ }
+
+ /* If it isn't defined locally, then clearly it's dynamic. */
+ if (!h->def_regular && !ELF_COMMON_DEF_P (h))
+ return TRUE;
+
+ /* Otherwise, the symbol is dynamic if binding rules don't tell
+ us that it remains local. */
+ return !binding_stays_local_p;
+}
+
+/* Return true if the symbol referred to by H should be considered
+ to resolve local to the current module, and false otherwise. Differs
+ from (the inverse of) _bfd_elf_dynamic_symbol_p in the treatment of
+ undefined symbols. The two functions are virtually identical except
+ for the place where forced_local and dynindx == -1 are tested. If
+ either of those tests are true, _bfd_elf_dynamic_symbol_p will say
+ the symbol is local, while _bfd_elf_symbol_refs_local_p will say
+ the symbol is local only for defined symbols.
+ It might seem that _bfd_elf_dynamic_symbol_p could be rewritten as
+ !_bfd_elf_symbol_refs_local_p, except that targets differ in their
+ treatment of undefined weak symbols. For those that do not make
+ undefined weak symbols dynamic, both functions may return false. */
+
+bfd_boolean
+_bfd_elf_symbol_refs_local_p (struct elf_link_hash_entry *h,
+ struct bfd_link_info *info,
+ bfd_boolean local_protected)
+{
+ const struct elf_backend_data *bed;
+ struct elf_link_hash_table *hash_table;
+
+ /* If it's a local sym, of course we resolve locally. */
+ if (h == NULL)
+ return TRUE;
+
+ /* STV_HIDDEN or STV_INTERNAL ones must be local. */
+ if (ELF_ST_VISIBILITY (h->other) == STV_HIDDEN
+ || ELF_ST_VISIBILITY (h->other) == STV_INTERNAL)
+ return TRUE;
+
+ /* Common symbols that become definitions don't get the DEF_REGULAR
+ flag set, so test it first, and don't bail out. */
+ if (ELF_COMMON_DEF_P (h))
+ /* Do nothing. */;
+ /* If we don't have a definition in a regular file, then we can't
+ resolve locally. The sym is either undefined or dynamic. */
+ else if (!h->def_regular)
+ return FALSE;
+
+ /* Forced local symbols resolve locally. */
+ if (h->forced_local)
+ return TRUE;
+
+ /* As do non-dynamic symbols. */
+ if (h->dynindx == -1)
+ return TRUE;
+
+ /* At this point, we know the symbol is defined and dynamic. In an
+ executable it must resolve locally, likewise when building symbolic
+ shared libraries. */
+ if (info->executable || SYMBOLIC_BIND (info, h))
+ return TRUE;
+
+ /* Now deal with defined dynamic symbols in shared libraries. Ones
+ with default visibility might not resolve locally. */
+ if (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)
+ return FALSE;
+
+ hash_table = elf_hash_table (info);
+ if (!is_elf_hash_table (hash_table))
+ return TRUE;
+
+ bed = get_elf_backend_data (hash_table->dynobj);
+
+ /* STV_PROTECTED non-function symbols are local. */
+ if (!bed->is_function_type (h->type))
+ return TRUE;
+
+ /* Function pointer equality tests may require that STV_PROTECTED
+ symbols be treated as dynamic symbols. If the address of a
+ function not defined in an executable is set to that function's
+ plt entry in the executable, then the address of the function in
+ a shared library must also be the plt entry in the executable. */
+ return local_protected;
+}
+
+/* Caches some TLS segment info, and ensures that the TLS segment vma is
+ aligned. Returns the first TLS output section. */
+
+struct bfd_section *
+_bfd_elf_tls_setup (bfd *obfd, struct bfd_link_info *info)
+{
+ struct bfd_section *sec, *tls;
+ unsigned int align = 0;
+
+ for (sec = obfd->sections; sec != NULL; sec = sec->next)
+ if ((sec->flags & SEC_THREAD_LOCAL) != 0)
+ break;
+ tls = sec;
+
+ for (; sec != NULL && (sec->flags & SEC_THREAD_LOCAL) != 0; sec = sec->next)
+ if (sec->alignment_power > align)
+ align = sec->alignment_power;
+
+ elf_hash_table (info)->tls_sec = tls;
+
+ /* Ensure the alignment of the first section is the largest alignment,
+ so that the tls segment starts aligned. */
+ if (tls != NULL)
+ tls->alignment_power = align;
+
+ return tls;
+}
+
+/* Return TRUE iff this is a non-common, definition of a non-function symbol. */
+static bfd_boolean
+is_global_data_symbol_definition (bfd *abfd ATTRIBUTE_UNUSED,
+ Elf_Internal_Sym *sym)
+{
+ const struct elf_backend_data *bed;
+
+ /* Local symbols do not count, but target specific ones might. */
+ if (ELF_ST_BIND (sym->st_info) != STB_GLOBAL
+ && ELF_ST_BIND (sym->st_info) < STB_LOOS)
+ return FALSE;
+
+ bed = get_elf_backend_data (abfd);
+ /* Function symbols do not count. */
+ if (bed->is_function_type (ELF_ST_TYPE (sym->st_info)))
+ return FALSE;
+
+ /* If the section is undefined, then so is the symbol. */
+ if (sym->st_shndx == SHN_UNDEF)
+ return FALSE;
+
+ /* If the symbol is defined in the common section, then
+ it is a common definition and so does not count. */
+ if (bed->common_definition (sym))
+ return FALSE;
+
+ /* If the symbol is in a target specific section then we
+ must rely upon the backend to tell us what it is. */
+ if (sym->st_shndx >= SHN_LORESERVE && sym->st_shndx < SHN_ABS)
+ /* FIXME - this function is not coded yet:
+
+ return _bfd_is_global_symbol_definition (abfd, sym);
+
+ Instead for now assume that the definition is not global,
+ Even if this is wrong, at least the linker will behave
+ in the same way that it used to do. */
+ return FALSE;
+
+ return TRUE;
+}
+
+/* Search the symbol table of the archive element of the archive ABFD
+ whose archive map contains a mention of SYMDEF, and determine if
+ the symbol is defined in this element. */
+static bfd_boolean
+elf_link_is_defined_archive_symbol (bfd * abfd, carsym * symdef)
+{
+ Elf_Internal_Shdr * hdr;
+ bfd_size_type symcount;
+ bfd_size_type extsymcount;
+ bfd_size_type extsymoff;
+ Elf_Internal_Sym *isymbuf;
+ Elf_Internal_Sym *isym;
+ Elf_Internal_Sym *isymend;
+ bfd_boolean result;
+
+ abfd = _bfd_get_elt_at_filepos (abfd, symdef->file_offset);
+ if (abfd == NULL)
+ return FALSE;
+
+ if (! bfd_check_format (abfd, bfd_object))
+ return FALSE;
+
+ /* Select the appropriate symbol table. */
+ if ((abfd->flags & DYNAMIC) == 0 || elf_dynsymtab (abfd) == 0)
+ hdr = &elf_tdata (abfd)->symtab_hdr;
+ else
+ hdr = &elf_tdata (abfd)->dynsymtab_hdr;
+
+ symcount = hdr->sh_size / get_elf_backend_data (abfd)->s->sizeof_sym;
+
+ /* The sh_info field of the symtab header tells us where the
+ external symbols start. We don't care about the local symbols. */
+ if (elf_bad_symtab (abfd))
+ {
+ extsymcount = symcount;
+ extsymoff = 0;
+ }
+ else
+ {
+ extsymcount = symcount - hdr->sh_info;
+ extsymoff = hdr->sh_info;
+ }
+
+ if (extsymcount == 0)
+ return FALSE;
+
+ /* Read in the symbol table. */
+ isymbuf = bfd_elf_get_elf_syms (abfd, hdr, extsymcount, extsymoff,
+ NULL, NULL, NULL);
+ if (isymbuf == NULL)
+ return FALSE;
+
+ /* Scan the symbol table looking for SYMDEF. */
+ result = FALSE;
+ for (isym = isymbuf, isymend = isymbuf + extsymcount; isym < isymend; isym++)
+ {
+ const char *name;
+
+ name = bfd_elf_string_from_elf_section (abfd, hdr->sh_link,
+ isym->st_name);
+ if (name == NULL)
+ break;
+
+ if (strcmp (name, symdef->name) == 0)
+ {
+ result = is_global_data_symbol_definition (abfd, isym);
+ break;
+ }
+ }
+
+ free (isymbuf);
+
+ return result;
+}
+
+/* Add an entry to the .dynamic table. */
+
+bfd_boolean
+_bfd_elf_add_dynamic_entry (struct bfd_link_info *info,
+ bfd_vma tag,
+ bfd_vma val)
+{
+ struct elf_link_hash_table *hash_table;
+ const struct elf_backend_data *bed;
+ asection *s;
+ bfd_size_type newsize;
+ bfd_byte *newcontents;
+ Elf_Internal_Dyn dyn;
+
+ hash_table = elf_hash_table (info);
+ if (! is_elf_hash_table (hash_table))
+ return FALSE;
+
+ bed = get_elf_backend_data (hash_table->dynobj);
+ s = bfd_get_linker_section (hash_table->dynobj, ".dynamic");
+ BFD_ASSERT (s != NULL);
+
+ newsize = s->size + bed->s->sizeof_dyn;
+ newcontents = (bfd_byte *) bfd_realloc (s->contents, newsize);
+ if (newcontents == NULL)
+ return FALSE;
+
+ dyn.d_tag = tag;
+ dyn.d_un.d_val = val;
+ bed->s->swap_dyn_out (hash_table->dynobj, &dyn, newcontents + s->size);
+
+ s->size = newsize;
+ s->contents = newcontents;
+
+ return TRUE;
+}
+
+/* Add a DT_NEEDED entry for this dynamic object if DO_IT is true,
+ otherwise just check whether one already exists. Returns -1 on error,
+ 1 if a DT_NEEDED tag already exists, and 0 on success. */
+
+static int
+elf_add_dt_needed_tag (bfd *abfd,
+ struct bfd_link_info *info,
+ const char *soname,
+ bfd_boolean do_it)
+{
+ struct elf_link_hash_table *hash_table;
+ bfd_size_type strindex;
+
+ if (!_bfd_elf_link_create_dynstrtab (abfd, info))
+ return -1;
+
+ hash_table = elf_hash_table (info);
+ strindex = _bfd_elf_strtab_add (hash_table->dynstr, soname, FALSE);
+ if (strindex == (bfd_size_type) -1)
+ return -1;
+
+ if (_bfd_elf_strtab_refcount (hash_table->dynstr, strindex) != 1)
+ {
+ asection *sdyn;
+ const struct elf_backend_data *bed;
+ bfd_byte *extdyn;
+
+ bed = get_elf_backend_data (hash_table->dynobj);
+ sdyn = bfd_get_linker_section (hash_table->dynobj, ".dynamic");
+ if (sdyn != NULL)
+ for (extdyn = sdyn->contents;
+ extdyn < sdyn->contents + sdyn->size;
+ extdyn += bed->s->sizeof_dyn)
+ {
+ Elf_Internal_Dyn dyn;
+
+ bed->s->swap_dyn_in (hash_table->dynobj, extdyn, &dyn);
+ if (dyn.d_tag == DT_NEEDED
+ && dyn.d_un.d_val == strindex)
+ {
+ _bfd_elf_strtab_delref (hash_table->dynstr, strindex);
+ return 1;
+ }
+ }
+ }
+
+ if (do_it)
+ {
+ if (!_bfd_elf_link_create_dynamic_sections (hash_table->dynobj, info))
+ return -1;
+
+ if (!_bfd_elf_add_dynamic_entry (info, DT_NEEDED, strindex))
+ return -1;
+ }
+ else
+ /* We were just checking for existence of the tag. */
+ _bfd_elf_strtab_delref (hash_table->dynstr, strindex);
+
+ return 0;
+}
+
+static bfd_boolean
+on_needed_list (const char *soname, struct bfd_link_needed_list *needed)
+{
+ for (; needed != NULL; needed = needed->next)
+ if ((elf_dyn_lib_class (needed->by) & DYN_AS_NEEDED) == 0
+ && strcmp (soname, needed->name) == 0)
+ return TRUE;
+
+ return FALSE;
+}
+
+/* Sort symbol by value, section, and size. */
+static int
+elf_sort_symbol (const void *arg1, const void *arg2)
+{
+ const struct elf_link_hash_entry *h1;
+ const struct elf_link_hash_entry *h2;
+ bfd_signed_vma vdiff;
+
+ h1 = *(const struct elf_link_hash_entry **) arg1;
+ h2 = *(const struct elf_link_hash_entry **) arg2;
+ vdiff = h1->root.u.def.value - h2->root.u.def.value;
+ if (vdiff != 0)
+ return vdiff > 0 ? 1 : -1;
+ else
+ {
+ long sdiff = h1->root.u.def.section->id - h2->root.u.def.section->id;
+ if (sdiff != 0)
+ return sdiff > 0 ? 1 : -1;
+ }
+ vdiff = h1->size - h2->size;
+ return vdiff == 0 ? 0 : vdiff > 0 ? 1 : -1;
+}
+
+/* This function is used to adjust offsets into .dynstr for
+ dynamic symbols. This is called via elf_link_hash_traverse. */
+
+static bfd_boolean
+elf_adjust_dynstr_offsets (struct elf_link_hash_entry *h, void *data)
+{
+ struct elf_strtab_hash *dynstr = (struct elf_strtab_hash *) data;
+
+ if (h->dynindx != -1)
+ h->dynstr_index = _bfd_elf_strtab_offset (dynstr, h->dynstr_index);
+ return TRUE;
+}
+
+/* Assign string offsets in .dynstr, update all structures referencing
+ them. */
+
+static bfd_boolean
+elf_finalize_dynstr (bfd *output_bfd, struct bfd_link_info *info)
+{
+ struct elf_link_hash_table *hash_table = elf_hash_table (info);
+ struct elf_link_local_dynamic_entry *entry;
+ struct elf_strtab_hash *dynstr = hash_table->dynstr;
+ bfd *dynobj = hash_table->dynobj;
+ asection *sdyn;
+ bfd_size_type size;
+ const struct elf_backend_data *bed;
+ bfd_byte *extdyn;
+
+ _bfd_elf_strtab_finalize (dynstr);
+ size = _bfd_elf_strtab_size (dynstr);
+
+ bed = get_elf_backend_data (dynobj);
+ sdyn = bfd_get_linker_section (dynobj, ".dynamic");
+ BFD_ASSERT (sdyn != NULL);
+
+ /* Update all .dynamic entries referencing .dynstr strings. */
+ for (extdyn = sdyn->contents;
+ extdyn < sdyn->contents + sdyn->size;
+ extdyn += bed->s->sizeof_dyn)
+ {
+ Elf_Internal_Dyn dyn;
+
+ bed->s->swap_dyn_in (dynobj, extdyn, &dyn);
+ switch (dyn.d_tag)
+ {
+ case DT_STRSZ:
+ dyn.d_un.d_val = size;
+ break;
+ case DT_NEEDED:
+ case DT_SONAME:
+ case DT_RPATH:
+ case DT_RUNPATH:
+ case DT_FILTER:
+ case DT_AUXILIARY:
+ case DT_AUDIT:
+ case DT_DEPAUDIT:
+ dyn.d_un.d_val = _bfd_elf_strtab_offset (dynstr, dyn.d_un.d_val);
+ break;
+ default:
+ continue;
+ }
+ bed->s->swap_dyn_out (dynobj, &dyn, extdyn);
+ }
+
+ /* Now update local dynamic symbols. */
+ for (entry = hash_table->dynlocal; entry ; entry = entry->next)
+ entry->isym.st_name = _bfd_elf_strtab_offset (dynstr,
+ entry->isym.st_name);
+
+ /* And the rest of dynamic symbols. */
+ elf_link_hash_traverse (hash_table, elf_adjust_dynstr_offsets, dynstr);
+
+ /* Adjust version definitions. */
+ if (elf_tdata (output_bfd)->cverdefs)
+ {
+ asection *s;
+ bfd_byte *p;
+ bfd_size_type i;
+ Elf_Internal_Verdef def;
+ Elf_Internal_Verdaux defaux;
+
+ s = bfd_get_linker_section (dynobj, ".gnu.version_d");
+ p = s->contents;
+ do
+ {
+ _bfd_elf_swap_verdef_in (output_bfd, (Elf_External_Verdef *) p,
+ &def);
+ p += sizeof (Elf_External_Verdef);
+ if (def.vd_aux != sizeof (Elf_External_Verdef))
+ continue;
+ for (i = 0; i < def.vd_cnt; ++i)
+ {
+ _bfd_elf_swap_verdaux_in (output_bfd,
+ (Elf_External_Verdaux *) p, &defaux);
+ defaux.vda_name = _bfd_elf_strtab_offset (dynstr,
+ defaux.vda_name);
+ _bfd_elf_swap_verdaux_out (output_bfd,
+ &defaux, (Elf_External_Verdaux *) p);
+ p += sizeof (Elf_External_Verdaux);
+ }
+ }
+ while (def.vd_next);
+ }
+
+ /* Adjust version references. */
+ if (elf_tdata (output_bfd)->verref)
+ {
+ asection *s;
+ bfd_byte *p;
+ bfd_size_type i;
+ Elf_Internal_Verneed need;
+ Elf_Internal_Vernaux needaux;
+
+ s = bfd_get_linker_section (dynobj, ".gnu.version_r");
+ p = s->contents;
+ do
+ {
+ _bfd_elf_swap_verneed_in (output_bfd, (Elf_External_Verneed *) p,
+ &need);
+ need.vn_file = _bfd_elf_strtab_offset (dynstr, need.vn_file);
+ _bfd_elf_swap_verneed_out (output_bfd, &need,
+ (Elf_External_Verneed *) p);
+ p += sizeof (Elf_External_Verneed);
+ for (i = 0; i < need.vn_cnt; ++i)
+ {
+ _bfd_elf_swap_vernaux_in (output_bfd,
+ (Elf_External_Vernaux *) p, &needaux);
+ needaux.vna_name = _bfd_elf_strtab_offset (dynstr,
+ needaux.vna_name);
+ _bfd_elf_swap_vernaux_out (output_bfd,
+ &needaux,
+ (Elf_External_Vernaux *) p);
+ p += sizeof (Elf_External_Vernaux);
+ }
+ }
+ while (need.vn_next);
+ }
+
+ return TRUE;
+}
+
+/* Return TRUE iff relocations for INPUT are compatible with OUTPUT.
+ The default is to only match when the INPUT and OUTPUT are exactly
+ the same target. */
+
+bfd_boolean
+_bfd_elf_default_relocs_compatible (const bfd_target *input,
+ const bfd_target *output)
+{
+ return input == output;
+}
+
+/* Return TRUE iff relocations for INPUT are compatible with OUTPUT.
+ This version is used when different targets for the same architecture
+ are virtually identical. */
+
+bfd_boolean
+_bfd_elf_relocs_compatible (const bfd_target *input,
+ const bfd_target *output)
+{
+ const struct elf_backend_data *obed, *ibed;
+
+ if (input == output)
+ return TRUE;
+
+ ibed = xvec_get_elf_backend_data (input);
+ obed = xvec_get_elf_backend_data (output);
+
+ if (ibed->arch != obed->arch)
+ return FALSE;
+
+ /* If both backends are using this function, deem them compatible. */
+ return ibed->relocs_compatible == obed->relocs_compatible;
+}
+
+/* Make a special call to the linker "notice" function to tell it that
+ we are about to handle an as-needed lib, or have finished
+ processing the lib. */
+
+bfd_boolean
+_bfd_elf_notice_as_needed (bfd *ibfd,
+ struct bfd_link_info *info,
+ enum notice_asneeded_action act)
+{
+ return (*info->callbacks->notice) (info, NULL, NULL, ibfd, NULL, act, 0);
+}
+
+/* Add symbols from an ELF object file to the linker hash table. */
+
+static bfd_boolean
+elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info)
+{
+ Elf_Internal_Ehdr *ehdr;
+ Elf_Internal_Shdr *hdr;
+ bfd_size_type symcount;
+ bfd_size_type extsymcount;
+ bfd_size_type extsymoff;
+ struct elf_link_hash_entry **sym_hash;
+ bfd_boolean dynamic;
+ Elf_External_Versym *extversym = NULL;
+ Elf_External_Versym *ever;
+ struct elf_link_hash_entry *weaks;
+ struct elf_link_hash_entry **nondeflt_vers = NULL;
+ bfd_size_type nondeflt_vers_cnt = 0;
+ Elf_Internal_Sym *isymbuf = NULL;
+ Elf_Internal_Sym *isym;
+ Elf_Internal_Sym *isymend;
+ const struct elf_backend_data *bed;
+ bfd_boolean add_needed;
+ struct elf_link_hash_table *htab;
+ bfd_size_type amt;
+ void *alloc_mark = NULL;
+ struct bfd_hash_entry **old_table = NULL;
+ unsigned int old_size = 0;
+ unsigned int old_count = 0;
+ void *old_tab = NULL;
+ void *old_ent;
+ struct bfd_link_hash_entry *old_undefs = NULL;
+ struct bfd_link_hash_entry *old_undefs_tail = NULL;
+ long old_dynsymcount = 0;
+ bfd_size_type old_dynstr_size = 0;
+ size_t tabsize = 0;
+ asection *s;
+ bfd_boolean just_syms;
+
+ htab = elf_hash_table (info);
+ bed = get_elf_backend_data (abfd);
+
+ 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->relocatable
+ || !is_elf_hash_table (htab)
+ || info->output_bfd->xvec != abfd->xvec)
+ {
+ if (info->relocatable)
+ bfd_set_error (bfd_error_invalid_operation);
+ else
+ bfd_set_error (bfd_error_wrong_format);
+ goto error_return;
+ }
+ }
+
+ ehdr = elf_elfheader (abfd);
+ if (info->warn_alternate_em
+ && bed->elf_machine_code != ehdr->e_machine
+ && ((bed->elf_machine_alt1 != 0
+ && ehdr->e_machine == bed->elf_machine_alt1)
+ || (bed->elf_machine_alt2 != 0
+ && ehdr->e_machine == bed->elf_machine_alt2)))
+ info->callbacks->einfo
+ (_("%P: alternate ELF machine code found (%d) in %B, expecting %d\n"),
+ ehdr->e_machine, abfd, bed->elf_machine_code);
+
+ /* 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. */
+ /* PR 12761: Also generate this warning when building shared libraries. */
+ for (s = abfd->sections; s != NULL; s = s->next)
+ {
+ const char *name;
+
+ name = bfd_get_section_name (abfd, s);
+ if (CONST_STRNEQ (name, ".gnu.warning."))
+ {
+ 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)
+ {
+ struct elf_link_hash_entry *h;
+
+ h = elf_link_hash_lookup (htab, 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))
+ continue;
+ }
+
+ sz = s->size;
+ msg = (char *) bfd_alloc (abfd, sz + 1);
+ if (msg == NULL)
+ goto error_return;
+
+ if (! bfd_get_section_contents (abfd, s, msg, 0, sz))
+ goto error_return;
+
+ msg[sz] = '\0';
+
+ if (! (_bfd_generic_link_add_one_symbol
+ (info, abfd, name, BSF_WARNING, s, 0, msg,
+ FALSE, bed->collect, NULL)))
+ goto error_return;
+
+ if (!info->relocatable && info->executable)
+ {
+ /* Clobber the section size so that the warning does
+ not get copied into the output file. */
+ s->size = 0;
+
+ /* Also set SEC_EXCLUDE, so that symbols defined in
+ the warning section don't get copied to the output. */
+ s->flags |= SEC_EXCLUDE;
+ }
+ }
+ }
+
+ just_syms = ((s = abfd->sections) != NULL
+ && s->sec_info_type == SEC_INFO_TYPE_JUST_SYMS);
+
+ add_needed = TRUE;
+ 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 and is not from ld --just-symbols. FIXME: If there
+ are no input BFD's of the same format as the output, we can't
+ make a shared library. */
+ if (!just_syms
+ && info->shared
+ && is_elf_hash_table (htab)
+ && info->output_bfd->xvec == abfd->xvec
+ && !htab->dynamic_sections_created)
+ {
+ if (! _bfd_elf_link_create_dynamic_sections (abfd, info))
+ goto error_return;
+ }
+ }
+ else if (!is_elf_hash_table (htab))
+ goto error_return;
+ else
+ {
+ const char *soname = NULL;
+ char *audit = NULL;
+ struct bfd_link_needed_list *rpath = NULL, *runpath = NULL;
+ int ret;
+
+ /* ld --just-symbols and dynamic objects don't mix very well.
+ ld shouldn't allow it. */
+ if (just_syms)
+ abort ();
+
+ /* If this dynamic lib was specified on the command line with
+ --as-needed in effect, then we don't want to add a DT_NEEDED
+ tag unless the lib is actually used. Similary for libs brought
+ in by another lib's DT_NEEDED. When --no-add-needed is used
+ on a dynamic lib, we don't want to add a DT_NEEDED entry for
+ any dynamic library in DT_NEEDED tags in the dynamic lib at
+ all. */
+ add_needed = (elf_dyn_lib_class (abfd)
+ & (DYN_AS_NEEDED | DYN_DT_NEEDED
+ | DYN_NO_NEEDED)) == 0;
+
+ s = bfd_get_section_by_name (abfd, ".dynamic");
+ if (s != NULL)
+ {
+ bfd_byte *dynbuf;
+ bfd_byte *extdyn;
+ unsigned int elfsec;
+ unsigned long shlink;
+
+ if (!bfd_malloc_and_get_section (abfd, s, &dynbuf))
+ {
+error_free_dyn:
+ free (dynbuf);
+ goto error_return;
+ }
+
+ elfsec = _bfd_elf_section_from_bfd_section (abfd, s);
+ if (elfsec == SHN_BAD)
+ goto error_free_dyn;
+ shlink = elf_elfsections (abfd)[elfsec]->sh_link;
+
+ for (extdyn = dynbuf;
+ extdyn < dynbuf + s->size;
+ extdyn += bed->s->sizeof_dyn)
+ {
+ Elf_Internal_Dyn dyn;
+
+ bed->s->swap_dyn_in (abfd, extdyn, &dyn);
+ if (dyn.d_tag == DT_SONAME)
+ {
+ unsigned int tagv = dyn.d_un.d_val;
+ soname = bfd_elf_string_from_elf_section (abfd, shlink, tagv);
+ if (soname == NULL)
+ goto error_free_dyn;
+ }
+ if (dyn.d_tag == DT_NEEDED)
+ {
+ struct bfd_link_needed_list *n, **pn;
+ char *fnm, *anm;
+ unsigned int tagv = dyn.d_un.d_val;
+
+ amt = sizeof (struct bfd_link_needed_list);
+ n = (struct bfd_link_needed_list *) bfd_alloc (abfd, amt);
+ fnm = bfd_elf_string_from_elf_section (abfd, shlink, tagv);
+ if (n == NULL || fnm == NULL)
+ goto error_free_dyn;
+ amt = strlen (fnm) + 1;
+ anm = (char *) bfd_alloc (abfd, amt);
+ if (anm == NULL)
+ goto error_free_dyn;
+ memcpy (anm, fnm, amt);
+ n->name = anm;
+ n->by = abfd;
+ n->next = NULL;
+ for (pn = &htab->needed; *pn != NULL; pn = &(*pn)->next)
+ ;
+ *pn = n;
+ }
+ if (dyn.d_tag == DT_RUNPATH)
+ {
+ struct bfd_link_needed_list *n, **pn;
+ char *fnm, *anm;
+ unsigned int tagv = dyn.d_un.d_val;
+
+ amt = sizeof (struct bfd_link_needed_list);
+ n = (struct bfd_link_needed_list *) bfd_alloc (abfd, amt);
+ fnm = bfd_elf_string_from_elf_section (abfd, shlink, tagv);
+ if (n == NULL || fnm == NULL)
+ goto error_free_dyn;
+ amt = strlen (fnm) + 1;
+ anm = (char *) bfd_alloc (abfd, amt);
+ if (anm == NULL)
+ goto error_free_dyn;
+ memcpy (anm, fnm, amt);
+ n->name = anm;
+ n->by = abfd;
+ n->next = NULL;
+ for (pn = & runpath;
+ *pn != NULL;
+ pn = &(*pn)->next)
+ ;
+ *pn = n;
+ }
+ /* Ignore DT_RPATH if we have seen DT_RUNPATH. */
+ if (!runpath && dyn.d_tag == DT_RPATH)
+ {
+ struct bfd_link_needed_list *n, **pn;
+ char *fnm, *anm;
+ unsigned int tagv = dyn.d_un.d_val;
+
+ amt = sizeof (struct bfd_link_needed_list);
+ n = (struct bfd_link_needed_list *) bfd_alloc (abfd, amt);
+ fnm = bfd_elf_string_from_elf_section (abfd, shlink, tagv);
+ if (n == NULL || fnm == NULL)
+ goto error_free_dyn;
+ amt = strlen (fnm) + 1;
+ anm = (char *) bfd_alloc (abfd, amt);
+ if (anm == NULL)
+ goto error_free_dyn;
+ memcpy (anm, fnm, amt);
+ n->name = anm;
+ n->by = abfd;
+ n->next = NULL;
+ for (pn = & rpath;
+ *pn != NULL;
+ pn = &(*pn)->next)
+ ;
+ *pn = n;
+ }
+ if (dyn.d_tag == DT_AUDIT)
+ {
+ unsigned int tagv = dyn.d_un.d_val;
+ audit = bfd_elf_string_from_elf_section (abfd, shlink, tagv);
+ }
+ }
+
+ free (dynbuf);
+ }
+
+ /* DT_RUNPATH overrides DT_RPATH. Do _NOT_ bfd_release, as that
+ frees all more recently bfd_alloc'd blocks as well. */
+ if (runpath)
+ rpath = runpath;
+
+ if (rpath)
+ {
+ struct bfd_link_needed_list **pn;
+ for (pn = &htab->runpath; *pn != NULL; pn = &(*pn)->next)
+ ;
+ *pn = rpath;
+ }
+
+ /* 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. */
+ bfd_section_list_clear (abfd);
+
+ /* 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 (soname == NULL || *soname == '\0')
+ {
+ soname = elf_dt_name (abfd);
+ if (soname == NULL || *soname == '\0')
+ soname = bfd_get_filename (abfd);
+ }
+
+ /* Save the SONAME because sometimes the linker emulation code
+ will need to know it. */
+ elf_dt_name (abfd) = soname;
+
+ ret = elf_add_dt_needed_tag (abfd, info, soname, add_needed);
+ if (ret < 0)
+ goto error_return;
+
+ /* 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. */
+ if (ret > 0)
+ return TRUE;
+
+ /* Save the DT_AUDIT entry for the linker emulation code. */
+ elf_dt_audit (abfd) = audit;
+ }
+
+ /* 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;
+
+ symcount = hdr->sh_size / bed->s->sizeof_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;
+ }
+
+ sym_hash = elf_sym_hashes (abfd);
+ if (extsymcount != 0)
+ {
+ isymbuf = bfd_elf_get_elf_syms (abfd, hdr, extsymcount, extsymoff,
+ NULL, NULL, NULL);
+ if (isymbuf == NULL)
+ goto error_return;
+
+ if (sym_hash == NULL)
+ {
+ /* We store a pointer to the hash table entry for each
+ external symbol. */
+ amt = extsymcount * sizeof (struct elf_link_hash_entry *);
+ sym_hash = (struct elf_link_hash_entry **) bfd_zalloc (abfd, amt);
+ if (sym_hash == NULL)
+ goto error_free_sym;
+ elf_sym_hashes (abfd) = sym_hash;
+ }
+ }
+
+ if (dynamic)
+ {
+ /* Read in any version definitions. */
+ if (!_bfd_elf_slurp_version_tables (abfd,
+ info->default_imported_symver))
+ goto error_free_sym;
+
+ /* 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 (versymhdr->sh_size);
+ if (extversym == NULL)
+ goto error_free_sym;
+ amt = versymhdr->sh_size;
+ if (bfd_seek (abfd, versymhdr->sh_offset, SEEK_SET) != 0
+ || bfd_bread (extversym, amt, abfd) != amt)
+ goto error_free_vers;
+ }
+ }
+
+ /* If we are loading an as-needed shared lib, save the symbol table
+ state before we start adding symbols. If the lib turns out
+ to be unneeded, restore the state. */
+ if ((elf_dyn_lib_class (abfd) & DYN_AS_NEEDED) != 0)
+ {
+ unsigned int i;
+ size_t entsize;
+
+ for (entsize = 0, i = 0; i < htab->root.table.size; i++)
+ {
+ struct bfd_hash_entry *p;
+ struct elf_link_hash_entry *h;
+
+ for (p = htab->root.table.table[i]; p != NULL; p = p->next)
+ {
+ h = (struct elf_link_hash_entry *) p;
+ entsize += htab->root.table.entsize;
+ if (h->root.type == bfd_link_hash_warning)
+ entsize += htab->root.table.entsize;
+ }
+ }
+
+ tabsize = htab->root.table.size * sizeof (struct bfd_hash_entry *);
+ old_tab = bfd_malloc (tabsize + entsize);
+ if (old_tab == NULL)
+ goto error_free_vers;
+
+ /* Remember the current objalloc pointer, so that all mem for
+ symbols added can later be reclaimed. */
+ alloc_mark = bfd_hash_allocate (&htab->root.table, 1);
+ if (alloc_mark == NULL)
+ goto error_free_vers;
+
+ /* Make a special call to the linker "notice" function to
+ tell it that we are about to handle an as-needed lib. */
+ if (!(*bed->notice_as_needed) (abfd, info, notice_as_needed))
+ goto error_free_vers;
+
+ /* Clone the symbol table. Remember some pointers into the
+ symbol table, and dynamic symbol count. */
+ old_ent = (char *) old_tab + tabsize;
+ memcpy (old_tab, htab->root.table.table, tabsize);
+ old_undefs = htab->root.undefs;
+ old_undefs_tail = htab->root.undefs_tail;
+ old_table = htab->root.table.table;
+ old_size = htab->root.table.size;
+ old_count = htab->root.table.count;
+ old_dynsymcount = htab->dynsymcount;
+ old_dynstr_size = _bfd_elf_strtab_size (htab->dynstr);
+
+ for (i = 0; i < htab->root.table.size; i++)
+ {
+ struct bfd_hash_entry *p;
+ struct elf_link_hash_entry *h;
+
+ for (p = htab->root.table.table[i]; p != NULL; p = p->next)
+ {
+ memcpy (old_ent, p, htab->root.table.entsize);
+ old_ent = (char *) old_ent + htab->root.table.entsize;
+ h = (struct elf_link_hash_entry *) p;
+ if (h->root.type == bfd_link_hash_warning)
+ {
+ memcpy (old_ent, h->root.u.i.link, htab->root.table.entsize);
+ old_ent = (char *) old_ent + htab->root.table.entsize;
+ }
+ }
+ }
+ }
+
+ weaks = NULL;
+ ever = extversym != NULL ? extversym + extsymoff : NULL;
+ for (isym = isymbuf, isymend = isymbuf + extsymcount;
+ isym < isymend;
+ isym++, sym_hash++, ever = (ever != NULL ? ever + 1 : NULL))
+ {
+ int bind;
+ bfd_vma value;
+ asection *sec, *new_sec;
+ flagword flags;
+ const char *name;
+ struct elf_link_hash_entry *h;
+ struct elf_link_hash_entry *hi;
+ bfd_boolean definition;
+ bfd_boolean size_change_ok;
+ bfd_boolean type_change_ok;
+ bfd_boolean new_weakdef;
+ bfd_boolean new_weak;
+ bfd_boolean old_weak;
+ bfd_boolean override;
+ bfd_boolean common;
+ unsigned int old_alignment;
+ bfd *old_bfd;
+
+ override = FALSE;
+
+ flags = BSF_NO_FLAGS;
+ sec = NULL;
+ value = isym->st_value;
+ common = bed->common_definition (isym);
+
+ bind = ELF_ST_BIND (isym->st_info);
+ switch (bind)
+ {
+ case 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. Unfortunately, Irix 5
+ screws this up. */
+ continue;
+
+ case STB_GLOBAL:
+ if (isym->st_shndx != SHN_UNDEF && !common)
+ flags = BSF_GLOBAL;
+ break;
+
+ case STB_WEAK:
+ flags = BSF_WEAK;
+ break;
+
+ case STB_GNU_UNIQUE:
+ flags = BSF_GNU_UNIQUE;
+ break;
+
+ default:
+ /* Leave it up to the processor backend. */
+ break;
+ }
+
+ if (isym->st_shndx == SHN_UNDEF)
+ sec = bfd_und_section_ptr;
+ else if (isym->st_shndx == SHN_ABS)
+ sec = bfd_abs_section_ptr;
+ else if (isym->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 = isym->st_size;
+ }
+ else
+ {
+ sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
+ if (sec == NULL)
+ sec = bfd_abs_section_ptr;
+ else if (discarded_section (sec))
+ {
+ /* Symbols from discarded section are undefined. We keep
+ its visibility. */
+ sec = bfd_und_section_ptr;
+ isym->st_shndx = SHN_UNDEF;
+ }
+ else if ((abfd->flags & (EXEC_P | DYNAMIC)) != 0)
+ value -= sec->vma;
+ }
+
+ name = bfd_elf_string_from_elf_section (abfd, hdr->sh_link,
+ isym->st_name);
+ if (name == NULL)
+ goto error_free_vers;
+
+ if (isym->st_shndx == SHN_COMMON
+ && (abfd->flags & BFD_PLUGIN) != 0)
+ {
+ asection *xc = bfd_get_section_by_name (abfd, "COMMON");
+
+ if (xc == NULL)
+ {
+ flagword sflags = (SEC_ALLOC | SEC_IS_COMMON | SEC_KEEP
+ | SEC_EXCLUDE);
+ xc = bfd_make_section_with_flags (abfd, "COMMON", sflags);
+ if (xc == NULL)
+ goto error_free_vers;
+ }
+ sec = xc;
+ }
+ else if (isym->st_shndx == SHN_COMMON
+ && ELF_ST_TYPE (isym->st_info) == STT_TLS
+ && !info->relocatable)
+ {
+ asection *tcomm = bfd_get_section_by_name (abfd, ".tcommon");
+
+ if (tcomm == NULL)
+ {
+ flagword sflags = (SEC_ALLOC | SEC_THREAD_LOCAL | SEC_IS_COMMON
+ | SEC_LINKER_CREATED);
+ tcomm = bfd_make_section_with_flags (abfd, ".tcommon", sflags);
+ if (tcomm == NULL)
+ goto error_free_vers;
+ }
+ sec = tcomm;
+ }
+ else if (bed->elf_add_symbol_hook)
+ {
+ if (! (*bed->elf_add_symbol_hook) (abfd, info, isym, &name, &flags,
+ &sec, &value))
+ goto error_free_vers;
+
+ /* The hook function sets the name to NULL if this symbol
+ should be skipped for some reason. */
+ if (name == NULL)
+ continue;
+ }
+
+ /* Sanity check that all possibilities were handled. */
+ if (sec == NULL)
+ {
+ bfd_set_error (bfd_error_bad_value);
+ goto error_free_vers;
+ }
+
+ /* Silently discard TLS symbols from --just-syms. There's
+ no way to combine a static TLS block with a new TLS block
+ for this executable. */
+ if (ELF_ST_TYPE (isym->st_info) == STT_TLS
+ && sec->sec_info_type == SEC_INFO_TYPE_JUST_SYMS)
+ continue;
+
+ if (bfd_is_und_section (sec)
+ || bfd_is_com_section (sec))
+ definition = FALSE;
+ else
+ definition = TRUE;
+
+ size_change_ok = FALSE;
+ type_change_ok = bed->type_change_ok;
+ old_weak = FALSE;
+ old_alignment = 0;
+ old_bfd = NULL;
+ new_sec = sec;
+
+ if (is_elf_hash_table (htab))
+ {
+ Elf_Internal_Versym iver;
+ unsigned int vernum = 0;
+ bfd_boolean skip;
+
+ if (ever == NULL)
+ {
+ if (info->default_imported_symver)
+ /* Use the default symbol version created earlier. */
+ iver.vs_vers = elf_tdata (abfd)->cverdefs;
+ else
+ iver.vs_vers = 0;
+ }
+ else
+ _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
+ if it is not a function, 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)
+ || bed->is_function_type (ELF_ST_TYPE (isym->st_info)))))
+ {
+ const char *verstr;
+ size_t namelen, verlen, newlen;
+ char *newname, *p;
+
+ if (isym->st_shndx != SHN_UNDEF)
+ {
+ if (vernum > elf_tdata (abfd)->cverdefs)
+ verstr = NULL;
+ else if (vernum > 1)
+ verstr =
+ elf_tdata (abfd)->verdef[vernum - 1].vd_nodename;
+ else
+ verstr = "";
+
+ if (verstr == NULL)
+ {
+ (*_bfd_error_handler)
+ (_("%B: %s: invalid version %u (max %d)"),
+ abfd, name, vernum,
+ elf_tdata (abfd)->cverdefs);
+ bfd_set_error (bfd_error_bad_value);
+ goto error_free_vers;
+ }
+ }
+ 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)
+ (_("%B: %s: invalid needed version %d"),
+ abfd, name, vernum);
+ bfd_set_error (bfd_error_bad_value);
+ goto error_free_vers;
+ }
+ }
+
+ namelen = strlen (name);
+ verlen = strlen (verstr);
+ newlen = namelen + verlen + 2;
+ if ((iver.vs_vers & VERSYM_HIDDEN) == 0
+ && isym->st_shndx != SHN_UNDEF)
+ ++newlen;
+
+ newname = (char *) bfd_hash_allocate (&htab->root.table, newlen);
+ if (newname == NULL)
+ goto error_free_vers;
+ memcpy (newname, name, namelen);
+ p = newname + namelen;
+ *p++ = ELF_VER_CHR;
+ /* If this is a defined non-hidden version symbol,
+ we add another @ to the name. This indicates the
+ default version of the symbol. */
+ if ((iver.vs_vers & VERSYM_HIDDEN) == 0
+ && isym->st_shndx != SHN_UNDEF)
+ *p++ = ELF_VER_CHR;
+ memcpy (p, verstr, verlen + 1);
+
+ name = newname;
+ }
+
+ /* If this symbol has default visibility and the user has
+ requested we not re-export it, then mark it as hidden. */
+ if (definition
+ && !dynamic
+ && (abfd->no_export
+ || (abfd->my_archive && abfd->my_archive->no_export))
+ && ELF_ST_VISIBILITY (isym->st_other) != STV_INTERNAL)
+ isym->st_other = (STV_HIDDEN
+ | (isym->st_other & ~ELF_ST_VISIBILITY (-1)));
+
+ if (!_bfd_elf_merge_symbol (abfd, info, name, isym, &sec, &value,
+ sym_hash, &old_bfd, &old_weak,
+ &old_alignment, &skip, &override,
+ &type_change_ok, &size_change_ok))
+ goto error_free_vers;
+
+ if (skip)
+ continue;
+
+ 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;
+
+ if (elf_tdata (abfd)->verdef != NULL
+ && 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, NULL, FALSE, bed->collect,
+ (struct bfd_link_hash_entry **) sym_hash)))
+ goto error_free_vers;
+
+ h = *sym_hash;
+ /* We need to make sure that indirect symbol dynamic flags are
+ updated. */
+ hi = h;
+ 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_weak = (flags & BSF_WEAK) != 0;
+ new_weakdef = FALSE;
+ if (dynamic
+ && definition
+ && new_weak
+ && !bed->is_function_type (ELF_ST_TYPE (isym->st_info))
+ && is_elf_hash_table (htab)
+ && h->u.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->u.weakdef = weaks;
+ weaks = h;
+ new_weakdef = TRUE;
+ }
+
+ /* Set the alignment of a common symbol. */
+ if ((common || bfd_is_com_section (sec))
+ && h->root.type == bfd_link_hash_common)
+ {
+ unsigned int align;
+
+ if (common)
+ align = bfd_log2 (isym->st_value);
+ else
+ {
+ /* The new symbol is a common symbol in a shared object.
+ We need to get the alignment from the section. */
+ align = new_sec->alignment_power;
+ }
+ if (align > old_alignment)
+ h->root.u.c.p->alignment_power = align;
+ else
+ h->root.u.c.p->alignment_power = old_alignment;
+ }
+
+ if (is_elf_hash_table (htab))
+ {
+ /* Set a flag in the hash table entry indicating the type of
+ reference or definition we just found. A dynamic symbol
+ is one which is referenced or defined by both a regular
+ object and a shared object. */
+ bfd_boolean dynsym = FALSE;
+
+ /* Plugin symbols aren't normal. Don't set def_regular or
+ ref_regular for them, or make them dynamic. */
+ if ((abfd->flags & BFD_PLUGIN) != 0)
+ ;
+ else if (! dynamic)
+ {
+ if (! definition)
+ {
+ h->ref_regular = 1;
+ if (bind != STB_WEAK)
+ h->ref_regular_nonweak = 1;
+ }
+ else
+ {
+ h->def_regular = 1;
+ if (h->def_dynamic)
+ {
+ h->def_dynamic = 0;
+ h->ref_dynamic = 1;
+ }
+ }
+
+ /* If the indirect symbol has been forced local, don't
+ make the real symbol dynamic. */
+ if ((h == hi || !hi->forced_local)
+ && (! info->executable
+ || h->def_dynamic
+ || h->ref_dynamic))
+ dynsym = TRUE;
+ }
+ else
+ {
+ if (! definition)
+ {
+ h->ref_dynamic = 1;
+ hi->ref_dynamic = 1;
+ }
+ else
+ {
+ h->def_dynamic = 1;
+ hi->def_dynamic = 1;
+ }
+
+ /* If the indirect symbol has been forced local, don't
+ make the real symbol dynamic. */
+ if ((h == hi || !hi->forced_local)
+ && (h->def_regular
+ || h->ref_regular
+ || (h->u.weakdef != NULL
+ && ! new_weakdef
+ && h->u.weakdef->dynindx != -1)))
+ dynsym = TRUE;
+ }
+
+ /* Check to see if we need to add an indirect symbol for
+ the default name. */
+ if (definition
+ || (!override && h->root.type == bfd_link_hash_common))
+ if (!_bfd_elf_add_default_symbol (abfd, info, h, name, isym,
+ sec, value, &old_bfd, &dynsym))
+ goto error_free_vers;
+
+ /* Check the alignment when a common symbol is involved. This
+ can change when a common symbol is overridden by a normal
+ definition or a common symbol is ignored due to the old
+ normal definition. We need to make sure the maximum
+ alignment is maintained. */
+ if ((old_alignment || common)
+ && h->root.type != bfd_link_hash_common)
+ {
+ unsigned int common_align;
+ unsigned int normal_align;
+ unsigned int symbol_align;
+ bfd *normal_bfd;
+ bfd *common_bfd;
+
+ BFD_ASSERT (h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak);
+
+ symbol_align = ffs (h->root.u.def.value) - 1;
+ if (h->root.u.def.section->owner != NULL
+ && (h->root.u.def.section->owner->flags & DYNAMIC) == 0)
+ {
+ normal_align = h->root.u.def.section->alignment_power;
+ if (normal_align > symbol_align)
+ normal_align = symbol_align;
+ }
+ else
+ normal_align = symbol_align;
+
+ if (old_alignment)
+ {
+ common_align = old_alignment;
+ common_bfd = old_bfd;
+ normal_bfd = abfd;
+ }
+ else
+ {
+ common_align = bfd_log2 (isym->st_value);
+ common_bfd = abfd;
+ normal_bfd = old_bfd;
+ }
+
+ if (normal_align < common_align)
+ {
+ /* PR binutils/2735 */
+ if (normal_bfd == NULL)
+ (*_bfd_error_handler)
+ (_("Warning: alignment %u of common symbol `%s' in %B is"
+ " greater than the alignment (%u) of its section %A"),
+ common_bfd, h->root.u.def.section,
+ 1 << common_align, name, 1 << normal_align);
+ else
+ (*_bfd_error_handler)
+ (_("Warning: alignment %u of symbol `%s' in %B"
+ " is smaller than %u in %B"),
+ normal_bfd, common_bfd,
+ 1 << normal_align, name, 1 << common_align);
+ }
+ }
+
+ /* Remember the symbol size if it isn't undefined. */
+ if (isym->st_size != 0
+ && isym->st_shndx != SHN_UNDEF
+ && (definition || h->size == 0))
+ {
+ if (h->size != 0
+ && h->size != isym->st_size
+ && ! size_change_ok)
+ (*_bfd_error_handler)
+ (_("Warning: size of symbol `%s' changed"
+ " from %lu in %B to %lu in %B"),
+ old_bfd, abfd,
+ name, (unsigned long) h->size,
+ (unsigned long) isym->st_size);
+
+ h->size = isym->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. Allow changes between different
+ function types. */
+ if (h->root.type == bfd_link_hash_common)
+ h->size = h->root.u.c.size;
+
+ if (ELF_ST_TYPE (isym->st_info) != STT_NOTYPE
+ && ((definition && !new_weak)
+ || (old_weak && h->root.type == bfd_link_hash_common)
+ || h->type == STT_NOTYPE))
+ {
+ unsigned int type = ELF_ST_TYPE (isym->st_info);
+
+ /* Turn an IFUNC symbol from a DSO into a normal FUNC
+ symbol. */
+ if (type == STT_GNU_IFUNC
+ && (abfd->flags & DYNAMIC) != 0)
+ type = STT_FUNC;
+
+ if (h->type != type)
+ {
+ if (h->type != STT_NOTYPE && ! type_change_ok)
+ (*_bfd_error_handler)
+ (_("Warning: type of symbol `%s' changed"
+ " from %d to %d in %B"),
+ abfd, name, h->type, type);
+
+ h->type = type;
+ }
+ }
+
+ /* Merge st_other field. */
+ elf_merge_st_other (abfd, h, isym, definition, dynamic);
+
+ /* We don't want to make debug symbol dynamic. */
+ if (definition && (sec->flags & SEC_DEBUGGING) && !info->relocatable)
+ dynsym = FALSE;
+
+ /* Nor should we make plugin symbols dynamic. */
+ if ((abfd->flags & BFD_PLUGIN) != 0)
+ dynsym = FALSE;
+
+ if (definition)
+ {
+ h->target_internal = isym->st_target_internal;
+ h->unique_global = (flags & BSF_GNU_UNIQUE) != 0;
+ }
+
+ if (definition && !dynamic)
+ {
+ char *p = strchr (name, ELF_VER_CHR);
+ if (p != NULL && p[1] != ELF_VER_CHR)
+ {
+ /* Queue non-default versions so that .symver x, x@FOO
+ aliases can be checked. */
+ if (!nondeflt_vers)
+ {
+ amt = ((isymend - isym + 1)
+ * sizeof (struct elf_link_hash_entry *));
+ nondeflt_vers =
+ (struct elf_link_hash_entry **) bfd_malloc (amt);
+ if (!nondeflt_vers)
+ goto error_free_vers;
+ }
+ nondeflt_vers[nondeflt_vers_cnt++] = h;
+ }
+ }
+
+ if (dynsym && h->dynindx == -1)
+ {
+ if (! bfd_elf_link_record_dynamic_symbol (info, h))
+ goto error_free_vers;
+ if (h->u.weakdef != NULL
+ && ! new_weakdef
+ && h->u.weakdef->dynindx == -1)
+ {
+ if (!bfd_elf_link_record_dynamic_symbol (info, h->u.weakdef))
+ goto error_free_vers;
+ }
+ }
+ else if (dynsym && h->dynindx != -1)
+ /* If the symbol already has a dynamic index, but
+ visibility says it should not be visible, turn it into
+ a local symbol. */
+ switch (ELF_ST_VISIBILITY (h->other))
+ {
+ case STV_INTERNAL:
+ case STV_HIDDEN:
+ (*bed->elf_backend_hide_symbol) (info, h, TRUE);
+ dynsym = FALSE;
+ break;
+ }
+
+ /* Don't add DT_NEEDED for references from the dummy bfd. */
+ if (!add_needed
+ && definition
+ && ((dynsym
+ && h->ref_regular_nonweak
+ && (old_bfd == NULL
+ || (old_bfd->flags & BFD_PLUGIN) == 0))
+ || (h->ref_dynamic_nonweak
+ && (elf_dyn_lib_class (abfd) & DYN_AS_NEEDED) != 0
+ && !on_needed_list (elf_dt_name (abfd), htab->needed))))
+ {
+ int ret;
+ const char *soname = elf_dt_name (abfd);
+
+ info->callbacks->minfo ("%!", soname, old_bfd,
+ h->root.root.string);
+
+ /* A symbol from a library loaded via DT_NEEDED of some
+ other library is referenced by a regular object.
+ Add a DT_NEEDED entry for it. Issue an error if
+ --no-add-needed is used and the reference was not
+ a weak one. */
+ if (old_bfd != NULL
+ && (elf_dyn_lib_class (abfd) & DYN_NO_NEEDED) != 0)
+ {
+ (*_bfd_error_handler)
+ (_("%B: undefined reference to symbol '%s'"),
+ old_bfd, name);
+ bfd_set_error (bfd_error_missing_dso);
+ goto error_free_vers;
+ }
+
+ elf_dyn_lib_class (abfd) = (enum dynamic_lib_link_class)
+ (elf_dyn_lib_class (abfd) & ~DYN_AS_NEEDED);
+
+ add_needed = TRUE;
+ ret = elf_add_dt_needed_tag (abfd, info, soname, add_needed);
+ if (ret < 0)
+ goto error_free_vers;
+
+ BFD_ASSERT (ret == 0);
+ }
+ }
+ }
+
+ if (extversym != NULL)
+ {
+ free (extversym);
+ extversym = NULL;
+ }
+
+ if (isymbuf != NULL)
+ {
+ free (isymbuf);
+ isymbuf = NULL;
+ }
+
+ if ((elf_dyn_lib_class (abfd) & DYN_AS_NEEDED) != 0)
+ {
+ unsigned int i;
+
+ /* Restore the symbol table. */
+ old_ent = (char *) old_tab + tabsize;
+ memset (elf_sym_hashes (abfd), 0,
+ extsymcount * sizeof (struct elf_link_hash_entry *));
+ htab->root.table.table = old_table;
+ htab->root.table.size = old_size;
+ htab->root.table.count = old_count;
+ memcpy (htab->root.table.table, old_tab, tabsize);
+ htab->root.undefs = old_undefs;
+ htab->root.undefs_tail = old_undefs_tail;
+ _bfd_elf_strtab_restore_size (htab->dynstr, old_dynstr_size);
+ for (i = 0; i < htab->root.table.size; i++)
+ {
+ struct bfd_hash_entry *p;
+ struct elf_link_hash_entry *h;
+ bfd_size_type size;
+ unsigned int alignment_power;
+
+ for (p = htab->root.table.table[i]; p != NULL; p = p->next)
+ {
+ h = (struct elf_link_hash_entry *) p;
+ if (h->root.type == bfd_link_hash_warning)
+ h = (struct elf_link_hash_entry *) h->root.u.i.link;
+ if (h->dynindx >= old_dynsymcount
+ && h->dynstr_index < old_dynstr_size)
+ _bfd_elf_strtab_delref (htab->dynstr, h->dynstr_index);
+
+ /* Preserve the maximum alignment and size for common
+ symbols even if this dynamic lib isn't on DT_NEEDED
+ since it can still be loaded at run time by another
+ dynamic lib. */
+ if (h->root.type == bfd_link_hash_common)
+ {
+ size = h->root.u.c.size;
+ alignment_power = h->root.u.c.p->alignment_power;
+ }
+ else
+ {
+ size = 0;
+ alignment_power = 0;
+ }
+ memcpy (p, old_ent, htab->root.table.entsize);
+ old_ent = (char *) old_ent + htab->root.table.entsize;
+ h = (struct elf_link_hash_entry *) p;
+ if (h->root.type == bfd_link_hash_warning)
+ {
+ memcpy (h->root.u.i.link, old_ent, htab->root.table.entsize);
+ old_ent = (char *) old_ent + htab->root.table.entsize;
+ h = (struct elf_link_hash_entry *) h->root.u.i.link;
+ }
+ if (h->root.type == bfd_link_hash_common)
+ {
+ if (size > h->root.u.c.size)
+ h->root.u.c.size = size;
+ if (alignment_power > h->root.u.c.p->alignment_power)
+ h->root.u.c.p->alignment_power = alignment_power;
+ }
+ }
+ }
+
+ /* Make a special call to the linker "notice" function to
+ tell it that symbols added for crefs may need to be removed. */
+ if (!(*bed->notice_as_needed) (abfd, info, notice_not_needed))
+ goto error_free_vers;
+
+ free (old_tab);
+ objalloc_free_block ((struct objalloc *) htab->root.table.memory,
+ alloc_mark);
+ if (nondeflt_vers != NULL)
+ free (nondeflt_vers);
+ return TRUE;
+ }
+
+ if (old_tab != NULL)
+ {
+ if (!(*bed->notice_as_needed) (abfd, info, notice_needed))
+ goto error_free_vers;
+ free (old_tab);
+ old_tab = NULL;
+ }
+
+ /* Now that all the symbols from this input file are created, handle
+ .symver foo, foo@BAR such that any relocs against foo become foo@BAR. */
+ if (nondeflt_vers != NULL)
+ {
+ bfd_size_type cnt, symidx;
+
+ for (cnt = 0; cnt < nondeflt_vers_cnt; ++cnt)
+ {
+ struct elf_link_hash_entry *h = nondeflt_vers[cnt], *hi;
+ char *shortname, *p;
+
+ p = strchr (h->root.root.string, ELF_VER_CHR);
+ if (p == NULL
+ || (h->root.type != bfd_link_hash_defined
+ && h->root.type != bfd_link_hash_defweak))
+ continue;
+
+ amt = p - h->root.root.string;
+ shortname = (char *) bfd_malloc (amt + 1);
+ if (!shortname)
+ goto error_free_vers;
+ memcpy (shortname, h->root.root.string, amt);
+ shortname[amt] = '\0';
+
+ hi = (struct elf_link_hash_entry *)
+ bfd_link_hash_lookup (&htab->root, shortname,
+ FALSE, FALSE, FALSE);
+ if (hi != NULL
+ && hi->root.type == h->root.type
+ && hi->root.u.def.value == h->root.u.def.value
+ && hi->root.u.def.section == h->root.u.def.section)
+ {
+ (*bed->elf_backend_hide_symbol) (info, hi, TRUE);
+ hi->root.type = bfd_link_hash_indirect;
+ hi->root.u.i.link = (struct bfd_link_hash_entry *) h;
+ (*bed->elf_backend_copy_indirect_symbol) (info, h, hi);
+ sym_hash = elf_sym_hashes (abfd);
+ if (sym_hash)
+ for (symidx = 0; symidx < extsymcount; ++symidx)
+ if (sym_hash[symidx] == hi)
+ {
+ sym_hash[symidx] = h;
+ break;
+ }
+ }
+ free (shortname);
+ }
+ free (nondeflt_vers);
+ nondeflt_vers = NULL;
+ }
+
+ /* 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. */
+ if (weaks != NULL)
+ {
+ struct elf_link_hash_entry **hpp;
+ struct elf_link_hash_entry **hppend;
+ struct elf_link_hash_entry **sorted_sym_hash;
+ struct elf_link_hash_entry *h;
+ size_t sym_count;
+
+ /* Since we have to search the whole symbol list for each weak
+ defined symbol, search time for N weak defined symbols will be
+ O(N^2). Binary search will cut it down to O(NlogN). */
+ amt = extsymcount * sizeof (struct elf_link_hash_entry *);
+ sorted_sym_hash = (struct elf_link_hash_entry **) bfd_malloc (amt);
+ if (sorted_sym_hash == NULL)
+ goto error_return;
+ sym_hash = sorted_sym_hash;
+ hpp = elf_sym_hashes (abfd);
+ hppend = hpp + extsymcount;
+ sym_count = 0;
+ for (; hpp < hppend; hpp++)
+ {
+ h = *hpp;
+ if (h != NULL
+ && h->root.type == bfd_link_hash_defined
+ && !bed->is_function_type (h->type))
+ {
+ *sym_hash = h;
+ sym_hash++;
+ sym_count++;
+ }
+ }
+
+ qsort (sorted_sym_hash, sym_count,
+ sizeof (struct elf_link_hash_entry *),
+ elf_sort_symbol);
+
+ while (weaks != NULL)
+ {
+ struct elf_link_hash_entry *hlook;
+ asection *slook;
+ bfd_vma vlook;
+ size_t i, j, idx = 0;
+
+ hlook = weaks;
+ weaks = hlook->u.weakdef;
+ hlook->u.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;
+
+ i = 0;
+ j = sym_count;
+ while (i != j)
+ {
+ bfd_signed_vma vdiff;
+ idx = (i + j) / 2;
+ h = sorted_sym_hash[idx];
+ vdiff = vlook - h->root.u.def.value;
+ if (vdiff < 0)
+ j = idx;
+ else if (vdiff > 0)
+ i = idx + 1;
+ else
+ {
+ long sdiff = slook->id - h->root.u.def.section->id;
+ if (sdiff < 0)
+ j = idx;
+ else if (sdiff > 0)
+ i = idx + 1;
+ else
+ break;
+ }
+ }
+
+ /* We didn't find a value/section match. */
+ if (i == j)
+ continue;
+
+ /* With multiple aliases, or when the weak symbol is already
+ strongly defined, we have multiple matching symbols and
+ the binary search above may land on any of them. Step
+ one past the matching symbol(s). */
+ while (++idx != j)
+ {
+ h = sorted_sym_hash[idx];
+ if (h->root.u.def.section != slook
+ || h->root.u.def.value != vlook)
+ break;
+ }
+
+ /* Now look back over the aliases. Since we sorted by size
+ as well as value and section, we'll choose the one with
+ the largest size. */
+ while (idx-- != i)
+ {
+ h = sorted_sym_hash[idx];
+
+ /* Stop if value or section doesn't match. */
+ if (h->root.u.def.section != slook
+ || h->root.u.def.value != vlook)
+ break;
+ else if (h != hlook)
+ {
+ hlook->u.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))
+ {
+ err_free_sym_hash:
+ free (sorted_sym_hash);
+ 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 err_free_sym_hash;
+ }
+ break;
+ }
+ }
+ }
+
+ free (sorted_sym_hash);
+ }
+
+ if (bed->check_directives
+ && !(*bed->check_directives) (abfd, info))
+ return FALSE;
+
+ /* 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. */
+ if (! dynamic
+ && is_elf_hash_table (htab)
+ && bed->check_relocs != NULL
+ && elf_object_id (abfd) == elf_hash_table_id (htab)
+ && (*bed->relocs_compatible) (abfd->xvec, info->output_bfd->xvec))
+ {
+ asection *o;
+
+ for (o = abfd->sections; o != NULL; o = o->next)
+ {
+ Elf_Internal_Rela *internal_relocs;
+ bfd_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 = _bfd_elf_link_read_relocs (abfd, o, NULL, NULL,
+ info->keep_memory);
+ if (internal_relocs == NULL)
+ goto error_return;
+
+ ok = (*bed->check_relocs) (abfd, info, o, internal_relocs);
+
+ if (elf_section_data (o)->relocs != internal_relocs)
+ free (internal_relocs);
+
+ if (! ok)
+ goto error_return;
+ }
+ }
+
+ /* If this is a non-traditional link, try to optimize the handling
+ of the .stab/.stabstr sections. */
+ if (! dynamic
+ && ! info->traditional_format
+ && is_elf_hash_table (htab)
+ && (info->strip != strip_all && info->strip != strip_debugger))
+ {
+ asection *stabstr;
+
+ stabstr = bfd_get_section_by_name (abfd, ".stabstr");
+ if (stabstr != NULL)
+ {
+ bfd_size_type string_offset = 0;
+ asection *stab;
+
+ for (stab = abfd->sections; stab; stab = stab->next)
+ if (CONST_STRNEQ (stab->name, ".stab")
+ && (!stab->name[5] ||
+ (stab->name[5] == '.' && ISDIGIT (stab->name[6])))
+ && (stab->flags & SEC_MERGE) == 0
+ && !bfd_is_abs_section (stab->output_section))
+ {
+ struct bfd_elf_section_data *secdata;
+
+ secdata = elf_section_data (stab);
+ if (! _bfd_link_section_stabs (abfd, &htab->stab_info, stab,
+ stabstr, &secdata->sec_info,
+ &string_offset))
+ goto error_return;
+ if (secdata->sec_info)
+ stab->sec_info_type = SEC_INFO_TYPE_STABS;
+ }
+ }
+ }
+
+ if (is_elf_hash_table (htab) && add_needed)
+ {
+ /* Add this bfd to the loaded list. */
+ struct elf_link_loaded_list *n;
+
+ n = (struct elf_link_loaded_list *)
+ bfd_alloc (abfd, sizeof (struct elf_link_loaded_list));
+ if (n == NULL)
+ goto error_return;
+ n->abfd = abfd;
+ n->next = htab->loaded;
+ htab->loaded = n;
+ }
+
+ return TRUE;
+
+ error_free_vers:
+ if (old_tab != NULL)
+ free (old_tab);
+ if (nondeflt_vers != NULL)
+ free (nondeflt_vers);
+ if (extversym != NULL)
+ free (extversym);
+ error_free_sym:
+ if (isymbuf != NULL)
+ free (isymbuf);
+ error_return:
+ return FALSE;
+}
+
+/* Return the linker hash table entry of a symbol that might be
+ satisfied by an archive symbol. Return -1 on error. */
+
+struct elf_link_hash_entry *
+_bfd_elf_archive_symbol_lookup (bfd *abfd,
+ struct bfd_link_info *info,
+ const char *name)
+{
+ struct elf_link_hash_entry *h;
+ char *p, *copy;
+ size_t len, first;
+
+ h = elf_link_hash_lookup (elf_hash_table (info), name, FALSE, FALSE, TRUE);
+ if (h != NULL)
+ return h;
+
+ /* If this is a default version (the name contains @@), look up the
+ symbol again with only one `@' as well as without the version.
+ The effect is that references to the symbol with and without the
+ version will be matched by the default symbol in the archive. */
+
+ p = strchr (name, ELF_VER_CHR);
+ if (p == NULL || p[1] != ELF_VER_CHR)
+ return h;
+
+ /* First check with only one `@'. */
+ len = strlen (name);
+ copy = (char *) bfd_alloc (abfd, len);
+ if (copy == NULL)
+ return (struct elf_link_hash_entry *) 0 - 1;
+
+ first = p - name + 1;
+ memcpy (copy, name, first);
+ memcpy (copy + first, name + first + 1, len - first);
+
+ h = elf_link_hash_lookup (elf_hash_table (info), copy, FALSE, FALSE, TRUE);
+ if (h == NULL)
+ {
+ /* We also need to check references to the symbol without the
+ version. */
+ copy[first - 1] = '\0';
+ h = elf_link_hash_lookup (elf_hash_table (info), copy,
+ FALSE, FALSE, TRUE);
+ }
+
+ bfd_release (abfd, copy);
+ return h;
+}
+
+/* Add symbols from an ELF archive file to the linker hash table. We
+ don't use _bfd_generic_link_add_archive_symbols because we need to
+ handle versioned symbols.
+
+ 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 bfd_boolean
+elf_link_add_archive_symbols (bfd *abfd, struct bfd_link_info *info)
+{
+ symindex c;
+ unsigned char *included = NULL;
+ carsym *symdefs;
+ bfd_boolean loop;
+ bfd_size_type amt;
+ const struct elf_backend_data *bed;
+ struct elf_link_hash_entry * (*archive_symbol_lookup)
+ (bfd *, struct bfd_link_info *, const char *);
+
+ if (! bfd_has_map (abfd))
+ {
+ /* An empty archive is a special case. */
+ if (bfd_openr_next_archived_file (abfd, 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;
+ amt = c;
+ amt *= sizeof (*included);
+ included = (unsigned char *) bfd_zmalloc (amt);
+ if (included == NULL)
+ return FALSE;
+
+ symdefs = bfd_ardata (abfd)->symdefs;
+ bed = get_elf_backend_data (abfd);
+ archive_symbol_lookup = bed->elf_backend_archive_symbol_lookup;
+
+ 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 (included[i])
+ continue;
+ if (symdef->file_offset == last)
+ {
+ included[i] = TRUE;
+ continue;
+ }
+
+ h = archive_symbol_lookup (abfd, info, symdef->name);
+ if (h == (struct elf_link_hash_entry *) 0 - 1)
+ goto error_return;
+
+ if (h == NULL)
+ continue;
+
+ if (h->root.type == bfd_link_hash_common)
+ {
+ /* We currently have a common symbol. The archive map contains
+ a reference to this symbol, so we may want to include it. We
+ only want to include it however, if this archive element
+ contains a definition of the symbol, not just another common
+ declaration of it.
+
+ Unfortunately some archivers (including GNU ar) will put
+ declarations of common symbols into their archive maps, as
+ well as real definitions, so we cannot just go by the archive
+ map alone. Instead we must read in the element's symbol
+ table and check that to see what kind of symbol definition
+ this is. */
+ if (! elf_link_is_defined_archive_symbol (abfd, symdef))
+ continue;
+ }
+ else if (h->root.type != bfd_link_hash_undefined)
+ {
+ if (h->root.type != bfd_link_hash_undefweak)
+ /* Symbol must be defined. Don't check it again. */
+ included[i] = TRUE;
+ continue;
+ }
+
+ /* We need to include this archive member. */
+ element = _bfd_get_elt_at_filepos (abfd, symdef->file_offset);
+ if (element == NULL)
+ goto error_return;
+
+ if (! bfd_check_format (element, bfd_object))
+ goto error_return;
+
+ undefs_tail = info->hash->undefs_tail;
+
+ if (!(*info->callbacks
+ ->add_archive_element) (info, element, symdef->name, &element))
+ goto error_return;
+ if (!bfd_link_add_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 (included);
+
+ return TRUE;
+
+ error_return:
+ if (included != NULL)
+ free (included);
+ return FALSE;
+}
+
+/* Given an ELF BFD, add symbols to the global hash table as
+ appropriate. */
+
+bfd_boolean
+bfd_elf_link_add_symbols (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;
+ }
+}
+
+struct hash_codes_info
+{
+ unsigned long *hashcodes;
+ bfd_boolean error;
+};
+
+/* This function will be called though elf_link_hash_traverse to store
+ all hash value of the exported symbols in an array. */
+
+static bfd_boolean
+elf_collect_hash_codes (struct elf_link_hash_entry *h, void *data)
+{
+ struct hash_codes_info *inf = (struct hash_codes_info *) 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 = (char *) bfd_malloc (p - name + 1);
+ if (alc == NULL)
+ {
+ inf->error = TRUE;
+ return FALSE;
+ }
+ 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. */
+ *(inf->hashcodes)++ = ha;
+
+ /* And store it in the struct so that we can put it in the hash table
+ later. */
+ h->u.elf_hash_value = ha;
+
+ if (alc != NULL)
+ free (alc);
+
+ return TRUE;
+}
+
+struct collect_gnu_hash_codes
+{
+ bfd *output_bfd;
+ const struct elf_backend_data *bed;
+ unsigned long int nsyms;
+ unsigned long int maskbits;
+ unsigned long int *hashcodes;
+ unsigned long int *hashval;
+ unsigned long int *indx;
+ unsigned long int *counts;
+ bfd_vma *bitmask;
+ bfd_byte *contents;
+ long int min_dynindx;
+ unsigned long int bucketcount;
+ unsigned long int symindx;
+ long int local_indx;
+ long int shift1, shift2;
+ unsigned long int mask;
+ bfd_boolean error;
+};
+
+/* This function will be called though elf_link_hash_traverse to store
+ all hash value of the exported symbols in an array. */
+
+static bfd_boolean
+elf_collect_gnu_hash_codes (struct elf_link_hash_entry *h, void *data)
+{
+ struct collect_gnu_hash_codes *s = (struct collect_gnu_hash_codes *) 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;
+
+ /* Ignore also local symbols and undefined symbols. */
+ if (! (*s->bed->elf_hash_symbol) (h))
+ return TRUE;
+
+ name = h->root.root.string;
+ p = strchr (name, ELF_VER_CHR);
+ if (p != NULL)
+ {
+ alc = (char *) bfd_malloc (p - name + 1);
+ if (alc == NULL)
+ {
+ s->error = TRUE;
+ return FALSE;
+ }
+ memcpy (alc, name, p - name);
+ alc[p - name] = '\0';
+ name = alc;
+ }
+
+ /* Compute the hash value. */
+ ha = bfd_elf_gnu_hash (name);
+
+ /* Store the found hash value in the array for compute_bucket_count,
+ and also for .dynsym reordering purposes. */
+ s->hashcodes[s->nsyms] = ha;
+ s->hashval[h->dynindx] = ha;
+ ++s->nsyms;
+ if (s->min_dynindx < 0 || s->min_dynindx > h->dynindx)
+ s->min_dynindx = h->dynindx;
+
+ if (alc != NULL)
+ free (alc);
+
+ return TRUE;
+}
+
+/* This function will be called though elf_link_hash_traverse to do
+ final dynaminc symbol renumbering. */
+
+static bfd_boolean
+elf_renumber_gnu_hash_syms (struct elf_link_hash_entry *h, void *data)
+{
+ struct collect_gnu_hash_codes *s = (struct collect_gnu_hash_codes *) data;
+ unsigned long int bucket;
+ unsigned long int val;
+
+ /* Ignore indirect symbols. */
+ if (h->dynindx == -1)
+ return TRUE;
+
+ /* Ignore also local symbols and undefined symbols. */
+ if (! (*s->bed->elf_hash_symbol) (h))
+ {
+ if (h->dynindx >= s->min_dynindx)
+ h->dynindx = s->local_indx++;
+ return TRUE;
+ }
+
+ bucket = s->hashval[h->dynindx] % s->bucketcount;
+ val = (s->hashval[h->dynindx] >> s->shift1)
+ & ((s->maskbits >> s->shift1) - 1);
+ s->bitmask[val] |= ((bfd_vma) 1) << (s->hashval[h->dynindx] & s->mask);
+ s->bitmask[val]
+ |= ((bfd_vma) 1) << ((s->hashval[h->dynindx] >> s->shift2) & s->mask);
+ val = s->hashval[h->dynindx] & ~(unsigned long int) 1;
+ if (s->counts[bucket] == 1)
+ /* Last element terminates the chain. */
+ val |= 1;
+ bfd_put_32 (s->output_bfd, val,
+ s->contents + (s->indx[bucket] - s->symindx) * 4);
+ --s->counts[bucket];
+ h->dynindx = s->indx[bucket]++;
+ return TRUE;
+}
+
+/* Return TRUE if symbol should be hashed in the `.gnu.hash' section. */
+
+bfd_boolean
+_bfd_elf_hash_symbol (struct elf_link_hash_entry *h)
+{
+ return !(h->forced_local
+ || h->root.type == bfd_link_hash_undefined
+ || h->root.type == bfd_link_hash_undefweak
+ || ((h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak)
+ && h->root.u.def.section->output_section == NULL));
+}
+
+/* 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 (struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ unsigned long int *hashcodes ATTRIBUTE_UNUSED,
+ unsigned long int nsyms,
+ int gnu_hash)
+{
+ size_t best_size = 0;
+ unsigned long int i;
+
+ /* 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)
+ {
+ size_t minsize;
+ size_t maxsize;
+ BFD_HOST_U_64_BIT best_chlen = ~((BFD_HOST_U_64_BIT) 0);
+ bfd *dynobj = elf_hash_table (info)->dynobj;
+ size_t dynsymcount = elf_hash_table (info)->dynsymcount;
+ const struct elf_backend_data *bed = get_elf_backend_data (dynobj);
+ unsigned long int *counts;
+ bfd_size_type amt;
+ unsigned int no_improvement_count = 0;
+
+ /* 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;
+ if (gnu_hash)
+ {
+ if (minsize < 2)
+ minsize = 2;
+ if ((best_size & 31) == 0)
+ ++best_size;
+ }
+
+ /* Create array where we count the collisions in. We must use bfd_malloc
+ since the size could be large. */
+ amt = maxsize;
+ amt *= sizeof (unsigned long int);
+ counts = (unsigned long int *) bfd_malloc (amt);
+ if (counts == NULL)
+ 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;
+
+ if (gnu_hash && (i & 31) == 0)
+ continue;
+
+ 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 + DYNSYMCOUNT entries for the size values
+ and the chains. */
+ max = (2 + dynsymcount) * bed->s->sizeof_hash_entry;
+
+# if 1
+ /* Variant 1: optimize for short chains. We add the squares
+ of all the chain lengths (which favors 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 / bed->s->sizeof_hash_entry) + 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 / bed->s->sizeof_hash_entry) + 1;
+ max *= fact;
+# endif
+
+ /* Compare with current best results. */
+ if (max < best_chlen)
+ {
+ best_chlen = max;
+ best_size = i;
+ no_improvement_count = 0;
+ }
+ /* PR 11843: Avoid futile long searches for the best bucket size
+ when there are a large number of symbols. */
+ else if (++no_improvement_count == 100)
+ break;
+ }
+
+ 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 (nsyms < elf_buckets[i + 1])
+ break;
+ }
+ if (gnu_hash && best_size < 2)
+ best_size = 2;
+ }
+
+ return best_size;
+}
+
+/* Size any SHT_GROUP section for ld -r. */
+
+bfd_boolean
+_bfd_elf_size_group_sections (struct bfd_link_info *info)
+{
+ bfd *ibfd;
+
+ for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next)
+ if (bfd_get_flavour (ibfd) == bfd_target_elf_flavour
+ && !_bfd_elf_fixup_group_sections (ibfd, bfd_abs_section_ptr))
+ return FALSE;
+ return TRUE;
+}
+
+/* Set a default stack segment size. The value in INFO wins. If it
+ is unset, LEGACY_SYMBOL's value is used, and if that symbol is
+ undefined it is initialized. */
+
+bfd_boolean
+bfd_elf_stack_segment_size (bfd *output_bfd,
+ struct bfd_link_info *info,
+ const char *legacy_symbol,
+ bfd_vma default_size)
+{
+ struct elf_link_hash_entry *h = NULL;
+
+ /* Look for legacy symbol. */
+ if (legacy_symbol)
+ h = elf_link_hash_lookup (elf_hash_table (info), legacy_symbol,
+ FALSE, FALSE, FALSE);
+ if (h && (h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak)
+ && h->def_regular
+ && (h->type == STT_NOTYPE || h->type == STT_OBJECT))
+ {
+ /* The symbol has no type if specified on the command line. */
+ h->type = STT_OBJECT;
+ if (info->stacksize)
+ (*_bfd_error_handler) (_("%B: stack size specified and %s set"),
+ output_bfd, legacy_symbol);
+ else if (h->root.u.def.section != bfd_abs_section_ptr)
+ (*_bfd_error_handler) (_("%B: %s not absolute"),
+ output_bfd, legacy_symbol);
+ else
+ info->stacksize = h->root.u.def.value;
+ }
+
+ if (!info->stacksize)
+ /* If the user didn't set a size, or explicitly inhibit the
+ size, set it now. */
+ info->stacksize = default_size;
+
+ /* Provide the legacy symbol, if it is referenced. */
+ if (h && (h->root.type == bfd_link_hash_undefined
+ || h->root.type == bfd_link_hash_undefweak))
+ {
+ struct bfd_link_hash_entry *bh = NULL;
+
+ if (!(_bfd_generic_link_add_one_symbol
+ (info, output_bfd, legacy_symbol,
+ BSF_GLOBAL, bfd_abs_section_ptr,
+ info->stacksize >= 0 ? info->stacksize : 0,
+ NULL, FALSE, get_elf_backend_data (output_bfd)->collect, &bh)))
+ return FALSE;
+
+ h = (struct elf_link_hash_entry *) bh;
+ h->def_regular = 1;
+ h->type = STT_OBJECT;
+ }
+
+ return TRUE;
+}
+
+/* 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. */
+
+bfd_boolean
+bfd_elf_size_dynamic_sections (bfd *output_bfd,
+ const char *soname,
+ const char *rpath,
+ const char *filter_shlib,
+ const char *audit,
+ const char *depaudit,
+ const char * const *auxiliary_filters,
+ struct bfd_link_info *info,
+ asection **sinterpptr)
+{
+ bfd_size_type soname_indx;
+ bfd *dynobj;
+ const struct elf_backend_data *bed;
+ struct elf_info_failed asvinfo;
+
+ *sinterpptr = NULL;
+
+ soname_indx = (bfd_size_type) -1;
+
+ if (!is_elf_hash_table (info->hash))
+ return TRUE;
+
+ bed = get_elf_backend_data (output_bfd);
+
+ /* Any syms created from now on start with -1 in
+ got.refcount/offset and plt.refcount/offset. */
+ elf_hash_table (info)->init_got_refcount
+ = elf_hash_table (info)->init_got_offset;
+ elf_hash_table (info)->init_plt_refcount
+ = elf_hash_table (info)->init_plt_offset;
+
+ if (info->relocatable
+ && !_bfd_elf_size_group_sections (info))
+ return FALSE;
+
+ /* The backend may have to create some sections regardless of whether
+ we're dynamic or not. */
+ if (bed->elf_backend_always_size_sections
+ && ! (*bed->elf_backend_always_size_sections) (output_bfd, info))
+ return FALSE;
+
+ /* Determine any GNU_STACK segment requirements, after the backend
+ has had a chance to set a default segment size. */
+ if (info->execstack)
+ elf_stack_flags (output_bfd) = PF_R | PF_W | PF_X;
+ else if (info->noexecstack)
+ elf_stack_flags (output_bfd) = PF_R | PF_W;
+ else
+ {
+ bfd *inputobj;
+ asection *notesec = NULL;
+ int exec = 0;
+
+ for (inputobj = info->input_bfds;
+ inputobj;
+ inputobj = inputobj->link.next)
+ {
+ asection *s;
+
+ if (inputobj->flags
+ & (DYNAMIC | EXEC_P | BFD_PLUGIN | BFD_LINKER_CREATED))
+ continue;
+ s = bfd_get_section_by_name (inputobj, ".note.GNU-stack");
+ if (s)
+ {
+ if (s->flags & SEC_CODE)
+ exec = PF_X;
+ notesec = s;
+ }
+ else if (bed->default_execstack)
+ exec = PF_X;
+ }
+ if (notesec || info->stacksize > 0)
+ elf_stack_flags (output_bfd) = PF_R | PF_W | exec;
+ if (notesec && exec && info->relocatable
+ && notesec->output_section != bfd_abs_section_ptr)
+ notesec->output_section->flags |= SEC_CODE;
+ }
+
+ dynobj = elf_hash_table (info)->dynobj;
+
+ if (dynobj != NULL && elf_hash_table (info)->dynamic_sections_created)
+ {
+ struct elf_info_failed eif;
+ struct elf_link_hash_entry *h;
+ asection *dynstr;
+ struct bfd_elf_version_tree *t;
+ struct bfd_elf_version_expr *d;
+ asection *s;
+ bfd_boolean all_defined;
+
+ *sinterpptr = bfd_get_linker_section (dynobj, ".interp");
+ BFD_ASSERT (*sinterpptr != NULL || !info->executable);
+
+ if (soname != NULL)
+ {
+ soname_indx = _bfd_elf_strtab_add (elf_hash_table (info)->dynstr,
+ soname, TRUE);
+ if (soname_indx == (bfd_size_type) -1
+ || !_bfd_elf_add_dynamic_entry (info, DT_SONAME, soname_indx))
+ return FALSE;
+ }
+
+ if (info->symbolic)
+ {
+ if (!_bfd_elf_add_dynamic_entry (info, DT_SYMBOLIC, 0))
+ return FALSE;
+ info->flags |= DF_SYMBOLIC;
+ }
+
+ if (rpath != NULL)
+ {
+ bfd_size_type indx;
+ bfd_vma tag;
+
+ indx = _bfd_elf_strtab_add (elf_hash_table (info)->dynstr, rpath,
+ TRUE);
+ if (indx == (bfd_size_type) -1)
+ return FALSE;
+
+ tag = info->new_dtags ? DT_RUNPATH : DT_RPATH;
+ if (!_bfd_elf_add_dynamic_entry (info, tag, indx))
+ return FALSE;
+ }
+
+ if (filter_shlib != NULL)
+ {
+ bfd_size_type indx;
+
+ indx = _bfd_elf_strtab_add (elf_hash_table (info)->dynstr,
+ filter_shlib, TRUE);
+ if (indx == (bfd_size_type) -1
+ || !_bfd_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_elf_strtab_add (elf_hash_table (info)->dynstr,
+ *p, TRUE);
+ if (indx == (bfd_size_type) -1
+ || !_bfd_elf_add_dynamic_entry (info, DT_AUXILIARY, indx))
+ return FALSE;
+ }
+ }
+
+ if (audit != NULL)
+ {
+ bfd_size_type indx;
+
+ indx = _bfd_elf_strtab_add (elf_hash_table (info)->dynstr, audit,
+ TRUE);
+ if (indx == (bfd_size_type) -1
+ || !_bfd_elf_add_dynamic_entry (info, DT_AUDIT, indx))
+ return FALSE;
+ }
+
+ if (depaudit != NULL)
+ {
+ bfd_size_type indx;
+
+ indx = _bfd_elf_strtab_add (elf_hash_table (info)->dynstr, depaudit,
+ TRUE);
+ if (indx == (bfd_size_type) -1
+ || !_bfd_elf_add_dynamic_entry (info, DT_DEPAUDIT, indx))
+ return FALSE;
+ }
+
+ eif.info = info;
+ eif.failed = FALSE;
+
+ /* If we are supposed to export all symbols into the dynamic symbol
+ table (this is not the normal case), then do so. */
+ if (info->export_dynamic
+ || (info->executable && info->dynamic))
+ {
+ elf_link_hash_traverse (elf_hash_table (info),
+ _bfd_elf_export_symbol,
+ &eif);
+ if (eif.failed)
+ return FALSE;
+ }
+
+ /* Make all global versions with definition. */
+ for (t = info->version_info; t != NULL; t = t->next)
+ for (d = t->globals.list; d != NULL; d = d->next)
+ if (!d->symver && d->literal)
+ {
+ const char *verstr, *name;
+ size_t namelen, verlen, newlen;
+ char *newname, *p, leading_char;
+ struct elf_link_hash_entry *newh;
+
+ leading_char = bfd_get_symbol_leading_char (output_bfd);
+ name = d->pattern;
+ namelen = strlen (name) + (leading_char != '\0');
+ verstr = t->name;
+ verlen = strlen (verstr);
+ newlen = namelen + verlen + 3;
+
+ newname = (char *) bfd_malloc (newlen);
+ if (newname == NULL)
+ return FALSE;
+ newname[0] = leading_char;
+ memcpy (newname + (leading_char != '\0'), name, namelen);
+
+ /* Check the hidden versioned definition. */
+ p = newname + namelen;
+ *p++ = ELF_VER_CHR;
+ memcpy (p, verstr, verlen + 1);
+ newh = elf_link_hash_lookup (elf_hash_table (info),
+ newname, FALSE, FALSE,
+ FALSE);
+ if (newh == NULL
+ || (newh->root.type != bfd_link_hash_defined
+ && newh->root.type != bfd_link_hash_defweak))
+ {
+ /* Check the default versioned definition. */
+ *p++ = ELF_VER_CHR;
+ memcpy (p, verstr, verlen + 1);
+ newh = elf_link_hash_lookup (elf_hash_table (info),
+ newname, FALSE, FALSE,
+ FALSE);
+ }
+ free (newname);
+
+ /* Mark this version if there is a definition and it is
+ not defined in a shared object. */
+ if (newh != NULL
+ && !newh->def_dynamic
+ && (newh->root.type == bfd_link_hash_defined
+ || newh->root.type == bfd_link_hash_defweak))
+ d->symver = 1;
+ }
+
+ /* Attach all the symbols to their version information. */
+ asvinfo.info = info;
+ asvinfo.failed = FALSE;
+
+ elf_link_hash_traverse (elf_hash_table (info),
+ _bfd_elf_link_assign_sym_version,
+ &asvinfo);
+ if (asvinfo.failed)
+ return FALSE;
+
+ if (!info->allow_undefined_version)
+ {
+ /* Check if all global versions have a definition. */
+ all_defined = TRUE;
+ for (t = info->version_info; t != NULL; t = t->next)
+ for (d = t->globals.list; d != NULL; d = d->next)
+ if (d->literal && !d->symver && !d->script)
+ {
+ (*_bfd_error_handler)
+ (_("%s: undefined version: %s"),
+ d->pattern, t->name);
+ all_defined = FALSE;
+ }
+
+ if (!all_defined)
+ {
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+ }
+
+ /* Find all symbols which were defined in a dynamic object and make
+ the backend pick a reasonable value for them. */
+ elf_link_hash_traverse (elf_hash_table (info),
+ _bfd_elf_adjust_dynamic_symbol,
+ &eif);
+ if (eif.failed)
+ return FALSE;
+
+ /* Add some entries to the .dynamic section. We fill in some of the
+ values later, in bfd_elf_final_link, but we must add the entries
+ now so that we know the final size of the .dynamic section. */
+
+ /* If there are initialization and/or finalization functions to
+ call then add the corresponding DT_INIT/DT_FINI entries. */
+ h = (info->init_function
+ ? elf_link_hash_lookup (elf_hash_table (info),
+ info->init_function, FALSE,
+ FALSE, FALSE)
+ : NULL);
+ if (h != NULL
+ && (h->ref_regular
+ || h->def_regular))
+ {
+ if (!_bfd_elf_add_dynamic_entry (info, DT_INIT, 0))
+ return FALSE;
+ }
+ h = (info->fini_function
+ ? elf_link_hash_lookup (elf_hash_table (info),
+ info->fini_function, FALSE,
+ FALSE, FALSE)
+ : NULL);
+ if (h != NULL
+ && (h->ref_regular
+ || h->def_regular))
+ {
+ if (!_bfd_elf_add_dynamic_entry (info, DT_FINI, 0))
+ return FALSE;
+ }
+
+ s = bfd_get_section_by_name (output_bfd, ".preinit_array");
+ if (s != NULL && s->linker_has_input)
+ {
+ /* DT_PREINIT_ARRAY is not allowed in shared library. */
+ if (! info->executable)
+ {
+ bfd *sub;
+ asection *o;
+
+ for (sub = info->input_bfds; sub != NULL;
+ sub = sub->link.next)
+ if (bfd_get_flavour (sub) == bfd_target_elf_flavour)
+ for (o = sub->sections; o != NULL; o = o->next)
+ if (elf_section_data (o)->this_hdr.sh_type
+ == SHT_PREINIT_ARRAY)
+ {
+ (*_bfd_error_handler)
+ (_("%B: .preinit_array section is not allowed in DSO"),
+ sub);
+ break;
+ }
+
+ bfd_set_error (bfd_error_nonrepresentable_section);
+ return FALSE;
+ }
+
+ if (!_bfd_elf_add_dynamic_entry (info, DT_PREINIT_ARRAY, 0)
+ || !_bfd_elf_add_dynamic_entry (info, DT_PREINIT_ARRAYSZ, 0))
+ return FALSE;
+ }
+ s = bfd_get_section_by_name (output_bfd, ".init_array");
+ if (s != NULL && s->linker_has_input)
+ {
+ if (!_bfd_elf_add_dynamic_entry (info, DT_INIT_ARRAY, 0)
+ || !_bfd_elf_add_dynamic_entry (info, DT_INIT_ARRAYSZ, 0))
+ return FALSE;
+ }
+ s = bfd_get_section_by_name (output_bfd, ".fini_array");
+ if (s != NULL && s->linker_has_input)
+ {
+ if (!_bfd_elf_add_dynamic_entry (info, DT_FINI_ARRAY, 0)
+ || !_bfd_elf_add_dynamic_entry (info, DT_FINI_ARRAYSZ, 0))
+ return FALSE;
+ }
+
+ dynstr = bfd_get_linker_section (dynobj, ".dynstr");
+ /* If .dynstr is excluded from the link, we don't want any of
+ these tags. Strictly, we should be checking each section
+ individually; This quick check covers for the case where
+ someone does a /DISCARD/ : { *(*) }. */
+ if (dynstr != NULL && dynstr->output_section != bfd_abs_section_ptr)
+ {
+ bfd_size_type strsize;
+
+ strsize = _bfd_elf_strtab_size (elf_hash_table (info)->dynstr);
+ if ((info->emit_hash
+ && !_bfd_elf_add_dynamic_entry (info, DT_HASH, 0))
+ || (info->emit_gnu_hash
+ && !_bfd_elf_add_dynamic_entry (info, DT_GNU_HASH, 0))
+ || !_bfd_elf_add_dynamic_entry (info, DT_STRTAB, 0)
+ || !_bfd_elf_add_dynamic_entry (info, DT_SYMTAB, 0)
+ || !_bfd_elf_add_dynamic_entry (info, DT_STRSZ, strsize)
+ || !_bfd_elf_add_dynamic_entry (info, DT_SYMENT,
+ bed->s->sizeof_sym))
+ return FALSE;
+ }
+ }
+
+ /* The backend must work out the sizes of all the other dynamic
+ sections. */
+ if (dynobj != NULL
+ && bed->elf_backend_size_dynamic_sections != NULL
+ && ! (*bed->elf_backend_size_dynamic_sections) (output_bfd, info))
+ return FALSE;
+
+ if (! _bfd_elf_maybe_strip_eh_frame_hdr (info))
+ return FALSE;
+
+ if (dynobj != NULL && elf_hash_table (info)->dynamic_sections_created)
+ {
+ unsigned long section_sym_count;
+ struct bfd_elf_version_tree *verdefs;
+ asection *s;
+
+ /* Set up the version definition section. */
+ s = bfd_get_linker_section (dynobj, ".gnu.version_d");
+ BFD_ASSERT (s != NULL);
+
+ /* We may have created additional version definitions if we are
+ just linking a regular application. */
+ verdefs = info->version_info;
+
+ /* Skip anonymous version tag. */
+ if (verdefs != NULL && verdefs->vernum == 0)
+ verdefs = verdefs->next;
+
+ if (verdefs == NULL && !info->create_default_symver)
+ s->flags |= SEC_EXCLUDE;
+ 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;
+ struct bfd_link_hash_entry *bh;
+ struct elf_link_hash_entry *h;
+ const char *name;
+
+ cdefs = 0;
+ size = 0;
+
+ /* Make space for the base version. */
+ size += sizeof (Elf_External_Verdef);
+ size += sizeof (Elf_External_Verdaux);
+ ++cdefs;
+
+ /* Make space for the default version. */
+ if (info->create_default_symver)
+ {
+ size += sizeof (Elf_External_Verdef);
+ ++cdefs;
+ }
+
+ for (t = verdefs; t != NULL; t = t->next)
+ {
+ struct bfd_elf_version_deps *n;
+
+ /* Don't emit base version twice. */
+ if (t->vernum == 0)
+ continue;
+
+ 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->size = size;
+ s->contents = (unsigned char *) bfd_alloc (output_bfd, s->size);
+ if (s->contents == NULL && s->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;
+ if (info->create_default_symver)
+ {
+ def.vd_aux = 2 * sizeof (Elf_External_Verdef);
+ def.vd_next = sizeof (Elf_External_Verdef);
+ }
+ else
+ {
+ 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)
+ {
+ _bfd_elf_strtab_addref (elf_hash_table (info)->dynstr,
+ soname_indx);
+ def.vd_hash = bfd_elf_hash (soname);
+ defaux.vda_name = soname_indx;
+ name = soname;
+ }
+ else
+ {
+ bfd_size_type indx;
+
+ name = lbasename (output_bfd->filename);
+ def.vd_hash = bfd_elf_hash (name);
+ indx = _bfd_elf_strtab_add (elf_hash_table (info)->dynstr,
+ name, 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);
+ if (info->create_default_symver)
+ {
+ /* Add a symbol representing this version. */
+ bh = NULL;
+ if (! (_bfd_generic_link_add_one_symbol
+ (info, dynobj, name, BSF_GLOBAL, bfd_abs_section_ptr,
+ 0, NULL, FALSE,
+ get_elf_backend_data (dynobj)->collect, &bh)))
+ return FALSE;
+ h = (struct elf_link_hash_entry *) bh;
+ h->non_elf = 0;
+ h->def_regular = 1;
+ h->type = STT_OBJECT;
+ h->verinfo.vertree = NULL;
+
+ if (! bfd_elf_link_record_dynamic_symbol (info, h))
+ return FALSE;
+
+ /* Create a duplicate of the base version with the same
+ aux block, but different flags. */
+ def.vd_flags = 0;
+ def.vd_ndx = 2;
+ def.vd_aux = sizeof (Elf_External_Verdef);
+ if (verdefs)
+ def.vd_next = (sizeof (Elf_External_Verdef)
+ + 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);
+ }
+ _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;
+
+ /* Don't emit the base version twice. */
+ if (t->vernum == 0)
+ continue;
+
+ cdeps = 0;
+ for (n = t->deps; n != NULL; n = n->next)
+ ++cdeps;
+
+ /* Add a symbol representing this version. */
+ bh = NULL;
+ if (! (_bfd_generic_link_add_one_symbol
+ (info, dynobj, t->name, BSF_GLOBAL, bfd_abs_section_ptr,
+ 0, NULL, FALSE,
+ get_elf_backend_data (dynobj)->collect, &bh)))
+ return FALSE;
+ h = (struct elf_link_hash_entry *) bh;
+ h->non_elf = 0;
+ h->def_regular = 1;
+ 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.list == NULL
+ && t->locals.list == NULL
+ && ! t->used)
+ def.vd_flags |= VER_FLG_WEAK;
+ def.vd_ndx = t->vernum + (info->create_default_symver ? 2 : 1);
+ def.vd_cnt = cdeps + 1;
+ def.vd_hash = bfd_elf_hash (t->name);
+ def.vd_aux = sizeof (Elf_External_Verdef);
+ def.vd_next = 0;
+
+ /* If a basever node is next, it *must* be the last node in
+ the chain, otherwise Verdef construction breaks. */
+ if (t->next != NULL && t->next->vernum == 0)
+ BFD_ASSERT (t->next->next == NULL);
+
+ if (t->next != NULL && t->next->vernum != 0)
+ def.vd_next = (sizeof (Elf_External_Verdef)
+ + (cdeps + 1) * sizeof (Elf_External_Verdaux));
+
+ _bfd_elf_swap_verdef_out (output_bfd, &def,
+ (Elf_External_Verdef *) p);
+ p += sizeof (Elf_External_Verdef);
+
+ defaux.vda_name = h->dynstr_index;
+ _bfd_elf_strtab_addref (elf_hash_table (info)->dynstr,
+ h->dynstr_index);
+ defaux.vda_next = 0;
+ if (t->deps != NULL)
+ 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;
+ _bfd_elf_strtab_addref (elf_hash_table (info)->dynstr,
+ defaux.vda_name);
+ }
+ 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 (!_bfd_elf_add_dynamic_entry (info, DT_VERDEF, 0)
+ || !_bfd_elf_add_dynamic_entry (info, DT_VERDEFNUM, cdefs))
+ return FALSE;
+
+ elf_tdata (output_bfd)->cverdefs = cdefs;
+ }
+
+ if ((info->new_dtags && info->flags) || (info->flags & DF_STATIC_TLS))
+ {
+ if (!_bfd_elf_add_dynamic_entry (info, DT_FLAGS, info->flags))
+ return FALSE;
+ }
+ else if (info->flags & DF_BIND_NOW)
+ {
+ if (!_bfd_elf_add_dynamic_entry (info, DT_BIND_NOW, 0))
+ return FALSE;
+ }
+
+ if (info->flags_1)
+ {
+ if (info->executable)
+ info->flags_1 &= ~ (DF_1_INITFIRST
+ | DF_1_NODELETE
+ | DF_1_NOOPEN);
+ if (!_bfd_elf_add_dynamic_entry (info, DT_FLAGS_1, info->flags_1))
+ return FALSE;
+ }
+
+ /* Work out the size of the version reference section. */
+
+ s = bfd_get_linker_section (dynobj, ".gnu.version_r");
+ BFD_ASSERT (s != NULL);
+ {
+ struct elf_find_verdep_info sinfo;
+
+ 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),
+ _bfd_elf_link_find_version_dependencies,
+ &sinfo);
+ if (sinfo.failed)
+ return FALSE;
+
+ if (elf_tdata (output_bfd)->verref == NULL)
+ s->flags |= SEC_EXCLUDE;
+ else
+ {
+ Elf_Internal_Verneed *t;
+ unsigned int size;
+ unsigned int crefs;
+ bfd_byte *p;
+
+ /* Build the version dependency 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->size = size;
+ s->contents = (unsigned char *) bfd_alloc (output_bfd, s->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;
+ indx = _bfd_elf_strtab_add (elf_hash_table (info)->dynstr,
+ elf_dt_name (t->vn_bfd) != NULL
+ ? elf_dt_name (t->vn_bfd)
+ : lbasename (t->vn_bfd->filename),
+ 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 (a->vna_nodename);
+ indx = _bfd_elf_strtab_add (elf_hash_table (info)->dynstr,
+ a->vna_nodename, 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 (!_bfd_elf_add_dynamic_entry (info, DT_VERNEED, 0)
+ || !_bfd_elf_add_dynamic_entry (info, DT_VERNEEDNUM, crefs))
+ return FALSE;
+
+ elf_tdata (output_bfd)->cverrefs = crefs;
+ }
+ }
+
+ if ((elf_tdata (output_bfd)->cverrefs == 0
+ && elf_tdata (output_bfd)->cverdefs == 0)
+ || _bfd_elf_link_renumber_dynsyms (output_bfd, info,
+ &section_sym_count) == 0)
+ {
+ s = bfd_get_linker_section (dynobj, ".gnu.version");
+ s->flags |= SEC_EXCLUDE;
+ }
+ }
+ return TRUE;
+}
+
+/* Find the first non-excluded output section. We'll use its
+ section symbol for some emitted relocs. */
+void
+_bfd_elf_init_1_index_section (bfd *output_bfd, struct bfd_link_info *info)
+{
+ asection *s;
+
+ for (s = output_bfd->sections; s != NULL; s = s->next)
+ if ((s->flags & (SEC_EXCLUDE | SEC_ALLOC)) == SEC_ALLOC
+ && !_bfd_elf_link_omit_section_dynsym (output_bfd, info, s))
+ {
+ elf_hash_table (info)->text_index_section = s;
+ break;
+ }
+}
+
+/* Find two non-excluded output sections, one for code, one for data.
+ We'll use their section symbols for some emitted relocs. */
+void
+_bfd_elf_init_2_index_sections (bfd *output_bfd, struct bfd_link_info *info)
+{
+ asection *s;
+
+ /* Data first, since setting text_index_section changes
+ _bfd_elf_link_omit_section_dynsym. */
+ for (s = output_bfd->sections; s != NULL; s = s->next)
+ if (((s->flags & (SEC_EXCLUDE | SEC_ALLOC | SEC_READONLY)) == SEC_ALLOC)
+ && !_bfd_elf_link_omit_section_dynsym (output_bfd, info, s))
+ {
+ elf_hash_table (info)->data_index_section = s;
+ break;
+ }
+
+ for (s = output_bfd->sections; s != NULL; s = s->next)
+ if (((s->flags & (SEC_EXCLUDE | SEC_ALLOC | SEC_READONLY))
+ == (SEC_ALLOC | SEC_READONLY))
+ && !_bfd_elf_link_omit_section_dynsym (output_bfd, info, s))
+ {
+ elf_hash_table (info)->text_index_section = s;
+ break;
+ }
+
+ if (elf_hash_table (info)->text_index_section == NULL)
+ elf_hash_table (info)->text_index_section
+ = elf_hash_table (info)->data_index_section;
+}
+
+bfd_boolean
+bfd_elf_size_dynsym_hash_dynstr (bfd *output_bfd, struct bfd_link_info *info)
+{
+ const struct elf_backend_data *bed;
+
+ if (!is_elf_hash_table (info->hash))
+ return TRUE;
+
+ bed = get_elf_backend_data (output_bfd);
+ (*bed->elf_backend_init_index_section) (output_bfd, info);
+
+ if (elf_hash_table (info)->dynamic_sections_created)
+ {
+ bfd *dynobj;
+ asection *s;
+ bfd_size_type dynsymcount;
+ unsigned long section_sym_count;
+ unsigned int dtagcount;
+
+ dynobj = elf_hash_table (info)->dynobj;
+
+ /* Assign dynsym indicies. In a shared library we generate a
+ section symbol for each output section, which come first.
+ Next come all of the back-end allocated local dynamic syms,
+ followed by the rest of the global symbols. */
+
+ dynsymcount = _bfd_elf_link_renumber_dynsyms (output_bfd, info,
+ &section_sym_count);
+
+ /* Work out the size of the symbol version section. */
+ s = bfd_get_linker_section (dynobj, ".gnu.version");
+ BFD_ASSERT (s != NULL);
+ if (dynsymcount != 0
+ && (s->flags & SEC_EXCLUDE) == 0)
+ {
+ s->size = dynsymcount * sizeof (Elf_External_Versym);
+ s->contents = (unsigned char *) bfd_zalloc (output_bfd, s->size);
+ if (s->contents == NULL)
+ return FALSE;
+
+ if (!_bfd_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_linker_section (dynobj, ".dynsym");
+ BFD_ASSERT (s != NULL);
+ s->size = dynsymcount * bed->s->sizeof_sym;
+
+ if (dynsymcount != 0)
+ {
+ s->contents = (unsigned char *) bfd_alloc (output_bfd, s->size);
+ if (s->contents == NULL)
+ return FALSE;
+
+ /* The first entry in .dynsym is a dummy symbol.
+ Clear all the section syms, in case we don't output them all. */
+ ++section_sym_count;
+ memset (s->contents, 0, section_sym_count * bed->s->sizeof_sym);
+ }
+
+ elf_hash_table (info)->bucketcount = 0;
+
+ /* Compute the size of the hashing table. As a side effect this
+ computes the hash values for all the names we export. */
+ if (info->emit_hash)
+ {
+ unsigned long int *hashcodes;
+ struct hash_codes_info hashinf;
+ bfd_size_type amt;
+ unsigned long int nsyms;
+ size_t bucketcount;
+ size_t hash_entry_size;
+
+ /* 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. */
+ amt = dynsymcount * sizeof (unsigned long int);
+ hashcodes = (unsigned long int *) bfd_malloc (amt);
+ if (hashcodes == NULL)
+ return FALSE;
+ hashinf.hashcodes = hashcodes;
+ hashinf.error = FALSE;
+
+ /* Put all hash values in HASHCODES. */
+ elf_link_hash_traverse (elf_hash_table (info),
+ elf_collect_hash_codes, &hashinf);
+ if (hashinf.error)
+ {
+ free (hashcodes);
+ return FALSE;
+ }
+
+ nsyms = hashinf.hashcodes - hashcodes;
+ bucketcount
+ = compute_bucket_count (info, hashcodes, nsyms, 0);
+ free (hashcodes);
+
+ if (bucketcount == 0)
+ return FALSE;
+
+ elf_hash_table (info)->bucketcount = bucketcount;
+
+ s = bfd_get_linker_section (dynobj, ".hash");
+ BFD_ASSERT (s != NULL);
+ hash_entry_size = elf_section_data (s)->this_hdr.sh_entsize;
+ s->size = ((2 + bucketcount + dynsymcount) * hash_entry_size);
+ s->contents = (unsigned char *) bfd_zalloc (output_bfd, s->size);
+ if (s->contents == NULL)
+ return FALSE;
+
+ bfd_put (8 * hash_entry_size, output_bfd, bucketcount, s->contents);
+ bfd_put (8 * hash_entry_size, output_bfd, dynsymcount,
+ s->contents + hash_entry_size);
+ }
+
+ if (info->emit_gnu_hash)
+ {
+ size_t i, cnt;
+ unsigned char *contents;
+ struct collect_gnu_hash_codes cinfo;
+ bfd_size_type amt;
+ size_t bucketcount;
+
+ memset (&cinfo, 0, sizeof (cinfo));
+
+ /* 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. */
+ amt = dynsymcount * 2 * sizeof (unsigned long int);
+ cinfo.hashcodes = (long unsigned int *) bfd_malloc (amt);
+ if (cinfo.hashcodes == NULL)
+ return FALSE;
+
+ cinfo.hashval = cinfo.hashcodes + dynsymcount;
+ cinfo.min_dynindx = -1;
+ cinfo.output_bfd = output_bfd;
+ cinfo.bed = bed;
+
+ /* Put all hash values in HASHCODES. */
+ elf_link_hash_traverse (elf_hash_table (info),
+ elf_collect_gnu_hash_codes, &cinfo);
+ if (cinfo.error)
+ {
+ free (cinfo.hashcodes);
+ return FALSE;
+ }
+
+ bucketcount
+ = compute_bucket_count (info, cinfo.hashcodes, cinfo.nsyms, 1);
+
+ if (bucketcount == 0)
+ {
+ free (cinfo.hashcodes);
+ return FALSE;
+ }
+
+ s = bfd_get_linker_section (dynobj, ".gnu.hash");
+ BFD_ASSERT (s != NULL);
+
+ if (cinfo.nsyms == 0)
+ {
+ /* Empty .gnu.hash section is special. */
+ BFD_ASSERT (cinfo.min_dynindx == -1);
+ free (cinfo.hashcodes);
+ s->size = 5 * 4 + bed->s->arch_size / 8;
+ contents = (unsigned char *) bfd_zalloc (output_bfd, s->size);
+ if (contents == NULL)
+ return FALSE;
+ s->contents = contents;
+ /* 1 empty bucket. */
+ bfd_put_32 (output_bfd, 1, contents);
+ /* SYMIDX above the special symbol 0. */
+ bfd_put_32 (output_bfd, 1, contents + 4);
+ /* Just one word for bitmask. */
+ bfd_put_32 (output_bfd, 1, contents + 8);
+ /* Only hash fn bloom filter. */
+ bfd_put_32 (output_bfd, 0, contents + 12);
+ /* No hashes are valid - empty bitmask. */
+ bfd_put (bed->s->arch_size, output_bfd, 0, contents + 16);
+ /* No hashes in the only bucket. */
+ bfd_put_32 (output_bfd, 0,
+ contents + 16 + bed->s->arch_size / 8);
+ }
+ else
+ {
+ unsigned long int maskwords, maskbitslog2, x;
+ BFD_ASSERT (cinfo.min_dynindx != -1);
+
+ x = cinfo.nsyms;
+ maskbitslog2 = 1;
+ while ((x >>= 1) != 0)
+ ++maskbitslog2;
+ if (maskbitslog2 < 3)
+ maskbitslog2 = 5;
+ else if ((1 << (maskbitslog2 - 2)) & cinfo.nsyms)
+ maskbitslog2 = maskbitslog2 + 3;
+ else
+ maskbitslog2 = maskbitslog2 + 2;
+ if (bed->s->arch_size == 64)
+ {
+ if (maskbitslog2 == 5)
+ maskbitslog2 = 6;
+ cinfo.shift1 = 6;
+ }
+ else
+ cinfo.shift1 = 5;
+ cinfo.mask = (1 << cinfo.shift1) - 1;
+ cinfo.shift2 = maskbitslog2;
+ cinfo.maskbits = 1 << maskbitslog2;
+ maskwords = 1 << (maskbitslog2 - cinfo.shift1);
+ amt = bucketcount * sizeof (unsigned long int) * 2;
+ amt += maskwords * sizeof (bfd_vma);
+ cinfo.bitmask = (bfd_vma *) bfd_malloc (amt);
+ if (cinfo.bitmask == NULL)
+ {
+ free (cinfo.hashcodes);
+ return FALSE;
+ }
+
+ cinfo.counts = (long unsigned int *) (cinfo.bitmask + maskwords);
+ cinfo.indx = cinfo.counts + bucketcount;
+ cinfo.symindx = dynsymcount - cinfo.nsyms;
+ memset (cinfo.bitmask, 0, maskwords * sizeof (bfd_vma));
+
+ /* Determine how often each hash bucket is used. */
+ memset (cinfo.counts, 0, bucketcount * sizeof (cinfo.counts[0]));
+ for (i = 0; i < cinfo.nsyms; ++i)
+ ++cinfo.counts[cinfo.hashcodes[i] % bucketcount];
+
+ for (i = 0, cnt = cinfo.symindx; i < bucketcount; ++i)
+ if (cinfo.counts[i] != 0)
+ {
+ cinfo.indx[i] = cnt;
+ cnt += cinfo.counts[i];
+ }
+ BFD_ASSERT (cnt == dynsymcount);
+ cinfo.bucketcount = bucketcount;
+ cinfo.local_indx = cinfo.min_dynindx;
+
+ s->size = (4 + bucketcount + cinfo.nsyms) * 4;
+ s->size += cinfo.maskbits / 8;
+ contents = (unsigned char *) bfd_zalloc (output_bfd, s->size);
+ if (contents == NULL)
+ {
+ free (cinfo.bitmask);
+ free (cinfo.hashcodes);
+ return FALSE;
+ }
+
+ s->contents = contents;
+ bfd_put_32 (output_bfd, bucketcount, contents);
+ bfd_put_32 (output_bfd, cinfo.symindx, contents + 4);
+ bfd_put_32 (output_bfd, maskwords, contents + 8);
+ bfd_put_32 (output_bfd, cinfo.shift2, contents + 12);
+ contents += 16 + cinfo.maskbits / 8;
+
+ for (i = 0; i < bucketcount; ++i)
+ {
+ if (cinfo.counts[i] == 0)
+ bfd_put_32 (output_bfd, 0, contents);
+ else
+ bfd_put_32 (output_bfd, cinfo.indx[i], contents);
+ contents += 4;
+ }
+
+ cinfo.contents = contents;
+
+ /* Renumber dynamic symbols, populate .gnu.hash section. */
+ elf_link_hash_traverse (elf_hash_table (info),
+ elf_renumber_gnu_hash_syms, &cinfo);
+
+ contents = s->contents + 16;
+ for (i = 0; i < maskwords; ++i)
+ {
+ bfd_put (bed->s->arch_size, output_bfd, cinfo.bitmask[i],
+ contents);
+ contents += bed->s->arch_size / 8;
+ }
+
+ free (cinfo.bitmask);
+ free (cinfo.hashcodes);
+ }
+ }
+
+ s = bfd_get_linker_section (dynobj, ".dynstr");
+ BFD_ASSERT (s != NULL);
+
+ elf_finalize_dynstr (output_bfd, info);
+
+ s->size = _bfd_elf_strtab_size (elf_hash_table (info)->dynstr);
+
+ for (dtagcount = 0; dtagcount <= info->spare_dynamic_tags; ++dtagcount)
+ if (!_bfd_elf_add_dynamic_entry (info, DT_NULL, 0))
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/* Make sure sec_info_type is cleared if sec_info is cleared too. */
+
+static void
+merge_sections_remove_hook (bfd *abfd ATTRIBUTE_UNUSED,
+ asection *sec)
+{
+ BFD_ASSERT (sec->sec_info_type == SEC_INFO_TYPE_MERGE);
+ sec->sec_info_type = SEC_INFO_TYPE_NONE;
+}
+
+/* Finish SHF_MERGE section merging. */
+
+bfd_boolean
+_bfd_elf_merge_sections (bfd *abfd, struct bfd_link_info *info)
+{
+ bfd *ibfd;
+ asection *sec;
+
+ if (!is_elf_hash_table (info->hash))
+ return FALSE;
+
+ for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next)
+ if ((ibfd->flags & DYNAMIC) == 0)
+ for (sec = ibfd->sections; sec != NULL; sec = sec->next)
+ if ((sec->flags & SEC_MERGE) != 0
+ && !bfd_is_abs_section (sec->output_section))
+ {
+ struct bfd_elf_section_data *secdata;
+
+ secdata = elf_section_data (sec);
+ if (! _bfd_add_merge_section (abfd,
+ &elf_hash_table (info)->merge_info,
+ sec, &secdata->sec_info))
+ return FALSE;
+ else if (secdata->sec_info)
+ sec->sec_info_type = SEC_INFO_TYPE_MERGE;
+ }
+
+ if (elf_hash_table (info)->merge_info != NULL)
+ _bfd_merge_sections (abfd, info, elf_hash_table (info)->merge_info,
+ merge_sections_remove_hook);
+ return TRUE;
+}
+
+/* Create an entry in an ELF linker hash table. */
+
+struct bfd_hash_entry *
+_bfd_elf_link_hash_newfunc (struct bfd_hash_entry *entry,
+ struct bfd_hash_table *table,
+ const char *string)
+{
+ /* Allocate the structure if it has not already been allocated by a
+ subclass. */
+ if (entry == NULL)
+ {
+ entry = (struct bfd_hash_entry *)
+ bfd_hash_allocate (table, sizeof (struct elf_link_hash_entry));
+ if (entry == NULL)
+ return entry;
+ }
+
+ /* Call the allocation method of the superclass. */
+ entry = _bfd_link_hash_newfunc (entry, table, string);
+ if (entry != NULL)
+ {
+ struct elf_link_hash_entry *ret = (struct elf_link_hash_entry *) entry;
+ struct elf_link_hash_table *htab = (struct elf_link_hash_table *) table;
+
+ /* Set local fields. */
+ ret->indx = -1;
+ ret->dynindx = -1;
+ ret->got = htab->init_got_refcount;
+ ret->plt = htab->init_plt_refcount;
+ memset (&ret->size, 0, (sizeof (struct elf_link_hash_entry)
+ - offsetof (struct elf_link_hash_entry, size)));
+ /* 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->non_elf = 1;
+ }
+
+ return entry;
+}
+
+/* Copy data from an indirect symbol to its direct symbol, hiding the
+ old indirect symbol. Also used for copying flags to a weakdef. */
+
+void
+_bfd_elf_link_hash_copy_indirect (struct bfd_link_info *info,
+ struct elf_link_hash_entry *dir,
+ struct elf_link_hash_entry *ind)
+{
+ struct elf_link_hash_table *htab;
+
+ /* Copy down any references that we may have already seen to the
+ symbol which just became indirect. */
+
+ dir->ref_dynamic |= ind->ref_dynamic;
+ dir->ref_regular |= ind->ref_regular;
+ dir->ref_regular_nonweak |= ind->ref_regular_nonweak;
+ dir->non_got_ref |= ind->non_got_ref;
+ dir->needs_plt |= ind->needs_plt;
+ dir->pointer_equality_needed |= ind->pointer_equality_needed;
+
+ if (ind->root.type != bfd_link_hash_indirect)
+ return;
+
+ /* Copy over the global and procedure linkage table refcount entries.
+ These may have been already set up by a check_relocs routine. */
+ htab = elf_hash_table (info);
+ if (ind->got.refcount > htab->init_got_refcount.refcount)
+ {
+ if (dir->got.refcount < 0)
+ dir->got.refcount = 0;
+ dir->got.refcount += ind->got.refcount;
+ ind->got.refcount = htab->init_got_refcount.refcount;
+ }
+
+ if (ind->plt.refcount > htab->init_plt_refcount.refcount)
+ {
+ if (dir->plt.refcount < 0)
+ dir->plt.refcount = 0;
+ dir->plt.refcount += ind->plt.refcount;
+ ind->plt.refcount = htab->init_plt_refcount.refcount;
+ }
+
+ if (ind->dynindx != -1)
+ {
+ if (dir->dynindx != -1)
+ _bfd_elf_strtab_delref (htab->dynstr, dir->dynstr_index);
+ dir->dynindx = ind->dynindx;
+ dir->dynstr_index = ind->dynstr_index;
+ ind->dynindx = -1;
+ ind->dynstr_index = 0;
+ }
+}
+
+void
+_bfd_elf_link_hash_hide_symbol (struct bfd_link_info *info,
+ struct elf_link_hash_entry *h,
+ bfd_boolean force_local)
+{
+ /* STT_GNU_IFUNC symbol must go through PLT. */
+ if (h->type != STT_GNU_IFUNC)
+ {
+ h->plt = elf_hash_table (info)->init_plt_offset;
+ h->needs_plt = 0;
+ }
+ if (force_local)
+ {
+ h->forced_local = 1;
+ if (h->dynindx != -1)
+ {
+ h->dynindx = -1;
+ _bfd_elf_strtab_delref (elf_hash_table (info)->dynstr,
+ h->dynstr_index);
+ }
+ }
+}
+
+/* Initialize an ELF linker hash table. *TABLE has been zeroed by our
+ caller. */
+
+bfd_boolean
+_bfd_elf_link_hash_table_init
+ (struct elf_link_hash_table *table,
+ bfd *abfd,
+ struct bfd_hash_entry *(*newfunc) (struct bfd_hash_entry *,
+ struct bfd_hash_table *,
+ const char *),
+ unsigned int entsize,
+ enum elf_target_id target_id)
+{
+ bfd_boolean ret;
+ int can_refcount = get_elf_backend_data (abfd)->can_refcount;
+
+ table->init_got_refcount.refcount = can_refcount - 1;
+ table->init_plt_refcount.refcount = can_refcount - 1;
+ table->init_got_offset.offset = -(bfd_vma) 1;
+ table->init_plt_offset.offset = -(bfd_vma) 1;
+ /* The first dynamic symbol is a dummy. */
+ table->dynsymcount = 1;
+
+ ret = _bfd_link_hash_table_init (&table->root, abfd, newfunc, entsize);
+
+ table->root.type = bfd_link_elf_hash_table;
+ table->hash_table_id = target_id;
+
+ return ret;
+}
+
+/* Create an ELF linker hash table. */
+
+struct bfd_link_hash_table *
+_bfd_elf_link_hash_table_create (bfd *abfd)
+{
+ struct elf_link_hash_table *ret;
+ bfd_size_type amt = sizeof (struct elf_link_hash_table);
+
+ ret = (struct elf_link_hash_table *) bfd_zmalloc (amt);
+ if (ret == NULL)
+ return NULL;
+
+ if (! _bfd_elf_link_hash_table_init (ret, abfd, _bfd_elf_link_hash_newfunc,
+ sizeof (struct elf_link_hash_entry),
+ GENERIC_ELF_DATA))
+ {
+ free (ret);
+ return NULL;
+ }
+ ret->root.hash_table_free = _bfd_elf_link_hash_table_free;
+
+ return &ret->root;
+}
+
+/* Destroy an ELF linker hash table. */
+
+void
+_bfd_elf_link_hash_table_free (bfd *obfd)
+{
+ struct elf_link_hash_table *htab;
+
+ htab = (struct elf_link_hash_table *) obfd->link.hash;
+ if (htab->dynstr != NULL)
+ _bfd_elf_strtab_free (htab->dynstr);
+ _bfd_merge_sections_free (htab->merge_info);
+ _bfd_generic_link_hash_table_free (obfd);
+}
+
+/* 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. */
+
+void
+bfd_elf_set_dt_needed_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;
+}
+
+int
+bfd_elf_get_dyn_lib_class (bfd *abfd)
+{
+ int lib_class;
+ if (bfd_get_flavour (abfd) == bfd_target_elf_flavour
+ && bfd_get_format (abfd) == bfd_object)
+ lib_class = elf_dyn_lib_class (abfd);
+ else
+ lib_class = 0;
+ return lib_class;
+}
+
+void
+bfd_elf_set_dyn_lib_class (bfd *abfd, enum dynamic_lib_link_class lib_class)
+{
+ if (bfd_get_flavour (abfd) == bfd_target_elf_flavour
+ && bfd_get_format (abfd) == bfd_object)
+ elf_dyn_lib_class (abfd) = lib_class;
+}
+
+/* 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 (bfd *abfd ATTRIBUTE_UNUSED,
+ struct bfd_link_info *info)
+{
+ if (! is_elf_hash_table (info->hash))
+ return NULL;
+ return elf_hash_table (info)->needed;
+}
+
+/* Get the list of DT_RPATH/DT_RUNPATH entries for a link. This is a
+ hook for the linker ELF emulation code. */
+
+struct bfd_link_needed_list *
+bfd_elf_get_runpath_list (bfd *abfd ATTRIBUTE_UNUSED,
+ struct bfd_link_info *info)
+{
+ if (! is_elf_hash_table (info->hash))
+ return NULL;
+ return elf_hash_table (info)->runpath;
+}
+
+/* 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 (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. */
+
+bfd_boolean
+bfd_elf_get_bfd_needed_list (bfd *abfd,
+ struct bfd_link_needed_list **pneeded)
+{
+ asection *s;
+ bfd_byte *dynbuf = NULL;
+ unsigned int elfsec;
+ unsigned long shlink;
+ bfd_byte *extdyn, *extdynend;
+ size_t extdynsize;
+ void (*swap_dyn_in) (bfd *, const void *, 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->size == 0)
+ return TRUE;
+
+ if (!bfd_malloc_and_get_section (abfd, s, &dynbuf))
+ goto error_return;
+
+ elfsec = _bfd_elf_section_from_bfd_section (abfd, s);
+ if (elfsec == SHN_BAD)
+ goto error_return;
+
+ shlink = 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->size;
+ for (; extdyn < extdynend; extdyn += extdynsize)
+ {
+ Elf_Internal_Dyn dyn;
+
+ (*swap_dyn_in) (abfd, extdyn, &dyn);
+
+ if (dyn.d_tag == DT_NULL)
+ break;
+
+ if (dyn.d_tag == DT_NEEDED)
+ {
+ const char *string;
+ struct bfd_link_needed_list *l;
+ unsigned int tagv = dyn.d_un.d_val;
+ bfd_size_type amt;
+
+ string = bfd_elf_string_from_elf_section (abfd, shlink, tagv);
+ if (string == NULL)
+ goto error_return;
+
+ amt = sizeof *l;
+ l = (struct bfd_link_needed_list *) bfd_alloc (abfd, amt);
+ 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;
+}
+
+struct elf_symbuf_symbol
+{
+ unsigned long st_name; /* Symbol name, index in string tbl */
+ unsigned char st_info; /* Type and binding attributes */
+ unsigned char st_other; /* Visibilty, and target specific */
+};
+
+struct elf_symbuf_head
+{
+ struct elf_symbuf_symbol *ssym;
+ bfd_size_type count;
+ unsigned int st_shndx;
+};
+
+struct elf_symbol
+{
+ union
+ {
+ Elf_Internal_Sym *isym;
+ struct elf_symbuf_symbol *ssym;
+ } u;
+ const char *name;
+};
+
+/* Sort references to symbols by ascending section number. */
+
+static int
+elf_sort_elf_symbol (const void *arg1, const void *arg2)
+{
+ const Elf_Internal_Sym *s1 = *(const Elf_Internal_Sym **) arg1;
+ const Elf_Internal_Sym *s2 = *(const Elf_Internal_Sym **) arg2;
+
+ return s1->st_shndx - s2->st_shndx;
+}
+
+static int
+elf_sym_name_compare (const void *arg1, const void *arg2)
+{
+ const struct elf_symbol *s1 = (const struct elf_symbol *) arg1;
+ const struct elf_symbol *s2 = (const struct elf_symbol *) arg2;
+ return strcmp (s1->name, s2->name);
+}
+
+static struct elf_symbuf_head *
+elf_create_symbuf (bfd_size_type symcount, Elf_Internal_Sym *isymbuf)
+{
+ Elf_Internal_Sym **ind, **indbufend, **indbuf;
+ struct elf_symbuf_symbol *ssym;
+ struct elf_symbuf_head *ssymbuf, *ssymhead;
+ bfd_size_type i, shndx_count, total_size;
+
+ indbuf = (Elf_Internal_Sym **) bfd_malloc2 (symcount, sizeof (*indbuf));
+ if (indbuf == NULL)
+ return NULL;
+
+ for (ind = indbuf, i = 0; i < symcount; i++)
+ if (isymbuf[i].st_shndx != SHN_UNDEF)
+ *ind++ = &isymbuf[i];
+ indbufend = ind;
+
+ qsort (indbuf, indbufend - indbuf, sizeof (Elf_Internal_Sym *),
+ elf_sort_elf_symbol);
+
+ shndx_count = 0;
+ if (indbufend > indbuf)
+ for (ind = indbuf, shndx_count++; ind < indbufend - 1; ind++)
+ if (ind[0]->st_shndx != ind[1]->st_shndx)
+ shndx_count++;
+
+ total_size = ((shndx_count + 1) * sizeof (*ssymbuf)
+ + (indbufend - indbuf) * sizeof (*ssym));
+ ssymbuf = (struct elf_symbuf_head *) bfd_malloc (total_size);
+ if (ssymbuf == NULL)
+ {
+ free (indbuf);
+ return NULL;
+ }
+
+ ssym = (struct elf_symbuf_symbol *) (ssymbuf + shndx_count + 1);
+ ssymbuf->ssym = NULL;
+ ssymbuf->count = shndx_count;
+ ssymbuf->st_shndx = 0;
+ for (ssymhead = ssymbuf, ind = indbuf; ind < indbufend; ssym++, ind++)
+ {
+ if (ind == indbuf || ssymhead->st_shndx != (*ind)->st_shndx)
+ {
+ ssymhead++;
+ ssymhead->ssym = ssym;
+ ssymhead->count = 0;
+ ssymhead->st_shndx = (*ind)->st_shndx;
+ }
+ ssym->st_name = (*ind)->st_name;
+ ssym->st_info = (*ind)->st_info;
+ ssym->st_other = (*ind)->st_other;
+ ssymhead->count++;
+ }
+ BFD_ASSERT ((bfd_size_type) (ssymhead - ssymbuf) == shndx_count
+ && (((bfd_hostptr_t) ssym - (bfd_hostptr_t) ssymbuf)
+ == total_size));
+
+ free (indbuf);
+ return ssymbuf;
+}
+
+/* Check if 2 sections define the same set of local and global
+ symbols. */
+
+static bfd_boolean
+bfd_elf_match_symbols_in_sections (asection *sec1, asection *sec2,
+ struct bfd_link_info *info)
+{
+ bfd *bfd1, *bfd2;
+ const struct elf_backend_data *bed1, *bed2;
+ Elf_Internal_Shdr *hdr1, *hdr2;
+ bfd_size_type symcount1, symcount2;
+ Elf_Internal_Sym *isymbuf1, *isymbuf2;
+ struct elf_symbuf_head *ssymbuf1, *ssymbuf2;
+ Elf_Internal_Sym *isym, *isymend;
+ struct elf_symbol *symtable1 = NULL, *symtable2 = NULL;
+ bfd_size_type count1, count2, i;
+ unsigned int shndx1, shndx2;
+ bfd_boolean result;
+
+ bfd1 = sec1->owner;
+ bfd2 = sec2->owner;
+
+ /* Both sections have to be in ELF. */
+ if (bfd_get_flavour (bfd1) != bfd_target_elf_flavour
+ || bfd_get_flavour (bfd2) != bfd_target_elf_flavour)
+ return FALSE;
+
+ if (elf_section_type (sec1) != elf_section_type (sec2))
+ return FALSE;
+
+ shndx1 = _bfd_elf_section_from_bfd_section (bfd1, sec1);
+ shndx2 = _bfd_elf_section_from_bfd_section (bfd2, sec2);
+ if (shndx1 == SHN_BAD || shndx2 == SHN_BAD)
+ return FALSE;
+
+ bed1 = get_elf_backend_data (bfd1);
+ bed2 = get_elf_backend_data (bfd2);
+ hdr1 = &elf_tdata (bfd1)->symtab_hdr;
+ symcount1 = hdr1->sh_size / bed1->s->sizeof_sym;
+ hdr2 = &elf_tdata (bfd2)->symtab_hdr;
+ symcount2 = hdr2->sh_size / bed2->s->sizeof_sym;
+
+ if (symcount1 == 0 || symcount2 == 0)
+ return FALSE;
+
+ result = FALSE;
+ isymbuf1 = NULL;
+ isymbuf2 = NULL;
+ ssymbuf1 = (struct elf_symbuf_head *) elf_tdata (bfd1)->symbuf;
+ ssymbuf2 = (struct elf_symbuf_head *) elf_tdata (bfd2)->symbuf;
+
+ if (ssymbuf1 == NULL)
+ {
+ isymbuf1 = bfd_elf_get_elf_syms (bfd1, hdr1, symcount1, 0,
+ NULL, NULL, NULL);
+ if (isymbuf1 == NULL)
+ goto done;
+
+ if (!info->reduce_memory_overheads)
+ elf_tdata (bfd1)->symbuf = ssymbuf1
+ = elf_create_symbuf (symcount1, isymbuf1);
+ }
+
+ if (ssymbuf1 == NULL || ssymbuf2 == NULL)
+ {
+ isymbuf2 = bfd_elf_get_elf_syms (bfd2, hdr2, symcount2, 0,
+ NULL, NULL, NULL);
+ if (isymbuf2 == NULL)
+ goto done;
+
+ if (ssymbuf1 != NULL && !info->reduce_memory_overheads)
+ elf_tdata (bfd2)->symbuf = ssymbuf2
+ = elf_create_symbuf (symcount2, isymbuf2);
+ }
+
+ if (ssymbuf1 != NULL && ssymbuf2 != NULL)
+ {
+ /* Optimized faster version. */
+ bfd_size_type lo, hi, mid;
+ struct elf_symbol *symp;
+ struct elf_symbuf_symbol *ssym, *ssymend;
+
+ lo = 0;
+ hi = ssymbuf1->count;
+ ssymbuf1++;
+ count1 = 0;
+ while (lo < hi)
+ {
+ mid = (lo + hi) / 2;
+ if (shndx1 < ssymbuf1[mid].st_shndx)
+ hi = mid;
+ else if (shndx1 > ssymbuf1[mid].st_shndx)
+ lo = mid + 1;
+ else
+ {
+ count1 = ssymbuf1[mid].count;
+ ssymbuf1 += mid;
+ break;
+ }
+ }
+
+ lo = 0;
+ hi = ssymbuf2->count;
+ ssymbuf2++;
+ count2 = 0;
+ while (lo < hi)
+ {
+ mid = (lo + hi) / 2;
+ if (shndx2 < ssymbuf2[mid].st_shndx)
+ hi = mid;
+ else if (shndx2 > ssymbuf2[mid].st_shndx)
+ lo = mid + 1;
+ else
+ {
+ count2 = ssymbuf2[mid].count;
+ ssymbuf2 += mid;
+ break;
+ }
+ }
+
+ if (count1 == 0 || count2 == 0 || count1 != count2)
+ goto done;
+
+ symtable1 = (struct elf_symbol *)
+ bfd_malloc (count1 * sizeof (struct elf_symbol));
+ symtable2 = (struct elf_symbol *)
+ bfd_malloc (count2 * sizeof (struct elf_symbol));
+ if (symtable1 == NULL || symtable2 == NULL)
+ goto done;
+
+ symp = symtable1;
+ for (ssym = ssymbuf1->ssym, ssymend = ssym + count1;
+ ssym < ssymend; ssym++, symp++)
+ {
+ symp->u.ssym = ssym;
+ symp->name = bfd_elf_string_from_elf_section (bfd1,
+ hdr1->sh_link,
+ ssym->st_name);
+ }
+
+ symp = symtable2;
+ for (ssym = ssymbuf2->ssym, ssymend = ssym + count2;
+ ssym < ssymend; ssym++, symp++)
+ {
+ symp->u.ssym = ssym;
+ symp->name = bfd_elf_string_from_elf_section (bfd2,
+ hdr2->sh_link,
+ ssym->st_name);
+ }
+
+ /* Sort symbol by name. */
+ qsort (symtable1, count1, sizeof (struct elf_symbol),
+ elf_sym_name_compare);
+ qsort (symtable2, count1, sizeof (struct elf_symbol),
+ elf_sym_name_compare);
+
+ for (i = 0; i < count1; i++)
+ /* Two symbols must have the same binding, type and name. */
+ if (symtable1 [i].u.ssym->st_info != symtable2 [i].u.ssym->st_info
+ || symtable1 [i].u.ssym->st_other != symtable2 [i].u.ssym->st_other
+ || strcmp (symtable1 [i].name, symtable2 [i].name) != 0)
+ goto done;
+
+ result = TRUE;
+ goto done;
+ }
+
+ symtable1 = (struct elf_symbol *)
+ bfd_malloc (symcount1 * sizeof (struct elf_symbol));
+ symtable2 = (struct elf_symbol *)
+ bfd_malloc (symcount2 * sizeof (struct elf_symbol));
+ if (symtable1 == NULL || symtable2 == NULL)
+ goto done;
+
+ /* Count definitions in the section. */
+ count1 = 0;
+ for (isym = isymbuf1, isymend = isym + symcount1; isym < isymend; isym++)
+ if (isym->st_shndx == shndx1)
+ symtable1[count1++].u.isym = isym;
+
+ count2 = 0;
+ for (isym = isymbuf2, isymend = isym + symcount2; isym < isymend; isym++)
+ if (isym->st_shndx == shndx2)
+ symtable2[count2++].u.isym = isym;
+
+ if (count1 == 0 || count2 == 0 || count1 != count2)
+ goto done;
+
+ for (i = 0; i < count1; i++)
+ symtable1[i].name
+ = bfd_elf_string_from_elf_section (bfd1, hdr1->sh_link,
+ symtable1[i].u.isym->st_name);
+
+ for (i = 0; i < count2; i++)
+ symtable2[i].name
+ = bfd_elf_string_from_elf_section (bfd2, hdr2->sh_link,
+ symtable2[i].u.isym->st_name);
+
+ /* Sort symbol by name. */
+ qsort (symtable1, count1, sizeof (struct elf_symbol),
+ elf_sym_name_compare);
+ qsort (symtable2, count1, sizeof (struct elf_symbol),
+ elf_sym_name_compare);
+
+ for (i = 0; i < count1; i++)
+ /* Two symbols must have the same binding, type and name. */
+ if (symtable1 [i].u.isym->st_info != symtable2 [i].u.isym->st_info
+ || symtable1 [i].u.isym->st_other != symtable2 [i].u.isym->st_other
+ || strcmp (symtable1 [i].name, symtable2 [i].name) != 0)
+ goto done;
+
+ result = TRUE;
+
+done:
+ if (symtable1)
+ free (symtable1);
+ if (symtable2)
+ free (symtable2);
+ if (isymbuf1)
+ free (isymbuf1);
+ if (isymbuf2)
+ free (isymbuf2);
+
+ return result;
+}
+
+/* Return TRUE if 2 section types are compatible. */
+
+bfd_boolean
+_bfd_elf_match_sections_by_type (bfd *abfd, const asection *asec,
+ bfd *bbfd, const asection *bsec)
+{
+ if (asec == NULL
+ || bsec == NULL
+ || abfd->xvec->flavour != bfd_target_elf_flavour
+ || bbfd->xvec->flavour != bfd_target_elf_flavour)
+ return TRUE;
+
+ return elf_section_type (asec) == elf_section_type (bsec);
+}
+
+/* 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. */
+ void *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. */
+ bfd_byte *external_syms;
+ /* And a buffer for symbol section indices. */
+ Elf_External_Sym_Shndx *locsym_shndx;
+ /* 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. */
+ bfd_byte *symbuf;
+ /* And one for symbol section indices. */
+ Elf_External_Sym_Shndx *symshndxbuf;
+ /* Number of swapped out symbols in buffer. */
+ size_t symbuf_count;
+ /* Number of symbols which fit in symbuf. */
+ size_t symbuf_size;
+ /* And same for symshndxbuf. */
+ size_t shndxbuf_size;
+ /* Number of STT_FILE syms seen. */
+ size_t filesym_count;
+};
+
+/* This struct is used to pass information to elf_link_output_extsym. */
+
+struct elf_outext_info
+{
+ bfd_boolean failed;
+ bfd_boolean localsyms;
+ bfd_boolean need_second_pass;
+ bfd_boolean second_pass;
+ bfd_boolean file_sym_done;
+ struct elf_final_link_info *flinfo;
+};
+
+
+/* Support for evaluating a complex relocation.
+
+ Complex relocations are generalized, self-describing relocations. The
+ implementation of them consists of two parts: complex symbols, and the
+ relocations themselves.
+
+ The relocations are use a reserved elf-wide relocation type code (R_RELC
+ external / BFD_RELOC_RELC internal) and an encoding of relocation field
+ information (start bit, end bit, word width, etc) into the addend. This
+ information is extracted from CGEN-generated operand tables within gas.
+
+ Complex symbols are mangled symbols (BSF_RELC external / STT_RELC
+ internal) representing prefix-notation expressions, including but not
+ limited to those sorts of expressions normally encoded as addends in the
+ addend field. The symbol mangling format is:
+
+ <node> := <literal>
+ | <unary-operator> ':' <node>
+ | <binary-operator> ':' <node> ':' <node>
+ ;
+
+ <literal> := 's' <digits=N> ':' <N character symbol name>
+ | 'S' <digits=N> ':' <N character section name>
+ | '#' <hexdigits>
+ ;
+
+ <binary-operator> := as in C
+ <unary-operator> := as in C, plus "0-" for unambiguous negation. */
+
+static void
+set_symbol_value (bfd *bfd_with_globals,
+ Elf_Internal_Sym *isymbuf,
+ size_t locsymcount,
+ size_t symidx,
+ bfd_vma val)
+{
+ struct elf_link_hash_entry **sym_hashes;
+ struct elf_link_hash_entry *h;
+ size_t extsymoff = locsymcount;
+
+ if (symidx < locsymcount)
+ {
+ Elf_Internal_Sym *sym;
+
+ sym = isymbuf + symidx;
+ if (ELF_ST_BIND (sym->st_info) == STB_LOCAL)
+ {
+ /* It is a local symbol: move it to the
+ "absolute" section and give it a value. */
+ sym->st_shndx = SHN_ABS;
+ sym->st_value = val;
+ return;
+ }
+ BFD_ASSERT (elf_bad_symtab (bfd_with_globals));
+ extsymoff = 0;
+ }
+
+ /* It is a global symbol: set its link type
+ to "defined" and give it a value. */
+
+ sym_hashes = elf_sym_hashes (bfd_with_globals);
+ h = sym_hashes [symidx - extsymoff];
+ 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;
+ h->root.type = bfd_link_hash_defined;
+ h->root.u.def.value = val;
+ h->root.u.def.section = bfd_abs_section_ptr;
+}
+
+static bfd_boolean
+resolve_symbol (const char *name,
+ bfd *input_bfd,
+ struct elf_final_link_info *flinfo,
+ bfd_vma *result,
+ Elf_Internal_Sym *isymbuf,
+ size_t locsymcount)
+{
+ Elf_Internal_Sym *sym;
+ struct bfd_link_hash_entry *global_entry;
+ const char *candidate = NULL;
+ Elf_Internal_Shdr *symtab_hdr;
+ size_t i;
+
+ symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
+
+ for (i = 0; i < locsymcount; ++ i)
+ {
+ sym = isymbuf + i;
+
+ if (ELF_ST_BIND (sym->st_info) != STB_LOCAL)
+ continue;
+
+ candidate = bfd_elf_string_from_elf_section (input_bfd,
+ symtab_hdr->sh_link,
+ sym->st_name);
+#ifdef DEBUG
+ printf ("Comparing string: '%s' vs. '%s' = 0x%lx\n",
+ name, candidate, (unsigned long) sym->st_value);
+#endif
+ if (candidate && strcmp (candidate, name) == 0)
+ {
+ asection *sec = flinfo->sections [i];
+
+ *result = _bfd_elf_rel_local_sym (input_bfd, sym, &sec, 0);
+ *result += sec->output_offset + sec->output_section->vma;
+#ifdef DEBUG
+ printf ("Found symbol with value %8.8lx\n",
+ (unsigned long) *result);
+#endif
+ return TRUE;
+ }
+ }
+
+ /* Hmm, haven't found it yet. perhaps it is a global. */
+ global_entry = bfd_link_hash_lookup (flinfo->info->hash, name,
+ FALSE, FALSE, TRUE);
+ if (!global_entry)
+ return FALSE;
+
+ if (global_entry->type == bfd_link_hash_defined
+ || global_entry->type == bfd_link_hash_defweak)
+ {
+ *result = (global_entry->u.def.value
+ + global_entry->u.def.section->output_section->vma
+ + global_entry->u.def.section->output_offset);
+#ifdef DEBUG
+ printf ("Found GLOBAL symbol '%s' with value %8.8lx\n",
+ global_entry->root.string, (unsigned long) *result);
+#endif
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static bfd_boolean
+resolve_section (const char *name,
+ asection *sections,
+ bfd_vma *result)
+{
+ asection *curr;
+ unsigned int len;
+
+ for (curr = sections; curr; curr = curr->next)
+ if (strcmp (curr->name, name) == 0)
+ {
+ *result = curr->vma;
+ return TRUE;
+ }
+
+ /* Hmm. still haven't found it. try pseudo-section names. */
+ for (curr = sections; curr; curr = curr->next)
+ {
+ len = strlen (curr->name);
+ if (len > strlen (name))
+ continue;
+
+ if (strncmp (curr->name, name, len) == 0)
+ {
+ if (strncmp (".end", name + len, 4) == 0)
+ {
+ *result = curr->vma + curr->size;
+ return TRUE;
+ }
+
+ /* Insert more pseudo-section names here, if you like. */
+ }
+ }
+
+ return FALSE;
+}
+
+static void
+undefined_reference (const char *reftype, const char *name)
+{
+ _bfd_error_handler (_("undefined %s reference in complex symbol: %s"),
+ reftype, name);
+}
+
+static bfd_boolean
+eval_symbol (bfd_vma *result,
+ const char **symp,
+ bfd *input_bfd,
+ struct elf_final_link_info *flinfo,
+ bfd_vma dot,
+ Elf_Internal_Sym *isymbuf,
+ size_t locsymcount,
+ int signed_p)
+{
+ size_t len;
+ size_t symlen;
+ bfd_vma a;
+ bfd_vma b;
+ char symbuf[4096];
+ const char *sym = *symp;
+ const char *symend;
+ bfd_boolean symbol_is_section = FALSE;
+
+ len = strlen (sym);
+ symend = sym + len;
+
+ if (len < 1 || len > sizeof (symbuf))
+ {
+ bfd_set_error (bfd_error_invalid_operation);
+ return FALSE;
+ }
+
+ switch (* sym)
+ {
+ case '.':
+ *result = dot;
+ *symp = sym + 1;
+ return TRUE;
+
+ case '#':
+ ++sym;
+ *result = strtoul (sym, (char **) symp, 16);
+ return TRUE;
+
+ case 'S':
+ symbol_is_section = TRUE;
+ case 's':
+ ++sym;
+ symlen = strtol (sym, (char **) symp, 10);
+ sym = *symp + 1; /* Skip the trailing ':'. */
+
+ if (symend < sym || symlen + 1 > sizeof (symbuf))
+ {
+ bfd_set_error (bfd_error_invalid_operation);
+ return FALSE;
+ }
+
+ memcpy (symbuf, sym, symlen);
+ symbuf[symlen] = '\0';
+ *symp = sym + symlen;
+
+ /* Is it always possible, with complex symbols, that gas "mis-guessed"
+ the symbol as a section, or vice-versa. so we're pretty liberal in our
+ interpretation here; section means "try section first", not "must be a
+ section", and likewise with symbol. */
+
+ if (symbol_is_section)
+ {
+ if (!resolve_section (symbuf, flinfo->output_bfd->sections, result)
+ && !resolve_symbol (symbuf, input_bfd, flinfo, result,
+ isymbuf, locsymcount))
+ {
+ undefined_reference ("section", symbuf);
+ return FALSE;
+ }
+ }
+ else
+ {
+ if (!resolve_symbol (symbuf, input_bfd, flinfo, result,
+ isymbuf, locsymcount)
+ && !resolve_section (symbuf, flinfo->output_bfd->sections,
+ result))
+ {
+ undefined_reference ("symbol", symbuf);
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+
+ /* All that remains are operators. */
+
+#define UNARY_OP(op) \
+ if (strncmp (sym, #op, strlen (#op)) == 0) \
+ { \
+ sym += strlen (#op); \
+ if (*sym == ':') \
+ ++sym; \
+ *symp = sym; \
+ if (!eval_symbol (&a, symp, input_bfd, flinfo, dot, \
+ isymbuf, locsymcount, signed_p)) \
+ return FALSE; \
+ if (signed_p) \
+ *result = op ((bfd_signed_vma) a); \
+ else \
+ *result = op a; \
+ return TRUE; \
+ }
+
+#define BINARY_OP(op) \
+ if (strncmp (sym, #op, strlen (#op)) == 0) \
+ { \
+ sym += strlen (#op); \
+ if (*sym == ':') \
+ ++sym; \
+ *symp = sym; \
+ if (!eval_symbol (&a, symp, input_bfd, flinfo, dot, \
+ isymbuf, locsymcount, signed_p)) \
+ return FALSE; \
+ ++*symp; \
+ if (!eval_symbol (&b, symp, input_bfd, flinfo, dot, \
+ isymbuf, locsymcount, signed_p)) \
+ return FALSE; \
+ if (signed_p) \
+ *result = ((bfd_signed_vma) a) op ((bfd_signed_vma) b); \
+ else \
+ *result = a op b; \
+ return TRUE; \
+ }
+
+ default:
+ UNARY_OP (0-);
+ BINARY_OP (<<);
+ BINARY_OP (>>);
+ BINARY_OP (==);
+ BINARY_OP (!=);
+ BINARY_OP (<=);
+ BINARY_OP (>=);
+ BINARY_OP (&&);
+ BINARY_OP (||);
+ UNARY_OP (~);
+ UNARY_OP (!);
+ BINARY_OP (*);
+ BINARY_OP (/);
+ BINARY_OP (%);
+ BINARY_OP (^);
+ BINARY_OP (|);
+ BINARY_OP (&);
+ BINARY_OP (+);
+ BINARY_OP (-);
+ BINARY_OP (<);
+ BINARY_OP (>);
+#undef UNARY_OP
+#undef BINARY_OP
+ _bfd_error_handler (_("unknown operator '%c' in complex symbol"), * sym);
+ bfd_set_error (bfd_error_invalid_operation);
+ return FALSE;
+ }
+}
+
+static void
+put_value (bfd_vma size,
+ unsigned long chunksz,
+ bfd *input_bfd,
+ bfd_vma x,
+ bfd_byte *location)
+{
+ location += (size - chunksz);
+
+ for (; size; size -= chunksz, location -= chunksz, x >>= (chunksz * 8))
+ {
+ switch (chunksz)
+ {
+ 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;
+ }
+ }
+}
+
+static bfd_vma
+get_value (bfd_vma size,
+ unsigned long chunksz,
+ bfd *input_bfd,
+ bfd_byte *location)
+{
+ int shift;
+ bfd_vma x = 0;
+
+ /* Sanity checks. */
+ BFD_ASSERT (chunksz <= sizeof (x)
+ && size >= chunksz
+ && chunksz != 0
+ && (size % chunksz) == 0
+ && input_bfd != NULL
+ && location != NULL);
+
+ if (chunksz == sizeof (x))
+ {
+ BFD_ASSERT (size == chunksz);
+
+ /* Make sure that we do not perform an undefined shift operation.
+ We know that size == chunksz so there will only be one iteration
+ of the loop below. */
+ shift = 0;
+ }
+ else
+ shift = 8 * chunksz;
+
+ for (; size; size -= chunksz, location += chunksz)
+ {
+ switch (chunksz)
+ {
+ case 1:
+ x = (x << shift) | bfd_get_8 (input_bfd, location);
+ break;
+ case 2:
+ x = (x << shift) | bfd_get_16 (input_bfd, location);
+ break;
+ case 4:
+ x = (x << shift) | bfd_get_32 (input_bfd, location);
+ break;
+#ifdef BFD64
+ case 8:
+ x = (x << shift) | bfd_get_64 (input_bfd, location);
+ break;
+#endif
+ default:
+ abort ();
+ }
+ }
+ return x;
+}
+
+static void
+decode_complex_addend (unsigned long *start, /* in bits */
+ unsigned long *oplen, /* in bits */
+ unsigned long *len, /* in bits */
+ unsigned long *wordsz, /* in bytes */
+ unsigned long *chunksz, /* in bytes */
+ unsigned long *lsb0_p,
+ unsigned long *signed_p,
+ unsigned long *trunc_p,
+ unsigned long encoded)
+{
+ * start = encoded & 0x3F;
+ * len = (encoded >> 6) & 0x3F;
+ * oplen = (encoded >> 12) & 0x3F;
+ * wordsz = (encoded >> 18) & 0xF;
+ * chunksz = (encoded >> 22) & 0xF;
+ * lsb0_p = (encoded >> 27) & 1;
+ * signed_p = (encoded >> 28) & 1;
+ * trunc_p = (encoded >> 29) & 1;
+}
+
+bfd_reloc_status_type
+bfd_elf_perform_complex_relocation (bfd *input_bfd,
+ asection *input_section ATTRIBUTE_UNUSED,
+ bfd_byte *contents,
+ Elf_Internal_Rela *rel,
+ bfd_vma relocation)
+{
+ bfd_vma shift, x, mask;
+ unsigned long start, oplen, len, wordsz, chunksz, lsb0_p, signed_p, trunc_p;
+ bfd_reloc_status_type r;
+
+ /* Perform this reloc, since it is complex.
+ (this is not to say that it necessarily refers to a complex
+ symbol; merely that it is a self-describing CGEN based reloc.
+ i.e. the addend has the complete reloc information (bit start, end,
+ word size, etc) encoded within it.). */
+
+ decode_complex_addend (&start, &oplen, &len, &wordsz,
+ &chunksz, &lsb0_p, &signed_p,
+ &trunc_p, rel->r_addend);
+
+ mask = (((1L << (len - 1)) - 1) << 1) | 1;
+
+ if (lsb0_p)
+ shift = (start + 1) - len;
+ else
+ shift = (8 * wordsz) - (start + len);
+
+ /* FIXME: octets_per_byte. */
+ x = get_value (wordsz, chunksz, input_bfd, contents + rel->r_offset);
+
+#ifdef DEBUG
+ printf ("Doing complex reloc: "
+ "lsb0? %ld, signed? %ld, trunc? %ld, wordsz %ld, "
+ "chunksz %ld, start %ld, len %ld, oplen %ld\n"
+ " dest: %8.8lx, mask: %8.8lx, reloc: %8.8lx\n",
+ lsb0_p, signed_p, trunc_p, wordsz, chunksz, start, len,
+ oplen, (unsigned long) x, (unsigned long) mask,
+ (unsigned long) relocation);
+#endif
+
+ r = bfd_reloc_ok;
+ if (! trunc_p)
+ /* Now do an overflow check. */
+ r = bfd_check_overflow ((signed_p
+ ? complain_overflow_signed
+ : complain_overflow_unsigned),
+ len, 0, (8 * wordsz),
+ relocation);
+
+ /* Do the deed. */
+ x = (x & ~(mask << shift)) | ((relocation & mask) << shift);
+
+#ifdef DEBUG
+ printf (" relocation: %8.8lx\n"
+ " shifted mask: %8.8lx\n"
+ " shifted/masked reloc: %8.8lx\n"
+ " result: %8.8lx\n",
+ (unsigned long) relocation, (unsigned long) (mask << shift),
+ (unsigned long) ((relocation & mask) << shift), (unsigned long) x);
+#endif
+ /* FIXME: octets_per_byte. */
+ put_value (wordsz, chunksz, input_bfd, x, contents + rel->r_offset);
+ return r;
+}
+
+/* When performing a relocatable link, the input relocations are
+ preserved. But, if they reference global symbols, the indices
+ referenced must be updated. Update all the relocations found in
+ RELDATA. */
+
+static void
+elf_link_adjust_relocs (bfd *abfd,
+ struct bfd_elf_section_reloc_data *reldata)
+{
+ unsigned int i;
+ const struct elf_backend_data *bed = get_elf_backend_data (abfd);
+ bfd_byte *erela;
+ void (*swap_in) (bfd *, const bfd_byte *, Elf_Internal_Rela *);
+ void (*swap_out) (bfd *, const Elf_Internal_Rela *, bfd_byte *);
+ bfd_vma r_type_mask;
+ int r_sym_shift;
+ unsigned int count = reldata->count;
+ struct elf_link_hash_entry **rel_hash = reldata->hashes;
+
+ if (reldata->hdr->sh_entsize == bed->s->sizeof_rel)
+ {
+ swap_in = bed->s->swap_reloc_in;
+ swap_out = bed->s->swap_reloc_out;
+ }
+ else if (reldata->hdr->sh_entsize == bed->s->sizeof_rela)
+ {
+ swap_in = bed->s->swap_reloca_in;
+ swap_out = bed->s->swap_reloca_out;
+ }
+ else
+ abort ();
+
+ if (bed->s->int_rels_per_ext_rel > MAX_INT_RELS_PER_EXT_REL)
+ abort ();
+
+ if (bed->s->arch_size == 32)
+ {
+ r_type_mask = 0xff;
+ r_sym_shift = 8;
+ }
+ else
+ {
+ r_type_mask = 0xffffffff;
+ r_sym_shift = 32;
+ }
+
+ erela = reldata->hdr->contents;
+ for (i = 0; i < count; i++, rel_hash++, erela += reldata->hdr->sh_entsize)
+ {
+ Elf_Internal_Rela irela[MAX_INT_RELS_PER_EXT_REL];
+ unsigned int j;
+
+ if (*rel_hash == NULL)
+ continue;
+
+ BFD_ASSERT ((*rel_hash)->indx >= 0);
+
+ (*swap_in) (abfd, erela, irela);
+ for (j = 0; j < bed->s->int_rels_per_ext_rel; j++)
+ irela[j].r_info = ((bfd_vma) (*rel_hash)->indx << r_sym_shift
+ | (irela[j].r_info & r_type_mask));
+ (*swap_out) (abfd, irela, erela);
+ }
+}
+
+struct elf_link_sort_rela
+{
+ union {
+ bfd_vma offset;
+ bfd_vma sym_mask;
+ } u;
+ enum elf_reloc_type_class type;
+ /* We use this as an array of size int_rels_per_ext_rel. */
+ Elf_Internal_Rela rela[1];
+};
+
+static int
+elf_link_sort_cmp1 (const void *A, const void *B)
+{
+ const struct elf_link_sort_rela *a = (const struct elf_link_sort_rela *) A;
+ const struct elf_link_sort_rela *b = (const struct elf_link_sort_rela *) B;
+ int relativea, relativeb;
+
+ relativea = a->type == reloc_class_relative;
+ relativeb = b->type == reloc_class_relative;
+
+ if (relativea < relativeb)
+ return 1;
+ if (relativea > relativeb)
+ return -1;
+ if ((a->rela->r_info & a->u.sym_mask) < (b->rela->r_info & b->u.sym_mask))
+ return -1;
+ if ((a->rela->r_info & a->u.sym_mask) > (b->rela->r_info & b->u.sym_mask))
+ return 1;
+ if (a->rela->r_offset < b->rela->r_offset)
+ return -1;
+ if (a->rela->r_offset > b->rela->r_offset)
+ return 1;
+ return 0;
+}
+
+static int
+elf_link_sort_cmp2 (const void *A, const void *B)
+{
+ const struct elf_link_sort_rela *a = (const struct elf_link_sort_rela *) A;
+ const struct elf_link_sort_rela *b = (const struct elf_link_sort_rela *) B;
+
+ if (a->type < b->type)
+ return -1;
+ if (a->type > b->type)
+ return 1;
+ if (a->u.offset < b->u.offset)
+ return -1;
+ if (a->u.offset > b->u.offset)
+ return 1;
+ if (a->rela->r_offset < b->rela->r_offset)
+ return -1;
+ if (a->rela->r_offset > b->rela->r_offset)
+ return 1;
+ return 0;
+}
+
+static size_t
+elf_link_sort_relocs (bfd *abfd, struct bfd_link_info *info, asection **psec)
+{
+ asection *dynamic_relocs;
+ asection *rela_dyn;
+ asection *rel_dyn;
+ bfd_size_type count, size;
+ size_t i, ret, sort_elt, ext_size;
+ bfd_byte *sort, *s_non_relative, *p;
+ struct elf_link_sort_rela *sq;
+ const struct elf_backend_data *bed = get_elf_backend_data (abfd);
+ int i2e = bed->s->int_rels_per_ext_rel;
+ void (*swap_in) (bfd *, const bfd_byte *, Elf_Internal_Rela *);
+ void (*swap_out) (bfd *, const Elf_Internal_Rela *, bfd_byte *);
+ struct bfd_link_order *lo;
+ bfd_vma r_sym_mask;
+ bfd_boolean use_rela;
+
+ /* Find a dynamic reloc section. */
+ rela_dyn = bfd_get_section_by_name (abfd, ".rela.dyn");
+ rel_dyn = bfd_get_section_by_name (abfd, ".rel.dyn");
+ if (rela_dyn != NULL && rela_dyn->size > 0
+ && rel_dyn != NULL && rel_dyn->size > 0)
+ {
+ bfd_boolean use_rela_initialised = FALSE;
+
+ /* This is just here to stop gcc from complaining.
+ It's initialization checking code is not perfect. */
+ use_rela = TRUE;
+
+ /* Both sections are present. Examine the sizes
+ of the indirect sections to help us choose. */
+ for (lo = rela_dyn->map_head.link_order; lo != NULL; lo = lo->next)
+ if (lo->type == bfd_indirect_link_order)
+ {
+ asection *o = lo->u.indirect.section;
+
+ if ((o->size % bed->s->sizeof_rela) == 0)
+ {
+ if ((o->size % bed->s->sizeof_rel) == 0)
+ /* Section size is divisible by both rel and rela sizes.
+ It is of no help to us. */
+ ;
+ else
+ {
+ /* Section size is only divisible by rela. */
+ if (use_rela_initialised && (use_rela == FALSE))
+ {
+ _bfd_error_handler
+ (_("%B: Unable to sort relocs - they are in more than one size"), abfd);
+ bfd_set_error (bfd_error_invalid_operation);
+ return 0;
+ }
+ else
+ {
+ use_rela = TRUE;
+ use_rela_initialised = TRUE;
+ }
+ }
+ }
+ else if ((o->size % bed->s->sizeof_rel) == 0)
+ {
+ /* Section size is only divisible by rel. */
+ if (use_rela_initialised && (use_rela == TRUE))
+ {
+ _bfd_error_handler
+ (_("%B: Unable to sort relocs - they are in more than one size"), abfd);
+ bfd_set_error (bfd_error_invalid_operation);
+ return 0;
+ }
+ else
+ {
+ use_rela = FALSE;
+ use_rela_initialised = TRUE;
+ }
+ }
+ else
+ {
+ /* The section size is not divisible by either - something is wrong. */
+ _bfd_error_handler
+ (_("%B: Unable to sort relocs - they are of an unknown size"), abfd);
+ bfd_set_error (bfd_error_invalid_operation);
+ return 0;
+ }
+ }
+
+ for (lo = rel_dyn->map_head.link_order; lo != NULL; lo = lo->next)
+ if (lo->type == bfd_indirect_link_order)
+ {
+ asection *o = lo->u.indirect.section;
+
+ if ((o->size % bed->s->sizeof_rela) == 0)
+ {
+ if ((o->size % bed->s->sizeof_rel) == 0)
+ /* Section size is divisible by both rel and rela sizes.
+ It is of no help to us. */
+ ;
+ else
+ {
+ /* Section size is only divisible by rela. */
+ if (use_rela_initialised && (use_rela == FALSE))
+ {
+ _bfd_error_handler
+ (_("%B: Unable to sort relocs - they are in more than one size"), abfd);
+ bfd_set_error (bfd_error_invalid_operation);
+ return 0;
+ }
+ else
+ {
+ use_rela = TRUE;
+ use_rela_initialised = TRUE;
+ }
+ }
+ }
+ else if ((o->size % bed->s->sizeof_rel) == 0)
+ {
+ /* Section size is only divisible by rel. */
+ if (use_rela_initialised && (use_rela == TRUE))
+ {
+ _bfd_error_handler
+ (_("%B: Unable to sort relocs - they are in more than one size"), abfd);
+ bfd_set_error (bfd_error_invalid_operation);
+ return 0;
+ }
+ else
+ {
+ use_rela = FALSE;
+ use_rela_initialised = TRUE;
+ }
+ }
+ else
+ {
+ /* The section size is not divisible by either - something is wrong. */
+ _bfd_error_handler
+ (_("%B: Unable to sort relocs - they are of an unknown size"), abfd);
+ bfd_set_error (bfd_error_invalid_operation);
+ return 0;
+ }
+ }
+
+ if (! use_rela_initialised)
+ /* Make a guess. */
+ use_rela = TRUE;
+ }
+ else if (rela_dyn != NULL && rela_dyn->size > 0)
+ use_rela = TRUE;
+ else if (rel_dyn != NULL && rel_dyn->size > 0)
+ use_rela = FALSE;
+ else
+ return 0;
+
+ if (use_rela)
+ {
+ dynamic_relocs = rela_dyn;
+ ext_size = bed->s->sizeof_rela;
+ swap_in = bed->s->swap_reloca_in;
+ swap_out = bed->s->swap_reloca_out;
+ }
+ else
+ {
+ dynamic_relocs = rel_dyn;
+ ext_size = bed->s->sizeof_rel;
+ swap_in = bed->s->swap_reloc_in;
+ swap_out = bed->s->swap_reloc_out;
+ }
+
+ size = 0;
+ for (lo = dynamic_relocs->map_head.link_order; lo != NULL; lo = lo->next)
+ if (lo->type == bfd_indirect_link_order)
+ size += lo->u.indirect.section->size;
+
+ if (size != dynamic_relocs->size)
+ return 0;
+
+ sort_elt = (sizeof (struct elf_link_sort_rela)
+ + (i2e - 1) * sizeof (Elf_Internal_Rela));
+
+ count = dynamic_relocs->size / ext_size;
+ if (count == 0)
+ return 0;
+ sort = (bfd_byte *) bfd_zmalloc (sort_elt * count);
+
+ if (sort == NULL)
+ {
+ (*info->callbacks->warning)
+ (info, _("Not enough memory to sort relocations"), 0, abfd, 0, 0);
+ return 0;
+ }
+
+ if (bed->s->arch_size == 32)
+ r_sym_mask = ~(bfd_vma) 0xff;
+ else
+ r_sym_mask = ~(bfd_vma) 0xffffffff;
+
+ for (lo = dynamic_relocs->map_head.link_order; lo != NULL; lo = lo->next)
+ if (lo->type == bfd_indirect_link_order)
+ {
+ bfd_byte *erel, *erelend;
+ asection *o = lo->u.indirect.section;
+
+ if (o->contents == NULL && o->size != 0)
+ {
+ /* This is a reloc section that is being handled as a normal
+ section. See bfd_section_from_shdr. We can't combine
+ relocs in this case. */
+ free (sort);
+ return 0;
+ }
+ erel = o->contents;
+ erelend = o->contents + o->size;
+ /* FIXME: octets_per_byte. */
+ p = sort + o->output_offset / ext_size * sort_elt;
+
+ while (erel < erelend)
+ {
+ struct elf_link_sort_rela *s = (struct elf_link_sort_rela *) p;
+
+ (*swap_in) (abfd, erel, s->rela);
+ s->type = (*bed->elf_backend_reloc_type_class) (info, o, s->rela);
+ s->u.sym_mask = r_sym_mask;
+ p += sort_elt;
+ erel += ext_size;
+ }
+ }
+
+ qsort (sort, count, sort_elt, elf_link_sort_cmp1);
+
+ for (i = 0, p = sort; i < count; i++, p += sort_elt)
+ {
+ struct elf_link_sort_rela *s = (struct elf_link_sort_rela *) p;
+ if (s->type != reloc_class_relative)
+ break;
+ }
+ ret = i;
+ s_non_relative = p;
+
+ sq = (struct elf_link_sort_rela *) s_non_relative;
+ for (; i < count; i++, p += sort_elt)
+ {
+ struct elf_link_sort_rela *sp = (struct elf_link_sort_rela *) p;
+ if (((sp->rela->r_info ^ sq->rela->r_info) & r_sym_mask) != 0)
+ sq = sp;
+ sp->u.offset = sq->rela->r_offset;
+ }
+
+ qsort (s_non_relative, count - ret, sort_elt, elf_link_sort_cmp2);
+
+ for (lo = dynamic_relocs->map_head.link_order; lo != NULL; lo = lo->next)
+ if (lo->type == bfd_indirect_link_order)
+ {
+ bfd_byte *erel, *erelend;
+ asection *o = lo->u.indirect.section;
+
+ erel = o->contents;
+ erelend = o->contents + o->size;
+ /* FIXME: octets_per_byte. */
+ p = sort + o->output_offset / ext_size * sort_elt;
+ while (erel < erelend)
+ {
+ struct elf_link_sort_rela *s = (struct elf_link_sort_rela *) p;
+ (*swap_out) (abfd, s->rela, erel);
+ p += sort_elt;
+ erel += ext_size;
+ }
+ }
+
+ free (sort);
+ *psec = dynamic_relocs;
+ return ret;
+}
+
+/* Flush the output symbols to the file. */
+
+static bfd_boolean
+elf_link_flush_output_syms (struct elf_final_link_info *flinfo,
+ const struct elf_backend_data *bed)
+{
+ if (flinfo->symbuf_count > 0)
+ {
+ Elf_Internal_Shdr *hdr;
+ file_ptr pos;
+ bfd_size_type amt;
+
+ hdr = &elf_tdata (flinfo->output_bfd)->symtab_hdr;
+ pos = hdr->sh_offset + hdr->sh_size;
+ amt = flinfo->symbuf_count * bed->s->sizeof_sym;
+ if (bfd_seek (flinfo->output_bfd, pos, SEEK_SET) != 0
+ || bfd_bwrite (flinfo->symbuf, amt, flinfo->output_bfd) != amt)
+ return FALSE;
+
+ hdr->sh_size += amt;
+ flinfo->symbuf_count = 0;
+ }
+
+ return TRUE;
+}
+
+/* Add a symbol to the output symbol table. */
+
+static int
+elf_link_output_sym (struct elf_final_link_info *flinfo,
+ const char *name,
+ Elf_Internal_Sym *elfsym,
+ asection *input_sec,
+ struct elf_link_hash_entry *h)
+{
+ bfd_byte *dest;
+ Elf_External_Sym_Shndx *destshndx;
+ int (*output_symbol_hook)
+ (struct bfd_link_info *, const char *, Elf_Internal_Sym *, asection *,
+ struct elf_link_hash_entry *);
+ const struct elf_backend_data *bed;
+
+ bed = get_elf_backend_data (flinfo->output_bfd);
+ output_symbol_hook = bed->elf_backend_link_output_symbol_hook;
+ if (output_symbol_hook != NULL)
+ {
+ int ret = (*output_symbol_hook) (flinfo->info, name, elfsym, input_sec, h);
+ if (ret != 1)
+ return ret;
+ }
+
+ if (name == 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 (flinfo->symstrtab,
+ name, TRUE, FALSE);
+ if (elfsym->st_name == (unsigned long) -1)
+ return 0;
+ }
+
+ if (flinfo->symbuf_count >= flinfo->symbuf_size)
+ {
+ if (! elf_link_flush_output_syms (flinfo, bed))
+ return 0;
+ }
+
+ dest = flinfo->symbuf + flinfo->symbuf_count * bed->s->sizeof_sym;
+ destshndx = flinfo->symshndxbuf;
+ if (destshndx != NULL)
+ {
+ if (bfd_get_symcount (flinfo->output_bfd) >= flinfo->shndxbuf_size)
+ {
+ bfd_size_type amt;
+
+ amt = flinfo->shndxbuf_size * sizeof (Elf_External_Sym_Shndx);
+ destshndx = (Elf_External_Sym_Shndx *) bfd_realloc (destshndx,
+ amt * 2);
+ if (destshndx == NULL)
+ return 0;
+ flinfo->symshndxbuf = destshndx;
+ memset ((char *) destshndx + amt, 0, amt);
+ flinfo->shndxbuf_size *= 2;
+ }
+ destshndx += bfd_get_symcount (flinfo->output_bfd);
+ }
+
+ bed->s->swap_symbol_out (flinfo->output_bfd, elfsym, dest, destshndx);
+ flinfo->symbuf_count += 1;
+ bfd_get_symcount (flinfo->output_bfd) += 1;
+
+ return 1;
+}
+
+/* Return TRUE if the dynamic symbol SYM in ABFD is supported. */
+
+static bfd_boolean
+check_dynsym (bfd *abfd, Elf_Internal_Sym *sym)
+{
+ if (sym->st_shndx >= (SHN_LORESERVE & 0xffff)
+ && sym->st_shndx < SHN_LORESERVE)
+ {
+ /* The gABI doesn't support dynamic symbols in output sections
+ beyond 64k. */
+ (*_bfd_error_handler)
+ (_("%B: Too many sections: %d (>= %d)"),
+ abfd, bfd_count_sections (abfd), SHN_LORESERVE & 0xffff);
+ bfd_set_error (bfd_error_nonrepresentable_section);
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/* For DSOs loaded in via a DT_NEEDED entry, emulate ld.so in
+ allowing an unsatisfied unversioned symbol in the DSO to match a
+ versioned symbol that would normally require an explicit version.
+ We also handle the case that a DSO references a hidden symbol
+ which may be satisfied by a versioned symbol in another DSO. */
+
+static bfd_boolean
+elf_link_check_versioned_symbol (struct bfd_link_info *info,
+ const struct elf_backend_data *bed,
+ struct elf_link_hash_entry *h)
+{
+ bfd *abfd;
+ struct elf_link_loaded_list *loaded;
+
+ if (!is_elf_hash_table (info->hash))
+ return FALSE;
+
+ /* Check indirect symbol. */
+ while (h->root.type == bfd_link_hash_indirect)
+ h = (struct elf_link_hash_entry *) h->root.u.i.link;
+
+ switch (h->root.type)
+ {
+ default:
+ abfd = NULL;
+ break;
+
+ case bfd_link_hash_undefined:
+ case bfd_link_hash_undefweak:
+ abfd = h->root.u.undef.abfd;
+ if ((abfd->flags & DYNAMIC) == 0
+ || (elf_dyn_lib_class (abfd) & DYN_DT_NEEDED) == 0)
+ return FALSE;
+ break;
+
+ case bfd_link_hash_defined:
+ case bfd_link_hash_defweak:
+ abfd = h->root.u.def.section->owner;
+ break;
+
+ case bfd_link_hash_common:
+ abfd = h->root.u.c.p->section->owner;
+ break;
+ }
+ BFD_ASSERT (abfd != NULL);
+
+ for (loaded = elf_hash_table (info)->loaded;
+ loaded != NULL;
+ loaded = loaded->next)
+ {
+ bfd *input;
+ Elf_Internal_Shdr *hdr;
+ bfd_size_type symcount;
+ bfd_size_type extsymcount;
+ bfd_size_type extsymoff;
+ Elf_Internal_Shdr *versymhdr;
+ Elf_Internal_Sym *isym;
+ Elf_Internal_Sym *isymend;
+ Elf_Internal_Sym *isymbuf;
+ Elf_External_Versym *ever;
+ Elf_External_Versym *extversym;
+
+ input = loaded->abfd;
+
+ /* We check each DSO for a possible hidden versioned definition. */
+ if (input == abfd
+ || (input->flags & DYNAMIC) == 0
+ || elf_dynversym (input) == 0)
+ continue;
+
+ hdr = &elf_tdata (input)->dynsymtab_hdr;
+
+ symcount = hdr->sh_size / bed->s->sizeof_sym;
+ if (elf_bad_symtab (input))
+ {
+ extsymcount = symcount;
+ extsymoff = 0;
+ }
+ else
+ {
+ extsymcount = symcount - hdr->sh_info;
+ extsymoff = hdr->sh_info;
+ }
+
+ if (extsymcount == 0)
+ continue;
+
+ isymbuf = bfd_elf_get_elf_syms (input, hdr, extsymcount, extsymoff,
+ NULL, NULL, NULL);
+ if (isymbuf == NULL)
+ return FALSE;
+
+ /* Read in any version definitions. */
+ versymhdr = &elf_tdata (input)->dynversym_hdr;
+ extversym = (Elf_External_Versym *) bfd_malloc (versymhdr->sh_size);
+ if (extversym == NULL)
+ goto error_ret;
+
+ if (bfd_seek (input, versymhdr->sh_offset, SEEK_SET) != 0
+ || (bfd_bread (extversym, versymhdr->sh_size, input)
+ != versymhdr->sh_size))
+ {
+ free (extversym);
+ error_ret:
+ free (isymbuf);
+ return FALSE;
+ }
+
+ ever = extversym + extsymoff;
+ isymend = isymbuf + extsymcount;
+ for (isym = isymbuf; isym < isymend; isym++, ever++)
+ {
+ const char *name;
+ Elf_Internal_Versym iver;
+ unsigned short version_index;
+
+ if (ELF_ST_BIND (isym->st_info) == STB_LOCAL
+ || isym->st_shndx == SHN_UNDEF)
+ continue;
+
+ name = bfd_elf_string_from_elf_section (input,
+ hdr->sh_link,
+ isym->st_name);
+ if (strcmp (name, h->root.root.string) != 0)
+ continue;
+
+ _bfd_elf_swap_versym_in (input, ever, &iver);
+
+ if ((iver.vs_vers & VERSYM_HIDDEN) == 0
+ && !(h->def_regular
+ && h->forced_local))
+ {
+ /* If we have a non-hidden versioned sym, then it should
+ have provided a definition for the undefined sym unless
+ it is defined in a non-shared object and forced local.
+ */
+ abort ();
+ }
+
+ version_index = iver.vs_vers & VERSYM_VERSION;
+ if (version_index == 1 || version_index == 2)
+ {
+ /* This is the base or first version. We can use it. */
+ free (extversym);
+ free (isymbuf);
+ return TRUE;
+ }
+ }
+
+ free (extversym);
+ free (isymbuf);
+ }
+
+ return FALSE;
+}
+
+/* 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 bfd_boolean
+elf_link_output_extsym (struct bfd_hash_entry *bh, void *data)
+{
+ struct elf_link_hash_entry *h = (struct elf_link_hash_entry *) bh;
+ struct elf_outext_info *eoinfo = (struct elf_outext_info *) data;
+ struct elf_final_link_info *flinfo = eoinfo->flinfo;
+ bfd_boolean strip;
+ Elf_Internal_Sym sym;
+ asection *input_sec;
+ const struct elf_backend_data *bed;
+ long indx;
+ int ret;
+
+ if (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_new)
+ return TRUE;
+ }
+
+ /* Decide whether to output this symbol in this pass. */
+ if (eoinfo->localsyms)
+ {
+ if (!h->forced_local)
+ return TRUE;
+ if (eoinfo->second_pass
+ && !((h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak)
+ && h->root.u.def.section->output_section != NULL))
+ return TRUE;
+
+ if (!eoinfo->file_sym_done
+ && (eoinfo->second_pass ? eoinfo->flinfo->filesym_count == 1
+ : eoinfo->flinfo->filesym_count > 1))
+ {
+ /* Output a FILE symbol so that following locals are not associated
+ with the wrong input file. */
+ memset (&sym, 0, sizeof (sym));
+ sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_FILE);
+ sym.st_shndx = SHN_ABS;
+ if (!elf_link_output_sym (eoinfo->flinfo, NULL, &sym,
+ bfd_und_section_ptr, NULL))
+ return FALSE;
+
+ eoinfo->file_sym_done = TRUE;
+ }
+ }
+ else
+ {
+ if (h->forced_local)
+ return TRUE;
+ }
+
+ bed = get_elf_backend_data (flinfo->output_bfd);
+
+ if (h->root.type == bfd_link_hash_undefined)
+ {
+ /* If we have an undefined symbol reference here then it must have
+ come from a shared library that is being linked in. (Undefined
+ references in regular files have already been handled unless
+ they are in unreferenced sections which are removed by garbage
+ collection). */
+ bfd_boolean ignore_undef = FALSE;
+
+ /* Some symbols may be special in that the fact that they're
+ undefined can be safely ignored - let backend determine that. */
+ if (bed->elf_backend_ignore_undef_symbol)
+ ignore_undef = bed->elf_backend_ignore_undef_symbol (h);
+
+ /* If we are reporting errors for this situation then do so now. */
+ if (!ignore_undef
+ && h->ref_dynamic
+ && (!h->ref_regular || flinfo->info->gc_sections)
+ && !elf_link_check_versioned_symbol (flinfo->info, bed, h)
+ && flinfo->info->unresolved_syms_in_shared_libs != RM_IGNORE)
+ {
+ if (!(flinfo->info->callbacks->undefined_symbol
+ (flinfo->info, h->root.root.string,
+ h->ref_regular ? NULL : h->root.u.undef.abfd,
+ NULL, 0,
+ (flinfo->info->unresolved_syms_in_shared_libs
+ == RM_GENERATE_ERROR))))
+ {
+ bfd_set_error (bfd_error_bad_value);
+ eoinfo->failed = TRUE;
+ return FALSE;
+ }
+ }
+ }
+
+ /* We should also warn if a forced local symbol is referenced from
+ shared libraries. */
+ if (!flinfo->info->relocatable
+ && flinfo->info->executable
+ && h->forced_local
+ && h->ref_dynamic
+ && h->def_regular
+ && !h->dynamic_def
+ && h->ref_dynamic_nonweak
+ && !elf_link_check_versioned_symbol (flinfo->info, bed, h))
+ {
+ bfd *def_bfd;
+ const char *msg;
+ struct elf_link_hash_entry *hi = h;
+
+ /* Check indirect symbol. */
+ while (hi->root.type == bfd_link_hash_indirect)
+ hi = (struct elf_link_hash_entry *) hi->root.u.i.link;
+
+ if (ELF_ST_VISIBILITY (h->other) == STV_INTERNAL)
+ msg = _("%B: internal symbol `%s' in %B is referenced by DSO");
+ else if (ELF_ST_VISIBILITY (h->other) == STV_HIDDEN)
+ msg = _("%B: hidden symbol `%s' in %B is referenced by DSO");
+ else
+ msg = _("%B: local symbol `%s' in %B is referenced by DSO");
+ def_bfd = flinfo->output_bfd;
+ if (hi->root.u.def.section != bfd_abs_section_ptr)
+ def_bfd = hi->root.u.def.section->owner;
+ (*_bfd_error_handler) (msg, flinfo->output_bfd, def_bfd,
+ h->root.root.string);
+ bfd_set_error (bfd_error_bad_value);
+ 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->def_dynamic
+ || h->ref_dynamic
+ || h->root.type == bfd_link_hash_new)
+ && !h->def_regular
+ && !h->ref_regular)
+ strip = TRUE;
+ else if (flinfo->info->strip == strip_all)
+ strip = TRUE;
+ else if (flinfo->info->strip == strip_some
+ && bfd_hash_lookup (flinfo->info->keep_hash,
+ h->root.root.string, FALSE, FALSE) == NULL)
+ strip = TRUE;
+ else if ((h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak)
+ && ((flinfo->info->strip_discarded
+ && discarded_section (h->root.u.def.section))
+ || (h->root.u.def.section->owner != NULL
+ && (h->root.u.def.section->owner->flags & BFD_PLUGIN) != 0)))
+ strip = TRUE;
+ else 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 & BFD_PLUGIN) != 0)
+ strip = TRUE;
+ else
+ strip = FALSE;
+
+ /* If we're stripping it, and it's not a dynamic symbol, there's
+ nothing else to do unless it is a forced local symbol or a
+ STT_GNU_IFUNC symbol. */
+ if (strip
+ && h->dynindx == -1
+ && h->type != STT_GNU_IFUNC
+ && !h->forced_local)
+ return TRUE;
+
+ sym.st_value = 0;
+ sym.st_size = h->size;
+ sym.st_other = h->other;
+ if (h->forced_local)
+ {
+ sym.st_info = ELF_ST_INFO (STB_LOCAL, h->type);
+ /* Turn off visibility on local symbol. */
+ sym.st_other &= ~ELF_ST_VISIBILITY (-1);
+ }
+ /* Set STB_GNU_UNIQUE only if symbol is defined in regular object. */
+ else if (h->unique_global && h->def_regular)
+ sym.st_info = ELF_ST_INFO (STB_GNU_UNIQUE, 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);
+ sym.st_target_internal = h->target_internal;
+
+ switch (h->root.type)
+ {
+ default:
+ case bfd_link_hash_new:
+ case bfd_link_hash_warning:
+ abort ();
+ return FALSE;
+
+ case bfd_link_hash_undefined:
+ 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)
+ {
+ if (eoinfo->localsyms && flinfo->filesym_count == 1)
+ {
+ bfd_boolean second_pass_sym
+ = (input_sec->owner == flinfo->output_bfd
+ || input_sec->owner == NULL
+ || (input_sec->flags & SEC_LINKER_CREATED) != 0
+ || (input_sec->owner->flags & BFD_LINKER_CREATED) != 0);
+
+ eoinfo->need_second_pass |= second_pass_sym;
+ if (eoinfo->second_pass != second_pass_sym)
+ return TRUE;
+ }
+
+ sym.st_shndx =
+ _bfd_elf_section_from_bfd_section (flinfo->output_bfd,
+ input_sec->output_section);
+ if (sym.st_shndx == SHN_BAD)
+ {
+ (*_bfd_error_handler)
+ (_("%B: could not find output section %A for input section %A"),
+ flinfo->output_bfd, input_sec->output_section, input_sec);
+ bfd_set_error (bfd_error_nonrepresentable_section);
+ eoinfo->failed = TRUE;
+ return FALSE;
+ }
+
+ /* ELF symbols in relocatable files are section relative,
+ but in nonrelocatable files they are virtual
+ addresses. */
+ sym.st_value = h->root.u.def.value + input_sec->output_offset;
+ if (!flinfo->info->relocatable)
+ {
+ sym.st_value += input_sec->output_section->vma;
+ if (h->type == STT_TLS)
+ {
+ asection *tls_sec = elf_hash_table (flinfo->info)->tls_sec;
+ if (tls_sec != NULL)
+ sym.st_value -= tls_sec->vma;
+ else
+ {
+ /* The TLS section may have been garbage collected. */
+ BFD_ASSERT (flinfo->info->gc_sections
+ && !input_sec->gc_mark);
+ }
+ }
+ }
+ }
+ 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 = bed->common_section_index (input_sec);
+ 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. */
+ return TRUE;
+ }
+
+ /* 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. FIXME: Not calling elf_backend_finish_dynamic_symbol for
+ forced local syms when non-shared is due to a historical quirk.
+ STT_GNU_IFUNC symbol must go through PLT. */
+ if ((h->type == STT_GNU_IFUNC
+ && h->def_regular
+ && !flinfo->info->relocatable)
+ || ((h->dynindx != -1
+ || h->forced_local)
+ && ((flinfo->info->shared
+ && (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
+ || h->root.type != bfd_link_hash_undefweak))
+ || !h->forced_local)
+ && elf_hash_table (flinfo->info)->dynamic_sections_created))
+ {
+ if (! ((*bed->elf_backend_finish_dynamic_symbol)
+ (flinfo->output_bfd, flinfo->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; if there are non-weak
+ references, mark the symbol as strong. 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
+ && h->ref_regular
+ && (ELF_ST_BIND (sym.st_info) == STB_GLOBAL
+ || ELF_ST_BIND (sym.st_info) == STB_WEAK))
+ {
+ int bindtype;
+ unsigned int type = ELF_ST_TYPE (sym.st_info);
+
+ /* Turn an undefined IFUNC symbol into a normal FUNC symbol. */
+ if (type == STT_GNU_IFUNC)
+ type = STT_FUNC;
+
+ if (h->ref_regular_nonweak)
+ bindtype = STB_GLOBAL;
+ else
+ bindtype = STB_WEAK;
+ sym.st_info = ELF_ST_INFO (bindtype, type);
+ }
+
+ /* If this is a symbol defined in a dynamic library, don't use the
+ symbol size from the dynamic library. Relinking an executable
+ against a new library may introduce gratuitous changes in the
+ executable's symbols if we keep the size. */
+ if (sym.st_shndx == SHN_UNDEF
+ && !h->def_regular
+ && h->def_dynamic)
+ sym.st_size = 0;
+
+ /* If a non-weak symbol with non-default visibility is not defined
+ locally, it is a fatal error. */
+ if (!flinfo->info->relocatable
+ && ELF_ST_VISIBILITY (sym.st_other) != STV_DEFAULT
+ && ELF_ST_BIND (sym.st_info) != STB_WEAK
+ && h->root.type == bfd_link_hash_undefined
+ && !h->def_regular)
+ {
+ const char *msg;
+
+ if (ELF_ST_VISIBILITY (sym.st_other) == STV_PROTECTED)
+ msg = _("%B: protected symbol `%s' isn't defined");
+ else if (ELF_ST_VISIBILITY (sym.st_other) == STV_INTERNAL)
+ msg = _("%B: internal symbol `%s' isn't defined");
+ else
+ msg = _("%B: hidden symbol `%s' isn't defined");
+ (*_bfd_error_handler) (msg, flinfo->output_bfd, h->root.root.string);
+ bfd_set_error (bfd_error_bad_value);
+ eoinfo->failed = TRUE;
+ return FALSE;
+ }
+
+ /* If this symbol should be put in the .dynsym section, then put it
+ there now. We already know the symbol index. We also fill in
+ the entry in the .hash section. */
+ if (flinfo->dynsym_sec != NULL
+ && h->dynindx != -1
+ && elf_hash_table (flinfo->info)->dynamic_sections_created)
+ {
+ bfd_byte *esym;
+
+ /* Since there is no version information in the dynamic string,
+ if there is no version info in symbol version section, we will
+ have a run-time problem. */
+ if (h->verinfo.verdef == NULL)
+ {
+ char *p = strrchr (h->root.root.string, ELF_VER_CHR);
+
+ if (p && p [1] != '\0')
+ {
+ (*_bfd_error_handler)
+ (_("%B: No symbol version section for versioned symbol `%s'"),
+ flinfo->output_bfd, h->root.root.string);
+ eoinfo->failed = TRUE;
+ return FALSE;
+ }
+ }
+
+ sym.st_name = h->dynstr_index;
+ esym = flinfo->dynsym_sec->contents + h->dynindx * bed->s->sizeof_sym;
+ if (!check_dynsym (flinfo->output_bfd, &sym))
+ {
+ eoinfo->failed = TRUE;
+ return FALSE;
+ }
+ bed->s->swap_symbol_out (flinfo->output_bfd, &sym, esym, 0);
+
+ if (flinfo->hash_sec != NULL)
+ {
+ size_t hash_entry_size;
+ bfd_byte *bucketpos;
+ bfd_vma chain;
+ size_t bucketcount;
+ size_t bucket;
+
+ bucketcount = elf_hash_table (flinfo->info)->bucketcount;
+ bucket = h->u.elf_hash_value % bucketcount;
+
+ hash_entry_size
+ = elf_section_data (flinfo->hash_sec)->this_hdr.sh_entsize;
+ bucketpos = ((bfd_byte *) flinfo->hash_sec->contents
+ + (bucket + 2) * hash_entry_size);
+ chain = bfd_get (8 * hash_entry_size, flinfo->output_bfd, bucketpos);
+ bfd_put (8 * hash_entry_size, flinfo->output_bfd, h->dynindx,
+ bucketpos);
+ bfd_put (8 * hash_entry_size, flinfo->output_bfd, chain,
+ ((bfd_byte *) flinfo->hash_sec->contents
+ + (bucketcount + 2 + h->dynindx) * hash_entry_size));
+ }
+
+ if (flinfo->symver_sec != NULL && flinfo->symver_sec->contents != NULL)
+ {
+ Elf_Internal_Versym iversym;
+ Elf_External_Versym *eversym;
+
+ if (!h->def_regular)
+ {
+ if (h->verinfo.verdef == NULL
+ || (elf_dyn_lib_class (h->verinfo.verdef->vd_bfd)
+ & (DYN_AS_NEEDED | DYN_DT_NEEDED | DYN_NO_NEEDED)))
+ 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 (flinfo->info->create_default_symver)
+ iversym.vs_vers++;
+ }
+
+ if (h->hidden)
+ iversym.vs_vers |= VERSYM_HIDDEN;
+
+ eversym = (Elf_External_Versym *) flinfo->symver_sec->contents;
+ eversym += h->dynindx;
+ _bfd_elf_swap_versym_out (flinfo->output_bfd, &iversym, eversym);
+ }
+ }
+
+ /* If we're stripping it, then it was just a dynamic symbol, and
+ there's nothing else to do. */
+ if (strip || (input_sec->flags & SEC_EXCLUDE) != 0)
+ return TRUE;
+
+ indx = bfd_get_symcount (flinfo->output_bfd);
+ ret = elf_link_output_sym (flinfo, h->root.root.string, &sym, input_sec, h);
+ if (ret == 0)
+ {
+ eoinfo->failed = TRUE;
+ return FALSE;
+ }
+ else if (ret == 1)
+ h->indx = indx;
+ else if (h->indx == -2)
+ abort();
+
+ return TRUE;
+}
+
+/* Return TRUE if special handling is done for relocs in SEC against
+ symbols defined in discarded sections. */
+
+static bfd_boolean
+elf_section_ignore_discarded_relocs (asection *sec)
+{
+ const struct elf_backend_data *bed;
+
+ switch (sec->sec_info_type)
+ {
+ case SEC_INFO_TYPE_STABS:
+ case SEC_INFO_TYPE_EH_FRAME:
+ return TRUE;
+ default:
+ break;
+ }
+
+ bed = get_elf_backend_data (sec->owner);
+ if (bed->elf_backend_ignore_discarded_relocs != NULL
+ && (*bed->elf_backend_ignore_discarded_relocs) (sec))
+ return TRUE;
+
+ return FALSE;
+}
+
+/* Return a mask saying how ld should treat relocations in SEC against
+ symbols defined in discarded sections. If this function returns
+ COMPLAIN set, ld will issue a warning message. If this function
+ returns PRETEND set, and the discarded section was link-once and the
+ same size as the kept link-once section, ld will pretend that the
+ symbol was actually defined in the kept section. Otherwise ld will
+ zero the reloc (at least that is the intent, but some cooperation by
+ the target dependent code is needed, particularly for REL targets). */
+
+unsigned int
+_bfd_elf_default_action_discarded (asection *sec)
+{
+ if (sec->flags & SEC_DEBUGGING)
+ return PRETEND;
+
+ if (strcmp (".eh_frame", sec->name) == 0)
+ return 0;
+
+ if (strcmp (".gcc_except_table", sec->name) == 0)
+ return 0;
+
+ return COMPLAIN | PRETEND;
+}
+
+/* Find a match between a section and a member of a section group. */
+
+static asection *
+match_group_member (asection *sec, asection *group,
+ struct bfd_link_info *info)
+{
+ asection *first = elf_next_in_group (group);
+ asection *s = first;
+
+ while (s != NULL)
+ {
+ if (bfd_elf_match_symbols_in_sections (s, sec, info))
+ return s;
+
+ s = elf_next_in_group (s);
+ if (s == first)
+ break;
+ }
+
+ return NULL;
+}
+
+/* Check if the kept section of a discarded section SEC can be used
+ to replace it. Return the replacement if it is OK. Otherwise return
+ NULL. */
+
+asection *
+_bfd_elf_check_kept_section (asection *sec, struct bfd_link_info *info)
+{
+ asection *kept;
+
+ kept = sec->kept_section;
+ if (kept != NULL)
+ {
+ if ((kept->flags & SEC_GROUP) != 0)
+ kept = match_group_member (sec, kept, info);
+ if (kept != NULL
+ && ((sec->rawsize != 0 ? sec->rawsize : sec->size)
+ != (kept->rawsize != 0 ? kept->rawsize : kept->size)))
+ kept = NULL;
+ sec->kept_section = kept;
+ }
+ return kept;
+}
+
+/* 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 bfd_boolean
+elf_link_input_bfd (struct elf_final_link_info *flinfo, bfd *input_bfd)
+{
+ int (*relocate_section)
+ (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_Internal_Sym *isymbuf;
+ Elf_Internal_Sym *isym;
+ Elf_Internal_Sym *isymend;
+ long *pindex;
+ asection **ppsection;
+ asection *o;
+ const struct elf_backend_data *bed;
+ struct elf_link_hash_entry **sym_hashes;
+ bfd_size_type address_size;
+ bfd_vma r_type_mask;
+ int r_sym_shift;
+ bfd_boolean have_file_sym = FALSE;
+
+ output_bfd = flinfo->output_bfd;
+ bed = get_elf_backend_data (output_bfd);
+ relocate_section = bed->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 / bed->s->sizeof_sym;
+ extsymoff = 0;
+ }
+ else
+ {
+ locsymcount = symtab_hdr->sh_info;
+ extsymoff = symtab_hdr->sh_info;
+ }
+
+ /* Read the local symbols. */
+ isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
+ if (isymbuf == NULL && locsymcount != 0)
+ {
+ isymbuf = bfd_elf_get_elf_syms (input_bfd, symtab_hdr, locsymcount, 0,
+ flinfo->internal_syms,
+ flinfo->external_syms,
+ flinfo->locsym_shndx);
+ if (isymbuf == NULL)
+ return FALSE;
+ }
+
+ /* Find local symbol sections and adjust values of symbols in
+ SEC_MERGE sections. Write out those local symbols we know are
+ going into the output file. */
+ isymend = isymbuf + locsymcount;
+ for (isym = isymbuf, pindex = flinfo->indices, ppsection = flinfo->sections;
+ isym < isymend;
+ isym++, pindex++, ppsection++)
+ {
+ asection *isec;
+ const char *name;
+ Elf_Internal_Sym osym;
+ long indx;
+ int ret;
+
+ *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 == SHN_ABS)
+ isec = bfd_abs_section_ptr;
+ else if (isym->st_shndx == SHN_COMMON)
+ isec = bfd_com_section_ptr;
+ else
+ {
+ isec = bfd_section_from_elf_index (input_bfd, isym->st_shndx);
+ if (isec == NULL)
+ {
+ /* Don't attempt to output symbols with st_shnx in the
+ reserved range other than SHN_ABS and SHN_COMMON. */
+ *ppsection = NULL;
+ continue;
+ }
+ else if (isec->sec_info_type == SEC_INFO_TYPE_MERGE
+ && ELF_ST_TYPE (isym->st_info) != STT_SECTION)
+ isym->st_value =
+ _bfd_merged_section_offset (output_bfd, &isec,
+ elf_section_data (isec)->sec_info,
+ isym->st_value);
+ }
+
+ *ppsection = isec;
+
+ /* Don't output the first, undefined, symbol. */
+ if (ppsection == flinfo->sections)
+ continue;
+
+ if (ELF_ST_TYPE (isym->st_info) == STT_SECTION)
+ {
+ /* We never output section symbols. Instead, we use the
+ section symbol of the corresponding section in the output
+ file. */
+ continue;
+ }
+
+ /* If we are stripping all symbols, we don't want to output this
+ one. */
+ if (flinfo->info->strip == strip_all)
+ continue;
+
+ /* If we are discarding all local symbols, we don't want to
+ output this one. If we are generating a relocatable 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 (flinfo->info->discard == discard_all)
+ continue;
+
+ /* If this symbol is defined in a section which we are
+ discarding, we don't need to keep it. */
+ if (isym->st_shndx != SHN_UNDEF
+ && isym->st_shndx < SHN_LORESERVE
+ && bfd_section_removed_from_list (output_bfd,
+ isec->output_section))
+ 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 ((flinfo->info->strip == strip_some
+ && (bfd_hash_lookup (flinfo->info->keep_hash, name, FALSE, FALSE)
+ == NULL))
+ || (((flinfo->info->discard == discard_sec_merge
+ && (isec->flags & SEC_MERGE) && !flinfo->info->relocatable)
+ || flinfo->info->discard == discard_l)
+ && bfd_is_local_label_name (input_bfd, name)))
+ continue;
+
+ if (ELF_ST_TYPE (isym->st_info) == STT_FILE)
+ {
+ have_file_sym = TRUE;
+ flinfo->filesym_count += 1;
+ }
+ if (!have_file_sym)
+ {
+ /* In the absence of debug info, bfd_find_nearest_line uses
+ FILE symbols to determine the source file for local
+ function symbols. Provide a FILE symbol here if input
+ files lack such, so that their symbols won't be
+ associated with a previous input file. It's not the
+ source file, but the best we can do. */
+ have_file_sym = TRUE;
+ flinfo->filesym_count += 1;
+ memset (&osym, 0, sizeof (osym));
+ osym.st_info = ELF_ST_INFO (STB_LOCAL, STT_FILE);
+ osym.st_shndx = SHN_ABS;
+ if (!elf_link_output_sym (flinfo, input_bfd->filename, &osym,
+ bfd_abs_section_ptr, NULL))
+ return FALSE;
+ }
+
+ 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 == SHN_BAD)
+ return FALSE;
+
+ /* ELF symbols in relocatable 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 (!flinfo->info->relocatable)
+ {
+ osym.st_value += isec->output_section->vma;
+ if (ELF_ST_TYPE (osym.st_info) == STT_TLS)
+ {
+ /* STT_TLS symbols are relative to PT_TLS segment base. */
+ BFD_ASSERT (elf_hash_table (flinfo->info)->tls_sec != NULL);
+ osym.st_value -= elf_hash_table (flinfo->info)->tls_sec->vma;
+ }
+ }
+
+ indx = bfd_get_symcount (output_bfd);
+ ret = elf_link_output_sym (flinfo, name, &osym, isec, NULL);
+ if (ret == 0)
+ return FALSE;
+ else if (ret == 1)
+ *pindex = indx;
+ }
+
+ if (bed->s->arch_size == 32)
+ {
+ r_type_mask = 0xff;
+ r_sym_shift = 8;
+ address_size = 4;
+ }
+ else
+ {
+ r_type_mask = 0xffffffff;
+ r_sym_shift = 32;
+ address_size = 8;
+ }
+
+ /* Relocate the contents of each section. */
+ sym_hashes = elf_sym_hashes (input_bfd);
+ 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 (flinfo->info->relocatable
+ && (o->flags & (SEC_LINKER_CREATED | SEC_GROUP)) == SEC_GROUP)
+ {
+ /* Deal with the group signature symbol. */
+ struct bfd_elf_section_data *sec_data = elf_section_data (o);
+ unsigned long symndx = sec_data->this_hdr.sh_info;
+ asection *osec = o->output_section;
+
+ if (symndx >= locsymcount
+ || (elf_bad_symtab (input_bfd)
+ && flinfo->sections[symndx] == NULL))
+ {
+ struct elf_link_hash_entry *h = sym_hashes[symndx - extsymoff];
+ 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;
+ /* Arrange for symbol to be output. */
+ h->indx = -2;
+ elf_section_data (osec)->this_hdr.sh_info = -2;
+ }
+ else if (ELF_ST_TYPE (isymbuf[symndx].st_info) == STT_SECTION)
+ {
+ /* We'll use the output section target_index. */
+ asection *sec = flinfo->sections[symndx]->output_section;
+ elf_section_data (osec)->this_hdr.sh_info = sec->target_index;
+ }
+ else
+ {
+ if (flinfo->indices[symndx] == -1)
+ {
+ /* Otherwise output the local symbol now. */
+ Elf_Internal_Sym sym = isymbuf[symndx];
+ asection *sec = flinfo->sections[symndx]->output_section;
+ const char *name;
+ long indx;
+ int ret;
+
+ name = bfd_elf_string_from_elf_section (input_bfd,
+ symtab_hdr->sh_link,
+ sym.st_name);
+ if (name == NULL)
+ return FALSE;
+
+ sym.st_shndx = _bfd_elf_section_from_bfd_section (output_bfd,
+ sec);
+ if (sym.st_shndx == SHN_BAD)
+ return FALSE;
+
+ sym.st_value += o->output_offset;
+
+ indx = bfd_get_symcount (output_bfd);
+ ret = elf_link_output_sym (flinfo, name, &sym, o, NULL);
+ if (ret == 0)
+ return FALSE;
+ else if (ret == 1)
+ flinfo->indices[symndx] = indx;
+ else
+ abort ();
+ }
+ elf_section_data (osec)->this_hdr.sh_info
+ = flinfo->indices[symndx];
+ }
+ }
+
+ if ((o->flags & SEC_HAS_CONTENTS) == 0
+ || (o->size == 0 && (o->flags & SEC_RELOC) == 0))
+ continue;
+
+ if ((o->flags & SEC_LINKER_CREATED) != 0)
+ {
+ /* Section was created by _bfd_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;
+ if (bed->caches_rawsize
+ && o->rawsize != 0
+ && o->rawsize < o->size)
+ {
+ memcpy (flinfo->contents, contents, o->rawsize);
+ contents = flinfo->contents;
+ }
+ }
+ else
+ {
+ contents = flinfo->contents;
+ if (! bfd_get_full_section_contents (input_bfd, o, &contents))
+ return FALSE;
+ }
+
+ if ((o->flags & SEC_RELOC) != 0)
+ {
+ Elf_Internal_Rela *internal_relocs;
+ Elf_Internal_Rela *rel, *relend;
+ int action_discarded;
+ int ret;
+
+ /* Get the swapped relocs. */
+ internal_relocs
+ = _bfd_elf_link_read_relocs (input_bfd, o, flinfo->external_relocs,
+ flinfo->internal_relocs, FALSE);
+ if (internal_relocs == NULL
+ && o->reloc_count > 0)
+ return FALSE;
+
+ /* We need to reverse-copy input .ctors/.dtors sections if
+ they are placed in .init_array/.finit_array for output. */
+ if (o->size > address_size
+ && ((strncmp (o->name, ".ctors", 6) == 0
+ && strcmp (o->output_section->name,
+ ".init_array") == 0)
+ || (strncmp (o->name, ".dtors", 6) == 0
+ && strcmp (o->output_section->name,
+ ".fini_array") == 0))
+ && (o->name[6] == 0 || o->name[6] == '.'))
+ {
+ if (o->size != o->reloc_count * address_size)
+ {
+ (*_bfd_error_handler)
+ (_("error: %B: size of section %A is not "
+ "multiple of address size"),
+ input_bfd, o);
+ bfd_set_error (bfd_error_on_input);
+ return FALSE;
+ }
+ o->flags |= SEC_ELF_REVERSE_COPY;
+ }
+
+ action_discarded = -1;
+ if (!elf_section_ignore_discarded_relocs (o))
+ action_discarded = (*bed->action_discarded) (o);
+
+ /* Run through the relocs evaluating complex reloc symbols and
+ looking for relocs against symbols from discarded sections
+ or section symbols from removed link-once sections.
+ Complain about relocs against discarded sections. Zero
+ relocs against removed link-once sections. */
+
+ rel = internal_relocs;
+ relend = rel + o->reloc_count * bed->s->int_rels_per_ext_rel;
+ for ( ; rel < relend; rel++)
+ {
+ unsigned long r_symndx = rel->r_info >> r_sym_shift;
+ unsigned int s_type;
+ asection **ps, *sec;
+ struct elf_link_hash_entry *h = NULL;
+ const char *sym_name;
+
+ if (r_symndx == STN_UNDEF)
+ continue;
+
+ if (r_symndx >= locsymcount
+ || (elf_bad_symtab (input_bfd)
+ && flinfo->sections[r_symndx] == NULL))
+ {
+ h = sym_hashes[r_symndx - extsymoff];
+
+ /* Badly formatted input files can contain relocs that
+ reference non-existant symbols. Check here so that
+ we do not seg fault. */
+ if (h == NULL)
+ {
+ char buffer [32];
+
+ sprintf_vma (buffer, rel->r_info);
+ (*_bfd_error_handler)
+ (_("error: %B contains a reloc (0x%s) for section %A "
+ "that references a non-existent global symbol"),
+ input_bfd, o, buffer);
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+
+ 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;
+
+ s_type = h->type;
+
+ ps = NULL;
+ if (h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak)
+ ps = &h->root.u.def.section;
+
+ sym_name = h->root.root.string;
+ }
+ else
+ {
+ Elf_Internal_Sym *sym = isymbuf + r_symndx;
+
+ s_type = ELF_ST_TYPE (sym->st_info);
+ ps = &flinfo->sections[r_symndx];
+ sym_name = bfd_elf_sym_name (input_bfd, symtab_hdr,
+ sym, *ps);
+ }
+
+ if ((s_type == STT_RELC || s_type == STT_SRELC)
+ && !flinfo->info->relocatable)
+ {
+ bfd_vma val;
+ bfd_vma dot = (rel->r_offset
+ + o->output_offset + o->output_section->vma);
+#ifdef DEBUG
+ printf ("Encountered a complex symbol!");
+ printf (" (input_bfd %s, section %s, reloc %ld\n",
+ input_bfd->filename, o->name,
+ (long) (rel - internal_relocs));
+ printf (" symbol: idx %8.8lx, name %s\n",
+ r_symndx, sym_name);
+ printf (" reloc : info %8.8lx, addr %8.8lx\n",
+ (unsigned long) rel->r_info,
+ (unsigned long) rel->r_offset);
+#endif
+ if (!eval_symbol (&val, &sym_name, input_bfd, flinfo, dot,
+ isymbuf, locsymcount, s_type == STT_SRELC))
+ return FALSE;
+
+ /* Symbol evaluated OK. Update to absolute value. */
+ set_symbol_value (input_bfd, isymbuf, locsymcount,
+ r_symndx, val);
+ continue;
+ }
+
+ if (action_discarded != -1 && ps != NULL)
+ {
+ /* Complain if the definition comes from a
+ discarded section. */
+ if ((sec = *ps) != NULL && discarded_section (sec))
+ {
+ BFD_ASSERT (r_symndx != STN_UNDEF);
+ if (action_discarded & COMPLAIN)
+ (*flinfo->info->callbacks->einfo)
+ (_("%X`%s' referenced in section `%A' of %B: "
+ "defined in discarded section `%A' of %B\n"),
+ sym_name, o, input_bfd, sec, sec->owner);
+
+ /* Try to do the best we can to support buggy old
+ versions of gcc. Pretend that the symbol is
+ really defined in the kept linkonce section.
+ FIXME: This is quite broken. Modifying the
+ symbol here means we will be changing all later
+ uses of the symbol, not just in this section. */
+ if (action_discarded & PRETEND)
+ {
+ asection *kept;
+
+ kept = _bfd_elf_check_kept_section (sec,
+ flinfo->info);
+ if (kept != NULL)
+ {
+ *ps = kept;
+ continue;
+ }
+ }
+ }
+ }
+ }
+
+ /* 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 relocatable 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 relocatable 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. */
+
+ ret = (*relocate_section) (output_bfd, flinfo->info,
+ input_bfd, o, contents,
+ internal_relocs,
+ isymbuf,
+ flinfo->sections);
+ if (!ret)
+ return FALSE;
+
+ if (ret == 2
+ || flinfo->info->relocatable
+ || flinfo->info->emitrelocations)
+ {
+ Elf_Internal_Rela *irela;
+ Elf_Internal_Rela *irelaend, *irelamid;
+ bfd_vma last_offset;
+ struct elf_link_hash_entry **rel_hash;
+ struct elf_link_hash_entry **rel_hash_list, **rela_hash_list;
+ Elf_Internal_Shdr *input_rel_hdr, *input_rela_hdr;
+ unsigned int next_erel;
+ bfd_boolean rela_normal;
+ struct bfd_elf_section_data *esdi, *esdo;
+
+ esdi = elf_section_data (o);
+ esdo = elf_section_data (o->output_section);
+ rela_normal = FALSE;
+
+ /* Adjust the reloc addresses and symbol indices. */
+
+ irela = internal_relocs;
+ irelaend = irela + o->reloc_count * bed->s->int_rels_per_ext_rel;
+ rel_hash = esdo->rel.hashes + esdo->rel.count;
+ /* We start processing the REL relocs, if any. When we reach
+ IRELAMID in the loop, we switch to the RELA relocs. */
+ irelamid = irela;
+ if (esdi->rel.hdr != NULL)
+ irelamid += (NUM_SHDR_ENTRIES (esdi->rel.hdr)
+ * bed->s->int_rels_per_ext_rel);
+ rel_hash_list = rel_hash;
+ rela_hash_list = NULL;
+ last_offset = o->output_offset;
+ if (!flinfo->info->relocatable)
+ last_offset += o->output_section->vma;
+ for (next_erel = 0; irela < irelaend; irela++, next_erel++)
+ {
+ unsigned long r_symndx;
+ asection *sec;
+ Elf_Internal_Sym sym;
+
+ if (next_erel == bed->s->int_rels_per_ext_rel)
+ {
+ rel_hash++;
+ next_erel = 0;
+ }
+
+ if (irela == irelamid)
+ {
+ rel_hash = esdo->rela.hashes + esdo->rela.count;
+ rela_hash_list = rel_hash;
+ rela_normal = bed->rela_normal;
+ }
+
+ irela->r_offset = _bfd_elf_section_offset (output_bfd,
+ flinfo->info, o,
+ irela->r_offset);
+ if (irela->r_offset >= (bfd_vma) -2)
+ {
+ /* This is a reloc for a deleted entry or somesuch.
+ Turn it into an R_*_NONE reloc, at the same
+ offset as the last reloc. elf_eh_frame.c and
+ bfd_elf_discard_info rely on reloc offsets
+ being ordered. */
+ irela->r_offset = last_offset;
+ irela->r_info = 0;
+ irela->r_addend = 0;
+ continue;
+ }
+
+ irela->r_offset += o->output_offset;
+
+ /* Relocs in an executable have to be virtual addresses. */
+ if (!flinfo->info->relocatable)
+ irela->r_offset += o->output_section->vma;
+
+ last_offset = irela->r_offset;
+
+ r_symndx = irela->r_info >> r_sym_shift;
+ if (r_symndx == STN_UNDEF)
+ continue;
+
+ if (r_symndx >= locsymcount
+ || (elf_bad_symtab (input_bfd)
+ && flinfo->sections[r_symndx] == NULL))
+ {
+ struct elf_link_hash_entry *rh;
+ unsigned 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 bfd_elf_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;
+ sym = isymbuf[r_symndx];
+ sec = flinfo->sections[r_symndx];
+ if (ELF_ST_TYPE (sym.st_info) == STT_SECTION)
+ {
+ /* I suppose the backend ought to fill in the
+ section of any STT_SECTION symbol against a
+ processor specific section. */
+ r_symndx = STN_UNDEF;
+ if (bfd_is_abs_section (sec))
+ ;
+ else if (sec == NULL || sec->owner == NULL)
+ {
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+ else
+ {
+ asection *osec = sec->output_section;
+
+ /* If we have discarded a section, the output
+ section will be the absolute section. In
+ case of discarded SEC_MERGE sections, use
+ the kept section. relocate_section should
+ have already handled discarded linkonce
+ sections. */
+ if (bfd_is_abs_section (osec)
+ && sec->kept_section != NULL
+ && sec->kept_section->output_section != NULL)
+ {
+ osec = sec->kept_section->output_section;
+ irela->r_addend -= osec->vma;
+ }
+
+ if (!bfd_is_abs_section (osec))
+ {
+ r_symndx = osec->target_index;
+ if (r_symndx == STN_UNDEF)
+ {
+ irela->r_addend += osec->vma;
+ osec = _bfd_nearby_section (output_bfd, osec,
+ osec->vma);
+ irela->r_addend -= osec->vma;
+ r_symndx = osec->target_index;
+ }
+ }
+ }
+
+ /* Adjust the addend according to where the
+ section winds up in the output section. */
+ if (rela_normal)
+ irela->r_addend += sec->output_offset;
+ }
+ else
+ {
+ if (flinfo->indices[r_symndx] == -1)
+ {
+ unsigned long shlink;
+ const char *name;
+ asection *osec;
+ long indx;
+
+ if (flinfo->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. */
+ shlink = symtab_hdr->sh_link;
+ name = (bfd_elf_string_from_elf_section
+ (input_bfd, shlink, sym.st_name));
+ if (name == NULL)
+ return FALSE;
+
+ osec = sec->output_section;
+ sym.st_shndx =
+ _bfd_elf_section_from_bfd_section (output_bfd,
+ osec);
+ if (sym.st_shndx == SHN_BAD)
+ return FALSE;
+
+ sym.st_value += sec->output_offset;
+ if (!flinfo->info->relocatable)
+ {
+ sym.st_value += osec->vma;
+ if (ELF_ST_TYPE (sym.st_info) == STT_TLS)
+ {
+ /* STT_TLS symbols are relative to PT_TLS
+ segment base. */
+ BFD_ASSERT (elf_hash_table (flinfo->info)
+ ->tls_sec != NULL);
+ sym.st_value -= (elf_hash_table (flinfo->info)
+ ->tls_sec->vma);
+ }
+ }
+
+ indx = bfd_get_symcount (output_bfd);
+ ret = elf_link_output_sym (flinfo, name, &sym, sec,
+ NULL);
+ if (ret == 0)
+ return FALSE;
+ else if (ret == 1)
+ flinfo->indices[r_symndx] = indx;
+ else
+ abort ();
+ }
+
+ r_symndx = flinfo->indices[r_symndx];
+ }
+
+ irela->r_info = ((bfd_vma) r_symndx << r_sym_shift
+ | (irela->r_info & r_type_mask));
+ }
+
+ /* Swap out the relocs. */
+ input_rel_hdr = esdi->rel.hdr;
+ if (input_rel_hdr && input_rel_hdr->sh_size != 0)
+ {
+ if (!bed->elf_backend_emit_relocs (output_bfd, o,
+ input_rel_hdr,
+ internal_relocs,
+ rel_hash_list))
+ return FALSE;
+ internal_relocs += (NUM_SHDR_ENTRIES (input_rel_hdr)
+ * bed->s->int_rels_per_ext_rel);
+ rel_hash_list += NUM_SHDR_ENTRIES (input_rel_hdr);
+ }
+
+ input_rela_hdr = esdi->rela.hdr;
+ if (input_rela_hdr && input_rela_hdr->sh_size != 0)
+ {
+ if (!bed->elf_backend_emit_relocs (output_bfd, o,
+ input_rela_hdr,
+ internal_relocs,
+ rela_hash_list))
+ return FALSE;
+ }
+ }
+ }
+
+ /* Write out the modified section contents. */
+ if (bed->elf_backend_write_section
+ && (*bed->elf_backend_write_section) (output_bfd, flinfo->info, o,
+ contents))
+ {
+ /* Section written out. */
+ }
+ else switch (o->sec_info_type)
+ {
+ case SEC_INFO_TYPE_STABS:
+ if (! (_bfd_write_section_stabs
+ (output_bfd,
+ &elf_hash_table (flinfo->info)->stab_info,
+ o, &elf_section_data (o)->sec_info, contents)))
+ return FALSE;
+ break;
+ case SEC_INFO_TYPE_MERGE:
+ if (! _bfd_write_merged_section (output_bfd, o,
+ elf_section_data (o)->sec_info))
+ return FALSE;
+ break;
+ case SEC_INFO_TYPE_EH_FRAME:
+ {
+ if (! _bfd_elf_write_section_eh_frame (output_bfd, flinfo->info,
+ o, contents))
+ return FALSE;
+ }
+ break;
+ default:
+ {
+ /* FIXME: octets_per_byte. */
+ if (! (o->flags & SEC_EXCLUDE))
+ {
+ file_ptr offset = (file_ptr) o->output_offset;
+ bfd_size_type todo = o->size;
+ if ((o->flags & SEC_ELF_REVERSE_COPY))
+ {
+ /* Reverse-copy input section to output. */
+ do
+ {
+ todo -= address_size;
+ if (! bfd_set_section_contents (output_bfd,
+ o->output_section,
+ contents + todo,
+ offset,
+ address_size))
+ return FALSE;
+ if (todo == 0)
+ break;
+ offset += address_size;
+ }
+ while (1);
+ }
+ else if (! bfd_set_section_contents (output_bfd,
+ o->output_section,
+ contents,
+ offset, todo))
+ return FALSE;
+ }
+ }
+ break;
+ }
+ }
+
+ return TRUE;
+}
+
+/* Generate a reloc when linking an ELF file. This is a reloc
+ requested by the linker, and does not come from any input file. This
+ is used to build constructor and destructor tables when linking
+ with -Ur. */
+
+static bfd_boolean
+elf_reloc_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 bfd_elf_section_reloc_data *reldata;
+ struct elf_link_hash_entry **rel_hash_ptr;
+ Elf_Internal_Shdr *rel_hdr;
+ const struct elf_backend_data *bed = get_elf_backend_data (output_bfd);
+ Elf_Internal_Rela irel[MAX_INT_RELS_PER_EXT_REL];
+ bfd_byte *erel;
+ unsigned int i;
+ struct bfd_elf_section_data *esdo = elf_section_data (output_section);
+
+ 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;
+
+ if (esdo->rel.hdr)
+ reldata = &esdo->rel;
+ else if (esdo->rela.hdr)
+ reldata = &esdo->rela;
+ else
+ {
+ reldata = NULL;
+ BFD_ASSERT (0);
+ }
+
+ /* Figure out the symbol index. */
+ rel_hash_ptr = reldata->hashes + reldata->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, NULL, NULL, 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;
+ bfd_boolean ok;
+ const char *sym_name;
+
+ size = (bfd_size_type) 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 (link_order->type == bfd_section_reloc_link_order)
+ sym_name = bfd_section_name (output_bfd,
+ link_order->u.reloc.p->u.section);
+ else
+ sym_name = link_order->u.reloc.p->u.name;
+ if (! ((*info->callbacks->reloc_overflow)
+ (info, NULL, sym_name, howto->name, addend, NULL,
+ NULL, (bfd_vma) 0)))
+ {
+ free (buf);
+ return FALSE;
+ }
+ break;
+ }
+ ok = bfd_set_section_contents (output_bfd, output_section, buf,
+ link_order->offset, size);
+ free (buf);
+ if (! ok)
+ return FALSE;
+ }
+
+ /* The address of a reloc is relative to the section in a
+ relocatable file, and is a virtual address in an executable
+ file. */
+ offset = link_order->offset;
+ if (! info->relocatable)
+ offset += output_section->vma;
+
+ for (i = 0; i < bed->s->int_rels_per_ext_rel; i++)
+ {
+ irel[i].r_offset = offset;
+ irel[i].r_info = 0;
+ irel[i].r_addend = 0;
+ }
+ if (bed->s->arch_size == 32)
+ irel[0].r_info = ELF32_R_INFO (indx, howto->type);
+ else
+ irel[0].r_info = ELF64_R_INFO (indx, howto->type);
+
+ rel_hdr = reldata->hdr;
+ erel = rel_hdr->contents;
+ if (rel_hdr->sh_type == SHT_REL)
+ {
+ erel += reldata->count * bed->s->sizeof_rel;
+ (*bed->s->swap_reloc_out) (output_bfd, irel, erel);
+ }
+ else
+ {
+ irel[0].r_addend = addend;
+ erel += reldata->count * bed->s->sizeof_rela;
+ (*bed->s->swap_reloca_out) (output_bfd, irel, erel);
+ }
+
+ ++reldata->count;
+
+ return TRUE;
+}
+
+
+/* Get the output vma of the section pointed to by the sh_link field. */
+
+static bfd_vma
+elf_get_linked_section_vma (struct bfd_link_order *p)
+{
+ Elf_Internal_Shdr **elf_shdrp;
+ asection *s;
+ int elfsec;
+
+ s = p->u.indirect.section;
+ elf_shdrp = elf_elfsections (s->owner);
+ elfsec = _bfd_elf_section_from_bfd_section (s->owner, s);
+ elfsec = elf_shdrp[elfsec]->sh_link;
+ /* PR 290:
+ The Intel C compiler generates SHT_IA_64_UNWIND with
+ SHF_LINK_ORDER. But it doesn't set the sh_link or
+ sh_info fields. Hence we could get the situation
+ where elfsec is 0. */
+ if (elfsec == 0)
+ {
+ const struct elf_backend_data *bed
+ = get_elf_backend_data (s->owner);
+ if (bed->link_order_error_handler)
+ bed->link_order_error_handler
+ (_("%B: warning: sh_link not set for section `%A'"), s->owner, s);
+ return 0;
+ }
+ else
+ {
+ s = elf_shdrp[elfsec]->bfd_section;
+ return s->output_section->vma + s->output_offset;
+ }
+}
+
+
+/* Compare two sections based on the locations of the sections they are
+ linked to. Used by elf_fixup_link_order. */
+
+static int
+compare_link_order (const void * a, const void * b)
+{
+ bfd_vma apos;
+ bfd_vma bpos;
+
+ apos = elf_get_linked_section_vma (*(struct bfd_link_order **)a);
+ bpos = elf_get_linked_section_vma (*(struct bfd_link_order **)b);
+ if (apos < bpos)
+ return -1;
+ return apos > bpos;
+}
+
+
+/* Looks for sections with SHF_LINK_ORDER set. Rearranges them into the same
+ order as their linked sections. Returns false if this could not be done
+ because an output section includes both ordered and unordered
+ sections. Ideally we'd do this in the linker proper. */
+
+static bfd_boolean
+elf_fixup_link_order (bfd *abfd, asection *o)
+{
+ int seen_linkorder;
+ int seen_other;
+ int n;
+ struct bfd_link_order *p;
+ bfd *sub;
+ const struct elf_backend_data *bed = get_elf_backend_data (abfd);
+ unsigned elfsec;
+ struct bfd_link_order **sections;
+ asection *s, *other_sec, *linkorder_sec;
+ bfd_vma offset;
+
+ other_sec = NULL;
+ linkorder_sec = NULL;
+ seen_other = 0;
+ seen_linkorder = 0;
+ for (p = o->map_head.link_order; p != NULL; p = p->next)
+ {
+ if (p->type == bfd_indirect_link_order)
+ {
+ s = p->u.indirect.section;
+ sub = s->owner;
+ if (bfd_get_flavour (sub) == bfd_target_elf_flavour
+ && elf_elfheader (sub)->e_ident[EI_CLASS] == bed->s->elfclass
+ && (elfsec = _bfd_elf_section_from_bfd_section (sub, s))
+ && elfsec < elf_numsections (sub)
+ && elf_elfsections (sub)[elfsec]->sh_flags & SHF_LINK_ORDER
+ && elf_elfsections (sub)[elfsec]->sh_link < elf_numsections (sub))
+ {
+ seen_linkorder++;
+ linkorder_sec = s;
+ }
+ else
+ {
+ seen_other++;
+ other_sec = s;
+ }
+ }
+ else
+ seen_other++;
+
+ if (seen_other && seen_linkorder)
+ {
+ if (other_sec && linkorder_sec)
+ (*_bfd_error_handler) (_("%A has both ordered [`%A' in %B] and unordered [`%A' in %B] sections"),
+ o, linkorder_sec,
+ linkorder_sec->owner, other_sec,
+ other_sec->owner);
+ else
+ (*_bfd_error_handler) (_("%A has both ordered and unordered sections"),
+ o);
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+ }
+
+ if (!seen_linkorder)
+ return TRUE;
+
+ sections = (struct bfd_link_order **)
+ bfd_malloc (seen_linkorder * sizeof (struct bfd_link_order *));
+ if (sections == NULL)
+ return FALSE;
+ seen_linkorder = 0;
+
+ for (p = o->map_head.link_order; p != NULL; p = p->next)
+ {
+ sections[seen_linkorder++] = p;
+ }
+ /* Sort the input sections in the order of their linked section. */
+ qsort (sections, seen_linkorder, sizeof (struct bfd_link_order *),
+ compare_link_order);
+
+ /* Change the offsets of the sections. */
+ offset = 0;
+ for (n = 0; n < seen_linkorder; n++)
+ {
+ s = sections[n]->u.indirect.section;
+ offset &= ~(bfd_vma) 0 << s->alignment_power;
+ s->output_offset = offset;
+ sections[n]->offset = offset;
+ /* FIXME: octets_per_byte. */
+ offset += sections[n]->size;
+ }
+
+ free (sections);
+ return TRUE;
+}
+
+static void
+elf_final_link_free (bfd *obfd, struct elf_final_link_info *flinfo)
+{
+ asection *o;
+
+ if (flinfo->symstrtab != NULL)
+ _bfd_stringtab_free (flinfo->symstrtab);
+ if (flinfo->contents != NULL)
+ free (flinfo->contents);
+ if (flinfo->external_relocs != NULL)
+ free (flinfo->external_relocs);
+ if (flinfo->internal_relocs != NULL)
+ free (flinfo->internal_relocs);
+ if (flinfo->external_syms != NULL)
+ free (flinfo->external_syms);
+ if (flinfo->locsym_shndx != NULL)
+ free (flinfo->locsym_shndx);
+ if (flinfo->internal_syms != NULL)
+ free (flinfo->internal_syms);
+ if (flinfo->indices != NULL)
+ free (flinfo->indices);
+ if (flinfo->sections != NULL)
+ free (flinfo->sections);
+ if (flinfo->symbuf != NULL)
+ free (flinfo->symbuf);
+ if (flinfo->symshndxbuf != NULL)
+ free (flinfo->symshndxbuf);
+ for (o = obfd->sections; o != NULL; o = o->next)
+ {
+ struct bfd_elf_section_data *esdo = elf_section_data (o);
+ if ((o->flags & SEC_RELOC) != 0 && esdo->rel.hashes != NULL)
+ free (esdo->rel.hashes);
+ if ((o->flags & SEC_RELOC) != 0 && esdo->rela.hashes != NULL)
+ free (esdo->rela.hashes);
+ }
+}
+
+/* Do the final step of an ELF link. */
+
+bfd_boolean
+bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info)
+{
+ bfd_boolean dynamic;
+ bfd_boolean emit_relocs;
+ bfd *dynobj;
+ struct elf_final_link_info flinfo;
+ asection *o;
+ struct bfd_link_order *p;
+ bfd *sub;
+ bfd_size_type max_contents_size;
+ bfd_size_type max_external_reloc_size;
+ bfd_size_type max_internal_reloc_count;
+ bfd_size_type max_sym_count;
+ bfd_size_type max_sym_shndx_count;
+ file_ptr off;
+ Elf_Internal_Sym elfsym;
+ unsigned int i;
+ Elf_Internal_Shdr *symtab_hdr;
+ Elf_Internal_Shdr *symtab_shndx_hdr;
+ Elf_Internal_Shdr *symstrtab_hdr;
+ const struct elf_backend_data *bed = get_elf_backend_data (abfd);
+ struct elf_outext_info eoinfo;
+ bfd_boolean merged;
+ size_t relativecount = 0;
+ asection *reldyn = 0;
+ bfd_size_type amt;
+ asection *attr_section = NULL;
+ bfd_vma attr_size = 0;
+ const char *std_attrs_section;
+
+ if (! is_elf_hash_table (info->hash))
+ return FALSE;
+
+ if (info->shared)
+ abfd->flags |= DYNAMIC;
+
+ dynamic = elf_hash_table (info)->dynamic_sections_created;
+ dynobj = elf_hash_table (info)->dynobj;
+
+ emit_relocs = (info->relocatable
+ || info->emitrelocations);
+
+ flinfo.info = info;
+ flinfo.output_bfd = abfd;
+ flinfo.symstrtab = _bfd_elf_stringtab_init ();
+ if (flinfo.symstrtab == NULL)
+ return FALSE;
+
+ if (! dynamic)
+ {
+ flinfo.dynsym_sec = NULL;
+ flinfo.hash_sec = NULL;
+ flinfo.symver_sec = NULL;
+ }
+ else
+ {
+ flinfo.dynsym_sec = bfd_get_linker_section (dynobj, ".dynsym");
+ flinfo.hash_sec = bfd_get_linker_section (dynobj, ".hash");
+ /* Note that dynsym_sec can be NULL (on VMS). */
+ flinfo.symver_sec = bfd_get_linker_section (dynobj, ".gnu.version");
+ /* Note that it is OK if symver_sec is NULL. */
+ }
+
+ flinfo.contents = NULL;
+ flinfo.external_relocs = NULL;
+ flinfo.internal_relocs = NULL;
+ flinfo.external_syms = NULL;
+ flinfo.locsym_shndx = NULL;
+ flinfo.internal_syms = NULL;
+ flinfo.indices = NULL;
+ flinfo.sections = NULL;
+ flinfo.symbuf = NULL;
+ flinfo.symshndxbuf = NULL;
+ flinfo.symbuf_count = 0;
+ flinfo.shndxbuf_size = 0;
+ flinfo.filesym_count = 0;
+
+ /* The object attributes have been merged. Remove the input
+ sections from the link, and set the contents of the output
+ secton. */
+ std_attrs_section = get_elf_backend_data (abfd)->obj_attrs_section;
+ for (o = abfd->sections; o != NULL; o = o->next)
+ {
+ if ((std_attrs_section && strcmp (o->name, std_attrs_section) == 0)
+ || strcmp (o->name, ".gnu.attributes") == 0)
+ {
+ for (p = o->map_head.link_order; p != NULL; p = p->next)
+ {
+ asection *input_section;
+
+ if (p->type != bfd_indirect_link_order)
+ continue;
+ 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;
+ }
+
+ attr_size = bfd_elf_obj_attr_size (abfd);
+ if (attr_size)
+ {
+ bfd_set_section_size (abfd, o, attr_size);
+ attr_section = o;
+ /* Skip this section later on. */
+ o->map_head.link_order = NULL;
+ }
+ else
+ o->flags |= SEC_EXCLUDE;
+ }
+ }
+
+ /* 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;
+ max_sym_shndx_count = 0;
+ merged = FALSE;
+ for (o = abfd->sections; o != NULL; o = o->next)
+ {
+ struct bfd_elf_section_data *esdo = elf_section_data (o);
+ o->reloc_count = 0;
+
+ for (p = o->map_head.link_order; p != NULL; p = p->next)
+ {
+ unsigned int reloc_count = 0;
+ struct bfd_elf_section_data *esdi = NULL;
+
+ if (p->type == bfd_section_reloc_link_order
+ || p->type == bfd_symbol_reloc_link_order)
+ reloc_count = 1;
+ else if (p->type == bfd_indirect_link_order)
+ {
+ asection *sec;
+
+ sec = p->u.indirect.section;
+ esdi = elf_section_data (sec);
+
+ /* 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 (sec->flags & SEC_MERGE)
+ merged = TRUE;
+
+ if (esdo->this_hdr.sh_type == SHT_REL
+ || esdo->this_hdr.sh_type == SHT_RELA)
+ /* Some backends use reloc_count in relocation sections
+ to count particular types of relocs. Of course,
+ reloc sections themselves can't have relocations. */
+ reloc_count = 0;
+ else if (info->relocatable || info->emitrelocations)
+ reloc_count = sec->reloc_count;
+ else if (bed->elf_backend_count_relocs)
+ reloc_count = (*bed->elf_backend_count_relocs) (info, sec);
+
+ if (sec->rawsize > max_contents_size)
+ max_contents_size = sec->rawsize;
+ if (sec->size > max_contents_size)
+ max_contents_size = sec->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
+ / bed->s->sizeof_sym);
+ else
+ sym_count = elf_tdata (sec->owner)->symtab_hdr.sh_info;
+
+ if (sym_count > max_sym_count)
+ max_sym_count = sym_count;
+
+ if (sym_count > max_sym_shndx_count
+ && elf_symtab_shndx (sec->owner) != 0)
+ max_sym_shndx_count = sym_count;
+
+ if ((sec->flags & SEC_RELOC) != 0)
+ {
+ size_t ext_size = 0;
+
+ if (esdi->rel.hdr != NULL)
+ ext_size = esdi->rel.hdr->sh_size;
+ if (esdi->rela.hdr != NULL)
+ ext_size += esdi->rela.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 (reloc_count == 0)
+ continue;
+
+ o->reloc_count += reloc_count;
+
+ if (p->type == bfd_indirect_link_order
+ && (info->relocatable || info->emitrelocations))
+ {
+ if (esdi->rel.hdr)
+ esdo->rel.count += NUM_SHDR_ENTRIES (esdi->rel.hdr);
+ if (esdi->rela.hdr)
+ esdo->rela.count += NUM_SHDR_ENTRIES (esdi->rela.hdr);
+ }
+ else
+ {
+ if (o->use_rela_p)
+ esdo->rela.count += reloc_count;
+ else
+ esdo->rel.count += 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;
+ }
+
+ if (! info->relocatable && merged)
+ elf_link_hash_traverse (elf_hash_table (info),
+ _bfd_elf_link_sec_merge_syms, abfd);
+
+ /* 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;
+
+ /* Set sizes, and assign file positions for reloc sections. */
+ for (o = abfd->sections; o != NULL; o = o->next)
+ {
+ struct bfd_elf_section_data *esdo = elf_section_data (o);
+ if ((o->flags & SEC_RELOC) != 0)
+ {
+ if (esdo->rel.hdr
+ && !(_bfd_elf_link_size_reloc_section (abfd, &esdo->rel)))
+ goto error_return;
+
+ if (esdo->rela.hdr
+ && !(_bfd_elf_link_size_reloc_section (abfd, &esdo->rela)))
+ goto error_return;
+ }
+
+ /* Now, reset REL_COUNT and REL_COUNT2 so that we can use them
+ to count upwards while actually outputting the relocations. */
+ esdo->rel.count = 0;
+ esdo->rela.count = 0;
+ }
+
+ /* We have now assigned file positions for all the sections except
+ .symtab, .strtab, and non-loaded reloc sections. 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;
+ /* sh_flags, sh_addr and sh_size all start off zero. */
+ symtab_hdr->sh_entsize = bed->s->sizeof_sym;
+ /* sh_link is set in assign_section_numbers. */
+ /* sh_info is set below. */
+ /* sh_offset is set just below. */
+ symtab_hdr->sh_addralign = (bfd_vma) 1 << bed->s->log_file_align;
+
+ off = elf_next_file_pos (abfd);
+ off = _bfd_elf_assign_file_position_for_section (symtab_hdr, off, TRUE);
+
+ /* Note that at this point elf_next_file_pos (abfd) 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)
+ flinfo.symbuf_size = 20;
+ else
+ flinfo.symbuf_size = max_sym_count;
+ amt = flinfo.symbuf_size;
+ amt *= bed->s->sizeof_sym;
+ flinfo.symbuf = (bfd_byte *) bfd_malloc (amt);
+ if (flinfo.symbuf == NULL)
+ goto error_return;
+ if (elf_numsections (abfd) > (SHN_LORESERVE & 0xFFFF))
+ {
+ /* Wild guess at number of output symbols. realloc'd as needed. */
+ amt = 2 * max_sym_count + elf_numsections (abfd) + 1000;
+ flinfo.shndxbuf_size = amt;
+ amt *= sizeof (Elf_External_Sym_Shndx);
+ flinfo.symshndxbuf = (Elf_External_Sym_Shndx *) bfd_zmalloc (amt);
+ if (flinfo.symshndxbuf == NULL)
+ goto error_return;
+ }
+
+ /* Start writing out the symbol table. The first symbol is always a
+ dummy symbol. */
+ if (info->strip != strip_all
+ || emit_relocs)
+ {
+ elfsym.st_value = 0;
+ elfsym.st_size = 0;
+ elfsym.st_info = 0;
+ elfsym.st_other = 0;
+ elfsym.st_shndx = SHN_UNDEF;
+ elfsym.st_target_internal = 0;
+ if (elf_link_output_sym (&flinfo, NULL, &elfsym, bfd_und_section_ptr,
+ NULL) != 1)
+ goto error_return;
+ }
+
+ /* 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
+ || emit_relocs)
+ {
+ elfsym.st_size = 0;
+ elfsym.st_info = ELF_ST_INFO (STB_LOCAL, STT_SECTION);
+ elfsym.st_other = 0;
+ elfsym.st_value = 0;
+ elfsym.st_target_internal = 0;
+ for (i = 1; i < elf_numsections (abfd); i++)
+ {
+ o = bfd_section_from_elf_index (abfd, i);
+ if (o != NULL)
+ {
+ o->target_index = bfd_get_symcount (abfd);
+ elfsym.st_shndx = i;
+ if (!info->relocatable)
+ elfsym.st_value = o->vma;
+ if (elf_link_output_sym (&flinfo, NULL, &elfsym, o, NULL) != 1)
+ goto error_return;
+ }
+ }
+ }
+
+ /* Allocate some memory to hold information read in from the input
+ files. */
+ if (max_contents_size != 0)
+ {
+ flinfo.contents = (bfd_byte *) bfd_malloc (max_contents_size);
+ if (flinfo.contents == NULL)
+ goto error_return;
+ }
+
+ if (max_external_reloc_size != 0)
+ {
+ flinfo.external_relocs = bfd_malloc (max_external_reloc_size);
+ if (flinfo.external_relocs == NULL)
+ goto error_return;
+ }
+
+ if (max_internal_reloc_count != 0)
+ {
+ amt = max_internal_reloc_count * bed->s->int_rels_per_ext_rel;
+ amt *= sizeof (Elf_Internal_Rela);
+ flinfo.internal_relocs = (Elf_Internal_Rela *) bfd_malloc (amt);
+ if (flinfo.internal_relocs == NULL)
+ goto error_return;
+ }
+
+ if (max_sym_count != 0)
+ {
+ amt = max_sym_count * bed->s->sizeof_sym;
+ flinfo.external_syms = (bfd_byte *) bfd_malloc (amt);
+ if (flinfo.external_syms == NULL)
+ goto error_return;
+
+ amt = max_sym_count * sizeof (Elf_Internal_Sym);
+ flinfo.internal_syms = (Elf_Internal_Sym *) bfd_malloc (amt);
+ if (flinfo.internal_syms == NULL)
+ goto error_return;
+
+ amt = max_sym_count * sizeof (long);
+ flinfo.indices = (long int *) bfd_malloc (amt);
+ if (flinfo.indices == NULL)
+ goto error_return;
+
+ amt = max_sym_count * sizeof (asection *);
+ flinfo.sections = (asection **) bfd_malloc (amt);
+ if (flinfo.sections == NULL)
+ goto error_return;
+ }
+
+ if (max_sym_shndx_count != 0)
+ {
+ amt = max_sym_shndx_count * sizeof (Elf_External_Sym_Shndx);
+ flinfo.locsym_shndx = (Elf_External_Sym_Shndx *) bfd_malloc (amt);
+ if (flinfo.locsym_shndx == NULL)
+ goto error_return;
+ }
+
+ if (elf_hash_table (info)->tls_sec)
+ {
+ bfd_vma base, end = 0;
+ asection *sec;
+
+ for (sec = elf_hash_table (info)->tls_sec;
+ sec && (sec->flags & SEC_THREAD_LOCAL);
+ sec = sec->next)
+ {
+ bfd_size_type size = sec->size;
+
+ if (size == 0
+ && (sec->flags & SEC_HAS_CONTENTS) == 0)
+ {
+ struct bfd_link_order *ord = sec->map_tail.link_order;
+
+ if (ord != NULL)
+ size = ord->offset + ord->size;
+ }
+ end = sec->vma + size;
+ }
+ base = elf_hash_table (info)->tls_sec->vma;
+ /* Only align end of TLS section if static TLS doesn't have special
+ alignment requirements. */
+ if (bed->static_tls_alignment == 1)
+ end = align_power (end,
+ elf_hash_table (info)->tls_sec->alignment_power);
+ elf_hash_table (info)->tls_size = end - base;
+ }
+
+ /* Reorder SHF_LINK_ORDER sections. */
+ for (o = abfd->sections; o != NULL; o = o->next)
+ {
+ if (!elf_fixup_link_order (abfd, o))
+ return FALSE;
+ }
+
+ /* 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 relocatable 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 relocatable
+ 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->map_head.link_order; p != NULL; p = p->next)
+ {
+ if (p->type == bfd_indirect_link_order
+ && (bfd_get_flavour ((sub = p->u.indirect.section->owner))
+ == bfd_target_elf_flavour)
+ && elf_elfheader (sub)->e_ident[EI_CLASS] == bed->s->elfclass)
+ {
+ if (! sub->output_has_begun)
+ {
+ if (! elf_link_input_bfd (&flinfo, 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))
+ {
+ if (p->type == bfd_indirect_link_order
+ && (bfd_get_flavour (sub)
+ == bfd_target_elf_flavour)
+ && (elf_elfheader (sub)->e_ident[EI_CLASS]
+ != bed->s->elfclass))
+ {
+ const char *iclass, *oclass;
+
+ if (bed->s->elfclass == ELFCLASS64)
+ {
+ iclass = "ELFCLASS32";
+ oclass = "ELFCLASS64";
+ }
+ else
+ {
+ iclass = "ELFCLASS64";
+ oclass = "ELFCLASS32";
+ }
+
+ bfd_set_error (bfd_error_wrong_format);
+ (*_bfd_error_handler)
+ (_("%B: file class %s incompatible with %s"),
+ sub, iclass, oclass);
+ }
+
+ goto error_return;
+ }
+ }
+ }
+ }
+
+ /* Free symbol buffer if needed. */
+ if (!info->reduce_memory_overheads)
+ {
+ for (sub = info->input_bfds; sub != NULL; sub = sub->link.next)
+ if (bfd_get_flavour (sub) == bfd_target_elf_flavour
+ && elf_tdata (sub)->symbuf)
+ {
+ free (elf_tdata (sub)->symbuf);
+ elf_tdata (sub)->symbuf = NULL;
+ }
+ }
+
+ /* Output any global symbols that got converted to local in a
+ version script or due to symbol visibility. 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.flinfo = &flinfo;
+ eoinfo.localsyms = TRUE;
+ eoinfo.need_second_pass = FALSE;
+ eoinfo.second_pass = FALSE;
+ eoinfo.file_sym_done = FALSE;
+ bfd_hash_traverse (&info->hash->table, elf_link_output_extsym, &eoinfo);
+ if (eoinfo.failed)
+ return FALSE;
+
+ if (eoinfo.need_second_pass)
+ {
+ eoinfo.second_pass = TRUE;
+ bfd_hash_traverse (&info->hash->table, elf_link_output_extsym, &eoinfo);
+ if (eoinfo.failed)
+ return FALSE;
+ }
+
+ /* If backend needs to output some local symbols not present in the hash
+ table, do it now. */
+ if (bed->elf_backend_output_arch_local_syms)
+ {
+ typedef int (*out_sym_func)
+ (void *, const char *, Elf_Internal_Sym *, asection *,
+ struct elf_link_hash_entry *);
+
+ if (! ((*bed->elf_backend_output_arch_local_syms)
+ (abfd, info, &flinfo, (out_sym_func) elf_link_output_sym)))
+ return FALSE;
+ }
+
+ /* That wrote out all the local symbols. Finish up the symbol table
+ with the global symbols. Even if we want to strip everything we
+ can, we still need to deal with those global symbols that got
+ converted to local in a version script. */
+
+ /* The sh_info field records the index of the first non local symbol. */
+ symtab_hdr->sh_info = bfd_get_symcount (abfd);
+
+ if (dynamic
+ && flinfo.dynsym_sec != NULL
+ && flinfo.dynsym_sec->output_section != bfd_abs_section_ptr)
+ {
+ Elf_Internal_Sym sym;
+ bfd_byte *dynsym = flinfo.dynsym_sec->contents;
+ long last_local = 0;
+
+ /* Write out the section symbols for the output sections. */
+ if (info->shared || elf_hash_table (info)->is_relocatable_executable)
+ {
+ asection *s;
+
+ sym.st_size = 0;
+ sym.st_name = 0;
+ sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_SECTION);
+ sym.st_other = 0;
+ sym.st_target_internal = 0;
+
+ for (s = abfd->sections; s != NULL; s = s->next)
+ {
+ int indx;
+ bfd_byte *dest;
+ long dynindx;
+
+ dynindx = elf_section_data (s)->dynindx;
+ if (dynindx <= 0)
+ continue;
+ indx = elf_section_data (s)->this_idx;
+ BFD_ASSERT (indx > 0);
+ sym.st_shndx = indx;
+ if (! check_dynsym (abfd, &sym))
+ return FALSE;
+ sym.st_value = s->vma;
+ dest = dynsym + dynindx * bed->s->sizeof_sym;
+ if (last_local < dynindx)
+ last_local = dynindx;
+ bed->s->swap_symbol_out (abfd, &sym, dest, 0);
+ }
+ }
+
+ /* Write out the local dynsyms. */
+ if (elf_hash_table (info)->dynlocal)
+ {
+ struct elf_link_local_dynamic_entry *e;
+ for (e = elf_hash_table (info)->dynlocal; e ; e = e->next)
+ {
+ asection *s;
+ bfd_byte *dest;
+
+ /* Copy the internal symbol and turn off visibility.
+ Note that we saved a word of storage and overwrote
+ the original st_name with the dynstr_index. */
+ sym = e->isym;
+ sym.st_other &= ~ELF_ST_VISIBILITY (-1);
+
+ s = bfd_section_from_elf_index (e->input_bfd,
+ e->isym.st_shndx);
+ if (s != NULL)
+ {
+ sym.st_shndx =
+ elf_section_data (s->output_section)->this_idx;
+ if (! check_dynsym (abfd, &sym))
+ return FALSE;
+ sym.st_value = (s->output_section->vma
+ + s->output_offset
+ + e->isym.st_value);
+ }
+
+ if (last_local < e->dynindx)
+ last_local = e->dynindx;
+
+ dest = dynsym + e->dynindx * bed->s->sizeof_sym;
+ bed->s->swap_symbol_out (abfd, &sym, dest, 0);
+ }
+ }
+
+ elf_section_data (flinfo.dynsym_sec->output_section)->this_hdr.sh_info =
+ last_local + 1;
+ }
+
+ /* We get the global symbols from the hash table. */
+ eoinfo.failed = FALSE;
+ eoinfo.localsyms = FALSE;
+ eoinfo.flinfo = &flinfo;
+ bfd_hash_traverse (&info->hash->table, elf_link_output_extsym, &eoinfo);
+ if (eoinfo.failed)
+ return FALSE;
+
+ /* If backend needs to output some symbols not present in the hash
+ table, do it now. */
+ if (bed->elf_backend_output_arch_syms)
+ {
+ typedef int (*out_sym_func)
+ (void *, const char *, Elf_Internal_Sym *, asection *,
+ struct elf_link_hash_entry *);
+
+ if (! ((*bed->elf_backend_output_arch_syms)
+ (abfd, info, &flinfo, (out_sym_func) elf_link_output_sym)))
+ return FALSE;
+ }
+
+ /* Flush all symbols to the file. */
+ if (! elf_link_flush_output_syms (&flinfo, bed))
+ return FALSE;
+
+ /* Now we know the size of the symtab section. */
+ off += symtab_hdr->sh_size;
+
+ symtab_shndx_hdr = &elf_tdata (abfd)->symtab_shndx_hdr;
+ if (symtab_shndx_hdr->sh_name != 0)
+ {
+ symtab_shndx_hdr->sh_type = SHT_SYMTAB_SHNDX;
+ symtab_shndx_hdr->sh_entsize = sizeof (Elf_External_Sym_Shndx);
+ symtab_shndx_hdr->sh_addralign = sizeof (Elf_External_Sym_Shndx);
+ amt = bfd_get_symcount (abfd) * sizeof (Elf_External_Sym_Shndx);
+ symtab_shndx_hdr->sh_size = amt;
+
+ off = _bfd_elf_assign_file_position_for_section (symtab_shndx_hdr,
+ off, TRUE);
+
+ if (bfd_seek (abfd, symtab_shndx_hdr->sh_offset, SEEK_SET) != 0
+ || (bfd_bwrite (flinfo.symshndxbuf, amt, abfd) != amt))
+ return FALSE;
+ }
+
+
+ /* 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 (flinfo.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_next_file_pos (abfd) = off;
+
+ if (bfd_get_symcount (abfd) > 0)
+ {
+ if (bfd_seek (abfd, symstrtab_hdr->sh_offset, SEEK_SET) != 0
+ || ! _bfd_stringtab_emit (abfd, flinfo.symstrtab))
+ return FALSE;
+ }
+
+ /* Adjust the relocs to have the correct symbol indices. */
+ for (o = abfd->sections; o != NULL; o = o->next)
+ {
+ struct bfd_elf_section_data *esdo = elf_section_data (o);
+ if ((o->flags & SEC_RELOC) == 0)
+ continue;
+
+ if (esdo->rel.hdr != NULL)
+ elf_link_adjust_relocs (abfd, &esdo->rel);
+ if (esdo->rela.hdr != NULL)
+ elf_link_adjust_relocs (abfd, &esdo->rela);
+
+ /* Set the reloc_count field to 0 to prevent write_relocs from
+ trying to swap the relocs out itself. */
+ o->reloc_count = 0;
+ }
+
+ if (dynamic && info->combreloc && dynobj != NULL)
+ relativecount = elf_link_sort_relocs (abfd, info, &reldyn);
+
+ /* If we are linking against a dynamic object, or generating a
+ shared library, finish up the dynamic linking information. */
+ if (dynamic)
+ {
+ bfd_byte *dyncon, *dynconend;
+
+ /* Fix up .dynamic entries. */
+ o = bfd_get_linker_section (dynobj, ".dynamic");
+ BFD_ASSERT (o != NULL);
+
+ dyncon = o->contents;
+ dynconend = o->contents + o->size;
+ for (; dyncon < dynconend; dyncon += bed->s->sizeof_dyn)
+ {
+ Elf_Internal_Dyn dyn;
+ const char *name;
+ unsigned int type;
+
+ bed->s->swap_dyn_in (dynobj, dyncon, &dyn);
+
+ switch (dyn.d_tag)
+ {
+ default:
+ continue;
+ case DT_NULL:
+ if (relativecount > 0 && dyncon + bed->s->sizeof_dyn < dynconend)
+ {
+ switch (elf_section_data (reldyn)->this_hdr.sh_type)
+ {
+ case SHT_REL: dyn.d_tag = DT_RELCOUNT; break;
+ case SHT_RELA: dyn.d_tag = DT_RELACOUNT; break;
+ default: continue;
+ }
+ dyn.d_un.d_val = relativecount;
+ relativecount = 0;
+ break;
+ }
+ continue;
+
+ case DT_INIT:
+ name = info->init_function;
+ goto get_sym;
+ case DT_FINI:
+ name = info->fini_function;
+ 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_ptr = h->root.u.def.value;
+ o = h->root.u.def.section;
+ if (o->output_section != NULL)
+ dyn.d_un.d_ptr += (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_ptr = 0;
+ }
+ break;
+ }
+ }
+ continue;
+
+ case DT_PREINIT_ARRAYSZ:
+ name = ".preinit_array";
+ goto get_size;
+ case DT_INIT_ARRAYSZ:
+ name = ".init_array";
+ goto get_size;
+ case DT_FINI_ARRAYSZ:
+ name = ".fini_array";
+ get_size:
+ o = bfd_get_section_by_name (abfd, name);
+ if (o == NULL)
+ {
+ (*_bfd_error_handler)
+ (_("%B: could not find output section %s"), abfd, name);
+ goto error_return;
+ }
+ if (o->size == 0)
+ (*_bfd_error_handler)
+ (_("warning: %s section has zero size"), name);
+ dyn.d_un.d_val = o->size;
+ break;
+
+ case DT_PREINIT_ARRAY:
+ name = ".preinit_array";
+ goto get_vma;
+ case DT_INIT_ARRAY:
+ name = ".init_array";
+ goto get_vma;
+ case DT_FINI_ARRAY:
+ name = ".fini_array";
+ goto get_vma;
+
+ case DT_HASH:
+ name = ".hash";
+ goto get_vma;
+ case DT_GNU_HASH:
+ name = ".gnu.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);
+ if (o == NULL)
+ {
+ (*_bfd_error_handler)
+ (_("%B: could not find output section %s"), abfd, name);
+ goto error_return;
+ }
+ if (elf_section_data (o->output_section)->this_hdr.sh_type == SHT_NOTE)
+ {
+ (*_bfd_error_handler)
+ (_("warning: section '%s' is being made into a note"), name);
+ bfd_set_error (bfd_error_nonrepresentable_section);
+ goto error_return;
+ }
+ dyn.d_un.d_ptr = o->vma;
+ 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;
+ dyn.d_un.d_ptr = 0;
+ for (i = 1; i < elf_numsections (abfd); 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_ptr == 0
+ || hdr->sh_addr < dyn.d_un.d_ptr)
+ dyn.d_un.d_ptr = hdr->sh_addr;
+ }
+ }
+ }
+ break;
+ }
+ bed->s->swap_dyn_out (dynobj, &dyn, dyncon);
+ }
+ }
+
+ /* 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;
+
+ /* Check for DT_TEXTREL (late, in case the backend removes it). */
+ if (((info->warn_shared_textrel && info->shared)
+ || info->error_textrel)
+ && (o = bfd_get_linker_section (dynobj, ".dynamic")) != NULL)
+ {
+ bfd_byte *dyncon, *dynconend;
+
+ dyncon = o->contents;
+ dynconend = o->contents + o->size;
+ for (; dyncon < dynconend; dyncon += bed->s->sizeof_dyn)
+ {
+ Elf_Internal_Dyn dyn;
+
+ bed->s->swap_dyn_in (dynobj, dyncon, &dyn);
+
+ if (dyn.d_tag == DT_TEXTREL)
+ {
+ if (info->error_textrel)
+ info->callbacks->einfo
+ (_("%P%X: read-only segment has dynamic relocations.\n"));
+ else
+ info->callbacks->einfo
+ (_("%P: warning: creating a DT_TEXTREL in a shared object.\n"));
+ break;
+ }
+ }
+ }
+
+ for (o = dynobj->sections; o != NULL; o = o->next)
+ {
+ if ((o->flags & SEC_HAS_CONTENTS) == 0
+ || o->size == 0
+ || o->output_section == bfd_abs_section_ptr)
+ continue;
+ if ((o->flags & SEC_LINKER_CREATED) == 0)
+ {
+ /* At this point, we are only interested in sections
+ created by _bfd_elf_link_create_dynamic_sections. */
+ continue;
+ }
+ if (elf_hash_table (info)->stab_info.stabstr == o)
+ continue;
+ if (elf_hash_table (info)->eh_info.hdr_sec == o)
+ continue;
+ if (strcmp (o->name, ".dynstr") != 0)
+ {
+ /* FIXME: octets_per_byte. */
+ if (! bfd_set_section_contents (abfd, o->output_section,
+ o->contents,
+ (file_ptr) o->output_offset,
+ o->size))
+ goto error_return;
+ }
+ else
+ {
+ /* 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_elf_strtab_emit (abfd,
+ elf_hash_table (info)->dynstr))
+ goto error_return;
+ }
+ }
+ }
+
+ if (info->relocatable)
+ {
+ bfd_boolean failed = FALSE;
+
+ bfd_map_over_sections (abfd, bfd_elf_set_group_contents, &failed);
+ if (failed)
+ goto error_return;
+ }
+
+ /* If we have optimized stabs strings, output them. */
+ if (elf_hash_table (info)->stab_info.stabstr != NULL)
+ {
+ if (! _bfd_write_stab_strings (abfd, &elf_hash_table (info)->stab_info))
+ goto error_return;
+ }
+
+ if (! _bfd_elf_write_section_eh_frame_hdr (abfd, info))
+ goto error_return;
+
+ elf_final_link_free (abfd, &flinfo);
+
+ elf_linker (abfd) = TRUE;
+
+ if (attr_section)
+ {
+ bfd_byte *contents = (bfd_byte *) bfd_malloc (attr_size);
+ if (contents == NULL)
+ return FALSE; /* Bail out and fail. */
+ bfd_elf_set_obj_attr_contents (abfd, contents, attr_size);
+ bfd_set_section_contents (abfd, attr_section, contents, 0, attr_size);
+ free (contents);
+ }
+
+ return TRUE;
+
+ error_return:
+ elf_final_link_free (abfd, &flinfo);
+ return FALSE;
+}
+
+/* Initialize COOKIE for input bfd ABFD. */
+
+static bfd_boolean
+init_reloc_cookie (struct elf_reloc_cookie *cookie,
+ struct bfd_link_info *info, bfd *abfd)
+{
+ Elf_Internal_Shdr *symtab_hdr;
+ const struct elf_backend_data *bed;
+
+ bed = get_elf_backend_data (abfd);
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+
+ cookie->abfd = abfd;
+ cookie->sym_hashes = elf_sym_hashes (abfd);
+ cookie->bad_symtab = elf_bad_symtab (abfd);
+ if (cookie->bad_symtab)
+ {
+ cookie->locsymcount = symtab_hdr->sh_size / bed->s->sizeof_sym;
+ cookie->extsymoff = 0;
+ }
+ else
+ {
+ cookie->locsymcount = symtab_hdr->sh_info;
+ cookie->extsymoff = symtab_hdr->sh_info;
+ }
+
+ if (bed->s->arch_size == 32)
+ cookie->r_sym_shift = 8;
+ else
+ cookie->r_sym_shift = 32;
+
+ cookie->locsyms = (Elf_Internal_Sym *) symtab_hdr->contents;
+ if (cookie->locsyms == NULL && cookie->locsymcount != 0)
+ {
+ cookie->locsyms = bfd_elf_get_elf_syms (abfd, symtab_hdr,
+ cookie->locsymcount, 0,
+ NULL, NULL, NULL);
+ if (cookie->locsyms == NULL)
+ {
+ info->callbacks->einfo (_("%P%X: can not read symbols: %E\n"));
+ return FALSE;
+ }
+ if (info->keep_memory)
+ symtab_hdr->contents = (bfd_byte *) cookie->locsyms;
+ }
+ return TRUE;
+}
+
+/* Free the memory allocated by init_reloc_cookie, if appropriate. */
+
+static void
+fini_reloc_cookie (struct elf_reloc_cookie *cookie, bfd *abfd)
+{
+ Elf_Internal_Shdr *symtab_hdr;
+
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+ if (cookie->locsyms != NULL
+ && symtab_hdr->contents != (unsigned char *) cookie->locsyms)
+ free (cookie->locsyms);
+}
+
+/* Initialize the relocation information in COOKIE for input section SEC
+ of input bfd ABFD. */
+
+static bfd_boolean
+init_reloc_cookie_rels (struct elf_reloc_cookie *cookie,
+ struct bfd_link_info *info, bfd *abfd,
+ asection *sec)
+{
+ const struct elf_backend_data *bed;
+
+ if (sec->reloc_count == 0)
+ {
+ cookie->rels = NULL;
+ cookie->relend = NULL;
+ }
+ else
+ {
+ bed = get_elf_backend_data (abfd);
+
+ cookie->rels = _bfd_elf_link_read_relocs (abfd, sec, NULL, NULL,
+ info->keep_memory);
+ if (cookie->rels == NULL)
+ return FALSE;
+ cookie->rel = cookie->rels;
+ cookie->relend = (cookie->rels
+ + sec->reloc_count * bed->s->int_rels_per_ext_rel);
+ }
+ cookie->rel = cookie->rels;
+ return TRUE;
+}
+
+/* Free the memory allocated by init_reloc_cookie_rels,
+ if appropriate. */
+
+static void
+fini_reloc_cookie_rels (struct elf_reloc_cookie *cookie,
+ asection *sec)
+{
+ if (cookie->rels && elf_section_data (sec)->relocs != cookie->rels)
+ free (cookie->rels);
+}
+
+/* Initialize the whole of COOKIE for input section SEC. */
+
+static bfd_boolean
+init_reloc_cookie_for_section (struct elf_reloc_cookie *cookie,
+ struct bfd_link_info *info,
+ asection *sec)
+{
+ if (!init_reloc_cookie (cookie, info, sec->owner))
+ goto error1;
+ if (!init_reloc_cookie_rels (cookie, info, sec->owner, sec))
+ goto error2;
+ return TRUE;
+
+ error2:
+ fini_reloc_cookie (cookie, sec->owner);
+ error1:
+ return FALSE;
+}
+
+/* Free the memory allocated by init_reloc_cookie_for_section,
+ if appropriate. */
+
+static void
+fini_reloc_cookie_for_section (struct elf_reloc_cookie *cookie,
+ asection *sec)
+{
+ fini_reloc_cookie_rels (cookie, sec);
+ fini_reloc_cookie (cookie, sec->owner);
+}
+
+/* Garbage collect unused sections. */
+
+/* Default gc_mark_hook. */
+
+asection *
+_bfd_elf_gc_mark_hook (asection *sec,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ Elf_Internal_Rela *rel ATTRIBUTE_UNUSED,
+ struct elf_link_hash_entry *h,
+ Elf_Internal_Sym *sym)
+{
+ const char *sec_name;
+
+ if (h != NULL)
+ {
+ 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;
+
+ case bfd_link_hash_undefined:
+ case bfd_link_hash_undefweak:
+ /* To work around a glibc bug, keep all XXX input sections
+ when there is an as yet undefined reference to __start_XXX
+ or __stop_XXX symbols. The linker will later define such
+ symbols for orphan input sections that have a name
+ representable as a C identifier. */
+ if (strncmp (h->root.root.string, "__start_", 8) == 0)
+ sec_name = h->root.root.string + 8;
+ else if (strncmp (h->root.root.string, "__stop_", 7) == 0)
+ sec_name = h->root.root.string + 7;
+ else
+ sec_name = NULL;
+
+ if (sec_name && *sec_name != '\0')
+ {
+ bfd *i;
+
+ for (i = info->input_bfds; i; i = i->link.next)
+ {
+ sec = bfd_get_section_by_name (i, sec_name);
+ if (sec)
+ sec->flags |= SEC_KEEP;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ else
+ return bfd_section_from_elf_index (sec->owner, sym->st_shndx);
+
+ return NULL;
+}
+
+/* COOKIE->rel describes a relocation against section SEC, which is
+ a section we've decided to keep. Return the section that contains
+ the relocation symbol, or NULL if no section contains it. */
+
+asection *
+_bfd_elf_gc_mark_rsec (struct bfd_link_info *info, asection *sec,
+ elf_gc_mark_hook_fn gc_mark_hook,
+ struct elf_reloc_cookie *cookie)
+{
+ unsigned long r_symndx;
+ struct elf_link_hash_entry *h;
+
+ r_symndx = cookie->rel->r_info >> cookie->r_sym_shift;
+ if (r_symndx == STN_UNDEF)
+ return NULL;
+
+ if (r_symndx >= cookie->locsymcount
+ || ELF_ST_BIND (cookie->locsyms[r_symndx].st_info) != STB_LOCAL)
+ {
+ h = cookie->sym_hashes[r_symndx - cookie->extsymoff];
+ if (h == NULL)
+ {
+ info->callbacks->einfo (_("%F%P: corrupt input: %B\n"),
+ sec->owner);
+ return NULL;
+ }
+ 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;
+ h->mark = 1;
+ /* If this symbol is weak and there is a non-weak definition, we
+ keep the non-weak definition because many backends put
+ dynamic reloc info on the non-weak definition for code
+ handling copy relocs. */
+ if (h->u.weakdef != NULL)
+ h->u.weakdef->mark = 1;
+ return (*gc_mark_hook) (sec, info, cookie->rel, h, NULL);
+ }
+
+ return (*gc_mark_hook) (sec, info, cookie->rel, NULL,
+ &cookie->locsyms[r_symndx]);
+}
+
+/* COOKIE->rel describes a relocation against section SEC, which is
+ a section we've decided to keep. Mark the section that contains
+ the relocation symbol. */
+
+bfd_boolean
+_bfd_elf_gc_mark_reloc (struct bfd_link_info *info,
+ asection *sec,
+ elf_gc_mark_hook_fn gc_mark_hook,
+ struct elf_reloc_cookie *cookie)
+{
+ asection *rsec;
+
+ rsec = _bfd_elf_gc_mark_rsec (info, sec, gc_mark_hook, cookie);
+ if (rsec && !rsec->gc_mark)
+ {
+ if (bfd_get_flavour (rsec->owner) != bfd_target_elf_flavour
+ || (rsec->owner->flags & DYNAMIC) != 0)
+ rsec->gc_mark = 1;
+ else if (!_bfd_elf_gc_mark (info, rsec, gc_mark_hook))
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/* The mark phase of garbage collection. For a given section, mark
+ it and any sections in this section's group, and all the sections
+ which define symbols to which it refers. */
+
+bfd_boolean
+_bfd_elf_gc_mark (struct bfd_link_info *info,
+ asection *sec,
+ elf_gc_mark_hook_fn gc_mark_hook)
+{
+ bfd_boolean ret;
+ asection *group_sec, *eh_frame;
+
+ sec->gc_mark = 1;
+
+ /* Mark all the sections in the group. */
+ group_sec = elf_section_data (sec)->next_in_group;
+ if (group_sec && !group_sec->gc_mark)
+ if (!_bfd_elf_gc_mark (info, group_sec, gc_mark_hook))
+ return FALSE;
+
+ /* Look through the section relocs. */
+ ret = TRUE;
+ eh_frame = elf_eh_frame_section (sec->owner);
+ if ((sec->flags & SEC_RELOC) != 0
+ && sec->reloc_count > 0
+ && sec != eh_frame)
+ {
+ struct elf_reloc_cookie cookie;
+
+ if (!init_reloc_cookie_for_section (&cookie, info, sec))
+ ret = FALSE;
+ else
+ {
+ for (; cookie.rel < cookie.relend; cookie.rel++)
+ if (!_bfd_elf_gc_mark_reloc (info, sec, gc_mark_hook, &cookie))
+ {
+ ret = FALSE;
+ break;
+ }
+ fini_reloc_cookie_for_section (&cookie, sec);
+ }
+ }
+
+ if (ret && eh_frame && elf_fde_list (sec))
+ {
+ struct elf_reloc_cookie cookie;
+
+ if (!init_reloc_cookie_for_section (&cookie, info, eh_frame))
+ ret = FALSE;
+ else
+ {
+ if (!_bfd_elf_gc_mark_fdes (info, sec, eh_frame,
+ gc_mark_hook, &cookie))
+ ret = FALSE;
+ fini_reloc_cookie_for_section (&cookie, eh_frame);
+ }
+ }
+
+ return ret;
+}
+
+/* Keep debug and special sections. */
+
+bfd_boolean
+_bfd_elf_gc_mark_extra_sections (struct bfd_link_info *info,
+ elf_gc_mark_hook_fn mark_hook ATTRIBUTE_UNUSED)
+{
+ bfd *ibfd;
+
+ for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next)
+ {
+ asection *isec;
+ bfd_boolean some_kept;
+ bfd_boolean debug_frag_seen;
+
+ if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour)
+ continue;
+
+ /* Ensure all linker created sections are kept,
+ see if any other section is already marked,
+ and note if we have any fragmented debug sections. */
+ debug_frag_seen = some_kept = FALSE;
+ for (isec = ibfd->sections; isec != NULL; isec = isec->next)
+ {
+ if ((isec->flags & SEC_LINKER_CREATED) != 0)
+ isec->gc_mark = 1;
+ else if (isec->gc_mark)
+ some_kept = TRUE;
+
+ if (debug_frag_seen == FALSE
+ && (isec->flags & SEC_DEBUGGING)
+ && CONST_STRNEQ (isec->name, ".debug_line."))
+ debug_frag_seen = TRUE;
+ }
+
+ /* If no section in this file will be kept, then we can
+ toss out the debug and special sections. */
+ if (!some_kept)
+ continue;
+
+ /* Keep debug and special sections like .comment when they are
+ not part of a group, or when we have single-member groups. */
+ for (isec = ibfd->sections; isec != NULL; isec = isec->next)
+ if ((elf_next_in_group (isec) == NULL
+ || elf_next_in_group (isec) == isec)
+ && ((isec->flags & SEC_DEBUGGING) != 0
+ || (isec->flags & (SEC_ALLOC | SEC_LOAD | SEC_RELOC)) == 0))
+ isec->gc_mark = 1;
+
+ if (! debug_frag_seen)
+ continue;
+
+ /* Look for CODE sections which are going to be discarded,
+ and find and discard any fragmented debug sections which
+ are associated with that code section. */
+ for (isec = ibfd->sections; isec != NULL; isec = isec->next)
+ if ((isec->flags & SEC_CODE) != 0
+ && isec->gc_mark == 0)
+ {
+ unsigned int ilen;
+ asection *dsec;
+
+ ilen = strlen (isec->name);
+
+ /* Association is determined by the name of the debug section
+ containing the name of the code section as a suffix. For
+ example .debug_line.text.foo is a debug section associated
+ with .text.foo. */
+ for (dsec = ibfd->sections; dsec != NULL; dsec = dsec->next)
+ {
+ unsigned int dlen;
+
+ if (dsec->gc_mark == 0
+ || (dsec->flags & SEC_DEBUGGING) == 0)
+ continue;
+
+ dlen = strlen (dsec->name);
+
+ if (dlen > ilen
+ && strncmp (dsec->name + (dlen - ilen),
+ isec->name, ilen) == 0)
+ {
+ dsec->gc_mark = 0;
+ break;
+ }
+ }
+ }
+ }
+ return TRUE;
+}
+
+/* Sweep symbols in swept sections. Called via elf_link_hash_traverse. */
+
+struct elf_gc_sweep_symbol_info
+{
+ struct bfd_link_info *info;
+ void (*hide_symbol) (struct bfd_link_info *, struct elf_link_hash_entry *,
+ bfd_boolean);
+};
+
+static bfd_boolean
+elf_gc_sweep_symbol (struct elf_link_hash_entry *h, void *data)
+{
+ if (!h->mark
+ && (((h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak)
+ && !(h->def_regular
+ && h->root.u.def.section->gc_mark))
+ || h->root.type == bfd_link_hash_undefined
+ || h->root.type == bfd_link_hash_undefweak))
+ {
+ struct elf_gc_sweep_symbol_info *inf;
+
+ inf = (struct elf_gc_sweep_symbol_info *) data;
+ (*inf->hide_symbol) (inf->info, h, TRUE);
+ h->def_regular = 0;
+ h->ref_regular = 0;
+ h->ref_regular_nonweak = 0;
+ }
+
+ return TRUE;
+}
+
+/* The sweep phase of garbage collection. Remove all garbage sections. */
+
+typedef bfd_boolean (*gc_sweep_hook_fn)
+ (bfd *, struct bfd_link_info *, asection *, const Elf_Internal_Rela *);
+
+static bfd_boolean
+elf_gc_sweep (bfd *abfd, struct bfd_link_info *info)
+{
+ bfd *sub;
+ const struct elf_backend_data *bed = get_elf_backend_data (abfd);
+ gc_sweep_hook_fn gc_sweep_hook = bed->gc_sweep_hook;
+ unsigned long section_sym_count;
+ struct elf_gc_sweep_symbol_info sweep_info;
+
+ for (sub = info->input_bfds; sub != NULL; sub = sub->link.next)
+ {
+ asection *o;
+
+ if (bfd_get_flavour (sub) != bfd_target_elf_flavour)
+ continue;
+
+ for (o = sub->sections; o != NULL; o = o->next)
+ {
+ /* When any section in a section group is kept, we keep all
+ sections in the section group. If the first member of
+ the section group is excluded, we will also exclude the
+ group section. */
+ if (o->flags & SEC_GROUP)
+ {
+ asection *first = elf_next_in_group (o);
+ o->gc_mark = first->gc_mark;
+ }
+
+ 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;
+
+ if (info->print_gc_sections && o->size != 0)
+ _bfd_error_handler (_("Removing unused section '%s' in file '%B'"), sub, o->name);
+
+ /* But we also have to update some of the relocation
+ info we collected before. */
+ if (gc_sweep_hook
+ && (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))
+ {
+ Elf_Internal_Rela *internal_relocs;
+ bfd_boolean r;
+
+ internal_relocs
+ = _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 (elf_section_data (o)->relocs != internal_relocs)
+ 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? */
+ sweep_info.info = info;
+ sweep_info.hide_symbol = bed->elf_backend_hide_symbol;
+ elf_link_hash_traverse (elf_hash_table (info), elf_gc_sweep_symbol,
+ &sweep_info);
+
+ _bfd_elf_link_renumber_dynsyms (abfd, info, &section_sym_count);
+ return TRUE;
+}
+
+/* Propagate collected vtable information. This is called through
+ elf_link_hash_traverse. */
+
+static bfd_boolean
+elf_gc_propagate_vtable_entries_used (struct elf_link_hash_entry *h, void *okp)
+{
+ /* Those that are not vtables. */
+ if (h->vtable == NULL || 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->used && h->vtable->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->used == NULL)
+ {
+ /* None of this table's entries were referenced. Re-use the
+ parent's table. */
+ h->vtable->used = h->vtable->parent->vtable->used;
+ h->vtable->size = h->vtable->parent->vtable->size;
+ }
+ else
+ {
+ size_t n;
+ bfd_boolean *cu, *pu;
+
+ /* Or the parent's entries into ours. */
+ cu = h->vtable->used;
+ cu[-1] = TRUE;
+ pu = h->vtable->parent->vtable->used;
+ if (pu != NULL)
+ {
+ const struct elf_backend_data *bed;
+ unsigned int log_file_align;
+
+ bed = get_elf_backend_data (h->root.u.def.section->owner);
+ log_file_align = bed->s->log_file_align;
+ n = h->vtable->parent->vtable->size >> log_file_align;
+ while (n--)
+ {
+ if (*pu)
+ *cu = TRUE;
+ pu++;
+ cu++;
+ }
+ }
+ }
+
+ return TRUE;
+}
+
+static bfd_boolean
+elf_gc_smash_unused_vtentry_relocs (struct elf_link_hash_entry *h, void *okp)
+{
+ asection *sec;
+ bfd_vma hstart, hend;
+ Elf_Internal_Rela *relstart, *relend, *rel;
+ const struct elf_backend_data *bed;
+ unsigned int log_file_align;
+
+ /* Take care of both those symbols that do not describe vtables as
+ well as those that are not loaded. */
+ if (h->vtable == NULL || 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 = _bfd_elf_link_read_relocs (sec->owner, sec, NULL, NULL, TRUE);
+ if (!relstart)
+ return *(bfd_boolean *) okp = FALSE;
+ bed = get_elf_backend_data (sec->owner);
+ log_file_align = bed->s->log_file_align;
+
+ relend = relstart + sec->reloc_count * bed->s->int_rels_per_ext_rel;
+
+ 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->used
+ && (rel->r_offset - hstart) < h->vtable->size)
+ {
+ bfd_vma entry = (rel->r_offset - hstart) >> log_file_align;
+ if (h->vtable->used[entry])
+ continue;
+ }
+ /* Otherwise, kill it. */
+ rel->r_offset = rel->r_info = rel->r_addend = 0;
+ }
+
+ return TRUE;
+}
+
+/* Mark sections containing dynamically referenced symbols. When
+ building shared libraries, we must assume that any visible symbol is
+ referenced. */
+
+bfd_boolean
+bfd_elf_gc_mark_dynamic_ref_symbol (struct elf_link_hash_entry *h, void *inf)
+{
+ struct bfd_link_info *info = (struct bfd_link_info *) inf;
+ struct bfd_elf_dynamic_list *d = info->dynamic_list;
+
+ if ((h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak)
+ && (h->ref_dynamic
+ || (h->def_regular
+ && ELF_ST_VISIBILITY (h->other) != STV_INTERNAL
+ && ELF_ST_VISIBILITY (h->other) != STV_HIDDEN
+ && (!info->executable
+ || info->export_dynamic
+ || (h->dynamic
+ && d != NULL
+ && (*d->match) (&d->head, NULL, h->root.root.string)))
+ && (strchr (h->root.root.string, ELF_VER_CHR) != NULL
+ || !bfd_hide_sym_by_version (info->version_info,
+ h->root.root.string)))))
+ h->root.u.def.section->flags |= SEC_KEEP;
+
+ return TRUE;
+}
+
+/* Keep all sections containing symbols undefined on the command-line,
+ and the section containing the entry symbol. */
+
+void
+_bfd_elf_gc_keep (struct bfd_link_info *info)
+{
+ struct bfd_sym_chain *sym;
+
+ for (sym = info->gc_sym_list; sym != NULL; sym = sym->next)
+ {
+ struct elf_link_hash_entry *h;
+
+ h = elf_link_hash_lookup (elf_hash_table (info), sym->name,
+ FALSE, FALSE, FALSE);
+
+ if (h != NULL
+ && (h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak)
+ && !bfd_is_abs_section (h->root.u.def.section))
+ h->root.u.def.section->flags |= SEC_KEEP;
+ }
+}
+
+/* Do mark and sweep of unused sections. */
+
+bfd_boolean
+bfd_elf_gc_sections (bfd *abfd, struct bfd_link_info *info)
+{
+ bfd_boolean ok = TRUE;
+ bfd *sub;
+ elf_gc_mark_hook_fn gc_mark_hook;
+ const struct elf_backend_data *bed = get_elf_backend_data (abfd);
+ struct elf_link_hash_table *htab;
+
+ if (!bed->can_gc_sections
+ || !is_elf_hash_table (info->hash))
+ {
+ (*_bfd_error_handler)(_("Warning: gc-sections option ignored"));
+ return TRUE;
+ }
+
+ bed->gc_keep (info);
+ htab = elf_hash_table (info);
+
+ /* Try to parse each bfd's .eh_frame section. Point elf_eh_frame_section
+ at the .eh_frame section if we can mark the FDEs individually. */
+ for (sub = info->input_bfds; sub != NULL; sub = sub->link.next)
+ {
+ asection *sec;
+ struct elf_reloc_cookie cookie;
+
+ sec = bfd_get_section_by_name (sub, ".eh_frame");
+ while (sec && init_reloc_cookie_for_section (&cookie, info, sec))
+ {
+ _bfd_elf_parse_eh_frame (sub, info, sec, &cookie);
+ if (elf_section_data (sec)->sec_info
+ && (sec->flags & SEC_LINKER_CREATED) == 0)
+ elf_eh_frame_section (sub) = sec;
+ fini_reloc_cookie_for_section (&cookie, sec);
+ sec = bfd_get_next_section_by_name (sec);
+ }
+ }
+
+ /* Apply transitive closure to the vtable entry usage info. */
+ elf_link_hash_traverse (htab, elf_gc_propagate_vtable_entries_used, &ok);
+ if (!ok)
+ return FALSE;
+
+ /* Kill the vtable relocations that were not used. */
+ elf_link_hash_traverse (htab, elf_gc_smash_unused_vtentry_relocs, &ok);
+ if (!ok)
+ return FALSE;
+
+ /* Mark dynamically referenced symbols. */
+ if (htab->dynamic_sections_created)
+ elf_link_hash_traverse (htab, bed->gc_mark_dynamic_ref, info);
+
+ /* Grovel through relocs to find out who stays ... */
+ gc_mark_hook = bed->gc_mark_hook;
+ for (sub = info->input_bfds; sub != NULL; sub = sub->link.next)
+ {
+ asection *o;
+
+ if (bfd_get_flavour (sub) != bfd_target_elf_flavour)
+ continue;
+
+ /* Start at sections marked with SEC_KEEP (ref _bfd_elf_gc_keep).
+ Also treat note sections as a root, if the section is not part
+ of a group. */
+ for (o = sub->sections; o != NULL; o = o->next)
+ if (!o->gc_mark
+ && (o->flags & SEC_EXCLUDE) == 0
+ && ((o->flags & SEC_KEEP) != 0
+ || (elf_section_data (o)->this_hdr.sh_type == SHT_NOTE
+ && elf_next_in_group (o) == NULL )))
+ {
+ if (!_bfd_elf_gc_mark (info, o, gc_mark_hook))
+ return FALSE;
+ }
+ }
+
+ /* Allow the backend to mark additional target specific sections. */
+ bed->gc_mark_extra_sections (info, gc_mark_hook);
+
+ /* ... and mark SEC_EXCLUDE for those that go. */
+ return elf_gc_sweep (abfd, info);
+}
+
+/* Called from check_relocs to record the existence of a VTINHERIT reloc. */
+
+bfd_boolean
+bfd_elf_gc_record_vtinherit (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;
+ const struct elf_backend_data *bed = get_elf_backend_data (abfd);
+
+ /* 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 / bed->s->sizeof_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) ("%B: %A+%lu: No symbol found for INHERIT",
+ abfd, sec, (unsigned long) offset);
+ bfd_set_error (bfd_error_invalid_operation);
+ return FALSE;
+
+ win:
+ if (!child->vtable)
+ {
+ child->vtable = (struct elf_link_virtual_table_entry *)
+ bfd_zalloc (abfd, sizeof (*child->vtable));
+ if (!child->vtable)
+ return FALSE;
+ }
+ 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 existence of a VTENTRY reloc. */
+
+bfd_boolean
+bfd_elf_gc_record_vtentry (bfd *abfd ATTRIBUTE_UNUSED,
+ asection *sec ATTRIBUTE_UNUSED,
+ struct elf_link_hash_entry *h,
+ bfd_vma addend)
+{
+ const struct elf_backend_data *bed = get_elf_backend_data (abfd);
+ unsigned int log_file_align = bed->s->log_file_align;
+
+ if (!h->vtable)
+ {
+ h->vtable = (struct elf_link_virtual_table_entry *)
+ bfd_zalloc (abfd, sizeof (*h->vtable));
+ if (!h->vtable)
+ return FALSE;
+ }
+
+ if (addend >= h->vtable->size)
+ {
+ size_t size, bytes, file_align;
+ bfd_boolean *ptr = h->vtable->used;
+
+ /* While the symbol is undefined, we have to be prepared to handle
+ a zero size. */
+ file_align = 1 << log_file_align;
+ if (h->root.type == bfd_link_hash_undefined)
+ size = addend + file_align;
+ else
+ {
+ size = h->size;
+ if (addend >= size)
+ {
+ /* Oops! We've got a reference past the defined end of
+ the table. This is probably a bug -- shall we warn? */
+ size = addend + file_align;
+ }
+ }
+ size = (size + file_align - 1) & -file_align;
+
+ /* Allocate one extra entry for use as a "done" flag for the
+ consolidation pass. */
+ bytes = ((size >> log_file_align) + 1) * sizeof (bfd_boolean);
+
+ if (ptr)
+ {
+ ptr = (bfd_boolean *) bfd_realloc (ptr - 1, bytes);
+
+ if (ptr != NULL)
+ {
+ size_t oldbytes;
+
+ oldbytes = (((h->vtable->size >> log_file_align) + 1)
+ * sizeof (bfd_boolean));
+ memset (((char *) ptr) + oldbytes, 0, bytes - oldbytes);
+ }
+ }
+ else
+ ptr = (bfd_boolean *) bfd_zmalloc (bytes);
+
+ if (ptr == NULL)
+ return FALSE;
+
+ /* And arrange for that done flag to be at index -1. */
+ h->vtable->used = ptr + 1;
+ h->vtable->size = size;
+ }
+
+ h->vtable->used[addend >> log_file_align] = TRUE;
+
+ return TRUE;
+}
+
+/* Map an ELF section header flag to its corresponding string. */
+typedef struct
+{
+ char *flag_name;
+ flagword flag_value;
+} elf_flags_to_name_table;
+
+static elf_flags_to_name_table elf_flags_to_names [] =
+{
+ { "SHF_WRITE", SHF_WRITE },
+ { "SHF_ALLOC", SHF_ALLOC },
+ { "SHF_EXECINSTR", SHF_EXECINSTR },
+ { "SHF_MERGE", SHF_MERGE },
+ { "SHF_STRINGS", SHF_STRINGS },
+ { "SHF_INFO_LINK", SHF_INFO_LINK},
+ { "SHF_LINK_ORDER", SHF_LINK_ORDER},
+ { "SHF_OS_NONCONFORMING", SHF_OS_NONCONFORMING},
+ { "SHF_GROUP", SHF_GROUP },
+ { "SHF_TLS", SHF_TLS },
+ { "SHF_MASKOS", SHF_MASKOS },
+ { "SHF_EXCLUDE", SHF_EXCLUDE },
+};
+
+/* Returns TRUE if the section is to be included, otherwise FALSE. */
+bfd_boolean
+bfd_elf_lookup_section_flags (struct bfd_link_info *info,
+ struct flag_info *flaginfo,
+ asection *section)
+{
+ const bfd_vma sh_flags = elf_section_flags (section);
+
+ if (!flaginfo->flags_initialized)
+ {
+ bfd *obfd = info->output_bfd;
+ const struct elf_backend_data *bed = get_elf_backend_data (obfd);
+ struct flag_info_list *tf = flaginfo->flag_list;
+ int with_hex = 0;
+ int without_hex = 0;
+
+ for (tf = flaginfo->flag_list; tf != NULL; tf = tf->next)
+ {
+ unsigned i;
+ flagword (*lookup) (char *);
+
+ lookup = bed->elf_backend_lookup_section_flags_hook;
+ if (lookup != NULL)
+ {
+ flagword hexval = (*lookup) ((char *) tf->name);
+
+ if (hexval != 0)
+ {
+ if (tf->with == with_flags)
+ with_hex |= hexval;
+ else if (tf->with == without_flags)
+ without_hex |= hexval;
+ tf->valid = TRUE;
+ continue;
+ }
+ }
+ for (i = 0; i < ARRAY_SIZE (elf_flags_to_names); ++i)
+ {
+ if (strcmp (tf->name, elf_flags_to_names[i].flag_name) == 0)
+ {
+ if (tf->with == with_flags)
+ with_hex |= elf_flags_to_names[i].flag_value;
+ else if (tf->with == without_flags)
+ without_hex |= elf_flags_to_names[i].flag_value;
+ tf->valid = TRUE;
+ break;
+ }
+ }
+ if (!tf->valid)
+ {
+ info->callbacks->einfo
+ (_("Unrecognized INPUT_SECTION_FLAG %s\n"), tf->name);
+ return FALSE;
+ }
+ }
+ flaginfo->flags_initialized = TRUE;
+ flaginfo->only_with_flags |= with_hex;
+ flaginfo->not_with_flags |= without_hex;
+ }
+
+ if ((flaginfo->only_with_flags & sh_flags) != flaginfo->only_with_flags)
+ return FALSE;
+
+ if ((flaginfo->not_with_flags & sh_flags) != 0)
+ return FALSE;
+
+ return TRUE;
+}
+
+struct alloc_got_off_arg {
+ bfd_vma gotoff;
+ struct bfd_link_info *info;
+};
+
+/* We need a special top-level link routine to convert got reference counts
+ to real got offsets. */
+
+static bfd_boolean
+elf_gc_allocate_got_offsets (struct elf_link_hash_entry *h, void *arg)
+{
+ struct alloc_got_off_arg *gofarg = (struct alloc_got_off_arg *) arg;
+ bfd *obfd = gofarg->info->output_bfd;
+ const struct elf_backend_data *bed = get_elf_backend_data (obfd);
+
+ if (h->got.refcount > 0)
+ {
+ h->got.offset = gofarg->gotoff;
+ gofarg->gotoff += bed->got_elt_size (obfd, gofarg->info, h, NULL, 0);
+ }
+ else
+ h->got.offset = (bfd_vma) -1;
+
+ return TRUE;
+}
+
+/* And an accompanying bit to work out final got entry offsets once
+ we're done. Should be called from final_link. */
+
+bfd_boolean
+bfd_elf_gc_common_finalize_got_offsets (bfd *abfd,
+ struct bfd_link_info *info)
+{
+ bfd *i;
+ const struct elf_backend_data *bed = get_elf_backend_data (abfd);
+ bfd_vma gotoff;
+ struct alloc_got_off_arg gofarg;
+
+ BFD_ASSERT (abfd == info->output_bfd);
+
+ if (! is_elf_hash_table (info->hash))
+ return FALSE;
+
+ /* 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;
+ bfd_size_type j, locsymcount;
+ Elf_Internal_Shdr *symtab_hdr;
+
+ if (bfd_get_flavour (i) != bfd_target_elf_flavour)
+ continue;
+
+ local_got = elf_local_got_refcounts (i);
+ if (!local_got)
+ continue;
+
+ symtab_hdr = &elf_tdata (i)->symtab_hdr;
+ if (elf_bad_symtab (i))
+ locsymcount = symtab_hdr->sh_size / bed->s->sizeof_sym;
+ else
+ locsymcount = symtab_hdr->sh_info;
+
+ for (j = 0; j < locsymcount; ++j)
+ {
+ if (local_got[j] > 0)
+ {
+ local_got[j] = gotoff;
+ gotoff += bed->got_elt_size (abfd, info, NULL, i, j);
+ }
+ else
+ local_got[j] = (bfd_vma) -1;
+ }
+ }
+
+ /* Then the global .got entries. .plt refcounts are handled by
+ adjust_dynamic_symbol */
+ gofarg.gotoff = gotoff;
+ gofarg.info = info;
+ elf_link_hash_traverse (elf_hash_table (info),
+ elf_gc_allocate_got_offsets,
+ &gofarg);
+ return TRUE;
+}
+
+/* Many folk need no more in the way of final link than this, once
+ got entry reference counting is enabled. */
+
+bfd_boolean
+bfd_elf_gc_common_final_link (bfd *abfd, struct bfd_link_info *info)
+{
+ if (!bfd_elf_gc_common_finalize_got_offsets (abfd, info))
+ return FALSE;
+
+ /* Invoke the regular ELF backend linker to do all the work. */
+ return bfd_elf_final_link (abfd, info);
+}
+
+bfd_boolean
+bfd_elf_reloc_symbol_deleted_p (bfd_vma offset, void *cookie)
+{
+ struct elf_reloc_cookie *rcookie = (struct elf_reloc_cookie *) cookie;
+
+ if (rcookie->bad_symtab)
+ rcookie->rel = rcookie->rels;
+
+ for (; rcookie->rel < rcookie->relend; rcookie->rel++)
+ {
+ unsigned long r_symndx;
+
+ if (! rcookie->bad_symtab)
+ if (rcookie->rel->r_offset > offset)
+ return FALSE;
+ if (rcookie->rel->r_offset != offset)
+ continue;
+
+ r_symndx = rcookie->rel->r_info >> rcookie->r_sym_shift;
+ if (r_symndx == STN_UNDEF)
+ return TRUE;
+
+ if (r_symndx >= rcookie->locsymcount
+ || ELF_ST_BIND (rcookie->locsyms[r_symndx].st_info) != STB_LOCAL)
+ {
+ struct elf_link_hash_entry *h;
+
+ h = rcookie->sym_hashes[r_symndx - rcookie->extsymoff];
+
+ 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)
+ && (h->root.u.def.section->owner != rcookie->abfd
+ || h->root.u.def.section->kept_section != NULL
+ || discarded_section (h->root.u.def.section)))
+ return TRUE;
+ }
+ else
+ {
+ /* It's not a relocation against a global symbol,
+ but it could be a relocation against a local
+ symbol for a discarded section. */
+ asection *isec;
+ Elf_Internal_Sym *isym;
+
+ /* Need to: get the symbol; get the section. */
+ isym = &rcookie->locsyms[r_symndx];
+ isec = bfd_section_from_elf_index (rcookie->abfd, isym->st_shndx);
+ if (isec != NULL
+ && (isec->kept_section != NULL
+ || discarded_section (isec)))
+ return TRUE;
+ }
+ return FALSE;
+ }
+ return FALSE;
+}
+
+/* Discard unneeded references to discarded sections.
+ Returns -1 on error, 1 if any section's size was changed, 0 if
+ nothing changed. This function assumes that the relocations are in
+ sorted order, which is true for all known assemblers. */
+
+int
+bfd_elf_discard_info (bfd *output_bfd, struct bfd_link_info *info)
+{
+ struct elf_reloc_cookie cookie;
+ asection *o;
+ bfd *abfd;
+ int changed = 0;
+
+ if (info->traditional_format
+ || !is_elf_hash_table (info->hash))
+ return 0;
+
+ o = bfd_get_section_by_name (output_bfd, ".stab");
+ if (o != NULL)
+ {
+ asection *i;
+
+ for (i = o->map_head.s; i != NULL; i = i->map_head.s)
+ {
+ if (i->size == 0
+ || i->reloc_count == 0
+ || i->sec_info_type != SEC_INFO_TYPE_STABS)
+ continue;
+
+ abfd = i->owner;
+ if (bfd_get_flavour (abfd) != bfd_target_elf_flavour)
+ continue;
+
+ if (!init_reloc_cookie_for_section (&cookie, info, i))
+ return -1;
+
+ if (_bfd_discard_section_stabs (abfd, i,
+ elf_section_data (i)->sec_info,
+ bfd_elf_reloc_symbol_deleted_p,
+ &cookie))
+ changed = 1;
+
+ fini_reloc_cookie_for_section (&cookie, i);
+ }
+ }
+
+ o = bfd_get_section_by_name (output_bfd, ".eh_frame");
+ if (o != NULL)
+ {
+ asection *i;
+
+ for (i = o->map_head.s; i != NULL; i = i->map_head.s)
+ {
+ if (i->size == 0)
+ continue;
+
+ abfd = i->owner;
+ if (bfd_get_flavour (abfd) != bfd_target_elf_flavour)
+ continue;
+
+ if (!init_reloc_cookie_for_section (&cookie, info, i))
+ return -1;
+
+ _bfd_elf_parse_eh_frame (abfd, info, i, &cookie);
+ if (_bfd_elf_discard_section_eh_frame (abfd, info, i,
+ bfd_elf_reloc_symbol_deleted_p,
+ &cookie))
+ changed = 1;
+
+ fini_reloc_cookie_for_section (&cookie, i);
+ }
+ }
+
+ for (abfd = info->input_bfds; abfd != NULL; abfd = abfd->link.next)
+ {
+ const struct elf_backend_data *bed;
+
+ if (bfd_get_flavour (abfd) != bfd_target_elf_flavour)
+ continue;
+
+ bed = get_elf_backend_data (abfd);
+
+ if (bed->elf_backend_discard_info != NULL)
+ {
+ if (!init_reloc_cookie (&cookie, info, abfd))
+ return -1;
+
+ if ((*bed->elf_backend_discard_info) (abfd, &cookie, info))
+ changed = 1;
+
+ fini_reloc_cookie (&cookie, abfd);
+ }
+ }
+
+ if (info->eh_frame_hdr
+ && !info->relocatable
+ && _bfd_elf_discard_section_eh_frame_hdr (output_bfd, info))
+ changed = 1;
+
+ return changed;
+}
+
+bfd_boolean
+_bfd_elf_section_already_linked (bfd *abfd,
+ asection *sec,
+ struct bfd_link_info *info)
+{
+ flagword flags;
+ const char *name, *key;
+ struct bfd_section_already_linked *l;
+ struct bfd_section_already_linked_hash_entry *already_linked_list;
+
+ if (sec->output_section == bfd_abs_section_ptr)
+ return FALSE;
+
+ flags = sec->flags;
+
+ /* Return if it isn't a linkonce section. A comdat group section
+ also has SEC_LINK_ONCE set. */
+ if ((flags & SEC_LINK_ONCE) == 0)
+ return FALSE;
+
+ /* Don't put group member sections on our list of already linked
+ sections. They are handled as a group via their group section. */
+ if (elf_sec_group (sec) != NULL)
+ return FALSE;
+
+ /* For a SHT_GROUP section, use the group signature as the key. */
+ name = sec->name;
+ if ((flags & SEC_GROUP) != 0
+ && elf_next_in_group (sec) != NULL
+ && elf_group_name (elf_next_in_group (sec)) != NULL)
+ key = elf_group_name (elf_next_in_group (sec));
+ else
+ {
+ /* Otherwise we should have a .gnu.linkonce.<type>.<key> section. */
+ if (CONST_STRNEQ (name, ".gnu.linkonce.")
+ && (key = strchr (name + sizeof (".gnu.linkonce.") - 1, '.')) != NULL)
+ key++;
+ else
+ /* Must be a user linkonce section that doesn't follow gcc's
+ naming convention. In this case we won't be matching
+ single member groups. */
+ key = name;
+ }
+
+ already_linked_list = bfd_section_already_linked_table_lookup (key);
+
+ for (l = already_linked_list->entry; l != NULL; l = l->next)
+ {
+ /* We may have 2 different types of sections on the list: group
+ sections with a signature of <key> (<key> is some string),
+ and linkonce sections named .gnu.linkonce.<type>.<key>.
+ Match like sections. LTO plugin sections are an exception.
+ They are always named .gnu.linkonce.t.<key> and match either
+ type of section. */
+ if (((flags & SEC_GROUP) == (l->sec->flags & SEC_GROUP)
+ && ((flags & SEC_GROUP) != 0
+ || strcmp (name, l->sec->name) == 0))
+ || (l->sec->owner->flags & BFD_PLUGIN) != 0)
+ {
+ /* The section has already been linked. See if we should
+ issue a warning. */
+ if (!_bfd_handle_already_linked (sec, l, info))
+ return FALSE;
+
+ if (flags & SEC_GROUP)
+ {
+ asection *first = elf_next_in_group (sec);
+ asection *s = first;
+
+ while (s != NULL)
+ {
+ s->output_section = bfd_abs_section_ptr;
+ /* Record which group discards it. */
+ s->kept_section = l->sec;
+ s = elf_next_in_group (s);
+ /* These lists are circular. */
+ if (s == first)
+ break;
+ }
+ }
+
+ return TRUE;
+ }
+ }
+
+ /* A single member comdat group section may be discarded by a
+ linkonce section and vice versa. */
+ if ((flags & SEC_GROUP) != 0)
+ {
+ asection *first = elf_next_in_group (sec);
+
+ if (first != NULL && elf_next_in_group (first) == first)
+ /* Check this single member group against linkonce sections. */
+ for (l = already_linked_list->entry; l != NULL; l = l->next)
+ if ((l->sec->flags & SEC_GROUP) == 0
+ && bfd_elf_match_symbols_in_sections (l->sec, first, info))
+ {
+ first->output_section = bfd_abs_section_ptr;
+ first->kept_section = l->sec;
+ sec->output_section = bfd_abs_section_ptr;
+ break;
+ }
+ }
+ else
+ /* Check this linkonce section against single member groups. */
+ for (l = already_linked_list->entry; l != NULL; l = l->next)
+ if (l->sec->flags & SEC_GROUP)
+ {
+ asection *first = elf_next_in_group (l->sec);
+
+ if (first != NULL
+ && elf_next_in_group (first) == first
+ && bfd_elf_match_symbols_in_sections (first, sec, info))
+ {
+ sec->output_section = bfd_abs_section_ptr;
+ sec->kept_section = first;
+ break;
+ }
+ }
+
+ /* Do not complain on unresolved relocations in `.gnu.linkonce.r.F'
+ referencing its discarded `.gnu.linkonce.t.F' counterpart - g++-3.4
+ specific as g++-4.x is using COMDAT groups (without the `.gnu.linkonce'
+ prefix) instead. `.gnu.linkonce.r.*' were the `.rodata' part of its
+ matching `.gnu.linkonce.t.*'. If `.gnu.linkonce.r.F' is not discarded
+ but its `.gnu.linkonce.t.F' is discarded means we chose one-only
+ `.gnu.linkonce.t.F' section from a different bfd not requiring any
+ `.gnu.linkonce.r.F'. Thus `.gnu.linkonce.r.F' should be discarded.
+ The reverse order cannot happen as there is never a bfd with only the
+ `.gnu.linkonce.r.F' section. The order of sections in a bfd does not
+ matter as here were are looking only for cross-bfd sections. */
+
+ if ((flags & SEC_GROUP) == 0 && CONST_STRNEQ (name, ".gnu.linkonce.r."))
+ for (l = already_linked_list->entry; l != NULL; l = l->next)
+ if ((l->sec->flags & SEC_GROUP) == 0
+ && CONST_STRNEQ (l->sec->name, ".gnu.linkonce.t."))
+ {
+ if (abfd != l->sec->owner)
+ sec->output_section = bfd_abs_section_ptr;
+ break;
+ }
+
+ /* This is the first section with this name. Record it. */
+ if (!bfd_section_already_linked_table_insert (already_linked_list, sec))
+ info->callbacks->einfo (_("%F%P: already_linked_table: %E\n"));
+ return sec->output_section == bfd_abs_section_ptr;
+}
+
+bfd_boolean
+_bfd_elf_common_definition (Elf_Internal_Sym *sym)
+{
+ return sym->st_shndx == SHN_COMMON;
+}
+
+unsigned int
+_bfd_elf_common_section_index (asection *sec ATTRIBUTE_UNUSED)
+{
+ return SHN_COMMON;
+}
+
+asection *
+_bfd_elf_common_section (asection *sec ATTRIBUTE_UNUSED)
+{
+ return bfd_com_section_ptr;
+}
+
+bfd_vma
+_bfd_elf_default_got_elt_size (bfd *abfd,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ struct elf_link_hash_entry *h ATTRIBUTE_UNUSED,
+ bfd *ibfd ATTRIBUTE_UNUSED,
+ unsigned long symndx ATTRIBUTE_UNUSED)
+{
+ const struct elf_backend_data *bed = get_elf_backend_data (abfd);
+ return bed->s->arch_size / 8;
+}
+
+/* Routines to support the creation of dynamic relocs. */
+
+/* Returns the name of the dynamic reloc section associated with SEC. */
+
+static const char *
+get_dynamic_reloc_section_name (bfd * abfd,
+ asection * sec,
+ bfd_boolean is_rela)
+{
+ char *name;
+ const char *old_name = bfd_get_section_name (NULL, sec);
+ const char *prefix = is_rela ? ".rela" : ".rel";
+
+ if (old_name == NULL)
+ return NULL;
+
+ name = bfd_alloc (abfd, strlen (prefix) + strlen (old_name) + 1);
+ sprintf (name, "%s%s", prefix, old_name);
+
+ return name;
+}
+
+/* Returns the dynamic reloc section associated with SEC.
+ If necessary compute the name of the dynamic reloc section based
+ on SEC's name (looked up in ABFD's string table) and the setting
+ of IS_RELA. */
+
+asection *
+_bfd_elf_get_dynamic_reloc_section (bfd * abfd,
+ asection * sec,
+ bfd_boolean is_rela)
+{
+ asection * reloc_sec = elf_section_data (sec)->sreloc;
+
+ if (reloc_sec == NULL)
+ {
+ const char * name = get_dynamic_reloc_section_name (abfd, sec, is_rela);
+
+ if (name != NULL)
+ {
+ reloc_sec = bfd_get_linker_section (abfd, name);
+
+ if (reloc_sec != NULL)
+ elf_section_data (sec)->sreloc = reloc_sec;
+ }
+ }
+
+ return reloc_sec;
+}
+
+/* Returns the dynamic reloc section associated with SEC. If the
+ section does not exist it is created and attached to the DYNOBJ
+ bfd and stored in the SRELOC field of SEC's elf_section_data
+ structure.
+
+ ALIGNMENT is the alignment for the newly created section and
+ IS_RELA defines whether the name should be .rela.<SEC's name>
+ or .rel.<SEC's name>. The section name is looked up in the
+ string table associated with ABFD. */
+
+asection *
+_bfd_elf_make_dynamic_reloc_section (asection * sec,
+ bfd * dynobj,
+ unsigned int alignment,
+ bfd * abfd,
+ bfd_boolean is_rela)
+{
+ asection * reloc_sec = elf_section_data (sec)->sreloc;
+
+ if (reloc_sec == NULL)
+ {
+ const char * name = get_dynamic_reloc_section_name (abfd, sec, is_rela);
+
+ if (name == NULL)
+ return NULL;
+
+ reloc_sec = bfd_get_linker_section (dynobj, name);
+
+ if (reloc_sec == NULL)
+ {
+ flagword flags = (SEC_HAS_CONTENTS | SEC_READONLY
+ | SEC_IN_MEMORY | SEC_LINKER_CREATED);
+ if ((sec->flags & SEC_ALLOC) != 0)
+ flags |= SEC_ALLOC | SEC_LOAD;
+
+ reloc_sec = bfd_make_section_anyway_with_flags (dynobj, name, flags);
+ if (reloc_sec != NULL)
+ {
+ /* _bfd_elf_get_sec_type_attr chooses a section type by
+ name. Override as it may be wrong, eg. for a user
+ section named "auto" we'll get ".relauto" which is
+ seen to be a .rela section. */
+ elf_section_type (reloc_sec) = is_rela ? SHT_RELA : SHT_REL;
+ if (! bfd_set_section_alignment (dynobj, reloc_sec, alignment))
+ reloc_sec = NULL;
+ }
+ }
+
+ elf_section_data (sec)->sreloc = reloc_sec;
+ }
+
+ return reloc_sec;
+}
+
+/* Copy the ELF symbol type and other attributes for a linker script
+ assignment from HSRC to HDEST. Generally this should be treated as
+ if we found a strong non-dynamic definition for HDEST (except that
+ ld ignores multiple definition errors). */
+void
+_bfd_elf_copy_link_hash_symbol_type (bfd *abfd,
+ struct bfd_link_hash_entry *hdest,
+ struct bfd_link_hash_entry *hsrc)
+{
+ struct elf_link_hash_entry *ehdest = (struct elf_link_hash_entry *) hdest;
+ struct elf_link_hash_entry *ehsrc = (struct elf_link_hash_entry *) hsrc;
+ Elf_Internal_Sym isym;
+
+ ehdest->type = ehsrc->type;
+ ehdest->target_internal = ehsrc->target_internal;
+
+ isym.st_other = ehsrc->other;
+ elf_merge_st_other (abfd, ehdest, &isym, TRUE, FALSE);
+}
+
+/* Append a RELA relocation REL to section S in BFD. */
+
+void
+elf_append_rela (bfd *abfd, asection *s, Elf_Internal_Rela *rel)
+{
+ const struct elf_backend_data *bed = get_elf_backend_data (abfd);
+ bfd_byte *loc = s->contents + (s->reloc_count++ * bed->s->sizeof_rela);
+ BFD_ASSERT (loc + bed->s->sizeof_rela <= s->contents + s->size);
+ bed->s->swap_reloca_out (abfd, rel, loc);
+}
+
+/* Append a REL relocation REL to section S in BFD. */
+
+void
+elf_append_rel (bfd *abfd, asection *s, Elf_Internal_Rela *rel)
+{
+ const struct elf_backend_data *bed = get_elf_backend_data (abfd);
+ bfd_byte *loc = s->contents + (s->reloc_count++ * bed->s->sizeof_rel);
+ BFD_ASSERT (loc + bed->s->sizeof_rel <= s->contents + s->size);
+ bed->s->swap_reloc_out (abfd, rel, loc);
+}
diff --git a/bfd/elfn32-mips.c b/bfd/elfn32-mips.c
new file mode 100644
index 0000000..9ddde24
--- /dev/null
+++ b/bfd/elfn32-mips.c
@@ -0,0 +1,3742 @@
+/* MIPS-specific support for 32-bit ELF
+ Copyright (C) 1993-2014 Free Software Foundation, Inc.
+
+ Most of the information added by Ian Lance Taylor, Cygnus Support,
+ <ian@cygnus.com>.
+ N32/64 ABI support added by Mark Mitchell, CodeSourcery, LLC.
+ <mark@codesourcery.com>
+ Traditional MIPS targets support added by Koundinya.K, Dansk Data
+ Elektronik & Operations Research Group. <kk@ddeorg.soft.net>
+
+ This file is part of BFD, the Binary File Descriptor library.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, 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 "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+#include "bfdlink.h"
+#include "genlink.h"
+#include "elf-bfd.h"
+#include "elfxx-mips.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_SIGNED_32
+#include "ecoffswap.h"
+
+static bfd_boolean mips_elf_assign_gp
+ (bfd *, bfd_vma *);
+static bfd_reloc_status_type mips_elf_final_gp
+ (bfd *, asymbol *, bfd_boolean, char **, bfd_vma *);
+static bfd_reloc_status_type mips_elf_gprel16_reloc
+ (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
+static bfd_reloc_status_type mips_elf_literal_reloc
+ (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
+static bfd_reloc_status_type mips_elf_gprel32_reloc
+ (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
+static bfd_reloc_status_type gprel32_with_gp
+ (bfd *, asymbol *, arelent *, asection *, bfd_boolean, void *, bfd_vma);
+static bfd_reloc_status_type mips_elf_shift6_reloc
+ (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
+static bfd_reloc_status_type mips16_gprel_reloc
+ (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
+static reloc_howto_type *bfd_elf32_bfd_reloc_type_lookup
+ (bfd *, bfd_reloc_code_real_type);
+static reloc_howto_type *mips_elf_n32_rtype_to_howto
+ (unsigned int, bfd_boolean);
+static void mips_info_to_howto_rel
+ (bfd *, arelent *, Elf_Internal_Rela *);
+static void mips_info_to_howto_rela
+ (bfd *, arelent *, Elf_Internal_Rela *);
+static bfd_boolean mips_elf_sym_is_global
+ (bfd *, asymbol *);
+static bfd_boolean mips_elf_n32_object_p
+ (bfd *);
+static bfd_boolean elf32_mips_grok_prstatus
+ (bfd *, Elf_Internal_Note *);
+static bfd_boolean elf32_mips_grok_psinfo
+ (bfd *, Elf_Internal_Note *);
+static irix_compat_t elf_n32_mips_irix_compat
+ (bfd *);
+
+extern const bfd_target mips_elf32_n_be_vec;
+extern const bfd_target mips_elf32_n_le_vec;
+
+/* Nonzero if ABFD is using the N32 ABI. */
+#define ABI_N32_P(abfd) \
+ ((elf_elfheader (abfd)->e_flags & EF_MIPS_ABI2) != 0)
+
+/* Whether we are trying to be compatible with IRIX at all. */
+#define SGI_COMPAT(abfd) \
+ (elf_n32_mips_irix_compat (abfd) != ict_none)
+
+/* The number of local .got entries we reserve. */
+#define MIPS_RESERVED_GOTNO (2)
+
+/* 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 elf_mips_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_mips_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 */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_16", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* 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_dont, /* complain_on_overflow */
+ _bfd_mips_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_dont, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_REL32", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* 26 bit jump 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 + 4. */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_26", /* name */
+ TRUE, /* partial_inplace */
+ 0x03ffffff, /* src_mask */
+ 0x03ffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* R_MIPS_HI16 and R_MIPS_LO16 are unsupported for NewABI REL.
+ However, the native IRIX6 tools use them, so we try our best. */
+
+ /* High 16 bits of symbol value. */
+ HOWTO (R_MIPS_HI16, /* type */
+ 16, /* 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 */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* 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 */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* 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 */
+ mips_elf_gprel16_reloc, /* special_function */
+ "R_MIPS_GPREL16", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* 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 */
+ mips_elf_literal_reloc, /* special_function */
+ "R_MIPS_LITERAL", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* 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 */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* 16 bit PC relative reference. Note that the ABI document has a typo
+ and claims R_MIPS_PC16 to be not rightshifted, rendering it useless.
+ We do the right thing here. */
+ HOWTO (R_MIPS_PC16, /* 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_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_PC16", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* 16 bit call through global offset table. */
+ 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_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_CALL16", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* 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_dont, /* complain_on_overflow */
+ 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. */
+ EMPTY_HOWTO (13),
+ EMPTY_HOWTO (14),
+ EMPTY_HOWTO (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_mips_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. */
+ 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 */
+ mips_elf_shift6_reloc, /* special_function */
+ "R_MIPS_SHIFT6", /* name */
+ TRUE, /* partial_inplace */
+ 0x000007c4, /* src_mask */
+ 0x000007c4, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A 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_dont, /* complain_on_overflow */
+ _bfd_mips_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. */
+ 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_signed, /* complain_on_overflow */
+ _bfd_mips_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. */
+ 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_signed, /* complain_on_overflow */
+ _bfd_mips_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. */
+ 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_signed, /* complain_on_overflow */
+ _bfd_mips_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. */
+ 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_mips_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. */
+ 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_mips_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. */
+ HOWTO (R_MIPS_SUB, /* type */
+ 0, /* rightshift */
+ 4, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ _bfd_mips_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 */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_INSERT_A", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* 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 */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_INSERT_B", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Delete a 32 bit instruction. */
+ /* FIXME: Not handled correctly. */
+ HOWTO (R_MIPS_DELETE, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_DELETE", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* The MIPS ELF64 ABI Draft wants us to support these for REL relocations.
+ We don't, because
+ a) It means building the addend from a R_MIPS_HIGHEST/R_MIPS_HIGHER/
+ R_MIPS_HI16/R_MIPS_LO16 sequence with varying ordering, using
+ fallable heuristics.
+ b) No other NewABI toolchain actually emits such relocations. */
+ EMPTY_HOWTO (R_MIPS_HIGHER),
+ EMPTY_HOWTO (R_MIPS_HIGHEST),
+
+ /* High 16 bits of displacement in global offset table. */
+ 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_mips_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. */
+ 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_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_CALL_LO16", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Section displacement. */
+ HOWTO (R_MIPS_SCN_DISP, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_SCN_DISP", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_MIPS_REL16, /* 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_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_REL16", /* name */
+ TRUE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* These two are obsolete. */
+ EMPTY_HOWTO (R_MIPS_ADD_IMMEDIATE),
+ EMPTY_HOWTO (R_MIPS_PJUMP),
+
+ /* Similiar to R_MIPS_REL32, but used for relocations in a GOT section.
+ It must be used for multigot GOT's (and only there). */
+ HOWTO (R_MIPS_RELGOT, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_RELGOT", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Protected jump conversion. This is an optimization hint. No
+ relocation is required for correctness. */
+ HOWTO (R_MIPS_JALR, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_JALR", /* name */
+ FALSE, /* partial_inplace */
+ 0x00000000, /* src_mask */
+ 0x00000000, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* TLS GD/LD dynamic relocations. */
+ HOWTO (R_MIPS_TLS_DTPMOD32, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_TLS_DTPMOD32", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_MIPS_TLS_DTPREL32, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_TLS_DTPREL32", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ EMPTY_HOWTO (R_MIPS_TLS_DTPMOD64),
+ EMPTY_HOWTO (R_MIPS_TLS_DTPREL64),
+
+ /* TLS general dynamic variable reference. */
+ HOWTO (R_MIPS_TLS_GD, /* 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_generic_reloc, /* special_function */
+ "R_MIPS_TLS_GD", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* TLS local dynamic variable reference. */
+ HOWTO (R_MIPS_TLS_LDM, /* 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_generic_reloc, /* special_function */
+ "R_MIPS_TLS_LDM", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* TLS local dynamic offset. */
+ HOWTO (R_MIPS_TLS_DTPREL_HI16, /* 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_generic_reloc, /* special_function */
+ "R_MIPS_TLS_DTPREL_HI16", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* TLS local dynamic offset. */
+ HOWTO (R_MIPS_TLS_DTPREL_LO16, /* 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_generic_reloc, /* special_function */
+ "R_MIPS_TLS_DTPREL_LO16", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* TLS thread pointer offset. */
+ HOWTO (R_MIPS_TLS_GOTTPREL, /* 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_generic_reloc, /* special_function */
+ "R_MIPS_TLS_GOTTPREL", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* TLS IE dynamic relocations. */
+ HOWTO (R_MIPS_TLS_TPREL32, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_TLS_TPREL32", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ EMPTY_HOWTO (R_MIPS_TLS_TPREL64),
+
+ /* TLS thread pointer offset. */
+ HOWTO (R_MIPS_TLS_TPREL_HI16, /* 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_generic_reloc, /* special_function */
+ "R_MIPS_TLS_TPREL_HI16", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* TLS thread pointer offset. */
+ HOWTO (R_MIPS_TLS_TPREL_LO16, /* 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_generic_reloc, /* special_function */
+ "R_MIPS_TLS_TPREL_LO16", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* 32 bit relocation with no addend. */
+ HOWTO (R_MIPS_GLOB_DAT, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_GLOB_DAT", /* name */
+ FALSE, /* partial_inplace */
+ 0x0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ EMPTY_HOWTO (52),
+ EMPTY_HOWTO (53),
+ EMPTY_HOWTO (54),
+ EMPTY_HOWTO (55),
+ EMPTY_HOWTO (56),
+ EMPTY_HOWTO (57),
+ EMPTY_HOWTO (58),
+ EMPTY_HOWTO (59),
+
+ HOWTO (R_MIPS_PC21_S2, /* type */
+ 2, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 21, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_PC21_S2", /* name */
+ TRUE, /* partial_inplace */
+ 0x001fffff, /* src_mask */
+ 0x001fffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_MIPS_PC26_S2, /* 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_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_PC26_S2", /* name */
+ TRUE, /* partial_inplace */
+ 0x03ffffff, /* src_mask */
+ 0x03ffffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_MIPS_PC18_S3, /* 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_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_PC18_S3", /* name */
+ TRUE, /* partial_inplace */
+ 0x0003ffff, /* src_mask */
+ 0x0003ffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_MIPS_PC19_S2, /* type */
+ 2, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 19, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_PC19_S2", /* name */
+ TRUE, /* partial_inplace */
+ 0x0007ffff, /* src_mask */
+ 0x0007ffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_MIPS_PCHI16, /* type */
+ 16, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_PCHI16", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_MIPS_PCLO16, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_PCLO16", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+};
+
+/* The relocation table used for SHT_RELA sections. */
+
+static reloc_howto_type elf_mips_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_mips_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 */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000, /* 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_dont, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_32", /* name */
+ FALSE, /* 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_dont, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_REL32", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* 26 bit jump 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 36
+ bits must match the PC + 4. */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_26", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x03ffffff, /* 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_generic_reloc, /* special_function */
+ "R_MIPS_HI16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* 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_generic_reloc, /* special_function */
+ "R_MIPS_LO16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* 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 */
+ mips_elf_gprel16_reloc, /* special_function */
+ "R_MIPS_GPREL16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* 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 */
+ mips_elf_literal_reloc, /* special_function */
+ "R_MIPS_LITERAL", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* 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_generic_reloc, /* special_function */
+ "R_MIPS_GOT16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* 16 bit PC relative reference. Note that the ABI document has a typo
+ and claims R_MIPS_PC16 to be not rightshifted, rendering it useless.
+ We do the right thing here. */
+ HOWTO (R_MIPS_PC16, /* 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_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_PC16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* 16 bit call through global offset table. */
+ 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_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_CALL16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* 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_dont, /* complain_on_overflow */
+ mips_elf_gprel32_reloc, /* special_function */
+ "R_MIPS_GPREL32", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ EMPTY_HOWTO (13),
+ EMPTY_HOWTO (14),
+ EMPTY_HOWTO (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_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_SHIFT5", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x000007c0, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A 6 bit shift field. */
+ 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 */
+ mips_elf_shift6_reloc, /* special_function */
+ "R_MIPS_SHIFT6", /* name */
+ FALSE, /* 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_dont, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_64", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ MINUS_ONE, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Displacement in the global offset table. */
+ 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_signed, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_GOT_DISP", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Displacement to page pointer in the global offset table. */
+ 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_signed, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_GOT_PAGE", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Offset from page pointer in the global offset table. */
+ 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_signed, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_GOT_OFST", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* High 16 bits of displacement in global offset table. */
+ 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_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_GOT_HI16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Low 16 bits of displacement in global offset table. */
+ 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_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_GOT_LO16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* 64 bit subtraction. */
+ HOWTO (R_MIPS_SUB, /* type */
+ 0, /* rightshift */
+ 4, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_SUB", /* name */
+ FALSE, /* 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 */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_INSERT_A", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffffffff, /* 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 */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_INSERT_B", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Delete a 32 bit instruction. */
+ /* FIXME: Not handled correctly. */
+ HOWTO (R_MIPS_DELETE, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_DELETE", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Get the higher value of a 64 bit addend. */
+ 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_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_HIGHER", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Get the highest value of a 64 bit addend. */
+ 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_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_HIGHEST", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* High 16 bits of displacement in global offset table. */
+ 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_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_CALL_HI16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Low 16 bits of displacement in global offset table. */
+ 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_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_CALL_LO16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Section displacement, used by an associated event location section. */
+ HOWTO (R_MIPS_SCN_DISP, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_SCN_DISP", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* 16 bit relocation. */
+ HOWTO (R_MIPS_REL16, /* 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_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_REL16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* These two are obsolete. */
+ EMPTY_HOWTO (R_MIPS_ADD_IMMEDIATE),
+ EMPTY_HOWTO (R_MIPS_PJUMP),
+
+ /* Similiar to R_MIPS_REL32, but used for relocations in a GOT section.
+ It must be used for multigot GOT's (and only there). */
+ HOWTO (R_MIPS_RELGOT, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_RELGOT", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Protected jump conversion. This is an optimization hint. No
+ relocation is required for correctness. */
+ HOWTO (R_MIPS_JALR, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_JALR", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* TLS GD/LD dynamic relocations. */
+ HOWTO (R_MIPS_TLS_DTPMOD32, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_TLS_DTPMOD32", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_MIPS_TLS_DTPREL32, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_TLS_DTPREL32", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ EMPTY_HOWTO (R_MIPS_TLS_DTPMOD64),
+ EMPTY_HOWTO (R_MIPS_TLS_DTPREL64),
+
+ /* TLS general dynamic variable reference. */
+ HOWTO (R_MIPS_TLS_GD, /* 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_generic_reloc, /* special_function */
+ "R_MIPS_TLS_GD", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* TLS local dynamic variable reference. */
+ HOWTO (R_MIPS_TLS_LDM, /* 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_generic_reloc, /* special_function */
+ "R_MIPS_TLS_LDM", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* TLS local dynamic offset. */
+ HOWTO (R_MIPS_TLS_DTPREL_HI16, /* 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_generic_reloc, /* special_function */
+ "R_MIPS_TLS_DTPREL_HI16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* TLS local dynamic offset. */
+ HOWTO (R_MIPS_TLS_DTPREL_LO16, /* 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_generic_reloc, /* special_function */
+ "R_MIPS_TLS_DTPREL_LO16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* TLS thread pointer offset. */
+ HOWTO (R_MIPS_TLS_GOTTPREL, /* 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_generic_reloc, /* special_function */
+ "R_MIPS_TLS_GOTTPREL", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* TLS IE dynamic relocations. */
+ HOWTO (R_MIPS_TLS_TPREL32, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_TLS_TPREL32", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ EMPTY_HOWTO (R_MIPS_TLS_TPREL64),
+
+ /* TLS thread pointer offset. */
+ HOWTO (R_MIPS_TLS_TPREL_HI16, /* 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_generic_reloc, /* special_function */
+ "R_MIPS_TLS_TPREL_HI16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* TLS thread pointer offset. */
+ HOWTO (R_MIPS_TLS_TPREL_LO16, /* 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_generic_reloc, /* special_function */
+ "R_MIPS_TLS_TPREL_LO16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* 32 bit relocation with no addend. */
+ HOWTO (R_MIPS_GLOB_DAT, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_GLOB_DAT", /* name */
+ FALSE, /* partial_inplace */
+ 0x0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ EMPTY_HOWTO (52),
+ EMPTY_HOWTO (53),
+ EMPTY_HOWTO (54),
+ EMPTY_HOWTO (55),
+ EMPTY_HOWTO (56),
+ EMPTY_HOWTO (57),
+ EMPTY_HOWTO (58),
+ EMPTY_HOWTO (59),
+
+ HOWTO (R_MIPS_PC21_S2, /* type */
+ 2, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 21, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_PC21_S2", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x001fffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_MIPS_PC26_S2, /* 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_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_PC26_S2", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x03ffffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_MIPS_PC18_S3, /* 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_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_PC18_S3", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0003ffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_MIPS_PC19_S2, /* type */
+ 2, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 19, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_PC19_S2", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0007ffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_MIPS_PCHI16, /* type */
+ 16, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_PCHI16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_MIPS_PCLO16, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_PCLO16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+};
+
+static reloc_howto_type elf_mips16_howto_table_rel[] =
+{
+ /* The reloc used for the mips16 jump instruction. */
+ 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. */
+ _bfd_mips_elf_generic_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. */
+ 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 */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A MIPS16 reference to the global offset table. */
+ HOWTO (R_MIPS16_GOT16, /* 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_got16_reloc, /* special_function */
+ "R_MIPS16_GOT16", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A MIPS16 call through the global offset table. */
+ HOWTO (R_MIPS16_CALL16, /* 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_generic_reloc, /* special_function */
+ "R_MIPS16_CALL16", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* MIPS16 high 16 bits of symbol value. */
+ HOWTO (R_MIPS16_HI16, /* type */
+ 16, /* 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_MIPS16_HI16", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* MIPS16 low 16 bits of symbol value. */
+ HOWTO (R_MIPS16_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_MIPS16_LO16", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* MIPS16 TLS general dynamic variable reference. */
+ HOWTO (R_MIPS16_TLS_GD, /* 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_generic_reloc, /* special_function */
+ "R_MIPS16_TLS_GD", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* MIPS16 TLS local dynamic variable reference. */
+ HOWTO (R_MIPS16_TLS_LDM, /* 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_generic_reloc, /* special_function */
+ "R_MIPS16_TLS_LDM", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* MIPS16 TLS local dynamic offset. */
+ HOWTO (R_MIPS16_TLS_DTPREL_HI16, /* 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_generic_reloc, /* special_function */
+ "R_MIPS16_TLS_DTPREL_HI16", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* MIPS16 TLS local dynamic offset. */
+ HOWTO (R_MIPS16_TLS_DTPREL_LO16, /* 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_generic_reloc, /* special_function */
+ "R_MIPS16_TLS_DTPREL_LO16", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* MIPS16 TLS thread pointer offset. */
+ HOWTO (R_MIPS16_TLS_GOTTPREL, /* 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_generic_reloc, /* special_function */
+ "R_MIPS16_TLS_GOTTPREL", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* MIPS16 TLS thread pointer offset. */
+ HOWTO (R_MIPS16_TLS_TPREL_HI16, /* 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_generic_reloc, /* special_function */
+ "R_MIPS16_TLS_TPREL_HI16", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* MIPS16 TLS thread pointer offset. */
+ HOWTO (R_MIPS16_TLS_TPREL_LO16, /* 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_generic_reloc, /* special_function */
+ "R_MIPS16_TLS_TPREL_LO16", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+};
+
+static reloc_howto_type elf_mips16_howto_table_rela[] =
+{
+ /* The reloc used for the mips16 jump instruction. */
+ 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. */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS16_26", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x3ffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* The reloc used for the mips16 gprel instruction. */
+ 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 */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A MIPS16 reference to the global offset table. */
+ HOWTO (R_MIPS16_GOT16, /* 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_got16_reloc, /* special_function */
+ "R_MIPS16_GOT16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A MIPS16 call through the global offset table. */
+ HOWTO (R_MIPS16_CALL16, /* 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_generic_reloc, /* special_function */
+ "R_MIPS16_CALL16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* MIPS16 high 16 bits of symbol value. */
+ HOWTO (R_MIPS16_HI16, /* type */
+ 16, /* 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_MIPS16_HI16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* MIPS16 low 16 bits of symbol value. */
+ HOWTO (R_MIPS16_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_MIPS16_LO16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* MIPS16 TLS general dynamic variable reference. */
+ HOWTO (R_MIPS16_TLS_GD, /* 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_generic_reloc, /* special_function */
+ "R_MIPS16_TLS_GD", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* MIPS16 TLS local dynamic variable reference. */
+ HOWTO (R_MIPS16_TLS_LDM, /* 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_generic_reloc, /* special_function */
+ "R_MIPS16_TLS_LDM", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* MIPS16 TLS local dynamic offset. */
+ HOWTO (R_MIPS16_TLS_DTPREL_HI16, /* 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_generic_reloc, /* special_function */
+ "R_MIPS16_TLS_DTPREL_HI16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* MIPS16 TLS local dynamic offset. */
+ HOWTO (R_MIPS16_TLS_DTPREL_LO16, /* 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_generic_reloc, /* special_function */
+ "R_MIPS16_TLS_DTPREL_LO16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* MIPS16 TLS thread pointer offset. */
+ HOWTO (R_MIPS16_TLS_GOTTPREL, /* 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_generic_reloc, /* special_function */
+ "R_MIPS16_TLS_GOTTPREL", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* MIPS16 TLS thread pointer offset. */
+ HOWTO (R_MIPS16_TLS_TPREL_HI16, /* 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_generic_reloc, /* special_function */
+ "R_MIPS16_TLS_TPREL_HI16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* MIPS16 TLS thread pointer offset. */
+ HOWTO (R_MIPS16_TLS_TPREL_LO16, /* 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_generic_reloc, /* special_function */
+ "R_MIPS16_TLS_TPREL_LO16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+};
+
+static reloc_howto_type elf_micromips_howto_table_rel[] =
+{
+ EMPTY_HOWTO (130),
+ EMPTY_HOWTO (131),
+ EMPTY_HOWTO (132),
+
+ /* 26 bit jump address. */
+ HOWTO (R_MICROMIPS_26_S1, /* type */
+ 1, /* 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_mips_elf_generic_reloc, /* special_function */
+ "R_MICROMIPS_26_S1", /* name */
+ TRUE, /* partial_inplace */
+ 0x3ffffff, /* src_mask */
+ 0x3ffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* High 16 bits of symbol value. */
+ HOWTO (R_MICROMIPS_HI16, /* type */
+ 16, /* 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_MICROMIPS_HI16", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Low 16 bits of symbol value. */
+ HOWTO (R_MICROMIPS_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_MICROMIPS_LO16", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* GP relative reference. */
+ HOWTO (R_MICROMIPS_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_elf32_gprel16_reloc, /* special_function */
+ "R_MICROMIPS_GPREL16", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Reference to literal section. */
+ HOWTO (R_MICROMIPS_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_elf32_gprel16_reloc, /* special_function */
+ "R_MICROMIPS_LITERAL", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Reference to global offset table. */
+ HOWTO (R_MICROMIPS_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_MICROMIPS_GOT16", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* This is for microMIPS branches. */
+ HOWTO (R_MICROMIPS_PC7_S1, /* type */
+ 1, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 7, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MICROMIPS_PC7_S1", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000007f, /* src_mask */
+ 0x0000007f, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_MICROMIPS_PC10_S1, /* type */
+ 1, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 10, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MICROMIPS_PC10_S1", /* name */
+ TRUE, /* partial_inplace */
+ 0x000003ff, /* src_mask */
+ 0x000003ff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_MICROMIPS_PC16_S1, /* type */
+ 1, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MICROMIPS_PC16_S1", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* 16 bit call through global offset table. */
+ HOWTO (R_MICROMIPS_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_mips_elf_generic_reloc, /* special_function */
+ "R_MICROMIPS_CALL16", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ EMPTY_HOWTO (143),
+ EMPTY_HOWTO (144),
+
+ /* Displacement in the global offset table. */
+ HOWTO (R_MICROMIPS_GOT_DISP, /* 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_generic_reloc, /* special_function */
+ "R_MICROMIPS_GOT_DISP",/* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Displacement to page pointer in the global offset table. */
+ HOWTO (R_MICROMIPS_GOT_PAGE, /* 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_generic_reloc, /* special_function */
+ "R_MICROMIPS_GOT_PAGE",/* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Offset from page pointer in the global offset table. */
+ HOWTO (R_MICROMIPS_GOT_OFST, /* 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_generic_reloc, /* special_function */
+ "R_MICROMIPS_GOT_OFST",/* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* High 16 bits of displacement in global offset table. */
+ HOWTO (R_MICROMIPS_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_mips_elf_generic_reloc, /* special_function */
+ "R_MICROMIPS_GOT_HI16",/* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Low 16 bits of displacement in global offset table. */
+ HOWTO (R_MICROMIPS_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_mips_elf_generic_reloc, /* special_function */
+ "R_MICROMIPS_GOT_LO16",/* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* 64 bit subtraction. Used in the N32 ABI. */
+ HOWTO (R_MICROMIPS_SUB, /* type */
+ 0, /* rightshift */
+ 4, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MICROMIPS_SUB", /* name */
+ TRUE, /* partial_inplace */
+ MINUS_ONE, /* src_mask */
+ MINUS_ONE, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* We don't support these for REL relocations, because it means building
+ the addend from a R_MICROMIPS_HIGHEST/R_MICROMIPS_HIGHER/
+ R_MICROMIPS_HI16/R_MICROMIPS_LO16 sequence with varying ordering,
+ using fallable heuristics. */
+ EMPTY_HOWTO (R_MICROMIPS_HIGHER),
+ EMPTY_HOWTO (R_MICROMIPS_HIGHEST),
+
+ /* High 16 bits of displacement in global offset table. */
+ HOWTO (R_MICROMIPS_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_mips_elf_generic_reloc, /* special_function */
+ "R_MICROMIPS_CALL_HI16",/* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Low 16 bits of displacement in global offset table. */
+ HOWTO (R_MICROMIPS_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_mips_elf_generic_reloc, /* special_function */
+ "R_MICROMIPS_CALL_LO16",/* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Section displacement. */
+ HOWTO (R_MICROMIPS_SCN_DISP, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MICROMIPS_SCN_DISP", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Protected jump conversion. This is an optimization hint. No
+ relocation is required for correctness. */
+ HOWTO (R_MICROMIPS_JALR, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MICROMIPS_JALR", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x00000000, /* dst_mask */
+ FALSE), /* pcrel_offset */
+};
+
+static reloc_howto_type elf_micromips_howto_table_rela[] =
+{
+ EMPTY_HOWTO (130),
+ EMPTY_HOWTO (131),
+ EMPTY_HOWTO (132),
+
+ /* 26 bit jump address. */
+ HOWTO (R_MICROMIPS_26_S1, /* type */
+ 1, /* 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_mips_elf_generic_reloc, /* special_function */
+ "R_MICROMIPS_26_S1", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x3ffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* High 16 bits of symbol value. */
+ HOWTO (R_MICROMIPS_HI16, /* type */
+ 16, /* 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_MICROMIPS_HI16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Low 16 bits of symbol value. */
+ HOWTO (R_MICROMIPS_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_MICROMIPS_LO16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* GP relative reference. */
+ HOWTO (R_MICROMIPS_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_elf32_gprel16_reloc, /* special_function */
+ "R_MICROMIPS_GPREL16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Reference to literal section. */
+ HOWTO (R_MICROMIPS_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_elf32_gprel16_reloc, /* special_function */
+ "R_MICROMIPS_LITERAL", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Reference to global offset table. */
+ HOWTO (R_MICROMIPS_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_MICROMIPS_GOT16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* This is for microMIPS branches. */
+ HOWTO (R_MICROMIPS_PC7_S1, /* type */
+ 1, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 7, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MICROMIPS_PC7_S1", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000007f, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_MICROMIPS_PC10_S1, /* type */
+ 1, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 10, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MICROMIPS_PC10_S1", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x000003ff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_MICROMIPS_PC16_S1, /* type */
+ 1, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MICROMIPS_PC16_S1", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* 16 bit call through global offset table. */
+ HOWTO (R_MICROMIPS_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_mips_elf_generic_reloc, /* special_function */
+ "R_MICROMIPS_CALL16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ EMPTY_HOWTO (143),
+ EMPTY_HOWTO (144),
+
+ /* Displacement in the global offset table. */
+ HOWTO (R_MICROMIPS_GOT_DISP, /* 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_generic_reloc, /* special_function */
+ "R_MICROMIPS_GOT_DISP",/* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Displacement to page pointer in the global offset table. */
+ HOWTO (R_MICROMIPS_GOT_PAGE, /* 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_generic_reloc, /* special_function */
+ "R_MICROMIPS_GOT_PAGE",/* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Offset from page pointer in the global offset table. */
+ HOWTO (R_MICROMIPS_GOT_OFST, /* 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_generic_reloc, /* special_function */
+ "R_MICROMIPS_GOT_OFST",/* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* High 16 bits of displacement in global offset table. */
+ HOWTO (R_MICROMIPS_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_mips_elf_generic_reloc, /* special_function */
+ "R_MICROMIPS_GOT_HI16",/* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Low 16 bits of displacement in global offset table. */
+ HOWTO (R_MICROMIPS_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_mips_elf_generic_reloc, /* special_function */
+ "R_MICROMIPS_GOT_LO16",/* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* 64 bit subtraction. Used in the N32 ABI. */
+ HOWTO (R_MICROMIPS_SUB, /* type */
+ 0, /* rightshift */
+ 4, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MICROMIPS_SUB", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ MINUS_ONE, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Get the higher value of a 64 bit addend. */
+ HOWTO (R_MICROMIPS_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_mips_elf_generic_reloc, /* special_function */
+ "R_MICROMIPS_HIGHER", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Get the highest value of a 64 bit addend. */
+ HOWTO (R_MICROMIPS_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_mips_elf_generic_reloc, /* special_function */
+ "R_MICROMIPS_HIGHEST", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* High 16 bits of displacement in global offset table. */
+ HOWTO (R_MICROMIPS_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_mips_elf_generic_reloc, /* special_function */
+ "R_MICROMIPS_CALL_HI16",/* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Low 16 bits of displacement in global offset table. */
+ HOWTO (R_MICROMIPS_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_mips_elf_generic_reloc, /* special_function */
+ "R_MICROMIPS_CALL_LO16",/* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Section displacement. */
+ HOWTO (R_MICROMIPS_SCN_DISP, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MICROMIPS_SCN_DISP", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Protected jump conversion. This is an optimization hint. No
+ relocation is required for correctness. */
+ HOWTO (R_MICROMIPS_JALR, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MICROMIPS_JALR", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x00000000, /* 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 */
+
+/* 16 bit offset for pc-relative branches. */
+static reloc_howto_type elf_mips_gnu_rel16_s2 =
+ HOWTO (R_MIPS_GNU_REL16_S2, /* 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_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_GNU_REL16_S2", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ TRUE); /* pcrel_offset */
+
+/* 16 bit offset for pc-relative branches. */
+static reloc_howto_type elf_mips_gnu_rela16_s2 =
+ HOWTO (R_MIPS_GNU_REL16_S2, /* 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_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_GNU_REL16_S2", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ TRUE); /* pcrel_offset */
+
+/* 32 bit pc-relative. Used for compact EH tables. */
+static reloc_howto_type elf_mips_gnu_pcrel32 =
+ HOWTO (R_MIPS_PC32, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_PC32", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ TRUE); /* pcrel_offset */
+
+
+/* Originally a VxWorks extension, but now used for other systems too. */
+static reloc_howto_type elf_mips_copy_howto =
+ HOWTO (R_MIPS_COPY, /* type */
+ 0, /* rightshift */
+ 0, /* this one is variable size */
+ 0, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_COPY", /* name */
+ FALSE, /* partial_inplace */
+ 0x0, /* src_mask */
+ 0x0, /* dst_mask */
+ FALSE); /* pcrel_offset */
+
+/* Originally a VxWorks extension, but now used for other systems too. */
+static reloc_howto_type elf_mips_jump_slot_howto =
+ HOWTO (R_MIPS_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_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_JUMP_SLOT", /* name */
+ FALSE, /* partial_inplace */
+ 0x0, /* src_mask */
+ 0x0, /* dst_mask */
+ FALSE); /* pcrel_offset */
+
+/* Used in EH tables. */
+static reloc_howto_type elf_mips_eh_howto =
+ HOWTO (R_MIPS_EH, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ _bfd_mips_elf_generic_reloc, /* special_function */
+ "R_MIPS_EH", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE); /* pcrel_offset */
+
+
+/* Set the GP value for OUTPUT_BFD. Returns FALSE if this is a
+ dangerous relocation. */
+
+static bfd_boolean
+mips_elf_assign_gp (bfd *output_bfd, bfd_vma *pgp)
+{
+ unsigned int count;
+ asymbol **sym;
+ unsigned int i;
+
+ /* If we've already figured out what GP will be, just return it. */
+ *pgp = _bfd_get_gp_value (output_bfd);
+ if (*pgp)
+ return TRUE;
+
+ count = bfd_get_symcount (output_bfd);
+ sym = bfd_get_outsymbols (output_bfd);
+
+ /* The linker script will have created a symbol named `_gp' with the
+ appropriate value. */
+ if (sym == 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);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/* 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 relocatable output. */
+
+static bfd_reloc_status_type
+mips_elf_final_gp (bfd *output_bfd, asymbol *symbol, bfd_boolean relocatable,
+ char **error_message, bfd_vma *pgp)
+{
+ if (bfd_is_und_section (symbol->section)
+ && ! relocatable)
+ {
+ *pgp = 0;
+ return bfd_reloc_undefined;
+ }
+
+ *pgp = _bfd_get_gp_value (output_bfd);
+ if (*pgp == 0
+ && (! relocatable
+ || (symbol->flags & BSF_SECTION_SYM) != 0))
+ {
+ if (relocatable)
+ {
+ /* Make up a value. */
+ *pgp = symbol->section->output_section->vma /*+ 0x4000*/;
+ _bfd_set_gp_value (output_bfd, *pgp);
+ }
+ else if (!mips_elf_assign_gp (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. */
+
+static bfd_reloc_status_type
+mips_elf_gprel16_reloc (bfd *abfd ATTRIBUTE_UNUSED, arelent *reloc_entry,
+ asymbol *symbol, void *data ATTRIBUTE_UNUSED,
+ asection *input_section, bfd *output_bfd,
+ char **error_message ATTRIBUTE_UNUSED)
+{
+ bfd_boolean relocatable;
+ bfd_reloc_status_type ret;
+ bfd_vma gp;
+
+ if (output_bfd != NULL)
+ relocatable = TRUE;
+ else
+ {
+ relocatable = FALSE;
+ output_bfd = symbol->section->output_section->owner;
+ }
+
+ ret = mips_elf_final_gp (output_bfd, symbol, relocatable, error_message,
+ &gp);
+ if (ret != bfd_reloc_ok)
+ return ret;
+
+ return _bfd_mips_elf_gprel16_with_gp (abfd, symbol, reloc_entry,
+ input_section, relocatable,
+ data, gp);
+}
+
+/* Do a R_MIPS_LITERAL relocation. */
+
+static bfd_reloc_status_type
+mips_elf_literal_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
+ void *data, asection *input_section, bfd *output_bfd,
+ char **error_message)
+{
+ bfd_boolean relocatable;
+ bfd_reloc_status_type ret;
+ bfd_vma gp;
+
+ /* R_MIPS_LITERAL relocations are defined for local symbols only. */
+ if (output_bfd != NULL
+ && (symbol->flags & BSF_SECTION_SYM) == 0
+ && (symbol->flags & BSF_LOCAL) != 0)
+ {
+ *error_message = (char *)
+ _("literal relocation occurs for an external symbol");
+ return bfd_reloc_outofrange;
+ }
+
+ /* FIXME: The entries in the .lit8 and .lit4 sections should be merged. */
+ if (output_bfd != NULL)
+ relocatable = TRUE;
+ else
+ {
+ relocatable = FALSE;
+ output_bfd = symbol->section->output_section->owner;
+ }
+
+ ret = mips_elf_final_gp (output_bfd, symbol, relocatable, error_message,
+ &gp);
+ if (ret != bfd_reloc_ok)
+ return ret;
+
+ return _bfd_mips_elf_gprel16_with_gp (abfd, symbol, reloc_entry,
+ input_section, relocatable,
+ data, gp);
+}
+
+/* Do a R_MIPS_GPREL32 relocation. This is a 32 bit value which must
+ become the offset from the gp register. */
+
+static bfd_reloc_status_type
+mips_elf_gprel32_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
+ void *data, asection *input_section, bfd *output_bfd,
+ char **error_message)
+{
+ bfd_boolean relocatable;
+ bfd_reloc_status_type ret;
+ bfd_vma gp;
+
+ /* R_MIPS_GPREL32 relocations are defined for local symbols only. */
+ if (output_bfd != NULL
+ && (symbol->flags & BSF_SECTION_SYM) == 0
+ && (symbol->flags & BSF_LOCAL) != 0)
+ {
+ *error_message = (char *)
+ _("32bits gp relative relocation occurs for an external symbol");
+ return bfd_reloc_outofrange;
+ }
+
+ if (output_bfd != NULL)
+ {
+ relocatable = TRUE;
+ gp = _bfd_get_gp_value (output_bfd);
+ }
+ else
+ {
+ relocatable = FALSE;
+ output_bfd = symbol->section->output_section->owner;
+
+ ret = mips_elf_final_gp (output_bfd, symbol, relocatable,
+ error_message, &gp);
+ if (ret != bfd_reloc_ok)
+ return ret;
+ }
+
+ return gprel32_with_gp (abfd, symbol, reloc_entry, input_section,
+ relocatable, data, gp);
+}
+
+static bfd_reloc_status_type
+gprel32_with_gp (bfd *abfd, asymbol *symbol, arelent *reloc_entry,
+ asection *input_section, bfd_boolean relocatable,
+ void *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 > bfd_get_section_limit (abfd, input_section))
+ return bfd_reloc_outofrange;
+
+ if (reloc_entry->howto->src_mask == 0)
+ 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 relocatable output, we don't want to do this for
+ an external symbol. */
+ if (! relocatable
+ || (symbol->flags & BSF_SECTION_SYM) != 0)
+ val += relocation - gp;
+
+ bfd_put_32 (abfd, val, (bfd_byte *) data + reloc_entry->address);
+
+ if (relocatable)
+ reloc_entry->address += input_section->output_offset;
+
+ return bfd_reloc_ok;
+}
+
+/* Do a R_MIPS_SHIFT6 relocation. The MSB of the shift is stored at bit 2,
+ the rest is at bits 6-10. The bitpos already got right by the howto. */
+
+static bfd_reloc_status_type
+mips_elf_shift6_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
+ void *data, asection *input_section, bfd *output_bfd,
+ char **error_message)
+{
+ if (reloc_entry->howto->partial_inplace)
+ {
+ reloc_entry->addend = ((reloc_entry->addend & 0x00007c0)
+ | (reloc_entry->addend & 0x00000800) >> 9);
+ }
+
+ return _bfd_mips_elf_generic_reloc (abfd, reloc_entry, symbol, data,
+ input_section, output_bfd,
+ error_message);
+}
+
+/* Handle a mips16 GP relative reloc. */
+
+static bfd_reloc_status_type
+mips16_gprel_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
+ void *data, asection *input_section, bfd *output_bfd,
+ char **error_message)
+{
+ bfd_boolean relocatable;
+ bfd_reloc_status_type ret;
+ bfd_byte *location;
+ bfd_vma gp;
+
+ /* If we're relocating, and this is an external symbol, we don't want
+ to change anything. */
+ if (output_bfd != NULL
+ && (symbol->flags & BSF_SECTION_SYM) == 0
+ && (symbol->flags & BSF_LOCAL) != 0)
+ {
+ reloc_entry->address += input_section->output_offset;
+ return bfd_reloc_ok;
+ }
+
+ if (output_bfd != NULL)
+ relocatable = TRUE;
+ else
+ {
+ relocatable = FALSE;
+ output_bfd = symbol->section->output_section->owner;
+ }
+
+ ret = mips_elf_final_gp (output_bfd, symbol, relocatable, error_message,
+ &gp);
+ if (ret != bfd_reloc_ok)
+ return ret;
+
+ location = (bfd_byte *) data + reloc_entry->address;
+ _bfd_mips_elf_reloc_unshuffle (abfd, reloc_entry->howto->type, FALSE,
+ location);
+ ret = _bfd_mips_elf_gprel16_with_gp (abfd, symbol, reloc_entry,
+ input_section, relocatable,
+ data, gp);
+ _bfd_mips_elf_reloc_shuffle (abfd, reloc_entry->howto->type, !relocatable,
+ location);
+
+ return ret;
+}
+
+/* A mapping from BFD reloc types to MIPS ELF reloc types. */
+
+struct elf_reloc_map {
+ bfd_reloc_code_real_type bfd_val;
+ enum elf_mips_reloc_type elf_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 },
+ /* There is no BFD reloc for R_MIPS_REL32. */
+ { BFD_RELOC_CTOR, R_MIPS_32 },
+ { BFD_RELOC_64, R_MIPS_64 },
+ { BFD_RELOC_16_PCREL_S2, R_MIPS_PC16 },
+ { BFD_RELOC_HI16_S, R_MIPS_HI16 },
+ { BFD_RELOC_LO16, R_MIPS_LO16 },
+ { BFD_RELOC_GPREL16, R_MIPS_GPREL16 },
+ { BFD_RELOC_GPREL32, R_MIPS_GPREL32 },
+ { BFD_RELOC_MIPS_JMP, R_MIPS_26 },
+ { BFD_RELOC_MIPS_LITERAL, R_MIPS_LITERAL },
+ { BFD_RELOC_MIPS_GOT16, R_MIPS_GOT16 },
+ { BFD_RELOC_MIPS_CALL16, R_MIPS_CALL16 },
+ { BFD_RELOC_MIPS_SHIFT5, R_MIPS_SHIFT5 },
+ { BFD_RELOC_MIPS_SHIFT6, R_MIPS_SHIFT6 },
+ { BFD_RELOC_MIPS_GOT_DISP, R_MIPS_GOT_DISP },
+ { BFD_RELOC_MIPS_GOT_PAGE, R_MIPS_GOT_PAGE },
+ { BFD_RELOC_MIPS_GOT_OFST, R_MIPS_GOT_OFST },
+ { BFD_RELOC_MIPS_GOT_HI16, R_MIPS_GOT_HI16 },
+ { BFD_RELOC_MIPS_GOT_LO16, R_MIPS_GOT_LO16 },
+ { BFD_RELOC_MIPS_SUB, R_MIPS_SUB },
+ { BFD_RELOC_MIPS_INSERT_A, R_MIPS_INSERT_A },
+ { BFD_RELOC_MIPS_INSERT_B, R_MIPS_INSERT_B },
+ { BFD_RELOC_MIPS_DELETE, R_MIPS_DELETE },
+ { BFD_RELOC_MIPS_HIGHEST, R_MIPS_HIGHEST },
+ { BFD_RELOC_MIPS_HIGHER, R_MIPS_HIGHER },
+ { BFD_RELOC_MIPS_CALL_HI16, R_MIPS_CALL_HI16 },
+ { BFD_RELOC_MIPS_CALL_LO16, R_MIPS_CALL_LO16 },
+ { BFD_RELOC_MIPS_SCN_DISP, R_MIPS_SCN_DISP },
+ { BFD_RELOC_MIPS_REL16, R_MIPS_REL16 },
+ /* Use of R_MIPS_ADD_IMMEDIATE and R_MIPS_PJUMP is deprecated. */
+ { BFD_RELOC_MIPS_RELGOT, R_MIPS_RELGOT },
+ { BFD_RELOC_MIPS_JALR, R_MIPS_JALR },
+ { BFD_RELOC_MIPS_TLS_DTPMOD32, R_MIPS_TLS_DTPMOD32 },
+ { BFD_RELOC_MIPS_TLS_DTPREL32, R_MIPS_TLS_DTPREL32 },
+ { BFD_RELOC_MIPS_TLS_DTPMOD64, R_MIPS_TLS_DTPMOD64 },
+ { BFD_RELOC_MIPS_TLS_DTPREL64, R_MIPS_TLS_DTPREL64 },
+ { BFD_RELOC_MIPS_TLS_GD, R_MIPS_TLS_GD },
+ { BFD_RELOC_MIPS_TLS_LDM, R_MIPS_TLS_LDM },
+ { BFD_RELOC_MIPS_TLS_DTPREL_HI16, R_MIPS_TLS_DTPREL_HI16 },
+ { BFD_RELOC_MIPS_TLS_DTPREL_LO16, R_MIPS_TLS_DTPREL_LO16 },
+ { BFD_RELOC_MIPS_TLS_GOTTPREL, R_MIPS_TLS_GOTTPREL },
+ { BFD_RELOC_MIPS_TLS_TPREL32, R_MIPS_TLS_TPREL32 },
+ { BFD_RELOC_MIPS_TLS_TPREL64, R_MIPS_TLS_TPREL64 },
+ { BFD_RELOC_MIPS_TLS_TPREL_HI16, R_MIPS_TLS_TPREL_HI16 },
+ { BFD_RELOC_MIPS_TLS_TPREL_LO16, R_MIPS_TLS_TPREL_LO16 },
+ { BFD_RELOC_MIPS_21_PCREL_S2, R_MIPS_PC21_S2 },
+ { BFD_RELOC_MIPS_26_PCREL_S2, R_MIPS_PC26_S2 },
+ { BFD_RELOC_MIPS_18_PCREL_S3, R_MIPS_PC18_S3 },
+ { BFD_RELOC_MIPS_19_PCREL_S2, R_MIPS_PC19_S2 },
+ { BFD_RELOC_HI16_S_PCREL, R_MIPS_PCHI16 },
+ { BFD_RELOC_LO16_PCREL, R_MIPS_PCLO16 }
+};
+
+static const struct elf_reloc_map mips16_reloc_map[] =
+{
+ { BFD_RELOC_MIPS16_JMP, R_MIPS16_26 - R_MIPS16_min },
+ { BFD_RELOC_MIPS16_GPREL, R_MIPS16_GPREL - R_MIPS16_min },
+ { BFD_RELOC_MIPS16_GOT16, R_MIPS16_GOT16 - R_MIPS16_min },
+ { BFD_RELOC_MIPS16_CALL16, R_MIPS16_CALL16 - R_MIPS16_min },
+ { BFD_RELOC_MIPS16_HI16_S, R_MIPS16_HI16 - R_MIPS16_min },
+ { BFD_RELOC_MIPS16_LO16, R_MIPS16_LO16 - R_MIPS16_min },
+ { BFD_RELOC_MIPS16_TLS_GD, R_MIPS16_TLS_GD - R_MIPS16_min },
+ { BFD_RELOC_MIPS16_TLS_LDM, R_MIPS16_TLS_LDM - R_MIPS16_min },
+ { BFD_RELOC_MIPS16_TLS_DTPREL_HI16,
+ R_MIPS16_TLS_DTPREL_HI16 - R_MIPS16_min },
+ { BFD_RELOC_MIPS16_TLS_DTPREL_LO16,
+ R_MIPS16_TLS_DTPREL_LO16 - R_MIPS16_min },
+ { BFD_RELOC_MIPS16_TLS_GOTTPREL, R_MIPS16_TLS_GOTTPREL - R_MIPS16_min },
+ { BFD_RELOC_MIPS16_TLS_TPREL_HI16, R_MIPS16_TLS_TPREL_HI16 - R_MIPS16_min },
+ { BFD_RELOC_MIPS16_TLS_TPREL_LO16, R_MIPS16_TLS_TPREL_LO16 - R_MIPS16_min }
+};
+
+static const struct elf_reloc_map micromips_reloc_map[] =
+{
+ { BFD_RELOC_MICROMIPS_JMP, R_MICROMIPS_26_S1 - R_MICROMIPS_min },
+ { BFD_RELOC_MICROMIPS_HI16_S, R_MICROMIPS_HI16 - R_MICROMIPS_min },
+ { BFD_RELOC_MICROMIPS_LO16, R_MICROMIPS_LO16 - R_MICROMIPS_min },
+ { BFD_RELOC_MICROMIPS_GPREL16, R_MICROMIPS_GPREL16 - R_MICROMIPS_min },
+ { BFD_RELOC_MICROMIPS_LITERAL, R_MICROMIPS_LITERAL - R_MICROMIPS_min },
+ { BFD_RELOC_MICROMIPS_GOT16, R_MICROMIPS_GOT16 - R_MICROMIPS_min },
+ { BFD_RELOC_MICROMIPS_7_PCREL_S1, R_MICROMIPS_PC7_S1 - R_MICROMIPS_min },
+ { BFD_RELOC_MICROMIPS_10_PCREL_S1, R_MICROMIPS_PC10_S1 - R_MICROMIPS_min },
+ { BFD_RELOC_MICROMIPS_16_PCREL_S1, R_MICROMIPS_PC16_S1 - R_MICROMIPS_min },
+ { BFD_RELOC_MICROMIPS_CALL16, R_MICROMIPS_CALL16 - R_MICROMIPS_min },
+ { BFD_RELOC_MICROMIPS_GOT_DISP, R_MICROMIPS_GOT_DISP - R_MICROMIPS_min },
+ { BFD_RELOC_MICROMIPS_GOT_PAGE, R_MICROMIPS_GOT_PAGE - R_MICROMIPS_min },
+ { BFD_RELOC_MICROMIPS_GOT_OFST, R_MICROMIPS_GOT_OFST - R_MICROMIPS_min },
+ { BFD_RELOC_MICROMIPS_GOT_HI16, R_MICROMIPS_GOT_HI16 - R_MICROMIPS_min },
+ { BFD_RELOC_MICROMIPS_GOT_LO16, R_MICROMIPS_GOT_LO16 - R_MICROMIPS_min },
+ { BFD_RELOC_MICROMIPS_SUB, R_MICROMIPS_SUB - R_MICROMIPS_min },
+ { BFD_RELOC_MICROMIPS_HIGHER, R_MICROMIPS_HIGHER - R_MICROMIPS_min },
+ { BFD_RELOC_MICROMIPS_HIGHEST, R_MICROMIPS_HIGHEST - R_MICROMIPS_min },
+ { BFD_RELOC_MICROMIPS_CALL_HI16, R_MICROMIPS_CALL_HI16 - R_MICROMIPS_min },
+ { BFD_RELOC_MICROMIPS_CALL_LO16, R_MICROMIPS_CALL_LO16 - R_MICROMIPS_min },
+ { BFD_RELOC_MICROMIPS_SCN_DISP, R_MICROMIPS_SCN_DISP - R_MICROMIPS_min },
+ { BFD_RELOC_MICROMIPS_JALR, R_MICROMIPS_JALR - R_MICROMIPS_min },
+};
+
+/* Given a BFD reloc type, return a howto structure. */
+
+static reloc_howto_type *
+bfd_elf32_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ bfd_reloc_code_real_type code)
+{
+ unsigned int i;
+ /* FIXME: We default to RELA here instead of choosing the right
+ relocation variant. */
+ reloc_howto_type *howto_table = elf_mips_howto_table_rela;
+ reloc_howto_type *howto16_table = elf_mips16_howto_table_rela;
+ reloc_howto_type *howto_micromips_table = elf_micromips_howto_table_rela;
+
+ for (i = 0; i < sizeof (mips_reloc_map) / sizeof (struct elf_reloc_map);
+ i++)
+ {
+ if (mips_reloc_map[i].bfd_val == code)
+ return &howto_table[(int) mips_reloc_map[i].elf_val];
+ }
+
+ for (i = 0; i < sizeof (mips16_reloc_map) / sizeof (struct elf_reloc_map);
+ i++)
+ {
+ if (mips16_reloc_map[i].bfd_val == code)
+ return &howto16_table[(int) mips16_reloc_map[i].elf_val];
+ }
+
+ for (i = 0; i < sizeof (micromips_reloc_map) / sizeof (struct elf_reloc_map);
+ i++)
+ {
+ if (micromips_reloc_map[i].bfd_val == code)
+ return &howto_micromips_table[(int) micromips_reloc_map[i].elf_val];
+ }
+
+ switch (code)
+ {
+ case BFD_RELOC_VTABLE_INHERIT:
+ return &elf_mips_gnu_vtinherit_howto;
+ case BFD_RELOC_VTABLE_ENTRY:
+ return &elf_mips_gnu_vtentry_howto;
+ case BFD_RELOC_32_PCREL:
+ return &elf_mips_gnu_pcrel32;
+ case BFD_RELOC_MIPS_EH:
+ return &elf_mips_eh_howto;
+ case BFD_RELOC_MIPS_COPY:
+ return &elf_mips_copy_howto;
+ case BFD_RELOC_MIPS_JUMP_SLOT:
+ return &elf_mips_jump_slot_howto;
+ default:
+ bfd_set_error (bfd_error_bad_value);
+ return NULL;
+ }
+}
+
+static reloc_howto_type *
+bfd_elf32_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ const char *r_name)
+{
+ unsigned int i;
+
+ for (i = 0;
+ i < (sizeof (elf_mips_howto_table_rela)
+ / sizeof (elf_mips_howto_table_rela[0]));
+ i++)
+ if (elf_mips_howto_table_rela[i].name != NULL
+ && strcasecmp (elf_mips_howto_table_rela[i].name, r_name) == 0)
+ return &elf_mips_howto_table_rela[i];
+
+ for (i = 0;
+ i < (sizeof (elf_mips16_howto_table_rela)
+ / sizeof (elf_mips16_howto_table_rela[0]));
+ i++)
+ if (elf_mips16_howto_table_rela[i].name != NULL
+ && strcasecmp (elf_mips16_howto_table_rela[i].name, r_name) == 0)
+ return &elf_mips16_howto_table_rela[i];
+
+ for (i = 0;
+ i < (sizeof (elf_micromips_howto_table_rela)
+ / sizeof (elf_micromips_howto_table_rela[0]));
+ i++)
+ if (elf_micromips_howto_table_rela[i].name != NULL
+ && strcasecmp (elf_micromips_howto_table_rela[i].name, r_name) == 0)
+ return &elf_micromips_howto_table_rela[i];
+
+ if (strcasecmp (elf_mips_gnu_vtinherit_howto.name, r_name) == 0)
+ return &elf_mips_gnu_vtinherit_howto;
+ if (strcasecmp (elf_mips_gnu_vtentry_howto.name, r_name) == 0)
+ return &elf_mips_gnu_vtentry_howto;
+ if (strcasecmp (elf_mips_gnu_rel16_s2.name, r_name) == 0)
+ return &elf_mips_gnu_rel16_s2;
+ if (strcasecmp (elf_mips_gnu_rela16_s2.name, r_name) == 0)
+ return &elf_mips_gnu_rela16_s2;
+ if (strcasecmp (elf_mips_gnu_pcrel32.name, r_name) == 0)
+ return &elf_mips_gnu_pcrel32;
+ if (strcasecmp (elf_mips_eh_howto.name, r_name) == 0)
+ return &elf_mips_eh_howto;
+ if (strcasecmp (elf_mips_copy_howto.name, r_name) == 0)
+ return &elf_mips_copy_howto;
+ if (strcasecmp (elf_mips_jump_slot_howto.name, r_name) == 0)
+ return &elf_mips_jump_slot_howto;
+
+ return NULL;
+}
+
+/* Given a MIPS Elf_Internal_Rel, fill in an arelent structure. */
+
+static reloc_howto_type *
+mips_elf_n32_rtype_to_howto (unsigned int r_type, bfd_boolean rela_p)
+{
+ switch (r_type)
+ {
+ case R_MIPS_GNU_VTINHERIT:
+ return &elf_mips_gnu_vtinherit_howto;
+ case R_MIPS_GNU_VTENTRY:
+ return &elf_mips_gnu_vtentry_howto;
+ case R_MIPS_GNU_REL16_S2:
+ if (rela_p)
+ return &elf_mips_gnu_rela16_s2;
+ else
+ return &elf_mips_gnu_rel16_s2;
+ case R_MIPS_PC32:
+ return &elf_mips_gnu_pcrel32;
+ case R_MIPS_EH:
+ return &elf_mips_eh_howto;
+ case R_MIPS_COPY:
+ return &elf_mips_copy_howto;
+ case R_MIPS_JUMP_SLOT:
+ return &elf_mips_jump_slot_howto;
+ default:
+ if (r_type >= R_MICROMIPS_min && r_type < R_MICROMIPS_max)
+ {
+ if (rela_p)
+ return &elf_micromips_howto_table_rela[r_type - R_MICROMIPS_min];
+ else
+ return &elf_micromips_howto_table_rel[r_type - R_MICROMIPS_min];
+ }
+ if (r_type >= R_MIPS16_min && r_type < R_MIPS16_max)
+ {
+ if (rela_p)
+ return &elf_mips16_howto_table_rela[r_type - R_MIPS16_min];
+ else
+ return &elf_mips16_howto_table_rel[r_type - R_MIPS16_min];
+ }
+ BFD_ASSERT (r_type < (unsigned int) R_MIPS_max);
+ if (rela_p)
+ return &elf_mips_howto_table_rela[r_type];
+ else
+ return &elf_mips_howto_table_rel[r_type];
+ break;
+ }
+}
+
+/* Given a MIPS Elf_Internal_Rel, fill in an arelent structure. */
+
+static void
+mips_info_to_howto_rel (bfd *abfd, arelent *cache_ptr, Elf_Internal_Rela *dst)
+{
+ unsigned int r_type;
+
+ r_type = ELF32_R_TYPE (dst->r_info);
+ cache_ptr->howto = mips_elf_n32_rtype_to_howto (r_type, FALSE);
+
+ /* 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
+ && (gprel16_reloc_p (r_type) || r_type == (unsigned int) R_MIPS_LITERAL))
+ cache_ptr->addend = elf_gp (abfd);
+}
+
+/* Given a MIPS Elf_Internal_Rela, fill in an arelent structure. */
+
+static void
+mips_info_to_howto_rela (bfd *abfd ATTRIBUTE_UNUSED,
+ arelent *cache_ptr, Elf_Internal_Rela *dst)
+{
+ unsigned int r_type;
+
+ r_type = ELF32_R_TYPE (dst->r_info);
+ cache_ptr->howto = mips_elf_n32_rtype_to_howto (r_type, TRUE);
+ cache_ptr->addend = dst->r_addend;
+}
+
+/* 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. */
+
+static bfd_boolean
+mips_elf_sym_is_global (bfd *abfd ATTRIBUTE_UNUSED, asymbol *sym)
+{
+ if (SGI_COMPAT (abfd))
+ return (sym->flags & BSF_SECTION_SYM) == 0;
+ else
+ return ((sym->flags & (BSF_GLOBAL | BSF_WEAK | BSF_GNU_UNIQUE)) != 0
+ || bfd_is_und_section (bfd_get_section (sym))
+ || bfd_is_com_section (bfd_get_section (sym)));
+}
+
+/* Set the right machine number for a MIPS ELF file. */
+
+static bfd_boolean
+mips_elf_n32_object_p (bfd *abfd)
+{
+ unsigned long mach;
+
+ if (!ABI_N32_P (abfd))
+ return FALSE;
+
+ /* Irix 5 and 6 are 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. */
+ if (SGI_COMPAT (abfd))
+ elf_bad_symtab (abfd) = TRUE;
+
+ mach = _bfd_elf_mips_mach (elf_elfheader (abfd)->e_flags);
+ bfd_default_set_arch_mach (abfd, bfd_arch_mips, mach);
+ return TRUE;
+}
+
+/* Support for core dump NOTE sections. */
+static bfd_boolean
+elf32_mips_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
+{
+ int offset;
+ unsigned int size;
+
+ switch (note->descsz)
+ {
+ default:
+ return FALSE;
+
+ case 440: /* Linux/MIPS N32 */
+ /* pr_cursig */
+ elf_tdata (abfd)->core->signal = bfd_get_16 (abfd, note->descdata + 12);
+
+ /* pr_pid */
+ elf_tdata (abfd)->core->lwpid = bfd_get_32 (abfd, note->descdata + 24);
+
+ /* pr_reg */
+ offset = 72;
+ size = 360;
+
+ break;
+ }
+
+ /* Make a ".reg/999" section. */
+ return _bfd_elfcore_make_pseudosection (abfd, ".reg", size,
+ note->descpos + offset);
+}
+
+static bfd_boolean
+elf32_mips_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
+{
+ switch (note->descsz)
+ {
+ default:
+ return FALSE;
+
+ case 128: /* Linux/MIPS elf_prpsinfo */
+ elf_tdata (abfd)->core->program
+ = _bfd_elfcore_strndup (abfd, note->descdata + 32, 16);
+ elf_tdata (abfd)->core->command
+ = _bfd_elfcore_strndup (abfd, note->descdata + 48, 80);
+ }
+
+ /* 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;
+}
+
+/* Depending on the target vector we generate some version of Irix
+ executables or "normal" MIPS ELF ABI executables. */
+static irix_compat_t
+elf_n32_mips_irix_compat (bfd *abfd)
+{
+ if ((abfd->xvec == &mips_elf32_n_be_vec)
+ || (abfd->xvec == &mips_elf32_n_le_vec))
+ return ict_irix6;
+ else
+ return ict_none;
+}
+
+/* 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 ELF_ARCH bfd_arch_mips
+#define ELF_TARGET_ID MIPS_ELF_DATA
+#define ELF_MACHINE_CODE EM_MIPS
+
+#define elf_backend_collect TRUE
+#define elf_backend_type_change_ok TRUE
+#define elf_backend_can_gc_sections TRUE
+#define elf_backend_gc_mark_extra_sections \
+ _bfd_mips_elf_gc_mark_extra_sections
+#define elf_info_to_howto mips_info_to_howto_rela
+#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_elf_n32_object_p
+#define elf_backend_symbol_processing _bfd_mips_elf_symbol_processing
+#define elf_backend_section_processing _bfd_mips_elf_section_processing
+#define elf_backend_section_from_shdr _bfd_mips_elf_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_add_symbol_hook _bfd_mips_elf_add_symbol_hook
+#define elf_backend_link_output_symbol_hook \
+ _bfd_mips_elf_link_output_symbol_hook
+#define elf_backend_create_dynamic_sections \
+ _bfd_mips_elf_create_dynamic_sections
+#define elf_backend_check_relocs _bfd_mips_elf_check_relocs
+#define elf_backend_merge_symbol_attribute \
+ _bfd_mips_elf_merge_symbol_attribute
+#define elf_backend_get_target_dtag _bfd_mips_elf_get_target_dtag
+#define elf_backend_adjust_dynamic_symbol \
+ _bfd_mips_elf_adjust_dynamic_symbol
+#define elf_backend_always_size_sections \
+ _bfd_mips_elf_always_size_sections
+#define elf_backend_size_dynamic_sections \
+ _bfd_mips_elf_size_dynamic_sections
+#define elf_backend_init_index_section _bfd_elf_init_1_index_section
+#define elf_backend_relocate_section _bfd_mips_elf_relocate_section
+#define elf_backend_finish_dynamic_symbol \
+ _bfd_mips_elf_finish_dynamic_symbol
+#define elf_backend_finish_dynamic_sections \
+ _bfd_mips_elf_finish_dynamic_sections
+#define elf_backend_final_write_processing \
+ _bfd_mips_elf_final_write_processing
+#define elf_backend_additional_program_headers \
+ _bfd_mips_elf_additional_program_headers
+#define elf_backend_modify_segment_map _bfd_mips_elf_modify_segment_map
+#define elf_backend_gc_mark_hook _bfd_mips_elf_gc_mark_hook
+#define elf_backend_gc_sweep_hook _bfd_mips_elf_gc_sweep_hook
+#define elf_backend_copy_indirect_symbol \
+ _bfd_mips_elf_copy_indirect_symbol
+#define elf_backend_grok_prstatus elf32_mips_grok_prstatus
+#define elf_backend_grok_psinfo elf32_mips_grok_psinfo
+#define elf_backend_ecoff_debug_swap &mips_elf32_ecoff_debug_swap
+
+#define elf_backend_got_header_size (4 * MIPS_RESERVED_GOTNO)
+
+/* MIPS n32 ELF can use a mixture of REL and RELA, but some Relocations
+ work better/work only in RELA, so we default to this. */
+#define elf_backend_may_use_rel_p 1
+#define elf_backend_may_use_rela_p 1
+#define elf_backend_default_use_rela_p 1
+#define elf_backend_rela_plts_and_copies_p 0
+#define elf_backend_sign_extend_vma TRUE
+#define elf_backend_plt_readonly 1
+#define elf_backend_plt_sym_val _bfd_mips_elf_plt_sym_val
+
+#define elf_backend_discard_info _bfd_mips_elf_discard_info
+#define elf_backend_ignore_discarded_relocs \
+ _bfd_mips_elf_ignore_discarded_relocs
+#define elf_backend_write_section _bfd_mips_elf_write_section
+#define elf_backend_mips_irix_compat elf_n32_mips_irix_compat
+#define elf_backend_mips_rtype_to_howto mips_elf_n32_rtype_to_howto
+#define bfd_elf32_bfd_is_target_special_symbol \
+ _bfd_mips_elf_is_target_special_symbol
+#define bfd_elf32_find_nearest_line _bfd_mips_elf_find_nearest_line
+#define bfd_elf32_find_inliner_info _bfd_mips_elf_find_inliner_info
+#define bfd_elf32_new_section_hook _bfd_mips_elf_new_section_hook
+#define bfd_elf32_set_section_contents _bfd_mips_elf_set_section_contents
+#define bfd_elf32_bfd_get_relocated_section_contents \
+ _bfd_elf_mips_get_relocated_section_contents
+#define bfd_elf32_bfd_link_hash_table_create \
+ _bfd_mips_elf_link_hash_table_create
+#define bfd_elf32_bfd_final_link _bfd_mips_elf_final_link
+#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 bfd_elf32_bfd_relax_section _bfd_mips_relax_section
+#define bfd_elf32_mkobject _bfd_mips_elf_mkobject
+
+/* Support for SGI-ish mips targets using n32 ABI. */
+
+#define TARGET_LITTLE_SYM mips_elf32_n_le_vec
+#define TARGET_LITTLE_NAME "elf32-nlittlemips"
+#define TARGET_BIG_SYM mips_elf32_n_be_vec
+#define TARGET_BIG_NAME "elf32-nbigmips"
+
+#define ELF_MAXPAGESIZE 0x10000
+#define ELF_COMMONPAGESIZE 0x1000
+
+#include "elf32-target.h"
+
+/* Support for traditional mips targets using n32 ABI. */
+#undef TARGET_LITTLE_SYM
+#undef TARGET_LITTLE_NAME
+#undef TARGET_BIG_SYM
+#undef TARGET_BIG_NAME
+
+#undef ELF_MAXPAGESIZE
+#undef ELF_COMMONPAGESIZE
+
+#define TARGET_LITTLE_SYM mips_elf32_ntrad_le_vec
+#define TARGET_LITTLE_NAME "elf32-ntradlittlemips"
+#define TARGET_BIG_SYM mips_elf32_ntrad_be_vec
+#define TARGET_BIG_NAME "elf32-ntradbigmips"
+
+#define ELF_MAXPAGESIZE 0x10000
+#define ELF_COMMONPAGESIZE 0x1000
+#define elf32_bed elf32_tradbed
+
+/* Include the target file again for this target. */
+#include "elf32-target.h"
+
+
+/* FreeBSD support. */
+
+#undef TARGET_LITTLE_SYM
+#undef TARGET_LITTLE_NAME
+#undef TARGET_BIG_SYM
+#undef TARGET_BIG_NAME
+
+#define TARGET_LITTLE_SYM mips_elf32_ntradfbsd_le_vec
+#define TARGET_LITTLE_NAME "elf32-ntradlittlemips-freebsd"
+#define TARGET_BIG_SYM mips_elf32_ntradfbsd_be_vec
+#define TARGET_BIG_NAME "elf32-ntradbigmips-freebsd"
+
+#undef ELF_OSABI
+#define ELF_OSABI ELFOSABI_FREEBSD
+
+#undef elf32_bed
+#define elf32_bed elf32_fbsd_tradbed
+
+#include "elf32-target.h"
diff --git a/bfd/elfnn-aarch64.c b/bfd/elfnn-aarch64.c
new file mode 100644
index 0000000..0879db9
--- /dev/null
+++ b/bfd/elfnn-aarch64.c
@@ -0,0 +1,7966 @@
+/* AArch64-specific support for NN-bit ELF.
+ Copyright (C) 2009-2014 Free Software Foundation, Inc.
+ Contributed by ARM Ltd.
+
+ This file is part of BFD, the Binary File Descriptor library.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 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 COPYING3. If not,
+ see <http://www.gnu.org/licenses/>. */
+
+/* Notes on implementation:
+
+ Thread Local Store (TLS)
+
+ Overview:
+
+ The implementation currently supports both traditional TLS and TLS
+ descriptors, but only general dynamic (GD).
+
+ For traditional TLS the assembler will present us with code
+ fragments of the form:
+
+ adrp x0, :tlsgd:foo
+ R_AARCH64_TLSGD_ADR_PAGE21(foo)
+ add x0, :tlsgd_lo12:foo
+ R_AARCH64_TLSGD_ADD_LO12_NC(foo)
+ bl __tls_get_addr
+ nop
+
+ For TLS descriptors the assembler will present us with code
+ fragments of the form:
+
+ adrp x0, :tlsdesc:foo R_AARCH64_TLSDESC_ADR_PAGE21(foo)
+ ldr x1, [x0, #:tlsdesc_lo12:foo] R_AARCH64_TLSDESC_LD64_LO12(foo)
+ add x0, x0, #:tlsdesc_lo12:foo R_AARCH64_TLSDESC_ADD_LO12(foo)
+ .tlsdesccall foo
+ blr x1 R_AARCH64_TLSDESC_CALL(foo)
+
+ The relocations R_AARCH64_TLSGD_{ADR_PREL21,ADD_LO12_NC} against foo
+ indicate that foo is thread local and should be accessed via the
+ traditional TLS mechanims.
+
+ The relocations R_AARCH64_TLSDESC_{ADR_PAGE21,LD64_LO12_NC,ADD_LO12_NC}
+ against foo indicate that 'foo' is thread local and should be accessed
+ via a TLS descriptor mechanism.
+
+ The precise instruction sequence is only relevant from the
+ perspective of linker relaxation which is currently not implemented.
+
+ The static linker must detect that 'foo' is a TLS object and
+ allocate a double GOT entry. The GOT entry must be created for both
+ global and local TLS symbols. Note that this is different to none
+ TLS local objects which do not need a GOT entry.
+
+ In the traditional TLS mechanism, the double GOT entry is used to
+ provide the tls_index structure, containing module and offset
+ entries. The static linker places the relocation R_AARCH64_TLS_DTPMOD
+ on the module entry. The loader will subsequently fixup this
+ relocation with the module identity.
+
+ For global traditional TLS symbols the static linker places an
+ R_AARCH64_TLS_DTPREL relocation on the offset entry. The loader
+ will subsequently fixup the offset. For local TLS symbols the static
+ linker fixes up offset.
+
+ In the TLS descriptor mechanism the double GOT entry is used to
+ provide the descriptor. The static linker places the relocation
+ R_AARCH64_TLSDESC on the first GOT slot. The loader will
+ subsequently fix this up.
+
+ Implementation:
+
+ The handling of TLS symbols is implemented across a number of
+ different backend functions. The following is a top level view of
+ what processing is performed where.
+
+ The TLS implementation maintains state information for each TLS
+ symbol. The state information for local and global symbols is kept
+ in different places. Global symbols use generic BFD structures while
+ local symbols use backend specific structures that are allocated and
+ maintained entirely by the backend.
+
+ The flow:
+
+ elfNN_aarch64_check_relocs()
+
+ This function is invoked for each relocation.
+
+ The TLS relocations R_AARCH64_TLSGD_{ADR_PREL21,ADD_LO12_NC} and
+ R_AARCH64_TLSDESC_{ADR_PAGE21,LD64_LO12_NC,ADD_LO12_NC} are
+ spotted. One time creation of local symbol data structures are
+ created when the first local symbol is seen.
+
+ The reference count for a symbol is incremented. The GOT type for
+ each symbol is marked as general dynamic.
+
+ elfNN_aarch64_allocate_dynrelocs ()
+
+ For each global with positive reference count we allocate a double
+ GOT slot. For a traditional TLS symbol we allocate space for two
+ relocation entries on the GOT, for a TLS descriptor symbol we
+ allocate space for one relocation on the slot. Record the GOT offset
+ for this symbol.
+
+ elfNN_aarch64_size_dynamic_sections ()
+
+ Iterate all input BFDS, look for in the local symbol data structure
+ constructed earlier for local TLS symbols and allocate them double
+ GOT slots along with space for a single GOT relocation. Update the
+ local symbol structure to record the GOT offset allocated.
+
+ elfNN_aarch64_relocate_section ()
+
+ Calls elfNN_aarch64_final_link_relocate ()
+
+ Emit the relevant TLS relocations against the GOT for each TLS
+ symbol. For local TLS symbols emit the GOT offset directly. The GOT
+ relocations are emitted once the first time a TLS symbol is
+ encountered. The implementation uses the LSB of the GOT offset to
+ flag that the relevant GOT relocations for a symbol have been
+ emitted. All of the TLS code that uses the GOT offset needs to take
+ care to mask out this flag bit before using the offset.
+
+ elfNN_aarch64_final_link_relocate ()
+
+ Fixup the R_AARCH64_TLSGD_{ADR_PREL21, ADD_LO12_NC} relocations. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libiberty.h"
+#include "libbfd.h"
+#include "bfd_stdint.h"
+#include "elf-bfd.h"
+#include "bfdlink.h"
+#include "objalloc.h"
+#include "elf/aarch64.h"
+#include "elfxx-aarch64.h"
+
+#define ARCH_SIZE NN
+
+#if ARCH_SIZE == 64
+#define AARCH64_R(NAME) R_AARCH64_ ## NAME
+#define AARCH64_R_STR(NAME) "R_AARCH64_" #NAME
+#define HOWTO64(...) HOWTO (__VA_ARGS__)
+#define HOWTO32(...) EMPTY_HOWTO (0)
+#define LOG_FILE_ALIGN 3
+#endif
+
+#if ARCH_SIZE == 32
+#define AARCH64_R(NAME) R_AARCH64_P32_ ## NAME
+#define AARCH64_R_STR(NAME) "R_AARCH64_P32_" #NAME
+#define HOWTO64(...) EMPTY_HOWTO (0)
+#define HOWTO32(...) HOWTO (__VA_ARGS__)
+#define LOG_FILE_ALIGN 2
+#endif
+
+#define IS_AARCH64_TLS_RELOC(R_TYPE) \
+ ((R_TYPE) == BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21 \
+ || (R_TYPE) == BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC \
+ || (R_TYPE) == BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G1 \
+ || (R_TYPE) == BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC \
+ || (R_TYPE) == BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21 \
+ || (R_TYPE) == BFD_RELOC_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC \
+ || (R_TYPE) == BFD_RELOC_AARCH64_TLSIE_LD32_GOTTPREL_LO12_NC \
+ || (R_TYPE) == BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19 \
+ || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12 \
+ || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_HI12 \
+ || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12_NC \
+ || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G2 \
+ || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1 \
+ || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1_NC \
+ || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0 \
+ || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC \
+ || (R_TYPE) == BFD_RELOC_AARCH64_TLS_DTPMOD \
+ || (R_TYPE) == BFD_RELOC_AARCH64_TLS_DTPREL \
+ || (R_TYPE) == BFD_RELOC_AARCH64_TLS_TPREL \
+ || IS_AARCH64_TLSDESC_RELOC ((R_TYPE)))
+
+#define IS_AARCH64_TLSDESC_RELOC(R_TYPE) \
+ ((R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_LD_PREL19 \
+ || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21 \
+ || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21 \
+ || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_ADD_LO12_NC \
+ || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_LD64_LO12_NC \
+ || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_LD32_LO12_NC \
+ || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_OFF_G1 \
+ || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_OFF_G0_NC \
+ || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_LDR \
+ || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_ADD \
+ || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_CALL \
+ || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC)
+
+#define ELIMINATE_COPY_RELOCS 0
+
+/* Return size of a relocation entry. HTAB is the bfd's
+ elf_aarch64_link_hash_entry. */
+#define RELOC_SIZE(HTAB) (sizeof (ElfNN_External_Rela))
+
+/* GOT Entry size - 8 bytes in ELF64 and 4 bytes in ELF32. */
+#define GOT_ENTRY_SIZE (ARCH_SIZE / 8)
+#define PLT_ENTRY_SIZE (32)
+#define PLT_SMALL_ENTRY_SIZE (16)
+#define PLT_TLSDESC_ENTRY_SIZE (32)
+
+/* Encoding of the nop instruction */
+#define INSN_NOP 0xd503201f
+
+#define aarch64_compute_jump_table_size(htab) \
+ (((htab)->root.srelplt == NULL) ? 0 \
+ : (htab)->root.srelplt->reloc_count * GOT_ENTRY_SIZE)
+
+/* The first entry in a procedure linkage table looks like this
+ if the distance between the PLTGOT and the PLT is < 4GB use
+ these PLT entries. Note that the dynamic linker gets &PLTGOT[2]
+ in x16 and needs to work out PLTGOT[1] by using an address of
+ [x16,#-GOT_ENTRY_SIZE]. */
+static const bfd_byte elfNN_aarch64_small_plt0_entry[PLT_ENTRY_SIZE] =
+{
+ 0xf0, 0x7b, 0xbf, 0xa9, /* stp x16, x30, [sp, #-16]! */
+ 0x10, 0x00, 0x00, 0x90, /* adrp x16, (GOT+16) */
+#if ARCH_SIZE == 64
+ 0x11, 0x0A, 0x40, 0xf9, /* ldr x17, [x16, #PLT_GOT+0x10] */
+ 0x10, 0x42, 0x00, 0x91, /* add x16, x16,#PLT_GOT+0x10 */
+#else
+ 0x11, 0x0A, 0x40, 0xb9, /* ldr w17, [x16, #PLT_GOT+0x8] */
+ 0x10, 0x22, 0x00, 0x11, /* add w16, w16,#PLT_GOT+0x8 */
+#endif
+ 0x20, 0x02, 0x1f, 0xd6, /* br x17 */
+ 0x1f, 0x20, 0x03, 0xd5, /* nop */
+ 0x1f, 0x20, 0x03, 0xd5, /* nop */
+ 0x1f, 0x20, 0x03, 0xd5, /* nop */
+};
+
+/* Per function entry in a procedure linkage table looks like this
+ if the distance between the PLTGOT and the PLT is < 4GB use
+ these PLT entries. */
+static const bfd_byte elfNN_aarch64_small_plt_entry[PLT_SMALL_ENTRY_SIZE] =
+{
+ 0x10, 0x00, 0x00, 0x90, /* adrp x16, PLTGOT + n * 8 */
+#if ARCH_SIZE == 64
+ 0x11, 0x02, 0x40, 0xf9, /* ldr x17, [x16, PLTGOT + n * 8] */
+ 0x10, 0x02, 0x00, 0x91, /* add x16, x16, :lo12:PLTGOT + n * 8 */
+#else
+ 0x11, 0x02, 0x40, 0xb9, /* ldr w17, [x16, PLTGOT + n * 4] */
+ 0x10, 0x02, 0x00, 0x11, /* add w16, w16, :lo12:PLTGOT + n * 4 */
+#endif
+ 0x20, 0x02, 0x1f, 0xd6, /* br x17. */
+};
+
+static const bfd_byte
+elfNN_aarch64_tlsdesc_small_plt_entry[PLT_TLSDESC_ENTRY_SIZE] =
+{
+ 0xe2, 0x0f, 0xbf, 0xa9, /* stp x2, x3, [sp, #-16]! */
+ 0x02, 0x00, 0x00, 0x90, /* adrp x2, 0 */
+ 0x03, 0x00, 0x00, 0x90, /* adrp x3, 0 */
+#if ARCH_SIZE == 64
+ 0x42, 0x00, 0x40, 0xf9, /* ldr x2, [x2, #0] */
+ 0x63, 0x00, 0x00, 0x91, /* add x3, x3, 0 */
+#else
+ 0x42, 0x00, 0x40, 0xb9, /* ldr w2, [x2, #0] */
+ 0x63, 0x00, 0x00, 0x11, /* add w3, w3, 0 */
+#endif
+ 0x40, 0x00, 0x1f, 0xd6, /* br x2 */
+ 0x1f, 0x20, 0x03, 0xd5, /* nop */
+ 0x1f, 0x20, 0x03, 0xd5, /* nop */
+};
+
+#define elf_info_to_howto elfNN_aarch64_info_to_howto
+#define elf_info_to_howto_rel elfNN_aarch64_info_to_howto
+
+#define AARCH64_ELF_ABI_VERSION 0
+
+/* In case we're on a 32-bit machine, construct a 64-bit "-1" value. */
+#define ALL_ONES (~ (bfd_vma) 0)
+
+/* Indexed by the bfd interal reloc enumerators.
+ Therefore, the table needs to be synced with BFD_RELOC_AARCH64_*
+ in reloc.c. */
+
+static reloc_howto_type elfNN_aarch64_howto_table[] =
+{
+ EMPTY_HOWTO (0),
+
+ /* Basic data relocations. */
+
+#if ARCH_SIZE == 64
+ HOWTO (R_AARCH64_NULL, /* 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_AARCH64_NULL", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ FALSE), /* pcrel_offset */
+#else
+ HOWTO (R_AARCH64_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_AARCH64_NONE", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ FALSE), /* pcrel_offset */
+#endif
+
+ /* .xword: (S+A) */
+ HOWTO64 (AARCH64_R (ABS64), /* type */
+ 0, /* rightshift */
+ 4, /* size (4 = long long) */
+ 64, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_unsigned, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ AARCH64_R_STR (ABS64), /* name */
+ FALSE, /* partial_inplace */
+ ALL_ONES, /* src_mask */
+ ALL_ONES, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* .word: (S+A) */
+ HOWTO (AARCH64_R (ABS32), /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_unsigned, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ AARCH64_R_STR (ABS32), /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* .half: (S+A) */
+ HOWTO (AARCH64_R (ABS16), /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_unsigned, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ AARCH64_R_STR (ABS16), /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* .xword: (S+A-P) */
+ HOWTO64 (AARCH64_R (PREL64), /* type */
+ 0, /* rightshift */
+ 4, /* size (4 = long long) */
+ 64, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ AARCH64_R_STR (PREL64), /* name */
+ FALSE, /* partial_inplace */
+ ALL_ONES, /* src_mask */
+ ALL_ONES, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* .word: (S+A-P) */
+ HOWTO (AARCH64_R (PREL32), /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ AARCH64_R_STR (PREL32), /* name */
+ FALSE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* .half: (S+A-P) */
+ HOWTO (AARCH64_R (PREL16), /* 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 */
+ AARCH64_R_STR (PREL16), /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* Group relocations to create a 16, 32, 48 or 64 bit
+ unsigned data or abs address inline. */
+
+ /* MOVZ: ((S+A) >> 0) & 0xffff */
+ HOWTO (AARCH64_R (MOVW_UABS_G0), /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_unsigned, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ AARCH64_R_STR (MOVW_UABS_G0), /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* MOVK: ((S+A) >> 0) & 0xffff [no overflow check] */
+ HOWTO (AARCH64_R (MOVW_UABS_G0_NC), /* 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 */
+ AARCH64_R_STR (MOVW_UABS_G0_NC), /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* MOVZ: ((S+A) >> 16) & 0xffff */
+ HOWTO (AARCH64_R (MOVW_UABS_G1), /* type */
+ 16, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_unsigned, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ AARCH64_R_STR (MOVW_UABS_G1), /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* MOVK: ((S+A) >> 16) & 0xffff [no overflow check] */
+ HOWTO64 (AARCH64_R (MOVW_UABS_G1_NC), /* type */
+ 16, /* 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 */
+ AARCH64_R_STR (MOVW_UABS_G1_NC), /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* MOVZ: ((S+A) >> 32) & 0xffff */
+ HOWTO64 (AARCH64_R (MOVW_UABS_G2), /* type */
+ 32, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_unsigned, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ AARCH64_R_STR (MOVW_UABS_G2), /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* MOVK: ((S+A) >> 32) & 0xffff [no overflow check] */
+ HOWTO64 (AARCH64_R (MOVW_UABS_G2_NC), /* type */
+ 32, /* 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 */
+ AARCH64_R_STR (MOVW_UABS_G2_NC), /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* MOVZ: ((S+A) >> 48) & 0xffff */
+ HOWTO64 (AARCH64_R (MOVW_UABS_G3), /* type */
+ 48, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_unsigned, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ AARCH64_R_STR (MOVW_UABS_G3), /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Group relocations to create high part of a 16, 32, 48 or 64 bit
+ signed data or abs address inline. Will change instruction
+ to MOVN or MOVZ depending on sign of calculated value. */
+
+ /* MOV[ZN]: ((S+A) >> 0) & 0xffff */
+ HOWTO (AARCH64_R (MOVW_SABS_G0), /* 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 */
+ AARCH64_R_STR (MOVW_SABS_G0), /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* MOV[ZN]: ((S+A) >> 16) & 0xffff */
+ HOWTO64 (AARCH64_R (MOVW_SABS_G1), /* type */
+ 16, /* 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 */
+ AARCH64_R_STR (MOVW_SABS_G1), /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* MOV[ZN]: ((S+A) >> 32) & 0xffff */
+ HOWTO64 (AARCH64_R (MOVW_SABS_G2), /* type */
+ 32, /* 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 */
+ AARCH64_R_STR (MOVW_SABS_G2), /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+/* Relocations to generate 19, 21 and 33 bit PC-relative load/store
+ addresses: PG(x) is (x & ~0xfff). */
+
+ /* LD-lit: ((S+A-P) >> 2) & 0x7ffff */
+ HOWTO (AARCH64_R (LD_PREL_LO19), /* type */
+ 2, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 19, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ AARCH64_R_STR (LD_PREL_LO19), /* name */
+ FALSE, /* partial_inplace */
+ 0x7ffff, /* src_mask */
+ 0x7ffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* ADR: (S+A-P) & 0x1fffff */
+ HOWTO (AARCH64_R (ADR_PREL_LO21), /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 21, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ AARCH64_R_STR (ADR_PREL_LO21), /* name */
+ FALSE, /* partial_inplace */
+ 0x1fffff, /* src_mask */
+ 0x1fffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* ADRP: ((PG(S+A)-PG(P)) >> 12) & 0x1fffff */
+ HOWTO (AARCH64_R (ADR_PREL_PG_HI21), /* type */
+ 12, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 21, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ AARCH64_R_STR (ADR_PREL_PG_HI21), /* name */
+ FALSE, /* partial_inplace */
+ 0x1fffff, /* src_mask */
+ 0x1fffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* ADRP: ((PG(S+A)-PG(P)) >> 12) & 0x1fffff [no overflow check] */
+ HOWTO64 (AARCH64_R (ADR_PREL_PG_HI21_NC), /* type */
+ 12, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 21, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ AARCH64_R_STR (ADR_PREL_PG_HI21_NC), /* name */
+ FALSE, /* partial_inplace */
+ 0x1fffff, /* src_mask */
+ 0x1fffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* ADD: (S+A) & 0xfff [no overflow check] */
+ HOWTO (AARCH64_R (ADD_ABS_LO12_NC), /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 12, /* bitsize */
+ FALSE, /* pc_relative */
+ 10, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ AARCH64_R_STR (ADD_ABS_LO12_NC), /* name */
+ FALSE, /* partial_inplace */
+ 0x3ffc00, /* src_mask */
+ 0x3ffc00, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* LD/ST8: (S+A) & 0xfff */
+ HOWTO (AARCH64_R (LDST8_ABS_LO12_NC), /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 12, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ AARCH64_R_STR (LDST8_ABS_LO12_NC), /* name */
+ FALSE, /* partial_inplace */
+ 0xfff, /* src_mask */
+ 0xfff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Relocations for control-flow instructions. */
+
+ /* TBZ/NZ: ((S+A-P) >> 2) & 0x3fff */
+ HOWTO (AARCH64_R (TSTBR14), /* type */
+ 2, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 14, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ AARCH64_R_STR (TSTBR14), /* name */
+ FALSE, /* partial_inplace */
+ 0x3fff, /* src_mask */
+ 0x3fff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* B.cond: ((S+A-P) >> 2) & 0x7ffff */
+ HOWTO (AARCH64_R (CONDBR19), /* type */
+ 2, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 19, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ AARCH64_R_STR (CONDBR19), /* name */
+ FALSE, /* partial_inplace */
+ 0x7ffff, /* src_mask */
+ 0x7ffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* B: ((S+A-P) >> 2) & 0x3ffffff */
+ HOWTO (AARCH64_R (JUMP26), /* 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 */
+ AARCH64_R_STR (JUMP26), /* name */
+ FALSE, /* partial_inplace */
+ 0x3ffffff, /* src_mask */
+ 0x3ffffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* BL: ((S+A-P) >> 2) & 0x3ffffff */
+ HOWTO (AARCH64_R (CALL26), /* 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 */
+ AARCH64_R_STR (CALL26), /* name */
+ FALSE, /* partial_inplace */
+ 0x3ffffff, /* src_mask */
+ 0x3ffffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* LD/ST16: (S+A) & 0xffe */
+ HOWTO (AARCH64_R (LDST16_ABS_LO12_NC), /* type */
+ 1, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 12, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ AARCH64_R_STR (LDST16_ABS_LO12_NC), /* name */
+ FALSE, /* partial_inplace */
+ 0xffe, /* src_mask */
+ 0xffe, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* LD/ST32: (S+A) & 0xffc */
+ HOWTO (AARCH64_R (LDST32_ABS_LO12_NC), /* type */
+ 2, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 12, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ AARCH64_R_STR (LDST32_ABS_LO12_NC), /* name */
+ FALSE, /* partial_inplace */
+ 0xffc, /* src_mask */
+ 0xffc, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* LD/ST64: (S+A) & 0xff8 */
+ HOWTO (AARCH64_R (LDST64_ABS_LO12_NC), /* type */
+ 3, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 12, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ AARCH64_R_STR (LDST64_ABS_LO12_NC), /* name */
+ FALSE, /* partial_inplace */
+ 0xff8, /* src_mask */
+ 0xff8, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* LD/ST128: (S+A) & 0xff0 */
+ HOWTO (AARCH64_R (LDST128_ABS_LO12_NC), /* type */
+ 4, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 12, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ AARCH64_R_STR (LDST128_ABS_LO12_NC), /* name */
+ FALSE, /* partial_inplace */
+ 0xff0, /* src_mask */
+ 0xff0, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Set a load-literal immediate field to bits
+ 0x1FFFFC of G(S)-P */
+ HOWTO (AARCH64_R (GOT_LD_PREL19), /* type */
+ 2, /* rightshift */
+ 2, /* size (0 = byte,1 = short,2 = long) */
+ 19, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ AARCH64_R_STR (GOT_LD_PREL19), /* name */
+ FALSE, /* partial_inplace */
+ 0xffffe0, /* src_mask */
+ 0xffffe0, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* Get to the page for the GOT entry for the symbol
+ (G(S) - P) using an ADRP instruction. */
+ HOWTO (AARCH64_R (ADR_GOT_PAGE), /* type */
+ 12, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 21, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ AARCH64_R_STR (ADR_GOT_PAGE), /* name */
+ FALSE, /* partial_inplace */
+ 0x1fffff, /* src_mask */
+ 0x1fffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* LD64: GOT offset G(S) & 0xff8 */
+ HOWTO64 (AARCH64_R (LD64_GOT_LO12_NC), /* type */
+ 3, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 12, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ AARCH64_R_STR (LD64_GOT_LO12_NC), /* name */
+ FALSE, /* partial_inplace */
+ 0xff8, /* src_mask */
+ 0xff8, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* LD32: GOT offset G(S) & 0xffc */
+ HOWTO32 (AARCH64_R (LD32_GOT_LO12_NC), /* type */
+ 2, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 12, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ AARCH64_R_STR (LD32_GOT_LO12_NC), /* name */
+ FALSE, /* partial_inplace */
+ 0xffc, /* src_mask */
+ 0xffc, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* Get to the page for the GOT entry for the symbol
+ (G(S) - P) using an ADRP instruction. */
+ HOWTO (AARCH64_R (TLSGD_ADR_PAGE21), /* type */
+ 12, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 21, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ AARCH64_R_STR (TLSGD_ADR_PAGE21), /* name */
+ FALSE, /* partial_inplace */
+ 0x1fffff, /* src_mask */
+ 0x1fffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* ADD: GOT offset G(S) & 0xff8 [no overflow check] */
+ HOWTO (AARCH64_R (TLSGD_ADD_LO12_NC), /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 12, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ AARCH64_R_STR (TLSGD_ADD_LO12_NC), /* name */
+ FALSE, /* partial_inplace */
+ 0xfff, /* src_mask */
+ 0xfff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO64 (AARCH64_R (TLSIE_MOVW_GOTTPREL_G1), /* type */
+ 16, /* 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 */
+ AARCH64_R_STR (TLSIE_MOVW_GOTTPREL_G1), /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO64 (AARCH64_R (TLSIE_MOVW_GOTTPREL_G0_NC), /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ AARCH64_R_STR (TLSIE_MOVW_GOTTPREL_G0_NC), /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (AARCH64_R (TLSIE_ADR_GOTTPREL_PAGE21), /* type */
+ 12, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 21, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ AARCH64_R_STR (TLSIE_ADR_GOTTPREL_PAGE21), /* name */
+ FALSE, /* partial_inplace */
+ 0x1fffff, /* src_mask */
+ 0x1fffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO64 (AARCH64_R (TLSIE_LD64_GOTTPREL_LO12_NC), /* type */
+ 3, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 12, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ AARCH64_R_STR (TLSIE_LD64_GOTTPREL_LO12_NC), /* name */
+ FALSE, /* partial_inplace */
+ 0xff8, /* src_mask */
+ 0xff8, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO32 (AARCH64_R (TLSIE_LD32_GOTTPREL_LO12_NC), /* type */
+ 2, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 12, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ AARCH64_R_STR (TLSIE_LD32_GOTTPREL_LO12_NC), /* name */
+ FALSE, /* partial_inplace */
+ 0xffc, /* src_mask */
+ 0xffc, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (AARCH64_R (TLSIE_LD_GOTTPREL_PREL19), /* type */
+ 2, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 21, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ AARCH64_R_STR (TLSIE_LD_GOTTPREL_PREL19), /* name */
+ FALSE, /* partial_inplace */
+ 0x1ffffc, /* src_mask */
+ 0x1ffffc, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO64 (AARCH64_R (TLSLE_MOVW_TPREL_G2), /* type */
+ 32, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 12, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ AARCH64_R_STR (TLSLE_MOVW_TPREL_G2), /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (AARCH64_R (TLSLE_MOVW_TPREL_G1), /* type */
+ 16, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 12, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ AARCH64_R_STR (TLSLE_MOVW_TPREL_G1), /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO64 (AARCH64_R (TLSLE_MOVW_TPREL_G1_NC), /* type */
+ 16, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 12, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ AARCH64_R_STR (TLSLE_MOVW_TPREL_G1_NC), /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (AARCH64_R (TLSLE_MOVW_TPREL_G0), /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 12, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ AARCH64_R_STR (TLSLE_MOVW_TPREL_G0), /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (AARCH64_R (TLSLE_MOVW_TPREL_G0_NC), /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 12, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ AARCH64_R_STR (TLSLE_MOVW_TPREL_G0_NC), /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (AARCH64_R (TLSLE_ADD_TPREL_HI12), /* type */
+ 12, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 12, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ AARCH64_R_STR (TLSLE_ADD_TPREL_HI12), /* name */
+ FALSE, /* partial_inplace */
+ 0xfff, /* src_mask */
+ 0xfff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (AARCH64_R (TLSLE_ADD_TPREL_LO12), /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 12, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ AARCH64_R_STR (TLSLE_ADD_TPREL_LO12), /* name */
+ FALSE, /* partial_inplace */
+ 0xfff, /* src_mask */
+ 0xfff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (AARCH64_R (TLSLE_ADD_TPREL_LO12_NC), /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 12, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ AARCH64_R_STR (TLSLE_ADD_TPREL_LO12_NC), /* name */
+ FALSE, /* partial_inplace */
+ 0xfff, /* src_mask */
+ 0xfff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (AARCH64_R (TLSDESC_LD_PREL19), /* type */
+ 2, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 21, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ AARCH64_R_STR (TLSDESC_LD_PREL19), /* name */
+ FALSE, /* partial_inplace */
+ 0x1ffffc, /* src_mask */
+ 0x1ffffc, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (AARCH64_R (TLSDESC_ADR_PREL21), /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 21, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ AARCH64_R_STR (TLSDESC_ADR_PREL21), /* name */
+ FALSE, /* partial_inplace */
+ 0x1fffff, /* src_mask */
+ 0x1fffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* Get to the page for the GOT entry for the symbol
+ (G(S) - P) using an ADRP instruction. */
+ HOWTO (AARCH64_R (TLSDESC_ADR_PAGE21), /* type */
+ 12, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 21, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ AARCH64_R_STR (TLSDESC_ADR_PAGE21), /* name */
+ FALSE, /* partial_inplace */
+ 0x1fffff, /* src_mask */
+ 0x1fffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* LD64: GOT offset G(S) & 0xff8. */
+ HOWTO64 (AARCH64_R (TLSDESC_LD64_LO12_NC), /* type */
+ 3, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 12, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ AARCH64_R_STR (TLSDESC_LD64_LO12_NC), /* name */
+ FALSE, /* partial_inplace */
+ 0xff8, /* src_mask */
+ 0xff8, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* LD32: GOT offset G(S) & 0xffc. */
+ HOWTO32 (AARCH64_R (TLSDESC_LD32_LO12_NC), /* type */
+ 2, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 12, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ AARCH64_R_STR (TLSDESC_LD32_LO12_NC), /* name */
+ FALSE, /* partial_inplace */
+ 0xffc, /* src_mask */
+ 0xffc, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* ADD: GOT offset G(S) & 0xfff. */
+ HOWTO (AARCH64_R (TLSDESC_ADD_LO12_NC), /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 12, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ AARCH64_R_STR (TLSDESC_ADD_LO12_NC), /* name */
+ FALSE, /* partial_inplace */
+ 0xfff, /* src_mask */
+ 0xfff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO64 (AARCH64_R (TLSDESC_OFF_G1), /* type */
+ 16, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 12, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ AARCH64_R_STR (TLSDESC_OFF_G1), /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO64 (AARCH64_R (TLSDESC_OFF_G0_NC), /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 12, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ AARCH64_R_STR (TLSDESC_OFF_G0_NC), /* name */
+ FALSE, /* partial_inplace */
+ 0xffff, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO64 (AARCH64_R (TLSDESC_LDR), /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 12, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ AARCH64_R_STR (TLSDESC_LDR), /* name */
+ FALSE, /* partial_inplace */
+ 0x0, /* src_mask */
+ 0x0, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO64 (AARCH64_R (TLSDESC_ADD), /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 12, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ AARCH64_R_STR (TLSDESC_ADD), /* name */
+ FALSE, /* partial_inplace */
+ 0x0, /* src_mask */
+ 0x0, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (AARCH64_R (TLSDESC_CALL), /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 12, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ AARCH64_R_STR (TLSDESC_CALL), /* name */
+ FALSE, /* partial_inplace */
+ 0x0, /* src_mask */
+ 0x0, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (AARCH64_R (COPY), /* type */
+ 0, /* rightshift */
+ 2, /* 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 */
+ AARCH64_R_STR (COPY), /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (AARCH64_R (GLOB_DAT), /* type */
+ 0, /* rightshift */
+ 2, /* 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 */
+ AARCH64_R_STR (GLOB_DAT), /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (AARCH64_R (JUMP_SLOT), /* type */
+ 0, /* rightshift */
+ 2, /* 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 */
+ AARCH64_R_STR (JUMP_SLOT), /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (AARCH64_R (RELATIVE), /* type */
+ 0, /* rightshift */
+ 2, /* 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 */
+ AARCH64_R_STR (RELATIVE), /* name */
+ TRUE, /* partial_inplace */
+ ALL_ONES, /* src_mask */
+ ALL_ONES, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (AARCH64_R (TLS_DTPMOD), /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+#if ARCH_SIZE == 64
+ AARCH64_R_STR (TLS_DTPMOD64), /* name */
+#else
+ AARCH64_R_STR (TLS_DTPMOD), /* name */
+#endif
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ ALL_ONES, /* dst_mask */
+ FALSE), /* pc_reloffset */
+
+ HOWTO (AARCH64_R (TLS_DTPREL), /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+#if ARCH_SIZE == 64
+ AARCH64_R_STR (TLS_DTPREL64), /* name */
+#else
+ AARCH64_R_STR (TLS_DTPREL), /* name */
+#endif
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ ALL_ONES, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (AARCH64_R (TLS_TPREL), /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+#if ARCH_SIZE == 64
+ AARCH64_R_STR (TLS_TPREL64), /* name */
+#else
+ AARCH64_R_STR (TLS_TPREL), /* name */
+#endif
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ ALL_ONES, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (AARCH64_R (TLSDESC), /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ AARCH64_R_STR (TLSDESC), /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ ALL_ONES, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (AARCH64_R (IRELATIVE), /* type */
+ 0, /* rightshift */
+ 2, /* 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 */
+ AARCH64_R_STR (IRELATIVE), /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ ALL_ONES, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ EMPTY_HOWTO (0),
+};
+
+static reloc_howto_type elfNN_aarch64_howto_none =
+ HOWTO (R_AARCH64_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_AARCH64_NONE", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ FALSE); /* pcrel_offset */
+
+/* Given HOWTO, return the bfd internal relocation enumerator. */
+
+static bfd_reloc_code_real_type
+elfNN_aarch64_bfd_reloc_from_howto (reloc_howto_type *howto)
+{
+ const int size
+ = (int) ARRAY_SIZE (elfNN_aarch64_howto_table);
+ const ptrdiff_t offset
+ = howto - elfNN_aarch64_howto_table;
+
+ if (offset > 0 && offset < size - 1)
+ return BFD_RELOC_AARCH64_RELOC_START + offset;
+
+ if (howto == &elfNN_aarch64_howto_none)
+ return BFD_RELOC_AARCH64_NONE;
+
+ return BFD_RELOC_AARCH64_RELOC_START;
+}
+
+/* Given R_TYPE, return the bfd internal relocation enumerator. */
+
+static bfd_reloc_code_real_type
+elfNN_aarch64_bfd_reloc_from_type (unsigned int r_type)
+{
+ static bfd_boolean initialized_p = FALSE;
+ /* Indexed by R_TYPE, values are offsets in the howto_table. */
+ static unsigned int offsets[R_AARCH64_end];
+
+ if (initialized_p == FALSE)
+ {
+ unsigned int i;
+
+ for (i = 1; i < ARRAY_SIZE (elfNN_aarch64_howto_table) - 1; ++i)
+ if (elfNN_aarch64_howto_table[i].type != 0)
+ offsets[elfNN_aarch64_howto_table[i].type] = i;
+
+ initialized_p = TRUE;
+ }
+
+ if (r_type == R_AARCH64_NONE || r_type == R_AARCH64_NULL)
+ return BFD_RELOC_AARCH64_NONE;
+
+ return BFD_RELOC_AARCH64_RELOC_START + offsets[r_type];
+}
+
+struct elf_aarch64_reloc_map
+{
+ bfd_reloc_code_real_type from;
+ bfd_reloc_code_real_type to;
+};
+
+/* Map bfd generic reloc to AArch64-specific reloc. */
+static const struct elf_aarch64_reloc_map elf_aarch64_reloc_map[] =
+{
+ {BFD_RELOC_NONE, BFD_RELOC_AARCH64_NONE},
+
+ /* Basic data relocations. */
+ {BFD_RELOC_CTOR, BFD_RELOC_AARCH64_NN},
+ {BFD_RELOC_64, BFD_RELOC_AARCH64_64},
+ {BFD_RELOC_32, BFD_RELOC_AARCH64_32},
+ {BFD_RELOC_16, BFD_RELOC_AARCH64_16},
+ {BFD_RELOC_64_PCREL, BFD_RELOC_AARCH64_64_PCREL},
+ {BFD_RELOC_32_PCREL, BFD_RELOC_AARCH64_32_PCREL},
+ {BFD_RELOC_16_PCREL, BFD_RELOC_AARCH64_16_PCREL},
+};
+
+/* Given the bfd internal relocation enumerator in CODE, return the
+ corresponding howto entry. */
+
+static reloc_howto_type *
+elfNN_aarch64_howto_from_bfd_reloc (bfd_reloc_code_real_type code)
+{
+ unsigned int i;
+
+ /* Convert bfd generic reloc to AArch64-specific reloc. */
+ if (code < BFD_RELOC_AARCH64_RELOC_START
+ || code > BFD_RELOC_AARCH64_RELOC_END)
+ for (i = 0; i < ARRAY_SIZE (elf_aarch64_reloc_map); i++)
+ if (elf_aarch64_reloc_map[i].from == code)
+ {
+ code = elf_aarch64_reloc_map[i].to;
+ break;
+ }
+
+ if (code > BFD_RELOC_AARCH64_RELOC_START
+ && code < BFD_RELOC_AARCH64_RELOC_END)
+ if (elfNN_aarch64_howto_table[code - BFD_RELOC_AARCH64_RELOC_START].type)
+ return &elfNN_aarch64_howto_table[code - BFD_RELOC_AARCH64_RELOC_START];
+
+ if (code == BFD_RELOC_AARCH64_NONE)
+ return &elfNN_aarch64_howto_none;
+
+ return NULL;
+}
+
+static reloc_howto_type *
+elfNN_aarch64_howto_from_type (unsigned int r_type)
+{
+ bfd_reloc_code_real_type val;
+ reloc_howto_type *howto;
+
+#if ARCH_SIZE == 32
+ if (r_type > 256)
+ {
+ bfd_set_error (bfd_error_bad_value);
+ return NULL;
+ }
+#endif
+
+ if (r_type == R_AARCH64_NONE)
+ return &elfNN_aarch64_howto_none;
+
+ val = elfNN_aarch64_bfd_reloc_from_type (r_type);
+ howto = elfNN_aarch64_howto_from_bfd_reloc (val);
+
+ if (howto != NULL)
+ return howto;
+
+ bfd_set_error (bfd_error_bad_value);
+ return NULL;
+}
+
+static void
+elfNN_aarch64_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED, arelent *bfd_reloc,
+ Elf_Internal_Rela *elf_reloc)
+{
+ unsigned int r_type;
+
+ r_type = ELFNN_R_TYPE (elf_reloc->r_info);
+ bfd_reloc->howto = elfNN_aarch64_howto_from_type (r_type);
+}
+
+static reloc_howto_type *
+elfNN_aarch64_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ bfd_reloc_code_real_type code)
+{
+ reloc_howto_type *howto = elfNN_aarch64_howto_from_bfd_reloc (code);
+
+ if (howto != NULL)
+ return howto;
+
+ bfd_set_error (bfd_error_bad_value);
+ return NULL;
+}
+
+static reloc_howto_type *
+elfNN_aarch64_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ const char *r_name)
+{
+ unsigned int i;
+
+ for (i = 1; i < ARRAY_SIZE (elfNN_aarch64_howto_table) - 1; ++i)
+ if (elfNN_aarch64_howto_table[i].name != NULL
+ && strcasecmp (elfNN_aarch64_howto_table[i].name, r_name) == 0)
+ return &elfNN_aarch64_howto_table[i];
+
+ return NULL;
+}
+
+#define TARGET_LITTLE_SYM aarch64_elfNN_le_vec
+#define TARGET_LITTLE_NAME "elfNN-littleaarch64"
+#define TARGET_BIG_SYM aarch64_elfNN_be_vec
+#define TARGET_BIG_NAME "elfNN-bigaarch64"
+
+/* 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 STUB_ENTRY_NAME "__%s_veneer"
+
+/* The name of the dynamic interpreter. This is put in the .interp
+ section. */
+#define ELF_DYNAMIC_INTERPRETER "/lib/ld.so.1"
+
+#define AARCH64_MAX_FWD_BRANCH_OFFSET \
+ (((1 << 25) - 1) << 2)
+#define AARCH64_MAX_BWD_BRANCH_OFFSET \
+ (-((1 << 25) << 2))
+
+#define AARCH64_MAX_ADRP_IMM ((1 << 20) - 1)
+#define AARCH64_MIN_ADRP_IMM (-(1 << 20))
+
+static int
+aarch64_valid_for_adrp_p (bfd_vma value, bfd_vma place)
+{
+ bfd_signed_vma offset = (bfd_signed_vma) (PG (value) - PG (place)) >> 12;
+ return offset <= AARCH64_MAX_ADRP_IMM && offset >= AARCH64_MIN_ADRP_IMM;
+}
+
+static int
+aarch64_valid_branch_p (bfd_vma value, bfd_vma place)
+{
+ bfd_signed_vma offset = (bfd_signed_vma) (value - place);
+ return (offset <= AARCH64_MAX_FWD_BRANCH_OFFSET
+ && offset >= AARCH64_MAX_BWD_BRANCH_OFFSET);
+}
+
+static const uint32_t aarch64_adrp_branch_stub [] =
+{
+ 0x90000010, /* adrp ip0, X */
+ /* R_AARCH64_ADR_HI21_PCREL(X) */
+ 0x91000210, /* add ip0, ip0, :lo12:X */
+ /* R_AARCH64_ADD_ABS_LO12_NC(X) */
+ 0xd61f0200, /* br ip0 */
+};
+
+static const uint32_t aarch64_long_branch_stub[] =
+{
+#if ARCH_SIZE == 64
+ 0x58000090, /* ldr ip0, 1f */
+#else
+ 0x18000090, /* ldr wip0, 1f */
+#endif
+ 0x10000011, /* adr ip1, #0 */
+ 0x8b110210, /* add ip0, ip0, ip1 */
+ 0xd61f0200, /* br ip0 */
+ 0x00000000, /* 1: .xword or .word
+ R_AARCH64_PRELNN(X) + 12
+ */
+ 0x00000000,
+};
+
+static const uint32_t aarch64_erratum_835769_stub[] =
+{
+ 0x00000000, /* Placeholder for multiply accumulate. */
+ 0x14000000, /* b <label> */
+};
+
+/* Section name for stubs is the associated section name plus this
+ string. */
+#define STUB_SUFFIX ".stub"
+
+enum elf_aarch64_stub_type
+{
+ aarch64_stub_none,
+ aarch64_stub_adrp_branch,
+ aarch64_stub_long_branch,
+ aarch64_stub_erratum_835769_veneer,
+};
+
+struct elf_aarch64_stub_hash_entry
+{
+ /* Base hash table entry structure. */
+ struct bfd_hash_entry root;
+
+ /* The stub section. */
+ asection *stub_sec;
+
+ /* Offset within stub_sec of the beginning of this stub. */
+ bfd_vma stub_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). */
+ bfd_vma target_value;
+ asection *target_section;
+
+ enum elf_aarch64_stub_type stub_type;
+
+ /* The symbol table entry, if any, that this was derived from. */
+ struct elf_aarch64_link_hash_entry *h;
+
+ /* Destination symbol type */
+ unsigned char st_type;
+
+ /* Where this stub is being called from, or, in the case of combined
+ stub sections, the first input section in the group. */
+ asection *id_sec;
+
+ /* The name for the local symbol at the start of this stub. The
+ stub name in the hash table has to be unique; this does not, so
+ it can be friendlier. */
+ char *output_name;
+
+ /* The instruction which caused this stub to be generated (only valid for
+ erratum 835769 workaround stubs at present). */
+ uint32_t veneered_insn;
+};
+
+/* Used to build a map of a section. This is required for mixed-endian
+ code/data. */
+
+typedef struct elf_elf_section_map
+{
+ bfd_vma vma;
+ char type;
+}
+elf_aarch64_section_map;
+
+
+typedef struct _aarch64_elf_section_data
+{
+ struct bfd_elf_section_data elf;
+ unsigned int mapcount;
+ unsigned int mapsize;
+ elf_aarch64_section_map *map;
+}
+_aarch64_elf_section_data;
+
+#define elf_aarch64_section_data(sec) \
+ ((_aarch64_elf_section_data *) elf_section_data (sec))
+
+/* A fix-descriptor for erratum 835769. */
+struct aarch64_erratum_835769_fix
+{
+ bfd *input_bfd;
+ asection *section;
+ bfd_vma offset;
+ uint32_t veneered_insn;
+ char *stub_name;
+ enum elf_aarch64_stub_type stub_type;
+};
+
+/* The size of the thread control block which is defined to be two pointers. */
+#define TCB_SIZE (ARCH_SIZE/8)*2
+
+struct elf_aarch64_local_symbol
+{
+ unsigned int got_type;
+ bfd_signed_vma got_refcount;
+ bfd_vma got_offset;
+
+ /* Offset of the GOTPLT entry reserved for the TLS descriptor. The
+ offset is from the end of the jump table and reserved entries
+ within the PLTGOT.
+
+ The magic value (bfd_vma) -1 indicates that an offset has not be
+ allocated. */
+ bfd_vma tlsdesc_got_jump_table_offset;
+};
+
+struct elf_aarch64_obj_tdata
+{
+ struct elf_obj_tdata root;
+
+ /* local symbol descriptors */
+ struct elf_aarch64_local_symbol *locals;
+
+ /* Zero to warn when linking objects with incompatible enum sizes. */
+ int no_enum_size_warning;
+
+ /* Zero to warn when linking objects with incompatible wchar_t sizes. */
+ int no_wchar_size_warning;
+};
+
+#define elf_aarch64_tdata(bfd) \
+ ((struct elf_aarch64_obj_tdata *) (bfd)->tdata.any)
+
+#define elf_aarch64_locals(bfd) (elf_aarch64_tdata (bfd)->locals)
+
+#define is_aarch64_elf(bfd) \
+ (bfd_get_flavour (bfd) == bfd_target_elf_flavour \
+ && elf_tdata (bfd) != NULL \
+ && elf_object_id (bfd) == AARCH64_ELF_DATA)
+
+static bfd_boolean
+elfNN_aarch64_mkobject (bfd *abfd)
+{
+ return bfd_elf_allocate_object (abfd, sizeof (struct elf_aarch64_obj_tdata),
+ AARCH64_ELF_DATA);
+}
+
+#define elf_aarch64_hash_entry(ent) \
+ ((struct elf_aarch64_link_hash_entry *)(ent))
+
+#define GOT_UNKNOWN 0
+#define GOT_NORMAL 1
+#define GOT_TLS_GD 2
+#define GOT_TLS_IE 4
+#define GOT_TLSDESC_GD 8
+
+#define GOT_TLS_GD_ANY_P(type) ((type & GOT_TLS_GD) || (type & GOT_TLSDESC_GD))
+
+/* AArch64 ELF linker hash entry. */
+struct elf_aarch64_link_hash_entry
+{
+ struct elf_link_hash_entry root;
+
+ /* Track dynamic relocs copied for this symbol. */
+ struct elf_dyn_relocs *dyn_relocs;
+
+ /* Since PLT entries have variable size, we need to record the
+ index into .got.plt instead of recomputing it from the PLT
+ offset. */
+ bfd_signed_vma plt_got_offset;
+
+ /* Bit mask representing the type of GOT entry(s) if any required by
+ this symbol. */
+ unsigned int got_type;
+
+ /* A pointer to the most recently used stub hash entry against this
+ symbol. */
+ struct elf_aarch64_stub_hash_entry *stub_cache;
+
+ /* Offset of the GOTPLT entry reserved for the TLS descriptor. The offset
+ is from the end of the jump table and reserved entries within the PLTGOT.
+
+ The magic value (bfd_vma) -1 indicates that an offset has not
+ be allocated. */
+ bfd_vma tlsdesc_got_jump_table_offset;
+};
+
+static unsigned int
+elfNN_aarch64_symbol_got_type (struct elf_link_hash_entry *h,
+ bfd *abfd,
+ unsigned long r_symndx)
+{
+ if (h)
+ return elf_aarch64_hash_entry (h)->got_type;
+
+ if (! elf_aarch64_locals (abfd))
+ return GOT_UNKNOWN;
+
+ return elf_aarch64_locals (abfd)[r_symndx].got_type;
+}
+
+/* Get the AArch64 elf linker hash table from a link_info structure. */
+#define elf_aarch64_hash_table(info) \
+ ((struct elf_aarch64_link_hash_table *) ((info)->hash))
+
+#define aarch64_stub_hash_lookup(table, string, create, copy) \
+ ((struct elf_aarch64_stub_hash_entry *) \
+ bfd_hash_lookup ((table), (string), (create), (copy)))
+
+/* AArch64 ELF linker hash table. */
+struct elf_aarch64_link_hash_table
+{
+ /* The main hash table. */
+ struct elf_link_hash_table root;
+
+ /* Nonzero to force PIC branch veneers. */
+ int pic_veneer;
+
+ /* Fix erratum 835769. */
+ int fix_erratum_835769;
+
+ /* A table of fix locations for erratum 835769. This holds erratum
+ fix locations between elfNN_aarch64_size_stubs() and
+ elfNN_aarch64_write_section(). */
+ struct aarch64_erratum_835769_fix *aarch64_erratum_835769_fixes;
+ unsigned int num_aarch64_erratum_835769_fixes;
+
+ /* The number of bytes in the initial entry in the PLT. */
+ bfd_size_type plt_header_size;
+
+ /* The number of bytes in the subsequent PLT etries. */
+ bfd_size_type plt_entry_size;
+
+ /* Short-cuts to get to dynamic linker sections. */
+ asection *sdynbss;
+ asection *srelbss;
+
+ /* Small local sym cache. */
+ struct sym_cache sym_cache;
+
+ /* For convenience in allocate_dynrelocs. */
+ bfd *obfd;
+
+ /* The amount of space used by the reserved portion of the sgotplt
+ section, plus whatever space is used by the jump slots. */
+ bfd_vma sgotplt_jump_table_size;
+
+ /* The stub hash table. */
+ struct bfd_hash_table stub_hash_table;
+
+ /* Linker stub bfd. */
+ bfd *stub_bfd;
+
+ /* Linker call-backs. */
+ asection *(*add_stub_section) (const char *, asection *);
+ void (*layout_sections_again) (void);
+
+ /* Array to keep track of which stub sections have been created, and
+ information on stub grouping. */
+ struct map_stub
+ {
+ /* This is the section to which stubs in the group will be
+ attached. */
+ asection *link_sec;
+ /* The stub section. */
+ asection *stub_sec;
+ } *stub_group;
+
+ /* Assorted information used by elfNN_aarch64_size_stubs. */
+ unsigned int bfd_count;
+ int top_index;
+ asection **input_list;
+
+ /* The offset into splt of the PLT entry for the TLS descriptor
+ resolver. Special values are 0, if not necessary (or not found
+ to be necessary yet), and -1 if needed but not determined
+ yet. */
+ bfd_vma tlsdesc_plt;
+
+ /* The GOT offset for the lazy trampoline. Communicated to the
+ loader via DT_TLSDESC_GOT. The magic value (bfd_vma) -1
+ indicates an offset is not allocated. */
+ bfd_vma dt_tlsdesc_got;
+
+ /* Used by local STT_GNU_IFUNC symbols. */
+ htab_t loc_hash_table;
+ void * loc_hash_memory;
+};
+
+/* Create an entry in an AArch64 ELF linker hash table. */
+
+static struct bfd_hash_entry *
+elfNN_aarch64_link_hash_newfunc (struct bfd_hash_entry *entry,
+ struct bfd_hash_table *table,
+ const char *string)
+{
+ struct elf_aarch64_link_hash_entry *ret =
+ (struct elf_aarch64_link_hash_entry *) entry;
+
+ /* Allocate the structure if it has not already been allocated by a
+ subclass. */
+ if (ret == NULL)
+ ret = bfd_hash_allocate (table,
+ sizeof (struct elf_aarch64_link_hash_entry));
+ if (ret == NULL)
+ return (struct bfd_hash_entry *) ret;
+
+ /* Call the allocation method of the superclass. */
+ ret = ((struct elf_aarch64_link_hash_entry *)
+ _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry *) ret,
+ table, string));
+ if (ret != NULL)
+ {
+ ret->dyn_relocs = NULL;
+ ret->got_type = GOT_UNKNOWN;
+ ret->plt_got_offset = (bfd_vma) - 1;
+ ret->stub_cache = NULL;
+ ret->tlsdesc_got_jump_table_offset = (bfd_vma) - 1;
+ }
+
+ return (struct bfd_hash_entry *) ret;
+}
+
+/* Initialize an entry in the stub hash table. */
+
+static struct bfd_hash_entry *
+stub_hash_newfunc (struct bfd_hash_entry *entry,
+ struct bfd_hash_table *table, const char *string)
+{
+ /* Allocate the structure if it has not already been allocated by a
+ subclass. */
+ if (entry == NULL)
+ {
+ entry = bfd_hash_allocate (table,
+ sizeof (struct
+ elf_aarch64_stub_hash_entry));
+ if (entry == NULL)
+ return entry;
+ }
+
+ /* Call the allocation method of the superclass. */
+ entry = bfd_hash_newfunc (entry, table, string);
+ if (entry != NULL)
+ {
+ struct elf_aarch64_stub_hash_entry *eh;
+
+ /* Initialize the local fields. */
+ eh = (struct elf_aarch64_stub_hash_entry *) entry;
+ eh->stub_sec = NULL;
+ eh->stub_offset = 0;
+ eh->target_value = 0;
+ eh->target_section = NULL;
+ eh->stub_type = aarch64_stub_none;
+ eh->h = NULL;
+ eh->id_sec = NULL;
+ }
+
+ return entry;
+}
+
+/* Compute a hash of a local hash entry. We use elf_link_hash_entry
+ for local symbol so that we can handle local STT_GNU_IFUNC symbols
+ as global symbol. We reuse indx and dynstr_index for local symbol
+ hash since they aren't used by global symbols in this backend. */
+
+static hashval_t
+elfNN_aarch64_local_htab_hash (const void *ptr)
+{
+ struct elf_link_hash_entry *h
+ = (struct elf_link_hash_entry *) ptr;
+ return ELF_LOCAL_SYMBOL_HASH (h->indx, h->dynstr_index);
+}
+
+/* Compare local hash entries. */
+
+static int
+elfNN_aarch64_local_htab_eq (const void *ptr1, const void *ptr2)
+{
+ struct elf_link_hash_entry *h1
+ = (struct elf_link_hash_entry *) ptr1;
+ struct elf_link_hash_entry *h2
+ = (struct elf_link_hash_entry *) ptr2;
+
+ return h1->indx == h2->indx && h1->dynstr_index == h2->dynstr_index;
+}
+
+/* Find and/or create a hash entry for local symbol. */
+
+static struct elf_link_hash_entry *
+elfNN_aarch64_get_local_sym_hash (struct elf_aarch64_link_hash_table *htab,
+ bfd *abfd, const Elf_Internal_Rela *rel,
+ bfd_boolean create)
+{
+ struct elf_aarch64_link_hash_entry e, *ret;
+ asection *sec = abfd->sections;
+ hashval_t h = ELF_LOCAL_SYMBOL_HASH (sec->id,
+ ELFNN_R_SYM (rel->r_info));
+ void **slot;
+
+ e.root.indx = sec->id;
+ e.root.dynstr_index = ELFNN_R_SYM (rel->r_info);
+ slot = htab_find_slot_with_hash (htab->loc_hash_table, &e, h,
+ create ? INSERT : NO_INSERT);
+
+ if (!slot)
+ return NULL;
+
+ if (*slot)
+ {
+ ret = (struct elf_aarch64_link_hash_entry *) *slot;
+ return &ret->root;
+ }
+
+ ret = (struct elf_aarch64_link_hash_entry *)
+ objalloc_alloc ((struct objalloc *) htab->loc_hash_memory,
+ sizeof (struct elf_aarch64_link_hash_entry));
+ if (ret)
+ {
+ memset (ret, 0, sizeof (*ret));
+ ret->root.indx = sec->id;
+ ret->root.dynstr_index = ELFNN_R_SYM (rel->r_info);
+ ret->root.dynindx = -1;
+ *slot = ret;
+ }
+ return &ret->root;
+}
+
+/* Copy the extra info we tack onto an elf_link_hash_entry. */
+
+static void
+elfNN_aarch64_copy_indirect_symbol (struct bfd_link_info *info,
+ struct elf_link_hash_entry *dir,
+ struct elf_link_hash_entry *ind)
+{
+ struct elf_aarch64_link_hash_entry *edir, *eind;
+
+ edir = (struct elf_aarch64_link_hash_entry *) dir;
+ eind = (struct elf_aarch64_link_hash_entry *) ind;
+
+ if (eind->dyn_relocs != NULL)
+ {
+ if (edir->dyn_relocs != NULL)
+ {
+ struct elf_dyn_relocs **pp;
+ struct elf_dyn_relocs *p;
+
+ /* Add reloc counts against the indirect sym to the direct sym
+ list. Merge any entries against the same section. */
+ for (pp = &eind->dyn_relocs; (p = *pp) != NULL;)
+ {
+ struct elf_dyn_relocs *q;
+
+ for (q = edir->dyn_relocs; q != NULL; q = q->next)
+ if (q->sec == p->sec)
+ {
+ q->pc_count += p->pc_count;
+ q->count += p->count;
+ *pp = p->next;
+ break;
+ }
+ if (q == NULL)
+ pp = &p->next;
+ }
+ *pp = edir->dyn_relocs;
+ }
+
+ edir->dyn_relocs = eind->dyn_relocs;
+ eind->dyn_relocs = NULL;
+ }
+
+ if (ind->root.type == bfd_link_hash_indirect)
+ {
+ /* Copy over PLT info. */
+ if (dir->got.refcount <= 0)
+ {
+ edir->got_type = eind->got_type;
+ eind->got_type = GOT_UNKNOWN;
+ }
+ }
+
+ _bfd_elf_link_hash_copy_indirect (info, dir, ind);
+}
+
+/* Destroy an AArch64 elf linker hash table. */
+
+static void
+elfNN_aarch64_link_hash_table_free (bfd *obfd)
+{
+ struct elf_aarch64_link_hash_table *ret
+ = (struct elf_aarch64_link_hash_table *) obfd->link.hash;
+
+ if (ret->loc_hash_table)
+ htab_delete (ret->loc_hash_table);
+ if (ret->loc_hash_memory)
+ objalloc_free ((struct objalloc *) ret->loc_hash_memory);
+
+ bfd_hash_table_free (&ret->stub_hash_table);
+ _bfd_elf_link_hash_table_free (obfd);
+}
+
+/* Create an AArch64 elf linker hash table. */
+
+static struct bfd_link_hash_table *
+elfNN_aarch64_link_hash_table_create (bfd *abfd)
+{
+ struct elf_aarch64_link_hash_table *ret;
+ bfd_size_type amt = sizeof (struct elf_aarch64_link_hash_table);
+
+ ret = bfd_zmalloc (amt);
+ if (ret == NULL)
+ return NULL;
+
+ if (!_bfd_elf_link_hash_table_init
+ (&ret->root, abfd, elfNN_aarch64_link_hash_newfunc,
+ sizeof (struct elf_aarch64_link_hash_entry), AARCH64_ELF_DATA))
+ {
+ free (ret);
+ return NULL;
+ }
+
+ ret->plt_header_size = PLT_ENTRY_SIZE;
+ ret->plt_entry_size = PLT_SMALL_ENTRY_SIZE;
+ ret->obfd = abfd;
+ ret->dt_tlsdesc_got = (bfd_vma) - 1;
+
+ if (!bfd_hash_table_init (&ret->stub_hash_table, stub_hash_newfunc,
+ sizeof (struct elf_aarch64_stub_hash_entry)))
+ {
+ _bfd_elf_link_hash_table_free (abfd);
+ return NULL;
+ }
+
+ ret->loc_hash_table = htab_try_create (1024,
+ elfNN_aarch64_local_htab_hash,
+ elfNN_aarch64_local_htab_eq,
+ NULL);
+ ret->loc_hash_memory = objalloc_create ();
+ if (!ret->loc_hash_table || !ret->loc_hash_memory)
+ {
+ elfNN_aarch64_link_hash_table_free (abfd);
+ return NULL;
+ }
+ ret->root.root.hash_table_free = elfNN_aarch64_link_hash_table_free;
+
+ return &ret->root.root;
+}
+
+static bfd_boolean
+aarch64_relocate (unsigned int r_type, bfd *input_bfd, asection *input_section,
+ bfd_vma offset, bfd_vma value)
+{
+ reloc_howto_type *howto;
+ bfd_vma place;
+
+ howto = elfNN_aarch64_howto_from_type (r_type);
+ place = (input_section->output_section->vma + input_section->output_offset
+ + offset);
+
+ r_type = elfNN_aarch64_bfd_reloc_from_type (r_type);
+ value = _bfd_aarch64_elf_resolve_relocation (r_type, place, value, 0, FALSE);
+ return _bfd_aarch64_elf_put_addend (input_bfd,
+ input_section->contents + offset, r_type,
+ howto, value);
+}
+
+static enum elf_aarch64_stub_type
+aarch64_select_branch_stub (bfd_vma value, bfd_vma place)
+{
+ if (aarch64_valid_for_adrp_p (value, place))
+ return aarch64_stub_adrp_branch;
+ return aarch64_stub_long_branch;
+}
+
+/* Determine the type of stub needed, if any, for a call. */
+
+static enum elf_aarch64_stub_type
+aarch64_type_of_stub (struct bfd_link_info *info,
+ asection *input_sec,
+ const Elf_Internal_Rela *rel,
+ unsigned char st_type,
+ struct elf_aarch64_link_hash_entry *hash,
+ bfd_vma destination)
+{
+ bfd_vma location;
+ bfd_signed_vma branch_offset;
+ unsigned int r_type;
+ struct elf_aarch64_link_hash_table *globals;
+ enum elf_aarch64_stub_type stub_type = aarch64_stub_none;
+ bfd_boolean via_plt_p;
+
+ if (st_type != STT_FUNC)
+ return stub_type;
+
+ globals = elf_aarch64_hash_table (info);
+ via_plt_p = (globals->root.splt != NULL && hash != NULL
+ && hash->root.plt.offset != (bfd_vma) - 1);
+
+ if (via_plt_p)
+ return stub_type;
+
+ /* Determine where the call point is. */
+ location = (input_sec->output_offset
+ + input_sec->output_section->vma + rel->r_offset);
+
+ branch_offset = (bfd_signed_vma) (destination - location);
+
+ r_type = ELFNN_R_TYPE (rel->r_info);
+
+ /* We don't want to redirect any old unconditional jump in this way,
+ only one which is being used for a sibcall, where it is
+ acceptable for the IP0 and IP1 registers to be clobbered. */
+ if ((r_type == AARCH64_R (CALL26) || r_type == AARCH64_R (JUMP26))
+ && (branch_offset > AARCH64_MAX_FWD_BRANCH_OFFSET
+ || branch_offset < AARCH64_MAX_BWD_BRANCH_OFFSET))
+ {
+ stub_type = aarch64_stub_long_branch;
+ }
+
+ return stub_type;
+}
+
+/* Build a name for an entry in the stub hash table. */
+
+static char *
+elfNN_aarch64_stub_name (const asection *input_section,
+ const asection *sym_sec,
+ const struct elf_aarch64_link_hash_entry *hash,
+ const Elf_Internal_Rela *rel)
+{
+ char *stub_name;
+ bfd_size_type len;
+
+ if (hash)
+ {
+ len = 8 + 1 + strlen (hash->root.root.root.string) + 1 + 16 + 1;
+ stub_name = bfd_malloc (len);
+ if (stub_name != NULL)
+ snprintf (stub_name, len, "%08x_%s+%" BFD_VMA_FMT "x",
+ (unsigned int) input_section->id,
+ hash->root.root.root.string,
+ rel->r_addend);
+ }
+ else
+ {
+ len = 8 + 1 + 8 + 1 + 8 + 1 + 16 + 1;
+ stub_name = bfd_malloc (len);
+ if (stub_name != NULL)
+ snprintf (stub_name, len, "%08x_%x:%x+%" BFD_VMA_FMT "x",
+ (unsigned int) input_section->id,
+ (unsigned int) sym_sec->id,
+ (unsigned int) ELFNN_R_SYM (rel->r_info),
+ rel->r_addend);
+ }
+
+ return stub_name;
+}
+
+/* Look up an entry in the stub hash. Stub entries are cached because
+ creating the stub name takes a bit of time. */
+
+static struct elf_aarch64_stub_hash_entry *
+elfNN_aarch64_get_stub_entry (const asection *input_section,
+ const asection *sym_sec,
+ struct elf_link_hash_entry *hash,
+ const Elf_Internal_Rela *rel,
+ struct elf_aarch64_link_hash_table *htab)
+{
+ struct elf_aarch64_stub_hash_entry *stub_entry;
+ struct elf_aarch64_link_hash_entry *h =
+ (struct elf_aarch64_link_hash_entry *) hash;
+ const asection *id_sec;
+
+ if ((input_section->flags & SEC_CODE) == 0)
+ return NULL;
+
+ /* If this input section is part of a group of sections sharing one
+ stub section, then use the id of the first section in the group.
+ Stub names need to include a section id, as there may well be
+ more than one stub used to reach say, printf, and we need to
+ distinguish between them. */
+ id_sec = htab->stub_group[input_section->id].link_sec;
+
+ if (h != NULL && h->stub_cache != NULL
+ && h->stub_cache->h == h && h->stub_cache->id_sec == id_sec)
+ {
+ stub_entry = h->stub_cache;
+ }
+ else
+ {
+ char *stub_name;
+
+ stub_name = elfNN_aarch64_stub_name (id_sec, sym_sec, h, rel);
+ if (stub_name == NULL)
+ return NULL;
+
+ stub_entry = aarch64_stub_hash_lookup (&htab->stub_hash_table,
+ stub_name, FALSE, FALSE);
+ if (h != NULL)
+ h->stub_cache = stub_entry;
+
+ free (stub_name);
+ }
+
+ return stub_entry;
+}
+
+/* Add a new stub entry to the stub hash. Not all fields of the new
+ stub entry are initialised. */
+
+static struct elf_aarch64_stub_hash_entry *
+elfNN_aarch64_add_stub (const char *stub_name,
+ asection *section,
+ struct elf_aarch64_link_hash_table *htab)
+{
+ asection *link_sec;
+ asection *stub_sec;
+ struct elf_aarch64_stub_hash_entry *stub_entry;
+
+ link_sec = htab->stub_group[section->id].link_sec;
+ stub_sec = htab->stub_group[section->id].stub_sec;
+ if (stub_sec == NULL)
+ {
+ stub_sec = htab->stub_group[link_sec->id].stub_sec;
+ if (stub_sec == NULL)
+ {
+ size_t namelen;
+ bfd_size_type len;
+ char *s_name;
+
+ namelen = strlen (link_sec->name);
+ len = namelen + sizeof (STUB_SUFFIX);
+ s_name = bfd_alloc (htab->stub_bfd, len);
+ if (s_name == NULL)
+ return NULL;
+
+ memcpy (s_name, link_sec->name, namelen);
+ memcpy (s_name + namelen, STUB_SUFFIX, sizeof (STUB_SUFFIX));
+ stub_sec = (*htab->add_stub_section) (s_name, link_sec);
+ if (stub_sec == NULL)
+ return NULL;
+ htab->stub_group[link_sec->id].stub_sec = stub_sec;
+ }
+ htab->stub_group[section->id].stub_sec = stub_sec;
+ }
+
+ /* Enter this entry into the linker stub hash table. */
+ stub_entry = aarch64_stub_hash_lookup (&htab->stub_hash_table, stub_name,
+ TRUE, FALSE);
+ if (stub_entry == NULL)
+ {
+ (*_bfd_error_handler) (_("%s: cannot create stub entry %s"),
+ section->owner, stub_name);
+ return NULL;
+ }
+
+ stub_entry->stub_sec = stub_sec;
+ stub_entry->stub_offset = 0;
+ stub_entry->id_sec = link_sec;
+
+ return stub_entry;
+}
+
+static bfd_boolean
+aarch64_build_one_stub (struct bfd_hash_entry *gen_entry,
+ void *in_arg ATTRIBUTE_UNUSED)
+{
+ struct elf_aarch64_stub_hash_entry *stub_entry;
+ asection *stub_sec;
+ bfd *stub_bfd;
+ bfd_byte *loc;
+ bfd_vma sym_value;
+ bfd_vma veneered_insn_loc;
+ bfd_vma veneer_entry_loc;
+ bfd_signed_vma branch_offset = 0;
+ unsigned int template_size;
+ const uint32_t *template;
+ unsigned int i;
+
+ /* Massage our args to the form they really have. */
+ stub_entry = (struct elf_aarch64_stub_hash_entry *) gen_entry;
+
+ stub_sec = stub_entry->stub_sec;
+
+ /* Make a note of the offset within the stubs for this entry. */
+ stub_entry->stub_offset = stub_sec->size;
+ loc = stub_sec->contents + stub_entry->stub_offset;
+
+ stub_bfd = stub_sec->owner;
+
+ /* This is the address of the stub destination. */
+ sym_value = (stub_entry->target_value
+ + stub_entry->target_section->output_offset
+ + stub_entry->target_section->output_section->vma);
+
+ if (stub_entry->stub_type == aarch64_stub_long_branch)
+ {
+ bfd_vma place = (stub_entry->stub_offset + stub_sec->output_section->vma
+ + stub_sec->output_offset);
+
+ /* See if we can relax the stub. */
+ if (aarch64_valid_for_adrp_p (sym_value, place))
+ stub_entry->stub_type = aarch64_select_branch_stub (sym_value, place);
+ }
+
+ switch (stub_entry->stub_type)
+ {
+ case aarch64_stub_adrp_branch:
+ template = aarch64_adrp_branch_stub;
+ template_size = sizeof (aarch64_adrp_branch_stub);
+ break;
+ case aarch64_stub_long_branch:
+ template = aarch64_long_branch_stub;
+ template_size = sizeof (aarch64_long_branch_stub);
+ break;
+ case aarch64_stub_erratum_835769_veneer:
+ template = aarch64_erratum_835769_stub;
+ template_size = sizeof (aarch64_erratum_835769_stub);
+ break;
+ default:
+ BFD_FAIL ();
+ return FALSE;
+ }
+
+ for (i = 0; i < (template_size / sizeof template[0]); i++)
+ {
+ bfd_putl32 (template[i], loc);
+ loc += 4;
+ }
+
+ template_size = (template_size + 7) & ~7;
+ stub_sec->size += template_size;
+
+ switch (stub_entry->stub_type)
+ {
+ case aarch64_stub_adrp_branch:
+ if (aarch64_relocate (AARCH64_R (ADR_PREL_PG_HI21), stub_bfd, stub_sec,
+ stub_entry->stub_offset, sym_value))
+ /* The stub would not have been relaxed if the offset was out
+ of range. */
+ BFD_FAIL ();
+
+ _bfd_final_link_relocate
+ (elfNN_aarch64_howto_from_type (AARCH64_R (ADD_ABS_LO12_NC)),
+ stub_bfd,
+ stub_sec,
+ stub_sec->contents,
+ stub_entry->stub_offset + 4,
+ sym_value,
+ 0);
+ break;
+
+ case aarch64_stub_long_branch:
+ /* We want the value relative to the address 12 bytes back from the
+ value itself. */
+ _bfd_final_link_relocate (elfNN_aarch64_howto_from_type
+ (AARCH64_R (PRELNN)), stub_bfd, stub_sec,
+ stub_sec->contents,
+ stub_entry->stub_offset + 16,
+ sym_value + 12, 0);
+ break;
+
+ case aarch64_stub_erratum_835769_veneer:
+ veneered_insn_loc = stub_entry->target_section->output_section->vma
+ + stub_entry->target_section->output_offset
+ + stub_entry->target_value;
+ veneer_entry_loc = stub_entry->stub_sec->output_section->vma
+ + stub_entry->stub_sec->output_offset
+ + stub_entry->stub_offset;
+ branch_offset = veneered_insn_loc - veneer_entry_loc;
+ branch_offset >>= 2;
+ branch_offset &= 0x3ffffff;
+ bfd_putl32 (stub_entry->veneered_insn,
+ stub_sec->contents + stub_entry->stub_offset);
+ bfd_putl32 (template[1] | branch_offset,
+ stub_sec->contents + stub_entry->stub_offset + 4);
+ break;
+
+ default:
+ break;
+ }
+
+ return TRUE;
+}
+
+/* As above, but don't actually build the stub. Just bump offset so
+ we know stub section sizes. */
+
+static bfd_boolean
+aarch64_size_one_stub (struct bfd_hash_entry *gen_entry,
+ void *in_arg ATTRIBUTE_UNUSED)
+{
+ struct elf_aarch64_stub_hash_entry *stub_entry;
+ int size;
+
+ /* Massage our args to the form they really have. */
+ stub_entry = (struct elf_aarch64_stub_hash_entry *) gen_entry;
+
+ switch (stub_entry->stub_type)
+ {
+ case aarch64_stub_adrp_branch:
+ size = sizeof (aarch64_adrp_branch_stub);
+ break;
+ case aarch64_stub_long_branch:
+ size = sizeof (aarch64_long_branch_stub);
+ break;
+ case aarch64_stub_erratum_835769_veneer:
+ size = sizeof (aarch64_erratum_835769_stub);
+ break;
+ default:
+ BFD_FAIL ();
+ return FALSE;
+ break;
+ }
+
+ size = (size + 7) & ~7;
+ stub_entry->stub_sec->size += size;
+ return TRUE;
+}
+
+/* External entry points for sizing and building linker stubs. */
+
+/* Set up various things so that we can make a list of input sections
+ for each output section included in the link. Returns -1 on error,
+ 0 when no stubs will be needed, and 1 on success. */
+
+int
+elfNN_aarch64_setup_section_lists (bfd *output_bfd,
+ struct bfd_link_info *info)
+{
+ bfd *input_bfd;
+ unsigned int bfd_count;
+ int top_id, top_index;
+ asection *section;
+ asection **input_list, **list;
+ bfd_size_type amt;
+ struct elf_aarch64_link_hash_table *htab =
+ elf_aarch64_hash_table (info);
+
+ if (!is_elf_hash_table (htab))
+ return 0;
+
+ /* Count the number of input BFDs and find the top input section id. */
+ for (input_bfd = info->input_bfds, bfd_count = 0, top_id = 0;
+ input_bfd != NULL; input_bfd = input_bfd->link.next)
+ {
+ bfd_count += 1;
+ for (section = input_bfd->sections;
+ section != NULL; section = section->next)
+ {
+ if (top_id < section->id)
+ top_id = section->id;
+ }
+ }
+ htab->bfd_count = bfd_count;
+
+ amt = sizeof (struct map_stub) * (top_id + 1);
+ htab->stub_group = bfd_zmalloc (amt);
+ if (htab->stub_group == NULL)
+ return -1;
+
+ /* We can't use output_bfd->section_count here to find the top output
+ section index as some sections may have been removed, and
+ _bfd_strip_section_from_output doesn't renumber the indices. */
+ for (section = output_bfd->sections, top_index = 0;
+ section != NULL; section = section->next)
+ {
+ if (top_index < section->index)
+ top_index = section->index;
+ }
+
+ htab->top_index = top_index;
+ amt = sizeof (asection *) * (top_index + 1);
+ input_list = bfd_malloc (amt);
+ htab->input_list = input_list;
+ if (input_list == NULL)
+ return -1;
+
+ /* For sections we aren't interested in, mark their entries with a
+ value we can check later. */
+ list = input_list + top_index;
+ do
+ *list = bfd_abs_section_ptr;
+ while (list-- != input_list);
+
+ for (section = output_bfd->sections;
+ section != NULL; section = section->next)
+ {
+ if ((section->flags & SEC_CODE) != 0)
+ input_list[section->index] = NULL;
+ }
+
+ return 1;
+}
+
+/* Used by elfNN_aarch64_next_input_section and group_sections. */
+#define PREV_SEC(sec) (htab->stub_group[(sec)->id].link_sec)
+
+/* The linker repeatedly calls this function for each input section,
+ in the order that input sections are linked into output sections.
+ Build lists of input sections to determine groupings between which
+ we may insert linker stubs. */
+
+void
+elfNN_aarch64_next_input_section (struct bfd_link_info *info, asection *isec)
+{
+ struct elf_aarch64_link_hash_table *htab =
+ elf_aarch64_hash_table (info);
+
+ if (isec->output_section->index <= htab->top_index)
+ {
+ asection **list = htab->input_list + isec->output_section->index;
+
+ if (*list != bfd_abs_section_ptr)
+ {
+ /* Steal the link_sec pointer for our list. */
+ /* This happens to make the list in reverse order,
+ which is what we want. */
+ PREV_SEC (isec) = *list;
+ *list = isec;
+ }
+ }
+}
+
+/* See whether we can group stub sections together. Grouping stub
+ sections may result in fewer stubs. More importantly, we need to
+ put all .init* and .fini* stubs at the beginning of the .init or
+ .fini output sections respectively, because glibc splits the
+ _init and _fini functions into multiple parts. Putting a stub in
+ the middle of a function is not a good idea. */
+
+static void
+group_sections (struct elf_aarch64_link_hash_table *htab,
+ bfd_size_type stub_group_size,
+ bfd_boolean stubs_always_before_branch)
+{
+ asection **list = htab->input_list + htab->top_index;
+
+ do
+ {
+ asection *tail = *list;
+
+ if (tail == bfd_abs_section_ptr)
+ continue;
+
+ while (tail != NULL)
+ {
+ asection *curr;
+ asection *prev;
+ bfd_size_type total;
+
+ curr = tail;
+ total = tail->size;
+ while ((prev = PREV_SEC (curr)) != NULL
+ && ((total += curr->output_offset - prev->output_offset)
+ < stub_group_size))
+ curr = prev;
+
+ /* OK, the size from the start of CURR to the end is less
+ than stub_group_size and thus can be handled by one stub
+ section. (Or the tail section is itself larger than
+ stub_group_size, in which case we may be toast.)
+ We should really be keeping track of the total size of
+ stubs added here, as stubs contribute to the final output
+ section size. */
+ do
+ {
+ prev = PREV_SEC (tail);
+ /* Set up this stub group. */
+ htab->stub_group[tail->id].link_sec = curr;
+ }
+ while (tail != curr && (tail = prev) != NULL);
+
+ /* But wait, there's more! Input sections up to stub_group_size
+ bytes before the stub section can be handled by it too. */
+ if (!stubs_always_before_branch)
+ {
+ total = 0;
+ while (prev != NULL
+ && ((total += tail->output_offset - prev->output_offset)
+ < stub_group_size))
+ {
+ tail = prev;
+ prev = PREV_SEC (tail);
+ htab->stub_group[tail->id].link_sec = curr;
+ }
+ }
+ tail = prev;
+ }
+ }
+ while (list-- != htab->input_list);
+
+ free (htab->input_list);
+}
+
+#undef PREV_SEC
+
+#define AARCH64_BITS(x, pos, n) (((x) >> (pos)) & ((1 << (n)) - 1))
+
+#define AARCH64_RT(insn) AARCH64_BITS (insn, 0, 5)
+#define AARCH64_RT2(insn) AARCH64_BITS (insn, 10, 5)
+#define AARCH64_RA(insn) AARCH64_BITS (insn, 10, 5)
+#define AARCH64_RD(insn) AARCH64_BITS (insn, 0, 5)
+#define AARCH64_RN(insn) AARCH64_BITS (insn, 5, 5)
+#define AARCH64_RM(insn) AARCH64_BITS (insn, 16, 5)
+
+#define AARCH64_MAC(insn) (((insn) & 0xff000000) == 0x9b000000)
+#define AARCH64_BIT(insn, n) AARCH64_BITS (insn, n, 1)
+#define AARCH64_OP31(insn) AARCH64_BITS (insn, 21, 3)
+#define AARCH64_ZR 0x1f
+
+/* All ld/st ops. See C4-182 of the ARM ARM. The encoding space for
+ LD_PCREL, LDST_RO, LDST_UI and LDST_UIMM cover prefetch ops. */
+
+#define AARCH64_LD(insn) (AARCH64_BIT (insn, 22) == 1)
+#define AARCH64_LDST(insn) (((insn) & 0x0a000000) == 0x08000000)
+#define AARCH64_LDST_EX(insn) (((insn) & 0x3f000000) == 0x08000000)
+#define AARCH64_LDST_PCREL(insn) (((insn) & 0x3b000000) == 0x18000000)
+#define AARCH64_LDST_NAP(insn) (((insn) & 0x3b800000) == 0x28000000)
+#define AARCH64_LDSTP_PI(insn) (((insn) & 0x3b800000) == 0x28800000)
+#define AARCH64_LDSTP_O(insn) (((insn) & 0x3b800000) == 0x29000000)
+#define AARCH64_LDSTP_PRE(insn) (((insn) & 0x3b800000) == 0x29800000)
+#define AARCH64_LDST_UI(insn) (((insn) & 0x3b200c00) == 0x38000000)
+#define AARCH64_LDST_PIIMM(insn) (((insn) & 0x3b200c00) == 0x38000400)
+#define AARCH64_LDST_U(insn) (((insn) & 0x3b200c00) == 0x38000800)
+#define AARCH64_LDST_PREIMM(insn) (((insn) & 0x3b200c00) == 0x38000c00)
+#define AARCH64_LDST_RO(insn) (((insn) & 0x3b200c00) == 0x38200800)
+#define AARCH64_LDST_UIMM(insn) (((insn) & 0x3b000000) == 0x39000000)
+#define AARCH64_LDST_SIMD_M(insn) (((insn) & 0xbfbf0000) == 0x0c000000)
+#define AARCH64_LDST_SIMD_M_PI(insn) (((insn) & 0xbfa00000) == 0x0c800000)
+#define AARCH64_LDST_SIMD_S(insn) (((insn) & 0xbf9f0000) == 0x0d000000)
+#define AARCH64_LDST_SIMD_S_PI(insn) (((insn) & 0xbf800000) == 0x0d800000)
+
+/* Classify an INSN if it is indeed a load/store. Return TRUE if INSN
+ is a load/store along with the Rt and Rtn. Return FALSE if not a
+ load/store. */
+
+static bfd_boolean
+aarch64_mem_op_p (uint32_t insn, unsigned int *rt, unsigned int *rtn,
+ bfd_boolean *pair, bfd_boolean *load)
+{
+ uint32_t opcode;
+ unsigned int r;
+ uint32_t opc = 0;
+ uint32_t v = 0;
+ uint32_t opc_v = 0;
+
+ /* Bail out quickly if INSN doesn't fall into the the load-store
+ encoding space. */
+ if (!AARCH64_LDST (insn))
+ return FALSE;
+
+ *pair = FALSE;
+ *load = FALSE;
+ if (AARCH64_LDST_EX (insn))
+ {
+ *rt = AARCH64_RT (insn);
+ *rtn = *rt;
+ if (AARCH64_BIT (insn, 21) == 1)
+ {
+ *pair = TRUE;
+ *rtn = AARCH64_RT2 (insn);
+ }
+ *load = AARCH64_LD (insn);
+ return TRUE;
+ }
+ else if (AARCH64_LDST_NAP (insn)
+ || AARCH64_LDSTP_PI (insn)
+ || AARCH64_LDSTP_O (insn)
+ || AARCH64_LDSTP_PRE (insn))
+ {
+ *pair = TRUE;
+ *rt = AARCH64_RT (insn);
+ *rtn = AARCH64_RT2 (insn);
+ *load = AARCH64_LD (insn);
+ return TRUE;
+ }
+ else if (AARCH64_LDST_PCREL (insn)
+ || AARCH64_LDST_UI (insn)
+ || AARCH64_LDST_PIIMM (insn)
+ || AARCH64_LDST_U (insn)
+ || AARCH64_LDST_PREIMM (insn)
+ || AARCH64_LDST_RO (insn)
+ || AARCH64_LDST_UIMM (insn))
+ {
+ *rt = AARCH64_RT (insn);
+ *rtn = *rt;
+ if (AARCH64_LDST_PCREL (insn))
+ *load = TRUE;
+ opc = AARCH64_BITS (insn, 22, 2);
+ v = AARCH64_BIT (insn, 26);
+ opc_v = opc | (v << 2);
+ *load = (opc_v == 1 || opc_v == 2 || opc_v == 3
+ || opc_v == 5 || opc_v == 7);
+ return TRUE;
+ }
+ else if (AARCH64_LDST_SIMD_M (insn)
+ || AARCH64_LDST_SIMD_M_PI (insn))
+ {
+ *rt = AARCH64_RT (insn);
+ *load = AARCH64_BIT (insn, 22);
+ opcode = (insn >> 12) & 0xf;
+ switch (opcode)
+ {
+ case 0:
+ case 2:
+ *rtn = *rt + 3;
+ break;
+
+ case 4:
+ case 6:
+ *rtn = *rt + 2;
+ break;
+
+ case 7:
+ *rtn = *rt;
+ break;
+
+ case 8:
+ case 10:
+ *rtn = *rt + 1;
+ break;
+
+ default:
+ return FALSE;
+ }
+ return TRUE;
+ }
+ else if (AARCH64_LDST_SIMD_S (insn)
+ || AARCH64_LDST_SIMD_S_PI (insn))
+ {
+ *rt = AARCH64_RT (insn);
+ r = (insn >> 21) & 1;
+ *load = AARCH64_BIT (insn, 22);
+ opcode = (insn >> 13) & 0x7;
+ switch (opcode)
+ {
+ case 0:
+ case 2:
+ case 4:
+ *rtn = *rt + r;
+ break;
+
+ case 1:
+ case 3:
+ case 5:
+ *rtn = *rt + (r == 0 ? 2 : 3);
+ break;
+
+ case 6:
+ *rtn = *rt + r;
+ break;
+
+ case 7:
+ *rtn = *rt + (r == 0 ? 2 : 3);
+ break;
+
+ default:
+ return FALSE;
+ }
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/* Return TRUE if INSN is multiply-accumulate. */
+
+static bfd_boolean
+aarch64_mlxl_p (uint32_t insn)
+{
+ uint32_t op31 = AARCH64_OP31 (insn);
+
+ if (AARCH64_MAC (insn)
+ && (op31 == 0 || op31 == 1 || op31 == 5)
+ /* Exclude MUL instructions which are encoded as a multiple accumulate
+ with RA = XZR. */
+ && AARCH64_RA (insn) != AARCH64_ZR)
+ return TRUE;
+
+ return FALSE;
+}
+
+/* Some early revisions of the Cortex-A53 have an erratum (835769) whereby
+ it is possible for a 64-bit multiply-accumulate instruction to generate an
+ incorrect result. The details are quite complex and hard to
+ determine statically, since branches in the code may exist in some
+ circumstances, but all cases end with a memory (load, store, or
+ prefetch) instruction followed immediately by the multiply-accumulate
+ operation. We employ a linker patching technique, by moving the potentially
+ affected multiply-accumulate instruction into a patch region and replacing
+ the original instruction with a branch to the patch. This function checks
+ if INSN_1 is the memory operation followed by a multiply-accumulate
+ operation (INSN_2). Return TRUE if an erratum sequence is found, FALSE
+ if INSN_1 and INSN_2 are safe. */
+
+static bfd_boolean
+aarch64_erratum_sequence (uint32_t insn_1, uint32_t insn_2)
+{
+ uint32_t rt;
+ uint32_t rtn;
+ uint32_t rn;
+ uint32_t rm;
+ uint32_t ra;
+ bfd_boolean pair;
+ bfd_boolean load;
+
+ if (aarch64_mlxl_p (insn_2)
+ && aarch64_mem_op_p (insn_1, &rt, &rtn, &pair, &load))
+ {
+ /* Any SIMD memory op is independent of the subsequent MLA
+ by definition of the erratum. */
+ if (AARCH64_BIT (insn_1, 26))
+ return TRUE;
+
+ /* If not SIMD, check for integer memory ops and MLA relationship. */
+ rn = AARCH64_RN (insn_2);
+ ra = AARCH64_RA (insn_2);
+ rm = AARCH64_RM (insn_2);
+
+ /* If this is a load and there's a true(RAW) dependency, we are safe
+ and this is not an erratum sequence. */
+ if (load &&
+ (rt == rn || rt == rm || rt == ra
+ || (pair && (rtn == rn || rtn == rm || rtn == ra))))
+ return FALSE;
+
+ /* We conservatively put out stubs for all other cases (including
+ writebacks). */
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/* Used to order a list of mapping symbols by address. */
+
+static int
+elf_aarch64_compare_mapping (const void *a, const void *b)
+{
+ const elf_aarch64_section_map *amap = (const elf_aarch64_section_map *) a;
+ const elf_aarch64_section_map *bmap = (const elf_aarch64_section_map *) b;
+
+ if (amap->vma > bmap->vma)
+ return 1;
+ else if (amap->vma < bmap->vma)
+ return -1;
+ else if (amap->type > bmap->type)
+ /* Ensure results do not depend on the host qsort for objects with
+ multiple mapping symbols at the same address by sorting on type
+ after vma. */
+ return 1;
+ else if (amap->type < bmap->type)
+ return -1;
+ else
+ return 0;
+}
+
+static bfd_boolean
+erratum_835769_scan (bfd *input_bfd,
+ struct bfd_link_info *info,
+ struct aarch64_erratum_835769_fix **fixes_p,
+ unsigned int *num_fixes_p,
+ unsigned int *fix_table_size_p)
+{
+ asection *section;
+ struct elf_aarch64_link_hash_table *htab = elf_aarch64_hash_table (info);
+ struct aarch64_erratum_835769_fix *fixes = *fixes_p;
+ unsigned int num_fixes = *num_fixes_p;
+ unsigned int fix_table_size = *fix_table_size_p;
+
+ if (htab == NULL)
+ return FALSE;
+
+ for (section = input_bfd->sections;
+ section != NULL;
+ section = section->next)
+ {
+ bfd_byte *contents = NULL;
+ struct _aarch64_elf_section_data *sec_data;
+ unsigned int span;
+
+ if (elf_section_type (section) != SHT_PROGBITS
+ || (elf_section_flags (section) & SHF_EXECINSTR) == 0
+ || (section->flags & SEC_EXCLUDE) != 0
+ || (section->sec_info_type == SEC_INFO_TYPE_JUST_SYMS)
+ || (section->output_section == bfd_abs_section_ptr))
+ continue;
+
+ if (elf_section_data (section)->this_hdr.contents != NULL)
+ contents = elf_section_data (section)->this_hdr.contents;
+ else if (! bfd_malloc_and_get_section (input_bfd, section, &contents))
+ return TRUE;
+
+ sec_data = elf_aarch64_section_data (section);
+
+ qsort (sec_data->map, sec_data->mapcount,
+ sizeof (elf_aarch64_section_map), elf_aarch64_compare_mapping);
+
+ for (span = 0; span < sec_data->mapcount; span++)
+ {
+ unsigned int span_start = sec_data->map[span].vma;
+ unsigned int span_end = ((span == sec_data->mapcount - 1)
+ ? sec_data->map[0].vma + section->size
+ : sec_data->map[span + 1].vma);
+ unsigned int i;
+ char span_type = sec_data->map[span].type;
+
+ if (span_type == 'd')
+ continue;
+
+ for (i = span_start; i + 4 < span_end; i += 4)
+ {
+ uint32_t insn_1 = bfd_getl32 (contents + i);
+ uint32_t insn_2 = bfd_getl32 (contents + i + 4);
+
+ if (aarch64_erratum_sequence (insn_1, insn_2))
+ {
+ char *stub_name = NULL;
+ stub_name = (char *) bfd_malloc
+ (strlen ("__erratum_835769_veneer_") + 16);
+ if (stub_name != NULL)
+ sprintf
+ (stub_name,"__erratum_835769_veneer_%d", num_fixes);
+ else
+ return TRUE;
+
+ if (num_fixes == fix_table_size)
+ {
+ fix_table_size *= 2;
+ fixes =
+ (struct aarch64_erratum_835769_fix *)
+ bfd_realloc (fixes,
+ sizeof (struct aarch64_erratum_835769_fix)
+ * fix_table_size);
+ if (fixes == NULL)
+ return TRUE;
+ }
+
+ fixes[num_fixes].input_bfd = input_bfd;
+ fixes[num_fixes].section = section;
+ fixes[num_fixes].offset = i + 4;
+ fixes[num_fixes].veneered_insn = insn_2;
+ fixes[num_fixes].stub_name = stub_name;
+ fixes[num_fixes].stub_type = aarch64_stub_erratum_835769_veneer;
+ num_fixes++;
+ }
+ }
+ }
+ if (elf_section_data (section)->this_hdr.contents == NULL)
+ free (contents);
+ }
+
+ *fixes_p = fixes;
+ *num_fixes_p = num_fixes;
+ *fix_table_size_p = fix_table_size;
+ return FALSE;
+}
+
+/* Find or create a stub section. Returns a pointer to the stub section, and
+ the section to which the stub section will be attached (in *LINK_SEC_P).
+ LINK_SEC_P may be NULL. */
+
+static asection *
+elf_aarch64_create_or_find_stub_sec (asection **link_sec_p, asection *section,
+ struct elf_aarch64_link_hash_table *htab)
+{
+ asection *link_sec;
+ asection *stub_sec;
+
+ link_sec = htab->stub_group[section->id].link_sec;
+ BFD_ASSERT (link_sec != NULL);
+ stub_sec = htab->stub_group[section->id].stub_sec;
+
+ if (stub_sec == NULL)
+ {
+ stub_sec = htab->stub_group[link_sec->id].stub_sec;
+ if (stub_sec == NULL)
+ {
+ size_t namelen;
+ bfd_size_type len;
+ char *s_name;
+
+ namelen = strlen (link_sec->name);
+ len = namelen + sizeof (STUB_SUFFIX);
+ s_name = (char *) bfd_alloc (htab->stub_bfd, len);
+ if (s_name == NULL)
+ return NULL;
+
+ memcpy (s_name, link_sec->name, namelen);
+ memcpy (s_name + namelen, STUB_SUFFIX, sizeof (STUB_SUFFIX));
+ stub_sec = (*htab->add_stub_section) (s_name, link_sec);
+
+ if (stub_sec == NULL)
+ return NULL;
+ htab->stub_group[link_sec->id].stub_sec = stub_sec;
+ }
+ htab->stub_group[section->id].stub_sec = stub_sec;
+ }
+
+ if (link_sec_p)
+ *link_sec_p = link_sec;
+
+ return stub_sec;
+}
+
+/* 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. */
+
+bfd_boolean
+elfNN_aarch64_size_stubs (bfd *output_bfd,
+ bfd *stub_bfd,
+ struct bfd_link_info *info,
+ bfd_signed_vma group_size,
+ asection * (*add_stub_section) (const char *,
+ asection *),
+ void (*layout_sections_again) (void))
+{
+ bfd_size_type stub_group_size;
+ bfd_boolean stubs_always_before_branch;
+ bfd_boolean stub_changed = 0;
+ struct elf_aarch64_link_hash_table *htab = elf_aarch64_hash_table (info);
+ struct aarch64_erratum_835769_fix *erratum_835769_fixes = NULL;
+ unsigned int num_erratum_835769_fixes = 0;
+ unsigned int erratum_835769_fix_table_size = 10;
+ unsigned int i;
+
+ if (htab->fix_erratum_835769)
+ {
+ erratum_835769_fixes
+ = (struct aarch64_erratum_835769_fix *)
+ bfd_zmalloc
+ (sizeof (struct aarch64_erratum_835769_fix) *
+ erratum_835769_fix_table_size);
+ if (erratum_835769_fixes == NULL)
+ goto error_ret_free_local;
+ }
+
+ /* Propagate mach to stub bfd, because it may not have been
+ finalized when we created stub_bfd. */
+ bfd_set_arch_mach (stub_bfd, bfd_get_arch (output_bfd),
+ bfd_get_mach (output_bfd));
+
+ /* Stash our params away. */
+ htab->stub_bfd = stub_bfd;
+ htab->add_stub_section = add_stub_section;
+ htab->layout_sections_again = layout_sections_again;
+ stubs_always_before_branch = group_size < 0;
+ if (group_size < 0)
+ stub_group_size = -group_size;
+ else
+ stub_group_size = group_size;
+
+ if (stub_group_size == 1)
+ {
+ /* Default values. */
+ /* AArch64 branch range is +-128MB. The value used is 1MB less. */
+ stub_group_size = 127 * 1024 * 1024;
+ }
+
+ group_sections (htab, stub_group_size, stubs_always_before_branch);
+
+ while (1)
+ {
+ bfd *input_bfd;
+ unsigned int bfd_indx;
+ asection *stub_sec;
+ unsigned prev_num_erratum_835769_fixes = num_erratum_835769_fixes;
+
+ num_erratum_835769_fixes = 0;
+ for (input_bfd = info->input_bfds, bfd_indx = 0;
+ input_bfd != NULL; input_bfd = input_bfd->link.next, bfd_indx++)
+ {
+ Elf_Internal_Shdr *symtab_hdr;
+ asection *section;
+ Elf_Internal_Sym *local_syms = NULL;
+
+ /* We'll need the symbol table in a second. */
+ symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
+ if (symtab_hdr->sh_info == 0)
+ continue;
+
+ /* Walk over each section attached to the input bfd. */
+ for (section = input_bfd->sections;
+ section != NULL; section = section->next)
+ {
+ Elf_Internal_Rela *internal_relocs, *irelaend, *irela;
+
+ /* If there aren't any relocs, then there's nothing more
+ to do. */
+ if ((section->flags & SEC_RELOC) == 0
+ || section->reloc_count == 0
+ || (section->flags & SEC_CODE) == 0)
+ continue;
+
+ /* If this section is a link-once section that will be
+ discarded, then don't create any stubs. */
+ if (section->output_section == NULL
+ || section->output_section->owner != output_bfd)
+ continue;
+
+ /* Get the relocs. */
+ internal_relocs
+ = _bfd_elf_link_read_relocs (input_bfd, section, NULL,
+ NULL, info->keep_memory);
+ if (internal_relocs == NULL)
+ goto error_ret_free_local;
+
+ /* Now examine each relocation. */
+ irela = internal_relocs;
+ irelaend = irela + section->reloc_count;
+ for (; irela < irelaend; irela++)
+ {
+ unsigned int r_type, r_indx;
+ enum elf_aarch64_stub_type stub_type;
+ struct elf_aarch64_stub_hash_entry *stub_entry;
+ asection *sym_sec;
+ bfd_vma sym_value;
+ bfd_vma destination;
+ struct elf_aarch64_link_hash_entry *hash;
+ const char *sym_name;
+ char *stub_name;
+ const asection *id_sec;
+ unsigned char st_type;
+ bfd_size_type len;
+
+ r_type = ELFNN_R_TYPE (irela->r_info);
+ r_indx = ELFNN_R_SYM (irela->r_info);
+
+ if (r_type >= (unsigned int) R_AARCH64_end)
+ {
+ bfd_set_error (bfd_error_bad_value);
+ error_ret_free_internal:
+ if (elf_section_data (section)->relocs == NULL)
+ free (internal_relocs);
+ goto error_ret_free_local;
+ }
+
+ /* Only look for stubs on unconditional branch and
+ branch and link instructions. */
+ if (r_type != (unsigned int) AARCH64_R (CALL26)
+ && r_type != (unsigned int) AARCH64_R (JUMP26))
+ continue;
+
+ /* Now determine the call target, its name, value,
+ section. */
+ sym_sec = NULL;
+ sym_value = 0;
+ destination = 0;
+ hash = NULL;
+ sym_name = NULL;
+ if (r_indx < symtab_hdr->sh_info)
+ {
+ /* It's a local symbol. */
+ Elf_Internal_Sym *sym;
+ Elf_Internal_Shdr *hdr;
+
+ if (local_syms == NULL)
+ {
+ local_syms
+ = (Elf_Internal_Sym *) symtab_hdr->contents;
+ if (local_syms == NULL)
+ local_syms
+ = bfd_elf_get_elf_syms (input_bfd, symtab_hdr,
+ symtab_hdr->sh_info, 0,
+ NULL, NULL, NULL);
+ if (local_syms == NULL)
+ goto error_ret_free_internal;
+ }
+
+ sym = local_syms + r_indx;
+ hdr = elf_elfsections (input_bfd)[sym->st_shndx];
+ sym_sec = hdr->bfd_section;
+ if (!sym_sec)
+ /* This is an undefined symbol. It can never
+ be resolved. */
+ continue;
+
+ if (ELF_ST_TYPE (sym->st_info) != STT_SECTION)
+ sym_value = sym->st_value;
+ destination = (sym_value + irela->r_addend
+ + sym_sec->output_offset
+ + sym_sec->output_section->vma);
+ st_type = ELF_ST_TYPE (sym->st_info);
+ sym_name
+ = bfd_elf_string_from_elf_section (input_bfd,
+ symtab_hdr->sh_link,
+ sym->st_name);
+ }
+ else
+ {
+ int e_indx;
+
+ e_indx = r_indx - symtab_hdr->sh_info;
+ hash = ((struct elf_aarch64_link_hash_entry *)
+ elf_sym_hashes (input_bfd)[e_indx]);
+
+ while (hash->root.root.type == bfd_link_hash_indirect
+ || hash->root.root.type == bfd_link_hash_warning)
+ hash = ((struct elf_aarch64_link_hash_entry *)
+ hash->root.root.u.i.link);
+
+ if (hash->root.root.type == bfd_link_hash_defined
+ || hash->root.root.type == bfd_link_hash_defweak)
+ {
+ struct elf_aarch64_link_hash_table *globals =
+ elf_aarch64_hash_table (info);
+ sym_sec = hash->root.root.u.def.section;
+ sym_value = hash->root.root.u.def.value;
+ /* For a destination in a shared library,
+ use the PLT stub as target address to
+ decide whether a branch stub is
+ needed. */
+ if (globals->root.splt != NULL && hash != NULL
+ && hash->root.plt.offset != (bfd_vma) - 1)
+ {
+ sym_sec = globals->root.splt;
+ sym_value = hash->root.plt.offset;
+ if (sym_sec->output_section != NULL)
+ destination = (sym_value
+ + sym_sec->output_offset
+ +
+ sym_sec->output_section->vma);
+ }
+ else if (sym_sec->output_section != NULL)
+ destination = (sym_value + irela->r_addend
+ + sym_sec->output_offset
+ + sym_sec->output_section->vma);
+ }
+ else if (hash->root.root.type == bfd_link_hash_undefined
+ || (hash->root.root.type
+ == bfd_link_hash_undefweak))
+ {
+ /* For a shared library, use the PLT stub as
+ target address to decide whether a long
+ branch stub is needed.
+ For absolute code, they cannot be handled. */
+ struct elf_aarch64_link_hash_table *globals =
+ elf_aarch64_hash_table (info);
+
+ if (globals->root.splt != NULL && hash != NULL
+ && hash->root.plt.offset != (bfd_vma) - 1)
+ {
+ sym_sec = globals->root.splt;
+ sym_value = hash->root.plt.offset;
+ if (sym_sec->output_section != NULL)
+ destination = (sym_value
+ + sym_sec->output_offset
+ +
+ sym_sec->output_section->vma);
+ }
+ else
+ continue;
+ }
+ else
+ {
+ bfd_set_error (bfd_error_bad_value);
+ goto error_ret_free_internal;
+ }
+ st_type = ELF_ST_TYPE (hash->root.type);
+ sym_name = hash->root.root.root.string;
+ }
+
+ /* Determine what (if any) linker stub is needed. */
+ stub_type = aarch64_type_of_stub
+ (info, section, irela, st_type, hash, destination);
+ if (stub_type == aarch64_stub_none)
+ continue;
+
+ /* Support for grouping stub sections. */
+ id_sec = htab->stub_group[section->id].link_sec;
+
+ /* Get the name of this stub. */
+ stub_name = elfNN_aarch64_stub_name (id_sec, sym_sec, hash,
+ irela);
+ if (!stub_name)
+ goto error_ret_free_internal;
+
+ stub_entry =
+ aarch64_stub_hash_lookup (&htab->stub_hash_table,
+ stub_name, FALSE, FALSE);
+ if (stub_entry != NULL)
+ {
+ /* The proper stub has already been created. */
+ free (stub_name);
+ continue;
+ }
+
+ stub_entry = elfNN_aarch64_add_stub (stub_name, section,
+ htab);
+ if (stub_entry == NULL)
+ {
+ free (stub_name);
+ goto error_ret_free_internal;
+ }
+
+ stub_entry->target_value = sym_value;
+ stub_entry->target_section = sym_sec;
+ stub_entry->stub_type = stub_type;
+ stub_entry->h = hash;
+ stub_entry->st_type = st_type;
+
+ if (sym_name == NULL)
+ sym_name = "unnamed";
+ len = sizeof (STUB_ENTRY_NAME) + strlen (sym_name);
+ stub_entry->output_name = bfd_alloc (htab->stub_bfd, len);
+ if (stub_entry->output_name == NULL)
+ {
+ free (stub_name);
+ goto error_ret_free_internal;
+ }
+
+ snprintf (stub_entry->output_name, len, STUB_ENTRY_NAME,
+ sym_name);
+
+ stub_changed = TRUE;
+ }
+
+ /* We're done with the internal relocs, free them. */
+ if (elf_section_data (section)->relocs == NULL)
+ free (internal_relocs);
+ }
+
+ if (htab->fix_erratum_835769)
+ {
+ /* Scan for sequences which might trigger erratum 835769. */
+ if (erratum_835769_scan (input_bfd, info, &erratum_835769_fixes,
+ &num_erratum_835769_fixes,
+ &erratum_835769_fix_table_size) != 0)
+ goto error_ret_free_local;
+ }
+ }
+
+ if (prev_num_erratum_835769_fixes != num_erratum_835769_fixes)
+ stub_changed = TRUE;
+
+ if (!stub_changed)
+ break;
+
+ /* OK, we've added some stubs. Find out the new size of the
+ stub sections. */
+ for (stub_sec = htab->stub_bfd->sections;
+ stub_sec != NULL; stub_sec = stub_sec->next)
+ {
+ /* Ignore non-stub sections. */
+ if (!strstr (stub_sec->name, STUB_SUFFIX))
+ continue;
+ stub_sec->size = 0;
+ }
+
+ bfd_hash_traverse (&htab->stub_hash_table, aarch64_size_one_stub, htab);
+
+ /* Add erratum 835769 veneers to stub section sizes too. */
+ if (htab->fix_erratum_835769)
+ for (i = 0; i < num_erratum_835769_fixes; i++)
+ {
+ stub_sec = elf_aarch64_create_or_find_stub_sec (NULL,
+ erratum_835769_fixes[i].section, htab);
+
+ if (stub_sec == NULL)
+ goto error_ret_free_local;
+
+ stub_sec->size += 8;
+ }
+
+ /* Ask the linker to do its stuff. */
+ (*htab->layout_sections_again) ();
+ stub_changed = FALSE;
+ }
+
+ /* Add stubs for erratum 835769 fixes now. */
+ if (htab->fix_erratum_835769)
+ {
+ for (i = 0; i < num_erratum_835769_fixes; i++)
+ {
+ struct elf_aarch64_stub_hash_entry *stub_entry;
+ char *stub_name = erratum_835769_fixes[i].stub_name;
+ asection *section = erratum_835769_fixes[i].section;
+ unsigned int section_id = erratum_835769_fixes[i].section->id;
+ asection *link_sec = htab->stub_group[section_id].link_sec;
+ asection *stub_sec = htab->stub_group[section_id].stub_sec;
+
+ stub_entry = aarch64_stub_hash_lookup (&htab->stub_hash_table,
+ stub_name, TRUE, FALSE);
+ if (stub_entry == NULL)
+ {
+ (*_bfd_error_handler) (_("%s: cannot create stub entry %s"),
+ section->owner,
+ stub_name);
+ return FALSE;
+ }
+
+ stub_entry->stub_sec = stub_sec;
+ stub_entry->stub_offset = 0;
+ stub_entry->id_sec = link_sec;
+ stub_entry->stub_type = erratum_835769_fixes[i].stub_type;
+ stub_entry->target_section = section;
+ stub_entry->target_value = erratum_835769_fixes[i].offset;
+ stub_entry->veneered_insn = erratum_835769_fixes[i].veneered_insn;
+ stub_entry->output_name = erratum_835769_fixes[i].stub_name;
+ }
+
+ /* Stash the erratum 835769 fix array for use later in
+ elfNN_aarch64_write_section(). */
+ htab->aarch64_erratum_835769_fixes = erratum_835769_fixes;
+ htab->num_aarch64_erratum_835769_fixes = num_erratum_835769_fixes;
+ }
+ else
+ {
+ htab->aarch64_erratum_835769_fixes = NULL;
+ htab->num_aarch64_erratum_835769_fixes = 0;
+ }
+
+ return TRUE;
+
+error_ret_free_local:
+ return FALSE;
+}
+
+/* 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. We also set up the .plt entries for statically linked PIC
+ functions here. This function is called via aarch64_elf_finish in the
+ linker. */
+
+bfd_boolean
+elfNN_aarch64_build_stubs (struct bfd_link_info *info)
+{
+ asection *stub_sec;
+ struct bfd_hash_table *table;
+ struct elf_aarch64_link_hash_table *htab;
+
+ htab = elf_aarch64_hash_table (info);
+
+ for (stub_sec = htab->stub_bfd->sections;
+ stub_sec != NULL; stub_sec = stub_sec->next)
+ {
+ bfd_size_type size;
+
+ /* Ignore non-stub sections. */
+ if (!strstr (stub_sec->name, STUB_SUFFIX))
+ continue;
+
+ /* Allocate memory to hold the linker stubs. */
+ size = stub_sec->size;
+ stub_sec->contents = bfd_zalloc (htab->stub_bfd, size);
+ if (stub_sec->contents == NULL && size != 0)
+ return FALSE;
+ stub_sec->size = 0;
+ }
+
+ /* Build the stubs as directed by the stub hash table. */
+ table = &htab->stub_hash_table;
+ bfd_hash_traverse (table, aarch64_build_one_stub, info);
+
+ return TRUE;
+}
+
+
+/* Add an entry to the code/data map for section SEC. */
+
+static void
+elfNN_aarch64_section_map_add (asection *sec, char type, bfd_vma vma)
+{
+ struct _aarch64_elf_section_data *sec_data =
+ elf_aarch64_section_data (sec);
+ unsigned int newidx;
+
+ if (sec_data->map == NULL)
+ {
+ sec_data->map = bfd_malloc (sizeof (elf_aarch64_section_map));
+ sec_data->mapcount = 0;
+ sec_data->mapsize = 1;
+ }
+
+ newidx = sec_data->mapcount++;
+
+ if (sec_data->mapcount > sec_data->mapsize)
+ {
+ sec_data->mapsize *= 2;
+ sec_data->map = bfd_realloc_or_free
+ (sec_data->map, sec_data->mapsize * sizeof (elf_aarch64_section_map));
+ }
+
+ if (sec_data->map)
+ {
+ sec_data->map[newidx].vma = vma;
+ sec_data->map[newidx].type = type;
+ }
+}
+
+
+/* Initialise maps of insn/data for input BFDs. */
+void
+bfd_elfNN_aarch64_init_maps (bfd *abfd)
+{
+ Elf_Internal_Sym *isymbuf;
+ Elf_Internal_Shdr *hdr;
+ unsigned int i, localsyms;
+
+ /* Make sure that we are dealing with an AArch64 elf binary. */
+ if (!is_aarch64_elf (abfd))
+ return;
+
+ if ((abfd->flags & DYNAMIC) != 0)
+ return;
+
+ hdr = &elf_symtab_hdr (abfd);
+ localsyms = hdr->sh_info;
+
+ /* Obtain a buffer full of symbols for this BFD. The hdr->sh_info field
+ should contain the number of local symbols, which should come before any
+ global symbols. Mapping symbols are always local. */
+ isymbuf = bfd_elf_get_elf_syms (abfd, hdr, localsyms, 0, NULL, NULL, NULL);
+
+ /* No internal symbols read? Skip this BFD. */
+ if (isymbuf == NULL)
+ return;
+
+ for (i = 0; i < localsyms; i++)
+ {
+ Elf_Internal_Sym *isym = &isymbuf[i];
+ asection *sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
+ const char *name;
+
+ if (sec != NULL && ELF_ST_BIND (isym->st_info) == STB_LOCAL)
+ {
+ name = bfd_elf_string_from_elf_section (abfd,
+ hdr->sh_link,
+ isym->st_name);
+
+ if (bfd_is_aarch64_special_symbol_name
+ (name, BFD_AARCH64_SPECIAL_SYM_TYPE_MAP))
+ elfNN_aarch64_section_map_add (sec, name[1], isym->st_value);
+ }
+ }
+}
+
+/* Set option values needed during linking. */
+void
+bfd_elfNN_aarch64_set_options (struct bfd *output_bfd,
+ struct bfd_link_info *link_info,
+ int no_enum_warn,
+ int no_wchar_warn, int pic_veneer,
+ int fix_erratum_835769)
+{
+ struct elf_aarch64_link_hash_table *globals;
+
+ globals = elf_aarch64_hash_table (link_info);
+ globals->pic_veneer = pic_veneer;
+ globals->fix_erratum_835769 = fix_erratum_835769;
+
+ BFD_ASSERT (is_aarch64_elf (output_bfd));
+ elf_aarch64_tdata (output_bfd)->no_enum_size_warning = no_enum_warn;
+ elf_aarch64_tdata (output_bfd)->no_wchar_size_warning = no_wchar_warn;
+}
+
+static bfd_vma
+aarch64_calculate_got_entry_vma (struct elf_link_hash_entry *h,
+ struct elf_aarch64_link_hash_table
+ *globals, struct bfd_link_info *info,
+ bfd_vma value, bfd *output_bfd,
+ bfd_boolean *unresolved_reloc_p)
+{
+ bfd_vma off = (bfd_vma) - 1;
+ asection *basegot = globals->root.sgot;
+ bfd_boolean dyn = globals->root.dynamic_sections_created;
+
+ if (h != NULL)
+ {
+ BFD_ASSERT (basegot != NULL);
+ off = h->got.offset;
+ BFD_ASSERT (off != (bfd_vma) - 1);
+ if (!WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h)
+ || (info->shared
+ && SYMBOL_REFERENCES_LOCAL (info, h))
+ || (ELF_ST_VISIBILITY (h->other)
+ && h->root.type == bfd_link_hash_undefweak))
+ {
+ /* 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 8 (4 in the case of ILP32), we use
+ the least significant bit to record whether we have
+ initialized it already.
+ When doing a dynamic link, we create a .rel(a).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_NN (output_bfd, value, basegot->contents + off);
+ h->got.offset |= 1;
+ }
+ }
+ else
+ *unresolved_reloc_p = FALSE;
+
+ off = off + basegot->output_section->vma + basegot->output_offset;
+ }
+
+ return off;
+}
+
+/* Change R_TYPE to a more efficient access model where possible,
+ return the new reloc type. */
+
+static bfd_reloc_code_real_type
+aarch64_tls_transition_without_check (bfd_reloc_code_real_type r_type,
+ struct elf_link_hash_entry *h)
+{
+ bfd_boolean is_local = h == NULL;
+
+ switch (r_type)
+ {
+ case BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21:
+ case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21:
+ return (is_local
+ ? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1
+ : BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21);
+
+ case BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC:
+ case BFD_RELOC_AARCH64_TLSDESC_LDNN_LO12_NC:
+ return (is_local
+ ? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC
+ : BFD_RELOC_AARCH64_TLSIE_LDNN_GOTTPREL_LO12_NC);
+
+ case BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21:
+ return is_local ? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1 : r_type;
+
+ case BFD_RELOC_AARCH64_TLSIE_LDNN_GOTTPREL_LO12_NC:
+ return is_local ? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC : r_type;
+
+ case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12_NC:
+ case BFD_RELOC_AARCH64_TLSDESC_CALL:
+ /* Instructions with these relocations will become NOPs. */
+ return BFD_RELOC_AARCH64_NONE;
+
+ default:
+ break;
+ }
+
+ return r_type;
+}
+
+static unsigned int
+aarch64_reloc_got_type (bfd_reloc_code_real_type r_type)
+{
+ switch (r_type)
+ {
+ case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC:
+ case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC:
+ case BFD_RELOC_AARCH64_ADR_GOT_PAGE:
+ case BFD_RELOC_AARCH64_GOT_LD_PREL19:
+ return GOT_NORMAL;
+
+ case BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21:
+ case BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC:
+ return GOT_TLS_GD;
+
+ case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12_NC:
+ case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21:
+ case BFD_RELOC_AARCH64_TLSDESC_CALL:
+ case BFD_RELOC_AARCH64_TLSDESC_LD64_LO12_NC:
+ case BFD_RELOC_AARCH64_TLSDESC_LD32_LO12_NC:
+ return GOT_TLSDESC_GD;
+
+ case BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21:
+ case BFD_RELOC_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC:
+ case BFD_RELOC_AARCH64_TLSIE_LD32_GOTTPREL_LO12_NC:
+ return GOT_TLS_IE;
+
+ case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_HI12:
+ case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12:
+ case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12_NC:
+ case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0:
+ case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC:
+ case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1:
+ case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1_NC:
+ case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G2:
+ return GOT_UNKNOWN;
+
+ default:
+ break;
+ }
+ return GOT_UNKNOWN;
+}
+
+static bfd_boolean
+aarch64_can_relax_tls (bfd *input_bfd,
+ struct bfd_link_info *info,
+ bfd_reloc_code_real_type r_type,
+ struct elf_link_hash_entry *h,
+ unsigned long r_symndx)
+{
+ unsigned int symbol_got_type;
+ unsigned int reloc_got_type;
+
+ if (! IS_AARCH64_TLS_RELOC (r_type))
+ return FALSE;
+
+ symbol_got_type = elfNN_aarch64_symbol_got_type (h, input_bfd, r_symndx);
+ reloc_got_type = aarch64_reloc_got_type (r_type);
+
+ if (symbol_got_type == GOT_TLS_IE && GOT_TLS_GD_ANY_P (reloc_got_type))
+ return TRUE;
+
+ if (info->shared)
+ return FALSE;
+
+ if (h && h->root.type == bfd_link_hash_undefweak)
+ return FALSE;
+
+ return TRUE;
+}
+
+/* Given the relocation code R_TYPE, return the relaxed bfd reloc
+ enumerator. */
+
+static bfd_reloc_code_real_type
+aarch64_tls_transition (bfd *input_bfd,
+ struct bfd_link_info *info,
+ unsigned int r_type,
+ struct elf_link_hash_entry *h,
+ unsigned long r_symndx)
+{
+ bfd_reloc_code_real_type bfd_r_type
+ = elfNN_aarch64_bfd_reloc_from_type (r_type);
+
+ if (! aarch64_can_relax_tls (input_bfd, info, bfd_r_type, h, r_symndx))
+ return bfd_r_type;
+
+ return aarch64_tls_transition_without_check (bfd_r_type, h);
+}
+
+/* Return the base VMA address which should be subtracted from real addresses
+ when resolving R_AARCH64_TLS_DTPREL relocation. */
+
+static bfd_vma
+dtpoff_base (struct bfd_link_info *info)
+{
+ /* If tls_sec is NULL, we should have signalled an error already. */
+ BFD_ASSERT (elf_hash_table (info)->tls_sec != NULL);
+ return elf_hash_table (info)->tls_sec->vma;
+}
+
+/* Return the base VMA address which should be subtracted from real addresses
+ when resolving R_AARCH64_TLS_GOTTPREL64 relocations. */
+
+static bfd_vma
+tpoff_base (struct bfd_link_info *info)
+{
+ struct elf_link_hash_table *htab = elf_hash_table (info);
+
+ /* If tls_sec is NULL, we should have signalled an error already. */
+ BFD_ASSERT (htab->tls_sec != NULL);
+
+ bfd_vma base = align_power ((bfd_vma) TCB_SIZE,
+ htab->tls_sec->alignment_power);
+ return htab->tls_sec->vma - base;
+}
+
+static bfd_vma *
+symbol_got_offset_ref (bfd *input_bfd, struct elf_link_hash_entry *h,
+ unsigned long r_symndx)
+{
+ /* Calculate the address of the GOT entry for symbol
+ referred to in h. */
+ if (h != NULL)
+ return &h->got.offset;
+ else
+ {
+ /* local symbol */
+ struct elf_aarch64_local_symbol *l;
+
+ l = elf_aarch64_locals (input_bfd);
+ return &l[r_symndx].got_offset;
+ }
+}
+
+static void
+symbol_got_offset_mark (bfd *input_bfd, struct elf_link_hash_entry *h,
+ unsigned long r_symndx)
+{
+ bfd_vma *p;
+ p = symbol_got_offset_ref (input_bfd, h, r_symndx);
+ *p |= 1;
+}
+
+static int
+symbol_got_offset_mark_p (bfd *input_bfd, struct elf_link_hash_entry *h,
+ unsigned long r_symndx)
+{
+ bfd_vma value;
+ value = * symbol_got_offset_ref (input_bfd, h, r_symndx);
+ return value & 1;
+}
+
+static bfd_vma
+symbol_got_offset (bfd *input_bfd, struct elf_link_hash_entry *h,
+ unsigned long r_symndx)
+{
+ bfd_vma value;
+ value = * symbol_got_offset_ref (input_bfd, h, r_symndx);
+ value &= ~1;
+ return value;
+}
+
+static bfd_vma *
+symbol_tlsdesc_got_offset_ref (bfd *input_bfd, struct elf_link_hash_entry *h,
+ unsigned long r_symndx)
+{
+ /* Calculate the address of the GOT entry for symbol
+ referred to in h. */
+ if (h != NULL)
+ {
+ struct elf_aarch64_link_hash_entry *eh;
+ eh = (struct elf_aarch64_link_hash_entry *) h;
+ return &eh->tlsdesc_got_jump_table_offset;
+ }
+ else
+ {
+ /* local symbol */
+ struct elf_aarch64_local_symbol *l;
+
+ l = elf_aarch64_locals (input_bfd);
+ return &l[r_symndx].tlsdesc_got_jump_table_offset;
+ }
+}
+
+static void
+symbol_tlsdesc_got_offset_mark (bfd *input_bfd, struct elf_link_hash_entry *h,
+ unsigned long r_symndx)
+{
+ bfd_vma *p;
+ p = symbol_tlsdesc_got_offset_ref (input_bfd, h, r_symndx);
+ *p |= 1;
+}
+
+static int
+symbol_tlsdesc_got_offset_mark_p (bfd *input_bfd,
+ struct elf_link_hash_entry *h,
+ unsigned long r_symndx)
+{
+ bfd_vma value;
+ value = * symbol_tlsdesc_got_offset_ref (input_bfd, h, r_symndx);
+ return value & 1;
+}
+
+static bfd_vma
+symbol_tlsdesc_got_offset (bfd *input_bfd, struct elf_link_hash_entry *h,
+ unsigned long r_symndx)
+{
+ bfd_vma value;
+ value = * symbol_tlsdesc_got_offset_ref (input_bfd, h, r_symndx);
+ value &= ~1;
+ return value;
+}
+
+/* Data for make_branch_to_erratum_835769_stub(). */
+
+struct erratum_835769_branch_to_stub_data
+{
+ asection *output_section;
+ bfd_byte *contents;
+};
+
+/* Helper to insert branches to erratum 835769 stubs in the right
+ places for a particular section. */
+
+static bfd_boolean
+make_branch_to_erratum_835769_stub (struct bfd_hash_entry *gen_entry,
+ void *in_arg)
+{
+ struct elf_aarch64_stub_hash_entry *stub_entry;
+ struct erratum_835769_branch_to_stub_data *data;
+ bfd_byte *contents;
+ unsigned long branch_insn = 0;
+ bfd_vma veneered_insn_loc, veneer_entry_loc;
+ bfd_signed_vma branch_offset;
+ unsigned int target;
+ bfd *abfd;
+
+ stub_entry = (struct elf_aarch64_stub_hash_entry *) gen_entry;
+ data = (struct erratum_835769_branch_to_stub_data *) in_arg;
+
+ if (stub_entry->target_section != data->output_section
+ || stub_entry->stub_type != aarch64_stub_erratum_835769_veneer)
+ return TRUE;
+
+ contents = data->contents;
+ veneered_insn_loc = stub_entry->target_section->output_section->vma
+ + stub_entry->target_section->output_offset
+ + stub_entry->target_value;
+ veneer_entry_loc = stub_entry->stub_sec->output_section->vma
+ + stub_entry->stub_sec->output_offset
+ + stub_entry->stub_offset;
+ branch_offset = veneer_entry_loc - veneered_insn_loc;
+
+ abfd = stub_entry->target_section->owner;
+ if (!aarch64_valid_branch_p (veneer_entry_loc, veneered_insn_loc))
+ (*_bfd_error_handler)
+ (_("%B: error: Erratum 835769 stub out "
+ "of range (input file too large)"), abfd);
+
+ target = stub_entry->target_value;
+ branch_insn = 0x14000000;
+ branch_offset >>= 2;
+ branch_offset &= 0x3ffffff;
+ branch_insn |= branch_offset;
+ bfd_putl32 (branch_insn, &contents[target]);
+
+ return TRUE;
+}
+
+static bfd_boolean
+elfNN_aarch64_write_section (bfd *output_bfd ATTRIBUTE_UNUSED,
+ struct bfd_link_info *link_info,
+ asection *sec,
+ bfd_byte *contents)
+
+{
+ struct elf_aarch64_link_hash_table *globals =
+ elf_aarch64_hash_table (link_info);
+
+ if (globals == NULL)
+ return FALSE;
+
+ /* Fix code to point to erratum 835769 stubs. */
+ if (globals->fix_erratum_835769)
+ {
+ struct erratum_835769_branch_to_stub_data data;
+
+ data.output_section = sec;
+ data.contents = contents;
+ bfd_hash_traverse (&globals->stub_hash_table,
+ make_branch_to_erratum_835769_stub, &data);
+ }
+
+ return FALSE;
+}
+
+/* Perform a relocation as part of a final link. */
+static bfd_reloc_status_type
+elfNN_aarch64_final_link_relocate (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,
+ struct elf_link_hash_entry *h,
+ bfd_boolean *unresolved_reloc_p,
+ bfd_boolean save_addend,
+ bfd_vma *saved_addend,
+ Elf_Internal_Sym *sym)
+{
+ Elf_Internal_Shdr *symtab_hdr;
+ unsigned int r_type = howto->type;
+ bfd_reloc_code_real_type bfd_r_type
+ = elfNN_aarch64_bfd_reloc_from_howto (howto);
+ bfd_reloc_code_real_type new_bfd_r_type;
+ unsigned long r_symndx;
+ bfd_byte *hit_data = contents + rel->r_offset;
+ bfd_vma place;
+ bfd_signed_vma signed_addend;
+ struct elf_aarch64_link_hash_table *globals;
+ bfd_boolean weak_undef_p;
+
+ globals = elf_aarch64_hash_table (info);
+
+ symtab_hdr = &elf_symtab_hdr (input_bfd);
+
+ BFD_ASSERT (is_aarch64_elf (input_bfd));
+
+ r_symndx = ELFNN_R_SYM (rel->r_info);
+
+ /* It is possible to have linker relaxations on some TLS access
+ models. Update our information here. */
+ new_bfd_r_type = aarch64_tls_transition (input_bfd, info, r_type, h, r_symndx);
+ if (new_bfd_r_type != bfd_r_type)
+ {
+ bfd_r_type = new_bfd_r_type;
+ howto = elfNN_aarch64_howto_from_bfd_reloc (bfd_r_type);
+ BFD_ASSERT (howto != NULL);
+ r_type = howto->type;
+ }
+
+ place = input_section->output_section->vma
+ + input_section->output_offset + rel->r_offset;
+
+ /* Get addend, accumulating the addend for consecutive relocs
+ which refer to the same offset. */
+ signed_addend = saved_addend ? *saved_addend : 0;
+ signed_addend += rel->r_addend;
+
+ weak_undef_p = (h ? h->root.type == bfd_link_hash_undefweak
+ : bfd_is_und_section (sym_sec));
+
+ /* Since STT_GNU_IFUNC symbol must go through PLT, we handle
+ it here if it is defined in a non-shared object. */
+ if (h != NULL
+ && h->type == STT_GNU_IFUNC
+ && h->def_regular)
+ {
+ asection *plt;
+ const char *name;
+ asection *base_got;
+ bfd_vma off;
+
+ if ((input_section->flags & SEC_ALLOC) == 0
+ || h->plt.offset == (bfd_vma) -1)
+ abort ();
+
+ /* STT_GNU_IFUNC symbol must go through PLT. */
+ plt = globals->root.splt ? globals->root.splt : globals->root.iplt;
+ value = (plt->output_section->vma + plt->output_offset + h->plt.offset);
+
+ switch (bfd_r_type)
+ {
+ default:
+ if (h->root.root.string)
+ name = h->root.root.string;
+ else
+ name = bfd_elf_sym_name (input_bfd, symtab_hdr, sym,
+ NULL);
+ (*_bfd_error_handler)
+ (_("%B: relocation %s against STT_GNU_IFUNC "
+ "symbol `%s' isn't handled by %s"), input_bfd,
+ howto->name, name, __FUNCTION__);
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+
+ case BFD_RELOC_AARCH64_NN:
+ if (rel->r_addend != 0)
+ {
+ if (h->root.root.string)
+ name = h->root.root.string;
+ else
+ name = bfd_elf_sym_name (input_bfd, symtab_hdr,
+ sym, NULL);
+ (*_bfd_error_handler)
+ (_("%B: relocation %s against STT_GNU_IFUNC "
+ "symbol `%s' has non-zero addend: %d"),
+ input_bfd, howto->name, name, rel->r_addend);
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+
+ /* Generate dynamic relocation only when there is a
+ non-GOT reference in a shared object. */
+ if (info->shared && h->non_got_ref)
+ {
+ Elf_Internal_Rela outrel;
+ asection *sreloc;
+
+ /* Need a dynamic relocation to get the real function
+ address. */
+ outrel.r_offset = _bfd_elf_section_offset (output_bfd,
+ info,
+ input_section,
+ rel->r_offset);
+ if (outrel.r_offset == (bfd_vma) -1
+ || outrel.r_offset == (bfd_vma) -2)
+ abort ();
+
+ outrel.r_offset += (input_section->output_section->vma
+ + input_section->output_offset);
+
+ if (h->dynindx == -1
+ || h->forced_local
+ || info->executable)
+ {
+ /* This symbol is resolved locally. */
+ outrel.r_info = ELFNN_R_INFO (0, AARCH64_R (IRELATIVE));
+ outrel.r_addend = (h->root.u.def.value
+ + h->root.u.def.section->output_section->vma
+ + h->root.u.def.section->output_offset);
+ }
+ else
+ {
+ outrel.r_info = ELFNN_R_INFO (h->dynindx, r_type);
+ outrel.r_addend = 0;
+ }
+
+ sreloc = globals->root.irelifunc;
+ elf_append_rela (output_bfd, sreloc, &outrel);
+
+ /* 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. For an
+ internal symbol, we have updated addend. */
+ return bfd_reloc_ok;
+ }
+ /* FALLTHROUGH */
+ case BFD_RELOC_AARCH64_JUMP26:
+ case BFD_RELOC_AARCH64_CALL26:
+ value = _bfd_aarch64_elf_resolve_relocation (bfd_r_type, place, value,
+ signed_addend,
+ weak_undef_p);
+ return _bfd_aarch64_elf_put_addend (input_bfd, hit_data, bfd_r_type,
+ howto, value);
+ case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC:
+ case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC:
+ case BFD_RELOC_AARCH64_ADR_GOT_PAGE:
+ case BFD_RELOC_AARCH64_GOT_LD_PREL19:
+ base_got = globals->root.sgot;
+ off = h->got.offset;
+
+ if (base_got == NULL)
+ abort ();
+
+ if (off == (bfd_vma) -1)
+ {
+ bfd_vma plt_index;
+
+ /* We can't use h->got.offset here to save state, or
+ even just remember the offset, as finish_dynamic_symbol
+ would use that as offset into .got. */
+
+ if (globals->root.splt != NULL)
+ {
+ plt_index = ((h->plt.offset - globals->plt_header_size) /
+ globals->plt_entry_size);
+ off = (plt_index + 3) * GOT_ENTRY_SIZE;
+ base_got = globals->root.sgotplt;
+ }
+ else
+ {
+ plt_index = h->plt.offset / globals->plt_entry_size;
+ off = plt_index * GOT_ENTRY_SIZE;
+ base_got = globals->root.igotplt;
+ }
+
+ if (h->dynindx == -1
+ || h->forced_local
+ || info->symbolic)
+ {
+ /* This references the local definition. 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_NN (output_bfd, value,
+ base_got->contents + off);
+ /* Note that this is harmless as -1 | 1 still is -1. */
+ h->got.offset |= 1;
+ }
+ }
+ value = (base_got->output_section->vma
+ + base_got->output_offset + off);
+ }
+ else
+ value = aarch64_calculate_got_entry_vma (h, globals, info,
+ value, output_bfd,
+ unresolved_reloc_p);
+ value = _bfd_aarch64_elf_resolve_relocation (bfd_r_type, place, value,
+ 0, weak_undef_p);
+ return _bfd_aarch64_elf_put_addend (input_bfd, hit_data, bfd_r_type, howto, value);
+ case BFD_RELOC_AARCH64_ADR_HI21_PCREL:
+ case BFD_RELOC_AARCH64_ADD_LO12:
+ break;
+ }
+ }
+
+ switch (bfd_r_type)
+ {
+ case BFD_RELOC_AARCH64_NONE:
+ case BFD_RELOC_AARCH64_TLSDESC_CALL:
+ *unresolved_reloc_p = FALSE;
+ return bfd_reloc_ok;
+
+ case BFD_RELOC_AARCH64_NN:
+
+ /* When generating a shared object or relocatable executable, these
+ relocations are copied into the output file to be resolved at
+ run time. */
+ if (((info->shared == TRUE) || globals->root.is_relocatable_executable)
+ && (input_section->flags & SEC_ALLOC)
+ && (h == NULL
+ || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
+ || h->root.type != bfd_link_hash_undefweak))
+ {
+ Elf_Internal_Rela outrel;
+ bfd_byte *loc;
+ bfd_boolean skip, relocate;
+ asection *sreloc;
+
+ *unresolved_reloc_p = FALSE;
+
+ skip = FALSE;
+ relocate = FALSE;
+
+ outrel.r_addend = signed_addend;
+ outrel.r_offset =
+ _bfd_elf_section_offset (output_bfd, info, input_section,
+ rel->r_offset);
+ if (outrel.r_offset == (bfd_vma) - 1)
+ skip = TRUE;
+ else if (outrel.r_offset == (bfd_vma) - 2)
+ {
+ skip = TRUE;
+ relocate = TRUE;
+ }
+
+ outrel.r_offset += (input_section->output_section->vma
+ + input_section->output_offset);
+
+ if (skip)
+ memset (&outrel, 0, sizeof outrel);
+ else if (h != NULL
+ && h->dynindx != -1
+ && (!info->shared || !info->symbolic || !h->def_regular))
+ outrel.r_info = ELFNN_R_INFO (h->dynindx, r_type);
+ else
+ {
+ int symbol;
+
+ /* On SVR4-ish systems, the dynamic loader cannot
+ relocate the text and data segments independently,
+ so the symbol does not matter. */
+ symbol = 0;
+ outrel.r_info = ELFNN_R_INFO (symbol, AARCH64_R (RELATIVE));
+ outrel.r_addend += value;
+ }
+
+ sreloc = elf_section_data (input_section)->sreloc;
+ if (sreloc == NULL || sreloc->contents == NULL)
+ return bfd_reloc_notsupported;
+
+ loc = sreloc->contents + sreloc->reloc_count++ * RELOC_SIZE (globals);
+ bfd_elfNN_swap_reloca_out (output_bfd, &outrel, loc);
+
+ if (sreloc->reloc_count * RELOC_SIZE (globals) > sreloc->size)
+ {
+ /* Sanity to check that we have previously allocated
+ sufficient space in the relocation section for the
+ number of relocations we actually want to emit. */
+ abort ();
+ }
+
+ /* 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,
+ signed_addend);
+ }
+ else
+ value += signed_addend;
+ break;
+
+ case BFD_RELOC_AARCH64_JUMP26:
+ case BFD_RELOC_AARCH64_CALL26:
+ {
+ asection *splt = globals->root.splt;
+ bfd_boolean via_plt_p =
+ splt != NULL && h != NULL && h->plt.offset != (bfd_vma) - 1;
+
+ /* A call to an undefined weak symbol is converted to a jump to
+ the next instruction unless a PLT entry will be created.
+ The jump to the next instruction is optimized as a NOP.
+ Do the same for local undefined symbols. */
+ if (weak_undef_p && ! via_plt_p)
+ {
+ bfd_putl32 (INSN_NOP, hit_data);
+ return bfd_reloc_ok;
+ }
+
+ /* If the call goes through a PLT entry, make sure to
+ check distance to the right destination address. */
+ if (via_plt_p)
+ {
+ value = (splt->output_section->vma
+ + splt->output_offset + h->plt.offset);
+ *unresolved_reloc_p = FALSE;
+ }
+
+ /* If the target symbol is global and marked as a function the
+ relocation applies a function call or a tail call. In this
+ situation we can veneer out of range branches. The veneers
+ use IP0 and IP1 hence cannot be used arbitrary out of range
+ branches that occur within the body of a function. */
+ if (h && h->type == STT_FUNC)
+ {
+ /* Check if a stub has to be inserted because the destination
+ is too far away. */
+ if (! aarch64_valid_branch_p (value, place))
+ {
+ /* The target is out of reach, so redirect the branch to
+ the local stub for this function. */
+ struct elf_aarch64_stub_hash_entry *stub_entry;
+ stub_entry = elfNN_aarch64_get_stub_entry (input_section,
+ sym_sec, h,
+ rel, globals);
+ if (stub_entry != NULL)
+ value = (stub_entry->stub_offset
+ + stub_entry->stub_sec->output_offset
+ + stub_entry->stub_sec->output_section->vma);
+ }
+ }
+ }
+ value = _bfd_aarch64_elf_resolve_relocation (bfd_r_type, place, value,
+ signed_addend, weak_undef_p);
+ break;
+
+ case BFD_RELOC_AARCH64_16:
+#if ARCH_SIZE == 64
+ case BFD_RELOC_AARCH64_32:
+#endif
+ case BFD_RELOC_AARCH64_ADD_LO12:
+ case BFD_RELOC_AARCH64_ADR_LO21_PCREL:
+ case BFD_RELOC_AARCH64_ADR_HI21_PCREL:
+ case BFD_RELOC_AARCH64_ADR_HI21_NC_PCREL:
+ case BFD_RELOC_AARCH64_BRANCH19:
+ case BFD_RELOC_AARCH64_LD_LO19_PCREL:
+ case BFD_RELOC_AARCH64_LDST8_LO12:
+ case BFD_RELOC_AARCH64_LDST16_LO12:
+ case BFD_RELOC_AARCH64_LDST32_LO12:
+ case BFD_RELOC_AARCH64_LDST64_LO12:
+ case BFD_RELOC_AARCH64_LDST128_LO12:
+ case BFD_RELOC_AARCH64_MOVW_G0_S:
+ case BFD_RELOC_AARCH64_MOVW_G1_S:
+ case BFD_RELOC_AARCH64_MOVW_G2_S:
+ case BFD_RELOC_AARCH64_MOVW_G0:
+ case BFD_RELOC_AARCH64_MOVW_G0_NC:
+ case BFD_RELOC_AARCH64_MOVW_G1:
+ case BFD_RELOC_AARCH64_MOVW_G1_NC:
+ case BFD_RELOC_AARCH64_MOVW_G2:
+ case BFD_RELOC_AARCH64_MOVW_G2_NC:
+ case BFD_RELOC_AARCH64_MOVW_G3:
+ case BFD_RELOC_AARCH64_16_PCREL:
+ case BFD_RELOC_AARCH64_32_PCREL:
+ case BFD_RELOC_AARCH64_64_PCREL:
+ case BFD_RELOC_AARCH64_TSTBR14:
+ value = _bfd_aarch64_elf_resolve_relocation (bfd_r_type, place, value,
+ signed_addend, weak_undef_p);
+ break;
+
+ case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC:
+ case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC:
+ case BFD_RELOC_AARCH64_ADR_GOT_PAGE:
+ case BFD_RELOC_AARCH64_GOT_LD_PREL19:
+ if (globals->root.sgot == NULL)
+ BFD_ASSERT (h != NULL);
+
+ if (h != NULL)
+ {
+ value = aarch64_calculate_got_entry_vma (h, globals, info, value,
+ output_bfd,
+ unresolved_reloc_p);
+ value = _bfd_aarch64_elf_resolve_relocation (bfd_r_type, place, value,
+ 0, weak_undef_p);
+ }
+ break;
+
+ case BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21:
+ case BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC:
+ case BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21:
+ case BFD_RELOC_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC:
+ case BFD_RELOC_AARCH64_TLSIE_LD32_GOTTPREL_LO12_NC:
+ if (globals->root.sgot == NULL)
+ return bfd_reloc_notsupported;
+
+ value = (symbol_got_offset (input_bfd, h, r_symndx)
+ + globals->root.sgot->output_section->vma
+ + globals->root.sgot->output_offset);
+
+ value = _bfd_aarch64_elf_resolve_relocation (bfd_r_type, place, value,
+ 0, weak_undef_p);
+ *unresolved_reloc_p = FALSE;
+ break;
+
+ case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_HI12:
+ case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12:
+ case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12_NC:
+ case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0:
+ case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC:
+ case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1:
+ case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1_NC:
+ case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G2:
+ value = _bfd_aarch64_elf_resolve_relocation (bfd_r_type, place, value,
+ signed_addend - tpoff_base (info),
+ weak_undef_p);
+ *unresolved_reloc_p = FALSE;
+ break;
+
+ case BFD_RELOC_AARCH64_TLSDESC_ADD:
+ case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12_NC:
+ case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21:
+ case BFD_RELOC_AARCH64_TLSDESC_LD32_LO12_NC:
+ case BFD_RELOC_AARCH64_TLSDESC_LD64_LO12_NC:
+ case BFD_RELOC_AARCH64_TLSDESC_LDR:
+ if (globals->root.sgot == NULL)
+ return bfd_reloc_notsupported;
+ value = (symbol_tlsdesc_got_offset (input_bfd, h, r_symndx)
+ + globals->root.sgotplt->output_section->vma
+ + globals->root.sgotplt->output_offset
+ + globals->sgotplt_jump_table_size);
+
+ value = _bfd_aarch64_elf_resolve_relocation (bfd_r_type, place, value,
+ 0, weak_undef_p);
+ *unresolved_reloc_p = FALSE;
+ break;
+
+ default:
+ return bfd_reloc_notsupported;
+ }
+
+ if (saved_addend)
+ *saved_addend = value;
+
+ /* Only apply the final relocation in a sequence. */
+ if (save_addend)
+ return bfd_reloc_continue;
+
+ return _bfd_aarch64_elf_put_addend (input_bfd, hit_data, bfd_r_type,
+ howto, value);
+}
+
+/* Handle TLS relaxations. Relaxing is possible for symbols that use
+ R_AARCH64_TLSDESC_ADR_{PAGE, LD64_LO12_NC, ADD_LO12_NC} during a static
+ link.
+
+ Return bfd_reloc_ok if we're done, bfd_reloc_continue if the caller
+ is to then call final_link_relocate. Return other values in the
+ case of error. */
+
+static bfd_reloc_status_type
+elfNN_aarch64_tls_relax (struct elf_aarch64_link_hash_table *globals,
+ bfd *input_bfd, bfd_byte *contents,
+ Elf_Internal_Rela *rel, struct elf_link_hash_entry *h)
+{
+ bfd_boolean is_local = h == NULL;
+ unsigned int r_type = ELFNN_R_TYPE (rel->r_info);
+ unsigned long insn;
+
+ BFD_ASSERT (globals && input_bfd && contents && rel);
+
+ switch (elfNN_aarch64_bfd_reloc_from_type (r_type))
+ {
+ case BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21:
+ case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21:
+ if (is_local)
+ {
+ /* GD->LE relaxation:
+ adrp x0, :tlsgd:var => movz x0, :tprel_g1:var
+ or
+ adrp x0, :tlsdesc:var => movz x0, :tprel_g1:var
+ */
+ bfd_putl32 (0xd2a00000, contents + rel->r_offset);
+ return bfd_reloc_continue;
+ }
+ else
+ {
+ /* GD->IE relaxation:
+ adrp x0, :tlsgd:var => adrp x0, :gottprel:var
+ or
+ adrp x0, :tlsdesc:var => adrp x0, :gottprel:var
+ */
+ return bfd_reloc_continue;
+ }
+
+ case BFD_RELOC_AARCH64_TLSDESC_LDNN_LO12_NC:
+ if (is_local)
+ {
+ /* GD->LE relaxation:
+ ldr xd, [x0, #:tlsdesc_lo12:var] => movk x0, :tprel_g0_nc:var
+ */
+ bfd_putl32 (0xf2800000, contents + rel->r_offset);
+ return bfd_reloc_continue;
+ }
+ else
+ {
+ /* GD->IE relaxation:
+ ldr xd, [x0, #:tlsdesc_lo12:var] => ldr x0, [x0, #:gottprel_lo12:var]
+ */
+ insn = bfd_getl32 (contents + rel->r_offset);
+ insn &= 0xffffffe0;
+ bfd_putl32 (insn, contents + rel->r_offset);
+ return bfd_reloc_continue;
+ }
+
+ case BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC:
+ if (is_local)
+ {
+ /* GD->LE relaxation
+ add x0, #:tlsgd_lo12:var => movk x0, :tprel_g0_nc:var
+ bl __tls_get_addr => mrs x1, tpidr_el0
+ nop => add x0, x1, x0
+ */
+
+ /* First kill the tls_get_addr reloc on the bl instruction. */
+ BFD_ASSERT (rel->r_offset + 4 == rel[1].r_offset);
+ rel[1].r_info = ELFNN_R_INFO (STN_UNDEF, R_AARCH64_NONE);
+
+ bfd_putl32 (0xf2800000, contents + rel->r_offset);
+ bfd_putl32 (0xd53bd041, contents + rel->r_offset + 4);
+ bfd_putl32 (0x8b000020, contents + rel->r_offset + 8);
+ return bfd_reloc_continue;
+ }
+ else
+ {
+ /* GD->IE relaxation
+ ADD x0, #:tlsgd_lo12:var => ldr x0, [x0, #:gottprel_lo12:var]
+ BL __tls_get_addr => mrs x1, tpidr_el0
+ R_AARCH64_CALL26
+ NOP => add x0, x1, x0
+ */
+
+ BFD_ASSERT (ELFNN_R_TYPE (rel[1].r_info) == AARCH64_R (CALL26));
+
+ /* Remove the relocation on the BL instruction. */
+ rel[1].r_info = ELFNN_R_INFO (STN_UNDEF, R_AARCH64_NONE);
+
+ bfd_putl32 (0xf9400000, contents + rel->r_offset);
+
+ /* We choose to fixup the BL and NOP instructions using the
+ offset from the second relocation to allow flexibility in
+ scheduling instructions between the ADD and BL. */
+ bfd_putl32 (0xd53bd041, contents + rel[1].r_offset);
+ bfd_putl32 (0x8b000020, contents + rel[1].r_offset + 4);
+ return bfd_reloc_continue;
+ }
+
+ case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12_NC:
+ case BFD_RELOC_AARCH64_TLSDESC_CALL:
+ /* GD->IE/LE relaxation:
+ add x0, x0, #:tlsdesc_lo12:var => nop
+ blr xd => nop
+ */
+ bfd_putl32 (INSN_NOP, contents + rel->r_offset);
+ return bfd_reloc_ok;
+
+ case BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21:
+ /* IE->LE relaxation:
+ adrp xd, :gottprel:var => movz xd, :tprel_g1:var
+ */
+ if (is_local)
+ {
+ insn = bfd_getl32 (contents + rel->r_offset);
+ bfd_putl32 (0xd2a00000 | (insn & 0x1f), contents + rel->r_offset);
+ }
+ return bfd_reloc_continue;
+
+ case BFD_RELOC_AARCH64_TLSIE_LDNN_GOTTPREL_LO12_NC:
+ /* IE->LE relaxation:
+ ldr xd, [xm, #:gottprel_lo12:var] => movk xd, :tprel_g0_nc:var
+ */
+ if (is_local)
+ {
+ insn = bfd_getl32 (contents + rel->r_offset);
+ bfd_putl32 (0xf2800000 | (insn & 0x1f), contents + rel->r_offset);
+ }
+ return bfd_reloc_continue;
+
+ default:
+ return bfd_reloc_continue;
+ }
+
+ return bfd_reloc_ok;
+}
+
+/* Relocate an AArch64 ELF section. */
+
+static bfd_boolean
+elfNN_aarch64_relocate_section (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;
+ struct elf_aarch64_link_hash_table *globals;
+ bfd_boolean save_addend = FALSE;
+ bfd_vma addend = 0;
+
+ globals = elf_aarch64_hash_table (info);
+
+ symtab_hdr = &elf_symtab_hdr (input_bfd);
+ sym_hashes = elf_sym_hashes (input_bfd);
+
+ rel = relocs;
+ relend = relocs + input_section->reloc_count;
+ for (; rel < relend; rel++)
+ {
+ unsigned int r_type;
+ bfd_reloc_code_real_type bfd_r_type;
+ bfd_reloc_code_real_type relaxed_bfd_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;
+ arelent bfd_reloc;
+ char sym_type;
+ bfd_boolean unresolved_reloc = FALSE;
+ char *error_message = NULL;
+
+ r_symndx = ELFNN_R_SYM (rel->r_info);
+ r_type = ELFNN_R_TYPE (rel->r_info);
+
+ bfd_reloc.howto = elfNN_aarch64_howto_from_type (r_type);
+ howto = bfd_reloc.howto;
+
+ if (howto == NULL)
+ {
+ (*_bfd_error_handler)
+ (_("%B: unrecognized relocation (0x%x) in section `%A'"),
+ input_bfd, input_section, r_type);
+ return FALSE;
+ }
+ bfd_r_type = elfNN_aarch64_bfd_reloc_from_howto (howto);
+
+ h = NULL;
+ sym = NULL;
+ sec = NULL;
+
+ if (r_symndx < symtab_hdr->sh_info)
+ {
+ sym = local_syms + r_symndx;
+ sym_type = ELFNN_ST_TYPE (sym->st_info);
+ sec = local_sections[r_symndx];
+
+ /* An object file might have a reference to a local
+ undefined symbol. This is a daft object file, but we
+ should at least do something about it. */
+ if (r_type != R_AARCH64_NONE && r_type != R_AARCH64_NULL
+ && bfd_is_und_section (sec)
+ && ELF_ST_BIND (sym->st_info) != STB_WEAK)
+ {
+ if (!info->callbacks->undefined_symbol
+ (info, bfd_elf_string_from_elf_section
+ (input_bfd, symtab_hdr->sh_link, sym->st_name),
+ input_bfd, input_section, rel->r_offset, TRUE))
+ return FALSE;
+ }
+
+ relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
+
+ /* Relocate against local STT_GNU_IFUNC symbol. */
+ if (!info->relocatable
+ && ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC)
+ {
+ h = elfNN_aarch64_get_local_sym_hash (globals, input_bfd,
+ rel, FALSE);
+ if (h == NULL)
+ abort ();
+
+ /* Set STT_GNU_IFUNC symbol value. */
+ h->root.u.def.value = sym->st_value;
+ h->root.u.def.section = sec;
+ }
+ }
+ else
+ {
+ bfd_boolean warned, ignored;
+
+ RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
+ r_symndx, symtab_hdr, sym_hashes,
+ h, sec, relocation,
+ unresolved_reloc, warned, ignored);
+
+ sym_type = h->type;
+ }
+
+ if (sec != NULL && discarded_section (sec))
+ RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+ rel, 1, relend, howto, 0, contents);
+
+ if (info->relocatable)
+ continue;
+
+ 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 (r_symndx != 0
+ && r_type != R_AARCH64_NONE
+ && r_type != R_AARCH64_NULL
+ && (h == NULL
+ || h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak)
+ && IS_AARCH64_TLS_RELOC (bfd_r_type) != (sym_type == STT_TLS))
+ {
+ (*_bfd_error_handler)
+ ((sym_type == STT_TLS
+ ? _("%B(%A+0x%lx): %s used with TLS symbol %s")
+ : _("%B(%A+0x%lx): %s used with non-TLS symbol %s")),
+ input_bfd,
+ input_section, (long) rel->r_offset, howto->name, name);
+ }
+
+ /* We relax only if we can see that there can be a valid transition
+ from a reloc type to another.
+ We call elfNN_aarch64_final_link_relocate unless we're completely
+ done, i.e., the relaxation produced the final output we want. */
+
+ relaxed_bfd_r_type = aarch64_tls_transition (input_bfd, info, r_type,
+ h, r_symndx);
+ if (relaxed_bfd_r_type != bfd_r_type)
+ {
+ bfd_r_type = relaxed_bfd_r_type;
+ howto = elfNN_aarch64_howto_from_bfd_reloc (bfd_r_type);
+ BFD_ASSERT (howto != NULL);
+ r_type = howto->type;
+ r = elfNN_aarch64_tls_relax (globals, input_bfd, contents, rel, h);
+ unresolved_reloc = 0;
+ }
+ else
+ r = bfd_reloc_continue;
+
+ /* There may be multiple consecutive relocations for the
+ same offset. In that case we are supposed to treat the
+ output of each relocation as the addend for the next. */
+ if (rel + 1 < relend
+ && rel->r_offset == rel[1].r_offset
+ && ELFNN_R_TYPE (rel[1].r_info) != R_AARCH64_NONE
+ && ELFNN_R_TYPE (rel[1].r_info) != R_AARCH64_NULL)
+ save_addend = TRUE;
+ else
+ save_addend = FALSE;
+
+ if (r == bfd_reloc_continue)
+ r = elfNN_aarch64_final_link_relocate (howto, input_bfd, output_bfd,
+ input_section, contents, rel,
+ relocation, info, sec,
+ h, &unresolved_reloc,
+ save_addend, &addend, sym);
+
+ switch (elfNN_aarch64_bfd_reloc_from_type (r_type))
+ {
+ case BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21:
+ case BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC:
+ if (! symbol_got_offset_mark_p (input_bfd, h, r_symndx))
+ {
+ bfd_boolean need_relocs = FALSE;
+ bfd_byte *loc;
+ int indx;
+ bfd_vma off;
+
+ off = symbol_got_offset (input_bfd, h, r_symndx);
+ indx = h && h->dynindx != -1 ? h->dynindx : 0;
+
+ need_relocs =
+ (info->shared || indx != 0) &&
+ (h == NULL
+ || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
+ || h->root.type != bfd_link_hash_undefweak);
+
+ BFD_ASSERT (globals->root.srelgot != NULL);
+
+ if (need_relocs)
+ {
+ Elf_Internal_Rela rela;
+ rela.r_info = ELFNN_R_INFO (indx, AARCH64_R (TLS_DTPMOD));
+ rela.r_addend = 0;
+ rela.r_offset = globals->root.sgot->output_section->vma +
+ globals->root.sgot->output_offset + off;
+
+
+ loc = globals->root.srelgot->contents;
+ loc += globals->root.srelgot->reloc_count++
+ * RELOC_SIZE (htab);
+ bfd_elfNN_swap_reloca_out (output_bfd, &rela, loc);
+
+ if (indx == 0)
+ {
+ bfd_put_NN (output_bfd,
+ relocation - dtpoff_base (info),
+ globals->root.sgot->contents + off
+ + GOT_ENTRY_SIZE);
+ }
+ else
+ {
+ /* This TLS symbol is global. We emit a
+ relocation to fixup the tls offset at load
+ time. */
+ rela.r_info =
+ ELFNN_R_INFO (indx, AARCH64_R (TLS_DTPREL));
+ rela.r_addend = 0;
+ rela.r_offset =
+ (globals->root.sgot->output_section->vma
+ + globals->root.sgot->output_offset + off
+ + GOT_ENTRY_SIZE);
+
+ loc = globals->root.srelgot->contents;
+ loc += globals->root.srelgot->reloc_count++
+ * RELOC_SIZE (globals);
+ bfd_elfNN_swap_reloca_out (output_bfd, &rela, loc);
+ bfd_put_NN (output_bfd, (bfd_vma) 0,
+ globals->root.sgot->contents + off
+ + GOT_ENTRY_SIZE);
+ }
+ }
+ else
+ {
+ bfd_put_NN (output_bfd, (bfd_vma) 1,
+ globals->root.sgot->contents + off);
+ bfd_put_NN (output_bfd,
+ relocation - dtpoff_base (info),
+ globals->root.sgot->contents + off
+ + GOT_ENTRY_SIZE);
+ }
+
+ symbol_got_offset_mark (input_bfd, h, r_symndx);
+ }
+ break;
+
+ case BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21:
+ case BFD_RELOC_AARCH64_TLSIE_LDNN_GOTTPREL_LO12_NC:
+ if (! symbol_got_offset_mark_p (input_bfd, h, r_symndx))
+ {
+ bfd_boolean need_relocs = FALSE;
+ bfd_byte *loc;
+ int indx;
+ bfd_vma off;
+
+ off = symbol_got_offset (input_bfd, h, r_symndx);
+
+ indx = h && h->dynindx != -1 ? h->dynindx : 0;
+
+ need_relocs =
+ (info->shared || indx != 0) &&
+ (h == NULL
+ || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
+ || h->root.type != bfd_link_hash_undefweak);
+
+ BFD_ASSERT (globals->root.srelgot != NULL);
+
+ if (need_relocs)
+ {
+ Elf_Internal_Rela rela;
+
+ if (indx == 0)
+ rela.r_addend = relocation - dtpoff_base (info);
+ else
+ rela.r_addend = 0;
+
+ rela.r_info = ELFNN_R_INFO (indx, AARCH64_R (TLS_TPREL));
+ rela.r_offset = globals->root.sgot->output_section->vma +
+ globals->root.sgot->output_offset + off;
+
+ loc = globals->root.srelgot->contents;
+ loc += globals->root.srelgot->reloc_count++
+ * RELOC_SIZE (htab);
+
+ bfd_elfNN_swap_reloca_out (output_bfd, &rela, loc);
+
+ bfd_put_NN (output_bfd, rela.r_addend,
+ globals->root.sgot->contents + off);
+ }
+ else
+ bfd_put_NN (output_bfd, relocation - tpoff_base (info),
+ globals->root.sgot->contents + off);
+
+ symbol_got_offset_mark (input_bfd, h, r_symndx);
+ }
+ break;
+
+ case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12:
+ case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_HI12:
+ case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12_NC:
+ case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G2:
+ case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1:
+ case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1_NC:
+ case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0:
+ case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC:
+ break;
+
+ case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12_NC:
+ case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21:
+ case BFD_RELOC_AARCH64_TLSDESC_LDNN_LO12_NC:
+ if (! symbol_tlsdesc_got_offset_mark_p (input_bfd, h, r_symndx))
+ {
+ bfd_boolean need_relocs = FALSE;
+ int indx = h && h->dynindx != -1 ? h->dynindx : 0;
+ bfd_vma off = symbol_tlsdesc_got_offset (input_bfd, h, r_symndx);
+
+ need_relocs = (h == NULL
+ || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
+ || h->root.type != bfd_link_hash_undefweak);
+
+ BFD_ASSERT (globals->root.srelgot != NULL);
+ BFD_ASSERT (globals->root.sgot != NULL);
+
+ if (need_relocs)
+ {
+ bfd_byte *loc;
+ Elf_Internal_Rela rela;
+ rela.r_info = ELFNN_R_INFO (indx, AARCH64_R (TLSDESC));
+
+ rela.r_addend = 0;
+ rela.r_offset = (globals->root.sgotplt->output_section->vma
+ + globals->root.sgotplt->output_offset
+ + off + globals->sgotplt_jump_table_size);
+
+ if (indx == 0)
+ rela.r_addend = relocation - dtpoff_base (info);
+
+ /* Allocate the next available slot in the PLT reloc
+ section to hold our R_AARCH64_TLSDESC, the next
+ available slot is determined from reloc_count,
+ which we step. But note, reloc_count was
+ artifically moved down while allocating slots for
+ real PLT relocs such that all of the PLT relocs
+ will fit above the initial reloc_count and the
+ extra stuff will fit below. */
+ loc = globals->root.srelplt->contents;
+ loc += globals->root.srelplt->reloc_count++
+ * RELOC_SIZE (globals);
+
+ bfd_elfNN_swap_reloca_out (output_bfd, &rela, loc);
+
+ bfd_put_NN (output_bfd, (bfd_vma) 0,
+ globals->root.sgotplt->contents + off +
+ globals->sgotplt_jump_table_size);
+ bfd_put_NN (output_bfd, (bfd_vma) 0,
+ globals->root.sgotplt->contents + off +
+ globals->sgotplt_jump_table_size +
+ GOT_ENTRY_SIZE);
+ }
+
+ symbol_tlsdesc_got_offset_mark (input_bfd, h, r_symndx);
+ }
+ break;
+ default:
+ break;
+ }
+
+ if (!save_addend)
+ addend = 0;
+
+
+ /* Dynamic relocs are not propagated for SEC_DEBUGGING sections
+ because such sections are not SEC_ALLOC and thus ld.so will
+ not process them. */
+ if (unresolved_reloc
+ && !((input_section->flags & SEC_DEBUGGING) != 0
+ && h->def_dynamic)
+ && _bfd_elf_section_offset (output_bfd, info, input_section,
+ +rel->r_offset) != (bfd_vma) - 1)
+ {
+ (*_bfd_error_handler)
+ (_
+ ("%B(%A+0x%lx): unresolvable %s relocation against symbol `%s'"),
+ input_bfd, input_section, (long) rel->r_offset, howto->name,
+ h->root.root.string);
+ return FALSE;
+ }
+
+ if (r != bfd_reloc_ok && r != bfd_reloc_continue)
+ {
+ switch (r)
+ {
+ case bfd_reloc_overflow:
+ /* If the overflowing reloc was to an undefined symbol,
+ we have already printed one error message and there
+ is no point complaining again. */
+ if ((!h ||
+ h->root.type != bfd_link_hash_undefined)
+ && (!((*info->callbacks->reloc_overflow)
+ (info, (h ? &h->root : NULL), 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, TRUE)))
+ return FALSE;
+ break;
+
+ case bfd_reloc_outofrange:
+ error_message = _("out of range");
+ goto common_error;
+
+ case bfd_reloc_notsupported:
+ error_message = _("unsupported relocation");
+ goto common_error;
+
+ case bfd_reloc_dangerous:
+ /* error_message should already be set. */
+ goto common_error;
+
+ default:
+ error_message = _("unknown error");
+ /* Fall through. */
+
+ common_error:
+ BFD_ASSERT (error_message != NULL);
+ if (!((*info->callbacks->reloc_dangerous)
+ (info, error_message, input_bfd, input_section,
+ rel->r_offset)))
+ return FALSE;
+ break;
+ }
+ }
+ }
+
+ return TRUE;
+}
+
+/* Set the right machine number. */
+
+static bfd_boolean
+elfNN_aarch64_object_p (bfd *abfd)
+{
+#if ARCH_SIZE == 32
+ bfd_default_set_arch_mach (abfd, bfd_arch_aarch64, bfd_mach_aarch64_ilp32);
+#else
+ bfd_default_set_arch_mach (abfd, bfd_arch_aarch64, bfd_mach_aarch64);
+#endif
+ return TRUE;
+}
+
+/* Function to keep AArch64 specific flags in the ELF header. */
+
+static bfd_boolean
+elfNN_aarch64_set_private_flags (bfd *abfd, flagword flags)
+{
+ if (elf_flags_init (abfd) && elf_elfheader (abfd)->e_flags != flags)
+ {
+ }
+ else
+ {
+ elf_elfheader (abfd)->e_flags = flags;
+ elf_flags_init (abfd) = TRUE;
+ }
+
+ return TRUE;
+}
+
+/* Merge backend specific data from an object file to the output
+ object file when linking. */
+
+static bfd_boolean
+elfNN_aarch64_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
+{
+ flagword out_flags;
+ flagword in_flags;
+ bfd_boolean flags_compatible = TRUE;
+ asection *sec;
+
+ /* Check if we have the same endianess. */
+ if (!_bfd_generic_verify_endian_match (ibfd, obfd))
+ return FALSE;
+
+ if (!is_aarch64_elf (ibfd) || !is_aarch64_elf (obfd))
+ return TRUE;
+
+ /* 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 and had the default
+ flags 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
+ uninitialised values, which surprise surprise, correspond
+ to the default values. */
+ if (bfd_get_arch_info (ibfd)->the_default
+ && elf_elfheader (ibfd)->e_flags == 0)
+ 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;
+ }
+
+ /* Identical flags must be compatible. */
+ if (in_flags == out_flags)
+ return TRUE;
+
+ /* Check to see if the input BFD actually contains any sections. If
+ not, its flags may not have been initialised either, but it
+ cannot actually cause any incompatiblity. Do not short-circuit
+ dynamic objects; their section list may be emptied by
+ elf_link_add_object_symbols.
+
+ Also check to see if there are no code sections in the input.
+ In this case there is no need to check for code specific flags.
+ XXX - do we need to worry about floating-point format compatability
+ in data sections ? */
+ if (!(ibfd->flags & DYNAMIC))
+ {
+ bfd_boolean null_input_bfd = TRUE;
+ bfd_boolean only_data_sections = TRUE;
+
+ for (sec = ibfd->sections; sec != NULL; sec = sec->next)
+ {
+ if ((bfd_get_section_flags (ibfd, sec)
+ & (SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS))
+ == (SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS))
+ only_data_sections = FALSE;
+
+ null_input_bfd = FALSE;
+ break;
+ }
+
+ if (null_input_bfd || only_data_sections)
+ return TRUE;
+ }
+
+ return flags_compatible;
+}
+
+/* Display the flags field. */
+
+static bfd_boolean
+elfNN_aarch64_print_private_bfd_data (bfd *abfd, void *ptr)
+{
+ FILE *file = (FILE *) ptr;
+ unsigned long flags;
+
+ BFD_ASSERT (abfd != NULL && ptr != NULL);
+
+ /* Print normal ELF private data. */
+ _bfd_elf_print_private_bfd_data (abfd, ptr);
+
+ flags = elf_elfheader (abfd)->e_flags;
+ /* 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 (flags)
+ fprintf (file, _("<Unrecognised flag bits set>"));
+
+ fputc ('\n', file);
+
+ return TRUE;
+}
+
+/* Update the got entry reference counts for the section being removed. */
+
+static bfd_boolean
+elfNN_aarch64_gc_sweep_hook (bfd *abfd,
+ struct bfd_link_info *info,
+ asection *sec,
+ const Elf_Internal_Rela * relocs)
+{
+ struct elf_aarch64_link_hash_table *htab;
+ Elf_Internal_Shdr *symtab_hdr;
+ struct elf_link_hash_entry **sym_hashes;
+ struct elf_aarch64_local_symbol *locals;
+ const Elf_Internal_Rela *rel, *relend;
+
+ if (info->relocatable)
+ return TRUE;
+
+ htab = elf_aarch64_hash_table (info);
+
+ if (htab == NULL)
+ return FALSE;
+
+ elf_section_data (sec)->local_dynrel = NULL;
+
+ symtab_hdr = &elf_symtab_hdr (abfd);
+ sym_hashes = elf_sym_hashes (abfd);
+
+ locals = elf_aarch64_locals (abfd);
+
+ relend = relocs + sec->reloc_count;
+ for (rel = relocs; rel < relend; rel++)
+ {
+ unsigned long r_symndx;
+ unsigned int r_type;
+ struct elf_link_hash_entry *h = NULL;
+
+ r_symndx = ELFNN_R_SYM (rel->r_info);
+
+ if (r_symndx >= symtab_hdr->sh_info)
+ {
+
+ 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;
+ }
+ else
+ {
+ Elf_Internal_Sym *isym;
+
+ /* A local symbol. */
+ isym = bfd_sym_from_r_symndx (&htab->sym_cache,
+ abfd, r_symndx);
+
+ /* Check relocation against local STT_GNU_IFUNC symbol. */
+ if (isym != NULL
+ && ELF_ST_TYPE (isym->st_info) == STT_GNU_IFUNC)
+ {
+ h = elfNN_aarch64_get_local_sym_hash (htab, abfd, rel, FALSE);
+ if (h == NULL)
+ abort ();
+ }
+ }
+
+ if (h)
+ {
+ struct elf_aarch64_link_hash_entry *eh;
+ struct elf_dyn_relocs **pp;
+ struct elf_dyn_relocs *p;
+
+ eh = (struct elf_aarch64_link_hash_entry *) h;
+
+ for (pp = &eh->dyn_relocs; (p = *pp) != NULL; pp = &p->next)
+ if (p->sec == sec)
+ {
+ /* Everything must go for SEC. */
+ *pp = p->next;
+ break;
+ }
+ }
+
+ r_type = ELFNN_R_TYPE (rel->r_info);
+ switch (aarch64_tls_transition (abfd,info, r_type, h ,r_symndx))
+ {
+ case BFD_RELOC_AARCH64_ADR_GOT_PAGE:
+ case BFD_RELOC_AARCH64_GOT_LD_PREL19:
+ case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC:
+ case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC:
+ case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12_NC:
+ case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21:
+ case BFD_RELOC_AARCH64_TLSDESC_LD32_LO12_NC:
+ case BFD_RELOC_AARCH64_TLSDESC_LD64_LO12_NC:
+ case BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC:
+ case BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21:
+ case BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21:
+ case BFD_RELOC_AARCH64_TLSIE_LD32_GOTTPREL_LO12_NC:
+ case BFD_RELOC_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC:
+ case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_HI12:
+ case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12:
+ case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12_NC:
+ case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0:
+ case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC:
+ case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1:
+ case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1_NC:
+ case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G2:
+ if (h != NULL)
+ {
+ if (h->got.refcount > 0)
+ h->got.refcount -= 1;
+
+ if (h->type == STT_GNU_IFUNC)
+ {
+ if (h->plt.refcount > 0)
+ h->plt.refcount -= 1;
+ }
+ }
+ else if (locals != NULL)
+ {
+ if (locals[r_symndx].got_refcount > 0)
+ locals[r_symndx].got_refcount -= 1;
+ }
+ break;
+
+ case BFD_RELOC_AARCH64_CALL26:
+ case BFD_RELOC_AARCH64_JUMP26:
+ /* If this is a local symbol then we resolve it
+ directly without creating a PLT entry. */
+ if (h == NULL)
+ continue;
+
+ if (h->plt.refcount > 0)
+ h->plt.refcount -= 1;
+ break;
+
+ case BFD_RELOC_AARCH64_MOVW_G0_NC:
+ case BFD_RELOC_AARCH64_MOVW_G1_NC:
+ case BFD_RELOC_AARCH64_MOVW_G2_NC:
+ case BFD_RELOC_AARCH64_MOVW_G3:
+ case BFD_RELOC_AARCH64_ADR_HI21_NC_PCREL:
+ case BFD_RELOC_AARCH64_ADR_HI21_PCREL:
+ case BFD_RELOC_AARCH64_ADR_LO21_PCREL:
+ case BFD_RELOC_AARCH64_NN:
+ if (h != NULL && info->executable)
+ {
+ if (h->plt.refcount > 0)
+ h->plt.refcount -= 1;
+ }
+ 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 bfd_boolean
+elfNN_aarch64_adjust_dynamic_symbol (struct bfd_link_info *info,
+ struct elf_link_hash_entry *h)
+{
+ struct elf_aarch64_link_hash_table *htab;
+ asection *s;
+
+ /* 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->type == STT_GNU_IFUNC || h->needs_plt)
+ {
+ if (h->plt.refcount <= 0
+ || (h->type != STT_GNU_IFUNC
+ && (SYMBOL_CALLS_LOCAL (info, h)
+ || (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
+ && h->root.type == bfd_link_hash_undefweak))))
+ {
+ /* This case can occur if we saw a CALL26 reloc in
+ an input file, but the symbol wasn't referred to
+ by a dynamic object or all references were
+ garbage collected. In which case we can end up
+ resolving. */
+ h->plt.offset = (bfd_vma) - 1;
+ h->needs_plt = 0;
+ }
+
+ return TRUE;
+ }
+ else
+ /* It's possible that we incorrectly decided a .plt reloc was
+ needed for an R_X86_64_PC32 reloc to a non-function sym in
+ check_relocs. We can't decide accurately between function and
+ non-function syms in check-relocs; Objects loaded later in
+ the link may change h->type. So fix it now. */
+ 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->u.weakdef != NULL)
+ {
+ BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
+ || h->u.weakdef->root.type == bfd_link_hash_defweak);
+ h->root.u.def.section = h->u.weakdef->root.u.def.section;
+ h->root.u.def.value = h->u.weakdef->root.u.def.value;
+ if (ELIMINATE_COPY_RELOCS || info->nocopyreloc)
+ h->non_got_ref = h->u.weakdef->non_got_ref;
+ return TRUE;
+ }
+
+ /* 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;
+
+ /* If there are no references to this symbol that do not use the
+ GOT, we don't need to generate a copy reloc. */
+ if (!h->non_got_ref)
+ return TRUE;
+
+ /* If -z nocopyreloc was given, we won't generate them either. */
+ if (info->nocopyreloc)
+ {
+ h->non_got_ref = 0;
+ 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. */
+
+ htab = elf_aarch64_hash_table (info);
+
+ /* We must generate a R_AARCH64_COPY reloc to tell the dynamic linker
+ to copy the initial value out of the dynamic object and into the
+ runtime process image. */
+ if ((h->root.u.def.section->flags & SEC_ALLOC) != 0 && h->size != 0)
+ {
+ htab->srelbss->size += RELOC_SIZE (htab);
+ h->needs_copy = 1;
+ }
+
+ s = htab->sdynbss;
+
+ return _bfd_elf_adjust_dynamic_copy (h, s);
+
+}
+
+static bfd_boolean
+elfNN_aarch64_allocate_local_symbols (bfd *abfd, unsigned number)
+{
+ struct elf_aarch64_local_symbol *locals;
+ locals = elf_aarch64_locals (abfd);
+ if (locals == NULL)
+ {
+ locals = (struct elf_aarch64_local_symbol *)
+ bfd_zalloc (abfd, number * sizeof (struct elf_aarch64_local_symbol));
+ if (locals == NULL)
+ return FALSE;
+ elf_aarch64_locals (abfd) = locals;
+ }
+ return TRUE;
+}
+
+/* Create the .got section to hold the global offset table. */
+
+static bfd_boolean
+aarch64_elf_create_got_section (bfd *abfd, struct bfd_link_info *info)
+{
+ const struct elf_backend_data *bed = get_elf_backend_data (abfd);
+ flagword flags;
+ asection *s;
+ struct elf_link_hash_entry *h;
+ struct elf_link_hash_table *htab = elf_hash_table (info);
+
+ /* This function may be called more than once. */
+ s = bfd_get_linker_section (abfd, ".got");
+ if (s != NULL)
+ return TRUE;
+
+ flags = bed->dynamic_sec_flags;
+
+ s = bfd_make_section_anyway_with_flags (abfd,
+ (bed->rela_plts_and_copies_p
+ ? ".rela.got" : ".rel.got"),
+ (bed->dynamic_sec_flags
+ | SEC_READONLY));
+ if (s == NULL
+ || ! bfd_set_section_alignment (abfd, s, bed->s->log_file_align))
+ return FALSE;
+ htab->srelgot = s;
+
+ s = bfd_make_section_anyway_with_flags (abfd, ".got", flags);
+ if (s == NULL
+ || !bfd_set_section_alignment (abfd, s, bed->s->log_file_align))
+ return FALSE;
+ htab->sgot = s;
+ htab->sgot->size += GOT_ENTRY_SIZE;
+
+ if (bed->want_got_sym)
+ {
+ /* 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 = _bfd_elf_define_linkage_sym (abfd, info, s,
+ "_GLOBAL_OFFSET_TABLE_");
+ elf_hash_table (info)->hgot = h;
+ if (h == NULL)
+ return FALSE;
+ }
+
+ if (bed->want_got_plt)
+ {
+ s = bfd_make_section_anyway_with_flags (abfd, ".got.plt", flags);
+ if (s == NULL
+ || !bfd_set_section_alignment (abfd, s,
+ bed->s->log_file_align))
+ return FALSE;
+ htab->sgotplt = s;
+ }
+
+ /* The first bit of the global offset table is the header. */
+ s->size += bed->got_header_size;
+
+ return TRUE;
+}
+
+/* Look through the relocs for a section during the first phase. */
+
+static bfd_boolean
+elfNN_aarch64_check_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;
+ const Elf_Internal_Rela *rel;
+ const Elf_Internal_Rela *rel_end;
+ asection *sreloc;
+
+ struct elf_aarch64_link_hash_table *htab;
+
+ if (info->relocatable)
+ return TRUE;
+
+ BFD_ASSERT (is_aarch64_elf (abfd));
+
+ htab = elf_aarch64_hash_table (info);
+ sreloc = NULL;
+
+ symtab_hdr = &elf_symtab_hdr (abfd);
+ sym_hashes = elf_sym_hashes (abfd);
+
+ rel_end = relocs + sec->reloc_count;
+ for (rel = relocs; rel < rel_end; rel++)
+ {
+ struct elf_link_hash_entry *h;
+ unsigned long r_symndx;
+ unsigned int r_type;
+ bfd_reloc_code_real_type bfd_r_type;
+ Elf_Internal_Sym *isym;
+
+ r_symndx = ELFNN_R_SYM (rel->r_info);
+ r_type = ELFNN_R_TYPE (rel->r_info);
+
+ if (r_symndx >= NUM_SHDR_ENTRIES (symtab_hdr))
+ {
+ (*_bfd_error_handler) (_("%B: bad symbol index: %d"), abfd,
+ r_symndx);
+ return FALSE;
+ }
+
+ if (r_symndx < symtab_hdr->sh_info)
+ {
+ /* A local symbol. */
+ isym = bfd_sym_from_r_symndx (&htab->sym_cache,
+ abfd, r_symndx);
+ if (isym == NULL)
+ return FALSE;
+
+ /* Check relocation against local STT_GNU_IFUNC symbol. */
+ if (ELF_ST_TYPE (isym->st_info) == STT_GNU_IFUNC)
+ {
+ h = elfNN_aarch64_get_local_sym_hash (htab, abfd, rel,
+ TRUE);
+ if (h == NULL)
+ return FALSE;
+
+ /* Fake a STT_GNU_IFUNC symbol. */
+ h->type = STT_GNU_IFUNC;
+ h->def_regular = 1;
+ h->ref_regular = 1;
+ h->forced_local = 1;
+ h->root.type = bfd_link_hash_defined;
+ }
+ else
+ h = NULL;
+ }
+ 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;
+
+ /* PR15323, ref flags aren't set for references in the same
+ object. */
+ h->root.non_ir_ref = 1;
+ }
+
+ /* Could be done earlier, if h were already available. */
+ bfd_r_type = aarch64_tls_transition (abfd, info, r_type, h, r_symndx);
+
+ if (h != NULL)
+ {
+ /* Create the ifunc sections for static executables. If we
+ never see an indirect function symbol nor we are building
+ a static executable, those sections will be empty and
+ won't appear in output. */
+ switch (bfd_r_type)
+ {
+ default:
+ break;
+
+ case BFD_RELOC_AARCH64_NN:
+ case BFD_RELOC_AARCH64_CALL26:
+ case BFD_RELOC_AARCH64_JUMP26:
+ case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC:
+ case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC:
+ case BFD_RELOC_AARCH64_ADR_GOT_PAGE:
+ case BFD_RELOC_AARCH64_GOT_LD_PREL19:
+ case BFD_RELOC_AARCH64_ADR_HI21_PCREL:
+ case BFD_RELOC_AARCH64_ADD_LO12:
+ if (htab->root.dynobj == NULL)
+ htab->root.dynobj = abfd;
+ if (!_bfd_elf_create_ifunc_sections (htab->root.dynobj, info))
+ return FALSE;
+ break;
+ }
+
+ /* It is referenced by a non-shared object. */
+ h->ref_regular = 1;
+ h->root.non_ir_ref = 1;
+ }
+
+ switch (bfd_r_type)
+ {
+ case BFD_RELOC_AARCH64_NN:
+
+ /* We don't need to handle relocs into sections not going into
+ the "real" output. */
+ if ((sec->flags & SEC_ALLOC) == 0)
+ break;
+
+ if (h != NULL)
+ {
+ if (!info->shared)
+ h->non_got_ref = 1;
+
+ h->plt.refcount += 1;
+ h->pointer_equality_needed = 1;
+ }
+
+ /* No need to do anything if we're not creating a shared
+ object. */
+ if (! info->shared)
+ break;
+
+ {
+ struct elf_dyn_relocs *p;
+ struct elf_dyn_relocs **head;
+
+ /* We must copy these reloc types into the output file.
+ Create a reloc section in dynobj and make room for
+ this reloc. */
+ if (sreloc == NULL)
+ {
+ if (htab->root.dynobj == NULL)
+ htab->root.dynobj = abfd;
+
+ sreloc = _bfd_elf_make_dynamic_reloc_section
+ (sec, htab->root.dynobj, LOG_FILE_ALIGN, abfd, /*rela? */ TRUE);
+
+ if (sreloc == NULL)
+ return FALSE;
+ }
+
+ /* If this is a global symbol, we count the number of
+ relocations we need for this symbol. */
+ if (h != NULL)
+ {
+ struct elf_aarch64_link_hash_entry *eh;
+ eh = (struct elf_aarch64_link_hash_entry *) h;
+ head = &eh->dyn_relocs;
+ }
+ else
+ {
+ /* Track dynamic relocs needed for local syms too.
+ We really need local syms available to do this
+ easily. Oh well. */
+
+ asection *s;
+ void **vpp;
+
+ isym = bfd_sym_from_r_symndx (&htab->sym_cache,
+ abfd, r_symndx);
+ if (isym == NULL)
+ return FALSE;
+
+ s = bfd_section_from_elf_index (abfd, isym->st_shndx);
+ if (s == NULL)
+ s = sec;
+
+ /* Beware of type punned pointers vs strict aliasing
+ rules. */
+ vpp = &(elf_section_data (s)->local_dynrel);
+ head = (struct elf_dyn_relocs **) vpp;
+ }
+
+ p = *head;
+ if (p == NULL || p->sec != sec)
+ {
+ bfd_size_type amt = sizeof *p;
+ p = ((struct elf_dyn_relocs *)
+ bfd_zalloc (htab->root.dynobj, amt));
+ if (p == NULL)
+ return FALSE;
+ p->next = *head;
+ *head = p;
+ p->sec = sec;
+ }
+
+ p->count += 1;
+
+ }
+ break;
+
+ /* RR: We probably want to keep a consistency check that
+ there are no dangling GOT_PAGE relocs. */
+ case BFD_RELOC_AARCH64_ADR_GOT_PAGE:
+ case BFD_RELOC_AARCH64_GOT_LD_PREL19:
+ case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC:
+ case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC:
+ case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12_NC:
+ case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21:
+ case BFD_RELOC_AARCH64_TLSDESC_LD32_LO12_NC:
+ case BFD_RELOC_AARCH64_TLSDESC_LD64_LO12_NC:
+ case BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC:
+ case BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21:
+ case BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21:
+ case BFD_RELOC_AARCH64_TLSIE_LD32_GOTTPREL_LO12_NC:
+ case BFD_RELOC_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC:
+ case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_HI12:
+ case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12:
+ case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12_NC:
+ case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0:
+ case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC:
+ case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1:
+ case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1_NC:
+ case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G2:
+ {
+ unsigned got_type;
+ unsigned old_got_type;
+
+ got_type = aarch64_reloc_got_type (bfd_r_type);
+
+ if (h)
+ {
+ h->got.refcount += 1;
+ old_got_type = elf_aarch64_hash_entry (h)->got_type;
+ }
+ else
+ {
+ struct elf_aarch64_local_symbol *locals;
+
+ if (!elfNN_aarch64_allocate_local_symbols
+ (abfd, symtab_hdr->sh_info))
+ return FALSE;
+
+ locals = elf_aarch64_locals (abfd);
+ BFD_ASSERT (r_symndx < symtab_hdr->sh_info);
+ locals[r_symndx].got_refcount += 1;
+ old_got_type = locals[r_symndx].got_type;
+ }
+
+ /* If a variable is accessed with both general dynamic TLS
+ methods, two slots may be created. */
+ if (GOT_TLS_GD_ANY_P (old_got_type) && GOT_TLS_GD_ANY_P (got_type))
+ got_type |= old_got_type;
+
+ /* We will already have issued an error message if there
+ is a TLS/non-TLS mismatch, based on the symbol type.
+ So just combine any TLS types needed. */
+ if (old_got_type != GOT_UNKNOWN && old_got_type != GOT_NORMAL
+ && got_type != GOT_NORMAL)
+ got_type |= old_got_type;
+
+ /* If the symbol is accessed by both IE and GD methods, we
+ are able to relax. Turn off the GD flag, without
+ messing up with any other kind of TLS types that may be
+ involved. */
+ if ((got_type & GOT_TLS_IE) && GOT_TLS_GD_ANY_P (got_type))
+ got_type &= ~ (GOT_TLSDESC_GD | GOT_TLS_GD);
+
+ if (old_got_type != got_type)
+ {
+ if (h != NULL)
+ elf_aarch64_hash_entry (h)->got_type = got_type;
+ else
+ {
+ struct elf_aarch64_local_symbol *locals;
+ locals = elf_aarch64_locals (abfd);
+ BFD_ASSERT (r_symndx < symtab_hdr->sh_info);
+ locals[r_symndx].got_type = got_type;
+ }
+ }
+
+ if (htab->root.dynobj == NULL)
+ htab->root.dynobj = abfd;
+ if (! aarch64_elf_create_got_section (htab->root.dynobj, info))
+ return FALSE;
+ break;
+ }
+
+ case BFD_RELOC_AARCH64_MOVW_G0_NC:
+ case BFD_RELOC_AARCH64_MOVW_G1_NC:
+ case BFD_RELOC_AARCH64_MOVW_G2_NC:
+ case BFD_RELOC_AARCH64_MOVW_G3:
+ if (info->shared)
+ {
+ int howto_index = bfd_r_type - BFD_RELOC_AARCH64_RELOC_START;
+ (*_bfd_error_handler)
+ (_("%B: relocation %s against `%s' can not be used when making "
+ "a shared object; recompile with -fPIC"),
+ abfd, elfNN_aarch64_howto_table[howto_index].name,
+ (h) ? h->root.root.string : "a local symbol");
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+
+ case BFD_RELOC_AARCH64_ADR_HI21_NC_PCREL:
+ case BFD_RELOC_AARCH64_ADR_HI21_PCREL:
+ case BFD_RELOC_AARCH64_ADR_LO21_PCREL:
+ if (h != NULL && info->executable)
+ {
+ /* If this reloc is in a read-only section, we might
+ need a copy reloc. We can't check reliably at this
+ stage whether the section is read-only, as input
+ sections have not yet been mapped to output sections.
+ Tentatively set the flag for now, and correct in
+ adjust_dynamic_symbol. */
+ h->non_got_ref = 1;
+ h->plt.refcount += 1;
+ h->pointer_equality_needed = 1;
+ }
+ /* FIXME:: RR need to handle these in shared libraries
+ and essentially bomb out as these being non-PIC
+ relocations in shared libraries. */
+ break;
+
+ case BFD_RELOC_AARCH64_CALL26:
+ case BFD_RELOC_AARCH64_JUMP26:
+ /* If this is a local symbol then we resolve it
+ directly without creating a PLT entry. */
+ if (h == NULL)
+ continue;
+
+ h->needs_plt = 1;
+ if (h->plt.refcount <= 0)
+ h->plt.refcount = 1;
+ else
+ h->plt.refcount += 1;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ return TRUE;
+}
+
+/* Treat mapping symbols as special target symbols. */
+
+static bfd_boolean
+elfNN_aarch64_is_target_special_symbol (bfd *abfd ATTRIBUTE_UNUSED,
+ asymbol *sym)
+{
+ return bfd_is_aarch64_special_symbol_name (sym->name,
+ BFD_AARCH64_SPECIAL_SYM_TYPE_ANY);
+}
+
+/* This is a copy of elf_find_function () from elf.c except that
+ AArch64 mapping symbols are ignored when looking for function names. */
+
+static bfd_boolean
+aarch64_elf_find_function (bfd *abfd ATTRIBUTE_UNUSED,
+ asymbol **symbols,
+ asection *section,
+ bfd_vma offset,
+ const char **filename_ptr,
+ const char **functionname_ptr)
+{
+ const char *filename = NULL;
+ asymbol *func = NULL;
+ bfd_vma low_func = 0;
+ asymbol **p;
+
+ for (p = symbols; *p != NULL; p++)
+ {
+ elf_symbol_type *q;
+
+ q = (elf_symbol_type *) * p;
+
+ switch (ELF_ST_TYPE (q->internal_elf_sym.st_info))
+ {
+ default:
+ break;
+ case STT_FILE:
+ filename = bfd_asymbol_name (&q->symbol);
+ break;
+ case STT_FUNC:
+ case STT_NOTYPE:
+ /* Skip mapping symbols. */
+ if ((q->symbol.flags & BSF_LOCAL)
+ && (bfd_is_aarch64_special_symbol_name
+ (q->symbol.name, BFD_AARCH64_SPECIAL_SYM_TYPE_ANY)))
+ continue;
+ /* Fall through. */
+ if (bfd_get_section (&q->symbol) == section
+ && q->symbol.value >= low_func && q->symbol.value <= offset)
+ {
+ func = (asymbol *) q;
+ low_func = q->symbol.value;
+ }
+ break;
+ }
+ }
+
+ if (func == NULL)
+ return FALSE;
+
+ if (filename_ptr)
+ *filename_ptr = filename;
+ if (functionname_ptr)
+ *functionname_ptr = bfd_asymbol_name (func);
+
+ 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 uses aarch64_elf_find_function. */
+
+static bfd_boolean
+elfNN_aarch64_find_nearest_line (bfd *abfd,
+ asymbol **symbols,
+ asection *section,
+ bfd_vma offset,
+ const char **filename_ptr,
+ const char **functionname_ptr,
+ unsigned int *line_ptr,
+ unsigned int *discriminator_ptr)
+{
+ bfd_boolean found = FALSE;
+
+ if (_bfd_dwarf2_find_nearest_line (abfd, symbols, NULL, section, offset,
+ filename_ptr, functionname_ptr,
+ line_ptr, discriminator_ptr,
+ dwarf_debug_sections, 0,
+ &elf_tdata (abfd)->dwarf2_find_line_info))
+ {
+ if (!*functionname_ptr)
+ aarch64_elf_find_function (abfd, symbols, section, offset,
+ *filename_ptr ? NULL : filename_ptr,
+ functionname_ptr);
+
+ return TRUE;
+ }
+
+ /* Skip _bfd_dwarf1_find_nearest_line since no known AArch64
+ toolchain uses DWARF1. */
+
+ 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 && (*functionname_ptr || *line_ptr))
+ return TRUE;
+
+ if (symbols == NULL)
+ return FALSE;
+
+ if (!aarch64_elf_find_function (abfd, symbols, section, offset,
+ filename_ptr, functionname_ptr))
+ return FALSE;
+
+ *line_ptr = 0;
+ return TRUE;
+}
+
+static bfd_boolean
+elfNN_aarch64_find_inliner_info (bfd *abfd,
+ const char **filename_ptr,
+ const char **functionname_ptr,
+ unsigned int *line_ptr)
+{
+ bfd_boolean found;
+ found = _bfd_dwarf2_find_inliner_info
+ (abfd, filename_ptr,
+ functionname_ptr, line_ptr, &elf_tdata (abfd)->dwarf2_find_line_info);
+ return found;
+}
+
+
+static void
+elfNN_aarch64_post_process_headers (bfd *abfd,
+ struct bfd_link_info *link_info)
+{
+ Elf_Internal_Ehdr *i_ehdrp; /* ELF file header, internal form. */
+
+ i_ehdrp = elf_elfheader (abfd);
+ i_ehdrp->e_ident[EI_ABIVERSION] = AARCH64_ELF_ABI_VERSION;
+
+ _bfd_elf_post_process_headers (abfd, link_info);
+}
+
+static enum elf_reloc_type_class
+elfNN_aarch64_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ const asection *rel_sec ATTRIBUTE_UNUSED,
+ const Elf_Internal_Rela *rela)
+{
+ switch ((int) ELFNN_R_TYPE (rela->r_info))
+ {
+ case AARCH64_R (RELATIVE):
+ return reloc_class_relative;
+ case AARCH64_R (JUMP_SLOT):
+ return reloc_class_plt;
+ case AARCH64_R (COPY):
+ return reloc_class_copy;
+ default:
+ return reloc_class_normal;
+ }
+}
+
+/* Handle an AArch64 specific section when reading an object file. This is
+ called when bfd_section_from_shdr finds a section with an unknown
+ type. */
+
+static bfd_boolean
+elfNN_aarch64_section_from_shdr (bfd *abfd,
+ Elf_Internal_Shdr *hdr,
+ const char *name, int shindex)
+{
+ /* 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
+ names for all the AArch64 specific sections, so we will probably get
+ away with this. */
+ switch (hdr->sh_type)
+ {
+ case SHT_AARCH64_ATTRIBUTES:
+ break;
+
+ default:
+ return FALSE;
+ }
+
+ if (!_bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex))
+ return FALSE;
+
+ return TRUE;
+}
+
+/* A structure used to record a list of sections, independently
+ of the next and prev fields in the asection structure. */
+typedef struct section_list
+{
+ asection *sec;
+ struct section_list *next;
+ struct section_list *prev;
+}
+section_list;
+
+/* Unfortunately we need to keep a list of sections for which
+ an _aarch64_elf_section_data structure has been allocated. This
+ is because it is possible for functions like elfNN_aarch64_write_section
+ to be called on a section which has had an elf_data_structure
+ allocated for it (and so the used_by_bfd field is valid) but
+ for which the AArch64 extended version of this structure - the
+ _aarch64_elf_section_data structure - has not been allocated. */
+static section_list *sections_with_aarch64_elf_section_data = NULL;
+
+static void
+record_section_with_aarch64_elf_section_data (asection *sec)
+{
+ struct section_list *entry;
+
+ entry = bfd_malloc (sizeof (*entry));
+ if (entry == NULL)
+ return;
+ entry->sec = sec;
+ entry->next = sections_with_aarch64_elf_section_data;
+ entry->prev = NULL;
+ if (entry->next != NULL)
+ entry->next->prev = entry;
+ sections_with_aarch64_elf_section_data = entry;
+}
+
+static struct section_list *
+find_aarch64_elf_section_entry (asection *sec)
+{
+ struct section_list *entry;
+ static struct section_list *last_entry = NULL;
+
+ /* This is a short cut for the typical case where the sections are added
+ to the sections_with_aarch64_elf_section_data list in forward order and
+ then looked up here in backwards order. This makes a real difference
+ to the ld-srec/sec64k.exp linker test. */
+ entry = sections_with_aarch64_elf_section_data;
+ if (last_entry != NULL)
+ {
+ if (last_entry->sec == sec)
+ entry = last_entry;
+ else if (last_entry->next != NULL && last_entry->next->sec == sec)
+ entry = last_entry->next;
+ }
+
+ for (; entry; entry = entry->next)
+ if (entry->sec == sec)
+ break;
+
+ if (entry)
+ /* Record the entry prior to this one - it is the entry we are
+ most likely to want to locate next time. Also this way if we
+ have been called from
+ unrecord_section_with_aarch64_elf_section_data () we will not
+ be caching a pointer that is about to be freed. */
+ last_entry = entry->prev;
+
+ return entry;
+}
+
+static void
+unrecord_section_with_aarch64_elf_section_data (asection *sec)
+{
+ struct section_list *entry;
+
+ entry = find_aarch64_elf_section_entry (sec);
+
+ if (entry)
+ {
+ if (entry->prev != NULL)
+ entry->prev->next = entry->next;
+ if (entry->next != NULL)
+ entry->next->prev = entry->prev;
+ if (entry == sections_with_aarch64_elf_section_data)
+ sections_with_aarch64_elf_section_data = entry->next;
+ free (entry);
+ }
+}
+
+
+typedef struct
+{
+ void *finfo;
+ struct bfd_link_info *info;
+ asection *sec;
+ int sec_shndx;
+ int (*func) (void *, const char *, Elf_Internal_Sym *,
+ asection *, struct elf_link_hash_entry *);
+} output_arch_syminfo;
+
+enum map_symbol_type
+{
+ AARCH64_MAP_INSN,
+ AARCH64_MAP_DATA
+};
+
+
+/* Output a single mapping symbol. */
+
+static bfd_boolean
+elfNN_aarch64_output_map_sym (output_arch_syminfo *osi,
+ enum map_symbol_type type, bfd_vma offset)
+{
+ static const char *names[2] = { "$x", "$d" };
+ Elf_Internal_Sym sym;
+
+ sym.st_value = (osi->sec->output_section->vma
+ + osi->sec->output_offset + offset);
+ sym.st_size = 0;
+ sym.st_other = 0;
+ sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_NOTYPE);
+ sym.st_shndx = osi->sec_shndx;
+ return osi->func (osi->finfo, names[type], &sym, osi->sec, NULL) == 1;
+}
+
+
+
+/* Output mapping symbols for PLT entries associated with H. */
+
+static bfd_boolean
+elfNN_aarch64_output_plt_map (struct elf_link_hash_entry *h, void *inf)
+{
+ output_arch_syminfo *osi = (output_arch_syminfo *) inf;
+ bfd_vma addr;
+
+ if (h->root.type == bfd_link_hash_indirect)
+ return TRUE;
+
+ if (h->root.type == bfd_link_hash_warning)
+ /* When warning symbols are created, they **replace** the "real"
+ entry in the hash table, thus we never get to see the real
+ symbol in a hash traversal. So look at it now. */
+ h = (struct elf_link_hash_entry *) h->root.u.i.link;
+
+ if (h->plt.offset == (bfd_vma) - 1)
+ return TRUE;
+
+ addr = h->plt.offset;
+ if (addr == 32)
+ {
+ if (!elfNN_aarch64_output_map_sym (osi, AARCH64_MAP_INSN, addr))
+ return FALSE;
+ }
+ return TRUE;
+}
+
+
+/* Output a single local symbol for a generated stub. */
+
+static bfd_boolean
+elfNN_aarch64_output_stub_sym (output_arch_syminfo *osi, const char *name,
+ bfd_vma offset, bfd_vma size)
+{
+ Elf_Internal_Sym sym;
+
+ sym.st_value = (osi->sec->output_section->vma
+ + osi->sec->output_offset + offset);
+ sym.st_size = size;
+ sym.st_other = 0;
+ sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_FUNC);
+ sym.st_shndx = osi->sec_shndx;
+ return osi->func (osi->finfo, name, &sym, osi->sec, NULL) == 1;
+}
+
+static bfd_boolean
+aarch64_map_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
+{
+ struct elf_aarch64_stub_hash_entry *stub_entry;
+ asection *stub_sec;
+ bfd_vma addr;
+ char *stub_name;
+ output_arch_syminfo *osi;
+
+ /* Massage our args to the form they really have. */
+ stub_entry = (struct elf_aarch64_stub_hash_entry *) gen_entry;
+ osi = (output_arch_syminfo *) in_arg;
+
+ stub_sec = stub_entry->stub_sec;
+
+ /* Ensure this stub is attached to the current section being
+ processed. */
+ if (stub_sec != osi->sec)
+ return TRUE;
+
+ addr = (bfd_vma) stub_entry->stub_offset;
+
+ stub_name = stub_entry->output_name;
+
+ switch (stub_entry->stub_type)
+ {
+ case aarch64_stub_adrp_branch:
+ if (!elfNN_aarch64_output_stub_sym (osi, stub_name, addr,
+ sizeof (aarch64_adrp_branch_stub)))
+ return FALSE;
+ if (!elfNN_aarch64_output_map_sym (osi, AARCH64_MAP_INSN, addr))
+ return FALSE;
+ break;
+ case aarch64_stub_long_branch:
+ if (!elfNN_aarch64_output_stub_sym
+ (osi, stub_name, addr, sizeof (aarch64_long_branch_stub)))
+ return FALSE;
+ if (!elfNN_aarch64_output_map_sym (osi, AARCH64_MAP_INSN, addr))
+ return FALSE;
+ if (!elfNN_aarch64_output_map_sym (osi, AARCH64_MAP_DATA, addr + 16))
+ return FALSE;
+ break;
+ case aarch64_stub_erratum_835769_veneer:
+ if (!elfNN_aarch64_output_stub_sym (osi, stub_name, addr,
+ sizeof (aarch64_erratum_835769_stub)))
+ return FALSE;
+ if (!elfNN_aarch64_output_map_sym (osi, AARCH64_MAP_INSN, addr))
+ return FALSE;
+ break;
+ default:
+ BFD_FAIL ();
+ }
+
+ return TRUE;
+}
+
+/* Output mapping symbols for linker generated sections. */
+
+static bfd_boolean
+elfNN_aarch64_output_arch_local_syms (bfd *output_bfd,
+ struct bfd_link_info *info,
+ void *finfo,
+ int (*func) (void *, const char *,
+ Elf_Internal_Sym *,
+ asection *,
+ struct elf_link_hash_entry
+ *))
+{
+ output_arch_syminfo osi;
+ struct elf_aarch64_link_hash_table *htab;
+
+ htab = elf_aarch64_hash_table (info);
+
+ osi.finfo = finfo;
+ osi.info = info;
+ osi.func = func;
+
+ /* Long calls stubs. */
+ if (htab->stub_bfd && htab->stub_bfd->sections)
+ {
+ asection *stub_sec;
+
+ for (stub_sec = htab->stub_bfd->sections;
+ stub_sec != NULL; stub_sec = stub_sec->next)
+ {
+ /* Ignore non-stub sections. */
+ if (!strstr (stub_sec->name, STUB_SUFFIX))
+ continue;
+
+ osi.sec = stub_sec;
+
+ osi.sec_shndx = _bfd_elf_section_from_bfd_section
+ (output_bfd, osi.sec->output_section);
+
+ bfd_hash_traverse (&htab->stub_hash_table, aarch64_map_one_stub,
+ &osi);
+ }
+ }
+
+ /* Finally, output mapping symbols for the PLT. */
+ if (!htab->root.splt || htab->root.splt->size == 0)
+ return TRUE;
+
+ /* For now live without mapping symbols for the plt. */
+ osi.sec_shndx = _bfd_elf_section_from_bfd_section
+ (output_bfd, htab->root.splt->output_section);
+ osi.sec = htab->root.splt;
+
+ elf_link_hash_traverse (&htab->root, elfNN_aarch64_output_plt_map,
+ (void *) &osi);
+
+ return TRUE;
+
+}
+
+/* Allocate target specific section data. */
+
+static bfd_boolean
+elfNN_aarch64_new_section_hook (bfd *abfd, asection *sec)
+{
+ if (!sec->used_by_bfd)
+ {
+ _aarch64_elf_section_data *sdata;
+ bfd_size_type amt = sizeof (*sdata);
+
+ sdata = bfd_zalloc (abfd, amt);
+ if (sdata == NULL)
+ return FALSE;
+ sec->used_by_bfd = sdata;
+ }
+
+ record_section_with_aarch64_elf_section_data (sec);
+
+ return _bfd_elf_new_section_hook (abfd, sec);
+}
+
+
+static void
+unrecord_section_via_map_over_sections (bfd *abfd ATTRIBUTE_UNUSED,
+ asection *sec,
+ void *ignore ATTRIBUTE_UNUSED)
+{
+ unrecord_section_with_aarch64_elf_section_data (sec);
+}
+
+static bfd_boolean
+elfNN_aarch64_close_and_cleanup (bfd *abfd)
+{
+ if (abfd->sections)
+ bfd_map_over_sections (abfd,
+ unrecord_section_via_map_over_sections, NULL);
+
+ return _bfd_elf_close_and_cleanup (abfd);
+}
+
+static bfd_boolean
+elfNN_aarch64_bfd_free_cached_info (bfd *abfd)
+{
+ if (abfd->sections)
+ bfd_map_over_sections (abfd,
+ unrecord_section_via_map_over_sections, NULL);
+
+ return _bfd_free_cached_info (abfd);
+}
+
+/* Create dynamic sections. This is different from the ARM backend in that
+ the got, plt, gotplt and their relocation sections are all created in the
+ standard part of the bfd elf backend. */
+
+static bfd_boolean
+elfNN_aarch64_create_dynamic_sections (bfd *dynobj,
+ struct bfd_link_info *info)
+{
+ struct elf_aarch64_link_hash_table *htab;
+
+ /* We need to create .got section. */
+ if (!aarch64_elf_create_got_section (dynobj, info))
+ return FALSE;
+
+ if (!_bfd_elf_create_dynamic_sections (dynobj, info))
+ return FALSE;
+
+ htab = elf_aarch64_hash_table (info);
+ htab->sdynbss = bfd_get_linker_section (dynobj, ".dynbss");
+ if (!info->shared)
+ htab->srelbss = bfd_get_linker_section (dynobj, ".rela.bss");
+
+ if (!htab->sdynbss || (!info->shared && !htab->srelbss))
+ abort ();
+
+ return TRUE;
+}
+
+
+/* Allocate space in .plt, .got and associated reloc sections for
+ dynamic relocs. */
+
+static bfd_boolean
+elfNN_aarch64_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
+{
+ struct bfd_link_info *info;
+ struct elf_aarch64_link_hash_table *htab;
+ struct elf_aarch64_link_hash_entry *eh;
+ struct elf_dyn_relocs *p;
+
+ /* An example of a bfd_link_hash_indirect symbol is versioned
+ symbol. For example: __gxx_personality_v0(bfd_link_hash_indirect)
+ -> __gxx_personality_v0(bfd_link_hash_defined)
+
+ There is no need to process bfd_link_hash_indirect symbols here
+ because we will also be presented with the concrete instance of
+ the symbol and elfNN_aarch64_copy_indirect_symbol () will have been
+ called to copy all relevant data from the generic to the concrete
+ symbol instance.
+ */
+ if (h->root.type == bfd_link_hash_indirect)
+ return TRUE;
+
+ if (h->root.type == bfd_link_hash_warning)
+ h = (struct elf_link_hash_entry *) h->root.u.i.link;
+
+ info = (struct bfd_link_info *) inf;
+ htab = elf_aarch64_hash_table (info);
+
+ /* Since STT_GNU_IFUNC symbol must go through PLT, we handle it
+ here if it is defined and referenced in a non-shared object. */
+ if (h->type == STT_GNU_IFUNC
+ && h->def_regular)
+ return TRUE;
+ else if (htab->root.dynamic_sections_created && h->plt.refcount > 0)
+ {
+ /* Make sure this symbol is output as a dynamic symbol.
+ Undefined weak syms won't yet be marked as dynamic. */
+ if (h->dynindx == -1 && !h->forced_local)
+ {
+ if (!bfd_elf_link_record_dynamic_symbol (info, h))
+ return FALSE;
+ }
+
+ if (info->shared || WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, 0, h))
+ {
+ asection *s = htab->root.splt;
+
+ /* If this is the first .plt entry, make room for the special
+ first entry. */
+ if (s->size == 0)
+ s->size += htab->plt_header_size;
+
+ h->plt.offset = s->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->def_regular)
+ {
+ h->root.u.def.section = s;
+ h->root.u.def.value = h->plt.offset;
+ }
+
+ /* Make room for this entry. For now we only create the
+ small model PLT entries. We later need to find a way
+ of relaxing into these from the large model PLT entries. */
+ s->size += PLT_SMALL_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. */
+ htab->root.sgotplt->size += GOT_ENTRY_SIZE;
+
+ /* We also need to make an entry in the .rela.plt section. */
+ htab->root.srelplt->size += RELOC_SIZE (htab);
+
+ /* We need to ensure that all GOT entries that serve the PLT
+ are consecutive with the special GOT slots [0] [1] and
+ [2]. Any addtional relocations, such as
+ R_AARCH64_TLSDESC, must be placed after the PLT related
+ entries. We abuse the reloc_count such that during
+ sizing we adjust reloc_count to indicate the number of
+ PLT related reserved entries. In subsequent phases when
+ filling in the contents of the reloc entries, PLT related
+ entries are placed by computing their PLT index (0
+ .. reloc_count). While other none PLT relocs are placed
+ at the slot indicated by reloc_count and reloc_count is
+ updated. */
+
+ htab->root.srelplt->reloc_count++;
+ }
+ else
+ {
+ h->plt.offset = (bfd_vma) - 1;
+ h->needs_plt = 0;
+ }
+ }
+ else
+ {
+ h->plt.offset = (bfd_vma) - 1;
+ h->needs_plt = 0;
+ }
+
+ eh = (struct elf_aarch64_link_hash_entry *) h;
+ eh->tlsdesc_got_jump_table_offset = (bfd_vma) - 1;
+
+ if (h->got.refcount > 0)
+ {
+ bfd_boolean dyn;
+ unsigned got_type = elf_aarch64_hash_entry (h)->got_type;
+
+ h->got.offset = (bfd_vma) - 1;
+
+ dyn = htab->root.dynamic_sections_created;
+
+ /* Make sure this symbol is output as a dynamic symbol.
+ Undefined weak syms won't yet be marked as dynamic. */
+ if (dyn && h->dynindx == -1 && !h->forced_local)
+ {
+ if (!bfd_elf_link_record_dynamic_symbol (info, h))
+ return FALSE;
+ }
+
+ if (got_type == GOT_UNKNOWN)
+ {
+ }
+ else if (got_type == GOT_NORMAL)
+ {
+ h->got.offset = htab->root.sgot->size;
+ htab->root.sgot->size += GOT_ENTRY_SIZE;
+ if ((ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
+ || h->root.type != bfd_link_hash_undefweak)
+ && (info->shared
+ || WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, 0, h)))
+ {
+ htab->root.srelgot->size += RELOC_SIZE (htab);
+ }
+ }
+ else
+ {
+ int indx;
+ if (got_type & GOT_TLSDESC_GD)
+ {
+ eh->tlsdesc_got_jump_table_offset =
+ (htab->root.sgotplt->size
+ - aarch64_compute_jump_table_size (htab));
+ htab->root.sgotplt->size += GOT_ENTRY_SIZE * 2;
+ h->got.offset = (bfd_vma) - 2;
+ }
+
+ if (got_type & GOT_TLS_GD)
+ {
+ h->got.offset = htab->root.sgot->size;
+ htab->root.sgot->size += GOT_ENTRY_SIZE * 2;
+ }
+
+ if (got_type & GOT_TLS_IE)
+ {
+ h->got.offset = htab->root.sgot->size;
+ htab->root.sgot->size += GOT_ENTRY_SIZE;
+ }
+
+ indx = h && h->dynindx != -1 ? h->dynindx : 0;
+ if ((ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
+ || h->root.type != bfd_link_hash_undefweak)
+ && (info->shared
+ || indx != 0
+ || WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, 0, h)))
+ {
+ if (got_type & GOT_TLSDESC_GD)
+ {
+ htab->root.srelplt->size += RELOC_SIZE (htab);
+ /* Note reloc_count not incremented here! We have
+ already adjusted reloc_count for this relocation
+ type. */
+
+ /* TLSDESC PLT is now needed, but not yet determined. */
+ htab->tlsdesc_plt = (bfd_vma) - 1;
+ }
+
+ if (got_type & GOT_TLS_GD)
+ htab->root.srelgot->size += RELOC_SIZE (htab) * 2;
+
+ if (got_type & GOT_TLS_IE)
+ htab->root.srelgot->size += RELOC_SIZE (htab);
+ }
+ }
+ }
+ else
+ {
+ h->got.offset = (bfd_vma) - 1;
+ }
+
+ if (eh->dyn_relocs == NULL)
+ return TRUE;
+
+ /* In the shared -Bsymbolic case, discard space allocated for
+ dynamic pc-relative relocs against symbols which turn out to be
+ defined in regular objects. For the normal shared case, discard
+ space for pc-relative relocs that have become local due to symbol
+ visibility changes. */
+
+ if (info->shared)
+ {
+ /* Relocs that use pc_count are those that appear on a call
+ insn, or certain REL relocs that can generated via assembly.
+ We want calls to protected symbols to resolve directly to the
+ function rather than going via the plt. If people want
+ function pointer comparisons to work as expected then they
+ should avoid writing weird assembly. */
+ if (SYMBOL_CALLS_LOCAL (info, h))
+ {
+ struct elf_dyn_relocs **pp;
+
+ for (pp = &eh->dyn_relocs; (p = *pp) != NULL;)
+ {
+ p->count -= p->pc_count;
+ p->pc_count = 0;
+ if (p->count == 0)
+ *pp = p->next;
+ else
+ pp = &p->next;
+ }
+ }
+
+ /* Also discard relocs on undefined weak syms with non-default
+ visibility. */
+ if (eh->dyn_relocs != NULL && h->root.type == bfd_link_hash_undefweak)
+ {
+ if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
+ eh->dyn_relocs = NULL;
+
+ /* Make sure undefined weak symbols are output as a dynamic
+ symbol in PIEs. */
+ else if (h->dynindx == -1
+ && !h->forced_local
+ && !bfd_elf_link_record_dynamic_symbol (info, h))
+ return FALSE;
+ }
+
+ }
+ else if (ELIMINATE_COPY_RELOCS)
+ {
+ /* For the non-shared case, discard space for relocs against
+ symbols which turn out to need copy relocs or are not
+ dynamic. */
+
+ if (!h->non_got_ref
+ && ((h->def_dynamic
+ && !h->def_regular)
+ || (htab->root.dynamic_sections_created
+ && (h->root.type == bfd_link_hash_undefweak
+ || h->root.type == bfd_link_hash_undefined))))
+ {
+ /* Make sure this symbol is output as a dynamic symbol.
+ Undefined weak syms won't yet be marked as dynamic. */
+ if (h->dynindx == -1
+ && !h->forced_local
+ && !bfd_elf_link_record_dynamic_symbol (info, h))
+ return FALSE;
+
+ /* If that succeeded, we know we'll be keeping all the
+ relocs. */
+ if (h->dynindx != -1)
+ goto keep;
+ }
+
+ eh->dyn_relocs = NULL;
+
+ keep:;
+ }
+
+ /* Finally, allocate space. */
+ for (p = eh->dyn_relocs; p != NULL; p = p->next)
+ {
+ asection *sreloc;
+
+ sreloc = elf_section_data (p->sec)->sreloc;
+
+ BFD_ASSERT (sreloc != NULL);
+
+ sreloc->size += p->count * RELOC_SIZE (htab);
+ }
+
+ return TRUE;
+}
+
+/* Allocate space in .plt, .got and associated reloc sections for
+ ifunc dynamic relocs. */
+
+static bfd_boolean
+elfNN_aarch64_allocate_ifunc_dynrelocs (struct elf_link_hash_entry *h,
+ void *inf)
+{
+ struct bfd_link_info *info;
+ struct elf_aarch64_link_hash_table *htab;
+ struct elf_aarch64_link_hash_entry *eh;
+
+ /* An example of a bfd_link_hash_indirect symbol is versioned
+ symbol. For example: __gxx_personality_v0(bfd_link_hash_indirect)
+ -> __gxx_personality_v0(bfd_link_hash_defined)
+
+ There is no need to process bfd_link_hash_indirect symbols here
+ because we will also be presented with the concrete instance of
+ the symbol and elfNN_aarch64_copy_indirect_symbol () will have been
+ called to copy all relevant data from the generic to the concrete
+ symbol instance.
+ */
+ if (h->root.type == bfd_link_hash_indirect)
+ return TRUE;
+
+ if (h->root.type == bfd_link_hash_warning)
+ h = (struct elf_link_hash_entry *) h->root.u.i.link;
+
+ info = (struct bfd_link_info *) inf;
+ htab = elf_aarch64_hash_table (info);
+
+ eh = (struct elf_aarch64_link_hash_entry *) h;
+
+ /* Since STT_GNU_IFUNC symbol must go through PLT, we handle it
+ here if it is defined and referenced in a non-shared object. */
+ if (h->type == STT_GNU_IFUNC
+ && h->def_regular)
+ return _bfd_elf_allocate_ifunc_dyn_relocs (info, h,
+ &eh->dyn_relocs,
+ htab->plt_entry_size,
+ htab->plt_header_size,
+ GOT_ENTRY_SIZE);
+ return TRUE;
+}
+
+/* Allocate space in .plt, .got and associated reloc sections for
+ local dynamic relocs. */
+
+static bfd_boolean
+elfNN_aarch64_allocate_local_dynrelocs (void **slot, void *inf)
+{
+ struct elf_link_hash_entry *h
+ = (struct elf_link_hash_entry *) *slot;
+
+ if (h->type != STT_GNU_IFUNC
+ || !h->def_regular
+ || !h->ref_regular
+ || !h->forced_local
+ || h->root.type != bfd_link_hash_defined)
+ abort ();
+
+ return elfNN_aarch64_allocate_dynrelocs (h, inf);
+}
+
+/* Allocate space in .plt, .got and associated reloc sections for
+ local ifunc dynamic relocs. */
+
+static bfd_boolean
+elfNN_aarch64_allocate_local_ifunc_dynrelocs (void **slot, void *inf)
+{
+ struct elf_link_hash_entry *h
+ = (struct elf_link_hash_entry *) *slot;
+
+ if (h->type != STT_GNU_IFUNC
+ || !h->def_regular
+ || !h->ref_regular
+ || !h->forced_local
+ || h->root.type != bfd_link_hash_defined)
+ abort ();
+
+ return elfNN_aarch64_allocate_ifunc_dynrelocs (h, inf);
+}
+
+/* This is the most important function of all . Innocuosly named
+ though ! */
+static bfd_boolean
+elfNN_aarch64_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
+ struct bfd_link_info *info)
+{
+ struct elf_aarch64_link_hash_table *htab;
+ bfd *dynobj;
+ asection *s;
+ bfd_boolean relocs;
+ bfd *ibfd;
+
+ htab = elf_aarch64_hash_table ((info));
+ dynobj = htab->root.dynobj;
+
+ BFD_ASSERT (dynobj != NULL);
+
+ if (htab->root.dynamic_sections_created)
+ {
+ if (info->executable)
+ {
+ s = bfd_get_linker_section (dynobj, ".interp");
+ if (s == NULL)
+ abort ();
+ s->size = sizeof ELF_DYNAMIC_INTERPRETER;
+ s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
+ }
+ }
+
+ /* Set up .got offsets for local syms, and space for local dynamic
+ relocs. */
+ for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next)
+ {
+ struct elf_aarch64_local_symbol *locals = NULL;
+ Elf_Internal_Shdr *symtab_hdr;
+ asection *srel;
+ unsigned int i;
+
+ if (!is_aarch64_elf (ibfd))
+ continue;
+
+ for (s = ibfd->sections; s != NULL; s = s->next)
+ {
+ struct elf_dyn_relocs *p;
+
+ for (p = (struct elf_dyn_relocs *)
+ (elf_section_data (s)->local_dynrel); p != NULL; p = p->next)
+ {
+ if (!bfd_is_abs_section (p->sec)
+ && bfd_is_abs_section (p->sec->output_section))
+ {
+ /* Input section has been discarded, either because
+ it is a copy of a linkonce section or due to
+ linker script /DISCARD/, so we'll be discarding
+ the relocs too. */
+ }
+ else if (p->count != 0)
+ {
+ srel = elf_section_data (p->sec)->sreloc;
+ srel->size += p->count * RELOC_SIZE (htab);
+ if ((p->sec->output_section->flags & SEC_READONLY) != 0)
+ info->flags |= DF_TEXTREL;
+ }
+ }
+ }
+
+ locals = elf_aarch64_locals (ibfd);
+ if (!locals)
+ continue;
+
+ symtab_hdr = &elf_symtab_hdr (ibfd);
+ srel = htab->root.srelgot;
+ for (i = 0; i < symtab_hdr->sh_info; i++)
+ {
+ locals[i].got_offset = (bfd_vma) - 1;
+ locals[i].tlsdesc_got_jump_table_offset = (bfd_vma) - 1;
+ if (locals[i].got_refcount > 0)
+ {
+ unsigned got_type = locals[i].got_type;
+ if (got_type & GOT_TLSDESC_GD)
+ {
+ locals[i].tlsdesc_got_jump_table_offset =
+ (htab->root.sgotplt->size
+ - aarch64_compute_jump_table_size (htab));
+ htab->root.sgotplt->size += GOT_ENTRY_SIZE * 2;
+ locals[i].got_offset = (bfd_vma) - 2;
+ }
+
+ if (got_type & GOT_TLS_GD)
+ {
+ locals[i].got_offset = htab->root.sgot->size;
+ htab->root.sgot->size += GOT_ENTRY_SIZE * 2;
+ }
+
+ if (got_type & GOT_TLS_IE)
+ {
+ locals[i].got_offset = htab->root.sgot->size;
+ htab->root.sgot->size += GOT_ENTRY_SIZE;
+ }
+
+ if (got_type == GOT_UNKNOWN)
+ {
+ }
+
+ if (got_type == GOT_NORMAL)
+ {
+ }
+
+ if (info->shared)
+ {
+ if (got_type & GOT_TLSDESC_GD)
+ {
+ htab->root.srelplt->size += RELOC_SIZE (htab);
+ /* Note RELOC_COUNT not incremented here! */
+ htab->tlsdesc_plt = (bfd_vma) - 1;
+ }
+
+ if (got_type & GOT_TLS_GD)
+ htab->root.srelgot->size += RELOC_SIZE (htab) * 2;
+
+ if (got_type & GOT_TLS_IE)
+ htab->root.srelgot->size += RELOC_SIZE (htab);
+ }
+ }
+ else
+ {
+ locals[i].got_refcount = (bfd_vma) - 1;
+ }
+ }
+ }
+
+
+ /* Allocate global sym .plt and .got entries, and space for global
+ sym dynamic relocs. */
+ elf_link_hash_traverse (&htab->root, elfNN_aarch64_allocate_dynrelocs,
+ info);
+
+ /* Allocate global ifunc sym .plt and .got entries, and space for global
+ ifunc sym dynamic relocs. */
+ elf_link_hash_traverse (&htab->root, elfNN_aarch64_allocate_ifunc_dynrelocs,
+ info);
+
+ /* Allocate .plt and .got entries, and space for local symbols. */
+ htab_traverse (htab->loc_hash_table,
+ elfNN_aarch64_allocate_local_dynrelocs,
+ info);
+
+ /* Allocate .plt and .got entries, and space for local ifunc symbols. */
+ htab_traverse (htab->loc_hash_table,
+ elfNN_aarch64_allocate_local_ifunc_dynrelocs,
+ info);
+
+ /* For every jump slot reserved in the sgotplt, reloc_count is
+ incremented. However, when we reserve space for TLS descriptors,
+ it's not incremented, so in order to compute the space reserved
+ for them, it suffices to multiply the reloc count by the jump
+ slot size. */
+
+ if (htab->root.srelplt)
+ htab->sgotplt_jump_table_size = aarch64_compute_jump_table_size (htab);
+
+ if (htab->tlsdesc_plt)
+ {
+ if (htab->root.splt->size == 0)
+ htab->root.splt->size += PLT_ENTRY_SIZE;
+
+ htab->tlsdesc_plt = htab->root.splt->size;
+ htab->root.splt->size += PLT_TLSDESC_ENTRY_SIZE;
+
+ /* If we're not using lazy TLS relocations, don't generate the
+ GOT entry required. */
+ if (!(info->flags & DF_BIND_NOW))
+ {
+ htab->dt_tlsdesc_got = htab->root.sgot->size;
+ htab->root.sgot->size += GOT_ENTRY_SIZE;
+ }
+ }
+
+ /* Init mapping symbols information to use later to distingush between
+ code and data while scanning for erratam 835769. */
+ if (htab->fix_erratum_835769)
+ for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next)
+ {
+ if (!is_aarch64_elf (ibfd))
+ continue;
+ bfd_elfNN_aarch64_init_maps (ibfd);
+ }
+
+ /* We now have determined the sizes of the various dynamic sections.
+ Allocate memory for them. */
+ relocs = FALSE;
+ for (s = dynobj->sections; s != NULL; s = s->next)
+ {
+ if ((s->flags & SEC_LINKER_CREATED) == 0)
+ continue;
+
+ if (s == htab->root.splt
+ || s == htab->root.sgot
+ || s == htab->root.sgotplt
+ || s == htab->root.iplt
+ || s == htab->root.igotplt || s == htab->sdynbss)
+ {
+ /* Strip this section if we don't need it; see the
+ comment below. */
+ }
+ else if (CONST_STRNEQ (bfd_get_section_name (dynobj, s), ".rela"))
+ {
+ if (s->size != 0 && s != htab->root.srelplt)
+ relocs = TRUE;
+
+ /* We use the reloc_count field as a counter if we need
+ to copy relocs into the output file. */
+ if (s != htab->root.srelplt)
+ s->reloc_count = 0;
+ }
+ else
+ {
+ /* It's not one of our sections, so don't allocate space. */
+ continue;
+ }
+
+ if (s->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. */
+
+ s->flags |= SEC_EXCLUDE;
+ continue;
+ }
+
+ if ((s->flags & SEC_HAS_CONTENTS) == 0)
+ continue;
+
+ /* Allocate memory for the section contents. We use bfd_zalloc
+ here in case unused entries are not reclaimed before the
+ section's contents are written out. This should not happen,
+ but this way if it does, we get a R_AARCH64_NONE reloc instead
+ of garbage. */
+ s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->size);
+ if (s->contents == NULL)
+ return FALSE;
+ }
+
+ if (htab->root.dynamic_sections_created)
+ {
+ /* Add some entries to the .dynamic section. We fill in the
+ values later, in elfNN_aarch64_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. */
+#define add_dynamic_entry(TAG, VAL) \
+ _bfd_elf_add_dynamic_entry (info, TAG, VAL)
+
+ if (info->executable)
+ {
+ if (!add_dynamic_entry (DT_DEBUG, 0))
+ return FALSE;
+ }
+
+ if (htab->root.splt->size != 0)
+ {
+ if (!add_dynamic_entry (DT_PLTGOT, 0)
+ || !add_dynamic_entry (DT_PLTRELSZ, 0)
+ || !add_dynamic_entry (DT_PLTREL, DT_RELA)
+ || !add_dynamic_entry (DT_JMPREL, 0))
+ return FALSE;
+
+ if (htab->tlsdesc_plt
+ && (!add_dynamic_entry (DT_TLSDESC_PLT, 0)
+ || !add_dynamic_entry (DT_TLSDESC_GOT, 0)))
+ return FALSE;
+ }
+
+ if (relocs)
+ {
+ if (!add_dynamic_entry (DT_RELA, 0)
+ || !add_dynamic_entry (DT_RELASZ, 0)
+ || !add_dynamic_entry (DT_RELAENT, RELOC_SIZE (htab)))
+ return FALSE;
+
+ /* If any dynamic relocs apply to a read-only section,
+ then we need a DT_TEXTREL entry. */
+ if ((info->flags & DF_TEXTREL) != 0)
+ {
+ if (!add_dynamic_entry (DT_TEXTREL, 0))
+ return FALSE;
+ }
+ }
+ }
+#undef add_dynamic_entry
+
+ return TRUE;
+}
+
+static inline void
+elf_aarch64_update_plt_entry (bfd *output_bfd,
+ bfd_reloc_code_real_type r_type,
+ bfd_byte *plt_entry, bfd_vma value)
+{
+ reloc_howto_type *howto = elfNN_aarch64_howto_from_bfd_reloc (r_type);
+
+ _bfd_aarch64_elf_put_addend (output_bfd, plt_entry, r_type, howto, value);
+}
+
+static void
+elfNN_aarch64_create_small_pltn_entry (struct elf_link_hash_entry *h,
+ struct elf_aarch64_link_hash_table
+ *htab, bfd *output_bfd,
+ struct bfd_link_info *info)
+{
+ bfd_byte *plt_entry;
+ bfd_vma plt_index;
+ bfd_vma got_offset;
+ bfd_vma gotplt_entry_address;
+ bfd_vma plt_entry_address;
+ Elf_Internal_Rela rela;
+ bfd_byte *loc;
+ asection *plt, *gotplt, *relplt;
+
+ /* When building a static executable, use .iplt, .igot.plt and
+ .rela.iplt sections for STT_GNU_IFUNC symbols. */
+ if (htab->root.splt != NULL)
+ {
+ plt = htab->root.splt;
+ gotplt = htab->root.sgotplt;
+ relplt = htab->root.srelplt;
+ }
+ else
+ {
+ plt = htab->root.iplt;
+ gotplt = htab->root.igotplt;
+ relplt = htab->root.irelplt;
+ }
+
+ /* 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.
+
+ Get the offset into the .got table of the entry that
+ corresponds to this function. Each .got entry is GOT_ENTRY_SIZE
+ bytes. The first three are reserved for the dynamic linker.
+
+ For static executables, we don't reserve anything. */
+
+ if (plt == htab->root.splt)
+ {
+ plt_index = (h->plt.offset - htab->plt_header_size) / htab->plt_entry_size;
+ got_offset = (plt_index + 3) * GOT_ENTRY_SIZE;
+ }
+ else
+ {
+ plt_index = h->plt.offset / htab->plt_entry_size;
+ got_offset = plt_index * GOT_ENTRY_SIZE;
+ }
+
+ plt_entry = plt->contents + h->plt.offset;
+ plt_entry_address = plt->output_section->vma
+ + plt->output_offset + h->plt.offset;
+ gotplt_entry_address = gotplt->output_section->vma +
+ gotplt->output_offset + got_offset;
+
+ /* Copy in the boiler-plate for the PLTn entry. */
+ memcpy (plt_entry, elfNN_aarch64_small_plt_entry, PLT_SMALL_ENTRY_SIZE);
+
+ /* Fill in the top 21 bits for this: ADRP x16, PLT_GOT + n * 8.
+ ADRP: ((PG(S+A)-PG(P)) >> 12) & 0x1fffff */
+ elf_aarch64_update_plt_entry (output_bfd, BFD_RELOC_AARCH64_ADR_HI21_PCREL,
+ plt_entry,
+ PG (gotplt_entry_address) -
+ PG (plt_entry_address));
+
+ /* Fill in the lo12 bits for the load from the pltgot. */
+ elf_aarch64_update_plt_entry (output_bfd, BFD_RELOC_AARCH64_LDSTNN_LO12,
+ plt_entry + 4,
+ PG_OFFSET (gotplt_entry_address));
+
+ /* Fill in the lo12 bits for the add from the pltgot entry. */
+ elf_aarch64_update_plt_entry (output_bfd, BFD_RELOC_AARCH64_ADD_LO12,
+ plt_entry + 8,
+ PG_OFFSET (gotplt_entry_address));
+
+ /* All the GOTPLT Entries are essentially initialized to PLT0. */
+ bfd_put_NN (output_bfd,
+ plt->output_section->vma + plt->output_offset,
+ gotplt->contents + got_offset);
+
+ rela.r_offset = gotplt_entry_address;
+
+ if (h->dynindx == -1
+ || ((info->executable
+ || ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
+ && h->def_regular
+ && h->type == STT_GNU_IFUNC))
+ {
+ /* If an STT_GNU_IFUNC symbol is locally defined, generate
+ R_AARCH64_IRELATIVE instead of R_AARCH64_JUMP_SLOT. */
+ rela.r_info = ELFNN_R_INFO (0, AARCH64_R (IRELATIVE));
+ rela.r_addend = (h->root.u.def.value
+ + h->root.u.def.section->output_section->vma
+ + h->root.u.def.section->output_offset);
+ }
+ else
+ {
+ /* Fill in the entry in the .rela.plt section. */
+ rela.r_info = ELFNN_R_INFO (h->dynindx, AARCH64_R (JUMP_SLOT));
+ rela.r_addend = 0;
+ }
+
+ /* Compute the relocation entry to used based on PLT index and do
+ not adjust reloc_count. The reloc_count has already been adjusted
+ to account for this entry. */
+ loc = relplt->contents + plt_index * RELOC_SIZE (htab);
+ bfd_elfNN_swap_reloca_out (output_bfd, &rela, loc);
+}
+
+/* Size sections even though they're not dynamic. We use it to setup
+ _TLS_MODULE_BASE_, if needed. */
+
+static bfd_boolean
+elfNN_aarch64_always_size_sections (bfd *output_bfd,
+ struct bfd_link_info *info)
+{
+ asection *tls_sec;
+
+ if (info->relocatable)
+ return TRUE;
+
+ tls_sec = elf_hash_table (info)->tls_sec;
+
+ if (tls_sec)
+ {
+ struct elf_link_hash_entry *tlsbase;
+
+ tlsbase = elf_link_hash_lookup (elf_hash_table (info),
+ "_TLS_MODULE_BASE_", TRUE, TRUE, FALSE);
+
+ if (tlsbase)
+ {
+ struct bfd_link_hash_entry *h = NULL;
+ const struct elf_backend_data *bed =
+ get_elf_backend_data (output_bfd);
+
+ if (!(_bfd_generic_link_add_one_symbol
+ (info, output_bfd, "_TLS_MODULE_BASE_", BSF_LOCAL,
+ tls_sec, 0, NULL, FALSE, bed->collect, &h)))
+ return FALSE;
+
+ tlsbase->type = STT_TLS;
+ tlsbase = (struct elf_link_hash_entry *) h;
+ tlsbase->def_regular = 1;
+ tlsbase->other = STV_HIDDEN;
+ (*bed->elf_backend_hide_symbol) (info, tlsbase, TRUE);
+ }
+ }
+
+ return TRUE;
+}
+
+/* Finish up dynamic symbol handling. We set the contents of various
+ dynamic sections here. */
+static bfd_boolean
+elfNN_aarch64_finish_dynamic_symbol (bfd *output_bfd,
+ struct bfd_link_info *info,
+ struct elf_link_hash_entry *h,
+ Elf_Internal_Sym *sym)
+{
+ struct elf_aarch64_link_hash_table *htab;
+ htab = elf_aarch64_hash_table (info);
+
+ if (h->plt.offset != (bfd_vma) - 1)
+ {
+ asection *plt, *gotplt, *relplt;
+
+ /* This symbol has an entry in the procedure linkage table. Set
+ it up. */
+
+ /* When building a static executable, use .iplt, .igot.plt and
+ .rela.iplt sections for STT_GNU_IFUNC symbols. */
+ if (htab->root.splt != NULL)
+ {
+ plt = htab->root.splt;
+ gotplt = htab->root.sgotplt;
+ relplt = htab->root.srelplt;
+ }
+ else
+ {
+ plt = htab->root.iplt;
+ gotplt = htab->root.igotplt;
+ relplt = htab->root.irelplt;
+ }
+
+ /* This symbol has an entry in the procedure linkage table. Set
+ it up. */
+ if ((h->dynindx == -1
+ && !((h->forced_local || info->executable)
+ && h->def_regular
+ && h->type == STT_GNU_IFUNC))
+ || plt == NULL
+ || gotplt == NULL
+ || relplt == NULL)
+ abort ();
+
+ elfNN_aarch64_create_small_pltn_entry (h, htab, output_bfd, info);
+ if (!h->def_regular)
+ {
+ /* Mark the symbol as undefined, rather than as defined in
+ the .plt section. Leave the value alone. This is a clue
+ for the dynamic linker, to make function pointer
+ comparisons work between an application and shared
+ library. */
+ sym->st_shndx = SHN_UNDEF;
+ }
+ }
+
+ if (h->got.offset != (bfd_vma) - 1
+ && elf_aarch64_hash_entry (h)->got_type == GOT_NORMAL)
+ {
+ Elf_Internal_Rela rela;
+ bfd_byte *loc;
+
+ /* This symbol has an entry in the global offset table. Set it
+ up. */
+ if (htab->root.sgot == NULL || htab->root.srelgot == NULL)
+ abort ();
+
+ rela.r_offset = (htab->root.sgot->output_section->vma
+ + htab->root.sgot->output_offset
+ + (h->got.offset & ~(bfd_vma) 1));
+
+ if (h->def_regular
+ && h->type == STT_GNU_IFUNC)
+ {
+ if (info->shared)
+ {
+ /* Generate R_AARCH64_GLOB_DAT. */
+ goto do_glob_dat;
+ }
+ else
+ {
+ asection *plt;
+
+ if (!h->pointer_equality_needed)
+ abort ();
+
+ /* For non-shared object, we can't use .got.plt, which
+ contains the real function address if we need pointer
+ equality. We load the GOT entry with the PLT entry. */
+ plt = htab->root.splt ? htab->root.splt : htab->root.iplt;
+ bfd_put_NN (output_bfd, (plt->output_section->vma
+ + plt->output_offset
+ + h->plt.offset),
+ htab->root.sgot->contents
+ + (h->got.offset & ~(bfd_vma) 1));
+ return TRUE;
+ }
+ }
+ else if (info->shared && SYMBOL_REFERENCES_LOCAL (info, h))
+ {
+ if (!h->def_regular)
+ return FALSE;
+
+ BFD_ASSERT ((h->got.offset & 1) != 0);
+ rela.r_info = ELFNN_R_INFO (0, AARCH64_R (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
+ {
+do_glob_dat:
+ BFD_ASSERT ((h->got.offset & 1) == 0);
+ bfd_put_NN (output_bfd, (bfd_vma) 0,
+ htab->root.sgot->contents + h->got.offset);
+ rela.r_info = ELFNN_R_INFO (h->dynindx, AARCH64_R (GLOB_DAT));
+ rela.r_addend = 0;
+ }
+
+ loc = htab->root.srelgot->contents;
+ loc += htab->root.srelgot->reloc_count++ * RELOC_SIZE (htab);
+ bfd_elfNN_swap_reloca_out (output_bfd, &rela, loc);
+ }
+
+ if (h->needs_copy)
+ {
+ Elf_Internal_Rela rela;
+ bfd_byte *loc;
+
+ /* This symbol needs a copy reloc. Set it up. */
+
+ if (h->dynindx == -1
+ || (h->root.type != bfd_link_hash_defined
+ && h->root.type != bfd_link_hash_defweak)
+ || htab->srelbss == NULL)
+ abort ();
+
+ 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 = ELFNN_R_INFO (h->dynindx, AARCH64_R (COPY));
+ rela.r_addend = 0;
+ loc = htab->srelbss->contents;
+ loc += htab->srelbss->reloc_count++ * RELOC_SIZE (htab);
+ bfd_elfNN_swap_reloca_out (output_bfd, &rela, loc);
+ }
+
+ /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute. SYM may
+ be NULL for local symbols. */
+ if (sym != NULL
+ && (h == elf_hash_table (info)->hdynamic
+ || h == elf_hash_table (info)->hgot))
+ sym->st_shndx = SHN_ABS;
+
+ return TRUE;
+}
+
+/* Finish up local dynamic symbol handling. We set the contents of
+ various dynamic sections here. */
+
+static bfd_boolean
+elfNN_aarch64_finish_local_dynamic_symbol (void **slot, void *inf)
+{
+ struct elf_link_hash_entry *h
+ = (struct elf_link_hash_entry *) *slot;
+ struct bfd_link_info *info
+ = (struct bfd_link_info *) inf;
+
+ return elfNN_aarch64_finish_dynamic_symbol (info->output_bfd,
+ info, h, NULL);
+}
+
+static void
+elfNN_aarch64_init_small_plt0_entry (bfd *output_bfd ATTRIBUTE_UNUSED,
+ struct elf_aarch64_link_hash_table
+ *htab)
+{
+ /* Fill in PLT0. Fixme:RR Note this doesn't distinguish between
+ small and large plts and at the minute just generates
+ the small PLT. */
+
+ /* PLT0 of the small PLT looks like this in ELF64 -
+ stp x16, x30, [sp, #-16]! // Save the reloc and lr on stack.
+ adrp x16, PLT_GOT + 16 // Get the page base of the GOTPLT
+ ldr x17, [x16, #:lo12:PLT_GOT+16] // Load the address of the
+ // symbol resolver
+ add x16, x16, #:lo12:PLT_GOT+16 // Load the lo12 bits of the
+ // GOTPLT entry for this.
+ br x17
+ PLT0 will be slightly different in ELF32 due to different got entry
+ size.
+ */
+ bfd_vma plt_got_2nd_ent; /* Address of GOT[2]. */
+ bfd_vma plt_base;
+
+
+ memcpy (htab->root.splt->contents, elfNN_aarch64_small_plt0_entry,
+ PLT_ENTRY_SIZE);
+ elf_section_data (htab->root.splt->output_section)->this_hdr.sh_entsize =
+ PLT_ENTRY_SIZE;
+
+ plt_got_2nd_ent = (htab->root.sgotplt->output_section->vma
+ + htab->root.sgotplt->output_offset
+ + GOT_ENTRY_SIZE * 2);
+
+ plt_base = htab->root.splt->output_section->vma +
+ htab->root.splt->output_offset;
+
+ /* Fill in the top 21 bits for this: ADRP x16, PLT_GOT + n * 8.
+ ADRP: ((PG(S+A)-PG(P)) >> 12) & 0x1fffff */
+ elf_aarch64_update_plt_entry (output_bfd, BFD_RELOC_AARCH64_ADR_HI21_PCREL,
+ htab->root.splt->contents + 4,
+ PG (plt_got_2nd_ent) - PG (plt_base + 4));
+
+ elf_aarch64_update_plt_entry (output_bfd, BFD_RELOC_AARCH64_LDSTNN_LO12,
+ htab->root.splt->contents + 8,
+ PG_OFFSET (plt_got_2nd_ent));
+
+ elf_aarch64_update_plt_entry (output_bfd, BFD_RELOC_AARCH64_ADD_LO12,
+ htab->root.splt->contents + 12,
+ PG_OFFSET (plt_got_2nd_ent));
+}
+
+static bfd_boolean
+elfNN_aarch64_finish_dynamic_sections (bfd *output_bfd,
+ struct bfd_link_info *info)
+{
+ struct elf_aarch64_link_hash_table *htab;
+ bfd *dynobj;
+ asection *sdyn;
+
+ htab = elf_aarch64_hash_table (info);
+ dynobj = htab->root.dynobj;
+ sdyn = bfd_get_linker_section (dynobj, ".dynamic");
+
+ if (htab->root.dynamic_sections_created)
+ {
+ ElfNN_External_Dyn *dyncon, *dynconend;
+
+ if (sdyn == NULL || htab->root.sgot == NULL)
+ abort ();
+
+ dyncon = (ElfNN_External_Dyn *) sdyn->contents;
+ dynconend = (ElfNN_External_Dyn *) (sdyn->contents + sdyn->size);
+ for (; dyncon < dynconend; dyncon++)
+ {
+ Elf_Internal_Dyn dyn;
+ asection *s;
+
+ bfd_elfNN_swap_dyn_in (dynobj, dyncon, &dyn);
+
+ switch (dyn.d_tag)
+ {
+ default:
+ continue;
+
+ case DT_PLTGOT:
+ s = htab->root.sgotplt;
+ dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
+ break;
+
+ case DT_JMPREL:
+ dyn.d_un.d_ptr = htab->root.srelplt->output_section->vma;
+ break;
+
+ case DT_PLTRELSZ:
+ s = htab->root.srelplt;
+ dyn.d_un.d_val = s->size;
+ 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. */
+ if (htab->root.srelplt != NULL)
+ {
+ s = htab->root.srelplt;
+ dyn.d_un.d_val -= s->size;
+ }
+ break;
+
+ case DT_TLSDESC_PLT:
+ s = htab->root.splt;
+ dyn.d_un.d_ptr = s->output_section->vma + s->output_offset
+ + htab->tlsdesc_plt;
+ break;
+
+ case DT_TLSDESC_GOT:
+ s = htab->root.sgot;
+ dyn.d_un.d_ptr = s->output_section->vma + s->output_offset
+ + htab->dt_tlsdesc_got;
+ break;
+ }
+
+ bfd_elfNN_swap_dyn_out (output_bfd, &dyn, dyncon);
+ }
+
+ }
+
+ /* Fill in the special first entry in the procedure linkage table. */
+ if (htab->root.splt && htab->root.splt->size > 0)
+ {
+ elfNN_aarch64_init_small_plt0_entry (output_bfd, htab);
+
+ elf_section_data (htab->root.splt->output_section)->
+ this_hdr.sh_entsize = htab->plt_entry_size;
+
+
+ if (htab->tlsdesc_plt)
+ {
+ bfd_put_NN (output_bfd, (bfd_vma) 0,
+ htab->root.sgot->contents + htab->dt_tlsdesc_got);
+
+ memcpy (htab->root.splt->contents + htab->tlsdesc_plt,
+ elfNN_aarch64_tlsdesc_small_plt_entry,
+ sizeof (elfNN_aarch64_tlsdesc_small_plt_entry));
+
+ {
+ bfd_vma adrp1_addr =
+ htab->root.splt->output_section->vma
+ + htab->root.splt->output_offset + htab->tlsdesc_plt + 4;
+
+ bfd_vma adrp2_addr = adrp1_addr + 4;
+
+ bfd_vma got_addr =
+ htab->root.sgot->output_section->vma
+ + htab->root.sgot->output_offset;
+
+ bfd_vma pltgot_addr =
+ htab->root.sgotplt->output_section->vma
+ + htab->root.sgotplt->output_offset;
+
+ bfd_vma dt_tlsdesc_got = got_addr + htab->dt_tlsdesc_got;
+
+ bfd_byte *plt_entry =
+ htab->root.splt->contents + htab->tlsdesc_plt;
+
+ /* adrp x2, DT_TLSDESC_GOT */
+ elf_aarch64_update_plt_entry (output_bfd,
+ BFD_RELOC_AARCH64_ADR_HI21_PCREL,
+ plt_entry + 4,
+ (PG (dt_tlsdesc_got)
+ - PG (adrp1_addr)));
+
+ /* adrp x3, 0 */
+ elf_aarch64_update_plt_entry (output_bfd,
+ BFD_RELOC_AARCH64_ADR_HI21_PCREL,
+ plt_entry + 8,
+ (PG (pltgot_addr)
+ - PG (adrp2_addr)));
+
+ /* ldr x2, [x2, #0] */
+ elf_aarch64_update_plt_entry (output_bfd,
+ BFD_RELOC_AARCH64_LDSTNN_LO12,
+ plt_entry + 12,
+ PG_OFFSET (dt_tlsdesc_got));
+
+ /* add x3, x3, 0 */
+ elf_aarch64_update_plt_entry (output_bfd,
+ BFD_RELOC_AARCH64_ADD_LO12,
+ plt_entry + 16,
+ PG_OFFSET (pltgot_addr));
+ }
+ }
+ }
+
+ if (htab->root.sgotplt)
+ {
+ if (bfd_is_abs_section (htab->root.sgotplt->output_section))
+ {
+ (*_bfd_error_handler)
+ (_("discarded output section: `%A'"), htab->root.sgotplt);
+ return FALSE;
+ }
+
+ /* Fill in the first three entries in the global offset table. */
+ if (htab->root.sgotplt->size > 0)
+ {
+ bfd_put_NN (output_bfd, (bfd_vma) 0, htab->root.sgotplt->contents);
+
+ /* Write GOT[1] and GOT[2], needed for the dynamic linker. */
+ bfd_put_NN (output_bfd,
+ (bfd_vma) 0,
+ htab->root.sgotplt->contents + GOT_ENTRY_SIZE);
+ bfd_put_NN (output_bfd,
+ (bfd_vma) 0,
+ htab->root.sgotplt->contents + GOT_ENTRY_SIZE * 2);
+ }
+
+ if (htab->root.sgot)
+ {
+ if (htab->root.sgot->size > 0)
+ {
+ bfd_vma addr =
+ sdyn ? sdyn->output_section->vma + sdyn->output_offset : 0;
+ bfd_put_NN (output_bfd, addr, htab->root.sgot->contents);
+ }
+ }
+
+ elf_section_data (htab->root.sgotplt->output_section)->
+ this_hdr.sh_entsize = GOT_ENTRY_SIZE;
+ }
+
+ if (htab->root.sgot && htab->root.sgot->size > 0)
+ elf_section_data (htab->root.sgot->output_section)->this_hdr.sh_entsize
+ = GOT_ENTRY_SIZE;
+
+ /* Fill PLT and GOT entries for local STT_GNU_IFUNC symbols. */
+ htab_traverse (htab->loc_hash_table,
+ elfNN_aarch64_finish_local_dynamic_symbol,
+ info);
+
+ return TRUE;
+}
+
+/* Return address for Ith PLT stub in section PLT, for relocation REL
+ or (bfd_vma) -1 if it should not be included. */
+
+static bfd_vma
+elfNN_aarch64_plt_sym_val (bfd_vma i, const asection *plt,
+ const arelent *rel ATTRIBUTE_UNUSED)
+{
+ return plt->vma + PLT_ENTRY_SIZE + i * PLT_SMALL_ENTRY_SIZE;
+}
+
+
+/* We use this so we can override certain functions
+ (though currently we don't). */
+
+const struct elf_size_info elfNN_aarch64_size_info =
+{
+ sizeof (ElfNN_External_Ehdr),
+ sizeof (ElfNN_External_Phdr),
+ sizeof (ElfNN_External_Shdr),
+ sizeof (ElfNN_External_Rel),
+ sizeof (ElfNN_External_Rela),
+ sizeof (ElfNN_External_Sym),
+ sizeof (ElfNN_External_Dyn),
+ sizeof (Elf_External_Note),
+ 4, /* Hash table entry size. */
+ 1, /* Internal relocs per external relocs. */
+ ARCH_SIZE, /* Arch size. */
+ LOG_FILE_ALIGN, /* Log_file_align. */
+ ELFCLASSNN, EV_CURRENT,
+ bfd_elfNN_write_out_phdrs,
+ bfd_elfNN_write_shdrs_and_ehdr,
+ bfd_elfNN_checksum_contents,
+ bfd_elfNN_write_relocs,
+ bfd_elfNN_swap_symbol_in,
+ bfd_elfNN_swap_symbol_out,
+ bfd_elfNN_slurp_reloc_table,
+ bfd_elfNN_slurp_symbol_table,
+ bfd_elfNN_swap_dyn_in,
+ bfd_elfNN_swap_dyn_out,
+ bfd_elfNN_swap_reloc_in,
+ bfd_elfNN_swap_reloc_out,
+ bfd_elfNN_swap_reloca_in,
+ bfd_elfNN_swap_reloca_out
+};
+
+#define ELF_ARCH bfd_arch_aarch64
+#define ELF_MACHINE_CODE EM_AARCH64
+#define ELF_MAXPAGESIZE 0x10000
+#define ELF_MINPAGESIZE 0x1000
+#define ELF_COMMONPAGESIZE 0x1000
+
+#define bfd_elfNN_close_and_cleanup \
+ elfNN_aarch64_close_and_cleanup
+
+#define bfd_elfNN_bfd_free_cached_info \
+ elfNN_aarch64_bfd_free_cached_info
+
+#define bfd_elfNN_bfd_is_target_special_symbol \
+ elfNN_aarch64_is_target_special_symbol
+
+#define bfd_elfNN_bfd_link_hash_table_create \
+ elfNN_aarch64_link_hash_table_create
+
+#define bfd_elfNN_bfd_merge_private_bfd_data \
+ elfNN_aarch64_merge_private_bfd_data
+
+#define bfd_elfNN_bfd_print_private_bfd_data \
+ elfNN_aarch64_print_private_bfd_data
+
+#define bfd_elfNN_bfd_reloc_type_lookup \
+ elfNN_aarch64_reloc_type_lookup
+
+#define bfd_elfNN_bfd_reloc_name_lookup \
+ elfNN_aarch64_reloc_name_lookup
+
+#define bfd_elfNN_bfd_set_private_flags \
+ elfNN_aarch64_set_private_flags
+
+#define bfd_elfNN_find_inliner_info \
+ elfNN_aarch64_find_inliner_info
+
+#define bfd_elfNN_find_nearest_line \
+ elfNN_aarch64_find_nearest_line
+
+#define bfd_elfNN_mkobject \
+ elfNN_aarch64_mkobject
+
+#define bfd_elfNN_new_section_hook \
+ elfNN_aarch64_new_section_hook
+
+#define elf_backend_adjust_dynamic_symbol \
+ elfNN_aarch64_adjust_dynamic_symbol
+
+#define elf_backend_always_size_sections \
+ elfNN_aarch64_always_size_sections
+
+#define elf_backend_check_relocs \
+ elfNN_aarch64_check_relocs
+
+#define elf_backend_copy_indirect_symbol \
+ elfNN_aarch64_copy_indirect_symbol
+
+/* Create .dynbss, and .rela.bss sections in DYNOBJ, and set up shortcuts
+ to them in our hash. */
+#define elf_backend_create_dynamic_sections \
+ elfNN_aarch64_create_dynamic_sections
+
+#define elf_backend_init_index_section \
+ _bfd_elf_init_2_index_sections
+
+#define elf_backend_finish_dynamic_sections \
+ elfNN_aarch64_finish_dynamic_sections
+
+#define elf_backend_finish_dynamic_symbol \
+ elfNN_aarch64_finish_dynamic_symbol
+
+#define elf_backend_gc_sweep_hook \
+ elfNN_aarch64_gc_sweep_hook
+
+#define elf_backend_object_p \
+ elfNN_aarch64_object_p
+
+#define elf_backend_output_arch_local_syms \
+ elfNN_aarch64_output_arch_local_syms
+
+#define elf_backend_plt_sym_val \
+ elfNN_aarch64_plt_sym_val
+
+#define elf_backend_post_process_headers \
+ elfNN_aarch64_post_process_headers
+
+#define elf_backend_relocate_section \
+ elfNN_aarch64_relocate_section
+
+#define elf_backend_reloc_type_class \
+ elfNN_aarch64_reloc_type_class
+
+#define elf_backend_section_from_shdr \
+ elfNN_aarch64_section_from_shdr
+
+#define elf_backend_size_dynamic_sections \
+ elfNN_aarch64_size_dynamic_sections
+
+#define elf_backend_size_info \
+ elfNN_aarch64_size_info
+
+#define elf_backend_write_section \
+ elfNN_aarch64_write_section
+
+#define elf_backend_can_refcount 1
+#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
+#define elf_backend_may_use_rel_p 0
+#define elf_backend_may_use_rela_p 1
+#define elf_backend_default_use_rela_p 1
+#define elf_backend_rela_normal 1
+#define elf_backend_got_header_size (GOT_ENTRY_SIZE * 3)
+#define elf_backend_default_execstack 0
+
+#undef elf_backend_obj_attrs_section
+#define elf_backend_obj_attrs_section ".ARM.attributes"
+
+#include "elfNN-target.h"
diff --git a/bfd/elfnn-ia64.c b/bfd/elfnn-ia64.c
new file mode 100644
index 0000000..a8d8d0b
--- /dev/null
+++ b/bfd/elfnn-ia64.c
@@ -0,0 +1,5110 @@
+/* IA-64 support for 64-bit ELF
+ Copyright (C) 1998-2014 Free Software Foundation, Inc.
+ Contributed by David Mosberger-Tang <davidm@hpl.hp.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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+#include "elf-bfd.h"
+#include "opcode/ia64.h"
+#include "elf/ia64.h"
+#include "objalloc.h"
+#include "hashtab.h"
+#include "bfd_stdint.h"
+#include "elfxx-ia64.h"
+
+#define ARCH_SIZE NN
+
+#if ARCH_SIZE == 64
+#define LOG_SECTION_ALIGN 3
+#endif
+
+#if ARCH_SIZE == 32
+#define LOG_SECTION_ALIGN 2
+#endif
+
+typedef struct bfd_hash_entry *(*new_hash_entry_func)
+ (struct bfd_hash_entry *, struct bfd_hash_table *, const char *);
+
+/* In dynamically (linker-) created sections, we generally need to keep track
+ of the place a symbol or expression got allocated to. This is done via hash
+ tables that store entries of the following type. */
+
+struct elfNN_ia64_dyn_sym_info
+{
+ /* The addend for which this entry is relevant. */
+ bfd_vma addend;
+
+ bfd_vma got_offset;
+ bfd_vma fptr_offset;
+ bfd_vma pltoff_offset;
+ bfd_vma plt_offset;
+ bfd_vma plt2_offset;
+ bfd_vma tprel_offset;
+ bfd_vma dtpmod_offset;
+ bfd_vma dtprel_offset;
+
+ /* The symbol table entry, if any, that this was derived from. */
+ struct elf_link_hash_entry *h;
+
+ /* Used to count non-got, non-plt relocations for delayed sizing
+ of relocation sections. */
+ struct elfNN_ia64_dyn_reloc_entry
+ {
+ struct elfNN_ia64_dyn_reloc_entry *next;
+ asection *srel;
+ int type;
+ int count;
+
+ /* Is this reloc against readonly section? */
+ bfd_boolean reltext;
+ } *reloc_entries;
+
+ /* TRUE when the section contents have been updated. */
+ unsigned got_done : 1;
+ unsigned fptr_done : 1;
+ unsigned pltoff_done : 1;
+ unsigned tprel_done : 1;
+ unsigned dtpmod_done : 1;
+ unsigned dtprel_done : 1;
+
+ /* TRUE for the different kinds of linker data we want created. */
+ unsigned want_got : 1;
+ unsigned want_gotx : 1;
+ unsigned want_fptr : 1;
+ unsigned want_ltoff_fptr : 1;
+ unsigned want_plt : 1;
+ unsigned want_plt2 : 1;
+ unsigned want_pltoff : 1;
+ unsigned want_tprel : 1;
+ unsigned want_dtpmod : 1;
+ unsigned want_dtprel : 1;
+};
+
+struct elfNN_ia64_local_hash_entry
+{
+ int id;
+ unsigned int r_sym;
+ /* The number of elements in elfNN_ia64_dyn_sym_info array. */
+ unsigned int count;
+ /* The number of sorted elements in elfNN_ia64_dyn_sym_info array. */
+ unsigned int sorted_count;
+ /* The size of elfNN_ia64_dyn_sym_info array. */
+ unsigned int size;
+ /* The array of elfNN_ia64_dyn_sym_info. */
+ struct elfNN_ia64_dyn_sym_info *info;
+
+ /* TRUE if this hash entry's addends was translated for
+ SHF_MERGE optimization. */
+ unsigned sec_merge_done : 1;
+};
+
+struct elfNN_ia64_link_hash_entry
+{
+ struct elf_link_hash_entry root;
+ /* The number of elements in elfNN_ia64_dyn_sym_info array. */
+ unsigned int count;
+ /* The number of sorted elements in elfNN_ia64_dyn_sym_info array. */
+ unsigned int sorted_count;
+ /* The size of elfNN_ia64_dyn_sym_info array. */
+ unsigned int size;
+ /* The array of elfNN_ia64_dyn_sym_info. */
+ struct elfNN_ia64_dyn_sym_info *info;
+};
+
+struct elfNN_ia64_link_hash_table
+{
+ /* The main hash table. */
+ struct elf_link_hash_table root;
+
+ asection *fptr_sec; /* Function descriptor table (or NULL). */
+ asection *rel_fptr_sec; /* Dynamic relocation section for same. */
+ asection *pltoff_sec; /* Private descriptors for plt (or NULL). */
+ asection *rel_pltoff_sec; /* Dynamic relocation section for same. */
+
+ bfd_size_type minplt_entries; /* Number of minplt entries. */
+ unsigned reltext : 1; /* Are there relocs against readonly sections? */
+ unsigned self_dtpmod_done : 1;/* Has self DTPMOD entry been finished? */
+ bfd_vma self_dtpmod_offset; /* .got offset to self DTPMOD entry. */
+ /* There are maybe R_IA64_GPREL22 relocations, including those
+ optimized from R_IA64_LTOFF22X, against non-SHF_IA_64_SHORT
+ sections. We need to record those sections so that we can choose
+ a proper GP to cover all R_IA64_GPREL22 relocations. */
+ asection *max_short_sec; /* Maximum short output section. */
+ bfd_vma max_short_offset; /* Maximum short offset. */
+ asection *min_short_sec; /* Minimum short output section. */
+ bfd_vma min_short_offset; /* Minimum short offset. */
+
+ htab_t loc_hash_table;
+ void *loc_hash_memory;
+};
+
+struct elfNN_ia64_allocate_data
+{
+ struct bfd_link_info *info;
+ bfd_size_type ofs;
+ bfd_boolean only_got;
+};
+
+#define elfNN_ia64_hash_table(p) \
+ (elf_hash_table_id ((struct elf_link_hash_table *) ((p)->hash)) \
+ == IA64_ELF_DATA ? ((struct elfNN_ia64_link_hash_table *) ((p)->hash)) : NULL)
+
+static struct elfNN_ia64_dyn_sym_info * get_dyn_sym_info
+ (struct elfNN_ia64_link_hash_table *ia64_info,
+ struct elf_link_hash_entry *h,
+ bfd *abfd, const Elf_Internal_Rela *rel, bfd_boolean create);
+static bfd_boolean elfNN_ia64_dynamic_symbol_p
+ (struct elf_link_hash_entry *h, struct bfd_link_info *info, int);
+static bfd_boolean elfNN_ia64_choose_gp
+ (bfd *abfd, struct bfd_link_info *info, bfd_boolean final);
+static void elfNN_ia64_dyn_sym_traverse
+ (struct elfNN_ia64_link_hash_table *ia64_info,
+ bfd_boolean (*func) (struct elfNN_ia64_dyn_sym_info *, void *),
+ void * info);
+static bfd_boolean allocate_global_data_got
+ (struct elfNN_ia64_dyn_sym_info *dyn_i, void * data);
+static bfd_boolean allocate_global_fptr_got
+ (struct elfNN_ia64_dyn_sym_info *dyn_i, void * data);
+static bfd_boolean allocate_local_got
+ (struct elfNN_ia64_dyn_sym_info *dyn_i, void * data);
+static bfd_boolean elfNN_ia64_hpux_vec
+ (const bfd_target *vec);
+static bfd_boolean allocate_dynrel_entries
+ (struct elfNN_ia64_dyn_sym_info *dyn_i, void * data);
+static asection *get_pltoff
+ (bfd *abfd, struct bfd_link_info *info,
+ struct elfNN_ia64_link_hash_table *ia64_info);
+
+/* ia64-specific relocation. */
+
+/* Given a ELF reloc, return the matching HOWTO structure. */
+
+static void
+elfNN_ia64_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED,
+ arelent *bfd_reloc,
+ Elf_Internal_Rela *elf_reloc)
+{
+ bfd_reloc->howto
+ = ia64_elf_lookup_howto ((unsigned int) ELFNN_R_TYPE (elf_reloc->r_info));
+}
+
+#define PLT_HEADER_SIZE (3 * 16)
+#define PLT_MIN_ENTRY_SIZE (1 * 16)
+#define PLT_FULL_ENTRY_SIZE (2 * 16)
+#define PLT_RESERVED_WORDS 3
+
+static const bfd_byte plt_header[PLT_HEADER_SIZE] =
+{
+ 0x0b, 0x10, 0x00, 0x1c, 0x00, 0x21, /* [MMI] mov r2=r14;; */
+ 0xe0, 0x00, 0x08, 0x00, 0x48, 0x00, /* addl r14=0,r2 */
+ 0x00, 0x00, 0x04, 0x00, /* nop.i 0x0;; */
+ 0x0b, 0x80, 0x20, 0x1c, 0x18, 0x14, /* [MMI] ld8 r16=[r14],8;; */
+ 0x10, 0x41, 0x38, 0x30, 0x28, 0x00, /* ld8 r17=[r14],8 */
+ 0x00, 0x00, 0x04, 0x00, /* nop.i 0x0;; */
+ 0x11, 0x08, 0x00, 0x1c, 0x18, 0x10, /* [MIB] ld8 r1=[r14] */
+ 0x60, 0x88, 0x04, 0x80, 0x03, 0x00, /* mov b6=r17 */
+ 0x60, 0x00, 0x80, 0x00 /* br.few b6;; */
+};
+
+static const bfd_byte plt_min_entry[PLT_MIN_ENTRY_SIZE] =
+{
+ 0x11, 0x78, 0x00, 0x00, 0x00, 0x24, /* [MIB] mov r15=0 */
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, /* nop.i 0x0 */
+ 0x00, 0x00, 0x00, 0x40 /* br.few 0 <PLT0>;; */
+};
+
+static const bfd_byte plt_full_entry[PLT_FULL_ENTRY_SIZE] =
+{
+ 0x0b, 0x78, 0x00, 0x02, 0x00, 0x24, /* [MMI] addl r15=0,r1;; */
+ 0x00, 0x41, 0x3c, 0x70, 0x29, 0xc0, /* ld8.acq r16=[r15],8*/
+ 0x01, 0x08, 0x00, 0x84, /* mov r14=r1;; */
+ 0x11, 0x08, 0x00, 0x1e, 0x18, 0x10, /* [MIB] ld8 r1=[r15] */
+ 0x60, 0x80, 0x04, 0x80, 0x03, 0x00, /* mov b6=r16 */
+ 0x60, 0x00, 0x80, 0x00 /* br.few b6;; */
+};
+
+#define ELF_DYNAMIC_INTERPRETER "/usr/lib/ld.so.1"
+
+static const bfd_byte oor_brl[16] =
+{
+ 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MLX] nop.m 0 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* brl.sptk.few tgt;; */
+ 0x00, 0x00, 0x00, 0xc0
+};
+
+static const bfd_byte oor_ip[48] =
+{
+ 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MLX] nop.m 0 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, /* movl r15=0 */
+ 0x01, 0x00, 0x00, 0x60,
+ 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MII] nop.m 0 */
+ 0x00, 0x01, 0x00, 0x60, 0x00, 0x00, /* mov r16=ip;; */
+ 0xf2, 0x80, 0x00, 0x80, /* add r16=r15,r16;; */
+ 0x11, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MIB] nop.m 0 */
+ 0x60, 0x80, 0x04, 0x80, 0x03, 0x00, /* mov b6=r16 */
+ 0x60, 0x00, 0x80, 0x00 /* br b6;; */
+};
+
+static size_t oor_branch_size = sizeof (oor_brl);
+
+void
+bfd_elfNN_ia64_after_parse (int itanium)
+{
+ oor_branch_size = itanium ? sizeof (oor_ip) : sizeof (oor_brl);
+}
+
+
+/* Rename some of the generic section flags to better document how they
+ are used here. */
+#define skip_relax_pass_0 sec_flg0
+#define skip_relax_pass_1 sec_flg1
+
+/* These functions do relaxation for IA-64 ELF. */
+
+static void
+elfNN_ia64_update_short_info (asection *sec, bfd_vma offset,
+ struct elfNN_ia64_link_hash_table *ia64_info)
+{
+ /* Skip ABS and SHF_IA_64_SHORT sections. */
+ if (sec == bfd_abs_section_ptr
+ || (sec->flags & SEC_SMALL_DATA) != 0)
+ return;
+
+ if (!ia64_info->min_short_sec)
+ {
+ ia64_info->max_short_sec = sec;
+ ia64_info->max_short_offset = offset;
+ ia64_info->min_short_sec = sec;
+ ia64_info->min_short_offset = offset;
+ }
+ else if (sec == ia64_info->max_short_sec
+ && offset > ia64_info->max_short_offset)
+ ia64_info->max_short_offset = offset;
+ else if (sec == ia64_info->min_short_sec
+ && offset < ia64_info->min_short_offset)
+ ia64_info->min_short_offset = offset;
+ else if (sec->output_section->vma
+ > ia64_info->max_short_sec->vma)
+ {
+ ia64_info->max_short_sec = sec;
+ ia64_info->max_short_offset = offset;
+ }
+ else if (sec->output_section->vma
+ < ia64_info->min_short_sec->vma)
+ {
+ ia64_info->min_short_sec = sec;
+ ia64_info->min_short_offset = offset;
+ }
+}
+
+static bfd_boolean
+elfNN_ia64_relax_section (bfd *abfd, asection *sec,
+ struct bfd_link_info *link_info,
+ bfd_boolean *again)
+{
+ struct one_fixup
+ {
+ struct one_fixup *next;
+ asection *tsec;
+ bfd_vma toff;
+ bfd_vma trampoff;
+ };
+
+ Elf_Internal_Shdr *symtab_hdr;
+ Elf_Internal_Rela *internal_relocs;
+ Elf_Internal_Rela *irel, *irelend;
+ bfd_byte *contents;
+ Elf_Internal_Sym *isymbuf = NULL;
+ struct elfNN_ia64_link_hash_table *ia64_info;
+ struct one_fixup *fixups = NULL;
+ bfd_boolean changed_contents = FALSE;
+ bfd_boolean changed_relocs = FALSE;
+ bfd_boolean changed_got = FALSE;
+ bfd_boolean skip_relax_pass_0 = TRUE;
+ bfd_boolean skip_relax_pass_1 = TRUE;
+ bfd_vma gp = 0;
+
+ /* Assume we're not going to change any sizes, and we'll only need
+ one pass. */
+ *again = FALSE;
+
+ if (link_info->relocatable)
+ (*link_info->callbacks->einfo)
+ (_("%P%F: --relax and -r may not be used together\n"));
+
+ /* Don't even try to relax for non-ELF outputs. */
+ if (!is_elf_hash_table (link_info->hash))
+ return FALSE;
+
+ /* Nothing to do if there are no relocations or there is no need for
+ the current pass. */
+ if ((sec->flags & SEC_RELOC) == 0
+ || sec->reloc_count == 0
+ || (link_info->relax_pass == 0 && sec->skip_relax_pass_0)
+ || (link_info->relax_pass == 1 && sec->skip_relax_pass_1))
+ return TRUE;
+
+ ia64_info = elfNN_ia64_hash_table (link_info);
+ if (ia64_info == NULL)
+ return FALSE;
+
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+
+ /* Load the relocations for this section. */
+ internal_relocs = (_bfd_elf_link_read_relocs
+ (abfd, sec, NULL, (Elf_Internal_Rela *) NULL,
+ link_info->keep_memory));
+ if (internal_relocs == NULL)
+ return FALSE;
+
+ irelend = internal_relocs + sec->reloc_count;
+
+ /* Get the section contents. */
+ if (elf_section_data (sec)->this_hdr.contents != NULL)
+ contents = elf_section_data (sec)->this_hdr.contents;
+ else
+ {
+ if (!bfd_malloc_and_get_section (abfd, sec, &contents))
+ goto error_return;
+ }
+
+ for (irel = internal_relocs; irel < irelend; irel++)
+ {
+ unsigned long r_type = ELFNN_R_TYPE (irel->r_info);
+ bfd_vma symaddr, reladdr, trampoff, toff, roff;
+ asection *tsec;
+ struct one_fixup *f;
+ bfd_size_type amt;
+ bfd_boolean is_branch;
+ struct elfNN_ia64_dyn_sym_info *dyn_i;
+ char symtype;
+
+ switch (r_type)
+ {
+ case R_IA64_PCREL21B:
+ case R_IA64_PCREL21BI:
+ case R_IA64_PCREL21M:
+ case R_IA64_PCREL21F:
+ /* In pass 1, all br relaxations are done. We can skip it. */
+ if (link_info->relax_pass == 1)
+ continue;
+ skip_relax_pass_0 = FALSE;
+ is_branch = TRUE;
+ break;
+
+ case R_IA64_PCREL60B:
+ /* We can't optimize brl to br in pass 0 since br relaxations
+ will increase the code size. Defer it to pass 1. */
+ if (link_info->relax_pass == 0)
+ {
+ skip_relax_pass_1 = FALSE;
+ continue;
+ }
+ is_branch = TRUE;
+ break;
+
+ case R_IA64_GPREL22:
+ /* Update max_short_sec/min_short_sec. */
+
+ case R_IA64_LTOFF22X:
+ case R_IA64_LDXMOV:
+ /* We can't relax ldx/mov in pass 0 since br relaxations will
+ increase the code size. Defer it to pass 1. */
+ if (link_info->relax_pass == 0)
+ {
+ skip_relax_pass_1 = FALSE;
+ continue;
+ }
+ is_branch = FALSE;
+ break;
+
+ default:
+ continue;
+ }
+
+ /* Get the value of the symbol referred to by the reloc. */
+ if (ELFNN_R_SYM (irel->r_info) < symtab_hdr->sh_info)
+ {
+ /* A local symbol. */
+ Elf_Internal_Sym *isym;
+
+ /* Read this BFD's local symbols. */
+ if (isymbuf == NULL)
+ {
+ isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
+ if (isymbuf == NULL)
+ isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
+ symtab_hdr->sh_info, 0,
+ NULL, NULL, NULL);
+ if (isymbuf == 0)
+ goto error_return;
+ }
+
+ isym = isymbuf + ELFNN_R_SYM (irel->r_info);
+ if (isym->st_shndx == SHN_UNDEF)
+ continue; /* We can't do anything with undefined symbols. */
+ else if (isym->st_shndx == SHN_ABS)
+ tsec = bfd_abs_section_ptr;
+ else if (isym->st_shndx == SHN_COMMON)
+ tsec = bfd_com_section_ptr;
+ else if (isym->st_shndx == SHN_IA_64_ANSI_COMMON)
+ tsec = bfd_com_section_ptr;
+ else
+ tsec = bfd_section_from_elf_index (abfd, isym->st_shndx);
+
+ toff = isym->st_value;
+ dyn_i = get_dyn_sym_info (ia64_info, NULL, abfd, irel, FALSE);
+ symtype = ELF_ST_TYPE (isym->st_info);
+ }
+ else
+ {
+ unsigned long indx;
+ struct elf_link_hash_entry *h;
+
+ indx = ELFNN_R_SYM (irel->r_info) - symtab_hdr->sh_info;
+ h = elf_sym_hashes (abfd)[indx];
+ BFD_ASSERT (h != NULL);
+
+ 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;
+
+ dyn_i = get_dyn_sym_info (ia64_info, h, abfd, irel, FALSE);
+
+ /* For branches to dynamic symbols, we're interested instead
+ in a branch to the PLT entry. */
+ if (is_branch && dyn_i && dyn_i->want_plt2)
+ {
+ /* Internal branches shouldn't be sent to the PLT.
+ Leave this for now and we'll give an error later. */
+ if (r_type != R_IA64_PCREL21B)
+ continue;
+
+ tsec = ia64_info->root.splt;
+ toff = dyn_i->plt2_offset;
+ BFD_ASSERT (irel->r_addend == 0);
+ }
+
+ /* Can't do anything else with dynamic symbols. */
+ else if (elfNN_ia64_dynamic_symbol_p (h, link_info, r_type))
+ continue;
+
+ else
+ {
+ /* We can't do anything with undefined symbols. */
+ if (h->root.type == bfd_link_hash_undefined
+ || h->root.type == bfd_link_hash_undefweak)
+ continue;
+
+ tsec = h->root.u.def.section;
+ toff = h->root.u.def.value;
+ }
+
+ symtype = h->type;
+ }
+
+ if (tsec->sec_info_type == SEC_INFO_TYPE_MERGE)
+ {
+ /* At this stage in linking, no SEC_MERGE symbol has been
+ adjusted, so all references to such symbols need to be
+ passed through _bfd_merged_section_offset. (Later, in
+ relocate_section, all SEC_MERGE symbols *except* for
+ section symbols have been adjusted.)
+
+ gas may reduce relocations against symbols in SEC_MERGE
+ sections to a relocation against the section symbol when
+ the original addend was zero. When the reloc is against
+ a section symbol we should include the addend in the
+ offset passed to _bfd_merged_section_offset, since the
+ location of interest is the original symbol. On the
+ other hand, an access to "sym+addend" where "sym" is not
+ a section symbol should not include the addend; Such an
+ access is presumed to be an offset from "sym"; The
+ location of interest is just "sym". */
+ if (symtype == STT_SECTION)
+ toff += irel->r_addend;
+
+ toff = _bfd_merged_section_offset (abfd, &tsec,
+ elf_section_data (tsec)->sec_info,
+ toff);
+
+ if (symtype != STT_SECTION)
+ toff += irel->r_addend;
+ }
+ else
+ toff += irel->r_addend;
+
+ symaddr = tsec->output_section->vma + tsec->output_offset + toff;
+
+ roff = irel->r_offset;
+
+ if (is_branch)
+ {
+ bfd_signed_vma offset;
+
+ reladdr = (sec->output_section->vma
+ + sec->output_offset
+ + roff) & (bfd_vma) -4;
+
+ /* The .plt section is aligned at 32byte and the .text section
+ is aligned at 64byte. The .text section is right after the
+ .plt section. After the first relaxation pass, linker may
+ increase the gap between the .plt and .text sections up
+ to 32byte. We assume linker will always insert 32byte
+ between the .plt and .text sections after the first
+ relaxation pass. */
+ if (tsec == ia64_info->root.splt)
+ offset = -0x1000000 + 32;
+ else
+ offset = -0x1000000;
+
+ /* If the branch is in range, no need to do anything. */
+ if ((bfd_signed_vma) (symaddr - reladdr) >= offset
+ && (bfd_signed_vma) (symaddr - reladdr) <= 0x0FFFFF0)
+ {
+ /* If the 60-bit branch is in 21-bit range, optimize it. */
+ if (r_type == R_IA64_PCREL60B)
+ {
+ ia64_elf_relax_brl (contents, roff);
+
+ irel->r_info
+ = ELFNN_R_INFO (ELFNN_R_SYM (irel->r_info),
+ R_IA64_PCREL21B);
+
+ /* If the original relocation offset points to slot
+ 1, change it to slot 2. */
+ if ((irel->r_offset & 3) == 1)
+ irel->r_offset += 1;
+ }
+
+ continue;
+ }
+ else if (r_type == R_IA64_PCREL60B)
+ continue;
+ else if (ia64_elf_relax_br (contents, roff))
+ {
+ irel->r_info
+ = ELFNN_R_INFO (ELFNN_R_SYM (irel->r_info),
+ R_IA64_PCREL60B);
+
+ /* Make the relocation offset point to slot 1. */
+ irel->r_offset = (irel->r_offset & ~((bfd_vma) 0x3)) + 1;
+ continue;
+ }
+
+ /* We can't put a trampoline in a .init/.fini section. Issue
+ an error. */
+ if (strcmp (sec->output_section->name, ".init") == 0
+ || strcmp (sec->output_section->name, ".fini") == 0)
+ {
+ (*_bfd_error_handler)
+ (_("%B: Can't relax br at 0x%lx in section `%A'. Please use brl or indirect branch."),
+ sec->owner, sec, (unsigned long) roff);
+ bfd_set_error (bfd_error_bad_value);
+ goto error_return;
+ }
+
+ /* If the branch and target are in the same section, you've
+ got one honking big section and we can't help you unless
+ you are branching backwards. You'll get an error message
+ later. */
+ if (tsec == sec && toff > roff)
+ continue;
+
+ /* Look for an existing fixup to this address. */
+ for (f = fixups; f ; f = f->next)
+ if (f->tsec == tsec && f->toff == toff)
+ break;
+
+ if (f == NULL)
+ {
+ /* Two alternatives: If it's a branch to a PLT entry, we can
+ make a copy of the FULL_PLT entry. Otherwise, we'll have
+ to use a `brl' insn to get where we're going. */
+
+ size_t size;
+
+ if (tsec == ia64_info->root.splt)
+ size = sizeof (plt_full_entry);
+ else
+ size = oor_branch_size;
+
+ /* Resize the current section to make room for the new branch. */
+ trampoff = (sec->size + 15) & (bfd_vma) -16;
+
+ /* If trampoline is out of range, there is nothing we
+ can do. */
+ offset = trampoff - (roff & (bfd_vma) -4);
+ if (offset < -0x1000000 || offset > 0x0FFFFF0)
+ continue;
+
+ amt = trampoff + size;
+ contents = (bfd_byte *) bfd_realloc (contents, amt);
+ if (contents == NULL)
+ goto error_return;
+ sec->size = amt;
+
+ if (tsec == ia64_info->root.splt)
+ {
+ memcpy (contents + trampoff, plt_full_entry, size);
+
+ /* Hijack the old relocation for use as the PLTOFF reloc. */
+ irel->r_info = ELFNN_R_INFO (ELFNN_R_SYM (irel->r_info),
+ R_IA64_PLTOFF22);
+ irel->r_offset = trampoff;
+ }
+ else
+ {
+ if (size == sizeof (oor_ip))
+ {
+ memcpy (contents + trampoff, oor_ip, size);
+ irel->r_info = ELFNN_R_INFO (ELFNN_R_SYM (irel->r_info),
+ R_IA64_PCREL64I);
+ irel->r_addend -= 16;
+ irel->r_offset = trampoff + 2;
+ }
+ else
+ {
+ memcpy (contents + trampoff, oor_brl, size);
+ irel->r_info = ELFNN_R_INFO (ELFNN_R_SYM (irel->r_info),
+ R_IA64_PCREL60B);
+ irel->r_offset = trampoff + 2;
+ }
+
+ }
+
+ /* Record the fixup so we don't do it again this section. */
+ f = (struct one_fixup *)
+ bfd_malloc ((bfd_size_type) sizeof (*f));
+ f->next = fixups;
+ f->tsec = tsec;
+ f->toff = toff;
+ f->trampoff = trampoff;
+ fixups = f;
+ }
+ else
+ {
+ /* If trampoline is out of range, there is nothing we
+ can do. */
+ offset = f->trampoff - (roff & (bfd_vma) -4);
+ if (offset < -0x1000000 || offset > 0x0FFFFF0)
+ continue;
+
+ /* Nop out the reloc, since we're finalizing things here. */
+ irel->r_info = ELFNN_R_INFO (0, R_IA64_NONE);
+ }
+
+ /* Fix up the existing branch to hit the trampoline. */
+ if (ia64_elf_install_value (contents + roff, offset, r_type)
+ != bfd_reloc_ok)
+ goto error_return;
+
+ changed_contents = TRUE;
+ changed_relocs = TRUE;
+ }
+ else
+ {
+ /* Fetch the gp. */
+ if (gp == 0)
+ {
+ bfd *obfd = sec->output_section->owner;
+ gp = _bfd_get_gp_value (obfd);
+ if (gp == 0)
+ {
+ if (!elfNN_ia64_choose_gp (obfd, link_info, FALSE))
+ goto error_return;
+ gp = _bfd_get_gp_value (obfd);
+ }
+ }
+
+ /* If the data is out of range, do nothing. */
+ if ((bfd_signed_vma) (symaddr - gp) >= 0x200000
+ ||(bfd_signed_vma) (symaddr - gp) < -0x200000)
+ continue;
+
+ if (r_type == R_IA64_GPREL22)
+ elfNN_ia64_update_short_info (tsec->output_section,
+ tsec->output_offset + toff,
+ ia64_info);
+ else if (r_type == R_IA64_LTOFF22X)
+ {
+ irel->r_info = ELFNN_R_INFO (ELFNN_R_SYM (irel->r_info),
+ R_IA64_GPREL22);
+ changed_relocs = TRUE;
+ if (dyn_i->want_gotx)
+ {
+ dyn_i->want_gotx = 0;
+ changed_got |= !dyn_i->want_got;
+ }
+
+ elfNN_ia64_update_short_info (tsec->output_section,
+ tsec->output_offset + toff,
+ ia64_info);
+ }
+ else
+ {
+ ia64_elf_relax_ldxmov (contents, roff);
+ irel->r_info = ELFNN_R_INFO (0, R_IA64_NONE);
+ changed_contents = TRUE;
+ changed_relocs = TRUE;
+ }
+ }
+ }
+
+ /* ??? If we created fixups, this may push the code segment large
+ enough that the data segment moves, which will change the GP.
+ Reset the GP so that we re-calculate next round. We need to
+ do this at the _beginning_ of the next round; now will not do. */
+
+ /* Clean up and go home. */
+ while (fixups)
+ {
+ struct one_fixup *f = fixups;
+ fixups = fixups->next;
+ free (f);
+ }
+
+ if (isymbuf != NULL
+ && symtab_hdr->contents != (unsigned char *) isymbuf)
+ {
+ if (! link_info->keep_memory)
+ free (isymbuf);
+ else
+ {
+ /* Cache the symbols for elf_link_input_bfd. */
+ symtab_hdr->contents = (unsigned char *) isymbuf;
+ }
+ }
+
+ if (contents != NULL
+ && elf_section_data (sec)->this_hdr.contents != contents)
+ {
+ if (!changed_contents && !link_info->keep_memory)
+ free (contents);
+ else
+ {
+ /* Cache the section contents for elf_link_input_bfd. */
+ elf_section_data (sec)->this_hdr.contents = contents;
+ }
+ }
+
+ if (elf_section_data (sec)->relocs != internal_relocs)
+ {
+ if (!changed_relocs)
+ free (internal_relocs);
+ else
+ elf_section_data (sec)->relocs = internal_relocs;
+ }
+
+ if (changed_got)
+ {
+ struct elfNN_ia64_allocate_data data;
+ data.info = link_info;
+ data.ofs = 0;
+ ia64_info->self_dtpmod_offset = (bfd_vma) -1;
+
+ elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_global_data_got, &data);
+ elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_global_fptr_got, &data);
+ elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_local_got, &data);
+ ia64_info->root.sgot->size = data.ofs;
+
+ if (ia64_info->root.dynamic_sections_created
+ && ia64_info->root.srelgot != NULL)
+ {
+ /* Resize .rela.got. */
+ ia64_info->root.srelgot->size = 0;
+ if (link_info->shared
+ && ia64_info->self_dtpmod_offset != (bfd_vma) -1)
+ ia64_info->root.srelgot->size += sizeof (ElfNN_External_Rela);
+ data.only_got = TRUE;
+ elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_dynrel_entries,
+ &data);
+ }
+ }
+
+ if (link_info->relax_pass == 0)
+ {
+ /* Pass 0 is only needed to relax br. */
+ sec->skip_relax_pass_0 = skip_relax_pass_0;
+ sec->skip_relax_pass_1 = skip_relax_pass_1;
+ }
+
+ *again = changed_contents || changed_relocs;
+ return TRUE;
+
+ error_return:
+ if (isymbuf != NULL && (unsigned char *) isymbuf != symtab_hdr->contents)
+ free (isymbuf);
+ if (contents != NULL
+ && elf_section_data (sec)->this_hdr.contents != contents)
+ free (contents);
+ if (internal_relocs != NULL
+ && elf_section_data (sec)->relocs != internal_relocs)
+ free (internal_relocs);
+ return FALSE;
+}
+#undef skip_relax_pass_0
+#undef skip_relax_pass_1
+
+/* Return TRUE if NAME is an unwind table section name. */
+
+static inline bfd_boolean
+is_unwind_section_name (bfd *abfd, const char *name)
+{
+ if (elfNN_ia64_hpux_vec (abfd->xvec)
+ && !strcmp (name, ELF_STRING_ia64_unwind_hdr))
+ return FALSE;
+
+ return ((CONST_STRNEQ (name, ELF_STRING_ia64_unwind)
+ && ! CONST_STRNEQ (name, ELF_STRING_ia64_unwind_info))
+ || CONST_STRNEQ (name, ELF_STRING_ia64_unwind_once));
+}
+
+/* Handle an IA-64 specific section when reading an object file. This
+ is called when bfd_section_from_shdr finds a section with an unknown
+ type. */
+
+static bfd_boolean
+elfNN_ia64_section_from_shdr (bfd *abfd,
+ Elf_Internal_Shdr *hdr,
+ const char *name,
+ int shindex)
+{
+ /* 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_IA_64_UNWIND:
+ case SHT_IA_64_HP_OPT_ANOT:
+ break;
+
+ case SHT_IA_64_EXT:
+ if (strcmp (name, ELF_STRING_ia64_archext) != 0)
+ return FALSE;
+ break;
+
+ default:
+ return FALSE;
+ }
+
+ if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex))
+ return FALSE;
+
+ return TRUE;
+}
+
+/* Convert IA-64 specific section flags to bfd internal section flags. */
+
+/* ??? There is no bfd internal flag equivalent to the SHF_IA_64_NORECOV
+ flag. */
+
+static bfd_boolean
+elfNN_ia64_section_flags (flagword *flags,
+ const Elf_Internal_Shdr *hdr)
+{
+ if (hdr->sh_flags & SHF_IA_64_SHORT)
+ *flags |= SEC_SMALL_DATA;
+
+ return TRUE;
+}
+
+/* Set the correct type for an IA-64 ELF section. We do this by the
+ section name, which is a hack, but ought to work. */
+
+static bfd_boolean
+elfNN_ia64_fake_sections (bfd *abfd, Elf_Internal_Shdr *hdr,
+ asection *sec)
+{
+ const char *name;
+
+ name = bfd_get_section_name (abfd, sec);
+
+ if (is_unwind_section_name (abfd, name))
+ {
+ /* We don't have the sections numbered at this point, so sh_info
+ is set later, in elfNN_ia64_final_write_processing. */
+ hdr->sh_type = SHT_IA_64_UNWIND;
+ hdr->sh_flags |= SHF_LINK_ORDER;
+ }
+ else if (strcmp (name, ELF_STRING_ia64_archext) == 0)
+ hdr->sh_type = SHT_IA_64_EXT;
+ else if (strcmp (name, ".HP.opt_annot") == 0)
+ hdr->sh_type = SHT_IA_64_HP_OPT_ANOT;
+ else if (strcmp (name, ".reloc") == 0)
+ /* This is an ugly, but unfortunately necessary hack that is
+ needed when producing EFI binaries on IA-64. It tells
+ elf.c:elf_fake_sections() not to consider ".reloc" as a section
+ containing ELF relocation info. We need this hack in order to
+ be able to generate ELF binaries that can be translated into
+ EFI applications (which are essentially COFF objects). Those
+ files contain a COFF ".reloc" section inside an ELFNN object,
+ which would normally cause BFD to segfault because it would
+ attempt to interpret this section as containing relocation
+ entries for section "oc". With this hack enabled, ".reloc"
+ will be treated as a normal data section, which will avoid the
+ segfault. However, you won't be able to create an ELFNN binary
+ with a section named "oc" that needs relocations, but that's
+ the kind of ugly side-effects you get when detecting section
+ types based on their names... In practice, this limitation is
+ unlikely to bite. */
+ hdr->sh_type = SHT_PROGBITS;
+
+ if (sec->flags & SEC_SMALL_DATA)
+ hdr->sh_flags |= SHF_IA_64_SHORT;
+
+ /* Some HP linkers look for the SHF_IA_64_HP_TLS flag instead of SHF_TLS. */
+
+ if (elfNN_ia64_hpux_vec (abfd->xvec) && (sec->flags & SHF_TLS))
+ hdr->sh_flags |= SHF_IA_64_HP_TLS;
+
+ return TRUE;
+}
+
+/* The final processing done just before writing out an IA-64 ELF
+ object file. */
+
+static void
+elfNN_ia64_final_write_processing (bfd *abfd,
+ bfd_boolean linker ATTRIBUTE_UNUSED)
+{
+ Elf_Internal_Shdr *hdr;
+ asection *s;
+
+ for (s = abfd->sections; s; s = s->next)
+ {
+ hdr = &elf_section_data (s)->this_hdr;
+ switch (hdr->sh_type)
+ {
+ case SHT_IA_64_UNWIND:
+ /* The IA-64 processor-specific ABI requires setting sh_link
+ to the unwind section, whereas HP-UX requires sh_info to
+ do so. For maximum compatibility, we'll set both for
+ now... */
+ hdr->sh_info = hdr->sh_link;
+ break;
+ }
+ }
+
+ if (! elf_flags_init (abfd))
+ {
+ unsigned long flags = 0;
+
+ if (abfd->xvec->byteorder == BFD_ENDIAN_BIG)
+ flags |= EF_IA_64_BE;
+ if (bfd_get_mach (abfd) == bfd_mach_ia64_elf64)
+ flags |= EF_IA_64_ABI64;
+
+ elf_elfheader(abfd)->e_flags = flags;
+ elf_flags_init (abfd) = 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 bfd_boolean
+elfNN_ia64_add_symbol_hook (bfd *abfd,
+ struct bfd_link_info *info,
+ Elf_Internal_Sym *sym,
+ const char **namep ATTRIBUTE_UNUSED,
+ flagword *flagsp ATTRIBUTE_UNUSED,
+ asection **secp,
+ bfd_vma *valp)
+{
+ if (sym->st_shndx == SHN_COMMON
+ && !info->relocatable
+ && sym->st_size <= elf_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_with_flags (abfd, ".scommon",
+ (SEC_ALLOC
+ | SEC_IS_COMMON
+ | SEC_LINKER_CREATED));
+ if (scomm == NULL)
+ return FALSE;
+ }
+
+ *secp = scomm;
+ *valp = sym->st_size;
+ }
+
+ return TRUE;
+}
+
+/* Return the number of additional phdrs we will need. */
+
+static int
+elfNN_ia64_additional_program_headers (bfd *abfd,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED)
+{
+ asection *s;
+ int ret = 0;
+
+ /* See if we need a PT_IA_64_ARCHEXT segment. */
+ s = bfd_get_section_by_name (abfd, ELF_STRING_ia64_archext);
+ if (s && (s->flags & SEC_LOAD))
+ ++ret;
+
+ /* Count how many PT_IA_64_UNWIND segments we need. */
+ for (s = abfd->sections; s; s = s->next)
+ if (is_unwind_section_name (abfd, s->name) && (s->flags & SEC_LOAD))
+ ++ret;
+
+ return ret;
+}
+
+static bfd_boolean
+elfNN_ia64_modify_segment_map (bfd *abfd,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED)
+{
+ struct elf_segment_map *m, **pm;
+ Elf_Internal_Shdr *hdr;
+ asection *s;
+
+ /* If we need a PT_IA_64_ARCHEXT segment, it must come before
+ all PT_LOAD segments. */
+ s = bfd_get_section_by_name (abfd, ELF_STRING_ia64_archext);
+ if (s && (s->flags & SEC_LOAD))
+ {
+ for (m = elf_seg_map (abfd); m != NULL; m = m->next)
+ if (m->p_type == PT_IA_64_ARCHEXT)
+ break;
+ if (m == NULL)
+ {
+ m = ((struct elf_segment_map *)
+ bfd_zalloc (abfd, (bfd_size_type) sizeof *m));
+ if (m == NULL)
+ return FALSE;
+
+ m->p_type = PT_IA_64_ARCHEXT;
+ m->count = 1;
+ m->sections[0] = s;
+
+ /* We want to put it after the PHDR and INTERP segments. */
+ pm = &elf_seg_map (abfd);
+ while (*pm != NULL
+ && ((*pm)->p_type == PT_PHDR
+ || (*pm)->p_type == PT_INTERP))
+ pm = &(*pm)->next;
+
+ m->next = *pm;
+ *pm = m;
+ }
+ }
+
+ /* Install PT_IA_64_UNWIND segments, if needed. */
+ for (s = abfd->sections; s; s = s->next)
+ {
+ hdr = &elf_section_data (s)->this_hdr;
+ if (hdr->sh_type != SHT_IA_64_UNWIND)
+ continue;
+
+ if (s && (s->flags & SEC_LOAD))
+ {
+ for (m = elf_seg_map (abfd); m != NULL; m = m->next)
+ if (m->p_type == PT_IA_64_UNWIND)
+ {
+ int i;
+
+ /* Look through all sections in the unwind segment
+ for a match since there may be multiple sections
+ to a segment. */
+ for (i = m->count - 1; i >= 0; --i)
+ if (m->sections[i] == s)
+ break;
+
+ if (i >= 0)
+ break;
+ }
+
+ if (m == NULL)
+ {
+ m = ((struct elf_segment_map *)
+ bfd_zalloc (abfd, (bfd_size_type) sizeof *m));
+ if (m == NULL)
+ return FALSE;
+
+ m->p_type = PT_IA_64_UNWIND;
+ m->count = 1;
+ m->sections[0] = s;
+ m->next = NULL;
+
+ /* We want to put it last. */
+ pm = &elf_seg_map (abfd);
+ while (*pm != NULL)
+ pm = &(*pm)->next;
+ *pm = m;
+ }
+ }
+ }
+
+ return TRUE;
+}
+
+/* Turn on PF_IA_64_NORECOV if needed. This involves traversing all of
+ the input sections for each output section in the segment and testing
+ for SHF_IA_64_NORECOV on each. */
+
+static bfd_boolean
+elfNN_ia64_modify_program_headers (bfd *abfd,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED)
+{
+ struct elf_obj_tdata *tdata = elf_tdata (abfd);
+ struct elf_segment_map *m;
+ Elf_Internal_Phdr *p;
+
+ for (p = tdata->phdr, m = elf_seg_map (abfd); m != NULL; m = m->next, p++)
+ if (m->p_type == PT_LOAD)
+ {
+ int i;
+ for (i = m->count - 1; i >= 0; --i)
+ {
+ struct bfd_link_order *order = m->sections[i]->map_head.link_order;
+
+ while (order != NULL)
+ {
+ if (order->type == bfd_indirect_link_order)
+ {
+ asection *is = order->u.indirect.section;
+ bfd_vma flags = elf_section_data(is)->this_hdr.sh_flags;
+ if (flags & SHF_IA_64_NORECOV)
+ {
+ p->p_flags |= PF_IA_64_NORECOV;
+ goto found;
+ }
+ }
+ order = order->next;
+ }
+ }
+ found:;
+ }
+
+ return TRUE;
+}
+
+/* According to the Tahoe assembler spec, all labels starting with a
+ '.' are local. */
+
+static bfd_boolean
+elfNN_ia64_is_local_label_name (bfd *abfd ATTRIBUTE_UNUSED,
+ const char *name)
+{
+ return name[0] == '.';
+}
+
+/* Should we do dynamic things to this symbol? */
+
+static bfd_boolean
+elfNN_ia64_dynamic_symbol_p (struct elf_link_hash_entry *h,
+ struct bfd_link_info *info, int r_type)
+{
+ bfd_boolean ignore_protected
+ = ((r_type & 0xf8) == 0x40 /* FPTR relocs */
+ || (r_type & 0xf8) == 0x50); /* LTOFF_FPTR relocs */
+
+ return _bfd_elf_dynamic_symbol_p (h, info, ignore_protected);
+}
+
+static struct bfd_hash_entry*
+elfNN_ia64_new_elf_hash_entry (struct bfd_hash_entry *entry,
+ struct bfd_hash_table *table,
+ const char *string)
+{
+ struct elfNN_ia64_link_hash_entry *ret;
+ ret = (struct elfNN_ia64_link_hash_entry *) entry;
+
+ /* Allocate the structure if it has not already been allocated by a
+ subclass. */
+ if (!ret)
+ ret = bfd_hash_allocate (table, sizeof (*ret));
+
+ if (!ret)
+ return 0;
+
+ /* Call the allocation method of the superclass. */
+ ret = ((struct elfNN_ia64_link_hash_entry *)
+ _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry *) ret,
+ table, string));
+
+ ret->info = NULL;
+ ret->count = 0;
+ ret->sorted_count = 0;
+ ret->size = 0;
+ return (struct bfd_hash_entry *) ret;
+}
+
+static void
+elfNN_ia64_hash_copy_indirect (struct bfd_link_info *info,
+ struct elf_link_hash_entry *xdir,
+ struct elf_link_hash_entry *xind)
+{
+ struct elfNN_ia64_link_hash_entry *dir, *ind;
+
+ dir = (struct elfNN_ia64_link_hash_entry *) xdir;
+ ind = (struct elfNN_ia64_link_hash_entry *) xind;
+
+ /* Copy down any references that we may have already seen to the
+ symbol which just became indirect. */
+
+ dir->root.ref_dynamic |= ind->root.ref_dynamic;
+ dir->root.ref_regular |= ind->root.ref_regular;
+ dir->root.ref_regular_nonweak |= ind->root.ref_regular_nonweak;
+ dir->root.needs_plt |= ind->root.needs_plt;
+
+ if (ind->root.root.type != bfd_link_hash_indirect)
+ return;
+
+ /* Copy over the got and plt data. This would have been done
+ by check_relocs. */
+
+ if (ind->info != NULL)
+ {
+ struct elfNN_ia64_dyn_sym_info *dyn_i;
+ unsigned int count;
+
+ if (dir->info)
+ free (dir->info);
+
+ dir->info = ind->info;
+ dir->count = ind->count;
+ dir->sorted_count = ind->sorted_count;
+ dir->size = ind->size;
+
+ ind->info = NULL;
+ ind->count = 0;
+ ind->sorted_count = 0;
+ ind->size = 0;
+
+ /* Fix up the dyn_sym_info pointers to the global symbol. */
+ for (count = dir->count, dyn_i = dir->info;
+ count != 0;
+ count--, dyn_i++)
+ dyn_i->h = &dir->root;
+ }
+
+ /* Copy over the dynindx. */
+
+ if (ind->root.dynindx != -1)
+ {
+ if (dir->root.dynindx != -1)
+ _bfd_elf_strtab_delref (elf_hash_table (info)->dynstr,
+ dir->root.dynstr_index);
+ dir->root.dynindx = ind->root.dynindx;
+ dir->root.dynstr_index = ind->root.dynstr_index;
+ ind->root.dynindx = -1;
+ ind->root.dynstr_index = 0;
+ }
+}
+
+static void
+elfNN_ia64_hash_hide_symbol (struct bfd_link_info *info,
+ struct elf_link_hash_entry *xh,
+ bfd_boolean force_local)
+{
+ struct elfNN_ia64_link_hash_entry *h;
+ struct elfNN_ia64_dyn_sym_info *dyn_i;
+ unsigned int count;
+
+ h = (struct elfNN_ia64_link_hash_entry *)xh;
+
+ _bfd_elf_link_hash_hide_symbol (info, &h->root, force_local);
+
+ for (count = h->count, dyn_i = h->info;
+ count != 0;
+ count--, dyn_i++)
+ {
+ dyn_i->want_plt2 = 0;
+ dyn_i->want_plt = 0;
+ }
+}
+
+/* Compute a hash of a local hash entry. */
+
+static hashval_t
+elfNN_ia64_local_htab_hash (const void *ptr)
+{
+ struct elfNN_ia64_local_hash_entry *entry
+ = (struct elfNN_ia64_local_hash_entry *) ptr;
+
+ return ELF_LOCAL_SYMBOL_HASH (entry->id, entry->r_sym);
+}
+
+/* Compare local hash entries. */
+
+static int
+elfNN_ia64_local_htab_eq (const void *ptr1, const void *ptr2)
+{
+ struct elfNN_ia64_local_hash_entry *entry1
+ = (struct elfNN_ia64_local_hash_entry *) ptr1;
+ struct elfNN_ia64_local_hash_entry *entry2
+ = (struct elfNN_ia64_local_hash_entry *) ptr2;
+
+ return entry1->id == entry2->id && entry1->r_sym == entry2->r_sym;
+}
+
+/* Free the global elfNN_ia64_dyn_sym_info array. */
+
+static bfd_boolean
+elfNN_ia64_global_dyn_info_free (void **xentry,
+ void * unused ATTRIBUTE_UNUSED)
+{
+ struct elfNN_ia64_link_hash_entry *entry
+ = (struct elfNN_ia64_link_hash_entry *) xentry;
+
+ if (entry->info)
+ {
+ free (entry->info);
+ entry->info = NULL;
+ entry->count = 0;
+ entry->sorted_count = 0;
+ entry->size = 0;
+ }
+
+ return TRUE;
+}
+
+/* Free the local elfNN_ia64_dyn_sym_info array. */
+
+static bfd_boolean
+elfNN_ia64_local_dyn_info_free (void **slot,
+ void * unused ATTRIBUTE_UNUSED)
+{
+ struct elfNN_ia64_local_hash_entry *entry
+ = (struct elfNN_ia64_local_hash_entry *) *slot;
+
+ if (entry->info)
+ {
+ free (entry->info);
+ entry->info = NULL;
+ entry->count = 0;
+ entry->sorted_count = 0;
+ entry->size = 0;
+ }
+
+ return TRUE;
+}
+
+/* Destroy IA-64 linker hash table. */
+
+static void
+elfNN_ia64_link_hash_table_free (bfd *obfd)
+{
+ struct elfNN_ia64_link_hash_table *ia64_info
+ = (struct elfNN_ia64_link_hash_table *) obfd->link.hash;
+ if (ia64_info->loc_hash_table)
+ {
+ htab_traverse (ia64_info->loc_hash_table,
+ elfNN_ia64_local_dyn_info_free, NULL);
+ htab_delete (ia64_info->loc_hash_table);
+ }
+ if (ia64_info->loc_hash_memory)
+ objalloc_free ((struct objalloc *) ia64_info->loc_hash_memory);
+ elf_link_hash_traverse (&ia64_info->root,
+ elfNN_ia64_global_dyn_info_free, NULL);
+ _bfd_elf_link_hash_table_free (obfd);
+}
+
+/* Create the derived linker hash table. The IA-64 ELF port uses this
+ derived hash table to keep information specific to the IA-64 ElF
+ linker (without using static variables). */
+
+static struct bfd_link_hash_table *
+elfNN_ia64_hash_table_create (bfd *abfd)
+{
+ struct elfNN_ia64_link_hash_table *ret;
+
+ ret = bfd_zmalloc ((bfd_size_type) sizeof (*ret));
+ if (!ret)
+ return NULL;
+
+ if (!_bfd_elf_link_hash_table_init (&ret->root, abfd,
+ elfNN_ia64_new_elf_hash_entry,
+ sizeof (struct elfNN_ia64_link_hash_entry),
+ IA64_ELF_DATA))
+ {
+ free (ret);
+ return NULL;
+ }
+
+ ret->loc_hash_table = htab_try_create (1024, elfNN_ia64_local_htab_hash,
+ elfNN_ia64_local_htab_eq, NULL);
+ ret->loc_hash_memory = objalloc_create ();
+ if (!ret->loc_hash_table || !ret->loc_hash_memory)
+ {
+ elfNN_ia64_link_hash_table_free (abfd);
+ return NULL;
+ }
+ ret->root.root.hash_table_free = elfNN_ia64_link_hash_table_free;
+
+ return &ret->root.root;
+}
+
+/* Traverse both local and global hash tables. */
+
+struct elfNN_ia64_dyn_sym_traverse_data
+{
+ bfd_boolean (*func) (struct elfNN_ia64_dyn_sym_info *, void *);
+ void * data;
+};
+
+static bfd_boolean
+elfNN_ia64_global_dyn_sym_thunk (struct bfd_hash_entry *xentry,
+ void * xdata)
+{
+ struct elfNN_ia64_link_hash_entry *entry
+ = (struct elfNN_ia64_link_hash_entry *) xentry;
+ struct elfNN_ia64_dyn_sym_traverse_data *data
+ = (struct elfNN_ia64_dyn_sym_traverse_data *) xdata;
+ struct elfNN_ia64_dyn_sym_info *dyn_i;
+ unsigned int count;
+
+ for (count = entry->count, dyn_i = entry->info;
+ count != 0;
+ count--, dyn_i++)
+ if (! (*data->func) (dyn_i, data->data))
+ return FALSE;
+ return TRUE;
+}
+
+static bfd_boolean
+elfNN_ia64_local_dyn_sym_thunk (void **slot, void * xdata)
+{
+ struct elfNN_ia64_local_hash_entry *entry
+ = (struct elfNN_ia64_local_hash_entry *) *slot;
+ struct elfNN_ia64_dyn_sym_traverse_data *data
+ = (struct elfNN_ia64_dyn_sym_traverse_data *) xdata;
+ struct elfNN_ia64_dyn_sym_info *dyn_i;
+ unsigned int count;
+
+ for (count = entry->count, dyn_i = entry->info;
+ count != 0;
+ count--, dyn_i++)
+ if (! (*data->func) (dyn_i, data->data))
+ return FALSE;
+ return TRUE;
+}
+
+static void
+elfNN_ia64_dyn_sym_traverse (struct elfNN_ia64_link_hash_table *ia64_info,
+ bfd_boolean (*func) (struct elfNN_ia64_dyn_sym_info *, void *),
+ void * data)
+{
+ struct elfNN_ia64_dyn_sym_traverse_data xdata;
+
+ xdata.func = func;
+ xdata.data = data;
+
+ elf_link_hash_traverse (&ia64_info->root,
+ elfNN_ia64_global_dyn_sym_thunk, &xdata);
+ htab_traverse (ia64_info->loc_hash_table,
+ elfNN_ia64_local_dyn_sym_thunk, &xdata);
+}
+
+static bfd_boolean
+elfNN_ia64_create_dynamic_sections (bfd *abfd,
+ struct bfd_link_info *info)
+{
+ struct elfNN_ia64_link_hash_table *ia64_info;
+ asection *s;
+
+ if (! _bfd_elf_create_dynamic_sections (abfd, info))
+ return FALSE;
+
+ ia64_info = elfNN_ia64_hash_table (info);
+ if (ia64_info == NULL)
+ return FALSE;
+
+ {
+ flagword flags = bfd_get_section_flags (abfd, ia64_info->root.sgot);
+ bfd_set_section_flags (abfd, ia64_info->root.sgot,
+ SEC_SMALL_DATA | flags);
+ /* The .got section is always aligned at 8 bytes. */
+ if (! bfd_set_section_alignment (abfd, ia64_info->root.sgot, 3))
+ return FALSE;
+ }
+
+ if (!get_pltoff (abfd, info, ia64_info))
+ return FALSE;
+
+ s = bfd_make_section_anyway_with_flags (abfd, ".rela.IA_64.pltoff",
+ (SEC_ALLOC | SEC_LOAD
+ | SEC_HAS_CONTENTS
+ | SEC_IN_MEMORY
+ | SEC_LINKER_CREATED
+ | SEC_READONLY));
+ if (s == NULL
+ || !bfd_set_section_alignment (abfd, s, LOG_SECTION_ALIGN))
+ return FALSE;
+ ia64_info->rel_pltoff_sec = s;
+
+ return TRUE;
+}
+
+/* Find and/or create a hash entry for local symbol. */
+static struct elfNN_ia64_local_hash_entry *
+get_local_sym_hash (struct elfNN_ia64_link_hash_table *ia64_info,
+ bfd *abfd, const Elf_Internal_Rela *rel,
+ bfd_boolean create)
+{
+ struct elfNN_ia64_local_hash_entry e, *ret;
+ asection *sec = abfd->sections;
+ hashval_t h = ELF_LOCAL_SYMBOL_HASH (sec->id,
+ ELFNN_R_SYM (rel->r_info));
+ void **slot;
+
+ e.id = sec->id;
+ e.r_sym = ELFNN_R_SYM (rel->r_info);
+ slot = htab_find_slot_with_hash (ia64_info->loc_hash_table, &e, h,
+ create ? INSERT : NO_INSERT);
+
+ if (!slot)
+ return NULL;
+
+ if (*slot)
+ return (struct elfNN_ia64_local_hash_entry *) *slot;
+
+ ret = (struct elfNN_ia64_local_hash_entry *)
+ objalloc_alloc ((struct objalloc *) ia64_info->loc_hash_memory,
+ sizeof (struct elfNN_ia64_local_hash_entry));
+ if (ret)
+ {
+ memset (ret, 0, sizeof (*ret));
+ ret->id = sec->id;
+ ret->r_sym = ELFNN_R_SYM (rel->r_info);
+ *slot = ret;
+ }
+ return ret;
+}
+
+/* Used to sort elfNN_ia64_dyn_sym_info array. */
+
+static int
+addend_compare (const void *xp, const void *yp)
+{
+ const struct elfNN_ia64_dyn_sym_info *x
+ = (const struct elfNN_ia64_dyn_sym_info *) xp;
+ const struct elfNN_ia64_dyn_sym_info *y
+ = (const struct elfNN_ia64_dyn_sym_info *) yp;
+
+ return x->addend < y->addend ? -1 : x->addend > y->addend ? 1 : 0;
+}
+
+/* Sort elfNN_ia64_dyn_sym_info array and remove duplicates. */
+
+static unsigned int
+sort_dyn_sym_info (struct elfNN_ia64_dyn_sym_info *info,
+ unsigned int count)
+{
+ bfd_vma curr, prev, got_offset;
+ unsigned int i, kept, dupes, diff, dest, src, len;
+
+ qsort (info, count, sizeof (*info), addend_compare);
+
+ /* Find the first duplicate. */
+ prev = info [0].addend;
+ got_offset = info [0].got_offset;
+ for (i = 1; i < count; i++)
+ {
+ curr = info [i].addend;
+ if (curr == prev)
+ {
+ /* For duplicates, make sure that GOT_OFFSET is valid. */
+ if (got_offset == (bfd_vma) -1)
+ got_offset = info [i].got_offset;
+ break;
+ }
+ got_offset = info [i].got_offset;
+ prev = curr;
+ }
+
+ /* We may move a block of elements to here. */
+ dest = i++;
+
+ /* Remove duplicates. */
+ if (i < count)
+ {
+ while (i < count)
+ {
+ /* For duplicates, make sure that the kept one has a valid
+ got_offset. */
+ kept = dest - 1;
+ if (got_offset != (bfd_vma) -1)
+ info [kept].got_offset = got_offset;
+
+ curr = info [i].addend;
+ got_offset = info [i].got_offset;
+
+ /* Move a block of elements whose first one is different from
+ the previous. */
+ if (curr == prev)
+ {
+ for (src = i + 1; src < count; src++)
+ {
+ if (info [src].addend != curr)
+ break;
+ /* For duplicates, make sure that GOT_OFFSET is
+ valid. */
+ if (got_offset == (bfd_vma) -1)
+ got_offset = info [src].got_offset;
+ }
+
+ /* Make sure that the kept one has a valid got_offset. */
+ if (got_offset != (bfd_vma) -1)
+ info [kept].got_offset = got_offset;
+ }
+ else
+ src = i;
+
+ if (src >= count)
+ break;
+
+ /* Find the next duplicate. SRC will be kept. */
+ prev = info [src].addend;
+ got_offset = info [src].got_offset;
+ for (dupes = src + 1; dupes < count; dupes ++)
+ {
+ curr = info [dupes].addend;
+ if (curr == prev)
+ {
+ /* Make sure that got_offset is valid. */
+ if (got_offset == (bfd_vma) -1)
+ got_offset = info [dupes].got_offset;
+
+ /* For duplicates, make sure that the kept one has
+ a valid got_offset. */
+ if (got_offset != (bfd_vma) -1)
+ info [dupes - 1].got_offset = got_offset;
+ break;
+ }
+ got_offset = info [dupes].got_offset;
+ prev = curr;
+ }
+
+ /* How much to move. */
+ len = dupes - src;
+ i = dupes + 1;
+
+ if (len == 1 && dupes < count)
+ {
+ /* If we only move 1 element, we combine it with the next
+ one. There must be at least a duplicate. Find the
+ next different one. */
+ for (diff = dupes + 1, src++; diff < count; diff++, src++)
+ {
+ if (info [diff].addend != curr)
+ break;
+ /* Make sure that got_offset is valid. */
+ if (got_offset == (bfd_vma) -1)
+ got_offset = info [diff].got_offset;
+ }
+
+ /* Makre sure that the last duplicated one has an valid
+ offset. */
+ BFD_ASSERT (curr == prev);
+ if (got_offset != (bfd_vma) -1)
+ info [diff - 1].got_offset = got_offset;
+
+ if (diff < count)
+ {
+ /* Find the next duplicate. Track the current valid
+ offset. */
+ prev = info [diff].addend;
+ got_offset = info [diff].got_offset;
+ for (dupes = diff + 1; dupes < count; dupes ++)
+ {
+ curr = info [dupes].addend;
+ if (curr == prev)
+ {
+ /* For duplicates, make sure that GOT_OFFSET
+ is valid. */
+ if (got_offset == (bfd_vma) -1)
+ got_offset = info [dupes].got_offset;
+ break;
+ }
+ got_offset = info [dupes].got_offset;
+ prev = curr;
+ diff++;
+ }
+
+ len = diff - src + 1;
+ i = diff + 1;
+ }
+ }
+
+ memmove (&info [dest], &info [src], len * sizeof (*info));
+
+ dest += len;
+ }
+
+ count = dest;
+ }
+ else
+ {
+ /* When we get here, either there is no duplicate at all or
+ the only duplicate is the last element. */
+ if (dest < count)
+ {
+ /* If the last element is a duplicate, make sure that the
+ kept one has a valid got_offset. We also update count. */
+ if (got_offset != (bfd_vma) -1)
+ info [dest - 1].got_offset = got_offset;
+ count = dest;
+ }
+ }
+
+ return count;
+}
+
+/* Find and/or create a descriptor for dynamic symbol info. This will
+ vary based on global or local symbol, and the addend to the reloc.
+
+ We don't sort when inserting. Also, we sort and eliminate
+ duplicates if there is an unsorted section. Typically, this will
+ only happen once, because we do all insertions before lookups. We
+ then use bsearch to do a lookup. This also allows lookups to be
+ fast. So we have fast insertion (O(log N) due to duplicate check),
+ fast lookup (O(log N)) and one sort (O(N log N) expected time).
+ Previously, all lookups were O(N) because of the use of the linked
+ list and also all insertions were O(N) because of the check for
+ duplicates. There are some complications here because the array
+ size grows occasionally, which may add an O(N) factor, but this
+ should be rare. Also, we free the excess array allocation, which
+ requires a copy which is O(N), but this only happens once. */
+
+static struct elfNN_ia64_dyn_sym_info *
+get_dyn_sym_info (struct elfNN_ia64_link_hash_table *ia64_info,
+ struct elf_link_hash_entry *h, bfd *abfd,
+ const Elf_Internal_Rela *rel, bfd_boolean create)
+{
+ struct elfNN_ia64_dyn_sym_info **info_p, *info, *dyn_i, key;
+ unsigned int *count_p, *sorted_count_p, *size_p;
+ unsigned int count, sorted_count, size;
+ bfd_vma addend = rel ? rel->r_addend : 0;
+ bfd_size_type amt;
+
+ if (h)
+ {
+ struct elfNN_ia64_link_hash_entry *global_h;
+
+ global_h = (struct elfNN_ia64_link_hash_entry *) h;
+ info_p = &global_h->info;
+ count_p = &global_h->count;
+ sorted_count_p = &global_h->sorted_count;
+ size_p = &global_h->size;
+ }
+ else
+ {
+ struct elfNN_ia64_local_hash_entry *loc_h;
+
+ loc_h = get_local_sym_hash (ia64_info, abfd, rel, create);
+ if (!loc_h)
+ {
+ BFD_ASSERT (!create);
+ return NULL;
+ }
+
+ info_p = &loc_h->info;
+ count_p = &loc_h->count;
+ sorted_count_p = &loc_h->sorted_count;
+ size_p = &loc_h->size;
+ }
+
+ count = *count_p;
+ sorted_count = *sorted_count_p;
+ size = *size_p;
+ info = *info_p;
+ if (create)
+ {
+ /* When we create the array, we don't check for duplicates,
+ except in the previously sorted section if one exists, and
+ against the last inserted entry. This allows insertions to
+ be fast. */
+ if (info)
+ {
+ if (sorted_count)
+ {
+ /* Try bsearch first on the sorted section. */
+ key.addend = addend;
+ dyn_i = bsearch (&key, info, sorted_count,
+ sizeof (*info), addend_compare);
+
+ if (dyn_i)
+ {
+ return dyn_i;
+ }
+ }
+
+ /* Do a quick check for the last inserted entry. */
+ dyn_i = info + count - 1;
+ if (dyn_i->addend == addend)
+ {
+ return dyn_i;
+ }
+ }
+
+ if (size == 0)
+ {
+ /* It is the very first element. We create the array of size
+ 1. */
+ size = 1;
+ amt = size * sizeof (*info);
+ info = bfd_malloc (amt);
+ }
+ else if (size <= count)
+ {
+ /* We double the array size every time when we reach the
+ size limit. */
+ size += size;
+ amt = size * sizeof (*info);
+ info = bfd_realloc (info, amt);
+ }
+ else
+ goto has_space;
+
+ if (info == NULL)
+ return NULL;
+ *size_p = size;
+ *info_p = info;
+
+has_space:
+ /* Append the new one to the array. */
+ dyn_i = info + count;
+ memset (dyn_i, 0, sizeof (*dyn_i));
+ dyn_i->got_offset = (bfd_vma) -1;
+ dyn_i->addend = addend;
+
+ /* We increment count only since the new ones are unsorted and
+ may have duplicate. */
+ (*count_p)++;
+ }
+ else
+ {
+ /* It is a lookup without insertion. Sort array if part of the
+ array isn't sorted. */
+ if (count != sorted_count)
+ {
+ count = sort_dyn_sym_info (info, count);
+ *count_p = count;
+ *sorted_count_p = count;
+ }
+
+ /* Free unused memory. */
+ if (size != count)
+ {
+ amt = count * sizeof (*info);
+ info = bfd_malloc (amt);
+ if (info != NULL)
+ {
+ memcpy (info, *info_p, amt);
+ free (*info_p);
+ *size_p = count;
+ *info_p = info;
+ }
+ }
+
+ key.addend = addend;
+ dyn_i = bsearch (&key, info, count,
+ sizeof (*info), addend_compare);
+ }
+
+ return dyn_i;
+}
+
+static asection *
+get_got (bfd *abfd, struct bfd_link_info *info,
+ struct elfNN_ia64_link_hash_table *ia64_info)
+{
+ asection *got;
+ bfd *dynobj;
+
+ got = ia64_info->root.sgot;
+ if (!got)
+ {
+ flagword flags;
+
+ dynobj = ia64_info->root.dynobj;
+ if (!dynobj)
+ ia64_info->root.dynobj = dynobj = abfd;
+ if (!_bfd_elf_create_got_section (dynobj, info))
+ return NULL;
+
+ got = ia64_info->root.sgot;
+
+ /* The .got section is always aligned at 8 bytes. */
+ if (!bfd_set_section_alignment (abfd, got, 3))
+ return NULL;
+
+ flags = bfd_get_section_flags (abfd, got);
+ if (! bfd_set_section_flags (abfd, got, SEC_SMALL_DATA | flags))
+ return NULL;
+ }
+
+ return got;
+}
+
+/* Create function descriptor section (.opd). This section is called .opd
+ because it contains "official procedure descriptors". The "official"
+ refers to the fact that these descriptors are used when taking the address
+ of a procedure, thus ensuring a unique address for each procedure. */
+
+static asection *
+get_fptr (bfd *abfd, struct bfd_link_info *info,
+ struct elfNN_ia64_link_hash_table *ia64_info)
+{
+ asection *fptr;
+ bfd *dynobj;
+
+ fptr = ia64_info->fptr_sec;
+ if (!fptr)
+ {
+ dynobj = ia64_info->root.dynobj;
+ if (!dynobj)
+ ia64_info->root.dynobj = dynobj = abfd;
+
+ fptr = bfd_make_section_anyway_with_flags (dynobj, ".opd",
+ (SEC_ALLOC
+ | SEC_LOAD
+ | SEC_HAS_CONTENTS
+ | SEC_IN_MEMORY
+ | (info->pie ? 0
+ : SEC_READONLY)
+ | SEC_LINKER_CREATED));
+ if (!fptr
+ || !bfd_set_section_alignment (abfd, fptr, 4))
+ {
+ BFD_ASSERT (0);
+ return NULL;
+ }
+
+ ia64_info->fptr_sec = fptr;
+
+ if (info->pie)
+ {
+ asection *fptr_rel;
+ fptr_rel = bfd_make_section_anyway_with_flags (dynobj, ".rela.opd",
+ (SEC_ALLOC | SEC_LOAD
+ | SEC_HAS_CONTENTS
+ | SEC_IN_MEMORY
+ | SEC_LINKER_CREATED
+ | SEC_READONLY));
+ if (fptr_rel == NULL
+ || !bfd_set_section_alignment (abfd, fptr_rel,
+ LOG_SECTION_ALIGN))
+ {
+ BFD_ASSERT (0);
+ return NULL;
+ }
+
+ ia64_info->rel_fptr_sec = fptr_rel;
+ }
+ }
+
+ return fptr;
+}
+
+static asection *
+get_pltoff (bfd *abfd, struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ struct elfNN_ia64_link_hash_table *ia64_info)
+{
+ asection *pltoff;
+ bfd *dynobj;
+
+ pltoff = ia64_info->pltoff_sec;
+ if (!pltoff)
+ {
+ dynobj = ia64_info->root.dynobj;
+ if (!dynobj)
+ ia64_info->root.dynobj = dynobj = abfd;
+
+ pltoff = bfd_make_section_anyway_with_flags (dynobj,
+ ELF_STRING_ia64_pltoff,
+ (SEC_ALLOC
+ | SEC_LOAD
+ | SEC_HAS_CONTENTS
+ | SEC_IN_MEMORY
+ | SEC_SMALL_DATA
+ | SEC_LINKER_CREATED));
+ if (!pltoff
+ || !bfd_set_section_alignment (abfd, pltoff, 4))
+ {
+ BFD_ASSERT (0);
+ return NULL;
+ }
+
+ ia64_info->pltoff_sec = pltoff;
+ }
+
+ return pltoff;
+}
+
+static asection *
+get_reloc_section (bfd *abfd,
+ struct elfNN_ia64_link_hash_table *ia64_info,
+ asection *sec, bfd_boolean create)
+{
+ const char *srel_name;
+ asection *srel;
+ bfd *dynobj;
+
+ srel_name = (bfd_elf_string_from_elf_section
+ (abfd, elf_elfheader(abfd)->e_shstrndx,
+ _bfd_elf_single_rel_hdr (sec)->sh_name));
+ if (srel_name == NULL)
+ return NULL;
+
+ dynobj = ia64_info->root.dynobj;
+ if (!dynobj)
+ ia64_info->root.dynobj = dynobj = abfd;
+
+ srel = bfd_get_linker_section (dynobj, srel_name);
+ if (srel == NULL && create)
+ {
+ srel = bfd_make_section_anyway_with_flags (dynobj, srel_name,
+ (SEC_ALLOC | SEC_LOAD
+ | SEC_HAS_CONTENTS
+ | SEC_IN_MEMORY
+ | SEC_LINKER_CREATED
+ | SEC_READONLY));
+ if (srel == NULL
+ || !bfd_set_section_alignment (dynobj, srel,
+ LOG_SECTION_ALIGN))
+ return NULL;
+ }
+
+ return srel;
+}
+
+static bfd_boolean
+count_dyn_reloc (bfd *abfd, struct elfNN_ia64_dyn_sym_info *dyn_i,
+ asection *srel, int type, bfd_boolean reltext)
+{
+ struct elfNN_ia64_dyn_reloc_entry *rent;
+
+ for (rent = dyn_i->reloc_entries; rent; rent = rent->next)
+ if (rent->srel == srel && rent->type == type)
+ break;
+
+ if (!rent)
+ {
+ rent = ((struct elfNN_ia64_dyn_reloc_entry *)
+ bfd_alloc (abfd, (bfd_size_type) sizeof (*rent)));
+ if (!rent)
+ return FALSE;
+
+ rent->next = dyn_i->reloc_entries;
+ rent->srel = srel;
+ rent->type = type;
+ rent->count = 0;
+ dyn_i->reloc_entries = rent;
+ }
+ rent->reltext = reltext;
+ rent->count++;
+
+ return TRUE;
+}
+
+static bfd_boolean
+elfNN_ia64_check_relocs (bfd *abfd, struct bfd_link_info *info,
+ asection *sec,
+ const Elf_Internal_Rela *relocs)
+{
+ struct elfNN_ia64_link_hash_table *ia64_info;
+ const Elf_Internal_Rela *relend;
+ Elf_Internal_Shdr *symtab_hdr;
+ const Elf_Internal_Rela *rel;
+ asection *got, *fptr, *srel, *pltoff;
+ enum {
+ NEED_GOT = 1,
+ NEED_GOTX = 2,
+ NEED_FPTR = 4,
+ NEED_PLTOFF = 8,
+ NEED_MIN_PLT = 16,
+ NEED_FULL_PLT = 32,
+ NEED_DYNREL = 64,
+ NEED_LTOFF_FPTR = 128,
+ NEED_TPREL = 256,
+ NEED_DTPMOD = 512,
+ NEED_DTPREL = 1024
+ };
+ int need_entry;
+ struct elf_link_hash_entry *h;
+ unsigned long r_symndx;
+ bfd_boolean maybe_dynamic;
+
+ if (info->relocatable)
+ return TRUE;
+
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+ ia64_info = elfNN_ia64_hash_table (info);
+ if (ia64_info == NULL)
+ return FALSE;
+
+ got = fptr = srel = pltoff = NULL;
+
+ relend = relocs + sec->reloc_count;
+
+ /* We scan relocations first to create dynamic relocation arrays. We
+ modified get_dyn_sym_info to allow fast insertion and support fast
+ lookup in the next loop. */
+ for (rel = relocs; rel < relend; ++rel)
+ {
+ r_symndx = ELFNN_R_SYM (rel->r_info);
+ if (r_symndx >= symtab_hdr->sh_info)
+ {
+ long indx = r_symndx - symtab_hdr->sh_info;
+ h = elf_sym_hashes (abfd)[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;
+ }
+ else
+ h = NULL;
+
+ /* We can only get preliminary data on whether a symbol is
+ locally or externally defined, as not all of the input files
+ have yet been processed. Do something with what we know, as
+ this may help reduce memory usage and processing time later. */
+ maybe_dynamic = (h && ((!info->executable
+ && (!SYMBOLIC_BIND (info, h)
+ || info->unresolved_syms_in_shared_libs == RM_IGNORE))
+ || !h->def_regular
+ || h->root.type == bfd_link_hash_defweak));
+
+ need_entry = 0;
+ switch (ELFNN_R_TYPE (rel->r_info))
+ {
+ case R_IA64_TPREL64MSB:
+ case R_IA64_TPREL64LSB:
+ if (info->shared || maybe_dynamic)
+ need_entry = NEED_DYNREL;
+ break;
+
+ case R_IA64_LTOFF_TPREL22:
+ need_entry = NEED_TPREL;
+ if (info->shared)
+ info->flags |= DF_STATIC_TLS;
+ break;
+
+ case R_IA64_DTPREL32MSB:
+ case R_IA64_DTPREL32LSB:
+ case R_IA64_DTPREL64MSB:
+ case R_IA64_DTPREL64LSB:
+ if (info->shared || maybe_dynamic)
+ need_entry = NEED_DYNREL;
+ break;
+
+ case R_IA64_LTOFF_DTPREL22:
+ need_entry = NEED_DTPREL;
+ break;
+
+ case R_IA64_DTPMOD64MSB:
+ case R_IA64_DTPMOD64LSB:
+ if (info->shared || maybe_dynamic)
+ need_entry = NEED_DYNREL;
+ break;
+
+ case R_IA64_LTOFF_DTPMOD22:
+ need_entry = NEED_DTPMOD;
+ break;
+
+ case R_IA64_LTOFF_FPTR22:
+ case R_IA64_LTOFF_FPTR64I:
+ case R_IA64_LTOFF_FPTR32MSB:
+ case R_IA64_LTOFF_FPTR32LSB:
+ case R_IA64_LTOFF_FPTR64MSB:
+ case R_IA64_LTOFF_FPTR64LSB:
+ need_entry = NEED_FPTR | NEED_GOT | NEED_LTOFF_FPTR;
+ break;
+
+ case R_IA64_FPTR64I:
+ case R_IA64_FPTR32MSB:
+ case R_IA64_FPTR32LSB:
+ case R_IA64_FPTR64MSB:
+ case R_IA64_FPTR64LSB:
+ if (info->shared || h)
+ need_entry = NEED_FPTR | NEED_DYNREL;
+ else
+ need_entry = NEED_FPTR;
+ break;
+
+ case R_IA64_LTOFF22:
+ case R_IA64_LTOFF64I:
+ need_entry = NEED_GOT;
+ break;
+
+ case R_IA64_LTOFF22X:
+ need_entry = NEED_GOTX;
+ break;
+
+ case R_IA64_PLTOFF22:
+ case R_IA64_PLTOFF64I:
+ case R_IA64_PLTOFF64MSB:
+ case R_IA64_PLTOFF64LSB:
+ need_entry = NEED_PLTOFF;
+ if (h)
+ {
+ if (maybe_dynamic)
+ need_entry |= NEED_MIN_PLT;
+ }
+ else
+ {
+ (*info->callbacks->warning)
+ (info, _("@pltoff reloc against local symbol"), 0,
+ abfd, 0, (bfd_vma) 0);
+ }
+ break;
+
+ case R_IA64_PCREL21B:
+ case R_IA64_PCREL60B:
+ /* Depending on where this symbol is defined, we may or may not
+ need a full plt entry. Only skip if we know we'll not need
+ the entry -- static or symbolic, and the symbol definition
+ has already been seen. */
+ if (maybe_dynamic && rel->r_addend == 0)
+ need_entry = NEED_FULL_PLT;
+ break;
+
+ case R_IA64_IMM14:
+ case R_IA64_IMM22:
+ case R_IA64_IMM64:
+ case R_IA64_DIR32MSB:
+ case R_IA64_DIR32LSB:
+ case R_IA64_DIR64MSB:
+ case R_IA64_DIR64LSB:
+ /* Shared objects will always need at least a REL relocation. */
+ if (info->shared || maybe_dynamic)
+ need_entry = NEED_DYNREL;
+ break;
+
+ case R_IA64_IPLTMSB:
+ case R_IA64_IPLTLSB:
+ /* Shared objects will always need at least a REL relocation. */
+ if (info->shared || maybe_dynamic)
+ need_entry = NEED_DYNREL;
+ break;
+
+ case R_IA64_PCREL22:
+ case R_IA64_PCREL64I:
+ case R_IA64_PCREL32MSB:
+ case R_IA64_PCREL32LSB:
+ case R_IA64_PCREL64MSB:
+ case R_IA64_PCREL64LSB:
+ if (maybe_dynamic)
+ need_entry = NEED_DYNREL;
+ break;
+ }
+
+ if (!need_entry)
+ continue;
+
+ if ((need_entry & NEED_FPTR) != 0
+ && rel->r_addend)
+ {
+ (*info->callbacks->warning)
+ (info, _("non-zero addend in @fptr reloc"), 0,
+ abfd, 0, (bfd_vma) 0);
+ }
+
+ if (get_dyn_sym_info (ia64_info, h, abfd, rel, TRUE) == NULL)
+ return FALSE;
+ }
+
+ /* Now, we only do lookup without insertion, which is very fast
+ with the modified get_dyn_sym_info. */
+ for (rel = relocs; rel < relend; ++rel)
+ {
+ struct elfNN_ia64_dyn_sym_info *dyn_i;
+ int dynrel_type = R_IA64_NONE;
+
+ r_symndx = ELFNN_R_SYM (rel->r_info);
+ if (r_symndx >= symtab_hdr->sh_info)
+ {
+ /* We're dealing with a global symbol -- find its hash entry
+ and mark it as being referenced. */
+ long indx = r_symndx - symtab_hdr->sh_info;
+ h = elf_sym_hashes (abfd)[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;
+
+ /* PR15323, ref flags aren't set for references in the same
+ object. */
+ h->root.non_ir_ref = 1;
+ h->ref_regular = 1;
+ }
+ else
+ h = NULL;
+
+ /* We can only get preliminary data on whether a symbol is
+ locally or externally defined, as not all of the input files
+ have yet been processed. Do something with what we know, as
+ this may help reduce memory usage and processing time later. */
+ maybe_dynamic = (h && ((!info->executable
+ && (!SYMBOLIC_BIND (info, h)
+ || info->unresolved_syms_in_shared_libs == RM_IGNORE))
+ || !h->def_regular
+ || h->root.type == bfd_link_hash_defweak));
+
+ need_entry = 0;
+ switch (ELFNN_R_TYPE (rel->r_info))
+ {
+ case R_IA64_TPREL64MSB:
+ case R_IA64_TPREL64LSB:
+ if (info->shared || maybe_dynamic)
+ need_entry = NEED_DYNREL;
+ dynrel_type = R_IA64_TPREL64LSB;
+ if (info->shared)
+ info->flags |= DF_STATIC_TLS;
+ break;
+
+ case R_IA64_LTOFF_TPREL22:
+ need_entry = NEED_TPREL;
+ if (info->shared)
+ info->flags |= DF_STATIC_TLS;
+ break;
+
+ case R_IA64_DTPREL32MSB:
+ case R_IA64_DTPREL32LSB:
+ case R_IA64_DTPREL64MSB:
+ case R_IA64_DTPREL64LSB:
+ if (info->shared || maybe_dynamic)
+ need_entry = NEED_DYNREL;
+ dynrel_type = R_IA64_DTPRELNNLSB;
+ break;
+
+ case R_IA64_LTOFF_DTPREL22:
+ need_entry = NEED_DTPREL;
+ break;
+
+ case R_IA64_DTPMOD64MSB:
+ case R_IA64_DTPMOD64LSB:
+ if (info->shared || maybe_dynamic)
+ need_entry = NEED_DYNREL;
+ dynrel_type = R_IA64_DTPMOD64LSB;
+ break;
+
+ case R_IA64_LTOFF_DTPMOD22:
+ need_entry = NEED_DTPMOD;
+ break;
+
+ case R_IA64_LTOFF_FPTR22:
+ case R_IA64_LTOFF_FPTR64I:
+ case R_IA64_LTOFF_FPTR32MSB:
+ case R_IA64_LTOFF_FPTR32LSB:
+ case R_IA64_LTOFF_FPTR64MSB:
+ case R_IA64_LTOFF_FPTR64LSB:
+ need_entry = NEED_FPTR | NEED_GOT | NEED_LTOFF_FPTR;
+ break;
+
+ case R_IA64_FPTR64I:
+ case R_IA64_FPTR32MSB:
+ case R_IA64_FPTR32LSB:
+ case R_IA64_FPTR64MSB:
+ case R_IA64_FPTR64LSB:
+ if (info->shared || h)
+ need_entry = NEED_FPTR | NEED_DYNREL;
+ else
+ need_entry = NEED_FPTR;
+ dynrel_type = R_IA64_FPTRNNLSB;
+ break;
+
+ case R_IA64_LTOFF22:
+ case R_IA64_LTOFF64I:
+ need_entry = NEED_GOT;
+ break;
+
+ case R_IA64_LTOFF22X:
+ need_entry = NEED_GOTX;
+ break;
+
+ case R_IA64_PLTOFF22:
+ case R_IA64_PLTOFF64I:
+ case R_IA64_PLTOFF64MSB:
+ case R_IA64_PLTOFF64LSB:
+ need_entry = NEED_PLTOFF;
+ if (h)
+ {
+ if (maybe_dynamic)
+ need_entry |= NEED_MIN_PLT;
+ }
+ break;
+
+ case R_IA64_PCREL21B:
+ case R_IA64_PCREL60B:
+ /* Depending on where this symbol is defined, we may or may not
+ need a full plt entry. Only skip if we know we'll not need
+ the entry -- static or symbolic, and the symbol definition
+ has already been seen. */
+ if (maybe_dynamic && rel->r_addend == 0)
+ need_entry = NEED_FULL_PLT;
+ break;
+
+ case R_IA64_IMM14:
+ case R_IA64_IMM22:
+ case R_IA64_IMM64:
+ case R_IA64_DIR32MSB:
+ case R_IA64_DIR32LSB:
+ case R_IA64_DIR64MSB:
+ case R_IA64_DIR64LSB:
+ /* Shared objects will always need at least a REL relocation. */
+ if (info->shared || maybe_dynamic)
+ need_entry = NEED_DYNREL;
+ dynrel_type = R_IA64_DIRNNLSB;
+ break;
+
+ case R_IA64_IPLTMSB:
+ case R_IA64_IPLTLSB:
+ /* Shared objects will always need at least a REL relocation. */
+ if (info->shared || maybe_dynamic)
+ need_entry = NEED_DYNREL;
+ dynrel_type = R_IA64_IPLTLSB;
+ break;
+
+ case R_IA64_PCREL22:
+ case R_IA64_PCREL64I:
+ case R_IA64_PCREL32MSB:
+ case R_IA64_PCREL32LSB:
+ case R_IA64_PCREL64MSB:
+ case R_IA64_PCREL64LSB:
+ if (maybe_dynamic)
+ need_entry = NEED_DYNREL;
+ dynrel_type = R_IA64_PCRELNNLSB;
+ break;
+ }
+
+ if (!need_entry)
+ continue;
+
+ dyn_i = get_dyn_sym_info (ia64_info, h, abfd, rel, FALSE);
+
+ /* Record whether or not this is a local symbol. */
+ dyn_i->h = h;
+
+ /* Create what's needed. */
+ if (need_entry & (NEED_GOT | NEED_GOTX | NEED_TPREL
+ | NEED_DTPMOD | NEED_DTPREL))
+ {
+ if (!got)
+ {
+ got = get_got (abfd, info, ia64_info);
+ if (!got)
+ return FALSE;
+ }
+ if (need_entry & NEED_GOT)
+ dyn_i->want_got = 1;
+ if (need_entry & NEED_GOTX)
+ dyn_i->want_gotx = 1;
+ if (need_entry & NEED_TPREL)
+ dyn_i->want_tprel = 1;
+ if (need_entry & NEED_DTPMOD)
+ dyn_i->want_dtpmod = 1;
+ if (need_entry & NEED_DTPREL)
+ dyn_i->want_dtprel = 1;
+ }
+ if (need_entry & NEED_FPTR)
+ {
+ if (!fptr)
+ {
+ fptr = get_fptr (abfd, info, ia64_info);
+ if (!fptr)
+ return FALSE;
+ }
+
+ /* FPTRs for shared libraries are allocated by the dynamic
+ linker. Make sure this local symbol will appear in the
+ dynamic symbol table. */
+ if (!h && info->shared)
+ {
+ if (! (bfd_elf_link_record_local_dynamic_symbol
+ (info, abfd, (long) r_symndx)))
+ return FALSE;
+ }
+
+ dyn_i->want_fptr = 1;
+ }
+ if (need_entry & NEED_LTOFF_FPTR)
+ dyn_i->want_ltoff_fptr = 1;
+ if (need_entry & (NEED_MIN_PLT | NEED_FULL_PLT))
+ {
+ if (!ia64_info->root.dynobj)
+ ia64_info->root.dynobj = abfd;
+ h->needs_plt = 1;
+ dyn_i->want_plt = 1;
+ }
+ if (need_entry & NEED_FULL_PLT)
+ dyn_i->want_plt2 = 1;
+ if (need_entry & NEED_PLTOFF)
+ {
+ /* This is needed here, in case @pltoff is used in a non-shared
+ link. */
+ if (!pltoff)
+ {
+ pltoff = get_pltoff (abfd, info, ia64_info);
+ if (!pltoff)
+ return FALSE;
+ }
+
+ dyn_i->want_pltoff = 1;
+ }
+ if ((need_entry & NEED_DYNREL) && (sec->flags & SEC_ALLOC))
+ {
+ if (!srel)
+ {
+ srel = get_reloc_section (abfd, ia64_info, sec, TRUE);
+ if (!srel)
+ return FALSE;
+ }
+ if (!count_dyn_reloc (abfd, dyn_i, srel, dynrel_type,
+ (sec->flags & SEC_READONLY) != 0))
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+/* For cleanliness, and potentially faster dynamic loading, allocate
+ external GOT entries first. */
+
+static bfd_boolean
+allocate_global_data_got (struct elfNN_ia64_dyn_sym_info *dyn_i,
+ void * data)
+{
+ struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
+
+ if ((dyn_i->want_got || dyn_i->want_gotx)
+ && ! dyn_i->want_fptr
+ && elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info, 0))
+ {
+ dyn_i->got_offset = x->ofs;
+ x->ofs += 8;
+ }
+ if (dyn_i->want_tprel)
+ {
+ dyn_i->tprel_offset = x->ofs;
+ x->ofs += 8;
+ }
+ if (dyn_i->want_dtpmod)
+ {
+ if (elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info, 0))
+ {
+ dyn_i->dtpmod_offset = x->ofs;
+ x->ofs += 8;
+ }
+ else
+ {
+ struct elfNN_ia64_link_hash_table *ia64_info;
+
+ ia64_info = elfNN_ia64_hash_table (x->info);
+ if (ia64_info == NULL)
+ return FALSE;
+
+ if (ia64_info->self_dtpmod_offset == (bfd_vma) -1)
+ {
+ ia64_info->self_dtpmod_offset = x->ofs;
+ x->ofs += 8;
+ }
+ dyn_i->dtpmod_offset = ia64_info->self_dtpmod_offset;
+ }
+ }
+ if (dyn_i->want_dtprel)
+ {
+ dyn_i->dtprel_offset = x->ofs;
+ x->ofs += 8;
+ }
+ return TRUE;
+}
+
+/* Next, allocate all the GOT entries used by LTOFF_FPTR relocs. */
+
+static bfd_boolean
+allocate_global_fptr_got (struct elfNN_ia64_dyn_sym_info *dyn_i,
+ void * data)
+{
+ struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
+
+ if (dyn_i->want_got
+ && dyn_i->want_fptr
+ && elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info, R_IA64_FPTRNNLSB))
+ {
+ dyn_i->got_offset = x->ofs;
+ x->ofs += 8;
+ }
+ return TRUE;
+}
+
+/* Lastly, allocate all the GOT entries for local data. */
+
+static bfd_boolean
+allocate_local_got (struct elfNN_ia64_dyn_sym_info *dyn_i,
+ void * data)
+{
+ struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
+
+ if ((dyn_i->want_got || dyn_i->want_gotx)
+ && !elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info, 0))
+ {
+ dyn_i->got_offset = x->ofs;
+ x->ofs += 8;
+ }
+ return TRUE;
+}
+
+/* Search for the index of a global symbol in it's defining object file. */
+
+static long
+global_sym_index (struct elf_link_hash_entry *h)
+{
+ struct elf_link_hash_entry **p;
+ bfd *obj;
+
+ BFD_ASSERT (h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak);
+
+ obj = h->root.u.def.section->owner;
+ for (p = elf_sym_hashes (obj); *p != h; ++p)
+ continue;
+
+ return p - elf_sym_hashes (obj) + elf_tdata (obj)->symtab_hdr.sh_info;
+}
+
+/* Allocate function descriptors. We can do these for every function
+ in a main executable that is not exported. */
+
+static bfd_boolean
+allocate_fptr (struct elfNN_ia64_dyn_sym_info *dyn_i, void * data)
+{
+ struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
+
+ if (dyn_i->want_fptr)
+ {
+ struct elf_link_hash_entry *h = dyn_i->h;
+
+ if (h)
+ 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 (!x->info->executable
+ && (!h
+ || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
+ || (h->root.type != bfd_link_hash_undefweak
+ && h->root.type != bfd_link_hash_undefined)))
+ {
+ if (h && h->dynindx == -1)
+ {
+ BFD_ASSERT ((h->root.type == bfd_link_hash_defined)
+ || (h->root.type == bfd_link_hash_defweak));
+
+ if (!bfd_elf_link_record_local_dynamic_symbol
+ (x->info, h->root.u.def.section->owner,
+ global_sym_index (h)))
+ return FALSE;
+ }
+
+ dyn_i->want_fptr = 0;
+ }
+ else if (h == NULL || h->dynindx == -1)
+ {
+ dyn_i->fptr_offset = x->ofs;
+ x->ofs += 16;
+ }
+ else
+ dyn_i->want_fptr = 0;
+ }
+ return TRUE;
+}
+
+/* Allocate all the minimal PLT entries. */
+
+static bfd_boolean
+allocate_plt_entries (struct elfNN_ia64_dyn_sym_info *dyn_i,
+ void * data)
+{
+ struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
+
+ if (dyn_i->want_plt)
+ {
+ struct elf_link_hash_entry *h = dyn_i->h;
+
+ if (h)
+ 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;
+
+ /* ??? Versioned symbols seem to lose NEEDS_PLT. */
+ if (elfNN_ia64_dynamic_symbol_p (h, x->info, 0))
+ {
+ bfd_size_type offset = x->ofs;
+ if (offset == 0)
+ offset = PLT_HEADER_SIZE;
+ dyn_i->plt_offset = offset;
+ x->ofs = offset + PLT_MIN_ENTRY_SIZE;
+
+ dyn_i->want_pltoff = 1;
+ }
+ else
+ {
+ dyn_i->want_plt = 0;
+ dyn_i->want_plt2 = 0;
+ }
+ }
+ return TRUE;
+}
+
+/* Allocate all the full PLT entries. */
+
+static bfd_boolean
+allocate_plt2_entries (struct elfNN_ia64_dyn_sym_info *dyn_i,
+ void * data)
+{
+ struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
+
+ if (dyn_i->want_plt2)
+ {
+ struct elf_link_hash_entry *h = dyn_i->h;
+ bfd_size_type ofs = x->ofs;
+
+ dyn_i->plt2_offset = ofs;
+ x->ofs = ofs + PLT_FULL_ENTRY_SIZE;
+
+ 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;
+ dyn_i->h->plt.offset = ofs;
+ }
+ return TRUE;
+}
+
+/* Allocate all the PLTOFF entries requested by relocations and
+ plt entries. We can't share space with allocated FPTR entries,
+ because the latter are not necessarily addressable by the GP.
+ ??? Relaxation might be able to determine that they are. */
+
+static bfd_boolean
+allocate_pltoff_entries (struct elfNN_ia64_dyn_sym_info *dyn_i,
+ void * data)
+{
+ struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
+
+ if (dyn_i->want_pltoff)
+ {
+ dyn_i->pltoff_offset = x->ofs;
+ x->ofs += 16;
+ }
+ return TRUE;
+}
+
+/* Allocate dynamic relocations for those symbols that turned out
+ to be dynamic. */
+
+static bfd_boolean
+allocate_dynrel_entries (struct elfNN_ia64_dyn_sym_info *dyn_i,
+ void * data)
+{
+ struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
+ struct elfNN_ia64_link_hash_table *ia64_info;
+ struct elfNN_ia64_dyn_reloc_entry *rent;
+ bfd_boolean dynamic_symbol, shared, resolved_zero;
+
+ ia64_info = elfNN_ia64_hash_table (x->info);
+ if (ia64_info == NULL)
+ return FALSE;
+
+ /* Note that this can't be used in relation to FPTR relocs below. */
+ dynamic_symbol = elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info, 0);
+
+ shared = x->info->shared;
+ resolved_zero = (dyn_i->h
+ && ELF_ST_VISIBILITY (dyn_i->h->other)
+ && dyn_i->h->root.type == bfd_link_hash_undefweak);
+
+ /* Take care of the GOT and PLT relocations. */
+
+ if ((!resolved_zero
+ && (dynamic_symbol || shared)
+ && (dyn_i->want_got || dyn_i->want_gotx))
+ || (dyn_i->want_ltoff_fptr
+ && dyn_i->h
+ && dyn_i->h->dynindx != -1))
+ {
+ if (!dyn_i->want_ltoff_fptr
+ || !x->info->pie
+ || dyn_i->h == NULL
+ || dyn_i->h->root.type != bfd_link_hash_undefweak)
+ ia64_info->root.srelgot->size += sizeof (ElfNN_External_Rela);
+ }
+ if ((dynamic_symbol || shared) && dyn_i->want_tprel)
+ ia64_info->root.srelgot->size += sizeof (ElfNN_External_Rela);
+ if (dynamic_symbol && dyn_i->want_dtpmod)
+ ia64_info->root.srelgot->size += sizeof (ElfNN_External_Rela);
+ if (dynamic_symbol && dyn_i->want_dtprel)
+ ia64_info->root.srelgot->size += sizeof (ElfNN_External_Rela);
+
+ if (x->only_got)
+ return TRUE;
+
+ if (ia64_info->rel_fptr_sec && dyn_i->want_fptr)
+ {
+ if (dyn_i->h == NULL || dyn_i->h->root.type != bfd_link_hash_undefweak)
+ ia64_info->rel_fptr_sec->size += sizeof (ElfNN_External_Rela);
+ }
+
+ if (!resolved_zero && dyn_i->want_pltoff)
+ {
+ bfd_size_type t = 0;
+
+ /* Dynamic symbols get one IPLT relocation. Local symbols in
+ shared libraries get two REL relocations. Local symbols in
+ main applications get nothing. */
+ if (dynamic_symbol)
+ t = sizeof (ElfNN_External_Rela);
+ else if (shared)
+ t = 2 * sizeof (ElfNN_External_Rela);
+
+ ia64_info->rel_pltoff_sec->size += t;
+ }
+
+ /* Take care of the normal data relocations. */
+
+ for (rent = dyn_i->reloc_entries; rent; rent = rent->next)
+ {
+ int count = rent->count;
+
+ switch (rent->type)
+ {
+ case R_IA64_FPTR32LSB:
+ case R_IA64_FPTR64LSB:
+ /* Allocate one iff !want_fptr and not PIE, which by this point
+ will be true only if we're actually allocating one statically
+ in the main executable. Position independent executables
+ need a relative reloc. */
+ if (dyn_i->want_fptr && !x->info->pie)
+ continue;
+ break;
+ case R_IA64_PCREL32LSB:
+ case R_IA64_PCREL64LSB:
+ if (!dynamic_symbol)
+ continue;
+ break;
+ case R_IA64_DIR32LSB:
+ case R_IA64_DIR64LSB:
+ if (!dynamic_symbol && !shared)
+ continue;
+ break;
+ case R_IA64_IPLTLSB:
+ if (!dynamic_symbol && !shared)
+ continue;
+ /* Use two REL relocations for IPLT relocations
+ against local symbols. */
+ if (!dynamic_symbol)
+ count *= 2;
+ break;
+ case R_IA64_DTPREL32LSB:
+ case R_IA64_TPREL64LSB:
+ case R_IA64_DTPREL64LSB:
+ case R_IA64_DTPMOD64LSB:
+ break;
+ default:
+ abort ();
+ }
+ if (rent->reltext)
+ ia64_info->reltext = 1;
+ rent->srel->size += sizeof (ElfNN_External_Rela) * count;
+ }
+
+ return TRUE;
+}
+
+static bfd_boolean
+elfNN_ia64_adjust_dynamic_symbol (struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ struct elf_link_hash_entry *h)
+{
+ /* ??? Undefined symbols with PLT entries should be re-defined
+ to be the PLT entry. */
+
+ /* 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->u.weakdef != NULL)
+ {
+ BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
+ || h->u.weakdef->root.type == bfd_link_hash_defweak);
+ h->root.u.def.section = h->u.weakdef->root.u.def.section;
+ h->root.u.def.value = h->u.weakdef->root.u.def.value;
+ return TRUE;
+ }
+
+ /* If this is a reference to a symbol defined by a dynamic object which
+ is not a function, we might allocate the symbol in our .dynbss section
+ and allocate a COPY dynamic relocation.
+
+ But IA-64 code is canonically PIC, so as a rule we can avoid this sort
+ of hackery. */
+
+ return TRUE;
+}
+
+static bfd_boolean
+elfNN_ia64_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
+ struct bfd_link_info *info)
+{
+ struct elfNN_ia64_allocate_data data;
+ struct elfNN_ia64_link_hash_table *ia64_info;
+ asection *sec;
+ bfd *dynobj;
+ bfd_boolean relplt = FALSE;
+
+ dynobj = elf_hash_table(info)->dynobj;
+ ia64_info = elfNN_ia64_hash_table (info);
+ if (ia64_info == NULL)
+ return FALSE;
+ ia64_info->self_dtpmod_offset = (bfd_vma) -1;
+ BFD_ASSERT(dynobj != NULL);
+ data.info = info;
+
+ /* Set the contents of the .interp section to the interpreter. */
+ if (ia64_info->root.dynamic_sections_created
+ && info->executable)
+ {
+ sec = bfd_get_linker_section (dynobj, ".interp");
+ BFD_ASSERT (sec != NULL);
+ sec->contents = (bfd_byte *) ELF_DYNAMIC_INTERPRETER;
+ sec->size = strlen (ELF_DYNAMIC_INTERPRETER) + 1;
+ }
+
+ /* Allocate the GOT entries. */
+
+ if (ia64_info->root.sgot)
+ {
+ data.ofs = 0;
+ elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_global_data_got, &data);
+ elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_global_fptr_got, &data);
+ elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_local_got, &data);
+ ia64_info->root.sgot->size = data.ofs;
+ }
+
+ /* Allocate the FPTR entries. */
+
+ if (ia64_info->fptr_sec)
+ {
+ data.ofs = 0;
+ elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_fptr, &data);
+ ia64_info->fptr_sec->size = data.ofs;
+ }
+
+ /* Now that we've seen all of the input files, we can decide which
+ symbols need plt entries. Allocate the minimal PLT entries first.
+ We do this even though dynamic_sections_created may be FALSE, because
+ this has the side-effect of clearing want_plt and want_plt2. */
+
+ data.ofs = 0;
+ elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_plt_entries, &data);
+
+ ia64_info->minplt_entries = 0;
+ if (data.ofs)
+ {
+ ia64_info->minplt_entries
+ = (data.ofs - PLT_HEADER_SIZE) / PLT_MIN_ENTRY_SIZE;
+ }
+
+ /* Align the pointer for the plt2 entries. */
+ data.ofs = (data.ofs + 31) & (bfd_vma) -32;
+
+ elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_plt2_entries, &data);
+ if (data.ofs != 0 || ia64_info->root.dynamic_sections_created)
+ {
+ /* FIXME: we always reserve the memory for dynamic linker even if
+ there are no PLT entries since dynamic linker may assume the
+ reserved memory always exists. */
+
+ BFD_ASSERT (ia64_info->root.dynamic_sections_created);
+
+ ia64_info->root.splt->size = data.ofs;
+
+ /* If we've got a .plt, we need some extra memory for the dynamic
+ linker. We stuff these in .got.plt. */
+ sec = bfd_get_linker_section (dynobj, ".got.plt");
+ sec->size = 8 * PLT_RESERVED_WORDS;
+ }
+
+ /* Allocate the PLTOFF entries. */
+
+ if (ia64_info->pltoff_sec)
+ {
+ data.ofs = 0;
+ elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_pltoff_entries, &data);
+ ia64_info->pltoff_sec->size = data.ofs;
+ }
+
+ if (ia64_info->root.dynamic_sections_created)
+ {
+ /* Allocate space for the dynamic relocations that turned out to be
+ required. */
+
+ if (info->shared && ia64_info->self_dtpmod_offset != (bfd_vma) -1)
+ ia64_info->root.srelgot->size += sizeof (ElfNN_External_Rela);
+ data.only_got = FALSE;
+ elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_dynrel_entries, &data);
+ }
+
+ /* We have now determined the sizes of the various dynamic sections.
+ Allocate memory for them. */
+ for (sec = dynobj->sections; sec != NULL; sec = sec->next)
+ {
+ bfd_boolean strip;
+
+ if (!(sec->flags & SEC_LINKER_CREATED))
+ continue;
+
+ /* If we don't need this section, strip it from the output file.
+ There were several sections primarily related to dynamic
+ linking that must be create before the linker maps input
+ sections to output sections. The linker does that before
+ bfd_elf_size_dynamic_sections is called, and it is that
+ function which decides whether anything needs to go into
+ these sections. */
+
+ strip = (sec->size == 0);
+
+ if (sec == ia64_info->root.sgot)
+ strip = FALSE;
+ else if (sec == ia64_info->root.srelgot)
+ {
+ if (strip)
+ ia64_info->root.srelgot = NULL;
+ else
+ /* We use the reloc_count field as a counter if we need to
+ copy relocs into the output file. */
+ sec->reloc_count = 0;
+ }
+ else if (sec == ia64_info->fptr_sec)
+ {
+ if (strip)
+ ia64_info->fptr_sec = NULL;
+ }
+ else if (sec == ia64_info->rel_fptr_sec)
+ {
+ if (strip)
+ ia64_info->rel_fptr_sec = NULL;
+ else
+ /* We use the reloc_count field as a counter if we need to
+ copy relocs into the output file. */
+ sec->reloc_count = 0;
+ }
+ else if (sec == ia64_info->root.splt)
+ {
+ if (strip)
+ ia64_info->root.splt = NULL;
+ }
+ else if (sec == ia64_info->pltoff_sec)
+ {
+ if (strip)
+ ia64_info->pltoff_sec = NULL;
+ }
+ else if (sec == ia64_info->rel_pltoff_sec)
+ {
+ if (strip)
+ ia64_info->rel_pltoff_sec = NULL;
+ else
+ {
+ relplt = TRUE;
+ /* We use the reloc_count field as a counter if we need to
+ copy relocs into the output file. */
+ sec->reloc_count = 0;
+ }
+ }
+ else
+ {
+ const char *name;
+
+ /* 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, sec);
+
+ if (strcmp (name, ".got.plt") == 0)
+ strip = FALSE;
+ else if (CONST_STRNEQ (name, ".rel"))
+ {
+ if (!strip)
+ {
+ /* We use the reloc_count field as a counter if we need to
+ copy relocs into the output file. */
+ sec->reloc_count = 0;
+ }
+ }
+ else
+ continue;
+ }
+
+ if (strip)
+ sec->flags |= SEC_EXCLUDE;
+ else
+ {
+ /* Allocate memory for the section contents. */
+ sec->contents = (bfd_byte *) bfd_zalloc (dynobj, sec->size);
+ if (sec->contents == NULL && sec->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 finish_dynamic_sections) but we must add the entries now
+ so that we get the correct size for the .dynamic section. */
+
+ if (info->executable)
+ {
+ /* The DT_DEBUG entry is filled in by the dynamic linker and used
+ by the debugger. */
+#define add_dynamic_entry(TAG, VAL) \
+ _bfd_elf_add_dynamic_entry (info, TAG, VAL)
+
+ if (!add_dynamic_entry (DT_DEBUG, 0))
+ return FALSE;
+ }
+
+ if (!add_dynamic_entry (DT_IA_64_PLT_RESERVE, 0))
+ return FALSE;
+ if (!add_dynamic_entry (DT_PLTGOT, 0))
+ return FALSE;
+
+ if (relplt)
+ {
+ if (!add_dynamic_entry (DT_PLTRELSZ, 0)
+ || !add_dynamic_entry (DT_PLTREL, DT_RELA)
+ || !add_dynamic_entry (DT_JMPREL, 0))
+ return FALSE;
+ }
+
+ if (!add_dynamic_entry (DT_RELA, 0)
+ || !add_dynamic_entry (DT_RELASZ, 0)
+ || !add_dynamic_entry (DT_RELAENT, sizeof (ElfNN_External_Rela)))
+ return FALSE;
+
+ if (ia64_info->reltext)
+ {
+ if (!add_dynamic_entry (DT_TEXTREL, 0))
+ return FALSE;
+ info->flags |= DF_TEXTREL;
+ }
+ }
+
+ /* ??? Perhaps force __gp local. */
+
+ return TRUE;
+}
+
+static void
+elfNN_ia64_install_dyn_reloc (bfd *abfd, struct bfd_link_info *info,
+ asection *sec, asection *srel,
+ bfd_vma offset, unsigned int type,
+ long dynindx, bfd_vma addend)
+{
+ Elf_Internal_Rela outrel;
+ bfd_byte *loc;
+
+ BFD_ASSERT (dynindx != -1);
+ outrel.r_info = ELFNN_R_INFO (dynindx, type);
+ outrel.r_addend = addend;
+ outrel.r_offset = _bfd_elf_section_offset (abfd, info, sec, offset);
+ if (outrel.r_offset >= (bfd_vma) -2)
+ {
+ /* Run for the hills. We shouldn't be outputting a relocation
+ for this. So do what everyone else does and output a no-op. */
+ outrel.r_info = ELFNN_R_INFO (0, R_IA64_NONE);
+ outrel.r_addend = 0;
+ outrel.r_offset = 0;
+ }
+ else
+ outrel.r_offset += sec->output_section->vma + sec->output_offset;
+
+ loc = srel->contents;
+ loc += srel->reloc_count++ * sizeof (ElfNN_External_Rela);
+ bfd_elfNN_swap_reloca_out (abfd, &outrel, loc);
+ BFD_ASSERT (sizeof (ElfNN_External_Rela) * srel->reloc_count <= srel->size);
+}
+
+/* Store an entry for target address TARGET_ADDR in the linkage table
+ and return the gp-relative address of the linkage table entry. */
+
+static bfd_vma
+set_got_entry (bfd *abfd, struct bfd_link_info *info,
+ struct elfNN_ia64_dyn_sym_info *dyn_i,
+ long dynindx, bfd_vma addend, bfd_vma value,
+ unsigned int dyn_r_type)
+{
+ struct elfNN_ia64_link_hash_table *ia64_info;
+ asection *got_sec;
+ bfd_boolean done;
+ bfd_vma got_offset;
+
+ ia64_info = elfNN_ia64_hash_table (info);
+ if (ia64_info == NULL)
+ return 0;
+
+ got_sec = ia64_info->root.sgot;
+
+ switch (dyn_r_type)
+ {
+ case R_IA64_TPREL64LSB:
+ done = dyn_i->tprel_done;
+ dyn_i->tprel_done = TRUE;
+ got_offset = dyn_i->tprel_offset;
+ break;
+ case R_IA64_DTPMOD64LSB:
+ if (dyn_i->dtpmod_offset != ia64_info->self_dtpmod_offset)
+ {
+ done = dyn_i->dtpmod_done;
+ dyn_i->dtpmod_done = TRUE;
+ }
+ else
+ {
+ done = ia64_info->self_dtpmod_done;
+ ia64_info->self_dtpmod_done = TRUE;
+ dynindx = 0;
+ }
+ got_offset = dyn_i->dtpmod_offset;
+ break;
+ case R_IA64_DTPREL32LSB:
+ case R_IA64_DTPREL64LSB:
+ done = dyn_i->dtprel_done;
+ dyn_i->dtprel_done = TRUE;
+ got_offset = dyn_i->dtprel_offset;
+ break;
+ default:
+ done = dyn_i->got_done;
+ dyn_i->got_done = TRUE;
+ got_offset = dyn_i->got_offset;
+ break;
+ }
+
+ BFD_ASSERT ((got_offset & 7) == 0);
+
+ if (! done)
+ {
+ /* Store the target address in the linkage table entry. */
+ bfd_put_64 (abfd, value, got_sec->contents + got_offset);
+
+ /* Install a dynamic relocation if needed. */
+ if (((info->shared
+ && (!dyn_i->h
+ || ELF_ST_VISIBILITY (dyn_i->h->other) == STV_DEFAULT
+ || dyn_i->h->root.type != bfd_link_hash_undefweak)
+ && dyn_r_type != R_IA64_DTPREL32LSB
+ && dyn_r_type != R_IA64_DTPREL64LSB)
+ || elfNN_ia64_dynamic_symbol_p (dyn_i->h, info, dyn_r_type)
+ || (dynindx != -1
+ && (dyn_r_type == R_IA64_FPTR32LSB
+ || dyn_r_type == R_IA64_FPTR64LSB)))
+ && (!dyn_i->want_ltoff_fptr
+ || !info->pie
+ || !dyn_i->h
+ || dyn_i->h->root.type != bfd_link_hash_undefweak))
+ {
+ if (dynindx == -1
+ && dyn_r_type != R_IA64_TPREL64LSB
+ && dyn_r_type != R_IA64_DTPMOD64LSB
+ && dyn_r_type != R_IA64_DTPREL32LSB
+ && dyn_r_type != R_IA64_DTPREL64LSB)
+ {
+ dyn_r_type = R_IA64_RELNNLSB;
+ dynindx = 0;
+ addend = value;
+ }
+
+ if (bfd_big_endian (abfd))
+ {
+ switch (dyn_r_type)
+ {
+ case R_IA64_REL32LSB:
+ dyn_r_type = R_IA64_REL32MSB;
+ break;
+ case R_IA64_DIR32LSB:
+ dyn_r_type = R_IA64_DIR32MSB;
+ break;
+ case R_IA64_FPTR32LSB:
+ dyn_r_type = R_IA64_FPTR32MSB;
+ break;
+ case R_IA64_DTPREL32LSB:
+ dyn_r_type = R_IA64_DTPREL32MSB;
+ break;
+ case R_IA64_REL64LSB:
+ dyn_r_type = R_IA64_REL64MSB;
+ break;
+ case R_IA64_DIR64LSB:
+ dyn_r_type = R_IA64_DIR64MSB;
+ break;
+ case R_IA64_FPTR64LSB:
+ dyn_r_type = R_IA64_FPTR64MSB;
+ break;
+ case R_IA64_TPREL64LSB:
+ dyn_r_type = R_IA64_TPREL64MSB;
+ break;
+ case R_IA64_DTPMOD64LSB:
+ dyn_r_type = R_IA64_DTPMOD64MSB;
+ break;
+ case R_IA64_DTPREL64LSB:
+ dyn_r_type = R_IA64_DTPREL64MSB;
+ break;
+ default:
+ BFD_ASSERT (FALSE);
+ break;
+ }
+ }
+
+ elfNN_ia64_install_dyn_reloc (abfd, NULL, got_sec,
+ ia64_info->root.srelgot,
+ got_offset, dyn_r_type,
+ dynindx, addend);
+ }
+ }
+
+ /* Return the address of the linkage table entry. */
+ value = (got_sec->output_section->vma
+ + got_sec->output_offset
+ + got_offset);
+
+ return value;
+}
+
+/* Fill in a function descriptor consisting of the function's code
+ address and its global pointer. Return the descriptor's address. */
+
+static bfd_vma
+set_fptr_entry (bfd *abfd, struct bfd_link_info *info,
+ struct elfNN_ia64_dyn_sym_info *dyn_i,
+ bfd_vma value)
+{
+ struct elfNN_ia64_link_hash_table *ia64_info;
+ asection *fptr_sec;
+
+ ia64_info = elfNN_ia64_hash_table (info);
+ if (ia64_info == NULL)
+ return 0;
+
+ fptr_sec = ia64_info->fptr_sec;
+
+ if (!dyn_i->fptr_done)
+ {
+ dyn_i->fptr_done = 1;
+
+ /* Fill in the function descriptor. */
+ bfd_put_64 (abfd, value, fptr_sec->contents + dyn_i->fptr_offset);
+ bfd_put_64 (abfd, _bfd_get_gp_value (abfd),
+ fptr_sec->contents + dyn_i->fptr_offset + 8);
+ if (ia64_info->rel_fptr_sec)
+ {
+ Elf_Internal_Rela outrel;
+ bfd_byte *loc;
+
+ if (bfd_little_endian (abfd))
+ outrel.r_info = ELFNN_R_INFO (0, R_IA64_IPLTLSB);
+ else
+ outrel.r_info = ELFNN_R_INFO (0, R_IA64_IPLTMSB);
+ outrel.r_addend = value;
+ outrel.r_offset = (fptr_sec->output_section->vma
+ + fptr_sec->output_offset
+ + dyn_i->fptr_offset);
+ loc = ia64_info->rel_fptr_sec->contents;
+ loc += ia64_info->rel_fptr_sec->reloc_count++
+ * sizeof (ElfNN_External_Rela);
+ bfd_elfNN_swap_reloca_out (abfd, &outrel, loc);
+ }
+ }
+
+ /* Return the descriptor's address. */
+ value = (fptr_sec->output_section->vma
+ + fptr_sec->output_offset
+ + dyn_i->fptr_offset);
+
+ return value;
+}
+
+/* Fill in a PLTOFF entry consisting of the function's code address
+ and its global pointer. Return the descriptor's address. */
+
+static bfd_vma
+set_pltoff_entry (bfd *abfd, struct bfd_link_info *info,
+ struct elfNN_ia64_dyn_sym_info *dyn_i,
+ bfd_vma value, bfd_boolean is_plt)
+{
+ struct elfNN_ia64_link_hash_table *ia64_info;
+ asection *pltoff_sec;
+
+ ia64_info = elfNN_ia64_hash_table (info);
+ if (ia64_info == NULL)
+ return 0;
+
+ pltoff_sec = ia64_info->pltoff_sec;
+
+ /* Don't do anything if this symbol uses a real PLT entry. In
+ that case, we'll fill this in during finish_dynamic_symbol. */
+ if ((! dyn_i->want_plt || is_plt)
+ && !dyn_i->pltoff_done)
+ {
+ bfd_vma gp = _bfd_get_gp_value (abfd);
+
+ /* Fill in the function descriptor. */
+ bfd_put_64 (abfd, value, pltoff_sec->contents + dyn_i->pltoff_offset);
+ bfd_put_64 (abfd, gp, pltoff_sec->contents + dyn_i->pltoff_offset + 8);
+
+ /* Install dynamic relocations if needed. */
+ if (!is_plt
+ && info->shared
+ && (!dyn_i->h
+ || ELF_ST_VISIBILITY (dyn_i->h->other) == STV_DEFAULT
+ || dyn_i->h->root.type != bfd_link_hash_undefweak))
+ {
+ unsigned int dyn_r_type;
+
+ if (bfd_big_endian (abfd))
+ dyn_r_type = R_IA64_RELNNMSB;
+ else
+ dyn_r_type = R_IA64_RELNNLSB;
+
+ elfNN_ia64_install_dyn_reloc (abfd, NULL, pltoff_sec,
+ ia64_info->rel_pltoff_sec,
+ dyn_i->pltoff_offset,
+ dyn_r_type, 0, value);
+ elfNN_ia64_install_dyn_reloc (abfd, NULL, pltoff_sec,
+ ia64_info->rel_pltoff_sec,
+ dyn_i->pltoff_offset + ARCH_SIZE / 8,
+ dyn_r_type, 0, gp);
+ }
+
+ dyn_i->pltoff_done = 1;
+ }
+
+ /* Return the descriptor's address. */
+ value = (pltoff_sec->output_section->vma
+ + pltoff_sec->output_offset
+ + dyn_i->pltoff_offset);
+
+ return value;
+}
+
+/* Return the base VMA address which should be subtracted from real addresses
+ when resolving @tprel() relocation.
+ Main program TLS (whose template starts at PT_TLS p_vaddr)
+ is assigned offset round(2 * size of pointer, PT_TLS p_align). */
+
+static bfd_vma
+elfNN_ia64_tprel_base (struct bfd_link_info *info)
+{
+ asection *tls_sec = elf_hash_table (info)->tls_sec;
+ return tls_sec->vma - align_power ((bfd_vma) ARCH_SIZE / 4,
+ tls_sec->alignment_power);
+}
+
+/* Return the base VMA address which should be subtracted from real addresses
+ when resolving @dtprel() relocation.
+ This is PT_TLS segment p_vaddr. */
+
+static bfd_vma
+elfNN_ia64_dtprel_base (struct bfd_link_info *info)
+{
+ return elf_hash_table (info)->tls_sec->vma;
+}
+
+/* Called through qsort to sort the .IA_64.unwind section during a
+ non-relocatable link. Set elfNN_ia64_unwind_entry_compare_bfd
+ to the output bfd so we can do proper endianness frobbing. */
+
+static bfd *elfNN_ia64_unwind_entry_compare_bfd;
+
+static int
+elfNN_ia64_unwind_entry_compare (const void * a, const void * b)
+{
+ bfd_vma av, bv;
+
+ av = bfd_get_64 (elfNN_ia64_unwind_entry_compare_bfd, a);
+ bv = bfd_get_64 (elfNN_ia64_unwind_entry_compare_bfd, b);
+
+ return (av < bv ? -1 : av > bv ? 1 : 0);
+}
+
+/* Make sure we've got ourselves a nice fat __gp value. */
+static bfd_boolean
+elfNN_ia64_choose_gp (bfd *abfd, struct bfd_link_info *info, bfd_boolean final)
+{
+ bfd_vma min_vma = (bfd_vma) -1, max_vma = 0;
+ bfd_vma min_short_vma = min_vma, max_short_vma = 0;
+ struct elf_link_hash_entry *gp;
+ bfd_vma gp_val;
+ asection *os;
+ struct elfNN_ia64_link_hash_table *ia64_info;
+
+ ia64_info = elfNN_ia64_hash_table (info);
+ if (ia64_info == NULL)
+ return FALSE;
+
+ /* Find the min and max vma of all sections marked short. Also collect
+ min and max vma of any type, for use in selecting a nice gp. */
+ for (os = abfd->sections; os ; os = os->next)
+ {
+ bfd_vma lo, hi;
+
+ if ((os->flags & SEC_ALLOC) == 0)
+ continue;
+
+ lo = os->vma;
+ /* When this function is called from elfNN_ia64_final_link
+ the correct value to use is os->size. When called from
+ elfNN_ia64_relax_section we are in the middle of section
+ sizing; some sections will already have os->size set, others
+ will have os->size zero and os->rawsize the previous size. */
+ hi = os->vma + (!final && os->rawsize ? os->rawsize : os->size);
+ if (hi < lo)
+ hi = (bfd_vma) -1;
+
+ if (min_vma > lo)
+ min_vma = lo;
+ if (max_vma < hi)
+ max_vma = hi;
+ if (os->flags & SEC_SMALL_DATA)
+ {
+ if (min_short_vma > lo)
+ min_short_vma = lo;
+ if (max_short_vma < hi)
+ max_short_vma = hi;
+ }
+ }
+
+ if (ia64_info->min_short_sec)
+ {
+ if (min_short_vma
+ > (ia64_info->min_short_sec->vma
+ + ia64_info->min_short_offset))
+ min_short_vma = (ia64_info->min_short_sec->vma
+ + ia64_info->min_short_offset);
+ if (max_short_vma
+ < (ia64_info->max_short_sec->vma
+ + ia64_info->max_short_offset))
+ max_short_vma = (ia64_info->max_short_sec->vma
+ + ia64_info->max_short_offset);
+ }
+
+ /* See if the user wants to force a value. */
+ gp = elf_link_hash_lookup (elf_hash_table (info), "__gp", FALSE,
+ FALSE, FALSE);
+
+ if (gp
+ && (gp->root.type == bfd_link_hash_defined
+ || gp->root.type == bfd_link_hash_defweak))
+ {
+ asection *gp_sec = gp->root.u.def.section;
+ gp_val = (gp->root.u.def.value
+ + gp_sec->output_section->vma
+ + gp_sec->output_offset);
+ }
+ else
+ {
+ /* Pick a sensible value. */
+
+ if (ia64_info->min_short_sec)
+ {
+ bfd_vma short_range = max_short_vma - min_short_vma;
+
+ /* If min_short_sec is set, pick one in the middle bewteen
+ min_short_vma and max_short_vma. */
+ if (short_range >= 0x400000)
+ goto overflow;
+ gp_val = min_short_vma + short_range / 2;
+ }
+ else
+ {
+ asection *got_sec = ia64_info->root.sgot;
+
+ /* Start with just the address of the .got. */
+ if (got_sec)
+ gp_val = got_sec->output_section->vma;
+ else if (max_short_vma != 0)
+ gp_val = min_short_vma;
+ else if (max_vma - min_vma < 0x200000)
+ gp_val = min_vma;
+ else
+ gp_val = max_vma - 0x200000 + 8;
+ }
+
+ /* If it is possible to address the entire image, but we
+ don't with the choice above, adjust. */
+ if (max_vma - min_vma < 0x400000
+ && (max_vma - gp_val >= 0x200000
+ || gp_val - min_vma > 0x200000))
+ gp_val = min_vma + 0x200000;
+ else if (max_short_vma != 0)
+ {
+ /* If we don't cover all the short data, adjust. */
+ if (max_short_vma - gp_val >= 0x200000)
+ gp_val = min_short_vma + 0x200000;
+
+ /* If we're addressing stuff past the end, adjust back. */
+ if (gp_val > max_vma)
+ gp_val = max_vma - 0x200000 + 8;
+ }
+ }
+
+ /* Validate whether all SHF_IA_64_SHORT sections are within
+ range of the chosen GP. */
+
+ if (max_short_vma != 0)
+ {
+ if (max_short_vma - min_short_vma >= 0x400000)
+ {
+overflow:
+ (*_bfd_error_handler)
+ (_("%s: short data segment overflowed (0x%lx >= 0x400000)"),
+ bfd_get_filename (abfd),
+ (unsigned long) (max_short_vma - min_short_vma));
+ return FALSE;
+ }
+ else if ((gp_val > min_short_vma
+ && gp_val - min_short_vma > 0x200000)
+ || (gp_val < max_short_vma
+ && max_short_vma - gp_val >= 0x200000))
+ {
+ (*_bfd_error_handler)
+ (_("%s: __gp does not cover short data segment"),
+ bfd_get_filename (abfd));
+ return FALSE;
+ }
+ }
+
+ _bfd_set_gp_value (abfd, gp_val);
+
+ return TRUE;
+}
+
+static bfd_boolean
+elfNN_ia64_final_link (bfd *abfd, struct bfd_link_info *info)
+{
+ struct elfNN_ia64_link_hash_table *ia64_info;
+ asection *unwind_output_sec;
+
+ ia64_info = elfNN_ia64_hash_table (info);
+ if (ia64_info == NULL)
+ return FALSE;
+
+ /* Make sure we've got ourselves a nice fat __gp value. */
+ if (!info->relocatable)
+ {
+ bfd_vma gp_val;
+ struct elf_link_hash_entry *gp;
+
+ /* We assume after gp is set, section size will only decrease. We
+ need to adjust gp for it. */
+ _bfd_set_gp_value (abfd, 0);
+ if (! elfNN_ia64_choose_gp (abfd, info, TRUE))
+ return FALSE;
+ gp_val = _bfd_get_gp_value (abfd);
+
+ gp = elf_link_hash_lookup (elf_hash_table (info), "__gp", FALSE,
+ FALSE, FALSE);
+ if (gp)
+ {
+ gp->root.type = bfd_link_hash_defined;
+ gp->root.u.def.value = gp_val;
+ gp->root.u.def.section = bfd_abs_section_ptr;
+ }
+ }
+
+ /* If we're producing a final executable, we need to sort the contents
+ of the .IA_64.unwind section. Force this section to be relocated
+ into memory rather than written immediately to the output file. */
+ unwind_output_sec = NULL;
+ if (!info->relocatable)
+ {
+ asection *s = bfd_get_section_by_name (abfd, ELF_STRING_ia64_unwind);
+ if (s)
+ {
+ unwind_output_sec = s->output_section;
+ unwind_output_sec->contents
+ = bfd_malloc (unwind_output_sec->size);
+ if (unwind_output_sec->contents == NULL)
+ return FALSE;
+ }
+ }
+
+ /* Invoke the regular ELF backend linker to do all the work. */
+ if (!bfd_elf_final_link (abfd, info))
+ return FALSE;
+
+ if (unwind_output_sec)
+ {
+ elfNN_ia64_unwind_entry_compare_bfd = abfd;
+ qsort (unwind_output_sec->contents,
+ (size_t) (unwind_output_sec->size / 24),
+ 24,
+ elfNN_ia64_unwind_entry_compare);
+
+ if (! bfd_set_section_contents (abfd, unwind_output_sec,
+ unwind_output_sec->contents, (bfd_vma) 0,
+ unwind_output_sec->size))
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static bfd_boolean
+elfNN_ia64_relocate_section (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)
+{
+ struct elfNN_ia64_link_hash_table *ia64_info;
+ Elf_Internal_Shdr *symtab_hdr;
+ Elf_Internal_Rela *rel;
+ Elf_Internal_Rela *relend;
+ asection *srel;
+ bfd_boolean ret_val = TRUE; /* for non-fatal errors */
+ bfd_vma gp_val;
+
+ symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
+ ia64_info = elfNN_ia64_hash_table (info);
+ if (ia64_info == NULL)
+ return FALSE;
+
+ /* Infect various flags from the input section to the output section. */
+ if (info->relocatable)
+ {
+ bfd_vma flags;
+
+ flags = elf_section_data(input_section)->this_hdr.sh_flags;
+ flags &= SHF_IA_64_NORECOV;
+
+ elf_section_data(input_section->output_section)
+ ->this_hdr.sh_flags |= flags;
+ }
+
+ gp_val = _bfd_get_gp_value (output_bfd);
+ srel = get_reloc_section (input_bfd, ia64_info, input_section, FALSE);
+
+ rel = relocs;
+ relend = relocs + input_section->reloc_count;
+ for (; rel < relend; ++rel)
+ {
+ struct elf_link_hash_entry *h;
+ struct elfNN_ia64_dyn_sym_info *dyn_i;
+ bfd_reloc_status_type r;
+ reloc_howto_type *howto;
+ unsigned long r_symndx;
+ Elf_Internal_Sym *sym;
+ unsigned int r_type;
+ bfd_vma value;
+ asection *sym_sec;
+ bfd_byte *hit_addr;
+ bfd_boolean dynamic_symbol_p;
+ bfd_boolean undef_weak_ref;
+
+ r_type = ELFNN_R_TYPE (rel->r_info);
+ if (r_type > R_IA64_MAX_RELOC_CODE)
+ {
+ (*_bfd_error_handler)
+ (_("%B: unknown relocation type %d"),
+ input_bfd, (int) r_type);
+ bfd_set_error (bfd_error_bad_value);
+ ret_val = FALSE;
+ continue;
+ }
+
+ howto = ia64_elf_lookup_howto (r_type);
+ r_symndx = ELFNN_R_SYM (rel->r_info);
+ h = NULL;
+ sym = NULL;
+ sym_sec = NULL;
+ undef_weak_ref = FALSE;
+
+ if (r_symndx < symtab_hdr->sh_info)
+ {
+ /* Reloc against local symbol. */
+ asection *msec;
+ sym = local_syms + r_symndx;
+ sym_sec = local_sections[r_symndx];
+ msec = sym_sec;
+ value = _bfd_elf_rela_local_sym (output_bfd, sym, &msec, rel);
+ if (!info->relocatable
+ && (sym_sec->flags & SEC_MERGE) != 0
+ && ELF_ST_TYPE (sym->st_info) == STT_SECTION
+ && sym_sec->sec_info_type == SEC_INFO_TYPE_MERGE)
+ {
+ struct elfNN_ia64_local_hash_entry *loc_h;
+
+ loc_h = get_local_sym_hash (ia64_info, input_bfd, rel, FALSE);
+ if (loc_h && ! loc_h->sec_merge_done)
+ {
+ struct elfNN_ia64_dyn_sym_info *dynent;
+ unsigned int count;
+
+ for (count = loc_h->count, dynent = loc_h->info;
+ count != 0;
+ count--, dynent++)
+ {
+ msec = sym_sec;
+ dynent->addend =
+ _bfd_merged_section_offset (output_bfd, &msec,
+ elf_section_data (msec)->
+ sec_info,
+ sym->st_value
+ + dynent->addend);
+ dynent->addend -= sym->st_value;
+ dynent->addend += msec->output_section->vma
+ + msec->output_offset
+ - sym_sec->output_section->vma
+ - sym_sec->output_offset;
+ }
+
+ /* We may have introduced duplicated entries. We need
+ to remove them properly. */
+ count = sort_dyn_sym_info (loc_h->info, loc_h->count);
+ if (count != loc_h->count)
+ {
+ loc_h->count = count;
+ loc_h->sorted_count = count;
+ }
+
+ loc_h->sec_merge_done = 1;
+ }
+ }
+ }
+ else
+ {
+ bfd_boolean unresolved_reloc;
+ bfd_boolean warned, ignored;
+ struct elf_link_hash_entry **sym_hashes = elf_sym_hashes (input_bfd);
+
+ RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
+ r_symndx, symtab_hdr, sym_hashes,
+ h, sym_sec, value,
+ unresolved_reloc, warned, ignored);
+
+ if (h->root.type == bfd_link_hash_undefweak)
+ undef_weak_ref = TRUE;
+ else if (warned || (ignored && info->executable))
+ continue;
+ }
+
+ if (sym_sec != NULL && discarded_section (sym_sec))
+ RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+ rel, 1, relend, howto, 0, contents);
+
+ if (info->relocatable)
+ continue;
+
+ hit_addr = contents + rel->r_offset;
+ value += rel->r_addend;
+ dynamic_symbol_p = elfNN_ia64_dynamic_symbol_p (h, info, r_type);
+
+ switch (r_type)
+ {
+ case R_IA64_NONE:
+ case R_IA64_LDXMOV:
+ continue;
+
+ case R_IA64_IMM14:
+ case R_IA64_IMM22:
+ case R_IA64_IMM64:
+ case R_IA64_DIR32MSB:
+ case R_IA64_DIR32LSB:
+ case R_IA64_DIR64MSB:
+ case R_IA64_DIR64LSB:
+ /* Install a dynamic relocation for this reloc. */
+ if ((dynamic_symbol_p || info->shared)
+ && r_symndx != STN_UNDEF
+ && (input_section->flags & SEC_ALLOC) != 0)
+ {
+ unsigned int dyn_r_type;
+ long dynindx;
+ bfd_vma addend;
+
+ BFD_ASSERT (srel != NULL);
+
+ switch (r_type)
+ {
+ case R_IA64_IMM14:
+ case R_IA64_IMM22:
+ case R_IA64_IMM64:
+ /* ??? People shouldn't be doing non-pic code in
+ shared libraries nor dynamic executables. */
+ (*_bfd_error_handler)
+ (_("%B: non-pic code with imm relocation against dynamic symbol `%s'"),
+ input_bfd,
+ h ? h->root.root.string
+ : bfd_elf_sym_name (input_bfd, symtab_hdr, sym,
+ sym_sec));
+ ret_val = FALSE;
+ continue;
+
+ default:
+ break;
+ }
+
+ /* If we don't need dynamic symbol lookup, find a
+ matching RELATIVE relocation. */
+ dyn_r_type = r_type;
+ if (dynamic_symbol_p)
+ {
+ dynindx = h->dynindx;
+ addend = rel->r_addend;
+ value = 0;
+ }
+ else
+ {
+ switch (r_type)
+ {
+ case R_IA64_DIR32MSB:
+ dyn_r_type = R_IA64_REL32MSB;
+ break;
+ case R_IA64_DIR32LSB:
+ dyn_r_type = R_IA64_REL32LSB;
+ break;
+ case R_IA64_DIR64MSB:
+ dyn_r_type = R_IA64_REL64MSB;
+ break;
+ case R_IA64_DIR64LSB:
+ dyn_r_type = R_IA64_REL64LSB;
+ break;
+
+ default:
+ break;
+ }
+ dynindx = 0;
+ addend = value;
+ }
+
+ elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
+ srel, rel->r_offset, dyn_r_type,
+ dynindx, addend);
+ }
+ /* Fall through. */
+
+ case R_IA64_LTV32MSB:
+ case R_IA64_LTV32LSB:
+ case R_IA64_LTV64MSB:
+ case R_IA64_LTV64LSB:
+ r = ia64_elf_install_value (hit_addr, value, r_type);
+ break;
+
+ case R_IA64_GPREL22:
+ case R_IA64_GPREL64I:
+ case R_IA64_GPREL32MSB:
+ case R_IA64_GPREL32LSB:
+ case R_IA64_GPREL64MSB:
+ case R_IA64_GPREL64LSB:
+ if (dynamic_symbol_p)
+ {
+ (*_bfd_error_handler)
+ (_("%B: @gprel relocation against dynamic symbol %s"),
+ input_bfd,
+ h ? h->root.root.string
+ : bfd_elf_sym_name (input_bfd, symtab_hdr, sym,
+ sym_sec));
+ ret_val = FALSE;
+ continue;
+ }
+ value -= gp_val;
+ r = ia64_elf_install_value (hit_addr, value, r_type);
+ break;
+
+ case R_IA64_LTOFF22:
+ case R_IA64_LTOFF22X:
+ case R_IA64_LTOFF64I:
+ dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, FALSE);
+ value = set_got_entry (input_bfd, info, dyn_i, (h ? h->dynindx : -1),
+ rel->r_addend, value, R_IA64_DIRNNLSB);
+ value -= gp_val;
+ r = ia64_elf_install_value (hit_addr, value, r_type);
+ break;
+
+ case R_IA64_PLTOFF22:
+ case R_IA64_PLTOFF64I:
+ case R_IA64_PLTOFF64MSB:
+ case R_IA64_PLTOFF64LSB:
+ dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, FALSE);
+ value = set_pltoff_entry (output_bfd, info, dyn_i, value, FALSE);
+ value -= gp_val;
+ r = ia64_elf_install_value (hit_addr, value, r_type);
+ break;
+
+ case R_IA64_FPTR64I:
+ case R_IA64_FPTR32MSB:
+ case R_IA64_FPTR32LSB:
+ case R_IA64_FPTR64MSB:
+ case R_IA64_FPTR64LSB:
+ dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, FALSE);
+ if (dyn_i->want_fptr)
+ {
+ if (!undef_weak_ref)
+ value = set_fptr_entry (output_bfd, info, dyn_i, value);
+ }
+ if (!dyn_i->want_fptr || info->pie)
+ {
+ long dynindx;
+ unsigned int dyn_r_type = r_type;
+ bfd_vma addend = rel->r_addend;
+
+ /* Otherwise, we expect the dynamic linker to create
+ the entry. */
+
+ if (dyn_i->want_fptr)
+ {
+ if (r_type == R_IA64_FPTR64I)
+ {
+ /* We can't represent this without a dynamic symbol.
+ Adjust the relocation to be against an output
+ section symbol, which are always present in the
+ dynamic symbol table. */
+ /* ??? People shouldn't be doing non-pic code in
+ shared libraries. Hork. */
+ (*_bfd_error_handler)
+ (_("%B: linking non-pic code in a position independent executable"),
+ input_bfd);
+ ret_val = FALSE;
+ continue;
+ }
+ dynindx = 0;
+ addend = value;
+ dyn_r_type = r_type + R_IA64_RELNNLSB - R_IA64_FPTRNNLSB;
+ }
+ else if (h)
+ {
+ if (h->dynindx != -1)
+ dynindx = h->dynindx;
+ else
+ dynindx = (_bfd_elf_link_lookup_local_dynindx
+ (info, h->root.u.def.section->owner,
+ global_sym_index (h)));
+ value = 0;
+ }
+ else
+ {
+ dynindx = (_bfd_elf_link_lookup_local_dynindx
+ (info, input_bfd, (long) r_symndx));
+ value = 0;
+ }
+
+ elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
+ srel, rel->r_offset, dyn_r_type,
+ dynindx, addend);
+ }
+
+ r = ia64_elf_install_value (hit_addr, value, r_type);
+ break;
+
+ case R_IA64_LTOFF_FPTR22:
+ case R_IA64_LTOFF_FPTR64I:
+ case R_IA64_LTOFF_FPTR32MSB:
+ case R_IA64_LTOFF_FPTR32LSB:
+ case R_IA64_LTOFF_FPTR64MSB:
+ case R_IA64_LTOFF_FPTR64LSB:
+ {
+ long dynindx;
+
+ dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, FALSE);
+ if (dyn_i->want_fptr)
+ {
+ BFD_ASSERT (h == NULL || h->dynindx == -1);
+ if (!undef_weak_ref)
+ value = set_fptr_entry (output_bfd, info, dyn_i, value);
+ dynindx = -1;
+ }
+ else
+ {
+ /* Otherwise, we expect the dynamic linker to create
+ the entry. */
+ if (h)
+ {
+ if (h->dynindx != -1)
+ dynindx = h->dynindx;
+ else
+ dynindx = (_bfd_elf_link_lookup_local_dynindx
+ (info, h->root.u.def.section->owner,
+ global_sym_index (h)));
+ }
+ else
+ dynindx = (_bfd_elf_link_lookup_local_dynindx
+ (info, input_bfd, (long) r_symndx));
+ value = 0;
+ }
+
+ value = set_got_entry (output_bfd, info, dyn_i, dynindx,
+ rel->r_addend, value, R_IA64_FPTRNNLSB);
+ value -= gp_val;
+ r = ia64_elf_install_value (hit_addr, value, r_type);
+ }
+ break;
+
+ case R_IA64_PCREL32MSB:
+ case R_IA64_PCREL32LSB:
+ case R_IA64_PCREL64MSB:
+ case R_IA64_PCREL64LSB:
+ /* Install a dynamic relocation for this reloc. */
+ if (dynamic_symbol_p && r_symndx != STN_UNDEF)
+ {
+ BFD_ASSERT (srel != NULL);
+
+ elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
+ srel, rel->r_offset, r_type,
+ h->dynindx, rel->r_addend);
+ }
+ goto finish_pcrel;
+
+ case R_IA64_PCREL21B:
+ case R_IA64_PCREL60B:
+ /* We should have created a PLT entry for any dynamic symbol. */
+ dyn_i = NULL;
+ if (h)
+ dyn_i = get_dyn_sym_info (ia64_info, h, NULL, NULL, FALSE);
+
+ if (dyn_i && dyn_i->want_plt2)
+ {
+ /* Should have caught this earlier. */
+ BFD_ASSERT (rel->r_addend == 0);
+
+ value = (ia64_info->root.splt->output_section->vma
+ + ia64_info->root.splt->output_offset
+ + dyn_i->plt2_offset);
+ }
+ else
+ {
+ /* Since there's no PLT entry, Validate that this is
+ locally defined. */
+ BFD_ASSERT (undef_weak_ref || sym_sec->output_section != NULL);
+
+ /* If the symbol is undef_weak, we shouldn't be trying
+ to call it. There's every chance that we'd wind up
+ with an out-of-range fixup here. Don't bother setting
+ any value at all. */
+ if (undef_weak_ref)
+ continue;
+ }
+ goto finish_pcrel;
+
+ case R_IA64_PCREL21BI:
+ case R_IA64_PCREL21F:
+ case R_IA64_PCREL21M:
+ case R_IA64_PCREL22:
+ case R_IA64_PCREL64I:
+ /* The PCREL21BI reloc is specifically not intended for use with
+ dynamic relocs. PCREL21F and PCREL21M are used for speculation
+ fixup code, and thus probably ought not be dynamic. The
+ PCREL22 and PCREL64I relocs aren't emitted as dynamic relocs. */
+ if (dynamic_symbol_p)
+ {
+ const char *msg;
+
+ if (r_type == R_IA64_PCREL21BI)
+ msg = _("%B: @internal branch to dynamic symbol %s");
+ else if (r_type == R_IA64_PCREL21F || r_type == R_IA64_PCREL21M)
+ msg = _("%B: speculation fixup to dynamic symbol %s");
+ else
+ msg = _("%B: @pcrel relocation against dynamic symbol %s");
+ (*_bfd_error_handler) (msg, input_bfd,
+ h ? h->root.root.string
+ : bfd_elf_sym_name (input_bfd,
+ symtab_hdr,
+ sym,
+ sym_sec));
+ ret_val = FALSE;
+ continue;
+ }
+ goto finish_pcrel;
+
+ finish_pcrel:
+ /* Make pc-relative. */
+ value -= (input_section->output_section->vma
+ + input_section->output_offset
+ + rel->r_offset) & ~ (bfd_vma) 0x3;
+ r = ia64_elf_install_value (hit_addr, value, r_type);
+ break;
+
+ case R_IA64_SEGREL32MSB:
+ case R_IA64_SEGREL32LSB:
+ case R_IA64_SEGREL64MSB:
+ case R_IA64_SEGREL64LSB:
+ {
+ /* Find the segment that contains the output_section. */
+ Elf_Internal_Phdr *p = _bfd_elf_find_segment_containing_section
+ (output_bfd, input_section->output_section);
+
+ if (p == NULL)
+ {
+ r = bfd_reloc_notsupported;
+ }
+ else
+ {
+ /* The VMA of the segment is the vaddr of the associated
+ program header. */
+ if (value > p->p_vaddr)
+ value -= p->p_vaddr;
+ else
+ value = 0;
+ r = ia64_elf_install_value (hit_addr, value, r_type);
+ }
+ break;
+ }
+
+ case R_IA64_SECREL32MSB:
+ case R_IA64_SECREL32LSB:
+ case R_IA64_SECREL64MSB:
+ case R_IA64_SECREL64LSB:
+ /* Make output-section relative to section where the symbol
+ is defined. PR 475 */
+ if (sym_sec)
+ value -= sym_sec->output_section->vma;
+ r = ia64_elf_install_value (hit_addr, value, r_type);
+ break;
+
+ case R_IA64_IPLTMSB:
+ case R_IA64_IPLTLSB:
+ /* Install a dynamic relocation for this reloc. */
+ if ((dynamic_symbol_p || info->shared)
+ && (input_section->flags & SEC_ALLOC) != 0)
+ {
+ BFD_ASSERT (srel != NULL);
+
+ /* If we don't need dynamic symbol lookup, install two
+ RELATIVE relocations. */
+ if (!dynamic_symbol_p)
+ {
+ unsigned int dyn_r_type;
+
+ if (r_type == R_IA64_IPLTMSB)
+ dyn_r_type = R_IA64_REL64MSB;
+ else
+ dyn_r_type = R_IA64_REL64LSB;
+
+ elfNN_ia64_install_dyn_reloc (output_bfd, info,
+ input_section,
+ srel, rel->r_offset,
+ dyn_r_type, 0, value);
+ elfNN_ia64_install_dyn_reloc (output_bfd, info,
+ input_section,
+ srel, rel->r_offset + 8,
+ dyn_r_type, 0, gp_val);
+ }
+ else
+ elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
+ srel, rel->r_offset, r_type,
+ h->dynindx, rel->r_addend);
+ }
+
+ if (r_type == R_IA64_IPLTMSB)
+ r_type = R_IA64_DIR64MSB;
+ else
+ r_type = R_IA64_DIR64LSB;
+ ia64_elf_install_value (hit_addr, value, r_type);
+ r = ia64_elf_install_value (hit_addr + 8, gp_val, r_type);
+ break;
+
+ case R_IA64_TPREL14:
+ case R_IA64_TPREL22:
+ case R_IA64_TPREL64I:
+ if (elf_hash_table (info)->tls_sec == NULL)
+ goto missing_tls_sec;
+ value -= elfNN_ia64_tprel_base (info);
+ r = ia64_elf_install_value (hit_addr, value, r_type);
+ break;
+
+ case R_IA64_DTPREL14:
+ case R_IA64_DTPREL22:
+ case R_IA64_DTPREL64I:
+ case R_IA64_DTPREL32LSB:
+ case R_IA64_DTPREL32MSB:
+ case R_IA64_DTPREL64LSB:
+ case R_IA64_DTPREL64MSB:
+ if (elf_hash_table (info)->tls_sec == NULL)
+ goto missing_tls_sec;
+ value -= elfNN_ia64_dtprel_base (info);
+ r = ia64_elf_install_value (hit_addr, value, r_type);
+ break;
+
+ case R_IA64_LTOFF_TPREL22:
+ case R_IA64_LTOFF_DTPMOD22:
+ case R_IA64_LTOFF_DTPREL22:
+ {
+ int got_r_type;
+ long dynindx = h ? h->dynindx : -1;
+ bfd_vma r_addend = rel->r_addend;
+
+ switch (r_type)
+ {
+ default:
+ case R_IA64_LTOFF_TPREL22:
+ if (!dynamic_symbol_p)
+ {
+ if (elf_hash_table (info)->tls_sec == NULL)
+ goto missing_tls_sec;
+ if (!info->shared)
+ value -= elfNN_ia64_tprel_base (info);
+ else
+ {
+ r_addend += value - elfNN_ia64_dtprel_base (info);
+ dynindx = 0;
+ }
+ }
+ got_r_type = R_IA64_TPREL64LSB;
+ break;
+ case R_IA64_LTOFF_DTPMOD22:
+ if (!dynamic_symbol_p && !info->shared)
+ value = 1;
+ got_r_type = R_IA64_DTPMOD64LSB;
+ break;
+ case R_IA64_LTOFF_DTPREL22:
+ if (!dynamic_symbol_p)
+ {
+ if (elf_hash_table (info)->tls_sec == NULL)
+ goto missing_tls_sec;
+ value -= elfNN_ia64_dtprel_base (info);
+ }
+ got_r_type = R_IA64_DTPRELNNLSB;
+ break;
+ }
+ dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, FALSE);
+ value = set_got_entry (input_bfd, info, dyn_i, dynindx, r_addend,
+ value, got_r_type);
+ value -= gp_val;
+ r = ia64_elf_install_value (hit_addr, value, r_type);
+ }
+ break;
+
+ default:
+ r = bfd_reloc_notsupported;
+ break;
+ }
+
+ switch (r)
+ {
+ case bfd_reloc_ok:
+ break;
+
+ case bfd_reloc_undefined:
+ /* This can happen for global table relative relocs if
+ __gp is undefined. This is a panic situation so we
+ don't try to continue. */
+ (*info->callbacks->undefined_symbol)
+ (info, "__gp", input_bfd, input_section, rel->r_offset, 1);
+ return FALSE;
+
+ case bfd_reloc_notsupported:
+ {
+ const char *name;
+
+ if (h)
+ name = h->root.root.string;
+ else
+ name = bfd_elf_sym_name (input_bfd, symtab_hdr, sym,
+ sym_sec);
+ if (!(*info->callbacks->warning) (info, _("unsupported reloc"),
+ name, input_bfd,
+ input_section, rel->r_offset))
+ return FALSE;
+ ret_val = FALSE;
+ }
+ break;
+
+ case bfd_reloc_dangerous:
+ case bfd_reloc_outofrange:
+ case bfd_reloc_overflow:
+ default:
+missing_tls_sec:
+ {
+ const char *name;
+
+ if (h)
+ name = h->root.root.string;
+ else
+ name = bfd_elf_sym_name (input_bfd, symtab_hdr, sym,
+ sym_sec);
+
+ switch (r_type)
+ {
+ case R_IA64_TPREL14:
+ case R_IA64_TPREL22:
+ case R_IA64_TPREL64I:
+ case R_IA64_DTPREL14:
+ case R_IA64_DTPREL22:
+ case R_IA64_DTPREL64I:
+ case R_IA64_DTPREL32LSB:
+ case R_IA64_DTPREL32MSB:
+ case R_IA64_DTPREL64LSB:
+ case R_IA64_DTPREL64MSB:
+ case R_IA64_LTOFF_TPREL22:
+ case R_IA64_LTOFF_DTPMOD22:
+ case R_IA64_LTOFF_DTPREL22:
+ (*_bfd_error_handler)
+ (_("%B: missing TLS section for relocation %s against `%s' at 0x%lx in section `%A'."),
+ input_bfd, input_section, howto->name, name,
+ rel->r_offset);
+ break;
+
+ case R_IA64_PCREL21B:
+ case R_IA64_PCREL21BI:
+ case R_IA64_PCREL21M:
+ case R_IA64_PCREL21F:
+ if (is_elf_hash_table (info->hash))
+ {
+ /* Relaxtion is always performed for ELF output.
+ Overflow failures for those relocations mean
+ that the section is too big to relax. */
+ (*_bfd_error_handler)
+ (_("%B: Can't relax br (%s) to `%s' at 0x%lx in section `%A' with size 0x%lx (> 0x1000000)."),
+ input_bfd, input_section, howto->name, name,
+ rel->r_offset, input_section->size);
+ break;
+ }
+ default:
+ if (!(*info->callbacks->reloc_overflow) (info,
+ &h->root,
+ name,
+ howto->name,
+ (bfd_vma) 0,
+ input_bfd,
+ input_section,
+ rel->r_offset))
+ return FALSE;
+ break;
+ }
+
+ ret_val = FALSE;
+ }
+ break;
+ }
+ }
+
+ return ret_val;
+}
+
+static bfd_boolean
+elfNN_ia64_finish_dynamic_symbol (bfd *output_bfd,
+ struct bfd_link_info *info,
+ struct elf_link_hash_entry *h,
+ Elf_Internal_Sym *sym)
+{
+ struct elfNN_ia64_link_hash_table *ia64_info;
+ struct elfNN_ia64_dyn_sym_info *dyn_i;
+
+ ia64_info = elfNN_ia64_hash_table (info);
+ if (ia64_info == NULL)
+ return FALSE;
+
+ dyn_i = get_dyn_sym_info (ia64_info, h, NULL, NULL, FALSE);
+
+ /* Fill in the PLT data, if required. */
+ if (dyn_i && dyn_i->want_plt)
+ {
+ Elf_Internal_Rela outrel;
+ bfd_byte *loc;
+ asection *plt_sec;
+ bfd_vma plt_addr, pltoff_addr, gp_val, plt_index;
+
+ gp_val = _bfd_get_gp_value (output_bfd);
+
+ /* Initialize the minimal PLT entry. */
+
+ plt_index = (dyn_i->plt_offset - PLT_HEADER_SIZE) / PLT_MIN_ENTRY_SIZE;
+ plt_sec = ia64_info->root.splt;
+ loc = plt_sec->contents + dyn_i->plt_offset;
+
+ memcpy (loc, plt_min_entry, PLT_MIN_ENTRY_SIZE);
+ ia64_elf_install_value (loc, plt_index, R_IA64_IMM22);
+ ia64_elf_install_value (loc+2, -dyn_i->plt_offset, R_IA64_PCREL21B);
+
+ plt_addr = (plt_sec->output_section->vma
+ + plt_sec->output_offset
+ + dyn_i->plt_offset);
+ pltoff_addr = set_pltoff_entry (output_bfd, info, dyn_i, plt_addr, TRUE);
+
+ /* Initialize the FULL PLT entry, if needed. */
+ if (dyn_i->want_plt2)
+ {
+ loc = plt_sec->contents + dyn_i->plt2_offset;
+
+ memcpy (loc, plt_full_entry, PLT_FULL_ENTRY_SIZE);
+ ia64_elf_install_value (loc, pltoff_addr - gp_val, R_IA64_IMM22);
+
+ /* Mark the symbol as undefined, rather than as defined in the
+ plt section. Leave the value alone. */
+ /* ??? We didn't redefine it in adjust_dynamic_symbol in the
+ first place. But perhaps elflink.c did some for us. */
+ if (!h->def_regular)
+ sym->st_shndx = SHN_UNDEF;
+ }
+
+ /* Create the dynamic relocation. */
+ outrel.r_offset = pltoff_addr;
+ if (bfd_little_endian (output_bfd))
+ outrel.r_info = ELFNN_R_INFO (h->dynindx, R_IA64_IPLTLSB);
+ else
+ outrel.r_info = ELFNN_R_INFO (h->dynindx, R_IA64_IPLTMSB);
+ outrel.r_addend = 0;
+
+ /* This is fun. In the .IA_64.pltoff section, we've got entries
+ that correspond both to real PLT entries, and those that
+ happened to resolve to local symbols but need to be created
+ to satisfy @pltoff relocations. The .rela.IA_64.pltoff
+ relocations for the real PLT should come at the end of the
+ section, so that they can be indexed by plt entry at runtime.
+
+ We emitted all of the relocations for the non-PLT @pltoff
+ entries during relocate_section. So we can consider the
+ existing sec->reloc_count to be the base of the array of
+ PLT relocations. */
+
+ loc = ia64_info->rel_pltoff_sec->contents;
+ loc += ((ia64_info->rel_pltoff_sec->reloc_count + plt_index)
+ * sizeof (ElfNN_External_Rela));
+ bfd_elfNN_swap_reloca_out (output_bfd, &outrel, loc);
+ }
+
+ /* Mark some specially defined symbols as absolute. */
+ if (h == ia64_info->root.hdynamic
+ || h == ia64_info->root.hgot
+ || h == ia64_info->root.hplt)
+ sym->st_shndx = SHN_ABS;
+
+ return TRUE;
+}
+
+static bfd_boolean
+elfNN_ia64_finish_dynamic_sections (bfd *abfd,
+ struct bfd_link_info *info)
+{
+ struct elfNN_ia64_link_hash_table *ia64_info;
+ bfd *dynobj;
+
+ ia64_info = elfNN_ia64_hash_table (info);
+ if (ia64_info == NULL)
+ return FALSE;
+
+ dynobj = ia64_info->root.dynobj;
+
+ if (elf_hash_table (info)->dynamic_sections_created)
+ {
+ ElfNN_External_Dyn *dyncon, *dynconend;
+ asection *sdyn, *sgotplt;
+ bfd_vma gp_val;
+
+ sdyn = bfd_get_linker_section (dynobj, ".dynamic");
+ sgotplt = bfd_get_linker_section (dynobj, ".got.plt");
+ BFD_ASSERT (sdyn != NULL);
+ dyncon = (ElfNN_External_Dyn *) sdyn->contents;
+ dynconend = (ElfNN_External_Dyn *) (sdyn->contents + sdyn->size);
+
+ gp_val = _bfd_get_gp_value (abfd);
+
+ for (; dyncon < dynconend; dyncon++)
+ {
+ Elf_Internal_Dyn dyn;
+
+ bfd_elfNN_swap_dyn_in (dynobj, dyncon, &dyn);
+
+ switch (dyn.d_tag)
+ {
+ case DT_PLTGOT:
+ dyn.d_un.d_ptr = gp_val;
+ break;
+
+ case DT_PLTRELSZ:
+ dyn.d_un.d_val = (ia64_info->minplt_entries
+ * sizeof (ElfNN_External_Rela));
+ break;
+
+ case DT_JMPREL:
+ /* See the comment above in finish_dynamic_symbol. */
+ dyn.d_un.d_ptr = (ia64_info->rel_pltoff_sec->output_section->vma
+ + ia64_info->rel_pltoff_sec->output_offset
+ + (ia64_info->rel_pltoff_sec->reloc_count
+ * sizeof (ElfNN_External_Rela)));
+ break;
+
+ case DT_IA_64_PLT_RESERVE:
+ dyn.d_un.d_ptr = (sgotplt->output_section->vma
+ + sgotplt->output_offset);
+ break;
+
+ case DT_RELASZ:
+ /* Do not have RELASZ include JMPREL. This makes things
+ easier on ld.so. This is not what the rest of BFD set up. */
+ dyn.d_un.d_val -= (ia64_info->minplt_entries
+ * sizeof (ElfNN_External_Rela));
+ break;
+ }
+
+ bfd_elfNN_swap_dyn_out (abfd, &dyn, dyncon);
+ }
+
+ /* Initialize the PLT0 entry. */
+ if (ia64_info->root.splt)
+ {
+ bfd_byte *loc = ia64_info->root.splt->contents;
+ bfd_vma pltres;
+
+ memcpy (loc, plt_header, PLT_HEADER_SIZE);
+
+ pltres = (sgotplt->output_section->vma
+ + sgotplt->output_offset
+ - gp_val);
+
+ ia64_elf_install_value (loc+1, pltres, R_IA64_GPREL22);
+ }
+ }
+
+ return TRUE;
+}
+
+/* ELF file flag handling: */
+
+/* Function to keep IA-64 specific file flags. */
+static bfd_boolean
+elfNN_ia64_set_private_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;
+}
+
+/* Merge backend specific data from an object file to the output
+ object file when linking. */
+static bfd_boolean
+elfNN_ia64_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
+{
+ flagword out_flags;
+ flagword in_flags;
+ bfd_boolean ok = TRUE;
+
+ /* Don't even pretend to support mixed-format linking. */
+ if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
+ || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
+ return FALSE;
+
+ in_flags = elf_elfheader (ibfd)->e_flags;
+ out_flags = elf_elfheader (obfd)->e_flags;
+
+ if (! elf_flags_init (obfd))
+ {
+ 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;
+
+ /* Output has EF_IA_64_REDUCEDFP set only if all inputs have it set. */
+ if (!(in_flags & EF_IA_64_REDUCEDFP) && (out_flags & EF_IA_64_REDUCEDFP))
+ elf_elfheader (obfd)->e_flags &= ~EF_IA_64_REDUCEDFP;
+
+ if ((in_flags & EF_IA_64_TRAPNIL) != (out_flags & EF_IA_64_TRAPNIL))
+ {
+ (*_bfd_error_handler)
+ (_("%B: linking trap-on-NULL-dereference with non-trapping files"),
+ ibfd);
+
+ bfd_set_error (bfd_error_bad_value);
+ ok = FALSE;
+ }
+ if ((in_flags & EF_IA_64_BE) != (out_flags & EF_IA_64_BE))
+ {
+ (*_bfd_error_handler)
+ (_("%B: linking big-endian files with little-endian files"),
+ ibfd);
+
+ bfd_set_error (bfd_error_bad_value);
+ ok = FALSE;
+ }
+ if ((in_flags & EF_IA_64_ABI64) != (out_flags & EF_IA_64_ABI64))
+ {
+ (*_bfd_error_handler)
+ (_("%B: linking 64-bit files with 32-bit files"),
+ ibfd);
+
+ bfd_set_error (bfd_error_bad_value);
+ ok = FALSE;
+ }
+ if ((in_flags & EF_IA_64_CONS_GP) != (out_flags & EF_IA_64_CONS_GP))
+ {
+ (*_bfd_error_handler)
+ (_("%B: linking constant-gp files with non-constant-gp files"),
+ ibfd);
+
+ bfd_set_error (bfd_error_bad_value);
+ ok = FALSE;
+ }
+ if ((in_flags & EF_IA_64_NOFUNCDESC_CONS_GP)
+ != (out_flags & EF_IA_64_NOFUNCDESC_CONS_GP))
+ {
+ (*_bfd_error_handler)
+ (_("%B: linking auto-pic files with non-auto-pic files"),
+ ibfd);
+
+ bfd_set_error (bfd_error_bad_value);
+ ok = FALSE;
+ }
+
+ return ok;
+}
+
+static bfd_boolean
+elfNN_ia64_print_private_bfd_data (bfd *abfd, void * ptr)
+{
+ FILE *file = (FILE *) ptr;
+ flagword flags = elf_elfheader (abfd)->e_flags;
+
+ BFD_ASSERT (abfd != NULL && ptr != NULL);
+
+ fprintf (file, "private flags = %s%s%s%s%s%s%s%s\n",
+ (flags & EF_IA_64_TRAPNIL) ? "TRAPNIL, " : "",
+ (flags & EF_IA_64_EXT) ? "EXT, " : "",
+ (flags & EF_IA_64_BE) ? "BE, " : "LE, ",
+ (flags & EF_IA_64_REDUCEDFP) ? "REDUCEDFP, " : "",
+ (flags & EF_IA_64_CONS_GP) ? "CONS_GP, " : "",
+ (flags & EF_IA_64_NOFUNCDESC_CONS_GP) ? "NOFUNCDESC_CONS_GP, " : "",
+ (flags & EF_IA_64_ABSOLUTE) ? "ABSOLUTE, " : "",
+ (flags & EF_IA_64_ABI64) ? "ABI64" : "ABI32");
+
+ _bfd_elf_print_private_bfd_data (abfd, ptr);
+ return TRUE;
+}
+
+static enum elf_reloc_type_class
+elfNN_ia64_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ const asection *rel_sec ATTRIBUTE_UNUSED,
+ const Elf_Internal_Rela *rela)
+{
+ switch ((int) ELFNN_R_TYPE (rela->r_info))
+ {
+ case R_IA64_REL32MSB:
+ case R_IA64_REL32LSB:
+ case R_IA64_REL64MSB:
+ case R_IA64_REL64LSB:
+ return reloc_class_relative;
+ case R_IA64_IPLTMSB:
+ case R_IA64_IPLTLSB:
+ return reloc_class_plt;
+ case R_IA64_COPY:
+ return reloc_class_copy;
+ default:
+ return reloc_class_normal;
+ }
+}
+
+static const struct bfd_elf_special_section elfNN_ia64_special_sections[] =
+{
+ { STRING_COMMA_LEN (".sbss"), -1, SHT_NOBITS, SHF_ALLOC + SHF_WRITE + SHF_IA_64_SHORT },
+ { STRING_COMMA_LEN (".sdata"), -1, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE + SHF_IA_64_SHORT },
+ { NULL, 0, 0, 0, 0 }
+};
+
+static bfd_boolean
+elfNN_ia64_object_p (bfd *abfd)
+{
+ asection *sec;
+ asection *group, *unwi, *unw;
+ flagword flags;
+ const char *name;
+ char *unwi_name, *unw_name;
+ bfd_size_type amt;
+
+ if (abfd->flags & DYNAMIC)
+ return TRUE;
+
+ /* Flags for fake group section. */
+ flags = (SEC_LINKER_CREATED | SEC_GROUP | SEC_LINK_ONCE
+ | SEC_EXCLUDE);
+
+ /* We add a fake section group for each .gnu.linkonce.t.* section,
+ which isn't in a section group, and its unwind sections. */
+ for (sec = abfd->sections; sec != NULL; sec = sec->next)
+ {
+ if (elf_sec_group (sec) == NULL
+ && ((sec->flags & (SEC_LINK_ONCE | SEC_CODE | SEC_GROUP))
+ == (SEC_LINK_ONCE | SEC_CODE))
+ && CONST_STRNEQ (sec->name, ".gnu.linkonce.t."))
+ {
+ name = sec->name + 16;
+
+ amt = strlen (name) + sizeof (".gnu.linkonce.ia64unwi.");
+ unwi_name = bfd_alloc (abfd, amt);
+ if (!unwi_name)
+ return FALSE;
+
+ strcpy (stpcpy (unwi_name, ".gnu.linkonce.ia64unwi."), name);
+ unwi = bfd_get_section_by_name (abfd, unwi_name);
+
+ amt = strlen (name) + sizeof (".gnu.linkonce.ia64unw.");
+ unw_name = bfd_alloc (abfd, amt);
+ if (!unw_name)
+ return FALSE;
+
+ strcpy (stpcpy (unw_name, ".gnu.linkonce.ia64unw."), name);
+ unw = bfd_get_section_by_name (abfd, unw_name);
+
+ /* We need to create a fake group section for it and its
+ unwind sections. */
+ group = bfd_make_section_anyway_with_flags (abfd, name,
+ flags);
+ if (group == NULL)
+ return FALSE;
+
+ /* Move the fake group section to the beginning. */
+ bfd_section_list_remove (abfd, group);
+ bfd_section_list_prepend (abfd, group);
+
+ elf_next_in_group (group) = sec;
+
+ elf_group_name (sec) = name;
+ elf_next_in_group (sec) = sec;
+ elf_sec_group (sec) = group;
+
+ if (unwi)
+ {
+ elf_group_name (unwi) = name;
+ elf_next_in_group (unwi) = sec;
+ elf_next_in_group (sec) = unwi;
+ elf_sec_group (unwi) = group;
+ }
+
+ if (unw)
+ {
+ elf_group_name (unw) = name;
+ if (unwi)
+ {
+ elf_next_in_group (unw) = elf_next_in_group (unwi);
+ elf_next_in_group (unwi) = unw;
+ }
+ else
+ {
+ elf_next_in_group (unw) = sec;
+ elf_next_in_group (sec) = unw;
+ }
+ elf_sec_group (unw) = group;
+ }
+
+ /* Fake SHT_GROUP section header. */
+ elf_section_data (group)->this_hdr.bfd_section = group;
+ elf_section_data (group)->this_hdr.sh_type = SHT_GROUP;
+ }
+ }
+ return TRUE;
+}
+
+static bfd_boolean
+elfNN_ia64_hpux_vec (const bfd_target *vec)
+{
+ extern const bfd_target ia64_elfNN_hpux_be_vec;
+ return (vec == &ia64_elfNN_hpux_be_vec);
+}
+
+static void
+elfNN_hpux_post_process_headers (bfd *abfd,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED)
+{
+ Elf_Internal_Ehdr *i_ehdrp = elf_elfheader (abfd);
+
+ i_ehdrp->e_ident[EI_OSABI] = get_elf_backend_data (abfd)->elf_osabi;
+ i_ehdrp->e_ident[EI_ABIVERSION] = 1;
+}
+
+static bfd_boolean
+elfNN_hpux_backend_section_from_bfd_section (bfd *abfd ATTRIBUTE_UNUSED,
+ asection *sec, int *retval)
+{
+ if (bfd_is_com_section (sec))
+ {
+ *retval = SHN_IA_64_ANSI_COMMON;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static void
+elfNN_hpux_backend_symbol_processing (bfd *abfd ATTRIBUTE_UNUSED,
+ asymbol *asym)
+{
+ elf_symbol_type *elfsym = (elf_symbol_type *) asym;
+
+ switch (elfsym->internal_elf_sym.st_shndx)
+ {
+ case SHN_IA_64_ANSI_COMMON:
+ asym->section = bfd_com_section_ptr;
+ asym->value = elfsym->internal_elf_sym.st_size;
+ asym->flags &= ~BSF_GLOBAL;
+ break;
+ }
+}
+
+#define TARGET_LITTLE_SYM ia64_elfNN_le_vec
+#define TARGET_LITTLE_NAME "elfNN-ia64-little"
+#define TARGET_BIG_SYM ia64_elfNN_be_vec
+#define TARGET_BIG_NAME "elfNN-ia64-big"
+#define ELF_ARCH bfd_arch_ia64
+#define ELF_TARGET_ID IA64_ELF_DATA
+#define ELF_MACHINE_CODE EM_IA_64
+#define ELF_MACHINE_ALT1 1999 /* EAS2.3 */
+#define ELF_MACHINE_ALT2 1998 /* EAS2.2 */
+#define ELF_MAXPAGESIZE 0x10000 /* 64KB */
+#define ELF_COMMONPAGESIZE 0x4000 /* 16KB */
+
+#define elf_backend_section_from_shdr \
+ elfNN_ia64_section_from_shdr
+#define elf_backend_section_flags \
+ elfNN_ia64_section_flags
+#define elf_backend_fake_sections \
+ elfNN_ia64_fake_sections
+#define elf_backend_final_write_processing \
+ elfNN_ia64_final_write_processing
+#define elf_backend_add_symbol_hook \
+ elfNN_ia64_add_symbol_hook
+#define elf_backend_additional_program_headers \
+ elfNN_ia64_additional_program_headers
+#define elf_backend_modify_segment_map \
+ elfNN_ia64_modify_segment_map
+#define elf_backend_modify_program_headers \
+ elfNN_ia64_modify_program_headers
+#define elf_info_to_howto \
+ elfNN_ia64_info_to_howto
+
+#define bfd_elfNN_bfd_reloc_type_lookup \
+ ia64_elf_reloc_type_lookup
+#define bfd_elfNN_bfd_reloc_name_lookup \
+ ia64_elf_reloc_name_lookup
+#define bfd_elfNN_bfd_is_local_label_name \
+ elfNN_ia64_is_local_label_name
+#define bfd_elfNN_bfd_relax_section \
+ elfNN_ia64_relax_section
+
+#define elf_backend_object_p \
+ elfNN_ia64_object_p
+
+/* Stuff for the BFD linker: */
+#define bfd_elfNN_bfd_link_hash_table_create \
+ elfNN_ia64_hash_table_create
+#define elf_backend_create_dynamic_sections \
+ elfNN_ia64_create_dynamic_sections
+#define elf_backend_check_relocs \
+ elfNN_ia64_check_relocs
+#define elf_backend_adjust_dynamic_symbol \
+ elfNN_ia64_adjust_dynamic_symbol
+#define elf_backend_size_dynamic_sections \
+ elfNN_ia64_size_dynamic_sections
+#define elf_backend_omit_section_dynsym \
+ ((bfd_boolean (*) (bfd *, struct bfd_link_info *, asection *)) bfd_true)
+#define elf_backend_relocate_section \
+ elfNN_ia64_relocate_section
+#define elf_backend_finish_dynamic_symbol \
+ elfNN_ia64_finish_dynamic_symbol
+#define elf_backend_finish_dynamic_sections \
+ elfNN_ia64_finish_dynamic_sections
+#define bfd_elfNN_bfd_final_link \
+ elfNN_ia64_final_link
+
+#define bfd_elfNN_bfd_merge_private_bfd_data \
+ elfNN_ia64_merge_private_bfd_data
+#define bfd_elfNN_bfd_set_private_flags \
+ elfNN_ia64_set_private_flags
+#define bfd_elfNN_bfd_print_private_bfd_data \
+ elfNN_ia64_print_private_bfd_data
+
+#define elf_backend_plt_readonly 1
+#define elf_backend_want_plt_sym 0
+#define elf_backend_plt_alignment 5
+#define elf_backend_got_header_size 0
+#define elf_backend_want_got_plt 1
+#define elf_backend_may_use_rel_p 1
+#define elf_backend_may_use_rela_p 1
+#define elf_backend_default_use_rela_p 1
+#define elf_backend_want_dynbss 0
+#define elf_backend_copy_indirect_symbol elfNN_ia64_hash_copy_indirect
+#define elf_backend_hide_symbol elfNN_ia64_hash_hide_symbol
+#define elf_backend_fixup_symbol _bfd_elf_link_hash_fixup_symbol
+#define elf_backend_reloc_type_class elfNN_ia64_reloc_type_class
+#define elf_backend_rela_normal 1
+#define elf_backend_special_sections elfNN_ia64_special_sections
+#define elf_backend_default_execstack 0
+
+/* FIXME: PR 290: The Intel C compiler generates SHT_IA_64_UNWIND with
+ SHF_LINK_ORDER. But it doesn't set the sh_link or sh_info fields.
+ We don't want to flood users with so many error messages. We turn
+ off the warning for now. It will be turned on later when the Intel
+ compiler is fixed. */
+#define elf_backend_link_order_error_handler NULL
+
+#include "elfNN-target.h"
+
+/* HPUX-specific vectors. */
+
+#undef TARGET_LITTLE_SYM
+#undef TARGET_LITTLE_NAME
+#undef TARGET_BIG_SYM
+#define TARGET_BIG_SYM ia64_elfNN_hpux_be_vec
+#undef TARGET_BIG_NAME
+#define TARGET_BIG_NAME "elfNN-ia64-hpux-big"
+
+/* These are HP-UX specific functions. */
+
+#undef elf_backend_post_process_headers
+#define elf_backend_post_process_headers elfNN_hpux_post_process_headers
+
+#undef elf_backend_section_from_bfd_section
+#define elf_backend_section_from_bfd_section elfNN_hpux_backend_section_from_bfd_section
+
+#undef elf_backend_symbol_processing
+#define elf_backend_symbol_processing elfNN_hpux_backend_symbol_processing
+
+#undef elf_backend_want_p_paddr_set_to_zero
+#define elf_backend_want_p_paddr_set_to_zero 1
+
+#undef ELF_COMMONPAGESIZE
+#undef ELF_OSABI
+#define ELF_OSABI ELFOSABI_HPUX
+
+#undef elfNN_bed
+#define elfNN_bed elfNN_ia64_hpux_bed
+
+#include "elfNN-target.h"
diff --git a/bfd/elfxx-aarch64.c b/bfd/elfxx-aarch64.c
new file mode 100644
index 0000000..6ae4adf
--- /dev/null
+++ b/bfd/elfxx-aarch64.c
@@ -0,0 +1,604 @@
+/* AArch64-specific support for ELF.
+ Copyright (C) 2009-2014 Free Software Foundation, Inc.
+ Contributed by ARM Ltd.
+
+ This file is part of BFD, the Binary File Descriptor library.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 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 COPYING3. If not,
+ see <http://www.gnu.org/licenses/>. */
+
+#include "sysdep.h"
+#include "elfxx-aarch64.h"
+#include <stdarg.h>
+#include <string.h>
+
+#define MASK(n) ((1u << (n)) - 1)
+
+/* Decode the 26-bit offset of unconditional branch. */
+static inline uint32_t
+decode_branch_ofs_26 (uint32_t insn)
+{
+ return insn & MASK (26);
+}
+
+/* Decode the 19-bit offset of conditional branch and compare & branch. */
+static inline uint32_t
+decode_cond_branch_ofs_19 (uint32_t insn)
+{
+ return (insn >> 5) & MASK (19);
+}
+
+/* Decode the 19-bit offset of load literal. */
+static inline uint32_t
+decode_ld_lit_ofs_19 (uint32_t insn)
+{
+ return (insn >> 5) & MASK (19);
+}
+
+/* Decode the 14-bit offset of test & branch. */
+static inline uint32_t
+decode_tst_branch_ofs_14 (uint32_t insn)
+{
+ return (insn >> 5) & MASK (14);
+}
+
+/* Decode the 16-bit imm of move wide. */
+static inline uint32_t
+decode_movw_imm (uint32_t insn)
+{
+ return (insn >> 5) & MASK (16);
+}
+
+/* Decode the 12-bit imm of add immediate. */
+static inline uint32_t
+decode_add_imm (uint32_t insn)
+{
+ return (insn >> 10) & MASK (12);
+}
+
+/* Reencode the imm field of add immediate. */
+static inline uint32_t
+reencode_add_imm (uint32_t insn, uint32_t imm)
+{
+ return (insn & ~(MASK (12) << 10)) | ((imm & MASK (12)) << 10);
+}
+
+/* Reencode the imm field of adr. */
+static inline uint32_t
+reencode_adr_imm (uint32_t insn, uint32_t imm)
+{
+ return (insn & ~((MASK (2) << 29) | (MASK (19) << 5)))
+ | ((imm & MASK (2)) << 29) | ((imm & (MASK (19) << 2)) << 3);
+}
+
+/* Reencode the imm field of ld/st pos immediate. */
+static inline uint32_t
+reencode_ldst_pos_imm (uint32_t insn, uint32_t imm)
+{
+ return (insn & ~(MASK (12) << 10)) | ((imm & MASK (12)) << 10);
+}
+
+/* Encode the 26-bit offset of unconditional branch. */
+static inline uint32_t
+reencode_branch_ofs_26 (uint32_t insn, uint32_t ofs)
+{
+ return (insn & ~MASK (26)) | (ofs & MASK (26));
+}
+
+/* Encode the 19-bit offset of conditional branch and compare & branch. */
+static inline uint32_t
+reencode_cond_branch_ofs_19 (uint32_t insn, uint32_t ofs)
+{
+ return (insn & ~(MASK (19) << 5)) | ((ofs & MASK (19)) << 5);
+}
+
+/* Decode the 19-bit offset of load literal. */
+static inline uint32_t
+reencode_ld_lit_ofs_19 (uint32_t insn, uint32_t ofs)
+{
+ return (insn & ~(MASK (19) << 5)) | ((ofs & MASK (19)) << 5);
+}
+
+/* Encode the 14-bit offset of test & branch. */
+static inline uint32_t
+reencode_tst_branch_ofs_14 (uint32_t insn, uint32_t ofs)
+{
+ return (insn & ~(MASK (14) << 5)) | ((ofs & MASK (14)) << 5);
+}
+
+/* Reencode the imm field of move wide. */
+static inline uint32_t
+reencode_movw_imm (uint32_t insn, uint32_t imm)
+{
+ return (insn & ~(MASK (16) << 5)) | ((imm & MASK (16)) << 5);
+}
+
+/* Reencode mov[zn] to movz. */
+static inline uint32_t
+reencode_movzn_to_movz (uint32_t opcode)
+{
+ return opcode | (1 << 30);
+}
+
+/* Reencode mov[zn] to movn. */
+static inline uint32_t
+reencode_movzn_to_movn (uint32_t opcode)
+{
+ return opcode & ~(1 << 30);
+}
+
+/* Return non-zero if the indicated VALUE has overflowed the maximum
+ range expressible by a unsigned number with the indicated number of
+ BITS. */
+
+static bfd_reloc_status_type
+aarch64_unsigned_overflow (bfd_vma value, unsigned int bits)
+{
+ bfd_vma lim;
+ if (bits >= sizeof (bfd_vma) * 8)
+ return bfd_reloc_ok;
+ lim = (bfd_vma) 1 << bits;
+ if (value >= lim)
+ return bfd_reloc_overflow;
+ return bfd_reloc_ok;
+}
+
+/* Return non-zero if the indicated VALUE has overflowed the maximum
+ range expressible by an signed number with the indicated number of
+ BITS. */
+
+static bfd_reloc_status_type
+aarch64_signed_overflow (bfd_vma value, unsigned int bits)
+{
+ bfd_signed_vma svalue = (bfd_signed_vma) value;
+ bfd_signed_vma lim;
+
+ if (bits >= sizeof (bfd_vma) * 8)
+ return bfd_reloc_ok;
+ lim = (bfd_signed_vma) 1 << (bits - 1);
+ if (svalue < -lim || svalue >= lim)
+ return bfd_reloc_overflow;
+ return bfd_reloc_ok;
+}
+
+/* Insert the addend/value into the instruction or data object being
+ relocated. */
+bfd_reloc_status_type
+_bfd_aarch64_elf_put_addend (bfd *abfd,
+ bfd_byte *address, bfd_reloc_code_real_type r_type,
+ reloc_howto_type *howto, bfd_signed_vma addend)
+{
+ bfd_reloc_status_type status = bfd_reloc_ok;
+ bfd_signed_vma old_addend = addend;
+ bfd_vma contents;
+ int size;
+
+ size = bfd_get_reloc_size (howto);
+ switch (size)
+ {
+ case 2:
+ contents = bfd_get_16 (abfd, address);
+ break;
+ case 4:
+ if (howto->src_mask != 0xffffffff)
+ /* Must be 32-bit instruction, always little-endian. */
+ contents = bfd_getl32 (address);
+ else
+ /* Must be 32-bit data (endianness dependent). */
+ contents = bfd_get_32 (abfd, address);
+ break;
+ case 8:
+ contents = bfd_get_64 (abfd, address);
+ break;
+ default:
+ abort ();
+ }
+
+ switch (howto->complain_on_overflow)
+ {
+ case complain_overflow_dont:
+ break;
+ case complain_overflow_signed:
+ status = aarch64_signed_overflow (addend,
+ howto->bitsize + howto->rightshift);
+ break;
+ case complain_overflow_unsigned:
+ status = aarch64_unsigned_overflow (addend,
+ howto->bitsize + howto->rightshift);
+ break;
+ case complain_overflow_bitfield:
+ default:
+ abort ();
+ }
+
+ addend >>= howto->rightshift;
+
+ switch (r_type)
+ {
+ case BFD_RELOC_AARCH64_JUMP26:
+ case BFD_RELOC_AARCH64_CALL26:
+ contents = reencode_branch_ofs_26 (contents, addend);
+ break;
+
+ case BFD_RELOC_AARCH64_BRANCH19:
+ contents = reencode_cond_branch_ofs_19 (contents, addend);
+ break;
+
+ case BFD_RELOC_AARCH64_TSTBR14:
+ contents = reencode_tst_branch_ofs_14 (contents, addend);
+ break;
+
+ case BFD_RELOC_AARCH64_LD_LO19_PCREL:
+ case BFD_RELOC_AARCH64_GOT_LD_PREL19:
+ if (old_addend & ((1 << howto->rightshift) - 1))
+ return bfd_reloc_overflow;
+ contents = reencode_ld_lit_ofs_19 (contents, addend);
+ break;
+
+ case BFD_RELOC_AARCH64_TLSDESC_CALL:
+ break;
+
+ case BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21:
+ case BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21:
+ case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21:
+ case BFD_RELOC_AARCH64_ADR_GOT_PAGE:
+ case BFD_RELOC_AARCH64_ADR_LO21_PCREL:
+ case BFD_RELOC_AARCH64_ADR_HI21_PCREL:
+ case BFD_RELOC_AARCH64_ADR_HI21_NC_PCREL:
+ contents = reencode_adr_imm (contents, addend);
+ break;
+
+ case BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC:
+ case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12:
+ case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_HI12:
+ case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12_NC:
+ case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12_NC:
+ case BFD_RELOC_AARCH64_ADD_LO12:
+ /* Corresponds to: add rd, rn, #uimm12 to provide the low order
+ 12 bits of the page offset following
+ BFD_RELOC_AARCH64_ADR_HI21_PCREL which computes the
+ (pc-relative) page base. */
+ contents = reencode_add_imm (contents, addend);
+ break;
+
+ case BFD_RELOC_AARCH64_LDST8_LO12:
+ case BFD_RELOC_AARCH64_LDST16_LO12:
+ case BFD_RELOC_AARCH64_LDST32_LO12:
+ case BFD_RELOC_AARCH64_LDST64_LO12:
+ case BFD_RELOC_AARCH64_LDST128_LO12:
+ case BFD_RELOC_AARCH64_TLSDESC_LD64_LO12_NC:
+ case BFD_RELOC_AARCH64_TLSDESC_LD32_LO12_NC:
+ case BFD_RELOC_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC:
+ case BFD_RELOC_AARCH64_TLSIE_LD32_GOTTPREL_LO12_NC:
+ case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC:
+ case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC:
+ if (old_addend & ((1 << howto->rightshift) - 1))
+ return bfd_reloc_overflow;
+ /* Used for ldr*|str* rt, [rn, #uimm12] to provide the low order
+ 12 bits of the page offset following BFD_RELOC_AARCH64_ADR_HI21_PCREL
+ which computes the (pc-relative) page base. */
+ contents = reencode_ldst_pos_imm (contents, addend);
+ break;
+
+ /* Group relocations to create high bits of a 16, 32, 48 or 64
+ bit signed data or abs address inline. Will change
+ instruction to MOVN or MOVZ depending on sign of calculated
+ value. */
+
+ case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G2:
+ case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1:
+ case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1_NC:
+ case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0:
+ case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC:
+ case BFD_RELOC_AARCH64_MOVW_G0_S:
+ case BFD_RELOC_AARCH64_MOVW_G1_S:
+ case BFD_RELOC_AARCH64_MOVW_G2_S:
+ /* NOTE: We can only come here with movz or movn. */
+ if (addend < 0)
+ {
+ /* Force use of MOVN. */
+ addend = ~addend;
+ contents = reencode_movzn_to_movn (contents);
+ }
+ else
+ {
+ /* Force use of MOVZ. */
+ contents = reencode_movzn_to_movz (contents);
+ }
+ /* fall through */
+
+ /* Group relocations to create a 16, 32, 48 or 64 bit unsigned
+ data or abs address inline. */
+
+ case BFD_RELOC_AARCH64_MOVW_G0:
+ case BFD_RELOC_AARCH64_MOVW_G0_NC:
+ case BFD_RELOC_AARCH64_MOVW_G1:
+ case BFD_RELOC_AARCH64_MOVW_G1_NC:
+ case BFD_RELOC_AARCH64_MOVW_G2:
+ case BFD_RELOC_AARCH64_MOVW_G2_NC:
+ case BFD_RELOC_AARCH64_MOVW_G3:
+ contents = reencode_movw_imm (contents, addend);
+ break;
+
+ default:
+ /* Repack simple data */
+ if (howto->dst_mask & (howto->dst_mask + 1))
+ return bfd_reloc_notsupported;
+
+ contents = ((contents & ~howto->dst_mask) | (addend & howto->dst_mask));
+ break;
+ }
+
+ switch (size)
+ {
+ case 2:
+ bfd_put_16 (abfd, contents, address);
+ break;
+ case 4:
+ if (howto->dst_mask != 0xffffffff)
+ /* must be 32-bit instruction, always little-endian */
+ bfd_putl32 (contents, address);
+ else
+ /* must be 32-bit data (endianness dependent) */
+ bfd_put_32 (abfd, contents, address);
+ break;
+ case 8:
+ bfd_put_64 (abfd, contents, address);
+ break;
+ default:
+ abort ();
+ }
+
+ return status;
+}
+
+bfd_vma
+_bfd_aarch64_elf_resolve_relocation (bfd_reloc_code_real_type r_type,
+ bfd_vma place, bfd_vma value,
+ bfd_vma addend, bfd_boolean weak_undef_p)
+{
+ switch (r_type)
+ {
+ case BFD_RELOC_AARCH64_TLSDESC_CALL:
+ case BFD_RELOC_AARCH64_NONE:
+ break;
+
+ case BFD_RELOC_AARCH64_ADR_LO21_PCREL:
+ case BFD_RELOC_AARCH64_BRANCH19:
+ case BFD_RELOC_AARCH64_LD_LO19_PCREL:
+ case BFD_RELOC_AARCH64_16_PCREL:
+ case BFD_RELOC_AARCH64_32_PCREL:
+ case BFD_RELOC_AARCH64_64_PCREL:
+ case BFD_RELOC_AARCH64_TSTBR14:
+ if (weak_undef_p)
+ value = place;
+ value = value + addend - place;
+ break;
+
+ case BFD_RELOC_AARCH64_CALL26:
+ case BFD_RELOC_AARCH64_JUMP26:
+ value = value + addend - place;
+ break;
+
+ case BFD_RELOC_AARCH64_16:
+ case BFD_RELOC_AARCH64_32:
+ case BFD_RELOC_AARCH64_MOVW_G0_S:
+ case BFD_RELOC_AARCH64_MOVW_G1_S:
+ case BFD_RELOC_AARCH64_MOVW_G2_S:
+ case BFD_RELOC_AARCH64_MOVW_G0:
+ case BFD_RELOC_AARCH64_MOVW_G0_NC:
+ case BFD_RELOC_AARCH64_MOVW_G1:
+ case BFD_RELOC_AARCH64_MOVW_G1_NC:
+ case BFD_RELOC_AARCH64_MOVW_G2:
+ case BFD_RELOC_AARCH64_MOVW_G2_NC:
+ case BFD_RELOC_AARCH64_MOVW_G3:
+ value = value + addend;
+ break;
+
+ case BFD_RELOC_AARCH64_ADR_HI21_PCREL:
+ case BFD_RELOC_AARCH64_ADR_HI21_NC_PCREL:
+ if (weak_undef_p)
+ value = PG (place);
+ value = PG (value + addend) - PG (place);
+ break;
+
+ case BFD_RELOC_AARCH64_GOT_LD_PREL19:
+ value = value + addend - place;
+ break;
+
+ case BFD_RELOC_AARCH64_ADR_GOT_PAGE:
+ case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21:
+ case BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21:
+ case BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21:
+ value = PG (value + addend) - PG (place);
+ break;
+
+ case BFD_RELOC_AARCH64_ADD_LO12:
+ case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC:
+ case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC:
+ case BFD_RELOC_AARCH64_LDST8_LO12:
+ case BFD_RELOC_AARCH64_LDST16_LO12:
+ case BFD_RELOC_AARCH64_LDST32_LO12:
+ case BFD_RELOC_AARCH64_LDST64_LO12:
+ case BFD_RELOC_AARCH64_LDST128_LO12:
+ case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12_NC:
+ case BFD_RELOC_AARCH64_TLSDESC_ADD:
+ case BFD_RELOC_AARCH64_TLSDESC_LD64_LO12_NC:
+ case BFD_RELOC_AARCH64_TLSDESC_LD32_LO12_NC:
+ case BFD_RELOC_AARCH64_TLSDESC_LDR:
+ case BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC:
+ case BFD_RELOC_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC:
+ case BFD_RELOC_AARCH64_TLSIE_LD32_GOTTPREL_LO12_NC:
+ case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12:
+ case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12_NC:
+ value = PG_OFFSET (value + addend);
+ break;
+
+ case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1:
+ case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1_NC:
+ value = (value + addend) & (bfd_vma) 0xffff0000;
+ break;
+ case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_HI12:
+ value = (value + addend) & (bfd_vma) 0xfff000;
+ break;
+
+ case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0:
+ case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC:
+ value = (value + addend) & (bfd_vma) 0xffff;
+ break;
+
+ case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G2:
+ value = (value + addend) & ~(bfd_vma) 0xffffffff;
+ value -= place & ~(bfd_vma) 0xffffffff;
+ break;
+
+ default:
+ break;
+ }
+
+ return value;
+}
+
+/* Hook called by the linker routine which adds symbols from an object
+ file. */
+
+bfd_boolean
+_bfd_aarch64_elf_add_symbol_hook (bfd *abfd, struct bfd_link_info *info,
+ Elf_Internal_Sym *sym,
+ const char **namep ATTRIBUTE_UNUSED,
+ flagword *flagsp ATTRIBUTE_UNUSED,
+ asection **secp ATTRIBUTE_UNUSED,
+ bfd_vma *valp ATTRIBUTE_UNUSED)
+{
+ if ((ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC
+ || ELF_ST_BIND (sym->st_info) == STB_GNU_UNIQUE)
+ && (abfd->flags & DYNAMIC) == 0
+ && bfd_get_flavour (info->output_bfd) == bfd_target_elf_flavour)
+ elf_tdata (info->output_bfd)->has_gnu_symbols = TRUE;
+
+ return TRUE;
+}
+
+/* Support for core dump NOTE sections. */
+
+bfd_boolean
+_bfd_aarch64_elf_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
+{
+ int offset;
+ size_t size;
+
+ switch (note->descsz)
+ {
+ default:
+ return FALSE;
+
+ case 392: /* sizeof(struct elf_prstatus) on Linux/arm64. */
+ /* pr_cursig */
+ elf_tdata (abfd)->core->signal
+ = bfd_get_16 (abfd, note->descdata + 12);
+
+ /* pr_pid */
+ elf_tdata (abfd)->core->lwpid
+ = bfd_get_32 (abfd, note->descdata + 32);
+
+ /* pr_reg */
+ offset = 112;
+ size = 272;
+
+ break;
+ }
+
+ /* Make a ".reg/999" section. */
+ return _bfd_elfcore_make_pseudosection (abfd, ".reg",
+ size, note->descpos + offset);
+}
+
+bfd_boolean
+_bfd_aarch64_elf_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
+{
+ switch (note->descsz)
+ {
+ default:
+ return FALSE;
+
+ case 136: /* This is sizeof(struct elf_prpsinfo) on Linux/aarch64. */
+ elf_tdata (abfd)->core->pid = bfd_get_32 (abfd, note->descdata + 24);
+ elf_tdata (abfd)->core->program
+ = _bfd_elfcore_strndup (abfd, note->descdata + 40, 16);
+ elf_tdata (abfd)->core->command
+ = _bfd_elfcore_strndup (abfd, note->descdata + 56, 80);
+ }
+
+ /* 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;
+}
+
+char *
+_bfd_aarch64_elf_write_core_note (bfd *abfd, char *buf, int *bufsiz, int note_type,
+ ...)
+{
+ switch (note_type)
+ {
+ default:
+ return NULL;
+
+ case NT_PRPSINFO:
+ {
+ char data[136];
+ va_list ap;
+
+ va_start (ap, note_type);
+ memset (data, 0, sizeof (data));
+ strncpy (data + 40, va_arg (ap, const char *), 16);
+ strncpy (data + 56, va_arg (ap, const char *), 80);
+ va_end (ap);
+
+ return elfcore_write_note (abfd, buf, bufsiz, "CORE",
+ note_type, data, sizeof (data));
+ }
+
+ case NT_PRSTATUS:
+ {
+ char data[392];
+ va_list ap;
+ long pid;
+ int cursig;
+ const void *greg;
+
+ va_start (ap, note_type);
+ memset (data, 0, sizeof (data));
+ pid = va_arg (ap, long);
+ bfd_put_32 (abfd, pid, data + 32);
+ cursig = va_arg (ap, int);
+ bfd_put_16 (abfd, cursig, data + 12);
+ greg = va_arg (ap, const void *);
+ memcpy (data + 112, greg, 272);
+ va_end (ap);
+
+ return elfcore_write_note (abfd, buf, bufsiz, "CORE",
+ note_type, data, sizeof (data));
+ }
+ }
+}
diff --git a/bfd/elfxx-aarch64.h b/bfd/elfxx-aarch64.h
new file mode 100644
index 0000000..8808104
--- /dev/null
+++ b/bfd/elfxx-aarch64.h
@@ -0,0 +1,54 @@
+/* AArch64-specific backend routines.
+ Copyright (C) 2009-2014 Free Software Foundation, Inc.
+ Contributed by ARM Ltd.
+
+ This file is part of BFD, the Binary File Descriptor library.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 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 COPYING3. If not,
+ see <http://www.gnu.org/licenses/>. */
+
+#include "bfd.h"
+#include "elf-bfd.h"
+#include "stdint.h"
+
+/* Take the PAGE component of an address or offset. */
+#define PG(x) ((x) & ~ (bfd_vma) 0xfff)
+#define PG_OFFSET(x) ((x) & (bfd_vma) 0xfff)
+
+extern bfd_reloc_status_type
+_bfd_aarch64_elf_put_addend (bfd *, bfd_byte *, bfd_reloc_code_real_type,
+ reloc_howto_type *, bfd_signed_vma);
+
+extern bfd_vma
+_bfd_aarch64_elf_resolve_relocation (bfd_reloc_code_real_type, bfd_vma, bfd_vma,
+ bfd_vma, bfd_boolean);
+
+extern bfd_boolean
+_bfd_aarch64_elf_add_symbol_hook (bfd *, struct bfd_link_info *,
+ Elf_Internal_Sym *, const char **,
+ flagword *, asection **, bfd_vma *);
+
+extern bfd_boolean
+_bfd_aarch64_elf_grok_prstatus (bfd *, Elf_Internal_Note *);
+
+extern bfd_boolean
+_bfd_aarch64_elf_grok_psinfo (bfd *, Elf_Internal_Note *);
+
+extern char *
+_bfd_aarch64_elf_write_core_note (bfd *, char *, int *, int, ...);
+
+#define elf_backend_add_symbol_hook _bfd_aarch64_elf_add_symbol_hook
+#define elf_backend_grok_prstatus _bfd_aarch64_elf_grok_prstatus
+#define elf_backend_grok_psinfo _bfd_aarch64_elf_grok_psinfo
+#define elf_backend_write_core_note _bfd_aarch64_elf_write_core_note
diff --git a/bfd/elfxx-ia64.c b/bfd/elfxx-ia64.c
new file mode 100644
index 0000000..e9f884b
--- /dev/null
+++ b/bfd/elfxx-ia64.c
@@ -0,0 +1,764 @@
+/* IA-64 support for 64-bit ELF
+ Copyright (C) 1998-2014 Free Software Foundation, Inc.
+ Contributed by David Mosberger-Tang <davidm@hpl.hp.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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+#include "elf-bfd.h"
+#include "opcode/ia64.h"
+#include "elf/ia64.h"
+#include "objalloc.h"
+#include "hashtab.h"
+#include "bfd_stdint.h"
+#include "elfxx-ia64.h"
+
+/* THE RULES for all the stuff the linker creates --
+
+ GOT Entries created in response to LTOFF or LTOFF_FPTR
+ relocations. Dynamic relocs created for dynamic
+ symbols in an application; REL relocs for locals
+ in a shared library.
+
+ FPTR The canonical function descriptor. Created for local
+ symbols in applications. Descriptors for dynamic symbols
+ and local symbols in shared libraries are created by
+ ld.so. Thus there are no dynamic relocs against these
+ objects. The FPTR relocs for such _are_ passed through
+ to the dynamic relocation tables.
+
+ FULL_PLT Created for a PCREL21B relocation against a dynamic symbol.
+ Requires the creation of a PLTOFF entry. This does not
+ require any dynamic relocations.
+
+ PLTOFF Created by PLTOFF relocations. For local symbols, this
+ is an alternate function descriptor, and in shared libraries
+ requires two REL relocations. Note that this cannot be
+ transformed into an FPTR relocation, since it must be in
+ range of the GP. For dynamic symbols, this is a function
+ descriptor for a MIN_PLT entry, and requires one IPLT reloc.
+
+ MIN_PLT Created by PLTOFF entries against dynamic symbols. This
+ does not require dynamic relocations. */
+
+/* ia64-specific relocation. */
+
+#define NELEMS(a) ((int) (sizeof (a) / sizeof ((a)[0])))
+
+/* Perform a relocation. Not much to do here as all the hard work is
+ done in elfNN_ia64_final_link_relocate. */
+static bfd_reloc_status_type
+ia64_elf_reloc (bfd *abfd ATTRIBUTE_UNUSED, arelent *reloc,
+ asymbol *sym ATTRIBUTE_UNUSED,
+ PTR data ATTRIBUTE_UNUSED, asection *input_section,
+ bfd *output_bfd, char **error_message)
+{
+ if (output_bfd)
+ {
+ reloc->address += input_section->output_offset;
+ return bfd_reloc_ok;
+ }
+
+ if (input_section->flags & SEC_DEBUGGING)
+ return bfd_reloc_continue;
+
+ *error_message = "Unsupported call to ia64_elf_reloc";
+ return bfd_reloc_notsupported;
+}
+
+#define IA64_HOWTO(TYPE, NAME, SIZE, PCREL, IN) \
+ HOWTO (TYPE, 0, SIZE, 0, PCREL, 0, complain_overflow_signed, \
+ ia64_elf_reloc, NAME, FALSE, 0, -1, IN)
+
+/* This table has to be sorted according to increasing number of the
+ TYPE field. */
+static reloc_howto_type ia64_howto_table[] =
+ {
+ IA64_HOWTO (R_IA64_NONE, "NONE", 0, FALSE, TRUE),
+
+ IA64_HOWTO (R_IA64_IMM14, "IMM14", 0, FALSE, TRUE),
+ IA64_HOWTO (R_IA64_IMM22, "IMM22", 0, FALSE, TRUE),
+ IA64_HOWTO (R_IA64_IMM64, "IMM64", 0, FALSE, TRUE),
+ IA64_HOWTO (R_IA64_DIR32MSB, "DIR32MSB", 2, FALSE, TRUE),
+ IA64_HOWTO (R_IA64_DIR32LSB, "DIR32LSB", 2, FALSE, TRUE),
+ IA64_HOWTO (R_IA64_DIR64MSB, "DIR64MSB", 4, FALSE, TRUE),
+ IA64_HOWTO (R_IA64_DIR64LSB, "DIR64LSB", 4, FALSE, TRUE),
+
+ IA64_HOWTO (R_IA64_GPREL22, "GPREL22", 0, FALSE, TRUE),
+ IA64_HOWTO (R_IA64_GPREL64I, "GPREL64I", 0, FALSE, TRUE),
+ IA64_HOWTO (R_IA64_GPREL32MSB, "GPREL32MSB", 2, FALSE, TRUE),
+ IA64_HOWTO (R_IA64_GPREL32LSB, "GPREL32LSB", 2, FALSE, TRUE),
+ IA64_HOWTO (R_IA64_GPREL64MSB, "GPREL64MSB", 4, FALSE, TRUE),
+ IA64_HOWTO (R_IA64_GPREL64LSB, "GPREL64LSB", 4, FALSE, TRUE),
+
+ IA64_HOWTO (R_IA64_LTOFF22, "LTOFF22", 0, FALSE, TRUE),
+ IA64_HOWTO (R_IA64_LTOFF64I, "LTOFF64I", 0, FALSE, TRUE),
+
+ IA64_HOWTO (R_IA64_PLTOFF22, "PLTOFF22", 0, FALSE, TRUE),
+ IA64_HOWTO (R_IA64_PLTOFF64I, "PLTOFF64I", 0, FALSE, TRUE),
+ IA64_HOWTO (R_IA64_PLTOFF64MSB, "PLTOFF64MSB", 4, FALSE, TRUE),
+ IA64_HOWTO (R_IA64_PLTOFF64LSB, "PLTOFF64LSB", 4, FALSE, TRUE),
+
+ IA64_HOWTO (R_IA64_FPTR64I, "FPTR64I", 0, FALSE, TRUE),
+ IA64_HOWTO (R_IA64_FPTR32MSB, "FPTR32MSB", 2, FALSE, TRUE),
+ IA64_HOWTO (R_IA64_FPTR32LSB, "FPTR32LSB", 2, FALSE, TRUE),
+ IA64_HOWTO (R_IA64_FPTR64MSB, "FPTR64MSB", 4, FALSE, TRUE),
+ IA64_HOWTO (R_IA64_FPTR64LSB, "FPTR64LSB", 4, FALSE, TRUE),
+
+ IA64_HOWTO (R_IA64_PCREL60B, "PCREL60B", 0, TRUE, TRUE),
+ IA64_HOWTO (R_IA64_PCREL21B, "PCREL21B", 0, TRUE, TRUE),
+ IA64_HOWTO (R_IA64_PCREL21M, "PCREL21M", 0, TRUE, TRUE),
+ IA64_HOWTO (R_IA64_PCREL21F, "PCREL21F", 0, TRUE, TRUE),
+ IA64_HOWTO (R_IA64_PCREL32MSB, "PCREL32MSB", 2, TRUE, TRUE),
+ IA64_HOWTO (R_IA64_PCREL32LSB, "PCREL32LSB", 2, TRUE, TRUE),
+ IA64_HOWTO (R_IA64_PCREL64MSB, "PCREL64MSB", 4, TRUE, TRUE),
+ IA64_HOWTO (R_IA64_PCREL64LSB, "PCREL64LSB", 4, TRUE, TRUE),
+
+ IA64_HOWTO (R_IA64_LTOFF_FPTR22, "LTOFF_FPTR22", 0, FALSE, TRUE),
+ IA64_HOWTO (R_IA64_LTOFF_FPTR64I, "LTOFF_FPTR64I", 0, FALSE, TRUE),
+ IA64_HOWTO (R_IA64_LTOFF_FPTR32MSB, "LTOFF_FPTR32MSB", 2, FALSE, TRUE),
+ IA64_HOWTO (R_IA64_LTOFF_FPTR32LSB, "LTOFF_FPTR32LSB", 2, FALSE, TRUE),
+ IA64_HOWTO (R_IA64_LTOFF_FPTR64MSB, "LTOFF_FPTR64MSB", 4, FALSE, TRUE),
+ IA64_HOWTO (R_IA64_LTOFF_FPTR64LSB, "LTOFF_FPTR64LSB", 4, FALSE, TRUE),
+
+ IA64_HOWTO (R_IA64_SEGREL32MSB, "SEGREL32MSB", 2, FALSE, TRUE),
+ IA64_HOWTO (R_IA64_SEGREL32LSB, "SEGREL32LSB", 2, FALSE, TRUE),
+ IA64_HOWTO (R_IA64_SEGREL64MSB, "SEGREL64MSB", 4, FALSE, TRUE),
+ IA64_HOWTO (R_IA64_SEGREL64LSB, "SEGREL64LSB", 4, FALSE, TRUE),
+
+ IA64_HOWTO (R_IA64_SECREL32MSB, "SECREL32MSB", 2, FALSE, TRUE),
+ IA64_HOWTO (R_IA64_SECREL32LSB, "SECREL32LSB", 2, FALSE, TRUE),
+ IA64_HOWTO (R_IA64_SECREL64MSB, "SECREL64MSB", 4, FALSE, TRUE),
+ IA64_HOWTO (R_IA64_SECREL64LSB, "SECREL64LSB", 4, FALSE, TRUE),
+
+ IA64_HOWTO (R_IA64_REL32MSB, "REL32MSB", 2, FALSE, TRUE),
+ IA64_HOWTO (R_IA64_REL32LSB, "REL32LSB", 2, FALSE, TRUE),
+ IA64_HOWTO (R_IA64_REL64MSB, "REL64MSB", 4, FALSE, TRUE),
+ IA64_HOWTO (R_IA64_REL64LSB, "REL64LSB", 4, FALSE, TRUE),
+
+ IA64_HOWTO (R_IA64_LTV32MSB, "LTV32MSB", 2, FALSE, TRUE),
+ IA64_HOWTO (R_IA64_LTV32LSB, "LTV32LSB", 2, FALSE, TRUE),
+ IA64_HOWTO (R_IA64_LTV64MSB, "LTV64MSB", 4, FALSE, TRUE),
+ IA64_HOWTO (R_IA64_LTV64LSB, "LTV64LSB", 4, FALSE, TRUE),
+
+ IA64_HOWTO (R_IA64_PCREL21BI, "PCREL21BI", 0, TRUE, TRUE),
+ IA64_HOWTO (R_IA64_PCREL22, "PCREL22", 0, TRUE, TRUE),
+ IA64_HOWTO (R_IA64_PCREL64I, "PCREL64I", 0, TRUE, TRUE),
+
+ IA64_HOWTO (R_IA64_IPLTMSB, "IPLTMSB", 4, FALSE, TRUE),
+ IA64_HOWTO (R_IA64_IPLTLSB, "IPLTLSB", 4, FALSE, TRUE),
+ IA64_HOWTO (R_IA64_COPY, "COPY", 4, FALSE, TRUE),
+ IA64_HOWTO (R_IA64_LTOFF22X, "LTOFF22X", 0, FALSE, TRUE),
+ IA64_HOWTO (R_IA64_LDXMOV, "LDXMOV", 0, FALSE, TRUE),
+
+ IA64_HOWTO (R_IA64_TPREL14, "TPREL14", 0, FALSE, FALSE),
+ IA64_HOWTO (R_IA64_TPREL22, "TPREL22", 0, FALSE, FALSE),
+ IA64_HOWTO (R_IA64_TPREL64I, "TPREL64I", 0, FALSE, FALSE),
+ IA64_HOWTO (R_IA64_TPREL64MSB, "TPREL64MSB", 4, FALSE, FALSE),
+ IA64_HOWTO (R_IA64_TPREL64LSB, "TPREL64LSB", 4, FALSE, FALSE),
+ IA64_HOWTO (R_IA64_LTOFF_TPREL22, "LTOFF_TPREL22", 0, FALSE, FALSE),
+
+ IA64_HOWTO (R_IA64_DTPMOD64MSB, "DTPMOD64MSB", 4, FALSE, FALSE),
+ IA64_HOWTO (R_IA64_DTPMOD64LSB, "DTPMOD64LSB", 4, FALSE, FALSE),
+ IA64_HOWTO (R_IA64_LTOFF_DTPMOD22, "LTOFF_DTPMOD22", 0, FALSE, FALSE),
+
+ IA64_HOWTO (R_IA64_DTPREL14, "DTPREL14", 0, FALSE, FALSE),
+ IA64_HOWTO (R_IA64_DTPREL22, "DTPREL22", 0, FALSE, FALSE),
+ IA64_HOWTO (R_IA64_DTPREL64I, "DTPREL64I", 0, FALSE, FALSE),
+ IA64_HOWTO (R_IA64_DTPREL32MSB, "DTPREL32MSB", 2, FALSE, FALSE),
+ IA64_HOWTO (R_IA64_DTPREL32LSB, "DTPREL32LSB", 2, FALSE, FALSE),
+ IA64_HOWTO (R_IA64_DTPREL64MSB, "DTPREL64MSB", 4, FALSE, FALSE),
+ IA64_HOWTO (R_IA64_DTPREL64LSB, "DTPREL64LSB", 4, FALSE, FALSE),
+ IA64_HOWTO (R_IA64_LTOFF_DTPREL22, "LTOFF_DTPREL22", 0, FALSE, FALSE),
+ };
+
+static unsigned char elf_code_to_howto_index[R_IA64_MAX_RELOC_CODE + 1];
+
+/* Given a BFD reloc type, return the matching HOWTO structure. */
+
+reloc_howto_type *
+ia64_elf_lookup_howto (unsigned int rtype)
+{
+ static int inited = 0;
+ int i;
+
+ if (!inited)
+ {
+ inited = 1;
+
+ memset (elf_code_to_howto_index, 0xff, sizeof (elf_code_to_howto_index));
+ for (i = 0; i < NELEMS (ia64_howto_table); ++i)
+ elf_code_to_howto_index[ia64_howto_table[i].type] = i;
+ }
+
+ if (rtype > R_IA64_MAX_RELOC_CODE)
+ return 0;
+ i = elf_code_to_howto_index[rtype];
+ if (i >= NELEMS (ia64_howto_table))
+ return 0;
+ return ia64_howto_table + i;
+}
+
+reloc_howto_type*
+ia64_elf_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ bfd_reloc_code_real_type bfd_code)
+{
+ unsigned int rtype;
+
+ switch (bfd_code)
+ {
+ case BFD_RELOC_NONE: rtype = R_IA64_NONE; break;
+
+ case BFD_RELOC_IA64_IMM14: rtype = R_IA64_IMM14; break;
+ case BFD_RELOC_IA64_IMM22: rtype = R_IA64_IMM22; break;
+ case BFD_RELOC_IA64_IMM64: rtype = R_IA64_IMM64; break;
+
+ case BFD_RELOC_IA64_DIR32MSB: rtype = R_IA64_DIR32MSB; break;
+ case BFD_RELOC_IA64_DIR32LSB: rtype = R_IA64_DIR32LSB; break;
+ case BFD_RELOC_IA64_DIR64MSB: rtype = R_IA64_DIR64MSB; break;
+ case BFD_RELOC_IA64_DIR64LSB: rtype = R_IA64_DIR64LSB; break;
+
+ case BFD_RELOC_IA64_GPREL22: rtype = R_IA64_GPREL22; break;
+ case BFD_RELOC_IA64_GPREL64I: rtype = R_IA64_GPREL64I; break;
+ case BFD_RELOC_IA64_GPREL32MSB: rtype = R_IA64_GPREL32MSB; break;
+ case BFD_RELOC_IA64_GPREL32LSB: rtype = R_IA64_GPREL32LSB; break;
+ case BFD_RELOC_IA64_GPREL64MSB: rtype = R_IA64_GPREL64MSB; break;
+ case BFD_RELOC_IA64_GPREL64LSB: rtype = R_IA64_GPREL64LSB; break;
+
+ case BFD_RELOC_IA64_LTOFF22: rtype = R_IA64_LTOFF22; break;
+ case BFD_RELOC_IA64_LTOFF64I: rtype = R_IA64_LTOFF64I; break;
+
+ case BFD_RELOC_IA64_PLTOFF22: rtype = R_IA64_PLTOFF22; break;
+ case BFD_RELOC_IA64_PLTOFF64I: rtype = R_IA64_PLTOFF64I; break;
+ case BFD_RELOC_IA64_PLTOFF64MSB: rtype = R_IA64_PLTOFF64MSB; break;
+ case BFD_RELOC_IA64_PLTOFF64LSB: rtype = R_IA64_PLTOFF64LSB; break;
+ case BFD_RELOC_IA64_FPTR64I: rtype = R_IA64_FPTR64I; break;
+ case BFD_RELOC_IA64_FPTR32MSB: rtype = R_IA64_FPTR32MSB; break;
+ case BFD_RELOC_IA64_FPTR32LSB: rtype = R_IA64_FPTR32LSB; break;
+ case BFD_RELOC_IA64_FPTR64MSB: rtype = R_IA64_FPTR64MSB; break;
+ case BFD_RELOC_IA64_FPTR64LSB: rtype = R_IA64_FPTR64LSB; break;
+
+ case BFD_RELOC_IA64_PCREL21B: rtype = R_IA64_PCREL21B; break;
+ case BFD_RELOC_IA64_PCREL21BI: rtype = R_IA64_PCREL21BI; break;
+ case BFD_RELOC_IA64_PCREL21M: rtype = R_IA64_PCREL21M; break;
+ case BFD_RELOC_IA64_PCREL21F: rtype = R_IA64_PCREL21F; break;
+ case BFD_RELOC_IA64_PCREL22: rtype = R_IA64_PCREL22; break;
+ case BFD_RELOC_IA64_PCREL60B: rtype = R_IA64_PCREL60B; break;
+ case BFD_RELOC_IA64_PCREL64I: rtype = R_IA64_PCREL64I; break;
+ case BFD_RELOC_IA64_PCREL32MSB: rtype = R_IA64_PCREL32MSB; break;
+ case BFD_RELOC_IA64_PCREL32LSB: rtype = R_IA64_PCREL32LSB; break;
+ case BFD_RELOC_IA64_PCREL64MSB: rtype = R_IA64_PCREL64MSB; break;
+ case BFD_RELOC_IA64_PCREL64LSB: rtype = R_IA64_PCREL64LSB; break;
+
+ case BFD_RELOC_IA64_LTOFF_FPTR22: rtype = R_IA64_LTOFF_FPTR22; break;
+ case BFD_RELOC_IA64_LTOFF_FPTR64I: rtype = R_IA64_LTOFF_FPTR64I; break;
+ case BFD_RELOC_IA64_LTOFF_FPTR32MSB: rtype = R_IA64_LTOFF_FPTR32MSB; break;
+ case BFD_RELOC_IA64_LTOFF_FPTR32LSB: rtype = R_IA64_LTOFF_FPTR32LSB; break;
+ case BFD_RELOC_IA64_LTOFF_FPTR64MSB: rtype = R_IA64_LTOFF_FPTR64MSB; break;
+ case BFD_RELOC_IA64_LTOFF_FPTR64LSB: rtype = R_IA64_LTOFF_FPTR64LSB; break;
+
+ case BFD_RELOC_IA64_SEGREL32MSB: rtype = R_IA64_SEGREL32MSB; break;
+ case BFD_RELOC_IA64_SEGREL32LSB: rtype = R_IA64_SEGREL32LSB; break;
+ case BFD_RELOC_IA64_SEGREL64MSB: rtype = R_IA64_SEGREL64MSB; break;
+ case BFD_RELOC_IA64_SEGREL64LSB: rtype = R_IA64_SEGREL64LSB; break;
+
+ case BFD_RELOC_IA64_SECREL32MSB: rtype = R_IA64_SECREL32MSB; break;
+ case BFD_RELOC_IA64_SECREL32LSB: rtype = R_IA64_SECREL32LSB; break;
+ case BFD_RELOC_IA64_SECREL64MSB: rtype = R_IA64_SECREL64MSB; break;
+ case BFD_RELOC_IA64_SECREL64LSB: rtype = R_IA64_SECREL64LSB; break;
+
+ case BFD_RELOC_IA64_REL32MSB: rtype = R_IA64_REL32MSB; break;
+ case BFD_RELOC_IA64_REL32LSB: rtype = R_IA64_REL32LSB; break;
+ case BFD_RELOC_IA64_REL64MSB: rtype = R_IA64_REL64MSB; break;
+ case BFD_RELOC_IA64_REL64LSB: rtype = R_IA64_REL64LSB; break;
+
+ case BFD_RELOC_IA64_LTV32MSB: rtype = R_IA64_LTV32MSB; break;
+ case BFD_RELOC_IA64_LTV32LSB: rtype = R_IA64_LTV32LSB; break;
+ case BFD_RELOC_IA64_LTV64MSB: rtype = R_IA64_LTV64MSB; break;
+ case BFD_RELOC_IA64_LTV64LSB: rtype = R_IA64_LTV64LSB; break;
+
+ case BFD_RELOC_IA64_IPLTMSB: rtype = R_IA64_IPLTMSB; break;
+ case BFD_RELOC_IA64_IPLTLSB: rtype = R_IA64_IPLTLSB; break;
+ case BFD_RELOC_IA64_COPY: rtype = R_IA64_COPY; break;
+ case BFD_RELOC_IA64_LTOFF22X: rtype = R_IA64_LTOFF22X; break;
+ case BFD_RELOC_IA64_LDXMOV: rtype = R_IA64_LDXMOV; break;
+
+ case BFD_RELOC_IA64_TPREL14: rtype = R_IA64_TPREL14; break;
+ case BFD_RELOC_IA64_TPREL22: rtype = R_IA64_TPREL22; break;
+ case BFD_RELOC_IA64_TPREL64I: rtype = R_IA64_TPREL64I; break;
+ case BFD_RELOC_IA64_TPREL64MSB: rtype = R_IA64_TPREL64MSB; break;
+ case BFD_RELOC_IA64_TPREL64LSB: rtype = R_IA64_TPREL64LSB; break;
+ case BFD_RELOC_IA64_LTOFF_TPREL22: rtype = R_IA64_LTOFF_TPREL22; break;
+
+ case BFD_RELOC_IA64_DTPMOD64MSB: rtype = R_IA64_DTPMOD64MSB; break;
+ case BFD_RELOC_IA64_DTPMOD64LSB: rtype = R_IA64_DTPMOD64LSB; break;
+ case BFD_RELOC_IA64_LTOFF_DTPMOD22: rtype = R_IA64_LTOFF_DTPMOD22; break;
+
+ case BFD_RELOC_IA64_DTPREL14: rtype = R_IA64_DTPREL14; break;
+ case BFD_RELOC_IA64_DTPREL22: rtype = R_IA64_DTPREL22; break;
+ case BFD_RELOC_IA64_DTPREL64I: rtype = R_IA64_DTPREL64I; break;
+ case BFD_RELOC_IA64_DTPREL32MSB: rtype = R_IA64_DTPREL32MSB; break;
+ case BFD_RELOC_IA64_DTPREL32LSB: rtype = R_IA64_DTPREL32LSB; break;
+ case BFD_RELOC_IA64_DTPREL64MSB: rtype = R_IA64_DTPREL64MSB; break;
+ case BFD_RELOC_IA64_DTPREL64LSB: rtype = R_IA64_DTPREL64LSB; break;
+ case BFD_RELOC_IA64_LTOFF_DTPREL22: rtype = R_IA64_LTOFF_DTPREL22; break;
+
+ default: return 0;
+ }
+ return ia64_elf_lookup_howto (rtype);
+}
+
+reloc_howto_type *
+ia64_elf_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ const char *r_name)
+{
+ unsigned int i;
+
+ for (i = 0;
+ i < sizeof (ia64_howto_table) / sizeof (ia64_howto_table[0]);
+ i++)
+ if (ia64_howto_table[i].name != NULL
+ && strcasecmp (ia64_howto_table[i].name, r_name) == 0)
+ return &ia64_howto_table[i];
+
+ return NULL;
+}
+
+#define BTYPE_SHIFT 6
+#define Y_SHIFT 26
+#define X6_SHIFT 27
+#define X4_SHIFT 27
+#define X3_SHIFT 33
+#define X2_SHIFT 31
+#define X_SHIFT 33
+#define OPCODE_SHIFT 37
+
+#define OPCODE_BITS (0xfLL << OPCODE_SHIFT)
+#define X6_BITS (0x3fLL << X6_SHIFT)
+#define X4_BITS (0xfLL << X4_SHIFT)
+#define X3_BITS (0x7LL << X3_SHIFT)
+#define X2_BITS (0x3LL << X2_SHIFT)
+#define X_BITS (0x1LL << X_SHIFT)
+#define Y_BITS (0x1LL << Y_SHIFT)
+#define BTYPE_BITS (0x7LL << BTYPE_SHIFT)
+#define PREDICATE_BITS (0x3fLL)
+
+#define IS_NOP_B(i) \
+ (((i) & (OPCODE_BITS | X6_BITS)) == (2LL << OPCODE_SHIFT))
+#define IS_NOP_F(i) \
+ (((i) & (OPCODE_BITS | X_BITS | X6_BITS | Y_BITS)) \
+ == (0x1LL << X6_SHIFT))
+#define IS_NOP_I(i) \
+ (((i) & (OPCODE_BITS | X3_BITS | X6_BITS | Y_BITS)) \
+ == (0x1LL << X6_SHIFT))
+#define IS_NOP_M(i) \
+ (((i) & (OPCODE_BITS | X3_BITS | X2_BITS | X4_BITS | Y_BITS)) \
+ == (0x1LL << X4_SHIFT))
+#define IS_BR_COND(i) \
+ (((i) & (OPCODE_BITS | BTYPE_BITS)) == (0x4LL << OPCODE_SHIFT))
+#define IS_BR_CALL(i) \
+ (((i) & OPCODE_BITS) == (0x5LL << OPCODE_SHIFT))
+
+bfd_boolean
+ia64_elf_relax_br (bfd_byte *contents, bfd_vma off)
+{
+ unsigned int template_val, mlx;
+ bfd_vma t0, t1, s0, s1, s2, br_code;
+ long br_slot;
+ bfd_byte *hit_addr;
+
+ hit_addr = (bfd_byte *) (contents + off);
+ br_slot = (intptr_t) hit_addr & 0x3;
+ hit_addr -= br_slot;
+ t0 = bfd_getl64 (hit_addr + 0);
+ t1 = bfd_getl64 (hit_addr + 8);
+
+ /* Check if we can turn br into brl. A label is always at the start
+ of the bundle. Even if there are predicates on NOPs, we still
+ perform this optimization. */
+ template_val = t0 & 0x1e;
+ s0 = (t0 >> 5) & 0x1ffffffffffLL;
+ s1 = ((t0 >> 46) | (t1 << 18)) & 0x1ffffffffffLL;
+ s2 = (t1 >> 23) & 0x1ffffffffffLL;
+ switch (br_slot)
+ {
+ case 0:
+ /* Check if slot 1 and slot 2 are NOPs. Possible template is
+ BBB. We only need to check nop.b. */
+ if (!(IS_NOP_B (s1) && IS_NOP_B (s2)))
+ return FALSE;
+ br_code = s0;
+ break;
+ case 1:
+ /* Check if slot 2 is NOP. Possible templates are MBB and BBB.
+ For BBB, slot 0 also has to be nop.b. */
+ if (!((template_val == 0x12 /* MBB */
+ && IS_NOP_B (s2))
+ || (template_val == 0x16 /* BBB */
+ && IS_NOP_B (s0)
+ && IS_NOP_B (s2))))
+ return FALSE;
+ br_code = s1;
+ break;
+ case 2:
+ /* Check if slot 1 is NOP. Possible templates are MIB, MBB, BBB,
+ MMB and MFB. For BBB, slot 0 also has to be nop.b. */
+ if (!((template_val == 0x10 /* MIB */
+ && IS_NOP_I (s1))
+ || (template_val == 0x12 /* MBB */
+ && IS_NOP_B (s1))
+ || (template_val == 0x16 /* BBB */
+ && IS_NOP_B (s0)
+ && IS_NOP_B (s1))
+ || (template_val == 0x18 /* MMB */
+ && IS_NOP_M (s1))
+ || (template_val == 0x1c /* MFB */
+ && IS_NOP_F (s1))))
+ return FALSE;
+ br_code = s2;
+ break;
+ default:
+ /* It should never happen. */
+ abort ();
+ }
+
+ /* We can turn br.cond/br.call into brl.cond/brl.call. */
+ if (!(IS_BR_COND (br_code) || IS_BR_CALL (br_code)))
+ return FALSE;
+
+ /* Turn br into brl by setting bit 40. */
+ br_code |= 0x1LL << 40;
+
+ /* Turn the old bundle into a MLX bundle with the same stop-bit
+ variety. */
+ if (t0 & 0x1)
+ mlx = 0x5;
+ else
+ mlx = 0x4;
+
+ if (template_val == 0x16)
+ {
+ /* For BBB, we need to put nop.m in slot 0. We keep the original
+ predicate only if slot 0 isn't br. */
+ if (br_slot == 0)
+ t0 = 0LL;
+ else
+ t0 &= PREDICATE_BITS << 5;
+ t0 |= 0x1LL << (X4_SHIFT + 5);
+ }
+ else
+ {
+ /* Keep the original instruction in slot 0. */
+ t0 &= 0x1ffffffffffLL << 5;
+ }
+
+ t0 |= mlx;
+
+ /* Put brl in slot 1. */
+ t1 = br_code << 23;
+
+ bfd_putl64 (t0, hit_addr);
+ bfd_putl64 (t1, hit_addr + 8);
+ return TRUE;
+}
+
+void
+ia64_elf_relax_brl (bfd_byte *contents, bfd_vma off)
+{
+ int template_val;
+ bfd_byte *hit_addr;
+ bfd_vma t0, t1, i0, i1, i2;
+
+ hit_addr = (bfd_byte *) (contents + off);
+ hit_addr -= (intptr_t) hit_addr & 0x3;
+ t0 = bfd_getl64 (hit_addr);
+ t1 = bfd_getl64 (hit_addr + 8);
+
+ /* Keep the instruction in slot 0. */
+ i0 = (t0 >> 5) & 0x1ffffffffffLL;
+ /* Use nop.b for slot 1. */
+ i1 = 0x4000000000LL;
+ /* For slot 2, turn brl into br by masking out bit 40. */
+ i2 = (t1 >> 23) & 0x0ffffffffffLL;
+
+ /* Turn a MLX bundle into a MBB bundle with the same stop-bit
+ variety. */
+ if (t0 & 0x1)
+ template_val = 0x13;
+ else
+ template_val = 0x12;
+ t0 = (i1 << 46) | (i0 << 5) | template_val;
+ t1 = (i2 << 23) | (i1 >> 18);
+
+ bfd_putl64 (t0, hit_addr);
+ bfd_putl64 (t1, hit_addr + 8);
+}
+
+void
+ia64_elf_relax_ldxmov (bfd_byte *contents, bfd_vma off)
+{
+ int shift, r1, r3;
+ bfd_vma dword, insn;
+
+ switch ((int)off & 0x3)
+ {
+ case 0: shift = 5; break;
+ case 1: shift = 14; off += 3; break;
+ case 2: shift = 23; off += 6; break;
+ default:
+ abort ();
+ }
+
+ dword = bfd_getl64 (contents + off);
+ insn = (dword >> shift) & 0x1ffffffffffLL;
+
+ r1 = (insn >> 6) & 127;
+ r3 = (insn >> 20) & 127;
+ if (r1 == r3)
+ insn = 0x8000000; /* nop */
+ else
+ insn = (insn & 0x7f01fff) | 0x10800000000LL; /* (qp) mov r1 = r3 */
+
+ dword &= ~(0x1ffffffffffLL << shift);
+ dword |= (insn << shift);
+ bfd_putl64 (dword, contents + off);
+}
+
+bfd_reloc_status_type
+ia64_elf_install_value (bfd_byte *hit_addr, bfd_vma v, unsigned int r_type)
+{
+ const struct ia64_operand *op;
+ int bigendian = 0, shift = 0;
+ bfd_vma t0, t1, dword;
+ ia64_insn insn;
+ enum ia64_opnd opnd;
+ const char *err;
+ size_t size = 8;
+#ifdef BFD_HOST_U_64_BIT
+ BFD_HOST_U_64_BIT val = (BFD_HOST_U_64_BIT) v;
+#else
+ bfd_vma val = v;
+#endif
+
+ opnd = IA64_OPND_NIL;
+ switch (r_type)
+ {
+ case R_IA64_NONE:
+ case R_IA64_LDXMOV:
+ return bfd_reloc_ok;
+
+ /* Instruction relocations. */
+
+ case R_IA64_IMM14:
+ case R_IA64_TPREL14:
+ case R_IA64_DTPREL14:
+ opnd = IA64_OPND_IMM14;
+ break;
+
+ case R_IA64_PCREL21F: opnd = IA64_OPND_TGT25; break;
+ case R_IA64_PCREL21M: opnd = IA64_OPND_TGT25b; break;
+ case R_IA64_PCREL60B: opnd = IA64_OPND_TGT64; break;
+ case R_IA64_PCREL21B:
+ case R_IA64_PCREL21BI:
+ opnd = IA64_OPND_TGT25c;
+ break;
+
+ case R_IA64_IMM22:
+ case R_IA64_GPREL22:
+ case R_IA64_LTOFF22:
+ case R_IA64_LTOFF22X:
+ case R_IA64_PLTOFF22:
+ case R_IA64_PCREL22:
+ case R_IA64_LTOFF_FPTR22:
+ case R_IA64_TPREL22:
+ case R_IA64_DTPREL22:
+ case R_IA64_LTOFF_TPREL22:
+ case R_IA64_LTOFF_DTPMOD22:
+ case R_IA64_LTOFF_DTPREL22:
+ opnd = IA64_OPND_IMM22;
+ break;
+
+ case R_IA64_IMM64:
+ case R_IA64_GPREL64I:
+ case R_IA64_LTOFF64I:
+ case R_IA64_PLTOFF64I:
+ case R_IA64_PCREL64I:
+ case R_IA64_FPTR64I:
+ case R_IA64_LTOFF_FPTR64I:
+ case R_IA64_TPREL64I:
+ case R_IA64_DTPREL64I:
+ opnd = IA64_OPND_IMMU64;
+ break;
+
+ /* Data relocations. */
+
+ case R_IA64_DIR32MSB:
+ case R_IA64_GPREL32MSB:
+ case R_IA64_FPTR32MSB:
+ case R_IA64_PCREL32MSB:
+ case R_IA64_LTOFF_FPTR32MSB:
+ case R_IA64_SEGREL32MSB:
+ case R_IA64_SECREL32MSB:
+ case R_IA64_LTV32MSB:
+ case R_IA64_DTPREL32MSB:
+ size = 4; bigendian = 1;
+ break;
+
+ case R_IA64_DIR32LSB:
+ case R_IA64_GPREL32LSB:
+ case R_IA64_FPTR32LSB:
+ case R_IA64_PCREL32LSB:
+ case R_IA64_LTOFF_FPTR32LSB:
+ case R_IA64_SEGREL32LSB:
+ case R_IA64_SECREL32LSB:
+ case R_IA64_LTV32LSB:
+ case R_IA64_DTPREL32LSB:
+ size = 4; bigendian = 0;
+ break;
+
+ case R_IA64_DIR64MSB:
+ case R_IA64_GPREL64MSB:
+ case R_IA64_PLTOFF64MSB:
+ case R_IA64_FPTR64MSB:
+ case R_IA64_PCREL64MSB:
+ case R_IA64_LTOFF_FPTR64MSB:
+ case R_IA64_SEGREL64MSB:
+ case R_IA64_SECREL64MSB:
+ case R_IA64_LTV64MSB:
+ case R_IA64_TPREL64MSB:
+ case R_IA64_DTPMOD64MSB:
+ case R_IA64_DTPREL64MSB:
+ size = 8; bigendian = 1;
+ break;
+
+ case R_IA64_DIR64LSB:
+ case R_IA64_GPREL64LSB:
+ case R_IA64_PLTOFF64LSB:
+ case R_IA64_FPTR64LSB:
+ case R_IA64_PCREL64LSB:
+ case R_IA64_LTOFF_FPTR64LSB:
+ case R_IA64_SEGREL64LSB:
+ case R_IA64_SECREL64LSB:
+ case R_IA64_LTV64LSB:
+ case R_IA64_TPREL64LSB:
+ case R_IA64_DTPMOD64LSB:
+ case R_IA64_DTPREL64LSB:
+ size = 8; bigendian = 0;
+ break;
+
+ /* Unsupported / Dynamic relocations. */
+ default:
+ return bfd_reloc_notsupported;
+ }
+
+ switch (opnd)
+ {
+ case IA64_OPND_IMMU64:
+ hit_addr -= (intptr_t) hit_addr & 0x3;
+ t0 = bfd_getl64 (hit_addr);
+ t1 = bfd_getl64 (hit_addr + 8);
+
+ /* tmpl/s: bits 0.. 5 in t0
+ slot 0: bits 5..45 in t0
+ slot 1: bits 46..63 in t0, bits 0..22 in t1
+ slot 2: bits 23..63 in t1 */
+
+ /* First, clear the bits that form the 64 bit constant. */
+ t0 &= ~(0x3ffffLL << 46);
+ t1 &= ~(0x7fffffLL
+ | (( (0x07fLL << 13) | (0x1ffLL << 27)
+ | (0x01fLL << 22) | (0x001LL << 21)
+ | (0x001LL << 36)) << 23));
+
+ t0 |= ((val >> 22) & 0x03ffffLL) << 46; /* 18 lsbs of imm41 */
+ t1 |= ((val >> 40) & 0x7fffffLL) << 0; /* 23 msbs of imm41 */
+ t1 |= ( (((val >> 0) & 0x07f) << 13) /* imm7b */
+ | (((val >> 7) & 0x1ff) << 27) /* imm9d */
+ | (((val >> 16) & 0x01f) << 22) /* imm5c */
+ | (((val >> 21) & 0x001) << 21) /* ic */
+ | (((val >> 63) & 0x001) << 36)) << 23; /* i */
+
+ bfd_putl64 (t0, hit_addr);
+ bfd_putl64 (t1, hit_addr + 8);
+ break;
+
+ case IA64_OPND_TGT64:
+ hit_addr -= (intptr_t) hit_addr & 0x3;
+ t0 = bfd_getl64 (hit_addr);
+ t1 = bfd_getl64 (hit_addr + 8);
+
+ /* tmpl/s: bits 0.. 5 in t0
+ slot 0: bits 5..45 in t0
+ slot 1: bits 46..63 in t0, bits 0..22 in t1
+ slot 2: bits 23..63 in t1 */
+
+ /* First, clear the bits that form the 64 bit constant. */
+ t0 &= ~(0x3ffffLL << 46);
+ t1 &= ~(0x7fffffLL
+ | ((1LL << 36 | 0xfffffLL << 13) << 23));
+
+ val >>= 4;
+ t0 |= ((val >> 20) & 0xffffLL) << 2 << 46; /* 16 lsbs of imm39 */
+ t1 |= ((val >> 36) & 0x7fffffLL) << 0; /* 23 msbs of imm39 */
+ t1 |= ((((val >> 0) & 0xfffffLL) << 13) /* imm20b */
+ | (((val >> 59) & 0x1LL) << 36)) << 23; /* i */
+
+ bfd_putl64 (t0, hit_addr);
+ bfd_putl64 (t1, hit_addr + 8);
+ break;
+
+ default:
+ switch ((intptr_t) hit_addr & 0x3)
+ {
+ case 0: shift = 5; break;
+ case 1: shift = 14; hit_addr += 3; break;
+ case 2: shift = 23; hit_addr += 6; break;
+ case 3: return bfd_reloc_notsupported; /* shouldn't happen... */
+ }
+ dword = bfd_getl64 (hit_addr);
+ insn = (dword >> shift) & 0x1ffffffffffLL;
+
+ op = elf64_ia64_operands + opnd;
+ err = (*op->insert) (op, val, &insn);
+ if (err)
+ return bfd_reloc_overflow;
+
+ dword &= ~(0x1ffffffffffLL << shift);
+ dword |= (insn << shift);
+ bfd_putl64 (dword, hit_addr);
+ break;
+
+ case IA64_OPND_NIL:
+ /* A data relocation. */
+ if (bigendian)
+ if (size == 4)
+ bfd_putb32 (val, hit_addr);
+ else
+ bfd_putb64 (val, hit_addr);
+ else
+ if (size == 4)
+ bfd_putl32 (val, hit_addr);
+ else
+ bfd_putl64 (val, hit_addr);
+ break;
+ }
+
+ return bfd_reloc_ok;
+}
diff --git a/bfd/elfxx-ia64.h b/bfd/elfxx-ia64.h
new file mode 100644
index 0000000..9f01315
--- /dev/null
+++ b/bfd/elfxx-ia64.h
@@ -0,0 +1,33 @@
+/* IA-64 support for 64-bit ELF
+ Copyright (C) 1998-2014 Free Software Foundation, Inc.
+ Contributed by David Mosberger-Tang <davidm@hpl.hp.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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+reloc_howto_type *ia64_elf_reloc_type_lookup (bfd *, bfd_reloc_code_real_type);
+
+reloc_howto_type *ia64_elf_reloc_name_lookup (bfd *, const char *);
+
+reloc_howto_type *ia64_elf_lookup_howto (unsigned int rtype);
+
+bfd_boolean ia64_elf_relax_br (bfd_byte *contents, bfd_vma off);
+void ia64_elf_relax_brl (bfd_byte *contents, bfd_vma off);
+void ia64_elf_relax_ldxmov (bfd_byte *contents, bfd_vma off);
+
+bfd_reloc_status_type ia64_elf_install_value (bfd_byte *hit_addr, bfd_vma v,
+ unsigned int r_type);
diff --git a/bfd/elfxx-mips.c b/bfd/elfxx-mips.c
new file mode 100644
index 0000000..a0cc26e
--- /dev/null
+++ b/bfd/elfxx-mips.c
@@ -0,0 +1,16088 @@
+/* MIPS-specific support for ELF
+ Copyright (C) 1993-2014 Free Software Foundation, Inc.
+
+ Most of the information added by Ian Lance Taylor, Cygnus Support,
+ <ian@cygnus.com>.
+ N32/64 ABI support added by Mark Mitchell, CodeSourcery, LLC.
+ <mark@codesourcery.com>
+ Traditional MIPS targets support added by Koundinya.K, Dansk Data
+ Elektronik & Operations Research Group. <kk@ddeorg.soft.net>
+
+ This file is part of BFD, the Binary File Descriptor library.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+
+/* This file handles functionality common to the different MIPS ABI's. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+#include "libiberty.h"
+#include "elf-bfd.h"
+#include "elfxx-mips.h"
+#include "elf/mips.h"
+#include "elf-vxworks.h"
+
+/* Get the ECOFF swapping routines. */
+#include "coff/sym.h"
+#include "coff/symconst.h"
+#include "coff/ecoff.h"
+#include "coff/mips.h"
+
+#include "hashtab.h"
+
+/* Types of TLS GOT entry. */
+enum mips_got_tls_type {
+ GOT_TLS_NONE,
+ GOT_TLS_GD,
+ GOT_TLS_LDM,
+ GOT_TLS_IE
+};
+
+/* This structure is used to hold information about one GOT entry.
+ There are four types of entry:
+
+ (1) an absolute address
+ requires: abfd == NULL
+ fields: d.address
+
+ (2) a SYMBOL + OFFSET address, where SYMBOL is local to an input bfd
+ requires: abfd != NULL, symndx >= 0, tls_type != GOT_TLS_LDM
+ fields: abfd, symndx, d.addend, tls_type
+
+ (3) a SYMBOL address, where SYMBOL is not local to an input bfd
+ requires: abfd != NULL, symndx == -1
+ fields: d.h, tls_type
+
+ (4) a TLS LDM slot
+ requires: abfd != NULL, symndx == 0, tls_type == GOT_TLS_LDM
+ fields: none; there's only one of these per GOT. */
+struct mips_got_entry
+{
+ /* One input bfd that needs the GOT entry. */
+ bfd *abfd;
+ /* The index of the symbol, as stored in the relocation r_info, if
+ we have a local symbol; -1 otherwise. */
+ long symndx;
+ union
+ {
+ /* If abfd == NULL, an address that must be stored in the got. */
+ bfd_vma address;
+ /* If abfd != NULL && symndx != -1, the addend of the relocation
+ that should be added to the symbol value. */
+ bfd_vma addend;
+ /* If abfd != NULL && symndx == -1, the hash table entry
+ corresponding to a symbol in the GOT. The symbol's entry
+ is in the local area if h->global_got_area is GGA_NONE,
+ otherwise it is in the global area. */
+ struct mips_elf_link_hash_entry *h;
+ } d;
+
+ /* The TLS type of this GOT entry. An LDM GOT entry will be a local
+ symbol entry with r_symndx == 0. */
+ unsigned char tls_type;
+
+ /* True if we have filled in the GOT contents for a TLS entry,
+ and created the associated relocations. */
+ unsigned char tls_initialized;
+
+ /* The offset from the beginning of the .got section to the entry
+ corresponding to this symbol+addend. If it's a global symbol
+ whose offset is yet to be decided, it's going to be -1. */
+ long gotidx;
+};
+
+/* This structure represents a GOT page reference from an input bfd.
+ Each instance represents a symbol + ADDEND, where the representation
+ of the symbol depends on whether it is local to the input bfd.
+ If it is, then SYMNDX >= 0, and the symbol has index SYMNDX in U.ABFD.
+ Otherwise, SYMNDX < 0 and U.H points to the symbol's hash table entry.
+
+ Page references with SYMNDX >= 0 always become page references
+ in the output. Page references with SYMNDX < 0 only become page
+ references if the symbol binds locally; in other cases, the page
+ reference decays to a global GOT reference. */
+struct mips_got_page_ref
+{
+ long symndx;
+ union
+ {
+ struct mips_elf_link_hash_entry *h;
+ bfd *abfd;
+ } u;
+ bfd_vma addend;
+};
+
+/* This structure describes a range of addends: [MIN_ADDEND, MAX_ADDEND].
+ The structures form a non-overlapping list that is sorted by increasing
+ MIN_ADDEND. */
+struct mips_got_page_range
+{
+ struct mips_got_page_range *next;
+ bfd_signed_vma min_addend;
+ bfd_signed_vma max_addend;
+};
+
+/* This structure describes the range of addends that are applied to page
+ relocations against a given section. */
+struct mips_got_page_entry
+{
+ /* The section that these entries are based on. */
+ asection *sec;
+ /* The ranges for this page entry. */
+ struct mips_got_page_range *ranges;
+ /* The maximum number of page entries needed for RANGES. */
+ bfd_vma num_pages;
+};
+
+/* This structure is used to hold .got information when linking. */
+
+struct mips_got_info
+{
+ /* The number of global .got entries. */
+ unsigned int global_gotno;
+ /* The number of global .got entries that are in the GGA_RELOC_ONLY area. */
+ unsigned int reloc_only_gotno;
+ /* The number of .got slots used for TLS. */
+ unsigned int tls_gotno;
+ /* The first unused TLS .got entry. Used only during
+ mips_elf_initialize_tls_index. */
+ unsigned int tls_assigned_gotno;
+ /* The number of local .got entries, eventually including page entries. */
+ unsigned int local_gotno;
+ /* The maximum number of page entries needed. */
+ unsigned int page_gotno;
+ /* The number of relocations needed for the GOT entries. */
+ unsigned int relocs;
+ /* The first unused local .got entry. */
+ unsigned int assigned_low_gotno;
+ /* The last unused local .got entry. */
+ unsigned int assigned_high_gotno;
+ /* A hash table holding members of the got. */
+ struct htab *got_entries;
+ /* A hash table holding mips_got_page_ref structures. */
+ struct htab *got_page_refs;
+ /* A hash table of mips_got_page_entry structures. */
+ struct htab *got_page_entries;
+ /* In multi-got links, a pointer to the next got (err, rather, most
+ of the time, it points to the previous got). */
+ struct mips_got_info *next;
+};
+
+/* Structure passed when merging bfds' gots. */
+
+struct mips_elf_got_per_bfd_arg
+{
+ /* The output bfd. */
+ bfd *obfd;
+ /* The link information. */
+ struct bfd_link_info *info;
+ /* A pointer to the primary got, i.e., the one that's going to get
+ the implicit relocations from DT_MIPS_LOCAL_GOTNO and
+ DT_MIPS_GOTSYM. */
+ struct mips_got_info *primary;
+ /* A non-primary got we're trying to merge with other input bfd's
+ gots. */
+ struct mips_got_info *current;
+ /* The maximum number of got entries that can be addressed with a
+ 16-bit offset. */
+ unsigned int max_count;
+ /* The maximum number of page entries needed by each got. */
+ unsigned int max_pages;
+ /* The total number of global entries which will live in the
+ primary got and be automatically relocated. This includes
+ those not referenced by the primary GOT but included in
+ the "master" GOT. */
+ unsigned int global_count;
+};
+
+/* A structure used to pass information to htab_traverse callbacks
+ when laying out the GOT. */
+
+struct mips_elf_traverse_got_arg
+{
+ struct bfd_link_info *info;
+ struct mips_got_info *g;
+ int value;
+};
+
+struct _mips_elf_section_data
+{
+ struct bfd_elf_section_data elf;
+ union
+ {
+ bfd_byte *tdata;
+ } u;
+};
+
+#define mips_elf_section_data(sec) \
+ ((struct _mips_elf_section_data *) elf_section_data (sec))
+
+#define is_mips_elf(bfd) \
+ (bfd_get_flavour (bfd) == bfd_target_elf_flavour \
+ && elf_tdata (bfd) != NULL \
+ && elf_object_id (bfd) == MIPS_ELF_DATA)
+
+/* The ABI says that every symbol used by dynamic relocations must have
+ a global GOT entry. Among other things, this provides the dynamic
+ linker with a free, directly-indexed cache. The GOT can therefore
+ contain symbols that are not referenced by GOT relocations themselves
+ (in other words, it may have symbols that are not referenced by things
+ like R_MIPS_GOT16 and R_MIPS_GOT_PAGE).
+
+ GOT relocations are less likely to overflow if we put the associated
+ GOT entries towards the beginning. We therefore divide the global
+ GOT entries into two areas: "normal" and "reloc-only". Entries in
+ the first area can be used for both dynamic relocations and GP-relative
+ accesses, while those in the "reloc-only" area are for dynamic
+ relocations only.
+
+ These GGA_* ("Global GOT Area") values are organised so that lower
+ values are more general than higher values. Also, non-GGA_NONE
+ values are ordered by the position of the area in the GOT. */
+#define GGA_NORMAL 0
+#define GGA_RELOC_ONLY 1
+#define GGA_NONE 2
+
+/* Information about a non-PIC interface to a PIC function. There are
+ two ways of creating these interfaces. The first is to add:
+
+ lui $25,%hi(func)
+ addiu $25,$25,%lo(func)
+
+ immediately before a PIC function "func". The second is to add:
+
+ lui $25,%hi(func)
+ j func
+ addiu $25,$25,%lo(func)
+
+ to a separate trampoline section.
+
+ Stubs of the first kind go in a new section immediately before the
+ target function. Stubs of the second kind go in a single section
+ pointed to by the hash table's "strampoline" field. */
+struct mips_elf_la25_stub {
+ /* The generated section that contains this stub. */
+ asection *stub_section;
+
+ /* The offset of the stub from the start of STUB_SECTION. */
+ bfd_vma offset;
+
+ /* One symbol for the original function. Its location is available
+ in H->root.root.u.def. */
+ struct mips_elf_link_hash_entry *h;
+};
+
+/* Macros for populating a mips_elf_la25_stub. */
+
+#define LA25_LUI(VAL) (0x3c190000 | (VAL)) /* lui t9,VAL */
+#define LA25_J(VAL) (0x08000000 | (((VAL) >> 2) & 0x3ffffff)) /* j VAL */
+#define LA25_ADDIU(VAL) (0x27390000 | (VAL)) /* addiu t9,t9,VAL */
+#define LA25_LUI_MICROMIPS(VAL) \
+ (0x41b90000 | (VAL)) /* lui t9,VAL */
+#define LA25_J_MICROMIPS(VAL) \
+ (0xd4000000 | (((VAL) >> 1) & 0x3ffffff)) /* j VAL */
+#define LA25_ADDIU_MICROMIPS(VAL) \
+ (0x33390000 | (VAL)) /* addiu t9,t9,VAL */
+
+/* This structure is passed to mips_elf_sort_hash_table_f when sorting
+ the dynamic symbols. */
+
+struct mips_elf_hash_sort_data
+{
+ /* The symbol in the global GOT with the lowest dynamic symbol table
+ index. */
+ struct elf_link_hash_entry *low;
+ /* The least dynamic symbol table index corresponding to a non-TLS
+ symbol with a GOT entry. */
+ long min_got_dynindx;
+ /* The greatest dynamic symbol table index corresponding to a symbol
+ with a GOT entry that is not referenced (e.g., a dynamic symbol
+ with dynamic relocations pointing to it from non-primary GOTs). */
+ long max_unref_got_dynindx;
+ /* The greatest dynamic symbol table index not corresponding to a
+ symbol without a GOT entry. */
+ long max_non_got_dynindx;
+};
+
+/* We make up to two PLT entries if needed, one for standard MIPS code
+ and one for compressed code, either a MIPS16 or microMIPS one. We
+ keep a separate record of traditional lazy-binding stubs, for easier
+ processing. */
+
+struct plt_entry
+{
+ /* Traditional SVR4 stub offset, or -1 if none. */
+ bfd_vma stub_offset;
+
+ /* Standard PLT entry offset, or -1 if none. */
+ bfd_vma mips_offset;
+
+ /* Compressed PLT entry offset, or -1 if none. */
+ bfd_vma comp_offset;
+
+ /* The corresponding .got.plt index, or -1 if none. */
+ bfd_vma gotplt_index;
+
+ /* Whether we need a standard PLT entry. */
+ unsigned int need_mips : 1;
+
+ /* Whether we need a compressed PLT entry. */
+ unsigned int need_comp : 1;
+};
+
+/* 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;
+
+ /* The la25 stub we have created for ths symbol, if any. */
+ struct mips_elf_la25_stub *la25_stub;
+
+ /* Number of R_MIPS_32, R_MIPS_REL32, or R_MIPS_64 relocs against
+ this symbol. */
+ unsigned int possibly_dynamic_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;
+
+ /* 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;
+
+ /* The highest GGA_* value that satisfies all references to this symbol. */
+ unsigned int global_got_area : 2;
+
+ /* True if all GOT relocations against this symbol are for calls. This is
+ a looser condition than no_fn_stub below, because there may be other
+ non-call non-GOT relocations against the symbol. */
+ unsigned int got_only_for_calls : 1;
+
+ /* True if one of the relocations described by possibly_dynamic_relocs
+ is against a readonly section. */
+ unsigned int readonly_reloc : 1;
+
+ /* True if there is a relocation against this symbol that must be
+ resolved by the static linker (in other words, if the relocation
+ cannot possibly be made dynamic). */
+ unsigned int has_static_relocs : 1;
+
+ /* True if we must not create a .MIPS.stubs entry for this symbol.
+ This is set, for example, if there are relocations related to
+ taking the function's address, i.e. any but R_MIPS_CALL*16 ones.
+ See "MIPS ABI Supplement, 3rd Edition", p. 4-20. */
+ unsigned int no_fn_stub : 1;
+
+ /* Whether we need the fn_stub; this is true if this symbol appears
+ in any relocs other than a 16 bit call. */
+ unsigned int need_fn_stub : 1;
+
+ /* True if this symbol is referenced by branch relocations from
+ any non-PIC input file. This is used to determine whether an
+ la25 stub is required. */
+ unsigned int has_nonpic_branches : 1;
+
+ /* Does this symbol need a traditional MIPS lazy-binding stub
+ (as opposed to a PLT entry)? */
+ unsigned int needs_lazy_stub : 1;
+
+ /* Does this symbol resolve to a PLT entry? */
+ unsigned int use_plt_entry : 1;
+};
+
+/* MIPS ELF linker hash table. */
+
+struct mips_elf_link_hash_table
+{
+ struct elf_link_hash_table root;
+
+ /* 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 IRIX5 and IRIX6. */
+ bfd_boolean use_rld_obj_head;
+
+ /* The __rld_map or __rld_obj_head symbol. */
+ struct elf_link_hash_entry *rld_symbol;
+
+ /* This is set if we see any mips16 stub sections. */
+ bfd_boolean mips16_stubs_seen;
+
+ /* True if we can generate copy relocs and PLTs. */
+ bfd_boolean use_plts_and_copy_relocs;
+
+ /* True if we can only use 32-bit microMIPS instructions. */
+ bfd_boolean insn32;
+
+ /* True if we're generating code for VxWorks. */
+ bfd_boolean is_vxworks;
+
+ /* True if we already reported the small-data section overflow. */
+ bfd_boolean small_data_overflow_reported;
+
+ /* Shortcuts to some dynamic sections, or NULL if they are not
+ being used. */
+ asection *srelbss;
+ asection *sdynbss;
+ asection *srelplt;
+ asection *srelplt2;
+ asection *sgotplt;
+ asection *splt;
+ asection *sstubs;
+ asection *sgot;
+
+ /* The master GOT information. */
+ struct mips_got_info *got_info;
+
+ /* The global symbol in the GOT with the lowest index in the dynamic
+ symbol table. */
+ struct elf_link_hash_entry *global_gotsym;
+
+ /* The size of the PLT header in bytes. */
+ bfd_vma plt_header_size;
+
+ /* The size of a standard PLT entry in bytes. */
+ bfd_vma plt_mips_entry_size;
+
+ /* The size of a compressed PLT entry in bytes. */
+ bfd_vma plt_comp_entry_size;
+
+ /* The offset of the next standard PLT entry to create. */
+ bfd_vma plt_mips_offset;
+
+ /* The offset of the next compressed PLT entry to create. */
+ bfd_vma plt_comp_offset;
+
+ /* The index of the next .got.plt entry to create. */
+ bfd_vma plt_got_index;
+
+ /* The number of functions that need a lazy-binding stub. */
+ bfd_vma lazy_stub_count;
+
+ /* The size of a function stub entry in bytes. */
+ bfd_vma function_stub_size;
+
+ /* The number of reserved entries at the beginning of the GOT. */
+ unsigned int reserved_gotno;
+
+ /* The section used for mips_elf_la25_stub trampolines.
+ See the comment above that structure for details. */
+ asection *strampoline;
+
+ /* A table of mips_elf_la25_stubs, indexed by (input_section, offset)
+ pairs. */
+ htab_t la25_stubs;
+
+ /* A function FN (NAME, IS, OS) that creates a new input section
+ called NAME and links it to output section OS. If IS is nonnull,
+ the new section should go immediately before it, otherwise it
+ should go at the (current) beginning of OS.
+
+ The function returns the new section on success, otherwise it
+ returns null. */
+ asection *(*add_stub_section) (const char *, asection *, asection *);
+
+ /* Small local sym cache. */
+ struct sym_cache sym_cache;
+
+ /* Is the PLT header compressed? */
+ unsigned int plt_header_is_comp : 1;
+};
+
+/* Get the MIPS ELF linker hash table from a link_info structure. */
+
+#define mips_elf_hash_table(p) \
+ (elf_hash_table_id ((struct elf_link_hash_table *) ((p)->hash)) \
+ == MIPS_ELF_DATA ? ((struct mips_elf_link_hash_table *) ((p)->hash)) : NULL)
+
+/* A structure used to communicate with htab_traverse callbacks. */
+struct mips_htab_traverse_info
+{
+ /* The usual link-wide information. */
+ struct bfd_link_info *info;
+ bfd *output_bfd;
+
+ /* Starts off FALSE and is set to TRUE if the link should be aborted. */
+ bfd_boolean error;
+};
+
+/* MIPS ELF private object data. */
+
+struct mips_elf_obj_tdata
+{
+ /* Generic ELF private object data. */
+ struct elf_obj_tdata root;
+
+ /* Input BFD providing Tag_GNU_MIPS_ABI_FP attribute for output. */
+ bfd *abi_fp_bfd;
+
+ /* Input BFD providing Tag_GNU_MIPS_ABI_MSA attribute for output. */
+ bfd *abi_msa_bfd;
+
+ /* The abiflags for this object. */
+ Elf_Internal_ABIFlags_v0 abiflags;
+ bfd_boolean abiflags_valid;
+
+ /* The GOT requirements of input bfds. */
+ struct mips_got_info *got;
+
+ /* Used by _bfd_mips_elf_find_nearest_line. 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;
+
+ /* An array of stub sections indexed by symbol number. */
+ asection **local_stubs;
+ asection **local_call_stubs;
+
+ /* The Irix 5 support uses two virtual sections, which represent
+ text/data symbols defined in dynamic objects. */
+ asymbol *elf_data_symbol;
+ asymbol *elf_text_symbol;
+ asection *elf_data_section;
+ asection *elf_text_section;
+};
+
+/* Get MIPS ELF private object data from BFD's tdata. */
+
+#define mips_elf_tdata(bfd) \
+ ((struct mips_elf_obj_tdata *) (bfd)->tdata.any)
+
+#define TLS_RELOC_P(r_type) \
+ (r_type == R_MIPS_TLS_DTPMOD32 \
+ || r_type == R_MIPS_TLS_DTPMOD64 \
+ || r_type == R_MIPS_TLS_DTPREL32 \
+ || r_type == R_MIPS_TLS_DTPREL64 \
+ || r_type == R_MIPS_TLS_GD \
+ || r_type == R_MIPS_TLS_LDM \
+ || r_type == R_MIPS_TLS_DTPREL_HI16 \
+ || r_type == R_MIPS_TLS_DTPREL_LO16 \
+ || r_type == R_MIPS_TLS_GOTTPREL \
+ || r_type == R_MIPS_TLS_TPREL32 \
+ || r_type == R_MIPS_TLS_TPREL64 \
+ || r_type == R_MIPS_TLS_TPREL_HI16 \
+ || r_type == R_MIPS_TLS_TPREL_LO16 \
+ || r_type == R_MIPS16_TLS_GD \
+ || r_type == R_MIPS16_TLS_LDM \
+ || r_type == R_MIPS16_TLS_DTPREL_HI16 \
+ || r_type == R_MIPS16_TLS_DTPREL_LO16 \
+ || r_type == R_MIPS16_TLS_GOTTPREL \
+ || r_type == R_MIPS16_TLS_TPREL_HI16 \
+ || r_type == R_MIPS16_TLS_TPREL_LO16 \
+ || r_type == R_MICROMIPS_TLS_GD \
+ || r_type == R_MICROMIPS_TLS_LDM \
+ || r_type == R_MICROMIPS_TLS_DTPREL_HI16 \
+ || r_type == R_MICROMIPS_TLS_DTPREL_LO16 \
+ || r_type == R_MICROMIPS_TLS_GOTTPREL \
+ || r_type == R_MICROMIPS_TLS_TPREL_HI16 \
+ || r_type == R_MICROMIPS_TLS_TPREL_LO16)
+
+/* 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;
+ bfd_boolean failed;
+};
+
+/* The names of the runtime procedure table symbols used on IRIX5. */
+
+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
+ IRIX5. */
+
+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)
+
+/* 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)
+
+static struct mips_got_entry *mips_elf_create_local_got_entry
+ (bfd *, struct bfd_link_info *, bfd *, bfd_vma, unsigned long,
+ struct mips_elf_link_hash_entry *, int);
+static bfd_boolean mips_elf_sort_hash_table_f
+ (struct mips_elf_link_hash_entry *, void *);
+static bfd_vma mips_elf_high
+ (bfd_vma);
+static bfd_boolean mips_elf_create_dynamic_relocation
+ (bfd *, struct bfd_link_info *, const Elf_Internal_Rela *,
+ struct mips_elf_link_hash_entry *, asection *, bfd_vma,
+ bfd_vma *, asection *);
+static bfd_vma mips_elf_adjust_gp
+ (bfd *, struct mips_got_info *, bfd *);
+
+/* This will be used when we sort the dynamic relocation records. */
+static bfd *reldyn_sorting_bfd;
+
+/* True if ABFD is for CPUs with load interlocking that include
+ non-MIPS1 CPUs and R3900. */
+#define LOAD_INTERLOCKS_P(abfd) \
+ ( ((elf_elfheader (abfd)->e_flags & EF_MIPS_ARCH) != E_MIPS_ARCH_1) \
+ || ((elf_elfheader (abfd)->e_flags & EF_MIPS_MACH) == E_MIPS_MACH_3900))
+
+/* True if ABFD is for CPUs that are faster if JAL is converted to BAL.
+ This should be safe for all architectures. We enable this predicate
+ for RM9000 for now. */
+#define JAL_TO_BAL_P(abfd) \
+ ((elf_elfheader (abfd)->e_flags & EF_MIPS_MACH) == E_MIPS_MACH_9000)
+
+/* True if ABFD is for CPUs that are faster if JALR is converted to BAL.
+ This should be safe for all architectures. We enable this predicate for
+ all CPUs. */
+#define JALR_TO_BAL_P(abfd) 1
+
+/* True if ABFD is for CPUs that are faster if JR is converted to B.
+ This should be safe for all architectures. We enable this predicate for
+ all CPUs. */
+#define JR_TO_B_P(abfd) 1
+
+/* True if ABFD is a PIC object. */
+#define PIC_OBJECT_P(abfd) \
+ ((elf_elfheader (abfd)->e_flags & EF_MIPS_PIC) != 0)
+
+/* Nonzero if ABFD is using the O32 ABI. */
+#define ABI_O32_P(abfd) \
+ ((elf_elfheader (abfd)->e_flags & EF_MIPS_ABI) == E_MIPS_ABI_O32)
+
+/* Nonzero if ABFD is using the N32 ABI. */
+#define ABI_N32_P(abfd) \
+ ((elf_elfheader (abfd)->e_flags & EF_MIPS_ABI2) != 0)
+
+/* Nonzero if ABFD is using the N64 ABI. */
+#define ABI_64_P(abfd) \
+ (get_elf_backend_data (abfd)->s->elfclass == ELFCLASS64)
+
+/* Nonzero if ABFD is using NewABI conventions. */
+#define NEWABI_P(abfd) (ABI_N32_P (abfd) || ABI_64_P (abfd))
+
+/* Nonzero if ABFD has microMIPS code. */
+#define MICROMIPS_P(abfd) \
+ ((elf_elfheader (abfd)->e_flags & EF_MIPS_ARCH_ASE_MICROMIPS) != 0)
+
+/* Nonzero if ABFD is MIPS R6. */
+#define MIPSR6_P(abfd) \
+ ((elf_elfheader (abfd)->e_flags & EF_MIPS_ARCH) == E_MIPS_ARCH_32R6 \
+ || (elf_elfheader (abfd)->e_flags & EF_MIPS_ARCH) == E_MIPS_ARCH_64R6)
+
+/* The IRIX compatibility level we are striving for. */
+#define IRIX_COMPAT(abfd) \
+ (get_elf_backend_data (abfd)->elf_backend_mips_irix_compat (abfd))
+
+/* Whether we are trying to be compatible with IRIX at all. */
+#define SGI_COMPAT(abfd) \
+ (IRIX_COMPAT (abfd) != ict_none)
+
+/* The name of the options section. */
+#define MIPS_ELF_OPTIONS_SECTION_NAME(abfd) \
+ (NEWABI_P (abfd) ? ".MIPS.options" : ".options")
+
+/* True if NAME is the recognized name of any SHT_MIPS_OPTIONS section.
+ Some IRIX system files do not use MIPS_ELF_OPTIONS_SECTION_NAME. */
+#define MIPS_ELF_OPTIONS_SECTION_NAME_P(NAME) \
+ (strcmp (NAME, ".MIPS.options") == 0 || strcmp (NAME, ".options") == 0)
+
+/* True if NAME is the recognized name of any SHT_MIPS_ABIFLAGS section. */
+#define MIPS_ELF_ABIFLAGS_SECTION_NAME_P(NAME) \
+ (strcmp (NAME, ".MIPS.abiflags") == 0)
+
+/* Whether the section is readonly. */
+#define MIPS_ELF_READONLY_SECTION(sec) \
+ ((sec->flags & (SEC_ALLOC | SEC_LOAD | SEC_READONLY)) \
+ == (SEC_ALLOC | SEC_LOAD | SEC_READONLY))
+
+/* The name of the stub section. */
+#define MIPS_ELF_STUB_SECTION_NAME(abfd) ".MIPS.stubs"
+
+/* The size of an external REL relocation. */
+#define MIPS_ELF_REL_SIZE(abfd) \
+ (get_elf_backend_data (abfd)->s->sizeof_rel)
+
+/* The size of an external RELA relocation. */
+#define MIPS_ELF_RELA_SIZE(abfd) \
+ (get_elf_backend_data (abfd)->s->sizeof_rela)
+
+/* The size of an external dynamic table entry. */
+#define MIPS_ELF_DYN_SIZE(abfd) \
+ (get_elf_backend_data (abfd)->s->sizeof_dyn)
+
+/* The size of a GOT entry. */
+#define MIPS_ELF_GOT_SIZE(abfd) \
+ (get_elf_backend_data (abfd)->s->arch_size / 8)
+
+/* The size of the .rld_map section. */
+#define MIPS_ELF_RLD_MAP_SIZE(abfd) \
+ (get_elf_backend_data (abfd)->s->arch_size / 8)
+
+/* The size of a symbol-table entry. */
+#define MIPS_ELF_SYM_SIZE(abfd) \
+ (get_elf_backend_data (abfd)->s->sizeof_sym)
+
+/* The default alignment for sections, as a power of two. */
+#define MIPS_ELF_LOG_FILE_ALIGN(abfd) \
+ (get_elf_backend_data (abfd)->s->log_file_align)
+
+/* Get word-sized data. */
+#define MIPS_ELF_GET_WORD(abfd, ptr) \
+ (ABI_64_P (abfd) ? bfd_get_64 (abfd, ptr) : bfd_get_32 (abfd, ptr))
+
+/* Put out word-sized data. */
+#define MIPS_ELF_PUT_WORD(abfd, val, ptr) \
+ (ABI_64_P (abfd) \
+ ? bfd_put_64 (abfd, val, ptr) \
+ : bfd_put_32 (abfd, val, ptr))
+
+/* The opcode for word-sized loads (LW or LD). */
+#define MIPS_ELF_LOAD_WORD(abfd) \
+ (ABI_64_P (abfd) ? 0xdc000000 : 0x8c000000)
+
+/* Add a dynamic symbol table-entry. */
+#define MIPS_ELF_ADD_DYNAMIC_ENTRY(info, tag, val) \
+ _bfd_elf_add_dynamic_entry (info, tag, val)
+
+#define MIPS_ELF_RTYPE_TO_HOWTO(abfd, rtype, rela) \
+ (get_elf_backend_data (abfd)->elf_backend_mips_rtype_to_howto (rtype, rela))
+
+/* The name of the dynamic relocation section. */
+#define MIPS_ELF_REL_DYN_NAME(INFO) \
+ (mips_elf_hash_table (INFO)->is_vxworks ? ".rela.dyn" : ".rel.dyn")
+
+/* 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)
+#define MINUS_TWO (((bfd_vma)0) - 2)
+
+/* The value to write into got[1] for SVR4 targets, to identify it is
+ a GNU object. The dynamic linker can then use got[1] to store the
+ module pointer. */
+#define MIPS_ELF_GNU_GOT1_MASK(abfd) \
+ ((bfd_vma) 1 << (ABI_64_P (abfd) ? 63 : 31))
+
+/* The offset of $gp from the beginning of the .got section. */
+#define ELF_MIPS_GP_OFFSET(INFO) \
+ (mips_elf_hash_table (INFO)->is_vxworks ? 0x0 : 0x7ff0)
+
+/* The maximum size of the GOT for it to be addressable using 16-bit
+ offsets from $gp. */
+#define MIPS_ELF_GOT_MAX_SIZE(INFO) (ELF_MIPS_GP_OFFSET (INFO) + 0x7fff)
+
+/* Instructions which appear in a stub. */
+#define STUB_LW(abfd) \
+ ((ABI_64_P (abfd) \
+ ? 0xdf998010 /* ld t9,0x8010(gp) */ \
+ : 0x8f998010)) /* lw t9,0x8010(gp) */
+#define STUB_MOVE(abfd) \
+ ((ABI_64_P (abfd) \
+ ? 0x03e0782d /* daddu t7,ra */ \
+ : 0x03e07821)) /* addu t7,ra */
+#define STUB_LUI(VAL) (0x3c180000 + (VAL)) /* lui t8,VAL */
+#define STUB_JALR 0x0320f809 /* jalr t9,ra */
+#define STUB_ORI(VAL) (0x37180000 + (VAL)) /* ori t8,t8,VAL */
+#define STUB_LI16U(VAL) (0x34180000 + (VAL)) /* ori t8,zero,VAL unsigned */
+#define STUB_LI16S(abfd, VAL) \
+ ((ABI_64_P (abfd) \
+ ? (0x64180000 + (VAL)) /* daddiu t8,zero,VAL sign extended */ \
+ : (0x24180000 + (VAL)))) /* addiu t8,zero,VAL sign extended */
+
+/* Likewise for the microMIPS ASE. */
+#define STUB_LW_MICROMIPS(abfd) \
+ (ABI_64_P (abfd) \
+ ? 0xdf3c8010 /* ld t9,0x8010(gp) */ \
+ : 0xff3c8010) /* lw t9,0x8010(gp) */
+#define STUB_MOVE_MICROMIPS 0x0dff /* move t7,ra */
+#define STUB_MOVE32_MICROMIPS(abfd) \
+ (ABI_64_P (abfd) \
+ ? 0x581f7950 /* daddu t7,ra,zero */ \
+ : 0x001f7950) /* addu t7,ra,zero */
+#define STUB_LUI_MICROMIPS(VAL) \
+ (0x41b80000 + (VAL)) /* lui t8,VAL */
+#define STUB_JALR_MICROMIPS 0x45d9 /* jalr t9 */
+#define STUB_JALR32_MICROMIPS 0x03f90f3c /* jalr ra,t9 */
+#define STUB_ORI_MICROMIPS(VAL) \
+ (0x53180000 + (VAL)) /* ori t8,t8,VAL */
+#define STUB_LI16U_MICROMIPS(VAL) \
+ (0x53000000 + (VAL)) /* ori t8,zero,VAL unsigned */
+#define STUB_LI16S_MICROMIPS(abfd, VAL) \
+ (ABI_64_P (abfd) \
+ ? 0x5f000000 + (VAL) /* daddiu t8,zero,VAL sign extended */ \
+ : 0x33000000 + (VAL)) /* addiu t8,zero,VAL sign extended */
+
+#define MIPS_FUNCTION_STUB_NORMAL_SIZE 16
+#define MIPS_FUNCTION_STUB_BIG_SIZE 20
+#define MICROMIPS_FUNCTION_STUB_NORMAL_SIZE 12
+#define MICROMIPS_FUNCTION_STUB_BIG_SIZE 16
+#define MICROMIPS_INSN32_FUNCTION_STUB_NORMAL_SIZE 16
+#define MICROMIPS_INSN32_FUNCTION_STUB_BIG_SIZE 20
+
+/* The name of the dynamic interpreter. This is put in the .interp
+ section. */
+
+#define ELF_DYNAMIC_INTERPRETER(abfd) \
+ (ABI_N32_P (abfd) ? "/usr/lib32/libc.so.1" \
+ : ABI_64_P (abfd) ? "/usr/lib64/libc.so.1" \
+ : "/usr/lib/libc.so.1")
+
+#ifdef BFD64
+#define MNAME(bfd,pre,pos) \
+ (ABI_64_P (bfd) ? CONCAT4 (pre,64,_,pos) : CONCAT4 (pre,32,_,pos))
+#define ELF_R_SYM(bfd, i) \
+ (ABI_64_P (bfd) ? ELF64_R_SYM (i) : ELF32_R_SYM (i))
+#define ELF_R_TYPE(bfd, i) \
+ (ABI_64_P (bfd) ? ELF64_MIPS_R_TYPE (i) : ELF32_R_TYPE (i))
+#define ELF_R_INFO(bfd, s, t) \
+ (ABI_64_P (bfd) ? ELF64_R_INFO (s, t) : ELF32_R_INFO (s, t))
+#else
+#define MNAME(bfd,pre,pos) CONCAT4 (pre,32,_,pos)
+#define ELF_R_SYM(bfd, i) \
+ (ELF32_R_SYM (i))
+#define ELF_R_TYPE(bfd, i) \
+ (ELF32_R_TYPE (i))
+#define ELF_R_INFO(bfd, s, t) \
+ (ELF32_R_INFO (s, t))
+#endif
+
+ /* 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."
+
+#define FN_STUB_P(name) CONST_STRNEQ (name, FN_STUB)
+#define CALL_STUB_P(name) CONST_STRNEQ (name, CALL_STUB)
+#define CALL_FP_STUB_P(name) CONST_STRNEQ (name, CALL_FP_STUB)
+
+/* The format of the first PLT entry in an O32 executable. */
+static const bfd_vma mips_o32_exec_plt0_entry[] =
+{
+ 0x3c1c0000, /* lui $28, %hi(&GOTPLT[0]) */
+ 0x8f990000, /* lw $25, %lo(&GOTPLT[0])($28) */
+ 0x279c0000, /* addiu $28, $28, %lo(&GOTPLT[0]) */
+ 0x031cc023, /* subu $24, $24, $28 */
+ 0x03e07821, /* move $15, $31 # 32-bit move (addu) */
+ 0x0018c082, /* srl $24, $24, 2 */
+ 0x0320f809, /* jalr $25 */
+ 0x2718fffe /* subu $24, $24, 2 */
+};
+
+/* The format of the first PLT entry in an N32 executable. Different
+ because gp ($28) is not available; we use t2 ($14) instead. */
+static const bfd_vma mips_n32_exec_plt0_entry[] =
+{
+ 0x3c0e0000, /* lui $14, %hi(&GOTPLT[0]) */
+ 0x8dd90000, /* lw $25, %lo(&GOTPLT[0])($14) */
+ 0x25ce0000, /* addiu $14, $14, %lo(&GOTPLT[0]) */
+ 0x030ec023, /* subu $24, $24, $14 */
+ 0x03e07821, /* move $15, $31 # 32-bit move (addu) */
+ 0x0018c082, /* srl $24, $24, 2 */
+ 0x0320f809, /* jalr $25 */
+ 0x2718fffe /* subu $24, $24, 2 */
+};
+
+/* The format of the first PLT entry in an N64 executable. Different
+ from N32 because of the increased size of GOT entries. */
+static const bfd_vma mips_n64_exec_plt0_entry[] =
+{
+ 0x3c0e0000, /* lui $14, %hi(&GOTPLT[0]) */
+ 0xddd90000, /* ld $25, %lo(&GOTPLT[0])($14) */
+ 0x25ce0000, /* addiu $14, $14, %lo(&GOTPLT[0]) */
+ 0x030ec023, /* subu $24, $24, $14 */
+ 0x03e0782d, /* move $15, $31 # 64-bit move (daddu) */
+ 0x0018c0c2, /* srl $24, $24, 3 */
+ 0x0320f809, /* jalr $25 */
+ 0x2718fffe /* subu $24, $24, 2 */
+};
+
+/* The format of the microMIPS first PLT entry in an O32 executable.
+ We rely on v0 ($2) rather than t8 ($24) to contain the address
+ of the GOTPLT entry handled, so this stub may only be used when
+ all the subsequent PLT entries are microMIPS code too.
+
+ The trailing NOP is for alignment and correct disassembly only. */
+static const bfd_vma micromips_o32_exec_plt0_entry[] =
+{
+ 0x7980, 0x0000, /* addiupc $3, (&GOTPLT[0]) - . */
+ 0xff23, 0x0000, /* lw $25, 0($3) */
+ 0x0535, /* subu $2, $2, $3 */
+ 0x2525, /* srl $2, $2, 2 */
+ 0x3302, 0xfffe, /* subu $24, $2, 2 */
+ 0x0dff, /* move $15, $31 */
+ 0x45f9, /* jalrs $25 */
+ 0x0f83, /* move $28, $3 */
+ 0x0c00 /* nop */
+};
+
+/* The format of the microMIPS first PLT entry in an O32 executable
+ in the insn32 mode. */
+static const bfd_vma micromips_insn32_o32_exec_plt0_entry[] =
+{
+ 0x41bc, 0x0000, /* lui $28, %hi(&GOTPLT[0]) */
+ 0xff3c, 0x0000, /* lw $25, %lo(&GOTPLT[0])($28) */
+ 0x339c, 0x0000, /* addiu $28, $28, %lo(&GOTPLT[0]) */
+ 0x0398, 0xc1d0, /* subu $24, $24, $28 */
+ 0x001f, 0x7950, /* move $15, $31 */
+ 0x0318, 0x1040, /* srl $24, $24, 2 */
+ 0x03f9, 0x0f3c, /* jalr $25 */
+ 0x3318, 0xfffe /* subu $24, $24, 2 */
+};
+
+/* The format of subsequent standard PLT entries. */
+static const bfd_vma mips_exec_plt_entry[] =
+{
+ 0x3c0f0000, /* lui $15, %hi(.got.plt entry) */
+ 0x01f90000, /* l[wd] $25, %lo(.got.plt entry)($15) */
+ 0x25f80000, /* addiu $24, $15, %lo(.got.plt entry) */
+ 0x03200008 /* jr $25 */
+};
+
+/* In the following PLT entry the JR and ADDIU instructions will
+ be swapped in _bfd_mips_elf_finish_dynamic_symbol because
+ LOAD_INTERLOCKS_P will be true for MIPS R6. */
+static const bfd_vma mipsr6_exec_plt_entry[] =
+{
+ 0x3c0f0000, /* lui $15, %hi(.got.plt entry) */
+ 0x01f90000, /* l[wd] $25, %lo(.got.plt entry)($15) */
+ 0x25f80000, /* addiu $24, $15, %lo(.got.plt entry) */
+ 0x03200009 /* jr $25 */
+};
+
+/* The format of subsequent MIPS16 o32 PLT entries. We use v0 ($2)
+ and v1 ($3) as temporaries because t8 ($24) and t9 ($25) are not
+ directly addressable. */
+static const bfd_vma mips16_o32_exec_plt_entry[] =
+{
+ 0xb203, /* lw $2, 12($pc) */
+ 0x9a60, /* lw $3, 0($2) */
+ 0x651a, /* move $24, $2 */
+ 0xeb00, /* jr $3 */
+ 0x653b, /* move $25, $3 */
+ 0x6500, /* nop */
+ 0x0000, 0x0000 /* .word (.got.plt entry) */
+};
+
+/* The format of subsequent microMIPS o32 PLT entries. We use v0 ($2)
+ as a temporary because t8 ($24) is not addressable with ADDIUPC. */
+static const bfd_vma micromips_o32_exec_plt_entry[] =
+{
+ 0x7900, 0x0000, /* addiupc $2, (.got.plt entry) - . */
+ 0xff22, 0x0000, /* lw $25, 0($2) */
+ 0x4599, /* jr $25 */
+ 0x0f02 /* move $24, $2 */
+};
+
+/* The format of subsequent microMIPS o32 PLT entries in the insn32 mode. */
+static const bfd_vma micromips_insn32_o32_exec_plt_entry[] =
+{
+ 0x41af, 0x0000, /* lui $15, %hi(.got.plt entry) */
+ 0xff2f, 0x0000, /* lw $25, %lo(.got.plt entry)($15) */
+ 0x0019, 0x0f3c, /* jr $25 */
+ 0x330f, 0x0000 /* addiu $24, $15, %lo(.got.plt entry) */
+};
+
+/* The format of the first PLT entry in a VxWorks executable. */
+static const bfd_vma mips_vxworks_exec_plt0_entry[] =
+{
+ 0x3c190000, /* lui t9, %hi(_GLOBAL_OFFSET_TABLE_) */
+ 0x27390000, /* addiu t9, t9, %lo(_GLOBAL_OFFSET_TABLE_) */
+ 0x8f390008, /* lw t9, 8(t9) */
+ 0x00000000, /* nop */
+ 0x03200008, /* jr t9 */
+ 0x00000000 /* nop */
+};
+
+/* The format of subsequent PLT entries. */
+static const bfd_vma mips_vxworks_exec_plt_entry[] =
+{
+ 0x10000000, /* b .PLT_resolver */
+ 0x24180000, /* li t8, <pltindex> */
+ 0x3c190000, /* lui t9, %hi(<.got.plt slot>) */
+ 0x27390000, /* addiu t9, t9, %lo(<.got.plt slot>) */
+ 0x8f390000, /* lw t9, 0(t9) */
+ 0x00000000, /* nop */
+ 0x03200008, /* jr t9 */
+ 0x00000000 /* nop */
+};
+
+/* The format of the first PLT entry in a VxWorks shared object. */
+static const bfd_vma mips_vxworks_shared_plt0_entry[] =
+{
+ 0x8f990008, /* lw t9, 8(gp) */
+ 0x00000000, /* nop */
+ 0x03200008, /* jr t9 */
+ 0x00000000, /* nop */
+ 0x00000000, /* nop */
+ 0x00000000 /* nop */
+};
+
+/* The format of subsequent PLT entries. */
+static const bfd_vma mips_vxworks_shared_plt_entry[] =
+{
+ 0x10000000, /* b .PLT_resolver */
+ 0x24180000 /* li t8, <pltindex> */
+};
+
+/* microMIPS 32-bit opcode helper installer. */
+
+static void
+bfd_put_micromips_32 (const bfd *abfd, bfd_vma opcode, bfd_byte *ptr)
+{
+ bfd_put_16 (abfd, (opcode >> 16) & 0xffff, ptr);
+ bfd_put_16 (abfd, opcode & 0xffff, ptr + 2);
+}
+
+/* microMIPS 32-bit opcode helper retriever. */
+
+static bfd_vma
+bfd_get_micromips_32 (const bfd *abfd, const bfd_byte *ptr)
+{
+ return (bfd_get_16 (abfd, ptr) << 16) | bfd_get_16 (abfd, ptr + 2);
+}
+
+/* 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, \
+ (bfd_boolean (*) (struct elf_link_hash_entry *, void *)) (func), \
+ (info)))
+
+/* Find the base offsets for thread-local storage in this object,
+ for GD/LD and IE/LE respectively. */
+
+#define TP_OFFSET 0x7000
+#define DTP_OFFSET 0x8000
+
+static bfd_vma
+dtprel_base (struct bfd_link_info *info)
+{
+ /* If tls_sec is NULL, we should have signalled an error already. */
+ if (elf_hash_table (info)->tls_sec == NULL)
+ return 0;
+ return elf_hash_table (info)->tls_sec->vma + DTP_OFFSET;
+}
+
+static bfd_vma
+tprel_base (struct bfd_link_info *info)
+{
+ /* If tls_sec is NULL, we should have signalled an error already. */
+ if (elf_hash_table (info)->tls_sec == NULL)
+ return 0;
+ return elf_hash_table (info)->tls_sec->vma + TP_OFFSET;
+}
+
+/* Create an entry in a MIPS ELF linker hash table. */
+
+static struct bfd_hash_entry *
+mips_elf_link_hash_newfunc (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 == NULL)
+ ret = bfd_hash_allocate (table, sizeof (struct mips_elf_link_hash_entry));
+ if (ret == 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 != 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->la25_stub = 0;
+ ret->possibly_dynamic_relocs = 0;
+ ret->fn_stub = NULL;
+ ret->call_stub = NULL;
+ ret->call_fp_stub = NULL;
+ ret->global_got_area = GGA_NONE;
+ ret->got_only_for_calls = TRUE;
+ ret->readonly_reloc = FALSE;
+ ret->has_static_relocs = FALSE;
+ ret->no_fn_stub = FALSE;
+ ret->need_fn_stub = FALSE;
+ ret->has_nonpic_branches = FALSE;
+ ret->needs_lazy_stub = FALSE;
+ ret->use_plt_entry = FALSE;
+ }
+
+ return (struct bfd_hash_entry *) ret;
+}
+
+/* Allocate MIPS ELF private object data. */
+
+bfd_boolean
+_bfd_mips_elf_mkobject (bfd *abfd)
+{
+ return bfd_elf_allocate_object (abfd, sizeof (struct mips_elf_obj_tdata),
+ MIPS_ELF_DATA);
+}
+
+bfd_boolean
+_bfd_mips_elf_new_section_hook (bfd *abfd, asection *sec)
+{
+ if (!sec->used_by_bfd)
+ {
+ struct _mips_elf_section_data *sdata;
+ bfd_size_type amt = sizeof (*sdata);
+
+ sdata = bfd_zalloc (abfd, amt);
+ if (sdata == NULL)
+ return FALSE;
+ sec->used_by_bfd = sdata;
+ }
+
+ return _bfd_elf_new_section_hook (abfd, sec);
+}
+
+/* Read ECOFF debugging information from a .mdebug section into a
+ ecoff_debug_info structure. */
+
+bfd_boolean
+_bfd_mips_elf_read_ecoff_info (bfd *abfd, asection *section,
+ struct ecoff_debug_info *debug)
+{
+ HDRR *symhdr;
+ const struct ecoff_debug_swap *swap;
+ char *ext_hdr;
+
+ swap = get_elf_backend_data (abfd)->elf_backend_ecoff_debug_swap;
+ memset (debug, 0, sizeof (*debug));
+
+ ext_hdr = bfd_malloc (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, 0,
+ swap->external_hdr_size))
+ 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 \
+ { \
+ bfd_size_type amt = (bfd_size_type) size * symhdr->count; \
+ debug->ptr = bfd_malloc (amt); \
+ if (debug->ptr == NULL) \
+ goto error_return; \
+ if (bfd_seek (abfd, symhdr->offset, SEEK_SET) != 0 \
+ || bfd_bread (debug->ptr, amt, abfd) != amt) \
+ goto error_return; \
+ }
+
+ READ (line, cbLineOffset, cbLine, sizeof (unsigned char), unsigned char *);
+ READ (external_dnr, cbDnOffset, idnMax, swap->external_dnr_size, void *);
+ READ (external_pdr, cbPdOffset, ipdMax, swap->external_pdr_size, void *);
+ READ (external_sym, cbSymOffset, isymMax, swap->external_sym_size, void *);
+ READ (external_opt, cbOptOffset, ioptMax, swap->external_opt_size, void *);
+ 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, void *);
+ READ (external_rfd, cbRfdOffset, crfd, swap->external_rfd_size, void *);
+ READ (external_ext, cbExtOffset, iextMax, swap->external_ext_size, void *);
+#undef READ
+
+ debug->fdr = 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;
+}
+
+/* Swap RPDR (runtime procedure table entry) for output. */
+
+static void
+ecoff_swap_rpdr_out (bfd *abfd, const RPDR *in, struct rpdr_ext *ex)
+{
+ H_PUT_S32 (abfd, in->adr, ex->p_adr);
+ H_PUT_32 (abfd, in->regmask, ex->p_regmask);
+ H_PUT_32 (abfd, in->regoffset, ex->p_regoffset);
+ H_PUT_32 (abfd, in->fregmask, ex->p_fregmask);
+ H_PUT_32 (abfd, in->fregoffset, ex->p_fregoffset);
+ H_PUT_32 (abfd, in->frameoffset, ex->p_frameoffset);
+
+ H_PUT_16 (abfd, in->framereg, ex->p_framereg);
+ H_PUT_16 (abfd, in->pcreg, ex->p_pcreg);
+
+ H_PUT_32 (abfd, in->irpss, ex->p_irpss);
+}
+
+/* Create a runtime procedure table from the .mdebug section. */
+
+static bfd_boolean
+mips_elf_create_procedure_table (void *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;
+ void *rtproc;
+ struct pdr_ext *epdr;
+ struct sym_ext *esym;
+ char *ss, **sv;
+ char *str;
+ bfd_size_type size;
+ bfd_size_type 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 = bfd_malloc (size * count);
+ if (epdr == NULL)
+ goto error_return;
+
+ if (! _bfd_ecoff_get_accumulated_pdr (handle, (bfd_byte *) epdr))
+ goto error_return;
+
+ size = sizeof (RPDR);
+ rp = rpdr = bfd_malloc (size * count);
+ if (rpdr == NULL)
+ goto error_return;
+
+ size = sizeof (char *);
+ sv = bfd_malloc (size * count);
+ if (sv == NULL)
+ goto error_return;
+
+ count = hdr->isymMax;
+ size = swap->external_sym_size;
+ esym = bfd_malloc (size * count);
+ if (esym == NULL)
+ goto error_return;
+
+ if (! _bfd_ecoff_get_accumulated_sym (handle, (bfd_byte *) esym))
+ goto error_return;
+
+ count = hdr->issMax;
+ ss = bfd_malloc (count);
+ if (ss == NULL)
+ goto error_return;
+ if (! _bfd_ecoff_get_accumulated_ss (handle, (bfd_byte *) ss))
+ goto error_return;
+
+ count = hdr->ipdMax;
+ for (i = 0; i < (unsigned long) count; i++, rp++)
+ {
+ (*swap->swap_pdr_in) (abfd, epdr + i, &pdr);
+ (*swap->swap_sym_in) (abfd, &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 = 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 = 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;
+ }
+ H_PUT_S32 (abfd, -1, (erp + count)->p_adr);
+
+ /* Set the size and contents of .rtproc section. */
+ s->size = size;
+ s->contents = rtproc;
+
+ /* Skip this section later on (I don't think this currently
+ matters, but someday it might). */
+ s->map_head.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;
+}
+
+/* We're going to create a stub for H. Create a symbol for the stub's
+ value and size, to help make the disassembly easier to read. */
+
+static bfd_boolean
+mips_elf_create_stub_symbol (struct bfd_link_info *info,
+ struct mips_elf_link_hash_entry *h,
+ const char *prefix, asection *s, bfd_vma value,
+ bfd_vma size)
+{
+ struct bfd_link_hash_entry *bh;
+ struct elf_link_hash_entry *elfh;
+ const char *name;
+
+ if (ELF_ST_IS_MICROMIPS (h->root.other))
+ value |= 1;
+
+ /* Create a new symbol. */
+ name = ACONCAT ((prefix, h->root.root.root.string, NULL));
+ bh = NULL;
+ if (!_bfd_generic_link_add_one_symbol (info, s->owner, name,
+ BSF_LOCAL, s, value, NULL,
+ TRUE, FALSE, &bh))
+ return FALSE;
+
+ /* Make it a local function. */
+ elfh = (struct elf_link_hash_entry *) bh;
+ elfh->type = ELF_ST_INFO (STB_LOCAL, STT_FUNC);
+ elfh->size = size;
+ elfh->forced_local = 1;
+ return TRUE;
+}
+
+/* We're about to redefine H. Create a symbol to represent H's
+ current value and size, to help make the disassembly easier
+ to read. */
+
+static bfd_boolean
+mips_elf_create_shadow_symbol (struct bfd_link_info *info,
+ struct mips_elf_link_hash_entry *h,
+ const char *prefix)
+{
+ struct bfd_link_hash_entry *bh;
+ struct elf_link_hash_entry *elfh;
+ const char *name;
+ asection *s;
+ bfd_vma value;
+
+ /* Read the symbol's value. */
+ BFD_ASSERT (h->root.root.type == bfd_link_hash_defined
+ || h->root.root.type == bfd_link_hash_defweak);
+ s = h->root.root.u.def.section;
+ value = h->root.root.u.def.value;
+
+ /* Create a new symbol. */
+ name = ACONCAT ((prefix, h->root.root.root.string, NULL));
+ bh = NULL;
+ if (!_bfd_generic_link_add_one_symbol (info, s->owner, name,
+ BSF_LOCAL, s, value, NULL,
+ TRUE, FALSE, &bh))
+ return FALSE;
+
+ /* Make it local and copy the other attributes from H. */
+ elfh = (struct elf_link_hash_entry *) bh;
+ elfh->type = ELF_ST_INFO (STB_LOCAL, ELF_ST_TYPE (h->root.type));
+ elfh->other = h->root.other;
+ elfh->size = h->root.size;
+ elfh->forced_local = 1;
+ return TRUE;
+}
+
+/* Return TRUE if relocations in SECTION can refer directly to a MIPS16
+ function rather than to a hard-float stub. */
+
+static bfd_boolean
+section_allows_mips16_refs_p (asection *section)
+{
+ const char *name;
+
+ name = bfd_get_section_name (section->owner, section);
+ return (FN_STUB_P (name)
+ || CALL_STUB_P (name)
+ || CALL_FP_STUB_P (name)
+ || strcmp (name, ".pdr") == 0);
+}
+
+/* [RELOCS, RELEND) are the relocations against SEC, which is a MIPS16
+ stub section of some kind. Return the R_SYMNDX of the target
+ function, or 0 if we can't decide which function that is. */
+
+static unsigned long
+mips16_stub_symndx (const struct elf_backend_data *bed,
+ asection *sec ATTRIBUTE_UNUSED,
+ const Elf_Internal_Rela *relocs,
+ const Elf_Internal_Rela *relend)
+{
+ int int_rels_per_ext_rel = bed->s->int_rels_per_ext_rel;
+ const Elf_Internal_Rela *rel;
+
+ /* Trust the first R_MIPS_NONE relocation, if any, but not a subsequent
+ one in a compound relocation. */
+ for (rel = relocs; rel < relend; rel += int_rels_per_ext_rel)
+ if (ELF_R_TYPE (sec->owner, rel->r_info) == R_MIPS_NONE)
+ return ELF_R_SYM (sec->owner, rel->r_info);
+
+ /* Otherwise trust the first relocation, whatever its kind. This is
+ the traditional behavior. */
+ if (relocs < relend)
+ return ELF_R_SYM (sec->owner, relocs->r_info);
+
+ return 0;
+}
+
+/* Check the mips16 stubs for a particular symbol, and see if we can
+ discard them. */
+
+static void
+mips_elf_check_mips16_stubs (struct bfd_link_info *info,
+ struct mips_elf_link_hash_entry *h)
+{
+ /* Dynamic symbols must use the standard call interface, in case other
+ objects try to call them. */
+ if (h->fn_stub != NULL
+ && h->root.dynindx != -1)
+ {
+ mips_elf_create_shadow_symbol (info, h, ".mips16.");
+ h->need_fn_stub = TRUE;
+ }
+
+ 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->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
+ && ELF_ST_IS_MIPS16 (h->root.other))
+ {
+ /* 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->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
+ && ELF_ST_IS_MIPS16 (h->root.other))
+ {
+ /* 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->size = 0;
+ h->call_fp_stub->flags &= ~SEC_RELOC;
+ h->call_fp_stub->reloc_count = 0;
+ h->call_fp_stub->flags |= SEC_EXCLUDE;
+ }
+}
+
+/* Hashtable callbacks for mips_elf_la25_stubs. */
+
+static hashval_t
+mips_elf_la25_stub_hash (const void *entry_)
+{
+ const struct mips_elf_la25_stub *entry;
+
+ entry = (struct mips_elf_la25_stub *) entry_;
+ return entry->h->root.root.u.def.section->id
+ + entry->h->root.root.u.def.value;
+}
+
+static int
+mips_elf_la25_stub_eq (const void *entry1_, const void *entry2_)
+{
+ const struct mips_elf_la25_stub *entry1, *entry2;
+
+ entry1 = (struct mips_elf_la25_stub *) entry1_;
+ entry2 = (struct mips_elf_la25_stub *) entry2_;
+ return ((entry1->h->root.root.u.def.section
+ == entry2->h->root.root.u.def.section)
+ && (entry1->h->root.root.u.def.value
+ == entry2->h->root.root.u.def.value));
+}
+
+/* Called by the linker to set up the la25 stub-creation code. FN is
+ the linker's implementation of add_stub_function. Return true on
+ success. */
+
+bfd_boolean
+_bfd_mips_elf_init_stubs (struct bfd_link_info *info,
+ asection *(*fn) (const char *, asection *,
+ asection *))
+{
+ struct mips_elf_link_hash_table *htab;
+
+ htab = mips_elf_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ htab->add_stub_section = fn;
+ htab->la25_stubs = htab_try_create (1, mips_elf_la25_stub_hash,
+ mips_elf_la25_stub_eq, NULL);
+ if (htab->la25_stubs == NULL)
+ return FALSE;
+
+ return TRUE;
+}
+
+/* Return true if H is a locally-defined PIC function, in the sense
+ that it or its fn_stub might need $25 to be valid on entry.
+ Note that MIPS16 functions set up $gp using PC-relative instructions,
+ so they themselves never need $25 to be valid. Only non-MIPS16
+ entry points are of interest here. */
+
+static bfd_boolean
+mips_elf_local_pic_function_p (struct mips_elf_link_hash_entry *h)
+{
+ return ((h->root.root.type == bfd_link_hash_defined
+ || h->root.root.type == bfd_link_hash_defweak)
+ && h->root.def_regular
+ && !bfd_is_abs_section (h->root.root.u.def.section)
+ && (!ELF_ST_IS_MIPS16 (h->root.other)
+ || (h->fn_stub && h->need_fn_stub))
+ && (PIC_OBJECT_P (h->root.root.u.def.section->owner)
+ || ELF_ST_IS_MIPS_PIC (h->root.other)));
+}
+
+/* Set *SEC to the input section that contains the target of STUB.
+ Return the offset of the target from the start of that section. */
+
+static bfd_vma
+mips_elf_get_la25_target (struct mips_elf_la25_stub *stub,
+ asection **sec)
+{
+ if (ELF_ST_IS_MIPS16 (stub->h->root.other))
+ {
+ BFD_ASSERT (stub->h->need_fn_stub);
+ *sec = stub->h->fn_stub;
+ return 0;
+ }
+ else
+ {
+ *sec = stub->h->root.root.u.def.section;
+ return stub->h->root.root.u.def.value;
+ }
+}
+
+/* STUB describes an la25 stub that we have decided to implement
+ by inserting an LUI/ADDIU pair before the target function.
+ Create the section and redirect the function symbol to it. */
+
+static bfd_boolean
+mips_elf_add_la25_intro (struct mips_elf_la25_stub *stub,
+ struct bfd_link_info *info)
+{
+ struct mips_elf_link_hash_table *htab;
+ char *name;
+ asection *s, *input_section;
+ unsigned int align;
+
+ htab = mips_elf_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ /* Create a unique name for the new section. */
+ name = bfd_malloc (11 + sizeof (".text.stub."));
+ if (name == NULL)
+ return FALSE;
+ sprintf (name, ".text.stub.%d", (int) htab_elements (htab->la25_stubs));
+
+ /* Create the section. */
+ mips_elf_get_la25_target (stub, &input_section);
+ s = htab->add_stub_section (name, input_section,
+ input_section->output_section);
+ if (s == NULL)
+ return FALSE;
+
+ /* Make sure that any padding goes before the stub. */
+ align = input_section->alignment_power;
+ if (!bfd_set_section_alignment (s->owner, s, align))
+ return FALSE;
+ if (align > 3)
+ s->size = (1 << align) - 8;
+
+ /* Create a symbol for the stub. */
+ mips_elf_create_stub_symbol (info, stub->h, ".pic.", s, s->size, 8);
+ stub->stub_section = s;
+ stub->offset = s->size;
+
+ /* Allocate room for it. */
+ s->size += 8;
+ return TRUE;
+}
+
+/* STUB describes an la25 stub that we have decided to implement
+ with a separate trampoline. Allocate room for it and redirect
+ the function symbol to it. */
+
+static bfd_boolean
+mips_elf_add_la25_trampoline (struct mips_elf_la25_stub *stub,
+ struct bfd_link_info *info)
+{
+ struct mips_elf_link_hash_table *htab;
+ asection *s;
+
+ htab = mips_elf_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ /* Create a trampoline section, if we haven't already. */
+ s = htab->strampoline;
+ if (s == NULL)
+ {
+ asection *input_section = stub->h->root.root.u.def.section;
+ s = htab->add_stub_section (".text", NULL,
+ input_section->output_section);
+ if (s == NULL || !bfd_set_section_alignment (s->owner, s, 4))
+ return FALSE;
+ htab->strampoline = s;
+ }
+
+ /* Create a symbol for the stub. */
+ mips_elf_create_stub_symbol (info, stub->h, ".pic.", s, s->size, 16);
+ stub->stub_section = s;
+ stub->offset = s->size;
+
+ /* Allocate room for it. */
+ s->size += 16;
+ return TRUE;
+}
+
+/* H describes a symbol that needs an la25 stub. Make sure that an
+ appropriate stub exists and point H at it. */
+
+static bfd_boolean
+mips_elf_add_la25_stub (struct bfd_link_info *info,
+ struct mips_elf_link_hash_entry *h)
+{
+ struct mips_elf_link_hash_table *htab;
+ struct mips_elf_la25_stub search, *stub;
+ bfd_boolean use_trampoline_p;
+ asection *s;
+ bfd_vma value;
+ void **slot;
+
+ /* Describe the stub we want. */
+ search.stub_section = NULL;
+ search.offset = 0;
+ search.h = h;
+
+ /* See if we've already created an equivalent stub. */
+ htab = mips_elf_hash_table (info);
+ if (htab == NULL)
+ return FALSE;
+
+ slot = htab_find_slot (htab->la25_stubs, &search, INSERT);
+ if (slot == NULL)
+ return FALSE;
+
+ stub = (struct mips_elf_la25_stub *) *slot;
+ if (stub != NULL)
+ {
+ /* We can reuse the existing stub. */
+ h->la25_stub = stub;
+ return TRUE;
+ }
+
+ /* Create a permanent copy of ENTRY and add it to the hash table. */
+ stub = bfd_malloc (sizeof (search));
+ if (stub == NULL)
+ return FALSE;
+ *stub = search;
+ *slot = stub;
+
+ /* Prefer to use LUI/ADDIU stubs if the function is at the beginning
+ of the section and if we would need no more than 2 nops. */
+ value = mips_elf_get_la25_target (stub, &s);
+ use_trampoline_p = (value != 0 || s->alignment_power > 4);
+
+ h->la25_stub = stub;
+ return (use_trampoline_p
+ ? mips_elf_add_la25_trampoline (stub, info)
+ : mips_elf_add_la25_intro (stub, info));
+}
+
+/* A mips_elf_link_hash_traverse callback that is called before sizing
+ sections. DATA points to a mips_htab_traverse_info structure. */
+
+static bfd_boolean
+mips_elf_check_symbols (struct mips_elf_link_hash_entry *h, void *data)
+{
+ struct mips_htab_traverse_info *hti;
+
+ hti = (struct mips_htab_traverse_info *) data;
+ if (!hti->info->relocatable)
+ mips_elf_check_mips16_stubs (hti->info, h);
+
+ if (mips_elf_local_pic_function_p (h))
+ {
+ /* PR 12845: If H is in a section that has been garbage
+ collected it will have its output section set to *ABS*. */
+ if (bfd_is_abs_section (h->root.root.u.def.section->output_section))
+ return TRUE;
+
+ /* H is a function that might need $25 to be valid on entry.
+ If we're creating a non-PIC relocatable object, mark H as
+ being PIC. If we're creating a non-relocatable object with
+ non-PIC branches and jumps to H, make sure that H has an la25
+ stub. */
+ if (hti->info->relocatable)
+ {
+ if (!PIC_OBJECT_P (hti->output_bfd))
+ h->root.other = ELF_ST_SET_MIPS_PIC (h->root.other);
+ }
+ else if (h->has_nonpic_branches && !mips_elf_add_la25_stub (hti->info, h))
+ {
+ hti->error = TRUE;
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+/* R_MIPS16_26 is used for the mips16 jal and jalx instructions.
+ Most mips16 instructions are 16 bits, but these instructions
+ are 32 bits.
+
+ The format of these instructions is:
+
+ +--------------+--------------------------------+
+ | JALX | X| Imm 20:16 | Imm 25:21 |
+ +--------------+--------------------------------+
+ | Immediate 15:0 |
+ +-----------------------------------------------+
+
+ JALX is the 5-bit value 00011. X is 0 for jal, 1 for jalx.
+ Note that the immediate value in the first word is swapped.
+
+ When producing a relocatable object file, R_MIPS16_26 is
+ handled mostly like R_MIPS_26. In particular, the addend is
+ stored as a straight 26-bit value in a 32-bit instruction.
+ (gas makes life simpler for itself by never adjusting a
+ R_MIPS16_26 reloc to be against a section, so the addend is
+ always zero). However, the 32 bit instruction is stored as 2
+ 16-bit values, rather than a single 32-bit value. In a
+ big-endian file, the result is the same; in a little-endian
+ file, the two 16-bit halves of the 32 bit value are swapped.
+ This is so that a disassembler can recognize the jal
+ instruction.
+
+ When doing a final link, R_MIPS16_26 is treated as a 32 bit
+ instruction stored as two 16-bit values. The addend A is the
+ contents of the targ26 field. The calculation is the same as
+ R_MIPS_26. When storing the calculated value, reorder the
+ immediate value as shown above, and don't forget to store the
+ value as two 16-bit values.
+
+ To put it in MIPS ABI terms, the relocation field is T-targ26-16,
+ defined as
+
+ big-endian:
+ +--------+----------------------+
+ | | |
+ | | targ26-16 |
+ |31 26|25 0|
+ +--------+----------------------+
+
+ little-endian:
+ +----------+------+-------------+
+ | | | |
+ | sub1 | | sub2 |
+ |0 9|10 15|16 31|
+ +----------+--------------------+
+ where targ26-16 is sub1 followed by sub2 (i.e., the addend field A is
+ ((sub1 << 16) | sub2)).
+
+ When producing a relocatable object file, the calculation is
+ (((A < 2) | ((P + 4) & 0xf0000000) + S) >> 2)
+ When producing a fully linked file, the calculation is
+ let R = (((A < 2) | ((P + 4) & 0xf0000000) + S) >> 2)
+ ((R & 0x1f0000) << 5) | ((R & 0x3e00000) >> 5) | (R & 0xffff)
+
+ The table below lists the other MIPS16 instruction relocations.
+ Each one is calculated in the same way as the non-MIPS16 relocation
+ given on the right, but using the extended MIPS16 layout of 16-bit
+ immediate fields:
+
+ R_MIPS16_GPREL R_MIPS_GPREL16
+ R_MIPS16_GOT16 R_MIPS_GOT16
+ R_MIPS16_CALL16 R_MIPS_CALL16
+ R_MIPS16_HI16 R_MIPS_HI16
+ R_MIPS16_LO16 R_MIPS_LO16
+
+ A typical instruction will have a format like this:
+
+ +--------------+--------------------------------+
+ | EXTEND | Imm 10:5 | Imm 15:11 |
+ +--------------+--------------------------------+
+ | Major | rx | ry | Imm 4:0 |
+ +--------------+--------------------------------+
+
+ EXTEND is the five bit value 11110. Major is the instruction
+ opcode.
+
+ All we need to do here is shuffle the bits appropriately.
+ As above, the two 16-bit halves must be swapped on a
+ little-endian system. */
+
+static inline bfd_boolean
+mips16_reloc_p (int r_type)
+{
+ switch (r_type)
+ {
+ case R_MIPS16_26:
+ case R_MIPS16_GPREL:
+ case R_MIPS16_GOT16:
+ case R_MIPS16_CALL16:
+ case R_MIPS16_HI16:
+ case R_MIPS16_LO16:
+ case R_MIPS16_TLS_GD:
+ case R_MIPS16_TLS_LDM:
+ case R_MIPS16_TLS_DTPREL_HI16:
+ case R_MIPS16_TLS_DTPREL_LO16:
+ case R_MIPS16_TLS_GOTTPREL:
+ case R_MIPS16_TLS_TPREL_HI16:
+ case R_MIPS16_TLS_TPREL_LO16:
+ return TRUE;
+
+ default:
+ return FALSE;
+ }
+}
+
+/* Check if a microMIPS reloc. */
+
+static inline bfd_boolean
+micromips_reloc_p (unsigned int r_type)
+{
+ return r_type >= R_MICROMIPS_min && r_type < R_MICROMIPS_max;
+}
+
+/* Similar to MIPS16, the two 16-bit halves in microMIPS must be swapped
+ on a little-endian system. This does not apply to R_MICROMIPS_PC7_S1
+ and R_MICROMIPS_PC10_S1 relocs that apply to 16-bit instructions. */
+
+static inline bfd_boolean
+micromips_reloc_shuffle_p (unsigned int r_type)
+{
+ return (micromips_reloc_p (r_type)
+ && r_type != R_MICROMIPS_PC7_S1
+ && r_type != R_MICROMIPS_PC10_S1);
+}
+
+static inline bfd_boolean
+got16_reloc_p (int r_type)
+{
+ return (r_type == R_MIPS_GOT16
+ || r_type == R_MIPS16_GOT16
+ || r_type == R_MICROMIPS_GOT16);
+}
+
+static inline bfd_boolean
+call16_reloc_p (int r_type)
+{
+ return (r_type == R_MIPS_CALL16
+ || r_type == R_MIPS16_CALL16
+ || r_type == R_MICROMIPS_CALL16);
+}
+
+static inline bfd_boolean
+got_disp_reloc_p (unsigned int r_type)
+{
+ return r_type == R_MIPS_GOT_DISP || r_type == R_MICROMIPS_GOT_DISP;
+}
+
+static inline bfd_boolean
+got_page_reloc_p (unsigned int r_type)
+{
+ return r_type == R_MIPS_GOT_PAGE || r_type == R_MICROMIPS_GOT_PAGE;
+}
+
+static inline bfd_boolean
+got_ofst_reloc_p (unsigned int r_type)
+{
+ return r_type == R_MIPS_GOT_OFST || r_type == R_MICROMIPS_GOT_OFST;
+}
+
+static inline bfd_boolean
+got_hi16_reloc_p (unsigned int r_type)
+{
+ return r_type == R_MIPS_GOT_HI16 || r_type == R_MICROMIPS_GOT_HI16;
+}
+
+static inline bfd_boolean
+got_lo16_reloc_p (unsigned int r_type)
+{
+ return r_type == R_MIPS_GOT_LO16 || r_type == R_MICROMIPS_GOT_LO16;
+}
+
+static inline bfd_boolean
+call_hi16_reloc_p (unsigned int r_type)
+{
+ return r_type == R_MIPS_CALL_HI16 || r_type == R_MICROMIPS_CALL_HI16;
+}
+
+static inline bfd_boolean
+call_lo16_reloc_p (unsigned int r_type)
+{
+ return r_type == R_MIPS_CALL_LO16 || r_type == R_MICROMIPS_CALL_LO16;
+}
+
+static inline bfd_boolean
+hi16_reloc_p (int r_type)
+{
+ return (r_type == R_MIPS_HI16
+ || r_type == R_MIPS16_HI16
+ || r_type == R_MICROMIPS_HI16
+ || r_type == R_MIPS_PCHI16);
+}
+
+static inline bfd_boolean
+lo16_reloc_p (int r_type)
+{
+ return (r_type == R_MIPS_LO16
+ || r_type == R_MIPS16_LO16
+ || r_type == R_MICROMIPS_LO16
+ || r_type == R_MIPS_PCLO16);
+}
+
+static inline bfd_boolean
+mips16_call_reloc_p (int r_type)
+{
+ return r_type == R_MIPS16_26 || r_type == R_MIPS16_CALL16;
+}
+
+static inline bfd_boolean
+jal_reloc_p (int r_type)
+{
+ return (r_type == R_MIPS_26
+ || r_type == R_MIPS16_26
+ || r_type == R_MICROMIPS_26_S1);
+}
+
+static inline bfd_boolean
+aligned_pcrel_reloc_p (int r_type)
+{
+ return (r_type == R_MIPS_PC18_S3
+ || r_type == R_MIPS_PC19_S2);
+}
+
+static inline bfd_boolean
+micromips_branch_reloc_p (int r_type)
+{
+ return (r_type == R_MICROMIPS_26_S1
+ || r_type == R_MICROMIPS_PC16_S1
+ || r_type == R_MICROMIPS_PC10_S1
+ || r_type == R_MICROMIPS_PC7_S1);
+}
+
+static inline bfd_boolean
+tls_gd_reloc_p (unsigned int r_type)
+{
+ return (r_type == R_MIPS_TLS_GD
+ || r_type == R_MIPS16_TLS_GD
+ || r_type == R_MICROMIPS_TLS_GD);
+}
+
+static inline bfd_boolean
+tls_ldm_reloc_p (unsigned int r_type)
+{
+ return (r_type == R_MIPS_TLS_LDM
+ || r_type == R_MIPS16_TLS_LDM
+ || r_type == R_MICROMIPS_TLS_LDM);
+}
+
+static inline bfd_boolean
+tls_gottprel_reloc_p (unsigned int r_type)
+{
+ return (r_type == R_MIPS_TLS_GOTTPREL
+ || r_type == R_MIPS16_TLS_GOTTPREL
+ || r_type == R_MICROMIPS_TLS_GOTTPREL);
+}
+
+void
+_bfd_mips_elf_reloc_unshuffle (bfd *abfd, int r_type,
+ bfd_boolean jal_shuffle, bfd_byte *data)
+{
+ bfd_vma first, second, val;
+
+ if (!mips16_reloc_p (r_type) && !micromips_reloc_shuffle_p (r_type))
+ return;
+
+ /* Pick up the first and second halfwords of the instruction. */
+ first = bfd_get_16 (abfd, data);
+ second = bfd_get_16 (abfd, data + 2);
+ if (micromips_reloc_p (r_type) || (r_type == R_MIPS16_26 && !jal_shuffle))
+ val = first << 16 | second;
+ else if (r_type != R_MIPS16_26)
+ val = (((first & 0xf800) << 16) | ((second & 0xffe0) << 11)
+ | ((first & 0x1f) << 11) | (first & 0x7e0) | (second & 0x1f));
+ else
+ val = (((first & 0xfc00) << 16) | ((first & 0x3e0) << 11)
+ | ((first & 0x1f) << 21) | second);
+ bfd_put_32 (abfd, val, data);
+}
+
+void
+_bfd_mips_elf_reloc_shuffle (bfd *abfd, int r_type,
+ bfd_boolean jal_shuffle, bfd_byte *data)
+{
+ bfd_vma first, second, val;
+
+ if (!mips16_reloc_p (r_type) && !micromips_reloc_shuffle_p (r_type))
+ return;
+
+ val = bfd_get_32 (abfd, data);
+ if (micromips_reloc_p (r_type) || (r_type == R_MIPS16_26 && !jal_shuffle))
+ {
+ second = val & 0xffff;
+ first = val >> 16;
+ }
+ else if (r_type != R_MIPS16_26)
+ {
+ second = ((val >> 11) & 0xffe0) | (val & 0x1f);
+ first = ((val >> 16) & 0xf800) | ((val >> 11) & 0x1f) | (val & 0x7e0);
+ }
+ else
+ {
+ second = val & 0xffff;
+ first = ((val >> 16) & 0xfc00) | ((val >> 11) & 0x3e0)
+ | ((val >> 21) & 0x1f);
+ }
+ bfd_put_16 (abfd, second, data + 2);
+ bfd_put_16 (abfd, first, data);
+}
+
+bfd_reloc_status_type
+_bfd_mips_elf_gprel16_with_gp (bfd *abfd, asymbol *symbol,
+ arelent *reloc_entry, asection *input_section,
+ bfd_boolean relocatable, void *data, bfd_vma gp)
+{
+ bfd_vma relocation;
+ bfd_signed_vma val;
+ bfd_reloc_status_type status;
+
+ 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 > bfd_get_section_limit (abfd, input_section))
+ return bfd_reloc_outofrange;
+
+ /* Set val to the offset into the section or symbol. */
+ val = reloc_entry->addend;
+
+ _bfd_mips_elf_sign_extend (val, 16);
+
+ /* Adjust val for the final section location and GP value. If we
+ are producing relocatable output, we don't want to do this for
+ an external symbol. */
+ if (! relocatable
+ || (symbol->flags & BSF_SECTION_SYM) != 0)
+ val += relocation - gp;
+
+ if (reloc_entry->howto->partial_inplace)
+ {
+ status = _bfd_relocate_contents (reloc_entry->howto, abfd, val,
+ (bfd_byte *) data
+ + reloc_entry->address);
+ if (status != bfd_reloc_ok)
+ return status;
+ }
+ else
+ reloc_entry->addend = val;
+
+ if (relocatable)
+ reloc_entry->address += input_section->output_offset;
+
+ return bfd_reloc_ok;
+}
+
+/* Used to store a REL high-part relocation such as R_MIPS_HI16 or
+ R_MIPS_GOT16. REL is the relocation, INPUT_SECTION is the section
+ that contains the relocation field and DATA points to the start of
+ INPUT_SECTION. */
+
+struct mips_hi16
+{
+ struct mips_hi16 *next;
+ bfd_byte *data;
+ asection *input_section;
+ arelent rel;
+};
+
+/* FIXME: This should not be a static variable. */
+
+static struct mips_hi16 *mips_hi16_list;
+
+/* A howto special_function for REL *HI16 relocations. We can only
+ calculate the correct value once we've seen the partnering
+ *LO16 relocation, so just save the information for later.
+
+ The ABI requires that the *LO16 immediately follow the *HI16.
+ However, as a GNU extension, we permit an arbitrary number of
+ *HI16s to be associated with a single *LO16. This significantly
+ simplies the relocation handling in gcc. */
+
+bfd_reloc_status_type
+_bfd_mips_elf_hi16_reloc (bfd *abfd ATTRIBUTE_UNUSED, arelent *reloc_entry,
+ asymbol *symbol ATTRIBUTE_UNUSED, void *data,
+ asection *input_section, bfd *output_bfd,
+ char **error_message ATTRIBUTE_UNUSED)
+{
+ struct mips_hi16 *n;
+
+ if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
+ return bfd_reloc_outofrange;
+
+ n = bfd_malloc (sizeof *n);
+ if (n == NULL)
+ return bfd_reloc_outofrange;
+
+ n->next = mips_hi16_list;
+ n->data = data;
+ n->input_section = input_section;
+ n->rel = *reloc_entry;
+ mips_hi16_list = n;
+
+ if (output_bfd != NULL)
+ reloc_entry->address += input_section->output_offset;
+
+ return bfd_reloc_ok;
+}
+
+/* A howto special_function for REL R_MIPS*_GOT16 relocations. This is just
+ like any other 16-bit relocation when applied to global symbols, but is
+ treated in the same as R_MIPS_HI16 when applied to local symbols. */
+
+bfd_reloc_status_type
+_bfd_mips_elf_got16_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
+ void *data, asection *input_section,
+ bfd *output_bfd, char **error_message)
+{
+ if ((symbol->flags & (BSF_GLOBAL | BSF_WEAK)) != 0
+ || bfd_is_und_section (bfd_get_section (symbol))
+ || bfd_is_com_section (bfd_get_section (symbol)))
+ /* The relocation is against a global symbol. */
+ return _bfd_mips_elf_generic_reloc (abfd, reloc_entry, symbol, data,
+ input_section, output_bfd,
+ error_message);
+
+ return _bfd_mips_elf_hi16_reloc (abfd, reloc_entry, symbol, data,
+ input_section, output_bfd, error_message);
+}
+
+/* A howto special_function for REL *LO16 relocations. The *LO16 itself
+ is a straightforward 16 bit inplace relocation, but we must deal with
+ any partnering high-part relocations as well. */
+
+bfd_reloc_status_type
+_bfd_mips_elf_lo16_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
+ void *data, asection *input_section,
+ bfd *output_bfd, char **error_message)
+{
+ bfd_vma vallo;
+ bfd_byte *location = (bfd_byte *) data + reloc_entry->address;
+
+ if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
+ return bfd_reloc_outofrange;
+
+ _bfd_mips_elf_reloc_unshuffle (abfd, reloc_entry->howto->type, FALSE,
+ location);
+ vallo = bfd_get_32 (abfd, location);
+ _bfd_mips_elf_reloc_shuffle (abfd, reloc_entry->howto->type, FALSE,
+ location);
+
+ while (mips_hi16_list != NULL)
+ {
+ bfd_reloc_status_type ret;
+ struct mips_hi16 *hi;
+
+ hi = mips_hi16_list;
+
+ /* R_MIPS*_GOT16 relocations are something of a special case. We
+ want to install the addend in the same way as for a R_MIPS*_HI16
+ relocation (with a rightshift of 16). However, since GOT16
+ relocations can also be used with global symbols, their howto
+ has a rightshift of 0. */
+ if (hi->rel.howto->type == R_MIPS_GOT16)
+ hi->rel.howto = MIPS_ELF_RTYPE_TO_HOWTO (abfd, R_MIPS_HI16, FALSE);
+ else if (hi->rel.howto->type == R_MIPS16_GOT16)
+ hi->rel.howto = MIPS_ELF_RTYPE_TO_HOWTO (abfd, R_MIPS16_HI16, FALSE);
+ else if (hi->rel.howto->type == R_MICROMIPS_GOT16)
+ hi->rel.howto = MIPS_ELF_RTYPE_TO_HOWTO (abfd, R_MICROMIPS_HI16, FALSE);
+
+ /* VALLO is a signed 16-bit number. Bias it by 0x8000 so that any
+ carry or borrow will induce a change of +1 or -1 in the high part. */
+ hi->rel.addend += (vallo + 0x8000) & 0xffff;
+
+ ret = _bfd_mips_elf_generic_reloc (abfd, &hi->rel, symbol, hi->data,
+ hi->input_section, output_bfd,
+ error_message);
+ if (ret != bfd_reloc_ok)
+ return ret;
+
+ mips_hi16_list = hi->next;
+ free (hi);
+ }
+
+ return _bfd_mips_elf_generic_reloc (abfd, reloc_entry, symbol, data,
+ input_section, output_bfd,
+ error_message);
+}
+
+/* A generic howto special_function. This calculates and installs the
+ relocation itself, thus avoiding the oft-discussed problems in
+ bfd_perform_relocation and bfd_install_relocation. */
+
+bfd_reloc_status_type
+_bfd_mips_elf_generic_reloc (bfd *abfd ATTRIBUTE_UNUSED, arelent *reloc_entry,
+ asymbol *symbol, void *data ATTRIBUTE_UNUSED,
+ asection *input_section, bfd *output_bfd,
+ char **error_message ATTRIBUTE_UNUSED)
+{
+ bfd_signed_vma val;
+ bfd_reloc_status_type status;
+ bfd_boolean relocatable;
+
+ relocatable = (output_bfd != NULL);
+
+ if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
+ return bfd_reloc_outofrange;
+
+ /* Build up the field adjustment in VAL. */
+ val = 0;
+ if (!relocatable || (symbol->flags & BSF_SECTION_SYM) != 0)
+ {
+ /* Either we're calculating the final field value or we have a
+ relocation against a section symbol. Add in the section's
+ offset or address. */
+ val += symbol->section->output_section->vma;
+ val += symbol->section->output_offset;
+ }
+
+ if (!relocatable)
+ {
+ /* We're calculating the final field value. Add in the symbol's value
+ and, if pc-relative, subtract the address of the field itself. */
+ val += symbol->value;
+ if (reloc_entry->howto->pc_relative)
+ {
+ val -= input_section->output_section->vma;
+ val -= input_section->output_offset;
+ val -= reloc_entry->address;
+ }
+ }
+
+ /* VAL is now the final adjustment. If we're keeping this relocation
+ in the output file, and if the relocation uses a separate addend,
+ we just need to add VAL to that addend. Otherwise we need to add
+ VAL to the relocation field itself. */
+ if (relocatable && !reloc_entry->howto->partial_inplace)
+ reloc_entry->addend += val;
+ else
+ {
+ bfd_byte *location = (bfd_byte *) data + reloc_entry->address;
+
+ /* Add in the separate addend, if any. */
+ val += reloc_entry->addend;
+
+ /* Add VAL to the relocation field. */
+ _bfd_mips_elf_reloc_unshuffle (abfd, reloc_entry->howto->type, FALSE,
+ location);
+ status = _bfd_relocate_contents (reloc_entry->howto, abfd, val,
+ location);
+ _bfd_mips_elf_reloc_shuffle (abfd, reloc_entry->howto->type, FALSE,
+ location);
+
+ if (status != bfd_reloc_ok)
+ return status;
+ }
+
+ if (relocatable)
+ reloc_entry->address += input_section->output_offset;
+
+ return bfd_reloc_ok;
+}
+
+/* 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 (bfd *abfd, const Elf32_External_gptab *ex,
+ Elf32_gptab *in)
+{
+ in->gt_entry.gt_g_value = H_GET_32 (abfd, ex->gt_entry.gt_g_value);
+ in->gt_entry.gt_bytes = H_GET_32 (abfd, ex->gt_entry.gt_bytes);
+}
+
+static void
+bfd_mips_elf32_swap_gptab_out (bfd *abfd, const Elf32_gptab *in,
+ Elf32_External_gptab *ex)
+{
+ H_PUT_32 (abfd, in->gt_entry.gt_g_value, ex->gt_entry.gt_g_value);
+ H_PUT_32 (abfd, in->gt_entry.gt_bytes, ex->gt_entry.gt_bytes);
+}
+
+static void
+bfd_elf32_swap_compact_rel_out (bfd *abfd, const Elf32_compact_rel *in,
+ Elf32_External_compact_rel *ex)
+{
+ H_PUT_32 (abfd, in->id1, ex->id1);
+ H_PUT_32 (abfd, in->num, ex->num);
+ H_PUT_32 (abfd, in->id2, ex->id2);
+ H_PUT_32 (abfd, in->offset, ex->offset);
+ H_PUT_32 (abfd, in->reserved0, ex->reserved0);
+ H_PUT_32 (abfd, in->reserved1, ex->reserved1);
+}
+
+static void
+bfd_elf32_swap_crinfo_out (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));
+ H_PUT_32 (abfd, l, ex->info);
+ H_PUT_32 (abfd, in->konst, ex->konst);
+ H_PUT_32 (abfd, in->vaddr, ex->vaddr);
+}
+
+/* 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 (bfd *abfd, const Elf32_External_RegInfo *ex,
+ Elf32_RegInfo *in)
+{
+ in->ri_gprmask = H_GET_32 (abfd, ex->ri_gprmask);
+ in->ri_cprmask[0] = H_GET_32 (abfd, ex->ri_cprmask[0]);
+ in->ri_cprmask[1] = H_GET_32 (abfd, ex->ri_cprmask[1]);
+ in->ri_cprmask[2] = H_GET_32 (abfd, ex->ri_cprmask[2]);
+ in->ri_cprmask[3] = H_GET_32 (abfd, ex->ri_cprmask[3]);
+ in->ri_gp_value = H_GET_32 (abfd, ex->ri_gp_value);
+}
+
+void
+bfd_mips_elf32_swap_reginfo_out (bfd *abfd, const Elf32_RegInfo *in,
+ Elf32_External_RegInfo *ex)
+{
+ H_PUT_32 (abfd, in->ri_gprmask, ex->ri_gprmask);
+ H_PUT_32 (abfd, in->ri_cprmask[0], ex->ri_cprmask[0]);
+ H_PUT_32 (abfd, in->ri_cprmask[1], ex->ri_cprmask[1]);
+ H_PUT_32 (abfd, in->ri_cprmask[2], ex->ri_cprmask[2]);
+ H_PUT_32 (abfd, in->ri_cprmask[3], ex->ri_cprmask[3]);
+ H_PUT_32 (abfd, in->ri_gp_value, 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 (bfd *abfd, const Elf64_External_RegInfo *ex,
+ Elf64_Internal_RegInfo *in)
+{
+ in->ri_gprmask = H_GET_32 (abfd, ex->ri_gprmask);
+ in->ri_pad = H_GET_32 (abfd, ex->ri_pad);
+ in->ri_cprmask[0] = H_GET_32 (abfd, ex->ri_cprmask[0]);
+ in->ri_cprmask[1] = H_GET_32 (abfd, ex->ri_cprmask[1]);
+ in->ri_cprmask[2] = H_GET_32 (abfd, ex->ri_cprmask[2]);
+ in->ri_cprmask[3] = H_GET_32 (abfd, ex->ri_cprmask[3]);
+ in->ri_gp_value = H_GET_64 (abfd, ex->ri_gp_value);
+}
+
+void
+bfd_mips_elf64_swap_reginfo_out (bfd *abfd, const Elf64_Internal_RegInfo *in,
+ Elf64_External_RegInfo *ex)
+{
+ H_PUT_32 (abfd, in->ri_gprmask, ex->ri_gprmask);
+ H_PUT_32 (abfd, in->ri_pad, ex->ri_pad);
+ H_PUT_32 (abfd, in->ri_cprmask[0], ex->ri_cprmask[0]);
+ H_PUT_32 (abfd, in->ri_cprmask[1], ex->ri_cprmask[1]);
+ H_PUT_32 (abfd, in->ri_cprmask[2], ex->ri_cprmask[2]);
+ H_PUT_32 (abfd, in->ri_cprmask[3], ex->ri_cprmask[3]);
+ H_PUT_64 (abfd, in->ri_gp_value, ex->ri_gp_value);
+}
+
+/* Swap in an options header. */
+
+void
+bfd_mips_elf_swap_options_in (bfd *abfd, const Elf_External_Options *ex,
+ Elf_Internal_Options *in)
+{
+ in->kind = H_GET_8 (abfd, ex->kind);
+ in->size = H_GET_8 (abfd, ex->size);
+ in->section = H_GET_16 (abfd, ex->section);
+ in->info = H_GET_32 (abfd, ex->info);
+}
+
+/* Swap out an options header. */
+
+void
+bfd_mips_elf_swap_options_out (bfd *abfd, const Elf_Internal_Options *in,
+ Elf_External_Options *ex)
+{
+ H_PUT_8 (abfd, in->kind, ex->kind);
+ H_PUT_8 (abfd, in->size, ex->size);
+ H_PUT_16 (abfd, in->section, ex->section);
+ H_PUT_32 (abfd, in->info, ex->info);
+}
+
+/* Swap in an abiflags structure. */
+
+void
+bfd_mips_elf_swap_abiflags_v0_in (bfd *abfd,
+ const Elf_External_ABIFlags_v0 *ex,
+ Elf_Internal_ABIFlags_v0 *in)
+{
+ in->version = H_GET_16 (abfd, ex->version);
+ in->isa_level = H_GET_8 (abfd, ex->isa_level);
+ in->isa_rev = H_GET_8 (abfd, ex->isa_rev);
+ in->gpr_size = H_GET_8 (abfd, ex->gpr_size);
+ in->cpr1_size = H_GET_8 (abfd, ex->cpr1_size);
+ in->cpr2_size = H_GET_8 (abfd, ex->cpr2_size);
+ in->fp_abi = H_GET_8 (abfd, ex->fp_abi);
+ in->isa_ext = H_GET_32 (abfd, ex->isa_ext);
+ in->ases = H_GET_32 (abfd, ex->ases);
+ in->flags1 = H_GET_32 (abfd, ex->flags1);
+ in->flags2 = H_GET_32 (abfd, ex->flags2);
+}
+
+/* Swap out an abiflags structure. */
+
+void
+bfd_mips_elf_swap_abiflags_v0_out (bfd *abfd,
+ const Elf_Internal_ABIFlags_v0 *in,
+ Elf_External_ABIFlags_v0 *ex)
+{
+ H_PUT_16 (abfd, in->version, ex->version);
+ H_PUT_8 (abfd, in->isa_level, ex->isa_level);
+ H_PUT_8 (abfd, in->isa_rev, ex->isa_rev);
+ H_PUT_8 (abfd, in->gpr_size, ex->gpr_size);
+ H_PUT_8 (abfd, in->cpr1_size, ex->cpr1_size);
+ H_PUT_8 (abfd, in->cpr2_size, ex->cpr2_size);
+ H_PUT_8 (abfd, in->fp_abi, ex->fp_abi);
+ H_PUT_32 (abfd, in->isa_ext, ex->isa_ext);
+ H_PUT_32 (abfd, in->ases, ex->ases);
+ H_PUT_32 (abfd, in->flags1, ex->flags1);
+ H_PUT_32 (abfd, in->flags2, ex->flags2);
+}
+
+/* This function is called via qsort() to sort the dynamic relocation
+ entries by increasing r_symndx value. */
+
+static int
+sort_dynamic_relocs (const void *arg1, const void *arg2)
+{
+ Elf_Internal_Rela int_reloc1;
+ Elf_Internal_Rela int_reloc2;
+ int diff;
+
+ bfd_elf32_swap_reloc_in (reldyn_sorting_bfd, arg1, &int_reloc1);
+ bfd_elf32_swap_reloc_in (reldyn_sorting_bfd, arg2, &int_reloc2);
+
+ diff = ELF32_R_SYM (int_reloc1.r_info) - ELF32_R_SYM (int_reloc2.r_info);
+ if (diff != 0)
+ return diff;
+
+ if (int_reloc1.r_offset < int_reloc2.r_offset)
+ return -1;
+ if (int_reloc1.r_offset > int_reloc2.r_offset)
+ return 1;
+ return 0;
+}
+
+/* Like sort_dynamic_relocs, but used for elf64 relocations. */
+
+static int
+sort_dynamic_relocs_64 (const void *arg1 ATTRIBUTE_UNUSED,
+ const void *arg2 ATTRIBUTE_UNUSED)
+{
+#ifdef BFD64
+ Elf_Internal_Rela int_reloc1[3];
+ Elf_Internal_Rela int_reloc2[3];
+
+ (*get_elf_backend_data (reldyn_sorting_bfd)->s->swap_reloc_in)
+ (reldyn_sorting_bfd, arg1, int_reloc1);
+ (*get_elf_backend_data (reldyn_sorting_bfd)->s->swap_reloc_in)
+ (reldyn_sorting_bfd, arg2, int_reloc2);
+
+ if (ELF64_R_SYM (int_reloc1[0].r_info) < ELF64_R_SYM (int_reloc2[0].r_info))
+ return -1;
+ if (ELF64_R_SYM (int_reloc1[0].r_info) > ELF64_R_SYM (int_reloc2[0].r_info))
+ return 1;
+
+ if (int_reloc1[0].r_offset < int_reloc2[0].r_offset)
+ return -1;
+ if (int_reloc1[0].r_offset > int_reloc2[0].r_offset)
+ return 1;
+ return 0;
+#else
+ abort ();
+#endif
+}
+
+
+/* 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 bfd_boolean
+mips_elf_output_extsym (struct mips_elf_link_hash_entry *h, void *data)
+{
+ struct extsym_info *einfo = data;
+ bfd_boolean strip;
+ asection *sec, *output_section;
+
+ if (h->root.indx == -2)
+ strip = FALSE;
+ else if ((h->root.def_dynamic
+ || h->root.ref_dynamic
+ || h->root.type == bfd_link_hash_new)
+ && !h->root.def_regular
+ && !h->root.ref_regular)
+ 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_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 && ! NEWABI_P (einfo->abfd))
+ {
+ 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
+ {
+ struct mips_elf_link_hash_entry *hd = h;
+
+ while (hd->root.root.type == bfd_link_hash_indirect)
+ hd = (struct mips_elf_link_hash_entry *)h->root.root.u.i.link;
+
+ if (hd->needs_lazy_stub)
+ {
+ BFD_ASSERT (hd->root.plt.plist != NULL);
+ BFD_ASSERT (hd->root.plt.plist->stub_offset != MINUS_ONE);
+ /* Set type and value for a symbol with a function stub. */
+ h->esym.asym.st = stProc;
+ sec = hd->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 = (hd->root.plt.plist->stub_offset
+ + sec->output_offset
+ + output_section->vma);
+ else
+ h->esym.asym.value = 0;
+ }
+ }
+ }
+
+ 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;
+}
+
+/* A comparison routine used to sort .gptab entries. */
+
+static int
+gptab_compare (const void *p1, const void *p2)
+{
+ const Elf32_gptab *a1 = p1;
+ const Elf32_gptab *a2 = p2;
+
+ return a1->gt_entry.gt_g_value - a2->gt_entry.gt_g_value;
+}
+
+/* Functions to manage the got entry hash table. */
+
+/* Use all 64 bits of a bfd_vma for the computation of a 32-bit
+ hash number. */
+
+static INLINE hashval_t
+mips_elf_hash_bfd_vma (bfd_vma addr)
+{
+#ifdef BFD64
+ return addr + (addr >> 32);
+#else
+ return addr;
+#endif
+}
+
+static hashval_t
+mips_elf_got_entry_hash (const void *entry_)
+{
+ const struct mips_got_entry *entry = (struct mips_got_entry *)entry_;
+
+ return (entry->symndx
+ + ((entry->tls_type == GOT_TLS_LDM) << 18)
+ + (entry->tls_type == GOT_TLS_LDM ? 0
+ : !entry->abfd ? mips_elf_hash_bfd_vma (entry->d.address)
+ : entry->symndx >= 0 ? (entry->abfd->id
+ + mips_elf_hash_bfd_vma (entry->d.addend))
+ : entry->d.h->root.root.root.hash));
+}
+
+static int
+mips_elf_got_entry_eq (const void *entry1, const void *entry2)
+{
+ const struct mips_got_entry *e1 = (struct mips_got_entry *)entry1;
+ const struct mips_got_entry *e2 = (struct mips_got_entry *)entry2;
+
+ return (e1->symndx == e2->symndx
+ && e1->tls_type == e2->tls_type
+ && (e1->tls_type == GOT_TLS_LDM ? TRUE
+ : !e1->abfd ? !e2->abfd && e1->d.address == e2->d.address
+ : e1->symndx >= 0 ? (e1->abfd == e2->abfd
+ && e1->d.addend == e2->d.addend)
+ : e2->abfd && e1->d.h == e2->d.h));
+}
+
+static hashval_t
+mips_got_page_ref_hash (const void *ref_)
+{
+ const struct mips_got_page_ref *ref;
+
+ ref = (const struct mips_got_page_ref *) ref_;
+ return ((ref->symndx >= 0
+ ? (hashval_t) (ref->u.abfd->id + ref->symndx)
+ : ref->u.h->root.root.root.hash)
+ + mips_elf_hash_bfd_vma (ref->addend));
+}
+
+static int
+mips_got_page_ref_eq (const void *ref1_, const void *ref2_)
+{
+ const struct mips_got_page_ref *ref1, *ref2;
+
+ ref1 = (const struct mips_got_page_ref *) ref1_;
+ ref2 = (const struct mips_got_page_ref *) ref2_;
+ return (ref1->symndx == ref2->symndx
+ && (ref1->symndx < 0
+ ? ref1->u.h == ref2->u.h
+ : ref1->u.abfd == ref2->u.abfd)
+ && ref1->addend == ref2->addend);
+}
+
+static hashval_t
+mips_got_page_entry_hash (const void *entry_)
+{
+ const struct mips_got_page_entry *entry;
+
+ entry = (const struct mips_got_page_entry *) entry_;
+ return entry->sec->id;
+}
+
+static int
+mips_got_page_entry_eq (const void *entry1_, const void *entry2_)
+{
+ const struct mips_got_page_entry *entry1, *entry2;
+
+ entry1 = (const struct mips_got_page_entry *) entry1_;
+ entry2 = (const struct mips_got_page_entry *) entry2_;
+ return entry1->sec == entry2->sec;
+}
+
+/* Create and return a new mips_got_info structure. */
+
+static struct mips_got_info *
+mips_elf_create_got_info (bfd *abfd)
+{
+ struct mips_got_info *g;
+
+ g = bfd_zalloc (abfd, sizeof (struct mips_got_info));
+ if (g == NULL)
+ return NULL;
+
+ g->got_entries = htab_try_create (1, mips_elf_got_entry_hash,
+ mips_elf_got_entry_eq, NULL);
+ if (g->got_entries == NULL)
+ return NULL;
+
+ g->got_page_refs = htab_try_create (1, mips_got_page_ref_hash,
+ mips_got_page_ref_eq, NULL);
+ if (g->got_page_refs == NULL)
+ return NULL;
+
+ return g;
+}
+
+/* Return the GOT info for input bfd ABFD, trying to create a new one if
+ CREATE_P and if ABFD doesn't already have a GOT. */
+
+static struct mips_got_info *
+mips_elf_bfd_got (bfd *abfd, bfd_boolean create_p)
+{
+ struct mips_elf_obj_tdata *tdata;
+
+ if (!is_mips_elf (abfd))
+ return NULL;
+
+ tdata = mips_elf_tdata (abfd);
+ if (!tdata->got && create_p)
+ tdata->got = mips_elf_create_got_info (abfd);
+ return tdata->got;
+}
+
+/* Record that ABFD should use output GOT G. */
+
+static void
+mips_elf_replace_bfd_got (bfd *abfd, struct mips_got_info *g)
+{
+ struct mips_elf_obj_tdata *tdata;
+
+ BFD_ASSERT (is_mips_elf (abfd));
+ tdata = mips_elf_tdata (abfd);
+ if (tdata->got)
+ {
+ /* The GOT structure itself and the hash table entries are
+ allocated to a bfd, but the hash tables aren't. */
+ htab_delete (tdata->got->got_entries);
+ htab_delete (tdata->got->got_page_refs);
+ if (tdata->got->got_page_entries)
+ htab_delete (tdata->got->got_page_entries);
+ }
+ tdata->got = g;
+}
+
+/* Return the dynamic relocation section. If it doesn't exist, try to
+ create a new it if CREATE_P, otherwise return NULL. Also return NULL
+ if creation fails. */
+
+static asection *
+mips_elf_rel_dyn_section (struct bfd_link_info *info, bfd_boolean create_p)
+{
+ const char *dname;
+ asection *sreloc;
+ bfd *dynobj;
+
+ dname = MIPS_ELF_REL_DYN_NAME (info);
+ dynobj = elf_hash_table (info)->dynobj;
+ sreloc = bfd_get_linker_section (dynobj, dname);
+ if (sreloc == NULL && create_p)
+ {
+ sreloc = bfd_make_section_anyway_with_flags (dynobj, dname,
+ (SEC_ALLOC
+ | SEC_LOAD
+ | SEC_HAS_CONTENTS
+ | SEC_IN_MEMORY
+ | SEC_LINKER_CREATED
+ | SEC_READONLY));
+ if (sreloc == NULL
+ || ! bfd_set_section_alignment (dynobj, sreloc,
+ MIPS_ELF_LOG_FILE_ALIGN (dynobj)))
+ return NULL;
+ }
+ return sreloc;
+}
+
+/* Return the GOT_TLS_* type required by relocation type R_TYPE. */
+
+static int
+mips_elf_reloc_tls_type (unsigned int r_type)
+{
+ if (tls_gd_reloc_p (r_type))
+ return GOT_TLS_GD;
+
+ if (tls_ldm_reloc_p (r_type))
+ return GOT_TLS_LDM;
+
+ if (tls_gottprel_reloc_p (r_type))
+ return GOT_TLS_IE;
+
+ return GOT_TLS_NONE;
+}
+
+/* Return the number of GOT slots needed for GOT TLS type TYPE. */
+
+static int
+mips_tls_got_entries (unsigned int type)
+{
+ switch (type)
+ {
+ case GOT_TLS_GD:
+ case GOT_TLS_LDM:
+ return 2;
+
+ case GOT_TLS_IE:
+ return 1;
+
+ case GOT_TLS_NONE:
+ return 0;
+ }
+ abort ();
+}
+
+/* Count the number of relocations needed for a TLS GOT entry, with
+ access types from TLS_TYPE, and symbol H (or a local symbol if H
+ is NULL). */
+
+static int
+mips_tls_got_relocs (struct bfd_link_info *info, unsigned char tls_type,
+ struct elf_link_hash_entry *h)
+{
+ int indx = 0;
+ bfd_boolean need_relocs = FALSE;
+ bfd_boolean dyn = elf_hash_table (info)->dynamic_sections_created;
+
+ if (h && WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h)
+ && (!info->shared || !SYMBOL_REFERENCES_LOCAL (info, h)))
+ indx = h->dynindx;
+
+ if ((info->shared || indx != 0)
+ && (h == NULL
+ || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
+ || h->root.type != bfd_link_hash_undefweak))
+ need_relocs = TRUE;
+
+ if (!need_relocs)
+ return 0;
+
+ switch (tls_type)
+ {
+ case GOT_TLS_GD:
+ return indx != 0 ? 2 : 1;
+
+ case GOT_TLS_IE:
+ return 1;
+
+ case GOT_TLS_LDM:
+ return info->shared ? 1 : 0;
+
+ default:
+ return 0;
+ }
+}
+
+/* Add the number of GOT entries and TLS relocations required by ENTRY
+ to G. */
+
+static void
+mips_elf_count_got_entry (struct bfd_link_info *info,
+ struct mips_got_info *g,
+ struct mips_got_entry *entry)
+{
+ if (entry->tls_type)
+ {
+ g->tls_gotno += mips_tls_got_entries (entry->tls_type);
+ g->relocs += mips_tls_got_relocs (info, entry->tls_type,
+ entry->symndx < 0
+ ? &entry->d.h->root : NULL);
+ }
+ else if (entry->symndx >= 0 || entry->d.h->global_got_area == GGA_NONE)
+ g->local_gotno += 1;
+ else
+ g->global_gotno += 1;
+}
+
+/* Output a simple dynamic relocation into SRELOC. */
+
+static void
+mips_elf_output_dynamic_relocation (bfd *output_bfd,
+ asection *sreloc,
+ unsigned long reloc_index,
+ unsigned long indx,
+ int r_type,
+ bfd_vma offset)
+{
+ Elf_Internal_Rela rel[3];
+
+ memset (rel, 0, sizeof (rel));
+
+ rel[0].r_info = ELF_R_INFO (output_bfd, indx, r_type);
+ rel[0].r_offset = rel[1].r_offset = rel[2].r_offset = offset;
+
+ if (ABI_64_P (output_bfd))
+ {
+ (*get_elf_backend_data (output_bfd)->s->swap_reloc_out)
+ (output_bfd, &rel[0],
+ (sreloc->contents
+ + reloc_index * sizeof (Elf64_Mips_External_Rel)));
+ }
+ else
+ bfd_elf32_swap_reloc_out
+ (output_bfd, &rel[0],
+ (sreloc->contents
+ + reloc_index * sizeof (Elf32_External_Rel)));
+}
+
+/* Initialize a set of TLS GOT entries for one symbol. */
+
+static void
+mips_elf_initialize_tls_slots (bfd *abfd, struct bfd_link_info *info,
+ struct mips_got_entry *entry,
+ struct mips_elf_link_hash_entry *h,
+ bfd_vma value)
+{
+ struct mips_elf_link_hash_table *htab;
+ int indx;
+ asection *sreloc, *sgot;
+ bfd_vma got_offset, got_offset2;
+ bfd_boolean need_relocs = FALSE;
+
+ htab = mips_elf_hash_table (info);
+ if (htab == NULL)
+ return;
+
+ sgot = htab->sgot;
+
+ indx = 0;
+ if (h != NULL)
+ {
+ bfd_boolean dyn = elf_hash_table (info)->dynamic_sections_created;
+
+ if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, &h->root)
+ && (!info->shared || !SYMBOL_REFERENCES_LOCAL (info, &h->root)))
+ indx = h->root.dynindx;
+ }
+
+ if (entry->tls_initialized)
+ return;
+
+ if ((info->shared || indx != 0)
+ && (h == NULL
+ || ELF_ST_VISIBILITY (h->root.other) == STV_DEFAULT
+ || h->root.type != bfd_link_hash_undefweak))
+ need_relocs = TRUE;
+
+ /* MINUS_ONE means the symbol is not defined in this object. It may not
+ be defined at all; assume that the value doesn't matter in that
+ case. Otherwise complain if we would use the value. */
+ BFD_ASSERT (value != MINUS_ONE || (indx != 0 && need_relocs)
+ || h->root.root.type == bfd_link_hash_undefweak);
+
+ /* Emit necessary relocations. */
+ sreloc = mips_elf_rel_dyn_section (info, FALSE);
+ got_offset = entry->gotidx;
+
+ switch (entry->tls_type)
+ {
+ case GOT_TLS_GD:
+ /* General Dynamic. */
+ got_offset2 = got_offset + MIPS_ELF_GOT_SIZE (abfd);
+
+ if (need_relocs)
+ {
+ mips_elf_output_dynamic_relocation
+ (abfd, sreloc, sreloc->reloc_count++, indx,
+ ABI_64_P (abfd) ? R_MIPS_TLS_DTPMOD64 : R_MIPS_TLS_DTPMOD32,
+ sgot->output_offset + sgot->output_section->vma + got_offset);
+
+ if (indx)
+ mips_elf_output_dynamic_relocation
+ (abfd, sreloc, sreloc->reloc_count++, indx,
+ ABI_64_P (abfd) ? R_MIPS_TLS_DTPREL64 : R_MIPS_TLS_DTPREL32,
+ sgot->output_offset + sgot->output_section->vma + got_offset2);
+ else
+ MIPS_ELF_PUT_WORD (abfd, value - dtprel_base (info),
+ sgot->contents + got_offset2);
+ }
+ else
+ {
+ MIPS_ELF_PUT_WORD (abfd, 1,
+ sgot->contents + got_offset);
+ MIPS_ELF_PUT_WORD (abfd, value - dtprel_base (info),
+ sgot->contents + got_offset2);
+ }
+ break;
+
+ case GOT_TLS_IE:
+ /* Initial Exec model. */
+ if (need_relocs)
+ {
+ if (indx == 0)
+ MIPS_ELF_PUT_WORD (abfd, value - elf_hash_table (info)->tls_sec->vma,
+ sgot->contents + got_offset);
+ else
+ MIPS_ELF_PUT_WORD (abfd, 0,
+ sgot->contents + got_offset);
+
+ mips_elf_output_dynamic_relocation
+ (abfd, sreloc, sreloc->reloc_count++, indx,
+ ABI_64_P (abfd) ? R_MIPS_TLS_TPREL64 : R_MIPS_TLS_TPREL32,
+ sgot->output_offset + sgot->output_section->vma + got_offset);
+ }
+ else
+ MIPS_ELF_PUT_WORD (abfd, value - tprel_base (info),
+ sgot->contents + got_offset);
+ break;
+
+ case GOT_TLS_LDM:
+ /* The initial offset is zero, and the LD offsets will include the
+ bias by DTP_OFFSET. */
+ MIPS_ELF_PUT_WORD (abfd, 0,
+ sgot->contents + got_offset
+ + MIPS_ELF_GOT_SIZE (abfd));
+
+ if (!info->shared)
+ MIPS_ELF_PUT_WORD (abfd, 1,
+ sgot->contents + got_offset);
+ else
+ mips_elf_output_dynamic_relocation
+ (abfd, sreloc, sreloc->reloc_count++, indx,
+ ABI_64_P (abfd) ? R_MIPS_TLS_DTPMOD64 : R_MIPS_TLS_DTPMOD32,
+ sgot->output_offset + sgot->output_section->vma + got_offset);
+ break;
+
+ default:
+ abort ();
+ }
+
+ entry->tls_initialized = TRUE;
+}
+
+/* Return the offset from _GLOBAL_OFFSET_TABLE_ of the .got.plt entry
+ for global symbol H. .got.plt comes before the GOT, so the offset
+ will be negative. */
+
+static bfd_vma
+mips_elf_gotplt_index (struct bfd_link_info *info,
+ struct elf_link_hash_entry *h)
+{
+ bfd_vma got_address, got_value;
+ struct mips_elf_link_hash_table *htab;
+
+ htab = mips_elf_hash_table (info);
+ BFD_ASSERT (htab != NULL);
+
+ BFD_ASSERT (h->plt.plist != NULL);
+ BFD_ASSERT (h->plt.plist->gotplt_index != MINUS_ONE);
+
+ /* Calculate the address of the associated .got.plt entry. */
+ got_address = (htab->sgotplt->output_section->vma
+ + htab->sgotplt->output_offset
+ + (h->plt.plist->gotplt_index
+ * MIPS_ELF_GOT_SIZE (info->output_bfd)));
+
+ /* Calculate the value of _GLOBAL_OFFSET_TABLE_. */
+ got_value = (htab->root.hgot->root.u.def.section->output_section->vma
+ + htab->root.hgot->root.u.def.section->output_offset
+ + htab->root.hgot->root.u.def.value);
+
+ return got_address - got_value;
+}
+
+/* Return the GOT offset for address VALUE. If there is not yet a GOT
+ entry for this value, create one. If R_SYMNDX refers to a TLS symbol,
+ create a TLS GOT entry instead. Return -1 if no satisfactory GOT
+ offset can be found. */
+
+static bfd_vma
+mips_elf_local_got_index (bfd *abfd, bfd *ibfd, struct bfd_link_info *info,
+ bfd_vma value, unsigned long r_symndx,
+ struct mips_elf_link_hash_entry *h, int r_type)
+{
+ struct mips_elf_link_hash_table *htab;
+ struct mips_got_entry *entry;
+
+ htab = mips_elf_hash_table (info);
+ BFD_ASSERT (htab != NULL);
+
+ entry = mips_elf_create_local_got_entry (abfd, info, ibfd, value,
+ r_symndx, h, r_type);
+ if (!entry)
+ return MINUS_ONE;
+
+ if (entry->tls_type)
+ mips_elf_initialize_tls_slots (abfd, info, entry, h, value);
+ return entry->gotidx;
+}
+
+/* Return the GOT index of global symbol H in the primary GOT. */
+
+static bfd_vma
+mips_elf_primary_global_got_index (bfd *obfd, struct bfd_link_info *info,
+ struct elf_link_hash_entry *h)
+{
+ struct mips_elf_link_hash_table *htab;
+ long global_got_dynindx;
+ struct mips_got_info *g;
+ bfd_vma got_index;
+
+ htab = mips_elf_hash_table (info);
+ BFD_ASSERT (htab != NULL);
+
+ global_got_dynindx = 0;
+ if (htab->global_gotsym != NULL)
+ global_got_dynindx = htab->global_gotsym->dynindx;
+
+ /* Once we determine the global GOT entry with the lowest dynamic
+ symbol table index, we must put all dynamic symbols with greater
+ indices into the primary GOT. That makes it easy to calculate the
+ GOT offset. */
+ BFD_ASSERT (h->dynindx >= global_got_dynindx);
+ g = mips_elf_bfd_got (obfd, FALSE);
+ got_index = ((h->dynindx - global_got_dynindx + g->local_gotno)
+ * MIPS_ELF_GOT_SIZE (obfd));
+ BFD_ASSERT (got_index < htab->sgot->size);
+
+ return got_index;
+}
+
+/* Return the GOT index for the global symbol indicated by H, which is
+ referenced by a relocation of type R_TYPE in IBFD. */
+
+static bfd_vma
+mips_elf_global_got_index (bfd *obfd, struct bfd_link_info *info, bfd *ibfd,
+ struct elf_link_hash_entry *h, int r_type)
+{
+ struct mips_elf_link_hash_table *htab;
+ struct mips_got_info *g;
+ struct mips_got_entry lookup, *entry;
+ bfd_vma gotidx;
+
+ htab = mips_elf_hash_table (info);
+ BFD_ASSERT (htab != NULL);
+
+ g = mips_elf_bfd_got (ibfd, FALSE);
+ BFD_ASSERT (g);
+
+ lookup.tls_type = mips_elf_reloc_tls_type (r_type);
+ if (!lookup.tls_type && g == mips_elf_bfd_got (obfd, FALSE))
+ return mips_elf_primary_global_got_index (obfd, info, h);
+
+ lookup.abfd = ibfd;
+ lookup.symndx = -1;
+ lookup.d.h = (struct mips_elf_link_hash_entry *) h;
+ entry = htab_find (g->got_entries, &lookup);
+ BFD_ASSERT (entry);
+
+ gotidx = entry->gotidx;
+ BFD_ASSERT (gotidx > 0 && gotidx < htab->sgot->size);
+
+ if (lookup.tls_type)
+ {
+ bfd_vma value = MINUS_ONE;
+
+ if ((h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak)
+ && h->root.u.def.section->output_section)
+ value = (h->root.u.def.value
+ + h->root.u.def.section->output_offset
+ + h->root.u.def.section->output_section->vma);
+
+ mips_elf_initialize_tls_slots (obfd, info, entry, lookup.d.h, value);
+ }
+ return gotidx;
+}
+
+/* Find a GOT page entry that points to within 32KB of VALUE. These
+ entries are supposed to be placed at small offsets in the GOT, i.e.,
+ within 32KB of GP. Return the index of the GOT entry, or -1 if no
+ entry could be created. If OFFSETP is nonnull, use it to return the
+ offset of the GOT entry from VALUE. */
+
+static bfd_vma
+mips_elf_got_page (bfd *abfd, bfd *ibfd, struct bfd_link_info *info,
+ bfd_vma value, bfd_vma *offsetp)
+{
+ bfd_vma page, got_index;
+ struct mips_got_entry *entry;
+
+ page = (value + 0x8000) & ~(bfd_vma) 0xffff;
+ entry = mips_elf_create_local_got_entry (abfd, info, ibfd, page, 0,
+ NULL, R_MIPS_GOT_PAGE);
+
+ if (!entry)
+ return MINUS_ONE;
+
+ got_index = entry->gotidx;
+
+ if (offsetp)
+ *offsetp = value - entry->d.address;
+
+ return got_index;
+}
+
+/* Find a local GOT entry for an R_MIPS*_GOT16 relocation against VALUE.
+ EXTERNAL is true if the relocation was originally against a global
+ symbol that binds locally. */
+
+static bfd_vma
+mips_elf_got16_entry (bfd *abfd, bfd *ibfd, struct bfd_link_info *info,
+ bfd_vma value, bfd_boolean external)
+{
+ struct mips_got_entry *entry;
+
+ /* GOT16 relocations against local symbols are followed by a LO16
+ relocation; those against global symbols are not. Thus if the
+ symbol was originally local, the GOT16 relocation should load the
+ equivalent of %hi(VALUE), otherwise it should load VALUE itself. */
+ if (! external)
+ value = mips_elf_high (value) << 16;
+
+ /* It doesn't matter whether the original relocation was R_MIPS_GOT16,
+ R_MIPS16_GOT16, R_MIPS_CALL16, etc. The format of the entry is the
+ same in all cases. */
+ entry = mips_elf_create_local_got_entry (abfd, info, ibfd, value, 0,
+ NULL, R_MIPS_GOT16);
+ if (entry)
+ return entry->gotidx;
+ else
+ return MINUS_ONE;
+}
+
+/* Returns the offset for the entry at the INDEXth position
+ in the GOT. */
+
+static bfd_vma
+mips_elf_got_offset_from_index (struct bfd_link_info *info, bfd *output_bfd,
+ bfd *input_bfd, bfd_vma got_index)
+{
+ struct mips_elf_link_hash_table *htab;
+ asection *sgot;
+ bfd_vma gp;
+
+ htab = mips_elf_hash_table (info);
+ BFD_ASSERT (htab != NULL);
+
+ sgot = htab->sgot;
+ gp = _bfd_get_gp_value (output_bfd)
+ + mips_elf_adjust_gp (output_bfd, htab->got_info, input_bfd);
+
+ return sgot->output_section->vma + sgot->output_offset + got_index - gp;
+}
+
+/* Create and return a local GOT entry for VALUE, which was calculated
+ from a symbol belonging to INPUT_SECTON. Return NULL if it could not
+ be created. If R_SYMNDX refers to a TLS symbol, create a TLS entry
+ instead. */
+
+static struct mips_got_entry *
+mips_elf_create_local_got_entry (bfd *abfd, struct bfd_link_info *info,
+ bfd *ibfd, bfd_vma value,
+ unsigned long r_symndx,
+ struct mips_elf_link_hash_entry *h,
+ int r_type)
+{
+ struct mips_got_entry lookup, *entry;
+ void **loc;
+ struct mips_got_info *g;
+ struct mips_elf_link_hash_table *htab;
+ bfd_vma gotidx;
+
+ htab = mips_elf_hash_table (info);
+ BFD_ASSERT (htab != NULL);
+
+ g = mips_elf_bfd_got (ibfd, FALSE);
+ if (g == NULL)
+ {
+ g = mips_elf_bfd_got (abfd, FALSE);
+ BFD_ASSERT (g != NULL);
+ }
+
+ /* This function shouldn't be called for symbols that live in the global
+ area of the GOT. */
+ BFD_ASSERT (h == NULL || h->global_got_area == GGA_NONE);
+
+ lookup.tls_type = mips_elf_reloc_tls_type (r_type);
+ if (lookup.tls_type)
+ {
+ lookup.abfd = ibfd;
+ if (tls_ldm_reloc_p (r_type))
+ {
+ lookup.symndx = 0;
+ lookup.d.addend = 0;
+ }
+ else if (h == NULL)
+ {
+ lookup.symndx = r_symndx;
+ lookup.d.addend = 0;
+ }
+ else
+ {
+ lookup.symndx = -1;
+ lookup.d.h = h;
+ }
+
+ entry = (struct mips_got_entry *) htab_find (g->got_entries, &lookup);
+ BFD_ASSERT (entry);
+
+ gotidx = entry->gotidx;
+ BFD_ASSERT (gotidx > 0 && gotidx < htab->sgot->size);
+
+ return entry;
+ }
+
+ lookup.abfd = NULL;
+ lookup.symndx = -1;
+ lookup.d.address = value;
+ loc = htab_find_slot (g->got_entries, &lookup, INSERT);
+ if (!loc)
+ return NULL;
+
+ entry = (struct mips_got_entry *) *loc;
+ if (entry)
+ return entry;
+
+ if (g->assigned_low_gotno > g->assigned_high_gotno)
+ {
+ /* We didn't allocate enough space in the GOT. */
+ (*_bfd_error_handler)
+ (_("not enough GOT space for local GOT entries"));
+ bfd_set_error (bfd_error_bad_value);
+ return NULL;
+ }
+
+ entry = (struct mips_got_entry *) bfd_alloc (abfd, sizeof (*entry));
+ if (!entry)
+ return NULL;
+
+ if (got16_reloc_p (r_type)
+ || call16_reloc_p (r_type)
+ || got_page_reloc_p (r_type)
+ || got_disp_reloc_p (r_type))
+ lookup.gotidx = MIPS_ELF_GOT_SIZE (abfd) * g->assigned_low_gotno++;
+ else
+ lookup.gotidx = MIPS_ELF_GOT_SIZE (abfd) * g->assigned_high_gotno--;
+
+ *entry = lookup;
+ *loc = entry;
+
+ MIPS_ELF_PUT_WORD (abfd, value, htab->sgot->contents + entry->gotidx);
+
+ /* These GOT entries need a dynamic relocation on VxWorks. */
+ if (htab->is_vxworks)
+ {
+ Elf_Internal_Rela outrel;
+ asection *s;
+ bfd_byte *rloc;
+ bfd_vma got_address;
+
+ s = mips_elf_rel_dyn_section (info, FALSE);
+ got_address = (htab->sgot->output_section->vma
+ + htab->sgot->output_offset
+ + entry->gotidx);
+
+ rloc = s->contents + (s->reloc_count++ * sizeof (Elf32_External_Rela));
+ outrel.r_offset = got_address;
+ outrel.r_info = ELF32_R_INFO (STN_UNDEF, R_MIPS_32);
+ outrel.r_addend = value;
+ bfd_elf32_swap_reloca_out (abfd, &outrel, rloc);
+ }
+
+ return entry;
+}
+
+/* Return the number of dynamic section symbols required by OUTPUT_BFD.
+ The number might be exact or a worst-case estimate, depending on how
+ much information is available to elf_backend_omit_section_dynsym at
+ the current linking stage. */
+
+static bfd_size_type
+count_section_dynsyms (bfd *output_bfd, struct bfd_link_info *info)
+{
+ bfd_size_type count;
+
+ count = 0;
+ if (info->shared || elf_hash_table (info)->is_relocatable_executable)
+ {
+ asection *p;
+ const struct elf_backend_data *bed;
+
+ bed = get_elf_backend_data (output_bfd);
+ for (p = output_bfd->sections; p ; p = p->next)
+ if ((p->flags & SEC_EXCLUDE) == 0
+ && (p->flags & SEC_ALLOC) != 0
+ && !(*bed->elf_backend_omit_section_dynsym) (output_bfd, info, p))
+ ++count;
+ }
+ return count;
+}
+
+/* Sort the dynamic symbol table so that symbols that need GOT entries
+ appear towards the end. */
+
+static bfd_boolean
+mips_elf_sort_hash_table (bfd *abfd, struct bfd_link_info *info)
+{
+ struct mips_elf_link_hash_table *htab;
+ struct mips_elf_hash_sort_data hsd;
+ struct mips_got_info *g;
+
+ if (elf_hash_table (info)->dynsymcount == 0)
+ return TRUE;
+
+ htab = mips_elf_hash_table (info);
+ BFD_ASSERT (htab != NULL);
+
+ g = htab->got_info;
+ if (g == NULL)
+ return TRUE;
+
+ hsd.low = NULL;
+ hsd.max_unref_got_dynindx
+ = hsd.min_got_dynindx
+ = (elf_hash_table (info)->dynsymcount - g->reloc_only_gotno);
+ hsd.max_non_got_dynindx = count_section_dynsyms (abfd, info) + 1;
+ mips_elf_link_hash_traverse (((struct mips_elf_link_hash_table *)
+ elf_hash_table (info)),
+ mips_elf_sort_hash_table_f,
+ &hsd);
+
+ /* There should have been enough room in the symbol table to
+ accommodate both the GOT and non-GOT symbols. */
+ BFD_ASSERT (hsd.max_non_got_dynindx <= hsd.min_got_dynindx);
+ BFD_ASSERT ((unsigned long) hsd.max_unref_got_dynindx
+ == elf_hash_table (info)->dynsymcount);
+ BFD_ASSERT (elf_hash_table (info)->dynsymcount - hsd.min_got_dynindx
+ == g->global_gotno);
+
+ /* Now we know which dynamic symbol has the lowest dynamic symbol
+ table index in the GOT. */
+ htab->global_gotsym = hsd.low;
+
+ return TRUE;
+}
+
+/* If H needs a GOT entry, assign it the highest available dynamic
+ index. Otherwise, assign it the lowest available dynamic
+ index. */
+
+static bfd_boolean
+mips_elf_sort_hash_table_f (struct mips_elf_link_hash_entry *h, void *data)
+{
+ struct mips_elf_hash_sort_data *hsd = data;
+
+ /* Symbols without dynamic symbol table entries aren't interesting
+ at all. */
+ if (h->root.dynindx == -1)
+ return TRUE;
+
+ switch (h->global_got_area)
+ {
+ case GGA_NONE:
+ h->root.dynindx = hsd->max_non_got_dynindx++;
+ break;
+
+ case GGA_NORMAL:
+ h->root.dynindx = --hsd->min_got_dynindx;
+ hsd->low = (struct elf_link_hash_entry *) h;
+ break;
+
+ case GGA_RELOC_ONLY:
+ if (hsd->max_unref_got_dynindx == hsd->min_got_dynindx)
+ hsd->low = (struct elf_link_hash_entry *) h;
+ h->root.dynindx = hsd->max_unref_got_dynindx++;
+ break;
+ }
+
+ return TRUE;
+}
+
+/* Record that input bfd ABFD requires a GOT entry like *LOOKUP
+ (which is owned by the caller and shouldn't be added to the
+ hash table directly). */
+
+static bfd_boolean
+mips_elf_record_got_entry (struct bfd_link_info *info, bfd *abfd,
+ struct mips_got_entry *lookup)
+{
+ struct mips_elf_link_hash_table *htab;
+ struct mips_got_entry *entry;
+ struct mips_got_info *g;
+ void **loc, **bfd_loc;
+
+ /* Make sure there's a slot for this entry in the master GOT. */
+ htab = mips_elf_hash_table (info);
+ g = htab->got_info;
+ loc = htab_find_slot (g->got_entries, lookup, INSERT);
+ if (!loc)
+ return FALSE;
+
+ /* Populate the entry if it isn't already. */
+ entry = (struct mips_got_entry *) *loc;
+ if (!entry)
+ {
+ entry = (struct mips_got_entry *) bfd_alloc (abfd, sizeof (*entry));
+ if (!entry)
+ return FALSE;
+
+ lookup->tls_initialized = FALSE;
+ lookup->gotidx = -1;
+ *entry = *lookup;
+ *loc = entry;
+ }
+
+ /* Reuse the same GOT entry for the BFD's GOT. */
+ g = mips_elf_bfd_got (abfd, TRUE);
+ if (!g)
+ return FALSE;
+
+ bfd_loc = htab_find_slot (g->got_entries, lookup, INSERT);
+ if (!bfd_loc)
+ return FALSE;
+
+ if (!*bfd_loc)
+ *bfd_loc = entry;
+ return TRUE;
+}
+
+/* ABFD has a GOT relocation of type R_TYPE against H. Reserve a GOT
+ entry for it. FOR_CALL is true if the caller is only interested in
+ using the GOT entry for calls. */
+
+static bfd_boolean
+mips_elf_record_global_got_symbol (struct elf_link_hash_entry *h,
+ bfd *abfd, struct bfd_link_info *info,
+ bfd_boolean for_call, int r_type)
+{
+ struct mips_elf_link_hash_table *htab;
+ struct mips_elf_link_hash_entry *hmips;
+ struct mips_got_entry entry;
+ unsigned char tls_type;
+
+ htab = mips_elf_hash_table (info);
+ BFD_ASSERT (htab != NULL);
+
+ hmips = (struct mips_elf_link_hash_entry *) h;
+ if (!for_call)
+ hmips->got_only_for_calls = FALSE;
+
+ /* A global symbol in the GOT must also be in the dynamic symbol
+ table. */
+ if (h->dynindx == -1)
+ {
+ switch (ELF_ST_VISIBILITY (h->other))
+ {
+ case STV_INTERNAL:
+ case STV_HIDDEN:
+ _bfd_elf_link_hash_hide_symbol (info, h, TRUE);
+ break;
+ }
+ if (!bfd_elf_link_record_dynamic_symbol (info, h))
+ return FALSE;
+ }
+
+ tls_type = mips_elf_reloc_tls_type (r_type);
+ if (tls_type == GOT_TLS_NONE && hmips->global_got_area > GGA_NORMAL)
+ hmips->global_got_area = GGA_NORMAL;
+
+ entry.abfd = abfd;
+ entry.symndx = -1;
+ entry.d.h = (struct mips_elf_link_hash_entry *) h;
+ entry.tls_type = tls_type;
+ return mips_elf_record_got_entry (info, abfd, &entry);
+}
+
+/* ABFD has a GOT relocation of type R_TYPE against symbol SYMNDX + ADDEND,
+ where SYMNDX is a local symbol. Reserve a GOT entry for it. */
+
+static bfd_boolean
+mips_elf_record_local_got_symbol (bfd *abfd, long symndx, bfd_vma addend,
+ struct bfd_link_info *info, int r_type)
+{
+ struct mips_elf_link_hash_table *htab;
+ struct mips_got_info *g;
+ struct mips_got_entry entry;
+
+ htab = mips_elf_hash_table (info);
+ BFD_ASSERT (htab != NULL);
+
+ g = htab->got_info;
+ BFD_ASSERT (g != NULL);
+
+ entry.abfd = abfd;
+ entry.symndx = symndx;
+ entry.d.addend = addend;
+ entry.tls_type = mips_elf_reloc_tls_type (r_type);
+ return mips_elf_record_got_entry (info, abfd, &entry);
+}
+
+/* Record that ABFD has a page relocation against SYMNDX + ADDEND.
+ H is the symbol's hash table entry, or null if SYMNDX is local
+ to ABFD. */
+
+static bfd_boolean
+mips_elf_record_got_page_ref (struct bfd_link_info *info, bfd *abfd,
+ long symndx, struct elf_link_hash_entry *h,
+ bfd_signed_vma addend)
+{
+ struct mips_elf_link_hash_table *htab;
+ struct mips_got_info *g1, *g2;
+ struct mips_got_page_ref lookup, *entry;
+ void **loc, **bfd_loc;
+
+ htab = mips_elf_hash_table (info);
+ BFD_ASSERT (htab != NULL);
+
+ g1 = htab->got_info;
+ BFD_ASSERT (g1 != NULL);
+
+ if (h)
+ {
+ lookup.symndx = -1;
+ lookup.u.h = (struct mips_elf_link_hash_entry *) h;
+ }
+ else
+ {
+ lookup.symndx = symndx;
+ lookup.u.abfd = abfd;
+ }
+ lookup.addend = addend;
+ loc = htab_find_slot (g1->got_page_refs, &lookup, INSERT);
+ if (loc == NULL)
+ return FALSE;
+
+ entry = (struct mips_got_page_ref *) *loc;
+ if (!entry)
+ {
+ entry = bfd_alloc (abfd, sizeof (*entry));
+ if (!entry)
+ return FALSE;
+
+ *entry = lookup;
+ *loc = entry;
+ }
+
+ /* Add the same entry to the BFD's GOT. */
+ g2 = mips_elf_bfd_got (abfd, TRUE);
+ if (!g2)
+ return FALSE;
+
+ bfd_loc = htab_find_slot (g2->got_page_refs, &lookup, INSERT);
+ if (!bfd_loc)
+ return FALSE;
+
+ if (!*bfd_loc)
+ *bfd_loc = entry;
+
+ return TRUE;
+}
+
+/* Add room for N relocations to the .rel(a).dyn section in ABFD. */
+
+static void
+mips_elf_allocate_dynamic_relocations (bfd *abfd, struct bfd_link_info *info,
+ unsigned int n)
+{
+ asection *s;
+ struct mips_elf_link_hash_table *htab;
+
+ htab = mips_elf_hash_table (info);
+ BFD_ASSERT (htab != NULL);
+
+ s = mips_elf_rel_dyn_section (info, FALSE);
+ BFD_ASSERT (s != NULL);
+
+ if (htab->is_vxworks)
+ s->size += n * MIPS_ELF_RELA_SIZE (abfd);
+ else
+ {
+ if (s->size == 0)
+ {
+ /* Make room for a null element. */
+ s->size += MIPS_ELF_REL_SIZE (abfd);
+ ++s->reloc_count;
+ }
+ s->size += n * MIPS_ELF_REL_SIZE (abfd);
+ }
+}
+
+/* A htab_traverse callback for GOT entries, with DATA pointing to a
+ mips_elf_traverse_got_arg structure. Count the number of GOT
+ entries and TLS relocs. Set DATA->value to true if we need
+ to resolve indirect or warning symbols and then recreate the GOT. */
+
+static int
+mips_elf_check_recreate_got (void **entryp, void *data)
+{
+ struct mips_got_entry *entry;
+ struct mips_elf_traverse_got_arg *arg;
+
+ entry = (struct mips_got_entry *) *entryp;
+ arg = (struct mips_elf_traverse_got_arg *) data;
+ if (entry->abfd != NULL && entry->symndx == -1)
+ {
+ struct mips_elf_link_hash_entry *h;
+
+ h = entry->d.h;
+ if (h->root.root.type == bfd_link_hash_indirect
+ || h->root.root.type == bfd_link_hash_warning)
+ {
+ arg->value = TRUE;
+ return 0;
+ }
+ }
+ mips_elf_count_got_entry (arg->info, arg->g, entry);
+ return 1;
+}
+
+/* A htab_traverse callback for GOT entries, with DATA pointing to a
+ mips_elf_traverse_got_arg structure. Add all entries to DATA->g,
+ converting entries for indirect and warning symbols into entries
+ for the target symbol. Set DATA->g to null on error. */
+
+static int
+mips_elf_recreate_got (void **entryp, void *data)
+{
+ struct mips_got_entry new_entry, *entry;
+ struct mips_elf_traverse_got_arg *arg;
+ void **slot;
+
+ entry = (struct mips_got_entry *) *entryp;
+ arg = (struct mips_elf_traverse_got_arg *) data;
+ if (entry->abfd != NULL
+ && entry->symndx == -1
+ && (entry->d.h->root.root.type == bfd_link_hash_indirect
+ || entry->d.h->root.root.type == bfd_link_hash_warning))
+ {
+ struct mips_elf_link_hash_entry *h;
+
+ new_entry = *entry;
+ entry = &new_entry;
+ h = entry->d.h;
+ do
+ {
+ BFD_ASSERT (h->global_got_area == GGA_NONE);
+ h = (struct mips_elf_link_hash_entry *) h->root.root.u.i.link;
+ }
+ while (h->root.root.type == bfd_link_hash_indirect
+ || h->root.root.type == bfd_link_hash_warning);
+ entry->d.h = h;
+ }
+ slot = htab_find_slot (arg->g->got_entries, entry, INSERT);
+ if (slot == NULL)
+ {
+ arg->g = NULL;
+ return 0;
+ }
+ if (*slot == NULL)
+ {
+ if (entry == &new_entry)
+ {
+ entry = bfd_alloc (entry->abfd, sizeof (*entry));
+ if (!entry)
+ {
+ arg->g = NULL;
+ return 0;
+ }
+ *entry = new_entry;
+ }
+ *slot = entry;
+ mips_elf_count_got_entry (arg->info, arg->g, entry);
+ }
+ return 1;
+}
+
+/* Return the maximum number of GOT page entries required for RANGE. */
+
+static bfd_vma
+mips_elf_pages_for_range (const struct mips_got_page_range *range)
+{
+ return (range->max_addend - range->min_addend + 0x1ffff) >> 16;
+}
+
+/* Record that G requires a page entry that can reach SEC + ADDEND. */
+
+static bfd_boolean
+mips_elf_record_got_page_entry (struct mips_elf_traverse_got_arg *arg,
+ asection *sec, bfd_signed_vma addend)
+{
+ struct mips_got_info *g = arg->g;
+ struct mips_got_page_entry lookup, *entry;
+ struct mips_got_page_range **range_ptr, *range;
+ bfd_vma old_pages, new_pages;
+ void **loc;
+
+ /* Find the mips_got_page_entry hash table entry for this section. */
+ lookup.sec = sec;
+ loc = htab_find_slot (g->got_page_entries, &lookup, INSERT);
+ if (loc == NULL)
+ return FALSE;
+
+ /* Create a mips_got_page_entry if this is the first time we've
+ seen the section. */
+ entry = (struct mips_got_page_entry *) *loc;
+ if (!entry)
+ {
+ entry = bfd_zalloc (arg->info->output_bfd, sizeof (*entry));
+ if (!entry)
+ return FALSE;
+
+ entry->sec = sec;
+ *loc = entry;
+ }
+
+ /* Skip over ranges whose maximum extent cannot share a page entry
+ with ADDEND. */
+ range_ptr = &entry->ranges;
+ while (*range_ptr && addend > (*range_ptr)->max_addend + 0xffff)
+ range_ptr = &(*range_ptr)->next;
+
+ /* If we scanned to the end of the list, or found a range whose
+ minimum extent cannot share a page entry with ADDEND, create
+ a new singleton range. */
+ range = *range_ptr;
+ if (!range || addend < range->min_addend - 0xffff)
+ {
+ range = bfd_zalloc (arg->info->output_bfd, sizeof (*range));
+ if (!range)
+ return FALSE;
+
+ range->next = *range_ptr;
+ range->min_addend = addend;
+ range->max_addend = addend;
+
+ *range_ptr = range;
+ entry->num_pages++;
+ g->page_gotno++;
+ return TRUE;
+ }
+
+ /* Remember how many pages the old range contributed. */
+ old_pages = mips_elf_pages_for_range (range);
+
+ /* Update the ranges. */
+ if (addend < range->min_addend)
+ range->min_addend = addend;
+ else if (addend > range->max_addend)
+ {
+ if (range->next && addend >= range->next->min_addend - 0xffff)
+ {
+ old_pages += mips_elf_pages_for_range (range->next);
+ range->max_addend = range->next->max_addend;
+ range->next = range->next->next;
+ }
+ else
+ range->max_addend = addend;
+ }
+
+ /* Record any change in the total estimate. */
+ new_pages = mips_elf_pages_for_range (range);
+ if (old_pages != new_pages)
+ {
+ entry->num_pages += new_pages - old_pages;
+ g->page_gotno += new_pages - old_pages;
+ }
+
+ return TRUE;
+}
+
+/* A htab_traverse callback for which *REFP points to a mips_got_page_ref
+ and for which DATA points to a mips_elf_traverse_got_arg. Work out
+ whether the page reference described by *REFP needs a GOT page entry,
+ and record that entry in DATA->g if so. Set DATA->g to null on failure. */
+
+static bfd_boolean
+mips_elf_resolve_got_page_ref (void **refp, void *data)
+{
+ struct mips_got_page_ref *ref;
+ struct mips_elf_traverse_got_arg *arg;
+ struct mips_elf_link_hash_table *htab;
+ asection *sec;
+ bfd_vma addend;
+
+ ref = (struct mips_got_page_ref *) *refp;
+ arg = (struct mips_elf_traverse_got_arg *) data;
+ htab = mips_elf_hash_table (arg->info);
+
+ if (ref->symndx < 0)
+ {
+ struct mips_elf_link_hash_entry *h;
+
+ /* Global GOT_PAGEs decay to GOT_DISP and so don't need page entries. */
+ h = ref->u.h;
+ if (!SYMBOL_REFERENCES_LOCAL (arg->info, &h->root))
+ return 1;
+
+ /* Ignore undefined symbols; we'll issue an error later if
+ appropriate. */
+ if (!((h->root.root.type == bfd_link_hash_defined
+ || h->root.root.type == bfd_link_hash_defweak)
+ && h->root.root.u.def.section))
+ return 1;
+
+ sec = h->root.root.u.def.section;
+ addend = h->root.root.u.def.value + ref->addend;
+ }
+ else
+ {
+ Elf_Internal_Sym *isym;
+
+ /* Read in the symbol. */
+ isym = bfd_sym_from_r_symndx (&htab->sym_cache, ref->u.abfd,
+ ref->symndx);
+ if (isym == NULL)
+ {
+ arg->g = NULL;
+ return 0;
+ }
+
+ /* Get the associated input section. */
+ sec = bfd_section_from_elf_index (ref->u.abfd, isym->st_shndx);
+ if (sec == NULL)
+ {
+ arg->g = NULL;
+ return 0;
+ }
+
+ /* If this is a mergable section, work out the section and offset
+ of the merged data. For section symbols, the addend specifies
+ of the offset _of_ the first byte in the data, otherwise it
+ specifies the offset _from_ the first byte. */
+ if (sec->flags & SEC_MERGE)
+ {
+ void *secinfo;
+
+ secinfo = elf_section_data (sec)->sec_info;
+ if (ELF_ST_TYPE (isym->st_info) == STT_SECTION)
+ addend = _bfd_merged_section_offset (ref->u.abfd, &sec, secinfo,
+ isym->st_value + ref->addend);
+ else
+ addend = _bfd_merged_section_offset (ref->u.abfd, &sec, secinfo,
+ isym->st_value) + ref->addend;
+ }
+ else
+ addend = isym->st_value + ref->addend;
+ }
+ if (!mips_elf_record_got_page_entry (arg, sec, addend))
+ {
+ arg->g = NULL;
+ return 0;
+ }
+ return 1;
+}
+
+/* If any entries in G->got_entries are for indirect or warning symbols,
+ replace them with entries for the target symbol. Convert g->got_page_refs
+ into got_page_entry structures and estimate the number of page entries
+ that they require. */
+
+static bfd_boolean
+mips_elf_resolve_final_got_entries (struct bfd_link_info *info,
+ struct mips_got_info *g)
+{
+ struct mips_elf_traverse_got_arg tga;
+ struct mips_got_info oldg;
+
+ oldg = *g;
+
+ tga.info = info;
+ tga.g = g;
+ tga.value = FALSE;
+ htab_traverse (g->got_entries, mips_elf_check_recreate_got, &tga);
+ if (tga.value)
+ {
+ *g = oldg;
+ g->got_entries = htab_create (htab_size (oldg.got_entries),
+ mips_elf_got_entry_hash,
+ mips_elf_got_entry_eq, NULL);
+ if (!g->got_entries)
+ return FALSE;
+
+ htab_traverse (oldg.got_entries, mips_elf_recreate_got, &tga);
+ if (!tga.g)
+ return FALSE;
+
+ htab_delete (oldg.got_entries);
+ }
+
+ g->got_page_entries = htab_try_create (1, mips_got_page_entry_hash,
+ mips_got_page_entry_eq, NULL);
+ if (g->got_page_entries == NULL)
+ return FALSE;
+
+ tga.info = info;
+ tga.g = g;
+ htab_traverse (g->got_page_refs, mips_elf_resolve_got_page_ref, &tga);
+
+ return TRUE;
+}
+
+/* Return true if a GOT entry for H should live in the local rather than
+ global GOT area. */
+
+static bfd_boolean
+mips_use_local_got_p (struct bfd_link_info *info,
+ struct mips_elf_link_hash_entry *h)
+{
+ /* Symbols that aren't in the dynamic symbol table must live in the
+ local GOT. This includes symbols that are completely undefined
+ and which therefore don't bind locally. We'll report undefined
+ symbols later if appropriate. */
+ if (h->root.dynindx == -1)
+ return TRUE;
+
+ /* Symbols that bind locally can (and in the case of forced-local
+ symbols, must) live in the local GOT. */
+ if (h->got_only_for_calls
+ ? SYMBOL_CALLS_LOCAL (info, &h->root)
+ : SYMBOL_REFERENCES_LOCAL (info, &h->root))
+ return TRUE;
+
+ /* If this is an executable that must provide a definition of the symbol,
+ either though PLTs or copy relocations, then that address should go in
+ the local rather than global GOT. */
+ if (info->executable && h->has_static_relocs)
+ return TRUE;
+
+ return FALSE;
+}
+
+/* A mips_elf_link_hash_traverse callback for which DATA points to the
+ link_info structure. Decide whether the hash entry needs an entry in
+ the global part of the primary GOT, setting global_got_area accordingly.
+ Count the number of global symbols that are in the primary GOT only
+ because they have relocations against them (reloc_only_gotno). */
+
+static int
+mips_elf_count_got_symbols (struct mips_elf_link_hash_entry *h, void *data)
+{
+ struct bfd_link_info *info;
+ struct mips_elf_link_hash_table *htab;
+ struct mips_got_info *g;
+
+ info = (struct bfd_link_info *) data;
+ htab = mips_elf_hash_table (info);
+ g = htab->got_info;
+ if (h->global_got_area != GGA_NONE)
+ {
+ /* Make a final decision about whether the symbol belongs in the
+ local or global GOT. */
+ if (mips_use_local_got_p (info, h))
+ /* The symbol belongs in the local GOT. We no longer need this
+ entry if it was only used for relocations; those relocations
+ will be against the null or section symbol instead of H. */
+ h->global_got_area = GGA_NONE;
+ else if (htab->is_vxworks
+ && h->got_only_for_calls
+ && h->root.plt.plist->mips_offset != MINUS_ONE)
+ /* On VxWorks, calls can refer directly to the .got.plt entry;
+ they don't need entries in the regular GOT. .got.plt entries
+ will be allocated by _bfd_mips_elf_adjust_dynamic_symbol. */
+ h->global_got_area = GGA_NONE;
+ else if (h->global_got_area == GGA_RELOC_ONLY)
+ {
+ g->reloc_only_gotno++;
+ g->global_gotno++;
+ }
+ }
+ return 1;
+}
+
+/* A htab_traverse callback for GOT entries. Add each one to the GOT
+ given in mips_elf_traverse_got_arg DATA. Clear DATA->G on error. */
+
+static int
+mips_elf_add_got_entry (void **entryp, void *data)
+{
+ struct mips_got_entry *entry;
+ struct mips_elf_traverse_got_arg *arg;
+ void **slot;
+
+ entry = (struct mips_got_entry *) *entryp;
+ arg = (struct mips_elf_traverse_got_arg *) data;
+ slot = htab_find_slot (arg->g->got_entries, entry, INSERT);
+ if (!slot)
+ {
+ arg->g = NULL;
+ return 0;
+ }
+ if (!*slot)
+ {
+ *slot = entry;
+ mips_elf_count_got_entry (arg->info, arg->g, entry);
+ }
+ return 1;
+}
+
+/* A htab_traverse callback for GOT page entries. Add each one to the GOT
+ given in mips_elf_traverse_got_arg DATA. Clear DATA->G on error. */
+
+static int
+mips_elf_add_got_page_entry (void **entryp, void *data)
+{
+ struct mips_got_page_entry *entry;
+ struct mips_elf_traverse_got_arg *arg;
+ void **slot;
+
+ entry = (struct mips_got_page_entry *) *entryp;
+ arg = (struct mips_elf_traverse_got_arg *) data;
+ slot = htab_find_slot (arg->g->got_page_entries, entry, INSERT);
+ if (!slot)
+ {
+ arg->g = NULL;
+ return 0;
+ }
+ if (!*slot)
+ {
+ *slot = entry;
+ arg->g->page_gotno += entry->num_pages;
+ }
+ return 1;
+}
+
+/* Consider merging FROM, which is ABFD's GOT, into TO. Return -1 if
+ this would lead to overflow, 1 if they were merged successfully,
+ and 0 if a merge failed due to lack of memory. (These values are chosen
+ so that nonnegative return values can be returned by a htab_traverse
+ callback.) */
+
+static int
+mips_elf_merge_got_with (bfd *abfd, struct mips_got_info *from,
+ struct mips_got_info *to,
+ struct mips_elf_got_per_bfd_arg *arg)
+{
+ struct mips_elf_traverse_got_arg tga;
+ unsigned int estimate;
+
+ /* Work out how many page entries we would need for the combined GOT. */
+ estimate = arg->max_pages;
+ if (estimate >= from->page_gotno + to->page_gotno)
+ estimate = from->page_gotno + to->page_gotno;
+
+ /* And conservatively estimate how many local and TLS entries
+ would be needed. */
+ estimate += from->local_gotno + to->local_gotno;
+ estimate += from->tls_gotno + to->tls_gotno;
+
+ /* If we're merging with the primary got, any TLS relocations will
+ come after the full set of global entries. Otherwise estimate those
+ conservatively as well. */
+ if (to == arg->primary && from->tls_gotno + to->tls_gotno)
+ estimate += arg->global_count;
+ else
+ estimate += from->global_gotno + to->global_gotno;
+
+ /* Bail out if the combined GOT might be too big. */
+ if (estimate > arg->max_count)
+ return -1;
+
+ /* Transfer the bfd's got information from FROM to TO. */
+ tga.info = arg->info;
+ tga.g = to;
+ htab_traverse (from->got_entries, mips_elf_add_got_entry, &tga);
+ if (!tga.g)
+ return 0;
+
+ htab_traverse (from->got_page_entries, mips_elf_add_got_page_entry, &tga);
+ if (!tga.g)
+ return 0;
+
+ mips_elf_replace_bfd_got (abfd, to);
+ return 1;
+}
+
+/* Attempt to merge GOT G, which belongs to ABFD. Try to use as much
+ as possible of the primary got, since it doesn't require explicit
+ dynamic relocations, but don't use bfds that would reference global
+ symbols out of the addressable range. Failing the primary got,
+ attempt to merge with the current got, or finish the current got
+ and then make make the new got current. */
+
+static bfd_boolean
+mips_elf_merge_got (bfd *abfd, struct mips_got_info *g,
+ struct mips_elf_got_per_bfd_arg *arg)
+{
+ unsigned int estimate;
+ int result;
+
+ if (!mips_elf_resolve_final_got_entries (arg->info, g))
+ return FALSE;
+
+ /* Work out the number of page, local and TLS entries. */
+ estimate = arg->max_pages;
+ if (estimate > g->page_gotno)
+ estimate = g->page_gotno;
+ estimate += g->local_gotno + g->tls_gotno;
+
+ /* We place TLS GOT entries after both locals and globals. The globals
+ for the primary GOT may overflow the normal GOT size limit, so be
+ sure not to merge a GOT which requires TLS with the primary GOT in that
+ case. This doesn't affect non-primary GOTs. */
+ estimate += (g->tls_gotno > 0 ? arg->global_count : g->global_gotno);
+
+ if (estimate <= arg->max_count)
+ {
+ /* If we don't have a primary GOT, use it as
+ a starting point for the primary GOT. */
+ if (!arg->primary)
+ {
+ arg->primary = g;
+ return TRUE;
+ }
+
+ /* Try merging with the primary GOT. */
+ result = mips_elf_merge_got_with (abfd, g, arg->primary, arg);
+ if (result >= 0)
+ return result;
+ }
+
+ /* If we can merge with the last-created got, do it. */
+ if (arg->current)
+ {
+ result = mips_elf_merge_got_with (abfd, g, arg->current, arg);
+ if (result >= 0)
+ return result;
+ }
+
+ /* Well, we couldn't merge, so create a new GOT. Don't check if it
+ fits; if it turns out that it doesn't, we'll get relocation
+ overflows anyway. */
+ g->next = arg->current;
+ arg->current = g;
+
+ return TRUE;
+}
+
+/* ENTRYP is a hash table entry for a mips_got_entry. Set its gotidx
+ to GOTIDX, duplicating the entry if it has already been assigned
+ an index in a different GOT. */
+
+static bfd_boolean
+mips_elf_set_gotidx (void **entryp, long gotidx)
+{
+ struct mips_got_entry *entry;
+
+ entry = (struct mips_got_entry *) *entryp;
+ if (entry->gotidx > 0)
+ {
+ struct mips_got_entry *new_entry;
+
+ new_entry = bfd_alloc (entry->abfd, sizeof (*entry));
+ if (!new_entry)
+ return FALSE;
+
+ *new_entry = *entry;
+ *entryp = new_entry;
+ entry = new_entry;
+ }
+ entry->gotidx = gotidx;
+ return TRUE;
+}
+
+/* Set the TLS GOT index for the GOT entry in ENTRYP. DATA points to a
+ mips_elf_traverse_got_arg in which DATA->value is the size of one
+ GOT entry. Set DATA->g to null on failure. */
+
+static int
+mips_elf_initialize_tls_index (void **entryp, void *data)
+{
+ struct mips_got_entry *entry;
+ struct mips_elf_traverse_got_arg *arg;
+
+ /* We're only interested in TLS symbols. */
+ entry = (struct mips_got_entry *) *entryp;
+ if (entry->tls_type == GOT_TLS_NONE)
+ return 1;
+
+ arg = (struct mips_elf_traverse_got_arg *) data;
+ if (!mips_elf_set_gotidx (entryp, arg->value * arg->g->tls_assigned_gotno))
+ {
+ arg->g = NULL;
+ return 0;
+ }
+
+ /* Account for the entries we've just allocated. */
+ arg->g->tls_assigned_gotno += mips_tls_got_entries (entry->tls_type);
+ return 1;
+}
+
+/* A htab_traverse callback for GOT entries, where DATA points to a
+ mips_elf_traverse_got_arg. Set the global_got_area of each global
+ symbol to DATA->value. */
+
+static int
+mips_elf_set_global_got_area (void **entryp, void *data)
+{
+ struct mips_got_entry *entry;
+ struct mips_elf_traverse_got_arg *arg;
+
+ entry = (struct mips_got_entry *) *entryp;
+ arg = (struct mips_elf_traverse_got_arg *) data;
+ if (entry->abfd != NULL
+ && entry->symndx == -1
+ && entry->d.h->global_got_area != GGA_NONE)
+ entry->d.h->global_got_area = arg->value;
+ return 1;
+}
+
+/* A htab_traverse callback for secondary GOT entries, where DATA points
+ to a mips_elf_traverse_got_arg. Assign GOT indices to global entries
+ and record the number of relocations they require. DATA->value is
+ the size of one GOT entry. Set DATA->g to null on failure. */
+
+static int
+mips_elf_set_global_gotidx (void **entryp, void *data)
+{
+ struct mips_got_entry *entry;
+ struct mips_elf_traverse_got_arg *arg;
+
+ entry = (struct mips_got_entry *) *entryp;
+ arg = (struct mips_elf_traverse_got_arg *) data;
+ if (entry->abfd != NULL
+ && entry->symndx == -1
+ && entry->d.h->global_got_area != GGA_NONE)
+ {
+ if (!mips_elf_set_gotidx (entryp, arg->value * arg->g->assigned_low_gotno))
+ {
+ arg->g = NULL;
+ return 0;
+ }
+ arg->g->assigned_low_gotno += 1;
+
+ if (arg->info->shared
+ || (elf_hash_table (arg->info)->dynamic_sections_created
+ && entry->d.h->root.def_dynamic
+ && !entry->d.h->root.def_regular))
+ arg->g->relocs += 1;
+ }
+
+ return 1;
+}
+
+/* A htab_traverse callback for GOT entries for which DATA is the
+ bfd_link_info. Forbid any global symbols from having traditional
+ lazy-binding stubs. */
+
+static int
+mips_elf_forbid_lazy_stubs (void **entryp, void *data)
+{
+ struct bfd_link_info *info;
+ struct mips_elf_link_hash_table *htab;
+ struct mips_got_entry *entry;
+
+ entry = (struct mips_got_entry *) *entryp;
+ info = (struct bfd_link_info *) data;
+ htab = mips_elf_hash_table (info);
+ BFD_ASSERT (htab != NULL);
+
+ if (entry->abfd != NULL
+ && entry->symndx == -1
+ && entry->d.h->needs_lazy_stub)
+ {
+ entry->d.h->needs_lazy_stub = FALSE;
+ htab->lazy_stub_count--;
+ }
+
+ return 1;
+}
+
+/* Return the offset of an input bfd IBFD's GOT from the beginning of
+ the primary GOT. */
+static bfd_vma
+mips_elf_adjust_gp (bfd *abfd, struct mips_got_info *g, bfd *ibfd)
+{
+ if (!g->next)
+ return 0;
+
+ g = mips_elf_bfd_got (ibfd, FALSE);
+ if (! g)
+ return 0;
+
+ BFD_ASSERT (g->next);
+
+ g = g->next;
+
+ return (g->local_gotno + g->global_gotno + g->tls_gotno)
+ * MIPS_ELF_GOT_SIZE (abfd);
+}
+
+/* Turn a single GOT that is too big for 16-bit addressing into
+ a sequence of GOTs, each one 16-bit addressable. */
+
+static bfd_boolean
+mips_elf_multi_got (bfd *abfd, struct bfd_link_info *info,
+ asection *got, bfd_size_type pages)
+{
+ struct mips_elf_link_hash_table *htab;
+ struct mips_elf_got_per_bfd_arg got_per_bfd_arg;
+ struct mips_elf_traverse_got_arg tga;
+ struct mips_got_info *g, *gg;
+ unsigned int assign, needed_relocs;
+ bfd *dynobj, *ibfd;
+
+ dynobj = elf_hash_table (info)->dynobj;
+ htab = mips_elf_hash_table (info);
+ BFD_ASSERT (htab != NULL);
+
+ g = htab->got_info;
+
+ got_per_bfd_arg.obfd = abfd;
+ got_per_bfd_arg.info = info;
+ got_per_bfd_arg.current = NULL;
+ got_per_bfd_arg.primary = NULL;
+ got_per_bfd_arg.max_count = ((MIPS_ELF_GOT_MAX_SIZE (info)
+ / MIPS_ELF_GOT_SIZE (abfd))
+ - htab->reserved_gotno);
+ got_per_bfd_arg.max_pages = pages;
+ /* The number of globals that will be included in the primary GOT.
+ See the calls to mips_elf_set_global_got_area below for more
+ information. */
+ got_per_bfd_arg.global_count = g->global_gotno;
+
+ /* Try to merge the GOTs of input bfds together, as long as they
+ don't seem to exceed the maximum GOT size, choosing one of them
+ to be the primary GOT. */
+ for (ibfd = info->input_bfds; ibfd; ibfd = ibfd->link.next)
+ {
+ gg = mips_elf_bfd_got (ibfd, FALSE);
+ if (gg && !mips_elf_merge_got (ibfd, gg, &got_per_bfd_arg))
+ return FALSE;
+ }
+
+ /* If we do not find any suitable primary GOT, create an empty one. */
+ if (got_per_bfd_arg.primary == NULL)
+ g->next = mips_elf_create_got_info (abfd);
+ else
+ g->next = got_per_bfd_arg.primary;
+ g->next->next = got_per_bfd_arg.current;
+
+ /* GG is now the master GOT, and G is the primary GOT. */
+ gg = g;
+ g = g->next;
+
+ /* Map the output bfd to the primary got. That's what we're going
+ to use for bfds that use GOT16 or GOT_PAGE relocations that we
+ didn't mark in check_relocs, and we want a quick way to find it.
+ We can't just use gg->next because we're going to reverse the
+ list. */
+ mips_elf_replace_bfd_got (abfd, g);
+
+ /* Every symbol that is referenced in a dynamic relocation must be
+ present in the primary GOT, so arrange for them to appear after
+ those that are actually referenced. */
+ gg->reloc_only_gotno = gg->global_gotno - g->global_gotno;
+ g->global_gotno = gg->global_gotno;
+
+ tga.info = info;
+ tga.value = GGA_RELOC_ONLY;
+ htab_traverse (gg->got_entries, mips_elf_set_global_got_area, &tga);
+ tga.value = GGA_NORMAL;
+ htab_traverse (g->got_entries, mips_elf_set_global_got_area, &tga);
+
+ /* Now go through the GOTs assigning them offset ranges.
+ [assigned_low_gotno, local_gotno[ will be set to the range of local
+ entries in each GOT. We can then compute the end of a GOT by
+ adding local_gotno to global_gotno. We reverse the list and make
+ it circular since then we'll be able to quickly compute the
+ beginning of a GOT, by computing the end of its predecessor. To
+ avoid special cases for the primary GOT, while still preserving
+ assertions that are valid for both single- and multi-got links,
+ we arrange for the main got struct to have the right number of
+ global entries, but set its local_gotno such that the initial
+ offset of the primary GOT is zero. Remember that the primary GOT
+ will become the last item in the circular linked list, so it
+ points back to the master GOT. */
+ gg->local_gotno = -g->global_gotno;
+ gg->global_gotno = g->global_gotno;
+ gg->tls_gotno = 0;
+ assign = 0;
+ gg->next = gg;
+
+ do
+ {
+ struct mips_got_info *gn;
+
+ assign += htab->reserved_gotno;
+ g->assigned_low_gotno = assign;
+ g->local_gotno += assign;
+ g->local_gotno += (pages < g->page_gotno ? pages : g->page_gotno);
+ g->assigned_high_gotno = g->local_gotno - 1;
+ assign = g->local_gotno + g->global_gotno + g->tls_gotno;
+
+ /* Take g out of the direct list, and push it onto the reversed
+ list that gg points to. g->next is guaranteed to be nonnull after
+ this operation, as required by mips_elf_initialize_tls_index. */
+ gn = g->next;
+ g->next = gg->next;
+ gg->next = g;
+
+ /* Set up any TLS entries. We always place the TLS entries after
+ all non-TLS entries. */
+ g->tls_assigned_gotno = g->local_gotno + g->global_gotno;
+ tga.g = g;
+ tga.value = MIPS_ELF_GOT_SIZE (abfd);
+ htab_traverse (g->got_entries, mips_elf_initialize_tls_index, &tga);
+ if (!tga.g)
+ return FALSE;
+ BFD_ASSERT (g->tls_assigned_gotno == assign);
+
+ /* Move onto the next GOT. It will be a secondary GOT if nonull. */
+ g = gn;
+
+ /* Forbid global symbols in every non-primary GOT from having
+ lazy-binding stubs. */
+ if (g)
+ htab_traverse (g->got_entries, mips_elf_forbid_lazy_stubs, info);
+ }
+ while (g);
+
+ got->size = assign * MIPS_ELF_GOT_SIZE (abfd);
+
+ needed_relocs = 0;
+ for (g = gg->next; g && g->next != gg; g = g->next)
+ {
+ unsigned int save_assign;
+
+ /* Assign offsets to global GOT entries and count how many
+ relocations they need. */
+ save_assign = g->assigned_low_gotno;
+ g->assigned_low_gotno = g->local_gotno;
+ tga.info = info;
+ tga.value = MIPS_ELF_GOT_SIZE (abfd);
+ tga.g = g;
+ htab_traverse (g->got_entries, mips_elf_set_global_gotidx, &tga);
+ if (!tga.g)
+ return FALSE;
+ BFD_ASSERT (g->assigned_low_gotno == g->local_gotno + g->global_gotno);
+ g->assigned_low_gotno = save_assign;
+
+ if (info->shared)
+ {
+ g->relocs += g->local_gotno - g->assigned_low_gotno;
+ BFD_ASSERT (g->assigned_low_gotno == g->next->local_gotno
+ + g->next->global_gotno
+ + g->next->tls_gotno
+ + htab->reserved_gotno);
+ }
+ needed_relocs += g->relocs;
+ }
+ needed_relocs += g->relocs;
+
+ if (needed_relocs)
+ mips_elf_allocate_dynamic_relocations (dynobj, info,
+ needed_relocs);
+
+ return TRUE;
+}
+
+
+/* Returns the first relocation of type r_type found, beginning with
+ RELOCATION. RELEND is one-past-the-end of the relocation table. */
+
+static const Elf_Internal_Rela *
+mips_elf_next_relocation (bfd *abfd ATTRIBUTE_UNUSED, unsigned int r_type,
+ const Elf_Internal_Rela *relocation,
+ const Elf_Internal_Rela *relend)
+{
+ unsigned long r_symndx = ELF_R_SYM (abfd, relocation->r_info);
+
+ while (relocation < relend)
+ {
+ if (ELF_R_TYPE (abfd, relocation->r_info) == r_type
+ && ELF_R_SYM (abfd, relocation->r_info) == r_symndx)
+ return relocation;
+
+ ++relocation;
+ }
+
+ /* We didn't find it. */
+ return NULL;
+}
+
+/* Return whether an input relocation is against a local symbol. */
+
+static bfd_boolean
+mips_elf_local_relocation_p (bfd *input_bfd,
+ const Elf_Internal_Rela *relocation,
+ asection **local_sections)
+{
+ unsigned long r_symndx;
+ Elf_Internal_Shdr *symtab_hdr;
+ size_t extsymoff;
+
+ r_symndx = ELF_R_SYM (input_bfd, relocation->r_info);
+ symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
+ extsymoff = (elf_bad_symtab (input_bfd)) ? 0 : symtab_hdr->sh_info;
+
+ if (r_symndx < extsymoff)
+ return TRUE;
+ if (elf_bad_symtab (input_bfd) && local_sections[r_symndx] != NULL)
+ return TRUE;
+
+ return FALSE;
+}
+
+/* Sign-extend VALUE, which has the indicated number of BITS. */
+
+bfd_vma
+_bfd_mips_elf_sign_extend (bfd_vma value, int bits)
+{
+ if (value & ((bfd_vma) 1 << (bits - 1)))
+ /* VALUE is negative. */
+ value |= ((bfd_vma) - 1) << bits;
+
+ return value;
+}
+
+/* Return non-zero if the indicated VALUE has overflowed the maximum
+ range expressible by a signed number with the indicated number of
+ BITS. */
+
+static bfd_boolean
+mips_elf_overflow_p (bfd_vma value, int bits)
+{
+ bfd_signed_vma svalue = (bfd_signed_vma) value;
+
+ if (svalue > (1 << (bits - 1)) - 1)
+ /* The value is too big. */
+ return TRUE;
+ else if (svalue < -(1 << (bits - 1)))
+ /* The value is too small. */
+ return TRUE;
+
+ /* All is well. */
+ return FALSE;
+}
+
+/* Calculate the %high function. */
+
+static bfd_vma
+mips_elf_high (bfd_vma value)
+{
+ return ((value + (bfd_vma) 0x8000) >> 16) & 0xffff;
+}
+
+/* Calculate the %higher function. */
+
+static bfd_vma
+mips_elf_higher (bfd_vma value ATTRIBUTE_UNUSED)
+{
+#ifdef BFD64
+ return ((value + (bfd_vma) 0x80008000) >> 32) & 0xffff;
+#else
+ abort ();
+ return MINUS_ONE;
+#endif
+}
+
+/* Calculate the %highest function. */
+
+static bfd_vma
+mips_elf_highest (bfd_vma value ATTRIBUTE_UNUSED)
+{
+#ifdef BFD64
+ return ((value + (((bfd_vma) 0x8000 << 32) | 0x80008000)) >> 48) & 0xffff;
+#else
+ abort ();
+ return MINUS_ONE;
+#endif
+}
+
+/* Create the .compact_rel section. */
+
+static bfd_boolean
+mips_elf_create_compact_rel_section
+ (bfd *abfd, struct bfd_link_info *info ATTRIBUTE_UNUSED)
+{
+ flagword flags;
+ register asection *s;
+
+ if (bfd_get_linker_section (abfd, ".compact_rel") == NULL)
+ {
+ flags = (SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_LINKER_CREATED
+ | SEC_READONLY);
+
+ s = bfd_make_section_anyway_with_flags (abfd, ".compact_rel", flags);
+ if (s == NULL
+ || ! bfd_set_section_alignment (abfd, s,
+ MIPS_ELF_LOG_FILE_ALIGN (abfd)))
+ return FALSE;
+
+ s->size = sizeof (Elf32_External_compact_rel);
+ }
+
+ return TRUE;
+}
+
+/* Create the .got section to hold the global offset table. */
+
+static bfd_boolean
+mips_elf_create_got_section (bfd *abfd, struct bfd_link_info *info)
+{
+ flagword flags;
+ register asection *s;
+ struct elf_link_hash_entry *h;
+ struct bfd_link_hash_entry *bh;
+ struct mips_elf_link_hash_table *htab;
+
+ htab = mips_elf_hash_table (info);
+ BFD_ASSERT (htab != NULL);
+
+ /* This function may be called more than once. */
+ if (htab->sgot)
+ return TRUE;
+
+ flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
+ | SEC_LINKER_CREATED);
+
+ /* We have to use an alignment of 2**4 here because this is hardcoded
+ in the function stub generation and in the linker script. */
+ s = bfd_make_section_anyway_with_flags (abfd, ".got", flags);
+ if (s == NULL
+ || ! bfd_set_section_alignment (abfd, s, 4))
+ return FALSE;
+ htab->sgot = s;
+
+ /* 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. */
+ bh = NULL;
+ if (! (_bfd_generic_link_add_one_symbol
+ (info, abfd, "_GLOBAL_OFFSET_TABLE_", BSF_GLOBAL, s,
+ 0, NULL, FALSE, get_elf_backend_data (abfd)->collect, &bh)))
+ return FALSE;
+
+ h = (struct elf_link_hash_entry *) bh;
+ h->non_elf = 0;
+ h->def_regular = 1;
+ h->type = STT_OBJECT;
+ h->other = (h->other & ~ELF_ST_VISIBILITY (-1)) | STV_HIDDEN;
+ elf_hash_table (info)->hgot = h;
+
+ if (info->shared
+ && ! bfd_elf_link_record_dynamic_symbol (info, h))
+ return FALSE;
+
+ htab->got_info = mips_elf_create_got_info (abfd);
+ mips_elf_section_data (s)->elf.this_hdr.sh_flags
+ |= SHF_ALLOC | SHF_WRITE | SHF_MIPS_GPREL;
+
+ /* We also need a .got.plt section when generating PLTs. */
+ s = bfd_make_section_anyway_with_flags (abfd, ".got.plt",
+ SEC_ALLOC | SEC_LOAD
+ | SEC_HAS_CONTENTS
+ | SEC_IN_MEMORY
+ | SEC_LINKER_CREATED);
+ if (s == NULL)
+ return FALSE;
+ htab->sgotplt = s;
+
+ return TRUE;
+}
+
+/* Return true if H refers to the special VxWorks __GOTT_BASE__ or
+ __GOTT_INDEX__ symbols. These symbols are only special for
+ shared objects; they are not used in executables. */
+
+static bfd_boolean
+is_gott_symbol (struct bfd_link_info *info, struct elf_link_hash_entry *h)
+{
+ return (mips_elf_hash_table (info)->is_vxworks
+ && info->shared
+ && (strcmp (h->root.root.string, "__GOTT_BASE__") == 0
+ || strcmp (h->root.root.string, "__GOTT_INDEX__") == 0));
+}
+
+/* Return TRUE if a relocation of type R_TYPE from INPUT_BFD might
+ require an la25 stub. See also mips_elf_local_pic_function_p,
+ which determines whether the destination function ever requires a
+ stub. */
+
+static bfd_boolean
+mips_elf_relocation_needs_la25_stub (bfd *input_bfd, int r_type,
+ bfd_boolean target_is_16_bit_code_p)
+{
+ /* We specifically ignore branches and jumps from EF_PIC objects,
+ where the onus is on the compiler or programmer to perform any
+ necessary initialization of $25. Sometimes such initialization
+ is unnecessary; for example, -mno-shared functions do not use
+ the incoming value of $25, and may therefore be called directly. */
+ if (PIC_OBJECT_P (input_bfd))
+ return FALSE;
+
+ switch (r_type)
+ {
+ case R_MIPS_26:
+ case R_MIPS_PC16:
+ case R_MIPS_PC21_S2:
+ case R_MIPS_PC26_S2:
+ case R_MICROMIPS_26_S1:
+ case R_MICROMIPS_PC7_S1:
+ case R_MICROMIPS_PC10_S1:
+ case R_MICROMIPS_PC16_S1:
+ case R_MICROMIPS_PC23_S2:
+ return TRUE;
+
+ case R_MIPS16_26:
+ return !target_is_16_bit_code_p;
+
+ default:
+ return FALSE;
+ }
+}
+
+/* Calculate the value produced by the RELOCATION (which comes from
+ the INPUT_BFD). The ADDEND is the addend to use for this
+ RELOCATION; RELOCATION->R_ADDEND is ignored.
+
+ The result of the relocation calculation is stored in VALUEP.
+ On exit, set *CROSS_MODE_JUMP_P to true if the relocation field
+ is a MIPS16 or microMIPS jump to standard MIPS code, or vice versa.
+
+ This function returns bfd_reloc_continue if the caller need take no
+ further action regarding this relocation, bfd_reloc_notsupported if
+ something goes dramatically wrong, bfd_reloc_overflow if an
+ overflow occurs, and bfd_reloc_ok to indicate success. */
+
+static bfd_reloc_status_type
+mips_elf_calculate_relocation (bfd *abfd, bfd *input_bfd,
+ asection *input_section,
+ struct bfd_link_info *info,
+ const Elf_Internal_Rela *relocation,
+ bfd_vma addend, reloc_howto_type *howto,
+ Elf_Internal_Sym *local_syms,
+ asection **local_sections, bfd_vma *valuep,
+ const char **namep,
+ bfd_boolean *cross_mode_jump_p,
+ bfd_boolean save_addend)
+{
+ /* The eventual value we will return. */
+ bfd_vma value;
+ /* The address of the symbol against which the relocation is
+ occurring. */
+ bfd_vma symbol = 0;
+ /* The final GP value to be used for the relocatable, executable, or
+ shared object file being produced. */
+ bfd_vma gp;
+ /* The place (section offset or address) of the storage unit being
+ relocated. */
+ bfd_vma p;
+ /* The value of GP used to create the relocatable object. */
+ bfd_vma gp0;
+ /* The offset into the global offset table at which the address of
+ the relocation entry symbol, adjusted by the addend, resides
+ during execution. */
+ bfd_vma g = MINUS_ONE;
+ /* The section in which the symbol referenced by the relocation is
+ located. */
+ asection *sec = NULL;
+ struct mips_elf_link_hash_entry *h = NULL;
+ /* TRUE if the symbol referred to by this relocation is a local
+ symbol. */
+ bfd_boolean local_p, was_local_p;
+ /* TRUE if the symbol referred to by this relocation is "_gp_disp". */
+ bfd_boolean gp_disp_p = FALSE;
+ /* TRUE if the symbol referred to by this relocation is
+ "__gnu_local_gp". */
+ bfd_boolean gnu_local_gp_p = FALSE;
+ Elf_Internal_Shdr *symtab_hdr;
+ size_t extsymoff;
+ unsigned long r_symndx;
+ int r_type;
+ /* TRUE if overflow occurred during the calculation of the
+ relocation value. */
+ bfd_boolean overflowed_p;
+ /* TRUE if this relocation refers to a MIPS16 function. */
+ bfd_boolean target_is_16_bit_code_p = FALSE;
+ bfd_boolean target_is_micromips_code_p = FALSE;
+ struct mips_elf_link_hash_table *htab;
+ bfd *dynobj;
+
+ dynobj = elf_hash_table (info)->dynobj;
+ htab = mips_elf_hash_table (info);
+ BFD_ASSERT (htab != NULL);
+
+ /* Parse the relocation. */
+ r_symndx = ELF_R_SYM (input_bfd, relocation->r_info);
+ r_type = ELF_R_TYPE (input_bfd, relocation->r_info);
+ p = (input_section->output_section->vma
+ + input_section->output_offset
+ + relocation->r_offset);
+
+ /* Assume that there will be no overflow. */
+ overflowed_p = FALSE;
+
+ /* Figure out whether or not the symbol is local, and get the offset
+ used in the array of hash table entries. */
+ symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
+ local_p = mips_elf_local_relocation_p (input_bfd, relocation,
+ local_sections);
+ was_local_p = local_p;
+ if (! elf_bad_symtab (input_bfd))
+ extsymoff = symtab_hdr->sh_info;
+ else
+ {
+ /* The symbol table does not follow the rule that local symbols
+ must come before globals. */
+ extsymoff = 0;
+ }
+
+ /* Figure out the value of the symbol. */
+ if (local_p)
+ {
+ Elf_Internal_Sym *sym;
+
+ sym = local_syms + r_symndx;
+ sec = local_sections[r_symndx];
+
+ symbol = sec->output_section->vma + sec->output_offset;
+ if (ELF_ST_TYPE (sym->st_info) != STT_SECTION
+ || (sec->flags & SEC_MERGE))
+ symbol += sym->st_value;
+ if ((sec->flags & SEC_MERGE)
+ && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
+ {
+ addend = _bfd_elf_rel_local_sym (abfd, sym, &sec, addend);
+ addend -= symbol;
+ addend += sec->output_section->vma + sec->output_offset;
+ }
+
+ /* MIPS16/microMIPS text labels should be treated as odd. */
+ if (ELF_ST_IS_COMPRESSED (sym->st_other))
+ ++symbol;
+
+ /* Record the name of this symbol, for our caller. */
+ *namep = bfd_elf_string_from_elf_section (input_bfd,
+ symtab_hdr->sh_link,
+ sym->st_name);
+ if (*namep == '\0')
+ *namep = bfd_section_name (input_bfd, sec);
+
+ target_is_16_bit_code_p = ELF_ST_IS_MIPS16 (sym->st_other);
+ target_is_micromips_code_p = ELF_ST_IS_MICROMIPS (sym->st_other);
+ }
+ else
+ {
+ /* ??? Could we use RELOC_FOR_GLOBAL_SYMBOL here ? */
+
+ /* For global symbols we look up the symbol in the hash-table. */
+ h = ((struct mips_elf_link_hash_entry *)
+ elf_sym_hashes (input_bfd) [r_symndx - extsymoff]);
+ /* Find the real hash-table entry for this symbol. */
+ while (h->root.root.type == bfd_link_hash_indirect
+ || h->root.root.type == bfd_link_hash_warning)
+ h = (struct mips_elf_link_hash_entry *) h->root.root.u.i.link;
+
+ /* Record the name of this symbol, for our caller. */
+ *namep = h->root.root.root.string;
+
+ /* See if this is the special _gp_disp symbol. Note that such a
+ symbol must always be a global symbol. */
+ if (strcmp (*namep, "_gp_disp") == 0
+ && ! NEWABI_P (input_bfd))
+ {
+ /* Relocations against _gp_disp are permitted only with
+ R_MIPS_HI16 and R_MIPS_LO16 relocations. */
+ if (!hi16_reloc_p (r_type) && !lo16_reloc_p (r_type))
+ return bfd_reloc_notsupported;
+
+ gp_disp_p = TRUE;
+ }
+ /* See if this is the special _gp symbol. Note that such a
+ symbol must always be a global symbol. */
+ else if (strcmp (*namep, "__gnu_local_gp") == 0)
+ gnu_local_gp_p = TRUE;
+
+
+ /* If this symbol is defined, calculate its address. Note that
+ _gp_disp is a magic symbol, always implicitly defined by the
+ linker, so it's inappropriate to check to see whether or not
+ its defined. */
+ else if ((h->root.root.type == bfd_link_hash_defined
+ || h->root.root.type == bfd_link_hash_defweak)
+ && h->root.root.u.def.section)
+ {
+ sec = h->root.root.u.def.section;
+ if (sec->output_section)
+ symbol = (h->root.root.u.def.value
+ + sec->output_section->vma
+ + sec->output_offset);
+ else
+ symbol = h->root.root.u.def.value;
+ }
+ else if (h->root.root.type == bfd_link_hash_undefweak)
+ /* We allow relocations against undefined weak symbols, giving
+ it the value zero, so that you can undefined weak functions
+ and check to see if they exist by looking at their
+ addresses. */
+ symbol = 0;
+ else if (info->unresolved_syms_in_objects == RM_IGNORE
+ && ELF_ST_VISIBILITY (h->root.other) == STV_DEFAULT)
+ symbol = 0;
+ else if (strcmp (*namep, SGI_COMPAT (input_bfd)
+ ? "_DYNAMIC_LINK" : "_DYNAMIC_LINKING") == 0)
+ {
+ /* If this is a dynamic link, we should have created a
+ _DYNAMIC_LINK symbol or _DYNAMIC_LINKING(for normal mips) symbol
+ in in _bfd_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 (abfd, ".dynamic") == NULL);
+ symbol = 0;
+ }
+ else if (ELF_MIPS_IS_OPTIONAL (h->root.other))
+ {
+ /* This is an optional symbol - an Irix specific extension to the
+ ELF spec. Ignore it for now.
+ XXX - FIXME - there is more to the spec for OPTIONAL symbols
+ than simply ignoring them, but we do not handle this for now.
+ For information see the "64-bit ELF Object File Specification"
+ which is available from here:
+ http://techpubs.sgi.com/library/manuals/4000/007-4658-001/pdf/007-4658-001.pdf */
+ symbol = 0;
+ }
+ else if ((*info->callbacks->undefined_symbol)
+ (info, h->root.root.root.string, input_bfd,
+ input_section, relocation->r_offset,
+ (info->unresolved_syms_in_objects == RM_GENERATE_ERROR)
+ || ELF_ST_VISIBILITY (h->root.other)))
+ {
+ return bfd_reloc_undefined;
+ }
+ else
+ {
+ return bfd_reloc_notsupported;
+ }
+
+ target_is_16_bit_code_p = ELF_ST_IS_MIPS16 (h->root.other);
+ target_is_micromips_code_p = ELF_ST_IS_MICROMIPS (h->root.other);
+ }
+
+ /* If this is a reference to a 16-bit function with a stub, we need
+ to redirect the relocation to the stub unless:
+
+ (a) the relocation is for a MIPS16 JAL;
+
+ (b) the relocation is for a MIPS16 PIC call, and there are no
+ non-MIPS16 uses of the GOT slot; or
+
+ (c) the section allows direct references to MIPS16 functions. */
+ if (r_type != R_MIPS16_26
+ && !info->relocatable
+ && ((h != NULL
+ && h->fn_stub != NULL
+ && (r_type != R_MIPS16_CALL16 || h->need_fn_stub))
+ || (local_p
+ && mips_elf_tdata (input_bfd)->local_stubs != NULL
+ && mips_elf_tdata (input_bfd)->local_stubs[r_symndx] != NULL))
+ && !section_allows_mips16_refs_p (input_section))
+ {
+ /* This is a 32- or 64-bit call to a 16-bit function. We should
+ have already noticed that we were going to need the
+ stub. */
+ if (local_p)
+ {
+ sec = mips_elf_tdata (input_bfd)->local_stubs[r_symndx];
+ value = 0;
+ }
+ else
+ {
+ BFD_ASSERT (h->need_fn_stub);
+ if (h->la25_stub)
+ {
+ /* If a LA25 header for the stub itself exists, point to the
+ prepended LUI/ADDIU sequence. */
+ sec = h->la25_stub->stub_section;
+ value = h->la25_stub->offset;
+ }
+ else
+ {
+ sec = h->fn_stub;
+ value = 0;
+ }
+ }
+
+ symbol = sec->output_section->vma + sec->output_offset + value;
+ /* The target is 16-bit, but the stub isn't. */
+ target_is_16_bit_code_p = FALSE;
+ }
+ /* If this is a MIPS16 call with a stub, that is made through the PLT or
+ to a standard MIPS function, we need to redirect the call to the stub.
+ Note that we specifically exclude R_MIPS16_CALL16 from this behavior;
+ indirect calls should use an indirect stub instead. */
+ else if (r_type == R_MIPS16_26 && !info->relocatable
+ && ((h != NULL && (h->call_stub != NULL || h->call_fp_stub != NULL))
+ || (local_p
+ && mips_elf_tdata (input_bfd)->local_call_stubs != NULL
+ && mips_elf_tdata (input_bfd)->local_call_stubs[r_symndx] != NULL))
+ && ((h != NULL && h->use_plt_entry) || !target_is_16_bit_code_p))
+ {
+ if (local_p)
+ sec = mips_elf_tdata (input_bfd)->local_call_stubs[r_symndx];
+ else
+ {
+ /* If both call_stub and call_fp_stub are defined, we can figure
+ out which one to use by checking which one appears in the input
+ file. */
+ if (h->call_stub != NULL && h->call_fp_stub != NULL)
+ {
+ asection *o;
+
+ sec = NULL;
+ for (o = input_bfd->sections; o != NULL; o = o->next)
+ {
+ if (CALL_FP_STUB_P (bfd_get_section_name (input_bfd, o)))
+ {
+ sec = h->call_fp_stub;
+ break;
+ }
+ }
+ if (sec == NULL)
+ sec = h->call_stub;
+ }
+ else if (h->call_stub != NULL)
+ sec = h->call_stub;
+ else
+ sec = h->call_fp_stub;
+ }
+
+ BFD_ASSERT (sec->size > 0);
+ symbol = sec->output_section->vma + sec->output_offset;
+ }
+ /* If this is a direct call to a PIC function, redirect to the
+ non-PIC stub. */
+ else if (h != NULL && h->la25_stub
+ && mips_elf_relocation_needs_la25_stub (input_bfd, r_type,
+ target_is_16_bit_code_p))
+ symbol = (h->la25_stub->stub_section->output_section->vma
+ + h->la25_stub->stub_section->output_offset
+ + h->la25_stub->offset);
+ /* For direct MIPS16 and microMIPS calls make sure the compressed PLT
+ entry is used if a standard PLT entry has also been made. In this
+ case the symbol will have been set by mips_elf_set_plt_sym_value
+ to point to the standard PLT entry, so redirect to the compressed
+ one. */
+ else if ((r_type == R_MIPS16_26 || r_type == R_MICROMIPS_26_S1)
+ && !info->relocatable
+ && h != NULL
+ && h->use_plt_entry
+ && h->root.plt.plist->comp_offset != MINUS_ONE
+ && h->root.plt.plist->mips_offset != MINUS_ONE)
+ {
+ bfd_boolean micromips_p = MICROMIPS_P (abfd);
+
+ sec = htab->splt;
+ symbol = (sec->output_section->vma
+ + sec->output_offset
+ + htab->plt_header_size
+ + htab->plt_mips_offset
+ + h->root.plt.plist->comp_offset
+ + 1);
+
+ target_is_16_bit_code_p = !micromips_p;
+ target_is_micromips_code_p = micromips_p;
+ }
+
+ /* Make sure MIPS16 and microMIPS are not used together. */
+ if ((r_type == R_MIPS16_26 && target_is_micromips_code_p)
+ || (micromips_branch_reloc_p (r_type) && target_is_16_bit_code_p))
+ {
+ (*_bfd_error_handler)
+ (_("MIPS16 and microMIPS functions cannot call each other"));
+ return bfd_reloc_notsupported;
+ }
+
+ /* Calls from 16-bit code to 32-bit code and vice versa require the
+ mode change. However, we can ignore calls to undefined weak symbols,
+ which should never be executed at runtime. This exception is important
+ because the assembly writer may have "known" that any definition of the
+ symbol would be 16-bit code, and that direct jumps were therefore
+ acceptable. */
+ *cross_mode_jump_p = (!info->relocatable
+ && !(h && h->root.root.type == bfd_link_hash_undefweak)
+ && ((r_type == R_MIPS16_26 && !target_is_16_bit_code_p)
+ || (r_type == R_MICROMIPS_26_S1
+ && !target_is_micromips_code_p)
+ || ((r_type == R_MIPS_26 || r_type == R_MIPS_JALR)
+ && (target_is_16_bit_code_p
+ || target_is_micromips_code_p))));
+
+ local_p = (h == NULL || mips_use_local_got_p (info, h));
+
+ gp0 = _bfd_get_gp_value (input_bfd);
+ gp = _bfd_get_gp_value (abfd);
+ if (htab->got_info)
+ gp += mips_elf_adjust_gp (abfd, htab->got_info, input_bfd);
+
+ if (gnu_local_gp_p)
+ symbol = gp;
+
+ /* Global R_MIPS_GOT_PAGE/R_MICROMIPS_GOT_PAGE relocations are equivalent
+ to R_MIPS_GOT_DISP/R_MICROMIPS_GOT_DISP. The addend is applied by the
+ corresponding R_MIPS_GOT_OFST/R_MICROMIPS_GOT_OFST. */
+ if (got_page_reloc_p (r_type) && !local_p)
+ {
+ r_type = (micromips_reloc_p (r_type)
+ ? R_MICROMIPS_GOT_DISP : R_MIPS_GOT_DISP);
+ addend = 0;
+ }
+
+ /* If we haven't already determined the GOT offset, and we're going
+ to need it, get it now. */
+ switch (r_type)
+ {
+ case R_MIPS16_CALL16:
+ case R_MIPS16_GOT16:
+ case R_MIPS_CALL16:
+ case R_MIPS_GOT16:
+ case R_MIPS_GOT_DISP:
+ case R_MIPS_GOT_HI16:
+ case R_MIPS_CALL_HI16:
+ case R_MIPS_GOT_LO16:
+ case R_MIPS_CALL_LO16:
+ case R_MICROMIPS_CALL16:
+ case R_MICROMIPS_GOT16:
+ case R_MICROMIPS_GOT_DISP:
+ case R_MICROMIPS_GOT_HI16:
+ case R_MICROMIPS_CALL_HI16:
+ case R_MICROMIPS_GOT_LO16:
+ case R_MICROMIPS_CALL_LO16:
+ case R_MIPS_TLS_GD:
+ case R_MIPS_TLS_GOTTPREL:
+ case R_MIPS_TLS_LDM:
+ case R_MIPS16_TLS_GD:
+ case R_MIPS16_TLS_GOTTPREL:
+ case R_MIPS16_TLS_LDM:
+ case R_MICROMIPS_TLS_GD:
+ case R_MICROMIPS_TLS_GOTTPREL:
+ case R_MICROMIPS_TLS_LDM:
+ /* Find the index into the GOT where this value is located. */
+ if (tls_ldm_reloc_p (r_type))
+ {
+ g = mips_elf_local_got_index (abfd, input_bfd, info,
+ 0, 0, NULL, r_type);
+ if (g == MINUS_ONE)
+ return bfd_reloc_outofrange;
+ }
+ else if (!local_p)
+ {
+ /* On VxWorks, CALL relocations should refer to the .got.plt
+ entry, which is initialized to point at the PLT stub. */
+ if (htab->is_vxworks
+ && (call_hi16_reloc_p (r_type)
+ || call_lo16_reloc_p (r_type)
+ || call16_reloc_p (r_type)))
+ {
+ BFD_ASSERT (addend == 0);
+ BFD_ASSERT (h->root.needs_plt);
+ g = mips_elf_gotplt_index (info, &h->root);
+ }
+ else
+ {
+ BFD_ASSERT (addend == 0);
+ g = mips_elf_global_got_index (abfd, info, input_bfd,
+ &h->root, r_type);
+ if (!TLS_RELOC_P (r_type)
+ && !elf_hash_table (info)->dynamic_sections_created)
+ /* This is a static link. We must initialize the GOT entry. */
+ MIPS_ELF_PUT_WORD (dynobj, symbol, htab->sgot->contents + g);
+ }
+ }
+ else if (!htab->is_vxworks
+ && (call16_reloc_p (r_type) || got16_reloc_p (r_type)))
+ /* The calculation below does not involve "g". */
+ break;
+ else
+ {
+ g = mips_elf_local_got_index (abfd, input_bfd, info,
+ symbol + addend, r_symndx, h, r_type);
+ if (g == MINUS_ONE)
+ return bfd_reloc_outofrange;
+ }
+
+ /* Convert GOT indices to actual offsets. */
+ g = mips_elf_got_offset_from_index (info, abfd, input_bfd, g);
+ break;
+ }
+
+ /* Relocations against the VxWorks __GOTT_BASE__ and __GOTT_INDEX__
+ symbols are resolved by the loader. Add them to .rela.dyn. */
+ if (h != NULL && is_gott_symbol (info, &h->root))
+ {
+ Elf_Internal_Rela outrel;
+ bfd_byte *loc;
+ asection *s;
+
+ s = mips_elf_rel_dyn_section (info, FALSE);
+ loc = s->contents + s->reloc_count++ * sizeof (Elf32_External_Rela);
+
+ outrel.r_offset = (input_section->output_section->vma
+ + input_section->output_offset
+ + relocation->r_offset);
+ outrel.r_info = ELF32_R_INFO (h->root.dynindx, r_type);
+ outrel.r_addend = addend;
+ bfd_elf32_swap_reloca_out (abfd, &outrel, loc);
+
+ /* If we've written this relocation for a readonly section,
+ we need to set DF_TEXTREL again, so that we do not delete the
+ DT_TEXTREL tag. */
+ if (MIPS_ELF_READONLY_SECTION (input_section))
+ info->flags |= DF_TEXTREL;
+
+ *valuep = 0;
+ return bfd_reloc_ok;
+ }
+
+ /* Figure out what kind of relocation is being performed. */
+ switch (r_type)
+ {
+ case R_MIPS_NONE:
+ return bfd_reloc_continue;
+
+ case R_MIPS_16:
+ if (howto->partial_inplace)
+ addend = _bfd_mips_elf_sign_extend (addend, 16);
+ value = symbol + addend;
+ overflowed_p = mips_elf_overflow_p (value, 16);
+ break;
+
+ case R_MIPS_32:
+ case R_MIPS_REL32:
+ case R_MIPS_64:
+ if ((info->shared
+ || (htab->root.dynamic_sections_created
+ && h != NULL
+ && h->root.def_dynamic
+ && !h->root.def_regular
+ && !h->has_static_relocs))
+ && r_symndx != STN_UNDEF
+ && (h == NULL
+ || h->root.root.type != bfd_link_hash_undefweak
+ || ELF_ST_VISIBILITY (h->root.other) == STV_DEFAULT)
+ && (input_section->flags & SEC_ALLOC) != 0)
+ {
+ /* If we're creating a shared library, then we can't know
+ where the symbol will end up. So, we create a relocation
+ record in the output, and leave the job up to the dynamic
+ linker. We must do the same for executable references to
+ shared library symbols, unless we've decided to use copy
+ relocs or PLTs instead. */
+ value = addend;
+ if (!mips_elf_create_dynamic_relocation (abfd,
+ info,
+ relocation,
+ h,
+ sec,
+ symbol,
+ &value,
+ input_section))
+ return bfd_reloc_undefined;
+ }
+ else
+ {
+ if (r_type != R_MIPS_REL32)
+ value = symbol + addend;
+ else
+ value = addend;
+ }
+ value &= howto->dst_mask;
+ break;
+
+ case R_MIPS_PC32:
+ value = symbol + addend - p;
+ value &= howto->dst_mask;
+ break;
+
+ case R_MIPS16_26:
+ /* The calculation for R_MIPS16_26 is just the same as for an
+ R_MIPS_26. It's only the storage of the relocated field into
+ the output file that's different. That's handled in
+ mips_elf_perform_relocation. So, we just fall through to the
+ R_MIPS_26 case here. */
+ case R_MIPS_26:
+ case R_MICROMIPS_26_S1:
+ {
+ unsigned int shift;
+
+ /* Make sure the target of JALX is word-aligned. Bit 0 must be
+ the correct ISA mode selector and bit 1 must be 0. */
+ if (*cross_mode_jump_p && (symbol & 3) != (r_type == R_MIPS_26))
+ return bfd_reloc_outofrange;
+
+ /* Shift is 2, unusually, for microMIPS JALX. */
+ shift = (!*cross_mode_jump_p && r_type == R_MICROMIPS_26_S1) ? 1 : 2;
+
+ if (was_local_p)
+ value = addend | ((p + 4) & (0xfc000000 << shift));
+ else if (howto->partial_inplace)
+ value = _bfd_mips_elf_sign_extend (addend, 26 + shift);
+ else
+ value = addend;
+ value = (value + symbol) >> shift;
+ if (!was_local_p && h->root.root.type != bfd_link_hash_undefweak)
+ overflowed_p = (value >> 26) != ((p + 4) >> (26 + shift));
+ value &= howto->dst_mask;
+ }
+ break;
+
+ case R_MIPS_TLS_DTPREL_HI16:
+ case R_MIPS16_TLS_DTPREL_HI16:
+ case R_MICROMIPS_TLS_DTPREL_HI16:
+ value = (mips_elf_high (addend + symbol - dtprel_base (info))
+ & howto->dst_mask);
+ break;
+
+ case R_MIPS_TLS_DTPREL_LO16:
+ case R_MIPS_TLS_DTPREL32:
+ case R_MIPS_TLS_DTPREL64:
+ case R_MIPS16_TLS_DTPREL_LO16:
+ case R_MICROMIPS_TLS_DTPREL_LO16:
+ value = (symbol + addend - dtprel_base (info)) & howto->dst_mask;
+ break;
+
+ case R_MIPS_TLS_TPREL_HI16:
+ case R_MIPS16_TLS_TPREL_HI16:
+ case R_MICROMIPS_TLS_TPREL_HI16:
+ value = (mips_elf_high (addend + symbol - tprel_base (info))
+ & howto->dst_mask);
+ break;
+
+ case R_MIPS_TLS_TPREL_LO16:
+ case R_MIPS_TLS_TPREL32:
+ case R_MIPS_TLS_TPREL64:
+ case R_MIPS16_TLS_TPREL_LO16:
+ case R_MICROMIPS_TLS_TPREL_LO16:
+ value = (symbol + addend - tprel_base (info)) & howto->dst_mask;
+ break;
+
+ case R_MIPS_HI16:
+ case R_MIPS16_HI16:
+ case R_MICROMIPS_HI16:
+ if (!gp_disp_p)
+ {
+ value = mips_elf_high (addend + symbol);
+ value &= howto->dst_mask;
+ }
+ else
+ {
+ /* For MIPS16 ABI code we generate this sequence
+ 0: li $v0,%hi(_gp_disp)
+ 4: addiupc $v1,%lo(_gp_disp)
+ 8: sll $v0,16
+ 12: addu $v0,$v1
+ 14: move $gp,$v0
+ So the offsets of hi and lo relocs are the same, but the
+ base $pc is that used by the ADDIUPC instruction at $t9 + 4.
+ ADDIUPC clears the low two bits of the instruction address,
+ so the base is ($t9 + 4) & ~3. */
+ if (r_type == R_MIPS16_HI16)
+ value = mips_elf_high (addend + gp - ((p + 4) & ~(bfd_vma) 0x3));
+ /* The microMIPS .cpload sequence uses the same assembly
+ instructions as the traditional psABI version, but the
+ incoming $t9 has the low bit set. */
+ else if (r_type == R_MICROMIPS_HI16)
+ value = mips_elf_high (addend + gp - p - 1);
+ else
+ value = mips_elf_high (addend + gp - p);
+ overflowed_p = mips_elf_overflow_p (value, 16);
+ }
+ break;
+
+ case R_MIPS_LO16:
+ case R_MIPS16_LO16:
+ case R_MICROMIPS_LO16:
+ case R_MICROMIPS_HI0_LO16:
+ if (!gp_disp_p)
+ value = (symbol + addend) & howto->dst_mask;
+ else
+ {
+ /* See the comment for R_MIPS16_HI16 above for the reason
+ for this conditional. */
+ if (r_type == R_MIPS16_LO16)
+ value = addend + gp - (p & ~(bfd_vma) 0x3);
+ else if (r_type == R_MICROMIPS_LO16
+ || r_type == R_MICROMIPS_HI0_LO16)
+ value = addend + gp - p + 3;
+ else
+ value = addend + gp - p + 4;
+ /* The MIPS ABI requires checking the R_MIPS_LO16 relocation
+ for overflow. But, on, say, IRIX5, relocations against
+ _gp_disp are normally generated from the .cpload
+ pseudo-op. It generates code that normally looks like
+ this:
+
+ lui $gp,%hi(_gp_disp)
+ addiu $gp,$gp,%lo(_gp_disp)
+ addu $gp,$gp,$t9
+
+ Here $t9 holds the address of the function being called,
+ as required by the MIPS ELF ABI. The R_MIPS_LO16
+ relocation can easily overflow in this situation, but the
+ R_MIPS_HI16 relocation will handle the overflow.
+ Therefore, we consider this a bug in the MIPS ABI, and do
+ not check for overflow here. */
+ }
+ break;
+
+ case R_MIPS_LITERAL:
+ case R_MICROMIPS_LITERAL:
+ /* Because we don't merge literal sections, we can handle this
+ just like R_MIPS_GPREL16. In the long run, we should merge
+ shared literals, and then we will need to additional work
+ here. */
+
+ /* Fall through. */
+
+ case R_MIPS16_GPREL:
+ /* The R_MIPS16_GPREL performs the same calculation as
+ R_MIPS_GPREL16, but stores the relocated bits in a different
+ order. We don't need to do anything special here; the
+ differences are handled in mips_elf_perform_relocation. */
+ case R_MIPS_GPREL16:
+ case R_MICROMIPS_GPREL7_S2:
+ case R_MICROMIPS_GPREL16:
+ /* Only sign-extend the addend if it was extracted from the
+ instruction. If the addend was separate, leave it alone,
+ otherwise we may lose significant bits. */
+ if (howto->partial_inplace)
+ addend = _bfd_mips_elf_sign_extend (addend, 16);
+ value = symbol + addend - gp;
+ /* If the symbol was local, any earlier relocatable links will
+ have adjusted its addend with the gp offset, so compensate
+ for that now. Don't do it for symbols forced local in this
+ link, though, since they won't have had the gp offset applied
+ to them before. */
+ if (was_local_p)
+ value += gp0;
+ if (was_local_p || h->root.root.type != bfd_link_hash_undefweak)
+ overflowed_p = mips_elf_overflow_p (value, 16);
+ break;
+
+ case R_MIPS16_GOT16:
+ case R_MIPS16_CALL16:
+ case R_MIPS_GOT16:
+ case R_MIPS_CALL16:
+ case R_MICROMIPS_GOT16:
+ case R_MICROMIPS_CALL16:
+ /* VxWorks does not have separate local and global semantics for
+ R_MIPS*_GOT16; every relocation evaluates to "G". */
+ if (!htab->is_vxworks && local_p)
+ {
+ value = mips_elf_got16_entry (abfd, input_bfd, info,
+ symbol + addend, !was_local_p);
+ if (value == MINUS_ONE)
+ return bfd_reloc_outofrange;
+ value
+ = mips_elf_got_offset_from_index (info, abfd, input_bfd, value);
+ overflowed_p = mips_elf_overflow_p (value, 16);
+ break;
+ }
+
+ /* Fall through. */
+
+ case R_MIPS_TLS_GD:
+ case R_MIPS_TLS_GOTTPREL:
+ case R_MIPS_TLS_LDM:
+ case R_MIPS_GOT_DISP:
+ case R_MIPS16_TLS_GD:
+ case R_MIPS16_TLS_GOTTPREL:
+ case R_MIPS16_TLS_LDM:
+ case R_MICROMIPS_TLS_GD:
+ case R_MICROMIPS_TLS_GOTTPREL:
+ case R_MICROMIPS_TLS_LDM:
+ case R_MICROMIPS_GOT_DISP:
+ value = g;
+ overflowed_p = mips_elf_overflow_p (value, 16);
+ break;
+
+ case R_MIPS_GPREL32:
+ value = (addend + symbol + gp0 - gp);
+ if (!save_addend)
+ value &= howto->dst_mask;
+ break;
+
+ case R_MIPS_PC16:
+ case R_MIPS_GNU_REL16_S2:
+ if (howto->partial_inplace)
+ addend = _bfd_mips_elf_sign_extend (addend, 18);
+
+ if ((symbol + addend) & 3)
+ return bfd_reloc_outofrange;
+
+ value = symbol + addend - p;
+ if (was_local_p || h->root.root.type != bfd_link_hash_undefweak)
+ overflowed_p = mips_elf_overflow_p (value, 18);
+ value >>= howto->rightshift;
+ value &= howto->dst_mask;
+ break;
+
+ case R_MIPS_PC21_S2:
+ if (howto->partial_inplace)
+ addend = _bfd_mips_elf_sign_extend (addend, 23);
+
+ if ((symbol + addend) & 3)
+ return bfd_reloc_outofrange;
+
+ value = symbol + addend - p;
+ if (was_local_p || h->root.root.type != bfd_link_hash_undefweak)
+ overflowed_p = mips_elf_overflow_p (value, 23);
+ value >>= howto->rightshift;
+ value &= howto->dst_mask;
+ break;
+
+ case R_MIPS_PC26_S2:
+ if (howto->partial_inplace)
+ addend = _bfd_mips_elf_sign_extend (addend, 28);
+
+ if ((symbol + addend) & 3)
+ return bfd_reloc_outofrange;
+
+ value = symbol + addend - p;
+ if (was_local_p || h->root.root.type != bfd_link_hash_undefweak)
+ overflowed_p = mips_elf_overflow_p (value, 28);
+ value >>= howto->rightshift;
+ value &= howto->dst_mask;
+ break;
+
+ case R_MIPS_PC18_S3:
+ if (howto->partial_inplace)
+ addend = _bfd_mips_elf_sign_extend (addend, 21);
+
+ if ((symbol + addend) & 7)
+ return bfd_reloc_outofrange;
+
+ value = symbol + addend - ((p | 7) ^ 7);
+ if (was_local_p || h->root.root.type != bfd_link_hash_undefweak)
+ overflowed_p = mips_elf_overflow_p (value, 21);
+ value >>= howto->rightshift;
+ value &= howto->dst_mask;
+ break;
+
+ case R_MIPS_PC19_S2:
+ if (howto->partial_inplace)
+ addend = _bfd_mips_elf_sign_extend (addend, 21);
+
+ if ((symbol + addend) & 3)
+ return bfd_reloc_outofrange;
+
+ value = symbol + addend - p;
+ if (was_local_p || h->root.root.type != bfd_link_hash_undefweak)
+ overflowed_p = mips_elf_overflow_p (value, 21);
+ value >>= howto->rightshift;
+ value &= howto->dst_mask;
+ break;
+
+ case R_MIPS_PCHI16:
+ value = mips_elf_high (symbol + addend - p);
+ if (was_local_p || h->root.root.type != bfd_link_hash_undefweak)
+ overflowed_p = mips_elf_overflow_p (value, 16);
+ value &= howto->dst_mask;
+ break;
+
+ case R_MIPS_PCLO16:
+ if (howto->partial_inplace)
+ addend = _bfd_mips_elf_sign_extend (addend, 16);
+ value = symbol + addend - p;
+ value &= howto->dst_mask;
+ break;
+
+ case R_MICROMIPS_PC7_S1:
+ if (howto->partial_inplace)
+ addend = _bfd_mips_elf_sign_extend (addend, 8);
+ value = symbol + addend - p;
+ if (was_local_p || h->root.root.type != bfd_link_hash_undefweak)
+ overflowed_p = mips_elf_overflow_p (value, 8);
+ value >>= howto->rightshift;
+ value &= howto->dst_mask;
+ break;
+
+ case R_MICROMIPS_PC10_S1:
+ if (howto->partial_inplace)
+ addend = _bfd_mips_elf_sign_extend (addend, 11);
+ value = symbol + addend - p;
+ if (was_local_p || h->root.root.type != bfd_link_hash_undefweak)
+ overflowed_p = mips_elf_overflow_p (value, 11);
+ value >>= howto->rightshift;
+ value &= howto->dst_mask;
+ break;
+
+ case R_MICROMIPS_PC16_S1:
+ if (howto->partial_inplace)
+ addend = _bfd_mips_elf_sign_extend (addend, 17);
+ value = symbol + addend - p;
+ if (was_local_p || h->root.root.type != bfd_link_hash_undefweak)
+ overflowed_p = mips_elf_overflow_p (value, 17);
+ value >>= howto->rightshift;
+ value &= howto->dst_mask;
+ break;
+
+ case R_MICROMIPS_PC23_S2:
+ if (howto->partial_inplace)
+ addend = _bfd_mips_elf_sign_extend (addend, 25);
+ value = symbol + addend - ((p | 3) ^ 3);
+ if (was_local_p || h->root.root.type != bfd_link_hash_undefweak)
+ overflowed_p = mips_elf_overflow_p (value, 25);
+ value >>= howto->rightshift;
+ value &= howto->dst_mask;
+ break;
+
+ case R_MIPS_GOT_HI16:
+ case R_MIPS_CALL_HI16:
+ case R_MICROMIPS_GOT_HI16:
+ case R_MICROMIPS_CALL_HI16:
+ /* We're allowed to handle these two relocations identically.
+ The dynamic linker is allowed to handle the CALL relocations
+ differently by creating a lazy evaluation stub. */
+ value = g;
+ value = mips_elf_high (value);
+ value &= howto->dst_mask;
+ break;
+
+ case R_MIPS_GOT_LO16:
+ case R_MIPS_CALL_LO16:
+ case R_MICROMIPS_GOT_LO16:
+ case R_MICROMIPS_CALL_LO16:
+ value = g & howto->dst_mask;
+ break;
+
+ case R_MIPS_GOT_PAGE:
+ case R_MICROMIPS_GOT_PAGE:
+ value = mips_elf_got_page (abfd, input_bfd, info, symbol + addend, NULL);
+ if (value == MINUS_ONE)
+ return bfd_reloc_outofrange;
+ value = mips_elf_got_offset_from_index (info, abfd, input_bfd, value);
+ overflowed_p = mips_elf_overflow_p (value, 16);
+ break;
+
+ case R_MIPS_GOT_OFST:
+ case R_MICROMIPS_GOT_OFST:
+ if (local_p)
+ mips_elf_got_page (abfd, input_bfd, info, symbol + addend, &value);
+ else
+ value = addend;
+ overflowed_p = mips_elf_overflow_p (value, 16);
+ break;
+
+ case R_MIPS_SUB:
+ case R_MICROMIPS_SUB:
+ value = symbol - addend;
+ value &= howto->dst_mask;
+ break;
+
+ case R_MIPS_HIGHER:
+ case R_MICROMIPS_HIGHER:
+ value = mips_elf_higher (addend + symbol);
+ value &= howto->dst_mask;
+ break;
+
+ case R_MIPS_HIGHEST:
+ case R_MICROMIPS_HIGHEST:
+ value = mips_elf_highest (addend + symbol);
+ value &= howto->dst_mask;
+ break;
+
+ case R_MIPS_SCN_DISP:
+ case R_MICROMIPS_SCN_DISP:
+ value = symbol + addend - sec->output_offset;
+ value &= howto->dst_mask;
+ break;
+
+ case R_MIPS_JALR:
+ case R_MICROMIPS_JALR:
+ /* This relocation is only a hint. In some cases, we optimize
+ it into a bal instruction. But we don't try to optimize
+ when the symbol does not resolve locally. */
+ if (h != NULL && !SYMBOL_CALLS_LOCAL (info, &h->root))
+ return bfd_reloc_continue;
+ value = symbol + addend;
+ break;
+
+ case R_MIPS_PJUMP:
+ case R_MIPS_GNU_VTINHERIT:
+ case R_MIPS_GNU_VTENTRY:
+ /* We don't do anything with these at present. */
+ return bfd_reloc_continue;
+
+ default:
+ /* An unrecognized relocation type. */
+ return bfd_reloc_notsupported;
+ }
+
+ /* Store the VALUE for our caller. */
+ *valuep = value;
+ return overflowed_p ? bfd_reloc_overflow : bfd_reloc_ok;
+}
+
+/* Obtain the field relocated by RELOCATION. */
+
+static bfd_vma
+mips_elf_obtain_contents (reloc_howto_type *howto,
+ const Elf_Internal_Rela *relocation,
+ bfd *input_bfd, bfd_byte *contents)
+{
+ bfd_vma x;
+ bfd_byte *location = contents + relocation->r_offset;
+
+ /* Obtain the bytes. */
+ x = bfd_get ((8 * bfd_get_reloc_size (howto)), input_bfd, location);
+
+ return x;
+}
+
+/* It has been determined that the result of the RELOCATION is the
+ VALUE. Use HOWTO to place VALUE into the output file at the
+ appropriate position. The SECTION is the section to which the
+ relocation applies.
+ CROSS_MODE_JUMP_P is true if the relocation field
+ is a MIPS16 or microMIPS jump to standard MIPS code, or vice versa.
+
+ Returns FALSE if anything goes wrong. */
+
+static bfd_boolean
+mips_elf_perform_relocation (struct bfd_link_info *info,
+ reloc_howto_type *howto,
+ const Elf_Internal_Rela *relocation,
+ bfd_vma value, bfd *input_bfd,
+ asection *input_section, bfd_byte *contents,
+ bfd_boolean cross_mode_jump_p)
+{
+ bfd_vma x;
+ bfd_byte *location;
+ int r_type = ELF_R_TYPE (input_bfd, relocation->r_info);
+
+ /* Figure out where the relocation is occurring. */
+ location = contents + relocation->r_offset;
+
+ _bfd_mips_elf_reloc_unshuffle (input_bfd, r_type, FALSE, location);
+
+ /* Obtain the current value. */
+ x = mips_elf_obtain_contents (howto, relocation, input_bfd, contents);
+
+ /* Clear the field we are setting. */
+ x &= ~howto->dst_mask;
+
+ /* Set the field. */
+ x |= (value & howto->dst_mask);
+
+ /* If required, turn JAL into JALX. */
+ if (cross_mode_jump_p && jal_reloc_p (r_type))
+ {
+ bfd_boolean ok;
+ bfd_vma opcode = x >> 26;
+ bfd_vma jalx_opcode;
+
+ /* Check to see if the opcode is already JAL or JALX. */
+ if (r_type == R_MIPS16_26)
+ {
+ ok = ((opcode == 0x6) || (opcode == 0x7));
+ jalx_opcode = 0x7;
+ }
+ else if (r_type == R_MICROMIPS_26_S1)
+ {
+ ok = ((opcode == 0x3d) || (opcode == 0x3c));
+ jalx_opcode = 0x3c;
+ }
+ else
+ {
+ ok = ((opcode == 0x3) || (opcode == 0x1d));
+ jalx_opcode = 0x1d;
+ }
+
+ /* If the opcode is not JAL or JALX, there's a problem. We cannot
+ convert J or JALS to JALX. */
+ if (!ok)
+ {
+ (*_bfd_error_handler)
+ (_("%B: %A+0x%lx: Unsupported jump between ISA modes; consider recompiling with interlinking enabled."),
+ input_bfd,
+ input_section,
+ (unsigned long) relocation->r_offset);
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+
+ /* Make this the JALX opcode. */
+ x = (x & ~(0x3f << 26)) | (jalx_opcode << 26);
+ }
+
+ /* Try converting JAL to BAL and J(AL)R to B(AL), if the target is in
+ range. */
+ if (!info->relocatable
+ && !cross_mode_jump_p
+ && ((JAL_TO_BAL_P (input_bfd)
+ && r_type == R_MIPS_26
+ && (x >> 26) == 0x3) /* jal addr */
+ || (JALR_TO_BAL_P (input_bfd)
+ && r_type == R_MIPS_JALR
+ && x == 0x0320f809) /* jalr t9 */
+ || (JR_TO_B_P (input_bfd)
+ && r_type == R_MIPS_JALR
+ && x == 0x03200008))) /* jr t9 */
+ {
+ bfd_vma addr;
+ bfd_vma dest;
+ bfd_signed_vma off;
+
+ addr = (input_section->output_section->vma
+ + input_section->output_offset
+ + relocation->r_offset
+ + 4);
+ if (r_type == R_MIPS_26)
+ dest = (value << 2) | ((addr >> 28) << 28);
+ else
+ dest = value;
+ off = dest - addr;
+ if (off <= 0x1ffff && off >= -0x20000)
+ {
+ if (x == 0x03200008) /* jr t9 */
+ x = 0x10000000 | (((bfd_vma) off >> 2) & 0xffff); /* b addr */
+ else
+ x = 0x04110000 | (((bfd_vma) off >> 2) & 0xffff); /* bal addr */
+ }
+ }
+
+ /* Put the value into the output. */
+ bfd_put (8 * bfd_get_reloc_size (howto), input_bfd, x, location);
+
+ _bfd_mips_elf_reloc_shuffle (input_bfd, r_type, !info->relocatable,
+ location);
+
+ return TRUE;
+}
+
+/* Create a rel.dyn relocation for the dynamic linker to resolve. REL
+ is the original relocation, which is now being transformed into a
+ dynamic relocation. The ADDENDP is adjusted if necessary; the
+ caller should store the result in place of the original addend. */
+
+static bfd_boolean
+mips_elf_create_dynamic_relocation (bfd *output_bfd,
+ struct bfd_link_info *info,
+ const Elf_Internal_Rela *rel,
+ struct mips_elf_link_hash_entry *h,
+ asection *sec, bfd_vma symbol,
+ bfd_vma *addendp, asection *input_section)
+{
+ Elf_Internal_Rela outrel[3];
+ asection *sreloc;
+ bfd *dynobj;
+ int r_type;
+ long indx;
+ bfd_boolean defined_p;
+ struct mips_elf_link_hash_table *htab;
+
+ htab = mips_elf_hash_table (info);
+ BFD_ASSERT (htab != NULL);
+
+ r_type = ELF_R_TYPE (output_bfd, rel->r_info);
+ dynobj = elf_hash_table (info)->dynobj;
+ sreloc = mips_elf_rel_dyn_section (info, FALSE);
+ BFD_ASSERT (sreloc != NULL);
+ BFD_ASSERT (sreloc->contents != NULL);
+ BFD_ASSERT (sreloc->reloc_count * MIPS_ELF_REL_SIZE (output_bfd)
+ < sreloc->size);
+
+ outrel[0].r_offset =
+ _bfd_elf_section_offset (output_bfd, info, input_section, rel[0].r_offset);
+ if (ABI_64_P (output_bfd))
+ {
+ outrel[1].r_offset =
+ _bfd_elf_section_offset (output_bfd, info, input_section, rel[1].r_offset);
+ outrel[2].r_offset =
+ _bfd_elf_section_offset (output_bfd, info, input_section, rel[2].r_offset);
+ }
+
+ if (outrel[0].r_offset == MINUS_ONE)
+ /* The relocation field has been deleted. */
+ return TRUE;
+
+ if (outrel[0].r_offset == MINUS_TWO)
+ {
+ /* The relocation field has been converted into a relative value of
+ some sort. Functions like _bfd_elf_write_section_eh_frame expect
+ the field to be fully relocated, so add in the symbol's value. */
+ *addendp += symbol;
+ return TRUE;
+ }
+
+ /* We must now calculate the dynamic symbol table index to use
+ in the relocation. */
+ if (h != NULL && ! SYMBOL_REFERENCES_LOCAL (info, &h->root))
+ {
+ BFD_ASSERT (htab->is_vxworks || h->global_got_area != GGA_NONE);
+ indx = h->root.dynindx;
+ if (SGI_COMPAT (output_bfd))
+ defined_p = h->root.def_regular;
+ else
+ /* ??? glibc's ld.so just adds the final GOT entry to the
+ relocation field. It therefore treats relocs against
+ defined symbols in the same way as relocs against
+ undefined symbols. */
+ defined_p = FALSE;
+ }
+ else
+ {
+ 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
+ {
+ indx = elf_section_data (sec->output_section)->dynindx;
+ if (indx == 0)
+ {
+ asection *osec = htab->root.text_index_section;
+ indx = elf_section_data (osec)->dynindx;
+ }
+ if (indx == 0)
+ abort ();
+ }
+
+ /* Instead of generating a relocation using the section
+ symbol, we may as well make it a fully relative
+ relocation. We want to avoid generating relocations to
+ local symbols because we used to generate them
+ incorrectly, without adding the original symbol value,
+ which is mandated by the ABI for section symbols. In
+ order to give dynamic loaders and applications time to
+ phase out the incorrect use, we refrain from emitting
+ section-relative relocations. It's not like they're
+ useful, after all. This should be a bit more efficient
+ as well. */
+ /* ??? Although this behavior is compatible with glibc's ld.so,
+ the ABI says that relocations against STN_UNDEF should have
+ a symbol value of 0. Irix rld honors this, so relocations
+ against STN_UNDEF have no effect. */
+ if (!SGI_COMPAT (output_bfd))
+ indx = 0;
+ defined_p = TRUE;
+ }
+
+ /* If the relocation was previously an absolute relocation and
+ this symbol will not be referred to by the relocation, we must
+ adjust it by the value we give it in the dynamic symbol table.
+ Otherwise leave the job up to the dynamic linker. */
+ if (defined_p && r_type != R_MIPS_REL32)
+ *addendp += symbol;
+
+ if (htab->is_vxworks)
+ /* VxWorks uses non-relative relocations for this. */
+ outrel[0].r_info = ELF32_R_INFO (indx, R_MIPS_32);
+ else
+ /* The relocation is always an REL32 relocation because we don't
+ know where the shared library will wind up at load-time. */
+ outrel[0].r_info = ELF_R_INFO (output_bfd, (unsigned long) indx,
+ R_MIPS_REL32);
+
+ /* For strict adherence to the ABI specification, we should
+ generate a R_MIPS_64 relocation record by itself before the
+ _REL32/_64 record as well, such that the addend is read in as
+ a 64-bit value (REL32 is a 32-bit relocation, after all).
+ However, since none of the existing ELF64 MIPS dynamic
+ loaders seems to care, we don't waste space with these
+ artificial relocations. If this turns out to not be true,
+ mips_elf_allocate_dynamic_relocation() should be tweaked so
+ as to make room for a pair of dynamic relocations per
+ invocation if ABI_64_P, and here we should generate an
+ additional relocation record with R_MIPS_64 by itself for a
+ NULL symbol before this relocation record. */
+ outrel[1].r_info = ELF_R_INFO (output_bfd, 0,
+ ABI_64_P (output_bfd)
+ ? R_MIPS_64
+ : R_MIPS_NONE);
+ outrel[2].r_info = ELF_R_INFO (output_bfd, 0, R_MIPS_NONE);
+
+ /* Adjust the output offset of the relocation to reference the
+ correct location in the output file. */
+ outrel[0].r_offset += (input_section->output_section->vma
+ + input_section->output_offset);
+ outrel[1].r_offset += (input_section->output_section->vma
+ + input_section->output_offset);
+ outrel[2].r_offset += (input_section->output_section->vma
+ + input_section->output_offset);
+
+ /* Put the relocation back out. We have to use the special
+ relocation outputter in the 64-bit case since the 64-bit
+ relocation format is non-standard. */
+ if (ABI_64_P (output_bfd))
+ {
+ (*get_elf_backend_data (output_bfd)->s->swap_reloc_out)
+ (output_bfd, &outrel[0],
+ (sreloc->contents
+ + sreloc->reloc_count * sizeof (Elf64_Mips_External_Rel)));
+ }
+ else if (htab->is_vxworks)
+ {
+ /* VxWorks uses RELA rather than REL dynamic relocations. */
+ outrel[0].r_addend = *addendp;
+ bfd_elf32_swap_reloca_out
+ (output_bfd, &outrel[0],
+ (sreloc->contents
+ + sreloc->reloc_count * sizeof (Elf32_External_Rela)));
+ }
+ else
+ bfd_elf32_swap_reloc_out
+ (output_bfd, &outrel[0],
+ (sreloc->contents + sreloc->reloc_count * sizeof (Elf32_External_Rel)));
+
+ /* We've now added another relocation. */
+ ++sreloc->reloc_count;
+
+ /* Make sure the output section is writable. The dynamic linker
+ will be writing to it. */
+ elf_section_data (input_section->output_section)->this_hdr.sh_flags
+ |= SHF_WRITE;
+
+ /* On IRIX5, make an entry of compact relocation info. */
+ if (IRIX_COMPAT (output_bfd) == ict_irix5)
+ {
+ asection *scpt = bfd_get_linker_section (dynobj, ".compact_rel");
+ bfd_byte *cr;
+
+ if (scpt)
+ {
+ Elf32_crinfo cptrel;
+
+ 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 = *addendp;
+
+ cr = (scpt->contents
+ + sizeof (Elf32_External_compact_rel));
+ mips_elf_set_cr_relvaddr (cptrel, 0);
+ bfd_elf32_swap_crinfo_out (output_bfd, &cptrel,
+ ((Elf32_External_crinfo *) cr
+ + scpt->reloc_count));
+ ++scpt->reloc_count;
+ }
+ }
+
+ /* If we've written this relocation for a readonly section,
+ we need to set DF_TEXTREL again, so that we do not delete the
+ DT_TEXTREL tag. */
+ if (MIPS_ELF_READONLY_SECTION (input_section))
+ info->flags |= DF_TEXTREL;
+
+ return TRUE;
+}
+
+/* Return the MACH for a MIPS e_flags value. */
+
+unsigned long
+_bfd_elf_mips_mach (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_4120:
+ return bfd_mach_mips4120;
+
+ case E_MIPS_MACH_4650:
+ return bfd_mach_mips4650;
+
+ case E_MIPS_MACH_5400:
+ return bfd_mach_mips5400;
+
+ case E_MIPS_MACH_5500:
+ return bfd_mach_mips5500;
+
+ case E_MIPS_MACH_5900:
+ return bfd_mach_mips5900;
+
+ case E_MIPS_MACH_9000:
+ return bfd_mach_mips9000;
+
+ case E_MIPS_MACH_SB1:
+ return bfd_mach_mips_sb1;
+
+ case E_MIPS_MACH_LS2E:
+ return bfd_mach_mips_loongson_2e;
+
+ case E_MIPS_MACH_LS2F:
+ return bfd_mach_mips_loongson_2f;
+
+ case E_MIPS_MACH_LS3A:
+ return bfd_mach_mips_loongson_3a;
+
+ case E_MIPS_MACH_OCTEON2:
+ return bfd_mach_mips_octeon2;
+
+ case E_MIPS_MACH_OCTEON:
+ return bfd_mach_mips_octeon;
+
+ case E_MIPS_MACH_XLR:
+ return bfd_mach_mips_xlr;
+
+ default:
+ switch (flags & EF_MIPS_ARCH)
+ {
+ default:
+ case E_MIPS_ARCH_1:
+ return bfd_mach_mips3000;
+
+ case E_MIPS_ARCH_2:
+ return bfd_mach_mips6000;
+
+ case E_MIPS_ARCH_3:
+ return bfd_mach_mips4000;
+
+ case E_MIPS_ARCH_4:
+ return bfd_mach_mips8000;
+
+ case E_MIPS_ARCH_5:
+ return bfd_mach_mips5;
+
+ case E_MIPS_ARCH_32:
+ return bfd_mach_mipsisa32;
+
+ case E_MIPS_ARCH_64:
+ return bfd_mach_mipsisa64;
+
+ case E_MIPS_ARCH_32R2:
+ return bfd_mach_mipsisa32r2;
+
+ case E_MIPS_ARCH_64R2:
+ return bfd_mach_mipsisa64r2;
+
+ case E_MIPS_ARCH_32R6:
+ return bfd_mach_mipsisa32r6;
+
+ case E_MIPS_ARCH_64R6:
+ return bfd_mach_mipsisa64r6;
+ }
+ }
+
+ return 0;
+}
+
+/* Return printable name for ABI. */
+
+static INLINE char *
+elf_mips_abi_name (bfd *abfd)
+{
+ flagword flags;
+
+ flags = elf_elfheader (abfd)->e_flags;
+ switch (flags & EF_MIPS_ABI)
+ {
+ case 0:
+ if (ABI_N32_P (abfd))
+ return "N32";
+ else if (ABI_64_P (abfd))
+ return "64";
+ else
+ 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";
+ }
+}
+
+/* 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;
+
+/* This is used for both the 32-bit and the 64-bit ABI. */
+
+void
+_bfd_mips_elf_symbol_processing (bfd *abfd, asymbol *asym)
+{
+ elf_symbol_type *elfsym;
+
+ /* Handle the special MIPS section numbers that a symbol may use. */
+ 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 on IRIX5. */
+ if (asym->value > elf_gp_size (abfd)
+ || ELF_ST_TYPE (elfsym->internal_elf_sym.st_info) == STT_TLS
+ || IRIX_COMPAT (abfd) == ict_irix6)
+ 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;
+
+ case SHN_MIPS_TEXT:
+ {
+ asection *section = bfd_get_section_by_name (abfd, ".text");
+
+ if (section != NULL)
+ {
+ asym->section = section;
+ /* MIPS_TEXT is a bit special, the address is not an offset
+ to the base of the .text section. So substract the section
+ base address to make it an offset. */
+ asym->value -= section->vma;
+ }
+ }
+ break;
+
+ case SHN_MIPS_DATA:
+ {
+ asection *section = bfd_get_section_by_name (abfd, ".data");
+
+ if (section != NULL)
+ {
+ asym->section = section;
+ /* MIPS_DATA is a bit special, the address is not an offset
+ to the base of the .data section. So substract the section
+ base address to make it an offset. */
+ asym->value -= section->vma;
+ }
+ }
+ break;
+ }
+
+ /* If this is an odd-valued function symbol, assume it's a MIPS16
+ or microMIPS one. */
+ if (ELF_ST_TYPE (elfsym->internal_elf_sym.st_info) == STT_FUNC
+ && (asym->value & 1) != 0)
+ {
+ asym->value--;
+ if (MICROMIPS_P (abfd))
+ elfsym->internal_elf_sym.st_other
+ = ELF_ST_SET_MICROMIPS (elfsym->internal_elf_sym.st_other);
+ else
+ elfsym->internal_elf_sym.st_other
+ = ELF_ST_SET_MIPS16 (elfsym->internal_elf_sym.st_other);
+ }
+}
+
+/* Implement elf_backend_eh_frame_address_size. This differs from
+ the default in the way it handles EABI64.
+
+ EABI64 was originally specified as an LP64 ABI, and that is what
+ -mabi=eabi normally gives on a 64-bit target. However, gcc has
+ historically accepted the combination of -mabi=eabi and -mlong32,
+ and this ILP32 variation has become semi-official over time.
+ Both forms use elf32 and have pointer-sized FDE addresses.
+
+ If an EABI object was generated by GCC 4.0 or above, it will have
+ an empty .gcc_compiled_longXX section, where XX is the size of longs
+ in bits. Unfortunately, ILP32 objects generated by earlier compilers
+ have no special marking to distinguish them from LP64 objects.
+
+ We don't want users of the official LP64 ABI to be punished for the
+ existence of the ILP32 variant, but at the same time, we don't want
+ to mistakenly interpret pre-4.0 ILP32 objects as being LP64 objects.
+ We therefore take the following approach:
+
+ - If ABFD contains a .gcc_compiled_longXX section, use it to
+ determine the pointer size.
+
+ - Otherwise check the type of the first relocation. Assume that
+ the LP64 ABI is being used if the relocation is of type R_MIPS_64.
+
+ - Otherwise punt.
+
+ The second check is enough to detect LP64 objects generated by pre-4.0
+ compilers because, in the kind of output generated by those compilers,
+ the first relocation will be associated with either a CIE personality
+ routine or an FDE start address. Furthermore, the compilers never
+ used a special (non-pointer) encoding for this ABI.
+
+ Checking the relocation type should also be safe because there is no
+ reason to use R_MIPS_64 in an ILP32 object. Pre-4.0 compilers never
+ did so. */
+
+unsigned int
+_bfd_mips_elf_eh_frame_address_size (bfd *abfd, asection *sec)
+{
+ if (elf_elfheader (abfd)->e_ident[EI_CLASS] == ELFCLASS64)
+ return 8;
+ if ((elf_elfheader (abfd)->e_flags & EF_MIPS_ABI) == E_MIPS_ABI_EABI64)
+ {
+ bfd_boolean long32_p, long64_p;
+
+ long32_p = bfd_get_section_by_name (abfd, ".gcc_compiled_long32") != 0;
+ long64_p = bfd_get_section_by_name (abfd, ".gcc_compiled_long64") != 0;
+ if (long32_p && long64_p)
+ return 0;
+ if (long32_p)
+ return 4;
+ if (long64_p)
+ return 8;
+
+ if (sec->reloc_count > 0
+ && elf_section_data (sec)->relocs != NULL
+ && (ELF32_R_TYPE (elf_section_data (sec)->relocs[0].r_info)
+ == R_MIPS_64))
+ return 8;
+
+ return 0;
+ }
+ return 4;
+}
+
+/* There appears to be a bug in the MIPSpro linker that causes GOT_DISP
+ relocations against two unnamed section symbols to resolve to the
+ same address. For example, if we have code like:
+
+ lw $4,%got_disp(.data)($gp)
+ lw $25,%got_disp(.text)($gp)
+ jalr $25
+
+ then the linker will resolve both relocations to .data and the program
+ will jump there rather than to .text.
+
+ We can work around this problem by giving names to local section symbols.
+ This is also what the MIPSpro tools do. */
+
+bfd_boolean
+_bfd_mips_elf_name_local_section_symbols (bfd *abfd)
+{
+ return SGI_COMPAT (abfd);
+}
+
+/* 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. */
+
+bfd_boolean
+_bfd_mips_elf_section_processing (bfd *abfd, Elf_Internal_Shdr *hdr)
+{
+ if (hdr->sh_type == SHT_MIPS_REGINFO
+ && hdr->sh_size > 0)
+ {
+ 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) != 0)
+ return FALSE;
+ H_PUT_32 (abfd, elf_gp (abfd), buf);
+ if (bfd_bwrite (buf, 4, abfd) != 4)
+ return FALSE;
+ }
+
+ if (hdr->sh_type == SHT_MIPS_OPTIONS
+ && hdr->bfd_section != NULL
+ && mips_elf_section_data (hdr->bfd_section) != NULL
+ && mips_elf_section_data (hdr->bfd_section)->u.tdata != NULL)
+ {
+ bfd_byte *contents, *l, *lend;
+
+ /* We stored the section contents in the 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 = mips_elf_section_data (hdr->bfd_section)->u.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.size < sizeof (Elf_External_Options))
+ {
+ (*_bfd_error_handler)
+ (_("%B: Warning: bad `%s' option size %u smaller than its header"),
+ abfd, MIPS_ELF_OPTIONS_SECTION_NAME (abfd), intopt.size);
+ break;
+ }
+ if (ABI_64_P (abfd) && 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) != 0)
+ return FALSE;
+ H_PUT_64 (abfd, elf_gp (abfd), buf);
+ if (bfd_bwrite (buf, 8, abfd) != 8)
+ return FALSE;
+ }
+ else 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) != 0)
+ return FALSE;
+ H_PUT_32 (abfd, elf_gp (abfd), buf);
+ if (bfd_bwrite (buf, 4, abfd) != 4)
+ return FALSE;
+ }
+ l += intopt.size;
+ }
+ }
+
+ if (hdr->bfd_section != NULL)
+ {
+ const char *name = bfd_get_section_name (abfd, hdr->bfd_section);
+
+ /* .sbss is not handled specially here because the GNU/Linux
+ prelinker can convert .sbss from NOBITS to PROGBITS and
+ changing it back to NOBITS breaks the binary. The entry in
+ _bfd_mips_elf_special_sections will ensure the correct flags
+ are set on .sbss if BFD creates it without reading it from an
+ input file, and without special handling here the flags set
+ on it in an input file will be followed. */
+ if (strcmp (name, ".sdata") == 0
+ || 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, ".srdata") == 0)
+ {
+ hdr->sh_flags |= SHF_ALLOC | 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;
+}
+
+/* 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. */
+
+bfd_boolean
+_bfd_mips_elf_section_from_shdr (bfd *abfd,
+ Elf_Internal_Shdr *hdr,
+ const char *name,
+ int shindex)
+{
+ 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 (! CONST_STRNEQ (name, ".gptab."))
+ 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 (! CONST_STRNEQ (name, ".MIPS.content"))
+ return FALSE;
+ break;
+ case SHT_MIPS_OPTIONS:
+ if (!MIPS_ELF_OPTIONS_SECTION_NAME_P (name))
+ return FALSE;
+ break;
+ case SHT_MIPS_ABIFLAGS:
+ if (!MIPS_ELF_ABIFLAGS_SECTION_NAME_P (name))
+ return FALSE;
+ flags = (SEC_LINK_ONCE | SEC_LINK_DUPLICATES_SAME_SIZE);
+ break;
+ case SHT_MIPS_DWARF:
+ if (! CONST_STRNEQ (name, ".debug_")
+ && ! CONST_STRNEQ (name, ".zdebug_"))
+ return FALSE;
+ break;
+ case SHT_MIPS_SYMBOL_LIB:
+ if (strcmp (name, ".MIPS.symlib") != 0)
+ return FALSE;
+ break;
+ case SHT_MIPS_EVENTS:
+ if (! CONST_STRNEQ (name, ".MIPS.events")
+ && ! CONST_STRNEQ (name, ".MIPS.post_rel"))
+ return FALSE;
+ break;
+ default:
+ break;
+ }
+
+ if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex))
+ return FALSE;
+
+ if (flags)
+ {
+ if (! bfd_set_section_flags (abfd, hdr->bfd_section,
+ (bfd_get_section_flags (abfd,
+ hdr->bfd_section)
+ | flags)))
+ return FALSE;
+ }
+
+ if (hdr->sh_type == SHT_MIPS_ABIFLAGS)
+ {
+ Elf_External_ABIFlags_v0 ext;
+
+ if (! bfd_get_section_contents (abfd, hdr->bfd_section,
+ &ext, 0, sizeof ext))
+ return FALSE;
+ bfd_mips_elf_swap_abiflags_v0_in (abfd, &ext,
+ &mips_elf_tdata (abfd)->abiflags);
+ if (mips_elf_tdata (abfd)->abiflags.version != 0)
+ return FALSE;
+ mips_elf_tdata (abfd)->abiflags_valid = TRUE;
+ }
+
+ /* 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,
+ &ext, 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_malloc (hdr->sh_size);
+ if (contents == NULL)
+ return FALSE;
+ if (! bfd_get_section_contents (abfd, hdr->bfd_section, contents,
+ 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.size < sizeof (Elf_External_Options))
+ {
+ (*_bfd_error_handler)
+ (_("%B: Warning: bad `%s' option size %u smaller than its header"),
+ abfd, MIPS_ELF_OPTIONS_SECTION_NAME (abfd), intopt.size);
+ break;
+ }
+ if (ABI_64_P (abfd) && 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;
+ }
+ else 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. */
+
+bfd_boolean
+_bfd_mips_elf_fake_sections (bfd *abfd, Elf_Internal_Shdr *hdr, asection *sec)
+{
+ const char *name = bfd_get_section_name (abfd, sec);
+
+ if (strcmp (name, ".liblist") == 0)
+ {
+ hdr->sh_type = SHT_MIPS_LIBLIST;
+ hdr->sh_info = sec->size / sizeof (Elf32_Lib);
+ /* The sh_link field is set in final_write_processing. */
+ }
+ else if (strcmp (name, ".conflict") == 0)
+ hdr->sh_type = SHT_MIPS_CONFLICT;
+ else if (CONST_STRNEQ (name, ".gptab."))
+ {
+ 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))
+ {
+ if ((abfd->flags & DYNAMIC) != 0)
+ hdr->sh_entsize = sizeof (Elf32_External_RegInfo);
+ else
+ hdr->sh_entsize = 1;
+ }
+ else
+ hdr->sh_entsize = sizeof (Elf32_External_RegInfo);
+ }
+ else if (SGI_COMPAT (abfd)
+ && (strcmp (name, ".hash") == 0
+ || strcmp (name, ".dynamic") == 0
+ || strcmp (name, ".dynstr") == 0))
+ {
+ if (SGI_COMPAT (abfd))
+ hdr->sh_entsize = 0;
+#if 0
+ /* This isn't how the IRIX6 linker behaves. */
+ hdr->sh_info = SIZEOF_MIPS_DYNSYM_SECNAMES;
+#endif
+ }
+ else if (strcmp (name, ".got") == 0
+ || strcmp (name, ".srdata") == 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 (CONST_STRNEQ (name, ".MIPS.content"))
+ {
+ hdr->sh_type = SHT_MIPS_CONTENT;
+ hdr->sh_flags |= SHF_MIPS_NOSTRIP;
+ /* The sh_info field is set in final_write_processing. */
+ }
+ else if (MIPS_ELF_OPTIONS_SECTION_NAME_P (name))
+ {
+ hdr->sh_type = SHT_MIPS_OPTIONS;
+ hdr->sh_entsize = 1;
+ hdr->sh_flags |= SHF_MIPS_NOSTRIP;
+ }
+ else if (CONST_STRNEQ (name, ".MIPS.abiflags"))
+ {
+ hdr->sh_type = SHT_MIPS_ABIFLAGS;
+ hdr->sh_entsize = sizeof (Elf_External_ABIFlags_v0);
+ }
+ else if (CONST_STRNEQ (name, ".debug_")
+ || CONST_STRNEQ (name, ".zdebug_"))
+ {
+ hdr->sh_type = SHT_MIPS_DWARF;
+
+ /* Irix facilities such as libexc expect a single .debug_frame
+ per executable, the system ones have NOSTRIP set and the linker
+ doesn't merge sections with different flags so ... */
+ if (SGI_COMPAT (abfd) && CONST_STRNEQ (name, ".debug_frame"))
+ hdr->sh_flags |= SHF_MIPS_NOSTRIP;
+ }
+ 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 (CONST_STRNEQ (name, ".MIPS.events")
+ || CONST_STRNEQ (name, ".MIPS.post_rel"))
+ {
+ hdr->sh_type = SHT_MIPS_EVENTS;
+ hdr->sh_flags |= SHF_MIPS_NOSTRIP;
+ /* The sh_link field is set in final_write_processing. */
+ }
+ else if (strcmp (name, ".msym") == 0)
+ {
+ hdr->sh_type = SHT_MIPS_MSYM;
+ hdr->sh_flags |= SHF_ALLOC;
+ hdr->sh_entsize = 8;
+ }
+
+ /* The generic elf_fake_sections will set up REL_HDR using the default
+ kind of relocations. We used to set up a second header for the
+ non-default kind of relocations here, but only NewABI would use
+ these, and the IRIX ld doesn't like resulting empty RELA sections.
+ Thus we create those header only on demand now. */
+
+ 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. */
+
+bfd_boolean
+_bfd_mips_elf_section_from_bfd_section (bfd *abfd ATTRIBUTE_UNUSED,
+ 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;
+}
+
+/* Hook called by the linker routine which adds symbols from an object
+ file. We must handle the special MIPS section numbers here. */
+
+bfd_boolean
+_bfd_mips_elf_add_symbol_hook (bfd *abfd, struct bfd_link_info *info,
+ Elf_Internal_Sym *sym, const char **namep,
+ flagword *flagsp ATTRIBUTE_UNUSED,
+ asection **secp, bfd_vma *valp)
+{
+ if (SGI_COMPAT (abfd)
+ && (abfd->flags & DYNAMIC) != 0
+ && strcmp (*namep, "_rld_new_interface") == 0)
+ {
+ /* Skip IRIX5 rld entry name. */
+ *namep = NULL;
+ return TRUE;
+ }
+
+ /* Shared objects may have a dynamic symbol '_gp_disp' defined as
+ a SECTION *ABS*. This causes ld to think it can resolve _gp_disp
+ by setting a DT_NEEDED for the shared object. Since _gp_disp is
+ a magic symbol resolved by the linker, we ignore this bogus definition
+ of _gp_disp. New ABI objects do not suffer from this problem so this
+ is not done for them. */
+ if (!NEWABI_P(abfd)
+ && (sym->st_shndx == SHN_ABS)
+ && (strcmp (*namep, "_gp_disp") == 0))
+ {
+ *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)
+ || ELF_ST_TYPE (sym->st_info) == STT_TLS
+ || IRIX_COMPAT (abfd) == ict_irix6)
+ 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_tdata (abfd)->elf_text_section == NULL)
+ {
+ asymbol *elf_text_symbol;
+ asection *elf_text_section;
+ bfd_size_type amt = sizeof (asection);
+
+ elf_text_section = bfd_zalloc (abfd, amt);
+ if (elf_text_section == NULL)
+ return FALSE;
+
+ amt = sizeof (asymbol);
+ elf_text_symbol = bfd_zalloc (abfd, amt);
+ if (elf_text_symbol == NULL)
+ return FALSE;
+
+ /* Initialize the section. */
+
+ mips_elf_tdata (abfd)->elf_text_section = elf_text_section;
+ mips_elf_tdata (abfd)->elf_text_symbol = elf_text_symbol;
+
+ elf_text_section->symbol = elf_text_symbol;
+ elf_text_section->symbol_ptr_ptr = &mips_elf_tdata (abfd)->elf_text_symbol;
+
+ elf_text_section->name = ".text";
+ elf_text_section->flags = SEC_NO_FLAGS;
+ elf_text_section->output_section = NULL;
+ elf_text_section->owner = abfd;
+ elf_text_symbol->name = ".text";
+ elf_text_symbol->flags = BSF_SECTION_SYM | BSF_DYNAMIC;
+ elf_text_symbol->section = 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_tdata (abfd)->elf_text_section;
+ 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_tdata (abfd)->elf_data_section == NULL)
+ {
+ asymbol *elf_data_symbol;
+ asection *elf_data_section;
+ bfd_size_type amt = sizeof (asection);
+
+ elf_data_section = bfd_zalloc (abfd, amt);
+ if (elf_data_section == NULL)
+ return FALSE;
+
+ amt = sizeof (asymbol);
+ elf_data_symbol = bfd_zalloc (abfd, amt);
+ if (elf_data_symbol == NULL)
+ return FALSE;
+
+ /* Initialize the section. */
+
+ mips_elf_tdata (abfd)->elf_data_section = elf_data_section;
+ mips_elf_tdata (abfd)->elf_data_symbol = elf_data_symbol;
+
+ elf_data_section->symbol = elf_data_symbol;
+ elf_data_section->symbol_ptr_ptr = &mips_elf_tdata (abfd)->elf_data_symbol;
+
+ elf_data_section->name = ".data";
+ elf_data_section->flags = SEC_NO_FLAGS;
+ elf_data_section->output_section = NULL;
+ elf_data_section->owner = abfd;
+ elf_data_symbol->name = ".data";
+ elf_data_symbol->flags = BSF_SECTION_SYM | BSF_DYNAMIC;
+ elf_data_symbol->section = 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_tdata (abfd)->elf_data_section;
+ break;
+
+ case SHN_MIPS_SUNDEFINED:
+ *secp = bfd_und_section_ptr;
+ break;
+ }
+
+ if (SGI_COMPAT (abfd)
+ && ! info->shared
+ && info->output_bfd->xvec == abfd->xvec
+ && strcmp (*namep, "__rld_obj_head") == 0)
+ {
+ struct elf_link_hash_entry *h;
+ struct bfd_link_hash_entry *bh;
+
+ /* Mark __rld_obj_head as dynamic. */
+ bh = NULL;
+ if (! (_bfd_generic_link_add_one_symbol
+ (info, abfd, *namep, BSF_GLOBAL, *secp, *valp, NULL, FALSE,
+ get_elf_backend_data (abfd)->collect, &bh)))
+ return FALSE;
+
+ h = (struct elf_link_hash_entry *) bh;
+ h->non_elf = 0;
+ h->def_regular = 1;
+ h->type = STT_OBJECT;
+
+ if (! bfd_elf_link_record_dynamic_symbol (info, h))
+ return FALSE;
+
+ mips_elf_hash_table (info)->use_rld_obj_head = TRUE;
+ mips_elf_hash_table (info)->rld_symbol = h;
+ }
+
+ /* 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 (ELF_ST_IS_COMPRESSED (sym->st_other))
+ ++*valp;
+
+ 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. */
+
+int
+_bfd_mips_elf_link_output_symbol_hook
+ (struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ const char *name ATTRIBUTE_UNUSED, Elf_Internal_Sym *sym,
+ asection *input_sec, struct elf_link_hash_entry *h ATTRIBUTE_UNUSED)
+{
+ /* 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 (ELF_ST_IS_COMPRESSED (sym->st_other))
+ sym->st_value &= ~1;
+
+ return 1;
+}
+
+/* Functions for the dynamic linker. */
+
+/* Create dynamic sections when linking against a dynamic object. */
+
+bfd_boolean
+_bfd_mips_elf_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
+{
+ struct elf_link_hash_entry *h;
+ struct bfd_link_hash_entry *bh;
+ flagword flags;
+ register asection *s;
+ const char * const *namep;
+ struct mips_elf_link_hash_table *htab;
+
+ htab = mips_elf_hash_table (info);
+ BFD_ASSERT (htab != NULL);
+
+ flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
+ | SEC_LINKER_CREATED | SEC_READONLY);
+
+ /* The psABI requires a read-only .dynamic section, but the VxWorks
+ EABI doesn't. */
+ if (!htab->is_vxworks)
+ {
+ s = bfd_get_linker_section (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;
+
+ if (! mips_elf_rel_dyn_section (info, TRUE))
+ return FALSE;
+
+ /* Create .stub section. */
+ s = bfd_make_section_anyway_with_flags (abfd,
+ MIPS_ELF_STUB_SECTION_NAME (abfd),
+ flags | SEC_CODE);
+ if (s == NULL
+ || ! bfd_set_section_alignment (abfd, s,
+ MIPS_ELF_LOG_FILE_ALIGN (abfd)))
+ return FALSE;
+ htab->sstubs = s;
+
+ if (!mips_elf_hash_table (info)->use_rld_obj_head
+ && !info->shared
+ && bfd_get_linker_section (abfd, ".rld_map") == NULL)
+ {
+ s = bfd_make_section_anyway_with_flags (abfd, ".rld_map",
+ flags &~ (flagword) SEC_READONLY);
+ if (s == NULL
+ || ! bfd_set_section_alignment (abfd, s,
+ MIPS_ELF_LOG_FILE_ALIGN (abfd)))
+ return FALSE;
+ }
+
+ /* On IRIX5, we adjust add some additional symbols and change the
+ alignments of several sections. There is no ABI documentation
+ indicating that this is necessary on IRIX6, nor any evidence that
+ the linker takes such action. */
+ if (IRIX_COMPAT (abfd) == ict_irix5)
+ {
+ for (namep = mips_elf_dynsym_rtproc_names; *namep != NULL; namep++)
+ {
+ bh = NULL;
+ if (! (_bfd_generic_link_add_one_symbol
+ (info, abfd, *namep, BSF_GLOBAL, bfd_und_section_ptr, 0,
+ NULL, FALSE, get_elf_backend_data (abfd)->collect, &bh)))
+ return FALSE;
+
+ h = (struct elf_link_hash_entry *) bh;
+ h->non_elf = 0;
+ h->def_regular = 1;
+ h->type = STT_SECTION;
+
+ if (! bfd_elf_link_record_dynamic_symbol (info, h))
+ return FALSE;
+ }
+
+ /* We need to create a .compact_rel section. */
+ if (SGI_COMPAT (abfd))
+ {
+ if (!mips_elf_create_compact_rel_section (abfd, info))
+ return FALSE;
+ }
+
+ /* Change alignments of some sections. */
+ s = bfd_get_linker_section (abfd, ".hash");
+ if (s != NULL)
+ (void) bfd_set_section_alignment (abfd, s, MIPS_ELF_LOG_FILE_ALIGN (abfd));
+
+ s = bfd_get_linker_section (abfd, ".dynsym");
+ if (s != NULL)
+ (void) bfd_set_section_alignment (abfd, s, MIPS_ELF_LOG_FILE_ALIGN (abfd));
+
+ s = bfd_get_linker_section (abfd, ".dynstr");
+ if (s != NULL)
+ (void) bfd_set_section_alignment (abfd, s, MIPS_ELF_LOG_FILE_ALIGN (abfd));
+
+ /* ??? */
+ s = bfd_get_section_by_name (abfd, ".reginfo");
+ if (s != NULL)
+ (void) bfd_set_section_alignment (abfd, s, MIPS_ELF_LOG_FILE_ALIGN (abfd));
+
+ s = bfd_get_linker_section (abfd, ".dynamic");
+ if (s != NULL)
+ (void) bfd_set_section_alignment (abfd, s, MIPS_ELF_LOG_FILE_ALIGN (abfd));
+ }
+
+ if (!info->shared)
+ {
+ const char *name;
+
+ name = SGI_COMPAT (abfd) ? "_DYNAMIC_LINK" : "_DYNAMIC_LINKING";
+ bh = NULL;
+ if (!(_bfd_generic_link_add_one_symbol
+ (info, abfd, name, BSF_GLOBAL, bfd_abs_section_ptr, 0,
+ NULL, FALSE, get_elf_backend_data (abfd)->collect, &bh)))
+ return FALSE;
+
+ h = (struct elf_link_hash_entry *) bh;
+ h->non_elf = 0;
+ h->def_regular = 1;
+ h->type = STT_SECTION;
+
+ if (! bfd_elf_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
+ _bfd_mips_elf_finish_dynamic_symbol. */
+ s = bfd_get_linker_section (abfd, ".rld_map");
+ BFD_ASSERT (s != NULL);
+
+ name = SGI_COMPAT (abfd) ? "__rld_map" : "__RLD_MAP";
+ bh = NULL;
+ if (!(_bfd_generic_link_add_one_symbol
+ (info, abfd, name, BSF_GLOBAL, s, 0, NULL, FALSE,
+ get_elf_backend_data (abfd)->collect, &bh)))
+ return FALSE;
+
+ h = (struct elf_link_hash_entry *) bh;
+ h->non_elf = 0;
+ h->def_regular = 1;
+ h->type = STT_OBJECT;
+
+ if (! bfd_elf_link_record_dynamic_symbol (info, h))
+ return FALSE;
+ mips_elf_hash_table (info)->rld_symbol = h;
+ }
+ }
+
+ /* Create the .plt, .rel(a).plt, .dynbss and .rel(a).bss sections.
+ Also, on VxWorks, create the _PROCEDURE_LINKAGE_TABLE_ symbol. */
+ if (!_bfd_elf_create_dynamic_sections (abfd, info))
+ return FALSE;
+
+ /* Cache the sections created above. */
+ htab->splt = bfd_get_linker_section (abfd, ".plt");
+ htab->sdynbss = bfd_get_linker_section (abfd, ".dynbss");
+ if (htab->is_vxworks)
+ {
+ htab->srelbss = bfd_get_linker_section (abfd, ".rela.bss");
+ htab->srelplt = bfd_get_linker_section (abfd, ".rela.plt");
+ }
+ else
+ htab->srelplt = bfd_get_linker_section (abfd, ".rel.plt");
+ if (!htab->sdynbss
+ || (htab->is_vxworks && !htab->srelbss && !info->shared)
+ || !htab->srelplt
+ || !htab->splt)
+ abort ();
+
+ /* Do the usual VxWorks handling. */
+ if (htab->is_vxworks
+ && !elf_vxworks_create_dynamic_sections (abfd, info, &htab->srelplt2))
+ return FALSE;
+
+ return TRUE;
+}
+
+/* Return true if relocation REL against section SEC is a REL rather than
+ RELA relocation. RELOCS is the first relocation in the section and
+ ABFD is the bfd that contains SEC. */
+
+static bfd_boolean
+mips_elf_rel_relocation_p (bfd *abfd, asection *sec,
+ const Elf_Internal_Rela *relocs,
+ const Elf_Internal_Rela *rel)
+{
+ Elf_Internal_Shdr *rel_hdr;
+ const struct elf_backend_data *bed;
+
+ /* To determine which flavor of relocation this is, we depend on the
+ fact that the INPUT_SECTION's REL_HDR is read before RELA_HDR. */
+ rel_hdr = elf_section_data (sec)->rel.hdr;
+ if (rel_hdr == NULL)
+ return FALSE;
+ bed = get_elf_backend_data (abfd);
+ return ((size_t) (rel - relocs)
+ < NUM_SHDR_ENTRIES (rel_hdr) * bed->s->int_rels_per_ext_rel);
+}
+
+/* Read the addend for REL relocation REL, which belongs to bfd ABFD.
+ HOWTO is the relocation's howto and CONTENTS points to the contents
+ of the section that REL is against. */
+
+static bfd_vma
+mips_elf_read_rel_addend (bfd *abfd, const Elf_Internal_Rela *rel,
+ reloc_howto_type *howto, bfd_byte *contents)
+{
+ bfd_byte *location;
+ unsigned int r_type;
+ bfd_vma addend;
+
+ r_type = ELF_R_TYPE (abfd, rel->r_info);
+ location = contents + rel->r_offset;
+
+ /* Get the addend, which is stored in the input file. */
+ _bfd_mips_elf_reloc_unshuffle (abfd, r_type, FALSE, location);
+ addend = mips_elf_obtain_contents (howto, rel, abfd, contents);
+ _bfd_mips_elf_reloc_shuffle (abfd, r_type, FALSE, location);
+
+ return addend & howto->src_mask;
+}
+
+/* REL is a relocation in ABFD that needs a partnering LO16 relocation
+ and *ADDEND is the addend for REL itself. Look for the LO16 relocation
+ and update *ADDEND with the final addend. Return true on success
+ or false if the LO16 could not be found. RELEND is the exclusive
+ upper bound on the relocations for REL's section. */
+
+static bfd_boolean
+mips_elf_add_lo16_rel_addend (bfd *abfd,
+ const Elf_Internal_Rela *rel,
+ const Elf_Internal_Rela *relend,
+ bfd_byte *contents, bfd_vma *addend)
+{
+ unsigned int r_type, lo16_type;
+ const Elf_Internal_Rela *lo16_relocation;
+ reloc_howto_type *lo16_howto;
+ bfd_vma l;
+
+ r_type = ELF_R_TYPE (abfd, rel->r_info);
+ if (mips16_reloc_p (r_type))
+ lo16_type = R_MIPS16_LO16;
+ else if (micromips_reloc_p (r_type))
+ lo16_type = R_MICROMIPS_LO16;
+ else if (r_type == R_MIPS_PCHI16)
+ lo16_type = R_MIPS_PCLO16;
+ else
+ lo16_type = R_MIPS_LO16;
+
+ /* The combined value is the sum of the HI16 addend, left-shifted by
+ sixteen bits, and the LO16 addend, sign extended. (Usually, the
+ code does a `lui' of the HI16 value, and then an `addiu' of the
+ LO16 value.)
+
+ Scan ahead to find a matching LO16 relocation.
+
+ According to the MIPS ELF ABI, the R_MIPS_LO16 relocation must
+ be immediately following. However, for the IRIX6 ABI, the next
+ relocation may be a composed relocation consisting of several
+ relocations for the same address. In that case, the R_MIPS_LO16
+ relocation may occur as one of these. We permit a similar
+ extension in general, as that is useful for GCC.
+
+ In some cases GCC dead code elimination removes the LO16 but keeps
+ the corresponding HI16. This is strictly speaking a violation of
+ the ABI but not immediately harmful. */
+ lo16_relocation = mips_elf_next_relocation (abfd, lo16_type, rel, relend);
+ if (lo16_relocation == NULL)
+ return FALSE;
+
+ /* Obtain the addend kept there. */
+ lo16_howto = MIPS_ELF_RTYPE_TO_HOWTO (abfd, lo16_type, FALSE);
+ l = mips_elf_read_rel_addend (abfd, lo16_relocation, lo16_howto, contents);
+
+ l <<= lo16_howto->rightshift;
+ l = _bfd_mips_elf_sign_extend (l, 16);
+
+ *addend <<= 16;
+ *addend += l;
+ return TRUE;
+}
+
+/* Try to read the contents of section SEC in bfd ABFD. Return true and
+ store the contents in *CONTENTS on success. Assume that *CONTENTS
+ already holds the contents if it is nonull on entry. */
+
+static bfd_boolean
+mips_elf_get_section_contents (bfd *abfd, asection *sec, bfd_byte **contents)
+{
+ if (*contents)
+ return TRUE;
+
+ /* Get cached copy if it exists. */
+ if (elf_section_data (sec)->this_hdr.contents != NULL)
+ {
+ *contents = elf_section_data (sec)->this_hdr.contents;
+ return TRUE;
+ }
+
+ return bfd_malloc_and_get_section (abfd, sec, contents);
+}
+
+/* Make a new PLT record to keep internal data. */
+
+static struct plt_entry *
+mips_elf_make_plt_record (bfd *abfd)
+{
+ struct plt_entry *entry;
+
+ entry = bfd_zalloc (abfd, sizeof (*entry));
+ if (entry == NULL)
+ return NULL;
+
+ entry->stub_offset = MINUS_ONE;
+ entry->mips_offset = MINUS_ONE;
+ entry->comp_offset = MINUS_ONE;
+ entry->gotplt_index = MINUS_ONE;
+ return entry;
+}
+
+/* Look through the relocs for a section during the first phase, and
+ allocate space in the global offset table and record the need for
+ standard MIPS and compressed procedure linkage table entries. */
+
+bfd_boolean
+_bfd_mips_elf_check_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;
+ size_t extsymoff;
+ const Elf_Internal_Rela *rel;
+ const Elf_Internal_Rela *rel_end;
+ asection *sreloc;
+ const struct elf_backend_data *bed;
+ struct mips_elf_link_hash_table *htab;
+ bfd_byte *contents;
+ bfd_vma addend;
+ reloc_howto_type *howto;
+
+ if (info->relocatable)
+ return TRUE;
+
+ htab = mips_elf_hash_table (info);
+ BFD_ASSERT (htab != NULL);
+
+ 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;
+
+ bed = get_elf_backend_data (abfd);
+ rel_end = relocs + sec->reloc_count * bed->s->int_rels_per_ext_rel;
+
+ /* Check for the mips16 stub sections. */
+
+ name = bfd_get_section_name (abfd, sec);
+ if (FN_STUB_P (name))
+ {
+ unsigned long r_symndx;
+
+ /* Look at the relocation information to figure out which symbol
+ this is for. */
+
+ r_symndx = mips16_stub_symndx (bed, sec, relocs, rel_end);
+ if (r_symndx == 0)
+ {
+ (*_bfd_error_handler)
+ (_("%B: Warning: cannot determine the target function for"
+ " stub section `%s'"),
+ abfd, name);
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+
+ 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
+ || section_allows_mips16_refs_p (o))
+ continue;
+
+ sec_relocs
+ = _bfd_elf_link_read_relocs (abfd, o, NULL, NULL,
+ info->keep_memory);
+ if (sec_relocs == NULL)
+ return FALSE;
+
+ rend = sec_relocs + o->reloc_count;
+ for (r = sec_relocs; r < rend; r++)
+ if (ELF_R_SYM (abfd, r->r_info) == r_symndx
+ && !mips16_call_reloc_p (ELF_R_TYPE (abfd, r->r_info)))
+ break;
+
+ if (elf_section_data (o)->relocs != sec_relocs)
+ 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 (mips_elf_tdata (abfd)->local_stubs == NULL)
+ {
+ unsigned long symcount;
+ asection **n;
+ bfd_size_type amt;
+
+ if (elf_bad_symtab (abfd))
+ symcount = NUM_SHDR_ENTRIES (symtab_hdr);
+ else
+ symcount = symtab_hdr->sh_info;
+ amt = symcount * sizeof (asection *);
+ n = bfd_zalloc (abfd, amt);
+ if (n == NULL)
+ return FALSE;
+ mips_elf_tdata (abfd)->local_stubs = n;
+ }
+
+ sec->flags |= SEC_KEEP;
+ mips_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]);
+
+ while (h->root.root.type == bfd_link_hash_indirect
+ || h->root.root.type == bfd_link_hash_warning)
+ h = (struct mips_elf_link_hash_entry *) h->root.root.u.i.link;
+
+ /* H is the symbol this stub is for. */
+
+ /* 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. */
+ if (h->fn_stub != NULL)
+ {
+ sec->flags |= SEC_EXCLUDE;
+ return TRUE;
+ }
+
+ sec->flags |= SEC_KEEP;
+ h->fn_stub = sec;
+ mips_elf_hash_table (info)->mips16_stubs_seen = TRUE;
+ }
+ }
+ else if (CALL_STUB_P (name) || CALL_FP_STUB_P (name))
+ {
+ 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 = mips16_stub_symndx (bed, sec, relocs, rel_end);
+ if (r_symndx == 0)
+ {
+ (*_bfd_error_handler)
+ (_("%B: Warning: cannot determine the target function for"
+ " stub section `%s'"),
+ abfd, name);
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+
+ 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 (R_MIPS16_26) in this BFD
+ that 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
+ || section_allows_mips16_refs_p (o))
+ continue;
+
+ sec_relocs
+ = _bfd_elf_link_read_relocs (abfd, o, NULL, NULL,
+ info->keep_memory);
+ if (sec_relocs == NULL)
+ return FALSE;
+
+ rend = sec_relocs + o->reloc_count;
+ for (r = sec_relocs; r < rend; r++)
+ if (ELF_R_SYM (abfd, r->r_info) == r_symndx
+ && ELF_R_TYPE (abfd, r->r_info) == R_MIPS16_26)
+ break;
+
+ if (elf_section_data (o)->relocs != sec_relocs)
+ 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 call_stubs for
+ this BFD. */
+ if (mips_elf_tdata (abfd)->local_call_stubs == NULL)
+ {
+ unsigned long symcount;
+ asection **n;
+ bfd_size_type amt;
+
+ if (elf_bad_symtab (abfd))
+ symcount = NUM_SHDR_ENTRIES (symtab_hdr);
+ else
+ symcount = symtab_hdr->sh_info;
+ amt = symcount * sizeof (asection *);
+ n = bfd_zalloc (abfd, amt);
+ if (n == NULL)
+ return FALSE;
+ mips_elf_tdata (abfd)->local_call_stubs = n;
+ }
+
+ sec->flags |= SEC_KEEP;
+ mips_elf_tdata (abfd)->local_call_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
+ {
+ h = ((struct mips_elf_link_hash_entry *)
+ sym_hashes[r_symndx - extsymoff]);
+
+ /* H is the symbol this stub is for. */
+
+ if (CALL_FP_STUB_P (name))
+ 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. */
+ if (*loc != NULL)
+ {
+ sec->flags |= SEC_EXCLUDE;
+ return TRUE;
+ }
+
+ sec->flags |= SEC_KEEP;
+ *loc = sec;
+ mips_elf_hash_table (info)->mips16_stubs_seen = TRUE;
+ }
+ }
+
+ sreloc = NULL;
+ contents = NULL;
+ for (rel = relocs; rel < rel_end; ++rel)
+ {
+ unsigned long r_symndx;
+ unsigned int r_type;
+ struct elf_link_hash_entry *h;
+ bfd_boolean can_make_dynamic_p;
+ bfd_boolean call_reloc_p;
+ bfd_boolean constrain_symbol_p;
+
+ r_symndx = ELF_R_SYM (abfd, rel->r_info);
+ r_type = ELF_R_TYPE (abfd, rel->r_info);
+
+ if (r_symndx < extsymoff)
+ h = NULL;
+ else if (r_symndx >= extsymoff + NUM_SHDR_ENTRIES (symtab_hdr))
+ {
+ (*_bfd_error_handler)
+ (_("%B: Malformed reloc detected for section %s"),
+ abfd, name);
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+ else
+ {
+ h = sym_hashes[r_symndx - extsymoff];
+ if (h != NULL)
+ {
+ 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;
+
+ /* PR15323, ref flags aren't set for references in the
+ same object. */
+ h->root.non_ir_ref = 1;
+ }
+ }
+
+ /* Set CAN_MAKE_DYNAMIC_P to true if we can convert this
+ relocation into a dynamic one. */
+ can_make_dynamic_p = FALSE;
+
+ /* Set CALL_RELOC_P to true if the relocation is for a call,
+ and if pointer equality therefore doesn't matter. */
+ call_reloc_p = FALSE;
+
+ /* Set CONSTRAIN_SYMBOL_P if we need to take the relocation
+ into account when deciding how to define the symbol.
+ Relocations in nonallocatable sections such as .pdr and
+ .debug* should have no effect. */
+ constrain_symbol_p = ((sec->flags & SEC_ALLOC) != 0);
+
+ switch (r_type)
+ {
+ case R_MIPS_CALL16:
+ case R_MIPS_CALL_HI16:
+ case R_MIPS_CALL_LO16:
+ case R_MIPS16_CALL16:
+ case R_MICROMIPS_CALL16:
+ case R_MICROMIPS_CALL_HI16:
+ case R_MICROMIPS_CALL_LO16:
+ call_reloc_p = TRUE;
+ /* Fall through. */
+
+ case R_MIPS_GOT16:
+ case R_MIPS_GOT_HI16:
+ case R_MIPS_GOT_LO16:
+ case R_MIPS_GOT_PAGE:
+ case R_MIPS_GOT_OFST:
+ case R_MIPS_GOT_DISP:
+ case R_MIPS_TLS_GOTTPREL:
+ case R_MIPS_TLS_GD:
+ case R_MIPS_TLS_LDM:
+ case R_MIPS16_GOT16:
+ case R_MIPS16_TLS_GOTTPREL:
+ case R_MIPS16_TLS_GD:
+ case R_MIPS16_TLS_LDM:
+ case R_MICROMIPS_GOT16:
+ case R_MICROMIPS_GOT_HI16:
+ case R_MICROMIPS_GOT_LO16:
+ case R_MICROMIPS_GOT_PAGE:
+ case R_MICROMIPS_GOT_OFST:
+ case R_MICROMIPS_GOT_DISP:
+ case R_MICROMIPS_TLS_GOTTPREL:
+ case R_MICROMIPS_TLS_GD:
+ case R_MICROMIPS_TLS_LDM:
+ if (dynobj == NULL)
+ elf_hash_table (info)->dynobj = dynobj = abfd;
+ if (!mips_elf_create_got_section (dynobj, info))
+ return FALSE;
+ if (htab->is_vxworks && !info->shared)
+ {
+ (*_bfd_error_handler)
+ (_("%B: GOT reloc at 0x%lx not expected in executables"),
+ abfd, (unsigned long) rel->r_offset);
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+ can_make_dynamic_p = TRUE;
+ break;
+
+ case R_MIPS_NONE:
+ case R_MIPS_JALR:
+ case R_MICROMIPS_JALR:
+ /* These relocations have empty fields and are purely there to
+ provide link information. The symbol value doesn't matter. */
+ constrain_symbol_p = FALSE;
+ break;
+
+ case R_MIPS_GPREL16:
+ case R_MIPS_GPREL32:
+ case R_MIPS16_GPREL:
+ case R_MICROMIPS_GPREL16:
+ /* GP-relative relocations always resolve to a definition in a
+ regular input file, ignoring the one-definition rule. This is
+ important for the GP setup sequence in NewABI code, which
+ always resolves to a local function even if other relocations
+ against the symbol wouldn't. */
+ constrain_symbol_p = FALSE;
+ break;
+
+ case R_MIPS_32:
+ case R_MIPS_REL32:
+ case R_MIPS_64:
+ /* In VxWorks executables, references to external symbols
+ must be handled using copy relocs or PLT entries; it is not
+ possible to convert this relocation into a dynamic one.
+
+ For executables that use PLTs and copy-relocs, we have a
+ choice between converting the relocation into a dynamic
+ one or using copy relocations or PLT entries. It is
+ usually better to do the former, unless the relocation is
+ against a read-only section. */
+ if ((info->shared
+ || (h != NULL
+ && !htab->is_vxworks
+ && strcmp (h->root.root.string, "__gnu_local_gp") != 0
+ && !(!info->nocopyreloc
+ && !PIC_OBJECT_P (abfd)
+ && MIPS_ELF_READONLY_SECTION (sec))))
+ && (sec->flags & SEC_ALLOC) != 0)
+ {
+ can_make_dynamic_p = TRUE;
+ if (dynobj == NULL)
+ elf_hash_table (info)->dynobj = dynobj = abfd;
+ }
+ break;
+
+ case R_MIPS_26:
+ case R_MIPS_PC16:
+ case R_MIPS_PC21_S2:
+ case R_MIPS_PC26_S2:
+ case R_MIPS16_26:
+ case R_MICROMIPS_26_S1:
+ case R_MICROMIPS_PC7_S1:
+ case R_MICROMIPS_PC10_S1:
+ case R_MICROMIPS_PC16_S1:
+ case R_MICROMIPS_PC23_S2:
+ call_reloc_p = TRUE;
+ break;
+ }
+
+ if (h)
+ {
+ if (constrain_symbol_p)
+ {
+ if (!can_make_dynamic_p)
+ ((struct mips_elf_link_hash_entry *) h)->has_static_relocs = 1;
+
+ if (!call_reloc_p)
+ h->pointer_equality_needed = 1;
+
+ /* We must not create a stub for a symbol that has
+ relocations related to taking the function's address.
+ This doesn't apply to VxWorks, where CALL relocs refer
+ to a .got.plt entry instead of a normal .got entry. */
+ if (!htab->is_vxworks && (!can_make_dynamic_p || !call_reloc_p))
+ ((struct mips_elf_link_hash_entry *) h)->no_fn_stub = TRUE;
+ }
+
+ /* Relocations against the special VxWorks __GOTT_BASE__ and
+ __GOTT_INDEX__ symbols must be left to the loader. Allocate
+ room for them in .rela.dyn. */
+ if (is_gott_symbol (info, h))
+ {
+ if (sreloc == NULL)
+ {
+ sreloc = mips_elf_rel_dyn_section (info, TRUE);
+ if (sreloc == NULL)
+ return FALSE;
+ }
+ mips_elf_allocate_dynamic_relocations (dynobj, info, 1);
+ if (MIPS_ELF_READONLY_SECTION (sec))
+ /* We tell the dynamic linker that there are
+ relocations against the text segment. */
+ info->flags |= DF_TEXTREL;
+ }
+ }
+ else if (call_lo16_reloc_p (r_type)
+ || got_lo16_reloc_p (r_type)
+ || got_disp_reloc_p (r_type)
+ || (got16_reloc_p (r_type) && htab->is_vxworks))
+ {
+ /* We may need a local GOT entry for this relocation. We
+ don't count R_MIPS_GOT_PAGE because we can estimate the
+ maximum number of pages needed by looking at the size of
+ the segment. Similar comments apply to R_MIPS*_GOT16 and
+ R_MIPS*_CALL16, except on VxWorks, where GOT relocations
+ always evaluate to "G". We don't count R_MIPS_GOT_HI16, or
+ R_MIPS_CALL_HI16 because these are always followed by an
+ R_MIPS_GOT_LO16 or R_MIPS_CALL_LO16. */
+ if (!mips_elf_record_local_got_symbol (abfd, r_symndx,
+ rel->r_addend, info, r_type))
+ return FALSE;
+ }
+
+ if (h != NULL
+ && mips_elf_relocation_needs_la25_stub (abfd, r_type,
+ ELF_ST_IS_MIPS16 (h->other)))
+ ((struct mips_elf_link_hash_entry *) h)->has_nonpic_branches = TRUE;
+
+ switch (r_type)
+ {
+ case R_MIPS_CALL16:
+ case R_MIPS16_CALL16:
+ case R_MICROMIPS_CALL16:
+ if (h == NULL)
+ {
+ (*_bfd_error_handler)
+ (_("%B: CALL16 reloc at 0x%lx not against global symbol"),
+ abfd, (unsigned long) rel->r_offset);
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+ /* Fall through. */
+
+ case R_MIPS_CALL_HI16:
+ case R_MIPS_CALL_LO16:
+ case R_MICROMIPS_CALL_HI16:
+ case R_MICROMIPS_CALL_LO16:
+ if (h != NULL)
+ {
+ /* Make sure there is room in the regular GOT to hold the
+ function's address. We may eliminate it in favour of
+ a .got.plt entry later; see mips_elf_count_got_symbols. */
+ if (!mips_elf_record_global_got_symbol (h, abfd, info, TRUE,
+ r_type))
+ return FALSE;
+
+ /* We need a stub, not a plt entry for the undefined
+ function. But we record it as if it needs plt. See
+ _bfd_elf_adjust_dynamic_symbol. */
+ h->needs_plt = 1;
+ h->type = STT_FUNC;
+ }
+ break;
+
+ case R_MIPS_GOT_PAGE:
+ case R_MICROMIPS_GOT_PAGE:
+ case R_MIPS16_GOT16:
+ case R_MIPS_GOT16:
+ case R_MIPS_GOT_HI16:
+ case R_MIPS_GOT_LO16:
+ case R_MICROMIPS_GOT16:
+ case R_MICROMIPS_GOT_HI16:
+ case R_MICROMIPS_GOT_LO16:
+ if (!h || got_page_reloc_p (r_type))
+ {
+ /* This relocation needs (or may need, if h != NULL) a
+ page entry in the GOT. For R_MIPS_GOT_PAGE we do not
+ know for sure until we know whether the symbol is
+ preemptible. */
+ if (mips_elf_rel_relocation_p (abfd, sec, relocs, rel))
+ {
+ if (!mips_elf_get_section_contents (abfd, sec, &contents))
+ return FALSE;
+ howto = MIPS_ELF_RTYPE_TO_HOWTO (abfd, r_type, FALSE);
+ addend = mips_elf_read_rel_addend (abfd, rel,
+ howto, contents);
+ if (got16_reloc_p (r_type))
+ mips_elf_add_lo16_rel_addend (abfd, rel, rel_end,
+ contents, &addend);
+ else
+ addend <<= howto->rightshift;
+ }
+ else
+ addend = rel->r_addend;
+ if (!mips_elf_record_got_page_ref (info, abfd, r_symndx,
+ h, addend))
+ return FALSE;
+
+ if (h)
+ {
+ struct mips_elf_link_hash_entry *hmips =
+ (struct mips_elf_link_hash_entry *) h;
+
+ /* This symbol is definitely not overridable. */
+ if (hmips->root.def_regular
+ && ! (info->shared && ! info->symbolic
+ && ! hmips->root.forced_local))
+ h = NULL;
+ }
+ }
+ /* If this is a global, overridable symbol, GOT_PAGE will
+ decay to GOT_DISP, so we'll need a GOT entry for it. */
+ /* Fall through. */
+
+ case R_MIPS_GOT_DISP:
+ case R_MICROMIPS_GOT_DISP:
+ if (h && !mips_elf_record_global_got_symbol (h, abfd, info,
+ FALSE, r_type))
+ return FALSE;
+ break;
+
+ case R_MIPS_TLS_GOTTPREL:
+ case R_MIPS16_TLS_GOTTPREL:
+ case R_MICROMIPS_TLS_GOTTPREL:
+ if (info->shared)
+ info->flags |= DF_STATIC_TLS;
+ /* Fall through */
+
+ case R_MIPS_TLS_LDM:
+ case R_MIPS16_TLS_LDM:
+ case R_MICROMIPS_TLS_LDM:
+ if (tls_ldm_reloc_p (r_type))
+ {
+ r_symndx = STN_UNDEF;
+ h = NULL;
+ }
+ /* Fall through */
+
+ case R_MIPS_TLS_GD:
+ case R_MIPS16_TLS_GD:
+ case R_MICROMIPS_TLS_GD:
+ /* This symbol requires a global offset table entry, or two
+ for TLS GD relocations. */
+ if (h != NULL)
+ {
+ if (!mips_elf_record_global_got_symbol (h, abfd, info,
+ FALSE, r_type))
+ return FALSE;
+ }
+ else
+ {
+ if (!mips_elf_record_local_got_symbol (abfd, r_symndx,
+ rel->r_addend,
+ info, r_type))
+ return FALSE;
+ }
+ break;
+
+ case R_MIPS_32:
+ case R_MIPS_REL32:
+ case R_MIPS_64:
+ /* In VxWorks executables, references to external symbols
+ are handled using copy relocs or PLT stubs, so there's
+ no need to add a .rela.dyn entry for this relocation. */
+ if (can_make_dynamic_p)
+ {
+ if (sreloc == NULL)
+ {
+ sreloc = mips_elf_rel_dyn_section (info, TRUE);
+ if (sreloc == NULL)
+ return FALSE;
+ }
+ if (info->shared && h == NULL)
+ {
+ /* When creating a shared object, we must copy these
+ reloc types into the output file as R_MIPS_REL32
+ relocs. Make room for this reloc in .rel(a).dyn. */
+ mips_elf_allocate_dynamic_relocations (dynobj, info, 1);
+ if (MIPS_ELF_READONLY_SECTION (sec))
+ /* We tell the dynamic linker that there are
+ relocations against the text segment. */
+ info->flags |= DF_TEXTREL;
+ }
+ else
+ {
+ struct mips_elf_link_hash_entry *hmips;
+
+ /* For a shared object, we must copy this relocation
+ unless the symbol turns out to be undefined and
+ weak with non-default visibility, in which case
+ it will be left as zero.
+
+ We could elide R_MIPS_REL32 for locally binding symbols
+ in shared libraries, but do not yet do so.
+
+ For an executable, 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->possibly_dynamic_relocs;
+ if (MIPS_ELF_READONLY_SECTION (sec))
+ /* We need it to tell the dynamic linker if there
+ are relocations against the text segment. */
+ hmips->readonly_reloc = TRUE;
+ }
+ }
+
+ 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:
+ case R_MICROMIPS_26_S1:
+ case R_MICROMIPS_GPREL16:
+ case R_MICROMIPS_LITERAL:
+ case R_MICROMIPS_GPREL7_S2:
+ 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_elf_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:
+ BFD_ASSERT (h != NULL);
+ if (h != NULL
+ && !bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_offset))
+ return FALSE;
+ break;
+
+ default:
+ break;
+ }
+
+ /* Record the need for a PLT entry. At this point we don't know
+ yet if we are going to create a PLT in the first place, but
+ we only record whether the relocation requires a standard MIPS
+ or a compressed code entry anyway. If we don't make a PLT after
+ all, then we'll just ignore these arrangements. Likewise if
+ a PLT entry is not created because the symbol is satisfied
+ locally. */
+ if (h != NULL
+ && jal_reloc_p (r_type)
+ && !SYMBOL_CALLS_LOCAL (info, h))
+ {
+ if (h->plt.plist == NULL)
+ h->plt.plist = mips_elf_make_plt_record (abfd);
+ if (h->plt.plist == NULL)
+ return FALSE;
+
+ if (r_type == R_MIPS_26)
+ h->plt.plist->need_mips = TRUE;
+ else
+ h->plt.plist->need_comp = TRUE;
+ }
+
+ /* See if this reloc would need to refer to a MIPS16 hard-float stub,
+ if there is one. We only need to handle global symbols here;
+ we decide whether to keep or delete stubs for local symbols
+ when processing the stub's relocations. */
+ if (h != NULL
+ && !mips16_call_reloc_p (r_type)
+ && !section_allows_mips16_refs_p (sec))
+ {
+ struct mips_elf_link_hash_entry *mh;
+
+ mh = (struct mips_elf_link_hash_entry *) h;
+ mh->need_fn_stub = TRUE;
+ }
+
+ /* Refuse some position-dependent relocations when creating a
+ shared library. Do not refuse R_MIPS_32 / R_MIPS_64; they're
+ not PIC, but we can create dynamic relocations and the result
+ will be fine. Also do not refuse R_MIPS_LO16, which can be
+ combined with R_MIPS_GOT16. */
+ if (info->shared)
+ {
+ switch (r_type)
+ {
+ case R_MIPS16_HI16:
+ case R_MIPS_HI16:
+ case R_MIPS_HIGHER:
+ case R_MIPS_HIGHEST:
+ case R_MICROMIPS_HI16:
+ case R_MICROMIPS_HIGHER:
+ case R_MICROMIPS_HIGHEST:
+ /* Don't refuse a high part relocation if it's against
+ no symbol (e.g. part of a compound relocation). */
+ if (r_symndx == STN_UNDEF)
+ break;
+
+ /* R_MIPS_HI16 against _gp_disp is used for $gp setup,
+ and has a special meaning. */
+ if (!NEWABI_P (abfd) && h != NULL
+ && strcmp (h->root.root.string, "_gp_disp") == 0)
+ break;
+
+ /* Likewise __GOTT_BASE__ and __GOTT_INDEX__ on VxWorks. */
+ if (is_gott_symbol (info, h))
+ break;
+
+ /* FALLTHROUGH */
+
+ case R_MIPS16_26:
+ case R_MIPS_26:
+ case R_MICROMIPS_26_S1:
+ howto = MIPS_ELF_RTYPE_TO_HOWTO (abfd, r_type, FALSE);
+ (*_bfd_error_handler)
+ (_("%B: relocation %s against `%s' can not be used when making a shared object; recompile with -fPIC"),
+ abfd, howto->name,
+ (h) ? h->root.root.string : "a local symbol");
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ default:
+ break;
+ }
+ }
+ }
+
+ return TRUE;
+}
+
+bfd_boolean
+_bfd_mips_relax_section (bfd *abfd, asection *sec,
+ struct bfd_link_info *link_info,
+ bfd_boolean *again)
+{
+ Elf_Internal_Rela *internal_relocs;
+ Elf_Internal_Rela *irel, *irelend;
+ Elf_Internal_Shdr *symtab_hdr;
+ bfd_byte *contents = NULL;
+ size_t extsymoff;
+ bfd_boolean changed_contents = FALSE;
+ bfd_vma sec_start = sec->output_section->vma + sec->output_offset;
+ Elf_Internal_Sym *isymbuf = NULL;
+
+ /* We are not currently changing any sizes, so only one pass. */
+ *again = FALSE;
+
+ if (link_info->relocatable)
+ return TRUE;
+
+ internal_relocs = _bfd_elf_link_read_relocs (abfd, sec, NULL, NULL,
+ link_info->keep_memory);
+ if (internal_relocs == NULL)
+ return TRUE;
+
+ irelend = internal_relocs + sec->reloc_count
+ * get_elf_backend_data (abfd)->s->int_rels_per_ext_rel;
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+ extsymoff = (elf_bad_symtab (abfd)) ? 0 : symtab_hdr->sh_info;
+
+ for (irel = internal_relocs; irel < irelend; irel++)
+ {
+ bfd_vma symval;
+ bfd_signed_vma sym_offset;
+ unsigned int r_type;
+ unsigned long r_symndx;
+ asection *sym_sec;
+ unsigned long instruction;
+
+ /* Turn jalr into bgezal, and jr into beq, if they're marked
+ with a JALR relocation, that indicate where they jump to.
+ This saves some pipeline bubbles. */
+ r_type = ELF_R_TYPE (abfd, irel->r_info);
+ if (r_type != R_MIPS_JALR)
+ continue;
+
+ r_symndx = ELF_R_SYM (abfd, irel->r_info);
+ /* Compute the address of the jump target. */
+ if (r_symndx >= extsymoff)
+ {
+ struct mips_elf_link_hash_entry *h
+ = ((struct mips_elf_link_hash_entry *)
+ elf_sym_hashes (abfd) [r_symndx - extsymoff]);
+
+ while (h->root.root.type == bfd_link_hash_indirect
+ || h->root.root.type == bfd_link_hash_warning)
+ h = (struct mips_elf_link_hash_entry *) h->root.root.u.i.link;
+
+ /* If a symbol is undefined, or if it may be overridden,
+ skip it. */
+ if (! ((h->root.root.type == bfd_link_hash_defined
+ || h->root.root.type == bfd_link_hash_defweak)
+ && h->root.root.u.def.section)
+ || (link_info->shared && ! link_info->symbolic
+ && !h->root.forced_local))
+ continue;
+
+ sym_sec = h->root.root.u.def.section;
+ if (sym_sec->output_section)
+ symval = (h->root.root.u.def.value
+ + sym_sec->output_section->vma
+ + sym_sec->output_offset);
+ else
+ symval = h->root.root.u.def.value;
+ }
+ else
+ {
+ Elf_Internal_Sym *isym;
+
+ /* Read this BFD's symbols if we haven't done so already. */
+ if (isymbuf == NULL && symtab_hdr->sh_info != 0)
+ {
+ isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
+ if (isymbuf == NULL)
+ isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
+ symtab_hdr->sh_info, 0,
+ NULL, NULL, NULL);
+ if (isymbuf == NULL)
+ goto relax_return;
+ }
+
+ isym = isymbuf + r_symndx;
+ if (isym->st_shndx == SHN_UNDEF)
+ continue;
+ 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;
+ else
+ sym_sec
+ = bfd_section_from_elf_index (abfd, isym->st_shndx);
+ symval = isym->st_value
+ + sym_sec->output_section->vma
+ + sym_sec->output_offset;
+ }
+
+ /* Compute branch offset, from delay slot of the jump to the
+ branch target. */
+ sym_offset = (symval + irel->r_addend)
+ - (sec_start + irel->r_offset + 4);
+
+ /* Branch offset must be properly aligned. */
+ if ((sym_offset & 3) != 0)
+ continue;
+
+ sym_offset >>= 2;
+
+ /* Check that it's in range. */
+ if (sym_offset < -0x8000 || sym_offset >= 0x8000)
+ continue;
+
+ /* Get the section contents if we haven't done so already. */
+ if (!mips_elf_get_section_contents (abfd, sec, &contents))
+ goto relax_return;
+
+ instruction = bfd_get_32 (abfd, contents + irel->r_offset);
+
+ /* If it was jalr <reg>, turn it into bgezal $zero, <target>. */
+ if ((instruction & 0xfc1fffff) == 0x0000f809)
+ instruction = 0x04110000;
+ /* If it was jr <reg>, turn it into b <target>. */
+ else if ((instruction & 0xfc1fffff) == 0x00000008)
+ instruction = 0x10000000;
+ else
+ continue;
+
+ instruction |= (sym_offset & 0xffff);
+ bfd_put_32 (abfd, instruction, contents + irel->r_offset);
+ changed_contents = TRUE;
+ }
+
+ if (contents != NULL
+ && elf_section_data (sec)->this_hdr.contents != contents)
+ {
+ if (!changed_contents && !link_info->keep_memory)
+ free (contents);
+ else
+ {
+ /* Cache the section contents for elf_link_input_bfd. */
+ elf_section_data (sec)->this_hdr.contents = contents;
+ }
+ }
+ return TRUE;
+
+ relax_return:
+ if (contents != NULL
+ && elf_section_data (sec)->this_hdr.contents != contents)
+ free (contents);
+ return FALSE;
+}
+
+/* Allocate space for global sym dynamic relocs. */
+
+static bfd_boolean
+allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
+{
+ struct bfd_link_info *info = inf;
+ bfd *dynobj;
+ struct mips_elf_link_hash_entry *hmips;
+ struct mips_elf_link_hash_table *htab;
+
+ htab = mips_elf_hash_table (info);
+ BFD_ASSERT (htab != NULL);
+
+ dynobj = elf_hash_table (info)->dynobj;
+ hmips = (struct mips_elf_link_hash_entry *) h;
+
+ /* VxWorks executables are handled elsewhere; we only need to
+ allocate relocations in shared objects. */
+ if (htab->is_vxworks && !info->shared)
+ return TRUE;
+
+ /* Ignore indirect symbols. All relocations against such symbols
+ will be redirected to the target symbol. */
+ if (h->root.type == bfd_link_hash_indirect)
+ return TRUE;
+
+ /* If this symbol is defined in a dynamic object, or we are creating
+ a shared library, we will need to copy any R_MIPS_32 or
+ R_MIPS_REL32 relocs against it into the output file. */
+ if (! info->relocatable
+ && hmips->possibly_dynamic_relocs != 0
+ && (h->root.type == bfd_link_hash_defweak
+ || (!h->def_regular && !ELF_COMMON_DEF_P (h))
+ || info->shared))
+ {
+ bfd_boolean do_copy = TRUE;
+
+ if (h->root.type == bfd_link_hash_undefweak)
+ {
+ /* Do not copy relocations for undefined weak symbols with
+ non-default visibility. */
+ if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
+ do_copy = FALSE;
+
+ /* Make sure undefined weak symbols are output as a dynamic
+ symbol in PIEs. */
+ else if (h->dynindx == -1 && !h->forced_local)
+ {
+ if (! bfd_elf_link_record_dynamic_symbol (info, h))
+ return FALSE;
+ }
+ }
+
+ if (do_copy)
+ {
+ /* Even though we don't directly need a GOT entry for this symbol,
+ the SVR4 psABI requires it to have a dynamic symbol table
+ index greater that DT_MIPS_GOTSYM if there are dynamic
+ relocations against it.
+
+ VxWorks does not enforce the same mapping between the GOT
+ and the symbol table, so the same requirement does not
+ apply there. */
+ if (!htab->is_vxworks)
+ {
+ if (hmips->global_got_area > GGA_RELOC_ONLY)
+ hmips->global_got_area = GGA_RELOC_ONLY;
+ hmips->got_only_for_calls = FALSE;
+ }
+
+ mips_elf_allocate_dynamic_relocations
+ (dynobj, info, hmips->possibly_dynamic_relocs);
+ if (hmips->readonly_reloc)
+ /* We tell the dynamic linker that there are relocations
+ against the text segment. */
+ info->flags |= DF_TEXTREL;
+ }
+ }
+
+ 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. */
+
+bfd_boolean
+_bfd_mips_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
+ struct elf_link_hash_entry *h)
+{
+ bfd *dynobj;
+ struct mips_elf_link_hash_entry *hmips;
+ struct mips_elf_link_hash_table *htab;
+
+ htab = mips_elf_hash_table (info);
+ BFD_ASSERT (htab != NULL);
+
+ dynobj = elf_hash_table (info)->dynobj;
+ hmips = (struct mips_elf_link_hash_entry *) h;
+
+ /* Make sure we know what is going on here. */
+ BFD_ASSERT (dynobj != NULL
+ && (h->needs_plt
+ || h->u.weakdef != NULL
+ || (h->def_dynamic
+ && h->ref_regular
+ && !h->def_regular)));
+
+ hmips = (struct mips_elf_link_hash_entry *) h;
+
+ /* If there are call relocations against an externally-defined symbol,
+ see whether we can create a MIPS lazy-binding stub for it. We can
+ only do this if all references to the function are through call
+ relocations, and in that case, the traditional lazy-binding stubs
+ are much more efficient than PLT entries.
+
+ Traditional stubs are only available on SVR4 psABI-based systems;
+ VxWorks always uses PLTs instead. */
+ if (!htab->is_vxworks && h->needs_plt && !hmips->no_fn_stub)
+ {
+ 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->def_regular)
+ {
+ hmips->needs_lazy_stub = TRUE;
+ htab->lazy_stub_count++;
+ return TRUE;
+ }
+ }
+ /* As above, VxWorks requires PLT entries for externally-defined
+ functions that are only accessed through call relocations.
+
+ Both VxWorks and non-VxWorks targets also need PLT entries if there
+ are static-only relocations against an externally-defined function.
+ This can technically occur for shared libraries if there are
+ branches to the symbol, although it is unlikely that this will be
+ used in practice due to the short ranges involved. It can occur
+ for any relative or absolute relocation in executables; in that
+ case, the PLT entry becomes the function's canonical address. */
+ else if (((h->needs_plt && !hmips->no_fn_stub)
+ || (h->type == STT_FUNC && hmips->has_static_relocs))
+ && htab->use_plts_and_copy_relocs
+ && !SYMBOL_CALLS_LOCAL (info, h)
+ && !(ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
+ && h->root.type == bfd_link_hash_undefweak))
+ {
+ bfd_boolean micromips_p = MICROMIPS_P (info->output_bfd);
+ bfd_boolean newabi_p = NEWABI_P (info->output_bfd);
+
+ /* If this is the first symbol to need a PLT entry, then make some
+ basic setup. Also work out PLT entry sizes. We'll need them
+ for PLT offset calculations. */
+ if (htab->plt_mips_offset + htab->plt_comp_offset == 0)
+ {
+ BFD_ASSERT (htab->sgotplt->size == 0);
+ BFD_ASSERT (htab->plt_got_index == 0);
+
+ /* If we're using the PLT additions to the psABI, each PLT
+ entry is 16 bytes and the PLT0 entry is 32 bytes.
+ Encourage better cache usage by aligning. We do this
+ lazily to avoid pessimizing traditional objects. */
+ if (!htab->is_vxworks
+ && !bfd_set_section_alignment (dynobj, htab->splt, 5))
+ return FALSE;
+
+ /* Make sure that .got.plt is word-aligned. We do this lazily
+ for the same reason as above. */
+ if (!bfd_set_section_alignment (dynobj, htab->sgotplt,
+ MIPS_ELF_LOG_FILE_ALIGN (dynobj)))
+ return FALSE;
+
+ /* On non-VxWorks targets, the first two entries in .got.plt
+ are reserved. */
+ if (!htab->is_vxworks)
+ htab->plt_got_index
+ += (get_elf_backend_data (dynobj)->got_header_size
+ / MIPS_ELF_GOT_SIZE (dynobj));
+
+ /* On VxWorks, also allocate room for the header's
+ .rela.plt.unloaded entries. */
+ if (htab->is_vxworks && !info->shared)
+ htab->srelplt2->size += 2 * sizeof (Elf32_External_Rela);
+
+ /* Now work out the sizes of individual PLT entries. */
+ if (htab->is_vxworks && info->shared)
+ htab->plt_mips_entry_size
+ = 4 * ARRAY_SIZE (mips_vxworks_shared_plt_entry);
+ else if (htab->is_vxworks)
+ htab->plt_mips_entry_size
+ = 4 * ARRAY_SIZE (mips_vxworks_exec_plt_entry);
+ else if (newabi_p)
+ htab->plt_mips_entry_size
+ = 4 * ARRAY_SIZE (mips_exec_plt_entry);
+ else if (!micromips_p)
+ {
+ htab->plt_mips_entry_size
+ = 4 * ARRAY_SIZE (mips_exec_plt_entry);
+ htab->plt_comp_entry_size
+ = 2 * ARRAY_SIZE (mips16_o32_exec_plt_entry);
+ }
+ else if (htab->insn32)
+ {
+ htab->plt_mips_entry_size
+ = 4 * ARRAY_SIZE (mips_exec_plt_entry);
+ htab->plt_comp_entry_size
+ = 2 * ARRAY_SIZE (micromips_insn32_o32_exec_plt_entry);
+ }
+ else
+ {
+ htab->plt_mips_entry_size
+ = 4 * ARRAY_SIZE (mips_exec_plt_entry);
+ htab->plt_comp_entry_size
+ = 2 * ARRAY_SIZE (micromips_o32_exec_plt_entry);
+ }
+ }
+
+ if (h->plt.plist == NULL)
+ h->plt.plist = mips_elf_make_plt_record (dynobj);
+ if (h->plt.plist == NULL)
+ return FALSE;
+
+ /* There are no defined MIPS16 or microMIPS PLT entries for VxWorks,
+ n32 or n64, so always use a standard entry there.
+
+ If the symbol has a MIPS16 call stub and gets a PLT entry, then
+ all MIPS16 calls will go via that stub, and there is no benefit
+ to having a MIPS16 entry. And in the case of call_stub a
+ standard entry actually has to be used as the stub ends with a J
+ instruction. */
+ if (newabi_p
+ || htab->is_vxworks
+ || hmips->call_stub
+ || hmips->call_fp_stub)
+ {
+ h->plt.plist->need_mips = TRUE;
+ h->plt.plist->need_comp = FALSE;
+ }
+
+ /* Otherwise, if there are no direct calls to the function, we
+ have a free choice of whether to use standard or compressed
+ entries. Prefer microMIPS entries if the object is known to
+ contain microMIPS code, so that it becomes possible to create
+ pure microMIPS binaries. Prefer standard entries otherwise,
+ because MIPS16 ones are no smaller and are usually slower. */
+ if (!h->plt.plist->need_mips && !h->plt.plist->need_comp)
+ {
+ if (micromips_p)
+ h->plt.plist->need_comp = TRUE;
+ else
+ h->plt.plist->need_mips = TRUE;
+ }
+
+ if (h->plt.plist->need_mips)
+ {
+ h->plt.plist->mips_offset = htab->plt_mips_offset;
+ htab->plt_mips_offset += htab->plt_mips_entry_size;
+ }
+ if (h->plt.plist->need_comp)
+ {
+ h->plt.plist->comp_offset = htab->plt_comp_offset;
+ htab->plt_comp_offset += htab->plt_comp_entry_size;
+ }
+
+ /* Reserve the corresponding .got.plt entry now too. */
+ h->plt.plist->gotplt_index = htab->plt_got_index++;
+
+ /* If the output file has no definition of the symbol, set the
+ symbol's value to the address of the stub. */
+ if (!info->shared && !h->def_regular)
+ hmips->use_plt_entry = TRUE;
+
+ /* Make room for the R_MIPS_JUMP_SLOT relocation. */
+ htab->srelplt->size += (htab->is_vxworks
+ ? MIPS_ELF_RELA_SIZE (dynobj)
+ : MIPS_ELF_REL_SIZE (dynobj));
+
+ /* Make room for the .rela.plt.unloaded relocations. */
+ if (htab->is_vxworks && !info->shared)
+ htab->srelplt2->size += 3 * sizeof (Elf32_External_Rela);
+
+ /* All relocations against this symbol that could have been made
+ dynamic will now refer to the PLT entry instead. */
+ hmips->possibly_dynamic_relocs = 0;
+
+ 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->u.weakdef != NULL)
+ {
+ BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
+ || h->u.weakdef->root.type == bfd_link_hash_defweak);
+ h->root.u.def.section = h->u.weakdef->root.u.def.section;
+ h->root.u.def.value = h->u.weakdef->root.u.def.value;
+ return TRUE;
+ }
+
+ /* Otherwise, there is nothing further to do for symbols defined
+ in regular objects. */
+ if (h->def_regular)
+ return TRUE;
+
+ /* There's also nothing more to do if we'll convert all relocations
+ against this symbol into dynamic relocations. */
+ if (!hmips->has_static_relocs)
+ return TRUE;
+
+ /* We're now relying on copy relocations. Complain if we have
+ some that we can't convert. */
+ if (!htab->use_plts_and_copy_relocs || info->shared)
+ {
+ (*_bfd_error_handler) (_("non-dynamic relocations refer to "
+ "dynamic symbol %s"),
+ h->root.root.string);
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+
+ /* 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. */
+
+ if ((h->root.u.def.section->flags & SEC_ALLOC) != 0)
+ {
+ if (htab->is_vxworks)
+ htab->srelbss->size += sizeof (Elf32_External_Rela);
+ else
+ mips_elf_allocate_dynamic_relocations (dynobj, info, 1);
+ h->needs_copy = 1;
+ }
+
+ /* All relocations against this symbol that could have been made
+ dynamic will now refer to the local copy instead. */
+ hmips->possibly_dynamic_relocs = 0;
+
+ return _bfd_elf_adjust_dynamic_copy (h, htab->sdynbss);
+}
+
+/* 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. */
+
+bfd_boolean
+_bfd_mips_elf_always_size_sections (bfd *output_bfd,
+ struct bfd_link_info *info)
+{
+ asection *sect;
+ struct mips_elf_link_hash_table *htab;
+ struct mips_htab_traverse_info hti;
+
+ htab = mips_elf_hash_table (info);
+ BFD_ASSERT (htab != NULL);
+
+ /* The .reginfo section has a fixed size. */
+ sect = bfd_get_section_by_name (output_bfd, ".reginfo");
+ if (sect != NULL)
+ bfd_set_section_size (output_bfd, sect, sizeof (Elf32_External_RegInfo));
+
+ /* The .MIPS.abiflags section has a fixed size. */
+ sect = bfd_get_section_by_name (output_bfd, ".MIPS.abiflags");
+ if (sect != NULL)
+ bfd_set_section_size (output_bfd, sect, sizeof (Elf_External_ABIFlags_v0));
+
+ hti.info = info;
+ hti.output_bfd = output_bfd;
+ hti.error = FALSE;
+ mips_elf_link_hash_traverse (mips_elf_hash_table (info),
+ mips_elf_check_symbols, &hti);
+ if (hti.error)
+ return FALSE;
+
+ return TRUE;
+}
+
+/* If the link uses a GOT, lay it out and work out its size. */
+
+static bfd_boolean
+mips_elf_lay_out_got (bfd *output_bfd, struct bfd_link_info *info)
+{
+ bfd *dynobj;
+ asection *s;
+ struct mips_got_info *g;
+ bfd_size_type loadable_size = 0;
+ bfd_size_type page_gotno;
+ bfd *ibfd;
+ struct mips_elf_traverse_got_arg tga;
+ struct mips_elf_link_hash_table *htab;
+
+ htab = mips_elf_hash_table (info);
+ BFD_ASSERT (htab != NULL);
+
+ s = htab->sgot;
+ if (s == NULL)
+ return TRUE;
+
+ dynobj = elf_hash_table (info)->dynobj;
+ g = htab->got_info;
+
+ /* Allocate room for the reserved entries. VxWorks always reserves
+ 3 entries; other objects only reserve 2 entries. */
+ BFD_ASSERT (g->assigned_low_gotno == 0);
+ if (htab->is_vxworks)
+ htab->reserved_gotno = 3;
+ else
+ htab->reserved_gotno = 2;
+ g->local_gotno += htab->reserved_gotno;
+ g->assigned_low_gotno = htab->reserved_gotno;
+
+ /* Decide which symbols need to go in the global part of the GOT and
+ count the number of reloc-only GOT symbols. */
+ mips_elf_link_hash_traverse (htab, mips_elf_count_got_symbols, info);
+
+ if (!mips_elf_resolve_final_got_entries (info, g))
+ return FALSE;
+
+ /* Calculate the total loadable size of the output. That
+ will give us the maximum number of GOT_PAGE entries
+ required. */
+ for (ibfd = info->input_bfds; ibfd; ibfd = ibfd->link.next)
+ {
+ asection *subsection;
+
+ for (subsection = ibfd->sections;
+ subsection;
+ subsection = subsection->next)
+ {
+ if ((subsection->flags & SEC_ALLOC) == 0)
+ continue;
+ loadable_size += ((subsection->size + 0xf)
+ &~ (bfd_size_type) 0xf);
+ }
+ }
+
+ if (htab->is_vxworks)
+ /* There's no need to allocate page entries for VxWorks; R_MIPS*_GOT16
+ relocations against local symbols evaluate to "G", and the EABI does
+ not include R_MIPS_GOT_PAGE. */
+ page_gotno = 0;
+ else
+ /* Assume there are two loadable segments consisting of contiguous
+ sections. Is 5 enough? */
+ page_gotno = (loadable_size >> 16) + 5;
+
+ /* Choose the smaller of the two page estimates; both are intended to be
+ conservative. */
+ if (page_gotno > g->page_gotno)
+ page_gotno = g->page_gotno;
+
+ g->local_gotno += page_gotno;
+ g->assigned_high_gotno = g->local_gotno - 1;
+
+ s->size += g->local_gotno * MIPS_ELF_GOT_SIZE (output_bfd);
+ s->size += g->global_gotno * MIPS_ELF_GOT_SIZE (output_bfd);
+ s->size += g->tls_gotno * MIPS_ELF_GOT_SIZE (output_bfd);
+
+ /* VxWorks does not support multiple GOTs. It initializes $gp to
+ __GOTT_BASE__[__GOTT_INDEX__], the value of which is set by the
+ dynamic loader. */
+ if (!htab->is_vxworks && s->size > MIPS_ELF_GOT_MAX_SIZE (info))
+ {
+ if (!mips_elf_multi_got (output_bfd, info, s, page_gotno))
+ return FALSE;
+ }
+ else
+ {
+ /* Record that all bfds use G. This also has the effect of freeing
+ the per-bfd GOTs, which we no longer need. */
+ for (ibfd = info->input_bfds; ibfd; ibfd = ibfd->link.next)
+ if (mips_elf_bfd_got (ibfd, FALSE))
+ mips_elf_replace_bfd_got (ibfd, g);
+ mips_elf_replace_bfd_got (output_bfd, g);
+
+ /* Set up TLS entries. */
+ g->tls_assigned_gotno = g->global_gotno + g->local_gotno;
+ tga.info = info;
+ tga.g = g;
+ tga.value = MIPS_ELF_GOT_SIZE (output_bfd);
+ htab_traverse (g->got_entries, mips_elf_initialize_tls_index, &tga);
+ if (!tga.g)
+ return FALSE;
+ BFD_ASSERT (g->tls_assigned_gotno
+ == g->global_gotno + g->local_gotno + g->tls_gotno);
+
+ /* Each VxWorks GOT entry needs an explicit relocation. */
+ if (htab->is_vxworks && info->shared)
+ g->relocs += g->global_gotno + g->local_gotno - htab->reserved_gotno;
+
+ /* Allocate room for the TLS relocations. */
+ if (g->relocs)
+ mips_elf_allocate_dynamic_relocations (dynobj, info, g->relocs);
+ }
+
+ return TRUE;
+}
+
+/* Estimate the size of the .MIPS.stubs section. */
+
+static void
+mips_elf_estimate_stub_size (bfd *output_bfd, struct bfd_link_info *info)
+{
+ struct mips_elf_link_hash_table *htab;
+ bfd_size_type dynsymcount;
+
+ htab = mips_elf_hash_table (info);
+ BFD_ASSERT (htab != NULL);
+
+ if (htab->lazy_stub_count == 0)
+ return;
+
+ /* IRIX rld assumes that a function stub isn't at the end of the .text
+ section, so add a dummy entry to the end. */
+ htab->lazy_stub_count++;
+
+ /* Get a worst-case estimate of the number of dynamic symbols needed.
+ At this point, dynsymcount does not account for section symbols
+ and count_section_dynsyms may overestimate the number that will
+ be needed. */
+ dynsymcount = (elf_hash_table (info)->dynsymcount
+ + count_section_dynsyms (output_bfd, info));
+
+ /* Determine the size of one stub entry. There's no disadvantage
+ from using microMIPS code here, so for the sake of pure-microMIPS
+ binaries we prefer it whenever there's any microMIPS code in
+ output produced at all. This has a benefit of stubs being
+ shorter by 4 bytes each too, unless in the insn32 mode. */
+ if (!MICROMIPS_P (output_bfd))
+ htab->function_stub_size = (dynsymcount > 0x10000
+ ? MIPS_FUNCTION_STUB_BIG_SIZE
+ : MIPS_FUNCTION_STUB_NORMAL_SIZE);
+ else if (htab->insn32)
+ htab->function_stub_size = (dynsymcount > 0x10000
+ ? MICROMIPS_INSN32_FUNCTION_STUB_BIG_SIZE
+ : MICROMIPS_INSN32_FUNCTION_STUB_NORMAL_SIZE);
+ else
+ htab->function_stub_size = (dynsymcount > 0x10000
+ ? MICROMIPS_FUNCTION_STUB_BIG_SIZE
+ : MICROMIPS_FUNCTION_STUB_NORMAL_SIZE);
+
+ htab->sstubs->size = htab->lazy_stub_count * htab->function_stub_size;
+}
+
+/* A mips_elf_link_hash_traverse callback for which DATA points to a
+ mips_htab_traverse_info. If H needs a traditional MIPS lazy-binding
+ stub, allocate an entry in the stubs section. */
+
+static bfd_boolean
+mips_elf_allocate_lazy_stub (struct mips_elf_link_hash_entry *h, void *data)
+{
+ struct mips_htab_traverse_info *hti = data;
+ struct mips_elf_link_hash_table *htab;
+ struct bfd_link_info *info;
+ bfd *output_bfd;
+
+ info = hti->info;
+ output_bfd = hti->output_bfd;
+ htab = mips_elf_hash_table (info);
+ BFD_ASSERT (htab != NULL);
+
+ if (h->needs_lazy_stub)
+ {
+ bfd_boolean micromips_p = MICROMIPS_P (output_bfd);
+ unsigned int other = micromips_p ? STO_MICROMIPS : 0;
+ bfd_vma isa_bit = micromips_p;
+
+ BFD_ASSERT (htab->root.dynobj != NULL);
+ if (h->root.plt.plist == NULL)
+ h->root.plt.plist = mips_elf_make_plt_record (htab->sstubs->owner);
+ if (h->root.plt.plist == NULL)
+ {
+ hti->error = TRUE;
+ return FALSE;
+ }
+ h->root.root.u.def.section = htab->sstubs;
+ h->root.root.u.def.value = htab->sstubs->size + isa_bit;
+ h->root.plt.plist->stub_offset = htab->sstubs->size;
+ h->root.other = other;
+ htab->sstubs->size += htab->function_stub_size;
+ }
+ return TRUE;
+}
+
+/* Allocate offsets in the stubs section to each symbol that needs one.
+ Set the final size of the .MIPS.stub section. */
+
+static bfd_boolean
+mips_elf_lay_out_lazy_stubs (struct bfd_link_info *info)
+{
+ bfd *output_bfd = info->output_bfd;
+ bfd_boolean micromips_p = MICROMIPS_P (output_bfd);
+ unsigned int other = micromips_p ? STO_MICROMIPS : 0;
+ bfd_vma isa_bit = micromips_p;
+ struct mips_elf_link_hash_table *htab;
+ struct mips_htab_traverse_info hti;
+ struct elf_link_hash_entry *h;
+ bfd *dynobj;
+
+ htab = mips_elf_hash_table (info);
+ BFD_ASSERT (htab != NULL);
+
+ if (htab->lazy_stub_count == 0)
+ return TRUE;
+
+ htab->sstubs->size = 0;
+ hti.info = info;
+ hti.output_bfd = output_bfd;
+ hti.error = FALSE;
+ mips_elf_link_hash_traverse (htab, mips_elf_allocate_lazy_stub, &hti);
+ if (hti.error)
+ return FALSE;
+ htab->sstubs->size += htab->function_stub_size;
+ BFD_ASSERT (htab->sstubs->size
+ == htab->lazy_stub_count * htab->function_stub_size);
+
+ dynobj = elf_hash_table (info)->dynobj;
+ BFD_ASSERT (dynobj != NULL);
+ h = _bfd_elf_define_linkage_sym (dynobj, info, htab->sstubs, "_MIPS_STUBS_");
+ if (h == NULL)
+ return FALSE;
+ h->root.u.def.value = isa_bit;
+ h->other = other;
+ h->type = STT_FUNC;
+
+ return TRUE;
+}
+
+/* A mips_elf_link_hash_traverse callback for which DATA points to a
+ bfd_link_info. If H uses the address of a PLT entry as the value
+ of the symbol, then set the entry in the symbol table now. Prefer
+ a standard MIPS PLT entry. */
+
+static bfd_boolean
+mips_elf_set_plt_sym_value (struct mips_elf_link_hash_entry *h, void *data)
+{
+ struct bfd_link_info *info = data;
+ bfd_boolean micromips_p = MICROMIPS_P (info->output_bfd);
+ struct mips_elf_link_hash_table *htab;
+ unsigned int other;
+ bfd_vma isa_bit;
+ bfd_vma val;
+
+ htab = mips_elf_hash_table (info);
+ BFD_ASSERT (htab != NULL);
+
+ if (h->use_plt_entry)
+ {
+ BFD_ASSERT (h->root.plt.plist != NULL);
+ BFD_ASSERT (h->root.plt.plist->mips_offset != MINUS_ONE
+ || h->root.plt.plist->comp_offset != MINUS_ONE);
+
+ val = htab->plt_header_size;
+ if (h->root.plt.plist->mips_offset != MINUS_ONE)
+ {
+ isa_bit = 0;
+ val += h->root.plt.plist->mips_offset;
+ other = 0;
+ }
+ else
+ {
+ isa_bit = 1;
+ val += htab->plt_mips_offset + h->root.plt.plist->comp_offset;
+ other = micromips_p ? STO_MICROMIPS : STO_MIPS16;
+ }
+ val += isa_bit;
+ /* For VxWorks, point at the PLT load stub rather than the lazy
+ resolution stub; this stub will become the canonical function
+ address. */
+ if (htab->is_vxworks)
+ val += 8;
+
+ h->root.root.u.def.section = htab->splt;
+ h->root.root.u.def.value = val;
+ h->root.other = other;
+ }
+
+ return TRUE;
+}
+
+/* Set the sizes of the dynamic sections. */
+
+bfd_boolean
+_bfd_mips_elf_size_dynamic_sections (bfd *output_bfd,
+ struct bfd_link_info *info)
+{
+ bfd *dynobj;
+ asection *s, *sreldyn;
+ bfd_boolean reltext;
+ struct mips_elf_link_hash_table *htab;
+
+ htab = mips_elf_hash_table (info);
+ BFD_ASSERT (htab != NULL);
+ 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->executable)
+ {
+ s = bfd_get_linker_section (dynobj, ".interp");
+ BFD_ASSERT (s != NULL);
+ s->size
+ = strlen (ELF_DYNAMIC_INTERPRETER (output_bfd)) + 1;
+ s->contents
+ = (bfd_byte *) ELF_DYNAMIC_INTERPRETER (output_bfd);
+ }
+
+ /* Figure out the size of the PLT header if we know that we
+ are using it. For the sake of cache alignment always use
+ a standard header whenever any standard entries are present
+ even if microMIPS entries are present as well. This also
+ lets the microMIPS header rely on the value of $v0 only set
+ by microMIPS entries, for a small size reduction.
+
+ Set symbol table entry values for symbols that use the
+ address of their PLT entry now that we can calculate it.
+
+ Also create the _PROCEDURE_LINKAGE_TABLE_ symbol if we
+ haven't already in _bfd_elf_create_dynamic_sections. */
+ if (htab->splt && htab->plt_mips_offset + htab->plt_comp_offset != 0)
+ {
+ bfd_boolean micromips_p = (MICROMIPS_P (output_bfd)
+ && !htab->plt_mips_offset);
+ unsigned int other = micromips_p ? STO_MICROMIPS : 0;
+ bfd_vma isa_bit = micromips_p;
+ struct elf_link_hash_entry *h;
+ bfd_vma size;
+
+ BFD_ASSERT (htab->use_plts_and_copy_relocs);
+ BFD_ASSERT (htab->sgotplt->size == 0);
+ BFD_ASSERT (htab->splt->size == 0);
+
+ if (htab->is_vxworks && info->shared)
+ size = 4 * ARRAY_SIZE (mips_vxworks_shared_plt0_entry);
+ else if (htab->is_vxworks)
+ size = 4 * ARRAY_SIZE (mips_vxworks_exec_plt0_entry);
+ else if (ABI_64_P (output_bfd))
+ size = 4 * ARRAY_SIZE (mips_n64_exec_plt0_entry);
+ else if (ABI_N32_P (output_bfd))
+ size = 4 * ARRAY_SIZE (mips_n32_exec_plt0_entry);
+ else if (!micromips_p)
+ size = 4 * ARRAY_SIZE (mips_o32_exec_plt0_entry);
+ else if (htab->insn32)
+ size = 2 * ARRAY_SIZE (micromips_insn32_o32_exec_plt0_entry);
+ else
+ size = 2 * ARRAY_SIZE (micromips_o32_exec_plt0_entry);
+
+ htab->plt_header_is_comp = micromips_p;
+ htab->plt_header_size = size;
+ htab->splt->size = (size
+ + htab->plt_mips_offset
+ + htab->plt_comp_offset);
+ htab->sgotplt->size = (htab->plt_got_index
+ * MIPS_ELF_GOT_SIZE (dynobj));
+
+ mips_elf_link_hash_traverse (htab, mips_elf_set_plt_sym_value, info);
+
+ if (htab->root.hplt == NULL)
+ {
+ h = _bfd_elf_define_linkage_sym (dynobj, info, htab->splt,
+ "_PROCEDURE_LINKAGE_TABLE_");
+ htab->root.hplt = h;
+ if (h == NULL)
+ return FALSE;
+ }
+
+ h = htab->root.hplt;
+ h->root.u.def.value = isa_bit;
+ h->other = other;
+ h->type = STT_FUNC;
+ }
+ }
+
+ /* Allocate space for global sym dynamic relocs. */
+ elf_link_hash_traverse (&htab->root, allocate_dynrelocs, info);
+
+ mips_elf_estimate_stub_size (output_bfd, info);
+
+ if (!mips_elf_lay_out_got (output_bfd, info))
+ return FALSE;
+
+ mips_elf_lay_out_lazy_stubs (info);
+
+ /* 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;
+
+ /* 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;
+
+ if (CONST_STRNEQ (name, ".rel"))
+ {
+ if (s->size != 0)
+ {
+ 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(a).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, MIPS_ELF_REL_DYN_NAME (info)) == 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, MIPS_ELF_REL_DYN_NAME (info)) != 0)
+ s->reloc_count = 0;
+
+ /* If combreloc is enabled, elf_link_sort_relocs() will
+ sort relocations, but in a different way than we do,
+ and before we're done creating relocations. Also, it
+ will move them around between input sections'
+ relocation's contents, so our sorting would be
+ broken, so don't let it run. */
+ info->combreloc = 0;
+ }
+ }
+ else if (! info->shared
+ && ! mips_elf_hash_table (info)->use_rld_obj_head
+ && CONST_STRNEQ (name, ".rld_map"))
+ {
+ /* 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->size += MIPS_ELF_RLD_MAP_SIZE (output_bfd);
+ }
+ else if (SGI_COMPAT (output_bfd)
+ && CONST_STRNEQ (name, ".compact_rel"))
+ s->size += mips_elf_hash_table (info)->compact_rel_size;
+ else if (s == htab->splt)
+ {
+ /* If the last PLT entry has a branch delay slot, allocate
+ room for an extra nop to fill the delay slot. This is
+ for CPUs without load interlocking. */
+ if (! LOAD_INTERLOCKS_P (output_bfd)
+ && ! htab->is_vxworks && s->size > 0)
+ s->size += 4;
+ }
+ else if (! CONST_STRNEQ (name, ".init")
+ && s != htab->sgot
+ && s != htab->sgotplt
+ && s != htab->sstubs
+ && s != htab->sdynbss)
+ {
+ /* It's not one of our sections, so don't allocate space. */
+ continue;
+ }
+
+ if (s->size == 0)
+ {
+ s->flags |= SEC_EXCLUDE;
+ continue;
+ }
+
+ if ((s->flags & SEC_HAS_CONTENTS) == 0)
+ continue;
+
+ /* Allocate memory for the section contents. */
+ s->contents = bfd_zalloc (dynobj, s->size);
+ if (s->contents == NULL)
+ {
+ bfd_set_error (bfd_error_no_memory);
+ return FALSE;
+ }
+ }
+
+ if (elf_hash_table (info)->dynamic_sections_created)
+ {
+ /* Add some entries to the .dynamic section. We fill in the
+ values later, in _bfd_mips_elf_finish_dynamic_sections, but we
+ must add the entries now so that we get the correct size for
+ the .dynamic section. */
+
+ /* SGI object has the equivalence of DT_DEBUG in the
+ DT_MIPS_RLD_MAP entry. This must come first because glibc
+ only fills in DT_MIPS_RLD_MAP (not DT_DEBUG) and some tools
+ may only look at the first one they see. */
+ if (!info->shared
+ && !MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_MIPS_RLD_MAP, 0))
+ return FALSE;
+
+ /* The DT_DEBUG entry may be filled in by the dynamic linker and
+ used by the debugger. */
+ if (info->executable
+ && !SGI_COMPAT (output_bfd)
+ && !MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_DEBUG, 0))
+ return FALSE;
+
+ if (reltext && (SGI_COMPAT (output_bfd) || htab->is_vxworks))
+ info->flags |= DF_TEXTREL;
+
+ if ((info->flags & DF_TEXTREL) != 0)
+ {
+ if (! MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_TEXTREL, 0))
+ return FALSE;
+
+ /* Clear the DF_TEXTREL flag. It will be set again if we
+ write out an actual text relocation; we may not, because
+ at this point we do not know whether e.g. any .eh_frame
+ absolute relocations have been converted to PC-relative. */
+ info->flags &= ~DF_TEXTREL;
+ }
+
+ if (! MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_PLTGOT, 0))
+ return FALSE;
+
+ sreldyn = mips_elf_rel_dyn_section (info, FALSE);
+ if (htab->is_vxworks)
+ {
+ /* VxWorks uses .rela.dyn instead of .rel.dyn. It does not
+ use any of the DT_MIPS_* tags. */
+ if (sreldyn && sreldyn->size > 0)
+ {
+ if (! MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_RELA, 0))
+ return FALSE;
+
+ if (! MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_RELASZ, 0))
+ return FALSE;
+
+ if (! MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_RELAENT, 0))
+ return FALSE;
+ }
+ }
+ else
+ {
+ if (sreldyn && sreldyn->size > 0)
+ {
+ if (! MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_REL, 0))
+ return FALSE;
+
+ if (! MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_RELSZ, 0))
+ return FALSE;
+
+ if (! MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_RELENT, 0))
+ return FALSE;
+ }
+
+ if (! MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_MIPS_RLD_VERSION, 0))
+ return FALSE;
+
+ if (! MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_MIPS_FLAGS, 0))
+ return FALSE;
+
+ if (! MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_MIPS_BASE_ADDRESS, 0))
+ return FALSE;
+
+ if (! MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_MIPS_LOCAL_GOTNO, 0))
+ return FALSE;
+
+ if (! MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_MIPS_SYMTABNO, 0))
+ return FALSE;
+
+ if (! MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_MIPS_UNREFEXTNO, 0))
+ return FALSE;
+
+ if (! MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_MIPS_GOTSYM, 0))
+ return FALSE;
+
+ if (IRIX_COMPAT (dynobj) == ict_irix5
+ && ! MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_MIPS_HIPAGENO, 0))
+ return FALSE;
+
+ if (IRIX_COMPAT (dynobj) == ict_irix6
+ && (bfd_get_section_by_name
+ (output_bfd, MIPS_ELF_OPTIONS_SECTION_NAME (dynobj)))
+ && !MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_MIPS_OPTIONS, 0))
+ return FALSE;
+ }
+ if (htab->splt->size > 0)
+ {
+ if (! MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_PLTREL, 0))
+ return FALSE;
+
+ if (! MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_JMPREL, 0))
+ return FALSE;
+
+ if (! MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_PLTRELSZ, 0))
+ return FALSE;
+
+ if (! MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_MIPS_PLTGOT, 0))
+ return FALSE;
+ }
+ if (htab->is_vxworks
+ && !elf_vxworks_add_dynamic_entries (output_bfd, info))
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/* REL is a relocation in INPUT_BFD that is being copied to OUTPUT_BFD.
+ Adjust its R_ADDEND field so that it is correct for the output file.
+ LOCAL_SYMS and LOCAL_SECTIONS are arrays of INPUT_BFD's local symbols
+ and sections respectively; both use symbol indexes. */
+
+static void
+mips_elf_adjust_addend (bfd *output_bfd, struct bfd_link_info *info,
+ bfd *input_bfd, Elf_Internal_Sym *local_syms,
+ asection **local_sections, Elf_Internal_Rela *rel)
+{
+ unsigned int r_type, r_symndx;
+ Elf_Internal_Sym *sym;
+ asection *sec;
+
+ if (mips_elf_local_relocation_p (input_bfd, rel, local_sections))
+ {
+ r_type = ELF_R_TYPE (output_bfd, rel->r_info);
+ if (gprel16_reloc_p (r_type)
+ || r_type == R_MIPS_GPREL32
+ || literal_reloc_p (r_type))
+ {
+ rel->r_addend += _bfd_get_gp_value (input_bfd);
+ rel->r_addend -= _bfd_get_gp_value (output_bfd);
+ }
+
+ r_symndx = ELF_R_SYM (output_bfd, rel->r_info);
+ sym = local_syms + r_symndx;
+
+ /* Adjust REL's addend to account for section merging. */
+ if (!info->relocatable)
+ {
+ sec = local_sections[r_symndx];
+ _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
+ }
+
+ /* This would normally be done by the rela_normal code in elflink.c. */
+ if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
+ rel->r_addend += local_sections[r_symndx]->output_offset;
+ }
+}
+
+/* Handle relocations against symbols from removed linkonce sections,
+ or sections discarded by a linker script. We use this wrapper around
+ RELOC_AGAINST_DISCARDED_SECTION to handle triplets of compound relocs
+ on 64-bit ELF targets. In this case for any relocation handled, which
+ always be the first in a triplet, the remaining two have to be processed
+ together with the first, even if they are R_MIPS_NONE. It is the symbol
+ index referred by the first reloc that applies to all the three and the
+ remaining two never refer to an object symbol. And it is the final
+ relocation (the last non-null one) that determines the output field of
+ the whole relocation so retrieve the corresponding howto structure for
+ the relocatable field to be cleared by RELOC_AGAINST_DISCARDED_SECTION.
+
+ Note that RELOC_AGAINST_DISCARDED_SECTION is a macro that uses "continue"
+ and therefore requires to be pasted in a loop. It also defines a block
+ and does not protect any of its arguments, hence the extra brackets. */
+
+static void
+mips_reloc_against_discarded_section (bfd *output_bfd,
+ struct bfd_link_info *info,
+ bfd *input_bfd, asection *input_section,
+ Elf_Internal_Rela **rel,
+ const Elf_Internal_Rela **relend,
+ bfd_boolean rel_reloc,
+ reloc_howto_type *howto,
+ bfd_byte *contents)
+{
+ const struct elf_backend_data *bed = get_elf_backend_data (output_bfd);
+ int count = bed->s->int_rels_per_ext_rel;
+ unsigned int r_type;
+ int i;
+
+ for (i = count - 1; i > 0; i--)
+ {
+ r_type = ELF_R_TYPE (output_bfd, (*rel)[i].r_info);
+ if (r_type != R_MIPS_NONE)
+ {
+ howto = MIPS_ELF_RTYPE_TO_HOWTO (input_bfd, r_type, !rel_reloc);
+ break;
+ }
+ }
+ do
+ {
+ RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+ (*rel), count, (*relend),
+ howto, i, contents);
+ }
+ while (0);
+}
+
+/* Relocate a MIPS ELF section. */
+
+bfd_boolean
+_bfd_mips_elf_relocate_section (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_Rela *rel;
+ const Elf_Internal_Rela *relend;
+ bfd_vma addend = 0;
+ bfd_boolean use_saved_addend_p = FALSE;
+ const struct elf_backend_data *bed;
+
+ bed = get_elf_backend_data (output_bfd);
+ relend = relocs + input_section->reloc_count * bed->s->int_rels_per_ext_rel;
+ for (rel = relocs; rel < relend; ++rel)
+ {
+ const char *name;
+ bfd_vma value = 0;
+ reloc_howto_type *howto;
+ bfd_boolean cross_mode_jump_p = FALSE;
+ /* TRUE if the relocation is a RELA relocation, rather than a
+ REL relocation. */
+ bfd_boolean rela_relocation_p = TRUE;
+ unsigned int r_type = ELF_R_TYPE (output_bfd, rel->r_info);
+ const char *msg;
+ unsigned long r_symndx;
+ asection *sec;
+ Elf_Internal_Shdr *symtab_hdr;
+ struct elf_link_hash_entry *h;
+ bfd_boolean rel_reloc;
+
+ rel_reloc = (NEWABI_P (input_bfd)
+ && mips_elf_rel_relocation_p (input_bfd, input_section,
+ relocs, rel));
+ /* Find the relocation howto for this relocation. */
+ howto = MIPS_ELF_RTYPE_TO_HOWTO (input_bfd, r_type, !rel_reloc);
+
+ r_symndx = ELF_R_SYM (input_bfd, rel->r_info);
+ symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
+ if (mips_elf_local_relocation_p (input_bfd, rel, local_sections))
+ {
+ sec = local_sections[r_symndx];
+ h = NULL;
+ }
+ else
+ {
+ unsigned long extsymoff;
+
+ extsymoff = 0;
+ if (!elf_bad_symtab (input_bfd))
+ extsymoff = symtab_hdr->sh_info;
+ h = elf_sym_hashes (input_bfd) [r_symndx - extsymoff];
+ 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;
+
+ sec = NULL;
+ if (h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak)
+ sec = h->root.u.def.section;
+ }
+
+ if (sec != NULL && discarded_section (sec))
+ {
+ mips_reloc_against_discarded_section (output_bfd, info, input_bfd,
+ input_section, &rel, &relend,
+ rel_reloc, howto, contents);
+ continue;
+ }
+
+ if (r_type == R_MIPS_64 && ! NEWABI_P (input_bfd))
+ {
+ /* Some 32-bit code uses R_MIPS_64. In particular, people use
+ 64-bit code, but make sure all their addresses are in the
+ lowermost or uppermost 32-bit section of the 64-bit address
+ space. Thus, when they use an R_MIPS_64 they mean what is
+ usually meant by R_MIPS_32, with the exception that the
+ stored value is sign-extended to 64 bits. */
+ howto = MIPS_ELF_RTYPE_TO_HOWTO (input_bfd, R_MIPS_32, FALSE);
+
+ /* On big-endian systems, we need to lie about the position
+ of the reloc. */
+ if (bfd_big_endian (input_bfd))
+ rel->r_offset += 4;
+ }
+
+ if (!use_saved_addend_p)
+ {
+ /* If these relocations were originally of the REL variety,
+ we must pull the addend out of the field that will be
+ relocated. Otherwise, we simply use the contents of the
+ RELA relocation. */
+ if (mips_elf_rel_relocation_p (input_bfd, input_section,
+ relocs, rel))
+ {
+ rela_relocation_p = FALSE;
+ addend = mips_elf_read_rel_addend (input_bfd, rel,
+ howto, contents);
+ if (hi16_reloc_p (r_type)
+ || (got16_reloc_p (r_type)
+ && mips_elf_local_relocation_p (input_bfd, rel,
+ local_sections)))
+ {
+ if (!mips_elf_add_lo16_rel_addend (input_bfd, rel, relend,
+ contents, &addend))
+ {
+ if (h)
+ name = h->root.root.string;
+ else
+ name = bfd_elf_sym_name (input_bfd, symtab_hdr,
+ local_syms + r_symndx,
+ sec);
+ (*_bfd_error_handler)
+ (_("%B: Can't find matching LO16 reloc against `%s' for %s at 0x%lx in section `%A'"),
+ input_bfd, input_section, name, howto->name,
+ rel->r_offset);
+ }
+ }
+ else
+ addend <<= howto->rightshift;
+ }
+ else
+ addend = rel->r_addend;
+ mips_elf_adjust_addend (output_bfd, info, input_bfd,
+ local_syms, local_sections, rel);
+ }
+
+ if (info->relocatable)
+ {
+ if (r_type == R_MIPS_64 && ! NEWABI_P (output_bfd)
+ && bfd_big_endian (input_bfd))
+ rel->r_offset -= 4;
+
+ if (!rela_relocation_p && rel->r_addend)
+ {
+ addend += rel->r_addend;
+ if (hi16_reloc_p (r_type) || got16_reloc_p (r_type))
+ addend = mips_elf_high (addend);
+ else if (r_type == R_MIPS_HIGHER)
+ addend = mips_elf_higher (addend);
+ else if (r_type == R_MIPS_HIGHEST)
+ addend = mips_elf_highest (addend);
+ else
+ addend >>= howto->rightshift;
+
+ /* We use the source mask, rather than the destination
+ mask because the place to which we are writing will be
+ source of the addend in the final link. */
+ addend &= howto->src_mask;
+
+ if (r_type == R_MIPS_64 && ! NEWABI_P (output_bfd))
+ /* See the comment above about using R_MIPS_64 in the 32-bit
+ ABI. Here, we need to update the addend. It would be
+ possible to get away with just using the R_MIPS_32 reloc
+ but for endianness. */
+ {
+ bfd_vma sign_bits;
+ bfd_vma low_bits;
+ bfd_vma high_bits;
+
+ if (addend & ((bfd_vma) 1 << 31))
+#ifdef BFD64
+ sign_bits = ((bfd_vma) 1 << 32) - 1;
+#else
+ sign_bits = -1;
+#endif
+ else
+ sign_bits = 0;
+
+ /* If we don't know that we have a 64-bit type,
+ do two separate stores. */
+ if (bfd_big_endian (input_bfd))
+ {
+ /* Store the sign-bits (which are most significant)
+ first. */
+ low_bits = sign_bits;
+ high_bits = addend;
+ }
+ else
+ {
+ low_bits = addend;
+ high_bits = sign_bits;
+ }
+ bfd_put_32 (input_bfd, low_bits,
+ contents + rel->r_offset);
+ bfd_put_32 (input_bfd, high_bits,
+ contents + rel->r_offset + 4);
+ continue;
+ }
+
+ if (! mips_elf_perform_relocation (info, howto, rel, addend,
+ input_bfd, input_section,
+ contents, FALSE))
+ return FALSE;
+ }
+
+ /* Go on to the next relocation. */
+ continue;
+ }
+
+ /* In the N32 and 64-bit ABIs there may be multiple consecutive
+ relocations for the same offset. In that case we are
+ supposed to treat the output of each relocation as the addend
+ for the next. */
+ if (rel + 1 < relend
+ && rel->r_offset == rel[1].r_offset
+ && ELF_R_TYPE (input_bfd, rel[1].r_info) != R_MIPS_NONE)
+ use_saved_addend_p = TRUE;
+ else
+ use_saved_addend_p = FALSE;
+
+ /* Figure out what value we are supposed to relocate. */
+ switch (mips_elf_calculate_relocation (output_bfd, input_bfd,
+ input_section, info, rel,
+ addend, howto, local_syms,
+ local_sections, &value,
+ &name, &cross_mode_jump_p,
+ use_saved_addend_p))
+ {
+ case bfd_reloc_continue:
+ /* There's nothing to do. */
+ continue;
+
+ case bfd_reloc_undefined:
+ /* mips_elf_calculate_relocation already called the
+ undefined_symbol callback. There's no real point in
+ trying to perform the relocation at this point, so we
+ just skip ahead to the next relocation. */
+ continue;
+
+ case bfd_reloc_notsupported:
+ msg = _("internal error: unsupported relocation error");
+ info->callbacks->warning
+ (info, msg, name, input_bfd, input_section, rel->r_offset);
+ return FALSE;
+
+ case bfd_reloc_overflow:
+ if (use_saved_addend_p)
+ /* Ignore overflow until we reach the last relocation for
+ a given location. */
+ ;
+ else
+ {
+ struct mips_elf_link_hash_table *htab;
+
+ htab = mips_elf_hash_table (info);
+ BFD_ASSERT (htab != NULL);
+ BFD_ASSERT (name != NULL);
+ if (!htab->small_data_overflow_reported
+ && (gprel16_reloc_p (howto->type)
+ || literal_reloc_p (howto->type)))
+ {
+ msg = _("small-data section exceeds 64KB;"
+ " lower small-data size limit (see option -G)");
+
+ htab->small_data_overflow_reported = TRUE;
+ (*info->callbacks->einfo) ("%P: %s\n", msg);
+ }
+ if (! ((*info->callbacks->reloc_overflow)
+ (info, NULL, name, howto->name, (bfd_vma) 0,
+ input_bfd, input_section, rel->r_offset)))
+ return FALSE;
+ }
+ break;
+
+ case bfd_reloc_ok:
+ break;
+
+ case bfd_reloc_outofrange:
+ if (jal_reloc_p (howto->type))
+ {
+ msg = _("JALX to a non-word-aligned address");
+ info->callbacks->warning
+ (info, msg, name, input_bfd, input_section, rel->r_offset);
+ return FALSE;
+ }
+ if (aligned_pcrel_reloc_p (howto->type))
+ {
+ msg = _("PC-relative load from unaligned address");
+ info->callbacks->warning
+ (info, msg, name, input_bfd, input_section, rel->r_offset);
+ return FALSE;
+ }
+ /* Fall through. */
+
+ default:
+ abort ();
+ break;
+ }
+
+ /* If we've got another relocation for the address, keep going
+ until we reach the last one. */
+ if (use_saved_addend_p)
+ {
+ addend = value;
+ continue;
+ }
+
+ if (r_type == R_MIPS_64 && ! NEWABI_P (output_bfd))
+ /* See the comment above about using R_MIPS_64 in the 32-bit
+ ABI. Until now, we've been using the HOWTO for R_MIPS_32;
+ that calculated the right value. Now, however, we
+ sign-extend the 32-bit result to 64-bits, and store it as a
+ 64-bit value. We are especially generous here in that we
+ go to extreme lengths to support this usage on systems with
+ only a 32-bit VMA. */
+ {
+ bfd_vma sign_bits;
+ bfd_vma low_bits;
+ bfd_vma high_bits;
+
+ if (value & ((bfd_vma) 1 << 31))
+#ifdef BFD64
+ sign_bits = ((bfd_vma) 1 << 32) - 1;
+#else
+ sign_bits = -1;
+#endif
+ else
+ sign_bits = 0;
+
+ /* If we don't know that we have a 64-bit type,
+ do two separate stores. */
+ if (bfd_big_endian (input_bfd))
+ {
+ /* Undo what we did above. */
+ rel->r_offset -= 4;
+ /* Store the sign-bits (which are most significant)
+ first. */
+ low_bits = sign_bits;
+ high_bits = value;
+ }
+ else
+ {
+ low_bits = value;
+ high_bits = sign_bits;
+ }
+ bfd_put_32 (input_bfd, low_bits,
+ contents + rel->r_offset);
+ bfd_put_32 (input_bfd, high_bits,
+ contents + rel->r_offset + 4);
+ continue;
+ }
+
+ /* Actually perform the relocation. */
+ if (! mips_elf_perform_relocation (info, howto, rel, value,
+ input_bfd, input_section,
+ contents, cross_mode_jump_p))
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/* A function that iterates over each entry in la25_stubs and fills
+ in the code for each one. DATA points to a mips_htab_traverse_info. */
+
+static int
+mips_elf_create_la25_stub (void **slot, void *data)
+{
+ struct mips_htab_traverse_info *hti;
+ struct mips_elf_link_hash_table *htab;
+ struct mips_elf_la25_stub *stub;
+ asection *s;
+ bfd_byte *loc;
+ bfd_vma offset, target, target_high, target_low;
+
+ stub = (struct mips_elf_la25_stub *) *slot;
+ hti = (struct mips_htab_traverse_info *) data;
+ htab = mips_elf_hash_table (hti->info);
+ BFD_ASSERT (htab != NULL);
+
+ /* Create the section contents, if we haven't already. */
+ s = stub->stub_section;
+ loc = s->contents;
+ if (loc == NULL)
+ {
+ loc = bfd_malloc (s->size);
+ if (loc == NULL)
+ {
+ hti->error = TRUE;
+ return FALSE;
+ }
+ s->contents = loc;
+ }
+
+ /* Work out where in the section this stub should go. */
+ offset = stub->offset;
+
+ /* Work out the target address. */
+ target = mips_elf_get_la25_target (stub, &s);
+ target += s->output_section->vma + s->output_offset;
+
+ target_high = ((target + 0x8000) >> 16) & 0xffff;
+ target_low = (target & 0xffff);
+
+ if (stub->stub_section != htab->strampoline)
+ {
+ /* This is a simple LUI/ADDIU stub. Zero out the beginning
+ of the section and write the two instructions at the end. */
+ memset (loc, 0, offset);
+ loc += offset;
+ if (ELF_ST_IS_MICROMIPS (stub->h->root.other))
+ {
+ bfd_put_micromips_32 (hti->output_bfd,
+ LA25_LUI_MICROMIPS (target_high),
+ loc);
+ bfd_put_micromips_32 (hti->output_bfd,
+ LA25_ADDIU_MICROMIPS (target_low),
+ loc + 4);
+ }
+ else
+ {
+ bfd_put_32 (hti->output_bfd, LA25_LUI (target_high), loc);
+ bfd_put_32 (hti->output_bfd, LA25_ADDIU (target_low), loc + 4);
+ }
+ }
+ else
+ {
+ /* This is trampoline. */
+ loc += offset;
+ if (ELF_ST_IS_MICROMIPS (stub->h->root.other))
+ {
+ bfd_put_micromips_32 (hti->output_bfd,
+ LA25_LUI_MICROMIPS (target_high), loc);
+ bfd_put_micromips_32 (hti->output_bfd,
+ LA25_J_MICROMIPS (target), loc + 4);
+ bfd_put_micromips_32 (hti->output_bfd,
+ LA25_ADDIU_MICROMIPS (target_low), loc + 8);
+ bfd_put_32 (hti->output_bfd, 0, loc + 12);
+ }
+ else
+ {
+ bfd_put_32 (hti->output_bfd, LA25_LUI (target_high), loc);
+ bfd_put_32 (hti->output_bfd, LA25_J (target), loc + 4);
+ bfd_put_32 (hti->output_bfd, LA25_ADDIU (target_low), loc + 8);
+ bfd_put_32 (hti->output_bfd, 0, loc + 12);
+ }
+ }
+ return TRUE;
+}
+
+/* If NAME is one of the special IRIX6 symbols defined by the linker,
+ adjust it appropriately now. */
+
+static void
+mips_elf_irix6_finish_dynamic_symbol (bfd *abfd ATTRIBUTE_UNUSED,
+ const char *name, Elf_Internal_Sym *sym)
+{
+ /* The linker script takes care of providing names and values for
+ these, but we must place them into the right sections. */
+ static const char* const text_section_symbols[] = {
+ "_ftext",
+ "_etext",
+ "__dso_displacement",
+ "__elf_header",
+ "__program_header_table",
+ NULL
+ };
+
+ static const char* const data_section_symbols[] = {
+ "_fdata",
+ "_edata",
+ "_end",
+ "_fbss",
+ NULL
+ };
+
+ const char* const *p;
+ int i;
+
+ for (i = 0; i < 2; ++i)
+ for (p = (i == 0) ? text_section_symbols : data_section_symbols;
+ *p;
+ ++p)
+ if (strcmp (*p, name) == 0)
+ {
+ /* All of these symbols are given type STT_SECTION by the
+ IRIX6 linker. */
+ sym->st_info = ELF_ST_INFO (STB_GLOBAL, STT_SECTION);
+ sym->st_other = STO_PROTECTED;
+
+ /* The IRIX linker puts these symbols in special sections. */
+ if (i == 0)
+ sym->st_shndx = SHN_MIPS_TEXT;
+ else
+ sym->st_shndx = SHN_MIPS_DATA;
+
+ break;
+ }
+}
+
+/* Finish up dynamic symbol handling. We set the contents of various
+ dynamic sections here. */
+
+bfd_boolean
+_bfd_mips_elf_finish_dynamic_symbol (bfd *output_bfd,
+ struct bfd_link_info *info,
+ struct elf_link_hash_entry *h,
+ Elf_Internal_Sym *sym)
+{
+ bfd *dynobj;
+ asection *sgot;
+ struct mips_got_info *g, *gg;
+ const char *name;
+ int idx;
+ struct mips_elf_link_hash_table *htab;
+ struct mips_elf_link_hash_entry *hmips;
+
+ htab = mips_elf_hash_table (info);
+ BFD_ASSERT (htab != NULL);
+ dynobj = elf_hash_table (info)->dynobj;
+ hmips = (struct mips_elf_link_hash_entry *) h;
+
+ BFD_ASSERT (!htab->is_vxworks);
+
+ if (h->plt.plist != NULL
+ && (h->plt.plist->mips_offset != MINUS_ONE
+ || h->plt.plist->comp_offset != MINUS_ONE))
+ {
+ /* We've decided to create a PLT entry for this symbol. */
+ bfd_byte *loc;
+ bfd_vma header_address, got_address;
+ bfd_vma got_address_high, got_address_low, load;
+ bfd_vma got_index;
+ bfd_vma isa_bit;
+
+ got_index = h->plt.plist->gotplt_index;
+
+ BFD_ASSERT (htab->use_plts_and_copy_relocs);
+ BFD_ASSERT (h->dynindx != -1);
+ BFD_ASSERT (htab->splt != NULL);
+ BFD_ASSERT (got_index != MINUS_ONE);
+ BFD_ASSERT (!h->def_regular);
+
+ /* Calculate the address of the PLT header. */
+ isa_bit = htab->plt_header_is_comp;
+ header_address = (htab->splt->output_section->vma
+ + htab->splt->output_offset + isa_bit);
+
+ /* Calculate the address of the .got.plt entry. */
+ got_address = (htab->sgotplt->output_section->vma
+ + htab->sgotplt->output_offset
+ + got_index * MIPS_ELF_GOT_SIZE (dynobj));
+
+ got_address_high = ((got_address + 0x8000) >> 16) & 0xffff;
+ got_address_low = got_address & 0xffff;
+
+ /* Initially point the .got.plt entry at the PLT header. */
+ loc = (htab->sgotplt->contents + got_index * MIPS_ELF_GOT_SIZE (dynobj));
+ if (ABI_64_P (output_bfd))
+ bfd_put_64 (output_bfd, header_address, loc);
+ else
+ bfd_put_32 (output_bfd, header_address, loc);
+
+ /* Now handle the PLT itself. First the standard entry (the order
+ does not matter, we just have to pick one). */
+ if (h->plt.plist->mips_offset != MINUS_ONE)
+ {
+ const bfd_vma *plt_entry;
+ bfd_vma plt_offset;
+
+ plt_offset = htab->plt_header_size + h->plt.plist->mips_offset;
+
+ BFD_ASSERT (plt_offset <= htab->splt->size);
+
+ /* Find out where the .plt entry should go. */
+ loc = htab->splt->contents + plt_offset;
+
+ /* Pick the load opcode. */
+ load = MIPS_ELF_LOAD_WORD (output_bfd);
+
+ /* Fill in the PLT entry itself. */
+
+ if (MIPSR6_P (output_bfd))
+ plt_entry = mipsr6_exec_plt_entry;
+ else
+ plt_entry = mips_exec_plt_entry;
+ bfd_put_32 (output_bfd, plt_entry[0] | got_address_high, loc);
+ bfd_put_32 (output_bfd, plt_entry[1] | got_address_low | load,
+ loc + 4);
+
+ if (! LOAD_INTERLOCKS_P (output_bfd))
+ {
+ bfd_put_32 (output_bfd, plt_entry[2] | got_address_low, loc + 8);
+ bfd_put_32 (output_bfd, plt_entry[3], loc + 12);
+ }
+ else
+ {
+ bfd_put_32 (output_bfd, plt_entry[3], loc + 8);
+ bfd_put_32 (output_bfd, plt_entry[2] | got_address_low,
+ loc + 12);
+ }
+ }
+
+ /* Now the compressed entry. They come after any standard ones. */
+ if (h->plt.plist->comp_offset != MINUS_ONE)
+ {
+ bfd_vma plt_offset;
+
+ plt_offset = (htab->plt_header_size + htab->plt_mips_offset
+ + h->plt.plist->comp_offset);
+
+ BFD_ASSERT (plt_offset <= htab->splt->size);
+
+ /* Find out where the .plt entry should go. */
+ loc = htab->splt->contents + plt_offset;
+
+ /* Fill in the PLT entry itself. */
+ if (!MICROMIPS_P (output_bfd))
+ {
+ const bfd_vma *plt_entry = mips16_o32_exec_plt_entry;
+
+ bfd_put_16 (output_bfd, plt_entry[0], loc);
+ bfd_put_16 (output_bfd, plt_entry[1], loc + 2);
+ bfd_put_16 (output_bfd, plt_entry[2], loc + 4);
+ bfd_put_16 (output_bfd, plt_entry[3], loc + 6);
+ bfd_put_16 (output_bfd, plt_entry[4], loc + 8);
+ bfd_put_16 (output_bfd, plt_entry[5], loc + 10);
+ bfd_put_32 (output_bfd, got_address, loc + 12);
+ }
+ else if (htab->insn32)
+ {
+ const bfd_vma *plt_entry = micromips_insn32_o32_exec_plt_entry;
+
+ bfd_put_16 (output_bfd, plt_entry[0], loc);
+ bfd_put_16 (output_bfd, got_address_high, loc + 2);
+ bfd_put_16 (output_bfd, plt_entry[2], loc + 4);
+ bfd_put_16 (output_bfd, got_address_low, loc + 6);
+ bfd_put_16 (output_bfd, plt_entry[4], loc + 8);
+ bfd_put_16 (output_bfd, plt_entry[5], loc + 10);
+ bfd_put_16 (output_bfd, plt_entry[6], loc + 12);
+ bfd_put_16 (output_bfd, got_address_low, loc + 14);
+ }
+ else
+ {
+ const bfd_vma *plt_entry = micromips_o32_exec_plt_entry;
+ bfd_signed_vma gotpc_offset;
+ bfd_vma loc_address;
+
+ BFD_ASSERT (got_address % 4 == 0);
+
+ loc_address = (htab->splt->output_section->vma
+ + htab->splt->output_offset + plt_offset);
+ gotpc_offset = got_address - ((loc_address | 3) ^ 3);
+
+ /* ADDIUPC has a span of +/-16MB, check we're in range. */
+ if (gotpc_offset + 0x1000000 >= 0x2000000)
+ {
+ (*_bfd_error_handler)
+ (_("%B: `%A' offset of %ld from `%A' "
+ "beyond the range of ADDIUPC"),
+ output_bfd,
+ htab->sgotplt->output_section,
+ htab->splt->output_section,
+ (long) gotpc_offset);
+ bfd_set_error (bfd_error_no_error);
+ return FALSE;
+ }
+ bfd_put_16 (output_bfd,
+ plt_entry[0] | ((gotpc_offset >> 18) & 0x7f), loc);
+ bfd_put_16 (output_bfd, (gotpc_offset >> 2) & 0xffff, loc + 2);
+ bfd_put_16 (output_bfd, plt_entry[2], loc + 4);
+ bfd_put_16 (output_bfd, plt_entry[3], loc + 6);
+ bfd_put_16 (output_bfd, plt_entry[4], loc + 8);
+ bfd_put_16 (output_bfd, plt_entry[5], loc + 10);
+ }
+ }
+
+ /* Emit an R_MIPS_JUMP_SLOT relocation against the .got.plt entry. */
+ mips_elf_output_dynamic_relocation (output_bfd, htab->srelplt,
+ got_index - 2, h->dynindx,
+ R_MIPS_JUMP_SLOT, got_address);
+
+ /* We distinguish between PLT entries and lazy-binding stubs by
+ giving the former an st_other value of STO_MIPS_PLT. Set the
+ flag and leave the value if there are any relocations in the
+ binary where pointer equality matters. */
+ sym->st_shndx = SHN_UNDEF;
+ if (h->pointer_equality_needed)
+ sym->st_other = ELF_ST_SET_MIPS_PLT (sym->st_other);
+ else
+ {
+ sym->st_value = 0;
+ sym->st_other = 0;
+ }
+ }
+
+ if (h->plt.plist != NULL && h->plt.plist->stub_offset != MINUS_ONE)
+ {
+ /* We've decided to create a lazy-binding stub. */
+ bfd_boolean micromips_p = MICROMIPS_P (output_bfd);
+ unsigned int other = micromips_p ? STO_MICROMIPS : 0;
+ bfd_vma stub_size = htab->function_stub_size;
+ bfd_byte stub[MIPS_FUNCTION_STUB_BIG_SIZE];
+ bfd_vma isa_bit = micromips_p;
+ bfd_vma stub_big_size;
+
+ if (!micromips_p)
+ stub_big_size = MIPS_FUNCTION_STUB_BIG_SIZE;
+ else if (htab->insn32)
+ stub_big_size = MICROMIPS_INSN32_FUNCTION_STUB_BIG_SIZE;
+ else
+ stub_big_size = MICROMIPS_FUNCTION_STUB_BIG_SIZE;
+
+ /* This symbol has a stub. Set it up. */
+
+ BFD_ASSERT (h->dynindx != -1);
+
+ BFD_ASSERT (stub_size == stub_big_size || h->dynindx <= 0xffff);
+
+ /* Values up to 2^31 - 1 are allowed. Larger values would cause
+ sign extension at runtime in the stub, resulting in a negative
+ index value. */
+ if (h->dynindx & ~0x7fffffff)
+ return FALSE;
+
+ /* Fill the stub. */
+ if (micromips_p)
+ {
+ idx = 0;
+ bfd_put_micromips_32 (output_bfd, STUB_LW_MICROMIPS (output_bfd),
+ stub + idx);
+ idx += 4;
+ if (htab->insn32)
+ {
+ bfd_put_micromips_32 (output_bfd,
+ STUB_MOVE32_MICROMIPS (output_bfd),
+ stub + idx);
+ idx += 4;
+ }
+ else
+ {
+ bfd_put_16 (output_bfd, STUB_MOVE_MICROMIPS, stub + idx);
+ idx += 2;
+ }
+ if (stub_size == stub_big_size)
+ {
+ long dynindx_hi = (h->dynindx >> 16) & 0x7fff;
+
+ bfd_put_micromips_32 (output_bfd,
+ STUB_LUI_MICROMIPS (dynindx_hi),
+ stub + idx);
+ idx += 4;
+ }
+ if (htab->insn32)
+ {
+ bfd_put_micromips_32 (output_bfd, STUB_JALR32_MICROMIPS,
+ stub + idx);
+ idx += 4;
+ }
+ else
+ {
+ bfd_put_16 (output_bfd, STUB_JALR_MICROMIPS, stub + idx);
+ idx += 2;
+ }
+
+ /* If a large stub is not required and sign extension is not a
+ problem, then use legacy code in the stub. */
+ if (stub_size == stub_big_size)
+ bfd_put_micromips_32 (output_bfd,
+ STUB_ORI_MICROMIPS (h->dynindx & 0xffff),
+ stub + idx);
+ else if (h->dynindx & ~0x7fff)
+ bfd_put_micromips_32 (output_bfd,
+ STUB_LI16U_MICROMIPS (h->dynindx & 0xffff),
+ stub + idx);
+ else
+ bfd_put_micromips_32 (output_bfd,
+ STUB_LI16S_MICROMIPS (output_bfd,
+ h->dynindx),
+ stub + idx);
+ }
+ else
+ {
+ idx = 0;
+ bfd_put_32 (output_bfd, STUB_LW (output_bfd), stub + idx);
+ idx += 4;
+ bfd_put_32 (output_bfd, STUB_MOVE (output_bfd), stub + idx);
+ idx += 4;
+ if (stub_size == stub_big_size)
+ {
+ bfd_put_32 (output_bfd, STUB_LUI ((h->dynindx >> 16) & 0x7fff),
+ stub + idx);
+ idx += 4;
+ }
+ bfd_put_32 (output_bfd, STUB_JALR, stub + idx);
+ idx += 4;
+
+ /* If a large stub is not required and sign extension is not a
+ problem, then use legacy code in the stub. */
+ if (stub_size == stub_big_size)
+ bfd_put_32 (output_bfd, STUB_ORI (h->dynindx & 0xffff),
+ stub + idx);
+ else if (h->dynindx & ~0x7fff)
+ bfd_put_32 (output_bfd, STUB_LI16U (h->dynindx & 0xffff),
+ stub + idx);
+ else
+ bfd_put_32 (output_bfd, STUB_LI16S (output_bfd, h->dynindx),
+ stub + idx);
+ }
+
+ BFD_ASSERT (h->plt.plist->stub_offset <= htab->sstubs->size);
+ memcpy (htab->sstubs->contents + h->plt.plist->stub_offset,
+ stub, stub_size);
+
+ /* Mark the symbol as undefined. stub_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. */
+ sym->st_value = (htab->sstubs->output_section->vma
+ + htab->sstubs->output_offset
+ + h->plt.plist->stub_offset
+ + isa_bit);
+ sym->st_other = other;
+ }
+
+ /* If we have a MIPS16 function with a stub, the dynamic symbol must
+ refer to the stub, since only the stub uses the standard calling
+ conventions. */
+ if (h->dynindx != -1 && hmips->fn_stub != NULL)
+ {
+ BFD_ASSERT (hmips->need_fn_stub);
+ sym->st_value = (hmips->fn_stub->output_section->vma
+ + hmips->fn_stub->output_offset);
+ sym->st_size = hmips->fn_stub->size;
+ sym->st_other = ELF_ST_VISIBILITY (sym->st_other);
+ }
+
+ BFD_ASSERT (h->dynindx != -1
+ || h->forced_local);
+
+ sgot = htab->sgot;
+ g = htab->got_info;
+ BFD_ASSERT (g != NULL);
+
+ /* Run through the global symbol table, creating GOT entries for all
+ the symbols that need them. */
+ if (hmips->global_got_area != GGA_NONE)
+ {
+ bfd_vma offset;
+ bfd_vma value;
+
+ value = sym->st_value;
+ offset = mips_elf_primary_global_got_index (output_bfd, info, h);
+ MIPS_ELF_PUT_WORD (output_bfd, value, sgot->contents + offset);
+ }
+
+ if (hmips->global_got_area != GGA_NONE && g->next)
+ {
+ struct mips_got_entry e, *p;
+ bfd_vma entry;
+ bfd_vma offset;
+
+ gg = g;
+
+ e.abfd = output_bfd;
+ e.symndx = -1;
+ e.d.h = hmips;
+ e.tls_type = GOT_TLS_NONE;
+
+ for (g = g->next; g->next != gg; g = g->next)
+ {
+ if (g->got_entries
+ && (p = (struct mips_got_entry *) htab_find (g->got_entries,
+ &e)))
+ {
+ offset = p->gotidx;
+ BFD_ASSERT (offset > 0 && offset < htab->sgot->size);
+ if (info->shared
+ || (elf_hash_table (info)->dynamic_sections_created
+ && p->d.h != NULL
+ && p->d.h->root.def_dynamic
+ && !p->d.h->root.def_regular))
+ {
+ /* Create an R_MIPS_REL32 relocation for this entry. Due to
+ the various compatibility problems, it's easier to mock
+ up an R_MIPS_32 or R_MIPS_64 relocation and leave
+ mips_elf_create_dynamic_relocation to calculate the
+ appropriate addend. */
+ Elf_Internal_Rela rel[3];
+
+ memset (rel, 0, sizeof (rel));
+ if (ABI_64_P (output_bfd))
+ rel[0].r_info = ELF_R_INFO (output_bfd, 0, R_MIPS_64);
+ else
+ rel[0].r_info = ELF_R_INFO (output_bfd, 0, R_MIPS_32);
+ rel[0].r_offset = rel[1].r_offset = rel[2].r_offset = offset;
+
+ entry = 0;
+ if (! (mips_elf_create_dynamic_relocation
+ (output_bfd, info, rel,
+ e.d.h, NULL, sym->st_value, &entry, sgot)))
+ return FALSE;
+ }
+ else
+ entry = sym->st_value;
+ MIPS_ELF_PUT_WORD (output_bfd, entry, sgot->contents + offset);
+ }
+ }
+ }
+
+ /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute. */
+ name = h->root.root.string;
+ if (h == elf_hash_table (info)->hdynamic
+ || h == elf_hash_table (info)->hgot)
+ sym->st_shndx = SHN_ABS;
+ else if (strcmp (name, "_DYNAMIC_LINK") == 0
+ || strcmp (name, "_DYNAMIC_LINKING") == 0)
+ {
+ sym->st_shndx = SHN_ABS;
+ sym->st_info = ELF_ST_INFO (STB_GLOBAL, STT_SECTION);
+ sym->st_value = 1;
+ }
+ else if (strcmp (name, "_gp_disp") == 0 && ! NEWABI_P (output_bfd))
+ {
+ sym->st_shndx = SHN_ABS;
+ sym->st_info = ELF_ST_INFO (STB_GLOBAL, STT_SECTION);
+ sym->st_value = elf_gp (output_bfd);
+ }
+ else if (SGI_COMPAT (output_bfd))
+ {
+ 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;
+ }
+ }
+
+ /* Emit a copy reloc, if needed. */
+ if (h->needs_copy)
+ {
+ asection *s;
+ bfd_vma symval;
+
+ BFD_ASSERT (h->dynindx != -1);
+ BFD_ASSERT (htab->use_plts_and_copy_relocs);
+
+ s = mips_elf_rel_dyn_section (info, FALSE);
+ symval = (h->root.u.def.section->output_section->vma
+ + h->root.u.def.section->output_offset
+ + h->root.u.def.value);
+ mips_elf_output_dynamic_relocation (output_bfd, s, s->reloc_count++,
+ h->dynindx, R_MIPS_COPY, symval);
+ }
+
+ /* Handle the IRIX6-specific symbols. */
+ if (IRIX_COMPAT (output_bfd) == ict_irix6)
+ mips_elf_irix6_finish_dynamic_symbol (output_bfd, name, sym);
+
+ /* Keep dynamic compressed symbols odd. This allows the dynamic linker
+ to treat compressed symbols like any other. */
+ if (ELF_ST_IS_MIPS16 (sym->st_other))
+ {
+ BFD_ASSERT (sym->st_value & 1);
+ sym->st_other -= STO_MIPS16;
+ }
+ else if (ELF_ST_IS_MICROMIPS (sym->st_other))
+ {
+ BFD_ASSERT (sym->st_value & 1);
+ sym->st_other -= STO_MICROMIPS;
+ }
+
+ return TRUE;
+}
+
+/* Likewise, for VxWorks. */
+
+bfd_boolean
+_bfd_mips_vxworks_finish_dynamic_symbol (bfd *output_bfd,
+ struct bfd_link_info *info,
+ struct elf_link_hash_entry *h,
+ Elf_Internal_Sym *sym)
+{
+ bfd *dynobj;
+ asection *sgot;
+ struct mips_got_info *g;
+ struct mips_elf_link_hash_table *htab;
+ struct mips_elf_link_hash_entry *hmips;
+
+ htab = mips_elf_hash_table (info);
+ BFD_ASSERT (htab != NULL);
+ dynobj = elf_hash_table (info)->dynobj;
+ hmips = (struct mips_elf_link_hash_entry *) h;
+
+ if (h->plt.plist != NULL && h->plt.plist->mips_offset != MINUS_ONE)
+ {
+ bfd_byte *loc;
+ bfd_vma plt_address, got_address, got_offset, branch_offset;
+ Elf_Internal_Rela rel;
+ static const bfd_vma *plt_entry;
+ bfd_vma gotplt_index;
+ bfd_vma plt_offset;
+
+ plt_offset = htab->plt_header_size + h->plt.plist->mips_offset;
+ gotplt_index = h->plt.plist->gotplt_index;
+
+ BFD_ASSERT (h->dynindx != -1);
+ BFD_ASSERT (htab->splt != NULL);
+ BFD_ASSERT (gotplt_index != MINUS_ONE);
+ BFD_ASSERT (plt_offset <= htab->splt->size);
+
+ /* Calculate the address of the .plt entry. */
+ plt_address = (htab->splt->output_section->vma
+ + htab->splt->output_offset
+ + plt_offset);
+
+ /* Calculate the address of the .got.plt entry. */
+ got_address = (htab->sgotplt->output_section->vma
+ + htab->sgotplt->output_offset
+ + gotplt_index * MIPS_ELF_GOT_SIZE (output_bfd));
+
+ /* Calculate the offset of the .got.plt entry from
+ _GLOBAL_OFFSET_TABLE_. */
+ got_offset = mips_elf_gotplt_index (info, h);
+
+ /* Calculate the offset for the branch at the start of the PLT
+ entry. The branch jumps to the beginning of .plt. */
+ branch_offset = -(plt_offset / 4 + 1) & 0xffff;
+
+ /* Fill in the initial value of the .got.plt entry. */
+ bfd_put_32 (output_bfd, plt_address,
+ (htab->sgotplt->contents
+ + gotplt_index * MIPS_ELF_GOT_SIZE (output_bfd)));
+
+ /* Find out where the .plt entry should go. */
+ loc = htab->splt->contents + plt_offset;
+
+ if (info->shared)
+ {
+ plt_entry = mips_vxworks_shared_plt_entry;
+ bfd_put_32 (output_bfd, plt_entry[0] | branch_offset, loc);
+ bfd_put_32 (output_bfd, plt_entry[1] | gotplt_index, loc + 4);
+ }
+ else
+ {
+ bfd_vma got_address_high, got_address_low;
+
+ plt_entry = mips_vxworks_exec_plt_entry;
+ got_address_high = ((got_address + 0x8000) >> 16) & 0xffff;
+ got_address_low = got_address & 0xffff;
+
+ bfd_put_32 (output_bfd, plt_entry[0] | branch_offset, loc);
+ bfd_put_32 (output_bfd, plt_entry[1] | gotplt_index, loc + 4);
+ bfd_put_32 (output_bfd, plt_entry[2] | got_address_high, loc + 8);
+ bfd_put_32 (output_bfd, plt_entry[3] | got_address_low, loc + 12);
+ bfd_put_32 (output_bfd, plt_entry[4], loc + 16);
+ bfd_put_32 (output_bfd, plt_entry[5], loc + 20);
+ bfd_put_32 (output_bfd, plt_entry[6], loc + 24);
+ bfd_put_32 (output_bfd, plt_entry[7], loc + 28);
+
+ loc = (htab->srelplt2->contents
+ + (gotplt_index * 3 + 2) * sizeof (Elf32_External_Rela));
+
+ /* Emit a relocation for the .got.plt entry. */
+ rel.r_offset = got_address;
+ rel.r_info = ELF32_R_INFO (htab->root.hplt->indx, R_MIPS_32);
+ rel.r_addend = plt_offset;
+ bfd_elf32_swap_reloca_out (output_bfd, &rel, loc);
+
+ /* Emit a relocation for the lui of %hi(<.got.plt slot>). */
+ loc += sizeof (Elf32_External_Rela);
+ rel.r_offset = plt_address + 8;
+ rel.r_info = ELF32_R_INFO (htab->root.hgot->indx, R_MIPS_HI16);
+ rel.r_addend = got_offset;
+ bfd_elf32_swap_reloca_out (output_bfd, &rel, loc);
+
+ /* Emit a relocation for the addiu of %lo(<.got.plt slot>). */
+ loc += sizeof (Elf32_External_Rela);
+ rel.r_offset += 4;
+ rel.r_info = ELF32_R_INFO (htab->root.hgot->indx, R_MIPS_LO16);
+ bfd_elf32_swap_reloca_out (output_bfd, &rel, loc);
+ }
+
+ /* Emit an R_MIPS_JUMP_SLOT relocation against the .got.plt entry. */
+ loc = (htab->srelplt->contents
+ + gotplt_index * sizeof (Elf32_External_Rela));
+ rel.r_offset = got_address;
+ rel.r_info = ELF32_R_INFO (h->dynindx, R_MIPS_JUMP_SLOT);
+ rel.r_addend = 0;
+ bfd_elf32_swap_reloca_out (output_bfd, &rel, loc);
+
+ if (!h->def_regular)
+ sym->st_shndx = SHN_UNDEF;
+ }
+
+ BFD_ASSERT (h->dynindx != -1 || h->forced_local);
+
+ sgot = htab->sgot;
+ g = htab->got_info;
+ BFD_ASSERT (g != NULL);
+
+ /* See if this symbol has an entry in the GOT. */
+ if (hmips->global_got_area != GGA_NONE)
+ {
+ bfd_vma offset;
+ Elf_Internal_Rela outrel;
+ bfd_byte *loc;
+ asection *s;
+
+ /* Install the symbol value in the GOT. */
+ offset = mips_elf_primary_global_got_index (output_bfd, info, h);
+ MIPS_ELF_PUT_WORD (output_bfd, sym->st_value, sgot->contents + offset);
+
+ /* Add a dynamic relocation for it. */
+ s = mips_elf_rel_dyn_section (info, FALSE);
+ loc = s->contents + (s->reloc_count++ * sizeof (Elf32_External_Rela));
+ outrel.r_offset = (sgot->output_section->vma
+ + sgot->output_offset
+ + offset);
+ outrel.r_info = ELF32_R_INFO (h->dynindx, R_MIPS_32);
+ outrel.r_addend = 0;
+ bfd_elf32_swap_reloca_out (dynobj, &outrel, loc);
+ }
+
+ /* Emit a copy reloc, if needed. */
+ if (h->needs_copy)
+ {
+ Elf_Internal_Rela rel;
+
+ BFD_ASSERT (h->dynindx != -1);
+
+ rel.r_offset = (h->root.u.def.section->output_section->vma
+ + h->root.u.def.section->output_offset
+ + h->root.u.def.value);
+ rel.r_info = ELF32_R_INFO (h->dynindx, R_MIPS_COPY);
+ rel.r_addend = 0;
+ bfd_elf32_swap_reloca_out (output_bfd, &rel,
+ htab->srelbss->contents
+ + (htab->srelbss->reloc_count
+ * sizeof (Elf32_External_Rela)));
+ ++htab->srelbss->reloc_count;
+ }
+
+ /* If this is a mips16/microMIPS symbol, force the value to be even. */
+ if (ELF_ST_IS_COMPRESSED (sym->st_other))
+ sym->st_value &= ~1;
+
+ return TRUE;
+}
+
+/* Write out a plt0 entry to the beginning of .plt. */
+
+static bfd_boolean
+mips_finish_exec_plt (bfd *output_bfd, struct bfd_link_info *info)
+{
+ bfd_byte *loc;
+ bfd_vma gotplt_value, gotplt_value_high, gotplt_value_low;
+ static const bfd_vma *plt_entry;
+ struct mips_elf_link_hash_table *htab;
+
+ htab = mips_elf_hash_table (info);
+ BFD_ASSERT (htab != NULL);
+
+ if (ABI_64_P (output_bfd))
+ plt_entry = mips_n64_exec_plt0_entry;
+ else if (ABI_N32_P (output_bfd))
+ plt_entry = mips_n32_exec_plt0_entry;
+ else if (!htab->plt_header_is_comp)
+ plt_entry = mips_o32_exec_plt0_entry;
+ else if (htab->insn32)
+ plt_entry = micromips_insn32_o32_exec_plt0_entry;
+ else
+ plt_entry = micromips_o32_exec_plt0_entry;
+
+ /* Calculate the value of .got.plt. */
+ gotplt_value = (htab->sgotplt->output_section->vma
+ + htab->sgotplt->output_offset);
+ gotplt_value_high = ((gotplt_value + 0x8000) >> 16) & 0xffff;
+ gotplt_value_low = gotplt_value & 0xffff;
+
+ /* The PLT sequence is not safe for N64 if .got.plt's address can
+ not be loaded in two instructions. */
+ BFD_ASSERT ((gotplt_value & ~(bfd_vma) 0x7fffffff) == 0
+ || ~(gotplt_value | 0x7fffffff) == 0);
+
+ /* Install the PLT header. */
+ loc = htab->splt->contents;
+ if (plt_entry == micromips_o32_exec_plt0_entry)
+ {
+ bfd_vma gotpc_offset;
+ bfd_vma loc_address;
+ size_t i;
+
+ BFD_ASSERT (gotplt_value % 4 == 0);
+
+ loc_address = (htab->splt->output_section->vma
+ + htab->splt->output_offset);
+ gotpc_offset = gotplt_value - ((loc_address | 3) ^ 3);
+
+ /* ADDIUPC has a span of +/-16MB, check we're in range. */
+ if (gotpc_offset + 0x1000000 >= 0x2000000)
+ {
+ (*_bfd_error_handler)
+ (_("%B: `%A' offset of %ld from `%A' beyond the range of ADDIUPC"),
+ output_bfd,
+ htab->sgotplt->output_section,
+ htab->splt->output_section,
+ (long) gotpc_offset);
+ bfd_set_error (bfd_error_no_error);
+ return FALSE;
+ }
+ bfd_put_16 (output_bfd,
+ plt_entry[0] | ((gotpc_offset >> 18) & 0x7f), loc);
+ bfd_put_16 (output_bfd, (gotpc_offset >> 2) & 0xffff, loc + 2);
+ for (i = 2; i < ARRAY_SIZE (micromips_o32_exec_plt0_entry); i++)
+ bfd_put_16 (output_bfd, plt_entry[i], loc + (i * 2));
+ }
+ else if (plt_entry == micromips_insn32_o32_exec_plt0_entry)
+ {
+ size_t i;
+
+ bfd_put_16 (output_bfd, plt_entry[0], loc);
+ bfd_put_16 (output_bfd, gotplt_value_high, loc + 2);
+ bfd_put_16 (output_bfd, plt_entry[2], loc + 4);
+ bfd_put_16 (output_bfd, gotplt_value_low, loc + 6);
+ bfd_put_16 (output_bfd, plt_entry[4], loc + 8);
+ bfd_put_16 (output_bfd, gotplt_value_low, loc + 10);
+ for (i = 6; i < ARRAY_SIZE (micromips_insn32_o32_exec_plt0_entry); i++)
+ bfd_put_16 (output_bfd, plt_entry[i], loc + (i * 2));
+ }
+ else
+ {
+ bfd_put_32 (output_bfd, plt_entry[0] | gotplt_value_high, loc);
+ bfd_put_32 (output_bfd, plt_entry[1] | gotplt_value_low, loc + 4);
+ bfd_put_32 (output_bfd, plt_entry[2] | gotplt_value_low, loc + 8);
+ bfd_put_32 (output_bfd, plt_entry[3], loc + 12);
+ bfd_put_32 (output_bfd, plt_entry[4], loc + 16);
+ bfd_put_32 (output_bfd, plt_entry[5], loc + 20);
+ bfd_put_32 (output_bfd, plt_entry[6], loc + 24);
+ bfd_put_32 (output_bfd, plt_entry[7], loc + 28);
+ }
+
+ return TRUE;
+}
+
+/* Install the PLT header for a VxWorks executable and finalize the
+ contents of .rela.plt.unloaded. */
+
+static void
+mips_vxworks_finish_exec_plt (bfd *output_bfd, struct bfd_link_info *info)
+{
+ Elf_Internal_Rela rela;
+ bfd_byte *loc;
+ bfd_vma got_value, got_value_high, got_value_low, plt_address;
+ static const bfd_vma *plt_entry;
+ struct mips_elf_link_hash_table *htab;
+
+ htab = mips_elf_hash_table (info);
+ BFD_ASSERT (htab != NULL);
+
+ plt_entry = mips_vxworks_exec_plt0_entry;
+
+ /* Calculate the value of _GLOBAL_OFFSET_TABLE_. */
+ got_value = (htab->root.hgot->root.u.def.section->output_section->vma
+ + htab->root.hgot->root.u.def.section->output_offset
+ + htab->root.hgot->root.u.def.value);
+
+ got_value_high = ((got_value + 0x8000) >> 16) & 0xffff;
+ got_value_low = got_value & 0xffff;
+
+ /* Calculate the address of the PLT header. */
+ plt_address = htab->splt->output_section->vma + htab->splt->output_offset;
+
+ /* Install the PLT header. */
+ loc = htab->splt->contents;
+ bfd_put_32 (output_bfd, plt_entry[0] | got_value_high, loc);
+ bfd_put_32 (output_bfd, plt_entry[1] | got_value_low, loc + 4);
+ bfd_put_32 (output_bfd, plt_entry[2], loc + 8);
+ bfd_put_32 (output_bfd, plt_entry[3], loc + 12);
+ bfd_put_32 (output_bfd, plt_entry[4], loc + 16);
+ bfd_put_32 (output_bfd, plt_entry[5], loc + 20);
+
+ /* Output the relocation for the lui of %hi(_GLOBAL_OFFSET_TABLE_). */
+ loc = htab->srelplt2->contents;
+ rela.r_offset = plt_address;
+ rela.r_info = ELF32_R_INFO (htab->root.hgot->indx, R_MIPS_HI16);
+ rela.r_addend = 0;
+ bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
+ loc += sizeof (Elf32_External_Rela);
+
+ /* Output the relocation for the following addiu of
+ %lo(_GLOBAL_OFFSET_TABLE_). */
+ rela.r_offset += 4;
+ rela.r_info = ELF32_R_INFO (htab->root.hgot->indx, R_MIPS_LO16);
+ bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
+ loc += sizeof (Elf32_External_Rela);
+
+ /* Fix up the remaining relocations. They may have the wrong
+ symbol index for _G_O_T_ or _P_L_T_ depending on the order
+ in which symbols were output. */
+ while (loc < htab->srelplt2->contents + htab->srelplt2->size)
+ {
+ Elf_Internal_Rela rel;
+
+ bfd_elf32_swap_reloca_in (output_bfd, loc, &rel);
+ rel.r_info = ELF32_R_INFO (htab->root.hplt->indx, R_MIPS_32);
+ bfd_elf32_swap_reloca_out (output_bfd, &rel, loc);
+ loc += sizeof (Elf32_External_Rela);
+
+ bfd_elf32_swap_reloca_in (output_bfd, loc, &rel);
+ rel.r_info = ELF32_R_INFO (htab->root.hgot->indx, R_MIPS_HI16);
+ bfd_elf32_swap_reloca_out (output_bfd, &rel, loc);
+ loc += sizeof (Elf32_External_Rela);
+
+ bfd_elf32_swap_reloca_in (output_bfd, loc, &rel);
+ rel.r_info = ELF32_R_INFO (htab->root.hgot->indx, R_MIPS_LO16);
+ bfd_elf32_swap_reloca_out (output_bfd, &rel, loc);
+ loc += sizeof (Elf32_External_Rela);
+ }
+}
+
+/* Install the PLT header for a VxWorks shared library. */
+
+static void
+mips_vxworks_finish_shared_plt (bfd *output_bfd, struct bfd_link_info *info)
+{
+ unsigned int i;
+ struct mips_elf_link_hash_table *htab;
+
+ htab = mips_elf_hash_table (info);
+ BFD_ASSERT (htab != NULL);
+
+ /* We just need to copy the entry byte-by-byte. */
+ for (i = 0; i < ARRAY_SIZE (mips_vxworks_shared_plt0_entry); i++)
+ bfd_put_32 (output_bfd, mips_vxworks_shared_plt0_entry[i],
+ htab->splt->contents + i * 4);
+}
+
+/* Finish up the dynamic sections. */
+
+bfd_boolean
+_bfd_mips_elf_finish_dynamic_sections (bfd *output_bfd,
+ struct bfd_link_info *info)
+{
+ bfd *dynobj;
+ asection *sdyn;
+ asection *sgot;
+ struct mips_got_info *gg, *g;
+ struct mips_elf_link_hash_table *htab;
+
+ htab = mips_elf_hash_table (info);
+ BFD_ASSERT (htab != NULL);
+
+ dynobj = elf_hash_table (info)->dynobj;
+
+ sdyn = bfd_get_linker_section (dynobj, ".dynamic");
+
+ sgot = htab->sgot;
+ gg = htab->got_info;
+
+ if (elf_hash_table (info)->dynamic_sections_created)
+ {
+ bfd_byte *b;
+ int dyn_to_skip = 0, dyn_skipped = 0;
+
+ BFD_ASSERT (sdyn != NULL);
+ BFD_ASSERT (gg != NULL);
+
+ g = mips_elf_bfd_got (output_bfd, FALSE);
+ BFD_ASSERT (g != NULL);
+
+ for (b = sdyn->contents;
+ b < sdyn->contents + sdyn->size;
+ b += MIPS_ELF_DYN_SIZE (dynobj))
+ {
+ Elf_Internal_Dyn dyn;
+ const char *name;
+ size_t elemsize;
+ asection *s;
+ bfd_boolean swap_out_p;
+
+ /* Read in the current dynamic entry. */
+ (*get_elf_backend_data (dynobj)->s->swap_dyn_in) (dynobj, b, &dyn);
+
+ /* Assume that we're going to modify it and write it out. */
+ swap_out_p = TRUE;
+
+ switch (dyn.d_tag)
+ {
+ case DT_RELENT:
+ dyn.d_un.d_val = MIPS_ELF_REL_SIZE (dynobj);
+ break;
+
+ case DT_RELAENT:
+ BFD_ASSERT (htab->is_vxworks);
+ dyn.d_un.d_val = MIPS_ELF_RELA_SIZE (dynobj);
+ break;
+
+ case DT_STRSZ:
+ /* Rewrite DT_STRSZ. */
+ dyn.d_un.d_val =
+ _bfd_elf_strtab_size (elf_hash_table (info)->dynstr);
+ break;
+
+ case DT_PLTGOT:
+ s = htab->sgot;
+ dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
+ break;
+
+ case DT_MIPS_PLTGOT:
+ s = htab->sgotplt;
+ dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
+ break;
+
+ case DT_MIPS_RLD_VERSION:
+ dyn.d_un.d_val = 1; /* XXX */
+ break;
+
+ case DT_MIPS_FLAGS:
+ dyn.d_un.d_val = RHF_NOTPOT; /* XXX */
+ break;
+
+ case DT_MIPS_TIME_STAMP:
+ {
+ time_t t;
+ time (&t);
+ dyn.d_un.d_val = t;
+ }
+ break;
+
+ case DT_MIPS_ICHECKSUM:
+ /* XXX FIXME: */
+ swap_out_p = FALSE;
+ break;
+
+ case DT_MIPS_IVERSION:
+ /* XXX FIXME: */
+ swap_out_p = FALSE;
+ break;
+
+ case DT_MIPS_BASE_ADDRESS:
+ s = output_bfd->sections;
+ BFD_ASSERT (s != NULL);
+ dyn.d_un.d_ptr = s->vma & ~(bfd_vma) 0xffff;
+ break;
+
+ case DT_MIPS_LOCAL_GOTNO:
+ dyn.d_un.d_val = g->local_gotno;
+ break;
+
+ case DT_MIPS_UNREFEXTNO:
+ /* The index into the dynamic symbol table which is the
+ entry of the first external symbol that is not
+ referenced within the same object. */
+ dyn.d_un.d_val = bfd_count_sections (output_bfd) + 1;
+ break;
+
+ case DT_MIPS_GOTSYM:
+ if (htab->global_gotsym)
+ {
+ dyn.d_un.d_val = htab->global_gotsym->dynindx;
+ break;
+ }
+ /* In case if we don't have global got symbols we default
+ to setting DT_MIPS_GOTSYM to the same value as
+ DT_MIPS_SYMTABNO, so we just fall through. */
+
+ case DT_MIPS_SYMTABNO:
+ name = ".dynsym";
+ elemsize = MIPS_ELF_SYM_SIZE (output_bfd);
+ s = bfd_get_section_by_name (output_bfd, name);
+ BFD_ASSERT (s != NULL);
+
+ dyn.d_un.d_val = s->size / elemsize;
+ break;
+
+ case DT_MIPS_HIPAGENO:
+ dyn.d_un.d_val = g->local_gotno - htab->reserved_gotno;
+ break;
+
+ case DT_MIPS_RLD_MAP:
+ {
+ struct elf_link_hash_entry *h;
+ h = mips_elf_hash_table (info)->rld_symbol;
+ if (!h)
+ {
+ dyn_to_skip = MIPS_ELF_DYN_SIZE (dynobj);
+ swap_out_p = FALSE;
+ break;
+ }
+ s = h->root.u.def.section;
+ dyn.d_un.d_ptr = (s->output_section->vma + s->output_offset
+ + h->root.u.def.value);
+ }
+ break;
+
+ case DT_MIPS_OPTIONS:
+ s = (bfd_get_section_by_name
+ (output_bfd, MIPS_ELF_OPTIONS_SECTION_NAME (output_bfd)));
+ dyn.d_un.d_ptr = s->vma;
+ break;
+
+ case DT_RELASZ:
+ BFD_ASSERT (htab->is_vxworks);
+ /* The count does not include the JUMP_SLOT relocations. */
+ if (htab->srelplt)
+ dyn.d_un.d_val -= htab->srelplt->size;
+ break;
+
+ case DT_PLTREL:
+ BFD_ASSERT (htab->use_plts_and_copy_relocs);
+ if (htab->is_vxworks)
+ dyn.d_un.d_val = DT_RELA;
+ else
+ dyn.d_un.d_val = DT_REL;
+ break;
+
+ case DT_PLTRELSZ:
+ BFD_ASSERT (htab->use_plts_and_copy_relocs);
+ dyn.d_un.d_val = htab->srelplt->size;
+ break;
+
+ case DT_JMPREL:
+ BFD_ASSERT (htab->use_plts_and_copy_relocs);
+ dyn.d_un.d_ptr = (htab->srelplt->output_section->vma
+ + htab->srelplt->output_offset);
+ break;
+
+ case DT_TEXTREL:
+ /* If we didn't need any text relocations after all, delete
+ the dynamic tag. */
+ if (!(info->flags & DF_TEXTREL))
+ {
+ dyn_to_skip = MIPS_ELF_DYN_SIZE (dynobj);
+ swap_out_p = FALSE;
+ }
+ break;
+
+ case DT_FLAGS:
+ /* If we didn't need any text relocations after all, clear
+ DF_TEXTREL from DT_FLAGS. */
+ if (!(info->flags & DF_TEXTREL))
+ dyn.d_un.d_val &= ~DF_TEXTREL;
+ else
+ swap_out_p = FALSE;
+ break;
+
+ default:
+ swap_out_p = FALSE;
+ if (htab->is_vxworks
+ && elf_vxworks_finish_dynamic_entry (output_bfd, &dyn))
+ swap_out_p = TRUE;
+ break;
+ }
+
+ if (swap_out_p || dyn_skipped)
+ (*get_elf_backend_data (dynobj)->s->swap_dyn_out)
+ (dynobj, &dyn, b - dyn_skipped);
+
+ if (dyn_to_skip)
+ {
+ dyn_skipped += dyn_to_skip;
+ dyn_to_skip = 0;
+ }
+ }
+
+ /* Wipe out any trailing entries if we shifted down a dynamic tag. */
+ if (dyn_skipped > 0)
+ memset (b - dyn_skipped, 0, dyn_skipped);
+ }
+
+ if (sgot != NULL && sgot->size > 0
+ && !bfd_is_abs_section (sgot->output_section))
+ {
+ if (htab->is_vxworks)
+ {
+ /* The first entry of the global offset table points to the
+ ".dynamic" section. The second is initialized by the
+ loader and contains the shared library identifier.
+ The third is also initialized by the loader and points
+ to the lazy resolution stub. */
+ MIPS_ELF_PUT_WORD (output_bfd,
+ sdyn->output_offset + sdyn->output_section->vma,
+ sgot->contents);
+ MIPS_ELF_PUT_WORD (output_bfd, 0,
+ sgot->contents + MIPS_ELF_GOT_SIZE (output_bfd));
+ MIPS_ELF_PUT_WORD (output_bfd, 0,
+ sgot->contents
+ + 2 * MIPS_ELF_GOT_SIZE (output_bfd));
+ }
+ else
+ {
+ /* 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. */
+ MIPS_ELF_PUT_WORD (output_bfd, (bfd_vma) 0, sgot->contents);
+ MIPS_ELF_PUT_WORD (output_bfd, MIPS_ELF_GNU_GOT1_MASK (output_bfd),
+ sgot->contents + MIPS_ELF_GOT_SIZE (output_bfd));
+ }
+
+ elf_section_data (sgot->output_section)->this_hdr.sh_entsize
+ = MIPS_ELF_GOT_SIZE (output_bfd);
+ }
+
+ /* Generate dynamic relocations for the non-primary gots. */
+ if (gg != NULL && gg->next)
+ {
+ Elf_Internal_Rela rel[3];
+ bfd_vma addend = 0;
+
+ memset (rel, 0, sizeof (rel));
+ rel[0].r_info = ELF_R_INFO (output_bfd, 0, R_MIPS_REL32);
+
+ for (g = gg->next; g->next != gg; g = g->next)
+ {
+ bfd_vma got_index = g->next->local_gotno + g->next->global_gotno
+ + g->next->tls_gotno;
+
+ MIPS_ELF_PUT_WORD (output_bfd, 0, sgot->contents
+ + got_index++ * MIPS_ELF_GOT_SIZE (output_bfd));
+ MIPS_ELF_PUT_WORD (output_bfd, MIPS_ELF_GNU_GOT1_MASK (output_bfd),
+ sgot->contents
+ + got_index++ * MIPS_ELF_GOT_SIZE (output_bfd));
+
+ if (! info->shared)
+ continue;
+
+ for (; got_index < g->local_gotno; got_index++)
+ {
+ if (got_index >= g->assigned_low_gotno
+ && got_index <= g->assigned_high_gotno)
+ continue;
+
+ rel[0].r_offset = rel[1].r_offset = rel[2].r_offset
+ = got_index * MIPS_ELF_GOT_SIZE (output_bfd);
+ if (!(mips_elf_create_dynamic_relocation
+ (output_bfd, info, rel, NULL,
+ bfd_abs_section_ptr,
+ 0, &addend, sgot)))
+ return FALSE;
+ BFD_ASSERT (addend == 0);
+ }
+ }
+ }
+
+ /* The generation of dynamic relocations for the non-primary gots
+ adds more dynamic relocations. We cannot count them until
+ here. */
+
+ if (elf_hash_table (info)->dynamic_sections_created)
+ {
+ bfd_byte *b;
+ bfd_boolean swap_out_p;
+
+ BFD_ASSERT (sdyn != NULL);
+
+ for (b = sdyn->contents;
+ b < sdyn->contents + sdyn->size;
+ b += MIPS_ELF_DYN_SIZE (dynobj))
+ {
+ Elf_Internal_Dyn dyn;
+ asection *s;
+
+ /* Read in the current dynamic entry. */
+ (*get_elf_backend_data (dynobj)->s->swap_dyn_in) (dynobj, b, &dyn);
+
+ /* Assume that we're going to modify it and write it out. */
+ swap_out_p = TRUE;
+
+ switch (dyn.d_tag)
+ {
+ case DT_RELSZ:
+ /* Reduce DT_RELSZ to account for any relocations we
+ decided not to make. This is for the n64 irix rld,
+ which doesn't seem to apply any relocations if there
+ are trailing null entries. */
+ s = mips_elf_rel_dyn_section (info, FALSE);
+ dyn.d_un.d_val = (s->reloc_count
+ * (ABI_64_P (output_bfd)
+ ? sizeof (Elf64_Mips_External_Rel)
+ : sizeof (Elf32_External_Rel)));
+ /* Adjust the section size too. Tools like the prelinker
+ can reasonably expect the values to the same. */
+ elf_section_data (s->output_section)->this_hdr.sh_size
+ = dyn.d_un.d_val;
+ break;
+
+ default:
+ swap_out_p = FALSE;
+ break;
+ }
+
+ if (swap_out_p)
+ (*get_elf_backend_data (dynobj)->s->swap_dyn_out)
+ (dynobj, &dyn, b);
+ }
+ }
+
+ {
+ asection *s;
+ Elf32_compact_rel cpt;
+
+ if (SGI_COMPAT (output_bfd))
+ {
+ /* Write .compact_rel section out. */
+ s = bfd_get_linker_section (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. */
+ if (htab->sstubs != NULL)
+ {
+ file_ptr dummy_offset;
+
+ BFD_ASSERT (htab->sstubs->size >= htab->function_stub_size);
+ dummy_offset = htab->sstubs->size - htab->function_stub_size;
+ memset (htab->sstubs->contents + dummy_offset, 0,
+ htab->function_stub_size);
+ }
+ }
+ }
+
+ /* The psABI says that the dynamic relocations must be sorted in
+ increasing order of r_symndx. The VxWorks EABI doesn't require
+ this, and because the code below handles REL rather than RELA
+ relocations, using it for VxWorks would be outright harmful. */
+ if (!htab->is_vxworks)
+ {
+ s = mips_elf_rel_dyn_section (info, FALSE);
+ if (s != NULL
+ && s->size > (bfd_vma)2 * MIPS_ELF_REL_SIZE (output_bfd))
+ {
+ reldyn_sorting_bfd = output_bfd;
+
+ if (ABI_64_P (output_bfd))
+ qsort ((Elf64_External_Rel *) s->contents + 1,
+ s->reloc_count - 1, sizeof (Elf64_Mips_External_Rel),
+ sort_dynamic_relocs_64);
+ else
+ qsort ((Elf32_External_Rel *) s->contents + 1,
+ s->reloc_count - 1, sizeof (Elf32_External_Rel),
+ sort_dynamic_relocs);
+ }
+ }
+ }
+
+ if (htab->splt && htab->splt->size > 0)
+ {
+ if (htab->is_vxworks)
+ {
+ if (info->shared)
+ mips_vxworks_finish_shared_plt (output_bfd, info);
+ else
+ mips_vxworks_finish_exec_plt (output_bfd, info);
+ }
+ else
+ {
+ BFD_ASSERT (!info->shared);
+ if (!mips_finish_exec_plt (output_bfd, info))
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+
+/* Set ABFD's EF_MIPS_ARCH and EF_MIPS_MACH flags. */
+
+static void
+mips_set_isa_flags (bfd *abfd)
+{
+ flagword val;
+
+ 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:
+ case bfd_mach_mips4400:
+ case bfd_mach_mips4600:
+ 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_mips4120:
+ val = E_MIPS_ARCH_3 | E_MIPS_MACH_4120;
+ break;
+
+ case bfd_mach_mips4650:
+ val = E_MIPS_ARCH_3 | E_MIPS_MACH_4650;
+ break;
+
+ case bfd_mach_mips5400:
+ val = E_MIPS_ARCH_4 | E_MIPS_MACH_5400;
+ break;
+
+ case bfd_mach_mips5500:
+ val = E_MIPS_ARCH_4 | E_MIPS_MACH_5500;
+ break;
+
+ case bfd_mach_mips5900:
+ val = E_MIPS_ARCH_3 | E_MIPS_MACH_5900;
+ break;
+
+ case bfd_mach_mips9000:
+ val = E_MIPS_ARCH_4 | E_MIPS_MACH_9000;
+ break;
+
+ case bfd_mach_mips5000:
+ case bfd_mach_mips7000:
+ case bfd_mach_mips8000:
+ case bfd_mach_mips10000:
+ case bfd_mach_mips12000:
+ case bfd_mach_mips14000:
+ case bfd_mach_mips16000:
+ val = E_MIPS_ARCH_4;
+ break;
+
+ case bfd_mach_mips5:
+ val = E_MIPS_ARCH_5;
+ break;
+
+ case bfd_mach_mips_loongson_2e:
+ val = E_MIPS_ARCH_3 | E_MIPS_MACH_LS2E;
+ break;
+
+ case bfd_mach_mips_loongson_2f:
+ val = E_MIPS_ARCH_3 | E_MIPS_MACH_LS2F;
+ break;
+
+ case bfd_mach_mips_sb1:
+ val = E_MIPS_ARCH_64 | E_MIPS_MACH_SB1;
+ break;
+
+ case bfd_mach_mips_loongson_3a:
+ val = E_MIPS_ARCH_64R2 | E_MIPS_MACH_LS3A;
+ break;
+
+ case bfd_mach_mips_octeon:
+ case bfd_mach_mips_octeonp:
+ val = E_MIPS_ARCH_64R2 | E_MIPS_MACH_OCTEON;
+ break;
+
+ case bfd_mach_mips_xlr:
+ val = E_MIPS_ARCH_64 | E_MIPS_MACH_XLR;
+ break;
+
+ case bfd_mach_mips_octeon2:
+ val = E_MIPS_ARCH_64R2 | E_MIPS_MACH_OCTEON2;
+ break;
+
+ case bfd_mach_mipsisa32:
+ val = E_MIPS_ARCH_32;
+ break;
+
+ case bfd_mach_mipsisa64:
+ val = E_MIPS_ARCH_64;
+ break;
+
+ case bfd_mach_mipsisa32r2:
+ case bfd_mach_mipsisa32r3:
+ case bfd_mach_mipsisa32r5:
+ val = E_MIPS_ARCH_32R2;
+ break;
+
+ case bfd_mach_mipsisa64r2:
+ case bfd_mach_mipsisa64r3:
+ case bfd_mach_mipsisa64r5:
+ val = E_MIPS_ARCH_64R2;
+ break;
+
+ case bfd_mach_mipsisa32r6:
+ val = E_MIPS_ARCH_32R6;
+ break;
+
+ case bfd_mach_mipsisa64r6:
+ val = E_MIPS_ARCH_64R6;
+ break;
+ }
+ elf_elfheader (abfd)->e_flags &= ~(EF_MIPS_ARCH | EF_MIPS_MACH);
+ elf_elfheader (abfd)->e_flags |= val;
+
+}
+
+
+/* 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. */
+
+void
+_bfd_mips_elf_final_write_processing (bfd *abfd,
+ bfd_boolean linker ATTRIBUTE_UNUSED)
+{
+ unsigned int i;
+ Elf_Internal_Shdr **hdrpp;
+ const char *name;
+ asection *sec;
+
+ /* Keep the existing EF_MIPS_MACH and EF_MIPS_ARCH flags if the former
+ is nonzero. This is for compatibility with old objects, which used
+ a combination of a 32-bit EF_MIPS_ARCH and a 64-bit EF_MIPS_MACH. */
+ if ((elf_elfheader (abfd)->e_flags & EF_MIPS_MACH) == 0)
+ mips_set_isa_flags (abfd);
+
+ /* 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_numsections (abfd);
+ i++, hdrpp++)
+ {
+ switch ((*hdrpp)->sh_type)
+ {
+ case SHT_MIPS_MSYM:
+ 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
+ && CONST_STRNEQ (name, ".gptab."));
+ 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
+ && CONST_STRNEQ (name, ".MIPS.content"));
+ sec = bfd_get_section_by_name (abfd,
+ name + sizeof ".MIPS.content" - 1);
+ BFD_ASSERT (sec != NULL);
+ (*hdrpp)->sh_link = 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 (CONST_STRNEQ (name, ".MIPS.events"))
+ sec = bfd_get_section_by_name (abfd,
+ name + sizeof ".MIPS.events" - 1);
+ else
+ {
+ BFD_ASSERT (CONST_STRNEQ (name, ".MIPS.post_rel"));
+ 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;
+
+ }
+ }
+}
+
+/* When creating an IRIX5 executable, we need REGINFO and RTPROC
+ segments. */
+
+int
+_bfd_mips_elf_additional_program_headers (bfd *abfd,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED)
+{
+ asection *s;
+ int ret = 0;
+
+ /* See if we need a PT_MIPS_REGINFO segment. */
+ s = bfd_get_section_by_name (abfd, ".reginfo");
+ if (s && (s->flags & SEC_LOAD))
+ ++ret;
+
+ /* See if we need a PT_MIPS_ABIFLAGS segment. */
+ if (bfd_get_section_by_name (abfd, ".MIPS.abiflags"))
+ ++ret;
+
+ /* See if we need a PT_MIPS_OPTIONS segment. */
+ if (IRIX_COMPAT (abfd) == ict_irix6
+ && bfd_get_section_by_name (abfd,
+ MIPS_ELF_OPTIONS_SECTION_NAME (abfd)))
+ ++ret;
+
+ /* See if we need a PT_MIPS_RTPROC segment. */
+ if (IRIX_COMPAT (abfd) == ict_irix5
+ && bfd_get_section_by_name (abfd, ".dynamic")
+ && bfd_get_section_by_name (abfd, ".mdebug"))
+ ++ret;
+
+ /* Allocate a PT_NULL header in dynamic objects. See
+ _bfd_mips_elf_modify_segment_map for details. */
+ if (!SGI_COMPAT (abfd)
+ && bfd_get_section_by_name (abfd, ".dynamic"))
+ ++ret;
+
+ return ret;
+}
+
+/* Modify the segment map for an IRIX5 executable. */
+
+bfd_boolean
+_bfd_mips_elf_modify_segment_map (bfd *abfd,
+ struct bfd_link_info *info)
+{
+ asection *s;
+ struct elf_segment_map *m, **pm;
+ bfd_size_type amt;
+
+ /* 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_seg_map (abfd); m != NULL; m = m->next)
+ if (m->p_type == PT_MIPS_REGINFO)
+ break;
+ if (m == NULL)
+ {
+ amt = sizeof *m;
+ m = bfd_zalloc (abfd, amt);
+ 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_seg_map (abfd);
+ while (*pm != NULL
+ && ((*pm)->p_type == PT_PHDR
+ || (*pm)->p_type == PT_INTERP))
+ pm = &(*pm)->next;
+
+ m->next = *pm;
+ *pm = m;
+ }
+ }
+
+ /* If there is a .MIPS.abiflags section, we need a PT_MIPS_ABIFLAGS
+ segment. */
+ s = bfd_get_section_by_name (abfd, ".MIPS.abiflags");
+ if (s != NULL && (s->flags & SEC_LOAD) != 0)
+ {
+ for (m = elf_seg_map (abfd); m != NULL; m = m->next)
+ if (m->p_type == PT_MIPS_ABIFLAGS)
+ break;
+ if (m == NULL)
+ {
+ amt = sizeof *m;
+ m = bfd_zalloc (abfd, amt);
+ if (m == NULL)
+ return FALSE;
+
+ m->p_type = PT_MIPS_ABIFLAGS;
+ m->count = 1;
+ m->sections[0] = s;
+
+ /* We want to put it after the PHDR and INTERP segments. */
+ pm = &elf_seg_map (abfd);
+ while (*pm != NULL
+ && ((*pm)->p_type == PT_PHDR
+ || (*pm)->p_type == PT_INTERP))
+ pm = &(*pm)->next;
+
+ m->next = *pm;
+ *pm = m;
+ }
+ }
+
+ /* For IRIX 6, we don't have .mdebug sections, nor does anything but
+ .dynamic end up in PT_DYNAMIC. However, we do have to insert a
+ PT_MIPS_OPTIONS segment immediately following the program header
+ table. */
+ if (NEWABI_P (abfd)
+ /* On non-IRIX6 new abi, we'll have already created a segment
+ for this section, so don't create another. I'm not sure this
+ is not also the case for IRIX 6, but I can't test it right
+ now. */
+ && IRIX_COMPAT (abfd) == ict_irix6)
+ {
+ for (s = abfd->sections; s; s = s->next)
+ if (elf_section_data (s)->this_hdr.sh_type == SHT_MIPS_OPTIONS)
+ break;
+
+ if (s)
+ {
+ struct elf_segment_map *options_segment;
+
+ pm = &elf_seg_map (abfd);
+ while (*pm != NULL
+ && ((*pm)->p_type == PT_PHDR
+ || (*pm)->p_type == PT_INTERP))
+ pm = &(*pm)->next;
+
+ if (*pm == NULL || (*pm)->p_type != PT_MIPS_OPTIONS)
+ {
+ amt = sizeof (struct elf_segment_map);
+ options_segment = bfd_zalloc (abfd, amt);
+ options_segment->next = *pm;
+ options_segment->p_type = PT_MIPS_OPTIONS;
+ options_segment->p_flags = PF_R;
+ options_segment->p_flags_valid = TRUE;
+ options_segment->count = 1;
+ options_segment->sections[0] = s;
+ *pm = options_segment;
+ }
+ }
+ }
+ else
+ {
+ if (IRIX_COMPAT (abfd) == ict_irix5)
+ {
+ /* 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_seg_map (abfd); m != NULL; m = m->next)
+ if (m->p_type == PT_MIPS_RTPROC)
+ break;
+ if (m == NULL)
+ {
+ amt = sizeof *m;
+ m = bfd_zalloc (abfd, amt);
+ 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_seg_map (abfd);
+ while (*pm != NULL && (*pm)->p_type != PT_DYNAMIC)
+ pm = &(*pm)->next;
+ if (*pm != NULL)
+ pm = &(*pm)->next;
+
+ m->next = *pm;
+ *pm = m;
+ }
+ }
+ }
+ /* On IRIX5, the PT_DYNAMIC segment includes the .dynamic,
+ .dynstr, .dynsym, and .hash sections, and everything in
+ between. */
+ for (pm = &elf_seg_map (abfd); *pm != NULL;
+ pm = &(*pm)->next)
+ if ((*pm)->p_type == PT_DYNAMIC)
+ break;
+ m = *pm;
+ /* GNU/Linux binaries do not need the extended PT_DYNAMIC section.
+ glibc's dynamic linker has traditionally derived the number of
+ tags from the p_filesz field, and sometimes allocates stack
+ arrays of that size. An overly-big PT_DYNAMIC segment can
+ be actively harmful in such cases. Making PT_DYNAMIC contain
+ other sections can also make life hard for the prelinker,
+ which might move one of the other sections to a different
+ PT_LOAD segment. */
+ if (SGI_COMPAT (abfd)
+ && 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 = ~(bfd_vma) 0;
+ 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->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->size <= high)
+ ++c;
+
+ amt = sizeof *n + (bfd_size_type) (c - 1) * sizeof (asection *);
+ n = bfd_zalloc (abfd, amt);
+ 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->size <= high)
+ {
+ n->sections[i] = s;
+ ++i;
+ }
+ }
+
+ *pm = n;
+ }
+ }
+
+ /* Allocate a spare program header in dynamic objects so that tools
+ like the prelinker can add an extra PT_LOAD entry.
+
+ If the prelinker needs to make room for a new PT_LOAD entry, its
+ standard procedure is to move the first (read-only) sections into
+ the new (writable) segment. However, the MIPS ABI requires
+ .dynamic to be in a read-only segment, and the section will often
+ start within sizeof (ElfNN_Phdr) bytes of the last program header.
+
+ Although the prelinker could in principle move .dynamic to a
+ writable segment, it seems better to allocate a spare program
+ header instead, and avoid the need to move any sections.
+ There is a long tradition of allocating spare dynamic tags,
+ so allocating a spare program header seems like a natural
+ extension.
+
+ If INFO is NULL, we may be copying an already prelinked binary
+ with objcopy or strip, so do not add this header. */
+ if (info != NULL
+ && !SGI_COMPAT (abfd)
+ && bfd_get_section_by_name (abfd, ".dynamic"))
+ {
+ for (pm = &elf_seg_map (abfd); *pm != NULL; pm = &(*pm)->next)
+ if ((*pm)->p_type == PT_NULL)
+ break;
+ if (*pm == NULL)
+ {
+ m = bfd_zalloc (abfd, sizeof (*m));
+ if (m == NULL)
+ return FALSE;
+
+ m->p_type = PT_NULL;
+ *pm = m;
+ }
+ }
+
+ return TRUE;
+}
+
+/* Return the section that should be marked against GC for a given
+ relocation. */
+
+asection *
+_bfd_mips_elf_gc_mark_hook (asection *sec,
+ 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 (ELF_R_TYPE (sec->owner, rel->r_info))
+ {
+ case R_MIPS_GNU_VTINHERIT:
+ case R_MIPS_GNU_VTENTRY:
+ return NULL;
+ }
+
+ return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
+}
+
+/* Update the got entry reference counts for the section being removed. */
+
+bfd_boolean
+_bfd_mips_elf_gc_sweep_hook (bfd *abfd ATTRIBUTE_UNUSED,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ asection *sec ATTRIBUTE_UNUSED,
+ const Elf_Internal_Rela *relocs ATTRIBUTE_UNUSED)
+{
+#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;
+
+ if (info->relocatable)
+ return TRUE;
+
+ 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 (ELF_R_TYPE (abfd, rel->r_info))
+ {
+ case R_MIPS16_GOT16:
+ case R_MIPS16_CALL16:
+ 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:
+ case R_MIPS_GOT_DISP:
+ case R_MIPS_GOT_PAGE:
+ case R_MIPS_GOT_OFST:
+ case R_MICROMIPS_GOT16:
+ case R_MICROMIPS_CALL16:
+ case R_MICROMIPS_CALL_HI16:
+ case R_MICROMIPS_CALL_LO16:
+ case R_MICROMIPS_GOT_HI16:
+ case R_MICROMIPS_GOT_LO16:
+ case R_MICROMIPS_GOT_DISP:
+ case R_MICROMIPS_GOT_PAGE:
+ case R_MICROMIPS_GOT_OFST:
+ /* ??? 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;
+}
+
+/* Prevent .MIPS.abiflags from being discarded with --gc-sections. */
+
+bfd_boolean
+_bfd_mips_elf_gc_mark_extra_sections (struct bfd_link_info *info,
+ elf_gc_mark_hook_fn gc_mark_hook)
+{
+ bfd *sub;
+
+ _bfd_elf_gc_mark_extra_sections (info, gc_mark_hook);
+
+ for (sub = info->input_bfds; sub != NULL; sub = sub->link.next)
+ {
+ asection *o;
+
+ if (! is_mips_elf (sub))
+ continue;
+
+ for (o = sub->sections; o != NULL; o = o->next)
+ if (!o->gc_mark
+ && MIPS_ELF_ABIFLAGS_SECTION_NAME_P
+ (bfd_get_section_name (sub, o)))
+ {
+ if (!_bfd_elf_gc_mark (info, o, gc_mark_hook))
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+/* Copy data from a MIPS ELF indirect symbol to its direct symbol,
+ hiding the old indirect symbol. Process additional relocation
+ information. Also called for weakdefs, in which case we just let
+ _bfd_elf_link_hash_copy_indirect copy the flags for us. */
+
+void
+_bfd_mips_elf_copy_indirect_symbol (struct bfd_link_info *info,
+ struct elf_link_hash_entry *dir,
+ struct elf_link_hash_entry *ind)
+{
+ struct mips_elf_link_hash_entry *dirmips, *indmips;
+
+ _bfd_elf_link_hash_copy_indirect (info, dir, ind);
+
+ dirmips = (struct mips_elf_link_hash_entry *) dir;
+ indmips = (struct mips_elf_link_hash_entry *) ind;
+ /* Any absolute non-dynamic relocations against an indirect or weak
+ definition will be against the target symbol. */
+ if (indmips->has_static_relocs)
+ dirmips->has_static_relocs = TRUE;
+
+ if (ind->root.type != bfd_link_hash_indirect)
+ return;
+
+ dirmips->possibly_dynamic_relocs += indmips->possibly_dynamic_relocs;
+ if (indmips->readonly_reloc)
+ dirmips->readonly_reloc = TRUE;
+ if (indmips->no_fn_stub)
+ dirmips->no_fn_stub = TRUE;
+ if (indmips->fn_stub)
+ {
+ dirmips->fn_stub = indmips->fn_stub;
+ indmips->fn_stub = NULL;
+ }
+ if (indmips->need_fn_stub)
+ {
+ dirmips->need_fn_stub = TRUE;
+ indmips->need_fn_stub = FALSE;
+ }
+ if (indmips->call_stub)
+ {
+ dirmips->call_stub = indmips->call_stub;
+ indmips->call_stub = NULL;
+ }
+ if (indmips->call_fp_stub)
+ {
+ dirmips->call_fp_stub = indmips->call_fp_stub;
+ indmips->call_fp_stub = NULL;
+ }
+ if (indmips->global_got_area < dirmips->global_got_area)
+ dirmips->global_got_area = indmips->global_got_area;
+ if (indmips->global_got_area < GGA_NONE)
+ indmips->global_got_area = GGA_NONE;
+ if (indmips->has_nonpic_branches)
+ dirmips->has_nonpic_branches = TRUE;
+}
+
+#define PDR_SIZE 32
+
+bfd_boolean
+_bfd_mips_elf_discard_info (bfd *abfd, struct elf_reloc_cookie *cookie,
+ struct bfd_link_info *info)
+{
+ asection *o;
+ bfd_boolean ret = FALSE;
+ unsigned char *tdata;
+ size_t i, skip;
+
+ o = bfd_get_section_by_name (abfd, ".pdr");
+ if (! o)
+ return FALSE;
+ if (o->size == 0)
+ return FALSE;
+ if (o->size % PDR_SIZE != 0)
+ return FALSE;
+ if (o->output_section != NULL
+ && bfd_is_abs_section (o->output_section))
+ return FALSE;
+
+ tdata = bfd_zmalloc (o->size / PDR_SIZE);
+ if (! tdata)
+ return FALSE;
+
+ cookie->rels = _bfd_elf_link_read_relocs (abfd, o, NULL, NULL,
+ info->keep_memory);
+ if (!cookie->rels)
+ {
+ free (tdata);
+ return FALSE;
+ }
+
+ cookie->rel = cookie->rels;
+ cookie->relend = cookie->rels + o->reloc_count;
+
+ for (i = 0, skip = 0; i < o->size / PDR_SIZE; i ++)
+ {
+ if (bfd_elf_reloc_symbol_deleted_p (i * PDR_SIZE, cookie))
+ {
+ tdata[i] = 1;
+ skip ++;
+ }
+ }
+
+ if (skip != 0)
+ {
+ mips_elf_section_data (o)->u.tdata = tdata;
+ if (o->rawsize == 0)
+ o->rawsize = o->size;
+ o->size -= skip * PDR_SIZE;
+ ret = TRUE;
+ }
+ else
+ free (tdata);
+
+ if (! info->keep_memory)
+ free (cookie->rels);
+
+ return ret;
+}
+
+bfd_boolean
+_bfd_mips_elf_ignore_discarded_relocs (asection *sec)
+{
+ if (strcmp (sec->name, ".pdr") == 0)
+ return TRUE;
+ return FALSE;
+}
+
+bfd_boolean
+_bfd_mips_elf_write_section (bfd *output_bfd,
+ struct bfd_link_info *link_info ATTRIBUTE_UNUSED,
+ asection *sec, bfd_byte *contents)
+{
+ bfd_byte *to, *from, *end;
+ int i;
+
+ if (strcmp (sec->name, ".pdr") != 0)
+ return FALSE;
+
+ if (mips_elf_section_data (sec)->u.tdata == NULL)
+ return FALSE;
+
+ to = contents;
+ end = contents + sec->size;
+ for (from = contents, i = 0;
+ from < end;
+ from += PDR_SIZE, i++)
+ {
+ if ((mips_elf_section_data (sec)->u.tdata)[i] == 1)
+ continue;
+ if (to != from)
+ memcpy (to, from, PDR_SIZE);
+ to += PDR_SIZE;
+ }
+ bfd_set_section_contents (output_bfd, sec->output_section, contents,
+ sec->output_offset, sec->size);
+ return TRUE;
+}
+
+/* microMIPS code retains local labels for linker relaxation. Omit them
+ from output by default for clarity. */
+
+bfd_boolean
+_bfd_mips_elf_is_target_special_symbol (bfd *abfd, asymbol *sym)
+{
+ return _bfd_elf_is_local_label_name (abfd, sym->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;
+};
+
+bfd_boolean
+_bfd_mips_elf_find_nearest_line (bfd *abfd, asymbol **symbols,
+ asection *section, bfd_vma offset,
+ const char **filename_ptr,
+ const char **functionname_ptr,
+ unsigned int *line_ptr,
+ unsigned int *discriminator_ptr)
+{
+ asection *msec;
+
+ if (_bfd_dwarf2_find_nearest_line (abfd, symbols, NULL, section, offset,
+ filename_ptr, functionname_ptr,
+ line_ptr, discriminator_ptr,
+ dwarf_debug_sections,
+ ABI_64_P (abfd) ? 8 : 0,
+ &elf_tdata (abfd)->dwarf2_find_line_info))
+ return TRUE;
+
+ if (_bfd_dwarf1_find_nearest_line (abfd, symbols, section, 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 = mips_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;
+ bfd_size_type amt = sizeof (struct mips_elf_find_line);
+
+ fi = bfd_zalloc (abfd, amt);
+ 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. */
+ amt = fi->d.symbolic_header.ifdMax * sizeof (struct fdr);
+ fi->d.fdr = bfd_alloc (abfd, amt);
+ 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, fraw_src, fdr_ptr);
+
+ mips_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, symbols, section, offset,
+ filename_ptr, functionname_ptr,
+ line_ptr, discriminator_ptr);
+}
+
+bfd_boolean
+_bfd_mips_elf_find_inliner_info (bfd *abfd,
+ const char **filename_ptr,
+ const char **functionname_ptr,
+ unsigned int *line_ptr)
+{
+ bfd_boolean found;
+ found = _bfd_dwarf2_find_inliner_info (abfd, filename_ptr,
+ functionname_ptr, line_ptr,
+ & elf_tdata (abfd)->dwarf2_find_line_info);
+ return found;
+}
+
+
+/* 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. */
+
+bfd_boolean
+_bfd_mips_elf_set_section_contents (bfd *abfd, sec_ptr section,
+ const void *location,
+ file_ptr offset, bfd_size_type count)
+{
+ if (MIPS_ELF_OPTIONS_SECTION_NAME_P (section->name))
+ {
+ bfd_byte *c;
+
+ if (elf_section_data (section) == NULL)
+ {
+ bfd_size_type amt = sizeof (struct bfd_elf_section_data);
+ section->used_by_bfd = bfd_zalloc (abfd, amt);
+ if (elf_section_data (section) == NULL)
+ return FALSE;
+ }
+ c = mips_elf_section_data (section)->u.tdata;
+ if (c == NULL)
+ {
+ c = bfd_zalloc (abfd, section->size);
+ if (c == NULL)
+ return FALSE;
+ mips_elf_section_data (section)->u.tdata = c;
+ }
+
+ memcpy (c + offset, location, count);
+ }
+
+ return _bfd_elf_set_section_contents (abfd, section, location, offset,
+ count);
+}
+
+/* This is almost identical to bfd_generic_get_... except that some
+ MIPS relocations need to be handled specially. Sigh. */
+
+bfd_byte *
+_bfd_elf_mips_get_relocated_section_contents
+ (bfd *abfd,
+ struct bfd_link_info *link_info,
+ struct bfd_link_order *link_order,
+ bfd_byte *data,
+ bfd_boolean relocatable,
+ 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;
+ bfd_size_type sz;
+
+ 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 = bfd_malloc (reloc_size);
+ if (reloc_vector == NULL && reloc_size != 0)
+ goto error_return;
+
+ /* read in the section */
+ sz = input_section->rawsize ? input_section->rawsize : input_section->size;
+ if (!bfd_get_section_contents (input_bfd, input_section, data, 0, sz))
+ goto error_return;
+
+ 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 != NULL; parent++)
+ {
+ char *error_message = 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 we've managed to find the gp and have a special
+ function for the relocation then go ahead, else default
+ to the generic handling. */
+ if (gp_found
+ && (*parent)->howto->special_function
+ == _bfd_mips_elf32_gprel16_reloc)
+ r = _bfd_mips_elf_gprel16_with_gp (input_bfd, sym, *parent,
+ input_section, relocatable,
+ data, gp);
+ else
+ r = bfd_perform_relocation (input_bfd, *parent, data,
+ input_section,
+ relocatable ? abfd : NULL,
+ &error_message);
+
+ if (relocatable)
+ {
+ 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, TRUE)))
+ goto error_return;
+ break;
+ case bfd_reloc_dangerous:
+ BFD_ASSERT (error_message != 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, NULL,
+ 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;
+}
+
+static bfd_boolean
+mips_elf_relax_delete_bytes (bfd *abfd,
+ asection *sec, bfd_vma addr, int count)
+{
+ Elf_Internal_Shdr *symtab_hdr;
+ unsigned int sec_shndx;
+ bfd_byte *contents;
+ Elf_Internal_Rela *irel, *irelend;
+ Elf_Internal_Sym *isym;
+ Elf_Internal_Sym *isymend;
+ struct elf_link_hash_entry **sym_hashes;
+ struct elf_link_hash_entry **end_hashes;
+ struct elf_link_hash_entry **start_hashes;
+ unsigned int symcount;
+
+ sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
+ contents = elf_section_data (sec)->this_hdr.contents;
+
+ irel = elf_section_data (sec)->relocs;
+ irelend = irel + sec->reloc_count;
+
+ /* Actually delete the bytes. */
+ memmove (contents + addr, contents + addr + count,
+ (size_t) (sec->size - addr - count));
+ sec->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 -= count;
+ }
+
+ BFD_ASSERT (addr % 2 == 0);
+ BFD_ASSERT (count % 2 == 0);
+
+ /* Adjust the local symbols defined in this section. */
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+ isym = (Elf_Internal_Sym *) symtab_hdr->contents;
+ for (isymend = isym + symtab_hdr->sh_info; isym < isymend; isym++)
+ if (isym->st_shndx == sec_shndx && isym->st_value > addr)
+ isym->st_value -= count;
+
+ /* Now adjust the global symbols defined in this section. */
+ symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
+ - symtab_hdr->sh_info);
+ sym_hashes = start_hashes = elf_sym_hashes (abfd);
+ end_hashes = sym_hashes + symcount;
+
+ for (; sym_hashes < end_hashes; sym_hashes++)
+ {
+ struct elf_link_hash_entry *sym_hash = *sym_hashes;
+
+ if ((sym_hash->root.type == bfd_link_hash_defined
+ || sym_hash->root.type == bfd_link_hash_defweak)
+ && sym_hash->root.u.def.section == sec)
+ {
+ bfd_vma value = sym_hash->root.u.def.value;
+
+ if (ELF_ST_IS_MICROMIPS (sym_hash->other))
+ value &= MINUS_TWO;
+ if (value > addr)
+ sym_hash->root.u.def.value -= count;
+ }
+ }
+
+ return TRUE;
+}
+
+
+/* Opcodes needed for microMIPS relaxation as found in
+ opcodes/micromips-opc.c. */
+
+struct opcode_descriptor {
+ unsigned long match;
+ unsigned long mask;
+};
+
+/* The $ra register aka $31. */
+
+#define RA 31
+
+/* 32-bit instruction format register fields. */
+
+#define OP32_SREG(opcode) (((opcode) >> 16) & 0x1f)
+#define OP32_TREG(opcode) (((opcode) >> 21) & 0x1f)
+
+/* Check if a 5-bit register index can be abbreviated to 3 bits. */
+
+#define OP16_VALID_REG(r) \
+ ((2 <= (r) && (r) <= 7) || (16 <= (r) && (r) <= 17))
+
+
+/* 32-bit and 16-bit branches. */
+
+static const struct opcode_descriptor b_insns_32[] = {
+ { /* "b", "p", */ 0x40400000, 0xffff0000 }, /* bgez 0 */
+ { /* "b", "p", */ 0x94000000, 0xffff0000 }, /* beq 0, 0 */
+ { 0, 0 } /* End marker for find_match(). */
+};
+
+static const struct opcode_descriptor bc_insn_32 =
+ { /* "bc(1|2)(ft)", "N,p", */ 0x42800000, 0xfec30000 };
+
+static const struct opcode_descriptor bz_insn_32 =
+ { /* "b(g|l)(e|t)z", "s,p", */ 0x40000000, 0xff200000 };
+
+static const struct opcode_descriptor bzal_insn_32 =
+ { /* "b(ge|lt)zal", "s,p", */ 0x40200000, 0xffa00000 };
+
+static const struct opcode_descriptor beq_insn_32 =
+ { /* "b(eq|ne)", "s,t,p", */ 0x94000000, 0xdc000000 };
+
+static const struct opcode_descriptor b_insn_16 =
+ { /* "b", "mD", */ 0xcc00, 0xfc00 };
+
+static const struct opcode_descriptor bz_insn_16 =
+ { /* "b(eq|ne)z", "md,mE", */ 0x8c00, 0xdc00 };
+
+
+/* 32-bit and 16-bit branch EQ and NE zero. */
+
+/* NOTE: All opcode tables have BEQ/BNE in the same order: first the
+ eq and second the ne. This convention is used when replacing a
+ 32-bit BEQ/BNE with the 16-bit version. */
+
+#define BZC32_REG_FIELD(r) (((r) & 0x1f) << 16)
+
+static const struct opcode_descriptor bz_rs_insns_32[] = {
+ { /* "beqz", "s,p", */ 0x94000000, 0xffe00000 },
+ { /* "bnez", "s,p", */ 0xb4000000, 0xffe00000 },
+ { 0, 0 } /* End marker for find_match(). */
+};
+
+static const struct opcode_descriptor bz_rt_insns_32[] = {
+ { /* "beqz", "t,p", */ 0x94000000, 0xfc01f000 },
+ { /* "bnez", "t,p", */ 0xb4000000, 0xfc01f000 },
+ { 0, 0 } /* End marker for find_match(). */
+};
+
+static const struct opcode_descriptor bzc_insns_32[] = {
+ { /* "beqzc", "s,p", */ 0x40e00000, 0xffe00000 },
+ { /* "bnezc", "s,p", */ 0x40a00000, 0xffe00000 },
+ { 0, 0 } /* End marker for find_match(). */
+};
+
+static const struct opcode_descriptor bz_insns_16[] = {
+ { /* "beqz", "md,mE", */ 0x8c00, 0xfc00 },
+ { /* "bnez", "md,mE", */ 0xac00, 0xfc00 },
+ { 0, 0 } /* End marker for find_match(). */
+};
+
+/* Switch between a 5-bit register index and its 3-bit shorthand. */
+
+#define BZ16_REG(opcode) ((((((opcode) >> 7) & 7) + 0x1e) & 0x17) + 2)
+#define BZ16_REG_FIELD(r) \
+ (((2 <= (r) && (r) <= 7) ? (r) : ((r) - 16)) << 7)
+
+
+/* 32-bit instructions with a delay slot. */
+
+static const struct opcode_descriptor jal_insn_32_bd16 =
+ { /* "jals", "a", */ 0x74000000, 0xfc000000 };
+
+static const struct opcode_descriptor jal_insn_32_bd32 =
+ { /* "jal", "a", */ 0xf4000000, 0xfc000000 };
+
+static const struct opcode_descriptor jal_x_insn_32_bd32 =
+ { /* "jal[x]", "a", */ 0xf0000000, 0xf8000000 };
+
+static const struct opcode_descriptor j_insn_32 =
+ { /* "j", "a", */ 0xd4000000, 0xfc000000 };
+
+static const struct opcode_descriptor jalr_insn_32 =
+ { /* "jalr[.hb]", "t,s", */ 0x00000f3c, 0xfc00efff };
+
+/* This table can be compacted, because no opcode replacement is made. */
+
+static const struct opcode_descriptor ds_insns_32_bd16[] = {
+ { /* "jals", "a", */ 0x74000000, 0xfc000000 },
+
+ { /* "jalrs[.hb]", "t,s", */ 0x00004f3c, 0xfc00efff },
+ { /* "b(ge|lt)zals", "s,p", */ 0x42200000, 0xffa00000 },
+
+ { /* "b(g|l)(e|t)z", "s,p", */ 0x40000000, 0xff200000 },
+ { /* "b(eq|ne)", "s,t,p", */ 0x94000000, 0xdc000000 },
+ { /* "j", "a", */ 0xd4000000, 0xfc000000 },
+ { 0, 0 } /* End marker for find_match(). */
+};
+
+/* This table can be compacted, because no opcode replacement is made. */
+
+static const struct opcode_descriptor ds_insns_32_bd32[] = {
+ { /* "jal[x]", "a", */ 0xf0000000, 0xf8000000 },
+
+ { /* "jalr[.hb]", "t,s", */ 0x00000f3c, 0xfc00efff },
+ { /* "b(ge|lt)zal", "s,p", */ 0x40200000, 0xffa00000 },
+ { 0, 0 } /* End marker for find_match(). */
+};
+
+
+/* 16-bit instructions with a delay slot. */
+
+static const struct opcode_descriptor jalr_insn_16_bd16 =
+ { /* "jalrs", "my,mj", */ 0x45e0, 0xffe0 };
+
+static const struct opcode_descriptor jalr_insn_16_bd32 =
+ { /* "jalr", "my,mj", */ 0x45c0, 0xffe0 };
+
+static const struct opcode_descriptor jr_insn_16 =
+ { /* "jr", "mj", */ 0x4580, 0xffe0 };
+
+#define JR16_REG(opcode) ((opcode) & 0x1f)
+
+/* This table can be compacted, because no opcode replacement is made. */
+
+static const struct opcode_descriptor ds_insns_16_bd16[] = {
+ { /* "jalrs", "my,mj", */ 0x45e0, 0xffe0 },
+
+ { /* "b", "mD", */ 0xcc00, 0xfc00 },
+ { /* "b(eq|ne)z", "md,mE", */ 0x8c00, 0xdc00 },
+ { /* "jr", "mj", */ 0x4580, 0xffe0 },
+ { 0, 0 } /* End marker for find_match(). */
+};
+
+
+/* LUI instruction. */
+
+static const struct opcode_descriptor lui_insn =
+ { /* "lui", "s,u", */ 0x41a00000, 0xffe00000 };
+
+
+/* ADDIU instruction. */
+
+static const struct opcode_descriptor addiu_insn =
+ { /* "addiu", "t,r,j", */ 0x30000000, 0xfc000000 };
+
+static const struct opcode_descriptor addiupc_insn =
+ { /* "addiu", "mb,$pc,mQ", */ 0x78000000, 0xfc000000 };
+
+#define ADDIUPC_REG_FIELD(r) \
+ (((2 <= (r) && (r) <= 7) ? (r) : ((r) - 16)) << 23)
+
+
+/* Relaxable instructions in a JAL delay slot: MOVE. */
+
+/* The 16-bit move has rd in 9:5 and rs in 4:0. The 32-bit moves
+ (ADDU, OR) have rd in 15:11 and rs in 10:16. */
+#define MOVE32_RD(opcode) (((opcode) >> 11) & 0x1f)
+#define MOVE32_RS(opcode) (((opcode) >> 16) & 0x1f)
+
+#define MOVE16_RD_FIELD(r) (((r) & 0x1f) << 5)
+#define MOVE16_RS_FIELD(r) (((r) & 0x1f) )
+
+static const struct opcode_descriptor move_insns_32[] = {
+ { /* "move", "d,s", */ 0x00000150, 0xffe007ff }, /* addu d,s,$0 */
+ { /* "move", "d,s", */ 0x00000290, 0xffe007ff }, /* or d,s,$0 */
+ { 0, 0 } /* End marker for find_match(). */
+};
+
+static const struct opcode_descriptor move_insn_16 =
+ { /* "move", "mp,mj", */ 0x0c00, 0xfc00 };
+
+
+/* NOP instructions. */
+
+static const struct opcode_descriptor nop_insn_32 =
+ { /* "nop", "", */ 0x00000000, 0xffffffff };
+
+static const struct opcode_descriptor nop_insn_16 =
+ { /* "nop", "", */ 0x0c00, 0xffff };
+
+
+/* Instruction match support. */
+
+#define MATCH(opcode, insn) ((opcode & insn.mask) == insn.match)
+
+static int
+find_match (unsigned long opcode, const struct opcode_descriptor insn[])
+{
+ unsigned long indx;
+
+ for (indx = 0; insn[indx].mask != 0; indx++)
+ if (MATCH (opcode, insn[indx]))
+ return indx;
+
+ return -1;
+}
+
+
+/* Branch and delay slot decoding support. */
+
+/* If PTR points to what *might* be a 16-bit branch or jump, then
+ return the minimum length of its delay slot, otherwise return 0.
+ Non-zero results are not definitive as we might be checking against
+ the second half of another instruction. */
+
+static int
+check_br16_dslot (bfd *abfd, bfd_byte *ptr)
+{
+ unsigned long opcode;
+ int bdsize;
+
+ opcode = bfd_get_16 (abfd, ptr);
+ if (MATCH (opcode, jalr_insn_16_bd32) != 0)
+ /* 16-bit branch/jump with a 32-bit delay slot. */
+ bdsize = 4;
+ else if (MATCH (opcode, jalr_insn_16_bd16) != 0
+ || find_match (opcode, ds_insns_16_bd16) >= 0)
+ /* 16-bit branch/jump with a 16-bit delay slot. */
+ bdsize = 2;
+ else
+ /* No delay slot. */
+ bdsize = 0;
+
+ return bdsize;
+}
+
+/* If PTR points to what *might* be a 32-bit branch or jump, then
+ return the minimum length of its delay slot, otherwise return 0.
+ Non-zero results are not definitive as we might be checking against
+ the second half of another instruction. */
+
+static int
+check_br32_dslot (bfd *abfd, bfd_byte *ptr)
+{
+ unsigned long opcode;
+ int bdsize;
+
+ opcode = bfd_get_micromips_32 (abfd, ptr);
+ if (find_match (opcode, ds_insns_32_bd32) >= 0)
+ /* 32-bit branch/jump with a 32-bit delay slot. */
+ bdsize = 4;
+ else if (find_match (opcode, ds_insns_32_bd16) >= 0)
+ /* 32-bit branch/jump with a 16-bit delay slot. */
+ bdsize = 2;
+ else
+ /* No delay slot. */
+ bdsize = 0;
+
+ return bdsize;
+}
+
+/* If PTR points to a 16-bit branch or jump with a 32-bit delay slot
+ that doesn't fiddle with REG, then return TRUE, otherwise FALSE. */
+
+static bfd_boolean
+check_br16 (bfd *abfd, bfd_byte *ptr, unsigned long reg)
+{
+ unsigned long opcode;
+
+ opcode = bfd_get_16 (abfd, ptr);
+ if (MATCH (opcode, b_insn_16)
+ /* B16 */
+ || (MATCH (opcode, jr_insn_16) && reg != JR16_REG (opcode))
+ /* JR16 */
+ || (MATCH (opcode, bz_insn_16) && reg != BZ16_REG (opcode))
+ /* BEQZ16, BNEZ16 */
+ || (MATCH (opcode, jalr_insn_16_bd32)
+ /* JALR16 */
+ && reg != JR16_REG (opcode) && reg != RA))
+ return TRUE;
+
+ return FALSE;
+}
+
+/* If PTR points to a 32-bit branch or jump that doesn't fiddle with REG,
+ then return TRUE, otherwise FALSE. */
+
+static bfd_boolean
+check_br32 (bfd *abfd, bfd_byte *ptr, unsigned long reg)
+{
+ unsigned long opcode;
+
+ opcode = bfd_get_micromips_32 (abfd, ptr);
+ if (MATCH (opcode, j_insn_32)
+ /* J */
+ || MATCH (opcode, bc_insn_32)
+ /* BC1F, BC1T, BC2F, BC2T */
+ || (MATCH (opcode, jal_x_insn_32_bd32) && reg != RA)
+ /* JAL, JALX */
+ || (MATCH (opcode, bz_insn_32) && reg != OP32_SREG (opcode))
+ /* BGEZ, BGTZ, BLEZ, BLTZ */
+ || (MATCH (opcode, bzal_insn_32)
+ /* BGEZAL, BLTZAL */
+ && reg != OP32_SREG (opcode) && reg != RA)
+ || ((MATCH (opcode, jalr_insn_32) || MATCH (opcode, beq_insn_32))
+ /* JALR, JALR.HB, BEQ, BNE */
+ && reg != OP32_SREG (opcode) && reg != OP32_TREG (opcode)))
+ return TRUE;
+
+ return FALSE;
+}
+
+/* If the instruction encoding at PTR and relocations [INTERNAL_RELOCS,
+ IRELEND) at OFFSET indicate that there must be a compact branch there,
+ then return TRUE, otherwise FALSE. */
+
+static bfd_boolean
+check_relocated_bzc (bfd *abfd, const bfd_byte *ptr, bfd_vma offset,
+ const Elf_Internal_Rela *internal_relocs,
+ const Elf_Internal_Rela *irelend)
+{
+ const Elf_Internal_Rela *irel;
+ unsigned long opcode;
+
+ opcode = bfd_get_micromips_32 (abfd, ptr);
+ if (find_match (opcode, bzc_insns_32) < 0)
+ return FALSE;
+
+ for (irel = internal_relocs; irel < irelend; irel++)
+ if (irel->r_offset == offset
+ && ELF32_R_TYPE (irel->r_info) == R_MICROMIPS_PC16_S1)
+ return TRUE;
+
+ return FALSE;
+}
+
+/* Bitsize checking. */
+#define IS_BITSIZE(val, N) \
+ (((((val) & ((1ULL << (N)) - 1)) ^ (1ULL << ((N) - 1))) \
+ - (1ULL << ((N) - 1))) == (val))
+
+
+bfd_boolean
+_bfd_mips_elf_relax_section (bfd *abfd, asection *sec,
+ struct bfd_link_info *link_info,
+ bfd_boolean *again)
+{
+ bfd_boolean insn32 = mips_elf_hash_table (link_info)->insn32;
+ Elf_Internal_Shdr *symtab_hdr;
+ Elf_Internal_Rela *internal_relocs;
+ Elf_Internal_Rela *irel, *irelend;
+ bfd_byte *contents = NULL;
+ Elf_Internal_Sym *isymbuf = NULL;
+
+ /* Assume nothing changes. */
+ *again = FALSE;
+
+ /* We don't have to do anything for a relocatable link, if
+ this section does not have relocs, or if this is not a
+ code section. */
+
+ if (link_info->relocatable
+ || (sec->flags & SEC_RELOC) == 0
+ || sec->reloc_count == 0
+ || (sec->flags & SEC_CODE) == 0)
+ return TRUE;
+
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+
+ /* Get a copy of the native relocations. */
+ internal_relocs = (_bfd_elf_link_read_relocs
+ (abfd, sec, NULL, (Elf_Internal_Rela *) NULL,
+ link_info->keep_memory));
+ if (internal_relocs == NULL)
+ goto error_return;
+
+ /* Walk through them looking for relaxing opportunities. */
+ irelend = internal_relocs + sec->reloc_count;
+ for (irel = internal_relocs; irel < irelend; irel++)
+ {
+ unsigned long r_symndx = ELF32_R_SYM (irel->r_info);
+ unsigned int r_type = ELF32_R_TYPE (irel->r_info);
+ bfd_boolean target_is_micromips_code_p;
+ unsigned long opcode;
+ bfd_vma symval;
+ bfd_vma pcrval;
+ bfd_byte *ptr;
+ int fndopc;
+
+ /* The number of bytes to delete for relaxation and from where
+ to delete these bytes starting at irel->r_offset. */
+ int delcnt = 0;
+ int deloff = 0;
+
+ /* If this isn't something that can be relaxed, then ignore
+ this reloc. */
+ if (r_type != R_MICROMIPS_HI16
+ && r_type != R_MICROMIPS_PC16_S1
+ && r_type != R_MICROMIPS_26_S1)
+ 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;
+ /* Go get them off disk. */
+ else if (!bfd_malloc_and_get_section (abfd, sec, &contents))
+ goto error_return;
+ }
+ ptr = contents + irel->r_offset;
+
+ /* Read this BFD's local symbols if we haven't done so already. */
+ if (isymbuf == NULL && symtab_hdr->sh_info != 0)
+ {
+ isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
+ if (isymbuf == NULL)
+ isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
+ symtab_hdr->sh_info, 0,
+ NULL, NULL, NULL);
+ if (isymbuf == NULL)
+ goto error_return;
+ }
+
+ /* Get the value of the symbol referred to by the reloc. */
+ if (r_symndx < symtab_hdr->sh_info)
+ {
+ /* A local symbol. */
+ Elf_Internal_Sym *isym;
+ asection *sym_sec;
+
+ isym = isymbuf + r_symndx;
+ if (isym->st_shndx == SHN_UNDEF)
+ sym_sec = bfd_und_section_ptr;
+ 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;
+ else
+ sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
+ symval = (isym->st_value
+ + sym_sec->output_section->vma
+ + sym_sec->output_offset);
+ target_is_micromips_code_p = ELF_ST_IS_MICROMIPS (isym->st_other);
+ }
+ else
+ {
+ unsigned long indx;
+ struct elf_link_hash_entry *h;
+
+ /* An external symbol. */
+ indx = r_symndx - 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);
+ target_is_micromips_code_p = (!h->needs_plt
+ && ELF_ST_IS_MICROMIPS (h->other));
+ }
+
+
+ /* 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. */
+
+ /* Only 32-bit instructions relaxed. */
+ if (irel->r_offset + 4 > sec->size)
+ continue;
+
+ opcode = bfd_get_micromips_32 (abfd, ptr);
+
+ /* This is the pc-relative distance from the instruction the
+ relocation is applied to, to the symbol referred. */
+ pcrval = (symval
+ - (sec->output_section->vma + sec->output_offset)
+ - irel->r_offset);
+
+ /* R_MICROMIPS_HI16 / LUI relaxation to nil, performing relaxation
+ of corresponding R_MICROMIPS_LO16 to R_MICROMIPS_HI0_LO16 or
+ R_MICROMIPS_PC23_S2. The R_MICROMIPS_PC23_S2 condition is
+
+ (symval % 4 == 0 && IS_BITSIZE (pcrval, 25))
+
+ where pcrval has first to be adjusted to apply against the LO16
+ location (we make the adjustment later on, when we have figured
+ out the offset). */
+ if (r_type == R_MICROMIPS_HI16 && MATCH (opcode, lui_insn))
+ {
+ bfd_boolean bzc = FALSE;
+ unsigned long nextopc;
+ unsigned long reg;
+ bfd_vma offset;
+
+ /* Give up if the previous reloc was a HI16 against this symbol
+ too. */
+ if (irel > internal_relocs
+ && ELF32_R_TYPE (irel[-1].r_info) == R_MICROMIPS_HI16
+ && ELF32_R_SYM (irel[-1].r_info) == r_symndx)
+ continue;
+
+ /* Or if the next reloc is not a LO16 against this symbol. */
+ if (irel + 1 >= irelend
+ || ELF32_R_TYPE (irel[1].r_info) != R_MICROMIPS_LO16
+ || ELF32_R_SYM (irel[1].r_info) != r_symndx)
+ continue;
+
+ /* Or if the second next reloc is a LO16 against this symbol too. */
+ if (irel + 2 >= irelend
+ && ELF32_R_TYPE (irel[2].r_info) == R_MICROMIPS_LO16
+ && ELF32_R_SYM (irel[2].r_info) == r_symndx)
+ continue;
+
+ /* See if the LUI instruction *might* be in a branch delay slot.
+ We check whether what looks like a 16-bit branch or jump is
+ actually an immediate argument to a compact branch, and let
+ it through if so. */
+ if (irel->r_offset >= 2
+ && check_br16_dslot (abfd, ptr - 2)
+ && !(irel->r_offset >= 4
+ && (bzc = check_relocated_bzc (abfd,
+ ptr - 4, irel->r_offset - 4,
+ internal_relocs, irelend))))
+ continue;
+ if (irel->r_offset >= 4
+ && !bzc
+ && check_br32_dslot (abfd, ptr - 4))
+ continue;
+
+ reg = OP32_SREG (opcode);
+
+ /* We only relax adjacent instructions or ones separated with
+ a branch or jump that has a delay slot. The branch or jump
+ must not fiddle with the register used to hold the address.
+ Subtract 4 for the LUI itself. */
+ offset = irel[1].r_offset - irel[0].r_offset;
+ switch (offset - 4)
+ {
+ case 0:
+ break;
+ case 2:
+ if (check_br16 (abfd, ptr + 4, reg))
+ break;
+ continue;
+ case 4:
+ if (check_br32 (abfd, ptr + 4, reg))
+ break;
+ continue;
+ default:
+ continue;
+ }
+
+ nextopc = bfd_get_micromips_32 (abfd, contents + irel[1].r_offset);
+
+ /* Give up unless the same register is used with both
+ relocations. */
+ if (OP32_SREG (nextopc) != reg)
+ continue;
+
+ /* Now adjust pcrval, subtracting the offset to the LO16 reloc
+ and rounding up to take masking of the two LSBs into account. */
+ pcrval = ((pcrval - offset + 3) | 3) ^ 3;
+
+ /* R_MICROMIPS_LO16 relaxation to R_MICROMIPS_HI0_LO16. */
+ if (IS_BITSIZE (symval, 16))
+ {
+ /* Fix the relocation's type. */
+ irel[1].r_info = ELF32_R_INFO (r_symndx, R_MICROMIPS_HI0_LO16);
+
+ /* Instructions using R_MICROMIPS_LO16 have the base or
+ source register in bits 20:16. This register becomes $0
+ (zero) as the result of the R_MICROMIPS_HI16 being 0. */
+ nextopc &= ~0x001f0000;
+ bfd_put_16 (abfd, (nextopc >> 16) & 0xffff,
+ contents + irel[1].r_offset);
+ }
+
+ /* R_MICROMIPS_LO16 / ADDIU relaxation to R_MICROMIPS_PC23_S2.
+ We add 4 to take LUI deletion into account while checking
+ the PC-relative distance. */
+ else if (symval % 4 == 0
+ && IS_BITSIZE (pcrval + 4, 25)
+ && MATCH (nextopc, addiu_insn)
+ && OP32_TREG (nextopc) == OP32_SREG (nextopc)
+ && OP16_VALID_REG (OP32_TREG (nextopc)))
+ {
+ /* Fix the relocation's type. */
+ irel[1].r_info = ELF32_R_INFO (r_symndx, R_MICROMIPS_PC23_S2);
+
+ /* Replace ADDIU with the ADDIUPC version. */
+ nextopc = (addiupc_insn.match
+ | ADDIUPC_REG_FIELD (OP32_TREG (nextopc)));
+
+ bfd_put_micromips_32 (abfd, nextopc,
+ contents + irel[1].r_offset);
+ }
+
+ /* Can't do anything, give up, sigh... */
+ else
+ continue;
+
+ /* Fix the relocation's type. */
+ irel->r_info = ELF32_R_INFO (r_symndx, R_MIPS_NONE);
+
+ /* Delete the LUI instruction: 4 bytes at irel->r_offset. */
+ delcnt = 4;
+ deloff = 0;
+ }
+
+ /* Compact branch relaxation -- due to the multitude of macros
+ employed by the compiler/assembler, compact branches are not
+ always generated. Obviously, this can/will be fixed elsewhere,
+ but there is no drawback in double checking it here. */
+ else if (r_type == R_MICROMIPS_PC16_S1
+ && irel->r_offset + 5 < sec->size
+ && ((fndopc = find_match (opcode, bz_rs_insns_32)) >= 0
+ || (fndopc = find_match (opcode, bz_rt_insns_32)) >= 0)
+ && ((!insn32
+ && (delcnt = MATCH (bfd_get_16 (abfd, ptr + 4),
+ nop_insn_16) ? 2 : 0))
+ || (irel->r_offset + 7 < sec->size
+ && (delcnt = MATCH (bfd_get_micromips_32 (abfd,
+ ptr + 4),
+ nop_insn_32) ? 4 : 0))))
+ {
+ unsigned long reg;
+
+ reg = OP32_SREG (opcode) ? OP32_SREG (opcode) : OP32_TREG (opcode);
+
+ /* Replace BEQZ/BNEZ with the compact version. */
+ opcode = (bzc_insns_32[fndopc].match
+ | BZC32_REG_FIELD (reg)
+ | (opcode & 0xffff)); /* Addend value. */
+
+ bfd_put_micromips_32 (abfd, opcode, ptr);
+
+ /* Delete the delay slot NOP: two or four bytes from
+ irel->offset + 4; delcnt has already been set above. */
+ deloff = 4;
+ }
+
+ /* R_MICROMIPS_PC16_S1 relaxation to R_MICROMIPS_PC10_S1. We need
+ to check the distance from the next instruction, so subtract 2. */
+ else if (!insn32
+ && r_type == R_MICROMIPS_PC16_S1
+ && IS_BITSIZE (pcrval - 2, 11)
+ && find_match (opcode, b_insns_32) >= 0)
+ {
+ /* Fix the relocation's type. */
+ irel->r_info = ELF32_R_INFO (r_symndx, R_MICROMIPS_PC10_S1);
+
+ /* Replace the 32-bit opcode with a 16-bit opcode. */
+ bfd_put_16 (abfd,
+ (b_insn_16.match
+ | (opcode & 0x3ff)), /* Addend value. */
+ ptr);
+
+ /* Delete 2 bytes from irel->r_offset + 2. */
+ delcnt = 2;
+ deloff = 2;
+ }
+
+ /* R_MICROMIPS_PC16_S1 relaxation to R_MICROMIPS_PC7_S1. We need
+ to check the distance from the next instruction, so subtract 2. */
+ else if (!insn32
+ && r_type == R_MICROMIPS_PC16_S1
+ && IS_BITSIZE (pcrval - 2, 8)
+ && (((fndopc = find_match (opcode, bz_rs_insns_32)) >= 0
+ && OP16_VALID_REG (OP32_SREG (opcode)))
+ || ((fndopc = find_match (opcode, bz_rt_insns_32)) >= 0
+ && OP16_VALID_REG (OP32_TREG (opcode)))))
+ {
+ unsigned long reg;
+
+ reg = OP32_SREG (opcode) ? OP32_SREG (opcode) : OP32_TREG (opcode);
+
+ /* Fix the relocation's type. */
+ irel->r_info = ELF32_R_INFO (r_symndx, R_MICROMIPS_PC7_S1);
+
+ /* Replace the 32-bit opcode with a 16-bit opcode. */
+ bfd_put_16 (abfd,
+ (bz_insns_16[fndopc].match
+ | BZ16_REG_FIELD (reg)
+ | (opcode & 0x7f)), /* Addend value. */
+ ptr);
+
+ /* Delete 2 bytes from irel->r_offset + 2. */
+ delcnt = 2;
+ deloff = 2;
+ }
+
+ /* R_MICROMIPS_26_S1 -- JAL to JALS relaxation for microMIPS targets. */
+ else if (!insn32
+ && r_type == R_MICROMIPS_26_S1
+ && target_is_micromips_code_p
+ && irel->r_offset + 7 < sec->size
+ && MATCH (opcode, jal_insn_32_bd32))
+ {
+ unsigned long n32opc;
+ bfd_boolean relaxed = FALSE;
+
+ n32opc = bfd_get_micromips_32 (abfd, ptr + 4);
+
+ if (MATCH (n32opc, nop_insn_32))
+ {
+ /* Replace delay slot 32-bit NOP with a 16-bit NOP. */
+ bfd_put_16 (abfd, nop_insn_16.match, ptr + 4);
+
+ relaxed = TRUE;
+ }
+ else if (find_match (n32opc, move_insns_32) >= 0)
+ {
+ /* Replace delay slot 32-bit MOVE with 16-bit MOVE. */
+ bfd_put_16 (abfd,
+ (move_insn_16.match
+ | MOVE16_RD_FIELD (MOVE32_RD (n32opc))
+ | MOVE16_RS_FIELD (MOVE32_RS (n32opc))),
+ ptr + 4);
+
+ relaxed = TRUE;
+ }
+ /* Other 32-bit instructions relaxable to 16-bit
+ instructions will be handled here later. */
+
+ if (relaxed)
+ {
+ /* JAL with 32-bit delay slot that is changed to a JALS
+ with 16-bit delay slot. */
+ bfd_put_micromips_32 (abfd, jal_insn_32_bd16.match, ptr);
+
+ /* Delete 2 bytes from irel->r_offset + 6. */
+ delcnt = 2;
+ deloff = 6;
+ }
+ }
+
+ if (delcnt != 0)
+ {
+ /* Note that we've changed the relocs, section contents, etc. */
+ elf_section_data (sec)->relocs = internal_relocs;
+ elf_section_data (sec)->this_hdr.contents = contents;
+ symtab_hdr->contents = (unsigned char *) isymbuf;
+
+ /* Delete bytes depending on the delcnt and deloff. */
+ if (!mips_elf_relax_delete_bytes (abfd, sec,
+ irel->r_offset + deloff, delcnt))
+ 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;
+ }
+ }
+
+ if (isymbuf != NULL
+ && symtab_hdr->contents != (unsigned char *) isymbuf)
+ {
+ if (! link_info->keep_memory)
+ free (isymbuf);
+ else
+ {
+ /* Cache the symbols for elf_link_input_bfd. */
+ symtab_hdr->contents = (unsigned char *) isymbuf;
+ }
+ }
+
+ if (contents != NULL
+ && elf_section_data (sec)->this_hdr.contents != contents)
+ {
+ if (! link_info->keep_memory)
+ free (contents);
+ else
+ {
+ /* Cache the section contents for elf_link_input_bfd. */
+ elf_section_data (sec)->this_hdr.contents = contents;
+ }
+ }
+
+ if (internal_relocs != NULL
+ && elf_section_data (sec)->relocs != internal_relocs)
+ free (internal_relocs);
+
+ return TRUE;
+
+ error_return:
+ if (isymbuf != NULL
+ && symtab_hdr->contents != (unsigned char *) isymbuf)
+ free (isymbuf);
+ if (contents != NULL
+ && elf_section_data (sec)->this_hdr.contents != contents)
+ free (contents);
+ if (internal_relocs != NULL
+ && elf_section_data (sec)->relocs != internal_relocs)
+ free (internal_relocs);
+
+ return FALSE;
+}
+
+/* Create a MIPS ELF linker hash table. */
+
+struct bfd_link_hash_table *
+_bfd_mips_elf_link_hash_table_create (bfd *abfd)
+{
+ struct mips_elf_link_hash_table *ret;
+ bfd_size_type amt = sizeof (struct mips_elf_link_hash_table);
+
+ ret = bfd_zmalloc (amt);
+ if (ret == NULL)
+ return NULL;
+
+ if (!_bfd_elf_link_hash_table_init (&ret->root, abfd,
+ mips_elf_link_hash_newfunc,
+ sizeof (struct mips_elf_link_hash_entry),
+ MIPS_ELF_DATA))
+ {
+ free (ret);
+ return NULL;
+ }
+ ret->root.init_plt_refcount.plist = NULL;
+ ret->root.init_plt_offset.plist = NULL;
+
+ return &ret->root.root;
+}
+
+/* Likewise, but indicate that the target is VxWorks. */
+
+struct bfd_link_hash_table *
+_bfd_mips_vxworks_link_hash_table_create (bfd *abfd)
+{
+ struct bfd_link_hash_table *ret;
+
+ ret = _bfd_mips_elf_link_hash_table_create (abfd);
+ if (ret)
+ {
+ struct mips_elf_link_hash_table *htab;
+
+ htab = (struct mips_elf_link_hash_table *) ret;
+ htab->use_plts_and_copy_relocs = TRUE;
+ htab->is_vxworks = TRUE;
+ }
+ return ret;
+}
+
+/* A function that the linker calls if we are allowed to use PLTs
+ and copy relocs. */
+
+void
+_bfd_mips_elf_use_plts_and_copy_relocs (struct bfd_link_info *info)
+{
+ mips_elf_hash_table (info)->use_plts_and_copy_relocs = TRUE;
+}
+
+/* A function that the linker calls to select between all or only
+ 32-bit microMIPS instructions. */
+
+void
+_bfd_mips_elf_insn32 (struct bfd_link_info *info, bfd_boolean on)
+{
+ mips_elf_hash_table (info)->insn32 = on;
+}
+
+/* Return the .MIPS.abiflags value representing each ISA Extension. */
+
+unsigned int
+bfd_mips_isa_ext (bfd *abfd)
+{
+ switch (bfd_get_mach (abfd))
+ {
+ case bfd_mach_mips3900:
+ return AFL_EXT_3900;
+ case bfd_mach_mips4010:
+ return AFL_EXT_4010;
+ case bfd_mach_mips4100:
+ return AFL_EXT_4100;
+ case bfd_mach_mips4111:
+ return AFL_EXT_4111;
+ case bfd_mach_mips4120:
+ return AFL_EXT_4120;
+ case bfd_mach_mips4650:
+ return AFL_EXT_4650;
+ case bfd_mach_mips5400:
+ return AFL_EXT_5400;
+ case bfd_mach_mips5500:
+ return AFL_EXT_5500;
+ case bfd_mach_mips5900:
+ return AFL_EXT_5900;
+ case bfd_mach_mips10000:
+ return AFL_EXT_10000;
+ case bfd_mach_mips_loongson_2e:
+ return AFL_EXT_LOONGSON_2E;
+ case bfd_mach_mips_loongson_2f:
+ return AFL_EXT_LOONGSON_2F;
+ case bfd_mach_mips_loongson_3a:
+ return AFL_EXT_LOONGSON_3A;
+ case bfd_mach_mips_sb1:
+ return AFL_EXT_SB1;
+ case bfd_mach_mips_octeon:
+ return AFL_EXT_OCTEON;
+ case bfd_mach_mips_octeonp:
+ return AFL_EXT_OCTEONP;
+ case bfd_mach_mips_octeon2:
+ return AFL_EXT_OCTEON2;
+ case bfd_mach_mips_xlr:
+ return AFL_EXT_XLR;
+ }
+ return 0;
+}
+
+/* Update the isa_level, isa_rev, isa_ext fields of abiflags. */
+
+static void
+update_mips_abiflags_isa (bfd *abfd, Elf_Internal_ABIFlags_v0 *abiflags)
+{
+ switch (elf_elfheader (abfd)->e_flags & EF_MIPS_ARCH)
+ {
+ case E_MIPS_ARCH_1:
+ abiflags->isa_level = 1;
+ abiflags->isa_rev = 0;
+ break;
+ case E_MIPS_ARCH_2:
+ abiflags->isa_level = 2;
+ abiflags->isa_rev = 0;
+ break;
+ case E_MIPS_ARCH_3:
+ abiflags->isa_level = 3;
+ abiflags->isa_rev = 0;
+ break;
+ case E_MIPS_ARCH_4:
+ abiflags->isa_level = 4;
+ abiflags->isa_rev = 0;
+ break;
+ case E_MIPS_ARCH_5:
+ abiflags->isa_level = 5;
+ abiflags->isa_rev = 0;
+ break;
+ case E_MIPS_ARCH_32:
+ abiflags->isa_level = 32;
+ abiflags->isa_rev = 1;
+ break;
+ case E_MIPS_ARCH_32R2:
+ abiflags->isa_level = 32;
+ /* Handle MIPS32r3 and MIPS32r5 which do not have a header flag. */
+ if (abiflags->isa_rev < 2)
+ abiflags->isa_rev = 2;
+ break;
+ case E_MIPS_ARCH_32R6:
+ abiflags->isa_level = 32;
+ abiflags->isa_rev = 6;
+ break;
+ case E_MIPS_ARCH_64:
+ abiflags->isa_level = 64;
+ abiflags->isa_rev = 1;
+ break;
+ case E_MIPS_ARCH_64R2:
+ /* Handle MIPS64r3 and MIPS64r5 which do not have a header flag. */
+ abiflags->isa_level = 64;
+ if (abiflags->isa_rev < 2)
+ abiflags->isa_rev = 2;
+ break;
+ case E_MIPS_ARCH_64R6:
+ abiflags->isa_level = 64;
+ abiflags->isa_rev = 6;
+ break;
+ default:
+ (*_bfd_error_handler)
+ (_("%B: Unknown architecture %s"),
+ abfd, bfd_printable_name (abfd));
+ }
+
+ abiflags->isa_ext = bfd_mips_isa_ext (abfd);
+}
+
+/* Return true if the given ELF header flags describe a 32-bit binary. */
+
+static bfd_boolean
+mips_32bit_flags_p (flagword flags)
+{
+ return ((flags & EF_MIPS_32BITMODE) != 0
+ || (flags & EF_MIPS_ABI) == E_MIPS_ABI_O32
+ || (flags & EF_MIPS_ABI) == E_MIPS_ABI_EABI32
+ || (flags & EF_MIPS_ARCH) == E_MIPS_ARCH_1
+ || (flags & EF_MIPS_ARCH) == E_MIPS_ARCH_2
+ || (flags & EF_MIPS_ARCH) == E_MIPS_ARCH_32
+ || (flags & EF_MIPS_ARCH) == E_MIPS_ARCH_32R2
+ || (flags & EF_MIPS_ARCH) == E_MIPS_ARCH_32R6);
+}
+
+/* Infer the content of the ABI flags based on the elf header. */
+
+static void
+infer_mips_abiflags (bfd *abfd, Elf_Internal_ABIFlags_v0* abiflags)
+{
+ obj_attribute *in_attr;
+
+ memset (abiflags, 0, sizeof (Elf_Internal_ABIFlags_v0));
+ update_mips_abiflags_isa (abfd, abiflags);
+
+ if (mips_32bit_flags_p (elf_elfheader (abfd)->e_flags))
+ abiflags->gpr_size = AFL_REG_32;
+ else
+ abiflags->gpr_size = AFL_REG_64;
+
+ abiflags->cpr1_size = AFL_REG_NONE;
+
+ in_attr = elf_known_obj_attributes (abfd)[OBJ_ATTR_GNU];
+ abiflags->fp_abi = in_attr[Tag_GNU_MIPS_ABI_FP].i;
+
+ if (abiflags->fp_abi == Val_GNU_MIPS_ABI_FP_SINGLE
+ || abiflags->fp_abi == Val_GNU_MIPS_ABI_FP_XX
+ || (abiflags->fp_abi == Val_GNU_MIPS_ABI_FP_DOUBLE
+ && abiflags->gpr_size == AFL_REG_32))
+ abiflags->cpr1_size = AFL_REG_32;
+ else if (abiflags->fp_abi == Val_GNU_MIPS_ABI_FP_DOUBLE
+ || abiflags->fp_abi == Val_GNU_MIPS_ABI_FP_64
+ || abiflags->fp_abi == Val_GNU_MIPS_ABI_FP_64A)
+ abiflags->cpr1_size = AFL_REG_64;
+
+ abiflags->cpr2_size = AFL_REG_NONE;
+
+ if (elf_elfheader (abfd)->e_flags & EF_MIPS_ARCH_ASE_MDMX)
+ abiflags->ases |= AFL_ASE_MDMX;
+ if (elf_elfheader (abfd)->e_flags & EF_MIPS_ARCH_ASE_M16)
+ abiflags->ases |= AFL_ASE_MIPS16;
+ if (elf_elfheader (abfd)->e_flags & EF_MIPS_ARCH_ASE_MICROMIPS)
+ abiflags->ases |= AFL_ASE_MICROMIPS;
+
+ if (abiflags->fp_abi != Val_GNU_MIPS_ABI_FP_ANY
+ && abiflags->fp_abi != Val_GNU_MIPS_ABI_FP_SOFT
+ && abiflags->fp_abi != Val_GNU_MIPS_ABI_FP_64A
+ && abiflags->isa_level >= 32
+ && abiflags->isa_ext != AFL_EXT_LOONGSON_3A)
+ abiflags->flags1 |= AFL_FLAGS1_ODDSPREG;
+}
+
+/* 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. */
+
+bfd_boolean
+_bfd_mips_elf_final_link (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;
+ asection *rtproc_sec, *abiflags_sec;
+ Elf32_RegInfo reginfo;
+ struct ecoff_debug_info debug;
+ struct mips_htab_traverse_info hti;
+ const struct elf_backend_data *bed = get_elf_backend_data (abfd);
+ const struct ecoff_debug_swap *swap = bed->elf_backend_ecoff_debug_swap;
+ HDRR *symhdr = &debug.symbolic_header;
+ void *mdebug_handle = NULL;
+ asection *s;
+ EXTR esym;
+ unsigned int i;
+ bfd_size_type amt;
+ struct mips_elf_link_hash_table *htab;
+
+ static const char * const secname[] =
+ {
+ ".text", ".init", ".fini", ".data",
+ ".rodata", ".sdata", ".sbss", ".bss"
+ };
+ static const int sc[] =
+ {
+ scText, scInit, scFini, scData,
+ scRData, scSData, scSBss, scBss
+ };
+
+ /* Sort the dynamic symbols so that those with GOT entries come after
+ those without. */
+ htab = mips_elf_hash_table (info);
+ BFD_ASSERT (htab != NULL);
+
+ if (!mips_elf_sort_hash_table (abfd, info))
+ return FALSE;
+
+ /* Create any scheduled LA25 stubs. */
+ hti.info = info;
+ hti.output_bfd = abfd;
+ hti.error = FALSE;
+ htab_traverse (htab->la25_stubs, mips_elf_create_la25_stub, &hti);
+ if (hti.error)
+ return FALSE;
+
+ /* 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 != 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 (htab->is_vxworks
+ && (h = bfd_link_hash_lookup (info->hash,
+ "_GLOBAL_OFFSET_TABLE_",
+ FALSE, FALSE, TRUE))
+ && h->type == bfd_link_hash_defined)
+ elf_gp (abfd) = (h->u.def.section->output_section->vma
+ + h->u.def.section->output_offset
+ + h->u.def.value);
+ else if (info->relocatable)
+ {
+ bfd_vma lo = MINUS_ONE;
+
+ /* Find the GP-relative section with the lowest offset. */
+ for (o = abfd->sections; o != NULL; o = o->next)
+ if (o->vma < lo
+ && (elf_section_data (o)->this_hdr.sh_flags & SHF_MIPS_GPREL))
+ lo = o->vma;
+
+ /* And calculate GP relative to that. */
+ elf_gp (abfd) = lo + ELF_MIPS_GP_OFFSET (info);
+ }
+ 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. */
+ abiflags_sec = NULL;
+ reginfo_sec = NULL;
+ mdebug_sec = NULL;
+ gptab_data_sec = NULL;
+ gptab_bss_sec = NULL;
+ for (o = abfd->sections; o != NULL; o = o->next)
+ {
+ if (strcmp (o->name, ".MIPS.abiflags") == 0)
+ {
+ /* We have found the .MIPS.abiflags section in the output file.
+ Look through all the link_orders comprising it and remove them.
+ The data is merged in _bfd_mips_elf_merge_private_bfd_data. */
+ for (p = o->map_head.link_order; p != NULL; p = p->next)
+ {
+ asection *input_section;
+
+ if (p->type != bfd_indirect_link_order)
+ {
+ if (p->type == bfd_data_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;
+ }
+
+ /* Size has been set in _bfd_mips_elf_always_size_sections. */
+ BFD_ASSERT(o->size == sizeof (Elf_External_ABIFlags_v0));
+
+ /* Skip this section later on (I don't think this currently
+ matters, but someday it might). */
+ o->map_head.link_order = NULL;
+
+ abiflags_sec = o;
+ }
+
+ 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->map_head.link_order; p != 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_data_link_order)
+ continue;
+ abort ();
+ }
+
+ input_section = p->u.indirect.section;
+ input_bfd = input_section->owner;
+
+ if (! bfd_get_section_contents (input_bfd, input_section,
+ &ext, 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 _bfd_mips_elf_always_size_sections. */
+ BFD_ASSERT(o->size == sizeof (Elf32_External_RegInfo));
+
+ /* Skip this section later on (I don't think this currently
+ matters, but someday it might). */
+ o->map_head.link_order = NULL;
+
+ reginfo_sec = o;
+ }
+
+ if (strcmp (o->name, ".mdebug") == 0)
+ {
+ struct extsym_info einfo;
+ bfd_vma last;
+
+ /* 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 == NULL)
+ return FALSE;
+
+ 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 < sizeof (secname) / sizeof (secname[0]); i++)
+ {
+ esym.asym.sc = sc[i];
+ s = bfd_get_section_by_name (abfd, secname[i]);
+ if (s != NULL)
+ {
+ esym.asym.value = s->vma;
+ last = s->vma + s->size;
+ }
+ else
+ esym.asym.value = last;
+ if (!bfd_ecoff_debug_one_external (abfd, &debug, swap,
+ secname[i], &esym))
+ return FALSE;
+ }
+
+ for (p = o->map_head.link_order; p != 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_data_link_order)
+ continue;
+ abort ();
+ }
+
+ input_section = p->u.indirect.section;
+ input_bfd = input_section->owner;
+
+ if (!is_mips_elf (input_bfd))
+ {
+ /* 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->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, 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_linker_section (abfd, ".rtproc");
+ if (rtproc_sec == NULL)
+ {
+ flagword flags = (SEC_HAS_CONTENTS | SEC_IN_MEMORY
+ | SEC_LINKER_CREATED | SEC_READONLY);
+
+ rtproc_sec = bfd_make_section_anyway_with_flags (abfd,
+ ".rtproc",
+ flags);
+ if (rtproc_sec == NULL
+ || ! 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, &einfo);
+ if (einfo.failed)
+ return FALSE;
+
+ /* Set the size of the .mdebug section. */
+ o->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->map_head.link_order = NULL;
+
+ mdebug_sec = o;
+ }
+
+ if (CONST_STRNEQ (o->name, ".gptab."))
+ {
+ const char *subname;
+ unsigned int c;
+ Elf32_gptab *tab;
+ Elf32_External_gptab *ext_tab;
+ unsigned int j;
+
+ /* 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->relocatable)
+ {
+ for (p = o->map_head.link_order; p != NULL; p = p->next)
+ {
+ asection *input_section;
+
+ if (p->type != bfd_indirect_link_order)
+ {
+ if (p->type == bfd_data_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->map_head.link_order = NULL;
+
+ /* Really remove the section. */
+ bfd_section_list_remove (abfd, o);
+ --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;
+ amt = c * sizeof (Elf32_gptab);
+ tab = bfd_malloc (amt);
+ 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->map_head.link_order; p != 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_data_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 = input_section->size;
+ 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;
+ bfd_boolean exact;
+ unsigned int look;
+
+ if (! (bfd_get_section_contents
+ (input_bfd, input_section, &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. */
+ amt = (bfd_size_type) (c + 1) * sizeof (Elf32_gptab);
+ new_tab = bfd_realloc (tab, amt);
+ 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. */
+ amt = (bfd_size_type) c * sizeof (Elf32_External_gptab);
+ ext_tab = bfd_alloc (abfd, amt);
+ if (ext_tab == NULL)
+ {
+ free (tab);
+ return FALSE;
+ }
+
+ for (j = 0; j < c; j++)
+ bfd_mips_elf32_swap_gptab_out (abfd, tab + j, ext_tab + j);
+ free (tab);
+
+ o->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->map_head.link_order = NULL;
+ }
+ }
+
+ /* Invoke the regular ELF backend linker to do all the work. */
+ if (!bfd_elf_final_link (abfd, info))
+ return FALSE;
+
+ /* Now write out the computed sections. */
+
+ if (abiflags_sec != NULL)
+ {
+ Elf_External_ABIFlags_v0 ext;
+ Elf_Internal_ABIFlags_v0 *abiflags;
+
+ abiflags = &mips_elf_tdata (abfd)->abiflags;
+
+ /* Set up the abiflags if no valid input sections were found. */
+ if (!mips_elf_tdata (abfd)->abiflags_valid)
+ {
+ infer_mips_abiflags (abfd, abiflags);
+ mips_elf_tdata (abfd)->abiflags_valid = TRUE;
+ }
+ bfd_mips_elf_swap_abiflags_v0_out (abfd, abiflags, &ext);
+ if (! bfd_set_section_contents (abfd, abiflags_sec, &ext, 0, sizeof ext))
+ return FALSE;
+ }
+
+ if (reginfo_sec != NULL)
+ {
+ Elf32_External_RegInfo ext;
+
+ bfd_mips_elf32_swap_reginfo_out (abfd, &reginfo, &ext);
+ if (! bfd_set_section_contents (abfd, reginfo_sec, &ext, 0, sizeof ext))
+ return FALSE;
+ }
+
+ if (mdebug_sec != 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 != NULL)
+ {
+ if (! bfd_set_section_contents (abfd, gptab_data_sec,
+ gptab_data_sec->contents,
+ 0, gptab_data_sec->size))
+ return FALSE;
+ }
+
+ if (gptab_bss_sec != NULL)
+ {
+ if (! bfd_set_section_contents (abfd, gptab_bss_sec,
+ gptab_bss_sec->contents,
+ 0, gptab_bss_sec->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,
+ 0, rtproc_sec->size))
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+/* Structure for saying that BFD machine EXTENSION extends BASE. */
+
+struct mips_mach_extension
+{
+ unsigned long extension, base;
+};
+
+
+/* An array describing how BFD machines relate to one another. The entries
+ are ordered topologically with MIPS I extensions listed last. */
+
+static const struct mips_mach_extension mips_mach_extensions[] =
+{
+ /* MIPS64r2 extensions. */
+ { bfd_mach_mips_octeon2, bfd_mach_mips_octeonp },
+ { bfd_mach_mips_octeonp, bfd_mach_mips_octeon },
+ { bfd_mach_mips_octeon, bfd_mach_mipsisa64r2 },
+ { bfd_mach_mips_loongson_3a, bfd_mach_mipsisa64r2 },
+
+ /* MIPS64 extensions. */
+ { bfd_mach_mipsisa64r2, bfd_mach_mipsisa64 },
+ { bfd_mach_mips_sb1, bfd_mach_mipsisa64 },
+ { bfd_mach_mips_xlr, bfd_mach_mipsisa64 },
+
+ /* MIPS V extensions. */
+ { bfd_mach_mipsisa64, bfd_mach_mips5 },
+
+ /* R10000 extensions. */
+ { bfd_mach_mips12000, bfd_mach_mips10000 },
+ { bfd_mach_mips14000, bfd_mach_mips10000 },
+ { bfd_mach_mips16000, bfd_mach_mips10000 },
+
+ /* R5000 extensions. Note: the vr5500 ISA is an extension of the core
+ vr5400 ISA, but doesn't include the multimedia stuff. It seems
+ better to allow vr5400 and vr5500 code to be merged anyway, since
+ many libraries will just use the core ISA. Perhaps we could add
+ some sort of ASE flag if this ever proves a problem. */
+ { bfd_mach_mips5500, bfd_mach_mips5400 },
+ { bfd_mach_mips5400, bfd_mach_mips5000 },
+
+ /* MIPS IV extensions. */
+ { bfd_mach_mips5, bfd_mach_mips8000 },
+ { bfd_mach_mips10000, bfd_mach_mips8000 },
+ { bfd_mach_mips5000, bfd_mach_mips8000 },
+ { bfd_mach_mips7000, bfd_mach_mips8000 },
+ { bfd_mach_mips9000, bfd_mach_mips8000 },
+
+ /* VR4100 extensions. */
+ { bfd_mach_mips4120, bfd_mach_mips4100 },
+ { bfd_mach_mips4111, bfd_mach_mips4100 },
+
+ /* MIPS III extensions. */
+ { bfd_mach_mips_loongson_2e, bfd_mach_mips4000 },
+ { bfd_mach_mips_loongson_2f, bfd_mach_mips4000 },
+ { bfd_mach_mips8000, bfd_mach_mips4000 },
+ { bfd_mach_mips4650, bfd_mach_mips4000 },
+ { bfd_mach_mips4600, bfd_mach_mips4000 },
+ { bfd_mach_mips4400, bfd_mach_mips4000 },
+ { bfd_mach_mips4300, bfd_mach_mips4000 },
+ { bfd_mach_mips4100, bfd_mach_mips4000 },
+ { bfd_mach_mips4010, bfd_mach_mips4000 },
+ { bfd_mach_mips5900, bfd_mach_mips4000 },
+
+ /* MIPS32 extensions. */
+ { bfd_mach_mipsisa32r2, bfd_mach_mipsisa32 },
+
+ /* MIPS II extensions. */
+ { bfd_mach_mips4000, bfd_mach_mips6000 },
+ { bfd_mach_mipsisa32, bfd_mach_mips6000 },
+
+ /* MIPS I extensions. */
+ { bfd_mach_mips6000, bfd_mach_mips3000 },
+ { bfd_mach_mips3900, bfd_mach_mips3000 }
+};
+
+
+/* Return true if bfd machine EXTENSION is an extension of machine BASE. */
+
+static bfd_boolean
+mips_mach_extends_p (unsigned long base, unsigned long extension)
+{
+ size_t i;
+
+ if (extension == base)
+ return TRUE;
+
+ if (base == bfd_mach_mipsisa32
+ && mips_mach_extends_p (bfd_mach_mipsisa64, extension))
+ return TRUE;
+
+ if (base == bfd_mach_mipsisa32r2
+ && mips_mach_extends_p (bfd_mach_mipsisa64r2, extension))
+ return TRUE;
+
+ for (i = 0; i < ARRAY_SIZE (mips_mach_extensions); i++)
+ if (extension == mips_mach_extensions[i].extension)
+ {
+ extension = mips_mach_extensions[i].base;
+ if (extension == base)
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+
+/* Merge object attributes from IBFD into OBFD. Raise an error if
+ there are conflicting attributes. */
+static bfd_boolean
+mips_elf_merge_obj_attributes (bfd *ibfd, bfd *obfd)
+{
+ obj_attribute *in_attr;
+ obj_attribute *out_attr;
+ bfd *abi_fp_bfd;
+ bfd *abi_msa_bfd;
+
+ abi_fp_bfd = mips_elf_tdata (obfd)->abi_fp_bfd;
+ in_attr = elf_known_obj_attributes (ibfd)[OBJ_ATTR_GNU];
+ if (!abi_fp_bfd && in_attr[Tag_GNU_MIPS_ABI_FP].i != Val_GNU_MIPS_ABI_FP_ANY)
+ mips_elf_tdata (obfd)->abi_fp_bfd = ibfd;
+
+ abi_msa_bfd = mips_elf_tdata (obfd)->abi_msa_bfd;
+ if (!abi_msa_bfd
+ && in_attr[Tag_GNU_MIPS_ABI_MSA].i != Val_GNU_MIPS_ABI_MSA_ANY)
+ mips_elf_tdata (obfd)->abi_msa_bfd = ibfd;
+
+ if (!elf_known_obj_attributes_proc (obfd)[0].i)
+ {
+ /* This is the first object. Copy the attributes. */
+ _bfd_elf_copy_obj_attributes (ibfd, obfd);
+
+ /* Use the Tag_null value to indicate the attributes have been
+ initialized. */
+ elf_known_obj_attributes_proc (obfd)[0].i = 1;
+
+ return TRUE;
+ }
+
+ /* Check for conflicting Tag_GNU_MIPS_ABI_FP attributes and merge
+ non-conflicting ones. */
+ out_attr = elf_known_obj_attributes (obfd)[OBJ_ATTR_GNU];
+ if (in_attr[Tag_GNU_MIPS_ABI_FP].i != out_attr[Tag_GNU_MIPS_ABI_FP].i)
+ {
+ int out_fp, in_fp;
+
+ out_fp = out_attr[Tag_GNU_MIPS_ABI_FP].i;
+ in_fp = in_attr[Tag_GNU_MIPS_ABI_FP].i;
+ out_attr[Tag_GNU_MIPS_ABI_FP].type = 1;
+ if (out_fp == Val_GNU_MIPS_ABI_FP_ANY)
+ out_attr[Tag_GNU_MIPS_ABI_FP].i = in_fp;
+ else if (out_fp == Val_GNU_MIPS_ABI_FP_XX
+ && (in_fp == Val_GNU_MIPS_ABI_FP_DOUBLE
+ || in_fp == Val_GNU_MIPS_ABI_FP_64
+ || in_fp == Val_GNU_MIPS_ABI_FP_64A))
+ {
+ mips_elf_tdata (obfd)->abi_fp_bfd = ibfd;
+ out_attr[Tag_GNU_MIPS_ABI_FP].i = in_attr[Tag_GNU_MIPS_ABI_FP].i;
+ }
+ else if (in_fp == Val_GNU_MIPS_ABI_FP_XX
+ && (out_fp == Val_GNU_MIPS_ABI_FP_DOUBLE
+ || out_fp == Val_GNU_MIPS_ABI_FP_64
+ || out_fp == Val_GNU_MIPS_ABI_FP_64A))
+ /* Keep the current setting. */;
+ else if (out_fp == Val_GNU_MIPS_ABI_FP_64A
+ && in_fp == Val_GNU_MIPS_ABI_FP_64)
+ {
+ mips_elf_tdata (obfd)->abi_fp_bfd = ibfd;
+ out_attr[Tag_GNU_MIPS_ABI_FP].i = in_attr[Tag_GNU_MIPS_ABI_FP].i;
+ }
+ else if (in_fp == Val_GNU_MIPS_ABI_FP_64A
+ && out_fp == Val_GNU_MIPS_ABI_FP_64)
+ /* Keep the current setting. */;
+ else if (in_fp != Val_GNU_MIPS_ABI_FP_ANY)
+ {
+ const char *out_string, *in_string;
+
+ out_string = _bfd_mips_fp_abi_string (out_fp);
+ in_string = _bfd_mips_fp_abi_string (in_fp);
+ /* First warn about cases involving unrecognised ABIs. */
+ if (!out_string && !in_string)
+ _bfd_error_handler
+ (_("Warning: %B uses unknown floating point ABI %d "
+ "(set by %B), %B uses unknown floating point ABI %d"),
+ obfd, abi_fp_bfd, ibfd, out_fp, in_fp);
+ else if (!out_string)
+ _bfd_error_handler
+ (_("Warning: %B uses unknown floating point ABI %d "
+ "(set by %B), %B uses %s"),
+ obfd, abi_fp_bfd, ibfd, out_fp, in_string);
+ else if (!in_string)
+ _bfd_error_handler
+ (_("Warning: %B uses %s (set by %B), "
+ "%B uses unknown floating point ABI %d"),
+ obfd, abi_fp_bfd, ibfd, out_string, in_fp);
+ else
+ {
+ /* If one of the bfds is soft-float, the other must be
+ hard-float. The exact choice of hard-float ABI isn't
+ really relevant to the error message. */
+ if (in_fp == Val_GNU_MIPS_ABI_FP_SOFT)
+ out_string = "-mhard-float";
+ else if (out_fp == Val_GNU_MIPS_ABI_FP_SOFT)
+ in_string = "-mhard-float";
+ _bfd_error_handler
+ (_("Warning: %B uses %s (set by %B), %B uses %s"),
+ obfd, abi_fp_bfd, ibfd, out_string, in_string);
+ }
+ }
+ }
+
+ /* Check for conflicting Tag_GNU_MIPS_ABI_MSA attributes and merge
+ non-conflicting ones. */
+ if (in_attr[Tag_GNU_MIPS_ABI_MSA].i != out_attr[Tag_GNU_MIPS_ABI_MSA].i)
+ {
+ out_attr[Tag_GNU_MIPS_ABI_MSA].type = 1;
+ if (out_attr[Tag_GNU_MIPS_ABI_MSA].i == Val_GNU_MIPS_ABI_MSA_ANY)
+ out_attr[Tag_GNU_MIPS_ABI_MSA].i = in_attr[Tag_GNU_MIPS_ABI_MSA].i;
+ else if (in_attr[Tag_GNU_MIPS_ABI_MSA].i != Val_GNU_MIPS_ABI_MSA_ANY)
+ switch (out_attr[Tag_GNU_MIPS_ABI_MSA].i)
+ {
+ case Val_GNU_MIPS_ABI_MSA_128:
+ _bfd_error_handler
+ (_("Warning: %B uses %s (set by %B), "
+ "%B uses unknown MSA ABI %d"),
+ obfd, abi_msa_bfd, ibfd,
+ "-mmsa", in_attr[Tag_GNU_MIPS_ABI_MSA].i);
+ break;
+
+ default:
+ switch (in_attr[Tag_GNU_MIPS_ABI_MSA].i)
+ {
+ case Val_GNU_MIPS_ABI_MSA_128:
+ _bfd_error_handler
+ (_("Warning: %B uses unknown MSA ABI %d "
+ "(set by %B), %B uses %s"),
+ obfd, abi_msa_bfd, ibfd,
+ out_attr[Tag_GNU_MIPS_ABI_MSA].i, "-mmsa");
+ break;
+
+ default:
+ _bfd_error_handler
+ (_("Warning: %B uses unknown MSA ABI %d "
+ "(set by %B), %B uses unknown MSA ABI %d"),
+ obfd, abi_msa_bfd, ibfd,
+ out_attr[Tag_GNU_MIPS_ABI_MSA].i,
+ in_attr[Tag_GNU_MIPS_ABI_MSA].i);
+ break;
+ }
+ }
+ }
+
+ /* Merge Tag_compatibility attributes and any common GNU ones. */
+ _bfd_elf_merge_object_attributes (ibfd, obfd);
+
+ return TRUE;
+}
+
+/* Merge backend specific data from an object file to the output
+ object file when linking. */
+
+bfd_boolean
+_bfd_mips_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
+{
+ flagword old_flags;
+ flagword new_flags;
+ bfd_boolean ok;
+ bfd_boolean null_input_bfd = TRUE;
+ asection *sec;
+ obj_attribute *out_attr;
+
+ /* Check if we have the same endianness. */
+ if (! _bfd_generic_verify_endian_match (ibfd, obfd))
+ {
+ (*_bfd_error_handler)
+ (_("%B: endianness incompatible with that of the selected emulation"),
+ ibfd);
+ return FALSE;
+ }
+
+ if (!is_mips_elf (ibfd) || !is_mips_elf (obfd))
+ return TRUE;
+
+ if (strcmp (bfd_get_target (ibfd), bfd_get_target (obfd)) != 0)
+ {
+ (*_bfd_error_handler)
+ (_("%B: ABI is incompatible with that of the selected emulation"),
+ ibfd);
+ return FALSE;
+ }
+
+ /* Set up the FP ABI attribute from the abiflags if it is not already
+ set. */
+ if (mips_elf_tdata (ibfd)->abiflags_valid)
+ {
+ obj_attribute *in_attr = elf_known_obj_attributes (ibfd)[OBJ_ATTR_GNU];
+ if (in_attr[Tag_GNU_MIPS_ABI_FP].i == Val_GNU_MIPS_ABI_FP_ANY)
+ in_attr[Tag_GNU_MIPS_ABI_FP].i =
+ mips_elf_tdata (ibfd)->abiflags.fp_abi;
+ }
+
+ if (!mips_elf_merge_obj_attributes (ibfd, obfd))
+ return FALSE;
+
+ /* Check to see if the input BFD actually contains any sections.
+ If not, its flags may not have been initialised either, but it cannot
+ actually cause any incompatibility. */
+ for (sec = ibfd->sections; sec != NULL; sec = sec->next)
+ {
+ /* Ignore synthetic sections and empty .text, .data and .bss sections
+ which are automatically generated by gas. Also ignore fake
+ (s)common sections, since merely defining a common symbol does
+ not affect compatibility. */
+ if ((sec->flags & SEC_IS_COMMON) == 0
+ && strcmp (sec->name, ".reginfo")
+ && strcmp (sec->name, ".mdebug")
+ && (sec->size != 0
+ || (strcmp (sec->name, ".text")
+ && strcmp (sec->name, ".data")
+ && strcmp (sec->name, ".bss"))))
+ {
+ null_input_bfd = FALSE;
+ break;
+ }
+ }
+ if (null_input_bfd)
+ return TRUE;
+
+ /* Populate abiflags using existing information. */
+ if (!mips_elf_tdata (ibfd)->abiflags_valid)
+ {
+ infer_mips_abiflags (ibfd, &mips_elf_tdata (ibfd)->abiflags);
+ mips_elf_tdata (ibfd)->abiflags_valid = TRUE;
+ }
+ else
+ {
+ Elf_Internal_ABIFlags_v0 abiflags;
+ Elf_Internal_ABIFlags_v0 in_abiflags;
+ infer_mips_abiflags (ibfd, &abiflags);
+ in_abiflags = mips_elf_tdata (ibfd)->abiflags;
+
+ /* It is not possible to infer the correct ISA revision
+ for R3 or R5 so drop down to R2 for the checks. */
+ if (in_abiflags.isa_rev == 3 || in_abiflags.isa_rev == 5)
+ in_abiflags.isa_rev = 2;
+
+ if (in_abiflags.isa_level != abiflags.isa_level
+ || in_abiflags.isa_rev != abiflags.isa_rev
+ || in_abiflags.isa_ext != abiflags.isa_ext)
+ (*_bfd_error_handler)
+ (_("%B: warning: Inconsistent ISA between e_flags and "
+ ".MIPS.abiflags"), ibfd);
+ if (abiflags.fp_abi != Val_GNU_MIPS_ABI_FP_ANY
+ && in_abiflags.fp_abi != abiflags.fp_abi)
+ (*_bfd_error_handler)
+ (_("%B: warning: Inconsistent FP ABI between e_flags and "
+ ".MIPS.abiflags"), ibfd);
+ if ((in_abiflags.ases & abiflags.ases) != abiflags.ases)
+ (*_bfd_error_handler)
+ (_("%B: warning: Inconsistent ASEs between e_flags and "
+ ".MIPS.abiflags"), ibfd);
+ if (in_abiflags.isa_ext != abiflags.isa_ext)
+ (*_bfd_error_handler)
+ (_("%B: warning: Inconsistent ISA extensions between e_flags and "
+ ".MIPS.abiflags"), ibfd);
+ if (in_abiflags.flags2 != 0)
+ (*_bfd_error_handler)
+ (_("%B: warning: Unexpected flag in the flags2 field of "
+ ".MIPS.abiflags (0x%lx)"), ibfd,
+ (unsigned long) in_abiflags.flags2);
+ }
+
+ if (!mips_elf_tdata (obfd)->abiflags_valid)
+ {
+ /* Copy input abiflags if output abiflags are not already valid. */
+ mips_elf_tdata (obfd)->abiflags = mips_elf_tdata (ibfd)->abiflags;
+ mips_elf_tdata (obfd)->abiflags_valid = TRUE;
+ }
+
+ if (! elf_flags_init (obfd))
+ {
+ elf_flags_init (obfd) = TRUE;
+ elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags;
+ elf_elfheader (obfd)->e_ident[EI_CLASS]
+ = elf_elfheader (ibfd)->e_ident[EI_CLASS];
+
+ if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
+ && (bfd_get_arch_info (obfd)->the_default
+ || mips_mach_extends_p (bfd_get_mach (obfd),
+ bfd_get_mach (ibfd))))
+ {
+ if (! bfd_set_arch_mach (obfd, bfd_get_arch (ibfd),
+ bfd_get_mach (ibfd)))
+ return FALSE;
+
+ /* Update the ABI flags isa_level, isa_rev and isa_ext fields. */
+ update_mips_abiflags_isa (obfd, &mips_elf_tdata (obfd)->abiflags);
+ }
+
+ return TRUE;
+ }
+
+ /* Update the output abiflags fp_abi using the computed fp_abi. */
+ out_attr = elf_known_obj_attributes (obfd)[OBJ_ATTR_GNU];
+ mips_elf_tdata (obfd)->abiflags.fp_abi = out_attr[Tag_GNU_MIPS_ABI_FP].i;
+
+#define max(a,b) ((a) > (b) ? (a) : (b))
+ /* Merge abiflags. */
+ mips_elf_tdata (obfd)->abiflags.isa_rev
+ = max (mips_elf_tdata (obfd)->abiflags.isa_rev,
+ mips_elf_tdata (ibfd)->abiflags.isa_rev);
+ mips_elf_tdata (obfd)->abiflags.gpr_size
+ = max (mips_elf_tdata (obfd)->abiflags.gpr_size,
+ mips_elf_tdata (ibfd)->abiflags.gpr_size);
+ mips_elf_tdata (obfd)->abiflags.cpr1_size
+ = max (mips_elf_tdata (obfd)->abiflags.cpr1_size,
+ mips_elf_tdata (ibfd)->abiflags.cpr1_size);
+ mips_elf_tdata (obfd)->abiflags.cpr2_size
+ = max (mips_elf_tdata (obfd)->abiflags.cpr2_size,
+ mips_elf_tdata (ibfd)->abiflags.cpr2_size);
+#undef max
+ mips_elf_tdata (obfd)->abiflags.ases
+ |= mips_elf_tdata (ibfd)->abiflags.ases;
+ mips_elf_tdata (obfd)->abiflags.flags1
+ |= mips_elf_tdata (ibfd)->abiflags.flags1;
+
+ new_flags = elf_elfheader (ibfd)->e_flags;
+ elf_elfheader (obfd)->e_flags |= new_flags & EF_MIPS_NOREORDER;
+ old_flags = elf_elfheader (obfd)->e_flags;
+
+ /* Check flag compatibility. */
+
+ new_flags &= ~EF_MIPS_NOREORDER;
+ old_flags &= ~EF_MIPS_NOREORDER;
+
+ /* Some IRIX 6 BSD-compatibility objects have this bit set. It
+ doesn't seem to matter. */
+ new_flags &= ~EF_MIPS_XGOT;
+ old_flags &= ~EF_MIPS_XGOT;
+
+ /* MIPSpro generates ucode info in n64 objects. Again, we should
+ just be able to ignore this. */
+ new_flags &= ~EF_MIPS_UCODE;
+ old_flags &= ~EF_MIPS_UCODE;
+
+ /* DSOs should only be linked with CPIC code. */
+ if ((ibfd->flags & DYNAMIC) != 0)
+ new_flags |= EF_MIPS_PIC | EF_MIPS_CPIC;
+
+ if (new_flags == old_flags)
+ return TRUE;
+
+ ok = TRUE;
+
+ if (((new_flags & (EF_MIPS_PIC | EF_MIPS_CPIC)) != 0)
+ != ((old_flags & (EF_MIPS_PIC | EF_MIPS_CPIC)) != 0))
+ {
+ (*_bfd_error_handler)
+ (_("%B: warning: linking abicalls files with non-abicalls files"),
+ ibfd);
+ ok = TRUE;
+ }
+
+ if (new_flags & (EF_MIPS_PIC | EF_MIPS_CPIC))
+ elf_elfheader (obfd)->e_flags |= EF_MIPS_CPIC;
+ if (! (new_flags & EF_MIPS_PIC))
+ elf_elfheader (obfd)->e_flags &= ~EF_MIPS_PIC;
+
+ new_flags &= ~ (EF_MIPS_PIC | EF_MIPS_CPIC);
+ old_flags &= ~ (EF_MIPS_PIC | EF_MIPS_CPIC);
+
+ /* Compare the ISAs. */
+ if (mips_32bit_flags_p (old_flags) != mips_32bit_flags_p (new_flags))
+ {
+ (*_bfd_error_handler)
+ (_("%B: linking 32-bit code with 64-bit code"),
+ ibfd);
+ ok = FALSE;
+ }
+ else if (!mips_mach_extends_p (bfd_get_mach (ibfd), bfd_get_mach (obfd)))
+ {
+ /* OBFD's ISA isn't the same as, or an extension of, IBFD's. */
+ if (mips_mach_extends_p (bfd_get_mach (obfd), bfd_get_mach (ibfd)))
+ {
+ /* Copy the architecture info from IBFD to OBFD. Also copy
+ the 32-bit flag (if set) so that we continue to recognise
+ OBFD as a 32-bit binary. */
+ bfd_set_arch_info (obfd, bfd_get_arch_info (ibfd));
+ elf_elfheader (obfd)->e_flags &= ~(EF_MIPS_ARCH | EF_MIPS_MACH);
+ elf_elfheader (obfd)->e_flags
+ |= new_flags & (EF_MIPS_ARCH | EF_MIPS_MACH | EF_MIPS_32BITMODE);
+
+ /* Update the ABI flags isa_level, isa_rev, isa_ext fields. */
+ update_mips_abiflags_isa (obfd, &mips_elf_tdata (obfd)->abiflags);
+
+ /* Copy across the ABI flags if OBFD doesn't use them
+ and if that was what caused us to treat IBFD as 32-bit. */
+ if ((old_flags & EF_MIPS_ABI) == 0
+ && mips_32bit_flags_p (new_flags)
+ && !mips_32bit_flags_p (new_flags & ~EF_MIPS_ABI))
+ elf_elfheader (obfd)->e_flags |= new_flags & EF_MIPS_ABI;
+ }
+ else
+ {
+ /* The ISAs aren't compatible. */
+ (*_bfd_error_handler)
+ (_("%B: linking %s module with previous %s modules"),
+ ibfd,
+ bfd_printable_name (ibfd),
+ bfd_printable_name (obfd));
+ ok = FALSE;
+ }
+ }
+
+ new_flags &= ~(EF_MIPS_ARCH | EF_MIPS_MACH | EF_MIPS_32BITMODE);
+ old_flags &= ~(EF_MIPS_ARCH | EF_MIPS_MACH | EF_MIPS_32BITMODE);
+
+ /* Compare ABIs. The 64-bit ABI does not use EF_MIPS_ABI. But, it
+ does set EI_CLASS differently from any 32-bit ABI. */
+ if ((new_flags & EF_MIPS_ABI) != (old_flags & EF_MIPS_ABI)
+ || (elf_elfheader (ibfd)->e_ident[EI_CLASS]
+ != elf_elfheader (obfd)->e_ident[EI_CLASS]))
+ {
+ /* Only error if both are set (to different values). */
+ if (((new_flags & EF_MIPS_ABI) && (old_flags & EF_MIPS_ABI))
+ || (elf_elfheader (ibfd)->e_ident[EI_CLASS]
+ != elf_elfheader (obfd)->e_ident[EI_CLASS]))
+ {
+ (*_bfd_error_handler)
+ (_("%B: ABI mismatch: linking %s module with previous %s modules"),
+ ibfd,
+ elf_mips_abi_name (ibfd),
+ elf_mips_abi_name (obfd));
+ ok = FALSE;
+ }
+ new_flags &= ~EF_MIPS_ABI;
+ old_flags &= ~EF_MIPS_ABI;
+ }
+
+ /* Compare ASEs. Forbid linking MIPS16 and microMIPS ASE modules together
+ and allow arbitrary mixing of the remaining ASEs (retain the union). */
+ if ((new_flags & EF_MIPS_ARCH_ASE) != (old_flags & EF_MIPS_ARCH_ASE))
+ {
+ int old_micro = old_flags & EF_MIPS_ARCH_ASE_MICROMIPS;
+ int new_micro = new_flags & EF_MIPS_ARCH_ASE_MICROMIPS;
+ int old_m16 = old_flags & EF_MIPS_ARCH_ASE_M16;
+ int new_m16 = new_flags & EF_MIPS_ARCH_ASE_M16;
+ int micro_mis = old_m16 && new_micro;
+ int m16_mis = old_micro && new_m16;
+
+ if (m16_mis || micro_mis)
+ {
+ (*_bfd_error_handler)
+ (_("%B: ASE mismatch: linking %s module with previous %s modules"),
+ ibfd,
+ m16_mis ? "MIPS16" : "microMIPS",
+ m16_mis ? "microMIPS" : "MIPS16");
+ ok = FALSE;
+ }
+
+ elf_elfheader (obfd)->e_flags |= new_flags & EF_MIPS_ARCH_ASE;
+
+ new_flags &= ~ EF_MIPS_ARCH_ASE;
+ old_flags &= ~ EF_MIPS_ARCH_ASE;
+ }
+
+ /* Compare NaN encodings. */
+ if ((new_flags & EF_MIPS_NAN2008) != (old_flags & EF_MIPS_NAN2008))
+ {
+ _bfd_error_handler (_("%B: linking %s module with previous %s modules"),
+ ibfd,
+ (new_flags & EF_MIPS_NAN2008
+ ? "-mnan=2008" : "-mnan=legacy"),
+ (old_flags & EF_MIPS_NAN2008
+ ? "-mnan=2008" : "-mnan=legacy"));
+ ok = FALSE;
+ new_flags &= ~EF_MIPS_NAN2008;
+ old_flags &= ~EF_MIPS_NAN2008;
+ }
+
+ /* Compare FP64 state. */
+ if ((new_flags & EF_MIPS_FP64) != (old_flags & EF_MIPS_FP64))
+ {
+ _bfd_error_handler (_("%B: linking %s module with previous %s modules"),
+ ibfd,
+ (new_flags & EF_MIPS_FP64
+ ? "-mfp64" : "-mfp32"),
+ (old_flags & EF_MIPS_FP64
+ ? "-mfp64" : "-mfp32"));
+ ok = FALSE;
+ new_flags &= ~EF_MIPS_FP64;
+ old_flags &= ~EF_MIPS_FP64;
+ }
+
+ /* Warn about any other mismatches */
+ if (new_flags != old_flags)
+ {
+ (*_bfd_error_handler)
+ (_("%B: uses different e_flags (0x%lx) fields than previous modules (0x%lx)"),
+ ibfd, (unsigned long) new_flags,
+ (unsigned long) old_flags);
+ ok = FALSE;
+ }
+
+ if (! ok)
+ {
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/* Function to keep MIPS specific file flags like as EF_MIPS_PIC. */
+
+bfd_boolean
+_bfd_mips_elf_set_private_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;
+}
+
+char *
+_bfd_mips_elf_get_target_dtag (bfd_vma dtag)
+{
+ switch (dtag)
+ {
+ default: return "";
+ 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_GOT_IDX";
+ case DT_MIPS_OPTIONS:
+ return "MIPS_OPTIONS";
+ case DT_MIPS_INTERFACE:
+ return "MIPS_INTERFACE";
+ case DT_MIPS_DYNSTR_ALIGN:
+ return "DT_MIPS_DYNSTR_ALIGN";
+ case DT_MIPS_INTERFACE_SIZE:
+ return "DT_MIPS_INTERFACE_SIZE";
+ case DT_MIPS_RLD_TEXT_RESOLVE_ADDR:
+ return "DT_MIPS_RLD_TEXT_RESOLVE_ADDR";
+ case DT_MIPS_PERF_SUFFIX:
+ return "DT_MIPS_PERF_SUFFIX";
+ case DT_MIPS_COMPACT_SIZE:
+ return "DT_MIPS_COMPACT_SIZE";
+ case DT_MIPS_GP_VALUE:
+ return "DT_MIPS_GP_VALUE";
+ case DT_MIPS_AUX_DYNAMIC:
+ return "DT_MIPS_AUX_DYNAMIC";
+ case DT_MIPS_PLTGOT:
+ return "DT_MIPS_PLTGOT";
+ case DT_MIPS_RWPLT:
+ return "DT_MIPS_RWPLT";
+ }
+}
+
+/* Return the meaning of Tag_GNU_MIPS_ABI_FP value FP, or null if
+ not known. */
+
+const char *
+_bfd_mips_fp_abi_string (int fp)
+{
+ switch (fp)
+ {
+ /* These strings aren't translated because they're simply
+ option lists. */
+ case Val_GNU_MIPS_ABI_FP_DOUBLE:
+ return "-mdouble-float";
+
+ case Val_GNU_MIPS_ABI_FP_SINGLE:
+ return "-msingle-float";
+
+ case Val_GNU_MIPS_ABI_FP_SOFT:
+ return "-msoft-float";
+
+ case Val_GNU_MIPS_ABI_FP_OLD_64:
+ return _("-mips32r2 -mfp64 (12 callee-saved)");
+
+ case Val_GNU_MIPS_ABI_FP_XX:
+ return "-mfpxx";
+
+ case Val_GNU_MIPS_ABI_FP_64:
+ return "-mgp32 -mfp64";
+
+ case Val_GNU_MIPS_ABI_FP_64A:
+ return "-mgp32 -mfp64 -mno-odd-spreg";
+
+ default:
+ return 0;
+ }
+}
+
+static void
+print_mips_ases (FILE *file, unsigned int mask)
+{
+ if (mask & AFL_ASE_DSP)
+ fputs ("\n\tDSP ASE", file);
+ if (mask & AFL_ASE_DSPR2)
+ fputs ("\n\tDSP R2 ASE", file);
+ if (mask & AFL_ASE_EVA)
+ fputs ("\n\tEnhanced VA Scheme", file);
+ if (mask & AFL_ASE_MCU)
+ fputs ("\n\tMCU (MicroController) ASE", file);
+ if (mask & AFL_ASE_MDMX)
+ fputs ("\n\tMDMX ASE", file);
+ if (mask & AFL_ASE_MIPS3D)
+ fputs ("\n\tMIPS-3D ASE", file);
+ if (mask & AFL_ASE_MT)
+ fputs ("\n\tMT ASE", file);
+ if (mask & AFL_ASE_SMARTMIPS)
+ fputs ("\n\tSmartMIPS ASE", file);
+ if (mask & AFL_ASE_VIRT)
+ fputs ("\n\tVZ ASE", file);
+ if (mask & AFL_ASE_MSA)
+ fputs ("\n\tMSA ASE", file);
+ if (mask & AFL_ASE_MIPS16)
+ fputs ("\n\tMIPS16 ASE", file);
+ if (mask & AFL_ASE_MICROMIPS)
+ fputs ("\n\tMICROMIPS ASE", file);
+ if (mask & AFL_ASE_XPA)
+ fputs ("\n\tXPA ASE", file);
+ if (mask == 0)
+ fprintf (file, "\n\t%s", _("None"));
+ else if ((mask & ~AFL_ASE_MASK) != 0)
+ fprintf (stdout, "\n\t%s (%x)", _("Unknown"), mask & ~AFL_ASE_MASK);
+}
+
+static void
+print_mips_isa_ext (FILE *file, unsigned int isa_ext)
+{
+ switch (isa_ext)
+ {
+ case 0:
+ fputs (_("None"), file);
+ break;
+ case AFL_EXT_XLR:
+ fputs ("RMI XLR", file);
+ break;
+ case AFL_EXT_OCTEON2:
+ fputs ("Cavium Networks Octeon2", file);
+ break;
+ case AFL_EXT_OCTEONP:
+ fputs ("Cavium Networks OcteonP", file);
+ break;
+ case AFL_EXT_LOONGSON_3A:
+ fputs ("Loongson 3A", file);
+ break;
+ case AFL_EXT_OCTEON:
+ fputs ("Cavium Networks Octeon", file);
+ break;
+ case AFL_EXT_5900:
+ fputs ("Toshiba R5900", file);
+ break;
+ case AFL_EXT_4650:
+ fputs ("MIPS R4650", file);
+ break;
+ case AFL_EXT_4010:
+ fputs ("LSI R4010", file);
+ break;
+ case AFL_EXT_4100:
+ fputs ("NEC VR4100", file);
+ break;
+ case AFL_EXT_3900:
+ fputs ("Toshiba R3900", file);
+ break;
+ case AFL_EXT_10000:
+ fputs ("MIPS R10000", file);
+ break;
+ case AFL_EXT_SB1:
+ fputs ("Broadcom SB-1", file);
+ break;
+ case AFL_EXT_4111:
+ fputs ("NEC VR4111/VR4181", file);
+ break;
+ case AFL_EXT_4120:
+ fputs ("NEC VR4120", file);
+ break;
+ case AFL_EXT_5400:
+ fputs ("NEC VR5400", file);
+ break;
+ case AFL_EXT_5500:
+ fputs ("NEC VR5500", file);
+ break;
+ case AFL_EXT_LOONGSON_2E:
+ fputs ("ST Microelectronics Loongson 2E", file);
+ break;
+ case AFL_EXT_LOONGSON_2F:
+ fputs ("ST Microelectronics Loongson 2F", file);
+ break;
+ default:
+ fprintf (file, "%s (%d)", _("Unknown"), isa_ext);
+ break;
+ }
+}
+
+static void
+print_mips_fp_abi_value (FILE *file, int val)
+{
+ switch (val)
+ {
+ case Val_GNU_MIPS_ABI_FP_ANY:
+ fprintf (file, _("Hard or soft float\n"));
+ break;
+ case Val_GNU_MIPS_ABI_FP_DOUBLE:
+ fprintf (file, _("Hard float (double precision)\n"));
+ break;
+ case Val_GNU_MIPS_ABI_FP_SINGLE:
+ fprintf (file, _("Hard float (single precision)\n"));
+ break;
+ case Val_GNU_MIPS_ABI_FP_SOFT:
+ fprintf (file, _("Soft float\n"));
+ break;
+ case Val_GNU_MIPS_ABI_FP_OLD_64:
+ fprintf (file, _("Hard float (MIPS32r2 64-bit FPU 12 callee-saved)\n"));
+ break;
+ case Val_GNU_MIPS_ABI_FP_XX:
+ fprintf (file, _("Hard float (32-bit CPU, Any FPU)\n"));
+ break;
+ case Val_GNU_MIPS_ABI_FP_64:
+ fprintf (file, _("Hard float (32-bit CPU, 64-bit FPU)\n"));
+ break;
+ case Val_GNU_MIPS_ABI_FP_64A:
+ fprintf (file, _("Hard float compat (32-bit CPU, 64-bit FPU)\n"));
+ break;
+ default:
+ fprintf (file, "??? (%d)\n", val);
+ break;
+ }
+}
+
+static int
+get_mips_reg_size (int reg_size)
+{
+ return (reg_size == AFL_REG_NONE) ? 0
+ : (reg_size == AFL_REG_32) ? 32
+ : (reg_size == AFL_REG_64) ? 64
+ : (reg_size == AFL_REG_128) ? 128
+ : -1;
+}
+
+bfd_boolean
+_bfd_mips_elf_print_private_bfd_data (bfd *abfd, void *ptr)
+{
+ 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 if (ABI_N32_P (abfd))
+ fprintf (file, _(" [abi=N32]"));
+ else if (ABI_64_P (abfd))
+ fprintf (file, _(" [abi=64]"));
+ 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 if ((elf_elfheader (abfd)->e_flags & EF_MIPS_ARCH) == E_MIPS_ARCH_5)
+ fprintf (file, " [mips5]");
+ else if ((elf_elfheader (abfd)->e_flags & EF_MIPS_ARCH) == E_MIPS_ARCH_32)
+ fprintf (file, " [mips32]");
+ else if ((elf_elfheader (abfd)->e_flags & EF_MIPS_ARCH) == E_MIPS_ARCH_64)
+ fprintf (file, " [mips64]");
+ else if ((elf_elfheader (abfd)->e_flags & EF_MIPS_ARCH) == E_MIPS_ARCH_32R2)
+ fprintf (file, " [mips32r2]");
+ else if ((elf_elfheader (abfd)->e_flags & EF_MIPS_ARCH) == E_MIPS_ARCH_64R2)
+ fprintf (file, " [mips64r2]");
+ else if ((elf_elfheader (abfd)->e_flags & EF_MIPS_ARCH) == E_MIPS_ARCH_32R6)
+ fprintf (file, " [mips32r6]");
+ else if ((elf_elfheader (abfd)->e_flags & EF_MIPS_ARCH) == E_MIPS_ARCH_64R6)
+ fprintf (file, " [mips64r6]");
+ else
+ fprintf (file, _(" [unknown ISA]"));
+
+ if (elf_elfheader (abfd)->e_flags & EF_MIPS_ARCH_ASE_MDMX)
+ fprintf (file, " [mdmx]");
+
+ if (elf_elfheader (abfd)->e_flags & EF_MIPS_ARCH_ASE_M16)
+ fprintf (file, " [mips16]");
+
+ if (elf_elfheader (abfd)->e_flags & EF_MIPS_ARCH_ASE_MICROMIPS)
+ fprintf (file, " [micromips]");
+
+ if (elf_elfheader (abfd)->e_flags & EF_MIPS_NAN2008)
+ fprintf (file, " [nan2008]");
+
+ if (elf_elfheader (abfd)->e_flags & EF_MIPS_FP64)
+ fprintf (file, " [old fp64]");
+
+ if (elf_elfheader (abfd)->e_flags & EF_MIPS_32BITMODE)
+ fprintf (file, " [32bitmode]");
+ else
+ fprintf (file, _(" [not 32bitmode]"));
+
+ if (elf_elfheader (abfd)->e_flags & EF_MIPS_NOREORDER)
+ fprintf (file, " [noreorder]");
+
+ if (elf_elfheader (abfd)->e_flags & EF_MIPS_PIC)
+ fprintf (file, " [PIC]");
+
+ if (elf_elfheader (abfd)->e_flags & EF_MIPS_CPIC)
+ fprintf (file, " [CPIC]");
+
+ if (elf_elfheader (abfd)->e_flags & EF_MIPS_XGOT)
+ fprintf (file, " [XGOT]");
+
+ if (elf_elfheader (abfd)->e_flags & EF_MIPS_UCODE)
+ fprintf (file, " [UCODE]");
+
+ fputc ('\n', file);
+
+ if (mips_elf_tdata (abfd)->abiflags_valid)
+ {
+ Elf_Internal_ABIFlags_v0 *abiflags = &mips_elf_tdata (abfd)->abiflags;
+ fprintf (file, "\nMIPS ABI Flags Version: %d\n", abiflags->version);
+ fprintf (file, "\nISA: MIPS%d", abiflags->isa_level);
+ if (abiflags->isa_rev > 1)
+ fprintf (file, "r%d", abiflags->isa_rev);
+ fprintf (file, "\nGPR size: %d",
+ get_mips_reg_size (abiflags->gpr_size));
+ fprintf (file, "\nCPR1 size: %d",
+ get_mips_reg_size (abiflags->cpr1_size));
+ fprintf (file, "\nCPR2 size: %d",
+ get_mips_reg_size (abiflags->cpr2_size));
+ fputs ("\nFP ABI: ", file);
+ print_mips_fp_abi_value (file, abiflags->fp_abi);
+ fputs ("ISA Extension: ", file);
+ print_mips_isa_ext (file, abiflags->isa_ext);
+ fputs ("\nASEs:", file);
+ print_mips_ases (file, abiflags->ases);
+ fprintf (file, "\nFLAGS 1: %8.8lx", abiflags->flags1);
+ fprintf (file, "\nFLAGS 2: %8.8lx", abiflags->flags2);
+ fputc ('\n', file);
+ }
+
+ return TRUE;
+}
+
+const struct bfd_elf_special_section _bfd_mips_elf_special_sections[] =
+{
+ { STRING_COMMA_LEN (".lit4"), 0, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE + SHF_MIPS_GPREL },
+ { STRING_COMMA_LEN (".lit8"), 0, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE + SHF_MIPS_GPREL },
+ { STRING_COMMA_LEN (".mdebug"), 0, SHT_MIPS_DEBUG, 0 },
+ { STRING_COMMA_LEN (".sbss"), -2, SHT_NOBITS, SHF_ALLOC + SHF_WRITE + SHF_MIPS_GPREL },
+ { STRING_COMMA_LEN (".sdata"), -2, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE + SHF_MIPS_GPREL },
+ { STRING_COMMA_LEN (".ucode"), 0, SHT_MIPS_UCODE, 0 },
+ { NULL, 0, 0, 0, 0 }
+};
+
+/* Merge non visibility st_other attributes. Ensure that the
+ STO_OPTIONAL flag is copied into h->other, even if this is not a
+ definiton of the symbol. */
+void
+_bfd_mips_elf_merge_symbol_attribute (struct elf_link_hash_entry *h,
+ const Elf_Internal_Sym *isym,
+ bfd_boolean definition,
+ bfd_boolean dynamic ATTRIBUTE_UNUSED)
+{
+ if ((isym->st_other & ~ELF_ST_VISIBILITY (-1)) != 0)
+ {
+ unsigned char other;
+
+ other = (definition ? isym->st_other : h->other);
+ other &= ~ELF_ST_VISIBILITY (-1);
+ h->other = other | ELF_ST_VISIBILITY (h->other);
+ }
+
+ if (!definition
+ && ELF_MIPS_IS_OPTIONAL (isym->st_other))
+ h->other |= STO_OPTIONAL;
+}
+
+/* Decide whether an undefined symbol is special and can be ignored.
+ This is the case for OPTIONAL symbols on IRIX. */
+bfd_boolean
+_bfd_mips_elf_ignore_undef_symbol (struct elf_link_hash_entry *h)
+{
+ return ELF_MIPS_IS_OPTIONAL (h->other) ? TRUE : FALSE;
+}
+
+bfd_boolean
+_bfd_mips_elf_common_definition (Elf_Internal_Sym *sym)
+{
+ return (sym->st_shndx == SHN_COMMON
+ || sym->st_shndx == SHN_MIPS_ACOMMON
+ || sym->st_shndx == SHN_MIPS_SCOMMON);
+}
+
+/* Return address for Ith PLT stub in section PLT, for relocation REL
+ or (bfd_vma) -1 if it should not be included. */
+
+bfd_vma
+_bfd_mips_elf_plt_sym_val (bfd_vma i, const asection *plt,
+ const arelent *rel ATTRIBUTE_UNUSED)
+{
+ return (plt->vma
+ + 4 * ARRAY_SIZE (mips_o32_exec_plt0_entry)
+ + i * 4 * ARRAY_SIZE (mips_exec_plt_entry));
+}
+
+/* Build a table of synthetic symbols to represent the PLT. As with MIPS16
+ and microMIPS PLT slots we may have a many-to-one mapping between .plt
+ and .got.plt and also the slots may be of a different size each we walk
+ the PLT manually fetching instructions and matching them against known
+ patterns. To make things easier standard MIPS slots, if any, always come
+ first. As we don't create proper ELF symbols we use the UDATA.I member
+ of ASYMBOL to carry ISA annotation. The encoding used is the same as
+ with the ST_OTHER member of the ELF symbol. */
+
+long
+_bfd_mips_elf_get_synthetic_symtab (bfd *abfd,
+ long symcount ATTRIBUTE_UNUSED,
+ asymbol **syms ATTRIBUTE_UNUSED,
+ long dynsymcount, asymbol **dynsyms,
+ asymbol **ret)
+{
+ static const char pltname[] = "_PROCEDURE_LINKAGE_TABLE_";
+ static const char microsuffix[] = "@micromipsplt";
+ static const char m16suffix[] = "@mips16plt";
+ static const char mipssuffix[] = "@plt";
+
+ bfd_boolean (*slurp_relocs) (bfd *, asection *, asymbol **, bfd_boolean);
+ const struct elf_backend_data *bed = get_elf_backend_data (abfd);
+ bfd_boolean micromips_p = MICROMIPS_P (abfd);
+ Elf_Internal_Shdr *hdr;
+ bfd_byte *plt_data;
+ bfd_vma plt_offset;
+ unsigned int other;
+ bfd_vma entry_size;
+ bfd_vma plt0_size;
+ asection *relplt;
+ bfd_vma opcode;
+ asection *plt;
+ asymbol *send;
+ size_t size;
+ char *names;
+ long counti;
+ arelent *p;
+ asymbol *s;
+ char *nend;
+ long count;
+ long pi;
+ long i;
+ long n;
+
+ *ret = NULL;
+
+ if ((abfd->flags & (DYNAMIC | EXEC_P)) == 0 || dynsymcount <= 0)
+ return 0;
+
+ relplt = bfd_get_section_by_name (abfd, ".rel.plt");
+ if (relplt == NULL)
+ return 0;
+
+ hdr = &elf_section_data (relplt)->this_hdr;
+ if (hdr->sh_link != elf_dynsymtab (abfd) || hdr->sh_type != SHT_REL)
+ return 0;
+
+ plt = bfd_get_section_by_name (abfd, ".plt");
+ if (plt == NULL)
+ return 0;
+
+ slurp_relocs = get_elf_backend_data (abfd)->s->slurp_reloc_table;
+ if (!(*slurp_relocs) (abfd, relplt, dynsyms, TRUE))
+ return -1;
+ p = relplt->relocation;
+
+ /* Calculating the exact amount of space required for symbols would
+ require two passes over the PLT, so just pessimise assuming two
+ PLT slots per relocation. */
+ count = relplt->size / hdr->sh_entsize;
+ counti = count * bed->s->int_rels_per_ext_rel;
+ size = 2 * count * sizeof (asymbol);
+ size += count * (sizeof (mipssuffix) +
+ (micromips_p ? sizeof (microsuffix) : sizeof (m16suffix)));
+ for (pi = 0; pi < counti; pi += bed->s->int_rels_per_ext_rel)
+ size += 2 * strlen ((*p[pi].sym_ptr_ptr)->name);
+
+ /* Add the size of "_PROCEDURE_LINKAGE_TABLE_" too. */
+ size += sizeof (asymbol) + sizeof (pltname);
+
+ if (!bfd_malloc_and_get_section (abfd, plt, &plt_data))
+ return -1;
+
+ if (plt->size < 16)
+ return -1;
+
+ s = *ret = bfd_malloc (size);
+ if (s == NULL)
+ return -1;
+ send = s + 2 * count + 1;
+
+ names = (char *) send;
+ nend = (char *) s + size;
+ n = 0;
+
+ opcode = bfd_get_micromips_32 (abfd, plt_data + 12);
+ if (opcode == 0x3302fffe)
+ {
+ if (!micromips_p)
+ return -1;
+ plt0_size = 2 * ARRAY_SIZE (micromips_o32_exec_plt0_entry);
+ other = STO_MICROMIPS;
+ }
+ else if (opcode == 0x0398c1d0)
+ {
+ if (!micromips_p)
+ return -1;
+ plt0_size = 2 * ARRAY_SIZE (micromips_insn32_o32_exec_plt0_entry);
+ other = STO_MICROMIPS;
+ }
+ else
+ {
+ plt0_size = 4 * ARRAY_SIZE (mips_o32_exec_plt0_entry);
+ other = 0;
+ }
+
+ s->the_bfd = abfd;
+ s->flags = BSF_SYNTHETIC | BSF_FUNCTION | BSF_LOCAL;
+ s->section = plt;
+ s->value = 0;
+ s->name = names;
+ s->udata.i = other;
+ memcpy (names, pltname, sizeof (pltname));
+ names += sizeof (pltname);
+ ++s, ++n;
+
+ pi = 0;
+ for (plt_offset = plt0_size;
+ plt_offset + 8 <= plt->size && s < send;
+ plt_offset += entry_size)
+ {
+ bfd_vma gotplt_addr;
+ const char *suffix;
+ bfd_vma gotplt_hi;
+ bfd_vma gotplt_lo;
+ size_t suffixlen;
+
+ opcode = bfd_get_micromips_32 (abfd, plt_data + plt_offset + 4);
+
+ /* Check if the second word matches the expected MIPS16 instruction. */
+ if (opcode == 0x651aeb00)
+ {
+ if (micromips_p)
+ return -1;
+ /* Truncated table??? */
+ if (plt_offset + 16 > plt->size)
+ break;
+ gotplt_addr = bfd_get_32 (abfd, plt_data + plt_offset + 12);
+ entry_size = 2 * ARRAY_SIZE (mips16_o32_exec_plt_entry);
+ suffixlen = sizeof (m16suffix);
+ suffix = m16suffix;
+ other = STO_MIPS16;
+ }
+ /* Likewise the expected microMIPS instruction (no insn32 mode). */
+ else if (opcode == 0xff220000)
+ {
+ if (!micromips_p)
+ return -1;
+ gotplt_hi = bfd_get_16 (abfd, plt_data + plt_offset) & 0x7f;
+ gotplt_lo = bfd_get_16 (abfd, plt_data + plt_offset + 2) & 0xffff;
+ gotplt_hi = ((gotplt_hi ^ 0x40) - 0x40) << 18;
+ gotplt_lo <<= 2;
+ gotplt_addr = gotplt_hi + gotplt_lo;
+ gotplt_addr += ((plt->vma + plt_offset) | 3) ^ 3;
+ entry_size = 2 * ARRAY_SIZE (micromips_o32_exec_plt_entry);
+ suffixlen = sizeof (microsuffix);
+ suffix = microsuffix;
+ other = STO_MICROMIPS;
+ }
+ /* Likewise the expected microMIPS instruction (insn32 mode). */
+ else if ((opcode & 0xffff0000) == 0xff2f0000)
+ {
+ gotplt_hi = bfd_get_16 (abfd, plt_data + plt_offset + 2) & 0xffff;
+ gotplt_lo = bfd_get_16 (abfd, plt_data + plt_offset + 6) & 0xffff;
+ gotplt_hi = ((gotplt_hi ^ 0x8000) - 0x8000) << 16;
+ gotplt_lo = (gotplt_lo ^ 0x8000) - 0x8000;
+ gotplt_addr = gotplt_hi + gotplt_lo;
+ entry_size = 2 * ARRAY_SIZE (micromips_insn32_o32_exec_plt_entry);
+ suffixlen = sizeof (microsuffix);
+ suffix = microsuffix;
+ other = STO_MICROMIPS;
+ }
+ /* Otherwise assume standard MIPS code. */
+ else
+ {
+ gotplt_hi = bfd_get_32 (abfd, plt_data + plt_offset) & 0xffff;
+ gotplt_lo = bfd_get_32 (abfd, plt_data + plt_offset + 4) & 0xffff;
+ gotplt_hi = ((gotplt_hi ^ 0x8000) - 0x8000) << 16;
+ gotplt_lo = (gotplt_lo ^ 0x8000) - 0x8000;
+ gotplt_addr = gotplt_hi + gotplt_lo;
+ entry_size = 4 * ARRAY_SIZE (mips_exec_plt_entry);
+ suffixlen = sizeof (mipssuffix);
+ suffix = mipssuffix;
+ other = 0;
+ }
+ /* Truncated table??? */
+ if (plt_offset + entry_size > plt->size)
+ break;
+
+ for (i = 0;
+ i < count && p[pi].address != gotplt_addr;
+ i++, pi = (pi + bed->s->int_rels_per_ext_rel) % counti);
+
+ if (i < count)
+ {
+ size_t namelen;
+ size_t len;
+
+ *s = **p[pi].sym_ptr_ptr;
+ /* Undefined syms won't have BSF_LOCAL or BSF_GLOBAL set. Since
+ we are defining a symbol, ensure one of them is set. */
+ if ((s->flags & BSF_LOCAL) == 0)
+ s->flags |= BSF_GLOBAL;
+ s->flags |= BSF_SYNTHETIC;
+ s->section = plt;
+ s->value = plt_offset;
+ s->name = names;
+ s->udata.i = other;
+
+ len = strlen ((*p[pi].sym_ptr_ptr)->name);
+ namelen = len + suffixlen;
+ if (names + namelen > nend)
+ break;
+
+ memcpy (names, (*p[pi].sym_ptr_ptr)->name, len);
+ names += len;
+ memcpy (names, suffix, suffixlen);
+ names += suffixlen;
+
+ ++s, ++n;
+ pi = (pi + bed->s->int_rels_per_ext_rel) % counti;
+ }
+ }
+
+ free (plt_data);
+
+ return n;
+}
+
+void
+_bfd_mips_post_process_headers (bfd *abfd, struct bfd_link_info *link_info)
+{
+ struct mips_elf_link_hash_table *htab;
+ Elf_Internal_Ehdr *i_ehdrp;
+
+ i_ehdrp = elf_elfheader (abfd);
+ if (link_info)
+ {
+ htab = mips_elf_hash_table (link_info);
+ BFD_ASSERT (htab != NULL);
+
+ if (htab->use_plts_and_copy_relocs && !htab->is_vxworks)
+ i_ehdrp->e_ident[EI_ABIVERSION] = 1;
+ }
+
+ _bfd_elf_post_process_headers (abfd, link_info);
+
+ if (mips_elf_tdata (abfd)->abiflags.fp_abi == Val_GNU_MIPS_ABI_FP_64
+ || mips_elf_tdata (abfd)->abiflags.fp_abi == Val_GNU_MIPS_ABI_FP_64A)
+ i_ehdrp->e_ident[EI_ABIVERSION] = 3;
+}
diff --git a/bfd/elfxx-mips.h b/bfd/elfxx-mips.h
new file mode 100644
index 0000000..8f5c53e
--- /dev/null
+++ b/bfd/elfxx-mips.h
@@ -0,0 +1,191 @@
+/* MIPS ELF specific backend routines.
+ Copyright (C) 2002-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "elf/common.h"
+#include "elf/internal.h"
+#include "elf/mips.h"
+
+extern bfd_boolean _bfd_mips_elf_mkobject
+ (bfd *);
+extern bfd_boolean _bfd_mips_elf_new_section_hook
+ (bfd *, asection *);
+extern void _bfd_mips_elf_symbol_processing
+ (bfd *, asymbol *);
+extern unsigned int _bfd_mips_elf_eh_frame_address_size
+ (bfd *, asection *);
+extern bfd_boolean _bfd_mips_elf_name_local_section_symbols
+ (bfd *);
+extern bfd_boolean _bfd_mips_elf_section_processing
+ (bfd *, Elf_Internal_Shdr *);
+extern bfd_boolean _bfd_mips_elf_section_from_shdr
+ (bfd *, Elf_Internal_Shdr *, const char *, int);
+extern bfd_boolean _bfd_mips_elf_fake_sections
+ (bfd *, Elf_Internal_Shdr *, asection *);
+extern bfd_boolean _bfd_mips_elf_section_from_bfd_section
+ (bfd *, asection *, int *);
+extern bfd_boolean _bfd_mips_elf_add_symbol_hook
+ (bfd *, struct bfd_link_info *, Elf_Internal_Sym *,
+ const char **, flagword *, asection **, bfd_vma *);
+extern int _bfd_mips_elf_link_output_symbol_hook
+ (struct bfd_link_info *, const char *, Elf_Internal_Sym *,
+ asection *, struct elf_link_hash_entry *);
+extern bfd_boolean _bfd_mips_elf_create_dynamic_sections
+ (bfd *, struct bfd_link_info *);
+extern bfd_boolean _bfd_mips_elf_check_relocs
+ (bfd *, struct bfd_link_info *, asection *, const Elf_Internal_Rela *);
+extern bfd_boolean _bfd_mips_elf_adjust_dynamic_symbol
+ (struct bfd_link_info *, struct elf_link_hash_entry *);
+extern bfd_boolean _bfd_mips_elf_always_size_sections
+ (bfd *, struct bfd_link_info *);
+extern bfd_boolean _bfd_mips_elf_size_dynamic_sections
+ (bfd *, struct bfd_link_info *);
+extern bfd_boolean _bfd_mips_elf_relocate_section
+ (bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
+ Elf_Internal_Rela *, Elf_Internal_Sym *, asection **);
+extern bfd_boolean _bfd_mips_elf_finish_dynamic_symbol
+ (bfd *, struct bfd_link_info *, struct elf_link_hash_entry *,
+ Elf_Internal_Sym *);
+extern bfd_boolean _bfd_mips_vxworks_finish_dynamic_symbol
+ (bfd *, struct bfd_link_info *, struct elf_link_hash_entry *,
+ Elf_Internal_Sym *);
+extern bfd_boolean _bfd_mips_elf_finish_dynamic_sections
+ (bfd *, struct bfd_link_info *);
+extern void _bfd_mips_elf_final_write_processing
+ (bfd *, bfd_boolean);
+extern int _bfd_mips_elf_additional_program_headers
+ (bfd *, struct bfd_link_info *);
+extern bfd_boolean _bfd_mips_elf_modify_segment_map
+ (bfd *, struct bfd_link_info *);
+extern asection * _bfd_mips_elf_gc_mark_hook
+ (asection *, struct bfd_link_info *, Elf_Internal_Rela *,
+ struct elf_link_hash_entry *, Elf_Internal_Sym *);
+extern bfd_boolean _bfd_mips_elf_gc_sweep_hook
+ (bfd *, struct bfd_link_info *, asection *, const Elf_Internal_Rela *);
+extern void _bfd_mips_elf_copy_indirect_symbol
+ (struct bfd_link_info *, struct elf_link_hash_entry *,
+ struct elf_link_hash_entry *);
+extern bfd_boolean _bfd_mips_elf_ignore_discarded_relocs
+ (asection *);
+extern bfd_boolean _bfd_mips_elf_is_target_special_symbol
+ (bfd *abfd, asymbol *sym);
+extern bfd_boolean _bfd_mips_elf_find_nearest_line
+ (bfd *, asymbol **, asection *, bfd_vma,
+ const char **, const char **, unsigned int *, unsigned int *);
+extern bfd_boolean _bfd_mips_elf_find_inliner_info
+ (bfd *, const char **, const char **, unsigned int *);
+extern bfd_boolean _bfd_mips_elf_set_section_contents
+ (bfd *, asection *, const void *, file_ptr, bfd_size_type);
+extern bfd_byte *_bfd_elf_mips_get_relocated_section_contents
+ (bfd *, struct bfd_link_info *, struct bfd_link_order *,
+ bfd_byte *, bfd_boolean, asymbol **);
+extern bfd_boolean _bfd_mips_elf_relax_section
+ (bfd *abfd, asection *sec, struct bfd_link_info *link_info,
+ bfd_boolean *again);
+extern struct bfd_link_hash_table *_bfd_mips_elf_link_hash_table_create
+ (bfd *);
+extern struct bfd_link_hash_table *_bfd_mips_vxworks_link_hash_table_create
+ (bfd *);
+extern bfd_boolean _bfd_mips_elf_final_link
+ (bfd *, struct bfd_link_info *);
+extern bfd_boolean _bfd_mips_elf_merge_private_bfd_data
+ (bfd *, bfd *);
+extern bfd_boolean _bfd_mips_elf_set_private_flags
+ (bfd *, flagword);
+extern const char * _bfd_mips_fp_abi_string
+ (int);
+extern bfd_boolean _bfd_mips_elf_print_private_bfd_data
+ (bfd *, void *);
+extern bfd_boolean _bfd_mips_elf_discard_info
+ (bfd *, struct elf_reloc_cookie *, struct bfd_link_info *);
+extern bfd_boolean _bfd_mips_elf_write_section
+ (bfd *, struct bfd_link_info *, asection *, bfd_byte *);
+
+extern bfd_boolean _bfd_mips_elf_read_ecoff_info
+ (bfd *, asection *, struct ecoff_debug_info *);
+extern void _bfd_mips_elf_reloc_unshuffle
+ (bfd *, int, bfd_boolean, bfd_byte *);
+extern void _bfd_mips_elf_reloc_shuffle
+ (bfd *, int, bfd_boolean, bfd_byte *);
+extern bfd_reloc_status_type _bfd_mips_elf_gprel16_with_gp
+ (bfd *, asymbol *, arelent *, asection *, bfd_boolean, void *, bfd_vma);
+extern bfd_reloc_status_type _bfd_mips_elf32_gprel16_reloc
+ (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
+extern bfd_reloc_status_type _bfd_mips_elf_hi16_reloc
+ (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
+extern bfd_reloc_status_type _bfd_mips_elf_got16_reloc
+ (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
+extern bfd_reloc_status_type _bfd_mips_elf_lo16_reloc
+ (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
+extern bfd_reloc_status_type _bfd_mips_elf_generic_reloc
+ (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
+extern unsigned long _bfd_elf_mips_mach
+ (flagword);
+extern bfd_boolean _bfd_mips_relax_section
+ (bfd *, asection *, struct bfd_link_info *, bfd_boolean *);
+extern bfd_vma _bfd_mips_elf_sign_extend
+ (bfd_vma, int);
+extern void _bfd_mips_elf_merge_symbol_attribute
+ (struct elf_link_hash_entry *, const Elf_Internal_Sym *, bfd_boolean, bfd_boolean);
+extern char *_bfd_mips_elf_get_target_dtag (bfd_vma);
+extern bfd_boolean _bfd_mips_elf_ignore_undef_symbol
+ (struct elf_link_hash_entry *);
+extern void _bfd_mips_elf_use_plts_and_copy_relocs
+ (struct bfd_link_info *);
+extern void _bfd_mips_elf_insn32
+ (struct bfd_link_info *, bfd_boolean);
+extern bfd_boolean _bfd_mips_elf_init_stubs
+ (struct bfd_link_info *,
+ asection *(*) (const char *, asection *, asection *));
+extern bfd_vma _bfd_mips_elf_plt_sym_val
+ (bfd_vma, const asection *, const arelent *rel);
+extern long _bfd_mips_elf_get_synthetic_symtab
+ (bfd *, long, asymbol **, long, asymbol **, asymbol **);
+extern bfd_boolean _bfd_mips_elf_gc_mark_extra_sections
+ (struct bfd_link_info *, elf_gc_mark_hook_fn);
+extern void _bfd_mips_post_process_headers
+ (bfd *abfd, struct bfd_link_info *link_info);
+
+extern const struct bfd_elf_special_section _bfd_mips_elf_special_sections [];
+
+extern bfd_boolean _bfd_mips_elf_common_definition (Elf_Internal_Sym *);
+
+static inline bfd_boolean
+gprel16_reloc_p (unsigned int r_type)
+{
+ return (r_type == R_MIPS_GPREL16
+ || r_type == R_MIPS16_GPREL
+ || r_type == R_MICROMIPS_GPREL16
+ || r_type == R_MICROMIPS_GPREL7_S2);
+}
+
+static inline bfd_boolean
+literal_reloc_p (int r_type)
+{
+ return r_type == R_MIPS_LITERAL || r_type == R_MICROMIPS_LITERAL;
+}
+
+#define elf_backend_common_definition _bfd_mips_elf_common_definition
+#define elf_backend_name_local_section_symbols \
+ _bfd_mips_elf_name_local_section_symbols
+#define elf_backend_special_sections _bfd_mips_elf_special_sections
+#define elf_backend_eh_frame_address_size _bfd_mips_elf_eh_frame_address_size
+#define elf_backend_merge_symbol_attribute _bfd_mips_elf_merge_symbol_attribute
+#define elf_backend_ignore_undef_symbol _bfd_mips_elf_ignore_undef_symbol
+#define elf_backend_post_process_headers _bfd_mips_post_process_headers
diff --git a/bfd/elfxx-sparc.c b/bfd/elfxx-sparc.c
new file mode 100644
index 0000000..d5f92d4
--- /dev/null
+++ b/bfd/elfxx-sparc.c
@@ -0,0 +1,4926 @@
+/* SPARC-specific support for ELF
+ Copyright (C) 2005-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+
+/* This file handles functionality common to the different SPARC ABI's. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "bfdlink.h"
+#include "libbfd.h"
+#include "libiberty.h"
+#include "elf-bfd.h"
+#include "elf/sparc.h"
+#include "opcode/sparc.h"
+#include "elfxx-sparc.h"
+#include "elf-vxworks.h"
+#include "objalloc.h"
+#include "hashtab.h"
+
+/* In case we're on a 32-bit machine, construct a 64-bit "-1" value. */
+#define MINUS_ONE (~ (bfd_vma) 0)
+
+#define ABI_64_P(abfd) \
+ (get_elf_backend_data (abfd)->s->elfclass == ELFCLASS64)
+
+/* The relocation "howto" table. */
+
+/* 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 (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
+ void * 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 is FALSE. */
+ if (output_bfd != NULL)
+ return bfd_reloc_continue;
+
+ if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
+ 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 (bfd *abfd ATTRIBUTE_UNUSED,
+ arelent *reloc_entry ATTRIBUTE_UNUSED,
+ asymbol *symbol ATTRIBUTE_UNUSED,
+ void * data ATTRIBUTE_UNUSED,
+ asection *input_section ATTRIBUTE_UNUSED,
+ bfd *output_bfd ATTRIBUTE_UNUSED,
+ char **error_message ATTRIBUTE_UNUSED)
+{
+ return bfd_reloc_notsupported;
+}
+
+/* Handle the WDISP16 reloc. */
+
+static bfd_reloc_status_type
+sparc_elf_wdisp16_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
+ void * data, asection *input_section, bfd *output_bfd,
+ char **error_message ATTRIBUTE_UNUSED)
+{
+ 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 &= ~ (bfd_vma) 0x303fff;
+ insn |= (((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 WDISP10 reloc. */
+
+static bfd_reloc_status_type
+sparc_elf_wdisp10_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
+ void * data, asection *input_section, bfd *output_bfd,
+ char **error_message ATTRIBUTE_UNUSED)
+{
+ 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 &= ~ (bfd_vma) 0x181fe0;
+ insn |= (((relocation >> 2) & 0x300) << 11)
+ | (((relocation >> 2) & 0xff) << 5);
+ bfd_put_32 (abfd, insn, (bfd_byte *) data + reloc_entry->address);
+
+ if ((bfd_signed_vma) relocation < - 0x1000
+ || (bfd_signed_vma) relocation > 0xfff)
+ return bfd_reloc_overflow;
+ else
+ return bfd_reloc_ok;
+}
+
+/* Handle the HIX22 reloc. */
+
+static bfd_reloc_status_type
+sparc_elf_hix22_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
+ void * data, asection *input_section, bfd *output_bfd,
+ char **error_message ATTRIBUTE_UNUSED)
+{
+ 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 &~ (bfd_vma) 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 (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
+ void * data, asection *input_section, bfd *output_bfd,
+ char **error_message ATTRIBUTE_UNUSED)
+{
+ 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 &~ (bfd_vma) 0x1fff) | 0x1c00 | (relocation & 0x3ff);
+ bfd_put_32 (abfd, insn, (bfd_byte *) data + reloc_entry->address);
+
+ return bfd_reloc_ok;
+}
+
+static 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,0xffffffff,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,2,32,FALSE,0,complain_overflow_bitfield,bfd_elf_generic_reloc, "R_SPARC_UA32", FALSE,0,0xffffffff,TRUE),
+ HOWTO(R_SPARC_PLT32, 0,2,32,FALSE,0,complain_overflow_bitfield,bfd_elf_generic_reloc, "R_SPARC_PLT32", FALSE,0,0xffffffff,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),
+ 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,bfd_elf_generic_reloc, "R_SPARC_PLT64", FALSE,0,MINUS_ONE, TRUE),
+ 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),
+ HOWTO(R_SPARC_TLS_GD_HI22,10,2,22,FALSE,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_TLS_GD_HI22",FALSE,0,0x003fffff,TRUE),
+ HOWTO(R_SPARC_TLS_GD_LO10,0,2,10,FALSE,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_TLS_GD_LO10",FALSE,0,0x000003ff,TRUE),
+ HOWTO(R_SPARC_TLS_GD_ADD,0,0, 0,FALSE,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_TLS_GD_ADD",FALSE,0,0x00000000,TRUE),
+ HOWTO(R_SPARC_TLS_GD_CALL,2,2,30,TRUE,0,complain_overflow_signed, bfd_elf_generic_reloc, "R_SPARC_TLS_GD_CALL",FALSE,0,0x3fffffff,TRUE),
+ HOWTO(R_SPARC_TLS_LDM_HI22,10,2,22,FALSE,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_TLS_LDM_HI22",FALSE,0,0x003fffff,TRUE),
+ HOWTO(R_SPARC_TLS_LDM_LO10,0,2,10,FALSE,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_TLS_LDM_LO10",FALSE,0,0x000003ff,TRUE),
+ HOWTO(R_SPARC_TLS_LDM_ADD,0,0, 0,FALSE,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_TLS_LDM_ADD",FALSE,0,0x00000000,TRUE),
+ HOWTO(R_SPARC_TLS_LDM_CALL,2,2,30,TRUE,0,complain_overflow_signed, bfd_elf_generic_reloc, "R_SPARC_TLS_LDM_CALL",FALSE,0,0x3fffffff,TRUE),
+ HOWTO(R_SPARC_TLS_LDO_HIX22,0,2,0,FALSE,0,complain_overflow_bitfield,sparc_elf_hix22_reloc,"R_SPARC_TLS_LDO_HIX22",FALSE,0,0x003fffff, FALSE),
+ HOWTO(R_SPARC_TLS_LDO_LOX10,0,2,0,FALSE,0,complain_overflow_dont, sparc_elf_lox10_reloc, "R_SPARC_TLS_LDO_LOX10",FALSE,0,0x000003ff, FALSE),
+ HOWTO(R_SPARC_TLS_LDO_ADD,0,0, 0,FALSE,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_TLS_LDO_ADD",FALSE,0,0x00000000,TRUE),
+ HOWTO(R_SPARC_TLS_IE_HI22,10,2,22,FALSE,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_TLS_IE_HI22",FALSE,0,0x003fffff,TRUE),
+ HOWTO(R_SPARC_TLS_IE_LO10,0,2,10,FALSE,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_TLS_IE_LO10",FALSE,0,0x000003ff,TRUE),
+ HOWTO(R_SPARC_TLS_IE_LD,0,0, 0,FALSE,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_TLS_IE_LD",FALSE,0,0x00000000,TRUE),
+ HOWTO(R_SPARC_TLS_IE_LDX,0,0, 0,FALSE,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_TLS_IE_LDX",FALSE,0,0x00000000,TRUE),
+ HOWTO(R_SPARC_TLS_IE_ADD,0,0, 0,FALSE,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_TLS_IE_ADD",FALSE,0,0x00000000,TRUE),
+ HOWTO(R_SPARC_TLS_LE_HIX22,0,2,0,FALSE,0,complain_overflow_bitfield,sparc_elf_hix22_reloc, "R_SPARC_TLS_LE_HIX22",FALSE,0,0x003fffff, FALSE),
+ HOWTO(R_SPARC_TLS_LE_LOX10,0,2,0,FALSE,0,complain_overflow_dont, sparc_elf_lox10_reloc, "R_SPARC_TLS_LE_LOX10",FALSE,0,0x000003ff, FALSE),
+ HOWTO(R_SPARC_TLS_DTPMOD32,0,0, 0,FALSE,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_TLS_DTPMOD32",FALSE,0,0x00000000,TRUE),
+ HOWTO(R_SPARC_TLS_DTPMOD64,0,0, 0,FALSE,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_TLS_DTPMOD64",FALSE,0,0x00000000,TRUE),
+ HOWTO(R_SPARC_TLS_DTPOFF32,0,2,32,FALSE,0,complain_overflow_bitfield,bfd_elf_generic_reloc,"R_SPARC_TLS_DTPOFF32",FALSE,0,0xffffffff,TRUE),
+ HOWTO(R_SPARC_TLS_DTPOFF64,0,4,64,FALSE,0,complain_overflow_bitfield,bfd_elf_generic_reloc,"R_SPARC_TLS_DTPOFF64",FALSE,0,MINUS_ONE,TRUE),
+ HOWTO(R_SPARC_TLS_TPOFF32,0,0, 0,FALSE,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_TLS_TPOFF32",FALSE,0,0x00000000,TRUE),
+ HOWTO(R_SPARC_TLS_TPOFF64,0,0, 0,FALSE,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_TLS_TPOFF64",FALSE,0,0x00000000,TRUE),
+ HOWTO(R_SPARC_GOTDATA_HIX22,0,2,0,FALSE,0,complain_overflow_bitfield,sparc_elf_hix22_reloc,"R_SPARC_GOTDATA_HIX22",FALSE,0,0x003fffff, FALSE),
+ HOWTO(R_SPARC_GOTDATA_LOX10,0,2,0,FALSE,0,complain_overflow_dont, sparc_elf_lox10_reloc, "R_SPARC_GOTDATA_LOX10",FALSE,0,0x000003ff, FALSE),
+ HOWTO(R_SPARC_GOTDATA_OP_HIX22,0,2,0,FALSE,0,complain_overflow_bitfield,sparc_elf_hix22_reloc,"R_SPARC_GOTDATA_OP_HIX22",FALSE,0,0x003fffff, FALSE),
+ HOWTO(R_SPARC_GOTDATA_OP_LOX10,0,2,0,FALSE,0,complain_overflow_dont, sparc_elf_lox10_reloc, "R_SPARC_GOTDATA_OP_LOX10",FALSE,0,0x000003ff, FALSE),
+ HOWTO(R_SPARC_GOTDATA_OP,0,0, 0,FALSE,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_GOTDATA_OP",FALSE,0,0x00000000,TRUE),
+ HOWTO(R_SPARC_H34,12,2,22,FALSE,0,complain_overflow_unsigned,bfd_elf_generic_reloc,"R_SPARC_H34",FALSE,0,0x003fffff,FALSE),
+ HOWTO(R_SPARC_SIZE32,0,2,32,FALSE,0,complain_overflow_bitfield,bfd_elf_generic_reloc,"R_SPARC_SIZE32",FALSE,0,0xffffffff,TRUE),
+ HOWTO(R_SPARC_SIZE64,0,4,64,FALSE,0,complain_overflow_bitfield,bfd_elf_generic_reloc,"R_SPARC_SIZE64",FALSE,0,MINUS_ONE, TRUE),
+ HOWTO(R_SPARC_WDISP10,2,2,10,TRUE, 0,complain_overflow_signed,sparc_elf_wdisp10_reloc,"R_SPARC_WDISP10",FALSE,0,0x00000000,TRUE),
+};
+static reloc_howto_type sparc_jmp_irel_howto =
+ HOWTO(R_SPARC_JMP_IREL, 0,0,00,FALSE,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_JMP_IREL",FALSE,0,0x00000000,TRUE);
+static reloc_howto_type sparc_irelative_howto =
+ HOWTO(R_SPARC_IRELATIVE, 0,0,00,FALSE,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_IRELATIVE",FALSE,0,0x00000000,TRUE);
+static reloc_howto_type 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 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);
+static reloc_howto_type sparc_rev32_howto =
+ HOWTO(R_SPARC_REV32, 0,2,32,FALSE,0,complain_overflow_bitfield,bfd_elf_generic_reloc, "R_SPARC_REV32", FALSE,0,0xffffffff,TRUE);
+
+reloc_howto_type *
+_bfd_sparc_elf_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ bfd_reloc_code_real_type code)
+{
+ /* We explicitly handle each relocation type in the switch
+ instead of using a lookup table for efficiency. */
+ switch (code)
+ {
+ case BFD_RELOC_NONE:
+ return &_bfd_sparc_elf_howto_table[R_SPARC_NONE];
+
+ case BFD_RELOC_8:
+ return &_bfd_sparc_elf_howto_table[R_SPARC_8];
+
+ case BFD_RELOC_16:
+ return &_bfd_sparc_elf_howto_table[R_SPARC_16];
+
+ case BFD_RELOC_32:
+ return &_bfd_sparc_elf_howto_table[R_SPARC_32];
+
+ case BFD_RELOC_8_PCREL:
+ return &_bfd_sparc_elf_howto_table[R_SPARC_DISP8];
+
+ case BFD_RELOC_16_PCREL:
+ return &_bfd_sparc_elf_howto_table[R_SPARC_DISP16];
+
+ case BFD_RELOC_32_PCREL:
+ return &_bfd_sparc_elf_howto_table[R_SPARC_DISP32];
+
+ case BFD_RELOC_32_PCREL_S2:
+ return &_bfd_sparc_elf_howto_table[R_SPARC_WDISP30];
+
+ case BFD_RELOC_SPARC_WDISP22:
+ return &_bfd_sparc_elf_howto_table[R_SPARC_WDISP22];
+
+ case BFD_RELOC_HI22:
+ return &_bfd_sparc_elf_howto_table[R_SPARC_HI22];
+
+ case BFD_RELOC_SPARC22:
+ return &_bfd_sparc_elf_howto_table[R_SPARC_22];
+
+ case BFD_RELOC_SPARC13:
+ return &_bfd_sparc_elf_howto_table[R_SPARC_13];
+
+ case BFD_RELOC_LO10:
+ return &_bfd_sparc_elf_howto_table[R_SPARC_LO10];
+
+ case BFD_RELOC_SPARC_GOT10:
+ return &_bfd_sparc_elf_howto_table[R_SPARC_GOT10];
+
+ case BFD_RELOC_SPARC_GOT13:
+ return &_bfd_sparc_elf_howto_table[R_SPARC_GOT13];
+
+ case BFD_RELOC_SPARC_GOT22:
+ return &_bfd_sparc_elf_howto_table[R_SPARC_GOT22];
+
+ case BFD_RELOC_SPARC_PC10:
+ return &_bfd_sparc_elf_howto_table[R_SPARC_PC10];
+
+ case BFD_RELOC_SPARC_PC22:
+ return &_bfd_sparc_elf_howto_table[R_SPARC_PC22];
+
+ case BFD_RELOC_SPARC_WPLT30:
+ return &_bfd_sparc_elf_howto_table[R_SPARC_WPLT30];
+
+ case BFD_RELOC_SPARC_COPY:
+ return &_bfd_sparc_elf_howto_table[R_SPARC_COPY];
+
+ case BFD_RELOC_SPARC_GLOB_DAT:
+ return &_bfd_sparc_elf_howto_table[R_SPARC_GLOB_DAT];
+
+ case BFD_RELOC_SPARC_JMP_SLOT:
+ return &_bfd_sparc_elf_howto_table[R_SPARC_JMP_SLOT];
+
+ case BFD_RELOC_SPARC_RELATIVE:
+ return &_bfd_sparc_elf_howto_table[R_SPARC_RELATIVE];
+
+ case BFD_RELOC_SPARC_UA32:
+ return &_bfd_sparc_elf_howto_table[R_SPARC_UA32];
+
+ case BFD_RELOC_SPARC_PLT32:
+ return &_bfd_sparc_elf_howto_table[R_SPARC_PLT32];
+
+ case BFD_RELOC_SPARC_10:
+ return &_bfd_sparc_elf_howto_table[R_SPARC_10];
+
+ case BFD_RELOC_SPARC_11:
+ return &_bfd_sparc_elf_howto_table[R_SPARC_11];
+
+ case BFD_RELOC_SPARC_64:
+ return &_bfd_sparc_elf_howto_table[R_SPARC_64];
+
+ case BFD_RELOC_SPARC_OLO10:
+ return &_bfd_sparc_elf_howto_table[R_SPARC_OLO10];
+
+ case BFD_RELOC_SPARC_HH22:
+ return &_bfd_sparc_elf_howto_table[R_SPARC_HH22];
+
+ case BFD_RELOC_SPARC_HM10:
+ return &_bfd_sparc_elf_howto_table[R_SPARC_HM10];
+
+ case BFD_RELOC_SPARC_LM22:
+ return &_bfd_sparc_elf_howto_table[R_SPARC_LM22];
+
+ case BFD_RELOC_SPARC_PC_HH22:
+ return &_bfd_sparc_elf_howto_table[R_SPARC_PC_HH22];
+
+ case BFD_RELOC_SPARC_PC_HM10:
+ return &_bfd_sparc_elf_howto_table[R_SPARC_PC_HM10];
+
+ case BFD_RELOC_SPARC_PC_LM22:
+ return &_bfd_sparc_elf_howto_table[R_SPARC_PC_LM22];
+
+ case BFD_RELOC_SPARC_WDISP16:
+ return &_bfd_sparc_elf_howto_table[R_SPARC_WDISP16];
+
+ case BFD_RELOC_SPARC_WDISP19:
+ return &_bfd_sparc_elf_howto_table[R_SPARC_WDISP19];
+
+ case BFD_RELOC_SPARC_7:
+ return &_bfd_sparc_elf_howto_table[R_SPARC_7];
+
+ case BFD_RELOC_SPARC_5:
+ return &_bfd_sparc_elf_howto_table[R_SPARC_5];
+
+ case BFD_RELOC_SPARC_6:
+ return &_bfd_sparc_elf_howto_table[R_SPARC_6];
+
+ case BFD_RELOC_SPARC_DISP64:
+ return &_bfd_sparc_elf_howto_table[R_SPARC_DISP64];
+
+ case BFD_RELOC_SPARC_PLT64:
+ return &_bfd_sparc_elf_howto_table[R_SPARC_PLT64];
+
+ case BFD_RELOC_SPARC_HIX22:
+ return &_bfd_sparc_elf_howto_table[R_SPARC_HIX22];
+
+ case BFD_RELOC_SPARC_LOX10:
+ return &_bfd_sparc_elf_howto_table[R_SPARC_LOX10];
+
+ case BFD_RELOC_SPARC_H44:
+ return &_bfd_sparc_elf_howto_table[R_SPARC_H44];
+
+ case BFD_RELOC_SPARC_M44:
+ return &_bfd_sparc_elf_howto_table[R_SPARC_M44];
+
+ case BFD_RELOC_SPARC_L44:
+ return &_bfd_sparc_elf_howto_table[R_SPARC_L44];
+
+ case BFD_RELOC_SPARC_REGISTER:
+ return &_bfd_sparc_elf_howto_table[R_SPARC_REGISTER];
+
+ case BFD_RELOC_SPARC_UA64:
+ return &_bfd_sparc_elf_howto_table[R_SPARC_UA64];
+
+ case BFD_RELOC_SPARC_UA16:
+ return &_bfd_sparc_elf_howto_table[R_SPARC_UA16];
+
+ case BFD_RELOC_SPARC_TLS_GD_HI22:
+ return &_bfd_sparc_elf_howto_table[R_SPARC_TLS_GD_HI22];
+
+ case BFD_RELOC_SPARC_TLS_GD_LO10:
+ return &_bfd_sparc_elf_howto_table[R_SPARC_TLS_GD_LO10];
+
+ case BFD_RELOC_SPARC_TLS_GD_ADD:
+ return &_bfd_sparc_elf_howto_table[R_SPARC_TLS_GD_ADD];
+
+ case BFD_RELOC_SPARC_TLS_GD_CALL:
+ return &_bfd_sparc_elf_howto_table[R_SPARC_TLS_GD_CALL];
+
+ case BFD_RELOC_SPARC_TLS_LDM_HI22:
+ return &_bfd_sparc_elf_howto_table[R_SPARC_TLS_LDM_HI22];
+
+ case BFD_RELOC_SPARC_TLS_LDM_LO10:
+ return &_bfd_sparc_elf_howto_table[R_SPARC_TLS_LDM_LO10];
+
+ case BFD_RELOC_SPARC_TLS_LDM_ADD:
+ return &_bfd_sparc_elf_howto_table[R_SPARC_TLS_LDM_ADD];
+
+ case BFD_RELOC_SPARC_TLS_LDM_CALL:
+ return &_bfd_sparc_elf_howto_table[R_SPARC_TLS_LDM_CALL];
+
+ case BFD_RELOC_SPARC_TLS_LDO_HIX22:
+ return &_bfd_sparc_elf_howto_table[R_SPARC_TLS_LDO_HIX22];
+
+ case BFD_RELOC_SPARC_TLS_LDO_LOX10:
+ return &_bfd_sparc_elf_howto_table[R_SPARC_TLS_LDO_LOX10];
+
+ case BFD_RELOC_SPARC_TLS_LDO_ADD:
+ return &_bfd_sparc_elf_howto_table[R_SPARC_TLS_LDO_ADD];
+
+ case BFD_RELOC_SPARC_TLS_IE_HI22:
+ return &_bfd_sparc_elf_howto_table[R_SPARC_TLS_IE_HI22];
+
+ case BFD_RELOC_SPARC_TLS_IE_LO10:
+ return &_bfd_sparc_elf_howto_table[R_SPARC_TLS_IE_LO10];
+
+ case BFD_RELOC_SPARC_TLS_IE_LD:
+ return &_bfd_sparc_elf_howto_table[R_SPARC_TLS_IE_LD];
+
+ case BFD_RELOC_SPARC_TLS_IE_LDX:
+ return &_bfd_sparc_elf_howto_table[R_SPARC_TLS_IE_LDX];
+
+ case BFD_RELOC_SPARC_TLS_IE_ADD:
+ return &_bfd_sparc_elf_howto_table[R_SPARC_TLS_IE_ADD];
+
+ case BFD_RELOC_SPARC_TLS_LE_HIX22:
+ return &_bfd_sparc_elf_howto_table[R_SPARC_TLS_LE_HIX22];
+
+ case BFD_RELOC_SPARC_TLS_LE_LOX10:
+ return &_bfd_sparc_elf_howto_table[R_SPARC_TLS_LE_LOX10];
+
+ case BFD_RELOC_SPARC_TLS_DTPMOD32:
+ return &_bfd_sparc_elf_howto_table[R_SPARC_TLS_DTPMOD32];
+
+ case BFD_RELOC_SPARC_TLS_DTPMOD64:
+ return &_bfd_sparc_elf_howto_table[R_SPARC_TLS_DTPMOD64];
+
+ case BFD_RELOC_SPARC_TLS_DTPOFF32:
+ return &_bfd_sparc_elf_howto_table[R_SPARC_TLS_DTPOFF32];
+
+ case BFD_RELOC_SPARC_TLS_DTPOFF64:
+ return &_bfd_sparc_elf_howto_table[R_SPARC_TLS_DTPOFF64];
+
+ case BFD_RELOC_SPARC_TLS_TPOFF32:
+ return &_bfd_sparc_elf_howto_table[R_SPARC_TLS_TPOFF32];
+
+ case BFD_RELOC_SPARC_TLS_TPOFF64:
+ return &_bfd_sparc_elf_howto_table[R_SPARC_TLS_TPOFF64];
+
+ case BFD_RELOC_SPARC_GOTDATA_HIX22:
+ return &_bfd_sparc_elf_howto_table[R_SPARC_GOTDATA_HIX22];
+
+ case BFD_RELOC_SPARC_GOTDATA_LOX10:
+ return &_bfd_sparc_elf_howto_table[R_SPARC_GOTDATA_LOX10];
+
+ case BFD_RELOC_SPARC_GOTDATA_OP_HIX22:
+ return &_bfd_sparc_elf_howto_table[R_SPARC_GOTDATA_OP_HIX22];
+
+ case BFD_RELOC_SPARC_GOTDATA_OP_LOX10:
+ return &_bfd_sparc_elf_howto_table[R_SPARC_GOTDATA_OP_LOX10];
+
+ case BFD_RELOC_SPARC_GOTDATA_OP:
+ return &_bfd_sparc_elf_howto_table[R_SPARC_GOTDATA_OP];
+
+ case BFD_RELOC_SPARC_H34:
+ return &_bfd_sparc_elf_howto_table[R_SPARC_H34];
+
+ case BFD_RELOC_SPARC_SIZE32:
+ return &_bfd_sparc_elf_howto_table[R_SPARC_SIZE32];
+
+ case BFD_RELOC_SPARC_SIZE64:
+ return &_bfd_sparc_elf_howto_table[R_SPARC_SIZE64];
+
+ case BFD_RELOC_SPARC_WDISP10:
+ return &_bfd_sparc_elf_howto_table[R_SPARC_WDISP10];
+
+ case BFD_RELOC_SPARC_JMP_IREL:
+ return &sparc_jmp_irel_howto;
+
+ case BFD_RELOC_SPARC_IRELATIVE:
+ return &sparc_irelative_howto;
+
+ case BFD_RELOC_VTABLE_INHERIT:
+ return &sparc_vtinherit_howto;
+
+ case BFD_RELOC_VTABLE_ENTRY:
+ return &sparc_vtentry_howto;
+
+ case BFD_RELOC_SPARC_REV32:
+ return &sparc_rev32_howto;
+
+ default:
+ break;
+ }
+ bfd_set_error (bfd_error_bad_value);
+ return NULL;
+}
+
+reloc_howto_type *
+_bfd_sparc_elf_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ const char *r_name)
+{
+ unsigned int i;
+
+ for (i = 0;
+ i < (sizeof (_bfd_sparc_elf_howto_table)
+ / sizeof (_bfd_sparc_elf_howto_table[0]));
+ i++)
+ if (_bfd_sparc_elf_howto_table[i].name != NULL
+ && strcasecmp (_bfd_sparc_elf_howto_table[i].name, r_name) == 0)
+ return &_bfd_sparc_elf_howto_table[i];
+
+ if (strcasecmp (sparc_vtinherit_howto.name, r_name) == 0)
+ return &sparc_vtinherit_howto;
+ if (strcasecmp (sparc_vtentry_howto.name, r_name) == 0)
+ return &sparc_vtentry_howto;
+ if (strcasecmp (sparc_rev32_howto.name, r_name) == 0)
+ return &sparc_rev32_howto;
+
+ return NULL;
+}
+
+reloc_howto_type *
+_bfd_sparc_elf_info_to_howto_ptr (unsigned int r_type)
+{
+ switch (r_type)
+ {
+ case R_SPARC_JMP_IREL:
+ return &sparc_jmp_irel_howto;
+
+ case R_SPARC_IRELATIVE:
+ return &sparc_irelative_howto;
+
+ case R_SPARC_GNU_VTINHERIT:
+ return &sparc_vtinherit_howto;
+
+ case R_SPARC_GNU_VTENTRY:
+ return &sparc_vtentry_howto;
+
+ case R_SPARC_REV32:
+ return &sparc_rev32_howto;
+
+ default:
+ if (r_type >= (unsigned int) R_SPARC_max_std)
+ {
+ (*_bfd_error_handler) (_("invalid relocation type %d"),
+ (int) r_type);
+ r_type = R_SPARC_NONE;
+ }
+ return &_bfd_sparc_elf_howto_table[r_type];
+ }
+}
+
+/* Both 32-bit and 64-bit sparc encode this in an identical manner,
+ so just take advantage of that. */
+#define SPARC_ELF_R_TYPE(r_info) \
+ ((r_info) & 0xff)
+
+void
+_bfd_sparc_elf_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED, arelent *cache_ptr,
+ Elf_Internal_Rela *dst)
+{
+ unsigned int r_type = SPARC_ELF_R_TYPE (dst->r_info);
+
+ cache_ptr->howto = _bfd_sparc_elf_info_to_howto_ptr (r_type);
+}
+
+
+/* The nop opcode we use. */
+#define SPARC_NOP 0x01000000
+
+#define SPARC_INSN_BYTES 4
+
+/* The SPARC linker needs to keep track of the number of relocs that it
+ decides to copy as dynamic relocs in check_relocs for each symbol.
+ This is so that it can later discard them if they are found to be
+ unnecessary. We store the information in a field extending the
+ regular ELF linker hash table. */
+
+struct _bfd_sparc_elf_dyn_relocs
+{
+ struct _bfd_sparc_elf_dyn_relocs *next;
+
+ /* The input section of the reloc. */
+ asection *sec;
+
+ /* Total number of relocs copied for the input section. */
+ bfd_size_type count;
+
+ /* Number of pc-relative relocs copied for the input section. */
+ bfd_size_type pc_count;
+};
+
+/* SPARC ELF linker hash entry. */
+
+struct _bfd_sparc_elf_link_hash_entry
+{
+ struct elf_link_hash_entry elf;
+
+ /* Track dynamic relocs copied for this symbol. */
+ struct _bfd_sparc_elf_dyn_relocs *dyn_relocs;
+
+#define GOT_UNKNOWN 0
+#define GOT_NORMAL 1
+#define GOT_TLS_GD 2
+#define GOT_TLS_IE 3
+ unsigned char tls_type;
+};
+
+#define _bfd_sparc_elf_hash_entry(ent) ((struct _bfd_sparc_elf_link_hash_entry *)(ent))
+
+struct _bfd_sparc_elf_obj_tdata
+{
+ struct elf_obj_tdata root;
+
+ /* tls_type for each local got entry. */
+ char *local_got_tls_type;
+
+ /* TRUE if TLS GD relocs has been seen for this object. */
+ bfd_boolean has_tlsgd;
+};
+
+#define _bfd_sparc_elf_tdata(abfd) \
+ ((struct _bfd_sparc_elf_obj_tdata *) (abfd)->tdata.any)
+
+#define _bfd_sparc_elf_local_got_tls_type(abfd) \
+ (_bfd_sparc_elf_tdata (abfd)->local_got_tls_type)
+
+#define is_sparc_elf(bfd) \
+ (bfd_get_flavour (bfd) == bfd_target_elf_flavour \
+ && elf_tdata (bfd) != NULL \
+ && elf_object_id (bfd) == SPARC_ELF_DATA)
+
+bfd_boolean
+_bfd_sparc_elf_mkobject (bfd *abfd)
+{
+ return bfd_elf_allocate_object (abfd, sizeof (struct _bfd_sparc_elf_obj_tdata),
+ SPARC_ELF_DATA);
+}
+
+static void
+sparc_put_word_32 (bfd *abfd, bfd_vma val, void *ptr)
+{
+ bfd_put_32 (abfd, val, ptr);
+}
+
+static void
+sparc_put_word_64 (bfd *abfd, bfd_vma val, void *ptr)
+{
+ bfd_put_64 (abfd, val, ptr);
+}
+
+static void
+sparc_elf_append_rela (bfd *abfd, asection *s, Elf_Internal_Rela *rel)
+{
+ const struct elf_backend_data *bed;
+ bfd_byte *loc;
+
+ bed = get_elf_backend_data (abfd);
+ loc = s->contents + (s->reloc_count++ * bed->s->sizeof_rela);
+ bed->s->swap_reloca_out (abfd, rel, loc);
+}
+
+static bfd_vma
+sparc_elf_r_info_64 (Elf_Internal_Rela *in_rel ATTRIBUTE_UNUSED,
+ bfd_vma rel_index ATTRIBUTE_UNUSED,
+ bfd_vma type ATTRIBUTE_UNUSED)
+{
+ return ELF64_R_INFO (rel_index,
+ (in_rel ?
+ ELF64_R_TYPE_INFO (ELF64_R_TYPE_DATA (in_rel->r_info),
+ type) : type));
+}
+
+static bfd_vma
+sparc_elf_r_info_32 (Elf_Internal_Rela *in_rel ATTRIBUTE_UNUSED,
+ bfd_vma rel_index, bfd_vma type)
+{
+ return ELF32_R_INFO (rel_index, type);
+}
+
+static bfd_vma
+sparc_elf_r_symndx_64 (bfd_vma r_info)
+{
+ bfd_vma r_symndx = ELF32_R_SYM (r_info);
+ return (r_symndx >> 24);
+}
+
+static bfd_vma
+sparc_elf_r_symndx_32 (bfd_vma r_info)
+{
+ return ELF32_R_SYM (r_info);
+}
+
+/* PLT/GOT stuff */
+
+#define PLT32_ENTRY_SIZE 12
+#define PLT32_HEADER_SIZE (4 * PLT32_ENTRY_SIZE)
+
+/* The first four entries in a 32-bit 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 PLT32_ENTRY_WORD0 0x03000000
+/* b,a .plt0. We fill in the offset later. */
+#define PLT32_ENTRY_WORD1 0x30800000
+/* nop. */
+#define PLT32_ENTRY_WORD2 SPARC_NOP
+
+static int
+sparc32_plt_entry_build (bfd *output_bfd, asection *splt, bfd_vma offset,
+ bfd_vma max ATTRIBUTE_UNUSED,
+ bfd_vma *r_offset)
+{
+ bfd_put_32 (output_bfd,
+ PLT32_ENTRY_WORD0 + offset,
+ splt->contents + offset);
+ bfd_put_32 (output_bfd,
+ (PLT32_ENTRY_WORD1
+ + (((- (offset + 4)) >> 2) & 0x3fffff)),
+ splt->contents + offset + 4);
+ bfd_put_32 (output_bfd, (bfd_vma) PLT32_ENTRY_WORD2,
+ splt->contents + offset + 8);
+
+ *r_offset = offset;
+
+ return offset / PLT32_ENTRY_SIZE - 4;
+}
+
+/* Both the headers and the entries are icache aligned. */
+#define PLT64_ENTRY_SIZE 32
+#define PLT64_HEADER_SIZE (4 * PLT64_ENTRY_SIZE)
+#define PLT64_LARGE_THRESHOLD 32768
+
+static int
+sparc64_plt_entry_build (bfd *output_bfd, asection *splt, bfd_vma offset,
+ bfd_vma max, bfd_vma *r_offset)
+{
+ unsigned char *entry = splt->contents + offset;
+ const unsigned int nop = SPARC_NOP;
+ int plt_index;
+
+ if (offset < (PLT64_LARGE_THRESHOLD * PLT64_ENTRY_SIZE))
+ {
+ unsigned int sethi, ba;
+
+ *r_offset = offset;
+
+ plt_index = (offset / PLT64_ENTRY_SIZE);
+
+ sethi = 0x03000000 | (plt_index * PLT64_ENTRY_SIZE);
+ ba = 0x30680000
+ | (((splt->contents + PLT64_ENTRY_SIZE) - (entry + 4)) / 4 & 0x7ffff);
+
+ bfd_put_32 (output_bfd, (bfd_vma) sethi, entry);
+ bfd_put_32 (output_bfd, (bfd_vma) ba, entry + 4);
+ bfd_put_32 (output_bfd, (bfd_vma) nop, entry + 8);
+ bfd_put_32 (output_bfd, (bfd_vma) nop, entry + 12);
+ bfd_put_32 (output_bfd, (bfd_vma) nop, entry + 16);
+ bfd_put_32 (output_bfd, (bfd_vma) nop, entry + 20);
+ bfd_put_32 (output_bfd, (bfd_vma) nop, entry + 24);
+ bfd_put_32 (output_bfd, (bfd_vma) nop, entry + 28);
+ }
+ else
+ {
+ unsigned char *ptr;
+ unsigned int ldx;
+ int block, last_block, ofs, last_ofs, chunks_this_block;
+ const int insn_chunk_size = (6 * 4);
+ const int ptr_chunk_size = (1 * 8);
+ const int entries_per_block = 160;
+ const int block_size = entries_per_block * (insn_chunk_size
+ + ptr_chunk_size);
+
+ /* Entries 32768 and higher are grouped into blocks of 160.
+ The blocks are further subdivided into 160 sequences of
+ 6 instructions and 160 pointers. If a block does not require
+ the full 160 entries, let's say it requires N, then there
+ will be N sequences of 6 instructions and N pointers. */
+
+ offset -= (PLT64_LARGE_THRESHOLD * PLT64_ENTRY_SIZE);
+ max -= (PLT64_LARGE_THRESHOLD * PLT64_ENTRY_SIZE);
+
+ block = offset / block_size;
+ last_block = max / block_size;
+ if (block != last_block)
+ {
+ chunks_this_block = 160;
+ }
+ else
+ {
+ last_ofs = max % block_size;
+ chunks_this_block = last_ofs / (insn_chunk_size + ptr_chunk_size);
+ }
+
+ ofs = offset % block_size;
+
+ plt_index = (PLT64_LARGE_THRESHOLD +
+ (block * 160) +
+ (ofs / insn_chunk_size));
+
+ ptr = splt->contents
+ + (PLT64_LARGE_THRESHOLD * PLT64_ENTRY_SIZE)
+ + (block * block_size)
+ + (chunks_this_block * insn_chunk_size)
+ + (ofs / insn_chunk_size) * ptr_chunk_size;
+
+ *r_offset = (bfd_vma) (ptr - splt->contents);
+
+ ldx = 0xc25be000 | ((ptr - (entry+4)) & 0x1fff);
+
+ /* mov %o7,%g5
+ call .+8
+ nop
+ ldx [%o7+P],%g1
+ jmpl %o7+%g1,%g1
+ mov %g5,%o7 */
+ bfd_put_32 (output_bfd, (bfd_vma) 0x8a10000f, entry);
+ bfd_put_32 (output_bfd, (bfd_vma) 0x40000002, entry + 4);
+ bfd_put_32 (output_bfd, (bfd_vma) SPARC_NOP, entry + 8);
+ bfd_put_32 (output_bfd, (bfd_vma) ldx, entry + 12);
+ bfd_put_32 (output_bfd, (bfd_vma) 0x83c3c001, entry + 16);
+ bfd_put_32 (output_bfd, (bfd_vma) 0x9e100005, entry + 20);
+
+ bfd_put_64 (output_bfd, (bfd_vma) (splt->contents - (entry + 4)), ptr);
+ }
+
+ return plt_index - 4;
+}
+
+/* The format of the first PLT entry in a VxWorks executable. */
+static const bfd_vma sparc_vxworks_exec_plt0_entry[] =
+ {
+ 0x05000000, /* sethi %hi(_GLOBAL_OFFSET_TABLE_+8), %g2 */
+ 0x8410a000, /* or %g2, %lo(_GLOBAL_OFFSET_TABLE_+8), %g2 */
+ 0xc4008000, /* ld [ %g2 ], %g2 */
+ 0x81c08000, /* jmp %g2 */
+ 0x01000000 /* nop */
+ };
+
+/* The format of subsequent PLT entries. */
+static const bfd_vma sparc_vxworks_exec_plt_entry[] =
+ {
+ 0x03000000, /* sethi %hi(_GLOBAL_OFFSET_TABLE_+f@got), %g1 */
+ 0x82106000, /* or %g1, %lo(_GLOBAL_OFFSET_TABLE_+f@got), %g1 */
+ 0xc2004000, /* ld [ %g1 ], %g1 */
+ 0x81c04000, /* jmp %g1 */
+ 0x01000000, /* nop */
+ 0x03000000, /* sethi %hi(f@pltindex), %g1 */
+ 0x10800000, /* b _PLT_resolve */
+ 0x82106000 /* or %g1, %lo(f@pltindex), %g1 */
+ };
+
+/* The format of the first PLT entry in a VxWorks shared object. */
+static const bfd_vma sparc_vxworks_shared_plt0_entry[] =
+ {
+ 0xc405e008, /* ld [ %l7 + 8 ], %g2 */
+ 0x81c08000, /* jmp %g2 */
+ 0x01000000 /* nop */
+ };
+
+/* The format of subsequent PLT entries. */
+static const bfd_vma sparc_vxworks_shared_plt_entry[] =
+ {
+ 0x03000000, /* sethi %hi(f@got), %g1 */
+ 0x82106000, /* or %g1, %lo(f@got), %g1 */
+ 0xc205c001, /* ld [ %l7 + %g1 ], %g1 */
+ 0x81c04000, /* jmp %g1 */
+ 0x01000000, /* nop */
+ 0x03000000, /* sethi %hi(f@pltindex), %g1 */
+ 0x10800000, /* b _PLT_resolve */
+ 0x82106000 /* or %g1, %lo(f@pltindex), %g1 */
+ };
+
+#define SPARC_ELF_PUT_WORD(htab, bfd, val, ptr) \
+ htab->put_word(bfd, val, ptr)
+
+#define SPARC_ELF_R_INFO(htab, in_rel, index, type) \
+ htab->r_info(in_rel, index, type)
+
+#define SPARC_ELF_R_SYMNDX(htab, r_info) \
+ htab->r_symndx(r_info)
+
+#define SPARC_ELF_WORD_BYTES(htab) \
+ htab->bytes_per_word
+
+#define SPARC_ELF_RELA_BYTES(htab) \
+ htab->bytes_per_rela
+
+#define SPARC_ELF_DTPOFF_RELOC(htab) \
+ htab->dtpoff_reloc
+
+#define SPARC_ELF_DTPMOD_RELOC(htab) \
+ htab->dtpmod_reloc
+
+#define SPARC_ELF_TPOFF_RELOC(htab) \
+ htab->tpoff_reloc
+
+#define SPARC_ELF_BUILD_PLT_ENTRY(htab, obfd, splt, off, max, r_off) \
+ htab->build_plt_entry (obfd, splt, off, max, r_off)
+
+/* Create an entry in an SPARC ELF linker hash table. */
+
+static struct bfd_hash_entry *
+link_hash_newfunc (struct bfd_hash_entry *entry,
+ struct bfd_hash_table *table, const char *string)
+{
+ /* Allocate the structure if it has not already been allocated by a
+ subclass. */
+ if (entry == NULL)
+ {
+ entry = bfd_hash_allocate (table,
+ sizeof (struct _bfd_sparc_elf_link_hash_entry));
+ if (entry == NULL)
+ return entry;
+ }
+
+ /* Call the allocation method of the superclass. */
+ entry = _bfd_elf_link_hash_newfunc (entry, table, string);
+ if (entry != NULL)
+ {
+ struct _bfd_sparc_elf_link_hash_entry *eh;
+
+ eh = (struct _bfd_sparc_elf_link_hash_entry *) entry;
+ eh->dyn_relocs = NULL;
+ eh->tls_type = GOT_UNKNOWN;
+ }
+
+ return entry;
+}
+
+/* The name of the dynamic interpreter. This is put in the .interp
+ section. */
+
+#define ELF32_DYNAMIC_INTERPRETER "/usr/lib/ld.so.1"
+#define ELF64_DYNAMIC_INTERPRETER "/usr/lib/sparcv9/ld.so.1"
+
+/* Compute a hash of a local hash entry. We use elf_link_hash_entry
+ for local symbol so that we can handle local STT_GNU_IFUNC symbols
+ as global symbol. We reuse indx and dynstr_index for local symbol
+ hash since they aren't used by global symbols in this backend. */
+
+static hashval_t
+elf_sparc_local_htab_hash (const void *ptr)
+{
+ struct elf_link_hash_entry *h
+ = (struct elf_link_hash_entry *) ptr;
+ return ELF_LOCAL_SYMBOL_HASH (h->indx, h->dynstr_index);
+}
+
+/* Compare local hash entries. */
+
+static int
+elf_sparc_local_htab_eq (const void *ptr1, const void *ptr2)
+{
+ struct elf_link_hash_entry *h1
+ = (struct elf_link_hash_entry *) ptr1;
+ struct elf_link_hash_entry *h2
+ = (struct elf_link_hash_entry *) ptr2;
+
+ return h1->indx == h2->indx && h1->dynstr_index == h2->dynstr_index;
+}
+
+/* Find and/or create a hash entry for local symbol. */
+
+static struct elf_link_hash_entry *
+elf_sparc_get_local_sym_hash (struct _bfd_sparc_elf_link_hash_table *htab,
+ bfd *abfd, const Elf_Internal_Rela *rel,
+ bfd_boolean create)
+{
+ struct _bfd_sparc_elf_link_hash_entry e, *ret;
+ asection *sec = abfd->sections;
+ unsigned long r_symndx;
+ hashval_t h;
+ void **slot;
+
+ r_symndx = SPARC_ELF_R_SYMNDX (htab, rel->r_info);
+ h = ELF_LOCAL_SYMBOL_HASH (sec->id, r_symndx);
+
+ e.elf.indx = sec->id;
+ e.elf.dynstr_index = r_symndx;
+ slot = htab_find_slot_with_hash (htab->loc_hash_table, &e, h,
+ create ? INSERT : NO_INSERT);
+
+ if (!slot)
+ return NULL;
+
+ if (*slot)
+ {
+ ret = (struct _bfd_sparc_elf_link_hash_entry *) *slot;
+ return &ret->elf;
+ }
+
+ ret = (struct _bfd_sparc_elf_link_hash_entry *)
+ objalloc_alloc ((struct objalloc *) htab->loc_hash_memory,
+ sizeof (struct _bfd_sparc_elf_link_hash_entry));
+ if (ret)
+ {
+ memset (ret, 0, sizeof (*ret));
+ ret->elf.indx = sec->id;
+ ret->elf.dynstr_index = r_symndx;
+ ret->elf.dynindx = -1;
+ ret->elf.plt.offset = (bfd_vma) -1;
+ ret->elf.got.offset = (bfd_vma) -1;
+ *slot = ret;
+ }
+ return &ret->elf;
+}
+
+/* Destroy a SPARC ELF linker hash table. */
+
+static void
+_bfd_sparc_elf_link_hash_table_free (bfd *obfd)
+{
+ struct _bfd_sparc_elf_link_hash_table *htab
+ = (struct _bfd_sparc_elf_link_hash_table *) obfd->link.hash;
+
+ if (htab->loc_hash_table)
+ htab_delete (htab->loc_hash_table);
+ if (htab->loc_hash_memory)
+ objalloc_free ((struct objalloc *) htab->loc_hash_memory);
+ _bfd_elf_link_hash_table_free (obfd);
+}
+
+/* Create a SPARC ELF linker hash table. */
+
+struct bfd_link_hash_table *
+_bfd_sparc_elf_link_hash_table_create (bfd *abfd)
+{
+ struct _bfd_sparc_elf_link_hash_table *ret;
+ bfd_size_type amt = sizeof (struct _bfd_sparc_elf_link_hash_table);
+
+ ret = (struct _bfd_sparc_elf_link_hash_table *) bfd_zmalloc (amt);
+ if (ret == NULL)
+ return NULL;
+
+ if (ABI_64_P (abfd))
+ {
+ ret->put_word = sparc_put_word_64;
+ ret->r_info = sparc_elf_r_info_64;
+ ret->r_symndx = sparc_elf_r_symndx_64;
+ ret->dtpoff_reloc = R_SPARC_TLS_DTPOFF64;
+ ret->dtpmod_reloc = R_SPARC_TLS_DTPMOD64;
+ ret->tpoff_reloc = R_SPARC_TLS_TPOFF64;
+ ret->word_align_power = 3;
+ ret->align_power_max = 4;
+ ret->bytes_per_word = 8;
+ ret->bytes_per_rela = sizeof (Elf64_External_Rela);
+ ret->dynamic_interpreter = ELF64_DYNAMIC_INTERPRETER;
+ ret->dynamic_interpreter_size = sizeof ELF64_DYNAMIC_INTERPRETER;
+
+ ret->build_plt_entry = sparc64_plt_entry_build;
+ ret->plt_header_size = PLT64_HEADER_SIZE;
+ ret->plt_entry_size = PLT64_ENTRY_SIZE;
+ }
+ else
+ {
+ ret->put_word = sparc_put_word_32;
+ ret->r_info = sparc_elf_r_info_32;
+ ret->r_symndx = sparc_elf_r_symndx_32;
+ ret->dtpoff_reloc = R_SPARC_TLS_DTPOFF32;
+ ret->dtpmod_reloc = R_SPARC_TLS_DTPMOD32;
+ ret->tpoff_reloc = R_SPARC_TLS_TPOFF32;
+ ret->word_align_power = 2;
+ ret->align_power_max = 3;
+ ret->bytes_per_word = 4;
+ ret->bytes_per_rela = sizeof (Elf32_External_Rela);
+ ret->dynamic_interpreter = ELF32_DYNAMIC_INTERPRETER;
+ ret->dynamic_interpreter_size = sizeof ELF32_DYNAMIC_INTERPRETER;
+
+ ret->build_plt_entry = sparc32_plt_entry_build;
+ ret->plt_header_size = PLT32_HEADER_SIZE;
+ ret->plt_entry_size = PLT32_ENTRY_SIZE;
+ }
+
+ if (!_bfd_elf_link_hash_table_init (&ret->elf, abfd, link_hash_newfunc,
+ sizeof (struct _bfd_sparc_elf_link_hash_entry),
+ SPARC_ELF_DATA))
+ {
+ free (ret);
+ return NULL;
+ }
+
+ ret->loc_hash_table = htab_try_create (1024,
+ elf_sparc_local_htab_hash,
+ elf_sparc_local_htab_eq,
+ NULL);
+ ret->loc_hash_memory = objalloc_create ();
+ if (!ret->loc_hash_table || !ret->loc_hash_memory)
+ {
+ _bfd_sparc_elf_link_hash_table_free (abfd);
+ return NULL;
+ }
+ ret->elf.root.hash_table_free = _bfd_sparc_elf_link_hash_table_free;
+
+ return &ret->elf.root;
+}
+
+/* Create .plt, .rela.plt, .got, .rela.got, .dynbss, and
+ .rela.bss sections in DYNOBJ, and set up shortcuts to them in our
+ hash table. */
+
+bfd_boolean
+_bfd_sparc_elf_create_dynamic_sections (bfd *dynobj,
+ struct bfd_link_info *info)
+{
+ struct _bfd_sparc_elf_link_hash_table *htab;
+
+ htab = _bfd_sparc_elf_hash_table (info);
+ BFD_ASSERT (htab != NULL);
+
+ if (!_bfd_elf_create_dynamic_sections (dynobj, info))
+ return FALSE;
+
+ htab->sdynbss = bfd_get_linker_section (dynobj, ".dynbss");
+ if (!info->shared)
+ htab->srelbss = bfd_get_linker_section (dynobj, ".rela.bss");
+
+ if (htab->is_vxworks)
+ {
+ if (!elf_vxworks_create_dynamic_sections (dynobj, info, &htab->srelplt2))
+ return FALSE;
+ if (info->shared)
+ {
+ htab->plt_header_size
+ = 4 * ARRAY_SIZE (sparc_vxworks_shared_plt0_entry);
+ htab->plt_entry_size
+ = 4 * ARRAY_SIZE (sparc_vxworks_shared_plt_entry);
+ }
+ else
+ {
+ htab->plt_header_size
+ = 4 * ARRAY_SIZE (sparc_vxworks_exec_plt0_entry);
+ htab->plt_entry_size
+ = 4 * ARRAY_SIZE (sparc_vxworks_exec_plt_entry);
+ }
+ }
+
+ if (!htab->elf.splt || !htab->elf.srelplt || !htab->sdynbss
+ || (!info->shared && !htab->srelbss))
+ abort ();
+
+ return TRUE;
+}
+
+static bfd_boolean
+create_ifunc_sections (bfd *abfd, struct bfd_link_info *info)
+{
+ const struct elf_backend_data *bed = get_elf_backend_data (abfd);
+ struct elf_link_hash_table *htab = elf_hash_table (info);
+ flagword flags, pltflags;
+ asection *s;
+
+ if (htab->irelifunc != NULL || htab->iplt != NULL)
+ return TRUE;
+
+ flags = bed->dynamic_sec_flags;
+ pltflags = flags | SEC_ALLOC | SEC_CODE | SEC_LOAD;
+
+ s = bfd_make_section_with_flags (abfd, ".iplt", pltflags);
+ if (s == NULL
+ || ! bfd_set_section_alignment (abfd, s, bed->plt_alignment))
+ return FALSE;
+ htab->iplt = s;
+
+ s = bfd_make_section_with_flags (abfd, ".rela.iplt",
+ flags | SEC_READONLY);
+ if (s == NULL
+ || ! bfd_set_section_alignment (abfd, s,
+ bed->s->log_file_align))
+ return FALSE;
+ htab->irelplt = s;
+
+ return TRUE;
+}
+
+/* Copy the extra info we tack onto an elf_link_hash_entry. */
+
+void
+_bfd_sparc_elf_copy_indirect_symbol (struct bfd_link_info *info,
+ struct elf_link_hash_entry *dir,
+ struct elf_link_hash_entry *ind)
+{
+ struct _bfd_sparc_elf_link_hash_entry *edir, *eind;
+
+ edir = (struct _bfd_sparc_elf_link_hash_entry *) dir;
+ eind = (struct _bfd_sparc_elf_link_hash_entry *) ind;
+
+ if (eind->dyn_relocs != NULL)
+ {
+ if (edir->dyn_relocs != NULL)
+ {
+ struct _bfd_sparc_elf_dyn_relocs **pp;
+ struct _bfd_sparc_elf_dyn_relocs *p;
+
+ /* Add reloc counts against the indirect sym to the direct sym
+ list. Merge any entries against the same section. */
+ for (pp = &eind->dyn_relocs; (p = *pp) != NULL; )
+ {
+ struct _bfd_sparc_elf_dyn_relocs *q;
+
+ for (q = edir->dyn_relocs; q != NULL; q = q->next)
+ if (q->sec == p->sec)
+ {
+ q->pc_count += p->pc_count;
+ q->count += p->count;
+ *pp = p->next;
+ break;
+ }
+ if (q == NULL)
+ pp = &p->next;
+ }
+ *pp = edir->dyn_relocs;
+ }
+
+ edir->dyn_relocs = eind->dyn_relocs;
+ eind->dyn_relocs = NULL;
+ }
+
+ if (ind->root.type == bfd_link_hash_indirect
+ && dir->got.refcount <= 0)
+ {
+ edir->tls_type = eind->tls_type;
+ eind->tls_type = GOT_UNKNOWN;
+ }
+ _bfd_elf_link_hash_copy_indirect (info, dir, ind);
+}
+
+static int
+sparc_elf_tls_transition (struct bfd_link_info *info, bfd *abfd,
+ int r_type, int is_local)
+{
+ if (! ABI_64_P (abfd)
+ && r_type == R_SPARC_TLS_GD_HI22
+ && ! _bfd_sparc_elf_tdata (abfd)->has_tlsgd)
+ r_type = R_SPARC_REV32;
+
+ if (info->shared)
+ return r_type;
+
+ switch (r_type)
+ {
+ case R_SPARC_TLS_GD_HI22:
+ if (is_local)
+ return R_SPARC_TLS_LE_HIX22;
+ return R_SPARC_TLS_IE_HI22;
+ case R_SPARC_TLS_GD_LO10:
+ if (is_local)
+ return R_SPARC_TLS_LE_LOX10;
+ return R_SPARC_TLS_IE_LO10;
+ case R_SPARC_TLS_IE_HI22:
+ if (is_local)
+ return R_SPARC_TLS_LE_HIX22;
+ return r_type;
+ case R_SPARC_TLS_IE_LO10:
+ if (is_local)
+ return R_SPARC_TLS_LE_LOX10;
+ return r_type;
+ case R_SPARC_TLS_LDM_HI22:
+ return R_SPARC_TLS_LE_HIX22;
+ case R_SPARC_TLS_LDM_LO10:
+ return R_SPARC_TLS_LE_LOX10;
+ }
+
+ return 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. */
+
+bfd_boolean
+_bfd_sparc_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
+ asection *sec, const Elf_Internal_Rela *relocs)
+{
+ struct _bfd_sparc_elf_link_hash_table *htab;
+ 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;
+ int num_relocs;
+ bfd_boolean checked_tlsgd = FALSE;
+
+ if (info->relocatable)
+ return TRUE;
+
+ htab = _bfd_sparc_elf_hash_table (info);
+ BFD_ASSERT (htab != NULL);
+ symtab_hdr = &elf_symtab_hdr (abfd);
+ sym_hashes = elf_sym_hashes (abfd);
+
+ sreloc = NULL;
+
+ if (ABI_64_P (abfd))
+ num_relocs = NUM_SHDR_ENTRIES (_bfd_elf_single_rel_hdr (sec));
+ else
+ num_relocs = sec->reloc_count;
+
+ BFD_ASSERT (is_sparc_elf (abfd) || num_relocs == 0);
+
+ if (htab->elf.dynobj == NULL)
+ htab->elf.dynobj = abfd;
+ if (!create_ifunc_sections (htab->elf.dynobj, info))
+ return FALSE;
+
+ rel_end = relocs + num_relocs;
+ for (rel = relocs; rel < rel_end; rel++)
+ {
+ unsigned int r_type;
+ unsigned long r_symndx;
+ struct elf_link_hash_entry *h;
+ Elf_Internal_Sym *isym;
+
+ r_symndx = SPARC_ELF_R_SYMNDX (htab, rel->r_info);
+ r_type = SPARC_ELF_R_TYPE (rel->r_info);
+
+ if (r_symndx >= NUM_SHDR_ENTRIES (symtab_hdr))
+ {
+ (*_bfd_error_handler) (_("%B: bad symbol index: %d"),
+ abfd, r_symndx);
+ return FALSE;
+ }
+
+ isym = NULL;
+ if (r_symndx < symtab_hdr->sh_info)
+ {
+ /* A local symbol. */
+ isym = bfd_sym_from_r_symndx (&htab->sym_cache,
+ abfd, r_symndx);
+ if (isym == NULL)
+ return FALSE;
+
+ /* Check relocation against local STT_GNU_IFUNC symbol. */
+ if (ELF_ST_TYPE (isym->st_info) == STT_GNU_IFUNC)
+ {
+ h = elf_sparc_get_local_sym_hash (htab, abfd, rel,
+ TRUE);
+ if (h == NULL)
+ return FALSE;
+
+ /* Fake a STT_GNU_IFUNC symbol. */
+ h->type = STT_GNU_IFUNC;
+ h->def_regular = 1;
+ h->ref_regular = 1;
+ h->forced_local = 1;
+ h->root.type = bfd_link_hash_defined;
+ }
+ else
+ h = NULL;
+ }
+ 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;
+
+ /* PR15323, ref flags aren't set for references in the same
+ object. */
+ h->root.non_ir_ref = 1;
+ }
+
+ if (h && h->type == STT_GNU_IFUNC)
+ {
+ if (h->def_regular)
+ {
+ h->ref_regular = 1;
+ h->plt.refcount += 1;
+ }
+ }
+
+ /* Compatibility with old R_SPARC_REV32 reloc conflicting
+ with R_SPARC_TLS_GD_HI22. */
+ if (! ABI_64_P (abfd) && ! checked_tlsgd)
+ switch (r_type)
+ {
+ case R_SPARC_TLS_GD_HI22:
+ {
+ const Elf_Internal_Rela *relt;
+
+ for (relt = rel + 1; relt < rel_end; relt++)
+ if (ELF32_R_TYPE (relt->r_info) == R_SPARC_TLS_GD_LO10
+ || ELF32_R_TYPE (relt->r_info) == R_SPARC_TLS_GD_ADD
+ || ELF32_R_TYPE (relt->r_info) == R_SPARC_TLS_GD_CALL)
+ break;
+ checked_tlsgd = TRUE;
+ _bfd_sparc_elf_tdata (abfd)->has_tlsgd = relt < rel_end;
+ }
+ break;
+ case R_SPARC_TLS_GD_LO10:
+ case R_SPARC_TLS_GD_ADD:
+ case R_SPARC_TLS_GD_CALL:
+ checked_tlsgd = TRUE;
+ _bfd_sparc_elf_tdata (abfd)->has_tlsgd = TRUE;
+ break;
+ }
+
+ r_type = sparc_elf_tls_transition (info, abfd, r_type, h == NULL);
+ switch (r_type)
+ {
+ case R_SPARC_TLS_LDM_HI22:
+ case R_SPARC_TLS_LDM_LO10:
+ htab->tls_ldm_got.refcount += 1;
+ break;
+
+ case R_SPARC_TLS_LE_HIX22:
+ case R_SPARC_TLS_LE_LOX10:
+ if (info->shared)
+ goto r_sparc_plt32;
+ break;
+
+ case R_SPARC_TLS_IE_HI22:
+ case R_SPARC_TLS_IE_LO10:
+ if (info->shared)
+ info->flags |= DF_STATIC_TLS;
+ /* Fall through */
+
+ case R_SPARC_GOT10:
+ case R_SPARC_GOT13:
+ case R_SPARC_GOT22:
+ case R_SPARC_GOTDATA_HIX22:
+ case R_SPARC_GOTDATA_LOX10:
+ case R_SPARC_GOTDATA_OP_HIX22:
+ case R_SPARC_GOTDATA_OP_LOX10:
+ case R_SPARC_TLS_GD_HI22:
+ case R_SPARC_TLS_GD_LO10:
+ /* This symbol requires a global offset table entry. */
+ {
+ int tls_type, old_tls_type;
+
+ switch (r_type)
+ {
+ default:
+ case R_SPARC_GOT10:
+ case R_SPARC_GOT13:
+ case R_SPARC_GOT22:
+ case R_SPARC_GOTDATA_OP_HIX22:
+ case R_SPARC_GOTDATA_OP_LOX10:
+ tls_type = GOT_NORMAL;
+ break;
+ case R_SPARC_TLS_GD_HI22:
+ case R_SPARC_TLS_GD_LO10:
+ tls_type = GOT_TLS_GD;
+ break;
+ case R_SPARC_TLS_IE_HI22:
+ case R_SPARC_TLS_IE_LO10:
+ tls_type = GOT_TLS_IE;
+ break;
+ }
+
+ if (h != NULL)
+ {
+ h->got.refcount += 1;
+ old_tls_type = _bfd_sparc_elf_hash_entry(h)->tls_type;
+ }
+ else
+ {
+ bfd_signed_vma *local_got_refcounts;
+
+ /* This is a global offset table entry for a local symbol. */
+ local_got_refcounts = elf_local_got_refcounts (abfd);
+ if (local_got_refcounts == NULL)
+ {
+ bfd_size_type size;
+
+ size = symtab_hdr->sh_info;
+ size *= (sizeof (bfd_signed_vma) + sizeof(char));
+ local_got_refcounts = ((bfd_signed_vma *)
+ bfd_zalloc (abfd, size));
+ if (local_got_refcounts == NULL)
+ return FALSE;
+ elf_local_got_refcounts (abfd) = local_got_refcounts;
+ _bfd_sparc_elf_local_got_tls_type (abfd)
+ = (char *) (local_got_refcounts + symtab_hdr->sh_info);
+ }
+ switch (r_type)
+ {
+ case R_SPARC_GOTDATA_OP_HIX22:
+ case R_SPARC_GOTDATA_OP_LOX10:
+ break;
+
+ default:
+ local_got_refcounts[r_symndx] += 1;
+ break;
+ }
+ old_tls_type = _bfd_sparc_elf_local_got_tls_type (abfd) [r_symndx];
+ }
+
+ /* If a TLS symbol is accessed using IE at least once,
+ there is no point to use dynamic model for it. */
+ if (old_tls_type != tls_type && old_tls_type != GOT_UNKNOWN
+ && (old_tls_type != GOT_TLS_GD
+ || tls_type != GOT_TLS_IE))
+ {
+ if (old_tls_type == GOT_TLS_IE && tls_type == GOT_TLS_GD)
+ tls_type = old_tls_type;
+ else
+ {
+ (*_bfd_error_handler)
+ (_("%B: `%s' accessed both as normal and thread local symbol"),
+ abfd, h ? h->root.root.string : "<local>");
+ return FALSE;
+ }
+ }
+
+ if (old_tls_type != tls_type)
+ {
+ if (h != NULL)
+ _bfd_sparc_elf_hash_entry (h)->tls_type = tls_type;
+ else
+ _bfd_sparc_elf_local_got_tls_type (abfd) [r_symndx] = tls_type;
+ }
+ }
+
+ if (htab->elf.sgot == NULL)
+ {
+ if (!_bfd_elf_create_got_section (htab->elf.dynobj, info))
+ return FALSE;
+ }
+ break;
+
+ case R_SPARC_TLS_GD_CALL:
+ case R_SPARC_TLS_LDM_CALL:
+ if (info->shared)
+ {
+ /* These are basically R_SPARC_TLS_WPLT30 relocs against
+ __tls_get_addr. */
+ struct bfd_link_hash_entry *bh = NULL;
+ if (! _bfd_generic_link_add_one_symbol (info, abfd,
+ "__tls_get_addr", 0,
+ bfd_und_section_ptr, 0,
+ NULL, FALSE, FALSE,
+ &bh))
+ return FALSE;
+ h = (struct elf_link_hash_entry *) bh;
+ }
+ else
+ break;
+ /* Fall through */
+
+ case R_SPARC_PLT32:
+ case R_SPARC_WPLT30:
+ 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)
+ {
+ if (! ABI_64_P (abfd))
+ {
+ /* 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 (ELF32_R_TYPE (rel->r_info) == R_SPARC_PLT32)
+ goto r_sparc_plt32;
+ break;
+ }
+ /* PR 7027: We need similar behaviour for 64-bit binaries. */
+ else if (r_type == R_SPARC_WPLT30)
+ break;
+
+ /* 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;
+ }
+
+ h->needs_plt = 1;
+
+ {
+ int this_r_type;
+
+ this_r_type = SPARC_ELF_R_TYPE (rel->r_info);
+ if (this_r_type == R_SPARC_PLT32
+ || this_r_type == R_SPARC_PLT64)
+ goto r_sparc_plt32;
+ }
+ h->plt.refcount += 1;
+ 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)
+ h->non_got_ref = 1;
+
+ 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:
+ case R_SPARC_WDISP10:
+ 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_UA16:
+ 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_H34:
+ case R_SPARC_UA64:
+ if (h != NULL)
+ h->non_got_ref = 1;
+
+ r_sparc_plt32:
+ if (h != NULL && !info->shared)
+ {
+ /* We may need a .plt entry if the function this reloc
+ refers to is in a shared lib. */
+ h->plt.refcount += 1;
+ }
+
+ /* 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). In case of a weak definition,
+ DEF_REGULAR may be cleared later by a strong definition in
+ a shared library. We account for that possibility below by
+ storing information in the relocs_copied field of the hash
+ table entry. A similar situation occurs when creating
+ shared libraries and symbol visibility changes render the
+ symbol local.
+
+ If on the other hand, we are creating an executable, we
+ may need to keep relocations for symbols satisfied by a
+ dynamic library if we manage to avoid copy relocs for the
+ symbol. */
+ if ((info->shared
+ && (sec->flags & SEC_ALLOC) != 0
+ && (! _bfd_sparc_elf_howto_table[r_type].pc_relative
+ || (h != NULL
+ && (! SYMBOLIC_BIND (info, h)
+ || h->root.type == bfd_link_hash_defweak
+ || !h->def_regular))))
+ || (!info->shared
+ && (sec->flags & SEC_ALLOC) != 0
+ && h != NULL
+ && (h->root.type == bfd_link_hash_defweak
+ || !h->def_regular))
+ || (!info->shared
+ && h != NULL
+ && h->type == STT_GNU_IFUNC))
+ {
+ struct _bfd_sparc_elf_dyn_relocs *p;
+ struct _bfd_sparc_elf_dyn_relocs **head;
+
+ /* 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)
+ {
+ sreloc = _bfd_elf_make_dynamic_reloc_section
+ (sec, htab->elf.dynobj, htab->word_align_power,
+ abfd, /*rela?*/ TRUE);
+
+ if (sreloc == NULL)
+ return FALSE;
+ }
+
+ /* If this is a global symbol, we count the number of
+ relocations we need for this symbol. */
+ if (h != NULL)
+ head = &((struct _bfd_sparc_elf_link_hash_entry *) h)->dyn_relocs;
+ else
+ {
+ /* Track dynamic relocs needed for local syms too.
+ We really need local syms available to do this
+ easily. Oh well. */
+ asection *s;
+ void *vpp;
+
+ BFD_ASSERT (isym != NULL);
+ s = bfd_section_from_elf_index (abfd, isym->st_shndx);
+ if (s == NULL)
+ s = sec;
+
+ vpp = &elf_section_data (s)->local_dynrel;
+ head = (struct _bfd_sparc_elf_dyn_relocs **) vpp;
+ }
+
+ p = *head;
+ if (p == NULL || p->sec != sec)
+ {
+ bfd_size_type amt = sizeof *p;
+ p = ((struct _bfd_sparc_elf_dyn_relocs *)
+ bfd_alloc (htab->elf.dynobj, amt));
+ if (p == NULL)
+ return FALSE;
+ p->next = *head;
+ *head = p;
+ p->sec = sec;
+ p->count = 0;
+ p->pc_count = 0;
+ }
+
+ p->count += 1;
+ if (_bfd_sparc_elf_howto_table[r_type].pc_relative)
+ p->pc_count += 1;
+ }
+
+ break;
+
+ case R_SPARC_GNU_VTINHERIT:
+ if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
+ return FALSE;
+ break;
+
+ case R_SPARC_GNU_VTENTRY:
+ BFD_ASSERT (h != NULL);
+ if (h != NULL
+ && !bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
+ return FALSE;
+ break;
+
+ case R_SPARC_REGISTER:
+ /* Nothing to do. */
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ return TRUE;
+}
+
+asection *
+_bfd_sparc_elf_gc_mark_hook (asection *sec,
+ struct bfd_link_info *info,
+ Elf_Internal_Rela *rel,
+ struct elf_link_hash_entry *h,
+ Elf_Internal_Sym *sym)
+{
+ if (h != NULL)
+ switch (SPARC_ELF_R_TYPE (rel->r_info))
+ {
+ case R_SPARC_GNU_VTINHERIT:
+ case R_SPARC_GNU_VTENTRY:
+ return NULL;
+ }
+
+ /* FIXME: The test here, in check_relocs and in relocate_section
+ dealing with TLS optimization, ought to be !info->executable. */
+ if (info->shared)
+ {
+ switch (SPARC_ELF_R_TYPE (rel->r_info))
+ {
+ case R_SPARC_TLS_GD_CALL:
+ case R_SPARC_TLS_LDM_CALL:
+ /* This reloc implicitly references __tls_get_addr. We know
+ another reloc will reference the same symbol as the one
+ on this reloc, so the real symbol and section will be
+ gc marked when processing the other reloc. That lets
+ us handle __tls_get_addr here. */
+ h = elf_link_hash_lookup (elf_hash_table (info), "__tls_get_addr",
+ FALSE, FALSE, TRUE);
+ BFD_ASSERT (h != NULL);
+ h->mark = 1;
+ if (h->u.weakdef != NULL)
+ h->u.weakdef->mark = 1;
+ sym = NULL;
+ }
+ }
+
+ return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
+}
+
+static Elf_Internal_Rela *
+sparc_elf_find_reloc_at_ofs (Elf_Internal_Rela *rel,
+ Elf_Internal_Rela *relend,
+ bfd_vma offset)
+{
+ while (rel < relend)
+ {
+ if (rel->r_offset == offset)
+ return rel;
+ rel++;
+ }
+ return NULL;
+}
+
+/* Update the got entry reference counts for the section being removed. */
+bfd_boolean
+_bfd_sparc_elf_gc_sweep_hook (bfd *abfd, struct bfd_link_info *info,
+ asection *sec, const Elf_Internal_Rela *relocs)
+{
+ struct _bfd_sparc_elf_link_hash_table *htab;
+ Elf_Internal_Shdr *symtab_hdr;
+ struct elf_link_hash_entry **sym_hashes;
+ bfd_signed_vma *local_got_refcounts;
+ const Elf_Internal_Rela *rel, *relend;
+
+ if (info->relocatable)
+ return TRUE;
+
+ BFD_ASSERT (is_sparc_elf (abfd) || sec->reloc_count == 0);
+
+ elf_section_data (sec)->local_dynrel = NULL;
+
+ htab = _bfd_sparc_elf_hash_table (info);
+ BFD_ASSERT (htab != NULL);
+ symtab_hdr = &elf_symtab_hdr (abfd);
+ 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++)
+ {
+ unsigned long r_symndx;
+ unsigned int r_type;
+ struct elf_link_hash_entry *h = NULL;
+
+ r_symndx = SPARC_ELF_R_SYMNDX (htab, rel->r_info);
+ if (r_symndx >= symtab_hdr->sh_info)
+ {
+ struct _bfd_sparc_elf_link_hash_entry *eh;
+ struct _bfd_sparc_elf_dyn_relocs **pp;
+ struct _bfd_sparc_elf_dyn_relocs *p;
+
+ 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;
+ eh = (struct _bfd_sparc_elf_link_hash_entry *) h;
+ for (pp = &eh->dyn_relocs; (p = *pp) != NULL; pp = &p->next)
+ if (p->sec == sec)
+ {
+ /* Everything must go for SEC. */
+ *pp = p->next;
+ break;
+ }
+ }
+
+ r_type = SPARC_ELF_R_TYPE (rel->r_info);
+ r_type = sparc_elf_tls_transition (info, abfd, r_type, h == NULL);
+ switch (r_type)
+ {
+ case R_SPARC_TLS_LDM_HI22:
+ case R_SPARC_TLS_LDM_LO10:
+ if (_bfd_sparc_elf_hash_table (info)->tls_ldm_got.refcount > 0)
+ _bfd_sparc_elf_hash_table (info)->tls_ldm_got.refcount -= 1;
+ break;
+
+ case R_SPARC_TLS_GD_HI22:
+ case R_SPARC_TLS_GD_LO10:
+ case R_SPARC_TLS_IE_HI22:
+ case R_SPARC_TLS_IE_LO10:
+ case R_SPARC_GOT10:
+ case R_SPARC_GOT13:
+ case R_SPARC_GOT22:
+ case R_SPARC_GOTDATA_HIX22:
+ case R_SPARC_GOTDATA_LOX10:
+ case R_SPARC_GOTDATA_OP_HIX22:
+ case R_SPARC_GOTDATA_OP_LOX10:
+ if (h != NULL)
+ {
+ if (h->got.refcount > 0)
+ h->got.refcount--;
+ }
+ else
+ {
+ switch (r_type)
+ {
+ case R_SPARC_GOTDATA_OP_HIX22:
+ case R_SPARC_GOTDATA_OP_LOX10:
+ break;
+
+ default:
+ if (local_got_refcounts[r_symndx] > 0)
+ local_got_refcounts[r_symndx]--;
+ break;
+ }
+ }
+ 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:
+ case R_SPARC_WDISP10:
+ 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_UA16:
+ case R_SPARC_UA32:
+ case R_SPARC_PLT32:
+ 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_H34:
+ case R_SPARC_UA64:
+ if (info->shared)
+ break;
+ /* Fall through. */
+
+ case R_SPARC_WPLT30:
+ if (h != NULL)
+ {
+ 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. */
+
+bfd_boolean
+_bfd_sparc_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
+ struct elf_link_hash_entry *h)
+{
+ struct _bfd_sparc_elf_link_hash_table *htab;
+ struct _bfd_sparc_elf_link_hash_entry * eh;
+ struct _bfd_sparc_elf_dyn_relocs *p;
+ asection *s;
+
+ htab = _bfd_sparc_elf_hash_table (info);
+ BFD_ASSERT (htab != NULL);
+
+ /* Make sure we know what is going on here. */
+ BFD_ASSERT (htab->elf.dynobj != NULL
+ && (h->needs_plt
+ || h->type == STT_GNU_IFUNC
+ || h->u.weakdef != NULL
+ || (h->def_dynamic
+ && h->ref_regular
+ && !h->def_regular)));
+
+ /* 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->type == STT_GNU_IFUNC
+ || h->needs_plt
+ || (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 (h->plt.refcount <= 0
+ || (h->type != STT_GNU_IFUNC
+ && (SYMBOL_CALLS_LOCAL (info, h)
+ || (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
+ && h->root.type == bfd_link_hash_undefweak))))
+ {
+ /* This case can occur if we saw a WPLT30 reloc in an input
+ file, but the symbol was never referred to by a dynamic
+ object, or if all references were garbage collected. In
+ such a case, we don't actually need to build a procedure
+ linkage table, and we can just do a WDISP30 reloc instead. */
+ h->plt.offset = (bfd_vma) -1;
+ h->needs_plt = 0;
+ }
+
+ return TRUE;
+ }
+ else
+ 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->u.weakdef != NULL)
+ {
+ BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
+ || h->u.weakdef->root.type == bfd_link_hash_defweak);
+ h->root.u.def.section = h->u.weakdef->root.u.def.section;
+ h->root.u.def.value = h->u.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;
+
+ /* If there are no references to this symbol that do not use the
+ GOT, we don't need to generate a copy reloc. */
+ if (!h->non_got_ref)
+ return TRUE;
+
+ /* If -z nocopyreloc was given, we won't generate them either. */
+ if (info->nocopyreloc)
+ {
+ h->non_got_ref = 0;
+ return TRUE;
+ }
+
+ eh = (struct _bfd_sparc_elf_link_hash_entry *) h;
+ for (p = eh->dyn_relocs; p != NULL; p = p->next)
+ {
+ s = p->sec->output_section;
+ if (s != NULL && (s->flags & SEC_READONLY) != 0)
+ break;
+ }
+
+ /* If we didn't find any dynamic relocs in read-only sections, then
+ we'll be keeping the dynamic relocs and avoiding the copy reloc. */
+ if (p == NULL)
+ {
+ h->non_got_ref = 0;
+ 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. */
+
+ /* 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 && h->size != 0)
+ {
+ htab->srelbss->size += SPARC_ELF_RELA_BYTES (htab);
+ h->needs_copy = 1;
+ }
+
+ s = htab->sdynbss;
+
+ return _bfd_elf_adjust_dynamic_copy (h, s);
+}
+
+/* Allocate space in .plt, .got and associated reloc sections for
+ dynamic relocs. */
+
+static bfd_boolean
+allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
+{
+ struct bfd_link_info *info;
+ struct _bfd_sparc_elf_link_hash_table *htab;
+ struct _bfd_sparc_elf_link_hash_entry *eh;
+ struct _bfd_sparc_elf_dyn_relocs *p;
+
+ if (h->root.type == bfd_link_hash_indirect)
+ return TRUE;
+
+ info = (struct bfd_link_info *) inf;
+ htab = _bfd_sparc_elf_hash_table (info);
+ BFD_ASSERT (htab != NULL);
+
+ if ((htab->elf.dynamic_sections_created
+ && h->plt.refcount > 0)
+ || (h->type == STT_GNU_IFUNC
+ && h->def_regular
+ && h->ref_regular))
+ {
+ /* Make sure this symbol is output as a dynamic symbol.
+ Undefined weak syms won't yet be marked as dynamic. */
+ if (h->dynindx == -1
+ && !h->forced_local)
+ {
+ if (! bfd_elf_link_record_dynamic_symbol (info, h))
+ return FALSE;
+ }
+
+ if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, info->shared, h)
+ || (h->type == STT_GNU_IFUNC
+ && h->def_regular))
+ {
+ asection *s = htab->elf.splt;
+
+ if (s == NULL)
+ s = htab->elf.iplt;
+
+ /* Allocate room for the header. */
+ if (s->size == 0)
+ {
+ s->size = htab->plt_header_size;
+
+ /* Allocate space for the .rela.plt.unloaded relocations. */
+ if (htab->is_vxworks && !info->shared)
+ htab->srelplt2->size = sizeof (Elf32_External_Rela) * 2;
+ }
+
+ /* The procedure linkage table size is bounded by the magnitude
+ of the offset we can describe in the entry. */
+ if (s->size >= (SPARC_ELF_WORD_BYTES(htab) == 8 ?
+ (((bfd_vma)1 << 31) << 1) : 0x400000))
+ {
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+
+ if (SPARC_ELF_WORD_BYTES(htab) == 8
+ && s->size >= PLT64_LARGE_THRESHOLD * PLT64_ENTRY_SIZE)
+ {
+ bfd_vma off = s->size - PLT64_LARGE_THRESHOLD * PLT64_ENTRY_SIZE;
+
+
+ off = (off % (160 * PLT64_ENTRY_SIZE)) / PLT64_ENTRY_SIZE;
+
+ h->plt.offset = (s->size - (off * 8));
+ }
+ else
+ h->plt.offset = s->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->def_regular)
+ {
+ h->root.u.def.section = s;
+ h->root.u.def.value = h->plt.offset;
+ }
+
+ /* Make room for this entry. */
+ s->size += htab->plt_entry_size;
+
+ /* We also need to make an entry in the .rela.plt section. */
+ if (s == htab->elf.splt)
+ htab->elf.srelplt->size += SPARC_ELF_RELA_BYTES (htab);
+ else
+ htab->elf.irelplt->size += SPARC_ELF_RELA_BYTES (htab);
+
+ if (htab->is_vxworks)
+ {
+ /* Allocate space for the .got.plt entry. */
+ htab->elf.sgotplt->size += 4;
+
+ /* ...and for the .rela.plt.unloaded relocations. */
+ if (!info->shared)
+ htab->srelplt2->size += sizeof (Elf32_External_Rela) * 3;
+ }
+ }
+ else
+ {
+ h->plt.offset = (bfd_vma) -1;
+ h->needs_plt = 0;
+ }
+ }
+ else
+ {
+ h->plt.offset = (bfd_vma) -1;
+ h->needs_plt = 0;
+ }
+
+ /* If R_SPARC_TLS_IE_{HI22,LO10} symbol is now local to the binary,
+ make it a R_SPARC_TLS_LE_{HI22,LO10} requiring no TLS entry. */
+ if (h->got.refcount > 0
+ && !info->shared
+ && h->dynindx == -1
+ && _bfd_sparc_elf_hash_entry(h)->tls_type == GOT_TLS_IE)
+ h->got.offset = (bfd_vma) -1;
+ else if (h->got.refcount > 0)
+ {
+ asection *s;
+ bfd_boolean dyn;
+ int tls_type = _bfd_sparc_elf_hash_entry(h)->tls_type;
+
+ /* Make sure this symbol is output as a dynamic symbol.
+ Undefined weak syms won't yet be marked as dynamic. */
+ if (h->dynindx == -1
+ && !h->forced_local)
+ {
+ if (! bfd_elf_link_record_dynamic_symbol (info, h))
+ return FALSE;
+ }
+
+ s = htab->elf.sgot;
+ h->got.offset = s->size;
+ s->size += SPARC_ELF_WORD_BYTES (htab);
+ /* R_SPARC_TLS_GD_HI{22,LO10} needs 2 consecutive GOT slots. */
+ if (tls_type == GOT_TLS_GD)
+ s->size += SPARC_ELF_WORD_BYTES (htab);
+ dyn = htab->elf.dynamic_sections_created;
+ /* R_SPARC_TLS_IE_{HI22,LO10} needs one dynamic relocation,
+ R_SPARC_TLS_GD_{HI22,LO10} needs one if local symbol and two if
+ global. */
+ if ((tls_type == GOT_TLS_GD && h->dynindx == -1)
+ || tls_type == GOT_TLS_IE
+ || h->type == STT_GNU_IFUNC)
+ htab->elf.srelgot->size += SPARC_ELF_RELA_BYTES (htab);
+ else if (tls_type == GOT_TLS_GD)
+ htab->elf.srelgot->size += 2 * SPARC_ELF_RELA_BYTES (htab);
+ else if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h))
+ htab->elf.srelgot->size += SPARC_ELF_RELA_BYTES (htab);
+ }
+ else
+ h->got.offset = (bfd_vma) -1;
+
+ eh = (struct _bfd_sparc_elf_link_hash_entry *) h;
+ if (eh->dyn_relocs == NULL)
+ return TRUE;
+
+ /* In the shared -Bsymbolic case, discard space allocated for
+ dynamic pc-relative relocs against symbols which turn out to be
+ defined in regular objects. For the normal shared case, discard
+ space for pc-relative relocs that have become local due to symbol
+ visibility changes. */
+
+ if (info->shared)
+ {
+ if (SYMBOL_CALLS_LOCAL (info, h))
+ {
+ struct _bfd_sparc_elf_dyn_relocs **pp;
+
+ for (pp = &eh->dyn_relocs; (p = *pp) != NULL; )
+ {
+ p->count -= p->pc_count;
+ p->pc_count = 0;
+ if (p->count == 0)
+ *pp = p->next;
+ else
+ pp = &p->next;
+ }
+ }
+
+ if (htab->is_vxworks)
+ {
+ struct _bfd_sparc_elf_dyn_relocs **pp;
+
+ for (pp = &eh->dyn_relocs; (p = *pp) != NULL; )
+ {
+ if (strcmp (p->sec->output_section->name, ".tls_vars") == 0)
+ *pp = p->next;
+ else
+ pp = &p->next;
+ }
+ }
+
+ /* Also discard relocs on undefined weak syms with non-default
+ visibility. */
+ if (eh->dyn_relocs != NULL
+ && h->root.type == bfd_link_hash_undefweak)
+ {
+ if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
+ eh->dyn_relocs = NULL;
+
+ /* Make sure undefined weak symbols are output as a dynamic
+ symbol in PIEs. */
+ else if (h->dynindx == -1
+ && !h->forced_local)
+ {
+ if (! bfd_elf_link_record_dynamic_symbol (info, h))
+ return FALSE;
+ }
+ }
+ }
+ else
+ {
+ /* For the non-shared case, discard space for relocs against
+ symbols which turn out to need copy relocs or are not
+ dynamic. */
+
+ if (!h->non_got_ref
+ && ((h->def_dynamic
+ && !h->def_regular)
+ || (htab->elf.dynamic_sections_created
+ && (h->root.type == bfd_link_hash_undefweak
+ || h->root.type == bfd_link_hash_undefined))))
+ {
+ /* Make sure this symbol is output as a dynamic symbol.
+ Undefined weak syms won't yet be marked as dynamic. */
+ if (h->dynindx == -1
+ && !h->forced_local)
+ {
+ if (! bfd_elf_link_record_dynamic_symbol (info, h))
+ return FALSE;
+ }
+
+ /* If that succeeded, we know we'll be keeping all the
+ relocs. */
+ if (h->dynindx != -1)
+ goto keep;
+ }
+
+ eh->dyn_relocs = NULL;
+
+ keep: ;
+ }
+
+ /* Finally, allocate space. */
+ for (p = eh->dyn_relocs; p != NULL; p = p->next)
+ {
+ asection *sreloc = elf_section_data (p->sec)->sreloc;
+ sreloc->size += p->count * SPARC_ELF_RELA_BYTES (htab);
+ }
+
+ return TRUE;
+}
+
+/* Allocate space in .plt, .got and associated reloc sections for
+ local dynamic relocs. */
+
+static bfd_boolean
+allocate_local_dynrelocs (void **slot, void *inf)
+{
+ struct elf_link_hash_entry *h
+ = (struct elf_link_hash_entry *) *slot;
+
+ if (h->type != STT_GNU_IFUNC
+ || !h->def_regular
+ || !h->ref_regular
+ || !h->forced_local
+ || h->root.type != bfd_link_hash_defined)
+ abort ();
+
+ return allocate_dynrelocs (h, inf);
+}
+
+/* Find any dynamic relocs that apply to read-only sections. */
+
+static bfd_boolean
+readonly_dynrelocs (struct elf_link_hash_entry *h, void * inf)
+{
+ struct _bfd_sparc_elf_link_hash_entry *eh;
+ struct _bfd_sparc_elf_dyn_relocs *p;
+
+ eh = (struct _bfd_sparc_elf_link_hash_entry *) h;
+ for (p = eh->dyn_relocs; p != NULL; p = p->next)
+ {
+ asection *s = p->sec->output_section;
+
+ if (s != NULL && (s->flags & SEC_READONLY) != 0)
+ {
+ struct bfd_link_info *info = (struct bfd_link_info *) inf;
+
+ info->flags |= DF_TEXTREL;
+
+ /* Not an error, just cut short the traversal. */
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+/* Return true if the dynamic symbol for a given section should be
+ omitted when creating a shared library. */
+
+bfd_boolean
+_bfd_sparc_elf_omit_section_dynsym (bfd *output_bfd,
+ struct bfd_link_info *info,
+ asection *p)
+{
+ /* We keep the .got section symbol so that explicit relocations
+ against the _GLOBAL_OFFSET_TABLE_ symbol emitted in PIC mode
+ can be turned into relocations against the .got symbol. */
+ if (strcmp (p->name, ".got") == 0)
+ return FALSE;
+
+ return _bfd_elf_link_omit_section_dynsym (output_bfd, info, p);
+}
+
+/* Set the sizes of the dynamic sections. */
+
+bfd_boolean
+_bfd_sparc_elf_size_dynamic_sections (bfd *output_bfd,
+ struct bfd_link_info *info)
+{
+ struct _bfd_sparc_elf_link_hash_table *htab;
+ bfd *dynobj;
+ asection *s;
+ bfd *ibfd;
+
+ htab = _bfd_sparc_elf_hash_table (info);
+ BFD_ASSERT (htab != NULL);
+ dynobj = htab->elf.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->executable)
+ {
+ s = bfd_get_linker_section (dynobj, ".interp");
+ BFD_ASSERT (s != NULL);
+ s->size = htab->dynamic_interpreter_size;
+ s->contents = (unsigned char *) htab->dynamic_interpreter;
+ }
+ }
+
+ /* Set up .got offsets for local syms, and space for local dynamic
+ relocs. */
+ for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next)
+ {
+ bfd_signed_vma *local_got;
+ bfd_signed_vma *end_local_got;
+ char *local_tls_type;
+ bfd_size_type locsymcount;
+ Elf_Internal_Shdr *symtab_hdr;
+ asection *srel;
+
+ if (! is_sparc_elf (ibfd))
+ continue;
+
+ for (s = ibfd->sections; s != NULL; s = s->next)
+ {
+ struct _bfd_sparc_elf_dyn_relocs *p;
+
+ for (p = elf_section_data (s)->local_dynrel; p != NULL; p = p->next)
+ {
+ if (!bfd_is_abs_section (p->sec)
+ && bfd_is_abs_section (p->sec->output_section))
+ {
+ /* Input section has been discarded, either because
+ it is a copy of a linkonce section or due to
+ linker script /DISCARD/, so we'll be discarding
+ the relocs too. */
+ }
+ else if (htab->is_vxworks
+ && strcmp (p->sec->output_section->name,
+ ".tls_vars") == 0)
+ {
+ /* Relocations in vxworks .tls_vars sections are
+ handled specially by the loader. */
+ }
+ else if (p->count != 0)
+ {
+ srel = elf_section_data (p->sec)->sreloc;
+ if (!htab->elf.dynamic_sections_created)
+ srel = htab->elf.irelplt;
+ srel->size += p->count * SPARC_ELF_RELA_BYTES (htab);
+ if ((p->sec->output_section->flags & SEC_READONLY) != 0)
+ info->flags |= DF_TEXTREL;
+ }
+ }
+ }
+
+ local_got = elf_local_got_refcounts (ibfd);
+ if (!local_got)
+ continue;
+
+ symtab_hdr = &elf_symtab_hdr (ibfd);
+ locsymcount = symtab_hdr->sh_info;
+ end_local_got = local_got + locsymcount;
+ local_tls_type = _bfd_sparc_elf_local_got_tls_type (ibfd);
+ s = htab->elf.sgot;
+ srel = htab->elf.srelgot;
+ for (; local_got < end_local_got; ++local_got, ++local_tls_type)
+ {
+ if (*local_got > 0)
+ {
+ *local_got = s->size;
+ s->size += SPARC_ELF_WORD_BYTES (htab);
+ if (*local_tls_type == GOT_TLS_GD)
+ s->size += SPARC_ELF_WORD_BYTES (htab);
+ if (info->shared
+ || *local_tls_type == GOT_TLS_GD
+ || *local_tls_type == GOT_TLS_IE)
+ srel->size += SPARC_ELF_RELA_BYTES (htab);
+ }
+ else
+ *local_got = (bfd_vma) -1;
+ }
+ }
+
+ if (htab->tls_ldm_got.refcount > 0)
+ {
+ /* Allocate 2 got entries and 1 dynamic reloc for
+ R_SPARC_TLS_LDM_{HI22,LO10} relocs. */
+ htab->tls_ldm_got.offset = htab->elf.sgot->size;
+ htab->elf.sgot->size += (2 * SPARC_ELF_WORD_BYTES (htab));
+ htab->elf.srelgot->size += SPARC_ELF_RELA_BYTES (htab);
+ }
+ else
+ htab->tls_ldm_got.offset = -1;
+
+ /* Allocate global sym .plt and .got entries, and space for global
+ sym dynamic relocs. */
+ elf_link_hash_traverse (&htab->elf, allocate_dynrelocs, info);
+
+ /* Allocate .plt and .got entries, and space for local symbols. */
+ htab_traverse (htab->loc_hash_table, allocate_local_dynrelocs, info);
+
+ if (! ABI_64_P (output_bfd)
+ && !htab->is_vxworks
+ && elf_hash_table (info)->dynamic_sections_created)
+ {
+ /* Make space for the trailing nop in .plt. */
+ if (htab->elf.splt->size > 0)
+ htab->elf.splt->size += 1 * SPARC_INSN_BYTES;
+
+ /* 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.
+
+ FIXME: Make this optimization work for 64-bit too. */
+ if (htab->elf.sgot->size >= 0x1000
+ && elf_hash_table (info)->hgot->root.u.def.value == 0)
+ elf_hash_table (info)->hgot->root.u.def.value = 0x1000;
+ }
+
+ /* The check_relocs and adjust_dynamic_symbol entry points have
+ determined the sizes of the various dynamic sections. Allocate
+ memory for them. */
+ for (s = dynobj->sections; s != NULL; s = s->next)
+ {
+ if ((s->flags & SEC_LINKER_CREATED) == 0)
+ continue;
+
+ if (s == htab->elf.splt
+ || s == htab->elf.sgot
+ || s == htab->sdynbss
+ || s == htab->elf.iplt
+ || s == htab->elf.sgotplt)
+ {
+ /* Strip this section if we don't need it; see the
+ comment below. */
+ }
+ else if (CONST_STRNEQ (s->name, ".rela"))
+ {
+ if (s->size != 0)
+ {
+ /* We use the reloc_count field as a counter if we need
+ to copy relocs into the output file. */
+ s->reloc_count = 0;
+ }
+ }
+ else
+ {
+ /* It's not one of our sections. */
+ continue;
+ }
+
+ if (s->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. */
+ s->flags |= SEC_EXCLUDE;
+ continue;
+ }
+
+ if ((s->flags & SEC_HAS_CONTENTS) == 0)
+ 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->size);
+ if (s->contents == NULL)
+ return FALSE;
+ }
+
+ if (elf_hash_table (info)->dynamic_sections_created)
+ {
+ /* Add some entries to the .dynamic section. We fill in the
+ values later, in _bfd_sparc_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. */
+#define add_dynamic_entry(TAG, VAL) \
+ _bfd_elf_add_dynamic_entry (info, TAG, VAL)
+
+ if (info->executable)
+ {
+ if (!add_dynamic_entry (DT_DEBUG, 0))
+ return FALSE;
+ }
+
+ if (htab->elf.srelplt->size != 0)
+ {
+ if (!add_dynamic_entry (DT_PLTGOT, 0)
+ || !add_dynamic_entry (DT_PLTRELSZ, 0)
+ || !add_dynamic_entry (DT_PLTREL, DT_RELA)
+ || !add_dynamic_entry (DT_JMPREL, 0))
+ return FALSE;
+ }
+
+ if (!add_dynamic_entry (DT_RELA, 0)
+ || !add_dynamic_entry (DT_RELASZ, 0)
+ || !add_dynamic_entry (DT_RELAENT,
+ SPARC_ELF_RELA_BYTES (htab)))
+ return FALSE;
+
+ /* If any dynamic relocs apply to a read-only section,
+ then we need a DT_TEXTREL entry. */
+ if ((info->flags & DF_TEXTREL) == 0)
+ elf_link_hash_traverse (&htab->elf, readonly_dynrelocs, info);
+
+ if (info->flags & DF_TEXTREL)
+ {
+ if (!add_dynamic_entry (DT_TEXTREL, 0))
+ return FALSE;
+ }
+
+ if (ABI_64_P (output_bfd))
+ {
+ int reg;
+ struct _bfd_sparc_elf_app_reg * app_regs;
+ struct elf_strtab_hash *dynstr;
+ struct elf_link_hash_table *eht = elf_hash_table (info);
+
+ /* Add dynamic STT_REGISTER symbols and corresponding DT_SPARC_REGISTER
+ entries if needed. */
+ app_regs = _bfd_sparc_elf_hash_table (info)->app_regs;
+ dynstr = eht->dynstr;
+
+ for (reg = 0; reg < 4; reg++)
+ if (app_regs [reg].name != NULL)
+ {
+ struct elf_link_local_dynamic_entry *entry, *e;
+
+ if (!add_dynamic_entry (DT_SPARC_REGISTER, 0))
+ return FALSE;
+
+ entry = (struct elf_link_local_dynamic_entry *)
+ bfd_hash_allocate (&info->hash->table, sizeof (*entry));
+ if (entry == NULL)
+ return FALSE;
+
+ /* We cheat here a little bit: the symbol will not be local, so we
+ put it at the end of the dynlocal linked list. We will fix it
+ later on, as we have to fix other fields anyway. */
+ entry->isym.st_value = reg < 2 ? reg + 2 : reg + 4;
+ entry->isym.st_size = 0;
+ if (*app_regs [reg].name != '\0')
+ entry->isym.st_name
+ = _bfd_elf_strtab_add (dynstr, app_regs[reg].name, FALSE);
+ else
+ entry->isym.st_name = 0;
+ entry->isym.st_other = 0;
+ entry->isym.st_info = ELF_ST_INFO (app_regs [reg].bind,
+ STT_REGISTER);
+ entry->isym.st_shndx = app_regs [reg].shndx;
+ entry->isym.st_target_internal = 0;
+ entry->next = NULL;
+ entry->input_bfd = output_bfd;
+ entry->input_indx = -1;
+
+ if (eht->dynlocal == NULL)
+ eht->dynlocal = entry;
+ else
+ {
+ for (e = eht->dynlocal; e->next; e = e->next)
+ ;
+ e->next = entry;
+ }
+ eht->dynsymcount++;
+ }
+ }
+ if (htab->is_vxworks
+ && !elf_vxworks_add_dynamic_entries (output_bfd, info))
+ return FALSE;
+ }
+#undef add_dynamic_entry
+
+ return TRUE;
+}
+
+bfd_boolean
+_bfd_sparc_elf_new_section_hook (bfd *abfd, asection *sec)
+{
+ if (!sec->used_by_bfd)
+ {
+ struct _bfd_sparc_elf_section_data *sdata;
+ bfd_size_type amt = sizeof (*sdata);
+
+ sdata = bfd_zalloc (abfd, amt);
+ if (sdata == NULL)
+ return FALSE;
+ sec->used_by_bfd = sdata;
+ }
+
+ return _bfd_elf_new_section_hook (abfd, sec);
+}
+
+bfd_boolean
+_bfd_sparc_elf_relax_section (bfd *abfd ATTRIBUTE_UNUSED,
+ struct bfd_section *section,
+ struct bfd_link_info *link_info ATTRIBUTE_UNUSED,
+ bfd_boolean *again)
+{
+ if (link_info->relocatable)
+ (*link_info->callbacks->einfo)
+ (_("%P%F: --relax and -r may not be used together\n"));
+
+ *again = FALSE;
+ sec_do_relax (section) = 1;
+ return TRUE;
+}
+
+/* Return the base VMA address which should be subtracted from real addresses
+ when resolving @dtpoff relocation.
+ This is PT_TLS segment p_vaddr. */
+
+static bfd_vma
+dtpoff_base (struct bfd_link_info *info)
+{
+ /* If tls_sec is NULL, we should have signalled an error already. */
+ if (elf_hash_table (info)->tls_sec == NULL)
+ return 0;
+ return elf_hash_table (info)->tls_sec->vma;
+}
+
+/* Return the relocation value for @tpoff relocation
+ if STT_TLS virtual address is ADDRESS. */
+
+static bfd_vma
+tpoff (struct bfd_link_info *info, bfd_vma address)
+{
+ struct elf_link_hash_table *htab = elf_hash_table (info);
+ const struct elf_backend_data *bed = get_elf_backend_data (info->output_bfd);
+ bfd_vma static_tls_size;
+
+ /* If tls_sec is NULL, we should have signalled an error already. */
+ if (htab->tls_sec == NULL)
+ return 0;
+
+ /* Consider special static TLS alignment requirements. */
+ static_tls_size = BFD_ALIGN (htab->tls_size, bed->static_tls_alignment);
+ return address - static_tls_size - htab->tls_sec->vma;
+}
+
+/* Return the relocation value for a %gdop relocation. */
+
+static bfd_vma
+gdopoff (struct bfd_link_info *info, bfd_vma address)
+{
+ struct elf_link_hash_table *htab = elf_hash_table (info);
+ bfd_vma got_base;
+
+ got_base = (htab->hgot->root.u.def.value
+ + htab->hgot->root.u.def.section->output_offset
+ + htab->hgot->root.u.def.section->output_section->vma);
+
+ return address - got_base;
+}
+
+/* Relocate a SPARC ELF section. */
+
+bfd_boolean
+_bfd_sparc_elf_relocate_section (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)
+{
+ struct _bfd_sparc_elf_link_hash_table *htab;
+ Elf_Internal_Shdr *symtab_hdr;
+ struct elf_link_hash_entry **sym_hashes;
+ bfd_vma *local_got_offsets;
+ bfd_vma got_base;
+ asection *sreloc;
+ Elf_Internal_Rela *rel;
+ Elf_Internal_Rela *relend;
+ int num_relocs;
+ bfd_boolean is_vxworks_tls;
+
+ htab = _bfd_sparc_elf_hash_table (info);
+ BFD_ASSERT (htab != NULL);
+ symtab_hdr = &elf_symtab_hdr (input_bfd);
+ 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;
+
+ sreloc = elf_section_data (input_section)->sreloc;
+ /* We have to handle relocations in vxworks .tls_vars sections
+ specially, because the dynamic loader is 'weird'. */
+ is_vxworks_tls = (htab->is_vxworks && info->shared
+ && !strcmp (input_section->output_section->name,
+ ".tls_vars"));
+
+ rel = relocs;
+ if (ABI_64_P (output_bfd))
+ num_relocs = NUM_SHDR_ENTRIES (_bfd_elf_single_rel_hdr (input_section));
+ else
+ num_relocs = input_section->reloc_count;
+ relend = relocs + num_relocs;
+ for (; rel < relend; rel++)
+ {
+ int r_type, tls_type;
+ reloc_howto_type *howto;
+ unsigned long r_symndx;
+ struct elf_link_hash_entry *h;
+ Elf_Internal_Sym *sym;
+ asection *sec;
+ bfd_vma relocation, off;
+ bfd_reloc_status_type r;
+ bfd_boolean is_plt = FALSE;
+ bfd_boolean unresolved_reloc;
+
+ r_type = SPARC_ELF_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_std)
+ {
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+ howto = _bfd_sparc_elf_howto_table + r_type;
+
+ r_symndx = SPARC_ELF_R_SYMNDX (htab, rel->r_info);
+ h = NULL;
+ sym = NULL;
+ sec = NULL;
+ unresolved_reloc = FALSE;
+ if (r_symndx < symtab_hdr->sh_info)
+ {
+ sym = local_syms + r_symndx;
+ sec = local_sections[r_symndx];
+ relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
+
+ if (!info->relocatable
+ && ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC)
+ {
+ /* Relocate against local STT_GNU_IFUNC symbol. */
+ h = elf_sparc_get_local_sym_hash (htab, input_bfd,
+ rel, FALSE);
+ if (h == NULL)
+ abort ();
+
+ /* Set STT_GNU_IFUNC symbol value. */
+ h->root.u.def.value = sym->st_value;
+ h->root.u.def.section = sec;
+ }
+ }
+ else
+ {
+ bfd_boolean warned, ignored;
+
+ RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
+ r_symndx, symtab_hdr, sym_hashes,
+ h, sec, relocation,
+ unresolved_reloc, warned, ignored);
+ if (warned)
+ {
+ /* To avoid generating warning messages about truncated
+ relocations, set the relocation's address to be the same as
+ the start of this section. */
+ if (input_section->output_section != NULL)
+ relocation = input_section->output_section->vma;
+ else
+ relocation = 0;
+ }
+ }
+
+ if (sec != NULL && discarded_section (sec))
+ RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+ rel, 1, relend, howto, 0, contents);
+
+ if (info->relocatable)
+ continue;
+
+ if (h != NULL
+ && h->type == STT_GNU_IFUNC
+ && h->def_regular)
+ {
+ asection *plt_sec;
+ const char *name;
+
+ if ((input_section->flags & SEC_ALLOC) == 0
+ || h->plt.offset == (bfd_vma) -1)
+ abort ();
+
+ plt_sec = htab->elf.splt;
+ if (! plt_sec)
+ plt_sec =htab->elf.iplt;
+
+ switch (r_type)
+ {
+ case R_SPARC_GOTDATA_OP:
+ continue;
+
+ case R_SPARC_GOTDATA_OP_HIX22:
+ case R_SPARC_GOTDATA_OP_LOX10:
+ r_type = (r_type == R_SPARC_GOTDATA_OP_HIX22
+ ? R_SPARC_GOT22
+ : R_SPARC_GOT10);
+ howto = _bfd_sparc_elf_howto_table + r_type;
+ /* Fall through. */
+
+ case R_SPARC_GOT10:
+ case R_SPARC_GOT13:
+ case R_SPARC_GOT22:
+ if (htab->elf.sgot == NULL)
+ abort ();
+ off = h->got.offset;
+ if (off == (bfd_vma) -1)
+ abort();
+ relocation = htab->elf.sgot->output_offset + off - got_base;
+ goto do_relocation;
+
+ case R_SPARC_WPLT30:
+ case R_SPARC_WDISP30:
+ relocation = (plt_sec->output_section->vma
+ + plt_sec->output_offset + h->plt.offset);
+ goto do_relocation;
+
+ case R_SPARC_32:
+ case R_SPARC_64:
+ if (info->shared && h->non_got_ref)
+ {
+ Elf_Internal_Rela outrel;
+ bfd_vma offset;
+
+ offset = _bfd_elf_section_offset (output_bfd, info,
+ input_section,
+ rel->r_offset);
+ if (offset == (bfd_vma) -1
+ || offset == (bfd_vma) -2)
+ abort();
+
+ outrel.r_offset = (input_section->output_section->vma
+ + input_section->output_offset
+ + offset);
+
+ if (h->dynindx == -1
+ || h->forced_local
+ || info->executable)
+ {
+ outrel.r_info = SPARC_ELF_R_INFO (htab, NULL,
+ 0, R_SPARC_IRELATIVE);
+ outrel.r_addend = relocation + rel->r_addend;
+ }
+ else
+ {
+ if (h->dynindx == -1)
+ abort();
+ outrel.r_info = SPARC_ELF_R_INFO (htab, rel, h->dynindx, r_type);
+ outrel.r_addend = rel->r_addend;
+ }
+
+ sparc_elf_append_rela (output_bfd, sreloc, &outrel);
+ continue;
+ }
+
+ relocation = (plt_sec->output_section->vma
+ + plt_sec->output_offset + h->plt.offset);
+ goto do_relocation;
+
+ case R_SPARC_HI22:
+ case R_SPARC_LO10:
+ /* We should only see such relocs in static links. */
+ if (info->shared)
+ abort();
+ relocation = (plt_sec->output_section->vma
+ + plt_sec->output_offset + h->plt.offset);
+ goto do_relocation;
+
+ default:
+ if (h->root.root.string)
+ name = h->root.root.string;
+ else
+ name = bfd_elf_sym_name (input_bfd, symtab_hdr, sym,
+ NULL);
+ (*_bfd_error_handler)
+ (_("%B: relocation %s against STT_GNU_IFUNC "
+ "symbol `%s' isn't handled by %s"), input_bfd,
+ _bfd_sparc_elf_howto_table[r_type].name,
+ name, __FUNCTION__);
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+ }
+
+ switch (r_type)
+ {
+ case R_SPARC_GOTDATA_OP_HIX22:
+ case R_SPARC_GOTDATA_OP_LOX10:
+ if (SYMBOL_REFERENCES_LOCAL (info, h))
+ r_type = (r_type == R_SPARC_GOTDATA_OP_HIX22
+ ? R_SPARC_GOTDATA_HIX22
+ : R_SPARC_GOTDATA_LOX10);
+ else
+ r_type = (r_type == R_SPARC_GOTDATA_OP_HIX22
+ ? R_SPARC_GOT22
+ : R_SPARC_GOT10);
+ howto = _bfd_sparc_elf_howto_table + r_type;
+ break;
+
+ case R_SPARC_GOTDATA_OP:
+ if (SYMBOL_REFERENCES_LOCAL (info, h))
+ {
+ bfd_vma insn = bfd_get_32 (input_bfd, contents + rel->r_offset);
+
+ /* {ld,ldx} [%rs1 + %rs2], %rd --> add %rs1, %rs2, %rd */
+ relocation = 0x80000000 | (insn & 0x3e07c01f);
+ bfd_put_32 (output_bfd, relocation, contents + rel->r_offset);
+ }
+ continue;
+ }
+
+ switch (r_type)
+ {
+ case R_SPARC_GOTDATA_HIX22:
+ case R_SPARC_GOTDATA_LOX10:
+ relocation = gdopoff (info, relocation);
+ break;
+
+ 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 (htab->elf.sgot == NULL)
+ abort ();
+
+ if (h != NULL)
+ {
+ bfd_boolean dyn;
+
+ off = h->got.offset;
+ BFD_ASSERT (off != (bfd_vma) -1);
+ dyn = elf_hash_table (info)->dynamic_sections_created;
+
+ if (! WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h)
+ || (info->shared
+ && SYMBOL_REFERENCES_LOCAL (info, h)))
+ {
+ /* 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 for 64-bit
+ and 4 for 32-bit, 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
+ {
+ SPARC_ELF_PUT_WORD (htab, output_bfd, relocation,
+ htab->elf.sgot->contents + off);
+ h->got.offset |= 1;
+ }
+ }
+ else
+ unresolved_reloc = FALSE;
+ }
+ 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 8 on 64-bit and
+ 4 on 32-bit. We use the least significant bit to record
+ whether we have already processed this entry. */
+ if ((off & 1) != 0)
+ off &= ~1;
+ else
+ {
+
+ if (info->shared)
+ {
+ asection *s;
+ Elf_Internal_Rela outrel;
+
+ /* We need to generate a R_SPARC_RELATIVE reloc
+ for the dynamic linker. */
+ s = htab->elf.srelgot;
+ BFD_ASSERT (s != NULL);
+
+ outrel.r_offset = (htab->elf.sgot->output_section->vma
+ + htab->elf.sgot->output_offset
+ + off);
+ outrel.r_info = SPARC_ELF_R_INFO (htab, NULL,
+ 0, R_SPARC_RELATIVE);
+ outrel.r_addend = relocation;
+ relocation = 0;
+ sparc_elf_append_rela (output_bfd, s, &outrel);
+ }
+
+ SPARC_ELF_PUT_WORD (htab, output_bfd, relocation,
+ htab->elf.sgot->contents + off);
+ local_got_offsets[r_symndx] |= 1;
+ }
+ }
+ relocation = htab->elf.sgot->output_offset + off - got_base;
+ break;
+
+ case R_SPARC_PLT32:
+ case R_SPARC_PLT64:
+ if (h == NULL || h->plt.offset == (bfd_vma) -1)
+ {
+ r_type = (r_type == R_SPARC_PLT32) ? R_SPARC_32 : R_SPARC_64;
+ goto r_sparc_plt32;
+ }
+ /* Fall through. */
+
+ case R_SPARC_WPLT30:
+ case R_SPARC_HIPLT22:
+ case R_SPARC_LOPLT10:
+ case R_SPARC_PCPLT32:
+ case R_SPARC_PCPLT22:
+ case R_SPARC_PCPLT10:
+ r_sparc_wplt30:
+ /* Relocation is to the entry for this symbol in the
+ procedure linkage table. */
+
+ if (! ABI_64_P (output_bfd))
+ {
+ /* 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;
+ }
+ /* PR 7027: We need similar behaviour for 64-bit binaries. */
+ else if (r_type == R_SPARC_WPLT30 && h == NULL)
+ break;
+ else
+ {
+ BFD_ASSERT (h != NULL);
+ }
+
+ if (h->plt.offset == (bfd_vma) -1 || htab->elf.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 = (htab->elf.splt->output_section->vma
+ + htab->elf.splt->output_offset
+ + h->plt.offset);
+ unresolved_reloc = FALSE;
+ if (r_type == R_SPARC_PLT32 || r_type == R_SPARC_PLT64)
+ {
+ r_type = r_type == R_SPARC_PLT32 ? R_SPARC_32 : R_SPARC_64;
+ is_plt = TRUE;
+ goto r_sparc_plt32;
+ }
+ 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:
+ case R_SPARC_WDISP10:
+ 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_UA16:
+ 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_H34:
+ case R_SPARC_UA64:
+ r_sparc_plt32:
+ if ((input_section->flags & SEC_ALLOC) == 0
+ || is_vxworks_tls)
+ break;
+
+ if ((info->shared
+ && (h == NULL
+ || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
+ || h->root.type != bfd_link_hash_undefweak)
+ && (! howto->pc_relative
+ || !SYMBOL_CALLS_LOCAL (info, h)))
+ || (!info->shared
+ && h != NULL
+ && h->dynindx != -1
+ && !h->non_got_ref
+ && ((h->def_dynamic
+ && !h->def_regular)
+ || h->root.type == bfd_link_hash_undefweak
+ || h->root.type == bfd_link_hash_undefined)))
+ {
+ Elf_Internal_Rela outrel;
+ bfd_boolean skip, relocate = FALSE;
+
+ /* When generating a shared object, these relocations
+ are copied into the output file to be resolved at run
+ time. */
+
+ BFD_ASSERT (sreloc != NULL);
+
+ skip = FALSE;
+
+ outrel.r_offset =
+ _bfd_elf_section_offset (output_bfd, info, input_section,
+ rel->r_offset);
+ if (outrel.r_offset == (bfd_vma) -1)
+ skip = TRUE;
+ else if (outrel.r_offset == (bfd_vma) -2)
+ skip = TRUE, relocate = TRUE;
+ 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;
+ case R_SPARC_DISP8:
+ case R_SPARC_DISP16:
+ case R_SPARC_DISP32:
+ case R_SPARC_DISP64:
+ /* If the symbol is not dynamic, we should not keep
+ a dynamic relocation. But an .rela.* slot has been
+ allocated for it, output R_SPARC_NONE.
+ FIXME: Add code tracking needed dynamic relocs as
+ e.g. i386 has. */
+ if (h->dynindx == -1)
+ skip = TRUE, relocate = TRUE;
+ 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 &&
+ h->dynindx != -1
+ && (! is_plt
+ || !info->shared
+ || !SYMBOLIC_BIND (info, h)
+ || !h->def_regular))
+ {
+ BFD_ASSERT (h->dynindx != -1);
+ outrel.r_info = SPARC_ELF_R_INFO (htab, rel, h->dynindx, r_type);
+ outrel.r_addend = rel->r_addend;
+ }
+ else
+ {
+ if (r_type == R_SPARC_32 || r_type == R_SPARC_64)
+ {
+ outrel.r_info = SPARC_ELF_R_INFO (htab, NULL,
+ 0, R_SPARC_RELATIVE);
+ outrel.r_addend = relocation + rel->r_addend;
+ }
+ else
+ {
+ long indx;
+
+ outrel.r_addend = relocation + rel->r_addend;
+
+ if (is_plt)
+ sec = htab->elf.splt;
+
+ if (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;
+
+ /* We are turning this relocation into one
+ against a section symbol. It would be
+ proper to subtract the symbol's value,
+ osec->vma, from the emitted reloc addend,
+ but ld.so expects buggy relocs. */
+ osec = sec->output_section;
+ indx = elf_section_data (osec)->dynindx;
+
+ if (indx == 0)
+ {
+ osec = htab->elf.text_index_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)
+ (_("%B: probably compiled without -fPIC?"),
+ input_bfd);
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+ }
+
+ outrel.r_info = SPARC_ELF_R_INFO (htab, rel, indx,
+ r_type);
+ }
+ }
+
+ sparc_elf_append_rela (output_bfd, sreloc, &outrel);
+
+ /* This reloc will be computed at runtime, so there's no
+ need to do anything now. */
+ if (! relocate)
+ continue;
+ }
+ break;
+
+ case R_SPARC_TLS_GD_HI22:
+ if (! ABI_64_P (input_bfd)
+ && ! _bfd_sparc_elf_tdata (input_bfd)->has_tlsgd)
+ {
+ /* R_SPARC_REV32 used the same reloc number as
+ R_SPARC_TLS_GD_HI22. */
+ r_type = R_SPARC_REV32;
+ break;
+ }
+ /* Fall through */
+
+ case R_SPARC_TLS_GD_LO10:
+ case R_SPARC_TLS_IE_HI22:
+ case R_SPARC_TLS_IE_LO10:
+ r_type = sparc_elf_tls_transition (info, input_bfd, r_type, h == NULL);
+ tls_type = GOT_UNKNOWN;
+ if (h == NULL && local_got_offsets)
+ tls_type = _bfd_sparc_elf_local_got_tls_type (input_bfd) [r_symndx];
+ else if (h != NULL)
+ {
+ tls_type = _bfd_sparc_elf_hash_entry(h)->tls_type;
+ if (!info->shared && h->dynindx == -1 && tls_type == GOT_TLS_IE)
+ switch (SPARC_ELF_R_TYPE (rel->r_info))
+ {
+ case R_SPARC_TLS_GD_HI22:
+ case R_SPARC_TLS_IE_HI22:
+ r_type = R_SPARC_TLS_LE_HIX22;
+ break;
+ default:
+ r_type = R_SPARC_TLS_LE_LOX10;
+ break;
+ }
+ }
+ if (tls_type == GOT_TLS_IE)
+ switch (r_type)
+ {
+ case R_SPARC_TLS_GD_HI22:
+ r_type = R_SPARC_TLS_IE_HI22;
+ break;
+ case R_SPARC_TLS_GD_LO10:
+ r_type = R_SPARC_TLS_IE_LO10;
+ break;
+ }
+
+ if (r_type == R_SPARC_TLS_LE_HIX22)
+ {
+ relocation = tpoff (info, relocation);
+ break;
+ }
+ if (r_type == R_SPARC_TLS_LE_LOX10)
+ {
+ /* Change add into xor. */
+ relocation = tpoff (info, relocation);
+ bfd_put_32 (output_bfd, (bfd_get_32 (input_bfd,
+ contents + rel->r_offset)
+ | 0x80182000), contents + rel->r_offset);
+ break;
+ }
+
+ if (h != NULL)
+ {
+ off = h->got.offset;
+ h->got.offset |= 1;
+ }
+ else
+ {
+ BFD_ASSERT (local_got_offsets != NULL);
+ off = local_got_offsets[r_symndx];
+ local_got_offsets[r_symndx] |= 1;
+ }
+
+ r_sparc_tlsldm:
+ if (htab->elf.sgot == NULL)
+ abort ();
+
+ if ((off & 1) != 0)
+ off &= ~1;
+ else
+ {
+ Elf_Internal_Rela outrel;
+ int dr_type, indx;
+
+ if (htab->elf.srelgot == NULL)
+ abort ();
+
+ SPARC_ELF_PUT_WORD (htab, output_bfd, 0,
+ htab->elf.sgot->contents + off);
+ outrel.r_offset = (htab->elf.sgot->output_section->vma
+ + htab->elf.sgot->output_offset + off);
+ indx = h && h->dynindx != -1 ? h->dynindx : 0;
+ if (r_type == R_SPARC_TLS_IE_HI22
+ || r_type == R_SPARC_TLS_IE_LO10)
+ dr_type = SPARC_ELF_TPOFF_RELOC (htab);
+ else
+ dr_type = SPARC_ELF_DTPMOD_RELOC (htab);
+ if (dr_type == SPARC_ELF_TPOFF_RELOC (htab) && indx == 0)
+ outrel.r_addend = relocation - dtpoff_base (info);
+ else
+ outrel.r_addend = 0;
+ outrel.r_info = SPARC_ELF_R_INFO (htab, NULL, indx, dr_type);
+ sparc_elf_append_rela (output_bfd, htab->elf.srelgot, &outrel);
+
+ if (r_type == R_SPARC_TLS_GD_HI22
+ || r_type == R_SPARC_TLS_GD_LO10)
+ {
+ if (indx == 0)
+ {
+ BFD_ASSERT (! unresolved_reloc);
+ SPARC_ELF_PUT_WORD (htab, output_bfd,
+ relocation - dtpoff_base (info),
+ (htab->elf.sgot->contents + off
+ + SPARC_ELF_WORD_BYTES (htab)));
+ }
+ else
+ {
+ SPARC_ELF_PUT_WORD (htab, output_bfd, 0,
+ (htab->elf.sgot->contents + off
+ + SPARC_ELF_WORD_BYTES (htab)));
+ outrel.r_info = SPARC_ELF_R_INFO (htab, NULL, indx,
+ SPARC_ELF_DTPOFF_RELOC (htab));
+ outrel.r_offset += SPARC_ELF_WORD_BYTES (htab);
+ sparc_elf_append_rela (output_bfd, htab->elf.srelgot,
+ &outrel);
+ }
+ }
+ else if (dr_type == SPARC_ELF_DTPMOD_RELOC (htab))
+ {
+ SPARC_ELF_PUT_WORD (htab, output_bfd, 0,
+ (htab->elf.sgot->contents + off
+ + SPARC_ELF_WORD_BYTES (htab)));
+ }
+ }
+
+ if (off >= (bfd_vma) -2)
+ abort ();
+
+ relocation = htab->elf.sgot->output_offset + off - got_base;
+ unresolved_reloc = FALSE;
+ howto = _bfd_sparc_elf_howto_table + r_type;
+ break;
+
+ case R_SPARC_TLS_LDM_HI22:
+ case R_SPARC_TLS_LDM_LO10:
+ if (! info->shared)
+ {
+ bfd_put_32 (output_bfd, SPARC_NOP, contents + rel->r_offset);
+ continue;
+ }
+ off = htab->tls_ldm_got.offset;
+ htab->tls_ldm_got.offset |= 1;
+ goto r_sparc_tlsldm;
+
+ case R_SPARC_TLS_LDO_HIX22:
+ case R_SPARC_TLS_LDO_LOX10:
+ if (info->shared)
+ {
+ relocation -= dtpoff_base (info);
+ break;
+ }
+
+ r_type = (r_type == R_SPARC_TLS_LDO_HIX22
+ ? R_SPARC_TLS_LE_HIX22 : R_SPARC_TLS_LE_LOX10);
+ /* Fall through. */
+
+ case R_SPARC_TLS_LE_HIX22:
+ case R_SPARC_TLS_LE_LOX10:
+ if (info->shared)
+ {
+ Elf_Internal_Rela outrel;
+ bfd_boolean skip;
+
+ BFD_ASSERT (sreloc != NULL);
+ skip = FALSE;
+ outrel.r_offset =
+ _bfd_elf_section_offset (output_bfd, info, input_section,
+ rel->r_offset);
+ if (outrel.r_offset == (bfd_vma) -1)
+ skip = TRUE;
+ else if (outrel.r_offset == (bfd_vma) -2)
+ skip = TRUE;
+ outrel.r_offset += (input_section->output_section->vma
+ + input_section->output_offset);
+ if (skip)
+ memset (&outrel, 0, sizeof outrel);
+ else
+ {
+ outrel.r_info = SPARC_ELF_R_INFO (htab, NULL, 0, r_type);
+ outrel.r_addend = relocation - dtpoff_base (info)
+ + rel->r_addend;
+ }
+
+ sparc_elf_append_rela (output_bfd, sreloc, &outrel);
+ continue;
+ }
+ relocation = tpoff (info, relocation);
+ break;
+
+ case R_SPARC_TLS_LDM_CALL:
+ if (! info->shared)
+ {
+ /* mov %g0, %o0 */
+ bfd_put_32 (output_bfd, 0x90100000, contents + rel->r_offset);
+ continue;
+ }
+ /* Fall through */
+
+ case R_SPARC_TLS_GD_CALL:
+ tls_type = GOT_UNKNOWN;
+ if (h == NULL && local_got_offsets)
+ tls_type = _bfd_sparc_elf_local_got_tls_type (input_bfd) [r_symndx];
+ else if (h != NULL)
+ tls_type = _bfd_sparc_elf_hash_entry(h)->tls_type;
+ if (! info->shared
+ || (r_type == R_SPARC_TLS_GD_CALL && tls_type == GOT_TLS_IE))
+ {
+ Elf_Internal_Rela *rel2;
+ bfd_vma insn;
+
+ if (!info->shared && (h == NULL || h->dynindx == -1))
+ {
+ /* GD -> LE */
+ bfd_put_32 (output_bfd, SPARC_NOP, contents + rel->r_offset);
+ continue;
+ }
+
+ /* GD -> IE */
+ if (rel + 1 < relend
+ && SPARC_ELF_R_TYPE (rel[1].r_info) == R_SPARC_TLS_GD_ADD
+ && rel[1].r_offset == rel->r_offset + 4
+ && SPARC_ELF_R_SYMNDX (htab, rel[1].r_info) == r_symndx
+ && (((insn = bfd_get_32 (input_bfd,
+ contents + rel[1].r_offset))
+ >> 25) & 0x1f) == 8)
+ {
+ /* We have
+ call __tls_get_addr, %tgd_call(foo)
+ add %reg1, %reg2, %o0, %tgd_add(foo)
+ and change it into IE:
+ {ld,ldx} [%reg1 + %reg2], %o0, %tie_ldx(foo)
+ add %g7, %o0, %o0, %tie_add(foo).
+ add is 0x80000000 | (rd << 25) | (rs1 << 14) | rs2,
+ ld is 0xc0000000 | (rd << 25) | (rs1 << 14) | rs2,
+ ldx is 0xc0580000 | (rd << 25) | (rs1 << 14) | rs2. */
+ bfd_put_32 (output_bfd, insn | (ABI_64_P (output_bfd) ? 0xc0580000 : 0xc0000000),
+ contents + rel->r_offset);
+ bfd_put_32 (output_bfd, 0x9001c008,
+ contents + rel->r_offset + 4);
+ rel++;
+ continue;
+ }
+
+ /* We cannot just overwrite the delay slot instruction,
+ as it might be what puts the %o0 argument to
+ __tls_get_addr into place. So we have to transpose
+ the delay slot with the add we patch in. */
+ insn = bfd_get_32 (input_bfd, contents + rel->r_offset + 4);
+ bfd_put_32 (output_bfd, insn,
+ contents + rel->r_offset);
+ bfd_put_32 (output_bfd, 0x9001c008,
+ contents + rel->r_offset + 4);
+
+ rel2 = rel;
+ while ((rel2 = sparc_elf_find_reloc_at_ofs (rel2 + 1, relend,
+ rel->r_offset + 4))
+ != NULL)
+ {
+ /* If the instruction we moved has a relocation attached to
+ it, adjust the offset so that it will apply to the correct
+ instruction. */
+ rel2->r_offset -= 4;
+ }
+ continue;
+ }
+
+ h = (struct elf_link_hash_entry *)
+ bfd_link_hash_lookup (info->hash, "__tls_get_addr", FALSE,
+ FALSE, TRUE);
+ BFD_ASSERT (h != NULL);
+ r_type = R_SPARC_WPLT30;
+ howto = _bfd_sparc_elf_howto_table + r_type;
+ goto r_sparc_wplt30;
+
+ case R_SPARC_TLS_GD_ADD:
+ tls_type = GOT_UNKNOWN;
+ if (h == NULL && local_got_offsets)
+ tls_type = _bfd_sparc_elf_local_got_tls_type (input_bfd) [r_symndx];
+ else if (h != NULL)
+ tls_type = _bfd_sparc_elf_hash_entry(h)->tls_type;
+ if (! info->shared || tls_type == GOT_TLS_IE)
+ {
+ /* add %reg1, %reg2, %reg3, %tgd_add(foo)
+ changed into IE:
+ {ld,ldx} [%reg1 + %reg2], %reg3, %tie_ldx(foo)
+ or LE:
+ add %g7, %reg2, %reg3. */
+ bfd_vma insn = bfd_get_32 (input_bfd, contents + rel->r_offset);
+ if ((h != NULL && h->dynindx != -1) || info->shared)
+ relocation = insn | (ABI_64_P (output_bfd) ? 0xc0580000 : 0xc0000000);
+ else
+ relocation = (insn & ~0x7c000) | 0x1c000;
+ bfd_put_32 (output_bfd, relocation, contents + rel->r_offset);
+ }
+ continue;
+
+ case R_SPARC_TLS_LDM_ADD:
+ if (! info->shared)
+ bfd_put_32 (output_bfd, SPARC_NOP, contents + rel->r_offset);
+ continue;
+
+ case R_SPARC_TLS_LDO_ADD:
+ if (! info->shared)
+ {
+ /* Change rs1 into %g7. */
+ bfd_vma insn = bfd_get_32 (input_bfd, contents + rel->r_offset);
+ insn = (insn & ~0x7c000) | 0x1c000;
+ bfd_put_32 (output_bfd, insn, contents + rel->r_offset);
+ }
+ continue;
+
+ case R_SPARC_TLS_IE_LD:
+ case R_SPARC_TLS_IE_LDX:
+ if (! info->shared && (h == NULL || h->dynindx == -1))
+ {
+ bfd_vma insn = bfd_get_32 (input_bfd, contents + rel->r_offset);
+ int rs2 = insn & 0x1f;
+ int rd = (insn >> 25) & 0x1f;
+
+ if (rs2 == rd)
+ relocation = SPARC_NOP;
+ else
+ relocation = 0x80100000 | (insn & 0x3e00001f);
+ bfd_put_32 (output_bfd, relocation, contents + rel->r_offset);
+ }
+ continue;
+
+ case R_SPARC_TLS_IE_ADD:
+ /* Totally useless relocation. */
+ continue;
+
+ case R_SPARC_TLS_DTPOFF32:
+ case R_SPARC_TLS_DTPOFF64:
+ relocation -= dtpoff_base (info);
+ break;
+
+ default:
+ break;
+ }
+
+ /* Dynamic relocs are not propagated for SEC_DEBUGGING sections
+ because such sections are not SEC_ALLOC and thus ld.so will
+ not process them. */
+ if (unresolved_reloc
+ && !((input_section->flags & SEC_DEBUGGING) != 0
+ && h->def_dynamic)
+ && _bfd_elf_section_offset (output_bfd, info, input_section,
+ rel->r_offset) != (bfd_vma) -1)
+ (*_bfd_error_handler)
+ (_("%B(%A+0x%lx): unresolvable %s relocation against symbol `%s'"),
+ input_bfd,
+ input_section,
+ (long) rel->r_offset,
+ howto->name,
+ h->root.root.string);
+
+ r = bfd_reloc_continue;
+ if (r_type == R_SPARC_OLO10)
+ {
+ bfd_vma x;
+
+ if (! ABI_64_P (output_bfd))
+ abort ();
+
+ 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 & ~(bfd_vma) 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);
+ }
+ else 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);
+
+ r = bfd_check_overflow (howto->complain_on_overflow,
+ howto->bitsize, howto->rightshift,
+ bfd_arch_bits_per_address (input_bfd),
+ relocation);
+ }
+ else if (r_type == R_SPARC_WDISP10)
+ {
+ 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) & 0x300) << 11)
+ | (((relocation >> 2) & 0xff) << 5));
+ 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);
+ }
+ 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 if (r_type == R_SPARC_TLS_LDO_HIX22
+ || r_type == R_SPARC_TLS_LE_HIX22)
+ {
+ bfd_vma x;
+
+ relocation += rel->r_addend;
+ if (r_type == R_SPARC_TLS_LE_HIX22)
+ relocation ^= MINUS_ONE;
+
+ x = bfd_get_32 (input_bfd, contents + rel->r_offset);
+ x = (x & ~(bfd_vma) 0x3fffff) | ((relocation >> 10) & 0x3fffff);
+ bfd_put_32 (input_bfd, x, contents + rel->r_offset);
+ r = bfd_reloc_ok;
+ }
+ else if (r_type == R_SPARC_TLS_LDO_LOX10
+ || r_type == R_SPARC_TLS_LE_LOX10)
+ {
+ bfd_vma x;
+
+ relocation += rel->r_addend;
+ relocation &= 0x3ff;
+ if (r_type == R_SPARC_TLS_LE_LOX10)
+ relocation |= 0x1c00;
+
+ x = bfd_get_32 (input_bfd, contents + rel->r_offset);
+ x = (x & ~(bfd_vma) 0x1fff) | relocation;
+ bfd_put_32 (input_bfd, x, contents + rel->r_offset);
+
+ r = bfd_reloc_ok;
+ }
+ else if (r_type == R_SPARC_HIX22
+ || r_type == R_SPARC_GOTDATA_HIX22)
+ {
+ bfd_vma x;
+
+ relocation += rel->r_addend;
+ if (r_type == R_SPARC_HIX22
+ || (bfd_signed_vma) relocation < 0)
+ relocation = relocation ^ MINUS_ONE;
+
+ x = bfd_get_32 (input_bfd, contents + rel->r_offset);
+ x = (x & ~(bfd_vma) 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);
+ }
+ else if (r_type == R_SPARC_LOX10
+ || r_type == R_SPARC_GOTDATA_LOX10)
+ {
+ bfd_vma x;
+
+ relocation += rel->r_addend;
+ if (r_type == R_SPARC_LOX10
+ || (bfd_signed_vma) relocation < 0)
+ relocation = (relocation & 0x3ff) | 0x1c00;
+ else
+ relocation = (relocation & 0x3ff);
+
+ x = bfd_get_32 (input_bfd, contents + rel->r_offset);
+ x = (x & ~(bfd_vma) 0x1fff) | relocation;
+ bfd_put_32 (input_bfd, x, contents + rel->r_offset);
+
+ r = bfd_reloc_ok;
+ }
+ else if ((r_type == R_SPARC_WDISP30 || r_type == R_SPARC_WPLT30)
+ && sec_do_relax (input_section)
+ && rel->r_offset + 4 < input_section->size)
+ {
+#define G0 0
+#define O7 15
+#define XCC (2 << 20)
+#define COND(x) (((x)&0xf)<<25)
+#define CONDA COND(0x8)
+#define INSN_BPA (F2(0,1) | CONDA | BPRED | XCC)
+#define INSN_BA (F2(0,2) | CONDA)
+#define INSN_OR F3(2, 0x2, 0)
+#define INSN_NOP F2(0,4)
+
+ bfd_vma x, y;
+
+ /* If the instruction is a call with either:
+ restore
+ arithmetic instruction with rd == %o7
+ where rs1 != %o7 and rs2 if it is register != %o7
+ then we can optimize if the call destination is near
+ by changing the call into a branch always. */
+ x = bfd_get_32 (input_bfd, contents + rel->r_offset);
+ y = bfd_get_32 (input_bfd, contents + rel->r_offset + 4);
+ if ((x & OP(~0)) == OP(1) && (y & OP(~0)) == OP(2))
+ {
+ if (((y & OP3(~0)) == OP3(0x3d) /* restore */
+ || ((y & OP3(0x28)) == 0 /* arithmetic */
+ && (y & RD(~0)) == RD(O7)))
+ && (y & RS1(~0)) != RS1(O7)
+ && ((y & F3I(~0))
+ || (y & RS2(~0)) != RS2(O7)))
+ {
+ bfd_vma reloc;
+
+ reloc = relocation + rel->r_addend - rel->r_offset;
+ reloc -= (input_section->output_section->vma
+ + input_section->output_offset);
+
+ /* Ensure the branch fits into simm22. */
+ if ((reloc & 3) == 0
+ && ((reloc & ~(bfd_vma)0x7fffff) == 0
+ || ((reloc | 0x7fffff) == ~(bfd_vma)0)))
+ {
+ reloc >>= 2;
+
+ /* Check whether it fits into simm19. */
+ if (((reloc & 0x3c0000) == 0
+ || (reloc & 0x3c0000) == 0x3c0000)
+ && (ABI_64_P (output_bfd)
+ || elf_elfheader (output_bfd)->e_flags & EF_SPARC_32PLUS))
+ x = INSN_BPA | (reloc & 0x7ffff); /* ba,pt %xcc */
+ else
+ x = INSN_BA | (reloc & 0x3fffff); /* ba */
+ bfd_put_32 (input_bfd, x, contents + rel->r_offset);
+ r = bfd_reloc_ok;
+ if (rel->r_offset >= 4
+ && (y & (0xffffffff ^ RS1(~0)))
+ == (INSN_OR | RD(O7) | RS2(G0)))
+ {
+ bfd_vma z;
+ unsigned int reg;
+
+ z = bfd_get_32 (input_bfd,
+ contents + rel->r_offset - 4);
+ if ((z & (0xffffffff ^ RD(~0)))
+ != (INSN_OR | RS1(O7) | RS2(G0)))
+ break;
+
+ /* The sequence was
+ or %o7, %g0, %rN
+ call foo
+ or %rN, %g0, %o7
+
+ If call foo was replaced with ba, replace
+ or %rN, %g0, %o7 with nop. */
+
+ reg = (y & RS1(~0)) >> 14;
+ if (reg != ((z & RD(~0)) >> 25)
+ || reg == G0 || reg == O7)
+ break;
+
+ bfd_put_32 (input_bfd, (bfd_vma) INSN_NOP,
+ contents + rel->r_offset + 4);
+ }
+
+ }
+ }
+ }
+ }
+
+ if (r == bfd_reloc_continue)
+ {
+do_relocation:
+ 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;
+
+ /* The Solaris native linker silently disregards overflows.
+ We don't, but this breaks stabs debugging info, whose
+ relocations are only 32-bits wide. Ignore overflows in
+ this case and also for discarded entries. */
+ if ((r_type == R_SPARC_32
+ || r_type == R_SPARC_UA32
+ || r_type == R_SPARC_DISP32)
+ && (((input_section->flags & SEC_DEBUGGING) != 0
+ && strcmp (bfd_section_name (input_bfd,
+ input_section),
+ ".stab") == 0)
+ || _bfd_elf_section_offset (output_bfd, info,
+ input_section,
+ rel->r_offset)
+ == (bfd_vma)-1))
+ break;
+
+ if (h != NULL)
+ {
+ /* 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. */
+ if (h->root.type == bfd_link_hash_undefweak
+ && howto->pc_relative)
+ break;
+
+ name = NULL;
+ }
+ 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, (h ? &h->root : NULL), name, howto->name,
+ (bfd_vma) 0, input_bfd, input_section,
+ rel->r_offset)))
+ return FALSE;
+ }
+ break;
+ }
+ }
+ }
+
+ return TRUE;
+}
+
+/* Build a VxWorks PLT entry. PLT_INDEX is the index of the PLT entry
+ and PLT_OFFSET is the byte offset from the start of .plt. GOT_OFFSET
+ is the offset of the associated .got.plt entry from
+ _GLOBAL_OFFSET_TABLE_. */
+
+static void
+sparc_vxworks_build_plt_entry (bfd *output_bfd, struct bfd_link_info *info,
+ bfd_vma plt_offset, bfd_vma plt_index,
+ bfd_vma got_offset)
+{
+ bfd_vma got_base;
+ const bfd_vma *plt_entry;
+ struct _bfd_sparc_elf_link_hash_table *htab;
+ bfd_byte *loc;
+ Elf_Internal_Rela rela;
+
+ htab = _bfd_sparc_elf_hash_table (info);
+ BFD_ASSERT (htab != NULL);
+
+ if (info->shared)
+ {
+ plt_entry = sparc_vxworks_shared_plt_entry;
+ got_base = 0;
+ }
+ else
+ {
+ plt_entry = sparc_vxworks_exec_plt_entry;
+ got_base = (htab->elf.hgot->root.u.def.value
+ + htab->elf.hgot->root.u.def.section->output_offset
+ + htab->elf.hgot->root.u.def.section->output_section->vma);
+ }
+
+ /* Fill in the entry in the procedure linkage table. */
+ bfd_put_32 (output_bfd, plt_entry[0] + ((got_base + got_offset) >> 10),
+ htab->elf.splt->contents + plt_offset);
+ bfd_put_32 (output_bfd, plt_entry[1] + ((got_base + got_offset) & 0x3ff),
+ htab->elf.splt->contents + plt_offset + 4);
+ bfd_put_32 (output_bfd, plt_entry[2],
+ htab->elf.splt->contents + plt_offset + 8);
+ bfd_put_32 (output_bfd, plt_entry[3],
+ htab->elf.splt->contents + plt_offset + 12);
+ bfd_put_32 (output_bfd, plt_entry[4],
+ htab->elf.splt->contents + plt_offset + 16);
+ bfd_put_32 (output_bfd, plt_entry[5] + (plt_index >> 10),
+ htab->elf.splt->contents + plt_offset + 20);
+ /* PC-relative displacement for a branch to the start of
+ the PLT section. */
+ bfd_put_32 (output_bfd, plt_entry[6] + (((-plt_offset - 24) >> 2)
+ & 0x003fffff),
+ htab->elf.splt->contents + plt_offset + 24);
+ bfd_put_32 (output_bfd, plt_entry[7] + (plt_index & 0x3ff),
+ htab->elf.splt->contents + plt_offset + 28);
+
+ /* Fill in the .got.plt entry, pointing initially at the
+ second half of the PLT entry. */
+ BFD_ASSERT (htab->elf.sgotplt != NULL);
+ bfd_put_32 (output_bfd,
+ htab->elf.splt->output_section->vma
+ + htab->elf.splt->output_offset
+ + plt_offset + 20,
+ htab->elf.sgotplt->contents + got_offset);
+
+ /* Add relocations to .rela.plt.unloaded. */
+ if (!info->shared)
+ {
+ loc = (htab->srelplt2->contents
+ + (2 + 3 * plt_index) * sizeof (Elf32_External_Rela));
+
+ /* Relocate the initial sethi. */
+ rela.r_offset = (htab->elf.splt->output_section->vma
+ + htab->elf.splt->output_offset
+ + plt_offset);
+ rela.r_info = ELF32_R_INFO (htab->elf.hgot->indx, R_SPARC_HI22);
+ rela.r_addend = got_offset;
+ bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
+ loc += sizeof (Elf32_External_Rela);
+
+ /* Likewise the following or. */
+ rela.r_offset += 4;
+ rela.r_info = ELF32_R_INFO (htab->elf.hgot->indx, R_SPARC_LO10);
+ bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
+ loc += sizeof (Elf32_External_Rela);
+
+ /* Relocate the .got.plt entry. */
+ rela.r_offset = (htab->elf.sgotplt->output_section->vma
+ + htab->elf.sgotplt->output_offset
+ + got_offset);
+ rela.r_info = ELF32_R_INFO (htab->elf.hplt->indx, R_SPARC_32);
+ rela.r_addend = plt_offset + 20;
+ bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
+ }
+}
+
+/* Finish up dynamic symbol handling. We set the contents of various
+ dynamic sections here. */
+
+bfd_boolean
+_bfd_sparc_elf_finish_dynamic_symbol (bfd *output_bfd,
+ struct bfd_link_info *info,
+ struct elf_link_hash_entry *h,
+ Elf_Internal_Sym *sym)
+{
+ struct _bfd_sparc_elf_link_hash_table *htab;
+ const struct elf_backend_data *bed;
+
+ htab = _bfd_sparc_elf_hash_table (info);
+ BFD_ASSERT (htab != NULL);
+ bed = get_elf_backend_data (output_bfd);
+
+ if (h->plt.offset != (bfd_vma) -1)
+ {
+ asection *splt;
+ asection *srela;
+ Elf_Internal_Rela rela;
+ bfd_byte *loc;
+ bfd_vma r_offset, got_offset;
+ int rela_index;
+
+ /* When building a static executable, use .iplt and
+ .rela.iplt sections for STT_GNU_IFUNC symbols. */
+ if (htab->elf.splt != NULL)
+ {
+ splt = htab->elf.splt;
+ srela = htab->elf.srelplt;
+ }
+ else
+ {
+ splt = htab->elf.iplt;
+ srela = htab->elf.irelplt;
+ }
+
+ if (splt == NULL || srela == NULL)
+ abort ();
+
+ /* Fill in the entry in the .rela.plt section. */
+ if (htab->is_vxworks)
+ {
+ /* Work out the index of this PLT entry. */
+ rela_index = ((h->plt.offset - htab->plt_header_size)
+ / htab->plt_entry_size);
+
+ /* Calculate the offset of the associated .got.plt entry.
+ The first three entries are reserved. */
+ got_offset = (rela_index + 3) * 4;
+
+ sparc_vxworks_build_plt_entry (output_bfd, info, h->plt.offset,
+ rela_index, got_offset);
+
+
+ /* On VxWorks, the relocation points to the .got.plt entry,
+ not the .plt entry. */
+ rela.r_offset = (htab->elf.sgotplt->output_section->vma
+ + htab->elf.sgotplt->output_offset
+ + got_offset);
+ rela.r_addend = 0;
+ rela.r_info = SPARC_ELF_R_INFO (htab, NULL, h->dynindx,
+ R_SPARC_JMP_SLOT);
+ }
+ else
+ {
+ bfd_boolean ifunc = FALSE;
+
+ /* Fill in the entry in the procedure linkage table. */
+ rela_index = SPARC_ELF_BUILD_PLT_ENTRY (htab, output_bfd, splt,
+ h->plt.offset, splt->size,
+ &r_offset);
+
+ if (h == NULL
+ || h->dynindx == -1
+ || ((info->executable
+ || ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
+ && h->def_regular
+ && h->type == STT_GNU_IFUNC))
+ {
+ ifunc = TRUE;
+ BFD_ASSERT (h == NULL
+ || (h->type == STT_GNU_IFUNC
+ && h->def_regular
+ && (h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak)));
+ }
+
+ rela.r_offset = r_offset
+ + (splt->output_section->vma + splt->output_offset);
+ if (ABI_64_P (output_bfd)
+ && h->plt.offset >= (PLT64_LARGE_THRESHOLD * PLT64_ENTRY_SIZE))
+ {
+ if (ifunc)
+ {
+ rela.r_addend = (h->root.u.def.section->output_section->vma
+ + h->root.u.def.section->output_offset
+ + h->root.u.def.value);
+ rela.r_info = SPARC_ELF_R_INFO (htab, NULL, 0,
+ R_SPARC_IRELATIVE);
+ }
+ else
+ {
+ rela.r_addend = (-(h->plt.offset + 4)
+ - splt->output_section->vma
+ - splt->output_offset);
+ rela.r_info = SPARC_ELF_R_INFO (htab, NULL, h->dynindx,
+ R_SPARC_JMP_SLOT);
+ }
+ }
+ else
+ {
+ if (ifunc)
+ {
+ rela.r_addend = (h->root.u.def.section->output_section->vma
+ + h->root.u.def.section->output_offset
+ + h->root.u.def.value);
+ rela.r_info = SPARC_ELF_R_INFO (htab, NULL, 0,
+ R_SPARC_JMP_IREL);
+ }
+ else
+ {
+ rela.r_addend = 0;
+ rela.r_info = SPARC_ELF_R_INFO (htab, NULL, h->dynindx,
+ R_SPARC_JMP_SLOT);
+ }
+ }
+ }
+
+ /* Adjust for the first 4 reserved elements in the .plt section
+ when setting the offset in the .rela.plt section.
+ Sun forgot to read their own ABI and copied elf32-sparc behaviour,
+ thus .plt[4] has corresponding .rela.plt[0] and so on. */
+
+ loc = srela->contents;
+ loc += rela_index * bed->s->sizeof_rela;
+ bed->s->swap_reloca_out (output_bfd, &rela, loc);
+
+ if (!h->def_regular)
+ {
+ /* Mark the symbol as undefined, rather than as defined in
+ the .plt section. Leave the value alone. */
+ sym->st_shndx = SHN_UNDEF;
+ /* If the symbol is weak, we do need to clear the value.
+ Otherwise, the PLT entry would provide a definition for
+ the symbol even if the symbol wasn't defined anywhere,
+ and so the symbol would never be NULL. */
+ if (!h->ref_regular_nonweak)
+ sym->st_value = 0;
+ }
+ }
+
+ if (h->got.offset != (bfd_vma) -1
+ && _bfd_sparc_elf_hash_entry(h)->tls_type != GOT_TLS_GD
+ && _bfd_sparc_elf_hash_entry(h)->tls_type != GOT_TLS_IE)
+ {
+ asection *sgot;
+ asection *srela;
+ Elf_Internal_Rela rela;
+
+ /* This symbol has an entry in the GOT. Set it up. */
+
+ sgot = htab->elf.sgot;
+ srela = htab->elf.srelgot;
+ BFD_ASSERT (sgot != NULL && srela != NULL);
+
+ rela.r_offset = (sgot->output_section->vma
+ + sgot->output_offset
+ + (h->got.offset &~ (bfd_vma) 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
+ && h->type == STT_GNU_IFUNC
+ && h->def_regular)
+ {
+ asection *plt;
+
+ /* We load the GOT entry with the PLT entry. */
+ plt = htab->elf.splt ? htab->elf.splt : htab->elf.iplt;
+ SPARC_ELF_PUT_WORD (htab, output_bfd,
+ (plt->output_section->vma
+ + plt->output_offset + h->plt.offset),
+ htab->elf.sgot->contents
+ + (h->got.offset & ~(bfd_vma) 1));
+ return TRUE;
+ }
+ else if (info->shared
+ && SYMBOL_REFERENCES_LOCAL (info, h))
+ {
+ asection *sec = h->root.u.def.section;
+ if (h->type == STT_GNU_IFUNC)
+ rela.r_info = SPARC_ELF_R_INFO (htab, NULL, 0, R_SPARC_IRELATIVE);
+ else
+ rela.r_info = SPARC_ELF_R_INFO (htab, NULL, 0, R_SPARC_RELATIVE);
+ rela.r_addend = (h->root.u.def.value
+ + sec->output_section->vma
+ + sec->output_offset);
+ }
+ else
+ {
+ rela.r_info = SPARC_ELF_R_INFO (htab, NULL, h->dynindx, R_SPARC_GLOB_DAT);
+ rela.r_addend = 0;
+ }
+
+ SPARC_ELF_PUT_WORD (htab, output_bfd, 0,
+ sgot->contents + (h->got.offset & ~(bfd_vma) 1));
+ sparc_elf_append_rela (output_bfd, srela, &rela);
+ }
+
+ if (h->needs_copy)
+ {
+ asection *s;
+ Elf_Internal_Rela rela;
+
+ /* This symbols needs a copy reloc. Set it up. */
+ BFD_ASSERT (h->dynindx != -1);
+
+ s = bfd_get_linker_section (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 = SPARC_ELF_R_INFO (htab, NULL, h->dynindx, R_SPARC_COPY);
+ rela.r_addend = 0;
+ sparc_elf_append_rela (output_bfd, s, &rela);
+ }
+
+ /* Mark some specially defined symbols as absolute. On VxWorks,
+ _GLOBAL_OFFSET_TABLE_ is not absolute: it is relative to the
+ ".got" section. Likewise _PROCEDURE_LINKAGE_TABLE_ and ".plt". */
+ if (sym != NULL
+ && (h == htab->elf.hdynamic
+ || (!htab->is_vxworks
+ && (h == htab->elf.hgot || h == htab->elf.hplt))))
+ sym->st_shndx = SHN_ABS;
+
+ return TRUE;
+}
+
+/* Finish up the dynamic sections. */
+
+static bfd_boolean
+sparc_finish_dyn (bfd *output_bfd, struct bfd_link_info *info,
+ bfd *dynobj, asection *sdyn,
+ asection *splt ATTRIBUTE_UNUSED)
+{
+ struct _bfd_sparc_elf_link_hash_table *htab;
+ const struct elf_backend_data *bed;
+ bfd_byte *dyncon, *dynconend;
+ size_t dynsize;
+ int stt_regidx = -1;
+ bfd_boolean abi_64_p;
+
+ htab = _bfd_sparc_elf_hash_table (info);
+ BFD_ASSERT (htab != NULL);
+ bed = get_elf_backend_data (output_bfd);
+ dynsize = bed->s->sizeof_dyn;
+ dynconend = sdyn->contents + sdyn->size;
+ abi_64_p = ABI_64_P (output_bfd);
+ for (dyncon = sdyn->contents; dyncon < dynconend; dyncon += dynsize)
+ {
+ Elf_Internal_Dyn dyn;
+ const char *name;
+ bfd_boolean size;
+
+ bed->s->swap_dyn_in (dynobj, dyncon, &dyn);
+
+ if (htab->is_vxworks && dyn.d_tag == DT_RELASZ)
+ {
+ /* On VxWorks, DT_RELASZ should not include the relocations
+ in .rela.plt. */
+ if (htab->elf.srelplt)
+ {
+ dyn.d_un.d_val -= htab->elf.srelplt->size;
+ bed->s->swap_dyn_out (output_bfd, &dyn, dyncon);
+ }
+ }
+ else if (htab->is_vxworks && dyn.d_tag == DT_PLTGOT)
+ {
+ /* On VxWorks, DT_PLTGOT should point to the start of the GOT,
+ not to the start of the PLT. */
+ if (htab->elf.sgotplt)
+ {
+ dyn.d_un.d_val = (htab->elf.sgotplt->output_section->vma
+ + htab->elf.sgotplt->output_offset);
+ bed->s->swap_dyn_out (output_bfd, &dyn, dyncon);
+ }
+ }
+ else if (htab->is_vxworks
+ && elf_vxworks_finish_dynamic_entry (output_bfd, &dyn))
+ bed->s->swap_dyn_out (output_bfd, &dyn, dyncon);
+ else if (abi_64_p && dyn.d_tag == DT_SPARC_REGISTER)
+ {
+ if (stt_regidx == -1)
+ {
+ stt_regidx =
+ _bfd_elf_link_lookup_local_dynindx (info, output_bfd, -1);
+ if (stt_regidx == -1)
+ return FALSE;
+ }
+ dyn.d_un.d_val = stt_regidx++;
+ bed->s->swap_dyn_out (output_bfd, &dyn, dyncon);
+ }
+ else
+ {
+ 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
+ dyn.d_un.d_val = s->size;
+ }
+ bed->s->swap_dyn_out (output_bfd, &dyn, dyncon);
+ }
+ }
+ }
+ return TRUE;
+}
+
+/* Install the first PLT entry in a VxWorks executable and make sure that
+ .rela.plt.unloaded relocations have the correct symbol indexes. */
+
+static void
+sparc_vxworks_finish_exec_plt (bfd *output_bfd, struct bfd_link_info *info)
+{
+ struct _bfd_sparc_elf_link_hash_table *htab;
+ Elf_Internal_Rela rela;
+ bfd_vma got_base;
+ bfd_byte *loc;
+
+ htab = _bfd_sparc_elf_hash_table (info);
+ BFD_ASSERT (htab != NULL);
+
+ /* Calculate the absolute value of _GLOBAL_OFFSET_TABLE_. */
+ got_base = (htab->elf.hgot->root.u.def.section->output_section->vma
+ + htab->elf.hgot->root.u.def.section->output_offset
+ + htab->elf.hgot->root.u.def.value);
+
+ /* Install the initial PLT entry. */
+ bfd_put_32 (output_bfd,
+ sparc_vxworks_exec_plt0_entry[0] + ((got_base + 8) >> 10),
+ htab->elf.splt->contents);
+ bfd_put_32 (output_bfd,
+ sparc_vxworks_exec_plt0_entry[1] + ((got_base + 8) & 0x3ff),
+ htab->elf.splt->contents + 4);
+ bfd_put_32 (output_bfd,
+ sparc_vxworks_exec_plt0_entry[2],
+ htab->elf.splt->contents + 8);
+ bfd_put_32 (output_bfd,
+ sparc_vxworks_exec_plt0_entry[3],
+ htab->elf.splt->contents + 12);
+ bfd_put_32 (output_bfd,
+ sparc_vxworks_exec_plt0_entry[4],
+ htab->elf.splt->contents + 16);
+
+ loc = htab->srelplt2->contents;
+
+ /* Add an unloaded relocation for the initial entry's "sethi". */
+ rela.r_offset = (htab->elf.splt->output_section->vma
+ + htab->elf.splt->output_offset);
+ rela.r_info = ELF32_R_INFO (htab->elf.hgot->indx, R_SPARC_HI22);
+ rela.r_addend = 8;
+ bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
+ loc += sizeof (Elf32_External_Rela);
+
+ /* Likewise the following "or". */
+ rela.r_offset += 4;
+ rela.r_info = ELF32_R_INFO (htab->elf.hgot->indx, R_SPARC_LO10);
+ bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
+ loc += sizeof (Elf32_External_Rela);
+
+ /* Fix up the remaining .rela.plt.unloaded relocations. They may have
+ the wrong symbol index for _G_O_T_ or _P_L_T_ depending on the order
+ in which symbols were output. */
+ while (loc < htab->srelplt2->contents + htab->srelplt2->size)
+ {
+ Elf_Internal_Rela rel;
+
+ /* The entry's initial "sethi" (against _G_O_T_). */
+ bfd_elf32_swap_reloc_in (output_bfd, loc, &rel);
+ rel.r_info = ELF32_R_INFO (htab->elf.hgot->indx, R_SPARC_HI22);
+ bfd_elf32_swap_reloc_out (output_bfd, &rel, loc);
+ loc += sizeof (Elf32_External_Rela);
+
+ /* The following "or" (also against _G_O_T_). */
+ bfd_elf32_swap_reloc_in (output_bfd, loc, &rel);
+ rel.r_info = ELF32_R_INFO (htab->elf.hgot->indx, R_SPARC_LO10);
+ bfd_elf32_swap_reloc_out (output_bfd, &rel, loc);
+ loc += sizeof (Elf32_External_Rela);
+
+ /* The .got.plt entry (against _P_L_T_). */
+ bfd_elf32_swap_reloc_in (output_bfd, loc, &rel);
+ rel.r_info = ELF32_R_INFO (htab->elf.hplt->indx, R_SPARC_32);
+ bfd_elf32_swap_reloc_out (output_bfd, &rel, loc);
+ loc += sizeof (Elf32_External_Rela);
+ }
+}
+
+/* Install the first PLT entry in a VxWorks shared object. */
+
+static void
+sparc_vxworks_finish_shared_plt (bfd *output_bfd, struct bfd_link_info *info)
+{
+ struct _bfd_sparc_elf_link_hash_table *htab;
+ unsigned int i;
+
+ htab = _bfd_sparc_elf_hash_table (info);
+ BFD_ASSERT (htab != NULL);
+
+ for (i = 0; i < ARRAY_SIZE (sparc_vxworks_shared_plt0_entry); i++)
+ bfd_put_32 (output_bfd, sparc_vxworks_shared_plt0_entry[i],
+ htab->elf.splt->contents + i * 4);
+}
+
+/* Finish up local dynamic symbol handling. We set the contents of
+ various dynamic sections here. */
+
+static bfd_boolean
+finish_local_dynamic_symbol (void **slot, void *inf)
+{
+ struct elf_link_hash_entry *h
+ = (struct elf_link_hash_entry *) *slot;
+ struct bfd_link_info *info
+ = (struct bfd_link_info *) inf;
+
+ return _bfd_sparc_elf_finish_dynamic_symbol (info->output_bfd, info,
+ h, NULL);
+}
+
+bfd_boolean
+_bfd_sparc_elf_finish_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
+{
+ bfd *dynobj;
+ asection *sdyn;
+ struct _bfd_sparc_elf_link_hash_table *htab;
+
+ htab = _bfd_sparc_elf_hash_table (info);
+ BFD_ASSERT (htab != NULL);
+ dynobj = htab->elf.dynobj;
+
+ sdyn = bfd_get_linker_section (dynobj, ".dynamic");
+
+ if (elf_hash_table (info)->dynamic_sections_created)
+ {
+ asection *splt;
+
+ splt = htab->elf.splt;
+ BFD_ASSERT (splt != NULL && sdyn != NULL);
+
+ if (!sparc_finish_dyn (output_bfd, info, dynobj, sdyn, splt))
+ return FALSE;
+
+ /* Initialize the contents of the .plt section. */
+ if (splt->size > 0)
+ {
+ if (htab->is_vxworks)
+ {
+ if (info->shared)
+ sparc_vxworks_finish_shared_plt (output_bfd, info);
+ else
+ sparc_vxworks_finish_exec_plt (output_bfd, info);
+ }
+ else
+ {
+ memset (splt->contents, 0, htab->plt_header_size);
+ if (!ABI_64_P (output_bfd))
+ bfd_put_32 (output_bfd, (bfd_vma) SPARC_NOP,
+ splt->contents + splt->size - 4);
+ }
+ }
+
+ if (elf_section_data (splt->output_section) != NULL)
+ elf_section_data (splt->output_section)->this_hdr.sh_entsize
+ = ((htab->is_vxworks || !ABI_64_P (output_bfd))
+ ? 0 : htab->plt_entry_size);
+ }
+
+ /* Set the first entry in the global offset table to the address of
+ the dynamic section. */
+ if (htab->elf.sgot && htab->elf.sgot->size > 0)
+ {
+ bfd_vma val = (sdyn ?
+ sdyn->output_section->vma + sdyn->output_offset :
+ 0);
+
+ SPARC_ELF_PUT_WORD (htab, output_bfd, val, htab->elf.sgot->contents);
+ }
+
+ if (htab->elf.sgot)
+ elf_section_data (htab->elf.sgot->output_section)->this_hdr.sh_entsize =
+ SPARC_ELF_WORD_BYTES (htab);
+
+ /* Fill PLT and GOT entries for local STT_GNU_IFUNC symbols. */
+ htab_traverse (htab->loc_hash_table, finish_local_dynamic_symbol, info);
+
+ return TRUE;
+}
+
+
+/* Set the right machine number for a SPARC ELF file. */
+
+bfd_boolean
+_bfd_sparc_elf_object_p (bfd *abfd)
+{
+ if (ABI_64_P (abfd))
+ {
+ unsigned long mach = bfd_mach_sparc_v9;
+
+ if (elf_elfheader (abfd)->e_flags & EF_SPARC_SUN_US3)
+ mach = bfd_mach_sparc_v9b;
+ else 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);
+ }
+ else
+ {
+ if (elf_elfheader (abfd)->e_machine == EM_SPARC32PLUS)
+ {
+ if (elf_elfheader (abfd)->e_flags & EF_SPARC_SUN_US3)
+ return bfd_default_set_arch_mach (abfd, bfd_arch_sparc,
+ bfd_mach_sparc_v8plusb);
+ else 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);
+ }
+}
+
+/* Return address for Ith PLT stub in section PLT, for relocation REL
+ or (bfd_vma) -1 if it should not be included. */
+
+bfd_vma
+_bfd_sparc_elf_plt_sym_val (bfd_vma i, const asection *plt, const arelent *rel)
+{
+ if (ABI_64_P (plt->owner))
+ {
+ bfd_vma j;
+
+ i += PLT64_HEADER_SIZE / PLT64_ENTRY_SIZE;
+ if (i < PLT64_LARGE_THRESHOLD)
+ return plt->vma + i * PLT64_ENTRY_SIZE;
+
+ j = (i - PLT64_LARGE_THRESHOLD) % 160;
+ i -= j;
+ return plt->vma + i * PLT64_ENTRY_SIZE + j * 4 * 6;
+ }
+ else
+ return rel->address;
+}
+
+/* Merge backend specific data from an object file to the output
+ object file when linking. */
+
+bfd_boolean
+_bfd_sparc_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
+{
+ obj_attribute *in_attr, *in_attrs;
+ obj_attribute *out_attr, *out_attrs;
+
+ if (!elf_known_obj_attributes_proc (obfd)[0].i)
+ {
+ /* This is the first object. Copy the attributes. */
+ _bfd_elf_copy_obj_attributes (ibfd, obfd);
+
+ /* Use the Tag_null value to indicate the attributes have been
+ initialized. */
+ elf_known_obj_attributes_proc (obfd)[0].i = 1;
+
+ return TRUE;
+ }
+
+ in_attrs = elf_known_obj_attributes (ibfd)[OBJ_ATTR_GNU];
+ out_attrs = elf_known_obj_attributes (obfd)[OBJ_ATTR_GNU];
+
+ in_attr = &in_attrs[Tag_GNU_Sparc_HWCAPS];
+ out_attr = &out_attrs[Tag_GNU_Sparc_HWCAPS];
+
+ out_attr->i |= in_attr->i;
+ out_attr->type = 1;
+
+ in_attr = &in_attrs[Tag_GNU_Sparc_HWCAPS2];
+ out_attr = &out_attrs[Tag_GNU_Sparc_HWCAPS2];
+
+ out_attr->i |= in_attr->i;
+ out_attr->type = 1;
+
+
+ /* Merge Tag_compatibility attributes and any common GNU ones. */
+ _bfd_elf_merge_object_attributes (ibfd, obfd);
+
+ return TRUE;
+}
diff --git a/bfd/elfxx-sparc.h b/bfd/elfxx-sparc.h
new file mode 100644
index 0000000..cf1991b
--- /dev/null
+++ b/bfd/elfxx-sparc.h
@@ -0,0 +1,148 @@
+/* SPARC ELF specific backend routines.
+ Copyright (C) 2005-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "elf/common.h"
+#include "elf/internal.h"
+
+struct _bfd_sparc_elf_section_data
+{
+ struct bfd_elf_section_data elf;
+ unsigned int do_relax, reloc_count;
+};
+
+#define sec_do_relax(sec) \
+ ((struct _bfd_sparc_elf_section_data *) elf_section_data (sec))->do_relax
+#define canon_reloc_count(sec) \
+ ((struct _bfd_sparc_elf_section_data *) elf_section_data (sec))->reloc_count
+
+struct _bfd_sparc_elf_app_reg
+{
+ unsigned char bind;
+ unsigned short shndx;
+ bfd *abfd;
+ char *name;
+};
+
+/* Sparc ELF linker hash table. */
+
+struct _bfd_sparc_elf_link_hash_table
+{
+ struct elf_link_hash_table elf;
+
+ /* Short-cuts to get to dynamic linker sections. */
+ asection *sdynbss;
+ asection *srelbss;
+
+ union
+ {
+ bfd_signed_vma refcount;
+ bfd_vma offset;
+ } tls_ldm_got;
+
+ /* Small local sym cache. */
+ struct sym_cache sym_cache;
+
+ /* Used by local STT_GNU_IFUNC symbols. */
+ htab_t loc_hash_table;
+ void *loc_hash_memory;
+
+ /* True if the target system is VxWorks. */
+ int is_vxworks;
+
+ /* The (unloaded but important) .rela.plt.unloaded section, for VxWorks. */
+ asection *srelplt2;
+
+ void (*put_word) (bfd *, bfd_vma, void *);
+ bfd_vma (*r_info) (Elf_Internal_Rela *, bfd_vma, bfd_vma);
+ bfd_vma (*r_symndx) (bfd_vma);
+ int (*build_plt_entry) (bfd *, asection *, bfd_vma, bfd_vma, bfd_vma *);
+ const char *dynamic_interpreter;
+ int dynamic_interpreter_size;
+ unsigned int word_align_power;
+ unsigned int align_power_max;
+ unsigned int plt_header_size;
+ unsigned int plt_entry_size;
+ int bytes_per_word;
+ int bytes_per_rela;
+ int dtpoff_reloc;
+ int dtpmod_reloc;
+ int tpoff_reloc;
+
+ struct _bfd_sparc_elf_app_reg app_regs [4];
+};
+
+/* Get the SPARC ELF linker hash table from a link_info structure. */
+
+#define _bfd_sparc_elf_hash_table(p) \
+ (elf_hash_table_id ((struct elf_link_hash_table *) ((p)->hash)) \
+ == SPARC_ELF_DATA ? ((struct _bfd_sparc_elf_link_hash_table *) ((p)->hash)) : NULL)
+
+extern reloc_howto_type *_bfd_sparc_elf_reloc_type_lookup
+ (bfd *, bfd_reloc_code_real_type);
+extern reloc_howto_type *_bfd_sparc_elf_reloc_name_lookup
+ (bfd *, const char *);
+extern void _bfd_sparc_elf_info_to_howto
+ (bfd *, arelent *, Elf_Internal_Rela *);
+extern reloc_howto_type *_bfd_sparc_elf_info_to_howto_ptr
+ (unsigned int);
+extern bfd_boolean _bfd_sparc_elf_mkobject
+ (bfd *);
+extern struct bfd_link_hash_table *_bfd_sparc_elf_link_hash_table_create
+ (bfd *);
+extern bfd_boolean _bfd_sparc_elf_create_dynamic_sections
+ (bfd *, struct bfd_link_info *);
+extern void _bfd_sparc_elf_copy_indirect_symbol
+ (struct bfd_link_info *,
+ struct elf_link_hash_entry *,
+ struct elf_link_hash_entry *);
+extern bfd_boolean _bfd_sparc_elf_check_relocs
+ (bfd *, struct bfd_link_info *,
+ asection *, const Elf_Internal_Rela *);
+extern asection *_bfd_sparc_elf_gc_mark_hook
+ (asection *, struct bfd_link_info *,
+ Elf_Internal_Rela *, struct elf_link_hash_entry *,
+ Elf_Internal_Sym *);
+extern bfd_boolean _bfd_sparc_elf_gc_sweep_hook
+ (bfd *, struct bfd_link_info *,
+ asection *, const Elf_Internal_Rela *);
+extern bfd_boolean _bfd_sparc_elf_adjust_dynamic_symbol
+ (struct bfd_link_info *, struct elf_link_hash_entry *);
+extern bfd_boolean _bfd_sparc_elf_omit_section_dynsym
+ (bfd *, struct bfd_link_info *, asection *);
+extern bfd_boolean _bfd_sparc_elf_size_dynamic_sections
+ (bfd *, struct bfd_link_info *);
+extern bfd_boolean _bfd_sparc_elf_new_section_hook
+ (bfd *, asection *);
+extern bfd_boolean _bfd_sparc_elf_relax_section
+ (bfd *, struct bfd_section *, struct bfd_link_info *, bfd_boolean *);
+extern bfd_boolean _bfd_sparc_elf_relocate_section
+ (bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
+ Elf_Internal_Rela *, Elf_Internal_Sym *, asection **);
+extern bfd_boolean _bfd_sparc_elf_finish_dynamic_symbol
+ (bfd *, struct bfd_link_info *, struct elf_link_hash_entry *,
+ Elf_Internal_Sym *sym);
+extern bfd_boolean _bfd_sparc_elf_finish_dynamic_sections
+ (bfd *, struct bfd_link_info *);
+extern bfd_boolean _bfd_sparc_elf_object_p
+ (bfd *);
+extern bfd_vma _bfd_sparc_elf_plt_sym_val
+ (bfd_vma, const asection *, const arelent *);
+extern bfd_boolean _bfd_sparc_elf_merge_private_bfd_data
+ (bfd *, bfd *);
diff --git a/bfd/elfxx-target.h b/bfd/elfxx-target.h
new file mode 100644
index 0000000..692fb46
--- /dev/null
+++ b/bfd/elfxx-target.h
@@ -0,0 +1,998 @@
+/* Target definitions for NN-bit ELF
+ Copyright (C) 1993-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, 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. */
+
+#ifndef bfd_elfNN_close_and_cleanup
+#define bfd_elfNN_close_and_cleanup _bfd_elf_close_and_cleanup
+#endif
+#ifndef bfd_elfNN_bfd_free_cached_info
+#define bfd_elfNN_bfd_free_cached_info _bfd_free_cached_info
+#endif
+#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
+#ifndef bfd_elfNN_get_synthetic_symtab
+#define bfd_elfNN_get_synthetic_symtab \
+ _bfd_elf_get_synthetic_symtab
+#endif
+#ifndef bfd_elfNN_canonicalize_reloc
+#define bfd_elfNN_canonicalize_reloc _bfd_elf_canonicalize_reloc
+#endif
+#ifndef bfd_elfNN_find_nearest_line
+#define bfd_elfNN_find_nearest_line _bfd_elf_find_nearest_line
+#endif
+#ifndef bfd_elfNN_find_line
+#define bfd_elfNN_find_line _bfd_elf_find_line
+#endif
+#ifndef bfd_elfNN_find_inliner_info
+#define bfd_elfNN_find_inliner_info _bfd_elf_find_inliner_info
+#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
+#ifndef bfd_elfNN_get_symbol_info
+#define bfd_elfNN_get_symbol_info _bfd_elf_get_symbol_info
+#endif
+#define bfd_elfNN_canonicalize_symtab _bfd_elf_canonicalize_symtab
+#define bfd_elfNN_get_symtab_upper_bound _bfd_elf_get_symtab_upper_bound
+#define bfd_elfNN_make_empty_symbol _bfd_elf_make_empty_symbol
+#ifndef bfd_elfNN_new_section_hook
+#define bfd_elfNN_new_section_hook _bfd_elf_new_section_hook
+#endif
+#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_can_refcount
+#define elf_backend_can_refcount 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
+#ifndef elf_backend_want_dynbss
+#define elf_backend_want_dynbss 1
+#endif
+#ifndef elf_backend_want_p_paddr_set_to_zero
+#define elf_backend_want_p_paddr_set_to_zero 0
+#endif
+#ifndef elf_backend_default_execstack
+#define elf_backend_default_execstack 1
+#endif
+#ifndef elf_backend_caches_rawsize
+#define elf_backend_caches_rawsize 0
+#endif
+#ifndef elf_backend_stack_align
+#define elf_backend_stack_align 16
+#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 \
+ ((void (*) (bfd*, struct bfd_section *)) 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_can_refcount
+#define elf_backend_can_refcount 0
+#endif
+#ifndef elf_backend_want_got_sym
+#define elf_backend_want_got_sym 1
+#endif
+#ifndef elf_backend_gc_keep
+#define elf_backend_gc_keep _bfd_elf_gc_keep
+#endif
+#ifndef elf_backend_gc_mark_dynamic_ref
+#define elf_backend_gc_mark_dynamic_ref bfd_elf_gc_mark_dynamic_ref_symbol
+#endif
+#ifndef elf_backend_gc_mark_hook
+#define elf_backend_gc_mark_hook _bfd_elf_gc_mark_hook
+#endif
+#ifndef elf_backend_gc_mark_extra_sections
+#define elf_backend_gc_mark_extra_sections _bfd_elf_gc_mark_extra_sections
+#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_elf_gc_sections
+#endif
+
+#ifndef bfd_elfNN_bfd_merge_sections
+#define bfd_elfNN_bfd_merge_sections \
+ _bfd_elf_merge_sections
+#endif
+
+#ifndef bfd_elfNN_bfd_is_group_section
+#define bfd_elfNN_bfd_is_group_section bfd_elf_is_group_section
+#endif
+
+#ifndef bfd_elfNN_bfd_discard_group
+#define bfd_elfNN_bfd_discard_group bfd_generic_discard_group
+#endif
+
+#ifndef bfd_elfNN_section_already_linked
+#define bfd_elfNN_section_already_linked \
+ _bfd_elf_section_already_linked
+#endif
+
+#ifndef bfd_elfNN_bfd_define_common_symbol
+#define bfd_elfNN_bfd_define_common_symbol bfd_generic_define_common_symbol
+#endif
+
+#ifndef bfd_elfNN_bfd_lookup_section_flags
+#define bfd_elfNN_bfd_lookup_section_flags bfd_elf_lookup_section_flags
+#endif
+
+#ifndef bfd_elfNN_bfd_make_debug_symbol
+#define bfd_elfNN_bfd_make_debug_symbol \
+ ((asymbol * (*) (bfd *, void *, unsigned long)) bfd_nullvoidptr)
+#endif
+
+#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_header_data
+#define bfd_elfNN_bfd_copy_private_header_data \
+ _bfd_elf_copy_private_header_data
+#endif
+#ifndef bfd_elfNN_bfd_copy_private_bfd_data
+#define bfd_elfNN_bfd_copy_private_bfd_data \
+ _bfd_elf_copy_private_bfd_data
+#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 \
+ ((bfd_boolean (*) (bfd *, bfd *)) bfd_true)
+#endif
+#ifndef bfd_elfNN_bfd_set_private_flags
+#define bfd_elfNN_bfd_set_private_flags \
+ ((bfd_boolean (*) (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_bfd_is_target_special_symbol
+#define bfd_elfNN_bfd_is_target_special_symbol \
+ ((bfd_boolean (*) (bfd *, asymbol *)) bfd_false)
+#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
+#ifndef bfd_elfNN_bfd_link_add_symbols
+#define bfd_elfNN_bfd_link_add_symbols bfd_elf_link_add_symbols
+#endif
+#ifndef bfd_elfNN_bfd_final_link
+#define bfd_elfNN_bfd_final_link bfd_elf_final_link
+#endif
+#else /* ! defined (elf_backend_relocate_section) */
+/* If no backend relocate_section routine, use the generic linker.
+ Note - this will prevent the port from being able to use some of
+ the other features of the ELF linker, because the generic hash structure
+ does not have the fields needed by the ELF linker. In particular it
+ means that linking directly to S-records will not work. */
+#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_just_syms
+#define bfd_elfNN_bfd_link_just_syms _bfd_elf_link_just_syms
+#endif
+
+#ifndef bfd_elfNN_bfd_copy_link_hash_symbol_type
+#define bfd_elfNN_bfd_copy_link_hash_symbol_type \
+ _bfd_elf_copy_link_hash_symbol_type
+#endif
+
+#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_make_object
+#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 bfd_elfNN_print_symbol
+#define bfd_elfNN_print_symbol bfd_elf_print_symbol
+#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_backend_arch_data
+#define elf_backend_arch_data NULL
+#endif
+
+#ifndef ELF_TARGET_ID
+#define ELF_TARGET_ID GENERIC_ELF_DATA
+#endif
+
+#ifndef ELF_OSABI
+#define ELF_OSABI ELFOSABI_NONE
+#endif
+
+#ifndef ELF_MAXPAGESIZE
+# error ELF_MAXPAGESIZE is not defined
+#define ELF_MAXPAGESIZE 1
+#endif
+
+#ifndef ELF_COMMONPAGESIZE
+#define ELF_COMMONPAGESIZE ELF_MAXPAGESIZE
+#endif
+
+#ifndef ELF_MINPAGESIZE
+#define ELF_MINPAGESIZE ELF_COMMONPAGESIZE
+#endif
+
+#if ELF_COMMONPAGESIZE > ELF_MAXPAGESIZE
+# error ELF_COMMONPAGESIZE > ELF_MAXPAGESIZE
+#endif
+#if ELF_MINPAGESIZE > ELF_COMMONPAGESIZE
+# error ELF_MINPAGESIZE > ELF_COMMONPAGESIZE
+#endif
+
+#ifndef ELF_DYNAMIC_SEC_FLAGS
+/* Note that we set the SEC_IN_MEMORY flag for these sections. */
+#define ELF_DYNAMIC_SEC_FLAGS \
+ (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS \
+ | SEC_IN_MEMORY | SEC_LINKER_CREATED)
+#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_archive_symbol_lookup
+#define elf_backend_archive_symbol_lookup _bfd_elf_archive_symbol_lookup
+#endif
+#ifndef elf_backend_name_local_section_symbols
+#define elf_backend_name_local_section_symbols 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 _bfd_elf_make_section_from_shdr
+#endif
+#ifndef elf_backend_section_flags
+#define elf_backend_section_flags 0
+#endif
+#ifndef elf_backend_get_sec_type_attr
+#define elf_backend_get_sec_type_attr _bfd_elf_get_sec_type_attr
+#endif
+#ifndef elf_backend_section_from_phdr
+#define elf_backend_section_from_phdr _bfd_elf_make_section_from_phdr
+#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_omit_section_dynsym
+#define elf_backend_omit_section_dynsym _bfd_elf_link_omit_section_dynsym
+#endif
+#ifndef elf_backend_relocs_compatible
+#define elf_backend_relocs_compatible _bfd_elf_default_relocs_compatible
+#endif
+#ifndef elf_backend_check_relocs
+#define elf_backend_check_relocs 0
+#endif
+#ifndef elf_backend_check_directives
+#define elf_backend_check_directives 0
+#endif
+#ifndef elf_backend_notice_as_needed
+#define elf_backend_notice_as_needed _bfd_elf_notice_as_needed
+#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_init_index_section
+#define elf_backend_init_index_section \
+ ((void (*) (bfd *, struct bfd_link_info *)) bfd_void)
+#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_modify_program_headers
+#define elf_backend_modify_program_headers 0
+#endif
+#ifndef elf_backend_ecoff_debug_swap
+#define elf_backend_ecoff_debug_swap 0
+#endif
+#ifndef elf_backend_bfd_from_remote_memory
+#define elf_backend_bfd_from_remote_memory _bfd_elfNN_bfd_from_remote_memory
+#endif
+#ifndef elf_backend_got_header_size
+#define elf_backend_got_header_size 0
+#endif
+#ifndef elf_backend_got_elt_size
+#define elf_backend_got_elt_size _bfd_elf_default_got_elt_size
+#endif
+#ifndef elf_backend_obj_attrs_vendor
+#define elf_backend_obj_attrs_vendor NULL
+#endif
+#ifndef elf_backend_obj_attrs_section
+#define elf_backend_obj_attrs_section NULL
+#endif
+#ifndef elf_backend_obj_attrs_arg_type
+#define elf_backend_obj_attrs_arg_type NULL
+#endif
+#ifndef elf_backend_obj_attrs_section_type
+#define elf_backend_obj_attrs_section_type SHT_GNU_ATTRIBUTES
+#endif
+#ifndef elf_backend_obj_attrs_order
+#define elf_backend_obj_attrs_order NULL
+#endif
+#ifndef elf_backend_obj_attrs_handle_unknown
+#define elf_backend_obj_attrs_handle_unknown NULL
+#endif
+#ifndef elf_backend_static_tls_alignment
+#define elf_backend_static_tls_alignment 1
+#endif
+#ifndef elf_backend_post_process_headers
+#define elf_backend_post_process_headers _bfd_elf_post_process_headers
+#endif
+#ifndef elf_backend_print_symbol_all
+#define elf_backend_print_symbol_all NULL
+#endif
+#ifndef elf_backend_output_arch_local_syms
+#define elf_backend_output_arch_local_syms NULL
+#endif
+#ifndef elf_backend_output_arch_syms
+#define elf_backend_output_arch_syms NULL
+#endif
+#ifndef elf_backend_copy_indirect_symbol
+#define elf_backend_copy_indirect_symbol _bfd_elf_link_hash_copy_indirect
+#endif
+#ifndef elf_backend_hide_symbol
+#define elf_backend_hide_symbol _bfd_elf_link_hash_hide_symbol
+#endif
+#ifndef elf_backend_fixup_symbol
+#define elf_backend_fixup_symbol NULL
+#endif
+#ifndef elf_backend_merge_symbol_attribute
+#define elf_backend_merge_symbol_attribute NULL
+#endif
+#ifndef elf_backend_get_target_dtag
+#define elf_backend_get_target_dtag NULL
+#endif
+#ifndef elf_backend_ignore_undef_symbol
+#define elf_backend_ignore_undef_symbol NULL
+#endif
+#ifndef elf_backend_emit_relocs
+#define elf_backend_emit_relocs _bfd_elf_link_output_relocs
+#endif
+#ifndef elf_backend_count_relocs
+#define elf_backend_count_relocs NULL
+#endif
+#ifndef elf_backend_grok_prstatus
+#define elf_backend_grok_prstatus NULL
+#endif
+#ifndef elf_backend_grok_psinfo
+#define elf_backend_grok_psinfo NULL
+#endif
+#ifndef elf_backend_write_core_note
+#define elf_backend_write_core_note NULL
+#endif
+#ifndef elf_backend_lookup_section_flags_hook
+#define elf_backend_lookup_section_flags_hook NULL
+#endif
+#ifndef elf_backend_reloc_type_class
+#define elf_backend_reloc_type_class _bfd_elf_reloc_type_class
+#endif
+#ifndef elf_backend_discard_info
+#define elf_backend_discard_info NULL
+#endif
+#ifndef elf_backend_ignore_discarded_relocs
+#define elf_backend_ignore_discarded_relocs NULL
+#endif
+#ifndef elf_backend_action_discarded
+#define elf_backend_action_discarded _bfd_elf_default_action_discarded
+#endif
+#ifndef elf_backend_eh_frame_address_size
+#define elf_backend_eh_frame_address_size _bfd_elf_eh_frame_address_size
+#endif
+#ifndef elf_backend_can_make_relative_eh_frame
+#define elf_backend_can_make_relative_eh_frame _bfd_elf_can_make_relative
+#endif
+#ifndef elf_backend_can_make_lsda_relative_eh_frame
+#define elf_backend_can_make_lsda_relative_eh_frame _bfd_elf_can_make_relative
+#endif
+#ifndef elf_backend_encode_eh_address
+#define elf_backend_encode_eh_address _bfd_elf_encode_eh_address
+#endif
+#ifndef elf_backend_write_section
+#define elf_backend_write_section NULL
+#endif
+#ifndef elf_backend_mips_irix_compat
+#define elf_backend_mips_irix_compat NULL
+#endif
+#ifndef elf_backend_mips_rtype_to_howto
+#define elf_backend_mips_rtype_to_howto NULL
+#endif
+
+/* Previously, backends could only use SHT_REL or SHT_RELA relocation
+ sections, but not both. They defined USE_REL to indicate SHT_REL
+ sections, and left it undefined to indicated SHT_RELA sections.
+ For backwards compatibility, we still support this usage. */
+#ifndef USE_REL
+#define USE_REL 0
+#endif
+
+/* Use these in new code. */
+#ifndef elf_backend_may_use_rel_p
+#define elf_backend_may_use_rel_p USE_REL
+#endif
+#ifndef elf_backend_may_use_rela_p
+#define elf_backend_may_use_rela_p !USE_REL
+#endif
+#ifndef elf_backend_default_use_rela_p
+#define elf_backend_default_use_rela_p !USE_REL
+#endif
+#ifndef elf_backend_rela_plts_and_copies_p
+#define elf_backend_rela_plts_and_copies_p elf_backend_default_use_rela_p
+#endif
+
+#ifndef elf_backend_rela_normal
+#define elf_backend_rela_normal 0
+#endif
+
+#ifndef elf_backend_plt_sym_val
+#define elf_backend_plt_sym_val NULL
+#endif
+#ifndef elf_backend_relplt_name
+#define elf_backend_relplt_name NULL
+#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
+
+#ifndef elf_backend_special_sections
+#define elf_backend_special_sections NULL
+#endif
+
+#ifndef elf_backend_sign_extend_vma
+#define elf_backend_sign_extend_vma 0
+#endif
+
+#ifndef elf_backend_link_order_error_handler
+#define elf_backend_link_order_error_handler _bfd_default_error_handler
+#endif
+
+#ifndef elf_backend_common_definition
+#define elf_backend_common_definition _bfd_elf_common_definition
+#endif
+
+#ifndef elf_backend_common_section_index
+#define elf_backend_common_section_index _bfd_elf_common_section_index
+#endif
+
+#ifndef elf_backend_common_section
+#define elf_backend_common_section _bfd_elf_common_section
+#endif
+
+#ifndef elf_backend_merge_symbol
+#define elf_backend_merge_symbol NULL
+#endif
+
+#ifndef elf_backend_hash_symbol
+#define elf_backend_hash_symbol _bfd_elf_hash_symbol
+#endif
+
+#ifndef elf_backend_is_function_type
+#define elf_backend_is_function_type _bfd_elf_is_function_type
+#endif
+
+#ifndef elf_backend_maybe_function_sym
+#define elf_backend_maybe_function_sym _bfd_elf_maybe_function_sym
+#endif
+
+#ifndef elf_match_priority
+#define elf_match_priority \
+ (ELF_ARCH == bfd_arch_unknown ? 2 : ELF_OSABI == ELFOSABI_NONE ? 1 : 0)
+#endif
+
+extern const struct elf_size_info _bfd_elfNN_size_info;
+
+static struct elf_backend_data elfNN_bed =
+{
+ ELF_ARCH, /* arch */
+ ELF_TARGET_ID, /* target_id */
+ ELF_MACHINE_CODE, /* elf_machine_code */
+ ELF_OSABI, /* elf_osabi */
+ ELF_MAXPAGESIZE, /* maxpagesize */
+ ELF_MINPAGESIZE, /* minpagesize */
+ ELF_COMMONPAGESIZE, /* commonpagesize */
+ ELF_DYNAMIC_SEC_FLAGS, /* dynamic_sec_flags */
+ elf_backend_arch_data,
+ 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_archive_symbol_lookup,
+ elf_backend_name_local_section_symbols,
+ elf_backend_section_processing,
+ elf_backend_section_from_shdr,
+ elf_backend_section_flags,
+ elf_backend_get_sec_type_attr,
+ elf_backend_section_from_phdr,
+ 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_omit_section_dynsym,
+ elf_backend_relocs_compatible,
+ elf_backend_check_relocs,
+ elf_backend_check_directives,
+ elf_backend_notice_as_needed,
+ elf_backend_adjust_dynamic_symbol,
+ elf_backend_always_size_sections,
+ elf_backend_size_dynamic_sections,
+ elf_backend_init_index_section,
+ 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_modify_program_headers,
+ elf_backend_gc_keep,
+ elf_backend_gc_mark_dynamic_ref,
+ elf_backend_gc_mark_hook,
+ elf_backend_gc_mark_extra_sections,
+ elf_backend_gc_sweep_hook,
+ elf_backend_post_process_headers,
+ elf_backend_print_symbol_all,
+ elf_backend_output_arch_local_syms,
+ elf_backend_output_arch_syms,
+ elf_backend_copy_indirect_symbol,
+ elf_backend_hide_symbol,
+ elf_backend_fixup_symbol,
+ elf_backend_merge_symbol_attribute,
+ elf_backend_get_target_dtag,
+ elf_backend_ignore_undef_symbol,
+ elf_backend_emit_relocs,
+ elf_backend_count_relocs,
+ elf_backend_grok_prstatus,
+ elf_backend_grok_psinfo,
+ elf_backend_write_core_note,
+ elf_backend_lookup_section_flags_hook,
+ elf_backend_reloc_type_class,
+ elf_backend_discard_info,
+ elf_backend_ignore_discarded_relocs,
+ elf_backend_action_discarded,
+ elf_backend_eh_frame_address_size,
+ elf_backend_can_make_relative_eh_frame,
+ elf_backend_can_make_lsda_relative_eh_frame,
+ elf_backend_encode_eh_address,
+ elf_backend_write_section,
+ elf_backend_mips_irix_compat,
+ elf_backend_mips_rtype_to_howto,
+ elf_backend_ecoff_debug_swap,
+ elf_backend_bfd_from_remote_memory,
+ elf_backend_plt_sym_val,
+ elf_backend_common_definition,
+ elf_backend_common_section_index,
+ elf_backend_common_section,
+ elf_backend_merge_symbol,
+ elf_backend_hash_symbol,
+ elf_backend_is_function_type,
+ elf_backend_maybe_function_sym,
+ elf_backend_link_order_error_handler,
+ elf_backend_relplt_name,
+ ELF_MACHINE_ALT1,
+ ELF_MACHINE_ALT2,
+ &elf_backend_size_info,
+ elf_backend_special_sections,
+ elf_backend_got_header_size,
+ elf_backend_got_elt_size,
+ elf_backend_obj_attrs_vendor,
+ elf_backend_obj_attrs_section,
+ elf_backend_obj_attrs_arg_type,
+ elf_backend_obj_attrs_section_type,
+ elf_backend_obj_attrs_order,
+ elf_backend_obj_attrs_handle_unknown,
+ elf_backend_static_tls_alignment,
+ elf_backend_stack_align,
+ elf_backend_collect,
+ elf_backend_type_change_ok,
+ elf_backend_may_use_rel_p,
+ elf_backend_may_use_rela_p,
+ elf_backend_default_use_rela_p,
+ elf_backend_rela_plts_and_copies_p,
+ elf_backend_rela_normal,
+ elf_backend_sign_extend_vma,
+ 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,
+ elf_backend_can_refcount,
+ elf_backend_want_got_sym,
+ elf_backend_want_dynbss,
+ elf_backend_want_p_paddr_set_to_zero,
+ elf_backend_default_execstack,
+ elf_backend_caches_rawsize
+};
+
+/* Forward declaration for use when initialising alternative_target field. */
+#ifdef TARGET_LITTLE_SYM
+extern const bfd_target TARGET_LITTLE_SYM;
+#endif
+
+#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 | BFD_COMPRESS | BFD_DECOMPRESS),
+
+ /* 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
+ | SEC_SMALL_DATA | SEC_MERGE | SEC_STRINGS | SEC_GROUP),
+
+ /* 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. The System V ABI,
+ Chapter 7 (Formats & Protocols), Archive section sets this as 15. */
+ 15,
+
+ elf_match_priority,
+
+ /* 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),
+
+ /* Alternative endian target. */
+#ifdef TARGET_LITTLE_SYM
+ & TARGET_LITTLE_SYM,
+#else
+ NULL,
+#endif
+
+ /* backend_data: */
+ &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 | BFD_COMPRESS | BFD_DECOMPRESS),
+
+ /* 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
+ | SEC_SMALL_DATA | SEC_MERGE | SEC_STRINGS | SEC_GROUP),
+
+ /* 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. The System V ABI,
+ Chapter 7 (Formats & Protocols), Archive section sets this as 15. */
+ 15,
+
+ elf_match_priority,
+
+ /* 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),
+
+ /* Alternative endian target. */
+#ifdef TARGET_BIG_SYM
+ & TARGET_BIG_SYM,
+#else
+ NULL,
+#endif
+
+ /* backend_data: */
+ &elfNN_bed
+};
+#endif
diff --git a/bfd/elfxx-tilegx.c b/bfd/elfxx-tilegx.c
new file mode 100644
index 0000000..e206bc7
--- /dev/null
+++ b/bfd/elfxx-tilegx.c
@@ -0,0 +1,4440 @@
+/* TILE-Gx-specific support for ELF.
+ Copyright (C) 2011-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+#include "elf-bfd.h"
+#include "elf/tilegx.h"
+#include "opcode/tilegx.h"
+#include "libiberty.h"
+#include "elfxx-tilegx.h"
+
+#define ABI_64_P(abfd) \
+ (get_elf_backend_data (abfd)->s->elfclass == ELFCLASS64)
+
+#define TILEGX_ELF_WORD_BYTES(htab) \
+ ((htab)->bytes_per_word)
+
+/* The size of an external RELA relocation. */
+#define TILEGX_ELF_RELA_BYTES(htab) \
+ ((htab)->bytes_per_rela)
+
+/* Both 32-bit and 64-bit tilegx encode this in an identical manner,
+ so just take advantage of that. */
+#define TILEGX_ELF_R_TYPE(r_info) \
+ ((r_info) & 0xFF)
+
+#define TILEGX_ELF_R_INFO(htab, in_rel, index, type) \
+ ((htab)->r_info (in_rel, index, type))
+
+#define TILEGX_ELF_R_SYMNDX(htab, r_info) \
+ ((htab)->r_symndx(r_info))
+
+#define TILEGX_ELF_DTPOFF_RELOC(htab) \
+ ((htab)->dtpoff_reloc)
+
+#define TILEGX_ELF_DTPMOD_RELOC(htab) \
+ ((htab)->dtpmod_reloc)
+
+#define TILEGX_ELF_TPOFF_RELOC(htab) \
+ ((htab)->tpoff_reloc)
+
+#define TILEGX_ELF_PUT_WORD(htab, bfd, val, ptr) \
+ ((htab)->put_word (bfd, val, ptr))
+
+/* The name of the dynamic interpreter. This is put in the .interp
+ section. */
+
+#define ELF64_DYNAMIC_INTERPRETER "/lib/ld.so.1"
+#define ELF32_DYNAMIC_INTERPRETER "/lib32/ld.so.1"
+
+
+static reloc_howto_type tilegx_elf_howto_table [] =
+{
+ /* This reloc does nothing. */
+ HOWTO (R_TILEGX_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_TILEGX_NONE", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ FALSE), /* pcrel_offset */
+#ifdef BFD64
+ /* A 64 bit absolute relocation. */
+ HOWTO (R_TILEGX_64, /* type */
+ 0, /* rightshift */
+ 4, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_TILEGX_64", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffffffffffffffffULL, /* dst_mask */
+ FALSE), /* pcrel_offset */
+#endif
+ /* A 32 bit absolute relocation. */
+ HOWTO (R_TILEGX_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 */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_TILEGX_32", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A 16 bit absolute relocation. */
+ HOWTO (R_TILEGX_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_TILEGX_16", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* An 8 bit absolute relocation. */
+ HOWTO (R_TILEGX_8, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 8, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_unsigned, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_TILEGX_8", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+#ifdef BFD64
+ /* A 64 bit pc-relative relocation. */
+ HOWTO (R_TILEGX_64_PCREL,/* type */
+ 0, /* rightshift */
+ 4, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_TILEGX_32_PCREL", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffffffffffffffffULL, /* dst_mask */
+ TRUE), /* pcrel_offset */
+#endif
+ /* A 32 bit pc-relative relocation. */
+ HOWTO (R_TILEGX_32_PCREL,/* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_TILEGX_32_PCREL", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* A 16 bit pc-relative relocation. */
+ HOWTO (R_TILEGX_16_PCREL,/* 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_TILEGX_16_PCREL", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* An 8 bit pc-relative relocation. */
+ HOWTO (R_TILEGX_8_PCREL, /* type */
+ 0, /* rightshift */
+ 0, /* 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_TILEGX_8_PCREL",/* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ /* A 16 bit relocation without overflow. */
+ HOWTO (R_TILEGX_HW0, /* 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_TILEGX_HW0", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A 16 bit relocation without overflow. */
+ HOWTO (R_TILEGX_HW1, /* 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_TILEGX_HW1", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A 16 bit relocation without overflow. */
+ HOWTO (R_TILEGX_HW2, /* type */
+ 32, /* 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_TILEGX_HW2", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A 16 bit relocation without overflow. */
+ HOWTO (R_TILEGX_HW3, /* type */
+ 48, /* 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_TILEGX_HW3", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A 16 bit relocation with overflow. */
+ HOWTO (R_TILEGX_HW0_LAST, /* 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_TILEGX_HW0_LAST", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A 16 bit relocation with overflow. */
+ HOWTO (R_TILEGX_HW1_LAST, /* type */
+ 16, /* 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_TILEGX_HW1_LAST", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ /* A 16 bit relocation with overflow. */
+ HOWTO (R_TILEGX_HW2_LAST, /* type */
+ 32, /* 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_TILEGX_HW2_LAST", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0xffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+ HOWTO (R_TILEGX_COPY, /* 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_TILEGX_COPY", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_TILEGX_GLOB_DAT, /* 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_TILEGX_GLOB_DAT", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_TILEGX_JMP_SLOT, /* 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_TILEGX_JMP_SLOT", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_TILEGX_RELATIVE, /* 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_TILEGX_RELATIVE", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_TILEGX_BROFF_X1, /* type */
+ TILEGX_LOG2_BUNDLE_ALIGNMENT_IN_BYTES, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 17, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_TILEGX_BROFF_X1", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ -1, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_TILEGX_JUMPOFF_X1, /* type */
+ TILEGX_LOG2_BUNDLE_ALIGNMENT_IN_BYTES, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 27, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_TILEGX_JUMPOFF_X1", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ -1, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ HOWTO (R_TILEGX_JUMPOFF_X1_PLT, /* type */
+ TILEGX_LOG2_BUNDLE_ALIGNMENT_IN_BYTES, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 27, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_TILEGX_JUMPOFF_X1_PLT", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ -1, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+#define TILEGX_IMM_HOWTO(name, size, bitsize) \
+ HOWTO (name, 0, size, bitsize, FALSE, 0, \
+ complain_overflow_signed, bfd_elf_generic_reloc, \
+ #name, FALSE, 0, -1, FALSE)
+
+#define TILEGX_UIMM_HOWTO(name, size, bitsize) \
+ HOWTO (name, 0, size, bitsize, FALSE, 0, \
+ complain_overflow_unsigned, bfd_elf_generic_reloc, \
+ #name, FALSE, 0, -1, FALSE)
+
+ TILEGX_IMM_HOWTO(R_TILEGX_IMM8_X0, 0, 8),
+ TILEGX_IMM_HOWTO(R_TILEGX_IMM8_Y0, 0, 8),
+ TILEGX_IMM_HOWTO(R_TILEGX_IMM8_X1, 0, 8),
+ TILEGX_IMM_HOWTO(R_TILEGX_IMM8_Y1, 0, 8),
+ TILEGX_IMM_HOWTO(R_TILEGX_DEST_IMM8_X1, 0, 8),
+
+ TILEGX_UIMM_HOWTO(R_TILEGX_MT_IMM14_X1, 1, 14),
+ TILEGX_UIMM_HOWTO(R_TILEGX_MF_IMM14_X1, 1, 14),
+
+ TILEGX_UIMM_HOWTO(R_TILEGX_MMSTART_X0, 0, 6),
+ TILEGX_UIMM_HOWTO(R_TILEGX_MMEND_X0, 0, 6),
+
+ TILEGX_UIMM_HOWTO(R_TILEGX_SHAMT_X0, 0, 6),
+ TILEGX_UIMM_HOWTO(R_TILEGX_SHAMT_X1, 0, 6),
+ TILEGX_UIMM_HOWTO(R_TILEGX_SHAMT_Y0, 0, 6),
+ TILEGX_UIMM_HOWTO(R_TILEGX_SHAMT_Y1, 0, 6),
+
+#define TILEGX_IMM16_HOWTO(name, rshift) \
+ HOWTO (name, rshift, 1, 16, FALSE, 0, \
+ complain_overflow_dont, bfd_elf_generic_reloc, \
+ #name, FALSE, 0, 0xffff, FALSE)
+
+ TILEGX_IMM16_HOWTO (R_TILEGX_IMM16_X0_HW0, 0),
+ TILEGX_IMM16_HOWTO (R_TILEGX_IMM16_X1_HW0, 0),
+ TILEGX_IMM16_HOWTO (R_TILEGX_IMM16_X0_HW1, 16),
+ TILEGX_IMM16_HOWTO (R_TILEGX_IMM16_X1_HW1, 16),
+ TILEGX_IMM16_HOWTO (R_TILEGX_IMM16_X0_HW2, 32),
+ TILEGX_IMM16_HOWTO (R_TILEGX_IMM16_X1_HW2, 32),
+ TILEGX_IMM16_HOWTO (R_TILEGX_IMM16_X0_HW3, 48),
+ TILEGX_IMM16_HOWTO (R_TILEGX_IMM16_X1_HW3, 48),
+
+#define TILEGX_IMM16_HOWTO_LAST(name, rshift) \
+ HOWTO (name, rshift, 1, 16, FALSE, 0, \
+ complain_overflow_signed, bfd_elf_generic_reloc, \
+ #name, FALSE, 0, 0xffff, FALSE)
+
+ TILEGX_IMM16_HOWTO_LAST (R_TILEGX_IMM16_X0_HW0_LAST, 0),
+ TILEGX_IMM16_HOWTO_LAST (R_TILEGX_IMM16_X1_HW0_LAST, 0),
+ TILEGX_IMM16_HOWTO_LAST (R_TILEGX_IMM16_X0_HW1_LAST, 16),
+ TILEGX_IMM16_HOWTO_LAST (R_TILEGX_IMM16_X1_HW1_LAST, 16),
+ TILEGX_IMM16_HOWTO_LAST (R_TILEGX_IMM16_X0_HW2_LAST, 32),
+ TILEGX_IMM16_HOWTO_LAST (R_TILEGX_IMM16_X1_HW2_LAST, 32),
+
+ /* PC-relative offsets. */
+
+#define TILEGX_IMM16_HOWTO_PCREL(name, rshift) \
+ HOWTO (name, rshift, 1, 16, TRUE, 0, \
+ complain_overflow_dont, bfd_elf_generic_reloc, \
+ #name, FALSE, 0, 0xffff, TRUE)
+
+ TILEGX_IMM16_HOWTO_PCREL (R_TILEGX_IMM16_X0_HW0_PCREL, 0),
+ TILEGX_IMM16_HOWTO_PCREL (R_TILEGX_IMM16_X1_HW0_PCREL, 0),
+ TILEGX_IMM16_HOWTO_PCREL (R_TILEGX_IMM16_X0_HW1_PCREL, 16),
+ TILEGX_IMM16_HOWTO_PCREL (R_TILEGX_IMM16_X1_HW1_PCREL, 16),
+ TILEGX_IMM16_HOWTO_PCREL (R_TILEGX_IMM16_X0_HW2_PCREL, 32),
+ TILEGX_IMM16_HOWTO_PCREL (R_TILEGX_IMM16_X1_HW2_PCREL, 32),
+ TILEGX_IMM16_HOWTO_PCREL (R_TILEGX_IMM16_X0_HW3_PCREL, 48),
+ TILEGX_IMM16_HOWTO_PCREL (R_TILEGX_IMM16_X1_HW3_PCREL, 48),
+
+#define TILEGX_IMM16_HOWTO_LAST_PCREL(name, rshift) \
+ HOWTO (name, rshift, 1, 16, TRUE, 0, \
+ complain_overflow_signed, bfd_elf_generic_reloc, \
+ #name, FALSE, 0, 0xffff, TRUE)
+
+ TILEGX_IMM16_HOWTO_LAST_PCREL (R_TILEGX_IMM16_X0_HW0_LAST_PCREL, 0),
+ TILEGX_IMM16_HOWTO_LAST_PCREL (R_TILEGX_IMM16_X1_HW0_LAST_PCREL, 0),
+ TILEGX_IMM16_HOWTO_LAST_PCREL (R_TILEGX_IMM16_X0_HW1_LAST_PCREL, 16),
+ TILEGX_IMM16_HOWTO_LAST_PCREL (R_TILEGX_IMM16_X1_HW1_LAST_PCREL, 16),
+ TILEGX_IMM16_HOWTO_LAST_PCREL (R_TILEGX_IMM16_X0_HW2_LAST_PCREL, 32),
+ TILEGX_IMM16_HOWTO_LAST_PCREL (R_TILEGX_IMM16_X1_HW2_LAST_PCREL, 32),
+
+ TILEGX_IMM16_HOWTO (R_TILEGX_IMM16_X0_HW0_GOT, 0),
+ TILEGX_IMM16_HOWTO (R_TILEGX_IMM16_X1_HW0_GOT, 0),
+
+ TILEGX_IMM16_HOWTO_PCREL (R_TILEGX_IMM16_X0_HW0_PLT_PCREL, 0),
+ TILEGX_IMM16_HOWTO_PCREL (R_TILEGX_IMM16_X1_HW0_PLT_PCREL, 0),
+ TILEGX_IMM16_HOWTO_PCREL (R_TILEGX_IMM16_X0_HW1_PLT_PCREL, 16),
+ TILEGX_IMM16_HOWTO_PCREL (R_TILEGX_IMM16_X1_HW1_PLT_PCREL, 16),
+ TILEGX_IMM16_HOWTO_PCREL (R_TILEGX_IMM16_X0_HW2_PLT_PCREL, 32),
+ TILEGX_IMM16_HOWTO_PCREL (R_TILEGX_IMM16_X1_HW2_PLT_PCREL, 32),
+
+ TILEGX_IMM16_HOWTO_LAST (R_TILEGX_IMM16_X0_HW0_LAST_GOT, 0),
+ TILEGX_IMM16_HOWTO_LAST (R_TILEGX_IMM16_X1_HW0_LAST_GOT, 0),
+ TILEGX_IMM16_HOWTO_LAST (R_TILEGX_IMM16_X0_HW1_LAST_GOT, 16),
+ TILEGX_IMM16_HOWTO_LAST (R_TILEGX_IMM16_X1_HW1_LAST_GOT, 16),
+
+ TILEGX_IMM16_HOWTO_PCREL (R_TILEGX_IMM16_X0_HW3_PLT_PCREL, 48),
+ TILEGX_IMM16_HOWTO_PCREL (R_TILEGX_IMM16_X1_HW3_PLT_PCREL, 48),
+
+ TILEGX_IMM16_HOWTO (R_TILEGX_IMM16_X0_HW0_TLS_GD, 0),
+ TILEGX_IMM16_HOWTO (R_TILEGX_IMM16_X1_HW0_TLS_GD, 0),
+
+ TILEGX_IMM16_HOWTO (R_TILEGX_IMM16_X0_HW0_TLS_LE, 0),
+ TILEGX_IMM16_HOWTO (R_TILEGX_IMM16_X1_HW0_TLS_LE, 0),
+ TILEGX_IMM16_HOWTO_LAST (R_TILEGX_IMM16_X0_HW0_LAST_TLS_LE, 0),
+ TILEGX_IMM16_HOWTO_LAST (R_TILEGX_IMM16_X1_HW0_LAST_TLS_LE, 0),
+ TILEGX_IMM16_HOWTO_LAST (R_TILEGX_IMM16_X0_HW1_LAST_TLS_LE, 16),
+ TILEGX_IMM16_HOWTO_LAST (R_TILEGX_IMM16_X1_HW1_LAST_TLS_LE, 16),
+
+ TILEGX_IMM16_HOWTO_LAST (R_TILEGX_IMM16_X0_HW0_LAST_TLS_GD, 0),
+ TILEGX_IMM16_HOWTO_LAST (R_TILEGX_IMM16_X1_HW0_LAST_TLS_GD, 0),
+ TILEGX_IMM16_HOWTO_LAST (R_TILEGX_IMM16_X0_HW1_LAST_TLS_GD, 16),
+ TILEGX_IMM16_HOWTO_LAST (R_TILEGX_IMM16_X1_HW1_LAST_TLS_GD, 16),
+ EMPTY_HOWTO (90),
+ EMPTY_HOWTO (91),
+
+#define TILEGX_IMM16_HOWTO_TLS_IE(name, rshift) \
+ HOWTO (name, rshift, 1, 16, FALSE, 0, \
+ complain_overflow_dont, bfd_elf_generic_reloc, \
+ #name, FALSE, 0, 0xffff, TRUE)
+
+ TILEGX_IMM16_HOWTO_TLS_IE (R_TILEGX_IMM16_X0_HW0_TLS_IE, 0),
+ TILEGX_IMM16_HOWTO_TLS_IE (R_TILEGX_IMM16_X1_HW0_TLS_IE, 0),
+
+ TILEGX_IMM16_HOWTO_LAST_PCREL (R_TILEGX_IMM16_X0_HW0_LAST_PLT_PCREL, 0),
+ TILEGX_IMM16_HOWTO_LAST_PCREL (R_TILEGX_IMM16_X1_HW0_LAST_PLT_PCREL, 0),
+ TILEGX_IMM16_HOWTO_LAST_PCREL (R_TILEGX_IMM16_X0_HW1_LAST_PLT_PCREL, 16),
+ TILEGX_IMM16_HOWTO_LAST_PCREL (R_TILEGX_IMM16_X1_HW1_LAST_PLT_PCREL, 16),
+ TILEGX_IMM16_HOWTO_LAST_PCREL (R_TILEGX_IMM16_X0_HW2_LAST_PLT_PCREL, 32),
+ TILEGX_IMM16_HOWTO_LAST_PCREL (R_TILEGX_IMM16_X1_HW2_LAST_PLT_PCREL, 32),
+
+#define TILEGX_IMM16_HOWTO_LAST_TLS_IE(name, rshift) \
+ HOWTO (name, rshift, 1, 16, FALSE, 0, \
+ complain_overflow_signed, bfd_elf_generic_reloc, \
+ #name, FALSE, 0, 0xffff, TRUE)
+
+ TILEGX_IMM16_HOWTO_LAST_TLS_IE (R_TILEGX_IMM16_X0_HW0_LAST_TLS_IE, 0),
+ TILEGX_IMM16_HOWTO_LAST_TLS_IE (R_TILEGX_IMM16_X1_HW0_LAST_TLS_IE, 0),
+ TILEGX_IMM16_HOWTO_LAST_TLS_IE (R_TILEGX_IMM16_X0_HW1_LAST_TLS_IE, 16),
+ TILEGX_IMM16_HOWTO_LAST_TLS_IE (R_TILEGX_IMM16_X1_HW1_LAST_TLS_IE, 16),
+ EMPTY_HOWTO (104),
+ EMPTY_HOWTO (105),
+
+ HOWTO(R_TILEGX_TLS_DTPMOD64, 0, 0, 0, FALSE, 0, complain_overflow_dont,
+ bfd_elf_generic_reloc, "R_TILEGX_TLS_DTPMOD64",
+ FALSE, 0, 0, TRUE),
+ HOWTO(R_TILEGX_TLS_DTPOFF64, 0, 4, 64, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_TILEGX_TLS_DTPOFF64",
+ FALSE, 0, -1, TRUE),
+ HOWTO(R_TILEGX_TLS_TPOFF64, 0, 0, 0, FALSE, 0, complain_overflow_dont,
+ bfd_elf_generic_reloc, "R_TILEGX_TLS_TPOFF64",
+ FALSE, 0, 0, TRUE),
+
+ HOWTO(R_TILEGX_TLS_DTPMOD32, 0, 0, 0, FALSE, 0, complain_overflow_dont,
+ bfd_elf_generic_reloc, "R_TILEGX_TLS_DTPMOD32",
+ FALSE, 0, 0, TRUE),
+ HOWTO(R_TILEGX_TLS_DTPOFF32, 0, 4, 32, FALSE, 0, complain_overflow_bitfield,
+ bfd_elf_generic_reloc, "R_TILEGX_TLS_DTPOFF32",
+ FALSE, 0, -1, TRUE),
+ HOWTO(R_TILEGX_TLS_TPOFF32, 0, 0, 0, FALSE, 0, complain_overflow_dont,
+ bfd_elf_generic_reloc, "R_TILEGX_TLS_TPOFF32",
+ FALSE, 0, 0, TRUE),
+
+ HOWTO (R_TILEGX_TLS_GD_CALL, /* type */
+ TILEGX_LOG2_BUNDLE_ALIGNMENT_IN_BYTES, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 27, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed,/* complain_on_overflow */
+ bfd_elf_generic_reloc, /* special_function */
+ "R_TILEGX_TLS_GD_CALL", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ -1, /* dst_mask */
+ TRUE), /* pcrel_offset */
+
+ TILEGX_IMM_HOWTO(R_TILEGX_IMM8_X0_TLS_GD_ADD, 0, 8),
+ TILEGX_IMM_HOWTO(R_TILEGX_IMM8_X1_TLS_GD_ADD, 0, 8),
+ TILEGX_IMM_HOWTO(R_TILEGX_IMM8_Y0_TLS_GD_ADD, 0, 8),
+ TILEGX_IMM_HOWTO(R_TILEGX_IMM8_Y1_TLS_GD_ADD, 0, 8),
+ TILEGX_IMM_HOWTO(R_TILEGX_TLS_IE_LOAD, 0, 8),
+ TILEGX_IMM_HOWTO(R_TILEGX_IMM8_X0_TLS_ADD, 0, 8),
+ TILEGX_IMM_HOWTO(R_TILEGX_IMM8_X1_TLS_ADD, 0, 8),
+ TILEGX_IMM_HOWTO(R_TILEGX_IMM8_Y0_TLS_ADD, 0, 8),
+ TILEGX_IMM_HOWTO(R_TILEGX_IMM8_Y1_TLS_ADD, 0, 8),
+};
+
+static reloc_howto_type tilegx_elf_howto_table2 [] =
+{
+ /* GNU extension to record C++ vtable hierarchy */
+ HOWTO (R_TILEGX_GNU_VTINHERIT, /* type */
+ 0, /* rightshift */
+ 4, /* size (0 = byte, 1 = short, 2 = long) */
+ 0, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ NULL, /* special_function */
+ "R_TILEGX_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_TILEGX_GNU_VTENTRY, /* type */
+ 0, /* rightshift */
+ 4, /* 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_TILEGX_GNU_VTENTRY", /* name */
+ FALSE, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ FALSE), /* pcrel_offset */
+
+};
+
+/* Map BFD reloc types to TILEGX ELF reloc types. */
+
+typedef struct tilegx_reloc_map
+{
+ bfd_reloc_code_real_type bfd_reloc_val;
+ unsigned int tilegx_reloc_val;
+ reloc_howto_type * table;
+} reloc_map;
+
+static const reloc_map tilegx_reloc_map [] =
+{
+#define TH_REMAP(bfd, tilegx) \
+ { bfd, tilegx, tilegx_elf_howto_table },
+
+ /* Standard relocations. */
+ TH_REMAP (BFD_RELOC_NONE, R_TILEGX_NONE)
+ TH_REMAP (BFD_RELOC_64, R_TILEGX_64)
+ TH_REMAP (BFD_RELOC_32, R_TILEGX_32)
+ TH_REMAP (BFD_RELOC_16, R_TILEGX_16)
+ TH_REMAP (BFD_RELOC_8, R_TILEGX_8)
+ TH_REMAP (BFD_RELOC_64_PCREL, R_TILEGX_64_PCREL)
+ TH_REMAP (BFD_RELOC_32_PCREL, R_TILEGX_32_PCREL)
+ TH_REMAP (BFD_RELOC_16_PCREL, R_TILEGX_16_PCREL)
+ TH_REMAP (BFD_RELOC_8_PCREL, R_TILEGX_8_PCREL)
+
+#define SIMPLE_REMAP(t) TH_REMAP (BFD_RELOC_##t, R_##t)
+
+ /* Custom relocations. */
+ SIMPLE_REMAP (TILEGX_HW0)
+ SIMPLE_REMAP (TILEGX_HW1)
+ SIMPLE_REMAP (TILEGX_HW2)
+ SIMPLE_REMAP (TILEGX_HW3)
+ SIMPLE_REMAP (TILEGX_HW0_LAST)
+ SIMPLE_REMAP (TILEGX_HW1_LAST)
+ SIMPLE_REMAP (TILEGX_HW2_LAST)
+ SIMPLE_REMAP (TILEGX_COPY)
+ SIMPLE_REMAP (TILEGX_GLOB_DAT)
+ SIMPLE_REMAP (TILEGX_JMP_SLOT)
+ SIMPLE_REMAP (TILEGX_RELATIVE)
+ SIMPLE_REMAP (TILEGX_BROFF_X1)
+ SIMPLE_REMAP (TILEGX_JUMPOFF_X1)
+ SIMPLE_REMAP (TILEGX_JUMPOFF_X1_PLT)
+ SIMPLE_REMAP (TILEGX_IMM8_X0)
+ SIMPLE_REMAP (TILEGX_IMM8_Y0)
+ SIMPLE_REMAP (TILEGX_IMM8_X1)
+ SIMPLE_REMAP (TILEGX_IMM8_Y1)
+ SIMPLE_REMAP (TILEGX_DEST_IMM8_X1)
+ SIMPLE_REMAP (TILEGX_MT_IMM14_X1)
+ SIMPLE_REMAP (TILEGX_MF_IMM14_X1)
+ SIMPLE_REMAP (TILEGX_MMSTART_X0)
+ SIMPLE_REMAP (TILEGX_MMEND_X0)
+ SIMPLE_REMAP (TILEGX_SHAMT_X0)
+ SIMPLE_REMAP (TILEGX_SHAMT_X1)
+ SIMPLE_REMAP (TILEGX_SHAMT_Y0)
+ SIMPLE_REMAP (TILEGX_SHAMT_Y1)
+ SIMPLE_REMAP (TILEGX_IMM16_X0_HW0)
+ SIMPLE_REMAP (TILEGX_IMM16_X1_HW0)
+ SIMPLE_REMAP (TILEGX_IMM16_X0_HW1)
+ SIMPLE_REMAP (TILEGX_IMM16_X1_HW1)
+ SIMPLE_REMAP (TILEGX_IMM16_X0_HW2)
+ SIMPLE_REMAP (TILEGX_IMM16_X1_HW2)
+ SIMPLE_REMAP (TILEGX_IMM16_X0_HW3)
+ SIMPLE_REMAP (TILEGX_IMM16_X1_HW3)
+ SIMPLE_REMAP (TILEGX_IMM16_X0_HW0_LAST)
+ SIMPLE_REMAP (TILEGX_IMM16_X1_HW0_LAST)
+ SIMPLE_REMAP (TILEGX_IMM16_X0_HW1_LAST)
+ SIMPLE_REMAP (TILEGX_IMM16_X1_HW1_LAST)
+ SIMPLE_REMAP (TILEGX_IMM16_X0_HW2_LAST)
+ SIMPLE_REMAP (TILEGX_IMM16_X1_HW2_LAST)
+ SIMPLE_REMAP (TILEGX_IMM16_X0_HW0_PCREL)
+ SIMPLE_REMAP (TILEGX_IMM16_X1_HW0_PCREL)
+ SIMPLE_REMAP (TILEGX_IMM16_X0_HW1_PCREL)
+ SIMPLE_REMAP (TILEGX_IMM16_X1_HW1_PCREL)
+ SIMPLE_REMAP (TILEGX_IMM16_X0_HW2_PCREL)
+ SIMPLE_REMAP (TILEGX_IMM16_X1_HW2_PCREL)
+ SIMPLE_REMAP (TILEGX_IMM16_X0_HW3_PCREL)
+ SIMPLE_REMAP (TILEGX_IMM16_X1_HW3_PCREL)
+ SIMPLE_REMAP (TILEGX_IMM16_X0_HW0_LAST_PCREL)
+ SIMPLE_REMAP (TILEGX_IMM16_X1_HW0_LAST_PCREL)
+ SIMPLE_REMAP (TILEGX_IMM16_X0_HW1_LAST_PCREL)
+ SIMPLE_REMAP (TILEGX_IMM16_X1_HW1_LAST_PCREL)
+ SIMPLE_REMAP (TILEGX_IMM16_X0_HW2_LAST_PCREL)
+ SIMPLE_REMAP (TILEGX_IMM16_X1_HW2_LAST_PCREL)
+ SIMPLE_REMAP (TILEGX_IMM16_X0_HW0_GOT)
+ SIMPLE_REMAP (TILEGX_IMM16_X1_HW0_GOT)
+ SIMPLE_REMAP (TILEGX_IMM16_X0_HW0_PLT_PCREL)
+ SIMPLE_REMAP (TILEGX_IMM16_X1_HW0_PLT_PCREL)
+ SIMPLE_REMAP (TILEGX_IMM16_X0_HW1_PLT_PCREL)
+ SIMPLE_REMAP (TILEGX_IMM16_X1_HW1_PLT_PCREL)
+ SIMPLE_REMAP (TILEGX_IMM16_X0_HW2_PLT_PCREL)
+ SIMPLE_REMAP (TILEGX_IMM16_X1_HW2_PLT_PCREL)
+ SIMPLE_REMAP (TILEGX_IMM16_X0_HW0_LAST_GOT)
+ SIMPLE_REMAP (TILEGX_IMM16_X1_HW0_LAST_GOT)
+ SIMPLE_REMAP (TILEGX_IMM16_X0_HW1_LAST_GOT)
+ SIMPLE_REMAP (TILEGX_IMM16_X1_HW1_LAST_GOT)
+ SIMPLE_REMAP (TILEGX_IMM16_X0_HW3_PLT_PCREL)
+ SIMPLE_REMAP (TILEGX_IMM16_X1_HW3_PLT_PCREL)
+ SIMPLE_REMAP (TILEGX_IMM16_X0_HW0_TLS_GD)
+ SIMPLE_REMAP (TILEGX_IMM16_X1_HW0_TLS_GD)
+ SIMPLE_REMAP (TILEGX_IMM16_X0_HW0_TLS_LE)
+ SIMPLE_REMAP (TILEGX_IMM16_X1_HW0_TLS_LE)
+ SIMPLE_REMAP (TILEGX_IMM16_X0_HW0_LAST_TLS_LE)
+ SIMPLE_REMAP (TILEGX_IMM16_X1_HW0_LAST_TLS_LE)
+ SIMPLE_REMAP (TILEGX_IMM16_X0_HW1_LAST_TLS_LE)
+ SIMPLE_REMAP (TILEGX_IMM16_X1_HW1_LAST_TLS_LE)
+ SIMPLE_REMAP (TILEGX_IMM16_X0_HW0_LAST_TLS_GD)
+ SIMPLE_REMAP (TILEGX_IMM16_X1_HW0_LAST_TLS_GD)
+ SIMPLE_REMAP (TILEGX_IMM16_X0_HW1_LAST_TLS_GD)
+ SIMPLE_REMAP (TILEGX_IMM16_X1_HW1_LAST_TLS_GD)
+ SIMPLE_REMAP (TILEGX_IMM16_X0_HW0_TLS_IE)
+ SIMPLE_REMAP (TILEGX_IMM16_X1_HW0_TLS_IE)
+ SIMPLE_REMAP (TILEGX_IMM16_X0_HW0_LAST_PLT_PCREL)
+ SIMPLE_REMAP (TILEGX_IMM16_X1_HW0_LAST_PLT_PCREL)
+ SIMPLE_REMAP (TILEGX_IMM16_X0_HW1_LAST_PLT_PCREL)
+ SIMPLE_REMAP (TILEGX_IMM16_X1_HW1_LAST_PLT_PCREL)
+ SIMPLE_REMAP (TILEGX_IMM16_X0_HW2_LAST_PLT_PCREL)
+ SIMPLE_REMAP (TILEGX_IMM16_X1_HW2_LAST_PLT_PCREL)
+ SIMPLE_REMAP (TILEGX_IMM16_X0_HW0_LAST_TLS_IE)
+ SIMPLE_REMAP (TILEGX_IMM16_X1_HW0_LAST_TLS_IE)
+ SIMPLE_REMAP (TILEGX_IMM16_X0_HW1_LAST_TLS_IE)
+ SIMPLE_REMAP (TILEGX_IMM16_X1_HW1_LAST_TLS_IE)
+
+ SIMPLE_REMAP (TILEGX_TLS_DTPMOD64)
+ SIMPLE_REMAP (TILEGX_TLS_DTPOFF64)
+ SIMPLE_REMAP (TILEGX_TLS_TPOFF64)
+
+ SIMPLE_REMAP (TILEGX_TLS_DTPMOD32)
+ SIMPLE_REMAP (TILEGX_TLS_DTPOFF32)
+ SIMPLE_REMAP (TILEGX_TLS_TPOFF32)
+
+ SIMPLE_REMAP (TILEGX_TLS_GD_CALL)
+ SIMPLE_REMAP (TILEGX_IMM8_X0_TLS_GD_ADD)
+ SIMPLE_REMAP (TILEGX_IMM8_X1_TLS_GD_ADD)
+ SIMPLE_REMAP (TILEGX_IMM8_Y0_TLS_GD_ADD)
+ SIMPLE_REMAP (TILEGX_IMM8_Y1_TLS_GD_ADD)
+ SIMPLE_REMAP (TILEGX_TLS_IE_LOAD)
+ SIMPLE_REMAP (TILEGX_IMM8_X0_TLS_ADD)
+ SIMPLE_REMAP (TILEGX_IMM8_X1_TLS_ADD)
+ SIMPLE_REMAP (TILEGX_IMM8_Y0_TLS_ADD)
+ SIMPLE_REMAP (TILEGX_IMM8_Y1_TLS_ADD)
+
+#undef SIMPLE_REMAP
+#undef TH_REMAP
+
+ { BFD_RELOC_VTABLE_INHERIT, R_TILEGX_GNU_VTINHERIT, tilegx_elf_howto_table2 },
+ { BFD_RELOC_VTABLE_ENTRY, R_TILEGX_GNU_VTENTRY, tilegx_elf_howto_table2 },
+};
+
+
+
+/* The TILE-Gx linker needs to keep track of the number of relocs that it
+ decides to copy as dynamic relocs in check_relocs for each symbol.
+ This is so that it can later discard them if they are found to be
+ unnecessary. We store the information in a field extending the
+ regular ELF linker hash table. */
+
+struct tilegx_elf_dyn_relocs
+{
+ struct tilegx_elf_dyn_relocs *next;
+
+ /* The input section of the reloc. */
+ asection *sec;
+
+ /* Total number of relocs copied for the input section. */
+ bfd_size_type count;
+
+ /* Number of pc-relative relocs copied for the input section. */
+ bfd_size_type pc_count;
+};
+
+/* TILEGX ELF linker hash entry. */
+
+struct tilegx_elf_link_hash_entry
+{
+ struct elf_link_hash_entry elf;
+
+ /* Track dynamic relocs copied for this symbol. */
+ struct tilegx_elf_dyn_relocs *dyn_relocs;
+
+#define GOT_UNKNOWN 0
+#define GOT_NORMAL 1
+#define GOT_TLS_GD 2
+#define GOT_TLS_IE 4
+ unsigned char tls_type;
+};
+
+#define tilegx_elf_hash_entry(ent) \
+ ((struct tilegx_elf_link_hash_entry *)(ent))
+
+struct _bfd_tilegx_elf_obj_tdata
+{
+ struct elf_obj_tdata root;
+
+ /* tls_type for each local got entry. */
+ char *local_got_tls_type;
+};
+
+#define _bfd_tilegx_elf_tdata(abfd) \
+ ((struct _bfd_tilegx_elf_obj_tdata *) (abfd)->tdata.any)
+
+#define _bfd_tilegx_elf_local_got_tls_type(abfd) \
+ (_bfd_tilegx_elf_tdata (abfd)->local_got_tls_type)
+
+#define is_tilegx_elf(bfd) \
+ (bfd_get_flavour (bfd) == bfd_target_elf_flavour \
+ && elf_tdata (bfd) != NULL \
+ && elf_object_id (bfd) == TILEGX_ELF_DATA)
+
+#include "elf/common.h"
+#include "elf/internal.h"
+
+struct tilegx_elf_link_hash_table
+{
+ struct elf_link_hash_table elf;
+
+ int bytes_per_word;
+ int word_align_power;
+ int bytes_per_rela;
+ int dtpmod_reloc;
+ int dtpoff_reloc;
+ int tpoff_reloc;
+ bfd_vma (*r_info) (Elf_Internal_Rela *, bfd_vma, bfd_vma);
+ bfd_vma (*r_symndx) (bfd_vma);
+ void (*put_word) (bfd *, bfd_vma, void *);
+ const char *dynamic_interpreter;
+
+ /* Short-cuts to get to dynamic linker sections. */
+ asection *sdynbss;
+ asection *srelbss;
+
+ /* Whether LE transition has been disabled for some of the
+ sections. */
+ bfd_boolean disable_le_transition;
+
+ /* Small local sym to section mapping cache. */
+ struct sym_cache sym_cache;
+};
+
+
+/* Get the Tile ELF linker hash table from a link_info structure. */
+#define tilegx_elf_hash_table(p) \
+ (elf_hash_table_id ((struct elf_link_hash_table *) ((p)->hash)) \
+ == TILEGX_ELF_DATA ? ((struct tilegx_elf_link_hash_table *) ((p)->hash)) : NULL)
+
+#ifdef BFD64
+static bfd_vma
+tilegx_elf_r_info_64 (Elf_Internal_Rela *in_rel ATTRIBUTE_UNUSED,
+ bfd_vma rel_index,
+ bfd_vma type)
+{
+ return ELF64_R_INFO (rel_index, type);
+}
+
+static bfd_vma
+tilegx_elf_r_symndx_64 (bfd_vma r_info)
+{
+ return ELF64_R_SYM (r_info);
+}
+
+static void
+tilegx_put_word_64 (bfd *abfd, bfd_vma val, void *ptr)
+{
+ bfd_put_64 (abfd, val, ptr);
+}
+#endif /* BFD64 */
+
+static bfd_vma
+tilegx_elf_r_info_32 (Elf_Internal_Rela *in_rel ATTRIBUTE_UNUSED,
+ bfd_vma rel_index,
+ bfd_vma type)
+{
+ return ELF32_R_INFO (rel_index, type);
+}
+
+static bfd_vma
+tilegx_elf_r_symndx_32 (bfd_vma r_info)
+{
+ return ELF32_R_SYM (r_info);
+}
+
+static void
+tilegx_put_word_32 (bfd *abfd, bfd_vma val, void *ptr)
+{
+ bfd_put_32 (abfd, val, ptr);
+}
+
+reloc_howto_type *
+tilegx_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED,
+ bfd_reloc_code_real_type code)
+{
+ unsigned int i;
+
+ for (i = ARRAY_SIZE (tilegx_reloc_map); --i;)
+ {
+ const reloc_map * entry;
+
+ entry = tilegx_reloc_map + i;
+
+ if (entry->bfd_reloc_val == code)
+ return entry->table + (entry->tilegx_reloc_val
+ - entry->table[0].type);
+ }
+
+ return NULL;
+}
+
+reloc_howto_type *
+tilegx_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ const char *r_name)
+{
+ unsigned int i;
+
+ for (i = 0;
+ i < (sizeof (tilegx_elf_howto_table)
+ / sizeof (tilegx_elf_howto_table[0]));
+ i++)
+ if (tilegx_elf_howto_table[i].name != NULL
+ && strcasecmp (tilegx_elf_howto_table[i].name, r_name) == 0)
+ return &tilegx_elf_howto_table[i];
+
+ return NULL;
+}
+
+void
+tilegx_info_to_howto_rela (bfd *abfd ATTRIBUTE_UNUSED,
+ arelent *cache_ptr,
+ Elf_Internal_Rela *dst)
+{
+ unsigned int r_type = TILEGX_ELF_R_TYPE (dst->r_info);
+
+ if (r_type <= (unsigned int) R_TILEGX_IMM8_Y1_TLS_ADD)
+ cache_ptr->howto = &tilegx_elf_howto_table [r_type];
+ else if (r_type - R_TILEGX_GNU_VTINHERIT
+ <= (unsigned int) R_TILEGX_GNU_VTENTRY)
+ cache_ptr->howto
+ = &tilegx_elf_howto_table2 [r_type - R_TILEGX_GNU_VTINHERIT];
+ else
+ abort ();
+}
+
+typedef tilegx_bundle_bits (*tilegx_create_func)(int);
+
+static const tilegx_create_func reloc_to_create_func[] =
+{
+ /* The first twenty relocation types don't correspond to operands */
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+
+ /* The remaining relocations are used for immediate operands */
+ create_BrOff_X1,
+ create_JumpOff_X1,
+ create_JumpOff_X1,
+ create_Imm8_X0,
+ create_Imm8_Y0,
+ create_Imm8_X1,
+ create_Imm8_Y1,
+ create_Dest_Imm8_X1,
+ create_MT_Imm14_X1,
+ create_MF_Imm14_X1,
+ create_BFStart_X0,
+ create_BFEnd_X0,
+ create_ShAmt_X0,
+ create_ShAmt_X1,
+ create_ShAmt_Y0,
+ create_ShAmt_Y1,
+ create_Imm16_X0,
+ create_Imm16_X1,
+ create_Imm16_X0,
+ create_Imm16_X1,
+ create_Imm16_X0,
+ create_Imm16_X1,
+ create_Imm16_X0,
+ create_Imm16_X1,
+ create_Imm16_X0,
+ create_Imm16_X1,
+ create_Imm16_X0,
+ create_Imm16_X1,
+ create_Imm16_X0,
+ create_Imm16_X1,
+ create_Imm16_X0,
+ create_Imm16_X1,
+ create_Imm16_X0,
+ create_Imm16_X1,
+ create_Imm16_X0,
+ create_Imm16_X1,
+ create_Imm16_X0,
+ create_Imm16_X1,
+ create_Imm16_X0,
+ create_Imm16_X1,
+ create_Imm16_X0,
+ create_Imm16_X1,
+ create_Imm16_X0,
+ create_Imm16_X1,
+ create_Imm16_X0,
+ create_Imm16_X1,
+ create_Imm16_X0,
+ create_Imm16_X1,
+ create_Imm16_X0,
+ create_Imm16_X1,
+ create_Imm16_X0,
+ create_Imm16_X1,
+ create_Imm16_X0,
+ create_Imm16_X1,
+ create_Imm16_X0,
+ create_Imm16_X1,
+ create_Imm16_X0,
+ create_Imm16_X1,
+ create_Imm16_X0,
+ create_Imm16_X1,
+ create_Imm16_X0,
+ create_Imm16_X1,
+ create_Imm16_X0,
+ create_Imm16_X1,
+ create_Imm16_X0,
+ create_Imm16_X1,
+ create_Imm16_X0,
+ create_Imm16_X1,
+ create_Imm16_X0,
+ create_Imm16_X1,
+ NULL,
+ NULL,
+ create_Imm16_X0,
+ create_Imm16_X1,
+ create_Imm16_X0,
+ create_Imm16_X1,
+ create_Imm16_X0,
+ create_Imm16_X1,
+ create_Imm16_X0,
+ create_Imm16_X1,
+ create_Imm16_X0,
+ create_Imm16_X1,
+ create_Imm16_X0,
+ create_Imm16_X1,
+};
+
+static void
+tilegx_elf_append_rela (bfd *abfd, asection *s, Elf_Internal_Rela *rel)
+{
+ const struct elf_backend_data *bed;
+ bfd_byte *loc;
+
+ bed = get_elf_backend_data (abfd);
+ loc = s->contents + (s->reloc_count++ * bed->s->sizeof_rela);
+ bed->s->swap_reloca_out (abfd, rel, loc);
+}
+
+/* PLT/GOT stuff */
+
+/* The procedure linkage table starts with the following header:
+
+ ld_add r28, r27, 8
+ ld r27, r27
+ {
+ jr r27
+ info 10 ## SP not offset, return PC in LR
+ }
+
+ Subsequent entries are the following, jumping to the header at the end:
+
+ {
+ moveli r28, <_GLOBAL_OFFSET_TABLE_ - 1f + MY_GOT_OFFSET>
+ lnk r26
+ }
+1:
+ {
+ moveli r27, <_GLOBAL_OFFSET_TABLE_ - 1b>
+ shl16insli r28, r28, <_GLOBAL_OFFSET_TABLE_ - 1b + MY_GOT_OFFSET>
+ }
+ {
+ add r28, r26, r28
+ shl16insli r27, r27, <_GLOBAL_OFFSET_TABLE_ - 1b>
+ }
+ {
+ add r27, r26, r27
+ ld r28, r28
+ info 10 ## SP not offset, return PC in LR
+ }
+ {
+ shl16insli r29, zero, MY_PLT_INDEX
+ jr r28
+ }
+
+ This code sequence lets the code at at the start of the PLT determine
+ which PLT entry was executed by examining 'r29'.
+
+ Note that MY_PLT_INDEX skips over the header entries, so the first
+ actual jump table entry has index zero.
+
+ If the offset fits in 16 bits,
+
+ lnk r26
+1:
+ {
+ addli r28, r26, <_GLOBAL_OFFSET_TABLE_ - 1b + MY_GOT_OFFSET>
+ moveli r27, <_GLOBAL_OFFSET_TABLE_ - 1b>
+ }
+ {
+ shl16insli r29, zero, MY_PLT_INDEX
+ ld r28, r28
+ }
+ {
+ add r27, r26, r27
+ jr r28
+ }
+ info 10 ## SP not offset, return PC in LR
+
+ For the purpose of backtracing, the procedure linkage table ends with the
+ following tail entry:
+
+ info 10 ## SP not offset, return PC in LR
+
+ The 32-bit versions are similar, with ld4s replacing ld, and offsets into
+ the GOT being multiples of 4 instead of 8.
+
+*/
+
+#define PLT_HEADER_SIZE_IN_BUNDLES 3
+#define PLT_ENTRY_SIZE_IN_BUNDLES 5
+#define PLT_TAIL_SIZE_IN_BUNDLES 1
+
+#define PLT_HEADER_SIZE \
+ (PLT_HEADER_SIZE_IN_BUNDLES * TILEGX_BUNDLE_SIZE_IN_BYTES)
+#define PLT_ENTRY_SIZE \
+ (PLT_ENTRY_SIZE_IN_BUNDLES * TILEGX_BUNDLE_SIZE_IN_BYTES)
+#define PLT_TAIL_SIZE \
+ (PLT_TAIL_SIZE_IN_BUNDLES * TILEGX_BUNDLE_SIZE_IN_BYTES)
+
+#define GOT_ENTRY_SIZE(htab) TILEGX_ELF_WORD_BYTES (htab)
+
+#define GOTPLT_HEADER_SIZE(htab) (2 * GOT_ENTRY_SIZE (htab))
+
+static const bfd_byte
+tilegx64_plt0_entry[PLT_HEADER_SIZE] =
+{
+ 0x00, 0x30, 0x48, 0x51,
+ 0x6e, 0x43, 0xa0, 0x18, /* { ld_add r28, r27, 8 } */
+ 0x00, 0x30, 0xbc, 0x35,
+ 0x00, 0x40, 0xde, 0x9e, /* { ld r27, r27 } */
+ 0xff, 0xaf, 0x30, 0x40,
+ 0x60, 0x73, 0x6a, 0x28, /* { info 10 ; jr r27 } */
+};
+
+static const bfd_byte
+tilegx64_long_plt_entry[PLT_ENTRY_SIZE] =
+{
+ 0xdc, 0x0f, 0x00, 0x10,
+ 0x0d, 0xf0, 0x6a, 0x28, /* { moveli r28, 0 ; lnk r26 } */
+ 0xdb, 0x0f, 0x00, 0x10,
+ 0x8e, 0x03, 0x00, 0x38, /* { moveli r27, 0 ; shl16insli r28, r28, 0 } */
+ 0x9c, 0xc6, 0x0d, 0xd0,
+ 0x6d, 0x03, 0x00, 0x38, /* { add r28, r26, r28 ; shl16insli r27, r27, 0 } */
+ 0x9b, 0xb6, 0xc5, 0xad,
+ 0xff, 0x57, 0xe0, 0x8e, /* { add r27, r26, r27 ; info 10 ; ld r28, r28 } */
+ 0xdd, 0x0f, 0x00, 0x70,
+ 0x80, 0x73, 0x6a, 0x28, /* { shl16insli r29, zero, 0 ; jr r28 } */
+};
+
+static const bfd_byte
+tilegx64_short_plt_entry[PLT_ENTRY_SIZE] =
+{
+ 0x00, 0x30, 0x48, 0x51,
+ 0x0d, 0xf0, 0x6a, 0x28, /* { lnk r26 } */
+ 0x9c, 0x06, 0x00, 0x90,
+ 0xed, 0x07, 0x00, 0x00, /* { addli r28, r26, 0 ; moveli r27, 0 } */
+ 0xdd, 0x0f, 0x00, 0x70,
+ 0x8e, 0xeb, 0x6a, 0x28, /* { shl16insli r29, zero, 0 ; ld r28, r28 } */
+ 0x9b, 0xb6, 0x0d, 0x50,
+ 0x80, 0x73, 0x6a, 0x28, /* { add r27, r26, r27 ; jr r28 } */
+ 0x00, 0x30, 0x48, 0xd1,
+ 0xff, 0x57, 0x18, 0x18, /* { info 10 } */
+};
+
+/* Reuse an existing info 10 bundle. */
+static const bfd_byte *const tilegx64_plt_tail_entry =
+ &tilegx64_short_plt_entry[4 * TILEGX_BUNDLE_SIZE_IN_BYTES];
+
+static const bfd_byte
+tilegx32_plt0_entry[PLT_HEADER_SIZE] =
+{
+ 0x00, 0x30, 0x48, 0x51,
+ 0x6e, 0x23, 0x58, 0x18, /* { ld4s_add r28, r27, 4 } */
+ 0x00, 0x30, 0xbc, 0x35,
+ 0x00, 0x40, 0xde, 0x9c, /* { ld4s r27, r27 } */
+ 0xff, 0xaf, 0x30, 0x40,
+ 0x60, 0x73, 0x6a, 0x28, /* { info 10 ; jr r27 } */
+};
+
+static const bfd_byte
+tilegx32_long_plt_entry[PLT_ENTRY_SIZE] =
+{
+ 0xdc, 0x0f, 0x00, 0x10,
+ 0x0d, 0xf0, 0x6a, 0x28, /* { moveli r28, 0 ; lnk r26 } */
+ 0xdb, 0x0f, 0x00, 0x10,
+ 0x8e, 0x03, 0x00, 0x38, /* { moveli r27, 0 ; shl16insli r28, r28, 0 } */
+ 0x9c, 0xc6, 0x0d, 0xd0,
+ 0x6d, 0x03, 0x00, 0x38, /* { add r28, r26, r28 ; shl16insli r27, r27, 0 } */
+ 0x9b, 0xb6, 0xc5, 0xad,
+ 0xff, 0x57, 0xe0, 0x8c, /* { add r27, r26, r27 ; info 10 ; ld4s r28, r28 } */
+ 0xdd, 0x0f, 0x00, 0x70,
+ 0x80, 0x73, 0x6a, 0x28, /* { shl16insli r29, zero, 0 ; jr r28 } */
+};
+
+static const bfd_byte
+tilegx32_short_plt_entry[PLT_ENTRY_SIZE] =
+{
+ 0x00, 0x30, 0x48, 0x51,
+ 0x0d, 0xf0, 0x6a, 0x28, /* { lnk r26 } */
+ 0x9c, 0x06, 0x00, 0x90,
+ 0xed, 0x07, 0x00, 0x00, /* { addli r28, r26, 0 ; moveli r27, 0 } */
+ 0xdd, 0x0f, 0x00, 0x70,
+ 0x8e, 0x9b, 0x6a, 0x28, /* { shl16insli r29, zero, 0 ; ld4s r28, r28 } */
+ 0x9b, 0xb6, 0x0d, 0x50,
+ 0x80, 0x73, 0x6a, 0x28, /* { add r27, r26, r27 ; jr r28 } */
+ 0x00, 0x30, 0x48, 0xd1,
+ 0xff, 0x57, 0x18, 0x18, /* { info 10 } */
+};
+
+/* Reuse an existing info 10 bundle. */
+static const bfd_byte *const tilegx32_plt_tail_entry =
+ &tilegx64_short_plt_entry[4 * TILEGX_BUNDLE_SIZE_IN_BYTES];
+
+static int
+tilegx_plt_entry_build (bfd *output_bfd,
+ struct tilegx_elf_link_hash_table *htab,
+ asection *splt, asection *sgotplt,
+ bfd_vma offset, bfd_vma *r_offset)
+{
+ int plt_index = (offset - PLT_HEADER_SIZE) / PLT_ENTRY_SIZE;
+ int got_offset = (plt_index * GOT_ENTRY_SIZE (htab)
+ + GOTPLT_HEADER_SIZE (htab));
+ tilegx_bundle_bits *pc;
+
+ /* Compute the distance from the got entry to the lnk. */
+ bfd_signed_vma dist_got_entry = sgotplt->output_section->vma
+ + sgotplt->output_offset
+ + got_offset
+ - splt->output_section->vma
+ - splt->output_offset
+ - offset
+ - TILEGX_BUNDLE_SIZE_IN_BYTES;
+
+ /* Compute the distance to GOTPLT[0]. */
+ bfd_signed_vma dist_got0 = dist_got_entry - got_offset;
+
+ /* Check whether we can use the short plt entry with 16-bit offset. */
+ bfd_boolean short_plt_entry =
+ (dist_got_entry <= 0x7fff && dist_got0 >= -0x8000);
+
+ const tilegx_bundle_bits *plt_entry = (tilegx_bundle_bits *)
+ (ABI_64_P (output_bfd) ?
+ (short_plt_entry ? tilegx64_short_plt_entry : tilegx64_long_plt_entry) :
+ (short_plt_entry ? tilegx32_short_plt_entry : tilegx32_long_plt_entry));
+
+ /* Copy the plt entry template. */
+ memcpy (splt->contents + offset, plt_entry, PLT_ENTRY_SIZE);
+
+ /* Write the immediate offsets. */
+ pc = (tilegx_bundle_bits *)(splt->contents + offset);
+
+ if (short_plt_entry)
+ {
+ /* { lnk r28 } */
+ pc++;
+
+ /* { addli r28, r28, &GOTPLT[MY_GOT_INDEX] ; moveli r27, &GOTPLT[0] } */
+ *pc++ |= create_Imm16_X0 (dist_got_entry)
+ | create_Imm16_X1 (dist_got0);
+
+ /* { shl16insli r29, zero, MY_PLT_INDEX ; ld r28, r28 } */
+ *pc++ |= create_Imm16_X0 (plt_index);
+ }
+ else
+ {
+ /* { moveli r28, &GOTPLT[MY_GOT_INDEX] ; lnk r26 } */
+ *pc++ |= create_Imm16_X0 (dist_got_entry >> 16);
+
+ /* { moveli r27, &GOTPLT[0] ;
+ shl16insli r28, r28, &GOTPLT[MY_GOT_INDEX] } */
+ *pc++ |= create_Imm16_X0 (dist_got0 >> 16)
+ | create_Imm16_X1 (dist_got_entry);
+
+ /* { add r28, r26, r28 ; shl16insli r27, r27, &GOTPLT[0] } */
+ *pc++ |= create_Imm16_X1 (dist_got0);
+
+ /* { add r27, r26, r27 ; info 10 ; ld r28, r28 } */
+ pc++;
+
+ /* { shl16insli r29, zero, MY_GOT_INDEX ; jr r28 } */
+ *pc++ |= create_Imm16_X0 (plt_index);
+ }
+
+ /* Set the relocation offset. */
+ *r_offset = got_offset;
+
+ return plt_index;
+}
+
+/* Create an entry in an TILEGX ELF linker hash table. */
+
+static struct bfd_hash_entry *
+link_hash_newfunc (struct bfd_hash_entry *entry,
+ struct bfd_hash_table *table, const char *string)
+{
+ /* Allocate the structure if it has not already been allocated by a
+ subclass. */
+ if (entry == NULL)
+ {
+ entry =
+ bfd_hash_allocate (table,
+ sizeof (struct tilegx_elf_link_hash_entry));
+ if (entry == NULL)
+ return entry;
+ }
+
+ /* Call the allocation method of the superclass. */
+ entry = _bfd_elf_link_hash_newfunc (entry, table, string);
+ if (entry != NULL)
+ {
+ struct tilegx_elf_link_hash_entry *eh;
+
+ eh = (struct tilegx_elf_link_hash_entry *) entry;
+ eh->dyn_relocs = NULL;
+ eh->tls_type = GOT_UNKNOWN;
+ }
+
+ return entry;
+}
+
+/* Create a TILEGX ELF linker hash table. */
+
+struct bfd_link_hash_table *
+tilegx_elf_link_hash_table_create (bfd *abfd)
+{
+ struct tilegx_elf_link_hash_table *ret;
+ bfd_size_type amt = sizeof (struct tilegx_elf_link_hash_table);
+
+ ret = (struct tilegx_elf_link_hash_table *) bfd_zmalloc (amt);
+ if (ret == NULL)
+ return NULL;
+
+#ifdef BFD64
+ if (ABI_64_P (abfd))
+ {
+ ret->bytes_per_word = 8;
+ ret->word_align_power = 3;
+ ret->bytes_per_rela = sizeof (Elf64_External_Rela);
+ ret->dtpoff_reloc = R_TILEGX_TLS_DTPOFF64;
+ ret->dtpmod_reloc = R_TILEGX_TLS_DTPMOD64;
+ ret->tpoff_reloc = R_TILEGX_TLS_TPOFF64;
+ ret->r_info = tilegx_elf_r_info_64;
+ ret->r_symndx = tilegx_elf_r_symndx_64;
+ ret->dynamic_interpreter = ELF64_DYNAMIC_INTERPRETER;
+ ret->put_word = tilegx_put_word_64;
+ }
+ else
+#endif
+ {
+ ret->bytes_per_word = 4;
+ ret->word_align_power = 2;
+ ret->bytes_per_rela = sizeof (Elf32_External_Rela);
+ ret->dtpoff_reloc = R_TILEGX_TLS_DTPOFF32;
+ ret->dtpmod_reloc = R_TILEGX_TLS_DTPMOD32;
+ ret->tpoff_reloc = R_TILEGX_TLS_TPOFF32;
+ ret->r_info = tilegx_elf_r_info_32;
+ ret->r_symndx = tilegx_elf_r_symndx_32;
+ ret->dynamic_interpreter = ELF32_DYNAMIC_INTERPRETER;
+ ret->put_word = tilegx_put_word_32;
+ }
+
+ if (!_bfd_elf_link_hash_table_init (&ret->elf, abfd, link_hash_newfunc,
+ sizeof (struct tilegx_elf_link_hash_entry),
+ TILEGX_ELF_DATA))
+ {
+ free (ret);
+ return NULL;
+ }
+
+ return &ret->elf.root;
+}
+
+/* Create the .got section. */
+
+static bfd_boolean
+tilegx_elf_create_got_section (bfd *abfd, struct bfd_link_info *info)
+{
+ flagword flags;
+ asection *s, *s_got;
+ struct elf_link_hash_entry *h;
+ const struct elf_backend_data *bed = get_elf_backend_data (abfd);
+ struct elf_link_hash_table *htab = elf_hash_table (info);
+
+ /* This function may be called more than once. */
+ s = bfd_get_linker_section (abfd, ".got");
+ if (s != NULL)
+ return TRUE;
+
+ flags = bed->dynamic_sec_flags;
+
+ s = bfd_make_section_anyway_with_flags (abfd,
+ (bed->rela_plts_and_copies_p
+ ? ".rela.got" : ".rel.got"),
+ (bed->dynamic_sec_flags
+ | SEC_READONLY));
+ if (s == NULL
+ || ! bfd_set_section_alignment (abfd, s, bed->s->log_file_align))
+ return FALSE;
+ htab->srelgot = s;
+
+ s = s_got = bfd_make_section_anyway_with_flags (abfd, ".got", flags);
+ if (s == NULL
+ || !bfd_set_section_alignment (abfd, s, bed->s->log_file_align))
+ return FALSE;
+ htab->sgot = s;
+
+ /* The first bit of the global offset table is the header. */
+ s->size += bed->got_header_size;
+
+ if (bed->want_got_plt)
+ {
+ s = bfd_make_section_anyway_with_flags (abfd, ".got.plt", flags);
+ if (s == NULL
+ || !bfd_set_section_alignment (abfd, s,
+ bed->s->log_file_align))
+ return FALSE;
+ htab->sgotplt = s;
+
+ /* Reserve room for the header. */
+ s->size += GOTPLT_HEADER_SIZE (tilegx_elf_hash_table (info));
+ }
+
+ if (bed->want_got_sym)
+ {
+ /* Define the symbol _GLOBAL_OFFSET_TABLE_ at the start of the .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 = _bfd_elf_define_linkage_sym (abfd, info, s_got,
+ "_GLOBAL_OFFSET_TABLE_");
+ elf_hash_table (info)->hgot = h;
+ if (h == NULL)
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/* Create .plt, .rela.plt, .got, .got.plt, .rela.got, .dynbss, and
+ .rela.bss sections in DYNOBJ, and set up shortcuts to them in our
+ hash table. */
+
+bfd_boolean
+tilegx_elf_create_dynamic_sections (bfd *dynobj,
+ struct bfd_link_info *info)
+{
+ struct tilegx_elf_link_hash_table *htab;
+
+ htab = tilegx_elf_hash_table (info);
+ BFD_ASSERT (htab != NULL);
+
+ if (!tilegx_elf_create_got_section (dynobj, info))
+ return FALSE;
+
+ if (!_bfd_elf_create_dynamic_sections (dynobj, info))
+ return FALSE;
+
+ htab->sdynbss = bfd_get_linker_section (dynobj, ".dynbss");
+ if (!info->shared)
+ htab->srelbss = bfd_get_linker_section (dynobj, ".rela.bss");
+
+ if (!htab->elf.splt || !htab->elf.srelplt || !htab->sdynbss
+ || (!info->shared && !htab->srelbss))
+ abort ();
+
+ return TRUE;
+}
+
+/* Copy the extra info we tack onto an elf_link_hash_entry. */
+
+void
+tilegx_elf_copy_indirect_symbol (struct bfd_link_info *info,
+ struct elf_link_hash_entry *dir,
+ struct elf_link_hash_entry *ind)
+{
+ struct tilegx_elf_link_hash_entry *edir, *eind;
+
+ edir = (struct tilegx_elf_link_hash_entry *) dir;
+ eind = (struct tilegx_elf_link_hash_entry *) ind;
+
+ if (eind->dyn_relocs != NULL)
+ {
+ if (edir->dyn_relocs != NULL)
+ {
+ struct tilegx_elf_dyn_relocs **pp;
+ struct tilegx_elf_dyn_relocs *p;
+
+ /* Add reloc counts against the indirect sym to the direct sym
+ list. Merge any entries against the same section. */
+ for (pp = &eind->dyn_relocs; (p = *pp) != NULL; )
+ {
+ struct tilegx_elf_dyn_relocs *q;
+
+ for (q = edir->dyn_relocs; q != NULL; q = q->next)
+ if (q->sec == p->sec)
+ {
+ q->pc_count += p->pc_count;
+ q->count += p->count;
+ *pp = p->next;
+ break;
+ }
+ if (q == NULL)
+ pp = &p->next;
+ }
+ *pp = edir->dyn_relocs;
+ }
+
+ edir->dyn_relocs = eind->dyn_relocs;
+ eind->dyn_relocs = NULL;
+ }
+
+ if (ind->root.type == bfd_link_hash_indirect
+ && dir->got.refcount <= 0)
+ {
+ edir->tls_type = eind->tls_type;
+ eind->tls_type = GOT_UNKNOWN;
+ }
+ _bfd_elf_link_hash_copy_indirect (info, dir, ind);
+}
+
+static int
+tilegx_tls_translate_to_le (int r_type)
+{
+ switch (r_type)
+ {
+ case R_TILEGX_IMM16_X0_HW0_TLS_GD:
+ case R_TILEGX_IMM16_X0_HW0_TLS_IE:
+ return R_TILEGX_IMM16_X0_HW0_TLS_LE;
+
+ case R_TILEGX_IMM16_X1_HW0_TLS_GD:
+ case R_TILEGX_IMM16_X1_HW0_TLS_IE:
+ return R_TILEGX_IMM16_X1_HW0_TLS_LE;
+
+ case R_TILEGX_IMM16_X0_HW0_LAST_TLS_GD:
+ case R_TILEGX_IMM16_X0_HW0_LAST_TLS_IE:
+ return R_TILEGX_IMM16_X0_HW0_LAST_TLS_LE;
+
+ case R_TILEGX_IMM16_X1_HW0_LAST_TLS_GD:
+ case R_TILEGX_IMM16_X1_HW0_LAST_TLS_IE:
+ return R_TILEGX_IMM16_X1_HW0_LAST_TLS_LE;
+
+ case R_TILEGX_IMM16_X0_HW1_LAST_TLS_GD:
+ case R_TILEGX_IMM16_X0_HW1_LAST_TLS_IE:
+ return R_TILEGX_IMM16_X0_HW1_LAST_TLS_LE;
+
+ case R_TILEGX_IMM16_X1_HW1_LAST_TLS_GD:
+ case R_TILEGX_IMM16_X1_HW1_LAST_TLS_IE:
+ return R_TILEGX_IMM16_X1_HW1_LAST_TLS_LE;
+ }
+ return r_type;
+}
+
+static int
+tilegx_tls_translate_to_ie (int r_type)
+{
+ switch (r_type)
+ {
+ case R_TILEGX_IMM16_X0_HW0_TLS_GD:
+ case R_TILEGX_IMM16_X0_HW0_TLS_IE:
+ return R_TILEGX_IMM16_X0_HW0_TLS_IE;
+
+ case R_TILEGX_IMM16_X1_HW0_TLS_GD:
+ case R_TILEGX_IMM16_X1_HW0_TLS_IE:
+ return R_TILEGX_IMM16_X1_HW0_TLS_IE;
+
+ case R_TILEGX_IMM16_X0_HW0_LAST_TLS_GD:
+ case R_TILEGX_IMM16_X0_HW0_LAST_TLS_IE:
+ return R_TILEGX_IMM16_X0_HW0_LAST_TLS_IE;
+
+ case R_TILEGX_IMM16_X1_HW0_LAST_TLS_GD:
+ case R_TILEGX_IMM16_X1_HW0_LAST_TLS_IE:
+ return R_TILEGX_IMM16_X1_HW0_LAST_TLS_IE;
+
+ case R_TILEGX_IMM16_X0_HW1_LAST_TLS_GD:
+ case R_TILEGX_IMM16_X0_HW1_LAST_TLS_IE:
+ return R_TILEGX_IMM16_X0_HW1_LAST_TLS_IE;
+
+ case R_TILEGX_IMM16_X1_HW1_LAST_TLS_GD:
+ case R_TILEGX_IMM16_X1_HW1_LAST_TLS_IE:
+ return R_TILEGX_IMM16_X1_HW1_LAST_TLS_IE;
+ }
+ return r_type;
+}
+
+static int
+tilegx_elf_tls_transition (struct bfd_link_info *info, int r_type,
+ int is_local, bfd_boolean disable_le_transition)
+{
+ if (info->shared)
+ return r_type;
+
+ if (is_local && !disable_le_transition)
+ return tilegx_tls_translate_to_le (r_type);
+ else
+ return tilegx_tls_translate_to_ie (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. */
+
+bfd_boolean
+tilegx_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
+ asection *sec, const Elf_Internal_Rela *relocs)
+{
+ struct tilegx_elf_link_hash_table *htab;
+ 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;
+ int num_relocs;
+ bfd_boolean has_tls_gd_or_ie = FALSE, has_tls_add = FALSE;
+
+ if (info->relocatable)
+ return TRUE;
+
+ htab = tilegx_elf_hash_table (info);
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+ sym_hashes = elf_sym_hashes (abfd);
+
+ sreloc = NULL;
+
+ num_relocs = sec->reloc_count;
+
+ BFD_ASSERT (is_tilegx_elf (abfd) || num_relocs == 0);
+
+ if (htab->elf.dynobj == NULL)
+ htab->elf.dynobj = abfd;
+
+ rel_end = relocs + num_relocs;
+
+ /* Check whether to do optimization to transform TLS GD/IE
+ referehces to TLS LE. We disable it if we're linking with old
+ TLS code sequences that do not support such optimization. Old
+ TLS code sequences have tls_gd_call/tls_ie_load relocations but
+ no tls_add relocations. */
+ for (rel = relocs; rel < rel_end && !has_tls_add; rel++)
+ {
+ int r_type = TILEGX_ELF_R_TYPE (rel->r_info);
+ switch (r_type)
+ {
+ case R_TILEGX_TLS_GD_CALL:
+ case R_TILEGX_TLS_IE_LOAD:
+ has_tls_gd_or_ie = TRUE;
+ break;
+ case R_TILEGX_IMM8_X0_TLS_ADD:
+ case R_TILEGX_IMM8_Y0_TLS_ADD:
+ case R_TILEGX_IMM8_X1_TLS_ADD:
+ case R_TILEGX_IMM8_Y1_TLS_ADD:
+ has_tls_add = TRUE;
+ break;
+ }
+ }
+
+ sec->sec_flg0 = (has_tls_gd_or_ie && !has_tls_add);
+ htab->disable_le_transition |= sec->sec_flg0;
+
+ for (rel = relocs; rel < rel_end; rel++)
+ {
+ unsigned int r_type;
+ unsigned long r_symndx;
+ struct elf_link_hash_entry *h;
+ int tls_type;
+
+ r_symndx = TILEGX_ELF_R_SYMNDX (htab, rel->r_info);
+ r_type = TILEGX_ELF_R_TYPE (rel->r_info);
+
+ if (r_symndx >= NUM_SHDR_ENTRIES (symtab_hdr))
+ {
+ (*_bfd_error_handler) (_("%B: bad symbol index: %d"),
+ abfd, r_symndx);
+ return FALSE;
+ }
+
+ if (r_symndx < symtab_hdr->sh_info)
+ h = NULL;
+ 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;
+
+ /* PR15323, ref flags aren't set for references in the same
+ object. */
+ h->root.non_ir_ref = 1;
+ }
+
+ r_type = tilegx_elf_tls_transition (info, r_type, h == NULL,
+ sec->sec_flg0);
+ switch (r_type)
+ {
+ case R_TILEGX_IMM16_X0_HW0_TLS_LE:
+ case R_TILEGX_IMM16_X1_HW0_TLS_LE:
+ case R_TILEGX_IMM16_X0_HW0_LAST_TLS_LE:
+ case R_TILEGX_IMM16_X1_HW0_LAST_TLS_LE:
+ case R_TILEGX_IMM16_X0_HW1_LAST_TLS_LE:
+ case R_TILEGX_IMM16_X1_HW1_LAST_TLS_LE:
+ if (info->shared)
+ goto r_tilegx_plt32;
+ break;
+
+ case R_TILEGX_IMM16_X0_HW0_TLS_GD:
+ case R_TILEGX_IMM16_X1_HW0_TLS_GD:
+ case R_TILEGX_IMM16_X0_HW0_LAST_TLS_GD:
+ case R_TILEGX_IMM16_X1_HW0_LAST_TLS_GD:
+ case R_TILEGX_IMM16_X0_HW1_LAST_TLS_GD:
+ case R_TILEGX_IMM16_X1_HW1_LAST_TLS_GD:
+ BFD_ASSERT (info->shared);
+ tls_type = GOT_TLS_GD;
+ goto have_got_reference;
+
+ case R_TILEGX_IMM16_X0_HW0_TLS_IE:
+ case R_TILEGX_IMM16_X1_HW0_TLS_IE:
+ case R_TILEGX_IMM16_X0_HW0_LAST_TLS_IE:
+ case R_TILEGX_IMM16_X1_HW0_LAST_TLS_IE:
+ case R_TILEGX_IMM16_X0_HW1_LAST_TLS_IE:
+ case R_TILEGX_IMM16_X1_HW1_LAST_TLS_IE:
+ tls_type = GOT_TLS_IE;
+ if (info->shared)
+ info->flags |= DF_STATIC_TLS;
+ goto have_got_reference;
+
+ case R_TILEGX_IMM16_X0_HW0_GOT:
+ case R_TILEGX_IMM16_X1_HW0_GOT:
+ case R_TILEGX_IMM16_X0_HW0_LAST_GOT:
+ case R_TILEGX_IMM16_X1_HW0_LAST_GOT:
+ case R_TILEGX_IMM16_X0_HW1_LAST_GOT:
+ case R_TILEGX_IMM16_X1_HW1_LAST_GOT:
+ tls_type = GOT_NORMAL;
+ /* Fall Through */
+
+ have_got_reference:
+ /* This symbol requires a global offset table entry. */
+ {
+ int old_tls_type;
+
+ if (h != NULL)
+ {
+ h->got.refcount += 1;
+ old_tls_type = tilegx_elf_hash_entry(h)->tls_type;
+ }
+ else
+ {
+ bfd_signed_vma *local_got_refcounts;
+
+ /* This is a global offset table entry for a local symbol. */
+ local_got_refcounts = elf_local_got_refcounts (abfd);
+ if (local_got_refcounts == NULL)
+ {
+ bfd_size_type size;
+
+ size = symtab_hdr->sh_info;
+ size *= (sizeof (bfd_signed_vma) + sizeof(char));
+ local_got_refcounts = ((bfd_signed_vma *)
+ bfd_zalloc (abfd, size));
+ if (local_got_refcounts == NULL)
+ return FALSE;
+ elf_local_got_refcounts (abfd) = local_got_refcounts;
+ _bfd_tilegx_elf_local_got_tls_type (abfd)
+ = (char *) (local_got_refcounts + symtab_hdr->sh_info);
+ }
+ local_got_refcounts[r_symndx] += 1;
+ old_tls_type = _bfd_tilegx_elf_local_got_tls_type (abfd) [r_symndx];
+ }
+
+ /* If a TLS symbol is accessed using IE at least once,
+ there is no point to use dynamic model for it. */
+ if (old_tls_type != tls_type && old_tls_type != GOT_UNKNOWN
+ && (old_tls_type != GOT_TLS_GD
+ || tls_type != GOT_TLS_IE))
+ {
+ if (old_tls_type == GOT_TLS_IE && tls_type == GOT_TLS_GD)
+ tls_type = old_tls_type;
+ else
+ {
+ (*_bfd_error_handler)
+ (_("%B: `%s' accessed both as normal and thread local symbol"),
+ abfd, h ? h->root.root.string : "<local>");
+ return FALSE;
+ }
+ }
+
+ if (old_tls_type != tls_type)
+ {
+ if (h != NULL)
+ tilegx_elf_hash_entry (h)->tls_type = tls_type;
+ else
+ _bfd_tilegx_elf_local_got_tls_type (abfd) [r_symndx] = tls_type;
+ }
+ }
+
+ if (htab->elf.sgot == NULL)
+ {
+ if (!tilegx_elf_create_got_section (htab->elf.dynobj, info))
+ return FALSE;
+ }
+ break;
+
+ case R_TILEGX_TLS_GD_CALL:
+ if (info->shared)
+ {
+ /* These are basically R_TILEGX_JUMPOFF_X1_PLT relocs
+ against __tls_get_addr. */
+ struct bfd_link_hash_entry *bh = NULL;
+ if (! _bfd_generic_link_add_one_symbol (info, abfd,
+ "__tls_get_addr", 0,
+ bfd_und_section_ptr, 0,
+ NULL, FALSE, FALSE,
+ &bh))
+ return FALSE;
+ h = (struct elf_link_hash_entry *) bh;
+ }
+ else
+ break;
+ /* Fall through */
+
+ case R_TILEGX_JUMPOFF_X1_PLT:
+ case R_TILEGX_IMM16_X0_HW0_PLT_PCREL:
+ case R_TILEGX_IMM16_X1_HW0_PLT_PCREL:
+ case R_TILEGX_IMM16_X0_HW1_PLT_PCREL:
+ case R_TILEGX_IMM16_X1_HW1_PLT_PCREL:
+ case R_TILEGX_IMM16_X0_HW2_PLT_PCREL:
+ case R_TILEGX_IMM16_X1_HW2_PLT_PCREL:
+ case R_TILEGX_IMM16_X0_HW3_PLT_PCREL:
+ case R_TILEGX_IMM16_X1_HW3_PLT_PCREL:
+ case R_TILEGX_IMM16_X0_HW0_LAST_PLT_PCREL:
+ case R_TILEGX_IMM16_X1_HW0_LAST_PLT_PCREL:
+ case R_TILEGX_IMM16_X0_HW1_LAST_PLT_PCREL:
+ case R_TILEGX_IMM16_X1_HW1_LAST_PLT_PCREL:
+ case R_TILEGX_IMM16_X0_HW2_LAST_PLT_PCREL:
+ case R_TILEGX_IMM16_X1_HW2_LAST_PLT_PCREL:
+ /* 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)
+ {
+ h->needs_plt = 1;
+ h->plt.refcount += 1;
+ }
+ break;
+
+ case R_TILEGX_64_PCREL:
+ case R_TILEGX_32_PCREL:
+ case R_TILEGX_16_PCREL:
+ case R_TILEGX_8_PCREL:
+ case R_TILEGX_IMM16_X0_HW0_PCREL:
+ case R_TILEGX_IMM16_X1_HW0_PCREL:
+ case R_TILEGX_IMM16_X0_HW1_PCREL:
+ case R_TILEGX_IMM16_X1_HW1_PCREL:
+ case R_TILEGX_IMM16_X0_HW2_PCREL:
+ case R_TILEGX_IMM16_X1_HW2_PCREL:
+ case R_TILEGX_IMM16_X0_HW3_PCREL:
+ case R_TILEGX_IMM16_X1_HW3_PCREL:
+ case R_TILEGX_IMM16_X0_HW0_LAST_PCREL:
+ case R_TILEGX_IMM16_X1_HW0_LAST_PCREL:
+ case R_TILEGX_IMM16_X0_HW1_LAST_PCREL:
+ case R_TILEGX_IMM16_X1_HW1_LAST_PCREL:
+ case R_TILEGX_IMM16_X0_HW2_LAST_PCREL:
+ case R_TILEGX_IMM16_X1_HW2_LAST_PCREL:
+ if (h != NULL)
+ h->non_got_ref = 1;
+
+ if (h != NULL
+ && strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0)
+ break;
+ /* Fall through. */
+
+ case R_TILEGX_64:
+ case R_TILEGX_32:
+ case R_TILEGX_16:
+ case R_TILEGX_8:
+ case R_TILEGX_HW0:
+ case R_TILEGX_HW1:
+ case R_TILEGX_HW2:
+ case R_TILEGX_HW3:
+ case R_TILEGX_HW0_LAST:
+ case R_TILEGX_HW1_LAST:
+ case R_TILEGX_HW2_LAST:
+ case R_TILEGX_COPY:
+ case R_TILEGX_GLOB_DAT:
+ case R_TILEGX_JMP_SLOT:
+ case R_TILEGX_RELATIVE:
+ case R_TILEGX_BROFF_X1:
+ case R_TILEGX_JUMPOFF_X1:
+ case R_TILEGX_IMM8_X0:
+ case R_TILEGX_IMM8_Y0:
+ case R_TILEGX_IMM8_X1:
+ case R_TILEGX_IMM8_Y1:
+ case R_TILEGX_DEST_IMM8_X1:
+ case R_TILEGX_MT_IMM14_X1:
+ case R_TILEGX_MF_IMM14_X1:
+ case R_TILEGX_MMSTART_X0:
+ case R_TILEGX_MMEND_X0:
+ case R_TILEGX_SHAMT_X0:
+ case R_TILEGX_SHAMT_X1:
+ case R_TILEGX_SHAMT_Y0:
+ case R_TILEGX_SHAMT_Y1:
+ case R_TILEGX_IMM16_X0_HW0:
+ case R_TILEGX_IMM16_X1_HW0:
+ case R_TILEGX_IMM16_X0_HW1:
+ case R_TILEGX_IMM16_X1_HW1:
+ case R_TILEGX_IMM16_X0_HW2:
+ case R_TILEGX_IMM16_X1_HW2:
+ case R_TILEGX_IMM16_X0_HW3:
+ case R_TILEGX_IMM16_X1_HW3:
+ case R_TILEGX_IMM16_X0_HW0_LAST:
+ case R_TILEGX_IMM16_X1_HW0_LAST:
+ case R_TILEGX_IMM16_X0_HW1_LAST:
+ case R_TILEGX_IMM16_X1_HW1_LAST:
+ case R_TILEGX_IMM16_X0_HW2_LAST:
+ case R_TILEGX_IMM16_X1_HW2_LAST:
+ if (h != NULL)
+ h->non_got_ref = 1;
+
+ r_tilegx_plt32:
+ if (h != NULL && !info->shared)
+ {
+ /* We may need a .plt entry if the function this reloc
+ refers to is in a shared lib. */
+ h->plt.refcount += 1;
+ }
+
+ /* 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). In case of a weak definition,
+ DEF_REGULAR may be cleared later by a strong definition in
+ a shared library. We account for that possibility below by
+ storing information in the relocs_copied field of the hash
+ table entry. A similar situation occurs when creating
+ shared libraries and symbol visibility changes render the
+ symbol local.
+
+ If on the other hand, we are creating an executable, we
+ may need to keep relocations for symbols satisfied by a
+ dynamic library if we manage to avoid copy relocs for the
+ symbol. */
+ if ((info->shared
+ && (sec->flags & SEC_ALLOC) != 0
+ && (! tilegx_elf_howto_table[r_type].pc_relative
+ || (h != NULL
+ && (! info->symbolic
+ || h->root.type == bfd_link_hash_defweak
+ || !h->def_regular))))
+ || (!info->shared
+ && (sec->flags & SEC_ALLOC) != 0
+ && h != NULL
+ && (h->root.type == bfd_link_hash_defweak
+ || !h->def_regular)))
+ {
+ struct tilegx_elf_dyn_relocs *p;
+ struct tilegx_elf_dyn_relocs **head;
+
+ /* 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)
+ {
+ sreloc = _bfd_elf_make_dynamic_reloc_section
+ (sec, htab->elf.dynobj, htab->word_align_power, abfd,
+ /*rela?*/ TRUE);
+
+ if (sreloc == NULL)
+ return FALSE;
+ }
+
+ /* If this is a global symbol, we count the number of
+ relocations we need for this symbol. */
+ if (h != NULL)
+ head =
+ &((struct tilegx_elf_link_hash_entry *) h)->dyn_relocs;
+ else
+ {
+ /* Track dynamic relocs needed for local syms too.
+ We really need local syms available to do this
+ easily. Oh well. */
+
+ asection *s;
+ void *vpp;
+ Elf_Internal_Sym *isym;
+
+ isym = bfd_sym_from_r_symndx (&htab->sym_cache,
+ abfd, r_symndx);
+ if (isym == NULL)
+ return FALSE;
+
+ s = bfd_section_from_elf_index (abfd, isym->st_shndx);
+ if (s == NULL)
+ s = sec;
+
+ vpp = &elf_section_data (s)->local_dynrel;
+ head = (struct tilegx_elf_dyn_relocs **) vpp;
+ }
+
+ p = *head;
+ if (p == NULL || p->sec != sec)
+ {
+ bfd_size_type amt = sizeof *p;
+ p = ((struct tilegx_elf_dyn_relocs *)
+ bfd_alloc (htab->elf.dynobj, amt));
+ if (p == NULL)
+ return FALSE;
+ p->next = *head;
+ *head = p;
+ p->sec = sec;
+ p->count = 0;
+ p->pc_count = 0;
+ }
+
+ p->count += 1;
+ if (tilegx_elf_howto_table[r_type].pc_relative)
+ p->pc_count += 1;
+ }
+
+ break;
+
+ case R_TILEGX_GNU_VTINHERIT:
+ if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
+ return FALSE;
+ break;
+
+ case R_TILEGX_GNU_VTENTRY:
+ if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
+ return FALSE;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ return TRUE;
+}
+
+
+asection *
+tilegx_elf_gc_mark_hook (asection *sec,
+ struct bfd_link_info *info,
+ Elf_Internal_Rela *rel,
+ struct elf_link_hash_entry *h,
+ Elf_Internal_Sym *sym)
+{
+ if (h != NULL)
+ {
+ switch (TILEGX_ELF_R_TYPE (rel->r_info))
+ {
+ case R_TILEGX_GNU_VTINHERIT:
+ case R_TILEGX_GNU_VTENTRY:
+ return NULL;
+ }
+ }
+
+ /* FIXME: The test here, in check_relocs and in relocate_section
+ dealing with TLS optimization, ought to be !info->executable. */
+ if (info->shared)
+ {
+ switch (TILEGX_ELF_R_TYPE (rel->r_info))
+ {
+ case R_TILEGX_TLS_GD_CALL:
+ /* This reloc implicitly references __tls_get_addr. We know
+ another reloc will reference the same symbol as the one
+ on this reloc, so the real symbol and section will be
+ gc marked when processing the other reloc. That lets
+ us handle __tls_get_addr here. */
+ h = elf_link_hash_lookup (elf_hash_table (info), "__tls_get_addr",
+ FALSE, FALSE, TRUE);
+ BFD_ASSERT (h != NULL);
+ h->mark = 1;
+ if (h->u.weakdef != NULL)
+ h->u.weakdef->mark = 1;
+ sym = NULL;
+ }
+ }
+
+ return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
+}
+
+/* Update the got entry reference counts for the section being removed. */
+bfd_boolean
+tilegx_elf_gc_sweep_hook (bfd *abfd, struct bfd_link_info *info,
+ asection *sec, const Elf_Internal_Rela *relocs)
+{
+ struct tilegx_elf_link_hash_table *htab;
+ Elf_Internal_Shdr *symtab_hdr;
+ struct elf_link_hash_entry **sym_hashes;
+ bfd_signed_vma *local_got_refcounts;
+ const Elf_Internal_Rela *rel, *relend;
+
+ if (info->relocatable)
+ return TRUE;
+
+ BFD_ASSERT (is_tilegx_elf (abfd) || sec->reloc_count == 0);
+
+ elf_section_data (sec)->local_dynrel = NULL;
+
+ htab = tilegx_elf_hash_table (info);
+ BFD_ASSERT (htab != NULL);
+ symtab_hdr = &elf_symtab_hdr (abfd);
+ 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++)
+ {
+ unsigned long r_symndx;
+ unsigned int r_type;
+ struct elf_link_hash_entry *h = NULL;
+
+ r_symndx = TILEGX_ELF_R_SYMNDX (htab, rel->r_info);
+ if (r_symndx >= symtab_hdr->sh_info)
+ {
+ struct tilegx_elf_link_hash_entry *eh;
+ struct tilegx_elf_dyn_relocs **pp;
+ struct tilegx_elf_dyn_relocs *p;
+
+ 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;
+ eh = (struct tilegx_elf_link_hash_entry *) h;
+ for (pp = &eh->dyn_relocs; (p = *pp) != NULL; pp = &p->next)
+ if (p->sec == sec)
+ {
+ /* Everything must go for SEC. */
+ *pp = p->next;
+ break;
+ }
+ }
+
+ r_type = TILEGX_ELF_R_TYPE (rel->r_info);
+ r_type = tilegx_elf_tls_transition (info, r_type, h != NULL,
+ sec->sec_flg0);
+ switch (r_type)
+ {
+ case R_TILEGX_IMM16_X0_HW0_GOT:
+ case R_TILEGX_IMM16_X1_HW0_GOT:
+ case R_TILEGX_IMM16_X0_HW0_LAST_GOT:
+ case R_TILEGX_IMM16_X1_HW0_LAST_GOT:
+ case R_TILEGX_IMM16_X0_HW1_LAST_GOT:
+ case R_TILEGX_IMM16_X1_HW1_LAST_GOT:
+ case R_TILEGX_IMM16_X0_HW0_TLS_GD:
+ case R_TILEGX_IMM16_X1_HW0_TLS_GD:
+ case R_TILEGX_IMM16_X0_HW0_LAST_TLS_GD:
+ case R_TILEGX_IMM16_X1_HW0_LAST_TLS_GD:
+ case R_TILEGX_IMM16_X0_HW1_LAST_TLS_GD:
+ case R_TILEGX_IMM16_X1_HW1_LAST_TLS_GD:
+ case R_TILEGX_IMM16_X0_HW0_TLS_IE:
+ case R_TILEGX_IMM16_X1_HW0_TLS_IE:
+ case R_TILEGX_IMM16_X0_HW0_LAST_TLS_IE:
+ case R_TILEGX_IMM16_X1_HW0_LAST_TLS_IE:
+ case R_TILEGX_IMM16_X0_HW1_LAST_TLS_IE:
+ case R_TILEGX_IMM16_X1_HW1_LAST_TLS_IE:
+ if (h != NULL)
+ {
+ if (h->got.refcount > 0)
+ h->got.refcount--;
+ }
+ else
+ {
+ if (local_got_refcounts &&
+ local_got_refcounts[r_symndx] > 0)
+ local_got_refcounts[r_symndx]--;
+ }
+ break;
+
+ case R_TILEGX_64_PCREL:
+ case R_TILEGX_32_PCREL:
+ case R_TILEGX_16_PCREL:
+ case R_TILEGX_8_PCREL:
+ case R_TILEGX_IMM16_X0_HW0_PCREL:
+ case R_TILEGX_IMM16_X1_HW0_PCREL:
+ case R_TILEGX_IMM16_X0_HW1_PCREL:
+ case R_TILEGX_IMM16_X1_HW1_PCREL:
+ case R_TILEGX_IMM16_X0_HW2_PCREL:
+ case R_TILEGX_IMM16_X1_HW2_PCREL:
+ case R_TILEGX_IMM16_X0_HW3_PCREL:
+ case R_TILEGX_IMM16_X1_HW3_PCREL:
+ case R_TILEGX_IMM16_X0_HW0_LAST_PCREL:
+ case R_TILEGX_IMM16_X1_HW0_LAST_PCREL:
+ case R_TILEGX_IMM16_X0_HW1_LAST_PCREL:
+ case R_TILEGX_IMM16_X1_HW1_LAST_PCREL:
+ case R_TILEGX_IMM16_X0_HW2_LAST_PCREL:
+ case R_TILEGX_IMM16_X1_HW2_LAST_PCREL:
+ if (h != NULL
+ && strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0)
+ break;
+ /* Fall through. */
+
+ case R_TILEGX_64:
+ case R_TILEGX_32:
+ case R_TILEGX_16:
+ case R_TILEGX_8:
+ case R_TILEGX_HW0:
+ case R_TILEGX_HW1:
+ case R_TILEGX_HW2:
+ case R_TILEGX_HW3:
+ case R_TILEGX_HW0_LAST:
+ case R_TILEGX_HW1_LAST:
+ case R_TILEGX_HW2_LAST:
+ case R_TILEGX_COPY:
+ case R_TILEGX_GLOB_DAT:
+ case R_TILEGX_JMP_SLOT:
+ case R_TILEGX_RELATIVE:
+ case R_TILEGX_BROFF_X1:
+ case R_TILEGX_JUMPOFF_X1:
+ case R_TILEGX_IMM8_X0:
+ case R_TILEGX_IMM8_Y0:
+ case R_TILEGX_IMM8_X1:
+ case R_TILEGX_IMM8_Y1:
+ case R_TILEGX_DEST_IMM8_X1:
+ case R_TILEGX_MT_IMM14_X1:
+ case R_TILEGX_MF_IMM14_X1:
+ case R_TILEGX_MMSTART_X0:
+ case R_TILEGX_MMEND_X0:
+ case R_TILEGX_SHAMT_X0:
+ case R_TILEGX_SHAMT_X1:
+ case R_TILEGX_SHAMT_Y0:
+ case R_TILEGX_SHAMT_Y1:
+ case R_TILEGX_IMM16_X0_HW0:
+ case R_TILEGX_IMM16_X1_HW0:
+ case R_TILEGX_IMM16_X0_HW1:
+ case R_TILEGX_IMM16_X1_HW1:
+ case R_TILEGX_IMM16_X0_HW2:
+ case R_TILEGX_IMM16_X1_HW2:
+ case R_TILEGX_IMM16_X0_HW3:
+ case R_TILEGX_IMM16_X1_HW3:
+ case R_TILEGX_IMM16_X0_HW0_LAST:
+ case R_TILEGX_IMM16_X1_HW0_LAST:
+ case R_TILEGX_IMM16_X0_HW1_LAST:
+ case R_TILEGX_IMM16_X1_HW1_LAST:
+ case R_TILEGX_IMM16_X0_HW2_LAST:
+ case R_TILEGX_IMM16_X1_HW2_LAST:
+ if (info->shared)
+ break;
+ /* Fall through. */
+
+ case R_TILEGX_JUMPOFF_X1_PLT:
+ case R_TILEGX_IMM16_X0_HW0_PLT_PCREL:
+ case R_TILEGX_IMM16_X1_HW0_PLT_PCREL:
+ case R_TILEGX_IMM16_X0_HW1_PLT_PCREL:
+ case R_TILEGX_IMM16_X1_HW1_PLT_PCREL:
+ case R_TILEGX_IMM16_X0_HW2_PLT_PCREL:
+ case R_TILEGX_IMM16_X1_HW2_PLT_PCREL:
+ case R_TILEGX_IMM16_X0_HW3_PLT_PCREL:
+ case R_TILEGX_IMM16_X1_HW3_PLT_PCREL:
+ case R_TILEGX_IMM16_X0_HW0_LAST_PLT_PCREL:
+ case R_TILEGX_IMM16_X1_HW0_LAST_PLT_PCREL:
+ case R_TILEGX_IMM16_X0_HW1_LAST_PLT_PCREL:
+ case R_TILEGX_IMM16_X1_HW1_LAST_PLT_PCREL:
+ case R_TILEGX_IMM16_X0_HW2_LAST_PLT_PCREL:
+ case R_TILEGX_IMM16_X1_HW2_LAST_PLT_PCREL:
+ if (h != NULL)
+ {
+ 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. */
+
+bfd_boolean
+tilegx_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
+ struct elf_link_hash_entry *h)
+{
+ struct tilegx_elf_link_hash_table *htab;
+ struct tilegx_elf_link_hash_entry * eh;
+ struct tilegx_elf_dyn_relocs *p;
+ bfd *dynobj;
+ asection *s;
+
+ htab = tilegx_elf_hash_table (info);
+ BFD_ASSERT (htab != NULL);
+
+ dynobj = htab->elf.dynobj;
+
+ /* Make sure we know what is going on here. */
+ BFD_ASSERT (dynobj != NULL
+ && (h->needs_plt
+ || h->u.weakdef != NULL
+ || (h->def_dynamic
+ && h->ref_regular
+ && !h->def_regular)));
+
+ /* 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). */
+ if (h->type == STT_FUNC || h->needs_plt)
+ {
+ if (h->plt.refcount <= 0
+ || SYMBOL_CALLS_LOCAL (info, h)
+ || (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
+ && h->root.type == bfd_link_hash_undefweak))
+ {
+ /* This case can occur if we saw a R_TILEGX_JUMPOFF_X1_PLT
+ reloc in an input file, but the symbol was never referred
+ to by a dynamic object, or if all references were garbage
+ collected. In such a case, we don't actually need to build
+ a procedure linkage table, and we can just do a
+ R_TILEGX_JUMPOFF_X1 relocation instead. */
+ h->plt.offset = (bfd_vma) -1;
+ h->needs_plt = 0;
+ }
+
+ return TRUE;
+ }
+ else
+ 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->u.weakdef != NULL)
+ {
+ BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
+ || h->u.weakdef->root.type == bfd_link_hash_defweak);
+ h->root.u.def.section = h->u.weakdef->root.u.def.section;
+ h->root.u.def.value = h->u.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;
+
+ /* If there are no references to this symbol that do not use the
+ GOT, we don't need to generate a copy reloc. */
+ if (!h->non_got_ref)
+ return TRUE;
+
+ /* If -z nocopyreloc was given, we won't generate them either. */
+ if (info->nocopyreloc)
+ {
+ h->non_got_ref = 0;
+ return TRUE;
+ }
+
+ eh = (struct tilegx_elf_link_hash_entry *) h;
+ for (p = eh->dyn_relocs; p != NULL; p = p->next)
+ {
+ s = p->sec->output_section;
+ if (s != NULL && (s->flags & SEC_READONLY) != 0)
+ break;
+ }
+
+ /* If we didn't find any dynamic relocs in read-only sections, then
+ we'll be keeping the dynamic relocs and avoiding the copy reloc. */
+ if (p == NULL)
+ {
+ h->non_got_ref = 0;
+ 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. */
+
+ /* We must generate a R_TILEGX_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 && h->size != 0)
+ {
+ htab->srelbss->size += TILEGX_ELF_RELA_BYTES (htab);
+ h->needs_copy = 1;
+ }
+
+ return _bfd_elf_adjust_dynamic_copy (h, htab->sdynbss);
+}
+
+/* Allocate space in .plt, .got and associated reloc sections for
+ dynamic relocs. */
+
+static bfd_boolean
+allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
+{
+ struct bfd_link_info *info;
+ struct tilegx_elf_link_hash_table *htab;
+ struct tilegx_elf_link_hash_entry *eh;
+ struct tilegx_elf_dyn_relocs *p;
+
+ if (h->root.type == bfd_link_hash_indirect)
+ return TRUE;
+
+ info = (struct bfd_link_info *) inf;
+ htab = tilegx_elf_hash_table (info);
+ BFD_ASSERT (htab != NULL);
+
+ if (htab->elf.dynamic_sections_created
+ && h->plt.refcount > 0)
+ {
+ /* Make sure this symbol is output as a dynamic symbol.
+ Undefined weak syms won't yet be marked as dynamic. */
+ if (h->dynindx == -1
+ && !h->forced_local)
+ {
+ if (! bfd_elf_link_record_dynamic_symbol (info, h))
+ return FALSE;
+ }
+
+ if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, info->shared, h))
+ {
+ asection *s = htab->elf.splt;
+
+ /* Allocate room for the header and tail. */
+ if (s->size == 0)
+ {
+ s->size = PLT_ENTRY_SIZE;
+ }
+
+ h->plt.offset = s->size - PLT_ENTRY_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->def_regular)
+ {
+ h->root.u.def.section = s;
+ h->root.u.def.value = h->plt.offset;
+ }
+
+ /* Make room for this entry. */
+ s->size += PLT_ENTRY_SIZE;
+
+ /* We also need to make an entry in the .got.plt section. */
+ htab->elf.sgotplt->size += GOT_ENTRY_SIZE (htab);
+
+ /* We also need to make an entry in the .rela.plt section. */
+ htab->elf.srelplt->size += TILEGX_ELF_RELA_BYTES (htab);
+ }
+ else
+ {
+ h->plt.offset = (bfd_vma) -1;
+ h->needs_plt = 0;
+ }
+ }
+ else
+ {
+ h->plt.offset = (bfd_vma) -1;
+ h->needs_plt = 0;
+ }
+
+ /* If a TLS_IE symbol is now local to the binary, make it a TLS_LE
+ requiring no TLS entry. */
+ if (h->got.refcount > 0
+ && !htab->disable_le_transition
+ && !info->shared
+ && h->dynindx == -1
+ && tilegx_elf_hash_entry(h)->tls_type == GOT_TLS_IE)
+ h->got.offset = (bfd_vma) -1;
+ else if (h->got.refcount > 0)
+ {
+ asection *s;
+ bfd_boolean dyn;
+ int tls_type = tilegx_elf_hash_entry(h)->tls_type;
+
+ /* Make sure this symbol is output as a dynamic symbol.
+ Undefined weak syms won't yet be marked as dynamic. */
+ if (h->dynindx == -1
+ && !h->forced_local)
+ {
+ if (! bfd_elf_link_record_dynamic_symbol (info, h))
+ return FALSE;
+ }
+
+ s = htab->elf.sgot;
+ h->got.offset = s->size;
+ s->size += TILEGX_ELF_WORD_BYTES (htab);
+ /* TLS_GD entries need 2 consecutive GOT slots. */
+ if (tls_type == GOT_TLS_GD)
+ s->size += TILEGX_ELF_WORD_BYTES (htab);
+ dyn = htab->elf.dynamic_sections_created;
+ /* TLS_IE needs one dynamic relocation,
+ TLS_GD needs two if local symbol and two if global. */
+ if (tls_type == GOT_TLS_GD || tls_type == GOT_TLS_IE)
+ htab->elf.srelgot->size += 2 * TILEGX_ELF_RELA_BYTES (htab);
+ else if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h))
+ htab->elf.srelgot->size += TILEGX_ELF_RELA_BYTES (htab);
+ }
+ else
+ h->got.offset = (bfd_vma) -1;
+
+ eh = (struct tilegx_elf_link_hash_entry *) h;
+ if (eh->dyn_relocs == NULL)
+ return TRUE;
+
+ /* In the shared -Bsymbolic case, discard space allocated for
+ dynamic pc-relative relocs against symbols which turn out to be
+ defined in regular objects. For the normal shared case, discard
+ space for pc-relative relocs that have become local due to symbol
+ visibility changes. */
+
+ if (info->shared)
+ {
+ if (SYMBOL_CALLS_LOCAL (info, h))
+ {
+ struct tilegx_elf_dyn_relocs **pp;
+
+ for (pp = &eh->dyn_relocs; (p = *pp) != NULL; )
+ {
+ p->count -= p->pc_count;
+ p->pc_count = 0;
+ if (p->count == 0)
+ *pp = p->next;
+ else
+ pp = &p->next;
+ }
+ }
+
+ /* Also discard relocs on undefined weak syms with non-default
+ visibility. */
+ if (eh->dyn_relocs != NULL
+ && h->root.type == bfd_link_hash_undefweak)
+ {
+ if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
+ eh->dyn_relocs = NULL;
+
+ /* Make sure undefined weak symbols are output as a dynamic
+ symbol in PIEs. */
+ else if (h->dynindx == -1
+ && !h->forced_local)
+ {
+ if (! bfd_elf_link_record_dynamic_symbol (info, h))
+ return FALSE;
+ }
+ }
+ }
+ else
+ {
+ /* For the non-shared case, discard space for relocs against
+ symbols which turn out to need copy relocs or are not
+ dynamic. */
+
+ if (!h->non_got_ref
+ && ((h->def_dynamic
+ && !h->def_regular)
+ || (htab->elf.dynamic_sections_created
+ && (h->root.type == bfd_link_hash_undefweak
+ || h->root.type == bfd_link_hash_undefined))))
+ {
+ /* Make sure this symbol is output as a dynamic symbol.
+ Undefined weak syms won't yet be marked as dynamic. */
+ if (h->dynindx == -1
+ && !h->forced_local)
+ {
+ if (! bfd_elf_link_record_dynamic_symbol (info, h))
+ return FALSE;
+ }
+
+ /* If that succeeded, we know we'll be keeping all the
+ relocs. */
+ if (h->dynindx != -1)
+ goto keep;
+ }
+
+ eh->dyn_relocs = NULL;
+
+ keep: ;
+ }
+
+ /* Finally, allocate space. */
+ for (p = eh->dyn_relocs; p != NULL; p = p->next)
+ {
+ asection *sreloc = elf_section_data (p->sec)->sreloc;
+ sreloc->size += p->count * TILEGX_ELF_RELA_BYTES (htab);
+ }
+
+ return TRUE;
+}
+
+/* Find any dynamic relocs that apply to read-only sections. */
+
+static bfd_boolean
+readonly_dynrelocs (struct elf_link_hash_entry *h, void *inf)
+{
+ struct tilegx_elf_link_hash_entry *eh;
+ struct tilegx_elf_dyn_relocs *p;
+
+ eh = (struct tilegx_elf_link_hash_entry *) h;
+ for (p = eh->dyn_relocs; p != NULL; p = p->next)
+ {
+ asection *s = p->sec->output_section;
+
+ if (s != NULL && (s->flags & SEC_READONLY) != 0)
+ {
+ struct bfd_link_info *info = (struct bfd_link_info *) inf;
+
+ info->flags |= DF_TEXTREL;
+
+ /* Not an error, just cut short the traversal. */
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+/* Return true if the dynamic symbol for a given section should be
+ omitted when creating a shared library. */
+
+bfd_boolean
+tilegx_elf_omit_section_dynsym (bfd *output_bfd,
+ struct bfd_link_info *info,
+ asection *p)
+{
+ /* We keep the .got section symbol so that explicit relocations
+ against the _GLOBAL_OFFSET_TABLE_ symbol emitted in PIC mode
+ can be turned into relocations against the .got symbol. */
+ if (strcmp (p->name, ".got") == 0)
+ return FALSE;
+
+ return _bfd_elf_link_omit_section_dynsym (output_bfd, info, p);
+}
+
+bfd_boolean
+tilegx_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
+ struct bfd_link_info *info)
+{
+ struct tilegx_elf_link_hash_table *htab;
+ bfd *dynobj;
+ asection *s;
+ bfd *ibfd;
+
+ htab = tilegx_elf_hash_table (info);
+ BFD_ASSERT (htab != NULL);
+ dynobj = htab->elf.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->executable)
+ {
+ s = bfd_get_linker_section (dynobj, ".interp");
+ BFD_ASSERT (s != NULL);
+ s->size = strlen (htab->dynamic_interpreter) + 1;
+ s->contents = (unsigned char *) htab->dynamic_interpreter;
+ }
+ }
+
+ /* Set up .got offsets for local syms, and space for local dynamic
+ relocs. */
+ for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next)
+ {
+ bfd_signed_vma *local_got;
+ bfd_signed_vma *end_local_got;
+ char *local_tls_type;
+ bfd_size_type locsymcount;
+ Elf_Internal_Shdr *symtab_hdr;
+ asection *srel;
+
+ if (! is_tilegx_elf (ibfd))
+ continue;
+
+ for (s = ibfd->sections; s != NULL; s = s->next)
+ {
+ struct tilegx_elf_dyn_relocs *p;
+
+ for (p = elf_section_data (s)->local_dynrel; p != NULL; p = p->next)
+ {
+ if (!bfd_is_abs_section (p->sec)
+ && bfd_is_abs_section (p->sec->output_section))
+ {
+ /* Input section has been discarded, either because
+ it is a copy of a linkonce section or due to
+ linker script /DISCARD/, so we'll be discarding
+ the relocs too. */
+ }
+ else if (p->count != 0)
+ {
+ srel = elf_section_data (p->sec)->sreloc;
+ srel->size += p->count * TILEGX_ELF_RELA_BYTES (htab);
+ if ((p->sec->output_section->flags & SEC_READONLY) != 0)
+ info->flags |= DF_TEXTREL;
+ }
+ }
+ }
+
+ local_got = elf_local_got_refcounts (ibfd);
+ if (!local_got)
+ continue;
+
+ symtab_hdr = &elf_symtab_hdr (ibfd);
+ locsymcount = symtab_hdr->sh_info;
+ end_local_got = local_got + locsymcount;
+ local_tls_type = _bfd_tilegx_elf_local_got_tls_type (ibfd);
+ s = htab->elf.sgot;
+ srel = htab->elf.srelgot;
+ for (; local_got < end_local_got; ++local_got, ++local_tls_type)
+ {
+ if (*local_got > 0)
+ {
+ *local_got = s->size;
+ s->size += TILEGX_ELF_WORD_BYTES (htab);
+ if (*local_tls_type == GOT_TLS_GD)
+ s->size += TILEGX_ELF_WORD_BYTES (htab);
+ if (info->shared
+ || *local_tls_type == GOT_TLS_GD
+ || *local_tls_type == GOT_TLS_IE)
+ srel->size += TILEGX_ELF_RELA_BYTES (htab);
+ }
+ else
+ *local_got = (bfd_vma) -1;
+ }
+ }
+
+ /* Allocate global sym .plt and .got entries, and space for global
+ sym dynamic relocs. */
+ elf_link_hash_traverse (&htab->elf, allocate_dynrelocs, info);
+
+ if (elf_hash_table (info)->dynamic_sections_created)
+ {
+ /* If the .got section is more than 0x8000 bytes, we add
+ 0x8000 to the value of _GLOBAL_OFFSET_TABLE_, so that 16
+ bit relocations have a greater chance of working. */
+ if (htab->elf.sgot->size >= 0x8000
+ && elf_hash_table (info)->hgot->root.u.def.value == 0)
+ elf_hash_table (info)->hgot->root.u.def.value = 0x8000;
+ }
+
+ if (htab->elf.sgotplt)
+ {
+ struct elf_link_hash_entry *got;
+ got = elf_link_hash_lookup (elf_hash_table (info),
+ "_GLOBAL_OFFSET_TABLE_",
+ FALSE, FALSE, FALSE);
+
+ /* Don't allocate .got.plt section if there are no GOT nor PLT
+ entries and there is no refeence to _GLOBAL_OFFSET_TABLE_. */
+ if ((got == NULL
+ || !got->ref_regular_nonweak)
+ && (htab->elf.sgotplt->size
+ == (unsigned)GOTPLT_HEADER_SIZE (htab))
+ && (htab->elf.splt == NULL
+ || htab->elf.splt->size == 0)
+ && (htab->elf.sgot == NULL
+ || (htab->elf.sgot->size
+ == get_elf_backend_data (output_bfd)->got_header_size)))
+ htab->elf.sgotplt->size = 0;
+ }
+
+ /* The check_relocs and adjust_dynamic_symbol entry points have
+ determined the sizes of the various dynamic sections. Allocate
+ memory for them. */
+ for (s = dynobj->sections; s != NULL; s = s->next)
+ {
+ if ((s->flags & SEC_LINKER_CREATED) == 0)
+ continue;
+
+ if (s == htab->elf.splt
+ || s == htab->elf.sgot
+ || s == htab->elf.sgotplt
+ || s == htab->sdynbss)
+ {
+ /* Strip this section if we don't need it; see the
+ comment below. */
+ }
+ else if (strncmp (s->name, ".rela", 5) == 0)
+ {
+ if (s->size != 0)
+ {
+ /* We use the reloc_count field as a counter if we need
+ to copy relocs into the output file. */
+ s->reloc_count = 0;
+ }
+ }
+ else
+ {
+ /* It's not one of our sections. */
+ continue;
+ }
+
+ if (s->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. */
+ s->flags |= SEC_EXCLUDE;
+ continue;
+ }
+
+ if ((s->flags & SEC_HAS_CONTENTS) == 0)
+ 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->size);
+ if (s->contents == NULL)
+ return FALSE;
+ }
+
+ if (elf_hash_table (info)->dynamic_sections_created)
+ {
+ /* Add some entries to the .dynamic section. We fill in the
+ values later, in tilegx_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. */
+#define add_dynamic_entry(TAG, VAL) \
+ _bfd_elf_add_dynamic_entry (info, TAG, VAL)
+
+ if (info->executable)
+ {
+ if (!add_dynamic_entry (DT_DEBUG, 0))
+ return FALSE;
+ }
+
+ if (htab->elf.srelplt->size != 0)
+ {
+ if (!add_dynamic_entry (DT_PLTGOT, 0)
+ || !add_dynamic_entry (DT_PLTRELSZ, 0)
+ || !add_dynamic_entry (DT_PLTREL, DT_RELA)
+ || !add_dynamic_entry (DT_JMPREL, 0))
+ return FALSE;
+ }
+
+ if (!add_dynamic_entry (DT_RELA, 0)
+ || !add_dynamic_entry (DT_RELASZ, 0)
+ || !add_dynamic_entry (DT_RELAENT, TILEGX_ELF_RELA_BYTES (htab)))
+ return FALSE;
+
+ /* If any dynamic relocs apply to a read-only section,
+ then we need a DT_TEXTREL entry. */
+ if ((info->flags & DF_TEXTREL) == 0)
+ elf_link_hash_traverse (&htab->elf, readonly_dynrelocs, info);
+
+ if (info->flags & DF_TEXTREL)
+ {
+ if (!add_dynamic_entry (DT_TEXTREL, 0))
+ return FALSE;
+ }
+ }
+#undef add_dynamic_entry
+
+ return TRUE;
+}
+
+/* Return the base VMA address which should be subtracted from real addresses
+ when resolving @dtpoff relocation.
+ This is PT_TLS segment p_vaddr. */
+
+static bfd_vma
+dtpoff_base (struct bfd_link_info *info)
+{
+ /* If tls_sec is NULL, we should have signalled an error already. */
+ if (elf_hash_table (info)->tls_sec == NULL)
+ return 0;
+ return elf_hash_table (info)->tls_sec->vma;
+}
+
+/* Return the relocation value for @tpoff relocation. */
+
+static bfd_vma
+tpoff (struct bfd_link_info *info, bfd_vma address)
+{
+ struct elf_link_hash_table *htab = elf_hash_table (info);
+
+ /* If tls_sec is NULL, we should have signalled an error already. */
+ if (htab->tls_sec == NULL)
+ return 0;
+
+ return (address - htab->tls_sec->vma);
+}
+
+/* Copy SIZE bits from FROM to TO at address ADDR. */
+
+static void
+tilegx_copy_bits (bfd_byte *addr, int from, int to, int size)
+{
+ int i;
+ for (i = 0; i < size; i++)
+ {
+ int from_byte = (from + i) / 8;
+ int from_bit = (from + i) % 8;
+ int to_byte = (to + i) / 8;
+ int to_bit = (to + i) % 8;
+ bfd_byte to_mask = 1 << to_bit;
+ addr[to_byte] = (addr[to_byte] & ~to_mask)
+ | ((addr[from_byte] >> from_bit << to_bit) & to_mask);
+ }
+}
+
+/* Replace the MASK bits in ADDR with those in INSN, for the next
+ TILEGX_BUNDLE_SIZE_IN_BYTES bytes. */
+
+static void
+tilegx_replace_insn (bfd_byte *addr, const bfd_byte *mask,
+ const bfd_byte *insn)
+{
+ int i;
+ for (i = 0; i < TILEGX_BUNDLE_SIZE_IN_BYTES; i++)
+ {
+ addr[i] = (addr[i] & ~mask[i]) | (insn[i] & mask[i]);
+ }
+}
+
+/* Mask to extract the bits corresponding to an instruction in a
+ specific pipe of a bundle. */
+static const bfd_byte insn_mask_X1[] = {
+ 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0x3f
+};
+
+/* Mask to extract the bits corresponding to an instruction in a
+ specific pipe of a bundle, minus the destination operand and the
+ first source operand. */
+static const bfd_byte insn_mask_X0_no_dest_no_srca[] = {
+ 0x00, 0xf0, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00
+};
+
+static const bfd_byte insn_mask_X1_no_dest_no_srca[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0x3f
+};
+
+static const bfd_byte insn_mask_Y0_no_dest_no_srca[] = {
+ 0x00, 0xf0, 0x0f, 0x78, 0x00, 0x00, 0x00, 0x00
+};
+static const bfd_byte insn_mask_Y1_no_dest_no_srca[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x07, 0x3c
+};
+
+/* Mask to extract the bits corresponding to an instruction in a
+ specific pipe of a bundle, minus the register operands. */
+static const bfd_byte insn_mask_X0_no_operand[] = {
+ 0x00, 0x00, 0xfc, 0x7f, 0x00, 0x00, 0x00, 0x00
+};
+
+static const bfd_byte insn_mask_X1_no_operand[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x3f
+};
+
+static const bfd_byte insn_mask_Y0_no_operand[] = {
+ 0x00, 0x00, 0x0c, 0x78, 0x00, 0x00, 0x00, 0x00
+};
+
+static const bfd_byte insn_mask_Y1_no_operand[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x3c
+};
+
+/* Various instructions synthesized to support tls references. */
+
+/* ld r0, r0 in the X1 pipe, used for tls ie. */
+static const bfd_byte insn_tls_ie_ld_X1[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xe8, 0x6a, 0x28
+};
+
+/* ld4s r0, r0 in the X1 pipe, used for tls ie. */
+static const bfd_byte insn_tls_ie_ld4s_X1[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x98, 0x6a, 0x28
+};
+
+/* add r0, r0, tp in various pipes, used for tls ie. */
+static const bfd_byte insn_tls_ie_add_X0X1[] = {
+ 0x00, 0x50, 0x0f, 0x50, 0x00, 0xa8, 0x07, 0x28
+};
+static const bfd_byte insn_tls_ie_add_Y0Y1[] = {
+ 0x00, 0x50, 0x27, 0x2c, 0x00, 0xa8, 0x13, 0x9a
+};
+
+/* addx r0, r0, tp in various pipes, used for tls ie. */
+static const bfd_byte insn_tls_ie_addx_X0X1[] = {
+ 0x00, 0x50, 0x0b, 0x50, 0x00, 0xa8, 0x05, 0x28
+};
+static const bfd_byte insn_tls_ie_addx_Y0Y1[] = {
+ 0x00, 0x50, 0x03, 0x2c, 0x00, 0xa8, 0x01, 0x9a
+};
+
+/* move r0, r0 in various pipes, used for tls gd. */
+static const bfd_byte insn_tls_gd_add_X0X1[] = {
+ 0x00, 0xf0, 0x07, 0x51, 0x00, 0xf8, 0x3b, 0x28
+};
+static const bfd_byte insn_tls_gd_add_Y0Y1[] = {
+ 0x00, 0xf0, 0x0b, 0x54, 0x00, 0xf8, 0x05, 0xae
+};
+
+static const bfd_byte *insn_move_X0X1 = insn_tls_gd_add_X0X1;
+static const bfd_byte *insn_move_Y0Y1 = insn_tls_gd_add_Y0Y1;
+
+static const bfd_byte *insn_add_X0X1 = insn_tls_ie_add_X0X1;
+static const bfd_byte *insn_add_Y0Y1 = insn_tls_ie_add_Y0Y1;
+
+static const bfd_byte *insn_addx_X0X1 = insn_tls_ie_addx_X0X1;
+static const bfd_byte *insn_addx_Y0Y1 = insn_tls_ie_addx_Y0Y1;
+
+/* Relocate an TILEGX ELF section.
+
+ 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.
+
+ This function is responsible for adjusting the section contents as
+ necessary, and (if generating a relocatable 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 relocatable 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. */
+
+bfd_boolean
+tilegx_elf_relocate_section (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)
+{
+ struct tilegx_elf_link_hash_table *htab;
+ Elf_Internal_Shdr *symtab_hdr;
+ struct elf_link_hash_entry **sym_hashes;
+ bfd_vma *local_got_offsets;
+ bfd_vma got_base;
+ asection *sreloc;
+ Elf_Internal_Rela *rel;
+ Elf_Internal_Rela *relend;
+ int num_relocs;
+
+ htab = tilegx_elf_hash_table (info);
+ BFD_ASSERT (htab != NULL);
+ symtab_hdr = &elf_symtab_hdr (input_bfd);
+ 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;
+
+ sreloc = elf_section_data (input_section)->sreloc;
+
+ rel = relocs;
+ num_relocs = input_section->reloc_count;
+ relend = relocs + num_relocs;
+ for (; rel < relend; rel++)
+ {
+ int r_type, tls_type;
+ bfd_boolean is_tls_iele, is_tls_le;
+ reloc_howto_type *howto;
+ unsigned long r_symndx;
+ struct elf_link_hash_entry *h;
+ Elf_Internal_Sym *sym;
+ tilegx_create_func create_func;
+ asection *sec;
+ bfd_vma relocation;
+ bfd_reloc_status_type r;
+ const char *name;
+ bfd_vma off;
+ bfd_boolean is_plt = FALSE;
+
+ bfd_boolean unresolved_reloc;
+
+ r_type = TILEGX_ELF_R_TYPE (rel->r_info);
+ if (r_type == R_TILEGX_GNU_VTINHERIT
+ || r_type == R_TILEGX_GNU_VTENTRY)
+ continue;
+
+ if ((unsigned int)r_type >= ARRAY_SIZE (tilegx_elf_howto_table))
+ {
+ /* Not clear if we need to check here, but just be paranoid. */
+ (*_bfd_error_handler)
+ (_("%B: unrecognized relocation (0x%x) in section `%A'"),
+ input_bfd, r_type, input_section);
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+
+ howto = tilegx_elf_howto_table + r_type;
+
+ /* This is a final link. */
+ r_symndx = TILEGX_ELF_R_SYMNDX (htab, rel->r_info);
+ h = NULL;
+ sym = NULL;
+ sec = NULL;
+ unresolved_reloc = FALSE;
+ if (r_symndx < symtab_hdr->sh_info)
+ {
+ sym = local_syms + r_symndx;
+ sec = local_sections[r_symndx];
+ relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
+ }
+ else
+ {
+ bfd_boolean warned ATTRIBUTE_UNUSED;
+ bfd_boolean ignored ATTRIBUTE_UNUSED;
+
+ RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
+ r_symndx, symtab_hdr, sym_hashes,
+ h, sec, relocation,
+ unresolved_reloc, warned, ignored);
+ if (warned)
+ {
+ /* To avoid generating warning messages about truncated
+ relocations, set the relocation's address to be the same as
+ the start of this section. */
+ if (input_section->output_section != NULL)
+ relocation = input_section->output_section->vma;
+ else
+ relocation = 0;
+ }
+ }
+
+ if (sec != NULL && discarded_section (sec))
+ RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+ rel, 1, relend, howto, 0, contents);
+
+ if (info->relocatable)
+ continue;
+
+ 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_type)
+ {
+ case R_TILEGX_TLS_GD_CALL:
+ case R_TILEGX_IMM8_X0_TLS_GD_ADD:
+ case R_TILEGX_IMM8_Y0_TLS_GD_ADD:
+ case R_TILEGX_IMM8_X1_TLS_GD_ADD:
+ case R_TILEGX_IMM8_Y1_TLS_GD_ADD:
+ case R_TILEGX_IMM8_X0_TLS_ADD:
+ case R_TILEGX_IMM8_Y0_TLS_ADD:
+ case R_TILEGX_IMM8_X1_TLS_ADD:
+ case R_TILEGX_IMM8_Y1_TLS_ADD:
+ tls_type = GOT_UNKNOWN;
+ if (h == NULL && local_got_offsets)
+ tls_type =
+ _bfd_tilegx_elf_local_got_tls_type (input_bfd) [r_symndx];
+ else if (h != NULL)
+ tls_type = tilegx_elf_hash_entry(h)->tls_type;
+
+ is_tls_iele = (! info->shared || tls_type == GOT_TLS_IE);
+ is_tls_le = is_tls_iele && (!input_section->sec_flg0
+ && !info->shared
+ && (h == NULL || h->dynindx == -1));
+
+ if (r_type == R_TILEGX_TLS_GD_CALL)
+ {
+ if (is_tls_le)
+ {
+ /* GD -> LE */
+ tilegx_replace_insn (contents + rel->r_offset,
+ insn_mask_X1, insn_move_X0X1);
+ continue;
+ }
+ else if (is_tls_iele)
+ {
+ /* GD -> IE */
+ if (ABI_64_P (output_bfd))
+ tilegx_replace_insn (contents + rel->r_offset,
+ insn_mask_X1, insn_tls_ie_ld_X1);
+ else
+ tilegx_replace_insn (contents + rel->r_offset,
+ insn_mask_X1, insn_tls_ie_ld4s_X1);
+ continue;
+ }
+
+ /* GD -> GD */
+ h = (struct elf_link_hash_entry *)
+ bfd_link_hash_lookup (info->hash, "__tls_get_addr", FALSE,
+ FALSE, TRUE);
+ BFD_ASSERT (h != NULL);
+ r_type = R_TILEGX_JUMPOFF_X1_PLT;
+ howto = tilegx_elf_howto_table + r_type;
+ }
+ else if (r_type == R_TILEGX_IMM8_X0_TLS_ADD
+ || r_type == R_TILEGX_IMM8_X1_TLS_ADD
+ || r_type == R_TILEGX_IMM8_Y0_TLS_ADD
+ || r_type == R_TILEGX_IMM8_Y1_TLS_ADD)
+ {
+ bfd_boolean is_pipe0 =
+ (r_type == R_TILEGX_IMM8_X0_TLS_ADD
+ || r_type == R_TILEGX_IMM8_Y0_TLS_ADD);
+ bfd_boolean is_X0X1 =
+ (r_type == R_TILEGX_IMM8_X0_TLS_ADD
+ || r_type == R_TILEGX_IMM8_X1_TLS_ADD);
+ int dest_begin = is_pipe0 ? 0 : 31;
+ int src_begin;
+ const bfd_byte *insn;
+ const bfd_byte *mask = NULL;
+
+ if (is_tls_le)
+ {
+ /* 1. copy dest operand into the first source operand.
+ 2. change the opcode to "move". */
+ src_begin = is_pipe0 ? 6 : 37;
+ insn = is_X0X1 ? insn_move_X0X1 : insn_move_Y0Y1;
+
+ switch (r_type)
+ {
+ case R_TILEGX_IMM8_X0_TLS_ADD:
+ mask = insn_mask_X0_no_dest_no_srca;
+ break;
+ case R_TILEGX_IMM8_X1_TLS_ADD:
+ mask = insn_mask_X1_no_dest_no_srca;
+ break;
+ case R_TILEGX_IMM8_Y0_TLS_ADD:
+ mask = insn_mask_Y0_no_dest_no_srca;
+ break;
+ case R_TILEGX_IMM8_Y1_TLS_ADD:
+ mask = insn_mask_Y1_no_dest_no_srca;
+ break;
+ }
+ }
+ else
+ {
+ /* 1. copy dest operand into the second source operand.
+ 2. change the opcode to "add". */
+ src_begin = is_pipe0 ? 12 : 43;
+ if (ABI_64_P (output_bfd))
+ insn = is_X0X1 ? insn_add_X0X1 : insn_add_Y0Y1;
+ else
+ insn = is_X0X1 ? insn_addx_X0X1 : insn_addx_Y0Y1;
+
+ switch (r_type)
+ {
+ case R_TILEGX_IMM8_X0_TLS_ADD:
+ mask = insn_mask_X0_no_operand;
+ break;
+ case R_TILEGX_IMM8_X1_TLS_ADD:
+ mask = insn_mask_X1_no_operand;
+ break;
+ case R_TILEGX_IMM8_Y0_TLS_ADD:
+ mask = insn_mask_Y0_no_operand;
+ break;
+ case R_TILEGX_IMM8_Y1_TLS_ADD:
+ mask = insn_mask_Y1_no_operand;
+ break;
+ }
+ }
+
+ tilegx_copy_bits (contents + rel->r_offset, dest_begin,
+ src_begin, 6);
+ tilegx_replace_insn (contents + rel->r_offset, mask, insn);
+
+ continue;
+ }
+ else
+ {
+ const bfd_byte *mask = NULL;
+ const bfd_byte *add_insn = NULL;
+ bfd_boolean is_64bit = ABI_64_P (output_bfd);
+
+ switch (r_type)
+ {
+ case R_TILEGX_IMM8_X0_TLS_GD_ADD:
+ add_insn = is_tls_iele
+ ? (is_64bit ? insn_tls_ie_add_X0X1 : insn_tls_ie_addx_X0X1)
+ : insn_tls_gd_add_X0X1;
+ mask = insn_mask_X0_no_dest_no_srca;
+ break;
+ case R_TILEGX_IMM8_X1_TLS_GD_ADD:
+ add_insn = is_tls_iele
+ ? (is_64bit ? insn_tls_ie_add_X0X1 : insn_tls_ie_addx_X0X1)
+ : insn_tls_gd_add_X0X1;
+ mask = insn_mask_X1_no_dest_no_srca;
+ break;
+ case R_TILEGX_IMM8_Y0_TLS_GD_ADD:
+ add_insn = is_tls_iele
+ ? (is_64bit ? insn_tls_ie_add_Y0Y1 : insn_tls_ie_addx_Y0Y1)
+ : insn_tls_gd_add_Y0Y1;
+ mask = insn_mask_Y0_no_dest_no_srca;
+ break;
+ case R_TILEGX_IMM8_Y1_TLS_GD_ADD:
+ add_insn = is_tls_iele
+ ? (is_64bit ? insn_tls_ie_add_Y0Y1 : insn_tls_ie_addx_Y0Y1)
+ : insn_tls_gd_add_Y0Y1;
+ mask = insn_mask_Y1_no_dest_no_srca;
+ break;
+ }
+
+ tilegx_replace_insn (contents + rel->r_offset, mask, add_insn);
+
+ continue;
+ }
+ break;
+ case R_TILEGX_TLS_IE_LOAD:
+ if (!input_section->sec_flg0
+ && !info->shared
+ && (h == NULL || h->dynindx == -1))
+ {
+ /* IE -> LE */
+ tilegx_replace_insn (contents + rel->r_offset,
+ insn_mask_X1_no_dest_no_srca,
+ insn_move_X0X1);
+ }
+ else
+ {
+ /* IE -> IE */
+ if (ABI_64_P (output_bfd))
+ tilegx_replace_insn (contents + rel->r_offset,
+ insn_mask_X1_no_dest_no_srca,
+ insn_tls_ie_ld_X1);
+ else
+ tilegx_replace_insn (contents + rel->r_offset,
+ insn_mask_X1_no_dest_no_srca,
+ insn_tls_ie_ld4s_X1);
+ }
+ continue;
+ break;
+ default:
+ break;
+ }
+
+ switch (r_type)
+ {
+ case R_TILEGX_IMM16_X0_HW0_GOT:
+ case R_TILEGX_IMM16_X1_HW0_GOT:
+ case R_TILEGX_IMM16_X0_HW0_LAST_GOT:
+ case R_TILEGX_IMM16_X1_HW0_LAST_GOT:
+ case R_TILEGX_IMM16_X0_HW1_LAST_GOT:
+ case R_TILEGX_IMM16_X1_HW1_LAST_GOT:
+ /* Relocation is to the entry for this symbol in the global
+ offset table. */
+ if (htab->elf.sgot == NULL)
+ abort ();
+
+ if (h != NULL)
+ {
+ bfd_boolean dyn;
+
+ off = h->got.offset;
+ BFD_ASSERT (off != (bfd_vma) -1);
+ dyn = elf_hash_table (info)->dynamic_sections_created;
+
+ if (! WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h)
+ || (info->shared
+ && SYMBOL_REFERENCES_LOCAL (info, h)))
+ {
+ /* 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 for 64-bit, 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
+ {
+ TILEGX_ELF_PUT_WORD (htab, output_bfd, relocation,
+ htab->elf.sgot->contents + off);
+ h->got.offset |= 1;
+ }
+ }
+ else
+ unresolved_reloc = FALSE;
+ }
+ 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 8 on 64-bit.
+ We use the least significant bit to record
+ whether we have already processed this entry. */
+ if ((off & 1) != 0)
+ off &= ~1;
+ else
+ {
+ if (info->shared)
+ {
+ asection *s;
+ Elf_Internal_Rela outrel;
+
+ /* We need to generate a R_TILEGX_RELATIVE reloc
+ for the dynamic linker. */
+ s = htab->elf.srelgot;
+ BFD_ASSERT (s != NULL);
+
+ outrel.r_offset = (htab->elf.sgot->output_section->vma
+ + htab->elf.sgot->output_offset
+ + off);
+ outrel.r_info =
+ TILEGX_ELF_R_INFO (htab, NULL, 0, R_TILEGX_RELATIVE);
+ outrel.r_addend = relocation;
+ relocation = 0;
+ tilegx_elf_append_rela (output_bfd, s, &outrel);
+ }
+
+ TILEGX_ELF_PUT_WORD (htab, output_bfd, relocation,
+ htab->elf.sgot->contents + off);
+ local_got_offsets[r_symndx] |= 1;
+ }
+ }
+ relocation = off - got_base;
+ break;
+
+ case R_TILEGX_JUMPOFF_X1_PLT:
+ case R_TILEGX_IMM16_X0_HW0_PLT_PCREL:
+ case R_TILEGX_IMM16_X1_HW0_PLT_PCREL:
+ case R_TILEGX_IMM16_X0_HW1_PLT_PCREL:
+ case R_TILEGX_IMM16_X1_HW1_PLT_PCREL:
+ case R_TILEGX_IMM16_X0_HW2_PLT_PCREL:
+ case R_TILEGX_IMM16_X1_HW2_PLT_PCREL:
+ case R_TILEGX_IMM16_X0_HW3_PLT_PCREL:
+ case R_TILEGX_IMM16_X1_HW3_PLT_PCREL:
+ case R_TILEGX_IMM16_X0_HW0_LAST_PLT_PCREL:
+ case R_TILEGX_IMM16_X1_HW0_LAST_PLT_PCREL:
+ case R_TILEGX_IMM16_X0_HW1_LAST_PLT_PCREL:
+ case R_TILEGX_IMM16_X1_HW1_LAST_PLT_PCREL:
+ case R_TILEGX_IMM16_X0_HW2_LAST_PLT_PCREL:
+ case R_TILEGX_IMM16_X1_HW2_LAST_PLT_PCREL:
+ /* Relocation is to the entry for this symbol in the
+ procedure linkage table. */
+ BFD_ASSERT (h != NULL);
+
+ if (h->plt.offset == (bfd_vma) -1 || htab->elf.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 = (htab->elf.splt->output_section->vma
+ + htab->elf.splt->output_offset
+ + h->plt.offset);
+ unresolved_reloc = FALSE;
+ break;
+
+ case R_TILEGX_64_PCREL:
+ case R_TILEGX_32_PCREL:
+ case R_TILEGX_16_PCREL:
+ case R_TILEGX_8_PCREL:
+ case R_TILEGX_IMM16_X0_HW0_PCREL:
+ case R_TILEGX_IMM16_X1_HW0_PCREL:
+ case R_TILEGX_IMM16_X0_HW1_PCREL:
+ case R_TILEGX_IMM16_X1_HW1_PCREL:
+ case R_TILEGX_IMM16_X0_HW2_PCREL:
+ case R_TILEGX_IMM16_X1_HW2_PCREL:
+ case R_TILEGX_IMM16_X0_HW3_PCREL:
+ case R_TILEGX_IMM16_X1_HW3_PCREL:
+ case R_TILEGX_IMM16_X0_HW0_LAST_PCREL:
+ case R_TILEGX_IMM16_X1_HW0_LAST_PCREL:
+ case R_TILEGX_IMM16_X0_HW1_LAST_PCREL:
+ case R_TILEGX_IMM16_X1_HW1_LAST_PCREL:
+ case R_TILEGX_IMM16_X0_HW2_LAST_PCREL:
+ case R_TILEGX_IMM16_X1_HW2_LAST_PCREL:
+ if (h != NULL
+ && strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0)
+ break;
+ /* Fall through. */
+ case R_TILEGX_64:
+ case R_TILEGX_32:
+ case R_TILEGX_16:
+ case R_TILEGX_8:
+ case R_TILEGX_HW0:
+ case R_TILEGX_HW1:
+ case R_TILEGX_HW2:
+ case R_TILEGX_HW3:
+ case R_TILEGX_HW0_LAST:
+ case R_TILEGX_HW1_LAST:
+ case R_TILEGX_HW2_LAST:
+ case R_TILEGX_COPY:
+ case R_TILEGX_GLOB_DAT:
+ case R_TILEGX_JMP_SLOT:
+ case R_TILEGX_RELATIVE:
+ case R_TILEGX_BROFF_X1:
+ case R_TILEGX_JUMPOFF_X1:
+ case R_TILEGX_IMM8_X0:
+ case R_TILEGX_IMM8_Y0:
+ case R_TILEGX_IMM8_X1:
+ case R_TILEGX_IMM8_Y1:
+ case R_TILEGX_DEST_IMM8_X1:
+ case R_TILEGX_MT_IMM14_X1:
+ case R_TILEGX_MF_IMM14_X1:
+ case R_TILEGX_MMSTART_X0:
+ case R_TILEGX_MMEND_X0:
+ case R_TILEGX_SHAMT_X0:
+ case R_TILEGX_SHAMT_X1:
+ case R_TILEGX_SHAMT_Y0:
+ case R_TILEGX_SHAMT_Y1:
+ case R_TILEGX_IMM16_X0_HW0:
+ case R_TILEGX_IMM16_X1_HW0:
+ case R_TILEGX_IMM16_X0_HW1:
+ case R_TILEGX_IMM16_X1_HW1:
+ case R_TILEGX_IMM16_X0_HW2:
+ case R_TILEGX_IMM16_X1_HW2:
+ case R_TILEGX_IMM16_X0_HW3:
+ case R_TILEGX_IMM16_X1_HW3:
+ case R_TILEGX_IMM16_X0_HW0_LAST:
+ case R_TILEGX_IMM16_X1_HW0_LAST:
+ case R_TILEGX_IMM16_X0_HW1_LAST:
+ case R_TILEGX_IMM16_X1_HW1_LAST:
+ case R_TILEGX_IMM16_X0_HW2_LAST:
+ case R_TILEGX_IMM16_X1_HW2_LAST:
+ if ((input_section->flags & SEC_ALLOC) == 0)
+ break;
+
+ if ((info->shared
+ && (h == NULL
+ || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
+ || h->root.type != bfd_link_hash_undefweak)
+ && (! howto->pc_relative
+ || !SYMBOL_CALLS_LOCAL (info, h)))
+ || (!info->shared
+ && h != NULL
+ && h->dynindx != -1
+ && !h->non_got_ref
+ && ((h->def_dynamic
+ && !h->def_regular)
+ || h->root.type == bfd_link_hash_undefweak
+ || h->root.type == bfd_link_hash_undefined)))
+ {
+ Elf_Internal_Rela outrel;
+ bfd_boolean skip, relocate = FALSE;
+
+ /* When generating a shared object, these relocations
+ are copied into the output file to be resolved at run
+ time. */
+
+ BFD_ASSERT (sreloc != NULL);
+
+ skip = FALSE;
+
+ outrel.r_offset =
+ _bfd_elf_section_offset (output_bfd, info, input_section,
+ rel->r_offset);
+ if (outrel.r_offset == (bfd_vma) -1)
+ skip = TRUE;
+ else if (outrel.r_offset == (bfd_vma) -2)
+ skip = TRUE, relocate = TRUE;
+ outrel.r_offset += (input_section->output_section->vma
+ + input_section->output_offset);
+
+ switch (r_type)
+ {
+ case R_TILEGX_64_PCREL:
+ case R_TILEGX_32_PCREL:
+ case R_TILEGX_16_PCREL:
+ case R_TILEGX_8_PCREL:
+ /* If the symbol is not dynamic, we should not keep
+ a dynamic relocation. But an .rela.* slot has been
+ allocated for it, output R_TILEGX_NONE.
+ FIXME: Add code tracking needed dynamic relocs as
+ e.g. i386 has. */
+ if (h->dynindx == -1)
+ skip = TRUE, relocate = TRUE;
+ 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 &&
+ h->dynindx != -1
+ && (! is_plt
+ || !info->shared
+ || !SYMBOLIC_BIND (info, h)
+ || !h->def_regular))
+ {
+ BFD_ASSERT (h->dynindx != -1);
+ outrel.r_info = TILEGX_ELF_R_INFO (htab, rel, h->dynindx, r_type);
+ outrel.r_addend = rel->r_addend;
+ }
+ else
+ {
+ if (r_type == R_TILEGX_32 || r_type == R_TILEGX_64)
+ {
+ outrel.r_info = TILEGX_ELF_R_INFO (htab, NULL, 0,
+ R_TILEGX_RELATIVE);
+ outrel.r_addend = relocation + rel->r_addend;
+ }
+ else
+ {
+ long indx;
+
+ outrel.r_addend = relocation + rel->r_addend;
+
+ if (is_plt)
+ sec = htab->elf.splt;
+
+ if (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;
+
+ /* We are turning this relocation into one
+ against a section symbol. It would be
+ proper to subtract the symbol's value,
+ osec->vma, from the emitted reloc addend,
+ but ld.so expects buggy relocs. */
+ osec = sec->output_section;
+ indx = elf_section_data (osec)->dynindx;
+
+ if (indx == 0)
+ {
+ osec = htab->elf.text_index_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)
+ (_("%B: probably compiled without -fPIC?"),
+ input_bfd);
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+ }
+
+ outrel.r_info = TILEGX_ELF_R_INFO (htab, rel, indx,
+ r_type);
+ }
+ }
+
+ tilegx_elf_append_rela (output_bfd, sreloc, &outrel);
+
+ /* This reloc will be computed at runtime, so there's no
+ need to do anything now. */
+ if (! relocate)
+ continue;
+ }
+ break;
+
+ case R_TILEGX_IMM16_X0_HW0_TLS_LE:
+ case R_TILEGX_IMM16_X1_HW0_TLS_LE:
+ case R_TILEGX_IMM16_X0_HW0_LAST_TLS_LE:
+ case R_TILEGX_IMM16_X1_HW0_LAST_TLS_LE:
+ case R_TILEGX_IMM16_X0_HW1_LAST_TLS_LE:
+ case R_TILEGX_IMM16_X1_HW1_LAST_TLS_LE:
+ if (info->shared)
+ {
+ Elf_Internal_Rela outrel;
+ bfd_boolean skip;
+
+ BFD_ASSERT (sreloc != NULL);
+ skip = FALSE;
+ outrel.r_offset =
+ _bfd_elf_section_offset (output_bfd, info, input_section,
+ rel->r_offset);
+ if (outrel.r_offset == (bfd_vma) -1)
+ skip = TRUE;
+ else if (outrel.r_offset == (bfd_vma) -2)
+ skip = TRUE;
+ outrel.r_offset += (input_section->output_section->vma
+ + input_section->output_offset);
+ if (skip)
+ memset (&outrel, 0, sizeof outrel);
+ else
+ {
+ outrel.r_info = TILEGX_ELF_R_INFO (htab, NULL, 0, r_type);
+ outrel.r_addend = relocation - dtpoff_base (info)
+ + rel->r_addend;
+ }
+
+ tilegx_elf_append_rela (output_bfd, sreloc, &outrel);
+ continue;
+ }
+ relocation = tpoff (info, relocation);
+ break;
+
+ case R_TILEGX_IMM16_X0_HW0_TLS_GD:
+ case R_TILEGX_IMM16_X1_HW0_TLS_GD:
+ case R_TILEGX_IMM16_X0_HW0_LAST_TLS_GD:
+ case R_TILEGX_IMM16_X1_HW0_LAST_TLS_GD:
+ case R_TILEGX_IMM16_X0_HW1_LAST_TLS_GD:
+ case R_TILEGX_IMM16_X1_HW1_LAST_TLS_GD:
+ case R_TILEGX_IMM16_X0_HW0_TLS_IE:
+ case R_TILEGX_IMM16_X1_HW0_TLS_IE:
+ case R_TILEGX_IMM16_X0_HW0_LAST_TLS_IE:
+ case R_TILEGX_IMM16_X1_HW0_LAST_TLS_IE:
+ case R_TILEGX_IMM16_X0_HW1_LAST_TLS_IE:
+ case R_TILEGX_IMM16_X1_HW1_LAST_TLS_IE:
+ r_type = tilegx_elf_tls_transition (info, r_type, h == NULL,
+ input_section->sec_flg0);
+ tls_type = GOT_UNKNOWN;
+ if (h == NULL && local_got_offsets)
+ tls_type =
+ _bfd_tilegx_elf_local_got_tls_type (input_bfd) [r_symndx];
+ else if (h != NULL)
+ {
+ tls_type = tilegx_elf_hash_entry(h)->tls_type;
+ if (!info->shared && h->dynindx == -1 && tls_type == GOT_TLS_IE)
+ r_type = (!input_section->sec_flg0
+ ? tilegx_tls_translate_to_le (r_type)
+ : tilegx_tls_translate_to_ie (r_type));
+ }
+
+ if (tls_type == GOT_TLS_IE)
+ r_type = tilegx_tls_translate_to_ie (r_type);
+
+ if (r_type == R_TILEGX_IMM16_X0_HW0_TLS_LE
+ || r_type == R_TILEGX_IMM16_X1_HW0_TLS_LE
+ || r_type == R_TILEGX_IMM16_X0_HW0_LAST_TLS_LE
+ || r_type == R_TILEGX_IMM16_X1_HW0_LAST_TLS_LE
+ || r_type == R_TILEGX_IMM16_X0_HW1_LAST_TLS_LE
+ || r_type == R_TILEGX_IMM16_X1_HW1_LAST_TLS_LE)
+ {
+ relocation = tpoff (info, relocation);
+ break;
+ }
+
+ if (h != NULL)
+ {
+ off = h->got.offset;
+ h->got.offset |= 1;
+ }
+ else
+ {
+ BFD_ASSERT (local_got_offsets != NULL);
+ off = local_got_offsets[r_symndx];
+ local_got_offsets[r_symndx] |= 1;
+ }
+
+ if (htab->elf.sgot == NULL)
+ abort ();
+
+ if ((off & 1) != 0)
+ off &= ~1;
+ else
+ {
+ Elf_Internal_Rela outrel;
+ int indx = 0;
+ bfd_boolean need_relocs = FALSE;
+
+ if (htab->elf.srelgot == NULL)
+ abort ();
+
+ if (h != NULL)
+ {
+ bfd_boolean dyn;
+ dyn = htab->elf.dynamic_sections_created;
+
+ if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h)
+ && (!info->shared
+ || !SYMBOL_REFERENCES_LOCAL (info, h)))
+ {
+ indx = h->dynindx;
+ }
+ }
+
+ /* The GOT entries have not been initialized yet. Do it
+ now, and emit any relocations. */
+ if ((info->shared || indx != 0)
+ && (h == NULL
+ || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
+ || h->root.type != bfd_link_hash_undefweak))
+ need_relocs = TRUE;
+
+ switch (r_type)
+ {
+ case R_TILEGX_IMM16_X0_HW0_TLS_IE:
+ case R_TILEGX_IMM16_X1_HW0_TLS_IE:
+ case R_TILEGX_IMM16_X0_HW0_LAST_TLS_IE:
+ case R_TILEGX_IMM16_X1_HW0_LAST_TLS_IE:
+ case R_TILEGX_IMM16_X0_HW1_LAST_TLS_IE:
+ case R_TILEGX_IMM16_X1_HW1_LAST_TLS_IE:
+ if (need_relocs) {
+ TILEGX_ELF_PUT_WORD (htab, output_bfd, 0,
+ htab->elf.sgot->contents + off);
+ outrel.r_offset = (htab->elf.sgot->output_section->vma
+ + htab->elf.sgot->output_offset + off);
+ outrel.r_addend = 0;
+ if (indx == 0)
+ outrel.r_addend = relocation - dtpoff_base (info);
+ outrel.r_info = TILEGX_ELF_R_INFO (htab, NULL, indx,
+ TILEGX_ELF_TPOFF_RELOC (htab));
+ tilegx_elf_append_rela (output_bfd, htab->elf.srelgot, &outrel);
+ } else {
+ TILEGX_ELF_PUT_WORD (htab, output_bfd,
+ tpoff (info, relocation),
+ htab->elf.sgot->contents + off);
+ }
+ break;
+
+ case R_TILEGX_IMM16_X0_HW0_TLS_GD:
+ case R_TILEGX_IMM16_X1_HW0_TLS_GD:
+ case R_TILEGX_IMM16_X0_HW0_LAST_TLS_GD:
+ case R_TILEGX_IMM16_X1_HW0_LAST_TLS_GD:
+ case R_TILEGX_IMM16_X0_HW1_LAST_TLS_GD:
+ case R_TILEGX_IMM16_X1_HW1_LAST_TLS_GD:
+ if (need_relocs) {
+ outrel.r_offset = (htab->elf.sgot->output_section->vma
+ + htab->elf.sgot->output_offset + off);
+ outrel.r_addend = 0;
+ outrel.r_info = TILEGX_ELF_R_INFO (htab, NULL, indx,
+ TILEGX_ELF_DTPMOD_RELOC (htab));
+ TILEGX_ELF_PUT_WORD (htab, output_bfd, 0,
+ htab->elf.sgot->contents + off);
+ tilegx_elf_append_rela (output_bfd, htab->elf.srelgot, &outrel);
+ if (indx == 0)
+ {
+ BFD_ASSERT (! unresolved_reloc);
+ TILEGX_ELF_PUT_WORD (htab, output_bfd,
+ relocation - dtpoff_base (info),
+ (htab->elf.sgot->contents + off +
+ TILEGX_ELF_WORD_BYTES (htab)));
+ }
+ else
+ {
+ TILEGX_ELF_PUT_WORD (htab, output_bfd, 0,
+ (htab->elf.sgot->contents + off +
+ TILEGX_ELF_WORD_BYTES (htab)));
+ outrel.r_info = TILEGX_ELF_R_INFO (htab, NULL, indx,
+ TILEGX_ELF_DTPOFF_RELOC (htab));
+ outrel.r_offset += TILEGX_ELF_WORD_BYTES (htab);
+ tilegx_elf_append_rela (output_bfd, htab->elf.srelgot, &outrel);
+ }
+ }
+
+ else {
+ /* If we are not emitting relocations for a
+ general dynamic reference, then we must be in a
+ static link or an executable link with the
+ symbol binding locally. Mark it as belonging
+ to module 1, the executable. */
+ TILEGX_ELF_PUT_WORD (htab, output_bfd, 1,
+ htab->elf.sgot->contents + off );
+ TILEGX_ELF_PUT_WORD (htab, output_bfd,
+ relocation - dtpoff_base (info),
+ htab->elf.sgot->contents + off +
+ TILEGX_ELF_WORD_BYTES (htab));
+ }
+ break;
+ }
+ }
+
+ if (off >= (bfd_vma) -2)
+ abort ();
+
+ relocation = off - got_base;
+ unresolved_reloc = FALSE;
+ howto = tilegx_elf_howto_table + r_type;
+ break;
+
+ default:
+ break;
+ }
+
+ /* Dynamic relocs are not propagated for SEC_DEBUGGING sections
+ because such sections are not SEC_ALLOC and thus ld.so will
+ not process them. */
+ if (unresolved_reloc
+ && !((input_section->flags & SEC_DEBUGGING) != 0
+ && h->def_dynamic)
+ && _bfd_elf_section_offset (output_bfd, info, input_section,
+ rel->r_offset) != (bfd_vma) -1)
+ (*_bfd_error_handler)
+ (_("%B(%A+0x%lx): unresolvable %s relocation against symbol `%s'"),
+ input_bfd,
+ input_section,
+ (long) rel->r_offset,
+ howto->name,
+ h->root.root.string);
+
+ r = bfd_reloc_continue;
+
+ /* Get the operand creation function, if any. */
+ create_func = reloc_to_create_func[r_type];
+ if (create_func == NULL)
+ {
+ r = _bfd_final_link_relocate (howto, input_bfd, input_section,
+ contents, rel->r_offset,
+ relocation, rel->r_addend);
+ }
+ else
+ {
+ if (howto->pc_relative)
+ {
+ relocation -=
+ input_section->output_section->vma + input_section->output_offset;
+ if (howto->pcrel_offset)
+ relocation -= rel->r_offset;
+ }
+
+ bfd_byte *data;
+
+ /* Add the relocation addend if any to the final target value */
+ relocation += rel->r_addend;
+
+ /* Do basic range checking */
+ r = bfd_check_overflow (howto->complain_on_overflow,
+ howto->bitsize,
+ howto->rightshift,
+ TILEGX_ELF_WORD_BYTES (htab) * 8,
+ relocation);
+
+ /*
+ * Write the relocated value out into the raw section data.
+ * Don't put a relocation out in the .rela section.
+ */
+ tilegx_bundle_bits mask = create_func(-1);
+ tilegx_bundle_bits value = create_func(relocation >> howto->rightshift);
+
+ /* Only touch bytes while the mask is not 0, so we
+ don't write to out of bounds memory if this is actually
+ a 16-bit switch instruction. */
+ for (data = contents + rel->r_offset; mask != 0; data++)
+ {
+ bfd_byte byte_mask = (bfd_byte)mask;
+ *data = (*data & ~byte_mask) | ((bfd_byte)value & byte_mask);
+ mask >>= 8;
+ value >>= 8;
+ }
+ }
+
+ if (r != bfd_reloc_ok)
+ {
+ const char *msg = NULL;
+
+ switch (r)
+ {
+ case bfd_reloc_overflow:
+ r = info->callbacks->reloc_overflow
+ (info, (h ? &h->root : NULL), 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,
+ TRUE);
+ 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;
+}
+
+/* Finish up dynamic symbol handling. We set the contents of various
+ dynamic sections here. */
+
+bfd_boolean
+tilegx_elf_finish_dynamic_symbol (bfd *output_bfd,
+ struct bfd_link_info *info,
+ struct elf_link_hash_entry *h,
+ Elf_Internal_Sym *sym)
+{
+ struct tilegx_elf_link_hash_table *htab;
+
+ htab = tilegx_elf_hash_table (info);
+ BFD_ASSERT (htab != NULL);
+
+ if (h->plt.offset != (bfd_vma) -1)
+ {
+ asection *splt;
+ asection *srela;
+ asection *sgotplt;
+ Elf_Internal_Rela rela;
+ bfd_byte *loc;
+ bfd_vma r_offset;
+ const struct elf_backend_data *bed = get_elf_backend_data (output_bfd);
+
+
+ int rela_index;
+
+ /* This symbol has an entry in the PLT. Set it up. */
+
+ BFD_ASSERT (h->dynindx != -1);
+
+ splt = htab->elf.splt;
+ srela = htab->elf.srelplt;
+ sgotplt = htab->elf.sgotplt;
+
+ if (splt == NULL || srela == NULL)
+ abort ();
+
+ /* Fill in the entry in the procedure linkage table. */
+ rela_index = tilegx_plt_entry_build (output_bfd, htab, splt, sgotplt,
+ h->plt.offset, &r_offset);
+
+ /* Fill in the entry in the global offset table, which initially points
+ to the beginning of the plt. */
+ TILEGX_ELF_PUT_WORD (htab, output_bfd,
+ splt->output_section->vma + splt->output_offset,
+ sgotplt->contents + r_offset);
+
+ /* Fill in the entry in the .rela.plt section. */
+ rela.r_offset = (sgotplt->output_section->vma
+ + sgotplt->output_offset
+ + r_offset);
+ rela.r_addend = 0;
+ rela.r_info = TILEGX_ELF_R_INFO (htab, NULL, h->dynindx, R_TILEGX_JMP_SLOT);
+
+ loc = srela->contents + rela_index * TILEGX_ELF_RELA_BYTES (htab);
+ bed->s->swap_reloca_out (output_bfd, &rela, loc);
+
+ if (!h->def_regular)
+ {
+ /* Mark the symbol as undefined, rather than as defined in
+ the .plt section. Leave the value alone. */
+ sym->st_shndx = SHN_UNDEF;
+ /* If the symbol is weak, we do need to clear the value.
+ Otherwise, the PLT entry would provide a definition for
+ the symbol even if the symbol wasn't defined anywhere,
+ and so the symbol would never be NULL. */
+ if (!h->ref_regular_nonweak)
+ sym->st_value = 0;
+ }
+ }
+
+ if (h->got.offset != (bfd_vma) -1
+ && tilegx_elf_hash_entry(h)->tls_type != GOT_TLS_GD
+ && tilegx_elf_hash_entry(h)->tls_type != GOT_TLS_IE)
+ {
+ asection *sgot;
+ asection *srela;
+ Elf_Internal_Rela rela;
+
+ /* This symbol has an entry in the GOT. Set it up. */
+
+ sgot = htab->elf.sgot;
+ srela = htab->elf.srelgot;
+ BFD_ASSERT (sgot != NULL && srela != NULL);
+
+ rela.r_offset = (sgot->output_section->vma
+ + sgot->output_offset
+ + (h->got.offset &~ (bfd_vma) 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->def_regular)
+ {
+ asection *sec = h->root.u.def.section;
+ rela.r_info = TILEGX_ELF_R_INFO (htab, NULL, 0, R_TILEGX_RELATIVE);
+ rela.r_addend = (h->root.u.def.value
+ + sec->output_section->vma
+ + sec->output_offset);
+ }
+ else
+ {
+ rela.r_info = TILEGX_ELF_R_INFO (htab, NULL, h->dynindx, R_TILEGX_GLOB_DAT);
+ rela.r_addend = 0;
+ }
+
+ TILEGX_ELF_PUT_WORD (htab, output_bfd, 0,
+ sgot->contents + (h->got.offset & ~(bfd_vma) 1));
+ tilegx_elf_append_rela (output_bfd, srela, &rela);
+ }
+
+ if (h->needs_copy)
+ {
+ asection *s;
+ Elf_Internal_Rela rela;
+
+ /* This symbols needs a copy reloc. Set it up. */
+ BFD_ASSERT (h->dynindx != -1);
+
+ s = htab->srelbss;
+ 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 = TILEGX_ELF_R_INFO (htab, NULL, h->dynindx, R_TILEGX_COPY);
+ rela.r_addend = 0;
+ tilegx_elf_append_rela (output_bfd, s, &rela);
+ }
+
+ /* Mark some specially defined symbols as absolute. */
+ if (h == htab->elf.hdynamic
+ || (h == htab->elf.hgot || h == htab->elf.hplt))
+ sym->st_shndx = SHN_ABS;
+
+ return TRUE;
+}
+
+/* Finish up the dynamic sections. */
+
+static bfd_boolean
+tilegx_finish_dyn (bfd *output_bfd, struct bfd_link_info *info,
+ bfd *dynobj, asection *sdyn,
+ asection *splt ATTRIBUTE_UNUSED)
+{
+ struct tilegx_elf_link_hash_table *htab;
+ const struct elf_backend_data *bed;
+ bfd_byte *dyncon, *dynconend;
+ size_t dynsize;
+
+ htab = tilegx_elf_hash_table (info);
+ BFD_ASSERT (htab != NULL);
+ bed = get_elf_backend_data (output_bfd);
+ dynsize = bed->s->sizeof_dyn;
+ dynconend = sdyn->contents + sdyn->size;
+
+ for (dyncon = sdyn->contents; dyncon < dynconend; dyncon += dynsize)
+ {
+ Elf_Internal_Dyn dyn;
+ asection *s;
+
+ bed->s->swap_dyn_in (dynobj, dyncon, &dyn);
+
+ switch (dyn.d_tag)
+ {
+ case DT_PLTGOT:
+ s = htab->elf.sgotplt;
+ dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
+ break;
+ case DT_JMPREL:
+ s = htab->elf.srelplt;
+ dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
+ break;
+ case DT_PLTRELSZ:
+ s = htab->elf.srelplt;
+ dyn.d_un.d_val = s->size;
+ break;
+ default:
+ continue;
+ }
+
+ bed->s->swap_dyn_out (output_bfd, &dyn, dyncon);
+ }
+ return TRUE;
+}
+
+bfd_boolean
+tilegx_elf_finish_dynamic_sections (bfd *output_bfd,
+ struct bfd_link_info *info)
+{
+ bfd *dynobj;
+ asection *sdyn;
+ struct tilegx_elf_link_hash_table *htab;
+ size_t pad_size;
+
+ htab = tilegx_elf_hash_table (info);
+ BFD_ASSERT (htab != NULL);
+ dynobj = htab->elf.dynobj;
+
+ sdyn = bfd_get_linker_section (dynobj, ".dynamic");
+
+ if (elf_hash_table (info)->dynamic_sections_created)
+ {
+ asection *splt;
+ bfd_boolean ret;
+
+ splt = htab->elf.splt;
+ BFD_ASSERT (splt != NULL && sdyn != NULL);
+
+ ret = tilegx_finish_dyn (output_bfd, info, dynobj, sdyn, splt);
+
+ if (ret != TRUE)
+ return ret;
+
+ /* Fill in the head and tail entries in the procedure linkage table. */
+ if (splt->size > 0)
+ {
+ memcpy (splt->contents,
+ ABI_64_P (output_bfd) ?
+ tilegx64_plt0_entry : tilegx32_plt0_entry,
+ PLT_HEADER_SIZE);
+
+ memcpy (splt->contents + splt->size
+ - PLT_ENTRY_SIZE + PLT_HEADER_SIZE,
+ ABI_64_P (output_bfd) ?
+ tilegx64_plt_tail_entry : tilegx32_plt_tail_entry,
+ PLT_TAIL_SIZE);
+ /* Add padding so that the plt section is a multiple of its
+ entry size. */
+ pad_size = PLT_ENTRY_SIZE - PLT_HEADER_SIZE - PLT_TAIL_SIZE;
+ memset (splt->contents + splt->size - pad_size, 0, pad_size);
+ }
+
+ elf_section_data (splt->output_section)->this_hdr.sh_entsize
+ = PLT_ENTRY_SIZE;
+ }
+
+ if (htab->elf.sgotplt)
+ {
+ if (bfd_is_abs_section (htab->elf.sgotplt->output_section))
+ {
+ (*_bfd_error_handler)
+ (_("discarded output section: `%A'"), htab->elf.sgotplt);
+ return FALSE;
+ }
+
+ if (htab->elf.sgotplt->size > 0)
+ {
+ /* Write the first two entries in .got.plt, needed for the dynamic
+ linker. */
+ TILEGX_ELF_PUT_WORD (htab, output_bfd, (bfd_vma) -1,
+ htab->elf.sgotplt->contents);
+ TILEGX_ELF_PUT_WORD (htab, output_bfd, (bfd_vma) 0,
+ htab->elf.sgotplt->contents
+ + GOT_ENTRY_SIZE (htab));
+ }
+
+ elf_section_data (htab->elf.sgotplt->output_section)->this_hdr.sh_entsize =
+ GOT_ENTRY_SIZE (htab);
+ }
+
+ if (htab->elf.sgot)
+ {
+ if (htab->elf.sgot->size > 0)
+ {
+ /* Set the first entry in the global offset table to the address of
+ the dynamic section. */
+ bfd_vma val = (sdyn ?
+ sdyn->output_section->vma + sdyn->output_offset :
+ 0);
+ TILEGX_ELF_PUT_WORD (htab, output_bfd, val,
+ htab->elf.sgot->contents);
+ }
+
+ elf_section_data (htab->elf.sgot->output_section)->this_hdr.sh_entsize =
+ GOT_ENTRY_SIZE (htab);
+ }
+
+ return TRUE;
+}
+
+
+
+/* Return address for Ith PLT stub in section PLT, for relocation REL
+ or (bfd_vma) -1 if it should not be included. */
+
+bfd_vma
+tilegx_elf_plt_sym_val (bfd_vma i, const asection *plt,
+ const arelent *rel ATTRIBUTE_UNUSED)
+{
+ return plt->vma + PLT_HEADER_SIZE + i * PLT_ENTRY_SIZE;
+}
+
+enum elf_reloc_type_class
+tilegx_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ const asection *rel_sec ATTRIBUTE_UNUSED,
+ const Elf_Internal_Rela *rela)
+{
+ switch ((int) TILEGX_ELF_R_TYPE (rela->r_info))
+ {
+ case R_TILEGX_RELATIVE:
+ return reloc_class_relative;
+ case R_TILEGX_JMP_SLOT:
+ return reloc_class_plt;
+ case R_TILEGX_COPY:
+ return reloc_class_copy;
+ default:
+ return reloc_class_normal;
+ }
+}
+
+int
+tilegx_additional_program_headers (bfd *abfd,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED)
+{
+ /* Each .intrpt section specified by the user adds another PT_LOAD
+ header since the sections are discontiguous. */
+ static const char intrpt_sections[4][9] =
+ {
+ ".intrpt0", ".intrpt1", ".intrpt2", ".intrpt3"
+ };
+ int count = 0;
+ int i;
+
+ for (i = 0; i < 4; i++)
+ {
+ asection *sec = bfd_get_section_by_name (abfd, intrpt_sections[i]);
+ if (sec != NULL && (sec->flags & SEC_LOAD) != 0)
+ ++count;
+ }
+
+ /* Add four "padding" headers in to leave room in case a custom linker
+ script does something fancy. Otherwise ld complains that it ran
+ out of program headers and refuses to link. */
+ count += 4;
+
+ return count;
+}
+
+
+bfd_boolean
+_bfd_tilegx_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
+{
+ const char *targ1 = bfd_get_target (ibfd);
+ const char *targ2 = bfd_get_target (obfd);
+
+ if (strcmp (targ1, targ2) != 0)
+ {
+ (*_bfd_error_handler)
+ (_("%B: Cannot link together %s and %s objects."),
+ ibfd, targ1, targ2);
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+
+ return TRUE;
+}
diff --git a/bfd/elfxx-tilegx.h b/bfd/elfxx-tilegx.h
new file mode 100644
index 0000000..4c3f2bf
--- /dev/null
+++ b/bfd/elfxx-tilegx.h
@@ -0,0 +1,99 @@
+/* TILE-Gx ELF specific backend routines.
+ Copyright (C) 2011-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "elf/common.h"
+#include "elf/internal.h"
+
+extern enum elf_reloc_type_class
+tilegx_reloc_type_class (const struct bfd_link_info *,
+ const asection *,
+ const Elf_Internal_Rela *);
+
+extern reloc_howto_type *
+tilegx_reloc_name_lookup (bfd *, const char *);
+
+extern struct bfd_link_hash_table *
+tilegx_elf_link_hash_table_create (bfd *);
+
+extern reloc_howto_type *
+tilegx_reloc_type_lookup (bfd *, bfd_reloc_code_real_type);
+
+extern void
+tilegx_elf_copy_indirect_symbol (struct bfd_link_info *,
+ struct elf_link_hash_entry *,
+ struct elf_link_hash_entry *);
+
+extern bfd_boolean
+tilegx_elf_create_dynamic_sections (bfd *, struct bfd_link_info *);
+
+extern bfd_boolean
+tilegx_elf_check_relocs (bfd *, struct bfd_link_info *,
+ asection *, const Elf_Internal_Rela *);
+
+extern bfd_boolean
+tilegx_elf_adjust_dynamic_symbol (struct bfd_link_info *,
+ struct elf_link_hash_entry *);
+
+extern bfd_boolean
+tilegx_elf_omit_section_dynsym (bfd *,
+ struct bfd_link_info *,
+ asection *);
+
+extern bfd_boolean
+tilegx_elf_size_dynamic_sections (bfd *, struct bfd_link_info *);
+
+extern bfd_boolean
+tilegx_elf_relocate_section (bfd *, struct bfd_link_info *,
+ bfd *, asection *,
+ bfd_byte *, Elf_Internal_Rela *,
+ Elf_Internal_Sym *,
+ asection **);
+
+extern asection *
+tilegx_elf_gc_mark_hook (asection *,
+ struct bfd_link_info *,
+ Elf_Internal_Rela *,
+ struct elf_link_hash_entry *,
+ Elf_Internal_Sym *);
+
+extern bfd_boolean
+tilegx_elf_gc_sweep_hook (bfd *, struct bfd_link_info *,
+ asection *, const Elf_Internal_Rela *);
+
+extern bfd_vma
+tilegx_elf_plt_sym_val (bfd_vma, const asection *, const arelent *);
+
+extern void
+tilegx_info_to_howto_rela (bfd *, arelent *, Elf_Internal_Rela *);
+
+extern int
+tilegx_additional_program_headers (bfd *, struct bfd_link_info *);
+
+extern bfd_boolean
+tilegx_elf_finish_dynamic_symbol (bfd *,
+ struct bfd_link_info *,
+ struct elf_link_hash_entry *,
+ Elf_Internal_Sym *);
+
+extern bfd_boolean
+tilegx_elf_finish_dynamic_sections (bfd *, struct bfd_link_info *);
+
+extern bfd_boolean
+_bfd_tilegx_elf_merge_private_bfd_data (bfd *, bfd *);
diff --git a/bfd/epoc-pe-arm.c b/bfd/epoc-pe-arm.c
new file mode 100644
index 0000000..71a7bf7
--- /dev/null
+++ b/bfd/epoc-pe-arm.c
@@ -0,0 +1,38 @@
+/* BFD back-end for ARM EPOC PE files.
+ Copyright (C) 1999-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#define TARGET_UNDERSCORE 0
+#define USER_LABEL_PREFIX ""
+
+#define TARGET_LITTLE_SYM arm_pe_epoc_le_vec
+#define TARGET_LITTLE_NAME "epoc-pe-arm-little"
+#define TARGET_BIG_SYM arm_pe_epoc_be_vec
+#define TARGET_BIG_NAME "epoc-pe-arm-big"
+
+#define bfd_arm_allocate_interworking_sections \
+ bfd_arm_epoc_pe_allocate_interworking_sections
+#define bfd_arm_get_bfd_for_interworking \
+ bfd_arm_epoc_pe_get_bfd_for_interworking
+#define bfd_arm_process_before_allocation \
+ bfd_arm_epoc_pe_process_before_allocation
+
+#define EXTRA_S_FLAGS (SEC_LINK_ONCE | SEC_LINK_DUPLICATES | SEC_CODE | SEC_READONLY | SEC_DATA)
+
+#include "pe-arm.c"
diff --git a/bfd/epoc-pei-arm.c b/bfd/epoc-pei-arm.c
new file mode 100644
index 0000000..716775c
--- /dev/null
+++ b/bfd/epoc-pei-arm.c
@@ -0,0 +1,31 @@
+/* BFD back-end for ARM EPOC PE IMAGE COFF files.
+ Copyright (C) 1999-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#define TARGET_UNDERSCORE 0
+#define USER_LABEL_PREFIX ""
+
+#define TARGET_LITTLE_SYM arm_pei_epoc_le_vec
+#define TARGET_LITTLE_NAME "epoc-pei-arm-little"
+#define TARGET_BIG_SYM arm_pei_epoc_be_vec
+#define TARGET_BIG_NAME "epoc-pei-arm-big"
+
+#define EXTRA_S_FLAGS (SEC_CODE | SEC_READONLY | SEC_DATA)
+
+#include "pei-arm.c"
diff --git a/bfd/format.c b/bfd/format.c
new file mode 100644
index 0000000..c4bc944
--- /dev/null
+++ b/bfd/format.c
@@ -0,0 +1,560 @@
+/* Generic BFD support for file formats.
+ Copyright (C) 1990-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, 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.
+
+SUBSECTION
+ File format functions
+*/
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+
+/* IMPORT from targets.c. */
+extern const size_t _bfd_target_vector_entries;
+
+/*
+FUNCTION
+ bfd_check_format
+
+SYNOPSIS
+ bfd_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.
+*/
+
+bfd_boolean
+bfd_check_format (bfd *abfd, bfd_format format)
+{
+ return bfd_check_format_matches (abfd, format, NULL);
+}
+
+struct bfd_preserve
+{
+ void *marker;
+ void *tdata;
+ flagword flags;
+ const struct bfd_arch_info *arch_info;
+ struct bfd_section *sections;
+ struct bfd_section *section_last;
+ unsigned int section_count;
+ struct bfd_hash_table section_htab;
+};
+
+/* When testing an object for compatibility with a particular target
+ back-end, the back-end object_p function needs to set up certain
+ fields in the bfd on successfully recognizing the object. This
+ typically happens in a piecemeal fashion, with failures possible at
+ many points. On failure, the bfd is supposed to be restored to its
+ initial state, which is virtually impossible. However, restoring a
+ subset of the bfd state works in practice. This function stores
+ the subset. */
+
+static bfd_boolean
+bfd_preserve_save (bfd *abfd, struct bfd_preserve *preserve)
+{
+ preserve->tdata = abfd->tdata.any;
+ preserve->arch_info = abfd->arch_info;
+ preserve->flags = abfd->flags;
+ preserve->sections = abfd->sections;
+ preserve->section_last = abfd->section_last;
+ preserve->section_count = abfd->section_count;
+ preserve->section_htab = abfd->section_htab;
+ preserve->marker = bfd_alloc (abfd, 1);
+ if (preserve->marker == NULL)
+ return FALSE;
+
+ return bfd_hash_table_init (&abfd->section_htab, bfd_section_hash_newfunc,
+ sizeof (struct section_hash_entry));
+}
+
+/* Clear out a subset of BFD state. */
+
+static void
+bfd_reinit (bfd *abfd)
+{
+ abfd->tdata.any = NULL;
+ abfd->arch_info = &bfd_default_arch_struct;
+ abfd->flags &= BFD_FLAGS_SAVED;
+ bfd_section_list_clear (abfd);
+}
+
+/* Restores bfd state saved by bfd_preserve_save. */
+
+static void
+bfd_preserve_restore (bfd *abfd, struct bfd_preserve *preserve)
+{
+ bfd_hash_table_free (&abfd->section_htab);
+
+ abfd->tdata.any = preserve->tdata;
+ abfd->arch_info = preserve->arch_info;
+ abfd->flags = preserve->flags;
+ abfd->section_htab = preserve->section_htab;
+ abfd->sections = preserve->sections;
+ abfd->section_last = preserve->section_last;
+ abfd->section_count = preserve->section_count;
+
+ /* bfd_release frees all memory more recently bfd_alloc'd than
+ its arg, as well as its arg. */
+ bfd_release (abfd, preserve->marker);
+ preserve->marker = NULL;
+}
+
+/* Called when the bfd state saved by bfd_preserve_save is no longer
+ needed. */
+
+static void
+bfd_preserve_finish (bfd *abfd ATTRIBUTE_UNUSED, struct bfd_preserve *preserve)
+{
+ /* It would be nice to be able to free more memory here, eg. old
+ tdata, but that's not possible since these blocks are sitting
+ inside bfd_alloc'd memory. The section hash is on a separate
+ objalloc. */
+ bfd_hash_table_free (&preserve->section_htab);
+ preserve->marker = NULL;
+}
+
+/*
+FUNCTION
+ bfd_check_format_matches
+
+SYNOPSIS
+ bfd_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.
+*/
+
+bfd_boolean
+bfd_check_format_matches (bfd *abfd, bfd_format format, char ***matching)
+{
+ extern const bfd_target binary_vec;
+ const bfd_target * const *target;
+ const bfd_target **matching_vector = NULL;
+ const bfd_target *save_targ, *right_targ, *ar_right_targ, *match_targ;
+ int match_count, best_count, best_match;
+ int ar_match_index;
+ struct bfd_preserve preserve;
+
+ if (matching != NULL)
+ *matching = NULL;
+
+ if (!bfd_read_p (abfd)
+ || (unsigned int) abfd->format >= (unsigned int) bfd_type_end)
+ {
+ bfd_set_error (bfd_error_invalid_operation);
+ return FALSE;
+ }
+
+ if (abfd->format != bfd_unknown)
+ return abfd->format == format;
+
+ if (matching != NULL || *bfd_associated_vector != NULL)
+ {
+ bfd_size_type amt;
+
+ amt = sizeof (*matching_vector) * 2 * _bfd_target_vector_entries;
+ matching_vector = (const bfd_target **) bfd_malloc (amt);
+ if (!matching_vector)
+ return FALSE;
+ }
+
+ /* Presume the answer is yes. */
+ abfd->format = format;
+ save_targ = abfd->xvec;
+ preserve.marker = NULL;
+
+ /* 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! */
+ goto err_ret;
+
+ right_targ = BFD_SEND_FMT (abfd, _bfd_check_format, (abfd));
+
+ if (right_targ)
+ goto ok_ret;
+
+ /* 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)
+ goto err_unrecog;
+ }
+
+ /* Since the target type was defaulted, check them all in the hope
+ that one will be uniquely recognized. */
+ right_targ = NULL;
+ ar_right_targ = NULL;
+ match_targ = NULL;
+ best_match = 256;
+ best_count = 0;
+ match_count = 0;
+ ar_match_index = _bfd_target_vector_entries;
+
+ for (target = bfd_target_vector; *target != NULL; target++)
+ {
+ const bfd_target *temp;
+
+ /* Don't check the default target twice. */
+ if (*target == &binary_vec
+ || (!abfd->target_defaulted && *target == save_targ)
+ || (*target)->match_priority > best_match)
+ continue;
+
+ /* If we already tried a match, the bfd is modified and may
+ have sections attached, which will confuse the next
+ _bfd_check_format call. */
+ bfd_reinit (abfd);
+
+ /* Change BFD's target temporarily. */
+ abfd->xvec = *target;
+
+ if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
+ goto err_ret;
+
+ /* 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)
+ {
+ match_targ = temp;
+ if (preserve.marker != NULL)
+ bfd_preserve_finish (abfd, &preserve);
+
+ if (abfd->format != bfd_archive
+ || (bfd_has_map (abfd)
+ && bfd_get_error () != bfd_error_wrong_object_format))
+ {
+ /* This format checks out as ok! */
+ right_targ = temp;
+
+ /* 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])
+ goto ok_ret;
+
+ if (matching_vector)
+ matching_vector[match_count] = temp;
+ match_count++;
+
+ if (temp->match_priority < best_match)
+ {
+ best_match = temp->match_priority;
+ best_count = 0;
+ }
+ best_count++;
+ }
+ else
+ {
+ /* An archive with no armap or objects of the wrong
+ type. We want this target to match if we get no
+ better matches. */
+ if (ar_right_targ != bfd_default_vector[0])
+ ar_right_targ = *target;
+ if (matching_vector)
+ matching_vector[ar_match_index] = *target;
+ ar_match_index++;
+ }
+
+ if (!bfd_preserve_save (abfd, &preserve))
+ goto err_ret;
+ }
+ else if (bfd_get_error () != bfd_error_wrong_format)
+ goto err_ret;
+ }
+
+ if (best_count == 1)
+ match_count = 1;
+
+ if (match_count == 0)
+ {
+ /* Try partial matches. */
+ right_targ = ar_right_targ;
+
+ if (right_targ == bfd_default_vector[0])
+ {
+ match_count = 1;
+ }
+ else
+ {
+ match_count = ar_match_index - _bfd_target_vector_entries;
+
+ if (matching_vector && match_count > 1)
+ memcpy (matching_vector,
+ matching_vector + _bfd_target_vector_entries,
+ sizeof (*matching_vector) * match_count);
+ }
+ }
+
+ /* We have more than one equally good match. If any of the best
+ matches is a target in config.bfd targ_defvec or targ_selvecs,
+ choose it. */
+ if (match_count > 1)
+ {
+ const bfd_target * const *assoc = bfd_associated_vector;
+
+ while ((right_targ = *assoc++) != NULL)
+ {
+ int i = match_count;
+
+ while (--i >= 0)
+ if (matching_vector[i] == right_targ
+ && right_targ->match_priority <= best_match)
+ break;
+
+ if (i >= 0)
+ {
+ match_count = 1;
+ break;
+ }
+ }
+ }
+
+ /* We still have more than one equally good match, and at least some
+ of the targets support match priority. Choose the first of the
+ best matches. */
+ if (match_count > 1 && best_count != match_count)
+ {
+ int i;
+
+ for (i = 0; i < match_count; i++)
+ {
+ right_targ = matching_vector[i];
+ if (right_targ->match_priority <= best_match)
+ break;
+ }
+ match_count = 1;
+ }
+
+ /* There is way too much undoing of half-known state here. We
+ really shouldn't iterate on live bfd's. Note that saving the
+ whole bfd and restoring it would be even worse; the first thing
+ you notice is that the cached bfd file position gets out of sync. */
+ if (preserve.marker != NULL)
+ bfd_preserve_restore (abfd, &preserve);
+
+ if (match_count == 1)
+ {
+ abfd->xvec = right_targ;
+ /* If we come out of the loop knowing that the last target that
+ matched is the one we want, then ABFD should still be in a usable
+ state (except possibly for XVEC). */
+ if (match_targ != right_targ)
+ {
+ bfd_reinit (abfd);
+ if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
+ goto err_ret;
+ match_targ = BFD_SEND_FMT (abfd, _bfd_check_format, (abfd));
+ BFD_ASSERT (match_targ != NULL);
+ }
+
+ ok_ret:
+ /* If the file was opened for update, then `output_has_begun'
+ some time ago when the file was created. Do not recompute
+ sections sizes or alignments in _bfd_set_section_contents.
+ We can not set this flag until after checking the format,
+ because it will interfere with creation of BFD sections. */
+ if (abfd->direction == both_direction)
+ abfd->output_has_begun = TRUE;
+
+ if (matching_vector)
+ free (matching_vector);
+
+ /* File position has moved, BTW. */
+ return TRUE;
+ }
+
+ if (match_count == 0)
+ {
+ err_unrecog:
+ bfd_set_error (bfd_error_file_not_recognized);
+ err_ret:
+ abfd->xvec = save_targ;
+ abfd->format = bfd_unknown;
+ if (matching_vector)
+ free (matching_vector);
+ if (preserve.marker != NULL)
+ bfd_preserve_restore (abfd, &preserve);
+ return FALSE;
+ }
+
+ /* Restore original target type and format. */
+ abfd->xvec = save_targ;
+ abfd->format = bfd_unknown;
+ bfd_set_error (bfd_error_file_ambiguously_recognized);
+
+ if (matching)
+ {
+ *matching = (char **) matching_vector;
+ matching_vector[match_count] = NULL;
+ /* Return target names. This is a little nasty. Maybe we
+ should do another bfd_malloc? */
+ while (--match_count >= 0)
+ {
+ const char *name = matching_vector[match_count]->name;
+ *(const char **) &matching_vector[match_count] = name;
+ }
+ }
+ return FALSE;
+}
+
+/*
+FUNCTION
+ bfd_set_format
+
+SYNOPSIS
+ bfd_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.
+*/
+
+bfd_boolean
+bfd_set_format (bfd *abfd, bfd_format format)
+{
+ if (bfd_read_p (abfd)
+ || (unsigned int) abfd->format >= (unsigned int) bfd_type_end)
+ {
+ bfd_set_error (bfd_error_invalid_operation);
+ return FALSE;
+ }
+
+ if (abfd->format != bfd_unknown)
+ return abfd->format == format;
+
+ /* 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 (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/assembler/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 0000000..8387d64
--- /dev/null
+++ b/bfd/freebsd.h
@@ -0,0 +1,106 @@
+/* BFD back-end definitions used by all FreeBSD targets.
+ Copyright (C) 1990-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, 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 "sysdep.h"
+#include "bfd.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 bfd_boolean MY (write_object_contents) (bfd *);
+
+#include "aout-target.h"
+
+/* Write an object file.
+ Section contents have already been written. We write the
+ file header, symbols, and relocation. */
+
+static bfd_boolean
+MY (write_object_contents) (bfd *abfd)
+{
+ struct external_exec exec_bytes;
+ struct internal_exec *execp = exec_hdr (abfd);
+
+ obj_reloc_entry_size (abfd) = RELOC_STD_SIZE;
+
+ /* 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 0000000..b1a59ff
--- /dev/null
+++ b/bfd/gen-aout.c
@@ -0,0 +1,120 @@
+/* Generate parameters for an a.out system.
+ Copyright (C) 1990-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "/usr/include/a.out.h"
+#include <stdio.h>
+
+#ifndef _
+#define _(X) X
+#endif
+
+int
+main (int argc, char** argv)
+{
+ struct exec my_exec;
+ int page_size;
+ char * target;
+ char * arch = "unknown";
+ FILE * file;
+
+ target = argv[1];
+ if (target == NULL)
+ {
+ fprintf (stderr, "Usage: gen-aout target_name\n");
+ exit (1);
+ }
+
+ 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;
+ }
+
+ fclose (file);
+
+#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\n", arch);
+
+ printf ("/* Do not \"beautify\" the CONCAT* macro args. Traditional C will not");
+ printf (" remove whitespace added here, and thus will fail to concatenate");
+ printf (" the tokens. */");
+ printf ("\n#define MY(OP) CONCAT2 (%s_,OP)\n\n", target);
+ printf ("#define TARGETNAME \"a.out-%s\"\n\n", target);
+
+ printf ("#include \"sysdep.h\"\n");
+ printf ("#include \"bfd.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 0000000..c1c16d0
--- /dev/null
+++ b/bfd/genlink.h
@@ -0,0 +1,110 @@
+/* genlink.h -- interface to the BFD generic linker
+ Copyright (C) 1993-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, 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. */
+ bfd_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 a 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 a generic link hash table. */
+
+#define _bfd_generic_link_hash_traverse(table, func, info) \
+ (bfd_link_hash_traverse \
+ (&(table)->root, \
+ (bfd_boolean (*) (struct bfd_link_hash_entry *, void *)) (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 bfd_boolean _bfd_generic_link_output_symbols
+ (bfd *, bfd *, struct bfd_link_info *, size_t *);
+
+/* 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 bfd_boolean _bfd_generic_link_write_global_symbol
+ (struct generic_link_hash_entry *, void *);
+
+/* Generic link hash table entry creation routine. */
+struct bfd_hash_entry *_bfd_generic_link_hash_newfunc
+ (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 0000000..333eec0
--- /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,0x00,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,0x32,0x38,0x20,0x31,0x31,0x3a,0x31,0x35,0x3a,0x30,0x34,0x20,0x32,0x30,
+0x30,0x30,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,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,0x32,0x38,0x2f,0x31,0x30,
+0x30,0x20,0x31,0x31,0x3a,0x31,0x35,0x3a,0x30,0x34,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,0x32,
+0x38,0x2f,0x31,0x30,0x30,0x20,0x31,0x31,0x3a,0x31,0x35,0x3a,0x30,0x34,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,
+0x67,0x6f,0x33,0x32,0x73,0x74,0x75,0x62,0x2c,0x20,0x76,0x20,0x32,0x2e,0x30,0x32,
+0x54,0x00,0x00,0x00,0x00,0x00,0x08,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,0x08,0xb0,0x6d,0xba,0xa7,0x05,0xe9,0xd4,0x03,0xa2,
+0x69,0x08,0xbe,0x20,0x00,0x8b,0x04,0x09,0xc0,0x75,0x02,0xb4,0xfe,0xbb,0x70,0x08,
+0x39,0xc3,0x73,0x02,0x89,0xc3,0x89,0x1c,0xfe,0xc7,0xb9,0x04,0xff,0xd3,0xeb,0xb4,
+0x4a,0xcd,0x21,0x73,0x08,0xd3,0xe3,0xfe,0xcf,0x89,0x1c,0xeb,0xd8,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,0x8c,0x04,0x4f,0xae,0x75,0xdf,0xaf,0xb4,0x3e,0xbb,0x13,0x00,0xcd,0x21,
+0xb4,0x3e,0xbb,0x12,0x00,0xcd,0x21,0x06,0x57,0x31,0xc9,0x74,0x12,0xb0,0x6e,0xba,
+0x7e,0x05,0xe9,0x5e,0x03,0x09,0xc9,0x75,0xf4,0x41,0xe8,0xa1,0x03,0x72,0xee,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,0xd3,0x02,0x89,0x3e,
+0x2a,0x00,0x89,0x36,0x62,0x07,0x80,0x3e,0x2c,0x00,0x00,0x74,0x23,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,0x83,0xc3,0x04,0xc6,0x07,0x00,0x89,0x1e,0x62,0x07,
+0xb8,0x00,0x3d,0xba,0x64,0x07,0xcd,0x21,0x0f,0x82,0xb3,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,0x98,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,0x61,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,0xf5,0x02,0x8b,0x1e,0x04,0x06,0x09,0xdb,
+0x74,0x0a,0xb4,0x48,0xcd,0x21,0x0f,0x82,0x15,0x02,0x8e,0xc0,0xe8,0x08,0x03,0xb8,
+0x01,0x00,0xff,0x1e,0x00,0x06,0x0f,0x82,0x0f,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,0xf3,0x01,0xa3,0x16,0x06,
+0x66,0x8b,0x0e,0x1c,0x00,0xb8,0x01,0x05,0x8b,0x1e,0x1e,0x00,0xcd,0x31,0x0f,0x82,
+0xe5,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,0x83,0xe1,0x03,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,0x73,0x01,0xb8,0x00,0x01,0xcd,0x31,
+0x0f,0x82,0x6a,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,0x0f,0x01,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,0x03,0x01,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,
+0xd9,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,0xb0,
+0x66,0xba,0x48,0x05,0xeb,0x0c,0xb0,0x67,0xba,0x55,0x05,0xeb,0x05,0xb0,0x68,0xba,
+0x5f,0x05,0x52,0x8b,0x1e,0x62,0x07,0xc6,0x07,0x24,0xbb,0x64,0x07,0xeb,0x28,0xe8,
+0xf5,0x00,0xb0,0x69,0xba,0x99,0x05,0xeb,0x1a,0xb0,0x6a,0xba,0xb2,0x05,0xeb,0x13,
+0xb0,0x6b,0xba,0xc4,0x05,0xeb,0x0c,0xb0,0x6c,0xba,0xd6,0x05,0xeb,0x05,0xb0,0x69,
+0xba,0x99,0x05,0x52,0xbb,0x3b,0x05,0xe8,0x15,0x00,0x5b,0xe8,0x11,0x00,0xbb,0x67,
+0x04,0xe8,0x0b,0x00,0xb4,0x4c,0xcd,0x21,0x43,0x50,0xb4,0x02,0xcd,0x21,0x58,0x8a,
+0x17,0x80,0xfa,0x24,0x75,0xf2,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,0x4e,0xff,0x89,0xde,0x8b,0x3e,0x8c,0x04,0xeb,0x17,0xb4,0x3b,0xe8,0x41,0xff,
+0x81,0xfe,0x64,0x07,0x74,0x12,0x8a,0x44,0xff,0xe8,0x2a,0xff,0x74,0x04,0xc6,0x04,
+0x5c,0x46,0xe8,0x03,0x00,0x72,0xe4,0xc3,0xe8,0x34,0x00,0xbb,0x44,0x00,0x8a,0x07,
+0x88,0x04,0x43,0x46,0x08,0xc0,0x75,0xf6,0x06,0x57,0x1e,0x07,0xe8,0x9b,0xff,0xbb,
+0x2a,0x06,0x8c,0x5f,0x04,0x89,0x5f,0x02,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,0x27,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
diff --git a/bfd/hash.c b/bfd/hash.c
new file mode 100644
index 0000000..4149474
--- /dev/null
+++ b/bfd/hash.c
@@ -0,0 +1,912 @@
+/* hash.c -- hash table routines for BFD
+ Copyright (C) 1993-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+#include "objalloc.h"
+#include "libiberty.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.
+
+@findex bfd_hash_set_default_size
+ Use <<bfd_hash_set_default_size>> to set the default size of
+ hash table to use.
+
+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} (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 == NULL)
+. {
+. ret = bfd_hash_allocate (table, sizeof (* ret));
+. if (ret == 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
+
+/* The following function returns a nearest prime number which is
+ greater than N, and near a power of two. Copied from libiberty.
+ Returns zero for ridiculously large N to signify an error. */
+
+static unsigned long
+higher_prime_number (unsigned long n)
+{
+ /* These are primes that are near, but slightly smaller than, a
+ power of two. */
+ static const unsigned long primes[] =
+ {
+ (unsigned long) 31,
+ (unsigned long) 61,
+ (unsigned long) 127,
+ (unsigned long) 251,
+ (unsigned long) 509,
+ (unsigned long) 1021,
+ (unsigned long) 2039,
+ (unsigned long) 4093,
+ (unsigned long) 8191,
+ (unsigned long) 16381,
+ (unsigned long) 32749,
+ (unsigned long) 65521,
+ (unsigned long) 131071,
+ (unsigned long) 262139,
+ (unsigned long) 524287,
+ (unsigned long) 1048573,
+ (unsigned long) 2097143,
+ (unsigned long) 4194301,
+ (unsigned long) 8388593,
+ (unsigned long) 16777213,
+ (unsigned long) 33554393,
+ (unsigned long) 67108859,
+ (unsigned long) 134217689,
+ (unsigned long) 268435399,
+ (unsigned long) 536870909,
+ (unsigned long) 1073741789,
+ (unsigned long) 2147483647,
+ /* 4294967291L */
+ ((unsigned long) 2147483647) + ((unsigned long) 2147483644),
+ };
+
+ const unsigned long *low = &primes[0];
+ const unsigned long *high = &primes[sizeof (primes) / sizeof (primes[0])];
+
+ while (low != high)
+ {
+ const unsigned long *mid = low + (high - low) / 2;
+ if (n >= *mid)
+ low = mid + 1;
+ else
+ high = mid;
+ }
+
+ if (n >= *low)
+ return 0;
+
+ return *low;
+}
+
+static unsigned long bfd_default_hash_table_size = DEFAULT_SIZE;
+
+/* Create a new hash table, given a number of entries. */
+
+bfd_boolean
+bfd_hash_table_init_n (struct bfd_hash_table *table,
+ struct bfd_hash_entry *(*newfunc) (struct bfd_hash_entry *,
+ struct bfd_hash_table *,
+ const char *),
+ unsigned int entsize,
+ unsigned int size)
+{
+ unsigned long alloc;
+
+ alloc = size;
+ alloc *= sizeof (struct bfd_hash_entry *);
+ if (alloc / sizeof (struct bfd_hash_entry *) != size)
+ {
+ bfd_set_error (bfd_error_no_memory);
+ return FALSE;
+ }
+
+ table->memory = (void *) 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_hash_table_free (table);
+ bfd_set_error (bfd_error_no_memory);
+ return FALSE;
+ }
+ memset ((void *) table->table, 0, alloc);
+ table->size = size;
+ table->entsize = entsize;
+ table->count = 0;
+ table->frozen = 0;
+ table->newfunc = newfunc;
+ return TRUE;
+}
+
+/* Create a new hash table with the default number of entries. */
+
+bfd_boolean
+bfd_hash_table_init (struct bfd_hash_table *table,
+ struct bfd_hash_entry *(*newfunc) (struct bfd_hash_entry *,
+ struct bfd_hash_table *,
+ const char *),
+ unsigned int entsize)
+{
+ return bfd_hash_table_init_n (table, newfunc, entsize,
+ bfd_default_hash_table_size);
+}
+
+/* Free a hash table. */
+
+void
+bfd_hash_table_free (struct bfd_hash_table *table)
+{
+ objalloc_free ((struct objalloc *) table->memory);
+ table->memory = NULL;
+}
+
+static inline unsigned long
+bfd_hash_hash (const char *string, unsigned int *lenp)
+{
+ const unsigned char *s;
+ unsigned long hash;
+ unsigned int len;
+ unsigned int c;
+
+ hash = 0;
+ len = 0;
+ s = (const unsigned char *) string;
+ while ((c = *s++) != '\0')
+ {
+ hash += c + (c << 17);
+ hash ^= hash >> 2;
+ }
+ len = (s - (const unsigned char *) string) - 1;
+ hash += len + (len << 17);
+ hash ^= hash >> 2;
+ if (lenp != NULL)
+ *lenp = len;
+ return hash;
+}
+
+/* Look up a string in a hash table. */
+
+struct bfd_hash_entry *
+bfd_hash_lookup (struct bfd_hash_table *table,
+ const char *string,
+ bfd_boolean create,
+ bfd_boolean copy)
+{
+ unsigned long hash;
+ struct bfd_hash_entry *hashp;
+ unsigned int len;
+ unsigned int _index;
+
+ hash = bfd_hash_hash (string, &len);
+ _index = hash % table->size;
+ for (hashp = table->table[_index];
+ hashp != NULL;
+ hashp = hashp->next)
+ {
+ if (hashp->hash == hash
+ && strcmp (hashp->string, string) == 0)
+ return hashp;
+ }
+
+ if (! create)
+ return NULL;
+
+ if (copy)
+ {
+ char *new_string;
+
+ new_string = (char *) objalloc_alloc ((struct objalloc *) table->memory,
+ len + 1);
+ if (!new_string)
+ {
+ bfd_set_error (bfd_error_no_memory);
+ return NULL;
+ }
+ memcpy (new_string, string, len + 1);
+ string = new_string;
+ }
+
+ return bfd_hash_insert (table, string, hash);
+}
+
+/* Insert an entry in a hash table. */
+
+struct bfd_hash_entry *
+bfd_hash_insert (struct bfd_hash_table *table,
+ const char *string,
+ unsigned long hash)
+{
+ struct bfd_hash_entry *hashp;
+ unsigned int _index;
+
+ hashp = (*table->newfunc) (NULL, table, string);
+ if (hashp == NULL)
+ return NULL;
+ hashp->string = string;
+ hashp->hash = hash;
+ _index = hash % table->size;
+ hashp->next = table->table[_index];
+ table->table[_index] = hashp;
+ table->count++;
+
+ if (!table->frozen && table->count > table->size * 3 / 4)
+ {
+ unsigned long newsize = higher_prime_number (table->size);
+ struct bfd_hash_entry **newtable;
+ unsigned int hi;
+ unsigned long alloc = newsize * sizeof (struct bfd_hash_entry *);
+
+ /* If we can't find a higher prime, or we can't possibly alloc
+ that much memory, don't try to grow the table. */
+ if (newsize == 0 || alloc / sizeof (struct bfd_hash_entry *) != newsize)
+ {
+ table->frozen = 1;
+ return hashp;
+ }
+
+ newtable = ((struct bfd_hash_entry **)
+ objalloc_alloc ((struct objalloc *) table->memory, alloc));
+ if (newtable == NULL)
+ {
+ table->frozen = 1;
+ return hashp;
+ }
+ memset (newtable, 0, alloc);
+
+ for (hi = 0; hi < table->size; hi ++)
+ while (table->table[hi])
+ {
+ struct bfd_hash_entry *chain = table->table[hi];
+ struct bfd_hash_entry *chain_end = chain;
+
+ while (chain_end->next && chain_end->next->hash == chain->hash)
+ chain_end = chain_end->next;
+
+ table->table[hi] = chain_end->next;
+ _index = chain->hash % newsize;
+ chain_end->next = newtable[_index];
+ newtable[_index] = chain;
+ }
+ table->table = newtable;
+ table->size = newsize;
+ }
+
+ return hashp;
+}
+
+/* Rename an entry in a hash table. */
+
+void
+bfd_hash_rename (struct bfd_hash_table *table,
+ const char *string,
+ struct bfd_hash_entry *ent)
+{
+ unsigned int _index;
+ struct bfd_hash_entry **pph;
+
+ _index = ent->hash % table->size;
+ for (pph = &table->table[_index]; *pph != NULL; pph = &(*pph)->next)
+ if (*pph == ent)
+ break;
+ if (*pph == NULL)
+ abort ();
+
+ *pph = ent->next;
+ ent->string = string;
+ ent->hash = bfd_hash_hash (string, NULL);
+ _index = ent->hash % table->size;
+ ent->next = table->table[_index];
+ table->table[_index] = ent;
+}
+
+/* Replace an entry in a hash table. */
+
+void
+bfd_hash_replace (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) != NULL;
+ pph = &(*pph)->next)
+ {
+ if (*pph == old)
+ {
+ *pph = nw;
+ return;
+ }
+ }
+
+ abort ();
+}
+
+/* Allocate space in a hash table. */
+
+void *
+bfd_hash_allocate (struct bfd_hash_table *table,
+ unsigned int size)
+{
+ void * ret;
+
+ ret = objalloc_alloc ((struct objalloc *) table->memory, size);
+ if (ret == NULL && size != 0)
+ bfd_set_error (bfd_error_no_memory);
+ return ret;
+}
+
+/* Base method for creating a new hash table entry. */
+
+struct bfd_hash_entry *
+bfd_hash_newfunc (struct bfd_hash_entry *entry,
+ struct bfd_hash_table *table,
+ const char *string ATTRIBUTE_UNUSED)
+{
+ if (entry == NULL)
+ entry = (struct bfd_hash_entry *) bfd_hash_allocate (table,
+ sizeof (* entry));
+ return entry;
+}
+
+/* Traverse a hash table. */
+
+void
+bfd_hash_traverse (struct bfd_hash_table *table,
+ bfd_boolean (*func) (struct bfd_hash_entry *, void *),
+ void * info)
+{
+ unsigned int i;
+
+ table->frozen = 1;
+ 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))
+ goto out;
+ }
+ out:
+ table->frozen = 0;
+}
+
+unsigned long
+bfd_hash_set_default_size (unsigned long hash_size)
+{
+ /* Extend this prime list if you want more granularity of hash table size. */
+ static const unsigned long hash_size_primes[] =
+ {
+ 31, 61, 127, 251, 509, 1021, 2039, 4091, 8191, 16381, 32749, 65537
+ };
+ unsigned int _index;
+
+ /* Work out best prime number near the hash_size. */
+ for (_index = 0; _index < ARRAY_SIZE (hash_size_primes) - 1; ++_index)
+ if (hash_size <= hash_size_primes[_index])
+ break;
+
+ bfd_default_hash_table_size = hash_size_primes[_index];
+ return bfd_default_hash_table_size;
+}
+
+/* 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. */
+ bfd_boolean xcoff;
+};
+
+/* Routine to create an entry in a strtab. */
+
+static struct bfd_hash_entry *
+strtab_hash_newfunc (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 == NULL)
+ ret = (struct strtab_hash_entry *) bfd_hash_allocate (table,
+ sizeof (* ret));
+ if (ret == 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 (void)
+{
+ struct bfd_strtab_hash *table;
+ bfd_size_type amt = sizeof (* table);
+
+ table = (struct bfd_strtab_hash *) bfd_malloc (amt);
+ if (table == NULL)
+ return NULL;
+
+ if (!bfd_hash_table_init (&table->table, strtab_hash_newfunc,
+ sizeof (struct strtab_hash_entry)))
+ {
+ 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 (void)
+{
+ struct bfd_strtab_hash *ret;
+
+ ret = _bfd_stringtab_init ();
+ if (ret != NULL)
+ ret->xcoff = TRUE;
+ return ret;
+}
+
+/* Free a strtab. */
+
+void
+_bfd_stringtab_free (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. If COPY is true
+ then store a copy of STR if creating a new entry. */
+
+bfd_size_type
+_bfd_stringtab_add (struct bfd_strtab_hash *tab,
+ const char *str,
+ bfd_boolean hash,
+ bfd_boolean copy)
+{
+ 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 (* entry));
+ if (entry == NULL)
+ return (bfd_size_type) -1;
+ if (! copy)
+ entry->root.string = str;
+ else
+ {
+ size_t len = strlen (str) + 1;
+ char *n;
+
+ n = (char *) bfd_hash_allocate (&tab->table, len);
+ if (n == NULL)
+ return (bfd_size_type) -1;
+ memcpy (n, str, len);
+ 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 (struct bfd_strtab_hash *tab)
+{
+ return tab->size;
+}
+
+/* Write out a strtab. ABFD must already be at the right location in
+ the file. */
+
+bfd_boolean
+_bfd_stringtab_emit (bfd *abfd, struct bfd_strtab_hash *tab)
+{
+ bfd_boolean xcoff;
+ struct strtab_hash_entry *entry;
+
+ xcoff = tab->xcoff;
+
+ for (entry = tab->first; entry != NULL; entry = entry->next)
+ {
+ const char *str;
+ 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, (bfd_vma) len, buf);
+ if (bfd_bwrite ((void *) buf, (bfd_size_type) 2, abfd) != 2)
+ return FALSE;
+ }
+
+ if (bfd_bwrite ((void *) str, (bfd_size_type) len, abfd) != len)
+ return FALSE;
+ }
+
+ return TRUE;
+}
diff --git a/bfd/host-aout.c b/bfd/host-aout.c
new file mode 100644
index 0000000..0693f6c
--- /dev/null
+++ b/bfd/host-aout.c
@@ -0,0 +1,87 @@
+/* BFD backend for local host's a.out binaries
+ Copyright (C) 1990-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.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 */
+
+/* Do not "beautify" the CONCAT* macro args. Traditional C will not
+ remove whitespace added here, and thus will fail to concatenate
+ the tokens. */
+#define MY(OP) CONCAT2 (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 0000000..5b67e75
--- /dev/null
+++ b/bfd/hosts/alphalinux.h
@@ -0,0 +1,25 @@
+/* Copyright (C) 2007-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+/* Linux dumps "struct task_struct" at the end of the core-file. This
+ structure is currently 1080 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/alphavms.h b/bfd/hosts/alphavms.h
new file mode 100644
index 0000000..831a94c
--- /dev/null
+++ b/bfd/hosts/alphavms.h
@@ -0,0 +1,62 @@
+/* alphavms.h -- BFD definitions for an openVMS host
+ Copyright (C) 1996-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#ifdef PACKAGE
+#error sysdep.h must be included in lieu of config.h
+#endif
+
+#include "config.h"
+#include "ansidecl.h"
+
+#include <stddef.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <string.h>
+#include <sys/file.h>
+#include <stdlib.h>
+#include <unixlib.h>
+#include <unixio.h>
+#include <time.h>
+
+#include "filenames.h"
+#include "fopen-vms.h"
+
+#define NO_FCNTL 1
+
+#ifndef O_ACCMODE
+#define O_ACCMODE (O_RDONLY | O_WRONLY | O_RDWR)
+#endif
+
+extern int getpagesize (void);
+extern char *stpcpy (char *, const char *);
+
+/* No intl. */
+#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 */
+#define _(String) (String)
+#define N_(String) (String)
diff --git a/bfd/hosts/decstation.h b/bfd/hosts/decstation.h
new file mode 100644
index 0000000..2a072e8
--- /dev/null
+++ b/bfd/hosts/decstation.h
@@ -0,0 +1,36 @@
+/* Copyright (C) 2007-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+/* 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 0000000..a7abc8f
--- /dev/null
+++ b/bfd/hosts/delta68.h
@@ -0,0 +1,33 @@
+/* Copyright (C) 2005-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+/* 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
+/* User's stack, copied from sys/param.h */
+#define HOST_STACK_END_ADDR USRSTACK
+#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 0000000..639b82f
--- /dev/null
+++ b/bfd/hosts/dpx2.h
@@ -0,0 +1,27 @@
+/* Copyright (C) 2007-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+/* 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 0000000..4b9d0d8
--- /dev/null
+++ b/bfd/hosts/hp300bsd.h
@@ -0,0 +1,32 @@
+/* Copyright (C) 2007-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#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 0000000..24a35c9
--- /dev/null
+++ b/bfd/hosts/i386bsd.h
@@ -0,0 +1,51 @@
+/* Copyright (C) 2007-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+/* 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 0000000..0c8536e
--- /dev/null
+++ b/bfd/hosts/i386linux.h
@@ -0,0 +1,27 @@
+/* Copyright (C) 2007-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+/* 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 0000000..8872f0d
--- /dev/null
+++ b/bfd/hosts/i386mach3.h
@@ -0,0 +1,44 @@
+/* Copyright (C) 2007-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#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 0000000..3e2a8b6
--- /dev/null
+++ b/bfd/hosts/i386sco.h
@@ -0,0 +1,38 @@
+/* Copyright (C) 2007-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+/* 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 0000000..b16e276
--- /dev/null
+++ b/bfd/hosts/i860mach3.h
@@ -0,0 +1,46 @@
+/* Copyright (C) 2007-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+/* 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 0000000..1a34c4f
--- /dev/null
+++ b/bfd/hosts/m68kaux.h
@@ -0,0 +1,35 @@
+/* Copyright (C) 2007-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+/* 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 0000000..533158b
--- /dev/null
+++ b/bfd/hosts/m68klinux.h
@@ -0,0 +1,25 @@
+/* Copyright (C) 2007-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+/* 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 0000000..af4a1ce
--- /dev/null
+++ b/bfd/hosts/m88kmach3.h
@@ -0,0 +1,30 @@
+/* Copyright (C) 2007-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#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 0000000..fd4b431
--- /dev/null
+++ b/bfd/hosts/mipsbsd.h
@@ -0,0 +1,31 @@
+/* Copyright (C) 2007-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#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 0000000..fd8357b
--- /dev/null
+++ b/bfd/hosts/mipsmach3.h
@@ -0,0 +1,29 @@
+/* Copyright (C) 2007-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#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 0000000..8358c76
--- /dev/null
+++ b/bfd/hosts/news-mips.h
@@ -0,0 +1,31 @@
+/* Copyright (C) 2007-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+/* 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 0000000..798263e
--- /dev/null
+++ b/bfd/hosts/news.h
@@ -0,0 +1,28 @@
+/* Copyright (C) 2007-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+/* 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 0000000..981ee95
--- /dev/null
+++ b/bfd/hosts/pc532mach.h
@@ -0,0 +1,43 @@
+/* Copyright (C) 2007-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#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 0000000..16d1b92
--- /dev/null
+++ b/bfd/hosts/riscos.h
@@ -0,0 +1,29 @@
+/* Copyright (C) 2007-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+/* 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 0000000..4ece03a
--- /dev/null
+++ b/bfd/hosts/symmetry.h
@@ -0,0 +1,39 @@
+/* Copyright (C) 2007-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+/* 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 0000000..f41d6c4
--- /dev/null
+++ b/bfd/hosts/tahoe.h
@@ -0,0 +1,31 @@
+/* Copyright (C) 2007-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#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 0000000..9e51fbe
--- /dev/null
+++ b/bfd/hosts/vaxbsd.h
@@ -0,0 +1,31 @@
+/* Copyright (C) 2005-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#define NO_CORE_COMMAND /* No command name in core file */
+
+#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/vaxlinux.h b/bfd/hosts/vaxlinux.h
new file mode 100644
index 0000000..ef1f5dc
--- /dev/null
+++ b/bfd/hosts/vaxlinux.h
@@ -0,0 +1,21 @@
+/* Copyright (C) 2005-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#define TRAD_CORE_EXTRA_SIZE_ALLOWED 4096
+#define HOST_MACHINE_ARCH bfd_arch_vax
diff --git a/bfd/hosts/vaxult.h b/bfd/hosts/vaxult.h
new file mode 100644
index 0000000..c7ed333
--- /dev/null
+++ b/bfd/hosts/vaxult.h
@@ -0,0 +1,27 @@
+/* Copyright (C) 2007-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#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 0000000..c7ed333
--- /dev/null
+++ b/bfd/hosts/vaxult2.h
@@ -0,0 +1,27 @@
+/* Copyright (C) 2007-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#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/x86-64linux.h b/bfd/hosts/x86-64linux.h
new file mode 100644
index 0000000..27fd176
--- /dev/null
+++ b/bfd/hosts/x86-64linux.h
@@ -0,0 +1,232 @@
+/* Copyright (C) 2006-2014 Free Software Foundation, Inc.
+ This file is part of 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 Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* This is somewhat modelled after the file of the same name on SVR4
+ systems. It provides a definition of the core file format for ELF
+ used on Linux. It doesn't have anything to do with the /proc file
+ system, even though Linux has one.
+
+ Anyway, the whole purpose of this file is for GDB and GDB only.
+ Don't read too much into it. Don't use it for anything other than
+ GDB unless you know what you are doing. */
+
+#include <features.h>
+#include <sys/time.h>
+#include <sys/types.h>
+
+/* We define here only the symbols differing from their 64-bit variant. */
+#include <sys/procfs.h>
+
+#ifdef HAVE_STDINT_H
+#include <stdint.h>
+#else
+typedef unsigned int uint32_t;
+typedef unsigned long long int uint64_t;
+#endif
+
+/* Unsigned 64-bit integer aligned to 8 bytes. */
+typedef uint64_t __attribute__ ((__aligned__ (8))) a8_uint64_t;
+
+#undef HAVE_PRPSINFO32_T
+#define HAVE_PRPSINFO32_T
+#undef HAVE_PRPSINFO32_T_PR_PID
+#define HAVE_PRPSINFO32_T_PR_PID
+
+#undef HAVE_PRSTATUS32_T
+#define HAVE_PRSTATUS32_T
+
+/* These are the 32-bit x86 structures. */
+
+struct user_regs32_struct
+{
+ int32_t ebx;
+ int32_t ecx;
+ int32_t edx;
+ int32_t esi;
+ int32_t edi;
+ int32_t ebp;
+ int32_t eax;
+ int32_t xds;
+ int32_t xes;
+ int32_t xfs;
+ int32_t xgs;
+ int32_t orig_eax;
+ int32_t eip;
+ int32_t xcs;
+ int32_t eflags;
+ int32_t esp;
+ int32_t xss;
+};
+
+struct user_regs64_struct
+{
+ a8_uint64_t r15;
+ a8_uint64_t r14;
+ a8_uint64_t r13;
+ a8_uint64_t r12;
+ a8_uint64_t rbp;
+ a8_uint64_t rbx;
+ a8_uint64_t r11;
+ a8_uint64_t r10;
+ a8_uint64_t r9;
+ a8_uint64_t r8;
+ a8_uint64_t rax;
+ a8_uint64_t rcx;
+ a8_uint64_t rdx;
+ a8_uint64_t rsi;
+ a8_uint64_t rdi;
+ a8_uint64_t orig_rax;
+ a8_uint64_t rip;
+ a8_uint64_t cs;
+ a8_uint64_t eflags;
+ a8_uint64_t rsp;
+ a8_uint64_t ss;
+ a8_uint64_t fs_base;
+ a8_uint64_t gs_base;
+ a8_uint64_t ds;
+ a8_uint64_t es;
+ a8_uint64_t fs;
+ a8_uint64_t gs;
+};
+
+/* Type for a general-purpose register. */
+typedef uint32_t elf_greg32_t;
+typedef a8_uint64_t elf_greg64_t;
+
+/* And the whole bunch of them. We could have used `struct
+ user_regs_struct' directly in the typedef, but tradition says that
+ the register set is an array, which does have some peculiar
+ semantics, so leave it that way. */
+#define ELF_NGREG32 (sizeof (struct user_regs32_struct) / sizeof(elf_greg32_t))
+typedef elf_greg32_t elf_gregset32_t[ELF_NGREG32];
+#define ELF_NGREG64 (sizeof (struct user_regs64_struct) / sizeof(elf_greg64_t))
+typedef elf_greg64_t elf_gregset64_t[ELF_NGREG64];
+
+/* Definitions to generate Intel SVR4-like core files. These mostly
+ have the same names as the SVR4 types with "elf_" tacked on the
+ front to prevent clashes with Linux definitions, and the typedef
+ forms have been avoided. This is mostly like the SVR4 structure,
+ but more Linuxy, with things that Linux does not support and which
+ GDB doesn't really use excluded. */
+
+struct prstatus32_timeval
+ {
+ int tv_sec;
+ int tv_usec;
+ };
+
+struct prstatus64_timeval
+ {
+ a8_uint64_t tv_sec;
+ a8_uint64_t tv_usec;
+ };
+
+struct elf_prstatus32
+ {
+ struct elf_siginfo pr_info; /* Info associated with signal. */
+ short int pr_cursig; /* Current signal. */
+ unsigned int pr_sigpend; /* Set of pending signals. */
+ unsigned int pr_sighold; /* Set of held signals. */
+ pid_t pr_pid;
+ pid_t pr_ppid;
+ pid_t pr_pgrp;
+ pid_t pr_sid;
+ struct prstatus32_timeval pr_utime; /* User time. */
+ struct prstatus32_timeval pr_stime; /* System time. */
+ struct prstatus32_timeval pr_cutime; /* Cumulative user time. */
+ struct prstatus32_timeval pr_cstime; /* Cumulative system time. */
+ elf_gregset32_t pr_reg; /* GP registers. */
+ int pr_fpvalid; /* True if math copro being used. */
+ };
+
+struct elf_prstatusx32
+ {
+ struct elf_siginfo pr_info; /* Info associated with signal. */
+ short int pr_cursig; /* Current signal. */
+ unsigned int pr_sigpend; /* Set of pending signals. */
+ unsigned int pr_sighold; /* Set of held signals. */
+ pid_t pr_pid;
+ pid_t pr_ppid;
+ pid_t pr_pgrp;
+ pid_t pr_sid;
+ struct prstatus32_timeval pr_utime; /* User time. */
+ struct prstatus32_timeval pr_stime; /* System time. */
+ struct prstatus32_timeval pr_cutime; /* Cumulative user time. */
+ struct prstatus32_timeval pr_cstime; /* Cumulative system time. */
+ elf_gregset64_t pr_reg; /* GP registers. */
+ int pr_fpvalid; /* True if math copro being used. */
+ };
+
+struct elf_prstatus64
+ {
+ struct elf_siginfo pr_info; /* Info associated with signal. */
+ short int pr_cursig; /* Current signal. */
+ a8_uint64_t pr_sigpend; /* Set of pending signals. */
+ a8_uint64_t pr_sighold; /* Set of held signals. */
+ pid_t pr_pid;
+ pid_t pr_ppid;
+ pid_t pr_pgrp;
+ pid_t pr_sid;
+ struct prstatus64_timeval pr_utime; /* User time. */
+ struct prstatus64_timeval pr_stime; /* System time. */
+ struct prstatus64_timeval pr_cutime; /* Cumulative user time. */
+ struct prstatus64_timeval pr_cstime; /* Cumulative system time. */
+ elf_gregset64_t pr_reg; /* GP registers. */
+ int pr_fpvalid; /* True if math copro being used. */
+ };
+
+struct elf_prpsinfo32
+ {
+ char pr_state; /* Numeric process state. */
+ char pr_sname; /* Char for pr_state. */
+ char pr_zomb; /* Zombie. */
+ char pr_nice; /* Nice val. */
+ unsigned int pr_flag; /* Flags. */
+ unsigned short int pr_uid;
+ unsigned short int pr_gid;
+ int pr_pid, pr_ppid, pr_pgrp, pr_sid;
+ /* Lots missing */
+ char pr_fname[16]; /* Filename of executable. */
+ char pr_psargs[ELF_PRARGSZ]; /* Initial part of arg list. */
+ };
+
+struct elf_prpsinfo64
+ {
+ char pr_state; /* Numeric process state. */
+ char pr_sname; /* Char for pr_state. */
+ char pr_zomb; /* Zombie. */
+ char pr_nice; /* Nice val. */
+ a8_uint64_t pr_flag; /* Flags. */
+ unsigned int pr_uid;
+ unsigned int pr_gid;
+ int pr_pid, pr_ppid, pr_pgrp, pr_sid;
+ /* Lots missing */
+ char pr_fname[16]; /* Filename of executable. */
+ char pr_psargs[ELF_PRARGSZ]; /* Initial part of arg list. */
+ };
+
+/* The rest of this file provides the types for emulation of the
+ Solaris <proc_service.h> interfaces that should be implemented by
+ users of libthread_db. */
+
+/* Process status and info. In the end we do provide typedefs for them. */
+typedef struct elf_prstatus32 prstatus32_t;
+typedef struct elf_prstatusx32 prstatusx32_t;
+typedef struct elf_prstatus64 prstatus64_t;
+typedef struct elf_prpsinfo32 prpsinfo32_t;
+typedef struct elf_prpsinfo64 prpsinfo64_t;
diff --git a/bfd/hp300bsd.c b/bfd/hp300bsd.c
new file mode 100644
index 0000000..9cca44a
--- /dev/null
+++ b/bfd/hp300bsd.c
@@ -0,0 +1,40 @@
+/* BFD back-end for HP 9000/300 (68000-based) machines running BSD Unix.
+ Copyright (C) 1992-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#define TARGET_IS_BIG_ENDIAN_P
+#define N_HEADER_IN_TEXT(x) 0
+#define ENTRY_CAN_BE_ZERO
+#define TEXT_START_ADDR 0
+#define TARGET_PAGE_SIZE 4096
+#define SEGMENT_SIZE TARGET_PAGE_SIZE
+#define DEFAULT_ARCH bfd_arch_m68k
+
+/* Do not "beautify" the CONCAT* macro args. Traditional C will not
+ remove whitespace added here, and thus will fail to concatenate
+ the tokens. */
+#define MY(OP) CONCAT2 (m68k_aout_hp300bsd_,OP)
+#define TARGETNAME "a.out-hp300bsd"
+
+#include "sysdep.h"
+#include "bfd.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 0000000..fa21a77
--- /dev/null
+++ b/bfd/hp300hpux.c
@@ -0,0 +1,857 @@
+/* BFD backend for hp-ux 9000/300
+ Copyright (C) 1990-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, 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
+ canonicalize_symtab
+ get_symtab_upper_bound
+ canonicalize_reloc
+ mkobject
+ This should also be fixed. */
+
+#define TARGETNAME "a.out-hp300hpux"
+
+/* Do not "beautify" the CONCAT* macro args. Traditional C will not
+ remove whitespace added here, and thus will fail to concatenate
+ the tokens. */
+#define MY(OP) CONCAT2 (m68k_aout_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
+ (CONCAT2 winds up being expanded recursively, which ANSI C compilers
+ will not do). */
+#define MY_canonicalize_symtab m68k_aout_hp300hpux_canonicalize_symtab
+#define MY_get_symtab_upper_bound m68k_aout_hp300hpux_get_symtab_upper_bound
+#define MY_canonicalize_reloc m68k_aout_hp300hpux_canonicalize_reloc
+#define MY_write_object_contents m68k_aout_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 m68k_aout_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) CONCAT3 (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"
+
+static const bfd_target * MY (callback) (bfd *);
+static bfd_boolean MY (write_object_contents) (bfd *);
+static void convert_sym_type
+ (struct external_nlist *, aout_symbol_type *, bfd *);
+
+bfd_boolean MY (slurp_symbol_table) (bfd *);
+void MY (swap_std_reloc_in)
+ (bfd *, struct hp300hpux_reloc *, arelent *, asymbol **, bfd_size_type);
+bfd_boolean MY (slurp_reloc_table)
+ (bfd *, sec_ptr, asymbol **);
+long MY (canonicalize_symtab) (bfd *, asymbol **);
+long MY (get_symtab_upper_bound) (bfd *);
+long MY (canonicalize_reloc) (bfd *, sec_ptr, arelent **, asymbol **);
+
+/* 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) (bfd *abfd)
+{
+ struct internal_exec *execp = exec_hdr (abfd);
+
+ /* Calculate the file positions of the parts of a newly read aout header */
+ obj_textsec (abfd)->size = N_TXTSIZE (*execp);
+
+ /* The virtual memory addresses of the sections */
+ obj_textsec (abfd)->vma = N_TXTADDR (*execp);
+ obj_datasec (abfd)->vma = N_DATADDR (*execp);
+ obj_bsssec (abfd)->vma = N_BSSADDR (*execp);
+
+ obj_textsec (abfd)->lma = obj_textsec (abfd)->vma;
+ obj_datasec (abfd)->lma = obj_datasec (abfd)->vma;
+ obj_bsssec (abfd)->lma = obj_bsssec (abfd)->vma;
+
+ /* The file offsets of the sections */
+ obj_textsec (abfd)->filepos = N_TXTOFF (*execp);
+ obj_datasec (abfd)->filepos = N_DATOFF (*execp);
+
+ /* The file offsets of the relocation info */
+ obj_textsec (abfd)->rel_filepos = N_TRELOFF (*execp);
+ obj_datasec (abfd)->rel_filepos = N_DRELOFF (*execp);
+
+ /* The file offsets of the string table and symbol table. */
+ obj_sym_filepos (abfd) = N_SYMOFF (*execp);
+ obj_str_filepos (abfd) = N_STROFF (*execp);
+
+ /* Determine the architecture and machine type of the object file. */
+#ifdef SET_ARCH_MACH
+ SET_ARCH_MACH (abfd, *execp);
+#else
+ bfd_default_set_arch_mach (abfd, DEFAULT_ARCH, 0);
+#endif
+
+ if (obj_aout_subformat (abfd) == gnu_encap_format)
+ {
+ /* The file offsets of the relocation info */
+ obj_textsec (abfd)->rel_filepos = N_GNU_TRELOFF (*execp);
+ obj_datasec (abfd)->rel_filepos = N_GNU_DRELOFF (*execp);
+
+ /* The file offsets of the string table and symbol table. */
+ obj_sym_filepos (abfd) = N_GNU_SYMOFF (*execp);
+ obj_str_filepos (abfd) = (obj_sym_filepos (abfd) + execp->a_syms);
+
+ abfd->flags |= HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS;
+ bfd_get_symcount (abfd) = execp->a_syms / 12;
+ obj_symbol_entry_size (abfd) = 12;
+ obj_reloc_entry_size (abfd) = RELOC_STD_SIZE;
+ }
+
+ return abfd->xvec;
+}
+
+extern bfd_boolean aout_32_write_syms (bfd *);
+
+static bfd_boolean
+MY (write_object_contents) (bfd * abfd)
+{
+ struct external_exec exec_bytes;
+ struct internal_exec *execp = exec_hdr (abfd);
+ bfd_size_type text_size; /* dummy vars */
+ file_ptr text_end;
+
+ memset (&exec_bytes, 0, sizeof (exec_bytes));
+
+ obj_reloc_entry_size (abfd) = RELOC_STD_SIZE;
+
+ if (adata (abfd).magic == undecided_magic)
+ NAME (aout,adjust_sizes_and_vmas) (abfd, &text_size, &text_end);
+ execp->a_syms = 0;
+
+ execp->a_entry = bfd_get_start_address (abfd);
+
+ execp->a_trsize = ((obj_textsec (abfd)->reloc_count) *
+ obj_reloc_entry_size (abfd));
+ execp->a_drsize = ((obj_datasec (abfd)->reloc_count) *
+ obj_reloc_entry_size (abfd));
+
+ N_SET_MACHTYPE (*execp, 0xc);
+ N_SET_FLAGS (*execp, aout_backend_info (abfd)->exec_hdr_flags);
+
+ NAME (aout,swap_exec_header_out) (abfd, execp, &exec_bytes);
+
+ /* update fields not covered by default swap_exec_header_out */
+
+ /* this is really the sym table size but we store it in drelocs */
+ H_PUT_32 (abfd, (bfd_get_symcount (abfd) * 12), exec_bytes.e_drelocs);
+
+ if (bfd_seek (abfd, (file_ptr) 0, FALSE) != 0
+ || (bfd_bwrite (&exec_bytes, (bfd_size_type) EXEC_BYTES_SIZE, abfd)
+ != EXEC_BYTES_SIZE))
+ return FALSE;
+
+ /* Write out the symbols, and then the relocs. We must write out
+ the symbols first so that we know the symbol indices. */
+
+ if (bfd_get_symcount (abfd) != 0)
+ {
+ /* Skip the relocs to where we want to put the symbols. */
+ if (bfd_seek (abfd, (file_ptr) (N_DRELOFF (*execp) + execp->a_drsize),
+ SEEK_SET) != 0)
+ return FALSE;
+ }
+
+ if (!MY (write_syms) (abfd))
+ return FALSE;
+
+ if (bfd_get_symcount (abfd) != 0)
+ {
+ if (bfd_seek (abfd, (file_ptr) N_TRELOFF (*execp), SEEK_CUR) != 0)
+ return FALSE;
+ if (!NAME (aout,squirt_out_relocs) (abfd, obj_textsec (abfd)))
+ return FALSE;
+ if (bfd_seek (abfd, (file_ptr) N_DRELOFF (*execp), SEEK_CUR) != 0)
+ return FALSE;
+ if (!NAME (aout,squirt_out_relocs) (abfd, obj_datasec (abfd)))
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/* 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 (struct external_nlist *sym_pointer ATTRIBUTE_UNUSED,
+ aout_symbol_type *cache_ptr,
+ bfd *abfd ATTRIBUTE_UNUSED)
+{
+ 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) (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 = 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 bizarrely 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;
+ bfd_size_type amt;
+
+ if (H_GET_32 (abfd, bytes->e_passize) != 0)
+ break;
+ if (H_GET_32 (abfd, bytes->e_syms) != 0)
+ break;
+ if (H_GET_32 (abfd, bytes->e_supsize) != 0)
+ break;
+
+ syms = 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 */
+ amt = sizeof (*rawptr);
+ rawptr = (struct aout_data_struct *) bfd_zalloc (abfd, amt);
+
+ 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
+ ...
+*/
+
+bfd_boolean
+MY (slurp_symbol_table) (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;
+ bfd_size_type amt;
+
+ /* 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;
+
+ amt = symbol_bytes + SYM_EXTRA_BYTES;
+ strings = (char *) bfd_alloc (abfd, amt);
+ if (!strings)
+ return FALSE;
+ syms = (struct external_nlist *) (strings + SYM_EXTRA_BYTES);
+ if (bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET) != 0
+ || bfd_bread (syms, symbol_bytes, 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;
+
+ amt = num_syms;
+ amt *= sizeof (aout_symbol_type);
+ cached = (aout_symbol_type *) bfd_zalloc (abfd, amt);
+ if (cached == NULL && num_syms != 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, caching symbol properties */
+ {
+ aout_symbol_type *cache_ptr = cached;
+ /* 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 */
+
+ convert_sym_type (sym_pointer, cache_ptr, abfd);
+ if (!translate_from_native_sym_flags (abfd, cache_ptr))
+ return FALSE;
+
+ /********************************************************/
+ /* for hpux, the 'length' 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) (bfd *abfd,
+ struct hp300hpux_reloc *bytes,
+ arelent *cache_ptr,
+ asymbol **symbols,
+ bfd_size_type symcount ATTRIBUTE_UNUSED)
+{
+ 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 = H_GET_32 (abfd, bytes->r_address);
+ r_index = 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);
+ }
+}
+
+bfd_boolean
+MY (slurp_reloc_table) (bfd *abfd, sec_ptr asect, asymbol **symbols)
+{
+ bfd_size_type count;
+ bfd_size_type reloc_size;
+ void * 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, count * sizeof (arelent));
+ if (!reloc_cache && count != 0)
+ return FALSE;
+
+ relocs = bfd_alloc (abfd, reloc_size);
+ if (!relocs && reloc_size != 0)
+ {
+ bfd_release (abfd, reloc_cache);
+ return FALSE;
+ }
+
+ if (bfd_bread (relocs, 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_size_type) 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_canonicalize_symtab (bfd *, asymbol **);
+long aout_32_get_symtab_upper_bound (bfd *);
+long aout_32_canonicalize_reloc (bfd *, sec_ptr, arelent **, asymbol **);
+
+long
+MY (canonicalize_symtab) (bfd *abfd, asymbol **location)
+{
+ unsigned int counter = 0;
+ aout_symbol_type *symbase;
+
+ if (obj_aout_subformat (abfd) == gnu_encap_format)
+ return aout_32_canonicalize_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) (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) (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/hppabsd-core.c b/bfd/hppabsd-core.c
new file mode 100644
index 0000000..3b1215b
--- /dev/null
+++ b/bfd/hppabsd-core.c
@@ -0,0 +1,269 @@
+/* BFD back-end for HPPA BSD core files.
+ Copyright (C) 1993-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, 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 "sysdep.h"
+#include "bfd.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>
+
+#define hppabsd_core_core_file_matches_executable_p generic_core_file_matches_executable_p
+#define hppabsd_core_core_file_pid _bfd_nocore_core_file_pid
+
+/* 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 (bfd *abfd,
+ const char *name,
+ flagword flags,
+ bfd_size_type size,
+ file_ptr offset,
+ unsigned int alignment_power)
+{
+ asection *asect;
+
+ asect = bfd_make_section_with_flags (abfd, name, flags);
+ if (!asect)
+ return NULL;
+
+ asect->size = size;
+ asect->filepos = offset;
+ asect->alignment_power = alignment_power;
+
+ return asect;
+}
+
+static const bfd_target *
+hppabsd_core_core_file_p (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_bread ((void *) &u, (bfd_size_type) 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. */
+ {
+ struct stat statbuf;
+
+ if (bfd_stat (abfd, &statbuf) < 0)
+ 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, (bfd_size_type) 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);
+ if (core_stacksec (abfd) == NULL)
+ goto fail;
+ 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);
+ if (core_datasec (abfd) == NULL)
+ goto fail;
+ core_datasec (abfd)->vma = UDATASEG;
+
+ core_regsec (abfd) = make_bfd_asection (abfd, ".reg",
+ SEC_HAS_CONTENTS,
+ KSTAKSIZE * NBPG,
+ NBPG * USIZE, 2);
+ if (core_regsec (abfd) == NULL)
+ goto fail;
+ core_regsec (abfd)->vma = 0;
+
+ strncpy (core_command (abfd), u.u_comm, MAXCOMLEN + 1);
+ core_signal (abfd) = u.u_code;
+ return abfd->xvec;
+
+ fail:
+ bfd_release (abfd, abfd->tdata.any);
+ abfd->tdata.any = NULL;
+ bfd_section_list_clear (abfd);
+ return NULL;
+}
+
+static char *
+hppabsd_core_core_file_failing_command (bfd *abfd)
+{
+ return core_command (abfd);
+}
+
+static int
+hppabsd_core_core_file_failing_signal (bfd *abfd)
+{
+ return core_signal (abfd);
+}
+
+/* If somebody calls any byte-swapping routines, shoot them. */
+static void
+swap_abort (void)
+{
+ /* This way doesn't require any declaration for ANSI to fuck up. */
+ abort ();
+}
+
+#define NO_GET ((bfd_vma (*) (const void *)) swap_abort)
+#define NO_PUT ((void (*) (bfd_vma, void *)) swap_abort)
+#define NO_GETS ((bfd_signed_vma (*) (const void *)) swap_abort)
+#define NO_GET64 ((bfd_uint64_t (*) (const void *)) swap_abort)
+#define NO_PUT64 ((void (*) (bfd_uint64_t, void *)) swap_abort)
+#define NO_GETS64 ((bfd_int64_t (*) (const void *)) swap_abort)
+
+const bfd_target core_hppabsd_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_GET64, NO_GETS64, NO_PUT64, /* 64 bit data */
+ NO_GET, NO_GETS, NO_PUT, /* 32 bit data */
+ NO_GET, NO_GETS, NO_PUT, /* 16 bit data */
+ NO_GET64, NO_GETS64, NO_PUT64, /* 64 bit hdrs */
+ NO_GET, NO_GETS, NO_PUT, /* 32 bit hdrs */
+ NO_GET, NO_GETS, 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 (_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),
+
+ NULL,
+
+ NULL /* backend_data */
+ };
+#endif
diff --git a/bfd/hpux-core.c b/bfd/hpux-core.c
new file mode 100644
index 0000000..c667465
--- /dev/null
+++ b/bfd/hpux-core.c
@@ -0,0 +1,428 @@
+/* BFD back-end for HP/UX core files.
+ Copyright (C) 1993-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+
+/* This file can only be compiled on systems which use HP/UX style
+ core files. */
+
+#include "sysdep.h"
+#include "bfd.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>
+#ifdef HPUX_CORE
+#include <machine/reg.h>
+#endif
+#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)
+#define hpux_core_core_file_matches_executable_p generic_core_file_matches_executable_p
+#define hpux_core_core_file_pid _bfd_nocore_core_file_pid
+
+static asection *make_bfd_asection (bfd *, const char *, flagword,
+ bfd_size_type, bfd_vma, unsigned int);
+static const bfd_target *hpux_core_core_file_p (bfd *);
+static char *hpux_core_core_file_failing_command (bfd *);
+static int hpux_core_core_file_failing_signal (bfd *);
+static void swap_abort (void);
+
+static asection *
+make_bfd_asection (bfd *abfd, const char *name, flagword flags,
+ bfd_size_type size, bfd_vma vma,
+ unsigned int alignment_power)
+{
+ asection *asect;
+ char *newname;
+
+ newname = bfd_alloc (abfd, (bfd_size_type) strlen (name) + 1);
+ if (!newname)
+ return NULL;
+
+ strcpy (newname, name);
+
+ asect = bfd_make_section_anyway_with_flags (abfd, newname, flags);
+ if (!asect)
+ return NULL;
+
+ asect->size = size;
+ asect->vma = vma;
+ asect->filepos = bfd_tell (abfd);
+ asect->alignment_power = alignment_power;
+
+ return asect;
+}
+
+/* Return true if the given core file section corresponds to a thread,
+ based on its name. */
+
+static int
+thread_section_p (bfd *abfd ATTRIBUTE_UNUSED,
+ asection *sect,
+ void *obj ATTRIBUTE_UNUSED)
+{
+ return CONST_STRNEQ (sect->name, ".reg/");
+}
+
+/* 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 (bfd *abfd)
+{
+ int good_sections = 0;
+ int unknown_sections = 0;
+
+ core_hdr (abfd) = (struct hpux_core_struct *)
+ bfd_zalloc (abfd, (bfd_size_type) sizeof (struct hpux_core_struct));
+ if (!core_hdr (abfd))
+ return NULL;
+
+ while (1)
+ {
+ int val;
+ struct corehead core_header;
+
+ val = bfd_bread ((void *) &core_header,
+ (bfd_size_type) sizeof core_header, abfd);
+ if (val <= 0)
+ break;
+ switch (core_header.type)
+ {
+ case CORE_KERNEL:
+ case CORE_FORMAT:
+ /* Just skip this. */
+ bfd_seek (abfd, (file_ptr) core_header.len, SEEK_CUR);
+ good_sections++;
+ break;
+ case CORE_EXEC:
+ {
+ struct proc_exec proc_exec;
+ if (bfd_bread ((void *) &proc_exec, (bfd_size_type) 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_bread (&proc_info, (bfd_size_type) 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, -((file_ptr) 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,
+ (bfd_vma) offsetof (struct proc_info,
+ hw_regs),
+ 2))
+ goto fail;
+ }
+ 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,
+ (bfd_vma)offsetof (struct proc_info,
+ hw_regs),
+ 2))
+ goto fail;
+ }
+ /* 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,
+ (bfd_vma) offsetof (struct proc_info,
+ hw_regs),
+ 2))
+ goto fail;
+ }
+ core_signal (abfd) = proc_info.sig;
+ if (bfd_seek (abfd, (file_ptr) 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,
+ (bfd_vma) core_header.addr, 2))
+ goto fail;
+
+ bfd_seek (abfd, (file_ptr) 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:
+ goto fail; /*unrecognized core file type */
+ }
+ }
+
+ /* OK, we believe you. You're a core file (sure, sure). */
+
+ /* On HP/UX, we sometimes encounter core files where none of the threads
+ was found to be the running thread (ie the signal was set to -1 for
+ all threads). This happens when the program was aborted externally
+ via a TT_CORE ttrace system call. In that case, we just pick one
+ thread at random to be the active thread. */
+ if (core_kernel_thread_id (abfd) != 0
+ && bfd_get_section_by_name (abfd, ".reg") == NULL)
+ {
+ asection *asect = bfd_sections_find_if (abfd, thread_section_p, NULL);
+ asection *reg_sect;
+
+ if (asect != NULL)
+ {
+ reg_sect = make_bfd_asection (abfd, ".reg", asect->flags,
+ asect->size, asect->vma,
+ asect->alignment_power);
+ if (reg_sect == NULL)
+ goto fail;
+
+ reg_sect->filepos = asect->filepos;
+ }
+ }
+
+ /* 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;
+
+ fail:
+ bfd_release (abfd, core_hdr (abfd));
+ core_hdr (abfd) = NULL;
+ bfd_section_list_clear (abfd);
+ return NULL;
+}
+
+static char *
+hpux_core_core_file_failing_command (bfd *abfd)
+{
+ return core_command (abfd);
+}
+
+static int
+hpux_core_core_file_failing_signal (bfd *abfd)
+{
+ return core_signal (abfd);
+}
+
+
+/* If somebody calls any byte-swapping routines, shoot them. */
+static void
+swap_abort (void)
+{
+ abort(); /* This way doesn't require any declaration for ANSI to fuck up */
+}
+
+#define NO_GET ((bfd_vma (*) (const void *)) swap_abort)
+#define NO_PUT ((void (*) (bfd_vma, void *)) swap_abort)
+#define NO_GETS ((bfd_signed_vma (*) (const void *)) swap_abort)
+#define NO_GET64 ((bfd_uint64_t (*) (const void *)) swap_abort)
+#define NO_PUT64 ((void (*) (bfd_uint64_t, void *)) swap_abort)
+#define NO_GETS64 ((bfd_int64_t (*) (const void *)) swap_abort)
+
+const bfd_target core_hpux_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 */
+ 0, /* match priority. */
+ NO_GET64, NO_GETS64, NO_PUT64, /* 64 bit data */
+ NO_GET, NO_GETS, NO_PUT, /* 32 bit data */
+ NO_GET, NO_GETS, NO_PUT, /* 16 bit data */
+ NO_GET64, NO_GETS64, NO_PUT64, /* 64 bit hdrs */
+ NO_GET, NO_GETS, NO_PUT, /* 32 bit hdrs */
+ NO_GET, NO_GETS, 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 (_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),
+
+ NULL,
+
+ NULL /* backend_data */
+ };
diff --git a/bfd/i386aout.c b/bfd/i386aout.c
new file mode 100644
index 0000000..4b5a83d
--- /dev/null
+++ b/bfd/i386aout.c
@@ -0,0 +1,88 @@
+/* BFD back-end for i386 a.out binaries.
+ Copyright (C) 1990-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, 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 N_TXTOFF(x) 0x20
+#define N_TXTADDR(x) (N_MAGIC (x) == ZMAGIC ? 0x1020 : 0)
+#define N_TXTSIZE(x) ((x).a_text)
+#define TARGET_PAGE_SIZE 4096
+#define SEGMENT_SIZE 0x400000
+#define DEFAULT_ARCH bfd_arch_i386
+
+/* Do not "beautify" the CONCAT* macro args. Traditional C will not
+ remove whitespace added here, and thus will fail to concatenate
+ the tokens. */
+#define MY(OP) CONCAT2 (i386_aout_,OP)
+#define TARGETNAME "a.out-i386"
+#define NO_WRITE_HEADER_KLUDGE 1
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+#include "aout/aout64.h"
+#include "libaout.h"
+
+/* Set the machine type correctly. */
+
+static bfd_boolean
+i386aout_write_object_contents (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
+#define MY_backend_data & MY (backend_data)
+
+static const struct aout_backend_data MY (backend_data);
+
+#include "aout-target.h"
+
+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. */
+};
diff --git a/bfd/i386bsd.c b/bfd/i386bsd.c
new file mode 100644
index 0000000..d1ed35b
--- /dev/null
+++ b/bfd/i386bsd.c
@@ -0,0 +1,50 @@
+/* BFD back-end for i386 a.out binaries under BSD.
+ Copyright (C) 1990-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, 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 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)
+
+/* Do not "beautify" the CONCAT* macro args. Traditional C will not
+ remove whitespace added here, and thus will fail to concatenate
+ the tokens. */
+#define MY(OP) CONCAT2 (i386_aout_bsd_,OP)
+#define TARGETNAME "a.out-i386-bsd"
+
+#include "sysdep.h"
+#include "bfd.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 0000000..d9a4182
--- /dev/null
+++ b/bfd/i386dynix.c
@@ -0,0 +1,82 @@
+/* BFD back-end for i386 a.out binaries under dynix.
+ Copyright (C) 1994-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+
+/* This BFD is currently only tested with gdb, writing object files
+ may not work. */
+
+#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)
+
+/* Do not "beautify" the CONCAT* macro args. Traditional C will not
+ remove whitespace added here, and thus will fail to concatenate
+ the tokens. */
+#define MY(OP) CONCAT2 (i386_aout_dynix_,OP)
+#define TARGETNAME "a.out-i386-dynix"
+#define NAME(x,y) CONCAT3 (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 (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 = 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 0000000..7c5ed90
--- /dev/null
+++ b/bfd/i386freebsd.c
@@ -0,0 +1,38 @@
+/* BFD back-end for FreeBSD/386 a.out-ish binaries.
+ Copyright (C) 1990-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, 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)
+
+/* Do not "beautify" the CONCAT* macro args. Traditional C will not
+ remove whitespace added here, and thus will fail to concatenate
+ the tokens. */
+#define MY(OP) CONCAT2 (i386_aout_fbsd_,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 0000000..461a7a5
--- /dev/null
+++ b/bfd/i386linux.c
@@ -0,0 +1,733 @@
+/* BFD back-end for linux flavored i386 a.out binaries.
+ Copyright (C) 1992-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#define TARGET_PAGE_SIZE 4096
+#define ZMAGIC_DISK_BLOCK_SIZE 1024
+#define SEGMENT_SIZE TARGET_PAGE_SIZE
+#define TEXT_START_ADDR 0x0
+
+#define MACHTYPE_OK(mtype) ((mtype) == M_386 || (mtype) == M_UNKNOWN)
+
+#include "sysdep.h"
+#include "bfd.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
+
+/* Do not "beautify" the CONCAT* macro args. Traditional C will not
+ remove whitespace added here, and thus will fail to concatenate
+ the tokens. */
+#define MY(OP) CONCAT2 (i386_aout_linux_,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
+ (bfd *, file_ptr *, file_ptr *, file_ptr *);
+static bfd_boolean i386linux_bfd_final_link
+ (bfd *, struct bfd_link_info *);
+static bfd_boolean i386linux_write_object_contents (bfd *);
+
+static bfd_boolean
+i386linux_bfd_final_link (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 bfd_boolean
+i386linux_write_object_contents (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) (CONST_STRNEQ (name, GOT_REF_PREFIX))
+
+/* 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) (CONST_STRNEQ (name, PLT_REF_PREFIX))
+
+/* 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 dynamically
+ 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;
+};
+
+/* Routine to create an entry in an Linux link hash table. */
+
+static struct bfd_hash_entry *
+linux_link_hash_newfunc (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 (bfd *abfd)
+{
+ struct linux_link_hash_table *ret;
+ bfd_size_type amt = sizeof (struct linux_link_hash_table);
+
+ ret = (struct linux_link_hash_table *) bfd_zmalloc (amt);
+ 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,
+ sizeof (struct linux_link_hash_entry)))
+ {
+ free (ret);
+ return (struct bfd_link_hash_table *) 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, \
+ (bfd_boolean (*) (struct aout_link_hash_entry *, void *)) (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 (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 bfd_boolean
+linux_link_create_dynamic_sections (bfd *abfd,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED)
+{
+ flagword flags;
+ 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_with_flags (abfd, ".linux-dynamic", flags);
+ if (s == NULL
+ || ! bfd_set_section_alignment (abfd, s, 2))
+ return FALSE;
+ s->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 bfd_boolean
+linux_add_one_symbol (struct bfd_link_info *info,
+ bfd *abfd,
+ const char *name,
+ flagword flags,
+ asection *section,
+ bfd_vma value,
+ const char *string,
+ bfd_boolean copy,
+ bfd_boolean collect,
+ struct bfd_link_hash_entry **hashp)
+{
+ struct linux_link_hash_entry *h;
+ bfd_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->output_bfd->xvec? We may
+ want to be able to link Linux a.out and ELF objects together,
+ but serious confusion is possible. */
+
+ insert = FALSE;
+
+ if (! info->relocatable
+ && linux_hash_table (info)->dynobj == NULL
+ && strcmp (name, SHARABLE_CONFLICTS) == 0
+ && (flags & BSF_CONSTRUCTOR) != 0
+ && abfd->xvec == info->output_bfd->xvec)
+ {
+ 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->output_bfd->xvec)
+ {
+ 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, (bfd_vma) 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 bfd_boolean
+linux_tally_symbols (struct linux_link_hash_entry *h, void * 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;
+ bfd_boolean exists;
+
+ if (h->root.root.type == bfd_link_hash_undefined
+ && CONST_STRNEQ (h->root.root.root.string, NEEDS_SHRLIB))
+ {
+ 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 ((bfd_size_type) 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. */
+
+bfd_boolean
+bfd_i386linux_size_dynamic_sections (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,
+ 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->size = linux_hash_table (info)->fixup_count + 1;
+ s->size *= 8;
+ s->contents = (bfd_byte *) bfd_zalloc (output_bfd, s->size);
+ if (s->contents == NULL)
+ return FALSE;
+ }
+
+ 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 bfd_boolean
+linux_finish_dynamic_link (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,
+ (bfd_vma) 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, (bfd_vma) 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, (bfd_vma) 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, (bfd_vma) 0, fixup_table);
+ fixup_table += 4;
+ bfd_put_32 (output_bfd, (bfd_vma) 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, (bfd_vma) 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, (bfd_vma) 0, fixup_table);
+ fixup_table += 4;
+ bfd_put_32 (output_bfd, (bfd_vma) 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, (bfd_vma) new_addr, fixup_table);
+ }
+ else
+ bfd_put_32 (output_bfd, (bfd_vma) 0, fixup_table);
+
+ if (bfd_seek (output_bfd, (file_ptr) (os->filepos + s->output_offset),
+ SEEK_SET) != 0)
+ return FALSE;
+
+ if (bfd_bwrite (s->contents, s->size, output_bfd) != s->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 0000000..9c1b9f2
--- /dev/null
+++ b/bfd/i386lynx.c
@@ -0,0 +1,550 @@
+/* BFD back-end for i386 a.out binaries under LynxOS.
+ Copyright (C) 1990-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#define TEXT_START_ADDR 0
+#define TARGET_PAGE_SIZE 4096
+#define SEGMENT_SIZE TARGET_PAGE_SIZE
+#define DEFAULT_ARCH bfd_arch_i386
+
+/* Do not "beautify" the CONCAT* macro args. Traditional C will not
+ remove whitespace added here, and thus will fail to concatenate
+ the tokens. */
+#define MY(OP) CONCAT2 (i386_aout_lynx_,OP)
+#define TARGETNAME "a.out-i386-lynx"
+
+#include "sysdep.h"
+#include "bfd.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 \
+ || bfd_bwrite (&exec_bytes, (bfd_size_type) 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 ();
+bfd_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. */
+
+static void
+NAME(lynx,swap_std_reloc_out) (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? */
+ /* r_baserel, r_jmptable, r_relative??? FIXME-soon */
+ r_baserel = 0;
+ r_jmptable = 0;
+ r_relative = 0;
+
+ /* 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. */
+
+static void
+NAME(lynx,swap_ext_reloc_out) (bfd *abfd,
+ arelent *g,
+ 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; \
+ } \
+ } \
+
+static void
+NAME(lynx,swap_ext_reloc_in) (bfd *abfd,
+ struct reloc_ext_external *bytes,
+ arelent *cache_ptr,
+ asymbol **symbols,
+ bfd_size_type symcount ATTRIBUTE_UNUSED)
+{
+ 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));
+}
+
+static void
+NAME(lynx,swap_std_reloc_in) (bfd *abfd,
+ struct reloc_std_external *bytes,
+ arelent *cache_ptr,
+ asymbol **symbols,
+ bfd_size_type symcount ATTRIBUTE_UNUSED)
+{
+ int r_index;
+ int r_extern;
+ unsigned int r_length;
+ int r_pcrel;
+ struct aoutdata *su = &(abfd->tdata.aout_data->a);
+
+ cache_ptr->address = 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_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 */
+
+static bfd_boolean
+NAME(lynx,slurp_reloc_table) (bfd *abfd,
+ sec_ptr asect,
+ asymbol **symbols)
+{
+ bfd_size_type count;
+ bfd_size_type reloc_size;
+ void * 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_zmalloc (count * sizeof (arelent));
+ if (!reloc_cache && count != 0)
+ return FALSE;
+
+ relocs = bfd_alloc (abfd, reloc_size);
+ if (!relocs && reloc_size != 0)
+ {
+ free (reloc_cache);
+ return FALSE;
+ }
+
+ if (bfd_bread (relocs, reloc_size, abfd) != reloc_size)
+ {
+ bfd_release (abfd, relocs);
+ free (reloc_cache);
+ return FALSE;
+ }
+
+ if (each_size == RELOC_EXT_SIZE)
+ {
+ 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_size_type) bfd_get_symcount (abfd));
+ }
+ }
+ else
+ {
+ 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_size_type) 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. */
+
+static bfd_boolean
+NAME(lynx,squirt_out_relocs) (bfd *abfd, asection *section)
+{
+ arelent **generic;
+ unsigned char *native, *natptr;
+ size_t each_size;
+ unsigned int count = section->reloc_count;
+ bfd_size_type natsize;
+
+ if (count == 0)
+ return TRUE;
+
+ each_size = obj_reloc_entry_size (abfd);
+ natsize = count;
+ natsize *= each_size;
+ 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_bwrite (native, 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 */
+static long
+NAME(lynx,canonicalize_reloc) (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 0000000..233041a
--- /dev/null
+++ b/bfd/i386mach3.c
@@ -0,0 +1,73 @@
+/* BFD back-end for i386 a.out binaries.
+ Copyright (C) 1990-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, 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
+/* 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 "sysdep.h"
+#include "bfd.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
+
+/* Do not "beautify" the CONCAT* macro args. Traditional C will not
+ remove whitespace added here, and thus will fail to concatenate
+ the tokens. */
+#define MY(OP) CONCAT2 (i386_aout_mach3_,OP)
+#define TARGETNAME "a.out-mach3"
+
+static bfd_boolean MY (set_sizes) (bfd *);
+#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 0000000..f02659f
--- /dev/null
+++ b/bfd/i386msdos.c
@@ -0,0 +1,233 @@
+/* BFD back-end for MS-DOS executables.
+ Copyright (C) 1990-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+#include "libaout.h"
+
+#define EXE_MAGIC 0x5a4d
+#define EXE_LOAD_HIGH 0x0000
+#define EXE_LOAD_LOW 0xffff
+#define EXE_PAGE_SIZE 512
+
+static int
+msdos_sizeof_headers (bfd *abfd ATTRIBUTE_UNUSED,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+static bfd_boolean
+msdos_write_object_contents (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 (sec->size == 0)
+ continue;
+ if (bfd_get_section_flags (abfd, sec) & SEC_ALLOC)
+ {
+ bfd_vma sec_vma = bfd_get_section_vma (abfd, sec) + sec->size;
+ 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)
+ + sec->size);
+ 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. */
+ H_PUT_16 (abfd, EXE_MAGIC, &hdr[0]);
+ H_PUT_16 (abfd, EXE_PAGE_SIZE / 16, &hdr[8]);
+ H_PUT_16 (abfd, EXE_LOAD_LOW, &hdr[12]);
+ H_PUT_16 (abfd, 0x3e, &hdr[24]);
+ H_PUT_16 (abfd, 0x0001, &hdr[28]); /* XXX??? */
+ H_PUT_16 (abfd, 0x30fb, &hdr[30]); /* XXX??? */
+ H_PUT_16 (abfd, 0x726a, &hdr[32]); /* XXX??? */
+
+ /* Bytes in last page (0 = full page). */
+ H_PUT_16 (abfd, outfile_size & (EXE_PAGE_SIZE - 1), &hdr[2]);
+
+ /* Number of pages. */
+ 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. */
+ H_PUT_16 (abfd, high_vma, &hdr[16]);
+
+ if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0
+ || bfd_bwrite (hdr, (bfd_size_type) sizeof(hdr), abfd) != sizeof(hdr))
+ return FALSE;
+
+ return TRUE;
+}
+
+static bfd_boolean
+msdos_set_section_contents (bfd *abfd,
+ sec_ptr section,
+ const void *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, section->filepos + offset, SEEK_SET) != 0
+ || bfd_bwrite (location, 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_bfd_reloc_name_lookup aout_32_reloc_name_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_lookup_section_flags bfd_generic_lookup_section_flags
+#define msdos_bfd_merge_sections bfd_generic_merge_sections
+#define msdos_bfd_is_group_section bfd_generic_is_group_section
+#define msdos_bfd_discard_group bfd_generic_discard_group
+#define msdos_section_already_linked \
+ _bfd_generic_section_already_linked
+#define msdos_bfd_define_common_symbol bfd_generic_define_common_symbol
+#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_link_just_syms _bfd_generic_link_just_syms
+#define msdos_bfd_copy_link_hash_symbol_type \
+ _bfd_generic_copy_link_hash_symbol_type
+#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_canonicalize_symtab _bfd_nosymbols_canonicalize_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_find_line _bfd_nosymbols_find_line
+#define msdos_find_inliner_info _bfd_nosymbols_find_inliner_info
+#define msdos_get_lineno _bfd_nosymbols_get_lineno
+#define msdos_bfd_is_target_special_symbol ((bfd_boolean (*) (bfd *, asymbol *)) bfd_false)
+#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 i386_msdos_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 */
+ 0, /* match priority. */
+ 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),
+
+ NULL,
+
+ NULL
+ };
+
+
diff --git a/bfd/i386netbsd.c b/bfd/i386netbsd.c
new file mode 100644
index 0000000..5e4d130
--- /dev/null
+++ b/bfd/i386netbsd.c
@@ -0,0 +1,38 @@
+/* BFD back-end for NetBSD/386 a.out-ish binaries.
+ Copyright (C) 1990-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, 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
+
+/* Do not "beautify" the CONCAT* macro args. Traditional C will not
+ remove whitespace added here, and thus will fail to concatenate
+ the tokens. */
+#define MY(OP) CONCAT2 (i386_aout_nbsd_,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 0000000..d8d5408
--- /dev/null
+++ b/bfd/i386os9k.c
@@ -0,0 +1,224 @@
+/* BFD back-end for os9000 i386 binaries.
+ Copyright (C) 1990-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+#include "bfdlink.h"
+#include "libaout.h" /* BFD a.out internal data structures */
+#include "os9k.h"
+
+/* Swaps the information in an executable header taken from a raw byte
+ stream memory image, into the internal exec_header structure. */
+static bfd_boolean
+os9k_swap_exec_header_in (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 = H_GET_16 (abfd, bytes->m_sync);
+ execp->a_syms = 0;
+ execp->a_entry = H_GET_32 (abfd, bytes->m_exec);
+ execp->a_talign = 2;
+ execp->a_dalign = 2;
+ execp->a_balign = 2;
+
+ dload = H_GET_32 (abfd, bytes->m_idata);
+ execp->a_data = dload + 8;
+
+ if (bfd_seek (abfd, (file_ptr) dload, SEEK_SET) != 0
+ || (bfd_bread (&dmemstart, (bfd_size_type) sizeof (dmemstart), abfd)
+ != sizeof (dmemstart))
+ || (bfd_bread (&dmemsize, (bfd_size_type) sizeof (dmemsize), abfd)
+ != sizeof (dmemsize)))
+ return FALSE;
+
+ execp->a_tload = 0;
+ execp->a_dload = H_GET_32 (abfd, (unsigned char *) &dmemstart);
+ execp->a_text = dload - execp->a_tload;
+ execp->a_data = H_GET_32 (abfd, (unsigned char *) &dmemsize);
+ execp->a_bss = H_GET_32 (abfd, bytes->m_data) - execp->a_data;
+
+ execp->a_trsize = 0;
+ execp->a_drsize = 0;
+
+ return TRUE;
+}
+
+
+/* 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 (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)->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;
+}
+
+static const bfd_target *
+os9k_object_p (bfd *abfd)
+{
+ struct internal_exec anexec;
+ mh_com exec_bytes;
+
+ if (bfd_bread (&exec_bytes, (bfd_size_type) MHCOM_BYTES_SIZE, abfd)
+ != MHCOM_BYTES_SIZE)
+ {
+ if (bfd_get_error () != bfd_error_system_call)
+ bfd_set_error (bfd_error_wrong_format);
+ return 0;
+ }
+
+ anexec.a_info = 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);
+}
+
+static int
+os9k_sizeof_headers (bfd *abfd ATTRIBUTE_UNUSED,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED)
+{
+ return sizeof (struct internal_exec);
+}
+
+
+
+#define aout_32_close_and_cleanup aout_32_bfd_free_cached_info
+
+#define aout_32_find_line _bfd_nosymbols_find_line
+#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_bfd_reloc_name_lookup _bfd_norelocs_bfd_reloc_name_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_lookup_section_flags bfd_generic_lookup_section_flags
+#define os9k_bfd_merge_sections bfd_generic_merge_sections
+#define os9k_bfd_is_group_section bfd_generic_is_group_section
+#define os9k_bfd_discard_group bfd_generic_discard_group
+#define os9k_section_already_linked \
+ _bfd_generic_section_already_linked
+#define os9k_bfd_define_common_symbol bfd_generic_define_common_symbol
+#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_link_just_syms _bfd_generic_link_just_syms
+#define os9k_bfd_copy_link_hash_symbol_type \
+ _bfd_generic_copy_link_hash_symbol_type
+#define os9k_bfd_final_link _bfd_generic_final_link
+#define os9k_bfd_link_split_section _bfd_generic_link_split_section
+
+const bfd_target i386_aout_os9k_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 */
+ 0, /* match priority. */
+
+ 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),
+
+ NULL,
+
+ NULL,
+ };
diff --git a/bfd/ieee.c b/bfd/ieee.c
new file mode 100644
index 0000000..313834e
--- /dev/null
+++ b/bfd/ieee.c
@@ -0,0 +1,3854 @@
+/* BFD back-end for ieee-695 objects.
+ Copyright (C) 1990-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, 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 "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+#include "ieee.h"
+#include "libieee.h"
+#include "safe-ctype.h"
+#include "libiberty.h"
+
+struct output_buffer_struct
+{
+ unsigned char *ptrp;
+ int buffer;
+};
+
+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 block (void);
+
+/* Functions for writing to ieee files in the strange way that the
+ standard requires. */
+
+static bfd_boolean
+ieee_write_byte (bfd *abfd, int barg)
+{
+ bfd_byte byte;
+
+ byte = barg;
+ if (bfd_bwrite ((void *) &byte, (bfd_size_type) 1, abfd) != 1)
+ return FALSE;
+ return TRUE;
+}
+
+static bfd_boolean
+ieee_write_2bytes (bfd *abfd, int bytes)
+{
+ bfd_byte buffer[2];
+
+ buffer[0] = bytes >> 8;
+ buffer[1] = bytes & 0xff;
+ if (bfd_bwrite ((void *) buffer, (bfd_size_type) 2, abfd) != 2)
+ return FALSE;
+ return TRUE;
+}
+
+static bfd_boolean
+ieee_write_int (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 bfd_boolean
+ieee_write_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_bwrite ((void *) id, (bfd_size_type) 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 (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 (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 (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, (bfd_size_type) length + 1);
+ if (!string)
+ return NULL;
+ bfd_get_string (ieee, string, length);
+ string[length] = 0;
+ return string;
+}
+
+static bfd_boolean
+ieee_write_expression (bfd *abfd,
+ bfd_vma value,
+ asymbol *symbol,
+ bfd_boolean pcrel,
+ unsigned int sindex)
+{
+ unsigned int term_count = 0;
+
+ if (value != 0)
+ {
+ if (! ieee_write_int (abfd, value))
+ return FALSE;
+ term_count++;
+ }
+
+ /* Badly formatted binaries can have a missing symbol,
+ so test here to prevent a seg fault. */
+ if (symbol != NULL)
+ {
+ 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) (sindex + 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, (bfd_vma) 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 (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 bfd_boolean
+ieee_write_int5_out (bfd *abfd, bfd_vma value)
+{
+ bfd_byte b[5];
+
+ ieee_write_int5 (b, value);
+ if (bfd_bwrite ((void *) b, (bfd_size_type) 5, abfd) != 5)
+ return FALSE;
+ return TRUE;
+}
+
+static bfd_boolean
+parse_int (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 (common_header_type *ieee, bfd_boolean *ok)
+{
+ bfd_vma x = 0;
+ *ok = parse_int (ieee, &x);
+ return x;
+}
+
+static bfd_vma
+must_parse_int (common_header_type *ieee)
+{
+ bfd_vma result = 0;
+ BFD_ASSERT (parse_int (ieee, &result));
+ 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_data_type *ieee,
+ bfd_vma *value,
+ ieee_symbol_index_type *symbol,
+ bfd_boolean *pcrel,
+ unsigned int *extra,
+ asection **section)
+
+{
+ bfd_boolean loop = TRUE;
+ ieee_value_type stack[10];
+ ieee_value_type *sp = stack;
+ asection *dummy;
+
+#define POS sp[1]
+#define TOS sp[0]
+#define NOS sp[-1]
+#define INC sp++;
+#define DEC sp--;
+
+ /* 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;
+
+ while (loop && ieee->h.input_p < ieee->h.last_byte)
+ {
+ 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));
+ (void) section_n;
+ 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))]->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. */
+ loop = FALSE;
+ }
+ }
+ }
+
+ /* 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);
+ (void) section1;
+ (void) sy1;
+ }
+
+ POP (*symbol, dummy, *value);
+ if (section)
+ *section = dummy;
+}
+
+
+#define ieee_seek(ieee, offset) \
+ do \
+ { \
+ ieee->h.input_p = ieee->h.first_byte + offset; \
+ ieee->h.last_byte = (ieee->h.first_byte \
+ + ieee_part_after (ieee, offset)); \
+ } \
+ while (0)
+
+#define ieee_pos(ieee) \
+ (ieee->h.input_p - ieee->h.first_byte)
+
+/* Find the first part of the ieee file after HERE. */
+
+static file_ptr
+ieee_part_after (ieee_data_type *ieee, file_ptr here)
+{
+ int part;
+ file_ptr after = ieee->w.r.me_record;
+
+ /* File parts can come in any order, except that module end is
+ guaranteed to be last (and the header first). */
+ for (part = 0; part < N_W_VARIABLES; part++)
+ if (ieee->w.offset[part] > here && after > ieee->w.offset[part])
+ after = ieee->w.offset[part];
+
+ return after;
+}
+
+static unsigned int last_index;
+static char last_type; /* Is the index for an X or a D. */
+
+static ieee_symbol_type *
+get_symbol (bfd *abfd ATTRIBUTE_UNUSED,
+ ieee_data_type *ieee,
+ ieee_symbol_type *last_symbol,
+ unsigned int *symbol_count,
+ ieee_symbol_type ***pptr,
+ unsigned int *max_index,
+ int 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;
+ bfd_size_type amt = sizeof (ieee_symbol_type);
+
+ new_symbol = bfd_alloc (ieee->h.abfd, amt);
+ 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 bfd_boolean
+ieee_slurp_external_symbols (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 = NULL;
+ unsigned int symbol_count = 0;
+ bfd_boolean loop = TRUE;
+
+ last_index = 0xffffff;
+ ieee->symbol_table_full = TRUE;
+
+ ieee_seek (ieee, 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 = 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 = 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 = 0;
+
+ switch (read_2bytes (&ieee->h))
+ {
+ case ieee_attribute_record_enum:
+ symbol_name_index = must_parse_int (&(ieee->h));
+ symbol_type_index = must_parse_int (&(ieee->h));
+ (void) symbol_type_index;
+ 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)
+ (_("%B: unimplemented ATI record %u for symbol %u"),
+ 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)
+ (_("%B: unexpected ATN type %d in external part"),
+ 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->h))
+ {
+ case ieee_asn_record_enum:
+ parse_int (&ieee->h, &val1);
+ parse_int (&ieee->h, &val1);
+ break;
+
+ default:
+ (*_bfd_error_handler)
+ (_("%B: unexpected type after ATN"), 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;
+ bfd_boolean pcrel_ignore;
+ unsigned int extra;
+
+ next_byte (&(ieee->h));
+ next_byte (&(ieee->h));
+
+ symbol_name_index = must_parse_int (&(ieee->h));
+ (void) symbol_name_index;
+ 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->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 default value if available. */
+ if (! parse_int (&(ieee->h), &value))
+ 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 = 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 = NULL;
+ *prev_reference_ptr = NULL;
+
+ return TRUE;
+}
+
+static bfd_boolean
+ieee_slurp_symbol_table (bfd *abfd)
+{
+ if (! IEEE_DATA (abfd)->read_symbols)
+ {
+ if (! ieee_slurp_external_symbols (abfd))
+ return FALSE;
+ IEEE_DATA (abfd)->read_symbols = TRUE;
+ }
+ return TRUE;
+}
+
+static long
+ieee_get_symtab_upper_bound (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;
+
+static long
+ieee_canonicalize_symtab (bfd *abfd, asymbol **location)
+{
+ ieee_symbol_type *symp;
+ static bfd dummy_bfd;
+ static asymbol empty_symbol =
+ {
+ &dummy_bfd,
+ " ieee empty",
+ (symvalue) 0,
+ BSF_DEBUGGING,
+ bfd_abs_section_ptr
+#ifdef __STDC__
+ /* K&R compilers can't initialise unions. */
+ , { 0 }
+#endif
+ };
+
+ 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)
+ {
+ /* 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 (bfd *abfd, ieee_data_type *ieee, unsigned int sindex)
+{
+ if (sindex >= ieee->section_table_size)
+ {
+ unsigned int c, i;
+ asection **n;
+ bfd_size_type amt;
+
+ c = ieee->section_table_size;
+ if (c == 0)
+ c = 20;
+ while (c <= sindex)
+ c *= 2;
+
+ amt = c;
+ amt *= sizeof (asection *);
+ n = bfd_realloc (ieee->section_table, amt);
+ 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[sindex] == (asection *) NULL)
+ {
+ char *tmp = bfd_alloc (abfd, (bfd_size_type) 11);
+ asection *section;
+
+ if (!tmp)
+ return NULL;
+ sprintf (tmp, " fsec%4d", sindex);
+ section = bfd_make_section (abfd, tmp);
+ ieee->section_table[sindex] = section;
+ section->target_index = sindex;
+ ieee->section_table[sindex] = section;
+ }
+ return ieee->section_table[sindex];
+}
+
+static void
+ieee_slurp_sections (bfd *abfd)
+{
+ ieee_data_type *ieee = IEEE_DATA (abfd);
+ file_ptr offset = ieee->w.r.section_part;
+ char *name;
+
+ if (offset != 0)
+ {
+ bfd_byte section_type[3];
+
+ ieee_seek (ieee, offset);
+ while (TRUE)
+ {
+ switch (this_byte (&(ieee->h)))
+ {
+ case ieee_section_type_enum:
+ {
+ asection *section;
+ 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])
+ {
+ /* AS Absolute section attributes. */
+ case 0xD3:
+ 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;
+
+ /* Named relocatable sections (type C). */
+ case 0xC3:
+ 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:
+ {
+ asection *section;
+ ieee_record_enum_type t;
+
+ 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->size = must_parse_int (&(ieee->h));
+ break;
+ case ieee_physical_region_size_enum:
+ section = ieee->section_table[must_parse_int (&(ieee->h))];
+ section->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 bfd_boolean
+ieee_slurp_debug (bfd *abfd)
+{
+ ieee_data_type *ieee = IEEE_DATA (abfd);
+ asection *sec;
+ file_ptr debug_end;
+ flagword flags;
+
+ if (ieee->w.r.debug_information_part == 0)
+ return TRUE;
+
+ flags = SEC_DEBUGGING | SEC_HAS_CONTENTS;
+ sec = bfd_make_section_with_flags (abfd, ".debug", flags);
+ if (sec == NULL)
+ return FALSE;
+ sec->filepos = ieee->w.r.debug_information_part;
+
+ debug_end = ieee_part_after (ieee, ieee->w.r.debug_information_part);
+ sec->size = debug_end - ieee->w.r.debug_information_part;
+
+ return TRUE;
+}
+
+/* Archive stuff. */
+
+static const bfd_target *
+ieee_archive_p (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;
+ bfd_size_type alc_elts;
+ ieee_ar_obstack_type *elts = NULL;
+ bfd_size_type amt = sizeof (ieee_ar_data_type);
+
+ abfd->tdata.ieee_ar_data = bfd_alloc (abfd, amt);
+ if (!abfd->tdata.ieee_ar_data)
+ goto error_ret_restore;
+ ieee = IEEE_AR_DATA (abfd);
+
+ /* Ignore the return value here. It doesn't matter if we don't read
+ the entire buffer. We might have a very small ieee file. */
+ if (bfd_bread ((void *) buffer, (bfd_size_type) sizeof (buffer), abfd) <= 0)
+ goto got_wrong_format_error;
+
+ ieee->h.first_byte = buffer;
+ ieee->h.input_p = buffer;
+
+ ieee->h.abfd = abfd;
+
+ if (this_byte (&(ieee->h)) != Module_Beginning)
+ goto got_wrong_format_error;
+
+ next_byte (&(ieee->h));
+ library = read_id (&(ieee->h));
+ if (strcmp (library, "LIBRARY") != 0)
+ goto got_wrong_format_error;
+
+ /* 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 = 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 = 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 (IEEE_DATA (abfd)) > sizeof (buffer) / 2)
+ {
+ /* Past half way, reseek and reprime. */
+ buffer_offset += ieee_pos (IEEE_DATA (abfd));
+ if (bfd_seek (abfd, buffer_offset, SEEK_SET) != 0)
+ goto error_return;
+
+ /* Again ignore return value of bfd_bread. */
+ bfd_bread ((void *) buffer, (bfd_size_type) sizeof (buffer), abfd);
+ ieee->h.first_byte = buffer;
+ ieee->h.input_p = buffer;
+ }
+ }
+
+ amt = ieee->element_count;
+ amt *= sizeof *ieee->elements;
+ ieee->elements = bfd_alloc (abfd, amt);
+ if (ieee->elements == NULL)
+ goto error_return;
+
+ memcpy (ieee->elements, elts, (size_t) amt);
+ 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;
+
+ /* Again ignore return value of bfd_bread. */
+ bfd_bread ((void *) buffer, (bfd_size_type) 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;
+
+ got_wrong_format_error:
+ bfd_set_error (bfd_error_wrong_format);
+ error_return:
+ if (elts != NULL)
+ free (elts);
+ bfd_release (abfd, ieee);
+ error_ret_restore:
+ abfd->tdata.ieee_ar_data = save;
+
+ return NULL;
+}
+
+static bfd_boolean
+ieee_mkobject (bfd *abfd)
+{
+ bfd_size_type amt;
+
+ output_ptr_start = NULL;
+ output_ptr = NULL;
+ output_ptr_end = NULL;
+ input_ptr_start = NULL;
+ input_ptr = NULL;
+ input_ptr_end = NULL;
+ input_bfd = NULL;
+ output_bfd = NULL;
+ output_buffer = 0;
+ amt = sizeof (ieee_data_type);
+ abfd->tdata.ieee_data = bfd_zalloc (abfd, amt);
+ return abfd->tdata.ieee_data != NULL;
+}
+
+static bfd_boolean
+do_one (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:
+ {
+ bfd_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;
+ bfd_boolean pcrel = FALSE;
+ asection *section;
+ ieee_reloc_type *r;
+
+ r = bfd_alloc (ieee->h.abfd, sizeof (* r));
+ 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)
+ {
+#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, (bfd_vma) 0, location_ptr +
+ current_map->pc);
+ r->relent.howto = &rel32_howto;
+#endif
+ }
+ else
+ {
+ bfd_put_32 (ieee->h.abfd, (bfd_vma) 0,
+ location_ptr + current_map->pc);
+ r->relent.howto = &abs32_howto;
+ }
+ current_map->pc += 4;
+ break;
+ case 2:
+ if (pcrel)
+ {
+#if KEEPMINUSPCININST
+ bfd_put_16 (ieee->h.abfd, (bfd_vma) -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, (bfd_vma) 0,
+ location_ptr + current_map->pc);
+ r->relent.howto = &rel16_howto;
+#endif
+ }
+
+ else
+ {
+ bfd_put_16 (ieee->h.abfd, (bfd_vma) 0,
+ location_ptr + current_map->pc);
+ r->relent.howto = &abs16_howto;
+ }
+ current_map->pc += 2;
+ break;
+ case 1:
+ if (pcrel)
+ {
+#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))
+ {
+ 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 bfd_boolean
+ieee_slurp_section_data (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 = NULL;
+ asection *s;
+
+ /* Seek to the start of the data area. */
+ if (ieee->read_data)
+ return TRUE;
+ ieee->read_data = TRUE;
+ ieee_seek (ieee, 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 (s);
+ arelent **relpp;
+
+ if ((s->flags & SEC_DEBUGGING) != 0)
+ continue;
+ per->data = bfd_alloc (ieee->h.abfd, s->size);
+ if (!per->data)
+ return FALSE;
+ relpp = &s->relocation;
+ per->reloc_tail_ptr = (ieee_reloc_type **) relpp;
+ }
+
+ 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 (s);
+ 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;
+ bfd_boolean pcrel;
+
+ next_byte (&(ieee->h));
+ must_parse_int (&(ieee->h)); /* Throw away section #. */
+ parse_expression (ieee, &value,
+ &symbol,
+ &pcrel, &extra,
+ 0);
+ current_map->pc = value;
+ BFD_ASSERT ((unsigned) (value - s->vma) <= s->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,
+ (int) 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;
+ }
+ }
+}
+
+static const bfd_target *
+ieee_object_p (bfd *abfd)
+{
+ char *processor;
+ unsigned int part;
+ ieee_data_type *ieee;
+ unsigned char buffer[300];
+ ieee_data_type *save = IEEE_DATA (abfd);
+ bfd_size_type amt;
+
+ 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. Ignore
+ bfd_bread return value; The file might be very small. */
+ if (bfd_bread ((void *) buffer, (bfd_size_type) sizeof (buffer), abfd) <= 0)
+ goto got_wrong_format;
+
+ 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 = xstrdup (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 identification
+ 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 ((CONST_STRNEQ (processor, "cpu32")) /* CPU32 and CPU32+ */
+ || (CONST_STRNEQ (processor, "CPU32")))
+ 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))
+ goto fail;
+
+ if (! parse_int (&(ieee->h), &ieee->ad.number_of_maus_in_address))
+ 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++)
+ {
+ bfd_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)
+ 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. */
+
+ amt = ieee->w.r.me_record + 1;
+ IEEE_DATA (abfd)->h.first_byte = bfd_alloc (ieee->h.abfd, amt);
+ 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_bread ((void *) (IEEE_DATA (abfd)->h.first_byte),
+ (bfd_size_type) 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:
+ bfd_release (abfd, ieee);
+ abfd->tdata.ieee_data = save;
+ return (const bfd_target *) NULL;
+}
+
+static void
+ieee_get_symbol_info (bfd *ignore_abfd ATTRIBUTE_UNUSED,
+ 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';
+}
+
+static void
+ieee_print_symbol (bfd *abfd,
+ void * 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:
+ 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 (abfd, (void *) file, symbol);
+
+ fprintf (file, " %-5s %04x %02x %s",
+ section_name,
+ (unsigned) ieee_symbol (symbol)->index,
+ (unsigned) 0,
+ symbol->name);
+ }
+ }
+ break;
+ }
+}
+
+static bfd_boolean
+ieee_new_section_hook (bfd *abfd, asection *newsect)
+{
+ if (!newsect->used_by_bfd)
+ {
+ newsect->used_by_bfd = bfd_alloc (abfd, sizeof (ieee_per_section_type));
+ if (!newsect->used_by_bfd)
+ return FALSE;
+ }
+ ieee_per_section (newsect)->data = NULL;
+ ieee_per_section (newsect)->section = newsect;
+ return _bfd_generic_new_section_hook (abfd, newsect);
+}
+
+static long
+ieee_get_reloc_upper_bound (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 bfd_boolean
+ieee_get_section_contents (bfd *abfd,
+ sec_ptr section,
+ void * location,
+ file_ptr offset,
+ bfd_size_type count)
+{
+ ieee_per_section_type *p = ieee_per_section (section);
+ if ((section->flags & SEC_DEBUGGING) != 0)
+ return _bfd_generic_get_section_contents (abfd, section, location,
+ offset, count);
+ ieee_slurp_section_data (abfd);
+ (void) memcpy ((void *) location, (void *) (p->data + offset), (unsigned) count);
+ return TRUE;
+}
+
+static long
+ieee_canonicalize_reloc (bfd *abfd,
+ sec_ptr section,
+ arelent **relptr,
+ asymbol **symbols)
+{
+ 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 = NULL;
+ return section->reloc_count;
+}
+
+static int
+comp (const void * ap, const void * bp)
+{
+ arelent *a = *((arelent **) ap);
+ arelent *b = *((arelent **) bp);
+ return a->address - b->address;
+}
+
+/* Write the section headers. */
+
+static bfd_boolean
+ieee_write_section_part (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;
+ /* 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, (bfd_vma) 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->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 bfd_boolean
+do_with_relocs (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, (bfd_vma) 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->size)
+ {
+ bfd_size_type run;
+ unsigned int MAXRUN = 127;
+
+ run = MAXRUN;
+ if (run > s->size - current_byte_index)
+ run = s->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_bwrite ((void *) (stream + current_byte_index), 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 (stream == NULL)
+ {
+ /* Outputting a section without data, fill it up. */
+ stream = bfd_zalloc (abfd, s->size);
+ if (!stream)
+ return FALSE;
+ }
+ while (current_byte_index < s->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->size - current_byte_index)
+ run = s->size - current_byte_index;
+
+ if (run != 0)
+ {
+ /* Output a stream of bytes. */
+ if (! ieee_write_int (abfd, run))
+ return FALSE;
+ if (bfd_bwrite ((void *) (stream + current_byte_index), 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;
+ 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;
+
+ if (r->sym_ptr_ptr != (asymbol **) NULL)
+ {
+ if (! ieee_write_expression (abfd, r->addend + ov,
+ *(r->sym_ptr_ptr),
+ r->howto->pc_relative,
+ (unsigned) s->index))
+ return FALSE;
+ }
+ else
+ {
+ if (! ieee_write_expression (abfd, r->addend + ov,
+ (asymbol *) NULL,
+ r->howto->pc_relative,
+ (unsigned) s->index))
+ return FALSE;
+ }
+
+ if (number_of_maus_in_address
+ != bfd_get_reloc_size (r->howto))
+ {
+ bfd_vma rsize = bfd_get_reloc_size (r->howto);
+ if (! ieee_write_int (abfd, rsize))
+ 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 bfd_boolean
+do_as_repeat (bfd *abfd, asection *s)
+{
+ if (s->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)))
+ return FALSE;
+
+ if ((abfd->flags & EXEC_P) != 0)
+ {
+ if (! ieee_write_int (abfd, s->lma))
+ return FALSE;
+ }
+ else
+ {
+ if (! ieee_write_expression (abfd, (bfd_vma) 0, s->symbol, 0, 0))
+ return FALSE;
+ }
+
+ if (! ieee_write_byte (abfd, ieee_repeat_data_enum)
+ || ! ieee_write_int (abfd, s->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 bfd_boolean
+do_without_relocs (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->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 void
+fill (void)
+{
+ bfd_size_type amt = input_ptr_end - input_ptr_start;
+ /* FIXME: Check return value. I'm not sure whether it needs to read
+ the entire buffer or not. */
+ bfd_bread ((void *) input_ptr_start, amt, input_bfd);
+ input_ptr = input_ptr_start;
+}
+
+static void
+flush (void)
+{
+ bfd_size_type amt = output_ptr - output_ptr_start;
+
+ if (bfd_bwrite ((void *) (output_ptr_start), amt, output_bfd) != amt)
+ 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 (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 (void)
+{
+ int length = THIS ();
+ char ch;
+
+ OUT (length);
+ NEXT ();
+ while (length--)
+ {
+ ch = THIS ();
+ OUT (ch);
+ NEXT ();
+ }
+}
+
+#define VAR(x) ((x | 0x80))
+static void
+copy_expression (void)
+{
+ int stack[10];
+ int *tos = stack;
+ int value;
+
+ 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 ();
+ break;
+ case 0xa5:
+ /* PLUS anything. */
+ 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];
+ value = 0;
+ if (s->output_section)
+ value = s->output_section->lma;
+ value += s->output_offset;
+ *tos++ = value;
+ }
+ 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. */
+
+static void
+fill_int (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 (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;
+ }
+ }
+ (void) ch;
+ OUT (0x84);
+ buf->ptrp = output_ptr;
+ buf->buffer = output_buffer;
+ OUT (0);
+ OUT (0);
+ OUT (0);
+ OUT (0);
+}
+
+static void
+copy_int (void)
+{
+ 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 ()
+#define INTn(q) copy_int ()
+#define EXPn(q) copy_expression ()
+
+static void
+copy_till_end (void)
+{
+ 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
+f1_record (void)
+{
+ 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 (void)
+{
+ /* Attribute record. */
+ NEXT ();
+ OUT (0xf0);
+ INTn (Symbol name);
+ ID;
+}
+
+static void
+f2_record (void)
+{
+ NEXT ();
+ OUT (0xf2);
+ INT;
+ NEXT ();
+ OUT (0xce);
+ INT;
+ copy_till_end ();
+}
+
+static void
+f8_record (void)
+{
+ 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 (void)
+{
+ OUT (0xe2);
+ NEXT ();
+ OUT (0xce);
+ NEXT ();
+ INT;
+ EXP;
+}
+
+static void
+block (void)
+{
+ 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;
+
+ }
+ }
+}
+
+/* Moves all the debug information from the source bfd to the output
+ bfd, and relocates any expressions it finds. */
+
+static void
+relocate_debug (bfd *output ATTRIBUTE_UNUSED,
+ 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_bread ((void *) input_ptr_start, (bfd_size_type) IBS, input);
+ block ();
+}
+
+/* Gather together all the debug information from each input BFD into
+ one place, relocating it and emitting it as we go. */
+
+static bfd_boolean
+ieee_write_debug_part (bfd *abfd)
+{
+ ieee_data_type *ieee = IEEE_DATA (abfd);
+ bfd_chain_type *chain = ieee->chain_root;
+ unsigned char obuff[OBS];
+ bfd_boolean some_debug = FALSE;
+ file_ptr here = bfd_tell (abfd);
+
+ output_ptr_start = output_ptr = obuff;
+ output_ptr_end = obuff + OBS;
+ output_ptr = obuff;
+ 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_bwrite (s->contents, s->size, abfd) != s->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 bfd_boolean
+ieee_write_data_part (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 bfd_boolean
+init_for_output (bfd *abfd)
+{
+ asection *s;
+
+ for (s = abfd->sections; s != (asection *) NULL; s = s->next)
+ {
+ if ((s->flags & SEC_DEBUGGING) != 0)
+ continue;
+ if (s->size != 0)
+ {
+ bfd_size_type size = s->size;
+ ieee_per_section (s)->data = bfd_alloc (abfd, 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. */
+
+static bfd_boolean
+ieee_set_section_contents (bfd *abfd,
+ sec_ptr section,
+ const void * location,
+ file_ptr offset,
+ bfd_size_type count)
+{
+ if ((section->flags & SEC_DEBUGGING) != 0)
+ {
+ if (section->contents == NULL)
+ {
+ bfd_size_type size = section->size;
+ section->contents = bfd_alloc (abfd, size);
+ if (section->contents == NULL)
+ return FALSE;
+ }
+ /* bfd_set_section_contents has already checked that everything
+ is within range. */
+ memcpy (section->contents + offset, location, (size_t) count);
+ return TRUE;
+ }
+
+ if (ieee_per_section (section)->data == (bfd_byte *) NULL)
+ {
+ if (!init_for_output (abfd))
+ return FALSE;
+ }
+ memcpy ((void *) (ieee_per_section (section)->data + offset),
+ (void *) 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 bfd_boolean
+ieee_write_external_part (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);
+ bfd_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, (bfd_vma) 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, (bfd_vma) reference_index)
+ || ! ieee_write_id (abfd, p->name)
+ || ! ieee_write_byte (abfd,
+ ieee_weak_external_reference_enum)
+ || ! ieee_write_int (abfd, (bfd_vma) 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, (bfd_vma) public_index)
+ || ! ieee_write_id (abfd, p->name)
+ || ! ieee_write_2bytes (abfd, ieee_attribute_record_enum)
+ || ! ieee_write_int (abfd, (bfd_vma) 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, (bfd_vma) 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 relocatable 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 bfd_boolean
+ieee_write_me_part (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 bfd_boolean
+ieee_write_processor (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_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;
+ case bfd_mach_mcf_isa_a_nodiv: id = "isa-a:nodiv"; break;
+ case bfd_mach_mcf_isa_a: id = "isa-a"; break;
+ case bfd_mach_mcf_isa_a_mac: id = "isa-a:mac"; break;
+ case bfd_mach_mcf_isa_a_emac: id = "isa-a:emac"; break;
+ case bfd_mach_mcf_isa_aplus: id = "isa-aplus"; break;
+ case bfd_mach_mcf_isa_aplus_mac: id = "isa-aplus:mac"; break;
+ case bfd_mach_mcf_isa_aplus_emac: id = "isa-aplus:mac"; break;
+ case bfd_mach_mcf_isa_b_nousp: id = "isa-b:nousp"; break;
+ case bfd_mach_mcf_isa_b_nousp_mac: id = "isa-b:nousp:mac"; break;
+ case bfd_mach_mcf_isa_b_nousp_emac: id = "isa-b:nousp:emac"; break;
+ case bfd_mach_mcf_isa_b: id = "isa-b"; break;
+ case bfd_mach_mcf_isa_b_mac: id = "isa-b:mac"; break;
+ case bfd_mach_mcf_isa_b_emac: id = "isa-b:emac"; break;
+ case bfd_mach_mcf_isa_b_float: id = "isa-b:float"; break;
+ case bfd_mach_mcf_isa_b_float_mac: id = "isa-b:float:mac"; break;
+ case bfd_mach_mcf_isa_b_float_emac: id = "isa-b:float:emac"; break;
+ case bfd_mach_mcf_isa_c: id = "isa-c"; break;
+ case bfd_mach_mcf_isa_c_mac: id = "isa-c:mac"; break;
+ case bfd_mach_mcf_isa_c_emac: id = "isa-c:emac"; break;
+ case bfd_mach_mcf_isa_c_nodiv: id = "isa-c:nodiv"; break;
+ case bfd_mach_mcf_isa_c_nodiv_mac: id = "isa-c:nodiv:mac"; break;
+ case bfd_mach_mcf_isa_c_nodiv_emac: id = "isa-c:nodiv:emac"; break;
+ }
+
+ if (! ieee_write_id (abfd, id))
+ return FALSE;
+ }
+ break;
+ }
+
+ return TRUE;
+}
+
+static bfd_boolean
+ieee_write_object_contents (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_bwrite ((char *) exten, (bfd_size_type) 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_bwrite ((char *) envi, (bfd_size_type) 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, (bfd_vma) (t->tm_year + 1900))
+ || ! ieee_write_int (abfd, (bfd_vma) (t->tm_mon + 1))
+ || ! ieee_write_int (abfd, (bfd_vma) t->tm_mday)
+ || ! ieee_write_int (abfd, (bfd_vma) t->tm_hour)
+ || ! ieee_write_int (abfd, (bfd_vma) t->tm_min)
+ || ! ieee_write_int (abfd, (bfd_vma) 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;
+
+ /* 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, (bfd_vma) 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. */
+
+static asymbol *
+ieee_make_empty_symbol (bfd *abfd)
+{
+ bfd_size_type amt = sizeof (ieee_symbol_type);
+ ieee_symbol_type *new_symbol = (ieee_symbol_type *) bfd_zalloc (abfd, amt);
+
+ if (!new_symbol)
+ return NULL;
+ new_symbol->symbol.the_bfd = abfd;
+ return &new_symbol->symbol;
+}
+
+static bfd *
+ieee_openr_next_archived_file (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 NULL;
+ }
+ }
+}
+
+#define ieee_find_nearest_line _bfd_nosymbols_find_nearest_line
+#define ieee_find_line _bfd_nosymbols_find_line
+#define ieee_find_inliner_info _bfd_nosymbols_find_inliner_info
+
+static int
+ieee_generic_stat_arch_elt (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 (bfd *abfd ATTRIBUTE_UNUSED,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+#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 \
+ ((bfd_boolean (*) \
+ (bfd *, char **, bfd_size_type *, const char **)) \
+ bfd_true)
+#define ieee_truncate_arname bfd_dont_truncate_arname
+#define ieee_write_armap \
+ ((bfd_boolean (*) \
+ (bfd *, unsigned int, struct orl *, unsigned int, int)) \
+ bfd_true)
+#define ieee_read_ar_hdr bfd_nullvoidptr
+#define ieee_write_ar_hdr ((bfd_boolean (*) (bfd *, bfd *)) bfd_false)
+#define ieee_update_armap_timestamp bfd_true
+#define ieee_get_elt_at_index _bfd_generic_get_elt_at_index
+
+#define ieee_bfd_is_target_special_symbol \
+ ((bfd_boolean (*) (bfd *, asymbol *)) bfd_false)
+#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_bfd_reloc_name_lookup _bfd_norelocs_bfd_reloc_name_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_lookup_section_flags bfd_generic_lookup_section_flags
+#define ieee_bfd_merge_sections bfd_generic_merge_sections
+#define ieee_bfd_is_group_section bfd_generic_is_group_section
+#define ieee_bfd_discard_group bfd_generic_discard_group
+#define ieee_section_already_linked \
+ _bfd_generic_section_already_linked
+#define ieee_bfd_define_common_symbol bfd_generic_define_common_symbol
+#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_link_just_syms _bfd_generic_link_just_syms
+#define ieee_bfd_copy_link_hash_symbol_type \
+ _bfd_generic_copy_link_hash_symbol_type
+#define ieee_bfd_final_link _bfd_generic_final_link
+#define ieee_bfd_link_split_section _bfd_generic_link_split_section
+
+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. */
+ 0, /* match priority. */
+ 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, /* Headers. */
+
+ {_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,
+ },
+
+ /* ieee_close_and_cleanup, ieee_bfd_free_cached_info, ieee_new_section_hook,
+ ieee_get_section_contents, ieee_get_section_contents_in_window. */
+ BFD_JUMP_TABLE_GENERIC (ieee),
+
+ BFD_JUMP_TABLE_COPY (_bfd_generic),
+ BFD_JUMP_TABLE_CORE (_bfd_nocore),
+
+ /* ieee_slurp_armap, ieee_slurp_extended_name_table,
+ ieee_construct_extended_name_table, ieee_truncate_arname,
+ ieee_write_armap, ieee_read_ar_hdr, ieee_openr_next_archived_file,
+ ieee_get_elt_at_index, ieee_generic_stat_arch_elt,
+ ieee_update_armap_timestamp. */
+ BFD_JUMP_TABLE_ARCHIVE (ieee),
+
+ /* ieee_get_symtab_upper_bound, ieee_canonicalize_symtab,
+ ieee_make_empty_symbol, ieee_print_symbol, ieee_get_symbol_info,
+ ieee_bfd_is_local_label_name, ieee_get_lineno,
+ ieee_find_nearest_line, ieee_bfd_make_debug_symbol,
+ ieee_read_minisymbols, ieee_minisymbol_to_symbol. */
+ BFD_JUMP_TABLE_SYMBOLS (ieee),
+
+ /* ieee_get_reloc_upper_bound, ieee_canonicalize_reloc,
+ ieee_bfd_reloc_type_lookup. */
+ BFD_JUMP_TABLE_RELOCS (ieee),
+
+ /* ieee_set_arch_mach, ieee_set_section_contents. */
+ BFD_JUMP_TABLE_WRITE (ieee),
+
+ /* ieee_sizeof_headers, ieee_bfd_get_relocated_section_contents,
+ ieee_bfd_relax_section, ieee_bfd_link_hash_table_create,
+ ieee_bfd_link_add_symbols, ieee_bfd_final_link,
+ ieee_bfd_link_split_section, ieee_bfd_gc_sections,
+ ieee_bfd_merge_sections. */
+ BFD_JUMP_TABLE_LINK (ieee),
+
+ BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
+
+ NULL,
+
+ NULL
+};
diff --git a/bfd/ihex.c b/bfd/ihex.c
new file mode 100644
index 0000000..9b3b813
--- /dev/null
+++ b/bfd/ihex.c
@@ -0,0 +1,1000 @@
+/* BFD back-end for Intel Hex objects.
+ Copyright (C) 1995-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, 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 "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+#include "libiberty.h"
+#include "safe-ctype.h"
+
+/* The number of bytes we put on one line during output. */
+
+#define CHUNK 16
+
+/* 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 (void)
+{
+ static bfd_boolean inited;
+
+ if (! inited)
+ {
+ inited = TRUE;
+ hex_init ();
+ }
+}
+
+/* Create an ihex object. */
+
+static bfd_boolean
+ihex_mkobject (bfd *abfd)
+{
+ struct ihex_data_struct *tdata;
+
+ tdata = (struct ihex_data_struct *) bfd_alloc (abfd, sizeof (* tdata));
+ 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 (bfd *abfd, bfd_boolean *errorptr)
+{
+ bfd_byte c;
+
+ if (bfd_bread (&c, (bfd_size_type) 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 (bfd *abfd, unsigned int lineno, int c, bfd_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)
+ (_("%B:%d: unexpected character `%s' in Intel Hex file"),
+ 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 bfd_boolean
+ihex_scan (bfd *abfd)
+{
+ bfd_vma segbase;
+ bfd_vma extbase;
+ asection *sec;
+ unsigned int lineno;
+ bfd_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_bread (hdr, (bfd_size_type) 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, (bfd_size_type) chars);
+ if (buf == NULL)
+ goto error_return;
+ bufsize = chars;
+ }
+
+ if (bfd_bread (buf, (bfd_size_type) chars, abfd) != chars)
+ goto error_return;
+
+ for (i = 0; i < chars; i++)
+ {
+ if (! ISHEX (buf[i]))
+ {
+ ihex_bad_byte (abfd, lineno, buf[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)
+ (_("%B:%u: bad checksum in Intel Hex file (expected %u, found %u)"),
+ 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->size == extbase + segbase + addr)
+ {
+ /* This data goes at the end of the section we are
+ currently building. */
+ sec->size += len;
+ }
+ else if (len > 0)
+ {
+ char secbuf[20];
+ char *secname;
+ bfd_size_type amt;
+ flagword flags;
+
+ sprintf (secbuf, ".sec%d", bfd_count_sections (abfd) + 1);
+ amt = strlen (secbuf) + 1;
+ secname = (char *) bfd_alloc (abfd, amt);
+ if (secname == NULL)
+ goto error_return;
+ strcpy (secname, secbuf);
+ flags = SEC_HAS_CONTENTS | SEC_LOAD | SEC_ALLOC;
+ sec = bfd_make_section_with_flags (abfd, secname, flags);
+ if (sec == NULL)
+ goto error_return;
+ sec->vma = extbase + segbase + addr;
+ sec->lma = extbase + segbase + addr;
+ sec->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)
+ (_("%B:%u: bad extended address record length in Intel Hex file"),
+ 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)
+ (_("%B:%u: bad extended start address length in Intel Hex file"),
+ 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)
+ (_("%B:%u: bad extended linear address record length in Intel Hex file"),
+ 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)
+ (_("%B:%u: bad extended linear start address length in Intel Hex file"),
+ 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)
+ (_("%B:%u: unrecognized ihex type %u in Intel Hex file"),
+ 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 (bfd *abfd)
+{
+ void * tdata_save;
+ 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_bread (b, (bfd_size_type) 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. */
+ tdata_save = abfd->tdata.any;
+ if (! ihex_mkobject (abfd) || ! ihex_scan (abfd))
+ {
+ if (abfd->tdata.any != tdata_save && abfd->tdata.any != NULL)
+ bfd_release (abfd, abfd->tdata.any);
+ abfd->tdata.any = tdata_save;
+ return NULL;
+ }
+
+ return abfd->xvec;
+}
+
+/* Read the contents of a section in an Intel Hex file. */
+
+static bfd_boolean
+ihex_read_section (bfd *abfd, asection *section, bfd_byte *contents)
+{
+ int c;
+ bfd_byte *p;
+ bfd_byte *buf = NULL;
+ size_t bufsize;
+ bfd_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;
+ 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_bread (hdr, (bfd_size_type) 8, abfd) != 8)
+ goto error_return;
+
+ len = HEX2 (hdr);
+ type = HEX2 (hdr + 6);
+
+ /* We should only see type 0 records here. */
+ if (type != 0)
+ {
+ (*_bfd_error_handler)
+ (_("%B: internal error in ihex_read_section"), abfd);
+ bfd_set_error (bfd_error_bad_value);
+ goto error_return;
+ }
+
+ if (len * 2 > bufsize)
+ {
+ buf = (bfd_byte *) bfd_realloc (buf, (bfd_size_type) len * 2);
+ if (buf == NULL)
+ goto error_return;
+ bufsize = len * 2;
+ }
+
+ if (bfd_bread (buf, (bfd_size_type) 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->size)
+ {
+ /* We've read everything in the section. */
+ if (buf != NULL)
+ free (buf);
+ return TRUE;
+ }
+
+ /* Skip the checksum. */
+ if (bfd_bread (buf, (bfd_size_type) 2, abfd) != 2)
+ goto error_return;
+ }
+
+ if ((bfd_size_type) (p - contents) < section->size)
+ {
+ (*_bfd_error_handler)
+ (_("%B: bad section length in ihex_read_section"), 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 bfd_boolean
+ihex_get_section_contents (bfd *abfd,
+ asection *section,
+ void * location,
+ file_ptr offset,
+ bfd_size_type count)
+{
+ if (section->used_by_bfd == NULL)
+ {
+ section->used_by_bfd = bfd_alloc (abfd, section->size);
+ if (section->used_by_bfd == NULL)
+ return FALSE;
+ if (! ihex_read_section (abfd, section,
+ (bfd_byte *) 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 bfd_boolean
+ihex_set_section_contents (bfd *abfd,
+ asection *section,
+ const void * 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 (* n));
+ 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
+ {
+ 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 bfd_boolean
+ihex_write_record (bfd *abfd,
+ size_t count,
+ unsigned int 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;
+ size_t total;
+
+#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';
+
+ total = 9 + count * 2 + 4;
+ if (bfd_bwrite (buf, (bfd_size_type) total, abfd) != total)
+ return FALSE;
+
+ return TRUE;
+}
+
+/* Write out an Intel Hex file. */
+
+static bfd_boolean
+ihex_write_object_contents (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)
+ {
+ size_t now;
+ unsigned int rec_addr;
+
+ now = count;
+ if (count > 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 Intel 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;
+ }
+ }
+
+ rec_addr = where - (extbase + segbase);
+
+ /* Output records shouldn't cross 64K boundaries. */
+ if (rec_addr + now > 0xffff)
+ now = 0x10000 - rec_addr;
+
+ if (! ihex_write_record (abfd, now, rec_addr, 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;
+}
+
+/* Set the architecture for the output file. The architecture is
+ irrelevant, so we ignore errors about unknown architectures. */
+
+static bfd_boolean
+ihex_set_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. */
+
+static int
+ihex_sizeof_headers (bfd *abfd ATTRIBUTE_UNUSED,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED)
+{
+ 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_canonicalize_symtab ((long (*) (bfd *, asymbol **)) bfd_0l)
+#define ihex_make_empty_symbol _bfd_generic_make_empty_symbol
+#define ihex_print_symbol _bfd_nosymbols_print_symbol
+#define ihex_get_symbol_info _bfd_nosymbols_get_symbol_info
+#define ihex_bfd_is_target_special_symbol ((bfd_boolean (*) (bfd *, asymbol *)) bfd_false)
+#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_find_line _bfd_nosymbols_find_line
+#define ihex_find_inliner_info _bfd_nosymbols_find_inliner_info
+#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_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_lookup_section_flags bfd_generic_lookup_section_flags
+#define ihex_bfd_merge_sections bfd_generic_merge_sections
+#define ihex_bfd_is_group_section bfd_generic_is_group_section
+#define ihex_bfd_discard_group bfd_generic_discard_group
+#define ihex_section_already_linked _bfd_generic_section_already_linked
+#define ihex_bfd_define_common_symbol bfd_generic_define_common_symbol
+#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_link_just_syms _bfd_generic_link_just_syms
+#define ihex_bfd_copy_link_hash_symbol_type \
+ _bfd_generic_copy_link_hash_symbol_type
+#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. */
+ 0, /* match priority. */
+ 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, /* Headers. */
+
+ {
+ _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 (_bfd_norelocs),
+ BFD_JUMP_TABLE_WRITE (ihex),
+ BFD_JUMP_TABLE_LINK (ihex),
+ BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
+
+ NULL,
+
+ NULL
+};
diff --git a/bfd/init.c b/bfd/init.c
new file mode 100644
index 0000000..c087496
--- /dev/null
+++ b/bfd/init.c
@@ -0,0 +1,54 @@
+/* bfd initialization stuff
+ Copyright (C) 1990-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+
+/*
+SECTION
+ Initialization
+
+SUBSECTION
+ Initialization functions
+
+ 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 (void)
+{
+}
diff --git a/bfd/irix-core.c b/bfd/irix-core.c
new file mode 100644
index 0000000..9dcc465
--- /dev/null
+++ b/bfd/irix-core.c
@@ -0,0 +1,333 @@
+/* BFD back-end for Irix core files.
+ Copyright (C) 1993-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+
+/* This file can only be compiled on systems which use Irix style core
+ files (namely, Irix 4 and Irix 5, so far). */
+
+#include "sysdep.h"
+#include "bfd.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)
+
+#define irix_core_core_file_matches_executable_p generic_core_file_matches_executable_p
+#define irix_core_core_file_pid _bfd_nocore_core_file_pid
+
+static asection *make_bfd_asection
+ (bfd *, const char *, flagword, bfd_size_type, bfd_vma, file_ptr);
+
+/* Helper function for irix_core_core_file_p:
+ 32-bit and 64-bit versions. */
+
+#ifdef CORE_MAGIC64
+static int
+do_sections64 (bfd *abfd, struct coreout *coreout)
+{
+ struct vmap64 vmap;
+ char *secname;
+ int i, val;
+
+ for (i = 0; i < coreout->c_nvmap; i++)
+ {
+ val = bfd_bread (&vmap, (bfd_size_type) 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))
+ /* Fail. */
+ return 0;
+ }
+
+ return 1;
+}
+#endif
+
+/* 32-bit version. */
+
+static int
+do_sections (bfd *abfd, struct coreout *coreout)
+{
+ struct vmap vmap;
+ char *secname;
+ int i, val;
+
+ for (i = 0; i < coreout->c_nvmap; i++)
+ {
+ val = bfd_bread (&vmap, (bfd_size_type) 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))
+ /* Fail. */
+ return 0;
+ }
+ return 1;
+}
+
+static asection *
+make_bfd_asection (bfd *abfd,
+ const char *name,
+ flagword flags,
+ bfd_size_type size,
+ bfd_vma vma,
+ file_ptr filepos)
+{
+ asection *asect;
+
+ asect = bfd_make_section_anyway_with_flags (abfd, name, flags);
+ if (!asect)
+ return NULL;
+
+ asect->size = size;
+ asect->vma = vma;
+ asect->filepos = filepos;
+ asect->alignment_power = 4;
+
+ return asect;
+}
+
+static const bfd_target *
+irix_core_core_file_p (bfd *abfd)
+{
+ int val;
+ struct coreout coreout;
+ struct idesc *idg, *idf, *ids;
+ bfd_size_type amt;
+
+ val = bfd_bread (&coreout, (bfd_size_type) sizeof coreout, abfd);
+ if (val != sizeof coreout)
+ {
+ if (bfd_get_error () != bfd_error_system_call)
+ bfd_set_error (bfd_error_wrong_format);
+ return 0;
+ }
+
+ if (coreout.c_version != CORE_VERSION1)
+ return 0;
+
+ /* Have we got a corefile? */
+ switch (coreout.c_magic)
+ {
+ case CORE_MAGIC: break;
+#ifdef CORE_MAGIC64
+ case CORE_MAGIC64: break;
+#endif
+#ifdef CORE_MAGICN32
+ case CORE_MAGICN32: break;
+#endif
+ default: return 0; /* Un-identifiable or not corefile. */
+ }
+
+ amt = sizeof (struct sgi_core_struct);
+ core_hdr (abfd) = (struct sgi_core_struct *) bfd_zalloc (abfd, amt);
+ 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)
+ goto fail;
+
+ /* Process corefile sections. */
+#ifdef CORE_MAGIC64
+ if (coreout.c_magic == (int) CORE_MAGIC64)
+ {
+ if (! do_sections64 (abfd, & coreout))
+ goto fail;
+ }
+ else
+#endif
+ if (! do_sections (abfd, & coreout))
+ goto fail;
+
+ /* 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)
+ goto fail; /* Can't deal with non-contig regs */
+
+ if (bfd_seek (abfd, idg->i_offset, SEEK_SET) != 0)
+ goto fail;
+
+ if (!make_bfd_asection (abfd, ".reg",
+ SEC_HAS_CONTENTS,
+ idg->i_len + idf->i_len + ids->i_len,
+ 0,
+ idg->i_offset))
+ goto fail;
+
+ /* OK, we believe you. You're a core file (sure, sure). */
+ bfd_default_set_arch_mach (abfd, bfd_arch_mips, 0);
+
+ return abfd->xvec;
+
+ fail:
+ bfd_release (abfd, core_hdr (abfd));
+ core_hdr (abfd) = NULL;
+ bfd_section_list_clear (abfd);
+ return NULL;
+}
+
+static char *
+irix_core_core_file_failing_command (bfd *abfd)
+{
+ return core_command (abfd);
+}
+
+static int
+irix_core_core_file_failing_signal (bfd *abfd)
+{
+ return core_signal (abfd);
+}
+
+/* If somebody calls any byte-swapping routines, shoot them. */
+static void
+swap_abort(void)
+{
+ abort(); /* This way doesn't require any declaration for ANSI to fuck up */
+}
+
+#define NO_GET ((bfd_vma (*) (const void *)) swap_abort)
+#define NO_PUT ((void (*) (bfd_vma, void *)) swap_abort)
+#define NO_GETS ((bfd_signed_vma (*) (const void *)) swap_abort)
+#define NO_GET64 ((bfd_uint64_t (*) (const void *)) swap_abort)
+#define NO_PUT64 ((void (*) (bfd_uint64_t, void *)) swap_abort)
+#define NO_GETS64 ((bfd_int64_t (*) (const void *)) swap_abort)
+
+const bfd_target core_irix_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 */
+ 0, /* match_priority */
+ NO_GET64, NO_GETS64, NO_PUT64, /* 64 bit data */
+ NO_GET, NO_GETS, NO_PUT, /* 32 bit data */
+ NO_GET, NO_GETS, NO_PUT, /* 16 bit data */
+ NO_GET64, NO_GETS64, NO_PUT64, /* 64 bit hdrs */
+ NO_GET, NO_GETS, NO_PUT, /* 32 bit hdrs */
+ NO_GET, NO_GETS, 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 (_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),
+
+ NULL,
+
+ NULL /* backend_data */
+ };
+
+#endif /* IRIX_CORE */
diff --git a/bfd/libaout.h b/bfd/libaout.h
new file mode 100644
index 0000000..25277cb
--- /dev/null
+++ b/bfd/libaout.h
@@ -0,0 +1,689 @@
+/* BFD back-end data structures for a.out (and similar) files.
+ Copyright (C) 1990-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, 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"
+
+/* Macros for accessing components in an aout header. */
+
+#define H_PUT_64 bfd_h_put_64
+#define H_PUT_32 bfd_h_put_32
+#define H_PUT_16 bfd_h_put_16
+#define H_PUT_8 bfd_h_put_8
+#define H_PUT_S64 bfd_h_put_signed_64
+#define H_PUT_S32 bfd_h_put_signed_32
+#define H_PUT_S16 bfd_h_put_signed_16
+#define H_PUT_S8 bfd_h_put_signed_8
+#define H_GET_64 bfd_h_get_64
+#define H_GET_32 bfd_h_get_32
+#define H_GET_16 bfd_h_get_16
+#define H_GET_8 bfd_h_get_8
+#define H_GET_S64 bfd_h_get_signed_64
+#define H_GET_S32 bfd_h_get_signed_32
+#define H_GET_S16 bfd_h_get_signed_16
+#define H_GET_S8 bfd_h_get_signed_8
+
+/* Parameterize the a.out code based on whether it is being built
+ for a 32-bit architecture or a 64-bit architecture. */
+/* Do not "beautify" the CONCAT* macro args. Traditional C will not
+ remove whitespace added here, and thus will fail to concatenate
+ the tokens. */
+#if ARCH_SIZE==64
+#define GET_WORD H_GET_64
+#define GET_SWORD H_GET_S64
+#define GET_MAGIC H_GET_32
+#define PUT_WORD H_PUT_64
+#define PUT_MAGIC H_PUT_32
+#ifndef NAME
+#define NAME(x,y) CONCAT3 (x,_64_,y)
+#endif
+#define JNAME(x) CONCAT2 (x,_64)
+#define BYTES_IN_WORD 8
+#else
+#if ARCH_SIZE==16
+#define GET_WORD H_GET_16
+#define GET_SWORD H_GET_S16
+#define GET_MAGIC H_GET_16
+#define PUT_WORD H_PUT_16
+#define PUT_MAGIC H_PUT_16
+#ifndef NAME
+#define NAME(x,y) CONCAT3 (x,_16_,y)
+#endif
+#define JNAME(x) CONCAT2 (x,_16)
+#define BYTES_IN_WORD 2
+#else /* ARCH_SIZE == 32 */
+#define GET_WORD H_GET_32
+#define GET_SWORD H_GET_S32
+#define GET_MAGIC H_GET_32
+#define PUT_WORD H_PUT_32
+#define PUT_MAGIC H_PUT_32
+#ifndef NAME
+#define NAME(x,y) CONCAT3 (x,_32_,y)
+#endif
+#define JNAME(x) CONCAT2 (x,_32)
+#define BYTES_IN_WORD 4
+#endif /* ARCH_SIZE==32 */
+#endif /* ARCH_SIZE==64 */
+
+/* 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. */
+ bfd_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, \
+ (bfd_boolean (*) (struct bfd_link_hash_entry *, void *)) (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. */
+ bfd_boolean (*set_sizes) (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. */
+ bfd_boolean (*add_dynamic_symbols)
+ (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. */
+ bfd_boolean (*add_one_symbol)
+ (struct bfd_link_info *, bfd *, const char *, flagword,
+ asection *, bfd_vma, const char *, bfd_boolean, bfd_boolean,
+ struct bfd_link_hash_entry **);
+
+ /* Called to handle linking a dynamic object. */
+ bfd_boolean (*link_dynamic_object)
+ (struct bfd_link_info *, bfd *);
+
+ /* Called for each global symbol being written out by the linker.
+ This should write out the dynamic symbol information. */
+ bfd_boolean (*write_dynamic_symbol)
+ (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. */
+ bfd_boolean (*check_dynamic_reloc)
+ (struct bfd_link_info *info, bfd *input_bfd,
+ asection *input_section, struct aout_link_hash_entry *h,
+ void * reloc, bfd_byte *contents, bfd_boolean *skip,
+ bfd_vma *relocation);
+
+ /* Called at the end of a link to finish up any dynamic linking
+ information. */
+ bfd_boolean (*finish_dynamic_link) (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 SUN's 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_POWERPC_NETBSD = 149, /* NetBSD/powerpc (big-endian) binary. */
+ M_VAX4K_NETBSD = 150, /* NetBSD/vax 4K pages binary. */
+ M_MIPS1 = 151, /* MIPS R2000/R3000 binary. */
+ M_MIPS2 = 152, /* MIPS R4000/R6000 binary. */
+ M_88K_OPENBSD = 153, /* OpenBSD/m88k binary. */
+ M_HPPA_OPENBSD = 154, /* OpenBSD/hppa binary. */
+ M_SPARC64_NETBSD = 156, /* NetBSD/sparc64 binary. */
+ M_X86_64_NETBSD = 157, /* NetBSD/amd64 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,
+ M_CRIS = 255 /* Axis CRIS binary. */
+};
+
+#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) ? (long) ((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. */
+
+enum aout_subformat {
+ 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
+};
+
+enum aout_magic {
+ undecided_magic = 0,
+ z_magic,
+ o_magic,
+ n_magic
+};
+
+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 aout_subformat subformat;
+
+ enum aout_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. */
+ void * 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. */
+ void * 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 = (void *)&(v)->relocs)
+
+/* Prototype declarations for functions defined in aoutx.h. */
+
+extern bfd_boolean NAME (aout, squirt_out_relocs)
+ (bfd *, asection *);
+
+extern bfd_boolean NAME (aout, make_sections)
+ (bfd *);
+
+extern const bfd_target * NAME (aout, some_aout_object_p)
+ (bfd *, struct internal_exec *, const bfd_target *(*) (bfd *));
+
+extern bfd_boolean NAME (aout, mkobject)
+ (bfd *);
+
+extern enum machine_type NAME (aout, machine_type)
+ (enum bfd_architecture, unsigned long, bfd_boolean *);
+
+extern bfd_boolean NAME (aout, set_arch_mach)
+ (bfd *, enum bfd_architecture, unsigned long);
+
+extern bfd_boolean NAME (aout, new_section_hook)
+ (bfd *, asection *);
+
+extern bfd_boolean NAME (aout, set_section_contents)
+ (bfd *, sec_ptr, const void *, file_ptr, bfd_size_type);
+
+extern asymbol * NAME (aout, make_empty_symbol)
+ (bfd *);
+
+extern bfd_boolean NAME (aout, translate_symbol_table)
+ (bfd *, aout_symbol_type *, struct external_nlist *, bfd_size_type,
+ char *, bfd_size_type, bfd_boolean);
+
+extern bfd_boolean NAME (aout, slurp_symbol_table)
+ (bfd *);
+
+extern bfd_boolean NAME (aout, write_syms)
+ (bfd *);
+
+extern void NAME (aout, reclaim_symbol_table)
+ (bfd *);
+
+extern long NAME (aout, get_symtab_upper_bound)
+ (bfd *);
+
+extern long NAME (aout, canonicalize_symtab)
+ (bfd *, asymbol **);
+
+extern void NAME (aout, swap_ext_reloc_in)
+ (bfd *, struct reloc_ext_external *, arelent *, asymbol **,
+ bfd_size_type);
+
+extern void NAME (aout, swap_std_reloc_in)
+ (bfd *, struct reloc_std_external *, arelent *, asymbol **,
+ bfd_size_type);
+
+extern reloc_howto_type * NAME (aout, reloc_type_lookup)
+ (bfd *, bfd_reloc_code_real_type);
+
+extern reloc_howto_type * NAME (aout, reloc_name_lookup)
+ (bfd *, const char *);
+
+extern bfd_boolean NAME (aout, slurp_reloc_table)
+ (bfd *, sec_ptr, asymbol **);
+
+extern long NAME (aout, canonicalize_reloc)
+ (bfd *, sec_ptr, arelent **, asymbol **);
+
+extern long NAME (aout, get_reloc_upper_bound)
+ (bfd *, sec_ptr);
+
+extern void NAME (aout, reclaim_reloc)
+ (bfd *, sec_ptr);
+
+extern alent * NAME (aout, get_lineno)
+ (bfd *, asymbol *);
+
+extern void NAME (aout, print_symbol)
+ (bfd *, void *, asymbol *, bfd_print_symbol_type);
+
+extern void NAME (aout, get_symbol_info)
+ (bfd *, asymbol *, symbol_info *);
+
+extern bfd_boolean NAME (aout, find_nearest_line)
+ (bfd *, asymbol **, asection *, bfd_vma,
+ const char **, const char **, unsigned int *, unsigned int *);
+
+extern long NAME (aout, read_minisymbols)
+ (bfd *, bfd_boolean, void * *, unsigned int *);
+
+extern asymbol * NAME (aout, minisymbol_to_symbol)
+ (bfd *, bfd_boolean, const void *, asymbol *);
+
+extern int NAME (aout, sizeof_headers)
+ (bfd *, struct bfd_link_info *);
+
+extern bfd_boolean NAME (aout, adjust_sizes_and_vmas)
+ (bfd *, bfd_size_type *, file_ptr *);
+
+extern void NAME (aout, swap_exec_header_in)
+ (bfd *, struct external_exec *, struct internal_exec *);
+
+extern void NAME (aout, swap_exec_header_out)
+ (bfd *, struct internal_exec *, struct external_exec *);
+
+extern struct bfd_hash_entry * NAME (aout, link_hash_newfunc)
+ (struct bfd_hash_entry *, struct bfd_hash_table *, const char *);
+
+extern bfd_boolean NAME (aout, link_hash_table_init)
+ (struct aout_link_hash_table *, bfd *,
+ struct bfd_hash_entry *(*) (struct bfd_hash_entry *,
+ struct bfd_hash_table *,
+ const char *),
+ unsigned int);
+
+extern struct bfd_link_hash_table * NAME (aout, link_hash_table_create)
+ (bfd *);
+
+extern bfd_boolean NAME (aout, link_add_symbols)
+ (bfd *, struct bfd_link_info *);
+
+extern bfd_boolean NAME (aout, final_link)
+ (bfd *, struct bfd_link_info *,
+ void (*) (bfd *, file_ptr *, file_ptr *, file_ptr *));
+
+extern bfd_boolean NAME (aout, bfd_free_cached_info)
+ (bfd *);
+
+#define aout_32_find_inliner_info _bfd_nosymbols_find_inliner_info
+#if 0 /* Are these needed? */
+#define aout_16_find_inliner_info _bfd_nosymbols_find_inliner_info
+#define aout_64_find_inliner_info _bfd_nosymbols_find_inliner_info
+#endif
+
+/* A.out uses the generic versions of these routines... */
+
+#define aout_16_get_section_contents _bfd_generic_get_section_contents
+
+#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 aout_32_bfd_is_target_special_symbol
+#define aout_32_bfd_is_target_special_symbol \
+ ((bfd_boolean (*) (bfd *, asymbol *)) bfd_false)
+#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 \
+ || bfd_bwrite (& exec_bytes, (bfd_size_type) EXEC_BYTES_SIZE, \
+ abfd) != EXEC_BYTES_SIZE) \
+ return FALSE; \
+ /* Now write out reloc info, followed by syms and strings. */ \
+ \
+ if (bfd_get_outsymbols (abfd) != 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
+
+/* Test if a read-only section can be merged with .text. This is
+ possible if:
+
+ 1. Section has file contents and is read-only.
+ 2. The VMA of the section is after the end of .text and before
+ the start of .data.
+ 3. The image is demand-pageable (otherwise, a_text in the header
+ will not reflect the gap between .text and .data). */
+
+#define aout_section_merge_with_text_p(abfd, sec) \
+ (((sec)->flags & (SEC_HAS_CONTENTS | SEC_READONLY)) == \
+ (SEC_HAS_CONTENTS | SEC_READONLY) \
+ && obj_textsec (abfd) != NULL \
+ && obj_datasec (abfd) != NULL \
+ && (sec)->vma >= (obj_textsec (abfd)->vma + \
+ obj_textsec (abfd)->size) \
+ && ((sec)->vma + (sec)->size) <= obj_datasec (abfd)->vma \
+ && ((abfd)->flags & D_PAGED) != 0)
+
+#endif /* ! defined (LIBAOUT_H) */
diff --git a/bfd/libbfd-in.h b/bfd/libbfd-in.h
new file mode 100644
index 0000000..50a46ac
--- /dev/null
+++ b/bfd/libbfd-in.h
@@ -0,0 +1,839 @@
+/* libbfd.h -- Declarations used by bfd library *implementation*.
+ (This include file is not for users of the library.)
+
+ Copyright (C) 1990-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "hashtab.h"
+
+/* 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)) & ~ (bfd_vma) ((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 = (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;
+};
+
+struct section_hash_entry
+{
+ struct bfd_hash_entry root;
+ asection section;
+};
+
+/* 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 */
+ htab_t 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. */
+ bfd_size_type extended_names_size; /* Size of extended names. */
+ /* 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. */
+ void *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. */
+ bfd_size_type parsed_size; /* Octets of filesize not including ar_hdr. */
+ bfd_size_type extra_size; /* BSD4.4: extra bytes after the header. */
+ char *filename; /* Null-terminated. */
+ file_ptr origin; /* For element of a thin archive. */
+ void *parent_cache; /* Where and how to find this member. */
+ file_ptr key;
+};
+
+#define arelt_size(bfd) (((struct areltdata *)((bfd)->arelt_data))->parsed_size)
+
+extern void *bfd_malloc
+ (bfd_size_type);
+extern void *bfd_realloc
+ (void *, bfd_size_type);
+extern void *bfd_realloc_or_free
+ (void *, bfd_size_type);
+extern void *bfd_zmalloc
+ (bfd_size_type);
+extern void *bfd_malloc2
+ (bfd_size_type, bfd_size_type);
+extern void *bfd_realloc2
+ (void *, bfd_size_type, bfd_size_type);
+extern void *bfd_zmalloc2
+ (bfd_size_type, bfd_size_type);
+
+extern void _bfd_default_error_handler (const char *s, ...);
+extern bfd_error_handler_type _bfd_error_handler;
+extern bfd_assert_handler_type _bfd_assert_handler;
+
+/* These routines allocate and free things on the BFD's objalloc. */
+
+extern void *bfd_alloc2
+ (bfd *, bfd_size_type, bfd_size_type);
+extern void *bfd_zalloc2
+ (bfd *, bfd_size_type, bfd_size_type);
+extern void bfd_release
+ (bfd *, void *);
+
+bfd * _bfd_create_empty_archive_element_shell
+ (bfd *obfd);
+bfd * _bfd_look_for_bfd_in_cache
+ (bfd *, file_ptr);
+bfd_boolean _bfd_add_bfd_to_archive_cache
+ (bfd *, file_ptr, bfd *);
+bfd_boolean _bfd_generic_mkarchive
+ (bfd *abfd);
+char *_bfd_append_relative_path
+ (bfd *arch, char *elt_name);
+const bfd_target *bfd_generic_archive_p
+ (bfd *abfd);
+bfd_boolean bfd_slurp_armap
+ (bfd *abfd);
+bfd_boolean bfd_slurp_bsd_armap_f2
+ (bfd *abfd);
+#define bfd_slurp_bsd_armap bfd_slurp_armap
+#define bfd_slurp_coff_armap bfd_slurp_armap
+bfd_boolean _bfd_slurp_extended_name_table
+ (bfd *abfd);
+extern bfd_boolean _bfd_construct_extended_name_table
+ (bfd *, bfd_boolean, char **, bfd_size_type *);
+bfd_boolean _bfd_write_archive_contents
+ (bfd *abfd);
+bfd_boolean _bfd_compute_and_write_armap
+ (bfd *, unsigned int elength);
+bfd *_bfd_get_elt_at_filepos
+ (bfd *archive, file_ptr filepos);
+extern bfd *_bfd_generic_get_elt_at_index
+ (bfd *, symindex);
+bfd * _bfd_new_bfd
+ (void);
+bfd_boolean _bfd_free_cached_info
+ (bfd *);
+
+bfd_boolean bfd_false
+ (bfd *ignore);
+bfd_boolean bfd_true
+ (bfd *ignore);
+void *bfd_nullvoidptr
+ (bfd *ignore);
+int bfd_0
+ (bfd *ignore);
+unsigned int bfd_0u
+ (bfd *ignore);
+long bfd_0l
+ (bfd *ignore);
+long _bfd_n1
+ (bfd *ignore);
+void bfd_void
+ (bfd *ignore);
+
+bfd *_bfd_new_bfd_contained_in
+ (bfd *);
+const bfd_target *_bfd_dummy_target
+ (bfd *abfd);
+
+void bfd_dont_truncate_arname
+ (bfd *abfd, const char *filename, char *hdr);
+void bfd_bsd_truncate_arname
+ (bfd *abfd, const char *filename, char *hdr);
+void bfd_gnu_truncate_arname
+ (bfd *abfd, const char *filename, char *hdr);
+
+bfd_boolean bsd_write_armap
+ (bfd *arch, unsigned int elength, struct orl *map, unsigned int orl_count,
+ int stridx);
+
+bfd_boolean coff_write_armap
+ (bfd *arch, unsigned int elength, struct orl *map, unsigned int orl_count,
+ int stridx);
+
+extern void *_bfd_generic_read_ar_hdr
+ (bfd *);
+extern void _bfd_ar_spacepad
+ (char *, size_t, const char *, long);
+extern bfd_boolean _bfd_ar_sizepad
+ (char *, size_t, bfd_size_type);
+
+extern void *_bfd_generic_read_ar_hdr_mag
+ (bfd *, const char *);
+
+extern bfd_boolean _bfd_generic_write_ar_hdr
+ (bfd *, bfd *);
+
+extern bfd_boolean _bfd_bsd44_write_ar_hdr
+ (bfd *, bfd *);
+
+bfd * bfd_generic_openr_next_archived_file
+ (bfd *archive, bfd *last_file);
+
+int bfd_generic_stat_arch_elt
+ (bfd *, struct stat *);
+
+#define _bfd_read_ar_hdr(abfd) \
+ BFD_SEND (abfd, _bfd_read_ar_hdr_fn, (abfd))
+#define _bfd_write_ar_hdr(archive, abfd) \
+ BFD_SEND (abfd, _bfd_write_ar_hdr_fn, (archive, abfd))
+
+/* Generic routines to use for BFD_JUMP_TABLE_GENERIC. Use
+ BFD_JUMP_TABLE_GENERIC (_bfd_generic). */
+
+#define _bfd_generic_close_and_cleanup _bfd_archive_close_and_cleanup
+extern bfd_boolean _bfd_archive_close_and_cleanup
+ (bfd *);
+#define _bfd_generic_bfd_free_cached_info bfd_true
+extern bfd_boolean _bfd_generic_new_section_hook
+ (bfd *, asection *);
+extern bfd_boolean _bfd_generic_get_section_contents
+ (bfd *, asection *, void *, file_ptr, bfd_size_type);
+extern bfd_boolean _bfd_generic_get_section_contents_in_window
+ (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 \
+ ((bfd_boolean (*) (bfd *, bfd *)) bfd_true)
+#define _bfd_generic_bfd_merge_private_bfd_data \
+ ((bfd_boolean (*) (bfd *, bfd *)) bfd_true)
+#define _bfd_generic_bfd_set_private_flags \
+ ((bfd_boolean (*) (bfd *, flagword)) bfd_true)
+#define _bfd_generic_bfd_copy_private_section_data \
+ ((bfd_boolean (*) (bfd *, asection *, bfd *, asection *)) bfd_true)
+#define _bfd_generic_bfd_copy_private_symbol_data \
+ ((bfd_boolean (*) (bfd *, asymbol *, bfd *, asymbol *)) bfd_true)
+#define _bfd_generic_bfd_copy_private_header_data \
+ ((bfd_boolean (*) (bfd *, bfd *)) bfd_true)
+#define _bfd_generic_bfd_print_private_bfd_data \
+ ((bfd_boolean (*) (bfd *, void *)) bfd_true)
+
+extern bfd_boolean _bfd_generic_init_private_section_data
+ (bfd *, asection *, bfd *, asection *, struct bfd_link_info *);
+
+/* 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
+ (bfd *);
+extern int _bfd_nocore_core_file_failing_signal
+ (bfd *);
+extern bfd_boolean _bfd_nocore_core_file_matches_executable_p
+ (bfd *, bfd *);
+extern int _bfd_nocore_core_file_pid
+ (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 \
+ ((bfd_boolean (*) (bfd *, char **, bfd_size_type *, const char **)) \
+ bfd_false)
+#define _bfd_noarchive_truncate_arname \
+ ((void (*) (bfd *, const char *, char *)) bfd_void)
+#define _bfd_noarchive_write_armap \
+ ((bfd_boolean (*) (bfd *, unsigned int, struct orl *, unsigned int, int)) \
+ bfd_false)
+#define _bfd_noarchive_read_ar_hdr bfd_nullvoidptr
+#define _bfd_noarchive_write_ar_hdr \
+ ((bfd_boolean (*) (bfd *, bfd *)) bfd_false)
+#define _bfd_noarchive_openr_next_archived_file \
+ ((bfd *(*) (bfd *, bfd *)) bfd_nullvoidptr)
+#define _bfd_noarchive_get_elt_at_index \
+ ((bfd *(*) (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 bfd_boolean _bfd_archive_bsd_construct_extended_name_table
+ (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_write_ar_hdr _bfd_generic_write_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 bfd_boolean _bfd_archive_bsd_update_armap_timestamp
+ (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 bfd_boolean _bfd_archive_coff_construct_extended_name_table
+ (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_write_ar_hdr _bfd_generic_write_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_ARCHIVE to get BSD4.4 style
+ archives. Use BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_bsd44). */
+
+#define _bfd_archive_bsd44_slurp_armap bfd_slurp_bsd_armap
+#define _bfd_archive_bsd44_slurp_extended_name_table \
+ _bfd_slurp_extended_name_table
+extern bfd_boolean _bfd_archive_bsd44_construct_extended_name_table
+ (bfd *, char **, bfd_size_type *, const char **);
+#define _bfd_archive_bsd44_truncate_arname bfd_bsd_truncate_arname
+#define _bfd_archive_bsd44_write_armap bsd_write_armap
+#define _bfd_archive_bsd44_read_ar_hdr _bfd_generic_read_ar_hdr
+#define _bfd_archive_bsd44_write_ar_hdr _bfd_bsd44_write_ar_hdr
+#define _bfd_archive_bsd44_openr_next_archived_file \
+ bfd_generic_openr_next_archived_file
+#define _bfd_archive_bsd44_get_elt_at_index _bfd_generic_get_elt_at_index
+#define _bfd_archive_bsd44_generic_stat_arch_elt \
+ bfd_generic_stat_arch_elt
+#define _bfd_archive_bsd44_update_armap_timestamp \
+ _bfd_archive_bsd_update_armap_timestamp
+
+/* Routines to use for BFD_JUMP_TABLE_ARCHIVE to get VMS style
+ archives. Use BFD_JUMP_TABLE_ARCHIVE (_bfd_vms_lib). Some of them
+ are irrelevant and never called, so defined as NULL. */
+
+extern bfd_boolean _bfd_vms_lib_write_archive_contents (bfd *arch);
+#define _bfd_vms_lib_slurp_armap NULL
+#define _bfd_vms_lib_slurp_extended_name_table NULL
+#define _bfd_vms_lib_construct_extended_name_table NULL
+#define _bfd_vms_lib_truncate_arname NULL
+#define _bfd_vms_lib_write_armap NULL
+#define _bfd_vms_lib_read_ar_hdr NULL
+#define _bfd_vms_lib_write_ar_hdr NULL
+extern bfd *_bfd_vms_lib_openr_next_archived_file (bfd *, bfd *);
+extern bfd *_bfd_vms_lib_get_elt_at_index (bfd *, symindex);
+extern int _bfd_vms_lib_generic_stat_arch_elt (bfd *, struct stat *);
+#define _bfd_vms_lib_update_armap_timestamp bfd_true
+
+/* Extra routines for VMS style archives. */
+
+extern symindex _bfd_vms_lib_find_symbol (bfd *, const char *);
+extern bfd *_bfd_vms_lib_get_imagelib_file (bfd *);
+extern const bfd_target *_bfd_vms_lib_alpha_archive_p (bfd *abfd);
+extern const bfd_target *_bfd_vms_lib_ia64_archive_p (bfd *abfd);
+extern bfd_boolean _bfd_vms_lib_alpha_mkarchive (bfd *abfd);
+extern bfd_boolean _bfd_vms_lib_ia64_mkarchive (bfd *abfd);
+
+/* 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_canonicalize_symtab \
+ ((long (*) (bfd *, asymbol **)) _bfd_n1)
+#define _bfd_nosymbols_make_empty_symbol _bfd_generic_make_empty_symbol
+#define _bfd_nosymbols_print_symbol \
+ ((void (*) (bfd *, void *, asymbol *, bfd_print_symbol_type)) bfd_void)
+#define _bfd_nosymbols_get_symbol_info \
+ ((void (*) (bfd *, asymbol *, symbol_info *)) bfd_void)
+#define _bfd_nosymbols_bfd_is_local_label_name \
+ ((bfd_boolean (*) (bfd *, const char *)) bfd_false)
+#define _bfd_nosymbols_bfd_is_target_special_symbol \
+ ((bfd_boolean (*) (bfd *, asymbol *)) bfd_false)
+#define _bfd_nosymbols_get_lineno \
+ ((alent *(*) (bfd *, asymbol *)) bfd_nullvoidptr)
+#define _bfd_nosymbols_find_nearest_line \
+ ((bfd_boolean (*) (bfd *, asymbol **, asection *, bfd_vma, \
+ const char **, const char **, unsigned int *, \
+ unsigned int *)) \
+ bfd_false)
+#define _bfd_nosymbols_find_line \
+ ((bfd_boolean (*) (bfd *, asymbol **, asymbol *, \
+ const char **, unsigned int *)) \
+ bfd_false)
+#define _bfd_nosymbols_find_inliner_info \
+ ((bfd_boolean (*) (bfd *, const char **, const char **, unsigned int *)) \
+ bfd_false)
+#define _bfd_nosymbols_bfd_make_debug_symbol \
+ ((asymbol *(*) (bfd *, void *, unsigned long)) bfd_nullvoidptr)
+#define _bfd_nosymbols_read_minisymbols \
+ ((long (*) (bfd *, bfd_boolean, void **, unsigned int *)) _bfd_n1)
+#define _bfd_nosymbols_minisymbol_to_symbol \
+ ((asymbol *(*) (bfd *, bfd_boolean, const void *, asymbol *)) \
+ bfd_nullvoidptr)
+
+/* Routines to use for BFD_JUMP_TABLE_RELOCS when there is no reloc
+ support. Use BFD_JUMP_TABLE_RELOCS (_bfd_norelocs). */
+
+extern long _bfd_norelocs_get_reloc_upper_bound (bfd *, asection *);
+extern long _bfd_norelocs_canonicalize_reloc (bfd *, asection *,
+ arelent **, asymbol **);
+#define _bfd_norelocs_bfd_reloc_type_lookup \
+ ((reloc_howto_type *(*) (bfd *, bfd_reloc_code_real_type)) bfd_nullvoidptr)
+#define _bfd_norelocs_bfd_reloc_name_lookup \
+ ((reloc_howto_type *(*) (bfd *, const char *)) 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 \
+ ((bfd_boolean (*) (bfd *, enum bfd_architecture, unsigned long)) \
+ bfd_false)
+#define _bfd_nowrite_set_section_contents \
+ ((bfd_boolean (*) (bfd *, asection *, const void *, 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 bfd_boolean _bfd_generic_set_section_contents
+ (bfd *, asection *, const void *, 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 (*) (bfd *, struct bfd_link_info *)) bfd_0)
+#define _bfd_nolink_bfd_get_relocated_section_contents \
+ ((bfd_byte *(*) (bfd *, struct bfd_link_info *, struct bfd_link_order *, \
+ bfd_byte *, bfd_boolean, asymbol **)) \
+ bfd_nullvoidptr)
+#define _bfd_nolink_bfd_relax_section \
+ ((bfd_boolean (*) \
+ (bfd *, asection *, struct bfd_link_info *, bfd_boolean *)) \
+ bfd_false)
+#define _bfd_nolink_bfd_gc_sections \
+ ((bfd_boolean (*) (bfd *, struct bfd_link_info *)) \
+ bfd_false)
+#define _bfd_nolink_bfd_lookup_section_flags \
+ ((bfd_boolean (*) (struct bfd_link_info *, struct flag_info *, asection *)) \
+ bfd_0)
+#define _bfd_nolink_bfd_merge_sections \
+ ((bfd_boolean (*) (bfd *, struct bfd_link_info *)) \
+ bfd_false)
+#define _bfd_nolink_bfd_is_group_section \
+ ((bfd_boolean (*) (bfd *, const struct bfd_section *)) \
+ bfd_false)
+#define _bfd_nolink_bfd_discard_group \
+ ((bfd_boolean (*) (bfd *, struct bfd_section *)) \
+ bfd_false)
+#define _bfd_nolink_bfd_link_hash_table_create \
+ ((struct bfd_link_hash_table *(*) (bfd *)) bfd_nullvoidptr)
+#define _bfd_nolink_bfd_link_add_symbols \
+ ((bfd_boolean (*) (bfd *, struct bfd_link_info *)) bfd_false)
+#define _bfd_nolink_bfd_link_just_syms \
+ ((void (*) (asection *, struct bfd_link_info *)) bfd_void)
+#define _bfd_nolink_bfd_copy_link_hash_symbol_type \
+ ((void (*) (bfd *, struct bfd_link_hash_entry *, \
+ struct bfd_link_hash_entry *)) bfd_void)
+#define _bfd_nolink_bfd_final_link \
+ ((bfd_boolean (*) (bfd *, struct bfd_link_info *)) bfd_false)
+#define _bfd_nolink_bfd_link_split_section \
+ ((bfd_boolean (*) (bfd *, struct bfd_section *)) bfd_false)
+#define _bfd_nolink_section_already_linked \
+ ((bfd_boolean (*) (bfd *, asection *, \
+ struct bfd_link_info *)) bfd_false)
+#define _bfd_nolink_bfd_define_common_symbol \
+ ((bfd_boolean (*) (bfd *, struct bfd_link_info *, \
+ struct bfd_link_hash_entry *)) 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 (*) (bfd *, asymbol **)) _bfd_n1)
+#define _bfd_nodynamic_get_synthetic_symtab \
+ ((long (*) (bfd *, long, asymbol **, long, asymbol **, asymbol **)) _bfd_n1)
+#define _bfd_nodynamic_get_dynamic_reloc_upper_bound _bfd_n1
+#define _bfd_nodynamic_canonicalize_dynamic_reloc \
+ ((long (*) (bfd *, arelent **, asymbol **)) _bfd_n1)
+
+/* Generic routine to determine of the given symbol is a local
+ label. */
+extern bfd_boolean bfd_generic_is_local_label_name
+ (bfd *, const char *);
+
+/* Generic minisymbol routines. */
+extern long _bfd_generic_read_minisymbols
+ (bfd *, bfd_boolean, void **, unsigned int *);
+extern asymbol *_bfd_generic_minisymbol_to_symbol
+ (bfd *, bfd_boolean, const void *, asymbol *);
+
+/* Find the nearest line using .stab/.stabstr sections. */
+extern bfd_boolean _bfd_stab_section_find_nearest_line
+ (bfd *, asymbol **, asection *, bfd_vma, bfd_boolean *,
+ const char **, const char **, unsigned int *, void **);
+
+/* Find the nearest line using DWARF 1 debugging information. */
+extern bfd_boolean _bfd_dwarf1_find_nearest_line
+ (bfd *, asymbol **, asection *, bfd_vma,
+ const char **, const char **, unsigned int *);
+
+struct dwarf_debug_section
+{
+ const char *uncompressed_name;
+ const char *compressed_name;
+};
+
+/* Map of uncompressed DWARF debug section name to compressed one. It
+ is terminated by NULL uncompressed_name. */
+
+extern const struct dwarf_debug_section dwarf_debug_sections[];
+
+/* Find the nearest line using DWARF 2 debugging information. */
+extern bfd_boolean _bfd_dwarf2_find_nearest_line
+ (bfd *, asymbol **, asymbol *, asection *, bfd_vma,
+ const char **, const char **, unsigned int *, unsigned int *,
+ const struct dwarf_debug_section *, unsigned int, void **);
+
+/* Find inliner info after calling bfd_find_nearest_line. */
+extern bfd_boolean _bfd_dwarf2_find_inliner_info
+ (bfd *, const char **, const char **, unsigned int *, void **);
+
+/* Read DWARF 2 debugging information. */
+extern bfd_boolean _bfd_dwarf2_slurp_debug_info
+ (bfd *, bfd *, const struct dwarf_debug_section *, asymbol **, void **,
+ bfd_boolean);
+
+/* Clean up the data used to handle DWARF 2 debugging information. */
+extern void _bfd_dwarf2_cleanup_debug_info
+ (bfd *, void **);
+
+/* Create a new section entry. */
+extern struct bfd_hash_entry *bfd_section_hash_newfunc
+ (struct bfd_hash_entry *, struct bfd_hash_table *, const char *);
+
+/* A routine to create entries for a bfd_link_hash_table. */
+extern struct bfd_hash_entry *_bfd_link_hash_newfunc
+ (struct bfd_hash_entry *entry, struct bfd_hash_table *table,
+ const char *string);
+
+/* Initialize a bfd_link_hash_table. */
+extern bfd_boolean _bfd_link_hash_table_init
+ (struct bfd_link_hash_table *, bfd *,
+ struct bfd_hash_entry *(*) (struct bfd_hash_entry *,
+ struct bfd_hash_table *,
+ const char *),
+ unsigned int);
+
+/* Generic link hash table creation routine. */
+extern struct bfd_link_hash_table *_bfd_generic_link_hash_table_create
+ (bfd *);
+
+/* Generic link hash table destruction routine. */
+extern void _bfd_generic_link_hash_table_free
+ (bfd *);
+
+/* Generic add symbol routine. */
+extern bfd_boolean _bfd_generic_link_add_symbols
+ (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 bfd_boolean _bfd_generic_link_add_symbols_collect
+ (bfd *, struct bfd_link_info *);
+
+/* Generic archive add symbol routine. */
+extern bfd_boolean _bfd_generic_link_add_archive_symbols
+ (bfd *, struct bfd_link_info *,
+ bfd_boolean (*) (bfd *, struct bfd_link_info *,
+ struct bfd_link_hash_entry *, const char *,
+ bfd_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 bfd_boolean _bfd_generic_link_add_one_symbol
+ (struct bfd_link_info *, bfd *, const char *name, flagword,
+ asection *, bfd_vma, const char *, bfd_boolean copy,
+ bfd_boolean constructor, struct bfd_link_hash_entry **);
+
+/* Generic routine to mark section as supplying symbols only. */
+extern void _bfd_generic_link_just_syms
+ (asection *, struct bfd_link_info *);
+
+/* Generic routine that does nothing. */
+extern void _bfd_generic_copy_link_hash_symbol_type
+ (bfd *, struct bfd_link_hash_entry *, struct bfd_link_hash_entry *);
+
+/* Generic link routine. */
+extern bfd_boolean _bfd_generic_final_link
+ (bfd *, struct bfd_link_info *);
+
+extern bfd_boolean _bfd_generic_link_split_section
+ (bfd *, struct bfd_section *);
+
+extern bfd_boolean _bfd_generic_section_already_linked
+ (bfd *, asection *, struct bfd_link_info *);
+
+/* Generic reloc_link_order processing routine. */
+extern bfd_boolean _bfd_generic_reloc_link_order
+ (bfd *, struct bfd_link_info *, asection *, struct bfd_link_order *);
+
+/* Default link order processing routine. */
+extern bfd_boolean _bfd_default_link_order
+ (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
+ (struct bfd_link_order *);
+
+/* Final link relocation routine. */
+extern bfd_reloc_status_type _bfd_final_link_relocate
+ (reloc_howto_type *, bfd *, asection *, bfd_byte *,
+ bfd_vma, bfd_vma, bfd_vma);
+
+/* Relocate a particular location by a howto and a value. */
+extern bfd_reloc_status_type _bfd_relocate_contents
+ (reloc_howto_type *, bfd *, bfd_vma, bfd_byte *);
+
+/* Clear a given location using a given howto. */
+extern void _bfd_clear_contents (reloc_howto_type *howto, bfd *input_bfd,
+ asection *input_section, bfd_byte *location);
+
+/* Link stabs in sections in the first pass. */
+
+extern bfd_boolean _bfd_link_section_stabs
+ (bfd *, struct stab_info *, asection *, asection *, void **,
+ bfd_size_type *);
+
+/* Eliminate stabs for discarded functions and symbols. */
+extern bfd_boolean _bfd_discard_section_stabs
+ (bfd *, asection *, void *, bfd_boolean (*) (bfd_vma, void *), void *);
+
+/* Write out the .stab section when linking stabs in sections. */
+
+extern bfd_boolean _bfd_write_section_stabs
+ (bfd *, struct stab_info *, asection *, void **, bfd_byte *);
+
+/* Write out the .stabstr string table when linking stabs in sections. */
+
+extern bfd_boolean _bfd_write_stab_strings
+ (bfd *, struct stab_info *);
+
+/* Find an offset within a .stab section when linking stabs in
+ sections. */
+
+extern bfd_vma _bfd_stab_section_offset
+ (asection *, void *, bfd_vma);
+
+/* Register a SEC_MERGE section as a candidate for merging. */
+
+extern bfd_boolean _bfd_add_merge_section
+ (bfd *, void **, asection *, void **);
+
+/* Attempt to merge SEC_MERGE sections. */
+
+extern bfd_boolean _bfd_merge_sections
+ (bfd *, struct bfd_link_info *, void *, void (*) (bfd *, asection *));
+
+/* Write out a merged section. */
+
+extern bfd_boolean _bfd_write_merged_section
+ (bfd *, asection *, void *);
+
+/* Find an offset within a modified SEC_MERGE section. */
+
+extern bfd_vma _bfd_merged_section_offset
+ (bfd *, asection **, void *, bfd_vma);
+
+/* Tidy up when done. */
+
+extern void _bfd_merge_sections_free (void *);
+
+/* Create a string table. */
+extern struct bfd_strtab_hash *_bfd_stringtab_init
+ (void);
+
+/* Create an XCOFF .debug section style string table. */
+extern struct bfd_strtab_hash *_bfd_xcoff_stringtab_init
+ (void);
+
+/* Free a string table. */
+extern void _bfd_stringtab_free
+ (struct bfd_strtab_hash *);
+
+/* Get the size of a string table. */
+extern bfd_size_type _bfd_stringtab_size
+ (struct bfd_strtab_hash *);
+
+/* Add a string to a string table. */
+extern bfd_size_type _bfd_stringtab_add
+ (struct bfd_strtab_hash *, const char *, bfd_boolean hash, bfd_boolean copy);
+
+/* Write out a string table. */
+extern bfd_boolean _bfd_stringtab_emit
+ (bfd *, struct bfd_strtab_hash *);
+
+/* Check that endianness of input and output file match. */
+extern bfd_boolean _bfd_generic_verify_endian_match
+ (bfd *, bfd *);
+
+/* 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
+ (const char*,int);
+
+#define BFD_ASSERT(x) \
+ do { if (!(x)) bfd_assert(__FILE__,__LINE__); } while (0)
+
+#define BFD_FAIL() \
+ do { bfd_assert(__FILE__,__LINE__); } while (0)
+
+extern void _bfd_abort
+ (const char *, int, const char *) ATTRIBUTE_NORETURN;
+
+/* if gcc >= 2.6, we can give a function name, too */
+#if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 6)
+#define __PRETTY_FUNCTION__ ((char *) NULL)
+#endif
+
+#undef abort
+#define abort() _bfd_abort (__FILE__, __LINE__, __PRETTY_FUNCTION__)
+
+/* Manipulate a system FILE but using BFD's "file_ptr", rather than
+ the system "off_t" or "off64_t", as the offset. */
+extern file_ptr real_ftell (FILE *file);
+extern int real_fseek (FILE *file, file_ptr offset, int whence);
+extern FILE *real_fopen (const char *filename, const char *modes);
+
+/* 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[];
+
+/* List of associated target vectors. */
+extern const bfd_target * const *bfd_associated_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 bfd_boolean _bfd_ecoff_locate_line
+ (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 bfd_boolean _bfd_ecoff_get_accumulated_pdr
+ (void *, bfd_byte *);
+extern bfd_boolean _bfd_ecoff_get_accumulated_sym
+ (void *, bfd_byte *);
+extern bfd_boolean _bfd_ecoff_get_accumulated_ss
+ (void *, bfd_byte *);
+
+extern bfd_vma _bfd_get_gp_value
+ (bfd *);
+extern void _bfd_set_gp_value
+ (bfd *, bfd_vma);
+
+/* Function shared by the COFF and ELF SH backends, which have no
+ other common header files. */
+
+#ifndef _bfd_sh_align_load_span
+extern bfd_boolean _bfd_sh_align_load_span
+ (bfd *, asection *, bfd_byte *,
+ bfd_boolean (*) (bfd *, asection *, void *, bfd_byte *, bfd_vma),
+ void *, bfd_vma **, bfd_vma *, bfd_vma, bfd_vma, bfd_boolean *);
+#endif
+
+/* This is the shape of the elements inside the already_linked hash
+ table. It maps a name onto a list of already_linked elements with
+ the same name. */
+
+struct bfd_section_already_linked_hash_entry
+{
+ struct bfd_hash_entry root;
+ struct bfd_section_already_linked *entry;
+};
+
+struct bfd_section_already_linked
+{
+ struct bfd_section_already_linked *next;
+ asection *sec;
+};
+
+extern struct bfd_section_already_linked_hash_entry *
+ bfd_section_already_linked_table_lookup (const char *);
+extern bfd_boolean bfd_section_already_linked_table_insert
+ (struct bfd_section_already_linked_hash_entry *, asection *);
+extern void bfd_section_already_linked_table_traverse
+ (bfd_boolean (*) (struct bfd_section_already_linked_hash_entry *,
+ void *), void *);
+
+extern bfd_vma read_unsigned_leb128 (bfd *, bfd_byte *, unsigned int *);
+extern bfd_signed_vma read_signed_leb128 (bfd *, bfd_byte *, unsigned int *);
diff --git a/bfd/libbfd.c b/bfd/libbfd.c
new file mode 100644
index 0000000..6352c9c
--- /dev/null
+++ b/bfd/libbfd.c
@@ -0,0 +1,1115 @@
+/* Assorted BFD support routines, only used internally.
+ Copyright (C) 1990-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+
+#ifndef HAVE_GETPAGESIZE
+#define getpagesize() 2048
+#endif
+
+/*
+SECTION
+ Implementation details
+
+SUBSECTION
+ 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. */
+
+bfd_boolean
+bfd_false (bfd *ignore ATTRIBUTE_UNUSED)
+{
+ 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. */
+
+bfd_boolean
+bfd_true (bfd *ignore ATTRIBUTE_UNUSED)
+{
+ return TRUE;
+}
+
+/* A routine which is used in target vectors for unsupported
+ operations which return a pointer value. */
+
+void *
+bfd_nullvoidptr (bfd *ignore ATTRIBUTE_UNUSED)
+{
+ bfd_set_error (bfd_error_invalid_operation);
+ return NULL;
+}
+
+int
+bfd_0 (bfd *ignore ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+unsigned int
+bfd_0u (bfd *ignore ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+long
+bfd_0l (bfd *ignore ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+/* A routine which is used in target vectors for unsupported
+ operations which return -1 on error. */
+
+long
+_bfd_n1 (bfd *ignore_abfd ATTRIBUTE_UNUSED)
+{
+ bfd_set_error (bfd_error_invalid_operation);
+ return -1;
+}
+
+void
+bfd_void (bfd *ignore ATTRIBUTE_UNUSED)
+{
+}
+
+long
+_bfd_norelocs_get_reloc_upper_bound (bfd *abfd ATTRIBUTE_UNUSED,
+ asection *sec ATTRIBUTE_UNUSED)
+{
+ return sizeof (arelent *);
+}
+
+long
+_bfd_norelocs_canonicalize_reloc (bfd *abfd ATTRIBUTE_UNUSED,
+ asection *sec ATTRIBUTE_UNUSED,
+ arelent **relptr,
+ asymbol **symbols ATTRIBUTE_UNUSED)
+{
+ *relptr = NULL;
+ return 0;
+}
+
+bfd_boolean
+_bfd_nocore_core_file_matches_executable_p
+ (bfd *ignore_core_bfd ATTRIBUTE_UNUSED,
+ bfd *ignore_exec_bfd ATTRIBUTE_UNUSED)
+{
+ bfd_set_error (bfd_error_invalid_operation);
+ return FALSE;
+}
+
+/* Routine to handle core_file_failing_command entry point for targets
+ without core file support. */
+
+char *
+_bfd_nocore_core_file_failing_command (bfd *ignore_abfd ATTRIBUTE_UNUSED)
+{
+ bfd_set_error (bfd_error_invalid_operation);
+ return NULL;
+}
+
+/* Routine to handle core_file_failing_signal entry point for targets
+ without core file support. */
+
+int
+_bfd_nocore_core_file_failing_signal (bfd *ignore_abfd ATTRIBUTE_UNUSED)
+{
+ bfd_set_error (bfd_error_invalid_operation);
+ return 0;
+}
+
+/* Routine to handle the core_file_pid entry point for targets without
+ core file support. */
+
+int
+_bfd_nocore_core_file_pid (bfd *ignore_abfd ATTRIBUTE_UNUSED)
+{
+ bfd_set_error (bfd_error_invalid_operation);
+ return 0;
+}
+
+const bfd_target *
+_bfd_dummy_target (bfd *ignore_abfd ATTRIBUTE_UNUSED)
+{
+ bfd_set_error (bfd_error_wrong_format);
+ return 0;
+}
+
+/* Allocate memory using malloc. */
+
+void *
+bfd_malloc (bfd_size_type size)
+{
+ void *ptr;
+
+ if (size != (size_t) size)
+ {
+ bfd_set_error (bfd_error_no_memory);
+ return NULL;
+ }
+
+ ptr = malloc ((size_t) size);
+ if (ptr == NULL && (size_t) size != 0)
+ bfd_set_error (bfd_error_no_memory);
+
+ return ptr;
+}
+
+/* Allocate memory using malloc, nmemb * size with overflow checking. */
+
+void *
+bfd_malloc2 (bfd_size_type nmemb, bfd_size_type size)
+{
+ void *ptr;
+
+ if ((nmemb | size) >= HALF_BFD_SIZE_TYPE
+ && size != 0
+ && nmemb > ~(bfd_size_type) 0 / size)
+ {
+ bfd_set_error (bfd_error_no_memory);
+ return NULL;
+ }
+
+ size *= nmemb;
+
+ if (size != (size_t) size)
+ {
+ bfd_set_error (bfd_error_no_memory);
+ return NULL;
+ }
+
+ ptr = malloc ((size_t) size);
+ if (ptr == NULL && (size_t) size != 0)
+ bfd_set_error (bfd_error_no_memory);
+
+ return ptr;
+}
+
+/* Reallocate memory using realloc. */
+
+void *
+bfd_realloc (void *ptr, bfd_size_type size)
+{
+ void *ret;
+
+ if (size != (size_t) size)
+ {
+ bfd_set_error (bfd_error_no_memory);
+ return NULL;
+ }
+
+ if (ptr == NULL)
+ ret = malloc ((size_t) size);
+ else
+ ret = realloc (ptr, (size_t) size);
+
+ if (ret == NULL && (size_t) size != 0)
+ bfd_set_error (bfd_error_no_memory);
+
+ return ret;
+}
+
+/* Reallocate memory using realloc, nmemb * size with overflow checking. */
+
+void *
+bfd_realloc2 (void *ptr, bfd_size_type nmemb, bfd_size_type size)
+{
+ void *ret;
+
+ if ((nmemb | size) >= HALF_BFD_SIZE_TYPE
+ && size != 0
+ && nmemb > ~(bfd_size_type) 0 / size)
+ {
+ bfd_set_error (bfd_error_no_memory);
+ return NULL;
+ }
+
+ size *= nmemb;
+
+ if (size != (size_t) size)
+ {
+ bfd_set_error (bfd_error_no_memory);
+ return NULL;
+ }
+
+ if (ptr == NULL)
+ ret = malloc ((size_t) size);
+ else
+ ret = realloc (ptr, (size_t) size);
+
+ if (ret == NULL && (size_t) size != 0)
+ bfd_set_error (bfd_error_no_memory);
+
+ return ret;
+}
+
+/* Reallocate memory using realloc.
+ If this fails the pointer is freed before returning. */
+
+void *
+bfd_realloc_or_free (void *ptr, bfd_size_type size)
+{
+ size_t amount = (size_t) size;
+ void *ret;
+
+ if (size != amount)
+ ret = NULL;
+ else if (ptr == NULL)
+ ret = malloc (amount);
+ else
+ ret = realloc (ptr, amount);
+
+ if (ret == NULL)
+ {
+ if (amount > 0)
+ bfd_set_error (bfd_error_no_memory);
+
+ if (ptr != NULL)
+ free (ptr);
+ }
+
+ return ret;
+}
+
+/* Allocate memory using malloc and clear it. */
+
+void *
+bfd_zmalloc (bfd_size_type size)
+{
+ void *ptr;
+
+ if (size != (size_t) size)
+ {
+ bfd_set_error (bfd_error_no_memory);
+ return NULL;
+ }
+
+ ptr = malloc ((size_t) size);
+
+ if ((size_t) size != 0)
+ {
+ if (ptr == NULL)
+ bfd_set_error (bfd_error_no_memory);
+ else
+ memset (ptr, 0, (size_t) size);
+ }
+
+ return ptr;
+}
+
+/* Allocate memory using malloc (nmemb * size) with overflow checking
+ and clear it. */
+
+void *
+bfd_zmalloc2 (bfd_size_type nmemb, bfd_size_type size)
+{
+ void *ptr;
+
+ if ((nmemb | size) >= HALF_BFD_SIZE_TYPE
+ && size != 0
+ && nmemb > ~(bfd_size_type) 0 / size)
+ {
+ bfd_set_error (bfd_error_no_memory);
+ return NULL;
+ }
+
+ size *= nmemb;
+
+ if (size != (size_t) size)
+ {
+ bfd_set_error (bfd_error_no_memory);
+ return NULL;
+ }
+
+ ptr = malloc ((size_t) size);
+
+ if ((size_t) size != 0)
+ {
+ if (ptr == NULL)
+ bfd_set_error (bfd_error_no_memory);
+ else
+ memset (ptr, 0, (size_t) size);
+ }
+
+ return ptr;
+}
+
+/*
+INTERNAL_FUNCTION
+ bfd_write_bigendian_4byte_int
+
+SYNOPSIS
+ bfd_boolean bfd_write_bigendian_4byte_int (bfd *, unsigned int);
+
+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.
+
+*/
+bfd_boolean
+bfd_write_bigendian_4byte_int (bfd *abfd, unsigned int i)
+{
+ bfd_byte buffer[4];
+ bfd_putb32 ((bfd_vma) i, buffer);
+ return bfd_bwrite (buffer, (bfd_size_type) 4, abfd) == 4;
+}
+
+
+/** 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) \
+. ((void) (*((unsigned char *) (ptr)) = (val) & 0xff))
+.#define bfd_put_signed_8 \
+. bfd_put_8
+.#define bfd_get_8(abfd, ptr) \
+. (*(const unsigned char *) (ptr) & 0xff)
+.#define bfd_get_signed_8(abfd, ptr) \
+. (((*(const unsigned char *) (ptr) & 0xff) ^ 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))
+.
+.#define bfd_get(bits, abfd, ptr) \
+. ((bits) == 8 ? (bfd_vma) bfd_get_8 (abfd, ptr) \
+. : (bits) == 16 ? bfd_get_16 (abfd, ptr) \
+. : (bits) == 32 ? bfd_get_32 (abfd, ptr) \
+. : (bits) == 64 ? bfd_get_64 (abfd, ptr) \
+. : (abort (), (bfd_vma) - 1))
+.
+.#define bfd_put(bits, abfd, val, ptr) \
+. ((bits) == 8 ? bfd_put_8 (abfd, val, ptr) \
+. : (bits) == 16 ? bfd_put_16 (abfd, val, ptr) \
+. : (bits) == 32 ? bfd_put_32 (abfd, val, ptr) \
+. : (bits) == 64 ? bfd_put_64 (abfd, val, ptr) \
+. : (abort (), (void) 0))
+.
+*/
+
+/*
+FUNCTION
+ bfd_h_put_size
+ bfd_h_get_size
+
+DESCRIPTION
+ These macros have the same function as their <<bfd_get_x>>
+ brethren, 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))
+.
+.{* Aliases for the above, which should eventually go away. *}
+.
+.#define H_PUT_64 bfd_h_put_64
+.#define H_PUT_32 bfd_h_put_32
+.#define H_PUT_16 bfd_h_put_16
+.#define H_PUT_8 bfd_h_put_8
+.#define H_PUT_S64 bfd_h_put_signed_64
+.#define H_PUT_S32 bfd_h_put_signed_32
+.#define H_PUT_S16 bfd_h_put_signed_16
+.#define H_PUT_S8 bfd_h_put_signed_8
+.#define H_GET_64 bfd_h_get_64
+.#define H_GET_32 bfd_h_get_32
+.#define H_GET_16 bfd_h_get_16
+.#define H_GET_8 bfd_h_get_8
+.#define H_GET_S64 bfd_h_get_signed_64
+.#define H_GET_S32 bfd_h_get_signed_32
+.#define H_GET_S16 bfd_h_get_signed_16
+.#define H_GET_S8 bfd_h_get_signed_8
+.
+.*/
+
+/* Sign extension to bfd_signed_vma. */
+#define COERCE16(x) (((bfd_vma) (x) ^ 0x8000) - 0x8000)
+#define COERCE32(x) (((bfd_vma) (x) ^ 0x80000000) - 0x80000000)
+#define COERCE64(x) \
+ (((bfd_uint64_t) (x) ^ ((bfd_uint64_t) 1 << 63)) - ((bfd_uint64_t) 1 << 63))
+
+bfd_vma
+bfd_getb16 (const void *p)
+{
+ const bfd_byte *addr = (const bfd_byte *) p;
+ return (addr[0] << 8) | addr[1];
+}
+
+bfd_vma
+bfd_getl16 (const void *p)
+{
+ const bfd_byte *addr = (const bfd_byte *) p;
+ return (addr[1] << 8) | addr[0];
+}
+
+bfd_signed_vma
+bfd_getb_signed_16 (const void *p)
+{
+ const bfd_byte *addr = (const bfd_byte *) p;
+ return COERCE16 ((addr[0] << 8) | addr[1]);
+}
+
+bfd_signed_vma
+bfd_getl_signed_16 (const void *p)
+{
+ const bfd_byte *addr = (const bfd_byte *) p;
+ return COERCE16 ((addr[1] << 8) | addr[0]);
+}
+
+void
+bfd_putb16 (bfd_vma data, void *p)
+{
+ bfd_byte *addr = (bfd_byte *) p;
+ addr[0] = (data >> 8) & 0xff;
+ addr[1] = data & 0xff;
+}
+
+void
+bfd_putl16 (bfd_vma data, void *p)
+{
+ bfd_byte *addr = (bfd_byte *) p;
+ addr[0] = data & 0xff;
+ addr[1] = (data >> 8) & 0xff;
+}
+
+bfd_vma
+bfd_getb32 (const void *p)
+{
+ const bfd_byte *addr = (const bfd_byte *) p;
+ 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 v;
+}
+
+bfd_vma
+bfd_getl32 (const void *p)
+{
+ const bfd_byte *addr = (const bfd_byte *) p;
+ 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 v;
+}
+
+bfd_signed_vma
+bfd_getb_signed_32 (const void *p)
+{
+ const bfd_byte *addr = (const bfd_byte *) p;
+ 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 (const void *p)
+{
+ const bfd_byte *addr = (const bfd_byte *) p;
+ 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_uint64_t
+bfd_getb64 (const void *p ATTRIBUTE_UNUSED)
+{
+#ifdef BFD_HOST_64_BIT
+ const bfd_byte *addr = (const bfd_byte *) p;
+ bfd_uint64_t v;
+
+ v = addr[0]; v <<= 8;
+ v |= addr[1]; v <<= 8;
+ v |= addr[2]; v <<= 8;
+ v |= addr[3]; v <<= 8;
+ v |= addr[4]; v <<= 8;
+ v |= addr[5]; v <<= 8;
+ v |= addr[6]; v <<= 8;
+ v |= addr[7];
+
+ return v;
+#else
+ BFD_FAIL();
+ return 0;
+#endif
+}
+
+bfd_uint64_t
+bfd_getl64 (const void *p ATTRIBUTE_UNUSED)
+{
+#ifdef BFD_HOST_64_BIT
+ const bfd_byte *addr = (const bfd_byte *) p;
+ bfd_uint64_t v;
+
+ v = addr[7]; v <<= 8;
+ v |= addr[6]; v <<= 8;
+ v |= addr[5]; v <<= 8;
+ v |= addr[4]; v <<= 8;
+ v |= addr[3]; v <<= 8;
+ v |= addr[2]; v <<= 8;
+ v |= addr[1]; v <<= 8;
+ v |= addr[0];
+
+ return v;
+#else
+ BFD_FAIL();
+ return 0;
+#endif
+
+}
+
+bfd_int64_t
+bfd_getb_signed_64 (const void *p ATTRIBUTE_UNUSED)
+{
+#ifdef BFD_HOST_64_BIT
+ const bfd_byte *addr = (const bfd_byte *) p;
+ bfd_uint64_t v;
+
+ v = addr[0]; v <<= 8;
+ v |= addr[1]; v <<= 8;
+ v |= addr[2]; v <<= 8;
+ v |= addr[3]; v <<= 8;
+ v |= addr[4]; v <<= 8;
+ v |= addr[5]; v <<= 8;
+ v |= addr[6]; v <<= 8;
+ v |= addr[7];
+
+ return COERCE64 (v);
+#else
+ BFD_FAIL();
+ return 0;
+#endif
+}
+
+bfd_int64_t
+bfd_getl_signed_64 (const void *p ATTRIBUTE_UNUSED)
+{
+#ifdef BFD_HOST_64_BIT
+ const bfd_byte *addr = (const bfd_byte *) p;
+ bfd_uint64_t v;
+
+ v = addr[7]; v <<= 8;
+ v |= addr[6]; v <<= 8;
+ v |= addr[5]; v <<= 8;
+ v |= addr[4]; v <<= 8;
+ v |= addr[3]; v <<= 8;
+ v |= addr[2]; v <<= 8;
+ v |= addr[1]; v <<= 8;
+ v |= addr[0];
+
+ return COERCE64 (v);
+#else
+ BFD_FAIL();
+ return 0;
+#endif
+}
+
+void
+bfd_putb32 (bfd_vma data, void *p)
+{
+ bfd_byte *addr = (bfd_byte *) p;
+ addr[0] = (data >> 24) & 0xff;
+ addr[1] = (data >> 16) & 0xff;
+ addr[2] = (data >> 8) & 0xff;
+ addr[3] = data & 0xff;
+}
+
+void
+bfd_putl32 (bfd_vma data, void *p)
+{
+ bfd_byte *addr = (bfd_byte *) p;
+ addr[0] = data & 0xff;
+ addr[1] = (data >> 8) & 0xff;
+ addr[2] = (data >> 16) & 0xff;
+ addr[3] = (data >> 24) & 0xff;
+}
+
+void
+bfd_putb64 (bfd_uint64_t data ATTRIBUTE_UNUSED, void *p ATTRIBUTE_UNUSED)
+{
+#ifdef BFD_HOST_64_BIT
+ bfd_byte *addr = (bfd_byte *) p;
+ addr[0] = (data >> (7*8)) & 0xff;
+ addr[1] = (data >> (6*8)) & 0xff;
+ addr[2] = (data >> (5*8)) & 0xff;
+ addr[3] = (data >> (4*8)) & 0xff;
+ addr[4] = (data >> (3*8)) & 0xff;
+ addr[5] = (data >> (2*8)) & 0xff;
+ addr[6] = (data >> (1*8)) & 0xff;
+ addr[7] = (data >> (0*8)) & 0xff;
+#else
+ BFD_FAIL();
+#endif
+}
+
+void
+bfd_putl64 (bfd_uint64_t data ATTRIBUTE_UNUSED, void *p ATTRIBUTE_UNUSED)
+{
+#ifdef BFD_HOST_64_BIT
+ bfd_byte *addr = (bfd_byte *) p;
+ addr[7] = (data >> (7*8)) & 0xff;
+ addr[6] = (data >> (6*8)) & 0xff;
+ addr[5] = (data >> (5*8)) & 0xff;
+ addr[4] = (data >> (4*8)) & 0xff;
+ addr[3] = (data >> (3*8)) & 0xff;
+ addr[2] = (data >> (2*8)) & 0xff;
+ addr[1] = (data >> (1*8)) & 0xff;
+ addr[0] = (data >> (0*8)) & 0xff;
+#else
+ BFD_FAIL();
+#endif
+}
+
+void
+bfd_put_bits (bfd_uint64_t data, void *p, int bits, bfd_boolean big_p)
+{
+ bfd_byte *addr = (bfd_byte *) p;
+ int i;
+ int bytes;
+
+ if (bits % 8 != 0)
+ abort ();
+
+ bytes = bits / 8;
+ for (i = 0; i < bytes; i++)
+ {
+ int addr_index = big_p ? bytes - i - 1 : i;
+
+ addr[addr_index] = data & 0xff;
+ data >>= 8;
+ }
+}
+
+bfd_uint64_t
+bfd_get_bits (const void *p, int bits, bfd_boolean big_p)
+{
+ const bfd_byte *addr = (const bfd_byte *) p;
+ bfd_uint64_t data;
+ int i;
+ int bytes;
+
+ if (bits % 8 != 0)
+ abort ();
+
+ data = 0;
+ bytes = bits / 8;
+ for (i = 0; i < bytes; i++)
+ {
+ int addr_index = big_p ? i : bytes - i - 1;
+
+ data = (data << 8) | addr[addr_index];
+ }
+
+ return data;
+}
+
+/* Default implementation */
+
+bfd_boolean
+_bfd_generic_get_section_contents (bfd *abfd,
+ sec_ptr section,
+ void *location,
+ file_ptr offset,
+ bfd_size_type count)
+{
+ bfd_size_type sz;
+ if (count == 0)
+ return TRUE;
+
+ if (section->compress_status != COMPRESS_SECTION_NONE)
+ {
+ (*_bfd_error_handler)
+ (_("%B: unable to get decompressed section %A"),
+ abfd, section);
+ bfd_set_error (bfd_error_invalid_operation);
+ return FALSE;
+ }
+
+ /* We do allow reading of a section after bfd_final_link has
+ written the contents out to disk. In that situation, rawsize is
+ just a stale version of size, so ignore it. Otherwise we must be
+ reading an input section, where rawsize, if different to size,
+ is the on-disk size. */
+ if (abfd->direction != write_direction && section->rawsize != 0)
+ sz = section->rawsize;
+ else
+ sz = section->size;
+ if (offset + count < count
+ || offset + count > sz)
+ {
+ bfd_set_error (bfd_error_invalid_operation);
+ return FALSE;
+ }
+
+ if (bfd_seek (abfd, section->filepos + offset, SEEK_SET) != 0
+ || bfd_bread (location, count, abfd) != count)
+ return FALSE;
+
+ return TRUE;
+}
+
+bfd_boolean
+_bfd_generic_get_section_contents_in_window
+ (bfd *abfd ATTRIBUTE_UNUSED,
+ sec_ptr section ATTRIBUTE_UNUSED,
+ bfd_window *w ATTRIBUTE_UNUSED,
+ file_ptr offset ATTRIBUTE_UNUSED,
+ bfd_size_type count ATTRIBUTE_UNUSED)
+{
+#ifdef USE_MMAP
+ bfd_size_type sz;
+
+ 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_zmalloc (sizeof (bfd_window_internal));
+ if (w->i == NULL)
+ return FALSE;
+ w->i->data = bfd_malloc (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 (abfd->direction != write_direction && section->rawsize != 0)
+ sz = section->rawsize;
+ else
+ sz = section->size;
+ if (offset + count > sz
+ || ! bfd_get_file_window (abfd, section->filepos + offset, count, w,
+ TRUE))
+ 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. */
+bfd_boolean
+_bfd_generic_set_section_contents (bfd *abfd,
+ sec_ptr section,
+ const void *location,
+ file_ptr offset,
+ bfd_size_type count)
+{
+ if (count == 0)
+ return TRUE;
+
+ if (bfd_seek (abfd, section->filepos + offset, SEEK_SET) != 0
+ || bfd_bwrite (location, 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. A @var{x} of 0 returns 0.
+*/
+
+unsigned int
+bfd_log2 (bfd_vma x)
+{
+ unsigned int result = 0;
+
+ if (x <= 1)
+ return result;
+ --x;
+ do
+ ++result;
+ while ((x >>= 1) != 0);
+ return result;
+}
+
+bfd_boolean
+bfd_generic_is_local_label_name (bfd *abfd, const char *name)
+{
+ char locals_prefix = (bfd_get_symbol_leading_char (abfd) == '_') ? 'L' : '.';
+
+ return name[0] == locals_prefix;
+}
+
+/* Can be used from / for bfd_merge_private_bfd_data to check that
+ endianness matches between input and output file. Returns
+ TRUE for a match, otherwise returns FALSE and emits an error. */
+bfd_boolean
+_bfd_generic_verify_endian_match (bfd *ibfd, bfd *obfd)
+{
+ if (ibfd->xvec->byteorder != obfd->xvec->byteorder
+ && ibfd->xvec->byteorder != BFD_ENDIAN_UNKNOWN
+ && obfd->xvec->byteorder != BFD_ENDIAN_UNKNOWN)
+ {
+ const char *msg;
+
+ if (bfd_big_endian (ibfd))
+ msg = _("%B: compiled for a big endian system and target is little endian");
+ else
+ msg = _("%B: compiled for a little endian system and target is big endian");
+
+ (*_bfd_error_handler) (msg, ibfd);
+
+ bfd_set_error (bfd_error_wrong_format);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/* Give a warning at runtime if someone compiles code which calls
+ old routines. */
+
+void
+warn_deprecated (const char *what,
+ const char *file,
+ int line,
+ const char *func)
+{
+ /* Poor man's tracking of functions we've already warned about. */
+ static size_t mask = 0;
+
+ if (~(size_t) func & ~mask)
+ {
+ fflush (stdout);
+ /* Note: separate sentences in order to allow
+ for translation into other languages. */
+ if (func)
+ fprintf (stderr, _("Deprecated %s called at %s line %d in %s\n"),
+ what, file, line, func);
+ else
+ fprintf (stderr, _("Deprecated %s called\n"), what);
+ fflush (stderr);
+ mask |= ~(size_t) func;
+ }
+}
+
+/* Helper function for reading uleb128 encoded data. */
+
+bfd_vma
+read_unsigned_leb128 (bfd *abfd ATTRIBUTE_UNUSED,
+ bfd_byte *buf,
+ unsigned int *bytes_read_ptr)
+{
+ bfd_vma result;
+ unsigned int num_read;
+ unsigned int shift;
+ unsigned char byte;
+
+ result = 0;
+ shift = 0;
+ num_read = 0;
+ do
+ {
+ byte = bfd_get_8 (abfd, buf);
+ buf++;
+ num_read++;
+ result |= (((bfd_vma) byte & 0x7f) << shift);
+ shift += 7;
+ }
+ while (byte & 0x80);
+ *bytes_read_ptr = num_read;
+ return result;
+}
+
+/* Helper function for reading sleb128 encoded data. */
+
+bfd_signed_vma
+read_signed_leb128 (bfd *abfd ATTRIBUTE_UNUSED,
+ bfd_byte *buf,
+ unsigned int *bytes_read_ptr)
+{
+ bfd_vma result;
+ unsigned int shift;
+ unsigned int num_read;
+ unsigned char byte;
+
+ result = 0;
+ shift = 0;
+ num_read = 0;
+ do
+ {
+ byte = bfd_get_8 (abfd, buf);
+ buf ++;
+ num_read ++;
+ result |= (((bfd_vma) byte & 0x7f) << shift);
+ shift += 7;
+ }
+ while (byte & 0x80);
+ if (shift < 8 * sizeof (result) && (byte & 0x40))
+ result |= (((bfd_vma) -1) << shift);
+ *bytes_read_ptr = num_read;
+ return result;
+}
+
+bfd_boolean
+_bfd_generic_init_private_section_data (bfd *ibfd ATTRIBUTE_UNUSED,
+ asection *isec ATTRIBUTE_UNUSED,
+ bfd *obfd ATTRIBUTE_UNUSED,
+ asection *osec ATTRIBUTE_UNUSED,
+ struct bfd_link_info *link_info ATTRIBUTE_UNUSED)
+{
+ return TRUE;
+}
diff --git a/bfd/libbfd.h b/bfd/libbfd.h
new file mode 100644
index 0000000..6c48f82
--- /dev/null
+++ b/bfd/libbfd.h
@@ -0,0 +1,3001 @@
+/* DO NOT EDIT! -*- buffer-read-only: t -*- This file is automatically
+ generated from "libbfd-in.h", "init.c", "libbfd.c", "bfdio.c",
+ "bfdwin.c", "cache.c", "reloc.c", "archures.c" and "elf.c".
+ Run "make headers" in your build bfd/ to regenerate. */
+
+/* libbfd.h -- Declarations used by bfd library *implementation*.
+ (This include file is not for users of the library.)
+
+ Copyright (C) 1990-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "hashtab.h"
+
+/* 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)) & ~ (bfd_vma) ((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 = (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;
+};
+
+struct section_hash_entry
+{
+ struct bfd_hash_entry root;
+ asection section;
+};
+
+/* 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 */
+ htab_t 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. */
+ bfd_size_type extended_names_size; /* Size of extended names. */
+ /* 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. */
+ void *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. */
+ bfd_size_type parsed_size; /* Octets of filesize not including ar_hdr. */
+ bfd_size_type extra_size; /* BSD4.4: extra bytes after the header. */
+ char *filename; /* Null-terminated. */
+ file_ptr origin; /* For element of a thin archive. */
+ void *parent_cache; /* Where and how to find this member. */
+ file_ptr key;
+};
+
+#define arelt_size(bfd) (((struct areltdata *)((bfd)->arelt_data))->parsed_size)
+
+extern void *bfd_malloc
+ (bfd_size_type);
+extern void *bfd_realloc
+ (void *, bfd_size_type);
+extern void *bfd_realloc_or_free
+ (void *, bfd_size_type);
+extern void *bfd_zmalloc
+ (bfd_size_type);
+extern void *bfd_malloc2
+ (bfd_size_type, bfd_size_type);
+extern void *bfd_realloc2
+ (void *, bfd_size_type, bfd_size_type);
+extern void *bfd_zmalloc2
+ (bfd_size_type, bfd_size_type);
+
+extern void _bfd_default_error_handler (const char *s, ...);
+extern bfd_error_handler_type _bfd_error_handler;
+extern bfd_assert_handler_type _bfd_assert_handler;
+
+/* These routines allocate and free things on the BFD's objalloc. */
+
+extern void *bfd_alloc2
+ (bfd *, bfd_size_type, bfd_size_type);
+extern void *bfd_zalloc2
+ (bfd *, bfd_size_type, bfd_size_type);
+extern void bfd_release
+ (bfd *, void *);
+
+bfd * _bfd_create_empty_archive_element_shell
+ (bfd *obfd);
+bfd * _bfd_look_for_bfd_in_cache
+ (bfd *, file_ptr);
+bfd_boolean _bfd_add_bfd_to_archive_cache
+ (bfd *, file_ptr, bfd *);
+bfd_boolean _bfd_generic_mkarchive
+ (bfd *abfd);
+char *_bfd_append_relative_path
+ (bfd *arch, char *elt_name);
+const bfd_target *bfd_generic_archive_p
+ (bfd *abfd);
+bfd_boolean bfd_slurp_armap
+ (bfd *abfd);
+bfd_boolean bfd_slurp_bsd_armap_f2
+ (bfd *abfd);
+#define bfd_slurp_bsd_armap bfd_slurp_armap
+#define bfd_slurp_coff_armap bfd_slurp_armap
+bfd_boolean _bfd_slurp_extended_name_table
+ (bfd *abfd);
+extern bfd_boolean _bfd_construct_extended_name_table
+ (bfd *, bfd_boolean, char **, bfd_size_type *);
+bfd_boolean _bfd_write_archive_contents
+ (bfd *abfd);
+bfd_boolean _bfd_compute_and_write_armap
+ (bfd *, unsigned int elength);
+bfd *_bfd_get_elt_at_filepos
+ (bfd *archive, file_ptr filepos);
+extern bfd *_bfd_generic_get_elt_at_index
+ (bfd *, symindex);
+bfd * _bfd_new_bfd
+ (void);
+bfd_boolean _bfd_free_cached_info
+ (bfd *);
+
+bfd_boolean bfd_false
+ (bfd *ignore);
+bfd_boolean bfd_true
+ (bfd *ignore);
+void *bfd_nullvoidptr
+ (bfd *ignore);
+int bfd_0
+ (bfd *ignore);
+unsigned int bfd_0u
+ (bfd *ignore);
+long bfd_0l
+ (bfd *ignore);
+long _bfd_n1
+ (bfd *ignore);
+void bfd_void
+ (bfd *ignore);
+
+bfd *_bfd_new_bfd_contained_in
+ (bfd *);
+const bfd_target *_bfd_dummy_target
+ (bfd *abfd);
+
+void bfd_dont_truncate_arname
+ (bfd *abfd, const char *filename, char *hdr);
+void bfd_bsd_truncate_arname
+ (bfd *abfd, const char *filename, char *hdr);
+void bfd_gnu_truncate_arname
+ (bfd *abfd, const char *filename, char *hdr);
+
+bfd_boolean bsd_write_armap
+ (bfd *arch, unsigned int elength, struct orl *map, unsigned int orl_count,
+ int stridx);
+
+bfd_boolean coff_write_armap
+ (bfd *arch, unsigned int elength, struct orl *map, unsigned int orl_count,
+ int stridx);
+
+extern void *_bfd_generic_read_ar_hdr
+ (bfd *);
+extern void _bfd_ar_spacepad
+ (char *, size_t, const char *, long);
+extern bfd_boolean _bfd_ar_sizepad
+ (char *, size_t, bfd_size_type);
+
+extern void *_bfd_generic_read_ar_hdr_mag
+ (bfd *, const char *);
+
+extern bfd_boolean _bfd_generic_write_ar_hdr
+ (bfd *, bfd *);
+
+extern bfd_boolean _bfd_bsd44_write_ar_hdr
+ (bfd *, bfd *);
+
+bfd * bfd_generic_openr_next_archived_file
+ (bfd *archive, bfd *last_file);
+
+int bfd_generic_stat_arch_elt
+ (bfd *, struct stat *);
+
+#define _bfd_read_ar_hdr(abfd) \
+ BFD_SEND (abfd, _bfd_read_ar_hdr_fn, (abfd))
+#define _bfd_write_ar_hdr(archive, abfd) \
+ BFD_SEND (abfd, _bfd_write_ar_hdr_fn, (archive, abfd))
+
+/* Generic routines to use for BFD_JUMP_TABLE_GENERIC. Use
+ BFD_JUMP_TABLE_GENERIC (_bfd_generic). */
+
+#define _bfd_generic_close_and_cleanup _bfd_archive_close_and_cleanup
+extern bfd_boolean _bfd_archive_close_and_cleanup
+ (bfd *);
+#define _bfd_generic_bfd_free_cached_info bfd_true
+extern bfd_boolean _bfd_generic_new_section_hook
+ (bfd *, asection *);
+extern bfd_boolean _bfd_generic_get_section_contents
+ (bfd *, asection *, void *, file_ptr, bfd_size_type);
+extern bfd_boolean _bfd_generic_get_section_contents_in_window
+ (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 \
+ ((bfd_boolean (*) (bfd *, bfd *)) bfd_true)
+#define _bfd_generic_bfd_merge_private_bfd_data \
+ ((bfd_boolean (*) (bfd *, bfd *)) bfd_true)
+#define _bfd_generic_bfd_set_private_flags \
+ ((bfd_boolean (*) (bfd *, flagword)) bfd_true)
+#define _bfd_generic_bfd_copy_private_section_data \
+ ((bfd_boolean (*) (bfd *, asection *, bfd *, asection *)) bfd_true)
+#define _bfd_generic_bfd_copy_private_symbol_data \
+ ((bfd_boolean (*) (bfd *, asymbol *, bfd *, asymbol *)) bfd_true)
+#define _bfd_generic_bfd_copy_private_header_data \
+ ((bfd_boolean (*) (bfd *, bfd *)) bfd_true)
+#define _bfd_generic_bfd_print_private_bfd_data \
+ ((bfd_boolean (*) (bfd *, void *)) bfd_true)
+
+extern bfd_boolean _bfd_generic_init_private_section_data
+ (bfd *, asection *, bfd *, asection *, struct bfd_link_info *);
+
+/* 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
+ (bfd *);
+extern int _bfd_nocore_core_file_failing_signal
+ (bfd *);
+extern bfd_boolean _bfd_nocore_core_file_matches_executable_p
+ (bfd *, bfd *);
+extern int _bfd_nocore_core_file_pid
+ (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 \
+ ((bfd_boolean (*) (bfd *, char **, bfd_size_type *, const char **)) \
+ bfd_false)
+#define _bfd_noarchive_truncate_arname \
+ ((void (*) (bfd *, const char *, char *)) bfd_void)
+#define _bfd_noarchive_write_armap \
+ ((bfd_boolean (*) (bfd *, unsigned int, struct orl *, unsigned int, int)) \
+ bfd_false)
+#define _bfd_noarchive_read_ar_hdr bfd_nullvoidptr
+#define _bfd_noarchive_write_ar_hdr \
+ ((bfd_boolean (*) (bfd *, bfd *)) bfd_false)
+#define _bfd_noarchive_openr_next_archived_file \
+ ((bfd *(*) (bfd *, bfd *)) bfd_nullvoidptr)
+#define _bfd_noarchive_get_elt_at_index \
+ ((bfd *(*) (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 bfd_boolean _bfd_archive_bsd_construct_extended_name_table
+ (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_write_ar_hdr _bfd_generic_write_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 bfd_boolean _bfd_archive_bsd_update_armap_timestamp
+ (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 bfd_boolean _bfd_archive_coff_construct_extended_name_table
+ (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_write_ar_hdr _bfd_generic_write_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_ARCHIVE to get BSD4.4 style
+ archives. Use BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_bsd44). */
+
+#define _bfd_archive_bsd44_slurp_armap bfd_slurp_bsd_armap
+#define _bfd_archive_bsd44_slurp_extended_name_table \
+ _bfd_slurp_extended_name_table
+extern bfd_boolean _bfd_archive_bsd44_construct_extended_name_table
+ (bfd *, char **, bfd_size_type *, const char **);
+#define _bfd_archive_bsd44_truncate_arname bfd_bsd_truncate_arname
+#define _bfd_archive_bsd44_write_armap bsd_write_armap
+#define _bfd_archive_bsd44_read_ar_hdr _bfd_generic_read_ar_hdr
+#define _bfd_archive_bsd44_write_ar_hdr _bfd_bsd44_write_ar_hdr
+#define _bfd_archive_bsd44_openr_next_archived_file \
+ bfd_generic_openr_next_archived_file
+#define _bfd_archive_bsd44_get_elt_at_index _bfd_generic_get_elt_at_index
+#define _bfd_archive_bsd44_generic_stat_arch_elt \
+ bfd_generic_stat_arch_elt
+#define _bfd_archive_bsd44_update_armap_timestamp \
+ _bfd_archive_bsd_update_armap_timestamp
+
+/* Routines to use for BFD_JUMP_TABLE_ARCHIVE to get VMS style
+ archives. Use BFD_JUMP_TABLE_ARCHIVE (_bfd_vms_lib). Some of them
+ are irrelevant and never called, so defined as NULL. */
+
+extern bfd_boolean _bfd_vms_lib_write_archive_contents (bfd *arch);
+#define _bfd_vms_lib_slurp_armap NULL
+#define _bfd_vms_lib_slurp_extended_name_table NULL
+#define _bfd_vms_lib_construct_extended_name_table NULL
+#define _bfd_vms_lib_truncate_arname NULL
+#define _bfd_vms_lib_write_armap NULL
+#define _bfd_vms_lib_read_ar_hdr NULL
+#define _bfd_vms_lib_write_ar_hdr NULL
+extern bfd *_bfd_vms_lib_openr_next_archived_file (bfd *, bfd *);
+extern bfd *_bfd_vms_lib_get_elt_at_index (bfd *, symindex);
+extern int _bfd_vms_lib_generic_stat_arch_elt (bfd *, struct stat *);
+#define _bfd_vms_lib_update_armap_timestamp bfd_true
+
+/* Extra routines for VMS style archives. */
+
+extern symindex _bfd_vms_lib_find_symbol (bfd *, const char *);
+extern bfd *_bfd_vms_lib_get_imagelib_file (bfd *);
+extern const bfd_target *_bfd_vms_lib_alpha_archive_p (bfd *abfd);
+extern const bfd_target *_bfd_vms_lib_ia64_archive_p (bfd *abfd);
+extern bfd_boolean _bfd_vms_lib_alpha_mkarchive (bfd *abfd);
+extern bfd_boolean _bfd_vms_lib_ia64_mkarchive (bfd *abfd);
+
+/* 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_canonicalize_symtab \
+ ((long (*) (bfd *, asymbol **)) _bfd_n1)
+#define _bfd_nosymbols_make_empty_symbol _bfd_generic_make_empty_symbol
+#define _bfd_nosymbols_print_symbol \
+ ((void (*) (bfd *, void *, asymbol *, bfd_print_symbol_type)) bfd_void)
+#define _bfd_nosymbols_get_symbol_info \
+ ((void (*) (bfd *, asymbol *, symbol_info *)) bfd_void)
+#define _bfd_nosymbols_bfd_is_local_label_name \
+ ((bfd_boolean (*) (bfd *, const char *)) bfd_false)
+#define _bfd_nosymbols_bfd_is_target_special_symbol \
+ ((bfd_boolean (*) (bfd *, asymbol *)) bfd_false)
+#define _bfd_nosymbols_get_lineno \
+ ((alent *(*) (bfd *, asymbol *)) bfd_nullvoidptr)
+#define _bfd_nosymbols_find_nearest_line \
+ ((bfd_boolean (*) (bfd *, asymbol **, asection *, bfd_vma, \
+ const char **, const char **, unsigned int *, \
+ unsigned int *)) \
+ bfd_false)
+#define _bfd_nosymbols_find_line \
+ ((bfd_boolean (*) (bfd *, asymbol **, asymbol *, \
+ const char **, unsigned int *)) \
+ bfd_false)
+#define _bfd_nosymbols_find_inliner_info \
+ ((bfd_boolean (*) (bfd *, const char **, const char **, unsigned int *)) \
+ bfd_false)
+#define _bfd_nosymbols_bfd_make_debug_symbol \
+ ((asymbol *(*) (bfd *, void *, unsigned long)) bfd_nullvoidptr)
+#define _bfd_nosymbols_read_minisymbols \
+ ((long (*) (bfd *, bfd_boolean, void **, unsigned int *)) _bfd_n1)
+#define _bfd_nosymbols_minisymbol_to_symbol \
+ ((asymbol *(*) (bfd *, bfd_boolean, const void *, asymbol *)) \
+ bfd_nullvoidptr)
+
+/* Routines to use for BFD_JUMP_TABLE_RELOCS when there is no reloc
+ support. Use BFD_JUMP_TABLE_RELOCS (_bfd_norelocs). */
+
+extern long _bfd_norelocs_get_reloc_upper_bound (bfd *, asection *);
+extern long _bfd_norelocs_canonicalize_reloc (bfd *, asection *,
+ arelent **, asymbol **);
+#define _bfd_norelocs_bfd_reloc_type_lookup \
+ ((reloc_howto_type *(*) (bfd *, bfd_reloc_code_real_type)) bfd_nullvoidptr)
+#define _bfd_norelocs_bfd_reloc_name_lookup \
+ ((reloc_howto_type *(*) (bfd *, const char *)) 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 \
+ ((bfd_boolean (*) (bfd *, enum bfd_architecture, unsigned long)) \
+ bfd_false)
+#define _bfd_nowrite_set_section_contents \
+ ((bfd_boolean (*) (bfd *, asection *, const void *, 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 bfd_boolean _bfd_generic_set_section_contents
+ (bfd *, asection *, const void *, 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 (*) (bfd *, struct bfd_link_info *)) bfd_0)
+#define _bfd_nolink_bfd_get_relocated_section_contents \
+ ((bfd_byte *(*) (bfd *, struct bfd_link_info *, struct bfd_link_order *, \
+ bfd_byte *, bfd_boolean, asymbol **)) \
+ bfd_nullvoidptr)
+#define _bfd_nolink_bfd_relax_section \
+ ((bfd_boolean (*) \
+ (bfd *, asection *, struct bfd_link_info *, bfd_boolean *)) \
+ bfd_false)
+#define _bfd_nolink_bfd_gc_sections \
+ ((bfd_boolean (*) (bfd *, struct bfd_link_info *)) \
+ bfd_false)
+#define _bfd_nolink_bfd_lookup_section_flags \
+ ((bfd_boolean (*) (struct bfd_link_info *, struct flag_info *, asection *)) \
+ bfd_0)
+#define _bfd_nolink_bfd_merge_sections \
+ ((bfd_boolean (*) (bfd *, struct bfd_link_info *)) \
+ bfd_false)
+#define _bfd_nolink_bfd_is_group_section \
+ ((bfd_boolean (*) (bfd *, const struct bfd_section *)) \
+ bfd_false)
+#define _bfd_nolink_bfd_discard_group \
+ ((bfd_boolean (*) (bfd *, struct bfd_section *)) \
+ bfd_false)
+#define _bfd_nolink_bfd_link_hash_table_create \
+ ((struct bfd_link_hash_table *(*) (bfd *)) bfd_nullvoidptr)
+#define _bfd_nolink_bfd_link_add_symbols \
+ ((bfd_boolean (*) (bfd *, struct bfd_link_info *)) bfd_false)
+#define _bfd_nolink_bfd_link_just_syms \
+ ((void (*) (asection *, struct bfd_link_info *)) bfd_void)
+#define _bfd_nolink_bfd_copy_link_hash_symbol_type \
+ ((void (*) (bfd *, struct bfd_link_hash_entry *, \
+ struct bfd_link_hash_entry *)) bfd_void)
+#define _bfd_nolink_bfd_final_link \
+ ((bfd_boolean (*) (bfd *, struct bfd_link_info *)) bfd_false)
+#define _bfd_nolink_bfd_link_split_section \
+ ((bfd_boolean (*) (bfd *, struct bfd_section *)) bfd_false)
+#define _bfd_nolink_section_already_linked \
+ ((bfd_boolean (*) (bfd *, asection *, \
+ struct bfd_link_info *)) bfd_false)
+#define _bfd_nolink_bfd_define_common_symbol \
+ ((bfd_boolean (*) (bfd *, struct bfd_link_info *, \
+ struct bfd_link_hash_entry *)) 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 (*) (bfd *, asymbol **)) _bfd_n1)
+#define _bfd_nodynamic_get_synthetic_symtab \
+ ((long (*) (bfd *, long, asymbol **, long, asymbol **, asymbol **)) _bfd_n1)
+#define _bfd_nodynamic_get_dynamic_reloc_upper_bound _bfd_n1
+#define _bfd_nodynamic_canonicalize_dynamic_reloc \
+ ((long (*) (bfd *, arelent **, asymbol **)) _bfd_n1)
+
+/* Generic routine to determine of the given symbol is a local
+ label. */
+extern bfd_boolean bfd_generic_is_local_label_name
+ (bfd *, const char *);
+
+/* Generic minisymbol routines. */
+extern long _bfd_generic_read_minisymbols
+ (bfd *, bfd_boolean, void **, unsigned int *);
+extern asymbol *_bfd_generic_minisymbol_to_symbol
+ (bfd *, bfd_boolean, const void *, asymbol *);
+
+/* Find the nearest line using .stab/.stabstr sections. */
+extern bfd_boolean _bfd_stab_section_find_nearest_line
+ (bfd *, asymbol **, asection *, bfd_vma, bfd_boolean *,
+ const char **, const char **, unsigned int *, void **);
+
+/* Find the nearest line using DWARF 1 debugging information. */
+extern bfd_boolean _bfd_dwarf1_find_nearest_line
+ (bfd *, asymbol **, asection *, bfd_vma,
+ const char **, const char **, unsigned int *);
+
+struct dwarf_debug_section
+{
+ const char *uncompressed_name;
+ const char *compressed_name;
+};
+
+/* Map of uncompressed DWARF debug section name to compressed one. It
+ is terminated by NULL uncompressed_name. */
+
+extern const struct dwarf_debug_section dwarf_debug_sections[];
+
+/* Find the nearest line using DWARF 2 debugging information. */
+extern bfd_boolean _bfd_dwarf2_find_nearest_line
+ (bfd *, asymbol **, asymbol *, asection *, bfd_vma,
+ const char **, const char **, unsigned int *, unsigned int *,
+ const struct dwarf_debug_section *, unsigned int, void **);
+
+/* Find inliner info after calling bfd_find_nearest_line. */
+extern bfd_boolean _bfd_dwarf2_find_inliner_info
+ (bfd *, const char **, const char **, unsigned int *, void **);
+
+/* Read DWARF 2 debugging information. */
+extern bfd_boolean _bfd_dwarf2_slurp_debug_info
+ (bfd *, bfd *, const struct dwarf_debug_section *, asymbol **, void **,
+ bfd_boolean);
+
+/* Clean up the data used to handle DWARF 2 debugging information. */
+extern void _bfd_dwarf2_cleanup_debug_info
+ (bfd *, void **);
+
+/* Create a new section entry. */
+extern struct bfd_hash_entry *bfd_section_hash_newfunc
+ (struct bfd_hash_entry *, struct bfd_hash_table *, const char *);
+
+/* A routine to create entries for a bfd_link_hash_table. */
+extern struct bfd_hash_entry *_bfd_link_hash_newfunc
+ (struct bfd_hash_entry *entry, struct bfd_hash_table *table,
+ const char *string);
+
+/* Initialize a bfd_link_hash_table. */
+extern bfd_boolean _bfd_link_hash_table_init
+ (struct bfd_link_hash_table *, bfd *,
+ struct bfd_hash_entry *(*) (struct bfd_hash_entry *,
+ struct bfd_hash_table *,
+ const char *),
+ unsigned int);
+
+/* Generic link hash table creation routine. */
+extern struct bfd_link_hash_table *_bfd_generic_link_hash_table_create
+ (bfd *);
+
+/* Generic link hash table destruction routine. */
+extern void _bfd_generic_link_hash_table_free
+ (bfd *);
+
+/* Generic add symbol routine. */
+extern bfd_boolean _bfd_generic_link_add_symbols
+ (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 bfd_boolean _bfd_generic_link_add_symbols_collect
+ (bfd *, struct bfd_link_info *);
+
+/* Generic archive add symbol routine. */
+extern bfd_boolean _bfd_generic_link_add_archive_symbols
+ (bfd *, struct bfd_link_info *,
+ bfd_boolean (*) (bfd *, struct bfd_link_info *,
+ struct bfd_link_hash_entry *, const char *,
+ bfd_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 bfd_boolean _bfd_generic_link_add_one_symbol
+ (struct bfd_link_info *, bfd *, const char *name, flagword,
+ asection *, bfd_vma, const char *, bfd_boolean copy,
+ bfd_boolean constructor, struct bfd_link_hash_entry **);
+
+/* Generic routine to mark section as supplying symbols only. */
+extern void _bfd_generic_link_just_syms
+ (asection *, struct bfd_link_info *);
+
+/* Generic routine that does nothing. */
+extern void _bfd_generic_copy_link_hash_symbol_type
+ (bfd *, struct bfd_link_hash_entry *, struct bfd_link_hash_entry *);
+
+/* Generic link routine. */
+extern bfd_boolean _bfd_generic_final_link
+ (bfd *, struct bfd_link_info *);
+
+extern bfd_boolean _bfd_generic_link_split_section
+ (bfd *, struct bfd_section *);
+
+extern bfd_boolean _bfd_generic_section_already_linked
+ (bfd *, asection *, struct bfd_link_info *);
+
+/* Generic reloc_link_order processing routine. */
+extern bfd_boolean _bfd_generic_reloc_link_order
+ (bfd *, struct bfd_link_info *, asection *, struct bfd_link_order *);
+
+/* Default link order processing routine. */
+extern bfd_boolean _bfd_default_link_order
+ (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
+ (struct bfd_link_order *);
+
+/* Final link relocation routine. */
+extern bfd_reloc_status_type _bfd_final_link_relocate
+ (reloc_howto_type *, bfd *, asection *, bfd_byte *,
+ bfd_vma, bfd_vma, bfd_vma);
+
+/* Relocate a particular location by a howto and a value. */
+extern bfd_reloc_status_type _bfd_relocate_contents
+ (reloc_howto_type *, bfd *, bfd_vma, bfd_byte *);
+
+/* Clear a given location using a given howto. */
+extern void _bfd_clear_contents (reloc_howto_type *howto, bfd *input_bfd,
+ asection *input_section, bfd_byte *location);
+
+/* Link stabs in sections in the first pass. */
+
+extern bfd_boolean _bfd_link_section_stabs
+ (bfd *, struct stab_info *, asection *, asection *, void **,
+ bfd_size_type *);
+
+/* Eliminate stabs for discarded functions and symbols. */
+extern bfd_boolean _bfd_discard_section_stabs
+ (bfd *, asection *, void *, bfd_boolean (*) (bfd_vma, void *), void *);
+
+/* Write out the .stab section when linking stabs in sections. */
+
+extern bfd_boolean _bfd_write_section_stabs
+ (bfd *, struct stab_info *, asection *, void **, bfd_byte *);
+
+/* Write out the .stabstr string table when linking stabs in sections. */
+
+extern bfd_boolean _bfd_write_stab_strings
+ (bfd *, struct stab_info *);
+
+/* Find an offset within a .stab section when linking stabs in
+ sections. */
+
+extern bfd_vma _bfd_stab_section_offset
+ (asection *, void *, bfd_vma);
+
+/* Register a SEC_MERGE section as a candidate for merging. */
+
+extern bfd_boolean _bfd_add_merge_section
+ (bfd *, void **, asection *, void **);
+
+/* Attempt to merge SEC_MERGE sections. */
+
+extern bfd_boolean _bfd_merge_sections
+ (bfd *, struct bfd_link_info *, void *, void (*) (bfd *, asection *));
+
+/* Write out a merged section. */
+
+extern bfd_boolean _bfd_write_merged_section
+ (bfd *, asection *, void *);
+
+/* Find an offset within a modified SEC_MERGE section. */
+
+extern bfd_vma _bfd_merged_section_offset
+ (bfd *, asection **, void *, bfd_vma);
+
+/* Tidy up when done. */
+
+extern void _bfd_merge_sections_free (void *);
+
+/* Create a string table. */
+extern struct bfd_strtab_hash *_bfd_stringtab_init
+ (void);
+
+/* Create an XCOFF .debug section style string table. */
+extern struct bfd_strtab_hash *_bfd_xcoff_stringtab_init
+ (void);
+
+/* Free a string table. */
+extern void _bfd_stringtab_free
+ (struct bfd_strtab_hash *);
+
+/* Get the size of a string table. */
+extern bfd_size_type _bfd_stringtab_size
+ (struct bfd_strtab_hash *);
+
+/* Add a string to a string table. */
+extern bfd_size_type _bfd_stringtab_add
+ (struct bfd_strtab_hash *, const char *, bfd_boolean hash, bfd_boolean copy);
+
+/* Write out a string table. */
+extern bfd_boolean _bfd_stringtab_emit
+ (bfd *, struct bfd_strtab_hash *);
+
+/* Check that endianness of input and output file match. */
+extern bfd_boolean _bfd_generic_verify_endian_match
+ (bfd *, bfd *);
+
+/* 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
+ (const char*,int);
+
+#define BFD_ASSERT(x) \
+ do { if (!(x)) bfd_assert(__FILE__,__LINE__); } while (0)
+
+#define BFD_FAIL() \
+ do { bfd_assert(__FILE__,__LINE__); } while (0)
+
+extern void _bfd_abort
+ (const char *, int, const char *) ATTRIBUTE_NORETURN;
+
+/* if gcc >= 2.6, we can give a function name, too */
+#if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 6)
+#define __PRETTY_FUNCTION__ ((char *) NULL)
+#endif
+
+#undef abort
+#define abort() _bfd_abort (__FILE__, __LINE__, __PRETTY_FUNCTION__)
+
+/* Manipulate a system FILE but using BFD's "file_ptr", rather than
+ the system "off_t" or "off64_t", as the offset. */
+extern file_ptr real_ftell (FILE *file);
+extern int real_fseek (FILE *file, file_ptr offset, int whence);
+extern FILE *real_fopen (const char *filename, const char *modes);
+
+/* 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[];
+
+/* List of associated target vectors. */
+extern const bfd_target * const *bfd_associated_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 bfd_boolean _bfd_ecoff_locate_line
+ (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 bfd_boolean _bfd_ecoff_get_accumulated_pdr
+ (void *, bfd_byte *);
+extern bfd_boolean _bfd_ecoff_get_accumulated_sym
+ (void *, bfd_byte *);
+extern bfd_boolean _bfd_ecoff_get_accumulated_ss
+ (void *, bfd_byte *);
+
+extern bfd_vma _bfd_get_gp_value
+ (bfd *);
+extern void _bfd_set_gp_value
+ (bfd *, bfd_vma);
+
+/* Function shared by the COFF and ELF SH backends, which have no
+ other common header files. */
+
+#ifndef _bfd_sh_align_load_span
+extern bfd_boolean _bfd_sh_align_load_span
+ (bfd *, asection *, bfd_byte *,
+ bfd_boolean (*) (bfd *, asection *, void *, bfd_byte *, bfd_vma),
+ void *, bfd_vma **, bfd_vma *, bfd_vma, bfd_vma, bfd_boolean *);
+#endif
+
+/* This is the shape of the elements inside the already_linked hash
+ table. It maps a name onto a list of already_linked elements with
+ the same name. */
+
+struct bfd_section_already_linked_hash_entry
+{
+ struct bfd_hash_entry root;
+ struct bfd_section_already_linked *entry;
+};
+
+struct bfd_section_already_linked
+{
+ struct bfd_section_already_linked *next;
+ asection *sec;
+};
+
+extern struct bfd_section_already_linked_hash_entry *
+ bfd_section_already_linked_table_lookup (const char *);
+extern bfd_boolean bfd_section_already_linked_table_insert
+ (struct bfd_section_already_linked_hash_entry *, asection *);
+extern void bfd_section_already_linked_table_traverse
+ (bfd_boolean (*) (struct bfd_section_already_linked_hash_entry *,
+ void *), void *);
+
+extern bfd_vma read_unsigned_leb128 (bfd *, bfd_byte *, unsigned int *);
+extern bfd_signed_vma read_signed_leb128 (bfd *, bfd_byte *, unsigned int *);
+/* Extracted from init.c. */
+/* Extracted from libbfd.c. */
+bfd_boolean bfd_write_bigendian_4byte_int (bfd *, unsigned int);
+
+unsigned int bfd_log2 (bfd_vma x);
+
+/* Extracted from bfdio.c. */
+struct bfd_iovec
+{
+ /* To avoid problems with macros, a "b" rather than "f"
+ prefix is prepended to each method name. */
+ /* Attempt to read/write NBYTES on ABFD's IOSTREAM storing/fetching
+ bytes starting at PTR. Return the number of bytes actually
+ transfered (a read past end-of-file returns less than NBYTES),
+ or -1 (setting <<bfd_error>>) if an error occurs. */
+ file_ptr (*bread) (struct bfd *abfd, void *ptr, file_ptr nbytes);
+ file_ptr (*bwrite) (struct bfd *abfd, const void *ptr,
+ file_ptr nbytes);
+ /* Return the current IOSTREAM file offset, or -1 (setting <<bfd_error>>
+ if an error occurs. */
+ file_ptr (*btell) (struct bfd *abfd);
+ /* For the following, on successful completion a value of 0 is returned.
+ Otherwise, a value of -1 is returned (and <<bfd_error>> is set). */
+ int (*bseek) (struct bfd *abfd, file_ptr offset, int whence);
+ int (*bclose) (struct bfd *abfd);
+ int (*bflush) (struct bfd *abfd);
+ int (*bstat) (struct bfd *abfd, struct stat *sb);
+ /* Mmap a part of the files. ADDR, LEN, PROT, FLAGS and OFFSET are the usual
+ mmap parameter, except that LEN and OFFSET do not need to be page
+ aligned. Returns (void *)-1 on failure, mmapped address on success.
+ Also write in MAP_ADDR the address of the page aligned buffer and in
+ MAP_LEN the size mapped (a page multiple). Use unmap with MAP_ADDR and
+ MAP_LEN to unmap. */
+ void *(*bmmap) (struct bfd *abfd, void *addr, bfd_size_type len,
+ int prot, int flags, file_ptr offset,
+ void **map_addr, bfd_size_type *map_len);
+};
+extern const struct bfd_iovec _bfd_memory_iovec;
+/* Extracted from bfdwin.c. */
+struct _bfd_window_internal {
+ struct _bfd_window_internal *next;
+ void *data;
+ bfd_size_type size;
+ int refcount : 31; /* should be enough... */
+ unsigned mapped : 1; /* 1 = mmap, 0 = malloc */
+};
+/* Extracted from cache.c. */
+bfd_boolean bfd_cache_init (bfd *abfd);
+
+bfd_boolean bfd_cache_close (bfd *abfd);
+
+FILE* bfd_open_file (bfd *abfd);
+
+/* Extracted from reloc.c. */
+#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_SECREL",
+ "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_64_PLT_PCREL",
+ "BFD_RELOC_32_PLT_PCREL",
+ "BFD_RELOC_24_PLT_PCREL",
+ "BFD_RELOC_16_PLT_PCREL",
+ "BFD_RELOC_8_PLT_PCREL",
+ "BFD_RELOC_64_PLTOFF",
+ "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_SIZE32",
+ "BFD_RELOC_SIZE64",
+ "BFD_RELOC_68K_GLOB_DAT",
+ "BFD_RELOC_68K_JMP_SLOT",
+ "BFD_RELOC_68K_RELATIVE",
+ "BFD_RELOC_68K_TLS_GD32",
+ "BFD_RELOC_68K_TLS_GD16",
+ "BFD_RELOC_68K_TLS_GD8",
+ "BFD_RELOC_68K_TLS_LDM32",
+ "BFD_RELOC_68K_TLS_LDM16",
+ "BFD_RELOC_68K_TLS_LDM8",
+ "BFD_RELOC_68K_TLS_LDO32",
+ "BFD_RELOC_68K_TLS_LDO16",
+ "BFD_RELOC_68K_TLS_LDO8",
+ "BFD_RELOC_68K_TLS_IE32",
+ "BFD_RELOC_68K_TLS_IE16",
+ "BFD_RELOC_68K_TLS_IE8",
+ "BFD_RELOC_68K_TLS_LE32",
+ "BFD_RELOC_68K_TLS_LE16",
+ "BFD_RELOC_68K_TLS_LE8",
+ "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_UA16",
+ "BFD_RELOC_SPARC_UA32",
+ "BFD_RELOC_SPARC_UA64",
+ "BFD_RELOC_SPARC_GOTDATA_HIX22",
+ "BFD_RELOC_SPARC_GOTDATA_LOX10",
+ "BFD_RELOC_SPARC_GOTDATA_OP_HIX22",
+ "BFD_RELOC_SPARC_GOTDATA_OP_LOX10",
+ "BFD_RELOC_SPARC_GOTDATA_OP",
+ "BFD_RELOC_SPARC_JMP_IREL",
+ "BFD_RELOC_SPARC_IRELATIVE",
+ "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_PLT32",
+ "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_H34",
+ "BFD_RELOC_SPARC_SIZE32",
+ "BFD_RELOC_SPARC_SIZE64",
+ "BFD_RELOC_SPARC_WDISP10",
+ "BFD_RELOC_SPARC_REV32",
+ "BFD_RELOC_SPARC_TLS_GD_HI22",
+ "BFD_RELOC_SPARC_TLS_GD_LO10",
+ "BFD_RELOC_SPARC_TLS_GD_ADD",
+ "BFD_RELOC_SPARC_TLS_GD_CALL",
+ "BFD_RELOC_SPARC_TLS_LDM_HI22",
+ "BFD_RELOC_SPARC_TLS_LDM_LO10",
+ "BFD_RELOC_SPARC_TLS_LDM_ADD",
+ "BFD_RELOC_SPARC_TLS_LDM_CALL",
+ "BFD_RELOC_SPARC_TLS_LDO_HIX22",
+ "BFD_RELOC_SPARC_TLS_LDO_LOX10",
+ "BFD_RELOC_SPARC_TLS_LDO_ADD",
+ "BFD_RELOC_SPARC_TLS_IE_HI22",
+ "BFD_RELOC_SPARC_TLS_IE_LO10",
+ "BFD_RELOC_SPARC_TLS_IE_LD",
+ "BFD_RELOC_SPARC_TLS_IE_LDX",
+ "BFD_RELOC_SPARC_TLS_IE_ADD",
+ "BFD_RELOC_SPARC_TLS_LE_HIX22",
+ "BFD_RELOC_SPARC_TLS_LE_LOX10",
+ "BFD_RELOC_SPARC_TLS_DTPMOD32",
+ "BFD_RELOC_SPARC_TLS_DTPMOD64",
+ "BFD_RELOC_SPARC_TLS_DTPOFF32",
+ "BFD_RELOC_SPARC_TLS_DTPOFF64",
+ "BFD_RELOC_SPARC_TLS_TPOFF32",
+ "BFD_RELOC_SPARC_TLS_TPOFF64",
+ "BFD_RELOC_SPU_IMM7",
+ "BFD_RELOC_SPU_IMM8",
+ "BFD_RELOC_SPU_IMM10",
+ "BFD_RELOC_SPU_IMM10W",
+ "BFD_RELOC_SPU_IMM16",
+ "BFD_RELOC_SPU_IMM16W",
+ "BFD_RELOC_SPU_IMM18",
+ "BFD_RELOC_SPU_PCREL9a",
+ "BFD_RELOC_SPU_PCREL9b",
+ "BFD_RELOC_SPU_PCREL16",
+ "BFD_RELOC_SPU_LO16",
+ "BFD_RELOC_SPU_HI16",
+ "BFD_RELOC_SPU_PPU32",
+ "BFD_RELOC_SPU_PPU64",
+ "BFD_RELOC_SPU_ADD_PIC",
+ "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_ALPHA_GPREL_HI16",
+ "BFD_RELOC_ALPHA_GPREL_LO16",
+ "BFD_RELOC_ALPHA_BRSGP",
+ "BFD_RELOC_ALPHA_NOP",
+ "BFD_RELOC_ALPHA_BSR",
+ "BFD_RELOC_ALPHA_LDA",
+ "BFD_RELOC_ALPHA_BOH",
+ "BFD_RELOC_ALPHA_TLSGD",
+ "BFD_RELOC_ALPHA_TLSLDM",
+ "BFD_RELOC_ALPHA_DTPMOD64",
+ "BFD_RELOC_ALPHA_GOTDTPREL16",
+ "BFD_RELOC_ALPHA_DTPREL64",
+ "BFD_RELOC_ALPHA_DTPREL_HI16",
+ "BFD_RELOC_ALPHA_DTPREL_LO16",
+ "BFD_RELOC_ALPHA_DTPREL16",
+ "BFD_RELOC_ALPHA_GOTTPREL16",
+ "BFD_RELOC_ALPHA_TPREL64",
+ "BFD_RELOC_ALPHA_TPREL_HI16",
+ "BFD_RELOC_ALPHA_TPREL_LO16",
+ "BFD_RELOC_ALPHA_TPREL16",
+ "BFD_RELOC_MIPS_JMP",
+ "BFD_RELOC_MICROMIPS_JMP",
+ "BFD_RELOC_MIPS16_JMP",
+ "BFD_RELOC_MIPS16_GPREL",
+ "BFD_RELOC_HI16",
+ "BFD_RELOC_HI16_S",
+ "BFD_RELOC_LO16",
+ "BFD_RELOC_HI16_PCREL",
+ "BFD_RELOC_HI16_S_PCREL",
+ "BFD_RELOC_LO16_PCREL",
+ "BFD_RELOC_MIPS16_GOT16",
+ "BFD_RELOC_MIPS16_CALL16",
+ "BFD_RELOC_MIPS16_HI16",
+ "BFD_RELOC_MIPS16_HI16_S",
+ "BFD_RELOC_MIPS16_LO16",
+ "BFD_RELOC_MIPS16_TLS_GD",
+ "BFD_RELOC_MIPS16_TLS_LDM",
+ "BFD_RELOC_MIPS16_TLS_DTPREL_HI16",
+ "BFD_RELOC_MIPS16_TLS_DTPREL_LO16",
+ "BFD_RELOC_MIPS16_TLS_GOTTPREL",
+ "BFD_RELOC_MIPS16_TLS_TPREL_HI16",
+ "BFD_RELOC_MIPS16_TLS_TPREL_LO16",
+ "BFD_RELOC_MIPS_LITERAL",
+ "BFD_RELOC_MICROMIPS_LITERAL",
+ "BFD_RELOC_MICROMIPS_7_PCREL_S1",
+ "BFD_RELOC_MICROMIPS_10_PCREL_S1",
+ "BFD_RELOC_MICROMIPS_16_PCREL_S1",
+ "BFD_RELOC_MIPS_21_PCREL_S2",
+ "BFD_RELOC_MIPS_26_PCREL_S2",
+ "BFD_RELOC_MIPS_18_PCREL_S3",
+ "BFD_RELOC_MIPS_19_PCREL_S2",
+ "BFD_RELOC_MICROMIPS_GPREL16",
+ "BFD_RELOC_MICROMIPS_HI16",
+ "BFD_RELOC_MICROMIPS_HI16_S",
+ "BFD_RELOC_MICROMIPS_LO16",
+ "BFD_RELOC_MIPS_GOT16",
+ "BFD_RELOC_MICROMIPS_GOT16",
+ "BFD_RELOC_MIPS_CALL16",
+ "BFD_RELOC_MICROMIPS_CALL16",
+ "BFD_RELOC_MIPS_GOT_HI16",
+ "BFD_RELOC_MICROMIPS_GOT_HI16",
+ "BFD_RELOC_MIPS_GOT_LO16",
+ "BFD_RELOC_MICROMIPS_GOT_LO16",
+ "BFD_RELOC_MIPS_CALL_HI16",
+ "BFD_RELOC_MICROMIPS_CALL_HI16",
+ "BFD_RELOC_MIPS_CALL_LO16",
+ "BFD_RELOC_MICROMIPS_CALL_LO16",
+ "BFD_RELOC_MIPS_SUB",
+ "BFD_RELOC_MICROMIPS_SUB",
+ "BFD_RELOC_MIPS_GOT_PAGE",
+ "BFD_RELOC_MICROMIPS_GOT_PAGE",
+ "BFD_RELOC_MIPS_GOT_OFST",
+ "BFD_RELOC_MICROMIPS_GOT_OFST",
+ "BFD_RELOC_MIPS_GOT_DISP",
+ "BFD_RELOC_MICROMIPS_GOT_DISP",
+ "BFD_RELOC_MIPS_SHIFT5",
+ "BFD_RELOC_MIPS_SHIFT6",
+ "BFD_RELOC_MIPS_INSERT_A",
+ "BFD_RELOC_MIPS_INSERT_B",
+ "BFD_RELOC_MIPS_DELETE",
+ "BFD_RELOC_MIPS_HIGHEST",
+ "BFD_RELOC_MICROMIPS_HIGHEST",
+ "BFD_RELOC_MIPS_HIGHER",
+ "BFD_RELOC_MICROMIPS_HIGHER",
+ "BFD_RELOC_MIPS_SCN_DISP",
+ "BFD_RELOC_MICROMIPS_SCN_DISP",
+ "BFD_RELOC_MIPS_REL16",
+ "BFD_RELOC_MIPS_RELGOT",
+ "BFD_RELOC_MIPS_JALR",
+ "BFD_RELOC_MICROMIPS_JALR",
+ "BFD_RELOC_MIPS_TLS_DTPMOD32",
+ "BFD_RELOC_MIPS_TLS_DTPREL32",
+ "BFD_RELOC_MIPS_TLS_DTPMOD64",
+ "BFD_RELOC_MIPS_TLS_DTPREL64",
+ "BFD_RELOC_MIPS_TLS_GD",
+ "BFD_RELOC_MICROMIPS_TLS_GD",
+ "BFD_RELOC_MIPS_TLS_LDM",
+ "BFD_RELOC_MICROMIPS_TLS_LDM",
+ "BFD_RELOC_MIPS_TLS_DTPREL_HI16",
+ "BFD_RELOC_MICROMIPS_TLS_DTPREL_HI16",
+ "BFD_RELOC_MIPS_TLS_DTPREL_LO16",
+ "BFD_RELOC_MICROMIPS_TLS_DTPREL_LO16",
+ "BFD_RELOC_MIPS_TLS_GOTTPREL",
+ "BFD_RELOC_MICROMIPS_TLS_GOTTPREL",
+ "BFD_RELOC_MIPS_TLS_TPREL32",
+ "BFD_RELOC_MIPS_TLS_TPREL64",
+ "BFD_RELOC_MIPS_TLS_TPREL_HI16",
+ "BFD_RELOC_MICROMIPS_TLS_TPREL_HI16",
+ "BFD_RELOC_MIPS_TLS_TPREL_LO16",
+ "BFD_RELOC_MICROMIPS_TLS_TPREL_LO16",
+ "BFD_RELOC_MIPS_EH",
+
+ "BFD_RELOC_MIPS_COPY",
+ "BFD_RELOC_MIPS_JUMP_SLOT",
+
+ "BFD_RELOC_MOXIE_10_PCREL",
+
+ "BFD_RELOC_FRV_LABEL16",
+ "BFD_RELOC_FRV_LABEL24",
+ "BFD_RELOC_FRV_LO16",
+ "BFD_RELOC_FRV_HI16",
+ "BFD_RELOC_FRV_GPREL12",
+ "BFD_RELOC_FRV_GPRELU12",
+ "BFD_RELOC_FRV_GPREL32",
+ "BFD_RELOC_FRV_GPRELHI",
+ "BFD_RELOC_FRV_GPRELLO",
+ "BFD_RELOC_FRV_GOT12",
+ "BFD_RELOC_FRV_GOTHI",
+ "BFD_RELOC_FRV_GOTLO",
+ "BFD_RELOC_FRV_FUNCDESC",
+ "BFD_RELOC_FRV_FUNCDESC_GOT12",
+ "BFD_RELOC_FRV_FUNCDESC_GOTHI",
+ "BFD_RELOC_FRV_FUNCDESC_GOTLO",
+ "BFD_RELOC_FRV_FUNCDESC_VALUE",
+ "BFD_RELOC_FRV_FUNCDESC_GOTOFF12",
+ "BFD_RELOC_FRV_FUNCDESC_GOTOFFHI",
+ "BFD_RELOC_FRV_FUNCDESC_GOTOFFLO",
+ "BFD_RELOC_FRV_GOTOFF12",
+ "BFD_RELOC_FRV_GOTOFFHI",
+ "BFD_RELOC_FRV_GOTOFFLO",
+ "BFD_RELOC_FRV_GETTLSOFF",
+ "BFD_RELOC_FRV_TLSDESC_VALUE",
+ "BFD_RELOC_FRV_GOTTLSDESC12",
+ "BFD_RELOC_FRV_GOTTLSDESCHI",
+ "BFD_RELOC_FRV_GOTTLSDESCLO",
+ "BFD_RELOC_FRV_TLSMOFF12",
+ "BFD_RELOC_FRV_TLSMOFFHI",
+ "BFD_RELOC_FRV_TLSMOFFLO",
+ "BFD_RELOC_FRV_GOTTLSOFF12",
+ "BFD_RELOC_FRV_GOTTLSOFFHI",
+ "BFD_RELOC_FRV_GOTTLSOFFLO",
+ "BFD_RELOC_FRV_TLSOFF",
+ "BFD_RELOC_FRV_TLSDESC_RELAX",
+ "BFD_RELOC_FRV_GETTLSOFF_RELAX",
+ "BFD_RELOC_FRV_TLSOFF_RELAX",
+ "BFD_RELOC_FRV_TLSMOFF",
+
+ "BFD_RELOC_MN10300_GOTOFF24",
+ "BFD_RELOC_MN10300_GOT32",
+ "BFD_RELOC_MN10300_GOT24",
+ "BFD_RELOC_MN10300_GOT16",
+ "BFD_RELOC_MN10300_COPY",
+ "BFD_RELOC_MN10300_GLOB_DAT",
+ "BFD_RELOC_MN10300_JMP_SLOT",
+ "BFD_RELOC_MN10300_RELATIVE",
+ "BFD_RELOC_MN10300_SYM_DIFF",
+ "BFD_RELOC_MN10300_ALIGN",
+ "BFD_RELOC_MN10300_TLS_GD",
+ "BFD_RELOC_MN10300_TLS_LD",
+ "BFD_RELOC_MN10300_TLS_LDO",
+ "BFD_RELOC_MN10300_TLS_GOTIE",
+ "BFD_RELOC_MN10300_TLS_IE",
+ "BFD_RELOC_MN10300_TLS_LE",
+ "BFD_RELOC_MN10300_TLS_DTPMOD",
+ "BFD_RELOC_MN10300_TLS_DTPOFF",
+ "BFD_RELOC_MN10300_TLS_TPOFF",
+ "BFD_RELOC_MN10300_32_PCREL",
+ "BFD_RELOC_MN10300_16_PCREL",
+
+ "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_386_TLS_TPOFF",
+ "BFD_RELOC_386_TLS_IE",
+ "BFD_RELOC_386_TLS_GOTIE",
+ "BFD_RELOC_386_TLS_LE",
+ "BFD_RELOC_386_TLS_GD",
+ "BFD_RELOC_386_TLS_LDM",
+ "BFD_RELOC_386_TLS_LDO_32",
+ "BFD_RELOC_386_TLS_IE_32",
+ "BFD_RELOC_386_TLS_LE_32",
+ "BFD_RELOC_386_TLS_DTPMOD32",
+ "BFD_RELOC_386_TLS_DTPOFF32",
+ "BFD_RELOC_386_TLS_TPOFF32",
+ "BFD_RELOC_386_TLS_GOTDESC",
+ "BFD_RELOC_386_TLS_DESC_CALL",
+ "BFD_RELOC_386_TLS_DESC",
+ "BFD_RELOC_386_IRELATIVE",
+ "BFD_RELOC_X86_64_GOT32",
+ "BFD_RELOC_X86_64_PLT32",
+ "BFD_RELOC_X86_64_COPY",
+ "BFD_RELOC_X86_64_GLOB_DAT",
+ "BFD_RELOC_X86_64_JUMP_SLOT",
+ "BFD_RELOC_X86_64_RELATIVE",
+ "BFD_RELOC_X86_64_GOTPCREL",
+ "BFD_RELOC_X86_64_32S",
+ "BFD_RELOC_X86_64_DTPMOD64",
+ "BFD_RELOC_X86_64_DTPOFF64",
+ "BFD_RELOC_X86_64_TPOFF64",
+ "BFD_RELOC_X86_64_TLSGD",
+ "BFD_RELOC_X86_64_TLSLD",
+ "BFD_RELOC_X86_64_DTPOFF32",
+ "BFD_RELOC_X86_64_GOTTPOFF",
+ "BFD_RELOC_X86_64_TPOFF32",
+ "BFD_RELOC_X86_64_GOTOFF64",
+ "BFD_RELOC_X86_64_GOTPC32",
+ "BFD_RELOC_X86_64_GOT64",
+ "BFD_RELOC_X86_64_GOTPCREL64",
+ "BFD_RELOC_X86_64_GOTPC64",
+ "BFD_RELOC_X86_64_GOTPLT64",
+ "BFD_RELOC_X86_64_PLTOFF64",
+ "BFD_RELOC_X86_64_GOTPC32_TLSDESC",
+ "BFD_RELOC_X86_64_TLSDESC_CALL",
+ "BFD_RELOC_X86_64_TLSDESC",
+ "BFD_RELOC_X86_64_IRELATIVE",
+ "BFD_RELOC_X86_64_PC32_BND",
+ "BFD_RELOC_X86_64_PLT32_BND",
+ "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_PDP11_DISP_8_PCREL",
+ "BFD_RELOC_PDP11_DISP_6_PCREL",
+ "BFD_RELOC_PJ_CODE_HI16",
+ "BFD_RELOC_PJ_CODE_LO16",
+ "BFD_RELOC_PJ_CODE_DIR16",
+ "BFD_RELOC_PJ_CODE_DIR32",
+ "BFD_RELOC_PJ_CODE_REL16",
+ "BFD_RELOC_PJ_CODE_REL32",
+ "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_PPC_VLE_REL8",
+ "BFD_RELOC_PPC_VLE_REL15",
+ "BFD_RELOC_PPC_VLE_REL24",
+ "BFD_RELOC_PPC_VLE_LO16A",
+ "BFD_RELOC_PPC_VLE_LO16D",
+ "BFD_RELOC_PPC_VLE_HI16A",
+ "BFD_RELOC_PPC_VLE_HI16D",
+ "BFD_RELOC_PPC_VLE_HA16A",
+ "BFD_RELOC_PPC_VLE_HA16D",
+ "BFD_RELOC_PPC_VLE_SDA21",
+ "BFD_RELOC_PPC_VLE_SDA21_LO",
+ "BFD_RELOC_PPC_VLE_SDAREL_LO16A",
+ "BFD_RELOC_PPC_VLE_SDAREL_LO16D",
+ "BFD_RELOC_PPC_VLE_SDAREL_HI16A",
+ "BFD_RELOC_PPC_VLE_SDAREL_HI16D",
+ "BFD_RELOC_PPC_VLE_SDAREL_HA16A",
+ "BFD_RELOC_PPC_VLE_SDAREL_HA16D",
+ "BFD_RELOC_PPC64_HIGHER",
+ "BFD_RELOC_PPC64_HIGHER_S",
+ "BFD_RELOC_PPC64_HIGHEST",
+ "BFD_RELOC_PPC64_HIGHEST_S",
+ "BFD_RELOC_PPC64_TOC16_LO",
+ "BFD_RELOC_PPC64_TOC16_HI",
+ "BFD_RELOC_PPC64_TOC16_HA",
+ "BFD_RELOC_PPC64_TOC",
+ "BFD_RELOC_PPC64_PLTGOT16",
+ "BFD_RELOC_PPC64_PLTGOT16_LO",
+ "BFD_RELOC_PPC64_PLTGOT16_HI",
+ "BFD_RELOC_PPC64_PLTGOT16_HA",
+ "BFD_RELOC_PPC64_ADDR16_DS",
+ "BFD_RELOC_PPC64_ADDR16_LO_DS",
+ "BFD_RELOC_PPC64_GOT16_DS",
+ "BFD_RELOC_PPC64_GOT16_LO_DS",
+ "BFD_RELOC_PPC64_PLT16_LO_DS",
+ "BFD_RELOC_PPC64_SECTOFF_DS",
+ "BFD_RELOC_PPC64_SECTOFF_LO_DS",
+ "BFD_RELOC_PPC64_TOC16_DS",
+ "BFD_RELOC_PPC64_TOC16_LO_DS",
+ "BFD_RELOC_PPC64_PLTGOT16_DS",
+ "BFD_RELOC_PPC64_PLTGOT16_LO_DS",
+ "BFD_RELOC_PPC64_ADDR16_HIGH",
+ "BFD_RELOC_PPC64_ADDR16_HIGHA",
+ "BFD_RELOC_PPC64_ADDR64_LOCAL",
+ "BFD_RELOC_PPC_TLS",
+ "BFD_RELOC_PPC_TLSGD",
+ "BFD_RELOC_PPC_TLSLD",
+ "BFD_RELOC_PPC_DTPMOD",
+ "BFD_RELOC_PPC_TPREL16",
+ "BFD_RELOC_PPC_TPREL16_LO",
+ "BFD_RELOC_PPC_TPREL16_HI",
+ "BFD_RELOC_PPC_TPREL16_HA",
+ "BFD_RELOC_PPC_TPREL",
+ "BFD_RELOC_PPC_DTPREL16",
+ "BFD_RELOC_PPC_DTPREL16_LO",
+ "BFD_RELOC_PPC_DTPREL16_HI",
+ "BFD_RELOC_PPC_DTPREL16_HA",
+ "BFD_RELOC_PPC_DTPREL",
+ "BFD_RELOC_PPC_GOT_TLSGD16",
+ "BFD_RELOC_PPC_GOT_TLSGD16_LO",
+ "BFD_RELOC_PPC_GOT_TLSGD16_HI",
+ "BFD_RELOC_PPC_GOT_TLSGD16_HA",
+ "BFD_RELOC_PPC_GOT_TLSLD16",
+ "BFD_RELOC_PPC_GOT_TLSLD16_LO",
+ "BFD_RELOC_PPC_GOT_TLSLD16_HI",
+ "BFD_RELOC_PPC_GOT_TLSLD16_HA",
+ "BFD_RELOC_PPC_GOT_TPREL16",
+ "BFD_RELOC_PPC_GOT_TPREL16_LO",
+ "BFD_RELOC_PPC_GOT_TPREL16_HI",
+ "BFD_RELOC_PPC_GOT_TPREL16_HA",
+ "BFD_RELOC_PPC_GOT_DTPREL16",
+ "BFD_RELOC_PPC_GOT_DTPREL16_LO",
+ "BFD_RELOC_PPC_GOT_DTPREL16_HI",
+ "BFD_RELOC_PPC_GOT_DTPREL16_HA",
+ "BFD_RELOC_PPC64_TPREL16_DS",
+ "BFD_RELOC_PPC64_TPREL16_LO_DS",
+ "BFD_RELOC_PPC64_TPREL16_HIGHER",
+ "BFD_RELOC_PPC64_TPREL16_HIGHERA",
+ "BFD_RELOC_PPC64_TPREL16_HIGHEST",
+ "BFD_RELOC_PPC64_TPREL16_HIGHESTA",
+ "BFD_RELOC_PPC64_DTPREL16_DS",
+ "BFD_RELOC_PPC64_DTPREL16_LO_DS",
+ "BFD_RELOC_PPC64_DTPREL16_HIGHER",
+ "BFD_RELOC_PPC64_DTPREL16_HIGHERA",
+ "BFD_RELOC_PPC64_DTPREL16_HIGHEST",
+ "BFD_RELOC_PPC64_DTPREL16_HIGHESTA",
+ "BFD_RELOC_PPC64_TPREL16_HIGH",
+ "BFD_RELOC_PPC64_TPREL16_HIGHA",
+ "BFD_RELOC_PPC64_DTPREL16_HIGH",
+ "BFD_RELOC_PPC64_DTPREL16_HIGHA",
+ "BFD_RELOC_I370_D12",
+ "BFD_RELOC_CTOR",
+ "BFD_RELOC_ARM_PCREL_BRANCH",
+ "BFD_RELOC_ARM_PCREL_BLX",
+ "BFD_RELOC_THUMB_PCREL_BLX",
+ "BFD_RELOC_ARM_PCREL_CALL",
+ "BFD_RELOC_ARM_PCREL_JUMP",
+ "BFD_RELOC_THUMB_PCREL_BRANCH7",
+ "BFD_RELOC_THUMB_PCREL_BRANCH9",
+ "BFD_RELOC_THUMB_PCREL_BRANCH12",
+ "BFD_RELOC_THUMB_PCREL_BRANCH20",
+ "BFD_RELOC_THUMB_PCREL_BRANCH23",
+ "BFD_RELOC_THUMB_PCREL_BRANCH25",
+ "BFD_RELOC_ARM_OFFSET_IMM",
+ "BFD_RELOC_ARM_THUMB_OFFSET",
+ "BFD_RELOC_ARM_TARGET1",
+ "BFD_RELOC_ARM_ROSEGREL32",
+ "BFD_RELOC_ARM_SBREL32",
+ "BFD_RELOC_ARM_TARGET2",
+ "BFD_RELOC_ARM_PREL31",
+ "BFD_RELOC_ARM_MOVW",
+ "BFD_RELOC_ARM_MOVT",
+ "BFD_RELOC_ARM_MOVW_PCREL",
+ "BFD_RELOC_ARM_MOVT_PCREL",
+ "BFD_RELOC_ARM_THUMB_MOVW",
+ "BFD_RELOC_ARM_THUMB_MOVT",
+ "BFD_RELOC_ARM_THUMB_MOVW_PCREL",
+ "BFD_RELOC_ARM_THUMB_MOVT_PCREL",
+ "BFD_RELOC_ARM_JUMP_SLOT",
+ "BFD_RELOC_ARM_GLOB_DAT",
+ "BFD_RELOC_ARM_GOT32",
+ "BFD_RELOC_ARM_PLT32",
+ "BFD_RELOC_ARM_RELATIVE",
+ "BFD_RELOC_ARM_GOTOFF",
+ "BFD_RELOC_ARM_GOTPC",
+ "BFD_RELOC_ARM_GOT_PREL",
+ "BFD_RELOC_ARM_TLS_GD32",
+ "BFD_RELOC_ARM_TLS_LDO32",
+ "BFD_RELOC_ARM_TLS_LDM32",
+ "BFD_RELOC_ARM_TLS_DTPOFF32",
+ "BFD_RELOC_ARM_TLS_DTPMOD32",
+ "BFD_RELOC_ARM_TLS_TPOFF32",
+ "BFD_RELOC_ARM_TLS_IE32",
+ "BFD_RELOC_ARM_TLS_LE32",
+ "BFD_RELOC_ARM_TLS_GOTDESC",
+ "BFD_RELOC_ARM_TLS_CALL",
+ "BFD_RELOC_ARM_THM_TLS_CALL",
+ "BFD_RELOC_ARM_TLS_DESCSEQ",
+ "BFD_RELOC_ARM_THM_TLS_DESCSEQ",
+ "BFD_RELOC_ARM_TLS_DESC",
+ "BFD_RELOC_ARM_ALU_PC_G0_NC",
+ "BFD_RELOC_ARM_ALU_PC_G0",
+ "BFD_RELOC_ARM_ALU_PC_G1_NC",
+ "BFD_RELOC_ARM_ALU_PC_G1",
+ "BFD_RELOC_ARM_ALU_PC_G2",
+ "BFD_RELOC_ARM_LDR_PC_G0",
+ "BFD_RELOC_ARM_LDR_PC_G1",
+ "BFD_RELOC_ARM_LDR_PC_G2",
+ "BFD_RELOC_ARM_LDRS_PC_G0",
+ "BFD_RELOC_ARM_LDRS_PC_G1",
+ "BFD_RELOC_ARM_LDRS_PC_G2",
+ "BFD_RELOC_ARM_LDC_PC_G0",
+ "BFD_RELOC_ARM_LDC_PC_G1",
+ "BFD_RELOC_ARM_LDC_PC_G2",
+ "BFD_RELOC_ARM_ALU_SB_G0_NC",
+ "BFD_RELOC_ARM_ALU_SB_G0",
+ "BFD_RELOC_ARM_ALU_SB_G1_NC",
+ "BFD_RELOC_ARM_ALU_SB_G1",
+ "BFD_RELOC_ARM_ALU_SB_G2",
+ "BFD_RELOC_ARM_LDR_SB_G0",
+ "BFD_RELOC_ARM_LDR_SB_G1",
+ "BFD_RELOC_ARM_LDR_SB_G2",
+ "BFD_RELOC_ARM_LDRS_SB_G0",
+ "BFD_RELOC_ARM_LDRS_SB_G1",
+ "BFD_RELOC_ARM_LDRS_SB_G2",
+ "BFD_RELOC_ARM_LDC_SB_G0",
+ "BFD_RELOC_ARM_LDC_SB_G1",
+ "BFD_RELOC_ARM_LDC_SB_G2",
+ "BFD_RELOC_ARM_V4BX",
+ "BFD_RELOC_ARM_IRELATIVE",
+ "BFD_RELOC_ARM_IMMEDIATE",
+ "BFD_RELOC_ARM_ADRL_IMMEDIATE",
+ "BFD_RELOC_ARM_T32_IMMEDIATE",
+ "BFD_RELOC_ARM_T32_ADD_IMM",
+ "BFD_RELOC_ARM_T32_IMM12",
+ "BFD_RELOC_ARM_T32_ADD_PC12",
+ "BFD_RELOC_ARM_SHIFT_IMM",
+ "BFD_RELOC_ARM_SMC",
+ "BFD_RELOC_ARM_HVC",
+ "BFD_RELOC_ARM_SWI",
+ "BFD_RELOC_ARM_MULTI",
+ "BFD_RELOC_ARM_CP_OFF_IMM",
+ "BFD_RELOC_ARM_CP_OFF_IMM_S2",
+ "BFD_RELOC_ARM_T32_CP_OFF_IMM",
+ "BFD_RELOC_ARM_T32_CP_OFF_IMM_S2",
+ "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_T32_OFFSET_U8",
+ "BFD_RELOC_ARM_T32_OFFSET_IMM",
+ "BFD_RELOC_ARM_HWLITERAL",
+ "BFD_RELOC_ARM_THUMB_ADD",
+ "BFD_RELOC_ARM_THUMB_IMM",
+ "BFD_RELOC_ARM_THUMB_SHIFT",
+ "BFD_RELOC_SH_PCDISP8BY2",
+ "BFD_RELOC_SH_PCDISP12BY2",
+ "BFD_RELOC_SH_IMM3",
+ "BFD_RELOC_SH_IMM3U",
+ "BFD_RELOC_SH_DISP12",
+ "BFD_RELOC_SH_DISP12BY2",
+ "BFD_RELOC_SH_DISP12BY4",
+ "BFD_RELOC_SH_DISP12BY8",
+ "BFD_RELOC_SH_DISP20",
+ "BFD_RELOC_SH_DISP20BY8",
+ "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_SH_LOOP_START",
+ "BFD_RELOC_SH_LOOP_END",
+ "BFD_RELOC_SH_COPY",
+ "BFD_RELOC_SH_GLOB_DAT",
+ "BFD_RELOC_SH_JMP_SLOT",
+ "BFD_RELOC_SH_RELATIVE",
+ "BFD_RELOC_SH_GOTPC",
+ "BFD_RELOC_SH_GOT_LOW16",
+ "BFD_RELOC_SH_GOT_MEDLOW16",
+ "BFD_RELOC_SH_GOT_MEDHI16",
+ "BFD_RELOC_SH_GOT_HI16",
+ "BFD_RELOC_SH_GOTPLT_LOW16",
+ "BFD_RELOC_SH_GOTPLT_MEDLOW16",
+ "BFD_RELOC_SH_GOTPLT_MEDHI16",
+ "BFD_RELOC_SH_GOTPLT_HI16",
+ "BFD_RELOC_SH_PLT_LOW16",
+ "BFD_RELOC_SH_PLT_MEDLOW16",
+ "BFD_RELOC_SH_PLT_MEDHI16",
+ "BFD_RELOC_SH_PLT_HI16",
+ "BFD_RELOC_SH_GOTOFF_LOW16",
+ "BFD_RELOC_SH_GOTOFF_MEDLOW16",
+ "BFD_RELOC_SH_GOTOFF_MEDHI16",
+ "BFD_RELOC_SH_GOTOFF_HI16",
+ "BFD_RELOC_SH_GOTPC_LOW16",
+ "BFD_RELOC_SH_GOTPC_MEDLOW16",
+ "BFD_RELOC_SH_GOTPC_MEDHI16",
+ "BFD_RELOC_SH_GOTPC_HI16",
+ "BFD_RELOC_SH_COPY64",
+ "BFD_RELOC_SH_GLOB_DAT64",
+ "BFD_RELOC_SH_JMP_SLOT64",
+ "BFD_RELOC_SH_RELATIVE64",
+ "BFD_RELOC_SH_GOT10BY4",
+ "BFD_RELOC_SH_GOT10BY8",
+ "BFD_RELOC_SH_GOTPLT10BY4",
+ "BFD_RELOC_SH_GOTPLT10BY8",
+ "BFD_RELOC_SH_GOTPLT32",
+ "BFD_RELOC_SH_SHMEDIA_CODE",
+ "BFD_RELOC_SH_IMMU5",
+ "BFD_RELOC_SH_IMMS6",
+ "BFD_RELOC_SH_IMMS6BY32",
+ "BFD_RELOC_SH_IMMU6",
+ "BFD_RELOC_SH_IMMS10",
+ "BFD_RELOC_SH_IMMS10BY2",
+ "BFD_RELOC_SH_IMMS10BY4",
+ "BFD_RELOC_SH_IMMS10BY8",
+ "BFD_RELOC_SH_IMMS16",
+ "BFD_RELOC_SH_IMMU16",
+ "BFD_RELOC_SH_IMM_LOW16",
+ "BFD_RELOC_SH_IMM_LOW16_PCREL",
+ "BFD_RELOC_SH_IMM_MEDLOW16",
+ "BFD_RELOC_SH_IMM_MEDLOW16_PCREL",
+ "BFD_RELOC_SH_IMM_MEDHI16",
+ "BFD_RELOC_SH_IMM_MEDHI16_PCREL",
+ "BFD_RELOC_SH_IMM_HI16",
+ "BFD_RELOC_SH_IMM_HI16_PCREL",
+ "BFD_RELOC_SH_PT_16",
+ "BFD_RELOC_SH_TLS_GD_32",
+ "BFD_RELOC_SH_TLS_LD_32",
+ "BFD_RELOC_SH_TLS_LDO_32",
+ "BFD_RELOC_SH_TLS_IE_32",
+ "BFD_RELOC_SH_TLS_LE_32",
+ "BFD_RELOC_SH_TLS_DTPMOD32",
+ "BFD_RELOC_SH_TLS_DTPOFF32",
+ "BFD_RELOC_SH_TLS_TPOFF32",
+ "BFD_RELOC_SH_GOT20",
+ "BFD_RELOC_SH_GOTOFF20",
+ "BFD_RELOC_SH_GOTFUNCDESC",
+ "BFD_RELOC_SH_GOTFUNCDESC20",
+ "BFD_RELOC_SH_GOTOFFFUNCDESC",
+ "BFD_RELOC_SH_GOTOFFFUNCDESC20",
+ "BFD_RELOC_SH_FUNCDESC",
+ "BFD_RELOC_ARC_B22_PCREL",
+ "BFD_RELOC_ARC_B26",
+ "BFD_RELOC_BFIN_16_IMM",
+ "BFD_RELOC_BFIN_16_HIGH",
+ "BFD_RELOC_BFIN_4_PCREL",
+ "BFD_RELOC_BFIN_5_PCREL",
+ "BFD_RELOC_BFIN_16_LOW",
+ "BFD_RELOC_BFIN_10_PCREL",
+ "BFD_RELOC_BFIN_11_PCREL",
+ "BFD_RELOC_BFIN_12_PCREL_JUMP",
+ "BFD_RELOC_BFIN_12_PCREL_JUMP_S",
+ "BFD_RELOC_BFIN_24_PCREL_CALL_X",
+ "BFD_RELOC_BFIN_24_PCREL_JUMP_L",
+ "BFD_RELOC_BFIN_GOT17M4",
+ "BFD_RELOC_BFIN_GOTHI",
+ "BFD_RELOC_BFIN_GOTLO",
+ "BFD_RELOC_BFIN_FUNCDESC",
+ "BFD_RELOC_BFIN_FUNCDESC_GOT17M4",
+ "BFD_RELOC_BFIN_FUNCDESC_GOTHI",
+ "BFD_RELOC_BFIN_FUNCDESC_GOTLO",
+ "BFD_RELOC_BFIN_FUNCDESC_VALUE",
+ "BFD_RELOC_BFIN_FUNCDESC_GOTOFF17M4",
+ "BFD_RELOC_BFIN_FUNCDESC_GOTOFFHI",
+ "BFD_RELOC_BFIN_FUNCDESC_GOTOFFLO",
+ "BFD_RELOC_BFIN_GOTOFF17M4",
+ "BFD_RELOC_BFIN_GOTOFFHI",
+ "BFD_RELOC_BFIN_GOTOFFLO",
+ "BFD_RELOC_BFIN_GOT",
+ "BFD_RELOC_BFIN_PLTPC",
+ "BFD_ARELOC_BFIN_PUSH",
+ "BFD_ARELOC_BFIN_CONST",
+ "BFD_ARELOC_BFIN_ADD",
+ "BFD_ARELOC_BFIN_SUB",
+ "BFD_ARELOC_BFIN_MULT",
+ "BFD_ARELOC_BFIN_DIV",
+ "BFD_ARELOC_BFIN_MOD",
+ "BFD_ARELOC_BFIN_LSHIFT",
+ "BFD_ARELOC_BFIN_RSHIFT",
+ "BFD_ARELOC_BFIN_AND",
+ "BFD_ARELOC_BFIN_OR",
+ "BFD_ARELOC_BFIN_XOR",
+ "BFD_ARELOC_BFIN_LAND",
+ "BFD_ARELOC_BFIN_LOR",
+ "BFD_ARELOC_BFIN_LEN",
+ "BFD_ARELOC_BFIN_NEG",
+ "BFD_ARELOC_BFIN_COMP",
+ "BFD_ARELOC_BFIN_PAGE",
+ "BFD_ARELOC_BFIN_HWPAGE",
+ "BFD_ARELOC_BFIN_ADDR",
+ "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_DLX_HI16_S",
+ "BFD_RELOC_DLX_LO16",
+ "BFD_RELOC_DLX_JMP26",
+ "BFD_RELOC_M32C_HI8",
+ "BFD_RELOC_M32C_RL_JUMP",
+ "BFD_RELOC_M32C_RL_1ADDR",
+ "BFD_RELOC_M32C_RL_2ADDR",
+ "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_M32R_GOT24",
+ "BFD_RELOC_M32R_26_PLTREL",
+ "BFD_RELOC_M32R_COPY",
+ "BFD_RELOC_M32R_GLOB_DAT",
+ "BFD_RELOC_M32R_JMP_SLOT",
+ "BFD_RELOC_M32R_RELATIVE",
+ "BFD_RELOC_M32R_GOTOFF",
+ "BFD_RELOC_M32R_GOTOFF_HI_ULO",
+ "BFD_RELOC_M32R_GOTOFF_HI_SLO",
+ "BFD_RELOC_M32R_GOTOFF_LO",
+ "BFD_RELOC_M32R_GOTPC24",
+ "BFD_RELOC_M32R_GOT16_HI_ULO",
+ "BFD_RELOC_M32R_GOT16_HI_SLO",
+ "BFD_RELOC_M32R_GOT16_LO",
+ "BFD_RELOC_M32R_GOTPC_HI_ULO",
+ "BFD_RELOC_M32R_GOTPC_HI_SLO",
+ "BFD_RELOC_M32R_GOTPC_LO",
+ "BFD_RELOC_NDS32_20",
+ "BFD_RELOC_NDS32_9_PCREL",
+ "BFD_RELOC_NDS32_WORD_9_PCREL",
+ "BFD_RELOC_NDS32_15_PCREL",
+ "BFD_RELOC_NDS32_17_PCREL",
+ "BFD_RELOC_NDS32_25_PCREL",
+ "BFD_RELOC_NDS32_HI20",
+ "BFD_RELOC_NDS32_LO12S3",
+ "BFD_RELOC_NDS32_LO12S2",
+ "BFD_RELOC_NDS32_LO12S1",
+ "BFD_RELOC_NDS32_LO12S0",
+ "BFD_RELOC_NDS32_LO12S0_ORI",
+ "BFD_RELOC_NDS32_SDA15S3",
+ "BFD_RELOC_NDS32_SDA15S2",
+ "BFD_RELOC_NDS32_SDA15S1",
+ "BFD_RELOC_NDS32_SDA15S0",
+ "BFD_RELOC_NDS32_SDA16S3",
+ "BFD_RELOC_NDS32_SDA17S2",
+ "BFD_RELOC_NDS32_SDA18S1",
+ "BFD_RELOC_NDS32_SDA19S0",
+ "BFD_RELOC_NDS32_GOT20",
+ "BFD_RELOC_NDS32_9_PLTREL",
+ "BFD_RELOC_NDS32_25_PLTREL",
+ "BFD_RELOC_NDS32_COPY",
+ "BFD_RELOC_NDS32_GLOB_DAT",
+ "BFD_RELOC_NDS32_JMP_SLOT",
+ "BFD_RELOC_NDS32_RELATIVE",
+ "BFD_RELOC_NDS32_GOTOFF",
+ "BFD_RELOC_NDS32_GOTOFF_HI20",
+ "BFD_RELOC_NDS32_GOTOFF_LO12",
+ "BFD_RELOC_NDS32_GOTPC20",
+ "BFD_RELOC_NDS32_GOT_HI20",
+ "BFD_RELOC_NDS32_GOT_LO12",
+ "BFD_RELOC_NDS32_GOTPC_HI20",
+ "BFD_RELOC_NDS32_GOTPC_LO12",
+ "BFD_RELOC_NDS32_INSN16",
+ "BFD_RELOC_NDS32_LABEL",
+ "BFD_RELOC_NDS32_LONGCALL1",
+ "BFD_RELOC_NDS32_LONGCALL2",
+ "BFD_RELOC_NDS32_LONGCALL3",
+ "BFD_RELOC_NDS32_LONGJUMP1",
+ "BFD_RELOC_NDS32_LONGJUMP2",
+ "BFD_RELOC_NDS32_LONGJUMP3",
+ "BFD_RELOC_NDS32_LOADSTORE",
+ "BFD_RELOC_NDS32_9_FIXED",
+ "BFD_RELOC_NDS32_15_FIXED",
+ "BFD_RELOC_NDS32_17_FIXED",
+ "BFD_RELOC_NDS32_25_FIXED",
+ "BFD_RELOC_NDS32_LONGCALL4",
+ "BFD_RELOC_NDS32_LONGCALL5",
+ "BFD_RELOC_NDS32_LONGCALL6",
+ "BFD_RELOC_NDS32_LONGJUMP4",
+ "BFD_RELOC_NDS32_LONGJUMP5",
+ "BFD_RELOC_NDS32_LONGJUMP6",
+ "BFD_RELOC_NDS32_LONGJUMP7",
+ "BFD_RELOC_NDS32_PLTREL_HI20",
+ "BFD_RELOC_NDS32_PLTREL_LO12",
+ "BFD_RELOC_NDS32_PLT_GOTREL_HI20",
+ "BFD_RELOC_NDS32_PLT_GOTREL_LO12",
+ "BFD_RELOC_NDS32_SDA12S2_DP",
+ "BFD_RELOC_NDS32_SDA12S2_SP",
+ "BFD_RELOC_NDS32_LO12S2_DP",
+ "BFD_RELOC_NDS32_LO12S2_SP",
+ "BFD_RELOC_NDS32_DWARF2_OP1",
+ "BFD_RELOC_NDS32_DWARF2_OP2",
+ "BFD_RELOC_NDS32_DWARF2_LEB",
+ "BFD_RELOC_NDS32_UPDATE_TA",
+ "BFD_RELOC_NDS32_PLT_GOTREL_LO20",
+ "BFD_RELOC_NDS32_PLT_GOTREL_LO15",
+ "BFD_RELOC_NDS32_PLT_GOTREL_LO19",
+ "BFD_RELOC_NDS32_GOT_LO15",
+ "BFD_RELOC_NDS32_GOT_LO19",
+ "BFD_RELOC_NDS32_GOTOFF_LO15",
+ "BFD_RELOC_NDS32_GOTOFF_LO19",
+ "BFD_RELOC_NDS32_GOT15S2",
+ "BFD_RELOC_NDS32_GOT17S2",
+ "BFD_RELOC_NDS32_5",
+ "BFD_RELOC_NDS32_10_UPCREL",
+ "BFD_RELOC_NDS32_SDA_FP7U2_RELA",
+ "BFD_RELOC_NDS32_RELAX_ENTRY",
+ "BFD_RELOC_NDS32_GOT_SUFF",
+ "BFD_RELOC_NDS32_GOTOFF_SUFF",
+ "BFD_RELOC_NDS32_PLT_GOT_SUFF",
+ "BFD_RELOC_NDS32_MULCALL_SUFF",
+ "BFD_RELOC_NDS32_PTR",
+ "BFD_RELOC_NDS32_PTR_COUNT",
+ "BFD_RELOC_NDS32_PTR_RESOLVED",
+ "BFD_RELOC_NDS32_PLTBLOCK",
+ "BFD_RELOC_NDS32_RELAX_REGION_BEGIN",
+ "BFD_RELOC_NDS32_RELAX_REGION_END",
+ "BFD_RELOC_NDS32_MINUEND",
+ "BFD_RELOC_NDS32_SUBTRAHEND",
+ "BFD_RELOC_NDS32_DIFF8",
+ "BFD_RELOC_NDS32_DIFF16",
+ "BFD_RELOC_NDS32_DIFF32",
+ "BFD_RELOC_NDS32_DIFF_ULEB128",
+ "BFD_RELOC_NDS32_EMPTY",
+ "BFD_RELOC_NDS32_25_ABS",
+ "BFD_RELOC_NDS32_DATA",
+ "BFD_RELOC_NDS32_TRAN",
+ "BFD_RELOC_NDS32_17IFC_PCREL",
+ "BFD_RELOC_NDS32_10IFCU_PCREL",
+ "BFD_RELOC_NDS32_TPOFF",
+ "BFD_RELOC_NDS32_TLS_LE_HI20",
+ "BFD_RELOC_NDS32_TLS_LE_LO12",
+ "BFD_RELOC_NDS32_TLS_LE_ADD",
+ "BFD_RELOC_NDS32_TLS_LE_LS",
+ "BFD_RELOC_NDS32_GOTTPOFF",
+ "BFD_RELOC_NDS32_TLS_IE_HI20",
+ "BFD_RELOC_NDS32_TLS_IE_LO12S2",
+ "BFD_RELOC_NDS32_TLS_TPOFF",
+ "BFD_RELOC_NDS32_TLS_LE_20",
+ "BFD_RELOC_NDS32_TLS_LE_15S0",
+ "BFD_RELOC_NDS32_TLS_LE_15S1",
+ "BFD_RELOC_NDS32_TLS_LE_15S2",
+ "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_V850_LONGCALL",
+ "BFD_RELOC_V850_LONGJUMP",
+ "BFD_RELOC_V850_ALIGN",
+ "BFD_RELOC_V850_LO16_SPLIT_OFFSET",
+ "BFD_RELOC_V850_16_PCREL",
+ "BFD_RELOC_V850_17_PCREL",
+ "BFD_RELOC_V850_23",
+ "BFD_RELOC_V850_32_PCREL",
+ "BFD_RELOC_V850_32_ABS",
+ "BFD_RELOC_V850_16_SPLIT_OFFSET",
+ "BFD_RELOC_V850_16_S1",
+ "BFD_RELOC_V850_LO16_S1",
+ "BFD_RELOC_V850_CALLT_15_16_OFFSET",
+ "BFD_RELOC_V850_32_GOTPCREL",
+ "BFD_RELOC_V850_16_GOT",
+ "BFD_RELOC_V850_32_GOT",
+ "BFD_RELOC_V850_22_PLT_PCREL",
+ "BFD_RELOC_V850_32_PLT_PCREL",
+ "BFD_RELOC_V850_COPY",
+ "BFD_RELOC_V850_GLOB_DAT",
+ "BFD_RELOC_V850_JMP_SLOT",
+ "BFD_RELOC_V850_RELATIVE",
+ "BFD_RELOC_V850_16_GOTOFF",
+ "BFD_RELOC_V850_32_GOTOFF",
+ "BFD_RELOC_V850_CODE",
+ "BFD_RELOC_V850_DATA",
+ "BFD_RELOC_TIC30_LDP",
+ "BFD_RELOC_TIC54X_PARTLS7",
+ "BFD_RELOC_TIC54X_PARTMS9",
+ "BFD_RELOC_TIC54X_23",
+ "BFD_RELOC_TIC54X_16_OF_23",
+ "BFD_RELOC_TIC54X_MS7_OF_23",
+ "BFD_RELOC_C6000_PCR_S21",
+ "BFD_RELOC_C6000_PCR_S12",
+ "BFD_RELOC_C6000_PCR_S10",
+ "BFD_RELOC_C6000_PCR_S7",
+ "BFD_RELOC_C6000_ABS_S16",
+ "BFD_RELOC_C6000_ABS_L16",
+ "BFD_RELOC_C6000_ABS_H16",
+ "BFD_RELOC_C6000_SBR_U15_B",
+ "BFD_RELOC_C6000_SBR_U15_H",
+ "BFD_RELOC_C6000_SBR_U15_W",
+ "BFD_RELOC_C6000_SBR_S16",
+ "BFD_RELOC_C6000_SBR_L16_B",
+ "BFD_RELOC_C6000_SBR_L16_H",
+ "BFD_RELOC_C6000_SBR_L16_W",
+ "BFD_RELOC_C6000_SBR_H16_B",
+ "BFD_RELOC_C6000_SBR_H16_H",
+ "BFD_RELOC_C6000_SBR_H16_W",
+ "BFD_RELOC_C6000_SBR_GOT_U15_W",
+ "BFD_RELOC_C6000_SBR_GOT_L16_W",
+ "BFD_RELOC_C6000_SBR_GOT_H16_W",
+ "BFD_RELOC_C6000_DSBT_INDEX",
+ "BFD_RELOC_C6000_PREL31",
+ "BFD_RELOC_C6000_COPY",
+ "BFD_RELOC_C6000_JUMP_SLOT",
+ "BFD_RELOC_C6000_EHTYPE",
+ "BFD_RELOC_C6000_PCR_H16",
+ "BFD_RELOC_C6000_PCR_L16",
+ "BFD_RELOC_C6000_ALIGN",
+ "BFD_RELOC_C6000_FPHEAD",
+ "BFD_RELOC_C6000_NOCMP",
+ "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_MCORE_RVA",
+ "BFD_RELOC_MEP_8",
+ "BFD_RELOC_MEP_16",
+ "BFD_RELOC_MEP_32",
+ "BFD_RELOC_MEP_PCREL8A2",
+ "BFD_RELOC_MEP_PCREL12A2",
+ "BFD_RELOC_MEP_PCREL17A2",
+ "BFD_RELOC_MEP_PCREL24A2",
+ "BFD_RELOC_MEP_PCABS24A2",
+ "BFD_RELOC_MEP_LOW16",
+ "BFD_RELOC_MEP_HI16U",
+ "BFD_RELOC_MEP_HI16S",
+ "BFD_RELOC_MEP_GPREL",
+ "BFD_RELOC_MEP_TPREL",
+ "BFD_RELOC_MEP_TPREL7",
+ "BFD_RELOC_MEP_TPREL7A2",
+ "BFD_RELOC_MEP_TPREL7A4",
+ "BFD_RELOC_MEP_UIMM24",
+ "BFD_RELOC_MEP_ADDR24A4",
+ "BFD_RELOC_MEP_GNU_VTINHERIT",
+ "BFD_RELOC_MEP_GNU_VTENTRY",
+
+ "BFD_RELOC_METAG_HIADDR16",
+ "BFD_RELOC_METAG_LOADDR16",
+ "BFD_RELOC_METAG_RELBRANCH",
+ "BFD_RELOC_METAG_GETSETOFF",
+ "BFD_RELOC_METAG_HIOG",
+ "BFD_RELOC_METAG_LOOG",
+ "BFD_RELOC_METAG_REL8",
+ "BFD_RELOC_METAG_REL16",
+ "BFD_RELOC_METAG_HI16_GOTOFF",
+ "BFD_RELOC_METAG_LO16_GOTOFF",
+ "BFD_RELOC_METAG_GETSET_GOTOFF",
+ "BFD_RELOC_METAG_GETSET_GOT",
+ "BFD_RELOC_METAG_HI16_GOTPC",
+ "BFD_RELOC_METAG_LO16_GOTPC",
+ "BFD_RELOC_METAG_HI16_PLT",
+ "BFD_RELOC_METAG_LO16_PLT",
+ "BFD_RELOC_METAG_RELBRANCH_PLT",
+ "BFD_RELOC_METAG_GOTOFF",
+ "BFD_RELOC_METAG_PLT",
+ "BFD_RELOC_METAG_COPY",
+ "BFD_RELOC_METAG_JMP_SLOT",
+ "BFD_RELOC_METAG_RELATIVE",
+ "BFD_RELOC_METAG_GLOB_DAT",
+ "BFD_RELOC_METAG_TLS_GD",
+ "BFD_RELOC_METAG_TLS_LDM",
+ "BFD_RELOC_METAG_TLS_LDO_HI16",
+ "BFD_RELOC_METAG_TLS_LDO_LO16",
+ "BFD_RELOC_METAG_TLS_LDO",
+ "BFD_RELOC_METAG_TLS_IE",
+ "BFD_RELOC_METAG_TLS_IENONPIC",
+ "BFD_RELOC_METAG_TLS_IENONPIC_HI16",
+ "BFD_RELOC_METAG_TLS_IENONPIC_LO16",
+ "BFD_RELOC_METAG_TLS_TPOFF",
+ "BFD_RELOC_METAG_TLS_DTPMOD",
+ "BFD_RELOC_METAG_TLS_DTPOFF",
+ "BFD_RELOC_METAG_TLS_LE",
+ "BFD_RELOC_METAG_TLS_LE_HI16",
+ "BFD_RELOC_METAG_TLS_LE_LO16",
+ "BFD_RELOC_MMIX_GETA",
+ "BFD_RELOC_MMIX_GETA_1",
+ "BFD_RELOC_MMIX_GETA_2",
+ "BFD_RELOC_MMIX_GETA_3",
+ "BFD_RELOC_MMIX_CBRANCH",
+ "BFD_RELOC_MMIX_CBRANCH_J",
+ "BFD_RELOC_MMIX_CBRANCH_1",
+ "BFD_RELOC_MMIX_CBRANCH_2",
+ "BFD_RELOC_MMIX_CBRANCH_3",
+ "BFD_RELOC_MMIX_PUSHJ",
+ "BFD_RELOC_MMIX_PUSHJ_1",
+ "BFD_RELOC_MMIX_PUSHJ_2",
+ "BFD_RELOC_MMIX_PUSHJ_3",
+ "BFD_RELOC_MMIX_PUSHJ_STUBBABLE",
+ "BFD_RELOC_MMIX_JMP",
+ "BFD_RELOC_MMIX_JMP_1",
+ "BFD_RELOC_MMIX_JMP_2",
+ "BFD_RELOC_MMIX_JMP_3",
+ "BFD_RELOC_MMIX_ADDR19",
+ "BFD_RELOC_MMIX_ADDR27",
+ "BFD_RELOC_MMIX_REG_OR_BYTE",
+ "BFD_RELOC_MMIX_REG",
+ "BFD_RELOC_MMIX_BASE_PLUS_OFFSET",
+ "BFD_RELOC_MMIX_LOCAL",
+ "BFD_RELOC_AVR_7_PCREL",
+ "BFD_RELOC_AVR_13_PCREL",
+ "BFD_RELOC_AVR_16_PM",
+ "BFD_RELOC_AVR_LO8_LDI",
+ "BFD_RELOC_AVR_HI8_LDI",
+ "BFD_RELOC_AVR_HH8_LDI",
+ "BFD_RELOC_AVR_MS8_LDI",
+ "BFD_RELOC_AVR_LO8_LDI_NEG",
+ "BFD_RELOC_AVR_HI8_LDI_NEG",
+ "BFD_RELOC_AVR_HH8_LDI_NEG",
+ "BFD_RELOC_AVR_MS8_LDI_NEG",
+ "BFD_RELOC_AVR_LO8_LDI_PM",
+ "BFD_RELOC_AVR_LO8_LDI_GS",
+ "BFD_RELOC_AVR_HI8_LDI_PM",
+ "BFD_RELOC_AVR_HI8_LDI_GS",
+ "BFD_RELOC_AVR_HH8_LDI_PM",
+ "BFD_RELOC_AVR_LO8_LDI_PM_NEG",
+ "BFD_RELOC_AVR_HI8_LDI_PM_NEG",
+ "BFD_RELOC_AVR_HH8_LDI_PM_NEG",
+ "BFD_RELOC_AVR_CALL",
+ "BFD_RELOC_AVR_LDI",
+ "BFD_RELOC_AVR_6",
+ "BFD_RELOC_AVR_6_ADIW",
+ "BFD_RELOC_AVR_8_LO",
+ "BFD_RELOC_AVR_8_HI",
+ "BFD_RELOC_AVR_8_HLO",
+ "BFD_RELOC_AVR_DIFF8",
+ "BFD_RELOC_AVR_DIFF16",
+ "BFD_RELOC_AVR_DIFF32",
+ "BFD_RELOC_AVR_LDS_STS_16",
+ "BFD_RELOC_AVR_PORT6",
+ "BFD_RELOC_AVR_PORT5",
+ "BFD_RELOC_RL78_NEG8",
+ "BFD_RELOC_RL78_NEG16",
+ "BFD_RELOC_RL78_NEG24",
+ "BFD_RELOC_RL78_NEG32",
+ "BFD_RELOC_RL78_16_OP",
+ "BFD_RELOC_RL78_24_OP",
+ "BFD_RELOC_RL78_32_OP",
+ "BFD_RELOC_RL78_8U",
+ "BFD_RELOC_RL78_16U",
+ "BFD_RELOC_RL78_24U",
+ "BFD_RELOC_RL78_DIR3U_PCREL",
+ "BFD_RELOC_RL78_DIFF",
+ "BFD_RELOC_RL78_GPRELB",
+ "BFD_RELOC_RL78_GPRELW",
+ "BFD_RELOC_RL78_GPRELL",
+ "BFD_RELOC_RL78_SYM",
+ "BFD_RELOC_RL78_OP_SUBTRACT",
+ "BFD_RELOC_RL78_OP_NEG",
+ "BFD_RELOC_RL78_OP_AND",
+ "BFD_RELOC_RL78_OP_SHRA",
+ "BFD_RELOC_RL78_ABS8",
+ "BFD_RELOC_RL78_ABS16",
+ "BFD_RELOC_RL78_ABS16_REV",
+ "BFD_RELOC_RL78_ABS32",
+ "BFD_RELOC_RL78_ABS32_REV",
+ "BFD_RELOC_RL78_ABS16U",
+ "BFD_RELOC_RL78_ABS16UW",
+ "BFD_RELOC_RL78_ABS16UL",
+ "BFD_RELOC_RL78_RELAX",
+ "BFD_RELOC_RL78_HI16",
+ "BFD_RELOC_RL78_HI8",
+ "BFD_RELOC_RL78_LO16",
+ "BFD_RELOC_RL78_CODE",
+ "BFD_RELOC_RX_NEG8",
+ "BFD_RELOC_RX_NEG16",
+ "BFD_RELOC_RX_NEG24",
+ "BFD_RELOC_RX_NEG32",
+ "BFD_RELOC_RX_16_OP",
+ "BFD_RELOC_RX_24_OP",
+ "BFD_RELOC_RX_32_OP",
+ "BFD_RELOC_RX_8U",
+ "BFD_RELOC_RX_16U",
+ "BFD_RELOC_RX_24U",
+ "BFD_RELOC_RX_DIR3U_PCREL",
+ "BFD_RELOC_RX_DIFF",
+ "BFD_RELOC_RX_GPRELB",
+ "BFD_RELOC_RX_GPRELW",
+ "BFD_RELOC_RX_GPRELL",
+ "BFD_RELOC_RX_SYM",
+ "BFD_RELOC_RX_OP_SUBTRACT",
+ "BFD_RELOC_RX_OP_NEG",
+ "BFD_RELOC_RX_ABS8",
+ "BFD_RELOC_RX_ABS16",
+ "BFD_RELOC_RX_ABS16_REV",
+ "BFD_RELOC_RX_ABS32",
+ "BFD_RELOC_RX_ABS32_REV",
+ "BFD_RELOC_RX_ABS16U",
+ "BFD_RELOC_RX_ABS16UW",
+ "BFD_RELOC_RX_ABS16UL",
+ "BFD_RELOC_RX_RELAX",
+ "BFD_RELOC_390_12",
+ "BFD_RELOC_390_GOT12",
+ "BFD_RELOC_390_PLT32",
+ "BFD_RELOC_390_COPY",
+ "BFD_RELOC_390_GLOB_DAT",
+ "BFD_RELOC_390_JMP_SLOT",
+ "BFD_RELOC_390_RELATIVE",
+ "BFD_RELOC_390_GOTPC",
+ "BFD_RELOC_390_GOT16",
+ "BFD_RELOC_390_PC12DBL",
+ "BFD_RELOC_390_PLT12DBL",
+ "BFD_RELOC_390_PC16DBL",
+ "BFD_RELOC_390_PLT16DBL",
+ "BFD_RELOC_390_PC24DBL",
+ "BFD_RELOC_390_PLT24DBL",
+ "BFD_RELOC_390_PC32DBL",
+ "BFD_RELOC_390_PLT32DBL",
+ "BFD_RELOC_390_GOTPCDBL",
+ "BFD_RELOC_390_GOT64",
+ "BFD_RELOC_390_PLT64",
+ "BFD_RELOC_390_GOTENT",
+ "BFD_RELOC_390_GOTOFF64",
+ "BFD_RELOC_390_GOTPLT12",
+ "BFD_RELOC_390_GOTPLT16",
+ "BFD_RELOC_390_GOTPLT32",
+ "BFD_RELOC_390_GOTPLT64",
+ "BFD_RELOC_390_GOTPLTENT",
+ "BFD_RELOC_390_PLTOFF16",
+ "BFD_RELOC_390_PLTOFF32",
+ "BFD_RELOC_390_PLTOFF64",
+ "BFD_RELOC_390_TLS_LOAD",
+ "BFD_RELOC_390_TLS_GDCALL",
+ "BFD_RELOC_390_TLS_LDCALL",
+ "BFD_RELOC_390_TLS_GD32",
+ "BFD_RELOC_390_TLS_GD64",
+ "BFD_RELOC_390_TLS_GOTIE12",
+ "BFD_RELOC_390_TLS_GOTIE32",
+ "BFD_RELOC_390_TLS_GOTIE64",
+ "BFD_RELOC_390_TLS_LDM32",
+ "BFD_RELOC_390_TLS_LDM64",
+ "BFD_RELOC_390_TLS_IE32",
+ "BFD_RELOC_390_TLS_IE64",
+ "BFD_RELOC_390_TLS_IEENT",
+ "BFD_RELOC_390_TLS_LE32",
+ "BFD_RELOC_390_TLS_LE64",
+ "BFD_RELOC_390_TLS_LDO32",
+ "BFD_RELOC_390_TLS_LDO64",
+ "BFD_RELOC_390_TLS_DTPMOD",
+ "BFD_RELOC_390_TLS_DTPOFF",
+ "BFD_RELOC_390_TLS_TPOFF",
+ "BFD_RELOC_390_20",
+ "BFD_RELOC_390_GOT20",
+ "BFD_RELOC_390_GOTPLT20",
+ "BFD_RELOC_390_TLS_GOTIE20",
+ "BFD_RELOC_390_IRELATIVE",
+ "BFD_RELOC_SCORE_GPREL15",
+ "BFD_RELOC_SCORE_DUMMY2",
+ "BFD_RELOC_SCORE_JMP",
+ "BFD_RELOC_SCORE_BRANCH",
+ "BFD_RELOC_SCORE_IMM30",
+ "BFD_RELOC_SCORE_IMM32",
+ "BFD_RELOC_SCORE16_JMP",
+ "BFD_RELOC_SCORE16_BRANCH",
+ "BFD_RELOC_SCORE_BCMP",
+ "BFD_RELOC_SCORE_GOT15",
+ "BFD_RELOC_SCORE_GOT_LO16",
+ "BFD_RELOC_SCORE_CALL15",
+ "BFD_RELOC_SCORE_DUMMY_HI16",
+ "BFD_RELOC_IP2K_FR9",
+ "BFD_RELOC_IP2K_BANK",
+ "BFD_RELOC_IP2K_ADDR16CJP",
+ "BFD_RELOC_IP2K_PAGE3",
+ "BFD_RELOC_IP2K_LO8DATA",
+ "BFD_RELOC_IP2K_HI8DATA",
+ "BFD_RELOC_IP2K_EX8DATA",
+ "BFD_RELOC_IP2K_LO8INSN",
+ "BFD_RELOC_IP2K_HI8INSN",
+ "BFD_RELOC_IP2K_PC_SKIP",
+ "BFD_RELOC_IP2K_TEXT",
+ "BFD_RELOC_IP2K_FR_OFFSET",
+ "BFD_RELOC_VPE4KMATH_DATA",
+ "BFD_RELOC_VPE4KMATH_INSN",
+ "BFD_RELOC_VTABLE_INHERIT",
+ "BFD_RELOC_VTABLE_ENTRY",
+ "BFD_RELOC_IA64_IMM14",
+ "BFD_RELOC_IA64_IMM22",
+ "BFD_RELOC_IA64_IMM64",
+ "BFD_RELOC_IA64_DIR32MSB",
+ "BFD_RELOC_IA64_DIR32LSB",
+ "BFD_RELOC_IA64_DIR64MSB",
+ "BFD_RELOC_IA64_DIR64LSB",
+ "BFD_RELOC_IA64_GPREL22",
+ "BFD_RELOC_IA64_GPREL64I",
+ "BFD_RELOC_IA64_GPREL32MSB",
+ "BFD_RELOC_IA64_GPREL32LSB",
+ "BFD_RELOC_IA64_GPREL64MSB",
+ "BFD_RELOC_IA64_GPREL64LSB",
+ "BFD_RELOC_IA64_LTOFF22",
+ "BFD_RELOC_IA64_LTOFF64I",
+ "BFD_RELOC_IA64_PLTOFF22",
+ "BFD_RELOC_IA64_PLTOFF64I",
+ "BFD_RELOC_IA64_PLTOFF64MSB",
+ "BFD_RELOC_IA64_PLTOFF64LSB",
+ "BFD_RELOC_IA64_FPTR64I",
+ "BFD_RELOC_IA64_FPTR32MSB",
+ "BFD_RELOC_IA64_FPTR32LSB",
+ "BFD_RELOC_IA64_FPTR64MSB",
+ "BFD_RELOC_IA64_FPTR64LSB",
+ "BFD_RELOC_IA64_PCREL21B",
+ "BFD_RELOC_IA64_PCREL21BI",
+ "BFD_RELOC_IA64_PCREL21M",
+ "BFD_RELOC_IA64_PCREL21F",
+ "BFD_RELOC_IA64_PCREL22",
+ "BFD_RELOC_IA64_PCREL60B",
+ "BFD_RELOC_IA64_PCREL64I",
+ "BFD_RELOC_IA64_PCREL32MSB",
+ "BFD_RELOC_IA64_PCREL32LSB",
+ "BFD_RELOC_IA64_PCREL64MSB",
+ "BFD_RELOC_IA64_PCREL64LSB",
+ "BFD_RELOC_IA64_LTOFF_FPTR22",
+ "BFD_RELOC_IA64_LTOFF_FPTR64I",
+ "BFD_RELOC_IA64_LTOFF_FPTR32MSB",
+ "BFD_RELOC_IA64_LTOFF_FPTR32LSB",
+ "BFD_RELOC_IA64_LTOFF_FPTR64MSB",
+ "BFD_RELOC_IA64_LTOFF_FPTR64LSB",
+ "BFD_RELOC_IA64_SEGREL32MSB",
+ "BFD_RELOC_IA64_SEGREL32LSB",
+ "BFD_RELOC_IA64_SEGREL64MSB",
+ "BFD_RELOC_IA64_SEGREL64LSB",
+ "BFD_RELOC_IA64_SECREL32MSB",
+ "BFD_RELOC_IA64_SECREL32LSB",
+ "BFD_RELOC_IA64_SECREL64MSB",
+ "BFD_RELOC_IA64_SECREL64LSB",
+ "BFD_RELOC_IA64_REL32MSB",
+ "BFD_RELOC_IA64_REL32LSB",
+ "BFD_RELOC_IA64_REL64MSB",
+ "BFD_RELOC_IA64_REL64LSB",
+ "BFD_RELOC_IA64_LTV32MSB",
+ "BFD_RELOC_IA64_LTV32LSB",
+ "BFD_RELOC_IA64_LTV64MSB",
+ "BFD_RELOC_IA64_LTV64LSB",
+ "BFD_RELOC_IA64_IPLTMSB",
+ "BFD_RELOC_IA64_IPLTLSB",
+ "BFD_RELOC_IA64_COPY",
+ "BFD_RELOC_IA64_LTOFF22X",
+ "BFD_RELOC_IA64_LDXMOV",
+ "BFD_RELOC_IA64_TPREL14",
+ "BFD_RELOC_IA64_TPREL22",
+ "BFD_RELOC_IA64_TPREL64I",
+ "BFD_RELOC_IA64_TPREL64MSB",
+ "BFD_RELOC_IA64_TPREL64LSB",
+ "BFD_RELOC_IA64_LTOFF_TPREL22",
+ "BFD_RELOC_IA64_DTPMOD64MSB",
+ "BFD_RELOC_IA64_DTPMOD64LSB",
+ "BFD_RELOC_IA64_LTOFF_DTPMOD22",
+ "BFD_RELOC_IA64_DTPREL14",
+ "BFD_RELOC_IA64_DTPREL22",
+ "BFD_RELOC_IA64_DTPREL64I",
+ "BFD_RELOC_IA64_DTPREL32MSB",
+ "BFD_RELOC_IA64_DTPREL32LSB",
+ "BFD_RELOC_IA64_DTPREL64MSB",
+ "BFD_RELOC_IA64_DTPREL64LSB",
+ "BFD_RELOC_IA64_LTOFF_DTPREL22",
+ "BFD_RELOC_M68HC11_HI8",
+ "BFD_RELOC_M68HC11_LO8",
+ "BFD_RELOC_M68HC11_3B",
+ "BFD_RELOC_M68HC11_RL_JUMP",
+ "BFD_RELOC_M68HC11_RL_GROUP",
+ "BFD_RELOC_M68HC11_LO16",
+ "BFD_RELOC_M68HC11_PAGE",
+ "BFD_RELOC_M68HC11_24",
+ "BFD_RELOC_M68HC12_5B",
+ "BFD_RELOC_XGATE_RL_JUMP",
+ "BFD_RELOC_XGATE_RL_GROUP",
+ "BFD_RELOC_XGATE_LO16",
+ "BFD_RELOC_XGATE_GPAGE",
+ "BFD_RELOC_XGATE_24",
+ "BFD_RELOC_XGATE_PCREL_9",
+ "BFD_RELOC_XGATE_PCREL_10",
+ "BFD_RELOC_XGATE_IMM8_LO",
+ "BFD_RELOC_XGATE_IMM8_HI",
+ "BFD_RELOC_XGATE_IMM3",
+ "BFD_RELOC_XGATE_IMM4",
+ "BFD_RELOC_XGATE_IMM5",
+ "BFD_RELOC_M68HC12_9B",
+ "BFD_RELOC_M68HC12_16B",
+ "BFD_RELOC_M68HC12_9_PCREL",
+ "BFD_RELOC_M68HC12_10_PCREL",
+ "BFD_RELOC_M68HC12_LO8XG",
+ "BFD_RELOC_M68HC12_HI8XG",
+ "BFD_RELOC_16C_NUM08",
+ "BFD_RELOC_16C_NUM08_C",
+ "BFD_RELOC_16C_NUM16",
+ "BFD_RELOC_16C_NUM16_C",
+ "BFD_RELOC_16C_NUM32",
+ "BFD_RELOC_16C_NUM32_C",
+ "BFD_RELOC_16C_DISP04",
+ "BFD_RELOC_16C_DISP04_C",
+ "BFD_RELOC_16C_DISP08",
+ "BFD_RELOC_16C_DISP08_C",
+ "BFD_RELOC_16C_DISP16",
+ "BFD_RELOC_16C_DISP16_C",
+ "BFD_RELOC_16C_DISP24",
+ "BFD_RELOC_16C_DISP24_C",
+ "BFD_RELOC_16C_DISP24a",
+ "BFD_RELOC_16C_DISP24a_C",
+ "BFD_RELOC_16C_REG04",
+ "BFD_RELOC_16C_REG04_C",
+ "BFD_RELOC_16C_REG04a",
+ "BFD_RELOC_16C_REG04a_C",
+ "BFD_RELOC_16C_REG14",
+ "BFD_RELOC_16C_REG14_C",
+ "BFD_RELOC_16C_REG16",
+ "BFD_RELOC_16C_REG16_C",
+ "BFD_RELOC_16C_REG20",
+ "BFD_RELOC_16C_REG20_C",
+ "BFD_RELOC_16C_ABS20",
+ "BFD_RELOC_16C_ABS20_C",
+ "BFD_RELOC_16C_ABS24",
+ "BFD_RELOC_16C_ABS24_C",
+ "BFD_RELOC_16C_IMM04",
+ "BFD_RELOC_16C_IMM04_C",
+ "BFD_RELOC_16C_IMM16",
+ "BFD_RELOC_16C_IMM16_C",
+ "BFD_RELOC_16C_IMM20",
+ "BFD_RELOC_16C_IMM20_C",
+ "BFD_RELOC_16C_IMM24",
+ "BFD_RELOC_16C_IMM24_C",
+ "BFD_RELOC_16C_IMM32",
+ "BFD_RELOC_16C_IMM32_C",
+ "BFD_RELOC_CR16_NUM8",
+ "BFD_RELOC_CR16_NUM16",
+ "BFD_RELOC_CR16_NUM32",
+ "BFD_RELOC_CR16_NUM32a",
+ "BFD_RELOC_CR16_REGREL0",
+ "BFD_RELOC_CR16_REGREL4",
+ "BFD_RELOC_CR16_REGREL4a",
+ "BFD_RELOC_CR16_REGREL14",
+ "BFD_RELOC_CR16_REGREL14a",
+ "BFD_RELOC_CR16_REGREL16",
+ "BFD_RELOC_CR16_REGREL20",
+ "BFD_RELOC_CR16_REGREL20a",
+ "BFD_RELOC_CR16_ABS20",
+ "BFD_RELOC_CR16_ABS24",
+ "BFD_RELOC_CR16_IMM4",
+ "BFD_RELOC_CR16_IMM8",
+ "BFD_RELOC_CR16_IMM16",
+ "BFD_RELOC_CR16_IMM20",
+ "BFD_RELOC_CR16_IMM24",
+ "BFD_RELOC_CR16_IMM32",
+ "BFD_RELOC_CR16_IMM32a",
+ "BFD_RELOC_CR16_DISP4",
+ "BFD_RELOC_CR16_DISP8",
+ "BFD_RELOC_CR16_DISP16",
+ "BFD_RELOC_CR16_DISP20",
+ "BFD_RELOC_CR16_DISP24",
+ "BFD_RELOC_CR16_DISP24a",
+ "BFD_RELOC_CR16_SWITCH8",
+ "BFD_RELOC_CR16_SWITCH16",
+ "BFD_RELOC_CR16_SWITCH32",
+ "BFD_RELOC_CR16_GOT_REGREL20",
+ "BFD_RELOC_CR16_GOTC_REGREL20",
+ "BFD_RELOC_CR16_GLOB_DAT",
+ "BFD_RELOC_CRX_REL4",
+ "BFD_RELOC_CRX_REL8",
+ "BFD_RELOC_CRX_REL8_CMP",
+ "BFD_RELOC_CRX_REL16",
+ "BFD_RELOC_CRX_REL24",
+ "BFD_RELOC_CRX_REL32",
+ "BFD_RELOC_CRX_REGREL12",
+ "BFD_RELOC_CRX_REGREL22",
+ "BFD_RELOC_CRX_REGREL28",
+ "BFD_RELOC_CRX_REGREL32",
+ "BFD_RELOC_CRX_ABS16",
+ "BFD_RELOC_CRX_ABS32",
+ "BFD_RELOC_CRX_NUM8",
+ "BFD_RELOC_CRX_NUM16",
+ "BFD_RELOC_CRX_NUM32",
+ "BFD_RELOC_CRX_IMM16",
+ "BFD_RELOC_CRX_IMM32",
+ "BFD_RELOC_CRX_SWITCH8",
+ "BFD_RELOC_CRX_SWITCH16",
+ "BFD_RELOC_CRX_SWITCH32",
+ "BFD_RELOC_CRIS_BDISP8",
+ "BFD_RELOC_CRIS_UNSIGNED_5",
+ "BFD_RELOC_CRIS_SIGNED_6",
+ "BFD_RELOC_CRIS_UNSIGNED_6",
+ "BFD_RELOC_CRIS_SIGNED_8",
+ "BFD_RELOC_CRIS_UNSIGNED_8",
+ "BFD_RELOC_CRIS_SIGNED_16",
+ "BFD_RELOC_CRIS_UNSIGNED_16",
+ "BFD_RELOC_CRIS_LAPCQ_OFFSET",
+ "BFD_RELOC_CRIS_UNSIGNED_4",
+ "BFD_RELOC_CRIS_COPY",
+ "BFD_RELOC_CRIS_GLOB_DAT",
+ "BFD_RELOC_CRIS_JUMP_SLOT",
+ "BFD_RELOC_CRIS_RELATIVE",
+ "BFD_RELOC_CRIS_32_GOT",
+ "BFD_RELOC_CRIS_16_GOT",
+ "BFD_RELOC_CRIS_32_GOTPLT",
+ "BFD_RELOC_CRIS_16_GOTPLT",
+ "BFD_RELOC_CRIS_32_GOTREL",
+ "BFD_RELOC_CRIS_32_PLT_GOTREL",
+ "BFD_RELOC_CRIS_32_PLT_PCREL",
+ "BFD_RELOC_CRIS_32_GOT_GD",
+ "BFD_RELOC_CRIS_16_GOT_GD",
+ "BFD_RELOC_CRIS_32_GD",
+ "BFD_RELOC_CRIS_DTP",
+ "BFD_RELOC_CRIS_32_DTPREL",
+ "BFD_RELOC_CRIS_16_DTPREL",
+ "BFD_RELOC_CRIS_32_GOT_TPREL",
+ "BFD_RELOC_CRIS_16_GOT_TPREL",
+ "BFD_RELOC_CRIS_32_TPREL",
+ "BFD_RELOC_CRIS_16_TPREL",
+ "BFD_RELOC_CRIS_DTPMOD",
+ "BFD_RELOC_CRIS_32_IE",
+ "BFD_RELOC_860_COPY",
+ "BFD_RELOC_860_GLOB_DAT",
+ "BFD_RELOC_860_JUMP_SLOT",
+ "BFD_RELOC_860_RELATIVE",
+ "BFD_RELOC_860_PC26",
+ "BFD_RELOC_860_PLT26",
+ "BFD_RELOC_860_PC16",
+ "BFD_RELOC_860_LOW0",
+ "BFD_RELOC_860_SPLIT0",
+ "BFD_RELOC_860_LOW1",
+ "BFD_RELOC_860_SPLIT1",
+ "BFD_RELOC_860_LOW2",
+ "BFD_RELOC_860_SPLIT2",
+ "BFD_RELOC_860_LOW3",
+ "BFD_RELOC_860_LOGOT0",
+ "BFD_RELOC_860_SPGOT0",
+ "BFD_RELOC_860_LOGOT1",
+ "BFD_RELOC_860_SPGOT1",
+ "BFD_RELOC_860_LOGOTOFF0",
+ "BFD_RELOC_860_SPGOTOFF0",
+ "BFD_RELOC_860_LOGOTOFF1",
+ "BFD_RELOC_860_SPGOTOFF1",
+ "BFD_RELOC_860_LOGOTOFF2",
+ "BFD_RELOC_860_LOGOTOFF3",
+ "BFD_RELOC_860_LOPC",
+ "BFD_RELOC_860_HIGHADJ",
+ "BFD_RELOC_860_HAGOT",
+ "BFD_RELOC_860_HAGOTOFF",
+ "BFD_RELOC_860_HAPC",
+ "BFD_RELOC_860_HIGH",
+ "BFD_RELOC_860_HIGOT",
+ "BFD_RELOC_860_HIGOTOFF",
+ "BFD_RELOC_OR1K_REL_26",
+ "BFD_RELOC_OR1K_GOTPC_HI16",
+ "BFD_RELOC_OR1K_GOTPC_LO16",
+ "BFD_RELOC_OR1K_GOT16",
+ "BFD_RELOC_OR1K_PLT26",
+ "BFD_RELOC_OR1K_GOTOFF_HI16",
+ "BFD_RELOC_OR1K_GOTOFF_LO16",
+ "BFD_RELOC_OR1K_COPY",
+ "BFD_RELOC_OR1K_GLOB_DAT",
+ "BFD_RELOC_OR1K_JMP_SLOT",
+ "BFD_RELOC_OR1K_RELATIVE",
+ "BFD_RELOC_OR1K_TLS_GD_HI16",
+ "BFD_RELOC_OR1K_TLS_GD_LO16",
+ "BFD_RELOC_OR1K_TLS_LDM_HI16",
+ "BFD_RELOC_OR1K_TLS_LDM_LO16",
+ "BFD_RELOC_OR1K_TLS_LDO_HI16",
+ "BFD_RELOC_OR1K_TLS_LDO_LO16",
+ "BFD_RELOC_OR1K_TLS_IE_HI16",
+ "BFD_RELOC_OR1K_TLS_IE_LO16",
+ "BFD_RELOC_OR1K_TLS_LE_HI16",
+ "BFD_RELOC_OR1K_TLS_LE_LO16",
+ "BFD_RELOC_OR1K_TLS_TPOFF",
+ "BFD_RELOC_OR1K_TLS_DTPOFF",
+ "BFD_RELOC_OR1K_TLS_DTPMOD",
+ "BFD_RELOC_H8_DIR16A8",
+ "BFD_RELOC_H8_DIR16R8",
+ "BFD_RELOC_H8_DIR24A8",
+ "BFD_RELOC_H8_DIR24R8",
+ "BFD_RELOC_H8_DIR32A16",
+ "BFD_RELOC_H8_DISP32A16",
+ "BFD_RELOC_XSTORMY16_REL_12",
+ "BFD_RELOC_XSTORMY16_12",
+ "BFD_RELOC_XSTORMY16_24",
+ "BFD_RELOC_XSTORMY16_FPTR16",
+ "BFD_RELOC_RELC",
+
+ "BFD_RELOC_XC16X_PAG",
+ "BFD_RELOC_XC16X_POF",
+ "BFD_RELOC_XC16X_SEG",
+ "BFD_RELOC_XC16X_SOF",
+ "BFD_RELOC_VAX_GLOB_DAT",
+ "BFD_RELOC_VAX_JMP_SLOT",
+ "BFD_RELOC_VAX_RELATIVE",
+ "BFD_RELOC_MT_PC16",
+ "BFD_RELOC_MT_HI16",
+ "BFD_RELOC_MT_LO16",
+ "BFD_RELOC_MT_GNU_VTINHERIT",
+ "BFD_RELOC_MT_GNU_VTENTRY",
+ "BFD_RELOC_MT_PCINSN8",
+ "BFD_RELOC_MSP430_10_PCREL",
+ "BFD_RELOC_MSP430_16_PCREL",
+ "BFD_RELOC_MSP430_16",
+ "BFD_RELOC_MSP430_16_PCREL_BYTE",
+ "BFD_RELOC_MSP430_16_BYTE",
+ "BFD_RELOC_MSP430_2X_PCREL",
+ "BFD_RELOC_MSP430_RL_PCREL",
+ "BFD_RELOC_MSP430_ABS8",
+ "BFD_RELOC_MSP430X_PCR20_EXT_SRC",
+ "BFD_RELOC_MSP430X_PCR20_EXT_DST",
+ "BFD_RELOC_MSP430X_PCR20_EXT_ODST",
+ "BFD_RELOC_MSP430X_ABS20_EXT_SRC",
+ "BFD_RELOC_MSP430X_ABS20_EXT_DST",
+ "BFD_RELOC_MSP430X_ABS20_EXT_ODST",
+ "BFD_RELOC_MSP430X_ABS20_ADR_SRC",
+ "BFD_RELOC_MSP430X_ABS20_ADR_DST",
+ "BFD_RELOC_MSP430X_PCR16",
+ "BFD_RELOC_MSP430X_PCR20_CALL",
+ "BFD_RELOC_MSP430X_ABS16",
+ "BFD_RELOC_MSP430_ABS_HI16",
+ "BFD_RELOC_MSP430_PREL31",
+ "BFD_RELOC_MSP430_SYM_DIFF",
+ "BFD_RELOC_NIOS2_S16",
+ "BFD_RELOC_NIOS2_U16",
+ "BFD_RELOC_NIOS2_CALL26",
+ "BFD_RELOC_NIOS2_IMM5",
+ "BFD_RELOC_NIOS2_CACHE_OPX",
+ "BFD_RELOC_NIOS2_IMM6",
+ "BFD_RELOC_NIOS2_IMM8",
+ "BFD_RELOC_NIOS2_HI16",
+ "BFD_RELOC_NIOS2_LO16",
+ "BFD_RELOC_NIOS2_HIADJ16",
+ "BFD_RELOC_NIOS2_GPREL",
+ "BFD_RELOC_NIOS2_UJMP",
+ "BFD_RELOC_NIOS2_CJMP",
+ "BFD_RELOC_NIOS2_CALLR",
+ "BFD_RELOC_NIOS2_ALIGN",
+ "BFD_RELOC_NIOS2_GOT16",
+ "BFD_RELOC_NIOS2_CALL16",
+ "BFD_RELOC_NIOS2_GOTOFF_LO",
+ "BFD_RELOC_NIOS2_GOTOFF_HA",
+ "BFD_RELOC_NIOS2_PCREL_LO",
+ "BFD_RELOC_NIOS2_PCREL_HA",
+ "BFD_RELOC_NIOS2_TLS_GD16",
+ "BFD_RELOC_NIOS2_TLS_LDM16",
+ "BFD_RELOC_NIOS2_TLS_LDO16",
+ "BFD_RELOC_NIOS2_TLS_IE16",
+ "BFD_RELOC_NIOS2_TLS_LE16",
+ "BFD_RELOC_NIOS2_TLS_DTPMOD",
+ "BFD_RELOC_NIOS2_TLS_DTPREL",
+ "BFD_RELOC_NIOS2_TLS_TPREL",
+ "BFD_RELOC_NIOS2_COPY",
+ "BFD_RELOC_NIOS2_GLOB_DAT",
+ "BFD_RELOC_NIOS2_JUMP_SLOT",
+ "BFD_RELOC_NIOS2_RELATIVE",
+ "BFD_RELOC_NIOS2_GOTOFF",
+ "BFD_RELOC_NIOS2_CALL26_NOAT",
+ "BFD_RELOC_NIOS2_GOT_LO",
+ "BFD_RELOC_NIOS2_GOT_HA",
+ "BFD_RELOC_NIOS2_CALL_LO",
+ "BFD_RELOC_NIOS2_CALL_HA",
+ "BFD_RELOC_IQ2000_OFFSET_16",
+ "BFD_RELOC_IQ2000_OFFSET_21",
+ "BFD_RELOC_IQ2000_UHI16",
+ "BFD_RELOC_XTENSA_RTLD",
+ "BFD_RELOC_XTENSA_GLOB_DAT",
+ "BFD_RELOC_XTENSA_JMP_SLOT",
+ "BFD_RELOC_XTENSA_RELATIVE",
+ "BFD_RELOC_XTENSA_PLT",
+ "BFD_RELOC_XTENSA_DIFF8",
+ "BFD_RELOC_XTENSA_DIFF16",
+ "BFD_RELOC_XTENSA_DIFF32",
+ "BFD_RELOC_XTENSA_SLOT0_OP",
+ "BFD_RELOC_XTENSA_SLOT1_OP",
+ "BFD_RELOC_XTENSA_SLOT2_OP",
+ "BFD_RELOC_XTENSA_SLOT3_OP",
+ "BFD_RELOC_XTENSA_SLOT4_OP",
+ "BFD_RELOC_XTENSA_SLOT5_OP",
+ "BFD_RELOC_XTENSA_SLOT6_OP",
+ "BFD_RELOC_XTENSA_SLOT7_OP",
+ "BFD_RELOC_XTENSA_SLOT8_OP",
+ "BFD_RELOC_XTENSA_SLOT9_OP",
+ "BFD_RELOC_XTENSA_SLOT10_OP",
+ "BFD_RELOC_XTENSA_SLOT11_OP",
+ "BFD_RELOC_XTENSA_SLOT12_OP",
+ "BFD_RELOC_XTENSA_SLOT13_OP",
+ "BFD_RELOC_XTENSA_SLOT14_OP",
+ "BFD_RELOC_XTENSA_SLOT0_ALT",
+ "BFD_RELOC_XTENSA_SLOT1_ALT",
+ "BFD_RELOC_XTENSA_SLOT2_ALT",
+ "BFD_RELOC_XTENSA_SLOT3_ALT",
+ "BFD_RELOC_XTENSA_SLOT4_ALT",
+ "BFD_RELOC_XTENSA_SLOT5_ALT",
+ "BFD_RELOC_XTENSA_SLOT6_ALT",
+ "BFD_RELOC_XTENSA_SLOT7_ALT",
+ "BFD_RELOC_XTENSA_SLOT8_ALT",
+ "BFD_RELOC_XTENSA_SLOT9_ALT",
+ "BFD_RELOC_XTENSA_SLOT10_ALT",
+ "BFD_RELOC_XTENSA_SLOT11_ALT",
+ "BFD_RELOC_XTENSA_SLOT12_ALT",
+ "BFD_RELOC_XTENSA_SLOT13_ALT",
+ "BFD_RELOC_XTENSA_SLOT14_ALT",
+ "BFD_RELOC_XTENSA_OP0",
+ "BFD_RELOC_XTENSA_OP1",
+ "BFD_RELOC_XTENSA_OP2",
+ "BFD_RELOC_XTENSA_ASM_EXPAND",
+ "BFD_RELOC_XTENSA_ASM_SIMPLIFY",
+ "BFD_RELOC_XTENSA_TLSDESC_FN",
+ "BFD_RELOC_XTENSA_TLSDESC_ARG",
+ "BFD_RELOC_XTENSA_TLS_DTPOFF",
+ "BFD_RELOC_XTENSA_TLS_TPOFF",
+ "BFD_RELOC_XTENSA_TLS_FUNC",
+ "BFD_RELOC_XTENSA_TLS_ARG",
+ "BFD_RELOC_XTENSA_TLS_CALL",
+ "BFD_RELOC_Z80_DISP8",
+ "BFD_RELOC_Z8K_DISP7",
+ "BFD_RELOC_Z8K_CALLR",
+ "BFD_RELOC_Z8K_IMM4L",
+ "BFD_RELOC_LM32_CALL",
+ "BFD_RELOC_LM32_BRANCH",
+ "BFD_RELOC_LM32_16_GOT",
+ "BFD_RELOC_LM32_GOTOFF_HI16",
+ "BFD_RELOC_LM32_GOTOFF_LO16",
+ "BFD_RELOC_LM32_COPY",
+ "BFD_RELOC_LM32_GLOB_DAT",
+ "BFD_RELOC_LM32_JMP_SLOT",
+ "BFD_RELOC_LM32_RELATIVE",
+ "BFD_RELOC_MACH_O_SECTDIFF",
+ "BFD_RELOC_MACH_O_LOCAL_SECTDIFF",
+ "BFD_RELOC_MACH_O_PAIR",
+ "BFD_RELOC_MACH_O_X86_64_BRANCH32",
+ "BFD_RELOC_MACH_O_X86_64_BRANCH8",
+ "BFD_RELOC_MACH_O_X86_64_GOT",
+ "BFD_RELOC_MACH_O_X86_64_GOT_LOAD",
+ "BFD_RELOC_MACH_O_X86_64_SUBTRACTOR32",
+ "BFD_RELOC_MACH_O_X86_64_SUBTRACTOR64",
+ "BFD_RELOC_MACH_O_X86_64_PCREL32_1",
+ "BFD_RELOC_MACH_O_X86_64_PCREL32_2",
+ "BFD_RELOC_MACH_O_X86_64_PCREL32_4",
+ "BFD_RELOC_MICROBLAZE_32_LO",
+ "BFD_RELOC_MICROBLAZE_32_LO_PCREL",
+ "BFD_RELOC_MICROBLAZE_32_ROSDA",
+ "BFD_RELOC_MICROBLAZE_32_RWSDA",
+ "BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM",
+ "BFD_RELOC_MICROBLAZE_64_NONE",
+ "BFD_RELOC_MICROBLAZE_64_GOTPC",
+ "BFD_RELOC_MICROBLAZE_64_GOT",
+ "BFD_RELOC_MICROBLAZE_64_PLT",
+ "BFD_RELOC_MICROBLAZE_64_GOTOFF",
+ "BFD_RELOC_MICROBLAZE_32_GOTOFF",
+ "BFD_RELOC_MICROBLAZE_COPY",
+ "BFD_RELOC_MICROBLAZE_64_TLS",
+ "BFD_RELOC_MICROBLAZE_64_TLSGD",
+ "BFD_RELOC_MICROBLAZE_64_TLSLD",
+ "BFD_RELOC_MICROBLAZE_32_TLSDTPMOD",
+ "BFD_RELOC_MICROBLAZE_32_TLSDTPREL",
+ "BFD_RELOC_MICROBLAZE_64_TLSDTPREL",
+ "BFD_RELOC_MICROBLAZE_64_TLSGOTTPREL",
+ "BFD_RELOC_MICROBLAZE_64_TLSTPREL",
+ "BFD_RELOC_AARCH64_RELOC_START",
+ "BFD_RELOC_AARCH64_NONE",
+ "BFD_RELOC_AARCH64_64",
+ "BFD_RELOC_AARCH64_32",
+ "BFD_RELOC_AARCH64_16",
+ "BFD_RELOC_AARCH64_64_PCREL",
+ "BFD_RELOC_AARCH64_32_PCREL",
+ "BFD_RELOC_AARCH64_16_PCREL",
+ "BFD_RELOC_AARCH64_MOVW_G0",
+ "BFD_RELOC_AARCH64_MOVW_G0_NC",
+ "BFD_RELOC_AARCH64_MOVW_G1",
+ "BFD_RELOC_AARCH64_MOVW_G1_NC",
+ "BFD_RELOC_AARCH64_MOVW_G2",
+ "BFD_RELOC_AARCH64_MOVW_G2_NC",
+ "BFD_RELOC_AARCH64_MOVW_G3",
+ "BFD_RELOC_AARCH64_MOVW_G0_S",
+ "BFD_RELOC_AARCH64_MOVW_G1_S",
+ "BFD_RELOC_AARCH64_MOVW_G2_S",
+ "BFD_RELOC_AARCH64_LD_LO19_PCREL",
+ "BFD_RELOC_AARCH64_ADR_LO21_PCREL",
+ "BFD_RELOC_AARCH64_ADR_HI21_PCREL",
+ "BFD_RELOC_AARCH64_ADR_HI21_NC_PCREL",
+ "BFD_RELOC_AARCH64_ADD_LO12",
+ "BFD_RELOC_AARCH64_LDST8_LO12",
+ "BFD_RELOC_AARCH64_TSTBR14",
+ "BFD_RELOC_AARCH64_BRANCH19",
+ "BFD_RELOC_AARCH64_JUMP26",
+ "BFD_RELOC_AARCH64_CALL26",
+ "BFD_RELOC_AARCH64_LDST16_LO12",
+ "BFD_RELOC_AARCH64_LDST32_LO12",
+ "BFD_RELOC_AARCH64_LDST64_LO12",
+ "BFD_RELOC_AARCH64_LDST128_LO12",
+ "BFD_RELOC_AARCH64_GOT_LD_PREL19",
+ "BFD_RELOC_AARCH64_ADR_GOT_PAGE",
+ "BFD_RELOC_AARCH64_LD64_GOT_LO12_NC",
+ "BFD_RELOC_AARCH64_LD32_GOT_LO12_NC",
+ "BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21",
+ "BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC",
+ "BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G1",
+ "BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC",
+ "BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21",
+ "BFD_RELOC_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC",
+ "BFD_RELOC_AARCH64_TLSIE_LD32_GOTTPREL_LO12_NC",
+ "BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19",
+ "BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G2",
+ "BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1",
+ "BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1_NC",
+ "BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0",
+ "BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC",
+ "BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_HI12",
+ "BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12",
+ "BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12_NC",
+ "BFD_RELOC_AARCH64_TLSDESC_LD_PREL19",
+ "BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21",
+ "BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21",
+ "BFD_RELOC_AARCH64_TLSDESC_LD64_LO12_NC",
+ "BFD_RELOC_AARCH64_TLSDESC_LD32_LO12_NC",
+ "BFD_RELOC_AARCH64_TLSDESC_ADD_LO12_NC",
+ "BFD_RELOC_AARCH64_TLSDESC_OFF_G1",
+ "BFD_RELOC_AARCH64_TLSDESC_OFF_G0_NC",
+ "BFD_RELOC_AARCH64_TLSDESC_LDR",
+ "BFD_RELOC_AARCH64_TLSDESC_ADD",
+ "BFD_RELOC_AARCH64_TLSDESC_CALL",
+ "BFD_RELOC_AARCH64_COPY",
+ "BFD_RELOC_AARCH64_GLOB_DAT",
+ "BFD_RELOC_AARCH64_JUMP_SLOT",
+ "BFD_RELOC_AARCH64_RELATIVE",
+ "BFD_RELOC_AARCH64_TLS_DTPMOD",
+ "BFD_RELOC_AARCH64_TLS_DTPREL",
+ "BFD_RELOC_AARCH64_TLS_TPREL",
+ "BFD_RELOC_AARCH64_TLSDESC",
+ "BFD_RELOC_AARCH64_IRELATIVE",
+ "BFD_RELOC_AARCH64_RELOC_END",
+ "BFD_RELOC_AARCH64_GAS_INTERNAL_FIXUP",
+ "BFD_RELOC_AARCH64_LDST_LO12",
+ "BFD_RELOC_AARCH64_LD_GOT_LO12_NC",
+ "BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_LO12_NC",
+ "BFD_RELOC_AARCH64_TLSDESC_LD_LO12_NC",
+ "BFD_RELOC_TILEPRO_COPY",
+ "BFD_RELOC_TILEPRO_GLOB_DAT",
+ "BFD_RELOC_TILEPRO_JMP_SLOT",
+ "BFD_RELOC_TILEPRO_RELATIVE",
+ "BFD_RELOC_TILEPRO_BROFF_X1",
+ "BFD_RELOC_TILEPRO_JOFFLONG_X1",
+ "BFD_RELOC_TILEPRO_JOFFLONG_X1_PLT",
+ "BFD_RELOC_TILEPRO_IMM8_X0",
+ "BFD_RELOC_TILEPRO_IMM8_Y0",
+ "BFD_RELOC_TILEPRO_IMM8_X1",
+ "BFD_RELOC_TILEPRO_IMM8_Y1",
+ "BFD_RELOC_TILEPRO_DEST_IMM8_X1",
+ "BFD_RELOC_TILEPRO_MT_IMM15_X1",
+ "BFD_RELOC_TILEPRO_MF_IMM15_X1",
+ "BFD_RELOC_TILEPRO_IMM16_X0",
+ "BFD_RELOC_TILEPRO_IMM16_X1",
+ "BFD_RELOC_TILEPRO_IMM16_X0_LO",
+ "BFD_RELOC_TILEPRO_IMM16_X1_LO",
+ "BFD_RELOC_TILEPRO_IMM16_X0_HI",
+ "BFD_RELOC_TILEPRO_IMM16_X1_HI",
+ "BFD_RELOC_TILEPRO_IMM16_X0_HA",
+ "BFD_RELOC_TILEPRO_IMM16_X1_HA",
+ "BFD_RELOC_TILEPRO_IMM16_X0_PCREL",
+ "BFD_RELOC_TILEPRO_IMM16_X1_PCREL",
+ "BFD_RELOC_TILEPRO_IMM16_X0_LO_PCREL",
+ "BFD_RELOC_TILEPRO_IMM16_X1_LO_PCREL",
+ "BFD_RELOC_TILEPRO_IMM16_X0_HI_PCREL",
+ "BFD_RELOC_TILEPRO_IMM16_X1_HI_PCREL",
+ "BFD_RELOC_TILEPRO_IMM16_X0_HA_PCREL",
+ "BFD_RELOC_TILEPRO_IMM16_X1_HA_PCREL",
+ "BFD_RELOC_TILEPRO_IMM16_X0_GOT",
+ "BFD_RELOC_TILEPRO_IMM16_X1_GOT",
+ "BFD_RELOC_TILEPRO_IMM16_X0_GOT_LO",
+ "BFD_RELOC_TILEPRO_IMM16_X1_GOT_LO",
+ "BFD_RELOC_TILEPRO_IMM16_X0_GOT_HI",
+ "BFD_RELOC_TILEPRO_IMM16_X1_GOT_HI",
+ "BFD_RELOC_TILEPRO_IMM16_X0_GOT_HA",
+ "BFD_RELOC_TILEPRO_IMM16_X1_GOT_HA",
+ "BFD_RELOC_TILEPRO_MMSTART_X0",
+ "BFD_RELOC_TILEPRO_MMEND_X0",
+ "BFD_RELOC_TILEPRO_MMSTART_X1",
+ "BFD_RELOC_TILEPRO_MMEND_X1",
+ "BFD_RELOC_TILEPRO_SHAMT_X0",
+ "BFD_RELOC_TILEPRO_SHAMT_X1",
+ "BFD_RELOC_TILEPRO_SHAMT_Y0",
+ "BFD_RELOC_TILEPRO_SHAMT_Y1",
+ "BFD_RELOC_TILEPRO_TLS_GD_CALL",
+ "BFD_RELOC_TILEPRO_IMM8_X0_TLS_GD_ADD",
+ "BFD_RELOC_TILEPRO_IMM8_X1_TLS_GD_ADD",
+ "BFD_RELOC_TILEPRO_IMM8_Y0_TLS_GD_ADD",
+ "BFD_RELOC_TILEPRO_IMM8_Y1_TLS_GD_ADD",
+ "BFD_RELOC_TILEPRO_TLS_IE_LOAD",
+ "BFD_RELOC_TILEPRO_IMM16_X0_TLS_GD",
+ "BFD_RELOC_TILEPRO_IMM16_X1_TLS_GD",
+ "BFD_RELOC_TILEPRO_IMM16_X0_TLS_GD_LO",
+ "BFD_RELOC_TILEPRO_IMM16_X1_TLS_GD_LO",
+ "BFD_RELOC_TILEPRO_IMM16_X0_TLS_GD_HI",
+ "BFD_RELOC_TILEPRO_IMM16_X1_TLS_GD_HI",
+ "BFD_RELOC_TILEPRO_IMM16_X0_TLS_GD_HA",
+ "BFD_RELOC_TILEPRO_IMM16_X1_TLS_GD_HA",
+ "BFD_RELOC_TILEPRO_IMM16_X0_TLS_IE",
+ "BFD_RELOC_TILEPRO_IMM16_X1_TLS_IE",
+ "BFD_RELOC_TILEPRO_IMM16_X0_TLS_IE_LO",
+ "BFD_RELOC_TILEPRO_IMM16_X1_TLS_IE_LO",
+ "BFD_RELOC_TILEPRO_IMM16_X0_TLS_IE_HI",
+ "BFD_RELOC_TILEPRO_IMM16_X1_TLS_IE_HI",
+ "BFD_RELOC_TILEPRO_IMM16_X0_TLS_IE_HA",
+ "BFD_RELOC_TILEPRO_IMM16_X1_TLS_IE_HA",
+ "BFD_RELOC_TILEPRO_TLS_DTPMOD32",
+ "BFD_RELOC_TILEPRO_TLS_DTPOFF32",
+ "BFD_RELOC_TILEPRO_TLS_TPOFF32",
+ "BFD_RELOC_TILEPRO_IMM16_X0_TLS_LE",
+ "BFD_RELOC_TILEPRO_IMM16_X1_TLS_LE",
+ "BFD_RELOC_TILEPRO_IMM16_X0_TLS_LE_LO",
+ "BFD_RELOC_TILEPRO_IMM16_X1_TLS_LE_LO",
+ "BFD_RELOC_TILEPRO_IMM16_X0_TLS_LE_HI",
+ "BFD_RELOC_TILEPRO_IMM16_X1_TLS_LE_HI",
+ "BFD_RELOC_TILEPRO_IMM16_X0_TLS_LE_HA",
+ "BFD_RELOC_TILEPRO_IMM16_X1_TLS_LE_HA",
+ "BFD_RELOC_TILEGX_HW0",
+ "BFD_RELOC_TILEGX_HW1",
+ "BFD_RELOC_TILEGX_HW2",
+ "BFD_RELOC_TILEGX_HW3",
+ "BFD_RELOC_TILEGX_HW0_LAST",
+ "BFD_RELOC_TILEGX_HW1_LAST",
+ "BFD_RELOC_TILEGX_HW2_LAST",
+ "BFD_RELOC_TILEGX_COPY",
+ "BFD_RELOC_TILEGX_GLOB_DAT",
+ "BFD_RELOC_TILEGX_JMP_SLOT",
+ "BFD_RELOC_TILEGX_RELATIVE",
+ "BFD_RELOC_TILEGX_BROFF_X1",
+ "BFD_RELOC_TILEGX_JUMPOFF_X1",
+ "BFD_RELOC_TILEGX_JUMPOFF_X1_PLT",
+ "BFD_RELOC_TILEGX_IMM8_X0",
+ "BFD_RELOC_TILEGX_IMM8_Y0",
+ "BFD_RELOC_TILEGX_IMM8_X1",
+ "BFD_RELOC_TILEGX_IMM8_Y1",
+ "BFD_RELOC_TILEGX_DEST_IMM8_X1",
+ "BFD_RELOC_TILEGX_MT_IMM14_X1",
+ "BFD_RELOC_TILEGX_MF_IMM14_X1",
+ "BFD_RELOC_TILEGX_MMSTART_X0",
+ "BFD_RELOC_TILEGX_MMEND_X0",
+ "BFD_RELOC_TILEGX_SHAMT_X0",
+ "BFD_RELOC_TILEGX_SHAMT_X1",
+ "BFD_RELOC_TILEGX_SHAMT_Y0",
+ "BFD_RELOC_TILEGX_SHAMT_Y1",
+ "BFD_RELOC_TILEGX_IMM16_X0_HW0",
+ "BFD_RELOC_TILEGX_IMM16_X1_HW0",
+ "BFD_RELOC_TILEGX_IMM16_X0_HW1",
+ "BFD_RELOC_TILEGX_IMM16_X1_HW1",
+ "BFD_RELOC_TILEGX_IMM16_X0_HW2",
+ "BFD_RELOC_TILEGX_IMM16_X1_HW2",
+ "BFD_RELOC_TILEGX_IMM16_X0_HW3",
+ "BFD_RELOC_TILEGX_IMM16_X1_HW3",
+ "BFD_RELOC_TILEGX_IMM16_X0_HW0_LAST",
+ "BFD_RELOC_TILEGX_IMM16_X1_HW0_LAST",
+ "BFD_RELOC_TILEGX_IMM16_X0_HW1_LAST",
+ "BFD_RELOC_TILEGX_IMM16_X1_HW1_LAST",
+ "BFD_RELOC_TILEGX_IMM16_X0_HW2_LAST",
+ "BFD_RELOC_TILEGX_IMM16_X1_HW2_LAST",
+ "BFD_RELOC_TILEGX_IMM16_X0_HW0_PCREL",
+ "BFD_RELOC_TILEGX_IMM16_X1_HW0_PCREL",
+ "BFD_RELOC_TILEGX_IMM16_X0_HW1_PCREL",
+ "BFD_RELOC_TILEGX_IMM16_X1_HW1_PCREL",
+ "BFD_RELOC_TILEGX_IMM16_X0_HW2_PCREL",
+ "BFD_RELOC_TILEGX_IMM16_X1_HW2_PCREL",
+ "BFD_RELOC_TILEGX_IMM16_X0_HW3_PCREL",
+ "BFD_RELOC_TILEGX_IMM16_X1_HW3_PCREL",
+ "BFD_RELOC_TILEGX_IMM16_X0_HW0_LAST_PCREL",
+ "BFD_RELOC_TILEGX_IMM16_X1_HW0_LAST_PCREL",
+ "BFD_RELOC_TILEGX_IMM16_X0_HW1_LAST_PCREL",
+ "BFD_RELOC_TILEGX_IMM16_X1_HW1_LAST_PCREL",
+ "BFD_RELOC_TILEGX_IMM16_X0_HW2_LAST_PCREL",
+ "BFD_RELOC_TILEGX_IMM16_X1_HW2_LAST_PCREL",
+ "BFD_RELOC_TILEGX_IMM16_X0_HW0_GOT",
+ "BFD_RELOC_TILEGX_IMM16_X1_HW0_GOT",
+ "BFD_RELOC_TILEGX_IMM16_X0_HW0_PLT_PCREL",
+ "BFD_RELOC_TILEGX_IMM16_X1_HW0_PLT_PCREL",
+ "BFD_RELOC_TILEGX_IMM16_X0_HW1_PLT_PCREL",
+ "BFD_RELOC_TILEGX_IMM16_X1_HW1_PLT_PCREL",
+ "BFD_RELOC_TILEGX_IMM16_X0_HW2_PLT_PCREL",
+ "BFD_RELOC_TILEGX_IMM16_X1_HW2_PLT_PCREL",
+ "BFD_RELOC_TILEGX_IMM16_X0_HW0_LAST_GOT",
+ "BFD_RELOC_TILEGX_IMM16_X1_HW0_LAST_GOT",
+ "BFD_RELOC_TILEGX_IMM16_X0_HW1_LAST_GOT",
+ "BFD_RELOC_TILEGX_IMM16_X1_HW1_LAST_GOT",
+ "BFD_RELOC_TILEGX_IMM16_X0_HW3_PLT_PCREL",
+ "BFD_RELOC_TILEGX_IMM16_X1_HW3_PLT_PCREL",
+ "BFD_RELOC_TILEGX_IMM16_X0_HW0_TLS_GD",
+ "BFD_RELOC_TILEGX_IMM16_X1_HW0_TLS_GD",
+ "BFD_RELOC_TILEGX_IMM16_X0_HW0_TLS_LE",
+ "BFD_RELOC_TILEGX_IMM16_X1_HW0_TLS_LE",
+ "BFD_RELOC_TILEGX_IMM16_X0_HW0_LAST_TLS_LE",
+ "BFD_RELOC_TILEGX_IMM16_X1_HW0_LAST_TLS_LE",
+ "BFD_RELOC_TILEGX_IMM16_X0_HW1_LAST_TLS_LE",
+ "BFD_RELOC_TILEGX_IMM16_X1_HW1_LAST_TLS_LE",
+ "BFD_RELOC_TILEGX_IMM16_X0_HW0_LAST_TLS_GD",
+ "BFD_RELOC_TILEGX_IMM16_X1_HW0_LAST_TLS_GD",
+ "BFD_RELOC_TILEGX_IMM16_X0_HW1_LAST_TLS_GD",
+ "BFD_RELOC_TILEGX_IMM16_X1_HW1_LAST_TLS_GD",
+ "BFD_RELOC_TILEGX_IMM16_X0_HW0_TLS_IE",
+ "BFD_RELOC_TILEGX_IMM16_X1_HW0_TLS_IE",
+ "BFD_RELOC_TILEGX_IMM16_X0_HW0_LAST_PLT_PCREL",
+ "BFD_RELOC_TILEGX_IMM16_X1_HW0_LAST_PLT_PCREL",
+ "BFD_RELOC_TILEGX_IMM16_X0_HW1_LAST_PLT_PCREL",
+ "BFD_RELOC_TILEGX_IMM16_X1_HW1_LAST_PLT_PCREL",
+ "BFD_RELOC_TILEGX_IMM16_X0_HW2_LAST_PLT_PCREL",
+ "BFD_RELOC_TILEGX_IMM16_X1_HW2_LAST_PLT_PCREL",
+ "BFD_RELOC_TILEGX_IMM16_X0_HW0_LAST_TLS_IE",
+ "BFD_RELOC_TILEGX_IMM16_X1_HW0_LAST_TLS_IE",
+ "BFD_RELOC_TILEGX_IMM16_X0_HW1_LAST_TLS_IE",
+ "BFD_RELOC_TILEGX_IMM16_X1_HW1_LAST_TLS_IE",
+ "BFD_RELOC_TILEGX_TLS_DTPMOD64",
+ "BFD_RELOC_TILEGX_TLS_DTPOFF64",
+ "BFD_RELOC_TILEGX_TLS_TPOFF64",
+ "BFD_RELOC_TILEGX_TLS_DTPMOD32",
+ "BFD_RELOC_TILEGX_TLS_DTPOFF32",
+ "BFD_RELOC_TILEGX_TLS_TPOFF32",
+ "BFD_RELOC_TILEGX_TLS_GD_CALL",
+ "BFD_RELOC_TILEGX_IMM8_X0_TLS_GD_ADD",
+ "BFD_RELOC_TILEGX_IMM8_X1_TLS_GD_ADD",
+ "BFD_RELOC_TILEGX_IMM8_Y0_TLS_GD_ADD",
+ "BFD_RELOC_TILEGX_IMM8_Y1_TLS_GD_ADD",
+ "BFD_RELOC_TILEGX_TLS_IE_LOAD",
+ "BFD_RELOC_TILEGX_IMM8_X0_TLS_ADD",
+ "BFD_RELOC_TILEGX_IMM8_X1_TLS_ADD",
+ "BFD_RELOC_TILEGX_IMM8_Y0_TLS_ADD",
+ "BFD_RELOC_TILEGX_IMM8_Y1_TLS_ADD",
+ "BFD_RELOC_EPIPHANY_SIMM8",
+ "BFD_RELOC_EPIPHANY_SIMM24",
+ "BFD_RELOC_EPIPHANY_HIGH",
+ "BFD_RELOC_EPIPHANY_LOW",
+ "BFD_RELOC_EPIPHANY_SIMM11",
+ "BFD_RELOC_EPIPHANY_IMM11",
+ "BFD_RELOC_EPIPHANY_IMM8",
+ "@@overflow: BFD_RELOC_UNUSED@@",
+};
+#endif
+
+reloc_howto_type *bfd_default_reloc_type_lookup
+ (bfd *abfd, bfd_reloc_code_real_type code);
+
+bfd_boolean bfd_generic_relax_section
+ (bfd *abfd,
+ asection *section,
+ struct bfd_link_info *,
+ bfd_boolean *);
+
+bfd_boolean bfd_generic_gc_sections
+ (bfd *, struct bfd_link_info *);
+
+bfd_boolean bfd_generic_lookup_section_flags
+ (struct bfd_link_info *, struct flag_info *, asection *);
+
+bfd_boolean bfd_generic_merge_sections
+ (bfd *, struct bfd_link_info *);
+
+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,
+ bfd_boolean relocatable,
+ asymbol **symbols);
+
+/* Extracted from archures.c. */
+extern const bfd_arch_info_type bfd_default_arch_struct;
+bfd_boolean bfd_default_set_arch_mach
+ (bfd *abfd, enum bfd_architecture arch, unsigned long mach);
+
+const bfd_arch_info_type *bfd_default_compatible
+ (const bfd_arch_info_type *a, const bfd_arch_info_type *b);
+
+bfd_boolean bfd_default_scan
+ (const struct bfd_arch_info *info, const char *string);
+
+void *bfd_arch_default_fill (bfd_size_type count,
+ bfd_boolean is_bigendian,
+ bfd_boolean code);
+
+/* Extracted from elf.c. */
diff --git a/bfd/libcoff-in.h b/bfd/libcoff-in.h
new file mode 100644
index 0000000..6b6eb28
--- /dev/null
+++ b/bfd/libcoff-in.h
@@ -0,0 +1,623 @@
+/* BFD COFF object file private structure.
+ Copyright (C) 1990-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "bfdlink.h"
+
+/* Object file tdata; access macros. */
+
+#define coff_data(bfd) ((bfd)->tdata.coff_obj_data)
+#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_strings_len(bfd) (coff_data (bfd)->strings_len)
+#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_strings_written(bfd) (coff_data (bfd)->strings_written)
+#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 long raw_syment_count;
+
+ /* These are only valid once writing has begun. */
+ unsigned 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. */
+ void * external_syms;
+ /* If this is TRUE, the external_syms may not be freed. */
+ bfd_boolean keep_syms;
+
+ /* The string table. May be NULL. Read by
+ _bfd_coff_read_string_table. */
+ char *strings;
+ /* The length of the strings table. For error checking. */
+ bfd_size_type strings_len;
+ /* If this is TRUE, the strings may not be freed. */
+ bfd_boolean keep_strings;
+ /* If this is TRUE, the strings have been written out already. */
+ bfd_boolean strings_written;
+
+ /* 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. */
+ void * line_info;
+
+ /* A place to stash dwarf2 info for this bfd. */
+ void * dwarf2_find_line_info;
+
+ /* The timestamp from the COFF file header. */
+ long timestamp;
+
+ /* Copy of some of the f_flags bits in the COFF filehdr structure,
+ used by ARM code. */
+ flagword flags;
+
+ /* coff-stgo32 EXE stub header after BFD tdata has been allocated. Its data
+ is kept in internal_filehdr.go32stub beforehand. */
+ char *go32stub;
+} 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;
+ int dont_strip_reloc;
+ bfd_boolean insert_timestamp;
+ bfd_boolean (*in_reloc_p) (bfd *, reloc_howto_type *);
+ flagword real_flags;
+
+ /* Build-id info. */
+ struct
+ {
+ bfd_boolean (*after_write_object_contents) (bfd *);
+ const char *style;
+ asection *sec;
+ } build_id;
+} 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 this is an XCOFF64 file. */
+ bfd_boolean xcoff64;
+
+ /* TRUE if a large a.out header should be generated. */
+ bfd_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_vma maxdata;
+
+ /* maxstack from optional header. */
+ bfd_vma maxstack;
+
+ /* Used by the XCOFF backend linker. */
+ asection **csects;
+ long *debug_indices;
+ unsigned int *lineno_counts;
+ unsigned int import_file_id;
+};
+
+#define xcoff_data(abfd) ((abfd)->tdata.xcoff_obj_data)
+
+/* We take the address of the first element of an 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. */
+ bfd_boolean keep_relocs;
+ /* The section contents. This may be NULL. */
+ bfd_byte *contents;
+ /* If this is TRUE, the contents entry may not be freed. */
+ bfd_boolean keep_contents;
+ /* Information cached by coff_find_nearest_line. */
+ bfd_vma offset;
+ unsigned int i;
+ const char *function;
+ /* Optional information about a COMDAT entry; NULL if not COMDAT. */
+ struct coff_comdat_info *comdat;
+ int line_base;
+ /* A pointer used for .stab linking optimizations. */
+ void * stab_info;
+ /* Available for individual backends. */
+ void * 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 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 PE files. */
+
+struct pei_section_tdata
+{
+ /* The virtual size of the section. */
+ bfd_size_type virt_size;
+ /* The PE section flags. */
+ long pe_flags;
+};
+
+/* 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 symbol_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;
+
+ /* Flag word; legal values follow. */
+ unsigned short coff_link_hash_flags;
+ /* Symbol is a PE section symbol. */
+#define COFF_LINK_HASH_PE_SECTION_SYMBOL (01)
+};
+
+/* 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. */
+ struct stab_info 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, \
+ (bfd_boolean (*) (struct bfd_link_hash_entry *, void *)) (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
+ (bfd *);
+extern struct bfd_section *coff_section_from_bfd_index
+ (bfd *, int);
+extern long coff_get_symtab_upper_bound
+ (bfd *);
+extern long coff_canonicalize_symtab
+ (bfd *, asymbol **);
+extern int coff_count_linenumbers
+ (bfd *);
+extern struct coff_symbol_struct *coff_symbol_from
+ (bfd *, asymbol *);
+extern bfd_boolean coff_renumber_symbols
+ (bfd *, int *);
+extern void coff_mangle_symbols
+ (bfd *);
+extern bfd_boolean coff_write_symbols
+ (bfd *);
+extern bfd_boolean coff_write_alien_symbol
+ (bfd *, asymbol *, struct internal_syment *, bfd_vma *,
+ bfd_size_type *, asection **, bfd_size_type *);
+extern bfd_boolean coff_write_linenumbers
+ (bfd *);
+extern alent *coff_get_lineno
+ (bfd *, asymbol *);
+extern asymbol *coff_section_symbol
+ (bfd *, char *);
+extern bfd_boolean _bfd_coff_get_external_symbols
+ (bfd *);
+extern const char *_bfd_coff_read_string_table
+ (bfd *);
+extern bfd_boolean _bfd_coff_free_symbols
+ (bfd *);
+extern struct coff_ptr_struct *coff_get_normalized_symtab
+ (bfd *);
+extern long coff_get_reloc_upper_bound
+ (bfd *, sec_ptr);
+extern asymbol *coff_make_empty_symbol
+ (bfd *);
+extern void coff_print_symbol
+ (bfd *, void * filep, asymbol *, bfd_print_symbol_type);
+extern void coff_get_symbol_info
+ (bfd *, asymbol *, symbol_info *ret);
+extern bfd_boolean _bfd_coff_is_local_label_name
+ (bfd *, const char *);
+extern asymbol *coff_bfd_make_debug_symbol
+ (bfd *, void *, unsigned long);
+extern bfd_boolean coff_find_nearest_line
+ (bfd *, asymbol **, asection *, bfd_vma,
+ const char **, const char **, unsigned int *, unsigned int *);
+#define coff_find_line _bfd_nosymbols_find_line
+struct dwarf_debug_section;
+extern bfd_boolean coff_find_nearest_line_with_names
+ (bfd *, asymbol **, asection *, bfd_vma, const char **, const char **,
+ unsigned int *, const struct dwarf_debug_section *);
+extern bfd_boolean coff_find_inliner_info
+ (bfd *, const char **, const char **, unsigned int *);
+extern int coff_sizeof_headers
+ (bfd *, struct bfd_link_info *);
+extern bfd_boolean bfd_coff_reloc16_relax_section
+ (bfd *, asection *, struct bfd_link_info *, bfd_boolean *);
+extern bfd_byte *bfd_coff_reloc16_get_relocated_section_contents
+ (bfd *, struct bfd_link_info *, struct bfd_link_order *,
+ bfd_byte *, bfd_boolean, asymbol **);
+extern bfd_vma bfd_coff_reloc16_get_value
+ (arelent *, struct bfd_link_info *, asection *);
+extern void bfd_perform_slip
+ (bfd *, unsigned int, asection *, bfd_vma);
+
+/* 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 type_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, \
+ sizeof (struct coff_debug_merge_hash_entry)))
+
+/* 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 relocatable 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. */
+ bfd_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. */
+ bfd_boolean global_to_static;
+ /* Hash table for long symbol names. */
+ struct bfd_strtab_hash *strtab;
+ /* When doing a relocatable 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;
+};
+
+/* Most COFF variants have no way to record the alignment of a
+ section. This struct is used to set a specific alignment based on
+ the name of the section. */
+
+struct coff_section_alignment_entry
+{
+ /* The section name. */
+ const char *name;
+
+ /* This is either (unsigned int) -1, indicating that the section
+ name must match exactly, or it is the number of letters which
+ must match at the start of the name. */
+ unsigned int comparison_length;
+
+ /* These macros may be used to fill in the first two fields in a
+ structure initialization. */
+#define COFF_SECTION_NAME_EXACT_MATCH(name) (name), ((unsigned int) -1)
+#define COFF_SECTION_NAME_PARTIAL_MATCH(name) (name), (sizeof (name) - 1)
+
+ /* Only use this entry if the default section alignment for this
+ target is at least that much (as a power of two). If this field
+ is COFF_ALIGNMENT_FIELD_EMPTY, it should be ignored. */
+ unsigned int default_alignment_min;
+
+ /* Only use this entry if the default section alignment for this
+ target is no greater than this (as a power of two). If this
+ field is COFF_ALIGNMENT_FIELD_EMPTY, it should be ignored. */
+ unsigned int default_alignment_max;
+
+#define COFF_ALIGNMENT_FIELD_EMPTY ((unsigned int) -1)
+
+ /* The desired alignment for this section (as a power of two). */
+ unsigned int alignment_power;
+};
+
+extern struct bfd_hash_entry *_bfd_coff_link_hash_newfunc
+ (struct bfd_hash_entry *, struct bfd_hash_table *, const char *);
+extern bfd_boolean _bfd_coff_link_hash_table_init
+ (struct coff_link_hash_table *, bfd *,
+ struct bfd_hash_entry *(*) (struct bfd_hash_entry *,
+ struct bfd_hash_table *,
+ const char *),
+ unsigned int);
+extern struct bfd_link_hash_table *_bfd_coff_link_hash_table_create
+ (bfd *);
+extern const char *_bfd_coff_internal_syment_name
+ (bfd *, const struct internal_syment *, char *);
+extern bfd_boolean _bfd_coff_section_already_linked
+ (bfd *, asection *, struct bfd_link_info *);
+extern bfd_boolean _bfd_coff_link_add_symbols
+ (bfd *, struct bfd_link_info *);
+extern bfd_boolean _bfd_coff_final_link
+ (bfd *, struct bfd_link_info *);
+extern struct internal_reloc *_bfd_coff_read_internal_relocs
+ (bfd *, asection *, bfd_boolean, bfd_byte *, bfd_boolean,
+ struct internal_reloc *);
+extern bfd_boolean _bfd_coff_generic_relocate_section
+ (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
+ (struct bfd_hash_entry *, struct bfd_hash_table *, const char *);
+extern bfd_boolean _bfd_coff_write_global_sym
+ (struct bfd_hash_entry *, void *);
+extern bfd_boolean _bfd_coff_write_task_globals
+ (struct coff_link_hash_entry *, void *);
+extern bfd_boolean _bfd_coff_link_input_bfd
+ (struct coff_final_link_info *, bfd *);
+extern bfd_boolean _bfd_coff_reloc_link_order
+ (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
+ (bfd *);
+extern long _bfd_xcoff_canonicalize_dynamic_symtab
+ (bfd *, asymbol **);
+extern long _bfd_xcoff_get_dynamic_reloc_upper_bound
+ (bfd *);
+extern long _bfd_xcoff_canonicalize_dynamic_reloc
+ (bfd *, arelent **, asymbol **);
+extern struct bfd_link_hash_table *_bfd_xcoff_bfd_link_hash_table_create
+ (bfd *);
+extern bfd_boolean _bfd_xcoff_bfd_link_add_symbols
+ (bfd *, struct bfd_link_info *);
+extern bfd_boolean _bfd_xcoff_bfd_final_link
+ (bfd *, struct bfd_link_info *);
+extern bfd_boolean _bfd_xcoff_define_common_symbol
+ (bfd *, struct bfd_link_info *, struct bfd_link_hash_entry *);
+extern bfd_boolean _bfd_ppc_xcoff_relocate_section
+ (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 by pe.em in the
+ linker, and so should start with bfd and be declared in bfd.h. */
+
+extern bfd_boolean ppc_allocate_toc_section
+ (struct bfd_link_info *);
+extern bfd_boolean ppc_process_before_allocation
+ (bfd *, struct bfd_link_info *);
diff --git a/bfd/libcoff.h b/bfd/libcoff.h
new file mode 100644
index 0000000..9479985
--- /dev/null
+++ b/bfd/libcoff.h
@@ -0,0 +1,982 @@
+/* DO NOT EDIT! -*- buffer-read-only: t -*- This file is automatically
+ generated from "libcoff-in.h" and "coffcode.h".
+ Run "make headers" in your build bfd/ to regenerate. */
+
+/* BFD COFF object file private structure.
+ Copyright (C) 1990-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "bfdlink.h"
+
+/* Object file tdata; access macros. */
+
+#define coff_data(bfd) ((bfd)->tdata.coff_obj_data)
+#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_strings_len(bfd) (coff_data (bfd)->strings_len)
+#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_strings_written(bfd) (coff_data (bfd)->strings_written)
+#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 long raw_syment_count;
+
+ /* These are only valid once writing has begun. */
+ unsigned 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. */
+ void * external_syms;
+ /* If this is TRUE, the external_syms may not be freed. */
+ bfd_boolean keep_syms;
+
+ /* The string table. May be NULL. Read by
+ _bfd_coff_read_string_table. */
+ char *strings;
+ /* The length of the strings table. For error checking. */
+ bfd_size_type strings_len;
+ /* If this is TRUE, the strings may not be freed. */
+ bfd_boolean keep_strings;
+ /* If this is TRUE, the strings have been written out already. */
+ bfd_boolean strings_written;
+
+ /* 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. */
+ void * line_info;
+
+ /* A place to stash dwarf2 info for this bfd. */
+ void * dwarf2_find_line_info;
+
+ /* The timestamp from the COFF file header. */
+ long timestamp;
+
+ /* Copy of some of the f_flags bits in the COFF filehdr structure,
+ used by ARM code. */
+ flagword flags;
+
+ /* coff-stgo32 EXE stub header after BFD tdata has been allocated. Its data
+ is kept in internal_filehdr.go32stub beforehand. */
+ char *go32stub;
+} 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;
+ int dont_strip_reloc;
+ bfd_boolean insert_timestamp;
+ bfd_boolean (*in_reloc_p) (bfd *, reloc_howto_type *);
+ flagword real_flags;
+
+ /* Build-id info. */
+ struct
+ {
+ bfd_boolean (*after_write_object_contents) (bfd *);
+ const char *style;
+ asection *sec;
+ } build_id;
+} 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 this is an XCOFF64 file. */
+ bfd_boolean xcoff64;
+
+ /* TRUE if a large a.out header should be generated. */
+ bfd_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_vma maxdata;
+
+ /* maxstack from optional header. */
+ bfd_vma maxstack;
+
+ /* Used by the XCOFF backend linker. */
+ asection **csects;
+ long *debug_indices;
+ unsigned int *lineno_counts;
+ unsigned int import_file_id;
+};
+
+#define xcoff_data(abfd) ((abfd)->tdata.xcoff_obj_data)
+
+/* We take the address of the first element of an 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. */
+ bfd_boolean keep_relocs;
+ /* The section contents. This may be NULL. */
+ bfd_byte *contents;
+ /* If this is TRUE, the contents entry may not be freed. */
+ bfd_boolean keep_contents;
+ /* Information cached by coff_find_nearest_line. */
+ bfd_vma offset;
+ unsigned int i;
+ const char *function;
+ /* Optional information about a COMDAT entry; NULL if not COMDAT. */
+ struct coff_comdat_info *comdat;
+ int line_base;
+ /* A pointer used for .stab linking optimizations. */
+ void * stab_info;
+ /* Available for individual backends. */
+ void * 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 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 PE files. */
+
+struct pei_section_tdata
+{
+ /* The virtual size of the section. */
+ bfd_size_type virt_size;
+ /* The PE section flags. */
+ long pe_flags;
+};
+
+/* 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 symbol_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;
+
+ /* Flag word; legal values follow. */
+ unsigned short coff_link_hash_flags;
+ /* Symbol is a PE section symbol. */
+#define COFF_LINK_HASH_PE_SECTION_SYMBOL (01)
+};
+
+/* 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. */
+ struct stab_info 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, \
+ (bfd_boolean (*) (struct bfd_link_hash_entry *, void *)) (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
+ (bfd *);
+extern struct bfd_section *coff_section_from_bfd_index
+ (bfd *, int);
+extern long coff_get_symtab_upper_bound
+ (bfd *);
+extern long coff_canonicalize_symtab
+ (bfd *, asymbol **);
+extern int coff_count_linenumbers
+ (bfd *);
+extern struct coff_symbol_struct *coff_symbol_from
+ (bfd *, asymbol *);
+extern bfd_boolean coff_renumber_symbols
+ (bfd *, int *);
+extern void coff_mangle_symbols
+ (bfd *);
+extern bfd_boolean coff_write_symbols
+ (bfd *);
+extern bfd_boolean coff_write_alien_symbol
+ (bfd *, asymbol *, struct internal_syment *, bfd_vma *,
+ bfd_size_type *, asection **, bfd_size_type *);
+extern bfd_boolean coff_write_linenumbers
+ (bfd *);
+extern alent *coff_get_lineno
+ (bfd *, asymbol *);
+extern asymbol *coff_section_symbol
+ (bfd *, char *);
+extern bfd_boolean _bfd_coff_get_external_symbols
+ (bfd *);
+extern const char *_bfd_coff_read_string_table
+ (bfd *);
+extern bfd_boolean _bfd_coff_free_symbols
+ (bfd *);
+extern struct coff_ptr_struct *coff_get_normalized_symtab
+ (bfd *);
+extern long coff_get_reloc_upper_bound
+ (bfd *, sec_ptr);
+extern asymbol *coff_make_empty_symbol
+ (bfd *);
+extern void coff_print_symbol
+ (bfd *, void * filep, asymbol *, bfd_print_symbol_type);
+extern void coff_get_symbol_info
+ (bfd *, asymbol *, symbol_info *ret);
+extern bfd_boolean _bfd_coff_is_local_label_name
+ (bfd *, const char *);
+extern asymbol *coff_bfd_make_debug_symbol
+ (bfd *, void *, unsigned long);
+extern bfd_boolean coff_find_nearest_line
+ (bfd *, asymbol **, asection *, bfd_vma,
+ const char **, const char **, unsigned int *, unsigned int *);
+#define coff_find_line _bfd_nosymbols_find_line
+struct dwarf_debug_section;
+extern bfd_boolean coff_find_nearest_line_with_names
+ (bfd *, asymbol **, asection *, bfd_vma, const char **, const char **,
+ unsigned int *, const struct dwarf_debug_section *);
+extern bfd_boolean coff_find_inliner_info
+ (bfd *, const char **, const char **, unsigned int *);
+extern int coff_sizeof_headers
+ (bfd *, struct bfd_link_info *);
+extern bfd_boolean bfd_coff_reloc16_relax_section
+ (bfd *, asection *, struct bfd_link_info *, bfd_boolean *);
+extern bfd_byte *bfd_coff_reloc16_get_relocated_section_contents
+ (bfd *, struct bfd_link_info *, struct bfd_link_order *,
+ bfd_byte *, bfd_boolean, asymbol **);
+extern bfd_vma bfd_coff_reloc16_get_value
+ (arelent *, struct bfd_link_info *, asection *);
+extern void bfd_perform_slip
+ (bfd *, unsigned int, asection *, bfd_vma);
+
+/* 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 type_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, \
+ sizeof (struct coff_debug_merge_hash_entry)))
+
+/* 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 relocatable 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. */
+ bfd_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. */
+ bfd_boolean global_to_static;
+ /* Hash table for long symbol names. */
+ struct bfd_strtab_hash *strtab;
+ /* When doing a relocatable 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;
+};
+
+/* Most COFF variants have no way to record the alignment of a
+ section. This struct is used to set a specific alignment based on
+ the name of the section. */
+
+struct coff_section_alignment_entry
+{
+ /* The section name. */
+ const char *name;
+
+ /* This is either (unsigned int) -1, indicating that the section
+ name must match exactly, or it is the number of letters which
+ must match at the start of the name. */
+ unsigned int comparison_length;
+
+ /* These macros may be used to fill in the first two fields in a
+ structure initialization. */
+#define COFF_SECTION_NAME_EXACT_MATCH(name) (name), ((unsigned int) -1)
+#define COFF_SECTION_NAME_PARTIAL_MATCH(name) (name), (sizeof (name) - 1)
+
+ /* Only use this entry if the default section alignment for this
+ target is at least that much (as a power of two). If this field
+ is COFF_ALIGNMENT_FIELD_EMPTY, it should be ignored. */
+ unsigned int default_alignment_min;
+
+ /* Only use this entry if the default section alignment for this
+ target is no greater than this (as a power of two). If this
+ field is COFF_ALIGNMENT_FIELD_EMPTY, it should be ignored. */
+ unsigned int default_alignment_max;
+
+#define COFF_ALIGNMENT_FIELD_EMPTY ((unsigned int) -1)
+
+ /* The desired alignment for this section (as a power of two). */
+ unsigned int alignment_power;
+};
+
+extern struct bfd_hash_entry *_bfd_coff_link_hash_newfunc
+ (struct bfd_hash_entry *, struct bfd_hash_table *, const char *);
+extern bfd_boolean _bfd_coff_link_hash_table_init
+ (struct coff_link_hash_table *, bfd *,
+ struct bfd_hash_entry *(*) (struct bfd_hash_entry *,
+ struct bfd_hash_table *,
+ const char *),
+ unsigned int);
+extern struct bfd_link_hash_table *_bfd_coff_link_hash_table_create
+ (bfd *);
+extern const char *_bfd_coff_internal_syment_name
+ (bfd *, const struct internal_syment *, char *);
+extern bfd_boolean _bfd_coff_section_already_linked
+ (bfd *, asection *, struct bfd_link_info *);
+extern bfd_boolean _bfd_coff_link_add_symbols
+ (bfd *, struct bfd_link_info *);
+extern bfd_boolean _bfd_coff_final_link
+ (bfd *, struct bfd_link_info *);
+extern struct internal_reloc *_bfd_coff_read_internal_relocs
+ (bfd *, asection *, bfd_boolean, bfd_byte *, bfd_boolean,
+ struct internal_reloc *);
+extern bfd_boolean _bfd_coff_generic_relocate_section
+ (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
+ (struct bfd_hash_entry *, struct bfd_hash_table *, const char *);
+extern bfd_boolean _bfd_coff_write_global_sym
+ (struct bfd_hash_entry *, void *);
+extern bfd_boolean _bfd_coff_write_task_globals
+ (struct coff_link_hash_entry *, void *);
+extern bfd_boolean _bfd_coff_link_input_bfd
+ (struct coff_final_link_info *, bfd *);
+extern bfd_boolean _bfd_coff_reloc_link_order
+ (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
+ (bfd *);
+extern long _bfd_xcoff_canonicalize_dynamic_symtab
+ (bfd *, asymbol **);
+extern long _bfd_xcoff_get_dynamic_reloc_upper_bound
+ (bfd *);
+extern long _bfd_xcoff_canonicalize_dynamic_reloc
+ (bfd *, arelent **, asymbol **);
+extern struct bfd_link_hash_table *_bfd_xcoff_bfd_link_hash_table_create
+ (bfd *);
+extern bfd_boolean _bfd_xcoff_bfd_link_add_symbols
+ (bfd *, struct bfd_link_info *);
+extern bfd_boolean _bfd_xcoff_bfd_final_link
+ (bfd *, struct bfd_link_info *);
+extern bfd_boolean _bfd_xcoff_define_common_symbol
+ (bfd *, struct bfd_link_info *, struct bfd_link_hash_entry *);
+extern bfd_boolean _bfd_ppc_xcoff_relocate_section
+ (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 by pe.em in the
+ linker, and so should start with bfd and be declared in bfd.h. */
+
+extern bfd_boolean ppc_allocate_toc_section
+ (struct bfd_link_info *);
+extern bfd_boolean ppc_process_before_allocation
+ (bfd *, struct bfd_link_info *);
+/* Extracted from coffcode.h. */
+
+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;
+
+ /* Selector for the union above. */
+ bfd_boolean is_sym;
+} 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 ? */
+ bfd_boolean done_lineno;
+} coff_symbol_type;
+/* COFF symbol classifications. */
+
+enum coff_symbol_classification
+{
+ /* Global symbol. */
+ COFF_SYMBOL_GLOBAL,
+ /* Common symbol. */
+ COFF_SYMBOL_COMMON,
+ /* Undefined symbol. */
+ COFF_SYMBOL_UNDEFINED,
+ /* Local symbol. */
+ COFF_SYMBOL_LOCAL,
+ /* PE section symbol. */
+ COFF_SYMBOL_PE_SECTION
+};
+
+typedef struct
+{
+ void (*_bfd_coff_swap_aux_in)
+ (bfd *, void *, int, int, int, int, void *);
+
+ void (*_bfd_coff_swap_sym_in)
+ (bfd *, void *, void *);
+
+ void (*_bfd_coff_swap_lineno_in)
+ (bfd *, void *, void *);
+
+ unsigned int (*_bfd_coff_swap_aux_out)
+ (bfd *, void *, int, int, int, int, void *);
+
+ unsigned int (*_bfd_coff_swap_sym_out)
+ (bfd *, void *, void *);
+
+ unsigned int (*_bfd_coff_swap_lineno_out)
+ (bfd *, void *, void *);
+
+ unsigned int (*_bfd_coff_swap_reloc_out)
+ (bfd *, void *, void *);
+
+ unsigned int (*_bfd_coff_swap_filehdr_out)
+ (bfd *, void *, void *);
+
+ unsigned int (*_bfd_coff_swap_aouthdr_out)
+ (bfd *, void *, void *);
+
+ unsigned int (*_bfd_coff_swap_scnhdr_out)
+ (bfd *, void *, void *);
+
+ 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;
+ unsigned int _bfd_filnmlen;
+ bfd_boolean _bfd_coff_long_filenames;
+
+ bfd_boolean _bfd_coff_long_section_names;
+ bfd_boolean (*_bfd_coff_set_long_section_names)
+ (bfd *, int);
+
+ unsigned int _bfd_coff_default_section_alignment_power;
+ bfd_boolean _bfd_coff_force_symnames_in_strings;
+ unsigned int _bfd_coff_debug_string_prefix_length;
+ unsigned int _bfd_coff_max_nscns;
+
+ void (*_bfd_coff_swap_filehdr_in)
+ (bfd *, void *, void *);
+
+ void (*_bfd_coff_swap_aouthdr_in)
+ (bfd *, void *, void *);
+
+ void (*_bfd_coff_swap_scnhdr_in)
+ (bfd *, void *, void *);
+
+ void (*_bfd_coff_swap_reloc_in)
+ (bfd *abfd, void *, void *);
+
+ bfd_boolean (*_bfd_coff_bad_format_hook)
+ (bfd *, void *);
+
+ bfd_boolean (*_bfd_coff_set_arch_mach_hook)
+ (bfd *, void *);
+
+ void * (*_bfd_coff_mkobject_hook)
+ (bfd *, void *, void *);
+
+ bfd_boolean (*_bfd_styp_to_sec_flags_hook)
+ (bfd *, void *, const char *, asection *, flagword *);
+
+ void (*_bfd_set_alignment_hook)
+ (bfd *, asection *, void *);
+
+ bfd_boolean (*_bfd_coff_slurp_symbol_table)
+ (bfd *);
+
+ bfd_boolean (*_bfd_coff_symname_in_debug)
+ (bfd *, struct internal_syment *);
+
+ bfd_boolean (*_bfd_coff_pointerize_aux_hook)
+ (bfd *, combined_entry_type *, combined_entry_type *,
+ unsigned int, combined_entry_type *);
+
+ bfd_boolean (*_bfd_coff_print_aux)
+ (bfd *, FILE *, combined_entry_type *, combined_entry_type *,
+ combined_entry_type *, unsigned int);
+
+ void (*_bfd_coff_reloc16_extra_cases)
+ (bfd *, struct bfd_link_info *, struct bfd_link_order *, arelent *,
+ bfd_byte *, unsigned int *, unsigned int *);
+
+ int (*_bfd_coff_reloc16_estimate)
+ (bfd *, asection *, arelent *, unsigned int,
+ struct bfd_link_info *);
+
+ enum coff_symbol_classification (*_bfd_coff_classify_symbol)
+ (bfd *, struct internal_syment *);
+
+ bfd_boolean (*_bfd_coff_compute_section_file_positions)
+ (bfd *);
+
+ bfd_boolean (*_bfd_coff_start_final_link)
+ (bfd *, struct bfd_link_info *);
+
+ bfd_boolean (*_bfd_coff_relocate_section)
+ (bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
+ struct internal_reloc *, struct internal_syment *, asection **);
+
+ reloc_howto_type *(*_bfd_coff_rtype_to_howto)
+ (bfd *, asection *, struct internal_reloc *,
+ struct coff_link_hash_entry *, struct internal_syment *,
+ bfd_vma *);
+
+ bfd_boolean (*_bfd_coff_adjust_symndx)
+ (bfd *, struct bfd_link_info *, bfd *, asection *,
+ struct internal_reloc *, bfd_boolean *);
+
+ bfd_boolean (*_bfd_coff_link_add_one_symbol)
+ (struct bfd_link_info *, bfd *, const char *, flagword,
+ asection *, bfd_vma, const char *, bfd_boolean, bfd_boolean,
+ struct bfd_link_hash_entry **);
+
+ bfd_boolean (*_bfd_coff_link_output_has_begun)
+ (bfd *, struct coff_final_link_info *);
+
+ bfd_boolean (*_bfd_coff_final_link_postscript)
+ (bfd *, struct coff_final_link_info *);
+
+ bfd_boolean (*_bfd_coff_print_pdata)
+ (bfd *, void *);
+
+} 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_filnmlen(abfd) (coff_backend_info (abfd)->_bfd_filnmlen)
+#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_set_long_section_names(abfd, enable) \
+ ((coff_backend_info (abfd)->_bfd_coff_set_long_section_names) (abfd, enable))
+#define bfd_coff_default_section_alignment_power(abfd) \
+ (coff_backend_info (abfd)->_bfd_coff_default_section_alignment_power)
+#define bfd_coff_max_nscns(abfd) \
+ (coff_backend_info (abfd)->_bfd_coff_max_nscns)
+
+#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, section, flags_ptr)\
+ ((coff_backend_info (abfd)->_bfd_styp_to_sec_flags_hook)\
+ (abfd, scnhdr, name, section, flags_ptr))
+
+#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_force_symnames_in_strings(abfd)\
+ (coff_backend_info (abfd)->_bfd_coff_force_symnames_in_strings)
+
+#define bfd_coff_debug_string_prefix_length(abfd)\
+ (coff_backend_info (abfd)->_bfd_coff_debug_string_prefix_length)
+
+#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_classify_symbol(abfd, sym)\
+ ((coff_backend_info (abfd)->_bfd_coff_classify_symbol)\
+ (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))
+
+#define bfd_coff_have_print_pdata(a) \
+ (coff_backend_info (a)->_bfd_coff_print_pdata)
+#define bfd_coff_print_pdata(a,p) \
+ ((coff_backend_info (a)->_bfd_coff_print_pdata) (a, p))
+
+/* Macro: Returns true if the bfd is a PE executable as opposed to a
+ PE object file. */
+#define bfd_pei_p(abfd) \
+ (CONST_STRNEQ ((abfd)->xvec->name, "pei-"))
diff --git a/bfd/libecoff.h b/bfd/libecoff.h
new file mode 100644
index 0000000..06434c2
--- /dev/null
+++ b/bfd/libecoff.h
@@ -0,0 +1,346 @@
+/* BFD ECOFF object file private structure.
+ Copyright (C) 1993-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, 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. */
+ bfd_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) (bfd *, void *, struct internal_reloc *);
+ void (*swap_reloc_out) (bfd *, const struct internal_reloc *, void *);
+ /* Backend reloc tweaking. */
+ void (*adjust_reloc_in)
+ (bfd *, const struct internal_reloc *, arelent *);
+ void (*adjust_reloc_out)
+ (bfd *, const arelent *, struct internal_reloc *);
+ /* Relocate section contents while linking. */
+ bfd_boolean (*relocate_section)
+ (bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *, void *);
+ /* Do final adjustments to filehdr and aouthdr. */
+ bfd_boolean (*adjust_headers)
+ (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) (bfd *, file_ptr);
+};
+
+/* ECOFF targets don't support COFF long section names, so this
+ macro is provided to use as an initialiser for the related
+ members of the embedded bfd_coff_backend_data struct. */
+#define ECOFF_NO_LONG_SECTION_NAMES (FALSE), _bfd_ecoff_no_long_sections
+
+/* 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. */
+ void * 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. */
+ bfd_boolean linker;
+
+ /* TRUE if a warning that multiple global pointer values are
+ needed in the output binary was issued already. */
+ bfd_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. */
+ bfd_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. */
+ bfd_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. */
+ void * native;
+} ecoff_symbol_type;
+
+/* We take the address of the first element of an 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))
+
+/* A pointer to this structure is put in the used_by_bfd pointer of
+ a section to keep track of any per-section data.
+ The user_by_bfd pointer will be NULL if the information was not
+ needed. */
+
+struct ecoff_section_tdata
+{
+ /* 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 bfd_boolean _bfd_ecoff_mkobject (bfd *);
+
+/* Read in the ECOFF symbolic debugging information. */
+extern bfd_boolean _bfd_ecoff_slurp_symbolic_info
+ (bfd *, asection *, struct ecoff_debug_info *);
+
+/* Generic ECOFF BFD backend vectors. */
+
+extern bfd_boolean _bfd_ecoff_write_object_contents (bfd *);
+
+#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 bfd_boolean _bfd_ecoff_new_section_hook
+ (bfd *, asection *);
+extern bfd_boolean _bfd_ecoff_get_section_contents
+ (bfd *, asection *, void * location, file_ptr, bfd_size_type);
+
+#define _bfd_ecoff_bfd_link_split_section _bfd_generic_link_split_section
+
+extern bfd_boolean _bfd_ecoff_bfd_copy_private_bfd_data
+ (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_copy_private_header_data \
+ _bfd_generic_bfd_copy_private_header_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 bfd_boolean _bfd_ecoff_slurp_armap (bfd *);
+#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 bfd_boolean _bfd_ecoff_write_armap
+ (bfd *, unsigned int, struct orl *, unsigned int, int);
+#define _bfd_ecoff_read_ar_hdr _bfd_generic_read_ar_hdr
+#define _bfd_ecoff_write_ar_hdr _bfd_generic_write_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
+#define _bfd_ecoff_bfd_is_target_special_symbol \
+ ((bfd_boolean (*) (bfd *, asymbol *)) bfd_false)
+
+extern long _bfd_ecoff_get_symtab_upper_bound (bfd *);
+extern long _bfd_ecoff_canonicalize_symtab (bfd *, asymbol **);
+extern asymbol *_bfd_ecoff_make_empty_symbol (bfd *);
+extern void _bfd_ecoff_print_symbol
+ (bfd *, void *, asymbol *, bfd_print_symbol_type);
+extern void _bfd_ecoff_get_symbol_info
+ (bfd *, asymbol *, symbol_info *);
+extern bfd_boolean _bfd_ecoff_bfd_is_local_label_name
+ (bfd *, const char *);
+#define _bfd_ecoff_get_lineno _bfd_nosymbols_get_lineno
+extern bfd_boolean _bfd_ecoff_find_nearest_line
+ (bfd *, asymbol **, asection *, bfd_vma,
+ const char **, const char **, unsigned int *, unsigned int *);
+#define _bfd_ecoff_find_line _bfd_nosymbols_find_line
+#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_find_inliner_info _bfd_nosymbols_find_inliner_info
+
+#define _bfd_ecoff_get_reloc_upper_bound coff_get_reloc_upper_bound
+extern long _bfd_ecoff_canonicalize_reloc
+ (bfd *, asection *, arelent **, asymbol **symbols);
+/* ecoff_bfd_reloc_type_lookup defined by backend. */
+
+extern bfd_boolean _bfd_ecoff_set_arch_mach
+ (bfd *, enum bfd_architecture, unsigned long);
+extern bfd_boolean _bfd_ecoff_set_section_contents
+ (bfd *, asection *, const void * location, file_ptr, bfd_size_type);
+
+extern int _bfd_ecoff_sizeof_headers (bfd *, struct bfd_link_info *);
+/* 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
+ (bfd *);
+extern bfd_boolean _bfd_ecoff_bfd_link_add_symbols
+ (bfd *, struct bfd_link_info *);
+#define _bfd_ecoff_bfd_link_just_syms _bfd_generic_link_just_syms
+#define _bfd_ecoff_bfd_copy_link_hash_symbol_type \
+ _bfd_generic_copy_link_hash_symbol_type
+extern bfd_boolean _bfd_ecoff_bfd_final_link
+ (bfd *, struct bfd_link_info *);
+
+/* Hook functions for the generic COFF section reading code. */
+
+extern void * _bfd_ecoff_mkobject_hook (bfd *, void *, void *);
+#define _bfd_ecoff_set_alignment_hook \
+ ((void (*) (bfd *, asection *, void *)) bfd_void)
+extern bfd_boolean _bfd_ecoff_set_arch_mach_hook
+ (bfd *, void *);
+extern bfd_boolean _bfd_ecoff_no_long_sections
+ (bfd *abfd, int enable);
+extern bfd_boolean _bfd_ecoff_styp_to_sec_flags
+ (bfd *, void *, const char *, asection *, flagword *);
+extern bfd_boolean _bfd_ecoff_slurp_symbol_table (bfd *);
+
+/* 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
+ (int, const struct tir_ext *, TIR *);
+extern void _bfd_ecoff_swap_tir_out
+ (int, const TIR *, struct tir_ext *);
+extern void _bfd_ecoff_swap_rndx_in
+ (int, const struct rndx_ext *, RNDXR *);
+extern void _bfd_ecoff_swap_rndx_out
+ (int, const RNDXR *, struct rndx_ext *);
diff --git a/bfd/libhppa.h b/bfd/libhppa.h
new file mode 100644
index 0000000..deb89d1
--- /dev/null
+++ b/bfd/libhppa.h
@@ -0,0 +1,594 @@
+/* HP PA-RISC SOM object file format: definitions internal to BFD.
+ Copyright (C) 1990-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#ifndef _LIBHPPA_H
+#define _LIBHPPA_H
+
+#define BYTES_IN_WORD 4
+#define PA_PAGESIZE 0x1000
+
+/* The PA instruction set variants. */
+enum pa_arch {pa10 = 10, pa11 = 11, pa20 = 20, pa20w = 25};
+
+/* 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,
+ R_HPPA_LTPSEL = 0x12,
+ R_HPPA_RTPSEL = 0x13
+ };
+
+/* /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,
+ e_ltpsel = R_HPPA_LTPSEL,
+ e_rtpsel = R_HPPA_RTPSEL
+ };
+
+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) \
+ ((((bfd_signed_vma)(a)) << (BFD_ARCH_SIZE-22)) >> (BFD_ARCH_SIZE-22))
+#define HPPA_R_ADDEND(r, c) \
+ (((r) << 22) + ((c) & 0x3fffff))
+
+
+/* Some functions to manipulate PA instructions. */
+
+/* Declare the functions with the unused attribute to avoid warnings. */
+static inline int sign_extend (int, int) ATTRIBUTE_UNUSED;
+static inline int low_sign_extend (int, int) ATTRIBUTE_UNUSED;
+static inline int sign_unext (int, int) ATTRIBUTE_UNUSED;
+static inline int low_sign_unext (int, int) ATTRIBUTE_UNUSED;
+static inline int re_assemble_3 (int) ATTRIBUTE_UNUSED;
+static inline int re_assemble_12 (int) ATTRIBUTE_UNUSED;
+static inline int re_assemble_14 (int) ATTRIBUTE_UNUSED;
+static inline int re_assemble_16 (int) ATTRIBUTE_UNUSED;
+static inline int re_assemble_17 (int) ATTRIBUTE_UNUSED;
+static inline int re_assemble_21 (int) ATTRIBUTE_UNUSED;
+static inline int re_assemble_22 (int) ATTRIBUTE_UNUSED;
+static inline bfd_signed_vma hppa_field_adjust
+ (bfd_vma, bfd_signed_vma, enum hppa_reloc_field_selector_type_alt)
+ ATTRIBUTE_UNUSED;
+static inline int bfd_hppa_insn2fmt (bfd *, int) ATTRIBUTE_UNUSED;
+static inline int hppa_rebuild_insn (int, int, int) ATTRIBUTE_UNUSED;
+
+
+/* The *sign_extend functions are used to assemble various bitfields
+ taken from an instruction and return the resulting immediate
+ value. */
+
+static inline int
+sign_extend (int x, int len)
+{
+ int signbit = (1 << (len - 1));
+ int mask = (signbit << 1) - 1;
+ return ((x & mask) ^ signbit) - signbit;
+}
+
+static inline int
+low_sign_extend (int x, int len)
+{
+ return (x >> 1) - ((x & 1) << (len - 1));
+}
+
+
+/* The re_assemble_* functions prepare an immediate value for
+ insertion into an opcode. pa-risc uses all sorts of weird bitfields
+ in the instruction to hold the value. */
+
+static inline int
+sign_unext (int x, int len)
+{
+ int len_ones;
+
+ len_ones = (1 << len) - 1;
+
+ return x & len_ones;
+}
+
+static inline int
+low_sign_unext (int x, int len)
+{
+ int temp;
+ int sign;
+
+ sign = (x >> (len-1)) & 1;
+
+ temp = sign_unext (x, len-1);
+
+ return (temp << 1) | sign;
+}
+
+static inline int
+re_assemble_3 (int as3)
+{
+ return (( (as3 & 4) << (13-2))
+ | ((as3 & 3) << (13+1)));
+}
+
+static inline int
+re_assemble_12 (int as12)
+{
+ return (( (as12 & 0x800) >> 11)
+ | ((as12 & 0x400) >> (10 - 2))
+ | ((as12 & 0x3ff) << (1 + 2)));
+}
+
+static inline int
+re_assemble_14 (int as14)
+{
+ return (( (as14 & 0x1fff) << 1)
+ | ((as14 & 0x2000) >> 13));
+}
+
+static inline int
+re_assemble_16 (int as16)
+{
+ int s, t;
+
+ /* Unusual 16-bit encoding, for wide mode only. */
+ t = (as16 << 1) & 0xffff;
+ s = (as16 & 0x8000);
+ return (t ^ s ^ (s >> 1)) | (s >> 15);
+}
+
+static inline int
+re_assemble_17 (int as17)
+{
+ return (( (as17 & 0x10000) >> 16)
+ | ((as17 & 0x0f800) << (16 - 11))
+ | ((as17 & 0x00400) >> (10 - 2))
+ | ((as17 & 0x003ff) << (1 + 2)));
+}
+
+static inline int
+re_assemble_21 (int as21)
+{
+ return (( (as21 & 0x100000) >> 20)
+ | ((as21 & 0x0ffe00) >> 8)
+ | ((as21 & 0x000180) << 7)
+ | ((as21 & 0x00007c) << 14)
+ | ((as21 & 0x000003) << 12));
+}
+
+static inline int
+re_assemble_22 (int as22)
+{
+ return (( (as22 & 0x200000) >> 21)
+ | ((as22 & 0x1f0000) << (21 - 16))
+ | ((as22 & 0x00f800) << (16 - 11))
+ | ((as22 & 0x000400) >> (10 - 2))
+ | ((as22 & 0x0003ff) << (1 + 2)));
+}
+
+
+/* Handle field selectors for PA instructions.
+ The L and R (and LS, RS etc.) selectors are used in pairs to form a
+ full 32 bit address. eg.
+
+ LDIL L'start,%r1 ; put left part into r1
+ LDW R'start(%r1),%r2 ; add r1 and right part to form address
+
+ This function returns sign extended values in all cases.
+*/
+
+static inline bfd_signed_vma
+hppa_field_adjust (bfd_vma sym_val,
+ bfd_signed_vma addend,
+ enum hppa_reloc_field_selector_type_alt r_field)
+{
+ bfd_signed_vma value;
+
+ value = sym_val + addend;
+ switch (r_field)
+ {
+ case e_fsel:
+ /* F: No change. */
+ break;
+
+ case e_nsel:
+ /* N: null selector. I don't really understand what this is all
+ about, but HP's documentation says "this indicates that zero
+ bits are to be used for the displacement on the instruction.
+ This fixup is used to identify three-instruction sequences to
+ access data (for importing shared library data)." */
+ value = 0;
+ break;
+
+ case e_lsel:
+ case e_nlsel:
+ /* L: Select top 21 bits. */
+ value = value >> 11;
+ break;
+
+ case e_rsel:
+ /* R: Select bottom 11 bits. */
+ value = value & 0x7ff;
+ break;
+
+ case e_lssel:
+ /* LS: Round to nearest multiple of 2048 then select top 21 bits. */
+ value = value + 0x400;
+ value = value >> 11;
+ break;
+
+ case e_rssel:
+ /* RS: Select bottom 11 bits for LS.
+ We need to return a value such that 2048 * LS'x + RS'x == x.
+ ie. RS'x = x - ((x + 0x400) & -0x800)
+ this is just a sign extension from bit 21. */
+ value = ((value & 0x7ff) ^ 0x400) - 0x400;
+ break;
+
+ case e_ldsel:
+ /* LD: Round to next multiple of 2048 then select top 21 bits.
+ Yes, if we are already on a multiple of 2048, we go up to the
+ next one. RD in this case will be -2048. */
+ value = value + 0x800;
+ value = value >> 11;
+ break;
+
+ case e_rdsel:
+ /* RD: Set bits 0-20 to one. */
+ value = value | -0x800;
+ break;
+
+ case e_lrsel:
+ case e_nlrsel:
+ /* LR: L with rounding of the addend to nearest 8k. */
+ value = sym_val + ((addend + 0x1000) & -0x2000);
+ value = value >> 11;
+ break;
+
+ case e_rrsel:
+ /* RR: R with rounding of the addend to nearest 8k.
+ We need to return a value such that 2048 * LR'x + RR'x == x
+ ie. RR'x = s+a - (s + (((a + 0x1000) & -0x2000) & -0x800))
+ . = s+a - ((s & -0x800) + ((a + 0x1000) & -0x2000))
+ . = (s & 0x7ff) + a - ((a + 0x1000) & -0x2000) */
+ value = (sym_val & 0x7ff) + (((addend & 0x1fff) ^ 0x1000) - 0x1000);
+ break;
+
+ default:
+ abort ();
+ }
+ return value;
+}
+
+/* PA-RISC OPCODES */
+#define get_opcode(insn) (((insn) >> 26) & 0x3f)
+
+enum hppa_opcode_type
+{
+ /* None of the opcodes in the first group generate relocs, so we
+ aren't too concerned about them. */
+ OP_SYSOP = 0x00,
+ OP_MEMMNG = 0x01,
+ OP_ALU = 0x02,
+ OP_NDXMEM = 0x03,
+ OP_SPOP = 0x04,
+ OP_DIAG = 0x05,
+ OP_FMPYADD = 0x06,
+ OP_UNDEF07 = 0x07,
+ OP_COPRW = 0x09,
+ OP_COPRDW = 0x0b,
+ OP_COPR = 0x0c,
+ OP_FLOAT = 0x0e,
+ OP_PRDSPEC = 0x0f,
+ OP_UNDEF15 = 0x15,
+ OP_UNDEF1d = 0x1d,
+ OP_FMPYSUB = 0x26,
+ OP_FPFUSED = 0x2e,
+ OP_SHEXDP0 = 0x34,
+ OP_SHEXDP1 = 0x35,
+ OP_SHEXDP2 = 0x36,
+ OP_UNDEF37 = 0x37,
+ OP_SHEXDP3 = 0x3c,
+ OP_SHEXDP4 = 0x3d,
+ OP_MULTMED = 0x3e,
+ OP_UNDEF3f = 0x3f,
+
+ OP_LDIL = 0x08,
+ OP_ADDIL = 0x0a,
+
+ OP_LDO = 0x0d,
+ OP_LDB = 0x10,
+ OP_LDH = 0x11,
+ OP_LDW = 0x12,
+ OP_LDWM = 0x13,
+ OP_STB = 0x18,
+ OP_STH = 0x19,
+ OP_STW = 0x1a,
+ OP_STWM = 0x1b,
+
+ OP_LDD = 0x14,
+ OP_STD = 0x1c,
+
+ OP_FLDW = 0x16,
+ OP_LDWL = 0x17,
+ OP_FSTW = 0x1e,
+ OP_STWL = 0x1f,
+
+ OP_COMBT = 0x20,
+ OP_COMIBT = 0x21,
+ OP_COMBF = 0x22,
+ OP_COMIBF = 0x23,
+ OP_CMPBDT = 0x27,
+ OP_ADDBT = 0x28,
+ OP_ADDIBT = 0x29,
+ OP_ADDBF = 0x2a,
+ OP_ADDIBF = 0x2b,
+ OP_CMPBDF = 0x2f,
+ OP_BVB = 0x30,
+ OP_BB = 0x31,
+ OP_MOVB = 0x32,
+ OP_MOVIB = 0x33,
+ OP_CMPIBD = 0x3b,
+
+ OP_COMICLR = 0x24,
+ OP_SUBI = 0x25,
+ OP_ADDIT = 0x2c,
+ OP_ADDI = 0x2d,
+
+ OP_BE = 0x38,
+ OP_BLE = 0x39,
+ OP_BL = 0x3a
+};
+
+
+/* Given a machine instruction, return its format. */
+
+static inline int
+bfd_hppa_insn2fmt (bfd *abfd, int insn)
+{
+ enum hppa_opcode_type op = get_opcode (insn);
+
+ switch (op)
+ {
+ case OP_COMICLR:
+ case OP_SUBI:
+ case OP_ADDIT:
+ case OP_ADDI:
+ return 11;
+
+ case OP_COMBT:
+ case OP_COMIBT:
+ case OP_COMBF:
+ case OP_COMIBF:
+ case OP_CMPBDT:
+ case OP_ADDBT:
+ case OP_ADDIBT:
+ case OP_ADDBF:
+ case OP_ADDIBF:
+ case OP_CMPBDF:
+ case OP_BVB:
+ case OP_BB:
+ case OP_MOVB:
+ case OP_MOVIB:
+ case OP_CMPIBD:
+ return 12;
+
+ case OP_LDO:
+ case OP_LDB:
+ case OP_LDH:
+ case OP_LDW:
+ case OP_LDWM:
+ case OP_STB:
+ case OP_STH:
+ case OP_STW:
+ case OP_STWM:
+ if (abfd->arch_info->mach >= 25)
+ return 16; /* Wide mode, format 16. */
+ return 14;
+
+ case OP_FLDW:
+ case OP_LDWL:
+ case OP_FSTW:
+ case OP_STWL:
+ /* This is a hack. Unfortunately, format 11 is already taken
+ and we're using integers rather than an enum, so it's hard
+ to describe the 11a format. */
+ if (abfd->arch_info->mach >= 25)
+ return -16; /* Wide mode, format 16a. */
+ return -11;
+
+ case OP_LDD:
+ case OP_STD:
+ if (abfd->arch_info->mach >= 25)
+ return -10; /* Wide mode, format 10a. */
+ return 10;
+
+ case OP_BL:
+ if ((insn & 0x8000) != 0)
+ return 22;
+ /* fall thru */
+ case OP_BE:
+ case OP_BLE:
+ return 17;
+
+ case OP_LDIL:
+ case OP_ADDIL:
+ return 21;
+
+ default:
+ break;
+ }
+ return 32;
+}
+
+
+/* Insert VALUE into INSN using R_FORMAT to determine exactly what
+ bits to change. */
+
+static inline int
+hppa_rebuild_insn (int insn, int value, int r_format)
+{
+ switch (r_format)
+ {
+ case 11:
+ return (insn & ~ 0x7ff) | low_sign_unext (value, 11);
+
+ case 12:
+ return (insn & ~ 0x1ffd) | re_assemble_12 (value);
+
+
+ case 10:
+ return (insn & ~ 0x3ff1) | re_assemble_14 (value & -8);
+
+ case -11:
+ return (insn & ~ 0x3ff9) | re_assemble_14 (value & -4);
+
+ case 14:
+ return (insn & ~ 0x3fff) | re_assemble_14 (value);
+
+
+ case -10:
+ return (insn & ~ 0xfff1) | re_assemble_16 (value & -8);
+
+ case -16:
+ return (insn & ~ 0xfff9) | re_assemble_16 (value & -4);
+
+ case 16:
+ return (insn & ~ 0xffff) | re_assemble_16 (value);
+
+
+ case 17:
+ return (insn & ~ 0x1f1ffd) | re_assemble_17 (value);
+
+ case 21:
+ return (insn & ~ 0x1fffff) | re_assemble_21 (value);
+
+ case 22:
+ return (insn & ~ 0x3ff1ffd) | re_assemble_22 (value);
+
+ case 32:
+ return value;
+
+ default:
+ abort ();
+ }
+ return insn;
+}
+
+#endif /* _LIBHPPA_H */
diff --git a/bfd/libieee.h b/bfd/libieee.h
new file mode 100644
index 0000000..7026b85
--- /dev/null
+++ b/bfd/libieee.h
@@ -0,0 +1,135 @@
+/* IEEE-695 object file formats: definitions internal to BFD.
+ Copyright (C) 1990-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, 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;
+ bfd_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;
+ unsigned char *last_byte;
+ bfd *abfd;
+} common_header_type ;
+
+typedef struct ieee_data_struct
+{
+ common_header_type h;
+ bfd_boolean read_symbols;
+ bfd_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;
+
+
+ bfd_boolean symbol_table_full;
+
+
+bfd_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 0000000..96cc73d
--- /dev/null
+++ b/bfd/libnlm.h
@@ -0,0 +1,222 @@
+/* BFD back-end data structures for NLM (NetWare Loadable Modules) files.
+ Copyright (C) 1993-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, 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 bfd_boolean nlm_mkobject (bfd *);
+extern bfd_boolean nlm_set_arch_mach (bfd *, enum bfd_architecture, unsigned long);
+extern void nlmNAME (get_symbol_info) (bfd *, asymbol *, symbol_info *);
+extern long nlmNAME (get_symtab_upper_bound)(bfd *);
+extern long nlmNAME (canonicalize_symtab) (bfd *, asymbol **);
+extern asymbol * nlmNAME (make_empty_symbol) (bfd *);
+extern void nlmNAME (print_symbol) (bfd *, void *, asymbol *, bfd_print_symbol_type);
+extern long nlmNAME (get_reloc_upper_bound) (bfd *, asection *);
+extern long nlmNAME (canonicalize_reloc) (bfd *, asection *, arelent **, asymbol **);
+extern const bfd_target * nlmNAME (object_p) (bfd *);
+extern bfd_boolean nlmNAME (set_arch_mach) (bfd *, enum bfd_architecture, unsigned long);
+extern bfd_boolean nlmNAME (set_section_contents) (bfd *, asection *, const void *, file_ptr, bfd_size_type);
+extern bfd_boolean nlmNAME (write_object_contents) (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. */
+ unsigned int mach;
+ /* Some NLM formats do not use the uninitialized data section, so
+ all uninitialized data must be put into the regular data section
+ instead. */
+ bfd_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_bread will pick up the fixed header. */
+ bfd_boolean (*nlm_backend_object_p) (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. */
+ bfd_boolean (*nlm_write_prefix) (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. */
+ bfd_boolean (*nlm_read_reloc) (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. */
+ bfd_boolean (*nlm_mangle_relocs) (bfd *, asection *, const void *, bfd_vma, bfd_size_type);
+ /* 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. */
+ bfd_boolean (*nlm_read_import) (bfd *, nlmNAME (symbol_type) *);
+ /* Write an import record to abfd. */
+ bfd_boolean (*nlm_write_import) (bfd *, asection *, arelent *);
+ /* Set the section for a public symbol. This may be NULL, in which
+ case a default method will be used. */
+ bfd_boolean (*nlm_set_public_section) (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) (bfd *, asymbol *);
+ /* Swap the fixed header in and out */
+ void (*nlm_swap_fhdr_in) (bfd *, void *, Nlm_Internal_Fixed_Header *);
+ void (*nlm_swap_fhdr_out) (bfd *, struct nlm_internal_fixed_header *, void *);
+ /* Write out an external reference. */
+ bfd_boolean (*nlm_write_external) (bfd *, bfd_size_type, asymbol *, struct reloc_and_sec *);
+ bfd_boolean (*nlm_write_export) (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 0000000..ea04d7e
--- /dev/null
+++ b/bfd/liboasys.h
@@ -0,0 +1,83 @@
+/* BFD internal declarations for Oasys file format handling.
+ Copyright (C) 1990-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, 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;
+ bfd_boolean had_vma;
+ oasys_reloc_type **reloc_tail_ptr;
+ bfd_vma pc;
+
+
+ file_ptr current_pos;
+ unsigned int current_byte;
+ bfd_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/libpei.h b/bfd/libpei.h
new file mode 100644
index 0000000..ffcafde
--- /dev/null
+++ b/bfd/libpei.h
@@ -0,0 +1,367 @@
+/* Support for the generic parts of PE/PEI; common header information.
+ Copyright (C) 1995-2014 Free Software Foundation, Inc.
+ Written by Cygnus Solutions.
+
+ This file is part of BFD, the Binary File Descriptor library.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+
+/* Most of this hacked by Steve Chamberlain,
+ sac@cygnus.com
+
+ PE/PEI rearrangement (and code added): Donn Terry
+ Softway Systems, Inc. */
+
+/* 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. */
+
+#ifndef GET_FCN_LNNOPTR
+#define GET_FCN_LNNOPTR(abfd, ext) \
+ H_GET_32 (abfd, ext->x_sym.x_fcnary.x_fcn.x_lnnoptr)
+#endif
+
+#ifndef GET_FCN_ENDNDX
+#define GET_FCN_ENDNDX(abfd, ext) \
+ H_GET_32 (abfd, ext->x_sym.x_fcnary.x_fcn.x_endndx)
+#endif
+
+#ifndef PUT_FCN_LNNOPTR
+#define PUT_FCN_LNNOPTR(abfd, in, ext) \
+ H_PUT_32(abfd, in, ext->x_sym.x_fcnary.x_fcn.x_lnnoptr)
+#endif
+#ifndef PUT_FCN_ENDNDX
+#define PUT_FCN_ENDNDX(abfd, in, ext) \
+ H_PUT_32(abfd, in, ext->x_sym.x_fcnary.x_fcn.x_endndx)
+#endif
+#ifndef GET_LNSZ_LNNO
+#define GET_LNSZ_LNNO(abfd, ext) \
+ H_GET_16 (abfd, ext->x_sym.x_misc.x_lnsz.x_lnno)
+#endif
+#ifndef GET_LNSZ_SIZE
+#define GET_LNSZ_SIZE(abfd, ext) \
+ H_GET_16 (abfd, ext->x_sym.x_misc.x_lnsz.x_size)
+#endif
+#ifndef PUT_LNSZ_LNNO
+#define PUT_LNSZ_LNNO(abfd, in, ext) \
+ H_PUT_16(abfd, in, ext->x_sym.x_misc.x_lnsz.x_lnno)
+#endif
+#ifndef PUT_LNSZ_SIZE
+#define PUT_LNSZ_SIZE(abfd, in, ext) \
+ H_PUT_16(abfd, in, ext->x_sym.x_misc.x_lnsz.x_size)
+#endif
+#ifndef GET_SCN_SCNLEN
+#define GET_SCN_SCNLEN(abfd, ext) \
+ H_GET_32 (abfd, ext->x_scn.x_scnlen)
+#endif
+#ifndef GET_SCN_NRELOC
+#define GET_SCN_NRELOC(abfd, ext) \
+ H_GET_16 (abfd, ext->x_scn.x_nreloc)
+#endif
+#ifndef GET_SCN_NLINNO
+#define GET_SCN_NLINNO(abfd, ext) \
+ H_GET_16 (abfd, ext->x_scn.x_nlinno)
+#endif
+#ifndef PUT_SCN_SCNLEN
+#define PUT_SCN_SCNLEN(abfd, in, ext) \
+ H_PUT_32(abfd, in, ext->x_scn.x_scnlen)
+#endif
+#ifndef PUT_SCN_NRELOC
+#define PUT_SCN_NRELOC(abfd, in, ext) \
+ H_PUT_16(abfd, in, ext->x_scn.x_nreloc)
+#endif
+#ifndef PUT_SCN_NLINNO
+#define PUT_SCN_NLINNO(abfd, in, ext) \
+ H_PUT_16(abfd,in, ext->x_scn.x_nlinno)
+#endif
+#ifndef GET_LINENO_LNNO
+#define GET_LINENO_LNNO(abfd, ext) \
+ H_GET_16 (abfd, ext->l_lnno);
+#endif
+#ifndef PUT_LINENO_LNNO
+#define PUT_LINENO_LNNO(abfd, val, ext) \
+ H_PUT_16(abfd,val, ext->l_lnno);
+#endif
+
+/* The f_symptr field in the filehdr is sometimes 64 bits. */
+#ifndef GET_FILEHDR_SYMPTR
+#define GET_FILEHDR_SYMPTR H_GET_32
+#endif
+#ifndef PUT_FILEHDR_SYMPTR
+#define PUT_FILEHDR_SYMPTR H_PUT_32
+#endif
+
+/* Some fields in the aouthdr are sometimes 64 bits. */
+#ifndef GET_AOUTHDR_TSIZE
+#define GET_AOUTHDR_TSIZE H_GET_32
+#endif
+#ifndef PUT_AOUTHDR_TSIZE
+#define PUT_AOUTHDR_TSIZE H_PUT_32
+#endif
+#ifndef GET_AOUTHDR_DSIZE
+#define GET_AOUTHDR_DSIZE H_GET_32
+#endif
+#ifndef PUT_AOUTHDR_DSIZE
+#define PUT_AOUTHDR_DSIZE H_PUT_32
+#endif
+#ifndef GET_AOUTHDR_BSIZE
+#define GET_AOUTHDR_BSIZE H_GET_32
+#endif
+#ifndef PUT_AOUTHDR_BSIZE
+#define PUT_AOUTHDR_BSIZE H_PUT_32
+#endif
+#ifndef GET_AOUTHDR_ENTRY
+#define GET_AOUTHDR_ENTRY H_GET_32
+#endif
+#ifndef PUT_AOUTHDR_ENTRY
+#define PUT_AOUTHDR_ENTRY H_PUT_32
+#endif
+#ifndef GET_AOUTHDR_TEXT_START
+#define GET_AOUTHDR_TEXT_START H_GET_32
+#endif
+#ifndef PUT_AOUTHDR_TEXT_START
+#define PUT_AOUTHDR_TEXT_START H_PUT_32
+#endif
+#ifndef GET_AOUTHDR_DATA_START
+#define GET_AOUTHDR_DATA_START H_GET_32
+#endif
+#ifndef PUT_AOUTHDR_DATA_START
+#define PUT_AOUTHDR_DATA_START H_PUT_32
+#endif
+
+/* Some fields in the scnhdr are sometimes 64 bits. */
+#ifndef GET_SCNHDR_PADDR
+#define GET_SCNHDR_PADDR H_GET_32
+#endif
+#ifndef PUT_SCNHDR_PADDR
+#define PUT_SCNHDR_PADDR H_PUT_32
+#endif
+#ifndef GET_SCNHDR_VADDR
+#define GET_SCNHDR_VADDR H_GET_32
+#endif
+#ifndef PUT_SCNHDR_VADDR
+#define PUT_SCNHDR_VADDR H_PUT_32
+#endif
+#ifndef GET_SCNHDR_SIZE
+#define GET_SCNHDR_SIZE H_GET_32
+#endif
+#ifndef PUT_SCNHDR_SIZE
+#define PUT_SCNHDR_SIZE H_PUT_32
+#endif
+#ifndef GET_SCNHDR_SCNPTR
+#define GET_SCNHDR_SCNPTR H_GET_32
+#endif
+#ifndef PUT_SCNHDR_SCNPTR
+#define PUT_SCNHDR_SCNPTR H_PUT_32
+#endif
+#ifndef GET_SCNHDR_RELPTR
+#define GET_SCNHDR_RELPTR H_GET_32
+#endif
+#ifndef PUT_SCNHDR_RELPTR
+#define PUT_SCNHDR_RELPTR H_PUT_32
+#endif
+#ifndef GET_SCNHDR_LNNOPTR
+#define GET_SCNHDR_LNNOPTR H_GET_32
+#endif
+#ifndef PUT_SCNHDR_LNNOPTR
+#define PUT_SCNHDR_LNNOPTR H_PUT_32
+#endif
+
+#ifdef COFF_WITH_pex64
+
+#define GET_OPTHDR_IMAGE_BASE H_GET_64
+#define PUT_OPTHDR_IMAGE_BASE H_PUT_64
+#define GET_OPTHDR_SIZE_OF_STACK_RESERVE H_GET_64
+#define PUT_OPTHDR_SIZE_OF_STACK_RESERVE H_PUT_64
+#define GET_OPTHDR_SIZE_OF_STACK_COMMIT H_GET_64
+#define PUT_OPTHDR_SIZE_OF_STACK_COMMIT H_PUT_64
+#define GET_OPTHDR_SIZE_OF_HEAP_RESERVE H_GET_64
+#define PUT_OPTHDR_SIZE_OF_HEAP_RESERVE H_PUT_64
+#define GET_OPTHDR_SIZE_OF_HEAP_COMMIT H_GET_64
+#define PUT_OPTHDR_SIZE_OF_HEAP_COMMIT H_PUT_64
+#define GET_PDATA_ENTRY bfd_get_32
+
+#define _bfd_XX_bfd_copy_private_bfd_data_common _bfd_pex64_bfd_copy_private_bfd_data_common
+#define _bfd_XX_bfd_copy_private_section_data _bfd_pex64_bfd_copy_private_section_data
+#define _bfd_XX_get_symbol_info _bfd_pex64_get_symbol_info
+#define _bfd_XX_only_swap_filehdr_out _bfd_pex64_only_swap_filehdr_out
+#define _bfd_XX_print_private_bfd_data_common _bfd_pex64_print_private_bfd_data_common
+#define _bfd_XXi_final_link_postscript _bfd_pex64i_final_link_postscript
+#define _bfd_XXi_only_swap_filehdr_out _bfd_pex64i_only_swap_filehdr_out
+#define _bfd_XXi_swap_aouthdr_in _bfd_pex64i_swap_aouthdr_in
+#define _bfd_XXi_swap_aouthdr_out _bfd_pex64i_swap_aouthdr_out
+#define _bfd_XXi_swap_aux_in _bfd_pex64i_swap_aux_in
+#define _bfd_XXi_swap_aux_out _bfd_pex64i_swap_aux_out
+#define _bfd_XXi_swap_lineno_in _bfd_pex64i_swap_lineno_in
+#define _bfd_XXi_swap_lineno_out _bfd_pex64i_swap_lineno_out
+#define _bfd_XXi_swap_scnhdr_out _bfd_pex64i_swap_scnhdr_out
+#define _bfd_XXi_swap_sym_in _bfd_pex64i_swap_sym_in
+#define _bfd_XXi_swap_sym_out _bfd_pex64i_swap_sym_out
+#define _bfd_XXi_swap_debugdir_in _bfd_pex64i_swap_debugdir_in
+#define _bfd_XXi_swap_debugdir_out _bfd_pex64i_swap_debugdir_out
+#define _bfd_XXi_write_codeview_record _bfd_pex64i_write_codeview_record
+
+#elif defined COFF_WITH_pep
+
+#define GET_OPTHDR_IMAGE_BASE H_GET_64
+#define PUT_OPTHDR_IMAGE_BASE H_PUT_64
+#define GET_OPTHDR_SIZE_OF_STACK_RESERVE H_GET_64
+#define PUT_OPTHDR_SIZE_OF_STACK_RESERVE H_PUT_64
+#define GET_OPTHDR_SIZE_OF_STACK_COMMIT H_GET_64
+#define PUT_OPTHDR_SIZE_OF_STACK_COMMIT H_PUT_64
+#define GET_OPTHDR_SIZE_OF_HEAP_RESERVE H_GET_64
+#define PUT_OPTHDR_SIZE_OF_HEAP_RESERVE H_PUT_64
+#define GET_OPTHDR_SIZE_OF_HEAP_COMMIT H_GET_64
+#define PUT_OPTHDR_SIZE_OF_HEAP_COMMIT H_PUT_64
+#define GET_PDATA_ENTRY bfd_get_64
+
+#define _bfd_XX_bfd_copy_private_bfd_data_common _bfd_pep_bfd_copy_private_bfd_data_common
+#define _bfd_XX_bfd_copy_private_section_data _bfd_pep_bfd_copy_private_section_data
+#define _bfd_XX_get_symbol_info _bfd_pep_get_symbol_info
+#define _bfd_XX_only_swap_filehdr_out _bfd_pep_only_swap_filehdr_out
+#define _bfd_XX_print_private_bfd_data_common _bfd_pep_print_private_bfd_data_common
+#define _bfd_XXi_final_link_postscript _bfd_pepi_final_link_postscript
+#define _bfd_XXi_only_swap_filehdr_out _bfd_pepi_only_swap_filehdr_out
+#define _bfd_XXi_swap_aouthdr_in _bfd_pepi_swap_aouthdr_in
+#define _bfd_XXi_swap_aouthdr_out _bfd_pepi_swap_aouthdr_out
+#define _bfd_XXi_swap_aux_in _bfd_pepi_swap_aux_in
+#define _bfd_XXi_swap_aux_out _bfd_pepi_swap_aux_out
+#define _bfd_XXi_swap_lineno_in _bfd_pepi_swap_lineno_in
+#define _bfd_XXi_swap_lineno_out _bfd_pepi_swap_lineno_out
+#define _bfd_XXi_swap_scnhdr_out _bfd_pepi_swap_scnhdr_out
+#define _bfd_XXi_swap_sym_in _bfd_pepi_swap_sym_in
+#define _bfd_XXi_swap_sym_out _bfd_pepi_swap_sym_out
+#define _bfd_XXi_swap_debugdir_in _bfd_pepi_swap_debugdir_in
+#define _bfd_XXi_swap_debugdir_out _bfd_pepi_swap_debugdir_out
+#define _bfd_XXi_write_codeview_record _bfd_pepi_write_codeview_record
+
+#else /* !COFF_WITH_pep */
+
+#define GET_OPTHDR_IMAGE_BASE H_GET_32
+#define PUT_OPTHDR_IMAGE_BASE H_PUT_32
+#define GET_OPTHDR_SIZE_OF_STACK_RESERVE H_GET_32
+#define PUT_OPTHDR_SIZE_OF_STACK_RESERVE H_PUT_32
+#define GET_OPTHDR_SIZE_OF_STACK_COMMIT H_GET_32
+#define PUT_OPTHDR_SIZE_OF_STACK_COMMIT H_PUT_32
+#define GET_OPTHDR_SIZE_OF_HEAP_RESERVE H_GET_32
+#define PUT_OPTHDR_SIZE_OF_HEAP_RESERVE H_PUT_32
+#define GET_OPTHDR_SIZE_OF_HEAP_COMMIT H_GET_32
+#define PUT_OPTHDR_SIZE_OF_HEAP_COMMIT H_PUT_32
+#define GET_PDATA_ENTRY bfd_get_32
+
+#define _bfd_XX_bfd_copy_private_bfd_data_common _bfd_pe_bfd_copy_private_bfd_data_common
+#define _bfd_XX_bfd_copy_private_section_data _bfd_pe_bfd_copy_private_section_data
+#define _bfd_XX_get_symbol_info _bfd_pe_get_symbol_info
+#define _bfd_XX_only_swap_filehdr_out _bfd_pe_only_swap_filehdr_out
+#define _bfd_XX_print_private_bfd_data_common _bfd_pe_print_private_bfd_data_common
+#define _bfd_XXi_final_link_postscript _bfd_pei_final_link_postscript
+#define _bfd_XXi_only_swap_filehdr_out _bfd_pei_only_swap_filehdr_out
+#define _bfd_XXi_swap_aouthdr_in _bfd_pei_swap_aouthdr_in
+#define _bfd_XXi_swap_aouthdr_out _bfd_pei_swap_aouthdr_out
+#define _bfd_XXi_swap_aux_in _bfd_pei_swap_aux_in
+#define _bfd_XXi_swap_aux_out _bfd_pei_swap_aux_out
+#define _bfd_XXi_swap_lineno_in _bfd_pei_swap_lineno_in
+#define _bfd_XXi_swap_lineno_out _bfd_pei_swap_lineno_out
+#define _bfd_XXi_swap_scnhdr_out _bfd_pei_swap_scnhdr_out
+#define _bfd_XXi_swap_sym_in _bfd_pei_swap_sym_in
+#define _bfd_XXi_swap_sym_out _bfd_pei_swap_sym_out
+#define _bfd_XXi_swap_debugdir_in _bfd_pei_swap_debugdir_in
+#define _bfd_XXi_swap_debugdir_out _bfd_pei_swap_debugdir_out
+#define _bfd_XXi_write_codeview_record _bfd_pei_write_codeview_record
+
+#endif /* !COFF_WITH_pep */
+
+/* These functions are architecture dependent, and are in peicode.h:
+ coff_swap_reloc_in
+ int coff_swap_reloc_out
+ coff_swap_filehdr_in
+ coff_swap_scnhdr_in
+ pe_mkobject
+ pe_mkobject_hook */
+
+/* The functions described below are common across all PE/PEI
+ implementations architecture types, and actually appear in
+ peigen.c. */
+
+#define coff_swap_sym_in _bfd_XXi_swap_sym_in
+#define coff_swap_sym_out _bfd_XXi_swap_sym_out
+#define coff_swap_aux_in _bfd_XXi_swap_aux_in
+#define coff_swap_aux_out _bfd_XXi_swap_aux_out
+#define coff_swap_lineno_in _bfd_XXi_swap_lineno_in
+#define coff_swap_lineno_out _bfd_XXi_swap_lineno_out
+#define coff_swap_aouthdr_in _bfd_XXi_swap_aouthdr_in
+#define coff_swap_aouthdr_out _bfd_XXi_swap_aouthdr_out
+#define coff_swap_scnhdr_out _bfd_XXi_swap_scnhdr_out
+
+#ifndef coff_final_link_postscript
+#define coff_final_link_postscript _bfd_XXi_final_link_postscript
+#endif
+
+void _bfd_XXi_swap_sym_in (bfd *, void *, void *);
+unsigned _bfd_XXi_swap_sym_out (bfd *, void *, void *);
+void _bfd_XXi_swap_aux_in (bfd *, void *, int, int, int, int, void *);
+unsigned _bfd_XXi_swap_aux_out (bfd *, void *, int, int, int, int, void *);
+void _bfd_XXi_swap_lineno_in (bfd *, void *, void *);
+unsigned _bfd_XXi_swap_lineno_out (bfd *, void *, void *);
+void _bfd_XXi_swap_aouthdr_in (bfd *, void *, void *);
+unsigned _bfd_XXi_swap_aouthdr_out (bfd *, void *, void *);
+unsigned _bfd_XXi_swap_scnhdr_out (bfd *, void *, void *);
+bfd_boolean _bfd_XX_print_private_bfd_data_common (bfd *, void *);
+bfd_boolean _bfd_XX_bfd_copy_private_bfd_data_common (bfd *, bfd *);
+void _bfd_XX_get_symbol_info (bfd *, asymbol *, symbol_info *);
+bfd_boolean _bfd_XXi_final_link_postscript (bfd *, struct coff_final_link_info *);
+void _bfd_XXi_swap_debugdir_in (bfd *, void *, void *);
+unsigned _bfd_XXi_swap_debugdir_out (bfd *, void *, void *);
+unsigned _bfd_XXi_write_codeview_record (bfd *, file_ptr, CODEVIEW_INFO *);
+
+/* The following are needed only for ONE of pe or pei, but don't
+ otherwise vary; peicode.h fixes up ifdefs but we provide the
+ prototype. */
+
+unsigned _bfd_XX_only_swap_filehdr_out (bfd *, void *, void *);
+unsigned _bfd_XXi_only_swap_filehdr_out (bfd *, void *, void *);
+bfd_boolean _bfd_XX_bfd_copy_private_section_data (bfd *, asection *, bfd *, asection *);
+
+bfd_boolean _bfd_pe_print_ce_compressed_pdata (bfd *, void *);
+bfd_boolean _bfd_pe64_print_ce_compressed_pdata (bfd *, void *);
+bfd_boolean _bfd_pex64_print_ce_compressed_pdata (bfd *, void *);
+bfd_boolean _bfd_pep_print_ce_compressed_pdata (bfd *, void *);
+
diff --git a/bfd/libxcoff.h b/bfd/libxcoff.h
new file mode 100644
index 0000000..9b9c9c7
--- /dev/null
+++ b/bfd/libxcoff.h
@@ -0,0 +1,260 @@
+/* BFD XCOFF object file private structure.
+ Copyright (C) 2001-2014 Free Software Foundation, Inc.
+ Written by Tom Rix, Redhat.
+
+ This file is part of BFD, the Binary File Descriptor library.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#ifndef LIBXCOFF_H
+#define LIBXCOFF_H
+
+/* This is the backend information kept for XCOFF files. This
+ structure is constant for a particular backend. The first element
+ is the COFF backend data structure, so that XCOFF targets can use
+ the generic COFF code. */
+
+struct xcoff_backend_data_rec
+{
+ /* COFF backend information. */
+ bfd_coff_backend_data coff;
+
+ /* Magic number. */
+ unsigned short _xcoff_magic_number;
+
+ /* Architecture and machine for coff_set_arch_mach_hook. */
+ enum bfd_architecture _xcoff_architecture;
+ long _xcoff_machine;
+
+ /* Function pointers to xcoff specific swap routines. */
+ void (* _xcoff_swap_ldhdr_in) (bfd *, const void *, struct internal_ldhdr *);
+ void (* _xcoff_swap_ldhdr_out)(bfd *, const struct internal_ldhdr *, void *);
+ void (* _xcoff_swap_ldsym_in) (bfd *, const void *, struct internal_ldsym *);
+ void (* _xcoff_swap_ldsym_out)(bfd *, const struct internal_ldsym *, void *);
+ void (* _xcoff_swap_ldrel_in) (bfd *, const void *, struct internal_ldrel *);
+ void (* _xcoff_swap_ldrel_out)(bfd *, const struct internal_ldrel *, void *);
+
+ /* Size of the external struct. */
+ unsigned int _xcoff_ldhdrsz;
+ unsigned int _xcoff_ldsymsz;
+ unsigned int _xcoff_ldrelsz;
+
+ /* Size an entry in a descriptor section. */
+ unsigned int _xcoff_function_descriptor_size;
+
+ /* Size of the small aout file header. */
+ unsigned int _xcoff_small_aout_header_size;
+
+ /* Loader version
+ 1 : XCOFF32
+ 2 : XCOFF64. */
+ unsigned long _xcoff_ldhdr_version;
+
+ bfd_boolean (* _xcoff_put_symbol_name)
+ (bfd *, struct bfd_strtab_hash *, struct internal_syment *,
+ const char *);
+
+ bfd_boolean (* _xcoff_put_ldsymbol_name)
+ (bfd *, struct xcoff_loader_info *, struct internal_ldsym *,
+ const char *);
+
+ reloc_howto_type *_xcoff_dynamic_reloc;
+
+ asection * (* _xcoff_create_csect_from_smclas)
+ (bfd *, union internal_auxent *, const char *);
+
+ /* Line number and relocation overflow.
+ XCOFF32 overflows to another section when the line number or the
+ relocation count exceeds 0xffff. XCOFF64 does not overflow. */
+ bfd_boolean (*_xcoff_is_lineno_count_overflow) (bfd *, bfd_vma);
+ bfd_boolean (*_xcoff_is_reloc_count_overflow) (bfd *, bfd_vma);
+
+ /* Loader section symbol and relocation table offset
+ XCOFF32 is after the .loader header
+ XCOFF64 is offset in .loader header. */
+ bfd_vma (*_xcoff_loader_symbol_offset) (bfd *, struct internal_ldhdr *);
+ bfd_vma (*_xcoff_loader_reloc_offset) (bfd *, struct internal_ldhdr *);
+
+ /* Global linkage. The first word of global linkage code must be be
+ modified by filling in the correct TOC offset. */
+ unsigned long *_xcoff_glink_code;
+
+ /* Size of the global link code in bytes of the xcoff_glink_code table. */
+ unsigned long _xcoff_glink_size;
+
+ /* rtinit. */
+ unsigned int _xcoff_rtinit_size;
+ bfd_boolean (*_xcoff_generate_rtinit)
+ (bfd *, const char *, const char *, bfd_boolean);
+};
+
+/* 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, \
+ (bfd_boolean (*) (struct bfd_link_hash_entry *, void *)) (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))
+
+
+#define xcoff_backend(abfd) \
+ ((struct xcoff_backend_data_rec *) (abfd)->xvec->backend_data)
+
+#define bfd_xcoff_magic_number(a) ((xcoff_backend (a)->_xcoff_magic_number))
+#define bfd_xcoff_architecture(a) ((xcoff_backend (a)->_xcoff_architecture))
+#define bfd_xcoff_machine(a) ((xcoff_backend (a)->_xcoff_machine))
+
+#define bfd_xcoff_swap_ldhdr_in(a, b, c) \
+ ((xcoff_backend (a)->_xcoff_swap_ldhdr_in) ((a), (b), (c)))
+
+#define bfd_xcoff_swap_ldhdr_out(a, b, c) \
+ ((xcoff_backend (a)->_xcoff_swap_ldhdr_out) ((a), (b), (c)))
+
+#define bfd_xcoff_swap_ldsym_in(a, b, c) \
+ ((xcoff_backend (a)->_xcoff_swap_ldsym_in) ((a), (b), (c)))
+
+#define bfd_xcoff_swap_ldsym_out(a, b, c) \
+ ((xcoff_backend (a)->_xcoff_swap_ldsym_out) ((a), (b), (c)))
+
+#define bfd_xcoff_swap_ldrel_in(a, b, c) \
+ ((xcoff_backend (a)->_xcoff_swap_ldrel_in) ((a), (b), (c)))
+
+#define bfd_xcoff_swap_ldrel_out(a, b, c) \
+ ((xcoff_backend (a)->_xcoff_swap_ldrel_out) ((a), (b), (c)))
+
+#define bfd_xcoff_ldhdrsz(a) ((xcoff_backend (a)->_xcoff_ldhdrsz))
+#define bfd_xcoff_ldsymsz(a) ((xcoff_backend (a)->_xcoff_ldsymsz))
+#define bfd_xcoff_ldrelsz(a) ((xcoff_backend (a)->_xcoff_ldrelsz))
+#define bfd_xcoff_function_descriptor_size(a) \
+ ((xcoff_backend (a)->_xcoff_function_descriptor_size))
+#define bfd_xcoff_small_aout_header_size(a) \
+ ((xcoff_backend (a)->_xcoff_small_aout_header_size))
+
+#define bfd_xcoff_ldhdr_version(a) ((xcoff_backend (a)->_xcoff_ldhdr_version))
+
+#define bfd_xcoff_put_symbol_name(a, b, c, d) \
+ ((xcoff_backend (a)->_xcoff_put_symbol_name) ((a), (b), (c), (d)))
+
+#define bfd_xcoff_put_ldsymbol_name(a, b, c, d) \
+ ((xcoff_backend (a)->_xcoff_put_ldsymbol_name) ((a), (b), (c), (d)))
+
+/* 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))
+
+#define bfd_xcoff_dynamic_reloc_howto(a) \
+ ((xcoff_backend (a)->_xcoff_dynamic_reloc))
+
+#define bfd_xcoff_create_csect_from_smclas(a, b, c) \
+ ((xcoff_backend (a)->_xcoff_create_csect_from_smclas((a), (b), (c))))
+
+#define bfd_xcoff_is_lineno_count_overflow(a, b) \
+ ((xcoff_backend (a)->_xcoff_is_lineno_count_overflow((a), (b))))
+
+#define bfd_xcoff_is_reloc_count_overflow(a, b) \
+ ((xcoff_backend (a)->_xcoff_is_reloc_count_overflow((a), (b))))
+
+#define bfd_xcoff_loader_symbol_offset(a, b) \
+ ((xcoff_backend (a)->_xcoff_loader_symbol_offset((a), (b))))
+
+#define bfd_xcoff_loader_reloc_offset(a, b) \
+ ((xcoff_backend (a)->_xcoff_loader_reloc_offset((a), (b))))
+
+#define bfd_xcoff_glink_code(a, b) ((xcoff_backend (a)->_xcoff_glink_code[(b)]))
+#define bfd_xcoff_glink_code_size(a) ((xcoff_backend (a)->_xcoff_glink_size))
+
+/* Check for the magic number U803XTOCMAGIC or U64_TOCMAGIC for 64 bit
+ targets. */
+#define bfd_xcoff_is_xcoff64(a) \
+ ( (0x01EF == (bfd_xcoff_magic_number (a))) \
+ || (0x01F7 == (bfd_xcoff_magic_number (a))))
+
+/* Check for the magic number U802TOMAGIC for 32 bit targets. */
+#define bfd_xcoff_is_xcoff32(a) (0x01DF == (bfd_xcoff_magic_number (a)))
+
+#define bfd_xcoff_rtinit_size(a) ((xcoff_backend (a)->_xcoff_rtinit_size))
+#define bfd_xcoff_generate_rtinit(a, b, c, d) ((xcoff_backend (a)->_xcoff_generate_rtinit ((a), (b), (c), (d))))
+
+/* Accessor macros for tdata. */
+#define bfd_xcoff_text_align_power(a) ((xcoff_data (a)->text_align_power))
+#define bfd_xcoff_data_align_power(a) ((xcoff_data (a)->data_align_power))
+
+/* xcoff*_ppc_relocate_section macros */
+#define XCOFF_MAX_CALCULATE_RELOCATION (0x1c)
+#define XCOFF_MAX_COMPLAIN_OVERFLOW (4)
+/* N_ONES produces N one bits, without overflowing machine arithmetic. */
+#ifdef N_ONES
+#undef N_ONES
+#endif
+#define N_ONES(n) (((((bfd_vma) 1 << ((n) - 1)) - 1) << 1) | 1)
+
+#define XCOFF_RELOC_FUNCTION_ARGS \
+ bfd *, asection *, bfd *, struct internal_reloc *, \
+ struct internal_syment *, struct reloc_howto_struct *, bfd_vma, bfd_vma, \
+ bfd_vma *relocation, bfd_byte *contents
+
+#define XCOFF_COMPLAIN_FUNCTION_ARGS \
+ bfd *, bfd_vma, bfd_vma, struct reloc_howto_struct *howto
+
+extern bfd_boolean (*xcoff_calculate_relocation[XCOFF_MAX_CALCULATE_RELOCATION])
+ (XCOFF_RELOC_FUNCTION_ARGS);
+extern bfd_boolean (*xcoff_complain_overflow[XCOFF_MAX_COMPLAIN_OVERFLOW])
+ (XCOFF_COMPLAIN_FUNCTION_ARGS);
+
+#define XCOFF_NO_LONG_SECTION_NAMES (FALSE), bfd_coff_set_long_section_names_disallowed
+
+/* Relocation functions */
+bfd_boolean xcoff_reloc_type_noop (XCOFF_RELOC_FUNCTION_ARGS);
+bfd_boolean xcoff_reloc_type_fail (XCOFF_RELOC_FUNCTION_ARGS);
+bfd_boolean xcoff_reloc_type_pos (XCOFF_RELOC_FUNCTION_ARGS);
+bfd_boolean xcoff_reloc_type_neg (XCOFF_RELOC_FUNCTION_ARGS);
+bfd_boolean xcoff_reloc_type_rel (XCOFF_RELOC_FUNCTION_ARGS);
+bfd_boolean xcoff_reloc_type_toc (XCOFF_RELOC_FUNCTION_ARGS);
+bfd_boolean xcoff_reloc_type_ba (XCOFF_RELOC_FUNCTION_ARGS);
+bfd_boolean xcoff_reloc_type_crel (XCOFF_RELOC_FUNCTION_ARGS);
+
+/* Structure to describe dwarf sections.
+ Useful to convert from XCOFF section name to flag and vice-versa.
+ Also mark if section has a length field at the beginning. */
+struct xcoff_dwsect_name {
+ /* A XCOFF dwarf section is identified by its name. */
+ unsigned int flag;
+
+ /* Corresponding XCOFF section name. */
+ const char *name;
+
+ /* True if size must be prepended. */
+ bfd_boolean def_size;
+};
+
+/* Number of entries in the array. The number is known and public so that user
+ can 'extend' this array by index. */
+#define XCOFF_DWSECT_NBR_NAMES 8
+
+/* The dwarf sections array. */
+extern const struct xcoff_dwsect_name
+ xcoff_dwsect_names[XCOFF_DWSECT_NBR_NAMES];
+
+#endif /* LIBXCOFF_H */
diff --git a/bfd/linker.c b/bfd/linker.c
new file mode 100644
index 0000000..abdf5b0
--- /dev/null
+++ b/bfd/linker.c
@@ -0,0 +1,3303 @@
+/* linker.c -- BFD linker routines
+ Copyright (C) 1993-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.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 relocatable
+ 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 output bfd
+ xvec 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 output bfd 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. (The
+ callback may in fact indicate that a replacement BFD should be
+ used, in which case the symbols from that BFD should be added
+ to the linker hash table instead.)
+
+@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.
+ <<_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. 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 element's 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 - possibly those of a substitute BFD, if the
+ <<add_archive_element>> callback avails itself of that option.
+
+ 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 relocatable 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 <<map_head.link_order>>
+ 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 relocatable 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 relocatable 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 bfd_boolean generic_link_add_object_symbols
+ (bfd *, struct bfd_link_info *, bfd_boolean collect);
+static bfd_boolean generic_link_add_symbols
+ (bfd *, struct bfd_link_info *, bfd_boolean);
+static bfd_boolean generic_link_check_archive_element_no_collect
+ (bfd *, struct bfd_link_info *, struct bfd_link_hash_entry *, const char *,
+ bfd_boolean *);
+static bfd_boolean generic_link_check_archive_element_collect
+ (bfd *, struct bfd_link_info *, struct bfd_link_hash_entry *, const char *,
+ bfd_boolean *);
+static bfd_boolean generic_link_check_archive_element
+ (bfd *, struct bfd_link_info *, struct bfd_link_hash_entry *, const char *,
+ bfd_boolean *, bfd_boolean);
+static bfd_boolean generic_link_add_symbol_list
+ (bfd *, struct bfd_link_info *, bfd_size_type count, asymbol **,
+ bfd_boolean);
+static bfd_boolean generic_add_output_symbol
+ (bfd *, size_t *psymalloc, asymbol *);
+static bfd_boolean default_data_link_order
+ (bfd *, struct bfd_link_info *, asection *, struct bfd_link_order *);
+static bfd_boolean default_indirect_link_order
+ (bfd *, struct bfd_link_info *, asection *, struct bfd_link_order *,
+ bfd_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 (struct bfd_hash_entry *entry,
+ struct bfd_hash_table *table,
+ const char *string)
+{
+ /* Allocate the structure if it has not already been allocated by a
+ subclass. */
+ if (entry == NULL)
+ {
+ entry = (struct bfd_hash_entry *)
+ bfd_hash_allocate (table, sizeof (struct bfd_link_hash_entry));
+ if (entry == NULL)
+ return entry;
+ }
+
+ /* Call the allocation method of the superclass. */
+ entry = bfd_hash_newfunc (entry, table, string);
+ if (entry)
+ {
+ struct bfd_link_hash_entry *h = (struct bfd_link_hash_entry *) entry;
+
+ /* Initialize the local fields. */
+ memset ((char *) &h->root + sizeof (h->root), 0,
+ sizeof (*h) - sizeof (h->root));
+ }
+
+ return entry;
+}
+
+/* Initialize a link hash table. The BFD argument is the one
+ responsible for creating this table. */
+
+bfd_boolean
+_bfd_link_hash_table_init
+ (struct bfd_link_hash_table *table,
+ bfd *abfd ATTRIBUTE_UNUSED,
+ struct bfd_hash_entry *(*newfunc) (struct bfd_hash_entry *,
+ struct bfd_hash_table *,
+ const char *),
+ unsigned int entsize)
+{
+ bfd_boolean ret;
+
+ BFD_ASSERT (!abfd->is_linker_output && !abfd->link.hash);
+ table->undefs = NULL;
+ table->undefs_tail = NULL;
+ table->type = bfd_link_generic_hash_table;
+
+ ret = bfd_hash_table_init (&table->table, newfunc, entsize);
+ if (ret)
+ {
+ /* Arrange for destruction of this hash table on closing ABFD. */
+ table->hash_table_free = _bfd_generic_link_hash_table_free;
+ abfd->link.hash = table;
+ abfd->is_linker_output = TRUE;
+ }
+ return ret;
+}
+
+/* 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 (struct bfd_link_hash_table *table,
+ const char *string,
+ bfd_boolean create,
+ bfd_boolean copy,
+ bfd_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 != 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 (bfd *abfd,
+ struct bfd_link_info *info,
+ const char *string,
+ bfd_boolean create,
+ bfd_boolean copy,
+ bfd_boolean follow)
+{
+ bfd_size_type amt;
+
+ if (info->wrap_hash != NULL)
+ {
+ const char *l;
+ char prefix = '\0';
+
+ l = string;
+ if (*l == bfd_get_symbol_leading_char (abfd) || *l == info->wrap_char)
+ {
+ prefix = *l;
+ ++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. */
+
+ amt = strlen (l) + sizeof WRAP + 1;
+ n = (char *) bfd_malloc (amt);
+ if (n == NULL)
+ return NULL;
+
+ n[0] = prefix;
+ 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 REAL
+#define REAL "__real_"
+
+ if (*l == '_'
+ && CONST_STRNEQ (l, REAL)
+ && 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. */
+
+ amt = strlen (l + sizeof REAL - 1) + 2;
+ n = (char *) bfd_malloc (amt);
+ if (n == NULL)
+ return NULL;
+
+ n[0] = prefix;
+ 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);
+}
+
+/* If H is a wrapped symbol, ie. the symbol name starts with "__wrap_"
+ and the remainder is found in wrap_hash, return the real symbol. */
+
+struct bfd_link_hash_entry *
+unwrap_hash_lookup (struct bfd_link_info *info,
+ bfd *input_bfd,
+ struct bfd_link_hash_entry *h)
+{
+ const char *l = h->root.string;
+
+ if (*l == bfd_get_symbol_leading_char (input_bfd)
+ || *l == info->wrap_char)
+ ++l;
+
+ if (CONST_STRNEQ (l, WRAP))
+ {
+ l += sizeof WRAP - 1;
+
+ if (bfd_hash_lookup (info->wrap_hash, l, FALSE, FALSE) != NULL)
+ {
+ char save = 0;
+ if (l - (sizeof WRAP - 1) != h->root.string)
+ {
+ --l;
+ save = *l;
+ *(char *) l = *h->root.string;
+ }
+ h = bfd_link_hash_lookup (info->hash, l, FALSE, FALSE, FALSE);
+ if (save)
+ *(char *) l = save;
+ }
+ }
+ return h;
+}
+#undef WRAP
+
+/* Traverse a generic link hash table. Differs from bfd_hash_traverse
+ in the treatment of warning symbols. When warning symbols are
+ created they replace the real symbol, so you don't get to see the
+ real symbol in a bfd_hash_travere. This traversal calls func with
+ the real symbol. */
+
+void
+bfd_link_hash_traverse
+ (struct bfd_link_hash_table *htab,
+ bfd_boolean (*func) (struct bfd_link_hash_entry *, void *),
+ void *info)
+{
+ unsigned int i;
+
+ htab->table.frozen = 1;
+ for (i = 0; i < htab->table.size; i++)
+ {
+ struct bfd_link_hash_entry *p;
+
+ p = (struct bfd_link_hash_entry *) htab->table.table[i];
+ for (; p != NULL; p = (struct bfd_link_hash_entry *) p->root.next)
+ if (!(*func) (p->type == bfd_link_hash_warning ? p->u.i.link : p, info))
+ goto out;
+ }
+ out:
+ htab->table.frozen = 0;
+}
+
+/* Add a symbol to the linker hash table undefs list. */
+
+void
+bfd_link_add_undef (struct bfd_link_hash_table *table,
+ struct bfd_link_hash_entry *h)
+{
+ BFD_ASSERT (h->u.undef.next == NULL);
+ if (table->undefs_tail != NULL)
+ table->undefs_tail->u.undef.next = h;
+ if (table->undefs == NULL)
+ table->undefs = h;
+ table->undefs_tail = h;
+}
+
+/* The undefs list was designed so that in normal use we don't need to
+ remove entries. However, if symbols on the list are changed from
+ bfd_link_hash_undefined to either bfd_link_hash_undefweak or
+ bfd_link_hash_new for some reason, then they must be removed from the
+ list. Failure to do so might result in the linker attempting to add
+ the symbol to the list again at a later stage. */
+
+void
+bfd_link_repair_undef_list (struct bfd_link_hash_table *table)
+{
+ struct bfd_link_hash_entry **pun;
+
+ pun = &table->undefs;
+ while (*pun != NULL)
+ {
+ struct bfd_link_hash_entry *h = *pun;
+
+ if (h->type == bfd_link_hash_new
+ || h->type == bfd_link_hash_undefweak)
+ {
+ *pun = h->u.undef.next;
+ h->u.undef.next = NULL;
+ if (h == table->undefs_tail)
+ {
+ if (pun == &table->undefs)
+ table->undefs_tail = NULL;
+ else
+ /* pun points at an u.undef.next field. Go back to
+ the start of the link_hash_entry. */
+ table->undefs_tail = (struct bfd_link_hash_entry *)
+ ((char *) pun - ((char *) &h->u.undef.next - (char *) h));
+ break;
+ }
+ }
+ else
+ pun = &h->u.undef.next;
+ }
+}
+
+/* Routine to create an entry in a generic link hash table. */
+
+struct bfd_hash_entry *
+_bfd_generic_link_hash_newfunc (struct bfd_hash_entry *entry,
+ struct bfd_hash_table *table,
+ const char *string)
+{
+ /* Allocate the structure if it has not already been allocated by a
+ subclass. */
+ if (entry == NULL)
+ {
+ entry = (struct bfd_hash_entry *)
+ bfd_hash_allocate (table, sizeof (struct generic_link_hash_entry));
+ if (entry == NULL)
+ return entry;
+ }
+
+ /* Call the allocation method of the superclass. */
+ entry = _bfd_link_hash_newfunc (entry, table, string);
+ if (entry)
+ {
+ struct generic_link_hash_entry *ret;
+
+ /* Set local fields. */
+ ret = (struct generic_link_hash_entry *) entry;
+ ret->written = FALSE;
+ ret->sym = NULL;
+ }
+
+ return entry;
+}
+
+/* Create a generic link hash table. */
+
+struct bfd_link_hash_table *
+_bfd_generic_link_hash_table_create (bfd *abfd)
+{
+ struct generic_link_hash_table *ret;
+ bfd_size_type amt = sizeof (struct generic_link_hash_table);
+
+ ret = (struct generic_link_hash_table *) bfd_malloc (amt);
+ if (ret == NULL)
+ return NULL;
+ if (! _bfd_link_hash_table_init (&ret->root, abfd,
+ _bfd_generic_link_hash_newfunc,
+ sizeof (struct generic_link_hash_entry)))
+ {
+ free (ret);
+ return NULL;
+ }
+ return &ret->root;
+}
+
+void
+_bfd_generic_link_hash_table_free (bfd *obfd)
+{
+ struct generic_link_hash_table *ret;
+
+ BFD_ASSERT (obfd->is_linker_output && obfd->link.hash);
+ ret = (struct generic_link_hash_table *) obfd->link.hash;
+ bfd_hash_table_free (&ret->root.table);
+ free (ret);
+ obfd->link.hash = NULL;
+ obfd->is_linker_output = FALSE;
+}
+
+/* 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. */
+
+bfd_boolean
+bfd_generic_link_read_symbols (bfd *abfd)
+{
+ if (bfd_get_outsymbols (abfd) == NULL)
+ {
+ long symsize;
+ long symcount;
+
+ symsize = bfd_get_symtab_upper_bound (abfd);
+ if (symsize < 0)
+ return FALSE;
+ bfd_get_outsymbols (abfd) = (struct bfd_symbol **) 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. */
+
+bfd_boolean
+_bfd_generic_link_add_symbols (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. */
+
+bfd_boolean
+_bfd_generic_link_add_symbols_collect (bfd *abfd, struct bfd_link_info *info)
+{
+ return generic_link_add_symbols (abfd, info, TRUE);
+}
+
+/* Indicate that we are only retrieving symbol values from this
+ section. We want the symbols to act as though the values in the
+ file are absolute. */
+
+void
+_bfd_generic_link_just_syms (asection *sec,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED)
+{
+ sec->sec_info_type = SEC_INFO_TYPE_JUST_SYMS;
+ sec->output_section = bfd_abs_section_ptr;
+ sec->output_offset = sec->vma;
+}
+
+/* Copy the symbol type and other attributes for a linker script
+ assignment from HSRC to HDEST.
+ The default implementation does nothing. */
+void
+_bfd_generic_copy_link_hash_symbol_type (bfd *abfd ATTRIBUTE_UNUSED,
+ struct bfd_link_hash_entry *hdest ATTRIBUTE_UNUSED,
+ struct bfd_link_hash_entry *hsrc ATTRIBUTE_UNUSED)
+{
+}
+
+/* Add symbols from an object file to the global hash table. */
+
+static bfd_boolean
+generic_link_add_symbols (bfd *abfd,
+ struct bfd_link_info *info,
+ bfd_boolean collect)
+{
+ bfd_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 bfd_boolean
+generic_link_add_object_symbols (bfd *abfd,
+ struct bfd_link_info *info,
+ bfd_boolean collect)
+{
+ bfd_size_type symcount;
+ struct bfd_symbol **outsyms;
+
+ if (!bfd_generic_link_read_symbols (abfd))
+ return FALSE;
+ symcount = _bfd_generic_link_get_symcount (abfd);
+ outsyms = _bfd_generic_link_get_symbols (abfd);
+ return generic_link_add_symbol_list (abfd, info, symcount, outsyms, collect);
+}
+
+/* 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 archive symbol
+ table for symbols that are undefined or common in the linker global
+ symbol hash table. When one is found, the CHECKFN argument is used
+ to see if an object file should be included. This allows targets
+ to customize common symbol behaviour. 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 must notice
+ if the callback indicates a substitute BFD, and arrange to add
+ those symbols instead if it does so. CHECKFN should only return
+ FALSE if some sort of error occurs. */
+
+bfd_boolean
+_bfd_generic_link_add_archive_symbols
+ (bfd *abfd,
+ struct bfd_link_info *info,
+ bfd_boolean (*checkfn) (bfd *, struct bfd_link_info *,
+ struct bfd_link_hash_entry *, const char *,
+ bfd_boolean *))
+{
+ bfd_boolean loop;
+ bfd_size_type amt;
+ unsigned char *included;
+
+ if (! bfd_has_map (abfd))
+ {
+ /* An empty archive is a special case. */
+ if (bfd_openr_next_archived_file (abfd, NULL) == NULL)
+ return TRUE;
+ bfd_set_error (bfd_error_no_armap);
+ return FALSE;
+ }
+
+ amt = bfd_ardata (abfd)->symdef_count;
+ if (amt == 0)
+ return TRUE;
+ amt *= sizeof (*included);
+ included = (unsigned char *) bfd_zmalloc (amt);
+ if (included == NULL)
+ return FALSE;
+
+ do
+ {
+ carsym *arsyms;
+ carsym *arsym_end;
+ carsym *arsym;
+ unsigned int indx;
+ file_ptr last_ar_offset = -1;
+ bfd_boolean needed = FALSE;
+ bfd *element = NULL;
+
+ loop = FALSE;
+ arsyms = bfd_ardata (abfd)->symdefs;
+ arsym_end = arsyms + bfd_ardata (abfd)->symdef_count;
+ for (arsym = arsyms, indx = 0; arsym < arsym_end; arsym++, indx++)
+ {
+ struct bfd_link_hash_entry *h;
+ struct bfd_link_hash_entry *undefs_tail;
+
+ if (included[indx])
+ continue;
+ if (needed && arsym->file_offset == last_ar_offset)
+ {
+ included[indx] = 1;
+ continue;
+ }
+
+ h = bfd_link_hash_lookup (info->hash, arsym->name,
+ FALSE, FALSE, TRUE);
+
+ if (h == NULL
+ && info->pei386_auto_import
+ && CONST_STRNEQ (arsym->name, "__imp_"))
+ h = bfd_link_hash_lookup (info->hash, arsym->name + 6,
+ FALSE, FALSE, TRUE);
+ if (h == NULL)
+ continue;
+
+ if (h->type != bfd_link_hash_undefined
+ && h->type != bfd_link_hash_common)
+ {
+ if (h->type != bfd_link_hash_undefweak)
+ /* Symbol must be defined. Don't check it again. */
+ included[indx] = 1;
+ continue;
+ }
+
+ if (last_ar_offset != arsym->file_offset)
+ {
+ last_ar_offset = arsym->file_offset;
+ element = _bfd_get_elt_at_filepos (abfd, last_ar_offset);
+ if (element == NULL
+ || !bfd_check_format (element, bfd_object))
+ goto error_return;
+ }
+
+ undefs_tail = info->hash->undefs_tail;
+
+ /* CHECKFN will see if this element should be included, and
+ go ahead and include it if appropriate. */
+ if (! (*checkfn) (element, info, h, arsym->name, &needed))
+ goto error_return;
+
+ if (needed)
+ {
+ unsigned int mark;
+
+ /* Look backward to mark all symbols from this object file
+ which we have already seen in this pass. */
+ mark = indx;
+ do
+ {
+ included[mark] = 1;
+ if (mark == 0)
+ break;
+ --mark;
+ }
+ while (arsyms[mark].file_offset == last_ar_offset);
+
+ if (undefs_tail != info->hash->undefs_tail)
+ loop = TRUE;
+ }
+ }
+ } while (loop);
+
+ free (included);
+ return TRUE;
+
+ error_return:
+ free (included);
+ 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 bfd_boolean
+generic_link_check_archive_element_no_collect (bfd *abfd,
+ struct bfd_link_info *info,
+ struct bfd_link_hash_entry *h,
+ const char *name,
+ bfd_boolean *pneeded)
+{
+ return generic_link_check_archive_element (abfd, info, h, name, 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 bfd_boolean
+generic_link_check_archive_element_collect (bfd *abfd,
+ struct bfd_link_info *info,
+ struct bfd_link_hash_entry *h,
+ const char *name,
+ bfd_boolean *pneeded)
+{
+ return generic_link_check_archive_element (abfd, info, h, name, pneeded,
+ TRUE);
+}
+
+/* See if we should include an archive element. Optionally collect
+ constructors. */
+
+static bfd_boolean
+generic_link_check_archive_element (bfd *abfd,
+ struct bfd_link_info *info,
+ struct bfd_link_hash_entry *h,
+ const char *name ATTRIBUTE_UNUSED,
+ bfd_boolean *pneeded,
+ bfd_boolean collect)
+{
+ asymbol **pp, **ppend;
+
+ *pneeded = FALSE;
+
+ if (!bfd_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;
+
+ 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 == 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)
+ || (h->type == bfd_link_hash_undefined
+ && h->u.undef.abfd == NULL))
+ {
+ /* P is not a common symbol, or an undefined reference was
+ created from outside BFD such as from a linker -u option.
+ This object file defines the symbol, so pull it in. */
+ *pneeded = TRUE;
+ if (!(*info->callbacks
+ ->add_archive_element) (info, abfd, bfd_asymbol_name (p),
+ &abfd))
+ return FALSE;
+ /* Potentially, the add_archive_element hook may have set a
+ substitute BFD for us. */
+ return generic_link_add_object_symbols (abfd, info, collect);
+ }
+
+ /* P is a common symbol. */
+
+ if (h->type == bfd_link_hash_undefined)
+ {
+ bfd *symbfd;
+ bfd_vma size;
+ unsigned int power;
+
+ /* 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. */
+ symbfd = h->u.undef.abfd;
+ 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 bfd_boolean
+generic_link_add_symbol_list (bfd *abfd,
+ struct bfd_link_info *info,
+ bfd_size_type symbol_count,
+ asymbol **symbols,
+ bfd_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;
+ struct bfd_link_hash_entry *bh;
+
+ string = 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. */
+ pp++;
+ name = bfd_asymbol_name (*pp);
+ }
+
+ bh = NULL;
+ if (! (_bfd_generic_link_add_one_symbol
+ (info, abfd, name, p->flags, bfd_get_section (p),
+ p->value, string, FALSE, collect, &bh)))
+ return FALSE;
+ h = (struct generic_link_hash_entry *) bh;
+
+ /* 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->output_bfd->xvec == abfd->xvec)
+ {
+ if (h->sym == 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 = 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, /* 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, COM, BIG, REFC, WARNC },
+ /* INDR_ROW */ {IND, IND, IND, MDEF, IND, CIND, MIND, CYCLE },
+ /* WARN_ROW */ {MWARN, WARN, WARN, WARN, WARN, WARN, WARN, NOACT },
+ /* 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 (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. */
+
+bfd_boolean
+_bfd_generic_link_add_one_symbol (struct bfd_link_info *info,
+ bfd *abfd,
+ const char *name,
+ flagword flags,
+ asection *section,
+ bfd_vma value,
+ const char *string,
+ bfd_boolean copy,
+ bfd_boolean collect,
+ struct bfd_link_hash_entry **hashp)
+{
+ enum link_row row;
+ struct bfd_link_hash_entry *h;
+ struct bfd_link_hash_entry *inh = NULL;
+ bfd_boolean cycle;
+
+ BFD_ASSERT (section != NULL);
+
+ if (bfd_is_ind_section (section)
+ || (flags & BSF_INDIRECT) != 0)
+ {
+ row = INDR_ROW;
+ /* Create the indirect symbol here. This is for the benefit of
+ the plugin "notice" function.
+ 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 == NULL)
+ return FALSE;
+ }
+ 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;
+ if (strcmp (name, "__gnu_lto_slim") == 0)
+ (*_bfd_error_handler)
+ (_("%s: plugin needed to handle lto object"),
+ bfd_get_filename (abfd));
+ }
+ 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 != NULL
+ && bfd_hash_lookup (info->notice_hash, name, FALSE, FALSE) != NULL))
+ {
+ if (! (*info->callbacks->notice) (info, h, inh,
+ abfd, section, value, flags))
+ return FALSE;
+ }
+
+ if (hashp != 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, abfd, bfd_link_hash_defined, 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' && CONST_STRNEQ (s, CONS_PREFIX))
+ {
+ 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',
+ 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->u.undef.next == NULL && info->hash->undefs_tail != h)
+ h->u.undef.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, and use the section required by the larger symbol. */
+ BFD_ASSERT (h->type == bfd_link_hash_common);
+ if (! ((*info->callbacks->multiple_common)
+ (info, h, 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;
+
+ /* Some systems have special treatment for small commons,
+ hence we want to select the section used by the larger
+ symbol. This makes sure the symbol does not go in a
+ small common section if it is now too large. */
+ 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 CREF:
+ /* We have found a common definition for a symbol which
+ was already defined. */
+ if (! ((*info->callbacks->multiple_common)
+ (info, h, 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. */
+ if (! ((*info->callbacks->multiple_definition)
+ (info, h, 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, abfd, bfd_link_hash_indirect, 0)))
+ return FALSE;
+ /* Fall through. */
+ case IND:
+ if (inh->type == bfd_link_hash_indirect
+ && inh->u.i.link == h)
+ {
+ (*_bfd_error_handler)
+ (_("%B: indirect symbol `%s' to `%s' is a loop"),
+ abfd, name, string);
+ bfd_set_error (bfd_error_invalid_operation);
+ 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)
+ {
+ /* ??? If inh->type == bfd_link_hash_undefweak this
+ converts inh to bfd_link_hash_undefined. */
+ row = UNDEF_ROW;
+ cycle = TRUE;
+ }
+
+ h->type = bfd_link_hash_indirect;
+ h->u.i.link = inh;
+ /* Not setting h = h->u.i.link here means that when cycle is
+ set above we'll always go to REFC, and then cycle again
+ to the indirected symbol. This means that any successful
+ change of an existing symbol to indirect counts as a
+ reference. ??? That may not be correct when the existing
+ symbol was defweak. */
+ 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, except when the reference is
+ in LTO IR. */
+ if (h->u.i.warning != NULL
+ && (abfd->flags & BFD_PLUGIN) == 0)
+ {
+ if (! (*info->callbacks->warning) (info, h->u.i.warning,
+ h->root.string, abfd,
+ NULL, 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->u.undef.next == NULL && info->hash->undefs_tail != h)
+ h->u.undef.next = h;
+ h = h->u.i.link;
+ cycle = TRUE;
+ break;
+
+ case WARN:
+ /* Warn if this symbol has been referenced already from non-IR,
+ otherwise add a warning. */
+ if ((!info->lto_plugin_active
+ && (h->u.undef.next != NULL || info->hash->undefs_tail == h))
+ || h->non_ir_ref)
+ {
+ if (! (*info->callbacks->warning) (info, string, h->root.string,
+ hash_entry_bfd (h), NULL, 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)
+ (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;
+ size_t len = strlen (string) + 1;
+
+ w = (char *) bfd_hash_allocate (&info->hash->table, len);
+ if (w == NULL)
+ return FALSE;
+ memcpy (w, string, len);
+ 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. */
+
+bfd_boolean
+_bfd_generic_final_link (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) = 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->map_head.link_order; 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 != 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,
+ &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->relocatable)
+ {
+ /* Allocate space for the output relocs for each section. */
+ for (o = abfd->sections; o != NULL; o = o->next)
+ {
+ o->reloc_count = 0;
+ for (p = o->map_head.link_order; 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 *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 (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);
+ free (relocs);
+ if (reloc_count < 0)
+ return FALSE;
+ BFD_ASSERT ((unsigned long) reloc_count
+ == input_section->reloc_count);
+ o->reloc_count += reloc_count;
+ }
+ }
+ if (o->reloc_count > 0)
+ {
+ bfd_size_type amt;
+
+ amt = o->reloc_count;
+ amt *= sizeof (arelent *);
+ o->orelocation = (struct reloc_cache_entry **) bfd_alloc (abfd, amt);
+ 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 != NULL; o = o->next)
+ {
+ for (p = o->map_head.link_order; p != 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 bfd_boolean
+generic_add_output_symbol (bfd *output_bfd, size_t *psymalloc, asymbol *sym)
+{
+ if (bfd_get_symcount (output_bfd) >= *psymalloc)
+ {
+ asymbol **newsyms;
+ bfd_size_type amt;
+
+ if (*psymalloc == 0)
+ *psymalloc = 124;
+ else
+ *psymalloc *= 2;
+ amt = *psymalloc;
+ amt *= sizeof (asymbol *);
+ newsyms = (asymbol **) bfd_realloc (bfd_get_outsymbols (output_bfd), amt);
+ if (newsyms == 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. */
+
+bfd_boolean
+_bfd_generic_link_output_symbols (bfd *output_bfd,
+ bfd *input_bfd,
+ struct bfd_link_info *info,
+ size_t *psymalloc)
+{
+ asymbol **sym_ptr;
+ asymbol **sym_end;
+
+ if (!bfd_generic_link_read_symbols (input_bfd))
+ return FALSE;
+
+ /* Create a filename symbol if we are supposed to. */
+ if (info->create_object_symbols_section != NULL)
+ {
+ asection *sec;
+
+ for (sec = input_bfd->sections; sec != 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;
+ bfd_boolean output;
+
+ h = 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 != 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->output_bfd->xvec == input_bfd->xvec)
+ {
+ if (h->sym != 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) == 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_sec_merge:
+ output = TRUE;
+ if (info->relocatable
+ || ! (sym->section->flags & SEC_MERGE))
+ break;
+ /* FALLTHROUGH */
+ 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 if (sym->flags == 0
+ && (sym->section->owner->flags & BFD_PLUGIN) != 0)
+ /* LTO doesn't set symbol information. We get here with the
+ generic linker for a symbol that was "common" but no longer
+ needs to be global. */
+ 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. */
+ if (!bfd_is_abs_section (sym->section)
+ && bfd_section_removed_from_list (output_bfd,
+ sym->section->output_section))
+ output = FALSE;
+
+ if (output)
+ {
+ if (! generic_add_output_symbol (output_bfd, psymalloc, sym))
+ return FALSE;
+ if (h != 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 (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. */
+
+bfd_boolean
+_bfd_generic_link_write_global_symbol (struct generic_link_hash_entry *h,
+ void *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 != 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. */
+
+bfd_boolean
+_bfd_generic_reloc_link_order (bfd *abfd,
+ struct bfd_link_info *info,
+ asection *sec,
+ struct bfd_link_order *link_order)
+{
+ arelent *r;
+
+ if (! info->relocatable)
+ abort ();
+ if (sec->orelocation == NULL)
+ abort ();
+
+ r = (arelent *) bfd_alloc (abfd, sizeof (arelent));
+ if (r == 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 == NULL
+ || ! h->written)
+ {
+ if (! ((*info->callbacks->unattached_reloc)
+ (info, link_order->u.reloc.p->u.name, NULL, NULL, 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;
+ bfd_boolean ok;
+ file_ptr loc;
+
+ size = bfd_get_reloc_size (r->howto);
+ buf = (bfd_byte *) bfd_zmalloc (size);
+ if (buf == NULL)
+ return FALSE;
+ rstat = _bfd_relocate_contents (r->howto, abfd,
+ (bfd_vma) 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, NULL,
+ (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,
+ NULL, NULL, 0)))
+ {
+ free (buf);
+ return FALSE;
+ }
+ break;
+ }
+ loc = link_order->offset * bfd_octets_per_byte (abfd);
+ ok = bfd_set_section_contents (abfd, sec, buf, loc, 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 (bfd *abfd, asection *section)
+{
+ bfd_size_type amt = sizeof (struct bfd_link_order);
+ struct bfd_link_order *new_lo;
+
+ new_lo = (struct bfd_link_order *) bfd_zalloc (abfd, amt);
+ if (!new_lo)
+ return NULL;
+
+ new_lo->type = bfd_undefined_link_order;
+
+ if (section->map_tail.link_order != NULL)
+ section->map_tail.link_order->next = new_lo;
+ else
+ section->map_head.link_order = new_lo;
+ section->map_tail.link_order = new_lo;
+
+ return new_lo;
+}
+
+/* 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. */
+
+bfd_boolean
+_bfd_default_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_data_link_order:
+ return default_data_link_order (abfd, info, sec, link_order);
+ }
+}
+
+/* Default routine to handle a bfd_data_link_order. */
+
+static bfd_boolean
+default_data_link_order (bfd *abfd,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ asection *sec,
+ struct bfd_link_order *link_order)
+{
+ bfd_size_type size;
+ size_t fill_size;
+ bfd_byte *fill;
+ file_ptr loc;
+ bfd_boolean result;
+
+ BFD_ASSERT ((sec->flags & SEC_HAS_CONTENTS) != 0);
+
+ size = link_order->size;
+ if (size == 0)
+ return TRUE;
+
+ fill = link_order->u.data.contents;
+ fill_size = link_order->u.data.size;
+ if (fill_size == 0)
+ {
+ fill = abfd->arch_info->fill (size, bfd_big_endian (abfd),
+ (sec->flags & SEC_CODE) != 0);
+ if (fill == NULL)
+ return FALSE;
+ }
+ else if (fill_size < size)
+ {
+ bfd_byte *p;
+ fill = (bfd_byte *) bfd_malloc (size);
+ if (fill == NULL)
+ return FALSE;
+ p = fill;
+ if (fill_size == 1)
+ memset (p, (int) link_order->u.data.contents[0], (size_t) size);
+ else
+ {
+ do
+ {
+ memcpy (p, link_order->u.data.contents, fill_size);
+ p += fill_size;
+ size -= fill_size;
+ }
+ while (size >= fill_size);
+ if (size != 0)
+ memcpy (p, link_order->u.data.contents, (size_t) size);
+ size = link_order->size;
+ }
+ }
+
+ loc = link_order->offset * bfd_octets_per_byte (abfd);
+ result = bfd_set_section_contents (abfd, sec, fill, loc, size);
+
+ if (fill != link_order->u.data.contents)
+ free (fill);
+ return result;
+}
+
+/* Default routine to handle a bfd_indirect_link_order. */
+
+static bfd_boolean
+default_indirect_link_order (bfd *output_bfd,
+ struct bfd_link_info *info,
+ asection *output_section,
+ struct bfd_link_order *link_order,
+ bfd_boolean generic_linker)
+{
+ asection *input_section;
+ bfd *input_bfd;
+ bfd_byte *contents = NULL;
+ bfd_byte *new_contents;
+ bfd_size_type sec_size;
+ file_ptr loc;
+
+ BFD_ASSERT ((output_section->flags & SEC_HAS_CONTENTS) != 0);
+
+ input_section = link_order->u.indirect.section;
+ input_bfd = input_section->owner;
+ if (input_section->size == 0)
+ return TRUE;
+
+ BFD_ASSERT (input_section->output_section == output_section);
+ BFD_ASSERT (input_section->output_offset == link_order->offset);
+ BFD_ASSERT (input_section->size == link_order->size);
+
+ if (info->relocatable
+ && input_section->reloc_count > 0
+ && output_section->orelocation == 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 relocatable 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 (!bfd_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);
+ }
+ }
+ }
+
+ if ((output_section->flags & (SEC_GROUP | SEC_LINKER_CREATED)) == SEC_GROUP
+ && input_section->size != 0)
+ {
+ /* Group section contents are set by bfd_elf_set_group_contents. */
+ if (!output_bfd->output_has_begun)
+ {
+ /* FIXME: This hack ensures bfd_elf_set_group_contents is called. */
+ if (!bfd_set_section_contents (output_bfd, output_section, "", 0, 1))
+ goto error_return;
+ }
+ new_contents = output_section->contents;
+ BFD_ASSERT (new_contents != NULL);
+ BFD_ASSERT (input_section->output_offset == 0);
+ }
+ else
+ {
+ /* Get and relocate the section contents. */
+ sec_size = (input_section->rawsize > input_section->size
+ ? input_section->rawsize
+ : input_section->size);
+ contents = (bfd_byte *) bfd_malloc (sec_size);
+ if (contents == NULL && sec_size != 0)
+ goto error_return;
+ new_contents = (bfd_get_relocated_section_contents
+ (output_bfd, info, link_order, contents,
+ info->relocatable,
+ _bfd_generic_link_get_symbols (input_bfd)));
+ if (!new_contents)
+ goto error_return;
+ }
+
+ /* Output the section contents. */
+ loc = input_section->output_offset * bfd_octets_per_byte (output_bfd);
+ if (! bfd_set_section_contents (output_bfd, output_section,
+ new_contents, loc, input_section->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 (struct bfd_link_order *link_order)
+{
+ register unsigned int c;
+ register struct bfd_link_order *l;
+
+ c = 0;
+ for (l = link_order; l != 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
+ bfd_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))
+.
+
+*/
+
+bfd_boolean
+_bfd_generic_link_split_section (bfd *abfd ATTRIBUTE_UNUSED,
+ asection *sec ATTRIBUTE_UNUSED)
+{
+ return FALSE;
+}
+
+/*
+FUNCTION
+ bfd_section_already_linked
+
+SYNOPSIS
+ bfd_boolean bfd_section_already_linked (bfd *abfd,
+ asection *sec,
+ struct bfd_link_info *info);
+
+DESCRIPTION
+ Check if @var{data} has been already linked during a reloceatable
+ or final link. Return TRUE if it has.
+
+.#define bfd_section_already_linked(abfd, sec, info) \
+. BFD_SEND (abfd, _section_already_linked, (abfd, sec, info))
+.
+
+*/
+
+/* Sections marked with the SEC_LINK_ONCE flag should only be linked
+ once into the output. This routine checks each section, and
+ arrange 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. bfd_section_already_linked is called via
+ bfd_map_over_sections. */
+
+/* The hash table. */
+
+static struct bfd_hash_table _bfd_section_already_linked_table;
+
+/* Support routines for the hash table used by section_already_linked,
+ initialize the table, traverse, lookup, fill in an entry and remove
+ the table. */
+
+void
+bfd_section_already_linked_table_traverse
+ (bfd_boolean (*func) (struct bfd_section_already_linked_hash_entry *,
+ void *), void *info)
+{
+ bfd_hash_traverse (&_bfd_section_already_linked_table,
+ (bfd_boolean (*) (struct bfd_hash_entry *,
+ void *)) func,
+ info);
+}
+
+struct bfd_section_already_linked_hash_entry *
+bfd_section_already_linked_table_lookup (const char *name)
+{
+ return ((struct bfd_section_already_linked_hash_entry *)
+ bfd_hash_lookup (&_bfd_section_already_linked_table, name,
+ TRUE, FALSE));
+}
+
+bfd_boolean
+bfd_section_already_linked_table_insert
+ (struct bfd_section_already_linked_hash_entry *already_linked_list,
+ asection *sec)
+{
+ struct bfd_section_already_linked *l;
+
+ /* Allocate the memory from the same obstack as the hash table is
+ kept in. */
+ l = (struct bfd_section_already_linked *)
+ bfd_hash_allocate (&_bfd_section_already_linked_table, sizeof *l);
+ if (l == NULL)
+ return FALSE;
+ l->sec = sec;
+ l->next = already_linked_list->entry;
+ already_linked_list->entry = l;
+ return TRUE;
+}
+
+static struct bfd_hash_entry *
+already_linked_newfunc (struct bfd_hash_entry *entry ATTRIBUTE_UNUSED,
+ struct bfd_hash_table *table,
+ const char *string ATTRIBUTE_UNUSED)
+{
+ struct bfd_section_already_linked_hash_entry *ret =
+ (struct bfd_section_already_linked_hash_entry *)
+ bfd_hash_allocate (table, sizeof *ret);
+
+ if (ret == NULL)
+ return NULL;
+
+ ret->entry = NULL;
+
+ return &ret->root;
+}
+
+bfd_boolean
+bfd_section_already_linked_table_init (void)
+{
+ return bfd_hash_table_init_n (&_bfd_section_already_linked_table,
+ already_linked_newfunc,
+ sizeof (struct bfd_section_already_linked_hash_entry),
+ 42);
+}
+
+void
+bfd_section_already_linked_table_free (void)
+{
+ bfd_hash_table_free (&_bfd_section_already_linked_table);
+}
+
+/* Report warnings as appropriate for duplicate section SEC.
+ Return FALSE if we decide to keep SEC after all. */
+
+bfd_boolean
+_bfd_handle_already_linked (asection *sec,
+ struct bfd_section_already_linked *l,
+ struct bfd_link_info *info)
+{
+ switch (sec->flags & SEC_LINK_DUPLICATES)
+ {
+ default:
+ abort ();
+
+ case SEC_LINK_DUPLICATES_DISCARD:
+ /* If we found an LTO IR match for this comdat group on
+ the first pass, replace it with the LTO output on the
+ second pass. We can't simply choose real object
+ files over IR because the first pass may contain a
+ mix of LTO and normal objects and we must keep the
+ first match, be it IR or real. */
+ if (info->loading_lto_outputs
+ && (l->sec->owner->flags & BFD_PLUGIN) != 0)
+ {
+ l->sec = sec;
+ return FALSE;
+ }
+ break;
+
+ case SEC_LINK_DUPLICATES_ONE_ONLY:
+ info->callbacks->einfo
+ (_("%B: ignoring duplicate section `%A'\n"),
+ sec->owner, sec);
+ break;
+
+ case SEC_LINK_DUPLICATES_SAME_SIZE:
+ if ((l->sec->owner->flags & BFD_PLUGIN) != 0)
+ ;
+ else if (sec->size != l->sec->size)
+ info->callbacks->einfo
+ (_("%B: duplicate section `%A' has different size\n"),
+ sec->owner, sec);
+ break;
+
+ case SEC_LINK_DUPLICATES_SAME_CONTENTS:
+ if ((l->sec->owner->flags & BFD_PLUGIN) != 0)
+ ;
+ else if (sec->size != l->sec->size)
+ info->callbacks->einfo
+ (_("%B: duplicate section `%A' has different size\n"),
+ sec->owner, sec);
+ else if (sec->size != 0)
+ {
+ bfd_byte *sec_contents, *l_sec_contents = NULL;
+
+ if (!bfd_malloc_and_get_section (sec->owner, sec, &sec_contents))
+ info->callbacks->einfo
+ (_("%B: could not read contents of section `%A'\n"),
+ sec->owner, sec);
+ else if (!bfd_malloc_and_get_section (l->sec->owner, l->sec,
+ &l_sec_contents))
+ info->callbacks->einfo
+ (_("%B: could not read contents of section `%A'\n"),
+ l->sec->owner, l->sec);
+ else if (memcmp (sec_contents, l_sec_contents, sec->size) != 0)
+ info->callbacks->einfo
+ (_("%B: duplicate section `%A' has different contents\n"),
+ sec->owner, sec);
+
+ if (sec_contents)
+ free (sec_contents);
+ if (l_sec_contents)
+ free (l_sec_contents);
+ }
+ break;
+ }
+
+ /* Set the output_section field so that lang_add_section
+ does not create a lang_input_section structure for this
+ section. Since there might be a symbol in the section
+ being discarded, we must retain a pointer to the section
+ which we are really going to use. */
+ sec->output_section = bfd_abs_section_ptr;
+ sec->kept_section = l->sec;
+ return TRUE;
+}
+
+/* This is used on non-ELF inputs. */
+
+bfd_boolean
+_bfd_generic_section_already_linked (bfd *abfd ATTRIBUTE_UNUSED,
+ asection *sec,
+ struct bfd_link_info *info)
+{
+ const char *name;
+ struct bfd_section_already_linked *l;
+ struct bfd_section_already_linked_hash_entry *already_linked_list;
+
+ if ((sec->flags & SEC_LINK_ONCE) == 0)
+ return FALSE;
+
+ /* The generic linker doesn't handle section groups. */
+ if ((sec->flags & SEC_GROUP) != 0)
+ return FALSE;
+
+ /* FIXME: When doing a relocatable link, we may have trouble
+ copying relocations in other sections that refer to local symbols
+ in the section being discarded. Those relocations will have to
+ be converted somehow; as of this writing I'm not sure that any of
+ the backends handle that correctly.
+
+ It is tempting to instead not discard link once sections when
+ doing a relocatable link (technically, they should be discarded
+ whenever we are building constructors). However, that fails,
+ because the linker winds up combining all the link once sections
+ into a single large link once section, which defeats the purpose
+ of having link once sections in the first place. */
+
+ name = bfd_get_section_name (abfd, sec);
+
+ already_linked_list = bfd_section_already_linked_table_lookup (name);
+
+ l = already_linked_list->entry;
+ if (l != NULL)
+ {
+ /* The section has already been linked. See if we should
+ issue a warning. */
+ return _bfd_handle_already_linked (sec, l, info);
+ }
+
+ /* This is the first section with this name. Record it. */
+ if (!bfd_section_already_linked_table_insert (already_linked_list, sec))
+ info->callbacks->einfo (_("%F%P: already_linked_table: %E\n"));
+ return FALSE;
+}
+
+/* Choose a neighbouring section to S in OBFD that will be output, or
+ the absolute section if ADDR is out of bounds of the neighbours. */
+
+asection *
+_bfd_nearby_section (bfd *obfd, asection *s, bfd_vma addr)
+{
+ asection *next, *prev, *best;
+
+ /* Find preceding kept section. */
+ for (prev = s->prev; prev != NULL; prev = prev->prev)
+ if ((prev->flags & SEC_EXCLUDE) == 0
+ && !bfd_section_removed_from_list (obfd, prev))
+ break;
+
+ /* Find following kept section. Start at prev->next because
+ other sections may have been added after S was removed. */
+ if (s->prev != NULL)
+ next = s->prev->next;
+ else
+ next = s->owner->sections;
+ for (; next != NULL; next = next->next)
+ if ((next->flags & SEC_EXCLUDE) == 0
+ && !bfd_section_removed_from_list (obfd, next))
+ break;
+
+ /* Choose better of two sections, based on flags. The idea
+ is to choose a section that will be in the same segment
+ as S would have been if it was kept. */
+ best = next;
+ if (prev == NULL)
+ {
+ if (next == NULL)
+ best = bfd_abs_section_ptr;
+ }
+ else if (next == NULL)
+ best = prev;
+ else if (((prev->flags ^ next->flags)
+ & (SEC_ALLOC | SEC_THREAD_LOCAL | SEC_LOAD)) != 0)
+ {
+ if (((next->flags ^ s->flags)
+ & (SEC_ALLOC | SEC_THREAD_LOCAL)) != 0
+ /* We prefer to choose a loaded section. Section S
+ doesn't have SEC_LOAD set (it being excluded, that
+ part of the flag processing didn't happen) so we
+ can't compare that flag to those of NEXT and PREV. */
+ || ((prev->flags & SEC_LOAD) != 0
+ && (next->flags & SEC_LOAD) == 0))
+ best = prev;
+ }
+ else if (((prev->flags ^ next->flags) & SEC_READONLY) != 0)
+ {
+ if (((next->flags ^ s->flags) & SEC_READONLY) != 0)
+ best = prev;
+ }
+ else if (((prev->flags ^ next->flags) & SEC_CODE) != 0)
+ {
+ if (((next->flags ^ s->flags) & SEC_CODE) != 0)
+ best = prev;
+ }
+ else
+ {
+ /* Flags we care about are the same. Prefer the following
+ section if that will result in a positive valued sym. */
+ if (addr < next->vma)
+ best = prev;
+ }
+
+ return best;
+}
+
+/* Convert symbols in excluded output sections to use a kept section. */
+
+static bfd_boolean
+fix_syms (struct bfd_link_hash_entry *h, void *data)
+{
+ bfd *obfd = (bfd *) data;
+
+ if (h->type == bfd_link_hash_defined
+ || h->type == bfd_link_hash_defweak)
+ {
+ asection *s = h->u.def.section;
+ if (s != NULL
+ && s->output_section != NULL
+ && (s->output_section->flags & SEC_EXCLUDE) != 0
+ && bfd_section_removed_from_list (obfd, s->output_section))
+ {
+ asection *op;
+
+ h->u.def.value += s->output_offset + s->output_section->vma;
+ op = _bfd_nearby_section (obfd, s->output_section, h->u.def.value);
+ h->u.def.value -= op->vma;
+ h->u.def.section = op;
+ }
+ }
+
+ return TRUE;
+}
+
+void
+_bfd_fix_excluded_sec_syms (bfd *obfd, struct bfd_link_info *info)
+{
+ bfd_link_hash_traverse (info->hash, fix_syms, obfd);
+}
+
+/*
+FUNCTION
+ bfd_generic_define_common_symbol
+
+SYNOPSIS
+ bfd_boolean bfd_generic_define_common_symbol
+ (bfd *output_bfd, struct bfd_link_info *info,
+ struct bfd_link_hash_entry *h);
+
+DESCRIPTION
+ Convert common symbol @var{h} into a defined symbol.
+ Return TRUE on success and FALSE on failure.
+
+.#define bfd_define_common_symbol(output_bfd, info, h) \
+. BFD_SEND (output_bfd, _bfd_define_common_symbol, (output_bfd, info, h))
+.
+*/
+
+bfd_boolean
+bfd_generic_define_common_symbol (bfd *output_bfd,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ struct bfd_link_hash_entry *h)
+{
+ unsigned int power_of_two;
+ bfd_vma alignment, size;
+ asection *section;
+
+ BFD_ASSERT (h != NULL && h->type == bfd_link_hash_common);
+
+ size = h->u.c.size;
+ power_of_two = h->u.c.p->alignment_power;
+ section = h->u.c.p->section;
+
+ /* Increase the size of the section to align the common symbol.
+ The alignment must be a power of two. */
+ alignment = bfd_octets_per_byte (output_bfd) << power_of_two;
+ BFD_ASSERT (alignment != 0 && (alignment & -alignment) == alignment);
+ section->size += alignment - 1;
+ section->size &= -alignment;
+
+ /* Adjust the section's overall 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->size;
+
+ /* Increase the size of the section. */
+ section->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;
+ return TRUE;
+}
+
+/*
+FUNCTION
+ bfd_find_version_for_sym
+
+SYNOPSIS
+ struct bfd_elf_version_tree * bfd_find_version_for_sym
+ (struct bfd_elf_version_tree *verdefs,
+ const char *sym_name, bfd_boolean *hide);
+
+DESCRIPTION
+ Search an elf version script tree for symbol versioning
+ info and export / don't-export status for a given symbol.
+ Return non-NULL on success and NULL on failure; also sets
+ the output @samp{hide} boolean parameter.
+
+*/
+
+struct bfd_elf_version_tree *
+bfd_find_version_for_sym (struct bfd_elf_version_tree *verdefs,
+ const char *sym_name,
+ bfd_boolean *hide)
+{
+ struct bfd_elf_version_tree *t;
+ struct bfd_elf_version_tree *local_ver, *global_ver, *exist_ver;
+ struct bfd_elf_version_tree *star_local_ver, *star_global_ver;
+
+ local_ver = NULL;
+ global_ver = NULL;
+ star_local_ver = NULL;
+ star_global_ver = NULL;
+ exist_ver = NULL;
+ for (t = verdefs; t != NULL; t = t->next)
+ {
+ if (t->globals.list != NULL)
+ {
+ struct bfd_elf_version_expr *d = NULL;
+
+ while ((d = (*t->match) (&t->globals, d, sym_name)) != NULL)
+ {
+ if (d->literal || strcmp (d->pattern, "*") != 0)
+ global_ver = t;
+ else
+ star_global_ver = t;
+ if (d->symver)
+ exist_ver = t;
+ d->script = 1;
+ /* If the match is a wildcard pattern, keep looking for
+ a more explicit, perhaps even local, match. */
+ if (d->literal)
+ break;
+ }
+
+ if (d != NULL)
+ break;
+ }
+
+ if (t->locals.list != NULL)
+ {
+ struct bfd_elf_version_expr *d = NULL;
+
+ while ((d = (*t->match) (&t->locals, d, sym_name)) != NULL)
+ {
+ if (d->literal || strcmp (d->pattern, "*") != 0)
+ local_ver = t;
+ else
+ star_local_ver = t;
+ /* If the match is a wildcard pattern, keep looking for
+ a more explicit, perhaps even global, match. */
+ if (d->literal)
+ {
+ /* An exact match overrides a global wildcard. */
+ global_ver = NULL;
+ star_global_ver = NULL;
+ break;
+ }
+ }
+
+ if (d != NULL)
+ break;
+ }
+ }
+
+ if (global_ver == NULL && local_ver == NULL)
+ global_ver = star_global_ver;
+
+ if (global_ver != NULL)
+ {
+ /* If we already have a versioned symbol that matches the
+ node for this symbol, then we don't want to create a
+ duplicate from the unversioned symbol. Instead hide the
+ unversioned symbol. */
+ *hide = exist_ver == global_ver;
+ return global_ver;
+ }
+
+ if (local_ver == NULL)
+ local_ver = star_local_ver;
+
+ if (local_ver != NULL)
+ {
+ *hide = TRUE;
+ return local_ver;
+ }
+
+ return NULL;
+}
+
+/*
+FUNCTION
+ bfd_hide_sym_by_version
+
+SYNOPSIS
+ bfd_boolean bfd_hide_sym_by_version
+ (struct bfd_elf_version_tree *verdefs, const char *sym_name);
+
+DESCRIPTION
+ Search an elf version script tree for symbol versioning
+ info for a given symbol. Return TRUE if the symbol is hidden.
+
+*/
+
+bfd_boolean
+bfd_hide_sym_by_version (struct bfd_elf_version_tree *verdefs,
+ const char *sym_name)
+{
+ bfd_boolean hidden = FALSE;
+ bfd_find_version_for_sym (verdefs, sym_name, &hidden);
+ return hidden;
+}
diff --git a/bfd/lynx-core.c b/bfd/lynx-core.c
new file mode 100644
index 0000000..dc4e457
--- /dev/null
+++ b/bfd/lynx-core.c
@@ -0,0 +1,226 @@
+/* BFD back end for Lynx core files
+ Copyright (C) 1993-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.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)
+
+#define lynx_core_file_matches_executable_p generic_core_file_matches_executable_p
+#define lynx_core_file_pid _bfd_nocore_core_file_pid
+
+/* Handle Lynx core dump file. */
+
+static asection *
+make_bfd_asection (bfd *abfd,
+ const char *name,
+ flagword flags,
+ bfd_size_type size,
+ bfd_vma vma,
+ file_ptr filepos)
+{
+ asection *asect;
+ char *newname;
+
+ newname = bfd_alloc (abfd, (bfd_size_type) strlen (name) + 1);
+ if (!newname)
+ return NULL;
+
+ strcpy (newname, name);
+
+ asect = bfd_make_section_with_flags (abfd, newname, flags);
+ if (!asect)
+ return NULL;
+
+ asect->size = size;
+ asect->vma = vma;
+ asect->filepos = filepos;
+ asect->alignment_power = 2;
+
+ return asect;
+}
+
+const bfd_target *
+lynx_core_file_p (bfd *abfd)
+{
+ int secnum;
+ struct pssentry pss;
+ bfd_size_type tcontext_size;
+ core_st_t *threadp;
+ int pagesize;
+ asection *newsect;
+ bfd_size_type amt;
+
+ 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, (file_ptr) 0, SEEK_SET) != 0)
+ return NULL;
+
+ amt = sizeof pss;
+ if (bfd_bread ((void *) &pss, amt, abfd) != amt)
+ {
+ /* Too small to be a core file */
+ if (bfd_get_error () != bfd_error_system_call)
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+
+ amt = sizeof (struct lynx_core_struct);
+ core_hdr (abfd) = (struct lynx_core_struct *) bfd_zalloc (abfd, amt);
+
+ 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)
+ goto fail;
+
+ /* Save thread contexts */
+
+ if (bfd_seek (abfd, (file_ptr) pagesize, SEEK_SET) != 0)
+ goto fail;
+
+ if (bfd_bread ((void *) threadp, tcontext_size, abfd) != 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);
+ goto fail;
+ }
+
+ 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)
+ goto fail;
+
+ 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)
+ goto fail;
+
+/* 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)
+ goto fail;
+
+ 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)
+ goto fail;
+ }
+
+ return abfd->xvec;
+
+ fail:
+ bfd_release (abfd, core_hdr (abfd));
+ core_hdr (abfd) = NULL;
+ bfd_section_list_clear (abfd);
+ return NULL;
+}
+
+char *
+lynx_core_file_failing_command (bfd *abfd)
+{
+ return core_command (abfd);
+}
+
+int
+lynx_core_file_failing_signal (bfd *abfd)
+{
+ return core_signal (abfd);
+}
+
+#endif /* LYNX_CORE */
diff --git a/bfd/m68k4knetbsd.c b/bfd/m68k4knetbsd.c
new file mode 100644
index 0000000..254f9ef
--- /dev/null
+++ b/bfd/m68k4knetbsd.c
@@ -0,0 +1,36 @@
+/* BFD back-end for NetBSD/m68k a.out-ish binaries.
+ Copyright (C) 1990-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#define TARGET_IS_BIG_ENDIAN_P
+
+#define TARGET_PAGE_SIZE 0x1000
+
+#define DEFAULT_ARCH bfd_arch_m68k
+#define DEFAULT_MID M_68K4K_NETBSD
+
+/* Do not "beautify" the CONCAT* macro args. Traditional C will not
+ remove whitespace added here, and thus will fail to concatenate
+ the tokens. */
+#define MY(OP) CONCAT2 (m68k_aout_4knbsd_,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 0000000..036870f
--- /dev/null
+++ b/bfd/m68klinux.c
@@ -0,0 +1,736 @@
+/* BFD back-end for linux flavored m68k a.out binaries.
+ Copyright (C) 1992-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#define TARGET_PAGE_SIZE 4096
+#define ZMAGIC_DISK_BLOCK_SIZE 1024
+#define SEGMENT_SIZE TARGET_PAGE_SIZE
+#define TEXT_START_ADDR 0x0
+
+#define MACHTYPE_OK(mtype) ((mtype) == M_68020 || (mtype) == M_UNKNOWN)
+
+#include "sysdep.h"
+#include "bfd.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
+
+/* Do not "beautify" the CONCAT* macro args. Traditional C will not
+ remove whitespace added here, and thus will fail to concatenate
+ the tokens. */
+#define MY(OP) CONCAT2 (m68k_aout_linux_,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
+ (bfd *, file_ptr *, file_ptr *, file_ptr *);
+
+static bfd_boolean
+m68klinux_bfd_final_link (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 bfd_boolean
+m68klinux_write_object_contents (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) (CONST_STRNEQ (name, GOT_REF_PREFIX))
+
+/* 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) (CONST_STRNEQ (name, PLT_REF_PREFIX))
+
+/* 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 dynamically
+ 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;
+};
+
+/* Routine to create an entry in an Linux link hash table. */
+
+static struct bfd_hash_entry *
+linux_link_hash_newfunc (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 (bfd *abfd)
+{
+ struct linux_link_hash_table *ret;
+ bfd_size_type amt = sizeof (struct linux_link_hash_table);
+
+ ret = (struct linux_link_hash_table *) bfd_zmalloc (amt);
+ 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,
+ sizeof (struct linux_link_hash_entry)))
+ {
+ free (ret);
+ return (struct bfd_link_hash_table *) 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, \
+ (bfd_boolean (*) (struct aout_link_hash_entry *, void *)) (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 (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 bfd_boolean
+linux_link_create_dynamic_sections (bfd *abfd,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED)
+{
+ flagword flags;
+ 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_with_flags (abfd, ".linux-dynamic", flags);
+ if (s == NULL
+ || ! bfd_set_section_alignment (abfd, s, 2))
+ return FALSE;
+ s->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 bfd_boolean
+linux_add_one_symbol (struct bfd_link_info *info,
+ bfd *abfd,
+ const char *name,
+ flagword flags,
+ asection *section,
+ bfd_vma value,
+ const char *string,
+ bfd_boolean copy,
+ bfd_boolean collect,
+ struct bfd_link_hash_entry **hashp)
+{
+ struct linux_link_hash_entry *h;
+ bfd_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->output_bfd->xvec? We may
+ want to be able to link Linux a.out and ELF objects together,
+ but serious confusion is possible. */
+
+ insert = FALSE;
+
+ if (! info->relocatable
+ && linux_hash_table (info)->dynobj == NULL
+ && strcmp (name, SHARABLE_CONFLICTS) == 0
+ && (flags & BSF_CONSTRUCTOR) != 0
+ && abfd->xvec == info->output_bfd->xvec)
+ {
+ 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->output_bfd->xvec)
+ {
+ 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, (bfd_vma) 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 bfd_boolean
+linux_tally_symbols (struct linux_link_hash_entry *h,
+ void * 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;
+ bfd_boolean exists;
+
+ if (h->root.root.type == bfd_link_hash_undefined
+ && CONST_STRNEQ (h->root.root.root.string, NEEDS_SHRLIB))
+ {
+ 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 ((bfd_size_type) 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. */
+
+bfd_boolean
+bfd_m68klinux_size_dynamic_sections (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,
+ 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->size = linux_hash_table (info)->fixup_count + 1;
+ s->size *= 8;
+ s->contents = (bfd_byte *) bfd_zalloc (output_bfd, s->size);
+ if (s->contents == NULL)
+ {
+ bfd_set_error (bfd_error_no_memory);
+ return FALSE;
+ }
+ }
+
+ 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 bfd_boolean
+linux_finish_dynamic_link (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, (bfd_vma) 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, (bfd_vma) 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, (bfd_vma) 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, (bfd_vma) 0, fixup_table);
+ fixup_table += 4;
+ bfd_put_32 (output_bfd, (bfd_vma) 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, (bfd_vma) 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, (bfd_vma) 0, fixup_table);
+ fixup_table += 4;
+ bfd_put_32 (output_bfd, (bfd_vma) 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, (bfd_vma) new_addr, fixup_table);
+ }
+ else
+ bfd_put_32 (output_bfd, (bfd_vma) 0, fixup_table);
+
+ if (bfd_seek (output_bfd, (file_ptr) (os->filepos + s->output_offset),
+ SEEK_SET) != 0)
+ return FALSE;
+
+ if (bfd_bwrite (s->contents, s->size, output_bfd) != s->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/m68knetbsd.c b/bfd/m68knetbsd.c
new file mode 100644
index 0000000..53a2563
--- /dev/null
+++ b/bfd/m68knetbsd.c
@@ -0,0 +1,38 @@
+/* BFD back-end for NetBSD/m68k a.out-ish binaries.
+ Copyright (C) 1990-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#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
+
+/* Do not "beautify" the CONCAT* macro args. Traditional C will not
+ remove whitespace added here, and thus will fail to concatenate
+ the tokens. */
+#define MY(OP) CONCAT2 (m68k_aout_nbsd_,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 0000000..b6c87fb
--- /dev/null
+++ b/bfd/m88kmach3.c
@@ -0,0 +1,41 @@
+/* BFD back-end for Motorola m88k a.out (Mach 3) binaries.
+ Copyright (C) 1990-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#define TARGET_PAGE_SIZE (4096*2)
+#define SEGMENT_SIZE 0x20000
+#define TEXT_START_ADDR 0
+#define N_HEADER_IN_TEXT(x) 1 /* (N_MAGIG(x) == ZMAGIC) */
+
+#define N_TXTSIZE(x) ((x).a_text)
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+#include "libaout.h"
+
+#define DEFAULT_ARCH bfd_arch_m88k
+
+/* Do not "beautify" the CONCAT* macro args. Traditional C will not
+ remove whitespace added here, and thus will fail to concatenate
+ the tokens. */
+#define MY(OP) CONCAT2 (m88k_aout_mach3_,OP)
+#define TARGETNAME "a.out-m88k-mach3"
+
+#include "aout-target.h"
diff --git a/bfd/m88kopenbsd.c b/bfd/m88kopenbsd.c
new file mode 100644
index 0000000..d970d94
--- /dev/null
+++ b/bfd/m88kopenbsd.c
@@ -0,0 +1,34 @@
+/* BFD back-end for OpenBSD/m88k a.out binaries.
+ Copyright (C) 2004-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#define TARGET_IS_BIG_ENDIAN_P
+
+#define TARGET_PAGE_SIZE 4096
+
+#define DEFAULT_ARCH bfd_arch_m88k
+#define DEFAULT_MID M_88K_OPENBSD
+
+/* Do not "beautify" the CONCAT* macro args. Traditional C will not
+ remove whitespace added here, and thus will fail to concatenate
+ the tokens. */
+#define MY(OP) CONCAT2 (m88k_aout_obsd_,OP)
+#define TARGETNAME "a.out-m88k-openbsd"
+
+#include "netbsd.h"
diff --git a/bfd/mach-o-i386.c b/bfd/mach-o-i386.c
new file mode 100644
index 0000000..a7d3a11
--- /dev/null
+++ b/bfd/mach-o-i386.c
@@ -0,0 +1,404 @@
+/* Intel i386 Mach-O support for BFD.
+ Copyright (C) 2009-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "mach-o.h"
+#include "bfd.h"
+#include "libbfd.h"
+#include "libiberty.h"
+#include "mach-o/reloc.h"
+
+#define bfd_mach_o_object_p bfd_mach_o_i386_object_p
+#define bfd_mach_o_core_p bfd_mach_o_i386_core_p
+#define bfd_mach_o_mkobject bfd_mach_o_i386_mkobject
+
+static const bfd_target *
+bfd_mach_o_i386_object_p (bfd *abfd)
+{
+ return bfd_mach_o_header_p (abfd, 0, BFD_MACH_O_CPU_TYPE_I386);
+}
+
+static const bfd_target *
+bfd_mach_o_i386_core_p (bfd *abfd)
+{
+ return bfd_mach_o_header_p (abfd,
+ BFD_MACH_O_MH_CORE, BFD_MACH_O_CPU_TYPE_I386);
+}
+
+static bfd_boolean
+bfd_mach_o_i386_mkobject (bfd *abfd)
+{
+ bfd_mach_o_data_struct *mdata;
+
+ if (!bfd_mach_o_mkobject_init (abfd))
+ return FALSE;
+
+ mdata = bfd_mach_o_get_data (abfd);
+ mdata->header.magic = BFD_MACH_O_MH_MAGIC;
+ mdata->header.cputype = BFD_MACH_O_CPU_TYPE_I386;
+ mdata->header.cpusubtype = BFD_MACH_O_CPU_SUBTYPE_X86_ALL;
+ mdata->header.byteorder = BFD_ENDIAN_LITTLE;
+ mdata->header.version = 1;
+
+ return TRUE;
+}
+
+static reloc_howto_type i386_howto_table[]=
+{
+ /* 0 */
+ HOWTO(BFD_RELOC_32, 0, 2, 32, FALSE, 0,
+ complain_overflow_bitfield,
+ NULL, "32",
+ FALSE, 0xffffffff, 0xffffffff, FALSE),
+ HOWTO(BFD_RELOC_16, 0, 1, 16, FALSE, 0,
+ complain_overflow_bitfield,
+ NULL, "16",
+ FALSE, 0xffff, 0xffff, FALSE),
+ HOWTO(BFD_RELOC_8, 0, 0, 8, FALSE, 0,
+ complain_overflow_bitfield,
+ NULL, "8",
+ FALSE, 0xff, 0xff, FALSE),
+ HOWTO(BFD_RELOC_32_PCREL, 0, 2, 32, TRUE, 0,
+ complain_overflow_bitfield,
+ NULL, "DISP32",
+ FALSE, 0xffffffff, 0xffffffff, TRUE),
+ /* 4 */
+ HOWTO(BFD_RELOC_16_PCREL, 0, 1, 16, TRUE, 0,
+ complain_overflow_bitfield,
+ NULL, "DISP16",
+ FALSE, 0xffff, 0xffff, TRUE),
+ HOWTO(BFD_RELOC_MACH_O_SECTDIFF, 0, 2, 32, FALSE, 0,
+ complain_overflow_bitfield,
+ NULL, "SECTDIFF_32",
+ FALSE, 0xffffffff, 0xffffffff, FALSE),
+ HOWTO(BFD_RELOC_MACH_O_LOCAL_SECTDIFF, 0, 2, 32, FALSE, 0,
+ complain_overflow_bitfield,
+ NULL, "LSECTDIFF_32",
+ FALSE, 0xffffffff, 0xffffffff, FALSE),
+ HOWTO(BFD_RELOC_MACH_O_PAIR, 0, 2, 32, FALSE, 0,
+ complain_overflow_bitfield,
+ NULL, "PAIR_32",
+ FALSE, 0xffffffff, 0xffffffff, FALSE),
+ /* 8 */
+ HOWTO(BFD_RELOC_MACH_O_SECTDIFF, 0, 1, 16, FALSE, 0,
+ complain_overflow_bitfield,
+ NULL, "SECTDIFF_16",
+ FALSE, 0xffff, 0xffff, FALSE),
+ HOWTO(BFD_RELOC_MACH_O_LOCAL_SECTDIFF, 0, 1, 16, FALSE, 0,
+ complain_overflow_bitfield,
+ NULL, "LSECTDIFF_16",
+ FALSE, 0xffff, 0xffff, FALSE),
+ HOWTO(BFD_RELOC_MACH_O_PAIR, 0, 1, 16, FALSE, 0,
+ complain_overflow_bitfield,
+ NULL, "PAIR_16",
+ FALSE, 0xffff, 0xffff, FALSE),
+};
+
+static bfd_boolean
+bfd_mach_o_i386_swap_reloc_in (arelent *res, bfd_mach_o_reloc_info *reloc)
+{
+ if (reloc->r_scattered)
+ {
+ switch (reloc->r_type)
+ {
+ case BFD_MACH_O_GENERIC_RELOC_PAIR:
+ if (reloc->r_length == 2)
+ {
+ res->howto = &i386_howto_table[7];
+ res->address = res[-1].address;
+ return TRUE;
+ }
+ else if (reloc->r_length == 1)
+ {
+ res->howto = &i386_howto_table[10];
+ res->address = res[-1].address;
+ return TRUE;
+ }
+ return FALSE;
+ case BFD_MACH_O_GENERIC_RELOC_SECTDIFF:
+ if (reloc->r_length == 2)
+ {
+ res->howto = &i386_howto_table[5];
+ return TRUE;
+ }
+ else if (reloc->r_length == 1)
+ {
+ res->howto = &i386_howto_table[8];
+ return TRUE;
+ }
+ return FALSE;
+ case BFD_MACH_O_GENERIC_RELOC_LOCAL_SECTDIFF:
+ if (reloc->r_length == 2)
+ {
+ res->howto = &i386_howto_table[6];
+ return TRUE;
+ }
+ else if (reloc->r_length == 1)
+ {
+ res->howto = &i386_howto_table[9];
+ return TRUE;
+ }
+ return FALSE;
+ default:
+ return FALSE;
+ }
+ }
+ else
+ {
+ switch (reloc->r_type)
+ {
+ case BFD_MACH_O_GENERIC_RELOC_VANILLA:
+ switch ((reloc->r_length << 1) | reloc->r_pcrel)
+ {
+ case 0: /* len = 0, pcrel = 0 */
+ res->howto = &i386_howto_table[2];
+ return TRUE;
+ case 2: /* len = 1, pcrel = 0 */
+ res->howto = &i386_howto_table[1];
+ return TRUE;
+ case 3: /* len = 1, pcrel = 1 */
+ res->howto = &i386_howto_table[4];
+ return TRUE;
+ case 4: /* len = 2, pcrel = 0 */
+ res->howto = &i386_howto_table[0];
+ return TRUE;
+ case 5: /* len = 2, pcrel = 1 */
+ res->howto = &i386_howto_table[3];
+ return TRUE;
+ default:
+ return FALSE;
+ }
+ break;
+ default:
+ return FALSE;
+ }
+ }
+}
+
+static bfd_boolean
+bfd_mach_o_i386_swap_reloc_out (arelent *rel, bfd_mach_o_reloc_info *rinfo)
+{
+ rinfo->r_address = rel->address;
+ switch (rel->howto->type)
+ {
+ case BFD_RELOC_32:
+ case BFD_RELOC_32_PCREL:
+ case BFD_RELOC_16:
+ case BFD_RELOC_16_PCREL:
+ case BFD_RELOC_8:
+ rinfo->r_scattered = 0;
+ rinfo->r_type = BFD_MACH_O_GENERIC_RELOC_VANILLA;
+ rinfo->r_pcrel = rel->howto->pc_relative;
+ rinfo->r_length = rel->howto->size; /* Correct in practice. */
+ if ((*rel->sym_ptr_ptr)->flags & BSF_SECTION_SYM)
+ {
+ rinfo->r_extern = 0;
+ rinfo->r_value =
+ (*rel->sym_ptr_ptr)->section->output_section->target_index;
+ }
+ else
+ {
+ rinfo->r_extern = 1;
+ rinfo->r_value = (*rel->sym_ptr_ptr)->udata.i;
+ }
+ break;
+ case BFD_RELOC_MACH_O_SECTDIFF:
+ rinfo->r_scattered = 1;
+ rinfo->r_type = BFD_MACH_O_GENERIC_RELOC_SECTDIFF;
+ rinfo->r_pcrel = 0;
+ rinfo->r_length = rel->howto->size;
+ rinfo->r_extern = 0;
+ rinfo->r_value = rel->addend;
+ break;
+ case BFD_RELOC_MACH_O_LOCAL_SECTDIFF:
+ rinfo->r_scattered = 1;
+ rinfo->r_type = BFD_MACH_O_GENERIC_RELOC_LOCAL_SECTDIFF;
+ rinfo->r_pcrel = 0;
+ rinfo->r_length = rel->howto->size;
+ rinfo->r_extern = 0;
+ rinfo->r_value = rel->addend;
+ break;
+ case BFD_RELOC_MACH_O_PAIR:
+ rinfo->r_address = 0;
+ rinfo->r_scattered = 1;
+ rinfo->r_type = BFD_MACH_O_GENERIC_RELOC_PAIR;
+ rinfo->r_pcrel = 0;
+ rinfo->r_length = rel->howto->size;
+ rinfo->r_extern = 0;
+ rinfo->r_value = rel->addend;
+ break;
+ default:
+ return FALSE;
+ }
+ return TRUE;
+}
+
+static reloc_howto_type *
+bfd_mach_o_i386_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ bfd_reloc_code_real_type code)
+{
+ unsigned int i;
+
+ for (i = 0; i < sizeof (i386_howto_table) / sizeof (*i386_howto_table); i++)
+ if (code == i386_howto_table[i].type)
+ return &i386_howto_table[i];
+ return NULL;
+}
+
+static reloc_howto_type *
+bfd_mach_o_i386_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ const char *name ATTRIBUTE_UNUSED)
+{
+ return NULL;
+}
+
+static bfd_boolean
+bfd_mach_o_i386_print_thread (bfd *abfd, bfd_mach_o_thread_flavour *thread,
+ void *vfile, char *buf)
+{
+ FILE *file = (FILE *)vfile;
+
+ switch (thread->flavour)
+ {
+ case BFD_MACH_O_x86_THREAD_STATE:
+ if (thread->size < (8 + 16 * 4))
+ return FALSE;
+ fprintf (file, " x86_THREAD_STATE:\n");
+ fprintf (file, " flavor: 0x%08lx count: 0x%08lx\n",
+ (unsigned long)bfd_get_32 (abfd, buf + 0),
+ (unsigned long)bfd_get_32 (abfd, buf + 4));
+ fprintf (file, " eax: %08lx ebx: %08lx ecx: %08lx edx: %08lx\n",
+ (unsigned long)bfd_get_32 (abfd, buf + 8),
+ (unsigned long)bfd_get_32 (abfd, buf + 12),
+ (unsigned long)bfd_get_32 (abfd, buf + 16),
+ (unsigned long)bfd_get_32 (abfd, buf + 20));
+ fprintf (file, " edi: %08lx esi: %08lx ebp: %08lx esp: %08lx\n",
+ (unsigned long)bfd_get_32 (abfd, buf + 24),
+ (unsigned long)bfd_get_32 (abfd, buf + 28),
+ (unsigned long)bfd_get_32 (abfd, buf + 32),
+ (unsigned long)bfd_get_32 (abfd, buf + 36));
+ fprintf (file, " ss: %08lx flg: %08lx eip: %08lx cs: %08lx\n",
+ (unsigned long)bfd_get_32 (abfd, buf + 40),
+ (unsigned long)bfd_get_32 (abfd, buf + 44),
+ (unsigned long)bfd_get_32 (abfd, buf + 48),
+ (unsigned long)bfd_get_32 (abfd, buf + 52));
+ fprintf (file, " ds: %08lx es: %08lx fs: %08lx gs: %08lx\n",
+ (unsigned long)bfd_get_32 (abfd, buf + 56),
+ (unsigned long)bfd_get_32 (abfd, buf + 60),
+ (unsigned long)bfd_get_32 (abfd, buf + 64),
+ (unsigned long)bfd_get_32 (abfd, buf + 68));
+ return TRUE;
+ case BFD_MACH_O_x86_FLOAT_STATE:
+ if (thread->size < 8)
+ return FALSE;
+ fprintf (file, " x86_FLOAT_STATE:\n");
+ fprintf (file, " flavor: 0x%08lx count: 0x%08lx\n",
+ (unsigned long)bfd_get_32 (abfd, buf + 0),
+ (unsigned long)bfd_get_32 (abfd, buf + 4));
+ return TRUE;
+ case BFD_MACH_O_x86_EXCEPTION_STATE:
+ if (thread->size < 8 + 3 * 4)
+ return FALSE;
+ fprintf (file, " x86_EXCEPTION_STATE:\n");
+ fprintf (file, " flavor: 0x%08lx count: 0x%08lx\n",
+ (unsigned long)bfd_get_32 (abfd, buf + 0),
+ (unsigned long)bfd_get_32 (abfd, buf + 4));
+ fprintf (file, " trapno: %08lx err: %08lx faultaddr: %08lx\n",
+ (unsigned long)bfd_get_32 (abfd, buf + 8),
+ (unsigned long)bfd_get_32 (abfd, buf + 12),
+ (unsigned long)bfd_get_32 (abfd, buf + 16));
+ return TRUE;
+ default:
+ break;
+ }
+ return FALSE;
+}
+
+static const mach_o_section_name_xlat text_section_names_xlat[] =
+ {
+ { ".symbol_stub", "__symbol_stub",
+ SEC_CODE | SEC_LOAD, BFD_MACH_O_S_SYMBOL_STUBS,
+ BFD_MACH_O_S_ATTR_PURE_INSTRUCTIONS,
+ 0},
+ { ".picsymbol_stub", "__picsymbol_stub",
+ SEC_CODE | SEC_LOAD, BFD_MACH_O_S_SYMBOL_STUBS,
+ BFD_MACH_O_S_ATTR_PURE_INSTRUCTIONS,
+ 0},
+ { NULL, NULL, 0, 0, 0, 0}
+ };
+
+static const mach_o_section_name_xlat data_section_names_xlat[] =
+ {
+ /* The first two are recognized by i386, but not emitted for x86 by
+ modern GCC. */
+ { ".non_lazy_symbol_pointer", "__nl_symbol_ptr",
+ SEC_DATA | SEC_LOAD, BFD_MACH_O_S_NON_LAZY_SYMBOL_POINTERS,
+ BFD_MACH_O_S_ATTR_NONE, 2},
+ { ".lazy_symbol_pointer", "__la_symbol_ptr",
+ SEC_DATA | SEC_LOAD, BFD_MACH_O_S_LAZY_SYMBOL_POINTERS,
+ BFD_MACH_O_S_ATTR_NONE, 2},
+ { ".lazy_symbol_pointer2", "__la_sym_ptr2",
+ SEC_DATA | SEC_LOAD, BFD_MACH_O_S_LAZY_SYMBOL_POINTERS,
+ BFD_MACH_O_S_ATTR_NONE, 2},
+ { ".lazy_symbol_pointer3", "__la_sym_ptr3",
+ SEC_DATA | SEC_LOAD, BFD_MACH_O_S_LAZY_SYMBOL_POINTERS,
+ BFD_MACH_O_S_ATTR_NONE, 2},
+ { NULL, NULL, 0, 0, 0, 0}
+ };
+
+static const mach_o_section_name_xlat import_section_names_xlat[] =
+ {
+ { ".picsymbol_stub3", "__jump_table",
+ SEC_CODE | SEC_LOAD, BFD_MACH_O_S_SYMBOL_STUBS,
+ BFD_MACH_O_S_ATTR_PURE_INSTRUCTIONS
+ | BFD_MACH_O_S_SELF_MODIFYING_CODE,
+ 6},
+ { ".non_lazy_symbol_pointer_x86", "__pointers",
+ SEC_DATA | SEC_LOAD, BFD_MACH_O_S_NON_LAZY_SYMBOL_POINTERS,
+ BFD_MACH_O_S_ATTR_NONE, 2},
+ { NULL, NULL, 0, 0, 0, 0}
+ };
+
+const mach_o_segment_name_xlat mach_o_i386_segsec_names_xlat[] =
+ {
+ { "__TEXT", text_section_names_xlat },
+ { "__DATA", data_section_names_xlat },
+ { "__IMPORT", import_section_names_xlat },
+ { NULL, NULL }
+ };
+
+#define bfd_mach_o_swap_reloc_in bfd_mach_o_i386_swap_reloc_in
+#define bfd_mach_o_swap_reloc_out bfd_mach_o_i386_swap_reloc_out
+#define bfd_mach_o_print_thread bfd_mach_o_i386_print_thread
+
+#define bfd_mach_o_tgt_seg_table mach_o_i386_segsec_names_xlat
+#define bfd_mach_o_section_type_valid_for_tgt NULL
+
+#define bfd_mach_o_bfd_reloc_type_lookup bfd_mach_o_i386_bfd_reloc_type_lookup
+#define bfd_mach_o_bfd_reloc_name_lookup bfd_mach_o_i386_bfd_reloc_name_lookup
+
+#define TARGET_NAME i386_mach_o_vec
+#define TARGET_STRING "mach-o-i386"
+#define TARGET_ARCHITECTURE bfd_arch_i386
+#define TARGET_PAGESIZE 4096
+#define TARGET_BIG_ENDIAN 0
+#define TARGET_ARCHIVE 0
+#define TARGET_PRIORITY 0
+#include "mach-o-target.c"
diff --git a/bfd/mach-o-target.c b/bfd/mach-o-target.c
new file mode 100644
index 0000000..a070e67
--- /dev/null
+++ b/bfd/mach-o-target.c
@@ -0,0 +1,189 @@
+/* Mach-O support for BFD.
+ Copyright (C) 1999-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+/* Define generic entry points here so that we don't need to duplicate the
+ defines in every target. But define once as this file may be included
+ several times. */
+#ifndef MACH_O_TARGET_COMMON_DEFINED
+#define MACH_O_TARGET_COMMON_DEFINED
+
+#define bfd_mach_o_bfd_free_cached_info _bfd_generic_bfd_free_cached_info
+#define bfd_mach_o_get_section_contents_in_window _bfd_generic_get_section_contents_in_window
+#define bfd_mach_o_bfd_print_private_bfd_data _bfd_generic_bfd_print_private_bfd_data
+#define bfd_mach_o_bfd_is_target_special_symbol ((bfd_boolean (*) (bfd *, asymbol *)) bfd_false)
+#define bfd_mach_o_bfd_is_local_label_name bfd_generic_is_local_label_name
+#define bfd_mach_o_get_lineno _bfd_nosymbols_get_lineno
+#define bfd_mach_o_find_inliner_info _bfd_nosymbols_find_inliner_info
+#define bfd_mach_o_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol
+#define bfd_mach_o_read_minisymbols _bfd_generic_read_minisymbols
+#define bfd_mach_o_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol
+#define bfd_mach_o_bfd_get_relocated_section_contents bfd_generic_get_relocated_section_contents
+#define bfd_mach_o_bfd_relax_section bfd_generic_relax_section
+#define bfd_mach_o_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
+#define bfd_mach_o_bfd_link_add_symbols _bfd_generic_link_add_symbols
+#define bfd_mach_o_bfd_link_just_syms _bfd_generic_link_just_syms
+#define bfd_mach_o_bfd_copy_link_hash_symbol_type \
+ _bfd_generic_copy_link_hash_symbol_type
+#define bfd_mach_o_bfd_final_link _bfd_generic_final_link
+#define bfd_mach_o_bfd_link_split_section _bfd_generic_link_split_section
+#define bfd_mach_o_bfd_merge_private_bfd_data _bfd_generic_bfd_merge_private_bfd_data
+#define bfd_mach_o_bfd_set_private_flags bfd_mach_o_bfd_set_private_flags
+#define bfd_mach_o_get_section_contents _bfd_generic_get_section_contents
+#define bfd_mach_o_bfd_gc_sections bfd_generic_gc_sections
+#define bfd_mach_o_bfd_lookup_section_flags bfd_generic_lookup_section_flags
+#define bfd_mach_o_bfd_merge_sections bfd_generic_merge_sections
+#define bfd_mach_o_bfd_is_group_section bfd_generic_is_group_section
+#define bfd_mach_o_bfd_discard_group bfd_generic_discard_group
+#define bfd_mach_o_section_already_linked _bfd_generic_section_already_linked
+#define bfd_mach_o_bfd_define_common_symbol bfd_generic_define_common_symbol
+#define bfd_mach_o_bfd_copy_private_bfd_data _bfd_generic_bfd_copy_private_bfd_data
+#define bfd_mach_o_core_file_matches_executable_p generic_core_file_matches_executable_p
+#define bfd_mach_o_core_file_pid _bfd_nocore_core_file_pid
+
+#define bfd_mach_o_get_dynamic_symtab_upper_bound bfd_mach_o_get_symtab_upper_bound
+#define bfd_mach_o_canonicalize_dynamic_symtab bfd_mach_o_canonicalize_symtab
+
+#define TARGET_NAME_BACKEND XCONCAT2(TARGET_NAME,_backend)
+
+#endif /* MACH_O_TARGET_COMMON_DEFINED */
+
+#ifndef TARGET_NAME
+#error TARGET_NAME must be defined
+#endif /* TARGET_NAME */
+
+#ifndef TARGET_STRING
+#error TARGET_STRING must be defined
+#endif /* TARGET_STRING */
+
+#ifndef TARGET_ARCHITECTURE
+#error TARGET_ARCHITECTURE must be defined
+#endif /* TARGET_ARCHITECTURE */
+
+#ifndef TARGET_BIG_ENDIAN
+#error TARGET_BIG_ENDIAN must be defined
+#endif /* TARGET_BIG_ENDIAN */
+
+#ifndef TARGET_ARCHIVE
+#error TARGET_ARCHIVE must be defined
+#endif /* TARGET_ARCHIVE */
+
+#ifndef TARGET_PAGESIZE
+#error TARGET_PAGESIZE must be defined
+#endif
+
+#if ((TARGET_ARCHIVE) && (! TARGET_BIG_ENDIAN))
+#error Mach-O fat files must always be big-endian.
+#endif /* ((TARGET_ARCHIVE) && (! TARGET_BIG_ENDIAN)) */
+
+static const bfd_mach_o_backend_data TARGET_NAME_BACKEND =
+{
+ TARGET_ARCHITECTURE,
+ TARGET_PAGESIZE,
+ bfd_mach_o_swap_reloc_in,
+ bfd_mach_o_swap_reloc_out,
+ bfd_mach_o_print_thread,
+ bfd_mach_o_tgt_seg_table,
+ bfd_mach_o_section_type_valid_for_tgt
+};
+
+const bfd_target TARGET_NAME =
+{
+ TARGET_STRING, /* Name. */
+ bfd_target_mach_o_flavour,
+#if TARGET_BIG_ENDIAN
+ BFD_ENDIAN_BIG, /* Target byte order. */
+ BFD_ENDIAN_BIG, /* Target headers byte order. */
+#else
+ BFD_ENDIAN_LITTLE, /* Target byte order. */
+ BFD_ENDIAN_LITTLE, /* Target headers byte order. */
+#endif
+ (HAS_RELOC | EXEC_P | /* Object flags. */
+ HAS_LINENO | HAS_DEBUG |
+ HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED),
+ (SEC_CODE | SEC_DATA | SEC_ROM | SEC_HAS_CONTENTS
+ | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* Section flags. */
+ '_', /* symbol_leading_char. */
+ ' ', /* ar_pad_char. */
+ 16, /* ar_max_namelen. */
+ TARGET_PRIORITY, /* match priority. */
+
+#if TARGET_BIG_ENDIAN
+ 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 /* TARGET_BIG_ENDIAN */
+
+ { /* bfd_check_format. */
+#if TARGET_ARCHIVE
+ _bfd_dummy_target,
+ _bfd_dummy_target,
+ bfd_mach_o_archive_p,
+ _bfd_dummy_target,
+#else
+ _bfd_dummy_target,
+ bfd_mach_o_object_p,
+ bfd_generic_archive_p,
+ bfd_mach_o_core_p
+#endif
+ },
+ { /* bfd_set_format. */
+ bfd_false,
+ bfd_mach_o_mkobject,
+ _bfd_generic_mkarchive,
+ bfd_mach_o_mkobject,
+ },
+ { /* bfd_write_contents. */
+ bfd_false,
+ bfd_mach_o_write_contents,
+ _bfd_write_archive_contents,
+ bfd_mach_o_write_contents,
+ },
+
+ BFD_JUMP_TABLE_GENERIC (bfd_mach_o),
+ BFD_JUMP_TABLE_COPY (bfd_mach_o),
+ BFD_JUMP_TABLE_CORE (bfd_mach_o),
+#if TARGET_ARCHIVE
+ BFD_JUMP_TABLE_ARCHIVE (bfd_mach_o),
+#else
+ BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_bsd44),
+#endif
+ BFD_JUMP_TABLE_SYMBOLS (bfd_mach_o),
+ BFD_JUMP_TABLE_RELOCS (bfd_mach_o),
+ BFD_JUMP_TABLE_WRITE (bfd_mach_o),
+ BFD_JUMP_TABLE_LINK (bfd_mach_o),
+ BFD_JUMP_TABLE_DYNAMIC (bfd_mach_o),
+
+ /* Alternative endian target. */
+ NULL,
+
+ /* Back-end data. */
+ &TARGET_NAME_BACKEND
+};
+
diff --git a/bfd/mach-o-x86-64.c b/bfd/mach-o-x86-64.c
new file mode 100644
index 0000000..c0042cb
--- /dev/null
+++ b/bfd/mach-o-x86-64.c
@@ -0,0 +1,363 @@
+/* Intel x86-64 Mach-O support for BFD.
+ Copyright (C) 2010-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "mach-o.h"
+#include "bfd.h"
+#include "libbfd.h"
+#include "libiberty.h"
+#include "mach-o/x86-64.h"
+
+#define bfd_mach_o_object_p bfd_mach_o_x86_64_object_p
+#define bfd_mach_o_core_p bfd_mach_o_x86_64_core_p
+#define bfd_mach_o_mkobject bfd_mach_o_x86_64_mkobject
+
+static const bfd_target *
+bfd_mach_o_x86_64_object_p (bfd *abfd)
+{
+ return bfd_mach_o_header_p (abfd, 0, BFD_MACH_O_CPU_TYPE_X86_64);
+}
+
+static const bfd_target *
+bfd_mach_o_x86_64_core_p (bfd *abfd)
+{
+ return bfd_mach_o_header_p (abfd,
+ BFD_MACH_O_MH_CORE, BFD_MACH_O_CPU_TYPE_X86_64);
+}
+
+static bfd_boolean
+bfd_mach_o_x86_64_mkobject (bfd *abfd)
+{
+ bfd_mach_o_data_struct *mdata;
+
+ if (!bfd_mach_o_mkobject_init (abfd))
+ return FALSE;
+
+ mdata = bfd_mach_o_get_data (abfd);
+ mdata->header.magic = BFD_MACH_O_MH_MAGIC_64;
+ mdata->header.cputype = BFD_MACH_O_CPU_TYPE_X86_64;
+ mdata->header.cpusubtype =
+ BFD_MACH_O_CPU_SUBTYPE_X86_ALL | BFD_MACH_O_CPU_SUBTYPE_LIB64;
+ mdata->header.byteorder = BFD_ENDIAN_LITTLE;
+ mdata->header.version = 2;
+
+ return TRUE;
+}
+
+/* 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 x86_64_howto_table[]=
+{
+ /* 0 */
+ HOWTO(BFD_RELOC_64, 0, 4, 64, FALSE, 0,
+ complain_overflow_bitfield,
+ NULL, "64",
+ FALSE, MINUS_ONE, MINUS_ONE, FALSE),
+ HOWTO(BFD_RELOC_32, 0, 2, 32, FALSE, 0,
+ complain_overflow_bitfield,
+ NULL, "32",
+ FALSE, 0xffffffff, 0xffffffff, FALSE),
+ HOWTO(BFD_RELOC_32_PCREL, 0, 2, 32, TRUE, 0,
+ complain_overflow_bitfield,
+ NULL, "DISP32",
+ FALSE, 0xffffffff, 0xffffffff, TRUE),
+ HOWTO(BFD_RELOC_MACH_O_X86_64_PCREL32_1, 0, 2, 32, TRUE, 0,
+ complain_overflow_bitfield,
+ NULL, "DISP32_1",
+ FALSE, 0xffffffff, 0xffffffff, TRUE),
+ /* 4 */
+ HOWTO(BFD_RELOC_MACH_O_X86_64_PCREL32_2, 0, 2, 32, TRUE, 0,
+ complain_overflow_bitfield,
+ NULL, "DISP32_2",
+ FALSE, 0xffffffff, 0xffffffff, TRUE),
+ HOWTO(BFD_RELOC_MACH_O_X86_64_PCREL32_4, 0, 2, 32, TRUE, 0,
+ complain_overflow_bitfield,
+ NULL, "DISP32_4",
+ FALSE, 0xffffffff, 0xffffffff, TRUE),
+ HOWTO(BFD_RELOC_MACH_O_X86_64_BRANCH32, 0, 2, 32, TRUE, 0,
+ complain_overflow_bitfield,
+ NULL, "BRANCH32",
+ FALSE, 0xffffffff, 0xffffffff, TRUE),
+ HOWTO(BFD_RELOC_MACH_O_X86_64_GOT_LOAD, 0, 2, 32, TRUE, 0,
+ complain_overflow_bitfield,
+ NULL, "GOT_LOAD",
+ FALSE, 0xffffffff, 0xffffffff, TRUE),
+ /* 8 */
+ HOWTO(BFD_RELOC_MACH_O_X86_64_SUBTRACTOR32, 0, 2, 32, FALSE, 0,
+ complain_overflow_bitfield,
+ NULL, "SUBTRACTOR32",
+ FALSE, 0xffffffff, 0xffffffff, FALSE),
+ HOWTO(BFD_RELOC_MACH_O_X86_64_SUBTRACTOR64, 0, 4, 64, FALSE, 0,
+ complain_overflow_bitfield,
+ NULL, "SUBTRACTOR64",
+ FALSE, MINUS_ONE, MINUS_ONE, FALSE),
+ HOWTO(BFD_RELOC_MACH_O_X86_64_GOT, 0, 2, 32, TRUE, 0,
+ complain_overflow_bitfield,
+ NULL, "GOT",
+ FALSE, 0xffffffff, 0xffffffff, TRUE),
+ HOWTO(BFD_RELOC_MACH_O_X86_64_BRANCH8, 0, 0, 8, TRUE, 0,
+ complain_overflow_bitfield,
+ NULL, "BRANCH8",
+ FALSE, 0xff, 0xff, TRUE),
+};
+
+static bfd_boolean
+bfd_mach_o_x86_64_swap_reloc_in (arelent *res, bfd_mach_o_reloc_info *reloc)
+{
+ /* On x86-64, scattered relocs are not used. */
+ if (reloc->r_scattered)
+ return FALSE;
+
+ switch (reloc->r_type)
+ {
+ case BFD_MACH_O_X86_64_RELOC_UNSIGNED:
+ if (reloc->r_pcrel)
+ return FALSE;
+ switch (reloc->r_length)
+ {
+ case 2:
+ res->howto = &x86_64_howto_table[1];
+ return TRUE;
+ case 3:
+ res->howto = &x86_64_howto_table[0];
+ return TRUE;
+ default:
+ return FALSE;
+ }
+ case BFD_MACH_O_X86_64_RELOC_SIGNED:
+ if (reloc->r_length == 2 && reloc->r_pcrel)
+ {
+ res->howto = &x86_64_howto_table[2];
+ return TRUE;
+ }
+ break;
+ case BFD_MACH_O_X86_64_RELOC_BRANCH:
+ if (!reloc->r_pcrel)
+ return FALSE;
+ switch (reloc->r_length)
+ {
+ case 2:
+ res->howto = &x86_64_howto_table[6];
+ return TRUE;
+ default:
+ return FALSE;
+ }
+ break;
+ case BFD_MACH_O_X86_64_RELOC_GOT_LOAD:
+ if (reloc->r_length == 2 && reloc->r_pcrel && reloc->r_extern)
+ {
+ res->howto = &x86_64_howto_table[7];
+ return TRUE;
+ }
+ break;
+ case BFD_MACH_O_X86_64_RELOC_GOT:
+ if (reloc->r_length == 2 && reloc->r_pcrel && reloc->r_extern)
+ {
+ res->howto = &x86_64_howto_table[10];
+ return TRUE;
+ }
+ break;
+ case BFD_MACH_O_X86_64_RELOC_SUBTRACTOR:
+ if (reloc->r_pcrel)
+ return FALSE;
+ switch (reloc->r_length)
+ {
+ case 2:
+ res->howto = &x86_64_howto_table[8];
+ return TRUE;
+ case 3:
+ res->howto = &x86_64_howto_table[9];
+ return TRUE;
+ default:
+ return FALSE;
+ }
+ break;
+ case BFD_MACH_O_X86_64_RELOC_SIGNED_1:
+ if (reloc->r_length == 2 && reloc->r_pcrel)
+ {
+ res->howto = &x86_64_howto_table[3];
+ return TRUE;
+ }
+ break;
+ case BFD_MACH_O_X86_64_RELOC_SIGNED_2:
+ if (reloc->r_length == 2 && reloc->r_pcrel)
+ {
+ res->howto = &x86_64_howto_table[4];
+ return TRUE;
+ }
+ break;
+ case BFD_MACH_O_X86_64_RELOC_SIGNED_4:
+ if (reloc->r_length == 2 && reloc->r_pcrel)
+ {
+ res->howto = &x86_64_howto_table[5];
+ return TRUE;
+ }
+ break;
+ default:
+ return FALSE;
+ }
+ return FALSE;
+}
+
+static bfd_boolean
+bfd_mach_o_x86_64_swap_reloc_out (arelent *rel, bfd_mach_o_reloc_info *rinfo)
+{
+ rinfo->r_address = rel->address;
+ rinfo->r_scattered = 0;
+ switch (rel->howto->type)
+ {
+ case BFD_RELOC_32:
+ rinfo->r_type = BFD_MACH_O_X86_64_RELOC_UNSIGNED;
+ rinfo->r_pcrel = 0;
+ rinfo->r_length = 2;
+ break;
+ case BFD_RELOC_64:
+ rinfo->r_type = BFD_MACH_O_X86_64_RELOC_UNSIGNED;
+ rinfo->r_pcrel = 0;
+ rinfo->r_length = 3;
+ break;
+ case BFD_RELOC_32_PCREL:
+ rinfo->r_type = BFD_MACH_O_X86_64_RELOC_SIGNED;
+ rinfo->r_pcrel = 1;
+ rinfo->r_length = 2;
+ break;
+ case BFD_RELOC_MACH_O_X86_64_PCREL32_1:
+ rinfo->r_type = BFD_MACH_O_X86_64_RELOC_SIGNED_1;
+ rinfo->r_pcrel = 1;
+ rinfo->r_length = 2;
+ break;
+ case BFD_RELOC_MACH_O_X86_64_PCREL32_2:
+ rinfo->r_type = BFD_MACH_O_X86_64_RELOC_SIGNED_2;
+ rinfo->r_pcrel = 1;
+ rinfo->r_length = 2;
+ break;
+ case BFD_RELOC_MACH_O_X86_64_PCREL32_4:
+ rinfo->r_type = BFD_MACH_O_X86_64_RELOC_SIGNED_4;
+ rinfo->r_pcrel = 1;
+ rinfo->r_length = 2;
+ break;
+ case BFD_RELOC_MACH_O_X86_64_BRANCH32:
+ rinfo->r_type = BFD_MACH_O_X86_64_RELOC_BRANCH;
+ rinfo->r_pcrel = 1;
+ rinfo->r_length = 2;
+ break;
+ case BFD_RELOC_MACH_O_X86_64_SUBTRACTOR32:
+ rinfo->r_type = BFD_MACH_O_X86_64_RELOC_SUBTRACTOR;
+ rinfo->r_pcrel = 0;
+ rinfo->r_length = 2;
+ break;
+ case BFD_RELOC_MACH_O_X86_64_SUBTRACTOR64:
+ rinfo->r_type = BFD_MACH_O_X86_64_RELOC_SUBTRACTOR;
+ rinfo->r_pcrel = 0;
+ rinfo->r_length = 3;
+ break;
+ case BFD_RELOC_MACH_O_X86_64_GOT:
+ rinfo->r_type = BFD_MACH_O_X86_64_RELOC_GOT;
+ rinfo->r_pcrel = 1;
+ rinfo->r_length = 2;
+ break;
+ case BFD_RELOC_MACH_O_X86_64_GOT_LOAD:
+ rinfo->r_type = BFD_MACH_O_X86_64_RELOC_GOT_LOAD;
+ rinfo->r_pcrel = 1;
+ rinfo->r_length = 2;
+ break;
+ default:
+ return FALSE;
+ }
+ if ((*rel->sym_ptr_ptr)->flags & BSF_SECTION_SYM)
+ {
+ rinfo->r_extern = 0;
+ rinfo->r_value =
+ (*rel->sym_ptr_ptr)->section->output_section->target_index;
+ }
+ else
+ {
+ rinfo->r_extern = 1;
+ rinfo->r_value = (*rel->sym_ptr_ptr)->udata.i;
+ }
+ return TRUE;
+}
+
+static reloc_howto_type *
+bfd_mach_o_x86_64_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ bfd_reloc_code_real_type code)
+{
+ unsigned int i;
+
+ for (i = 0;
+ i < sizeof (x86_64_howto_table) / sizeof (*x86_64_howto_table);
+ i++)
+ if (code == x86_64_howto_table[i].type)
+ return &x86_64_howto_table[i];
+ return NULL;
+}
+
+static reloc_howto_type *
+bfd_mach_o_x86_64_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ const char *name ATTRIBUTE_UNUSED)
+{
+ return NULL;
+}
+
+static bfd_boolean
+bfd_mach_o_section_type_valid_for_x86_64 (unsigned long val)
+{
+ if (val == BFD_MACH_O_S_NON_LAZY_SYMBOL_POINTERS
+ || val == BFD_MACH_O_S_LAZY_SYMBOL_POINTERS
+ || val == BFD_MACH_O_S_SYMBOL_STUBS)
+ return FALSE;
+ return TRUE;
+}
+
+/* We want to bump the alignment of some sections. */
+static const mach_o_section_name_xlat text_section_names_xlat[] =
+ {
+ { ".eh_frame", "__eh_frame",
+ SEC_READONLY | SEC_DATA | SEC_LOAD, BFD_MACH_O_S_COALESCED,
+ BFD_MACH_O_S_ATTR_LIVE_SUPPORT
+ | BFD_MACH_O_S_ATTR_STRIP_STATIC_SYMS
+ | BFD_MACH_O_S_ATTR_NO_TOC, 3},
+ { NULL, NULL, 0, 0, 0, 0}
+ };
+
+const mach_o_segment_name_xlat mach_o_x86_64_segsec_names_xlat[] =
+ {
+ { "__TEXT", text_section_names_xlat },
+ { NULL, NULL }
+ };
+
+#define bfd_mach_o_swap_reloc_in bfd_mach_o_x86_64_swap_reloc_in
+#define bfd_mach_o_swap_reloc_out bfd_mach_o_x86_64_swap_reloc_out
+
+#define bfd_mach_o_bfd_reloc_type_lookup bfd_mach_o_x86_64_bfd_reloc_type_lookup
+#define bfd_mach_o_bfd_reloc_name_lookup bfd_mach_o_x86_64_bfd_reloc_name_lookup
+#define bfd_mach_o_print_thread NULL
+#define bfd_mach_o_tgt_seg_table mach_o_x86_64_segsec_names_xlat
+#define bfd_mach_o_section_type_valid_for_tgt bfd_mach_o_section_type_valid_for_x86_64
+
+#define TARGET_NAME x86_64_mach_o_vec
+#define TARGET_STRING "mach-o-x86-64"
+#define TARGET_ARCHITECTURE bfd_arch_i386
+#define TARGET_PAGESIZE 4096
+#define TARGET_BIG_ENDIAN 0
+#define TARGET_ARCHIVE 0
+#define TARGET_PRIORITY 0
+#include "mach-o-target.c"
diff --git a/bfd/mach-o.c b/bfd/mach-o.c
new file mode 100644
index 0000000..3952689
--- /dev/null
+++ b/bfd/mach-o.c
@@ -0,0 +1,5797 @@
+/* Mach-O support for BFD.
+ Copyright (C) 1999-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "mach-o.h"
+#include "bfd.h"
+#include "libbfd.h"
+#include "libiberty.h"
+#include "aout/stab_gnu.h"
+#include "mach-o/reloc.h"
+#include "mach-o/external.h"
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define bfd_mach_o_object_p bfd_mach_o_gen_object_p
+#define bfd_mach_o_core_p bfd_mach_o_gen_core_p
+#define bfd_mach_o_mkobject bfd_mach_o_gen_mkobject
+
+#define FILE_ALIGN(off, algn) \
+ (((off) + ((file_ptr) 1 << (algn)) - 1) & ((file_ptr) -1 << (algn)))
+
+static bfd_boolean
+bfd_mach_o_read_dyld_content (bfd *abfd, bfd_mach_o_dyld_info_command *cmd);
+
+unsigned int
+bfd_mach_o_version (bfd *abfd)
+{
+ bfd_mach_o_data_struct *mdata = NULL;
+
+ BFD_ASSERT (bfd_mach_o_valid (abfd));
+ mdata = bfd_mach_o_get_data (abfd);
+
+ return mdata->header.version;
+}
+
+bfd_boolean
+bfd_mach_o_valid (bfd *abfd)
+{
+ if (abfd == NULL || abfd->xvec == NULL)
+ return FALSE;
+
+ if (abfd->xvec->flavour != bfd_target_mach_o_flavour)
+ return FALSE;
+
+ if (bfd_mach_o_get_data (abfd) == NULL)
+ return FALSE;
+ return TRUE;
+}
+
+static INLINE bfd_boolean
+mach_o_wide_p (bfd_mach_o_header *header)
+{
+ switch (header->version)
+ {
+ case 1:
+ return FALSE;
+ case 2:
+ return TRUE;
+ default:
+ BFD_FAIL ();
+ return FALSE;
+ }
+}
+
+static INLINE bfd_boolean
+bfd_mach_o_wide_p (bfd *abfd)
+{
+ return mach_o_wide_p (&bfd_mach_o_get_data (abfd)->header);
+}
+
+/* Tables to translate well known Mach-O segment/section names to bfd
+ names. Use of canonical names (such as .text or .debug_frame) is required
+ by gdb. */
+
+/* __TEXT Segment. */
+static const mach_o_section_name_xlat text_section_names_xlat[] =
+ {
+ { ".text", "__text",
+ SEC_CODE | SEC_LOAD, BFD_MACH_O_S_REGULAR,
+ BFD_MACH_O_S_ATTR_PURE_INSTRUCTIONS, 0},
+ { ".const", "__const",
+ SEC_READONLY | SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
+ BFD_MACH_O_S_ATTR_NONE, 0},
+ { ".static_const", "__static_const",
+ SEC_READONLY | SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
+ BFD_MACH_O_S_ATTR_NONE, 0},
+ { ".cstring", "__cstring",
+ SEC_READONLY | SEC_DATA | SEC_LOAD | SEC_MERGE | SEC_STRINGS,
+ BFD_MACH_O_S_CSTRING_LITERALS,
+ BFD_MACH_O_S_ATTR_NONE, 0},
+ { ".literal4", "__literal4",
+ SEC_READONLY | SEC_DATA | SEC_LOAD, BFD_MACH_O_S_4BYTE_LITERALS,
+ BFD_MACH_O_S_ATTR_NONE, 2},
+ { ".literal8", "__literal8",
+ SEC_READONLY | SEC_DATA | SEC_LOAD, BFD_MACH_O_S_8BYTE_LITERALS,
+ BFD_MACH_O_S_ATTR_NONE, 3},
+ { ".literal16", "__literal16",
+ SEC_READONLY | SEC_DATA | SEC_LOAD, BFD_MACH_O_S_16BYTE_LITERALS,
+ BFD_MACH_O_S_ATTR_NONE, 4},
+ { ".constructor", "__constructor",
+ SEC_CODE | SEC_LOAD, BFD_MACH_O_S_REGULAR,
+ BFD_MACH_O_S_ATTR_NONE, 0},
+ { ".destructor", "__destructor",
+ SEC_CODE | SEC_LOAD, BFD_MACH_O_S_REGULAR,
+ BFD_MACH_O_S_ATTR_NONE, 0},
+ { ".eh_frame", "__eh_frame",
+ SEC_READONLY | SEC_DATA | SEC_LOAD, BFD_MACH_O_S_COALESCED,
+ BFD_MACH_O_S_ATTR_LIVE_SUPPORT
+ | BFD_MACH_O_S_ATTR_STRIP_STATIC_SYMS
+ | BFD_MACH_O_S_ATTR_NO_TOC, 2},
+ { NULL, NULL, 0, 0, 0, 0}
+ };
+
+/* __DATA Segment. */
+static const mach_o_section_name_xlat data_section_names_xlat[] =
+ {
+ { ".data", "__data",
+ SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
+ BFD_MACH_O_S_ATTR_NONE, 0},
+ { ".bss", "__bss",
+ SEC_NO_FLAGS, BFD_MACH_O_S_ZEROFILL,
+ BFD_MACH_O_S_ATTR_NONE, 0},
+ { ".const_data", "__const",
+ SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
+ BFD_MACH_O_S_ATTR_NONE, 0},
+ { ".static_data", "__static_data",
+ SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
+ BFD_MACH_O_S_ATTR_NONE, 0},
+ { ".mod_init_func", "__mod_init_func",
+ SEC_DATA | SEC_LOAD, BFD_MACH_O_S_MOD_INIT_FUNC_POINTERS,
+ BFD_MACH_O_S_ATTR_NONE, 2},
+ { ".mod_term_func", "__mod_term_func",
+ SEC_DATA | SEC_LOAD, BFD_MACH_O_S_MOD_FINI_FUNC_POINTERS,
+ BFD_MACH_O_S_ATTR_NONE, 2},
+ { ".dyld", "__dyld",
+ SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
+ BFD_MACH_O_S_ATTR_NONE, 0},
+ { ".cfstring", "__cfstring",
+ SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
+ BFD_MACH_O_S_ATTR_NONE, 2},
+ { NULL, NULL, 0, 0, 0, 0}
+ };
+
+/* __DWARF Segment. */
+static const mach_o_section_name_xlat dwarf_section_names_xlat[] =
+ {
+ { ".debug_frame", "__debug_frame",
+ SEC_DEBUGGING, BFD_MACH_O_S_REGULAR,
+ BFD_MACH_O_S_ATTR_DEBUG, 0},
+ { ".debug_info", "__debug_info",
+ SEC_DEBUGGING, BFD_MACH_O_S_REGULAR,
+ BFD_MACH_O_S_ATTR_DEBUG, 0},
+ { ".debug_abbrev", "__debug_abbrev",
+ SEC_DEBUGGING, BFD_MACH_O_S_REGULAR,
+ BFD_MACH_O_S_ATTR_DEBUG, 0},
+ { ".debug_aranges", "__debug_aranges",
+ SEC_DEBUGGING, BFD_MACH_O_S_REGULAR,
+ BFD_MACH_O_S_ATTR_DEBUG, 0},
+ { ".debug_macinfo", "__debug_macinfo",
+ SEC_DEBUGGING, BFD_MACH_O_S_REGULAR,
+ BFD_MACH_O_S_ATTR_DEBUG, 0},
+ { ".debug_line", "__debug_line",
+ SEC_DEBUGGING, BFD_MACH_O_S_REGULAR,
+ BFD_MACH_O_S_ATTR_DEBUG, 0},
+ { ".debug_loc", "__debug_loc",
+ SEC_DEBUGGING, BFD_MACH_O_S_REGULAR,
+ BFD_MACH_O_S_ATTR_DEBUG, 0},
+ { ".debug_pubnames", "__debug_pubnames",
+ SEC_DEBUGGING, BFD_MACH_O_S_REGULAR,
+ BFD_MACH_O_S_ATTR_DEBUG, 0},
+ { ".debug_pubtypes", "__debug_pubtypes",
+ SEC_DEBUGGING, BFD_MACH_O_S_REGULAR,
+ BFD_MACH_O_S_ATTR_DEBUG, 0},
+ { ".debug_str", "__debug_str",
+ SEC_DEBUGGING, BFD_MACH_O_S_REGULAR,
+ BFD_MACH_O_S_ATTR_DEBUG, 0},
+ { ".debug_ranges", "__debug_ranges",
+ SEC_DEBUGGING, BFD_MACH_O_S_REGULAR,
+ BFD_MACH_O_S_ATTR_DEBUG, 0},
+ { ".debug_macro", "__debug_macro",
+ SEC_DEBUGGING, BFD_MACH_O_S_REGULAR,
+ BFD_MACH_O_S_ATTR_DEBUG, 0},
+ { ".debug_gdb_scripts", "__debug_gdb_scri",
+ SEC_DEBUGGING, BFD_MACH_O_S_REGULAR,
+ BFD_MACH_O_S_ATTR_DEBUG, 0},
+ { NULL, NULL, 0, 0, 0, 0}
+ };
+
+/* __OBJC Segment. */
+static const mach_o_section_name_xlat objc_section_names_xlat[] =
+ {
+ { ".objc_class", "__class",
+ SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
+ BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0},
+ { ".objc_meta_class", "__meta_class",
+ SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
+ BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0},
+ { ".objc_cat_cls_meth", "__cat_cls_meth",
+ SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
+ BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0},
+ { ".objc_cat_inst_meth", "__cat_inst_meth",
+ SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
+ BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0},
+ { ".objc_protocol", "__protocol",
+ SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
+ BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0},
+ { ".objc_string_object", "__string_object",
+ SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
+ BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0},
+ { ".objc_cls_meth", "__cls_meth",
+ SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
+ BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0},
+ { ".objc_inst_meth", "__inst_meth",
+ SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
+ BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0},
+ { ".objc_cls_refs", "__cls_refs",
+ SEC_DATA | SEC_LOAD, BFD_MACH_O_S_LITERAL_POINTERS,
+ BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0},
+ { ".objc_message_refs", "__message_refs",
+ SEC_DATA | SEC_LOAD, BFD_MACH_O_S_LITERAL_POINTERS,
+ BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0},
+ { ".objc_symbols", "__symbols",
+ SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
+ BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0},
+ { ".objc_category", "__category",
+ SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
+ BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0},
+ { ".objc_class_vars", "__class_vars",
+ SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
+ BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0},
+ { ".objc_instance_vars", "__instance_vars",
+ SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
+ BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0},
+ { ".objc_module_info", "__module_info",
+ SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
+ BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0},
+ { ".objc_selector_strs", "__selector_strs",
+ SEC_DATA | SEC_LOAD, BFD_MACH_O_S_CSTRING_LITERALS,
+ BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0},
+ { ".objc_image_info", "__image_info",
+ SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
+ BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0},
+ { ".objc_selector_fixup", "__sel_fixup",
+ SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
+ BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0},
+ /* Objc V1 */
+ { ".objc1_class_ext", "__class_ext",
+ SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
+ BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0},
+ { ".objc1_property_list", "__property",
+ SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
+ BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0},
+ { ".objc1_protocol_ext", "__protocol_ext",
+ SEC_DATA | SEC_LOAD, BFD_MACH_O_S_REGULAR,
+ BFD_MACH_O_S_ATTR_NO_DEAD_STRIP, 0},
+ { NULL, NULL, 0, 0, 0, 0}
+ };
+
+static const mach_o_segment_name_xlat segsec_names_xlat[] =
+ {
+ { "__TEXT", text_section_names_xlat },
+ { "__DATA", data_section_names_xlat },
+ { "__DWARF", dwarf_section_names_xlat },
+ { "__OBJC", objc_section_names_xlat },
+ { NULL, NULL }
+ };
+
+static const char dsym_subdir[] = ".dSYM/Contents/Resources/DWARF";
+
+/* For both cases bfd-name => mach-o name and vice versa, the specific target
+ is checked before the generic. This allows a target (e.g. ppc for cstring)
+ to override the generic definition with a more specific one. */
+
+/* Fetch the translation from a Mach-O section designation (segment, section)
+ as a bfd short name, if one exists. Otherwise return NULL.
+
+ Allow the segment and section names to be unterminated 16 byte arrays. */
+
+const mach_o_section_name_xlat *
+bfd_mach_o_section_data_for_mach_sect (bfd *abfd, const char *segname,
+ const char *sectname)
+{
+ const struct mach_o_segment_name_xlat *seg;
+ const mach_o_section_name_xlat *sec;
+ bfd_mach_o_backend_data *bed = bfd_mach_o_get_backend_data (abfd);
+
+ /* First try any target-specific translations defined... */
+ if (bed->segsec_names_xlat)
+ for (seg = bed->segsec_names_xlat; seg->segname; seg++)
+ if (strncmp (seg->segname, segname, BFD_MACH_O_SEGNAME_SIZE) == 0)
+ for (sec = seg->sections; sec->mach_o_name; sec++)
+ if (strncmp (sec->mach_o_name, sectname,
+ BFD_MACH_O_SECTNAME_SIZE) == 0)
+ return sec;
+
+ /* ... and then the Mach-O generic ones. */
+ for (seg = segsec_names_xlat; seg->segname; seg++)
+ if (strncmp (seg->segname, segname, BFD_MACH_O_SEGNAME_SIZE) == 0)
+ for (sec = seg->sections; sec->mach_o_name; sec++)
+ if (strncmp (sec->mach_o_name, sectname,
+ BFD_MACH_O_SECTNAME_SIZE) == 0)
+ return sec;
+
+ return NULL;
+}
+
+/* If the bfd_name for this section is a 'canonical' form for which we
+ know the Mach-O data, return the segment name and the data for the
+ Mach-O equivalent. Otherwise return NULL. */
+
+const mach_o_section_name_xlat *
+bfd_mach_o_section_data_for_bfd_name (bfd *abfd, const char *bfd_name,
+ const char **segname)
+{
+ const struct mach_o_segment_name_xlat *seg;
+ const mach_o_section_name_xlat *sec;
+ bfd_mach_o_backend_data *bed = bfd_mach_o_get_backend_data (abfd);
+ *segname = NULL;
+
+ if (bfd_name[0] != '.')
+ return NULL;
+
+ /* First try any target-specific translations defined... */
+ if (bed->segsec_names_xlat)
+ for (seg = bed->segsec_names_xlat; seg->segname; seg++)
+ for (sec = seg->sections; sec->bfd_name; sec++)
+ if (strcmp (bfd_name, sec->bfd_name) == 0)
+ {
+ *segname = seg->segname;
+ return sec;
+ }
+
+ /* ... and then the Mach-O generic ones. */
+ for (seg = segsec_names_xlat; seg->segname; seg++)
+ for (sec = seg->sections; sec->bfd_name; sec++)
+ if (strcmp (bfd_name, sec->bfd_name) == 0)
+ {
+ *segname = seg->segname;
+ return sec;
+ }
+
+ return NULL;
+}
+
+/* Convert Mach-O section name to BFD.
+
+ Try to use standard/canonical names, for which we have tables including
+ default flag settings - which are returned. Otherwise forge a new name
+ in the form "<segmentname>.<sectionname>" this will be prefixed with
+ LC_SEGMENT. if the segment name does not begin with an underscore.
+
+ SEGNAME and SECTNAME are 16 byte arrays (they do not need to be NUL-
+ terminated if the name length is exactly 16 bytes - but must be if the name
+ length is less than 16 characters). */
+
+void
+bfd_mach_o_convert_section_name_to_bfd (bfd *abfd, const char *segname,
+ const char *secname, const char **name,
+ flagword *flags)
+{
+ const mach_o_section_name_xlat *xlat;
+ char *res;
+ unsigned int len;
+ const char *pfx = "";
+
+ *name = NULL;
+ *flags = SEC_NO_FLAGS;
+
+ /* First search for a canonical name...
+ xlat will be non-null if there is an entry for segname, secname. */
+ xlat = bfd_mach_o_section_data_for_mach_sect (abfd, segname, secname);
+ if (xlat)
+ {
+ len = strlen (xlat->bfd_name);
+ res = bfd_alloc (abfd, len+1);
+ if (res == NULL)
+ return;
+ memcpy (res, xlat->bfd_name, len+1);
+ *name = res;
+ *flags = xlat->bfd_flags;
+ return;
+ }
+
+ /* ... else we make up a bfd name from the segment concatenated with the
+ section. */
+
+ len = 16 + 1 + 16 + 1;
+
+ /* Put "LC_SEGMENT." prefix if the segment name is weird (ie doesn't start
+ with an underscore. */
+ if (segname[0] != '_')
+ {
+ static const char seg_pfx[] = "LC_SEGMENT.";
+
+ pfx = seg_pfx;
+ len += sizeof (seg_pfx) - 1;
+ }
+
+ res = bfd_alloc (abfd, len);
+ if (res == NULL)
+ return;
+ snprintf (res, len, "%s%.16s.%.16s", pfx, segname, secname);
+ *name = res;
+}
+
+/* Convert a bfd section name to a Mach-O segment + section name.
+
+ If the name is a canonical one for which we have a Darwin match
+ return the translation table - which contains defaults for flags,
+ type, attribute and default alignment data.
+
+ Otherwise, expand the bfd_name (assumed to be in the form
+ "[LC_SEGMENT.]<segmentname>.<sectionname>") and return NULL. */
+
+static const mach_o_section_name_xlat *
+bfd_mach_o_convert_section_name_to_mach_o (bfd *abfd ATTRIBUTE_UNUSED,
+ asection *sect,
+ bfd_mach_o_section *section)
+{
+ const mach_o_section_name_xlat *xlat;
+ const char *name = bfd_get_section_name (abfd, sect);
+ const char *segname;
+ const char *dot;
+ unsigned int len;
+ unsigned int seglen;
+ unsigned int seclen;
+
+ memset (section->segname, 0, BFD_MACH_O_SEGNAME_SIZE + 1);
+ memset (section->sectname, 0, BFD_MACH_O_SECTNAME_SIZE + 1);
+
+ /* See if is a canonical name ... */
+ xlat = bfd_mach_o_section_data_for_bfd_name (abfd, name, &segname);
+ if (xlat)
+ {
+ strcpy (section->segname, segname);
+ strcpy (section->sectname, xlat->mach_o_name);
+ return xlat;
+ }
+
+ /* .. else we convert our constructed one back to Mach-O.
+ Strip LC_SEGMENT. prefix, if present. */
+ if (strncmp (name, "LC_SEGMENT.", 11) == 0)
+ name += 11;
+
+ /* Find a dot. */
+ dot = strchr (name, '.');
+ len = strlen (name);
+
+ /* Try to split name into segment and section names. */
+ if (dot && dot != name)
+ {
+ seglen = dot - name;
+ seclen = len - (dot + 1 - name);
+
+ if (seglen <= BFD_MACH_O_SEGNAME_SIZE
+ && seclen <= BFD_MACH_O_SECTNAME_SIZE)
+ {
+ memcpy (section->segname, name, seglen);
+ section->segname[seglen] = 0;
+ memcpy (section->sectname, dot + 1, seclen);
+ section->sectname[seclen] = 0;
+ return NULL;
+ }
+ }
+
+ /* The segment and section names are both missing - don't make them
+ into dots. */
+ if (dot && dot == name)
+ return NULL;
+
+ /* Just duplicate the name into both segment and section. */
+ if (len > 16)
+ len = 16;
+ memcpy (section->segname, name, len);
+ section->segname[len] = 0;
+ memcpy (section->sectname, name, len);
+ section->sectname[len] = 0;
+ return NULL;
+}
+
+/* Return the size of an entry for section SEC.
+ Must be called only for symbol pointer section and symbol stubs
+ sections. */
+
+unsigned int
+bfd_mach_o_section_get_entry_size (bfd *abfd, bfd_mach_o_section *sec)
+{
+ switch (sec->flags & BFD_MACH_O_SECTION_TYPE_MASK)
+ {
+ case BFD_MACH_O_S_NON_LAZY_SYMBOL_POINTERS:
+ case BFD_MACH_O_S_LAZY_SYMBOL_POINTERS:
+ return bfd_mach_o_wide_p (abfd) ? 8 : 4;
+ case BFD_MACH_O_S_SYMBOL_STUBS:
+ return sec->reserved2;
+ default:
+ BFD_FAIL ();
+ return 0;
+ }
+}
+
+/* Return the number of indirect symbols for a section.
+ Must be called only for symbol pointer section and symbol stubs
+ sections. */
+
+unsigned int
+bfd_mach_o_section_get_nbr_indirect (bfd *abfd, bfd_mach_o_section *sec)
+{
+ unsigned int elsz;
+
+ elsz = bfd_mach_o_section_get_entry_size (abfd, sec);
+ if (elsz == 0)
+ return 0;
+ else
+ return sec->size / elsz;
+}
+
+/* Append command CMD to ABFD. Note that header.ncmds is not updated. */
+
+static void
+bfd_mach_o_append_command (bfd *abfd, bfd_mach_o_load_command *cmd)
+{
+ bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
+
+ if (mdata->last_command != NULL)
+ mdata->last_command->next = cmd;
+ else
+ mdata->first_command = cmd;
+ mdata->last_command = cmd;
+ cmd->next = NULL;
+}
+
+/* Copy any private info we understand from the input symbol
+ to the output symbol. */
+
+bfd_boolean
+bfd_mach_o_bfd_copy_private_symbol_data (bfd *ibfd ATTRIBUTE_UNUSED,
+ asymbol *isymbol,
+ bfd *obfd ATTRIBUTE_UNUSED,
+ asymbol *osymbol)
+{
+ bfd_mach_o_asymbol *os, *is;
+
+ os = (bfd_mach_o_asymbol *)osymbol;
+ is = (bfd_mach_o_asymbol *)isymbol;
+ os->n_type = is->n_type;
+ os->n_sect = is->n_sect;
+ os->n_desc = is->n_desc;
+ os->symbol.udata.i = is->symbol.udata.i;
+
+ return TRUE;
+}
+
+/* Copy any private info we understand from the input section
+ to the output section. */
+
+bfd_boolean
+bfd_mach_o_bfd_copy_private_section_data (bfd *ibfd, asection *isection,
+ bfd *obfd, asection *osection)
+{
+ bfd_mach_o_section *os = bfd_mach_o_get_mach_o_section (osection);
+ bfd_mach_o_section *is = bfd_mach_o_get_mach_o_section (isection);
+
+ if (ibfd->xvec->flavour != bfd_target_mach_o_flavour
+ || obfd->xvec->flavour != bfd_target_mach_o_flavour)
+ return TRUE;
+
+ BFD_ASSERT (is != NULL && os != NULL);
+
+ os->flags = is->flags;
+ os->reserved1 = is->reserved1;
+ os->reserved2 = is->reserved2;
+ os->reserved3 = is->reserved3;
+
+ return TRUE;
+}
+
+/* Copy any private info we understand from the input bfd
+ to the output bfd. */
+
+bfd_boolean
+bfd_mach_o_bfd_copy_private_header_data (bfd *ibfd, bfd *obfd)
+{
+ bfd_mach_o_data_struct *imdata;
+ bfd_mach_o_data_struct *omdata;
+ bfd_mach_o_load_command *icmd;
+
+ if (bfd_get_flavour (ibfd) != bfd_target_mach_o_flavour
+ || bfd_get_flavour (obfd) != bfd_target_mach_o_flavour)
+ return TRUE;
+
+ BFD_ASSERT (bfd_mach_o_valid (ibfd));
+ BFD_ASSERT (bfd_mach_o_valid (obfd));
+
+ imdata = bfd_mach_o_get_data (ibfd);
+ omdata = bfd_mach_o_get_data (obfd);
+
+ /* Copy header flags. */
+ omdata->header.flags = imdata->header.flags;
+
+ /* Copy commands. */
+ for (icmd = imdata->first_command; icmd != NULL; icmd = icmd->next)
+ {
+ bfd_mach_o_load_command *ocmd;
+
+ switch (icmd->type)
+ {
+ case BFD_MACH_O_LC_LOAD_DYLIB:
+ case BFD_MACH_O_LC_LOAD_DYLINKER:
+ case BFD_MACH_O_LC_DYLD_INFO:
+ /* Command is copied. */
+ ocmd = bfd_alloc (obfd, sizeof (bfd_mach_o_load_command));
+ if (ocmd == NULL)
+ return FALSE;
+
+ /* Copy common fields. */
+ ocmd->type = icmd->type;
+ ocmd->type_required = icmd->type_required;
+ ocmd->offset = 0;
+ ocmd->len = icmd->len;
+ break;
+
+ default:
+ /* Command is not copied. */
+ continue;
+ break;
+ }
+
+ switch (icmd->type)
+ {
+ case BFD_MACH_O_LC_LOAD_DYLIB:
+ {
+ bfd_mach_o_dylib_command *idy = &icmd->command.dylib;
+ bfd_mach_o_dylib_command *ody = &ocmd->command.dylib;
+
+ ody->name_offset = idy->name_offset;
+ ody->timestamp = idy->timestamp;
+ ody->current_version = idy->current_version;
+ ody->compatibility_version = idy->compatibility_version;
+ ody->name_str = idy->name_str;
+ }
+ break;
+
+ case BFD_MACH_O_LC_LOAD_DYLINKER:
+ {
+ bfd_mach_o_dylinker_command *idy = &icmd->command.dylinker;
+ bfd_mach_o_dylinker_command *ody = &ocmd->command.dylinker;
+
+ ody->name_offset = idy->name_offset;
+ ody->name_str = idy->name_str;
+ }
+ break;
+
+ case BFD_MACH_O_LC_DYLD_INFO:
+ {
+ bfd_mach_o_dyld_info_command *idy = &icmd->command.dyld_info;
+ bfd_mach_o_dyld_info_command *ody = &ocmd->command.dyld_info;
+
+ if (bfd_mach_o_read_dyld_content (ibfd, idy))
+ {
+ ody->rebase_size = idy->rebase_size;
+ ody->rebase_content = idy->rebase_content;
+
+ ody->bind_size = idy->bind_size;
+ ody->bind_content = idy->bind_content;
+
+ ody->weak_bind_size = idy->weak_bind_size;
+ ody->weak_bind_content = idy->weak_bind_content;
+
+ ody->lazy_bind_size = idy->lazy_bind_size;
+ ody->lazy_bind_content = idy->lazy_bind_content;
+
+ ody->export_size = idy->export_size;
+ ody->export_content = idy->export_content;
+ }
+ }
+ break;
+
+ default:
+ /* That command should be handled. */
+ abort ();
+ }
+
+ /* Insert command. */
+ bfd_mach_o_append_command (obfd, ocmd);
+ }
+
+ return TRUE;
+}
+
+/* This allows us to set up to 32 bits of flags (unless we invent some
+ fiendish scheme to subdivide). For now, we'll just set the file flags
+ without error checking - just overwrite. */
+
+bfd_boolean
+bfd_mach_o_bfd_set_private_flags (bfd *abfd, flagword flags)
+{
+ bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
+
+ if (!mdata)
+ return FALSE;
+
+ mdata->header.flags = flags;
+ return TRUE;
+}
+
+/* Count the total number of symbols. */
+
+static long
+bfd_mach_o_count_symbols (bfd *abfd)
+{
+ bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
+
+ if (mdata->symtab == NULL)
+ return 0;
+ return mdata->symtab->nsyms;
+}
+
+long
+bfd_mach_o_get_symtab_upper_bound (bfd *abfd)
+{
+ long nsyms = bfd_mach_o_count_symbols (abfd);
+
+ return ((nsyms + 1) * sizeof (asymbol *));
+}
+
+long
+bfd_mach_o_canonicalize_symtab (bfd *abfd, asymbol **alocation)
+{
+ bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
+ long nsyms = bfd_mach_o_count_symbols (abfd);
+ bfd_mach_o_symtab_command *sym = mdata->symtab;
+ unsigned long j;
+
+ if (nsyms < 0)
+ return nsyms;
+
+ if (nsyms == 0)
+ {
+ /* Do not try to read symbols if there are none. */
+ alocation[0] = NULL;
+ return 0;
+ }
+
+ if (!bfd_mach_o_read_symtab_symbols (abfd))
+ {
+ (*_bfd_error_handler)
+ (_("bfd_mach_o_canonicalize_symtab: unable to load symbols"));
+ return 0;
+ }
+
+ BFD_ASSERT (sym->symbols != NULL);
+
+ for (j = 0; j < sym->nsyms; j++)
+ alocation[j] = &sym->symbols[j].symbol;
+
+ alocation[j] = NULL;
+
+ return nsyms;
+}
+
+/* Create synthetic symbols for indirect symbols. */
+
+long
+bfd_mach_o_get_synthetic_symtab (bfd *abfd,
+ long symcount ATTRIBUTE_UNUSED,
+ asymbol **syms ATTRIBUTE_UNUSED,
+ long dynsymcount ATTRIBUTE_UNUSED,
+ asymbol **dynsyms ATTRIBUTE_UNUSED,
+ asymbol **ret)
+{
+ bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
+ bfd_mach_o_dysymtab_command *dysymtab = mdata->dysymtab;
+ bfd_mach_o_symtab_command *symtab = mdata->symtab;
+ asymbol *s;
+ unsigned long count, i, j, n;
+ size_t size;
+ char *names;
+ char *nul_name;
+
+ *ret = NULL;
+
+ /* Stop now if no symbols or no indirect symbols. */
+ if (dysymtab == NULL || symtab == NULL || symtab->symbols == NULL)
+ return 0;
+
+ if (dysymtab->nindirectsyms == 0)
+ return 0;
+
+ /* We need to allocate a bfd symbol for every indirect symbol and to
+ allocate the memory for its name. */
+ count = dysymtab->nindirectsyms;
+ size = count * sizeof (asymbol) + 1;
+
+ for (j = 0; j < count; j++)
+ {
+ unsigned int isym = dysymtab->indirect_syms[j];
+
+ /* Some indirect symbols are anonymous. */
+ if (isym < symtab->nsyms && symtab->symbols[isym].symbol.name)
+ size += strlen (symtab->symbols[isym].symbol.name) + sizeof ("$stub");
+ }
+
+ s = *ret = (asymbol *) bfd_malloc (size);
+ if (s == NULL)
+ return -1;
+ names = (char *) (s + count);
+ nul_name = names;
+ *names++ = 0;
+
+ n = 0;
+ for (i = 0; i < mdata->nsects; i++)
+ {
+ bfd_mach_o_section *sec = mdata->sections[i];
+ unsigned int first, last;
+ bfd_vma addr;
+ bfd_vma entry_size;
+
+ switch (sec->flags & BFD_MACH_O_SECTION_TYPE_MASK)
+ {
+ case BFD_MACH_O_S_NON_LAZY_SYMBOL_POINTERS:
+ case BFD_MACH_O_S_LAZY_SYMBOL_POINTERS:
+ case BFD_MACH_O_S_SYMBOL_STUBS:
+ /* Only these sections have indirect symbols. */
+ first = sec->reserved1;
+ last = first + bfd_mach_o_section_get_nbr_indirect (abfd, sec);
+ addr = sec->addr;
+ entry_size = bfd_mach_o_section_get_entry_size (abfd, sec);
+ for (j = first; j < last; j++)
+ {
+ unsigned int isym = dysymtab->indirect_syms[j];
+
+ s->flags = BSF_GLOBAL | BSF_SYNTHETIC;
+ s->section = sec->bfdsection;
+ s->value = addr - sec->addr;
+ s->udata.p = NULL;
+
+ if (isym < symtab->nsyms
+ && symtab->symbols[isym].symbol.name)
+ {
+ const char *sym = symtab->symbols[isym].symbol.name;
+ size_t len;
+
+ s->name = names;
+ len = strlen (sym);
+ memcpy (names, sym, len);
+ names += len;
+ memcpy (names, "$stub", sizeof ("$stub"));
+ names += sizeof ("$stub");
+ }
+ else
+ s->name = nul_name;
+
+ addr += entry_size;
+ s++;
+ n++;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ return n;
+}
+
+void
+bfd_mach_o_get_symbol_info (bfd *abfd ATTRIBUTE_UNUSED,
+ asymbol *symbol,
+ symbol_info *ret)
+{
+ bfd_symbol_info (symbol, ret);
+}
+
+void
+bfd_mach_o_print_symbol (bfd *abfd,
+ void * afile,
+ asymbol *symbol,
+ bfd_print_symbol_type how)
+{
+ FILE *file = (FILE *) afile;
+ const char *name;
+ bfd_mach_o_asymbol *asym = (bfd_mach_o_asymbol *)symbol;
+
+ switch (how)
+ {
+ case bfd_print_symbol_name:
+ fprintf (file, "%s", symbol->name);
+ break;
+ default:
+ bfd_print_symbol_vandf (abfd, (void *) file, symbol);
+ if (asym->n_type & BFD_MACH_O_N_STAB)
+ name = bfd_get_stab_name (asym->n_type);
+ else
+ switch (asym->n_type & BFD_MACH_O_N_TYPE)
+ {
+ case BFD_MACH_O_N_UNDF:
+ if (symbol->value == 0)
+ name = "UND";
+ else
+ name = "COM";
+ break;
+ case BFD_MACH_O_N_ABS:
+ name = "ABS";
+ break;
+ case BFD_MACH_O_N_INDR:
+ name = "INDR";
+ break;
+ case BFD_MACH_O_N_PBUD:
+ name = "PBUD";
+ break;
+ case BFD_MACH_O_N_SECT:
+ name = "SECT";
+ break;
+ default:
+ name = "???";
+ break;
+ }
+ if (name == NULL)
+ name = "";
+ fprintf (file, " %02x %-6s %02x %04x",
+ asym->n_type, name, asym->n_sect, asym->n_desc);
+ if ((asym->n_type & BFD_MACH_O_N_STAB) == 0
+ && (asym->n_type & BFD_MACH_O_N_TYPE) == BFD_MACH_O_N_SECT)
+ fprintf (file, " [%s]", symbol->section->name);
+ fprintf (file, " %s", symbol->name);
+ }
+}
+
+static void
+bfd_mach_o_convert_architecture (bfd_mach_o_cpu_type mtype,
+ bfd_mach_o_cpu_subtype msubtype,
+ enum bfd_architecture *type,
+ unsigned long *subtype)
+{
+ *subtype = bfd_arch_unknown;
+
+ switch (mtype)
+ {
+ case BFD_MACH_O_CPU_TYPE_VAX:
+ *type = bfd_arch_vax;
+ break;
+ case BFD_MACH_O_CPU_TYPE_MC680x0:
+ *type = bfd_arch_m68k;
+ break;
+ case BFD_MACH_O_CPU_TYPE_I386:
+ *type = bfd_arch_i386;
+ *subtype = bfd_mach_i386_i386;
+ break;
+ case BFD_MACH_O_CPU_TYPE_X86_64:
+ *type = bfd_arch_i386;
+ *subtype = bfd_mach_x86_64;
+ break;
+ case BFD_MACH_O_CPU_TYPE_MIPS:
+ *type = bfd_arch_mips;
+ break;
+ case BFD_MACH_O_CPU_TYPE_MC98000:
+ *type = bfd_arch_m98k;
+ break;
+ case BFD_MACH_O_CPU_TYPE_HPPA:
+ *type = bfd_arch_hppa;
+ break;
+ case BFD_MACH_O_CPU_TYPE_ARM:
+ *type = bfd_arch_arm;
+ switch (msubtype)
+ {
+ case BFD_MACH_O_CPU_SUBTYPE_ARM_V4T:
+ *subtype = bfd_mach_arm_4T;
+ break;
+ case BFD_MACH_O_CPU_SUBTYPE_ARM_V6:
+ *subtype = bfd_mach_arm_4T; /* Best fit ? */
+ break;
+ case BFD_MACH_O_CPU_SUBTYPE_ARM_V5TEJ:
+ *subtype = bfd_mach_arm_5TE;
+ break;
+ case BFD_MACH_O_CPU_SUBTYPE_ARM_XSCALE:
+ *subtype = bfd_mach_arm_XScale;
+ break;
+ case BFD_MACH_O_CPU_SUBTYPE_ARM_V7:
+ *subtype = bfd_mach_arm_5TE; /* Best fit ? */
+ break;
+ case BFD_MACH_O_CPU_SUBTYPE_ARM_ALL:
+ default:
+ break;
+ }
+ break;
+ case BFD_MACH_O_CPU_TYPE_MC88000:
+ *type = bfd_arch_m88k;
+ break;
+ case BFD_MACH_O_CPU_TYPE_SPARC:
+ *type = bfd_arch_sparc;
+ *subtype = bfd_mach_sparc;
+ break;
+ case BFD_MACH_O_CPU_TYPE_I860:
+ *type = bfd_arch_i860;
+ break;
+ case BFD_MACH_O_CPU_TYPE_ALPHA:
+ *type = bfd_arch_alpha;
+ break;
+ case BFD_MACH_O_CPU_TYPE_POWERPC:
+ *type = bfd_arch_powerpc;
+ *subtype = bfd_mach_ppc;
+ break;
+ case BFD_MACH_O_CPU_TYPE_POWERPC_64:
+ *type = bfd_arch_powerpc;
+ *subtype = bfd_mach_ppc64;
+ break;
+ case BFD_MACH_O_CPU_TYPE_ARM64:
+ *type = bfd_arch_aarch64;
+ *subtype = bfd_mach_aarch64;
+ break;
+ default:
+ *type = bfd_arch_unknown;
+ break;
+ }
+}
+
+/* Write n NUL bytes to ABFD so that LEN + n is a multiple of 4. Return the
+ number of bytes written or -1 in case of error. */
+
+static int
+bfd_mach_o_pad4 (bfd *abfd, unsigned int len)
+{
+ if (len % 4 != 0)
+ {
+ char pad[4] = {0,0,0,0};
+ unsigned int padlen = 4 - (len % 4);
+
+ if (bfd_bwrite (pad, padlen, abfd) != padlen)
+ return -1;
+
+ return padlen;
+ }
+ else
+ return 0;
+}
+
+/* Likewise, but for a command. */
+
+static int
+bfd_mach_o_pad_command (bfd *abfd, unsigned int len)
+{
+ unsigned int align = bfd_mach_o_wide_p (abfd) ? 8 : 4;
+
+ if (len % align != 0)
+ {
+ char pad[8] = {0};
+ unsigned int padlen = align - (len % align);
+
+ if (bfd_bwrite (pad, padlen, abfd) != padlen)
+ return -1;
+
+ return padlen;
+ }
+ else
+ return 0;
+}
+
+static bfd_boolean
+bfd_mach_o_write_header (bfd *abfd, bfd_mach_o_header *header)
+{
+ struct mach_o_header_external raw;
+ unsigned int size;
+
+ size = mach_o_wide_p (header) ?
+ BFD_MACH_O_HEADER_64_SIZE : BFD_MACH_O_HEADER_SIZE;
+
+ bfd_h_put_32 (abfd, header->magic, raw.magic);
+ bfd_h_put_32 (abfd, header->cputype, raw.cputype);
+ bfd_h_put_32 (abfd, header->cpusubtype, raw.cpusubtype);
+ bfd_h_put_32 (abfd, header->filetype, raw.filetype);
+ bfd_h_put_32 (abfd, header->ncmds, raw.ncmds);
+ bfd_h_put_32 (abfd, header->sizeofcmds, raw.sizeofcmds);
+ bfd_h_put_32 (abfd, header->flags, raw.flags);
+
+ if (mach_o_wide_p (header))
+ bfd_h_put_32 (abfd, header->reserved, raw.reserved);
+
+ if (bfd_seek (abfd, 0, SEEK_SET) != 0
+ || bfd_bwrite (&raw, size, abfd) != size)
+ return FALSE;
+
+ return TRUE;
+}
+
+static bfd_boolean
+bfd_mach_o_write_thread (bfd *abfd, bfd_mach_o_load_command *command)
+{
+ bfd_mach_o_thread_command *cmd = &command->command.thread;
+ unsigned int i;
+ struct mach_o_thread_command_external raw;
+ unsigned int offset;
+
+ BFD_ASSERT ((command->type == BFD_MACH_O_LC_THREAD)
+ || (command->type == BFD_MACH_O_LC_UNIXTHREAD));
+
+ offset = BFD_MACH_O_LC_SIZE;
+ for (i = 0; i < cmd->nflavours; i++)
+ {
+ BFD_ASSERT ((cmd->flavours[i].size % 4) == 0);
+ BFD_ASSERT (cmd->flavours[i].offset ==
+ (command->offset + offset + BFD_MACH_O_LC_SIZE));
+
+ bfd_h_put_32 (abfd, cmd->flavours[i].flavour, raw.flavour);
+ bfd_h_put_32 (abfd, (cmd->flavours[i].size / 4), raw.count);
+
+ if (bfd_seek (abfd, command->offset + offset, SEEK_SET) != 0
+ || bfd_bwrite (&raw, sizeof (raw), abfd) != sizeof (raw))
+ return FALSE;
+
+ offset += cmd->flavours[i].size + sizeof (raw);
+ }
+
+ return TRUE;
+}
+
+static bfd_boolean
+bfd_mach_o_write_dylinker (bfd *abfd, bfd_mach_o_load_command *command)
+{
+ bfd_mach_o_dylinker_command *cmd = &command->command.dylinker;
+ struct mach_o_str_command_external raw;
+ unsigned int namelen;
+
+ bfd_h_put_32 (abfd, cmd->name_offset, raw.str);
+
+ if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
+ || bfd_bwrite (&raw, sizeof (raw), abfd) != sizeof (raw))
+ return FALSE;
+
+ namelen = strlen (cmd->name_str) + 1;
+ if (bfd_bwrite (cmd->name_str, namelen, abfd) != namelen)
+ return FALSE;
+
+ if (bfd_mach_o_pad_command (abfd, namelen) < 0)
+ return FALSE;
+
+ return TRUE;
+}
+
+static bfd_boolean
+bfd_mach_o_write_dylib (bfd *abfd, bfd_mach_o_load_command *command)
+{
+ bfd_mach_o_dylib_command *cmd = &command->command.dylib;
+ struct mach_o_dylib_command_external raw;
+ unsigned int namelen;
+
+ bfd_h_put_32 (abfd, cmd->name_offset, raw.name);
+ bfd_h_put_32 (abfd, cmd->timestamp, raw.timestamp);
+ bfd_h_put_32 (abfd, cmd->current_version, raw.current_version);
+ bfd_h_put_32 (abfd, cmd->compatibility_version, raw.compatibility_version);
+
+ if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
+ || bfd_bwrite (&raw, sizeof (raw), abfd) != sizeof (raw))
+ return FALSE;
+
+ namelen = strlen (cmd->name_str) + 1;
+ if (bfd_bwrite (cmd->name_str, namelen, abfd) != namelen)
+ return FALSE;
+
+ if (bfd_mach_o_pad_command (abfd, namelen) < 0)
+ return FALSE;
+
+ return TRUE;
+}
+
+static bfd_boolean
+bfd_mach_o_write_main (bfd *abfd, bfd_mach_o_load_command *command)
+{
+ bfd_mach_o_main_command *cmd = &command->command.main;
+ struct mach_o_entry_point_command_external raw;
+
+ bfd_h_put_64 (abfd, cmd->entryoff, raw.entryoff);
+ bfd_h_put_64 (abfd, cmd->stacksize, raw.stacksize);
+
+ if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
+ || bfd_bwrite (&raw, sizeof (raw), abfd) != sizeof (raw))
+ return FALSE;
+
+ return TRUE;
+}
+
+static bfd_boolean
+bfd_mach_o_write_dyld_info (bfd *abfd, bfd_mach_o_load_command *command)
+{
+ bfd_mach_o_dyld_info_command *cmd = &command->command.dyld_info;
+ struct mach_o_dyld_info_command_external raw;
+
+ bfd_h_put_32 (abfd, cmd->rebase_off, raw.rebase_off);
+ bfd_h_put_32 (abfd, cmd->rebase_size, raw.rebase_size);
+ bfd_h_put_32 (abfd, cmd->bind_off, raw.bind_off);
+ bfd_h_put_32 (abfd, cmd->bind_size, raw.bind_size);
+ bfd_h_put_32 (abfd, cmd->weak_bind_off, raw.weak_bind_off);
+ bfd_h_put_32 (abfd, cmd->weak_bind_size, raw.weak_bind_size);
+ bfd_h_put_32 (abfd, cmd->lazy_bind_off, raw.lazy_bind_off);
+ bfd_h_put_32 (abfd, cmd->lazy_bind_size, raw.lazy_bind_size);
+ bfd_h_put_32 (abfd, cmd->export_off, raw.export_off);
+ bfd_h_put_32 (abfd, cmd->export_size, raw.export_size);
+
+ if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
+ || bfd_bwrite (&raw, sizeof (raw), abfd) != sizeof (raw))
+ return FALSE;
+
+ if (cmd->rebase_size != 0)
+ if (bfd_seek (abfd, cmd->rebase_off, SEEK_SET) != 0
+ || (bfd_bwrite (cmd->rebase_content, cmd->rebase_size, abfd) !=
+ cmd->rebase_size))
+ return FALSE;
+
+ if (cmd->bind_size != 0)
+ if (bfd_seek (abfd, cmd->bind_off, SEEK_SET) != 0
+ || (bfd_bwrite (cmd->bind_content, cmd->bind_size, abfd) !=
+ cmd->bind_size))
+ return FALSE;
+
+ if (cmd->weak_bind_size != 0)
+ if (bfd_seek (abfd, cmd->weak_bind_off, SEEK_SET) != 0
+ || (bfd_bwrite (cmd->weak_bind_content, cmd->weak_bind_size, abfd) !=
+ cmd->weak_bind_size))
+ return FALSE;
+
+ if (cmd->lazy_bind_size != 0)
+ if (bfd_seek (abfd, cmd->lazy_bind_off, SEEK_SET) != 0
+ || (bfd_bwrite (cmd->lazy_bind_content, cmd->lazy_bind_size, abfd) !=
+ cmd->lazy_bind_size))
+ return FALSE;
+
+ if (cmd->export_size != 0)
+ if (bfd_seek (abfd, cmd->export_off, SEEK_SET) != 0
+ || (bfd_bwrite (cmd->export_content, cmd->export_size, abfd) !=
+ cmd->export_size))
+ return FALSE;
+
+ return TRUE;
+}
+
+long
+bfd_mach_o_get_reloc_upper_bound (bfd *abfd ATTRIBUTE_UNUSED,
+ asection *asect)
+{
+ return (asect->reloc_count + 1) * sizeof (arelent *);
+}
+
+/* In addition to the need to byte-swap the symbol number, the bit positions
+ of the fields in the relocation information vary per target endian-ness. */
+
+static void
+bfd_mach_o_swap_in_non_scattered_reloc (bfd *abfd, bfd_mach_o_reloc_info *rel,
+ unsigned char *fields)
+{
+ unsigned char info = fields[3];
+
+ if (bfd_big_endian (abfd))
+ {
+ rel->r_value = (fields[0] << 16) | (fields[1] << 8) | fields[2];
+ rel->r_type = (info >> BFD_MACH_O_BE_TYPE_SHIFT) & BFD_MACH_O_TYPE_MASK;
+ rel->r_pcrel = (info & BFD_MACH_O_BE_PCREL) ? 1 : 0;
+ rel->r_length = (info >> BFD_MACH_O_BE_LENGTH_SHIFT)
+ & BFD_MACH_O_LENGTH_MASK;
+ rel->r_extern = (info & BFD_MACH_O_BE_EXTERN) ? 1 : 0;
+ }
+ else
+ {
+ rel->r_value = (fields[2] << 16) | (fields[1] << 8) | fields[0];
+ rel->r_type = (info >> BFD_MACH_O_LE_TYPE_SHIFT) & BFD_MACH_O_TYPE_MASK;
+ rel->r_pcrel = (info & BFD_MACH_O_LE_PCREL) ? 1 : 0;
+ rel->r_length = (info >> BFD_MACH_O_LE_LENGTH_SHIFT)
+ & BFD_MACH_O_LENGTH_MASK;
+ rel->r_extern = (info & BFD_MACH_O_LE_EXTERN) ? 1 : 0;
+ }
+}
+
+static int
+bfd_mach_o_canonicalize_one_reloc (bfd *abfd,
+ struct mach_o_reloc_info_external *raw,
+ arelent *res, asymbol **syms)
+{
+ bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
+ bfd_mach_o_backend_data *bed = bfd_mach_o_get_backend_data (abfd);
+ bfd_mach_o_reloc_info reloc;
+ bfd_vma addr;
+ asymbol **sym;
+
+ addr = bfd_get_32 (abfd, raw->r_address);
+ res->sym_ptr_ptr = NULL;
+ res->addend = 0;
+
+ if (addr & BFD_MACH_O_SR_SCATTERED)
+ {
+ unsigned int j;
+ bfd_vma symnum = bfd_get_32 (abfd, raw->r_symbolnum);
+
+ /* Scattered relocation, can't be extern. */
+ reloc.r_scattered = 1;
+ reloc.r_extern = 0;
+
+ /* Extract section and offset from r_value (symnum). */
+ reloc.r_value = symnum;
+ /* FIXME: This breaks when a symbol in a reloc exactly follows the
+ end of the data for the section (e.g. in a calculation of section
+ data length). At present, the symbol will end up associated with
+ the following section or, if it falls within alignment padding, as
+ null - which will assert later. */
+ for (j = 0; j < mdata->nsects; j++)
+ {
+ bfd_mach_o_section *sect = mdata->sections[j];
+ if (symnum >= sect->addr && symnum < sect->addr + sect->size)
+ {
+ res->sym_ptr_ptr = sect->bfdsection->symbol_ptr_ptr;
+ res->addend = symnum - sect->addr;
+ break;
+ }
+ }
+
+ /* Extract the info and address fields from r_address. */
+ reloc.r_type = BFD_MACH_O_GET_SR_TYPE (addr);
+ reloc.r_length = BFD_MACH_O_GET_SR_LENGTH (addr);
+ reloc.r_pcrel = addr & BFD_MACH_O_SR_PCREL;
+ reloc.r_address = BFD_MACH_O_GET_SR_TYPE (addr);
+ res->address = BFD_MACH_O_GET_SR_ADDRESS (addr);
+ }
+ else
+ {
+ unsigned int num;
+
+ /* Non-scattered relocation. */
+ reloc.r_scattered = 0;
+
+ /* The value and info fields have to be extracted dependent on target
+ endian-ness. */
+ bfd_mach_o_swap_in_non_scattered_reloc (abfd, &reloc, raw->r_symbolnum);
+ num = reloc.r_value;
+
+ if (reloc.r_extern)
+ {
+ /* An external symbol number. */
+ sym = syms + num;
+ }
+ else if (num == 0x00ffffff || num == 0)
+ {
+ /* The 'symnum' in a non-scattered PAIR is 0x00ffffff. But as this
+ is generic code, we don't know wether this is really a PAIR.
+ This value is almost certainly not a valid section number, hence
+ this specific case to avoid an assertion failure.
+ Target specific swap_reloc_in routine should adjust that. */
+ sym = bfd_abs_section_ptr->symbol_ptr_ptr;
+ }
+ else
+ {
+ /* A section number. */
+ BFD_ASSERT (num <= mdata->nsects);
+
+ sym = mdata->sections[num - 1]->bfdsection->symbol_ptr_ptr;
+ /* For a symbol defined in section S, the addend (stored in the
+ binary) contains the address of the section. To comply with
+ bfd convention, subtract the section address.
+ Use the address from the header, so that the user can modify
+ the vma of the section. */
+ res->addend = -mdata->sections[num - 1]->addr;
+ }
+ /* Note: Pairs for PPC LO/HI/HA are not scattered, but contain the offset
+ in the lower 16bits of the address value. So we have to find the
+ 'symbol' from the preceding reloc. We do this even though the
+ section symbol is probably not needed here, because NULL symbol
+ values cause an assert in generic BFD code. This must be done in
+ the PPC swap_reloc_in routine. */
+ res->sym_ptr_ptr = sym;
+
+ /* The 'address' is just r_address.
+ ??? maybe this should be masked with 0xffffff for safety. */
+ res->address = addr;
+ reloc.r_address = addr;
+ }
+
+ /* We have set up a reloc with all the information present, so the swapper
+ can modify address, value and addend fields, if necessary, to convey
+ information in the generic BFD reloc that is mach-o specific. */
+
+ if (!(*bed->_bfd_mach_o_swap_reloc_in)(res, &reloc))
+ return -1;
+ return 0;
+}
+
+static int
+bfd_mach_o_canonicalize_relocs (bfd *abfd, unsigned long filepos,
+ unsigned long count,
+ arelent *res, asymbol **syms)
+{
+ unsigned long i;
+ struct mach_o_reloc_info_external *native_relocs;
+ bfd_size_type native_size;
+
+ /* Allocate and read relocs. */
+ native_size = count * BFD_MACH_O_RELENT_SIZE;
+ native_relocs =
+ (struct mach_o_reloc_info_external *) bfd_malloc (native_size);
+ if (native_relocs == NULL)
+ return -1;
+
+ if (bfd_seek (abfd, filepos, SEEK_SET) != 0
+ || bfd_bread (native_relocs, native_size, abfd) != native_size)
+ goto err;
+
+ for (i = 0; i < count; i++)
+ {
+ if (bfd_mach_o_canonicalize_one_reloc (abfd, &native_relocs[i],
+ &res[i], syms) < 0)
+ goto err;
+ }
+ free (native_relocs);
+ return i;
+ err:
+ free (native_relocs);
+ return -1;
+}
+
+long
+bfd_mach_o_canonicalize_reloc (bfd *abfd, asection *asect,
+ arelent **rels, asymbol **syms)
+{
+ bfd_mach_o_backend_data *bed = bfd_mach_o_get_backend_data (abfd);
+ unsigned long i;
+ arelent *res;
+
+ if (asect->reloc_count == 0)
+ return 0;
+
+ /* No need to go further if we don't know how to read relocs. */
+ if (bed->_bfd_mach_o_swap_reloc_in == NULL)
+ return 0;
+
+ if (asect->relocation == NULL)
+ {
+ res = bfd_malloc (asect->reloc_count * sizeof (arelent));
+ if (res == NULL)
+ return -1;
+
+ if (bfd_mach_o_canonicalize_relocs (abfd, asect->rel_filepos,
+ asect->reloc_count, res, syms) < 0)
+ {
+ free (res);
+ return -1;
+ }
+ asect->relocation = res;
+ }
+
+ res = asect->relocation;
+ for (i = 0; i < asect->reloc_count; i++)
+ rels[i] = &res[i];
+ rels[i] = NULL;
+
+ return i;
+}
+
+long
+bfd_mach_o_get_dynamic_reloc_upper_bound (bfd *abfd)
+{
+ bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
+
+ if (mdata->dysymtab == NULL)
+ return 1;
+ return (mdata->dysymtab->nextrel + mdata->dysymtab->nlocrel + 1)
+ * sizeof (arelent *);
+}
+
+long
+bfd_mach_o_canonicalize_dynamic_reloc (bfd *abfd, arelent **rels,
+ struct bfd_symbol **syms)
+{
+ bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
+ bfd_mach_o_dysymtab_command *dysymtab = mdata->dysymtab;
+ bfd_mach_o_backend_data *bed = bfd_mach_o_get_backend_data (abfd);
+ unsigned long i;
+ arelent *res;
+
+ if (dysymtab == NULL)
+ return 0;
+ if (dysymtab->nextrel == 0 && dysymtab->nlocrel == 0)
+ return 0;
+
+ /* No need to go further if we don't know how to read relocs. */
+ if (bed->_bfd_mach_o_swap_reloc_in == NULL)
+ return 0;
+
+ if (mdata->dyn_reloc_cache == NULL)
+ {
+ res = bfd_malloc ((dysymtab->nextrel + dysymtab->nlocrel)
+ * sizeof (arelent));
+ if (res == NULL)
+ return -1;
+
+ if (bfd_mach_o_canonicalize_relocs (abfd, dysymtab->extreloff,
+ dysymtab->nextrel, res, syms) < 0)
+ {
+ free (res);
+ return -1;
+ }
+
+ if (bfd_mach_o_canonicalize_relocs (abfd, dysymtab->locreloff,
+ dysymtab->nlocrel,
+ res + dysymtab->nextrel, syms) < 0)
+ {
+ free (res);
+ return -1;
+ }
+
+ mdata->dyn_reloc_cache = res;
+ }
+
+ res = mdata->dyn_reloc_cache;
+ for (i = 0; i < dysymtab->nextrel + dysymtab->nlocrel; i++)
+ rels[i] = &res[i];
+ rels[i] = NULL;
+ return i;
+}
+
+/* In addition to the need to byte-swap the symbol number, the bit positions
+ of the fields in the relocation information vary per target endian-ness. */
+
+static void
+bfd_mach_o_swap_out_non_scattered_reloc (bfd *abfd, unsigned char *fields,
+ bfd_mach_o_reloc_info *rel)
+{
+ unsigned char info = 0;
+
+ BFD_ASSERT (rel->r_type <= 15);
+ BFD_ASSERT (rel->r_length <= 3);
+
+ if (bfd_big_endian (abfd))
+ {
+ fields[0] = (rel->r_value >> 16) & 0xff;
+ fields[1] = (rel->r_value >> 8) & 0xff;
+ fields[2] = rel->r_value & 0xff;
+ info |= rel->r_type << BFD_MACH_O_BE_TYPE_SHIFT;
+ info |= rel->r_pcrel ? BFD_MACH_O_BE_PCREL : 0;
+ info |= rel->r_length << BFD_MACH_O_BE_LENGTH_SHIFT;
+ info |= rel->r_extern ? BFD_MACH_O_BE_EXTERN : 0;
+ }
+ else
+ {
+ fields[2] = (rel->r_value >> 16) & 0xff;
+ fields[1] = (rel->r_value >> 8) & 0xff;
+ fields[0] = rel->r_value & 0xff;
+ info |= rel->r_type << BFD_MACH_O_LE_TYPE_SHIFT;
+ info |= rel->r_pcrel ? BFD_MACH_O_LE_PCREL : 0;
+ info |= rel->r_length << BFD_MACH_O_LE_LENGTH_SHIFT;
+ info |= rel->r_extern ? BFD_MACH_O_LE_EXTERN : 0;
+ }
+ fields[3] = info;
+}
+
+static bfd_boolean
+bfd_mach_o_write_relocs (bfd *abfd, bfd_mach_o_section *section)
+{
+ unsigned int i;
+ arelent **entries;
+ asection *sec;
+ bfd_mach_o_backend_data *bed = bfd_mach_o_get_backend_data (abfd);
+
+ sec = section->bfdsection;
+ if (sec->reloc_count == 0)
+ return TRUE;
+
+ if (bed->_bfd_mach_o_swap_reloc_out == NULL)
+ return TRUE;
+
+ if (bfd_seek (abfd, section->reloff, SEEK_SET) != 0)
+ return FALSE;
+
+ /* Convert and write. */
+ entries = section->bfdsection->orelocation;
+ for (i = 0; i < section->nreloc; i++)
+ {
+ arelent *rel = entries[i];
+ struct mach_o_reloc_info_external raw;
+ bfd_mach_o_reloc_info info, *pinfo = &info;
+
+ /* Convert relocation to an intermediate representation. */
+ if (!(*bed->_bfd_mach_o_swap_reloc_out) (rel, pinfo))
+ return FALSE;
+
+ /* Lower the relocation info. */
+ if (pinfo->r_scattered)
+ {
+ unsigned long v;
+
+ v = BFD_MACH_O_SR_SCATTERED
+ | (pinfo->r_pcrel ? BFD_MACH_O_SR_PCREL : 0)
+ | BFD_MACH_O_SET_SR_LENGTH (pinfo->r_length)
+ | BFD_MACH_O_SET_SR_TYPE (pinfo->r_type)
+ | BFD_MACH_O_SET_SR_ADDRESS (pinfo->r_address);
+ /* Note: scattered relocs have field in reverse order... */
+ bfd_put_32 (abfd, v, raw.r_address);
+ bfd_put_32 (abfd, pinfo->r_value, raw.r_symbolnum);
+ }
+ else
+ {
+ bfd_put_32 (abfd, pinfo->r_address, raw.r_address);
+ bfd_mach_o_swap_out_non_scattered_reloc (abfd, raw.r_symbolnum,
+ pinfo);
+ }
+
+ if (bfd_bwrite (&raw, BFD_MACH_O_RELENT_SIZE, abfd)
+ != BFD_MACH_O_RELENT_SIZE)
+ return FALSE;
+ }
+ return TRUE;
+}
+
+static bfd_boolean
+bfd_mach_o_write_section_32 (bfd *abfd, bfd_mach_o_section *section)
+{
+ struct mach_o_section_32_external raw;
+
+ memcpy (raw.sectname, section->sectname, 16);
+ memcpy (raw.segname, section->segname, 16);
+ bfd_h_put_32 (abfd, section->addr, raw.addr);
+ bfd_h_put_32 (abfd, section->size, raw.size);
+ bfd_h_put_32 (abfd, section->offset, raw.offset);
+ bfd_h_put_32 (abfd, section->align, raw.align);
+ bfd_h_put_32 (abfd, section->reloff, raw.reloff);
+ bfd_h_put_32 (abfd, section->nreloc, raw.nreloc);
+ bfd_h_put_32 (abfd, section->flags, raw.flags);
+ bfd_h_put_32 (abfd, section->reserved1, raw.reserved1);
+ bfd_h_put_32 (abfd, section->reserved2, raw.reserved2);
+
+ if (bfd_bwrite (&raw, BFD_MACH_O_SECTION_SIZE, abfd)
+ != BFD_MACH_O_SECTION_SIZE)
+ return FALSE;
+
+ return TRUE;
+}
+
+static bfd_boolean
+bfd_mach_o_write_section_64 (bfd *abfd, bfd_mach_o_section *section)
+{
+ struct mach_o_section_64_external raw;
+
+ memcpy (raw.sectname, section->sectname, 16);
+ memcpy (raw.segname, section->segname, 16);
+ bfd_h_put_64 (abfd, section->addr, raw.addr);
+ bfd_h_put_64 (abfd, section->size, raw.size);
+ bfd_h_put_32 (abfd, section->offset, raw.offset);
+ bfd_h_put_32 (abfd, section->align, raw.align);
+ bfd_h_put_32 (abfd, section->reloff, raw.reloff);
+ bfd_h_put_32 (abfd, section->nreloc, raw.nreloc);
+ bfd_h_put_32 (abfd, section->flags, raw.flags);
+ bfd_h_put_32 (abfd, section->reserved1, raw.reserved1);
+ bfd_h_put_32 (abfd, section->reserved2, raw.reserved2);
+ bfd_h_put_32 (abfd, section->reserved3, raw.reserved3);
+
+ if (bfd_bwrite (&raw, BFD_MACH_O_SECTION_64_SIZE, abfd)
+ != BFD_MACH_O_SECTION_64_SIZE)
+ return FALSE;
+
+ return TRUE;
+}
+
+static bfd_boolean
+bfd_mach_o_write_segment_32 (bfd *abfd, bfd_mach_o_load_command *command)
+{
+ struct mach_o_segment_command_32_external raw;
+ bfd_mach_o_segment_command *seg = &command->command.segment;
+ bfd_mach_o_section *sec;
+
+ BFD_ASSERT (command->type == BFD_MACH_O_LC_SEGMENT);
+
+ for (sec = seg->sect_head; sec != NULL; sec = sec->next)
+ if (!bfd_mach_o_write_relocs (abfd, sec))
+ return FALSE;
+
+ memcpy (raw.segname, seg->segname, 16);
+ bfd_h_put_32 (abfd, seg->vmaddr, raw.vmaddr);
+ bfd_h_put_32 (abfd, seg->vmsize, raw.vmsize);
+ bfd_h_put_32 (abfd, seg->fileoff, raw.fileoff);
+ bfd_h_put_32 (abfd, seg->filesize, raw.filesize);
+ bfd_h_put_32 (abfd, seg->maxprot, raw.maxprot);
+ bfd_h_put_32 (abfd, seg->initprot, raw.initprot);
+ bfd_h_put_32 (abfd, seg->nsects, raw.nsects);
+ bfd_h_put_32 (abfd, seg->flags, raw.flags);
+
+ if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
+ || bfd_bwrite (&raw, sizeof (raw), abfd) != sizeof (raw))
+ return FALSE;
+
+ for (sec = seg->sect_head; sec != NULL; sec = sec->next)
+ if (!bfd_mach_o_write_section_32 (abfd, sec))
+ return FALSE;
+
+ return TRUE;
+}
+
+static bfd_boolean
+bfd_mach_o_write_segment_64 (bfd *abfd, bfd_mach_o_load_command *command)
+{
+ struct mach_o_segment_command_64_external raw;
+ bfd_mach_o_segment_command *seg = &command->command.segment;
+ bfd_mach_o_section *sec;
+
+ BFD_ASSERT (command->type == BFD_MACH_O_LC_SEGMENT_64);
+
+ for (sec = seg->sect_head; sec != NULL; sec = sec->next)
+ if (!bfd_mach_o_write_relocs (abfd, sec))
+ return FALSE;
+
+ memcpy (raw.segname, seg->segname, 16);
+ bfd_h_put_64 (abfd, seg->vmaddr, raw.vmaddr);
+ bfd_h_put_64 (abfd, seg->vmsize, raw.vmsize);
+ bfd_h_put_64 (abfd, seg->fileoff, raw.fileoff);
+ bfd_h_put_64 (abfd, seg->filesize, raw.filesize);
+ bfd_h_put_32 (abfd, seg->maxprot, raw.maxprot);
+ bfd_h_put_32 (abfd, seg->initprot, raw.initprot);
+ bfd_h_put_32 (abfd, seg->nsects, raw.nsects);
+ bfd_h_put_32 (abfd, seg->flags, raw.flags);
+
+ if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
+ || bfd_bwrite (&raw, sizeof (raw), abfd) != sizeof (raw))
+ return FALSE;
+
+ for (sec = seg->sect_head; sec != NULL; sec = sec->next)
+ if (!bfd_mach_o_write_section_64 (abfd, sec))
+ return FALSE;
+
+ return TRUE;
+}
+
+static bfd_boolean
+bfd_mach_o_write_symtab_content (bfd *abfd, bfd_mach_o_symtab_command *sym)
+{
+ bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
+ unsigned long i;
+ unsigned int wide = bfd_mach_o_wide_p (abfd);
+ struct bfd_strtab_hash *strtab;
+ asymbol **symbols = bfd_get_outsymbols (abfd);
+ int padlen;
+
+ /* Write the symbols first. */
+ if (bfd_seek (abfd, sym->symoff, SEEK_SET) != 0)
+ return FALSE;
+
+ strtab = _bfd_stringtab_init ();
+ if (strtab == NULL)
+ return FALSE;
+
+ if (sym->nsyms > 0)
+ /* Although we don't strictly need to do this, for compatibility with
+ Darwin system tools, actually output an empty string for the index
+ 0 entry. */
+ _bfd_stringtab_add (strtab, "", TRUE, FALSE);
+
+ for (i = 0; i < sym->nsyms; i++)
+ {
+ bfd_size_type str_index;
+ bfd_mach_o_asymbol *s = (bfd_mach_o_asymbol *)symbols[i];
+
+ if (s->symbol.name == 0 || s->symbol.name[0] == '\0')
+ /* An index of 0 always means the empty string. */
+ str_index = 0;
+ else
+ {
+ str_index = _bfd_stringtab_add (strtab, s->symbol.name, TRUE, FALSE);
+
+ if (str_index == (bfd_size_type) -1)
+ goto err;
+ }
+
+ if (wide)
+ {
+ struct mach_o_nlist_64_external raw;
+
+ bfd_h_put_32 (abfd, str_index, raw.n_strx);
+ bfd_h_put_8 (abfd, s->n_type, raw.n_type);
+ bfd_h_put_8 (abfd, s->n_sect, raw.n_sect);
+ bfd_h_put_16 (abfd, s->n_desc, raw.n_desc);
+ bfd_h_put_64 (abfd, s->symbol.section->vma + s->symbol.value,
+ raw.n_value);
+
+ if (bfd_bwrite (&raw, sizeof (raw), abfd) != sizeof (raw))
+ goto err;
+ }
+ else
+ {
+ struct mach_o_nlist_external raw;
+
+ bfd_h_put_32 (abfd, str_index, raw.n_strx);
+ bfd_h_put_8 (abfd, s->n_type, raw.n_type);
+ bfd_h_put_8 (abfd, s->n_sect, raw.n_sect);
+ bfd_h_put_16 (abfd, s->n_desc, raw.n_desc);
+ bfd_h_put_32 (abfd, s->symbol.section->vma + s->symbol.value,
+ raw.n_value);
+
+ if (bfd_bwrite (&raw, sizeof (raw), abfd) != sizeof (raw))
+ goto err;
+ }
+ }
+ sym->strsize = _bfd_stringtab_size (strtab);
+ sym->stroff = mdata->filelen;
+ mdata->filelen += sym->strsize;
+
+ if (bfd_seek (abfd, sym->stroff, SEEK_SET) != 0)
+ return FALSE;
+
+ if (_bfd_stringtab_emit (abfd, strtab) != TRUE)
+ goto err;
+ _bfd_stringtab_free (strtab);
+
+ /* Pad string table. */
+ padlen = bfd_mach_o_pad4 (abfd, sym->strsize);
+ if (padlen < 0)
+ return FALSE;
+ mdata->filelen += padlen;
+ sym->strsize += padlen;
+
+ return TRUE;
+
+ err:
+ _bfd_stringtab_free (strtab);
+ return FALSE;
+}
+
+static bfd_boolean
+bfd_mach_o_write_symtab (bfd *abfd, bfd_mach_o_load_command *command)
+{
+ bfd_mach_o_symtab_command *sym = &command->command.symtab;
+ struct mach_o_symtab_command_external raw;
+
+ BFD_ASSERT (command->type == BFD_MACH_O_LC_SYMTAB);
+
+ /* The command. */
+ bfd_h_put_32 (abfd, sym->symoff, raw.symoff);
+ bfd_h_put_32 (abfd, sym->nsyms, raw.nsyms);
+ bfd_h_put_32 (abfd, sym->stroff, raw.stroff);
+ bfd_h_put_32 (abfd, sym->strsize, raw.strsize);
+
+ if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
+ || bfd_bwrite (&raw, sizeof (raw), abfd) != sizeof (raw))
+ return FALSE;
+
+ return TRUE;
+}
+
+/* Count the number of indirect symbols in the image.
+ Requires that the sections are in their final order. */
+
+static unsigned int
+bfd_mach_o_count_indirect_symbols (bfd *abfd, bfd_mach_o_data_struct *mdata)
+{
+ unsigned int i;
+ unsigned int nisyms = 0;
+
+ for (i = 0; i < mdata->nsects; ++i)
+ {
+ bfd_mach_o_section *sec = mdata->sections[i];
+
+ switch (sec->flags & BFD_MACH_O_SECTION_TYPE_MASK)
+ {
+ case BFD_MACH_O_S_NON_LAZY_SYMBOL_POINTERS:
+ case BFD_MACH_O_S_LAZY_SYMBOL_POINTERS:
+ case BFD_MACH_O_S_SYMBOL_STUBS:
+ nisyms += bfd_mach_o_section_get_nbr_indirect (abfd, sec);
+ break;
+ default:
+ break;
+ }
+ }
+ return nisyms;
+}
+
+/* Create the dysymtab. */
+
+static bfd_boolean
+bfd_mach_o_build_dysymtab (bfd *abfd, bfd_mach_o_dysymtab_command *cmd)
+{
+ bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
+
+ /* TODO:
+ We are not going to try and fill these in yet and, moreover, we are
+ going to bail if they are already set. */
+ if (cmd->nmodtab != 0
+ || cmd->ntoc != 0
+ || cmd->nextrefsyms != 0)
+ {
+ (*_bfd_error_handler) (_("sorry: modtab, toc and extrefsyms are not yet"
+ " implemented for dysymtab commands."));
+ return FALSE;
+ }
+
+ cmd->ilocalsym = 0;
+
+ if (bfd_get_symcount (abfd) > 0)
+ {
+ asymbol **symbols = bfd_get_outsymbols (abfd);
+ unsigned long i;
+
+ /* Count the number of each kind of symbol. */
+ for (i = 0; i < bfd_get_symcount (abfd); ++i)
+ {
+ bfd_mach_o_asymbol *s = (bfd_mach_o_asymbol *)symbols[i];
+ if (s->n_type & (BFD_MACH_O_N_EXT | BFD_MACH_O_N_PEXT))
+ break;
+ }
+ cmd->nlocalsym = i;
+ cmd->iextdefsym = i;
+ for (; i < bfd_get_symcount (abfd); ++i)
+ {
+ bfd_mach_o_asymbol *s = (bfd_mach_o_asymbol *)symbols[i];
+ if ((s->n_type & BFD_MACH_O_N_TYPE) == BFD_MACH_O_N_UNDF)
+ break;
+ }
+ cmd->nextdefsym = i - cmd->nlocalsym;
+ cmd->iundefsym = cmd->nextdefsym + cmd->iextdefsym;
+ cmd->nundefsym = bfd_get_symcount (abfd)
+ - cmd->nlocalsym
+ - cmd->nextdefsym;
+ }
+ else
+ {
+ cmd->nlocalsym = 0;
+ cmd->iextdefsym = 0;
+ cmd->nextdefsym = 0;
+ cmd->iundefsym = 0;
+ cmd->nundefsym = 0;
+ }
+
+ cmd->nindirectsyms = bfd_mach_o_count_indirect_symbols (abfd, mdata);
+ if (cmd->nindirectsyms > 0)
+ {
+ unsigned i;
+ unsigned n;
+
+ mdata->filelen = FILE_ALIGN (mdata->filelen, 2);
+ cmd->indirectsymoff = mdata->filelen;
+ mdata->filelen += cmd->nindirectsyms * 4;
+
+ cmd->indirect_syms = bfd_zalloc (abfd, cmd->nindirectsyms * 4);
+ if (cmd->indirect_syms == NULL)
+ return FALSE;
+
+ n = 0;
+ for (i = 0; i < mdata->nsects; ++i)
+ {
+ bfd_mach_o_section *sec = mdata->sections[i];
+
+ switch (sec->flags & BFD_MACH_O_SECTION_TYPE_MASK)
+ {
+ case BFD_MACH_O_S_NON_LAZY_SYMBOL_POINTERS:
+ case BFD_MACH_O_S_LAZY_SYMBOL_POINTERS:
+ case BFD_MACH_O_S_SYMBOL_STUBS:
+ {
+ unsigned j, num;
+ bfd_mach_o_asymbol **isyms = sec->indirect_syms;
+
+ num = bfd_mach_o_section_get_nbr_indirect (abfd, sec);
+ if (isyms == NULL || num == 0)
+ break;
+ /* Record the starting index in the reserved1 field. */
+ sec->reserved1 = n;
+ for (j = 0; j < num; j++, n++)
+ {
+ if (isyms[j] == NULL)
+ cmd->indirect_syms[n] = BFD_MACH_O_INDIRECT_SYM_LOCAL;
+ else if (isyms[j]->symbol.section == bfd_abs_section_ptr
+ && ! (isyms[j]->n_type & BFD_MACH_O_N_EXT))
+ cmd->indirect_syms[n] = BFD_MACH_O_INDIRECT_SYM_LOCAL
+ | BFD_MACH_O_INDIRECT_SYM_ABS;
+ else
+ cmd->indirect_syms[n] = isyms[j]->symbol.udata.i;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ return TRUE;
+}
+
+/* Write a dysymtab command.
+ TODO: Possibly coalesce writes of smaller objects. */
+
+static bfd_boolean
+bfd_mach_o_write_dysymtab (bfd *abfd, bfd_mach_o_load_command *command)
+{
+ bfd_mach_o_dysymtab_command *cmd = &command->command.dysymtab;
+
+ BFD_ASSERT (command->type == BFD_MACH_O_LC_DYSYMTAB);
+
+ if (cmd->nmodtab != 0)
+ {
+ unsigned int i;
+
+ if (bfd_seek (abfd, cmd->modtaboff, SEEK_SET) != 0)
+ return FALSE;
+
+ for (i = 0; i < cmd->nmodtab; i++)
+ {
+ bfd_mach_o_dylib_module *module = &cmd->dylib_module[i];
+ unsigned int iinit;
+ unsigned int ninit;
+
+ iinit = module->iinit & 0xffff;
+ iinit |= ((module->iterm & 0xffff) << 16);
+
+ ninit = module->ninit & 0xffff;
+ ninit |= ((module->nterm & 0xffff) << 16);
+
+ if (bfd_mach_o_wide_p (abfd))
+ {
+ struct mach_o_dylib_module_64_external w;
+
+ bfd_h_put_32 (abfd, module->module_name_idx, &w.module_name);
+ bfd_h_put_32 (abfd, module->iextdefsym, &w.iextdefsym);
+ bfd_h_put_32 (abfd, module->nextdefsym, &w.nextdefsym);
+ bfd_h_put_32 (abfd, module->irefsym, &w.irefsym);
+ bfd_h_put_32 (abfd, module->nrefsym, &w.nrefsym);
+ bfd_h_put_32 (abfd, module->ilocalsym, &w.ilocalsym);
+ bfd_h_put_32 (abfd, module->nlocalsym, &w.nlocalsym);
+ bfd_h_put_32 (abfd, module->iextrel, &w.iextrel);
+ bfd_h_put_32 (abfd, module->nextrel, &w.nextrel);
+ bfd_h_put_32 (abfd, iinit, &w.iinit_iterm);
+ bfd_h_put_32 (abfd, ninit, &w.ninit_nterm);
+ bfd_h_put_64 (abfd, module->objc_module_info_addr,
+ &w.objc_module_info_addr);
+ bfd_h_put_32 (abfd, module->objc_module_info_size,
+ &w.objc_module_info_size);
+
+ if (bfd_bwrite ((void *) &w, sizeof (w), abfd) != sizeof (w))
+ return FALSE;
+ }
+ else
+ {
+ struct mach_o_dylib_module_external n;
+
+ bfd_h_put_32 (abfd, module->module_name_idx, &n.module_name);
+ bfd_h_put_32 (abfd, module->iextdefsym, &n.iextdefsym);
+ bfd_h_put_32 (abfd, module->nextdefsym, &n.nextdefsym);
+ bfd_h_put_32 (abfd, module->irefsym, &n.irefsym);
+ bfd_h_put_32 (abfd, module->nrefsym, &n.nrefsym);
+ bfd_h_put_32 (abfd, module->ilocalsym, &n.ilocalsym);
+ bfd_h_put_32 (abfd, module->nlocalsym, &n.nlocalsym);
+ bfd_h_put_32 (abfd, module->iextrel, &n.iextrel);
+ bfd_h_put_32 (abfd, module->nextrel, &n.nextrel);
+ bfd_h_put_32 (abfd, iinit, &n.iinit_iterm);
+ bfd_h_put_32 (abfd, ninit, &n.ninit_nterm);
+ bfd_h_put_32 (abfd, module->objc_module_info_addr,
+ &n.objc_module_info_addr);
+ bfd_h_put_32 (abfd, module->objc_module_info_size,
+ &n.objc_module_info_size);
+
+ if (bfd_bwrite ((void *) &n, sizeof (n), abfd) != sizeof (n))
+ return FALSE;
+ }
+ }
+ }
+
+ if (cmd->ntoc != 0)
+ {
+ unsigned int i;
+
+ if (bfd_seek (abfd, cmd->tocoff, SEEK_SET) != 0)
+ return FALSE;
+
+ for (i = 0; i < cmd->ntoc; i++)
+ {
+ struct mach_o_dylib_table_of_contents_external raw;
+ bfd_mach_o_dylib_table_of_content *toc = &cmd->dylib_toc[i];
+
+ bfd_h_put_32 (abfd, toc->symbol_index, &raw.symbol_index);
+ bfd_h_put_32 (abfd, toc->module_index, &raw.module_index);
+
+ if (bfd_bwrite (&raw, sizeof (raw), abfd) != sizeof (raw))
+ return FALSE;
+ }
+ }
+
+ if (cmd->nindirectsyms > 0)
+ {
+ unsigned int i;
+
+ if (bfd_seek (abfd, cmd->indirectsymoff, SEEK_SET) != 0)
+ return FALSE;
+
+ for (i = 0; i < cmd->nindirectsyms; ++i)
+ {
+ unsigned char raw[4];
+
+ bfd_h_put_32 (abfd, cmd->indirect_syms[i], &raw);
+ if (bfd_bwrite (raw, sizeof (raw), abfd) != sizeof (raw))
+ return FALSE;
+ }
+ }
+
+ if (cmd->nextrefsyms != 0)
+ {
+ unsigned int i;
+
+ if (bfd_seek (abfd, cmd->extrefsymoff, SEEK_SET) != 0)
+ return FALSE;
+
+ for (i = 0; i < cmd->nextrefsyms; i++)
+ {
+ unsigned long v;
+ unsigned char raw[4];
+ bfd_mach_o_dylib_reference *ref = &cmd->ext_refs[i];
+
+ /* Fields isym and flags are written as bit-fields, thus we need
+ a specific processing for endianness. */
+
+ if (bfd_big_endian (abfd))
+ {
+ v = ((ref->isym & 0xffffff) << 8);
+ v |= ref->flags & 0xff;
+ }
+ else
+ {
+ v = ref->isym & 0xffffff;
+ v |= ((ref->flags & 0xff) << 24);
+ }
+
+ bfd_h_put_32 (abfd, v, raw);
+ if (bfd_bwrite (raw, sizeof (raw), abfd) != sizeof (raw))
+ return FALSE;
+ }
+ }
+
+ /* The command. */
+ if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0)
+ return FALSE;
+ else
+ {
+ struct mach_o_dysymtab_command_external raw;
+
+ bfd_h_put_32 (abfd, cmd->ilocalsym, &raw.ilocalsym);
+ bfd_h_put_32 (abfd, cmd->nlocalsym, &raw.nlocalsym);
+ bfd_h_put_32 (abfd, cmd->iextdefsym, &raw.iextdefsym);
+ bfd_h_put_32 (abfd, cmd->nextdefsym, &raw.nextdefsym);
+ bfd_h_put_32 (abfd, cmd->iundefsym, &raw.iundefsym);
+ bfd_h_put_32 (abfd, cmd->nundefsym, &raw.nundefsym);
+ bfd_h_put_32 (abfd, cmd->tocoff, &raw.tocoff);
+ bfd_h_put_32 (abfd, cmd->ntoc, &raw.ntoc);
+ bfd_h_put_32 (abfd, cmd->modtaboff, &raw.modtaboff);
+ bfd_h_put_32 (abfd, cmd->nmodtab, &raw.nmodtab);
+ bfd_h_put_32 (abfd, cmd->extrefsymoff, &raw.extrefsymoff);
+ bfd_h_put_32 (abfd, cmd->nextrefsyms, &raw.nextrefsyms);
+ bfd_h_put_32 (abfd, cmd->indirectsymoff, &raw.indirectsymoff);
+ bfd_h_put_32 (abfd, cmd->nindirectsyms, &raw.nindirectsyms);
+ bfd_h_put_32 (abfd, cmd->extreloff, &raw.extreloff);
+ bfd_h_put_32 (abfd, cmd->nextrel, &raw.nextrel);
+ bfd_h_put_32 (abfd, cmd->locreloff, &raw.locreloff);
+ bfd_h_put_32 (abfd, cmd->nlocrel, &raw.nlocrel);
+
+ if (bfd_bwrite (&raw, sizeof (raw), abfd) != sizeof (raw))
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static unsigned
+bfd_mach_o_primary_symbol_sort_key (bfd_mach_o_asymbol *s)
+{
+ unsigned mtyp = s->n_type & BFD_MACH_O_N_TYPE;
+
+ /* Just leave debug symbols where they are (pretend they are local, and
+ then they will just be sorted on position). */
+ if (s->n_type & BFD_MACH_O_N_STAB)
+ return 0;
+
+ /* Local (we should never see an undefined local AFAICT). */
+ if (! (s->n_type & (BFD_MACH_O_N_EXT | BFD_MACH_O_N_PEXT)))
+ return 0;
+
+ /* Common symbols look like undefined externs. */
+ if (mtyp == BFD_MACH_O_N_UNDF)
+ return 2;
+
+ /* A defined non-local, non-debug symbol. */
+ return 1;
+}
+
+static int
+bfd_mach_o_cf_symbols (const void *a, const void *b)
+{
+ bfd_mach_o_asymbol *sa = *(bfd_mach_o_asymbol **) a;
+ bfd_mach_o_asymbol *sb = *(bfd_mach_o_asymbol **) b;
+ unsigned int soa, sob;
+
+ soa = bfd_mach_o_primary_symbol_sort_key (sa);
+ sob = bfd_mach_o_primary_symbol_sort_key (sb);
+ if (soa < sob)
+ return -1;
+
+ if (soa > sob)
+ return 1;
+
+ /* If it's local or stab, just preserve the input order. */
+ if (soa == 0)
+ {
+ if (sa->symbol.udata.i < sb->symbol.udata.i)
+ return -1;
+ if (sa->symbol.udata.i > sb->symbol.udata.i)
+ return 1;
+
+ /* This is probably an error. */
+ return 0;
+ }
+
+ /* The second sort key is name. */
+ return strcmp (sa->symbol.name, sb->symbol.name);
+}
+
+/* Process the symbols.
+
+ This should be OK for single-module files - but it is not likely to work
+ for multi-module shared libraries.
+
+ (a) If the application has not filled in the relevant mach-o fields, make
+ an estimate.
+
+ (b) Order them, like this:
+ ( i) local.
+ (unsorted)
+ ( ii) external defined
+ (by name)
+ (iii) external undefined/common
+ (by name)
+ ( iv) common
+ (by name)
+*/
+
+static bfd_boolean
+bfd_mach_o_mangle_symbols (bfd *abfd)
+{
+ unsigned long i;
+ asymbol **symbols = bfd_get_outsymbols (abfd);
+
+ if (symbols == NULL || bfd_get_symcount (abfd) == 0)
+ return TRUE;
+
+ for (i = 0; i < bfd_get_symcount (abfd); i++)
+ {
+ bfd_mach_o_asymbol *s = (bfd_mach_o_asymbol *)symbols[i];
+
+ /* We use this value, which is out-of-range as a symbol index, to signal
+ that the mach-o-specific data are not filled in and need to be created
+ from the bfd values. It is much preferable for the application to do
+ this, since more meaningful diagnostics can be made that way. */
+
+ if (s->symbol.udata.i == SYM_MACHO_FIELDS_UNSET)
+ {
+ /* No symbol information has been set - therefore determine
+ it from the bfd symbol flags/info. */
+ if (s->symbol.section == bfd_abs_section_ptr)
+ s->n_type = BFD_MACH_O_N_ABS;
+ else if (s->symbol.section == bfd_und_section_ptr)
+ {
+ s->n_type = BFD_MACH_O_N_UNDF;
+ if (s->symbol.flags & BSF_WEAK)
+ s->n_desc |= BFD_MACH_O_N_WEAK_REF;
+ /* mach-o automatically makes undefined symbols extern. */
+ s->n_type |= BFD_MACH_O_N_EXT;
+ s->symbol.flags |= BSF_GLOBAL;
+ }
+ else if (s->symbol.section == bfd_com_section_ptr)
+ {
+ s->n_type = BFD_MACH_O_N_UNDF | BFD_MACH_O_N_EXT;
+ s->symbol.flags |= BSF_GLOBAL;
+ }
+ else
+ s->n_type = BFD_MACH_O_N_SECT;
+
+ if (s->symbol.flags & BSF_GLOBAL)
+ s->n_type |= BFD_MACH_O_N_EXT;
+ }
+
+ /* Put the section index in, where required. */
+ if ((s->symbol.section != bfd_abs_section_ptr
+ && s->symbol.section != bfd_und_section_ptr
+ && s->symbol.section != bfd_com_section_ptr)
+ || ((s->n_type & BFD_MACH_O_N_STAB) != 0
+ && s->symbol.name == NULL))
+ s->n_sect = s->symbol.section->output_section->target_index;
+
+ /* Number to preserve order for local and debug syms. */
+ s->symbol.udata.i = i;
+ }
+
+ /* Sort the symbols. */
+ qsort ((void *) symbols, (size_t) bfd_get_symcount (abfd),
+ sizeof (asymbol *), bfd_mach_o_cf_symbols);
+
+ for (i = 0; i < bfd_get_symcount (abfd); ++i)
+ {
+ bfd_mach_o_asymbol *s = (bfd_mach_o_asymbol *)symbols[i];
+ s->symbol.udata.i = i; /* renumber. */
+ }
+
+ return TRUE;
+}
+
+/* We build a flat table of sections, which can be re-ordered if necessary.
+ Fill in the section number and other mach-o-specific data. */
+
+static bfd_boolean
+bfd_mach_o_mangle_sections (bfd *abfd, bfd_mach_o_data_struct *mdata)
+{
+ asection *sec;
+ unsigned target_index;
+ unsigned nsect;
+
+ nsect = bfd_count_sections (abfd);
+
+ /* Don't do it if it's already set - assume the application knows what it's
+ doing. */
+ if (mdata->nsects == nsect
+ && (mdata->nsects == 0 || mdata->sections != NULL))
+ return TRUE;
+
+ mdata->nsects = nsect;
+ mdata->sections = bfd_alloc (abfd,
+ mdata->nsects * sizeof (bfd_mach_o_section *));
+ if (mdata->sections == NULL)
+ return FALSE;
+
+ /* We need to check that this can be done... */
+ if (nsect > 255)
+ (*_bfd_error_handler) (_("mach-o: there are too many sections (%d)"
+ " maximum is 255,\n"), nsect);
+
+ /* Create Mach-O sections.
+ Section type, attribute and align should have been set when the
+ section was created - either read in or specified. */
+ target_index = 0;
+ for (sec = abfd->sections; sec; sec = sec->next)
+ {
+ unsigned bfd_align = bfd_get_section_alignment (abfd, sec);
+ bfd_mach_o_section *msect = bfd_mach_o_get_mach_o_section (sec);
+
+ mdata->sections[target_index] = msect;
+
+ msect->addr = bfd_get_section_vma (abfd, sec);
+ msect->size = bfd_get_section_size (sec);
+
+ /* Use the largest alignment set, in case it was bumped after the
+ section was created. */
+ msect->align = msect->align > bfd_align ? msect->align : bfd_align;
+
+ msect->offset = 0;
+ sec->target_index = ++target_index;
+ }
+
+ return TRUE;
+}
+
+bfd_boolean
+bfd_mach_o_write_contents (bfd *abfd)
+{
+ bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
+ bfd_mach_o_load_command *cmd;
+ bfd_mach_o_symtab_command *symtab = NULL;
+ bfd_mach_o_dysymtab_command *dysymtab = NULL;
+ bfd_mach_o_segment_command *linkedit = NULL;
+
+ /* Make the commands, if not already present. */
+ if (!abfd->output_has_begun && !bfd_mach_o_build_commands (abfd))
+ return FALSE;
+ abfd->output_has_begun = TRUE;
+
+ /* Write the header. */
+ if (!bfd_mach_o_write_header (abfd, &mdata->header))
+ return FALSE;
+
+ /* First pass: allocate the linkedit segment. */
+ for (cmd = mdata->first_command; cmd != NULL; cmd = cmd->next)
+ switch (cmd->type)
+ {
+ case BFD_MACH_O_LC_SEGMENT_64:
+ case BFD_MACH_O_LC_SEGMENT:
+ if (strcmp (cmd->command.segment.segname, "__LINKEDIT") == 0)
+ linkedit = &cmd->command.segment;
+ break;
+ case BFD_MACH_O_LC_SYMTAB:
+ symtab = &cmd->command.symtab;
+ break;
+ case BFD_MACH_O_LC_DYSYMTAB:
+ dysymtab = &cmd->command.dysymtab;
+ break;
+ case BFD_MACH_O_LC_DYLD_INFO:
+ {
+ bfd_mach_o_dyld_info_command *di = &cmd->command.dyld_info;
+
+ if (di->rebase_size != 0)
+ {
+ di->rebase_off = mdata->filelen;
+ mdata->filelen += di->rebase_size;
+ }
+ if (di->bind_size != 0)
+ {
+ di->bind_off = mdata->filelen;
+ mdata->filelen += di->bind_size;
+ }
+ if (di->weak_bind_size != 0)
+ {
+ di->weak_bind_off = mdata->filelen;
+ mdata->filelen += di->weak_bind_size;
+ }
+ if (di->lazy_bind_size != 0)
+ {
+ di->lazy_bind_off = mdata->filelen;
+ mdata->filelen += di->lazy_bind_size;
+ }
+ if (di->export_size != 0)
+ {
+ di->export_off = mdata->filelen;
+ mdata->filelen += di->export_size;
+ }
+ }
+ break;
+ case BFD_MACH_O_LC_LOAD_DYLIB:
+ case BFD_MACH_O_LC_LOAD_DYLINKER:
+ case BFD_MACH_O_LC_MAIN:
+ /* Nothing to do. */
+ break;
+ default:
+ (*_bfd_error_handler)
+ (_("unable to allocate data for load command 0x%lx"),
+ (unsigned long) cmd->type);
+ break;
+ }
+
+ /* Specially handle symtab and dysymtab. */
+
+ /* Pre-allocate the symbol table (but not the string table). The reason
+ is that the dysymtab is after the symbol table but before the string
+ table (required by the native strip tool). */
+ if (symtab != NULL)
+ {
+ unsigned int symlen;
+ unsigned int wide = bfd_mach_o_wide_p (abfd);
+
+ symlen = wide ? BFD_MACH_O_NLIST_64_SIZE : BFD_MACH_O_NLIST_SIZE;
+
+ /* Align for symbols. */
+ mdata->filelen = FILE_ALIGN (mdata->filelen, wide ? 3 : 2);
+ symtab->symoff = mdata->filelen;
+
+ symtab->nsyms = bfd_get_symcount (abfd);
+ mdata->filelen += symtab->nsyms * symlen;
+ }
+
+ /* Build the dysymtab. */
+ if (dysymtab != NULL)
+ if (!bfd_mach_o_build_dysymtab (abfd, dysymtab))
+ return FALSE;
+
+ /* Write symtab and strtab. */
+ if (symtab != NULL)
+ if (!bfd_mach_o_write_symtab_content (abfd, symtab))
+ return FALSE;
+
+ /* Adjust linkedit size. */
+ if (linkedit != NULL)
+ {
+ /* bfd_vma pagemask = bfd_mach_o_get_backend_data (abfd)->page_size - 1; */
+
+ linkedit->vmsize = mdata->filelen - linkedit->fileoff;
+ /* linkedit->vmsize = (linkedit->vmsize + pagemask) & ~pagemask; */
+ linkedit->filesize = mdata->filelen - linkedit->fileoff;
+
+ linkedit->initprot = BFD_MACH_O_PROT_READ;
+ linkedit->maxprot = BFD_MACH_O_PROT_READ | BFD_MACH_O_PROT_WRITE
+ | BFD_MACH_O_PROT_EXECUTE;
+ }
+
+ /* Second pass: write commands. */
+ for (cmd = mdata->first_command; cmd != NULL; cmd = cmd->next)
+ {
+ struct mach_o_load_command_external raw;
+ unsigned long typeflag;
+
+ typeflag = cmd->type | (cmd->type_required ? BFD_MACH_O_LC_REQ_DYLD : 0);
+
+ bfd_h_put_32 (abfd, typeflag, raw.cmd);
+ bfd_h_put_32 (abfd, cmd->len, raw.cmdsize);
+
+ if (bfd_seek (abfd, cmd->offset, SEEK_SET) != 0
+ || bfd_bwrite (&raw, BFD_MACH_O_LC_SIZE, abfd) != 8)
+ return FALSE;
+
+ switch (cmd->type)
+ {
+ case BFD_MACH_O_LC_SEGMENT:
+ if (!bfd_mach_o_write_segment_32 (abfd, cmd))
+ return FALSE;
+ break;
+ case BFD_MACH_O_LC_SEGMENT_64:
+ if (!bfd_mach_o_write_segment_64 (abfd, cmd))
+ return FALSE;
+ break;
+ case BFD_MACH_O_LC_SYMTAB:
+ if (!bfd_mach_o_write_symtab (abfd, cmd))
+ return FALSE;
+ break;
+ case BFD_MACH_O_LC_DYSYMTAB:
+ if (!bfd_mach_o_write_dysymtab (abfd, cmd))
+ return FALSE;
+ break;
+ case BFD_MACH_O_LC_THREAD:
+ case BFD_MACH_O_LC_UNIXTHREAD:
+ if (!bfd_mach_o_write_thread (abfd, cmd))
+ return FALSE;
+ break;
+ case BFD_MACH_O_LC_LOAD_DYLIB:
+ if (!bfd_mach_o_write_dylib (abfd, cmd))
+ return FALSE;
+ break;
+ case BFD_MACH_O_LC_LOAD_DYLINKER:
+ if (!bfd_mach_o_write_dylinker (abfd, cmd))
+ return FALSE;
+ break;
+ case BFD_MACH_O_LC_MAIN:
+ if (!bfd_mach_o_write_main (abfd, cmd))
+ return FALSE;
+ break;
+ case BFD_MACH_O_LC_DYLD_INFO:
+ if (!bfd_mach_o_write_dyld_info (abfd, cmd))
+ return FALSE;
+ break;
+ default:
+ (*_bfd_error_handler)
+ (_("unable to write unknown load command 0x%lx"),
+ (unsigned long) cmd->type);
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+static void
+bfd_mach_o_append_section_to_segment (bfd_mach_o_segment_command *seg,
+ bfd_mach_o_section *s)
+{
+ if (seg->sect_head == NULL)
+ seg->sect_head = s;
+ else
+ seg->sect_tail->next = s;
+ seg->sect_tail = s;
+}
+
+/* Create section Mach-O flags from BFD flags. */
+
+static void
+bfd_mach_o_set_section_flags_from_bfd (bfd *abfd ATTRIBUTE_UNUSED,
+ asection *sec)
+{
+ flagword bfd_flags;
+ bfd_mach_o_section *s = bfd_mach_o_get_mach_o_section (sec);
+
+ /* Create default flags. */
+ bfd_flags = bfd_get_section_flags (abfd, sec);
+ if ((bfd_flags & SEC_CODE) == SEC_CODE)
+ s->flags = BFD_MACH_O_S_ATTR_PURE_INSTRUCTIONS
+ | BFD_MACH_O_S_ATTR_SOME_INSTRUCTIONS
+ | BFD_MACH_O_S_REGULAR;
+ else if ((bfd_flags & (SEC_ALLOC | SEC_LOAD)) == SEC_ALLOC)
+ s->flags = BFD_MACH_O_S_ZEROFILL;
+ else if (bfd_flags & SEC_DEBUGGING)
+ s->flags = BFD_MACH_O_S_REGULAR | BFD_MACH_O_S_ATTR_DEBUG;
+ else
+ s->flags = BFD_MACH_O_S_REGULAR;
+}
+
+static bfd_boolean
+bfd_mach_o_build_obj_seg_command (bfd *abfd, bfd_mach_o_segment_command *seg)
+{
+ bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
+ unsigned int i, j;
+
+ seg->vmaddr = 0;
+ seg->fileoff = mdata->filelen;
+ seg->initprot = BFD_MACH_O_PROT_READ | BFD_MACH_O_PROT_WRITE
+ | BFD_MACH_O_PROT_EXECUTE;
+ seg->maxprot = seg->initprot;
+
+ /* Append sections to the segment.
+
+ This is a little tedious, we have to honor the need to account zerofill
+ sections after all the rest. This forces us to do the calculation of
+ total vmsize in three passes so that any alignment increments are
+ properly accounted. */
+ for (i = 0; i < mdata->nsects; ++i)
+ {
+ bfd_mach_o_section *s = mdata->sections[i];
+ asection *sec = s->bfdsection;
+
+ /* Although we account for zerofill section sizes in vm order, they are
+ placed in the file in source sequence. */
+ bfd_mach_o_append_section_to_segment (seg, s);
+ s->offset = 0;
+
+ /* Zerofill sections have zero file size & offset, the only content
+ written to the file is the symbols. */
+ if ((s->flags & BFD_MACH_O_SECTION_TYPE_MASK) == BFD_MACH_O_S_ZEROFILL
+ || ((s->flags & BFD_MACH_O_SECTION_TYPE_MASK)
+ == BFD_MACH_O_S_GB_ZEROFILL))
+ continue;
+
+ /* The Darwin system tools (in MH_OBJECT files, at least) always account
+ sections, even those with zero size. */
+ if (s->size > 0)
+ {
+ seg->vmsize = FILE_ALIGN (seg->vmsize, s->align);
+ seg->vmsize += s->size;
+
+ /* MH_OBJECT files have unaligned content. */
+ if (1)
+ {
+ seg->filesize = FILE_ALIGN (seg->filesize, s->align);
+ mdata->filelen = FILE_ALIGN (mdata->filelen, s->align);
+ }
+ seg->filesize += s->size;
+
+ /* The system tools write even zero-sized sections with an offset
+ field set to the current file position. */
+ s->offset = mdata->filelen;
+ }
+
+ sec->filepos = s->offset;
+ mdata->filelen += s->size;
+ }
+
+ /* Now pass through again, for zerofill, only now we just update the
+ vmsize, and then for zerofill_GB. */
+ for (j = 0; j < 2; j++)
+ {
+ unsigned int stype;
+
+ if (j == 0)
+ stype = BFD_MACH_O_S_ZEROFILL;
+ else
+ stype = BFD_MACH_O_S_GB_ZEROFILL;
+
+ for (i = 0; i < mdata->nsects; ++i)
+ {
+ bfd_mach_o_section *s = mdata->sections[i];
+
+ if ((s->flags & BFD_MACH_O_SECTION_TYPE_MASK) != stype)
+ continue;
+
+ if (s->size > 0)
+ {
+ seg->vmsize = FILE_ALIGN (seg->vmsize, s->align);
+ seg->vmsize += s->size;
+ }
+ }
+ }
+
+ /* Allocate space for the relocations. */
+ mdata->filelen = FILE_ALIGN (mdata->filelen, 2);
+
+ for (i = 0; i < mdata->nsects; ++i)
+ {
+ bfd_mach_o_section *ms = mdata->sections[i];
+ asection *sec = ms->bfdsection;
+
+ ms->nreloc = sec->reloc_count;
+ if (ms->nreloc == 0)
+ {
+ /* Clear nreloc and reloff if there is no relocs. */
+ ms->reloff = 0;
+ continue;
+ }
+ sec->rel_filepos = mdata->filelen;
+ ms->reloff = sec->rel_filepos;
+ mdata->filelen += sec->reloc_count * BFD_MACH_O_RELENT_SIZE;
+ }
+
+ return TRUE;
+}
+
+static bfd_boolean
+bfd_mach_o_build_exec_seg_command (bfd *abfd, bfd_mach_o_segment_command *seg)
+{
+ bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
+ unsigned int i;
+ bfd_vma pagemask = bfd_mach_o_get_backend_data (abfd)->page_size - 1;
+ bfd_vma vma;
+ bfd_mach_o_section *s;
+
+ seg->vmsize = 0;
+
+ seg->fileoff = mdata->filelen;
+ seg->maxprot = 0;
+ seg->initprot = 0;
+ seg->flags = 0;
+
+ /* Append sections to the segment. We assume they are properly ordered
+ by vma (but we check that). */
+ vma = 0;
+ for (i = 0; i < mdata->nsects; ++i)
+ {
+ s = mdata->sections[i];
+
+ /* Consider only sections for this segment. */
+ if (strcmp (seg->segname, s->segname) != 0)
+ continue;
+
+ bfd_mach_o_append_section_to_segment (seg, s);
+
+ BFD_ASSERT (s->addr >= vma);
+ vma = s->addr + s->size;
+ }
+
+ /* Set segment file offset: make it page aligned. */
+ vma = seg->sect_head->addr;
+ seg->vmaddr = vma & ~pagemask;
+ if ((mdata->filelen & pagemask) > (vma & pagemask))
+ mdata->filelen += pagemask + 1;
+ seg->fileoff = mdata->filelen & ~pagemask;
+ mdata->filelen = seg->fileoff + (vma & pagemask);
+
+ /* Set section file offset. */
+ for (s = seg->sect_head; s != NULL; s = s->next)
+ {
+ asection *sec = s->bfdsection;
+ flagword flags = bfd_get_section_flags (abfd, sec);
+
+ /* Adjust segment size. */
+ seg->vmsize = FILE_ALIGN (seg->vmsize, s->align);
+ seg->vmsize += s->size;
+
+ /* File offset and length. */
+ seg->filesize = FILE_ALIGN (seg->filesize, s->align);
+
+ if ((s->flags & BFD_MACH_O_SECTION_TYPE_MASK) != BFD_MACH_O_S_ZEROFILL
+ && ((s->flags & BFD_MACH_O_SECTION_TYPE_MASK)
+ != BFD_MACH_O_S_GB_ZEROFILL))
+ {
+ mdata->filelen = FILE_ALIGN (mdata->filelen, s->align);
+
+ s->offset = mdata->filelen;
+ s->bfdsection->filepos = s->offset;
+
+ seg->filesize += s->size;
+ mdata->filelen += s->size;
+ }
+ else
+ {
+ s->offset = 0;
+ s->bfdsection->filepos = 0;
+ }
+
+ /* Set protection. */
+ if (flags & SEC_LOAD)
+ {
+ if (flags & SEC_CODE)
+ seg->initprot |= BFD_MACH_O_PROT_READ | BFD_MACH_O_PROT_EXECUTE;
+ if ((flags & (SEC_DATA | SEC_READONLY)) == SEC_DATA)
+ seg->initprot |= BFD_MACH_O_PROT_WRITE | BFD_MACH_O_PROT_READ;
+ }
+
+ /* Relocs shouldn't appear in non-object files. */
+ if (s->bfdsection->reloc_count != 0)
+ return FALSE;
+ }
+
+ /* Set maxprot. */
+ if (seg->initprot != 0)
+ seg->maxprot = BFD_MACH_O_PROT_READ | BFD_MACH_O_PROT_WRITE
+ | BFD_MACH_O_PROT_EXECUTE;
+ else
+ seg->maxprot = 0;
+
+ /* Round segment size (and file size). */
+ seg->vmsize = (seg->vmsize + pagemask) & ~pagemask;
+ seg->filesize = (seg->filesize + pagemask) & ~pagemask;
+ mdata->filelen = (mdata->filelen + pagemask) & ~pagemask;
+
+ return TRUE;
+}
+
+/* Layout the commands: set commands size and offset, set ncmds and sizeofcmds
+ fields in header. */
+
+static void
+bfd_mach_o_layout_commands (bfd_mach_o_data_struct *mdata)
+{
+ unsigned wide = mach_o_wide_p (&mdata->header);
+ unsigned int hdrlen;
+ ufile_ptr offset;
+ bfd_mach_o_load_command *cmd;
+ unsigned int align;
+
+ hdrlen = wide ? BFD_MACH_O_HEADER_64_SIZE : BFD_MACH_O_HEADER_SIZE;
+ align = wide ? 8 - 1 : 4 - 1;
+ offset = hdrlen;
+ mdata->header.ncmds = 0;
+
+ for (cmd = mdata->first_command; cmd; cmd = cmd->next)
+ {
+ mdata->header.ncmds++;
+ cmd->offset = offset;
+
+ switch (cmd->type)
+ {
+ case BFD_MACH_O_LC_SEGMENT_64:
+ cmd->len = BFD_MACH_O_LC_SEGMENT_64_SIZE
+ + BFD_MACH_O_SECTION_64_SIZE * cmd->command.segment.nsects;
+ break;
+ case BFD_MACH_O_LC_SEGMENT:
+ cmd->len = BFD_MACH_O_LC_SEGMENT_SIZE
+ + BFD_MACH_O_SECTION_SIZE * cmd->command.segment.nsects;
+ break;
+ case BFD_MACH_O_LC_SYMTAB:
+ cmd->len = sizeof (struct mach_o_symtab_command_external)
+ + BFD_MACH_O_LC_SIZE;
+ break;
+ case BFD_MACH_O_LC_DYSYMTAB:
+ cmd->len = sizeof (struct mach_o_dysymtab_command_external)
+ + BFD_MACH_O_LC_SIZE;
+ break;
+ case BFD_MACH_O_LC_LOAD_DYLIB:
+ cmd->len = sizeof (struct mach_o_dylib_command_external)
+ + BFD_MACH_O_LC_SIZE;
+ cmd->command.dylib.name_offset = cmd->len;
+ cmd->len += strlen (cmd->command.dylib.name_str);
+ cmd->len = (cmd->len + align) & ~align;
+ break;
+ case BFD_MACH_O_LC_LOAD_DYLINKER:
+ cmd->len = sizeof (struct mach_o_str_command_external)
+ + BFD_MACH_O_LC_SIZE;
+ cmd->command.dylinker.name_offset = cmd->len;
+ cmd->len += strlen (cmd->command.dylinker.name_str);
+ cmd->len = (cmd->len + align) & ~align;
+ break;
+ case BFD_MACH_O_LC_MAIN:
+ cmd->len = sizeof (struct mach_o_entry_point_command_external)
+ + BFD_MACH_O_LC_SIZE;
+ break;
+ case BFD_MACH_O_LC_DYLD_INFO:
+ cmd->len = sizeof (struct mach_o_dyld_info_command_external)
+ + BFD_MACH_O_LC_SIZE;
+ break;
+ default:
+ (*_bfd_error_handler)
+ (_("unable to layout unknown load command 0x%lx"),
+ (unsigned long) cmd->type);
+ break;
+ }
+
+ BFD_ASSERT (cmd->len % (align + 1) == 0);
+ offset += cmd->len;
+ }
+ mdata->header.sizeofcmds = offset - hdrlen;
+ mdata->filelen = offset;
+}
+
+/* Subroutine of bfd_mach_o_build_commands: set type, name and nsects of a
+ segment. */
+
+static void
+bfd_mach_o_init_segment (bfd_mach_o_data_struct *mdata,
+ bfd_mach_o_load_command *cmd,
+ const char *segname, unsigned int nbr_sect)
+{
+ bfd_mach_o_segment_command *seg = &cmd->command.segment;
+ unsigned wide = mach_o_wide_p (&mdata->header);
+
+ /* Init segment command. */
+ cmd->type = wide ? BFD_MACH_O_LC_SEGMENT_64 : BFD_MACH_O_LC_SEGMENT;
+ cmd->type_required = FALSE;
+
+ strcpy (seg->segname, segname);
+ seg->nsects = nbr_sect;
+
+ seg->vmaddr = 0;
+ seg->vmsize = 0;
+
+ seg->fileoff = 0;
+ seg->filesize = 0;
+ seg->maxprot = 0;
+ seg->initprot = 0;
+ seg->flags = 0;
+ seg->sect_head = NULL;
+ seg->sect_tail = NULL;
+}
+
+/* Build Mach-O load commands (currently assuming an MH_OBJECT file).
+ TODO: Other file formats, rebuilding symtab/dysymtab commands for strip
+ and copy functionality. */
+
+bfd_boolean
+bfd_mach_o_build_commands (bfd *abfd)
+{
+ bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
+ unsigned wide = mach_o_wide_p (&mdata->header);
+ unsigned int nbr_segcmd = 0;
+ bfd_mach_o_load_command *commands;
+ unsigned int nbr_commands;
+ int symtab_idx = -1;
+ int dysymtab_idx = -1;
+ int main_idx = -1;
+ unsigned int i;
+
+ /* Return now if already built. */
+ if (mdata->header.ncmds != 0)
+ return TRUE;
+
+ /* Fill in the file type, if not already set. */
+ if (mdata->header.filetype == 0)
+ {
+ if (abfd->flags & EXEC_P)
+ mdata->header.filetype = BFD_MACH_O_MH_EXECUTE;
+ else if (abfd->flags & DYNAMIC)
+ mdata->header.filetype = BFD_MACH_O_MH_DYLIB;
+ else
+ mdata->header.filetype = BFD_MACH_O_MH_OBJECT;
+ }
+
+ /* If hasn't already been done, flatten sections list, and sort
+ if/when required. Must be done before the symbol table is adjusted,
+ since that depends on properly numbered sections. */
+ if (mdata->nsects == 0 || mdata->sections == NULL)
+ if (! bfd_mach_o_mangle_sections (abfd, mdata))
+ return FALSE;
+
+ /* Order the symbol table, fill-in/check mach-o specific fields and
+ partition out any indirect symbols. */
+ if (!bfd_mach_o_mangle_symbols (abfd))
+ return FALSE;
+
+ /* Segment commands. */
+ if (mdata->header.filetype == BFD_MACH_O_MH_OBJECT)
+ {
+ /* Only one segment for all the sections. But the segment is
+ optional if there is no sections. */
+ nbr_segcmd = (mdata->nsects > 0) ? 1 : 0;
+ }
+ else
+ {
+ bfd_mach_o_section *prev_sect = NULL;
+
+ /* One pagezero segment and one linkedit segment. */
+ nbr_segcmd = 2;
+
+ /* Create one segment for associated segment name in sections.
+ Assume that sections with the same segment name are consecutive. */
+ for (i = 0; i < mdata->nsects; i++)
+ {
+ bfd_mach_o_section *this_sect = mdata->sections[i];
+
+ if (prev_sect == NULL
+ || strcmp (prev_sect->segname, this_sect->segname) != 0)
+ {
+ nbr_segcmd++;
+ prev_sect = this_sect;
+ }
+ }
+ }
+
+ nbr_commands = nbr_segcmd;
+
+ /* One command for the symbol table (only if there are symbols. */
+ if (bfd_get_symcount (abfd) > 0)
+ symtab_idx = nbr_commands++;
+
+ /* FIXME:
+ This is a rather crude test for whether we should build a dysymtab. */
+ if (bfd_mach_o_should_emit_dysymtab ()
+ && bfd_get_symcount (abfd))
+ {
+ /* If there should be a case where a dysymtab could be emitted without
+ a symtab (seems improbable), this would need amending. */
+ dysymtab_idx = nbr_commands++;
+ }
+
+ /* Add an entry point command. */
+ if (mdata->header.filetype == BFD_MACH_O_MH_EXECUTE
+ && bfd_get_start_address (abfd) != 0)
+ main_idx = nbr_commands++;
+
+ /* Well, we must have a header, at least. */
+ mdata->filelen = wide ? BFD_MACH_O_HEADER_64_SIZE : BFD_MACH_O_HEADER_SIZE;
+
+ /* A bit unusual, but no content is valid;
+ as -n empty.s -o empty.o */
+ if (nbr_commands == 0)
+ {
+ /* Layout commands (well none...) and set headers command fields. */
+ bfd_mach_o_layout_commands (mdata);
+ return TRUE;
+ }
+
+ /* Create commands for segments (and symtabs), prepend them. */
+ commands = bfd_zalloc (abfd, nbr_commands * sizeof (bfd_mach_o_load_command));
+ if (commands == NULL)
+ return FALSE;
+ for (i = 0; i < nbr_commands - 1; i++)
+ commands[i].next = &commands[i + 1];
+ commands[nbr_commands - 1].next = mdata->first_command;
+ if (mdata->first_command == NULL)
+ mdata->last_command = &commands[nbr_commands - 1];
+ mdata->first_command = &commands[0];
+
+ if (mdata->header.filetype == BFD_MACH_O_MH_OBJECT && nbr_segcmd != 0)
+ {
+ /* For object file, there is only one segment. */
+ bfd_mach_o_init_segment (mdata, &commands[0], "", mdata->nsects);
+ }
+ else if (nbr_segcmd != 0)
+ {
+ bfd_mach_o_load_command *cmd;
+
+ BFD_ASSERT (nbr_segcmd >= 2);
+
+ /* The pagezero. */
+ cmd = &commands[0];
+ bfd_mach_o_init_segment (mdata, cmd, "__PAGEZERO", 0);
+
+ /* Segments from sections. */
+ cmd++;
+ for (i = 0; i < mdata->nsects;)
+ {
+ const char *segname = mdata->sections[i]->segname;
+ unsigned int nbr_sect = 1;
+
+ /* Count number of sections for this segment. */
+ for (i++; i < mdata->nsects; i++)
+ if (strcmp (mdata->sections[i]->segname, segname) == 0)
+ nbr_sect++;
+ else
+ break;
+
+ bfd_mach_o_init_segment (mdata, cmd, segname, nbr_sect);
+ cmd++;
+ }
+
+ /* The linkedit. */
+ bfd_mach_o_init_segment (mdata, cmd, "__LINKEDIT", 0);
+ }
+
+ if (symtab_idx >= 0)
+ {
+ /* Init symtab command. */
+ bfd_mach_o_load_command *cmd = &commands[symtab_idx];
+
+ cmd->type = BFD_MACH_O_LC_SYMTAB;
+ cmd->type_required = FALSE;
+ }
+
+ /* If required, setup symtab command, see comment above about the quality
+ of this test. */
+ if (dysymtab_idx >= 0)
+ {
+ bfd_mach_o_load_command *cmd = &commands[dysymtab_idx];
+
+ cmd->type = BFD_MACH_O_LC_DYSYMTAB;
+ cmd->type_required = FALSE;
+ }
+
+ /* Create the main command. */
+ if (main_idx >= 0)
+ {
+ bfd_mach_o_load_command *cmd = &commands[main_idx];
+
+ cmd->type = BFD_MACH_O_LC_MAIN;
+ cmd->type_required = TRUE;
+
+ cmd->command.main.entryoff = 0;
+ cmd->command.main.stacksize = 0;
+ }
+
+ /* Layout commands. */
+ bfd_mach_o_layout_commands (mdata);
+
+ /* So, now we have sized the commands and the filelen set to that.
+ Now we can build the segment command and set the section file offsets. */
+ if (mdata->header.filetype == BFD_MACH_O_MH_OBJECT)
+ {
+ for (i = 0; i < nbr_segcmd; i++)
+ if (!bfd_mach_o_build_obj_seg_command
+ (abfd, &commands[i].command.segment))
+ return FALSE;
+ }
+ else
+ {
+ bfd_vma maxvma = 0;
+
+ /* Skip pagezero and linkedit segments. */
+ for (i = 1; i < nbr_segcmd - 1; i++)
+ {
+ bfd_mach_o_segment_command *seg = &commands[i].command.segment;
+
+ if (!bfd_mach_o_build_exec_seg_command (abfd, seg))
+ return FALSE;
+
+ if (seg->vmaddr + seg->vmsize > maxvma)
+ maxvma = seg->vmaddr + seg->vmsize;
+ }
+
+ /* Set the size of __PAGEZERO. */
+ commands[0].command.segment.vmsize =
+ commands[1].command.segment.vmaddr;
+
+ /* Set the vma and fileoff of __LINKEDIT. */
+ commands[nbr_segcmd - 1].command.segment.vmaddr = maxvma;
+ commands[nbr_segcmd - 1].command.segment.fileoff = mdata->filelen;
+
+ /* Set entry point (once segments have been laid out). */
+ if (main_idx >= 0)
+ commands[main_idx].command.main.entryoff =
+ bfd_get_start_address (abfd) - commands[1].command.segment.vmaddr;
+ }
+
+ return TRUE;
+}
+
+/* Set the contents of a section. */
+
+bfd_boolean
+bfd_mach_o_set_section_contents (bfd *abfd,
+ asection *section,
+ const void * location,
+ file_ptr offset,
+ bfd_size_type count)
+{
+ file_ptr pos;
+
+ /* Trying to write the first section contents will trigger the creation of
+ the load commands if they are not already present. */
+ if (!abfd->output_has_begun && !bfd_mach_o_build_commands (abfd))
+ return FALSE;
+
+ if (count == 0)
+ return TRUE;
+
+ pos = section->filepos + offset;
+ if (bfd_seek (abfd, pos, SEEK_SET) != 0
+ || bfd_bwrite (location, count, abfd) != count)
+ return FALSE;
+
+ return TRUE;
+}
+
+int
+bfd_mach_o_sizeof_headers (bfd *a ATTRIBUTE_UNUSED,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+/* Make an empty symbol. This is required only because
+ bfd_make_section_anyway wants to create a symbol for the section. */
+
+asymbol *
+bfd_mach_o_make_empty_symbol (bfd *abfd)
+{
+ asymbol *new_symbol;
+
+ new_symbol = bfd_zalloc (abfd, sizeof (bfd_mach_o_asymbol));
+ if (new_symbol == NULL)
+ return new_symbol;
+ new_symbol->the_bfd = abfd;
+ new_symbol->udata.i = SYM_MACHO_FIELDS_UNSET;
+ return new_symbol;
+}
+
+static bfd_boolean
+bfd_mach_o_read_header (bfd *abfd, bfd_mach_o_header *header)
+{
+ struct mach_o_header_external raw;
+ unsigned int size;
+ bfd_vma (*get32) (const void *) = NULL;
+
+ /* Just read the magic number. */
+ if (bfd_seek (abfd, 0, SEEK_SET) != 0
+ || bfd_bread (raw.magic, sizeof (raw.magic), abfd) != 4)
+ return FALSE;
+
+ if (bfd_getb32 (raw.magic) == BFD_MACH_O_MH_MAGIC)
+ {
+ header->byteorder = BFD_ENDIAN_BIG;
+ header->magic = BFD_MACH_O_MH_MAGIC;
+ header->version = 1;
+ get32 = bfd_getb32;
+ }
+ else if (bfd_getl32 (raw.magic) == BFD_MACH_O_MH_MAGIC)
+ {
+ header->byteorder = BFD_ENDIAN_LITTLE;
+ header->magic = BFD_MACH_O_MH_MAGIC;
+ header->version = 1;
+ get32 = bfd_getl32;
+ }
+ else if (bfd_getb32 (raw.magic) == BFD_MACH_O_MH_MAGIC_64)
+ {
+ header->byteorder = BFD_ENDIAN_BIG;
+ header->magic = BFD_MACH_O_MH_MAGIC_64;
+ header->version = 2;
+ get32 = bfd_getb32;
+ }
+ else if (bfd_getl32 (raw.magic) == BFD_MACH_O_MH_MAGIC_64)
+ {
+ header->byteorder = BFD_ENDIAN_LITTLE;
+ header->magic = BFD_MACH_O_MH_MAGIC_64;
+ header->version = 2;
+ get32 = bfd_getl32;
+ }
+ else
+ {
+ header->byteorder = BFD_ENDIAN_UNKNOWN;
+ return FALSE;
+ }
+
+ /* Once the size of the header is known, read the full header. */
+ size = mach_o_wide_p (header) ?
+ BFD_MACH_O_HEADER_64_SIZE : BFD_MACH_O_HEADER_SIZE;
+
+ if (bfd_seek (abfd, 0, SEEK_SET) != 0
+ || bfd_bread (&raw, size, abfd) != size)
+ return FALSE;
+
+ header->cputype = (*get32) (raw.cputype);
+ header->cpusubtype = (*get32) (raw.cpusubtype);
+ header->filetype = (*get32) (raw.filetype);
+ header->ncmds = (*get32) (raw.ncmds);
+ header->sizeofcmds = (*get32) (raw.sizeofcmds);
+ header->flags = (*get32) (raw.flags);
+
+ if (mach_o_wide_p (header))
+ header->reserved = (*get32) (raw.reserved);
+ else
+ header->reserved = 0;
+
+ return TRUE;
+}
+
+bfd_boolean
+bfd_mach_o_new_section_hook (bfd *abfd, asection *sec)
+{
+ bfd_mach_o_section *s;
+ unsigned bfdalign = bfd_get_section_alignment (abfd, sec);
+
+ s = bfd_mach_o_get_mach_o_section (sec);
+ if (s == NULL)
+ {
+ flagword bfd_flags;
+ static const mach_o_section_name_xlat * xlat;
+
+ s = (bfd_mach_o_section *) bfd_zalloc (abfd, sizeof (*s));
+ if (s == NULL)
+ return FALSE;
+ sec->used_by_bfd = s;
+ s->bfdsection = sec;
+
+ /* Create the Darwin seg/sect name pair from the bfd name.
+ If this is a canonical name for which a specific paiting exists
+ there will also be defined flags, type, attribute and alignment
+ values. */
+ xlat = bfd_mach_o_convert_section_name_to_mach_o (abfd, sec, s);
+ if (xlat != NULL)
+ {
+ s->flags = xlat->macho_sectype | xlat->macho_secattr;
+ s->align = xlat->sectalign > bfdalign ? xlat->sectalign
+ : bfdalign;
+ (void) bfd_set_section_alignment (abfd, sec, s->align);
+ bfd_flags = bfd_get_section_flags (abfd, sec);
+ if (bfd_flags == SEC_NO_FLAGS)
+ bfd_set_section_flags (abfd, sec, xlat->bfd_flags);
+ }
+ else
+ /* Create default flags. */
+ bfd_mach_o_set_section_flags_from_bfd (abfd, sec);
+ }
+
+ return _bfd_generic_new_section_hook (abfd, sec);
+}
+
+static void
+bfd_mach_o_init_section_from_mach_o (bfd *abfd, asection *sec,
+ unsigned long prot)
+{
+ flagword flags;
+ bfd_mach_o_section *section;
+
+ flags = bfd_get_section_flags (abfd, sec);
+ section = bfd_mach_o_get_mach_o_section (sec);
+
+ /* TODO: see if we should use the xlat system for doing this by
+ preference and fall back to this for unknown sections. */
+
+ if (flags == SEC_NO_FLAGS)
+ {
+ /* Try to guess flags. */
+ if (section->flags & BFD_MACH_O_S_ATTR_DEBUG)
+ flags = SEC_DEBUGGING;
+ else
+ {
+ flags = SEC_ALLOC;
+ if ((section->flags & BFD_MACH_O_SECTION_TYPE_MASK)
+ != BFD_MACH_O_S_ZEROFILL)
+ {
+ flags |= SEC_LOAD;
+ if (prot & BFD_MACH_O_PROT_EXECUTE)
+ flags |= SEC_CODE;
+ if (prot & BFD_MACH_O_PROT_WRITE)
+ flags |= SEC_DATA;
+ else if (prot & BFD_MACH_O_PROT_READ)
+ flags |= SEC_READONLY;
+ }
+ }
+ }
+ else
+ {
+ if ((flags & SEC_DEBUGGING) == 0)
+ flags |= SEC_ALLOC;
+ }
+
+ if (section->offset != 0)
+ flags |= SEC_HAS_CONTENTS;
+ if (section->nreloc != 0)
+ flags |= SEC_RELOC;
+
+ bfd_set_section_flags (abfd, sec, flags);
+
+ sec->vma = section->addr;
+ sec->lma = section->addr;
+ sec->size = section->size;
+ sec->filepos = section->offset;
+ sec->alignment_power = section->align;
+ sec->segment_mark = 0;
+ sec->reloc_count = section->nreloc;
+ sec->rel_filepos = section->reloff;
+}
+
+static asection *
+bfd_mach_o_make_bfd_section (bfd *abfd,
+ const unsigned char *segname,
+ const unsigned char *sectname)
+{
+ const char *sname;
+ flagword flags;
+
+ bfd_mach_o_convert_section_name_to_bfd
+ (abfd, (const char *)segname, (const char *)sectname, &sname, &flags);
+ if (sname == NULL)
+ return NULL;
+
+ return bfd_make_section_anyway_with_flags (abfd, sname, flags);
+}
+
+static asection *
+bfd_mach_o_read_section_32 (bfd *abfd,
+ unsigned int offset,
+ unsigned long prot)
+{
+ struct mach_o_section_32_external raw;
+ asection *sec;
+ bfd_mach_o_section *section;
+
+ if (bfd_seek (abfd, offset, SEEK_SET) != 0
+ || (bfd_bread (&raw, BFD_MACH_O_SECTION_SIZE, abfd)
+ != BFD_MACH_O_SECTION_SIZE))
+ return NULL;
+
+ sec = bfd_mach_o_make_bfd_section (abfd, raw.segname, raw.sectname);
+ if (sec == NULL)
+ return NULL;
+
+ section = bfd_mach_o_get_mach_o_section (sec);
+ memcpy (section->segname, raw.segname, sizeof (raw.segname));
+ section->segname[BFD_MACH_O_SEGNAME_SIZE] = 0;
+ memcpy (section->sectname, raw.sectname, sizeof (raw.sectname));
+ section->sectname[BFD_MACH_O_SECTNAME_SIZE] = 0;
+ section->addr = bfd_h_get_32 (abfd, raw.addr);
+ section->size = bfd_h_get_32 (abfd, raw.size);
+ section->offset = bfd_h_get_32 (abfd, raw.offset);
+ section->align = bfd_h_get_32 (abfd, raw.align);
+ section->reloff = bfd_h_get_32 (abfd, raw.reloff);
+ section->nreloc = bfd_h_get_32 (abfd, raw.nreloc);
+ section->flags = bfd_h_get_32 (abfd, raw.flags);
+ section->reserved1 = bfd_h_get_32 (abfd, raw.reserved1);
+ section->reserved2 = bfd_h_get_32 (abfd, raw.reserved2);
+ section->reserved3 = 0;
+
+ bfd_mach_o_init_section_from_mach_o (abfd, sec, prot);
+
+ return sec;
+}
+
+static asection *
+bfd_mach_o_read_section_64 (bfd *abfd,
+ unsigned int offset,
+ unsigned long prot)
+{
+ struct mach_o_section_64_external raw;
+ asection *sec;
+ bfd_mach_o_section *section;
+
+ if (bfd_seek (abfd, offset, SEEK_SET) != 0
+ || (bfd_bread (&raw, BFD_MACH_O_SECTION_64_SIZE, abfd)
+ != BFD_MACH_O_SECTION_64_SIZE))
+ return NULL;
+
+ sec = bfd_mach_o_make_bfd_section (abfd, raw.segname, raw.sectname);
+ if (sec == NULL)
+ return NULL;
+
+ section = bfd_mach_o_get_mach_o_section (sec);
+ memcpy (section->segname, raw.segname, sizeof (raw.segname));
+ section->segname[BFD_MACH_O_SEGNAME_SIZE] = 0;
+ memcpy (section->sectname, raw.sectname, sizeof (raw.sectname));
+ section->sectname[BFD_MACH_O_SECTNAME_SIZE] = 0;
+ section->addr = bfd_h_get_64 (abfd, raw.addr);
+ section->size = bfd_h_get_64 (abfd, raw.size);
+ section->offset = bfd_h_get_32 (abfd, raw.offset);
+ section->align = bfd_h_get_32 (abfd, raw.align);
+ section->reloff = bfd_h_get_32 (abfd, raw.reloff);
+ section->nreloc = bfd_h_get_32 (abfd, raw.nreloc);
+ section->flags = bfd_h_get_32 (abfd, raw.flags);
+ section->reserved1 = bfd_h_get_32 (abfd, raw.reserved1);
+ section->reserved2 = bfd_h_get_32 (abfd, raw.reserved2);
+ section->reserved3 = bfd_h_get_32 (abfd, raw.reserved3);
+
+ bfd_mach_o_init_section_from_mach_o (abfd, sec, prot);
+
+ return sec;
+}
+
+static asection *
+bfd_mach_o_read_section (bfd *abfd,
+ unsigned int offset,
+ unsigned long prot,
+ unsigned int wide)
+{
+ if (wide)
+ return bfd_mach_o_read_section_64 (abfd, offset, prot);
+ else
+ return bfd_mach_o_read_section_32 (abfd, offset, prot);
+}
+
+static bfd_boolean
+bfd_mach_o_read_symtab_symbol (bfd *abfd,
+ bfd_mach_o_symtab_command *sym,
+ bfd_mach_o_asymbol *s,
+ unsigned long i)
+{
+ bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
+ unsigned int wide = mach_o_wide_p (&mdata->header);
+ unsigned int symwidth =
+ wide ? BFD_MACH_O_NLIST_64_SIZE : BFD_MACH_O_NLIST_SIZE;
+ unsigned int symoff = sym->symoff + (i * symwidth);
+ struct mach_o_nlist_64_external raw;
+ unsigned char type = -1;
+ unsigned char section = -1;
+ short desc = -1;
+ symvalue value = -1;
+ unsigned long stroff = -1;
+ unsigned int symtype = -1;
+
+ BFD_ASSERT (sym->strtab != NULL);
+
+ if (bfd_seek (abfd, symoff, SEEK_SET) != 0
+ || bfd_bread (&raw, symwidth, abfd) != symwidth)
+ {
+ (*_bfd_error_handler)
+ (_("bfd_mach_o_read_symtab_symbol: unable to read %d bytes at %lu"),
+ symwidth, (unsigned long) symoff);
+ return FALSE;
+ }
+
+ stroff = bfd_h_get_32 (abfd, raw.n_strx);
+ type = bfd_h_get_8 (abfd, raw.n_type);
+ symtype = type & BFD_MACH_O_N_TYPE;
+ section = bfd_h_get_8 (abfd, raw.n_sect);
+ desc = bfd_h_get_16 (abfd, raw.n_desc);
+ if (wide)
+ value = bfd_h_get_64 (abfd, raw.n_value);
+ else
+ value = bfd_h_get_32 (abfd, raw.n_value);
+
+ if (stroff >= sym->strsize)
+ {
+ (*_bfd_error_handler)
+ (_("bfd_mach_o_read_symtab_symbol: name out of range (%lu >= %lu)"),
+ (unsigned long) stroff,
+ (unsigned long) sym->strsize);
+ return FALSE;
+ }
+
+ s->symbol.the_bfd = abfd;
+ s->symbol.name = sym->strtab + stroff;
+ s->symbol.value = value;
+ s->symbol.flags = 0x0;
+ s->symbol.udata.i = i;
+ s->n_type = type;
+ s->n_sect = section;
+ s->n_desc = desc;
+
+ if (type & BFD_MACH_O_N_STAB)
+ {
+ s->symbol.flags |= BSF_DEBUGGING;
+ s->symbol.section = bfd_und_section_ptr;
+ switch (type)
+ {
+ case N_FUN:
+ case N_STSYM:
+ case N_LCSYM:
+ case N_BNSYM:
+ case N_SLINE:
+ case N_ENSYM:
+ case N_ECOMM:
+ case N_ECOML:
+ case N_GSYM:
+ if ((section > 0) && (section <= mdata->nsects))
+ {
+ s->symbol.section = mdata->sections[section - 1]->bfdsection;
+ s->symbol.value =
+ s->symbol.value - mdata->sections[section - 1]->addr;
+ }
+ break;
+ }
+ }
+ else
+ {
+ if (type & (BFD_MACH_O_N_PEXT | BFD_MACH_O_N_EXT))
+ s->symbol.flags |= BSF_GLOBAL;
+ else
+ s->symbol.flags |= BSF_LOCAL;
+
+ switch (symtype)
+ {
+ case BFD_MACH_O_N_UNDF:
+ if (type == (BFD_MACH_O_N_UNDF | BFD_MACH_O_N_EXT)
+ && s->symbol.value != 0)
+ {
+ /* A common symbol. */
+ s->symbol.section = bfd_com_section_ptr;
+ s->symbol.flags = BSF_NO_FLAGS;
+ }
+ else
+ {
+ s->symbol.section = bfd_und_section_ptr;
+ if (s->n_desc & BFD_MACH_O_N_WEAK_REF)
+ s->symbol.flags |= BSF_WEAK;
+ }
+ break;
+ case BFD_MACH_O_N_PBUD:
+ s->symbol.section = bfd_und_section_ptr;
+ break;
+ case BFD_MACH_O_N_ABS:
+ s->symbol.section = bfd_abs_section_ptr;
+ break;
+ case BFD_MACH_O_N_SECT:
+ if ((section > 0) && (section <= mdata->nsects))
+ {
+ s->symbol.section = mdata->sections[section - 1]->bfdsection;
+ s->symbol.value =
+ s->symbol.value - mdata->sections[section - 1]->addr;
+ }
+ else
+ {
+ /* Mach-O uses 0 to mean "no section"; not an error. */
+ if (section != 0)
+ {
+ (*_bfd_error_handler) (_("bfd_mach_o_read_symtab_symbol: "
+ "symbol \"%s\" specified invalid section %d (max %lu): setting to undefined"),
+ s->symbol.name, section, mdata->nsects);
+ }
+ s->symbol.section = bfd_und_section_ptr;
+ }
+ break;
+ case BFD_MACH_O_N_INDR:
+ /* FIXME: we don't follow the BFD convention as this indirect symbol
+ won't be followed by the referenced one. This looks harmless
+ unless we start using the linker. */
+ s->symbol.flags |= BSF_INDIRECT;
+ s->symbol.section = bfd_ind_section_ptr;
+ s->symbol.value = 0;
+ break;
+ default:
+ (*_bfd_error_handler) (_("bfd_mach_o_read_symtab_symbol: "
+ "symbol \"%s\" specified invalid type field 0x%x: setting to undefined"),
+ s->symbol.name, symtype);
+ s->symbol.section = bfd_und_section_ptr;
+ break;
+ }
+ }
+
+ return TRUE;
+}
+
+bfd_boolean
+bfd_mach_o_read_symtab_strtab (bfd *abfd)
+{
+ bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
+ bfd_mach_o_symtab_command *sym = mdata->symtab;
+
+ /* Fail if there is no symtab. */
+ if (sym == NULL)
+ return FALSE;
+
+ /* Success if already loaded. */
+ if (sym->strtab)
+ return TRUE;
+
+ if (abfd->flags & BFD_IN_MEMORY)
+ {
+ struct bfd_in_memory *b;
+
+ b = (struct bfd_in_memory *) abfd->iostream;
+
+ if ((sym->stroff + sym->strsize) > b->size)
+ {
+ bfd_set_error (bfd_error_file_truncated);
+ return FALSE;
+ }
+ sym->strtab = (char *) b->buffer + sym->stroff;
+ }
+ else
+ {
+ sym->strtab = bfd_alloc (abfd, sym->strsize);
+ if (sym->strtab == NULL)
+ return FALSE;
+
+ if (bfd_seek (abfd, sym->stroff, SEEK_SET) != 0
+ || bfd_bread (sym->strtab, sym->strsize, abfd) != sym->strsize)
+ {
+ bfd_set_error (bfd_error_file_truncated);
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+bfd_boolean
+bfd_mach_o_read_symtab_symbols (bfd *abfd)
+{
+ bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
+ bfd_mach_o_symtab_command *sym = mdata->symtab;
+ unsigned long i;
+
+ if (sym == NULL || sym->symbols)
+ {
+ /* Return now if there are no symbols or if already loaded. */
+ return TRUE;
+ }
+
+ sym->symbols = bfd_alloc (abfd, sym->nsyms * sizeof (bfd_mach_o_asymbol));
+
+ if (sym->symbols == NULL)
+ {
+ (*_bfd_error_handler) (_("bfd_mach_o_read_symtab_symbols: unable to allocate memory for symbols"));
+ return FALSE;
+ }
+
+ if (!bfd_mach_o_read_symtab_strtab (abfd))
+ return FALSE;
+
+ for (i = 0; i < sym->nsyms; i++)
+ {
+ if (!bfd_mach_o_read_symtab_symbol (abfd, sym, &sym->symbols[i], i))
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static const char *
+bfd_mach_o_i386_flavour_string (unsigned int flavour)
+{
+ switch ((int) flavour)
+ {
+ case BFD_MACH_O_x86_THREAD_STATE32: return "x86_THREAD_STATE32";
+ case BFD_MACH_O_x86_FLOAT_STATE32: return "x86_FLOAT_STATE32";
+ case BFD_MACH_O_x86_EXCEPTION_STATE32: return "x86_EXCEPTION_STATE32";
+ case BFD_MACH_O_x86_THREAD_STATE64: return "x86_THREAD_STATE64";
+ case BFD_MACH_O_x86_FLOAT_STATE64: return "x86_FLOAT_STATE64";
+ case BFD_MACH_O_x86_EXCEPTION_STATE64: return "x86_EXCEPTION_STATE64";
+ case BFD_MACH_O_x86_THREAD_STATE: return "x86_THREAD_STATE";
+ case BFD_MACH_O_x86_FLOAT_STATE: return "x86_FLOAT_STATE";
+ case BFD_MACH_O_x86_EXCEPTION_STATE: return "x86_EXCEPTION_STATE";
+ case BFD_MACH_O_x86_DEBUG_STATE32: return "x86_DEBUG_STATE32";
+ case BFD_MACH_O_x86_DEBUG_STATE64: return "x86_DEBUG_STATE64";
+ case BFD_MACH_O_x86_DEBUG_STATE: return "x86_DEBUG_STATE";
+ case BFD_MACH_O_x86_THREAD_STATE_NONE: return "x86_THREAD_STATE_NONE";
+ default: return "UNKNOWN";
+ }
+}
+
+static const char *
+bfd_mach_o_ppc_flavour_string (unsigned int flavour)
+{
+ switch ((int) flavour)
+ {
+ case BFD_MACH_O_PPC_THREAD_STATE: return "PPC_THREAD_STATE";
+ case BFD_MACH_O_PPC_FLOAT_STATE: return "PPC_FLOAT_STATE";
+ case BFD_MACH_O_PPC_EXCEPTION_STATE: return "PPC_EXCEPTION_STATE";
+ case BFD_MACH_O_PPC_VECTOR_STATE: return "PPC_VECTOR_STATE";
+ case BFD_MACH_O_PPC_THREAD_STATE64: return "PPC_THREAD_STATE64";
+ case BFD_MACH_O_PPC_EXCEPTION_STATE64: return "PPC_EXCEPTION_STATE64";
+ default: return "UNKNOWN";
+ }
+}
+
+static bfd_boolean
+bfd_mach_o_read_dylinker (bfd *abfd, bfd_mach_o_load_command *command)
+{
+ bfd_mach_o_dylinker_command *cmd = &command->command.dylinker;
+ struct mach_o_str_command_external raw;
+ unsigned int nameoff;
+ unsigned int namelen;
+
+ if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
+ || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
+ return FALSE;
+
+ nameoff = bfd_h_get_32 (abfd, raw.str);
+
+ cmd->name_offset = nameoff;
+ namelen = command->len - nameoff;
+ nameoff += command->offset;
+ cmd->name_str = bfd_alloc (abfd, namelen);
+ if (cmd->name_str == NULL)
+ return FALSE;
+ if (bfd_seek (abfd, nameoff, SEEK_SET) != 0
+ || bfd_bread (cmd->name_str, namelen, abfd) != namelen)
+ return FALSE;
+ return TRUE;
+}
+
+static bfd_boolean
+bfd_mach_o_read_dylib (bfd *abfd, bfd_mach_o_load_command *command)
+{
+ bfd_mach_o_dylib_command *cmd = &command->command.dylib;
+ struct mach_o_dylib_command_external raw;
+ unsigned int nameoff;
+ unsigned int namelen;
+
+ switch (command->type)
+ {
+ case BFD_MACH_O_LC_LOAD_DYLIB:
+ case BFD_MACH_O_LC_LAZY_LOAD_DYLIB:
+ case BFD_MACH_O_LC_LOAD_WEAK_DYLIB:
+ case BFD_MACH_O_LC_ID_DYLIB:
+ case BFD_MACH_O_LC_REEXPORT_DYLIB:
+ case BFD_MACH_O_LC_LOAD_UPWARD_DYLIB:
+ break;
+ default:
+ BFD_FAIL ();
+ return FALSE;
+ }
+
+ if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
+ || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
+ return FALSE;
+
+ nameoff = bfd_h_get_32 (abfd, raw.name);
+ cmd->timestamp = bfd_h_get_32 (abfd, raw.timestamp);
+ cmd->current_version = bfd_h_get_32 (abfd, raw.current_version);
+ cmd->compatibility_version = bfd_h_get_32 (abfd, raw.compatibility_version);
+
+ cmd->name_offset = command->offset + nameoff;
+ namelen = command->len - nameoff;
+ cmd->name_str = bfd_alloc (abfd, namelen);
+ if (cmd->name_str == NULL)
+ return FALSE;
+ if (bfd_seek (abfd, cmd->name_offset, SEEK_SET) != 0
+ || bfd_bread (cmd->name_str, namelen, abfd) != namelen)
+ return FALSE;
+ return TRUE;
+}
+
+static bfd_boolean
+bfd_mach_o_read_prebound_dylib (bfd *abfd,
+ bfd_mach_o_load_command *command)
+{
+ bfd_mach_o_prebound_dylib_command *cmd = &command->command.prebound_dylib;
+ struct mach_o_prebound_dylib_command_external raw;
+ unsigned int nameoff;
+ unsigned int modoff;
+ unsigned int str_len;
+ unsigned char *str;
+
+ if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
+ || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
+ return FALSE;
+
+ nameoff = bfd_h_get_32 (abfd, raw.name);
+ modoff = bfd_h_get_32 (abfd, raw.linked_modules);
+ if (nameoff > command->len || modoff > command->len)
+ return FALSE;
+
+ str_len = command->len - sizeof (raw);
+ str = bfd_alloc (abfd, str_len);
+ if (str == NULL)
+ return FALSE;
+ if (bfd_bread (str, str_len, abfd) != str_len)
+ return FALSE;
+
+ cmd->name_offset = command->offset + nameoff;
+ cmd->nmodules = bfd_h_get_32 (abfd, raw.nmodules);
+ cmd->linked_modules_offset = command->offset + modoff;
+
+ cmd->name_str = (char *)str + nameoff - (sizeof (raw) + BFD_MACH_O_LC_SIZE);
+ cmd->linked_modules = str + modoff - (sizeof (raw) + BFD_MACH_O_LC_SIZE);
+ return TRUE;
+}
+
+static bfd_boolean
+bfd_mach_o_read_prebind_cksum (bfd *abfd,
+ bfd_mach_o_load_command *command)
+{
+ bfd_mach_o_prebind_cksum_command *cmd = &command->command.prebind_cksum;
+ struct mach_o_prebind_cksum_command_external raw;
+
+ if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
+ || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
+ return FALSE;
+
+ cmd->cksum = bfd_get_32 (abfd, raw.cksum);
+ return TRUE;
+}
+
+static bfd_boolean
+bfd_mach_o_read_twolevel_hints (bfd *abfd,
+ bfd_mach_o_load_command *command)
+{
+ bfd_mach_o_twolevel_hints_command *cmd = &command->command.twolevel_hints;
+ struct mach_o_twolevel_hints_command_external raw;
+
+ if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
+ || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
+ return FALSE;
+
+ cmd->offset = bfd_get_32 (abfd, raw.offset);
+ cmd->nhints = bfd_get_32 (abfd, raw.nhints);
+ return TRUE;
+}
+
+static bfd_boolean
+bfd_mach_o_read_fvmlib (bfd *abfd, bfd_mach_o_load_command *command)
+{
+ bfd_mach_o_fvmlib_command *fvm = &command->command.fvmlib;
+ struct mach_o_fvmlib_command_external raw;
+ unsigned int nameoff;
+ unsigned int namelen;
+
+ if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
+ || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
+ return FALSE;
+
+ nameoff = bfd_h_get_32 (abfd, raw.name);
+ fvm->minor_version = bfd_h_get_32 (abfd, raw.minor_version);
+ fvm->header_addr = bfd_h_get_32 (abfd, raw.header_addr);
+
+ fvm->name_offset = command->offset + nameoff;
+ namelen = command->len - nameoff;
+ fvm->name_str = bfd_alloc (abfd, namelen);
+ if (fvm->name_str == NULL)
+ return FALSE;
+ if (bfd_seek (abfd, fvm->name_offset, SEEK_SET) != 0
+ || bfd_bread (fvm->name_str, namelen, abfd) != namelen)
+ return FALSE;
+ return TRUE;
+}
+
+static bfd_boolean
+bfd_mach_o_read_thread (bfd *abfd, bfd_mach_o_load_command *command)
+{
+ bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
+ bfd_mach_o_thread_command *cmd = &command->command.thread;
+ unsigned int offset;
+ unsigned int nflavours;
+ unsigned int i;
+
+ BFD_ASSERT ((command->type == BFD_MACH_O_LC_THREAD)
+ || (command->type == BFD_MACH_O_LC_UNIXTHREAD));
+
+ /* Count the number of threads. */
+ offset = 8;
+ nflavours = 0;
+ while (offset != command->len)
+ {
+ struct mach_o_thread_command_external raw;
+
+ if (offset >= command->len)
+ return FALSE;
+
+ if (bfd_seek (abfd, command->offset + offset, SEEK_SET) != 0
+ || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
+ return FALSE;
+
+ offset += sizeof (raw) + bfd_h_get_32 (abfd, raw.count) * 4;
+ nflavours++;
+ }
+
+ /* Allocate threads. */
+ cmd->flavours = bfd_alloc
+ (abfd, nflavours * sizeof (bfd_mach_o_thread_flavour));
+ if (cmd->flavours == NULL)
+ return FALSE;
+ cmd->nflavours = nflavours;
+
+ offset = 8;
+ nflavours = 0;
+ while (offset != command->len)
+ {
+ struct mach_o_thread_command_external raw;
+
+ if (offset >= command->len)
+ return FALSE;
+
+ if (nflavours >= cmd->nflavours)
+ return FALSE;
+
+ if (bfd_seek (abfd, command->offset + offset, SEEK_SET) != 0
+ || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
+ return FALSE;
+
+ cmd->flavours[nflavours].flavour = bfd_h_get_32 (abfd, raw.flavour);
+ cmd->flavours[nflavours].offset = command->offset + offset + sizeof (raw);
+ cmd->flavours[nflavours].size = bfd_h_get_32 (abfd, raw.count) * 4;
+ offset += cmd->flavours[nflavours].size + sizeof (raw);
+ nflavours++;
+ }
+
+ for (i = 0; i < nflavours; i++)
+ {
+ asection *bfdsec;
+ unsigned int snamelen;
+ char *sname;
+ const char *flavourstr;
+ const char *prefix = "LC_THREAD";
+ unsigned int j = 0;
+
+ switch (mdata->header.cputype)
+ {
+ case BFD_MACH_O_CPU_TYPE_POWERPC:
+ case BFD_MACH_O_CPU_TYPE_POWERPC_64:
+ flavourstr =
+ bfd_mach_o_ppc_flavour_string (cmd->flavours[i].flavour);
+ break;
+ case BFD_MACH_O_CPU_TYPE_I386:
+ case BFD_MACH_O_CPU_TYPE_X86_64:
+ flavourstr =
+ bfd_mach_o_i386_flavour_string (cmd->flavours[i].flavour);
+ break;
+ default:
+ flavourstr = "UNKNOWN_ARCHITECTURE";
+ break;
+ }
+
+ snamelen = strlen (prefix) + 1 + 20 + 1 + strlen (flavourstr) + 1;
+ sname = bfd_alloc (abfd, snamelen);
+ if (sname == NULL)
+ return FALSE;
+
+ for (;;)
+ {
+ sprintf (sname, "%s.%s.%u", prefix, flavourstr, j);
+ if (bfd_get_section_by_name (abfd, sname) == NULL)
+ break;
+ j++;
+ }
+
+ bfdsec = bfd_make_section_with_flags (abfd, sname, SEC_HAS_CONTENTS);
+
+ bfdsec->vma = 0;
+ bfdsec->lma = 0;
+ bfdsec->size = cmd->flavours[i].size;
+ bfdsec->filepos = cmd->flavours[i].offset;
+ bfdsec->alignment_power = 0x0;
+
+ cmd->section = bfdsec;
+ }
+
+ return TRUE;
+}
+
+static bfd_boolean
+bfd_mach_o_read_dysymtab (bfd *abfd, bfd_mach_o_load_command *command)
+{
+ bfd_mach_o_dysymtab_command *cmd = &command->command.dysymtab;
+ bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
+
+ BFD_ASSERT (command->type == BFD_MACH_O_LC_DYSYMTAB);
+
+ {
+ struct mach_o_dysymtab_command_external raw;
+
+ if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
+ || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
+ return FALSE;
+
+ cmd->ilocalsym = bfd_h_get_32 (abfd, raw.ilocalsym);
+ cmd->nlocalsym = bfd_h_get_32 (abfd, raw.nlocalsym);
+ cmd->iextdefsym = bfd_h_get_32 (abfd, raw.iextdefsym);
+ cmd->nextdefsym = bfd_h_get_32 (abfd, raw.nextdefsym);
+ cmd->iundefsym = bfd_h_get_32 (abfd, raw.iundefsym);
+ cmd->nundefsym = bfd_h_get_32 (abfd, raw.nundefsym);
+ cmd->tocoff = bfd_h_get_32 (abfd, raw.tocoff);
+ cmd->ntoc = bfd_h_get_32 (abfd, raw.ntoc);
+ cmd->modtaboff = bfd_h_get_32 (abfd, raw.modtaboff);
+ cmd->nmodtab = bfd_h_get_32 (abfd, raw.nmodtab);
+ cmd->extrefsymoff = bfd_h_get_32 (abfd, raw.extrefsymoff);
+ cmd->nextrefsyms = bfd_h_get_32 (abfd, raw.nextrefsyms);
+ cmd->indirectsymoff = bfd_h_get_32 (abfd, raw.indirectsymoff);
+ cmd->nindirectsyms = bfd_h_get_32 (abfd, raw.nindirectsyms);
+ cmd->extreloff = bfd_h_get_32 (abfd, raw.extreloff);
+ cmd->nextrel = bfd_h_get_32 (abfd, raw.nextrel);
+ cmd->locreloff = bfd_h_get_32 (abfd, raw.locreloff);
+ cmd->nlocrel = bfd_h_get_32 (abfd, raw.nlocrel);
+ }
+
+ if (cmd->nmodtab != 0)
+ {
+ unsigned int i;
+ int wide = bfd_mach_o_wide_p (abfd);
+ unsigned int module_len = wide ? 56 : 52;
+
+ cmd->dylib_module =
+ bfd_alloc (abfd, cmd->nmodtab * sizeof (bfd_mach_o_dylib_module));
+ if (cmd->dylib_module == NULL)
+ return FALSE;
+
+ if (bfd_seek (abfd, cmd->modtaboff, SEEK_SET) != 0)
+ return FALSE;
+
+ for (i = 0; i < cmd->nmodtab; i++)
+ {
+ bfd_mach_o_dylib_module *module = &cmd->dylib_module[i];
+ unsigned long v;
+ unsigned char buf[56];
+
+ if (bfd_bread ((void *) buf, module_len, abfd) != module_len)
+ return FALSE;
+
+ module->module_name_idx = bfd_h_get_32 (abfd, buf + 0);
+ module->iextdefsym = bfd_h_get_32 (abfd, buf + 4);
+ module->nextdefsym = bfd_h_get_32 (abfd, buf + 8);
+ module->irefsym = bfd_h_get_32 (abfd, buf + 12);
+ module->nrefsym = bfd_h_get_32 (abfd, buf + 16);
+ module->ilocalsym = bfd_h_get_32 (abfd, buf + 20);
+ module->nlocalsym = bfd_h_get_32 (abfd, buf + 24);
+ module->iextrel = bfd_h_get_32 (abfd, buf + 28);
+ module->nextrel = bfd_h_get_32 (abfd, buf + 32);
+ v = bfd_h_get_32 (abfd, buf +36);
+ module->iinit = v & 0xffff;
+ module->iterm = (v >> 16) & 0xffff;
+ v = bfd_h_get_32 (abfd, buf + 40);
+ module->ninit = v & 0xffff;
+ module->nterm = (v >> 16) & 0xffff;
+ if (wide)
+ {
+ module->objc_module_info_size = bfd_h_get_32 (abfd, buf + 44);
+ module->objc_module_info_addr = bfd_h_get_64 (abfd, buf + 48);
+ }
+ else
+ {
+ module->objc_module_info_addr = bfd_h_get_32 (abfd, buf + 44);
+ module->objc_module_info_size = bfd_h_get_32 (abfd, buf + 48);
+ }
+ }
+ }
+
+ if (cmd->ntoc != 0)
+ {
+ unsigned int i;
+
+ cmd->dylib_toc = bfd_alloc
+ (abfd, cmd->ntoc * sizeof (bfd_mach_o_dylib_table_of_content));
+ if (cmd->dylib_toc == NULL)
+ return FALSE;
+
+ if (bfd_seek (abfd, cmd->tocoff, SEEK_SET) != 0)
+ return FALSE;
+
+ for (i = 0; i < cmd->ntoc; i++)
+ {
+ struct mach_o_dylib_table_of_contents_external raw;
+ bfd_mach_o_dylib_table_of_content *toc = &cmd->dylib_toc[i];
+
+ if (bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
+ return FALSE;
+
+ toc->symbol_index = bfd_h_get_32 (abfd, raw.symbol_index);
+ toc->module_index = bfd_h_get_32 (abfd, raw.module_index);
+ }
+ }
+
+ if (cmd->nindirectsyms != 0)
+ {
+ unsigned int i;
+
+ cmd->indirect_syms = bfd_alloc
+ (abfd, cmd->nindirectsyms * sizeof (unsigned int));
+ if (cmd->indirect_syms == NULL)
+ return FALSE;
+
+ if (bfd_seek (abfd, cmd->indirectsymoff, SEEK_SET) != 0)
+ return FALSE;
+
+ for (i = 0; i < cmd->nindirectsyms; i++)
+ {
+ unsigned char raw[4];
+ unsigned int *is = &cmd->indirect_syms[i];
+
+ if (bfd_bread (raw, sizeof (raw), abfd) != sizeof (raw))
+ return FALSE;
+
+ *is = bfd_h_get_32 (abfd, raw);
+ }
+ }
+
+ if (cmd->nextrefsyms != 0)
+ {
+ unsigned long v;
+ unsigned int i;
+
+ cmd->ext_refs = bfd_alloc
+ (abfd, cmd->nextrefsyms * sizeof (bfd_mach_o_dylib_reference));
+ if (cmd->ext_refs == NULL)
+ return FALSE;
+
+ if (bfd_seek (abfd, cmd->extrefsymoff, SEEK_SET) != 0)
+ return FALSE;
+
+ for (i = 0; i < cmd->nextrefsyms; i++)
+ {
+ unsigned char raw[4];
+ bfd_mach_o_dylib_reference *ref = &cmd->ext_refs[i];
+
+ if (bfd_bread (raw, sizeof (raw), abfd) != sizeof (raw))
+ return FALSE;
+
+ /* Fields isym and flags are written as bit-fields, thus we need
+ a specific processing for endianness. */
+ v = bfd_h_get_32 (abfd, raw);
+ if (bfd_big_endian (abfd))
+ {
+ ref->isym = (v >> 8) & 0xffffff;
+ ref->flags = v & 0xff;
+ }
+ else
+ {
+ ref->isym = v & 0xffffff;
+ ref->flags = (v >> 24) & 0xff;
+ }
+ }
+ }
+
+ if (mdata->dysymtab)
+ return FALSE;
+ mdata->dysymtab = cmd;
+
+ return TRUE;
+}
+
+static bfd_boolean
+bfd_mach_o_read_symtab (bfd *abfd, bfd_mach_o_load_command *command)
+{
+ bfd_mach_o_symtab_command *symtab = &command->command.symtab;
+ bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
+ struct mach_o_symtab_command_external raw;
+
+ BFD_ASSERT (command->type == BFD_MACH_O_LC_SYMTAB);
+
+ if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
+ || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
+ return FALSE;
+
+ symtab->symoff = bfd_h_get_32 (abfd, raw.symoff);
+ symtab->nsyms = bfd_h_get_32 (abfd, raw.nsyms);
+ symtab->stroff = bfd_h_get_32 (abfd, raw.stroff);
+ symtab->strsize = bfd_h_get_32 (abfd, raw.strsize);
+ symtab->symbols = NULL;
+ symtab->strtab = NULL;
+
+ if (symtab->nsyms != 0)
+ abfd->flags |= HAS_SYMS;
+
+ if (mdata->symtab)
+ return FALSE;
+ mdata->symtab = symtab;
+ return TRUE;
+}
+
+static bfd_boolean
+bfd_mach_o_read_uuid (bfd *abfd, bfd_mach_o_load_command *command)
+{
+ bfd_mach_o_uuid_command *cmd = &command->command.uuid;
+
+ BFD_ASSERT (command->type == BFD_MACH_O_LC_UUID);
+
+ if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
+ || bfd_bread (cmd->uuid, 16, abfd) != 16)
+ return FALSE;
+
+ return TRUE;
+}
+
+static bfd_boolean
+bfd_mach_o_read_linkedit (bfd *abfd, bfd_mach_o_load_command *command)
+{
+ bfd_mach_o_linkedit_command *cmd = &command->command.linkedit;
+ struct mach_o_linkedit_data_command_external raw;
+
+ if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
+ || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
+ return FALSE;
+
+ cmd->dataoff = bfd_get_32 (abfd, raw.dataoff);
+ cmd->datasize = bfd_get_32 (abfd, raw.datasize);
+ return TRUE;
+}
+
+static bfd_boolean
+bfd_mach_o_read_str (bfd *abfd, bfd_mach_o_load_command *command)
+{
+ bfd_mach_o_str_command *cmd = &command->command.str;
+ struct mach_o_str_command_external raw;
+ unsigned long off;
+
+ if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
+ || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
+ return FALSE;
+
+ off = bfd_get_32 (abfd, raw.str);
+ cmd->stroff = command->offset + off;
+ cmd->str_len = command->len - off;
+ cmd->str = bfd_alloc (abfd, cmd->str_len);
+ if (cmd->str == NULL)
+ return FALSE;
+ if (bfd_seek (abfd, cmd->stroff, SEEK_SET) != 0
+ || bfd_bread ((void *) cmd->str, cmd->str_len, abfd) != cmd->str_len)
+ return FALSE;
+ return TRUE;
+}
+
+static unsigned char *
+bfd_mach_o_alloc_and_read (bfd *abfd, unsigned int off, unsigned int size)
+{
+ unsigned char *buf;
+
+ buf = bfd_alloc (abfd, size);
+ if (buf == NULL)
+ return NULL;
+ if (bfd_seek (abfd, off, SEEK_SET) != 0
+ || bfd_bread (buf, size, abfd) != size)
+ return NULL;
+ return buf;
+}
+
+static bfd_boolean
+bfd_mach_o_read_dyld_content (bfd *abfd, bfd_mach_o_dyld_info_command *cmd)
+{
+ /* Read rebase content. */
+ if (cmd->rebase_content == NULL && cmd->rebase_size != 0)
+ {
+ cmd->rebase_content =
+ bfd_mach_o_alloc_and_read (abfd, cmd->rebase_off, cmd->rebase_size);
+ if (cmd->rebase_content == NULL)
+ return FALSE;
+ }
+
+ /* Read bind content. */
+ if (cmd->bind_content == NULL && cmd->bind_size != 0)
+ {
+ cmd->bind_content =
+ bfd_mach_o_alloc_and_read (abfd, cmd->bind_off, cmd->bind_size);
+ if (cmd->bind_content == NULL)
+ return FALSE;
+ }
+
+ /* Read weak bind content. */
+ if (cmd->weak_bind_content == NULL && cmd->weak_bind_size != 0)
+ {
+ cmd->weak_bind_content = bfd_mach_o_alloc_and_read
+ (abfd, cmd->weak_bind_off, cmd->weak_bind_size);
+ if (cmd->weak_bind_content == NULL)
+ return FALSE;
+ }
+
+ /* Read lazy bind content. */
+ if (cmd->lazy_bind_content == NULL && cmd->lazy_bind_size != 0)
+ {
+ cmd->lazy_bind_content = bfd_mach_o_alloc_and_read
+ (abfd, cmd->lazy_bind_off, cmd->lazy_bind_size);
+ if (cmd->lazy_bind_content == NULL)
+ return FALSE;
+ }
+
+ /* Read export content. */
+ if (cmd->export_content == NULL && cmd->export_size != 0)
+ {
+ cmd->export_content = bfd_mach_o_alloc_and_read
+ (abfd, cmd->export_off, cmd->export_size);
+ if (cmd->export_content == NULL)
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static bfd_boolean
+bfd_mach_o_read_dyld_info (bfd *abfd, bfd_mach_o_load_command *command)
+{
+ bfd_mach_o_dyld_info_command *cmd = &command->command.dyld_info;
+ struct mach_o_dyld_info_command_external raw;
+
+ if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
+ || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
+ return FALSE;
+
+ cmd->rebase_off = bfd_get_32 (abfd, raw.rebase_off);
+ cmd->rebase_size = bfd_get_32 (abfd, raw.rebase_size);
+ cmd->rebase_content = NULL;
+ cmd->bind_off = bfd_get_32 (abfd, raw.bind_off);
+ cmd->bind_size = bfd_get_32 (abfd, raw.bind_size);
+ cmd->bind_content = NULL;
+ cmd->weak_bind_off = bfd_get_32 (abfd, raw.weak_bind_off);
+ cmd->weak_bind_size = bfd_get_32 (abfd, raw.weak_bind_size);
+ cmd->weak_bind_content = NULL;
+ cmd->lazy_bind_off = bfd_get_32 (abfd, raw.lazy_bind_off);
+ cmd->lazy_bind_size = bfd_get_32 (abfd, raw.lazy_bind_size);
+ cmd->lazy_bind_content = NULL;
+ cmd->export_off = bfd_get_32 (abfd, raw.export_off);
+ cmd->export_size = bfd_get_32 (abfd, raw.export_size);
+ cmd->export_content = NULL;
+ return TRUE;
+}
+
+static bfd_boolean
+bfd_mach_o_read_version_min (bfd *abfd, bfd_mach_o_load_command *command)
+{
+ bfd_mach_o_version_min_command *cmd = &command->command.version_min;
+ struct mach_o_version_min_command_external raw;
+ unsigned int ver;
+
+ if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
+ || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
+ return FALSE;
+
+ ver = bfd_get_32 (abfd, raw.version);
+ cmd->rel = ver >> 16;
+ cmd->maj = ver >> 8;
+ cmd->min = ver;
+ cmd->reserved = bfd_get_32 (abfd, raw.reserved);
+ return TRUE;
+}
+
+static bfd_boolean
+bfd_mach_o_read_encryption_info (bfd *abfd, bfd_mach_o_load_command *command)
+{
+ bfd_mach_o_encryption_info_command *cmd = &command->command.encryption_info;
+ struct mach_o_encryption_info_command_external raw;
+
+ if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
+ || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
+ return FALSE;
+
+ cmd->cryptoff = bfd_get_32 (abfd, raw.cryptoff);
+ cmd->cryptsize = bfd_get_32 (abfd, raw.cryptsize);
+ cmd->cryptid = bfd_get_32 (abfd, raw.cryptid);
+ return TRUE;
+}
+
+static bfd_boolean
+bfd_mach_o_read_main (bfd *abfd, bfd_mach_o_load_command *command)
+{
+ bfd_mach_o_main_command *cmd = &command->command.main;
+ struct mach_o_entry_point_command_external raw;
+
+ if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
+ || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
+ return FALSE;
+
+ cmd->entryoff = bfd_get_64 (abfd, raw.entryoff);
+ cmd->stacksize = bfd_get_64 (abfd, raw.stacksize);
+ return TRUE;
+}
+
+static bfd_boolean
+bfd_mach_o_read_source_version (bfd *abfd, bfd_mach_o_load_command *command)
+{
+ bfd_mach_o_source_version_command *cmd = &command->command.source_version;
+ struct mach_o_source_version_command_external raw;
+ bfd_uint64_t ver;
+
+ if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
+ || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
+ return FALSE;
+
+ ver = bfd_get_64 (abfd, raw.version);
+ /* Note: we use a serie of shift to avoid shift > 32 (for which gcc
+ generates warnings) in case of the host doesn't support 64 bit
+ integers. */
+ cmd->e = ver & 0x3ff;
+ ver >>= 10;
+ cmd->d = ver & 0x3ff;
+ ver >>= 10;
+ cmd->c = ver & 0x3ff;
+ ver >>= 10;
+ cmd->b = ver & 0x3ff;
+ ver >>= 10;
+ cmd->a = ver & 0xffffff;
+ return TRUE;
+}
+
+static bfd_boolean
+bfd_mach_o_read_segment (bfd *abfd,
+ bfd_mach_o_load_command *command,
+ unsigned int wide)
+{
+ bfd_mach_o_segment_command *seg = &command->command.segment;
+ unsigned long i;
+
+ if (wide)
+ {
+ struct mach_o_segment_command_64_external raw;
+
+ BFD_ASSERT (command->type == BFD_MACH_O_LC_SEGMENT_64);
+
+ if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
+ || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
+ return FALSE;
+
+ memcpy (seg->segname, raw.segname, 16);
+ seg->segname[16] = '\0';
+
+ seg->vmaddr = bfd_h_get_64 (abfd, raw.vmaddr);
+ seg->vmsize = bfd_h_get_64 (abfd, raw.vmsize);
+ seg->fileoff = bfd_h_get_64 (abfd, raw.fileoff);
+ seg->filesize = bfd_h_get_64 (abfd, raw.filesize);
+ seg->maxprot = bfd_h_get_32 (abfd, raw.maxprot);
+ seg->initprot = bfd_h_get_32 (abfd, raw.initprot);
+ seg->nsects = bfd_h_get_32 (abfd, raw.nsects);
+ seg->flags = bfd_h_get_32 (abfd, raw.flags);
+ }
+ else
+ {
+ struct mach_o_segment_command_32_external raw;
+
+ BFD_ASSERT (command->type == BFD_MACH_O_LC_SEGMENT);
+
+ if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
+ || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
+ return FALSE;
+
+ memcpy (seg->segname, raw.segname, 16);
+ seg->segname[16] = '\0';
+
+ seg->vmaddr = bfd_h_get_32 (abfd, raw.vmaddr);
+ seg->vmsize = bfd_h_get_32 (abfd, raw.vmsize);
+ seg->fileoff = bfd_h_get_32 (abfd, raw.fileoff);
+ seg->filesize = bfd_h_get_32 (abfd, raw.filesize);
+ seg->maxprot = bfd_h_get_32 (abfd, raw.maxprot);
+ seg->initprot = bfd_h_get_32 (abfd, raw.initprot);
+ seg->nsects = bfd_h_get_32 (abfd, raw.nsects);
+ seg->flags = bfd_h_get_32 (abfd, raw.flags);
+ }
+ seg->sect_head = NULL;
+ seg->sect_tail = NULL;
+
+ for (i = 0; i < seg->nsects; i++)
+ {
+ bfd_vma segoff;
+ asection *sec;
+
+ if (wide)
+ segoff = command->offset + BFD_MACH_O_LC_SEGMENT_64_SIZE
+ + (i * BFD_MACH_O_SECTION_64_SIZE);
+ else
+ segoff = command->offset + BFD_MACH_O_LC_SEGMENT_SIZE
+ + (i * BFD_MACH_O_SECTION_SIZE);
+
+ sec = bfd_mach_o_read_section (abfd, segoff, seg->initprot, wide);
+ if (sec == NULL)
+ return FALSE;
+
+ bfd_mach_o_append_section_to_segment
+ (seg, bfd_mach_o_get_mach_o_section (sec));
+ }
+
+ return TRUE;
+}
+
+static bfd_boolean
+bfd_mach_o_read_segment_32 (bfd *abfd, bfd_mach_o_load_command *command)
+{
+ return bfd_mach_o_read_segment (abfd, command, 0);
+}
+
+static bfd_boolean
+bfd_mach_o_read_segment_64 (bfd *abfd, bfd_mach_o_load_command *command)
+{
+ return bfd_mach_o_read_segment (abfd, command, 1);
+}
+
+static bfd_boolean
+bfd_mach_o_read_command (bfd *abfd, bfd_mach_o_load_command *command)
+{
+ struct mach_o_load_command_external raw;
+ unsigned int cmd;
+
+ /* Read command type and length. */
+ if (bfd_seek (abfd, command->offset, SEEK_SET) != 0
+ || bfd_bread (&raw, BFD_MACH_O_LC_SIZE, abfd) != BFD_MACH_O_LC_SIZE)
+ return FALSE;
+
+ cmd = bfd_h_get_32 (abfd, raw.cmd);
+ command->type = cmd & ~BFD_MACH_O_LC_REQ_DYLD;
+ command->type_required = cmd & BFD_MACH_O_LC_REQ_DYLD ? TRUE : FALSE;
+ command->len = bfd_h_get_32 (abfd, raw.cmdsize);
+
+ switch (command->type)
+ {
+ case BFD_MACH_O_LC_SEGMENT:
+ if (!bfd_mach_o_read_segment_32 (abfd, command))
+ return FALSE;
+ break;
+ case BFD_MACH_O_LC_SEGMENT_64:
+ if (!bfd_mach_o_read_segment_64 (abfd, command))
+ return FALSE;
+ break;
+ case BFD_MACH_O_LC_SYMTAB:
+ if (!bfd_mach_o_read_symtab (abfd, command))
+ return FALSE;
+ break;
+ case BFD_MACH_O_LC_SYMSEG:
+ break;
+ case BFD_MACH_O_LC_THREAD:
+ case BFD_MACH_O_LC_UNIXTHREAD:
+ if (!bfd_mach_o_read_thread (abfd, command))
+ return FALSE;
+ break;
+ case BFD_MACH_O_LC_LOAD_DYLINKER:
+ case BFD_MACH_O_LC_ID_DYLINKER:
+ case BFD_MACH_O_LC_DYLD_ENVIRONMENT:
+ if (!bfd_mach_o_read_dylinker (abfd, command))
+ return FALSE;
+ break;
+ case BFD_MACH_O_LC_LOAD_DYLIB:
+ case BFD_MACH_O_LC_LAZY_LOAD_DYLIB:
+ case BFD_MACH_O_LC_ID_DYLIB:
+ case BFD_MACH_O_LC_LOAD_WEAK_DYLIB:
+ case BFD_MACH_O_LC_REEXPORT_DYLIB:
+ case BFD_MACH_O_LC_LOAD_UPWARD_DYLIB:
+ if (!bfd_mach_o_read_dylib (abfd, command))
+ return FALSE;
+ break;
+ case BFD_MACH_O_LC_PREBOUND_DYLIB:
+ if (!bfd_mach_o_read_prebound_dylib (abfd, command))
+ return FALSE;
+ break;
+ case BFD_MACH_O_LC_LOADFVMLIB:
+ case BFD_MACH_O_LC_IDFVMLIB:
+ if (!bfd_mach_o_read_fvmlib (abfd, command))
+ return FALSE;
+ break;
+ case BFD_MACH_O_LC_IDENT:
+ case BFD_MACH_O_LC_FVMFILE:
+ case BFD_MACH_O_LC_PREPAGE:
+ case BFD_MACH_O_LC_ROUTINES:
+ case BFD_MACH_O_LC_ROUTINES_64:
+ break;
+ case BFD_MACH_O_LC_SUB_FRAMEWORK:
+ case BFD_MACH_O_LC_SUB_UMBRELLA:
+ case BFD_MACH_O_LC_SUB_LIBRARY:
+ case BFD_MACH_O_LC_SUB_CLIENT:
+ case BFD_MACH_O_LC_RPATH:
+ if (!bfd_mach_o_read_str (abfd, command))
+ return FALSE;
+ break;
+ case BFD_MACH_O_LC_DYSYMTAB:
+ if (!bfd_mach_o_read_dysymtab (abfd, command))
+ return FALSE;
+ break;
+ case BFD_MACH_O_LC_PREBIND_CKSUM:
+ if (!bfd_mach_o_read_prebind_cksum (abfd, command))
+ return FALSE;
+ break;
+ case BFD_MACH_O_LC_TWOLEVEL_HINTS:
+ if (!bfd_mach_o_read_twolevel_hints (abfd, command))
+ return FALSE;
+ break;
+ case BFD_MACH_O_LC_UUID:
+ if (!bfd_mach_o_read_uuid (abfd, command))
+ return FALSE;
+ break;
+ case BFD_MACH_O_LC_CODE_SIGNATURE:
+ case BFD_MACH_O_LC_SEGMENT_SPLIT_INFO:
+ case BFD_MACH_O_LC_FUNCTION_STARTS:
+ case BFD_MACH_O_LC_DATA_IN_CODE:
+ case BFD_MACH_O_LC_DYLIB_CODE_SIGN_DRS:
+ if (!bfd_mach_o_read_linkedit (abfd, command))
+ return FALSE;
+ break;
+ case BFD_MACH_O_LC_ENCRYPTION_INFO:
+ if (!bfd_mach_o_read_encryption_info (abfd, command))
+ return FALSE;
+ break;
+ case BFD_MACH_O_LC_DYLD_INFO:
+ if (!bfd_mach_o_read_dyld_info (abfd, command))
+ return FALSE;
+ break;
+ case BFD_MACH_O_LC_VERSION_MIN_MACOSX:
+ case BFD_MACH_O_LC_VERSION_MIN_IPHONEOS:
+ if (!bfd_mach_o_read_version_min (abfd, command))
+ return FALSE;
+ break;
+ case BFD_MACH_O_LC_MAIN:
+ if (!bfd_mach_o_read_main (abfd, command))
+ return FALSE;
+ break;
+ case BFD_MACH_O_LC_SOURCE_VERSION:
+ if (!bfd_mach_o_read_source_version (abfd, command))
+ return FALSE;
+ break;
+ default:
+ (*_bfd_error_handler)(_("%B: unknown load command 0x%lx"),
+ abfd, (unsigned long) command->type);
+ break;
+ }
+
+ return TRUE;
+}
+
+static void
+bfd_mach_o_flatten_sections (bfd *abfd)
+{
+ bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
+ bfd_mach_o_load_command *cmd;
+ long csect = 0;
+
+ /* Count total number of sections. */
+ mdata->nsects = 0;
+
+ for (cmd = mdata->first_command; cmd != NULL; cmd = cmd->next)
+ {
+ if (cmd->type == BFD_MACH_O_LC_SEGMENT
+ || cmd->type == BFD_MACH_O_LC_SEGMENT_64)
+ {
+ bfd_mach_o_segment_command *seg = &cmd->command.segment;
+
+ mdata->nsects += seg->nsects;
+ }
+ }
+
+ /* Allocate sections array. */
+ mdata->sections = bfd_alloc (abfd,
+ mdata->nsects * sizeof (bfd_mach_o_section *));
+
+ /* Fill the array. */
+ csect = 0;
+
+ for (cmd = mdata->first_command; cmd != NULL; cmd = cmd->next)
+ {
+ if (cmd->type == BFD_MACH_O_LC_SEGMENT
+ || cmd->type == BFD_MACH_O_LC_SEGMENT_64)
+ {
+ bfd_mach_o_segment_command *seg = &cmd->command.segment;
+ bfd_mach_o_section *sec;
+
+ BFD_ASSERT (csect + seg->nsects <= mdata->nsects);
+
+ for (sec = seg->sect_head; sec != NULL; sec = sec->next)
+ mdata->sections[csect++] = sec;
+ }
+ }
+}
+
+static bfd_boolean
+bfd_mach_o_scan_start_address (bfd *abfd)
+{
+ bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
+ bfd_mach_o_thread_command *thr = NULL;
+ bfd_mach_o_load_command *cmd;
+ unsigned long i;
+
+ for (cmd = mdata->first_command; cmd != NULL; cmd = cmd->next)
+ if (cmd->type == BFD_MACH_O_LC_THREAD
+ || cmd->type == BFD_MACH_O_LC_UNIXTHREAD)
+ {
+ thr = &cmd->command.thread;
+ break;
+ }
+ else if (cmd->type == BFD_MACH_O_LC_MAIN && mdata->nsects > 1)
+ {
+ bfd_mach_o_main_command *main_cmd = &cmd->command.main;
+ bfd_mach_o_section *text_sect = mdata->sections[0];
+
+ if (text_sect)
+ {
+ abfd->start_address = main_cmd->entryoff
+ + (text_sect->addr - text_sect->offset);
+ return TRUE;
+ }
+ }
+
+ /* An object file has no start address, so do not fail if not found. */
+ if (thr == NULL)
+ return TRUE;
+
+ /* FIXME: create a subtarget hook ? */
+ for (i = 0; i < thr->nflavours; i++)
+ {
+ if ((mdata->header.cputype == BFD_MACH_O_CPU_TYPE_I386)
+ && (thr->flavours[i].flavour == BFD_MACH_O_x86_THREAD_STATE32))
+ {
+ unsigned char buf[4];
+
+ if (bfd_seek (abfd, thr->flavours[i].offset + 40, SEEK_SET) != 0
+ || bfd_bread (buf, 4, abfd) != 4)
+ return FALSE;
+
+ abfd->start_address = bfd_h_get_32 (abfd, buf);
+ }
+ else if ((mdata->header.cputype == BFD_MACH_O_CPU_TYPE_POWERPC)
+ && (thr->flavours[i].flavour == BFD_MACH_O_PPC_THREAD_STATE))
+ {
+ unsigned char buf[4];
+
+ if (bfd_seek (abfd, thr->flavours[i].offset + 0, SEEK_SET) != 0
+ || bfd_bread (buf, 4, abfd) != 4)
+ return FALSE;
+
+ abfd->start_address = bfd_h_get_32 (abfd, buf);
+ }
+ else if ((mdata->header.cputype == BFD_MACH_O_CPU_TYPE_POWERPC_64)
+ && (thr->flavours[i].flavour == BFD_MACH_O_PPC_THREAD_STATE64))
+ {
+ unsigned char buf[8];
+
+ if (bfd_seek (abfd, thr->flavours[i].offset + 0, SEEK_SET) != 0
+ || bfd_bread (buf, 8, abfd) != 8)
+ return FALSE;
+
+ abfd->start_address = bfd_h_get_64 (abfd, buf);
+ }
+ else if ((mdata->header.cputype == BFD_MACH_O_CPU_TYPE_X86_64)
+ && (thr->flavours[i].flavour == BFD_MACH_O_x86_THREAD_STATE64))
+ {
+ unsigned char buf[8];
+
+ if (bfd_seek (abfd, thr->flavours[i].offset + (16 * 8), SEEK_SET) != 0
+ || bfd_bread (buf, 8, abfd) != 8)
+ return FALSE;
+
+ abfd->start_address = bfd_h_get_64 (abfd, buf);
+ }
+ }
+
+ return TRUE;
+}
+
+bfd_boolean
+bfd_mach_o_set_arch_mach (bfd *abfd,
+ enum bfd_architecture arch,
+ unsigned long machine)
+{
+ bfd_mach_o_backend_data *bed = bfd_mach_o_get_backend_data (abfd);
+
+ /* If this isn't the right architecture for this backend, and this
+ isn't the generic backend, fail. */
+ if (arch != bed->arch
+ && arch != bfd_arch_unknown
+ && bed->arch != bfd_arch_unknown)
+ return FALSE;
+
+ return bfd_default_set_arch_mach (abfd, arch, machine);
+}
+
+static bfd_boolean
+bfd_mach_o_scan (bfd *abfd,
+ bfd_mach_o_header *header,
+ bfd_mach_o_data_struct *mdata)
+{
+ unsigned int i;
+ enum bfd_architecture cputype;
+ unsigned long cpusubtype;
+ unsigned int hdrsize;
+
+ hdrsize = mach_o_wide_p (header) ?
+ BFD_MACH_O_HEADER_64_SIZE : BFD_MACH_O_HEADER_SIZE;
+
+ mdata->header = *header;
+
+ abfd->flags = abfd->flags & BFD_IN_MEMORY;
+ switch (header->filetype)
+ {
+ case BFD_MACH_O_MH_OBJECT:
+ abfd->flags |= HAS_RELOC;
+ break;
+ case BFD_MACH_O_MH_EXECUTE:
+ abfd->flags |= EXEC_P;
+ break;
+ case BFD_MACH_O_MH_DYLIB:
+ case BFD_MACH_O_MH_BUNDLE:
+ abfd->flags |= DYNAMIC;
+ break;
+ }
+
+ abfd->tdata.mach_o_data = mdata;
+
+ bfd_mach_o_convert_architecture (header->cputype, header->cpusubtype,
+ &cputype, &cpusubtype);
+ if (cputype == bfd_arch_unknown)
+ {
+ (*_bfd_error_handler)
+ (_("bfd_mach_o_scan: unknown architecture 0x%lx/0x%lx"),
+ header->cputype, header->cpusubtype);
+ return FALSE;
+ }
+
+ bfd_set_arch_mach (abfd, cputype, cpusubtype);
+
+ if (header->ncmds != 0)
+ {
+ bfd_mach_o_load_command *cmd;
+
+ mdata->first_command = NULL;
+ mdata->last_command = NULL;
+ cmd = bfd_alloc (abfd, header->ncmds * sizeof (bfd_mach_o_load_command));
+ if (cmd == NULL)
+ return FALSE;
+
+ for (i = 0; i < header->ncmds; i++)
+ {
+ bfd_mach_o_load_command *cur = &cmd[i];
+
+ bfd_mach_o_append_command (abfd, cur);
+
+ if (i == 0)
+ cur->offset = hdrsize;
+ else
+ {
+ bfd_mach_o_load_command *prev = &cmd[i - 1];
+ cur->offset = prev->offset + prev->len;
+ }
+
+ if (!bfd_mach_o_read_command (abfd, cur))
+ return FALSE;
+ }
+ }
+
+ /* Sections should be flatten before scanning start address. */
+ bfd_mach_o_flatten_sections (abfd);
+ if (!bfd_mach_o_scan_start_address (abfd))
+ return FALSE;
+
+ return TRUE;
+}
+
+bfd_boolean
+bfd_mach_o_mkobject_init (bfd *abfd)
+{
+ bfd_mach_o_data_struct *mdata = NULL;
+
+ mdata = bfd_zalloc (abfd, sizeof (bfd_mach_o_data_struct));
+ if (mdata == NULL)
+ return FALSE;
+ abfd->tdata.mach_o_data = mdata;
+
+ mdata->header.magic = 0;
+ mdata->header.cputype = 0;
+ mdata->header.cpusubtype = 0;
+ mdata->header.filetype = 0;
+ mdata->header.ncmds = 0;
+ mdata->header.sizeofcmds = 0;
+ mdata->header.flags = 0;
+ mdata->header.byteorder = BFD_ENDIAN_UNKNOWN;
+ mdata->first_command = NULL;
+ mdata->last_command = NULL;
+ mdata->nsects = 0;
+ mdata->sections = NULL;
+ mdata->dyn_reloc_cache = NULL;
+
+ return TRUE;
+}
+
+static bfd_boolean
+bfd_mach_o_gen_mkobject (bfd *abfd)
+{
+ bfd_mach_o_data_struct *mdata;
+
+ if (!bfd_mach_o_mkobject_init (abfd))
+ return FALSE;
+
+ mdata = bfd_mach_o_get_data (abfd);
+ mdata->header.magic = BFD_MACH_O_MH_MAGIC;
+ mdata->header.cputype = 0;
+ mdata->header.cpusubtype = 0;
+ mdata->header.byteorder = abfd->xvec->byteorder;
+ mdata->header.version = 1;
+
+ return TRUE;
+}
+
+const bfd_target *
+bfd_mach_o_header_p (bfd *abfd,
+ bfd_mach_o_filetype filetype,
+ bfd_mach_o_cpu_type cputype)
+{
+ bfd_mach_o_header header;
+ bfd_mach_o_data_struct *mdata;
+
+ if (!bfd_mach_o_read_header (abfd, &header))
+ goto wrong;
+
+ if (! (header.byteorder == BFD_ENDIAN_BIG
+ || header.byteorder == BFD_ENDIAN_LITTLE))
+ {
+ (*_bfd_error_handler) (_("unknown header byte-order value 0x%lx"),
+ (unsigned long) header.byteorder);
+ goto wrong;
+ }
+
+ if (! ((header.byteorder == BFD_ENDIAN_BIG
+ && abfd->xvec->byteorder == BFD_ENDIAN_BIG
+ && abfd->xvec->header_byteorder == BFD_ENDIAN_BIG)
+ || (header.byteorder == BFD_ENDIAN_LITTLE
+ && abfd->xvec->byteorder == BFD_ENDIAN_LITTLE
+ && abfd->xvec->header_byteorder == BFD_ENDIAN_LITTLE)))
+ goto wrong;
+
+ /* Check cputype and filetype.
+ In case of wildcard, do not accept magics that are handled by existing
+ targets. */
+ if (cputype)
+ {
+ if (header.cputype != cputype)
+ goto wrong;
+ }
+ else
+ {
+#ifndef BFD64
+ /* Do not recognize 64 architectures if not configured for 64bit targets.
+ This could happen only for generic targets. */
+ if (mach_o_wide_p (&header))
+ goto wrong;
+#endif
+ }
+
+ if (filetype)
+ {
+ if (header.filetype != filetype)
+ goto wrong;
+ }
+ else
+ {
+ switch (header.filetype)
+ {
+ case BFD_MACH_O_MH_CORE:
+ /* Handled by core_p */
+ goto wrong;
+ default:
+ break;
+ }
+ }
+
+ mdata = (bfd_mach_o_data_struct *) bfd_zalloc (abfd, sizeof (*mdata));
+ if (mdata == NULL)
+ goto fail;
+
+ if (!bfd_mach_o_scan (abfd, &header, mdata))
+ goto wrong;
+
+ return abfd->xvec;
+
+ wrong:
+ bfd_set_error (bfd_error_wrong_format);
+
+ fail:
+ return NULL;
+}
+
+static const bfd_target *
+bfd_mach_o_gen_object_p (bfd *abfd)
+{
+ return bfd_mach_o_header_p (abfd, 0, 0);
+}
+
+static const bfd_target *
+bfd_mach_o_gen_core_p (bfd *abfd)
+{
+ return bfd_mach_o_header_p (abfd, BFD_MACH_O_MH_CORE, 0);
+}
+
+/* Return the base address of ABFD, ie the address at which the image is
+ mapped. The possible initial pagezero is ignored. */
+
+bfd_vma
+bfd_mach_o_get_base_address (bfd *abfd)
+{
+ bfd_mach_o_data_struct *mdata;
+ bfd_mach_o_load_command *cmd;
+
+ /* Check for Mach-O. */
+ if (!bfd_mach_o_valid (abfd))
+ return 0;
+ mdata = bfd_mach_o_get_data (abfd);
+
+ for (cmd = mdata->first_command; cmd != NULL; cmd = cmd->next)
+ {
+ if ((cmd->type == BFD_MACH_O_LC_SEGMENT
+ || cmd->type == BFD_MACH_O_LC_SEGMENT_64))
+ {
+ struct bfd_mach_o_segment_command *segcmd = &cmd->command.segment;
+
+ if (segcmd->initprot != 0)
+ return segcmd->vmaddr;
+ }
+ }
+ return 0;
+}
+
+typedef struct mach_o_fat_archentry
+{
+ unsigned long cputype;
+ unsigned long cpusubtype;
+ unsigned long offset;
+ unsigned long size;
+ unsigned long align;
+} mach_o_fat_archentry;
+
+typedef struct mach_o_fat_data_struct
+{
+ unsigned long magic;
+ unsigned long nfat_arch;
+ mach_o_fat_archentry *archentries;
+} mach_o_fat_data_struct;
+
+const bfd_target *
+bfd_mach_o_archive_p (bfd *abfd)
+{
+ mach_o_fat_data_struct *adata = NULL;
+ struct mach_o_fat_header_external hdr;
+ unsigned long i;
+
+ if (bfd_seek (abfd, 0, SEEK_SET) != 0
+ || bfd_bread (&hdr, sizeof (hdr), abfd) != sizeof (hdr))
+ goto error;
+
+ adata = bfd_alloc (abfd, sizeof (mach_o_fat_data_struct));
+ if (adata == NULL)
+ goto error;
+
+ adata->magic = bfd_getb32 (hdr.magic);
+ adata->nfat_arch = bfd_getb32 (hdr.nfat_arch);
+ if (adata->magic != 0xcafebabe)
+ goto error;
+ /* Avoid matching Java bytecode files, which have the same magic number.
+ In the Java bytecode file format this field contains the JVM version,
+ which starts at 43.0. */
+ if (adata->nfat_arch > 30)
+ goto error;
+
+ adata->archentries =
+ bfd_alloc (abfd, adata->nfat_arch * sizeof (mach_o_fat_archentry));
+ if (adata->archentries == NULL)
+ goto error;
+
+ for (i = 0; i < adata->nfat_arch; i++)
+ {
+ struct mach_o_fat_arch_external arch;
+ if (bfd_bread (&arch, sizeof (arch), abfd) != sizeof (arch))
+ goto error;
+ adata->archentries[i].cputype = bfd_getb32 (arch.cputype);
+ adata->archentries[i].cpusubtype = bfd_getb32 (arch.cpusubtype);
+ adata->archentries[i].offset = bfd_getb32 (arch.offset);
+ adata->archentries[i].size = bfd_getb32 (arch.size);
+ adata->archentries[i].align = bfd_getb32 (arch.align);
+ }
+
+ abfd->tdata.mach_o_fat_data = adata;
+ return abfd->xvec;
+
+ error:
+ if (adata != NULL)
+ bfd_release (abfd, adata);
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+}
+
+/* Set the filename for a fat binary member ABFD, whose bfd architecture is
+ ARCH_TYPE/ARCH_SUBTYPE and corresponding entry in header is ENTRY.
+ Set arelt_data and origin fields too. */
+
+static void
+bfd_mach_o_fat_member_init (bfd *abfd,
+ enum bfd_architecture arch_type,
+ unsigned long arch_subtype,
+ mach_o_fat_archentry *entry)
+{
+ struct areltdata *areltdata;
+ /* Create the member filename. Use ARCH_NAME. */
+ const bfd_arch_info_type *ap = bfd_lookup_arch (arch_type, arch_subtype);
+
+ if (ap)
+ {
+ /* Use the architecture name if known. */
+ abfd->filename = xstrdup (ap->printable_name);
+ }
+ else
+ {
+ /* Forge a uniq id. */
+ const size_t namelen = 2 + 8 + 1 + 2 + 8 + 1;
+ char *name = xmalloc (namelen);
+ snprintf (name, namelen, "0x%lx-0x%lx",
+ entry->cputype, entry->cpusubtype);
+ abfd->filename = name;
+ }
+
+ areltdata = bfd_zmalloc (sizeof (struct areltdata));
+ areltdata->parsed_size = entry->size;
+ abfd->arelt_data = areltdata;
+ abfd->iostream = NULL;
+ abfd->origin = entry->offset;
+}
+
+bfd *
+bfd_mach_o_openr_next_archived_file (bfd *archive, bfd *prev)
+{
+ mach_o_fat_data_struct *adata;
+ mach_o_fat_archentry *entry = NULL;
+ unsigned long i;
+ bfd *nbfd;
+ enum bfd_architecture arch_type;
+ unsigned long arch_subtype;
+
+ adata = (mach_o_fat_data_struct *) archive->tdata.mach_o_fat_data;
+ BFD_ASSERT (adata != NULL);
+
+ /* Find index of previous entry. */
+ if (prev == NULL)
+ {
+ /* Start at first one. */
+ i = 0;
+ }
+ else
+ {
+ /* Find index of PREV. */
+ for (i = 0; i < adata->nfat_arch; i++)
+ {
+ if (adata->archentries[i].offset == prev->origin)
+ break;
+ }
+
+ if (i == adata->nfat_arch)
+ {
+ /* Not found. */
+ bfd_set_error (bfd_error_bad_value);
+ return NULL;
+ }
+
+ /* Get next entry. */
+ i++;
+ }
+
+ if (i >= adata->nfat_arch)
+ {
+ bfd_set_error (bfd_error_no_more_archived_files);
+ return NULL;
+ }
+
+ entry = &adata->archentries[i];
+ nbfd = _bfd_new_bfd_contained_in (archive);
+ if (nbfd == NULL)
+ return NULL;
+
+ bfd_mach_o_convert_architecture (entry->cputype, entry->cpusubtype,
+ &arch_type, &arch_subtype);
+
+ bfd_mach_o_fat_member_init (nbfd, arch_type, arch_subtype, entry);
+
+ bfd_set_arch_mach (nbfd, arch_type, arch_subtype);
+
+ return nbfd;
+}
+
+/* Analogous to stat call. */
+
+static int
+bfd_mach_o_fat_stat_arch_elt (bfd *abfd, struct stat *buf)
+{
+ if (abfd->arelt_data == NULL)
+ {
+ bfd_set_error (bfd_error_invalid_operation);
+ return -1;
+ }
+
+ buf->st_mtime = 0;
+ buf->st_uid = 0;
+ buf->st_gid = 0;
+ buf->st_mode = 0644;
+ buf->st_size = arelt_size (abfd);
+
+ return 0;
+}
+
+/* If ABFD format is FORMAT and architecture is ARCH, return it.
+ If ABFD is a fat image containing a member that corresponds to FORMAT
+ and ARCH, returns it.
+ In other case, returns NULL.
+ This function allows transparent uses of fat images. */
+
+bfd *
+bfd_mach_o_fat_extract (bfd *abfd,
+ bfd_format format,
+ const bfd_arch_info_type *arch)
+{
+ bfd *res;
+ mach_o_fat_data_struct *adata;
+ unsigned int i;
+
+ if (bfd_check_format (abfd, format))
+ {
+ if (bfd_get_arch_info (abfd) == arch)
+ return abfd;
+ return NULL;
+ }
+ if (!bfd_check_format (abfd, bfd_archive)
+ || abfd->xvec != &mach_o_fat_vec)
+ return NULL;
+
+ /* This is a Mach-O fat image. */
+ adata = (mach_o_fat_data_struct *) abfd->tdata.mach_o_fat_data;
+ BFD_ASSERT (adata != NULL);
+
+ for (i = 0; i < adata->nfat_arch; i++)
+ {
+ struct mach_o_fat_archentry *e = &adata->archentries[i];
+ enum bfd_architecture cpu_type;
+ unsigned long cpu_subtype;
+
+ bfd_mach_o_convert_architecture (e->cputype, e->cpusubtype,
+ &cpu_type, &cpu_subtype);
+ if (cpu_type != arch->arch || cpu_subtype != arch->mach)
+ continue;
+
+ /* The architecture is found. */
+ res = _bfd_new_bfd_contained_in (abfd);
+ if (res == NULL)
+ return NULL;
+
+ bfd_mach_o_fat_member_init (res, cpu_type, cpu_subtype, e);
+
+ if (bfd_check_format (res, format))
+ {
+ BFD_ASSERT (bfd_get_arch_info (res) == arch);
+ return res;
+ }
+ bfd_close (res);
+ return NULL;
+ }
+
+ return NULL;
+}
+
+int
+bfd_mach_o_lookup_command (bfd *abfd,
+ bfd_mach_o_load_command_type type,
+ bfd_mach_o_load_command **mcommand)
+{
+ struct mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
+ struct bfd_mach_o_load_command *cmd;
+ unsigned int num;
+
+ BFD_ASSERT (mdata != NULL);
+ BFD_ASSERT (mcommand != NULL);
+
+ num = 0;
+ for (cmd = mdata->first_command; cmd != NULL; cmd = cmd->next)
+ {
+ if (cmd->type != type)
+ continue;
+
+ if (num == 0)
+ *mcommand = cmd;
+ num++;
+ }
+
+ return num;
+}
+
+unsigned long
+bfd_mach_o_stack_addr (enum bfd_mach_o_cpu_type type)
+{
+ switch (type)
+ {
+ case BFD_MACH_O_CPU_TYPE_MC680x0:
+ return 0x04000000;
+ case BFD_MACH_O_CPU_TYPE_MC88000:
+ return 0xffffe000;
+ case BFD_MACH_O_CPU_TYPE_POWERPC:
+ return 0xc0000000;
+ case BFD_MACH_O_CPU_TYPE_I386:
+ return 0xc0000000;
+ case BFD_MACH_O_CPU_TYPE_SPARC:
+ return 0xf0000000;
+ case BFD_MACH_O_CPU_TYPE_I860:
+ return 0;
+ case BFD_MACH_O_CPU_TYPE_HPPA:
+ return 0xc0000000 - 0x04000000;
+ default:
+ return 0;
+ }
+}
+
+/* The following two tables should be kept, as far as possible, in order of
+ most frequently used entries to optimize their use from gas. */
+
+const bfd_mach_o_xlat_name bfd_mach_o_section_type_name[] =
+{
+ { "regular", BFD_MACH_O_S_REGULAR},
+ { "coalesced", BFD_MACH_O_S_COALESCED},
+ { "zerofill", BFD_MACH_O_S_ZEROFILL},
+ { "cstring_literals", BFD_MACH_O_S_CSTRING_LITERALS},
+ { "4byte_literals", BFD_MACH_O_S_4BYTE_LITERALS},
+ { "8byte_literals", BFD_MACH_O_S_8BYTE_LITERALS},
+ { "16byte_literals", BFD_MACH_O_S_16BYTE_LITERALS},
+ { "literal_pointers", BFD_MACH_O_S_LITERAL_POINTERS},
+ { "mod_init_func_pointers", BFD_MACH_O_S_MOD_INIT_FUNC_POINTERS},
+ { "mod_fini_func_pointers", BFD_MACH_O_S_MOD_FINI_FUNC_POINTERS},
+ { "gb_zerofill", BFD_MACH_O_S_GB_ZEROFILL},
+ { "interposing", BFD_MACH_O_S_INTERPOSING},
+ { "dtrace_dof", BFD_MACH_O_S_DTRACE_DOF},
+ { "non_lazy_symbol_pointers", BFD_MACH_O_S_NON_LAZY_SYMBOL_POINTERS},
+ { "lazy_symbol_pointers", BFD_MACH_O_S_LAZY_SYMBOL_POINTERS},
+ { "symbol_stubs", BFD_MACH_O_S_SYMBOL_STUBS},
+ { "lazy_dylib_symbol_pointers", BFD_MACH_O_S_LAZY_DYLIB_SYMBOL_POINTERS},
+ { NULL, 0}
+};
+
+const bfd_mach_o_xlat_name bfd_mach_o_section_attribute_name[] =
+{
+ { "pure_instructions", BFD_MACH_O_S_ATTR_PURE_INSTRUCTIONS },
+ { "some_instructions", BFD_MACH_O_S_ATTR_SOME_INSTRUCTIONS },
+ { "loc_reloc", BFD_MACH_O_S_ATTR_LOC_RELOC },
+ { "ext_reloc", BFD_MACH_O_S_ATTR_EXT_RELOC },
+ { "debug", BFD_MACH_O_S_ATTR_DEBUG },
+ { "live_support", BFD_MACH_O_S_ATTR_LIVE_SUPPORT },
+ { "no_dead_strip", BFD_MACH_O_S_ATTR_NO_DEAD_STRIP },
+ { "strip_static_syms", BFD_MACH_O_S_ATTR_STRIP_STATIC_SYMS },
+ { "no_toc", BFD_MACH_O_S_ATTR_NO_TOC },
+ { "self_modifying_code", BFD_MACH_O_S_SELF_MODIFYING_CODE },
+ { "modifying_code", BFD_MACH_O_S_SELF_MODIFYING_CODE },
+ { NULL, 0}
+};
+
+/* Get the section type from NAME. Return 256 if NAME is unknown. */
+
+unsigned int
+bfd_mach_o_get_section_type_from_name (bfd *abfd, const char *name)
+{
+ const bfd_mach_o_xlat_name *x;
+ bfd_mach_o_backend_data *bed = bfd_mach_o_get_backend_data (abfd);
+
+ for (x = bfd_mach_o_section_type_name; x->name; x++)
+ if (strcmp (x->name, name) == 0)
+ {
+ /* We found it... does the target support it? */
+ if (bed->bfd_mach_o_section_type_valid_for_target == NULL
+ || bed->bfd_mach_o_section_type_valid_for_target (x->val))
+ return x->val; /* OK. */
+ else
+ break; /* Not supported. */
+ }
+ /* Maximum section ID = 0xff. */
+ return 256;
+}
+
+/* Get the section attribute from NAME. Return -1 if NAME is unknown. */
+
+unsigned int
+bfd_mach_o_get_section_attribute_from_name (const char *name)
+{
+ const bfd_mach_o_xlat_name *x;
+
+ for (x = bfd_mach_o_section_attribute_name; x->name; x++)
+ if (strcmp (x->name, name) == 0)
+ return x->val;
+ return (unsigned int)-1;
+}
+
+int
+bfd_mach_o_core_fetch_environment (bfd *abfd,
+ unsigned char **rbuf,
+ unsigned int *rlen)
+{
+ bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
+ unsigned long stackaddr = bfd_mach_o_stack_addr (mdata->header.cputype);
+ bfd_mach_o_load_command *cmd;
+
+ for (cmd = mdata->first_command; cmd != NULL; cmd = cmd->next)
+ {
+ bfd_mach_o_segment_command *seg;
+
+ if (cmd->type != BFD_MACH_O_LC_SEGMENT)
+ continue;
+
+ seg = &cmd->command.segment;
+
+ if ((seg->vmaddr + seg->vmsize) == stackaddr)
+ {
+ unsigned long start = seg->fileoff;
+ unsigned long end = seg->fileoff + seg->filesize;
+ unsigned char *buf = bfd_malloc (1024);
+ unsigned long size = 1024;
+
+ for (;;)
+ {
+ bfd_size_type nread = 0;
+ unsigned long offset;
+ int found_nonnull = 0;
+
+ if (size > (end - start))
+ size = (end - start);
+
+ buf = bfd_realloc_or_free (buf, size);
+ if (buf == NULL)
+ return -1;
+
+ if (bfd_seek (abfd, end - size, SEEK_SET) != 0)
+ {
+ free (buf);
+ return -1;
+ }
+
+ nread = bfd_bread (buf, size, abfd);
+
+ if (nread != size)
+ {
+ free (buf);
+ return -1;
+ }
+
+ for (offset = 4; offset <= size; offset += 4)
+ {
+ unsigned long val;
+
+ val = *((unsigned long *) (buf + size - offset));
+ if (! found_nonnull)
+ {
+ if (val != 0)
+ found_nonnull = 1;
+ }
+ else if (val == 0x0)
+ {
+ unsigned long bottom;
+ unsigned long top;
+
+ bottom = seg->fileoff + seg->filesize - offset;
+ top = seg->fileoff + seg->filesize - 4;
+ *rbuf = bfd_malloc (top - bottom);
+ *rlen = top - bottom;
+
+ memcpy (*rbuf, buf + size - *rlen, *rlen);
+ free (buf);
+ return 0;
+ }
+ }
+
+ if (size == (end - start))
+ break;
+
+ size *= 2;
+ }
+
+ free (buf);
+ }
+ }
+
+ return -1;
+}
+
+char *
+bfd_mach_o_core_file_failing_command (bfd *abfd)
+{
+ unsigned char *buf = NULL;
+ unsigned int len = 0;
+ int ret;
+
+ ret = bfd_mach_o_core_fetch_environment (abfd, &buf, &len);
+ if (ret < 0)
+ return NULL;
+
+ return (char *) buf;
+}
+
+int
+bfd_mach_o_core_file_failing_signal (bfd *abfd ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+static bfd_mach_o_uuid_command *
+bfd_mach_o_lookup_uuid_command (bfd *abfd)
+{
+ bfd_mach_o_load_command *uuid_cmd;
+ int ncmd = bfd_mach_o_lookup_command (abfd, BFD_MACH_O_LC_UUID, &uuid_cmd);
+ if (ncmd != 1)
+ return FALSE;
+ return &uuid_cmd->command.uuid;
+}
+
+/* Return true if ABFD is a dSYM file and its UUID matches UUID_CMD. */
+
+static bfd_boolean
+bfd_mach_o_dsym_for_uuid_p (bfd *abfd, const bfd_mach_o_uuid_command *uuid_cmd)
+{
+ bfd_mach_o_uuid_command *dsym_uuid_cmd;
+
+ BFD_ASSERT (abfd);
+ BFD_ASSERT (uuid_cmd);
+
+ if (!bfd_check_format (abfd, bfd_object))
+ return FALSE;
+
+ if (bfd_get_flavour (abfd) != bfd_target_mach_o_flavour
+ || bfd_mach_o_get_data (abfd) == NULL
+ || bfd_mach_o_get_data (abfd)->header.filetype != BFD_MACH_O_MH_DSYM)
+ return FALSE;
+
+ dsym_uuid_cmd = bfd_mach_o_lookup_uuid_command (abfd);
+ if (dsym_uuid_cmd == NULL)
+ return FALSE;
+
+ if (memcmp (uuid_cmd->uuid, dsym_uuid_cmd->uuid,
+ sizeof (uuid_cmd->uuid)) != 0)
+ return FALSE;
+
+ return TRUE;
+}
+
+/* Find a BFD in DSYM_FILENAME which matches ARCH and UUID_CMD.
+ The caller is responsible for closing the returned BFD object and
+ its my_archive if the returned BFD is in a fat dSYM. */
+
+static bfd *
+bfd_mach_o_find_dsym (const char *dsym_filename,
+ const bfd_mach_o_uuid_command *uuid_cmd,
+ const bfd_arch_info_type *arch)
+{
+ bfd *base_dsym_bfd, *dsym_bfd;
+
+ BFD_ASSERT (uuid_cmd);
+
+ base_dsym_bfd = bfd_openr (dsym_filename, NULL);
+ if (base_dsym_bfd == NULL)
+ return NULL;
+
+ dsym_bfd = bfd_mach_o_fat_extract (base_dsym_bfd, bfd_object, arch);
+ if (bfd_mach_o_dsym_for_uuid_p (dsym_bfd, uuid_cmd))
+ return dsym_bfd;
+
+ bfd_close (dsym_bfd);
+ if (base_dsym_bfd != dsym_bfd)
+ bfd_close (base_dsym_bfd);
+
+ return NULL;
+}
+
+/* Return a BFD created from a dSYM file for ABFD.
+ The caller is responsible for closing the returned BFD object, its
+ filename, and its my_archive if the returned BFD is in a fat dSYM. */
+
+static bfd *
+bfd_mach_o_follow_dsym (bfd *abfd)
+{
+ char *dsym_filename;
+ bfd_mach_o_uuid_command *uuid_cmd;
+ bfd *dsym_bfd, *base_bfd = abfd;
+ const char *base_basename;
+
+ if (abfd == NULL || bfd_get_flavour (abfd) != bfd_target_mach_o_flavour)
+ return NULL;
+
+ if (abfd->my_archive)
+ base_bfd = abfd->my_archive;
+ /* BFD may have been opened from a stream. */
+ if (base_bfd->filename == NULL)
+ {
+ bfd_set_error (bfd_error_invalid_operation);
+ return NULL;
+ }
+ base_basename = lbasename (base_bfd->filename);
+
+ uuid_cmd = bfd_mach_o_lookup_uuid_command (abfd);
+ if (uuid_cmd == NULL)
+ return NULL;
+
+ /* TODO: We assume the DWARF file has the same as the binary's.
+ It seems apple's GDB checks all files in the dSYM bundle directory.
+ http://opensource.apple.com/source/gdb/gdb-1708/src/gdb/macosx/macosx-tdep.c
+ */
+ dsym_filename = (char *)bfd_malloc (strlen (base_bfd->filename)
+ + strlen (dsym_subdir) + 1
+ + strlen (base_basename) + 1);
+ sprintf (dsym_filename, "%s%s/%s",
+ base_bfd->filename, dsym_subdir, base_basename);
+
+ dsym_bfd = bfd_mach_o_find_dsym (dsym_filename, uuid_cmd,
+ bfd_get_arch_info (abfd));
+ if (dsym_bfd == NULL)
+ free (dsym_filename);
+
+ return dsym_bfd;
+}
+
+bfd_boolean
+bfd_mach_o_find_nearest_line (bfd *abfd,
+ asymbol **symbols,
+ asection *section,
+ bfd_vma offset,
+ const char **filename_ptr,
+ const char **functionname_ptr,
+ unsigned int *line_ptr,
+ unsigned int *discriminator_ptr)
+{
+ bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
+ if (mdata == NULL)
+ return FALSE;
+ switch (mdata->header.filetype)
+ {
+ case BFD_MACH_O_MH_OBJECT:
+ break;
+ case BFD_MACH_O_MH_EXECUTE:
+ case BFD_MACH_O_MH_DYLIB:
+ case BFD_MACH_O_MH_BUNDLE:
+ case BFD_MACH_O_MH_KEXT_BUNDLE:
+ if (mdata->dwarf2_find_line_info == NULL)
+ {
+ mdata->dsym_bfd = bfd_mach_o_follow_dsym (abfd);
+ /* When we couldn't find dSYM for this binary, we look for
+ the debug information in the binary itself. In this way,
+ we won't try finding separated dSYM again because
+ mdata->dwarf2_find_line_info will be filled. */
+ if (! mdata->dsym_bfd)
+ break;
+ if (! _bfd_dwarf2_slurp_debug_info (abfd, mdata->dsym_bfd,
+ dwarf_debug_sections, symbols,
+ &mdata->dwarf2_find_line_info,
+ FALSE))
+ return FALSE;
+ }
+ break;
+ default:
+ return FALSE;
+ }
+ return _bfd_dwarf2_find_nearest_line (abfd, symbols, NULL, section, offset,
+ filename_ptr, functionname_ptr,
+ line_ptr, discriminator_ptr,
+ dwarf_debug_sections, 0,
+ &mdata->dwarf2_find_line_info);
+}
+
+bfd_boolean
+bfd_mach_o_close_and_cleanup (bfd *abfd)
+{
+ bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
+ if (bfd_get_format (abfd) == bfd_object && mdata != NULL)
+ {
+ _bfd_dwarf2_cleanup_debug_info (abfd, &mdata->dwarf2_find_line_info);
+ bfd_mach_o_free_cached_info (abfd);
+ if (mdata->dsym_bfd != NULL)
+ {
+ bfd *fat_bfd = mdata->dsym_bfd->my_archive;
+ char *dsym_filename = (char *)(fat_bfd
+ ? fat_bfd->filename
+ : mdata->dsym_bfd->filename);
+ bfd_close (mdata->dsym_bfd);
+ mdata->dsym_bfd = NULL;
+ if (fat_bfd)
+ bfd_close (fat_bfd);
+ free (dsym_filename);
+ }
+ }
+
+ if (bfd_get_format (abfd) == bfd_archive
+ && abfd->xvec == &mach_o_fat_vec)
+ return TRUE;
+ return _bfd_generic_close_and_cleanup (abfd);
+}
+
+bfd_boolean bfd_mach_o_free_cached_info (bfd *abfd)
+{
+ bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
+ asection *asect;
+ free (mdata->dyn_reloc_cache);
+ mdata->dyn_reloc_cache = NULL;
+ for (asect = abfd->sections; asect != NULL; asect = asect->next)
+ {
+ free (asect->relocation);
+ asect->relocation = NULL;
+ }
+
+ return TRUE;
+}
+
+#define bfd_mach_o_bfd_reloc_type_lookup _bfd_norelocs_bfd_reloc_type_lookup
+#define bfd_mach_o_bfd_reloc_name_lookup _bfd_norelocs_bfd_reloc_name_lookup
+
+#define bfd_mach_o_swap_reloc_in NULL
+#define bfd_mach_o_swap_reloc_out NULL
+#define bfd_mach_o_print_thread NULL
+#define bfd_mach_o_tgt_seg_table NULL
+#define bfd_mach_o_section_type_valid_for_tgt NULL
+
+#define TARGET_NAME mach_o_be_vec
+#define TARGET_STRING "mach-o-be"
+#define TARGET_ARCHITECTURE bfd_arch_unknown
+#define TARGET_PAGESIZE 1
+#define TARGET_BIG_ENDIAN 1
+#define TARGET_ARCHIVE 0
+#define TARGET_PRIORITY 1
+#include "mach-o-target.c"
+
+#undef TARGET_NAME
+#undef TARGET_STRING
+#undef TARGET_ARCHITECTURE
+#undef TARGET_PAGESIZE
+#undef TARGET_BIG_ENDIAN
+#undef TARGET_ARCHIVE
+#undef TARGET_PRIORITY
+
+#define TARGET_NAME mach_o_le_vec
+#define TARGET_STRING "mach-o-le"
+#define TARGET_ARCHITECTURE bfd_arch_unknown
+#define TARGET_PAGESIZE 1
+#define TARGET_BIG_ENDIAN 0
+#define TARGET_ARCHIVE 0
+#define TARGET_PRIORITY 1
+
+#include "mach-o-target.c"
+
+#undef TARGET_NAME
+#undef TARGET_STRING
+#undef TARGET_ARCHITECTURE
+#undef TARGET_PAGESIZE
+#undef TARGET_BIG_ENDIAN
+#undef TARGET_ARCHIVE
+#undef TARGET_PRIORITY
+
+/* Not yet handled: creating an archive. */
+#define bfd_mach_o_mkarchive _bfd_noarchive_mkarchive
+
+/* Not used. */
+#define bfd_mach_o_read_ar_hdr _bfd_noarchive_read_ar_hdr
+#define bfd_mach_o_write_ar_hdr _bfd_noarchive_write_ar_hdr
+#define bfd_mach_o_slurp_armap _bfd_noarchive_slurp_armap
+#define bfd_mach_o_slurp_extended_name_table _bfd_noarchive_slurp_extended_name_table
+#define bfd_mach_o_construct_extended_name_table _bfd_noarchive_construct_extended_name_table
+#define bfd_mach_o_truncate_arname _bfd_noarchive_truncate_arname
+#define bfd_mach_o_write_armap _bfd_noarchive_write_armap
+#define bfd_mach_o_get_elt_at_index _bfd_noarchive_get_elt_at_index
+#define bfd_mach_o_generic_stat_arch_elt bfd_mach_o_fat_stat_arch_elt
+#define bfd_mach_o_update_armap_timestamp _bfd_noarchive_update_armap_timestamp
+
+#define TARGET_NAME mach_o_fat_vec
+#define TARGET_STRING "mach-o-fat"
+#define TARGET_ARCHITECTURE bfd_arch_unknown
+#define TARGET_PAGESIZE 1
+#define TARGET_BIG_ENDIAN 1
+#define TARGET_ARCHIVE 1
+#define TARGET_PRIORITY 0
+
+#include "mach-o-target.c"
+
+#undef TARGET_NAME
+#undef TARGET_STRING
+#undef TARGET_ARCHITECTURE
+#undef TARGET_PAGESIZE
+#undef TARGET_BIG_ENDIAN
+#undef TARGET_ARCHIVE
+#undef TARGET_PRIORITY
diff --git a/bfd/mach-o.h b/bfd/mach-o.h
new file mode 100644
index 0000000..afe2dee
--- /dev/null
+++ b/bfd/mach-o.h
@@ -0,0 +1,749 @@
+/* Mach-O support for BFD.
+ Copyright (C) 1999-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#ifndef _BFD_MACH_O_H_
+#define _BFD_MACH_O_H_
+
+#include "bfd.h"
+#include "mach-o/loader.h"
+
+typedef struct bfd_mach_o_header
+{
+ unsigned long magic;
+ unsigned long cputype;
+ unsigned long cpusubtype;
+ unsigned long filetype;
+ unsigned long ncmds;
+ unsigned long sizeofcmds;
+ unsigned long flags;
+ unsigned int reserved;
+ /* Version 1: 32 bits, version 2: 64 bits. */
+ unsigned int version;
+ enum bfd_endian byteorder;
+}
+bfd_mach_o_header;
+
+typedef struct bfd_mach_o_asymbol
+{
+ /* The actual symbol which the rest of BFD works with. */
+ asymbol symbol;
+
+ /* Mach-O symbol fields. */
+ unsigned char n_type;
+ unsigned char n_sect;
+ unsigned short n_desc;
+}
+bfd_mach_o_asymbol;
+
+#define BFD_MACH_O_SEGNAME_SIZE 16
+#define BFD_MACH_O_SECTNAME_SIZE 16
+
+typedef struct bfd_mach_o_section
+{
+ /* Fields present in the file. */
+ char sectname[BFD_MACH_O_SECTNAME_SIZE + 1]; /* Always NUL padded. */
+ char segname[BFD_MACH_O_SEGNAME_SIZE + 1];
+ bfd_vma addr;
+ bfd_vma size;
+ bfd_vma offset;
+ unsigned long align;
+ bfd_vma reloff;
+ unsigned long nreloc;
+ unsigned long flags;
+ unsigned long reserved1;
+ unsigned long reserved2;
+ unsigned long reserved3;
+
+ /* Corresponding bfd section. */
+ asection *bfdsection;
+
+ /* An array holding the indirect symbols for this section.
+ NULL values indicate local symbols.
+ The number of symbols is determined from the section size and type. */
+
+ bfd_mach_o_asymbol **indirect_syms;
+
+ /* Simply linked list. */
+ struct bfd_mach_o_section *next;
+}
+bfd_mach_o_section;
+
+typedef struct bfd_mach_o_segment_command
+{
+ char segname[BFD_MACH_O_SEGNAME_SIZE + 1];
+ bfd_vma vmaddr;
+ bfd_vma vmsize;
+ bfd_vma fileoff;
+ unsigned long filesize;
+ unsigned long maxprot; /* Maximum permitted protection. */
+ unsigned long initprot; /* Initial protection. */
+ unsigned long nsects;
+ unsigned long flags;
+
+ /* Linked list of sections. */
+ bfd_mach_o_section *sect_head;
+ bfd_mach_o_section *sect_tail;
+}
+bfd_mach_o_segment_command;
+
+/* Protection flags. */
+#define BFD_MACH_O_PROT_READ 0x01
+#define BFD_MACH_O_PROT_WRITE 0x02
+#define BFD_MACH_O_PROT_EXECUTE 0x04
+
+/* Expanded internal representation of a relocation entry. */
+typedef struct bfd_mach_o_reloc_info
+{
+ bfd_vma r_address;
+ bfd_vma r_value;
+ unsigned int r_scattered : 1;
+ unsigned int r_type : 4;
+ unsigned int r_pcrel : 1;
+ unsigned int r_length : 2;
+ unsigned int r_extern : 1;
+}
+bfd_mach_o_reloc_info;
+
+/* The symbol table is sorted like this:
+ (1) local.
+ (otherwise in order of generation)
+ (2) external defined
+ (sorted by name)
+ (3) external undefined / common
+ (sorted by name)
+*/
+
+typedef struct bfd_mach_o_symtab_command
+{
+ unsigned int symoff;
+ unsigned int nsyms;
+ unsigned int stroff;
+ unsigned int strsize;
+ bfd_mach_o_asymbol *symbols;
+ char *strtab;
+}
+bfd_mach_o_symtab_command;
+
+/* This is the second set of the symbolic information which is used to support
+ the data structures for the dynamically link editor.
+
+ The original set of symbolic information in the symtab_command which contains
+ the symbol and string tables must also be present when this load command is
+ present. When this load command is present the symbol table is organized
+ into three groups of symbols:
+ local symbols (static and debugging symbols) - grouped by module
+ defined external symbols - grouped by module (sorted by name if not lib)
+ undefined external symbols (sorted by name)
+ In this load command there are offsets and counts to each of the three groups
+ of symbols.
+
+ This load command contains a the offsets and sizes of the following new
+ symbolic information tables:
+ table of contents
+ module table
+ reference symbol table
+ indirect symbol table
+ The first three tables above (the table of contents, module table and
+ reference symbol table) are only present if the file is a dynamically linked
+ shared library. For executable and object modules, which are files
+ containing only one module, the information that would be in these three
+ tables is determined as follows:
+ table of contents - the defined external symbols are sorted by name
+ module table - the file contains only one module so everything in the
+ file is part of the module.
+ reference symbol table - is the defined and undefined external symbols
+
+ For dynamically linked shared library files this load command also contains
+ offsets and sizes to the pool of relocation entries for all sections
+ separated into two groups:
+ external relocation entries
+ local relocation entries
+ For executable and object modules the relocation entries continue to hang
+ off the section structures. */
+
+typedef struct bfd_mach_o_dylib_module
+{
+ /* Index into the string table indicating the name of the module. */
+ unsigned long module_name_idx;
+ char *module_name;
+
+ /* Index into the symbol table of the first defined external symbol provided
+ by the module. */
+ unsigned long iextdefsym;
+
+ /* Number of external symbols provided by this module. */
+ unsigned long nextdefsym;
+
+ /* Index into the external reference table of the first entry
+ provided by this module. */
+ unsigned long irefsym;
+
+ /* Number of external reference entries provided by this module. */
+ unsigned long nrefsym;
+
+ /* Index into the symbol table of the first local symbol provided by this
+ module. */
+ unsigned long ilocalsym;
+
+ /* Number of local symbols provided by this module. */
+ unsigned long nlocalsym;
+
+ /* Index into the external relocation table of the first entry provided
+ by this module. */
+ unsigned long iextrel;
+
+ /* Number of external relocation entries provided by this module. */
+ unsigned long nextrel;
+
+ /* Index in the module initialization section to the pointers for this
+ module. */
+ unsigned short iinit;
+
+ /* Index in the module termination section to the pointers for this
+ module. */
+ unsigned short iterm;
+
+ /* Number of pointers in the module initialization for this module. */
+ unsigned short ninit;
+
+ /* Number of pointers in the module termination for this module. */
+ unsigned short nterm;
+
+ /* Number of data byte for this module that are used in the __module_info
+ section of the __OBJC segment. */
+ unsigned long objc_module_info_size;
+
+ /* Statically linked address of the start of the data for this module
+ in the __module_info section of the __OBJC_segment. */
+ bfd_vma objc_module_info_addr;
+}
+bfd_mach_o_dylib_module;
+
+typedef struct bfd_mach_o_dylib_table_of_content
+{
+ /* Index into the symbol table to the defined external symbol. */
+ unsigned long symbol_index;
+
+ /* Index into the module table to the module for this entry. */
+ unsigned long module_index;
+}
+bfd_mach_o_dylib_table_of_content;
+
+typedef struct bfd_mach_o_dylib_reference
+{
+ /* Index into the symbol table for the symbol being referenced. */
+ unsigned long isym;
+
+ /* Type of the reference being made (use REFERENCE_FLAGS constants). */
+ unsigned long flags;
+}
+bfd_mach_o_dylib_reference;
+#define BFD_MACH_O_REFERENCE_SIZE 4
+
+typedef struct bfd_mach_o_dysymtab_command
+{
+ /* The symbols indicated by symoff and nsyms of the LC_SYMTAB load command
+ are grouped into the following three groups:
+ local symbols (further grouped by the module they are from)
+ defined external symbols (further grouped by the module they are from)
+ undefined symbols
+
+ The local symbols are used only for debugging. The dynamic binding
+ process may have to use them to indicate to the debugger the local
+ symbols for a module that is being bound.
+
+ The last two groups are used by the dynamic binding process to do the
+ binding (indirectly through the module table and the reference symbol
+ table when this is a dynamically linked shared library file). */
+
+ unsigned long ilocalsym; /* Index to local symbols. */
+ unsigned long nlocalsym; /* Number of local symbols. */
+ unsigned long iextdefsym; /* Index to externally defined symbols. */
+ unsigned long nextdefsym; /* Number of externally defined symbols. */
+ unsigned long iundefsym; /* Index to undefined symbols. */
+ unsigned long nundefsym; /* Number of undefined symbols. */
+
+ /* For the for the dynamic binding process to find which module a symbol
+ is defined in the table of contents is used (analogous to the ranlib
+ structure in an archive) which maps defined external symbols to modules
+ they are defined in. This exists only in a dynamically linked shared
+ library file. For executable and object modules the defined external
+ symbols are sorted by name and is use as the table of contents. */
+
+ unsigned long tocoff; /* File offset to table of contents. */
+ unsigned long ntoc; /* Number of entries in table of contents. */
+
+ /* To support dynamic binding of "modules" (whole object files) the symbol
+ table must reflect the modules that the file was created from. This is
+ done by having a module table that has indexes and counts into the merged
+ tables for each module. The module structure that these two entries
+ refer to is described below. This exists only in a dynamically linked
+ shared library file. For executable and object modules the file only
+ contains one module so everything in the file belongs to the module. */
+
+ unsigned long modtaboff; /* File offset to module table. */
+ unsigned long nmodtab; /* Number of module table entries. */
+
+ /* To support dynamic module binding the module structure for each module
+ indicates the external references (defined and undefined) each module
+ makes. For each module there is an offset and a count into the
+ reference symbol table for the symbols that the module references.
+ This exists only in a dynamically linked shared library file. For
+ executable and object modules the defined external symbols and the
+ undefined external symbols indicates the external references. */
+
+ unsigned long extrefsymoff; /* Offset to referenced symbol table. */
+ unsigned long nextrefsyms; /* Number of referenced symbol table entries. */
+
+ /* The sections that contain "symbol pointers" and "routine stubs" have
+ indexes and (implied counts based on the size of the section and fixed
+ size of the entry) into the "indirect symbol" table for each pointer
+ and stub. For every section of these two types the index into the
+ indirect symbol table is stored in the section header in the field
+ reserved1. An indirect symbol table entry is simply a 32bit index into
+ the symbol table to the symbol that the pointer or stub is referring to.
+ The indirect symbol table is ordered to match the entries in the section. */
+
+ unsigned long indirectsymoff; /* File offset to the indirect symbol table. */
+ unsigned long nindirectsyms; /* Number of indirect symbol table entries. */
+
+ /* To support relocating an individual module in a library file quickly the
+ external relocation entries for each module in the library need to be
+ accessed efficiently. Since the relocation entries can't be accessed
+ through the section headers for a library file they are separated into
+ groups of local and external entries further grouped by module. In this
+ case the presents of this load command who's extreloff, nextrel,
+ locreloff and nlocrel fields are non-zero indicates that the relocation
+ entries of non-merged sections are not referenced through the section
+ structures (and the reloff and nreloc fields in the section headers are
+ set to zero).
+
+ Since the relocation entries are not accessed through the section headers
+ this requires the r_address field to be something other than a section
+ offset to identify the item to be relocated. In this case r_address is
+ set to the offset from the vmaddr of the first LC_SEGMENT command.
+
+ The relocation entries are grouped by module and the module table
+ entries have indexes and counts into them for the group of external
+ relocation entries for that the module.
+
+ For sections that are merged across modules there must not be any
+ remaining external relocation entries for them (for merged sections
+ remaining relocation entries must be local). */
+
+ unsigned long extreloff; /* Offset to external relocation entries. */
+ unsigned long nextrel; /* Number of external relocation entries. */
+
+ /* All the local relocation entries are grouped together (they are not
+ grouped by their module since they are only used if the object is moved
+ from it statically link edited address). */
+
+ unsigned long locreloff; /* Offset to local relocation entries. */
+ unsigned long nlocrel; /* Number of local relocation entries. */
+
+ bfd_mach_o_dylib_module *dylib_module;
+ bfd_mach_o_dylib_table_of_content *dylib_toc;
+ unsigned int *indirect_syms;
+ bfd_mach_o_dylib_reference *ext_refs;
+}
+bfd_mach_o_dysymtab_command;
+
+/* An indirect symbol table entry is simply a 32bit index into the symbol table
+ to the symbol that the pointer or stub is refering to. Unless it is for a
+ non-lazy symbol pointer section for a defined symbol which strip(1) has
+ removed. In which case it has the value INDIRECT_SYMBOL_LOCAL. If the
+ symbol was also absolute INDIRECT_SYMBOL_ABS is or'ed with that. */
+
+#define BFD_MACH_O_INDIRECT_SYMBOL_LOCAL 0x80000000
+#define BFD_MACH_O_INDIRECT_SYMBOL_ABS 0x40000000
+#define BFD_MACH_O_INDIRECT_SYMBOL_SIZE 4
+
+/* For LC_TWOLEVEL_HINTS. */
+
+typedef struct bfd_mach_o_twolevel_hints_command
+{
+ /* Offset to the hint table. */
+ unsigned int offset;
+
+ /* Number of entries in the table. */
+ unsigned int nhints;
+}
+bfd_mach_o_twolevel_hints_command;
+
+/* For LC_PREBIND_CKSUM. */
+
+typedef struct bfd_mach_o_prebind_cksum_command
+{
+ /* Checksum or zero. */
+ unsigned int cksum;
+}
+bfd_mach_o_prebind_cksum_command;
+
+/* For LC_THREAD or LC_UNIXTHREAD. */
+
+typedef struct bfd_mach_o_thread_flavour
+{
+ unsigned long flavour;
+ unsigned long offset;
+ unsigned long size;
+}
+bfd_mach_o_thread_flavour;
+
+typedef struct bfd_mach_o_thread_command
+{
+ unsigned long nflavours;
+ bfd_mach_o_thread_flavour *flavours;
+ asection *section;
+}
+bfd_mach_o_thread_command;
+
+/* For LC_LOAD_DYLINKER and LC_ID_DYLINKER. */
+
+typedef struct bfd_mach_o_dylinker_command
+{
+ unsigned int name_offset; /* Offset to library's path name. */
+ char *name_str;
+}
+bfd_mach_o_dylinker_command;
+
+/* For LC_LOAD_DYLIB, LC_LOAD_WEAK_DYLIB, LC_ID_DYLIB
+ or LC_REEXPORT_DYLIB. */
+
+typedef struct bfd_mach_o_dylib_command
+{
+ unsigned int name_offset; /* Offset to library's path name. */
+ unsigned long timestamp; /* Library's build time stamp. */
+ unsigned long current_version; /* Library's current version number. */
+ unsigned long compatibility_version; /* Library's compatibility vers number. */
+ char *name_str;
+}
+bfd_mach_o_dylib_command;
+
+/* For LC_PREBOUND_DYLIB. */
+
+typedef struct bfd_mach_o_prebound_dylib_command
+{
+ unsigned int name_offset; /* Library's path name. */
+ unsigned int nmodules; /* Number of modules in library. */
+ unsigned int linked_modules_offset; /* Bit vector of linked modules. */
+
+ char *name_str;
+ unsigned char *linked_modules;
+}
+bfd_mach_o_prebound_dylib_command;
+
+/* For LC_UUID. */
+
+typedef struct bfd_mach_o_uuid_command
+{
+ unsigned char uuid[16];
+}
+bfd_mach_o_uuid_command;
+
+/* For LC_CODE_SIGNATURE or LC_SEGMENT_SPLIT_INFO. */
+
+typedef struct bfd_mach_o_linkedit_command
+{
+ unsigned long dataoff;
+ unsigned long datasize;
+}
+bfd_mach_o_linkedit_command;
+
+typedef struct bfd_mach_o_str_command
+{
+ unsigned long stroff;
+ unsigned long str_len;
+ char *str;
+}
+bfd_mach_o_str_command;
+
+typedef struct bfd_mach_o_fvmlib_command
+{
+ unsigned int name_offset;
+ char *name_str;
+ unsigned int minor_version;
+ unsigned int header_addr;
+}
+bfd_mach_o_fvmlib_command;
+
+typedef struct bfd_mach_o_dyld_info_command
+{
+ /* File offset and size to rebase info. */
+ unsigned int rebase_off;
+ unsigned int rebase_size;
+ unsigned char *rebase_content;
+
+ /* File offset and size of binding info. */
+ unsigned int bind_off;
+ unsigned int bind_size;
+ unsigned char *bind_content;
+
+ /* File offset and size of weak binding info. */
+ unsigned int weak_bind_off;
+ unsigned int weak_bind_size;
+ unsigned char *weak_bind_content;
+
+ /* File offset and size of lazy binding info. */
+ unsigned int lazy_bind_off;
+ unsigned int lazy_bind_size;
+ unsigned char *lazy_bind_content;
+
+ /* File offset and size of export info. */
+ unsigned int export_off;
+ unsigned int export_size;
+ unsigned char *export_content;
+}
+bfd_mach_o_dyld_info_command;
+
+typedef struct bfd_mach_o_version_min_command
+{
+ unsigned char rel;
+ unsigned char maj;
+ unsigned char min;
+ unsigned int reserved;
+}
+bfd_mach_o_version_min_command;
+
+typedef struct bfd_mach_o_encryption_info_command
+{
+ unsigned int cryptoff;
+ unsigned int cryptsize;
+ unsigned int cryptid;
+}
+bfd_mach_o_encryption_info_command;
+
+typedef struct bfd_mach_o_main_command
+{
+ bfd_uint64_t entryoff;
+ bfd_uint64_t stacksize;
+}
+bfd_mach_o_main_command;
+
+typedef struct bfd_mach_o_source_version_command
+{
+ unsigned int a;
+ unsigned short b;
+ unsigned short c;
+ unsigned short d;
+ unsigned short e;
+}
+bfd_mach_o_source_version_command;
+
+typedef struct bfd_mach_o_load_command
+{
+ /* Next command in the single linked list. */
+ struct bfd_mach_o_load_command *next;
+
+ /* Type and required flag. */
+ bfd_mach_o_load_command_type type;
+ bfd_boolean type_required;
+
+ /* Offset and length in the file. */
+ unsigned int offset;
+ unsigned int len;
+
+ union
+ {
+ bfd_mach_o_segment_command segment;
+ bfd_mach_o_symtab_command symtab;
+ bfd_mach_o_dysymtab_command dysymtab;
+ bfd_mach_o_thread_command thread;
+ bfd_mach_o_dylib_command dylib;
+ bfd_mach_o_dylinker_command dylinker;
+ bfd_mach_o_prebound_dylib_command prebound_dylib;
+ bfd_mach_o_prebind_cksum_command prebind_cksum;
+ bfd_mach_o_twolevel_hints_command twolevel_hints;
+ bfd_mach_o_uuid_command uuid;
+ bfd_mach_o_linkedit_command linkedit;
+ bfd_mach_o_str_command str;
+ bfd_mach_o_dyld_info_command dyld_info;
+ bfd_mach_o_version_min_command version_min;
+ bfd_mach_o_encryption_info_command encryption_info;
+ bfd_mach_o_fvmlib_command fvmlib;
+ bfd_mach_o_main_command main;
+ bfd_mach_o_source_version_command source_version;
+ } command;
+}
+bfd_mach_o_load_command;
+
+typedef struct mach_o_data_struct
+{
+ /* Mach-O header. */
+ bfd_mach_o_header header;
+ /* Array of load commands (length is given by header.ncmds). */
+ bfd_mach_o_load_command *first_command;
+ bfd_mach_o_load_command *last_command;
+
+ /* Flatten array of sections. The array is 0-based. */
+ unsigned long nsects;
+ bfd_mach_o_section **sections;
+
+ /* Used while writing: current length of the output file. This is used
+ to allocate space in the file. */
+ ufile_ptr filelen;
+
+ /* As symtab is referenced by other load command, it is handy to have
+ a direct access to it. Although it is not clearly stated, only one symtab
+ is expected. */
+ bfd_mach_o_symtab_command *symtab;
+ bfd_mach_o_dysymtab_command *dysymtab;
+
+ /* A place to stash dwarf2 info for this bfd. */
+ void *dwarf2_find_line_info;
+
+ /* BFD of .dSYM file. */
+ bfd *dsym_bfd;
+
+ /* Cache of dynamic relocs. */
+ arelent *dyn_reloc_cache;
+}
+bfd_mach_o_data_struct;
+
+typedef struct bfd_mach_o_xlat_name
+{
+ const char *name;
+ unsigned long val;
+}
+bfd_mach_o_xlat_name;
+
+/* Target specific routines. */
+
+#define bfd_mach_o_get_data(abfd) ((abfd)->tdata.mach_o_data)
+#define bfd_mach_o_get_backend_data(abfd) \
+ ((bfd_mach_o_backend_data*)(abfd)->xvec->backend_data)
+
+/* Get the Mach-O header for section SEC. */
+#define bfd_mach_o_get_mach_o_section(sec) \
+ ((bfd_mach_o_section *)(sec)->used_by_bfd)
+
+bfd_boolean bfd_mach_o_valid (bfd *);
+bfd_boolean bfd_mach_o_mkobject_init (bfd *);
+const bfd_target *bfd_mach_o_object_p (bfd *);
+const bfd_target *bfd_mach_o_core_p (bfd *);
+const bfd_target *bfd_mach_o_archive_p (bfd *);
+bfd *bfd_mach_o_openr_next_archived_file (bfd *, bfd *);
+bfd_boolean bfd_mach_o_set_arch_mach (bfd *, enum bfd_architecture,
+ unsigned long);
+int bfd_mach_o_lookup_command (bfd *, bfd_mach_o_load_command_type, bfd_mach_o_load_command **);
+bfd_boolean bfd_mach_o_new_section_hook (bfd *, asection *);
+bfd_boolean bfd_mach_o_write_contents (bfd *);
+bfd_boolean bfd_mach_o_bfd_copy_private_symbol_data (bfd *, asymbol *,
+ bfd *, asymbol *);
+bfd_boolean bfd_mach_o_bfd_copy_private_section_data (bfd *, asection *,
+ bfd *, asection *);
+bfd_boolean bfd_mach_o_bfd_copy_private_header_data (bfd *, bfd *);
+bfd_boolean bfd_mach_o_bfd_set_private_flags (bfd *, flagword);
+long bfd_mach_o_get_symtab_upper_bound (bfd *);
+long bfd_mach_o_canonicalize_symtab (bfd *, asymbol **);
+long bfd_mach_o_get_synthetic_symtab (bfd *, long, asymbol **, long,
+ asymbol **, asymbol **ret);
+long bfd_mach_o_get_reloc_upper_bound (bfd *, asection *);
+long bfd_mach_o_canonicalize_reloc (bfd *, asection *, arelent **, asymbol **);
+long bfd_mach_o_get_dynamic_reloc_upper_bound (bfd *);
+long bfd_mach_o_canonicalize_dynamic_reloc (bfd *, arelent **, asymbol **);
+asymbol *bfd_mach_o_make_empty_symbol (bfd *);
+void bfd_mach_o_get_symbol_info (bfd *, asymbol *, symbol_info *);
+void bfd_mach_o_print_symbol (bfd *, void *, asymbol *, bfd_print_symbol_type);
+int bfd_mach_o_sizeof_headers (bfd *, struct bfd_link_info *);
+unsigned long bfd_mach_o_stack_addr (enum bfd_mach_o_cpu_type);
+int bfd_mach_o_core_fetch_environment (bfd *, unsigned char **, unsigned int *);
+char *bfd_mach_o_core_file_failing_command (bfd *);
+int bfd_mach_o_core_file_failing_signal (bfd *);
+bfd_boolean bfd_mach_o_core_file_matches_executable_p (bfd *, bfd *);
+bfd *bfd_mach_o_fat_extract (bfd *, bfd_format , const bfd_arch_info_type *);
+const bfd_target *bfd_mach_o_header_p (bfd *, bfd_mach_o_filetype,
+ bfd_mach_o_cpu_type);
+bfd_boolean bfd_mach_o_build_commands (bfd *);
+bfd_boolean bfd_mach_o_set_section_contents (bfd *, asection *, const void *,
+ file_ptr, bfd_size_type);
+unsigned int bfd_mach_o_version (bfd *);
+
+unsigned int bfd_mach_o_get_section_type_from_name (bfd *, const char *);
+unsigned int bfd_mach_o_get_section_attribute_from_name (const char *);
+
+void bfd_mach_o_convert_section_name_to_bfd (bfd *, const char *, const char *,
+ const char **, flagword *);
+bfd_boolean bfd_mach_o_find_nearest_line (bfd *, asymbol **,
+ asection *, bfd_vma,
+ const char **, const char **,
+ unsigned int *, unsigned int *);
+#define bfd_mach_o_find_line _bfd_nosymbols_find_line
+bfd_boolean bfd_mach_o_close_and_cleanup (bfd *);
+bfd_boolean bfd_mach_o_free_cached_info (bfd *);
+
+unsigned int bfd_mach_o_section_get_nbr_indirect (bfd *, bfd_mach_o_section *);
+unsigned int bfd_mach_o_section_get_entry_size (bfd *, bfd_mach_o_section *);
+bfd_boolean bfd_mach_o_read_symtab_symbols (bfd *);
+bfd_boolean bfd_mach_o_read_symtab_strtab (bfd *abfd);
+
+bfd_vma bfd_mach_o_get_base_address (bfd *);
+
+/* A placeholder in case we need to suppress emitting the dysymtab for some
+ reason (e.g. compatibility with older system versions). */
+#define bfd_mach_o_should_emit_dysymtab(x) TRUE
+
+extern const bfd_mach_o_xlat_name bfd_mach_o_section_attribute_name[];
+extern const bfd_mach_o_xlat_name bfd_mach_o_section_type_name[];
+
+extern const bfd_target mach_o_fat_vec;
+
+/* Interfaces between BFD names and Mach-O names. */
+
+typedef struct mach_o_section_name_xlat
+{
+ const char *bfd_name;
+ const char *mach_o_name;
+ flagword bfd_flags;
+ unsigned int macho_sectype;
+ unsigned int macho_secattr;
+ unsigned int sectalign;
+} mach_o_section_name_xlat;
+
+typedef struct mach_o_segment_name_xlat
+{
+ const char *segname;
+ const mach_o_section_name_xlat *sections;
+} mach_o_segment_name_xlat;
+
+const mach_o_section_name_xlat *
+bfd_mach_o_section_data_for_mach_sect (bfd *, const char *, const char *);
+const mach_o_section_name_xlat *
+bfd_mach_o_section_data_for_bfd_name (bfd *, const char *, const char **);
+
+typedef struct bfd_mach_o_backend_data
+{
+ enum bfd_architecture arch;
+ bfd_vma page_size;
+ bfd_boolean (*_bfd_mach_o_swap_reloc_in)(arelent *, bfd_mach_o_reloc_info *);
+ bfd_boolean (*_bfd_mach_o_swap_reloc_out)(arelent *, bfd_mach_o_reloc_info *);
+ bfd_boolean (*_bfd_mach_o_print_thread)(bfd *, bfd_mach_o_thread_flavour *,
+ void *, char *);
+ const mach_o_segment_name_xlat *segsec_names_xlat;
+ bfd_boolean (*bfd_mach_o_section_type_valid_for_target) (unsigned long);
+}
+bfd_mach_o_backend_data;
+
+/* Values used in symbol.udata.i, to signal that the mach-o-specific data in the
+ symbol are not yet set, or need validation (where this is possible). */
+
+#define SYM_MACHO_FIELDS_UNSET ((bfd_vma) -1)
+#define SYM_MACHO_FIELDS_NOT_VALIDATED ((bfd_vma) -2)
+
+#endif /* _BFD_MACH_O_H_ */
diff --git a/bfd/makefile.vms b/bfd/makefile.vms
new file mode 100644
index 0000000..9ef4019
--- /dev/null
+++ b/bfd/makefile.vms
@@ -0,0 +1,66 @@
+#
+# Makefile for bfd library under openVMS
+#
+# For use with gnu-make for vms
+#
+# Created by Klaus K"ampf, kkaempf@rmi.de
+#
+# Copyright (C) 2012-2014 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 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 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 COPYING3. If not see
+# <http://www.gnu.org/licenses/>.
+#
+
+ifeq ($(ARCH),IA64)
+HOSTFILE=alphavms.h
+OBJS:=cpu-ia64.obj,elfxx-ia64.obj,elf64-ia64-vms.obj,\
+ vms-misc.obj,vms-lib.obj,elf-strtab.obj,corefile.obj,stabs.obj,\
+ merge.obj,elf-eh-frame.obj,elflink.obj,elf-attrs.obj,dwarf1.obj,elf64.obj
+DEFS=SELECT_VECS="&ia64_elf64_vms_vec",\
+ SELECT_ARCHITECTURES="&bfd_ia64_arch","HAVE_ia64_elf64_vms_vec"=1
+endif
+ifeq ($(ARCH),ALPHA)
+HOSTFILE=alphavms.h
+OBJS:=vms-alpha.obj,vms-lib.obj,vms-misc.obj,cpu-alpha.obj
+DEFS=SELECT_VECS="&alpha_vms_vec",SELECT_ARCHITECTURES="&bfd_alpha_arch"
+endif
+
+OBJS:=$(OBJS),archive.obj,archive64.obj,archures.obj,bfd.obj,bfdio.obj,\
+ binary.obj,cache.obj,coffgen.obj,compress.obj,corefile.obj,dwarf2.obj,\
+ elf.obj,format.obj,hash.obj,ihex.obj,init.obj,libbfd.obj,linker.obj,\
+ opncls.obj,reloc.obj,section.obj,simple.obj,srec.obj,stab-syms.obj,\
+ syms.obj,targets.obj,tekhex.obj,verilog.obj
+
+ifeq ($(CC),gcc)
+CFLAGS=/include=([],[-.include])$(DEFS)
+else
+OPT=/noopt/debug
+CFLAGS=/name=(as_is,shortened)/include=([],"../include")\
+ /define=("unlink=remove",DEBUGDIR="""GNU$$DEBUGDIR:""",$(DEFS))\
+ /warns=(infor=(missingreturn,badansialias))$(OPT)
+endif
+
+libbfd.olb: $(OBJS)
+ purge
+ lib/create libbfd $(OBJS)
+
+targmatch.h: bfd.h
+config.h: bfd.h
+vms-misc.c: vms.h
+targets.c: targmatch.h
+
+clean:
+ $$ purge
+ $(RM) libbfd.olb;
+ $(RM) *.obj;
diff --git a/bfd/mep-relocs.pl b/bfd/mep-relocs.pl
new file mode 100755
index 0000000..97f1627
--- /dev/null
+++ b/bfd/mep-relocs.pl
@@ -0,0 +1,275 @@
+#!/usr/bin/perl
+# -*- perl -*-
+#
+# Toshiba MeP Media Engine Relocation Generator
+# Copyright (C) 2001-2014 Free Software Foundation, Inc.
+# This file is part of BFD.
+# Originally written by DJ Delorie <dj@redhat.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 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+# MA 02110-1301, USA.
+
+
+# Usage: Run this anywhere inside your source tree. It will read
+# include/elf/mep.h and scan the comments therein. It will renumber
+# the relocs to be sequential (this is needed so that bfd/elf32-mep.h
+# works) if needed. It will then update the reloc list in bfd/reloc.c
+# and the howto, mapping, and apply routines in bfd/elf32-mep.c. You
+# can then regenerate bfd-in2.h and check everything in.
+
+# FIXME: After the relocation list is finalized, change this to
+# *verify* the reloc list, rather than resequence it.
+
+while (! -f "include/elf/mep.h" && ! -f "bfd/reloc.c") {
+ chdir "..";
+ $pwd = `pwd`;
+ if ($pwd !~ m@/.*/@) {
+ print STDERR "Cannot find include/elf/mep.h or bfd/reloc.h\n";
+ exit 1;
+ }
+}
+$pwd = `pwd`;
+print "srctop is $pwd";
+
+printf "Reading include/elf/mep.h ...\n";
+open(MEPH, "include/elf/mep.h");
+open(MEPHO, "> include/elf/mep.h.new") || die("mep.h.new create: $!");
+$val = 0;
+while (<MEPH>) {
+ if (($pre,$rel,$rest) = /(.*RELOC_NUMBER \()([^,]+), *\d+(.*)/) {
+ $rest =~ s/[\r\n]+$//;
+ print (MEPHO "$pre$rel, $val$rest\n") || die("mep.h.new write: $!");
+ $val ++;
+ $rel =~ s/R_MEP_//;
+ push(@relocs, $rel);
+
+ $rest =~ s@.*/\* @@;
+ ($pattern, $sign, $attrs) = $rest =~ m@(.*) ([US]) (.*)\*/@;
+ $pattern =~ s/ //g;
+ push(@pattern, $pattern);
+ push(@sign, $sign);
+ push(@attrs, $attrs);
+
+ printf "%4d $rel p=`$pattern' s=`$sign' a=`$attrs'\n", $#pattern;
+
+ } else {
+ print(MEPHO) || die("mep.h.new write: $!");
+ }
+}
+close(MEPH);
+close(MEPHO) || die("mep.h.new close: $!");
+
+&swapfile("include/elf/mep.h");
+
+redo_file ("bfd/reloc.c",
+ "",
+ "ENUMDOC\n Toshiba Media Processor Relocations.\n\nCOMMENT\n",
+ "ENUM\n BFD_RELOC_MEP_%s\n",
+ "");
+
+$autogen = " /* This section generated from bfd/mep-relocs.pl from include/elf/mep.h. */\n";
+
+redo_file ("bfd/elf32-mep.c",
+ "MEPRELOC:HOWTO",
+ $autogen,
+ "MEPRELOC:END",
+ "",
+ "&emit_howto();",
+ "MEPRELOC:MAP",
+ $autogen,
+ "MEPRELOC:END",
+ "",
+ " MAP(%s);\n",
+ "MEPRELOC:APPLY",
+ $autogen,
+ "MEPRELOC:END",
+ "",
+ "&emit_apply();",
+ );
+
+sub mask2shifts {
+ my ($mask) = @_;
+ my ($bits, $left, $right, $ci, $c, $cv);
+ $bits = 0;
+ $left = 0;
+ $right = 32;
+ for ($ci=0; $ci<length($mask); $ci++) {
+ $c = substr($mask, $ci, 1);
+ $left++;
+ next if $c eq '-';
+ $left = 0;
+ $cv = ord($c) - ord('0');
+ $cv -= ord('a') - ord('9') - 1 if $cv > 9;
+ $right = $cv unless $right < $cv;
+ $bits = $cv+1 unless $bits > $cv+1;
+ }
+ $mask =~ tr/-/1/c;
+ $mask =~ tr/-/0/;
+ ($rmask = $mask) =~ tr/01/10/;
+ $mask = unpack("H*", pack("B*", $mask));
+ $rmask = unpack("H*", pack("B*", $rmask));
+ return ($bits, $left, $right, $mask, $rmask);
+}
+
+sub emit_howto {
+ for ($i=2; $i<=$#relocs; $i++) {
+ $mask = $pattern[$i];
+
+ if (length($mask) == 8) { $bytesize = 0; }
+ elsif (length($mask) == 16) { $bytesize = 1; }
+ elsif (length($mask) == 32) { $bytesize = 2; }
+
+ ($bits, $left, $right, $mask) = mask2shifts ($mask);
+ $bits[$i] = $bits;
+ $pcrel = 0;
+ $pcrel = 1 if $attrs[$i] =~ /pc-rel/i;
+ $overflow = $sign[$i];
+ $overflow = 'N' if $attrs[$i] =~ /no-overflow/;
+
+ $c = "$relocs[$i],";
+ printf(NEW " MEPREL (R_MEP_%-10s%d,%3d,%2d,%2d,%2d,%2s, 0x%s),\n",
+ $c, $bytesize, $bits, $left, $right, $pcrel, $overflow, $mask);
+ }
+}
+
+sub emit_apply {
+ for ($i=2; $i<=$#relocs; $i++) {
+ $v = "u";
+ $v = "s" if $sign[$i] =~ /S/;
+ if (length($pattern[$i]) == 8) {
+ $e = ''; # no endian swap for bytes
+ } elsif ($pattern[$i] =~ /-/ || length($pattern[$i]) == 16) {
+ $e = '^e2'; # endian swap - 2byte words only
+ } else {
+ $e = '^e4' # endian swap for data
+ }
+ print NEW " case R_MEP_$relocs[$i]: /* $pattern[$i] */\n";
+ if ($attrs[$i] =~ /tp-rel/i) {
+ print NEW " $v -= mep_tpoff_base(rel->r_offset);\n";
+ }
+ if ($attrs[$i] =~ /gp-rel/i) {
+ print NEW " $v -= mep_sdaoff_base(rel->r_offset);\n";
+ }
+ if ($attrs[$i] !~ /no-overflow/ && $bits[$i] < 32) {
+ if ($v eq "u") {
+ $max = (1 << $bits[$i]) - 1;
+ print NEW " if (u > $max) r = bfd_reloc_overflow;\n";
+ } else {
+ $min = -(1 << ($bits[$i]-1));
+ $max = (1 << ($bits[$i]-1)) - 1;
+ print NEW " if ($min > s || s > $max) r = bfd_reloc_overflow;\n";
+ }
+ }
+ for ($b=0; $b<length($pattern[$i]); $b += 8) {
+ $mask = substr($pattern[$i], $b, 8);
+ ($bits, $left, $right, $mask, $rmask) = mask2shifts ($mask);
+ if ($left > $right) { $left -= $right; $right = 0; }
+ else { $right -= $left; $left = 0; }
+
+ if ($mask ne "00") {
+ $bb = $b / 8;
+ print NEW " byte[$bb$e] = ";
+ print NEW "(byte[$bb$e] & 0x$rmask) | " if $rmask ne "00";
+ if ($left) {
+ print NEW "(($v << $left) & 0x$mask)";
+ } elsif ($right) {
+ print NEW "(($v >> $right) & 0x$mask)";
+ } else {
+ print NEW "($v & 0x$mask)";
+ }
+ print NEW ";\n";
+ }
+ }
+ print NEW " break;\n";
+ }
+}
+
+
+#-----------------------------------------------------------------------------
+
+sub redo_file {
+ my ($file, @control) = @_;
+ open(OLD, $file);
+ open(NEW, "> $file.new") || die("$file.new create: $!");
+
+ print "Scanning file $file ...\n";
+
+ while (1) {
+ $start = shift @control;
+ $prefix = shift @control;
+ $end = shift @control;
+ $suffix = shift @control;
+ $pattern = shift @control;
+
+ if (!$start) {
+ print NEW while <OLD>;
+ last;
+ }
+
+ print " looking for $start\n";
+ while (<OLD>) {
+ print NEW;
+ last if /\Q$start\E/;
+ }
+ print "can't find $start\n" unless $_;
+ last unless $_;
+
+ print NEW $prefix;
+ if ($pattern =~ /^\&/) {
+ eval $pattern;
+ die("$pattern: $@") if $@;
+ } else {
+ for $i (2..$#relocs) {
+ printf (NEW "$pattern", $relocs[$i]) || die("$file.new write: $!");
+ $pattern =~ s/^ENUM\n/ENUMX\n/;
+ }
+ }
+ print NEW $suffix;
+ while (<OLD>) {
+ last if /\Q$end\E/;
+ }
+ print NEW;
+ }
+
+ close(OLD);
+ close(NEW) || die("$file.new close: $!");
+ &swapfile($file);
+}
+
+#-----------------------------------------------------------------------------
+
+sub swapfile {
+ my ($f) = @_;
+ if ( ! -f "$f.save") {
+ system "cp $f $f.save";
+ }
+ open(ORIG, $f);
+ open(NEW, "$f.new");
+ while (<ORIG>) {
+ $n = <NEW>;
+ if ($n ne $_) {
+ close(ORIG);
+ close(NEW);
+ print " Updating $f\n";
+ rename "$f", "$f.old";
+ rename "$f.new", "$f";
+ return;
+ }
+ }
+ close(ORIG);
+ close(NEW);
+ print " No change to $f\n";
+ unlink "$f.new";
+}
diff --git a/bfd/merge.c b/bfd/merge.c
new file mode 100644
index 0000000..15328f1
--- /dev/null
+++ b/bfd/merge.c
@@ -0,0 +1,900 @@
+/* SEC_MERGE support.
+ Copyright (C) 2001-2014 Free Software Foundation, Inc.
+ Written by Jakub Jelinek <jakub@redhat.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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+
+/* This file contains support for merging duplicate entities within sections,
+ as used in ELF SHF_MERGE. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+#include "hashtab.h"
+#include "libiberty.h"
+
+struct sec_merge_sec_info;
+
+/* An entry in the section merge hash table. */
+
+struct sec_merge_hash_entry
+{
+ struct bfd_hash_entry root;
+ /* Length of this entry. This includes the zero terminator. */
+ unsigned int len;
+ /* Start of this string needs to be aligned to
+ alignment octets (not 1 << align). */
+ unsigned int alignment;
+ union
+ {
+ /* Index within the merged section. */
+ bfd_size_type index;
+ /* Entry this is a suffix of (if alignment is 0). */
+ struct sec_merge_hash_entry *suffix;
+ } u;
+ /* Which section is it in. */
+ struct sec_merge_sec_info *secinfo;
+ /* Next entity in the hash table. */
+ struct sec_merge_hash_entry *next;
+};
+
+/* The section merge hash table. */
+
+struct sec_merge_hash
+{
+ struct bfd_hash_table table;
+ /* Next available index. */
+ bfd_size_type size;
+ /* First entity in the SEC_MERGE sections of this type. */
+ struct sec_merge_hash_entry *first;
+ /* Last entity in the SEC_MERGE sections of this type. */
+ struct sec_merge_hash_entry *last;
+ /* Entity size. */
+ unsigned int entsize;
+ /* Are entries fixed size or zero terminated strings? */
+ bfd_boolean strings;
+};
+
+struct sec_merge_info
+{
+ /* Chain of sec_merge_infos. */
+ struct sec_merge_info *next;
+ /* Chain of sec_merge_sec_infos. */
+ struct sec_merge_sec_info *chain;
+ /* A hash table used to hold section content. */
+ struct sec_merge_hash *htab;
+};
+
+struct sec_merge_sec_info
+{
+ /* Chain of sec_merge_sec_infos. */
+ struct sec_merge_sec_info *next;
+ /* The corresponding section. */
+ asection *sec;
+ /* Pointer to merge_info pointing to us. */
+ void **psecinfo;
+ /* A hash table used to hold section content. */
+ struct sec_merge_hash *htab;
+ /* First string in this section. */
+ struct sec_merge_hash_entry *first_str;
+ /* Original section content. */
+ unsigned char contents[1];
+};
+
+
+/* Routine to create an entry in a section merge hashtab. */
+
+static struct bfd_hash_entry *
+sec_merge_hash_newfunc (struct bfd_hash_entry *entry,
+ struct bfd_hash_table *table, const char *string)
+{
+ /* Allocate the structure if it has not already been allocated by a
+ subclass. */
+ if (entry == NULL)
+ entry = (struct bfd_hash_entry *)
+ bfd_hash_allocate (table, sizeof (struct sec_merge_hash_entry));
+ if (entry == NULL)
+ return NULL;
+
+ /* Call the allocation method of the superclass. */
+ entry = bfd_hash_newfunc (entry, table, string);
+
+ if (entry != NULL)
+ {
+ /* Initialize the local fields. */
+ struct sec_merge_hash_entry *ret = (struct sec_merge_hash_entry *) entry;
+
+ ret->u.suffix = NULL;
+ ret->alignment = 0;
+ ret->secinfo = NULL;
+ ret->next = NULL;
+ }
+
+ return entry;
+}
+
+/* Look up an entry in a section merge hash table. */
+
+static struct sec_merge_hash_entry *
+sec_merge_hash_lookup (struct sec_merge_hash *table, const char *string,
+ unsigned int alignment, bfd_boolean create)
+{
+ const unsigned char *s;
+ unsigned long hash;
+ unsigned int c;
+ struct sec_merge_hash_entry *hashp;
+ unsigned int len, i;
+ unsigned int _index;
+
+ hash = 0;
+ len = 0;
+ s = (const unsigned char *) string;
+ if (table->strings)
+ {
+ if (table->entsize == 1)
+ {
+ while ((c = *s++) != '\0')
+ {
+ hash += c + (c << 17);
+ hash ^= hash >> 2;
+ ++len;
+ }
+ hash += len + (len << 17);
+ }
+ else
+ {
+ for (;;)
+ {
+ for (i = 0; i < table->entsize; ++i)
+ if (s[i] != '\0')
+ break;
+ if (i == table->entsize)
+ break;
+ for (i = 0; i < table->entsize; ++i)
+ {
+ c = *s++;
+ hash += c + (c << 17);
+ hash ^= hash >> 2;
+ }
+ ++len;
+ }
+ hash += len + (len << 17);
+ len *= table->entsize;
+ }
+ hash ^= hash >> 2;
+ len += table->entsize;
+ }
+ else
+ {
+ for (i = 0; i < table->entsize; ++i)
+ {
+ c = *s++;
+ hash += c + (c << 17);
+ hash ^= hash >> 2;
+ }
+ len = table->entsize;
+ }
+
+ _index = hash % table->table.size;
+ for (hashp = (struct sec_merge_hash_entry *) table->table.table[_index];
+ hashp != NULL;
+ hashp = (struct sec_merge_hash_entry *) hashp->root.next)
+ {
+ if (hashp->root.hash == hash
+ && len == hashp->len
+ && memcmp (hashp->root.string, string, len) == 0)
+ {
+ /* If the string we found does not have at least the required
+ alignment, we need to insert another copy. */
+ if (hashp->alignment < alignment)
+ {
+ if (create)
+ {
+ /* Mark the less aligned copy as deleted. */
+ hashp->len = 0;
+ hashp->alignment = 0;
+ }
+ break;
+ }
+ return hashp;
+ }
+ }
+
+ if (! create)
+ return NULL;
+
+ hashp = ((struct sec_merge_hash_entry *)
+ bfd_hash_insert (&table->table, string, hash));
+ if (hashp == NULL)
+ return NULL;
+ hashp->len = len;
+ hashp->alignment = alignment;
+ return hashp;
+}
+
+/* Create a new hash table. */
+
+static struct sec_merge_hash *
+sec_merge_init (unsigned int entsize, bfd_boolean strings)
+{
+ struct sec_merge_hash *table;
+
+ table = (struct sec_merge_hash *) bfd_malloc (sizeof (struct sec_merge_hash));
+ if (table == NULL)
+ return NULL;
+
+ if (! bfd_hash_table_init_n (&table->table, sec_merge_hash_newfunc,
+ sizeof (struct sec_merge_hash_entry), 16699))
+ {
+ free (table);
+ return NULL;
+ }
+
+ table->size = 0;
+ table->first = NULL;
+ table->last = NULL;
+ table->entsize = entsize;
+ table->strings = strings;
+
+ return table;
+}
+
+/* Get the index of an entity in a hash table, adding it if it is not
+ already present. */
+
+static struct sec_merge_hash_entry *
+sec_merge_add (struct sec_merge_hash *tab, const char *str,
+ unsigned int alignment, struct sec_merge_sec_info *secinfo)
+{
+ struct sec_merge_hash_entry *entry;
+
+ entry = sec_merge_hash_lookup (tab, str, alignment, TRUE);
+ if (entry == NULL)
+ return NULL;
+
+ if (entry->secinfo == NULL)
+ {
+ tab->size++;
+ entry->secinfo = secinfo;
+ if (tab->first == NULL)
+ tab->first = entry;
+ else
+ tab->last->next = entry;
+ tab->last = entry;
+ }
+
+ return entry;
+}
+
+static bfd_boolean
+sec_merge_emit (bfd *abfd, struct sec_merge_hash_entry *entry)
+{
+ struct sec_merge_sec_info *secinfo = entry->secinfo;
+ asection *sec = secinfo->sec;
+ char *pad = NULL;
+ bfd_size_type off = 0;
+ int alignment_power = sec->output_section->alignment_power;
+
+ if (alignment_power)
+ {
+ pad = (char *) bfd_zmalloc ((bfd_size_type) 1 << alignment_power);
+ if (pad == NULL)
+ return FALSE;
+ }
+
+ for (; entry != NULL && entry->secinfo == secinfo; entry = entry->next)
+ {
+ const char *str;
+ bfd_size_type len;
+
+ len = -off & (entry->alignment - 1);
+ if (len != 0)
+ {
+ if (bfd_bwrite (pad, len, abfd) != len)
+ goto err;
+ off += len;
+ }
+
+ str = entry->root.string;
+ len = entry->len;
+
+ if (bfd_bwrite (str, len, abfd) != len)
+ goto err;
+
+ off += len;
+ }
+
+ /* Trailing alignment needed? */
+ off = sec->size - off;
+ if (off != 0
+ && bfd_bwrite (pad, off, abfd) != off)
+ goto err;
+
+ if (pad != NULL)
+ free (pad);
+ return TRUE;
+
+ err:
+ if (pad != NULL)
+ free (pad);
+ return FALSE;
+}
+
+/* Register a SEC_MERGE section as a candidate for merging.
+ This function is called for all non-dynamic SEC_MERGE input sections. */
+
+bfd_boolean
+_bfd_add_merge_section (bfd *abfd, void **psinfo, asection *sec,
+ void **psecinfo)
+{
+ struct sec_merge_info *sinfo;
+ struct sec_merge_sec_info *secinfo;
+ unsigned int align;
+ bfd_size_type amt;
+ bfd_byte *contents;
+
+ if ((abfd->flags & DYNAMIC) != 0
+ || (sec->flags & SEC_MERGE) == 0)
+ abort ();
+
+ if (sec->size == 0
+ || (sec->flags & SEC_EXCLUDE) != 0
+ || sec->entsize == 0)
+ return TRUE;
+
+ if ((sec->flags & SEC_RELOC) != 0)
+ {
+ /* We aren't prepared to handle relocations in merged sections. */
+ return TRUE;
+ }
+
+ align = sec->alignment_power;
+ if ((sec->entsize < (unsigned) 1 << align
+ && ((sec->entsize & (sec->entsize - 1))
+ || !(sec->flags & SEC_STRINGS)))
+ || (sec->entsize > (unsigned) 1 << align
+ && (sec->entsize & (((unsigned) 1 << align) - 1))))
+ {
+ /* Sanity check. If string character size is smaller than
+ alignment, then we require character size to be a power
+ of 2, otherwise character size must be integer multiple
+ of alignment. For non-string constants, alignment must
+ be smaller than or equal to entity size and entity size
+ must be integer multiple of alignment. */
+ return TRUE;
+ }
+
+ for (sinfo = (struct sec_merge_info *) *psinfo; sinfo; sinfo = sinfo->next)
+ if ((secinfo = sinfo->chain)
+ && ! ((secinfo->sec->flags ^ sec->flags) & (SEC_MERGE | SEC_STRINGS))
+ && secinfo->sec->entsize == sec->entsize
+ && secinfo->sec->alignment_power == sec->alignment_power
+ && secinfo->sec->output_section == sec->output_section)
+ break;
+
+ if (sinfo == NULL)
+ {
+ /* Initialize the information we need to keep track of. */
+ sinfo = (struct sec_merge_info *)
+ bfd_alloc (abfd, sizeof (struct sec_merge_info));
+ if (sinfo == NULL)
+ goto error_return;
+ sinfo->next = (struct sec_merge_info *) *psinfo;
+ sinfo->chain = NULL;
+ *psinfo = sinfo;
+ sinfo->htab = sec_merge_init (sec->entsize, (sec->flags & SEC_STRINGS));
+ if (sinfo->htab == NULL)
+ goto error_return;
+ }
+
+ /* Read the section from abfd. */
+
+ amt = sizeof (struct sec_merge_sec_info) - 1 + sec->size;
+ if (sec->flags & SEC_STRINGS)
+ /* Some versions of gcc may emit a string without a zero terminator.
+ See http://gcc.gnu.org/ml/gcc-patches/2006-06/msg01004.html
+ Allocate space for an extra zero. */
+ amt += sec->entsize;
+ *psecinfo = bfd_alloc (abfd, amt);
+ if (*psecinfo == NULL)
+ goto error_return;
+
+ secinfo = (struct sec_merge_sec_info *) *psecinfo;
+ if (sinfo->chain)
+ {
+ secinfo->next = sinfo->chain->next;
+ sinfo->chain->next = secinfo;
+ }
+ else
+ secinfo->next = secinfo;
+ sinfo->chain = secinfo;
+ secinfo->sec = sec;
+ secinfo->psecinfo = psecinfo;
+ secinfo->htab = sinfo->htab;
+ secinfo->first_str = NULL;
+
+ sec->rawsize = sec->size;
+ if (sec->flags & SEC_STRINGS)
+ memset (secinfo->contents + sec->size, 0, sec->entsize);
+ contents = secinfo->contents;
+ if (! bfd_get_full_section_contents (sec->owner, sec, &contents))
+ goto error_return;
+
+ return TRUE;
+
+ error_return:
+ *psecinfo = NULL;
+ return FALSE;
+}
+
+/* Record one section into the hash table. */
+static bfd_boolean
+record_section (struct sec_merge_info *sinfo,
+ struct sec_merge_sec_info *secinfo)
+{
+ asection *sec = secinfo->sec;
+ struct sec_merge_hash_entry *entry;
+ bfd_boolean nul;
+ unsigned char *p, *end;
+ bfd_vma mask, eltalign;
+ unsigned int align, i;
+
+ align = sec->alignment_power;
+ end = secinfo->contents + sec->size;
+ nul = FALSE;
+ mask = ((bfd_vma) 1 << align) - 1;
+ if (sec->flags & SEC_STRINGS)
+ {
+ for (p = secinfo->contents; p < end; )
+ {
+ eltalign = p - secinfo->contents;
+ eltalign = ((eltalign ^ (eltalign - 1)) + 1) >> 1;
+ if (!eltalign || eltalign > mask)
+ eltalign = mask + 1;
+ entry = sec_merge_add (sinfo->htab, (char *) p, (unsigned) eltalign,
+ secinfo);
+ if (! entry)
+ goto error_return;
+ p += entry->len;
+ if (sec->entsize == 1)
+ {
+ while (p < end && *p == 0)
+ {
+ if (!nul && !((p - secinfo->contents) & mask))
+ {
+ nul = TRUE;
+ entry = sec_merge_add (sinfo->htab, "",
+ (unsigned) mask + 1, secinfo);
+ if (! entry)
+ goto error_return;
+ }
+ p++;
+ }
+ }
+ else
+ {
+ while (p < end)
+ {
+ for (i = 0; i < sec->entsize; i++)
+ if (p[i] != '\0')
+ break;
+ if (i != sec->entsize)
+ break;
+ if (!nul && !((p - secinfo->contents) & mask))
+ {
+ nul = TRUE;
+ entry = sec_merge_add (sinfo->htab, (char *) p,
+ (unsigned) mask + 1, secinfo);
+ if (! entry)
+ goto error_return;
+ }
+ p += sec->entsize;
+ }
+ }
+ }
+ }
+ else
+ {
+ for (p = secinfo->contents; p < end; p += sec->entsize)
+ {
+ entry = sec_merge_add (sinfo->htab, (char *) p, 1, secinfo);
+ if (! entry)
+ goto error_return;
+ }
+ }
+
+ return TRUE;
+
+error_return:
+ for (secinfo = sinfo->chain; secinfo; secinfo = secinfo->next)
+ *secinfo->psecinfo = NULL;
+ return FALSE;
+}
+
+static int
+strrevcmp (const void *a, const void *b)
+{
+ struct sec_merge_hash_entry *A = *(struct sec_merge_hash_entry **) a;
+ struct sec_merge_hash_entry *B = *(struct sec_merge_hash_entry **) b;
+ unsigned int lenA = A->len;
+ unsigned int lenB = B->len;
+ const unsigned char *s = (const unsigned char *) A->root.string + lenA - 1;
+ const unsigned char *t = (const unsigned char *) B->root.string + lenB - 1;
+ int l = lenA < lenB ? lenA : lenB;
+
+ while (l)
+ {
+ if (*s != *t)
+ return (int) *s - (int) *t;
+ s--;
+ t--;
+ l--;
+ }
+ return lenA - lenB;
+}
+
+/* Like strrevcmp, but for the case where all strings have the same
+ alignment > entsize. */
+
+static int
+strrevcmp_align (const void *a, const void *b)
+{
+ struct sec_merge_hash_entry *A = *(struct sec_merge_hash_entry **) a;
+ struct sec_merge_hash_entry *B = *(struct sec_merge_hash_entry **) b;
+ unsigned int lenA = A->len;
+ unsigned int lenB = B->len;
+ const unsigned char *s = (const unsigned char *) A->root.string + lenA - 1;
+ const unsigned char *t = (const unsigned char *) B->root.string + lenB - 1;
+ int l = lenA < lenB ? lenA : lenB;
+ int tail_align = (lenA & (A->alignment - 1)) - (lenB & (A->alignment - 1));
+
+ if (tail_align != 0)
+ return tail_align;
+
+ while (l)
+ {
+ if (*s != *t)
+ return (int) *s - (int) *t;
+ s--;
+ t--;
+ l--;
+ }
+ return lenA - lenB;
+}
+
+static inline int
+is_suffix (const struct sec_merge_hash_entry *A,
+ const struct sec_merge_hash_entry *B)
+{
+ if (A->len <= B->len)
+ /* B cannot be a suffix of A unless A is equal to B, which is guaranteed
+ not to be equal by the hash table. */
+ return 0;
+
+ return memcmp (A->root.string + (A->len - B->len),
+ B->root.string, B->len) == 0;
+}
+
+/* This is a helper function for _bfd_merge_sections. It attempts to
+ merge strings matching suffixes of longer strings. */
+static void
+merge_strings (struct sec_merge_info *sinfo)
+{
+ struct sec_merge_hash_entry **array, **a, *e;
+ struct sec_merge_sec_info *secinfo;
+ bfd_size_type size, amt;
+ unsigned int alignment = 0;
+
+ /* Now sort the strings */
+ amt = sinfo->htab->size * sizeof (struct sec_merge_hash_entry *);
+ array = (struct sec_merge_hash_entry **) bfd_malloc (amt);
+ if (array == NULL)
+ goto alloc_failure;
+
+ for (e = sinfo->htab->first, a = array; e; e = e->next)
+ if (e->alignment)
+ {
+ *a++ = e;
+ /* Adjust the length to not include the zero terminator. */
+ e->len -= sinfo->htab->entsize;
+ if (alignment != e->alignment)
+ {
+ if (alignment == 0)
+ alignment = e->alignment;
+ else
+ alignment = (unsigned) -1;
+ }
+ }
+
+ sinfo->htab->size = a - array;
+ if (sinfo->htab->size != 0)
+ {
+ qsort (array, (size_t) sinfo->htab->size,
+ sizeof (struct sec_merge_hash_entry *),
+ (alignment != (unsigned) -1 && alignment > sinfo->htab->entsize
+ ? strrevcmp_align : strrevcmp));
+
+ /* Loop over the sorted array and merge suffixes */
+ e = *--a;
+ e->len += sinfo->htab->entsize;
+ while (--a >= array)
+ {
+ struct sec_merge_hash_entry *cmp = *a;
+
+ cmp->len += sinfo->htab->entsize;
+ if (e->alignment >= cmp->alignment
+ && !((e->len - cmp->len) & (cmp->alignment - 1))
+ && is_suffix (e, cmp))
+ {
+ cmp->u.suffix = e;
+ cmp->alignment = 0;
+ }
+ else
+ e = cmp;
+ }
+ }
+
+alloc_failure:
+ if (array)
+ free (array);
+
+ /* Now assign positions to the strings we want to keep. */
+ size = 0;
+ secinfo = sinfo->htab->first->secinfo;
+ for (e = sinfo->htab->first; e; e = e->next)
+ {
+ if (e->secinfo != secinfo)
+ {
+ secinfo->sec->size = size;
+ secinfo = e->secinfo;
+ }
+ if (e->alignment)
+ {
+ if (e->secinfo->first_str == NULL)
+ {
+ e->secinfo->first_str = e;
+ size = 0;
+ }
+ size = (size + e->alignment - 1) & ~((bfd_vma) e->alignment - 1);
+ e->u.index = size;
+ size += e->len;
+ }
+ }
+ secinfo->sec->size = size;
+ if (secinfo->sec->alignment_power != 0)
+ {
+ bfd_size_type align = (bfd_size_type) 1 << secinfo->sec->alignment_power;
+ secinfo->sec->size = (secinfo->sec->size + align - 1) & -align;
+ }
+
+ /* And now adjust the rest, removing them from the chain (but not hashtable)
+ at the same time. */
+ for (a = &sinfo->htab->first, e = *a; e; e = e->next)
+ if (e->alignment)
+ a = &e->next;
+ else
+ {
+ *a = e->next;
+ if (e->len)
+ {
+ e->secinfo = e->u.suffix->secinfo;
+ e->alignment = e->u.suffix->alignment;
+ e->u.index = e->u.suffix->u.index + (e->u.suffix->len - e->len);
+ }
+ }
+}
+
+/* This function is called once after all SEC_MERGE sections are registered
+ with _bfd_merge_section. */
+
+bfd_boolean
+_bfd_merge_sections (bfd *abfd,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ void *xsinfo,
+ void (*remove_hook) (bfd *, asection *))
+{
+ struct sec_merge_info *sinfo;
+
+ for (sinfo = (struct sec_merge_info *) xsinfo; sinfo; sinfo = sinfo->next)
+ {
+ struct sec_merge_sec_info * secinfo;
+
+ if (! sinfo->chain)
+ continue;
+
+ /* Move sinfo->chain to head of the chain, terminate it. */
+ secinfo = sinfo->chain;
+ sinfo->chain = secinfo->next;
+ secinfo->next = NULL;
+
+ /* Record the sections into the hash table. */
+ for (secinfo = sinfo->chain; secinfo; secinfo = secinfo->next)
+ if (secinfo->sec->flags & SEC_EXCLUDE)
+ {
+ *secinfo->psecinfo = NULL;
+ if (remove_hook)
+ (*remove_hook) (abfd, secinfo->sec);
+ }
+ else if (! record_section (sinfo, secinfo))
+ break;
+
+ if (secinfo)
+ continue;
+
+ if (sinfo->htab->first == NULL)
+ continue;
+
+ if (sinfo->htab->strings)
+ merge_strings (sinfo);
+ else
+ {
+ struct sec_merge_hash_entry *e;
+ bfd_size_type size = 0;
+
+ /* Things are much simpler for non-strings.
+ Just assign them slots in the section. */
+ secinfo = NULL;
+ for (e = sinfo->htab->first; e; e = e->next)
+ {
+ if (e->secinfo->first_str == NULL)
+ {
+ if (secinfo)
+ secinfo->sec->size = size;
+ e->secinfo->first_str = e;
+ size = 0;
+ }
+ size = (size + e->alignment - 1)
+ & ~((bfd_vma) e->alignment - 1);
+ e->u.index = size;
+ size += e->len;
+ secinfo = e->secinfo;
+ }
+ secinfo->sec->size = size;
+ }
+
+ /* Finally remove all input sections which have not made it into
+ the hash table at all. */
+ for (secinfo = sinfo->chain; secinfo; secinfo = secinfo->next)
+ if (secinfo->first_str == NULL)
+ secinfo->sec->flags |= SEC_EXCLUDE | SEC_KEEP;
+ }
+
+ return TRUE;
+}
+
+/* Write out the merged section. */
+
+bfd_boolean
+_bfd_write_merged_section (bfd *output_bfd, asection *sec, void *psecinfo)
+{
+ struct sec_merge_sec_info *secinfo;
+ file_ptr pos;
+
+ secinfo = (struct sec_merge_sec_info *) psecinfo;
+
+ if (!secinfo)
+ return FALSE;
+
+ if (secinfo->first_str == NULL)
+ return TRUE;
+
+ /* FIXME: octets_per_byte. */
+ pos = sec->output_section->filepos + sec->output_offset;
+ if (bfd_seek (output_bfd, pos, SEEK_SET) != 0)
+ return FALSE;
+
+ if (! sec_merge_emit (output_bfd, secinfo->first_str))
+ return FALSE;
+
+ return TRUE;
+}
+
+/* Adjust an address in the SEC_MERGE section. Given OFFSET within
+ *PSEC, this returns the new offset in the adjusted SEC_MERGE
+ section and writes the new section back into *PSEC. */
+
+bfd_vma
+_bfd_merged_section_offset (bfd *output_bfd ATTRIBUTE_UNUSED, asection **psec,
+ void *psecinfo, bfd_vma offset)
+{
+ struct sec_merge_sec_info *secinfo;
+ struct sec_merge_hash_entry *entry;
+ unsigned char *p;
+ asection *sec = *psec;
+
+ secinfo = (struct sec_merge_sec_info *) psecinfo;
+
+ if (!secinfo)
+ return offset;
+
+ if (offset >= sec->rawsize)
+ {
+ if (offset > sec->rawsize)
+ {
+ (*_bfd_error_handler)
+ (_("%s: access beyond end of merged section (%ld)"),
+ bfd_get_filename (sec->owner), (long) offset);
+ }
+ return secinfo->first_str ? sec->size : 0;
+ }
+
+ if (secinfo->htab->strings)
+ {
+ if (sec->entsize == 1)
+ {
+ p = secinfo->contents + offset - 1;
+ while (p >= secinfo->contents && *p)
+ --p;
+ ++p;
+ }
+ else
+ {
+ p = secinfo->contents + (offset / sec->entsize) * sec->entsize;
+ p -= sec->entsize;
+ while (p >= secinfo->contents)
+ {
+ unsigned int i;
+
+ for (i = 0; i < sec->entsize; ++i)
+ if (p[i] != '\0')
+ break;
+ if (i == sec->entsize)
+ break;
+ p -= sec->entsize;
+ }
+ p += sec->entsize;
+ }
+ }
+ else
+ {
+ p = secinfo->contents + (offset / sec->entsize) * sec->entsize;
+ }
+ entry = sec_merge_hash_lookup (secinfo->htab, (char *) p, 0, FALSE);
+ if (!entry)
+ {
+ if (! secinfo->htab->strings)
+ abort ();
+ /* This should only happen if somebody points into the padding
+ after a NUL character but before next entity. */
+ if (*p)
+ abort ();
+ if (! secinfo->htab->first)
+ abort ();
+ entry = secinfo->htab->first;
+ p = (secinfo->contents + (offset / sec->entsize + 1) * sec->entsize
+ - entry->len);
+ }
+
+ *psec = entry->secinfo->sec;
+ return entry->u.index + (secinfo->contents + offset - p);
+}
+
+/* Tidy up when done. */
+
+void
+_bfd_merge_sections_free (void *xsinfo)
+{
+ struct sec_merge_info *sinfo;
+
+ for (sinfo = (struct sec_merge_info *) xsinfo; sinfo; sinfo = sinfo->next)
+ {
+ bfd_hash_table_free (&sinfo->htab->table);
+ free (sinfo->htab);
+ }
+}
diff --git a/bfd/mipsbsd.c b/bfd/mipsbsd.c
new file mode 100644
index 0000000..d124cfd
--- /dev/null
+++ b/bfd/mipsbsd.c
@@ -0,0 +1,485 @@
+/* BFD backend for MIPS BSD (a.out) binaries.
+ Copyright (C) 1993-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+
+/* #define ENTRY_CAN_BE_ZERO */
+#define N_HEADER_IN_TEXT(x) 1
+#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'
+
+/* Do not "beautify" the CONCAT* macro args. Traditional C will not
+ remove whitespace added here, and thus will fail to concatenate
+ the tokens. */
+#define MY(OP) CONCAT2 (mipsbsd_,OP)
+
+#include "sysdep.h"
+#include "bfd.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) (bfd *, unsigned long);
+static void MY(choose_reloc_size) (bfd *);
+
+#define MY_write_object_contents MY(write_object_contents)
+static bfd_boolean MY(write_object_contents) (bfd *);
+
+/* We can't use MY(x) here because it leads to a recursive call to CONCAT2
+ when expanded inside JUMP_TABLE. */
+#define MY_bfd_reloc_type_lookup mipsbsd_reloc_type_lookup
+#define MY_bfd_reloc_name_lookup mipsbsd_reloc_name_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 bfd_reloc_status_type mips_fix_jmp_addr
+ (bfd *, arelent *, struct bfd_symbol *, void *, asection *,
+ bfd *, char **);
+
+long MY(canonicalize_reloc) (bfd *, sec_ptr, arelent **, asymbol **);
+
+static void
+MY(set_arch_mach) (bfd *abfd, unsigned long machtype)
+{
+ enum bfd_architecture arch;
+ unsigned int machine;
+
+ /* Determine the architecture and machine type of the object file. */
+ switch (machtype)
+ {
+ case M_MIPS1:
+ arch = bfd_arch_mips;
+ machine = bfd_mach_mips3000;
+ break;
+
+ case M_MIPS2:
+ arch = bfd_arch_mips;
+ machine = bfd_mach_mips4000;
+ 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) (bfd *abfd)
+{
+ switch (bfd_get_arch (abfd))
+ {
+ case bfd_arch_sparc:
+ 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 bfd_boolean
+MY (write_object_contents) (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_mips:
+ switch (bfd_get_mach (abfd))
+ {
+ case bfd_mach_mips4000:
+ case bfd_mach_mips6000:
+ 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 (bfd *abfd ATTRIBUTE_UNUSED,
+ arelent *reloc_entry,
+ struct bfd_symbol *symbol,
+ void * data ATTRIBUTE_UNUSED,
+ asection *input_section,
+ bfd *output_bfd,
+ char **error_message ATTRIBUTE_UNUSED)
+{
+ 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 targeted 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 (bfd *abfd ATTRIBUTE_UNUSED,
+ arelent *reloc_entry,
+ asymbol *symbol,
+ void * data ATTRIBUTE_UNUSED,
+ asection *input_section ATTRIBUTE_UNUSED,
+ bfd *output_bfd,
+ char **error_message ATTRIBUTE_UNUSED)
+{
+ 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 targeted 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_type_lookup) (bfd *abfd, bfd_reloc_code_real_type code)
+{
+ if (bfd_get_arch (abfd) != bfd_arch_mips)
+ return NULL;
+
+ 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 NULL;
+ }
+}
+
+static reloc_howto_type *
+MY(reloc_name_lookup) (bfd *abfd ATTRIBUTE_UNUSED,
+ const char *r_name)
+{
+ unsigned int i;
+
+ for (i = 0;
+ i < sizeof (mips_howto_table_ext) / sizeof (mips_howto_table_ext[0]);
+ i++)
+ if (mips_howto_table_ext[i].name != NULL
+ && strcasecmp (mips_howto_table_ext[i].name, r_name) == 0)
+ return &mips_howto_table_ext[i];
+
+ return NULL;
+}
+
+/* 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) (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 */
+};
+
+extern const bfd_target mips_aout_be_vec;
+
+const bfd_target mips_aout_le_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 */
+ 0, /* match priority. */
+ 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),
+
+ & mips_aout_be_vec,
+
+ MY_backend_data
+ };
+
+const bfd_target mips_aout_be_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 */
+ 0, /* match priority. */
+ 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),
+
+ & mips_aout_le_vec,
+
+ MY_backend_data
+ };
diff --git a/bfd/mmo.c b/bfd/mmo.c
new file mode 100644
index 0000000..2c74c76
--- /dev/null
+++ b/bfd/mmo.c
@@ -0,0 +1,3313 @@
+/* BFD back-end for mmo objects (MMIX-specific object-format).
+ Copyright (C) 2001-2014 Free Software Foundation, Inc.
+ Written by Hans-Peter Nilsson (hp@bitrange.com).
+ Infrastructure and other bits originally copied from srec.c and
+ binary.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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+
+/*
+SECTION
+ mmo backend
+
+ The mmo object format is used exclusively together with Professor
+ Donald E.@: Knuth's educational 64-bit processor MMIX. The simulator
+ @command{mmix} which is available at
+ @url{http://mmix.cs.hm.edu/src/index.html}
+ understands this format. That package also includes a combined
+ assembler and linker called @command{mmixal}. The mmo format has
+ no advantages feature-wise compared to e.g. ELF. It is a simple
+ non-relocatable object format with no support for archives or
+ debugging information, except for symbol value information and
+ line numbers (which is not yet implemented in BFD). See
+ @url{http://mmix.cs.hm.edu/} for more
+ information about MMIX. The ELF format is used for intermediate
+ object files in the BFD implementation.
+
+@c We want to xref the symbol table node. A feature in "chew"
+@c requires that "commands" do not contain spaces in the
+@c arguments. Hence the hyphen in "Symbol-table".
+@menu
+@* File layout::
+@* Symbol-table::
+@* mmo section mapping::
+@end menu
+
+INODE
+File layout, Symbol-table, mmo, mmo
+SUBSECTION
+ File layout
+
+ The mmo file contents is not partitioned into named sections as
+ with e.g.@: ELF. Memory areas is formed by specifying the
+ location of the data that follows. Only the memory area
+ @samp{0x0000@dots{}00} to @samp{0x01ff@dots{}ff} is executable, so
+ it is used for code (and constants) and the area
+ @samp{0x2000@dots{}00} to @samp{0x20ff@dots{}ff} is used for
+ writable data. @xref{mmo section mapping}.
+
+ There is provision for specifying ``special data'' of 65536
+ different types. We use type 80 (decimal), arbitrarily chosen the
+ same as the ELF <<e_machine>> number for MMIX, filling it with
+ section information normally found in ELF objects. @xref{mmo
+ section mapping}.
+
+ Contents is entered as 32-bit words, xor:ed over previous
+ contents, always zero-initialized. A word that starts with the
+ byte @samp{0x98} forms a command called a @samp{lopcode}, where
+ the next byte distinguished between the thirteen lopcodes. The
+ two remaining bytes, called the @samp{Y} and @samp{Z} fields, or
+ the @samp{YZ} field (a 16-bit big-endian number), are used for
+ various purposes different for each lopcode. As documented in
+ @url{http://mmix.cs.hm.edu/doc/mmixal.pdf},
+ the lopcodes are:
+
+ @table @code
+ @item lop_quote
+ 0x98000001. The next word is contents, regardless of whether it
+ starts with 0x98 or not.
+
+ @item lop_loc
+ 0x9801YYZZ, where @samp{Z} is 1 or 2. This is a location
+ directive, setting the location for the next data to the next
+ 32-bit word (for @math{Z = 1}) or 64-bit word (for @math{Z = 2}),
+ plus @math{Y * 2^56}. Normally @samp{Y} is 0 for the text segment
+ and 2 for the data segment. Beware that the low bits of non-
+ tetrabyte-aligned values are silently discarded when being
+ automatically incremented and when storing contents (in contrast
+ to e.g. its use as current location when followed by lop_fixo
+ et al before the next possibly-quoted tetrabyte contents).
+
+ @item lop_skip
+ 0x9802YYZZ. Increase the current location by @samp{YZ} bytes.
+
+ @item lop_fixo
+ 0x9803YYZZ, where @samp{Z} is 1 or 2. Store the current location
+ as 64 bits into the location pointed to by the next 32-bit
+ (@math{Z = 1}) or 64-bit (@math{Z = 2}) word, plus @math{Y *
+ 2^56}.
+
+ @item lop_fixr
+ 0x9804YYZZ. @samp{YZ} is stored into the current location plus
+ @math{2 - 4 * YZ}.
+
+ @item lop_fixrx
+ 0x980500ZZ. @samp{Z} is 16 or 24. A value @samp{L} derived from
+ the following 32-bit word are used in a manner similar to
+ @samp{YZ} in lop_fixr: it is xor:ed into the current location
+ minus @math{4 * L}. The first byte of the word is 0 or 1. If it
+ is 1, then @math{L = (@var{lowest 24 bits of word}) - 2^Z}, if 0,
+ then @math{L = (@var{lowest 24 bits of word})}.
+
+ @item lop_file
+ 0x9806YYZZ. @samp{Y} is the file number, @samp{Z} is count of
+ 32-bit words. Set the file number to @samp{Y} and the line
+ counter to 0. The next @math{Z * 4} bytes contain the file name,
+ padded with zeros if the count is not a multiple of four. The
+ same @samp{Y} may occur multiple times, but @samp{Z} must be 0 for
+ all but the first occurrence.
+
+ @item lop_line
+ 0x9807YYZZ. @samp{YZ} is the line number. Together with
+ lop_file, it forms the source location for the next 32-bit word.
+ Note that for each non-lopcode 32-bit word, line numbers are
+ assumed incremented by one.
+
+ @item lop_spec
+ 0x9808YYZZ. @samp{YZ} is the type number. Data until the next
+ lopcode other than lop_quote forms special data of type @samp{YZ}.
+ @xref{mmo section mapping}.
+
+ Other types than 80, (or type 80 with a content that does not
+ parse) is stored in sections named <<.MMIX.spec_data.@var{n}>>
+ where @var{n} is the @samp{YZ}-type. The flags for such a
+ sections say not to allocate or load the data. The vma is 0.
+ Contents of multiple occurrences of special data @var{n} is
+ concatenated to the data of the previous lop_spec @var{n}s. The
+ location in data or code at which the lop_spec occurred is lost.
+
+ @item lop_pre
+ 0x980901ZZ. The first lopcode in a file. The @samp{Z} field forms the
+ length of header information in 32-bit words, where the first word
+ tells the time in seconds since @samp{00:00:00 GMT Jan 1 1970}.
+
+ @item lop_post
+ 0x980a00ZZ. @math{Z > 32}. This lopcode follows after all
+ content-generating lopcodes in a program. The @samp{Z} field
+ denotes the value of @samp{rG} at the beginning of the program.
+ The following @math{256 - Z} big-endian 64-bit words are loaded
+ into global registers @samp{$G} @dots{} @samp{$255}.
+
+ @item lop_stab
+ 0x980b0000. The next-to-last lopcode in a program. Must follow
+ immediately after the lop_post lopcode and its data. After this
+ lopcode follows all symbols in a compressed format
+ (@pxref{Symbol-table}).
+
+ @item lop_end
+ 0x980cYYZZ. The last lopcode in a program. It must follow the
+ lop_stab lopcode and its data. The @samp{YZ} field contains the
+ number of 32-bit words of symbol table information after the
+ preceding lop_stab lopcode.
+ @end table
+
+ Note that the lopcode "fixups"; <<lop_fixr>>, <<lop_fixrx>> and
+ <<lop_fixo>> are not generated by BFD, but are handled. They are
+ generated by <<mmixal>>.
+
+EXAMPLE
+ This trivial one-label, one-instruction file:
+
+| :Main TRAP 1,2,3
+
+ can be represented this way in mmo:
+
+| 0x98090101 - lop_pre, one 32-bit word with timestamp.
+| <timestamp>
+| 0x98010002 - lop_loc, text segment, using a 64-bit address.
+| Note that mmixal does not emit this for the file above.
+| 0x00000000 - Address, high 32 bits.
+| 0x00000000 - Address, low 32 bits.
+| 0x98060002 - lop_file, 2 32-bit words for file-name.
+| 0x74657374 - "test"
+| 0x2e730000 - ".s\0\0"
+| 0x98070001 - lop_line, line 1.
+| 0x00010203 - TRAP 1,2,3
+| 0x980a00ff - lop_post, setting $255 to 0.
+| 0x00000000
+| 0x00000000
+| 0x980b0000 - lop_stab for ":Main" = 0, serial 1.
+| 0x203a4040 @xref{Symbol-table}.
+| 0x10404020
+| 0x4d206120
+| 0x69016e00
+| 0x81000000
+| 0x980c0005 - lop_end; symbol table contained five 32-bit words. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+#include "libiberty.h"
+#include "elf/mmix.h"
+#include "opcode/mmix.h"
+
+#define LOP 0x98
+#define LOP_QUOTE 0
+#define LOP_LOC 1
+#define LOP_SKIP 2
+#define LOP_FIXO 3
+#define LOP_FIXR 4
+#define LOP_FIXRX 5
+#define LOP_FILE 6
+#define LOP_LINE 7
+#define LOP_SPEC 8
+#define LOP_PRE 9
+#define LOP_POST 10
+#define LOP_STAB 11
+#define LOP_END 12
+
+#define LOP_QUOTE_NEXT ((LOP << 24) | (LOP_QUOTE << 16) | 1)
+#define SPEC_DATA_SECTION 80
+#define LOP_SPEC_SECTION \
+ ((LOP << 24) | (LOP_SPEC << 16) | SPEC_DATA_SECTION)
+
+/* Must be a power of two. If you change this to be >= 64k, you need a
+ new test-case; the ld test b-loc64k.d touches chunk-size problem areas. */
+#define MMO_SEC_CONTENTS_CHUNK_SIZE (1 << 15)
+
+/* An arbitrary number for the maximum length section name size. */
+#define MAX_SECTION_NAME_SIZE (1024 * 1024)
+
+/* A quite arbitrary number for the maximum length section size. */
+#define MAX_ARTIFICIAL_SECTION_SIZE (1024 * 1024 * 1024)
+
+#define MMO3_WCHAR 0x80
+#define MMO3_LEFT 0x40
+#define MMO3_MIDDLE 0x20
+#define MMO3_RIGHT 0x10
+#define MMO3_TYPEBITS 0xf
+#define MMO3_REGQUAL_BITS 0xf
+#define MMO3_UNDEF 2
+#define MMO3_DATA 8
+#define MMO3_SYMBITS 0x2f
+
+/* Put these everywhere in new code. */
+#define FATAL_DEBUG \
+ _bfd_abort (__FILE__, __LINE__, \
+ "Internal: Non-debugged code (test-case missing)")
+
+#define BAD_CASE(x) \
+ _bfd_abort (__FILE__, __LINE__, \
+ "bad case for " #x)
+
+enum mmo_sym_type { mmo_reg_sym, mmo_undef_sym, mmo_data_sym, mmo_abs_sym};
+
+/* When scanning the mmo file, a linked list of mmo_symbol
+ structures is built to represent the symbol table (if there is
+ one). */
+
+struct mmo_symbol
+ {
+ struct mmo_symbol *next;
+ char *name;
+ bfd_vma value;
+ enum mmo_sym_type sym_type;
+ unsigned int serno;
+ };
+
+struct mmo_data_list_struct
+ {
+ struct mmo_data_list_struct *next;
+ bfd_vma where;
+ bfd_size_type size;
+ bfd_size_type allocated_size;
+ bfd_byte data[1];
+ };
+
+typedef struct mmo_data_list_struct mmo_data_list_type;
+
+struct mmo_symbol_trie
+ {
+ struct mmo_symbol_trie *left;
+ struct mmo_symbol_trie *right;
+ struct mmo_symbol_trie *middle;
+
+ bfd_byte symchar;
+
+ /* A zero name means there's nothing here. */
+ struct mmo_symbol sym;
+ };
+
+/* The mmo tdata information. */
+
+struct mmo_data_struct
+ {
+ struct mmo_symbol *symbols;
+ struct mmo_symbol *symtail;
+ asymbol *csymbols;
+
+ /* File representation of time (NULL) when this file was created. */
+ bfd_byte created[4];
+
+ /* When we're reading bytes recursively, check this occasionally.
+ Also holds write errors. */
+ bfd_boolean have_error;
+
+ /* Max symbol length that may appear in the lop_stab table. Note that
+ this table might just hold a subset of symbols for not-really large
+ programs, as it can only be 65536 * 4 bytes large. */
+ int max_symbol_length;
+
+ /* Here's the symbol we build in lop_stab. */
+ char *lop_stab_symbol;
+
+ /* Index into lop_stab_symbol for the next character when parsing the
+ symbol information. */
+ int symbol_position;
+
+ /* When creating arbitrary sections, we need to count section numbers. */
+ int sec_no;
+
+ /* When writing or reading byte-wise, we need to count the bytes
+ within a 32-bit word. */
+ int byte_no;
+
+ /* We also need a buffer to hold the bytes we count reading or writing. */
+ bfd_byte buf[4];
+ };
+
+typedef struct mmo_data_struct tdata_type;
+
+struct mmo_section_data_struct
+ {
+ mmo_data_list_type *head;
+ mmo_data_list_type *tail;
+ };
+
+#define mmo_section_data(sec) \
+ ((struct mmo_section_data_struct *) (sec)->used_by_bfd)
+
+/* These structures are used in bfd_map_over_sections constructs. */
+
+/* Used when writing out sections; all but the register contents section
+ which is stored in reg_section. */
+struct mmo_write_sec_info
+ {
+ asection *reg_section;
+ bfd_boolean retval;
+ };
+
+/* Used when trying to find a section corresponding to addr. */
+struct mmo_find_sec_info
+ {
+ asection *sec;
+ bfd_vma addr;
+ };
+
+static bfd_boolean mmo_bfd_copy_private_bfd_data (bfd *, bfd *);
+static void mmo_write_section_unless_reg_contents (bfd *, asection *, void *);
+static void mmo_find_sec_w_addr (bfd *, asection *, void *);
+static void mmo_find_sec_w_addr_grow (bfd *, asection *, void *);
+static asection *mmo_make_section (bfd *, const char *);
+static void mmo_get_symbol_info (bfd *, asymbol *, symbol_info *);
+static void mmo_print_symbol (bfd *, void *, asymbol *,
+ bfd_print_symbol_type);
+static void mmo_init (void);
+static bfd_boolean mmo_mkobject (bfd *);
+static bfd_boolean mmo_scan (bfd *);
+static asection *mmo_decide_section (bfd *, bfd_vma);
+static asection *mmo_get_generic_spec_data_section (bfd *, int);
+static asection *mmo_get_spec_section (bfd *, int);
+static INLINE bfd_byte *mmo_get_loc (asection *, bfd_vma, int);
+static void mmo_xore_64 (asection *, bfd_vma vma, bfd_vma value);
+static void mmo_xore_32 (asection *, bfd_vma vma, unsigned int);
+static void mmo_xore_16 (asection *, bfd_vma vma, unsigned int);
+static const bfd_target *mmo_object_p (bfd *);
+static void mmo_map_set_sizes (bfd *, asection *, void *);
+static bfd_boolean mmo_get_symbols (bfd *);
+static bfd_boolean mmo_create_symbol (bfd *, const char *, bfd_vma,
+ enum mmo_sym_type, unsigned int);
+static bfd_boolean mmo_get_section_contents (bfd *, asection *, void *,
+ file_ptr, bfd_size_type);
+static long mmo_get_symtab_upper_bound (bfd *);
+static long mmo_canonicalize_symtab (bfd *, asymbol **);
+static void mmo_get_symbol_info (bfd *, asymbol *, symbol_info *);
+static void mmo_print_symbol (bfd *, void *, asymbol *,
+ bfd_print_symbol_type);
+static bfd_boolean mmo_set_section_contents (bfd *, sec_ptr, const void *,
+ file_ptr, bfd_size_type);
+static int mmo_sizeof_headers (bfd *, struct bfd_link_info *);
+static bfd_boolean mmo_internal_write_header (bfd *);
+static bfd_boolean mmo_internal_write_post (bfd *, int, asection *);
+static bfd_boolean mmo_internal_add_3_sym (bfd *, struct mmo_symbol_trie *,
+ const struct mmo_symbol *);
+static unsigned int mmo_internal_3_length (bfd *, struct mmo_symbol_trie *);
+static void mmo_internal_3_dump (bfd *, struct mmo_symbol_trie *);
+static void mmo_beb128_out (bfd *, int, int);
+static bfd_boolean mmo_internal_write_section (bfd *, asection *);
+static void mmo_write_tetra (bfd *, unsigned int);
+static void mmo_write_tetra_raw (bfd *, unsigned int);
+static void mmo_write_octa (bfd *, bfd_vma);
+static void mmo_write_octa_raw (bfd *, bfd_vma);
+static bfd_boolean mmo_write_chunk (bfd *, const bfd_byte *, unsigned int);
+static bfd_boolean mmo_flush_chunk (bfd *);
+static bfd_boolean mmo_write_loc_chunk (bfd *, bfd_vma, const bfd_byte *,
+ unsigned int, bfd_vma *);
+static bfd_boolean mmo_write_chunk_list (bfd *, mmo_data_list_type *);
+static bfd_boolean mmo_write_loc_chunk_list (bfd *, mmo_data_list_type *);
+static bfd_boolean mmo_write_symbols_and_terminator (bfd *);
+static flagword mmo_sec_flags_from_bfd_flags (flagword);
+static flagword bfd_sec_flags_from_mmo_flags (flagword);
+static bfd_byte mmo_get_byte (bfd *);
+static void mmo_write_byte (bfd *, bfd_byte);
+static bfd_boolean mmo_new_section_hook (bfd *, asection *);
+static int mmo_sort_mmo_symbols (const void *, const void *);
+static bfd_boolean mmo_write_object_contents (bfd *);
+static bfd_boolean mmo_write_section_description (bfd *, asection *);
+static bfd_boolean mmo_has_leading_or_trailing_zero_tetra_p (bfd *,
+ asection *);
+
+/* Global "const" variables initialized once. Must not depend on
+ particular input or caller; put such things into the bfd or elsewhere.
+ Look ma, no static per-invocation data! */
+
+static
+char valid_mmo_symbol_character_set[/* A-Z a-z (we assume consecutive
+ codes; sorry EBCDIC:ers!). */
+ + 'Z' - 'A' + 1 + 'z' - 'a' + 1
+ /* Digits. */
+ + 10
+ /* ':' and '_'. */
+ + 1 + 1
+ /* Codes higher than 126. */
+ + 256 - 126
+ /* Ending zero. */
+ + 1];
+
+
+/* Get section SECNAME or create one if it doesn't exist. When creating
+ one, new memory for the name is allocated. */
+
+static asection *
+mmo_make_section (bfd *abfd, const char *secname)
+{
+ asection *sec = bfd_get_section_by_name (abfd, secname);
+
+ if (sec == NULL)
+ {
+ char *newsecname = strdup (secname);
+
+ if (newsecname == NULL)
+ {
+ (*_bfd_error_handler)
+ (_("%s: No core to allocate section name %s\n"),
+ bfd_get_filename (abfd), secname);
+ bfd_set_error (bfd_error_system_call);
+ return NULL;
+ }
+ sec = bfd_make_section (abfd, newsecname);
+ }
+
+ return sec;
+}
+
+/* Nothing to do, but keep as a placeholder if we need it.
+ Note that state that might differ between bfd:s must not be initialized
+ here, nor must it be static. Add it to tdata information instead. */
+
+static void
+mmo_init (void)
+{
+ static bfd_boolean inited = FALSE;
+ int i = 0;
+ int j = 0;
+ static const char letters[]
+ = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789:_";
+
+ if (inited)
+ return;
+ inited = TRUE;
+
+ /* Fill in the set of valid symbol characters. */
+ strcpy (valid_mmo_symbol_character_set, letters);
+ i = strlen (letters);
+
+ for (j = 126; j < 256; j++)
+ valid_mmo_symbol_character_set[i++] = j;
+}
+
+/* Check whether an existing file is an mmo file. */
+
+static const bfd_target *
+mmo_object_p (bfd *abfd)
+{
+ struct stat statbuf;
+ bfd_byte b[4];
+
+ mmo_init ();
+
+ if (bfd_stat (abfd, &statbuf) < 0
+ || bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0
+ || bfd_bread (b, 4, abfd) != 4)
+ goto bad_final;
+
+ /* All mmo files are a multiple of four bytes long.
+ Only recognize version one. */
+ if ((statbuf.st_size % 4) != 0
+ || b[0] != LOP || b[1] != LOP_PRE || b[2] != 1)
+ goto bad_format;
+
+ /* Get the last 32-bit word. */
+ if (bfd_seek (abfd, (file_ptr) statbuf.st_size - 4, SEEK_SET) != 0
+ || bfd_bread (b, 4, abfd) != 4)
+ goto bad_final;
+
+ /* Check if the file ends in a lop_end lopcode. */
+ if (b[0] != LOP || b[1] != LOP_END || ! mmo_mkobject (abfd))
+ goto bad_format;
+
+ /* Compute an upper bound on the max symbol length. Not really
+ important as all of the symbol information can only be 256k. */
+ abfd->tdata.mmo_data->max_symbol_length = (b[2] * 256 + b[3]) * 4;
+ abfd->tdata.mmo_data->lop_stab_symbol
+ = bfd_malloc (abfd->tdata.mmo_data->max_symbol_length + 1);
+
+ if (abfd->tdata.mmo_data->lop_stab_symbol == NULL)
+ {
+ (*_bfd_error_handler)
+ (_("%s: No core to allocate a symbol %d bytes long\n"),
+ bfd_get_filename (abfd), abfd->tdata.mmo_data->max_symbol_length);
+ goto bad_final;
+ }
+
+ /* Read in everything. */
+ if (! mmo_scan (abfd))
+ goto bad_format_free;
+
+ if (abfd->symcount > 0)
+ abfd->flags |= HAS_SYMS;
+
+ /* You'll have to tweak this if you want to use this format for other
+ arches (not recommended due to its small-size limitations). Look at
+ the ELF format for how to make it target-generic. */
+ if (! bfd_default_set_arch_mach (abfd, bfd_arch_mmix, 0))
+ goto bad_format_free;
+
+ return abfd->xvec;
+
+ bad_format_free:
+ free (abfd->tdata.mmo_data->lop_stab_symbol);
+ bad_format:
+ bfd_set_error (bfd_error_wrong_format);
+ bad_final:
+ return NULL;
+}
+
+/* Set up the mmo tdata information. */
+
+static bfd_boolean
+mmo_mkobject (bfd *abfd)
+{
+ mmo_init ();
+
+ if (abfd->tdata.mmo_data == NULL)
+ {
+ time_t created;
+
+ /* All fields are zero-initialized, so we don't have to explicitly
+ initialize most. */
+ tdata_type *tdata = (tdata_type *) bfd_zmalloc (sizeof (tdata_type));
+ if (tdata == NULL)
+ return FALSE;
+
+ created = time (NULL);
+ bfd_put_32 (abfd, created, tdata->created);
+
+ abfd->tdata.mmo_data = tdata;
+ }
+
+ return TRUE;
+}
+
+static bfd_boolean
+mmo_bfd_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
+{
+ if (bfd_get_flavour (ibfd) != bfd_target_mmo_flavour
+ || bfd_get_flavour (obfd) != bfd_target_mmo_flavour)
+ return TRUE;
+
+ /* Copy the time the copied-from file was created. If people want the
+ time the file was last *modified*, they have that in the normal file
+ information. */
+ memcpy (obfd->tdata.mmo_data->created, ibfd->tdata.mmo_data->created,
+ sizeof (obfd->tdata.mmo_data->created));
+ return TRUE;
+}
+
+/* Helper functions for mmo_decide_section, used through
+ bfd_map_over_sections. */
+
+static void
+mmo_find_sec_w_addr (bfd *abfd ATTRIBUTE_UNUSED, asection *sec, void *p)
+{
+ struct mmo_find_sec_info *infop = (struct mmo_find_sec_info *) p;
+ bfd_vma vma = bfd_get_section_vma (abfd, sec);
+
+ /* Ignore sections that aren't loaded. */
+ if ((bfd_get_section_flags (abfd, sec) & (SEC_LOAD | SEC_ALLOC))
+ != (SEC_LOAD | SEC_ALLOC))
+ return;
+
+ if (infop->addr >= vma && infop->addr < vma + sec->size)
+ infop->sec = sec;
+}
+
+static void
+mmo_find_sec_w_addr_grow (bfd *abfd ATTRIBUTE_UNUSED, asection *sec, void *p)
+{
+ struct mmo_find_sec_info *infop = (struct mmo_find_sec_info *) p;
+ bfd_vma vma = bfd_get_section_vma (abfd, sec);
+
+ /* Ignore sections that aren't loaded. */
+ if ((bfd_get_section_flags (abfd, sec) & (SEC_LOAD | SEC_ALLOC))
+ != (SEC_LOAD | SEC_ALLOC))
+ return;
+
+ if (infop->addr >= vma && infop->addr < vma + MAX_ARTIFICIAL_SECTION_SIZE)
+ infop->sec = sec;
+}
+
+/* Find a section that corresponds to a VMA. Automatically create .text
+ or .data and set current section to it, depending on what vma. If we
+ can't deduce a section, make one up as ".MMIX.sec.N", where N is an
+ increasing number. */
+
+static asection *
+mmo_decide_section (bfd *abfd, bfd_vma vma)
+{
+ asection *sec = NULL;
+ char sec_name[sizeof (".MMIX.sec.") + 20];
+ struct mmo_find_sec_info info;
+
+ info.addr = vma;
+ info.sec = NULL;
+
+ /* First see if there's a section that would match exactly. */
+ bfd_map_over_sections (abfd, mmo_find_sec_w_addr, &info);
+
+ if (info.sec != NULL)
+ return info.sec;
+
+ /* If there's no such section, try and expand one of the existing ones,
+ up to a limit. Make sure we have .text and .data before we try that;
+ create them corresponding to expected addresses and set flags to make
+ them match the "loaded and with contents" expectation. */
+ if ((vma >> 56) == 0)
+ {
+ sec = bfd_make_section_old_way (abfd, MMO_TEXT_SECTION_NAME);
+
+ if (sec == NULL)
+ return NULL;
+
+ if (! sec->user_set_vma && ! bfd_set_section_vma (abfd, sec, vma))
+ return NULL;
+
+ if (! bfd_set_section_flags (abfd, sec,
+ bfd_get_section_flags (abfd, sec)
+ | SEC_CODE | SEC_LOAD | SEC_ALLOC))
+ return NULL;
+ }
+ else if ((vma >> 56) == 0x20)
+ {
+ sec = bfd_make_section_old_way (abfd, MMO_DATA_SECTION_NAME);
+
+ if (sec == NULL)
+ return NULL;
+
+ if (! sec->user_set_vma && ! bfd_set_section_vma (abfd, sec, vma))
+ return NULL;
+
+ if (! bfd_set_section_flags (abfd, sec,
+ bfd_get_section_flags (abfd, sec)
+ | SEC_LOAD | SEC_ALLOC))
+ return NULL;
+ }
+
+ bfd_map_over_sections (abfd, mmo_find_sec_w_addr_grow, &info);
+
+ if (info.sec != NULL)
+ return info.sec;
+
+ /* If there's still no suitable section, make a new one. */
+ sprintf (sec_name, ".MMIX.sec.%d", abfd->tdata.mmo_data->sec_no++);
+ sec = mmo_make_section (abfd, sec_name);
+
+ if (! sec->user_set_vma && ! bfd_set_section_vma (abfd, sec, vma))
+ return NULL;
+
+ if (! bfd_set_section_flags (abfd, sec,
+ bfd_get_section_flags (abfd, sec)
+ | SEC_LOAD | SEC_ALLOC))
+ return NULL;
+ return sec;
+}
+
+/* Xor in a 64-bit value VALUE at VMA. */
+
+static INLINE void
+mmo_xore_64 (asection *sec, bfd_vma vma, bfd_vma value)
+{
+ bfd_byte *loc = mmo_get_loc (sec, vma, 8);
+ bfd_vma prev = bfd_get_64 (sec->owner, loc);
+
+ value ^= prev;
+ bfd_put_64 (sec->owner, value, loc);
+}
+
+/* Xor in a 32-bit value VALUE at VMA. */
+
+static INLINE void
+mmo_xore_32 (asection *sec, bfd_vma vma, unsigned int value)
+{
+ bfd_byte *loc = mmo_get_loc (sec, vma, 4);
+ unsigned int prev = bfd_get_32 (sec->owner, loc);
+
+ value ^= prev;
+ bfd_put_32 (sec->owner, value, loc);
+}
+
+/* Xor in a 16-bit value VALUE at VMA. */
+
+static INLINE void
+mmo_xore_16 (asection *sec, bfd_vma vma, unsigned int value)
+{
+ bfd_byte *loc = mmo_get_loc (sec, vma, 2);
+ unsigned int prev = bfd_get_16 (sec->owner, loc);
+
+ value ^= prev;
+ bfd_put_16 (sec->owner, value, loc);
+}
+
+/* Write a 32-bit word to output file, no lop_quote generated. */
+
+static INLINE void
+mmo_write_tetra_raw (bfd *abfd, unsigned int value)
+{
+ bfd_byte buf[4];
+
+ bfd_put_32 (abfd, value, buf);
+
+ if (bfd_bwrite (buf, 4, abfd) != 4)
+ abfd->tdata.mmo_data->have_error = TRUE;
+}
+
+/* Write a 32-bit word to output file; lop_quote if necessary. */
+
+static INLINE void
+mmo_write_tetra (bfd *abfd, unsigned int value)
+{
+ if (((value >> 24) & 0xff) == LOP)
+ mmo_write_tetra_raw (abfd, LOP_QUOTE_NEXT);
+
+ mmo_write_tetra_raw (abfd, value);
+}
+
+/* Write a 64-bit word to output file, perhaps with lop_quoting. */
+
+static INLINE void
+mmo_write_octa (bfd *abfd, bfd_vma value)
+{
+ mmo_write_tetra (abfd, (unsigned int) (value >> 32));
+ mmo_write_tetra (abfd, (unsigned int) value);
+}
+
+/* Write a 64-bit word to output file, without lop_quoting. */
+
+static INLINE void
+mmo_write_octa_raw (bfd *abfd, bfd_vma value)
+{
+ mmo_write_tetra_raw (abfd, (unsigned int) (value >> 32));
+ mmo_write_tetra_raw (abfd, (unsigned int) value);
+}
+
+/* Write quoted contents. Intended to be called multiple times in
+ sequence, followed by a call to mmo_flush_chunk. */
+
+static INLINE bfd_boolean
+mmo_write_chunk (bfd *abfd, const bfd_byte *loc, unsigned int len)
+{
+ bfd_boolean retval = TRUE;
+ struct mmo_data_struct *mmop = abfd->tdata.mmo_data;
+
+ /* Fill up a tetra from bytes remaining from a previous chunk. */
+ if (mmop->byte_no != 0)
+ {
+ while (mmop->byte_no < 4 && len != 0)
+ {
+ mmop->buf[mmop->byte_no++] = *loc++;
+ len--;
+ }
+
+ if (mmop->byte_no == 4)
+ {
+ mmo_write_tetra (abfd, bfd_get_32 (abfd, mmop->buf));
+ mmop->byte_no = 0;
+ }
+ }
+
+ while (len >= 4)
+ {
+ if (loc[0] == LOP)
+ mmo_write_tetra_raw (abfd, LOP_QUOTE_NEXT);
+
+ retval = (retval
+ && ! mmop->have_error
+ && 4 == bfd_bwrite (loc, 4, abfd));
+
+ loc += 4;
+ len -= 4;
+ }
+
+ if (len)
+ {
+ /* We must have flushed a previous remainder if we get one from
+ this chunk too. */
+ BFD_ASSERT (mmop->byte_no == 0);
+ memcpy (mmop->buf, loc, len);
+ mmop->byte_no = len;
+ }
+
+ if (! retval)
+ mmop->have_error = TRUE;
+ return retval;
+}
+
+/* Flush remaining bytes, from a previous mmo_write_chunk, zero-padded to
+ 4 bytes. */
+
+static INLINE bfd_boolean
+mmo_flush_chunk (bfd *abfd)
+{
+ if (abfd->tdata.mmo_data->byte_no != 0)
+ {
+ memset (abfd->tdata.mmo_data->buf + abfd->tdata.mmo_data->byte_no,
+ 0, 4 - abfd->tdata.mmo_data->byte_no);
+ mmo_write_tetra (abfd,
+ bfd_get_32 (abfd, abfd->tdata.mmo_data->buf));
+ abfd->tdata.mmo_data->byte_no = 0;
+ }
+
+ return ! abfd->tdata.mmo_data->have_error;
+}
+
+/* Same, but from a list. */
+
+static INLINE bfd_boolean
+mmo_write_chunk_list (bfd *abfd, mmo_data_list_type *datap)
+{
+ for (; datap != NULL; datap = datap->next)
+ if (! mmo_write_chunk (abfd, datap->data, datap->size))
+ return FALSE;
+
+ return mmo_flush_chunk (abfd);
+}
+
+/* Write a lop_loc and some contents. A caller needs to call
+ mmo_flush_chunk after calling this function. The location is only
+ output if different than *LAST_VMAP, which is updated after this call. */
+
+static bfd_boolean
+mmo_write_loc_chunk (bfd *abfd, bfd_vma vma, const bfd_byte *loc,
+ unsigned int len, bfd_vma *last_vmap)
+{
+ /* Find an initial and trailing section of zero (aligned) tetras; we don't
+ need to write out zeros. FIXME: When we do this, we should emit
+ section size and address specifiers, else objcopy can't always perform
+ an identity translation. Only do this if we *don't* have left-over
+ data from a previous write (and will not add any) or else the vma of
+ this chunk is *not* the next address, because then data isn't
+ tetrabyte-aligned and we're concatenating to that left-over data. */
+
+ if ((vma & 3) == 0
+ && (abfd->tdata.mmo_data->byte_no == 0 || vma != *last_vmap))
+ {
+ while (len > 4 && bfd_get_32 (abfd, loc) == 0)
+ {
+ vma += 4;
+ len -= 4;
+ loc += 4;
+ }
+
+ if ((len & 3) == 0)
+ while (len > 4 && bfd_get_32 (abfd, loc + len - 4) == 0)
+ len -= 4;
+ }
+
+ /* Only write out the location if it's different than the one the caller
+ (supposedly) previously handled, accounting for omitted leading zeros. */
+ if (vma != *last_vmap)
+ {
+ /* We might be in the middle of a sequence. */
+ mmo_flush_chunk (abfd);
+
+ /* This should not happen during normal usage, but can presumably
+ happen with an erroneous linker-script, so handle gracefully.
+ Avoid Knuth-specific terms in the message, such as "tetrabyte".
+ Note that this function will get non-4-multiple lengths and
+ unaligned vmas but those come in tuples (mostly pairs) and are
+ continuous (i.e. the if-condition above false) and they are
+ group-wise aligned. */
+ if ((vma & 3) != 0)
+ {
+ (*_bfd_error_handler)
+ (_("%s: attempt to emit contents at non-multiple-of-4 address 0x%lx\n"),
+ bfd_get_filename (abfd), (unsigned long) vma);
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+
+ /* We always write the location as 64 bits; no use saving bytes
+ here. */
+ mmo_write_tetra_raw (abfd, (LOP << 24) | (LOP_LOC << 16) | 2);
+ mmo_write_octa_raw (abfd, vma);
+ }
+
+ /* Update to reflect end of this chunk, with trailing zeros omitted. */
+ *last_vmap = vma + len;
+
+ return (! abfd->tdata.mmo_data->have_error
+ && mmo_write_chunk (abfd, loc, len));
+}
+
+/* Same, but from a list. */
+
+static INLINE bfd_boolean
+mmo_write_loc_chunk_list (bfd *abfd, mmo_data_list_type *datap)
+{
+ /* Get an address different than the address of the first chunk. */
+ bfd_vma last_vma = datap ? datap->where - 1 : 0;
+
+ for (; datap != NULL; datap = datap->next)
+ if (! mmo_write_loc_chunk (abfd, datap->where, datap->data, datap->size,
+ &last_vma))
+ return FALSE;
+
+ return mmo_flush_chunk (abfd);
+}
+
+/* Make a .MMIX.spec_data.N section. */
+
+static asection *
+mmo_get_generic_spec_data_section (bfd *abfd, int spec_data_number)
+{
+ asection *sec;
+ char secname[sizeof (MMIX_OTHER_SPEC_SECTION_PREFIX) + 20]
+ = MMIX_OTHER_SPEC_SECTION_PREFIX;
+
+ sprintf (secname + strlen (MMIX_OTHER_SPEC_SECTION_PREFIX),
+ "%d", spec_data_number);
+
+ sec = mmo_make_section (abfd, secname);
+
+ return sec;
+}
+
+/* Make a special section for SPEC_DATA_NUMBER. If it is the one we use
+ ourselves, parse some of its data to get at the section name. */
+
+static asection *
+mmo_get_spec_section (bfd *abfd, int spec_data_number)
+{
+ char *secname;
+ asection *sec;
+ bfd_byte buf[4];
+ unsigned int secname_length;
+ unsigned int i;
+ bfd_vma section_length;
+ bfd_vma section_vma;
+ mmo_data_list_type *loc;
+ flagword flags;
+ long orig_pos;
+
+ /* If this isn't the "special" special data, then make a placeholder
+ section. */
+ if (spec_data_number != SPEC_DATA_SECTION)
+ return mmo_get_generic_spec_data_section (abfd, spec_data_number);
+
+ /* Seek back to this position if there was a format error. */
+ orig_pos = bfd_tell (abfd);
+
+ /* Read the length (in 32-bit words). */
+ if (bfd_bread (buf, 4, abfd) != 4)
+ goto format_error;
+
+ if (buf[0] == LOP)
+ {
+ if (buf[1] != LOP_QUOTE)
+ goto format_error;
+
+ if (bfd_bread (buf, 4, abfd) != 4)
+ goto format_error;
+ }
+
+ /* We don't care to keep the name length accurate. It's
+ zero-terminated. */
+ secname_length = bfd_get_32 (abfd, buf) * 4;
+
+ /* Check section name length for sanity. */
+ if (secname_length > MAX_SECTION_NAME_SIZE)
+ goto format_error;
+
+ /* This should be free'd regardless if a section is created. */
+ secname = bfd_malloc (secname_length + 1);
+ secname[secname_length] = 0;
+
+ for (i = 0; i < secname_length / 4; i++)
+ {
+ if (bfd_bread (secname + i * 4, 4, abfd) != 4)
+ goto format_error_free;
+
+ if (secname[i * 4] == (char) LOP)
+ {
+ /* A bit of overkill, but we handle char 0x98 in a section name,
+ and recognize misparsing. */
+ if (secname[i * 4 + 1] != LOP_QUOTE
+ || bfd_bread (secname + i * 4, 4, abfd) != 4)
+ /* Whoops. We thought this was a name, and now we found a
+ non-lop_quote lopcode before we parsed the whole length of
+ the name. Signal end-of-file in the same manner. */
+ goto format_error_free;
+ }
+ }
+
+ /* Get the section flags. */
+ if (bfd_bread (buf, 4, abfd) != 4
+ || (buf[0] == LOP
+ && (buf[1] != LOP_QUOTE || bfd_bread (buf, 4, abfd) != 4)))
+ goto format_error_free;
+
+ flags = bfd_get_32 (abfd, buf);
+
+ /* Get the section length. */
+ if (bfd_bread (buf, 4, abfd) != 4
+ || (buf[0] == LOP
+ && (buf[1] != LOP_QUOTE || bfd_bread (buf, 4, abfd) != 4)))
+ goto format_error_free;
+
+ section_length = (bfd_vma) bfd_get_32 (abfd, buf) << 32;
+
+ /* That's the first, high-part. Now get the low part. */
+
+ if (bfd_bread (buf, 4, abfd) != 4
+ || (buf[0] == LOP
+ && (buf[1] != LOP_QUOTE || bfd_bread (buf, 4, abfd) != 4)))
+ goto format_error_free;
+
+ section_length |= (bfd_vma) bfd_get_32 (abfd, buf);
+
+ /* Check the section length for sanity. */
+ if (section_length > MAX_ARTIFICIAL_SECTION_SIZE)
+ goto format_error_free;
+
+ /* Get the section VMA. */
+ if (bfd_bread (buf, 4, abfd) != 4
+ || (buf[0] == LOP
+ && (buf[1] != LOP_QUOTE || bfd_bread (buf, 4, abfd) != 4)))
+ goto format_error_free;
+
+ section_vma = (bfd_vma) bfd_get_32 (abfd, buf) << 32;
+
+ /* That's the first, high-part. Now get the low part. */
+ if (bfd_bread (buf, 4, abfd) != 4
+ || (buf[0] == LOP
+ && (buf[1] != LOP_QUOTE || bfd_bread (buf, 4, abfd) != 4)))
+ goto format_error_free;
+
+ section_vma |= (bfd_vma) bfd_get_32 (abfd, buf);
+
+ sec = mmo_make_section (abfd, secname);
+ free (secname);
+ if (sec == NULL)
+ goto format_error;
+
+ /* We allocate a buffer here for the advertised size, with head room for
+ tetrabyte alignment. */
+ loc = bfd_zmalloc (section_length + 3
+ + sizeof (struct mmo_data_list_struct));
+ if (loc == NULL)
+ goto format_error;
+
+ /* Use a TETRA-rounded size for the allocated buffer; we set the
+ "visible" section size below. */
+ loc->size = (section_length + 3) & ~3;
+
+ /* Add in the section flags we found to those bfd entered during this
+ process and set the contents. */
+ if (! bfd_set_section_flags (abfd, sec,
+ bfd_sec_flags_from_mmo_flags (flags)
+ | bfd_get_section_flags (abfd, sec)
+ | (section_length != 0 ? SEC_HAS_CONTENTS : 0))
+ || ! bfd_set_section_size (abfd, sec, sec->size + section_length)
+ /* Set VMA only for the first occurrence. */
+ || (! sec->user_set_vma
+ && ! bfd_set_section_vma (abfd, sec, section_vma)))
+ {
+ /* If we get an error for any of the calls above, signal more than
+ just a format error for the spec section. */
+ return NULL;
+ }
+
+ loc->next = NULL;
+ if (mmo_section_data (sec)->tail != NULL)
+ mmo_section_data (sec)->tail->next = loc;
+ else
+ mmo_section_data (sec)->head = loc;
+ mmo_section_data (sec)->tail = loc;
+ loc->where = section_vma;
+
+ return sec;
+
+ format_error_free:
+ free (secname);
+ format_error:
+ if (bfd_seek (abfd, orig_pos, SEEK_SET) != 0)
+ return NULL;
+
+ return mmo_get_generic_spec_data_section (abfd, spec_data_number);
+}
+
+/* Read a byte, but read from file in multiples of 32-bit words. */
+
+static bfd_byte
+mmo_get_byte (bfd *abfd)
+{
+ bfd_byte retval;
+
+ if (abfd->tdata.mmo_data->byte_no == 0)
+ {
+ if (! abfd->tdata.mmo_data->have_error
+ && bfd_bread (abfd->tdata.mmo_data->buf, 4, abfd) != 4)
+ {
+ abfd->tdata.mmo_data->have_error = TRUE;
+
+ /* A value somewhat safe against tripping on some inconsistency
+ when mopping up after this error. */
+ return 128;
+ }
+ }
+
+ retval = abfd->tdata.mmo_data->buf[abfd->tdata.mmo_data->byte_no];
+ abfd->tdata.mmo_data->byte_no = (abfd->tdata.mmo_data->byte_no + 1) % 4;
+
+ return retval;
+}
+
+/* Write a byte, in multiples of 32-bit words. */
+
+static void
+mmo_write_byte (bfd *abfd, bfd_byte value)
+{
+ abfd->tdata.mmo_data->buf[(abfd->tdata.mmo_data->byte_no++ % 4)] = value;
+ if ((abfd->tdata.mmo_data->byte_no % 4) == 0)
+ {
+ if (! abfd->tdata.mmo_data->have_error
+ && bfd_bwrite (abfd->tdata.mmo_data->buf, 4, abfd) != 4)
+ abfd->tdata.mmo_data->have_error = TRUE;
+ }
+}
+
+/* Create a symbol. */
+
+static bfd_boolean
+mmo_create_symbol (bfd *abfd, const char *symname, bfd_vma addr, enum
+ mmo_sym_type sym_type, unsigned int serno)
+{
+ struct mmo_symbol *n;
+
+ n = (struct mmo_symbol *) bfd_alloc (abfd, sizeof (struct mmo_symbol));
+ if (n == NULL)
+ return FALSE;
+
+ n->name = bfd_alloc (abfd, strlen (symname) + 1);
+ if (n->name == NULL)
+ return FALSE;
+
+ strcpy (n->name, symname);
+
+ n->value = addr;
+ n->sym_type = sym_type;
+ n->serno = serno;
+
+ if (abfd->tdata.mmo_data->symbols == NULL)
+ abfd->tdata.mmo_data->symbols = n;
+ else
+ abfd->tdata.mmo_data->symtail->next = n;
+ abfd->tdata.mmo_data->symtail = n;
+ n->next = NULL;
+
+ ++abfd->symcount;
+
+ /* Check that :Main equals the last octa of the .MMIX.reg_contents
+ section, as it's the one place we're sure to pass when reading a mmo
+ object. For written objects, we do it while setting the symbol
+ table. */
+ if (strcmp (symname, MMIX_START_SYMBOL_NAME) == 0
+ && bfd_get_start_address (abfd) != addr)
+ {
+ (*_bfd_error_handler)
+ (_("%s: invalid mmo file: initialization value for $255 is not `Main'\n"),
+ bfd_get_filename (abfd));
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/* Read in symbols. */
+
+static bfd_boolean
+mmo_get_symbols (bfd *abfd)
+{
+/*
+INODE
+Symbol-table, mmo section mapping, File layout, mmo
+SUBSECTION
+ Symbol table format
+
+ From mmixal.w (or really, the generated mmixal.tex) in the
+ MMIXware package which also contains the @command{mmix} simulator:
+ ``Symbols are stored and retrieved by means of a @samp{ternary
+ search trie}, following ideas of Bentley and Sedgewick. (See
+ ACM--SIAM Symp.@: on Discrete Algorithms @samp{8} (1997), 360--369;
+ R.@:Sedgewick, @samp{Algorithms in C} (Reading, Mass.@:
+ Addison--Wesley, 1998), @samp{15.4}.) Each trie node stores a
+ character, and there are branches to subtries for the cases where
+ a given character is less than, equal to, or greater than the
+ character in the trie. There also is a pointer to a symbol table
+ entry if a symbol ends at the current node.''
+
+ So it's a tree encoded as a stream of bytes. The stream of bytes
+ acts on a single virtual global symbol, adding and removing
+ characters and signalling complete symbol points. Here, we read
+ the stream and create symbols at the completion points.
+
+ First, there's a control byte <<m>>. If any of the listed bits
+ in <<m>> is nonzero, we execute what stands at the right, in
+ the listed order:
+
+| (MMO3_LEFT)
+| 0x40 - Traverse left trie.
+| (Read a new command byte and recurse.)
+|
+| (MMO3_SYMBITS)
+| 0x2f - Read the next byte as a character and store it in the
+| current character position; increment character position.
+| Test the bits of <<m>>:
+|
+| (MMO3_WCHAR)
+| 0x80 - The character is 16-bit (so read another byte,
+| merge into current character.
+|
+| (MMO3_TYPEBITS)
+| 0xf - We have a complete symbol; parse the type, value
+| and serial number and do what should be done
+| with a symbol. The type and length information
+| is in j = (m & 0xf).
+|
+| (MMO3_REGQUAL_BITS)
+| j == 0xf: A register variable. The following
+| byte tells which register.
+| j <= 8: An absolute symbol. Read j bytes as the
+| big-endian number the symbol equals.
+| A j = 2 with two zero bytes denotes an
+| unknown symbol.
+| j > 8: As with j <= 8, but add (0x20 << 56)
+| to the value in the following j - 8
+| bytes.
+|
+| Then comes the serial number, as a variant of
+| uleb128, but better named ubeb128:
+| Read bytes and shift the previous value left 7
+| (multiply by 128). Add in the new byte, repeat
+| until a byte has bit 7 set. The serial number
+| is the computed value minus 128.
+|
+| (MMO3_MIDDLE)
+| 0x20 - Traverse middle trie. (Read a new command byte
+| and recurse.) Decrement character position.
+|
+| (MMO3_RIGHT)
+| 0x10 - Traverse right trie. (Read a new command byte and
+| recurse.)
+
+ Let's look again at the <<lop_stab>> for the trivial file
+ (@pxref{File layout}).
+
+| 0x980b0000 - lop_stab for ":Main" = 0, serial 1.
+| 0x203a4040
+| 0x10404020
+| 0x4d206120
+| 0x69016e00
+| 0x81000000
+
+ This forms the trivial trie (note that the path between ``:'' and
+ ``M'' is redundant):
+
+| 203a ":"
+| 40 /
+| 40 /
+| 10 \
+| 40 /
+| 40 /
+| 204d "M"
+| 2061 "a"
+| 2069 "i"
+| 016e "n" is the last character in a full symbol, and
+| with a value represented in one byte.
+| 00 The value is 0.
+| 81 The serial number is 1. */
+
+ bfd_byte m = mmo_get_byte (abfd);
+
+ /* Check first if we have a bad hair day. */
+ if (abfd->tdata.mmo_data->have_error)
+ return FALSE;
+
+ if (m & MMO3_LEFT)
+ /* Traverse left trie. */
+ mmo_get_symbols (abfd);
+
+ if (m & MMO3_SYMBITS)
+ {
+ bfd_byte c = mmo_get_byte (abfd);
+ bfd_byte j = m & MMO3_TYPEBITS;
+ bfd_vma addr = 0;
+ enum mmo_sym_type sym_type;
+ unsigned int serno = 0;
+ bfd_byte k;
+
+ if (m & MMO3_WCHAR)
+ {
+ bfd_byte c2 = mmo_get_byte (abfd);
+
+ /* A two-byte character. We can't grok this, but neither can
+ mmotype, for other cases than the second byte being zero. */
+
+ if (c != 0)
+ {
+ abfd->tdata.mmo_data->lop_stab_symbol
+ [abfd->tdata.mmo_data->symbol_position] = 0;
+
+ (*_bfd_error_handler)
+ (_("%s: unsupported wide character sequence"
+ " 0x%02X 0x%02X after symbol name starting with `%s'\n"),
+ bfd_get_filename (abfd), c, c2,
+ abfd->tdata.mmo_data->lop_stab_symbol);
+ bfd_set_error (bfd_error_bad_value);
+ abfd->tdata.mmo_data->have_error = TRUE;
+ return FALSE;
+ }
+ else
+ c = c2;
+ }
+
+ abfd->tdata.mmo_data->lop_stab_symbol[abfd->tdata.mmo_data->symbol_position++] = c;
+ abfd->tdata.mmo_data->lop_stab_symbol[abfd->tdata.mmo_data->symbol_position] = 0;
+
+ if (j & MMO3_REGQUAL_BITS)
+ {
+ if (j == MMO3_REGQUAL_BITS)
+ {
+ sym_type = mmo_reg_sym;
+ addr = mmo_get_byte (abfd);
+ }
+ else if (j <= 8)
+ {
+ unsigned int i;
+
+ for (i = 0; i < j; i++)
+ addr = (addr << 8) + mmo_get_byte (abfd);
+
+ if (addr == 0 && j == MMO3_UNDEF)
+ sym_type = mmo_undef_sym;
+ else
+ sym_type = mmo_abs_sym;
+ }
+ else
+ {
+ unsigned int i;
+
+ for (i = MMO3_DATA; i < j; i++)
+ addr = (addr << 8) + mmo_get_byte (abfd);
+
+ addr += (bfd_vma) 0x20 << 56;
+ sym_type = mmo_data_sym;
+ }
+
+ /* Get the serial number. */
+ do
+ {
+ k = mmo_get_byte (abfd);
+ serno = (serno << 7) + k;
+ }
+ while (k < 128);
+ serno -= 128;
+
+ /* Got it. Now enter it. Skip a leading ":". */
+ if (! abfd->tdata.mmo_data->have_error
+ && ! mmo_create_symbol (abfd,
+ abfd->tdata.mmo_data->lop_stab_symbol
+ + 1,
+ addr, sym_type, serno))
+ abfd->tdata.mmo_data->have_error = TRUE;
+ }
+
+ if (m & MMO3_MIDDLE)
+ /* Traverse middle trie. */
+ mmo_get_symbols (abfd);
+
+ abfd->tdata.mmo_data->symbol_position--;
+ }
+
+ if (m & MMO3_RIGHT)
+ /* Traverse right trie. */
+ mmo_get_symbols (abfd);
+
+ return ! abfd->tdata.mmo_data->have_error;
+}
+
+/* Get the location of memory area [VMA..VMA + SIZE - 1], which we think
+ is in section SEC. Adjust and reallocate zero-initialized contents.
+ If there's new contents, allocate to the next multiple of
+ MMO_SEC_CONTENTS_CHUNK_SIZE. */
+
+static INLINE bfd_byte *
+mmo_get_loc (asection *sec, bfd_vma vma, int size)
+{
+ bfd_size_type allocated_size;
+ struct mmo_section_data_struct *sdatap = mmo_section_data (sec);
+ struct mmo_data_list_struct *datap = sdatap->head;
+ struct mmo_data_list_struct *entry;
+
+ /* First search the list to see if we have the requested chunk in one
+ piece, or perhaps if we have a suitable chunk with room to fit. */
+ for (; datap != NULL; datap = datap->next)
+ {
+ if (datap->where <= vma
+ && datap->where + datap->size >= vma + size)
+ return datap->data + vma - datap->where;
+ else if (datap->where <= vma
+ && datap->where + datap->allocated_size >= vma + size
+ /* Only munch on the "allocated size" if it does not
+ overlap the next chunk. */
+ && (datap->next == NULL || datap->next->where >= vma + size))
+ {
+ /* There was room allocated, but the size wasn't set to include
+ it. Do that now. */
+ datap->size += (vma + size) - (datap->where + datap->size);
+
+ /* Update the section size. This happens only if we update the
+ 32-bit-aligned chunk size. Callers that have
+ non-32-bit-aligned sections should do all allocation and
+ size-setting by themselves or at least set the section size
+ after the last allocating call to this function. */
+ if (vma + size > sec->vma + sec->size)
+ sec->size += (vma + size) - (sec->vma + sec->size);
+
+ return datap->data + vma - datap->where;
+ }
+ }
+
+ /* Not found; allocate a new block. First check in case we get a
+ request for a size split up over several blocks; we'll have to return
+ NULL for those cases, requesting the caller to split up the request.
+ Requests with an address aligned on MMO_SEC_CONTENTS_CHUNK_SIZE bytes and
+ for no more than MMO_SEC_CONTENTS_CHUNK_SIZE will always get resolved. */
+
+ for (datap = sdatap->head; datap != NULL; datap = datap->next)
+ if ((datap->where <= vma && datap->where + datap->size > vma)
+ || (datap->where < vma + size
+ && datap->where + datap->size >= vma + size))
+ return NULL;
+
+ allocated_size
+ = (size + MMO_SEC_CONTENTS_CHUNK_SIZE - 1) & ~(MMO_SEC_CONTENTS_CHUNK_SIZE - 1);
+ entry = (mmo_data_list_type *)
+ bfd_zalloc (sec->owner, sizeof (mmo_data_list_type) + allocated_size);
+ if (entry == NULL)
+ return NULL;
+ entry->where = vma;
+ entry->size = size;
+ entry->allocated_size = allocated_size;
+
+ datap = sdatap->head;
+
+ /* Sort the records by address. Optimize for the common case of adding
+ a record to the end of the list. */
+ if (sdatap->tail != NULL && entry->where >= sdatap->tail->where)
+ {
+ sdatap->tail->next = entry;
+ entry->next = NULL;
+ sdatap->tail = entry;
+ }
+ else
+ {
+ mmo_data_list_type **look;
+ for (look = &sdatap->head;
+ *look != NULL && (*look)->where < entry->where;
+ look = &(*look)->next)
+ ;
+ entry->next = *look;
+ *look = entry;
+ if (entry->next == NULL)
+ {
+ sdatap->tail = entry;
+
+ /* We get here for the first time (at other times too) for this
+ section. Say we have contents. */
+ if (! bfd_set_section_flags (sec->owner, sec,
+ bfd_get_section_flags (sec->owner, sec)
+ | SEC_HAS_CONTENTS))
+ return NULL;
+ }
+ }
+
+ /* Update the section size. This happens only when we add contents and
+ re-size as we go. The section size will then be aligned to 32 bits. */
+ if (vma + size > sec->vma + sec->size)
+ sec->size += (vma + size) - (sec->vma + sec->size);
+ return entry->data;
+}
+
+/* Set sizes once we've read in all sections. */
+
+static void
+mmo_map_set_sizes (bfd *abfd ATTRIBUTE_UNUSED, asection *sec,
+ void *ignored ATTRIBUTE_UNUSED)
+{
+ sec->lma = sec->vma;
+}
+
+/* Read the mmo file and turn it into sections. */
+
+static bfd_boolean
+mmo_scan (bfd *abfd)
+{
+ unsigned int i;
+ unsigned int lineno = 1;
+ bfd_boolean error = FALSE;
+ bfd_vma vma = 0;
+ asection *sec = bfd_make_section_old_way (abfd, MMO_TEXT_SECTION_NAME);
+ asection *non_spec_sec = NULL;
+ bfd_vma non_spec_vma = 0;
+ bfd_size_type nbytes_read = 0;
+ /* Buffer with room to read a 64-bit value. */
+ bfd_byte buf[8];
+ long stab_loc = -1;
+ char *file_names[256];
+
+ abfd->symcount = 0;
+ memset (file_names, 0, sizeof (file_names));
+
+ if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
+ goto error_return;
+
+ while ((nbytes_read = bfd_bread (buf, 4, abfd)) == 4)
+ {
+ if (buf[0] == LOP)
+ {
+ unsigned int y = bfd_get_8 (abfd, buf + 2);
+ unsigned int z = bfd_get_8 (abfd, buf + 3);
+
+ /* Change back to the original section for lopcodes other
+ than LOP_QUOTE that comes after a LOP_SPEC. */
+ if ((buf[1] != LOP_QUOTE || y != 0 || z != 1)
+ && non_spec_sec != NULL)
+ {
+ sec = non_spec_sec;
+ vma = non_spec_vma;
+ non_spec_sec = NULL;
+ }
+
+ switch (buf[1])
+ {
+ default:
+ (*_bfd_error_handler)
+ (_("%s: invalid mmo file: unsupported lopcode `%d'\n"),
+ bfd_get_filename (abfd), buf[1]);
+ bfd_set_error (bfd_error_bad_value);
+ goto error_return;
+
+ case LOP_QUOTE:
+ /* Quote the next 32-bit word. */
+ if (y != 0 || z != 1)
+ {
+ (*_bfd_error_handler)
+ (_("%s: invalid mmo file: expected YZ = 1 got YZ = %d for lop_quote\n"),
+ bfd_get_filename (abfd), y*256+z);
+ bfd_set_error (bfd_error_bad_value);
+ goto error_return;
+ }
+ if (bfd_bread (buf, 4, abfd) != 4)
+ goto error_return;
+
+ vma &= ~3;
+ mmo_xore_32 (sec, vma, bfd_get_32 (abfd, buf));
+ vma += 4;
+ lineno++;
+ break;
+
+ case LOP_LOC:
+ /* Set vma (and section). */
+ vma = (bfd_vma) y << 56;
+ if (z == 1)
+ {
+ /* Get a 32-bit value. */
+ if (bfd_bread (buf, 4, abfd) != 4)
+ goto error_return;
+
+ vma += bfd_get_32 (abfd, buf);
+ }
+ else if (z == 2)
+ {
+ /* Get a 64-bit value. */
+ if (bfd_bread (buf, 8, abfd) != 8)
+ goto error_return;
+
+ vma += bfd_get_64 (abfd, buf);
+ }
+ else
+ {
+ (*_bfd_error_handler)
+ (_("%s: invalid mmo file: expected z = 1 or z = 2, got z = %d for lop_loc\n"),
+ bfd_get_filename (abfd), z);
+ bfd_set_error (bfd_error_bad_value);
+ goto error_return;
+ }
+
+ /* When we decide which section the data goes into, we might
+ create the section. If that happens, make sure the VMA at
+ creation time is tetra-aligned. */
+ sec = mmo_decide_section (abfd, vma & ~3);
+ if (sec == NULL)
+ goto error_return;
+ break;
+
+ case LOP_SKIP:
+ /* Move forward within the same section. */
+ vma += y * 256 + z;
+
+ sec = mmo_decide_section (abfd, vma);
+ if (sec == NULL)
+ goto error_return;
+ break;
+
+ case LOP_FIXO:
+ /* A fixup: Store the current vma somewhere. Position using
+ same format as LOP_LOC. */
+ {
+ bfd_vma p = (bfd_vma) y << 56;
+ asection *fixosec;
+
+ if (z == 1)
+ {
+ /* Get a 32-bit value. */
+ if (bfd_bread (buf, 4, abfd) != 4)
+ goto error_return;
+
+ p += bfd_get_32 (abfd, buf);
+ }
+ else if (z == 2)
+ {
+ /* Get a 64-bit value. */
+ if (bfd_bread (buf, 8, abfd) != 8)
+ goto error_return;
+
+ p += bfd_get_64 (abfd, buf);
+ }
+ else
+ {
+ (*_bfd_error_handler)
+ (_("%s: invalid mmo file: expected z = 1 or z = 2, got z = %d for lop_fixo\n"),
+ bfd_get_filename (abfd), z);
+ bfd_set_error (bfd_error_bad_value);
+ goto error_return;
+ }
+
+ /* The section where we store this address might be a
+ different one than the current section. */
+ fixosec = mmo_decide_section (abfd, p);
+ if (fixosec == NULL)
+ goto error_return;
+ mmo_xore_64 (fixosec, p, vma);
+ }
+ break;
+
+ case LOP_FIXR:
+ /* A fixup: Store YZ of this lopcode into YZ at vma - 4 * yz. */
+ {
+ unsigned int yz = (y * 256 + z);
+ bfd_vma p = vma + 2 - 4 * yz;
+ asection *fixrsec = mmo_decide_section (abfd, p);
+ if (fixrsec == NULL)
+ goto error_return;
+ mmo_xore_16 (fixrsec, p, yz);
+ }
+ break;
+
+ case LOP_FIXRX:
+ /* A fixup, similar to lop_fixr, but taking larger numbers
+ and can change branches into the opposite direction
+ (gasp!). */
+ {
+ bfd_vma delta;
+ bfd_vma p;
+ asection *fixrsec;
+
+ if (y != 0)
+ {
+ (*_bfd_error_handler)
+ (_("%s: invalid mmo file: expected y = 0, got y = %d for lop_fixrx\n"),
+ bfd_get_filename (abfd), y);
+ bfd_set_error (bfd_error_bad_value);
+ goto error_return;
+ }
+
+ if (z != 16 && z != 24)
+ {
+ (*_bfd_error_handler)
+ (_("%s: invalid mmo file: expected z = 16 or z = 24, got z = %d for lop_fixrx\n"),
+ bfd_get_filename (abfd), z);
+ bfd_set_error (bfd_error_bad_value);
+ goto error_return;
+ }
+
+ /* Get the next 32-bit value. */
+ if (bfd_bread (buf, 4, abfd) != 4)
+ goto error_return;
+
+ delta = bfd_get_32 (abfd, buf);
+
+ /* Do an, ehm, involved calculation for the location of
+ the fixup. See mmixal documentation for a verbose
+ explanation. We follow it verbosely here for the
+ readers delight. */
+ if (buf[0] == 0)
+ p = vma - 4 * delta;
+ else if (buf[0] == 1)
+ p = vma - 4 * ((delta & 0xffffff) - (1 << z));
+ else
+ {
+ (*_bfd_error_handler)
+ (_("%s: invalid mmo file: leading byte of operand word must be 0 or 1, got %d for lop_fixrx\n"),
+ bfd_get_filename (abfd), buf[0]);
+ bfd_set_error (bfd_error_bad_value);
+ goto error_return;
+ }
+
+ fixrsec = mmo_decide_section (abfd, vma);
+ if (fixrsec == NULL)
+ goto error_return;
+ mmo_xore_32 (fixrsec, p, delta);
+ }
+ break;
+
+ case LOP_FILE:
+ /* Set current file and perhaps the file name. Reset line
+ number. */
+ if (z != 0)
+ {
+ char *fname = bfd_malloc (z * 4 + 1);
+
+ if (fname == NULL)
+ {
+ (*_bfd_error_handler)
+ (_("%s: cannot allocate file name for file number %d, %d bytes\n"),
+ bfd_get_filename (abfd), y, z * 4 + 1);
+ bfd_set_error (bfd_error_system_call);
+ goto error_return;
+ }
+
+ fname[z * 4] = 0;
+
+ for (i = 0; i < z; i++)
+ {
+ if (bfd_bread (fname + i * 4, 4, abfd) != 4)
+ {
+ free (fname);
+ goto error_return;
+ }
+ }
+
+ if (file_names[y] != NULL)
+ {
+ (*_bfd_error_handler)
+ (_("%s: invalid mmo file: file number %d `%s',"
+ " was already entered as `%s'\n"),
+ bfd_get_filename (abfd), y, fname, file_names[y]);
+ bfd_set_error (bfd_error_bad_value);
+ goto error_return;
+ }
+
+ file_names[y] = fname;
+ }
+
+ if (file_names[y] == NULL)
+ {
+ (*_bfd_error_handler)
+ (_("%s: invalid mmo file: file name for number %d"
+ " was not specified before use\n"),
+ bfd_get_filename (abfd), y);
+ bfd_set_error (bfd_error_bad_value);
+ goto error_return;
+ }
+
+ lineno = 0;
+ break;
+
+ case LOP_LINE:
+ /* Set line number. */
+ lineno = y * 256 + z;
+ /* FIXME: Create a sequence of mmo-specific line number
+ entries for each section, then translate into canonical
+ format. */
+ break;
+
+ case LOP_SPEC:
+ /* Special data follows until the next non-lop_quote
+ lopcode. */
+ non_spec_sec = sec;
+ non_spec_vma = vma;
+ sec = mmo_get_spec_section (abfd, y * 256 + z);
+ if (sec == NULL)
+ goto error_return;
+
+ vma = sec->vma;
+ break;
+
+ case LOP_PRE:
+ {
+ /* We ignore header information, except we read in the
+ creation time from the first 32-bit word with the time
+ in seconds since era. */
+ if (z >= 1
+ && bfd_bread (abfd->tdata.mmo_data->created, 4,
+ abfd) != 4)
+ goto error_return;
+
+ for (i = 1; i < z; i++)
+ if (bfd_bread (buf, 4, abfd) != 4)
+ goto error_return;
+ }
+ break;
+
+ case LOP_POST:
+ /* This tells of the contents of registers $Z..$255 at
+ startup. We make a section out of it, with VMA = Z * 8,
+ but only if Z != 255 or the contents is non-zero. */
+ {
+ asection *rsec;
+ bfd_byte *loc;
+ bfd_vma first_octa;
+ bfd_vma startaddr_octa;
+
+ /* Read first octaword outside loop to simplify logic when
+ excluding the Z == 255, octa == 0 case. */
+ if (bfd_bread (buf, 8, abfd) != 8)
+ goto error_return;
+
+ first_octa = bfd_get_64 (abfd, buf);
+
+ /* Don't emit contents for the trivial case which is
+ always present; $255 pointing to Main. */
+ if (z != 255)
+ {
+ rsec
+ = bfd_make_section_old_way (abfd,
+ MMIX_REG_CONTENTS_SECTION_NAME);
+ rsec->flags |= SEC_LINKER_CREATED;
+ rsec->vma = z * 8;
+ loc = mmo_get_loc (rsec, z * 8, (255 - z) * 8);
+ bfd_put_64 (abfd, first_octa, loc);
+
+ for (i = z + 1; i < 255; i++)
+ {
+ if (bfd_bread (loc + (i - z) * 8, 8, abfd) != 8)
+ goto error_return;
+ }
+
+ /* Read out the last octabyte, and use it to set the
+ start address. */
+ if (bfd_bread (buf, 8, abfd) != 8)
+ goto error_return;
+
+ startaddr_octa = bfd_get_64 (abfd, buf);
+ }
+ else
+ startaddr_octa = first_octa;
+
+ if (! bfd_set_start_address (abfd, startaddr_octa))
+ {
+ /* Currently this can't fail, but this should handle
+ future failures. */
+ bfd_set_error (bfd_error_bad_value);
+ goto error_return;
+ }
+ }
+ break;
+
+ case LOP_STAB:
+ /* We read in the symbols now, not later. */
+ if (y != 0 || z != 0)
+ {
+ (*_bfd_error_handler)
+ (_("%s: invalid mmo file: fields y and z of lop_stab"
+ " non-zero, y: %d, z: %d\n"),
+ bfd_get_filename (abfd), y, z);
+ bfd_set_error (bfd_error_bad_value);
+ goto error_return;
+ }
+
+ /* Save the location, so we can check that YZ in the LOP_END
+ is correct. */
+ stab_loc = bfd_tell (abfd);
+
+ /* It's not said that an MMO can be without symbols (though
+ mmixal will refuse to assemble files without Main), but
+ it seems it would still be a valid mmo-file, so allow it.
+ We detect the absence of a symbol area in that the upper
+ limit is computed (from the lop_end YZ field) as 0.
+ Don't call mmo_get_symbols; it can only detect the end of
+ a valid symbol trie, not the absence of one. */
+ if (abfd->tdata.mmo_data->max_symbol_length != 0
+ && ! mmo_get_symbols (abfd))
+ goto error_return;
+ break;
+
+ case LOP_END:
+ {
+ /* This must be the last 32-bit word in an mmo file.
+ Let's find out. */
+ struct stat statbuf;
+ file_ptr curpos = bfd_tell (abfd);
+
+ if (bfd_stat (abfd, &statbuf) < 0)
+ goto error_return;
+
+ if (statbuf.st_size != curpos)
+ {
+ (*_bfd_error_handler)
+ (_("%s: invalid mmo file: lop_end not last item in"
+ " file\n"),
+ bfd_get_filename (abfd));
+ bfd_set_error (bfd_error_bad_value);
+ goto error_return;
+ }
+
+ /* Check that the YZ field is right. Subtract the size of
+ this LOP_END in the calculation; YZ does not include
+ it. */
+ if ((long) (y * 256 + z) * 4 != (curpos - stab_loc) - 4)
+ {
+ (*_bfd_error_handler)
+ (_("%s: invalid mmo file: YZ of lop_end (%ld)"
+ " not equal to the number of tetras to the preceding"
+ " lop_stab (%ld)\n"),
+ bfd_get_filename (abfd), (long) (y * 256 + z),
+ (curpos - stab_loc - 4)/4);
+ bfd_set_error (bfd_error_bad_value);
+ goto error_return;
+ }
+
+ bfd_map_over_sections (abfd, mmo_map_set_sizes, NULL);
+ goto done;
+ }
+ }
+ }
+ else
+ {
+ /* This wasn't a lopcode, so store it in the current section. */
+ mmo_xore_32 (sec, vma & ~3, bfd_get_32 (abfd, buf));
+ vma += 4;
+ vma &= ~3;
+ lineno++;
+ }
+ }
+
+ /* We know this file is a multiple of four bytes (checked in
+ mmo_object_p), so if we got something other than 0, this was a bad
+ file (although it's more likely we'll get 0 in that case too).
+ If we got end-of-file, then there was no lop_stab, so the file has
+ invalid format. */
+
+ if (nbytes_read != 0)
+ bfd_set_error (bfd_error_system_call);
+ else
+ bfd_set_error (bfd_error_bad_value);
+
+ error_return:
+ error = TRUE;
+ done:
+ /* Mark the .text and .data section with their normal attribute if they
+ contain anything. This is not redundant wrt. mmo_decide_section,
+ since that code might never execute, and conversely the alloc+code
+ section flags must be set then. */
+ sec = bfd_get_section_by_name (abfd, MMO_TEXT_SECTION_NAME);
+ if (sec != NULL
+ && (bfd_get_section_flags (abfd, sec) & SEC_HAS_CONTENTS)
+ && ! bfd_set_section_flags (abfd, sec,
+ bfd_get_section_flags (abfd, sec)
+ | SEC_ALLOC | SEC_LOAD | SEC_CODE))
+ error = TRUE;
+
+ sec = bfd_get_section_by_name (abfd, MMO_DATA_SECTION_NAME);
+ if (sec != NULL
+ && (bfd_get_section_flags (abfd, sec) & SEC_HAS_CONTENTS)
+ && ! bfd_set_section_flags (abfd, sec,
+ bfd_get_section_flags (abfd, sec)
+ | SEC_ALLOC | SEC_LOAD))
+ error = TRUE;
+
+ /* Free whatever resources we took. */
+ for (i = 0; i < sizeof (file_names) / sizeof (file_names[0]); i++)
+ if (file_names[i])
+ free (file_names[i]);
+ return ! error;
+}
+
+/* A hook to set up object file dependent section information. For mmo,
+ we point out the shape of allocated section contents. */
+
+static bfd_boolean
+mmo_new_section_hook (bfd *abfd, asection *newsect)
+{
+ if (!newsect->used_by_bfd)
+ {
+ /* We zero-fill all fields and assume NULL is represented by an all
+ zero-bit pattern. */
+ newsect->used_by_bfd
+ = bfd_zalloc (abfd, sizeof (struct mmo_section_data_struct));
+ if (!newsect->used_by_bfd)
+ return FALSE;
+ }
+
+ /* Always align to at least 32-bit words. */
+ newsect->alignment_power = 2;
+ return _bfd_generic_new_section_hook (abfd, newsect);
+}
+
+/* We already have section contents loaded for sections that have
+ contents. */
+
+static bfd_boolean
+mmo_get_section_contents (bfd *abfd ATTRIBUTE_UNUSED,
+ asection *sec,
+ void * location,
+ file_ptr offset,
+ bfd_size_type bytes_to_do)
+{
+ /* Iterate over diminishing chunk sizes, copying contents, like
+ mmo_set_section_contents. */
+ while (bytes_to_do)
+ {
+ /* A minor song-and-dance to make sure we're not bitten by the
+ distant possibility of the cast from bfd_vma to int making the
+ chunk zero-sized. */
+ int chunk_size
+ = (int) bytes_to_do != 0 ? bytes_to_do : MMO_SEC_CONTENTS_CHUNK_SIZE;
+ bfd_byte *loc;
+
+ do
+ loc = mmo_get_loc (sec, sec->vma + offset, chunk_size);
+ while (loc == NULL && (chunk_size /= 2) != 0);
+
+ if (chunk_size == 0)
+ return FALSE;
+
+ memcpy (location, loc, chunk_size);
+
+ location += chunk_size;
+ bytes_to_do -= chunk_size;
+ offset += chunk_size;
+ }
+ return TRUE;
+}
+
+/* Return the amount of memory needed to read the symbol table. */
+
+static long
+mmo_get_symtab_upper_bound (bfd *abfd)
+{
+ return (abfd->symcount + 1) * sizeof (asymbol *);
+}
+
+/* Sort mmo symbols by serial number. */
+
+static int
+mmo_sort_mmo_symbols (const void *arg1, const void *arg2)
+{
+ const struct mmo_symbol *sym1 = *(const struct mmo_symbol **) arg1;
+ const struct mmo_symbol *sym2 = *(const struct mmo_symbol **) arg2;
+
+ /* Sort by serial number first. */
+ if (sym1->serno < sym2->serno)
+ return -1;
+ else if (sym1->serno > sym2->serno)
+ return 1;
+
+ /* Then sort by address of the table entries. */
+ return ((const char *) arg1 - (const char *) arg2);
+}
+
+/* Translate the symbol table. */
+
+static long
+mmo_canonicalize_symtab (bfd *abfd, asymbol **alocation)
+{
+ unsigned int symcount = bfd_get_symcount (abfd);
+ asymbol *csymbols;
+ unsigned int i;
+
+ csymbols = abfd->tdata.mmo_data->csymbols;
+ if (csymbols == NULL && symcount != 0)
+ {
+ asymbol *c;
+ struct mmo_symbol *s;
+ struct mmo_symbol **msp;
+
+ /* First we store the symbols into the table we'll return, then we
+ qsort it on the serial number, with secondary on the address of
+ the symbol, to preserve order if there would be non-unique serial
+ numbers. */
+ for (s = abfd->tdata.mmo_data->symbols,
+ msp = (struct mmo_symbol **) alocation;
+ s != NULL;
+ s = s->next, ++msp)
+ *msp = s;
+
+ *msp = NULL;
+
+ qsort (alocation, symcount, sizeof (struct mmo_symbol *),
+ mmo_sort_mmo_symbols);
+
+ csymbols = (asymbol *) bfd_alloc (abfd, symcount * sizeof (asymbol));
+ if (csymbols == NULL)
+ return -1;
+ abfd->tdata.mmo_data->csymbols = csymbols;
+
+ for (msp = (struct mmo_symbol **) alocation, c = csymbols;
+ *msp != NULL;
+ msp++, ++c)
+ {
+ s = *msp;
+ c->the_bfd = abfd;
+ c->name = s->name;
+ c->value = s->value;
+ c->flags = BSF_GLOBAL;
+
+ if (s->sym_type == mmo_data_sym)
+ {
+ c->section
+ = bfd_get_section_by_name (abfd, MMO_DATA_SECTION_NAME);
+
+ if (c->section == NULL)
+ c->section = bfd_abs_section_ptr;
+ else
+ c->value -= c->section->vma;
+ }
+ else if (s->sym_type == mmo_undef_sym)
+ c->section = bfd_und_section_ptr;
+ else if (s->sym_type == mmo_reg_sym)
+ {
+ c->section
+ = bfd_make_section_old_way (abfd, MMIX_REG_SECTION_NAME);
+ c->section->flags |= SEC_LINKER_CREATED;
+ }
+ else
+ {
+ asection *textsec
+ = bfd_get_section_by_name (abfd, MMO_TEXT_SECTION_NAME);
+ asection *datasec;
+
+ if (textsec != NULL
+ && c->value >= textsec->vma
+ && c->value <= textsec->vma + textsec->size)
+ {
+ c->section = textsec;
+ c->value -= c->section->vma;
+ }
+ /* In mmo, symbol types depend on the VMA. Therefore, if
+ the data section isn't within the usual bounds, its
+ symbols are marked as absolute. Correct that. This
+ means we can't have absolute symbols with values matching
+ data section addresses, but we also can't have with
+ absolute symbols with values matching text section
+ addresses. For such needs, use the ELF format. */
+ else if ((datasec
+ = bfd_get_section_by_name (abfd,
+ MMO_DATA_SECTION_NAME))
+ != NULL
+ && c->value >= datasec->vma
+ && c->value <= datasec->vma + datasec->size)
+ {
+ c->section = datasec;
+ c->value -= c->section->vma;
+ }
+ else
+ c->section = bfd_abs_section_ptr;
+ }
+
+ c->udata.p = NULL;
+ }
+ }
+
+ /* Last, overwrite the incoming table with the right-type entries. */
+ for (i = 0; i < symcount; i++)
+ *alocation++ = csymbols++;
+ *alocation = NULL;
+
+ return symcount;
+}
+
+/* Get information about a symbol. */
+
+static void
+mmo_get_symbol_info (bfd *ignore_abfd ATTRIBUTE_UNUSED,
+ asymbol *symbol, symbol_info *ret)
+{
+ bfd_symbol_info (symbol, ret);
+}
+
+static void
+mmo_print_symbol (bfd *abfd, void *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 (abfd, file, symbol);
+
+ fprintf (file, " %-5s %s",
+ symbol->section->name,
+ symbol->name);
+ }
+}
+
+/* We can't map a file directly into executable code, so the
+ size of header information is irrelevant. */
+
+static int
+mmo_sizeof_headers (bfd *abfd ATTRIBUTE_UNUSED,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+/* Write the (section-neutral) file preamble. */
+
+static bfd_boolean
+mmo_internal_write_header (bfd *abfd)
+{
+ const char lop_pre_bfd[] = { LOP, LOP_PRE, 1, 1};
+
+ if (bfd_bwrite (lop_pre_bfd, 4, abfd) != 4)
+ return FALSE;
+
+ /* Copy creation time of original file. */
+ if (bfd_bwrite (abfd->tdata.mmo_data->created, 4, abfd) != 4)
+ return FALSE;
+
+ return TRUE;
+}
+
+/* Write the LOP_POST record, with global register initializations.
+ Z is the Z field of the LOP_POST, corresponding to 255 - number of
+ registers at DATA. The Z = 255 field is filled in with the
+ start-address. */
+
+static bfd_boolean
+mmo_internal_write_post (bfd *abfd, int z, asection *sec)
+{
+ int i;
+ bfd_byte buf[8];
+ mmo_write_tetra_raw (abfd, (LOP << 24) | (LOP_POST << 16) | z);
+
+ for (i = z; i < 255; i++)
+ {
+ bfd_byte *data = mmo_get_loc (sec, i * 8, 8);
+
+ if (bfd_bwrite (data, 8, abfd) != 8)
+ return FALSE;
+ }
+
+ /* For Z == $255, we always emit the start location; supposedly Main,
+ but we have it handy at bfd_get_start_address. If we're called with
+ Z == 255, don't assume DATA is valid. */
+ bfd_put_64 (abfd, bfd_get_start_address (abfd), buf);
+
+ return ! abfd->tdata.mmo_data->have_error && bfd_bwrite (buf, 8, abfd) == 8;
+}
+
+/* Translate to and from BFD flags. This is to make sure that we don't
+ get bitten by BFD flag number changes. */
+
+static flagword
+mmo_sec_flags_from_bfd_flags (flagword flags)
+{
+ flagword oflags = 0;
+
+ if (flags & SEC_ALLOC)
+ oflags |= MMO_SEC_ALLOC;
+ if (flags & SEC_LOAD)
+ oflags |= MMO_SEC_LOAD;
+ if (flags & SEC_RELOC)
+ oflags |= MMO_SEC_RELOC;
+ if (flags & SEC_READONLY)
+ oflags |= MMO_SEC_READONLY;
+ if (flags & SEC_CODE)
+ oflags |= MMO_SEC_CODE;
+ if (flags & SEC_DATA)
+ oflags |= MMO_SEC_DATA;
+ if (flags & SEC_NEVER_LOAD)
+ oflags |= MMO_SEC_NEVER_LOAD;
+ if (flags & SEC_IS_COMMON)
+ oflags |= MMO_SEC_IS_COMMON;
+ if (flags & SEC_DEBUGGING)
+ oflags |= MMO_SEC_DEBUGGING;
+
+ return oflags;
+}
+
+static flagword
+bfd_sec_flags_from_mmo_flags (flagword flags)
+{
+ flagword oflags = 0;
+
+ if (flags & MMO_SEC_ALLOC)
+ oflags |= SEC_ALLOC;
+ if (flags & MMO_SEC_LOAD)
+ oflags |= SEC_LOAD;
+ if (flags & MMO_SEC_RELOC)
+ oflags |= SEC_RELOC;
+ if (flags & MMO_SEC_READONLY)
+ oflags |= SEC_READONLY;
+ if (flags & MMO_SEC_CODE)
+ oflags |= SEC_CODE;
+ if (flags & MMO_SEC_DATA)
+ oflags |= SEC_DATA;
+ if (flags & MMO_SEC_NEVER_LOAD)
+ oflags |= SEC_NEVER_LOAD;
+ if (flags & MMO_SEC_IS_COMMON)
+ oflags |= SEC_IS_COMMON;
+ if (flags & MMO_SEC_DEBUGGING)
+ oflags |= SEC_DEBUGGING;
+
+ return oflags;
+}
+
+/* Return TRUE iff the leading or trailing tetrabyte in SEC is defined and
+ is 0. */
+
+static bfd_boolean
+mmo_has_leading_or_trailing_zero_tetra_p (bfd *abfd, asection *sec)
+{
+ bfd_vma secaddr = bfd_get_section_vma (abfd, sec);
+
+ if (sec->size < 4)
+ return FALSE;
+
+ if (bfd_get_32 (abfd, mmo_get_loc (sec, secaddr, 4)) == 0
+ && bfd_get_32 (abfd,
+ mmo_get_loc (sec, secaddr + sec->size - 4, 4)) == 0)
+ return TRUE;
+
+ return FALSE;
+}
+
+/* Write a section. */
+
+static bfd_boolean
+mmo_internal_write_section (bfd *abfd, asection *sec)
+{
+ /* We do it differently depending on what section this is:
+
+ ".text": Output, prepended by information about the first source file
+ (not yet implemented.)
+
+ ".data": Output.
+
+ (".MMIX.reg_contents": Not handled here.)
+
+ Anything else: Output inside a lop_spec 80, in the format described
+ above. */
+
+ if (strcmp (sec->name, MMO_TEXT_SECTION_NAME) == 0)
+ {
+ bfd_vma secaddr = bfd_get_section_vma (abfd, sec);
+
+ /* Because leading and trailing zeros are omitted in output, we need to
+ specify the section boundaries so they're correct when the file
+ is read in again. That's also the case if this section is
+ specified as not within its usual boundaries or alignments. */
+ if (sec->size != 0
+ && (secaddr + sec->size >= (bfd_vma) 1 << 56
+ || (secaddr & 3) != 0
+ || (sec->size & 3) != 0
+ || mmo_has_leading_or_trailing_zero_tetra_p (abfd, sec)))
+ {
+ if (!mmo_write_section_description (abfd, sec))
+ return FALSE;
+ }
+
+ /* FIXME: Output source file name and line number. */
+ return mmo_write_loc_chunk_list (abfd, mmo_section_data (sec)->head);
+ }
+ else if (strcmp (sec->name, MMO_DATA_SECTION_NAME) == 0)
+ {
+ bfd_vma secaddr = bfd_get_section_vma (abfd, sec);
+
+ /* Same goes as for MMO_TEXT_SECTION_NAME above. */
+ if (sec->size != 0
+ && (secaddr < (bfd_vma) 0x20 << 56
+ || secaddr + sec->size >= (bfd_vma) 0x21 << 56
+ || (secaddr & 3) != 0
+ || (sec->size & 3) != 0
+ || mmo_has_leading_or_trailing_zero_tetra_p (abfd, sec)))
+ {
+ if (!mmo_write_section_description (abfd, sec))
+ return FALSE;
+ }
+
+ return mmo_write_loc_chunk_list (abfd, mmo_section_data (sec)->head);
+ }
+ else if (strcmp (sec->name, MMIX_REG_CONTENTS_SECTION_NAME) == 0)
+ /* Not handled here. */
+ {
+ /* This would normally be an abort call since this can't happen, but
+ we don't do that. */
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+ else if (CONST_STRNEQ (sec->name, MMIX_OTHER_SPEC_SECTION_PREFIX))
+ {
+ int n = atoi (sec->name + strlen (MMIX_OTHER_SPEC_SECTION_PREFIX));
+
+ mmo_write_tetra_raw (abfd, (LOP << 24) | (LOP_SPEC << 16) | n);
+ return (! abfd->tdata.mmo_data->have_error
+ && mmo_write_chunk_list (abfd, mmo_section_data (sec)->head));
+ }
+ /* Ignore sections that are just allocated or empty; we write out
+ _contents_ here. */
+ else if ((bfd_get_section_flags (abfd, sec) & SEC_HAS_CONTENTS) != 0
+ && sec->size != 0)
+ {
+ if (!mmo_write_section_description (abfd, sec))
+ return FALSE;
+
+ /* Writing a LOP_LOC ends the LOP_SPEC data, and makes data actually
+ loaded. */
+ if (bfd_get_section_flags (abfd, sec) & SEC_LOAD)
+ return (! abfd->tdata.mmo_data->have_error
+ && mmo_write_loc_chunk_list (abfd,
+ mmo_section_data (sec)->head));
+ return (! abfd->tdata.mmo_data->have_error
+ && mmo_write_chunk_list (abfd, mmo_section_data (sec)->head));
+ }
+
+ /* Some section without contents. */
+ return TRUE;
+}
+
+/* Write the description of a section, extended-mmo-style. */
+
+static bfd_boolean
+mmo_write_section_description (bfd *abfd, asection *sec)
+{
+ /* Keep the following document-comment formatted the way it is. */
+/*
+INODE
+mmo section mapping, , Symbol-table, mmo
+SUBSECTION
+ mmo section mapping
+
+ The implementation in BFD uses special data type 80 (decimal) to
+ encapsulate and describe named sections, containing e.g.@: debug
+ information. If needed, any datum in the encapsulation will be
+ quoted using lop_quote. First comes a 32-bit word holding the
+ number of 32-bit words containing the zero-terminated zero-padded
+ segment name. After the name there's a 32-bit word holding flags
+ describing the section type. Then comes a 64-bit big-endian word
+ with the section length (in bytes), then another with the section
+ start address. Depending on the type of section, the contents
+ might follow, zero-padded to 32-bit boundary. For a loadable
+ section (such as data or code), the contents might follow at some
+ later point, not necessarily immediately, as a lop_loc with the
+ same start address as in the section description, followed by the
+ contents. This in effect forms a descriptor that must be emitted
+ before the actual contents. Sections described this way must not
+ overlap.
+
+ For areas that don't have such descriptors, synthetic sections are
+ formed by BFD. Consecutive contents in the two memory areas
+ @samp{0x0000@dots{}00} to @samp{0x01ff@dots{}ff} and
+ @samp{0x2000@dots{}00} to @samp{0x20ff@dots{}ff} are entered in
+ sections named <<.text>> and <<.data>> respectively. If an area
+ is not otherwise described, but would together with a neighboring
+ lower area be less than @samp{0x40000000} bytes long, it is joined
+ with the lower area and the gap is zero-filled. For other cases,
+ a new section is formed, named <<.MMIX.sec.@var{n}>>. Here,
+ @var{n} is a number, a running count through the mmo file,
+ starting at 0.
+
+EXAMPLE
+ A loadable section specified as:
+
+| .section secname,"ax"
+| TETRA 1,2,3,4,-1,-2009
+| BYTE 80
+
+ and linked to address @samp{0x4}, is represented by the sequence:
+
+| 0x98080050 - lop_spec 80
+| 0x00000002 - two 32-bit words for the section name
+| 0x7365636e - "secn"
+| 0x616d6500 - "ame\0"
+| 0x00000033 - flags CODE, READONLY, LOAD, ALLOC
+| 0x00000000 - high 32 bits of section length
+| 0x0000001c - section length is 28 bytes; 6 * 4 + 1 + alignment to 32 bits
+| 0x00000000 - high 32 bits of section address
+| 0x00000004 - section address is 4
+| 0x98010002 - 64 bits with address of following data
+| 0x00000000 - high 32 bits of address
+| 0x00000004 - low 32 bits: data starts at address 4
+| 0x00000001 - 1
+| 0x00000002 - 2
+| 0x00000003 - 3
+| 0x00000004 - 4
+| 0xffffffff - -1
+| 0xfffff827 - -2009
+| 0x50000000 - 80 as a byte, padded with zeros.
+
+ Note that the lop_spec wrapping does not include the section
+ contents. Compare this to a non-loaded section specified as:
+
+| .section thirdsec
+| TETRA 200001,100002
+| BYTE 38,40
+
+ This, when linked to address @samp{0x200000000000001c}, is
+ represented by:
+
+| 0x98080050 - lop_spec 80
+| 0x00000002 - two 32-bit words for the section name
+| 0x7365636e - "thir"
+| 0x616d6500 - "dsec"
+| 0x00000010 - flag READONLY
+| 0x00000000 - high 32 bits of section length
+| 0x0000000c - section length is 12 bytes; 2 * 4 + 2 + alignment to 32 bits
+| 0x20000000 - high 32 bits of address
+| 0x0000001c - low 32 bits of address 0x200000000000001c
+| 0x00030d41 - 200001
+| 0x000186a2 - 100002
+| 0x26280000 - 38, 40 as bytes, padded with zeros
+
+ For the latter example, the section contents must not be
+ loaded in memory, and is therefore specified as part of the
+ special data. The address is usually unimportant but might
+ provide information for e.g.@: the DWARF 2 debugging format. */
+
+ mmo_write_tetra_raw (abfd, LOP_SPEC_SECTION);
+ mmo_write_tetra (abfd, (strlen (sec->name) + 3) / 4);
+ mmo_write_chunk (abfd, (bfd_byte *) sec->name, strlen (sec->name));
+ mmo_flush_chunk (abfd);
+ /* FIXME: We can get debug sections (.debug_line & Co.) with a section
+ flag still having SEC_RELOC set. Investigate. This might be true
+ for all alien sections; perhaps mmo.em should clear that flag. Might
+ be related to weak references. */
+ mmo_write_tetra (abfd,
+ mmo_sec_flags_from_bfd_flags
+ (bfd_get_section_flags (abfd, sec)));
+ mmo_write_octa (abfd, sec->size);
+ mmo_write_octa (abfd, bfd_get_section_vma (abfd, sec));
+ return TRUE;
+}
+
+/* We save up all data before output. */
+
+static bfd_boolean
+mmo_set_section_contents (bfd *abfd ATTRIBUTE_UNUSED, sec_ptr sec,
+ const void *location, file_ptr offset,
+ bfd_size_type bytes_to_do)
+{
+ /* Iterate over diminishing chunk sizes, copying contents. */
+ while (bytes_to_do)
+ {
+ /* A minor song-and-dance to make sure we're not bitten by the
+ distant possibility of the cast from bfd_vma to int making the
+ chunk zero-sized. */
+ int chunk_size
+ = (int) bytes_to_do != 0 ? bytes_to_do : MMO_SEC_CONTENTS_CHUNK_SIZE;
+ bfd_byte *loc;
+
+ do
+ loc = mmo_get_loc (sec, sec->vma + offset, chunk_size);
+ while (loc == NULL && (chunk_size /= 2) != 0);
+
+ if (chunk_size == 0)
+ return FALSE;
+
+ memcpy (loc, location, chunk_size);
+
+ location += chunk_size;
+ bytes_to_do -= chunk_size;
+ offset += chunk_size;
+ }
+ return TRUE;
+}
+
+/* Add a symbol to a trie-tree. */
+
+static bfd_boolean
+mmo_internal_add_3_sym (bfd *abfd, struct mmo_symbol_trie *rootp,
+ const struct mmo_symbol *symp)
+{
+ const char *name = symp->name;
+ struct mmo_symbol_trie *trie = rootp;
+ struct mmo_symbol_trie **triep = NULL;
+
+ while (*name && trie != NULL)
+ {
+ if (*name < trie->symchar)
+ {
+ triep = &trie->left;
+ trie = trie->left;
+ }
+ else if (*name > trie->symchar)
+ {
+ triep = &trie->right;
+ trie = trie->right;
+ }
+ else if (*name == trie->symchar)
+ {
+ triep = &trie->middle;
+ name++;
+
+ /* Make sure "trie" points to where we should fill in the
+ current symbol whenever we've iterated through "name". We
+ would lose the right position if we encounter "foobar" then
+ "foo". */
+ if (*name)
+ trie = trie->middle;
+ }
+ }
+
+ while (*name != 0)
+ {
+ /* Create middle branches for the rest of the characters. */
+ trie = bfd_zalloc (abfd, sizeof (struct mmo_symbol_trie));
+ *triep = trie;
+ trie->symchar = *name++;
+ triep = &trie->middle;
+ }
+
+ /* We discover a duplicate symbol rather late in the process, but still;
+ we discover it and bail out. */
+ if (trie->sym.name != NULL)
+ {
+ (*_bfd_error_handler)
+ (_("%s: invalid symbol table: duplicate symbol `%s'\n"),
+ bfd_get_filename (abfd), trie->sym.name);
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+
+ memcpy (&trie->sym, symp, sizeof *symp);
+ return TRUE;
+}
+
+/* Find out the length of the serialized version of a trie in bytes. */
+
+static unsigned int
+mmo_internal_3_length (bfd *abfd, struct mmo_symbol_trie *trie)
+{
+ /* First, one for the control byte. */
+ unsigned int length = 1;
+
+ if (trie == NULL)
+ return 0;
+
+ /* Add in the recursion to the left. */
+ length += mmo_internal_3_length (abfd, trie->left);
+
+ /* Add in the middle trie and the character. */
+ length += 1 + mmo_internal_3_length (abfd, trie->middle);
+
+ /* Add in the recursion to the right. */
+ length += mmo_internal_3_length (abfd, trie->right);
+
+ /* Add in bytes for the symbol (if this is an endnode). */
+ if (trie->sym.name != NULL)
+ {
+ unsigned int serno = trie->sym.serno;
+
+ /* First what it takes to encode the value. */
+ if (trie->sym.sym_type == mmo_reg_sym)
+ length++;
+ else if (trie->sym.sym_type == mmo_undef_sym)
+ length += 2;
+ else
+ {
+ bfd_vma value = trie->sym.value;
+
+ /* Coded in one to eight following bytes. */
+ if (trie->sym.sym_type == mmo_data_sym)
+ value -= (bfd_vma) 0x20 << 56;
+
+ do
+ {
+ value >>= 8;
+ length++;
+ }
+ while (value != 0);
+ }
+
+ /* Find out what it takes to encode the serial number. */
+ do
+ {
+ serno >>= 7;
+ length++;
+ }
+ while (serno != 0);
+ }
+
+ return length;
+}
+
+/* Helper function for outputting the serial number of a symbol, output as
+ a variant of leb128 (see dwarf2 documentation) which could be called
+ beb128. Using a helper function and recursion simplifies debugging. */
+
+static void
+mmo_beb128_out (bfd *abfd, int serno, int marker)
+{
+ if (serno & ~0x7f)
+ mmo_beb128_out (abfd, serno >> 7, 0);
+ mmo_write_byte (abfd, marker | (serno & 0x7f));
+}
+
+/* Serialize a trie. */
+
+static void
+mmo_internal_3_dump (bfd *abfd, struct mmo_symbol_trie *trie)
+{
+ bfd_byte control = 0;
+
+ if (trie == NULL)
+ return;
+
+ if (trie->left)
+ control |= MMO3_LEFT;
+
+ if (trie->middle)
+ control |= MMO3_MIDDLE;
+
+ if (trie->right)
+ control |= MMO3_RIGHT;
+
+ if (trie->sym.name != NULL)
+ {
+ /* Encode the symbol type and length of value bytes. */
+ if (trie->sym.sym_type == mmo_reg_sym)
+ control |= MMO3_REGQUAL_BITS;
+ else if (trie->sym.sym_type == mmo_undef_sym)
+ control |= MMO3_UNDEF;
+ else
+ {
+ bfd_vma value = trie->sym.value;
+
+ /* Coded in 1..8 following bytes. */
+ if (trie->sym.sym_type == mmo_data_sym)
+ {
+ control |= MMO3_DATA;
+ value -= (bfd_vma) 0x20 << 56;
+ }
+
+ do
+ {
+ value >>= 8;
+ control++;
+ }
+ while (value != 0);
+ }
+ }
+
+ /* The control byte is output before recursing. */
+ mmo_write_byte (abfd, control);
+
+ mmo_internal_3_dump (abfd, trie->left);
+
+ if (control & MMO3_SYMBITS)
+ {
+ mmo_write_byte (abfd, trie->symchar);
+
+ if (trie->sym.name != NULL)
+ {
+ if (trie->sym.sym_type == mmo_reg_sym)
+ mmo_write_byte (abfd, trie->sym.value);
+ else if (trie->sym.sym_type == mmo_undef_sym)
+ {
+ mmo_write_byte (abfd, 0);
+ mmo_write_byte (abfd, 0);
+ }
+ else
+ {
+ bfd_vma value = trie->sym.value;
+
+ bfd_byte byte_n = control & 15;
+
+ /* Coded in 1..8 following bytes. Note that the value is
+ shifted out big-endian. */
+ if (trie->sym.sym_type == mmo_data_sym)
+ {
+ value -= (bfd_vma) 0x20 << 56;
+ byte_n -= 8;
+ }
+
+ do
+ {
+ mmo_write_byte (abfd, (value >> ((byte_n - 1) * 8)) & 0xff);
+ byte_n--;
+ }
+ while (byte_n != 0);
+ }
+
+ mmo_beb128_out (abfd, trie->sym.serno, 128);
+ }
+ mmo_internal_3_dump (abfd, trie->middle);
+ }
+ mmo_internal_3_dump (abfd, trie->right);
+}
+
+/* Write symbols in mmo format. Also write the lop_end terminator. */
+
+static bfd_boolean
+mmo_write_symbols_and_terminator (bfd *abfd)
+{
+ int count = bfd_get_symcount (abfd);
+ asymbol **table;
+ asymbol **orig_table = bfd_get_outsymbols (abfd);
+ int serno;
+ struct mmo_symbol_trie root;
+ int trie_len;
+ int i;
+ bfd_byte buf[4];
+
+ /* Create a symbol for "Main". */
+ asymbol *fakemain = bfd_make_empty_symbol (abfd);
+
+ fakemain->flags = BSF_GLOBAL;
+ fakemain->value = bfd_get_start_address (abfd);
+ fakemain->name = MMIX_START_SYMBOL_NAME;
+ fakemain->section = bfd_abs_section_ptr;
+
+ memset (&root, 0, sizeof (root));
+
+ /* Make all symbols take a left turn. */
+ root.symchar = 0xff;
+
+ /* There must always be a ":Main", so we'll add one if there are no
+ symbols. Make sure we have room for it. */
+ table = bfd_alloc (abfd, (count + 1) * sizeof (asymbol *));
+ if (table == NULL)
+ return FALSE;
+
+ memcpy (table, orig_table, count * sizeof (asymbol *));
+
+ /* Move :Main (if there is one) to the first position. This is
+ necessary to get the same layout of the trie-tree when linking as
+ when objcopying the result as in the objcopy.exp test "simple objcopy
+ of executable". It also automatically takes care of assigning serial
+ number 1 to :Main (as is mandatory). */
+ for (i = 0; i < count; i++)
+ if (table[i] != NULL
+ && strcmp (table[i]->name, MMIX_START_SYMBOL_NAME) == 0
+ && (table[i]->flags & (BSF_DEBUGGING|BSF_GLOBAL)) == BSF_GLOBAL)
+ {
+ asymbol *mainsym = table[i];
+ memcpy (table + 1, orig_table, i * sizeof (asymbol *));
+ table[0] = mainsym;
+
+ /* Check that the value assigned to :Main is the same as the entry
+ address. The default linker script asserts this. This is as
+ good a place as any to check this consistency. */
+ if ((mainsym->value
+ + mainsym->section->output_section->vma
+ + mainsym->section->output_offset)
+ != bfd_get_start_address (abfd))
+ {
+ /* Arbitrary buffer to hold the printable representation of a
+ vma. */
+ char vmas_main[40];
+ char vmas_start[40];
+ bfd_vma vma_start = bfd_get_start_address (abfd);
+
+ sprintf_vma (vmas_main, mainsym->value);
+ sprintf_vma (vmas_start, vma_start);
+
+ (*_bfd_error_handler)
+ (_("%s: Bad symbol definition: `Main' set to %s rather"
+ " than the start address %s\n"),
+ bfd_get_filename (abfd), vmas_main, vmas_start);
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+ break;
+ }
+ if (i == count && count != 0)
+ {
+ /* When there are symbols, there must be a :Main. There was no
+ :Main, so we need to add it manually. */
+ memcpy (table + 1, orig_table, count * sizeof (asymbol *));
+ table[0] = fakemain;
+ count++;
+ }
+
+ for (i = 0, serno = 1; i < count && table[i] != NULL; i++)
+ {
+ asymbol *s = table[i];
+
+ /* It's not enough to consult bfd_is_local_label, since it does not
+ mean "local" in the sense of linkable-and-observable-after-link.
+ Let's just check the BSF_GLOBAL flag.
+
+ Also, don't export symbols with characters not in the allowed set. */
+ if ((s->flags & (BSF_DEBUGGING|BSF_GLOBAL)) == BSF_GLOBAL
+ && strspn (s->name,
+ valid_mmo_symbol_character_set) == strlen (s->name))
+ {
+ struct mmo_symbol sym;
+ memset (&sym, 0, sizeof (sym));
+
+ /* Need to strip const here; strdup:ing would leak and the
+ existing string must be safe to reuse. */
+ sym.name = (char *) s->name;
+ sym.value =
+ s->value
+ + s->section->output_section->vma
+ + s->section->output_offset;
+
+ if (bfd_is_und_section (s->section))
+ sym.sym_type = mmo_undef_sym;
+ else if (strcmp (s->section->name, MMO_DATA_SECTION_NAME) == 0
+ /* The encoding of data symbols require that the "rest"
+ of the value fits in 6 bytes, so the upper two bytes
+ must be 0x2000. All other symbols get to be the
+ absolute type. */
+ && (sym.value >> 48) == 0x2000)
+ sym.sym_type = mmo_data_sym;
+ else if (strcmp (s->section->name, MMIX_REG_SECTION_NAME) == 0)
+ sym.sym_type = mmo_reg_sym;
+ else if (strcmp (s->section->name,
+ MMIX_REG_CONTENTS_SECTION_NAME) == 0)
+ {
+ sym.sym_type = mmo_reg_sym;
+ sym.value /= 8;
+ }
+ else
+ sym.sym_type = mmo_abs_sym;
+
+ /* FIXME: We assume the order of the received symbols is an
+ ordered mapping of the serial numbers. This is not
+ necessarily true if we e.g. objcopy a mmo file to another and
+ there are gaps in the numbering. Not sure if this can
+ happen. Not sure what to do. */
+ sym.serno = serno++;
+
+ if (! mmo_internal_add_3_sym (abfd, &root, &sym))
+ return FALSE;
+ }
+ }
+
+ /* Change the root node to be a ":"-prefix. */
+ root.symchar = ':';
+ root.middle = root.left;
+ root.right = NULL;
+ root.left = NULL;
+
+ /* We have to find out if we can fit the whole symbol table in the mmo
+ symtab. It would be bad to assume we can always fit it in 262144
+ bytes. If we can't, just leave the Main symbol. */
+ trie_len = (mmo_internal_3_length (abfd, &root) + 3)/4;
+
+ if (trie_len > 0xffff)
+ {
+ /* Test this code by using a lower limit in the test above and check
+ that the single "Main" symbol is emitted and handled properly.
+ There's no specific test-case. */
+ struct mmo_symbol sym;
+
+ (*_bfd_error_handler)
+ (_("%s: warning: symbol table too large for mmo, larger than 65535"
+ " 32-bit words: %d. Only `Main' will be emitted.\n"),
+ bfd_get_filename (abfd), trie_len);
+
+ memset (&sym, 0, sizeof (sym));
+ sym.sym_type = mmo_abs_sym;
+ sym.name = MMIX_START_SYMBOL_NAME;
+ sym.serno = 1;
+ sym.value = bfd_get_start_address (abfd);
+
+ /* Then patch up a symbol table to be just the ":Main" symbol. */
+ memset (&root, 0, sizeof (root));
+ root.left = root.middle;
+ root.symchar = 0xff;
+ root.middle = NULL;
+ root.right = NULL;
+
+ if (! mmo_internal_add_3_sym (abfd, &root, &sym))
+ return FALSE;
+
+ root.symchar = ':';
+ root.middle = root.left;
+ root.right = NULL;
+ root.left = NULL;
+
+ trie_len = (mmo_internal_3_length (abfd, &root) + 3)/4;
+ }
+
+ /* Reset the written-bytes counter. */
+ abfd->tdata.mmo_data->byte_no = 0;
+
+ /* Put out the lop_stab mark. */
+ bfd_put_32 (abfd, (LOP << 24) | (LOP_STAB << 16), buf);
+ if (bfd_bwrite (buf, 4, abfd) != 4)
+ return FALSE;
+
+ /* Dump out symbols. */
+ mmo_internal_3_dump (abfd, &root);
+
+ if (trie_len != (abfd->tdata.mmo_data->byte_no + 3)/4)
+ {
+ /* I haven't seen this trig. It seems no use claiming this case
+ isn't debugged and abort if we get here. Instead emit a
+ diagnostic and fail "normally". */
+ (*_bfd_error_handler)
+ (_("%s: internal error, symbol table changed size from %d to %d"
+ " words\n"),
+ bfd_get_filename (abfd), trie_len,
+ (abfd->tdata.mmo_data->byte_no + 3)/4);
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+
+ /* Dump out remaining bytes in the buffer and handle I/O errors by
+ propagating errors. */
+ if ((abfd->tdata.mmo_data->byte_no % 4) != 0
+ || abfd->tdata.mmo_data->have_error)
+ {
+ memset (abfd->tdata.mmo_data->buf + (abfd->tdata.mmo_data->byte_no % 4),
+ 0, 4 - (abfd->tdata.mmo_data->byte_no % 4));
+
+ if (abfd->tdata.mmo_data->have_error
+ || bfd_bwrite (abfd->tdata.mmo_data->buf, 4, abfd) != 4)
+ return FALSE;
+ }
+
+ bfd_put_32 (abfd, (LOP << 24) | (LOP_END << 16) | trie_len, buf);
+ return bfd_bwrite (buf, 4, abfd) == 4;
+}
+
+/* Write section unless it is the register contents section. For that, we
+ instead store the section in the supplied pointer. This function is
+ used through bfd_map_over_sections. */
+
+static void
+mmo_write_section_unless_reg_contents (bfd *abfd, asection *sec, void *p)
+{
+ struct mmo_write_sec_info *infop = (struct mmo_write_sec_info *) p;
+
+ if (! infop->retval)
+ return;
+
+ if (strcmp (sec->name, MMIX_REG_CONTENTS_SECTION_NAME) == 0)
+ {
+ infop->reg_section = sec;
+ return;
+ }
+
+ /* Exclude the convenience register section. */
+ if (strcmp (sec->name, MMIX_REG_SECTION_NAME) == 0)
+ {
+ if (bfd_get_section_flags (abfd, sec) & SEC_HAS_CONTENTS)
+ {
+ /* Make sure it hasn't got contents. It seems impossible to
+ make it carry contents, so we don't have a test-case for
+ this. */
+ (*_bfd_error_handler)
+ (_("%s: internal error, internal register section %s had"
+ " contents\n"),
+ bfd_get_filename (abfd), sec->name);
+ bfd_set_error (bfd_error_bad_value);
+ infop->retval = FALSE;
+ return;
+ }
+
+ return;
+ }
+
+ infop->retval = mmo_internal_write_section (abfd, sec);
+}
+
+/* Do the actual output of a file. Assumes mmo_set_section_contents is
+ already called. */
+
+static bfd_boolean
+mmo_write_object_contents (bfd *abfd)
+{
+ struct mmo_write_sec_info wsecinfo;
+
+ /* First, there are a few words of preamble. */
+ if (! mmo_internal_write_header (abfd))
+ return FALSE;
+
+ wsecinfo.reg_section = NULL;
+ wsecinfo.retval = TRUE;
+
+ bfd_map_over_sections (abfd, mmo_write_section_unless_reg_contents,
+ &wsecinfo);
+
+ if (! wsecinfo.retval)
+ return FALSE;
+
+ if (wsecinfo.reg_section != NULL)
+ {
+ asection *sec = wsecinfo.reg_section;
+ unsigned int z = (unsigned int) (sec->vma / 8);
+
+ /* Registers 0..31 must not be global. Do sanity check on the "vma"
+ of the register contents section and check that it corresponds to
+ the length of the section. */
+ if (z < 32 || z >= 255 || (sec->vma & 7) != 0
+ || sec->vma != 256 * 8 - sec->size - 8)
+ {
+ bfd_set_error (bfd_error_bad_value);
+
+ if (sec->size == 0)
+ /* There must always be at least one such register. */
+ (*_bfd_error_handler)
+ (_("%s: no initialized registers; section length 0\n"),
+ bfd_get_filename (abfd));
+ else if (sec->vma > (256 - 32) * 8)
+ /* Provide better error message for the case of too many
+ global registers. */
+ (*_bfd_error_handler)
+ (_("%s: too many initialized registers; section length %ld\n"),
+ bfd_get_filename (abfd),
+ (long) sec->size);
+ else
+ (*_bfd_error_handler)
+ (_("%s: invalid start address for initialized registers of"
+ " length %ld: 0x%lx%08lx\n"),
+ bfd_get_filename (abfd),
+ (long) sec->size,
+ (unsigned long) (sec->vma >> 32), (unsigned long) (sec->vma));
+
+ return FALSE;
+ }
+
+ if (! mmo_internal_write_post (abfd, z, sec))
+ return FALSE;
+ }
+ else
+ if (! mmo_internal_write_post (abfd, 255, NULL))
+ return FALSE;
+
+ return mmo_write_symbols_and_terminator (abfd);
+}
+
+/* If there's anything in particular in a mmo bfd that we want to free,
+ make this a real function. Only do this if you see major memory
+ thrashing; zealous free:ing will cause unwanted behavior, especially if
+ you "free" memory allocated with "bfd_alloc", or even "bfd_release" a
+ block allocated with "bfd_alloc"; they're really allocated from an
+ obstack, and we don't know what was allocated there since this
+ particular allocation. */
+
+#define mmo_close_and_cleanup _bfd_generic_close_and_cleanup
+#define mmo_bfd_free_cached_info _bfd_generic_bfd_free_cached_info
+
+/* Perhaps we need to adjust this one; mmo labels (originally) without a
+ leading ':' might more appropriately be called local. */
+#define mmo_bfd_is_local_label_name bfd_generic_is_local_label_name
+#define mmo_bfd_is_target_special_symbol \
+ ((bfd_boolean (*) (bfd *, asymbol *)) bfd_false)
+
+/* Is this one really used or defined by anyone? */
+#define mmo_get_lineno _bfd_nosymbols_get_lineno
+
+/* FIXME: We can do better on this one, if we have a dwarf2 .debug_line
+ section or if MMO line numbers are implemented. */
+#define mmo_find_nearest_line _bfd_nosymbols_find_nearest_line
+#define mmo_find_line _bfd_nosymbols_find_line
+#define mmo_find_inliner_info _bfd_nosymbols_find_inliner_info
+#define mmo_make_empty_symbol _bfd_generic_make_empty_symbol
+#define mmo_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol
+#define mmo_read_minisymbols _bfd_generic_read_minisymbols
+#define mmo_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol
+
+#define mmo_get_section_contents_in_window \
+ _bfd_generic_get_section_contents_in_window
+#define mmo_bfd_get_relocated_section_contents \
+ bfd_generic_get_relocated_section_contents
+#define mmo_bfd_gc_sections bfd_generic_gc_sections
+#define mmo_bfd_lookup_section_flags bfd_generic_lookup_section_flags
+#define mmo_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
+#define mmo_bfd_link_add_symbols _bfd_generic_link_add_symbols
+#define mmo_bfd_link_just_syms _bfd_generic_link_just_syms
+#define mmo_bfd_copy_link_hash_symbol_type \
+ _bfd_generic_copy_link_hash_symbol_type
+#define mmo_bfd_final_link _bfd_generic_final_link
+#define mmo_bfd_link_split_section _bfd_generic_link_split_section
+
+/* Strictly speaking, only MMIX uses this restricted format, but let's not
+ stop anybody from shooting themselves in the foot. */
+#define mmo_set_arch_mach bfd_default_set_arch_mach
+#define mmo_bfd_relax_section bfd_generic_relax_section
+#define mmo_bfd_merge_sections bfd_generic_merge_sections
+#define mmo_bfd_is_group_section bfd_generic_is_group_section
+#define mmo_bfd_discard_group bfd_generic_discard_group
+#define mmo_section_already_linked \
+ _bfd_generic_section_already_linked
+#define mmo_bfd_define_common_symbol bfd_generic_define_common_symbol
+
+/* We want to copy time of creation, otherwise we'd use
+ BFD_JUMP_TABLE_COPY (_bfd_generic). */
+#define mmo_bfd_merge_private_bfd_data _bfd_generic_bfd_merge_private_bfd_data
+#define mmo_bfd_copy_private_section_data _bfd_generic_bfd_copy_private_section_data
+#define mmo_bfd_copy_private_symbol_data _bfd_generic_bfd_copy_private_symbol_data
+#define mmo_bfd_copy_private_header_data _bfd_generic_bfd_copy_private_header_data
+#define mmo_bfd_set_private_flags _bfd_generic_bfd_set_private_flags
+#define mmo_bfd_print_private_bfd_data _bfd_generic_bfd_print_private_bfd_data
+
+const bfd_target mmix_mmo_vec =
+{
+ "mmo", /* name */
+ bfd_target_mmo_flavour,
+ BFD_ENDIAN_BIG, /* target byte order */
+ BFD_ENDIAN_BIG, /* target headers byte order */
+
+ /* FIXME: Might need adjustments. */
+ (HAS_RELOC | EXEC_P | /* object flags */
+ HAS_LINENO | HAS_DEBUG |
+ HAS_SYMS | HAS_LOCALS | WP_TEXT),
+
+ /* FIXME: Might need adjustments. */
+ (SEC_CODE | SEC_DATA | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD
+ | SEC_READONLY | SEC_EXCLUDE | SEC_DEBUGGING | SEC_IN_MEMORY),
+ /* section flags */
+ 0, /* leading underscore */
+ ' ', /* ar_pad_char */
+ 16, /* ar_max_namelen */
+ 0, /* match priority. */
+ 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,
+ mmo_object_p, /* bfd_check_format */
+ _bfd_dummy_target,
+ _bfd_dummy_target,
+ },
+ {
+ bfd_false,
+ mmo_mkobject,
+ bfd_false,
+ bfd_false,
+ },
+ { /* bfd_write_contents */
+ bfd_false,
+ mmo_write_object_contents,
+ bfd_false,
+ bfd_false,
+ },
+
+ BFD_JUMP_TABLE_GENERIC (mmo),
+ BFD_JUMP_TABLE_COPY (mmo),
+ BFD_JUMP_TABLE_CORE (_bfd_nocore),
+ BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive),
+ BFD_JUMP_TABLE_SYMBOLS (mmo),
+ BFD_JUMP_TABLE_RELOCS (_bfd_norelocs),
+ BFD_JUMP_TABLE_WRITE (mmo),
+ BFD_JUMP_TABLE_LINK (mmo),
+ BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
+
+ NULL,
+
+ NULL
+};
diff --git a/bfd/netbsd-core.c b/bfd/netbsd-core.c
new file mode 100644
index 0000000..a048f13
--- /dev/null
+++ b/bfd/netbsd-core.c
@@ -0,0 +1,318 @@
+/* BFD back end for NetBSD style core files
+ Copyright (C) 1988-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.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>
+
+/* The machine ID for OpenBSD/sparc64 and older versions of
+ NetBSD/sparc64 overlaps with M_MIPS1. */
+#define M_SPARC64_OPENBSD M_MIPS1
+
+/* Offset of StackGhost cookie within `struct md_coredump' on
+ OpenBSD/sparc. */
+#define SPARC_WCOOKIE_OFFSET 344
+
+/* Offset of StackGhost cookie within `struct md_coredump' on
+ OpenBSD/sparc64. */
+#define SPARC64_WCOOKIE_OFFSET 832
+
+#define netbsd_core_file_matches_executable_p generic_core_file_matches_executable_p
+#define netbsd_core_file_pid _bfd_nocore_core_file_pid
+
+struct netbsd_core_struct
+{
+ struct core core;
+} *rawptr;
+
+/* Handle NetBSD-style core dump file. */
+
+static const bfd_target *
+netbsd_core_file_p (bfd *abfd)
+{
+ int val;
+ unsigned i;
+ file_ptr offset;
+ asection *asect;
+ struct core core;
+ struct coreseg coreseg;
+ bfd_size_type amt = sizeof core;
+
+ val = bfd_bread (&core, amt, 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;
+ }
+
+ amt = sizeof (struct netbsd_core_struct);
+ rawptr = (struct netbsd_core_struct *) bfd_zalloc (abfd, amt);
+ if (rawptr == NULL)
+ return 0;
+
+ rawptr->core = core;
+ abfd->tdata.netbsd_core_data = rawptr;
+
+ offset = core.c_hdrsize;
+ for (i = 0; i < core.c_nseg; i++)
+ {
+ const char *sname;
+ flagword flags;
+
+ if (bfd_seek (abfd, offset, SEEK_SET) != 0)
+ goto punt;
+
+ val = bfd_bread (&coreseg, 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;
+
+ switch (CORE_GETFLAG (coreseg))
+ {
+ case CORE_CPU:
+ sname = ".reg";
+ flags = SEC_ALLOC + SEC_HAS_CONTENTS;
+ break;
+ case CORE_DATA:
+ sname = ".data";
+ flags = SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS;
+ break;
+ case CORE_STACK:
+ sname = ".stack";
+ flags = SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS;
+ break;
+ default:
+ sname = ".unknown";
+ flags = SEC_ALLOC + SEC_HAS_CONTENTS;
+ break;
+ }
+ asect = bfd_make_section_anyway_with_flags (abfd, sname, flags);
+ if (asect == NULL)
+ goto punt;
+
+ asect->size = coreseg.c_size;
+ asect->vma = coreseg.c_addr;
+ asect->filepos = offset;
+ asect->alignment_power = 2;
+
+ if (CORE_GETFLAG (coreseg) == CORE_CPU)
+ {
+ bfd_size_type wcookie_offset;
+
+ switch (CORE_GETMID (core))
+ {
+ case M_SPARC_NETBSD:
+ wcookie_offset = SPARC_WCOOKIE_OFFSET;
+ break;
+ case M_SPARC64_OPENBSD:
+ wcookie_offset = SPARC64_WCOOKIE_OFFSET;
+ break;
+ default:
+ wcookie_offset = 0;
+ break;
+ }
+
+ if (wcookie_offset > 0 && coreseg.c_size > wcookie_offset)
+ {
+ /* Truncate the .reg section. */
+ asect->size = wcookie_offset;
+
+ /* And create the .wcookie section. */
+ flags = SEC_ALLOC + SEC_HAS_CONTENTS;
+ asect = bfd_make_section_anyway_with_flags (abfd, ".wcookie",
+ flags);
+ if (asect == NULL)
+ goto punt;
+
+ asect->size = coreseg.c_size - wcookie_offset;
+ asect->vma = 0;
+ asect->filepos = offset + wcookie_offset;
+ asect->alignment_power = 2;
+ }
+ }
+
+ offset += coreseg.c_size;
+ }
+
+ /* Set architecture from machine ID. */
+ switch (CORE_GETMID (core))
+ {
+ case M_ALPHA_NETBSD:
+ bfd_default_set_arch_mach (abfd, bfd_arch_alpha, 0);
+ break;
+
+ case M_ARM6_NETBSD:
+ bfd_default_set_arch_mach (abfd, bfd_arch_arm, bfd_mach_arm_3);
+ break;
+
+ case M_X86_64_NETBSD:
+ bfd_default_set_arch_mach (abfd, bfd_arch_i386, bfd_mach_x86_64);
+ break;
+
+ case M_386_NETBSD:
+ bfd_default_set_arch_mach (abfd, bfd_arch_i386, bfd_mach_i386_i386);
+ break;
+
+ case M_68K_NETBSD:
+ case M_68K4K_NETBSD:
+ bfd_default_set_arch_mach (abfd, bfd_arch_m68k, 0);
+ break;
+
+ case M_88K_OPENBSD:
+ bfd_default_set_arch_mach (abfd, bfd_arch_m88k, 0);
+ break;
+
+ case M_HPPA_OPENBSD:
+ bfd_default_set_arch_mach (abfd, bfd_arch_hppa, bfd_mach_hppa11);
+ break;
+
+ case M_POWERPC_NETBSD:
+ bfd_default_set_arch_mach (abfd, bfd_arch_powerpc, bfd_mach_ppc);
+ break;
+
+ case M_SPARC_NETBSD:
+ bfd_default_set_arch_mach (abfd, bfd_arch_sparc, bfd_mach_sparc);
+ break;
+
+ case M_SPARC64_NETBSD:
+ case M_SPARC64_OPENBSD:
+ bfd_default_set_arch_mach (abfd, bfd_arch_sparc, bfd_mach_sparc_v9);
+ break;
+
+ case M_VAX_NETBSD:
+ case M_VAX4K_NETBSD:
+ bfd_default_set_arch_mach (abfd, bfd_arch_vax, 0);
+ break;
+ }
+
+ /* OK, we believe you. You're a core file (sure, sure). */
+ return abfd->xvec;
+
+ punt:
+ bfd_release (abfd, abfd->tdata.any);
+ abfd->tdata.any = NULL;
+ bfd_section_list_clear (abfd);
+ return 0;
+}
+
+static char*
+netbsd_core_file_failing_command (bfd *abfd)
+{
+ /*return core_command (abfd);*/
+ return abfd->tdata.netbsd_core_data->core.c_name;
+}
+
+static int
+netbsd_core_file_failing_signal (bfd *abfd)
+{
+ /*return core_signal (abfd);*/
+ return abfd->tdata.netbsd_core_data->core.c_signo;
+}
+
+/* If somebody calls any byte-swapping routines, shoot them. */
+
+static void
+swap_abort (void)
+{
+ /* This way doesn't require any declaration for ANSI to fuck up. */
+ abort ();
+}
+
+#define NO_GET ((bfd_vma (*) (const void *)) swap_abort)
+#define NO_PUT ((void (*) (bfd_vma, void *)) swap_abort)
+#define NO_GETS ((bfd_signed_vma (*) (const void *)) swap_abort)
+#define NO_GET64 ((bfd_uint64_t (*) (const void *)) swap_abort)
+#define NO_PUT64 ((void (*) (bfd_uint64_t, void *)) swap_abort)
+#define NO_GETS64 ((bfd_int64_t (*) (const void *)) swap_abort)
+
+const bfd_target core_netbsd_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 | /* Section flags. */
+ SEC_ALLOC | SEC_LOAD | SEC_RELOC),
+ 0, /* Symbol prefix. */
+ ' ', /* ar_pad_char. */
+ 16, /* ar_max_namelen. */
+ 0, /* Match priority. */
+ NO_GET64, NO_GETS64, NO_PUT64, /* 64 bit data. */
+ NO_GET, NO_GETS, NO_PUT, /* 32 bit data. */
+ NO_GET, NO_GETS, NO_PUT, /* 16 bit data. */
+ NO_GET64, NO_GETS64, NO_PUT64, /* 64 bit hdrs. */
+ NO_GET, NO_GETS, NO_PUT, /* 32 bit hdrs. */
+ NO_GET, NO_GETS, 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),
+
+ NULL,
+
+ NULL /* Backend_data. */
+ };
diff --git a/bfd/netbsd.h b/bfd/netbsd.h
new file mode 100644
index 0000000..e4b861c
--- /dev/null
+++ b/bfd/netbsd.h
@@ -0,0 +1,119 @@
+/* BFD back-end definitions used by all NetBSD targets.
+ Copyright (C) 1990-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, 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 "sysdep.h"
+#include "bfd.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 bfd_boolean MY (write_object_contents) (bfd *);
+
+#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 bfd_boolean
+MY (write_object_contents) (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);
+ }
+
+ obj_reloc_entry_size (abfd) = RELOC_STD_SIZE;
+
+ /* 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 endiannesses? */
+ 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 0000000..4eb4bee
--- /dev/null
+++ b/bfd/newsos3.c
@@ -0,0 +1,43 @@
+/* BFD back-end for NewsOS3 (Sony, 68k) binaries.
+ Copyright (C) 1990-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#define TARGET_PAGE_SIZE 4096
+#define SEGMENT_SIZE TARGET_PAGE_SIZE
+#define TEXT_START_ADDR 0
+
+/* Do not "beautify" the CONCAT* macro args. Traditional C will not
+ remove whitespace added here, and thus will fail to concatenate
+ the tokens. */
+#define MY(OP) CONCAT2 (m68k_aout_newsos3_,OP)
+#define TARGETNAME "a.out-newsos3"
+#define ENTRY_CAN_BE_ZERO
+#define DEFAULT_ARCH bfd_arch_m68k
+#define TARGET_IS_BIG_ENDIAN_P
+#define N_HEADER_IN_TEXT(x) 0
+
+#include "sysdep.h"
+#include "bfd.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 0000000..2343cff
--- /dev/null
+++ b/bfd/nlm-target.h
@@ -0,0 +1,261 @@
+/* Target definitions for 32/64-bit NLM (NetWare Loadable Module)
+ Copyright (C) 1993-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#define nlm_core_file_p _bfd_dummy_target
+
+#define nlm_get_symtab_upper_bound nlmNAME (get_symtab_upper_bound)
+#define nlm_canonicalize_symtab nlmNAME (canonicalize_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_bfd_is_target_special_symbol ((bfd_boolean (*) (bfd *, asymbol *)) bfd_false)
+#define nlm_get_lineno _bfd_nosymbols_get_lineno
+#define nlm_find_nearest_line _bfd_nosymbols_find_nearest_line
+#define nlm_find_line _bfd_nosymbols_find_line
+#define nlm_find_inliner_info _bfd_nosymbols_find_inliner_info
+#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_bfd_reloc_name_lookup _bfd_norelocs_bfd_reloc_name_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_lookup_section_flags bfd_generic_lookup_section_flags
+#define nlm_bfd_merge_sections bfd_generic_merge_sections
+#define nlm_bfd_is_group_section bfd_generic_is_group_section
+#define nlm_bfd_discard_group bfd_generic_discard_group
+#define nlm_section_already_linked _bfd_generic_section_already_linked
+#define nlm_bfd_define_common_symbol bfd_generic_define_common_symbol
+#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_link_just_syms _bfd_generic_link_just_syms
+#define nlm_bfd_copy_link_hash_symbol_type \
+ _bfd_generic_copy_link_hash_symbol_type
+#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. */
+
+/* Forward declaration for use when initialising alternative_target field. */
+#ifdef TARGET_LITTLE_SYM
+extern const bfd_target TARGET_LITTLE_SYM;
+#endif
+
+#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,
+ 0, /* match priority. */
+
+ /* 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),
+
+ /* Alternative endian target. */
+#ifdef TARGET_LITTLE_SYM
+ & TARGET_LITTLE_SYM,
+#else
+ NULL,
+#endif
+
+ /* Backend_data. */
+ (void *) 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,
+ 0, /* match priority. */
+
+ /* 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),
+
+ /* Alternative endian target. */
+#ifdef TARGET_BIG_SYM
+ & TARGET_BIG_SYM,
+#else
+ NULL,
+#endif
+
+ /* Backend_data. */
+ (void *) TARGET_BACKEND_DATA
+};
+#endif
diff --git a/bfd/nlm.c b/bfd/nlm.c
new file mode 100644
index 0000000..acfc5d8
--- /dev/null
+++ b/bfd/nlm.c
@@ -0,0 +1,55 @@
+/* NLM (NetWare Loadable Module) executable support for BFD.
+ Copyright (C) 1993-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+#include "libnlm.h"
+
+/* Make an NLM object. We just need to allocate the backend
+ information. */
+
+bfd_boolean
+nlm_mkobject (bfd * abfd)
+{
+ bfd_size_type amt = sizeof (struct nlm_obj_tdata);
+
+ nlm_tdata (abfd) = bfd_zalloc (abfd, amt);
+ 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. */
+
+bfd_boolean
+nlm_set_arch_mach (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 0000000..1e403a1
--- /dev/null
+++ b/bfd/nlm32-alpha.c
@@ -0,0 +1,859 @@
+/* Support for 32-bit Alpha NLM (NetWare Loadable Module)
+ Copyright (C) 1993-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, 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 "sysdep.h"
+#include "bfd.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"
+
+/* 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 bfd_boolean
+nlm_alpha_backend_object_p (bfd *abfd)
+{
+ struct nlm32_alpha_external_prefix_header s;
+ file_ptr size;
+
+ if (bfd_bread (&s, (bfd_size_type) sizeof s, abfd) != sizeof s)
+ return FALSE;
+
+ if (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 = H_GET_32 (abfd, s.size);
+ if (bfd_seek (abfd, size, SEEK_SET) != 0)
+ return FALSE;
+
+ return TRUE;
+}
+
+/* Write out the prefix. */
+
+static bfd_boolean
+nlm_alpha_write_prefix (bfd *abfd)
+{
+ struct nlm32_alpha_external_prefix_header s;
+
+ memset (&s, 0, sizeof s);
+ H_PUT_32 (abfd, NLM32_ALPHA_MAGIC, s.magic);
+ H_PUT_32 (abfd, 2, s.format);
+ H_PUT_32 (abfd, sizeof s, s.size);
+ if (bfd_bwrite (&s, (bfd_size_type) sizeof s, abfd) != sizeof s)
+ return FALSE;
+ return TRUE;
+}
+
+#define ONES(n) (((bfd_vma) 1 << ((n) - 1) << 1) - 1)
+
+/* 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, /* Source mask. */
+ 0, /* Dest 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, /* Source mask. */
+ 0xffffffff, /* Dest 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. */
+ ONES (64), /* Source mask. */
+ ONES (64), /* Dest 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, /* Source mask. */
+ 0xffffffff, /* Dest 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, /* Source mask. */
+ 0xffff, /* Dest 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, /* Source mask. */
+ 0, /* Dest 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, /* Source mask. */
+ 0xffff, /* Dest 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, /* Source mask. */
+ 0x1fffff, /* Dest 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, /* Source mask. */
+ 0x3fff, /* Dest 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, /* Source mask. */
+ 0xffff, /* Dest 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, /* Source mask. */
+ 0xffffffff, /* Dest 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. */
+ ONES (64), /* Source mask. */
+ ONES (64), /* Dest 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, /* Source mask. */
+ 0, /* Dest 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, /* Source mask. */
+ ONES (64), /* Dest 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, /* Source mask. */
+ 0, /* Dest 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, /* Source mask. */
+ 0, /* Dest 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, /* Source mask. */
+ 0, /* Dest 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, /* Source mask. */
+ 0, /* Dest 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 bfd_boolean
+nlm_alpha_read_reloc (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_bread (&ext, (bfd_size_type) sizeof ext, abfd) != sizeof ext)
+ return FALSE;
+
+ /* Swap in the reloc information. */
+ r_vaddr = H_GET_64 (abfd, ext.r_vaddr);
+ r_symndx = H_GET_32 (abfd, 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 < code_sec->size)
+ {
+ *secp = code_sec;
+ rel->address = r_vaddr;
+ }
+ else
+ {
+ *secp = data_sec;
+ rel->address = r_vaddr - code_sec->size;
+ }
+
+ /* 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 bfd_boolean
+nlm_alpha_mangle_relocs (bfd *abfd ATTRIBUTE_UNUSED,
+ asection *sec ATTRIBUTE_UNUSED,
+ const void * data ATTRIBUTE_UNUSED,
+ bfd_vma offset ATTRIBUTE_UNUSED,
+ bfd_size_type count ATTRIBUTE_UNUSED)
+{
+ return TRUE;
+}
+
+/* Read an ALPHA NLM import record. */
+
+static bfd_boolean
+nlm_alpha_read_import (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;
+ bfd_size_type amt;
+
+ if (bfd_bread (& symlength, (bfd_size_type) sizeof (symlength), abfd)
+ != sizeof (symlength))
+ return FALSE;
+ sym -> symbol.the_bfd = abfd;
+ name = bfd_alloc (abfd, (bfd_size_type) symlength + 1);
+ if (name == NULL)
+ return FALSE;
+ if (bfd_bread (name, (bfd_size_type) symlength, 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_bread (temp, (bfd_size_type) sizeof (temp), abfd)
+ != sizeof (temp))
+ return FALSE;
+ rcount = H_GET_32 (abfd, temp);
+ amt = rcount * sizeof (struct nlm_relent);
+ nlm_relocs = bfd_alloc (abfd, amt);
+ 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))
+ return FALSE;
+ nlm_relocs -> section = section;
+ nlm_relocs++;
+ sym -> rcnt++;
+ }
+
+ return TRUE;
+}
+
+/* Write an Alpha NLM reloc. */
+
+static bfd_boolean
+nlm_alpha_write_import (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_get_section_by_name (abfd, NLM_CODE_NAME) -> size;
+ 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. */
+ H_PUT_64 (abfd, r_vaddr, ext.r_vaddr);
+ H_PUT_32 (abfd, r_symndx, 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_bwrite (&ext, (bfd_size_type) sizeof ext, 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 bfd_boolean
+nlm_alpha_set_public_section (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 < code_sec->size)
+ {
+ sym->symbol.section = code_sec;
+ sym->symbol.flags |= BSF_FUNCTION;
+ }
+ else
+ {
+ sym->symbol.section = data_sec;
+ sym->symbol.value -= code_sec->size;
+ /* The data segment had better be aligned. */
+ BFD_ASSERT ((code_sec->size & 0xf) == 0);
+ }
+ return TRUE;
+}
+
+/* Get the offset to write out for a public symbol. */
+
+static bfd_vma
+nlm_alpha_get_public_offset (bfd * abfd ATTRIBUTE_UNUSED, asymbol * sym)
+{
+ return bfd_asymbol_value (sym);
+}
+
+/* Write an Alpha NLM external symbol. */
+
+static bfd_boolean
+nlm_alpha_write_external (bfd *abfd,
+ bfd_size_type count,
+ asymbol *sym,
+ struct reloc_and_sec *relocs)
+{
+ bfd_size_type i;
+ bfd_byte len;
+ unsigned char temp[NLM_TARGET_LONG_SIZE];
+ arelent r;
+
+ len = strlen (sym->name);
+ if ((bfd_bwrite (&len, (bfd_size_type) sizeof (bfd_byte), abfd)
+ != sizeof (bfd_byte))
+ || bfd_bwrite (sym->name, (bfd_size_type) len, abfd) != len)
+ return FALSE;
+
+ bfd_put_32 (abfd, count + 2, temp);
+ if (bfd_bwrite (temp, (bfd_size_type) sizeof (temp), 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, NULL, &r))
+ return FALSE;
+
+ r.address = nlm_alpha_backend_data (abfd)->gp;
+ r.addend = 0;
+ if (! nlm_alpha_write_import (abfd, NULL, &r))
+ return FALSE;
+
+ for (i = 0; i < count; i++)
+ if (! nlm_alpha_write_import (abfd, relocs[i].sec, relocs[i].rel))
+ 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 alpha_nlm32_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 0000000..797e667
--- /dev/null
+++ b/bfd/nlm32-i386.c
@@ -0,0 +1,429 @@
+/* Support for 32-bit i386 NLM (NetWare Loadable Module)
+ Copyright (C) 1993-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.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"
+
+/* 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, /* Source mask. */
+ 0xffffffff, /* Dest mask. */
+ FALSE); /* PR rel_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, /* Source mask. */
+ 0xffffffff, /* Dest mask. */
+ TRUE); /* PR rel_offset. */
+
+/* Read a NetWare i386 reloc. */
+
+static bfd_boolean
+nlm_i386_read_reloc (bfd *abfd,
+ nlmNAME (symbol_type) *sym,
+ asection **secp,
+ arelent *rel)
+{
+ bfd_byte temp[4];
+ bfd_vma val;
+ const char *name;
+
+ if (bfd_bread (temp, (bfd_size_type) sizeof (temp), 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 bfd_boolean
+nlm_i386_write_import (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_bwrite (temp, (bfd_size_type) sizeof (temp), abfd) != sizeof (temp))
+ return FALSE;
+
+ return TRUE;
+}
+
+/* I want to be able to use objcopy to turn an 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 bfd_boolean
+nlm_i386_mangle_relocs (bfd *abfd,
+ asection *sec,
+ const void * 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 bfd_boolean
+nlm_i386_read_import (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_bread (& symlength, (bfd_size_type) sizeof (symlength), abfd)
+ != sizeof (symlength))
+ return FALSE;
+ sym -> symbol.the_bfd = abfd;
+ name = bfd_alloc (abfd, (bfd_size_type) symlength + 1);
+ if (name == NULL)
+ return FALSE;
+ if (bfd_bread (name, (bfd_size_type) symlength, 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_bread (temp, (bfd_size_type) sizeof (temp), abfd) != sizeof (temp))
+ return FALSE;
+ rcount = H_GET_32 (abfd, temp);
+ nlm_relocs = 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))
+ return FALSE;
+ nlm_relocs -> section = section;
+ nlm_relocs++;
+ sym -> rcnt++;
+ }
+ return TRUE;
+}
+
+/* Write out an external reference. */
+
+static bfd_boolean
+nlm_i386_write_external (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_bwrite (&len, (bfd_size_type) sizeof (bfd_byte), abfd)
+ != sizeof (bfd_byte))
+ || bfd_bwrite (sym->name, (bfd_size_type) len, abfd) != len)
+ return FALSE;
+
+ bfd_put_32 (abfd, count, temp);
+ if (bfd_bwrite (temp, (bfd_size_type) sizeof (temp), abfd) != sizeof (temp))
+ return FALSE;
+
+ for (i = 0; i < count; i++)
+ if (! nlm_i386_write_import (abfd, relocs[i].sec, relocs[i].rel))
+ 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, /* Set_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 i386_nlm32_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 0000000..5ff11f0
--- /dev/null
+++ b/bfd/nlm32-ppc.c
@@ -0,0 +1,986 @@
+/* Support for 32-bit PowerPC NLM (NetWare Loadable Module)
+ Copyright (C) 1994-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.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
+
+/* 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 bfd_boolean
+nlm_powerpc_backend_object_p (bfd *abfd)
+{
+ struct nlm32_powerpc_external_prefix_header s;
+
+ if (bfd_bread (& s, (bfd_size_type) sizeof s, abfd) != sizeof s)
+ return FALSE;
+
+ if (memcmp (s.signature, NLM32_POWERPC_SIGNATURE, sizeof s.signature) != 0
+ || H_GET_32 (abfd, s.headerVersion) != NLM32_POWERPC_HEADER_VERSION)
+ return FALSE;
+
+ return TRUE;
+}
+
+/* Write out the prefix. */
+
+static bfd_boolean
+nlm_powerpc_write_prefix (bfd *abfd)
+{
+ struct nlm32_powerpc_external_prefix_header s;
+
+ memset (&s, 0, sizeof s);
+ memcpy (s.signature, NLM32_POWERPC_SIGNATURE, sizeof s.signature);
+ H_PUT_32 (abfd, NLM32_POWERPC_HEADER_VERSION, s.headerVersion);
+ H_PUT_32 (abfd, 0, s.origins);
+
+ /* FIXME: What should we do about the date? */
+
+ if (bfd_bwrite (& s, (bfd_size_type) sizeof s, abfd) != sizeof s)
+ return FALSE;
+
+ return TRUE;
+}
+
+/* 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, /* Source mask. */
+ 0xffffffff, /* Dest mask. */
+ FALSE), /* PC rel 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, /* Source mask. */
+ 0xffffffff, /* Dest mask. */
+ FALSE), /* PC rel 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, /* Source mask. */
+ 0xffffffff, /* Dest mask. */
+ FALSE), /* PC rel 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, /* Source mask. */
+ 0xffff, /* Dest mask. */
+ FALSE), /* PC rel 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, /* Source mask. */
+ 0xffffffff, /* Dest mask. */
+ FALSE), /* PC rel 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, /* Source mask. */
+ 0xffff, /* Dest mask. */
+ FALSE), /* PC rel 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, /* Source mask. */
+ 0xffff, /* Dest mask. */
+ FALSE), /* PC rel 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, /* Source mask. */
+ 0x3fffffc, /* Dest mask. */
+ FALSE), /* PC rel 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, /* Source mask. */
+ 0x3fffffc, /* Dest mask. */
+ FALSE), /* PC rel 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, /* Source mask. */
+ 0xffff, /* Dest mask. */
+ FALSE), /* PC rel 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, /* Source mask. */
+ 0xffff, /* Dest mask. */
+ FALSE), /* PC rel 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, /* Source mask. */
+ 0, /* Dest mask. */
+ FALSE), /* PC rel 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, /* Source mask. */
+ 0xffff, /* Dest mask. */
+ FALSE), /* PC rel 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, /* Source mask. */
+ 0xffff, /* Dest mask. */
+ FALSE), /* PC rel 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, /* Source mask. */
+ 0xffffffff, /* Dest mask. */
+ FALSE), /* PC rel 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, /* Source mask. */
+ 0xffffffff, /* Dest mask. */
+ FALSE), /* PC rel 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, /* Source mask. */
+ 0xffff, /* Dest mask. */
+ FALSE), /* PC rel 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, /* Source mask. */
+ 0xffff, /* Dest mask. */
+ FALSE), /* PC rel 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, /* Source mask. */
+ 0xffff, /* Dest mask. */
+ FALSE), /* PC rel 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, /* Source mask. */
+ 0xffff, /* Dest mask. */
+ FALSE), /* PC rel 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, /* Source mask. */
+ 0xffff, /* Dest mask. */
+ FALSE), /* PC rel 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, /* Source mask. */
+ 0xffff, /* Dest mask. */
+ FALSE) /* PC rel offset. */
+};
+
+#define HOWTO_COUNT (sizeof nlm_powerpc_howto_table \
+ / sizeof nlm_powerpc_howto_table[0])
+
+/* Read a PowerPC NLM reloc. */
+
+static bfd_boolean
+nlm_powerpc_read_reloc (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_bread (&ext, (bfd_size_type) sizeof ext, abfd) != sizeof ext)
+ return FALSE;
+
+ /* Swap in the fields. */
+ l_vaddr = H_GET_32 (abfd, ext.l_vaddr);
+ l_symndx = H_GET_32 (abfd, ext.l_symndx);
+ l_rtype = H_GET_16 (abfd, ext.l_rtype);
+ l_rsecnm = 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 -= code_sec->size;
+ }
+ else
+ {
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+
+ rel->address = l_vaddr;
+
+ return TRUE;
+}
+
+#else /* not 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, /* Source mask. */
+ 0xffffffff, /* Dest mask. */
+ FALSE); /* PC rel_offset. */
+
+/* Read a PowerPC NLM reloc. */
+
+static bfd_boolean
+nlm_powerpc_read_reloc (bfd *abfd,
+ nlmNAME (symbol_type) *sym,
+ asection **secp,
+ arelent *rel)
+{
+ bfd_byte temp[4];
+ bfd_vma val;
+ const char *name;
+
+ if (bfd_bread (temp, (bfd_size_type) sizeof (temp), 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;
+}
+
+#endif /* not OLDFORMAT */
+
+/* Mangle PowerPC NLM relocs for output. */
+
+static bfd_boolean
+nlm_powerpc_mangle_relocs (bfd *abfd ATTRIBUTE_UNUSED,
+ asection *sec ATTRIBUTE_UNUSED,
+ const void * data ATTRIBUTE_UNUSED,
+ bfd_vma offset ATTRIBUTE_UNUSED,
+ bfd_size_type count ATTRIBUTE_UNUSED)
+{
+ return TRUE;
+}
+
+/* Read a PowerPC NLM import record */
+
+static bfd_boolean
+nlm_powerpc_read_import (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_bread (& symlength, (bfd_size_type) sizeof (symlength), abfd)
+ != sizeof (symlength))
+ return FALSE;
+ sym -> symbol.the_bfd = abfd;
+ name = bfd_alloc (abfd, (bfd_size_type) symlength + 1);
+ if (name == NULL)
+ return FALSE;
+ if (bfd_bread (name, (bfd_size_type) symlength, 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_bread (temp, (bfd_size_type) sizeof (temp), abfd)
+ != sizeof (temp))
+ return FALSE;
+ rcount = H_GET_32 (abfd, temp);
+ nlm_relocs = bfd_alloc (abfd, rcount * sizeof (struct nlm_relent));
+ if (nlm_relocs == 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))
+ return FALSE;
+ nlm_relocs -> section = section;
+ nlm_relocs++;
+ sym -> rcnt++;
+ }
+ return TRUE;
+}
+
+#ifndef OLDFORMAT
+
+/* Write a PowerPC NLM reloc. */
+
+static bfd_boolean
+nlm_powerpc_write_import (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_bwrite (temp, (bfd_size_type) sizeof (temp), 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 bfd_boolean
+nlm_powerpc_write_reloc (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;
+ }
+ }
+
+ H_PUT_32 (abfd, 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;
+ H_PUT_16 (abfd, l_rtype, ext.l_rtype);
+
+ address = rel->address;
+
+ if (sec == code_sec)
+ l_rsecnm = 0;
+ else if (sec == data_sec)
+ {
+ l_rsecnm = 1;
+ address += code_sec->size;
+ }
+ else
+ {
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+
+ H_PUT_16 (abfd, l_rsecnm, ext.l_rsecnm);
+ H_PUT_32 (abfd, address, ext.l_vaddr);
+
+ if (bfd_bwrite (&ext, (bfd_size_type) sizeof ext, abfd) != sizeof ext)
+ return FALSE;
+
+ return TRUE;
+}
+
+/* Write a PowerPC NLM import. */
+
+static bfd_boolean
+nlm_powerpc_write_import (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 bfd_boolean
+nlm_powerpc_write_external (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_bwrite (&len, (bfd_size_type) sizeof (bfd_byte), abfd)
+ != sizeof (bfd_byte))
+ || bfd_bwrite (sym->name, (bfd_size_type) len, abfd) != len)
+ return FALSE;
+
+ bfd_put_32 (abfd, count, temp);
+ if (bfd_bwrite (temp, (bfd_size_type) sizeof (temp), 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 bfd_boolean
+nlm_powerpc_set_public_section (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 (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 powerpc_nlm32_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 0000000..4a68fa2
--- /dev/null
+++ b/bfd/nlm32-sparc.c
@@ -0,0 +1,378 @@
+/* Support for 32-bit SPARC NLM (NetWare Loadable Module)
+ Copyright (C) 1993-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.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"
+
+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
+};
+
+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 bfd_boolean
+nlm_sparc_read_reloc (bfd *abfd,
+ nlmNAME (symbol_type) *sym ATTRIBUTE_UNUSED,
+ asection **secp,
+ arelent *rel)
+{
+ bfd_vma val, addend;
+ unsigned int howto_index;
+ unsigned int type;
+ struct nlm32_sparc_reloc_ext tmp_reloc;
+ asection *code_sec;
+
+ if (bfd_bread (&tmp_reloc, (bfd_size_type) 12, abfd) != 12)
+ return FALSE;
+
+ code_sec = bfd_get_section_by_name (abfd, NLM_CODE_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 (howto_index = 0;
+ howto_index < sizeof (nlm32_sparc_howto_table) / sizeof (reloc_howto_type);
+ howto_index++)
+ if (nlm32_sparc_howto_table[howto_index].type == type)
+ {
+ rel->howto = &nlm32_sparc_howto_table[howto_index];
+ break;
+ }
+
+#ifdef DEBUG
+ fprintf (stderr, "%s: address = %08lx, addend = %08lx, type = %u, howto = %p\n",
+ __FUNCTION__, (unsigned long) rel->address,
+ (unsigned long) rel->addend, type, rel->howto);
+#endif
+ return TRUE;
+
+}
+
+/* Write a NetWare sparc reloc. */
+
+static bfd_boolean
+nlm_sparc_write_reloc (bfd * abfd, asection * sec, arelent * rel)
+{
+ bfd_vma val;
+ struct nlm32_sparc_reloc_ext tmp_reloc;
+ unsigned int howto_index;
+ int type = -1;
+ reloc_howto_type *tmp;
+
+ for (howto_index = 0;
+ howto_index < sizeof (nlm32_sparc_howto_table) / sizeof (reloc_howto_type);
+ howto_index++)
+ {
+ tmp = &nlm32_sparc_howto_table[howto_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. */
+ val = bfd_get_section_vma (abfd, sec) + rel->address;
+
+#ifdef DEBUG
+ fprintf (stderr, "%s: val = %08lx, addend = %08lx, type = %u\n",
+ __FUNCTION__, (unsigned long) val, (unsigned long) 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_bwrite (&tmp_reloc, (bfd_size_type) 12, abfd) != 12)
+ return FALSE;
+
+ return TRUE;
+}
+
+/* Mangle relocs for SPARC NetWare. We can just use the standard
+ SPARC relocs. */
+
+static bfd_boolean
+nlm_sparc_mangle_relocs (bfd *abfd ATTRIBUTE_UNUSED,
+ asection *sec ATTRIBUTE_UNUSED,
+ const void * data ATTRIBUTE_UNUSED,
+ bfd_vma offset ATTRIBUTE_UNUSED,
+ bfd_size_type count ATTRIBUTE_UNUSED)
+{
+ return TRUE;
+}
+
+/* Read a NetWare sparc import record. */
+
+static bfd_boolean
+nlm_sparc_read_import (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_bread (temp, (bfd_size_type) 4, abfd) != 4)
+ return FALSE;
+
+ rcount = bfd_get_32 (abfd, temp);
+
+ /* Next, read in the length of the symbol. */
+ if (bfd_bread (& symlength, (bfd_size_type) sizeof (symlength), abfd)
+ != sizeof (symlength))
+ return FALSE;
+ sym -> symbol.the_bfd = abfd;
+ name = bfd_alloc (abfd, (bfd_size_type) symlength + 1);
+ if (name == NULL)
+ return FALSE;
+
+ /* Then read in the symbol. */
+ if (bfd_bread (name, (bfd_size_type) symlength, 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 = 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))
+ return FALSE;
+ nlm_relocs -> section = section;
+ nlm_relocs++;
+ sym -> rcnt++;
+ }
+
+ return TRUE;
+}
+
+static bfd_boolean
+nlm_sparc_write_import (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 = code->size;
+ else if (symsec == bss)
+ base = code->size + data->size;
+ else
+ base = 0;
+
+#ifdef DEBUG
+ fprintf (stderr, "%s: <%lx, 1>\n\t",
+ __FUNCTION__, (unsigned long) (base + (*rel->sym_ptr_ptr)->value));
+#endif
+ bfd_put_32 (abfd, base + (*rel->sym_ptr_ptr)->value, temp);
+ if (bfd_bwrite (temp, (bfd_size_type) 4, abfd) != 4)
+ return FALSE;
+ bfd_put_32 (abfd, (bfd_vma) 1, temp);
+ if (bfd_bwrite (temp, (bfd_size_type) 4, abfd) != 4)
+ return FALSE;
+ if (! nlm_sparc_write_reloc (abfd, sec, rel))
+ return FALSE;
+ return TRUE;
+}
+
+/* Write out an external reference. */
+
+static bfd_boolean
+nlm_sparc_write_external (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_bwrite (temp, (bfd_size_type) sizeof (temp), abfd) != sizeof (temp))
+ return FALSE;
+
+ len = strlen (sym->name);
+ if ((bfd_bwrite (&len, (bfd_size_type) sizeof (bfd_byte), abfd)
+ != sizeof (bfd_byte))
+ || bfd_bwrite (sym->name, (bfd_size_type) len, abfd) != len)
+ return FALSE;
+
+ for (i = 0; i < count; i++)
+ if (! nlm_sparc_write_reloc (abfd, relocs[i].sec, relocs[i].rel))
+ return FALSE;
+
+ return TRUE;
+}
+
+static bfd_boolean
+nlm_sparc_write_export (bfd * abfd, asymbol * sym, bfd_vma value)
+{
+ bfd_byte len;
+ bfd_byte temp[4];
+
+#ifdef DEBUG
+ fprintf (stderr, "%s: <%lx, %u, %s>\n",
+ __FUNCTION__, (unsigned long) value, strlen (sym->name), sym->name);
+#endif
+ bfd_put_32 (abfd, value, temp);
+ len = strlen (sym->name);
+
+ if (bfd_bwrite (temp, (bfd_size_type) 4, abfd) != 4
+ || bfd_bwrite (&len, (bfd_size_type) 1, abfd) != 1
+ || bfd_bwrite (sym->name, (bfd_size_type) len, 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 sparc_nlm32_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 0000000..ea20c6a
--- /dev/null
+++ b/bfd/nlm32.c
@@ -0,0 +1,22 @@
+/* NLM (NetWare Loadable Module) 32-bit executable support for BFD.
+ Copyright (C) 1993-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#define ARCH_SIZE 32
+#include "nlmcode.h"
diff --git a/bfd/nlm64.c b/bfd/nlm64.c
new file mode 100644
index 0000000..a9f4606
--- /dev/null
+++ b/bfd/nlm64.c
@@ -0,0 +1,22 @@
+/* NLM (NetWare Loadable Module) 64-bit executable support for BFD.
+ Copyright (C) 1993-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#define ARCH_SIZE 64
+#include "nlmcode.h"
diff --git a/bfd/nlmcode.h b/bfd/nlmcode.h
new file mode 100644
index 0000000..c8092e0
--- /dev/null
+++ b/bfd/nlmcode.h
@@ -0,0 +1,1980 @@
+/* NLM (NetWare Loadable Module) executable support for BFD.
+ Copyright (C) 1993-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.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_canonicalize_symtab nlmNAME (canonicalize_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)
+
+/* 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 H_PUT_64
+#define get_word H_GET_64
+#endif
+#if ARCH_SIZE == 32
+#define put_word H_PUT_32
+#define get_word H_GET_32
+#endif
+
+/* 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 bfd_boolean
+nlm_swap_variable_header_in (bfd *abfd)
+{
+ unsigned char temp[NLM_TARGET_LONG_SIZE];
+ bfd_size_type amt;
+
+ /* Read the description length and text members. */
+ amt = sizeof (nlm_variable_header (abfd)->descriptionLength);
+ if (bfd_bread ((void *) &nlm_variable_header (abfd)->descriptionLength,
+ amt, abfd) != amt)
+ return FALSE;
+ amt = nlm_variable_header (abfd)->descriptionLength + 1;
+ if (bfd_bread ((void *) nlm_variable_header (abfd)->descriptionText,
+ amt, abfd) != amt)
+ return FALSE;
+
+ /* Read and convert the stackSize field. */
+ amt = sizeof (temp);
+ if (bfd_bread ((void *) temp, amt, abfd) != amt)
+ return FALSE;
+ nlm_variable_header (abfd)->stackSize = get_word (abfd, (bfd_byte *) temp);
+
+ /* Read and convert the reserved field. */
+ amt = sizeof (temp);
+ if (bfd_bread ((void *) temp, amt, abfd) != amt)
+ return FALSE;
+ nlm_variable_header (abfd)->reserved = get_word (abfd, (bfd_byte *) temp);
+
+ /* Read the oldThreadName field. This field is a fixed length string. */
+ amt = sizeof (nlm_variable_header (abfd)->oldThreadName);
+ if (bfd_bread ((void *) nlm_variable_header (abfd)->oldThreadName,
+ amt, abfd) != amt)
+ return FALSE;
+
+ /* Read the screen name length and text members. */
+ amt = sizeof (nlm_variable_header (abfd)->screenNameLength);
+ if (bfd_bread ((void *) & nlm_variable_header (abfd)->screenNameLength,
+ amt, abfd) != amt)
+ return FALSE;
+ amt = nlm_variable_header (abfd)->screenNameLength + 1;
+ if (bfd_bread ((void *) nlm_variable_header (abfd)->screenName,
+ amt, abfd) != amt)
+ return FALSE;
+
+ /* Read the thread name length and text members. */
+ amt = sizeof (nlm_variable_header (abfd)->threadNameLength);
+ if (bfd_bread ((void *) & nlm_variable_header (abfd)->threadNameLength,
+ amt, abfd) != amt)
+ return FALSE;
+ amt = nlm_variable_header (abfd)->threadNameLength + 1;
+ if (bfd_bread ((void *) nlm_variable_header (abfd)->threadName,
+ amt, abfd) != amt)
+ return FALSE;
+ return TRUE;
+}
+
+/* Add a section to the bfd. */
+
+static bfd_boolean
+add_bfd_section (bfd *abfd,
+ char *name,
+ file_ptr offset,
+ bfd_size_type size,
+ flagword flags)
+{
+ asection *newsect;
+
+ newsect = bfd_make_section_with_flags (abfd, name, flags);
+ if (newsect == NULL)
+ return FALSE;
+
+ newsect->vma = 0; /* NLM's are relocatable. */
+ newsect->size = size;
+ newsect->filepos = offset;
+ newsect->alignment_power = bfd_log2 ((bfd_vma) 0); /* FIXME */
+
+ 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 bfd_boolean
+nlm_swap_auxiliary_headers_in (bfd *abfd)
+{
+ char tempstr[16];
+ file_ptr position;
+ bfd_size_type amt;
+
+ for (;;)
+ {
+ position = bfd_tell (abfd);
+ amt = sizeof (tempstr);
+ if (bfd_bread ((void *) tempstr, amt, abfd) != amt)
+ return FALSE;
+ if (bfd_seek (abfd, position, SEEK_SET) != 0)
+ return FALSE;
+ if (CONST_STRNEQ (tempstr, "VeRsIoN#"))
+ {
+ Nlm_External_Version_Header thdr;
+
+ amt = sizeof (thdr);
+ if (bfd_bread ((void *) &thdr, amt, abfd) != amt)
+ 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 (CONST_STRNEQ (tempstr, "MeSsAgEs"))
+ {
+ Nlm_External_Extended_Header thdr;
+
+ amt = sizeof (thdr);
+ if (bfd_bread ((void *) &thdr, amt, abfd) != amt)
+ 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 (CONST_STRNEQ (tempstr, "CoPyRiGhT="))
+ {
+ amt = sizeof (nlm_copyright_header (abfd)->stamp);
+ if (bfd_bread ((void *) nlm_copyright_header (abfd)->stamp,
+ amt, abfd) != amt)
+ return FALSE;
+ if (bfd_bread ((void *) &(nlm_copyright_header (abfd)
+ ->copyrightMessageLength),
+ (bfd_size_type) 1, abfd) != 1)
+ return FALSE;
+ /* The copyright message is a variable length string. */
+ amt = nlm_copyright_header (abfd)->copyrightMessageLength + 1;
+ if (bfd_bread ((void *) nlm_copyright_header (abfd)->copyrightMessage,
+ amt, abfd) != amt)
+ return FALSE;
+ }
+ else if (CONST_STRNEQ (tempstr, "CuStHeAd"))
+ {
+ Nlm_External_Custom_Header thdr;
+ bfd_size_type hdrLength;
+ file_ptr dataOffset;
+ bfd_size_type dataLength;
+ char dataStamp[8];
+ void * hdr;
+
+ /* Read the stamp ("CuStHeAd"). */
+ amt = sizeof (thdr.stamp);
+ if (bfd_bread ((void *) thdr.stamp, amt, abfd) != amt)
+ return FALSE;
+ /* Read the length of this custom header. */
+ amt = sizeof (thdr.length);
+ if (bfd_bread ((void *) thdr.length, amt, abfd) != amt)
+ 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
+ {
+ amt = sizeof (thdr.dataOffset);
+ if (bfd_bread ((void *) thdr.dataOffset, amt, abfd) != amt)
+ return FALSE;
+ dataOffset = get_word (abfd, (bfd_byte *) thdr.dataOffset);
+ }
+ if (hdrLength < 2 * NLM_TARGET_LONG_SIZE)
+ dataLength = 0;
+ else
+ {
+ amt = sizeof (thdr.dataLength);
+ if (bfd_bread ((void *) thdr.dataLength, amt, abfd) != amt)
+ return FALSE;
+ dataLength = get_word (abfd, (bfd_byte *) thdr.dataLength);
+ }
+ if (hdrLength < 2 * NLM_TARGET_LONG_SIZE + 8)
+ memset (dataStamp, 0, sizeof (dataStamp));
+ else
+ {
+ amt = sizeof (dataStamp);
+ if (bfd_bread ((void *) dataStamp, amt, abfd) != amt)
+ 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_bread (hdr, 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 (CONST_STRNEQ (dataStamp, "CyGnUsEx"))
+ {
+ 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_alloc (abfd, dataLength);
+ if (contents == NULL)
+ return FALSE;
+ if (bfd_bread (contents, dataLength, abfd) != dataLength)
+ return FALSE;
+ if (bfd_seek (abfd, pos, SEEK_SET) != 0)
+ return FALSE;
+
+ LITMEMCPY (nlm_cygnus_ext_header (abfd), "CyGnUsEx");
+ 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) &~ (size_t) 3;
+ p += l;
+ filepos = H_GET_32 (abfd, p);
+ p += 4;
+ size = H_GET_32 (abfd, p);
+ p += 4;
+
+ newsec = bfd_make_section_anyway (abfd, name);
+ if (newsec == NULL)
+ return FALSE;
+ newsec->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;
+}
+
+const bfd_target *
+nlm_object_p (bfd *abfd)
+{
+ struct nlm_obj_tdata *preserved_tdata = nlm_tdata (abfd);
+ bfd_boolean (*backend_object_p) (bfd *);
+ void * x_fxdhdr = NULL;
+ Nlm_Internal_Fixed_Header *i_fxdhdrp;
+ struct nlm_obj_tdata *new_tdata = NULL;
+ const char *signature;
+ enum bfd_architecture arch;
+ bfd_size_type amt;
+
+ /* 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. */
+ amt = nlm_fixed_header_size (abfd);
+ x_fxdhdr = bfd_malloc (amt);
+ if (x_fxdhdr == NULL)
+ goto got_no_match;
+
+ if (bfd_bread ((void *) x_fxdhdr, amt, abfd) != amt)
+ {
+ 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. */
+ amt = sizeof (struct nlm_obj_tdata);
+ new_tdata = bfd_zalloc (abfd, amt);
+ 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 endianness 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;
+}
+
+/* Swap and write out the variable length header. All the fields must
+ exist in the NLM, and must exist in this order. */
+
+static bfd_boolean
+nlm_swap_variable_header_out (bfd *abfd)
+{
+ bfd_byte temp[NLM_TARGET_LONG_SIZE];
+ bfd_size_type amt;
+
+ /* Write the description length and text members. */
+ amt = sizeof (nlm_variable_header (abfd)->descriptionLength);
+ if (bfd_bwrite (& nlm_variable_header (abfd)->descriptionLength, amt,
+ abfd) != amt)
+ return FALSE;
+ amt = nlm_variable_header (abfd)->descriptionLength + 1;
+ if (bfd_bwrite ((void *) nlm_variable_header (abfd)->descriptionText, amt,
+ abfd) != amt)
+ return FALSE;
+
+ /* Convert and write the stackSize field. */
+ put_word (abfd, (bfd_vma) nlm_variable_header (abfd)->stackSize, temp);
+ amt = sizeof (temp);
+ if (bfd_bwrite (temp, amt, abfd) != amt)
+ return FALSE;
+
+ /* Convert and write the reserved field. */
+ put_word (abfd, (bfd_vma) nlm_variable_header (abfd)->reserved, temp);
+ amt = sizeof (temp);
+ if (bfd_bwrite (temp, amt, abfd) != amt)
+ return FALSE;
+
+ /* Write the oldThreadName field. This field is a fixed length string. */
+ amt = sizeof (nlm_variable_header (abfd)->oldThreadName);
+ if (bfd_bwrite (nlm_variable_header (abfd)->oldThreadName, amt,
+ abfd) != amt)
+ return FALSE;
+
+ /* Write the screen name length and text members. */
+ amt = sizeof (nlm_variable_header (abfd)->screenNameLength);
+ if (bfd_bwrite (& nlm_variable_header (abfd)->screenNameLength, amt,
+ abfd) != amt)
+ return FALSE;
+ amt = nlm_variable_header (abfd)->screenNameLength + 1;
+ if (bfd_bwrite (nlm_variable_header (abfd)->screenName, amt, abfd) != amt)
+ return FALSE;
+
+ /* Write the thread name length and text members. */
+ amt = sizeof (nlm_variable_header (abfd)->threadNameLength);
+ if (bfd_bwrite (& nlm_variable_header (abfd)->threadNameLength, amt,
+ abfd) != amt)
+ return FALSE;
+ amt = nlm_variable_header (abfd)->threadNameLength + 1;
+ if (bfd_bwrite (nlm_variable_header (abfd)->threadName, amt, abfd) != amt)
+ return FALSE;
+ return TRUE;
+}
+
+/* Return whether there is a non-zero byte in a memory block. */
+
+static bfd_boolean
+find_nonzero (void * 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 bfd_boolean
+nlm_swap_auxiliary_headers_out (bfd *abfd)
+{
+ bfd_size_type amt;
+
+ /* Write out the version header if there is one. */
+ if (find_nonzero (nlm_version_header (abfd),
+ sizeof (Nlm_Internal_Version_Header)))
+ {
+ Nlm_External_Version_Header thdr;
+
+ LITMEMCPY (thdr.stamp, "VeRsIoN#");
+ 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_bwrite ((void *) &thdr, (bfd_size_type) sizeof (thdr), abfd)
+ != sizeof (thdr))
+ return FALSE;
+ }
+
+ /* Note - the CoPyRiGhT tag is emitted before the MeSsAgEs
+ tag in order to make the NW4.x and NW5.x loaders happy. */
+
+ /* Write out the copyright header if there is one. */
+ if (find_nonzero (nlm_copyright_header (abfd),
+ sizeof (Nlm_Internal_Copyright_Header)))
+ {
+ Nlm_External_Copyright_Header thdr;
+
+ LITMEMCPY (thdr.stamp, "CoPyRiGhT=");
+ amt = sizeof (thdr.stamp);
+ if (bfd_bwrite ((void *) thdr.stamp, amt, abfd) != amt)
+ return FALSE;
+ thdr.copyrightMessageLength[0] =
+ nlm_copyright_header (abfd)->copyrightMessageLength;
+ amt = 1;
+ if (bfd_bwrite ((void *) thdr.copyrightMessageLength, amt, abfd) != amt)
+ return FALSE;
+ /* The copyright message is a variable length string. */
+ amt = nlm_copyright_header (abfd)->copyrightMessageLength + 1;
+ if (bfd_bwrite ((void *) nlm_copyright_header (abfd)->copyrightMessage,
+ amt, abfd) != amt)
+ return FALSE;
+ }
+
+ /* Write out the extended header if there is one. */
+ if (find_nonzero (nlm_extended_header (abfd),
+ sizeof (Nlm_Internal_Extended_Header)))
+ {
+ Nlm_External_Extended_Header thdr;
+
+ LITMEMCPY (thdr.stamp, "MeSsAgEs");
+ 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_bwrite ((void *) &thdr, (bfd_size_type) sizeof (thdr), abfd)
+ != sizeof (thdr))
+ return FALSE;
+ }
+
+ /* Write out the custom header if there is one. */
+ if (find_nonzero (nlm_custom_header (abfd),
+ sizeof (Nlm_Internal_Custom_Header)))
+ {
+ Nlm_External_Custom_Header thdr;
+ bfd_boolean ds;
+ bfd_size_type hdrLength;
+
+ ds = find_nonzero (nlm_custom_header (abfd)->dataStamp,
+ sizeof (nlm_custom_header (abfd)->dataStamp));
+ LITMEMCPY (thdr.stamp, "CuStHeAd");
+ 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);
+ amt = sizeof (thdr) - sizeof (thdr.dataStamp);
+ if (bfd_bwrite ((void *) &thdr, amt, abfd) != amt)
+ return FALSE;
+ }
+ else
+ {
+ memcpy (thdr.dataStamp, nlm_custom_header (abfd)->dataStamp,
+ sizeof (thdr.dataStamp));
+ amt = sizeof (thdr);
+ if (bfd_bwrite ((void *) &thdr, amt, abfd) != amt)
+ return FALSE;
+ amt = nlm_custom_header (abfd)->hdrLength;
+ if (bfd_bwrite (nlm_custom_header (abfd)->hdr, amt, abfd) != amt)
+ return FALSE;
+ }
+ }
+
+ /* Write out the Cygnus debugging header if there is one. */
+ if (find_nonzero (nlm_cygnus_ext_header (abfd),
+ sizeof (Nlm_Internal_Cygnus_Ext_Header)))
+ {
+ Nlm_External_Custom_Header thdr;
+
+ LITMEMCPY (thdr.stamp, "CuStHeAd");
+ 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);
+ LITMEMCPY (thdr.dataStamp, "CyGnUsEx");
+ amt = sizeof (thdr);
+ if (bfd_bwrite ((void *) &thdr, amt, abfd) != amt)
+ 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 (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;
+}
+
+/* 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 SYMvoid *S.
+
+ When we return, the bfd symcount is either zero or contains the correct
+ number of symbols. */
+
+static bfd_boolean
+nlm_slurp_symbol_table (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. */
+ bfd_boolean (*read_import_func) (bfd *, nlm_symbol_type *);
+ bfd_boolean (*set_public_section_func) (bfd *, nlm_symbol_type *);
+ bfd_size_type amt;
+
+ 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) != 0)
+ return FALSE;
+
+ amt = totsymcount * sizeof (nlm_symbol_type);
+ sym = bfd_zalloc (abfd, amt);
+ 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)
+ {
+ amt = sizeof (symlength);
+ if (bfd_bread ((void *) &symlength, amt, abfd) != amt)
+ return FALSE;
+ amt = symlength;
+ sym->symbol.the_bfd = abfd;
+ sym->symbol.name = bfd_alloc (abfd, amt + 1);
+ if (!sym->symbol.name)
+ return FALSE;
+ if (bfd_bread ((void *) sym->symbol.name, amt, abfd) != amt)
+ return FALSE;
+ /* Cast away const. */
+ ((char *) (sym->symbol.name))[symlength] = '\0';
+ amt = sizeof (temp);
+ if (bfd_bread ((void *) temp, amt, abfd) != amt)
+ 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))
+ 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) != 0)
+ return FALSE;
+
+ symcount += i_fxdhdrp->numberOfDebugRecords;
+ while (abfd->symcount < symcount)
+ {
+ amt = sizeof (symtype);
+ if (bfd_bread ((void *) &symtype, amt, abfd) != amt)
+ return FALSE;
+ amt = sizeof (temp);
+ if (bfd_bread ((void *) temp, amt, abfd) != amt)
+ return FALSE;
+ amt = sizeof (symlength);
+ if (bfd_bread ((void *) &symlength, amt, abfd) != amt)
+ return FALSE;
+ amt = symlength;
+ sym->symbol.the_bfd = abfd;
+ sym->symbol.name = bfd_alloc (abfd, amt + 1);
+ if (!sym->symbol.name)
+ return FALSE;
+ if (bfd_bread ((void *) sym->symbol.name, amt, abfd) != amt)
+ 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) != 0)
+ return FALSE;
+
+ symcount += i_fxdhdrp->numberOfExternalReferences;
+ while (abfd->symcount < symcount)
+ {
+ if (! (*read_import_func) (abfd, sym))
+ return FALSE;
+ sym++;
+ abfd->symcount++;
+ }
+ }
+
+ return TRUE;
+}
+
+/* Note that bfd_get_symcount is guaranteed to be zero if slurping the
+ symbol table fails. */
+
+long
+nlm_canonicalize_symtab (bfd *abfd, asymbol **alocation)
+{
+ nlm_symbol_type *symbase;
+ bfd_size_type counter = 0;
+
+ if (! nlm_slurp_symbol_table (abfd))
+ return -1;
+ symbase = nlm_get_symbols (abfd);
+ while (counter < bfd_get_symcount (abfd))
+ {
+ *alocation++ = &symbase->symbol;
+ symbase++;
+ counter++;
+ }
+ *alocation = NULL;
+ return bfd_get_symcount (abfd);
+}
+
+/* Make an NLM symbol. There is nothing special to do here. */
+
+asymbol *
+nlm_make_empty_symbol (bfd *abfd)
+{
+ bfd_size_type amt = sizeof (nlm_symbol_type);
+ nlm_symbol_type *new = bfd_zalloc (abfd, amt);
+
+ if (new == NULL)
+ return NULL;
+ new->symbol.the_bfd = abfd;
+ return & new->symbol;
+}
+
+/* Get symbol information. */
+
+void
+nlm_get_symbol_info (bfd *ignore_abfd ATTRIBUTE_UNUSED,
+ asymbol *symbol,
+ symbol_info *ret)
+{
+ bfd_symbol_info (symbol, ret);
+}
+
+/* Print symbol information. */
+
+void
+nlm_print_symbol (bfd *abfd,
+ void * 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 (abfd, (void *) file, symbol);
+ fprintf (file, " %-5s", symbol->section->name);
+ if (symbol->name)
+ fprintf (file, " %s", symbol->name);
+ break;
+ }
+}
+
+/* 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 bfd_boolean
+nlm_slurp_reloc_fixups (bfd *abfd)
+{
+ bfd_boolean (*read_func) (bfd *, nlm_symbol_type *, asection **, arelent *);
+ bfd_size_type count, amt;
+ 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;
+ amt = count * sizeof (arelent);
+ rels = bfd_alloc (abfd, amt);
+ amt = count * sizeof (asection *);
+ secs = bfd_alloc (abfd, amt);
+ 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, NULL, secs, rels))
+ {
+ 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 (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))
+ 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 (bfd *abfd,
+ asection *sec,
+ arelent **relptr,
+ asymbol **symbols)
+{
+ arelent *rels;
+ asection **secs;
+ bfd_size_type count, i;
+ long ret;
+
+ /* Get the relocation fixups. */
+ rels = nlm_relocation_fixups (abfd);
+ if (rels == NULL)
+ {
+ if (! nlm_slurp_reloc_fixups (abfd))
+ 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 bfd_boolean
+nlm_compute_section_file_positions (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)
+ 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 (nlm_version_header (abfd),
+ sizeof (Nlm_Internal_Version_Header)))
+ sofar += sizeof (Nlm_External_Version_Header);
+ if (find_nonzero (nlm_extended_header (abfd),
+ sizeof (Nlm_Internal_Extended_Header)))
+ sofar += sizeof (Nlm_External_Extended_Header);
+ if (find_nonzero (nlm_copyright_header (abfd),
+ sizeof (Nlm_Internal_Copyright_Header)))
+ sofar += (sizeof (Nlm_External_Copyright_Header)
+ + nlm_copyright_header (abfd)->copyrightMessageLength + 1);
+ if (find_nonzero (nlm_custom_header (abfd),
+ sizeof (Nlm_Internal_Custom_Header)))
+ sofar += (sizeof (Nlm_External_Custom_Header)
+ + nlm_custom_header (abfd)->hdrLength);
+ if (find_nonzero (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 != NULL; sec = sec->next)
+ {
+ flagword f;
+
+ sec->size = BFD_ALIGN (sec->size, 1 << sec->alignment_power);
+
+ f = bfd_get_section_flags (abfd, sec);
+ if (f & SEC_CODE)
+ {
+ text += sec->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->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->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 != NULL; sec = sec->next)
+ {
+ flagword f;
+
+ f = bfd_get_section_flags (abfd, sec);
+
+ if (f & SEC_CODE)
+ {
+ sec->filepos = text_ptr;
+ text_ptr += sec->size;
+ }
+ else if (f & SEC_DATA)
+ {
+ sec->filepos = data_ptr;
+ data_ptr += sec->size;
+ }
+ else if (f & SEC_HAS_CONTENTS)
+ {
+ sec->filepos = other_ptr;
+ other_ptr += sec->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->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->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. */
+
+bfd_boolean
+nlm_set_section_contents (bfd *abfd,
+ asection *section,
+ const void * location,
+ file_ptr offset,
+ bfd_size_type count)
+{
+ if (! abfd->output_has_begun
+ && ! nlm_compute_section_file_positions (abfd))
+ 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)
+ {
+ bfd_boolean (*mangle_relocs_func)
+ (bfd *, asection *, const void *, 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, section->filepos + offset, SEEK_SET) != 0
+ || bfd_bwrite (location, 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 (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. */
+
+bfd_boolean
+nlm_write_object_contents (bfd *abfd)
+{
+ asection *sec;
+ bfd_boolean (*write_import_func) (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;
+ bfd_boolean (*write_prefix_func) (bfd *);
+ unsigned char *fixed_header = NULL;
+ file_ptr pos;
+ bfd_size_type amt;
+
+ fixed_header = bfd_malloc (nlm_fixed_header_size (abfd));
+ if (fixed_header == NULL)
+ goto error_return;
+
+ if (! abfd->output_has_begun
+ && ! nlm_compute_section_file_positions (abfd))
+ goto error_return;
+
+ /* Write out the variable length headers. */
+ pos = nlm_optional_prefix_size (abfd) + nlm_fixed_header_size (abfd);
+ if (bfd_seek (abfd, pos, SEEK_SET) != 0)
+ goto error_return;
+ if (! nlm_swap_variable_header_out (abfd)
+ || ! nlm_swap_auxiliary_headers_out (abfd))
+ {
+ 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 != 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))
+ 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. */
+ amt = external_reloc_count * sizeof (struct reloc_and_sec);
+ external_relocs = bfd_alloc (abfd, amt);
+ if (external_relocs == NULL)
+ goto error_return;
+ i = 0;
+ for (sec = abfd->sections; sec != 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 (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]))
+ 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 != NULL)
+ {
+ bfd_vma (*get_public_offset_func) (bfd *, asymbol *);
+ bfd_boolean (*write_export_func) (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))
+ goto error_return;
+ }
+ else
+ {
+ len = strlen (sym->name);
+ if ((bfd_bwrite (&len, (bfd_size_type) sizeof (bfd_byte), abfd)
+ != sizeof (bfd_byte))
+ || bfd_bwrite (sym->name, (bfd_size_type) len, abfd) != len)
+ goto error_return;
+
+ put_word (abfd, offset, temp);
+ if (bfd_bwrite (temp, (bfd_size_type) sizeof (temp), 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_bwrite (&type, (bfd_size_type) sizeof (bfd_byte), abfd)
+ != sizeof (bfd_byte))
+ goto error_return;
+
+ put_word (abfd, offset, temp);
+ if (bfd_bwrite (temp, (bfd_size_type) sizeof (temp), abfd)
+ != sizeof (temp))
+ goto error_return;
+
+ len = strlen (sym->name);
+ if ((bfd_bwrite (&len, (bfd_size_type) sizeof (bfd_byte), abfd)
+ != sizeof (bfd_byte))
+ || bfd_bwrite (sym->name, (bfd_size_type) len, 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, (file_ptr) 0, SEEK_SET) != 0)
+ goto error_return;
+
+ write_prefix_func = nlm_write_prefix_func (abfd);
+ if (write_prefix_func)
+ {
+ if (! (*write_prefix_func) (abfd))
+ 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_bwrite (fixed_header, nlm_fixed_header_size (abfd), 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 0000000..5a34c4f
--- /dev/null
+++ b/bfd/nlmswap.h
@@ -0,0 +1,153 @@
+/* NLM (NetWare Loadable Module) swapping routines for BFD.
+ Copyright (C) 1993-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, 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. */
+
+/* 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 (bfd *abfd,
+ void * 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 =
+ H_GET_32 (abfd, src->version);
+ dst->codeImageOffset =
+ H_GET_32 (abfd, src->codeImageOffset);
+ dst->codeImageSize =
+ H_GET_32 (abfd, src->codeImageSize);
+ dst->dataImageOffset =
+ H_GET_32 (abfd, src->dataImageOffset);
+ dst->dataImageSize =
+ H_GET_32 (abfd, src->dataImageSize);
+ dst->uninitializedDataSize =
+ H_GET_32 (abfd, src->uninitializedDataSize);
+ dst->customDataOffset =
+ H_GET_32 (abfd, src->customDataOffset);
+ dst->customDataSize =
+ H_GET_32 (abfd, src->customDataSize);
+ dst->moduleDependencyOffset =
+ H_GET_32 (abfd, src->moduleDependencyOffset);
+ dst->numberOfModuleDependencies =
+ H_GET_32 (abfd, src->numberOfModuleDependencies);
+ dst->relocationFixupOffset =
+ H_GET_32 (abfd, src->relocationFixupOffset);
+ dst->numberOfRelocationFixups =
+ H_GET_32 (abfd, src->numberOfRelocationFixups);
+ dst->externalReferencesOffset =
+ H_GET_32 (abfd, src->externalReferencesOffset);
+ dst->numberOfExternalReferences =
+ H_GET_32 (abfd, src->numberOfExternalReferences);
+ dst->publicsOffset =
+ H_GET_32 (abfd, src->publicsOffset);
+ dst->numberOfPublics =
+ H_GET_32 (abfd, src->numberOfPublics);
+ dst->debugInfoOffset =
+ H_GET_32 (abfd, src->debugInfoOffset);
+ dst->numberOfDebugRecords =
+ H_GET_32 (abfd, src->numberOfDebugRecords);
+ dst->codeStartOffset =
+ H_GET_32 (abfd, src->codeStartOffset);
+ dst->exitProcedureOffset =
+ H_GET_32 (abfd, src->exitProcedureOffset);
+ dst->checkUnloadProcedureOffset =
+ H_GET_32 (abfd, src->checkUnloadProcedureOffset);
+ dst->moduleType =
+ H_GET_32 (abfd, src->moduleType);
+ dst->flags =
+ H_GET_32 (abfd, 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 (bfd *abfd,
+ Nlm_Internal_Fixed_Header *src,
+ void * 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);
+ H_PUT_32 (abfd, src->version,
+ dst->version);
+ H_PUT_32 (abfd, src->codeImageOffset,
+ dst->codeImageOffset);
+ H_PUT_32 (abfd, src->codeImageSize,
+ dst->codeImageSize);
+ H_PUT_32 (abfd, src->dataImageOffset,
+ dst->dataImageOffset);
+ H_PUT_32 (abfd, src->dataImageSize,
+ dst->dataImageSize);
+ H_PUT_32 (abfd, src->uninitializedDataSize,
+ dst->uninitializedDataSize);
+ H_PUT_32 (abfd, src->customDataOffset,
+ dst->customDataOffset);
+ H_PUT_32 (abfd, src->customDataSize,
+ dst->customDataSize);
+ H_PUT_32 (abfd, src->moduleDependencyOffset,
+ dst->moduleDependencyOffset);
+ H_PUT_32 (abfd, src->numberOfModuleDependencies,
+ dst->numberOfModuleDependencies);
+ H_PUT_32 (abfd, src->relocationFixupOffset,
+ dst->relocationFixupOffset);
+ H_PUT_32 (abfd, src->numberOfRelocationFixups,
+ dst->numberOfRelocationFixups);
+ H_PUT_32 (abfd, src->externalReferencesOffset,
+ dst->externalReferencesOffset);
+ H_PUT_32 (abfd, src->numberOfExternalReferences,
+ dst->numberOfExternalReferences);
+ H_PUT_32 (abfd, src->publicsOffset,
+ dst->publicsOffset);
+ H_PUT_32 (abfd, src->numberOfPublics,
+ dst->numberOfPublics);
+ H_PUT_32 (abfd, src->debugInfoOffset,
+ dst->debugInfoOffset);
+ H_PUT_32 (abfd, src->numberOfDebugRecords,
+ dst->numberOfDebugRecords);
+ H_PUT_32 (abfd, src->codeStartOffset,
+ dst->codeStartOffset);
+ H_PUT_32 (abfd, src->exitProcedureOffset,
+ dst->exitProcedureOffset);
+ H_PUT_32 (abfd, src->checkUnloadProcedureOffset,
+ dst->checkUnloadProcedureOffset);
+ H_PUT_32 (abfd, src->moduleType,
+ dst->moduleType);
+ H_PUT_32 (abfd, src->flags,
+ dst->flags);
+}
diff --git a/bfd/ns32k.h b/bfd/ns32k.h
new file mode 100644
index 0000000..f6715e1
--- /dev/null
+++ b/bfd/ns32k.h
@@ -0,0 +1,30 @@
+/* Header file for ns32k routines.
+ Copyright (C) 1996-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+extern bfd_reloc_status_type _bfd_ns32k_relocate_contents (reloc_howto_type *, bfd *, bfd_vma, bfd_byte *);
+extern bfd_reloc_status_type _bfd_do_ns32k_reloc_contents (reloc_howto_type *, bfd *, bfd_vma, bfd_byte *, bfd_vma (*) (bfd_byte *, int), void (*) (bfd_vma, bfd_byte *, int));
+extern bfd_reloc_status_type _bfd_ns32k_final_link_relocate (reloc_howto_type *, bfd *, asection *, bfd_byte *, bfd_vma, bfd_vma, bfd_vma);
+extern bfd_vma _bfd_ns32k_get_displacement (bfd_byte *, int);
+extern bfd_vma _bfd_ns32k_get_immediate (bfd_byte *, int);
+extern void _bfd_ns32k_put_displacement (bfd_vma, bfd_byte *, int);
+extern void _bfd_ns32k_put_immediate (bfd_vma, bfd_byte *, int);
+extern bfd_reloc_status_type _bfd_ns32k_reloc_disp (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
+extern bfd_reloc_status_type _bfd_ns32k_reloc_imm (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
diff --git a/bfd/ns32knetbsd.c b/bfd/ns32knetbsd.c
new file mode 100644
index 0000000..4af3aea
--- /dev/null
+++ b/bfd/ns32knetbsd.c
@@ -0,0 +1,53 @@
+/* BFD back-end for NetBSD/ns32k a.out-ish binaries.
+ Copyright (C) 1990-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, 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
+
+/* Do not "beautify" the CONCAT* macro args. Traditional C will not
+ remove whitespace added here, and thus will fail to concatenate
+ the tokens. */
+#define MY(OP) CONCAT2 (ns32k_aout_pc532nbsd_,OP)
+
+#define NAME(x,y) CONCAT3 (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 ns32k_aout_bfd_reloc_type_lookup
+
+#include "sysdep.h"
+#include "bfd.h" /* To ensure following declaration is OK. */
+
+const struct reloc_howto_struct * MY_bfd_reloc_type_lookup (bfd *, bfd_reloc_code_real_type);
+
+#include "netbsd.h"
diff --git a/bfd/oasys.c b/bfd/oasys.c
new file mode 100644
index 0000000..9ff9b9e
--- /dev/null
+++ b/bfd/oasys.c
@@ -0,0 +1,1250 @@
+/* BFD back-end for oasys objects.
+ Copyright (C) 1990-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#define UNDERSCORE_HACK 1
+#include "sysdep.h"
+#include "bfd.h"
+#include "safe-ctype.h"
+#include "libbfd.h"
+#include "oasys.h"
+#include "liboasys.h"
+#include "libiberty.h"
+
+/* Read in all the section data and relocation stuff too. */
+
+static bfd_boolean
+oasys_read_record (bfd *abfd, oasys_record_union_type *record)
+{
+ bfd_size_type amt = sizeof (record->header);
+
+ if (bfd_bread ((void *) record, amt, abfd) != amt)
+ return FALSE;
+
+ amt = record->header.length - sizeof (record->header);
+ if ((long) amt <= 0)
+ return TRUE;
+ if (bfd_bread ((void *) ((char *) record + sizeof (record->header)), amt, abfd)
+ != amt)
+ return FALSE;
+ return TRUE;
+}
+
+static size_t
+oasys_string_length (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 bfd_boolean
+oasys_slurp_symbol_table (bfd *const abfd)
+{
+ oasys_record_union_type record;
+ oasys_data_type *data = OASYS_DATA (abfd);
+ bfd_boolean loop = TRUE;
+ asymbol *dest_defined;
+ asymbol *dest;
+ char *string_ptr;
+ bfd_size_type amt;
+
+ if (data->symbols != NULL)
+ return TRUE;
+
+ /* Buy enough memory for all the symbols and all the names. */
+ amt = abfd->symcount;
+ amt *= sizeof (asymbol);
+ data->symbols = bfd_alloc (abfd, amt);
+
+ amt = data->symbol_string_length;
+#ifdef UNDERSCORE_HACK
+ /* Buy 1 more char for each symbol to keep the underscore in. */
+ amt += abfd->symcount;
+#endif
+ data->strings = bfd_alloc (abfd, amt);
+
+ 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 + 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 (FALSE);
+ break;
+ }
+ dest->name = string_ptr;
+ dest->the_bfd = abfd;
+ dest->udata.p = NULL;
+ dest->value = 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 (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;
+
+static long
+oasys_canonicalize_symtab (bfd *abfd, asymbol **location)
+{
+ asymbol *symbase;
+ unsigned int counter;
+
+ if (! oasys_slurp_symbol_table (abfd))
+ 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 (bfd *abfd)
+{
+ oasys_archive_header_type header;
+ oasys_extarchive_header_type header_ext;
+ unsigned int i;
+ file_ptr filepos;
+ bfd_size_type amt;
+
+ amt = sizeof (header_ext);
+ if (bfd_seek (abfd, (file_ptr) 0, 0) != 0
+ || bfd_bread ((void *) &header_ext, amt, abfd) != amt)
+ {
+ if (bfd_get_error () != bfd_error_system_call)
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+
+ header.version = H_GET_32 (abfd, header_ext.version);
+ header.mod_count = H_GET_32 (abfd, header_ext.mod_count);
+ header.mod_tbl_offset = H_GET_32 (abfd, header_ext.mod_tbl_offset);
+ header.sym_tbl_size = H_GET_32 (abfd, header_ext.sym_tbl_size);
+ header.sym_count = H_GET_32 (abfd, header_ext.sym_count);
+ header.sym_tbl_offset = H_GET_32 (abfd, header_ext.sym_tbl_offset);
+ header.xref_count = H_GET_32 (abfd, header_ext.xref_count);
+ header.xref_lst_offset = 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 reasonableness 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 NULL;
+
+ /* That all worked, let's buy the space for the header and read in
+ the headers. */
+ {
+ oasys_ar_data_type *ar;
+ oasys_module_info_type *module;
+ oasys_module_table_type record;
+
+ amt = sizeof (oasys_ar_data_type);
+ ar = bfd_alloc (abfd, amt);
+
+ amt = header.mod_count;
+ amt *= sizeof (oasys_module_info_type);
+ module = bfd_alloc (abfd, amt);
+
+ 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. */
+ {
+ oasys_extmodule_table_type_b_type record_ext;
+
+ amt = sizeof (record_ext);
+ if (bfd_bread ((void *) &record_ext, amt, abfd) != amt)
+ return NULL;
+
+ record.mod_size = H_GET_32 (abfd, record_ext.mod_size);
+ record.file_offset = H_GET_32 (abfd, record_ext.file_offset);
+
+ record.dep_count = H_GET_32 (abfd, record_ext.dep_count);
+ record.depee_count = H_GET_32 (abfd, record_ext.depee_count);
+ record.sect_count = H_GET_32 (abfd, record_ext.sect_count);
+ record.module_name_size = H_GET_32 (abfd,
+ record_ext.mod_name_length);
+
+ amt = record.module_name_size;
+ module[i].name = bfd_alloc (abfd, amt + 1);
+ if (!module[i].name)
+ return NULL;
+ if (bfd_bread ((void *) module[i].name, amt, abfd) != amt)
+ 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 bfd_boolean
+oasys_mkobject (bfd *abfd)
+{
+ bfd_size_type amt = sizeof (oasys_data_type);
+
+ abfd->tdata.oasys_obj_data = bfd_alloc (abfd, amt);
+
+ return abfd->tdata.oasys_obj_data != NULL;
+}
+
+/* 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 bfd_boolean
+oasys_slurp_section_data (bfd *const abfd)
+{
+ oasys_record_union_type record;
+ oasys_data_type *data = OASYS_DATA (abfd);
+ bfd_boolean loop = TRUE;
+ oasys_per_section_type *per;
+ asection *s;
+ bfd_size_type amt;
+
+ /* See if the data has been slurped already. */
+ for (s = abfd->sections; s != NULL; s = s->next)
+ {
+ per = oasys_per_section (s);
+ if (per->initialized)
+ 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)
+ {
+ arelent **relpp;
+
+ per->data = bfd_zalloc (abfd, section->size);
+ if (!per->data)
+ return FALSE;
+ relpp = &section->relocation;
+ per->reloc_tail_ptr = (oasys_reloc_type **) relpp;
+ per->had_vma = FALSE;
+ per->initialized = TRUE;
+ section->reloc_count = 0;
+ section->flags = SEC_ALLOC;
+ }
+
+ dst_offset = H_GET_32 (abfd, record.data.addr);
+ if (! per->had_vma)
+ {
+ /* 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;
+
+ amt = sizeof (oasys_reloc_type);
+ r = bfd_alloc (abfd, amt);
+ if (!r)
+ return FALSE;
+ *(per->reloc_tail_ptr) = r;
+ per->reloc_tail_ptr = &r->next;
+ r->next = NULL;
+ /* Reference to undefined symbol. */
+ src++;
+ /* There is no symbol. */
+ r->symbol = 0;
+ /* Work out the howto. */
+ abort ();
+ r->relent.address = dst_ptr - dst_base_ptr;
+ r->relent.howto = &howto_table[reloc >> 6];
+ r->relent.sym_ptr_ptr = 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)
+ r->relent.addend -= dst_ptr - dst_base_ptr;
+ }
+ break;
+
+ case RELOCATION_TYPE_UND:
+ {
+ oasys_reloc_type *r;
+
+ amt = sizeof (oasys_reloc_type);
+ r = bfd_alloc (abfd, amt);
+ if (!r)
+ return FALSE;
+ *(per->reloc_tail_ptr) = r;
+ per->reloc_tail_ptr = &r->next;
+ r->next = NULL;
+ /* Reference to undefined symbol. */
+ src++;
+ /* Get symbol number. */
+ r->symbol = (src[0] << 8) | src[1];
+ /* Work out the howto. */
+ abort ();
+
+ r->relent.addend = 0;
+ r->relent.address = dst_ptr - dst_base_ptr;
+ r->relent.howto = &howto_table[reloc >> 6];
+ r->relent.sym_ptr_ptr = 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)
+ 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;
+
+}
+
+#define MAX_SECS 16
+
+static const bfd_target *
+oasys_object_p (bfd *abfd)
+{
+ oasys_data_type *oasys;
+ oasys_data_type *save = OASYS_DATA (abfd);
+ bfd_boolean loop = TRUE;
+ bfd_boolean had_usefull = FALSE;
+
+ abfd->tdata.oasys_obj_data = 0;
+ oasys_mkobject (abfd);
+ oasys = OASYS_DATA (abfd);
+ memset ((void *) 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, (bfd_size_type) 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->size = H_GET_32 (abfd, record.section.value);
+ s->vma = 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)
+ goto fail;
+ loop = FALSE;
+ break;
+ default:
+ goto fail;
+ }
+ }
+ oasys->symbols = 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 NULL;
+}
+
+
+static void
+oasys_get_symbol_info (bfd *ignore_abfd ATTRIBUTE_UNUSED,
+ 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 (bfd *abfd, void * 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 == NULL ?
+ (const char *) "*abs" : symbol->section->name;
+
+ bfd_print_symbol_vandf (abfd, (void *) file, symbol);
+
+ fprintf (file, " %-5s %s",
+ section_name,
+ symbol->name);
+ }
+ break;
+ }
+}
+
+static bfd_boolean
+oasys_new_section_hook (bfd *abfd, asection *newsect)
+{
+ if (!newsect->used_by_bfd)
+ {
+ newsect->used_by_bfd
+ = bfd_alloc (abfd, (bfd_size_type) sizeof (oasys_per_section_type));
+ if (!newsect->used_by_bfd)
+ return FALSE;
+ }
+ oasys_per_section (newsect)->data = 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 _bfd_generic_new_section_hook (abfd, newsect);
+}
+
+
+static long
+oasys_get_reloc_upper_bound (bfd *abfd, sec_ptr asect)
+{
+ if (! oasys_slurp_section_data (abfd))
+ return -1;
+ return (asect->reloc_count + 1) * sizeof (arelent *);
+}
+
+static bfd_boolean
+oasys_get_section_contents (bfd *abfd,
+ sec_ptr section,
+ void * location,
+ file_ptr offset,
+ bfd_size_type count)
+{
+ oasys_per_section_type *p = oasys_per_section (section);
+
+ oasys_slurp_section_data (abfd);
+
+ if (! p->initialized)
+ (void) memset (location, 0, (size_t) count);
+ else
+ (void) memcpy (location, (void *) (p->data + offset), (size_t) count);
+
+ return TRUE;
+}
+
+static long
+oasys_canonicalize_reloc (bfd *ignore_abfd ATTRIBUTE_UNUSED,
+ sec_ptr section,
+ arelent **relptr,
+ asymbol **symbols ATTRIBUTE_UNUSED)
+{
+ unsigned int reloc_count = 0;
+ oasys_reloc_type *src = (oasys_reloc_type *) (section->relocation);
+
+ if (src != NULL)
+ abort ();
+
+ *relptr = NULL;
+ return section->reloc_count = reloc_count;
+}
+
+
+/* Writing. */
+
+/* Calculate the checksum and write one record. */
+
+static bfd_boolean
+oasys_write_record (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_bwrite ((void *) record, (bfd_size_type) size, abfd) != size)
+ return FALSE;
+ return TRUE;
+}
+
+
+/* Write out all the symbols. */
+
+static bfd_boolean
+oasys_write_syms (bfd *abfd)
+{
+ unsigned int count;
+ asymbol **generic = bfd_get_outsymbols (abfd);
+ unsigned int sym_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;
+ H_PUT_16 (abfd, sym_index, symbol.refno);
+ sym_index++;
+ }
+ else if (bfd_is_abs_section (g->section))
+ {
+ symbol.relb = RELOCATION_TYPE_ABS;
+ H_PUT_16 (abfd, 0, symbol.refno);
+ }
+ else if (bfd_is_und_section (g->section))
+ {
+ symbol.relb = RELOCATION_TYPE_UND;
+ H_PUT_16 (abfd, sym_index, symbol.refno);
+ /* Overload the value field with the output sym_index number */
+ sym_index++;
+ }
+ else if (g->flags & BSF_DEBUGGING)
+ /* Throw it away. */
+ continue;
+ else
+ {
+ if (g->section == 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;
+
+ H_PUT_16 (abfd, 0, symbol.refno);
+ }
+
+#ifdef UNDERSCORE_HACK
+ if (src[l] == '_')
+ dst[l++] = '.';
+#endif
+ while (src[l])
+ {
+ dst[l] = src[l];
+ l++;
+ }
+
+ 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 = sym_index - 1;
+ }
+
+ return TRUE;
+}
+
+/* Write a section header for each section. */
+
+static bfd_boolean
+oasys_write_sections (bfd *abfd)
+{
+ asection *s;
+ static oasys_section_record_type out;
+
+ for (s = abfd->sections; s != NULL; s = s->next)
+ {
+ if (!ISDIGIT (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;
+ H_PUT_32 (abfd, s->size, out.value);
+ 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 bfd_boolean
+oasys_write_header (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);
+ else if (length < (size_t) sizeof (r.module_name))
+ (void) memset (r.module_name + length, ' ',
+ sizeof (r.module_name) - length);
+
+ (void) memcpy (r.module_name, abfd->filename, length);
+
+ r.version_number = OASYS_VERSION_NUMBER;
+ r.rev_number = OASYS_REV_NUMBER;
+
+ return oasys_write_record (abfd, oasys_record_is_header_enum,
+ (oasys_record_union_type *) & r,
+ offsetof (oasys_header_record_type,
+ description[0]));
+}
+
+static bfd_boolean
+oasys_write_end (bfd *abfd)
+{
+ oasys_end_record_type end;
+ unsigned char null = 0;
+
+ end.relb = RELOCATION_TYPE_ABS;
+ H_PUT_32 (abfd, abfd->start_address, end.entry);
+ 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;
+
+ return bfd_bwrite ((void *) &null, (bfd_size_type) 1, abfd) == 1;
+}
+
+static int
+comp (const void * ap, const void * bp)
+{
+ arelent *a = *((arelent **) ap);
+ arelent *b = *((arelent **) bp);
+
+ return a->address - b->address;
+}
+
+static bfd_boolean
+oasys_write_data (bfd *abfd)
+{
+ asection *s;
+
+ for (s = abfd->sections; s != 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->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;
+
+ 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->size && dst <=
+ & processed_data.data[sizeof (processed_data.data) - 8])
+ {
+ if (relocs_to_go != 0)
+ {
+ arelent *r = *p;
+
+ /* There is a relocation, is it for this byte ? */
+ if (r->address == current_byte_index)
+ abort ();
+ }
+
+ /* If this is coming from an unloadable section then copy
+ zeros. */
+ if (raw_data == NULL)
+ *dst++ = 0;
+ else
+ *dst++ = *raw_data++;
+
+ if (++i >= 8)
+ {
+ i = 0;
+ mod = dst++;
+ *mod = 0;
+ }
+ current_byte_index++;
+ }
+
+ /* 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),
+ (size_t) (dst - (bfd_byte *) &processed_data))))
+ return FALSE;
+ }
+ }
+ }
+
+ return TRUE;
+}
+
+static bfd_boolean
+oasys_write_object_contents (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;
+}
+
+/* Set section contents is complicated with OASYS since the format is
+ not a byte image, but a record stream. */
+
+static bfd_boolean
+oasys_set_section_contents (bfd *abfd,
+ sec_ptr section,
+ const void * location,
+ file_ptr offset,
+ bfd_size_type count)
+{
+ if (count != 0)
+ {
+ if (oasys_per_section (section)->data == NULL)
+ {
+ oasys_per_section (section)->data = bfd_alloc (abfd, section->size);
+ if (!oasys_per_section (section)->data)
+ return FALSE;
+ }
+ (void) memcpy ((void *) (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 (bfd *abfd)
+{
+ bfd_size_type amt = sizeof (oasys_symbol_type);
+ oasys_symbol_type *new_symbol_type = bfd_zalloc (abfd, amt);
+
+ if (!new_symbol_type)
+ return NULL;
+ new_symbol_type->symbol.the_bfd = abfd;
+ return &new_symbol_type->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 (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 == 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 == NULL)
+ {
+ p->abfd = _bfd_create_empty_archive_element_shell (arch);
+ p->abfd->origin = p->pos;
+ p->abfd->filename = xstrdup (p->name);
+
+ /* Fixup a pointer to this element for the member. */
+ p->abfd->arelt_data = (void *) p;
+ }
+ return p->abfd;
+ }
+
+ bfd_set_error (bfd_error_no_more_archived_files);
+ return NULL;
+}
+
+#define oasys_find_nearest_line _bfd_nosymbols_find_nearest_line
+#define oasys_find_line _bfd_nosymbols_find_line
+#define oasys_find_inliner_info _bfd_nosymbols_find_inliner_info
+
+static int
+oasys_generic_stat_arch_elt (bfd *abfd, struct stat *buf)
+{
+ oasys_module_info_type *mod = (oasys_module_info_type *) abfd->arelt_data;
+
+ if (mod == NULL)
+ {
+ bfd_set_error (bfd_error_invalid_operation);
+ return -1;
+ }
+
+ buf->st_size = mod->size;
+ buf->st_mode = 0666;
+ return 0;
+}
+
+static int
+oasys_sizeof_headers (bfd *abfd ATTRIBUTE_UNUSED,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED)
+{
+ 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 ((bfd_boolean (*) (bfd *, char **, bfd_size_type *, const char **)) bfd_true)
+#define oasys_truncate_arname bfd_dont_truncate_arname
+#define oasys_write_armap ((bfd_boolean (*) (bfd *, unsigned int, struct orl *, unsigned int, int)) bfd_true)
+#define oasys_read_ar_hdr bfd_nullvoidptr
+#define oasys_write_ar_hdr ((bfd_boolean (*) (bfd *, bfd *)) bfd_false)
+#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_bfd_is_target_special_symbol ((bfd_boolean (*) (bfd *, asymbol *)) bfd_false)
+#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_bfd_reloc_name_lookup _bfd_norelocs_bfd_reloc_name_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_lookup_section_flags bfd_generic_lookup_section_flags
+#define oasys_bfd_merge_sections bfd_generic_merge_sections
+#define oasys_bfd_is_group_section bfd_generic_is_group_section
+#define oasys_bfd_discard_group bfd_generic_discard_group
+#define oasys_section_already_linked _bfd_generic_section_already_linked
+#define oasys_bfd_define_common_symbol bfd_generic_define_common_symbol
+#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_link_just_syms _bfd_generic_link_just_syms
+#define oasys_bfd_copy_link_hash_symbol_type \
+ _bfd_generic_copy_link_hash_symbol_type
+#define oasys_bfd_final_link _bfd_generic_final_link
+#define oasys_bfd_link_split_section _bfd_generic_link_split_section
+
+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. */
+ 0, /* match priority. */
+ 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, /* Headers. */
+
+ {_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),
+
+ NULL,
+
+ NULL
+};
diff --git a/bfd/opncls.c b/bfd/opncls.c
new file mode 100644
index 0000000..75af627
--- /dev/null
+++ b/bfd/opncls.c
@@ -0,0 +1,1691 @@
+/* opncls.c -- open and close a BFD.
+ Copyright (C) 1990-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "objalloc.h"
+#include "libbfd.h"
+#include "libiberty.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
+
+/* Counters used to initialize the bfd identifier. */
+
+static unsigned int bfd_id_counter = 0;
+static unsigned int bfd_reserved_id_counter = 0;
+
+/*
+CODE_FRAGMENT
+.{* Set to N to open the next N BFDs using an alternate id space. *}
+.extern unsigned int bfd_use_reserved_id;
+*/
+unsigned int bfd_use_reserved_id = 0;
+
+/* fdopen is a loser -- we should use stdio exclusively. Unfortunately
+ if we do that we can't use fcntl. */
+
+/* Return a new BFD. All BFD's are allocated through this routine. */
+
+bfd *
+_bfd_new_bfd (void)
+{
+ bfd *nbfd;
+
+ nbfd = (bfd *) bfd_zmalloc (sizeof (bfd));
+ if (nbfd == NULL)
+ return NULL;
+
+ if (bfd_use_reserved_id)
+ {
+ nbfd->id = --bfd_reserved_id_counter;
+ --bfd_use_reserved_id;
+ }
+ else
+ nbfd->id = bfd_id_counter++;
+
+ nbfd->memory = objalloc_create ();
+ if (nbfd->memory == NULL)
+ {
+ bfd_set_error (bfd_error_no_memory);
+ free (nbfd);
+ return NULL;
+ }
+
+ nbfd->arch_info = &bfd_default_arch_struct;
+
+ if (!bfd_hash_table_init_n (& nbfd->section_htab, bfd_section_hash_newfunc,
+ sizeof (struct section_hash_entry), 13))
+ {
+ free (nbfd);
+ return NULL;
+ }
+
+ return nbfd;
+}
+
+static const struct bfd_iovec opncls_iovec;
+
+/* Allocate a new BFD as a member of archive OBFD. */
+
+bfd *
+_bfd_new_bfd_contained_in (bfd *obfd)
+{
+ bfd *nbfd;
+
+ nbfd = _bfd_new_bfd ();
+ if (nbfd == NULL)
+ return NULL;
+ nbfd->xvec = obfd->xvec;
+ nbfd->iovec = obfd->iovec;
+ if (obfd->iovec == &opncls_iovec)
+ nbfd->iostream = obfd->iostream;
+ nbfd->my_archive = obfd;
+ nbfd->direction = read_direction;
+ nbfd->target_defaulted = obfd->target_defaulted;
+ return nbfd;
+}
+
+/* Delete a BFD. */
+
+static void
+_bfd_delete_bfd (bfd *abfd)
+{
+ if (abfd->memory)
+ {
+ bfd_hash_table_free (&abfd->section_htab);
+ objalloc_free ((struct objalloc *) abfd->memory);
+ }
+
+ if (abfd->filename)
+ free ((char *) abfd->filename);
+ free (abfd->arelt_data);
+ free (abfd);
+}
+
+/* Free objalloc memory. */
+
+bfd_boolean
+_bfd_free_cached_info (bfd *abfd)
+{
+ if (abfd->memory)
+ {
+ bfd_hash_table_free (&abfd->section_htab);
+ objalloc_free ((struct objalloc *) abfd->memory);
+
+ abfd->sections = NULL;
+ abfd->section_last = NULL;
+ abfd->outsymbols = NULL;
+ abfd->tdata.any = NULL;
+ abfd->usrdata = NULL;
+ abfd->memory = NULL;
+ }
+
+ return TRUE;
+}
+
+/*
+SECTION
+ Opening and closing BFDs
+
+SUBSECTION
+ Functions for opening and closing
+*/
+
+/*
+FUNCTION
+ bfd_fopen
+
+SYNOPSIS
+ bfd *bfd_fopen (const char *filename, const char *target,
+ const char *mode, int fd);
+
+DESCRIPTION
+ Open the file @var{filename} with the target @var{target}.
+ Return a pointer to the created BFD. If @var{fd} is not -1,
+ then <<fdopen>> is used to open the file; otherwise, <<fopen>>
+ is used. @var{mode} is passed directly to <<fopen>> or
+ <<fdopen>>.
+
+ Calls <<bfd_find_target>>, so @var{target} is interpreted as by
+ that function.
+
+ The new BFD is marked as cacheable iff @var{fd} is -1.
+
+ If <<NULL>> is returned then an error has occured. Possible errors
+ are <<bfd_error_no_memory>>, <<bfd_error_invalid_target>> or
+ <<system_call>> error.
+
+ On error, @var{fd} is always closed.
+
+ A copy of the @var{filename} argument is stored in the newly created
+ BFD. It can be accessed via the bfd_get_filename() macro.
+*/
+
+bfd *
+bfd_fopen (const char *filename, const char *target, const char *mode, int fd)
+{
+ bfd *nbfd;
+ const bfd_target *target_vec;
+
+ nbfd = _bfd_new_bfd ();
+ if (nbfd == NULL)
+ {
+ if (fd != -1)
+ close (fd);
+ return NULL;
+ }
+
+ target_vec = bfd_find_target (target, nbfd);
+ if (target_vec == NULL)
+ {
+ if (fd != -1)
+ close (fd);
+ _bfd_delete_bfd (nbfd);
+ return NULL;
+ }
+
+#ifdef HAVE_FDOPEN
+ if (fd != -1)
+ nbfd->iostream = fdopen (fd, mode);
+ else
+#endif
+ nbfd->iostream = real_fopen (filename, mode);
+ if (nbfd->iostream == NULL)
+ {
+ bfd_set_error (bfd_error_system_call);
+ _bfd_delete_bfd (nbfd);
+ return NULL;
+ }
+
+ /* OK, put everything where it belongs. */
+
+ /* PR 11983: Do not cache the original filename, but
+ rather make a copy - the original might go away. */
+ nbfd->filename = xstrdup (filename);
+
+ /* Figure out whether the user is opening the file for reading,
+ writing, or both, by looking at the MODE argument. */
+ if ((mode[0] == 'r' || mode[0] == 'w' || mode[0] == 'a')
+ && mode[1] == '+')
+ nbfd->direction = both_direction;
+ else if (mode[0] == 'r')
+ nbfd->direction = read_direction;
+ else
+ nbfd->direction = write_direction;
+
+ if (! bfd_cache_init (nbfd))
+ {
+ _bfd_delete_bfd (nbfd);
+ return NULL;
+ }
+ nbfd->opened_once = TRUE;
+
+ /* If we opened the file by name, mark it cacheable; we can close it
+ and reopen it later. However, if a file descriptor was provided,
+ then it may have been opened with special flags that make it
+ unsafe to close and reopen the file. */
+ if (fd == -1)
+ (void) bfd_set_cacheable (nbfd, TRUE);
+
+ return nbfd;
+}
+
+/*
+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.
+
+ A copy of the @var{filename} argument is stored in the newly created
+ BFD. It can be accessed via the bfd_get_filename() macro.
+*/
+
+bfd *
+bfd_openr (const char *filename, const char *target)
+{
+ return bfd_fopen (filename, target, FOPEN_RB, -1);
+}
+
+/* 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 caching; 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>>.
+
+ On error, @var{fd} is closed.
+
+ A copy of the @var{filename} argument is stored in the newly created
+ BFD. It can be accessed via the bfd_get_filename() macro.
+*/
+
+bfd *
+bfd_fdopenr (const char *filename, const char *target, int fd)
+{
+ const char *mode;
+#if defined(HAVE_FCNTL) && defined(F_GETFL)
+ int fdflags;
+#endif
+
+#if ! defined(HAVE_FCNTL) || ! defined(F_GETFL)
+ mode = FOPEN_RUB; /* Assume full access. */
+#else
+ fdflags = fcntl (fd, F_GETFL, NULL);
+ if (fdflags == -1)
+ {
+ int save = errno;
+
+ close (fd);
+ errno = save;
+ bfd_set_error (bfd_error_system_call);
+ return NULL;
+ }
+
+ /* (O_ACCMODE) parens are to avoid Ultrix header file bug. */
+ switch (fdflags & (O_ACCMODE))
+ {
+ case O_RDONLY: mode = FOPEN_RB; break;
+ case O_WRONLY: mode = FOPEN_RUB; break;
+ case O_RDWR: mode = FOPEN_RUB; break;
+ default: abort ();
+ }
+#endif
+
+ return bfd_fopen (filename, target, mode, fd);
+}
+
+/*
+FUNCTION
+ bfd_openstreamr
+
+SYNOPSIS
+ bfd *bfd_openstreamr (const char * filename, const char * target, void * stream);
+
+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.
+
+ A copy of the @var{filename} argument is stored in the newly created
+ BFD. It can be accessed via the bfd_get_filename() macro.
+*/
+
+bfd *
+bfd_openstreamr (const char *filename, const char *target, void *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_delete_bfd (nbfd);
+ return NULL;
+ }
+
+ nbfd->iostream = stream;
+ /* PR 11983: Do not cache the original filename, but
+ rather make a copy - the original might go away. */
+ nbfd->filename = xstrdup (filename);
+ nbfd->direction = read_direction;
+
+ if (! bfd_cache_init (nbfd))
+ {
+ _bfd_delete_bfd (nbfd);
+ return NULL;
+ }
+
+ return nbfd;
+}
+
+/*
+FUNCTION
+ bfd_openr_iovec
+
+SYNOPSIS
+ bfd *bfd_openr_iovec (const char *filename, const char *target,
+ void *(*open_func) (struct bfd *nbfd,
+ void *open_closure),
+ void *open_closure,
+ file_ptr (*pread_func) (struct bfd *nbfd,
+ void *stream,
+ void *buf,
+ file_ptr nbytes,
+ file_ptr offset),
+ int (*close_func) (struct bfd *nbfd,
+ void *stream),
+ int (*stat_func) (struct bfd *abfd,
+ void *stream,
+ struct stat *sb));
+
+DESCRIPTION
+
+ Create and return a BFD backed by a read-only @var{stream}.
+ The @var{stream} is created using @var{open_func}, accessed using
+ @var{pread_func} and destroyed using @var{close_func}.
+
+ Calls <<bfd_find_target>>, so @var{target} is interpreted as by
+ that function.
+
+ Calls @var{open_func} (which can call <<bfd_zalloc>> and
+ <<bfd_get_filename>>) to obtain the read-only stream backing
+ the BFD. @var{open_func} either succeeds returning the
+ non-<<NULL>> @var{stream}, or fails returning <<NULL>>
+ (setting <<bfd_error>>).
+
+ Calls @var{pread_func} to request @var{nbytes} of data from
+ @var{stream} starting at @var{offset} (e.g., via a call to
+ <<bfd_read>>). @var{pread_func} either succeeds returning the
+ number of bytes read (which can be less than @var{nbytes} when
+ end-of-file), or fails returning -1 (setting <<bfd_error>>).
+
+ Calls @var{close_func} when the BFD is later closed using
+ <<bfd_close>>. @var{close_func} either succeeds returning 0, or
+ fails returning -1 (setting <<bfd_error>>).
+
+ Calls @var{stat_func} to fill in a stat structure for bfd_stat,
+ bfd_get_size, and bfd_get_mtime calls. @var{stat_func} returns 0
+ on success, or returns -1 on failure (setting <<bfd_error>>).
+
+ If <<bfd_openr_iovec>> returns <<NULL>> then an error has
+ occurred. Possible errors are <<bfd_error_no_memory>>,
+ <<bfd_error_invalid_target>> and <<bfd_error_system_call>>.
+
+ A copy of the @var{filename} argument is stored in the newly created
+ BFD. It can be accessed via the bfd_get_filename() macro.
+*/
+
+struct opncls
+{
+ void *stream;
+ file_ptr (*pread) (struct bfd *abfd, void *stream, void *buf,
+ file_ptr nbytes, file_ptr offset);
+ int (*close) (struct bfd *abfd, void *stream);
+ int (*stat) (struct bfd *abfd, void *stream, struct stat *sb);
+ file_ptr where;
+};
+
+static file_ptr
+opncls_btell (struct bfd *abfd)
+{
+ struct opncls *vec = (struct opncls *) abfd->iostream;
+ return vec->where;
+}
+
+static int
+opncls_bseek (struct bfd *abfd, file_ptr offset, int whence)
+{
+ struct opncls *vec = (struct opncls *) abfd->iostream;
+ switch (whence)
+ {
+ case SEEK_SET: vec->where = offset; break;
+ case SEEK_CUR: vec->where += offset; break;
+ case SEEK_END: return -1;
+ }
+ return 0;
+}
+
+static file_ptr
+opncls_bread (struct bfd *abfd, void *buf, file_ptr nbytes)
+{
+ struct opncls *vec = (struct opncls *) abfd->iostream;
+ file_ptr nread = (vec->pread) (abfd, vec->stream, buf, nbytes, vec->where);
+ if (nread < 0)
+ return nread;
+ vec->where += nread;
+ return nread;
+}
+
+static file_ptr
+opncls_bwrite (struct bfd *abfd ATTRIBUTE_UNUSED,
+ const void *where ATTRIBUTE_UNUSED,
+ file_ptr nbytes ATTRIBUTE_UNUSED)
+{
+ return -1;
+}
+
+static int
+opncls_bclose (struct bfd *abfd)
+{
+ struct opncls *vec = (struct opncls *) abfd->iostream;
+ /* Since the VEC's memory is bound to the bfd deleting the bfd will
+ free it. */
+ int status = 0;
+ if (vec->close != NULL)
+ status = (vec->close) (abfd, vec->stream);
+ abfd->iostream = NULL;
+ return status;
+}
+
+static int
+opncls_bflush (struct bfd *abfd ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+static int
+opncls_bstat (struct bfd *abfd, struct stat *sb)
+{
+ struct opncls *vec = (struct opncls *) abfd->iostream;
+
+ memset (sb, 0, sizeof (*sb));
+ if (vec->stat == NULL)
+ return 0;
+
+ return (vec->stat) (abfd, vec->stream, sb);
+}
+
+static void *
+opncls_bmmap (struct bfd *abfd ATTRIBUTE_UNUSED,
+ void *addr ATTRIBUTE_UNUSED,
+ bfd_size_type len ATTRIBUTE_UNUSED,
+ int prot ATTRIBUTE_UNUSED,
+ int flags ATTRIBUTE_UNUSED,
+ file_ptr offset ATTRIBUTE_UNUSED,
+ void **map_addr ATTRIBUTE_UNUSED,
+ bfd_size_type *map_len ATTRIBUTE_UNUSED)
+{
+ return (void *) -1;
+}
+
+static const struct bfd_iovec opncls_iovec = {
+ &opncls_bread, &opncls_bwrite, &opncls_btell, &opncls_bseek,
+ &opncls_bclose, &opncls_bflush, &opncls_bstat, &opncls_bmmap
+};
+
+bfd *
+bfd_openr_iovec (const char *filename, const char *target,
+ void *(*open_p) (struct bfd *, void *),
+ void *open_closure,
+ file_ptr (*pread_p) (struct bfd *, void *, void *,
+ file_ptr, file_ptr),
+ int (*close_p) (struct bfd *, void *),
+ int (*stat_p) (struct bfd *, void *, struct stat *))
+{
+ bfd *nbfd;
+ const bfd_target *target_vec;
+ struct opncls *vec;
+ void *stream;
+
+ nbfd = _bfd_new_bfd ();
+ if (nbfd == NULL)
+ return NULL;
+
+ target_vec = bfd_find_target (target, nbfd);
+ if (target_vec == NULL)
+ {
+ _bfd_delete_bfd (nbfd);
+ return NULL;
+ }
+
+ /* PR 11983: Do not cache the original filename, but
+ rather make a copy - the original might go away. */
+ nbfd->filename = xstrdup (filename);
+ nbfd->direction = read_direction;
+
+ /* `open_p (...)' would get expanded by an the open(2) syscall macro. */
+ stream = (*open_p) (nbfd, open_closure);
+ if (stream == NULL)
+ {
+ _bfd_delete_bfd (nbfd);
+ return NULL;
+ }
+
+ vec = (struct opncls *) bfd_zalloc (nbfd, sizeof (struct opncls));
+ vec->stream = stream;
+ vec->pread = pread_p;
+ vec->close = close_p;
+ vec->stat = stat_p;
+
+ nbfd->iovec = &opncls_iovec;
+ nbfd->iostream = vec;
+
+ 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>>.
+
+ A copy of the @var{filename} argument is stored in the newly created
+ BFD. It can be accessed via the bfd_get_filename() macro.
+*/
+
+bfd *
+bfd_openw (const char *filename, const char *target)
+{
+ bfd *nbfd;
+ const bfd_target *target_vec;
+
+ /* 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)
+ {
+ _bfd_delete_bfd (nbfd);
+ return NULL;
+ }
+
+ /* PR 11983: Do not cache the original filename, but
+ rather make a copy - the original might go away. */
+ nbfd->filename = xstrdup (filename);
+ nbfd->direction = write_direction;
+
+ if (bfd_open_file (nbfd) == NULL)
+ {
+ /* File not writeable, etc. */
+ bfd_set_error (bfd_error_system_call);
+ _bfd_delete_bfd (nbfd);
+ return NULL;
+ }
+
+ return nbfd;
+}
+
+static inline void
+_maybe_make_executable (bfd * abfd)
+{
+ /* If the file was open for writing and is now executable,
+ make it so. */
+ if (abfd->direction == write_direction
+ && (abfd->flags & (EXEC_P | DYNAMIC)) != 0)
+ {
+ struct stat buf;
+
+ if (stat (abfd->filename, &buf) == 0
+ /* Do not attempt to change non-regular files. This is
+ here especially for configure scripts and kernel builds
+ which run tests with "ld [...] -o /dev/null". */
+ && S_ISREG(buf.st_mode))
+ {
+ unsigned int mask = umask (0);
+
+ umask (mask);
+ chmod (abfd->filename,
+ (0777
+ & (buf.st_mode | ((S_IXUSR | S_IXGRP | S_IXOTH) &~ mask))));
+ }
+ }
+}
+
+/*
+
+FUNCTION
+ bfd_close
+
+SYNOPSIS
+ bfd_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>>.
+*/
+
+
+bfd_boolean
+bfd_close (bfd *abfd)
+{
+ bfd_boolean ret;
+
+ if (bfd_write_p (abfd))
+ {
+ if (! BFD_SEND_FMT (abfd, _bfd_write_contents, (abfd)))
+ return FALSE;
+ }
+
+ if (! BFD_SEND (abfd, _close_and_cleanup, (abfd)))
+ return FALSE;
+
+ ret = abfd->iovec->bclose (abfd) == 0;
+
+ if (ret)
+ _maybe_make_executable (abfd);
+
+ _bfd_delete_bfd (abfd);
+
+ return ret;
+}
+
+/*
+FUNCTION
+ bfd_close_all_done
+
+SYNOPSIS
+ bfd_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>>.
+*/
+
+bfd_boolean
+bfd_close_all_done (bfd *abfd)
+{
+ bfd_boolean ret;
+
+ ret = bfd_cache_close (abfd);
+
+ if (ret)
+ _maybe_make_executable (abfd);
+
+ _bfd_delete_bfd (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{templ}. The format is always set to <<bfd_object>>.
+
+ A copy of the @var{filename} argument is stored in the newly created
+ BFD. It can be accessed via the bfd_get_filename() macro.
+*/
+
+bfd *
+bfd_create (const char *filename, bfd *templ)
+{
+ bfd *nbfd;
+
+ nbfd = _bfd_new_bfd ();
+ if (nbfd == NULL)
+ return NULL;
+ /* PR 11983: Do not cache the original filename, but
+ rather make a copy - the original might go away. */
+ nbfd->filename = xstrdup (filename);
+ if (templ)
+ nbfd->xvec = templ->xvec;
+ nbfd->direction = no_direction;
+ bfd_set_format (nbfd, bfd_object);
+
+ return nbfd;
+}
+
+/*
+FUNCTION
+ bfd_make_writable
+
+SYNOPSIS
+ bfd_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>>.
+*/
+
+bfd_boolean
+bfd_make_writable (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));
+ if (bim == NULL)
+ return FALSE; /* bfd_error already set. */
+ abfd->iostream = bim;
+ /* bfd_bwrite will grow these as needed. */
+ bim->size = 0;
+ bim->buffer = 0;
+
+ abfd->flags |= BFD_IN_MEMORY;
+ abfd->iovec = &_bfd_memory_iovec;
+ abfd->origin = 0;
+ abfd->direction = write_direction;
+ abfd->where = 0;
+
+ return TRUE;
+}
+
+/*
+FUNCTION
+ bfd_make_readable
+
+SYNOPSIS
+ bfd_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>>. */
+
+bfd_boolean
+bfd_make_readable (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->format = bfd_unknown;
+ abfd->my_archive = NULL;
+ abfd->origin = 0;
+ abfd->opened_once = FALSE;
+ abfd->output_has_begun = FALSE;
+ abfd->section_count = 0;
+ abfd->usrdata = 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_section_list_clear (abfd);
+ bfd_check_format (abfd, bfd_object);
+
+ return TRUE;
+}
+
+/*
+FUNCTION
+ bfd_alloc
+
+SYNOPSIS
+ void *bfd_alloc (bfd *abfd, bfd_size_type wanted);
+
+DESCRIPTION
+ Allocate a block of @var{wanted} bytes of memory attached to
+ <<abfd>> and return a pointer to it.
+*/
+
+void *
+bfd_alloc (bfd *abfd, bfd_size_type size)
+{
+ void *ret;
+ unsigned long ul_size = (unsigned long) size;
+
+ if (size != ul_size
+ /* A small negative size can result in objalloc_alloc allocating just
+ 1 byte of memory, but the caller will be expecting more. So catch
+ this case here. */
+ || (size != 0 && (((ul_size + OBJALLOC_ALIGN - 1) &~ (OBJALLOC_ALIGN - 1)) == 0)))
+ {
+ bfd_set_error (bfd_error_no_memory);
+ return NULL;
+ }
+
+ ret = objalloc_alloc ((struct objalloc *) abfd->memory, ul_size);
+ if (ret == NULL)
+ bfd_set_error (bfd_error_no_memory);
+ return ret;
+}
+
+/*
+INTERNAL_FUNCTION
+ bfd_alloc2
+
+SYNOPSIS
+ void *bfd_alloc2 (bfd *abfd, bfd_size_type nmemb, bfd_size_type size);
+
+DESCRIPTION
+ Allocate a block of @var{nmemb} elements of @var{size} bytes each
+ of memory attached to <<abfd>> and return a pointer to it.
+*/
+
+void *
+bfd_alloc2 (bfd *abfd, bfd_size_type nmemb, bfd_size_type size)
+{
+ if ((nmemb | size) >= HALF_BFD_SIZE_TYPE
+ && size != 0
+ && nmemb > ~(bfd_size_type) 0 / size)
+ {
+ bfd_set_error (bfd_error_no_memory);
+ return NULL;
+ }
+
+ return bfd_alloc (abfd, size * nmemb);
+}
+
+/*
+FUNCTION
+ bfd_zalloc
+
+SYNOPSIS
+ void *bfd_zalloc (bfd *abfd, bfd_size_type wanted);
+
+DESCRIPTION
+ Allocate a block of @var{wanted} bytes of zeroed memory
+ attached to <<abfd>> and return a pointer to it.
+*/
+
+void *
+bfd_zalloc (bfd *abfd, bfd_size_type size)
+{
+ void *res;
+
+ res = bfd_alloc (abfd, size);
+ if (res)
+ memset (res, 0, (size_t) size);
+ return res;
+}
+
+/*
+INTERNAL_FUNCTION
+ bfd_zalloc2
+
+SYNOPSIS
+ void *bfd_zalloc2 (bfd *abfd, bfd_size_type nmemb, bfd_size_type size);
+
+DESCRIPTION
+ Allocate a block of @var{nmemb} elements of @var{size} bytes each
+ of zeroed memory attached to <<abfd>> and return a pointer to it.
+*/
+
+void *
+bfd_zalloc2 (bfd *abfd, bfd_size_type nmemb, bfd_size_type size)
+{
+ void *res;
+
+ if ((nmemb | size) >= HALF_BFD_SIZE_TYPE
+ && size != 0
+ && nmemb > ~(bfd_size_type) 0 / size)
+ {
+ bfd_set_error (bfd_error_no_memory);
+ return NULL;
+ }
+
+ size *= nmemb;
+
+ res = bfd_alloc (abfd, size);
+ if (res)
+ memset (res, 0, (size_t) size);
+ return res;
+}
+
+/* Free a block allocated for a BFD.
+ Note: Also frees all more recently allocated blocks! */
+
+void
+bfd_release (bfd *abfd, void *block)
+{
+ objalloc_free_block ((struct objalloc *) abfd->memory, block);
+}
+
+
+/*
+ GNU Extension: separate debug-info files
+
+ The idea here is that a special section called .gnu_debuglink might be
+ embedded in a binary file, which indicates that some *other* file
+ contains the real debugging information. This special section contains a
+ filename and CRC32 checksum, which we read and resolve to another file,
+ if it exists.
+
+ This facilitates "optional" provision of debugging information, without
+ having to provide two complete copies of every binary object (with and
+ without debug symbols). */
+
+#define GNU_DEBUGLINK ".gnu_debuglink"
+#define GNU_DEBUGALTLINK ".gnu_debugaltlink"
+
+/*
+FUNCTION
+ bfd_calc_gnu_debuglink_crc32
+
+SYNOPSIS
+ unsigned long bfd_calc_gnu_debuglink_crc32
+ (unsigned long crc, const unsigned char *buf, bfd_size_type len);
+
+DESCRIPTION
+ Computes a CRC value as used in the .gnu_debuglink section.
+ Advances the previously computed @var{crc} value by computing
+ and adding in the crc32 for @var{len} bytes of @var{buf}.
+
+RETURNS
+ Return the updated CRC32 value.
+*/
+
+unsigned long
+bfd_calc_gnu_debuglink_crc32 (unsigned long crc,
+ const unsigned char *buf,
+ bfd_size_type len)
+{
+ static const unsigned long crc32_table[256] =
+ {
+ 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419,
+ 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4,
+ 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07,
+ 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
+ 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856,
+ 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
+ 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4,
+ 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
+ 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3,
+ 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a,
+ 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599,
+ 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
+ 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190,
+ 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f,
+ 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e,
+ 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
+ 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed,
+ 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
+ 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3,
+ 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
+ 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a,
+ 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5,
+ 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010,
+ 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
+ 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17,
+ 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6,
+ 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615,
+ 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
+ 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344,
+ 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
+ 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a,
+ 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
+ 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1,
+ 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c,
+ 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef,
+ 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
+ 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe,
+ 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31,
+ 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c,
+ 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
+ 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b,
+ 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
+ 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1,
+ 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
+ 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278,
+ 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7,
+ 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66,
+ 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
+ 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605,
+ 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8,
+ 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b,
+ 0x2d02ef8d
+ };
+ const unsigned char *end;
+
+ crc = ~crc & 0xffffffff;
+ for (end = buf + len; buf < end; ++ buf)
+ crc = crc32_table[(crc ^ *buf) & 0xff] ^ (crc >> 8);
+ return ~crc & 0xffffffff;
+}
+
+
+/*
+FUNCTION
+ bfd_get_debug_link_info
+
+SYNOPSIS
+ char *bfd_get_debug_link_info (bfd *abfd, unsigned long *crc32_out);
+
+DESCRIPTION
+ Fetch the filename and CRC32 value for any separate debuginfo
+ associated with @var{abfd}. Return NULL if no such info found,
+ otherwise return filename and update @var{crc32_out}. The
+ returned filename is allocated with @code{malloc}; freeing it
+ is the responsibility of the caller.
+*/
+
+char *
+bfd_get_debug_link_info (bfd *abfd, unsigned long *crc32_out)
+{
+ asection *sect;
+ unsigned long crc32;
+ bfd_byte *contents;
+ unsigned int crc_offset;
+ char *name;
+
+ BFD_ASSERT (abfd);
+ BFD_ASSERT (crc32_out);
+
+ sect = bfd_get_section_by_name (abfd, GNU_DEBUGLINK);
+
+ if (sect == NULL)
+ return NULL;
+
+ if (!bfd_malloc_and_get_section (abfd, sect, &contents))
+ {
+ if (contents != NULL)
+ free (contents);
+ return NULL;
+ }
+
+ /* CRC value is stored after the filename, aligned up to 4 bytes. */
+ name = (char *) contents;
+ /* PR 17597: avoid reading off the end of the buffer. */
+ crc_offset = strnlen (name, bfd_get_section_size (sect)) + 1;
+ crc_offset = (crc_offset + 3) & ~3;
+ if (crc_offset >= bfd_get_section_size (sect))
+ return NULL;
+
+ crc32 = bfd_get_32 (abfd, contents + crc_offset);
+
+ *crc32_out = crc32;
+ return name;
+}
+
+/*
+FUNCTION
+ bfd_get_alt_debug_link_info
+
+SYNOPSIS
+ char *bfd_get_alt_debug_link_info (bfd * abfd,
+ bfd_size_type *buildid_len,
+ bfd_byte **buildid_out);
+
+DESCRIPTION
+ Fetch the filename and BuildID value for any alternate debuginfo
+ associated with @var{abfd}. Return NULL if no such info found,
+ otherwise return filename and update @var{buildid_len} and
+ @var{buildid_out}. The returned filename and build_id are
+ allocated with @code{malloc}; freeing them is the
+ responsibility of the caller.
+*/
+
+char *
+bfd_get_alt_debug_link_info (bfd * abfd, bfd_size_type *buildid_len,
+ bfd_byte **buildid_out)
+{
+ asection *sect;
+ bfd_byte *contents;
+ unsigned int buildid_offset;
+ char *name;
+
+ BFD_ASSERT (abfd);
+ BFD_ASSERT (buildid_len);
+ BFD_ASSERT (buildid_out);
+
+ sect = bfd_get_section_by_name (abfd, GNU_DEBUGALTLINK);
+
+ if (sect == NULL)
+ return NULL;
+
+ if (!bfd_malloc_and_get_section (abfd, sect, & contents))
+ {
+ if (contents != NULL)
+ free (contents);
+ return NULL;
+ }
+
+ /* BuildID value is stored after the filename. */
+ name = (char *) contents;
+ buildid_offset = strnlen (name, bfd_get_section_size (sect)) + 1;
+ if (buildid_offset >= bfd_get_section_size (sect))
+ return NULL;
+
+ *buildid_len = bfd_get_section_size (sect) - buildid_offset;
+ *buildid_out = bfd_malloc (*buildid_len);
+ memcpy (*buildid_out, contents + buildid_offset, *buildid_len);
+
+ return name;
+}
+
+/*
+INTERNAL_FUNCTION
+ separate_debug_file_exists
+
+SYNOPSIS
+ bfd_boolean separate_debug_file_exists
+ (char *name, unsigned long crc32);
+
+DESCRIPTION
+ Checks to see if @var{name} is a file and if its contents
+ match @var{crc32}.
+*/
+
+static bfd_boolean
+separate_debug_file_exists (const char *name, const unsigned long crc)
+{
+ static unsigned char buffer [8 * 1024];
+ unsigned long file_crc = 0;
+ FILE *f;
+ bfd_size_type count;
+
+ BFD_ASSERT (name);
+
+ f = real_fopen (name, FOPEN_RB);
+ if (f == NULL)
+ return FALSE;
+
+ while ((count = fread (buffer, 1, sizeof (buffer), f)) > 0)
+ file_crc = bfd_calc_gnu_debuglink_crc32 (file_crc, buffer, count);
+
+ fclose (f);
+
+ return crc == file_crc;
+}
+
+/*
+INTERNAL_FUNCTION
+ separate_alt_debug_file_exists
+
+SYNOPSIS
+ bfd_boolean separate_alt_debug_file_exists
+ (char *name, unsigned long crc32);
+
+DESCRIPTION
+ Checks to see if @var{name} is a file and if its BuildID
+ matches @var{buildid}.
+*/
+
+static bfd_boolean
+separate_alt_debug_file_exists (const char *name,
+ const unsigned long buildid ATTRIBUTE_UNUSED)
+{
+ FILE *f;
+
+ BFD_ASSERT (name);
+
+ f = real_fopen (name, FOPEN_RB);
+ if (f == NULL)
+ return FALSE;
+
+ /* FIXME: Add code to check buildid. */
+
+ fclose (f);
+
+ return TRUE;
+}
+
+/*
+INTERNAL_FUNCTION
+ find_separate_debug_file
+
+SYNOPSIS
+ char *find_separate_debug_file (bfd *abfd);
+
+DESCRIPTION
+ Searches @var{abfd} for a section called @var{section_name} which
+ is expected to contain a reference to a file containing separate
+ debugging information. The function scans various locations in
+ the filesystem, including the file tree rooted at
+ @var{debug_file_directory}, and returns the first matching
+ filename that it finds. If @var{check_crc} is TRUE then the
+ contents of the file must also match the CRC value contained in
+ @var{section_name}. Returns NULL if no valid file could be found.
+*/
+
+typedef char * (* get_func_type) (bfd *, unsigned long *);
+typedef bfd_boolean (* check_func_type) (const char *, const unsigned long);
+
+static char *
+find_separate_debug_file (bfd * abfd,
+ const char * debug_file_directory,
+ get_func_type get_func,
+ check_func_type check_func)
+{
+ char *base;
+ char *dir;
+ char *debugfile;
+ char *canon_dir;
+ unsigned long crc32;
+ size_t dirlen;
+ size_t canon_dirlen;
+
+ BFD_ASSERT (abfd);
+ if (debug_file_directory == NULL)
+ debug_file_directory = ".";
+
+ /* BFD may have been opened from a stream. */
+ if (abfd->filename == NULL)
+ {
+ bfd_set_error (bfd_error_invalid_operation);
+ return NULL;
+ }
+
+ base = get_func (abfd, & crc32);
+
+ if (base == NULL)
+ return NULL;
+
+ if (base[0] == '\0')
+ {
+ free (base);
+ bfd_set_error (bfd_error_no_debug_section);
+ return NULL;
+ }
+
+ for (dirlen = strlen (abfd->filename); dirlen > 0; dirlen--)
+ if (IS_DIR_SEPARATOR (abfd->filename[dirlen - 1]))
+ break;
+
+ dir = (char *) bfd_malloc (dirlen + 1);
+ if (dir == NULL)
+ {
+ free (base);
+ return NULL;
+ }
+ memcpy (dir, abfd->filename, dirlen);
+ dir[dirlen] = '\0';
+
+ /* Compute the canonical name of the bfd object with all symbolic links
+ resolved, for use in the global debugfile directory. */
+ canon_dir = lrealpath (abfd->filename);
+ for (canon_dirlen = strlen (canon_dir); canon_dirlen > 0; canon_dirlen--)
+ if (IS_DIR_SEPARATOR (canon_dir[canon_dirlen - 1]))
+ break;
+ canon_dir[canon_dirlen] = '\0';
+
+ debugfile = (char *)
+ bfd_malloc (strlen (debug_file_directory) + 1
+ + (canon_dirlen > dirlen ? canon_dirlen : dirlen)
+ + strlen (".debug/")
+ + strlen (base)
+ + 1);
+ if (debugfile == NULL)
+ goto found; /* Actually this returns NULL. */
+
+ /* First try in the same directory as the original file: */
+ strcpy (debugfile, dir);
+ strcat (debugfile, base);
+
+ if (check_func (debugfile, crc32))
+ goto found;
+
+ /* Then try in a subdirectory called .debug. */
+ strcpy (debugfile, dir);
+ strcat (debugfile, ".debug/");
+ strcat (debugfile, base);
+
+ if (check_func (debugfile, crc32))
+ goto found;
+
+ /* Then try in the global debugfile directory. */
+ strcpy (debugfile, debug_file_directory);
+ dirlen = strlen (debug_file_directory) - 1;
+ if (dirlen > 0
+ && debug_file_directory[dirlen] != '/'
+ && canon_dir[0] != '/')
+ strcat (debugfile, "/");
+ strcat (debugfile, canon_dir);
+ strcat (debugfile, base);
+
+ if (check_func (debugfile, crc32))
+ goto found;
+
+ /* Failed to find the file. */
+ free (debugfile);
+ debugfile = NULL;
+
+ found:
+ free (base);
+ free (dir);
+ free (canon_dir);
+ return debugfile;
+}
+
+
+/*
+FUNCTION
+ bfd_follow_gnu_debuglink
+
+SYNOPSIS
+ char *bfd_follow_gnu_debuglink (bfd *abfd, const char *dir);
+
+DESCRIPTION
+
+ Takes a BFD and searches it for a .gnu_debuglink section. If this
+ section is found, it examines the section for the name and checksum
+ of a '.debug' file containing auxiliary debugging information. It
+ then searches the filesystem for this .debug file in some standard
+ locations, including the directory tree rooted at @var{dir}, and if
+ found returns the full filename.
+
+ If @var{dir} is NULL, it will search a default path configured into
+ libbfd at build time. [XXX this feature is not currently
+ implemented].
+
+RETURNS
+ <<NULL>> on any errors or failure to locate the .debug file,
+ otherwise a pointer to a heap-allocated string containing the
+ filename. The caller is responsible for freeing this string.
+*/
+
+char *
+bfd_follow_gnu_debuglink (bfd *abfd, const char *dir)
+{
+ return find_separate_debug_file (abfd, dir,
+ bfd_get_debug_link_info,
+ separate_debug_file_exists);
+}
+
+/* Helper for bfd_follow_gnu_debugaltlink. It just pretends to return
+ a CRC. .gnu_debugaltlink supplies a build-id, which is different,
+ but this is ok because separate_alt_debug_file_exists ignores the
+ CRC anyway. */
+
+static char *
+get_alt_debug_link_info_shim (bfd * abfd, unsigned long *crc32_out)
+{
+ bfd_size_type len;
+ bfd_byte *buildid = NULL;
+ char *result = bfd_get_alt_debug_link_info (abfd, &len, &buildid);
+
+ *crc32_out = 0;
+ free (buildid);
+
+ return result;
+}
+
+/*
+FUNCTION
+ bfd_follow_gnu_debugaltlink
+
+SYNOPSIS
+ char *bfd_follow_gnu_debugaltlink (bfd *abfd, const char *dir);
+
+DESCRIPTION
+
+ Takes a BFD and searches it for a .gnu_debugaltlink section. If this
+ section is found, it examines the section for the name of a file
+ containing auxiliary debugging information. It then searches the
+ filesystem for this file in a set of standard locations, including
+ the directory tree rooted at @var{dir}, and if found returns the
+ full filename.
+
+ If @var{dir} is NULL, it will search a default path configured into
+ libbfd at build time. [FIXME: This feature is not currently
+ implemented].
+
+RETURNS
+ <<NULL>> on any errors or failure to locate the debug file,
+ otherwise a pointer to a heap-allocated string containing the
+ filename. The caller is responsible for freeing this string.
+*/
+
+char *
+bfd_follow_gnu_debugaltlink (bfd *abfd, const char *dir)
+{
+ return find_separate_debug_file (abfd, dir,
+ get_alt_debug_link_info_shim,
+ separate_alt_debug_file_exists);
+}
+
+/*
+FUNCTION
+ bfd_create_gnu_debuglink_section
+
+SYNOPSIS
+ struct bfd_section *bfd_create_gnu_debuglink_section
+ (bfd *abfd, const char *filename);
+
+DESCRIPTION
+
+ Takes a @var{BFD} and adds a .gnu_debuglink section to it. The section is sized
+ to be big enough to contain a link to the specified @var{filename}.
+
+RETURNS
+ A pointer to the new section is returned if all is ok. Otherwise <<NULL>> is
+ returned and bfd_error is set.
+*/
+
+asection *
+bfd_create_gnu_debuglink_section (bfd *abfd, const char *filename)
+{
+ asection *sect;
+ bfd_size_type debuglink_size;
+ flagword flags;
+
+ if (abfd == NULL || filename == NULL)
+ {
+ bfd_set_error (bfd_error_invalid_operation);
+ return NULL;
+ }
+
+ /* Strip off any path components in filename. */
+ filename = lbasename (filename);
+
+ sect = bfd_get_section_by_name (abfd, GNU_DEBUGLINK);
+ if (sect)
+ {
+ /* Section already exists. */
+ bfd_set_error (bfd_error_invalid_operation);
+ return NULL;
+ }
+
+ flags = SEC_HAS_CONTENTS | SEC_READONLY | SEC_DEBUGGING;
+ sect = bfd_make_section_with_flags (abfd, GNU_DEBUGLINK, flags);
+ if (sect == NULL)
+ return NULL;
+
+ debuglink_size = strlen (filename) + 1;
+ debuglink_size += 3;
+ debuglink_size &= ~3;
+ debuglink_size += 4;
+
+ if (! bfd_set_section_size (abfd, sect, debuglink_size))
+ /* XXX Should we delete the section from the bfd ? */
+ return NULL;
+
+ return sect;
+}
+
+
+/*
+FUNCTION
+ bfd_fill_in_gnu_debuglink_section
+
+SYNOPSIS
+ bfd_boolean bfd_fill_in_gnu_debuglink_section
+ (bfd *abfd, struct bfd_section *sect, const char *filename);
+
+DESCRIPTION
+
+ Takes a @var{BFD} and containing a .gnu_debuglink section @var{SECT}
+ and fills in the contents of the section to contain a link to the
+ specified @var{filename}. The filename should be relative to the
+ current directory.
+
+RETURNS
+ <<TRUE>> is returned if all is ok. Otherwise <<FALSE>> is returned
+ and bfd_error is set.
+*/
+
+bfd_boolean
+bfd_fill_in_gnu_debuglink_section (bfd *abfd,
+ struct bfd_section *sect,
+ const char *filename)
+{
+ bfd_size_type debuglink_size;
+ unsigned long crc32;
+ char * contents;
+ bfd_size_type crc_offset;
+ FILE * handle;
+ static unsigned char buffer[8 * 1024];
+ size_t count;
+ size_t filelen;
+
+ if (abfd == NULL || sect == NULL || filename == NULL)
+ {
+ bfd_set_error (bfd_error_invalid_operation);
+ return FALSE;
+ }
+
+ /* Make sure that we can read the file.
+ XXX - Should we attempt to locate the debug info file using the same
+ algorithm as gdb ? At the moment, since we are creating the
+ .gnu_debuglink section, we insist upon the user providing us with a
+ correct-for-section-creation-time path, but this need not conform to
+ the gdb location algorithm. */
+ handle = real_fopen (filename, FOPEN_RB);
+ if (handle == NULL)
+ {
+ bfd_set_error (bfd_error_system_call);
+ return FALSE;
+ }
+
+ crc32 = 0;
+ while ((count = fread (buffer, 1, sizeof buffer, handle)) > 0)
+ crc32 = bfd_calc_gnu_debuglink_crc32 (crc32, buffer, count);
+ fclose (handle);
+
+ /* Strip off any path components in filename,
+ now that we no longer need them. */
+ filename = lbasename (filename);
+
+ filelen = strlen (filename);
+ debuglink_size = filelen + 1;
+ debuglink_size += 3;
+ debuglink_size &= ~3;
+ debuglink_size += 4;
+
+ contents = (char *) bfd_malloc (debuglink_size);
+ if (contents == NULL)
+ {
+ /* XXX Should we delete the section from the bfd ? */
+ return FALSE;
+ }
+
+ crc_offset = debuglink_size - 4;
+ memcpy (contents, filename, filelen);
+ memset (contents + filelen, 0, crc_offset - filelen);
+
+ bfd_put_32 (abfd, crc32, contents + crc_offset);
+
+ if (! bfd_set_section_contents (abfd, sect, contents, 0, debuglink_size))
+ {
+ /* XXX Should we delete the section from the bfd ? */
+ free (contents);
+ return FALSE;
+ }
+
+ return TRUE;
+}
diff --git a/bfd/osf-core.c b/bfd/osf-core.c
new file mode 100644
index 0000000..e4e2adb
--- /dev/null
+++ b/bfd/osf-core.c
@@ -0,0 +1,225 @@
+/* BFD back-end for OSF/1 core files.
+ Copyright (C) 1993-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+
+/* This file can only be compiled on systems which use OSF/1 style
+ core files. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+
+#include <sys/user.h>
+#ifdef OSF_CORE
+#include <sys/core.h>
+#endif
+
+/* forward declarations */
+
+#define osf_core_core_file_matches_executable_p generic_core_file_matches_executable_p
+#define osf_core_core_file_pid _bfd_nocore_core_file_pid
+
+/* 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 (bfd *abfd,
+ const char *name,
+ flagword flags,
+ bfd_size_type size,
+ bfd_vma vma,
+ file_ptr filepos)
+{
+ asection *asect;
+
+ asect = bfd_make_section_anyway_with_flags (abfd, name, flags);
+ if (!asect)
+ return NULL;
+
+ asect->size = size;
+ asect->vma = vma;
+ asect->filepos = filepos;
+ asect->alignment_power = 8;
+
+ return asect;
+}
+
+static const bfd_target *
+osf_core_core_file_p (bfd *abfd)
+{
+ int val;
+ int i;
+ char *secname;
+ struct core_filehdr core_header;
+ bfd_size_type amt;
+
+ amt = sizeof core_header;
+ val = bfd_bread (& core_header, amt, abfd);
+ if (val != sizeof core_header)
+ return NULL;
+
+ if (! CONST_STRNEQ (core_header.magic, "Core"))
+ return NULL;
+
+ core_hdr (abfd) = (struct osf_core_struct *)
+ bfd_zalloc (abfd, (bfd_size_type) 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;
+
+ amt = sizeof core_scnhdr;
+ val = bfd_bread (& core_scnhdr, amt, 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))
+ goto fail;
+ }
+
+ /* OK, we believe you. You're a core file (sure, sure). */
+
+ return abfd->xvec;
+
+ fail:
+ bfd_release (abfd, core_hdr (abfd));
+ core_hdr (abfd) = NULL;
+ bfd_section_list_clear (abfd);
+ return NULL;
+}
+
+static char *
+osf_core_core_file_failing_command (bfd *abfd)
+{
+ return core_command (abfd);
+}
+
+static int
+osf_core_core_file_failing_signal (bfd *abfd)
+{
+ return core_signal (abfd);
+}
+
+/* If somebody calls any byte-swapping routines, shoot them. */
+static void
+swap_abort (void)
+{
+ abort (); /* This way doesn't require any declaration for ANSI to fuck up */
+}
+
+#define NO_GET ((bfd_vma (*) (const void *)) swap_abort)
+#define NO_PUT ((void (*) (bfd_vma, void *)) swap_abort)
+#define NO_GETS ((bfd_signed_vma (*) (const void *)) swap_abort)
+#define NO_GET64 ((bfd_uint64_t (*) (const void *)) swap_abort)
+#define NO_PUT64 ((void (*) (bfd_uint64_t, void *)) swap_abort)
+#define NO_GETS64 ((bfd_int64_t (*) (const void *)) swap_abort)
+
+const bfd_target core_osf_vec =
+ {
+ "osf-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 */
+ 0, /* match priority. */
+ NO_GET64, NO_GETS64, NO_PUT64, /* 64 bit data */
+ NO_GET, NO_GETS, NO_PUT, /* 32 bit data */
+ NO_GET, NO_GETS, NO_PUT, /* 16 bit data */
+ NO_GET64, NO_GETS64, NO_PUT64, /* 64 bit hdrs */
+ NO_GET, NO_GETS, NO_PUT, /* 32 bit hdrs */
+ NO_GET, NO_GETS, 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 (_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),
+
+ NULL,
+
+ NULL /* backend_data */
+ };
diff --git a/bfd/pc532-mach.c b/bfd/pc532-mach.c
new file mode 100644
index 0000000..c9dcc66
--- /dev/null
+++ b/bfd/pc532-mach.c
@@ -0,0 +1,108 @@
+/* BFD back-end for Mach3/532 a.out-ish binaries.
+ Copyright (C) 1990-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, 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 SEGMENT_SIZE TARGET_PAGE_SIZE
+#define DEFAULT_ARCH bfd_arch_ns32k
+
+/* Do not "beautify" the CONCAT* macro args. Traditional C will not
+ remove whitespace added here, and thus will fail to concatenate
+ the tokens. */
+#define MY(OP) CONCAT2 (ns32k_aout_pc532mach_,OP)
+
+/* Must be the same as aout-ns32k.c */
+#define NAME(x,y) CONCAT3 (ns32kaout,_32_,y)
+
+#define TARGETNAME "a.out-pc532-mach"
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libaout.h"
+#include "libbfd.h"
+#include "aout/aout64.h"
+
+#define MY_bfd_reloc_type_lookup ns32k_aout_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
+
+reloc_howto_type *MY_bfd_reloc_type_lookup
+ (bfd *abfd, bfd_reloc_code_real_type code);
+
+static bfd_boolean
+MY(write_object_contents) (bfd *abfd)
+{
+ struct external_exec exec_bytes;
+ struct internal_exec *execp = exec_hdr (abfd);
+
+ obj_reloc_entry_size (abfd) = RELOC_STD_SIZE;
+
+ 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/pdp11.c b/bfd/pdp11.c
new file mode 100644
index 0000000..593c5ca
--- /dev/null
+++ b/bfd/pdp11.c
@@ -0,0 +1,4547 @@
+/* BFD back-end for PDP-11 a.out binaries.
+ Copyright (C) 2001-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+
+/* BFD backend for PDP-11, running 2.11BSD in particular.
+
+ This file was hacked up by looking hard at the existing vaxnetbsd
+ back end and the header files in 2.11BSD.
+
+ TODO
+ * support for V7 file formats
+ * support for overlay object files (see 2.11 a.out(5))
+ * support for old and very old archives
+ (see 2.11 ar(5), historical section)
+
+ Search for TODO to find other areas needing more work. */
+
+#define BYTES_IN_WORD 2
+#define BYTES_IN_LONG 4
+#define ARCH_SIZE 16
+#undef TARGET_IS_BIG_ENDIAN_P
+
+#define TARGET_PAGE_SIZE 1024
+#define SEGMENT__SIZE TARGET_PAGE_SIZE
+
+#define DEFAULT_ARCH bfd_arch_pdp11
+#define DEFAULT_MID M_PDP11
+
+/* Do not "beautify" the CONCAT* macro args. Traditional C will not
+ remove whitespace added here, and thus will fail to concatenate
+ the tokens. */
+#define MY(OP) CONCAT2 (pdp11_aout_,OP)
+
+/* This needs to start with a.out so GDB knows it is an a.out variant. */
+#define TARGETNAME "a.out-pdp11"
+
+/* This is the normal load address for executables. */
+#define TEXT_START_ADDR 0
+
+/* The header is not included in the text segment. */
+#define N_HEADER_IN_TEXT(x) 0
+
+/* There is no flags field. */
+#define N_FLAGS(exec) 0
+
+#define N_SET_FLAGS(exec, flags) do { } while (0)
+#define N_BADMAG(x) (N_MAGIC(x) != OMAGIC \
+ && N_MAGIC(x) != NMAGIC \
+ && N_MAGIC(x) != ZMAGIC)
+
+#include "sysdep.h"
+#include "bfd.h"
+
+#define external_exec pdp11_external_exec
+struct pdp11_external_exec
+{
+ bfd_byte e_info[2]; /* Magic number. */
+ bfd_byte e_text[2]; /* Length of text section in bytes. */
+ bfd_byte e_data[2]; /* Length of data section in bytes. */
+ bfd_byte e_bss[2]; /* Length of bss area in bytes. */
+ bfd_byte e_syms[2]; /* Length of symbol table in bytes. */
+ bfd_byte e_entry[2]; /* Start address. */
+ bfd_byte e_unused[2]; /* Not used. */
+ bfd_byte e_flag[2]; /* Relocation info stripped. */
+ bfd_byte e_relocatable; /* Ugly hack. */
+};
+
+#define EXEC_BYTES_SIZE (8 * 2)
+
+#define A_MAGIC1 OMAGIC
+#define OMAGIC 0407 /* ...object file or impure executable. */
+#define A_MAGIC2 NMAGIC
+#define NMAGIC 0410 /* Pure executable. */
+#define ZMAGIC 0413 /* Demand-paged executable. */
+#define A_MAGIC3 0411 /* Separated I&D. */
+#define A_MAGIC4 0405 /* Overlay. */
+#define A_MAGIC5 0430 /* Auto-overlay (nonseparate). */
+#define A_MAGIC6 0431 /* Auto-overlay (separate). */
+#define QMAGIC 0
+#define BMAGIC 0
+
+#define A_FLAG_RELOC_STRIPPED 0x0001
+
+#define external_nlist pdp11_external_nlist
+struct pdp11_external_nlist
+{
+ bfd_byte e_unused[2]; /* Unused. */
+ bfd_byte e_strx[2]; /* Index into string table of name. */
+ bfd_byte e_type[1]; /* Type of symbol. */
+ bfd_byte e_ovly[1]; /* Overlay number. */
+ bfd_byte e_value[2]; /* Value of symbol. */
+};
+
+#define EXTERNAL_NLIST_SIZE 8
+
+#define N_TXTOFF(x) (EXEC_BYTES_SIZE)
+#define N_DATOFF(x) (N_TXTOFF(x) + (x).a_text)
+#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)
+
+#define WRITE_HEADERS(abfd, execp) pdp11_aout_write_headers (abfd, execp)
+
+#include "libbfd.h"
+#include "libaout.h"
+
+#define SWAP_MAGIC(ext) bfd_getl16 (ext)
+
+#define MY_entry_is_text_address 1
+
+#define MY_write_object_contents MY(write_object_contents)
+static bfd_boolean MY(write_object_contents) (bfd *);
+#define MY_text_includes_header 1
+
+#define MY_BFD_TARGET
+
+#include "aout-target.h"
+
+/* Start of modified aoutx.h. */
+#define KEEPIT udata.i
+
+#include <string.h> /* For strchr and friends. */
+#include "bfd.h"
+#include "sysdep.h"
+#include "safe-ctype.h"
+#include "bfdlink.h"
+
+#include "libaout.h"
+#include "aout/aout64.h"
+#include "aout/stab_gnu.h"
+#include "aout/ar.h"
+
+#undef N_TYPE
+#undef N_UNDF
+#undef N_ABS
+#undef N_TEXT
+#undef N_DATA
+#undef N_BSS
+#undef N_REG
+#undef N_FN
+#undef N_EXT
+#define N_TYPE 0x1f /* Type mask. */
+#define N_UNDF 0x00 /* Undefined. */
+#define N_ABS 0x01 /* Absolute. */
+#define N_TEXT 0x02 /* Text segment. */
+#define N_DATA 0x03 /* Data segment. */
+#define N_BSS 0x04 /* Bss segment. */
+#define N_REG 0x14 /* Register symbol. */
+#define N_FN 0x1f /* File name. */
+#define N_EXT 0x20 /* External flag. */
+
+#define RELOC_SIZE 2
+
+#define RELFLG 0x0001 /* PC-relative flag. */
+#define RTYPE 0x000e /* Type mask. */
+#define RIDXMASK 0xfff0 /* Index mask. */
+
+#define RABS 0x00 /* Absolute. */
+#define RTEXT 0x02 /* Text. */
+#define RDATA 0x04 /* Data. */
+#define RBSS 0x06 /* Bss. */
+#define REXT 0x08 /* External. */
+
+#define RINDEX(x) (((x) & 0xfff0) >> 4)
+
+#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
+
+/* 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;
+};
+
+/* 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. */
+ void * 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;
+};
+
+reloc_howto_type howto_table_pdp11[] =
+{
+ /* type rs size bsz pcrel bitpos ovrf sf name part_inpl readmask setmask pcdone */
+HOWTO( 0, 0, 1, 16, FALSE, 0, complain_overflow_signed,0,"16", TRUE, 0x0000ffff,0x0000ffff, FALSE),
+HOWTO( 1, 0, 1, 16, TRUE, 0, complain_overflow_signed,0,"DISP16", TRUE, 0x0000ffff,0x0000ffff, FALSE),
+};
+
+#define TABLE_SIZE(TABLE) (sizeof(TABLE)/sizeof(TABLE[0]))
+
+
+static bfd_boolean aout_link_check_archive_element (bfd *, struct bfd_link_info *, struct bfd_link_hash_entry *, const char *, bfd_boolean *);
+static bfd_boolean aout_link_add_object_symbols (bfd *, struct bfd_link_info *);
+static bfd_boolean aout_link_add_symbols (bfd *, struct bfd_link_info *);
+static bfd_boolean aout_link_write_symbols (struct aout_final_link_info *, bfd *);
+
+
+reloc_howto_type *
+NAME (aout, reloc_type_lookup) (bfd * abfd ATTRIBUTE_UNUSED,
+ bfd_reloc_code_real_type code)
+{
+ switch (code)
+ {
+ case BFD_RELOC_16:
+ return &howto_table_pdp11[0];
+ case BFD_RELOC_16_PCREL:
+ return &howto_table_pdp11[1];
+ default:
+ return NULL;
+ }
+}
+
+reloc_howto_type *
+NAME (aout, reloc_name_lookup) (bfd *abfd ATTRIBUTE_UNUSED,
+ const char *r_name)
+{
+ unsigned int i;
+
+ for (i = 0;
+ i < sizeof (howto_table_pdp11) / sizeof (howto_table_pdp11[0]);
+ i++)
+ if (howto_table_pdp11[i].name != NULL
+ && strcasecmp (howto_table_pdp11[i].name, r_name) == 0)
+ return &howto_table_pdp11[i];
+
+ return NULL;
+}
+
+static int
+pdp11_aout_write_headers (bfd *abfd, struct internal_exec *execp)
+{
+ struct external_exec exec_bytes;
+ bfd_size_type text_size;
+ 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);
+
+ if (obj_textsec (abfd)->reloc_count > 0
+ || obj_datasec (abfd)->reloc_count > 0)
+ {
+ execp->a_trsize = execp->a_text;
+ execp->a_drsize = execp->a_data;
+ }
+ else
+ {
+ execp->a_trsize = 0;
+ execp->a_drsize = 0;
+ }
+
+ NAME (aout, swap_exec_header_out) (abfd, execp, & exec_bytes);
+
+ if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
+ return FALSE;
+
+ if (bfd_bwrite ((void *) &exec_bytes, (bfd_size_type) EXEC_BYTES_SIZE, abfd)
+ != EXEC_BYTES_SIZE)
+ return FALSE;
+
+ /* Now write out reloc info, followed by syms and strings. */
+ if (bfd_get_outsymbols (abfd) != 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 (obj_textsec (abfd)->reloc_count > 0
+ || obj_datasec (abfd)->reloc_count > 0)
+ {
+ if (bfd_seek (abfd, (file_ptr) (N_TRELOFF(*execp)), SEEK_SET) != 0
+ || !NAME (aout, squirt_out_relocs) (abfd, obj_textsec (abfd))
+ || bfd_seek (abfd, (file_ptr) (N_DRELOFF(*execp)), SEEK_SET) != 0
+ || !NAME (aout, squirt_out_relocs) (abfd, obj_datasec (abfd)))
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/* Write an object file.
+ Section contents have already been written. We write the
+ file header, symbols, and relocation. */
+
+static bfd_boolean
+MY(write_object_contents) (bfd *abfd)
+{
+ 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);
+ }
+
+ obj_reloc_entry_size (abfd) = RELOC_SIZE;
+
+ return WRITE_HEADERS (abfd, execp);
+}
+
+/* Swap the information in an executable header @var{raw_bytes} taken
+ from a raw byte stream memory image into the internal exec header
+ structure "execp". */
+
+#ifndef NAME_swap_exec_header_in
+void
+NAME (aout, swap_exec_header_in) (bfd *abfd,
+ struct external_exec *bytes,
+ struct internal_exec *execp)
+{
+ /* 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 ((void *) execp, 0, sizeof (struct internal_exec));
+ /* Now fill in fields in the execp, from the bytes in the raw data. */
+ execp->a_info = GET_MAGIC (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);
+
+ if (GET_WORD (abfd, bytes->e_flag) & A_FLAG_RELOC_STRIPPED)
+ {
+ execp->a_trsize = 0;
+ execp->a_drsize = 0;
+ }
+ else
+ {
+ execp->a_trsize = execp->a_text;
+ execp->a_drsize = execp->a_data;
+ }
+}
+#define NAME_swap_exec_header_in NAME (aout, swap_exec_header_in)
+#endif
+
+/* Swap the information in an internal exec header structure
+ "execp" into the buffer "bytes" ready for writing to disk. */
+void
+NAME (aout, swap_exec_header_out) (bfd *abfd,
+ struct internal_exec *execp,
+ struct external_exec *bytes)
+{
+ /* Now fill in fields in the raw data, from the fields in the exec struct. */
+ PUT_MAGIC (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, 0, bytes->e_unused);
+
+ if ((execp->a_trsize == 0 || execp->a_text == 0)
+ && (execp->a_drsize == 0 || execp->a_data == 0))
+ PUT_WORD (abfd, A_FLAG_RELOC_STRIPPED, bytes->e_flag);
+ else if (execp->a_trsize == execp->a_text
+ && execp->a_drsize == execp->a_data)
+ PUT_WORD (abfd, 0, bytes->e_flag);
+ else
+ {
+ /* TODO: print a proper warning message. */
+ fprintf (stderr, "BFD:%s:%d: internal error\n", __FILE__, __LINE__);
+ PUT_WORD (abfd, 0, bytes->e_flag);
+ }
+}
+
+/* Make all the section for an a.out file. */
+
+bfd_boolean
+NAME (aout, make_sections) (bfd *abfd)
+{
+ if (obj_textsec (abfd) == NULL && bfd_make_section (abfd, ".text") == NULL)
+ return FALSE;
+ if (obj_datasec (abfd) == NULL && bfd_make_section (abfd, ".data") == NULL)
+ return FALSE;
+ if (obj_bsssec (abfd) == NULL && bfd_make_section (abfd, ".bss") == NULL)
+ return FALSE;
+ return TRUE;
+}
+
+/* Some a.out variant thinks that the file open in 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) (bfd *abfd,
+ struct internal_exec *execp,
+ const bfd_target *(*callback_to_real_object_p) (bfd *))
+{
+ struct aout_data_struct *rawptr, *oldrawptr;
+ const bfd_target *result;
+ bfd_size_type amt = sizeof (struct aout_data_struct);
+
+ rawptr = bfd_zalloc (abfd, amt);
+ 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) == 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) = 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_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)->size = execp->a_data;
+ obj_bsssec (abfd)->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);
+ /* 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. */
+ abfd->obj_arch = bfd_arch_obscure;
+
+ 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)->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)
+ {
+ free (rawptr);
+ abfd->tdata.aout_data = oldrawptr;
+ }
+ return result;
+}
+
+/* Initialize ABFD for use with a.out files. */
+
+bfd_boolean
+NAME (aout, mkobject) (bfd *abfd)
+{
+ struct aout_data_struct *rawptr;
+ bfd_size_type amt = sizeof (struct aout_data_struct);
+
+ bfd_set_error (bfd_error_system_call);
+
+ /* Use an intermediate variable for clarity. */
+ rawptr = bfd_zalloc (abfd, amt);
+
+ if (rawptr == NULL)
+ return FALSE;
+
+ abfd->tdata.aout_data = rawptr;
+ exec_hdr (abfd) = &(rawptr->e);
+
+ obj_textsec (abfd) = NULL;
+ obj_datasec (abfd) = NULL;
+ obj_bsssec (abfd) = NULL;
+
+ return TRUE;
+}
+
+/* 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) (enum bfd_architecture arch,
+ unsigned long machine,
+ bfd_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_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
+ || machine == bfd_mach_i386_i386
+ || machine == bfd_mach_i386_i386_intel_syntax)
+ arch_flags = M_386;
+ break;
+
+ case bfd_arch_arm:
+ if (machine == 0) arch_flags = M_ARM;
+ break;
+
+ case bfd_arch_mips:
+ switch (machine)
+ {
+ case 0:
+ case 2000:
+ case bfd_mach_mips3000:
+ arch_flags = M_MIPS1;
+ break;
+ case bfd_mach_mips4000: /* MIPS3 */
+ case bfd_mach_mips4400:
+ case bfd_mach_mips8000: /* MIPS4 */
+ case bfd_mach_mips6000: /* Real MIPS2: */
+ 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_pdp11:
+ /* TODO: arch_flags = M_PDP11; */
+ *unknown = FALSE;
+ break;
+
+ case bfd_arch_vax:
+ *unknown = FALSE;
+ break;
+
+ default:
+ arch_flags = M_UNKNOWN;
+ }
+
+ if (arch_flags != M_UNKNOWN)
+ *unknown = FALSE;
+
+ return arch_flags;
+}
+
+/* Set the architecture and the machine of the ABFD to the
+ values ARCH and MACHINE. Verify that @ABFD's format
+ can support the architecture required. */
+
+bfd_boolean
+NAME (aout, set_arch_mach) (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)
+ {
+ bfd_boolean unknown;
+
+ NAME (aout, machine_type) (arch, machine, &unknown);
+ if (unknown)
+ return FALSE;
+ }
+
+ obj_reloc_entry_size (abfd) = RELOC_SIZE;
+
+ return (*aout_backend_info(abfd)->set_sizes) (abfd);
+}
+
+static void
+adjust_o_magic (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)->size;
+ vma += obj_textsec (abfd)->size;
+
+ /* Data. */
+ if (!obj_datasec (abfd)->user_set_vma)
+ {
+ obj_textsec (abfd)->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)->size;
+ vma += obj_datasec (abfd)->size;
+
+ /* BSS. */
+ if (! obj_bsssec (abfd)->user_set_vma)
+ {
+ obj_datasec (abfd)->size += pad;
+ pos += pad;
+ vma += pad;
+ obj_bsssec (abfd)->vma = vma;
+ }
+ else
+ {
+ /* The VMA of the .bss section is set by 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)->size += pad;
+ pos += pad;
+ }
+ }
+ obj_bsssec (abfd)->filepos = pos;
+
+ /* Fix up the exec header. */
+ execp->a_text = obj_textsec (abfd)->size;
+ execp->a_data = obj_datasec (abfd)->size;
+ execp->a_bss = obj_bsssec (abfd)->size;
+ N_SET_MAGIC (*execp, OMAGIC);
+}
+
+static void
+adjust_z_magic (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)->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)->size;
+ text_pad += BFD_ALIGN (text_end, adata (abfd).page_size) - text_end;
+ text_end += obj_textsec (abfd)->filepos;
+ }
+
+ obj_textsec (abfd)->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)->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)->size);
+ obj_textsec(abfd)->size += text_pad;
+ }
+ obj_datasec (abfd)->filepos = (obj_textsec (abfd)->filepos
+ + obj_textsec (abfd)->size);
+
+ /* Fix up exec header while we're at it. */
+ execp->a_text = obj_textsec(abfd)->size;
+ if (ztih && (!abdp || (abdp && !abdp->exec_header_not_counted)))
+ execp->a_text += adata(abfd).exec_bytes_size;
+ N_SET_MAGIC (*execp, ZMAGIC);
+
+ /* Spec says data section should be rounded up to page boundary. */
+ obj_datasec(abfd)->size
+ = align_power (obj_datasec(abfd)->size,
+ obj_bsssec(abfd)->alignment_power);
+ execp->a_data = BFD_ALIGN (obj_datasec(abfd)->size,
+ adata(abfd).page_size);
+ data_pad = execp->a_data - obj_datasec(abfd)->size;
+
+ /* BSS. */
+ if (!obj_bsssec(abfd)->user_set_vma)
+ obj_bsssec(abfd)->vma = (obj_datasec(abfd)->vma
+ + obj_datasec(abfd)->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)->size)
+ execp->a_bss = (data_pad > obj_bsssec(abfd)->size) ? 0 :
+ obj_bsssec(abfd)->size - data_pad;
+ else
+ execp->a_bss = obj_bsssec(abfd)->size;
+}
+
+static void
+adjust_n_magic (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)->size;
+ vma += obj_textsec(abfd)->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)->size;
+ pad = align_power (vma, obj_bsssec(abfd)->alignment_power) - vma;
+ obj_datasec(abfd)->size += pad;
+ pos += obj_datasec(abfd)->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)->size;
+ execp->a_data = obj_datasec(abfd)->size;
+ execp->a_bss = obj_bsssec(abfd)->size;
+ N_SET_MAGIC (*execp, NMAGIC);
+}
+
+bfd_boolean
+NAME (aout, adjust_sizes_and_vmas) (bfd *abfd,
+ bfd_size_type *text_size,
+ file_ptr * text_end ATTRIBUTE_UNUSED)
+{
+ 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)->size =
+ align_power(obj_textsec(abfd)->size,
+ obj_textsec(abfd)->alignment_power);
+
+ *text_size = obj_textsec (abfd)->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 & 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)->size,
+ obj_textsec(abfd)->alignment_power,
+ obj_datasec(abfd)->vma, obj_datasec(abfd)->size,
+ obj_datasec(abfd)->alignment_power,
+ obj_bsssec(abfd)->vma, obj_bsssec(abfd)->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)->size,
+ obj_textsec(abfd)->filepos,
+ obj_datasec(abfd)->vma, obj_datasec(abfd)->size,
+ obj_datasec(abfd)->filepos,
+ obj_bsssec(abfd)->vma, obj_bsssec(abfd)->size);
+#endif
+
+ return TRUE;
+}
+
+/* Called by the BFD in response to a bfd_make_section request. */
+
+bfd_boolean
+NAME (aout, new_section_hook) (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;
+ }
+ else if (obj_datasec (abfd) == NULL
+ && !strcmp (newsect->name, ".data"))
+ {
+ obj_datasec (abfd) = newsect;
+ newsect->target_index = N_DATA;
+ }
+ else if (obj_bsssec (abfd) == NULL
+ && !strcmp (newsect->name, ".bss"))
+ {
+ obj_bsssec (abfd) = newsect;
+ newsect->target_index = N_BSS;
+ }
+ }
+
+ /* We allow more than three sections internally. */
+ return _bfd_generic_new_section_hook (abfd, newsect);
+}
+
+bfd_boolean
+NAME (aout, set_section_contents) (bfd *abfd,
+ sec_ptr section,
+ const void * 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_bwrite (location, count, abfd) != count)
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/* Read the external symbols from an a.out file. */
+
+static bfd_boolean
+aout_get_external_symbols (bfd *abfd)
+{
+ if (obj_aout_external_syms (abfd) == 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))
+ 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 = bfd_malloc (count * EXTERNAL_NLIST_SIZE);
+ if (syms == NULL && count != 0)
+ return FALSE;
+
+ if (bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET) != 0
+ || (bfd_bread (syms, 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_LONG];
+ bfd_size_type stringsize;
+ char *strings;
+
+ /* Get the size of the strings. */
+ if (bfd_seek (abfd, obj_str_filepos (abfd), SEEK_SET) != 0
+ || (bfd_bread ((void *) string_chars, (bfd_size_type) BYTES_IN_LONG,
+ abfd) != BYTES_IN_LONG))
+ return FALSE;
+ stringsize = H_GET_32 (abfd, string_chars);
+
+#ifdef USE_MMAP
+ if (! bfd_get_file_window (abfd, obj_str_filepos (abfd), stringsize,
+ &obj_aout_string_window (abfd), TRUE))
+ return FALSE;
+ strings = (char *) obj_aout_string_window (abfd).data;
+#else
+ strings = bfd_malloc (stringsize + 1);
+ if (strings == NULL)
+ return FALSE;
+
+ /* Skip space for the string count in the buffer for convenience
+ when using indexes. */
+ if (bfd_bread (strings + 4, stringsize - 4, abfd) != stringsize - 4)
+ {
+ 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 bfd_boolean
+translate_from_native_sym_flags (bfd *abfd,
+ aout_symbol_type *cache_ptr)
+{
+ flagword visible;
+
+ if (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;
+
+ 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;
+ }
+
+ return TRUE;
+}
+
+/* Set the fields of SYM_POINTER according to CACHE_PTR. */
+
+static bfd_boolean
+translate_to_native_sym_flags (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)
+ ("%B: can not represent section for symbol `%s' in a.out object file format",
+ 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_com_section (sec))
+ sym_pointer->e_type[0] = N_UNDF | N_EXT;
+ else
+ {
+ (*_bfd_error_handler)
+ ("%B: can not represent section `%A' in a.out object file format",
+ 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_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;
+
+ PUT_WORD(abfd, value, sym_pointer->e_value);
+
+ return TRUE;
+}
+
+/* Native-level interface to symbols. */
+
+asymbol *
+NAME (aout, make_empty_symbol) (bfd *abfd)
+{
+ bfd_size_type amt = sizeof (aout_symbol_type);
+ aout_symbol_type *new_symbol_type = bfd_zalloc (abfd, amt);
+
+ if (!new_symbol_type)
+ return NULL;
+ new_symbol_type->symbol.the_bfd = abfd;
+
+ return &new_symbol_type->symbol;
+}
+
+/* Translate a set of internal symbols into external symbols. */
+
+bfd_boolean
+NAME (aout, translate_symbol_table) (bfd *abfd,
+ aout_symbol_type *in,
+ struct external_nlist *ext,
+ bfd_size_type count,
+ char *str,
+ bfd_size_type strsize,
+ bfd_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);
+ /* TODO: is 0 a safe value here? */
+ in->desc = 0;
+ in->other = 0;
+ in->type = 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. */
+
+bfd_boolean
+NAME (aout, slurp_symbol_table) (bfd *abfd)
+{
+ struct external_nlist *old_external_syms;
+ aout_symbol_type *cached;
+ bfd_size_type cached_size;
+
+ /* If there's no work to be done, don't do any. */
+ if (obj_aout_symbols (abfd) != 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);
+ cached_size *= sizeof (aout_symbol_type);
+ cached = bfd_zmalloc (cached_size);
+ if (cached == NULL && cached_size != 0)
+ return FALSE;
+
+ /* 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 == NULL
+ && obj_aout_external_syms (abfd) != 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. */
+
+/* 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 (bfd *abfd,
+ struct bfd_strtab_hash *tab,
+ const char *str,
+ bfd_boolean copy)
+{
+ bfd_boolean hash;
+ bfd_size_type str_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;
+
+ str_index = _bfd_stringtab_add (tab, str, hash, copy);
+
+ if (str_index != (bfd_size_type) -1)
+ /* Add BYTES_IN_LONG to the return value to account for the
+ space taken up by the string table size. */
+ str_index += BYTES_IN_LONG;
+
+ return str_index;
+}
+
+/* Write out a strtab. ABFD is already at the right location in the
+ file. */
+
+static bfd_boolean
+emit_stringtab (bfd *abfd, struct bfd_strtab_hash *tab)
+{
+ bfd_byte buffer[BYTES_IN_LONG];
+
+ /* The string table starts with the size. */
+ H_PUT_32 (abfd, _bfd_stringtab_size (tab) + BYTES_IN_LONG, buffer);
+ if (bfd_bwrite ((void *) buffer, (bfd_size_type) BYTES_IN_LONG, abfd)
+ != BYTES_IN_LONG)
+ return FALSE;
+
+ return _bfd_stringtab_emit (abfd, tab);
+}
+
+bfd_boolean
+NAME (aout, write_syms) (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;
+
+ PUT_WORD (abfd, 0, nsp.e_unused);
+
+ indx = add_to_stringtab (abfd, strtab, g->name, FALSE);
+ if (indx == (bfd_size_type) -1)
+ goto error_return;
+ PUT_WORD (abfd, indx, nsp.e_strx);
+
+ if (bfd_asymbol_flavour(g) == abfd->xvec->flavour)
+ H_PUT_8 (abfd, aout_symbol(g)->type, nsp.e_type);
+ else
+ H_PUT_8 (abfd, 0, nsp.e_type);
+
+ if (! translate_to_native_sym_flags (abfd, g, &nsp))
+ goto error_return;
+
+ H_PUT_8 (abfd, 0, nsp.e_ovly);
+
+ if (bfd_bwrite ((void *)&nsp, (bfd_size_type) 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, canonicalize_symtab) (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);
+}
+
+
+/* Output extended relocation information to a file in target byte order. */
+
+static void
+pdp11_aout_swap_reloc_out (bfd *abfd, arelent *g, bfd_byte *natptr)
+{
+ int r_index;
+ int r_pcrel;
+ int reloc_entry;
+ int r_type;
+ asymbol *sym = *(g->sym_ptr_ptr);
+ asection *output_section = sym->section->output_section;
+
+ if (g->addend != 0)
+ fprintf (stderr, "BFD: can't do this reloc addend stuff\n");
+
+ r_pcrel = g->howto->pc_relative;
+
+ if (bfd_is_abs_section (output_section))
+ r_type = RABS;
+ else if (output_section == obj_textsec (abfd))
+ r_type = RTEXT;
+ else if (output_section == obj_datasec (abfd))
+ r_type = RDATA;
+ else if (output_section == obj_bsssec (abfd))
+ r_type = RBSS;
+ else if (bfd_is_und_section (output_section))
+ r_type = REXT;
+ else if (bfd_is_com_section (output_section))
+ r_type = REXT;
+ else
+ r_type = -1;
+
+ BFD_ASSERT (r_type != -1);
+
+ if (r_type == RABS)
+ r_index = 0;
+ else
+ r_index = (*(g->sym_ptr_ptr))->KEEPIT;
+
+ reloc_entry = r_index << 4 | r_type | r_pcrel;
+
+ PUT_WORD (abfd, reloc_entry, natptr);
+}
+
+/* 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; \
+ } \
+ }
+
+static void
+pdp11_aout_swap_reloc_in (bfd * abfd,
+ bfd_byte * bytes,
+ arelent * cache_ptr,
+ bfd_size_type offset,
+ asymbol ** symbols,
+ bfd_size_type symcount)
+{
+ struct aoutdata *su = &(abfd->tdata.aout_data->a);
+ unsigned int r_index;
+ int reloc_entry;
+ int r_extern;
+ int r_pcrel;
+
+ reloc_entry = GET_WORD (abfd, (void *) bytes);
+
+ r_pcrel = reloc_entry & RELFLG;
+
+ cache_ptr->address = offset;
+ cache_ptr->howto = howto_table_pdp11 + (r_pcrel ? 1 : 0);
+
+ if ((reloc_entry & RTYPE) == RABS)
+ r_index = N_ABS;
+ else
+ r_index = RINDEX (reloc_entry);
+
+ /* r_extern reflects whether the symbol the reloc is against is
+ local or global. */
+ r_extern = (reloc_entry & RTYPE) == REXT;
+
+ 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. */
+
+bfd_boolean
+NAME (aout, slurp_reloc_table) (bfd *abfd, sec_ptr asect, asymbol **symbols)
+{
+ bfd_byte *rptr;
+ bfd_size_type count;
+ bfd_size_type reloc_size;
+ void * 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);
+
+ relocs = bfd_malloc (reloc_size);
+ if (relocs == NULL && reloc_size != 0)
+ return FALSE;
+
+ if (bfd_bread (relocs, reloc_size, abfd) != reloc_size)
+ {
+ free (relocs);
+ return FALSE;
+ }
+
+ count = reloc_size / each_size;
+
+ /* Count the number of NON-ZERO relocs, this is the count we want. */
+ {
+ unsigned int real_count = 0;
+
+ for (counter = 0; counter < count; counter++)
+ {
+ int x;
+
+ x = GET_WORD (abfd, (char *) relocs + each_size * counter);
+ if (x != 0)
+ real_count++;
+ }
+
+ count = real_count;
+ }
+
+ reloc_cache = bfd_zmalloc (count * sizeof (arelent));
+ if (reloc_cache == NULL && count != 0)
+ return FALSE;
+
+ cache_ptr = reloc_cache;
+
+ rptr = relocs;
+ for (counter = 0;
+ counter < count;
+ counter++, rptr += RELOC_SIZE, cache_ptr++)
+ {
+ while (GET_WORD (abfd, (void *) rptr) == 0)
+ {
+ rptr += RELOC_SIZE;
+ if ((char *) rptr >= (char *) relocs + reloc_size)
+ goto done;
+ }
+
+ pdp11_aout_swap_reloc_in (abfd, rptr, cache_ptr,
+ (bfd_size_type) ((char *) rptr - (char *) relocs),
+ symbols,
+ (bfd_size_type) bfd_get_symcount (abfd));
+ }
+ done:
+ /* Just in case, if rptr >= relocs + reloc_size should happen
+ too early. */
+ BFD_ASSERT (counter == count);
+
+ free (relocs);
+
+ asect->relocation = reloc_cache;
+ asect->reloc_count = cache_ptr - reloc_cache;
+
+ return TRUE;
+}
+
+/* Write out a relocation section into an object file. */
+
+bfd_boolean
+NAME (aout, squirt_out_relocs) (bfd *abfd, asection *section)
+{
+ arelent **generic;
+ unsigned char *native;
+ unsigned int count = section->reloc_count;
+ bfd_size_type natsize;
+
+ natsize = section->size;
+ native = bfd_zalloc (abfd, natsize);
+ if (!native)
+ return FALSE;
+
+ generic = section->orelocation;
+ if (generic != NULL)
+ {
+ while (count > 0)
+ {
+ bfd_byte *r;
+
+ r = native + (*generic)->address;
+ pdp11_aout_swap_reloc_out (abfd, *generic, r);
+ count--;
+ generic++;
+ }
+ }
+
+ if (bfd_bwrite ((void *) native, 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) (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) (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));
+
+ /* TODO: why are there two if statements for obj_bsssec()? */
+
+ 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) (bfd *abfd)
+{
+ if (!NAME (aout, slurp_symbol_table) (abfd))
+ return -1;
+
+ return (bfd_get_symcount (abfd) + 1) * (sizeof (aout_symbol_type *));
+}
+
+alent *
+NAME (aout, get_lineno) (bfd * abfd ATTRIBUTE_UNUSED,
+ asymbol * symbol ATTRIBUTE_UNUSED)
+{
+ return NULL;
+}
+
+void
+NAME (aout, get_symbol_info) (bfd * abfd ATTRIBUTE_UNUSED,
+ 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;
+ }
+}
+
+void
+NAME (aout, print_symbol) (bfd * abfd,
+ void * 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 (abfd, (void *) 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 method: 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) (bfd *abfd,
+ bfd_boolean dynamic,
+ void * *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 = (void *) 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) (bfd *abfd,
+ bfd_boolean dynamic,
+ const void * 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. */
+
+bfd_boolean
+NAME (aout, find_nearest_line) (bfd *abfd,
+ asymbol **symbols,
+ asection *section,
+ bfd_vma offset,
+ const char **filename_ptr,
+ const char **functionname_ptr,
+ unsigned int *line_ptr,
+ unsigned int *discriminator_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. */
+ 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 (discriminator_ptr)
+ *discriminator_ptr = 0;
+
+ if (symbols != 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;
+ }
+ 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;
+
+ 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 = bfd_malloc ((bfd_size_type) 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 *colon;
+
+ /* 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. */
+ colon = strchr (buf, ':');
+ if (colon != NULL)
+ *colon = '\0';
+ *functionname_ptr = buf;
+ }
+
+ return TRUE;
+}
+
+int
+NAME (aout, sizeof_headers) (bfd *abfd,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED)
+{
+ 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. */
+
+bfd_boolean
+NAME (aout, bfd_free_cached_info) (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 != NULL; o = o->next)
+ BFCI_FREE (o->relocation);
+#undef BFCI_FREE
+
+ return TRUE;
+}
+
+/* Routine to create an entry in an a.out link hash table. */
+
+struct bfd_hash_entry *
+NAME (aout, link_hash_newfunc) (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 == NULL)
+ ret = bfd_hash_allocate (table, sizeof (* ret));
+ if (ret == NULL)
+ return NULL;
+
+ /* 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. */
+
+bfd_boolean
+NAME (aout, link_hash_table_init) (struct aout_link_hash_table *table,
+ bfd *abfd,
+ struct bfd_hash_entry *(*newfunc) (struct bfd_hash_entry *,
+ struct bfd_hash_table *,
+ const char *),
+ unsigned int entsize)
+{
+ return _bfd_link_hash_table_init (&table->root, abfd, newfunc, entsize);
+}
+
+/* Create an a.out link hash table. */
+
+struct bfd_link_hash_table *
+NAME (aout, link_hash_table_create) (bfd *abfd)
+{
+ struct aout_link_hash_table *ret;
+ bfd_size_type amt = sizeof (struct aout_link_hash_table);
+
+ ret = bfd_malloc (amt);
+ if (ret == NULL)
+ return NULL;
+ if (! NAME (aout, link_hash_table_init) (ret, abfd,
+ NAME (aout, link_hash_newfunc),
+ sizeof (struct aout_link_hash_entry)))
+ {
+ free (ret);
+ return NULL;
+ }
+ return &ret->root;
+}
+
+/* Free up the internal symbols read from an a.out file. */
+
+static bfd_boolean
+aout_link_free_symbols (bfd *abfd)
+{
+ if (obj_aout_external_syms (abfd) != NULL)
+ {
+#ifdef USE_MMAP
+ bfd_free_window (&obj_aout_sym_window (abfd));
+#else
+ free ((void *) obj_aout_external_syms (abfd));
+#endif
+ obj_aout_external_syms (abfd) = NULL;
+ }
+
+ if (obj_aout_external_strings (abfd) != NULL)
+ {
+#ifdef USE_MMAP
+ bfd_free_window (&obj_aout_string_window (abfd));
+#else
+ free ((void *) obj_aout_external_strings (abfd));
+#endif
+ obj_aout_external_strings (abfd) = NULL;
+ }
+ return TRUE;
+}
+
+/* Given an a.out BFD, add symbols to the global hash table as
+ appropriate. */
+
+bfd_boolean
+NAME (aout, link_add_symbols) (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 bfd_boolean
+aout_link_add_object_symbols (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;
+}
+
+/* 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 bfd_boolean
+aout_link_check_ar_symbols (bfd *abfd,
+ struct bfd_link_info *info,
+ bfd_boolean *pneeded,
+ bfd **subsbfd)
+{
+ 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 = 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_FN)
+ 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 == NULL
+ || (h->type != bfd_link_hash_undefined
+ && h->type != bfd_link_hash_common))
+ continue;
+
+ if (type == (N_TEXT | N_EXT)
+ || type == (N_DATA | N_EXT)
+ || type == (N_BSS | N_EXT)
+ || type == (N_ABS | 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, subsbfd))
+ 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 == 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, subsbfd))
+ 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 = 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;
+ }
+ }
+ }
+ }
+
+ /* We do not need this object file. */
+ 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 bfd_boolean
+aout_link_check_archive_element (bfd *abfd,
+ struct bfd_link_info *info,
+ struct bfd_link_hash_entry *h ATTRIBUTE_UNUSED,
+ const char *name ATTRIBUTE_UNUSED,
+ bfd_boolean *pneeded)
+{
+ bfd *oldbfd;
+ bfd_boolean needed;
+
+ if (!aout_get_external_symbols (abfd))
+ return FALSE;
+
+ oldbfd = abfd;
+ if (!aout_link_check_ar_symbols (abfd, info, pneeded, &abfd))
+ return FALSE;
+
+ needed = *pneeded;
+ if (needed)
+ {
+ /* Potentially, the add_archive_element hook may have set a
+ substitute BFD for us. */
+ if (abfd != oldbfd)
+ {
+ if (!info->keep_memory
+ && !aout_link_free_symbols (oldbfd))
+ return FALSE;
+ if (!aout_get_external_symbols (abfd))
+ return FALSE;
+ }
+ if (!aout_link_add_symbols (abfd, info))
+ return FALSE;
+ }
+
+ if (!info->keep_memory || !needed)
+ {
+ if (!aout_link_free_symbols (abfd))
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/* Add all symbols from an object file to the hash table. */
+
+static bfd_boolean
+aout_link_add_symbols (bfd *abfd, struct bfd_link_info *info)
+{
+ bfd_boolean (*add_one_symbol)
+ (struct bfd_link_info *, bfd *, const char *, flagword, asection *,
+ bfd_vma, const char *, bfd_boolean, bfd_boolean,
+ struct bfd_link_hash_entry **);
+ struct external_nlist *syms;
+ bfd_size_type sym_count;
+ char *strings;
+ bfd_boolean copy;
+ struct aout_link_hash_entry **sym_hash;
+ 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 = bfd_alloc (abfd,
+ 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 = H_GET_8 (abfd, p->e_type);
+
+ name = strings + GET_WORD (abfd, p->e_strx);
+ value = GET_WORD (abfd, p->e_value);
+ flags = BSF_GLOBAL;
+ string = NULL;
+ switch (type)
+ {
+ default:
+ /* Anything else should be a debugging symbol. */
+ BFD_ASSERT ((type & N_STAB) != 0);
+ continue;
+
+ case N_UNDF:
+ case N_ABS:
+ case N_TEXT:
+ case N_DATA:
+ case N_BSS:
+ case N_REG:
+ case N_FN:
+ /* Ignore symbols that are not externally visible. */
+ 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:
+ /* 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;
+ }
+
+ 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;
+ }
+ }
+
+ return TRUE;
+}
+
+/* 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)))
+
+/* The function to create a new entry in the header file hash table. */
+
+static struct bfd_hash_entry *
+aout_link_includes_newfunc (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 == NULL)
+ ret = bfd_hash_allocate (table,
+ sizeof (struct aout_link_includes_entry));
+ if (ret == NULL)
+ return NULL;
+
+ /* 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;
+}
+
+static bfd_boolean
+aout_link_write_other_symbol (struct bfd_hash_entry *bh, void *data)
+{
+ struct aout_link_hash_entry *h = (struct aout_link_hash_entry *) bh;
+ struct aout_final_link_info *flaginfo = (struct aout_final_link_info *) data;
+ bfd *output_bfd;
+ int type;
+ bfd_vma val;
+ struct external_nlist outsym;
+ bfd_size_type indx;
+ bfd_size_type amt;
+
+ if (h->root.type == bfd_link_hash_warning)
+ {
+ h = (struct aout_link_hash_entry *) h->root.u.i.link;
+ if (h->root.type == bfd_link_hash_new)
+ return TRUE;
+ }
+
+ output_bfd = flaginfo->output_bfd;
+
+ if (aout_backend_info (output_bfd)->write_dynamic_symbol != NULL)
+ {
+ if (! ((*aout_backend_info (output_bfd)->write_dynamic_symbol)
+ (output_bfd, flaginfo->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
+ && (flaginfo->info->strip == strip_all
+ || (flaginfo->info->strip == strip_some
+ && bfd_hash_lookup (flaginfo->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;
+ }
+
+ H_PUT_8 (output_bfd, type, outsym.e_type);
+ indx = add_to_stringtab (output_bfd, flaginfo->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);
+
+ amt = EXTERNAL_NLIST_SIZE;
+ if (bfd_seek (output_bfd, flaginfo->symoff, SEEK_SET) != 0
+ || bfd_bwrite ((void *) &outsym, amt, output_bfd) != amt)
+ /* FIXME: No way to handle errors. */
+ abort ();
+
+ flaginfo->symoff += amt;
+ h->indx = obj_aout_external_sym_count (output_bfd);
+ ++obj_aout_external_sym_count (output_bfd);
+
+ return TRUE;
+}
+
+/* Handle a link order which is supposed to generate a reloc. */
+
+static bfd_boolean
+aout_link_reloc_link_order (struct aout_final_link_info *flaginfo,
+ 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;
+ void * rel_ptr;
+ bfd_size_type rel_size;
+
+ 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 == flaginfo->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 (flaginfo->output_bfd, flaginfo->info,
+ pr->u.name, FALSE, FALSE, TRUE));
+ if (h != 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->root.root, flaginfo))
+ return FALSE;
+ r_index = h->indx;
+ }
+ else
+ {
+ if (! ((*flaginfo->info->callbacks->unattached_reloc)
+ (flaginfo->info, pr->u.name, NULL, NULL, (bfd_vma) 0)))
+ return FALSE;
+ r_index = 0;
+ }
+ }
+
+ howto = bfd_reloc_type_lookup (flaginfo->output_bfd, pr->reloc);
+ if (howto == 0)
+ {
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+
+ if (o == obj_textsec (flaginfo->output_bfd))
+ reloff_ptr = &flaginfo->treloff;
+ else if (o == obj_datasec (flaginfo->output_bfd))
+ reloff_ptr = &flaginfo->dreloff;
+ else
+ abort ();
+
+#ifdef MY_put_reloc
+ MY_put_reloc(flaginfo->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;
+
+ fprintf (stderr, "TODO: line %d in bfd/pdp11.c\n", __LINE__);
+
+ 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 (flaginfo->output_bfd, p->offset, srel.r_address);
+ if (bfd_header_big_endian (flaginfo->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 = (void *) &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;
+ bfd_boolean ok;
+
+ size = bfd_get_reloc_size (howto);
+ buf = bfd_zmalloc (size);
+ if (buf == NULL)
+ return FALSE;
+ r = MY_relocate_contents (howto, flaginfo->output_bfd,
+ pr->addend, buf);
+ switch (r)
+ {
+ case bfd_reloc_ok:
+ break;
+ default:
+ case bfd_reloc_outofrange:
+ abort ();
+ case bfd_reloc_overflow:
+ if (! ((*flaginfo->info->callbacks->reloc_overflow)
+ (flaginfo->info, NULL,
+ (p->type == bfd_section_reloc_link_order
+ ? bfd_section_name (flaginfo->output_bfd,
+ pr->u.section)
+ : pr->u.name),
+ howto->name, pr->addend, NULL,
+ (asection *) NULL, (bfd_vma) 0)))
+ {
+ free (buf);
+ return FALSE;
+ }
+ break;
+ }
+ ok = bfd_set_section_contents (flaginfo->output_bfd, o,
+ (void *) buf,
+ (file_ptr) p->offset,
+ size);
+ free (buf);
+ if (! ok)
+ return FALSE;
+ }
+
+ rel_size = obj_reloc_entry_size (flaginfo->output_bfd);
+ if (bfd_seek (flaginfo->output_bfd, *reloff_ptr, SEEK_SET) != 0
+ || bfd_bwrite (rel_ptr, rel_size, flaginfo->output_bfd) != rel_size)
+ return FALSE;
+
+ *reloff_ptr += rel_size;
+
+ /* 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 (flaginfo->output_bfd)
+ && (reloff_ptr != &flaginfo->treloff
+ || (*reloff_ptr
+ <= obj_datasec (flaginfo->output_bfd)->rel_filepos)));
+
+ return TRUE;
+}
+
+/* Get the section corresponding to a reloc index. */
+
+static inline asection *
+aout_reloc_type_to_section (bfd *abfd, int type)
+{
+ switch (type)
+ {
+ case RTEXT: return obj_textsec (abfd);
+ case RDATA: return obj_datasec (abfd);
+ case RBSS: return obj_bsssec (abfd);
+ case RABS: return bfd_abs_section_ptr;
+ case REXT: return bfd_und_section_ptr;
+ default: abort ();
+ }
+}
+
+static bfd_boolean
+pdp11_aout_link_input_section (struct aout_final_link_info *flaginfo,
+ bfd *input_bfd,
+ asection *input_section,
+ bfd_byte *relocs,
+ bfd_size_type rel_size,
+ bfd_byte *contents)
+{
+ bfd_boolean (*check_dynamic_reloc)
+ (struct bfd_link_info *, bfd *, asection *,
+ struct aout_link_hash_entry *, void *, bfd_byte *, bfd_boolean *,
+ bfd_vma *);
+ bfd *output_bfd;
+ bfd_boolean relocatable;
+ struct external_nlist *syms;
+ char *strings;
+ struct aout_link_hash_entry **sym_hashes;
+ int *symbol_map;
+ bfd_byte *rel;
+ bfd_byte *rel_end;
+
+ output_bfd = flaginfo->output_bfd;
+ check_dynamic_reloc = aout_backend_info (output_bfd)->check_dynamic_reloc;
+
+ BFD_ASSERT (obj_reloc_entry_size (input_bfd) == RELOC_SIZE);
+ BFD_ASSERT (input_bfd->xvec->header_byteorder
+ == output_bfd->xvec->header_byteorder);
+
+ relocatable = flaginfo->info->relocatable;
+ syms = obj_aout_external_syms (input_bfd);
+ strings = obj_aout_external_strings (input_bfd);
+ sym_hashes = obj_aout_sym_hashes (input_bfd);
+ symbol_map = flaginfo->symbol_map;
+
+ rel = relocs;
+ rel_end = rel + rel_size;
+ for (; rel < rel_end; rel += RELOC_SIZE)
+ {
+ bfd_vma r_addr;
+ int r_index;
+ int r_type;
+ int r_pcrel;
+ int r_extern;
+ reloc_howto_type *howto;
+ struct aout_link_hash_entry *h = NULL;
+ bfd_vma relocation;
+ bfd_reloc_status_type r;
+ int reloc_entry;
+
+ reloc_entry = GET_WORD (input_bfd, (void *) rel);
+ if (reloc_entry == 0)
+ continue;
+
+ {
+ unsigned int howto_idx;
+
+ r_index = (reloc_entry & RIDXMASK) >> 4;
+ r_type = reloc_entry & RTYPE;
+ r_pcrel = reloc_entry & RELFLG;
+ r_addr = (char *) rel - (char *) relocs;
+
+ r_extern = (r_type == REXT);
+
+ howto_idx = r_pcrel;
+ BFD_ASSERT (howto_idx < TABLE_SIZE (howto_table_pdp11));
+ howto = howto_table_pdp11 + howto_idx;
+ }
+
+ if (relocatable)
+ {
+ /* We are generating a relocatable 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 != NULL
+ && (h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak))
+ {
+ asection *output_section;
+
+ /* Compute a new r_index. */
+ output_section = h->root.u.def.section->output_section;
+ if (output_section == obj_textsec (output_bfd))
+ r_type = N_TEXT;
+ else if (output_section == obj_datasec (output_bfd))
+ r_type = N_DATA;
+ else if (output_section == obj_bsssec (output_bfd))
+ r_type = N_BSS;
+ else
+ r_type = 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->root.root,
+ flaginfo))
+ return FALSE;
+ }
+ r_index = h->indx;
+ }
+ else
+ {
+ const char *name;
+
+ name = strings + GET_WORD (input_bfd,
+ syms[r_index].e_strx);
+ if (! ((*flaginfo->info->callbacks->unattached_reloc)
+ (flaginfo->info, name, input_bfd, input_section,
+ r_addr)))
+ return FALSE;
+ r_index = 0;
+ }
+ }
+
+ relocation = 0;
+ }
+
+ /* Write out the new r_index value. */
+ reloc_entry = GET_WORD (input_bfd, rel);
+ reloc_entry &= RIDXMASK;
+ reloc_entry |= r_index << 4;
+ PUT_WORD (input_bfd, reloc_entry, rel);
+ }
+ else
+ {
+ asection *section;
+
+ /* This is a relocation against a section. We must
+ adjust by the amount that the section moved. */
+ section = aout_reloc_type_to_section (input_bfd, r_type);
+ relocation = (section->output_section->vma
+ + section->output_offset
+ - section->vma);
+ }
+
+ /* Change the address of the relocation. */
+ fprintf (stderr, "TODO: change the address of the relocation\n");
+
+ /* 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
+ {
+ bfd_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 != 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 != NULL
+ && h->root.type == bfd_link_hash_undefweak)
+ relocation = 0;
+ else
+ {
+ hundef = TRUE;
+ relocation = 0;
+ }
+ }
+ else
+ {
+ asection *section;
+
+ section = aout_reloc_type_to_section (input_bfd, r_type);
+ relocation = (section->output_section->vma
+ + section->output_offset
+ - section->vma);
+ if (r_pcrel)
+ relocation += input_section->vma;
+ }
+
+ if (check_dynamic_reloc != NULL)
+ {
+ bfd_boolean skip;
+
+ if (! ((*check_dynamic_reloc)
+ (flaginfo->info, input_bfd, input_section, h,
+ (void *) 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 && ! flaginfo->info->shared)
+ {
+ const char *name;
+
+ if (h != NULL)
+ name = h->root.root.string;
+ else
+ name = strings + GET_WORD (input_bfd, syms[r_index].e_strx);
+ if (! ((*flaginfo->info->callbacks->undefined_symbol)
+ (flaginfo->info, name, input_bfd, input_section,
+ r_addr, TRUE)))
+ 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 = NULL;
+ else if (r_extern)
+ name = strings + GET_WORD (input_bfd,
+ syms[r_index].e_strx);
+ else
+ {
+ asection *s;
+
+ s = aout_reloc_type_to_section (input_bfd, r_type);
+ name = bfd_section_name (input_bfd, s);
+ }
+ if (! ((*flaginfo->info->callbacks->reloc_overflow)
+ (flaginfo->info, (h ? &h->root : NULL), name,
+ howto->name, (bfd_vma) 0, input_bfd,
+ input_section, r_addr)))
+ return FALSE;
+ }
+ break;
+ }
+ }
+ }
+
+ return TRUE;
+}
+
+/* Link an a.out section into the output file. */
+
+static bfd_boolean
+aout_link_input_section (struct aout_final_link_info *flaginfo,
+ bfd *input_bfd,
+ asection *input_section,
+ file_ptr *reloff_ptr,
+ bfd_size_type rel_size)
+{
+ bfd_size_type input_size;
+ void * relocs;
+
+ /* Get the section contents. */
+ input_size = input_section->size;
+ if (! bfd_get_section_contents (input_bfd, input_section,
+ (void *) flaginfo->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 = flaginfo->relocs;
+ if (rel_size > 0)
+ {
+ if (bfd_seek (input_bfd, input_section->rel_filepos, SEEK_SET) != 0
+ || bfd_bread (relocs, rel_size, input_bfd) != rel_size)
+ return FALSE;
+ }
+ }
+
+ /* Relocate the section contents. */
+ if (! pdp11_aout_link_input_section (flaginfo, input_bfd, input_section,
+ (bfd_byte *) relocs,
+ rel_size, flaginfo->contents))
+ return FALSE;
+
+ /* Write out the section contents. */
+ if (! bfd_set_section_contents (flaginfo->output_bfd,
+ input_section->output_section,
+ (void *) flaginfo->contents,
+ (file_ptr) input_section->output_offset,
+ input_size))
+ return FALSE;
+
+ /* If we are producing relocatable output, the relocs were
+ modified, and we now write them out. */
+ if (flaginfo->info->relocatable && rel_size > 0)
+ {
+ if (bfd_seek (flaginfo->output_bfd, *reloff_ptr, SEEK_SET) != 0)
+ return FALSE;
+ if (bfd_bwrite (relocs, rel_size, flaginfo->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 (flaginfo->output_bfd)
+ && (reloff_ptr != &flaginfo->treloff
+ || (*reloff_ptr
+ <= obj_datasec (flaginfo->output_bfd)->rel_filepos)));
+ }
+
+ return TRUE;
+}
+
+/* Link an a.out input BFD into the output file. */
+
+static bfd_boolean
+aout_link_input_bfd (struct aout_final_link_info *flaginfo, bfd *input_bfd)
+{
+ 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)
+ (flaginfo->info, input_bfd));
+
+ /* Get the symbols. We probably have them already, unless
+ flaginfo->info->keep_memory is FALSE. */
+ if (! aout_get_external_symbols (input_bfd))
+ return FALSE;
+
+ /* Write out the symbols and get a map of the new indices. The map
+ is placed into flaginfo->symbol_map. */
+ if (! aout_link_write_symbols (flaginfo, 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 (flaginfo, input_bfd,
+ obj_textsec (input_bfd),
+ &flaginfo->treloff,
+ exec_hdr (input_bfd)->a_trsize))
+ return FALSE;
+ }
+ if (obj_datasec (input_bfd)->linker_mark)
+ {
+ if (! aout_link_input_section (flaginfo, input_bfd,
+ obj_datasec (input_bfd),
+ &flaginfo->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 (! flaginfo->info->keep_memory)
+ {
+ if (! aout_link_free_symbols (input_bfd))
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/* 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. */
+
+bfd_boolean
+NAME (aout, final_link) (bfd *abfd,
+ struct bfd_link_info *info,
+ void (*callback) (bfd *, file_ptr *, file_ptr *, file_ptr *))
+{
+ struct aout_final_link_info aout_info;
+ bfd_boolean includes_hash_initialized = FALSE;
+ bfd *sub;
+ bfd_size_type trsize, drsize;
+ bfd_size_type max_contents_size;
+ bfd_size_type max_relocs_size;
+ bfd_size_type max_sym_count;
+ bfd_size_type text_size;
+ file_ptr text_end;
+ struct bfd_link_order *p;
+ asection *o;
+ bfd_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,
+ sizeof (struct aout_link_includes_entry),
+ 251))
+ goto error_return;
+ includes_hash_initialized = TRUE;
+
+ /* Figure out the largest section size. Also, if generating
+ relocatable 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->relocatable)
+ {
+ 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: relocatable 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 = obj_textsec (sub)->size;
+ if (sz > max_contents_size)
+ max_contents_size = sz;
+ sz = obj_datasec (sub)->size;
+ 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->relocatable)
+ {
+ if (obj_textsec (abfd) != NULL)
+ trsize += (_bfd_count_link_order_relocs (obj_textsec (abfd)
+ ->map_head.link_order)
+ * obj_reloc_entry_size (abfd));
+ if (obj_datasec (abfd) != NULL)
+ drsize += (_bfd_count_link_order_relocs (obj_datasec (abfd)
+ ->map_head.link_order)
+ * 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_malloc (max_contents_size);
+ aout_info.relocs = bfd_malloc (max_relocs_size);
+ aout_info.symbol_map = bfd_malloc (max_sym_count * sizeof (int *));
+ aout_info.output_syms = 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->root.root, &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 != 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->map_head.link_order; 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 != NULL; o = o->next)
+ {
+ for (p = o->map_head.link_order;
+ p != 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. */
+ bfd_hash_traverse (&info->hash->table,
+ aout_link_write_other_symbol,
+ &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 != NULL; o = o->next)
+ {
+ for (p = o->map_head.link_order;
+ p != 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,
+ (file_ptr) (obj_datasec (abfd)->filepos
+ + exec_hdr (abfd)->a_data
+ - 1),
+ SEEK_SET) != 0
+ || bfd_bwrite (&b, (bfd_size_type) 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;
+}
+
+/* Adjust and write out the symbols for an a.out file. Set the new
+ symbol indices into a symbol_map. */
+
+static bfd_boolean
+aout_link_write_symbols (struct aout_final_link_info *flaginfo, 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;
+ struct external_nlist *sym;
+ struct external_nlist *sym_end;
+ struct aout_link_hash_entry **sym_hash;
+ int *symbol_map;
+ bfd_boolean pass;
+ bfd_boolean skip_next;
+
+ output_bfd = flaginfo->output_bfd;
+ sym_count = obj_aout_external_sym_count (input_bfd);
+ strings = obj_aout_external_strings (input_bfd);
+ strip = flaginfo->info->strip;
+ discard = flaginfo->info->discard;
+ outsym = flaginfo->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 (flaginfo->info->keep_hash, input_bfd->filename,
+ FALSE, FALSE) != NULL)
+ && discard != discard_all)
+ {
+ H_PUT_8 (output_bfd, N_TEXT, outsym->e_type);
+ strtab_index = add_to_stringtab (output_bfd, flaginfo->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 = flaginfo->symbol_map;
+ memset (symbol_map, 0, (size_t) 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;
+ bfd_boolean skip;
+ asection *symsec;
+ bfd_vma val = 0;
+ bfd_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 = 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 != 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 != 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 (flaginfo->info->keep_hash, name, FALSE, FALSE)
+ == NULL)
+ skip = TRUE;
+ break;
+ case strip_all:
+ skip = TRUE;
+ break;
+ }
+ if (skip)
+ {
+ if (h != 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 == 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 == 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 != 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 != 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:
+ case discard_sec_merge:
+ 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 = 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 (*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 = ! flaginfo->info->keep_memory;
+ incl_entry = aout_link_includes_lookup (&flaginfo->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 = bfd_hash_allocate (&flaginfo->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 = 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. */
+ H_PUT_8 (output_bfd, type, outsym->e_type);
+ copy = FALSE;
+ if (! flaginfo->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 != NULL)
+ name = h->root.root.string;
+ else
+ copy = TRUE;
+ }
+ strtab_index = add_to_stringtab (output_bfd, flaginfo->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 > flaginfo->output_syms)
+ {
+ bfd_size_type size;
+
+ if (bfd_seek (output_bfd, flaginfo->symoff, SEEK_SET) != 0)
+ return FALSE;
+ size = outsym - flaginfo->output_syms;
+ size *= EXTERNAL_NLIST_SIZE;
+ if (bfd_bwrite ((void *) flaginfo->output_syms, size, output_bfd) != size)
+ return FALSE;
+ flaginfo->symoff += size;
+ }
+
+ return TRUE;
+}
+
+/* Write out a symbol that was not associated with an a.out input
+ object. */
+
+static bfd_vma
+bfd_getp32 (const void *p)
+{
+ const bfd_byte *addr = p;
+ unsigned long v;
+
+ v = (unsigned long) addr[1] << 24;
+ v |= (unsigned long) addr[0] << 16;
+ v |= (unsigned long) addr[3] << 8;
+ v |= (unsigned long) addr[2];
+ return v;
+}
+
+#define COERCE32(x) (((bfd_signed_vma) (x) ^ 0x80000000) - 0x80000000)
+
+static bfd_signed_vma
+bfd_getp_signed_32 (const void *p)
+{
+ const bfd_byte *addr = p;
+ unsigned long v;
+
+ v = (unsigned long) addr[1] << 24;
+ v |= (unsigned long) addr[0] << 16;
+ v |= (unsigned long) addr[3] << 8;
+ v |= (unsigned long) addr[2];
+ return COERCE32 (v);
+}
+
+static void
+bfd_putp32 (bfd_vma data, void *p)
+{
+ bfd_byte *addr = p;
+
+ addr[0] = (data >> 16) & 0xff;
+ addr[1] = (data >> 24) & 0xff;
+ addr[2] = (data >> 0) & 0xff;
+ addr[3] = (data >> 8) & 0xff;
+}
+
+const bfd_target MY (vec) =
+{
+ TARGETNAME, /* 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),
+ (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. */
+ 0, /* match priority. */
+ bfd_getl64, bfd_getl_signed_64, bfd_putl64,
+ bfd_getp32, bfd_getp_signed_32, bfd_putp32,
+ bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* Data. */
+ bfd_getl64, bfd_getl_signed_64, bfd_putl64,
+ bfd_getp32, bfd_getp_signed_32, bfd_putp32,
+ bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* Headers. */
+ {_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),
+
+ /* Alternative_target. */
+ NULL,
+
+ (void *) MY_backend_data
+};
diff --git a/bfd/pe-arm-wince.c b/bfd/pe-arm-wince.c
new file mode 100644
index 0000000..dcfccb3
--- /dev/null
+++ b/bfd/pe-arm-wince.c
@@ -0,0 +1,45 @@
+/* BFD back-end for ARM WINCE PE files.
+ Copyright (C) 2006-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#define TARGET_UNDERSCORE 0
+#define USER_LABEL_PREFIX ""
+
+#define TARGET_LITTLE_SYM arm_pe_wince_le_vec
+#define TARGET_LITTLE_NAME "pe-arm-wince-little"
+#define TARGET_BIG_SYM arm_pe_wince_be_vec
+#define TARGET_BIG_NAME "pe-arm-wince-big"
+
+#define bfd_arm_allocate_interworking_sections \
+ bfd_arm_wince_pe_allocate_interworking_sections
+#define bfd_arm_get_bfd_for_interworking \
+ bfd_arm_wince_pe_get_bfd_for_interworking
+#define bfd_arm_process_before_allocation \
+ bfd_arm_wince_pe_process_before_allocation
+
+#define LOCAL_LABEL_PREFIX "."
+
+#include "sysdep.h"
+#include "bfd.h"
+
+#undef bfd_pe_print_pdata
+#define bfd_pe_print_pdata _bfd_pe_print_ce_compressed_pdata
+
+#include "pe-arm.c"
+
diff --git a/bfd/pe-arm.c b/bfd/pe-arm.c
new file mode 100644
index 0000000..136fbf5
--- /dev/null
+++ b/bfd/pe-arm.c
@@ -0,0 +1,67 @@
+/* BFD back-end for ARM PECOFF files.
+ Copyright (C) 1995-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+
+/* Do this before including bfd.h, so we prototype the right functions. */
+
+#ifndef bfd_arm_allocate_interworking_sections
+#define bfd_arm_allocate_interworking_sections \
+ bfd_armpe_allocate_interworking_sections
+#define bfd_arm_get_bfd_for_interworking \
+ bfd_armpe_get_bfd_for_interworking
+#define bfd_arm_process_before_allocation \
+ bfd_armpe_process_before_allocation
+#endif
+
+#include "sysdep.h"
+#include "bfd.h"
+
+#ifndef TARGET_LITTLE_SYM
+#define TARGET_LITTLE_SYM arm_pe_le_vec
+#define TARGET_LITTLE_NAME "pe-arm-little"
+#define TARGET_BIG_SYM arm_pe_be_vec
+#define TARGET_BIG_NAME "pe-arm-big"
+#endif
+
+#define COFF_WITH_PE
+#define PCRELOFFSET TRUE
+#define COFF_LONG_SECTION_NAMES
+
+#define COFF_SECTION_ALIGNMENT_ENTRIES \
+{ COFF_SECTION_NAME_EXACT_MATCH (".bss"), \
+ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 2 }, \
+{ COFF_SECTION_NAME_EXACT_MATCH (".data"), \
+ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 2 }, \
+{ COFF_SECTION_NAME_EXACT_MATCH (".rdata"), \
+ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 2 }, \
+{ COFF_SECTION_NAME_EXACT_MATCH (".text"), \
+ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 2 }, \
+{ COFF_SECTION_NAME_PARTIAL_MATCH (".idata"), \
+ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 2 }, \
+{ COFF_SECTION_NAME_EXACT_MATCH (".pdata"), \
+ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 2 }, \
+{ COFF_SECTION_NAME_PARTIAL_MATCH (".debug"), \
+ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 0 }, \
+{ COFF_SECTION_NAME_PARTIAL_MATCH (".zdebug"), \
+ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 0 }, \
+{ COFF_SECTION_NAME_PARTIAL_MATCH (".gnu.linkonce.wi."), \
+ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 0 }
+
+#include "coff-arm.c"
diff --git a/bfd/pe-i386.c b/bfd/pe-i386.c
new file mode 100644
index 0000000..5f3789c
--- /dev/null
+++ b/bfd/pe-i386.c
@@ -0,0 +1,45 @@
+/* BFD back-end for Intel 386 PECOFF files.
+ Copyright (C) 1995-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+
+#define TARGET_SYM i386_pe_vec
+#define TARGET_NAME "pe-i386"
+#define COFF_WITH_PE
+#define PCRELOFFSET TRUE
+#define TARGET_UNDERSCORE '_'
+#define COFF_LONG_SECTION_NAMES
+#define COFF_SUPPORT_GNU_LINKONCE
+#define COFF_LONG_FILENAMES
+
+#define COFF_SECTION_ALIGNMENT_ENTRIES \
+{ COFF_SECTION_NAME_PARTIAL_MATCH (".idata"), \
+ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 2 }, \
+{ COFF_SECTION_NAME_EXACT_MATCH (".pdata"), \
+ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 2 }, \
+{ COFF_SECTION_NAME_PARTIAL_MATCH (".debug"), \
+ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 0 }, \
+{ COFF_SECTION_NAME_PARTIAL_MATCH (".zdebug"), \
+ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 0 }, \
+{ COFF_SECTION_NAME_PARTIAL_MATCH (".gnu.linkonce.wi."), \
+ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 0 }
+
+#include "coff-i386.c"
diff --git a/bfd/pe-mcore.c b/bfd/pe-mcore.c
new file mode 100644
index 0000000..f9b9d34
--- /dev/null
+++ b/bfd/pe-mcore.c
@@ -0,0 +1,41 @@
+/* BFD back-end for MCore PECOFF files.
+ Copyright (C) 1999-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+
+#ifndef TARGET_BIG_SYM
+#define TARGET_BIG_SYM mcore_pe_be_vec
+#define TARGET_BIG_NAME "pe-mcore-big"
+#define TARGET_LITTLE_SYM mcore_pe_le_vec
+#define TARGET_LITTLE_NAME "pe-mcore-little"
+#endif
+
+#define COFF_WITH_PE
+#define PCRELOFFSET TRUE
+#define COFF_LONG_SECTION_NAMES
+
+#define MCORE_PE
+
+#ifndef bfd_pe_print_pdata
+#define bfd_pe_print_pdata NULL
+#endif
+
+#include "coff-mcore.c"
diff --git a/bfd/pe-mips.c b/bfd/pe-mips.c
new file mode 100644
index 0000000..57ec51f
--- /dev/null
+++ b/bfd/pe-mips.c
@@ -0,0 +1,922 @@
+/* BFD back-end for MIPS PE COFF files.
+ Copyright (C) 1990-2014 Free Software Foundation, Inc.
+ Modified from coff-i386.c by DJ Delorie, dj@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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#define COFF_WITH_PE
+/* pei-mips.c may have defined this to default off (0) before
+ including this file, so don't redefine if that's the case.
+ Otherwise we're generating objects, not executable images,
+ so we want to define it to default on. */
+#ifndef COFF_LONG_SECTION_NAMES
+#define COFF_LONG_SECTION_NAMES
+#endif /* COFF_LONG_SECTION_NAMES */
+#define PCRELOFFSET TRUE
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+#include "coff/mipspe.h"
+#include "coff/internal.h"
+#include "coff/pe.h"
+#include "libcoff.h"
+
+#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 mips 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 relocatable 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_mips_reloc (bfd *abfd,
+ arelent *reloc_entry,
+ asymbol *symbol,
+ void * data,
+ asection *input_section ATTRIBUTE_UNUSED,
+ bfd *output_bfd,
+ char **error_message ATTRIBUTE_UNUSED)
+{
+ symvalue diff;
+
+ if (output_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
+ relocatable 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->rightshift)) & 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, (bfd_vma) x, addr);
+ }
+ break;
+
+ case 2:
+ {
+ long x = bfd_get_32 (abfd, addr);
+
+ DOIT (x);
+ bfd_put_32 (abfd, (bfd_vma) 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 bfd_boolean
+in_reloc_p (bfd * abfd ATTRIBUTE_UNUSED, reloc_howto_type *howto)
+{
+ return ! howto->pc_relative && howto->type != MIPS_R_RVA;
+}
+#endif
+
+#ifndef PCRELOFFSET
+#define PCRELOFFSET FALSE
+#endif
+
+static reloc_howto_type 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_ABSOLUTE, /* 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. */
+ coff_mips_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. */
+ coff_mips_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. */
+ coff_mips_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. */
+ coff_mips_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. */
+ coff_mips_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. */
+ coff_mips_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. */
+ coff_mips_reloc, /* Special_function. */
+ "LITERAL", /* Name. */
+ TRUE, /* Partial_inplace. */
+ 0xffff, /* Src_mask. */
+ 0xffff, /* Dst_mask. */
+ FALSE), /* Pcrel_offset. */
+
+ EMPTY_HOWTO (8),
+ EMPTY_HOWTO (9),
+ EMPTY_HOWTO (10),
+ EMPTY_HOWTO (11),
+ EMPTY_HOWTO (12),
+ EMPTY_HOWTO (13),
+ EMPTY_HOWTO (14),
+ EMPTY_HOWTO (15),
+ EMPTY_HOWTO (16),
+ EMPTY_HOWTO (17),
+ EMPTY_HOWTO (18),
+ EMPTY_HOWTO (19),
+ EMPTY_HOWTO (20),
+ EMPTY_HOWTO (21),
+ EMPTY_HOWTO (22),
+ EMPTY_HOWTO (23),
+ EMPTY_HOWTO (24),
+ EMPTY_HOWTO (25),
+ EMPTY_HOWTO (26),
+ EMPTY_HOWTO (27),
+ EMPTY_HOWTO (28),
+ EMPTY_HOWTO (29),
+ EMPTY_HOWTO (30),
+ EMPTY_HOWTO (31),
+ EMPTY_HOWTO (32),
+ EMPTY_HOWTO (33),
+ HOWTO (MIPS_R_RVA, /* 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_mips_reloc, /* Special_function. */
+ "rva32", /* Name. */
+ TRUE, /* Partial_inplace. */
+ 0xffffffff, /* Src_mask. */
+ 0xffffffff, /* Dst_mask. */
+ FALSE), /* Pcrel_offset. */
+ EMPTY_HOWTO (35),
+ EMPTY_HOWTO (36),
+ HOWTO (MIPS_R_PAIR, /* 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_mips_reloc, /* Special_function. */
+ "PAIR", /* Name. */
+ TRUE, /* Partial_inplace. */
+ 0xffffffff, /* Src_mask. */
+ 0xffffffff, /* Dst_mask. */
+ FALSE), /* Pcrel_offset. */
+};
+
+#define NUM_HOWTOS (sizeof (howto_table) / sizeof (howto_table[0]))
+
+/* Turn a howto into a reloc nunmber. */
+
+#define SELECT_RELOC(x, howto) { x.r_type = howto->type; }
+#define BADMAG(x) MIPSBADMAG (x)
+
+/* Customize coffcode.h. */
+#define MIPS 1
+
+#define RTYPE2HOWTO(cache_ptr, dst) \
+ (cache_ptr)->howto = howto_table + (dst)->r_type;
+
+/* 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 = 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 != 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 != NULL) \
+ cache_ptr->addend = - (ptr->section->vma + ptr->value); \
+ else \
+ cache_ptr->addend = 0; \
+ if (ptr && reloc.r_type < NUM_HOWTOS \
+ && howto_table[reloc.r_type].pc_relative) \
+ cache_ptr->addend += asect->vma; \
+ }
+
+/* Convert an rtype to howto for the COFF backend linker. */
+
+static reloc_howto_type *
+coff_mips_rtype_to_howto (bfd *abfd ATTRIBUTE_UNUSED,
+ 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
+ relocatable 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 == MIPS_R_RVA)
+ *addendp -= pe_data (sec->output_section->owner)->pe_opthdr.ImageBase;
+#endif
+
+ return howto;
+}
+
+#define coff_rtype_to_howto coff_mips_rtype_to_howto
+#define coff_bfd_reloc_type_lookup coff_mips_reloc_type_lookup
+#define coff_bfd_reloc_name_lookup coff_mips_reloc_name_lookup
+
+/* Get the howto structure for a generic reloc type. */
+
+static reloc_howto_type *
+coff_mips_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ 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_GPREL16:
+ mips_type = MIPS_R_GPREL;
+ break;
+ case BFD_RELOC_MIPS_LITERAL:
+ mips_type = MIPS_R_LITERAL;
+ break;
+ case BFD_RELOC_RVA:
+ mips_type = MIPS_R_RVA;
+ break;
+ default:
+ return NULL;
+ }
+
+ return & howto_table [mips_type];
+}
+
+static reloc_howto_type *
+coff_mips_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ const char *r_name)
+{
+ unsigned int i;
+
+ for (i = 0; i < NUM_HOWTOS; i++)
+ if (howto_table[i].name != NULL
+ && strcasecmp (howto_table[i].name, r_name) == 0)
+ return &howto_table[i];
+
+ return NULL;
+}
+
+static void
+mips_swap_reloc_in (bfd * abfd, void * src, void * dst)
+{
+ static struct internal_reloc pair_prev;
+ RELOC *reloc_src = (RELOC *) src;
+ struct internal_reloc *reloc_dst = (struct internal_reloc *) dst;
+
+ reloc_dst->r_vaddr = H_GET_32 (abfd, reloc_src->r_vaddr);
+ reloc_dst->r_symndx = H_GET_S32 (abfd, reloc_src->r_symndx);
+ reloc_dst->r_type = H_GET_16 (abfd, reloc_src->r_type);
+ reloc_dst->r_size = 0;
+ reloc_dst->r_extern = 0;
+ reloc_dst->r_offset = 0;
+
+ switch (reloc_dst->r_type)
+ {
+ case MIPS_R_REFHI:
+ pair_prev = *reloc_dst;
+ break;
+ case MIPS_R_PAIR:
+ reloc_dst->r_offset = reloc_dst->r_symndx;
+ if (reloc_dst->r_offset & 0x8000)
+ reloc_dst->r_offset -= 0x10000;
+ reloc_dst->r_symndx = pair_prev.r_symndx;
+ break;
+ }
+}
+
+static unsigned int
+mips_swap_reloc_out (bfd * abfd, void * src, void * dst)
+{
+ static bfd_vma prev_addr = 0;
+ struct internal_reloc *reloc_src = (struct internal_reloc *)src;
+ struct external_reloc *reloc_dst = (struct external_reloc *)dst;
+
+ switch (reloc_src->r_type)
+ {
+ case MIPS_R_REFHI:
+ prev_addr = reloc_src->r_vaddr;
+ break;
+ case MIPS_R_REFLO:
+ if (reloc_src->r_vaddr == prev_addr)
+ {
+ /* FIXME: only slightly hackish. If we see a REFLO pointing to
+ the same address as a REFHI, we assume this is the matching
+ PAIR reloc and output it accordingly. The symndx is really
+ the low 16 bits of the addend */
+ H_PUT_32 (abfd, reloc_src->r_vaddr, reloc_dst->r_vaddr);
+ H_PUT_32 (abfd, reloc_src->r_symndx, reloc_dst->r_symndx);
+ H_PUT_16 (abfd, MIPS_R_PAIR, reloc_dst->r_type);
+ return RELSZ;
+ }
+ break;
+ }
+
+ H_PUT_32 (abfd, reloc_src->r_vaddr, reloc_dst->r_vaddr);
+ H_PUT_32 (abfd, reloc_src->r_symndx, reloc_dst->r_symndx);
+
+ H_PUT_16 (abfd, reloc_src->r_type, reloc_dst->r_type);
+ return RELSZ;
+}
+
+#define coff_swap_reloc_in mips_swap_reloc_in
+#define coff_swap_reloc_out mips_swap_reloc_out
+#define NO_COFF_RELOCS
+
+static bfd_boolean
+coff_pe_mips_relocate_section (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 *rel_end;
+ unsigned int i;
+
+ if (info->relocatable)
+ {
+ (*_bfd_error_handler)
+ (_("%B: `ld -r' not supported with PE MIPS objects\n"), input_bfd);
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+
+ BFD_ASSERT (input_bfd->xvec->byteorder
+ == output_bfd->xvec->byteorder);
+
+ rel = relocs;
+ rel_end = rel + input_section->reloc_count;
+
+ for (i = 0; rel < rel_end; rel++, i++)
+ {
+ long symndx;
+ struct coff_link_hash_entry *h;
+ struct internal_syment *sym;
+ bfd_vma addend = 0;
+ bfd_vma val, tmp, targ, src, low;
+ reloc_howto_type *howto;
+ unsigned char *mem = contents + rel->r_vaddr;
+
+ 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 relocatable 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 relocatable link,
+ then we should ignore the symbol value. */
+ if (howto->pc_relative && howto->pcrel_offset)
+ {
+ if (info->relocatable)
+ 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->relocatable)
+ {
+ if (! ((*info->callbacks->undefined_symbol)
+ (info, h->root.root.string, input_bfd, input_section,
+ rel->r_vaddr - input_section->vma, TRUE)))
+ return FALSE;
+ }
+ }
+
+ src = rel->r_vaddr + input_section->output_section->vma
+ + input_section->output_offset;
+
+ /* OK, at this point the following variables are set up:
+ src = VMA of the memory we're fixing up
+ mem = pointer to memory we're fixing up
+ val = VMA of what we need to refer to. */
+
+#define UI(x) (*_bfd_error_handler) (_("%B: unimplemented %s\n"), \
+ input_bfd, x); \
+ bfd_set_error (bfd_error_bad_value);
+
+ switch (rel->r_type)
+ {
+ case MIPS_R_ABSOLUTE:
+ /* Ignore these. */
+ break;
+
+ case MIPS_R_REFHALF:
+ UI ("refhalf");
+ break;
+
+ case MIPS_R_REFWORD:
+ tmp = bfd_get_32 (input_bfd, mem);
+ /* printf ("refword: src=%08x targ=%08x+%08x\n", src, tmp, val); */
+ tmp += val;
+ bfd_put_32 (input_bfd, tmp, mem);
+ break;
+
+ case MIPS_R_JMPADDR:
+ tmp = bfd_get_32 (input_bfd, mem);
+ targ = val + (tmp & 0x03ffffff) * 4;
+ if ((src & 0xf0000000) != (targ & 0xf0000000))
+ {
+ (*_bfd_error_handler) (_("%B: jump too far away\n"), input_bfd);
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+ tmp &= 0xfc000000;
+ tmp |= (targ / 4) & 0x3ffffff;
+ bfd_put_32 (input_bfd, tmp, mem);
+ break;
+
+ case MIPS_R_REFHI:
+ tmp = bfd_get_32 (input_bfd, mem);
+ switch (rel[1].r_type)
+ {
+ case MIPS_R_PAIR:
+ /* MS PE object */
+ targ = val + rel[1].r_offset + ((tmp & 0xffff) << 16);
+ break;
+ case MIPS_R_REFLO:
+ /* GNU COFF object */
+ low = bfd_get_32 (input_bfd, contents + rel[1].r_vaddr);
+ low &= 0xffff;
+ if (low & 0x8000)
+ low -= 0x10000;
+ targ = val + low + ((tmp & 0xffff) << 16);
+ break;
+ default:
+ (*_bfd_error_handler) (_("%B: bad pair/reflo after refhi\n"),
+ input_bfd);
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+ tmp &= 0xffff0000;
+ tmp |= (targ >> 16) & 0xffff;
+ bfd_put_32 (input_bfd, tmp, mem);
+ break;
+
+ case MIPS_R_REFLO:
+ tmp = bfd_get_32 (input_bfd, mem);
+ targ = val + (tmp & 0xffff);
+ /* printf ("refword: src=%08x targ=%08x\n", src, targ); */
+ tmp &= 0xffff0000;
+ tmp |= targ & 0xffff;
+ bfd_put_32 (input_bfd, tmp, mem);
+ break;
+
+ case MIPS_R_GPREL:
+ case MIPS_R_LITERAL:
+ UI ("gprel");
+ break;
+
+ case MIPS_R_SECTION:
+ UI ("section");
+ break;
+
+ case MIPS_R_SECREL:
+ UI ("secrel");
+ break;
+
+ case MIPS_R_SECRELLO:
+ UI ("secrello");
+ break;
+
+ case MIPS_R_SECRELHI:
+ UI ("secrelhi");
+ break;
+
+ case MIPS_R_RVA:
+ tmp = bfd_get_32 (input_bfd, mem);
+ /* printf ("rva: src=%08x targ=%08x+%08x\n", src, tmp, val); */
+ tmp += val
+ - pe_data (input_section->output_section->owner)->pe_opthdr.ImageBase;
+ bfd_put_32 (input_bfd, tmp, mem);
+ break;
+
+ case MIPS_R_PAIR:
+ /* ignore these */
+ break;
+ }
+ }
+
+ return TRUE;
+}
+
+#define coff_relocate_section coff_pe_mips_relocate_section
+
+#ifdef TARGET_UNDERSCORE
+
+/* If mips 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 bfd_boolean
+coff_mips_is_local_label_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_mips_is_local_label_name
+
+#endif /* TARGET_UNDERSCORE */
+
+#define COFF_NO_HACK_SCNHDR_SIZE
+
+#ifndef bfd_pe_print_pdata
+#define bfd_pe_print_pdata NULL
+#endif
+
+#include "coffcode.h"
+
+const bfd_target
+#ifdef TARGET_SYM
+ TARGET_SYM =
+#else
+ mips_pe_le_vec =
+#endif
+{
+#ifdef TARGET_NAME
+ TARGET_NAME,
+#else
+ "pe-mips", /* 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. */
+ 0, /* match priority. */
+
+ 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, /* Headers. */
+
+ /* 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),
+
+ NULL,
+
+ COFF_SWAP_TABLE
+};
diff --git a/bfd/pe-ppc.c b/bfd/pe-ppc.c
new file mode 100644
index 0000000..ea082b9
--- /dev/null
+++ b/bfd/pe-ppc.c
@@ -0,0 +1,47 @@
+/* BFD back-end for PowerPC PECOFF files.
+ Copyright (C) 1995-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, 51 Franklin Street - Fifth Floor,
+ Boston, MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+
+#define E_FILENMLEN 18
+
+#define PPC_PE
+
+#define TARGET_LITTLE_SYM powerpc_pe_le_vec
+#define TARGET_LITTLE_NAME "pe-powerpcle"
+
+#define TARGET_BIG_SYM powerpc_pe_vec
+#define TARGET_BIG_NAME "pe-powerpc"
+
+#define COFF_WITH_PE
+
+#define COFF_LONG_SECTION_NAMES
+
+/* FIXME: verify PCRELOFFSET is always false */
+
+/* FIXME: This target no longer works. Search for POWERPC_LE_PE in
+ coff-ppc.c and peigen.c. */
+
+#ifndef bfd_pe_print_pdata
+#define bfd_pe_print_pdata NULL
+#endif
+
+#include "coff-ppc.c"
diff --git a/bfd/pe-sh.c b/bfd/pe-sh.c
new file mode 100644
index 0000000..9516a85
--- /dev/null
+++ b/bfd/pe-sh.c
@@ -0,0 +1,31 @@
+/* BFD back-end for SH PECOFF files.
+ Copyright (C) 1995-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+
+#define TARGET_SHL_SYM sh_pe_le_vec
+#define TARGET_SHL_NAME "pe-shl"
+#define COFF_WITH_PE
+#define PCRELOFFSET TRUE
+#define TARGET_UNDERSCORE '_'
+#define COFF_LONG_SECTION_NAMES
+
+#include "coff-sh.c"
diff --git a/bfd/pe-x86_64.c b/bfd/pe-x86_64.c
new file mode 100644
index 0000000..673a544
--- /dev/null
+++ b/bfd/pe-x86_64.c
@@ -0,0 +1,114 @@
+/* BFD back-end for Intel/AMD x86_64 PECOFF files.
+ Copyright (C) 2006-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA.
+
+ Written by Kai Tietz, OneVision Software GmbH&CoKg. */
+
+#include "sysdep.h"
+#include "bfd.h"
+
+#define TARGET_SYM x86_64_pe_vec
+#define TARGET_NAME "pe-x86-64"
+#define COFF_WITH_PE
+#define COFF_WITH_pex64
+#define COFF_WITH_PE_BIGOBJ
+#define PCRELOFFSET TRUE
+#if defined (USE_MINGW64_LEADING_UNDERSCORES)
+#define TARGET_UNDERSCORE '_'
+#else
+#define TARGET_UNDERSCORE 0
+#endif
+#define COFF_LONG_SECTION_NAMES
+#define COFF_SUPPORT_GNU_LINKONCE
+#define COFF_LONG_FILENAMES
+
+#define COFF_SECTION_ALIGNMENT_ENTRIES \
+{ COFF_SECTION_NAME_EXACT_MATCH (".bss"), \
+ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 4 }, \
+{ COFF_SECTION_NAME_PARTIAL_MATCH (".data"), \
+ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 4 }, \
+{ COFF_SECTION_NAME_PARTIAL_MATCH (".rdata"), \
+ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 4 }, \
+{ COFF_SECTION_NAME_PARTIAL_MATCH (".text"), \
+ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 4 }, \
+{ COFF_SECTION_NAME_PARTIAL_MATCH (".idata"), \
+ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 2 }, \
+{ COFF_SECTION_NAME_EXACT_MATCH (".pdata"), \
+ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 2 }, \
+{ COFF_SECTION_NAME_PARTIAL_MATCH (".debug"), \
+ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 0 }, \
+{ COFF_SECTION_NAME_PARTIAL_MATCH (".zdebug"), \
+ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 0 }, \
+{ COFF_SECTION_NAME_PARTIAL_MATCH (".gnu.linkonce.wi."), \
+ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 0 }
+
+#include "coff-x86_64.c"
+
+/* Entry for big object files. */
+
+const bfd_target
+x86_64_pe_be_vec =
+{
+ "pe-bigobj-x86-64", /* 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 | BFD_COMPRESS | BFD_DECOMPRESS),
+
+ (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC /* Section flags. */
+ | SEC_LINK_ONCE | SEC_LINK_DUPLICATES | SEC_READONLY | SEC_DEBUGGING
+ | SEC_CODE | SEC_DATA | SEC_EXCLUDE ),
+
+ TARGET_UNDERSCORE, /* Leading underscore. */
+ '/', /* Ar_pad_char. */
+ 15, /* Ar_max_namelen. */
+ 0, /* match priority. */
+
+ 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, amd64coff_object_p, /* BFD_check_format. */
+ bfd_generic_archive_p, amd64coff_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),
+
+ NULL,
+
+ &bigobj_swap_table
+};
diff --git a/bfd/peXXigen.c b/bfd/peXXigen.c
new file mode 100644
index 0000000..13e39e4
--- /dev/null
+++ b/bfd/peXXigen.c
@@ -0,0 +1,4470 @@
+/* Support for the generic parts of PE/PEI; the common executable parts.
+ Copyright (C) 1995-2014 Free Software Foundation, Inc.
+ Written by Cygnus Solutions.
+
+ This file is part of BFD, the Binary File Descriptor library.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+
+/* Most of this hacked by Steve Chamberlain <sac@cygnus.com>.
+
+ PE/PEI rearrangement (and code added): Donn Terry
+ Softway Systems, Inc. */
+
+/* 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. */
+
+/* This expands into COFF_WITH_pe, COFF_WITH_pep, or COFF_WITH_pex64
+ depending on whether we're compiling for straight PE or PE+. */
+#define COFF_WITH_XX
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+#include "coff/internal.h"
+#include "bfdver.h"
+#ifdef HAVE_WCHAR_H
+#include <wchar.h>
+#endif
+
+/* NOTE: it's strange to be including an architecture specific header
+ in what's supposed to be general (to PE/PEI) code. However, that's
+ where the definitions are, and they don't vary per architecture
+ within PE/PEI, so we get them from there. FIXME: The lack of
+ variance is an assumption which may prove to be incorrect if new
+ PE/PEI targets are created. */
+#if defined COFF_WITH_pex64
+# include "coff/x86_64.h"
+#elif defined COFF_WITH_pep
+# include "coff/ia64.h"
+#else
+# include "coff/i386.h"
+#endif
+
+#include "coff/pe.h"
+#include "libcoff.h"
+#include "libpei.h"
+#include "safe-ctype.h"
+
+#if defined COFF_WITH_pep || defined COFF_WITH_pex64
+# undef AOUTSZ
+# define AOUTSZ PEPAOUTSZ
+# define PEAOUTHDR PEPAOUTHDR
+#endif
+
+#define HighBitSet(val) ((val) & 0x80000000)
+#define SetHighBit(val) ((val) | 0x80000000)
+#define WithoutHighBit(val) ((val) & 0x7fffffff)
+
+/* FIXME: This file has various tests of POWERPC_LE_PE. Those tests
+ worked when the code was in peicode.h, but no longer work now that
+ the code is in peigen.c. PowerPC NT is said to be dead. If
+ anybody wants to revive the code, you will have to figure out how
+ to handle those issues. */
+
+void
+_bfd_XXi_swap_sym_in (bfd * abfd, void * ext1, void * 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 = H_GET_32 (abfd, ext->e.e.e_offset);
+ }
+ else
+ memcpy (in->_n._n_name, ext->e.e_name, SYMNMLEN);
+
+ in->n_value = H_GET_32 (abfd, ext->e_value);
+ in->n_scnum = H_GET_16 (abfd, ext->e_scnum);
+
+ if (sizeof (ext->e_type) == 2)
+ in->n_type = H_GET_16 (abfd, ext->e_type);
+ else
+ in->n_type = H_GET_32 (abfd, ext->e_type);
+
+ in->n_sclass = H_GET_8 (abfd, ext->e_sclass);
+ in->n_numaux = H_GET_8 (abfd, ext->e_numaux);
+
+#ifndef STRICT_PE_FORMAT
+ /* This is for Gnu-created DLLs. */
+
+ /* 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)
+ {
+ char namebuf[SYMNMLEN + 1];
+ const char *name = NULL;
+
+ in->n_value = 0x0;
+
+ /* Create synthetic empty sections as needed. DJ */
+ if (in->n_scnum == 0)
+ {
+ asection *sec;
+
+ name = _bfd_coff_internal_syment_name (abfd, in, namebuf);
+ if (name == NULL)
+ {
+ _bfd_error_handler (_("%B: unable to find name for empty section"),
+ abfd);
+ bfd_set_error (bfd_error_invalid_target);
+ return;
+ }
+
+ sec = bfd_get_section_by_name (abfd, name);
+ if (sec != NULL)
+ in->n_scnum = sec->target_index;
+ }
+
+ if (in->n_scnum == 0)
+ {
+ int unused_section_number = 0;
+ asection *sec;
+ flagword flags;
+
+ for (sec = abfd->sections; sec; sec = sec->next)
+ if (unused_section_number <= sec->target_index)
+ unused_section_number = sec->target_index + 1;
+
+ if (name == namebuf)
+ {
+ name = (const char *) bfd_alloc (abfd, strlen (namebuf) + 1);
+ if (name == NULL)
+ {
+ _bfd_error_handler (_("%B: out of memory creating name for empty section"),
+ abfd);
+ return;
+ }
+ strcpy ((char *) name, namebuf);
+ }
+
+ flags = SEC_HAS_CONTENTS | SEC_ALLOC | SEC_DATA | SEC_LOAD;
+ sec = bfd_make_section_anyway_with_flags (abfd, name, flags);
+ if (sec == NULL)
+ {
+ _bfd_error_handler (_("%B: unable to create fake empty section"),
+ abfd);
+ return;
+ }
+
+ sec->vma = 0;
+ sec->lma = 0;
+ sec->size = 0;
+ sec->filepos = 0;
+ sec->rel_filepos = 0;
+ sec->reloc_count = 0;
+ sec->line_filepos = 0;
+ sec->lineno_count = 0;
+ sec->userdata = NULL;
+ sec->next = NULL;
+ sec->alignment_power = 2;
+
+ sec->target_index = unused_section_number;
+
+ in->n_scnum = unused_section_number;
+ }
+ in->n_sclass = C_STAT;
+ }
+#endif
+
+#ifdef coff_swap_sym_in_hook
+ /* This won't work in peigen.c, but since it's for PPC PE, it's not
+ worth fixing. */
+ coff_swap_sym_in_hook (abfd, ext1, in1);
+#endif
+}
+
+static bfd_boolean
+abs_finder (bfd * abfd ATTRIBUTE_UNUSED, asection * sec, void * data)
+{
+ bfd_vma abs_val = * (bfd_vma *) data;
+
+ return (sec->vma <= abs_val) && ((sec->vma + (1ULL << 32)) > abs_val);
+}
+
+unsigned int
+_bfd_XXi_swap_sym_out (bfd * abfd, void * inp, void * extp)
+{
+ struct internal_syment *in = (struct internal_syment *) inp;
+ SYMENT *ext = (SYMENT *) extp;
+
+ if (in->_n._n_name[0] == 0)
+ {
+ H_PUT_32 (abfd, 0, ext->e.e.e_zeroes);
+ H_PUT_32 (abfd, in->_n._n_n._n_offset, ext->e.e.e_offset);
+ }
+ else
+ memcpy (ext->e.e_name, in->_n._n_name, SYMNMLEN);
+
+ /* The PE32 and PE32+ formats only use 4 bytes to hold the value of a
+ symbol. This is a problem on 64-bit targets where we can generate
+ absolute symbols with values >= 1^32. We try to work around this
+ problem by finding a section whose base address is sufficient to
+ reduce the absolute value to < 1^32, and then transforming the
+ symbol into a section relative symbol. This of course is a hack. */
+ if (sizeof (in->n_value) > 4
+ /* The strange computation of the shift amount is here in order to
+ avoid a compile time warning about the comparison always being
+ false. It does not matter if this test fails to work as expected
+ as the worst that can happen is that some absolute symbols are
+ needlessly converted into section relative symbols. */
+ && in->n_value > ((1ULL << (sizeof (in->n_value) > 4 ? 32 : 31)) - 1)
+ && in->n_scnum == -1)
+ {
+ asection * sec;
+
+ sec = bfd_sections_find_if (abfd, abs_finder, & in->n_value);
+ if (sec)
+ {
+ in->n_value -= sec->vma;
+ in->n_scnum = sec->target_index;
+ }
+ /* else: FIXME: The value is outside the range of any section. This
+ happens for __image_base__ and __ImageBase and maybe some other
+ symbols as well. We should find a way to handle these values. */
+ }
+
+ H_PUT_32 (abfd, in->n_value, ext->e_value);
+ H_PUT_16 (abfd, in->n_scnum, ext->e_scnum);
+
+ if (sizeof (ext->e_type) == 2)
+ H_PUT_16 (abfd, in->n_type, ext->e_type);
+ else
+ H_PUT_32 (abfd, in->n_type, ext->e_type);
+
+ H_PUT_8 (abfd, in->n_sclass, ext->e_sclass);
+ H_PUT_8 (abfd, in->n_numaux, ext->e_numaux);
+
+ return SYMESZ;
+}
+
+void
+_bfd_XXi_swap_aux_in (bfd * abfd,
+ void * ext1,
+ int type,
+ int in_class,
+ int indx ATTRIBUTE_UNUSED,
+ int numaux ATTRIBUTE_UNUSED,
+ void * in1)
+{
+ AUXENT *ext = (AUXENT *) ext1;
+ union internal_auxent *in = (union internal_auxent *) in1;
+
+ /* PR 17521: Make sure that all fields in the aux structure
+ are initialised. */
+ memset (in, 0, sizeof * in);
+ switch (in_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 = H_GET_32 (abfd, ext->x_file.x_n.x_offset);
+ }
+ else
+ memcpy (in->x_file.x_fname, ext->x_file.x_fname, FILNMLEN);
+ return;
+
+ case C_STAT:
+ case C_LEAFSTAT:
+ 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 = H_GET_32 (abfd, ext->x_scn.x_checksum);
+ in->x_scn.x_associated = H_GET_16 (abfd, ext->x_scn.x_associated);
+ in->x_scn.x_comdat = H_GET_8 (abfd, ext->x_scn.x_comdat);
+ return;
+ }
+ break;
+ }
+
+ in->x_sym.x_tagndx.l = H_GET_32 (abfd, ext->x_sym.x_tagndx);
+ in->x_sym.x_tvndx = H_GET_16 (abfd, ext->x_sym.x_tvndx);
+
+ if (in_class == C_BLOCK || in_class == C_FCN || ISFCN (type)
+ || ISTAG (in_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
+ {
+ in->x_sym.x_fcnary.x_ary.x_dimen[0] =
+ H_GET_16 (abfd, ext->x_sym.x_fcnary.x_ary.x_dimen[0]);
+ in->x_sym.x_fcnary.x_ary.x_dimen[1] =
+ H_GET_16 (abfd, ext->x_sym.x_fcnary.x_ary.x_dimen[1]);
+ in->x_sym.x_fcnary.x_ary.x_dimen[2] =
+ H_GET_16 (abfd, ext->x_sym.x_fcnary.x_ary.x_dimen[2]);
+ in->x_sym.x_fcnary.x_ary.x_dimen[3] =
+ H_GET_16 (abfd, ext->x_sym.x_fcnary.x_ary.x_dimen[3]);
+ }
+
+ if (ISFCN (type))
+ {
+ in->x_sym.x_misc.x_fsize = H_GET_32 (abfd, 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);
+ }
+}
+
+unsigned int
+_bfd_XXi_swap_aux_out (bfd * abfd,
+ void * inp,
+ int type,
+ int in_class,
+ int indx ATTRIBUTE_UNUSED,
+ int numaux ATTRIBUTE_UNUSED,
+ void * extp)
+{
+ union internal_auxent *in = (union internal_auxent *) inp;
+ AUXENT *ext = (AUXENT *) extp;
+
+ memset (ext, 0, AUXESZ);
+
+ switch (in_class)
+ {
+ case C_FILE:
+ if (in->x_file.x_fname[0] == 0)
+ {
+ H_PUT_32 (abfd, 0, ext->x_file.x_n.x_zeroes);
+ H_PUT_32 (abfd, in->x_file.x_n.x_offset, ext->x_file.x_n.x_offset);
+ }
+ else
+ memcpy (ext->x_file.x_fname, in->x_file.x_fname, FILNMLEN);
+
+ return AUXESZ;
+
+ case C_STAT:
+ case C_LEAFSTAT:
+ 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);
+ H_PUT_32 (abfd, in->x_scn.x_checksum, ext->x_scn.x_checksum);
+ H_PUT_16 (abfd, in->x_scn.x_associated, ext->x_scn.x_associated);
+ H_PUT_8 (abfd, in->x_scn.x_comdat, ext->x_scn.x_comdat);
+ return AUXESZ;
+ }
+ break;
+ }
+
+ H_PUT_32 (abfd, in->x_sym.x_tagndx.l, ext->x_sym.x_tagndx);
+ H_PUT_16 (abfd, in->x_sym.x_tvndx, ext->x_sym.x_tvndx);
+
+ if (in_class == C_BLOCK || in_class == C_FCN || ISFCN (type)
+ || ISTAG (in_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
+ {
+ H_PUT_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[0],
+ ext->x_sym.x_fcnary.x_ary.x_dimen[0]);
+ H_PUT_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[1],
+ ext->x_sym.x_fcnary.x_ary.x_dimen[1]);
+ H_PUT_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[2],
+ ext->x_sym.x_fcnary.x_ary.x_dimen[2]);
+ H_PUT_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[3],
+ ext->x_sym.x_fcnary.x_ary.x_dimen[3]);
+ }
+
+ if (ISFCN (type))
+ H_PUT_32 (abfd, in->x_sym.x_misc.x_fsize, 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;
+}
+
+void
+_bfd_XXi_swap_lineno_in (bfd * abfd, void * ext1, void * in1)
+{
+ LINENO *ext = (LINENO *) ext1;
+ struct internal_lineno *in = (struct internal_lineno *) in1;
+
+ in->l_addr.l_symndx = H_GET_32 (abfd, ext->l_addr.l_symndx);
+ in->l_lnno = GET_LINENO_LNNO (abfd, ext);
+}
+
+unsigned int
+_bfd_XXi_swap_lineno_out (bfd * abfd, void * inp, void * outp)
+{
+ struct internal_lineno *in = (struct internal_lineno *) inp;
+ struct external_lineno *ext = (struct external_lineno *) outp;
+ H_PUT_32 (abfd, in->l_addr.l_symndx, ext->l_addr.l_symndx);
+
+ PUT_LINENO_LNNO (abfd, in->l_lnno, ext);
+ return LINESZ;
+}
+
+void
+_bfd_XXi_swap_aouthdr_in (bfd * abfd,
+ void * aouthdr_ext1,
+ void * aouthdr_int1)
+{
+ PEAOUTHDR * src = (PEAOUTHDR *) aouthdr_ext1;
+ AOUTHDR * aouthdr_ext = (AOUTHDR *) aouthdr_ext1;
+ struct internal_aouthdr *aouthdr_int
+ = (struct internal_aouthdr *) aouthdr_int1;
+ struct internal_extra_pe_aouthdr *a = &aouthdr_int->pe;
+
+ aouthdr_int->magic = H_GET_16 (abfd, aouthdr_ext->magic);
+ aouthdr_int->vstamp = H_GET_16 (abfd, aouthdr_ext->vstamp);
+ aouthdr_int->tsize = GET_AOUTHDR_TSIZE (abfd, aouthdr_ext->tsize);
+ aouthdr_int->dsize = GET_AOUTHDR_DSIZE (abfd, aouthdr_ext->dsize);
+ aouthdr_int->bsize = GET_AOUTHDR_BSIZE (abfd, aouthdr_ext->bsize);
+ aouthdr_int->entry = GET_AOUTHDR_ENTRY (abfd, aouthdr_ext->entry);
+ aouthdr_int->text_start =
+ GET_AOUTHDR_TEXT_START (abfd, aouthdr_ext->text_start);
+
+#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64)
+ /* PE32+ does not have data_start member! */
+ aouthdr_int->data_start =
+ GET_AOUTHDR_DATA_START (abfd, aouthdr_ext->data_start);
+ a->BaseOfData = aouthdr_int->data_start;
+#endif
+
+ a->Magic = aouthdr_int->magic;
+ a->MajorLinkerVersion = H_GET_8 (abfd, aouthdr_ext->vstamp);
+ a->MinorLinkerVersion = H_GET_8 (abfd, aouthdr_ext->vstamp + 1);
+ a->SizeOfCode = aouthdr_int->tsize ;
+ a->SizeOfInitializedData = aouthdr_int->dsize ;
+ a->SizeOfUninitializedData = aouthdr_int->bsize ;
+ a->AddressOfEntryPoint = aouthdr_int->entry;
+ a->BaseOfCode = aouthdr_int->text_start;
+ a->ImageBase = GET_OPTHDR_IMAGE_BASE (abfd, src->ImageBase);
+ a->SectionAlignment = H_GET_32 (abfd, src->SectionAlignment);
+ a->FileAlignment = H_GET_32 (abfd, src->FileAlignment);
+ a->MajorOperatingSystemVersion =
+ H_GET_16 (abfd, src->MajorOperatingSystemVersion);
+ a->MinorOperatingSystemVersion =
+ H_GET_16 (abfd, src->MinorOperatingSystemVersion);
+ a->MajorImageVersion = H_GET_16 (abfd, src->MajorImageVersion);
+ a->MinorImageVersion = H_GET_16 (abfd, src->MinorImageVersion);
+ a->MajorSubsystemVersion = H_GET_16 (abfd, src->MajorSubsystemVersion);
+ a->MinorSubsystemVersion = H_GET_16 (abfd, src->MinorSubsystemVersion);
+ a->Reserved1 = H_GET_32 (abfd, src->Reserved1);
+ a->SizeOfImage = H_GET_32 (abfd, src->SizeOfImage);
+ a->SizeOfHeaders = H_GET_32 (abfd, src->SizeOfHeaders);
+ a->CheckSum = H_GET_32 (abfd, src->CheckSum);
+ a->Subsystem = H_GET_16 (abfd, src->Subsystem);
+ a->DllCharacteristics = H_GET_16 (abfd, src->DllCharacteristics);
+ a->SizeOfStackReserve =
+ GET_OPTHDR_SIZE_OF_STACK_RESERVE (abfd, src->SizeOfStackReserve);
+ a->SizeOfStackCommit =
+ GET_OPTHDR_SIZE_OF_STACK_COMMIT (abfd, src->SizeOfStackCommit);
+ a->SizeOfHeapReserve =
+ GET_OPTHDR_SIZE_OF_HEAP_RESERVE (abfd, src->SizeOfHeapReserve);
+ a->SizeOfHeapCommit =
+ GET_OPTHDR_SIZE_OF_HEAP_COMMIT (abfd, src->SizeOfHeapCommit);
+ a->LoaderFlags = H_GET_32 (abfd, src->LoaderFlags);
+ a->NumberOfRvaAndSizes = H_GET_32 (abfd, src->NumberOfRvaAndSizes);
+
+ {
+ int idx;
+
+ /* PR 17512: Corrupt PE binaries can cause seg-faults. */
+ if (a->NumberOfRvaAndSizes > IMAGE_NUMBEROF_DIRECTORY_ENTRIES)
+ {
+ (*_bfd_error_handler)
+ (_("%B: aout header specifies an invalid number of data-directory entries: %d"),
+ abfd, a->NumberOfRvaAndSizes);
+ /* Paranoia: If the number is corrupt, then assume that the
+ actual entries themselves might be corrupt as well. */
+ a->NumberOfRvaAndSizes = 0;
+ }
+
+ for (idx = 0; idx < a->NumberOfRvaAndSizes; idx++)
+ {
+ /* If data directory is empty, rva also should be 0. */
+ int size =
+ H_GET_32 (abfd, src->DataDirectory[idx][1]);
+
+ a->DataDirectory[idx].Size = size;
+
+ if (size)
+ a->DataDirectory[idx].VirtualAddress =
+ H_GET_32 (abfd, src->DataDirectory[idx][0]);
+ else
+ a->DataDirectory[idx].VirtualAddress = 0;
+ }
+
+ while (idx < IMAGE_NUMBEROF_DIRECTORY_ENTRIES)
+ {
+ a->DataDirectory[idx].Size = 0;
+ a->DataDirectory[idx].VirtualAddress = 0;
+ idx ++;
+ }
+ }
+
+ if (aouthdr_int->entry)
+ {
+ aouthdr_int->entry += a->ImageBase;
+#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64)
+ aouthdr_int->entry &= 0xffffffff;
+#endif
+ }
+
+ if (aouthdr_int->tsize)
+ {
+ aouthdr_int->text_start += a->ImageBase;
+#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64)
+ aouthdr_int->text_start &= 0xffffffff;
+#endif
+ }
+
+#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64)
+ /* PE32+ does not have data_start member! */
+ if (aouthdr_int->dsize)
+ {
+ aouthdr_int->data_start += a->ImageBase;
+ aouthdr_int->data_start &= 0xffffffff;
+ }
+#endif
+
+#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[PE_IMPORT_ADDRESS_TABLE].VirtualAddress;
+ thunk_size = a->DataDirectory[PE_IMPORT_ADDRESS_TABLE].Size;
+ import_table_size = a->DataDirectory[PE_IMPORT_TABLE].Size;
+#endif
+}
+
+/* A support function for below. */
+
+static void
+add_data_entry (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))
+ {
+ /* If data directory is empty, rva also should be 0. */
+ int size = pei_section_data (abfd, sec)->virt_size;
+ aout->DataDirectory[idx].Size = size;
+
+ if (size)
+ {
+ aout->DataDirectory[idx].VirtualAddress =
+ (sec->vma - base) & 0xffffffff;
+ sec->flags |= SEC_DATA;
+ }
+ }
+}
+
+unsigned int
+_bfd_XXi_swap_aouthdr_out (bfd * abfd, void * in, void * out)
+{
+ struct internal_aouthdr *aouthdr_in = (struct internal_aouthdr *) in;
+ pe_data_type *pe = pe_data (abfd);
+ struct internal_extra_pe_aouthdr *extra = &pe->pe_opthdr;
+ PEAOUTHDR *aouthdr_out = (PEAOUTHDR *) out;
+ bfd_vma sa, fa, ib;
+ IMAGE_DATA_DIRECTORY idata2, idata5, tls;
+
+ sa = extra->SectionAlignment;
+ fa = extra->FileAlignment;
+ ib = extra->ImageBase;
+
+ idata2 = pe->pe_opthdr.DataDirectory[PE_IMPORT_TABLE];
+ idata5 = pe->pe_opthdr.DataDirectory[PE_IMPORT_ADDRESS_TABLE];
+ tls = pe->pe_opthdr.DataDirectory[PE_TLS_TABLE];
+
+ if (aouthdr_in->tsize)
+ {
+ aouthdr_in->text_start -= ib;
+#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64)
+ aouthdr_in->text_start &= 0xffffffff;
+#endif
+ }
+
+ if (aouthdr_in->dsize)
+ {
+ aouthdr_in->data_start -= ib;
+#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64)
+ aouthdr_in->data_start &= 0xffffffff;
+#endif
+ }
+
+ if (aouthdr_in->entry)
+ {
+ aouthdr_in->entry -= ib;
+#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64)
+ aouthdr_in->entry &= 0xffffffff;
+#endif
+ }
+
+#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;
+
+ add_data_entry (abfd, extra, 0, ".edata", ib);
+ add_data_entry (abfd, extra, 2, ".rsrc", ib);
+ add_data_entry (abfd, extra, 3, ".pdata", ib);
+
+ /* In theory we do not need to call add_data_entry for .idata$2 or
+ .idata$5. It will be done in bfd_coff_final_link where all the
+ required information is available. If however, we are not going
+ to perform a final link, eg because we have been invoked by objcopy
+ or strip, then we need to make sure that these Data Directory
+ entries are initialised properly.
+
+ So - we copy the input values into the output values, and then, if
+ a final link is going to be performed, it can overwrite them. */
+ extra->DataDirectory[PE_IMPORT_TABLE] = idata2;
+ extra->DataDirectory[PE_IMPORT_ADDRESS_TABLE] = idata5;
+ extra->DataDirectory[PE_TLS_TABLE] = tls;
+
+ if (extra->DataDirectory[PE_IMPORT_TABLE].VirtualAddress == 0)
+ /* Until other .idata fixes are made (pending patch), the entry for
+ .idata is needed for backwards compatibility. FIXME. */
+ add_data_entry (abfd, extra, 1, ".idata", ib);
+
+ /* For some reason, the virtual size (which is what's set by
+ add_data_entry) for .reloc is not the same as the size recorded
+ in this slot by MSVC; it doesn't seem to cause problems (so far),
+ but since it's the best we've got, use it. It does do the right
+ thing for .pdata. */
+ if (pe->has_reloc_section)
+ add_data_entry (abfd, extra, 5, ".reloc", ib);
+
+ {
+ asection *sec;
+ bfd_vma hsize = 0;
+ bfd_vma dsize = 0;
+ bfd_vma isize = 0;
+ bfd_vma tsize = 0;
+
+ for (sec = abfd->sections; sec; sec = sec->next)
+ {
+ int rounded = FA (sec->size);
+
+ /* The first non-zero section filepos is the header size.
+ Sections without contents will have a filepos of 0. */
+ if (hsize == 0)
+ hsize = sec->filepos;
+ if (sec->flags & SEC_DATA)
+ dsize += rounded;
+ if (sec->flags & SEC_CODE)
+ tsize += rounded;
+ /* The image size is the total VIRTUAL size (which is what is
+ in the virt_size field). Files have been seen (from MSVC
+ 5.0 link.exe) where the file size of the .data segment is
+ quite small compared to the virtual size. Without this
+ fix, strip munges the file.
+
+ FIXME: We need to handle holes between sections, which may
+ happpen when we covert from another format. We just use
+ the virtual address and virtual size of the last section
+ for the image size. */
+ if (coff_section_data (abfd, sec) != NULL
+ && pei_section_data (abfd, sec) != NULL)
+ isize = (sec->vma - extra->ImageBase
+ + SA (FA (pei_section_data (abfd, sec)->virt_size)));
+ }
+
+ aouthdr_in->dsize = dsize;
+ aouthdr_in->tsize = tsize;
+ extra->SizeOfHeaders = hsize;
+ extra->SizeOfImage = isize;
+ }
+
+ H_PUT_16 (abfd, aouthdr_in->magic, aouthdr_out->standard.magic);
+
+/* e.g. 219510000 is linker version 2.19 */
+#define LINKER_VERSION ((short) (BFD_VERSION / 1000000))
+
+ /* This piece of magic sets the "linker version" field to
+ LINKER_VERSION. */
+ H_PUT_16 (abfd, (LINKER_VERSION / 100 + (LINKER_VERSION % 100) * 256),
+ aouthdr_out->standard.vstamp);
+
+ PUT_AOUTHDR_TSIZE (abfd, aouthdr_in->tsize, aouthdr_out->standard.tsize);
+ PUT_AOUTHDR_DSIZE (abfd, aouthdr_in->dsize, aouthdr_out->standard.dsize);
+ PUT_AOUTHDR_BSIZE (abfd, aouthdr_in->bsize, aouthdr_out->standard.bsize);
+ PUT_AOUTHDR_ENTRY (abfd, aouthdr_in->entry, aouthdr_out->standard.entry);
+ PUT_AOUTHDR_TEXT_START (abfd, aouthdr_in->text_start,
+ aouthdr_out->standard.text_start);
+
+#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64)
+ /* PE32+ does not have data_start member! */
+ PUT_AOUTHDR_DATA_START (abfd, aouthdr_in->data_start,
+ aouthdr_out->standard.data_start);
+#endif
+
+ PUT_OPTHDR_IMAGE_BASE (abfd, extra->ImageBase, aouthdr_out->ImageBase);
+ H_PUT_32 (abfd, extra->SectionAlignment, aouthdr_out->SectionAlignment);
+ H_PUT_32 (abfd, extra->FileAlignment, aouthdr_out->FileAlignment);
+ H_PUT_16 (abfd, extra->MajorOperatingSystemVersion,
+ aouthdr_out->MajorOperatingSystemVersion);
+ H_PUT_16 (abfd, extra->MinorOperatingSystemVersion,
+ aouthdr_out->MinorOperatingSystemVersion);
+ H_PUT_16 (abfd, extra->MajorImageVersion, aouthdr_out->MajorImageVersion);
+ H_PUT_16 (abfd, extra->MinorImageVersion, aouthdr_out->MinorImageVersion);
+ H_PUT_16 (abfd, extra->MajorSubsystemVersion,
+ aouthdr_out->MajorSubsystemVersion);
+ H_PUT_16 (abfd, extra->MinorSubsystemVersion,
+ aouthdr_out->MinorSubsystemVersion);
+ H_PUT_32 (abfd, extra->Reserved1, aouthdr_out->Reserved1);
+ H_PUT_32 (abfd, extra->SizeOfImage, aouthdr_out->SizeOfImage);
+ H_PUT_32 (abfd, extra->SizeOfHeaders, aouthdr_out->SizeOfHeaders);
+ H_PUT_32 (abfd, extra->CheckSum, aouthdr_out->CheckSum);
+ H_PUT_16 (abfd, extra->Subsystem, aouthdr_out->Subsystem);
+ H_PUT_16 (abfd, extra->DllCharacteristics, aouthdr_out->DllCharacteristics);
+ PUT_OPTHDR_SIZE_OF_STACK_RESERVE (abfd, extra->SizeOfStackReserve,
+ aouthdr_out->SizeOfStackReserve);
+ PUT_OPTHDR_SIZE_OF_STACK_COMMIT (abfd, extra->SizeOfStackCommit,
+ aouthdr_out->SizeOfStackCommit);
+ PUT_OPTHDR_SIZE_OF_HEAP_RESERVE (abfd, extra->SizeOfHeapReserve,
+ aouthdr_out->SizeOfHeapReserve);
+ PUT_OPTHDR_SIZE_OF_HEAP_COMMIT (abfd, extra->SizeOfHeapCommit,
+ aouthdr_out->SizeOfHeapCommit);
+ H_PUT_32 (abfd, extra->LoaderFlags, aouthdr_out->LoaderFlags);
+ H_PUT_32 (abfd, extra->NumberOfRvaAndSizes,
+ aouthdr_out->NumberOfRvaAndSizes);
+ {
+ int idx;
+
+ for (idx = 0; idx < IMAGE_NUMBEROF_DIRECTORY_ENTRIES; idx++)
+ {
+ H_PUT_32 (abfd, extra->DataDirectory[idx].VirtualAddress,
+ aouthdr_out->DataDirectory[idx][0]);
+ H_PUT_32 (abfd, extra->DataDirectory[idx].Size,
+ aouthdr_out->DataDirectory[idx][1]);
+ }
+ }
+
+ return AOUTSZ;
+}
+
+unsigned int
+_bfd_XXi_only_swap_filehdr_out (bfd * abfd, void * in, void * out)
+{
+ int idx;
+ struct internal_filehdr *filehdr_in = (struct internal_filehdr *) in;
+ struct external_PEI_filehdr *filehdr_out = (struct external_PEI_filehdr *) out;
+
+ if (pe_data (abfd)->has_reloc_section
+ || pe_data (abfd)->dont_strip_reloc)
+ 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;
+
+ H_PUT_16 (abfd, filehdr_in->f_magic, filehdr_out->f_magic);
+ H_PUT_16 (abfd, filehdr_in->f_nscns, filehdr_out->f_nscns);
+
+ /* Only use a real timestamp if the option was chosen. */
+ if ((pe_data (abfd)->insert_timestamp))
+ H_PUT_32 (abfd, time (0), filehdr_out->f_timdat);
+
+ PUT_FILEHDR_SYMPTR (abfd, filehdr_in->f_symptr,
+ filehdr_out->f_symptr);
+ H_PUT_32 (abfd, filehdr_in->f_nsyms, filehdr_out->f_nsyms);
+ H_PUT_16 (abfd, filehdr_in->f_opthdr, filehdr_out->f_opthdr);
+ H_PUT_16 (abfd, filehdr_in->f_flags, 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. */
+ H_PUT_16 (abfd, filehdr_in->pe.e_magic, filehdr_out->e_magic);
+ H_PUT_16 (abfd, filehdr_in->pe.e_cblp, filehdr_out->e_cblp);
+ H_PUT_16 (abfd, filehdr_in->pe.e_cp, filehdr_out->e_cp);
+ H_PUT_16 (abfd, filehdr_in->pe.e_crlc, filehdr_out->e_crlc);
+ H_PUT_16 (abfd, filehdr_in->pe.e_cparhdr, filehdr_out->e_cparhdr);
+ H_PUT_16 (abfd, filehdr_in->pe.e_minalloc, filehdr_out->e_minalloc);
+ H_PUT_16 (abfd, filehdr_in->pe.e_maxalloc, filehdr_out->e_maxalloc);
+ H_PUT_16 (abfd, filehdr_in->pe.e_ss, filehdr_out->e_ss);
+ H_PUT_16 (abfd, filehdr_in->pe.e_sp, filehdr_out->e_sp);
+ H_PUT_16 (abfd, filehdr_in->pe.e_csum, filehdr_out->e_csum);
+ H_PUT_16 (abfd, filehdr_in->pe.e_ip, filehdr_out->e_ip);
+ H_PUT_16 (abfd, filehdr_in->pe.e_cs, filehdr_out->e_cs);
+ H_PUT_16 (abfd, filehdr_in->pe.e_lfarlc, filehdr_out->e_lfarlc);
+ H_PUT_16 (abfd, filehdr_in->pe.e_ovno, filehdr_out->e_ovno);
+
+ for (idx = 0; idx < 4; idx++)
+ H_PUT_16 (abfd, filehdr_in->pe.e_res[idx], filehdr_out->e_res[idx]);
+
+ H_PUT_16 (abfd, filehdr_in->pe.e_oemid, filehdr_out->e_oemid);
+ H_PUT_16 (abfd, filehdr_in->pe.e_oeminfo, filehdr_out->e_oeminfo);
+
+ for (idx = 0; idx < 10; idx++)
+ H_PUT_16 (abfd, filehdr_in->pe.e_res2[idx], filehdr_out->e_res2[idx]);
+
+ H_PUT_32 (abfd, filehdr_in->pe.e_lfanew, filehdr_out->e_lfanew);
+
+ for (idx = 0; idx < 16; idx++)
+ H_PUT_32 (abfd, filehdr_in->pe.dos_message[idx],
+ filehdr_out->dos_message[idx]);
+
+ /* Also put in the NT signature. */
+ H_PUT_32 (abfd, filehdr_in->pe.nt_signature, filehdr_out->nt_signature);
+
+ return FILHSZ;
+}
+
+unsigned int
+_bfd_XX_only_swap_filehdr_out (bfd * abfd, void * in, void * out)
+{
+ struct internal_filehdr *filehdr_in = (struct internal_filehdr *) in;
+ FILHDR *filehdr_out = (FILHDR *) out;
+
+ H_PUT_16 (abfd, filehdr_in->f_magic, filehdr_out->f_magic);
+ H_PUT_16 (abfd, filehdr_in->f_nscns, filehdr_out->f_nscns);
+ H_PUT_32 (abfd, filehdr_in->f_timdat, filehdr_out->f_timdat);
+ PUT_FILEHDR_SYMPTR (abfd, filehdr_in->f_symptr, filehdr_out->f_symptr);
+ H_PUT_32 (abfd, filehdr_in->f_nsyms, filehdr_out->f_nsyms);
+ H_PUT_16 (abfd, filehdr_in->f_opthdr, filehdr_out->f_opthdr);
+ H_PUT_16 (abfd, filehdr_in->f_flags, filehdr_out->f_flags);
+
+ return FILHSZ;
+}
+
+unsigned int
+_bfd_XXi_swap_scnhdr_out (bfd * abfd, void * in, void * 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),
+ scnhdr_ext->s_vaddr);
+
+ /* NT wants the size data to be rounded up to the next
+ NT_FILE_ALIGNMENT, but zero if it has no content (as in .bss,
+ sometimes). */
+ if ((scnhdr_int->s_flags & IMAGE_SCN_CNT_UNINITIALIZED_DATA) != 0)
+ {
+ if (bfd_pei_p (abfd))
+ {
+ ps = scnhdr_int->s_size;
+ ss = 0;
+ }
+ else
+ {
+ ps = 0;
+ ss = scnhdr_int->s_size;
+ }
+ }
+ else
+ {
+ if (bfd_pei_p (abfd))
+ ps = scnhdr_int->s_paddr;
+ else
+ ps = 0;
+
+ ss = scnhdr_int->s_size;
+ }
+
+ PUT_SCNHDR_SIZE (abfd, ss,
+ scnhdr_ext->s_size);
+
+ /* s_paddr in PE is really the virtual size. */
+ PUT_SCNHDR_PADDR (abfd, ps, scnhdr_ext->s_paddr);
+
+ PUT_SCNHDR_SCNPTR (abfd, scnhdr_int->s_scnptr,
+ scnhdr_ext->s_scnptr);
+ PUT_SCNHDR_RELPTR (abfd, scnhdr_int->s_relptr,
+ scnhdr_ext->s_relptr);
+ PUT_SCNHDR_LNNOPTR (abfd, scnhdr_int->s_lnnoptr,
+ scnhdr_ext->s_lnnoptr);
+
+ {
+ /* Extra flags must be set when dealing with PE. 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 and
+ ARM-WINCE. Although - how do we get the original alignment field
+ back ? */
+
+ typedef struct
+ {
+ const char * section_name;
+ unsigned long must_have;
+ }
+ pe_required_section_flags;
+
+ pe_required_section_flags known_sections [] =
+ {
+ { ".arch", IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_DISCARDABLE | IMAGE_SCN_ALIGN_8BYTES },
+ { ".bss", IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_UNINITIALIZED_DATA | IMAGE_SCN_MEM_WRITE },
+ { ".data", IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_WRITE },
+ { ".edata", IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_INITIALIZED_DATA },
+ { ".idata", IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_WRITE },
+ { ".pdata", IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_INITIALIZED_DATA },
+ { ".rdata", IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_INITIALIZED_DATA },
+ { ".reloc", IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_DISCARDABLE },
+ { ".rsrc", IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_WRITE },
+ { ".text" , IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_EXECUTE },
+ { ".tls", IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_WRITE },
+ { ".xdata", IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_INITIALIZED_DATA },
+ { NULL, 0}
+ };
+
+ pe_required_section_flags * p;
+
+ /* We have defaulted to adding the IMAGE_SCN_MEM_WRITE flag, but now
+ we know exactly what this specific section wants so we remove it
+ and then allow the must_have field to add it back in if necessary.
+ However, we don't remove IMAGE_SCN_MEM_WRITE flag from .text if the
+ default WP_TEXT file flag has been cleared. WP_TEXT may be cleared
+ by ld --enable-auto-import (if auto-import is actually needed),
+ by ld --omagic, or by obcopy --writable-text. */
+
+ for (p = known_sections; p->section_name; p++)
+ if (strcmp (scnhdr_int->s_name, p->section_name) == 0)
+ {
+ if (strcmp (scnhdr_int->s_name, ".text")
+ || (bfd_get_file_flags (abfd) & WP_TEXT))
+ scnhdr_int->s_flags &= ~IMAGE_SCN_MEM_WRITE;
+ scnhdr_int->s_flags |= p->must_have;
+ break;
+ }
+
+ H_PUT_32 (abfd, scnhdr_int->s_flags, scnhdr_ext->s_flags);
+ }
+
+ if (coff_data (abfd)->link_info
+ && ! coff_data (abfd)->link_info->relocatable
+ && ! coff_data (abfd)->link_info->shared
+ && strcmp (scnhdr_int->s_name, ".text") == 0)
+ {
+ /* By inference from looking at MS output, the 32 bit field
+ which is the combination of the number_of_relocs and
+ number_of_linenos is used for the line number count in
+ executables. A 16-bit field won't do for cc1. The MS
+ document says that the number of relocs is zero for
+ executables, but the 17-th bit has been observed to be there.
+ Overflow is not an issue: a 4G-line program will overflow a
+ bunch of other fields long before this! */
+ H_PUT_16 (abfd, (scnhdr_int->s_nlnno & 0xffff), scnhdr_ext->s_nlnno);
+ H_PUT_16 (abfd, (scnhdr_int->s_nlnno >> 16), scnhdr_ext->s_nreloc);
+ }
+ else
+ {
+ if (scnhdr_int->s_nlnno <= 0xffff)
+ H_PUT_16 (abfd, scnhdr_int->s_nlnno, 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);
+ H_PUT_16 (abfd, 0xffff, scnhdr_ext->s_nlnno);
+ ret = 0;
+ }
+
+ /* Although we could encode 0xffff relocs here, we do not, to be
+ consistent with other parts of bfd. Also it lets us warn, as
+ we should never see 0xffff here w/o having the overflow flag
+ set. */
+ if (scnhdr_int->s_nreloc < 0xffff)
+ H_PUT_16 (abfd, scnhdr_int->s_nreloc, scnhdr_ext->s_nreloc);
+ else
+ {
+ /* PE can deal with large #s of relocs, but not here. */
+ H_PUT_16 (abfd, 0xffff, scnhdr_ext->s_nreloc);
+ scnhdr_int->s_flags |= IMAGE_SCN_LNK_NRELOC_OVFL;
+ H_PUT_32 (abfd, scnhdr_int->s_flags, scnhdr_ext->s_flags);
+ }
+ }
+ return ret;
+}
+
+void
+_bfd_XXi_swap_debugdir_in (bfd * abfd, void * ext1, void * in1)
+{
+ struct external_IMAGE_DEBUG_DIRECTORY *ext = (struct external_IMAGE_DEBUG_DIRECTORY *) ext1;
+ struct internal_IMAGE_DEBUG_DIRECTORY *in = (struct internal_IMAGE_DEBUG_DIRECTORY *) in1;
+
+ in->Characteristics = H_GET_32(abfd, ext->Characteristics);
+ in->TimeDateStamp = H_GET_32(abfd, ext->TimeDateStamp);
+ in->MajorVersion = H_GET_16(abfd, ext->MajorVersion);
+ in->MinorVersion = H_GET_16(abfd, ext->MinorVersion);
+ in->Type = H_GET_32(abfd, ext->Type);
+ in->SizeOfData = H_GET_32(abfd, ext->SizeOfData);
+ in->AddressOfRawData = H_GET_32(abfd, ext->AddressOfRawData);
+ in->PointerToRawData = H_GET_32(abfd, ext->PointerToRawData);
+}
+
+unsigned int
+_bfd_XXi_swap_debugdir_out (bfd * abfd, void * inp, void * extp)
+{
+ struct external_IMAGE_DEBUG_DIRECTORY *ext = (struct external_IMAGE_DEBUG_DIRECTORY *) extp;
+ struct internal_IMAGE_DEBUG_DIRECTORY *in = (struct internal_IMAGE_DEBUG_DIRECTORY *) inp;
+
+ H_PUT_32(abfd, in->Characteristics, ext->Characteristics);
+ H_PUT_32(abfd, in->TimeDateStamp, ext->TimeDateStamp);
+ H_PUT_16(abfd, in->MajorVersion, ext->MajorVersion);
+ H_PUT_16(abfd, in->MinorVersion, ext->MinorVersion);
+ H_PUT_32(abfd, in->Type, ext->Type);
+ H_PUT_32(abfd, in->SizeOfData, ext->SizeOfData);
+ H_PUT_32(abfd, in->AddressOfRawData, ext->AddressOfRawData);
+ H_PUT_32(abfd, in->PointerToRawData, ext->PointerToRawData);
+
+ return sizeof (struct external_IMAGE_DEBUG_DIRECTORY);
+}
+
+static CODEVIEW_INFO *
+_bfd_XXi_slurp_codeview_record (bfd * abfd, file_ptr where, unsigned long length, CODEVIEW_INFO *cvinfo)
+{
+ char buffer[256+1];
+
+ if (bfd_seek (abfd, where, SEEK_SET) != 0)
+ return NULL;
+
+ if (bfd_bread (buffer, 256, abfd) < 4)
+ return NULL;
+
+ /* Ensure null termination of filename. */
+ buffer[256] = '\0';
+
+ cvinfo->CVSignature = H_GET_32(abfd, buffer);
+ cvinfo->Age = 0;
+
+ if ((cvinfo->CVSignature == CVINFO_PDB70_CVSIGNATURE)
+ && (length > sizeof (CV_INFO_PDB70)))
+ {
+ CV_INFO_PDB70 *cvinfo70 = (CV_INFO_PDB70 *)(buffer);
+
+ cvinfo->Age = H_GET_32(abfd, cvinfo70->Age);
+
+ /* A GUID consists of 4,2,2 byte values in little-endian order, followed
+ by 8 single bytes. Byte swap them so we can conveniently treat the GUID
+ as 16 bytes in big-endian order. */
+ bfd_putb32 (bfd_getl32 (cvinfo70->Signature), cvinfo->Signature);
+ bfd_putb16 (bfd_getl16 (&(cvinfo70->Signature[4])), &(cvinfo->Signature[4]));
+ bfd_putb16 (bfd_getl16 (&(cvinfo70->Signature[6])), &(cvinfo->Signature[6]));
+ memcpy (&(cvinfo->Signature[8]), &(cvinfo70->Signature[8]), 8);
+
+ cvinfo->SignatureLength = CV_INFO_SIGNATURE_LENGTH;
+ // cvinfo->PdbFileName = cvinfo70->PdbFileName;
+
+ return cvinfo;
+ }
+ else if ((cvinfo->CVSignature == CVINFO_PDB20_CVSIGNATURE)
+ && (length > sizeof (CV_INFO_PDB20)))
+ {
+ CV_INFO_PDB20 *cvinfo20 = (CV_INFO_PDB20 *)(buffer);
+ cvinfo->Age = H_GET_32(abfd, cvinfo20->Age);
+ memcpy (cvinfo->Signature, cvinfo20->Signature, 4);
+ cvinfo->SignatureLength = 4;
+ // cvinfo->PdbFileName = cvinfo20->PdbFileName;
+
+ return cvinfo;
+ }
+
+ return NULL;
+}
+
+unsigned int
+_bfd_XXi_write_codeview_record (bfd * abfd, file_ptr where, CODEVIEW_INFO *cvinfo)
+{
+ unsigned int size = sizeof (CV_INFO_PDB70) + 1;
+ CV_INFO_PDB70 *cvinfo70;
+ char buffer[size];
+
+ if (bfd_seek (abfd, where, SEEK_SET) != 0)
+ return 0;
+
+ cvinfo70 = (CV_INFO_PDB70 *) buffer;
+ H_PUT_32 (abfd, CVINFO_PDB70_CVSIGNATURE, cvinfo70->CvSignature);
+
+ /* Byte swap the GUID from 16 bytes in big-endian order to 4,2,2 byte values
+ in little-endian order, followed by 8 single bytes. */
+ bfd_putl32 (bfd_getb32 (cvinfo->Signature), cvinfo70->Signature);
+ bfd_putl16 (bfd_getb16 (&(cvinfo->Signature[4])), &(cvinfo70->Signature[4]));
+ bfd_putl16 (bfd_getb16 (&(cvinfo->Signature[6])), &(cvinfo70->Signature[6]));
+ memcpy (&(cvinfo70->Signature[8]), &(cvinfo->Signature[8]), 8);
+
+ H_PUT_32 (abfd, cvinfo->Age, cvinfo70->Age);
+ cvinfo70->PdbFileName[0] = '\0';
+
+ if (bfd_bwrite (buffer, size, abfd) != size)
+ return 0;
+
+ return size;
+}
+
+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_("Delay Import Directory"),
+ N_("CLR Runtime Header"),
+ N_("Reserved")
+};
+
+#ifdef POWERPC_LE_PE
+/* The code for the PPC really falls in the "architecture dependent"
+ category. However, it's not clear that anyone will ever care, so
+ we're ignoring the issue for now; if/when PPC matters, some of this
+ may need to go into peicode.h, or arguments passed to enable the
+ PPC- specific code. */
+#endif
+
+static bfd_boolean
+pe_print_idata (bfd * abfd, void * vfile)
+{
+ FILE *file = (FILE *) vfile;
+ bfd_byte *data;
+ asection *section;
+ bfd_signed_vma adj;
+
+#ifdef POWERPC_LE_PE
+ asection *rel_section = bfd_get_section_by_name (abfd, ".reldata");
+#endif
+
+ bfd_size_type datasize = 0;
+ bfd_size_type dataoff;
+ bfd_size_type i;
+ int onaline = 20;
+
+ pe_data_type *pe = pe_data (abfd);
+ struct internal_extra_pe_aouthdr *extra = &pe->pe_opthdr;
+
+ bfd_vma addr;
+
+ addr = extra->DataDirectory[PE_IMPORT_TABLE].VirtualAddress;
+
+ if (addr == 0 && extra->DataDirectory[PE_IMPORT_TABLE].Size == 0)
+ {
+ /* Maybe the extra header isn't there. Look for the section. */
+ section = bfd_get_section_by_name (abfd, ".idata");
+ if (section == NULL)
+ return TRUE;
+
+ addr = section->vma;
+ datasize = section->size;
+ if (datasize == 0)
+ return TRUE;
+ }
+ else
+ {
+ addr += extra->ImageBase;
+ for (section = abfd->sections; section != NULL; section = section->next)
+ {
+ datasize = section->size;
+ if (addr >= section->vma && addr < section->vma + datasize)
+ break;
+ }
+
+ if (section == NULL)
+ {
+ fprintf (file,
+ _("\nThere is an import table, but the section containing it could not be found\n"));
+ return TRUE;
+ }
+ else if (!(section->flags & SEC_HAS_CONTENTS))
+ {
+ fprintf (file,
+ _("\nThere is an import table in %s, but that section has no contents\n"),
+ section->name);
+ return TRUE;
+ }
+ }
+
+ fprintf (file, _("\nThere is an import table in %s at 0x%lx\n"),
+ section->name, (unsigned long) addr);
+
+ dataoff = addr - section->vma;
+
+#ifdef POWERPC_LE_PE
+ if (rel_section != 0 && rel_section->size != 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;
+ bfd_vma offset;
+
+ if (!bfd_malloc_and_get_section (abfd, rel_section, &data))
+ {
+ if (data != NULL)
+ free (data);
+ return FALSE;
+ }
+
+ offset = abfd->start_address - rel_section->vma;
+
+ if (offset >= rel_section->size || offset + 8 > rel_section->size)
+ {
+ if (data != NULL)
+ free (data);
+ return FALSE;
+ }
+
+ 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);
+ if (data != NULL)
+ free (data);
+ }
+ else
+ {
+ fprintf (file,
+ _("\nNo reldata section! Function descriptor not decoded.\n"));
+ }
+#endif
+
+ fprintf (file,
+ _("\nThe Import Tables (interpreted %s section contents)\n"),
+ section->name);
+ fprintf (file,
+ _("\
+ vma: Hint Time Forward DLL First\n\
+ Table Stamp Chain Name Thunk\n"));
+
+ /* Read the whole section. Some of the fields might be before dataoff. */
+ if (!bfd_malloc_and_get_section (abfd, section, &data))
+ {
+ if (data != NULL)
+ free (data);
+ return FALSE;
+ }
+
+ adj = section->vma - extra->ImageBase;
+
+ /* Print all image import descriptors. */
+ for (i = dataoff; i + onaline <= datasize; 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;
+
+ /* Print (i + extra->DataDirectory[PE_IMPORT_TABLE].VirtualAddress). */
+ fprintf (file, " %08lx\t", (unsigned long) (i + adj));
+ 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",
+ (unsigned long) hint_addr,
+ (unsigned long) time_stamp,
+ (unsigned long) forward_chain,
+ (unsigned long) dll_name,
+ (unsigned long) first_thunk);
+
+ if (hint_addr == 0 && first_thunk == 0)
+ break;
+
+ if (dll_name - adj >= section->size)
+ break;
+
+ dll = (char *) data + dll_name - adj;
+ /* PR 17512 file: 078-12277-0.004. */
+ bfd_size_type maxlen = (char *)(data + datasize) - dll - 1;
+ fprintf (file, _("\n\tDLL Name: %.*s\n"), (int) maxlen, dll);
+
+ if (hint_addr != 0)
+ {
+ bfd_byte *ft_data;
+ asection *ft_section;
+ bfd_vma ft_addr;
+ bfd_size_type ft_datasize;
+ int ft_idx;
+ int ft_allocated;
+
+ fprintf (file, _("\tvma: Hint/Ord Member-Name Bound-To\n"));
+
+ idx = hint_addr - adj;
+
+ ft_addr = first_thunk + extra->ImageBase;
+ ft_idx = first_thunk - adj;
+ ft_data = data + ft_idx;
+ ft_datasize = datasize - ft_idx;
+ ft_allocated = 0;
+
+ if (first_thunk != hint_addr)
+ {
+ /* Find the section which contains the first thunk. */
+ for (ft_section = abfd->sections;
+ ft_section != NULL;
+ ft_section = ft_section->next)
+ {
+ if (ft_addr >= ft_section->vma
+ && ft_addr < ft_section->vma + ft_section->size)
+ break;
+ }
+
+ if (ft_section == NULL)
+ {
+ fprintf (file,
+ _("\nThere is a first thunk, but the section containing it could not be found\n"));
+ continue;
+ }
+
+ /* Now check to see if this section is the same as our current
+ section. If it is not then we will have to load its data in. */
+ if (ft_section != section)
+ {
+ ft_idx = first_thunk - (ft_section->vma - extra->ImageBase);
+ ft_datasize = ft_section->size - ft_idx;
+ ft_data = (bfd_byte *) bfd_malloc (ft_datasize);
+ if (ft_data == NULL)
+ continue;
+
+ /* Read ft_datasize bytes starting at offset ft_idx. */
+ if (!bfd_get_section_contents (abfd, ft_section, ft_data,
+ (bfd_vma) ft_idx, ft_datasize))
+ {
+ free (ft_data);
+ continue;
+ }
+ ft_allocated = 1;
+ }
+ }
+
+ /* Print HintName vector entries. */
+#ifdef COFF_WITH_pex64
+ for (j = 0; idx + j + 8 <= datasize; j += 8)
+ {
+ bfd_size_type amt;
+ unsigned long member = bfd_get_32 (abfd, data + idx + j);
+ unsigned long member_high = bfd_get_32 (abfd, data + idx + j + 4);
+
+ if (!member && !member_high)
+ break;
+
+ amt = member - adj;
+
+ if (HighBitSet (member_high))
+ fprintf (file, "\t%lx%08lx\t %4lx%08lx <none>",
+ member_high, member,
+ WithoutHighBit (member_high), member);
+ /* PR binutils/17512: Handle corrupt PE data. */
+ else if (amt + 2 >= datasize)
+ fprintf (file, _("\t<corrupt: 0x%04lx>"), member);
+ else
+ {
+ int ordinal;
+ char *member_name;
+
+ ordinal = bfd_get_16 (abfd, data + amt);
+ member_name = (char *) data + amt + 2;
+ fprintf (file, "\t%04lx\t %4d %.*s",member, ordinal,
+ (int) (datasize - (amt + 2)), 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
+ && j + 4 <= ft_datasize)
+ fprintf (file, "\t%04lx",
+ (unsigned long) bfd_get_32 (abfd, ft_data + j));
+ fprintf (file, "\n");
+ }
+#else
+ for (j = 0; idx + j + 4 <= datasize; j += 4)
+ {
+ bfd_size_type amt;
+ unsigned long member = bfd_get_32 (abfd, data + idx + j);
+
+ /* Print single IMAGE_IMPORT_BY_NAME vector. */
+ if (member == 0)
+ break;
+
+ amt = member - adj;
+ if (HighBitSet (member))
+ fprintf (file, "\t%04lx\t %4lu <none>",
+ member, WithoutHighBit (member));
+ /* PR binutils/17512: Handle corrupt PE data. */
+ else if (amt + 2 >= datasize)
+ fprintf (file, _("\t<corrupt: 0x%04lx>"), member);
+ else
+ {
+ int ordinal;
+ char *member_name;
+
+ ordinal = bfd_get_16 (abfd, data + amt);
+ member_name = (char *) data + amt + 2;
+ fprintf (file, "\t%04lx\t %4d %.*s",
+ member, ordinal,
+ (int) (datasize - (amt + 2)), 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
+ && j + 4 <= ft_datasize)
+ fprintf (file, "\t%04lx",
+ (unsigned long) bfd_get_32 (abfd, ft_data + j));
+
+ fprintf (file, "\n");
+ }
+#endif
+ if (ft_allocated)
+ free (ft_data);
+ }
+
+ fprintf (file, "\n");
+ }
+
+ free (data);
+
+ return TRUE;
+}
+
+static bfd_boolean
+pe_print_edata (bfd * abfd, void * vfile)
+{
+ FILE *file = (FILE *) vfile;
+ bfd_byte *data;
+ asection *section;
+ bfd_size_type datasize = 0;
+ bfd_size_type dataoff;
+ bfd_size_type i;
+ bfd_vma 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;
+
+ bfd_vma addr;
+
+ addr = extra->DataDirectory[PE_EXPORT_TABLE].VirtualAddress;
+
+ if (addr == 0 && extra->DataDirectory[PE_EXPORT_TABLE].Size == 0)
+ {
+ /* Maybe the extra header isn't there. Look for the section. */
+ section = bfd_get_section_by_name (abfd, ".edata");
+ if (section == NULL)
+ return TRUE;
+
+ addr = section->vma;
+ dataoff = 0;
+ datasize = section->size;
+ if (datasize == 0)
+ return TRUE;
+ }
+ else
+ {
+ addr += extra->ImageBase;
+
+ for (section = abfd->sections; section != NULL; section = section->next)
+ if (addr >= section->vma && addr < section->vma + section->size)
+ break;
+
+ if (section == NULL)
+ {
+ fprintf (file,
+ _("\nThere is an export table, but the section containing it could not be found\n"));
+ return TRUE;
+ }
+ else if (!(section->flags & SEC_HAS_CONTENTS))
+ {
+ fprintf (file,
+ _("\nThere is an export table in %s, but that section has no contents\n"),
+ section->name);
+ return TRUE;
+ }
+
+ dataoff = addr - section->vma;
+ datasize = extra->DataDirectory[PE_EXPORT_TABLE].Size;
+ if (datasize > section->size - dataoff)
+ {
+ fprintf (file,
+ _("\nThere is an export table in %s, but it does not fit into that section\n"),
+ section->name);
+ return TRUE;
+ }
+ }
+
+ /* PR 17512: Handle corrupt PE binaries. */
+ if (datasize < 36)
+ {
+ fprintf (file,
+ _("\nThere is an export table in %s, but it is too small (%d)\n"),
+ section->name, (int) datasize);
+ return TRUE;
+ }
+
+ fprintf (file, _("\nThere is an export table in %s at 0x%lx\n"),
+ section->name, (unsigned long) addr);
+
+ data = (bfd_byte *) bfd_malloc (datasize);
+ if (data == NULL)
+ return FALSE;
+
+ if (! bfd_get_section_contents (abfd, section, data,
+ (file_ptr) 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 = section->vma - extra->ImageBase + dataoff;
+
+ /* Dump the EDT first. */
+ fprintf (file,
+ _("\nThe Export Tables (interpreted %s section contents)\n\n"),
+ section->name);
+
+ 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"));
+ bfd_fprintf_vma (abfd, file, edt.name);
+
+ if ((edt.name >= adj) && (edt.name < adj + datasize))
+ fprintf (file, " %.*s\n",
+ (int) (datasize - (edt.name - adj)),
+ data + edt.name - adj);
+ else
+ fprintf (file, "(outside .edata section)\n");
+
+ fprintf (file,
+ _("Ordinal Base \t\t\t%ld\n"), edt.base);
+
+ fprintf (file,
+ _("Number in:\n"));
+
+ fprintf (file,
+ _("\tExport Address Table \t\t%08lx\n"),
+ edt.num_functions);
+
+ fprintf (file,
+ _("\t[Name Pointer/Ordinal] Table\t%08lx\n"), edt.num_names);
+
+ fprintf (file,
+ _("Table Addresses\n"));
+
+ fprintf (file,
+ _("\tExport Address Table \t\t"));
+ bfd_fprintf_vma (abfd, file, edt.eat_addr);
+ fprintf (file, "\n");
+
+ fprintf (file,
+ _("\tName Pointer Table \t\t"));
+ bfd_fprintf_vma (abfd, file, edt.npt_addr);
+ fprintf (file, "\n");
+
+ fprintf (file,
+ _("\tOrdinal Table \t\t\t"));
+ bfd_fprintf_vma (abfd, file, edt.ot_addr);
+ fprintf (file, "\n");
+
+ /* The next table to find is 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);
+
+ /* PR 17512: Handle corrupt PE binaries. */
+ if (edt.eat_addr + (edt.num_functions * 4) - adj >= datasize
+ /* PR 17512 file: 140-165018-0.004. */
+ || data + edt.eat_addr - adj < data)
+ fprintf (file, _("\tInvalid Export Address Table rva (0x%lx) or entry count (0x%lx)\n"),
+ (long) edt.eat_addr,
+ (long) edt.num_functions);
+ else for (i = 0; i < edt.num_functions; ++i)
+ {
+ bfd_vma eat_member = bfd_get_32 (abfd,
+ data + edt.eat_addr + (i * 4) - adj);
+ if (eat_member == 0)
+ continue;
+
+ if (eat_member - adj <= datasize)
+ {
+ /* 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),
+ (unsigned long) eat_member,
+ _("Forwarder RVA"),
+ (int)(datasize - (eat_member - adj)),
+ 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),
+ (unsigned long) 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"));
+
+ /* PR 17512: Handle corrupt PE binaries. */
+ if (edt.npt_addr + (edt.num_names * 4) - adj >= datasize
+ || (data + edt.npt_addr - adj) < data)
+ fprintf (file, _("\tInvalid Name Pointer Table rva (0x%lx) or entry count (0x%lx)\n"),
+ (long) edt.npt_addr,
+ (long) edt.num_names);
+ /* PR 17512: file: 140-147171-0.004. */
+ else if (edt.ot_addr + (edt.num_names * 2) - adj >= datasize
+ || data + edt.ot_addr - adj < data)
+ fprintf (file, _("\tInvalid Ordinal Table rva (0x%lx) or entry count (0x%lx)\n"),
+ (long) edt.ot_addr,
+ (long) edt.num_names);
+ else for (i = 0; i < edt.num_names; ++i)
+ {
+ bfd_vma name_ptr;
+ bfd_vma ord;
+
+ ord = bfd_get_16 (abfd, data + edt.ot_addr + (i * 2) - adj);
+ name_ptr = bfd_get_32 (abfd, data + edt.npt_addr + (i * 4) - adj);
+
+ if ((name_ptr - adj) >= datasize)
+ {
+ fprintf (file, _("\t[%4ld] <corrupt offset: %lx>\n"),
+ (long) ord, (long) name_ptr);
+ }
+ else
+ {
+ char * name = (char *) data + name_ptr - adj;
+
+ fprintf (file, "\t[%4ld] %.*s\n", (long) ord,
+ (int)((char *)(data + datasize) - name), name);
+ }
+ }
+
+ free (data);
+
+ return TRUE;
+}
+
+/* This really is architecture dependent. On IA-64, a .pdata entry
+ consists of three dwords containing relative virtual addresses that
+ specify the start and end address of the code range the entry
+ covers and the address of the corresponding unwind info data.
+
+ On ARM and SH-4, a compressed PDATA structure is used :
+ _IMAGE_CE_RUNTIME_FUNCTION_ENTRY, whereas MIPS is documented to use
+ _IMAGE_ALPHA_RUNTIME_FUNCTION_ENTRY.
+ See http://msdn2.microsoft.com/en-us/library/ms253988(VS.80).aspx .
+
+ This is the version for uncompressed data. */
+
+static bfd_boolean
+pe_print_pdata (bfd * abfd, void * vfile)
+{
+#if defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64)
+# define PDATA_ROW_SIZE (3 * 8)
+#else
+# define PDATA_ROW_SIZE (5 * 4)
+#endif
+ 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 = PDATA_ROW_SIZE;
+
+ if (section == NULL
+ || coff_section_data (abfd, section) == NULL
+ || pei_section_data (abfd, section) == NULL)
+ return TRUE;
+
+ stop = pei_section_data (abfd, section)->virt_size;
+ 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"));
+#if defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64)
+ fprintf (file,
+ _(" vma:\t\t\tBegin Address End Address Unwind Info\n"));
+#else
+ fprintf (file, _("\
+ vma:\t\tBegin End EH EH PrologEnd Exception\n\
+ \t\tAddress Address Handler Data Address Mask\n"));
+#endif
+
+ datasize = section->size;
+ if (datasize == 0)
+ return TRUE;
+
+ if (! bfd_malloc_and_get_section (abfd, section, &data))
+ {
+ if (data != NULL)
+ free (data);
+ return FALSE;
+ }
+
+ 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 !defined(COFF_WITH_pep) || defined(COFF_WITH_pex64)
+ int em_data;
+#endif
+
+ if (i + PDATA_ROW_SIZE > stop)
+ break;
+
+ begin_addr = GET_PDATA_ENTRY (abfd, data + i );
+ end_addr = GET_PDATA_ENTRY (abfd, data + i + 4);
+ eh_handler = GET_PDATA_ENTRY (abfd, data + i + 8);
+ eh_data = GET_PDATA_ENTRY (abfd, data + i + 12);
+ prolog_end_addr = GET_PDATA_ENTRY (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;
+
+#if !defined(COFF_WITH_pep) || defined(COFF_WITH_pex64)
+ em_data = ((eh_handler & 0x1) << 2) | (prolog_end_addr & 0x3);
+#endif
+ eh_handler &= ~(bfd_vma) 0x3;
+ prolog_end_addr &= ~(bfd_vma) 0x3;
+
+ fputc (' ', file);
+ bfd_fprintf_vma (abfd, file, i + section->vma); fputc ('\t', file);
+ bfd_fprintf_vma (abfd, file, begin_addr); fputc (' ', file);
+ bfd_fprintf_vma (abfd, file, end_addr); fputc (' ', file);
+ bfd_fprintf_vma (abfd, file, eh_handler);
+#if !defined(COFF_WITH_pep) || defined(COFF_WITH_pex64)
+ fputc (' ', file);
+ bfd_fprintf_vma (abfd, file, eh_data); fputc (' ', file);
+ bfd_fprintf_vma (abfd, file, prolog_end_addr);
+ fprintf (file, " %x", em_data);
+#endif
+
+#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;
+#undef PDATA_ROW_SIZE
+}
+
+typedef struct sym_cache
+{
+ int symcount;
+ asymbol ** syms;
+} sym_cache;
+
+static asymbol **
+slurp_symtab (bfd *abfd, sym_cache *psc)
+{
+ asymbol ** sy = NULL;
+ long storage;
+
+ if (!(bfd_get_file_flags (abfd) & HAS_SYMS))
+ {
+ psc->symcount = 0;
+ return NULL;
+ }
+
+ storage = bfd_get_symtab_upper_bound (abfd);
+ if (storage < 0)
+ return NULL;
+ if (storage)
+ sy = (asymbol **) bfd_malloc (storage);
+
+ psc->symcount = bfd_canonicalize_symtab (abfd, sy);
+ if (psc->symcount < 0)
+ return NULL;
+ return sy;
+}
+
+static const char *
+my_symbol_for_address (bfd *abfd, bfd_vma func, sym_cache *psc)
+{
+ int i;
+
+ if (psc->syms == 0)
+ psc->syms = slurp_symtab (abfd, psc);
+
+ for (i = 0; i < psc->symcount; i++)
+ {
+ if (psc->syms[i]->section->vma + psc->syms[i]->value == func)
+ return psc->syms[i]->name;
+ }
+
+ return NULL;
+}
+
+static void
+cleanup_syms (sym_cache *psc)
+{
+ psc->symcount = 0;
+ free (psc->syms);
+ psc->syms = NULL;
+}
+
+/* This is the version for "compressed" pdata. */
+
+bfd_boolean
+_bfd_XX_print_ce_compressed_pdata (bfd * abfd, void * vfile)
+{
+# define PDATA_ROW_SIZE (2 * 4)
+ FILE *file = (FILE *) vfile;
+ bfd_byte *data = NULL;
+ 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 = PDATA_ROW_SIZE;
+ struct sym_cache cache = {0, 0} ;
+
+ if (section == NULL
+ || coff_section_data (abfd, section) == NULL
+ || pei_section_data (abfd, section) == NULL)
+ return TRUE;
+
+ stop = pei_section_data (abfd, section)->virt_size;
+ 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 Prolog Function Flags Exception EH\n\
+ \t\tAddress Length Length 32b exc Handler Data\n"));
+
+ datasize = section->size;
+ if (datasize == 0)
+ return TRUE;
+
+ if (! bfd_malloc_and_get_section (abfd, section, &data))
+ {
+ if (data != NULL)
+ free (data);
+ return FALSE;
+ }
+
+ start = 0;
+
+ for (i = start; i < stop; i += onaline)
+ {
+ bfd_vma begin_addr;
+ bfd_vma other_data;
+ bfd_vma prolog_length, function_length;
+ int flag32bit, exception_flag;
+ asection *tsection;
+
+ if (i + PDATA_ROW_SIZE > stop)
+ break;
+
+ begin_addr = GET_PDATA_ENTRY (abfd, data + i );
+ other_data = GET_PDATA_ENTRY (abfd, data + i + 4);
+
+ if (begin_addr == 0 && other_data == 0)
+ /* We are probably into the padding of the section now. */
+ break;
+
+ prolog_length = (other_data & 0x000000FF);
+ function_length = (other_data & 0x3FFFFF00) >> 8;
+ flag32bit = (int)((other_data & 0x40000000) >> 30);
+ exception_flag = (int)((other_data & 0x80000000) >> 31);
+
+ fputc (' ', file);
+ bfd_fprintf_vma (abfd, file, i + section->vma); fputc ('\t', file);
+ bfd_fprintf_vma (abfd, file, begin_addr); fputc (' ', file);
+ bfd_fprintf_vma (abfd, file, prolog_length); fputc (' ', file);
+ bfd_fprintf_vma (abfd, file, function_length); fputc (' ', file);
+ fprintf (file, "%2d %2d ", flag32bit, exception_flag);
+
+ /* Get the exception handler's address and the data passed from the
+ .text section. This is really the data that belongs with the .pdata
+ but got "compressed" out for the ARM and SH4 architectures. */
+ tsection = bfd_get_section_by_name (abfd, ".text");
+ if (tsection && coff_section_data (abfd, tsection)
+ && pei_section_data (abfd, tsection))
+ {
+ bfd_vma eh_off = (begin_addr - 8) - tsection->vma;
+ bfd_byte *tdata;
+
+ tdata = (bfd_byte *) bfd_malloc (8);
+ if (tdata)
+ {
+ if (bfd_get_section_contents (abfd, tsection, tdata, eh_off, 8))
+ {
+ bfd_vma eh, eh_data;
+
+ eh = bfd_get_32 (abfd, tdata);
+ eh_data = bfd_get_32 (abfd, tdata + 4);
+ fprintf (file, "%08x ", (unsigned int) eh);
+ fprintf (file, "%08x", (unsigned int) eh_data);
+ if (eh != 0)
+ {
+ const char *s = my_symbol_for_address (abfd, eh, &cache);
+
+ if (s)
+ fprintf (file, " (%s) ", s);
+ }
+ }
+ free (tdata);
+ }
+ }
+
+ fprintf (file, "\n");
+ }
+
+ free (data);
+
+ cleanup_syms (& cache);
+
+ return TRUE;
+#undef PDATA_ROW_SIZE
+}
+
+
+#define IMAGE_REL_BASED_HIGHADJ 4
+static const char * const tbl[] =
+{
+ "ABSOLUTE",
+ "HIGH",
+ "LOW",
+ "HIGHLOW",
+ "HIGHADJ",
+ "MIPS_JMPADDR",
+ "SECTION",
+ "REL32",
+ "RESERVED1",
+ "MIPS_JMPADDR16",
+ "DIR64",
+ "HIGH3ADJ",
+ "UNKNOWN", /* MUST be last. */
+};
+
+static bfd_boolean
+pe_print_reloc (bfd * abfd, void * vfile)
+{
+ FILE *file = (FILE *) vfile;
+ bfd_byte *data = 0;
+ asection *section = bfd_get_section_by_name (abfd, ".reloc");
+ bfd_byte *p, *end;
+
+ if (section == NULL || section->size == 0 || !(section->flags & SEC_HAS_CONTENTS))
+ return TRUE;
+
+ fprintf (file,
+ _("\n\nPE File Base Relocations (interpreted .reloc section contents)\n"));
+
+ if (! bfd_malloc_and_get_section (abfd, section, &data))
+ {
+ if (data != NULL)
+ free (data);
+ return FALSE;
+ }
+
+ p = data;
+ end = data + section->size;
+ while (p + 8 <= end)
+ {
+ int j;
+ bfd_vma virtual_address;
+ long number, size;
+ bfd_byte *chunk_end;
+
+ /* 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, p);
+ size = bfd_get_32 (abfd, p + 4);
+ p += 8;
+ number = (size - 8) / 2;
+
+ if (size == 0)
+ break;
+
+ fprintf (file,
+ _("\nVirtual Address: %08lx Chunk size %ld (0x%lx) Number of fixups %ld\n"),
+ (unsigned long) virtual_address, size, (unsigned long) size, number);
+
+ chunk_end = p + size;
+ if (chunk_end > end)
+ chunk_end = end;
+ j = 0;
+ while (p + 2 <= chunk_end)
+ {
+ unsigned short e = bfd_get_16 (abfd, p);
+ unsigned int t = (e & 0xF000) >> 12;
+ int off = e & 0x0FFF;
+
+ if (t >= sizeof (tbl) / sizeof (tbl[0]))
+ t = (sizeof (tbl) / sizeof (tbl[0])) - 1;
+
+ fprintf (file,
+ _("\treloc %4d offset %4x [%4lx] %s"),
+ j, off, (unsigned long) (off + virtual_address), tbl[t]);
+
+ p += 2;
+ j++;
+
+ /* HIGHADJ takes an argument, - the next record *is* the
+ low 16 bits of addend. */
+ if (t == IMAGE_REL_BASED_HIGHADJ && p + 2 <= chunk_end)
+ {
+ fprintf (file, " (%4x)", (unsigned int) bfd_get_16 (abfd, p));
+ p += 2;
+ j++;
+ }
+
+ fprintf (file, "\n");
+ }
+ }
+
+ free (data);
+
+ return TRUE;
+}
+
+/* A data structure describing the regions of a .rsrc section.
+ Some fields are filled in as the section is parsed. */
+
+typedef struct rsrc_regions
+{
+ bfd_byte * section_start;
+ bfd_byte * section_end;
+ bfd_byte * strings_start;
+ bfd_byte * resource_start;
+} rsrc_regions;
+
+static bfd_byte *
+rsrc_print_resource_directory (FILE * , bfd *, unsigned int, bfd_byte *,
+ rsrc_regions *, bfd_vma);
+
+/* Print the resource entry at DATA, with the text indented by INDENT.
+ Recusively calls rsrc_print_resource_directory to print the contents
+ of directory entries.
+ Returns the address of the end of the data associated with the entry
+ or section_end + 1 upon failure. */
+
+static bfd_byte *
+rsrc_print_resource_entries (FILE * file,
+ bfd * abfd,
+ unsigned int indent,
+ bfd_boolean is_name,
+ bfd_byte * data,
+ rsrc_regions * regions,
+ bfd_vma rva_bias)
+{
+ unsigned long entry, addr, size;
+
+ if (data + 8 >= regions->section_end)
+ return regions->section_end + 1;
+
+ fprintf (file, _("%03x %*.s Entry: "), (int)(data - regions->section_start), indent, " ");
+
+ entry = (unsigned long) bfd_get_32 (abfd, data);
+ if (is_name)
+ {
+ bfd_byte * name;
+
+ /* Note - the documentation says that this field is an RVA value
+ but windres appears to produce a section relative offset with
+ the top bit set. Support both styles for now. */
+ if (HighBitSet (entry))
+ name = regions->section_start + WithoutHighBit (entry);
+ else
+ name = regions->section_start + entry - rva_bias;
+
+ if (name + 2 < regions->section_end && name > regions->section_start)
+ {
+ unsigned int len;
+
+ if (regions->strings_start == NULL)
+ regions->strings_start = name;
+
+ len = bfd_get_16 (abfd, name);
+
+ fprintf (file, _("name: [val: %08lx len %d]: "), entry, len);
+
+ if (name + 2 + len * 2 < regions->section_end)
+ {
+ /* This strange loop is to cope with multibyte characters. */
+ while (len --)
+ {
+ char c;
+
+ name += 2;
+ c = * name;
+ /* Avoid printing control characters. */
+ if (c > 0 && c < 32)
+ fprintf (file, "^%c", c + 64);
+ else
+ fprintf (file, "%.1s", name);
+ }
+ }
+ else
+ {
+ fprintf (file, _("<corrupt string length: %#x>\n"), len);
+ /* PR binutils/17512: Do not try to continue decoding a
+ corrupted resource section. It is likely to end up with
+ reams of extraneous output. FIXME: We could probably
+ continue if we disable the printing of strings... */
+ return regions->section_end + 1;
+ }
+ }
+ else
+ {
+ fprintf (file, _("<corrupt string offset: %#lx>\n"), entry);
+ return regions->section_end + 1;
+ }
+ }
+ else
+ fprintf (file, _("ID: %#08lx"), entry);
+
+ entry = (long) bfd_get_32 (abfd, data + 4);
+ fprintf (file, _(", Value: %#08lx\n"), entry);
+
+ if (HighBitSet (entry))
+ {
+ data = regions->section_start + WithoutHighBit (entry);
+ if (data <= regions->section_start || data > regions->section_end)
+ return regions->section_end + 1;
+
+ /* FIXME: PR binutils/17512: A corrupt file could contain a loop
+ in the resource table. We need some way to detect this. */
+ return rsrc_print_resource_directory (file, abfd, indent + 1, data,
+ regions, rva_bias);
+ }
+
+ if (regions->section_start + entry + 16 >= regions->section_end)
+ return regions->section_end + 1;
+
+ fprintf (file, _("%03x %*.s Leaf: Addr: %#08lx, Size: %#08lx, Codepage: %d\n"),
+ (int) (entry),
+ indent, " ",
+ addr = (long) bfd_get_32 (abfd, regions->section_start + entry),
+ size = (long) bfd_get_32 (abfd, regions->section_start + entry + 4),
+ (int) bfd_get_32 (abfd, regions->section_start + entry + 8));
+
+ /* Check that the reserved entry is 0. */
+ if (bfd_get_32 (abfd, regions->section_start + entry + 12) != 0
+ /* And that the data address/size is valid too. */
+ || (regions->section_start + (addr - rva_bias) + size > regions->section_end))
+ return regions->section_end + 1;
+
+ if (regions->resource_start == NULL)
+ regions->resource_start = regions->section_start + (addr - rva_bias);
+
+ return regions->section_start + (addr - rva_bias) + size;
+}
+
+#define max(a,b) ((a) > (b) ? (a) : (b))
+#define min(a,b) ((a) < (b) ? (a) : (b))
+
+static bfd_byte *
+rsrc_print_resource_directory (FILE * file,
+ bfd * abfd,
+ unsigned int indent,
+ bfd_byte * data,
+ rsrc_regions * regions,
+ bfd_vma rva_bias)
+{
+ unsigned int num_names, num_ids;
+ bfd_byte * highest_data = data;
+
+ if (data + 16 >= regions->section_end)
+ return regions->section_end + 1;
+
+ fprintf (file, "%03x %*.s ", (int)(data - regions->section_start), indent, " ");
+ switch (indent)
+ {
+ case 0: fprintf (file, "Type"); break;
+ case 2: fprintf (file, "Name"); break;
+ case 4: fprintf (file, "Language"); break;
+ default:
+ fprintf (file, _("<unknown directory type: %d>\n"), indent);
+ /* FIXME: For now we end the printing here. If in the
+ future more directory types are added to the RSRC spec
+ then we will need to change this. */
+ return regions->section_end + 1;
+ }
+
+ fprintf (file, _(" Table: Char: %d, Time: %08lx, Ver: %d/%d, Num Names: %d, IDs: %d\n"),
+ (int) bfd_get_32 (abfd, data),
+ (long) bfd_get_32 (abfd, data + 4),
+ (int) bfd_get_16 (abfd, data + 8),
+ (int) bfd_get_16 (abfd, data + 10),
+ num_names = (int) bfd_get_16 (abfd, data + 12),
+ num_ids = (int) bfd_get_16 (abfd, data + 14));
+ data += 16;
+
+ while (num_names --)
+ {
+ bfd_byte * entry_end;
+
+ entry_end = rsrc_print_resource_entries (file, abfd, indent + 1, TRUE,
+ data, regions, rva_bias);
+ data += 8;
+ highest_data = max (highest_data, entry_end);
+ if (entry_end >= regions->section_end)
+ return entry_end;
+ }
+
+ while (num_ids --)
+ {
+ bfd_byte * entry_end;
+
+ entry_end = rsrc_print_resource_entries (file, abfd, indent + 1, FALSE,
+ data, regions, rva_bias);
+ data += 8;
+ highest_data = max (highest_data, entry_end);
+ if (entry_end >= regions->section_end)
+ return entry_end;
+ }
+
+ return max (highest_data, data);
+}
+
+/* Display the contents of a .rsrc section. We do not try to
+ reproduce the resources, windres does that. Instead we dump
+ the tables in a human readable format. */
+
+static bfd_boolean
+rsrc_print_section (bfd * abfd, void * vfile)
+{
+ bfd_vma rva_bias;
+ pe_data_type * pe;
+ FILE * file = (FILE *) vfile;
+ bfd_size_type datasize;
+ asection * section;
+ bfd_byte * data;
+ rsrc_regions regions;
+
+ pe = pe_data (abfd);
+ if (pe == NULL)
+ return TRUE;
+
+ section = bfd_get_section_by_name (abfd, ".rsrc");
+ if (section == NULL)
+ return TRUE;
+ if (!(section->flags & SEC_HAS_CONTENTS))
+ return TRUE;
+
+ datasize = section->size;
+ if (datasize == 0)
+ return TRUE;
+
+ rva_bias = section->vma - pe->pe_opthdr.ImageBase;
+
+ if (! bfd_malloc_and_get_section (abfd, section, & data))
+ {
+ if (data != NULL)
+ free (data);
+ return FALSE;
+ }
+
+ regions.section_start = data;
+ regions.section_end = data + datasize;
+ regions.strings_start = NULL;
+ regions.resource_start = NULL;
+
+ fflush (file);
+ fprintf (file, "\nThe .rsrc Resource Directory section:\n");
+
+ while (data < regions.section_end)
+ {
+ bfd_byte * p = data;
+
+ data = rsrc_print_resource_directory (file, abfd, 0, data, & regions, rva_bias);
+
+ if (data == regions.section_end + 1)
+ fprintf (file, _("Corrupt .rsrc section detected!\n"));
+ else
+ {
+ /* Align data before continuing. */
+ int align = (1 << section->alignment_power) - 1;
+
+ data = (bfd_byte *) (((ptrdiff_t) (data + align)) & ~ align);
+ rva_bias += data - p;
+
+ /* For reasons that are unclear .rsrc sections are sometimes created
+ aligned to a 1^3 boundary even when their alignment is set at
+ 1^2. Catch that case here before we issue a spurious warning
+ message. */
+ if (data == (regions.section_end - 4))
+ data = regions.section_end;
+ else if (data < regions.section_end)
+ {
+ /* If the extra data is all zeros then do not complain.
+ This is just padding so that the section meets the
+ page size requirements. */
+ while (data ++ < regions.section_end)
+ if (*data != 0)
+ break;
+ if (data < regions.section_end)
+ fprintf (file, _("\nWARNING: Extra data in .rsrc section - it will be ignored by Windows:\n"));
+ }
+ }
+ }
+
+ if (regions.strings_start != NULL)
+ fprintf (file, " String table starts at offset: %#03x\n",
+ (int) (regions.strings_start - regions.section_start));
+ if (regions.resource_start != NULL)
+ fprintf (file, " Resources start at offset: %#03x\n",
+ (int) (regions.resource_start - regions.section_start));
+
+ free (regions.section_start);
+ return TRUE;
+}
+
+#define IMAGE_NUMBEROF_DEBUG_TYPES 12
+
+static char * debug_type_names[IMAGE_NUMBEROF_DEBUG_TYPES] =
+{
+ "Unknown",
+ "COFF",
+ "CodeView",
+ "FPO",
+ "Misc",
+ "Exception",
+ "Fixup",
+ "OMAP-to-SRC",
+ "OMAP-from-SRC",
+ "Borland",
+ "Reserved",
+ "CLSID",
+};
+
+static bfd_boolean
+pe_print_debugdata (bfd * abfd, void * vfile)
+{
+ FILE *file = (FILE *) vfile;
+ pe_data_type *pe = pe_data (abfd);
+ struct internal_extra_pe_aouthdr *extra = &pe->pe_opthdr;
+ asection *section;
+ bfd_byte *data = 0;
+ bfd_size_type dataoff;
+ unsigned int i;
+
+ bfd_vma addr = extra->DataDirectory[PE_DEBUG_DATA].VirtualAddress;
+ bfd_size_type size = extra->DataDirectory[PE_DEBUG_DATA].Size;
+
+ if (size == 0)
+ return TRUE;
+
+ addr += extra->ImageBase;
+ for (section = abfd->sections; section != NULL; section = section->next)
+ {
+ if ((addr >= section->vma) && (addr < (section->vma + section->size)))
+ break;
+ }
+
+ if (section == NULL)
+ {
+ fprintf (file,
+ _("\nThere is a debug directory, but the section containing it could not be found\n"));
+ return TRUE;
+ }
+ else if (!(section->flags & SEC_HAS_CONTENTS))
+ {
+ fprintf (file,
+ _("\nThere is a debug directory in %s, but that section has no contents\n"),
+ section->name);
+ return TRUE;
+ }
+ else if (section->size < size)
+ {
+ fprintf (file,
+ _("\nError: section %s contains the debug data starting address but it is too small\n"),
+ section->name);
+ return FALSE;
+ }
+
+ fprintf (file, _("\nThere is a debug directory in %s at 0x%lx\n\n"),
+ section->name, (unsigned long) addr);
+
+ dataoff = addr - section->vma;
+
+ if (size > (section->size - dataoff))
+ {
+ fprintf (file, _("The debug data size field in the data directory is too big for the section"));
+ return FALSE;
+ }
+
+ fprintf (file,
+ _("Type Size Rva Offset\n"));
+
+ /* Read the whole section. */
+ if (!bfd_malloc_and_get_section (abfd, section, &data))
+ {
+ if (data != NULL)
+ free (data);
+ return FALSE;
+ }
+
+ for (i = 0; i < size / sizeof (struct external_IMAGE_DEBUG_DIRECTORY); i++)
+ {
+ const char *type_name;
+ struct external_IMAGE_DEBUG_DIRECTORY *ext
+ = &((struct external_IMAGE_DEBUG_DIRECTORY *)(data + dataoff))[i];
+ struct internal_IMAGE_DEBUG_DIRECTORY idd;
+
+ _bfd_XXi_swap_debugdir_in (abfd, ext, &idd);
+
+ if ((idd.Type) >= IMAGE_NUMBEROF_DEBUG_TYPES)
+ type_name = debug_type_names[0];
+ else
+ type_name = debug_type_names[idd.Type];
+
+ fprintf (file, " %2ld %14s %08lx %08lx %08lx\n",
+ idd.Type, type_name, idd.SizeOfData,
+ idd.AddressOfRawData, idd.PointerToRawData);
+
+ if (idd.Type == PE_IMAGE_DEBUG_TYPE_CODEVIEW)
+ {
+ char signature[CV_INFO_SIGNATURE_LENGTH * 2 + 1];
+ char buffer[256 + 1];
+ CODEVIEW_INFO *cvinfo = (CODEVIEW_INFO *) buffer;
+
+ /* The debug entry doesn't have to have to be in a section,
+ in which case AddressOfRawData is 0, so always use PointerToRawData. */
+ if (!_bfd_XXi_slurp_codeview_record (abfd, (file_ptr) idd.PointerToRawData,
+ idd.SizeOfData, cvinfo))
+ continue;
+
+ for (i = 0; i < cvinfo->SignatureLength; i++)
+ sprintf (&signature[i*2], "%02x", cvinfo->Signature[i] & 0xff);
+
+ fprintf (file, "(format %c%c%c%c signature %s age %ld)\n",
+ buffer[0], buffer[1], buffer[2], buffer[3],
+ signature, cvinfo->Age);
+ }
+ }
+
+ if (size % sizeof (struct external_IMAGE_DEBUG_DIRECTORY) != 0)
+ fprintf (file,
+ _("The debug directory size is not a multiple of the debug directory entry size\n"));
+
+ return TRUE;
+}
+
+/* Print out the program headers. */
+
+bfd_boolean
+_bfd_XX_print_private_bfd_data_common (bfd * abfd, void * vfile)
+{
+ FILE *file = (FILE *) vfile;
+ int j;
+ pe_data_type *pe = pe_data (abfd);
+ struct internal_extra_pe_aouthdr *i = &pe->pe_opthdr;
+ const char *subsystem_name = NULL;
+ const char *name;
+
+ /* 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 (IMAGE_FILE_RELOCS_STRIPPED, "relocations stripped");
+ PF (IMAGE_FILE_EXECUTABLE_IMAGE, "executable");
+ PF (IMAGE_FILE_LINE_NUMS_STRIPPED, "line numbers stripped");
+ PF (IMAGE_FILE_LOCAL_SYMS_STRIPPED, "symbols stripped");
+ PF (IMAGE_FILE_LARGE_ADDRESS_AWARE, "large address aware");
+ PF (IMAGE_FILE_BYTES_REVERSED_LO, "little endian");
+ PF (IMAGE_FILE_32BIT_MACHINE, "32 bit words");
+ PF (IMAGE_FILE_DEBUG_STRIPPED, "debugging information removed");
+ PF (IMAGE_FILE_SYSTEM, "system file");
+ PF (IMAGE_FILE_DLL, "DLL");
+ PF (IMAGE_FILE_BYTES_REVERSED_HI, "big endian");
+#undef PF
+
+ /* ctime implies '\n'. */
+ {
+ time_t t = pe->coff.timestamp;
+ fprintf (file, "\nTime/Date\t\t%s", ctime (&t));
+ }
+
+#ifndef IMAGE_NT_OPTIONAL_HDR_MAGIC
+# define IMAGE_NT_OPTIONAL_HDR_MAGIC 0x10b
+#endif
+#ifndef IMAGE_NT_OPTIONAL_HDR64_MAGIC
+# define IMAGE_NT_OPTIONAL_HDR64_MAGIC 0x20b
+#endif
+#ifndef IMAGE_NT_OPTIONAL_HDRROM_MAGIC
+# define IMAGE_NT_OPTIONAL_HDRROM_MAGIC 0x107
+#endif
+
+ switch (i->Magic)
+ {
+ case IMAGE_NT_OPTIONAL_HDR_MAGIC:
+ name = "PE32";
+ break;
+ case IMAGE_NT_OPTIONAL_HDR64_MAGIC:
+ name = "PE32+";
+ break;
+ case IMAGE_NT_OPTIONAL_HDRROM_MAGIC:
+ name = "ROM";
+ break;
+ default:
+ name = NULL;
+ break;
+ }
+ fprintf (file, "Magic\t\t\t%04x", i->Magic);
+ if (name)
+ fprintf (file, "\t(%s)",name);
+ fprintf (file, "\nMajorLinkerVersion\t%d\n", i->MajorLinkerVersion);
+ fprintf (file, "MinorLinkerVersion\t%d\n", i->MinorLinkerVersion);
+ fprintf (file, "SizeOfCode\t\t%08lx\n", (unsigned long) i->SizeOfCode);
+ fprintf (file, "SizeOfInitializedData\t%08lx\n",
+ (unsigned long) i->SizeOfInitializedData);
+ fprintf (file, "SizeOfUninitializedData\t%08lx\n",
+ (unsigned long) i->SizeOfUninitializedData);
+ fprintf (file, "AddressOfEntryPoint\t");
+ bfd_fprintf_vma (abfd, file, i->AddressOfEntryPoint);
+ fprintf (file, "\nBaseOfCode\t\t");
+ bfd_fprintf_vma (abfd, file, i->BaseOfCode);
+#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64)
+ /* PE32+ does not have BaseOfData member! */
+ fprintf (file, "\nBaseOfData\t\t");
+ bfd_fprintf_vma (abfd, file, i->BaseOfData);
+#endif
+
+ fprintf (file, "\nImageBase\t\t");
+ bfd_fprintf_vma (abfd, file, i->ImageBase);
+ fprintf (file, "\nSectionAlignment\t");
+ bfd_fprintf_vma (abfd, file, i->SectionAlignment);
+ fprintf (file, "\nFileAlignment\t\t");
+ bfd_fprintf_vma (abfd, 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, "Win32Version\t\t%08lx\n", (unsigned long) i->Reserved1);
+ fprintf (file, "SizeOfImage\t\t%08lx\n", (unsigned long) i->SizeOfImage);
+ fprintf (file, "SizeOfHeaders\t\t%08lx\n", (unsigned long) i->SizeOfHeaders);
+ fprintf (file, "CheckSum\t\t%08lx\n", (unsigned long) i->CheckSum);
+
+ switch (i->Subsystem)
+ {
+ case IMAGE_SUBSYSTEM_UNKNOWN:
+ subsystem_name = "unspecified";
+ break;
+ case IMAGE_SUBSYSTEM_NATIVE:
+ subsystem_name = "NT native";
+ break;
+ case IMAGE_SUBSYSTEM_WINDOWS_GUI:
+ subsystem_name = "Windows GUI";
+ break;
+ case IMAGE_SUBSYSTEM_WINDOWS_CUI:
+ subsystem_name = "Windows CUI";
+ break;
+ case IMAGE_SUBSYSTEM_POSIX_CUI:
+ subsystem_name = "POSIX CUI";
+ break;
+ case IMAGE_SUBSYSTEM_WINDOWS_CE_GUI:
+ subsystem_name = "Wince CUI";
+ break;
+ // These are from UEFI Platform Initialization Specification 1.1.
+ case IMAGE_SUBSYSTEM_EFI_APPLICATION:
+ subsystem_name = "EFI application";
+ break;
+ case IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER:
+ subsystem_name = "EFI boot service driver";
+ break;
+ case IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER:
+ subsystem_name = "EFI runtime driver";
+ break;
+ case IMAGE_SUBSYSTEM_SAL_RUNTIME_DRIVER:
+ subsystem_name = "SAL runtime driver";
+ break;
+ // This is from revision 8.0 of the MS PE/COFF spec
+ case IMAGE_SUBSYSTEM_XBOX:
+ subsystem_name = "XBOX";
+ break;
+ // Added default case for clarity - subsystem_name is NULL anyway.
+ default:
+ subsystem_name = NULL;
+ }
+
+ fprintf (file, "Subsystem\t\t%08x", i->Subsystem);
+ if (subsystem_name)
+ fprintf (file, "\t(%s)", subsystem_name);
+ fprintf (file, "\nDllCharacteristics\t%08x\n", i->DllCharacteristics);
+ fprintf (file, "SizeOfStackReserve\t");
+ bfd_fprintf_vma (abfd, file, i->SizeOfStackReserve);
+ fprintf (file, "\nSizeOfStackCommit\t");
+ bfd_fprintf_vma (abfd, file, i->SizeOfStackCommit);
+ fprintf (file, "\nSizeOfHeapReserve\t");
+ bfd_fprintf_vma (abfd, file, i->SizeOfHeapReserve);
+ fprintf (file, "\nSizeOfHeapCommit\t");
+ bfd_fprintf_vma (abfd, file, i->SizeOfHeapCommit);
+ fprintf (file, "\nLoaderFlags\t\t%08lx\n", (unsigned long) i->LoaderFlags);
+ fprintf (file, "NumberOfRvaAndSizes\t%08lx\n",
+ (unsigned long) i->NumberOfRvaAndSizes);
+
+ fprintf (file, "\nThe Data Directory\n");
+ for (j = 0; j < IMAGE_NUMBEROF_DIRECTORY_ENTRIES; j++)
+ {
+ fprintf (file, "Entry %1x ", j);
+ bfd_fprintf_vma (abfd, file, i->DataDirectory[j].VirtualAddress);
+ fprintf (file, " %08lx ", (unsigned long) i->DataDirectory[j].Size);
+ fprintf (file, "%s\n", dir_names[j]);
+ }
+
+ pe_print_idata (abfd, vfile);
+ pe_print_edata (abfd, vfile);
+ if (bfd_coff_have_print_pdata (abfd))
+ bfd_coff_print_pdata (abfd, vfile);
+ else
+ pe_print_pdata (abfd, vfile);
+ pe_print_reloc (abfd, vfile);
+ pe_print_debugdata (abfd, file);
+
+ rsrc_print_section (abfd, vfile);
+
+ return TRUE;
+}
+
+static bfd_boolean
+is_vma_in_section (bfd *abfd ATTRIBUTE_UNUSED, asection *sect, void *obj)
+{
+ bfd_vma addr = * (bfd_vma *) obj;
+ return (addr >= sect->vma) && (addr < (sect->vma + sect->size));
+}
+
+static asection *
+find_section_by_vma (bfd *abfd, bfd_vma addr)
+{
+ return bfd_sections_find_if (abfd, is_vma_in_section, (void *) & addr);
+}
+
+/* Copy any private info we understand from the input bfd
+ to the output bfd. */
+
+bfd_boolean
+_bfd_XX_bfd_copy_private_bfd_data_common (bfd * ibfd, bfd * obfd)
+{
+ pe_data_type *ipe, *ope;
+
+ /* 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;
+
+ ipe = pe_data (ibfd);
+ ope = pe_data (obfd);
+
+ /* pe_opthdr is copied in copy_object. */
+ ope->dll = ipe->dll;
+
+ /* Don't copy input subsystem if output is different from input. */
+ if (obfd->xvec != ibfd->xvec)
+ ope->pe_opthdr.Subsystem = IMAGE_SUBSYSTEM_UNKNOWN;
+
+ /* For strip: if we removed .reloc, we'll make a real mess of things
+ if we don't remove this entry as well. */
+ if (! pe_data (obfd)->has_reloc_section)
+ {
+ pe_data (obfd)->pe_opthdr.DataDirectory[PE_BASE_RELOCATION_TABLE].VirtualAddress = 0;
+ pe_data (obfd)->pe_opthdr.DataDirectory[PE_BASE_RELOCATION_TABLE].Size = 0;
+ }
+
+ /* For PIE, if there is .reloc, we won't add IMAGE_FILE_RELOCS_STRIPPED.
+ But there is no .reloc, we make sure that IMAGE_FILE_RELOCS_STRIPPED
+ won't be added. */
+ if (! pe_data (ibfd)->has_reloc_section
+ && ! (pe_data (ibfd)->real_flags & IMAGE_FILE_RELOCS_STRIPPED))
+ pe_data (obfd)->dont_strip_reloc = 1;
+
+ /* The file offsets contained in the debug directory need rewriting. */
+ if (ope->pe_opthdr.DataDirectory[PE_DEBUG_DATA].Size != 0)
+ {
+ bfd_vma addr = ope->pe_opthdr.DataDirectory[PE_DEBUG_DATA].VirtualAddress
+ + ope->pe_opthdr.ImageBase;
+ asection *section = find_section_by_vma (obfd, addr);
+ bfd_byte *data;
+
+ if (section && bfd_malloc_and_get_section (obfd, section, &data))
+ {
+ unsigned int i;
+ struct external_IMAGE_DEBUG_DIRECTORY *dd =
+ (struct external_IMAGE_DEBUG_DIRECTORY *)(data + (addr - section->vma));
+
+ for (i = 0; i < ope->pe_opthdr.DataDirectory[PE_DEBUG_DATA].Size
+ / sizeof (struct external_IMAGE_DEBUG_DIRECTORY); i++)
+ {
+ asection *ddsection;
+ struct external_IMAGE_DEBUG_DIRECTORY *edd = &(dd[i]);
+ struct internal_IMAGE_DEBUG_DIRECTORY idd;
+
+ _bfd_XXi_swap_debugdir_in (obfd, edd, &idd);
+
+ if (idd.AddressOfRawData == 0)
+ continue; /* RVA 0 means only offset is valid, not handled yet. */
+
+ ddsection = find_section_by_vma (obfd, idd.AddressOfRawData + ope->pe_opthdr.ImageBase);
+ if (!ddsection)
+ continue; /* Not in a section! */
+
+ idd.PointerToRawData = ddsection->filepos + (idd.AddressOfRawData
+ + ope->pe_opthdr.ImageBase) - ddsection->vma;
+
+ _bfd_XXi_swap_debugdir_out (obfd, &idd, edd);
+ }
+
+ if (!bfd_set_section_contents (obfd, section, data, 0, section->size))
+ _bfd_error_handler (_("Failed to update file offsets in debug directory"));
+ }
+ }
+
+ return TRUE;
+}
+
+/* Copy private section data. */
+
+bfd_boolean
+_bfd_XX_bfd_copy_private_section_data (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)
+ {
+ bfd_size_type amt = sizeof (struct coff_section_tdata);
+ osec->used_by_bfd = bfd_zalloc (obfd, amt);
+ if (osec->used_by_bfd == NULL)
+ return FALSE;
+ }
+
+ if (pei_section_data (obfd, osec) == NULL)
+ {
+ bfd_size_type amt = sizeof (struct pei_section_tdata);
+ coff_section_data (obfd, osec)->tdata = bfd_zalloc (obfd, amt);
+ if (coff_section_data (obfd, osec)->tdata == NULL)
+ return FALSE;
+ }
+
+ pei_section_data (obfd, osec)->virt_size =
+ pei_section_data (ibfd, isec)->virt_size;
+ pei_section_data (obfd, osec)->pe_flags =
+ pei_section_data (ibfd, isec)->pe_flags;
+ }
+
+ return TRUE;
+}
+
+void
+_bfd_XX_get_symbol_info (bfd * abfd, asymbol *symbol, symbol_info *ret)
+{
+ coff_get_symbol_info (abfd, symbol, ret);
+}
+
+#if !defined(COFF_WITH_pep) && defined(COFF_WITH_pex64)
+static int
+sort_x64_pdata (const void *l, const void *r)
+{
+ const char *lp = (const char *) l;
+ const char *rp = (const char *) r;
+ bfd_vma vl, vr;
+ vl = bfd_getl32 (lp); vr = bfd_getl32 (rp);
+ if (vl != vr)
+ return (vl < vr ? -1 : 1);
+ /* We compare just begin address. */
+ return 0;
+}
+#endif
+
+/* Functions to process a .rsrc section. */
+
+static unsigned int sizeof_leaves;
+static unsigned int sizeof_strings;
+static unsigned int sizeof_tables_and_entries;
+
+static bfd_byte *
+rsrc_count_directory (bfd *, bfd_byte *, bfd_byte *, bfd_byte *, bfd_vma);
+
+static bfd_byte *
+rsrc_count_entries (bfd * abfd,
+ bfd_boolean is_name,
+ bfd_byte * datastart,
+ bfd_byte * data,
+ bfd_byte * dataend,
+ bfd_vma rva_bias)
+{
+ unsigned long entry, addr, size;
+
+ if (data + 8 >= dataend)
+ return dataend + 1;
+
+ if (is_name)
+ {
+ bfd_byte * name;
+
+ entry = (long) bfd_get_32 (abfd, data);
+
+ if (HighBitSet (entry))
+ name = datastart + WithoutHighBit (entry);
+ else
+ name = datastart + entry - rva_bias;
+
+ if (name + 2 >= dataend || name < datastart)
+ return dataend + 1;
+
+ unsigned int len = bfd_get_16 (abfd, name);
+ if (len == 0 || len > 256)
+ return dataend + 1;
+ }
+
+ entry = (long) bfd_get_32 (abfd, data + 4);
+
+ if (HighBitSet (entry))
+ {
+ data = datastart + WithoutHighBit (entry);
+
+ if (data <= datastart || data >= dataend)
+ return dataend + 1;
+
+ return rsrc_count_directory (abfd, datastart, data, dataend, rva_bias);
+ }
+
+ if (datastart + entry + 16 >= dataend)
+ return dataend + 1;
+
+ addr = (long) bfd_get_32 (abfd, datastart + entry);
+ size = (long) bfd_get_32 (abfd, datastart + entry + 4);
+
+ return datastart + addr - rva_bias + size;
+}
+
+static bfd_byte *
+rsrc_count_directory (bfd * abfd,
+ bfd_byte * datastart,
+ bfd_byte * data,
+ bfd_byte * dataend,
+ bfd_vma rva_bias)
+{
+ unsigned int num_entries, num_ids;
+ bfd_byte * highest_data = data;
+
+ if (data + 16 >= dataend)
+ return dataend + 1;
+
+ num_entries = (int) bfd_get_16 (abfd, data + 12);
+ num_ids = (int) bfd_get_16 (abfd, data + 14);
+
+ num_entries += num_ids;
+
+ data += 16;
+
+ while (num_entries --)
+ {
+ bfd_byte * entry_end;
+
+ entry_end = rsrc_count_entries (abfd, num_entries >= num_ids,
+ datastart, data, dataend, rva_bias);
+ data += 8;
+ highest_data = max (highest_data, entry_end);
+ if (entry_end >= dataend)
+ break;
+ }
+
+ return max (highest_data, data);
+}
+
+typedef struct rsrc_dir_chain
+{
+ unsigned int num_entries;
+ struct rsrc_entry * first_entry;
+ struct rsrc_entry * last_entry;
+} rsrc_dir_chain;
+
+typedef struct rsrc_directory
+{
+ unsigned int characteristics;
+ unsigned int time;
+ unsigned int major;
+ unsigned int minor;
+
+ rsrc_dir_chain names;
+ rsrc_dir_chain ids;
+
+ struct rsrc_entry * entry;
+} rsrc_directory;
+
+typedef struct rsrc_string
+{
+ unsigned int len;
+ bfd_byte * string;
+} rsrc_string;
+
+typedef struct rsrc_leaf
+{
+ unsigned int size;
+ unsigned int codepage;
+ bfd_byte * data;
+} rsrc_leaf;
+
+typedef struct rsrc_entry
+{
+ bfd_boolean is_name;
+ union
+ {
+ unsigned int id;
+ struct rsrc_string name;
+ } name_id;
+
+ bfd_boolean is_dir;
+ union
+ {
+ struct rsrc_directory * directory;
+ struct rsrc_leaf * leaf;
+ } value;
+
+ struct rsrc_entry * next_entry;
+ struct rsrc_directory * parent;
+} rsrc_entry;
+
+static bfd_byte *
+rsrc_parse_directory (bfd *, rsrc_directory *, bfd_byte *,
+ bfd_byte *, bfd_byte *, bfd_vma, rsrc_entry *);
+
+static bfd_byte *
+rsrc_parse_entry (bfd * abfd,
+ bfd_boolean is_name,
+ rsrc_entry * entry,
+ bfd_byte * datastart,
+ bfd_byte * data,
+ bfd_byte * dataend,
+ bfd_vma rva_bias,
+ rsrc_directory * parent)
+{
+ unsigned long val, addr, size;
+
+ val = bfd_get_32 (abfd, data);
+
+ entry->parent = parent;
+ entry->is_name = is_name;
+
+ if (is_name)
+ {
+ bfd_byte * address;
+
+ if (HighBitSet (val))
+ {
+ val = WithoutHighBit (val);
+
+ address = datastart + val;
+ }
+ else
+ {
+ address = datastart + val - rva_bias;
+ }
+
+ if (address + 3 > dataend)
+ return dataend;
+
+ entry->name_id.name.len = bfd_get_16 (abfd, address);
+ entry->name_id.name.string = address + 2;
+ }
+ else
+ entry->name_id.id = val;
+
+ val = bfd_get_32 (abfd, data + 4);
+
+ if (HighBitSet (val))
+ {
+ entry->is_dir = TRUE;
+ entry->value.directory = bfd_malloc (sizeof * entry->value.directory);
+ if (entry->value.directory == NULL)
+ return dataend;
+
+ return rsrc_parse_directory (abfd, entry->value.directory,
+ datastart,
+ datastart + WithoutHighBit (val),
+ dataend, rva_bias, entry);
+ }
+
+ entry->is_dir = FALSE;
+ entry->value.leaf = bfd_malloc (sizeof * entry->value.leaf);
+ if (entry->value.leaf == NULL)
+ return dataend;
+
+ addr = bfd_get_32 (abfd, datastart + val);
+ size = entry->value.leaf->size = bfd_get_32 (abfd, datastart + val + 4);
+ entry->value.leaf->codepage = bfd_get_32 (abfd, datastart + val + 8);
+
+ entry->value.leaf->data = bfd_malloc (size);
+ if (entry->value.leaf->data == NULL)
+ return dataend;
+
+ memcpy (entry->value.leaf->data, datastart + addr - rva_bias, size);
+ return datastart + (addr - rva_bias) + size;
+}
+
+static bfd_byte *
+rsrc_parse_entries (bfd * abfd,
+ rsrc_dir_chain * chain,
+ bfd_boolean is_name,
+ bfd_byte * highest_data,
+ bfd_byte * datastart,
+ bfd_byte * data,
+ bfd_byte * dataend,
+ bfd_vma rva_bias,
+ rsrc_directory * parent)
+{
+ unsigned int i;
+ rsrc_entry * entry;
+
+ if (chain->num_entries == 0)
+ {
+ chain->first_entry = chain->last_entry = NULL;
+ return highest_data;
+ }
+
+ entry = bfd_malloc (sizeof * entry);
+ if (entry == NULL)
+ return dataend;
+
+ chain->first_entry = entry;
+
+ for (i = chain->num_entries; i--;)
+ {
+ bfd_byte * entry_end;
+
+ entry_end = rsrc_parse_entry (abfd, is_name, entry, datastart,
+ data, dataend, rva_bias, parent);
+ data += 8;
+ highest_data = max (entry_end, highest_data);
+ if (entry_end > dataend)
+ return dataend;
+
+ if (i)
+ {
+ entry->next_entry = bfd_malloc (sizeof * entry);
+ entry = entry->next_entry;
+ if (entry == NULL)
+ return dataend;
+ }
+ else
+ entry->next_entry = NULL;
+ }
+
+ chain->last_entry = entry;
+
+ return highest_data;
+}
+
+static bfd_byte *
+rsrc_parse_directory (bfd * abfd,
+ rsrc_directory * table,
+ bfd_byte * datastart,
+ bfd_byte * data,
+ bfd_byte * dataend,
+ bfd_vma rva_bias,
+ rsrc_entry * entry)
+{
+ bfd_byte * highest_data = data;
+
+ if (table == NULL)
+ return dataend;
+
+ table->characteristics = bfd_get_32 (abfd, data);
+ table->time = bfd_get_32 (abfd, data + 4);
+ table->major = bfd_get_16 (abfd, data + 8);
+ table->minor = bfd_get_16 (abfd, data + 10);
+ table->names.num_entries = bfd_get_16 (abfd, data + 12);
+ table->ids.num_entries = bfd_get_16 (abfd, data + 14);
+ table->entry = entry;
+
+ data += 16;
+
+ highest_data = rsrc_parse_entries (abfd, & table->names, TRUE, data,
+ datastart, data, dataend, rva_bias, table);
+ data += table->names.num_entries * 8;
+
+ highest_data = rsrc_parse_entries (abfd, & table->ids, FALSE, highest_data,
+ datastart, data, dataend, rva_bias, table);
+ data += table->ids.num_entries * 8;
+
+ return max (highest_data, data);
+}
+
+typedef struct rsrc_write_data
+{
+ bfd * abfd;
+ bfd_byte * datastart;
+ bfd_byte * next_table;
+ bfd_byte * next_leaf;
+ bfd_byte * next_string;
+ bfd_byte * next_data;
+ bfd_vma rva_bias;
+} rsrc_write_data;
+
+static void
+rsrc_write_string (rsrc_write_data * data,
+ rsrc_string * string)
+{
+ bfd_put_16 (data->abfd, string->len, data->next_string);
+ memcpy (data->next_string + 2, string->string, string->len * 2);
+ data->next_string += (string->len + 1) * 2;
+}
+
+static inline unsigned int
+rsrc_compute_rva (rsrc_write_data * data,
+ bfd_byte * addr)
+{
+ return (addr - data->datastart) + data->rva_bias;
+}
+
+static void
+rsrc_write_leaf (rsrc_write_data * data,
+ rsrc_leaf * leaf)
+{
+ bfd_put_32 (data->abfd, rsrc_compute_rva (data, data->next_data),
+ data->next_leaf);
+ bfd_put_32 (data->abfd, leaf->size, data->next_leaf + 4);
+ bfd_put_32 (data->abfd, leaf->codepage, data->next_leaf + 8);
+ bfd_put_32 (data->abfd, 0 /*reserved*/, data->next_leaf + 12);
+ data->next_leaf += 16;
+
+ memcpy (data->next_data, leaf->data, leaf->size);
+ /* An undocumented feature of Windows resources is that each unit
+ of raw data is 8-byte aligned... */
+ data->next_data += ((leaf->size + 7) & ~7);
+}
+
+static void rsrc_write_directory (rsrc_write_data *, rsrc_directory *);
+
+static void
+rsrc_write_entry (rsrc_write_data * data,
+ bfd_byte * where,
+ rsrc_entry * entry)
+{
+ if (entry->is_name)
+ {
+ bfd_put_32 (data->abfd,
+ SetHighBit (data->next_string - data->datastart),
+ where);
+ rsrc_write_string (data, & entry->name_id.name);
+ }
+ else
+ bfd_put_32 (data->abfd, entry->name_id.id, where);
+
+ if (entry->is_dir)
+ {
+ bfd_put_32 (data->abfd,
+ SetHighBit (data->next_table - data->datastart),
+ where + 4);
+ rsrc_write_directory (data, entry->value.directory);
+ }
+ else
+ {
+ bfd_put_32 (data->abfd, data->next_leaf - data->datastart, where + 4);
+ rsrc_write_leaf (data, entry->value.leaf);
+ }
+}
+
+static void
+rsrc_compute_region_sizes (rsrc_directory * dir)
+{
+ struct rsrc_entry * entry;
+
+ if (dir == NULL)
+ return;
+
+ sizeof_tables_and_entries += 16;
+
+ for (entry = dir->names.first_entry; entry != NULL; entry = entry->next_entry)
+ {
+ sizeof_tables_and_entries += 8;
+
+ sizeof_strings += (entry->name_id.name.len + 1) * 2;
+
+ if (entry->is_dir)
+ rsrc_compute_region_sizes (entry->value.directory);
+ else
+ sizeof_leaves += 16;
+ }
+
+ for (entry = dir->ids.first_entry; entry != NULL; entry = entry->next_entry)
+ {
+ sizeof_tables_and_entries += 8;
+
+ if (entry->is_dir)
+ rsrc_compute_region_sizes (entry->value.directory);
+ else
+ sizeof_leaves += 16;
+ }
+}
+
+static void
+rsrc_write_directory (rsrc_write_data * data,
+ rsrc_directory * dir)
+{
+ rsrc_entry * entry;
+ unsigned int i;
+ bfd_byte * next_entry;
+ bfd_byte * nt;
+
+ bfd_put_32 (data->abfd, dir->characteristics, data->next_table);
+ bfd_put_32 (data->abfd, 0 /*dir->time*/, data->next_table + 4);
+ bfd_put_16 (data->abfd, dir->major, data->next_table + 8);
+ bfd_put_16 (data->abfd, dir->minor, data->next_table + 10);
+ bfd_put_16 (data->abfd, dir->names.num_entries, data->next_table + 12);
+ bfd_put_16 (data->abfd, dir->ids.num_entries, data->next_table + 14);
+
+ /* Compute where the entries and the next table will be placed. */
+ next_entry = data->next_table + 16;
+ data->next_table = next_entry + (dir->names.num_entries * 8)
+ + (dir->ids.num_entries * 8);
+ nt = data->next_table;
+
+ /* Write the entries. */
+ for (i = dir->names.num_entries, entry = dir->names.first_entry;
+ i > 0 && entry != NULL;
+ i--, entry = entry->next_entry)
+ {
+ BFD_ASSERT (entry->is_name);
+ rsrc_write_entry (data, next_entry, entry);
+ next_entry += 8;
+ }
+ BFD_ASSERT (i == 0);
+ BFD_ASSERT (entry == NULL);
+
+ for (i = dir->ids.num_entries, entry = dir->ids.first_entry;
+ i > 0 && entry != NULL;
+ i--, entry = entry->next_entry)
+ {
+ BFD_ASSERT (! entry->is_name);
+ rsrc_write_entry (data, next_entry, entry);
+ next_entry += 8;
+ }
+ BFD_ASSERT (i == 0);
+ BFD_ASSERT (entry == NULL);
+ BFD_ASSERT (nt == next_entry);
+}
+
+#if defined HAVE_WCHAR_H && ! defined __CYGWIN__ && ! defined __MINGW32__
+/* Return the length (number of units) of the first character in S,
+ putting its 'ucs4_t' representation in *PUC. */
+
+static unsigned int
+u16_mbtouc (wchar_t * puc, const unsigned short * s, unsigned int n)
+{
+ unsigned short c = * s;
+
+ if (c < 0xd800 || c >= 0xe000)
+ {
+ *puc = c;
+ return 1;
+ }
+
+ if (c < 0xdc00)
+ {
+ if (n >= 2)
+ {
+ if (s[1] >= 0xdc00 && s[1] < 0xe000)
+ {
+ *puc = 0x10000 + ((c - 0xd800) << 10) + (s[1] - 0xdc00);
+ return 2;
+ }
+ }
+ else
+ {
+ /* Incomplete multibyte character. */
+ *puc = 0xfffd;
+ return n;
+ }
+ }
+
+ /* Invalid multibyte character. */
+ *puc = 0xfffd;
+ return 1;
+}
+#endif /* HAVE_WCHAR_H and not Cygwin/Mingw */
+
+/* Perform a comparison of two entries. */
+static signed int
+rsrc_cmp (bfd_boolean is_name, rsrc_entry * a, rsrc_entry * b)
+{
+ signed int res;
+ bfd_byte * astring;
+ unsigned int alen;
+ bfd_byte * bstring;
+ unsigned int blen;
+
+ if (! is_name)
+ return a->name_id.id - b->name_id.id;
+
+ /* We have to perform a case insenstive, unicode string comparison... */
+ astring = a->name_id.name.string;
+ alen = a->name_id.name.len;
+ bstring = b->name_id.name.string;
+ blen = b->name_id.name.len;
+
+#if defined __CYGWIN__ || defined __MINGW32__
+ /* Under Windows hosts (both Cygwin and Mingw types),
+ unicode == UTF-16 == wchar_t. The case insensitive string comparison
+ function however goes by different names in the two environments... */
+
+#undef rscpcmp
+#ifdef __CYGWIN__
+#define rscpcmp wcsncasecmp
+#endif
+#ifdef __MINGW32__
+#define rscpcmp wcsnicmp
+#endif
+
+ res = rscpcmp ((const wchar_t *) astring, (const wchar_t *) bstring,
+ min (alen, blen));
+
+#elif defined HAVE_WCHAR_H
+ {
+ unsigned int i;
+ res = 0;
+ for (i = min (alen, blen); i--; astring += 2, bstring += 2)
+ {
+ wchar_t awc;
+ wchar_t bwc;
+
+ /* Convert UTF-16 unicode characters into wchar_t characters so
+ that we can then perform a case insensitive comparison. */
+ int Alen = u16_mbtouc (& awc, (const unsigned short *) astring, 2);
+ int Blen = u16_mbtouc (& bwc, (const unsigned short *) bstring, 2);
+
+ if (Alen != Blen)
+ return Alen - Blen;
+ res = wcsncasecmp (& awc, & bwc, 1);
+ if (res)
+ break;
+ }
+ }
+#else
+ /* Do the best we can - a case sensitive, untranslated comparison. */
+ res = memcmp (astring, bstring, min (alen, blen) * 2);
+#endif
+
+ if (res == 0)
+ res = alen - blen;
+
+ return res;
+}
+
+static void
+rsrc_print_name (char * buffer, rsrc_string string)
+{
+ unsigned int i;
+ bfd_byte * name = string.string;
+
+ for (i = string.len; i--; name += 2)
+ sprintf (buffer + strlen (buffer), "%.1s", name);
+}
+
+static const char *
+rsrc_resource_name (rsrc_entry * entry, rsrc_directory * dir)
+{
+ static char buffer [256];
+ bfd_boolean is_string = FALSE;
+
+ buffer[0] = 0;
+
+ if (dir != NULL && dir->entry != NULL && dir->entry->parent != NULL
+ && dir->entry->parent->entry != NULL)
+ {
+ strcpy (buffer, "type: ");
+ if (dir->entry->parent->entry->is_name)
+ rsrc_print_name (buffer + strlen (buffer),
+ dir->entry->parent->entry->name_id.name);
+ else
+ {
+ unsigned int id = dir->entry->parent->entry->name_id.id;
+
+ sprintf (buffer + strlen (buffer), "%x", id);
+ switch (id)
+ {
+ case 1: strcat (buffer, " (CURSOR)"); break;
+ case 2: strcat (buffer, " (BITMAP)"); break;
+ case 3: strcat (buffer, " (ICON)"); break;
+ case 4: strcat (buffer, " (MENU)"); break;
+ case 5: strcat (buffer, " (DIALOG)"); break;
+ case 6: strcat (buffer, " (STRING)"); is_string = TRUE; break;
+ case 7: strcat (buffer, " (FONTDIR)"); break;
+ case 8: strcat (buffer, " (FONT)"); break;
+ case 9: strcat (buffer, " (ACCELERATOR)"); break;
+ case 10: strcat (buffer, " (RCDATA)"); break;
+ case 11: strcat (buffer, " (MESSAGETABLE)"); break;
+ case 12: strcat (buffer, " (GROUP_CURSOR)"); break;
+ case 14: strcat (buffer, " (GROUP_ICON)"); break;
+ case 16: strcat (buffer, " (VERSION)"); break;
+ case 17: strcat (buffer, " (DLGINCLUDE)"); break;
+ case 19: strcat (buffer, " (PLUGPLAY)"); break;
+ case 20: strcat (buffer, " (VXD)"); break;
+ case 21: strcat (buffer, " (ANICURSOR)"); break;
+ case 22: strcat (buffer, " (ANIICON)"); break;
+ case 23: strcat (buffer, " (HTML)"); break;
+ case 24: strcat (buffer, " (MANIFEST)"); break;
+ case 240: strcat (buffer, " (DLGINIT)"); break;
+ case 241: strcat (buffer, " (TOOLBAR)"); break;
+ }
+ }
+ }
+
+ if (dir != NULL && dir->entry != NULL)
+ {
+ strcat (buffer, " name: ");
+ if (dir->entry->is_name)
+ rsrc_print_name (buffer + strlen (buffer), dir->entry->name_id.name);
+ else
+ {
+ unsigned int id = dir->entry->name_id.id;
+
+ sprintf (buffer + strlen (buffer), "%x", id);
+
+ if (is_string)
+ sprintf (buffer + strlen (buffer), " (resource id range: %d - %d)",
+ (id - 1) << 4, (id << 4) - 1);
+ }
+ }
+
+ if (entry != NULL)
+ {
+ strcat (buffer, " lang: ");
+
+ if (entry->is_name)
+ rsrc_print_name (buffer + strlen (buffer), entry->name_id.name);
+ else
+ sprintf (buffer + strlen (buffer), "%x", entry->name_id.id);
+ }
+
+ return buffer;
+}
+
+/* *sigh* Windows resource strings are special. Only the top 28-bits of
+ their ID is stored in the NAME entry. The bottom four bits are used as
+ an index into unicode string table that makes up the data of the leaf.
+ So identical type-name-lang string resources may not actually be
+ identical at all.
+
+ This function is called when we have detected two string resources with
+ match top-28-bit IDs. We have to scan the string tables inside the leaves
+ and discover if there are any real collisions. If there are then we report
+ them and return FALSE. Otherwise we copy any strings from B into A and
+ then return TRUE. */
+
+static bfd_boolean
+rsrc_merge_string_entries (rsrc_entry * a ATTRIBUTE_UNUSED,
+ rsrc_entry * b ATTRIBUTE_UNUSED)
+{
+ unsigned int copy_needed = 0;
+ unsigned int i;
+ bfd_byte * astring;
+ bfd_byte * bstring;
+ bfd_byte * new_data;
+ bfd_byte * nstring;
+
+ /* Step one: Find out what we have to do. */
+ BFD_ASSERT (! a->is_dir);
+ astring = a->value.leaf->data;
+
+ BFD_ASSERT (! b->is_dir);
+ bstring = b->value.leaf->data;
+
+ for (i = 0; i < 16; i++)
+ {
+ unsigned int alen = astring[0] + (astring[1] << 8);
+ unsigned int blen = bstring[0] + (bstring[1] << 8);
+
+ if (alen == 0)
+ {
+ copy_needed += blen * 2;
+ }
+ else if (blen == 0)
+ ;
+ else if (alen != blen)
+ /* FIXME: Should we continue the loop in order to report other duplicates ? */
+ break;
+ /* alen == blen != 0. We might have two identical strings. If so we
+ can ignore the second one. There is no need for wchar_t vs UTF-16
+ theatrics here - we are only interested in (case sensitive) equality. */
+ else if (memcmp (astring + 2, bstring + 2, alen * 2) != 0)
+ break;
+
+ astring += (alen + 1) * 2;
+ bstring += (blen + 1) * 2;
+ }
+
+ if (i != 16)
+ {
+ if (a->parent != NULL
+ && a->parent->entry != NULL
+ && a->parent->entry->is_name == FALSE)
+ _bfd_error_handler (_(".rsrc merge failure: duplicate string resource: %d"),
+ ((a->parent->entry->name_id.id - 1) << 4) + i);
+ return FALSE;
+ }
+
+ if (copy_needed == 0)
+ return TRUE;
+
+ /* If we reach here then A and B must both have non-colliding strings.
+ (We never get string resources with fully empty string tables).
+ We need to allocate an extra COPY_NEEDED bytes in A and then bring
+ in B's strings. */
+ new_data = bfd_malloc (a->value.leaf->size + copy_needed);
+ if (new_data == NULL)
+ return FALSE;
+
+ nstring = new_data;
+ astring = a->value.leaf->data;
+ bstring = b->value.leaf->data;
+
+ for (i = 0; i < 16; i++)
+ {
+ unsigned int alen = astring[0] + (astring[1] << 8);
+ unsigned int blen = bstring[0] + (bstring[1] << 8);
+
+ if (alen != 0)
+ {
+ memcpy (nstring, astring, (alen + 1) * 2);
+ nstring += (alen + 1) * 2;
+ }
+ else if (blen != 0)
+ {
+ memcpy (nstring, bstring, (blen + 1) * 2);
+ nstring += (blen + 1) * 2;
+ }
+ else
+ {
+ * nstring++ = 0;
+ * nstring++ = 0;
+ }
+
+ astring += (alen + 1) * 2;
+ bstring += (blen + 1) * 2;
+ }
+
+ BFD_ASSERT (nstring - new_data == (signed) (a->value.leaf->size + copy_needed));
+
+ free (a->value.leaf->data);
+ a->value.leaf->data = new_data;
+ a->value.leaf->size += copy_needed;
+
+ return TRUE;
+}
+
+static void rsrc_merge (rsrc_entry *, rsrc_entry *);
+
+/* Sort the entries in given part of the directory.
+ We use an old fashioned bubble sort because we are dealing
+ with lists and we want to handle matches specially. */
+
+static void
+rsrc_sort_entries (rsrc_dir_chain * chain,
+ bfd_boolean is_name,
+ rsrc_directory * dir)
+{
+ rsrc_entry * entry;
+ rsrc_entry * next;
+ rsrc_entry ** points_to_entry;
+ bfd_boolean swapped;
+
+ if (chain->num_entries < 2)
+ return;
+
+ do
+ {
+ swapped = FALSE;
+ points_to_entry = & chain->first_entry;
+ entry = * points_to_entry;
+ next = entry->next_entry;
+
+ do
+ {
+ signed int cmp = rsrc_cmp (is_name, entry, next);
+
+ if (cmp > 0)
+ {
+ entry->next_entry = next->next_entry;
+ next->next_entry = entry;
+ * points_to_entry = next;
+ points_to_entry = & next->next_entry;
+ next = entry->next_entry;
+ swapped = TRUE;
+ }
+ else if (cmp == 0)
+ {
+ if (entry->is_dir && next->is_dir)
+ {
+ /* When we encounter identical directory entries we have to
+ merge them together. The exception to this rule is for
+ resource manifests - there can only be one of these,
+ even if they differ in language. Zero-language manifests
+ are assumed to be default manifests (provided by the
+ Cygwin/MinGW build system) and these can be silently dropped,
+ unless that would reduce the number of manifests to zero.
+ There should only ever be one non-zero lang manifest -
+ if there are more it is an error. A non-zero lang
+ manifest takes precedence over a default manifest. */
+ if (entry->is_name == FALSE
+ && entry->name_id.id == 1
+ && dir != NULL
+ && dir->entry != NULL
+ && dir->entry->is_name == FALSE
+ && dir->entry->name_id.id == 0x18)
+ {
+ if (next->value.directory->names.num_entries == 0
+ && next->value.directory->ids.num_entries == 1
+ && next->value.directory->ids.first_entry->is_name == FALSE
+ && next->value.directory->ids.first_entry->name_id.id == 0)
+ /* Fall through so that NEXT is dropped. */
+ ;
+ else if (entry->value.directory->names.num_entries == 0
+ && entry->value.directory->ids.num_entries == 1
+ && entry->value.directory->ids.first_entry->is_name == FALSE
+ && entry->value.directory->ids.first_entry->name_id.id == 0)
+ {
+ /* Swap ENTRY and NEXT. Then fall through so that the old ENTRY is dropped. */
+ entry->next_entry = next->next_entry;
+ next->next_entry = entry;
+ * points_to_entry = next;
+ points_to_entry = & next->next_entry;
+ next = entry->next_entry;
+ swapped = TRUE;
+ }
+ else
+ {
+ _bfd_error_handler (_(".rsrc merge failure: multiple non-default manifests"));
+ bfd_set_error (bfd_error_file_truncated);
+ return;
+ }
+
+ /* Unhook NEXT from the chain. */
+ /* FIXME: memory loss here. */
+ entry->next_entry = next->next_entry;
+ chain->num_entries --;
+ if (chain->num_entries < 2)
+ return;
+ next = next->next_entry;
+ }
+ else
+ rsrc_merge (entry, next);
+ }
+ else if (entry->is_dir != next->is_dir)
+ {
+ _bfd_error_handler (_(".rsrc merge failure: a directory matches a leaf"));
+ bfd_set_error (bfd_error_file_truncated);
+ return;
+ }
+ else
+ {
+ /* Otherwise with identical leaves we issue an error
+ message - because there should never be duplicates.
+ The exception is Type 18/Name 1/Lang 0 which is the
+ defaul manifest - this can just be dropped. */
+ if (entry->is_name == FALSE
+ && entry->name_id.id == 0
+ && dir != NULL
+ && dir->entry != NULL
+ && dir->entry->is_name == FALSE
+ && dir->entry->name_id.id == 1
+ && dir->entry->parent != NULL
+ && dir->entry->parent->entry != NULL
+ && dir->entry->parent->entry->is_name == FALSE
+ && dir->entry->parent->entry->name_id.id == 0x18 /* RT_MANIFEST */)
+ ;
+ else if (dir != NULL
+ && dir->entry != NULL
+ && dir->entry->parent != NULL
+ && dir->entry->parent->entry != NULL
+ && dir->entry->parent->entry->is_name == FALSE
+ && dir->entry->parent->entry->name_id.id == 0x6 /* RT_STRING */)
+ {
+ /* Strings need special handling. */
+ if (! rsrc_merge_string_entries (entry, next))
+ {
+ /* _bfd_error_handler should have been called inside merge_strings. */
+ bfd_set_error (bfd_error_file_truncated);
+ return;
+ }
+ }
+ else
+ {
+ if (dir == NULL
+ || dir->entry == NULL
+ || dir->entry->parent == NULL
+ || dir->entry->parent->entry == NULL)
+ _bfd_error_handler (_(".rsrc merge failure: duplicate leaf"));
+ else
+ _bfd_error_handler (_(".rsrc merge failure: duplicate leaf: %s"),
+ rsrc_resource_name (entry, dir));
+ bfd_set_error (bfd_error_file_truncated);
+ return;
+ }
+ }
+
+ /* Unhook NEXT from the chain. */
+ entry->next_entry = next->next_entry;
+ chain->num_entries --;
+ if (chain->num_entries < 2)
+ return;
+ next = next->next_entry;
+ }
+ else
+ {
+ points_to_entry = & entry->next_entry;
+ entry = next;
+ next = next->next_entry;
+ }
+ }
+ while (next);
+
+ chain->last_entry = entry;
+ }
+ while (swapped);
+}
+
+/* Attach B's chain onto A. */
+static void
+rsrc_attach_chain (rsrc_dir_chain * achain, rsrc_dir_chain * bchain)
+{
+ if (bchain->num_entries == 0)
+ return;
+
+ achain->num_entries += bchain->num_entries;
+
+ if (achain->first_entry == NULL)
+ {
+ achain->first_entry = bchain->first_entry;
+ achain->last_entry = bchain->last_entry;
+ }
+ else
+ {
+ achain->last_entry->next_entry = bchain->first_entry;
+ achain->last_entry = bchain->last_entry;
+ }
+
+ bchain->num_entries = 0;
+ bchain->first_entry = bchain->last_entry = NULL;
+}
+
+static void
+rsrc_merge (struct rsrc_entry * a, struct rsrc_entry * b)
+{
+ rsrc_directory * adir;
+ rsrc_directory * bdir;
+
+ BFD_ASSERT (a->is_dir);
+ BFD_ASSERT (b->is_dir);
+
+ adir = a->value.directory;
+ bdir = b->value.directory;
+
+ if (adir->characteristics != bdir->characteristics)
+ {
+ _bfd_error_handler (_(".rsrc merge failure: dirs with differing characteristics\n"));
+ bfd_set_error (bfd_error_file_truncated);
+ return;
+ }
+
+ if (adir->major != bdir->major || adir->minor != bdir->minor)
+ {
+ _bfd_error_handler (_(".rsrc merge failure: differing directory versions\n"));
+ bfd_set_error (bfd_error_file_truncated);
+ return;
+ }
+
+ /* Attach B's name chain to A. */
+ rsrc_attach_chain (& adir->names, & bdir->names);
+
+ /* Attach B's ID chain to A. */
+ rsrc_attach_chain (& adir->ids, & bdir->ids);
+
+ /* Now sort A's entries. */
+ rsrc_sort_entries (& adir->names, TRUE, adir);
+ rsrc_sort_entries (& adir->ids, FALSE, adir);
+}
+
+/* Check the .rsrc section. If it contains multiple concatenated
+ resources then we must merge them properly. Otherwise Windows
+ will ignore all but the first set. */
+
+static void
+rsrc_process_section (bfd * abfd,
+ struct coff_final_link_info * pfinfo)
+{
+ rsrc_directory new_table;
+ bfd_size_type size;
+ asection * sec;
+ pe_data_type * pe;
+ bfd_vma rva_bias;
+ bfd_byte * data;
+ bfd_byte * datastart;
+ bfd_byte * dataend;
+ bfd_byte * new_data;
+ unsigned int num_resource_sets;
+ rsrc_directory * type_tables;
+ rsrc_write_data write_data;
+ unsigned int indx;
+ bfd * input;
+ unsigned int num_input_rsrc = 0;
+ unsigned int max_num_input_rsrc = 4;
+ ptrdiff_t * rsrc_sizes = NULL;
+
+ new_table.names.num_entries = 0;
+ new_table.ids.num_entries = 0;
+
+ sec = bfd_get_section_by_name (abfd, ".rsrc");
+ if (sec == NULL || (size = sec->rawsize) == 0)
+ return;
+
+ pe = pe_data (abfd);
+ if (pe == NULL)
+ return;
+
+ rva_bias = sec->vma - pe->pe_opthdr.ImageBase;
+
+ data = bfd_malloc (size);
+ if (data == NULL)
+ return;
+
+ datastart = data;
+
+ if (! bfd_get_section_contents (abfd, sec, data, 0, size))
+ goto end;
+
+ /* Step zero: Scan the input bfds looking for .rsrc sections and record
+ their lengths. Note - we rely upon the fact that the linker script
+ does *not* sort the input .rsrc sections, so that the order in the
+ linkinfo list matches the order in the output .rsrc section.
+
+ We need to know the lengths because each input .rsrc section has padding
+ at the end of a variable amount. (It does not appear to be based upon
+ the section alignment or the file alignment). We need to skip any
+ padding bytes when parsing the input .rsrc sections. */
+ rsrc_sizes = bfd_malloc (max_num_input_rsrc * sizeof * rsrc_sizes);
+ if (rsrc_sizes == NULL)
+ goto end;
+
+ for (input = pfinfo->info->input_bfds;
+ input != NULL;
+ input = input->link.next)
+ {
+ asection * rsrc_sec = bfd_get_section_by_name (input, ".rsrc");
+
+ if (rsrc_sec != NULL)
+ {
+ if (num_input_rsrc == max_num_input_rsrc)
+ {
+ max_num_input_rsrc += 10;
+ rsrc_sizes = bfd_realloc (rsrc_sizes, max_num_input_rsrc
+ * sizeof * rsrc_sizes);
+ if (rsrc_sizes == NULL)
+ goto end;
+ }
+
+ BFD_ASSERT (rsrc_sec->size > 0);
+ rsrc_sizes [num_input_rsrc ++] = rsrc_sec->size;
+ }
+ }
+
+ if (num_input_rsrc < 2)
+ goto end;
+
+ /* Step one: Walk the section, computing the size of the tables,
+ leaves and data and decide if we need to do anything. */
+ dataend = data + size;
+ num_resource_sets = 0;
+
+ while (data < dataend)
+ {
+ bfd_byte * p = data;
+
+ data = rsrc_count_directory (abfd, data, data, dataend, rva_bias);
+
+ if (data > dataend)
+ {
+ /* Corrupted .rsrc section - cannot merge. */
+ _bfd_error_handler (_("%s: .rsrc merge failure: corrupt .rsrc section"),
+ bfd_get_filename (abfd));
+ bfd_set_error (bfd_error_file_truncated);
+ goto end;
+ }
+
+ if ((data - p) > rsrc_sizes [num_resource_sets])
+ {
+ _bfd_error_handler (_("%s: .rsrc merge failure: unexpected .rsrc size"),
+ bfd_get_filename (abfd));
+ bfd_set_error (bfd_error_file_truncated);
+ goto end;
+ }
+ /* FIXME: Should we add a check for "data - p" being much smaller
+ than rsrc_sizes[num_resource_sets] ? */
+
+ data = p + rsrc_sizes[num_resource_sets];
+ rva_bias += data - p;
+ ++ num_resource_sets;
+ }
+ BFD_ASSERT (num_resource_sets == num_input_rsrc);
+
+ /* Step two: Walk the data again, building trees of the resources. */
+ data = datastart;
+ rva_bias = sec->vma - pe->pe_opthdr.ImageBase;
+
+ type_tables = bfd_malloc (num_resource_sets * sizeof * type_tables);
+ if (type_tables == NULL)
+ goto end;
+
+ indx = 0;
+ while (data < dataend)
+ {
+ bfd_byte * p = data;
+
+ (void) rsrc_parse_directory (abfd, type_tables + indx, data, data,
+ dataend, rva_bias, NULL);
+ data = p + rsrc_sizes[indx];
+ rva_bias += data - p;
+ ++ indx;
+ }
+ BFD_ASSERT (indx == num_resource_sets);
+
+ /* Step three: Merge the top level tables (there can be only one).
+
+ We must ensure that the merged entries are in ascending order.
+
+ We also thread the top level table entries from the old tree onto
+ the new table, so that they can be pulled off later. */
+
+ /* FIXME: Should we verify that all type tables are the same ? */
+ new_table.characteristics = type_tables[0].characteristics;
+ new_table.time = type_tables[0].time;
+ new_table.major = type_tables[0].major;
+ new_table.minor = type_tables[0].minor;
+
+ /* Chain the NAME entries onto the table. */
+ new_table.names.first_entry = NULL;
+ new_table.names.last_entry = NULL;
+
+ for (indx = 0; indx < num_resource_sets; indx++)
+ rsrc_attach_chain (& new_table.names, & type_tables[indx].names);
+
+ rsrc_sort_entries (& new_table.names, TRUE, & new_table);
+
+ /* Chain the ID entries onto the table. */
+ new_table.ids.first_entry = NULL;
+ new_table.ids.last_entry = NULL;
+
+ for (indx = 0; indx < num_resource_sets; indx++)
+ rsrc_attach_chain (& new_table.ids, & type_tables[indx].ids);
+
+ rsrc_sort_entries (& new_table.ids, FALSE, & new_table);
+
+ /* Step four: Create new contents for the .rsrc section. */
+ /* Step four point one: Compute the size of each region of the .rsrc section.
+ We do this now, rather than earlier, as the merging above may have dropped
+ some entries. */
+ sizeof_leaves = sizeof_strings = sizeof_tables_and_entries = 0;
+ rsrc_compute_region_sizes (& new_table);
+ /* We increment sizeof_strings to make sure that resource data
+ starts on an 8-byte boundary. FIXME: Is this correct ? */
+ sizeof_strings = (sizeof_strings + 7) & ~ 7;
+
+ new_data = bfd_zalloc (abfd, size);
+ if (new_data == NULL)
+ goto end;
+
+ write_data.abfd = abfd;
+ write_data.datastart = new_data;
+ write_data.next_table = new_data;
+ write_data.next_leaf = new_data + sizeof_tables_and_entries;
+ write_data.next_string = write_data.next_leaf + sizeof_leaves;
+ write_data.next_data = write_data.next_string + sizeof_strings;
+ write_data.rva_bias = sec->vma - pe->pe_opthdr.ImageBase;
+
+ rsrc_write_directory (& write_data, & new_table);
+
+ /* Step five: Replace the old contents with the new.
+ We recompute the size as we may have lost entries due to mergeing. */
+ size = ((write_data.next_data - new_data) + 3) & ~ 3;
+
+ {
+ int page_size;
+
+ if (coff_data (abfd)->link_info)
+ {
+ page_size = pe_data (abfd)->pe_opthdr.FileAlignment;
+
+ /* If no file alignment has been set, default to one.
+ This repairs 'ld -r' for arm-wince-pe target. */
+ if (page_size == 0)
+ page_size = 1;
+ }
+ else
+ page_size = PE_DEF_FILE_ALIGNMENT;
+ size = (size + page_size - 1) & - page_size;
+ }
+
+ bfd_set_section_contents (pfinfo->output_bfd, sec, new_data, 0, size);
+ sec->size = sec->rawsize = size;
+
+ end:
+ /* Step six: Free all the memory that we have used. */
+ /* FIXME: Free the resource tree, if we have one. */
+ free (datastart);
+ free (rsrc_sizes);
+}
+
+/* Handle the .idata section and other things that need symbol table
+ access. */
+
+bfd_boolean
+_bfd_XXi_final_link_postscript (bfd * abfd, struct coff_final_link_info *pfinfo)
+{
+ struct coff_link_hash_entry *h1;
+ struct bfd_link_info *info = pfinfo->info;
+ bfd_boolean result = TRUE;
+
+ /* There are a few fields that need to be filled in now while we
+ have symbol table access.
+
+ The .idata subsections aren't directly available as sections, but
+ they are in the symbol table, so get them from there. */
+
+ /* The import directory. This is the address of .idata$2, with size
+ of .idata$2 + .idata$3. */
+ h1 = coff_link_hash_lookup (coff_hash_table (info),
+ ".idata$2", FALSE, FALSE, TRUE);
+ if (h1 != NULL)
+ {
+ /* PR ld/2729: We cannot rely upon all the output sections having been
+ created properly, so check before referencing them. Issue a warning
+ message for any sections tht could not be found. */
+ if ((h1->root.type == bfd_link_hash_defined
+ || h1->root.type == bfd_link_hash_defweak)
+ && h1->root.u.def.section != NULL
+ && h1->root.u.def.section->output_section != NULL)
+ pe_data (abfd)->pe_opthdr.DataDirectory[PE_IMPORT_TABLE].VirtualAddress =
+ (h1->root.u.def.value
+ + h1->root.u.def.section->output_section->vma
+ + h1->root.u.def.section->output_offset);
+ else
+ {
+ _bfd_error_handler
+ (_("%B: unable to fill in DataDictionary[1] because .idata$2 is missing"),
+ abfd);
+ result = FALSE;
+ }
+
+ h1 = coff_link_hash_lookup (coff_hash_table (info),
+ ".idata$4", FALSE, FALSE, TRUE);
+ if (h1 != NULL
+ && (h1->root.type == bfd_link_hash_defined
+ || h1->root.type == bfd_link_hash_defweak)
+ && h1->root.u.def.section != NULL
+ && h1->root.u.def.section->output_section != NULL)
+ pe_data (abfd)->pe_opthdr.DataDirectory[PE_IMPORT_TABLE].Size =
+ ((h1->root.u.def.value
+ + h1->root.u.def.section->output_section->vma
+ + h1->root.u.def.section->output_offset)
+ - pe_data (abfd)->pe_opthdr.DataDirectory[PE_IMPORT_TABLE].VirtualAddress);
+ else
+ {
+ _bfd_error_handler
+ (_("%B: unable to fill in DataDictionary[1] because .idata$4 is missing"),
+ abfd);
+ result = FALSE;
+ }
+
+ /* The import address table. This is the size/address of
+ .idata$5. */
+ h1 = coff_link_hash_lookup (coff_hash_table (info),
+ ".idata$5", FALSE, FALSE, TRUE);
+ if (h1 != NULL
+ && (h1->root.type == bfd_link_hash_defined
+ || h1->root.type == bfd_link_hash_defweak)
+ && h1->root.u.def.section != NULL
+ && h1->root.u.def.section->output_section != NULL)
+ pe_data (abfd)->pe_opthdr.DataDirectory[PE_IMPORT_ADDRESS_TABLE].VirtualAddress =
+ (h1->root.u.def.value
+ + h1->root.u.def.section->output_section->vma
+ + h1->root.u.def.section->output_offset);
+ else
+ {
+ _bfd_error_handler
+ (_("%B: unable to fill in DataDictionary[12] because .idata$5 is missing"),
+ abfd);
+ result = FALSE;
+ }
+
+ h1 = coff_link_hash_lookup (coff_hash_table (info),
+ ".idata$6", FALSE, FALSE, TRUE);
+ if (h1 != NULL
+ && (h1->root.type == bfd_link_hash_defined
+ || h1->root.type == bfd_link_hash_defweak)
+ && h1->root.u.def.section != NULL
+ && h1->root.u.def.section->output_section != NULL)
+ pe_data (abfd)->pe_opthdr.DataDirectory[PE_IMPORT_ADDRESS_TABLE].Size =
+ ((h1->root.u.def.value
+ + h1->root.u.def.section->output_section->vma
+ + h1->root.u.def.section->output_offset)
+ - pe_data (abfd)->pe_opthdr.DataDirectory[PE_IMPORT_ADDRESS_TABLE].VirtualAddress);
+ else
+ {
+ _bfd_error_handler
+ (_("%B: unable to fill in DataDictionary[PE_IMPORT_ADDRESS_TABLE (12)] because .idata$6 is missing"),
+ abfd);
+ result = FALSE;
+ }
+ }
+ else
+ {
+ h1 = coff_link_hash_lookup (coff_hash_table (info),
+ "__IAT_start__", FALSE, FALSE, TRUE);
+ if (h1 != NULL
+ && (h1->root.type == bfd_link_hash_defined
+ || h1->root.type == bfd_link_hash_defweak)
+ && h1->root.u.def.section != NULL
+ && h1->root.u.def.section->output_section != NULL)
+ {
+ bfd_vma iat_va;
+
+ iat_va =
+ (h1->root.u.def.value
+ + h1->root.u.def.section->output_section->vma
+ + h1->root.u.def.section->output_offset);
+
+ h1 = coff_link_hash_lookup (coff_hash_table (info),
+ "__IAT_end__", FALSE, FALSE, TRUE);
+ if (h1 != NULL
+ && (h1->root.type == bfd_link_hash_defined
+ || h1->root.type == bfd_link_hash_defweak)
+ && h1->root.u.def.section != NULL
+ && h1->root.u.def.section->output_section != NULL)
+ {
+ pe_data (abfd)->pe_opthdr.DataDirectory[PE_IMPORT_ADDRESS_TABLE].Size =
+ ((h1->root.u.def.value
+ + h1->root.u.def.section->output_section->vma
+ + h1->root.u.def.section->output_offset)
+ - iat_va);
+ if (pe_data (abfd)->pe_opthdr.DataDirectory[PE_IMPORT_ADDRESS_TABLE].Size != 0)
+ pe_data (abfd)->pe_opthdr.DataDirectory[PE_IMPORT_ADDRESS_TABLE].VirtualAddress =
+ iat_va - pe_data (abfd)->pe_opthdr.ImageBase;
+ }
+ else
+ {
+ _bfd_error_handler
+ (_("%B: unable to fill in DataDictionary[PE_IMPORT_ADDRESS_TABLE(12)]"
+ " because .idata$6 is missing"), abfd);
+ result = FALSE;
+ }
+ }
+ }
+
+ h1 = coff_link_hash_lookup (coff_hash_table (info),
+ (bfd_get_symbol_leading_char (abfd) != 0
+ ? "__tls_used" : "_tls_used"),
+ FALSE, FALSE, TRUE);
+ if (h1 != NULL)
+ {
+ if ((h1->root.type == bfd_link_hash_defined
+ || h1->root.type == bfd_link_hash_defweak)
+ && h1->root.u.def.section != NULL
+ && h1->root.u.def.section->output_section != NULL)
+ pe_data (abfd)->pe_opthdr.DataDirectory[PE_TLS_TABLE].VirtualAddress =
+ (h1->root.u.def.value
+ + h1->root.u.def.section->output_section->vma
+ + h1->root.u.def.section->output_offset
+ - pe_data (abfd)->pe_opthdr.ImageBase);
+ else
+ {
+ _bfd_error_handler
+ (_("%B: unable to fill in DataDictionary[9] because __tls_used is missing"),
+ abfd);
+ result = FALSE;
+ }
+ /* According to PECOFF sepcifications by Microsoft version 8.2
+ the TLS data directory consists of 4 pointers, followed
+ by two 4-byte integer. This implies that the total size
+ is different for 32-bit and 64-bit executables. */
+#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64)
+ pe_data (abfd)->pe_opthdr.DataDirectory[PE_TLS_TABLE].Size = 0x18;
+#else
+ pe_data (abfd)->pe_opthdr.DataDirectory[PE_TLS_TABLE].Size = 0x28;
+#endif
+ }
+
+/* If there is a .pdata section and we have linked pdata finally, we
+ need to sort the entries ascending. */
+#if !defined(COFF_WITH_pep) && defined(COFF_WITH_pex64)
+ {
+ asection *sec = bfd_get_section_by_name (abfd, ".pdata");
+
+ if (sec)
+ {
+ bfd_size_type x = sec->rawsize;
+ bfd_byte *tmp_data = NULL;
+
+ if (x)
+ tmp_data = bfd_malloc (x);
+
+ if (tmp_data != NULL)
+ {
+ if (bfd_get_section_contents (abfd, sec, tmp_data, 0, x))
+ {
+ qsort (tmp_data,
+ (size_t) (x / 12),
+ 12, sort_x64_pdata);
+ bfd_set_section_contents (pfinfo->output_bfd, sec,
+ tmp_data, 0, x);
+ }
+ free (tmp_data);
+ }
+ }
+ }
+#endif
+
+ rsrc_process_section (abfd, pfinfo);
+
+ /* If we couldn't find idata$2, we either have an excessively
+ trivial program or are in DEEP trouble; we have to assume trivial
+ program.... */
+ return result;
+}
diff --git a/bfd/pef-traceback.h b/bfd/pef-traceback.h
new file mode 100644
index 0000000..fe5bf4d
--- /dev/null
+++ b/bfd/pef-traceback.h
@@ -0,0 +1,216 @@
+/* PowerPC traceback table support for BFD.
+ Copyright (C) 1993-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+
+/* Originally written by Ira Ruben, 06/28/93. */
+
+/* This is a compiler independent representation of the AIX Version 3 traceback table (in
+ sys/debug.h), which occurs, usually, one per procedure (routine). The table is marked by
+ a multiple of 4 32-bit word of zeroes in the instruction space. The traceback table is
+ also referred to as "procedure-end table".
+
+ The AIX traceback table representation on which this header is based is defined as a
+ series of bit field struct specifications. Bit fields are compiler dependent! Thus,
+ the definitions presented here follow the original header and the existing documentation
+ (such as it is), but define the fields as BIT MASKS and other macros. The mask names,
+ however, where chosen as the original field names to give some compatibility with the
+ original header and to agree with the documentation. */
+
+#ifndef __TRACEBACK__
+#define __TRACEBACK__
+
+#define TB_C 0U /* C */
+#define TB_FORTRAN 1U /* FORTRAN */
+#define TB_PASCAL 2U /* Pascal */
+#define TB_ADA 3U /* ADA */
+#define TB_PL1 4U /* PL1 */
+#define TB_BASIC 5U /* Basic */
+#define TB_LISP 6U /* Lisp */
+#define TB_COBOL 7U /* eCobol */
+#define TB_MODULA2 8U /* Modula2 */
+#define TB_CPLUSPLUS 9U /* C++ */
+#define TB_RPG 10U /* RPG */
+#define TB_PL8 11U /* PL8 */
+#define TB_ASM 12U /* Asm */
+
+/* Flags 1. */
+
+#define TB_GLOBALLINK 0x80U /* Routine is Global Linkage. */
+#define TB_is_eprol 0x40U /* Out-of-line prolog or epilog routine. */
+#define TB_HAS_TBOFF 0x20U /* tb_offset set (extension field). */
+#define TB_INT_PROC 0x10U /* Internal leaf routine. */
+#define TB_HAS_CTL 0x08U /* Has controlled automatic storage. */
+#define TB_TOCLESS 0X04U /* Routine has no TOC. */
+#define TB_FP_PRESENT 0x02U /* Routine has floating point ops. */
+#define TB_LOG_ABORT 0x01U /* fp_present && log/abort compiler opt. */
+
+/* Flags 2. */
+
+#define TB_INT_HNDL 0x80U /* Routine is an interrupt handler. */
+#define TB_NAME_PRESENT 0x40U /* Name_len/name set (extension field). */
+#define TB_USES_ALLOCA 0x20U /* Uses alloca() to allocate storage. */
+#define TB_CL_DIS_inv 0x1CU /* On-condition directives (see below). */
+#define TB_SAVES_CR 0x02U /* Routine saves the CR. */
+#define TB_SAVES_LR 0x01U /* Routine saves the LR. */
+
+/* cl_dis_inv "on condition" settings: */
+
+#define TB_CL_DIS_INV(x) (((x) & cl_dis_inv) >> 2U)
+
+#define TB_WALK_ONCOND 0U /* Walk stack without restoring state. */
+#define TB_DISCARD_ONCOND 1U /* Walk stack and discard. */
+#define TB_INVOKE_ONCOND 2U /* Invoke a specific system routine. */
+
+/* Flags 3. */
+
+#define TB_STORES_BC 0x80U /* Routine saves frame ptr of caller. */
+#define TB_SPARE2 0X40U /* Spare bit. */
+#define TB_FPR_SAVED 0x3fU /* Number of FPRs saved (max of 32). */
+ /* (Last reg saved is ALWAYS fpr31). */
+
+#define TB_NUM_FPR_SAVED(x) ((x) & fpr_saved)
+
+/* Flags 4. */
+
+#define TB_HAS_VEC_INFO 0x80U /* Routine uses vectors. */
+#define TB_SPARE3 0X40U /* Spare bit. */
+#define TB_GPR_SAVED 0x3fU /* Number of GPRs saved (max of 32). */
+ /* (Last reg saved is ALWAYS gpr31). */
+
+#define TB_NUM_GPR_SAVED(x) ((x) & gpr_saved)
+
+/* Flags 5. */
+
+#define TB_FLOATPARAMS 0xfeU /* Number of floating point parameters. */
+#define TB_PARAMSONSTK 0X01U /* All parameters are on the stack. */
+
+#define TB_NUM_FLOATPARAMS(X) (((x) & floatparams) >> 1U)
+
+/* Traceback_table (fixed portion). */
+
+struct traceback_table
+{
+ /* Traceback table layout (fixed portion): */
+
+ unsigned char version; /* Traceback format version. */
+ unsigned char lang; /* Language indicators: */
+ unsigned char flags1; /* Flag bits #1: */
+ unsigned char flags2; /* Flag bits #2: */
+ unsigned char flags3; /* Flag bits #3: */
+ unsigned char flags4; /* Flag bits #4: */
+ unsigned char fixedparams; /* Number of fixed point parameters. */
+ unsigned char flags5; /* Flag bits #5: */
+};
+
+/* traceback_table (optional) extensions. */
+
+/* Optional portions exist independently in the order presented below,
+ not as a structure or a union. Whether or not portions exist is
+ determinable from bit-fields within the fixed portion above. */
+
+/* The following is present only if fixedparams or floatparams are non
+ zero and it immediately follows the fixed portion of the traceback
+ table... */
+
+/* Order and type encoding of parameters: */
+struct traceback_table_fixedparams
+{
+ unsigned long paraminfo;
+};
+
+/* Left-justified bit-encoding as follows: */
+#define FIXED_PARAM 0 /* '0' ==> fixed param (1 gpr or word). */
+#define SPFP_PARAM 2 /* '10' ==> single-precision float param. */
+#define DPFP_PARAM 3 /* '11' ==> double-precision float param. */
+
+#define PARAM_ENCODING(x, bit) /* Yields xxx_PARAM as a function of "bit". */ \
+ ((((x)&(1UL<<(31UL-(bit++))))==0UL) /* Values 0:31 (left-to-right). "bit" is */ \
+ ? FIXED_PARAM /* an L-value that's left incremented to */ \
+ : ((((x)&(1UL<<(31UL-(bit++))))==0)/* the next bit position for the next */ \
+ ? SPFP_PARAM /* parameter. This will be 1 or 2 bit */ \
+ : DPFP_PARAM)) /* positions later. */
+
+/* The following is present only if has_tboff (in flags1) in fixed part is present... */
+
+/* Offset from start of code to TracebackTbl. */
+struct traceback_table_tboff
+{
+ unsigned long tb_offset;
+};
+
+/* The following is present only if int_hndl (in flags2) in fixed part is present ... */
+
+/* What interrupts are handled by the routine. */
+struct traceback_table_interrupts
+{
+ long hand_mask;
+};
+
+/* The following are present only if has_ctl (in flags1) in fixed part is present... */
+
+/* Controlled automatic storage info: */
+struct traceback_table_anchors
+{
+ unsigned long ctl_info; /* Number of controlled automatic anchors. */
+ long ctl_info_disp[1]; /* Array of stack displacements where each. */
+}; /* Anchor is located (array STARTS here). */
+
+/* The following are present only if name_present (in flags2) in fixed
+ part is present... */
+
+/* Routine name: */
+struct traceback_table_routine
+{
+ unsigned short name_len; /* Length of name that follows. */
+ char name[1]; /* Name starts here (NOT null terminated). */
+};
+
+/* The following are present only if uses_alloca (in flags2) in fixed
+ part is present... */
+
+/* Register auto storage when alloca() is used. */
+struct traceback_table_alloca
+{
+ char alloca_reg;
+};
+
+/* The following are present only if has_vec_info (in flags4) in fixed
+ part is present... */
+
+/* Vector info: */
+struct traceback_table_vector
+{
+ unsigned char vec_flags1; /* Vec info bits #1: */
+
+#define TB_VR_SAVED 0xFCU /* Number of saved vector registers. */
+#define TB_SAVES_VRSAVE 0x02U /* Saves VRsave. */
+#define TB_HAS_VARARGS 0x01U /* Routine has a variable argument list. */
+
+#define TB_NUM_VR_SAVED(x) (((x) & TB_VR_SAVED) >> 2U)
+
+ unsigned char vec_flags2; /* Vec info bits #2: */
+
+#define TB_VECTORPARAMS 0xfeU /* Number of vector parameters. */
+#define TB_VEC_PRESENT 0x01U /* Routine uses at least one vec instr. */
+
+#define VECPARAMS(x) (((x) & TB_VECTORPARAMS) >> 1U)
+};
+
+#endif
diff --git a/bfd/pef.c b/bfd/pef.c
new file mode 100644
index 0000000..4c29417
--- /dev/null
+++ b/bfd/pef.c
@@ -0,0 +1,1198 @@
+/* PEF support for BFD.
+ Copyright (C) 1999-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+/* PEF (Preferred Executable Format) is the binary file format for late
+ classic Mac OS versions (before Darwin). It is supported by both m68k
+ and PowerPc. It is also called CFM (Code Fragment Manager). */
+
+#include "sysdep.h"
+#include "safe-ctype.h"
+#include "pef.h"
+#include "pef-traceback.h"
+#include "bfd.h"
+#include "libbfd.h"
+#include "libiberty.h"
+
+#ifndef BFD_IO_FUNCS
+#define BFD_IO_FUNCS 0
+#endif
+
+#define bfd_pef_close_and_cleanup _bfd_generic_close_and_cleanup
+#define bfd_pef_bfd_free_cached_info _bfd_generic_bfd_free_cached_info
+#define bfd_pef_new_section_hook _bfd_generic_new_section_hook
+#define bfd_pef_bfd_is_local_label_name bfd_generic_is_local_label_name
+#define bfd_pef_bfd_is_target_special_symbol ((bfd_boolean (*) (bfd *, asymbol *)) bfd_false)
+#define bfd_pef_get_lineno _bfd_nosymbols_get_lineno
+#define bfd_pef_find_nearest_line _bfd_nosymbols_find_nearest_line
+#define bfd_pef_find_line _bfd_nosymbols_find_line
+#define bfd_pef_find_inliner_info _bfd_nosymbols_find_inliner_info
+#define bfd_pef_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol
+#define bfd_pef_read_minisymbols _bfd_generic_read_minisymbols
+#define bfd_pef_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol
+#define bfd_pef_set_arch_mach _bfd_generic_set_arch_mach
+#define bfd_pef_get_section_contents _bfd_generic_get_section_contents
+#define bfd_pef_set_section_contents _bfd_generic_set_section_contents
+#define bfd_pef_bfd_get_relocated_section_contents bfd_generic_get_relocated_section_contents
+#define bfd_pef_bfd_relax_section bfd_generic_relax_section
+#define bfd_pef_bfd_gc_sections bfd_generic_gc_sections
+#define bfd_pef_bfd_lookup_section_flags bfd_generic_lookup_section_flags
+#define bfd_pef_bfd_merge_sections bfd_generic_merge_sections
+#define bfd_pef_bfd_is_group_section bfd_generic_is_group_section
+#define bfd_pef_bfd_discard_group bfd_generic_discard_group
+#define bfd_pef_section_already_linked _bfd_generic_section_already_linked
+#define bfd_pef_bfd_define_common_symbol bfd_generic_define_common_symbol
+#define bfd_pef_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
+#define bfd_pef_bfd_link_add_symbols _bfd_generic_link_add_symbols
+#define bfd_pef_bfd_link_just_syms _bfd_generic_link_just_syms
+#define bfd_pef_bfd_copy_link_hash_symbol_type \
+ _bfd_generic_copy_link_hash_symbol_type
+#define bfd_pef_bfd_final_link _bfd_generic_final_link
+#define bfd_pef_bfd_link_split_section _bfd_generic_link_split_section
+#define bfd_pef_get_section_contents_in_window _bfd_generic_get_section_contents_in_window
+
+static int
+bfd_pef_parse_traceback_table (bfd *abfd,
+ asection *section,
+ unsigned char *buf,
+ size_t len,
+ size_t pos,
+ asymbol *sym,
+ FILE *file)
+{
+ struct traceback_table table;
+ size_t offset;
+ const char *s;
+ asymbol tmpsymbol;
+
+ if (sym == NULL)
+ sym = & tmpsymbol;
+
+ sym->name = NULL;
+ sym->value = 0;
+ sym->the_bfd = abfd;
+ sym->section = section;
+ sym->flags = 0;
+ sym->udata.i = 0;
+
+ /* memcpy is fine since all fields are unsigned char. */
+ if ((pos + 8) > len)
+ return -1;
+ memcpy (&table, buf + pos, 8);
+
+ /* Calling code relies on returned symbols having a name and
+ correct offset. */
+ if ((table.lang != TB_C) && (table.lang != TB_CPLUSPLUS))
+ return -1;
+
+ if (! (table.flags2 & TB_NAME_PRESENT))
+ return -1;
+
+ if (! (table.flags1 & TB_HAS_TBOFF))
+ return -1;
+
+ offset = 8;
+
+ if ((table.flags5 & TB_FLOATPARAMS) || (table.fixedparams))
+ offset += 4;
+
+ if (table.flags1 & TB_HAS_TBOFF)
+ {
+ struct traceback_table_tboff off;
+
+ if ((pos + offset + 4) > len)
+ return -1;
+ off.tb_offset = bfd_getb32 (buf + pos + offset);
+ offset += 4;
+
+ /* Need to subtract 4 because the offset includes the 0x0L
+ preceding the table. */
+ if (file != NULL)
+ fprintf (file, " [offset = 0x%lx]", off.tb_offset);
+
+ if ((file == NULL) && ((off.tb_offset + 4) > (pos + offset)))
+ return -1;
+
+ sym->value = pos - off.tb_offset - 4;
+ }
+
+ if (table.flags2 & TB_INT_HNDL)
+ offset += 4;
+
+ if (table.flags1 & TB_HAS_CTL)
+ {
+ struct traceback_table_anchors anchors;
+
+ if ((pos + offset + 4) > len)
+ return -1;
+ anchors.ctl_info = bfd_getb32 (buf + pos + offset);
+ offset += 4;
+
+ if (anchors.ctl_info > 1024)
+ return -1;
+
+ offset += anchors.ctl_info * 4;
+ }
+
+ if (table.flags2 & TB_NAME_PRESENT)
+ {
+ struct traceback_table_routine name;
+ char *namebuf;
+
+ if ((pos + offset + 2) > len)
+ return -1;
+ name.name_len = bfd_getb16 (buf + pos + offset);
+ offset += 2;
+
+ if (name.name_len > 4096)
+ return -1;
+
+ if ((pos + offset + name.name_len) > len)
+ return -1;
+
+ namebuf = bfd_alloc (abfd, name.name_len + 1);
+ if (namebuf == NULL)
+ return -1;
+
+ memcpy (namebuf, buf + pos + offset, name.name_len);
+ namebuf[name.name_len] = '\0';
+
+ /* Strip leading period inserted by compiler. */
+ if (namebuf[0] == '.')
+ memmove (namebuf, namebuf + 1, name.name_len + 1);
+
+ sym->name = namebuf;
+
+ for (s = sym->name; (*s != '\0'); s++)
+ if (! ISPRINT (*s))
+ return -1;
+
+ offset += name.name_len;
+ }
+
+ if (table.flags2 & TB_USES_ALLOCA)
+ offset += 4;
+
+ if (table.flags4 & TB_HAS_VEC_INFO)
+ offset += 4;
+
+ if (file != NULL)
+ fprintf (file, " [length = 0x%lx]", (unsigned long) offset);
+
+ return offset;
+}
+
+static void
+bfd_pef_print_symbol (bfd *abfd,
+ void * 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 (abfd, (void *) file, symbol);
+ fprintf (file, " %-5s %s", symbol->section->name, symbol->name);
+ if (CONST_STRNEQ (symbol->name, "__traceback_"))
+ {
+ unsigned char *buf = alloca (symbol->udata.i);
+ size_t offset = symbol->value + 4;
+ size_t len = symbol->udata.i;
+ int ret;
+
+ bfd_get_section_contents (abfd, symbol->section, buf, offset, len);
+ ret = bfd_pef_parse_traceback_table (abfd, symbol->section, buf,
+ len, 0, NULL, file);
+ if (ret < 0)
+ fprintf (file, " [ERROR]");
+ }
+ }
+}
+
+static void
+bfd_pef_convert_architecture (unsigned long architecture,
+ enum bfd_architecture *type,
+ unsigned long *subtype)
+{
+ const unsigned long ARCH_POWERPC = 0x70777063; /* 'pwpc'. */
+ const unsigned long ARCH_M68K = 0x6d36386b; /* 'm68k'. */
+
+ *subtype = bfd_arch_unknown;
+ *type = bfd_arch_unknown;
+
+ if (architecture == ARCH_POWERPC)
+ *type = bfd_arch_powerpc;
+ else if (architecture == ARCH_M68K)
+ *type = bfd_arch_m68k;
+}
+
+static bfd_boolean
+bfd_pef_mkobject (bfd *abfd ATTRIBUTE_UNUSED)
+{
+ return TRUE;
+}
+
+static const char *bfd_pef_section_name (bfd_pef_section *section)
+{
+ switch (section->section_kind)
+ {
+ case BFD_PEF_SECTION_CODE: return "code";
+ case BFD_PEF_SECTION_UNPACKED_DATA: return "unpacked-data";
+ case BFD_PEF_SECTION_PACKED_DATA: return "packed-data";
+ case BFD_PEF_SECTION_CONSTANT: return "constant";
+ case BFD_PEF_SECTION_LOADER: return "loader";
+ case BFD_PEF_SECTION_DEBUG: return "debug";
+ case BFD_PEF_SECTION_EXEC_DATA: return "exec-data";
+ case BFD_PEF_SECTION_EXCEPTION: return "exception";
+ case BFD_PEF_SECTION_TRACEBACK: return "traceback";
+ default: return "unknown";
+ }
+}
+
+static unsigned long bfd_pef_section_flags (bfd_pef_section *section)
+{
+ switch (section->section_kind)
+ {
+ case BFD_PEF_SECTION_CODE:
+ return SEC_HAS_CONTENTS | SEC_LOAD | SEC_ALLOC | SEC_CODE;
+ case BFD_PEF_SECTION_UNPACKED_DATA:
+ case BFD_PEF_SECTION_PACKED_DATA:
+ case BFD_PEF_SECTION_CONSTANT:
+ case BFD_PEF_SECTION_LOADER:
+ case BFD_PEF_SECTION_DEBUG:
+ case BFD_PEF_SECTION_EXEC_DATA:
+ case BFD_PEF_SECTION_EXCEPTION:
+ case BFD_PEF_SECTION_TRACEBACK:
+ default:
+ return SEC_HAS_CONTENTS | SEC_LOAD | SEC_ALLOC;
+ }
+}
+
+static asection *
+bfd_pef_make_bfd_section (bfd *abfd, bfd_pef_section *section)
+{
+ asection *bfdsec;
+ const char *name = bfd_pef_section_name (section);
+
+ bfdsec = bfd_make_section_anyway (abfd, name);
+ if (bfdsec == NULL)
+ return NULL;
+
+ bfdsec->vma = section->default_address + section->container_offset;
+ bfdsec->lma = section->default_address + section->container_offset;
+ bfdsec->size = section->container_length;
+ bfdsec->filepos = section->container_offset;
+ bfdsec->alignment_power = section->alignment;
+
+ bfdsec->flags = bfd_pef_section_flags (section);
+
+ return bfdsec;
+}
+
+int
+bfd_pef_parse_loader_header (bfd *abfd ATTRIBUTE_UNUSED,
+ unsigned char *buf,
+ size_t len,
+ bfd_pef_loader_header *header)
+{
+ BFD_ASSERT (len == 56);
+
+ header->main_section = bfd_getb32 (buf);
+ header->main_offset = bfd_getb32 (buf + 4);
+ header->init_section = bfd_getb32 (buf + 8);
+ header->init_offset = bfd_getb32 (buf + 12);
+ header->term_section = bfd_getb32 (buf + 16);
+ header->term_offset = bfd_getb32 (buf + 20);
+ header->imported_library_count = bfd_getb32 (buf + 24);
+ header->total_imported_symbol_count = bfd_getb32 (buf + 28);
+ header->reloc_section_count = bfd_getb32 (buf + 32);
+ header->reloc_instr_offset = bfd_getb32 (buf + 36);
+ header->loader_strings_offset = bfd_getb32 (buf + 40);
+ header->export_hash_offset = bfd_getb32 (buf + 44);
+ header->export_hash_table_power = bfd_getb32 (buf + 48);
+ header->exported_symbol_count = bfd_getb32 (buf + 52);
+
+ return 0;
+}
+
+int
+bfd_pef_parse_imported_library (bfd *abfd ATTRIBUTE_UNUSED,
+ unsigned char *buf,
+ size_t len,
+ bfd_pef_imported_library *header)
+{
+ BFD_ASSERT (len == 24);
+
+ header->name_offset = bfd_getb32 (buf);
+ header->old_implementation_version = bfd_getb32 (buf + 4);
+ header->current_version = bfd_getb32 (buf + 8);
+ header->imported_symbol_count = bfd_getb32 (buf + 12);
+ header->first_imported_symbol = bfd_getb32 (buf + 16);
+ header->options = buf[20];
+ header->reserved_a = buf[21];
+ header->reserved_b = bfd_getb16 (buf + 22);
+
+ return 0;
+}
+
+int
+bfd_pef_parse_imported_symbol (bfd *abfd ATTRIBUTE_UNUSED,
+ unsigned char *buf,
+ size_t len,
+ bfd_pef_imported_symbol *symbol)
+{
+ unsigned long value;
+
+ BFD_ASSERT (len == 4);
+
+ value = bfd_getb32 (buf);
+ symbol->symbol_class = value >> 24;
+ symbol->name = value & 0x00ffffff;
+
+ return 0;
+}
+
+int
+bfd_pef_scan_section (bfd *abfd, bfd_pef_section *section)
+{
+ unsigned char buf[28];
+
+ bfd_seek (abfd, section->header_offset, SEEK_SET);
+ if (bfd_bread ((void *) buf, 28, abfd) != 28)
+ return -1;
+
+ section->name_offset = bfd_h_get_32 (abfd, buf);
+ section->default_address = bfd_h_get_32 (abfd, buf + 4);
+ section->total_length = bfd_h_get_32 (abfd, buf + 8);
+ section->unpacked_length = bfd_h_get_32 (abfd, buf + 12);
+ section->container_length = bfd_h_get_32 (abfd, buf + 16);
+ section->container_offset = bfd_h_get_32 (abfd, buf + 20);
+ section->section_kind = buf[24];
+ section->share_kind = buf[25];
+ section->alignment = buf[26];
+ section->reserved = buf[27];
+
+ section->bfd_section = bfd_pef_make_bfd_section (abfd, section);
+ if (section->bfd_section == NULL)
+ return -1;
+
+ return 0;
+}
+
+void
+bfd_pef_print_loader_header (bfd *abfd ATTRIBUTE_UNUSED,
+ bfd_pef_loader_header *header,
+ FILE *file)
+{
+ fprintf (file, "main_section: %ld\n", header->main_section);
+ fprintf (file, "main_offset: %lu\n", header->main_offset);
+ fprintf (file, "init_section: %ld\n", header->init_section);
+ fprintf (file, "init_offset: %lu\n", header->init_offset);
+ fprintf (file, "term_section: %ld\n", header->term_section);
+ fprintf (file, "term_offset: %lu\n", header->term_offset);
+ fprintf (file, "imported_library_count: %lu\n",
+ header->imported_library_count);
+ fprintf (file, "total_imported_symbol_count: %lu\n",
+ header->total_imported_symbol_count);
+ fprintf (file, "reloc_section_count: %lu\n", header->reloc_section_count);
+ fprintf (file, "reloc_instr_offset: %lu\n", header->reloc_instr_offset);
+ fprintf (file, "loader_strings_offset: %lu\n",
+ header->loader_strings_offset);
+ fprintf (file, "export_hash_offset: %lu\n", header->export_hash_offset);
+ fprintf (file, "export_hash_table_power: %lu\n",
+ header->export_hash_table_power);
+ fprintf (file, "exported_symbol_count: %lu\n",
+ header->exported_symbol_count);
+}
+
+int
+bfd_pef_print_loader_section (bfd *abfd, FILE *file)
+{
+ bfd_pef_loader_header header;
+ asection *loadersec = NULL;
+ unsigned char *loaderbuf = NULL;
+ size_t loaderlen = 0;
+
+ loadersec = bfd_get_section_by_name (abfd, "loader");
+ if (loadersec == NULL)
+ return -1;
+
+ loaderlen = loadersec->size;
+ loaderbuf = bfd_malloc (loaderlen);
+
+ if (bfd_seek (abfd, loadersec->filepos, SEEK_SET) < 0
+ || bfd_bread ((void *) loaderbuf, loaderlen, abfd) != loaderlen
+ || loaderlen < 56
+ || bfd_pef_parse_loader_header (abfd, loaderbuf, 56, &header) < 0)
+ {
+ free (loaderbuf);
+ return -1;
+ }
+
+ bfd_pef_print_loader_header (abfd, &header, file);
+ return 0;
+}
+
+int
+bfd_pef_scan_start_address (bfd *abfd)
+{
+ bfd_pef_loader_header header;
+ asection *section;
+
+ asection *loadersec = NULL;
+ unsigned char *loaderbuf = NULL;
+ size_t loaderlen = 0;
+ int ret;
+
+ loadersec = bfd_get_section_by_name (abfd, "loader");
+ if (loadersec == NULL)
+ goto end;
+
+ loaderlen = loadersec->size;
+ loaderbuf = bfd_malloc (loaderlen);
+ if (bfd_seek (abfd, loadersec->filepos, SEEK_SET) < 0)
+ goto error;
+ if (bfd_bread ((void *) loaderbuf, loaderlen, abfd) != loaderlen)
+ goto error;
+
+ if (loaderlen < 56)
+ goto error;
+ ret = bfd_pef_parse_loader_header (abfd, loaderbuf, 56, &header);
+ if (ret < 0)
+ goto error;
+
+ if (header.main_section < 0)
+ goto end;
+
+ for (section = abfd->sections; section != NULL; section = section->next)
+ if ((section->index + 1) == header.main_section)
+ break;
+
+ if (section == NULL)
+ goto error;
+
+ abfd->start_address = section->vma + header.main_offset;
+
+ end:
+ if (loaderbuf != NULL)
+ free (loaderbuf);
+ return 0;
+
+ error:
+ if (loaderbuf != NULL)
+ free (loaderbuf);
+ return -1;
+}
+
+int
+bfd_pef_scan (bfd *abfd,
+ bfd_pef_header *header,
+ bfd_pef_data_struct *mdata)
+{
+ unsigned int i;
+ enum bfd_architecture cputype;
+ unsigned long cpusubtype;
+
+ mdata->header = *header;
+
+ bfd_pef_convert_architecture (header->architecture, &cputype, &cpusubtype);
+ if (cputype == bfd_arch_unknown)
+ {
+ (*_bfd_error_handler) (_("bfd_pef_scan: unknown architecture 0x%lx"),
+ header->architecture);
+ return -1;
+ }
+ bfd_set_arch_mach (abfd, cputype, cpusubtype);
+
+ mdata->header = *header;
+
+ abfd->flags = (abfd->xvec->object_flags
+ | (abfd->flags & (BFD_IN_MEMORY | BFD_IO_FUNCS)));
+
+ if (header->section_count != 0)
+ {
+ mdata->sections = bfd_alloc (abfd, header->section_count * sizeof (bfd_pef_section));
+
+ if (mdata->sections == NULL)
+ return -1;
+
+ for (i = 0; i < header->section_count; i++)
+ {
+ bfd_pef_section *cur = &mdata->sections[i];
+ cur->header_offset = 40 + (i * 28);
+ if (bfd_pef_scan_section (abfd, cur) < 0)
+ return -1;
+ }
+ }
+
+ if (bfd_pef_scan_start_address (abfd) < 0)
+ return -1;
+
+ abfd->tdata.pef_data = mdata;
+
+ return 0;
+}
+
+static int
+bfd_pef_read_header (bfd *abfd, bfd_pef_header *header)
+{
+ unsigned char buf[40];
+
+ bfd_seek (abfd, 0, SEEK_SET);
+
+ if (bfd_bread ((void *) buf, 40, abfd) != 40)
+ return -1;
+
+ header->tag1 = bfd_getb32 (buf);
+ header->tag2 = bfd_getb32 (buf + 4);
+ header->architecture = bfd_getb32 (buf + 8);
+ header->format_version = bfd_getb32 (buf + 12);
+ header->timestamp = bfd_getb32 (buf + 16);
+ header->old_definition_version = bfd_getb32 (buf + 20);
+ header->old_implementation_version = bfd_getb32 (buf + 24);
+ header->current_version = bfd_getb32 (buf + 28);
+ header->section_count = bfd_getb32 (buf + 32) + 1;
+ header->instantiated_section_count = bfd_getb32 (buf + 34);
+ header->reserved = bfd_getb32 (buf + 36);
+
+ return 0;
+}
+
+static const bfd_target *
+bfd_pef_object_p (bfd *abfd)
+{
+ bfd_pef_header header;
+ bfd_pef_data_struct *mdata;
+
+ if (bfd_pef_read_header (abfd, &header) != 0)
+ goto wrong;
+
+ if (header.tag1 != BFD_PEF_TAG1 || header.tag2 != BFD_PEF_TAG2)
+ goto wrong;
+
+ mdata = (bfd_pef_data_struct *) bfd_zalloc (abfd, sizeof (*mdata));
+ if (mdata == NULL)
+ goto fail;
+
+ if (bfd_pef_scan (abfd, &header, mdata))
+ goto wrong;
+
+ return abfd->xvec;
+
+ wrong:
+ bfd_set_error (bfd_error_wrong_format);
+
+ fail:
+ return NULL;
+}
+
+static int
+bfd_pef_parse_traceback_tables (bfd *abfd,
+ asection *sec,
+ unsigned char *buf,
+ size_t len,
+ long *nsym,
+ asymbol **csym)
+{
+ char *name;
+
+ asymbol function;
+ asymbol traceback;
+
+ const char *const tbprefix = "__traceback_";
+ size_t tbnamelen;
+
+ size_t pos = 0;
+ unsigned long count = 0;
+ int ret;
+
+ for (;;)
+ {
+ /* We're reading symbols two at a time. */
+ if (csym && ((csym[count] == NULL) || (csym[count + 1] == NULL)))
+ break;
+
+ pos += 3;
+ pos -= (pos % 4);
+
+ while ((pos + 4) <= len)
+ {
+ if (bfd_getb32 (buf + pos) == 0)
+ break;
+ pos += 4;
+ }
+
+ if ((pos + 4) > len)
+ break;
+
+ ret = bfd_pef_parse_traceback_table (abfd, sec, buf, len, pos + 4,
+ &function, 0);
+ if (ret < 0)
+ {
+ /* Skip over 0x0L to advance to next possible traceback table. */
+ pos += 4;
+ continue;
+ }
+
+ BFD_ASSERT (function.name != NULL);
+
+ /* Don't bother to compute the name if we are just
+ counting symbols. */
+ if (csym)
+ {
+ tbnamelen = strlen (tbprefix) + strlen (function.name);
+ name = bfd_alloc (abfd, tbnamelen + 1);
+ if (name == NULL)
+ {
+ bfd_release (abfd, (void *) function.name);
+ function.name = NULL;
+ break;
+ }
+ snprintf (name, tbnamelen + 1, "%s%s", tbprefix, function.name);
+ traceback.name = name;
+ traceback.value = pos;
+ traceback.the_bfd = abfd;
+ traceback.section = sec;
+ traceback.flags = 0;
+ traceback.udata.i = ret;
+
+ *(csym[count]) = function;
+ *(csym[count + 1]) = traceback;
+ }
+
+ pos += ret;
+ count += 2;
+ }
+
+ *nsym = count;
+ return 0;
+}
+
+static int
+bfd_pef_parse_function_stub (bfd *abfd ATTRIBUTE_UNUSED,
+ unsigned char *buf,
+ size_t len,
+ unsigned long *offset)
+{
+ BFD_ASSERT (len == 24);
+
+ if ((bfd_getb32 (buf) & 0xffff0000) != 0x81820000)
+ return -1;
+ if (bfd_getb32 (buf + 4) != 0x90410014)
+ return -1;
+ if (bfd_getb32 (buf + 8) != 0x800c0000)
+ return -1;
+ if (bfd_getb32 (buf + 12) != 0x804c0004)
+ return -1;
+ if (bfd_getb32 (buf + 16) != 0x7c0903a6)
+ return -1;
+ if (bfd_getb32 (buf + 20) != 0x4e800420)
+ return -1;
+
+ if (offset != NULL)
+ *offset = (bfd_getb32 (buf) & 0x0000ffff) / 4;
+
+ return 0;
+}
+
+static int
+bfd_pef_parse_function_stubs (bfd *abfd,
+ asection *codesec,
+ unsigned char *codebuf,
+ size_t codelen,
+ unsigned char *loaderbuf,
+ size_t loaderlen,
+ unsigned long *nsym,
+ asymbol **csym)
+{
+ const char *const sprefix = "__stub_";
+ size_t codepos = 0;
+ unsigned long count = 0;
+ bfd_pef_loader_header header;
+ bfd_pef_imported_library *libraries = NULL;
+ bfd_pef_imported_symbol *imports = NULL;
+ unsigned long i;
+ int ret;
+
+ if (loaderlen < 56)
+ goto error;
+
+ ret = bfd_pef_parse_loader_header (abfd, loaderbuf, 56, &header);
+ if (ret < 0)
+ goto error;
+
+ libraries = bfd_malloc
+ (header.imported_library_count * sizeof (bfd_pef_imported_library));
+ imports = bfd_malloc
+ (header.total_imported_symbol_count * sizeof (bfd_pef_imported_symbol));
+
+ if (loaderlen < (56 + (header.imported_library_count * 24)))
+ goto error;
+ for (i = 0; i < header.imported_library_count; i++)
+ {
+ ret = bfd_pef_parse_imported_library
+ (abfd, loaderbuf + 56 + (i * 24), 24, &libraries[i]);
+ if (ret < 0)
+ goto error;
+ }
+
+ if (loaderlen < (56 + (header.imported_library_count * 24)
+ + (header.total_imported_symbol_count * 4)))
+ goto error;
+ for (i = 0; i < header.total_imported_symbol_count; i++)
+ {
+ ret = (bfd_pef_parse_imported_symbol
+ (abfd,
+ loaderbuf + 56 + (header.imported_library_count * 24) + (i * 4),
+ 4, &imports[i]));
+ if (ret < 0)
+ goto error;
+ }
+
+ codepos = 0;
+
+ for (;;)
+ {
+ asymbol sym;
+ const char *symname;
+ char *name;
+ unsigned long sym_index;
+
+ if (csym && (csym[count] == NULL))
+ break;
+
+ codepos += 3;
+ codepos -= (codepos % 4);
+
+ while ((codepos + 4) <= codelen)
+ {
+ if ((bfd_getb32 (codebuf + codepos) & 0xffff0000) == 0x81820000)
+ break;
+ codepos += 4;
+ }
+
+ if ((codepos + 4) > codelen)
+ break;
+
+ ret = bfd_pef_parse_function_stub (abfd, codebuf + codepos, 24, &sym_index);
+ if (ret < 0)
+ {
+ codepos += 24;
+ continue;
+ }
+
+ if (sym_index >= header.total_imported_symbol_count)
+ {
+ codepos += 24;
+ continue;
+ }
+
+ {
+ size_t max, namelen;
+ const char *s;
+
+ if (loaderlen < (header.loader_strings_offset + imports[sym_index].name))
+ goto error;
+
+ max = loaderlen - (header.loader_strings_offset + imports[sym_index].name);
+ symname = (char *) loaderbuf;
+ symname += header.loader_strings_offset + imports[sym_index].name;
+ namelen = 0;
+ for (s = symname; s < (symname + max); s++)
+ {
+ if (*s == '\0')
+ break;
+ if (! ISPRINT (*s))
+ goto error;
+ namelen++;
+ }
+ if (*s != '\0')
+ goto error;
+
+ name = bfd_alloc (abfd, strlen (sprefix) + namelen + 1);
+ if (name == NULL)
+ break;
+
+ snprintf (name, strlen (sprefix) + namelen + 1, "%s%s",
+ sprefix, symname);
+ sym.name = name;
+ }
+
+ sym.value = codepos;
+ sym.the_bfd = abfd;
+ sym.section = codesec;
+ sym.flags = 0;
+ sym.udata.i = 0;
+
+ codepos += 24;
+
+ if (csym != NULL)
+ *(csym[count]) = sym;
+
+ count++;
+ }
+
+ goto end;
+
+ end:
+ if (libraries != NULL)
+ free (libraries);
+ if (imports != NULL)
+ free (imports);
+ *nsym = count;
+ return 0;
+
+ error:
+ if (libraries != NULL)
+ free (libraries);
+ if (imports != NULL)
+ free (imports);
+ *nsym = count;
+ return -1;
+}
+
+static long
+bfd_pef_parse_symbols (bfd *abfd, asymbol **csym)
+{
+ unsigned long count = 0;
+
+ asection *codesec = NULL;
+ unsigned char *codebuf = NULL;
+ size_t codelen = 0;
+
+ asection *loadersec = NULL;
+ unsigned char *loaderbuf = NULL;
+ size_t loaderlen = 0;
+
+ codesec = bfd_get_section_by_name (abfd, "code");
+ if (codesec != NULL)
+ {
+ codelen = codesec->size;
+ codebuf = bfd_malloc (codelen);
+ if (bfd_seek (abfd, codesec->filepos, SEEK_SET) < 0)
+ goto end;
+ if (bfd_bread ((void *) codebuf, codelen, abfd) != codelen)
+ goto end;
+ }
+
+ loadersec = bfd_get_section_by_name (abfd, "loader");
+ if (loadersec != NULL)
+ {
+ loaderlen = loadersec->size;
+ loaderbuf = bfd_malloc (loaderlen);
+ if (bfd_seek (abfd, loadersec->filepos, SEEK_SET) < 0)
+ goto end;
+ if (bfd_bread ((void *) loaderbuf, loaderlen, abfd) != loaderlen)
+ goto end;
+ }
+
+ count = 0;
+ if (codesec != NULL)
+ {
+ long ncount = 0;
+ bfd_pef_parse_traceback_tables (abfd, codesec, codebuf, codelen,
+ &ncount, csym);
+ count += ncount;
+ }
+
+ if ((codesec != NULL) && (loadersec != NULL))
+ {
+ unsigned long ncount = 0;
+ bfd_pef_parse_function_stubs
+ (abfd, codesec, codebuf, codelen, loaderbuf, loaderlen, &ncount,
+ (csym != NULL) ? (csym + count) : NULL);
+ count += ncount;
+ }
+
+ if (csym != NULL)
+ csym[count] = NULL;
+
+ end:
+ if (codebuf != NULL)
+ free (codebuf);
+
+ if (loaderbuf != NULL)
+ free (loaderbuf);
+
+ return count;
+}
+
+static long
+bfd_pef_count_symbols (bfd *abfd)
+{
+ return bfd_pef_parse_symbols (abfd, NULL);
+}
+
+static long
+bfd_pef_get_symtab_upper_bound (bfd *abfd)
+{
+ long nsyms = bfd_pef_count_symbols (abfd);
+
+ if (nsyms < 0)
+ return nsyms;
+ return ((nsyms + 1) * sizeof (asymbol *));
+}
+
+static long
+bfd_pef_canonicalize_symtab (bfd *abfd, asymbol **alocation)
+{
+ long i;
+ asymbol *syms;
+ long ret;
+ long nsyms = bfd_pef_count_symbols (abfd);
+
+ if (nsyms < 0)
+ return nsyms;
+
+ syms = bfd_alloc (abfd, nsyms * sizeof (asymbol));
+ if (syms == NULL)
+ return -1;
+
+ for (i = 0; i < nsyms; i++)
+ alocation[i] = &syms[i];
+
+ alocation[nsyms] = NULL;
+
+ ret = bfd_pef_parse_symbols (abfd, alocation);
+ if (ret != nsyms)
+ return 0;
+
+ return ret;
+}
+
+#define bfd_pef_make_empty_symbol _bfd_generic_make_empty_symbol
+
+static void
+bfd_pef_get_symbol_info (bfd *abfd ATTRIBUTE_UNUSED,
+ asymbol *symbol,
+ symbol_info *ret)
+{
+ bfd_symbol_info (symbol, ret);
+}
+
+static int
+bfd_pef_sizeof_headers (bfd *abfd ATTRIBUTE_UNUSED,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+const bfd_target pef_vec =
+{
+ "pef", /* Name. */
+ bfd_target_pef_flavour, /* Flavour. */
+ BFD_ENDIAN_BIG, /* Byteorder. */
+ BFD_ENDIAN_BIG, /* Header_byteorder. */
+ (HAS_RELOC | EXEC_P | /* Object flags. */
+ HAS_LINENO | HAS_DEBUG |
+ HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED),
+ (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. */
+ 0, /* match priority. */
+ 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, /* Headers. */
+ { /* bfd_check_format. */
+ _bfd_dummy_target,
+ bfd_pef_object_p, /* bfd_check_format. */
+ _bfd_dummy_target,
+ _bfd_dummy_target,
+ },
+ { /* bfd_set_format. */
+ bfd_false,
+ bfd_pef_mkobject,
+ bfd_false,
+ bfd_false,
+ },
+ { /* bfd_write_contents. */
+ bfd_false,
+ bfd_true,
+ bfd_false,
+ bfd_false,
+ },
+
+ BFD_JUMP_TABLE_GENERIC (bfd_pef),
+ BFD_JUMP_TABLE_COPY (_bfd_generic),
+ BFD_JUMP_TABLE_CORE (_bfd_nocore),
+ BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive),
+ BFD_JUMP_TABLE_SYMBOLS (bfd_pef),
+ BFD_JUMP_TABLE_RELOCS (_bfd_norelocs),
+ BFD_JUMP_TABLE_WRITE (bfd_pef),
+ BFD_JUMP_TABLE_LINK (bfd_pef),
+ BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
+
+ NULL,
+
+ NULL
+};
+
+#define bfd_pef_xlib_close_and_cleanup _bfd_generic_close_and_cleanup
+#define bfd_pef_xlib_bfd_free_cached_info _bfd_generic_bfd_free_cached_info
+#define bfd_pef_xlib_new_section_hook _bfd_generic_new_section_hook
+#define bfd_pef_xlib_get_section_contents _bfd_generic_get_section_contents
+#define bfd_pef_xlib_set_section_contents _bfd_generic_set_section_contents
+#define bfd_pef_xlib_get_section_contents_in_window _bfd_generic_get_section_contents_in_window
+#define bfd_pef_xlib_set_section_contents_in_window _bfd_generic_set_section_contents_in_window
+
+static int
+bfd_pef_xlib_read_header (bfd *abfd, bfd_pef_xlib_header *header)
+{
+ unsigned char buf[80];
+
+ bfd_seek (abfd, 0, SEEK_SET);
+
+ if (bfd_bread ((void *) buf, sizeof buf, abfd) != sizeof buf)
+ return -1;
+
+ header->tag1 = bfd_getb32 (buf);
+ header->tag2 = bfd_getb32 (buf + 4);
+ header->current_format = bfd_getb32 (buf + 8);
+ header->container_strings_offset = bfd_getb32 (buf + 12);
+ header->export_hash_offset = bfd_getb32 (buf + 16);
+ header->export_key_offset = bfd_getb32 (buf + 20);
+ header->export_symbol_offset = bfd_getb32 (buf + 24);
+ header->export_names_offset = bfd_getb32 (buf + 28);
+ header->export_hash_table_power = bfd_getb32 (buf + 32);
+ header->exported_symbol_count = bfd_getb32 (buf + 36);
+ header->frag_name_offset = bfd_getb32 (buf + 40);
+ header->frag_name_length = bfd_getb32 (buf + 44);
+ header->dylib_path_offset = bfd_getb32 (buf + 48);
+ header->dylib_path_length = bfd_getb32 (buf + 52);
+ header->cpu_family = bfd_getb32 (buf + 56);
+ header->cpu_model = bfd_getb32 (buf + 60);
+ header->date_time_stamp = bfd_getb32 (buf + 64);
+ header->current_version = bfd_getb32 (buf + 68);
+ header->old_definition_version = bfd_getb32 (buf + 72);
+ header->old_implementation_version = bfd_getb32 (buf + 76);
+
+ return 0;
+}
+
+static int
+bfd_pef_xlib_scan (bfd *abfd, bfd_pef_xlib_header *header)
+{
+ bfd_pef_xlib_data_struct *mdata = NULL;
+
+ mdata = bfd_alloc (abfd, sizeof (* mdata));
+ if (mdata == NULL)
+ return -1;
+
+ mdata->header = *header;
+
+ abfd->flags = (abfd->xvec->object_flags
+ | (abfd->flags & (BFD_IN_MEMORY | BFD_IO_FUNCS)));
+
+ abfd->tdata.pef_xlib_data = mdata;
+
+ return 0;
+}
+
+static const bfd_target *
+bfd_pef_xlib_object_p (bfd *abfd)
+{
+ bfd_pef_xlib_header header;
+
+ if (bfd_pef_xlib_read_header (abfd, &header) != 0)
+ {
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+
+ if ((header.tag1 != BFD_PEF_XLIB_TAG1)
+ || ((header.tag2 != BFD_PEF_VLIB_TAG2)
+ && (header.tag2 != BFD_PEF_BLIB_TAG2)))
+ {
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+
+ if (bfd_pef_xlib_scan (abfd, &header) != 0)
+ {
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+
+ return abfd->xvec;
+}
+
+const bfd_target pef_xlib_vec =
+{
+ "pef-xlib", /* Name. */
+ bfd_target_pef_xlib_flavour, /* Flavour. */
+ BFD_ENDIAN_BIG, /* Byteorder */
+ BFD_ENDIAN_BIG, /* Header_byteorder. */
+ (HAS_RELOC | EXEC_P | /* Object flags. */
+ HAS_LINENO | HAS_DEBUG |
+ HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED),
+ (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. */
+ 0, /* match priority. */
+ 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, /* Headers. */
+ { /* bfd_check_format. */
+ _bfd_dummy_target,
+ bfd_pef_xlib_object_p, /* bfd_check_format. */
+ _bfd_dummy_target,
+ _bfd_dummy_target,
+ },
+ { /* bfd_set_format. */
+ bfd_false,
+ bfd_pef_mkobject,
+ bfd_false,
+ bfd_false,
+ },
+ { /* bfd_write_contents. */
+ bfd_false,
+ bfd_true,
+ bfd_false,
+ bfd_false,
+ },
+
+ BFD_JUMP_TABLE_GENERIC (bfd_pef_xlib),
+ BFD_JUMP_TABLE_COPY (_bfd_generic),
+ BFD_JUMP_TABLE_CORE (_bfd_nocore),
+ BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive),
+ BFD_JUMP_TABLE_SYMBOLS (_bfd_nosymbols),
+ BFD_JUMP_TABLE_RELOCS (_bfd_norelocs),
+ BFD_JUMP_TABLE_WRITE (_bfd_nowrite),
+ BFD_JUMP_TABLE_LINK (_bfd_nolink),
+ BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
+
+ NULL,
+
+ NULL
+};
diff --git a/bfd/pef.h b/bfd/pef.h
new file mode 100644
index 0000000..49527c9
--- /dev/null
+++ b/bfd/pef.h
@@ -0,0 +1,187 @@
+/* PEF support for BFD.
+ Copyright (C) 1999-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+
+#include <stdio.h>
+
+struct bfd_pef_header
+{
+ unsigned long tag1;
+ unsigned long tag2;
+ unsigned long architecture;
+ unsigned long format_version;
+ unsigned long timestamp;
+ unsigned long old_definition_version;
+ unsigned long old_implementation_version;
+ unsigned long current_version;
+ unsigned short section_count;
+ unsigned short instantiated_section_count;
+ unsigned long reserved;
+};
+typedef struct bfd_pef_header bfd_pef_header;
+
+struct bfd_pef_loader_header
+{
+ long main_section;
+ unsigned long main_offset;
+ long init_section;
+ unsigned long init_offset;
+ long term_section;
+ unsigned long term_offset;
+ unsigned long imported_library_count;
+ unsigned long total_imported_symbol_count;
+ unsigned long reloc_section_count;
+ unsigned long reloc_instr_offset;
+ unsigned long loader_strings_offset;
+ unsigned long export_hash_offset;
+ unsigned long export_hash_table_power;
+ unsigned long exported_symbol_count;
+};
+typedef struct bfd_pef_loader_header bfd_pef_loader_header;
+
+struct bfd_pef_imported_library
+{
+ unsigned long name_offset;
+ unsigned long old_implementation_version;
+ unsigned long current_version;
+ unsigned long imported_symbol_count;
+ unsigned long first_imported_symbol;
+ unsigned char options;
+ unsigned char reserved_a;
+ unsigned short reserved_b;
+};
+typedef struct bfd_pef_imported_library bfd_pef_imported_library;
+
+enum bfd_pef_imported_library_options
+ {
+ BFD_PEF_WEAK_IMPORT_LIB = 0x40,
+ BFD_PEF_INIT_LIB_BEFORE = 0x80
+ };
+
+struct bfd_pef_imported_symbol
+{
+ unsigned char symbol_class;
+ unsigned long name;
+};
+typedef struct bfd_pef_imported_symbol bfd_pef_imported_symbol;
+
+enum bfd_pef_imported_symbol_class
+ {
+ BFD_PEF_CODE_SYMBOL = 0x00,
+ BFD_PEF_DATA_SYMBOL = 0x01,
+ BFD_PEF_TVECTOR_SYMBOL = 0x02,
+ BFD_PEF_TOC_SYMBOL = 0x03,
+ BFD_PEF_GLUE_SYMBOL = 0x04,
+ BFD_PEF_UNDEFINED_SYMBOL = 0x0F,
+ BFD_PEF_WEAK_IMPORT_SYMBOL_MASK = 0x80
+ };
+
+#define BFD_PEF_TAG1 0x4A6F7921 /* 'Joy!' */
+#define BFD_PEF_TAG2 0x70656666 /* 'peff' */
+
+#define BFD_PEF_VERSION 0x00000001
+
+struct bfd_pef_section
+{
+ long name_offset;
+ unsigned long header_offset;
+ unsigned long default_address;
+ unsigned long total_length;
+ unsigned long unpacked_length;
+ unsigned long container_length;
+ unsigned long container_offset;
+ unsigned char section_kind;
+ unsigned char share_kind;
+ unsigned char alignment;
+ unsigned char reserved;
+ asection *bfd_section;
+};
+typedef struct bfd_pef_section bfd_pef_section;
+
+#define BFD_PEF_SECTION_CODE 0
+#define BFD_PEF_SECTION_UNPACKED_DATA 1
+#define BFD_PEF_SECTION_PACKED_DATA 2
+#define BFD_PEF_SECTION_CONSTANT 3
+#define BFD_PEF_SECTION_LOADER 4
+#define BFD_PEF_SECTION_DEBUG 5
+#define BFD_PEF_SECTION_EXEC_DATA 6
+#define BFD_PEF_SECTION_EXCEPTION 7
+#define BFD_PEF_SECTION_TRACEBACK 8
+
+#define BFD_PEF_SHARE_PROCESS 1
+#define BFD_PEF_SHARE_GLOBAL 4
+#define BFD_PEF_SHARE_PROTECTED 5
+
+struct bfd_pef_data_struct
+{
+ bfd_pef_header header;
+ bfd_pef_section *sections;
+ bfd *ibfd;
+};
+typedef struct bfd_pef_data_struct bfd_pef_data_struct;
+
+#define BFD_PEF_XLIB_TAG1 0xF04D6163 /* '?Mac' */
+#define BFD_PEF_VLIB_TAG2 0x564C6962 /* 'VLib' */
+#define BFD_PEF_BLIB_TAG2 0x424C6962 /* 'BLib' */
+
+#define BFD_PEF_XLIB_VERSION 0x00000001
+
+struct bfd_pef_xlib_header
+{
+ unsigned long tag1;
+ unsigned long tag2;
+ unsigned long current_format;
+ unsigned long container_strings_offset;
+ unsigned long export_hash_offset;
+ unsigned long export_key_offset;
+ unsigned long export_symbol_offset;
+ unsigned long export_names_offset;
+ unsigned long export_hash_table_power;
+ unsigned long exported_symbol_count;
+
+ unsigned long frag_name_offset;
+ unsigned long frag_name_length;
+ unsigned long dylib_path_offset;
+ unsigned long dylib_path_length;
+ unsigned long cpu_family;
+ unsigned long cpu_model;
+ unsigned long date_time_stamp;
+ unsigned long current_version;
+ unsigned long old_definition_version;
+ unsigned long old_implementation_version;
+};
+typedef struct bfd_pef_xlib_header bfd_pef_xlib_header;
+
+struct bfd_pef_xlib_data_struct
+{
+ bfd_pef_xlib_header header;
+};
+typedef struct bfd_pef_xlib_data_struct bfd_pef_xlib_data_struct;
+
+int bfd_pef_parse_loader_header (bfd *, unsigned char *, size_t, bfd_pef_loader_header *);
+int bfd_pef_print_loader_section (bfd *, FILE *);
+void bfd_pef_print_loader_header (bfd *, bfd_pef_loader_header *, FILE *);
+int bfd_pef_parse_imported_library (bfd *, unsigned char *, size_t, bfd_pef_imported_library *);
+int bfd_pef_parse_imported_symbol (bfd *, unsigned char *, size_t, bfd_pef_imported_symbol *);
+int bfd_pef_scan_section (bfd *, bfd_pef_section *);
+int bfd_pef_scan_start_address (bfd *);
+int bfd_pef_scan (bfd *, bfd_pef_header *, bfd_pef_data_struct *);
diff --git a/bfd/pei-arm-wince.c b/bfd/pei-arm-wince.c
new file mode 100644
index 0000000..6ef9aa9
--- /dev/null
+++ b/bfd/pei-arm-wince.c
@@ -0,0 +1,31 @@
+/* BFD back-end for ARM WINCE PE IMAGE COFF files.
+ Copyright (C) 2006-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#define TARGET_UNDERSCORE 0
+#define USER_LABEL_PREFIX ""
+
+#define TARGET_LITTLE_SYM arm_pei_wince_le_vec
+#define TARGET_LITTLE_NAME "pei-arm-wince-little"
+#define TARGET_BIG_SYM arm_pei_wince_be_vec
+#define TARGET_BIG_NAME "pei-arm-wince-big"
+
+#define LOCAL_LABEL_PREFIX "."
+
+#include "pei-arm.c"
diff --git a/bfd/pei-arm.c b/bfd/pei-arm.c
new file mode 100644
index 0000000..84318f2
--- /dev/null
+++ b/bfd/pei-arm.c
@@ -0,0 +1,55 @@
+/* BFD back-end for arm PE IMAGE COFF files.
+ Copyright (C) 1995-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+
+#ifndef TARGET_LITTLE_SYM
+#define TARGET_LITTLE_SYM arm_pei_le_vec
+#define TARGET_LITTLE_NAME "pei-arm-little"
+#define TARGET_BIG_SYM arm_pei_be_vec
+#define TARGET_BIG_NAME "pei-arm-big"
+#endif
+
+#define COFF_IMAGE_WITH_PE
+#define COFF_WITH_PE
+#define PCRELOFFSET TRUE
+/* Long section names not allowed in executable images, only object files. */
+#define COFF_LONG_SECTION_NAMES 0
+
+#define COFF_SECTION_ALIGNMENT_ENTRIES \
+{ COFF_SECTION_NAME_EXACT_MATCH (".bss"), \
+ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 2 }, \
+{ COFF_SECTION_NAME_EXACT_MATCH (".data"), \
+ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 2 }, \
+{ COFF_SECTION_NAME_EXACT_MATCH (".rdata"), \
+ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 2 }, \
+{ COFF_SECTION_NAME_EXACT_MATCH (".text"), \
+ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 2 }, \
+{ COFF_SECTION_NAME_PARTIAL_MATCH (".idata"), \
+ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 2 }, \
+{ COFF_SECTION_NAME_EXACT_MATCH (".pdata"), \
+ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 2 }, \
+{ COFF_SECTION_NAME_PARTIAL_MATCH (".debug"), \
+ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 0 }, \
+{ COFF_SECTION_NAME_PARTIAL_MATCH (".gnu.linkonce.wi."), \
+ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 0 }
+
+#include "coff-arm.c"
diff --git a/bfd/pei-i386.c b/bfd/pei-i386.c
new file mode 100644
index 0000000..080ed1a
--- /dev/null
+++ b/bfd/pei-i386.c
@@ -0,0 +1,45 @@
+/* BFD back-end for Intel 386 PE IMAGE COFF files.
+ Copyright (C) 1995-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+
+#define TARGET_SYM i386_pei_vec
+#define TARGET_NAME "pei-i386"
+#define COFF_IMAGE_WITH_PE
+#define COFF_WITH_PE
+#define PCRELOFFSET TRUE
+#define TARGET_UNDERSCORE '_'
+/* Long section names not allowed in executable images, only object files. */
+#define COFF_LONG_SECTION_NAMES 0
+#define COFF_SUPPORT_GNU_LINKONCE
+#define COFF_LONG_FILENAMES
+
+#define COFF_SECTION_ALIGNMENT_ENTRIES \
+{ COFF_SECTION_NAME_PARTIAL_MATCH (".idata"), \
+ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 2 }, \
+{ COFF_SECTION_NAME_EXACT_MATCH (".pdata"), \
+ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 2 }, \
+{ COFF_SECTION_NAME_PARTIAL_MATCH (".debug"), \
+ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 0 }, \
+{ COFF_SECTION_NAME_PARTIAL_MATCH (".gnu.linkonce.wi."), \
+ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 0 }
+
+#include "coff-i386.c"
diff --git a/bfd/pei-ia64.c b/bfd/pei-ia64.c
new file mode 100644
index 0000000..a3cf735
--- /dev/null
+++ b/bfd/pei-ia64.c
@@ -0,0 +1,38 @@
+/* BFD back-end for HP/Intel IA-64 PE IMAGE COFF files.
+ Copyright (C) 1999-2014 Free Software Foundation, Inc.
+ Contributed by David Mosberger <davidm@hpl.hp.com>
+
+ This implementation only supports objcopy to ouput IA-64 PE IMAGE 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+
+#define TARGET_SYM ia64_pei_vec
+#define TARGET_NAME "pei-ia64"
+#define COFF_IMAGE_WITH_PE
+#define COFF_WITH_PE
+#define COFF_WITH_pep
+#define PCRELOFFSET TRUE
+#define TARGET_UNDERSCORE '_'
+/* Long section names not allowed in executable images, only object files. */
+#define COFF_LONG_SECTION_NAMES 0
+
+#include "coff-ia64.c"
diff --git a/bfd/pei-mcore.c b/bfd/pei-mcore.c
new file mode 100644
index 0000000..cb0652d
--- /dev/null
+++ b/bfd/pei-mcore.c
@@ -0,0 +1,43 @@
+/* BFD back-end for MCore PECOFF files.
+ Copyright (C) 1999-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+
+#ifndef TARGET_BIG_SYM
+#define TARGET_BIG_SYM mcore_pei_be_vec
+#define TARGET_BIG_NAME "pei-mcore-big"
+#define TARGET_LITTLE_SYM mcore_pei_le_vec
+#define TARGET_LITTLE_NAME "pei-mcore-little"
+#endif
+
+#define COFF_IMAGE_WITH_PE
+#define COFF_WITH_PE
+#define PCRELOFFSET TRUE
+/* Long section names not allowed in executable images, only object files. */
+#define COFF_LONG_SECTION_NAMES 0
+
+#define MCORE_PE
+
+#ifndef bfd_pe_print_pdata
+#define bfd_pe_print_pdata NULL
+#endif
+
+#include "coff-mcore.c"
diff --git a/bfd/pei-mips.c b/bfd/pei-mips.c
new file mode 100644
index 0000000..5885390
--- /dev/null
+++ b/bfd/pei-mips.c
@@ -0,0 +1,32 @@
+/* BFD back-end for MIPS PE IMAGE COFF files.
+ Copyright (C) 1995-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+
+#define TARGET_SYM mips_pei_le_vec
+#define TARGET_NAME "pei-mips"
+#define COFF_IMAGE_WITH_PE
+#define PCRELOFFSET TRUE
+/* Long section names not allowed in executable images, only object files. */
+#define COFF_LONG_SECTION_NAMES 0
+
+#include "pe-mips.c"
+
diff --git a/bfd/pei-ppc.c b/bfd/pei-ppc.c
new file mode 100644
index 0000000..6a5bb29
--- /dev/null
+++ b/bfd/pei-ppc.c
@@ -0,0 +1,50 @@
+/* BFD back-end for PowerPC PE IMAGE COFF files.
+ Copyright (C) 1995-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, 51 Franklin Street - Fifth Floor,
+ Boston, MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.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 powerpc_pei_le_vec
+#define TARGET_LITTLE_NAME "pei-powerpcle"
+
+#define TARGET_BIG_SYM powerpc_pei_vec
+#define TARGET_BIG_NAME "pei-powerpc"
+
+#define COFF_IMAGE_WITH_PE
+#define COFF_WITH_PE
+
+/* Long section names not allowed in executable images, only object files. */
+#define COFF_LONG_SECTION_NAMES 0
+
+/* FIXME: Verify PCRELOFFSET is always false */
+
+/* FIXME: This target no longer works. Search for POWERPC_LE_PE in
+ coff-ppc.c and peigen.c. */
+
+#ifndef bfd_pe_print_pdata
+#define bfd_pe_print_pdata NULL
+#endif
+
+#include "coff-ppc.c"
diff --git a/bfd/pei-sh.c b/bfd/pei-sh.c
new file mode 100644
index 0000000..50d677b
--- /dev/null
+++ b/bfd/pei-sh.c
@@ -0,0 +1,35 @@
+/* BFD back-end for SH PE IMAGE COFF files.
+ Copyright (C) 1995-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+
+#define TARGET_SHL_SYM sh_pei_le_vec
+#define TARGET_SHL_NAME "pei-shl"
+#define IMAGE_BASE NT_IMAGE_BASE
+#define COFF_IMAGE_WITH_PE
+#define COFF_WITH_PE
+#define PCRELOFFSET TRUE
+#define TARGET_UNDERSCORE '_'
+/* Long section names not allowed in executable images, only object files. */
+#define COFF_LONG_SECTION_NAMES 0
+
+#include "coff-sh.c"
+
diff --git a/bfd/pei-x86_64.c b/bfd/pei-x86_64.c
new file mode 100644
index 0000000..48554d3
--- /dev/null
+++ b/bfd/pei-x86_64.c
@@ -0,0 +1,656 @@
+/* BFD back-end for Intel 386 PE IMAGE COFF files.
+ Copyright (C) 2006-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA.
+
+ Written by Kai Tietz, OneVision Software GmbH&CoKg. */
+
+#include "sysdep.h"
+#include "bfd.h"
+
+#define TARGET_SYM x86_64_pei_vec
+#define TARGET_NAME "pei-x86-64"
+#define COFF_IMAGE_WITH_PE
+#define COFF_WITH_PE
+#define COFF_WITH_pex64
+#define PCRELOFFSET TRUE
+#if defined (USE_MINGW64_LEADING_UNDERSCORES)
+#define TARGET_UNDERSCORE '_'
+#else
+#define TARGET_UNDERSCORE 0
+#endif
+/* Long section names not allowed in executable images, only object files. */
+#define COFF_LONG_SECTION_NAMES 0
+#define COFF_SUPPORT_GNU_LINKONCE
+#define COFF_LONG_FILENAMES
+#define PDATA_ROW_SIZE (3 * 4)
+
+#define COFF_SECTION_ALIGNMENT_ENTRIES \
+{ COFF_SECTION_NAME_EXACT_MATCH (".bss"), \
+ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 4 }, \
+{ COFF_SECTION_NAME_PARTIAL_MATCH (".data"), \
+ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 4 }, \
+{ COFF_SECTION_NAME_PARTIAL_MATCH (".rdata"), \
+ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 4 }, \
+{ COFF_SECTION_NAME_PARTIAL_MATCH (".text"), \
+ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 4 }, \
+{ COFF_SECTION_NAME_PARTIAL_MATCH (".idata"), \
+ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 2 }, \
+{ COFF_SECTION_NAME_EXACT_MATCH (".pdata"), \
+ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 2 }, \
+{ COFF_SECTION_NAME_PARTIAL_MATCH (".debug"), \
+ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 0 }, \
+{ COFF_SECTION_NAME_PARTIAL_MATCH (".gnu.linkonce.wi."), \
+ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 0 }
+
+/* Note we have to make sure not to include headers twice.
+ Not all headers are wrapped in #ifdef guards, so we define
+ PEI_HEADERS to prevent double including in coff-x86_64.c */
+#define PEI_HEADERS
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+#include "coff/x86_64.h"
+#include "coff/internal.h"
+#include "coff/pe.h"
+#include "libcoff.h"
+#include "libpei.h"
+#include "libiberty.h"
+
+#undef AOUTSZ
+#define AOUTSZ PEPAOUTSZ
+#define PEAOUTHDR PEPAOUTHDR
+
+/* Name of registers according to SEH conventions. */
+
+static const char * const pex_regs[16] = {
+ "rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi",
+ "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
+};
+
+/* Swap in a runtime function. */
+
+static void
+pex64_get_runtime_function (bfd *abfd, struct pex64_runtime_function *rf,
+ const void *data)
+{
+ const struct external_pex64_runtime_function *ex_rf =
+ (const struct external_pex64_runtime_function *) data;
+ rf->rva_BeginAddress = bfd_get_32 (abfd, ex_rf->rva_BeginAddress);
+ rf->rva_EndAddress = bfd_get_32 (abfd, ex_rf->rva_EndAddress);
+ rf->rva_UnwindData = bfd_get_32 (abfd, ex_rf->rva_UnwindData);
+}
+
+/* Swap in unwind info header. */
+
+static void
+pex64_get_unwind_info (bfd *abfd, struct pex64_unwind_info *ui, void *data)
+{
+ struct external_pex64_unwind_info *ex_ui =
+ (struct external_pex64_unwind_info *) data;
+ bfd_byte *ex_dta = (bfd_byte *) data;
+
+ memset (ui, 0, sizeof (struct pex64_unwind_info));
+ ui->Version = PEX64_UWI_VERSION (ex_ui->Version_Flags);
+ ui->Flags = PEX64_UWI_FLAGS (ex_ui->Version_Flags);
+ ui->SizeOfPrologue = (bfd_vma) ex_ui->SizeOfPrologue;
+ ui->CountOfCodes = (bfd_vma) ex_ui->CountOfCodes;
+ ui->FrameRegister = PEX64_UWI_FRAMEREG (ex_ui->FrameRegisterOffset);
+ ui->FrameOffset = PEX64_UWI_FRAMEOFF (ex_ui->FrameRegisterOffset);
+ ui->sizeofUnwindCodes = PEX64_UWI_SIZEOF_UWCODE_ARRAY (ui->CountOfCodes);
+ ui->SizeOfBlock = ui->sizeofUnwindCodes + 4;
+ ui->rawUnwindCodes = &ex_dta[4];
+ ex_dta += ui->SizeOfBlock;
+ switch (ui->Flags)
+ {
+ case UNW_FLAG_CHAININFO:
+ ui->rva_BeginAddress = bfd_get_32 (abfd, ex_dta + 0);
+ ui->rva_EndAddress = bfd_get_32 (abfd, ex_dta + 4);
+ ui->rva_UnwindData = bfd_get_32 (abfd, ex_dta + 8);
+ ui->SizeOfBlock += 12;
+ return;
+ case UNW_FLAG_EHANDLER:
+ case UNW_FLAG_UHANDLER:
+ case UNW_FLAG_FHANDLER:
+ ui->rva_ExceptionHandler = bfd_get_32 (abfd, ex_dta);
+ ui->SizeOfBlock += 4;
+ return;
+ default:
+ return;
+ }
+}
+
+/* Display unwind codes. */
+
+static void
+pex64_xdata_print_uwd_codes (FILE *file, bfd *abfd,
+ struct pex64_unwind_info *ui,
+ struct pex64_runtime_function *rf)
+{
+ unsigned int i;
+ unsigned int tmp; /* At least 32 bits. */
+ int save_allowed;
+
+ if (ui->CountOfCodes == 0 || ui->rawUnwindCodes == NULL)
+ return;
+
+ /* According to UNWIND_CODE documentation:
+ If an FP reg is used, the any unwind code taking an offset must only be
+ used after the FP reg is established in the prolog.
+ But there are counter examples of that in system dlls... */
+ save_allowed = TRUE;
+
+ i = 0;
+
+ if (ui->Version == 2
+ && PEX64_UNWCODE_CODE (ui->rawUnwindCodes[1]) == UWOP_EPILOG)
+ {
+ /* Display epilog opcode (whose docoding is not fully documented).
+ Looks to be designed to speed-up unwinding, as there is no need
+ to decode instruction flow if outside an epilog. */
+ unsigned int func_size = rf->rva_EndAddress - rf->rva_BeginAddress;
+
+ fprintf (file, "\tv2 epilog (length: %02x) at pc+:",
+ ui->rawUnwindCodes[0]);
+ if (PEX64_UNWCODE_INFO (ui->rawUnwindCodes[1]))
+ fprintf (file, " 0x%x", func_size - ui->rawUnwindCodes[0]);
+ i++;
+ for (; i < ui->CountOfCodes; i++)
+ {
+ const bfd_byte *dta = ui->rawUnwindCodes + 2 * i;
+ unsigned int off;
+
+ if (PEX64_UNWCODE_CODE (dta[1]) != UWOP_EPILOG)
+ break;
+ off = dta[0] | (PEX64_UNWCODE_INFO (dta[1]) << 8);
+ if (off == 0)
+ fprintf (file, " [pad]");
+ else
+ fprintf (file, " 0x%x", func_size - off);
+ }
+ fputc ('\n', file);
+ }
+
+ for (; i < ui->CountOfCodes; i++)
+ {
+ const bfd_byte *dta = ui->rawUnwindCodes + 2 * i;
+ unsigned int info = PEX64_UNWCODE_INFO (dta[1]);
+ int unexpected = FALSE;
+
+ fprintf (file, "\t pc+0x%02x: ", (unsigned int) dta[0]);
+ switch (PEX64_UNWCODE_CODE (dta[1]))
+ {
+ case UWOP_PUSH_NONVOL:
+ fprintf (file, "push %s", pex_regs[info]);
+ break;
+ case UWOP_ALLOC_LARGE:
+ if (info == 0)
+ {
+ tmp = bfd_get_16 (abfd, &dta[2]) * 8;
+ i++;
+ }
+ else
+ {
+ tmp = bfd_get_32 (abfd, &dta[2]);
+ i += 2;
+ }
+ fprintf (file, "alloc large area: rsp = rsp - 0x%x", tmp);
+ break;
+ case UWOP_ALLOC_SMALL:
+ fprintf (file, "alloc small area: rsp = rsp - 0x%x", (info + 1) * 8);
+ break;
+ case UWOP_SET_FPREG:
+ /* According to the documentation, info field is unused. */
+ fprintf (file, "FPReg: %s = rsp + 0x%x (info = 0x%x)",
+ pex_regs[ui->FrameRegister],
+ (unsigned int) ui->FrameOffset * 16, info);
+ unexpected = ui->FrameRegister == 0;
+ save_allowed = FALSE;
+ break;
+ case UWOP_SAVE_NONVOL:
+ tmp = bfd_get_16 (abfd, &dta[2]) * 8;
+ i++;
+ fprintf (file, "save %s at rsp + 0x%x", pex_regs[info], tmp);
+ unexpected = !save_allowed;
+ break;
+ case UWOP_SAVE_NONVOL_FAR:
+ tmp = bfd_get_32 (abfd, &dta[2]);
+ i += 2;
+ fprintf (file, "save %s at rsp + 0x%x", pex_regs[info], tmp);
+ unexpected = !save_allowed;
+ break;
+ case UWOP_SAVE_XMM:
+ if (ui->Version == 1)
+ {
+ tmp = bfd_get_16 (abfd, &dta[2]) * 8;
+ i++;
+ fprintf (file, "save mm%u at rsp + 0x%x", info, tmp);
+ unexpected = !save_allowed;
+ }
+ else if (ui->Version == 2)
+ {
+ fprintf (file, "epilog %02x %01x", dta[0], info);
+ unexpected = TRUE;
+ }
+ break;
+ case UWOP_SAVE_XMM_FAR:
+ tmp = bfd_get_32 (abfd, &dta[2]) * 8;
+ i += 2;
+ fprintf (file, "save mm%u at rsp + 0x%x", info, tmp);
+ unexpected = !save_allowed;
+ break;
+ case UWOP_SAVE_XMM128:
+ tmp = bfd_get_16 (abfd, &dta[2]) * 16;
+ i++;
+ fprintf (file, "save xmm%u at rsp + 0x%x", info, tmp);
+ unexpected = !save_allowed;
+ break;
+ case UWOP_SAVE_XMM128_FAR:
+ tmp = bfd_get_32 (abfd, &dta[2]) * 16;
+ i += 2;
+ fprintf (file, "save xmm%u at rsp + 0x%x", info, tmp);
+ unexpected = !save_allowed;
+ break;
+ case UWOP_PUSH_MACHFRAME:
+ fprintf (file, "interrupt entry (SS, old RSP, EFLAGS, CS, RIP");
+ if (info == 0)
+ fprintf (file, ")");
+ else if (info == 1)
+ fprintf (file, ",ErrorCode)");
+ else
+ fprintf (file, ", unknown(%u))", info);
+ break;
+ default:
+ /* Already caught by the previous scan. */
+ abort ();
+ }
+ if (unexpected)
+ fprintf (file, " [Unexpected!]");
+ fputc ('\n', file);
+ }
+}
+
+/* Check wether section SEC_NAME contains the xdata at address ADDR. */
+
+static asection *
+pex64_get_section_by_rva (bfd *abfd, bfd_vma addr, const char *sec_name)
+{
+ asection *section = bfd_get_section_by_name (abfd, sec_name);
+ bfd_vma vsize;
+ bfd_size_type datasize = 0;
+
+ if (section == NULL
+ || coff_section_data (abfd, section) == NULL
+ || pei_section_data (abfd, section) == NULL)
+ return NULL;
+ vsize = section->vma - pe_data (abfd)->pe_opthdr.ImageBase;
+ datasize = section->size;
+ if (!datasize || vsize > addr || (vsize + datasize) < addr)
+ return NULL;
+ return section;
+}
+
+/* Dump xdata at for function RF to FILE. The argument XDATA_SECTION
+ designate the bfd section containing the xdata, XDATA is its content,
+ and ENDX the size if known (or NULL). */
+
+static void
+pex64_dump_xdata (FILE *file, bfd *abfd,
+ asection *xdata_section, bfd_byte *xdata, bfd_vma *endx,
+ struct pex64_runtime_function *rf)
+{
+ bfd_vma vaddr;
+ bfd_vma end_addr;
+ bfd_vma addr = rf->rva_UnwindData;
+ struct pex64_unwind_info ui;
+
+ vaddr = xdata_section->vma - pe_data (abfd)->pe_opthdr.ImageBase;
+ addr -= vaddr;
+
+ if (endx)
+ end_addr = endx[0] - vaddr;
+ else
+ end_addr = (xdata_section->rawsize != 0 ?
+ xdata_section->rawsize : xdata_section->size);
+
+
+ pex64_get_unwind_info (abfd, &ui, &xdata[addr]);
+
+ if (ui.Version != 1 && ui.Version != 2)
+ {
+ unsigned int i;
+ fprintf (file, "\tVersion %u (unknown).\n",
+ (unsigned int) ui.Version);
+ for (i = 0; addr < end_addr; addr += 1, i++)
+ {
+ if ((i & 15) == 0)
+ fprintf (file, "\t %03x:", i);
+ fprintf (file, " %02x", xdata[addr]);
+ if ((i & 15) == 15)
+ fprintf (file, "\n");
+ }
+ if ((i & 15) != 0)
+ fprintf (file, "\n");
+ return;
+ }
+
+ fprintf (file, "\tVersion: %d, Flags: ", ui.Version);
+ switch (ui.Flags)
+ {
+ case UNW_FLAG_NHANDLER:
+ fprintf (file, "none");
+ break;
+ case UNW_FLAG_EHANDLER:
+ fprintf (file, "UNW_FLAG_EHANDLER");
+ break;
+ case UNW_FLAG_UHANDLER:
+ fprintf (file, "UNW_FLAG_UHANDLER");
+ break;
+ case UNW_FLAG_FHANDLER:
+ fprintf
+ (file, "UNW_FLAG_EHANDLER | UNW_FLAG_UHANDLER");
+ break;
+ case UNW_FLAG_CHAININFO:
+ fprintf (file, "UNW_FLAG_CHAININFO");
+ break;
+ default:
+ fprintf (file, "unknown flags value 0x%x", (unsigned int) ui.Flags);
+ break;
+ }
+ fputc ('\n', file);
+ fprintf (file, "\tNbr codes: %u, ", (unsigned int) ui.CountOfCodes);
+ fprintf (file, "Prologue size: 0x%02x, Frame offset: 0x%x, ",
+ (unsigned int) ui.SizeOfPrologue, (unsigned int) ui.FrameOffset);
+ fprintf (file, "Frame reg: %s\n",
+ ui.FrameRegister == 0 ? "none"
+ : pex_regs[(unsigned int) ui.FrameRegister]);
+
+ pex64_xdata_print_uwd_codes (file, abfd, &ui, rf);
+
+ switch (ui.Flags)
+ {
+ case UNW_FLAG_EHANDLER:
+ case UNW_FLAG_UHANDLER:
+ case UNW_FLAG_FHANDLER:
+ fprintf (file, "\tHandler: ");
+ fprintf_vma (file, (ui.rva_ExceptionHandler
+ + pe_data (abfd)->pe_opthdr.ImageBase));
+ fprintf (file, ".\n");
+ break;
+ case UNW_FLAG_CHAININFO:
+ fprintf (file, "\tChain: start: ");
+ fprintf_vma (file, ui.rva_BeginAddress);
+ fprintf (file, ", end: ");
+ fprintf_vma (file, ui.rva_EndAddress);
+ fprintf (file, "\n\t unwind data: ");
+ fprintf_vma (file, ui.rva_UnwindData);
+ fprintf (file, ".\n");
+ break;
+ }
+
+ /* Now we need end of this xdata block. */
+ addr += ui.SizeOfBlock;
+ if (addr < end_addr)
+ {
+ unsigned int i;
+ fprintf (file,"\tUser data:\n");
+ for (i = 0; addr < end_addr; addr += 1, i++)
+ {
+ if ((i & 15) == 0)
+ fprintf (file, "\t %03x:", i);
+ fprintf (file, " %02x", xdata[addr]);
+ if ((i & 15) == 15)
+ fprintf (file, "\n");
+ }
+ if ((i & 15) != 0)
+ fprintf (file, "\n");
+ }
+}
+
+/* Helper function to sort xdata. The entries of xdata are sorted to know
+ the size of each entry. */
+
+static int
+sort_xdata_arr (const void *l, const void *r)
+{
+ const bfd_vma *lp = (const bfd_vma *) l;
+ const bfd_vma *rp = (const bfd_vma *) r;
+
+ if (*lp == *rp)
+ return 0;
+ return (*lp < *rp ? -1 : 1);
+}
+
+/* Display unwind tables for x86-64. */
+
+static bfd_boolean
+pex64_bfd_print_pdata (bfd *abfd, void *vfile)
+{
+ FILE *file = (FILE *) vfile;
+ bfd_byte *pdata = NULL;
+ bfd_byte *xdata = NULL;
+ asection *pdata_section = bfd_get_section_by_name (abfd, ".pdata");
+ asection *xdata_section;
+ bfd_vma xdata_base;
+ bfd_size_type i;
+ bfd_size_type stop;
+ bfd_vma prev_beginaddress = 0;
+ bfd_vma prev_unwinddata_rva = 0;
+ bfd_vma imagebase;
+ int onaline = PDATA_ROW_SIZE;
+ int seen_error = 0;
+ bfd_vma *xdata_arr = NULL;
+ int xdata_arr_cnt;
+
+ /* Sanity checks. */
+ if (pdata_section == NULL
+ || coff_section_data (abfd, pdata_section) == NULL
+ || pei_section_data (abfd, pdata_section) == NULL)
+ return TRUE;
+
+ stop = pei_section_data (abfd, pdata_section)->virt_size;
+ if ((stop % onaline) != 0)
+ fprintf (file,
+ _("warning: .pdata section size (%ld) is not a multiple of %d\n"),
+ (long) stop, onaline);
+
+ /* Display functions table. */
+ fprintf (file,
+ _("\nThe Function Table (interpreted .pdata section contents)\n"));
+
+ fprintf (file, _("vma:\t\t\tBeginAddress\t EndAddress\t UnwindData\n"));
+
+ if (!bfd_malloc_and_get_section (abfd, pdata_section, &pdata))
+ goto done;
+
+ /* Table of xdata entries. */
+ xdata_arr = (bfd_vma *) xmalloc (sizeof (bfd_vma) * ((stop / onaline) + 1));
+ xdata_arr_cnt = 0;
+
+ imagebase = pe_data (abfd)->pe_opthdr.ImageBase;
+
+ for (i = 0; i < stop; i += onaline)
+ {
+ struct pex64_runtime_function rf;
+
+ if (i + PDATA_ROW_SIZE > stop)
+ break;
+ pex64_get_runtime_function (abfd, &rf, &pdata[i]);
+
+ if (rf.rva_BeginAddress == 0 && rf.rva_EndAddress == 0
+ && rf.rva_UnwindData == 0)
+ /* We are probably into the padding of the section now. */
+ break;
+ fputc (' ', file);
+ fprintf_vma (file, i + pdata_section->vma);
+ fprintf (file, ":\t");
+ fprintf_vma (file, imagebase + rf.rva_BeginAddress);
+ fprintf (file, " ");
+ fprintf_vma (file, imagebase + rf.rva_EndAddress);
+ fprintf (file, " ");
+ fprintf_vma (file, imagebase + rf.rva_UnwindData);
+ fprintf (file, "\n");
+ if (i != 0 && rf.rva_BeginAddress <= prev_beginaddress)
+ {
+ seen_error = 1;
+ fprintf (file, " has %s begin address as predecessor\n",
+ (rf.rva_BeginAddress < prev_beginaddress ? "smaller" : "same"));
+ }
+ prev_beginaddress = rf.rva_BeginAddress;
+ /* Now we check for negative addresses. */
+ if ((prev_beginaddress & 0x80000000) != 0)
+ {
+ seen_error = 1;
+ fprintf (file, " has negative begin address\n");
+ }
+ if ((rf.rva_EndAddress & 0x80000000) != 0)
+ {
+ seen_error = 1;
+ fprintf (file, " has negative end address\n");
+ }
+ if ((rf.rva_UnwindData & 0x80000000) != 0)
+ {
+ seen_error = 1;
+ fprintf (file, " has negative unwind address\n");
+ }
+ if (rf.rva_UnwindData && !PEX64_IS_RUNTIME_FUNCTION_CHAINED (&rf))
+ xdata_arr[xdata_arr_cnt++] = rf.rva_UnwindData;
+ }
+
+ if (seen_error)
+ goto done;
+
+ /* Add end of list marker. */
+ xdata_arr[xdata_arr_cnt++] = ~((bfd_vma) 0);
+
+ /* Sort start RVAs of xdata. */
+ if (xdata_arr_cnt > 1)
+ qsort (xdata_arr, (size_t) xdata_arr_cnt, sizeof (bfd_vma),
+ sort_xdata_arr);
+
+ /* Find the section containing the unwind data (.xdata). */
+ xdata_base = xdata_arr[0];
+ xdata_section = pex64_get_section_by_rva (abfd, xdata_base, ".rdata");
+
+ if (!xdata_section)
+ xdata_section = pex64_get_section_by_rva (abfd, xdata_base, ".data");
+ if (!xdata_section)
+ xdata_section = pex64_get_section_by_rva (abfd, xdata_base, ".xdata");
+ if (!xdata_section)
+ xdata_section = pex64_get_section_by_rva (abfd, xdata_base, ".pdata");
+ if (!xdata_section)
+ xdata_section = pex64_get_section_by_rva (abfd, xdata_base, ".text");
+ if (!xdata_section
+ || !bfd_malloc_and_get_section (abfd, xdata_section, &xdata))
+ goto done;
+
+ /* Do dump of pdata related xdata. */
+ for (i = 0; i < stop; i += onaline)
+ {
+ struct pex64_runtime_function rf;
+
+ if (i + PDATA_ROW_SIZE > stop)
+ break;
+ pex64_get_runtime_function (abfd, &rf, &pdata[i]);
+
+ if (rf.rva_BeginAddress == 0 && rf.rva_EndAddress == 0
+ && rf.rva_UnwindData == 0)
+ /* We are probably into the padding of the section now. */
+ break;
+ if (i == 0)
+ fprintf (file, "\nDump of .xdata\n");
+
+ fputc (' ', file);
+ fprintf_vma (file, rf.rva_UnwindData + imagebase);
+
+ if (prev_unwinddata_rva == rf.rva_UnwindData)
+ {
+ /* Do not dump again the xdata for the same entry. */
+ fprintf (file, " also used for function at ");
+ fprintf_vma (file, rf.rva_BeginAddress + imagebase);
+ fputc ('\n', file);
+ continue;
+ }
+ else
+ prev_unwinddata_rva = rf.rva_UnwindData;
+
+ fprintf (file, " (rva: %08x): ",
+ (unsigned int) rf.rva_UnwindData);
+ fprintf_vma (file, rf.rva_BeginAddress + imagebase);
+ fprintf (file, " - ");
+ fprintf_vma (file, rf.rva_EndAddress + imagebase);
+ fputc ('\n', file);
+
+ if (rf.rva_UnwindData != 0)
+ {
+ if (PEX64_IS_RUNTIME_FUNCTION_CHAINED (&rf))
+ {
+ bfd_vma altent = PEX64_GET_UNWINDDATA_UNIFIED_RVA (&rf);
+ bfd_vma pdata_vma = bfd_get_section_vma (abfd, pdata_section);
+ struct pex64_runtime_function arf;
+
+ fprintf (file, "\t shares information with ");
+ altent += imagebase;
+
+ if (altent >= pdata_vma
+ && (altent + PDATA_ROW_SIZE <= pdata_vma
+ + pei_section_data (abfd, pdata_section)->virt_size))
+ {
+ pex64_get_runtime_function
+ (abfd, &arf, &pdata[altent - pdata_vma]);
+ fprintf (file, "pdata element at 0x");
+ fprintf_vma (file, arf.rva_UnwindData);
+ }
+ else
+ fprintf (file, "unknown pdata element");
+ fprintf (file, ".\n");
+ }
+ else
+ {
+ bfd_vma *p;
+
+ /* Search for the current entry in the sorted array. */
+ p = (bfd_vma *)
+ bsearch (&rf.rva_UnwindData, xdata_arr,
+ (size_t) xdata_arr_cnt, sizeof (bfd_vma),
+ sort_xdata_arr);
+
+ /* Advance to the next pointer into the xdata section. We may
+ have shared xdata entries, which will result in a string of
+ identical pointers in the array; advance past all of them. */
+ while (p[0] <= rf.rva_UnwindData)
+ ++p;
+ if (p[0] == ~((bfd_vma) 0))
+ p = NULL;
+
+ pex64_dump_xdata (file, abfd, xdata_section, xdata, p, &rf);
+ }
+ }
+ }
+
+ done:
+ free (pdata);
+ free (xdata_arr);
+ free (xdata);
+
+ return TRUE;
+}
+
+#define bfd_pe_print_pdata pex64_bfd_print_pdata
+
+#include "coff-x86_64.c"
diff --git a/bfd/peicode.h b/bfd/peicode.h
new file mode 100644
index 0000000..8365353
--- /dev/null
+++ b/bfd/peicode.h
@@ -0,0 +1,1356 @@
+/* Support for the generic parts of PE/PEI, for BFD.
+ Copyright (C) 1995-2014 Free Software Foundation, Inc.
+ Written by Cygnus Solutions.
+
+ This file is part of BFD, the Binary File Descriptor library.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+
+/* Most of this hacked by Steve Chamberlain,
+ sac@cygnus.com
+
+ PE/PEI rearrangement (and code added): Donn Terry
+ Softway Systems, Inc. */
+
+/* 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. */
+
+#include "libpei.h"
+
+static bfd_boolean (*pe_saved_coff_bfd_print_private_bfd_data) (bfd *, void *) =
+#ifndef coff_bfd_print_private_bfd_data
+ NULL;
+#else
+ coff_bfd_print_private_bfd_data;
+#undef coff_bfd_print_private_bfd_data
+#endif
+
+static bfd_boolean pe_print_private_bfd_data (bfd *, void *);
+#define coff_bfd_print_private_bfd_data pe_print_private_bfd_data
+
+static bfd_boolean (*pe_saved_coff_bfd_copy_private_bfd_data) (bfd *, bfd *) =
+#ifndef coff_bfd_copy_private_bfd_data
+ NULL;
+#else
+ coff_bfd_copy_private_bfd_data;
+#undef coff_bfd_copy_private_bfd_data
+#endif
+
+static bfd_boolean pe_bfd_copy_private_bfd_data (bfd *, bfd *);
+#define coff_bfd_copy_private_bfd_data pe_bfd_copy_private_bfd_data
+
+#define coff_mkobject pe_mkobject
+#define coff_mkobject_hook pe_mkobject_hook
+
+#ifdef COFF_IMAGE_WITH_PE
+/* This structure contains static variables used by the ILF code. */
+typedef asection * asection_ptr;
+
+typedef struct
+{
+ bfd * abfd;
+ bfd_byte * data;
+ struct bfd_in_memory * bim;
+ unsigned short magic;
+
+ arelent * reltab;
+ unsigned int relcount;
+
+ coff_symbol_type * sym_cache;
+ coff_symbol_type * sym_ptr;
+ unsigned int sym_index;
+
+ unsigned int * sym_table;
+ unsigned int * table_ptr;
+
+ combined_entry_type * native_syms;
+ combined_entry_type * native_ptr;
+
+ coff_symbol_type ** sym_ptr_table;
+ coff_symbol_type ** sym_ptr_ptr;
+
+ unsigned int sec_index;
+
+ char * string_table;
+ char * string_ptr;
+ char * end_string_ptr;
+
+ SYMENT * esym_table;
+ SYMENT * esym_ptr;
+
+ struct internal_reloc * int_reltab;
+}
+pe_ILF_vars;
+#endif /* COFF_IMAGE_WITH_PE */
+
+const bfd_target *coff_real_object_p
+ (bfd *, unsigned, struct internal_filehdr *, struct internal_aouthdr *);
+
+#ifndef NO_COFF_RELOCS
+static void
+coff_swap_reloc_in (bfd * abfd, void * src, void * dst)
+{
+ RELOC *reloc_src = (RELOC *) src;
+ struct internal_reloc *reloc_dst = (struct internal_reloc *) dst;
+
+ reloc_dst->r_vaddr = H_GET_32 (abfd, reloc_src->r_vaddr);
+ reloc_dst->r_symndx = H_GET_S32 (abfd, reloc_src->r_symndx);
+ reloc_dst->r_type = H_GET_16 (abfd, reloc_src->r_type);
+#ifdef SWAP_IN_RELOC_OFFSET
+ reloc_dst->r_offset = SWAP_IN_RELOC_OFFSET (abfd, reloc_src->r_offset);
+#endif
+}
+
+static unsigned int
+coff_swap_reloc_out (bfd * abfd, void * src, void * dst)
+{
+ struct internal_reloc *reloc_src = (struct internal_reloc *) src;
+ struct external_reloc *reloc_dst = (struct external_reloc *) dst;
+
+ H_PUT_32 (abfd, reloc_src->r_vaddr, reloc_dst->r_vaddr);
+ H_PUT_32 (abfd, reloc_src->r_symndx, reloc_dst->r_symndx);
+ H_PUT_16 (abfd, reloc_src->r_type, reloc_dst->r_type);
+
+#ifdef SWAP_OUT_RELOC_OFFSET
+ SWAP_OUT_RELOC_OFFSET (abfd, reloc_src->r_offset, reloc_dst->r_offset);
+#endif
+#ifdef SWAP_OUT_RELOC_EXTRA
+ SWAP_OUT_RELOC_EXTRA (abfd, reloc_src, reloc_dst);
+#endif
+ return RELSZ;
+}
+#endif /* not NO_COFF_RELOCS */
+
+#ifdef COFF_IMAGE_WITH_PE
+#undef FILHDR
+#define FILHDR struct external_PEI_IMAGE_hdr
+#endif
+
+static void
+coff_swap_filehdr_in (bfd * abfd, void * src, void * dst)
+{
+ FILHDR *filehdr_src = (FILHDR *) src;
+ struct internal_filehdr *filehdr_dst = (struct internal_filehdr *) dst;
+
+ filehdr_dst->f_magic = H_GET_16 (abfd, filehdr_src->f_magic);
+ filehdr_dst->f_nscns = H_GET_16 (abfd, filehdr_src->f_nscns);
+ filehdr_dst->f_timdat = H_GET_32 (abfd, filehdr_src->f_timdat);
+ filehdr_dst->f_nsyms = H_GET_32 (abfd, filehdr_src->f_nsyms);
+ filehdr_dst->f_flags = H_GET_16 (abfd, filehdr_src->f_flags);
+ filehdr_dst->f_symptr = H_GET_32 (abfd, 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 = H_GET_16 (abfd, filehdr_src-> f_opthdr);
+}
+
+#ifdef COFF_IMAGE_WITH_PE
+# define coff_swap_filehdr_out _bfd_XXi_only_swap_filehdr_out
+#elif defined COFF_WITH_pex64
+# define coff_swap_filehdr_out _bfd_pex64_only_swap_filehdr_out
+#elif defined COFF_WITH_pep
+# define coff_swap_filehdr_out _bfd_pep_only_swap_filehdr_out
+#else
+# define coff_swap_filehdr_out _bfd_pe_only_swap_filehdr_out
+#endif
+
+static void
+coff_swap_scnhdr_in (bfd * abfd, void * ext, void * 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, scnhdr_ext->s_vaddr);
+ scnhdr_int->s_paddr = GET_SCNHDR_PADDR (abfd, scnhdr_ext->s_paddr);
+ scnhdr_int->s_size = GET_SCNHDR_SIZE (abfd, scnhdr_ext->s_size);
+ scnhdr_int->s_scnptr = GET_SCNHDR_SCNPTR (abfd, scnhdr_ext->s_scnptr);
+ scnhdr_int->s_relptr = GET_SCNHDR_RELPTR (abfd, scnhdr_ext->s_relptr);
+ scnhdr_int->s_lnnoptr = GET_SCNHDR_LNNOPTR (abfd, scnhdr_ext->s_lnnoptr);
+ scnhdr_int->s_flags = H_GET_32 (abfd, scnhdr_ext->s_flags);
+
+ /* MS handles overflow of line numbers by carrying into the reloc
+ field (it appears). Since it's supposed to be zero for PE
+ *IMAGE* format, that's safe. This is still a bit iffy. */
+#ifdef COFF_IMAGE_WITH_PE
+ scnhdr_int->s_nlnno = (H_GET_16 (abfd, scnhdr_ext->s_nlnno)
+ + (H_GET_16 (abfd, scnhdr_ext->s_nreloc) << 16));
+ scnhdr_int->s_nreloc = 0;
+#else
+ scnhdr_int->s_nreloc = H_GET_16 (abfd, scnhdr_ext->s_nreloc);
+ scnhdr_int->s_nlnno = H_GET_16 (abfd, scnhdr_ext->s_nlnno);
+#endif
+
+ if (scnhdr_int->s_vaddr != 0)
+ {
+ scnhdr_int->s_vaddr += pe_data (abfd)->pe_opthdr.ImageBase;
+ /* Do not cut upper 32-bits for 64-bit vma. */
+#ifndef COFF_WITH_pex64
+ scnhdr_int->s_vaddr &= 0xffffffff;
+#endif
+ }
+
+#ifndef COFF_NO_HACK_SCNHDR_SIZE
+ /* If this section holds uninitialized data and is from an object file
+ or from an executable image that has not initialized the field,
+ or if the image is an executable file and the physical size is padded,
+ use the virtual size (stored in s_paddr) instead. */
+ if (scnhdr_int->s_paddr > 0
+ && (((scnhdr_int->s_flags & IMAGE_SCN_CNT_UNINITIALIZED_DATA) != 0
+ && (! bfd_pei_p (abfd) || scnhdr_int->s_size == 0))
+ || (bfd_pei_p (abfd) && (scnhdr_int->s_size > scnhdr_int->s_paddr))))
+ /* This code used to set scnhdr_int->s_paddr to 0. However,
+ coff_set_alignment_hook stores s_paddr in virt_size, which
+ only works if it correctly holds the virtual size of the
+ section. */
+ scnhdr_int->s_size = scnhdr_int->s_paddr;
+#endif
+}
+
+static bfd_boolean
+pe_mkobject (bfd * abfd)
+{
+ pe_data_type *pe;
+ bfd_size_type amt = sizeof (pe_data_type);
+
+ abfd->tdata.pe_obj_data = (struct pe_tdata *) bfd_zalloc (abfd, amt);
+
+ if (abfd->tdata.pe_obj_data == 0)
+ return FALSE;
+
+ pe = pe_data (abfd);
+
+ pe->coff.pe = 1;
+
+ /* in_reloc_p is architecture dependent. */
+ pe->in_reloc_p = in_reloc_p;
+
+ memset (& pe->pe_opthdr, 0, sizeof pe->pe_opthdr);
+ return TRUE;
+}
+
+/* Create the COFF backend specific information. */
+
+static void *
+pe_mkobject_hook (bfd * abfd,
+ void * filehdr,
+ void * aouthdr ATTRIBUTE_UNUSED)
+{
+ struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr;
+ pe_data_type *pe;
+
+ if (! pe_mkobject (abfd))
+ 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;
+
+ pe->coff.timestamp = internal_f->f_timdat;
+
+ 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;
+
+ if ((internal_f->f_flags & IMAGE_FILE_DEBUG_STRIPPED) == 0)
+ abfd->flags |= HAS_DEBUG;
+
+#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 (void *) pe;
+}
+
+static bfd_boolean
+pe_print_private_bfd_data (bfd *abfd, void * vfile)
+{
+ FILE *file = (FILE *) vfile;
+
+ if (!_bfd_XX_print_private_bfd_data_common (abfd, vfile))
+ return FALSE;
+
+ if (pe_saved_coff_bfd_print_private_bfd_data == NULL)
+ return TRUE;
+
+ fputc ('\n', file);
+
+ return pe_saved_coff_bfd_print_private_bfd_data (abfd, vfile);
+}
+
+/* Copy any private info we understand from the input bfd
+ to the output bfd. */
+
+static bfd_boolean
+pe_bfd_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
+{
+ /* PR binutils/716: Copy the large address aware flag.
+ XXX: Should we be copying other flags or other fields in the pe_data()
+ structure ? */
+ if (pe_data (obfd) != NULL
+ && pe_data (ibfd) != NULL
+ && pe_data (ibfd)->real_flags & IMAGE_FILE_LARGE_ADDRESS_AWARE)
+ pe_data (obfd)->real_flags |= IMAGE_FILE_LARGE_ADDRESS_AWARE;
+
+ if (!_bfd_XX_bfd_copy_private_bfd_data_common (ibfd, obfd))
+ return FALSE;
+
+ if (pe_saved_coff_bfd_copy_private_bfd_data)
+ return pe_saved_coff_bfd_copy_private_bfd_data (ibfd, obfd);
+
+ return TRUE;
+}
+
+#define coff_bfd_copy_private_section_data \
+ _bfd_XX_bfd_copy_private_section_data
+
+#define coff_get_symbol_info _bfd_XX_get_symbol_info
+
+#ifdef COFF_IMAGE_WITH_PE
+
+/* Code to handle Microsoft's Image Library Format.
+ Also known as LINK6 format.
+ Documentation about this format can be found at:
+
+ http://msdn.microsoft.com/library/specs/pecoff_section8.htm */
+
+/* The following constants specify the sizes of the various data
+ structures that we have to create in order to build a bfd describing
+ an ILF object file. The final "+ 1" in the definitions of SIZEOF_IDATA6
+ and SIZEOF_IDATA7 below is to allow for the possibility that we might
+ need a padding byte in order to ensure 16 bit alignment for the section's
+ contents.
+
+ The value for SIZEOF_ILF_STRINGS is computed as follows:
+
+ There will be NUM_ILF_SECTIONS section symbols. Allow 9 characters
+ per symbol for their names (longest section name is .idata$x).
+
+ There will be two symbols for the imported value, one the symbol name
+ and one with _imp__ prefixed. Allowing for the terminating nul's this
+ is strlen (symbol_name) * 2 + 8 + 21 + strlen (source_dll).
+
+ The strings in the string table must start STRING__SIZE_SIZE bytes into
+ the table in order to for the string lookup code in coffgen/coffcode to
+ work. */
+#define NUM_ILF_RELOCS 8
+#define NUM_ILF_SECTIONS 6
+#define NUM_ILF_SYMS (2 + NUM_ILF_SECTIONS)
+
+#define SIZEOF_ILF_SYMS (NUM_ILF_SYMS * sizeof (* vars.sym_cache))
+#define SIZEOF_ILF_SYM_TABLE (NUM_ILF_SYMS * sizeof (* vars.sym_table))
+#define SIZEOF_ILF_NATIVE_SYMS (NUM_ILF_SYMS * sizeof (* vars.native_syms))
+#define SIZEOF_ILF_SYM_PTR_TABLE (NUM_ILF_SYMS * sizeof (* vars.sym_ptr_table))
+#define SIZEOF_ILF_EXT_SYMS (NUM_ILF_SYMS * sizeof (* vars.esym_table))
+#define SIZEOF_ILF_RELOCS (NUM_ILF_RELOCS * sizeof (* vars.reltab))
+#define SIZEOF_ILF_INT_RELOCS (NUM_ILF_RELOCS * sizeof (* vars.int_reltab))
+#define SIZEOF_ILF_STRINGS (strlen (symbol_name) * 2 + 8 \
+ + 21 + strlen (source_dll) \
+ + NUM_ILF_SECTIONS * 9 \
+ + STRING_SIZE_SIZE)
+#define SIZEOF_IDATA2 (5 * 4)
+
+/* For PEx64 idata4 & 5 have thumb size of 8 bytes. */
+#ifdef COFF_WITH_pex64
+#define SIZEOF_IDATA4 (2 * 4)
+#define SIZEOF_IDATA5 (2 * 4)
+#else
+#define SIZEOF_IDATA4 (1 * 4)
+#define SIZEOF_IDATA5 (1 * 4)
+#endif
+
+#define SIZEOF_IDATA6 (2 + strlen (symbol_name) + 1 + 1)
+#define SIZEOF_IDATA7 (strlen (source_dll) + 1 + 1)
+#define SIZEOF_ILF_SECTIONS (NUM_ILF_SECTIONS * sizeof (struct coff_section_tdata))
+
+#define ILF_DATA_SIZE \
+ + SIZEOF_ILF_SYMS \
+ + SIZEOF_ILF_SYM_TABLE \
+ + SIZEOF_ILF_NATIVE_SYMS \
+ + SIZEOF_ILF_SYM_PTR_TABLE \
+ + SIZEOF_ILF_EXT_SYMS \
+ + SIZEOF_ILF_RELOCS \
+ + SIZEOF_ILF_INT_RELOCS \
+ + SIZEOF_ILF_STRINGS \
+ + SIZEOF_IDATA2 \
+ + SIZEOF_IDATA4 \
+ + SIZEOF_IDATA5 \
+ + SIZEOF_IDATA6 \
+ + SIZEOF_IDATA7 \
+ + SIZEOF_ILF_SECTIONS \
+ + MAX_TEXT_SECTION_SIZE
+
+/* Create an empty relocation against the given symbol. */
+
+static void
+pe_ILF_make_a_symbol_reloc (pe_ILF_vars * vars,
+ bfd_vma address,
+ bfd_reloc_code_real_type reloc,
+ struct bfd_symbol ** sym,
+ unsigned int sym_index)
+{
+ arelent * entry;
+ struct internal_reloc * internal;
+
+ entry = vars->reltab + vars->relcount;
+ internal = vars->int_reltab + vars->relcount;
+
+ entry->address = address;
+ entry->addend = 0;
+ entry->howto = bfd_reloc_type_lookup (vars->abfd, reloc);
+ entry->sym_ptr_ptr = sym;
+
+ internal->r_vaddr = address;
+ internal->r_symndx = sym_index;
+ internal->r_type = entry->howto->type;
+
+ vars->relcount ++;
+
+ BFD_ASSERT (vars->relcount <= NUM_ILF_RELOCS);
+}
+
+/* Create an empty relocation against the given section. */
+
+static void
+pe_ILF_make_a_reloc (pe_ILF_vars * vars,
+ bfd_vma address,
+ bfd_reloc_code_real_type reloc,
+ asection_ptr sec)
+{
+ pe_ILF_make_a_symbol_reloc (vars, address, reloc, sec->symbol_ptr_ptr,
+ coff_section_data (vars->abfd, sec)->i);
+}
+
+/* Move the queued relocs into the given section. */
+
+static void
+pe_ILF_save_relocs (pe_ILF_vars * vars,
+ asection_ptr sec)
+{
+ /* Make sure that there is somewhere to store the internal relocs. */
+ if (coff_section_data (vars->abfd, sec) == NULL)
+ /* We should probably return an error indication here. */
+ abort ();
+
+ coff_section_data (vars->abfd, sec)->relocs = vars->int_reltab;
+ coff_section_data (vars->abfd, sec)->keep_relocs = TRUE;
+
+ sec->relocation = vars->reltab;
+ sec->reloc_count = vars->relcount;
+ sec->flags |= SEC_RELOC;
+
+ vars->reltab += vars->relcount;
+ vars->int_reltab += vars->relcount;
+ vars->relcount = 0;
+
+ BFD_ASSERT ((bfd_byte *) vars->int_reltab < (bfd_byte *) vars->string_table);
+}
+
+/* Create a global symbol and add it to the relevant tables. */
+
+static void
+pe_ILF_make_a_symbol (pe_ILF_vars * vars,
+ const char * prefix,
+ const char * symbol_name,
+ asection_ptr section,
+ flagword extra_flags)
+{
+ coff_symbol_type * sym;
+ combined_entry_type * ent;
+ SYMENT * esym;
+ unsigned short sclass;
+
+ if (extra_flags & BSF_LOCAL)
+ sclass = C_STAT;
+ else
+ sclass = C_EXT;
+
+#ifdef THUMBPEMAGIC
+ if (vars->magic == THUMBPEMAGIC)
+ {
+ if (extra_flags & BSF_FUNCTION)
+ sclass = C_THUMBEXTFUNC;
+ else if (extra_flags & BSF_LOCAL)
+ sclass = C_THUMBSTAT;
+ else
+ sclass = C_THUMBEXT;
+ }
+#endif
+
+ BFD_ASSERT (vars->sym_index < NUM_ILF_SYMS);
+
+ sym = vars->sym_ptr;
+ ent = vars->native_ptr;
+ esym = vars->esym_ptr;
+
+ /* Copy the symbol's name into the string table. */
+ sprintf (vars->string_ptr, "%s%s", prefix, symbol_name);
+
+ if (section == NULL)
+ section = bfd_und_section_ptr;
+
+ /* Initialise the external symbol. */
+ H_PUT_32 (vars->abfd, vars->string_ptr - vars->string_table,
+ esym->e.e.e_offset);
+ H_PUT_16 (vars->abfd, section->target_index, esym->e_scnum);
+ esym->e_sclass[0] = sclass;
+
+ /* The following initialisations are unnecessary - the memory is
+ zero initialised. They are just kept here as reminders. */
+
+ /* Initialise the internal symbol structure. */
+ ent->u.syment.n_sclass = sclass;
+ ent->u.syment.n_scnum = section->target_index;
+ ent->u.syment._n._n_n._n_offset = (bfd_hostptr_t) sym;
+ ent->is_sym = TRUE;
+
+ sym->symbol.the_bfd = vars->abfd;
+ sym->symbol.name = vars->string_ptr;
+ sym->symbol.flags = BSF_EXPORT | BSF_GLOBAL | extra_flags;
+ sym->symbol.section = section;
+ sym->native = ent;
+
+ * vars->table_ptr = vars->sym_index;
+ * vars->sym_ptr_ptr = sym;
+
+ /* Adjust pointers for the next symbol. */
+ vars->sym_index ++;
+ vars->sym_ptr ++;
+ vars->sym_ptr_ptr ++;
+ vars->table_ptr ++;
+ vars->native_ptr ++;
+ vars->esym_ptr ++;
+ vars->string_ptr += strlen (symbol_name) + strlen (prefix) + 1;
+
+ BFD_ASSERT (vars->string_ptr < vars->end_string_ptr);
+}
+
+/* Create a section. */
+
+static asection_ptr
+pe_ILF_make_a_section (pe_ILF_vars * vars,
+ const char * name,
+ unsigned int size,
+ flagword extra_flags)
+{
+ asection_ptr sec;
+ flagword flags;
+
+ sec = bfd_make_section_old_way (vars->abfd, name);
+ if (sec == NULL)
+ return NULL;
+
+ flags = SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_KEEP | SEC_IN_MEMORY;
+
+ bfd_set_section_flags (vars->abfd, sec, flags | extra_flags);
+
+ (void) bfd_set_section_alignment (vars->abfd, sec, 2);
+
+ /* Check that we will not run out of space. */
+ BFD_ASSERT (vars->data + size < vars->bim->buffer + vars->bim->size);
+
+ /* Set the section size and contents. The actual
+ contents are filled in by our parent. */
+ bfd_set_section_size (vars->abfd, sec, (bfd_size_type) size);
+ sec->contents = vars->data;
+ sec->target_index = vars->sec_index ++;
+
+ /* Advance data pointer in the vars structure. */
+ vars->data += size;
+
+ /* Skip the padding byte if it was not needed.
+ The logic here is that if the string length is odd,
+ then the entire string length, including the null byte,
+ is even and so the extra, padding byte, is not needed. */
+ if (size & 1)
+ vars->data --;
+
+ /* Create a coff_section_tdata structure for our use. */
+ sec->used_by_bfd = (struct coff_section_tdata *) vars->data;
+ vars->data += sizeof (struct coff_section_tdata);
+
+ BFD_ASSERT (vars->data <= vars->bim->buffer + vars->bim->size);
+
+ /* Create a symbol to refer to this section. */
+ pe_ILF_make_a_symbol (vars, "", name, sec, BSF_LOCAL);
+
+ /* Cache the index to the symbol in the coff_section_data structure. */
+ coff_section_data (vars->abfd, sec)->i = vars->sym_index - 1;
+
+ return sec;
+}
+
+/* This structure contains the code that goes into the .text section
+ in order to perform a jump into the DLL lookup table. The entries
+ in the table are index by the magic number used to represent the
+ machine type in the PE file. The contents of the data[] arrays in
+ these entries are stolen from the jtab[] arrays in ld/pe-dll.c.
+ The SIZE field says how many bytes in the DATA array are actually
+ used. The OFFSET field says where in the data array the address
+ of the .idata$5 section should be placed. */
+#define MAX_TEXT_SECTION_SIZE 32
+
+typedef struct
+{
+ unsigned short magic;
+ unsigned char data[MAX_TEXT_SECTION_SIZE];
+ unsigned int size;
+ unsigned int offset;
+}
+jump_table;
+
+static jump_table jtab[] =
+{
+#ifdef I386MAGIC
+ { I386MAGIC,
+ { 0xff, 0x25, 0x00, 0x00, 0x00, 0x00, 0x90, 0x90 },
+ 8, 2
+ },
+#endif
+
+#ifdef AMD64MAGIC
+ { AMD64MAGIC,
+ { 0xff, 0x25, 0x00, 0x00, 0x00, 0x00, 0x90, 0x90 },
+ 8, 2
+ },
+#endif
+
+#ifdef MC68MAGIC
+ { MC68MAGIC,
+ { /* XXX fill me in */ },
+ 0, 0
+ },
+#endif
+
+#ifdef MIPS_ARCH_MAGIC_WINCE
+ { MIPS_ARCH_MAGIC_WINCE,
+ { 0x00, 0x00, 0x08, 0x3c, 0x00, 0x00, 0x08, 0x8d,
+ 0x08, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00 },
+ 16, 0
+ },
+#endif
+
+#ifdef SH_ARCH_MAGIC_WINCE
+ { SH_ARCH_MAGIC_WINCE,
+ { 0x01, 0xd0, 0x02, 0x60, 0x2b, 0x40,
+ 0x09, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ 12, 8
+ },
+#endif
+
+#ifdef ARMPEMAGIC
+ { ARMPEMAGIC,
+ { 0x00, 0xc0, 0x9f, 0xe5, 0x00, 0xf0,
+ 0x9c, 0xe5, 0x00, 0x00, 0x00, 0x00},
+ 12, 8
+ },
+#endif
+
+#ifdef THUMBPEMAGIC
+ { THUMBPEMAGIC,
+ { 0x40, 0xb4, 0x02, 0x4e, 0x36, 0x68, 0xb4, 0x46,
+ 0x40, 0xbc, 0x60, 0x47, 0x00, 0x00, 0x00, 0x00 },
+ 16, 12
+ },
+#endif
+ { 0, { 0 }, 0, 0 }
+};
+
+#ifndef NUM_ENTRIES
+#define NUM_ENTRIES(a) (sizeof (a) / sizeof (a)[0])
+#endif
+
+/* Build a full BFD from the information supplied in a ILF object. */
+
+static bfd_boolean
+pe_ILF_build_a_bfd (bfd * abfd,
+ unsigned int magic,
+ char * symbol_name,
+ char * source_dll,
+ unsigned int ordinal,
+ unsigned int types)
+{
+ bfd_byte * ptr;
+ pe_ILF_vars vars;
+ struct internal_filehdr internal_f;
+ unsigned int import_type;
+ unsigned int import_name_type;
+ asection_ptr id4, id5, id6 = NULL, text = NULL;
+ coff_symbol_type ** imp_sym;
+ unsigned int imp_index;
+
+ /* Decode and verify the types field of the ILF structure. */
+ import_type = types & 0x3;
+ import_name_type = (types & 0x1c) >> 2;
+
+ switch (import_type)
+ {
+ case IMPORT_CODE:
+ case IMPORT_DATA:
+ break;
+
+ case IMPORT_CONST:
+ /* XXX code yet to be written. */
+ _bfd_error_handler (_("%B: Unhandled import type; %x"),
+ abfd, import_type);
+ return FALSE;
+
+ default:
+ _bfd_error_handler (_("%B: Unrecognised import type; %x"),
+ abfd, import_type);
+ return FALSE;
+ }
+
+ switch (import_name_type)
+ {
+ case IMPORT_ORDINAL:
+ case IMPORT_NAME:
+ case IMPORT_NAME_NOPREFIX:
+ case IMPORT_NAME_UNDECORATE:
+ break;
+
+ default:
+ _bfd_error_handler (_("%B: Unrecognised import name type; %x"),
+ abfd, import_name_type);
+ return FALSE;
+ }
+
+ /* Initialise local variables.
+
+ Note these are kept in a structure rather than being
+ declared as statics since bfd frowns on global variables.
+
+ We are going to construct the contents of the BFD in memory,
+ so allocate all the space that we will need right now. */
+ vars.bim
+ = (struct bfd_in_memory *) bfd_malloc ((bfd_size_type) sizeof (*vars.bim));
+ if (vars.bim == NULL)
+ return FALSE;
+
+ ptr = (bfd_byte *) bfd_zmalloc ((bfd_size_type) ILF_DATA_SIZE);
+ vars.bim->buffer = ptr;
+ vars.bim->size = ILF_DATA_SIZE;
+ if (ptr == NULL)
+ goto error_return;
+
+ /* Initialise the pointers to regions of the memory and the
+ other contents of the pe_ILF_vars structure as well. */
+ vars.sym_cache = (coff_symbol_type *) ptr;
+ vars.sym_ptr = (coff_symbol_type *) ptr;
+ vars.sym_index = 0;
+ ptr += SIZEOF_ILF_SYMS;
+
+ vars.sym_table = (unsigned int *) ptr;
+ vars.table_ptr = (unsigned int *) ptr;
+ ptr += SIZEOF_ILF_SYM_TABLE;
+
+ vars.native_syms = (combined_entry_type *) ptr;
+ vars.native_ptr = (combined_entry_type *) ptr;
+ ptr += SIZEOF_ILF_NATIVE_SYMS;
+
+ vars.sym_ptr_table = (coff_symbol_type **) ptr;
+ vars.sym_ptr_ptr = (coff_symbol_type **) ptr;
+ ptr += SIZEOF_ILF_SYM_PTR_TABLE;
+
+ vars.esym_table = (SYMENT *) ptr;
+ vars.esym_ptr = (SYMENT *) ptr;
+ ptr += SIZEOF_ILF_EXT_SYMS;
+
+ vars.reltab = (arelent *) ptr;
+ vars.relcount = 0;
+ ptr += SIZEOF_ILF_RELOCS;
+
+ vars.int_reltab = (struct internal_reloc *) ptr;
+ ptr += SIZEOF_ILF_INT_RELOCS;
+
+ vars.string_table = (char *) ptr;
+ vars.string_ptr = (char *) ptr + STRING_SIZE_SIZE;
+ ptr += SIZEOF_ILF_STRINGS;
+ vars.end_string_ptr = (char *) ptr;
+
+ /* The remaining space in bim->buffer is used
+ by the pe_ILF_make_a_section() function. */
+ vars.data = ptr;
+ vars.abfd = abfd;
+ vars.sec_index = 0;
+ vars.magic = magic;
+
+ /* Create the initial .idata$<n> sections:
+ [.idata$2: Import Directory Table -- not needed]
+ .idata$4: Import Lookup Table
+ .idata$5: Import Address Table
+
+ Note we do not create a .idata$3 section as this is
+ created for us by the linker script. */
+ id4 = pe_ILF_make_a_section (& vars, ".idata$4", SIZEOF_IDATA4, 0);
+ id5 = pe_ILF_make_a_section (& vars, ".idata$5", SIZEOF_IDATA5, 0);
+ if (id4 == NULL || id5 == NULL)
+ goto error_return;
+
+ /* Fill in the contents of these sections. */
+ if (import_name_type == IMPORT_ORDINAL)
+ {
+ if (ordinal == 0)
+ /* XXX - treat as IMPORT_NAME ??? */
+ abort ();
+
+#ifdef COFF_WITH_pex64
+ ((unsigned int *) id4->contents)[0] = ordinal;
+ ((unsigned int *) id4->contents)[1] = 0x80000000;
+ ((unsigned int *) id5->contents)[0] = ordinal;
+ ((unsigned int *) id5->contents)[1] = 0x80000000;
+#else
+ * (unsigned int *) id4->contents = ordinal | 0x80000000;
+ * (unsigned int *) id5->contents = ordinal | 0x80000000;
+#endif
+ }
+ else
+ {
+ char * symbol;
+ unsigned int len;
+
+ /* Create .idata$6 - the Hint Name Table. */
+ id6 = pe_ILF_make_a_section (& vars, ".idata$6", SIZEOF_IDATA6, 0);
+ if (id6 == NULL)
+ goto error_return;
+
+ /* If necessary, trim the import symbol name. */
+ symbol = symbol_name;
+
+ /* As used by MS compiler, '_', '@', and '?' are alternative
+ forms of USER_LABEL_PREFIX, with '?' for c++ mangled names,
+ '@' used for fastcall (in C), '_' everywhere else. Only one
+ of these is used for a symbol. We strip this leading char for
+ IMPORT_NAME_NOPREFIX and IMPORT_NAME_UNDECORATE as per the
+ PE COFF 6.0 spec (section 8.3, Import Name Type). */
+
+ if (import_name_type != IMPORT_NAME)
+ {
+ char c = symbol[0];
+
+ /* Check that we don't remove for targets with empty
+ USER_LABEL_PREFIX the leading underscore. */
+ if ((c == '_' && abfd->xvec->symbol_leading_char != 0)
+ || c == '@' || c == '?')
+ symbol++;
+ }
+
+ len = strlen (symbol);
+ if (import_name_type == IMPORT_NAME_UNDECORATE)
+ {
+ /* Truncate at the first '@'. */
+ char *at = strchr (symbol, '@');
+
+ if (at != NULL)
+ len = at - symbol;
+ }
+
+ id6->contents[0] = ordinal & 0xff;
+ id6->contents[1] = ordinal >> 8;
+
+ memcpy ((char *) id6->contents + 2, symbol, len);
+ id6->contents[len + 2] = '\0';
+ }
+
+ if (import_name_type != IMPORT_ORDINAL)
+ {
+ pe_ILF_make_a_reloc (&vars, (bfd_vma) 0, BFD_RELOC_RVA, id6);
+ pe_ILF_save_relocs (&vars, id4);
+
+ pe_ILF_make_a_reloc (&vars, (bfd_vma) 0, BFD_RELOC_RVA, id6);
+ pe_ILF_save_relocs (&vars, id5);
+ }
+
+ /* Create extra sections depending upon the type of import we are dealing with. */
+ switch (import_type)
+ {
+ int i;
+
+ case IMPORT_CODE:
+ /* Create a .text section.
+ First we need to look up its contents in the jump table. */
+ for (i = NUM_ENTRIES (jtab); i--;)
+ {
+ if (jtab[i].size == 0)
+ continue;
+ if (jtab[i].magic == magic)
+ break;
+ }
+ /* If we did not find a matching entry something is wrong. */
+ if (i < 0)
+ abort ();
+
+ /* Create the .text section. */
+ text = pe_ILF_make_a_section (& vars, ".text", jtab[i].size, SEC_CODE);
+ if (text == NULL)
+ goto error_return;
+
+ /* Copy in the jump code. */
+ memcpy (text->contents, jtab[i].data, jtab[i].size);
+
+ /* Create an import symbol. */
+ pe_ILF_make_a_symbol (& vars, "__imp_", symbol_name, id5, 0);
+ imp_sym = vars.sym_ptr_ptr - 1;
+ imp_index = vars.sym_index - 1;
+
+ /* Create a reloc for the data in the text section. */
+#ifdef MIPS_ARCH_MAGIC_WINCE
+ if (magic == MIPS_ARCH_MAGIC_WINCE)
+ {
+ pe_ILF_make_a_symbol_reloc (&vars, (bfd_vma) 0, BFD_RELOC_HI16_S,
+ (struct bfd_symbol **) imp_sym,
+ imp_index);
+ pe_ILF_make_a_reloc (&vars, (bfd_vma) 0, BFD_RELOC_LO16, text);
+ pe_ILF_make_a_symbol_reloc (&vars, (bfd_vma) 4, BFD_RELOC_LO16,
+ (struct bfd_symbol **) imp_sym,
+ imp_index);
+ }
+ else
+#endif
+ pe_ILF_make_a_symbol_reloc (&vars, (bfd_vma) jtab[i].offset,
+ BFD_RELOC_32, (asymbol **) imp_sym,
+ imp_index);
+
+ pe_ILF_save_relocs (& vars, text);
+ break;
+
+ case IMPORT_DATA:
+ break;
+
+ default:
+ /* XXX code not yet written. */
+ abort ();
+ }
+
+ /* Initialise the bfd. */
+ memset (& internal_f, 0, sizeof (internal_f));
+
+ internal_f.f_magic = magic;
+ internal_f.f_symptr = 0;
+ internal_f.f_nsyms = 0;
+ internal_f.f_flags = F_AR32WR | F_LNNO; /* XXX is this correct ? */
+
+ if ( ! bfd_set_start_address (abfd, (bfd_vma) 0)
+ || ! bfd_coff_set_arch_mach_hook (abfd, & internal_f))
+ goto error_return;
+
+ if (bfd_coff_mkobject_hook (abfd, (void *) & internal_f, NULL) == NULL)
+ goto error_return;
+
+ coff_data (abfd)->pe = 1;
+#ifdef THUMBPEMAGIC
+ if (vars.magic == THUMBPEMAGIC)
+ /* Stop some linker warnings about thumb code not supporting interworking. */
+ coff_data (abfd)->flags |= F_INTERWORK | F_INTERWORK_SET;
+#endif
+
+ /* Switch from file contents to memory contents. */
+ bfd_cache_close (abfd);
+
+ abfd->iostream = (void *) vars.bim;
+ abfd->flags |= BFD_IN_MEMORY /* | HAS_LOCALS */;
+ abfd->iovec = &_bfd_memory_iovec;
+ abfd->where = 0;
+ abfd->origin = 0;
+ obj_sym_filepos (abfd) = 0;
+
+ /* Now create a symbol describing the imported value. */
+ switch (import_type)
+ {
+ case IMPORT_CODE:
+ pe_ILF_make_a_symbol (& vars, "", symbol_name, text,
+ BSF_NOT_AT_END | BSF_FUNCTION);
+
+ /* Create an import symbol for the DLL, without the
+ .dll suffix. */
+ ptr = (bfd_byte *) strrchr (source_dll, '.');
+ if (ptr)
+ * ptr = 0;
+ pe_ILF_make_a_symbol (& vars, "__IMPORT_DESCRIPTOR_", source_dll, NULL, 0);
+ if (ptr)
+ * ptr = '.';
+ break;
+
+ case IMPORT_DATA:
+ /* Nothing to do here. */
+ break;
+
+ default:
+ /* XXX code not yet written. */
+ abort ();
+ }
+
+ /* Point the bfd at the symbol table. */
+ obj_symbols (abfd) = vars.sym_cache;
+ bfd_get_symcount (abfd) = vars.sym_index;
+
+ obj_raw_syments (abfd) = vars.native_syms;
+ obj_raw_syment_count (abfd) = vars.sym_index;
+
+ obj_coff_external_syms (abfd) = (void *) vars.esym_table;
+ obj_coff_keep_syms (abfd) = TRUE;
+
+ obj_convert (abfd) = vars.sym_table;
+ obj_conv_table_size (abfd) = vars.sym_index;
+
+ obj_coff_strings (abfd) = vars.string_table;
+ obj_coff_keep_strings (abfd) = TRUE;
+
+ abfd->flags |= HAS_SYMS;
+
+ return TRUE;
+
+ error_return:
+ if (vars.bim->buffer != NULL)
+ free (vars.bim->buffer);
+ free (vars.bim);
+ return FALSE;
+}
+
+/* We have detected a Image Library Format archive element.
+ Decode the element and return the appropriate target. */
+
+static const bfd_target *
+pe_ILF_object_p (bfd * abfd)
+{
+ bfd_byte buffer[14];
+ bfd_byte * ptr;
+ char * symbol_name;
+ char * source_dll;
+ unsigned int machine;
+ bfd_size_type size;
+ unsigned int ordinal;
+ unsigned int types;
+ unsigned int magic;
+
+ /* Upon entry the first six bytes of the ILF header have
+ already been read. Now read the rest of the header. */
+ if (bfd_bread (buffer, (bfd_size_type) 14, abfd) != 14)
+ return NULL;
+
+ ptr = buffer;
+
+ machine = H_GET_16 (abfd, ptr);
+ ptr += 2;
+
+ /* Check that the machine type is recognised. */
+ magic = 0;
+
+ switch (machine)
+ {
+ case IMAGE_FILE_MACHINE_UNKNOWN:
+ case IMAGE_FILE_MACHINE_ALPHA:
+ case IMAGE_FILE_MACHINE_ALPHA64:
+ case IMAGE_FILE_MACHINE_IA64:
+ break;
+
+ case IMAGE_FILE_MACHINE_I386:
+#ifdef I386MAGIC
+ magic = I386MAGIC;
+#endif
+ break;
+
+ case IMAGE_FILE_MACHINE_AMD64:
+#ifdef AMD64MAGIC
+ magic = AMD64MAGIC;
+#endif
+ break;
+
+ case IMAGE_FILE_MACHINE_M68K:
+#ifdef MC68AGIC
+ magic = MC68MAGIC;
+#endif
+ break;
+
+ case IMAGE_FILE_MACHINE_R3000:
+ case IMAGE_FILE_MACHINE_R4000:
+ case IMAGE_FILE_MACHINE_R10000:
+
+ case IMAGE_FILE_MACHINE_MIPS16:
+ case IMAGE_FILE_MACHINE_MIPSFPU:
+ case IMAGE_FILE_MACHINE_MIPSFPU16:
+#ifdef MIPS_ARCH_MAGIC_WINCE
+ magic = MIPS_ARCH_MAGIC_WINCE;
+#endif
+ break;
+
+ case IMAGE_FILE_MACHINE_SH3:
+ case IMAGE_FILE_MACHINE_SH4:
+#ifdef SH_ARCH_MAGIC_WINCE
+ magic = SH_ARCH_MAGIC_WINCE;
+#endif
+ break;
+
+ case IMAGE_FILE_MACHINE_ARM:
+#ifdef ARMPEMAGIC
+ magic = ARMPEMAGIC;
+#endif
+ break;
+
+ case IMAGE_FILE_MACHINE_THUMB:
+#ifdef THUMBPEMAGIC
+ {
+ extern const bfd_target TARGET_LITTLE_SYM;
+
+ if (abfd->xvec == & TARGET_LITTLE_SYM)
+ magic = THUMBPEMAGIC;
+ }
+#endif
+ break;
+
+ case IMAGE_FILE_MACHINE_POWERPC:
+ /* We no longer support PowerPC. */
+ default:
+ _bfd_error_handler
+ (_("%B: Unrecognised machine type (0x%x)"
+ " in Import Library Format archive"),
+ abfd, machine);
+ bfd_set_error (bfd_error_malformed_archive);
+
+ return NULL;
+ break;
+ }
+
+ if (magic == 0)
+ {
+ _bfd_error_handler
+ (_("%B: Recognised but unhandled machine type (0x%x)"
+ " in Import Library Format archive"),
+ abfd, machine);
+ bfd_set_error (bfd_error_wrong_format);
+
+ return NULL;
+ }
+
+ /* We do not bother to check the date.
+ date = H_GET_32 (abfd, ptr); */
+ ptr += 4;
+
+ size = H_GET_32 (abfd, ptr);
+ ptr += 4;
+
+ if (size == 0)
+ {
+ _bfd_error_handler
+ (_("%B: size field is zero in Import Library Format header"), abfd);
+ bfd_set_error (bfd_error_malformed_archive);
+
+ return NULL;
+ }
+
+ ordinal = H_GET_16 (abfd, ptr);
+ ptr += 2;
+
+ types = H_GET_16 (abfd, ptr);
+ /* ptr += 2; */
+
+ /* Now read in the two strings that follow. */
+ ptr = (bfd_byte *) bfd_alloc (abfd, size);
+ if (ptr == NULL)
+ return NULL;
+
+ if (bfd_bread (ptr, size, abfd) != size)
+ {
+ bfd_release (abfd, ptr);
+ return NULL;
+ }
+
+ symbol_name = (char *) ptr;
+ source_dll = symbol_name + strlen (symbol_name) + 1;
+
+ /* Verify that the strings are null terminated. */
+ if (ptr[size - 1] != 0
+ || (bfd_size_type) ((bfd_byte *) source_dll - ptr) >= size)
+ {
+ _bfd_error_handler
+ (_("%B: string not null terminated in ILF object file."), abfd);
+ bfd_set_error (bfd_error_malformed_archive);
+ bfd_release (abfd, ptr);
+ return NULL;
+ }
+
+ /* Now construct the bfd. */
+ if (! pe_ILF_build_a_bfd (abfd, magic, symbol_name,
+ source_dll, ordinal, types))
+ {
+ bfd_release (abfd, ptr);
+ return NULL;
+ }
+
+ return abfd->xvec;
+}
+
+static const bfd_target *
+pe_bfd_object_p (bfd * abfd)
+{
+ bfd_byte buffer[6];
+ struct external_PEI_DOS_hdr dos_hdr;
+ struct external_PEI_IMAGE_hdr image_hdr;
+ struct internal_filehdr internal_f;
+ struct internal_aouthdr internal_a;
+ file_ptr opt_hdr_size;
+ file_ptr offset;
+
+ /* Detect if this a Microsoft Import Library Format element. */
+ /* First read the beginning of the header. */
+ if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0
+ || bfd_bread (buffer, (bfd_size_type) 6, abfd) != 6)
+ {
+ if (bfd_get_error () != bfd_error_system_call)
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+
+ /* Then check the magic and the version (only 0 is supported). */
+ if (H_GET_32 (abfd, buffer) == 0xffff0000
+ && H_GET_16 (abfd, buffer + 4) == 0)
+ return pe_ILF_object_p (abfd);
+
+ if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0
+ || bfd_bread (&dos_hdr, (bfd_size_type) sizeof (dos_hdr), abfd)
+ != sizeof (dos_hdr))
+ {
+ if (bfd_get_error () != bfd_error_system_call)
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+
+ /* There are really two magic numbers involved; the magic number
+ that says this is a NT executable (PEI) and the magic number that
+ determines the architecture. The former is DOSMAGIC, stored in
+ the e_magic field. The latter is stored in the f_magic field.
+ If the NT magic number isn't valid, the architecture magic number
+ could be mimicked by some other field (specifically, the number
+ of relocs in section 3). Since this routine can only be called
+ correctly for a PEI file, check the e_magic number here, and, if
+ it doesn't match, clobber the f_magic number so that we don't get
+ a false match. */
+ if (H_GET_16 (abfd, dos_hdr.e_magic) != DOSMAGIC)
+ {
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+
+ offset = H_GET_32 (abfd, dos_hdr.e_lfanew);
+ if (bfd_seek (abfd, offset, SEEK_SET) != 0
+ || (bfd_bread (&image_hdr, (bfd_size_type) sizeof (image_hdr), abfd)
+ != sizeof (image_hdr)))
+ {
+ if (bfd_get_error () != bfd_error_system_call)
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+
+ if (H_GET_32 (abfd, image_hdr.nt_signature) != 0x4550)
+ {
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+
+ /* Swap file header, so that we get the location for calling
+ real_object_p. */
+ bfd_coff_swap_filehdr_in (abfd, &image_hdr, &internal_f);
+
+ if (! bfd_coff_bad_format_hook (abfd, &internal_f)
+ || internal_f.f_opthdr > bfd_coff_aoutsz (abfd))
+ {
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+
+ /* Read the optional header, which has variable size. */
+ opt_hdr_size = internal_f.f_opthdr;
+
+ if (opt_hdr_size != 0)
+ {
+ bfd_size_type amt = opt_hdr_size;
+ void * opthdr;
+
+ /* PR 17521 file: 230-131433-0.004. */
+ if (amt < sizeof (PEAOUTHDR))
+ amt = sizeof (PEAOUTHDR);
+
+ opthdr = bfd_zalloc (abfd, amt);
+ if (opthdr == NULL)
+ return NULL;
+ if (bfd_bread (opthdr, opt_hdr_size, abfd)
+ != (bfd_size_type) opt_hdr_size)
+ return NULL;
+
+ bfd_coff_swap_aouthdr_in (abfd, opthdr, & internal_a);
+ }
+
+ return coff_real_object_p (abfd, internal_f.f_nscns, &internal_f,
+ (opt_hdr_size != 0
+ ? &internal_a
+ : (struct internal_aouthdr *) NULL));
+}
+
+#define coff_object_p pe_bfd_object_p
+#endif /* COFF_IMAGE_WITH_PE */
diff --git a/bfd/plugin.c b/bfd/plugin.c
new file mode 100644
index 0000000..a068861
--- /dev/null
+++ b/bfd/plugin.c
@@ -0,0 +1,561 @@
+/* Plugin support for BFD.
+ Copyright (C) 2009-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+
+#if BFD_SUPPORTS_PLUGINS
+
+#include <assert.h>
+#ifdef HAVE_DLFCN_H
+#include <dlfcn.h>
+#elif defined (HAVE_WINDOWS_H)
+#include <windows.h>
+#else
+#error Unknown how to handle dynamic-load-libraries.
+#endif
+#include <stdarg.h>
+#include "plugin-api.h"
+#include "plugin.h"
+#include "libbfd.h"
+#include "libiberty.h"
+#include <dirent.h>
+
+#if !defined (HAVE_DLFCN_H) && defined (HAVE_WINDOWS_H)
+
+#define RTLD_NOW 0 /* Dummy value. */
+
+static void *
+dlopen (const char *file, int mode ATTRIBUTE_UNUSED)
+{
+ return LoadLibrary (file);
+}
+
+static void *
+dlsym (void *handle, const char *name)
+{
+ return GetProcAddress (handle, name);
+}
+
+static int ATTRIBUTE_UNUSED
+dlclose (void *handle)
+{
+ FreeLibrary (handle);
+ return 0;
+}
+
+static const char *
+dlerror (void)
+{
+ return "Unable to load DLL.";
+}
+
+#endif /* !defined (HAVE_DLFCN_H) && defined (HAVE_WINDOWS_H) */
+
+#define bfd_plugin_close_and_cleanup _bfd_generic_close_and_cleanup
+#define bfd_plugin_bfd_free_cached_info _bfd_generic_bfd_free_cached_info
+#define bfd_plugin_new_section_hook _bfd_generic_new_section_hook
+#define bfd_plugin_get_section_contents _bfd_generic_get_section_contents
+#define bfd_plugin_get_section_contents_in_window _bfd_generic_get_section_contents_in_window
+#define bfd_plugin_bfd_copy_private_header_data _bfd_generic_bfd_copy_private_header_data
+#define bfd_plugin_bfd_merge_private_bfd_data _bfd_generic_bfd_merge_private_bfd_data
+#define bfd_plugin_bfd_copy_private_header_data _bfd_generic_bfd_copy_private_header_data
+#define bfd_plugin_bfd_set_private_flags _bfd_generic_bfd_set_private_flags
+#define bfd_plugin_core_file_matches_executable_p generic_core_file_matches_executable_p
+#define bfd_plugin_bfd_is_local_label_name _bfd_nosymbols_bfd_is_local_label_name
+#define bfd_plugin_bfd_is_target_special_symbol ((bfd_boolean (*) (bfd *, asymbol *)) bfd_false)
+#define bfd_plugin_get_lineno _bfd_nosymbols_get_lineno
+#define bfd_plugin_find_nearest_line _bfd_nosymbols_find_nearest_line
+#define bfd_plugin_find_line _bfd_nosymbols_find_line
+#define bfd_plugin_find_inliner_info _bfd_nosymbols_find_inliner_info
+#define bfd_plugin_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol
+#define bfd_plugin_read_minisymbols _bfd_generic_read_minisymbols
+#define bfd_plugin_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol
+#define bfd_plugin_set_arch_mach bfd_default_set_arch_mach
+#define bfd_plugin_set_section_contents _bfd_generic_set_section_contents
+#define bfd_plugin_bfd_get_relocated_section_contents bfd_generic_get_relocated_section_contents
+#define bfd_plugin_bfd_relax_section bfd_generic_relax_section
+#define bfd_plugin_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
+#define bfd_plugin_bfd_link_add_symbols _bfd_generic_link_add_symbols
+#define bfd_plugin_bfd_link_just_syms _bfd_generic_link_just_syms
+#define bfd_plugin_bfd_final_link _bfd_generic_final_link
+#define bfd_plugin_bfd_link_split_section _bfd_generic_link_split_section
+#define bfd_plugin_bfd_gc_sections bfd_generic_gc_sections
+#define bfd_plugin_bfd_lookup_section_flags bfd_generic_lookup_section_flags
+#define bfd_plugin_bfd_merge_sections bfd_generic_merge_sections
+#define bfd_plugin_bfd_is_group_section bfd_generic_is_group_section
+#define bfd_plugin_bfd_discard_group bfd_generic_discard_group
+#define bfd_plugin_section_already_linked _bfd_generic_section_already_linked
+#define bfd_plugin_bfd_define_common_symbol bfd_generic_define_common_symbol
+#define bfd_plugin_bfd_copy_link_hash_symbol_type _bfd_generic_copy_link_hash_symbol_type
+
+static enum ld_plugin_status
+message (int level ATTRIBUTE_UNUSED,
+ const char * format, ...)
+{
+ va_list args;
+ va_start (args, format);
+ printf ("bfd plugin: ");
+ vprintf (format, args);
+ putchar ('\n');
+ va_end (args);
+ return LDPS_OK;
+}
+
+/* Register a claim-file handler. */
+static ld_plugin_claim_file_handler claim_file;
+
+static enum ld_plugin_status
+register_claim_file (ld_plugin_claim_file_handler handler)
+{
+ claim_file = handler;
+ return LDPS_OK;
+}
+
+static enum ld_plugin_status
+add_symbols (void * handle,
+ int nsyms,
+ const struct ld_plugin_symbol * syms)
+{
+ bfd *abfd = handle;
+ struct plugin_data_struct *plugin_data =
+ bfd_alloc (abfd, sizeof (plugin_data_struct));
+
+ plugin_data->nsyms = nsyms;
+ plugin_data->syms = syms;
+
+ if (nsyms != 0)
+ abfd->flags |= HAS_SYMS;
+
+ abfd->tdata.plugin_data = plugin_data;
+ return LDPS_OK;
+}
+
+static const char *plugin_program_name;
+
+void
+bfd_plugin_set_program_name (const char *program_name)
+{
+ plugin_program_name = program_name;
+}
+
+static int
+try_claim (bfd *abfd)
+{
+ int claimed = 0;
+ struct ld_plugin_input_file file;
+ bfd *iobfd;
+
+ file.name = abfd->filename;
+
+ if (abfd->my_archive)
+ {
+ iobfd = abfd->my_archive;
+ file.offset = abfd->origin;
+ file.filesize = arelt_size (abfd);
+ }
+ else
+ {
+ iobfd = abfd;
+ file.offset = 0;
+ file.filesize = 0;
+ }
+
+ if (!iobfd->iostream && !bfd_open_file (iobfd))
+ return 0;
+
+ file.fd = fileno ((FILE *) iobfd->iostream);
+
+ if (!abfd->my_archive)
+ {
+ struct stat stat_buf;
+ if (fstat (file.fd, &stat_buf))
+ return 0;
+ file.filesize = stat_buf.st_size;
+ }
+
+ file.handle = abfd;
+ off_t cur_offset = lseek(file.fd, 0, SEEK_CUR);
+ claim_file (&file, &claimed);
+ lseek(file.fd, cur_offset, SEEK_SET);
+ if (!claimed)
+ return 0;
+
+ return 1;
+}
+
+static int
+try_load_plugin (const char *pname, bfd *abfd)
+{
+ void *plugin_handle;
+ int tv_size = 4;
+ struct ld_plugin_tv tv[tv_size];
+ int i;
+ ld_plugin_onload onload;
+ enum ld_plugin_status status;
+
+ plugin_handle = dlopen (pname, RTLD_NOW);
+ if (!plugin_handle)
+ {
+ (*_bfd_error_handler)("%s\n", dlerror ());
+ return 0;
+ }
+
+ onload = dlsym (plugin_handle, "onload");
+ if (!onload)
+ goto err;
+
+ i = 0;
+ tv[i].tv_tag = LDPT_MESSAGE;
+ tv[i].tv_u.tv_message = message;
+
+ ++i;
+ tv[i].tv_tag = LDPT_REGISTER_CLAIM_FILE_HOOK;
+ tv[i].tv_u.tv_register_claim_file = register_claim_file;
+
+ ++i;
+ tv[i].tv_tag = LDPT_ADD_SYMBOLS;
+ tv[i].tv_u.tv_add_symbols = add_symbols;
+
+ ++i;
+ tv[i].tv_tag = LDPT_NULL;
+ tv[i].tv_u.tv_val = 0;
+
+ status = (*onload)(tv);
+
+ if (status != LDPS_OK)
+ goto err;
+
+ if (!claim_file)
+ goto err;
+
+ if (!try_claim (abfd))
+ goto err;
+
+ return 1;
+
+ err:
+ plugin_handle = NULL;
+ return 0;
+}
+
+static const char *plugin_name;
+
+void
+bfd_plugin_set_plugin (const char *p)
+{
+ plugin_name = p;
+}
+
+static int
+load_plugin (bfd *abfd)
+{
+ char *plugin_dir;
+ char *p;
+ DIR *d;
+ struct dirent *ent;
+ int found = 0;
+
+ if (plugin_name)
+ return try_load_plugin (plugin_name, abfd);
+
+ if (plugin_program_name == NULL)
+ return 0;
+
+ plugin_dir = concat (BINDIR, "/../lib/bfd-plugins", NULL);
+ p = make_relative_prefix (plugin_program_name,
+ BINDIR,
+ plugin_dir);
+ free (plugin_dir);
+ plugin_dir = NULL;
+
+ d = opendir (p);
+ if (!d)
+ goto out;
+
+ while ((ent = readdir (d)))
+ {
+ char *full_name;
+ struct stat s;
+
+ full_name = concat (p, "/", ent->d_name, NULL);
+ if (stat(full_name, &s) == 0 && S_ISREG (s.st_mode))
+ found = try_load_plugin (full_name, abfd);
+ free (full_name);
+ if (found)
+ break;
+ }
+
+ out:
+ free (p);
+ if (d)
+ closedir (d);
+
+ return found;
+}
+
+
+static const bfd_target *
+bfd_plugin_object_p (bfd *abfd)
+{
+ if (!load_plugin (abfd))
+ return NULL;
+
+ return abfd->xvec;
+}
+
+/* Copy any private info we understand from the input bfd
+ to the output bfd. */
+
+static bfd_boolean
+bfd_plugin_bfd_copy_private_bfd_data (bfd *ibfd ATTRIBUTE_UNUSED,
+ bfd *obfd ATTRIBUTE_UNUSED)
+{
+ BFD_ASSERT (0);
+ return TRUE;
+}
+
+/* Copy any private info we understand from the input section
+ to the output section. */
+
+static bfd_boolean
+bfd_plugin_bfd_copy_private_section_data (bfd *ibfd ATTRIBUTE_UNUSED,
+ asection *isection ATTRIBUTE_UNUSED,
+ bfd *obfd ATTRIBUTE_UNUSED,
+ asection *osection ATTRIBUTE_UNUSED)
+{
+ BFD_ASSERT (0);
+ return TRUE;
+}
+
+/* Copy any private info we understand from the input symbol
+ to the output symbol. */
+
+static bfd_boolean
+bfd_plugin_bfd_copy_private_symbol_data (bfd *ibfd ATTRIBUTE_UNUSED,
+ asymbol *isymbol ATTRIBUTE_UNUSED,
+ bfd *obfd ATTRIBUTE_UNUSED,
+ asymbol *osymbol ATTRIBUTE_UNUSED)
+{
+ BFD_ASSERT (0);
+ return TRUE;
+}
+
+static bfd_boolean
+bfd_plugin_bfd_print_private_bfd_data (bfd *abfd ATTRIBUTE_UNUSED, PTR ptr ATTRIBUTE_UNUSED)
+{
+ BFD_ASSERT (0);
+ return TRUE;
+}
+
+static char *
+bfd_plugin_core_file_failing_command (bfd *abfd ATTRIBUTE_UNUSED)
+{
+ BFD_ASSERT (0);
+ return NULL;
+}
+
+static int
+bfd_plugin_core_file_failing_signal (bfd *abfd ATTRIBUTE_UNUSED)
+{
+ BFD_ASSERT (0);
+ return 0;
+}
+
+static int
+bfd_plugin_core_file_pid (bfd *abfd ATTRIBUTE_UNUSED)
+{
+ BFD_ASSERT (0);
+ return 0;
+}
+
+static long
+bfd_plugin_get_symtab_upper_bound (bfd *abfd)
+{
+ struct plugin_data_struct *plugin_data = abfd->tdata.plugin_data;
+ long nsyms = plugin_data->nsyms;
+
+ BFD_ASSERT (nsyms >= 0);
+
+ return ((nsyms + 1) * sizeof (asymbol *));
+}
+
+static flagword
+convert_flags (const struct ld_plugin_symbol *sym)
+{
+ switch (sym->def)
+ {
+ case LDPK_DEF:
+ case LDPK_COMMON:
+ case LDPK_UNDEF:
+ return BSF_GLOBAL;
+
+ case LDPK_WEAKUNDEF:
+ case LDPK_WEAKDEF:
+ return BSF_GLOBAL | BSF_WEAK;
+
+ default:
+ BFD_ASSERT (0);
+ return 0;
+ }
+}
+
+static long
+bfd_plugin_canonicalize_symtab (bfd *abfd,
+ asymbol **alocation)
+{
+ struct plugin_data_struct *plugin_data = abfd->tdata.plugin_data;
+ long nsyms = plugin_data->nsyms;
+ const struct ld_plugin_symbol *syms = plugin_data->syms;
+ static asection fake_section;
+ static asection fake_common_section;
+ int i;
+
+ fake_section.name = ".text";
+ fake_common_section.flags = SEC_IS_COMMON;
+
+ for (i = 0; i < nsyms; i++)
+ {
+ asymbol *s = bfd_alloc (abfd, sizeof (asymbol));
+
+ BFD_ASSERT (s);
+ alocation[i] = s;
+
+ s->the_bfd = abfd;
+ s->name = syms[i].name;
+ s->value = 0;
+ s->flags = convert_flags (&syms[i]);
+ switch (syms[i].def)
+ {
+ case LDPK_COMMON:
+ s->section = &fake_common_section;
+ break;
+ case LDPK_UNDEF:
+ case LDPK_WEAKUNDEF:
+ s->section = bfd_und_section_ptr;
+ break;
+ case LDPK_DEF:
+ case LDPK_WEAKDEF:
+ s->section = &fake_section;
+ break;
+ default:
+ BFD_ASSERT (0);
+ }
+
+ s->udata.p = (void *) &syms[i];
+ }
+
+ return nsyms;
+}
+
+static void
+bfd_plugin_print_symbol (bfd *abfd ATTRIBUTE_UNUSED,
+ PTR afile ATTRIBUTE_UNUSED,
+ asymbol *symbol ATTRIBUTE_UNUSED,
+ bfd_print_symbol_type how ATTRIBUTE_UNUSED)
+{
+ BFD_ASSERT (0);
+}
+
+static void
+bfd_plugin_get_symbol_info (bfd *abfd ATTRIBUTE_UNUSED,
+ asymbol *symbol,
+ symbol_info *ret)
+{
+ bfd_symbol_info (symbol, ret);
+}
+
+/* Make an empty symbol. */
+
+static asymbol *
+bfd_plugin_make_empty_symbol (bfd *abfd)
+{
+ asymbol *new_symbol = bfd_zalloc (abfd, sizeof (asymbol));
+ if (new_symbol == NULL)
+ return new_symbol;
+ new_symbol->the_bfd = abfd;
+ return new_symbol;
+}
+
+static int
+bfd_plugin_sizeof_headers (bfd *a ATTRIBUTE_UNUSED,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED)
+{
+ BFD_ASSERT (0);
+ return 0;
+}
+
+const bfd_target plugin_vec =
+{
+ "plugin", /* Name. */
+ 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 | DYNAMIC | WP_TEXT | D_PAGED),
+ (SEC_CODE | SEC_DATA | SEC_ROM | SEC_HAS_CONTENTS
+ | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* Section flags. */
+ 0, /* symbol_leading_char. */
+ '/', /* ar_pad_char. */
+ 15, /* ar_max_namelen. */
+ 0, /* match priority. */
+
+ 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_check_format. */
+ _bfd_dummy_target,
+ bfd_plugin_object_p,
+ bfd_generic_archive_p,
+ _bfd_dummy_target
+ },
+ { /* bfd_set_format. */
+ bfd_false,
+ bfd_false,
+ _bfd_generic_mkarchive,
+ bfd_false,
+ },
+ { /* bfd_write_contents. */
+ bfd_false,
+ bfd_false,
+ _bfd_write_archive_contents,
+ bfd_false,
+ },
+
+ BFD_JUMP_TABLE_GENERIC (bfd_plugin),
+ BFD_JUMP_TABLE_COPY (bfd_plugin),
+ BFD_JUMP_TABLE_CORE (bfd_plugin),
+ BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),
+ BFD_JUMP_TABLE_SYMBOLS (bfd_plugin),
+ BFD_JUMP_TABLE_RELOCS (_bfd_norelocs),
+ BFD_JUMP_TABLE_WRITE (bfd_plugin),
+ BFD_JUMP_TABLE_LINK (bfd_plugin),
+ BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
+
+ NULL,
+
+ NULL /* backend_data. */
+};
+#endif /* BFD_SUPPORTS_PLUGIN */
diff --git a/bfd/plugin.h b/bfd/plugin.h
new file mode 100644
index 0000000..4f1d18b
--- /dev/null
+++ b/bfd/plugin.h
@@ -0,0 +1,36 @@
+/* Plugin support for BFD.
+ Copyright (C) 2009-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#ifndef _PLUGIN_H_
+#define _PLUGIN_H_
+
+#include "bfd.h"
+
+void bfd_plugin_set_program_name (const char *);
+void bfd_plugin_set_plugin (const char *);
+
+typedef struct plugin_data_struct
+{
+ int nsyms;
+ const struct ld_plugin_symbol *syms;
+}
+plugin_data_struct;
+
+#endif
diff --git a/bfd/po/BLD-POTFILES.in b/bfd/po/BLD-POTFILES.in
new file mode 100644
index 0000000..b86829c
--- /dev/null
+++ b/bfd/po/BLD-POTFILES.in
@@ -0,0 +1,12 @@
+bfd_stdint.h
+bfdver.h
+elf32-aarch64.c
+elf32-ia64.c
+elf32-target.h
+elf64-aarch64.c
+elf64-ia64.c
+elf64-target.h
+peigen.c
+pepigen.c
+pex64igen.c
+targmatch.h
diff --git a/bfd/po/Make-in b/bfd/po/Make-in
new file mode 100644
index 0000000..c40a243
--- /dev/null
+++ b/bfd/po/Make-in
@@ -0,0 +1,298 @@
+# Makefile for program source directory in GNU NLS utilities package.
+# Copyright (C) 1995, 1996, 1997 by Ulrich Drepper <drepper@gnu.ai.mit.edu>
+# Copyright (C) 2001-2014 Free Software Foundation, Inc.
+#
+# This file may 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@
+top_builddir = @top_builddir@
+
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+datadir = $(prefix)/@DATADIRNAME@
+localedir = $(datadir)/locale
+gnulocaledir = $(prefix)/share/locale
+gettextsrcdir = $(prefix)/share/gettext/po
+subdir = po
+
+DESTDIR =
+
+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 SRC-POTFILES.in BLD-POTFILES.in $(PACKAGE).pot \
+stamp-cat-id $(POFILES) $(GMOFILES) $(SOURCES)
+
+# Note - the following line gets processed by bfd/configure and amended
+# to contain the full list of source dir POTFILES.
+SRC-POTFILES = \
+
+# Note - the following line gets processed by bfd/configure and amended
+# to contain the full list of build dir POTFILES.
+BLD-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=`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: $(SRC-POTFILES) $(BLD-POTFILES)
+ $(XGETTEXT) --default-domain=$(PACKAGE) \
+ --directory=$(top_srcdir) \
+ --add-comments --keyword=_ --keyword=N_ \
+ --msgid-bugs-address=bug-binutils@gnu.org \
+ --files-from=$(srcdir)/SRC-POTFILES.in
+ $(XGETTEXT) --default-domain=$(PACKAGE) \
+ --directory=.. \
+ --directory=. \
+ --add-comments --keyword=_ --keyword=N_ \
+ --join-existing \
+ --msgid-bugs-address=bug-binutils@gnu.org \
+ --files-from=$(srcdir)/BLD-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-html:
+install-pdf:
+install-data: install-data-@USE_NLS@
+install-data-no: all
+install-data-yes: all
+ if test -r $(MKINSTALLDIRS); then \
+ $(MKINSTALLDIRS) $(DESTDIR)$(datadir); \
+ else \
+ $(top_srcdir)/mkinstalldirs $(DESTDIR)$(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)$$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) $(DESTDIR)$(gettextsrcdir); \
+ else \
+ $(top_srcdir)/mkinstalldirs $(DESTDIR)$(gettextsrcdir); \
+ fi; \
+ $(INSTALL_DATA) $(srcdir)/Makefile.in.in \
+ $(DESTDIR)$(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 $(DESTDIR)$(localedir)/$$lang/LC_MESSAGES/$(PACKAGE)$(INSTOBJEXT); \
+ rm -f $(DESTDIR)$(localedir)/$$lang/LC_MESSAGES/$(PACKAGE)$(INSTOBJEXT).m; \
+ rm -f $(DESTDIR)$(gnulocaledir)/$$lang/LC_MESSAGES/$(PACKAGE)$(INSTOBJEXT); \
+ rm -f $(DESTDIR)$(gnulocaledir)/$$lang/LC_MESSAGES/$(PACKAGE)$(INSTOBJEXT).m; \
+ done
+ rm -f $(DESTDIR)$(gettextsrcdir)/po-Makefile.in.in
+
+check: all
+
+cat-id-tbl.o: ../intl/libgettext.h
+
+html dvi pdf ps 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 *.mo *.msg *.cat *.cat.m
+ rm -f SRC-POTFILES BLD-POTFILES
+
+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) SRC-POTFILES.in BLD-POTFILES.in
+
+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
+
+SRC-POTFILES: SRC-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 $@ )
+
+BLD-POTFILES: BLD-POTFILES.in
+ ( rm -f $@-t $@ \
+ && (sed -e '/^#/d' \
+ -e '/^[ ]*$$/d' \
+ -e "s@.*@ ../& \\\\@" < $(srcdir)/$@.in \
+ | sed -e '$$s/\\$$//') > $@-t \
+ && chmod a-w $@-t \
+ && mv $@-t $@ )
+
+SRC-POTFILES.in: @MAINT@ ../Makefile
+ cd .. && $(MAKE) po/SRC-POTFILES.in
+
+BLD-POTFILES.in: @MAINT@ ../Makefile
+ cd .. && $(MAKE) po/BLD-POTFILES.in
+
+# Note - The presence of SRC-POTFILES and BLD-POTFILES as dependencies
+# here breaks the implementation of the 'distclean' rule for maintainers.
+# This is because if 'make distclean' is run in the BFD directory, the
+# Makefile there will be deleted before 'distclean' is made here, and so
+# the dependency SRC-POTFILES -> SRC-POTFILES.in -> ../Makefile cannot
+# be satisfied.
+#
+# The SRC-POTFILES and BLD-POTFILES dependencies cannot be removed,
+# however since it is necessary that these files be built during
+# *configure* time, so that configure can insert them into the
+# po/Makefile that it is creating, so that the Makefile will have
+# the correct dependencies.
+Makefile: Make-in ../config.status SRC-POTFILES BLD-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/SRC-POTFILES.in b/bfd/po/SRC-POTFILES.in
new file mode 100644
index 0000000..3e5cbd0
--- /dev/null
+++ b/bfd/po/SRC-POTFILES.in
@@ -0,0 +1,378 @@
+aix386-core.c
+aix5ppc-core.c
+aout-adobe.c
+aout-arm.c
+aout-cris.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
+archive64.c
+archures.c
+armnetbsd.c
+bfd.c
+bfdio.c
+bfdwin.c
+binary.c
+bout.c
+cache.c
+cf-i386lynx.c
+cf-sparclynx.c
+cisco-core.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-mips.c
+coff-rs6000.c
+coff-sh.c
+coff-sparc.c
+coff-stgo32.c
+coff-svm68k.c
+coff-tic30.c
+coff-tic4x.c
+coff-tic54x.c
+coff-tic80.c
+coff-u68k.c
+coff-w65.c
+coff-we32k.c
+coff-x86_64.c
+coff-z80.c
+coff-z8k.c
+coff64-rs6000.c
+coffcode.h
+coffgen.c
+cofflink.c
+coffswap.h
+compress.c
+corefile.c
+cpu-aarch64.c
+cpu-alpha.c
+cpu-arc.c
+cpu-arm.c
+cpu-avr.c
+cpu-bfin.c
+cpu-cr16.c
+cpu-cr16c.c
+cpu-cris.c
+cpu-crx.c
+cpu-d10v.c
+cpu-d30v.c
+cpu-dlx.c
+cpu-epiphany.c
+cpu-fr30.c
+cpu-frv.c
+cpu-h8300.c
+cpu-h8500.c
+cpu-hppa.c
+cpu-i370.c
+cpu-i386.c
+cpu-i860.c
+cpu-i960.c
+cpu-ia64.c
+cpu-ip2k.c
+cpu-iq2000.c
+cpu-k1om.c
+cpu-l1om.c
+cpu-lm32.c
+cpu-m10200.c
+cpu-m10300.c
+cpu-m32c.c
+cpu-m32r.c
+cpu-m68hc11.c
+cpu-m68hc12.c
+cpu-m68k.c
+cpu-m88k.c
+cpu-m9s12x.c
+cpu-m9s12xg.c
+cpu-mcore.c
+cpu-mep.c
+cpu-metag.c
+cpu-microblaze.c
+cpu-mips.c
+cpu-mmix.c
+cpu-moxie.c
+cpu-msp430.c
+cpu-mt.c
+cpu-nds32.c
+cpu-nios2.c
+cpu-ns32k.c
+cpu-or1k.c
+cpu-pdp11.c
+cpu-pj.c
+cpu-plugin.c
+cpu-powerpc.c
+cpu-rl78.c
+cpu-rs6000.c
+cpu-rx.c
+cpu-s390.c
+cpu-score.c
+cpu-sh.c
+cpu-sparc.c
+cpu-spu.c
+cpu-tic30.c
+cpu-tic4x.c
+cpu-tic54x.c
+cpu-tic6x.c
+cpu-tic80.c
+cpu-tilegx.c
+cpu-tilepro.c
+cpu-v850.c
+cpu-v850_rh850.c
+cpu-vax.c
+cpu-w65.c
+cpu-we32k.c
+cpu-xc16x.c
+cpu-xgate.c
+cpu-xstormy16.c
+cpu-xtensa.c
+cpu-z80.c
+cpu-z8k.c
+demo64.c
+dwarf1.c
+dwarf2.c
+ecoff.c
+ecofflink.c
+ecoffswap.h
+elf-attrs.c
+elf-bfd.h
+elf-eh-frame.c
+elf-hppa.h
+elf-ifunc.c
+elf-linux-psinfo.h
+elf-m10200.c
+elf-m10300.c
+elf-nacl.c
+elf-strtab.c
+elf-vxworks.c
+elf.c
+elf32-am33lin.c
+elf32-arc.c
+elf32-arm.c
+elf32-avr.c
+elf32-bfin.c
+elf32-cr16.c
+elf32-cr16c.c
+elf32-cris.c
+elf32-crx.c
+elf32-d10v.c
+elf32-d30v.c
+elf32-dlx.c
+elf32-epiphany.c
+elf32-fr30.c
+elf32-frv.c
+elf32-gen.c
+elf32-h8300.c
+elf32-hppa.c
+elf32-hppa.h
+elf32-i370.c
+elf32-i386.c
+elf32-i860.c
+elf32-i960.c
+elf32-ip2k.c
+elf32-iq2000.c
+elf32-lm32.c
+elf32-m32c.c
+elf32-m32r.c
+elf32-m68hc11.c
+elf32-m68hc12.c
+elf32-m68hc1x.c
+elf32-m68k.c
+elf32-m88k.c
+elf32-mcore.c
+elf32-mep.c
+elf32-metag.c
+elf32-microblaze.c
+elf32-mips.c
+elf32-moxie.c
+elf32-msp430.c
+elf32-mt.c
+elf32-nds32.c
+elf32-nios2.c
+elf32-or1k.c
+elf32-pj.c
+elf32-ppc.c
+elf32-rl78.c
+elf32-rx.c
+elf32-s390.c
+elf32-score.c
+elf32-score7.c
+elf32-sh-symbian.c
+elf32-sh.c
+elf32-sh64-com.c
+elf32-sh64.c
+elf32-sparc.c
+elf32-spu.c
+elf32-tic6x.c
+elf32-tilegx.c
+elf32-tilepro.c
+elf32-v850.c
+elf32-vax.c
+elf32-xc16x.c
+elf32-xgate.c
+elf32-xstormy16.c
+elf32-xtensa.c
+elf32.c
+elf64-alpha.c
+elf64-gen.c
+elf64-hppa.c
+elf64-hppa.h
+elf64-ia64-vms.c
+elf64-mips.c
+elf64-mmix.c
+elf64-ppc.c
+elf64-s390.c
+elf64-sh64.c
+elf64-sparc.c
+elf64-tilegx.c
+elf64-x86-64.c
+elf64.c
+elfcode.h
+elfcore.h
+elflink.c
+elfn32-mips.c
+elfxx-aarch64.c
+elfxx-ia64.c
+elfxx-mips.c
+elfxx-sparc.c
+elfxx-tilegx.c
+epoc-pe-arm.c
+epoc-pei-arm.c
+format.c
+freebsd.h
+genlink.h
+go32stub.h
+hash.c
+hp300bsd.c
+hp300hpux.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.c
+libbfd.h
+libcoff.h
+libecoff.h
+libhppa.h
+libieee.h
+libnlm.h
+liboasys.h
+libpei.h
+libxcoff.h
+linker.c
+lynx-core.c
+m68k4knetbsd.c
+m68klinux.c
+m68knetbsd.c
+m88kmach3.c
+m88kopenbsd.c
+mach-o-i386.c
+mach-o-x86-64.c
+mach-o.c
+mach-o.h
+merge.c
+mipsbsd.c
+mmo.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
+pdp11.c
+pe-arm-wince.c
+pe-arm.c
+pe-i386.c
+pe-mcore.c
+pe-mips.c
+pe-ppc.c
+pe-sh.c
+pe-x86_64.c
+pef-traceback.h
+pef.c
+pef.h
+pei-arm-wince.c
+pei-arm.c
+pei-i386.c
+pei-ia64.c
+pei-mcore.c
+pei-mips.c
+pei-ppc.c
+pei-sh.c
+pei-x86_64.c
+peicode.h
+plugin.c
+ppcboot.c
+reloc.c
+reloc16.c
+riscix.c
+rs6000-core.c
+sco5-core.c
+section.c
+simple.c
+som.c
+som.h
+sparclinux.c
+sparclynx.c
+sparcnetbsd.c
+srec.c
+stab-syms.c
+stabs.c
+sunos.c
+syms.c
+targets.c
+tekhex.c
+trad-core.c
+vax1knetbsd.c
+vaxbsd.c
+vaxnetbsd.c
+verilog.c
+versados.c
+version.h
+vms-alpha.c
+vms-lib.c
+vms-misc.c
+vms.h
+xcofflink.c
+xsym.c
+xsym.h
+xtensa-isa.c
+xtensa-modules.c
diff --git a/bfd/po/bfd.pot b/bfd/po/bfd.pot
new file mode 100644
index 0000000..f2ae349
--- /dev/null
+++ b/bfd/po/bfd.pot
@@ -0,0 +1,6710 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"Report-Msgid-Bugs-To: bug-binutils@gnu.org\n"
+"POT-Creation-Date: 2014-02-10 09:42+1030\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"
+"Language: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=CHARSET\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: aout-adobe.c:127
+msgid "%B: Unknown section type in a.out.adobe file: %x\n"
+msgstr ""
+
+#: aout-cris.c:200
+#, c-format
+msgid "%s: Invalid relocation type exported: %d"
+msgstr ""
+
+#: aout-cris.c:243
+msgid "%B: Invalid relocation type imported: %d"
+msgstr ""
+
+#: aout-cris.c:254
+msgid "%B: Bad relocation record imported: %d"
+msgstr ""
+
+#: aoutx.h:1273 aoutx.h:1611
+#, c-format
+msgid "%s: can not represent section `%s' in a.out object file format"
+msgstr ""
+
+#: aoutx.h:1577
+#, c-format
+msgid ""
+"%s: can not represent section for symbol `%s' in a.out object file format"
+msgstr ""
+
+#: aoutx.h:1579 vms-alpha.c:7564
+msgid "*unknown*"
+msgstr ""
+
+#: aoutx.h:4018 aoutx.h:4344
+msgid "%P: %B: unexpected relocation type\n"
+msgstr ""
+
+#: aoutx.h:5375
+#, c-format
+msgid "%s: relocatable link from %s to %s not supported"
+msgstr ""
+
+#: archive.c:2249
+msgid "Warning: writing archive was slow: rewriting timestamp\n"
+msgstr ""
+
+#: archive.c:2549
+msgid "Reading archive file mod timestamp"
+msgstr ""
+
+#: archive.c:2573
+msgid "Writing updated armap timestamp"
+msgstr ""
+
+#: bfd.c:411
+msgid "No error"
+msgstr ""
+
+#: bfd.c:412
+msgid "System call error"
+msgstr ""
+
+#: bfd.c:413
+msgid "Invalid bfd target"
+msgstr ""
+
+#: bfd.c:414
+msgid "File in wrong format"
+msgstr ""
+
+#: bfd.c:415
+msgid "Archive object file in wrong format"
+msgstr ""
+
+#: bfd.c:416
+msgid "Invalid operation"
+msgstr ""
+
+#: bfd.c:417
+msgid "Memory exhausted"
+msgstr ""
+
+#: bfd.c:418
+msgid "No symbols"
+msgstr ""
+
+#: bfd.c:419
+msgid "Archive has no index; run ranlib to add one"
+msgstr ""
+
+#: bfd.c:420
+msgid "No more archived files"
+msgstr ""
+
+#: bfd.c:421
+msgid "Malformed archive"
+msgstr ""
+
+#: bfd.c:422
+msgid "DSO missing from command line"
+msgstr ""
+
+#: bfd.c:423
+msgid "File format not recognized"
+msgstr ""
+
+#: bfd.c:424
+msgid "File format is ambiguous"
+msgstr ""
+
+#: bfd.c:425
+msgid "Section has no contents"
+msgstr ""
+
+#: bfd.c:426
+msgid "Nonrepresentable section on output"
+msgstr ""
+
+#: bfd.c:427
+msgid "Symbol needs debug section which does not exist"
+msgstr ""
+
+#: bfd.c:428
+msgid "Bad value"
+msgstr ""
+
+#: bfd.c:429
+msgid "File truncated"
+msgstr ""
+
+#: bfd.c:430
+msgid "File too big"
+msgstr ""
+
+#: bfd.c:431
+#, c-format
+msgid "Error reading %s: %s"
+msgstr ""
+
+#: bfd.c:432
+msgid "#<Invalid error code>"
+msgstr ""
+
+#: bfd.c:1046
+#, c-format
+msgid "BFD %s assertion fail %s:%d"
+msgstr ""
+
+#: bfd.c:1058
+#, c-format
+msgid "BFD %s internal error, aborting at %s line %d in %s\n"
+msgstr ""
+
+#: bfd.c:1062
+#, c-format
+msgid "BFD %s internal error, aborting at %s line %d\n"
+msgstr ""
+
+#: bfd.c:1064
+msgid "Please report this bug.\n"
+msgstr ""
+
+#: bfdwin.c:206
+#, c-format
+msgid "not mapping: data=%lx mapped=%d\n"
+msgstr ""
+
+#: bfdwin.c:209
+#, c-format
+msgid "not mapping: env var not set\n"
+msgstr ""
+
+#: binary.c:271
+#, c-format
+msgid "Warning: Writing section `%s' to huge (ie negative) file offset 0x%lx."
+msgstr ""
+
+#: bout.c:1146 elf-m10300.c:2665 elf32-avr.c:1706 elf32-frv.c:5641
+#: elf64-ia64-vms.c:354 elfxx-sparc.c:2869 reloc.c:7324 reloc16.c:160
+#: elf32-ia64.c:351 elf64-ia64.c:351
+msgid "%P%F: --relax and -r may not be used together\n"
+msgstr ""
+
+#: cache.c:253
+msgid "reopening %B: %s\n"
+msgstr ""
+
+#: coff-alpha.c:452
+msgid ""
+"%B: Cannot handle compressed Alpha binaries.\n"
+" Use compiler flags, or objZ, to generate uncompressed binaries."
+msgstr ""
+
+#: coff-alpha.c:603
+msgid "%B: unknown/unsupported relocation type %d"
+msgstr ""
+
+#: coff-alpha.c:852 coff-alpha.c:889 coff-alpha.c:1973 coff-mips.c:946
+msgid "GP relative relocation used when GP not defined"
+msgstr ""
+
+#: coff-alpha.c:1450
+msgid "using multiple gp values"
+msgstr ""
+
+#: coff-alpha.c:1509
+msgid "%B: unsupported relocation: ALPHA_R_GPRELHIGH"
+msgstr ""
+
+#: coff-alpha.c:1516
+msgid "%B: unsupported relocation: ALPHA_R_GPRELLOW"
+msgstr ""
+
+#: coff-alpha.c:1523 elf32-m32r.c:2443 elf64-alpha.c:4083 elf64-alpha.c:4233
+#: elf64-ia64-vms.c:3429 elf32-ia64.c:3836 elf64-ia64.c:3836
+msgid "%B: unknown relocation type %d"
+msgstr ""
+
+#: coff-arm.c:1034
+#, c-format
+msgid "%B: unable to find THUMB glue '%s' for `%s'"
+msgstr ""
+
+#: coff-arm.c:1063
+#, c-format
+msgid "%B: unable to find ARM glue '%s' for `%s'"
+msgstr ""
+
+#: coff-arm.c:1365 elf32-arm.c:7141
+#, c-format
+msgid ""
+"%B(%s): warning: interworking not enabled.\n"
+" first occurrence: %B: arm call to thumb"
+msgstr ""
+
+#: coff-arm.c:1455
+#, c-format
+msgid ""
+"%B(%s): warning: interworking not enabled.\n"
+" first occurrence: %B: thumb call to arm\n"
+" consider relinking with --support-old-code enabled"
+msgstr ""
+
+#: coff-arm.c:1750 coff-tic80.c:673 cofflink.c:3168
+msgid "%B: bad reloc address 0x%lx in section `%A'"
+msgstr ""
+
+#: coff-arm.c:2075
+msgid "%B: illegal symbol index in reloc: %d"
+msgstr ""
+
+#: coff-arm.c:2206
+#, c-format
+msgid "error: %B is compiled for APCS-%d, whereas %B is compiled for APCS-%d"
+msgstr ""
+
+#: coff-arm.c:2222 elf32-arm.c:16123
+#, c-format
+msgid ""
+"error: %B passes floats in float registers, whereas %B passes them in "
+"integer registers"
+msgstr ""
+
+#: coff-arm.c:2225 elf32-arm.c:16127
+#, c-format
+msgid ""
+"error: %B passes floats in integer registers, whereas %B passes them in "
+"float registers"
+msgstr ""
+
+#: coff-arm.c:2239
+#, c-format
+msgid ""
+"error: %B is compiled as position independent code, whereas target %B is "
+"absolute position"
+msgstr ""
+
+#: coff-arm.c:2242
+#, c-format
+msgid ""
+"error: %B is compiled as absolute position code, whereas target %B is "
+"position independent"
+msgstr ""
+
+#: coff-arm.c:2270 elf32-arm.c:16192
+#, c-format
+msgid "Warning: %B supports interworking, whereas %B does not"
+msgstr ""
+
+#: coff-arm.c:2273 elf32-arm.c:16198
+#, c-format
+msgid "Warning: %B does not support interworking, whereas %B does"
+msgstr ""
+
+#: coff-arm.c:2297
+#, c-format
+msgid "private flags = %x:"
+msgstr ""
+
+#: coff-arm.c:2305 elf32-arm.c:12119
+#, c-format
+msgid " [floats passed in float registers]"
+msgstr ""
+
+#: coff-arm.c:2307
+#, c-format
+msgid " [floats passed in integer registers]"
+msgstr ""
+
+#: coff-arm.c:2310 elf32-arm.c:12122
+#, c-format
+msgid " [position independent]"
+msgstr ""
+
+#: coff-arm.c:2312
+#, c-format
+msgid " [absolute position]"
+msgstr ""
+
+#: coff-arm.c:2316
+#, c-format
+msgid " [interworking flag not initialised]"
+msgstr ""
+
+#: coff-arm.c:2318
+#, c-format
+msgid " [interworking supported]"
+msgstr ""
+
+#: coff-arm.c:2320
+#, c-format
+msgid " [interworking not supported]"
+msgstr ""
+
+#: coff-arm.c:2366 elf32-arm.c:11104
+#, c-format
+msgid ""
+"Warning: Not setting interworking flag of %B since it has already been "
+"specified as non-interworking"
+msgstr ""
+
+#: coff-arm.c:2370 elf32-arm.c:11108
+#, c-format
+msgid "Warning: Clearing the interworking flag of %B due to outside request"
+msgstr ""
+
+#: coff-h8300.c:1096
+#, c-format
+msgid "cannot handle R_MEM_INDIRECT reloc when using %s output"
+msgstr ""
+
+#: coff-i860.c:147
+#, c-format
+msgid "relocation `%s' not yet implemented"
+msgstr ""
+
+#: coff-i860.c:605 coff-tic54x.c:365 coffcode.h:5209
+msgid "%B: warning: illegal symbol index %ld in relocs"
+msgstr ""
+
+#: coff-i960.c:124 coff-i960.c:480
+msgid "uncertain calling convention for non-COFF symbol"
+msgstr ""
+
+#: coff-m68k.c:484 elf32-bfin.c:5556 elf32-cr16.c:2853 elf32-m68k.c:4632
+msgid "unsupported reloc type"
+msgstr ""
+
+#: coff-mips.c:636 elf32-mips.c:1637 elf32-score.c:431 elf32-score7.c:330
+#: elf64-mips.c:2925 elfn32-mips.c:2737
+msgid "GP relative relocation when _gp not defined"
+msgstr ""
+
+#: coff-or32.c:216
+msgid "Unrecognized reloc"
+msgstr ""
+
+#: coff-rs6000.c:2802
+#, c-format
+msgid "%s: unsupported relocation type 0x%02x"
+msgstr ""
+
+#: coff-rs6000.c:2887
+#, c-format
+msgid "%s: TOC reloc at 0x%x to symbol `%s' with no TOC entry"
+msgstr ""
+
+#: coff-rs6000.c:3638 coff64-rs6000.c:2117
+msgid "%B: symbol `%s' has unrecognized smclas %d"
+msgstr ""
+
+#: coff-sh.c:506
+#, c-format
+msgid "SH Error: unknown reloc type %d"
+msgstr ""
+
+#: coff-tic4x.c:184 coff-tic54x.c:279 coff-tic80.c:440
+#, c-format
+msgid "Unrecognized reloc type 0x%x"
+msgstr ""
+
+#: coff-tic4x.c:227
+#, c-format
+msgid "%s: warning: illegal symbol index %ld in relocs"
+msgstr ""
+
+#: coff-w65.c:355
+#, c-format
+msgid "ignoring reloc %s\n"
+msgstr ""
+
+#: coffcode.h:1005
+msgid "%B: warning: COMDAT symbol '%s' does not match section name '%s'"
+msgstr ""
+
+#. Generate a warning message rather using the 'unhandled'
+#. variable as this will allow some .sys files generate by
+#. other toolchains to be processed. See bugzilla issue 196.
+#: coffcode.h:1230
+msgid ""
+"%B: Warning: Ignoring section flag IMAGE_SCN_MEM_NOT_PAGED in section %s"
+msgstr ""
+
+#: coffcode.h:1297
+msgid "%B (%s): Section flag %s (0x%x) ignored"
+msgstr ""
+
+#: coffcode.h:2439
+#, c-format
+msgid "Unrecognized TI COFF target id '0x%x'"
+msgstr ""
+
+#: coffcode.h:2753
+msgid "%B: reloc against a non-existant symbol index: %ld"
+msgstr ""
+
+#: coffcode.h:3311
+msgid "%B: too many sections (%d)"
+msgstr ""
+
+#: coffcode.h:3729
+msgid "%B: section %s: string table overflow at offset %ld"
+msgstr ""
+
+#: coffcode.h:4534
+msgid "%B: warning: line number table read failed"
+msgstr ""
+
+#: coffcode.h:4564
+msgid "%B: warning: illegal symbol index %ld in line numbers"
+msgstr ""
+
+#: coffcode.h:4578
+msgid "%B: warning: duplicate line number information for `%s'"
+msgstr ""
+
+#: coffcode.h:4978
+msgid "%B: Unrecognized storage class %d for %s symbol `%s'"
+msgstr ""
+
+#: coffcode.h:5104
+msgid "warning: %B: local symbol `%s' has no section"
+msgstr ""
+
+#: coffcode.h:5248
+msgid "%B: illegal relocation type %d at address 0x%lx"
+msgstr ""
+
+#: coffgen.c:179 elf.c:1030
+msgid "%B: unable to initialize compress status for section %s"
+msgstr ""
+
+#: coffgen.c:199 elf.c:1050
+msgid "%B: unable to initialize decompress status for section %s"
+msgstr ""
+
+#: coffgen.c:1685
+msgid "%B: bad string table size %lu"
+msgstr ""
+
+#: coffgen.c:2608 elflink.c:12906 linker.c:3136
+msgid "%F%P: already_linked_table: %E\n"
+msgstr ""
+
+#: cofflink.c:533 elf64-ia64-vms.c:5173 elflink.c:4356
+msgid "Warning: type of symbol `%s' changed from %d to %d in %B"
+msgstr ""
+
+#: cofflink.c:2416
+msgid "%B: relocs in section `%A', but it has no contents"
+msgstr ""
+
+#: cofflink.c:2478 elflink.c:9711
+msgid ""
+"%X`%s' referenced in section `%A' of %B: defined in discarded section `%A' "
+"of %B\n"
+msgstr ""
+
+#: cofflink.c:2777 coffswap.h:826
+#, c-format
+msgid "%s: %s: reloc overflow: 0x%lx > 0xffff"
+msgstr ""
+
+#: cofflink.c:2786 coffswap.h:812
+#, c-format
+msgid "%s: warning: %s: line number overflow: 0x%lx > 0xffff"
+msgstr ""
+
+#: cpu-arm.c:190 cpu-arm.c:201
+msgid "error: %B is compiled for the EP9312, whereas %B is compiled for XScale"
+msgstr ""
+
+#: cpu-arm.c:334
+#, c-format
+msgid "warning: unable to update contents of %s section in %s"
+msgstr ""
+
+#: dwarf2.c:514
+#, c-format
+msgid "Dwarf Error: Can't find %s section."
+msgstr ""
+
+#: dwarf2.c:543
+#, c-format
+msgid "Dwarf Error: Offset (%lu) greater than or equal to %s size (%lu)."
+msgstr ""
+
+#: dwarf2.c:1071
+#, c-format
+msgid "Dwarf Error: Invalid or unhandled FORM value: %#x."
+msgstr ""
+
+#: dwarf2.c:1332
+msgid "Dwarf Error: mangled line number section (bad file number)."
+msgstr ""
+
+#: dwarf2.c:1590
+#, c-format
+msgid "Dwarf Error: Unhandled .debug_line version %d."
+msgstr ""
+
+#: dwarf2.c:1612
+msgid "Dwarf Error: Invalid maximum operations per instruction."
+msgstr ""
+
+#: dwarf2.c:1807
+msgid "Dwarf Error: mangled line number section."
+msgstr ""
+
+#: dwarf2.c:2160
+#, c-format
+msgid "Dwarf Error: Unable to read alt ref %u."
+msgstr ""
+
+#: dwarf2.c:2179 dwarf2.c:2299 dwarf2.c:2595
+#, c-format
+msgid "Dwarf Error: Could not find abbrev number %u."
+msgstr ""
+
+#: dwarf2.c:2551
+#, c-format
+msgid ""
+"Dwarf Error: found dwarf version '%u', this reader only handles version 2, 3 "
+"and 4 information."
+msgstr ""
+
+#: dwarf2.c:2560
+#, c-format
+msgid ""
+"Dwarf Error: found address size '%u', this reader can not handle sizes "
+"greater than '%u'."
+msgstr ""
+
+#: dwarf2.c:2586
+#, c-format
+msgid "Dwarf Error: Bad abbrev number: %u."
+msgstr ""
+
+#: ecoff.c:1233
+#, c-format
+msgid "Unknown basic type %d"
+msgstr ""
+
+#: ecoff.c:1490
+#, c-format
+msgid ""
+"\n"
+" End+1 symbol: %ld"
+msgstr ""
+
+#: ecoff.c:1497 ecoff.c:1500
+#, c-format
+msgid ""
+"\n"
+" First symbol: %ld"
+msgstr ""
+
+#: ecoff.c:1512
+#, c-format
+msgid ""
+"\n"
+" End+1 symbol: %-7ld Type: %s"
+msgstr ""
+
+#: ecoff.c:1519
+#, c-format
+msgid ""
+"\n"
+" Local symbol: %ld"
+msgstr ""
+
+#: ecoff.c:1527
+#, c-format
+msgid ""
+"\n"
+" struct; End+1 symbol: %ld"
+msgstr ""
+
+#: ecoff.c:1532
+#, c-format
+msgid ""
+"\n"
+" union; End+1 symbol: %ld"
+msgstr ""
+
+#: ecoff.c:1537
+#, c-format
+msgid ""
+"\n"
+" enum; End+1 symbol: %ld"
+msgstr ""
+
+#: ecoff.c:1543
+#, c-format
+msgid ""
+"\n"
+" Type: %s"
+msgstr ""
+
+#: elf-attrs.c:573
+msgid ""
+"error: %B: Object has vendor-specific contents that must be processed by the "
+"'%s' toolchain"
+msgstr ""
+
+#: elf-attrs.c:582
+msgid "error: %B: Object tag '%d, %s' is incompatible with tag '%d, %s'"
+msgstr ""
+
+#: elf-eh-frame.c:921
+msgid "%P: error in %B(%A); no .eh_frame_hdr table will be created.\n"
+msgstr ""
+
+#: elf-eh-frame.c:1193
+msgid ""
+"%P: fde encoding in %B(%A) prevents .eh_frame_hdr table being created.\n"
+msgstr ""
+
+#: elf-eh-frame.c:1612
+msgid "%P: DW_EH_PE_datarel unspecified for this architecture.\n"
+msgstr ""
+
+#: elf-ifunc.c:135
+msgid ""
+"%F%P: dynamic STT_GNU_IFUNC symbol `%s' with pointer equality in `%B' can "
+"not be used when making an executable; recompile with -fPIE and relink with -"
+"pie\n"
+msgstr ""
+
+#: elf-m10200.c:430 elf-m10300.c:2164 elf32-avr.c:1256 elf32-bfin.c:3220
+#: elf32-cr16.c:1484 elf32-cr16c.c:780 elf32-cris.c:2016 elf32-crx.c:922
+#: elf32-d10v.c:513 elf32-epiphany.c:557 elf32-fr30.c:589 elf32-frv.c:4039
+#: elf32-h8300.c:525 elf32-i860.c:1212 elf32-ip2k.c:1468 elf32-iq2000.c:688
+#: elf32-lm32.c:1160 elf32-m32c.c:553 elf32-m32r.c:3066 elf32-m68hc1x.c:1283
+#: elf32-mep.c:535 elf32-metag.c:1992 elf32-microblaze.c:1560
+#: elf32-moxie.c:282 elf32-mt.c:395 elf32-nds32.c:4910 elf32-openrisc.c:404
+#: elf32-score.c:2729 elf32-score7.c:2537 elf32-spu.c:5041
+#: elf32-tilepro.c:3666 elf32-v850.c:2281 elf32-xstormy16.c:936
+#: elf64-mmix.c:1538 elfxx-tilegx.c:4051
+msgid "internal error: out of range error"
+msgstr ""
+
+#: elf-m10200.c:434 elf-m10300.c:2168 elf32-avr.c:1260 elf32-bfin.c:3224
+#: elf32-cr16.c:1488 elf32-cr16c.c:784 elf32-cris.c:2020 elf32-crx.c:926
+#: elf32-d10v.c:517 elf32-fr30.c:593 elf32-frv.c:4043 elf32-h8300.c:529
+#: elf32-i860.c:1216 elf32-iq2000.c:692 elf32-lm32.c:1164 elf32-m32c.c:557
+#: elf32-m32r.c:3070 elf32-m68hc1x.c:1287 elf32-mep.c:539 elf32-metag.c:1996
+#: elf32-microblaze.c:1564 elf32-moxie.c:286 elf32-msp430.c:1321
+#: elf32-nds32.c:4914 elf32-openrisc.c:408 elf32-score.c:2733
+#: elf32-score7.c:2541 elf32-spu.c:5045 elf32-tilepro.c:3670 elf32-v850.c:2285
+#: elf32-xstormy16.c:940 elf64-mmix.c:1542 elfxx-mips.c:9995
+#: elfxx-tilegx.c:4055
+msgid "internal error: unsupported relocation error"
+msgstr ""
+
+#: elf-m10200.c:438 elf32-cr16.c:1492 elf32-cr16c.c:788 elf32-crx.c:930
+#: elf32-d10v.c:521 elf32-h8300.c:533 elf32-lm32.c:1168 elf32-m32r.c:3074
+#: elf32-m68hc1x.c:1291 elf32-microblaze.c:1568 elf32-nds32.c:4918
+#: elf32-score.c:2737 elf32-score7.c:2545 elf32-spu.c:5049
+msgid "internal error: dangerous error"
+msgstr ""
+
+#: elf-m10200.c:442 elf-m10300.c:2184 elf32-avr.c:1268 elf32-bfin.c:3232
+#: elf32-cr16.c:1496 elf32-cr16c.c:792 elf32-cris.c:2028 elf32-crx.c:934
+#: elf32-d10v.c:525 elf32-epiphany.c:572 elf32-fr30.c:601 elf32-frv.c:4051
+#: elf32-h8300.c:537 elf32-i860.c:1224 elf32-ip2k.c:1483 elf32-iq2000.c:700
+#: elf32-lm32.c:1172 elf32-m32c.c:565 elf32-m32r.c:3078 elf32-m68hc1x.c:1295
+#: elf32-mep.c:547 elf32-metag.c:2004 elf32-microblaze.c:1572
+#: elf32-moxie.c:294 elf32-msp430.c:1329 elf32-mt.c:403 elf32-nds32.c:4922
+#: elf32-openrisc.c:416 elf32-score.c:2746 elf32-score7.c:2549
+#: elf32-spu.c:5053 elf32-tilepro.c:3678 elf32-v850.c:2305
+#: elf32-xstormy16.c:948 elf64-mmix.c:1550 elfxx-tilegx.c:4063
+msgid "internal error: unknown error"
+msgstr ""
+
+#: elf-m10300.c:1021
+#, c-format
+msgid "%s: Unsupported transition from %s to %s"
+msgstr ""
+
+#: elf-m10300.c:1213
+msgid "%B: %s' accessed both as normal and thread local symbol"
+msgstr ""
+
+#: elf-m10300.c:2108 elf32-arm.c:10632 elf32-i386.c:4363 elf32-m32r.c:2558
+#: elf32-m68k.c:4120 elf32-s390.c:3303 elf32-sh.c:4109 elf32-tilepro.c:3569
+#: elf32-xtensa.c:3063 elf64-s390.c:3229 elf64-sh64.c:1640 elf64-x86-64.c:4463
+#: elfxx-sparc.c:3904 elfxx-tilegx.c:3974
+#: /src/binutils-gdb/bfd/elfnn-aarch64.c:4450
+msgid "%B(%A+0x%lx): unresolvable %s relocation against symbol `%s'"
+msgstr ""
+
+#: elf-m10300.c:2173
+msgid ""
+"error: inappropriate relocation type for shared library (did you forget -"
+"fpic?)"
+msgstr ""
+
+#: elf-m10300.c:2176
+msgid ""
+"%B: taking the address of protected function '%s' cannot be done when making "
+"a shared library"
+msgstr ""
+
+#: elf-m10300.c:2179
+msgid "internal error: suspicious relocation type used in shared library"
+msgstr ""
+
+#: elf.c:343
+msgid "%B: invalid string offset %u >= %lu for section `%s'"
+msgstr ""
+
+#: elf.c:455
+msgid "%B symbol number %lu references nonexistent SHT_SYMTAB_SHNDX section"
+msgstr ""
+
+#: elf.c:611
+msgid "%B: Corrupt size field in group section header: 0x%lx"
+msgstr ""
+
+#: elf.c:647
+msgid "%B: invalid SHT_GROUP entry"
+msgstr ""
+
+#: elf.c:717
+msgid "%B: no group info for section %A"
+msgstr ""
+
+#: elf.c:746 elf.c:3144 elflink.c:10290
+msgid "%B: warning: sh_link not set for section `%A'"
+msgstr ""
+
+#: elf.c:765
+msgid "%B: sh_link [%d] in section `%A' is incorrect"
+msgstr ""
+
+#: elf.c:800
+msgid "%B: unknown [%d] section `%s' in group [%s]"
+msgstr ""
+
+#: elf.c:1174
+#, c-format
+msgid ""
+"\n"
+"Program Header:\n"
+msgstr ""
+
+#: elf.c:1216
+#, c-format
+msgid ""
+"\n"
+"Dynamic Section:\n"
+msgstr ""
+
+#: elf.c:1352
+#, c-format
+msgid ""
+"\n"
+"Version definitions:\n"
+msgstr ""
+
+#: elf.c:1377
+#, c-format
+msgid ""
+"\n"
+"Version References:\n"
+msgstr ""
+
+#: elf.c:1382
+#, c-format
+msgid " required from %s:\n"
+msgstr ""
+
+#: elf.c:1807
+msgid "%B: invalid link %lu for reloc section %s (index %u)"
+msgstr ""
+
+#: elf.c:1977
+msgid ""
+"%B: don't know how to handle allocated, application specific section `%s' [0x"
+"%8x]"
+msgstr ""
+
+#: elf.c:1989
+msgid "%B: don't know how to handle processor specific section `%s' [0x%8x]"
+msgstr ""
+
+#: elf.c:2000
+msgid "%B: don't know how to handle OS specific section `%s' [0x%8x]"
+msgstr ""
+
+#: elf.c:2010
+msgid "%B: don't know how to handle section `%s' [0x%8x]"
+msgstr ""
+
+#: elf.c:2648
+#, c-format
+msgid "warning: section `%A' type changed to PROGBITS"
+msgstr ""
+
+#: elf.c:3015
+msgid "%B: too many sections: %u"
+msgstr ""
+
+#: elf.c:3101
+msgid "%B: sh_link of section `%A' points to discarded section `%A' of `%B'"
+msgstr ""
+
+#: elf.c:3124
+msgid "%B: sh_link of section `%A' points to removed section `%A' of `%B'"
+msgstr ""
+
+#: elf.c:4126
+msgid "%B: TLS sections are not adjacent:"
+msgstr ""
+
+#: elf.c:4133
+#, c-format
+msgid "\t TLS: %A"
+msgstr ""
+
+#: elf.c:4137
+#, c-format
+msgid "\tnon-TLS: %A"
+msgstr ""
+
+#: elf.c:4596
+msgid ""
+"%B: The first section in the PT_DYNAMIC segment is not the .dynamic section"
+msgstr ""
+
+#: elf.c:4621
+msgid "%B: Not enough room for program headers, try linking with -N"
+msgstr ""
+
+#: elf.c:4707
+msgid "%B: section %A lma %#lx adjusted to %#lx"
+msgstr ""
+
+#: elf.c:4843
+msgid "%B: section `%A' can't be allocated in segment %d"
+msgstr ""
+
+#: elf.c:4892
+msgid "%B: warning: allocated section `%s' not in segment"
+msgstr ""
+
+#: elf.c:5473
+msgid "%B: symbol `%s' required but not present"
+msgstr ""
+
+#: elf.c:5811
+msgid "%B: warning: Empty loadable segment detected, is this intentional ?\n"
+msgstr ""
+
+#: elf.c:6867
+#, c-format
+msgid ""
+"Unable to find equivalent output section for symbol '%s' from section '%s'"
+msgstr ""
+
+#: elf.c:7915
+msgid "%B: unsupported relocation type %s"
+msgstr ""
+
+#: elf32-arm.c:3722 elf32-arm.c:7051
+msgid ""
+"%B(%s): warning: interworking not enabled.\n"
+" first occurrence: %B: Thumb call to ARM"
+msgstr ""
+
+#: elf32-arm.c:3769
+msgid ""
+"%B(%s): warning: interworking not enabled.\n"
+" first occurrence: %B: ARM call to Thumb"
+msgstr ""
+
+#: elf32-arm.c:3988 elf32-arm.c:5433
+#: /src/binutils-gdb/bfd/elfnn-aarch64.c:2324
+#, c-format
+msgid "%s: cannot create stub entry %s"
+msgstr ""
+
+#: elf32-arm.c:5549
+#, c-format
+msgid "unable to find THUMB glue '%s' for '%s'"
+msgstr ""
+
+#: elf32-arm.c:5585
+#, c-format
+msgid "unable to find ARM glue '%s' for '%s'"
+msgstr ""
+
+#: elf32-arm.c:6123
+msgid "%B: BE8 images only valid in big-endian mode."
+msgstr ""
+
+#. Give a warning, but do as the user requests anyway.
+#: elf32-arm.c:6353
+msgid ""
+"%B: warning: selected VFP11 erratum workaround is not necessary for target "
+"architecture"
+msgstr ""
+
+#: elf32-arm.c:6897 elf32-arm.c:6917
+msgid "%B: unable to find VFP11 veneer `%s'"
+msgstr ""
+
+#: elf32-arm.c:6966
+#, c-format
+msgid "Invalid TARGET2 relocation type '%s'."
+msgstr ""
+
+#. PR ld/16017: Do not generate ARM instructions for
+#. the PLT if compiling for a thumb-only target.
+#.
+#. FIXME: We ought to be able to generate thumb PLT instructions...
+#: elf32-arm.c:7696
+msgid "%B: Warning: thumb mode PLT generation not currently supported"
+msgstr ""
+
+#: elf32-arm.c:7909
+msgid "%B(%A+0x%lx):unexpected Thumb instruction '0x%x' in TLS trampoline"
+msgstr ""
+
+#: elf32-arm.c:7948
+msgid "%B(%A+0x%lx):unexpected ARM instruction '0x%x' in TLS trampoline"
+msgstr ""
+
+#: elf32-arm.c:8412
+msgid "\\%B: Warning: Arm BLX instruction targets Arm function '%s'."
+msgstr ""
+
+#: elf32-arm.c:8831
+msgid "%B: Warning: Thumb BLX instruction targets thumb function '%s'."
+msgstr ""
+
+#: elf32-arm.c:9672
+msgid ""
+"%B(%A+0x%lx):unexpected Thumb instruction '0x%x' referenced by TLS_GOTDESC"
+msgstr ""
+
+#: elf32-arm.c:9695
+msgid ""
+"%B(%A+0x%lx):unexpected ARM instruction '0x%x' referenced by TLS_GOTDESC"
+msgstr ""
+
+#: elf32-arm.c:9724
+msgid "%B(%A+0x%lx): R_ARM_TLS_LE32 relocation not permitted in shared object"
+msgstr ""
+
+#: elf32-arm.c:9937
+msgid ""
+"%B(%A+0x%lx): Only ADD or SUB instructions are allowed for ALU group "
+"relocations"
+msgstr ""
+
+#: elf32-arm.c:9977 elf32-arm.c:10065 elf32-arm.c:10149 elf32-arm.c:10235
+msgid "%B(%A+0x%lx): Overflow whilst splitting 0x%lx for group relocation %s"
+msgstr ""
+
+#: elf32-arm.c:10474 elf32-sh.c:3994 elf64-sh64.c:1544
+msgid "%B(%A+0x%lx): %s relocation against SEC_MERGE section"
+msgstr ""
+
+#: elf32-arm.c:10585 elf32-m68k.c:4155 elf32-xtensa.c:2799
+#: /src/binutils-gdb/bfd/elfnn-aarch64.c:4192
+msgid "%B(%A+0x%lx): %s used with TLS symbol %s"
+msgstr ""
+
+#: elf32-arm.c:10586 elf32-m68k.c:4156 elf32-xtensa.c:2800
+#: /src/binutils-gdb/bfd/elfnn-aarch64.c:4193
+msgid "%B(%A+0x%lx): %s used with non-TLS symbol %s"
+msgstr ""
+
+#: elf32-arm.c:10666 elf32-tic6x.c:2736
+#: /src/binutils-gdb/bfd/elfnn-aarch64.c:4481
+msgid "out of range"
+msgstr ""
+
+#: elf32-arm.c:10670 elf32-nios2.c:3525 elf32-tic6x.c:2740
+#: /src/binutils-gdb/bfd/elfnn-aarch64.c:4485
+msgid "unsupported relocation"
+msgstr ""
+
+#: elf32-arm.c:10678 elf32-nios2.c:3535 elf32-tic6x.c:2748
+#: /src/binutils-gdb/bfd/elfnn-aarch64.c:4493
+msgid "unknown error"
+msgstr ""
+
+#: elf32-arm.c:11153
+msgid ""
+"Warning: Clearing the interworking flag of %B because non-interworking code "
+"in %B has been linked with it"
+msgstr ""
+
+#: elf32-arm.c:11240
+msgid "%B: Unknown mandatory EABI object attribute %d"
+msgstr ""
+
+#: elf32-arm.c:11248
+msgid "Warning: %B: Unknown EABI object attribute %d"
+msgstr ""
+
+#: elf32-arm.c:11449
+msgid "error: %B: Unknown CPU architecture"
+msgstr ""
+
+#: elf32-arm.c:11487
+msgid "error: %B: Conflicting CPU architectures %d/%d"
+msgstr ""
+
+#: elf32-arm.c:11576
+msgid ""
+"Error: %B has both the current and legacy Tag_MPextension_use attributes"
+msgstr ""
+
+#: elf32-arm.c:11601
+msgid "error: %B uses VFP register arguments, %B does not"
+msgstr ""
+
+#: elf32-arm.c:11747
+msgid "error: %B: unable to merge virtualization attributes with %B"
+msgstr ""
+
+#: elf32-arm.c:11773
+msgid "error: %B: Conflicting architecture profiles %c/%c"
+msgstr ""
+
+#: elf32-arm.c:11877
+msgid "Warning: %B: Conflicting platform configuration"
+msgstr ""
+
+#: elf32-arm.c:11886
+msgid "error: %B: Conflicting use of R9"
+msgstr ""
+
+#: elf32-arm.c:11898
+msgid "error: %B: SB relative addressing conflicts with use of R9"
+msgstr ""
+
+#: elf32-arm.c:11911
+msgid ""
+"warning: %B uses %u-byte wchar_t yet the output is to use %u-byte wchar_t; "
+"use of wchar_t values across objects may fail"
+msgstr ""
+
+#: elf32-arm.c:11942
+msgid ""
+"warning: %B uses %s enums yet the output is to use %s enums; use of enum "
+"values across objects may fail"
+msgstr ""
+
+#: elf32-arm.c:11954
+msgid "error: %B uses iWMMXt register arguments, %B does not"
+msgstr ""
+
+#: elf32-arm.c:11971
+msgid "error: fp16 format mismatch between %B and %B"
+msgstr ""
+
+#: elf32-arm.c:12007
+msgid "%B has has both the current and legacy Tag_MPextension_use attributes"
+msgstr ""
+
+#. Ignore init flag - it may not be set, despite the flags field
+#. containing valid data.
+#. Ignore init flag - it may not be set, despite the flags field containing valid data.
+#. Ignore init flag - it may not be set, despite the flags field
+#. containing valid data.
+#: elf32-arm.c:12095 elf32-bfin.c:4949 elf32-cris.c:4139 elf32-m68hc1x.c:1427
+#: elf32-m68k.c:1195 elf32-score.c:4004 elf32-score7.c:3808 elf32-vax.c:529
+#: elf32-xgate.c:674 elfxx-mips.c:14955
+#: /src/binutils-gdb/bfd/elfnn-aarch64.c:4645
+#, c-format
+msgid "private flags = %lx:"
+msgstr ""
+
+#: elf32-arm.c:12104
+#, c-format
+msgid " [interworking enabled]"
+msgstr ""
+
+#: elf32-arm.c:12112
+#, c-format
+msgid " [VFP float format]"
+msgstr ""
+
+#: elf32-arm.c:12114
+#, c-format
+msgid " [Maverick float format]"
+msgstr ""
+
+#: elf32-arm.c:12116
+#, c-format
+msgid " [FPA float format]"
+msgstr ""
+
+#: elf32-arm.c:12125
+#, c-format
+msgid " [new ABI]"
+msgstr ""
+
+#: elf32-arm.c:12128
+#, c-format
+msgid " [old ABI]"
+msgstr ""
+
+#: elf32-arm.c:12131
+#, c-format
+msgid " [software FP]"
+msgstr ""
+
+#: elf32-arm.c:12140
+#, c-format
+msgid " [Version1 EABI]"
+msgstr ""
+
+#: elf32-arm.c:12143 elf32-arm.c:12154
+#, c-format
+msgid " [sorted symbol table]"
+msgstr ""
+
+#: elf32-arm.c:12145 elf32-arm.c:12156
+#, c-format
+msgid " [unsorted symbol table]"
+msgstr ""
+
+#: elf32-arm.c:12151
+#, c-format
+msgid " [Version2 EABI]"
+msgstr ""
+
+#: elf32-arm.c:12159
+#, c-format
+msgid " [dynamic symbols use segment index]"
+msgstr ""
+
+#: elf32-arm.c:12162
+#, c-format
+msgid " [mapping symbols precede others]"
+msgstr ""
+
+#: elf32-arm.c:12169
+#, c-format
+msgid " [Version3 EABI]"
+msgstr ""
+
+#: elf32-arm.c:12173
+#, c-format
+msgid " [Version4 EABI]"
+msgstr ""
+
+#: elf32-arm.c:12177
+#, c-format
+msgid " [Version5 EABI]"
+msgstr ""
+
+#: elf32-arm.c:12180
+#, c-format
+msgid " [soft-float ABI]"
+msgstr ""
+
+#: elf32-arm.c:12183
+#, c-format
+msgid " [hard-float ABI]"
+msgstr ""
+
+#: elf32-arm.c:12189
+#, c-format
+msgid " [BE8]"
+msgstr ""
+
+#: elf32-arm.c:12192
+#, c-format
+msgid " [LE8]"
+msgstr ""
+
+#: elf32-arm.c:12198
+#, c-format
+msgid " <EABI version unrecognised>"
+msgstr ""
+
+#: elf32-arm.c:12205
+#, c-format
+msgid " [relocatable executable]"
+msgstr ""
+
+#: elf32-arm.c:12208
+#, c-format
+msgid " [has entry point]"
+msgstr ""
+
+#: elf32-arm.c:12213 /src/binutils-gdb/bfd/elfnn-aarch64.c:4648
+#, c-format
+msgid "<Unrecognised flag bits set>"
+msgstr ""
+
+#: elf32-arm.c:12522 elf32-i386.c:1452 elf32-s390.c:1005 elf32-tic6x.c:2812
+#: elf32-tilepro.c:1511 elf32-xtensa.c:999 elf64-s390.c:927
+#: elf64-x86-64.c:1467 elfxx-sparc.c:1415 elfxx-tilegx.c:1728
+#: /src/binutils-gdb/bfd/elfnn-aarch64.c:5038
+msgid "%B: bad symbol index: %d"
+msgstr ""
+
+#: elf32-arm.c:12674 elf32-metag.c:2283 elf64-x86-64.c:1593
+#: elf64-x86-64.c:1771 elfxx-mips.c:8482
+msgid ""
+"%B: relocation %s against `%s' can not be used when making a shared object; "
+"recompile with -fPIC"
+msgstr ""
+
+#: elf32-arm.c:13796
+#, c-format
+msgid "Errors encountered processing file %s"
+msgstr ""
+
+#: elf32-arm.c:14230
+#, c-format
+msgid "error: required section '%s' not found in the linker script"
+msgstr ""
+
+#: elf32-arm.c:15252
+msgid "%B: error: Cortex-A8 erratum stub is allocated in unsafe location"
+msgstr ""
+
+#. There's not much we can do apart from complain if this
+#. happens.
+#: elf32-arm.c:15279
+msgid "%B: error: Cortex-A8 erratum stub out of range (input file too large)"
+msgstr ""
+
+#: elf32-arm.c:15373 elf32-arm.c:15395
+msgid "%B: error: VFP11 veneer out of range"
+msgstr ""
+
+#: elf32-arm.c:16020
+msgid "error: %B is already in final BE8 format"
+msgstr ""
+
+#: elf32-arm.c:16096
+msgid ""
+"error: Source object %B has EABI version %d, but target %B has EABI version "
+"%d"
+msgstr ""
+
+#: elf32-arm.c:16112
+msgid "error: %B is compiled for APCS-%d, whereas target %B uses APCS-%d"
+msgstr ""
+
+#: elf32-arm.c:16137
+msgid "error: %B uses VFP instructions, whereas %B does not"
+msgstr ""
+
+#: elf32-arm.c:16141
+msgid "error: %B uses FPA instructions, whereas %B does not"
+msgstr ""
+
+#: elf32-arm.c:16151
+msgid "error: %B uses Maverick instructions, whereas %B does not"
+msgstr ""
+
+#: elf32-arm.c:16155
+msgid "error: %B does not use Maverick instructions, whereas %B does"
+msgstr ""
+
+#: elf32-arm.c:16174
+msgid "error: %B uses software FP, whereas %B uses hardware FP"
+msgstr ""
+
+#: elf32-arm.c:16178
+msgid "error: %B uses hardware FP, whereas %B uses software FP"
+msgstr ""
+
+#: elf32-avr.c:1264 elf32-bfin.c:3228 elf32-cris.c:2024 elf32-epiphany.c:568
+#: elf32-fr30.c:597 elf32-frv.c:4047 elf32-i860.c:1220 elf32-ip2k.c:1479
+#: elf32-iq2000.c:696 elf32-m32c.c:561 elf32-mep.c:543 elf32-metag.c:2000
+#: elf32-moxie.c:290 elf32-msp430.c:1325 elf32-mt.c:399 elf32-openrisc.c:412
+#: elf32-tilepro.c:3674 elf32-v850.c:2289 elf32-xstormy16.c:944
+#: elf64-mmix.c:1546 elfxx-tilegx.c:4059
+msgid "internal error: dangerous relocation"
+msgstr ""
+
+#: elf32-avr.c:2476 elf32-hppa.c:578 elf32-m68hc1x.c:160 elf32-metag.c:1197
+#: elf32-nios2.c:1357
+msgid "%B: cannot create stub entry %s"
+msgstr ""
+
+#: elf32-bfin.c:107 elf32-bfin.c:363
+msgid "relocation should be even number"
+msgstr ""
+
+#: elf32-bfin.c:1601
+msgid "%B(%A+0x%lx): unresolvable relocation against symbol `%s'"
+msgstr ""
+
+#: elf32-bfin.c:1634 elf32-i386.c:4406 elf32-m68k.c:4197 elf32-s390.c:3364
+#: elf64-s390.c:3290 elf64-x86-64.c:4506
+msgid "%B(%A+0x%lx): reloc against `%s': error %d"
+msgstr ""
+
+#: elf32-bfin.c:2732
+msgid "%B: relocation at `%A+0x%x' references symbol `%s' with nonzero addend"
+msgstr ""
+
+#: elf32-bfin.c:2748
+msgid "relocation references symbol not defined in the module"
+msgstr ""
+
+#: elf32-bfin.c:2845
+msgid "R_BFIN_FUNCDESC references dynamic symbol with nonzero addend"
+msgstr ""
+
+#: elf32-bfin.c:2886 elf32-bfin.c:3009
+msgid "cannot emit fixups in read-only section"
+msgstr ""
+
+#: elf32-bfin.c:2917 elf32-bfin.c:3047 elf32-lm32.c:1095 elf32-sh.c:4913
+msgid "cannot emit dynamic relocations in read-only section"
+msgstr ""
+
+#: elf32-bfin.c:2967
+msgid "R_BFIN_FUNCDESC_VALUE references dynamic symbol with nonzero addend"
+msgstr ""
+
+#: elf32-bfin.c:3132
+msgid "relocations between different segments are not supported"
+msgstr ""
+
+#: elf32-bfin.c:3133
+msgid "warning: relocation references a different segment"
+msgstr ""
+
+#: elf32-bfin.c:4907
+msgid "%B: unsupported relocation type %i"
+msgstr ""
+
+#: elf32-bfin.c:4995 elf32-frv.c:6600
+#, c-format
+msgid "%s: cannot link non-fdpic object file into fdpic executable"
+msgstr ""
+
+#: elf32-bfin.c:4999 elf32-frv.c:6604
+#, c-format
+msgid "%s: cannot link fdpic object file into non-fdpic executable"
+msgstr ""
+
+#: elf32-bfin.c:5153
+#, c-format
+msgid "*** check this relocation %s"
+msgstr ""
+
+#: elf32-cris.c:1110
+msgid "%B, section %A: unresolvable relocation %s against symbol `%s'"
+msgstr ""
+
+#: elf32-cris.c:1172
+msgid "%B, section %A: No PLT nor GOT for relocation %s against symbol `%s'"
+msgstr ""
+
+#: elf32-cris.c:1174
+msgid "%B, section %A: No PLT for relocation %s against symbol `%s'"
+msgstr ""
+
+#: elf32-cris.c:1180 elf32-cris.c:1313 elf32-cris.c:1573 elf32-cris.c:1656
+#: elf32-cris.c:1809 elf32-tic6x.c:2645
+msgid "[whose name is lost]"
+msgstr ""
+
+#: elf32-cris.c:1299 elf32-tic6x.c:2630
+msgid ""
+"%B, section %A: relocation %s with non-zero addend %d against local symbol"
+msgstr ""
+
+#: elf32-cris.c:1307 elf32-cris.c:1650 elf32-cris.c:1803 elf32-tic6x.c:2638
+msgid ""
+"%B, section %A: relocation %s with non-zero addend %d against symbol `%s'"
+msgstr ""
+
+#: elf32-cris.c:1333
+msgid "%B, section %A: relocation %s is not allowed for global symbol: `%s'"
+msgstr ""
+
+#: elf32-cris.c:1349
+msgid "%B, section %A: relocation %s with no GOT created"
+msgstr ""
+
+#. We shouldn't get here for GCC-emitted code.
+#: elf32-cris.c:1564
+msgid ""
+"%B, section %A: relocation %s has an undefined reference to `%s', perhaps a "
+"declaration mixup?"
+msgstr ""
+
+#: elf32-cris.c:1937
+msgid ""
+"%B, section %A: relocation %s is not allowed for symbol: `%s' which is "
+"defined outside the program, perhaps a declaration mixup?"
+msgstr ""
+
+#: elf32-cris.c:1990
+msgid "(too many global variables for -fpic: recompile with -fPIC)"
+msgstr ""
+
+#: elf32-cris.c:1997
+msgid ""
+"(thread-local data too big for -fpic or -msmall-tls: recompile with -fPIC or "
+"-mno-small-tls)"
+msgstr ""
+
+#: elf32-cris.c:3234
+msgid ""
+"%B, section %A:\n"
+" v10/v32 compatible object %s must not contain a PIC relocation"
+msgstr ""
+
+#: elf32-cris.c:3342
+msgid ""
+"%B, section %A:\n"
+" relocation %s not valid in a shared object; typically an option mixup, "
+"recompile with -fPIC"
+msgstr ""
+
+#: elf32-cris.c:3556
+msgid ""
+"%B, section %A:\n"
+" relocation %s should not be used in a shared object; recompile with -fPIC"
+msgstr ""
+
+#: elf32-cris.c:3978
+msgid ""
+"%B, section `%A', to symbol `%s':\n"
+" relocation %s should not be used in a shared object; recompile with -fPIC"
+msgstr ""
+
+#: elf32-cris.c:4091
+msgid "Unexpected machine number"
+msgstr ""
+
+#: elf32-cris.c:4142
+#, c-format
+msgid " [symbols have a _ prefix]"
+msgstr ""
+
+#: elf32-cris.c:4145
+#, c-format
+msgid " [v10 and v32]"
+msgstr ""
+
+#: elf32-cris.c:4148
+#, c-format
+msgid " [v32]"
+msgstr ""
+
+#: elf32-cris.c:4191
+msgid "%B: uses _-prefixed symbols, but writing file with non-prefixed symbols"
+msgstr ""
+
+#: elf32-cris.c:4192
+msgid "%B: uses non-prefixed symbols, but writing file with _-prefixed symbols"
+msgstr ""
+
+#: elf32-cris.c:4211
+msgid "%B contains CRIS v32 code, incompatible with previous objects"
+msgstr ""
+
+#: elf32-cris.c:4213
+msgid "%B contains non-CRIS-v32 code, incompatible with previous objects"
+msgstr ""
+
+#: elf32-dlx.c:142
+#, c-format
+msgid "BFD Link Error: branch (PC rel16) to section (%s) not supported"
+msgstr ""
+
+#: elf32-dlx.c:204
+#, c-format
+msgid "BFD Link Error: jump (PC rel26) to section (%s) not supported"
+msgstr ""
+
+#. Only if it's not an unresolved symbol.
+#: elf32-epiphany.c:564 elf32-ip2k.c:1475
+msgid "unsupported relocation between data/insn address spaces"
+msgstr ""
+
+#: elf32-frv.c:1460 elf32-frv.c:1609
+msgid "relocation requires zero addend"
+msgstr ""
+
+#: elf32-frv.c:2822
+msgid "%H: relocation to `%s+%v' may have caused the error above\n"
+msgstr ""
+
+#: elf32-frv.c:2839
+msgid "%H: relocation references symbol not defined in the module\n"
+msgstr ""
+
+#: elf32-frv.c:2915
+msgid "%H: R_FRV_GETTLSOFF not applied to a call instruction\n"
+msgstr ""
+
+#: elf32-frv.c:2956
+msgid "%H: R_FRV_GOTTLSDESC12 not applied to an lddi instruction\n"
+msgstr ""
+
+#: elf32-frv.c:3027
+msgid "%H: R_FRV_GOTTLSDESCHI not applied to a sethi instruction\n"
+msgstr ""
+
+#: elf32-frv.c:3064
+msgid "%H: R_FRV_GOTTLSDESCLO not applied to a setlo or setlos instruction\n"
+msgstr ""
+
+#: elf32-frv.c:3111
+msgid "%H: R_FRV_TLSDESC_RELAX not applied to an ldd instruction\n"
+msgstr ""
+
+#: elf32-frv.c:3195
+msgid "%H: R_FRV_GETTLSOFF_RELAX not applied to a calll instruction\n"
+msgstr ""
+
+#: elf32-frv.c:3249
+msgid "%H: R_FRV_GOTTLSOFF12 not applied to an ldi instruction\n"
+msgstr ""
+
+#: elf32-frv.c:3279
+msgid "%H: R_FRV_GOTTLSOFFHI not applied to a sethi instruction\n"
+msgstr ""
+
+#: elf32-frv.c:3308
+msgid "%H: R_FRV_GOTTLSOFFLO not applied to a setlo or setlos instruction\n"
+msgstr ""
+
+#: elf32-frv.c:3338
+msgid "%H: R_FRV_TLSOFF_RELAX not applied to an ld instruction\n"
+msgstr ""
+
+#: elf32-frv.c:3383
+msgid "%H: R_FRV_TLSMOFFHI not applied to a sethi instruction\n"
+msgstr ""
+
+#: elf32-frv.c:3410
+msgid "R_FRV_TLSMOFFLO not applied to a setlo or setlos instruction\n"
+msgstr ""
+
+#: elf32-frv.c:3531
+msgid "%H: R_FRV_FUNCDESC references dynamic symbol with nonzero addend\n"
+msgstr ""
+
+#: elf32-frv.c:3572 elf32-frv.c:3694
+msgid "%H: cannot emit fixups in read-only section\n"
+msgstr ""
+
+#: elf32-frv.c:3603 elf32-frv.c:3737
+msgid "%H: cannot emit dynamic relocations in read-only section\n"
+msgstr ""
+
+#: elf32-frv.c:3652
+msgid ""
+"%H: R_FRV_FUNCDESC_VALUE references dynamic symbol with nonzero addend\n"
+msgstr ""
+
+#: elf32-frv.c:3908
+msgid "%H: reloc against `%s' references a different segment\n"
+msgstr ""
+
+#: elf32-frv.c:4058
+msgid "%H: reloc against `%s': %s\n"
+msgstr ""
+
+#: elf32-frv.c:6265
+msgid "%B: unsupported relocation type %i\n"
+msgstr ""
+
+#: elf32-frv.c:6514
+#, c-format
+msgid ""
+"%s: compiled with %s and linked with modules that use non-pic relocations"
+msgstr ""
+
+#: elf32-frv.c:6567 elf32-iq2000.c:828 elf32-m32c.c:812
+#, c-format
+msgid "%s: compiled with %s and linked with modules compiled with %s"
+msgstr ""
+
+#: elf32-frv.c:6579
+#, c-format
+msgid ""
+"%s: uses different unknown e_flags (0x%lx) fields than previous modules (0x"
+"%lx)"
+msgstr ""
+
+#: elf32-frv.c:6627 elf32-iq2000.c:865 elf32-m32c.c:848 elf32-mt.c:561
+#: elf32-rl78.c:1069 elf32-rx.c:3040 elf64-ppc.c:5839
+#, c-format
+msgid "private flags = 0x%lx:"
+msgstr ""
+
+#: elf32-gen.c:69 elf64-gen.c:69
+msgid "%B: Relocations in generic ELF (EM: %d)"
+msgstr ""
+
+#: elf32-hppa.c:830 elf32-hppa.c:3592
+msgid "%B(%A+0x%lx): cannot reach %s, recompile with -ffunction-sections"
+msgstr ""
+
+#: elf32-hppa.c:1268
+msgid ""
+"%B: relocation %s can not be used when making a shared object; recompile "
+"with -fPIC"
+msgstr ""
+
+#: elf32-hppa.c:2781
+msgid "%B: duplicate export stub %s"
+msgstr ""
+
+#: elf32-hppa.c:3427
+msgid ""
+"%B(%A+0x%lx): %s fixup for insn 0x%x is not supported in a non-shared link"
+msgstr ""
+
+#: elf32-hppa.c:4279
+msgid "%B(%A+0x%lx): cannot handle %s for %s"
+msgstr ""
+
+#: elf32-hppa.c:4598
+msgid ".got section not immediately after .plt section"
+msgstr ""
+
+#. Unknown relocation.
+#: elf32-i386.c:380 elf32-m68k.c:353 elf32-ppc.c:2035 elf32-s390.c:345
+#: elf32-tic6x.c:2667 elf64-ppc.c:2427 elf64-s390.c:371 elf64-x86-64.c:281
+msgid "%B: invalid relocation type %d"
+msgstr ""
+
+#: elf32-i386.c:1394 elf64-x86-64.c:1410
+msgid ""
+"%B: TLS transition from %s to %s against `%s' at 0x%lx in section `%A' failed"
+msgstr ""
+
+#: elf32-i386.c:1642 elf32-s390.c:1233 elf32-sh.c:6263 elf32-tilepro.c:1627
+#: elf32-xtensa.c:1176 elf64-s390.c:1166 elfxx-sparc.c:1596
+#: elfxx-tilegx.c:1836
+msgid "%B: `%s' accessed both as normal and thread local symbol"
+msgstr ""
+
+#: elf32-i386.c:2500 elf64-x86-64.c:2582
+msgid "%P: %B: warning: relocation against `%s' in readonly section `%A'.\n"
+msgstr ""
+
+#: elf32-i386.c:2740 elf64-x86-64.c:2820
+msgid "%P: %B: warning: relocation in readonly section `%A'.\n"
+msgstr ""
+
+#: elf32-i386.c:3207 elf32-tilepro.c:2873 elf64-x86-64.c:3275
+#: elfxx-tilegx.c:3172 /src/binutils-gdb/bfd/elfnn-aarch64.c:4099
+msgid "%B: unrecognized relocation (0x%x) in section `%A'"
+msgstr ""
+
+#: elf32-i386.c:3368 elf64-x86-64.c:3380 elfxx-sparc.c:3150
+#: /src/binutils-gdb/bfd/elfnn-aarch64.c:3496
+msgid "%B: relocation %s against STT_GNU_IFUNC symbol `%s' isn't handled by %s"
+msgstr ""
+
+#: elf32-i386.c:3610 elf64-x86-64.c:3777
+msgid "hidden symbol"
+msgstr ""
+
+#: elf32-i386.c:3613 elf64-x86-64.c:3780
+msgid "internal symbol"
+msgstr ""
+
+#: elf32-i386.c:3616 elf64-x86-64.c:3783
+msgid "protected symbol"
+msgstr ""
+
+#: elf32-i386.c:3619 elf64-x86-64.c:3786
+msgid "symbol"
+msgstr ""
+
+#: elf32-i386.c:3624
+msgid ""
+"%B: relocation R_386_GOTOFF against undefined %s `%s' can not be used when "
+"making a shared object"
+msgstr ""
+
+#: elf32-i386.c:3635
+msgid ""
+"%B: relocation R_386_GOTOFF against protected function `%s' can not be used "
+"when making a shared object"
+msgstr ""
+
+#: elf32-i386.c:4923 elf32-tilepro.c:3923 elf64-x86-64.c:4964
+#: elfxx-tilegx.c:4326 /src/binutils-gdb/bfd/elfnn-aarch64.c:7105
+#, c-format
+msgid "discarded output section: `%A'"
+msgstr ""
+
+#: elf32-ip2k.c:857 elf32-ip2k.c:863 elf32-ip2k.c:930 elf32-ip2k.c:936
+msgid ""
+"ip2k relaxer: switch table without complete matching relocation information."
+msgstr ""
+
+#: elf32-ip2k.c:880 elf32-ip2k.c:963
+msgid "ip2k relaxer: switch table header corrupt."
+msgstr ""
+
+#: elf32-ip2k.c:1292
+#, c-format
+msgid "ip2k linker: missing page instruction at 0x%08lx (dest = 0x%08lx)."
+msgstr ""
+
+#: elf32-ip2k.c:1308
+#, c-format
+msgid "ip2k linker: redundant page instruction at 0x%08lx (dest = 0x%08lx)."
+msgstr ""
+
+#: elf32-iq2000.c:841 elf32-m32c.c:824
+#, c-format
+msgid "%s: uses different e_flags (0x%lx) fields than previous modules (0x%lx)"
+msgstr ""
+
+#: elf32-lm32.c:698 elf32-nios2.c:2191
+msgid "global pointer relative relocation when _gp not defined"
+msgstr ""
+
+#: elf32-lm32.c:753 elf32-nios2.c:2623
+msgid "global pointer relative address out of range"
+msgstr ""
+
+#: elf32-lm32.c:1049
+msgid "internal error: addend should be zero for R_LM32_16_GOT"
+msgstr ""
+
+#: elf32-m32r.c:1453
+msgid "SDA relocation when _SDA_BASE_ not defined"
+msgstr ""
+
+#: elf32-m32r.c:3003
+msgid "%B: The target (%s) of an %s relocation is in the wrong section (%A)"
+msgstr ""
+
+#: elf32-m32r.c:3529
+msgid "%B: Instruction set mismatch with previous modules"
+msgstr ""
+
+#: elf32-m32r.c:3550 elf32-nds32.c:5636
+#, c-format
+msgid "private flags = %lx"
+msgstr ""
+
+#: elf32-m32r.c:3555
+#, c-format
+msgid ": m32r instructions"
+msgstr ""
+
+#: elf32-m32r.c:3556
+#, c-format
+msgid ": m32rx instructions"
+msgstr ""
+
+#: elf32-m32r.c:3557
+#, c-format
+msgid ": m32r2 instructions"
+msgstr ""
+
+#: elf32-m68hc1x.c:1114
+#, c-format
+msgid ""
+"Reference to the far symbol `%s' using a wrong relocation may result in "
+"incorrect execution"
+msgstr ""
+
+#: elf32-m68hc1x.c:1150
+#, c-format
+msgid ""
+"XGATE address (%lx) is not within shared RAM(0xE000-0xFFFF), therefore you "
+"must manually offset the address, and possibly manage the page, in your code."
+msgstr ""
+
+#: elf32-m68hc1x.c:1170
+#, c-format
+msgid ""
+"banked address [%lx:%04lx] (%lx) is not in the same bank as current banked "
+"address [%lx:%04lx] (%lx)"
+msgstr ""
+
+#: elf32-m68hc1x.c:1190
+#, c-format
+msgid ""
+"reference to a banked address [%lx:%04lx] in the normal address space at "
+"%04lx"
+msgstr ""
+
+#: elf32-m68hc1x.c:1237
+#, c-format
+msgid ""
+"S12 address (%lx) is not within shared RAM(0x2000-0x4000), therefore you "
+"must manually offset the address in your code"
+msgstr ""
+
+#: elf32-m68hc1x.c:1370
+msgid ""
+"%B: linking files compiled for 16-bit integers (-mshort) and others for 32-"
+"bit integers"
+msgstr ""
+
+#: elf32-m68hc1x.c:1377
+msgid ""
+"%B: linking files compiled for 32-bit double (-fshort-double) and others for "
+"64-bit double"
+msgstr ""
+
+#: elf32-m68hc1x.c:1386
+msgid "%B: linking files compiled for HCS12 with others compiled for HC12"
+msgstr ""
+
+#: elf32-m68hc1x.c:1402 elf32-ppc.c:4776 elf64-sparc.c:706 elfxx-mips.c:14817
+msgid "%B: uses different e_flags (0x%lx) fields than previous modules (0x%lx)"
+msgstr ""
+
+#: elf32-m68hc1x.c:1430 elf32-xgate.c:677
+#, c-format
+msgid "[abi=32-bit int, "
+msgstr ""
+
+#: elf32-m68hc1x.c:1432 elf32-xgate.c:679
+#, c-format
+msgid "[abi=16-bit int, "
+msgstr ""
+
+#: elf32-m68hc1x.c:1435 elf32-xgate.c:682
+#, c-format
+msgid "64-bit double, "
+msgstr ""
+
+#: elf32-m68hc1x.c:1437 elf32-xgate.c:684
+#, c-format
+msgid "32-bit double, "
+msgstr ""
+
+#: elf32-m68hc1x.c:1440
+#, c-format
+msgid "cpu=HC11]"
+msgstr ""
+
+#: elf32-m68hc1x.c:1442
+#, c-format
+msgid "cpu=HCS12]"
+msgstr ""
+
+#: elf32-m68hc1x.c:1444
+#, c-format
+msgid "cpu=HC12]"
+msgstr ""
+
+#: elf32-m68hc1x.c:1447
+#, c-format
+msgid " [memory=bank-model]"
+msgstr ""
+
+#: elf32-m68hc1x.c:1449
+#, c-format
+msgid " [memory=flat]"
+msgstr ""
+
+#: elf32-m68hc1x.c:1452
+#, c-format
+msgid " [XGATE RAM offsetting]"
+msgstr ""
+
+#: elf32-m68k.c:1210 elf32-m68k.c:1211 vms-alpha.c:7207 vms-alpha.c:7222
+msgid "unknown"
+msgstr ""
+
+#: elf32-m68k.c:1674
+msgid "%B: GOT overflow: Number of relocations with 8-bit offset > %d"
+msgstr ""
+
+#: elf32-m68k.c:1680
+msgid "%B: GOT overflow: Number of relocations with 8- or 16-bit offset > %d"
+msgstr ""
+
+#: elf32-m68k.c:3921
+msgid "%B(%A+0x%lx): R_68K_TLS_LE32 relocation not permitted in shared object"
+msgstr ""
+
+#: elf32-mcore.c:99 elf32-mcore.c:442
+msgid "%B: Relocation %s (%d) is not currently supported.\n"
+msgstr ""
+
+#: elf32-mcore.c:428
+msgid "%B: Unknown relocation type %d\n"
+msgstr ""
+
+#. Pacify gcc -Wall.
+#: elf32-mep.c:157
+#, c-format
+msgid "mep: no reloc for code %d"
+msgstr ""
+
+#: elf32-mep.c:163
+#, c-format
+msgid "MeP: howto %d has type %d"
+msgstr ""
+
+#: elf32-mep.c:632
+msgid "%B and %B are for different cores"
+msgstr ""
+
+#: elf32-mep.c:649
+msgid "%B and %B are for different configurations"
+msgstr ""
+
+#: elf32-mep.c:686
+#, c-format
+msgid "private flags = 0x%lx"
+msgstr ""
+
+#: elf32-metag.c:1921
+msgid ""
+"%B(%A+0x%lx): R_METAG_TLS_LE/IENONPIC relocation not permitted in shared "
+"object"
+msgstr ""
+
+#: elf32-microblaze.c:950
+#, c-format
+msgid "%s: unknown relocation type %d"
+msgstr ""
+
+#: elf32-microblaze.c:1076 elf32-microblaze.c:1121
+#, c-format
+msgid "%s: The target (%s) of an %s relocation is in the wrong section (%s)"
+msgstr ""
+
+#: elf32-microblaze.c:1484 elf32-tilepro.c:3320 elfxx-sparc.c:3526
+#: elfxx-tilegx.c:3729
+msgid "%B: probably compiled without -fPIC?"
+msgstr ""
+
+#: elf32-mips.c:1670 elf64-mips.c:2990 elfn32-mips.c:2793
+msgid "literal relocation occurs for an external symbol"
+msgstr ""
+
+#: elf32-mips.c:1717 elf32-score.c:570 elf32-score7.c:469 elf64-mips.c:3033
+#: elfn32-mips.c:2834
+msgid "32bits gp relative relocation occurs for an external symbol"
+msgstr ""
+
+#: elf32-msp430.c:801 elf32-msp430.c:1109
+msgid "Try enabling relaxation to avoid relocation truncations"
+msgstr ""
+
+#: elf32-msp430.c:1317
+msgid "internal error: branch/jump to an odd address detected"
+msgstr ""
+
+#: elf32-msp430.c:2221
+msgid "Warning: %B: Unknown MSPABI object attribute %d"
+msgstr ""
+
+#: elf32-msp430.c:2312
+msgid "error: %B uses %s instructions but %B uses %s"
+msgstr ""
+
+#: elf32-msp430.c:2324
+msgid "error: %B uses the %s code model whereas %B uses the %s code model"
+msgstr ""
+
+#: elf32-msp430.c:2336
+msgid "error: %B uses the large code model but %B uses MSP430 instructions"
+msgstr ""
+
+#: elf32-msp430.c:2346
+msgid "error: %B uses the %s data model whereas %B uses the %s data model"
+msgstr ""
+
+#: elf32-msp430.c:2358
+msgid "error: %B uses the small code model but %B uses the %s data model"
+msgstr ""
+
+#: elf32-msp430.c:2369
+msgid "error: %B uses the %s data model but %B only uses MSP430 instructions"
+msgstr ""
+
+#: elf32-nds32.c:2921
+msgid "error: Can't find symbol: _SDA_BASE_."
+msgstr ""
+
+#: elf32-nds32.c:4142
+msgid "%B: error: unknown relocation type %d."
+msgstr ""
+
+#: elf32-nds32.c:4584
+#, c-format
+msgid "%s: warning: cannot deal R_NDS32_25_ABS_RELA in shared mode."
+msgstr ""
+
+#: elf32-nds32.c:4716
+msgid "%B: warning: unaligned access to GOT entry."
+msgstr ""
+
+#: elf32-nds32.c:4758
+msgid "%B: warning: relocate SDA_BASE failed."
+msgstr ""
+
+#: elf32-nds32.c:4779
+msgid "%B(%A): warning: unaligned small data access of type %d."
+msgstr ""
+
+#: elf32-nds32.c:5446
+msgid ""
+"%B: ISR vector size mismatch with previous modules, previous %u-byte, "
+"current %u-byte"
+msgstr ""
+
+#: elf32-nds32.c:5489
+msgid "%B: warning: Endian mismatch with previous modules."
+msgstr ""
+
+#: elf32-nds32.c:5499
+msgid ""
+"%B: warning: Older version of object file encountered, Please recompile with "
+"current tool chain."
+msgstr ""
+
+#: elf32-nds32.c:5577
+msgid "%B: error: ABI mismatch with previous modules."
+msgstr ""
+
+#: elf32-nds32.c:5588
+msgid "%B: error: Instruction set mismatch with previous modules."
+msgstr ""
+
+#: elf32-nds32.c:5612
+msgid "%B: warning: Incompatible elf-versions %s and %s."
+msgstr ""
+
+#: elf32-nds32.c:5642
+#, c-format
+msgid ": n1 instructions"
+msgstr ""
+
+#: elf32-nds32.c:5645
+#, c-format
+msgid ": n1h instructions"
+msgstr ""
+
+#: elf32-nds32.c:8147
+msgid "%B: %s\n"
+msgstr ""
+
+#: elf32-nds32.c:8449
+msgid ""
+"%B(%A): warning: relax is suppressed for sections of alignment %d-bytes > 4-"
+"byte."
+msgstr ""
+
+#: elf32-nds32.c:8502
+msgid "%B: error: Cannot set _ITB_BASE_"
+msgstr ""
+
+#: elf32-nds32.c:11384
+msgid "%B: Nested OMIT_FP in %A."
+msgstr ""
+
+#: elf32-nds32.c:11401
+msgid "%B: Unmatched OMIT_FP in %A."
+msgstr ""
+
+#: elf32-nds32.c:13357
+msgid "Linker: cannot init ex9 hash table error \n"
+msgstr ""
+
+#: elf32-nds32.c:13790 elf32-nds32.c:13804
+msgid "Linker: error cannot fixed ex9 relocation \n"
+msgstr ""
+
+#: elf32-nds32.c:14015
+#, c-format
+msgid ""
+"%s: warning: unaligned small data access. For entry: {%d, %d, %d}, addr = 0x"
+"%x, align = 0x%x."
+msgstr ""
+
+#: elf32-nds32.c:14047
+msgid "%P%F: failed creating ex9.it %s hash table: %E\n"
+msgstr ""
+
+#: elf32-nios2.c:2861
+#, c-format
+msgid ""
+"global pointer relative relocation at address 0x%08x when _gp not defined\n"
+msgstr ""
+
+#: elf32-nios2.c:2878
+#, c-format
+msgid ""
+"Unable to reach %s (at 0x%08x) from the global pointer (at 0x%08x) because "
+"the offset (%d) is out of the allowed range, -32678 to 32767.\n"
+msgstr ""
+
+#: elf32-nios2.c:3392
+msgid ""
+"%B(%A+0x%lx): R_NIOS2_TLS_LE16 relocation not permitted in shared object"
+msgstr ""
+
+#: elf32-nios2.c:3520
+msgid "relocation out of range"
+msgstr ""
+
+#: elf32-nios2.c:3530 elf32-tic6x.c:2744
+msgid "dangerous relocation"
+msgstr ""
+
+#: elf32-nios2.c:4529
+#, c-format
+msgid "dynamic variable `%s' is zero size"
+msgstr ""
+
+#: elf32-ppc.c:2100
+#, c-format
+msgid "generic linker can't handle %s"
+msgstr ""
+
+#: elf32-ppc.c:2642
+msgid "corrupt %s section in %B"
+msgstr ""
+
+#: elf32-ppc.c:2661
+msgid "unable to read in %s section from %B"
+msgstr ""
+
+#: elf32-ppc.c:2702
+msgid "warning: unable to set size of %s section in %B"
+msgstr ""
+
+#: elf32-ppc.c:2752
+msgid "failed to allocate space for new APUinfo section."
+msgstr ""
+
+#: elf32-ppc.c:2771
+msgid "failed to compute new APUinfo section."
+msgstr ""
+
+#: elf32-ppc.c:2774
+msgid "failed to install new APUinfo section."
+msgstr ""
+
+#: elf32-ppc.c:3844
+msgid "%B: relocation %s cannot be used when making a shared object"
+msgstr ""
+
+#. It does not make sense to have a procedure linkage
+#. table entry for a local symbol.
+#: elf32-ppc.c:4218
+msgid "%P: %H: %s reloc against local symbol\n"
+msgstr ""
+
+#: elf32-ppc.c:4299
+msgid "%P: %H: @local call to ifunc %s\n"
+msgstr ""
+
+#: elf32-ppc.c:4588 elf32-ppc.c:4603
+msgid "Warning: %B uses hard float, %B uses soft float"
+msgstr ""
+
+#: elf32-ppc.c:4591 elf32-ppc.c:4595
+msgid ""
+"Warning: %B uses double-precision hard float, %B uses single-precision hard "
+"float"
+msgstr ""
+
+#: elf32-ppc.c:4599
+msgid "Warning: %B uses soft float, %B uses single-precision hard float"
+msgstr ""
+
+#: elf32-ppc.c:4606 elf32-ppc.c:4610
+msgid "Warning: %B uses unknown floating point ABI %d"
+msgstr ""
+
+#: elf32-ppc.c:4652 elf32-ppc.c:4656
+msgid "Warning: %B uses unknown vector ABI %d"
+msgstr ""
+
+#: elf32-ppc.c:4660
+msgid "Warning: %B uses vector ABI \"%s\", %B uses \"%s\""
+msgstr ""
+
+#: elf32-ppc.c:4677 elf32-ppc.c:4680
+msgid "Warning: %B uses r3/r4 for small structure returns, %B uses memory"
+msgstr ""
+
+#: elf32-ppc.c:4683 elf32-ppc.c:4687
+msgid "Warning: %B uses unknown small structure return convention %d"
+msgstr ""
+
+#: elf32-ppc.c:4741
+msgid ""
+"%B: compiled with -mrelocatable and linked with modules compiled normally"
+msgstr ""
+
+#: elf32-ppc.c:4749
+msgid ""
+"%B: compiled normally and linked with modules compiled with -mrelocatable"
+msgstr ""
+
+#: elf32-ppc.c:4872
+msgid "%P: bss-plt forced due to %B\n"
+msgstr ""
+
+#: elf32-ppc.c:4875
+msgid "%P: bss-plt forced by profiling\n"
+msgstr ""
+
+#. Uh oh, we didn't find the expected call. We
+#. could just mark this symbol to exclude it
+#. from tls optimization but it's safer to skip
+#. the entire optimization.
+#: elf32-ppc.c:5369 elf64-ppc.c:8371
+msgid "%H arg lost __tls_get_addr, TLS optimization disabled\n"
+msgstr ""
+
+#: elf32-ppc.c:7927
+msgid "%P: %B: unknown relocation type %d for symbol %s\n"
+msgstr ""
+
+#: elf32-ppc.c:8191
+msgid "%P: %H: non-zero addend on %s reloc against `%s'\n"
+msgstr ""
+
+#: elf32-ppc.c:8389
+msgid "%P: %H: relocation %s for indirect function %s unsupported\n"
+msgstr ""
+
+#: elf32-ppc.c:8646 elf32-ppc.c:8676 elf32-ppc.c:8767
+msgid ""
+"%P: %B: the target (%s) of a %s relocation is in the wrong output section "
+"(%s)\n"
+msgstr ""
+
+#: elf32-ppc.c:8854
+msgid ""
+"%B: the target (%s) of a %s relocation is in the wrong output section (%s)"
+msgstr ""
+
+#: elf32-ppc.c:8958
+msgid "%P: %B: relocation %s is not yet supported for symbol %s\n"
+msgstr ""
+
+#: elf32-ppc.c:9038
+msgid "%P: %H: error: %s against `%s' not a multiple of %u\n"
+msgstr ""
+
+#: elf32-ppc.c:9067
+msgid "%P: %H: unresolvable %s relocation against symbol `%s'\n"
+msgstr ""
+
+#: elf32-ppc.c:9114
+msgid "%P: %H: %s reloc against `%s': error %d\n"
+msgstr ""
+
+#: elf32-ppc.c:9750
+msgid "%P: %s not defined in linker created %s\n"
+msgstr ""
+
+#: elf32-rl78.c:784
+msgid "Warning: RL78_SYM reloc with an unknown symbol"
+msgstr ""
+
+#: elf32-rl78.c:952 elf32-rx.c:1324
+msgid "%B(%A): error: call to undefined function '%s'"
+msgstr ""
+
+#: elf32-rl78.c:966 elf32-rx.c:1338
+msgid "%B(%A): warning: unaligned access to symbol '%s' in the small data area"
+msgstr ""
+
+#: elf32-rl78.c:970 elf32-rx.c:1342
+msgid "%B(%A): internal error: out of range error"
+msgstr ""
+
+#: elf32-rl78.c:974 elf32-rx.c:1346
+msgid "%B(%A): internal error: unsupported relocation error"
+msgstr ""
+
+#: elf32-rl78.c:978 elf32-rx.c:1350
+msgid "%B(%A): internal error: dangerous relocation"
+msgstr ""
+
+#: elf32-rl78.c:982 elf32-rx.c:1354
+msgid "%B(%A): internal error: unknown error"
+msgstr ""
+
+#: elf32-rl78.c:1043
+msgid "RL78/G10 ABI conflict: cannot link G10 and non-G10 objects together"
+msgstr ""
+
+#: elf32-rl78.c:1046 elf32-rl78.c:1049
+#, c-format
+msgid "- %s is G10, %s is not"
+msgstr ""
+
+#: elf32-rl78.c:1072
+#, c-format
+msgid " [G10]"
+msgstr ""
+
+#: elf32-rx.c:563
+msgid "%B:%A: Warning: deprecated Red Hat reloc "
+msgstr ""
+
+#. Check for unsafe relocs in PID mode. These are any relocs where
+#. an absolute address is being computed. There are special cases
+#. for relocs against symbols that are known to be referenced in
+#. crt0.o before the PID base address register has been initialised.
+#: elf32-rx.c:581
+msgid "%B(%A): unsafe PID relocation %s at 0x%08lx (against %s in %s)"
+msgstr ""
+
+#: elf32-rx.c:1157
+msgid "Warning: RX_SYM reloc with an unknown symbol"
+msgstr ""
+
+#: elf32-s390.c:2292 elf64-s390.c:2244
+msgid "%B(%A+0x%lx): invalid instruction for TLS relocation %s"
+msgstr ""
+
+#: elf32-score.c:1520 elf32-score7.c:1379 elfxx-mips.c:3642
+msgid "not enough GOT space for local GOT entries"
+msgstr ""
+
+#: elf32-score.c:2742
+msgid "address not word align"
+msgstr ""
+
+#: elf32-score.c:2827 elf32-score7.c:2631
+#, c-format
+msgid "%s: Malformed reloc detected for section %s"
+msgstr ""
+
+#: elf32-score.c:2882 elf32-score7.c:2686
+msgid "%B: CALL15 reloc at 0x%lx not against global symbol"
+msgstr ""
+
+#: elf32-score.c:4007 elf32-score7.c:3811
+#, c-format
+msgid " [pic]"
+msgstr ""
+
+#: elf32-score.c:4011 elf32-score7.c:3815
+#, c-format
+msgid " [fix dep]"
+msgstr ""
+
+#: elf32-score.c:4053 elf32-score7.c:3857
+msgid "%B: warning: linking PIC files with non-PIC files"
+msgstr ""
+
+#: elf32-sh-symbian.c:130
+msgid "%B: IMPORT AS directive for %s conceals previous IMPORT AS"
+msgstr ""
+
+#: elf32-sh-symbian.c:383
+msgid "%B: Unrecognised .directive command: %s"
+msgstr ""
+
+#: elf32-sh-symbian.c:500
+msgid "%B: Failed to add renamed symbol %s"
+msgstr ""
+
+#: elf32-sh.c:569
+msgid "%B: 0x%lx: warning: bad R_SH_USES offset"
+msgstr ""
+
+#: elf32-sh.c:581
+msgid "%B: 0x%lx: warning: R_SH_USES points to unrecognized insn 0x%x"
+msgstr ""
+
+#: elf32-sh.c:598
+msgid "%B: 0x%lx: warning: bad R_SH_USES load offset"
+msgstr ""
+
+#: elf32-sh.c:613
+msgid "%B: 0x%lx: warning: could not find expected reloc"
+msgstr ""
+
+#: elf32-sh.c:641
+msgid "%B: 0x%lx: warning: symbol in unexpected section"
+msgstr ""
+
+#: elf32-sh.c:767
+msgid "%B: 0x%lx: warning: could not find expected COUNT reloc"
+msgstr ""
+
+#: elf32-sh.c:776
+msgid "%B: 0x%lx: warning: bad count"
+msgstr ""
+
+#: elf32-sh.c:1180 elf32-sh.c:1550
+msgid "%B: 0x%lx: fatal: reloc overflow while relaxing"
+msgstr ""
+
+#: elf32-sh.c:3939 elf64-sh64.c:1514
+msgid "Unexpected STO_SH5_ISA32 on local symbol is not handled"
+msgstr ""
+
+#: elf32-sh.c:4190
+msgid "%B: 0x%lx: fatal: unaligned branch target for relax-support relocation"
+msgstr ""
+
+#: elf32-sh.c:4223 elf32-sh.c:4238
+msgid "%B: 0x%lx: fatal: unaligned %s relocation 0x%lx"
+msgstr ""
+
+#: elf32-sh.c:4252
+msgid "%B: 0x%lx: fatal: R_SH_PSHA relocation %d not in range -32..32"
+msgstr ""
+
+#: elf32-sh.c:4266
+msgid "%B: 0x%lx: fatal: R_SH_PSHL relocation %d not in range -32..32"
+msgstr ""
+
+#: elf32-sh.c:4410 elf32-sh.c:4886
+msgid "%B(%A+0x%lx): cannot emit fixup to `%s' in read-only section"
+msgstr ""
+
+#: elf32-sh.c:4993
+msgid "%B(%A+0x%lx): %s relocation against external symbol \"%s\""
+msgstr ""
+
+#: elf32-sh.c:5466
+#, c-format
+msgid "%X%C: relocation to \"%s\" references a different segment\n"
+msgstr ""
+
+#: elf32-sh.c:5472
+#, c-format
+msgid "%C: warning: relocation to \"%s\" references a different segment\n"
+msgstr ""
+
+#: elf32-sh.c:6254 elf32-sh.c:6337
+msgid "%B: `%s' accessed both as normal and FDPIC symbol"
+msgstr ""
+
+#: elf32-sh.c:6259 elf32-sh.c:6341
+msgid "%B: `%s' accessed both as FDPIC and thread local symbol"
+msgstr ""
+
+#: elf32-sh.c:6289
+msgid "%B: Function descriptor relocation with non-zero addend"
+msgstr ""
+
+#: elf32-sh.c:6525 elf64-alpha.c:4661
+msgid "%B: TLS local exec code cannot be linked into shared objects"
+msgstr ""
+
+#: elf32-sh64.c:224 elf64-sh64.c:2318
+#, c-format
+msgid "%s: compiled as 32-bit object and %s is 64-bit"
+msgstr ""
+
+#: elf32-sh64.c:227 elf64-sh64.c:2321
+#, c-format
+msgid "%s: compiled as 64-bit object and %s is 32-bit"
+msgstr ""
+
+#: elf32-sh64.c:229 elf64-sh64.c:2323
+#, c-format
+msgid "%s: object size does not match that of target %s"
+msgstr ""
+
+#: elf32-sh64.c:452 elf64-sh64.c:2839
+#, c-format
+msgid "%s: encountered datalabel symbol in input"
+msgstr ""
+
+#: elf32-sh64.c:529
+msgid "PTB mismatch: a SHmedia address (bit 0 == 1)"
+msgstr ""
+
+#: elf32-sh64.c:532
+msgid "PTA mismatch: a SHcompact address (bit 0 == 0)"
+msgstr ""
+
+#: elf32-sh64.c:550
+#, c-format
+msgid "%s: GAS error: unexpected PTB insn with R_SH_PT_16"
+msgstr ""
+
+#: elf32-sh64.c:599
+msgid "%B: error: unaligned relocation type %d at %08x reloc %p\n"
+msgstr ""
+
+#: elf32-sh64.c:675
+#, c-format
+msgid "%s: could not write out added .cranges entries"
+msgstr ""
+
+#: elf32-sh64.c:735
+#, c-format
+msgid "%s: could not write out sorted .cranges entries"
+msgstr ""
+
+#: elf32-sparc.c:90
+msgid "%B: compiled for a 64 bit system and target is 32 bit"
+msgstr ""
+
+#: elf32-sparc.c:103
+msgid "%B: linking little endian files with big endian files"
+msgstr ""
+
+#: elf32-spu.c:716
+msgid "%X%P: overlay section %A does not start on a cache line.\n"
+msgstr ""
+
+#: elf32-spu.c:724
+msgid "%X%P: overlay section %A is larger than a cache line.\n"
+msgstr ""
+
+#: elf32-spu.c:744
+msgid "%X%P: overlay section %A is not in cache area.\n"
+msgstr ""
+
+#: elf32-spu.c:784
+msgid "%X%P: overlay sections %A and %A do not start at the same address.\n"
+msgstr ""
+
+#: elf32-spu.c:1008
+msgid "warning: call to non-function symbol %s defined in %B"
+msgstr ""
+
+#: elf32-spu.c:1358
+msgid "%A:0x%v lrlive .brinfo (%u) differs from analysis (%u)\n"
+msgstr ""
+
+#: elf32-spu.c:1877
+msgid "%B is not allowed to define %s"
+msgstr ""
+
+#: elf32-spu.c:1885
+#, c-format
+msgid "you are not allowed to define %s in a script"
+msgstr ""
+
+#: elf32-spu.c:1919
+#, c-format
+msgid "%s in overlay section"
+msgstr ""
+
+#: elf32-spu.c:1948
+msgid "overlay stub relocation overflow"
+msgstr ""
+
+#: elf32-spu.c:1957
+msgid "stubs don't match calculated size"
+msgstr ""
+
+#: elf32-spu.c:2539
+#, c-format
+msgid "warning: %s overlaps %s\n"
+msgstr ""
+
+#: elf32-spu.c:2555
+#, c-format
+msgid "warning: %s exceeds section size\n"
+msgstr ""
+
+#: elf32-spu.c:2586
+msgid "%A:0x%v not found in function table\n"
+msgstr ""
+
+#: elf32-spu.c:2726
+msgid "%B(%A+0x%v): call to non-code section %B(%A), analysis incomplete\n"
+msgstr ""
+
+#: elf32-spu.c:3294
+#, c-format
+msgid "Stack analysis will ignore the call from %s to %s\n"
+msgstr ""
+
+#: elf32-spu.c:3985
+msgid " %s: 0x%v\n"
+msgstr ""
+
+#: elf32-spu.c:3986
+msgid "%s: 0x%v 0x%v\n"
+msgstr ""
+
+#: elf32-spu.c:3991
+msgid " calls:\n"
+msgstr ""
+
+#: elf32-spu.c:3999
+#, c-format
+msgid " %s%s %s\n"
+msgstr ""
+
+#: elf32-spu.c:4304
+#, c-format
+msgid "%s duplicated in %s\n"
+msgstr ""
+
+#: elf32-spu.c:4308
+#, c-format
+msgid "%s duplicated\n"
+msgstr ""
+
+#: elf32-spu.c:4315
+msgid "sorry, no support for duplicate object files in auto-overlay script\n"
+msgstr ""
+
+#: elf32-spu.c:4356
+msgid ""
+"non-overlay size of 0x%v plus maximum overlay size of 0x%v exceeds local "
+"store\n"
+msgstr ""
+
+#: elf32-spu.c:4511
+msgid "%B:%A%s exceeds overlay size\n"
+msgstr ""
+
+#: elf32-spu.c:4673
+msgid "Stack size for call graph root nodes.\n"
+msgstr ""
+
+#: elf32-spu.c:4674
+msgid ""
+"\n"
+"Stack size for functions. Annotations: '*' max stack, 't' tail call\n"
+msgstr ""
+
+#: elf32-spu.c:4684
+msgid "Maximum stack required is 0x%v\n"
+msgstr ""
+
+#: elf32-spu.c:4775
+msgid "fatal error while creating .fixup"
+msgstr ""
+
+#: elf32-spu.c:5005
+msgid "%B(%s+0x%lx): unresolvable %s relocation against symbol `%s'"
+msgstr ""
+
+#: elf32-tic6x.c:1600
+msgid "warning: generating a shared library containing non-PIC code"
+msgstr ""
+
+#: elf32-tic6x.c:1605
+msgid "warning: generating a shared library containing non-PID code"
+msgstr ""
+
+#: elf32-tic6x.c:2524
+msgid "%B: SB-relative relocation but __c6xabi_DSBT_BASE not defined"
+msgstr ""
+
+#: elf32-tic6x.c:3648
+msgid "%B: error: unknown mandatory EABI object attribute %d"
+msgstr ""
+
+#: elf32-tic6x.c:3656
+msgid "%B: warning: unknown EABI object attribute %d"
+msgstr ""
+
+#: elf32-tic6x.c:3768 elf32-tic6x.c:3776
+msgid "error: %B requires more stack alignment than %B preserves"
+msgstr ""
+
+#: elf32-tic6x.c:3786 elf32-tic6x.c:3795
+msgid "error: unknown Tag_ABI_array_object_alignment value in %B"
+msgstr ""
+
+#: elf32-tic6x.c:3804 elf32-tic6x.c:3813
+msgid "error: unknown Tag_ABI_array_object_align_expected value in %B"
+msgstr ""
+
+#: elf32-tic6x.c:3821 elf32-tic6x.c:3828
+msgid "error: %B requires more array alignment than %B preserves"
+msgstr ""
+
+#: elf32-tic6x.c:3850
+msgid "warning: %B and %B differ in wchar_t size"
+msgstr ""
+
+#: elf32-tic6x.c:3868
+msgid "warning: %B and %B differ in whether code is compiled for DSBT"
+msgstr ""
+
+#: elf32-v850.c:157
+#, c-format
+msgid "Variable `%s' cannot occupy in multiple small data regions"
+msgstr ""
+
+#: elf32-v850.c:160
+#, c-format
+msgid ""
+"Variable `%s' can only be in one of the small, zero, and tiny data regions"
+msgstr ""
+
+#: elf32-v850.c:163
+#, c-format
+msgid ""
+"Variable `%s' cannot be in both small and zero data regions simultaneously"
+msgstr ""
+
+#: elf32-v850.c:166
+#, c-format
+msgid ""
+"Variable `%s' cannot be in both small and tiny data regions simultaneously"
+msgstr ""
+
+#: elf32-v850.c:169
+#, c-format
+msgid ""
+"Variable `%s' cannot be in both zero and tiny data regions simultaneously"
+msgstr ""
+
+#: elf32-v850.c:467
+msgid "FAILED to find previous HI16 reloc"
+msgstr ""
+
+#: elf32-v850.c:2293
+msgid "could not locate special linker symbol __gp"
+msgstr ""
+
+#: elf32-v850.c:2297
+msgid "could not locate special linker symbol __ep"
+msgstr ""
+
+#: elf32-v850.c:2301
+msgid "could not locate special linker symbol __ctbp"
+msgstr ""
+
+#: elf32-v850.c:2471 elf32-v850.c:2534
+msgid "%B: Architecture mismatch with previous modules"
+msgstr ""
+
+#: elf32-v850.c:2478
+msgid "%B: Alignment mismatch with previous modules"
+msgstr ""
+
+#. xgettext:c-format.
+#: elf32-v850.c:2553
+#, c-format
+msgid "private flags = %lx: "
+msgstr ""
+
+#: elf32-v850.c:2558
+#, c-format
+msgid "unknown v850 architecture"
+msgstr ""
+
+#: elf32-v850.c:2560
+#, c-format
+msgid "v850 E3 architecture"
+msgstr ""
+
+#: elf32-v850.c:2562 elf32-v850.c:2572
+#, c-format
+msgid "v850 architecture"
+msgstr ""
+
+#: elf32-v850.c:2565
+#, c-format
+msgid ", 8-byte data alignment"
+msgstr ""
+
+#: elf32-v850.c:2573
+#, c-format
+msgid "v850e architecture"
+msgstr ""
+
+#: elf32-v850.c:2574
+#, c-format
+msgid "v850e1 architecture"
+msgstr ""
+
+#: elf32-v850.c:2575
+#, c-format
+msgid "v850e2 architecture"
+msgstr ""
+
+#: elf32-v850.c:2576
+#, c-format
+msgid "v850e2v3 architecture"
+msgstr ""
+
+#: elf32-v850.c:2577
+#, c-format
+msgid "v850e3v5 architecture"
+msgstr ""
+
+#: elf32-vax.c:532
+#, c-format
+msgid " [nonpic]"
+msgstr ""
+
+#: elf32-vax.c:535
+#, c-format
+msgid " [d-float]"
+msgstr ""
+
+#: elf32-vax.c:538
+#, c-format
+msgid " [g-float]"
+msgstr ""
+
+#: elf32-vax.c:656
+#, c-format
+msgid ""
+"%s: warning: GOT addend of %ld to `%s' does not match previous GOT addend of "
+"%ld"
+msgstr ""
+
+#: elf32-vax.c:1543
+#, c-format
+msgid "%s: warning: PLT addend of %d to `%s' from %s section ignored"
+msgstr ""
+
+#: elf32-vax.c:1668
+#, c-format
+msgid "%s: warning: %s relocation against symbol `%s' from %s section"
+msgstr ""
+
+#: elf32-vax.c:1674
+#, c-format
+msgid "%s: warning: %s relocation to 0x%x from %s section"
+msgstr ""
+
+#: elf32-xgate.c:686
+#, c-format
+msgid "cpu=XGATE]"
+msgstr ""
+
+#: elf32-xgate.c:688
+#, c-format
+msgid "error reading cpu type from elf private data"
+msgstr ""
+
+#: elf32-xstormy16.c:455 elf64-ia64-vms.c:2072 elf32-ia64.c:2330
+#: elf64-ia64.c:2330
+msgid "non-zero addend in @fptr reloc"
+msgstr ""
+
+#: elf32-xtensa.c:908
+msgid "%B(%A): invalid property table"
+msgstr ""
+
+#: elf32-xtensa.c:2774
+msgid "%B(%A+0x%lx): relocation offset out of range (size=0x%x)"
+msgstr ""
+
+#: elf32-xtensa.c:2853 elf32-xtensa.c:2974
+msgid "dynamic relocation in read-only section"
+msgstr ""
+
+#: elf32-xtensa.c:2950
+msgid "TLS relocation invalid without dynamic sections"
+msgstr ""
+
+#: elf32-xtensa.c:3169
+msgid "internal inconsistency in size of .got.loc section"
+msgstr ""
+
+#: elf32-xtensa.c:3482
+msgid "%B: incompatible machine type. Output is 0x%x. Input is 0x%x"
+msgstr ""
+
+#: elf32-xtensa.c:4713 elf32-xtensa.c:4721
+msgid "Attempt to convert L32R/CALLX to CALL failed"
+msgstr ""
+
+#: elf32-xtensa.c:6330 elf32-xtensa.c:6406 elf32-xtensa.c:7522
+msgid ""
+"%B(%A+0x%lx): could not decode instruction; possible configuration mismatch"
+msgstr ""
+
+#: elf32-xtensa.c:7262
+msgid ""
+"%B(%A+0x%lx): could not decode instruction for XTENSA_ASM_SIMPLIFY "
+"relocation; possible configuration mismatch"
+msgstr ""
+
+#: elf32-xtensa.c:9022
+msgid "invalid relocation address"
+msgstr ""
+
+#: elf32-xtensa.c:9071
+msgid "overflow after relaxation"
+msgstr ""
+
+#: elf32-xtensa.c:10203
+msgid "%B(%A+0x%lx): unexpected fix for %s relocation"
+msgstr ""
+
+#: elf64-alpha.c:474
+msgid "GPDISP relocation did not find ldah and lda instructions"
+msgstr ""
+
+#: elf64-alpha.c:2503
+msgid "%B: .got subsegment exceeds 64K (size %d)"
+msgstr ""
+
+#: elf64-alpha.c:4396 elf64-alpha.c:4408
+msgid "%B: gp-relative relocation against dynamic symbol %s"
+msgstr ""
+
+#: elf64-alpha.c:4434 elf64-alpha.c:4574
+msgid "%B: pc-relative relocation against dynamic symbol %s"
+msgstr ""
+
+#: elf64-alpha.c:4462
+msgid "%B: change in gp: BRSGP %s"
+msgstr ""
+
+#: elf64-alpha.c:4487
+msgid "<unknown>"
+msgstr ""
+
+#: elf64-alpha.c:4492
+msgid "%B: !samegp reloc against symbol without .prologue: %s"
+msgstr ""
+
+#: elf64-alpha.c:4549
+msgid "%B: unhandled dynamic relocation against %s"
+msgstr ""
+
+#: elf64-alpha.c:4581
+msgid "%B: pc-relative relocation against undefined weak symbol %s"
+msgstr ""
+
+#: elf64-alpha.c:4645
+msgid "%B: dtp-relative relocation against dynamic symbol %s"
+msgstr ""
+
+#: elf64-alpha.c:4668
+msgid "%B: tp-relative relocation against dynamic symbol %s"
+msgstr ""
+
+#: elf64-hppa.c:2084
+#, c-format
+msgid "stub entry for %s cannot load .plt, dp offset = %ld"
+msgstr ""
+
+#: elf64-hppa.c:3280
+msgid "%B(%A+0x%"
+msgstr ""
+
+#: elf64-ia64-vms.c:587 elf32-ia64.c:619 elf64-ia64.c:619
+msgid ""
+"%B: Can't relax br at 0x%lx in section `%A'. Please use brl or indirect "
+"branch."
+msgstr ""
+
+#: elf64-ia64-vms.c:2027 elf32-ia64.c:2278 elf64-ia64.c:2278
+msgid "@pltoff reloc against local symbol"
+msgstr ""
+
+#: elf64-ia64-vms.c:3279 elf32-ia64.c:3684 elf64-ia64.c:3684
+#, c-format
+msgid "%s: short data segment overflowed (0x%lx >= 0x400000)"
+msgstr ""
+
+#: elf64-ia64-vms.c:3290 elf32-ia64.c:3695 elf64-ia64.c:3695
+#, c-format
+msgid "%s: __gp does not cover short data segment"
+msgstr ""
+
+#: elf64-ia64-vms.c:3555 elf32-ia64.c:3962 elf64-ia64.c:3962
+msgid "%B: non-pic code with imm relocation against dynamic symbol `%s'"
+msgstr ""
+
+#: elf64-ia64-vms.c:3617 elf32-ia64.c:4029 elf64-ia64.c:4029
+msgid "%B: @gprel relocation against dynamic symbol %s"
+msgstr ""
+
+#: elf64-ia64-vms.c:3676 elf32-ia64.c:4092 elf64-ia64.c:4092
+msgid "%B: linking non-pic code in a position independent executable"
+msgstr ""
+
+#: elf64-ia64-vms.c:3777 elf32-ia64.c:4229 elf64-ia64.c:4229
+msgid "%B: @internal branch to dynamic symbol %s"
+msgstr ""
+
+#: elf64-ia64-vms.c:3779 elf32-ia64.c:4231 elf64-ia64.c:4231
+msgid "%B: speculation fixup to dynamic symbol %s"
+msgstr ""
+
+#: elf64-ia64-vms.c:3781 elf32-ia64.c:4233 elf64-ia64.c:4233
+msgid "%B: @pcrel relocation against dynamic symbol %s"
+msgstr ""
+
+#: elf64-ia64-vms.c:3905 elf32-ia64.c:4430 elf64-ia64.c:4430
+msgid "unsupported reloc"
+msgstr ""
+
+#: elf64-ia64-vms.c:3942 elf32-ia64.c:4468 elf64-ia64.c:4468
+msgid ""
+"%B: missing TLS section for relocation %s against `%s' at 0x%lx in section `"
+"%A'."
+msgstr ""
+
+#: elf64-ia64-vms.c:3957 elf32-ia64.c:4483 elf64-ia64.c:4483
+msgid ""
+"%B: Can't relax br (%s) to `%s' at 0x%lx in section `%A' with size 0x%lx (> "
+"0x1000000)."
+msgstr ""
+
+#: elf64-ia64-vms.c:4246 elf32-ia64.c:4745 elf64-ia64.c:4745
+msgid "%B: linking trap-on-NULL-dereference with non-trapping files"
+msgstr ""
+
+#: elf64-ia64-vms.c:4255 elf32-ia64.c:4754 elf64-ia64.c:4754
+msgid "%B: linking big-endian files with little-endian files"
+msgstr ""
+
+#: elf64-ia64-vms.c:4264 elf32-ia64.c:4763 elf64-ia64.c:4763
+msgid "%B: linking 64-bit files with 32-bit files"
+msgstr ""
+
+#: elf64-ia64-vms.c:4273 elf32-ia64.c:4772 elf64-ia64.c:4772
+msgid "%B: linking constant-gp files with non-constant-gp files"
+msgstr ""
+
+#: elf64-ia64-vms.c:4283 elf32-ia64.c:4782 elf64-ia64.c:4782
+msgid "%B: linking auto-pic files with non-auto-pic files"
+msgstr ""
+
+#: elf64-ia64-vms.c:5125 elflink.c:4299
+msgid ""
+"Warning: alignment %u of common symbol `%s' in %B is greater than the "
+"alignment (%u) of its section %A"
+msgstr ""
+
+#: elf64-ia64-vms.c:5131 elflink.c:4305
+msgid "Warning: alignment %u of symbol `%s' in %B is smaller than %u in %B"
+msgstr ""
+
+#: elf64-ia64-vms.c:5146 elflink.c:4321
+msgid "Warning: size of symbol `%s' changed from %lu in %B to %lu in %B"
+msgstr ""
+
+#: elf64-mmix.c:986
+msgid ""
+"invalid input relocation when producing non-ELF, non-mmo format output.\n"
+" Please use the objcopy program to convert from ELF or mmo,\n"
+" or assemble using \"-no-expand\" (for gcc, \"-Wa,-no-expand\""
+msgstr ""
+
+#: elf64-mmix.c:1170
+msgid ""
+"invalid input relocation when producing non-ELF, non-mmo format output.\n"
+" Please use the objcopy program to convert from ELF or mmo,\n"
+" or compile using the gcc-option \"-mno-base-addresses\"."
+msgstr ""
+
+#: elf64-mmix.c:1196
+#, c-format
+msgid ""
+"%s: Internal inconsistency error for value for\n"
+" linker-allocated global register: linked: 0x%lx%08lx != relaxed: 0x%lx"
+"%08lx\n"
+msgstr ""
+
+#: elf64-mmix.c:1618
+#, c-format
+msgid ""
+"%s: base-plus-offset relocation against register symbol: (unknown) in %s"
+msgstr ""
+
+#: elf64-mmix.c:1623
+#, c-format
+msgid "%s: base-plus-offset relocation against register symbol: %s in %s"
+msgstr ""
+
+#: elf64-mmix.c:1667
+#, c-format
+msgid "%s: register relocation against non-register symbol: (unknown) in %s"
+msgstr ""
+
+#: elf64-mmix.c:1672
+#, c-format
+msgid "%s: register relocation against non-register symbol: %s in %s"
+msgstr ""
+
+#: elf64-mmix.c:1709
+#, c-format
+msgid "%s: directive LOCAL valid only with a register or absolute value"
+msgstr ""
+
+#: elf64-mmix.c:1739
+#, c-format
+msgid ""
+"%s: LOCAL directive: Register $%ld is not a local register. First global "
+"register is $%ld."
+msgstr ""
+
+#: elf64-mmix.c:2198
+#, c-format
+msgid ""
+"%s: Error: multiple definition of `%s'; start of %s is set in a earlier "
+"linked file\n"
+msgstr ""
+
+#: elf64-mmix.c:2252
+msgid "Register section has contents\n"
+msgstr ""
+
+#: elf64-mmix.c:2441
+#, c-format
+msgid ""
+"Internal inconsistency: remaining %u != max %u.\n"
+" Please report this bug."
+msgstr ""
+
+#: elf64-ppc.c:4463
+msgid "%P: %B: cannot create stub entry %s\n"
+msgstr ""
+
+#: elf64-ppc.c:4810
+msgid "%P: symbol '%s' has invalid st_other for ABI version 1\n"
+msgstr ""
+
+#: elf64-ppc.c:5170
+msgid "%P: .opd not allowed in ABI version %d\n"
+msgstr ""
+
+#: elf64-ppc.c:5809
+msgid "%B uses unknown e_flags 0x%lx"
+msgstr ""
+
+#: elf64-ppc.c:5816
+msgid "%B: ABI version %ld is not compatible with ABI version %ld output"
+msgstr ""
+
+#: elf64-ppc.c:5843
+#, c-format
+msgid " [abiv%ld]"
+msgstr ""
+
+#: elf64-ppc.c:7007
+msgid ""
+"%P: copy reloc against `%T' requires lazy plt linking; avoid setting "
+"LD_BIND_NOW=1 or upgrade gcc\n"
+msgstr ""
+
+#: elf64-ppc.c:7270
+msgid "%B: undefined symbol on R_PPC64_TOCSAVE relocation"
+msgstr ""
+
+#: elf64-ppc.c:7499
+msgid "%P: dynreloc miscount for %B, section %A\n"
+msgstr ""
+
+#: elf64-ppc.c:7583
+msgid "%B: .opd is not a regular array of opd entries"
+msgstr ""
+
+#: elf64-ppc.c:7592
+msgid "%B: unexpected reloc type %u in .opd section"
+msgstr ""
+
+#: elf64-ppc.c:7613
+msgid "%B: undefined sym `%s' in .opd section"
+msgstr ""
+
+#: elf64-ppc.c:8177
+msgid "%H __tls_get_addr lost arg, TLS optimization disabled\n"
+msgstr ""
+
+#: elf64-ppc.c:8516 elf64-ppc.c:9139
+#, c-format
+msgid "%s defined on removed toc entry"
+msgstr ""
+
+#: elf64-ppc.c:8868
+msgid "%P: %H: toc optimization is not supported for %s instruction.\n"
+msgstr ""
+
+#: elf64-ppc.c:9096
+msgid "%P: %H: %s references optimized away TOC entry\n"
+msgstr ""
+
+#: elf64-ppc.c:10394
+msgid "%P: cannot find opd entry toc for `%T'\n"
+msgstr ""
+
+#: elf64-ppc.c:10479
+msgid "%P: long branch stub `%s' offset overflow\n"
+msgstr ""
+
+#: elf64-ppc.c:10538
+msgid "%P: can't find branch stub `%s'\n"
+msgstr ""
+
+#: elf64-ppc.c:10602 elf64-ppc.c:10749 elf64-ppc.c:12416
+msgid "%P: linkage table error against `%T'\n"
+msgstr ""
+
+#: elf64-ppc.c:10940
+msgid "%P: can't build branch stub `%s'\n"
+msgstr ""
+
+#: elf64-ppc.c:11748
+msgid "%B section %A exceeds stub group size"
+msgstr ""
+
+#: elf64-ppc.c:12662 elf64-ppc.c:12697
+msgid "%P: %s offset too large for .eh_frame sdata4 encoding"
+msgstr ""
+
+#: elf64-ppc.c:12758
+msgid "%P: stubs don't match calculated size\n"
+msgstr ""
+
+#: elf64-ppc.c:12770
+#, c-format
+msgid ""
+"linker stubs in %u group%s\n"
+" branch %lu\n"
+" toc adjust %lu\n"
+" long branch %lu\n"
+" long toc adj %lu\n"
+" plt call %lu\n"
+" plt call toc %lu"
+msgstr ""
+
+#: elf64-ppc.c:13096
+msgid "%P: %H: %s used with TLS symbol `%T'\n"
+msgstr ""
+
+#: elf64-ppc.c:13097
+msgid "%P: %H: %s used with non-TLS symbol `%T'\n"
+msgstr ""
+
+#: elf64-ppc.c:13675
+msgid ""
+"%P: %H: call to `%T' lacks nop, can't restore toc; recompile with -fPIC\n"
+msgstr ""
+
+#: elf64-ppc.c:13793
+msgid "%P: %B: unknown relocation type %d for `%T'\n"
+msgstr ""
+
+#: elf64-ppc.c:14310
+msgid "%P: %H: %s for indirect function `%T' unsupported\n"
+msgstr ""
+
+#: elf64-ppc.c:14417
+msgid "%P: %B: %s is not supported for `%T'\n"
+msgstr ""
+
+#: elf64-ppc.c:14565
+msgid "%P: %H: error: %s not a multiple of %u\n"
+msgstr ""
+
+#: elf64-ppc.c:14586
+msgid "%P: %H: unresolvable %s against `%T'\n"
+msgstr ""
+
+#: elf64-ppc.c:14644
+msgid "%P: %H: %s against `%T': error %d\n"
+msgstr ""
+
+#: elf64-sh64.c:1686
+#, c-format
+msgid "%s: error: unaligned relocation type %d at %08x reloc %08x\n"
+msgstr ""
+
+#: elf64-sparc.c:446
+msgid "%B: Only registers %%g[2367] can be declared using STT_REGISTER"
+msgstr ""
+
+#: elf64-sparc.c:466
+msgid "Register %%g%d used incompatibly: %s in %B, previously %s in %B"
+msgstr ""
+
+#: elf64-sparc.c:489
+msgid "Symbol `%s' has differing types: REGISTER in %B, previously %s in %B"
+msgstr ""
+
+#: elf64-sparc.c:534
+msgid "Symbol `%s' has differing types: %s in %B, previously REGISTER in %B"
+msgstr ""
+
+#: elf64-sparc.c:687
+msgid "%B: linking UltraSPARC specific with HAL specific code"
+msgstr ""
+
+#: elf64-x86-64.c:1530
+msgid "%B: relocation %s against symbol `%s' isn't supported in x32 mode"
+msgstr ""
+
+#: elf64-x86-64.c:1688
+msgid "%B: '%s' accessed both as normal and thread local symbol"
+msgstr ""
+
+#: elf64-x86-64.c:3405 /src/binutils-gdb/bfd/elfnn-aarch64.c:3511
+msgid ""
+"%B: relocation %s against STT_GNU_IFUNC symbol `%s' has non-zero addend: %d"
+msgstr ""
+
+#: elf64-x86-64.c:3667
+msgid ""
+"%B: relocation R_X86_64_GOTOFF64 against protected function `%s' can not be "
+"used when making a shared object"
+msgstr ""
+
+#: elf64-x86-64.c:3787
+msgid "; recompile with -fPIC"
+msgstr ""
+
+#: elf64-x86-64.c:3792
+msgid ""
+"%B: relocation %s against %s `%s' can not be used when making a shared object"
+"%s"
+msgstr ""
+
+#: elf64-x86-64.c:3794
+msgid ""
+"%B: relocation %s against undefined %s `%s' can not be used when making a "
+"shared object%s"
+msgstr ""
+
+#: elf64-x86-64.c:3900
+msgid ""
+"%B: addend -0x%x in relocation %s against symbol `%s' at 0x%lx in section `"
+"%A' is out of range"
+msgstr ""
+
+#: elf64-x86-64.c:3908
+msgid ""
+"%B: addend 0x%x in relocation %s against symbol `%s' at 0x%lx in section `"
+"%A' is out of range"
+msgstr ""
+
+#: elfcode.h:760
+#, c-format
+msgid "warning: %s has a corrupt string table index - ignoring"
+msgstr ""
+
+#: elfcode.h:1186
+#, c-format
+msgid "%s: version count (%ld) does not match symbol count (%ld)"
+msgstr ""
+
+#: elfcode.h:1440
+#, c-format
+msgid "%s(%s): relocation %d has invalid symbol index %ld"
+msgstr ""
+
+#: elfcore.h:305
+msgid "Warning: %B is truncated: expected core file size >= %lu, found: %lu."
+msgstr ""
+
+#: elflink.c:1143
+msgid ""
+"%s: TLS definition in %B section %A mismatches non-TLS definition in %B "
+"section %A"
+msgstr ""
+
+#: elflink.c:1148
+msgid "%s: TLS reference in %B mismatches non-TLS reference in %B"
+msgstr ""
+
+#: elflink.c:1153
+msgid "%s: TLS definition in %B section %A mismatches non-TLS reference in %B"
+msgstr ""
+
+#: elflink.c:1158
+msgid "%s: TLS reference in %B mismatches non-TLS definition in %B section %A"
+msgstr ""
+
+#: elflink.c:1763
+msgid "%B: unexpected redefinition of indirect versioned symbol `%s'"
+msgstr ""
+
+#: elflink.c:2066
+msgid "%B: version node not found for symbol %s"
+msgstr ""
+
+#: elflink.c:2157
+msgid ""
+"%B: bad reloc symbol index (0x%lx >= 0x%lx) for offset 0x%lx in section `%A'"
+msgstr ""
+
+#: elflink.c:2168
+msgid ""
+"%B: non-zero symbol index (0x%lx) for offset 0x%lx in section `%A' when the "
+"object file has no symbol table"
+msgstr ""
+
+#: elflink.c:2358
+msgid "%B: relocation size mismatch in %B section %A"
+msgstr ""
+
+#: elflink.c:2640
+#, c-format
+msgid "warning: type and size of dynamic symbol `%s' are not defined"
+msgstr ""
+
+#: elflink.c:3403
+msgid "%P: alternate ELF machine code found (%d) in %B, expecting %d\n"
+msgstr ""
+
+#: elflink.c:4032
+msgid "%B: %s: invalid version %u (max %d)"
+msgstr ""
+
+#: elflink.c:4068
+msgid "%B: %s: invalid needed version %d"
+msgstr ""
+
+#: elflink.c:4452
+msgid "%B: undefined reference to symbol '%s'"
+msgstr ""
+
+#: elflink.c:5523
+msgid "%B: stack size specified and %s set"
+msgstr ""
+
+#: elflink.c:5526
+msgid "%B: %s not absolute"
+msgstr ""
+
+#: elflink.c:5824
+#, c-format
+msgid "%s: undefined version: %s"
+msgstr ""
+
+#: elflink.c:5892
+msgid "%B: .preinit_array section is not allowed in DSO"
+msgstr ""
+
+#: elflink.c:7657
+#, c-format
+msgid "undefined %s reference in complex symbol: %s"
+msgstr ""
+
+#: elflink.c:7811
+#, c-format
+msgid "unknown operator '%c' in complex symbol"
+msgstr ""
+
+#: elflink.c:8165 elflink.c:8182 elflink.c:8219 elflink.c:8236
+msgid "%B: Unable to sort relocs - they are in more than one size"
+msgstr ""
+
+#: elflink.c:8196 elflink.c:8250
+msgid "%B: Unable to sort relocs - they are of an unknown size"
+msgstr ""
+
+#: elflink.c:8301
+msgid "Not enough memory to sort relocations"
+msgstr ""
+
+#: elflink.c:8494
+msgid "%B: Too many sections: %d (>= %d)"
+msgstr ""
+
+#: elflink.c:8775
+msgid "%B: internal symbol `%s' in %B is referenced by DSO"
+msgstr ""
+
+#: elflink.c:8777
+msgid "%B: hidden symbol `%s' in %B is referenced by DSO"
+msgstr ""
+
+#: elflink.c:8779
+msgid "%B: local symbol `%s' in %B is referenced by DSO"
+msgstr ""
+
+#: elflink.c:8890
+msgid "%B: could not find output section %A for input section %A"
+msgstr ""
+
+#: elflink.c:9013
+msgid "%B: protected symbol `%s' isn't defined"
+msgstr ""
+
+#: elflink.c:9015
+msgid "%B: internal symbol `%s' isn't defined"
+msgstr ""
+
+#: elflink.c:9017
+msgid "%B: hidden symbol `%s' isn't defined"
+msgstr ""
+
+#: elflink.c:9043
+msgid "%B: No symbol version section for versioned symbol `%s'"
+msgstr ""
+
+#: elflink.c:9598
+msgid "error: %B: size of section %A is not multiple of address size"
+msgstr ""
+
+#: elflink.c:9645
+msgid ""
+"error: %B contains a reloc (0x%s) for section %A that references a non-"
+"existent global symbol"
+msgstr ""
+
+#: elflink.c:10369
+msgid "%A has both ordered [`%A' in %B] and unordered [`%A' in %B] sections"
+msgstr ""
+
+#: elflink.c:10374
+#, c-format
+msgid "%A has both ordered and unordered sections"
+msgstr ""
+
+#: elflink.c:10982
+msgid "%B: file class %s incompatible with %s"
+msgstr ""
+
+#: elflink.c:11303 elflink.c:11347
+msgid "%B: could not find output section %s"
+msgstr ""
+
+#: elflink.c:11308
+#, c-format
+msgid "warning: %s section has zero size"
+msgstr ""
+
+#: elflink.c:11353
+#, c-format
+msgid "warning: section '%s' is being made into a note"
+msgstr ""
+
+#: elflink.c:11419
+msgid "%P%X: read-only segment has dynamic relocations.\n"
+msgstr ""
+
+#: elflink.c:11422
+msgid "%P: warning: creating a DT_TEXTREL in a shared object.\n"
+msgstr ""
+
+#: elflink.c:11545
+msgid "%P%X: can not read symbols: %E\n"
+msgstr ""
+
+#: elflink.c:11989
+msgid "Removing unused section '%s' in file '%B'"
+msgstr ""
+
+#: elflink.c:12200
+msgid "Warning: gc-sections option ignored"
+msgstr ""
+
+#: elflink.c:12489
+#, c-format
+msgid "Unrecognized INPUT_SECTION_FLAG %s\n"
+msgstr ""
+
+#: elfxx-mips.c:1419
+msgid "static procedure (no name)"
+msgstr ""
+
+#: elfxx-mips.c:5476
+msgid "MIPS16 and microMIPS functions cannot call each other"
+msgstr ""
+
+#: elfxx-mips.c:6087
+msgid ""
+"%B: %A+0x%lx: Unsupported jump between ISA modes; consider recompiling with "
+"interlinking enabled."
+msgstr ""
+
+#: elfxx-mips.c:6756 elfxx-mips.c:6979
+msgid "%B: Warning: bad `%s' option size %u smaller than its header"
+msgstr ""
+
+#: elfxx-mips.c:7734 elfxx-mips.c:7859
+msgid "%B: Warning: cannot determine the target function for stub section `%s'"
+msgstr ""
+
+#: elfxx-mips.c:7990
+msgid "%B: Malformed reloc detected for section %s"
+msgstr ""
+
+#: elfxx-mips.c:8065
+msgid "%B: GOT reloc at 0x%lx not expected in executables"
+msgstr ""
+
+#: elfxx-mips.c:8199
+msgid "%B: CALL16 reloc at 0x%lx not against global symbol"
+msgstr ""
+
+#: elfxx-mips.c:8977
+#, c-format
+msgid "non-dynamic relocations refer to dynamic symbol %s"
+msgstr ""
+
+#: elfxx-mips.c:9877
+msgid ""
+"%B: Can't find matching LO16 reloc against `%s' for %s at 0x%lx in section `"
+"%A'"
+msgstr ""
+
+#: elfxx-mips.c:10016
+msgid ""
+"small-data section exceeds 64KB; lower small-data size limit (see option -G)"
+msgstr ""
+
+#: elfxx-mips.c:10035
+msgid "JALX to a non-word-aligned address"
+msgstr ""
+
+#: elfxx-mips.c:10402 elfxx-mips.c:10966
+msgid "%B: `%A' offset of %ld from `%A' beyond the range of ADDIUPC"
+msgstr ""
+
+#: elfxx-mips.c:13990
+#, c-format
+msgid "%s: illegal section name `%s'"
+msgstr ""
+
+#: elfxx-mips.c:14375 elfxx-mips.c:14381 elfxx-mips.c:14387 elfxx-mips.c:14407
+#: elfxx-mips.c:14413 elfxx-mips.c:14419 elfxx-mips.c:14441 elfxx-mips.c:14460
+#: elfxx-mips.c:14467 elfxx-mips.c:14474
+msgid "Warning: %B uses %s (set by %B), %B uses %s"
+msgstr ""
+
+#: elfxx-mips.c:14394 elfxx-mips.c:14426 elfxx-mips.c:14447 elfxx-mips.c:14480
+msgid "Warning: %B uses %s (set by %B), %B uses unknown floating point ABI %d"
+msgstr ""
+
+#: elfxx-mips.c:14493 elfxx-mips.c:14501 elfxx-mips.c:14509 elfxx-mips.c:14517
+msgid "Warning: %B uses unknown floating point ABI %d (set by %B), %B uses %s"
+msgstr ""
+
+#: elfxx-mips.c:14525
+msgid ""
+"Warning: %B uses unknown floating point ABI %d (set by %B), %B uses unknown "
+"floating point ABI %d"
+msgstr ""
+
+#: elfxx-mips.c:14548
+msgid "Warning: %B uses %s (set by %B), %B uses unknown MSA ABI %d"
+msgstr ""
+
+#: elfxx-mips.c:14559
+msgid "Warning: %B uses unknown MSA ABI %d (set by %B), %B uses %s"
+msgstr ""
+
+#: elfxx-mips.c:14567
+msgid ""
+"Warning: %B uses unknown MSA ABI %d (set by %B), %B uses unknown MSA ABI %d"
+msgstr ""
+
+#: elfxx-mips.c:14599
+msgid "%B: endianness incompatible with that of the selected emulation"
+msgstr ""
+
+#: elfxx-mips.c:14610
+msgid "%B: ABI is incompatible with that of the selected emulation"
+msgstr ""
+
+#: elfxx-mips.c:14694
+msgid "%B: warning: linking abicalls files with non-abicalls files"
+msgstr ""
+
+#: elfxx-mips.c:14711
+msgid "%B: linking 32-bit code with 64-bit code"
+msgstr ""
+
+#: elfxx-mips.c:14739 elfxx-mips.c:14802
+msgid "%B: linking %s module with previous %s modules"
+msgstr ""
+
+#: elfxx-mips.c:14762
+msgid "%B: ABI mismatch: linking %s module with previous %s modules"
+msgstr ""
+
+#: elfxx-mips.c:14786
+msgid "%B: ASE mismatch: linking %s module with previous %s modules"
+msgstr ""
+
+#: elfxx-mips.c:14958
+#, c-format
+msgid " [abi=O32]"
+msgstr ""
+
+#: elfxx-mips.c:14960
+#, c-format
+msgid " [abi=O64]"
+msgstr ""
+
+#: elfxx-mips.c:14962
+#, c-format
+msgid " [abi=EABI32]"
+msgstr ""
+
+#: elfxx-mips.c:14964
+#, c-format
+msgid " [abi=EABI64]"
+msgstr ""
+
+#: elfxx-mips.c:14966
+#, c-format
+msgid " [abi unknown]"
+msgstr ""
+
+#: elfxx-mips.c:14968
+#, c-format
+msgid " [abi=N32]"
+msgstr ""
+
+#: elfxx-mips.c:14970
+#, c-format
+msgid " [abi=64]"
+msgstr ""
+
+#: elfxx-mips.c:14972
+#, c-format
+msgid " [no abi set]"
+msgstr ""
+
+#: elfxx-mips.c:14993
+#, c-format
+msgid " [unknown ISA]"
+msgstr ""
+
+#: elfxx-mips.c:15013
+#, c-format
+msgid " [not 32bitmode]"
+msgstr ""
+
+#: elfxx-sparc.c:640
+#, c-format
+msgid "invalid relocation type %d"
+msgstr ""
+
+#: elfxx-tilegx.c:4433
+msgid "%B: Cannot link together %s and %s objects."
+msgstr ""
+
+#: i386linux.c:418 m68klinux.c:421 sparclinux.c:414
+#, c-format
+msgid "Output file requires shared library `%s'\n"
+msgstr ""
+
+#: i386linux.c:426 m68klinux.c:429 sparclinux.c:422
+#, c-format
+msgid "Output file requires shared library `%s.so.%s'\n"
+msgstr ""
+
+#: i386linux.c:613 i386linux.c:663 m68klinux.c:618 m68klinux.c:666
+#: sparclinux.c:609 sparclinux.c:659
+#, c-format
+msgid "Symbol %s not defined for fixups\n"
+msgstr ""
+
+#: i386linux.c:687 m68klinux.c:690 sparclinux.c:683
+msgid "Warning: fixup count mismatch\n"
+msgstr ""
+
+#: ieee.c:158
+#, c-format
+msgid "%s: string too long (%d chars, max 65535)"
+msgstr ""
+
+#: ieee.c:285
+#, c-format
+msgid "%s: unrecognized symbol `%s' flags 0x%x"
+msgstr ""
+
+#: ieee.c:791
+msgid "%B: unimplemented ATI record %u for symbol %u"
+msgstr ""
+
+#: ieee.c:815
+msgid "%B: unexpected ATN type %d in external part"
+msgstr ""
+
+#: ieee.c:837
+msgid "%B: unexpected type after ATN"
+msgstr ""
+
+#: ihex.c:230
+msgid "%B:%d: unexpected character `%s' in Intel Hex file"
+msgstr ""
+
+#: ihex.c:337
+msgid "%B:%u: bad checksum in Intel Hex file (expected %u, found %u)"
+msgstr ""
+
+#: ihex.c:392
+msgid "%B:%u: bad extended address record length in Intel Hex file"
+msgstr ""
+
+#: ihex.c:409
+msgid "%B:%u: bad extended start address length in Intel Hex file"
+msgstr ""
+
+#: ihex.c:426
+msgid "%B:%u: bad extended linear address record length in Intel Hex file"
+msgstr ""
+
+#: ihex.c:443
+msgid "%B:%u: bad extended linear start address length in Intel Hex file"
+msgstr ""
+
+#: ihex.c:460
+msgid "%B:%u: unrecognized ihex type %u in Intel Hex file"
+msgstr ""
+
+#: ihex.c:579
+msgid "%B: internal error in ihex_read_section"
+msgstr ""
+
+#: ihex.c:613
+msgid "%B: bad section length in ihex_read_section"
+msgstr ""
+
+#: ihex.c:826
+#, c-format
+msgid "%s: address 0x%s out of range for Intel Hex file"
+msgstr ""
+
+#: libbfd.c:863
+msgid "%B: unable to get decompressed section %A"
+msgstr ""
+
+#: libbfd.c:1012
+msgid "%B: compiled for a big endian system and target is little endian"
+msgstr ""
+
+#: libbfd.c:1014
+msgid "%B: compiled for a little endian system and target is big endian"
+msgstr ""
+
+#: libbfd.c:1043
+#, c-format
+msgid "Deprecated %s called at %s line %d in %s\n"
+msgstr ""
+
+#: libbfd.c:1046
+#, c-format
+msgid "Deprecated %s called\n"
+msgstr ""
+
+#: linker.c:1873
+msgid "%B: indirect symbol `%s' to `%s' is a loop"
+msgstr ""
+
+#: linker.c:2750
+#, c-format
+msgid "Attempt to do relocatable link with %s input and %s output"
+msgstr ""
+
+#: linker.c:3035
+msgid "%B: ignoring duplicate section `%A'\n"
+msgstr ""
+
+#: linker.c:3044 linker.c:3053
+msgid "%B: duplicate section `%A' has different size\n"
+msgstr ""
+
+#: linker.c:3061 linker.c:3066
+msgid "%B: could not read contents of section `%A'\n"
+msgstr ""
+
+#: linker.c:3070
+msgid "%B: duplicate section `%A' has different contents\n"
+msgstr ""
+
+#: mach-o.c:648
+msgid "bfd_mach_o_canonicalize_symtab: unable to load symbols"
+msgstr ""
+
+#: mach-o.c:1918
+#, c-format
+msgid "mach-o: there are too many sections (%d) maximum is 255,\n"
+msgstr ""
+
+#: mach-o.c:2017
+#, c-format
+msgid "unable to write unknown load command 0x%lx"
+msgstr ""
+
+#: mach-o.c:2272
+msgid ""
+"sorry: modtab, toc and extrefsyms are not yet implemented for dysymtab "
+"commands."
+msgstr ""
+
+#: mach-o.c:2898
+#, c-format
+msgid "bfd_mach_o_read_symtab_symbol: unable to read %d bytes at %lu"
+msgstr ""
+
+#: mach-o.c:2916
+#, c-format
+msgid "bfd_mach_o_read_symtab_symbol: name out of range (%lu >= %lu)"
+msgstr ""
+
+#: mach-o.c:2997
+#, c-format
+msgid ""
+"bfd_mach_o_read_symtab_symbol: symbol \"%s\" specified invalid section %d "
+"(max %lu): setting to undefined"
+msgstr ""
+
+#: mach-o.c:3013
+#, c-format
+msgid ""
+"bfd_mach_o_read_symtab_symbol: symbol \"%s\" specified invalid type field 0x"
+"%x: setting to undefined"
+msgstr ""
+
+#: mach-o.c:3085
+msgid "bfd_mach_o_read_symtab_symbols: unable to allocate memory for symbols"
+msgstr ""
+
+#: mach-o.c:3915
+msgid "%B: unknown load command 0x%lx"
+msgstr ""
+
+#: mach-o.c:4107
+#, c-format
+msgid "bfd_mach_o_scan: unknown architecture 0x%lx/0x%lx"
+msgstr ""
+
+#: mach-o.c:4204
+#, c-format
+msgid "unknown header byte-order value 0x%lx"
+msgstr ""
+
+#: merge.c:832
+#, c-format
+msgid "%s: access beyond end of merged section (%ld)"
+msgstr ""
+
+#: mmo.c:455
+#, c-format
+msgid "%s: No core to allocate section name %s\n"
+msgstr ""
+
+#: mmo.c:530
+#, c-format
+msgid "%s: No core to allocate a symbol %d bytes long\n"
+msgstr ""
+
+#: mmo.c:1189
+#, c-format
+msgid "%s: invalid mmo file: initialization value for $255 is not `Main'\n"
+msgstr ""
+
+#: mmo.c:1334
+#, c-format
+msgid ""
+"%s: unsupported wide character sequence 0x%02X 0x%02X after symbol name "
+"starting with `%s'\n"
+msgstr ""
+
+#: mmo.c:1568
+#, c-format
+msgid "%s: invalid mmo file: unsupported lopcode `%d'\n"
+msgstr ""
+
+#: mmo.c:1578
+#, c-format
+msgid "%s: invalid mmo file: expected YZ = 1 got YZ = %d for lop_quote\n"
+msgstr ""
+
+#: mmo.c:1614
+#, c-format
+msgid "%s: invalid mmo file: expected z = 1 or z = 2, got z = %d for lop_loc\n"
+msgstr ""
+
+#: mmo.c:1660
+#, c-format
+msgid ""
+"%s: invalid mmo file: expected z = 1 or z = 2, got z = %d for lop_fixo\n"
+msgstr ""
+
+#: mmo.c:1699
+#, c-format
+msgid "%s: invalid mmo file: expected y = 0, got y = %d for lop_fixrx\n"
+msgstr ""
+
+#: mmo.c:1708
+#, c-format
+msgid ""
+"%s: invalid mmo file: expected z = 16 or z = 24, got z = %d for lop_fixrx\n"
+msgstr ""
+
+#: mmo.c:1731
+#, c-format
+msgid ""
+"%s: invalid mmo file: leading byte of operand word must be 0 or 1, got %d "
+"for lop_fixrx\n"
+msgstr ""
+
+#: mmo.c:1754
+#, c-format
+msgid "%s: cannot allocate file name for file number %d, %d bytes\n"
+msgstr ""
+
+#: mmo.c:1774
+#, c-format
+msgid ""
+"%s: invalid mmo file: file number %d `%s', was already entered as `%s'\n"
+msgstr ""
+
+#: mmo.c:1787
+#, c-format
+msgid ""
+"%s: invalid mmo file: file name for number %d was not specified before use\n"
+msgstr ""
+
+#: mmo.c:1893
+#, c-format
+msgid ""
+"%s: invalid mmo file: fields y and z of lop_stab non-zero, y: %d, z: %d\n"
+msgstr ""
+
+#: mmo.c:1929
+#, c-format
+msgid "%s: invalid mmo file: lop_end not last item in file\n"
+msgstr ""
+
+#: mmo.c:1942
+#, c-format
+msgid ""
+"%s: invalid mmo file: YZ of lop_end (%ld) not equal to the number of tetras "
+"to the preceding lop_stab (%ld)\n"
+msgstr ""
+
+#: mmo.c:2652
+#, c-format
+msgid "%s: invalid symbol table: duplicate symbol `%s'\n"
+msgstr ""
+
+#: mmo.c:2892
+#, c-format
+msgid ""
+"%s: Bad symbol definition: `Main' set to %s rather than the start address "
+"%s\n"
+msgstr ""
+
+#: mmo.c:2984
+#, c-format
+msgid ""
+"%s: warning: symbol table too large for mmo, larger than 65535 32-bit words: "
+"%d. Only `Main' will be emitted.\n"
+msgstr ""
+
+#: mmo.c:3029
+#, c-format
+msgid "%s: internal error, symbol table changed size from %d to %d words\n"
+msgstr ""
+
+#: mmo.c:3081
+#, c-format
+msgid "%s: internal error, internal register section %s had contents\n"
+msgstr ""
+
+#: mmo.c:3132
+#, c-format
+msgid "%s: no initialized registers; section length 0\n"
+msgstr ""
+
+#: mmo.c:3138
+#, c-format
+msgid "%s: too many initialized registers; section length %ld\n"
+msgstr ""
+
+#: mmo.c:3143
+#, c-format
+msgid ""
+"%s: invalid start address for initialized registers of length %ld: 0x%lx"
+"%08lx\n"
+msgstr ""
+
+#: oasys.c:881
+#, c-format
+msgid "%s: can not represent section `%s' in oasys"
+msgstr ""
+
+#: osf-core.c:128
+#, c-format
+msgid "Unhandled OSF/1 core file section type %d\n"
+msgstr ""
+
+#: pe-mips.c:607
+msgid "%B: `ld -r' not supported with PE MIPS objects\n"
+msgstr ""
+
+#. OK, at this point the following variables are set up:
+#. src = VMA of the memory we're fixing up
+#. mem = pointer to memory we're fixing up
+#. val = VMA of what we need to refer to.
+#: pe-mips.c:719
+msgid "%B: unimplemented %s\n"
+msgstr ""
+
+#: pe-mips.c:745
+msgid "%B: jump too far away\n"
+msgstr ""
+
+#: pe-mips.c:771
+msgid "%B: bad pair/reflo after refhi\n"
+msgstr ""
+
+#: pef.c:522
+#, c-format
+msgid "bfd_pef_scan: unknown architecture 0x%lx"
+msgstr ""
+
+#: pei-x86_64.c:469
+#, c-format
+msgid "warning: .pdata section size (%ld) is not a multiple of %d\n"
+msgstr ""
+
+#: pei-x86_64.c:474 peigen.c:1626 peigen.c:1809 pepigen.c:1626 pepigen.c:1809
+#: pex64igen.c:1626 pex64igen.c:1809
+#, c-format
+msgid ""
+"\n"
+"The Function Table (interpreted .pdata section contents)\n"
+msgstr ""
+
+#: pei-x86_64.c:476
+#, c-format
+msgid "vma:\t\t\tBeginAddress\t EndAddress\t UnwindData\n"
+msgstr ""
+
+#. XXX code yet to be written.
+#: peicode.h:758
+msgid "%B: Unhandled import type; %x"
+msgstr ""
+
+#: peicode.h:763
+msgid "%B: Unrecognised import type; %x"
+msgstr ""
+
+#: peicode.h:777
+msgid "%B: Unrecognised import name type; %x"
+msgstr ""
+
+#: peicode.h:1173
+msgid "%B: Unrecognised machine type (0x%x) in Import Library Format archive"
+msgstr ""
+
+#: peicode.h:1185
+msgid ""
+"%B: Recognised but unhandled machine type (0x%x) in Import Library Format "
+"archive"
+msgstr ""
+
+#: peicode.h:1203
+msgid "%B: size field is zero in Import Library Format header"
+msgstr ""
+
+#: peicode.h:1234
+msgid "%B: string not null terminated in ILF object file."
+msgstr ""
+
+#: ppcboot.c:391
+#, c-format
+msgid ""
+"\n"
+"ppcboot header:\n"
+msgstr ""
+
+#: ppcboot.c:392
+#, c-format
+msgid "Entry offset = 0x%.8lx (%ld)\n"
+msgstr ""
+
+#: ppcboot.c:394
+#, c-format
+msgid "Length = 0x%.8lx (%ld)\n"
+msgstr ""
+
+#: ppcboot.c:398
+#, c-format
+msgid "Flag field = 0x%.2x\n"
+msgstr ""
+
+#: ppcboot.c:404
+#, c-format
+msgid "Partition name = \"%s\"\n"
+msgstr ""
+
+#: ppcboot.c:423
+#, c-format
+msgid ""
+"\n"
+"Partition[%d] start = { 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x }\n"
+msgstr ""
+
+#: ppcboot.c:429
+#, c-format
+msgid "Partition[%d] end = { 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x }\n"
+msgstr ""
+
+#: ppcboot.c:435
+#, c-format
+msgid "Partition[%d] sector = 0x%.8lx (%ld)\n"
+msgstr ""
+
+#: ppcboot.c:437
+#, c-format
+msgid "Partition[%d] length = 0x%.8lx (%ld)\n"
+msgstr ""
+
+#: reloc.c:7371
+msgid "INPUT_SECTION_FLAGS are not supported.\n"
+msgstr ""
+
+#: reloc.c:7526
+msgid "%X%P: %B(%A): relocation \"%R\" goes out of range\n"
+msgstr ""
+
+#: rs6000-core.c:448
+#, c-format
+msgid "%s: warning core file truncated"
+msgstr ""
+
+#: som.c:5471
+#, c-format
+msgid ""
+"\n"
+"Exec Auxiliary Header\n"
+msgstr ""
+
+#: som.c:5776
+msgid "som_sizeof_headers unimplemented"
+msgstr ""
+
+#: srec.c:261
+msgid "%B:%d: Unexpected character `%s' in S-record file\n"
+msgstr ""
+
+#: srec.c:567 srec.c:600
+msgid "%B:%d: Bad checksum in S-record file\n"
+msgstr ""
+
+#: stabs.c:279
+msgid "%B(%A+0x%lx): Stabs entry has invalid string index."
+msgstr ""
+
+#: syms.c:1079
+msgid "Unsupported .stab relocation"
+msgstr ""
+
+#: vms-alpha.c:1294
+#, c-format
+msgid "Unknown EGSD subtype %d"
+msgstr ""
+
+#: vms-alpha.c:1325
+#, c-format
+msgid "Stack overflow (%d) in _bfd_vms_push"
+msgstr ""
+
+#: vms-alpha.c:1338
+msgid "Stack underflow in _bfd_vms_pop"
+msgstr ""
+
+#. These names have not yet been added to this switch statement.
+#: vms-alpha.c:1575
+#, c-format
+msgid "unknown ETIR command %d"
+msgstr ""
+
+#: vms-alpha.c:1762
+#, c-format
+msgid "bad section index in %s"
+msgstr ""
+
+#: vms-alpha.c:1775
+#, c-format
+msgid "unsupported STA cmd %s"
+msgstr ""
+
+#. Insert field.
+#. Unsigned shift.
+#. Rotate.
+#. Redefine symbol to current location.
+#. Define a literal.
+#: vms-alpha.c:1951 vms-alpha.c:1982 vms-alpha.c:2229
+#, c-format
+msgid "%s: not supported"
+msgstr ""
+
+#: vms-alpha.c:1957
+#, c-format
+msgid "%s: not implemented"
+msgstr ""
+
+#: vms-alpha.c:2213
+#, c-format
+msgid "invalid use of %s with contexts"
+msgstr ""
+
+#: vms-alpha.c:2247
+#, c-format
+msgid "reserved cmd %d"
+msgstr ""
+
+#: vms-alpha.c:2332
+msgid "Object module NOT error-free !\n"
+msgstr ""
+
+#: vms-alpha.c:3657
+#, c-format
+msgid "SEC_RELOC with no relocs in section %s"
+msgstr ""
+
+#: vms-alpha.c:3709 vms-alpha.c:3922
+#, c-format
+msgid "Size error in section %s"
+msgstr ""
+
+#: vms-alpha.c:3868
+msgid "Spurious ALPHA_R_BSR reloc"
+msgstr ""
+
+#: vms-alpha.c:3909
+#, c-format
+msgid "Unhandled relocation %s"
+msgstr ""
+
+#: vms-alpha.c:4199
+#, c-format
+msgid "unknown source command %d"
+msgstr ""
+
+#: vms-alpha.c:4260
+msgid "DST__K_SET_LINUM_INCR not implemented"
+msgstr ""
+
+#: vms-alpha.c:4266
+msgid "DST__K_SET_LINUM_INCR_W not implemented"
+msgstr ""
+
+#: vms-alpha.c:4272
+msgid "DST__K_RESET_LINUM_INCR not implemented"
+msgstr ""
+
+#: vms-alpha.c:4278
+msgid "DST__K_BEG_STMT_MODE not implemented"
+msgstr ""
+
+#: vms-alpha.c:4284
+msgid "DST__K_END_STMT_MODE not implemented"
+msgstr ""
+
+#: vms-alpha.c:4311
+msgid "DST__K_SET_PC not implemented"
+msgstr ""
+
+#: vms-alpha.c:4317
+msgid "DST__K_SET_PC_W not implemented"
+msgstr ""
+
+#: vms-alpha.c:4323
+msgid "DST__K_SET_PC_L not implemented"
+msgstr ""
+
+#: vms-alpha.c:4329
+msgid "DST__K_SET_STMTNUM not implemented"
+msgstr ""
+
+#: vms-alpha.c:4372
+#, c-format
+msgid "unknown line command %d"
+msgstr ""
+
+#: vms-alpha.c:4846 vms-alpha.c:4863 vms-alpha.c:4877 vms-alpha.c:4892
+#: vms-alpha.c:4904 vms-alpha.c:4915 vms-alpha.c:4927
+#, c-format
+msgid "Unknown reloc %s + %s"
+msgstr ""
+
+#: vms-alpha.c:4982
+#, c-format
+msgid "Unknown reloc %s"
+msgstr ""
+
+#: vms-alpha.c:4995
+msgid "Invalid section index in ETIR"
+msgstr ""
+
+#: vms-alpha.c:5002
+msgid "Relocation for non-REL psect"
+msgstr ""
+
+#: vms-alpha.c:5049
+#, c-format
+msgid "Unknown symbol in command %s"
+msgstr ""
+
+#: vms-alpha.c:5564
+#, c-format
+msgid " EMH %u (len=%u): "
+msgstr ""
+
+#: vms-alpha.c:5573
+#, c-format
+msgid "Module header\n"
+msgstr ""
+
+#: vms-alpha.c:5574
+#, c-format
+msgid " structure level: %u\n"
+msgstr ""
+
+#: vms-alpha.c:5575
+#, c-format
+msgid " max record size: %u\n"
+msgstr ""
+
+#: vms-alpha.c:5578
+#, c-format
+msgid " module name : %.*s\n"
+msgstr ""
+
+#: vms-alpha.c:5580
+#, c-format
+msgid " module version : %.*s\n"
+msgstr ""
+
+#: vms-alpha.c:5582
+#, c-format
+msgid " compile date : %.17s\n"
+msgstr ""
+
+#: vms-alpha.c:5587
+#, c-format
+msgid "Language Processor Name\n"
+msgstr ""
+
+#: vms-alpha.c:5588
+#, c-format
+msgid " language name: %.*s\n"
+msgstr ""
+
+#: vms-alpha.c:5595
+#, c-format
+msgid "Source Files Header\n"
+msgstr ""
+
+#: vms-alpha.c:5596
+#, c-format
+msgid " file: %.*s\n"
+msgstr ""
+
+#: vms-alpha.c:5603
+#, c-format
+msgid "Title Text Header\n"
+msgstr ""
+
+#: vms-alpha.c:5604
+#, c-format
+msgid " title: %.*s\n"
+msgstr ""
+
+#: vms-alpha.c:5611
+#, c-format
+msgid "Copyright Header\n"
+msgstr ""
+
+#: vms-alpha.c:5612
+#, c-format
+msgid " copyright: %.*s\n"
+msgstr ""
+
+#: vms-alpha.c:5618
+#, c-format
+msgid "unhandled emh subtype %u\n"
+msgstr ""
+
+#: vms-alpha.c:5628
+#, c-format
+msgid " EEOM (len=%u):\n"
+msgstr ""
+
+#: vms-alpha.c:5629
+#, c-format
+msgid " number of cond linkage pairs: %u\n"
+msgstr ""
+
+#: vms-alpha.c:5631
+#, c-format
+msgid " completion code: %u\n"
+msgstr ""
+
+#: vms-alpha.c:5635
+#, c-format
+msgid " transfer addr flags: 0x%02x\n"
+msgstr ""
+
+#: vms-alpha.c:5636
+#, c-format
+msgid " transfer addr psect: %u\n"
+msgstr ""
+
+#: vms-alpha.c:5638
+#, c-format
+msgid " transfer address : 0x%08x\n"
+msgstr ""
+
+#: vms-alpha.c:5647
+msgid " WEAK"
+msgstr ""
+
+#: vms-alpha.c:5649
+msgid " DEF"
+msgstr ""
+
+#: vms-alpha.c:5651
+msgid " UNI"
+msgstr ""
+
+#: vms-alpha.c:5653 vms-alpha.c:5674
+msgid " REL"
+msgstr ""
+
+#: vms-alpha.c:5655
+msgid " COMM"
+msgstr ""
+
+#: vms-alpha.c:5657
+msgid " VECEP"
+msgstr ""
+
+#: vms-alpha.c:5659
+msgid " NORM"
+msgstr ""
+
+#: vms-alpha.c:5661
+msgid " QVAL"
+msgstr ""
+
+#: vms-alpha.c:5668
+msgid " PIC"
+msgstr ""
+
+#: vms-alpha.c:5670
+msgid " LIB"
+msgstr ""
+
+#: vms-alpha.c:5672
+msgid " OVR"
+msgstr ""
+
+#: vms-alpha.c:5676
+msgid " GBL"
+msgstr ""
+
+#: vms-alpha.c:5678
+msgid " SHR"
+msgstr ""
+
+#: vms-alpha.c:5680
+msgid " EXE"
+msgstr ""
+
+#: vms-alpha.c:5682
+msgid " RD"
+msgstr ""
+
+#: vms-alpha.c:5684
+msgid " WRT"
+msgstr ""
+
+#: vms-alpha.c:5686
+msgid " VEC"
+msgstr ""
+
+#: vms-alpha.c:5688
+msgid " NOMOD"
+msgstr ""
+
+#: vms-alpha.c:5690
+msgid " COM"
+msgstr ""
+
+#: vms-alpha.c:5692
+msgid " 64B"
+msgstr ""
+
+#: vms-alpha.c:5701
+#, c-format
+msgid " EGSD (len=%u):\n"
+msgstr ""
+
+#: vms-alpha.c:5713
+#, c-format
+msgid " EGSD entry %2u (type: %u, len: %u): "
+msgstr ""
+
+#: vms-alpha.c:5725
+#, c-format
+msgid "PSC - Program section definition\n"
+msgstr ""
+
+#: vms-alpha.c:5726 vms-alpha.c:5743
+#, c-format
+msgid " alignment : 2**%u\n"
+msgstr ""
+
+#: vms-alpha.c:5727 vms-alpha.c:5744
+#, c-format
+msgid " flags : 0x%04x"
+msgstr ""
+
+#: vms-alpha.c:5731
+#, c-format
+msgid " alloc (len): %u (0x%08x)\n"
+msgstr ""
+
+#: vms-alpha.c:5732 vms-alpha.c:5789 vms-alpha.c:5838
+#, c-format
+msgid " name : %.*s\n"
+msgstr ""
+
+#: vms-alpha.c:5742
+#, c-format
+msgid "SPSC - Shared Image Program section def\n"
+msgstr ""
+
+#: vms-alpha.c:5748
+#, c-format
+msgid " alloc (len) : %u (0x%08x)\n"
+msgstr ""
+
+#: vms-alpha.c:5749
+#, c-format
+msgid " image offset : 0x%08x\n"
+msgstr ""
+
+#: vms-alpha.c:5751
+#, c-format
+msgid " symvec offset : 0x%08x\n"
+msgstr ""
+
+#: vms-alpha.c:5753
+#, c-format
+msgid " name : %.*s\n"
+msgstr ""
+
+#: vms-alpha.c:5766
+#, c-format
+msgid "SYM - Global symbol definition\n"
+msgstr ""
+
+#: vms-alpha.c:5767 vms-alpha.c:5827 vms-alpha.c:5848 vms-alpha.c:5867
+#, c-format
+msgid " flags: 0x%04x"
+msgstr ""
+
+#: vms-alpha.c:5770
+#, c-format
+msgid " psect offset: 0x%08x\n"
+msgstr ""
+
+#: vms-alpha.c:5774
+#, c-format
+msgid " code address: 0x%08x\n"
+msgstr ""
+
+#: vms-alpha.c:5776
+#, c-format
+msgid " psect index for entry point : %u\n"
+msgstr ""
+
+#: vms-alpha.c:5779 vms-alpha.c:5855 vms-alpha.c:5874
+#, c-format
+msgid " psect index : %u\n"
+msgstr ""
+
+#: vms-alpha.c:5781 vms-alpha.c:5857 vms-alpha.c:5876
+#, c-format
+msgid " name : %.*s\n"
+msgstr ""
+
+#: vms-alpha.c:5788
+#, c-format
+msgid "SYM - Global symbol reference\n"
+msgstr ""
+
+#: vms-alpha.c:5800
+#, c-format
+msgid "IDC - Ident Consistency check\n"
+msgstr ""
+
+#: vms-alpha.c:5801
+#, c-format
+msgid " flags : 0x%08x"
+msgstr ""
+
+#: vms-alpha.c:5805
+#, c-format
+msgid " id match : %x\n"
+msgstr ""
+
+#: vms-alpha.c:5807
+#, c-format
+msgid " error severity: %x\n"
+msgstr ""
+
+#: vms-alpha.c:5810
+#, c-format
+msgid " entity name : %.*s\n"
+msgstr ""
+
+#: vms-alpha.c:5812
+#, c-format
+msgid " object name : %.*s\n"
+msgstr ""
+
+#: vms-alpha.c:5815
+#, c-format
+msgid " binary ident : 0x%08x\n"
+msgstr ""
+
+#: vms-alpha.c:5818
+#, c-format
+msgid " ascii ident : %.*s\n"
+msgstr ""
+
+#: vms-alpha.c:5826
+#, c-format
+msgid "SYMG - Universal symbol definition\n"
+msgstr ""
+
+#: vms-alpha.c:5830
+#, c-format
+msgid " symbol vector offset: 0x%08x\n"
+msgstr ""
+
+#: vms-alpha.c:5832
+#, c-format
+msgid " entry point: 0x%08x\n"
+msgstr ""
+
+#: vms-alpha.c:5834
+#, c-format
+msgid " proc descr : 0x%08x\n"
+msgstr ""
+
+#: vms-alpha.c:5836
+#, c-format
+msgid " psect index: %u\n"
+msgstr ""
+
+#: vms-alpha.c:5847
+#, c-format
+msgid "SYMV - Vectored symbol definition\n"
+msgstr ""
+
+#: vms-alpha.c:5851
+#, c-format
+msgid " vector : 0x%08x\n"
+msgstr ""
+
+#: vms-alpha.c:5853 vms-alpha.c:5872
+#, c-format
+msgid " psect offset: %u\n"
+msgstr ""
+
+#: vms-alpha.c:5866
+#, c-format
+msgid "SYMM - Global symbol definition with version\n"
+msgstr ""
+
+#: vms-alpha.c:5870
+#, c-format
+msgid " version mask: 0x%08x\n"
+msgstr ""
+
+#: vms-alpha.c:5881
+#, c-format
+msgid "unhandled egsd entry type %u\n"
+msgstr ""
+
+#: vms-alpha.c:5915
+#, c-format
+msgid " linkage index: %u, replacement insn: 0x%08x\n"
+msgstr ""
+
+#: vms-alpha.c:5918
+#, c-format
+msgid " psect idx 1: %u, offset 1: 0x%08x %08x\n"
+msgstr ""
+
+#: vms-alpha.c:5922
+#, c-format
+msgid " psect idx 2: %u, offset 2: 0x%08x %08x\n"
+msgstr ""
+
+#: vms-alpha.c:5927
+#, c-format
+msgid " psect idx 3: %u, offset 3: 0x%08x %08x\n"
+msgstr ""
+
+#: vms-alpha.c:5932
+#, c-format
+msgid " global name: %.*s\n"
+msgstr ""
+
+#: vms-alpha.c:5942
+#, c-format
+msgid " %s (len=%u+%u):\n"
+msgstr ""
+
+#: vms-alpha.c:5957
+#, c-format
+msgid " (type: %3u, size: 4+%3u): "
+msgstr ""
+
+#: vms-alpha.c:5961
+#, c-format
+msgid "STA_GBL (stack global) %.*s\n"
+msgstr ""
+
+#: vms-alpha.c:5965
+#, c-format
+msgid "STA_LW (stack longword) 0x%08x\n"
+msgstr ""
+
+#: vms-alpha.c:5969
+#, c-format
+msgid "STA_QW (stack quadword) 0x%08x %08x\n"
+msgstr ""
+
+#: vms-alpha.c:5974
+#, c-format
+msgid "STA_PQ (stack psect base + offset)\n"
+msgstr ""
+
+#: vms-alpha.c:5975
+#, c-format
+msgid " psect: %u, offset: 0x%08x %08x\n"
+msgstr ""
+
+#: vms-alpha.c:5981
+#, c-format
+msgid "STA_LI (stack literal)\n"
+msgstr ""
+
+#: vms-alpha.c:5984
+#, c-format
+msgid "STA_MOD (stack module)\n"
+msgstr ""
+
+#: vms-alpha.c:5987
+#, c-format
+msgid "STA_CKARG (compare procedure argument)\n"
+msgstr ""
+
+#: vms-alpha.c:5991
+#, c-format
+msgid "STO_B (store byte)\n"
+msgstr ""
+
+#: vms-alpha.c:5994
+#, c-format
+msgid "STO_W (store word)\n"
+msgstr ""
+
+#: vms-alpha.c:5997
+#, c-format
+msgid "STO_LW (store longword)\n"
+msgstr ""
+
+#: vms-alpha.c:6000
+#, c-format
+msgid "STO_QW (store quadword)\n"
+msgstr ""
+
+#: vms-alpha.c:6006
+#, c-format
+msgid "STO_IMMR (store immediate repeat) %u bytes\n"
+msgstr ""
+
+#: vms-alpha.c:6013
+#, c-format
+msgid "STO_GBL (store global) %.*s\n"
+msgstr ""
+
+#: vms-alpha.c:6017
+#, c-format
+msgid "STO_CA (store code address) %.*s\n"
+msgstr ""
+
+#: vms-alpha.c:6021
+#, c-format
+msgid "STO_RB (store relative branch)\n"
+msgstr ""
+
+#: vms-alpha.c:6024
+#, c-format
+msgid "STO_AB (store absolute branch)\n"
+msgstr ""
+
+#: vms-alpha.c:6027
+#, c-format
+msgid "STO_OFF (store offset to psect)\n"
+msgstr ""
+
+#: vms-alpha.c:6033
+#, c-format
+msgid "STO_IMM (store immediate) %u bytes\n"
+msgstr ""
+
+#: vms-alpha.c:6040
+#, c-format
+msgid "STO_GBL_LW (store global longword) %.*s\n"
+msgstr ""
+
+#: vms-alpha.c:6044
+#, c-format
+msgid "STO_OFF (store LP with procedure signature)\n"
+msgstr ""
+
+#: vms-alpha.c:6047
+#, c-format
+msgid "STO_BR_GBL (store branch global) *todo*\n"
+msgstr ""
+
+#: vms-alpha.c:6050
+#, c-format
+msgid "STO_BR_PS (store branch psect + offset) *todo*\n"
+msgstr ""
+
+#: vms-alpha.c:6054
+#, c-format
+msgid "OPR_NOP (no-operation)\n"
+msgstr ""
+
+#: vms-alpha.c:6057
+#, c-format
+msgid "OPR_ADD (add)\n"
+msgstr ""
+
+#: vms-alpha.c:6060
+#, c-format
+msgid "OPR_SUB (substract)\n"
+msgstr ""
+
+#: vms-alpha.c:6063
+#, c-format
+msgid "OPR_MUL (multiply)\n"
+msgstr ""
+
+#: vms-alpha.c:6066
+#, c-format
+msgid "OPR_DIV (divide)\n"
+msgstr ""
+
+#: vms-alpha.c:6069
+#, c-format
+msgid "OPR_AND (logical and)\n"
+msgstr ""
+
+#: vms-alpha.c:6072
+#, c-format
+msgid "OPR_IOR (logical inclusive or)\n"
+msgstr ""
+
+#: vms-alpha.c:6075
+#, c-format
+msgid "OPR_EOR (logical exclusive or)\n"
+msgstr ""
+
+#: vms-alpha.c:6078
+#, c-format
+msgid "OPR_NEG (negate)\n"
+msgstr ""
+
+#: vms-alpha.c:6081
+#, c-format
+msgid "OPR_COM (complement)\n"
+msgstr ""
+
+#: vms-alpha.c:6084
+#, c-format
+msgid "OPR_INSV (insert field)\n"
+msgstr ""
+
+#: vms-alpha.c:6087
+#, c-format
+msgid "OPR_ASH (arithmetic shift)\n"
+msgstr ""
+
+#: vms-alpha.c:6090
+#, c-format
+msgid "OPR_USH (unsigned shift)\n"
+msgstr ""
+
+#: vms-alpha.c:6093
+#, c-format
+msgid "OPR_ROT (rotate)\n"
+msgstr ""
+
+#: vms-alpha.c:6096
+#, c-format
+msgid "OPR_SEL (select)\n"
+msgstr ""
+
+#: vms-alpha.c:6099
+#, c-format
+msgid "OPR_REDEF (redefine symbol to curr location)\n"
+msgstr ""
+
+#: vms-alpha.c:6102
+#, c-format
+msgid "OPR_REDEF (define a literal)\n"
+msgstr ""
+
+#: vms-alpha.c:6106
+#, c-format
+msgid "STC_LP (store cond linkage pair)\n"
+msgstr ""
+
+#: vms-alpha.c:6110
+#, c-format
+msgid "STC_LP_PSB (store cond linkage pair + signature)\n"
+msgstr ""
+
+#: vms-alpha.c:6111
+#, c-format
+msgid " linkage index: %u, procedure: %.*s\n"
+msgstr ""
+
+#: vms-alpha.c:6114
+#, c-format
+msgid " signature: %.*s\n"
+msgstr ""
+
+#: vms-alpha.c:6117
+#, c-format
+msgid "STC_GBL (store cond global)\n"
+msgstr ""
+
+#: vms-alpha.c:6118
+#, c-format
+msgid " linkage index: %u, global: %.*s\n"
+msgstr ""
+
+#: vms-alpha.c:6122
+#, c-format
+msgid "STC_GCA (store cond code address)\n"
+msgstr ""
+
+#: vms-alpha.c:6123
+#, c-format
+msgid " linkage index: %u, procedure name: %.*s\n"
+msgstr ""
+
+#: vms-alpha.c:6127
+#, c-format
+msgid "STC_PS (store cond psect + offset)\n"
+msgstr ""
+
+#: vms-alpha.c:6129
+#, c-format
+msgid " linkage index: %u, psect: %u, offset: 0x%08x %08x\n"
+msgstr ""
+
+#: vms-alpha.c:6136
+#, c-format
+msgid "STC_NOP_GBL (store cond NOP at global addr)\n"
+msgstr ""
+
+#: vms-alpha.c:6140
+#, c-format
+msgid "STC_NOP_PS (store cond NOP at psect + offset)\n"
+msgstr ""
+
+#: vms-alpha.c:6144
+#, c-format
+msgid "STC_BSR_GBL (store cond BSR at global addr)\n"
+msgstr ""
+
+#: vms-alpha.c:6148
+#, c-format
+msgid "STC_BSR_PS (store cond BSR at psect + offset)\n"
+msgstr ""
+
+#: vms-alpha.c:6152
+#, c-format
+msgid "STC_LDA_GBL (store cond LDA at global addr)\n"
+msgstr ""
+
+#: vms-alpha.c:6156
+#, c-format
+msgid "STC_LDA_PS (store cond LDA at psect + offset)\n"
+msgstr ""
+
+#: vms-alpha.c:6160
+#, c-format
+msgid "STC_BOH_GBL (store cond BOH at global addr)\n"
+msgstr ""
+
+#: vms-alpha.c:6164
+#, c-format
+msgid "STC_BOH_PS (store cond BOH at psect + offset)\n"
+msgstr ""
+
+#: vms-alpha.c:6169
+#, c-format
+msgid "STC_NBH_GBL (store cond or hint at global addr)\n"
+msgstr ""
+
+#: vms-alpha.c:6173
+#, c-format
+msgid "STC_NBH_PS (store cond or hint at psect + offset)\n"
+msgstr ""
+
+#: vms-alpha.c:6177
+#, c-format
+msgid "CTL_SETRB (set relocation base)\n"
+msgstr ""
+
+#: vms-alpha.c:6183
+#, c-format
+msgid "CTL_AUGRB (augment relocation base) %u\n"
+msgstr ""
+
+#: vms-alpha.c:6187
+#, c-format
+msgid "CTL_DFLOC (define location)\n"
+msgstr ""
+
+#: vms-alpha.c:6190
+#, c-format
+msgid "CTL_STLOC (set location)\n"
+msgstr ""
+
+#: vms-alpha.c:6193
+#, c-format
+msgid "CTL_STKDL (stack defined location)\n"
+msgstr ""
+
+#: vms-alpha.c:6196 vms-alpha.c:6610
+#, c-format
+msgid "*unhandled*\n"
+msgstr ""
+
+#: vms-alpha.c:6226 vms-alpha.c:6265
+#, c-format
+msgid "cannot read GST record length\n"
+msgstr ""
+
+#. Ill-formed.
+#: vms-alpha.c:6247
+#, c-format
+msgid "cannot find EMH in first GST record\n"
+msgstr ""
+
+#: vms-alpha.c:6273
+#, c-format
+msgid "cannot read GST record header\n"
+msgstr ""
+
+#: vms-alpha.c:6286
+#, c-format
+msgid " corrupted GST\n"
+msgstr ""
+
+#: vms-alpha.c:6294
+#, c-format
+msgid "cannot read GST record\n"
+msgstr ""
+
+#: vms-alpha.c:6323
+#, c-format
+msgid " unhandled EOBJ record type %u\n"
+msgstr ""
+
+#: vms-alpha.c:6346
+#, c-format
+msgid " bitcount: %u, base addr: 0x%08x\n"
+msgstr ""
+
+#: vms-alpha.c:6359
+#, c-format
+msgid " bitmap: 0x%08x (count: %u):\n"
+msgstr ""
+
+#: vms-alpha.c:6366
+#, c-format
+msgid " %08x"
+msgstr ""
+
+#: vms-alpha.c:6391
+#, c-format
+msgid " image %u (%u entries)\n"
+msgstr ""
+
+#: vms-alpha.c:6396
+#, c-format
+msgid " offset: 0x%08x, val: 0x%08x\n"
+msgstr ""
+
+#: vms-alpha.c:6417
+#, c-format
+msgid " image %u (%u entries), offsets:\n"
+msgstr ""
+
+#: vms-alpha.c:6424
+#, c-format
+msgid " 0x%08x"
+msgstr ""
+
+#. 64 bits.
+#: vms-alpha.c:6546
+#, c-format
+msgid "64 bits *unhandled*\n"
+msgstr ""
+
+#: vms-alpha.c:6550
+#, c-format
+msgid "class: %u, dtype: %u, length: %u, pointer: 0x%08x\n"
+msgstr ""
+
+#: vms-alpha.c:6561
+#, c-format
+msgid "non-contiguous array of %s\n"
+msgstr ""
+
+#: vms-alpha.c:6565
+#, c-format
+msgid "dimct: %u, aflags: 0x%02x, digits: %u, scale: %u\n"
+msgstr ""
+
+#: vms-alpha.c:6569
+#, c-format
+msgid "arsize: %u, a0: 0x%08x\n"
+msgstr ""
+
+#: vms-alpha.c:6573
+#, c-format
+msgid "Strides:\n"
+msgstr ""
+
+#: vms-alpha.c:6578
+#, c-format
+msgid "[%u]: %u\n"
+msgstr ""
+
+#: vms-alpha.c:6583
+#, c-format
+msgid "Bounds:\n"
+msgstr ""
+
+#: vms-alpha.c:6588
+#, c-format
+msgid "[%u]: Lower: %u, upper: %u\n"
+msgstr ""
+
+#: vms-alpha.c:6600
+#, c-format
+msgid "unaligned bit-string of %s\n"
+msgstr ""
+
+#: vms-alpha.c:6604
+#, c-format
+msgid "base: %u, pos: %u\n"
+msgstr ""
+
+#: vms-alpha.c:6624
+#, c-format
+msgid "vflags: 0x%02x, value: 0x%08x "
+msgstr ""
+
+#: vms-alpha.c:6630
+#, c-format
+msgid "(no value)\n"
+msgstr ""
+
+#: vms-alpha.c:6633
+#, c-format
+msgid "(not active)\n"
+msgstr ""
+
+#: vms-alpha.c:6636
+#, c-format
+msgid "(not allocated)\n"
+msgstr ""
+
+#: vms-alpha.c:6639
+#, c-format
+msgid "(descriptor)\n"
+msgstr ""
+
+#: vms-alpha.c:6643
+#, c-format
+msgid "(trailing value)\n"
+msgstr ""
+
+#: vms-alpha.c:6646
+#, c-format
+msgid "(value spec follows)\n"
+msgstr ""
+
+#: vms-alpha.c:6649
+#, c-format
+msgid "(at bit offset %u)\n"
+msgstr ""
+
+#: vms-alpha.c:6652
+#, c-format
+msgid "(reg: %u, disp: %u, indir: %u, kind: "
+msgstr ""
+
+#: vms-alpha.c:6659
+msgid "literal"
+msgstr ""
+
+#: vms-alpha.c:6662
+msgid "address"
+msgstr ""
+
+#: vms-alpha.c:6665
+msgid "desc"
+msgstr ""
+
+#: vms-alpha.c:6668
+msgid "reg"
+msgstr ""
+
+#: vms-alpha.c:6743
+#, c-format
+msgid "Debug symbol table:\n"
+msgstr ""
+
+#: vms-alpha.c:6754
+#, c-format
+msgid "cannot read DST header\n"
+msgstr ""
+
+#: vms-alpha.c:6759
+#, c-format
+msgid " type: %3u, len: %3u (at 0x%08x): "
+msgstr ""
+
+#: vms-alpha.c:6773
+#, c-format
+msgid "cannot read DST symbol\n"
+msgstr ""
+
+#: vms-alpha.c:6816
+#, c-format
+msgid "standard data: %s\n"
+msgstr ""
+
+#: vms-alpha.c:6819 vms-alpha.c:6903
+#, c-format
+msgid " name: %.*s\n"
+msgstr ""
+
+#: vms-alpha.c:6826
+#, c-format
+msgid "modbeg\n"
+msgstr ""
+
+#: vms-alpha.c:6827
+#, c-format
+msgid " flags: %d, language: %u, major: %u, minor: %u\n"
+msgstr ""
+
+#: vms-alpha.c:6833 vms-alpha.c:7099
+#, c-format
+msgid " module name: %.*s\n"
+msgstr ""
+
+#: vms-alpha.c:6836
+#, c-format
+msgid " compiler : %.*s\n"
+msgstr ""
+
+#: vms-alpha.c:6841
+#, c-format
+msgid "modend\n"
+msgstr ""
+
+#: vms-alpha.c:6848
+msgid "rtnbeg\n"
+msgstr ""
+
+#: vms-alpha.c:6849
+#, c-format
+msgid " flags: %u, address: 0x%08x, pd-address: 0x%08x\n"
+msgstr ""
+
+#: vms-alpha.c:6854
+#, c-format
+msgid " routine name: %.*s\n"
+msgstr ""
+
+#: vms-alpha.c:6862
+#, c-format
+msgid "rtnend: size 0x%08x\n"
+msgstr ""
+
+#: vms-alpha.c:6870
+#, c-format
+msgid "prolog: bkpt address 0x%08x\n"
+msgstr ""
+
+#: vms-alpha.c:6878
+#, c-format
+msgid "epilog: flags: %u, count: %u\n"
+msgstr ""
+
+#: vms-alpha.c:6887
+#, c-format
+msgid "blkbeg: address: 0x%08x, name: %.*s\n"
+msgstr ""
+
+#: vms-alpha.c:6896
+#, c-format
+msgid "blkend: size: 0x%08x\n"
+msgstr ""
+
+#: vms-alpha.c:6902
+#, c-format
+msgid "typspec (len: %u)\n"
+msgstr ""
+
+#: vms-alpha.c:6909
+#, c-format
+msgid "septyp, name: %.*s\n"
+msgstr ""
+
+#: vms-alpha.c:6918
+#, c-format
+msgid "recbeg: name: %.*s\n"
+msgstr ""
+
+#: vms-alpha.c:6925
+#, c-format
+msgid "recend\n"
+msgstr ""
+
+#: vms-alpha.c:6928
+#, c-format
+msgid "enumbeg, len: %u, name: %.*s\n"
+msgstr ""
+
+#: vms-alpha.c:6932
+#, c-format
+msgid "enumelt, name: %.*s\n"
+msgstr ""
+
+#: vms-alpha.c:6936
+#, c-format
+msgid "enumend\n"
+msgstr ""
+
+#: vms-alpha.c:6953
+#, c-format
+msgid "discontiguous range (nbr: %u)\n"
+msgstr ""
+
+#: vms-alpha.c:6955
+#, c-format
+msgid " address: 0x%08x, size: %u\n"
+msgstr ""
+
+#: vms-alpha.c:6965
+#, c-format
+msgid "line num (len: %u)\n"
+msgstr ""
+
+#: vms-alpha.c:6982
+#, c-format
+msgid "delta_pc_w %u\n"
+msgstr ""
+
+#: vms-alpha.c:6989
+#, c-format
+msgid "incr_linum(b): +%u\n"
+msgstr ""
+
+#: vms-alpha.c:6995
+#, c-format
+msgid "incr_linum_w: +%u\n"
+msgstr ""
+
+#: vms-alpha.c:7001
+#, c-format
+msgid "incr_linum_l: +%u\n"
+msgstr ""
+
+#: vms-alpha.c:7007
+#, c-format
+msgid "set_line_num(w) %u\n"
+msgstr ""
+
+#: vms-alpha.c:7012
+#, c-format
+msgid "set_line_num_b %u\n"
+msgstr ""
+
+#: vms-alpha.c:7017
+#, c-format
+msgid "set_line_num_l %u\n"
+msgstr ""
+
+#: vms-alpha.c:7022
+#, c-format
+msgid "set_abs_pc: 0x%08x\n"
+msgstr ""
+
+#: vms-alpha.c:7026
+#, c-format
+msgid "delta_pc_l: +0x%08x\n"
+msgstr ""
+
+#: vms-alpha.c:7031
+#, c-format
+msgid "term(b): 0x%02x"
+msgstr ""
+
+#: vms-alpha.c:7033
+#, c-format
+msgid " pc: 0x%08x\n"
+msgstr ""
+
+#: vms-alpha.c:7038
+#, c-format
+msgid "term_w: 0x%04x"
+msgstr ""
+
+#: vms-alpha.c:7040
+#, c-format
+msgid " pc: 0x%08x\n"
+msgstr ""
+
+#: vms-alpha.c:7046
+#, c-format
+msgid "delta pc +%-4d"
+msgstr ""
+
+#: vms-alpha.c:7049
+#, c-format
+msgid " pc: 0x%08x line: %5u\n"
+msgstr ""
+
+#: vms-alpha.c:7054
+#, c-format
+msgid " *unhandled* cmd %u\n"
+msgstr ""
+
+#: vms-alpha.c:7069
+#, c-format
+msgid "source (len: %u)\n"
+msgstr ""
+
+#: vms-alpha.c:7083
+#, c-format
+msgid " declfile: len: %u, flags: %u, fileid: %u\n"
+msgstr ""
+
+#: vms-alpha.c:7087
+#, c-format
+msgid " rms: cdt: 0x%08x %08x, ebk: 0x%08x, ffb: 0x%04x, rfo: %u\n"
+msgstr ""
+
+#: vms-alpha.c:7096
+#, c-format
+msgid " filename : %.*s\n"
+msgstr ""
+
+#: vms-alpha.c:7105
+#, c-format
+msgid " setfile %u\n"
+msgstr ""
+
+#: vms-alpha.c:7110 vms-alpha.c:7115
+#, c-format
+msgid " setrec %u\n"
+msgstr ""
+
+#: vms-alpha.c:7120 vms-alpha.c:7125
+#, c-format
+msgid " setlnum %u\n"
+msgstr ""
+
+#: vms-alpha.c:7130 vms-alpha.c:7135
+#, c-format
+msgid " deflines %u\n"
+msgstr ""
+
+#: vms-alpha.c:7139
+#, c-format
+msgid " formfeed\n"
+msgstr ""
+
+#: vms-alpha.c:7143
+#, c-format
+msgid " *unhandled* cmd %u\n"
+msgstr ""
+
+#: vms-alpha.c:7155
+#, c-format
+msgid "*unhandled* dst type %u\n"
+msgstr ""
+
+#: vms-alpha.c:7187
+#, c-format
+msgid "cannot read EIHD\n"
+msgstr ""
+
+#: vms-alpha.c:7190
+#, c-format
+msgid "EIHD: (size: %u, nbr blocks: %u)\n"
+msgstr ""
+
+#: vms-alpha.c:7193
+#, c-format
+msgid " majorid: %u, minorid: %u\n"
+msgstr ""
+
+#: vms-alpha.c:7201
+msgid "executable"
+msgstr ""
+
+#: vms-alpha.c:7204
+msgid "linkable image"
+msgstr ""
+
+#: vms-alpha.c:7210
+#, c-format
+msgid " image type: %u (%s)"
+msgstr ""
+
+#: vms-alpha.c:7216
+msgid "native"
+msgstr ""
+
+#: vms-alpha.c:7219
+msgid "CLI"
+msgstr ""
+
+#: vms-alpha.c:7225
+#, c-format
+msgid ", subtype: %u (%s)\n"
+msgstr ""
+
+#: vms-alpha.c:7231
+#, c-format
+msgid " offsets: isd: %u, activ: %u, symdbg: %u, imgid: %u, patch: %u\n"
+msgstr ""
+
+#: vms-alpha.c:7235
+#, c-format
+msgid " fixup info rva: "
+msgstr ""
+
+#: vms-alpha.c:7237
+#, c-format
+msgid ", symbol vector rva: "
+msgstr ""
+
+#: vms-alpha.c:7240
+#, c-format
+msgid ""
+"\n"
+" version array off: %u\n"
+msgstr ""
+
+#: vms-alpha.c:7244
+#, c-format
+msgid " img I/O count: %u, nbr channels: %u, req pri: %08x%08x\n"
+msgstr ""
+
+#: vms-alpha.c:7250
+#, c-format
+msgid " linker flags: %08x:"
+msgstr ""
+
+#: vms-alpha.c:7280
+#, c-format
+msgid " ident: 0x%08x, sysver: 0x%08x, match ctrl: %u, symvect_size: %u\n"
+msgstr ""
+
+#: vms-alpha.c:7286
+#, c-format
+msgid " BPAGE: %u"
+msgstr ""
+
+#: vms-alpha.c:7292
+#, c-format
+msgid ", ext fixup offset: %u, no_opt psect off: %u"
+msgstr ""
+
+#: vms-alpha.c:7295
+#, c-format
+msgid ", alias: %u\n"
+msgstr ""
+
+#: vms-alpha.c:7303
+#, c-format
+msgid "system version array information:\n"
+msgstr ""
+
+#: vms-alpha.c:7307
+#, c-format
+msgid "cannot read EIHVN header\n"
+msgstr ""
+
+#: vms-alpha.c:7317
+#, c-format
+msgid "cannot read EIHVN version\n"
+msgstr ""
+
+#: vms-alpha.c:7320
+#, c-format
+msgid " %02u "
+msgstr ""
+
+#: vms-alpha.c:7324
+msgid "BASE_IMAGE "
+msgstr ""
+
+#: vms-alpha.c:7327
+msgid "MEMORY_MANAGEMENT"
+msgstr ""
+
+#: vms-alpha.c:7330
+msgid "IO "
+msgstr ""
+
+#: vms-alpha.c:7333
+msgid "FILES_VOLUMES "
+msgstr ""
+
+#: vms-alpha.c:7336
+msgid "PROCESS_SCHED "
+msgstr ""
+
+#: vms-alpha.c:7339
+msgid "SYSGEN "
+msgstr ""
+
+#: vms-alpha.c:7342
+msgid "CLUSTERS_LOCKMGR "
+msgstr ""
+
+#: vms-alpha.c:7345
+msgid "LOGICAL_NAMES "
+msgstr ""
+
+#: vms-alpha.c:7348
+msgid "SECURITY "
+msgstr ""
+
+#: vms-alpha.c:7351
+msgid "IMAGE_ACTIVATOR "
+msgstr ""
+
+#: vms-alpha.c:7354
+msgid "NETWORKS "
+msgstr ""
+
+#: vms-alpha.c:7357
+msgid "COUNTERS "
+msgstr ""
+
+#: vms-alpha.c:7360
+msgid "STABLE "
+msgstr ""
+
+#: vms-alpha.c:7363
+msgid "MISC "
+msgstr ""
+
+#: vms-alpha.c:7366
+msgid "CPU "
+msgstr ""
+
+#: vms-alpha.c:7369
+msgid "VOLATILE "
+msgstr ""
+
+#: vms-alpha.c:7372
+msgid "SHELL "
+msgstr ""
+
+#: vms-alpha.c:7375
+msgid "POSIX "
+msgstr ""
+
+#: vms-alpha.c:7378
+msgid "MULTI_PROCESSING "
+msgstr ""
+
+#: vms-alpha.c:7381
+msgid "GALAXY "
+msgstr ""
+
+#: vms-alpha.c:7384
+msgid "*unknown* "
+msgstr ""
+
+#: vms-alpha.c:7387
+#, c-format
+msgid ": %u.%u\n"
+msgstr ""
+
+#: vms-alpha.c:7400 vms-alpha.c:7659
+#, c-format
+msgid "cannot read EIHA\n"
+msgstr ""
+
+#: vms-alpha.c:7403
+#, c-format
+msgid "Image activation: (size=%u)\n"
+msgstr ""
+
+#: vms-alpha.c:7405
+#, c-format
+msgid " First address : 0x%08x 0x%08x\n"
+msgstr ""
+
+#: vms-alpha.c:7408
+#, c-format
+msgid " Second address: 0x%08x 0x%08x\n"
+msgstr ""
+
+#: vms-alpha.c:7411
+#, c-format
+msgid " Third address : 0x%08x 0x%08x\n"
+msgstr ""
+
+#: vms-alpha.c:7414
+#, c-format
+msgid " Fourth address: 0x%08x 0x%08x\n"
+msgstr ""
+
+#: vms-alpha.c:7417
+#, c-format
+msgid " Shared image : 0x%08x 0x%08x\n"
+msgstr ""
+
+#: vms-alpha.c:7428
+#, c-format
+msgid "cannot read EIHI\n"
+msgstr ""
+
+#: vms-alpha.c:7431
+#, c-format
+msgid "Image identification: (major: %u, minor: %u)\n"
+msgstr ""
+
+#: vms-alpha.c:7434
+#, c-format
+msgid " image name : %.*s\n"
+msgstr ""
+
+#: vms-alpha.c:7436
+#, c-format
+msgid " link time : %s\n"
+msgstr ""
+
+#: vms-alpha.c:7438
+#, c-format
+msgid " image ident : %.*s\n"
+msgstr ""
+
+#: vms-alpha.c:7440
+#, c-format
+msgid " linker ident : %.*s\n"
+msgstr ""
+
+#: vms-alpha.c:7442
+#, c-format
+msgid " image build ident: %.*s\n"
+msgstr ""
+
+#: vms-alpha.c:7452
+#, c-format
+msgid "cannot read EIHS\n"
+msgstr ""
+
+#: vms-alpha.c:7455
+#, c-format
+msgid "Image symbol & debug table: (major: %u, minor: %u)\n"
+msgstr ""
+
+#: vms-alpha.c:7460
+#, c-format
+msgid " debug symbol table : vbn: %u, size: %u (0x%x)\n"
+msgstr ""
+
+#: vms-alpha.c:7464
+#, c-format
+msgid " global symbol table: vbn: %u, records: %u\n"
+msgstr ""
+
+#: vms-alpha.c:7468
+#, c-format
+msgid " debug module table : vbn: %u, size: %u\n"
+msgstr ""
+
+#: vms-alpha.c:7481
+#, c-format
+msgid "cannot read EISD\n"
+msgstr ""
+
+#: vms-alpha.c:7491
+#, c-format
+msgid ""
+"Image section descriptor: (major: %u, minor: %u, size: %u, offset: %u)\n"
+msgstr ""
+
+#: vms-alpha.c:7498
+#, c-format
+msgid " section: base: 0x%08x%08x size: 0x%08x\n"
+msgstr ""
+
+#: vms-alpha.c:7503
+#, c-format
+msgid " flags: 0x%04x"
+msgstr ""
+
+#: vms-alpha.c:7540
+#, c-format
+msgid " vbn: %u, pfc: %u, matchctl: %u type: %u ("
+msgstr ""
+
+#: vms-alpha.c:7546
+msgid "NORMAL"
+msgstr ""
+
+#: vms-alpha.c:7549
+msgid "SHRFXD"
+msgstr ""
+
+#: vms-alpha.c:7552
+msgid "PRVFXD"
+msgstr ""
+
+#: vms-alpha.c:7555
+msgid "SHRPIC"
+msgstr ""
+
+#: vms-alpha.c:7558
+msgid "PRVPIC"
+msgstr ""
+
+#: vms-alpha.c:7561
+msgid "USRSTACK"
+msgstr ""
+
+#: vms-alpha.c:7567
+msgid ")\n"
+msgstr ""
+
+#: vms-alpha.c:7569
+#, c-format
+msgid " ident: 0x%08x, name: %.*s\n"
+msgstr ""
+
+#: vms-alpha.c:7579
+#, c-format
+msgid "cannot read DMT\n"
+msgstr ""
+
+#: vms-alpha.c:7583
+#, c-format
+msgid "Debug module table:\n"
+msgstr ""
+
+#: vms-alpha.c:7592
+#, c-format
+msgid "cannot read DMT header\n"
+msgstr ""
+
+#: vms-alpha.c:7597
+#, c-format
+msgid " module offset: 0x%08x, size: 0x%08x, (%u psects)\n"
+msgstr ""
+
+#: vms-alpha.c:7607
+#, c-format
+msgid "cannot read DMT psect\n"
+msgstr ""
+
+#: vms-alpha.c:7610
+#, c-format
+msgid " psect start: 0x%08x, length: %u\n"
+msgstr ""
+
+#: vms-alpha.c:7623
+#, c-format
+msgid "cannot read DST\n"
+msgstr ""
+
+#: vms-alpha.c:7633
+#, c-format
+msgid "cannot read GST\n"
+msgstr ""
+
+#: vms-alpha.c:7637
+#, c-format
+msgid "Global symbol table:\n"
+msgstr ""
+
+#: vms-alpha.c:7665
+#, c-format
+msgid "Image activator fixup: (major: %u, minor: %u)\n"
+msgstr ""
+
+#: vms-alpha.c:7668
+#, c-format
+msgid " iaflink : 0x%08x %08x\n"
+msgstr ""
+
+#: vms-alpha.c:7671
+#, c-format
+msgid " fixuplnk: 0x%08x %08x\n"
+msgstr ""
+
+#: vms-alpha.c:7674
+#, c-format
+msgid " size : %u\n"
+msgstr ""
+
+#: vms-alpha.c:7676
+#, c-format
+msgid " flags: 0x%08x\n"
+msgstr ""
+
+#: vms-alpha.c:7680
+#, c-format
+msgid " qrelfixoff: %5u, lrelfixoff: %5u\n"
+msgstr ""
+
+#: vms-alpha.c:7684
+#, c-format
+msgid " qdotadroff: %5u, ldotadroff: %5u\n"
+msgstr ""
+
+#: vms-alpha.c:7688
+#, c-format
+msgid " codeadroff: %5u, lpfixoff : %5u\n"
+msgstr ""
+
+#: vms-alpha.c:7691
+#, c-format
+msgid " chgprtoff : %5u\n"
+msgstr ""
+
+#: vms-alpha.c:7694
+#, c-format
+msgid " shlstoff : %5u, shrimgcnt : %5u\n"
+msgstr ""
+
+#: vms-alpha.c:7696
+#, c-format
+msgid " shlextra : %5u, permctx : %5u\n"
+msgstr ""
+
+#: vms-alpha.c:7699
+#, c-format
+msgid " base_va : 0x%08x\n"
+msgstr ""
+
+#: vms-alpha.c:7701
+#, c-format
+msgid " lppsbfixoff: %5u\n"
+msgstr ""
+
+#: vms-alpha.c:7709
+#, c-format
+msgid " Shareable images:\n"
+msgstr ""
+
+#: vms-alpha.c:7713
+#, c-format
+msgid " %u: size: %u, flags: 0x%02x, name: %.*s\n"
+msgstr ""
+
+#: vms-alpha.c:7720
+#, c-format
+msgid " quad-word relocation fixups:\n"
+msgstr ""
+
+#: vms-alpha.c:7725
+#, c-format
+msgid " long-word relocation fixups:\n"
+msgstr ""
+
+#: vms-alpha.c:7730
+#, c-format
+msgid " quad-word .address reference fixups:\n"
+msgstr ""
+
+#: vms-alpha.c:7735
+#, c-format
+msgid " long-word .address reference fixups:\n"
+msgstr ""
+
+#: vms-alpha.c:7740
+#, c-format
+msgid " Code Address Reference Fixups:\n"
+msgstr ""
+
+#: vms-alpha.c:7745
+#, c-format
+msgid " Linkage Pairs Reference Fixups:\n"
+msgstr ""
+
+#: vms-alpha.c:7754
+#, c-format
+msgid " Change Protection (%u entries):\n"
+msgstr ""
+
+#: vms-alpha.c:7759
+#, c-format
+msgid " base: 0x%08x %08x, size: 0x%08x, prot: 0x%08x "
+msgstr ""
+
+#. FIXME: we do not yet support relocatable link. It is not obvious
+#. how to do it for debug infos.
+#: vms-alpha.c:8599
+msgid "%P: relocatable link is not supported\n"
+msgstr ""
+
+#: vms-alpha.c:8669
+msgid "%P: multiple entry points: in modules %B and %B\n"
+msgstr ""
+
+#: vms-lib.c:1444
+#, c-format
+msgid "could not open shared image '%s' from '%s'"
+msgstr ""
+
+#: vms-misc.c:360
+msgid "_bfd_vms_output_counted called with zero bytes"
+msgstr ""
+
+#: vms-misc.c:365
+msgid "_bfd_vms_output_counted called with too many bytes"
+msgstr ""
+
+#: xcofflink.c:824
+#, c-format
+msgid "%s: XCOFF shared object when not producing XCOFF output"
+msgstr ""
+
+#: xcofflink.c:845
+#, c-format
+msgid "%s: dynamic object with no .loader section"
+msgstr ""
+
+#: xcofflink.c:1404
+msgid "%B: `%s' has line numbers but no enclosing section"
+msgstr ""
+
+#: xcofflink.c:1456
+msgid "%B: class %d symbol `%s' has no aux entries"
+msgstr ""
+
+#: xcofflink.c:1478
+msgid "%B: symbol `%s' has unrecognized csect type %d"
+msgstr ""
+
+#: xcofflink.c:1490
+msgid "%B: bad XTY_ER symbol `%s': class %d scnum %d scnlen %d"
+msgstr ""
+
+#: xcofflink.c:1519
+msgid "%B: XMC_TC0 symbol `%s' is class %d scnlen %d"
+msgstr ""
+
+#: xcofflink.c:1665
+msgid "%B: csect `%s' not in enclosing section"
+msgstr ""
+
+#: xcofflink.c:1772
+msgid "%B: misplaced XTY_LD `%s'"
+msgstr ""
+
+#: xcofflink.c:2091
+msgid "%B: reloc %s:%d not in csect"
+msgstr ""
+
+#: xcofflink.c:3182
+#, c-format
+msgid "%s: no such symbol"
+msgstr ""
+
+#: xcofflink.c:3287
+#, c-format
+msgid "warning: attempt to export undefined symbol `%s'"
+msgstr ""
+
+#: xcofflink.c:3666
+msgid "error: undefined symbol __rtinit"
+msgstr ""
+
+#: xcofflink.c:4045
+msgid "%B: loader reloc in unrecognized section `%s'"
+msgstr ""
+
+#: xcofflink.c:4056
+msgid "%B: `%s' in loader reloc but not loader sym"
+msgstr ""
+
+#: xcofflink.c:4072
+msgid "%B: loader reloc in read-only section %A"
+msgstr ""
+
+#: xcofflink.c:5094
+#, c-format
+msgid "TOC overflow: 0x%lx > 0x10000; try -mminimal-toc when compiling"
+msgstr ""
+
+#: peigen.c:1009 pepigen.c:1009 pex64igen.c:1009
+#, c-format
+msgid "%s: line number overflow: 0x%lx > 0xffff"
+msgstr ""
+
+#: peigen.c:1036 pepigen.c:1036 pex64igen.c:1036
+msgid "Export Directory [.edata (or where ever we found it)]"
+msgstr ""
+
+#: peigen.c:1037 pepigen.c:1037 pex64igen.c:1037
+msgid "Import Directory [parts of .idata]"
+msgstr ""
+
+#: peigen.c:1038 pepigen.c:1038 pex64igen.c:1038
+msgid "Resource Directory [.rsrc]"
+msgstr ""
+
+#: peigen.c:1039 pepigen.c:1039 pex64igen.c:1039
+msgid "Exception Directory [.pdata]"
+msgstr ""
+
+#: peigen.c:1040 pepigen.c:1040 pex64igen.c:1040
+msgid "Security Directory"
+msgstr ""
+
+#: peigen.c:1041 pepigen.c:1041 pex64igen.c:1041
+msgid "Base Relocation Directory [.reloc]"
+msgstr ""
+
+#: peigen.c:1042 pepigen.c:1042 pex64igen.c:1042
+msgid "Debug Directory"
+msgstr ""
+
+#: peigen.c:1043 pepigen.c:1043 pex64igen.c:1043
+msgid "Description Directory"
+msgstr ""
+
+#: peigen.c:1044 pepigen.c:1044 pex64igen.c:1044
+msgid "Special Directory"
+msgstr ""
+
+#: peigen.c:1045 pepigen.c:1045 pex64igen.c:1045
+msgid "Thread Storage Directory [.tls]"
+msgstr ""
+
+#: peigen.c:1046 pepigen.c:1046 pex64igen.c:1046
+msgid "Load Configuration Directory"
+msgstr ""
+
+#: peigen.c:1047 pepigen.c:1047 pex64igen.c:1047
+msgid "Bound Import Directory"
+msgstr ""
+
+#: peigen.c:1048 pepigen.c:1048 pex64igen.c:1048
+msgid "Import Address Table Directory"
+msgstr ""
+
+#: peigen.c:1049 pepigen.c:1049 pex64igen.c:1049
+msgid "Delay Import Directory"
+msgstr ""
+
+#: peigen.c:1050 pepigen.c:1050 pex64igen.c:1050
+msgid "CLR Runtime Header"
+msgstr ""
+
+#: peigen.c:1051 pepigen.c:1051 pex64igen.c:1051
+msgid "Reserved"
+msgstr ""
+
+#: peigen.c:1111 pepigen.c:1111 pex64igen.c:1111
+#, c-format
+msgid ""
+"\n"
+"There is an import table, but the section containing it could not be found\n"
+msgstr ""
+
+#: peigen.c:1116 pepigen.c:1116 pex64igen.c:1116
+#, c-format
+msgid ""
+"\n"
+"There is an import table in %s at 0x%lx\n"
+msgstr ""
+
+#: peigen.c:1158 pepigen.c:1158 pex64igen.c:1158
+#, c-format
+msgid ""
+"\n"
+"Function descriptor located at the start address: %04lx\n"
+msgstr ""
+
+#: peigen.c:1161 pepigen.c:1161 pex64igen.c:1161
+#, c-format
+msgid "\tcode-base %08lx toc (loadable/actual) %08lx/%08lx\n"
+msgstr ""
+
+#: peigen.c:1169 pepigen.c:1169 pex64igen.c:1169
+#, c-format
+msgid ""
+"\n"
+"No reldata section! Function descriptor not decoded.\n"
+msgstr ""
+
+#: peigen.c:1174 pepigen.c:1174 pex64igen.c:1174
+#, c-format
+msgid ""
+"\n"
+"The Import Tables (interpreted %s section contents)\n"
+msgstr ""
+
+#: peigen.c:1177 pepigen.c:1177 pex64igen.c:1177
+#, c-format
+msgid ""
+" vma: Hint Time Forward DLL First\n"
+" Table Stamp Chain Name Thunk\n"
+msgstr ""
+
+#: peigen.c:1225 pepigen.c:1225 pex64igen.c:1225
+#, c-format
+msgid ""
+"\n"
+"\tDLL Name: %s\n"
+msgstr ""
+
+#: peigen.c:1236 pepigen.c:1236 pex64igen.c:1236
+#, c-format
+msgid "\tvma: Hint/Ord Member-Name Bound-To\n"
+msgstr ""
+
+#: peigen.c:1261 pepigen.c:1261 pex64igen.c:1261
+#, c-format
+msgid ""
+"\n"
+"There is a first thunk, but the section containing it could not be found\n"
+msgstr ""
+
+#: peigen.c:1423 pepigen.c:1423 pex64igen.c:1423
+#, c-format
+msgid ""
+"\n"
+"There is an export table, but the section containing it could not be found\n"
+msgstr ""
+
+#: peigen.c:1432 pepigen.c:1432 pex64igen.c:1432
+#, c-format
+msgid ""
+"\n"
+"There is an export table in %s, but it does not fit into that section\n"
+msgstr ""
+
+#: peigen.c:1438 pepigen.c:1438 pex64igen.c:1438
+#, c-format
+msgid ""
+"\n"
+"There is an export table in %s at 0x%lx\n"
+msgstr ""
+
+#: peigen.c:1466 pepigen.c:1466 pex64igen.c:1466
+#, c-format
+msgid ""
+"\n"
+"The Export Tables (interpreted %s section contents)\n"
+"\n"
+msgstr ""
+
+#: peigen.c:1470 pepigen.c:1470 pex64igen.c:1470
+#, c-format
+msgid "Export Flags \t\t\t%lx\n"
+msgstr ""
+
+#: peigen.c:1473 pepigen.c:1473 pex64igen.c:1473
+#, c-format
+msgid "Time/Date stamp \t\t%lx\n"
+msgstr ""
+
+#: peigen.c:1476 pepigen.c:1476 pex64igen.c:1476
+#, c-format
+msgid "Major/Minor \t\t\t%d/%d\n"
+msgstr ""
+
+#: peigen.c:1479 pepigen.c:1479 pex64igen.c:1479
+#, c-format
+msgid "Name \t\t\t\t"
+msgstr ""
+
+#: peigen.c:1485 pepigen.c:1485 pex64igen.c:1485
+#, c-format
+msgid "Ordinal Base \t\t\t%ld\n"
+msgstr ""
+
+#: peigen.c:1488 pepigen.c:1488 pex64igen.c:1488
+#, c-format
+msgid "Number in:\n"
+msgstr ""
+
+#: peigen.c:1491 pepigen.c:1491 pex64igen.c:1491
+#, c-format
+msgid "\tExport Address Table \t\t%08lx\n"
+msgstr ""
+
+#: peigen.c:1495 pepigen.c:1495 pex64igen.c:1495
+#, c-format
+msgid "\t[Name Pointer/Ordinal] Table\t%08lx\n"
+msgstr ""
+
+#: peigen.c:1498 pepigen.c:1498 pex64igen.c:1498
+#, c-format
+msgid "Table Addresses\n"
+msgstr ""
+
+#: peigen.c:1501 pepigen.c:1501 pex64igen.c:1501
+#, c-format
+msgid "\tExport Address Table \t\t"
+msgstr ""
+
+#: peigen.c:1506 pepigen.c:1506 pex64igen.c:1506
+#, c-format
+msgid "\tName Pointer Table \t\t"
+msgstr ""
+
+#: peigen.c:1511 pepigen.c:1511 pex64igen.c:1511
+#, c-format
+msgid "\tOrdinal Table \t\t\t"
+msgstr ""
+
+#: peigen.c:1525 pepigen.c:1525 pex64igen.c:1525
+#, c-format
+msgid ""
+"\n"
+"Export Address Table -- Ordinal Base %ld\n"
+msgstr ""
+
+#: peigen.c:1544 pepigen.c:1544 pex64igen.c:1544
+msgid "Forwarder RVA"
+msgstr ""
+
+#: peigen.c:1555 pepigen.c:1555 pex64igen.c:1555
+msgid "Export RVA"
+msgstr ""
+
+#: peigen.c:1562 pepigen.c:1562 pex64igen.c:1562
+#, c-format
+msgid ""
+"\n"
+"[Ordinal/Name Pointer] Table\n"
+msgstr ""
+
+#: peigen.c:1622 peigen.c:1805 pepigen.c:1622 pepigen.c:1805 pex64igen.c:1622
+#: pex64igen.c:1805
+#, c-format
+msgid "Warning, .pdata section size (%ld) is not a multiple of %d\n"
+msgstr ""
+
+#: peigen.c:1629 pepigen.c:1629 pex64igen.c:1629
+#, c-format
+msgid " vma:\t\t\tBegin Address End Address Unwind Info\n"
+msgstr ""
+
+#: peigen.c:1631 pepigen.c:1631 pex64igen.c:1631
+#, c-format
+msgid ""
+" vma:\t\tBegin End EH EH PrologEnd Exception\n"
+" \t\tAddress Address Handler Data Address Mask\n"
+msgstr ""
+
+#: peigen.c:1705 pepigen.c:1705 pex64igen.c:1705
+#, c-format
+msgid " Register save millicode"
+msgstr ""
+
+#: peigen.c:1708 pepigen.c:1708 pex64igen.c:1708
+#, c-format
+msgid " Register restore millicode"
+msgstr ""
+
+#: peigen.c:1711 pepigen.c:1711 pex64igen.c:1711
+#, c-format
+msgid " Glue code sequence"
+msgstr ""
+
+#: peigen.c:1811 pepigen.c:1811 pex64igen.c:1811
+#, c-format
+msgid ""
+" vma:\t\tBegin Prolog Function Flags Exception EH\n"
+" \t\tAddress Length Length 32b exc Handler Data\n"
+msgstr ""
+
+#: peigen.c:1937 pepigen.c:1937 pex64igen.c:1937
+#, c-format
+msgid ""
+"\n"
+"\n"
+"PE File Base Relocations (interpreted .reloc section contents)\n"
+msgstr ""
+
+#: peigen.c:1966 pepigen.c:1966 pex64igen.c:1966
+#, c-format
+msgid ""
+"\n"
+"Virtual Address: %08lx Chunk size %ld (0x%lx) Number of fixups %ld\n"
+msgstr ""
+
+#: peigen.c:1979 pepigen.c:1979 pex64igen.c:1979
+#, c-format
+msgid "\treloc %4d offset %4x [%4lx] %s"
+msgstr ""
+
+#: peigen.c:2023 pepigen.c:2023 pex64igen.c:2023
+#, c-format
+msgid "%*.s Entry: "
+msgstr ""
+
+#: peigen.c:2043 pepigen.c:2043 pex64igen.c:2043
+#, c-format
+msgid "name: [val: %08lx len %d]: "
+msgstr ""
+
+#: peigen.c:2054 pepigen.c:2054 pex64igen.c:2054
+#, c-format
+msgid "<corrupt string length: %#x>"
+msgstr ""
+
+#: peigen.c:2057 pepigen.c:2057 pex64igen.c:2057
+#, c-format
+msgid "<corrupt string offset: %#lx>"
+msgstr ""
+
+#: peigen.c:2060 pepigen.c:2060 pex64igen.c:2060
+#, c-format
+msgid "ID: %#08lx"
+msgstr ""
+
+#: peigen.c:2063 pepigen.c:2063 pex64igen.c:2063
+#, c-format
+msgid ", Value: %#08lx\n"
+msgstr ""
+
+#: peigen.c:2074 pepigen.c:2074 pex64igen.c:2074
+#, c-format
+msgid "%*.s Leaf: Addr: %#08lx, Size: %#08lx, Codepage: %d\n"
+msgstr ""
+
+#: peigen.c:2116 pepigen.c:2116 pex64igen.c:2116
+#, c-format
+msgid " Table: Char: %d, Time: %08lx, Ver: %d/%d, Num Names: %d, IDs: %d\n"
+msgstr ""
+
+#: peigen.c:2204 pepigen.c:2204 pex64igen.c:2204
+#, c-format
+msgid "Corrupt .rsrc section detected!\n"
+msgstr ""
+
+#: peigen.c:2220 pepigen.c:2220 pex64igen.c:2220
+#, c-format
+msgid ""
+"\n"
+"WARNING: Extra data in .rsrc section - it will be ignored by Windows:\n"
+msgstr ""
+
+#. The MS dumpbin program reportedly ands with 0xff0f before
+#. printing the characteristics field. Not sure why. No reason to
+#. emulate it here.
+#: peigen.c:2243 pepigen.c:2243 pex64igen.c:2243
+#, c-format
+msgid ""
+"\n"
+"Characteristics 0x%x\n"
+msgstr ""
+
+#: peigen.c:3194 pepigen.c:3194 pex64igen.c:3194
+#, c-format
+msgid ".rsrc merge failure: duplicate string resource: %d"
+msgstr ""
+
+#: peigen.c:3329 pepigen.c:3329 pex64igen.c:3329
+msgid ".rsrc merge failure: multiple non-default manifests"
+msgstr ""
+
+#: peigen.c:3347 pepigen.c:3347 pex64igen.c:3347
+msgid ".rsrc merge failure: a directory matches a leaf"
+msgstr ""
+
+#: peigen.c:3389 pepigen.c:3389 pex64igen.c:3389
+msgid ".rsrc merge failure: duplicate leaf"
+msgstr ""
+
+#: peigen.c:3391 pepigen.c:3391 pex64igen.c:3391
+#, c-format
+msgid ".rsrc merge failure: duplicate leaf: %s"
+msgstr ""
+
+#: peigen.c:3457 pepigen.c:3457 pex64igen.c:3457
+msgid ".rsrc merge failure: dirs with differing characteristics\n"
+msgstr ""
+
+#: peigen.c:3464 pepigen.c:3464 pex64igen.c:3464
+msgid ".rsrc merge failure: differing directory versions\n"
+msgstr ""
+
+#. Corrupted .rsrc section - cannot merge.
+#: peigen.c:3537 pepigen.c:3537 pex64igen.c:3537
+#, c-format
+msgid "%s: .rsrc merge failure: corrupt .rsrc section"
+msgstr ""
+
+#: peigen.c:3673 pepigen.c:3673 pex64igen.c:3673
+msgid "%B: unable to fill in DataDictionary[1] because .idata$2 is missing"
+msgstr ""
+
+#: peigen.c:3693 pepigen.c:3693 pex64igen.c:3693
+msgid "%B: unable to fill in DataDictionary[1] because .idata$4 is missing"
+msgstr ""
+
+#: peigen.c:3714 pepigen.c:3714 pex64igen.c:3714
+msgid "%B: unable to fill in DataDictionary[12] because .idata$5 is missing"
+msgstr ""
+
+#: peigen.c:3734 pepigen.c:3734 pex64igen.c:3734
+msgid ""
+"%B: unable to fill in DataDictionary[PE_IMPORT_ADDRESS_TABLE (12)] because ."
+"idata$6 is missing"
+msgstr ""
+
+#: peigen.c:3776 pepigen.c:3776 pex64igen.c:3776
+msgid ""
+"%B: unable to fill in DataDictionary[PE_IMPORT_ADDRESS_TABLE(12)] because ."
+"idata$6 is missing"
+msgstr ""
+
+#: peigen.c:3801 pepigen.c:3801 pex64igen.c:3801
+msgid "%B: unable to fill in DataDictionary[9] because __tls_used is missing"
+msgstr ""
diff --git a/bfd/po/da.gmo b/bfd/po/da.gmo
new file mode 100644
index 0000000..deb4565
--- /dev/null
+++ b/bfd/po/da.gmo
Binary files differ
diff --git a/bfd/po/da.po b/bfd/po/da.po
new file mode 100644
index 0000000..5cac995
--- /dev/null
+++ b/bfd/po/da.po
@@ -0,0 +1,6159 @@
+# Danish messages for bfd.
+# Copyright (C) 2001, 2002, 2011 Free Software Foundation, Inc.
+# This file is distributed under the same license as the binutils package.
+#
+# Keld Simonsen <keld@dkuug.dk>, 2002-2003
+# Ask Hjorth Larsen <asklarsen@gmail.com>, 2011
+#
+# Følgende konventioner bruges, men jeg er ikke sikker på at de nødvendigvis er de bedste:
+#
+# entry (alene) -> post
+# entry point -> startpunkt
+# link -> lænke
+# overlay -> overlay
+# relax -> forenkle
+# record -> post
+# image -> aftryk
+# TOC -> TOC (=table of contents, evt. indholdsfortegnelse)
+msgid ""
+msgstr ""
+"Project-Id-Version: bfd-2.20.90\n"
+"Report-Msgid-Bugs-To: bug-binutils@gnu.org\n"
+"POT-Creation-Date: 2010-11-05 11:31+0100\n"
+"PO-Revision-Date: 2011-03-16 02:31+0100\n"
+"Last-Translator: Ask Hjorth Larsen <asklarsen@gmail.com>\n"
+"Language-Team: Danish <dansk@dansk-gruppen.dk>\n"
+"Language: da\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: aout-adobe.c:127
+msgid "%B: Unknown section type in a.out.adobe file: %x\n"
+msgstr "%B: Ukendt sektionstype i a.out.adobe-fil: %x\n"
+
+#: aout-cris.c:199
+#, c-format
+msgid "%s: Invalid relocation type exported: %d"
+msgstr "%s: Ugyldig relokeringstype eksporteret: %d"
+
+#: aout-cris.c:242
+msgid "%B: Invalid relocation type imported: %d"
+msgstr "%B: Ugyldig relokeringstype importeret: %d"
+
+#: aout-cris.c:253
+msgid "%B: Bad relocation record imported: %d"
+msgstr "%B: Fejlagtig relokeringspost importeret: %d"
+
+#: aoutx.h:1273 aoutx.h:1611
+#, c-format
+msgid "%s: can not represent section `%s' in a.out object file format"
+msgstr "%s: kan ikke repræsentere sektionen \"%s\" i a.out-objektfilformat"
+
+#: aoutx.h:1577
+#, c-format
+msgid "%s: can not represent section for symbol `%s' in a.out object file format"
+msgstr "%s: kan ikke repræsentere sektion for symbolet \"%s\" i a.out-objektfilformat"
+
+#: aoutx.h:1579 vms-alpha.c:7649
+msgid "*unknown*"
+msgstr "*ukendt*"
+
+#: aoutx.h:4007 aoutx.h:4333
+msgid "%P: %B: unexpected relocation type\n"
+msgstr "%P: %B: uventet relokeringstype\n"
+
+#: aoutx.h:5364
+#, c-format
+msgid "%s: relocatable link from %s to %s not supported"
+msgstr "%s: relokérbar lænke fra %s til %s understøttes ikke"
+
+#: archive.c:2125
+msgid "Warning: writing archive was slow: rewriting timestamp\n"
+msgstr "Advarsel: arkivskrivning var langsom: genskriver tidsstempel\n"
+
+#: archive.c:2416
+msgid "Reading archive file mod timestamp"
+msgstr "Læser arkivfilens ændringstidsstempel"
+
+#: archive.c:2440
+msgid "Writing updated armap timestamp"
+msgstr "Skriver opdateret armap-tidsstempel"
+
+#: bfd.c:395
+msgid "No error"
+msgstr "Ingen fejl"
+
+#: bfd.c:396
+msgid "System call error"
+msgstr "Systemkaldsfejl"
+
+#: bfd.c:397
+msgid "Invalid bfd target"
+msgstr "Ugyldigt bfd-mål"
+
+#: bfd.c:398
+msgid "File in wrong format"
+msgstr "Filen er i forkert format"
+
+#: bfd.c:399
+msgid "Archive object file in wrong format"
+msgstr "Arkivobjektfil er i forkert format"
+
+#: bfd.c:400
+msgid "Invalid operation"
+msgstr "Ugyldig handling"
+
+#: bfd.c:401
+msgid "Memory exhausted"
+msgstr "Hukommelsen er opbrugt"
+
+#: bfd.c:402
+msgid "No symbols"
+msgstr "Ingen symboler"
+
+#: bfd.c:403
+msgid "Archive has no index; run ranlib to add one"
+msgstr "Arkivet har intet indeks; kør ranlib til at tilføje ét"
+
+#: bfd.c:404
+msgid "No more archived files"
+msgstr "Ikke flere arkiverede filer"
+
+#: bfd.c:405
+msgid "Malformed archive"
+msgstr "Forvansket arkiv"
+
+#: bfd.c:406
+msgid "File format not recognized"
+msgstr "Filformatet ikke genkendt"
+
+#: bfd.c:407
+msgid "File format is ambiguous"
+msgstr "Filformatet er flertydigt"
+
+#: bfd.c:408
+msgid "Section has no contents"
+msgstr "Sektionen har intet indhold"
+
+#: bfd.c:409
+msgid "Nonrepresentable section on output"
+msgstr "Ikkerepræsenterbar sektion i uddata"
+
+#: bfd.c:410
+msgid "Symbol needs debug section which does not exist"
+msgstr "Symbolet kræver fejlsøgningssektion som ikke eksisterer"
+
+#: bfd.c:411
+msgid "Bad value"
+msgstr "Fejlagtigt værdi"
+
+#: bfd.c:412
+msgid "File truncated"
+msgstr "Filen trunkeret"
+
+#: bfd.c:413
+msgid "File too big"
+msgstr "Filen er for stor"
+
+#: bfd.c:414
+#, c-format
+msgid "Error reading %s: %s"
+msgstr "Fejl ved læsning af %s: %s"
+
+#: bfd.c:415
+msgid "#<Invalid error code>"
+msgstr "#<Ugyldig fejlkode>"
+
+#: bfd.c:939
+#, c-format
+msgid "BFD %s assertion fail %s:%d"
+msgstr "BFD %s-forsikring mislykkedes %s:%d"
+
+#: bfd.c:951
+#, c-format
+msgid "BFD %s internal error, aborting at %s line %d in %s\n"
+msgstr "Intern BFD %s-fejl, afbryder ved %s linje %d i %s\n"
+
+#: bfd.c:955
+#, c-format
+msgid "BFD %s internal error, aborting at %s line %d\n"
+msgstr "Internt BFD %s-fejl, afbryder ved %s linje %d\n"
+
+#: bfd.c:957
+msgid "Please report this bug.\n"
+msgstr "Rapportér gerne denne fejl.\n"
+
+#: bfdwin.c:206
+#, c-format
+msgid "not mapping: data=%lx mapped=%d\n"
+msgstr "mapper ikke: data=%lx mappet=%d\n"
+
+#: bfdwin.c:209
+#, c-format
+msgid "not mapping: env var not set\n"
+msgstr "mapper ikke: miljøvariabel er ikke sat\n"
+
+#: binary.c:271
+#, c-format
+msgid "Warning: Writing section `%s' to huge (ie negative) file offset 0x%lx."
+msgstr "Advarsel: Skrivning af sektionen \"%s\" til enorm (dvs negativ) afsætsbyte 0x%lx."
+
+#: bout.c:1146 elf-m10300.c:2063 elf32-avr.c:1640 elf32-frv.c:5740
+#: elfxx-sparc.c:2795 reloc.c:5646 reloc16.c:162 elf32-ia64.c:842
+#: elf64-ia64.c:842
+msgid "%P%F: --relax and -r may not be used together\n"
+msgstr "%P%F: --relax og -r kan ikke bruges sammen\n"
+
+#: cache.c:226
+msgid "reopening %B: %s\n"
+msgstr "genåbner %B: %s\n"
+
+#: coff-alpha.c:491
+msgid ""
+"%B: Cannot handle compressed Alpha binaries.\n"
+" Use compiler flags, or objZ, to generate uncompressed binaries."
+msgstr ""
+"%B: Kan ikke håndtere komprimerede Alpha-binærfiler.\n"
+" Brug kompilerflag eller objZ til at generere ukomprimerede binærfiler."
+
+#: coff-alpha.c:648
+msgid "%B: unknown/unsupported relocation type %d"
+msgstr "%B: relokeringstypen %d kendes eller understøttes ikke"
+
+#: coff-alpha.c:900 coff-alpha.c:937 coff-alpha.c:2025 coff-mips.c:1003
+msgid "GP relative relocation used when GP not defined"
+msgstr "GP-relativ relokering bruges når GP ikke er defineret"
+
+#: coff-alpha.c:1502
+msgid "using multiple gp values"
+msgstr "bruger flere gp-værdier"
+
+#: coff-alpha.c:1561
+msgid "%B: unsupported relocation: ALPHA_R_GPRELHIGH"
+msgstr "%B: relokering understøttes ikke: ALPHA_R_GPRELHIGH"
+
+#: coff-alpha.c:1568
+msgid "%B: unsupported relocation: ALPHA_R_GPRELLOW"
+msgstr "%B: relokering understøttes ikke: ALPHA_R_GPRELLOW"
+
+#: coff-alpha.c:1575 elf32-m32r.c:2493 elf64-alpha.c:3991 elf64-alpha.c:4140
+#: elf32-ia64.c:4582 elf64-ia64.c:4582
+msgid "%B: unknown relocation type %d"
+msgstr "%B: ukendt relokeringstype %d"
+
+#: coff-arm.c:1038
+#, c-format
+msgid "%B: unable to find THUMB glue '%s' for `%s'"
+msgstr "%B: kan ikke finde THUMB-klistret \"%s\" til \"%s\""
+
+#: coff-arm.c:1067
+#, c-format
+msgid "%B: unable to find ARM glue '%s' for `%s'"
+msgstr "%B: kan ikke finde ARM-klistret \"%s\" til \"%s\""
+
+#: coff-arm.c:1369 elf32-arm.c:6501
+#, c-format
+msgid ""
+"%B(%s): warning: interworking not enabled.\n"
+" first occurrence: %B: arm call to thumb"
+msgstr ""
+"%B(%s): advarsel: samvirken (interworking) er ikke aktiveret.\n"
+" første forekomst: %B: arm-kald til thumb"
+
+#: coff-arm.c:1459
+#, c-format
+msgid ""
+"%B(%s): warning: interworking not enabled.\n"
+" first occurrence: %B: thumb call to arm\n"
+" consider relinking with --support-old-code enabled"
+msgstr ""
+"%B(%s): advarsel: \"Interworking\" er ikke slået til.\n"
+" første forekomst: %B: thumb-kald til arm\n"
+" overvej at genlænke med --support-old-code tilvalgt"
+
+#: coff-arm.c:1754 coff-tic80.c:695 cofflink.c:3043
+msgid "%B: bad reloc address 0x%lx in section `%A'"
+msgstr "%B: fejlagtig relokeringsadresse 0x%lx i sektionen \"%s\""
+
+#: coff-arm.c:2079
+msgid "%B: illegal symbol index in reloc: %d"
+msgstr "%B: illegalt symbolindeks i relokering: %d"
+
+#: coff-arm.c:2210
+#, c-format
+msgid "error: %B is compiled for APCS-%d, whereas %B is compiled for APCS-%d"
+msgstr "fejl: %B er kompileret til APCS-%d, mens %B er kompileret til APCS-%d"
+
+#: coff-arm.c:2226 elf32-arm.c:14105
+#, c-format
+msgid "error: %B passes floats in float registers, whereas %B passes them in integer registers"
+msgstr "fejl: %B overfører flydende tal i flydendetalsregistre, mens %B overfører dem i heltalsregistre"
+
+#: coff-arm.c:2229 elf32-arm.c:14109
+#, c-format
+msgid "error: %B passes floats in integer registers, whereas %B passes them in float registers"
+msgstr "fejl: %B overfører flydende tal i heltalsregistre, mens %B overfører dem i flydendetalsregistre"
+
+#: coff-arm.c:2243
+#, c-format
+msgid "error: %B is compiled as position independent code, whereas target %B is absolute position"
+msgstr "fejl: %s er kompileret som positionsuafhængig kode, mens målet %B har absolut position"
+
+#: coff-arm.c:2246
+#, c-format
+msgid "error: %B is compiled as absolute position code, whereas target %B is position independent"
+msgstr "fejl: %B er kompileret som kode med absolut position, mens målet %B er positionsuafhængigt"
+
+#: coff-arm.c:2274 elf32-arm.c:14174
+#, c-format
+msgid "Warning: %B supports interworking, whereas %B does not"
+msgstr "Advarsel: %B understøtter samvirken (interworking), mens %B ikke gør det"
+
+#: coff-arm.c:2277 elf32-arm.c:14180
+#, c-format
+msgid "Warning: %B does not support interworking, whereas %B does"
+msgstr "Advarsel: %B understøtter ikke samvirken (interworking), mens %B gør det"
+
+#: coff-arm.c:2301
+#, c-format
+msgid "private flags = %x:"
+msgstr "private flag = %x:"
+
+#: coff-arm.c:2309 elf32-arm.c:10492
+#, c-format
+msgid " [floats passed in float registers]"
+msgstr " [flydende tal overført i flydendetalsregistre]"
+
+#: coff-arm.c:2311
+#, c-format
+msgid " [floats passed in integer registers]"
+msgstr " [flydende tal overført i heltalsregistre]"
+
+#: coff-arm.c:2314 elf32-arm.c:10495
+#, c-format
+msgid " [position independent]"
+msgstr " [positionsuafhængigt]"
+
+#: coff-arm.c:2316
+#, c-format
+msgid " [absolute position]"
+msgstr " [absolut position]"
+
+#: coff-arm.c:2320
+#, c-format
+msgid " [interworking flag not initialised]"
+msgstr " [samvirkendeflag er ikke initieret]"
+
+#: coff-arm.c:2322
+#, c-format
+msgid " [interworking supported]"
+msgstr " [samvirken understøttes]"
+
+#: coff-arm.c:2324
+#, c-format
+msgid " [interworking not supported]"
+msgstr " [samvirken understøttes ikke]"
+
+#: coff-arm.c:2370 elf32-arm.c:9520
+#, c-format
+msgid "Warning: Not setting interworking flag of %B since it has already been specified as non-interworking"
+msgstr "Advarsel: Sætter ikke samvirkeflaget (interworking) for %B, da den allerede er angivet som ikke-samvirkende"
+
+#: coff-arm.c:2374 elf32-arm.c:9524
+#, c-format
+msgid "Warning: Clearing the interworking flag of %B due to outside request"
+msgstr "Advarsel: Fjerner samvirkeflaget (interworking) for %B på grund af anmodning udefra"
+
+#: coff-h8300.c:1122
+#, c-format
+msgid "cannot handle R_MEM_INDIRECT reloc when using %s output"
+msgstr "kan ikke håndtere R_MEM_INDIRECT-relokering ved brug af %s-uddata"
+
+#: coff-i860.c:147
+#, c-format
+msgid "Relocation `%s' not yet implemented\n"
+msgstr "Relokeringen \"%s\" er endnu ikke implementeret\n"
+
+#: coff-i860.c:605 coff-tic54x.c:398 coffcode.h:5147
+msgid "%B: warning: illegal symbol index %ld in relocs"
+msgstr "%B: advarsel: illegalt symbolindeks %ld i relokeringerne"
+
+#: coff-i960.c:143 coff-i960.c:506
+msgid "uncertain calling convention for non-COFF symbol"
+msgstr "usikker kaldskonvention for ikke-COFF-symbol"
+
+#: coff-m68k.c:506 elf32-bfin.c:5678 elf32-cr16.c:2897 elf32-m68k.c:4672
+msgid "unsupported reloc type"
+msgstr "relokeringstypen understøttes ikke"
+
+#: coff-mips.c:688 elf32-mips.c:1014 elf32-score.c:430 elf32-score7.c:330
+#: elf64-mips.c:2019 elfn32-mips.c:1832
+msgid "GP relative relocation when _gp not defined"
+msgstr "GP-relativ relokering når _gp ikke var defineret"
+
+#: coff-or32.c:229
+msgid "Unrecognized reloc"
+msgstr "Ukendt relokering"
+
+#: coff-rs6000.c:2794
+#, c-format
+msgid "%s: unsupported relocation type 0x%02x"
+msgstr "%s: relokeringstypen 0x%02x understøttes ikke"
+
+#: coff-rs6000.c:2887
+#, c-format
+msgid "%s: TOC reloc at 0x%x to symbol `%s' with no TOC entry"
+msgstr "%s: TOC-relokering ved 0x%x til symbolet \"%s\" uden nogen TOC-post"
+
+#: coff-rs6000.c:3652 coff64-rs6000.c:2175
+msgid "%B: symbol `%s' has unrecognized smclas %d"
+msgstr "%B: symbolet \"%s\" har ukendt smclas %d"
+
+#: coff-tic4x.c:195 coff-tic54x.c:299 coff-tic80.c:458
+#, c-format
+msgid "Unrecognized reloc type 0x%x"
+msgstr "Ukendt relokeringstype 0x%x"
+
+#: coff-tic4x.c:240
+#, c-format
+msgid "%s: warning: illegal symbol index %ld in relocs"
+msgstr "%s: advarsel: ikke tilladt symbolindeks %ld i relokeringerne"
+
+#: coff-w65.c:367
+#, c-format
+msgid "ignoring reloc %s\n"
+msgstr "ignorerer relokering %s\n"
+
+#: coffcode.h:973
+msgid "%B: warning: COMDAT symbol '%s' does not match section name '%s'"
+msgstr "%B: advarsel: COMDAT-symbol \"%s\" passer ikke til sektionsnavnet \"%s\""
+
+#. Generate a warning message rather using the 'unhandled'
+#. variable as this will allow some .sys files generate by
+#. other toolchains to be processed. See bugzilla issue 196.
+#: coffcode.h:1197
+msgid "%B: Warning: Ignoring section flag IMAGE_SCN_MEM_NOT_PAGED in section %s"
+msgstr "%B: Advarsel: Ignorerer sektionsflag IMAGE_SCN_MEM_NOT_PAGED i sektionen %s"
+
+#: coffcode.h:1264
+msgid "%B (%s): Section flag %s (0x%x) ignored"
+msgstr "%B (%s): Sektionsflag %s (0x%x) ignoreret"
+
+#: coffcode.h:2390
+#, c-format
+msgid "Unrecognized TI COFF target id '0x%x'"
+msgstr "Ukendt TI COFF-mål-id \"0x%x\""
+
+#: coffcode.h:2704
+msgid "%B: reloc against a non-existant symbol index: %ld"
+msgstr "%B: relokering mod et ikke-eksisterende symbolindeks: %ld"
+
+#: coffcode.h:3262
+msgid "%B: too many sections (%d)"
+msgstr "%B: for mange sektioner (%d)"
+
+#: coffcode.h:3676
+msgid "%B: section %s: string table overflow at offset %ld"
+msgstr "%B: sektion %s: overløb i strengtabel ved afsæt %ld"
+
+#: coffcode.h:4481
+msgid "%B: warning: line number table read failed"
+msgstr "%B: advarsel: læsning af linjenummertabel mislykkedes"
+
+#: coffcode.h:4511
+msgid "%B: warning: illegal symbol index %ld in line numbers"
+msgstr "%B: advarsel: illegalt symbolindeks %ld i linjetal"
+
+#: coffcode.h:4525
+msgid "%B: warning: duplicate line number information for `%s'"
+msgstr "%B: advarsel: dobbelt linjenummersinformation for \"%s\""
+
+#: coffcode.h:4916
+msgid "%B: Unrecognized storage class %d for %s symbol `%s'"
+msgstr "%B: Ukendt lagringsklasse %d for %s-symbolet \"%s\""
+
+#: coffcode.h:5042
+msgid "warning: %B: local symbol `%s' has no section"
+msgstr "advarsel: %B: lokalt symbol \"%s\" har ingen sektion"
+
+#: coffcode.h:5186
+msgid "%B: illegal relocation type %d at address 0x%lx"
+msgstr "%B: ikke tilladt relokeringstype %d på adresse 0x%lx"
+
+#: coffgen.c:1573
+msgid "%B: bad string table size %lu"
+msgstr "%B: fejlagtig strengtabelstørrelse %lu"
+
+#: cofflink.c:524 elflink.c:4339
+msgid "Warning: type of symbol `%s' changed from %d to %d in %B"
+msgstr "Advarsel: typen på symbol \"%s\" ændredes fra %d til %d i %B"
+
+#: cofflink.c:2321
+msgid "%B: relocs in section `%A', but it has no contents"
+msgstr "%B: relokeringer i sektionen \"%s\", men den har intet indhold"
+
+#: cofflink.c:2652 coffswap.h:826
+#, c-format
+msgid "%s: %s: reloc overflow: 0x%lx > 0xffff"
+msgstr "%s: %s: relokering giver overløb: 0x%lx > 0xffff"
+
+#: cofflink.c:2661 coffswap.h:812
+#, c-format
+msgid "%s: warning: %s: line number overflow: 0x%lx > 0xffff"
+msgstr "%s: advarsel: %s: linjenummer giver overløb: 0x%lx > 0xffff"
+
+#: cpu-arm.c:189 cpu-arm.c:200
+msgid "error: %B is compiled for the EP9312, whereas %B is compiled for XScale"
+msgstr "fejl: %B kompileret til EP9312, mens %B er kompileret til XScale"
+
+#: cpu-arm.c:333
+#, c-format
+msgid "warning: unable to update contents of %s section in %s"
+msgstr "advarsel: kan ikke opdatere indholdet af %s-sektion i %s"
+
+#: dwarf2.c:490
+#, c-format
+msgid "Dwarf Error: Can't find %s section."
+msgstr "Dwarf-fejl: Kan ikke finde %s-sektion."
+
+#: dwarf2.c:518
+#, c-format
+msgid "Dwarf Error: Offset (%lu) greater than or equal to %s size (%lu)."
+msgstr "Dwarf-fejl: Afsæt (%lu) større end eller lig med %s-størrelse (%lu)."
+
+#: dwarf2.c:940
+#, c-format
+msgid "Dwarf Error: Invalid or unhandled FORM value: %u."
+msgstr "Dwarf-fejl: Ugyldig eller ubehandlet FORM-værdi: %u."
+
+#: dwarf2.c:1191
+msgid "Dwarf Error: mangled line number section (bad file number)."
+msgstr "Dwarf-fejl: vanskabt linjenummerssektion (fejlagtigt filnummer)."
+
+#: dwarf2.c:1443
+#, c-format
+msgid "Dwarf Error: Unhandled .debug_line version %d."
+msgstr "Dwarf-fejl: Uhåndteret .debug_line-version %d."
+
+#: dwarf2.c:1465
+msgid "Dwarf Error: Invalid maximum operations per instruction."
+msgstr "Dwarf-fejl: Ugyldigt maksimalt antal operationer per instruktion."
+
+#: dwarf2.c:1652
+msgid "Dwarf Error: mangled line number section."
+msgstr "Dwarf-fejl: vanskabt linjenummerssektion."
+
+#: dwarf2.c:1978 dwarf2.c:2098 dwarf2.c:2382
+#, c-format
+msgid "Dwarf Error: Could not find abbrev number %u."
+msgstr "Dwarf-fejl: Kunne ikke finde forkortelsesnumret %u."
+
+#: dwarf2.c:2343
+#, c-format
+msgid "Dwarf Error: found dwarf version '%u', this reader only handles version 2, 3 and 4 information."
+msgstr "Dwarf-fejl: fandt dwarf version \"%u\", men denne læser kan kun håndtere information fra version 2, 3 og 4."
+
+#: dwarf2.c:2350
+#, c-format
+msgid "Dwarf Error: found address size '%u', this reader can not handle sizes greater than '%u'."
+msgstr "Dwarf-fejl: fandt adressestørrelsen \"%u\", denne læser kan ikke håndtere størrelser større end \"%u\"."
+
+#: dwarf2.c:2373
+#, c-format
+msgid "Dwarf Error: Bad abbrev number: %u."
+msgstr "Dwarf-fejl: Fejlagtigt forkortelsesnummer: %u."
+
+#: ecoff.c:1237
+#, c-format
+msgid "Unknown basic type %d"
+msgstr "Ukendt grundtype %d"
+
+#: ecoff.c:1494
+#, c-format
+msgid ""
+"\n"
+" End+1 symbol: %ld"
+msgstr ""
+"\n"
+" Symbol slut+1: %ld"
+
+#: ecoff.c:1501 ecoff.c:1504
+#, c-format
+msgid ""
+"\n"
+" First symbol: %ld"
+msgstr ""
+"\n"
+" Første symbol: %ld"
+
+#: ecoff.c:1516
+#, c-format
+msgid ""
+"\n"
+" End+1 symbol: %-7ld Type: %s"
+msgstr ""
+"\n"
+" Symbol slut+1: %-7ld Type: %s"
+
+#: ecoff.c:1523
+#, c-format
+msgid ""
+"\n"
+" Local symbol: %ld"
+msgstr ""
+"\n"
+" Lokalt symbol: %ld"
+
+#: ecoff.c:1531
+#, c-format
+msgid ""
+"\n"
+" struct; End+1 symbol: %ld"
+msgstr ""
+"\n"
+" struct; symbol slut+1: %ld"
+
+#: ecoff.c:1536
+#, c-format
+msgid ""
+"\n"
+" union; End+1 symbol: %ld"
+msgstr ""
+"\n"
+" union; symbol slut+1: %ld"
+
+#: ecoff.c:1541
+#, c-format
+msgid ""
+"\n"
+" enum; End+1 symbol: %ld"
+msgstr ""
+"\n"
+" enum; symbol slut+1: %ld"
+
+#: ecoff.c:1547
+#, c-format
+msgid ""
+"\n"
+" Type: %s"
+msgstr ""
+"\n"
+" Type: %s"
+
+#: elf-attrs.c:569
+msgid "error: %B: Object has vendor-specific contents that must be processed by the '%s' toolchain"
+msgstr "fejl: %B: Objekt har leverandørspecifikt indhold, som skal behandles med '%s'-værktøjerne"
+
+#: elf-attrs.c:578
+msgid "error: %B: Object tag '%d, %s' is incompatible with tag '%d, %s'"
+msgstr "fejl: %B: Objektmærke \"%d, %d\" er ikke kompatibelt med mærket \"%d, %s\""
+
+#: elf-eh-frame.c:913
+msgid "%P: error in %B(%A); no .eh_frame_hdr table will be created.\n"
+msgstr "%P: fejl i %B(%A); ingen .eh_frame_hdr-tabel vil blive oprettet.\n"
+
+#: elf-eh-frame.c:1165
+msgid "%P: fde encoding in %B(%A) prevents .eh_frame_hdr table being created.\n"
+msgstr "%P: fde-kodning i %B(%A) forhindrer .eh_frame_hdr-tabel i at blive oprettet.\n"
+
+#: elf-ifunc.c:179
+msgid "%F%P: dynamic STT_GNU_IFUNC symbol `%s' with pointer equality in `%B' can not be used when making an executable; recompile with -fPIE and relink with -pie\n"
+msgstr "%F%P: dynamisk STT_GNU_IFUNC-symbol \"%s\" med pointerlighed i \"%B\" kan ikke bruges når der oprettes en eksekverbar fil; genkompilér med -fPIE og genlænk med -pie\n"
+
+#: elf-m10200.c:450 elf-m10300.c:1560 elf32-avr.c:1263 elf32-bfin.c:3193
+#: elf32-cr16.c:1482 elf32-cr16c.c:780 elf32-cris.c:2077 elf32-crx.c:922
+#: elf32-d10v.c:509 elf32-fr30.c:609 elf32-frv.c:4111 elf32-h8300.c:509
+#: elf32-i860.c:1211 elf32-ip2k.c:1468 elf32-iq2000.c:684 elf32-lm32.c:1168
+#: elf32-m32c.c:553 elf32-m32r.c:3111 elf32-m68hc1x.c:1138 elf32-mep.c:534
+#: elf32-microblaze.c:1231 elf32-moxie.c:282 elf32-msp430.c:486 elf32-mt.c:395
+#: elf32-openrisc.c:404 elf32-score.c:2731 elf32-score7.c:2540
+#: elf32-spu.c:5042 elf32-v850.c:2143 elf32-xstormy16.c:941 elf64-mmix.c:1522
+msgid "internal error: out of range error"
+msgstr "intern fejl: uden for intervallet"
+
+#: elf-m10200.c:454 elf-m10300.c:1564 elf32-avr.c:1267 elf32-bfin.c:3197
+#: elf32-cr16.c:1486 elf32-cr16c.c:784 elf32-cris.c:2081 elf32-crx.c:926
+#: elf32-d10v.c:513 elf32-fr30.c:613 elf32-frv.c:4115 elf32-h8300.c:513
+#: elf32-i860.c:1215 elf32-iq2000.c:688 elf32-lm32.c:1172 elf32-m32c.c:557
+#: elf32-m32r.c:3115 elf32-m68hc1x.c:1142 elf32-mep.c:538
+#: elf32-microblaze.c:1235 elf32-moxie.c:286 elf32-msp430.c:490
+#: elf32-openrisc.c:408 elf32-score.c:2735 elf32-score7.c:2544
+#: elf32-spu.c:5046 elf32-v850.c:2147 elf32-xstormy16.c:945 elf64-mmix.c:1526
+#: elfxx-mips.c:9186
+msgid "internal error: unsupported relocation error"
+msgstr "intern fejl: relokeringen understøttes ikke"
+
+#: elf-m10200.c:458 elf32-cr16.c:1490 elf32-cr16c.c:788 elf32-crx.c:930
+#: elf32-d10v.c:517 elf32-h8300.c:517 elf32-lm32.c:1176 elf32-m32r.c:3119
+#: elf32-m68hc1x.c:1146 elf32-microblaze.c:1239 elf32-score.c:2739
+#: elf32-score7.c:2548 elf32-spu.c:5050
+msgid "internal error: dangerous error"
+msgstr "intern fejl: farlig fejl"
+
+#: elf-m10200.c:462 elf-m10300.c:1577 elf32-avr.c:1275 elf32-bfin.c:3205
+#: elf32-cr16.c:1494 elf32-cr16c.c:792 elf32-cris.c:2089 elf32-crx.c:934
+#: elf32-d10v.c:521 elf32-fr30.c:621 elf32-frv.c:4123 elf32-h8300.c:521
+#: elf32-i860.c:1223 elf32-ip2k.c:1483 elf32-iq2000.c:696 elf32-lm32.c:1180
+#: elf32-m32c.c:565 elf32-m32r.c:3123 elf32-m68hc1x.c:1150 elf32-mep.c:546
+#: elf32-microblaze.c:1243 elf32-moxie.c:294 elf32-msp430.c:498 elf32-mt.c:403
+#: elf32-openrisc.c:416 elf32-score.c:2748 elf32-score7.c:2552
+#: elf32-spu.c:5054 elf32-v850.c:2167 elf32-xstormy16.c:953 elf64-mmix.c:1534
+msgid "internal error: unknown error"
+msgstr "intern fejl: ukendt fejl"
+
+#: elf-m10300.c:1504 elf32-arm.c:9098 elf32-i386.c:4081 elf32-m32r.c:2604
+#: elf32-m68k.c:4156 elf32-ppc.c:8089 elf32-s390.c:3010 elf32-sh.c:4223
+#: elf32-xtensa.c:3067 elf64-ppc.c:13115 elf64-s390.c:2985 elf64-sh64.c:1636
+#: elf64-x86-64.c:3719 elfxx-sparc.c:3806
+msgid "%B(%A+0x%lx): unresolvable %s relocation against symbol `%s'"
+msgstr "%B(%A+0x%lx): uløselig %s-relokering mod symbol \"%s\""
+
+#: elf-m10300.c:1569
+msgid "error: inappropriate relocation type for shared library (did you forget -fpic?)"
+msgstr "fejl: upassende relokeringstype til delt bibliotek (glemte du -fpic?)"
+
+#: elf-m10300.c:1572
+msgid "internal error: suspicious relocation type used in shared library"
+msgstr "intern fejl: mistænkelig relokeringstype brugt i delt bibliotek"
+
+#: elf-m10300.c:4372 elf32-arm.c:11392 elf32-cr16.c:2451 elf32-cris.c:3044
+#: elf32-hppa.c:1894 elf32-i370.c:503 elf32-i386.c:2036 elf32-lm32.c:1868
+#: elf32-m32r.c:1927 elf32-m68k.c:3252 elf32-ppc.c:4994 elf32-s390.c:1652
+#: elf32-sh.c:2931 elf32-vax.c:1040 elf64-ppc.c:6483 elf64-s390.c:1635
+#: elf64-sh64.c:3377 elf64-x86-64.c:1871 elfxx-sparc.c:2104
+#, c-format
+msgid "dynamic variable `%s' is zero size"
+msgstr "dynamisk variabel \"%s\" har størrelse nul"
+
+#: elf.c:334
+msgid "%B: invalid string offset %u >= %lu for section `%s'"
+msgstr "%B: ugyldigt strengafsæt %u >= %lu for sektionen \"%s\""
+
+#: elf.c:446
+msgid "%B symbol number %lu references nonexistent SHT_SYMTAB_SHNDX section"
+msgstr "%B-symbol nummer %lu refererer SHT_SYMTAB_SHNDX-sektion, der ikke findes"
+
+#: elf.c:602
+msgid "%B: Corrupt size field in group section header: 0x%lx"
+msgstr "%B: Beskadiget størrelsesfelt i gruppesektionshoved: 0x%lx"
+
+#: elf.c:638
+msgid "%B: invalid SHT_GROUP entry"
+msgstr "%B: ugyldig SHT_GROUP-post"
+
+#: elf.c:708
+msgid "%B: no group info for section %A"
+msgstr "%B: ingen gruppeinformation for sektionen %A"
+
+#: elf.c:737 elf.c:3090 elflink.c:10062
+msgid "%B: warning: sh_link not set for section `%A'"
+msgstr "%B: advarsel: sh_link ikke givet for sektionen \"%s\""
+
+#: elf.c:756
+msgid "%B: sh_link [%d] in section `%A' is incorrect"
+msgstr "%B: sh_link [%d] sektionen \"%s\" er forkert"
+
+#: elf.c:791
+msgid "%B: unknown [%d] section `%s' in group [%s]"
+msgstr "%B: ukendt [%d] sektion \"%s\" i gruppe [%s]"
+
+#: elf.c:1041
+msgid "%B: unable to initialize commpress status for section %s"
+msgstr "%B: kan ikke initiere commpress-status for sektion %s"
+
+#: elf.c:1050
+msgid "%B: unable to initialize decommpress status for section %s"
+msgstr "%B: kan ikke klargøre afkomprimeringsstatus for sektion %s"
+
+#: elf.c:1158
+#, c-format
+msgid ""
+"\n"
+"Program Header:\n"
+msgstr ""
+"\n"
+"Programhoved:\n"
+
+#: elf.c:1200
+#, c-format
+msgid ""
+"\n"
+"Dynamic Section:\n"
+msgstr ""
+"\n"
+"Dynamisk sektion:\n"
+
+#: elf.c:1336
+#, c-format
+msgid ""
+"\n"
+"Version definitions:\n"
+msgstr ""
+"\n"
+"Versionsdefinitioner:\n"
+
+#: elf.c:1361
+#, c-format
+msgid ""
+"\n"
+"Version References:\n"
+msgstr ""
+"\n"
+"Versionsreferencer:\n"
+
+#: elf.c:1366
+#, c-format
+msgid " required from %s:\n"
+msgstr " kræves fra %s:\n"
+
+#: elf.c:1773
+msgid "%B: invalid link %lu for reloc section %s (index %u)"
+msgstr "%B: ugyldig lænke %lu for relokeringssektion %s (indeks %u)"
+
+#: elf.c:1943
+msgid "%B: don't know how to handle allocated, application specific section `%s' [0x%8x]"
+msgstr "%B: ved ikke hvordan allokeret, programspecifik sektion \"%s\" [0x%8x] skal håndteres"
+
+#: elf.c:1955
+msgid "%B: don't know how to handle processor specific section `%s' [0x%8x]"
+msgstr "%B: ved ikke hvordan processorspecifik sektion \"%s\" [0x%8x] skal håndteres"
+
+#: elf.c:1966
+msgid "%B: don't know how to handle OS specific section `%s' [0x%8x]"
+msgstr "%B: ved ikke hvordan OS-specifik sektion \"%s\" [0x%8x] skal håndteres"
+
+#: elf.c:1976
+msgid "%B: don't know how to handle section `%s' [0x%8x]"
+msgstr "%B: ved ikke hvordan sektion \"%s\" [0x%8x] skal håndteres"
+
+#: elf.c:2603
+#, c-format
+msgid "warning: section `%A' type changed to PROGBITS"
+msgstr "advarsel: typen af sektionen \"%A\" ændret til PROGBITS"
+
+#: elf.c:3047
+msgid "%B: sh_link of section `%A' points to discarded section `%A' of `%B'"
+msgstr "%B: sh_link af sektion \"%A\" peger på forkastet sektion \"%A\" i \"%B\""
+
+#: elf.c:3070
+msgid "%B: sh_link of section `%A' points to removed section `%A' of `%B'"
+msgstr "%B: sh_link af sektion \"%A\" peger på fjernet sektion \"%A\" af \"%B\""
+
+#: elf.c:4480
+msgid "%B: The first section in the PT_DYNAMIC segment is not the .dynamic section"
+msgstr "%B: Første sektion i segmentet PT_DYNAMIC er ikke .dynamic-sektionen"
+
+#: elf.c:4507
+msgid "%B: Not enough room for program headers, try linking with -N"
+msgstr "%s: Ikke tilstrækkeligt med plads til programhoveder, forsøg at lænke med -N"
+
+#: elf.c:4594
+msgid "%B: section %A lma %#lx adjusted to %#lx"
+msgstr "%B: sektion %A lma %#lx justeret til %#lx"
+
+#: elf.c:4713
+msgid "%B: section `%A' can't be allocated in segment %d"
+msgstr "%B: sektion \"%A\" kan ikke allokeres i segment %d"
+
+#: elf.c:4761
+msgid "%B: warning: allocated section `%s' not in segment"
+msgstr "%B: advarsel: allokeret sektion \"%s\" ikke i segment"
+
+#: elf.c:5257
+msgid "%B: symbol `%s' required but not present"
+msgstr "%B: symbol \"%s\" kræves, men er ikke tilstede"
+
+#: elf.c:5595
+msgid "%B: warning: Empty loadable segment detected, is this intentional ?\n"
+msgstr "%B: advarsel: Tomt indlæseligt segment opdaget, er dette meningen?\n"
+
+#: elf.c:6622
+#, c-format
+msgid "Unable to find equivalent output section for symbol '%s' from section '%s'"
+msgstr "Kunne ikke finde ækvivalent uddatasektion for symbolet \"%s\" fra sektionen \"%s\""
+
+#: elf.c:7611
+msgid "%B: unsupported relocation type %s"
+msgstr "%B: relokeringstypen %s understøttes ikke"
+
+#: elf32-arm.c:3183
+msgid ""
+"%B(%s): warning: interworking not enabled.\n"
+" first occurrence: %B: Thumb call to ARM"
+msgstr ""
+"%s(%s): advarsel: samvirken (interworking) er ikke aktiveret.\n"
+" første forekomst: %B: Thumb-kald til ARM"
+
+#: elf32-arm.c:3226
+msgid ""
+"%B(%s): warning: interworking not enabled.\n"
+" first occurrence: %B: ARM call to Thumb"
+msgstr ""
+"%B(%s): advarsel: samvirken (interworking) er ikke aktiveret.\n"
+" første forekomst: %B: ARM-kald til Thumb"
+
+#: elf32-arm.c:3432 elf32-arm.c:4807
+#, c-format
+msgid "%s: cannot create stub entry %s"
+msgstr "%s: kan ikke oprette stub-posten %s"
+
+#: elf32-arm.c:4923
+#, c-format
+msgid "unable to find THUMB glue '%s' for '%s'"
+msgstr "kan ikke finde finde THUMB-klistret \"%s\" til \"%s\""
+
+#: elf32-arm.c:4959
+#, c-format
+msgid "unable to find ARM glue '%s' for '%s'"
+msgstr "kan ikke finde ARM-klistret \"%s\" til \"%s\""
+
+#: elf32-arm.c:5485
+msgid "%B: BE8 images only valid in big-endian mode."
+msgstr "%B: BE8-aftryk er kun gyldige i big-endian-tilstanden."
+
+#. Give a warning, but do as the user requests anyway.
+#: elf32-arm.c:5715
+msgid "%B: warning: selected VFP11 erratum workaround is not necessary for target architecture"
+msgstr "%B: advarsel: valgte omgåelse af VFP11-erratum er ikke nødvendig for målarkitekturen"
+
+#: elf32-arm.c:6259 elf32-arm.c:6279
+msgid "%B: unable to find VFP11 veneer `%s'"
+msgstr "%B: kan ikke finde VFP11-veneer \"%s\""
+
+#: elf32-arm.c:6327
+#, c-format
+msgid "Invalid TARGET2 relocation type '%s'."
+msgstr "Ugyldig TARGET2-relokeringstype \"%s\"."
+
+#: elf32-arm.c:6411
+msgid ""
+"%B(%s): warning: interworking not enabled.\n"
+" first occurrence: %B: thumb call to arm"
+msgstr ""
+"%B(%s): advarsel: samvirken (interworking) er ikke aktiveret.\n"
+" første forekomst: %B: thumb-kald til arm"
+
+#: elf32-arm.c:7130
+msgid "\\%B: Warning: Arm BLX instruction targets Arm function '%s'."
+msgstr "\\%B: Advarsel: Arm BLX-instruktion bruger Arm-funktionen \"%s\" som mål."
+
+#: elf32-arm.c:7541
+msgid "%B: Warning: Thumb BLX instruction targets thumb function '%s'."
+msgstr "%B: Advarsel: Thumb BLX-instruktionen bruger thumb-funktionen \"%s\" som mål."
+
+#: elf32-arm.c:8223
+msgid "%B(%A+0x%lx): R_ARM_TLS_LE32 relocation not permitted in shared object"
+msgstr "%B(%A+0x%lx): Relokering af R_ARM_TLS_LE32 er ikke tilladt i delt objekt"
+
+#: elf32-arm.c:8438
+msgid "%B(%A+0x%lx): Only ADD or SUB instructions are allowed for ALU group relocations"
+msgstr "%B(%A+0x%lx): Kun instruktionerne ADD og SUB er tilladt for ALU-grupperelokeringer"
+
+#: elf32-arm.c:8478 elf32-arm.c:8565 elf32-arm.c:8648 elf32-arm.c:8733
+msgid "%B(%A+0x%lx): Overflow whilst splitting 0x%lx for group relocation %s"
+msgstr "%B(%A+0x%lx): Overløb ved opdeling af 0x%lx til grupperelokering %s"
+
+#: elf32-arm.c:8963 elf32-sh.c:4112 elf64-sh64.c:1544
+msgid "%B(%A+0x%lx): %s relocation against SEC_MERGE section"
+msgstr "%B(%A+0x%lx): %s-relokering mod SEC_MERGE-sektion"
+
+#: elf32-arm.c:9074 elf32-m68k.c:4191 elf32-xtensa.c:2805 elf64-ppc.c:11689
+msgid "%B(%A+0x%lx): %s used with TLS symbol %s"
+msgstr "%B(%A+0x%lx): %s bruges med TLS-symbol %s"
+
+#: elf32-arm.c:9075 elf32-m68k.c:4192 elf32-xtensa.c:2806 elf64-ppc.c:11690
+msgid "%B(%A+0x%lx): %s used with non-TLS symbol %s"
+msgstr "%B(%A+0x%lx): %s bruges med ikke-TLS-symbol %s"
+
+#: elf32-arm.c:9132 elf32-tic6x.c:1632
+msgid "out of range"
+msgstr "uden for gyldigt interval"
+
+#: elf32-arm.c:9136 elf32-tic6x.c:1636
+msgid "unsupported relocation"
+msgstr "relokeringen understøttes ikke"
+
+#: elf32-arm.c:9144 elf32-tic6x.c:1644
+msgid "unknown error"
+msgstr "ukendt fejl"
+
+#: elf32-arm.c:9569
+msgid "Warning: Clearing the interworking flag of %B because non-interworking code in %B has been linked with it"
+msgstr "Advarsel: Fjerner samvirkendeflaget (interworking) i %B eftersom ikke-samvirkende kode i %B er lænket med det"
+
+#: elf32-arm.c:9663
+msgid "%B: Unknown mandatory EABI object attribute %d"
+msgstr "%B: Ukendt obligatorisk EABI-objekt-attribut %d"
+
+#: elf32-arm.c:9671
+msgid "Warning: %B: Unknown EABI object attribute %d"
+msgstr "Advarsel: %B: Ukendt EABI-objekt-attribut %d"
+
+#: elf32-arm.c:9852
+msgid "error: %B: Unknown CPU architecture"
+msgstr "Fejl: %B: Ukendt CPU-arkitektur"
+
+#: elf32-arm.c:9890
+msgid "error: %B: Conflicting CPU architectures %d/%d"
+msgstr "fejl: %B: Modstridende CPU-arkitekturer %d/%d"
+
+#: elf32-arm.c:9942
+msgid "Error: %B has both the current and legacy Tag_MPextension_use attributes"
+msgstr "Fejl: %B har både nuværende og ældre Tag_MPextension_use-attributter"
+
+#: elf32-arm.c:9967
+msgid "error: %B uses VFP register arguments, %B does not"
+msgstr "fejl: %B bruger VFP-registerargumenter, mens %B ikke gør"
+
+#: elf32-arm.c:10112
+msgid "error: %B: unable to merge virtualization attributes with %B"
+msgstr "fejl: %B: kan ikke sammenføje virtualiseringsattributter med %B"
+
+#: elf32-arm.c:10138
+msgid "error: %B: Conflicting architecture profiles %c/%c"
+msgstr "fejl: %B: Modstridende arkitekturprofiler %c/%c"
+
+#: elf32-arm.c:10239
+msgid "Warning: %B: Conflicting platform configuration"
+msgstr "Advarsel: %B: Modstridende platformkonfiguration"
+
+#: elf32-arm.c:10248
+msgid "error: %B: Conflicting use of R9"
+msgstr "fejl: %B: Modstridende brug af R9"
+
+#: elf32-arm.c:10260
+msgid "error: %B: SB relative addressing conflicts with use of R9"
+msgstr "fejl: %B: SB-relativ adressering strider med brugen af R9"
+
+#: elf32-arm.c:10273
+msgid "warning: %B uses %u-byte wchar_t yet the output is to use %u-byte wchar_t; use of wchar_t values across objects may fail"
+msgstr "advarsel: %B bruger wchar_t på %u byte, men uddata skal bruge wchar_t på %u byte; brug af wchar_t-værdier på tværs af objekter kan gå galt"
+
+#: elf32-arm.c:10304
+msgid "warning: %B uses %s enums yet the output is to use %s enums; use of enum values across objects may fail"
+msgstr "advarsel: %B bruger %s-enum'er, men uddata skal bruge %s-enum'er; brug af enum-værdier på tværs af objekter kan gå galt"
+
+#: elf32-arm.c:10316
+msgid "error: %B uses iWMMXt register arguments, %B does not"
+msgstr "fejl: %B bruger iWMMXt-registerargumenter, mens %B ikke gør"
+
+#: elf32-arm.c:10333
+msgid "error: fp16 format mismatch between %B and %B"
+msgstr "fejl: uoverensstemmelse i fp16-format mellem %B og %B"
+
+#: elf32-arm.c:10357
+msgid "DIV usage mismatch between %B and %B"
+msgstr "Uoverensstemmelse i DIV-forbrug mellem %B og %B"
+
+#: elf32-arm.c:10376
+msgid "%B has has both the current and legacy Tag_MPextension_use attributes"
+msgstr "%B har både nuværende og ældre Tag_MPextension_use-attributter"
+
+#. Ignore init flag - it may not be set, despite the flags field
+#. containing valid data.
+#. Ignore init flag - it may not be set, despite the flags field containing valid data.
+#: elf32-arm.c:10468 elf32-bfin.c:5065 elf32-cris.c:4162 elf32-m68hc1x.c:1282
+#: elf32-m68k.c:1235 elf32-score.c:3996 elf32-score7.c:3803 elf32-vax.c:528
+#: elfxx-mips.c:12842
+#, c-format
+msgid "private flags = %lx:"
+msgstr "private flag = %lx:"
+
+#: elf32-arm.c:10477
+#, c-format
+msgid " [interworking enabled]"
+msgstr " [samvirkende er aktiveret]"
+
+#: elf32-arm.c:10485
+#, c-format
+msgid " [VFP float format]"
+msgstr " [VFP-flydendetalsformat]"
+
+#: elf32-arm.c:10487
+#, c-format
+msgid " [Maverick float format]"
+msgstr " [Maverick-flydendetalformat]"
+
+#: elf32-arm.c:10489
+#, c-format
+msgid " [FPA float format]"
+msgstr " [FPA-flydendetalformat]"
+
+#: elf32-arm.c:10498
+#, c-format
+msgid " [new ABI]"
+msgstr " [nyt ABI]"
+
+#: elf32-arm.c:10501
+#, c-format
+msgid " [old ABI]"
+msgstr " [gammelt ABI]"
+
+#: elf32-arm.c:10504
+#, c-format
+msgid " [software FP]"
+msgstr " [programmeret FP]"
+
+#: elf32-arm.c:10513
+#, c-format
+msgid " [Version1 EABI]"
+msgstr " [Version1 EABI]"
+
+#: elf32-arm.c:10516 elf32-arm.c:10527
+#, c-format
+msgid " [sorted symbol table]"
+msgstr " [sorteret symboltabel]"
+
+#: elf32-arm.c:10518 elf32-arm.c:10529
+#, c-format
+msgid " [unsorted symbol table]"
+msgstr " [usorteret symboltabel]"
+
+#: elf32-arm.c:10524
+#, c-format
+msgid " [Version2 EABI]"
+msgstr " [Version2 EABI]"
+
+#: elf32-arm.c:10532
+#, c-format
+msgid " [dynamic symbols use segment index]"
+msgstr " [dynamiske symboler bruger segmentindeks]"
+
+#: elf32-arm.c:10535
+#, c-format
+msgid " [mapping symbols precede others]"
+msgstr " [mapningssymboler foretrækkes frem for andre]"
+
+#: elf32-arm.c:10542
+#, c-format
+msgid " [Version3 EABI]"
+msgstr " [Version3 EABI]"
+
+#: elf32-arm.c:10546
+#, c-format
+msgid " [Version4 EABI]"
+msgstr " [Version4 EABI]"
+
+#: elf32-arm.c:10550
+#, c-format
+msgid " [Version5 EABI]"
+msgstr " [Version5 EABI]"
+
+#: elf32-arm.c:10553
+#, c-format
+msgid " [BE8]"
+msgstr " [BE8]"
+
+#: elf32-arm.c:10556
+#, c-format
+msgid " [LE8]"
+msgstr " [LE8]"
+
+#: elf32-arm.c:10562
+#, c-format
+msgid " <EABI version unrecognised>"
+msgstr " <EABI-version genkendes ikke>"
+
+#: elf32-arm.c:10569
+#, c-format
+msgid " [relocatable executable]"
+msgstr " [relokérbar kørbar fil]"
+
+#: elf32-arm.c:10572
+#, c-format
+msgid " [has entry point]"
+msgstr " [har startpunkt]"
+
+#: elf32-arm.c:10577
+#, c-format
+msgid "<Unrecognised flag bits set>"
+msgstr "<Ukendte flagbit er sat>"
+
+#: elf32-arm.c:10824 elf32-i386.c:1322 elf32-s390.c:1000 elf32-xtensa.c:1009
+#: elf64-s390.c:960 elf64-x86-64.c:1105 elfxx-sparc.c:1370
+msgid "%B: bad symbol index: %d"
+msgstr "%B: fejlagtigt symbolindeks: %d"
+
+#: elf32-arm.c:10946 elf64-x86-64.c:1265 elf64-x86-64.c:1434 elfxx-mips.c:7942
+msgid "%B: relocation %s against `%s' can not be used when making a shared object; recompile with -fPIC"
+msgstr "%B: relokeringen %s mod \"%s\" kan ikke bruges når et delt objekt oprettes; genkompilér med -fPIC"
+
+#: elf32-arm.c:11948
+#, c-format
+msgid "Errors encountered processing file %s"
+msgstr "Stødte på fejl ved behandling af filen %s"
+
+#: elf32-arm.c:13334
+msgid "%B: error: Cortex-A8 erratum stub is allocated in unsafe location"
+msgstr "%B: fejl: Cortex-A8-erratum-stub er allokeret på et usikkert sted"
+
+#. There's not much we can do apart from complain if this
+#. happens.
+#: elf32-arm.c:13361
+msgid "%B: error: Cortex-A8 erratum stub out of range (input file too large)"
+msgstr "%B: fejl: Cortex-A8-erratum-stub er uden for gyldigt interval (inddatafil for stor)"
+
+#: elf32-arm.c:13455 elf32-arm.c:13477
+msgid "%B: error: VFP11 veneer out of range"
+msgstr "%B: fejl: VFP11-veneer uden for gyldigt interval"
+
+#: elf32-arm.c:14002
+msgid "error: %B is already in final BE8 format"
+msgstr "fejl: %B er allerede i endeligt BE8-format"
+
+#: elf32-arm.c:14078
+msgid "error: Source object %B has EABI version %d, but target %B has EABI version %d"
+msgstr "fejl: Kildeobjektet %B har EABI-version %d, men målet %B har EABI-version %d"
+
+#: elf32-arm.c:14094
+msgid "error: %B is compiled for APCS-%d, whereas target %B uses APCS-%d"
+msgstr "fejl: %B er kompileret til APCS-%d, mens målet %B bruger APCS-%d"
+
+#: elf32-arm.c:14119
+msgid "error: %B uses VFP instructions, whereas %B does not"
+msgstr "fejl: %B bruger VFP-instruktioner, mens %B ikke gør"
+
+#: elf32-arm.c:14123
+msgid "error: %B uses FPA instructions, whereas %B does not"
+msgstr "fejl: %B bruger FPA-instruktioner, mens %B ikke gør"
+
+#: elf32-arm.c:14133
+msgid "error: %B uses Maverick instructions, whereas %B does not"
+msgstr "fejl: %B bruger Maverick-instruktioner, mens %B ikke gør"
+
+#: elf32-arm.c:14137
+msgid "error: %B does not use Maverick instructions, whereas %B does"
+msgstr "fejl: %B bruger ikke Maverick-instruktioner, men %B gør"
+
+#: elf32-arm.c:14156
+msgid "error: %B uses software FP, whereas %B uses hardware FP"
+msgstr "fejl: %B bruger flydende tal i software, mens %B bruger hardware"
+
+#: elf32-arm.c:14160
+msgid "error: %B uses hardware FP, whereas %B uses software FP"
+msgstr "fejl: %B bruger flydende tal i hardware, mens %B bruger software"
+
+#: elf32-avr.c:1271 elf32-bfin.c:3201 elf32-cris.c:2085 elf32-fr30.c:617
+#: elf32-frv.c:4119 elf32-i860.c:1219 elf32-ip2k.c:1479 elf32-iq2000.c:692
+#: elf32-m32c.c:561 elf32-mep.c:542 elf32-moxie.c:290 elf32-msp430.c:494
+#: elf32-mt.c:399 elf32-openrisc.c:412 elf32-v850.c:2151 elf32-xstormy16.c:949
+#: elf64-mmix.c:1530
+msgid "internal error: dangerous relocation"
+msgstr "intern fejl: farlig relokering"
+
+#: elf32-avr.c:2400 elf32-hppa.c:598 elf32-m68hc1x.c:166 elf64-ppc.c:4175
+msgid "%B: cannot create stub entry %s"
+msgstr "%B: kan ikke oprette stub-post %s"
+
+#: elf32-bfin.c:1575
+msgid "%B(%A+0x%lx): unresolvable relocation against symbol `%s'"
+msgstr "%B(%A+0x%lx): uløselig relokering mod symbol \"%s\""
+
+#: elf32-bfin.c:1608 elf32-i386.c:4123 elf32-m68k.c:4233 elf32-s390.c:3062
+#: elf64-s390.c:3037 elf64-x86-64.c:3759
+msgid "%B(%A+0x%lx): reloc against `%s': error %d"
+msgstr "%B(%A+0x%lx): relokering mod \"%s\": fejl %d"
+
+#: elf32-bfin.c:2707
+msgid "%B: relocation at `%A+0x%x' references symbol `%s' with nonzero addend"
+msgstr "%B: relokering ved \"%A+0x%x\" refererer til symbolet \"%s\" med addend forskellig fra nul"
+
+#: elf32-bfin.c:2721 elf32-frv.c:2901
+msgid "relocation references symbol not defined in the module"
+msgstr "relokering refererer symbol som ikke er defineret i modulet"
+
+#: elf32-bfin.c:2818
+msgid "R_BFIN_FUNCDESC references dynamic symbol with nonzero addend"
+msgstr "R_BFIN_FUNCDESC refererer til dynamisk symbol med addend forskellig fra nul"
+
+#: elf32-bfin.c:2859 elf32-bfin.c:2982 elf32-frv.c:3638 elf32-frv.c:3759
+msgid "cannot emit fixups in read-only section"
+msgstr "kan ikke udsende fixup'er i skrivebeskyttet sektion %s"
+
+#: elf32-bfin.c:2890 elf32-bfin.c:3020 elf32-frv.c:3669 elf32-frv.c:3803
+#: elf32-lm32.c:1103 elf32-sh.c:5021
+msgid "cannot emit dynamic relocations in read-only section"
+msgstr "kan ikke udsende dynamiske relokeringer i skrivebeskyttet sektion"
+
+#: elf32-bfin.c:2940
+msgid "R_BFIN_FUNCDESC_VALUE references dynamic symbol with nonzero addend"
+msgstr "R_BFIN_FUNCDESC_VALUE refererer dynamisk symbol med addend forskellig fra nul"
+
+#: elf32-bfin.c:3105
+msgid "relocations between different segments are not supported"
+msgstr "relokeringer mellem forskellige segmenter understøttes ikke"
+
+#: elf32-bfin.c:3106
+msgid "warning: relocation references a different segment"
+msgstr "advarsel: relokering refererer til et andet segment"
+
+#: elf32-bfin.c:4957 elf32-frv.c:6406
+msgid "%B: unsupported relocation type %i"
+msgstr "%B: relokeringstypen %i understøttes ikke"
+
+#: elf32-bfin.c:5111 elf32-frv.c:6814
+#, c-format
+msgid "%s: cannot link non-fdpic object file into fdpic executable"
+msgstr "%s: kan ikke lænke ikke-fdpic-objektfil ind i fdpic-eksekveringsfil"
+
+#: elf32-bfin.c:5115 elf32-frv.c:6818
+#, c-format
+msgid "%s: cannot link fdpic object file into non-fdpic executable"
+msgstr "%s: kan ikke lænke fdpic-objektfil ind i en ikke-fdpic-eksekveringsfil"
+
+#: elf32-cris.c:1172
+msgid "%B, section %A: unresolvable relocation %s against symbol `%s'"
+msgstr "%B, sektion %A: uløselig relokering %s mod symbol \"%s\""
+
+#: elf32-cris.c:1234
+msgid "%B, section %A: No PLT nor GOT for relocation %s against symbol `%s'"
+msgstr "%B, sektion %A: Hverken nogen PLT eller GOT til relokering %s mod symbol \"%s\""
+
+#: elf32-cris.c:1236
+msgid "%B, section %A: No PLT for relocation %s against symbol `%s'"
+msgstr "%B, sektion %A: Ingen PLT til relokering %s mod symbol \"%s\""
+
+#: elf32-cris.c:1242 elf32-cris.c:1375 elf32-cris.c:1635 elf32-cris.c:1718
+#: elf32-cris.c:1871
+msgid "[whose name is lost]"
+msgstr "[hvis navn er tabt]"
+
+#: elf32-cris.c:1361
+msgid "%B, section %A: relocation %s with non-zero addend %d against local symbol"
+msgstr "%B, sektion %A: relokering %s med ikke-tom addend %d mod lokalt symbol"
+
+#: elf32-cris.c:1369 elf32-cris.c:1712 elf32-cris.c:1865
+msgid "%B, section %A: relocation %s with non-zero addend %d against symbol `%s'"
+msgstr "%B, sektion %A: relokering %s med ikke-tom addend %d mod symbol \"%s\""
+
+#: elf32-cris.c:1395
+msgid "%B, section %A: relocation %s is not allowed for global symbol: `%s'"
+msgstr "%B, sektion %A: relokeringen %s er ikke tilladt for globalt symbol: \"%s\""
+
+#: elf32-cris.c:1411
+msgid "%B, section %A: relocation %s with no GOT created"
+msgstr "%B, sektion %A: relokering %s oprettet uden nogen GOT"
+
+#. We shouldn't get here for GCC-emitted code.
+#: elf32-cris.c:1626
+msgid "%B, section %A: relocation %s has an undefined reference to `%s', perhaps a declaration mixup?"
+msgstr "%B, sektion %A: relokeringen %s har en udefineret reference til \"%s\". Måske er der noget galt med erklæringen?"
+
+#: elf32-cris.c:1998
+msgid "%B, section %A: relocation %s is not allowed for symbol: `%s' which is defined outside the program, perhaps a declaration mixup?"
+msgstr "%B: relokeringen %A er ikke tilladt for symbol: \"%s\", som er defineret uden for programmet. Måske er der noget galt med erklæringen?"
+
+#: elf32-cris.c:2051
+msgid "(too many global variables for -fpic: recompile with -fPIC)"
+msgstr "(for mange globale variable til -fpic: genkompilér med -fPIC)"
+
+#: elf32-cris.c:2058
+msgid "(thread-local data too big for -fpic or -msmall-tls: recompile with -fPIC or -mno-small-tls)"
+msgstr "(trådlokale data er for store til -fpic eller -msmall-tls: genkompilér med -fPIC eller -mno-small-tls)"
+
+#: elf32-cris.c:3248
+msgid ""
+"%B, section %A:\n"
+" v10/v32 compatible object %s must not contain a PIC relocation"
+msgstr ""
+"%B, sektion %A:\n"
+" v10/v32-kompatibelt objekt %s må ikke indeholde en PIC-relokering"
+
+#: elf32-cris.c:3353
+msgid ""
+"%B, section %A:\n"
+" relocation %s not valid in a shared object; typically an option mixup, recompile with -fPIC"
+msgstr ""
+"%B, sektion %A:\n"
+" relokeringen %s er ikke gyldig i et delt objekt; dette er typisk en fejl i tilvalgende - genkompilér med -fPIC"
+
+#: elf32-cris.c:3567
+msgid ""
+"%B, section %A:\n"
+" relocation %s should not be used in a shared object; recompile with -fPIC"
+msgstr ""
+"%B, sektion %A:\n"
+" relokeringen %s bør ikke bruges i et delt objekt; genoversæt med -fPIC"
+
+#: elf32-cris.c:3992
+msgid ""
+"%B, section `%A', to symbol `%s':\n"
+" relocation %s should not be used in a shared object; recompile with -fPIC"
+msgstr ""
+"%B, sektion %A til symbol \"%s\":\n"
+" relokeringen %s bør ikke bruges i et delt objekt; genkompilér med -fPIC"
+
+#: elf32-cris.c:4111
+msgid "Unexpected machine number"
+msgstr "Uventet maskinnummer"
+
+#: elf32-cris.c:4165
+#, c-format
+msgid " [symbols have a _ prefix]"
+msgstr " [symboler har et _-præfiks]"
+
+#: elf32-cris.c:4168
+#, c-format
+msgid " [v10 and v32]"
+msgstr " [v10 og v32]"
+
+#: elf32-cris.c:4171
+#, c-format
+msgid " [v32]"
+msgstr " [v32]"
+
+#: elf32-cris.c:4216
+msgid "%B: uses _-prefixed symbols, but writing file with non-prefixed symbols"
+msgstr "%B: bruger symboler med _-præfiks, men skriver fil med symboler uden præfiks"
+
+#: elf32-cris.c:4217
+msgid "%B: uses non-prefixed symbols, but writing file with _-prefixed symbols"
+msgstr "%B: bruger symboler uden præfiks, men skriver fil med symboler med _-præfiks"
+
+#: elf32-cris.c:4236
+msgid "%B contains CRIS v32 code, incompatible with previous objects"
+msgstr "%B indeholder CRIS v32-kode, som er inkompatibel med tidligere objekter"
+
+#: elf32-cris.c:4238
+msgid "%B contains non-CRIS-v32 code, incompatible with previous objects"
+msgstr "%B indeholder ikke-CRIS-v32-kode, som er inkompatibel med tidligere objekter"
+
+#: elf32-frv.c:1509 elf32-frv.c:1658
+msgid "relocation requires zero addend"
+msgstr "relokering kræver addend på nul"
+
+#: elf32-frv.c:2888
+msgid "%B(%A+0x%x): relocation to `%s+%x' may have caused the error above"
+msgstr "%B(%A+0x%x): relokering til \"%s+%x\" kan have forårsaget ovenstående fejl"
+
+#: elf32-frv.c:2977
+msgid "R_FRV_GETTLSOFF not applied to a call instruction"
+msgstr "R_FRV_GETTLSOFF ikke anvendt til call-instruktion"
+
+#: elf32-frv.c:3019
+msgid "R_FRV_GOTTLSDESC12 not applied to an lddi instruction"
+msgstr "R_FRV_GOTTLSDESC12 ikke anvendt til en lddi-instruktion"
+
+#: elf32-frv.c:3090
+msgid "R_FRV_GOTTLSDESCHI not applied to a sethi instruction"
+msgstr "R_FRV_GOTTLSDESCHI ikke anvendt til en sethi-instruktion"
+
+#: elf32-frv.c:3127
+msgid "R_FRV_GOTTLSDESCLO not applied to a setlo or setlos instruction"
+msgstr "R_FRV_GOTTLSDESCLO ikke anvendt til en setlo- eller setlos-instruktion"
+
+#: elf32-frv.c:3175
+msgid "R_FRV_TLSDESC_RELAX not applied to an ldd instruction"
+msgstr "R_FRV_TLSDESC_RELAX ikke anvendt til en ldd-instruktion"
+
+# virkelig?
+#: elf32-frv.c:3259
+msgid "R_FRV_GETTLSOFF_RELAX not applied to a calll instruction"
+msgstr "R_FRV_GETTLSOFF_RELAX ikke anvendt til en calll-instruktion"
+
+#: elf32-frv.c:3314
+msgid "R_FRV_GOTTLSOFF12 not applied to an ldi instruction"
+msgstr "R_FRV_GOTTLSOFF12 ikke anvendt til en ldi-instruktion"
+
+#: elf32-frv.c:3344
+msgid "R_FRV_GOTTLSOFFHI not applied to a sethi instruction"
+msgstr "R_FRV_GOTTLSOFFHI ikke anvendt til en sethi-instruktion"
+
+#: elf32-frv.c:3373
+msgid "R_FRV_GOTTLSOFFLO not applied to a setlo or setlos instruction"
+msgstr "R_FRV_GOTTLSOFFLO ikke anvendt til en setlos-instruktion"
+
+#: elf32-frv.c:3404
+msgid "R_FRV_TLSOFF_RELAX not applied to an ld instruction"
+msgstr "R_FRV_TLSOFF_RELAX ikke anvendt til en ld-instruktion"
+
+#: elf32-frv.c:3449
+msgid "R_FRV_TLSMOFFHI not applied to a sethi instruction"
+msgstr "R_FRV_TLSMOFFHI ikke anvendt til en sethi-instruktion"
+
+#: elf32-frv.c:3476
+msgid "R_FRV_TLSMOFFLO not applied to a setlo or setlos instruction"
+msgstr "R_FRV_TLSMOFFLO ikke anvendt til en setlos-instruktion"
+
+#: elf32-frv.c:3597
+msgid "R_FRV_FUNCDESC references dynamic symbol with nonzero addend"
+msgstr "R_FRV_FUNCDESC refererer dynamisk symbol med addend forskellig fra nul"
+
+#: elf32-frv.c:3717
+msgid "R_FRV_FUNCDESC_VALUE references dynamic symbol with nonzero addend"
+msgstr "R_FRV_FUNCDESC_VALUE refererer dynamisk symbol med addend forskellig fra nul"
+
+#: elf32-frv.c:3974 elf32-frv.c:4130
+msgid "%B(%A+0x%lx): reloc against `%s': %s"
+msgstr "%B(%A+0x%lx): relokering mod \"%s\": %s"
+
+#: elf32-frv.c:3976 elf32-frv.c:3980
+msgid "relocation references a different segment"
+msgstr "relokering refererer et andet segment"
+
+#: elf32-frv.c:6728
+#, c-format
+msgid "%s: compiled with %s and linked with modules that use non-pic relocations"
+msgstr "%s: oversat med %s og lænket med moduler som bruger ikke-pic-relokering"
+
+#: elf32-frv.c:6781 elf32-iq2000.c:845 elf32-m32c.c:807
+#, c-format
+msgid "%s: compiled with %s and linked with modules compiled with %s"
+msgstr "%s: oversat med %s og lænket med moduler som oversattes med %s"
+
+#: elf32-frv.c:6793
+#, c-format
+msgid "%s: uses different unknown e_flags (0x%lx) fields than previous modules (0x%lx)"
+msgstr "%s: bruger andre ukendte e_flags-felter (0x%lx) end tidligere moduler (0x%lx)"
+
+#: elf32-frv.c:6843 elf32-iq2000.c:882 elf32-m32c.c:843 elf32-mt.c:576
+#: elf32-rx.c:2925
+#, c-format
+msgid "private flags = 0x%lx:"
+msgstr "private flag = 0x%lx:"
+
+#: elf32-gen.c:69 elf64-gen.c:69
+msgid "%B: Relocations in generic ELF (EM: %d)"
+msgstr "%B: Relokeringer i generisk ELF (EM: %d)"
+
+#: elf32-hppa.c:850 elf32-hppa.c:3610
+msgid "%B(%A+0x%lx): cannot reach %s, recompile with -ffunction-sections"
+msgstr "%B(%A+0x%lx): kan ikke nå %s, genkompilér med -ffunction-sections"
+
+#: elf32-hppa.c:1284
+msgid "%B: relocation %s can not be used when making a shared object; recompile with -fPIC"
+msgstr "%B: relokeringen %s kan ikke bruges når et delt objekt oprettes; genkompilér med -fPIC"
+
+#: elf32-hppa.c:2803
+msgid "%B: duplicate export stub %s"
+msgstr "%B: dobbelt eksportstub %s"
+
+#: elf32-hppa.c:3449
+msgid "%B(%A+0x%lx): %s fixup for insn 0x%x is not supported in a non-shared link"
+msgstr "%B(%A+0x%lx): %s-\"fixup\" for instruktion 0x%x understøttes ikke i et ikke-delt lænke"
+
+#: elf32-hppa.c:4296
+msgid "%B(%A+0x%lx): cannot handle %s for %s"
+msgstr "%B(%A+0x%lx): kan ikke håndtere %s til %s"
+
+#: elf32-hppa.c:4608
+msgid ".got section not immediately after .plt section"
+msgstr ".got-sektionen følger ikke umiddelbart efter .plt-sektion"
+
+#. Unknown relocation.
+#: elf32-i386.c:371 elf32-m68k.c:383 elf32-ppc.c:1674 elf32-s390.c:379
+#: elf32-tic6x.c:1563 elf64-ppc.c:2284 elf64-s390.c:403 elf64-x86-64.c:234
+msgid "%B: invalid relocation type %d"
+msgstr "%B: ugyldig relokeringstype %d"
+
+#: elf32-i386.c:1265 elf64-x86-64.c:1049
+msgid "%B: TLS transition from %s to %s against `%s' at 0x%lx in section `%A' failed"
+msgstr "%B: TLS-overgang fra %s til %s mod \"%s\" ved 0x%lx i afsnittet \"%A\" mislykkedes"
+
+#: elf32-i386.c:1408 elf32-i386.c:3068 elf64-x86-64.c:1194 elf64-x86-64.c:2780
+#: elfxx-sparc.c:3076
+msgid "%B: relocation %s against STT_GNU_IFUNC symbol `%s' isn't handled by %s"
+msgstr "%B: relokeringen %s mod STT_GNU_IFUNC-symbolet \"%s\" håndteres ikke af %s"
+
+#: elf32-i386.c:1570 elf32-s390.c:1182 elf32-sh.c:6367 elf32-xtensa.c:1182
+#: elf64-s390.c:1151 elfxx-sparc.c:1547
+msgid "%B: `%s' accessed both as normal and thread local symbol"
+msgstr "%B: \"%s\" tilgås både som normalt symbol og trådlokalt symbol"
+
+#: elf32-i386.c:2910
+msgid "%B: unrecognized relocation (0x%x) in section `%A'"
+msgstr "%B: ukendt relokering (0x%x) i sektionen \"%A\""
+
+#: elf32-i386.c:3317 elf64-x86-64.c:3174
+msgid "hidden symbol"
+msgstr "skjult symbol"
+
+#: elf32-i386.c:3320 elf64-x86-64.c:3177
+msgid "internal symbol"
+msgstr "internt symbol"
+
+#: elf32-i386.c:3323 elf64-x86-64.c:3180
+msgid "protected symbol"
+msgstr "beskyttet symbol"
+
+#: elf32-i386.c:3326 elf64-x86-64.c:3183
+msgid "symbol"
+msgstr "symbol"
+
+#: elf32-i386.c:3331
+msgid "%B: relocation R_386_GOTOFF against undefined %s `%s' can not be used when making a shared object"
+msgstr "%B: relokeringen R_386_GOTOFF mod udefineret %s \"%s\" kan ikke bruges når et delt objekt oprettes"
+
+#: elf32-i386.c:3341
+msgid "%B: relocation R_386_GOTOFF against protected function `%s' can not be used when making a shared object"
+msgstr "%B: relokeringen R_386_GOTOFF mod beskyttet funktion \"%s\" kan ikke bruges når et delt objekt oprettes"
+
+#: elf32-i386.c:4633 elf64-x86-64.c:4206
+#, c-format
+msgid "discarded output section: `%A'"
+msgstr "forkastet uddatasektion: \"%A\""
+
+#: elf32-ip2k.c:857 elf32-ip2k.c:863 elf32-ip2k.c:930 elf32-ip2k.c:936
+msgid "ip2k relaxer: switch table without complete matching relocation information."
+msgstr "ip2k relaxer: switch-tabel uden fuldstændig passende relokeringsinformation."
+
+#: elf32-ip2k.c:880 elf32-ip2k.c:963
+msgid "ip2k relaxer: switch table header corrupt."
+msgstr "ip2k relaxer: switch-tabelhoved beskadiget."
+
+#: elf32-ip2k.c:1292
+#, c-format
+msgid "ip2k linker: missing page instruction at 0x%08lx (dest = 0x%08lx)."
+msgstr "ip2k linker: manglende sideinstruktion ved 0x%08lx (dest = 0x%08lx)."
+
+#: elf32-ip2k.c:1308
+#, c-format
+msgid "ip2k linker: redundant page instruction at 0x%08lx (dest = 0x%08lx)."
+msgstr "ip2k linker: gentaget sideinstruktion ved 0x%08lx (dest = 0x%08lx)."
+
+#. Only if it's not an unresolved symbol.
+#: elf32-ip2k.c:1475
+msgid "unsupported relocation between data/insn address spaces"
+msgstr "ikke-understøttet relokering mellem data/insn-adresserum"
+
+#: elf32-iq2000.c:858 elf32-m32c.c:819
+#, c-format
+msgid "%s: uses different e_flags (0x%lx) fields than previous modules (0x%lx)"
+msgstr "%s: bruger andre e_flags-felter (0x%lx) end tidligere moduler (0x%lx)"
+
+#: elf32-lm32.c:706
+msgid "global pointer relative relocation when _gp not defined"
+msgstr "global pointer-relativ relokering, når _gp ikke er defineret"
+
+#: elf32-lm32.c:761
+msgid "global pointer relative address out of range"
+msgstr "global pointer-relativ adresse er uden for det gyldige interval"
+
+#: elf32-lm32.c:1057
+msgid "internal error: addend should be zero for R_LM32_16_GOT"
+msgstr "intern fejl: addend burde være nul for R_LM32_16_GOT"
+
+#: elf32-m32r.c:1453
+msgid "SDA relocation when _SDA_BASE_ not defined"
+msgstr "SDA-relokering når _SDA_BASE_ ikke er defineret"
+
+#: elf32-m32r.c:3048
+msgid "%B: The target (%s) of an %s relocation is in the wrong section (%A)"
+msgstr "%B: MÃ¥let (%s) for en %s-relokering er i forkert sektion (%A)"
+
+#: elf32-m32r.c:3576
+msgid "%B: Instruction set mismatch with previous modules"
+msgstr "%B: Instruktionssæt passer ikke med tidligere moduler"
+
+#: elf32-m32r.c:3597
+#, c-format
+msgid "private flags = %lx"
+msgstr "private flag = %lx"
+
+#: elf32-m32r.c:3602
+#, c-format
+msgid ": m32r instructions"
+msgstr ": m32r-instruktioner"
+
+#: elf32-m32r.c:3603
+#, c-format
+msgid ": m32rx instructions"
+msgstr ": m32rx-instruktioner"
+
+#: elf32-m32r.c:3604
+#, c-format
+msgid ": m32r2 instructions"
+msgstr ": m32r2-instruktioner"
+
+#: elf32-m68hc1x.c:1050
+#, c-format
+msgid "Reference to the far symbol `%s' using a wrong relocation may result in incorrect execution"
+msgstr "Reference til fjernsymbol \"%s\", der bruger en forkert relokering, kan resultere i forkert udførelse"
+
+#: elf32-m68hc1x.c:1073
+#, c-format
+msgid "banked address [%lx:%04lx] (%lx) is not in the same bank as current banked address [%lx:%04lx] (%lx)"
+msgstr "bankadresse [%lx:%04lx] (%lx) er ikke i samme bank som nuværende bankadresse [%lx:%04lx] (%lx)"
+
+#: elf32-m68hc1x.c:1092
+#, c-format
+msgid "reference to a banked address [%lx:%04lx] in the normal address space at %04lx"
+msgstr "reference til bankadresse [%lx:%04lx] i det normale adresserum ved %04lx"
+
+#: elf32-m68hc1x.c:1225
+msgid "%B: linking files compiled for 16-bit integers (-mshort) and others for 32-bit integers"
+msgstr "%B: lænker filer, der er kompileret til 16 bit-heltal (-mshort), og andre til 32 bit-heltal"
+
+#: elf32-m68hc1x.c:1232
+msgid "%B: linking files compiled for 32-bit double (-fshort-double) and others for 64-bit double"
+msgstr "%B: lænker filer, der er kompileret til 32 bit-double (-fshort-double), og andre til 64 bit-double"
+
+#: elf32-m68hc1x.c:1241
+msgid "%B: linking files compiled for HCS12 with others compiled for HC12"
+msgstr "%B: lænkning af filer kompileret til HCS12 med andre, der er kompileret til HC12"
+
+#: elf32-m68hc1x.c:1257 elf32-ppc.c:4232 elf64-sparc.c:703 elfxx-mips.c:12704
+msgid "%B: uses different e_flags (0x%lx) fields than previous modules (0x%lx)"
+msgstr "%B: bruger andre e_flags-felter (0x%lx) end tidligere moduler (0x%lx)"
+
+#: elf32-m68hc1x.c:1285
+#, c-format
+msgid "[abi=32-bit int, "
+msgstr "[abi=32-bit int, "
+
+#: elf32-m68hc1x.c:1287
+#, c-format
+msgid "[abi=16-bit int, "
+msgstr "[abi=16-bit int, "
+
+#: elf32-m68hc1x.c:1290
+#, c-format
+msgid "64-bit double, "
+msgstr "64-bit double, "
+
+#: elf32-m68hc1x.c:1292
+#, c-format
+msgid "32-bit double, "
+msgstr "32-bit double, "
+
+#: elf32-m68hc1x.c:1295
+#, c-format
+msgid "cpu=HC11]"
+msgstr "cpu=HC11]"
+
+#: elf32-m68hc1x.c:1297
+#, c-format
+msgid "cpu=HCS12]"
+msgstr "cpu=HCS12]"
+
+#: elf32-m68hc1x.c:1299
+#, c-format
+msgid "cpu=HC12]"
+msgstr "cpu=HC12]"
+
+# ?
+#: elf32-m68hc1x.c:1302
+#, c-format
+msgid " [memory=bank-model]"
+msgstr " [memory=bank-model]"
+
+# ?
+#: elf32-m68hc1x.c:1304
+#, c-format
+msgid " [memory=flat]"
+msgstr " [memory=flat]"
+
+#: elf32-m68k.c:1250 elf32-m68k.c:1251 vms-alpha.c:7292 vms-alpha.c:7307
+msgid "unknown"
+msgstr "ukendt"
+
+#: elf32-m68k.c:1714
+msgid "%B: GOT overflow: Number of relocations with 8-bit offset > %d"
+msgstr "%B: GOT-overløb: Antallet af relokeringer med 8 bit-afsæt > %d"
+
+#: elf32-m68k.c:1720
+msgid "%B: GOT overflow: Number of relocations with 8- or 16-bit offset > %d"
+msgstr "%B: GOT-overløb: Antallet af relokeringer med 8 eller 16 bit-afsæt > %d"
+
+#: elf32-m68k.c:3959
+msgid "%B(%A+0x%lx): R_68K_TLS_LE32 relocation not permitted in shared object"
+msgstr "%B(%A+0x%lx): R_68K_TLS_LE32-relokering tillades ikke i delt objekt"
+
+#: elf32-mcore.c:99 elf32-mcore.c:442
+msgid "%B: Relocation %s (%d) is not currently supported.\n"
+msgstr "%B: Relokering %s (%d) understøttes ikke i øjeblikket.\n"
+
+#: elf32-mcore.c:428
+msgid "%B: Unknown relocation type %d\n"
+msgstr "%B: Ukendt relokeringstype %d\n"
+
+# ?
+#: elf32-mep.c:647
+msgid "%B and %B are for different cores"
+msgstr "%B og %B er til forskellige cpu-kerner"
+
+#: elf32-mep.c:664
+msgid "%B and %B are for different configurations"
+msgstr "%B og %B er til forskellige konfigurationer"
+
+#: elf32-mep.c:701
+#, c-format
+msgid "private flags = 0x%lx"
+msgstr "private flag = 0x%lx"
+
+#: elf32-microblaze.c:742
+#, c-format
+msgid "%s: unknown relocation type %d"
+msgstr "%s: ukendt relokeringstype %d"
+
+#: elf32-microblaze.c:867 elf32-microblaze.c:912
+#, c-format
+msgid "%s: The target (%s) of an %s relocation is in the wrong section (%s)"
+msgstr "%s: MÃ¥let (%s) for en %s-relokering er i forkert sektion (%s)"
+
+#: elf32-microblaze.c:1155 elfxx-sparc.c:3450
+msgid "%B: probably compiled without -fPIC?"
+msgstr "%B: nok oversat uden -fPIC?"
+
+#: elf32-microblaze.c:2074 elflink.c:12601
+msgid "%B: bad relocation section name `%s'"
+msgstr "%B: fejlagtigt relokeringssektionsnavn \"%s\""
+
+#: elf32-mips.c:1045 elf64-mips.c:2084 elfn32-mips.c:1888
+msgid "literal relocation occurs for an external symbol"
+msgstr "der sker ordret relokering for et eksternt symbol"
+
+#: elf32-mips.c:1085 elf32-score.c:569 elf32-score7.c:469 elf64-mips.c:2127
+#: elfn32-mips.c:1929
+msgid "32bits gp relative relocation occurs for an external symbol"
+msgstr "32-bit gp-relativ relokering forekommer for et eksternt symbol"
+
+#: elf32-ppc.c:1739
+#, c-format
+msgid "generic linker can't handle %s"
+msgstr "generisk lænker kan ikke håndtere %s"
+
+#: elf32-ppc.c:2180
+msgid "corrupt %s section in %B"
+msgstr "beskadiget %s-sektion i %B"
+
+#: elf32-ppc.c:2199
+msgid "unable to read in %s section from %B"
+msgstr "kan ikke læse i %s-sektion fra %B"
+
+#: elf32-ppc.c:2240
+msgid "warning: unable to set size of %s section in %B"
+msgstr "advarsel: kan ikke sætte størrelsen af %s-sektion i %B"
+
+#: elf32-ppc.c:2290
+msgid "failed to allocate space for new APUinfo section."
+msgstr "kunne ikke tildele plads til ny APUinfo-sektion."
+
+#: elf32-ppc.c:2309
+msgid "failed to compute new APUinfo section."
+msgstr "kunne ikke beregne ny APUinfo-sektion."
+
+#: elf32-ppc.c:2312
+msgid "failed to install new APUinfo section."
+msgstr "kunne ikke installere ny APUinfo-sektion."
+
+#: elf32-ppc.c:3358
+msgid "%B: relocation %s cannot be used when making a shared object"
+msgstr "%B: relokeringen %s kan ikke bruges når et delt objekt oprettes"
+
+#. It does not make sense to have a procedure linkage
+#. table entry for a local symbol.
+#: elf32-ppc.c:3702
+msgid "%B(%A+0x%lx): %s reloc against local symbol"
+msgstr "%B(%A+0x%lx): %s-relokering mod lokalt symbol"
+
+#: elf32-ppc.c:4044 elf32-ppc.c:4059 elfxx-mips.c:12411 elfxx-mips.c:12437
+#: elfxx-mips.c:12459 elfxx-mips.c:12485
+msgid "Warning: %B uses hard float, %B uses soft float"
+msgstr "Advarsel: %B bruger flydende tal i hardware, %B bruger flydende tal i software"
+
+#: elf32-ppc.c:4047 elf32-ppc.c:4051
+msgid "Warning: %B uses double-precision hard float, %B uses single-precision hard float"
+msgstr "Advarsel: %B bruger dobbeltpræcisions-float i hardware, mens %B bruger enkeltpræcisions-float i hardware"
+
+#: elf32-ppc.c:4055
+msgid "Warning: %B uses soft float, %B uses single-precision hard float"
+msgstr "Advarsel: %B bruger software-float, mens %B bruger enkeltpræcisions-float i hardware"
+
+#: elf32-ppc.c:4062 elf32-ppc.c:4066 elfxx-mips.c:12391 elfxx-mips.c:12395
+msgid "Warning: %B uses unknown floating point ABI %d"
+msgstr "Advarsel: %B bruger ukendt ABI %d til flydende tal"
+
+#: elf32-ppc.c:4108 elf32-ppc.c:4112
+msgid "Warning: %B uses unknown vector ABI %d"
+msgstr "Advarsel: %B bruger ukendt vektor-ABI %d"
+
+#: elf32-ppc.c:4116
+msgid "Warning: %B uses vector ABI \"%s\", %B uses \"%s\""
+msgstr "Advarsel: %B bruger vektor-ABI \"%s\", mens %B bruger \"%s\""
+
+#: elf32-ppc.c:4133 elf32-ppc.c:4136
+msgid "Warning: %B uses r3/r4 for small structure returns, %B uses memory"
+msgstr "Advarsel: %B bruger r3/r4 til små struktur-returneringer, mens %B bruger hukommelsen"
+
+#: elf32-ppc.c:4139 elf32-ppc.c:4143
+msgid "Warning: %B uses unknown small structure return convention %d"
+msgstr "Advarsel: %B bruger ukendt returkonvention %d for småstrukturer"
+
+#: elf32-ppc.c:4197
+msgid "%B: compiled with -mrelocatable and linked with modules compiled normally"
+msgstr "%B: kompileret med -mrelocatable og lænket med moduler som er kompileret normalt"
+
+#: elf32-ppc.c:4205
+msgid "%B: compiled normally and linked with modules compiled with -mrelocatable"
+msgstr "%B: kompileret normalt og lænket med moduler som er kompileret med -mrelocatable"
+
+#: elf32-ppc.c:4293
+msgid "Using bss-plt due to %B"
+msgstr "Bruger bss-plt på grund af %B"
+
+#: elf32-ppc.c:7192 elf64-ppc.c:12307
+msgid "%B: unknown relocation type %d for symbol %s"
+msgstr "%B: ukendt relokeringstype %d for symbol %s"
+
+#: elf32-ppc.c:7453
+msgid "%B(%A+0x%lx): non-zero addend on %s reloc against `%s'"
+msgstr "%B(%A+0x%lx): addend forskellig fra nul på %s-relokering mod \"%s\""
+
+#: elf32-ppc.c:7651 elf64-ppc.c:12812
+msgid "%B(%A+0x%lx): relocation %s for indirect function %s unsupported"
+msgstr "%B(%A+0x%lx): relokering %s for indirekte funktion %s understøttes ikke"
+
+#: elf32-ppc.c:7881 elf32-ppc.c:7911 elf32-ppc.c:7958
+msgid "%B: the target (%s) of a %s relocation is in the wrong output section (%s)"
+msgstr "%B: målet (%s) for en %s-relokering er i den forkerte uddatasektion (%s)"
+
+#: elf32-ppc.c:8030
+msgid "%B: relocation %s is not yet supported for symbol %s."
+msgstr "%B: relokeringen %s understøttes endnu ikke for symbolet %s."
+
+#: elf32-ppc.c:8138 elf64-ppc.c:13162
+msgid "%B(%A+0x%lx): %s reloc against `%s': error %d"
+msgstr "%B(%A+0x%lx): relokering af %s mod \"%s\": fejl %d"
+
+#: elf32-ppc.c:8629
+#, c-format
+msgid "%s not defined in linker created %s"
+msgstr "%s er ikke defineret i lænker-oprettet %s"
+
+#: elf32-rx.c:544
+msgid "%B:%A: Warning: deprecated Red Hat reloc "
+msgstr "%B:%A: Advarsel: forældet Red Hat-relokering "
+
+#: elf32-rx.c:1086
+msgid "Warning: RX_SYM reloc with an unknown symbol"
+msgstr "Advarsel: RX_SYM-relokering med et ukendt symbol"
+
+#: elf32-rx.c:1251
+msgid "%B(%A): error: call to undefined function '%s'"
+msgstr "%B(%A): fejl: kald til udefineret funktion \"%s\""
+
+#: elf32-rx.c:1265
+msgid "%B(%A): warning: unaligned access to symbol '%s' in the small data area"
+msgstr "%B(%A): advarsel: ikke-justeret tilgang til symbol \"%s\" i det lille dataområde"
+
+#: elf32-rx.c:1269
+msgid "%B(%A): internal error: out of range error"
+msgstr "%B(%A): intern fejl: uden for intervallet"
+
+#: elf32-rx.c:1273
+msgid "%B(%A): internal error: unsupported relocation error"
+msgstr "%B(%A): intern fejl: relokeringen understøttes ikke"
+
+#: elf32-rx.c:1277
+msgid "%B(%A): internal error: dangerous relocation"
+msgstr "%B(%A): intern fejl: farlig relokering"
+
+#: elf32-rx.c:1281
+msgid "%B(%A): internal error: unknown error"
+msgstr "%B(%A): intern fejl: ukendt fejl"
+
+#: elf32-rx.c:2928
+#, c-format
+msgid " [64-bit doubles]"
+msgstr " [64 bit-doubles]"
+
+#: elf32-rx.c:2930
+#, c-format
+msgid " [dsp]"
+msgstr " [dsp]"
+
+#: elf32-s390.c:2209 elf64-s390.c:2196
+msgid "%B(%A+0x%lx): invalid instruction for TLS relocation %s"
+msgstr "%B(%A+0x%lx): ugyldig instruktion til TLS-relokering %s"
+
+#: elf32-score.c:1522 elf32-score7.c:1382 elfxx-mips.c:3323
+msgid "not enough GOT space for local GOT entries"
+msgstr "ikke nok med GOT-plads for lokale GOT-poster"
+
+# word er en datatype
+#: elf32-score.c:2744
+msgid "address not word align"
+msgstr "adresse er ikke justeret til word-position"
+
+#: elf32-score.c:2829 elf32-score7.c:2634
+#, c-format
+msgid "%s: Malformed reloc detected for section %s"
+msgstr "%s: Fejlagtig relokering for sektion %s opdaget"
+
+#: elf32-score.c:2880 elf32-score7.c:2685
+msgid "%B: CALL15 reloc at 0x%lx not against global symbol"
+msgstr "%B: CALL15-relokering ved 0x%lx er ikke mod globalt symbol"
+
+#: elf32-score.c:3999 elf32-score7.c:3806
+#, c-format
+msgid " [pic]"
+msgstr " [pic]"
+
+#: elf32-score.c:4003 elf32-score7.c:3810
+#, c-format
+msgid " [fix dep]"
+msgstr " [fix dep]"
+
+#: elf32-score.c:4045 elf32-score7.c:3852
+msgid "%B: warning: linking PIC files with non-PIC files"
+msgstr "%B: advarsel: lænker PIC-filer med ikke-PIC-filer"
+
+#: elf32-sh-symbian.c:130
+msgid "%B: IMPORT AS directive for %s conceals previous IMPORT AS"
+msgstr "%B: IMPORT AS-direktiv til %s skjuler forrige IMPORT AS"
+
+#: elf32-sh-symbian.c:383
+msgid "%B: Unrecognised .directive command: %s"
+msgstr "%B: Ukendt .directive-kommando: %s"
+
+#: elf32-sh-symbian.c:503
+msgid "%B: Failed to add renamed symbol %s"
+msgstr "%B: Kunne ikke tilføje omdøbt symbol %s"
+
+#: elf32-sh.c:568
+msgid "%B: 0x%lx: warning: bad R_SH_USES offset"
+msgstr "%B: 0x%lx: advarsel: fejlagtig R_SH_USES-afstand"
+
+#: elf32-sh.c:580
+msgid "%B: 0x%lx: warning: R_SH_USES points to unrecognized insn 0x%x"
+msgstr "%B: 0x%lx: advarsel: R_SH_USES peger på ukendt instruktion 0x%x"
+
+#: elf32-sh.c:597
+msgid "%B: 0x%lx: warning: bad R_SH_USES load offset"
+msgstr "%B: 0x%lx: advarsel: fejlagtig R_SH_USES-indlæsningsafstand"
+
+#: elf32-sh.c:612
+msgid "%B: 0x%lx: warning: could not find expected reloc"
+msgstr "%B: 0x%lx: advarsel: kunne ikke finde forventet relokering"
+
+#: elf32-sh.c:640
+msgid "%B: 0x%lx: warning: symbol in unexpected section"
+msgstr "%B: 0x%lx: advarsel: symbol i uventet sektion"
+
+#: elf32-sh.c:766
+msgid "%B: 0x%lx: warning: could not find expected COUNT reloc"
+msgstr "%B: 0x%lx: advarsel: kunne ikke finde forventet COUNT-relokering"
+
+#: elf32-sh.c:775
+msgid "%B: 0x%lx: warning: bad count"
+msgstr "%B: 0x%lx: advarsel: fejlagtigt antal"
+
+#: elf32-sh.c:1179 elf32-sh.c:1549
+msgid "%B: 0x%lx: fatal: reloc overflow while relaxing"
+msgstr "%B: 0x%lx: fatalt: relokering giver overløb ved forenklingen"
+
+#: elf32-sh.c:4057 elf64-sh64.c:1514
+msgid "Unexpected STO_SH5_ISA32 on local symbol is not handled"
+msgstr "Uventet STO_SH5_ISA32 på lokalt symbol håndteres ikke"
+
+#: elf32-sh.c:4304
+msgid "%B: 0x%lx: fatal: unaligned branch target for relax-support relocation"
+msgstr "%B: 0x%lx: fatalt: ujusteret grenmål for relokering for forenklingsunderstøttelse"
+
+#: elf32-sh.c:4337 elf32-sh.c:4352
+msgid "%B: 0x%lx: fatal: unaligned %s relocation 0x%lx"
+msgstr "%s: 0x%lx: fatalt: ujusteret %s-relokering 0x%lx"
+
+#: elf32-sh.c:4366
+msgid "%B: 0x%lx: fatal: R_SH_PSHA relocation %d not in range -32..32"
+msgstr "%B: 0x%lx: fatalt: R_SH_PSHA-relokering %d er uden for gyldigt interval -32..32"
+
+#: elf32-sh.c:4380
+msgid "%B: 0x%lx: fatal: R_SH_PSHL relocation %d not in range -32..32"
+msgstr "%B: 0x%lx: fatalt: R_SH_PSHL-relokering %d er uden for gyldigt interval -32..32"
+
+#: elf32-sh.c:4524 elf32-sh.c:4994
+msgid "%B(%A+0x%lx): cannot emit fixup to `%s' in read-only section"
+msgstr "%B(%A+0x%lx): kan ikke udsende \"fixup\" til \"%s\" i skrivebeskyttet sektion"
+
+#: elf32-sh.c:5101
+msgid "%B(%A+0x%lx): %s relocation against external symbol \"%s\""
+msgstr "%B(%A+0x%lx): %s-relokering mod eksternt symbol \"%s\""
+
+#: elf32-sh.c:5574
+#, c-format
+msgid "%X%C: relocation to \"%s\" references a different segment\n"
+msgstr "%X%C: relokering til \"%s\" refererer et andet segment\n"
+
+#: elf32-sh.c:5580
+#, c-format
+msgid "%C: warning: relocation to \"%s\" references a different segment\n"
+msgstr "%C: advarsel: relokering til \"%s\" refererer et andet segment\n"
+
+#: elf32-sh.c:6358 elf32-sh.c:6441
+msgid "%B: `%s' accessed both as normal and FDPIC symbol"
+msgstr "%B: \"%s\" tilgås både som normalt symbol og FDPIC-symbol"
+
+#: elf32-sh.c:6363 elf32-sh.c:6445
+msgid "%B: `%s' accessed both as FDPIC and thread local symbol"
+msgstr "%B: \"%s\" tilgås både som FDPIC-symbol og trådlokalt symbol"
+
+#: elf32-sh.c:6393
+msgid "%B: Function descriptor relocation with non-zero addend"
+msgstr "%B: Relokering af funktionsdeskriptor med addend forskellig fra nul"
+
+#: elf32-sh.c:6629 elf64-alpha.c:4560
+msgid "%B: TLS local exec code cannot be linked into shared objects"
+msgstr "%B: lokal TLS-eksekveringskode kan ikke lænkes ind i delte objekter"
+
+#: elf32-sh64.c:223 elf64-sh64.c:2314
+#, c-format
+msgid "%s: compiled as 32-bit object and %s is 64-bit"
+msgstr "%s: oversat som 32-bitsobjekt og %s er 64-bit"
+
+#: elf32-sh64.c:226 elf64-sh64.c:2317
+#, c-format
+msgid "%s: compiled as 64-bit object and %s is 32-bit"
+msgstr "%s: oversat som 64-bitsobjekt og %s er 32-bit"
+
+#: elf32-sh64.c:228 elf64-sh64.c:2319
+#, c-format
+msgid "%s: object size does not match that of target %s"
+msgstr "%s: objektstørrelsen stemmer ikke overens med den hos målet %s"
+
+#: elf32-sh64.c:451 elf64-sh64.c:2833
+#, c-format
+msgid "%s: encountered datalabel symbol in input"
+msgstr "%s: mødte dataetikettesymbol i inddata"
+
+#: elf32-sh64.c:528
+msgid "PTB mismatch: a SHmedia address (bit 0 == 1)"
+msgstr "PTB passer ikke: en SHmedia-adresse (bit 0 == 1)"
+
+#: elf32-sh64.c:531
+msgid "PTA mismatch: a SHcompact address (bit 0 == 0)"
+msgstr "PTA passer ikke: en SHcompact-adresse (bit 0 == 0)"
+
+#: elf32-sh64.c:549
+#, c-format
+msgid "%s: GAS error: unexpected PTB insn with R_SH_PT_16"
+msgstr "%s: GAS-fejl: uventet PTB-instruktion med R_SH_PT_16"
+
+#: elf32-sh64.c:598
+msgid "%B: error: unaligned relocation type %d at %08x reloc %p\n"
+msgstr "%B: fejl: ujusteret relokeringstype %d på %08x-relokering %08x\n"
+
+#: elf32-sh64.c:674
+#, c-format
+msgid "%s: could not write out added .cranges entries"
+msgstr "%s: kunne ikke udskrive tilføjede .cranges-poster"
+
+#: elf32-sh64.c:734
+#, c-format
+msgid "%s: could not write out sorted .cranges entries"
+msgstr "%s: kunne ikke udskrive sorterede cranges-poster"
+
+#: elf32-sparc.c:89
+msgid "%B: compiled for a 64 bit system and target is 32 bit"
+msgstr "%B: kompileret til et 64-bitssystem, men målet er 32-bit"
+
+#: elf32-sparc.c:102
+msgid "%B: linking little endian files with big endian files"
+msgstr "%B: lænker little endian-filer med big endian-filer"
+
+#: elf32-spu.c:719
+msgid "%X%P: overlay section %A does not start on a cache line.\n"
+msgstr "%X%P: overlay-sektion %A starter ikke på en cachelinje.\n"
+
+#: elf32-spu.c:727
+msgid "%X%P: overlay section %A is larger than a cache line.\n"
+msgstr "%X%P: overlay-sektion %A er større end en cachelinje.\n"
+
+#: elf32-spu.c:747
+msgid "%X%P: overlay section %A is not in cache area.\n"
+msgstr "%X%P: overlay-sektion %A er ikke i cacheområdet.\n"
+
+#: elf32-spu.c:787
+msgid "%X%P: overlay sections %A and %A do not start at the same address.\n"
+msgstr "%X%P: overlay-sektionerne %A og %A starter ikke på samme adresse.\n"
+
+#: elf32-spu.c:1011
+msgid "warning: call to non-function symbol %s defined in %B"
+msgstr "advarsel: kald til ikke-funktionssymbol %s defineret i %B"
+
+#: elf32-spu.c:1361
+msgid "%A:0x%v lrlive .brinfo (%u) differs from analysis (%u)\n"
+msgstr "%A:0x%v lrlive .brinfo (%u) afviger fra analyse (%u)\n"
+
+#: elf32-spu.c:1880
+msgid "%B is not allowed to define %s"
+msgstr "%B må ikke definere %s"
+
+#: elf32-spu.c:1888
+#, c-format
+msgid "you are not allowed to define %s in a script"
+msgstr "du har ikke lov til at definere %s i et script"
+
+#: elf32-spu.c:1922
+#, c-format
+msgid "%s in overlay section"
+msgstr "%s i overlay-sektion"
+
+#: elf32-spu.c:1951
+msgid "overlay stub relocation overflow"
+msgstr "overløb ved overlay-stub-relokering"
+
+#: elf32-spu.c:1960 elf64-ppc.c:11327
+msgid "stubs don't match calculated size"
+msgstr "stubbe stemmer ikke overens med beregnet størrelse"
+
+#: elf32-spu.c:2542
+#, c-format
+msgid "warning: %s overlaps %s\n"
+msgstr "advarsel: %s overlapper %s\n"
+
+#: elf32-spu.c:2558
+#, c-format
+msgid "warning: %s exceeds section size\n"
+msgstr "advarsel: %s overstiger sektionsstørrelse\n"
+
+#: elf32-spu.c:2589
+msgid "%A:0x%v not found in function table\n"
+msgstr "%A:0x%v ikke fundet i funktionstabel\n"
+
+#: elf32-spu.c:2729
+msgid "%B(%A+0x%v): call to non-code section %B(%A), analysis incomplete\n"
+msgstr "%B(%A+0x%v): kald til ikke-kodesektion %B(%A), analyse ufuldstændig\n"
+
+#: elf32-spu.c:3297
+#, c-format
+msgid "Stack analysis will ignore the call from %s to %s\n"
+msgstr "Stak-analyse vil ignorere kaldet fra %s til %s\n"
+
+#: elf32-spu.c:3988
+msgid " %s: 0x%v\n"
+msgstr " %s: 0x%v\n"
+
+#: elf32-spu.c:3989
+msgid "%s: 0x%v 0x%v\n"
+msgstr "%s: 0x%v 0x%v\n"
+
+#: elf32-spu.c:3994
+msgid " calls:\n"
+msgstr " kald:\n"
+
+#: elf32-spu.c:4002
+#, c-format
+msgid " %s%s %s\n"
+msgstr " %s%s %s\n"
+
+#: elf32-spu.c:4307
+#, c-format
+msgid "%s duplicated in %s\n"
+msgstr "%s er duplikeret i %s\n"
+
+#: elf32-spu.c:4311
+#, c-format
+msgid "%s duplicated\n"
+msgstr "%s duplikeret\n"
+
+#: elf32-spu.c:4318
+msgid "sorry, no support for duplicate object files in auto-overlay script\n"
+msgstr "beklager, men auto-overlay-scriptet understøtter ikke duplikerede objektfiler\n"
+
+#: elf32-spu.c:4359
+msgid "non-overlay size of 0x%v plus maximum overlay size of 0x%v exceeds local store\n"
+msgstr "ikke-overlay-størrelse af 0x%v plus den maksimale overlaystørrelse af 0x%v overstiger lokalt lager\n"
+
+#: elf32-spu.c:4514
+msgid "%B:%A%s exceeds overlay size\n"
+msgstr "%B:%A%s overstiger overlay-størrelsen\n"
+
+#: elf32-spu.c:4676
+msgid "Stack size for call graph root nodes.\n"
+msgstr "Stakstørrelsen for rodknuder i funktionskaldsgrafen.\n"
+
+#: elf32-spu.c:4677
+msgid ""
+"\n"
+"Stack size for functions. Annotations: '*' max stack, 't' tail call\n"
+msgstr ""
+"\n"
+"Stakstørrelse til funktioner. Annotationer: '*' maks stak, 't' tail call\n"
+
+#: elf32-spu.c:4687
+msgid "Maximum stack required is 0x%v\n"
+msgstr "Maksimum påkrævet stak er 0x%v\n"
+
+#: elf32-spu.c:4778
+msgid "fatal error while creating .fixup"
+msgstr "fatal fejl ved oprettelse af .fixup"
+
+#: elf32-spu.c:5006
+msgid "%B(%s+0x%lx): unresolvable %s relocation against symbol `%s'"
+msgstr "%B(%s+0x%lx): uløselig %s-relokering mod symbol \"%s\""
+
+#: elf32-tic6x.c:1539
+msgid "%B: SB-relative relocation but __c6xabi_DSBT_BASE not defined"
+msgstr "%B: SB-relativ relokering, men __c6xabi_DSBT_BASE er ikke defineret"
+
+#. Shared libraries and exception handling support not
+#. implemented.
+#: elf32-tic6x.c:1554
+msgid "%B: relocation type %d not implemented"
+msgstr "%B: relokeringstypen %d er ikke implementeret"
+
+#: elf32-tic6x.c:1640
+msgid "dangerous relocation"
+msgstr "farlig relokering"
+
+# ikke sikker på hvad det her betyder, så bruger mere direkte oversættelse end hvad der måske er nødvendigt
+#: elf32-tic6x.c:1788 elf32-tic6x.c:1796
+msgid "error: %B requires more stack alignment than %B preserves"
+msgstr "fejl: %B kræver mere stakjustering end %B præserverer"
+
+#: elf32-tic6x.c:1806 elf32-tic6x.c:1815
+msgid "error: unknown Tag_ABI_array_object_alignment value in %B"
+msgstr "fejl: ukendt værdi for Tag_ABI_array_object_alignment i %B"
+
+#: elf32-tic6x.c:1824 elf32-tic6x.c:1833
+msgid "error: unknown Tag_ABI_array_object_align_expected value in %B"
+msgstr "error: ukendt værdi for Tag_ABI_array_object_align_expected i %B"
+
+#: elf32-tic6x.c:1841 elf32-tic6x.c:1848
+msgid "error: %B requires more array alignment than %B preserves"
+msgstr "fejl: %B kræver mere array-justering end %B præserverer"
+
+#: elf32-tic6x.c:1870
+msgid "warning: %B and %B differ in wchar_t size"
+msgstr "advarsel: %B og %B har forskellig størrelse af wchar_t"
+
+#: elf32-tic6x.c:1888
+msgid "warning: %B and %B differ in whether code is compiled for DSBT"
+msgstr "advarsel: forskel på om %B og %B er kompileret til DSBT"
+
+#: elf32-tic6x.c:1898
+msgid "warning: %B and %B differ in position-dependence of data addressing"
+msgstr "advarsel: %B og %B har forskellig positionsafhængighed af dataadressering"
+
+#: elf32-tic6x.c:1908
+msgid "warning: %B and %B differ in position-dependence of code addressing"
+msgstr "advarsel: %B og %B har forskellig positionsafhængighed af kodeadressering"
+
+#: elf32-v850.c:173
+#, c-format
+msgid "Variable `%s' cannot occupy in multiple small data regions"
+msgstr "Variabel \"%s\" kan ikke befinde sig i flere små dataområder"
+
+#: elf32-v850.c:176
+#, c-format
+msgid "Variable `%s' can only be in one of the small, zero, and tiny data regions"
+msgstr "Variabel \"%s\" kan kun være i ét af de små, tomme og bittesmå dataområder"
+
+#: elf32-v850.c:179
+#, c-format
+msgid "Variable `%s' cannot be in both small and zero data regions simultaneously"
+msgstr "Variabel \"%s\" kan ikke være i både små og tomme dataområder samtidigt"
+
+#: elf32-v850.c:182
+#, c-format
+msgid "Variable `%s' cannot be in both small and tiny data regions simultaneously"
+msgstr "Variabel \"%s\" kan ikke være i både små og bittesmå dataområder samtidigt"
+
+#: elf32-v850.c:185
+#, c-format
+msgid "Variable `%s' cannot be in both zero and tiny data regions simultaneously"
+msgstr "Variabel \"%s\" kan ikke være i både tomme og bittesmå dataområder samtidigt"
+
+#: elf32-v850.c:483
+#, c-format
+msgid "FAILED to find previous HI16 reloc\n"
+msgstr "MISLYKKEDES med at finde tidligere HI16-relokering\n"
+
+#: elf32-v850.c:2155
+msgid "could not locate special linker symbol __gp"
+msgstr "kunne ikke lokalisere specielt lænkersymbol __gp"
+
+#: elf32-v850.c:2159
+msgid "could not locate special linker symbol __ep"
+msgstr "kunne ikke lokalisere specielt lænkersymbol __ep"
+
+#: elf32-v850.c:2163
+msgid "could not locate special linker symbol __ctbp"
+msgstr "kunne ikke lokalisere specielt lænkersymbol __ctbp"
+
+#: elf32-v850.c:2341
+msgid "%B: Architecture mismatch with previous modules"
+msgstr "%B: Arkitekturen passer ikke sammen med tidligere moduler"
+
+#. xgettext:c-format.
+#: elf32-v850.c:2360
+#, c-format
+msgid "private flags = %lx: "
+msgstr "private flag = %lx: "
+
+#: elf32-v850.c:2365
+#, c-format
+msgid "v850 architecture"
+msgstr "v850-arkitektur"
+
+#: elf32-v850.c:2366
+#, c-format
+msgid "v850e architecture"
+msgstr "v850e-arkitektur"
+
+#: elf32-v850.c:2367
+#, c-format
+msgid "v850e1 architecture"
+msgstr "v850e1-arkitektur"
+
+#: elf32-v850.c:2368
+#, c-format
+msgid "v850e2 architecture"
+msgstr "v850e2-arkitektur"
+
+#: elf32-v850.c:2369
+#, c-format
+msgid "v850e2v3 architecture"
+msgstr "v850e2v3-arkitektur"
+
+#: elf32-vax.c:531
+#, c-format
+msgid " [nonpic]"
+msgstr " [ikke-pic]"
+
+#: elf32-vax.c:534
+#, c-format
+msgid " [d-float]"
+msgstr " [d-flydende tal]"
+
+#: elf32-vax.c:537
+#, c-format
+msgid " [g-float]"
+msgstr " [g-flydende tal]"
+
+#: elf32-vax.c:654
+#, c-format
+msgid "%s: warning: GOT addend of %ld to `%s' does not match previous GOT addend of %ld"
+msgstr "%s: advarsel: GOT-addendum %ld til \"%s\" stemmer ikke overens med tidligere GOT-addendum %ld"
+
+#: elf32-vax.c:1587
+#, c-format
+msgid "%s: warning: PLT addend of %d to `%s' from %s section ignored"
+msgstr "%s: advarsel: PLT-addendum %d til \"%s\" fra sektionen %s ignoreredes"
+
+#: elf32-vax.c:1714
+#, c-format
+msgid "%s: warning: %s relocation against symbol `%s' from %s section"
+msgstr "%s: advarsel: %s-relokering mod symbol \"%s\" fra sektionen %s"
+
+#: elf32-vax.c:1720
+#, c-format
+msgid "%s: warning: %s relocation to 0x%x from %s section"
+msgstr "%s: advarsel: %s-relokering til 0x%x fra sektionen %s"
+
+#: elf32-xstormy16.c:451 elf32-ia64.c:2861 elf64-ia64.c:2861
+msgid "non-zero addend in @fptr reloc"
+msgstr "ikke-tomt addendum i @fptr-relokering"
+
+#: elf32-xtensa.c:918
+msgid "%B(%A): invalid property table"
+msgstr "%B(%A): ugyldig egenskabstabel"
+
+#: elf32-xtensa.c:2780
+msgid "%B(%A+0x%lx): relocation offset out of range (size=0x%x)"
+msgstr "%B(%A+0x%lx): relokeringsafsæt uden for gyldigt interval (størrelse=0x%x)"
+
+#: elf32-xtensa.c:2859 elf32-xtensa.c:2980
+msgid "dynamic relocation in read-only section"
+msgstr "dynamisk relokering i skrivebeskyttet sektion"
+
+#: elf32-xtensa.c:2956
+msgid "TLS relocation invalid without dynamic sections"
+msgstr "TLS-relokering er ugyldig uden dynamiske sektioner"
+
+#: elf32-xtensa.c:3173
+msgid "internal inconsistency in size of .got.loc section"
+msgstr "intern inkonsistens i størrelsen af .got.loc-sektion"
+
+#: elf32-xtensa.c:3486
+msgid "%B: incompatible machine type. Output is 0x%x. Input is 0x%x"
+msgstr "%B: inkompatibel maskintype. Uddata er 0x%x. Inddata er 0x%x"
+
+#: elf32-xtensa.c:4715 elf32-xtensa.c:4723
+msgid "Attempt to convert L32R/CALLX to CALL failed"
+msgstr "Forsøg på at konvertere L32R/CALLX til CALL mislykkedes"
+
+#: elf32-xtensa.c:6333 elf32-xtensa.c:6409 elf32-xtensa.c:7525
+msgid "%B(%A+0x%lx): could not decode instruction; possible configuration mismatch"
+msgstr "%B(%A+0x%lx): kunne ikke afkode instruktion; mulig konfigurationsmodstrid"
+
+#: elf32-xtensa.c:7265
+msgid "%B(%A+0x%lx): could not decode instruction for XTENSA_ASM_SIMPLIFY relocation; possible configuration mismatch"
+msgstr "%B(%A+0x%lx): kunne ikke afkode instruktion til XTENSA_ASM_SIMPLIFY-relokering; mulig konfigurationsmodstrid"
+
+#: elf32-xtensa.c:9024
+msgid "invalid relocation address"
+msgstr "ugyldig relokeringsadresse"
+
+#: elf32-xtensa.c:9073
+msgid "overflow after relaxation"
+msgstr "overløb efter forenkling"
+
+#: elf32-xtensa.c:10205
+msgid "%B(%A+0x%lx): unexpected fix for %s relocation"
+msgstr "%B(%A+0x%lx): uventet fiks til %s-relokering"
+
+#: elf64-alpha.c:460
+msgid "GPDISP relocation did not find ldah and lda instructions"
+msgstr "GPDISP-relokering fandt ingen ldah- og lda-instruktioner"
+
+#: elf64-alpha.c:2408
+msgid "%B: .got subsegment exceeds 64K (size %d)"
+msgstr "%B: .got-subsegment overskrider 64K (størrelse %d)"
+
+#: elf64-alpha.c:4304 elf64-alpha.c:4316
+msgid "%B: gp-relative relocation against dynamic symbol %s"
+msgstr "%B: gp-relativ relokering mod dynamisk symbol %s"
+
+#: elf64-alpha.c:4342 elf64-alpha.c:4477
+msgid "%B: pc-relative relocation against dynamic symbol %s"
+msgstr "%B: pc-relativ relokering mod dynamisk symbol %s"
+
+#: elf64-alpha.c:4370
+msgid "%B: change in gp: BRSGP %s"
+msgstr "%B: ændring i gp: BRSGP %s"
+
+#: elf64-alpha.c:4395
+msgid "<unknown>"
+msgstr "<ukendt>"
+
+#: elf64-alpha.c:4400
+msgid "%B: !samegp reloc against symbol without .prologue: %s"
+msgstr "%B: !samegp-relokering mod symbol uden .prologue: %s"
+
+#: elf64-alpha.c:4452
+msgid "%B: unhandled dynamic relocation against %s"
+msgstr "%B: uhåndteret dynamisk relokering mod %s"
+
+#: elf64-alpha.c:4484
+msgid "%B: pc-relative relocation against undefined weak symbol %s"
+msgstr "%B: pc-relativ relokering mod udefineret svagt symbol %s"
+
+#: elf64-alpha.c:4544
+msgid "%B: dtp-relative relocation against dynamic symbol %s"
+msgstr "%B: dtp-relativ relokering mod dynamisk symbol %s"
+
+#: elf64-alpha.c:4567
+msgid "%B: tp-relative relocation against dynamic symbol %s"
+msgstr "%B: tp-relativ relokering mod dynamisk symbol %s"
+
+#: elf64-hppa.c:2101
+#, c-format
+msgid "stub entry for %s cannot load .plt, dp offset = %ld"
+msgstr "stubpost for %s kan ikke indlæse .plt, dp-afstand = %ld"
+
+#: elf64-hppa.c:3299
+msgid "%B(%A+0x%lx): cannot reach %s"
+msgstr "%B(%A+0x%lx): kan ikke nå %s"
+
+#: elf64-mmix.c:1177
+#, c-format
+msgid ""
+"%s: Internal inconsistency error for value for\n"
+" linker-allocated global register: linked: 0x%lx%08lx != relaxed: 0x%lx%08lx\n"
+msgstr ""
+"%s: Intern inkonsistensfejl for værdien for\n"
+" lænkerallokeret globalt register: lænket: 0x%lx%08lx != forenklet: 0x%lx%08lx\n"
+
+#: elf64-mmix.c:1607
+#, c-format
+msgid "%s: base-plus-offset relocation against register symbol: (unknown) in %s"
+msgstr "%s: base-plus-afstandsrelokering mod registersymbol: (ukendt) i %s"
+
+#: elf64-mmix.c:1612
+#, c-format
+msgid "%s: base-plus-offset relocation against register symbol: %s in %s"
+msgstr "%s: base-plus-afstandsrelokering mod registersymbol: %s i %s"
+
+#: elf64-mmix.c:1656
+#, c-format
+msgid "%s: register relocation against non-register symbol: (unknown) in %s"
+msgstr "%s: registerrelokering mod ikke-registersymbol: (ukendt) i %s"
+
+#: elf64-mmix.c:1661
+#, c-format
+msgid "%s: register relocation against non-register symbol: %s in %s"
+msgstr "%s: registerrelokering mod ikke-registersymbol: %s i %s"
+
+#: elf64-mmix.c:1698
+#, c-format
+msgid "%s: directive LOCAL valid only with a register or absolute value"
+msgstr "%s: LOCAL-direktivet er kun gyldigt med et register eller en absolutværdi"
+
+#: elf64-mmix.c:1726
+#, c-format
+msgid "%s: LOCAL directive: Register $%ld is not a local register. First global register is $%ld."
+msgstr "%s: LOCAL-direktiv: Register $%ld er ikke et lokalt register. Første globale register er $%ld."
+
+#: elf64-mmix.c:2190
+#, c-format
+msgid "%s: Error: multiple definition of `%s'; start of %s is set in a earlier linked file\n"
+msgstr "%s: Fejl: flere definitioner af \"%s\"; begyndelsen på %s er sat i en tidligere lænket fil\n"
+
+#: elf64-mmix.c:2248
+msgid "Register section has contents\n"
+msgstr "Registersektion har indhold\n"
+
+#: elf64-mmix.c:2440
+#, c-format
+msgid ""
+"Internal inconsistency: remaining %u != max %u.\n"
+" Please report this bug."
+msgstr ""
+"Intern inkonsekvens: genstående %u != max %u.\n"
+" Rapportér gerne denne fejl."
+
+#: elf64-ppc.c:2741 libbfd.c:997
+msgid "%B: compiled for a big endian system and target is little endian"
+msgstr "%B: kompileret til et big endian-system, men målet er little endian"
+
+#: elf64-ppc.c:2744 libbfd.c:999
+msgid "%B: compiled for a little endian system and target is big endian"
+msgstr "%B: kompileret til et little endian-system, men målet er big endian"
+
+# lazy (i computersammenhæng) ~ først at gøre noget, når det er nødvendigt. Hvis programmøren skriver x = 2 + 2 men først bruger variablen x senere, vil udregningen 2+2 altså først ske senere.
+#: elf64-ppc.c:6473
+#, c-format
+msgid "copy reloc against `%s' requires lazy plt linking; avoid setting LD_BIND_NOW=1 or upgrade gcc"
+msgstr "kopiering af relokering mod \"%s\" kræver forsinket plt-lænkning; undgå at sætte LD_BIND_NOW=1 eller opgradér gcc"
+
+#: elf64-ppc.c:6901
+msgid "dynreloc miscount for %B, section %A"
+msgstr "dynreloc-fejloptælling for %B, sektion %A"
+
+#: elf64-ppc.c:6985
+msgid "%B: .opd is not a regular array of opd entries"
+msgstr "%B: .opd er ikke et almindeligt array af opd-poster"
+
+#: elf64-ppc.c:6994
+msgid "%B: unexpected reloc type %u in .opd section"
+msgstr "%B: uventet relokeringstype %u i .opd-sektion"
+
+#: elf64-ppc.c:7015
+msgid "%B: undefined sym `%s' in .opd section"
+msgstr "%B: udefineret symbol \"%s\" i .opd-sektion"
+
+#: elf64-ppc.c:7877 elf64-ppc.c:8392
+#, c-format
+msgid "%s defined on removed toc entry"
+msgstr "%s defineret på fjernet toc-post"
+
+#: elf64-ppc.c:9459
+#, c-format
+msgid "long branch stub `%s' offset overflow"
+msgstr "afsætoverløb for lang grenstub \"%s\""
+
+#: elf64-ppc.c:9518
+#, c-format
+msgid "can't find branch stub `%s'"
+msgstr "kan ikke finde grenstub \"%s\""
+
+#: elf64-ppc.c:9580 elf64-ppc.c:9716
+#, c-format
+msgid "linkage table error against `%s'"
+msgstr "lænketabelsfejl mod \"%s\""
+
+#: elf64-ppc.c:9886
+#, c-format
+msgid "can't build branch stub `%s'"
+msgstr "kan ikke bygge grenstub \"%s\""
+
+#: elf64-ppc.c:10684
+msgid "%B section %A exceeds stub group size"
+msgstr "%B-sektionen %A overstiger stub-gruppestørrelsen"
+
+# ?
+#: elf64-ppc.c:11339
+#, c-format
+msgid ""
+"linker stubs in %u group%s\n"
+" branch %lu\n"
+" toc adjust %lu\n"
+" long branch %lu\n"
+" long toc adj %lu\n"
+" plt call %lu"
+msgstr ""
+"lænkerstubbe i %u gruppe%s\n"
+" branch %lu\n"
+" toc adjust %lu\n"
+" long branch %lu\n"
+" long toc adj %lu\n"
+" plt call %lu"
+
+#: elf64-ppc.c:12190
+msgid "%B(%A+0x%lx): automatic multiple TOCs not supported using your crt files; recompile with -mminimal-toc or upgrade gcc"
+msgstr "%B(%A+0x%lx): flere automatiske TOC'er understøttes ikke med dine crt-filer; genkompilér med -mminimal-toc eller opgradér gcc"
+
+#: elf64-ppc.c:12198
+msgid "%B(%A+0x%lx): sibling call optimization to `%s' does not allow automatic multiple TOCs; recompile with -mminimal-toc or -fno-optimize-sibling-calls, or make `%s' extern"
+msgstr "%B(%A+0x%lx): \"sibling call\"-optimering til \"%s\" tillader ikke flere indholdsfortegnelser; genkompilér med -mminimal-toc eller -fno-optimize-sibling-calls eller gør \"%s\" ekstern"
+
+#: elf64-ppc.c:12919
+msgid "%B: relocation %s is not supported for symbol %s."
+msgstr "%B: relokeringen %s understøttes ikke for symbol %s."
+
+#: elf64-ppc.c:13096
+msgid "%B: error: relocation %s not a multiple of %d"
+msgstr "%B: fejl: relokeringen %s er ikke et multiplum af %d"
+
+#: elf64-sh64.c:1682
+#, c-format
+msgid "%s: error: unaligned relocation type %d at %08x reloc %08x\n"
+msgstr "%s: fejl: ujusteret relokeringstype %d på %08x relokering %08x\n"
+
+#: elf64-sparc.c:444
+msgid "%B: Only registers %%g[2367] can be declared using STT_REGISTER"
+msgstr "%B: Kun registrene %%g[2367] kan erklæres med STT_REGISTER"
+
+#: elf64-sparc.c:464
+msgid "Register %%g%d used incompatibly: %s in %B, previously %s in %B"
+msgstr "Register %%g%d bruges inkompatibelt: %s i %B, tidligere %s i %B"
+
+#: elf64-sparc.c:487
+msgid "Symbol `%s' has differing types: REGISTER in %B, previously %s in %B"
+msgstr "Symbolet \"%s\" har forskellige typer: REGISTER i %B, tidligere %s i %B"
+
+#: elf64-sparc.c:532
+msgid "Symbol `%s' has differing types: %s in %B, previously REGISTER in %B"
+msgstr "Symbolet \"%s\" har forskellige typer: %s i %B, tidligere REGISTER i %B"
+
+#: elf64-sparc.c:684
+msgid "%B: linking UltraSPARC specific with HAL specific code"
+msgstr "%B: lænker UltraSPARC-specifik med HAL-specifik kode"
+
+#: elf64-x86-64.c:1360
+msgid "%B: '%s' accessed both as normal and thread local symbol"
+msgstr "%B: \"%s\" tilgås både som normalt og trådlokalt symbol"
+
+#: elf64-x86-64.c:2801
+msgid "%B: relocation %s against STT_GNU_IFUNC symbol `%s' has non-zero addend: %d"
+msgstr "%B: relokering %s mod STT_GNU_IFUNC-symbol \"%s\" har addend forskellig fra nul: %d"
+
+#: elf64-x86-64.c:3073
+msgid "%B: relocation R_X86_64_GOTOFF64 against protected function `%s' can not be used when making a shared object"
+msgstr "%B: relokeringen R_X86_64_GOTOFF64 mod beskyttet funktion \"%s\" kan ikke bruges når et delt objekt oprettes"
+
+#: elf64-x86-64.c:3184
+msgid "; recompile with -fPIC"
+msgstr "; genkompilér med -fPIC"
+
+#: elf64-x86-64.c:3189
+msgid "%B: relocation %s against %s `%s' can not be used when making a shared object%s"
+msgstr "%B: relokeringen %s mod %s \"%s\" kan ikke bruges når et delt objekt oprettes%s"
+
+#: elf64-x86-64.c:3191
+msgid "%B: relocation %s against undefined %s `%s' can not be used when making a shared object%s"
+msgstr "%B: relokeringen %s mod udefineret %s \"%s\" kan ikke bruges når et delt objekt oprettes%s"
+
+#: elfcode.h:826
+#, c-format
+msgid "warning: %s has a corrupt string table index - ignoring"
+msgstr "advarsel: %s har et beskadiget strengtabelindeks - ignorerer"
+
+#: elfcode.h:1236
+#, c-format
+msgid "%s: version count (%ld) does not match symbol count (%ld)"
+msgstr "%s: versionsantal (%ld) stemmer ikke med symbolantal (%ld)"
+
+#: elfcode.h:1476
+#, c-format
+msgid "%s(%s): relocation %d has invalid symbol index %ld"
+msgstr "%s(%s): relokering %d har ugyligt symbolindeks %ld"
+
+#: elfcore.h:312
+msgid "Warning: %B is truncated: expected core file size >= %lu, found: %lu."
+msgstr "Advarsel: %B er afkortet: forventede kernefilstørrelse >= %lu, fandt: %lu."
+
+#: elflink.c:1119
+msgid "%s: TLS definition in %B section %A mismatches non-TLS definition in %B section %A"
+msgstr "%s: TLS-definition i %B sektion %A stemmer ikke med ikke-TLS-definition i %B sektion %A"
+
+#: elflink.c:1123
+msgid "%s: TLS reference in %B mismatches non-TLS reference in %B"
+msgstr "%s: TLS-reference i %B stemmer ikke med ikke-TLS-reference i %B"
+
+#: elflink.c:1127
+msgid "%s: TLS definition in %B section %A mismatches non-TLS reference in %B"
+msgstr "%s: TLS-definition i %B sektion %A stemmer ikke med ikke-TLS-reference i %B"
+
+#: elflink.c:1131
+msgid "%s: TLS reference in %B mismatches non-TLS definition in %B section %A"
+msgstr "%s: TLS-reference i %B stemmer ikke med ikke-TLS-definition i %B sektion %A"
+
+#: elflink.c:1763
+msgid "%B: unexpected redefinition of indirect versioned symbol `%s'"
+msgstr "%B: uventet omdefinition af indirekte versionstildelt symbol \"%s\""
+
+#: elflink.c:2076
+msgid "%B: version node not found for symbol %s"
+msgstr "%B: versionsknude ikke fundet for symbolet %s"
+
+#: elflink.c:2166
+msgid "%B: bad reloc symbol index (0x%lx >= 0x%lx) for offset 0x%lx in section `%A'"
+msgstr "%B: fejlagtig relokeringssymbolindeks (0x%lx >= 0x%lx) for afsæt 0x%lx i sektionen \"%A\""
+
+#: elflink.c:2177
+msgid "%B: non-zero symbol index (0x%lx) for offset 0x%lx in section `%A' when the object file has no symbol table"
+msgstr "%B: symboltabellen (0x%lx) forskelligt fra nul for afsæt 0x%lx i sektion \"%s\" mens objektfilen ikke har nogen symboltabelc"
+
+#: elflink.c:2367
+msgid "%B: relocation size mismatch in %B section %A"
+msgstr "%B: relokeringsstørrelsen stemmer ikke overens i %B-sektionen %A"
+
+#: elflink.c:2662
+#, c-format
+msgid "warning: type and size of dynamic symbol `%s' are not defined"
+msgstr "advarsel: typen og størrelsen på dynamisk symbol \"%s\" er ikke defineret"
+
+#: elflink.c:3418
+msgid "%P: alternate ELF machine code found (%d) in %B, expecting %d\n"
+msgstr "%P: alternativ ELF-maskinkode fundet (%d) i %B; forventer %d\n"
+
+#: elflink.c:4050
+msgid "%B: %s: invalid version %u (max %d)"
+msgstr "%B: %s: ugyldig version %u (max %d)"
+
+#: elflink.c:4086
+msgid "%B: %s: invalid needed version %d"
+msgstr "%B: %s: ugyldig krævet version %d"
+
+#: elflink.c:4285
+msgid "Warning: alignment %u of common symbol `%s' in %B is greater than the alignment (%u) of its section %A"
+msgstr "Advarsel: justering %u af fælles symbol \"%s\" i %B er større end justeringen (%u) af dets sektion %A"
+
+#: elflink.c:4291
+msgid "Warning: alignment %u of symbol `%s' in %B is smaller than %u in %B"
+msgstr "Advarsel: justeringen %u på symbolet \"%s\" i %B er mindre end %u i %B"
+
+#: elflink.c:4306
+msgid "Warning: size of symbol `%s' changed from %lu in %B to %lu in %B"
+msgstr "Advarsel: størrelsen på symbol \"%s\" ændredes fra %lu i %B til %lu i %B"
+
+#: elflink.c:4472
+msgid "%B: undefined reference to symbol '%s'"
+msgstr "%B: udefineret reference til symbol \"%s\""
+
+#: elflink.c:4475
+msgid "note: '%s' is defined in DSO %B so try adding it to the linker command line"
+msgstr "bemærk: \"%s\" er defineret i DSO %B, så prøv at tilføje den til lænker-kommandolinjen"
+
+#: elflink.c:5779
+#, c-format
+msgid "%s: undefined version: %s"
+msgstr "%s: udefineret version: %s"
+
+#: elflink.c:5847
+msgid "%B: .preinit_array section is not allowed in DSO"
+msgstr "%B: .preinit_array-sektionen er ikke tilladt i DSO"
+
+#: elflink.c:7598
+#, c-format
+msgid "undefined %s reference in complex symbol: %s"
+msgstr "udefineret %s-reference i komplekst symbol: %s"
+
+#: elflink.c:7752
+#, c-format
+msgid "unknown operator '%c' in complex symbol"
+msgstr "ukendt operator \"%c\" i komplekst symbol"
+
+#: elflink.c:8091 elflink.c:8108 elflink.c:8145 elflink.c:8162
+msgid "%B: Unable to sort relocs - they are in more than one size"
+msgstr "%B: Kan ikke sortere relokeringer - de har flere forskellige størrelser"
+
+#: elflink.c:8122 elflink.c:8176
+msgid "%B: Unable to sort relocs - they are of an unknown size"
+msgstr "%B: Kan ikke sortere relokeringer - de har ukendt størrelse"
+
+#: elflink.c:8227
+msgid "Not enough memory to sort relocations"
+msgstr "Ikke nok hukommelse til at sortere relokeringer"
+
+#: elflink.c:8420
+msgid "%B: Too many sections: %d (>= %d)"
+msgstr "%B: For mange sektioner: %d (>= %d)"
+
+#: elflink.c:8663
+msgid "%B: %s symbol `%s' in %B is referenced by DSO"
+msgstr "%B: %s-symbol \"%s\" i %B refereres af DSO"
+
+#: elflink.c:8754
+msgid "%B: could not find output section %A for input section %A"
+msgstr "%B: kunne ikke finde uddatasektionen %A for inddatasektionen %A"
+
+#: elflink.c:8874
+msgid "%B: %s symbol `%s' isn't defined"
+msgstr "%B: %s-symbolet \"%s\" er udefineret"
+
+#: elflink.c:9428
+msgid "error: %B contains a reloc (0x%s) for section %A that references a non-existent global symbol"
+msgstr "fejl: %B indeholder en relokering (0x%s) til sektionen %A, som refererer et ikke-eksisterende global symbol"
+
+#: elflink.c:9494
+msgid "%X`%s' referenced in section `%A' of %B: defined in discarded section `%A' of %B\n"
+msgstr "%X\"%s\" refereret i sektion \"%A\" af %B: defineret i forkastet sektion \"%A\" af %B\n"
+
+#: elflink.c:10141
+msgid "%A has both ordered [`%A' in %B] and unordered [`%A' in %B] sections"
+msgstr "%A har både ordnede [\"%A\" i %B] og uordnede [\"%A\" i %B] sektioner"
+
+#: elflink.c:10146
+#, c-format
+msgid "%A has both ordered and unordered sections"
+msgstr "%A har både ordnede og uordnede sektioner"
+
+#: elflink.c:10992 elflink.c:11036
+msgid "%B: could not find output section %s"
+msgstr "%B: kunne ikke finde uddatasektionen %s"
+
+#: elflink.c:10997
+#, c-format
+msgid "warning: %s section has zero size"
+msgstr "advarsel: %s-sektionen har nulstørrelse"
+
+#: elflink.c:11102
+msgid "%P: warning: creating a DT_TEXTREL in a shared object.\n"
+msgstr "%P: advarsel: opretter en DT_TEXTREL i et delt objekt.\n"
+
+#: elflink.c:11289
+msgid "%P%X: can not read symbols: %E\n"
+msgstr "%P%X: kan ikke læse symboler: %E\n"
+
+#: elflink.c:11638
+msgid "Removing unused section '%s' in file '%B'"
+msgstr "Fjerner ubrugt sektion \"%s\" i filen \"%B\""
+
+# gc-sections- eller gc-sektions-?
+#: elflink.c:11850
+msgid "Warning: gc-sections option ignored"
+msgstr "Advarsel: gc-sections-tilvalg ignoreret"
+
+#: elflink.c:12399
+msgid "%B: ignoring duplicate section `%A'"
+msgstr "%B: ignorerer gentaget sektion \"%A\""
+
+#: elflink.c:12406 elflink.c:12413
+msgid "%B: duplicate section `%A' has different size"
+msgstr "%B: gentaget sektion \"%A\" har forskellig størrelse"
+
+#: elflink.c:12421 elflink.c:12426
+msgid "%B: warning: could not read contents of section `%A'"
+msgstr "%B: advarsel: kunne ikke læse indholdet af sektionen \"%A\""
+
+#: elflink.c:12430
+msgid "%B: warning: duplicate section `%A' has different contents"
+msgstr "%B: advarsel: gentaget sektion \"%A\" har forskelligt indhold"
+
+#: elflink.c:12531 linker.c:3138
+msgid "%F%P: already_linked_table: %E\n"
+msgstr "%F%P: already_linked_table: %E\n"
+
+#: elfxx-mips.c:1220
+msgid "static procedure (no name)"
+msgstr "statisk procedure (intet navn)"
+
+#: elfxx-mips.c:5623
+msgid "%B: %A+0x%lx: Direct jumps between ISA modes are not allowed; consider recompiling with interlinking enabled."
+msgstr "%B: %A+0x%lx: Direkte hop mellem ISA-tilstande er ikke tilladt; overvej at genkompilere med interlinking slået til."
+
+#: elfxx-mips.c:6280 elfxx-mips.c:6503
+msgid "%B: Warning: bad `%s' option size %u smaller than its header"
+msgstr "%B: Advarsel: Ugyldig \"%s\"-tilvalgsstørrelse %u mindre end dens header"
+
+#: elfxx-mips.c:7254 elfxx-mips.c:7379
+msgid "%B: Warning: cannot determine the target function for stub section `%s'"
+msgstr "%B: Advarsel: Kan ikke bestemme målfunktionen for stubsektionen \"%s\""
+
+#: elfxx-mips.c:7508
+msgid "%B: Malformed reloc detected for section %s"
+msgstr "%B: Fejlagtig relokering for sektion %s opdaget"
+
+#: elfxx-mips.c:7548
+msgid "%B: GOT reloc at 0x%lx not expected in executables"
+msgstr "%B: GOT-relokering ved 0x%lx forventes ikke i eksekveringsfiler"
+
+#: elfxx-mips.c:7670
+msgid "%B: CALL16 reloc at 0x%lx not against global symbol"
+msgstr "%B: CALL16-relokering ved 0x%lx er ikke mod globalt symbol"
+
+#: elfxx-mips.c:8365
+#, c-format
+msgid "non-dynamic relocations refer to dynamic symbol %s"
+msgstr "udynamiske relokeringer refererer til dynamisk symbol %s"
+
+#: elfxx-mips.c:9068
+msgid "%B: Can't find matching LO16 reloc against `%s' for %s at 0x%lx in section `%A'"
+msgstr "%B: Kan ikke finde matchende LO16-relokering mod \"%s\" for %s ved 0x%lx i sektion \"%A\""
+
+#: elfxx-mips.c:9207
+msgid "small-data section exceeds 64KB; lower small-data size limit (see option -G)"
+msgstr "sektionen small-data overstiger 6KB; gør størrelsesgrænsen for small-data mindre (se tilvalget -G)"
+
+#: elfxx-mips.c:12027
+#, c-format
+msgid "%s: illegal section name `%s'"
+msgstr "%s: ugyldigt sektionsnavn \"%s\""
+
+#: elfxx-mips.c:12405 elfxx-mips.c:12431
+msgid "Warning: %B uses -msingle-float, %B uses -mdouble-float"
+msgstr "Advarsel: %B bruger -msingle-float, %B bruger -mdouble-float"
+
+#: elfxx-mips.c:12417 elfxx-mips.c:12473
+msgid "Warning: %B uses -msingle-float, %B uses -mips32r2 -mfp64"
+msgstr "Advarsel: %B bruger -msingle-float, %B bruger -mips32r2 -mfp64"
+
+#: elfxx-mips.c:12443 elfxx-mips.c:12479
+msgid "Warning: %B uses -mdouble-float, %B uses -mips32r2 -mfp64"
+msgstr "Advarsel: %B bruger -mdouble-float, %B bruger -mips32r2 -mfp64"
+
+#: elfxx-mips.c:12521
+msgid "%B: endianness incompatible with that of the selected emulation"
+msgstr "%B: endian-hed er ikke kompatibel den valgte emulerings endian-hed"
+
+#: elfxx-mips.c:12532
+msgid "%B: ABI is incompatible with that of the selected emulation"
+msgstr "%B: ABI er ikke kompatibel med den valgte emulerings ABI"
+
+#: elfxx-mips.c:12613
+msgid "%B: warning: linking abicalls files with non-abicalls files"
+msgstr "%B: advarsel: lænker abicalls-filer med ikke-abicalls-filer"
+
+#: elfxx-mips.c:12630
+msgid "%B: linking 32-bit code with 64-bit code"
+msgstr "%B: lænker 32 bit-kode med 64 bit-kode"
+
+#: elfxx-mips.c:12658
+msgid "%B: linking %s module with previous %s modules"
+msgstr "%B: lænker %s-modul med tidligere %s-moduler"
+
+#: elfxx-mips.c:12681
+msgid "%B: ABI mismatch: linking %s module with previous %s modules"
+msgstr "%B: ABI passer ikke: lænker %s-modul med tidligere %s-moduler"
+
+#: elfxx-mips.c:12845
+#, c-format
+msgid " [abi=O32]"
+msgstr " [abi=O32]"
+
+#: elfxx-mips.c:12847
+#, c-format
+msgid " [abi=O64]"
+msgstr " [abi=O64]"
+
+#: elfxx-mips.c:12849
+#, c-format
+msgid " [abi=EABI32]"
+msgstr " [abi=EABI32]"
+
+#: elfxx-mips.c:12851
+#, c-format
+msgid " [abi=EABI64]"
+msgstr " [abi=EABI64]"
+
+#: elfxx-mips.c:12853
+#, c-format
+msgid " [abi unknown]"
+msgstr " [ukendt abi]"
+
+#: elfxx-mips.c:12855
+#, c-format
+msgid " [abi=N32]"
+msgstr " [abi=N32]"
+
+#: elfxx-mips.c:12857
+#, c-format
+msgid " [abi=64]"
+msgstr " [abi=64]"
+
+#: elfxx-mips.c:12859
+#, c-format
+msgid " [no abi set]"
+msgstr " [intet abi sat]"
+
+#: elfxx-mips.c:12880
+#, c-format
+msgid " [unknown ISA]"
+msgstr " [ukendt ISA]"
+
+#: elfxx-mips.c:12891
+#, c-format
+msgid " [not 32bitmode]"
+msgstr " [ikke 32-bittilstand]"
+
+#: elfxx-sparc.c:595
+#, c-format
+msgid "invalid relocation type %d"
+msgstr "ugyldig relokeringstype %d"
+
+#: i386linux.c:454 m68klinux.c:458 sparclinux.c:452
+#, c-format
+msgid "Output file requires shared library `%s'\n"
+msgstr "Uddatafilen kræver delt bibliotek \"%s\"\n"
+
+#: i386linux.c:462 m68klinux.c:466 sparclinux.c:460
+#, c-format
+msgid "Output file requires shared library `%s.so.%s'\n"
+msgstr "Uddatafilen kræver delt bibliotek \"%s.so.%s\"\n"
+
+#: i386linux.c:651 i386linux.c:701 m68klinux.c:658 m68klinux.c:706
+#: sparclinux.c:650 sparclinux.c:700
+#, c-format
+msgid "Symbol %s not defined for fixups\n"
+msgstr "Symbol %s er ikke defineret for rettelser\n"
+
+#: i386linux.c:725 m68klinux.c:730 sparclinux.c:724
+msgid "Warning: fixup count mismatch\n"
+msgstr "Advarsel: antal rettelser stemmer ikke\n"
+
+#: ieee.c:159
+#, c-format
+msgid "%s: string too long (%d chars, max 65535)"
+msgstr "%s: strengen er for lang (%d tegn, max 65535)"
+
+#: ieee.c:286
+#, c-format
+msgid "%s: unrecognized symbol `%s' flags 0x%x"
+msgstr "%s: ukendt symbol \"%s\" flag 0x%x"
+
+#: ieee.c:792
+msgid "%B: unimplemented ATI record %u for symbol %u"
+msgstr "%B: ikke-implementeret ATI-post %u for symbol %u"
+
+#: ieee.c:816
+msgid "%B: unexpected ATN type %d in external part"
+msgstr "%B: uventet ATN-type %d i ekstern del"
+
+#: ieee.c:838
+msgid "%B: unexpected type after ATN"
+msgstr "%B: uventet type efter ATN"
+
+#: ihex.c:230
+msgid "%B:%d: unexpected character `%s' in Intel Hex file"
+msgstr "%B:%d: uventet tegn \"%s\" i heksadecimal Intel-fil"
+
+#: ihex.c:337
+msgid "%B:%u: bad checksum in Intel Hex file (expected %u, found %u)"
+msgstr "%B:%u: fejlagtig kontrolsum i heksadecimal Intel-fil (forventede %u, fandt %u)"
+
+#: ihex.c:392
+msgid "%B:%u: bad extended address record length in Intel Hex file"
+msgstr "%B:%u: fejlagtig længde på post for udvidet adresse i heksadecimal Intel-fil"
+
+#: ihex.c:409
+msgid "%B:%u: bad extended start address length in Intel Hex file"
+msgstr "%B:%u: fejlagtig længde på udvidet startadresse i heksadecimal Intel-fil"
+
+#: ihex.c:426
+msgid "%B:%u: bad extended linear address record length in Intel Hex file"
+msgstr "%B:%u: fejlagtig længde på post for udvidet lineær adresse i heksadecimal Intel-fil"
+
+#: ihex.c:443
+msgid "%B:%u: bad extended linear start address length in Intel Hex file"
+msgstr "%B:%u: fejlagtig længde på udvidet lineær startadresse i heksadecimal Intel-fil"
+
+#: ihex.c:460
+msgid "%B:%u: unrecognized ihex type %u in Intel Hex file"
+msgstr "%B:%u: ukendt ihex-type %u i heksadecimal Intel-fil"
+
+#: ihex.c:579
+msgid "%B: internal error in ihex_read_section"
+msgstr "%B: intern fejl i ihex_read_section"
+
+#: ihex.c:613
+msgid "%B: bad section length in ihex_read_section"
+msgstr "%B: fejlagtig sektionslængde i ihex_read_sektion"
+
+#: ihex.c:826
+#, c-format
+msgid "%s: address 0x%s out of range for Intel Hex file"
+msgstr "%s: adressen 0x%s er uden for intervallet for heksadecimal Intel-fil"
+
+#: libbfd.c:863
+msgid "%B: unable to get decompressed section %A"
+msgstr "%B: kan ikke hente dekomprimeret sektion %A"
+
+#: libbfd.c:1027
+#, c-format
+msgid "Deprecated %s called at %s line %d in %s\n"
+msgstr "Forældet %s kaldt ved %s linje %d i %s\n"
+
+#: libbfd.c:1030
+#, c-format
+msgid "Deprecated %s called\n"
+msgstr "Forældet %s kaldt\n"
+
+#: linker.c:1911
+msgid "%B: indirect symbol `%s' to `%s' is a loop"
+msgstr "%B: indirekte symbol \"%s\" til \"%s\" er en løkke"
+
+#: linker.c:2778
+#, c-format
+msgid "Attempt to do relocatable link with %s input and %s output"
+msgstr "Forsøg at lave en relokérbar lænke med %s-inddata og %s-uddata"
+
+#: linker.c:3105
+msgid "%B: warning: ignoring duplicate section `%A'\n"
+msgstr "%B: advarsel: ignorerer gentaget sektion \"%A\"\n"
+
+#: linker.c:3119
+msgid "%B: warning: duplicate section `%A' has different size\n"
+msgstr "%B: advarsel: gentaget sektion \"%A\" har forskellig længde\n"
+
+#: mach-o.c:3403
+msgid "Mach-O header:\n"
+msgstr "Mach-O-header:\n"
+
+# eller skal det være magisk tal?
+#: mach-o.c:3404
+#, c-format
+msgid " magic : %08lx\n"
+msgstr " magi : %08lx\n"
+
+#: mach-o.c:3405
+#, c-format
+msgid " cputype : %08lx (%s)\n"
+msgstr " cputype : %08lx (%s)\n"
+
+#: mach-o.c:3407
+#, c-format
+msgid " cpusubtype: %08lx\n"
+msgstr " cpusubtype: %08lx\n"
+
+#: mach-o.c:3408
+#, c-format
+msgid " filetype : %08lx (%s)\n"
+msgstr " filtype : %08lx (%s)\n"
+
+# ?
+#: mach-o.c:3411
+#, c-format
+msgid " ncmds : %08lx (%lu)\n"
+msgstr " nkmd'er : %08lx (%lu)\n"
+
+# kan ikke så godt gøre de her konsistente
+#: mach-o.c:3412
+#, c-format
+msgid " sizeofcmds: %08lx\n"
+msgstr " sizeofcmds: %08lx\n"
+
+#: mach-o.c:3413
+#, c-format
+msgid " flags : %08lx ("
+msgstr " flag : %08lx ("
+
+#: mach-o.c:3415 vms-alpha.c:7652
+msgid ")\n"
+msgstr ")\n"
+
+#: mach-o.c:3416
+#, c-format
+msgid " reserved : %08x\n"
+msgstr " reserveret: %08x\n"
+
+#: mach-o.c:3426
+msgid "Segments and Sections:\n"
+msgstr "Segmenter og sektioner:\n"
+
+#: mach-o.c:3427
+msgid " #: Segment name Section name Address\n"
+msgstr " #: Segmentnavn Sektionsnavn Adresse\n"
+
+#: merge.c:832
+#, c-format
+msgid "%s: access beyond end of merged section (%ld)"
+msgstr "%s: tilgang ud over slutningen på sammenflettet sektion (%ld)"
+
+#: mmo.c:456
+#, c-format
+msgid "%s: No core to allocate section name %s\n"
+msgstr "%s: Ingen kerne til at allokere sektionsnavn %s\n"
+
+#: mmo.c:531
+#, c-format
+msgid "%s: No core to allocate a symbol %d bytes long\n"
+msgstr "%s: Ingen kerne til at allokere et %d byte langt symbol\n"
+
+#: mmo.c:1187
+#, c-format
+msgid "%s: invalid mmo file: initialization value for $255 is not `Main'\n"
+msgstr "%s: ugyldig mmo-fil: initieringsværdi for $255 er ikke \"Main\"\n"
+
+#: mmo.c:1332
+#, c-format
+msgid "%s: unsupported wide character sequence 0x%02X 0x%02X after symbol name starting with `%s'\n"
+msgstr "%s: bred tegn-sekvens som ikke understøttes 0x%02X 0x%02X efter symbolnavnet som begynder med \"%s\"\n"
+
+#: mmo.c:1565
+#, c-format
+msgid "%s: invalid mmo file: unsupported lopcode `%d'\n"
+msgstr "%s: ugyldig mmo-fil: lopkode \"%d\" understøttes ikke\n"
+
+#: mmo.c:1575
+#, c-format
+msgid "%s: invalid mmo file: expected YZ = 1 got YZ = %d for lop_quote\n"
+msgstr "%s: ugyldig mmo-fil: forventede YZ = 1 fik YZ = %d for lop_quote\n"
+
+#: mmo.c:1611
+#, c-format
+msgid "%s: invalid mmo file: expected z = 1 or z = 2, got z = %d for lop_loc\n"
+msgstr "%s: ugyldig mmo-fil: forventede z = 1 eller z = 2, fik z = %d for lop_loc\n"
+
+#: mmo.c:1657
+#, c-format
+msgid "%s: invalid mmo file: expected z = 1 or z = 2, got z = %d for lop_fixo\n"
+msgstr "%s: ugyldig mmo-fil: forventede z = 1 eller z = 2, fik z = %d for lop_fixo\n"
+
+#: mmo.c:1696
+#, c-format
+msgid "%s: invalid mmo file: expected y = 0, got y = %d for lop_fixrx\n"
+msgstr "%s: ugyldig mmo-fil: forventede y = 0, fik y = %d for lop_fixrx\n"
+
+#: mmo.c:1705
+#, c-format
+msgid "%s: invalid mmo file: expected z = 16 or z = 24, got z = %d for lop_fixrx\n"
+msgstr "%s: ugyldig mmo-fil: forventede z = 16 eller z = 24, fik z = %d for lop_fixr\n"
+
+#: mmo.c:1728
+#, c-format
+msgid "%s: invalid mmo file: leading byte of operand word must be 0 or 1, got %d for lop_fixrx\n"
+msgstr "%s: ugyldig mmo-fil: indledende byte i operandord skal være 0 eller 1, fik %d for lop_fixrx\n"
+
+#: mmo.c:1751
+#, c-format
+msgid "%s: cannot allocate file name for file number %d, %d bytes\n"
+msgstr "%s: kan ikke allokere filnavn for fil nummer %d, %d byte\n"
+
+#: mmo.c:1771
+#, c-format
+msgid "%s: invalid mmo file: file number %d `%s', was already entered as `%s'\n"
+msgstr "%s: ugyldig mmo-fil: fil nummer %d \"%s\", var allerede angivet som \"%s\"\n"
+
+#: mmo.c:1784
+#, c-format
+msgid "%s: invalid mmo file: file name for number %d was not specified before use\n"
+msgstr "%s: ugyldig mmo-fil: filnavnet for nummer %d blev ikke angivet inden brug\n"
+
+#: mmo.c:1890
+#, c-format
+msgid "%s: invalid mmo file: fields y and z of lop_stab non-zero, y: %d, z: %d\n"
+msgstr "%s: ugyldig mmo-fil: felter y og z i lop_stab er ikke-tomme, y: %d, z: %d\n"
+
+#: mmo.c:1926
+#, c-format
+msgid "%s: invalid mmo file: lop_end not last item in file\n"
+msgstr "%s: ugyldig mmo-fil: lop_end er ikke sidste objekt i fil\n"
+
+#: mmo.c:1939
+#, c-format
+msgid "%s: invalid mmo file: YZ of lop_end (%ld) not equal to the number of tetras to the preceding lop_stab (%ld)\n"
+msgstr "%s: ugyldig mmo-fil: YZ i lop_end (%ld) er ikke lig med antal af tetraer til den foregående lop_stab (%ld)\n"
+
+#: mmo.c:2649
+#, c-format
+msgid "%s: invalid symbol table: duplicate symbol `%s'\n"
+msgstr "%s: ugyldig symboltabel: dubletsymbol \"%s\"\n"
+
+#: mmo.c:2889
+#, c-format
+msgid "%s: Bad symbol definition: `Main' set to %s rather than the start address %s\n"
+msgstr "%s: Fejlagtig symboldefinition: \"Main\" er sat til %s i stedet for startadressen %s\n"
+
+#: mmo.c:2981
+#, c-format
+msgid "%s: warning: symbol table too large for mmo, larger than 65535 32-bit words: %d. Only `Main' will be emitted.\n"
+msgstr "%s: advarsel: symboltabellen er for stor for mmo, større end 65535 32-bit ord: %d. Kun \"Main\" vil blive sendt.\n"
+
+#: mmo.c:3026
+#, c-format
+msgid "%s: internal error, symbol table changed size from %d to %d words\n"
+msgstr "%s: intern fejl, symboltabellen ændrede størrelse fra %d til %d ord\n"
+
+#: mmo.c:3078
+#, c-format
+msgid "%s: internal error, internal register section %s had contents\n"
+msgstr "%s: intern fejl, den interne registersektion %s havde indhold\n"
+
+#: mmo.c:3129
+#, c-format
+msgid "%s: no initialized registers; section length 0\n"
+msgstr "%s: ingen initierede registre; sektionslængde 0\n"
+
+#: mmo.c:3135
+#, c-format
+msgid "%s: too many initialized registers; section length %ld\n"
+msgstr "%s: for mange initierede registre; sektionslængde %ld\n"
+
+#: mmo.c:3140
+#, c-format
+msgid "%s: invalid start address for initialized registers of length %ld: 0x%lx%08lx\n"
+msgstr "%s: ugyldig startadresse for initierede registre med længden %ld: 0x%lx%08lx\n"
+
+#: oasys.c:882
+#, c-format
+msgid "%s: can not represent section `%s' in oasys"
+msgstr "%s: kan ikke repræsentere sektionen \"%s\" i oasys"
+
+#: osf-core.c:140
+#, c-format
+msgid "Unhandled OSF/1 core file section type %d\n"
+msgstr "Uhåndteret sektionstype %d for OSF/1-hukommelsesfil\n"
+
+#: pe-mips.c:607
+msgid "%B: `ld -r' not supported with PE MIPS objects\n"
+msgstr "%B: \"ld -r\" understøttes ikke med PE MIPS-objekter\n"
+
+#. OK, at this point the following variables are set up:
+#. src = VMA of the memory we're fixing up
+#. mem = pointer to memory we're fixing up
+#. val = VMA of what we need to refer to.
+#: pe-mips.c:719
+msgid "%B: unimplemented %s\n"
+msgstr "%B: uimplementeret %s\n"
+
+#: pe-mips.c:745
+msgid "%B: jump too far away\n"
+msgstr "%B: hop for langt bort\n"
+
+#: pe-mips.c:771
+msgid "%B: bad pair/reflo after refhi\n"
+msgstr "%B: fejlagtigt par/reflo efter refhi\n"
+
+#: pei-x86_64.c:444
+#, c-format
+msgid "warning: .pdata section size (%ld) is not a multiple of %d\n"
+msgstr "advarsel: størrelsen på .pdata-sektionen (%ld) er ikke et multiplum af %d\n"
+
+#: pei-x86_64.c:448 peigen.c:1618 peigen.c:1801 pepigen.c:1618 pepigen.c:1801
+#: pex64igen.c:1618 pex64igen.c:1801
+#, c-format
+msgid ""
+"\n"
+"The Function Table (interpreted .pdata section contents)\n"
+msgstr ""
+"\n"
+"Funktionstabellen (tolket indhold fra .pdata-sektionen)\n"
+
+#: pei-x86_64.c:450
+#, c-format
+msgid "vma:\t\t\tBeginAddress\t EndAddress\t UnwindData\n"
+msgstr "vma:\t\t\tStartadresse\t Slutadresse\t Tilbagespolingsdata\n"
+
+#. XXX code yet to be written.
+#: peicode.h:751
+msgid "%B: Unhandled import type; %x"
+msgstr "%B: Uhåndteret importtype; %x"
+
+#: peicode.h:756
+msgid "%B: Unrecognised import type; %x"
+msgstr "%B: Ukendt importtype; %x"
+
+#: peicode.h:770
+msgid "%B: Unrecognised import name type; %x"
+msgstr "%B: Ukendt importnavnstype; %x"
+
+#: peicode.h:1162
+msgid "%B: Unrecognised machine type (0x%x) in Import Library Format archive"
+msgstr "%B: Ukendt maskintype (0x%x) i Import Library Format-arkiv"
+
+#: peicode.h:1174
+msgid "%B: Recognised but unhandled machine type (0x%x) in Import Library Format archive"
+msgstr "%B: Genkendt men uhåndteret maskintype (0x%x) i Import Library Format-arkiv"
+
+#: peicode.h:1192
+msgid "%B: size field is zero in Import Library Format header"
+msgstr "%B: størrelsesfeltet er nul i Import Library Format-header"
+
+#: peicode.h:1223
+msgid "%B: string not null terminated in ILF object file."
+msgstr "%B: streng ikke nultermineret i ILF-objektfil."
+
+#: ppcboot.c:414
+#, c-format
+msgid ""
+"\n"
+"ppcboot header:\n"
+msgstr ""
+"\n"
+"ppcboot-hoved:\n"
+
+#: ppcboot.c:415
+#, c-format
+msgid "Entry offset = 0x%.8lx (%ld)\n"
+msgstr "Startafstand = 0x%.8lx (%ld)\n"
+
+#: ppcboot.c:417
+#, c-format
+msgid "Length = 0x%.8lx (%ld)\n"
+msgstr "Længde = 0x%.8lx (%ld)\n"
+
+#: ppcboot.c:421
+#, c-format
+msgid "Flag field = 0x%.2x\n"
+msgstr "Flagfelt = 0x%.2x\n"
+
+#: ppcboot.c:427
+#, c-format
+msgid "Partition name = \"%s\"\n"
+msgstr "Partitionsnavn = \"%s\"\n"
+
+#: ppcboot.c:446
+#, c-format
+msgid ""
+"\n"
+"Partition[%d] start = { 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x }\n"
+msgstr ""
+"\n"
+"Start på partition[%d] = { 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x }\n"
+
+#: ppcboot.c:452
+#, c-format
+msgid "Partition[%d] end = { 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x }\n"
+msgstr "Slut på partition[%d] = { 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x }\n"
+
+#: ppcboot.c:458
+#, c-format
+msgid "Partition[%d] sector = 0x%.8lx (%ld)\n"
+msgstr "Sektor for partition[%d] = 0x%.8lx (%ld)\n"
+
+#: ppcboot.c:460
+#, c-format
+msgid "Partition[%d] length = 0x%.8lx (%ld)\n"
+msgstr "Længde på partition[%d] = 0x%.8lx (%ld)\n"
+
+#: som.c:5471
+#, c-format
+msgid ""
+"\n"
+"Exec Auxiliary Header\n"
+msgstr ""
+"\n"
+"Ekstraheader til kørsel\n"
+
+#: som.c:5776
+msgid "som_sizeof_headers unimplemented"
+msgstr "som_sizeof_headers er ikke implementeret"
+
+#: srec.c:261
+msgid "%B:%d: Unexpected character `%s' in S-record file\n"
+msgstr "%B:%d: Uventet tegn \"%s\" i S-post-fil\n"
+
+#: srec.c:567 srec.c:600
+msgid "%B:%d: Bad checksum in S-record file\n"
+msgstr "%B:%d: DÃ¥rlig tjeksum i S-post-fil\n"
+
+# Hvad er stabs?
+#: stabs.c:279
+msgid "%B(%A+0x%lx): Stabs entry has invalid string index."
+msgstr "%B(%A+0x%lx): Stabs-post har ugyldigt strengindeks."
+
+#: syms.c:1079
+msgid "Unsupported .stab relocation"
+msgstr ".stab-relokering som ikke understøttes"
+
+#: vms-alpha.c:1287
+#, c-format
+msgid "Unknown EGSD subtype %d"
+msgstr "Ukendt EGSD-undertype %d"
+
+#: vms-alpha.c:1318
+#, c-format
+msgid "Stack overflow (%d) in _bfd_vms_push"
+msgstr "Stakken giver overløb (%d) i _bfd_vms_push"
+
+#: vms-alpha.c:1331
+msgid "Stack underflow in _bfd_vms_pop"
+msgstr "Stakken giver underløb i _bfd_vms_pop"
+
+#. These names have not yet been added to this switch statement.
+#: vms-alpha.c:1568
+#, c-format
+msgid "unknown ETIR command %d"
+msgstr "ukendt ETIR-kommando %d"
+
+#: vms-alpha.c:1755
+#, c-format
+msgid "bad section index in %s"
+msgstr "fejlagtigt sektionsindeks i %s"
+
+#: vms-alpha.c:1768
+#, c-format
+msgid "unsupported STA cmd %s"
+msgstr "STA-kommando %s understøttes ikke"
+
+#. Insert field.
+#. Unsigned shift.
+#. Rotate.
+#. Redefine symbol to current location.
+#. Define a literal.
+#: vms-alpha.c:1944 vms-alpha.c:1975 vms-alpha.c:2222
+#, c-format
+msgid "%s: not supported"
+msgstr "%s: understøttes ikke"
+
+#: vms-alpha.c:1950
+#, c-format
+msgid "%s: not implemented"
+msgstr "%s: ikke implementeret"
+
+#: vms-alpha.c:2206
+#, c-format
+msgid "invalid use of %s with contexts"
+msgstr "ugyldig brug af %s med kontekster"
+
+#: vms-alpha.c:2240
+#, c-format
+msgid "reserved cmd %d"
+msgstr "reserveret kommando %d"
+
+#: vms-alpha.c:2325
+msgid "Object module NOT error-free !\n"
+msgstr "Objektmodulet IKKE fejlfri!\n"
+
+#: vms-alpha.c:2754
+#, c-format
+msgid "Symbol %s replaced by %s\n"
+msgstr "Symbol %s erstattet med %s\n"
+
+#: vms-alpha.c:3757
+#, c-format
+msgid "SEC_RELOC with no relocs in section %s"
+msgstr "SEC_RELOC uden relokeringer i sektion %s"
+
+#: vms-alpha.c:3810 vms-alpha.c:4041
+#, c-format
+msgid "Size error in section %s"
+msgstr "Størrelsesfejl i sektion %s"
+
+#: vms-alpha.c:3980
+msgid "Spurious ALPHA_R_BSR reloc"
+msgstr "Uægte ALPHA_R_BSD-relokering"
+
+#: vms-alpha.c:4028
+#, c-format
+msgid "Unhandled relocation %s"
+msgstr "Uhåndteret relokering %s"
+
+#: vms-alpha.c:4318
+#, c-format
+msgid "unknown source command %d"
+msgstr "ukendt kildekommando %d"
+
+#: vms-alpha.c:4379
+msgid "DST__K_SET_LINUM_INCR not implemented"
+msgstr "DST__K_SET_LINUM_INCR er ikke implementeret"
+
+#: vms-alpha.c:4385
+msgid "DST__K_SET_LINUM_INCR_W not implemented"
+msgstr "DST__K_SET_LINUM_INCR_W er ikke implementeret"
+
+#: vms-alpha.c:4391
+msgid "DST__K_RESET_LINUM_INCR not implemented"
+msgstr "DST__K_RESET_LINUM_INCR ikke implementeret"
+
+#: vms-alpha.c:4397
+msgid "DST__K_BEG_STMT_MODE not implemented"
+msgstr "DST__K_BEG_STMT_MODE er ikke implementeret"
+
+#: vms-alpha.c:4403
+msgid "DST__K_END_STMT_MODE not implemented"
+msgstr "DST__K_END_STMT_MODE er ikke implementeret"
+
+#: vms-alpha.c:4430
+msgid "DST__K_SET_PC not implemented"
+msgstr "DST__K_SET_PC er ikke implementeret"
+
+#: vms-alpha.c:4436
+msgid "DST__K_SET_PC_W not implemented"
+msgstr "DST__K_SET_PC_W er ikke implementeret"
+
+#: vms-alpha.c:4442
+msgid "DST__K_SET_PC_L not implemented"
+msgstr "DST__K_SET_PC_L er ikke implementeret"
+
+#: vms-alpha.c:4448
+msgid "DST__K_SET_STMTNUM not implemented"
+msgstr "DST__K_SET_STMTNUM er ikke implementeret"
+
+#: vms-alpha.c:4491
+#, c-format
+msgid "unknown line command %d"
+msgstr "ukendt linjekommando %d"
+
+#: vms-alpha.c:4938 vms-alpha.c:4955 vms-alpha.c:4969 vms-alpha.c:4984
+#: vms-alpha.c:4996 vms-alpha.c:5007 vms-alpha.c:5019
+#, c-format
+msgid "Unknown reloc %s + %s"
+msgstr "Ukendt relokering %s + %s"
+
+#: vms-alpha.c:5074
+#, c-format
+msgid "Unknown reloc %s"
+msgstr "Ukendt relokering %s"
+
+#: vms-alpha.c:5087
+msgid "Invalid section index in ETIR"
+msgstr "Fejlagtigt sektionsindeks i ETIR"
+
+#: vms-alpha.c:5134
+#, c-format
+msgid "Unknown symbol in command %s"
+msgstr "Ugyldigt symbol i kommando %s"
+
+#: vms-alpha.c:5649
+#, c-format
+msgid " EMH %u (len=%u): "
+msgstr " EMH %u (længde=%u): "
+
+#: vms-alpha.c:5658
+#, c-format
+msgid "Module header\n"
+msgstr "Modulheader\n"
+
+#: vms-alpha.c:5659
+#, c-format
+msgid " structure level: %u\n"
+msgstr " strukturniveau : %u\n"
+
+#: vms-alpha.c:5660
+#, c-format
+msgid " max record size: %u\n"
+msgstr " maks post-str: %u\n"
+
+#: vms-alpha.c:5663
+#, c-format
+msgid " module name : %.*s\n"
+msgstr " modulnavn : %.*s\n"
+
+#: vms-alpha.c:5665
+#, c-format
+msgid " module version : %.*s\n"
+msgstr " modulversion : %.*s\n"
+
+#: vms-alpha.c:5667
+#, c-format
+msgid " compile date : %.17s\n"
+msgstr " kompileringsdag: %.17s\n"
+
+#: vms-alpha.c:5672
+#, c-format
+msgid "Language Processor Name\n"
+msgstr "Navn på sprogprocessor\n"
+
+#: vms-alpha.c:5673
+#, c-format
+msgid " language name: %.*s\n"
+msgstr " sprognavn: %.*s\n"
+
+#: vms-alpha.c:5680
+#, c-format
+msgid "Source Files Header\n"
+msgstr "Kildefilheader\n"
+
+#: vms-alpha.c:5681
+#, c-format
+msgid " file: %.*s\n"
+msgstr " fil: %.*s\n"
+
+#: vms-alpha.c:5688
+#, c-format
+msgid "Title Text Header\n"
+msgstr "Titeltekstheader\n"
+
+#: vms-alpha.c:5689
+#, c-format
+msgid " title: %.*s\n"
+msgstr " titel: %.*s\n"
+
+#: vms-alpha.c:5696
+#, c-format
+msgid "Copyright Header\n"
+msgstr "Ophavsretsheader\n"
+
+#: vms-alpha.c:5697
+#, c-format
+msgid " copyright: %.*s\n"
+msgstr " ophavsret: %.*s\n"
+
+#: vms-alpha.c:5703
+#, c-format
+msgid "unhandled emh subtype %u\n"
+msgstr "uhåndteret emh-undertype %u\n"
+
+#: vms-alpha.c:5713
+#, c-format
+msgid " EEOM (len=%u):\n"
+msgstr " EEOM (længde=%u):\n"
+
+#: vms-alpha.c:5714
+#, c-format
+msgid " number of cond linkage pairs: %u\n"
+msgstr " antal cond-lænkningspar: %u\n"
+
+#: vms-alpha.c:5716
+#, c-format
+msgid " completion code: %u\n"
+msgstr " fuldførelseskode: %u\n"
+
+#: vms-alpha.c:5720
+#, c-format
+msgid " transfer addr flags: 0x%02x\n"
+msgstr " overførselsadresseflag: 0x%02x\n"
+
+#: vms-alpha.c:5721
+#, c-format
+msgid " transfer addr psect: %u\n"
+msgstr " overførselsadresse-psect: %u\n"
+
+#: vms-alpha.c:5723
+#, c-format
+msgid " transfer address : 0x%08x\n"
+msgstr " overførselsadresse : 0x%08x\n"
+
+#: vms-alpha.c:5732
+msgid " WEAK"
+msgstr " WEAK"
+
+#: vms-alpha.c:5734
+msgid " DEF"
+msgstr " DEF"
+
+#: vms-alpha.c:5736
+msgid " UNI"
+msgstr " UNI"
+
+#: vms-alpha.c:5738 vms-alpha.c:5759
+msgid " REL"
+msgstr " REL"
+
+#: vms-alpha.c:5740
+msgid " COMM"
+msgstr " COMM"
+
+#: vms-alpha.c:5742
+msgid " VECEP"
+msgstr " VECEP"
+
+#: vms-alpha.c:5744
+msgid " NORM"
+msgstr " NORM"
+
+#: vms-alpha.c:5746
+msgid " QVAL"
+msgstr " QVAL"
+
+#: vms-alpha.c:5753
+msgid " PIC"
+msgstr " PIC"
+
+#: vms-alpha.c:5755
+msgid " LIB"
+msgstr " LIB"
+
+#: vms-alpha.c:5757
+msgid " OVR"
+msgstr " OVR"
+
+#: vms-alpha.c:5761
+msgid " GBL"
+msgstr " GBL"
+
+#: vms-alpha.c:5763
+msgid " SHR"
+msgstr " SHR"
+
+#: vms-alpha.c:5765
+msgid " EXE"
+msgstr " EXE"
+
+#: vms-alpha.c:5767
+msgid " RD"
+msgstr " RD"
+
+#: vms-alpha.c:5769
+msgid " WRT"
+msgstr " WRT"
+
+#: vms-alpha.c:5771
+msgid " VEC"
+msgstr " VEC"
+
+#: vms-alpha.c:5773
+msgid " NOMOD"
+msgstr " NOMOD"
+
+#: vms-alpha.c:5775
+msgid " COM"
+msgstr " COM"
+
+#: vms-alpha.c:5777
+msgid " 64B"
+msgstr " 64B"
+
+#: vms-alpha.c:5786
+#, c-format
+msgid " EGSD (len=%u):\n"
+msgstr " EGSD (længde=%u):\n"
+
+#: vms-alpha.c:5798
+#, c-format
+msgid " EGSD entry %2u (type: %u, len: %u): "
+msgstr " EGSD-post %2u (type: %u, længde: %u): "
+
+#: vms-alpha.c:5810
+#, c-format
+msgid "PSC - Program section definition\n"
+msgstr "PSC - Programsektionsdefinition\n"
+
+#: vms-alpha.c:5811 vms-alpha.c:5828
+#, c-format
+msgid " alignment : 2**%u\n"
+msgstr " justering : 2**%u\n"
+
+#: vms-alpha.c:5812 vms-alpha.c:5829
+#, c-format
+msgid " flags : 0x%04x"
+msgstr " flag : 0x%04x"
+
+#: vms-alpha.c:5816
+#, c-format
+msgid " alloc (len): %u (0x%08x)\n"
+msgstr " allok (lgd): %u (0x%08x)\n"
+
+#: vms-alpha.c:5817 vms-alpha.c:5874 vms-alpha.c:5923
+#, c-format
+msgid " name : %.*s\n"
+msgstr " navn : %.*s\n"
+
+#: vms-alpha.c:5827
+#, c-format
+msgid "SPSC - Shared Image Program section def\n"
+msgstr "SPSC - Shared Image Program-sektionsdefinition\n"
+
+#: vms-alpha.c:5833
+#, c-format
+msgid " alloc (len) : %u (0x%08x)\n"
+msgstr " allok (længde): %u (0x%08x)\n"
+
+#: vms-alpha.c:5834
+#, c-format
+msgid " image offset : 0x%08x\n"
+msgstr " image-afsæt : 0x%08x\n"
+
+#: vms-alpha.c:5836
+#, c-format
+msgid " symvec offset : 0x%08x\n"
+msgstr " symvec-afsæt : 0x%08x\n"
+
+#: vms-alpha.c:5838
+#, c-format
+msgid " name : %.*s\n"
+msgstr " navn : %.*s\n"
+
+#: vms-alpha.c:5851
+#, c-format
+msgid "SYM - Global symbol definition\n"
+msgstr "SYM - Global symboldefinition\n"
+
+#: vms-alpha.c:5852 vms-alpha.c:5912 vms-alpha.c:5933 vms-alpha.c:5952
+#, c-format
+msgid " flags: 0x%04x"
+msgstr " flag : 0x%04x"
+
+#: vms-alpha.c:5855
+#, c-format
+msgid " psect offset: 0x%08x\n"
+msgstr " psect-afsæt : 0x%08x\n"
+
+#: vms-alpha.c:5859
+#, c-format
+msgid " code address: 0x%08x\n"
+msgstr " kodeadresse : 0x%08x\n"
+
+#: vms-alpha.c:5861
+#, c-format
+msgid " psect index for entry point : %u\n"
+msgstr " psect-indeks for indgangspunkt : %u\n"
+
+#: vms-alpha.c:5864 vms-alpha.c:5940 vms-alpha.c:5959
+#, c-format
+msgid " psect index : %u\n"
+msgstr " psect-indeks : %u\n"
+
+#: vms-alpha.c:5866 vms-alpha.c:5942 vms-alpha.c:5961
+#, c-format
+msgid " name : %.*s\n"
+msgstr " navn : %.*s\n"
+
+#: vms-alpha.c:5873
+#, c-format
+msgid "SYM - Global symbol reference\n"
+msgstr "SYM - Global symbolreference\n"
+
+#: vms-alpha.c:5885
+#, c-format
+msgid "IDC - Ident Consistency check\n"
+msgstr "IDC - identitetskonsistenstjek\n"
+
+#: vms-alpha.c:5886
+#, c-format
+msgid " flags : 0x%08x"
+msgstr " flag : 0x%08x"
+
+#: vms-alpha.c:5890
+#, c-format
+msgid " id match : %x\n"
+msgstr " id-match : %x\n"
+
+#: vms-alpha.c:5892
+#, c-format
+msgid " error severity: %x\n"
+msgstr " fejlalvorlighed: %x\n"
+
+#: vms-alpha.c:5895
+#, c-format
+msgid " entity name : %.*s\n"
+msgstr " entitetsnavn : %.*s\n"
+
+#: vms-alpha.c:5897
+#, c-format
+msgid " object name : %.*s\n"
+msgstr " objektnavn : %.*s\n"
+
+#: vms-alpha.c:5900
+#, c-format
+msgid " binary ident : 0x%08x\n"
+msgstr " binær id : 0x%08x\n"
+
+#: vms-alpha.c:5903
+#, c-format
+msgid " ascii ident : %.*s\n"
+msgstr " ascii-id : %.*s\n"
+
+#: vms-alpha.c:5911
+#, c-format
+msgid "SYMG - Universal symbol definition\n"
+msgstr "SYMG - Universel symboldefinition\n"
+
+#: vms-alpha.c:5915
+#, c-format
+msgid " symbol vector offset: 0x%08x\n"
+msgstr " symbolvektorafsæt : 0x%08x\n"
+
+#: vms-alpha.c:5917
+#, c-format
+msgid " entry point: 0x%08x\n"
+msgstr " indgangspunkt: 0x%08x\n"
+
+#: vms-alpha.c:5919
+#, c-format
+msgid " proc descr : 0x%08x\n"
+msgstr " proc-beskr : 0x%08x\n"
+
+#: vms-alpha.c:5921
+#, c-format
+msgid " psect index: %u\n"
+msgstr " psect-indeks: %u\n"
+
+#: vms-alpha.c:5932
+#, c-format
+msgid "SYMV - Vectored symbol definition\n"
+msgstr "SYMV - vektoriseret symboldefinition\n"
+
+#: vms-alpha.c:5936
+#, c-format
+msgid " vector : 0x%08x\n"
+msgstr " vektor : 0x%08x\n"
+
+#: vms-alpha.c:5938 vms-alpha.c:5957
+#, c-format
+msgid " psect offset: %u\n"
+msgstr " psect-afsæt : %u\n"
+
+#: vms-alpha.c:5951
+#, c-format
+msgid "SYMM - Global symbol definition with version\n"
+msgstr "SYMM - Global symboldefinition med version\n"
+
+#: vms-alpha.c:5955
+#, c-format
+msgid " version mask: 0x%08x\n"
+msgstr " versionsmaske: 0x%08x\n"
+
+#: vms-alpha.c:5966
+#, c-format
+msgid "unhandled egsd entry type %u\n"
+msgstr "uhåndteret egsd-post-type %u\n"
+
+#: vms-alpha.c:6000
+#, c-format
+msgid " linkage index: %u, replacement insn: 0x%08x\n"
+msgstr " lænkningsindeks: %u, erstatnings-insn: 0x%08x\n"
+
+#: vms-alpha.c:6003
+#, c-format
+msgid " psect idx 1: %u, offset 1: 0x%08x %08x\n"
+msgstr " psect-idx 1: %u, afsæt 1: 0x%08x %08x\n"
+
+#: vms-alpha.c:6007
+#, c-format
+msgid " psect idx 2: %u, offset 2: 0x%08x %08x\n"
+msgstr " psect-idx 2: %u, afsæt 2: 0x%08x %08x\n"
+
+#: vms-alpha.c:6012
+#, c-format
+msgid " psect idx 3: %u, offset 3: 0x%08x %08x\n"
+msgstr " psect-idx 3: %u, afsæt 3: 0x%08x %08x\n"
+
+#: vms-alpha.c:6017
+#, c-format
+msgid " global name: %.*s\n"
+msgstr " globalt navn: %.*s\n"
+
+#: vms-alpha.c:6027
+#, c-format
+msgid " %s (len=%u+%u):\n"
+msgstr " %s (længde=%u+%u):\n"
+
+#: vms-alpha.c:6042
+#, c-format
+msgid " (type: %3u, size: 4+%3u): "
+msgstr " (type: %3u, størrelse: 4+%3u): "
+
+#: vms-alpha.c:6046
+#, c-format
+msgid "STA_GBL (stack global) %.*s\n"
+msgstr "STA_GBL (stak-global) %.*s\n"
+
+#: vms-alpha.c:6050
+#, c-format
+msgid "STA_LW (stack longword) 0x%08x\n"
+msgstr "STA_LW (stak-longword) 0x%08x\n"
+
+#: vms-alpha.c:6054
+#, c-format
+msgid "STA_QW (stack quadword) 0x%08x %08x\n"
+msgstr "STA_QW (stak-quadword) 0x%08x %08x\n"
+
+#: vms-alpha.c:6059
+#, c-format
+msgid "STA_PQ (stack psect base + offset)\n"
+msgstr "STA_PQ (stak-psect base + afsæt)\n"
+
+#: vms-alpha.c:6060
+#, c-format
+msgid " psect: %u, offset: 0x%08x %08x\n"
+msgstr " psect: %u, afsæt: 0x%08x %08x\n"
+
+#: vms-alpha.c:6066
+#, c-format
+msgid "STA_LI (stack literal)\n"
+msgstr "STA_LI (stak-literal)\n"
+
+#: vms-alpha.c:6069
+#, c-format
+msgid "STA_MOD (stack module)\n"
+msgstr "STA_MOD (stakmodul)\n"
+
+#: vms-alpha.c:6072
+#, c-format
+msgid "STA_CKARG (compare procedure argument)\n"
+msgstr "STA_CKARG (argument til sammenligningsprocedure)\n"
+
+#: vms-alpha.c:6076
+#, c-format
+msgid "STO_B (store byte)\n"
+msgstr "STO_B (gem byte)\n"
+
+#: vms-alpha.c:6079
+#, c-format
+msgid "STO_W (store word)\n"
+msgstr "STO_W (gem word)\n"
+
+#: vms-alpha.c:6082
+#, c-format
+msgid "STO_LW (store longword)\n"
+msgstr "STO_LW (gem longword)\n"
+
+#: vms-alpha.c:6085
+#, c-format
+msgid "STO_QW (store quadword)\n"
+msgstr "STO_QW (gem quadword)\n"
+
+#: vms-alpha.c:6091
+#, c-format
+msgid "STO_IMMR (store immediate repeat) %u bytes\n"
+msgstr "STO_IMMR (gem omgående gentagelse) %u byte\n"
+
+#: vms-alpha.c:6098
+#, c-format
+msgid "STO_GBL (store global) %.*s\n"
+msgstr "STO_GBL (gem global) %.*s\n"
+
+#: vms-alpha.c:6102
+#, c-format
+msgid "STO_CA (store code address) %.*s\n"
+msgstr "STO_CA (gem kodeadresse) %.*s\n"
+
+#: vms-alpha.c:6106
+#, c-format
+msgid "STO_RB (store relative branch)\n"
+msgstr "STO_RB (gem relativ gren)\n"
+
+#: vms-alpha.c:6109
+#, c-format
+msgid "STO_AB (store absolute branch)\n"
+msgstr "STO_AB (gem absolut gren)\n"
+
+#: vms-alpha.c:6112
+#, c-format
+msgid "STO_OFF (store offset to psect)\n"
+msgstr "STO_OFF (gem afsæt til psect)\n"
+
+#: vms-alpha.c:6118
+#, c-format
+msgid "STO_IMM (store immediate) %u bytes\n"
+msgstr "STO_IMM (gem omgående) %u byte\n"
+
+#: vms-alpha.c:6125
+#, c-format
+msgid "STO_GBL_LW (store global longword) %.*s\n"
+msgstr "STO_GBL_LW (gem globalt longword) %.*s\n"
+
+#: vms-alpha.c:6129
+#, c-format
+msgid "STO_OFF (store LP with procedure signature)\n"
+msgstr "STO_OFF (gem LP med proceduresignatur)\n"
+
+#: vms-alpha.c:6132
+#, c-format
+msgid "STO_BR_GBL (store branch global) *todo*\n"
+msgstr "STO_BR_GBL (gem gren globalt) *todo*\n"
+
+#: vms-alpha.c:6135
+#, c-format
+msgid "STO_BR_PS (store branch psect + offset) *todo*\n"
+msgstr "STO_BR_PS (gem gren-psect + afsæt) *todo*\n"
+
+#: vms-alpha.c:6139
+#, c-format
+msgid "OPR_NOP (no-operation)\n"
+msgstr "OPR_NOP (ingen operation)\n"
+
+#: vms-alpha.c:6142
+#, c-format
+msgid "OPR_ADD (add)\n"
+msgstr "OPR_ADD (læg sammen)\n"
+
+#: vms-alpha.c:6145
+#, c-format
+msgid "OPR_SUB (substract)\n"
+msgstr "OPR_SUB (træk fra)\n"
+
+#: vms-alpha.c:6148
+#, c-format
+msgid "OPR_MUL (multiply)\n"
+msgstr "OPR_MUL (multiplicér)\n"
+
+#: vms-alpha.c:6151
+#, c-format
+msgid "OPR_DIV (divide)\n"
+msgstr "OPR_DIV (dividér)\n"
+
+#: vms-alpha.c:6154
+#, c-format
+msgid "OPR_AND (logical and)\n"
+msgstr "OPR_AND (logisk og)\n"
+
+#: vms-alpha.c:6157
+#, c-format
+msgid "OPR_IOR (logical inclusive or)\n"
+msgstr "OPR_IOR (logisk inklusiv eller)\n"
+
+#: vms-alpha.c:6160
+#, c-format
+msgid "OPR_EOR (logical exclusive or)\n"
+msgstr "OPR_EOR (logisk eksklusiv eller)\n"
+
+#: vms-alpha.c:6163
+#, c-format
+msgid "OPR_NEG (negate)\n"
+msgstr "OPR_NEG (negation)\n"
+
+#: vms-alpha.c:6166
+#, c-format
+msgid "OPR_COM (complement)\n"
+msgstr "OPR_COM (komplement)\n"
+
+#: vms-alpha.c:6169
+#, c-format
+msgid "OPR_INSV (insert field)\n"
+msgstr "OPR_INSV (indsæt felt)\n"
+
+#: vms-alpha.c:6172
+#, c-format
+msgid "OPR_ASH (arithmetic shift)\n"
+msgstr "OPR_ASH (aritmetisk skift)\n"
+
+#: vms-alpha.c:6175
+#, c-format
+msgid "OPR_USH (unsigned shift)\n"
+msgstr "OPR_USH (skift uden fortegn)\n"
+
+#: vms-alpha.c:6178
+#, c-format
+msgid "OPR_ROT (rotate)\n"
+msgstr "OPR_ROT (rotér)\n"
+
+#: vms-alpha.c:6181
+#, c-format
+msgid "OPR_SEL (select)\n"
+msgstr "OPR_SEL (vælg)\n"
+
+#: vms-alpha.c:6184
+#, c-format
+msgid "OPR_REDEF (redefine symbol to curr location)\n"
+msgstr "OPR_REDEF (omdefinér symbol til nuværende placering)\n"
+
+#: vms-alpha.c:6187
+#, c-format
+msgid "OPR_REDEF (define a literal)\n"
+msgstr "OPR_REDEF (definér en literal)\n"
+
+#: vms-alpha.c:6191
+#, c-format
+msgid "STC_LP (store cond linkage pair)\n"
+msgstr "STC_LP (gem cond-lænkningspar)\n"
+
+#: vms-alpha.c:6195
+#, c-format
+msgid "STC_LP_PSB (store cond linkage pair + signature)\n"
+msgstr "STC_LP_PSB (gem cond-lænkningspar + signatur)\n"
+
+#: vms-alpha.c:6196
+#, c-format
+msgid " linkage index: %u, procedure: %.*s\n"
+msgstr " lænkningsindeks: %u, procedure: %.*s\n"
+
+#: vms-alpha.c:6199
+#, c-format
+msgid " signature: %.*s\n"
+msgstr " signatur: %.*s\n"
+
+#: vms-alpha.c:6202
+#, c-format
+msgid "STC_GBL (store cond global)\n"
+msgstr "STC_GBL (gem cond globalt)\n"
+
+#: vms-alpha.c:6203
+#, c-format
+msgid " linkage index: %u, global: %.*s\n"
+msgstr " lænkningsindeks: %u, global: %.*s\n"
+
+#: vms-alpha.c:6207
+#, c-format
+msgid "STC_GCA (store cond code address)\n"
+msgstr "STC_GCA (gem cond-kodeadresse)\n"
+
+#: vms-alpha.c:6208
+#, c-format
+msgid " linkage index: %u, procedure name: %.*s\n"
+msgstr " lænkningsindeks: %u, procedurenavn: %.*s\n"
+
+#: vms-alpha.c:6212
+#, c-format
+msgid "STC_PS (store cond psect + offset)\n"
+msgstr "STC_PS (gem cond-psect + afsæt)\n"
+
+#: vms-alpha.c:6214
+#, c-format
+msgid " linkage index: %u, psect: %u, offset: 0x%08x %08x\n"
+msgstr " lænkningsindeks: %u, psect: %u, afsæt: 0x%08x %08x\n"
+
+#: vms-alpha.c:6221
+#, c-format
+msgid "STC_NOP_GBL (store cond NOP at global addr)\n"
+msgstr "STC_NOP_GBL (gem cond NOP på global adresse)\n"
+
+#: vms-alpha.c:6225
+#, c-format
+msgid "STC_NOP_PS (store cond NOP at psect + offset)\n"
+msgstr "STC_NOP_PS (gem cond NOP på psect + afsæt)\n"
+
+#: vms-alpha.c:6229
+#, c-format
+msgid "STC_BSR_GBL (store cond BSR at global addr)\n"
+msgstr "STC_BSR_GBL (gem cond BSR på global adresse)\n"
+
+#: vms-alpha.c:6233
+#, c-format
+msgid "STC_BSR_PS (store cond BSR at psect + offset)\n"
+msgstr "STC_BSR_PS (gem cond BSR på psect + afsæt)\n"
+
+#: vms-alpha.c:6237
+#, c-format
+msgid "STC_LDA_GBL (store cond LDA at global addr)\n"
+msgstr "STC_LDA_GBL (gem cond LDA på global adresse)\n"
+
+#: vms-alpha.c:6241
+#, c-format
+msgid "STC_LDA_PS (store cond LDA at psect + offset)\n"
+msgstr "STC_LDA_PS (gem cond LDA på psect + afsæt)\n"
+
+#: vms-alpha.c:6245
+#, c-format
+msgid "STC_BOH_GBL (store cond BOH at global addr)\n"
+msgstr "STC_BOH_GBL (gem cond BOH på global adresse)\n"
+
+#: vms-alpha.c:6249
+#, c-format
+msgid "STC_BOH_PS (store cond BOH at psect + offset)\n"
+msgstr "STC_BOH_PS (gem cond BOH på psect + afsæt)\n"
+
+#: vms-alpha.c:6254
+#, c-format
+msgid "STC_NBH_GBL (store cond or hint at global addr)\n"
+msgstr "STC_NBH_GBL (gem cond eller hint på global adresse)\n"
+
+#: vms-alpha.c:6258
+#, c-format
+msgid "STC_NBH_PS (store cond or hint at psect + offset)\n"
+msgstr "STC_NBH_PS (gem cond eller hint på psect + afsæt)\n"
+
+#: vms-alpha.c:6262
+#, c-format
+msgid "CTL_SETRB (set relocation base)\n"
+msgstr "CTL_SETRB (sæt relokeringsbase)\n"
+
+#: vms-alpha.c:6268
+#, c-format
+msgid "CTL_AUGRB (augment relocation base) %u\n"
+msgstr "CTL_AUGRB (sammensæt (augment) relokeringsbase) %u\n"
+
+#: vms-alpha.c:6272
+#, c-format
+msgid "CTL_DFLOC (define location)\n"
+msgstr "CTL_DFLOC (defineŕ placering)\n"
+
+#: vms-alpha.c:6275
+#, c-format
+msgid "CTL_STLOC (set location)\n"
+msgstr "CTL_STLOC (indstil placering)\n"
+
+#: vms-alpha.c:6278
+#, c-format
+msgid "CTL_STKDL (stack defined location)\n"
+msgstr "CTL_STKDL (stakdefineret placering)\n"
+
+#: vms-alpha.c:6281 vms-alpha.c:6695
+#, c-format
+msgid "*unhandled*\n"
+msgstr "*uhåndteret*\n"
+
+#: vms-alpha.c:6311 vms-alpha.c:6350
+#, c-format
+msgid "cannot read GST record length\n"
+msgstr "kan ikke læse GST-post-længde\n"
+
+#. Ill-formed.
+#: vms-alpha.c:6332
+#, c-format
+msgid "cannot find EMH in first GST record\n"
+msgstr "kan ikke finde EMH i første GST-post\n"
+
+#: vms-alpha.c:6358
+#, c-format
+msgid "cannot read GST record header\n"
+msgstr "kan ikke læse GST-post-header\n"
+
+#: vms-alpha.c:6371
+#, c-format
+msgid " corrupted GST\n"
+msgstr " beskadiget GST\n"
+
+#: vms-alpha.c:6379
+#, c-format
+msgid "cannot read GST record\n"
+msgstr "kan ikke læse GST-post\n"
+
+#: vms-alpha.c:6408
+#, c-format
+msgid " unhandled EOBJ record type %u\n"
+msgstr " uhåndteret EOBJ-post-type %u\n"
+
+#: vms-alpha.c:6431
+#, c-format
+msgid " bitcount: %u, base addr: 0x%08x\n"
+msgstr " antal bit: %u, basisadresse: 0x%08x\n"
+
+#: vms-alpha.c:6444
+#, c-format
+msgid " bitmap: 0x%08x (count: %u):\n"
+msgstr " bitmap: 0x%08x (antal: %u):\n"
+
+#: vms-alpha.c:6451
+#, c-format
+msgid " %08x"
+msgstr " %08x"
+
+#: vms-alpha.c:6476
+#, c-format
+msgid " image %u (%u entries)\n"
+msgstr " aftryk %u (%u elementer)\n"
+
+#: vms-alpha.c:6481
+#, c-format
+msgid " offset: 0x%08x, val: 0x%08x\n"
+msgstr " afsæt: 0x%08x, værdi: 0x%08x\n"
+
+#: vms-alpha.c:6502
+#, c-format
+msgid " image %u (%u entries), offsets:\n"
+msgstr " aftryk %u (%u elementer), afsæt:\n"
+
+#: vms-alpha.c:6509
+#, c-format
+msgid " 0x%08x"
+msgstr " 0x%08x"
+
+#. 64 bits.
+#: vms-alpha.c:6631
+#, c-format
+msgid "64 bits *unhandled*\n"
+msgstr "64 bit *uhåndteret*\n"
+
+#: vms-alpha.c:6635
+#, c-format
+msgid "class: %u, dtype: %u, length: %u, pointer: 0x%08x\n"
+msgstr "klasse: %u, dtype: %u, længde: %u, pointer: 0x%08x\n"
+
+#: vms-alpha.c:6646
+#, c-format
+msgid "non-contiguous array of %s\n"
+msgstr "usammenhængende array af %s\n"
+
+#: vms-alpha.c:6650
+#, c-format
+msgid "dimct: %u, aflags: 0x%02x, digits: %u, scale: %u\n"
+msgstr "dimct: %u, aflags: 0x%02x, cifre: %u, skala: %u\n"
+
+#: vms-alpha.c:6654
+#, c-format
+msgid "arsize: %u, a0: 0x%08x\n"
+msgstr "arsize: %u, a0: 0x%08x\n"
+
+#: vms-alpha.c:6658
+#, c-format
+msgid "Strides:\n"
+msgstr "Trinstørrelser:\n"
+
+#: vms-alpha.c:6663
+#, c-format
+msgid "[%u]: %u\n"
+msgstr "[%u]: %u\n"
+
+#: vms-alpha.c:6668
+#, c-format
+msgid "Bounds:\n"
+msgstr "Grænser:\n"
+
+#: vms-alpha.c:6673
+#, c-format
+msgid "[%u]: Lower: %u, upper: %u\n"
+msgstr "[%u]: Nedre: %u, øvre: %u\n"
+
+#: vms-alpha.c:6685
+#, c-format
+msgid "unaligned bit-string of %s\n"
+msgstr "ujusteret bit-streng af %s\n"
+
+#: vms-alpha.c:6689
+#, c-format
+msgid "base: %u, pos: %u\n"
+msgstr "base: %u, pos: %u\n"
+
+#: vms-alpha.c:6709
+#, c-format
+msgid "vflags: 0x%02x, value: 0x%08x "
+msgstr "vflags: 0x%02x, værdi: 0x%08x "
+
+#: vms-alpha.c:6715
+#, c-format
+msgid "(no value)\n"
+msgstr "(ingen værdi)\n"
+
+#: vms-alpha.c:6718
+#, c-format
+msgid "(not active)\n"
+msgstr "(ikke aktiv)\n"
+
+#: vms-alpha.c:6721
+#, c-format
+msgid "(not allocated)\n"
+msgstr "(ikke tildelt)\n"
+
+#: vms-alpha.c:6724
+#, c-format
+msgid "(descriptor)\n"
+msgstr "(deskriptor)\n"
+
+#: vms-alpha.c:6728
+#, c-format
+msgid "(trailing value)\n"
+msgstr "(afsluttende værdi)\n"
+
+#: vms-alpha.c:6731
+#, c-format
+msgid "(value spec follows)\n"
+msgstr "(værdi-spec følger)\n"
+
+#: vms-alpha.c:6734
+#, c-format
+msgid "(at bit offset %u)\n"
+msgstr "(ved bitafsæt %u)\n"
+
+#: vms-alpha.c:6737
+#, c-format
+msgid "(reg: %u, disp: %u, indir: %u, kind: "
+msgstr "(reg: %u, disp: %u, indir: %u, type: "
+
+#: vms-alpha.c:6744
+msgid "literal"
+msgstr "literal"
+
+#: vms-alpha.c:6747
+msgid "address"
+msgstr "adresse"
+
+#: vms-alpha.c:6750
+msgid "desc"
+msgstr "beskr"
+
+#: vms-alpha.c:6753
+msgid "reg"
+msgstr "reg"
+
+#: vms-alpha.c:6828
+#, c-format
+msgid "Debug symbol table:\n"
+msgstr "Fejlsøgningssymboltabel:\n"
+
+#: vms-alpha.c:6839
+#, c-format
+msgid "cannot read DST header\n"
+msgstr "kan ikke læse DST-header\n"
+
+#: vms-alpha.c:6844
+#, c-format
+msgid " type: %3u, len: %3u (at 0x%08x): "
+msgstr " type: %3u, længde: %3u (på 0x%08x): "
+
+#: vms-alpha.c:6858
+#, c-format
+msgid "cannot read DST symbol\n"
+msgstr "kan ikke læse DST-symbol\n"
+
+#: vms-alpha.c:6901
+#, c-format
+msgid "standard data: %s\n"
+msgstr "standarddata : %s\n"
+
+#: vms-alpha.c:6904 vms-alpha.c:6988
+#, c-format
+msgid " name: %.*s\n"
+msgstr " navn: %.*s\n"
+
+#: vms-alpha.c:6911
+#, c-format
+msgid "modbeg\n"
+msgstr "modbeg\n"
+
+#: vms-alpha.c:6912
+#, c-format
+msgid " flags: %d, language: %u, major: %u, minor: %u\n"
+msgstr " flag: %d, sprog: %u, hoved: %u, under: %u\n"
+
+#: vms-alpha.c:6918 vms-alpha.c:7184
+#, c-format
+msgid " module name: %.*s\n"
+msgstr " modulnavn : %.*s\n"
+
+#: vms-alpha.c:6921
+#, c-format
+msgid " compiler : %.*s\n"
+msgstr " kompiler : %.*s\n"
+
+#: vms-alpha.c:6926
+#, c-format
+msgid "modend\n"
+msgstr "modend\n"
+
+#: vms-alpha.c:6933
+msgid "rtnbeg\n"
+msgstr "rtnbeg\n"
+
+#: vms-alpha.c:6934
+#, c-format
+msgid " flags: %u, address: 0x%08x, pd-address: 0x%08x\n"
+msgstr " flag: %u, adresse: 0x%08x, pd-adresse: 0x%08x\n"
+
+#: vms-alpha.c:6939
+#, c-format
+msgid " routine name: %.*s\n"
+msgstr " rutinenavn: %.*s\n"
+
+#: vms-alpha.c:6947
+#, c-format
+msgid "rtnend: size 0x%08x\n"
+msgstr "rtnend: størrelse 0x%08x\n"
+
+#: vms-alpha.c:6955
+#, c-format
+msgid "prolog: bkpt address 0x%08x\n"
+msgstr "prolog: bkpt-adresse 0x%08x\n"
+
+#: vms-alpha.c:6963
+#, c-format
+msgid "epilog: flags: %u, count: %u\n"
+msgstr "epilog: flag: %u, antal: %u\n"
+
+#: vms-alpha.c:6972
+#, c-format
+msgid "blkbeg: address: 0x%08x, name: %.*s\n"
+msgstr "blkbeg: adresse: 0x%08x, navn: %.*s\n"
+
+#: vms-alpha.c:6981
+#, c-format
+msgid "blkend: size: 0x%08x\n"
+msgstr "blkend: størrelse: 0x%08x\n"
+
+#: vms-alpha.c:6987
+#, c-format
+msgid "typspec (len: %u)\n"
+msgstr "typspec (længde: %u)\n"
+
+#: vms-alpha.c:6994
+#, c-format
+msgid "septyp, name: %.*s\n"
+msgstr "septyp, navn: %.*s\n"
+
+#: vms-alpha.c:7003
+#, c-format
+msgid "recbeg: name: %.*s\n"
+msgstr "recbeg: navn: %.*s\n"
+
+#: vms-alpha.c:7010
+#, c-format
+msgid "recend\n"
+msgstr "recend\n"
+
+#: vms-alpha.c:7013
+#, c-format
+msgid "enumbeg, len: %u, name: %.*s\n"
+msgstr "enumbeg, længde: %u, navn: %.*s\n"
+
+#: vms-alpha.c:7017
+#, c-format
+msgid "enumelt, name: %.*s\n"
+msgstr "enumelt, navn: %.*s\n"
+
+#: vms-alpha.c:7021
+#, c-format
+msgid "enumend\n"
+msgstr "enumend\n"
+
+#: vms-alpha.c:7038
+#, c-format
+msgid "discontiguous range (nbr: %u)\n"
+msgstr "usammenhængende interval (nbr: %u)\n"
+
+#: vms-alpha.c:7040
+#, c-format
+msgid " address: 0x%08x, size: %u\n"
+msgstr " adresse: 0x%08x, størrelse: %u\n"
+
+#: vms-alpha.c:7050
+#, c-format
+msgid "line num (len: %u)\n"
+msgstr "linjenummer (længde: %u)\n"
+
+#: vms-alpha.c:7067
+#, c-format
+msgid "delta_pc_w %u\n"
+msgstr "delta_pc_w %u\n"
+
+#: vms-alpha.c:7074
+#, c-format
+msgid "incr_linum(b): +%u\n"
+msgstr "incr_linum(b): +%u\n"
+
+#: vms-alpha.c:7080
+#, c-format
+msgid "incr_linum_w: +%u\n"
+msgstr "incr_linum_w: +%u\n"
+
+#: vms-alpha.c:7086
+#, c-format
+msgid "incr_linum_l: +%u\n"
+msgstr "incr_linum_l: +%u\n"
+
+#: vms-alpha.c:7092
+#, c-format
+msgid "set_line_num(w) %u\n"
+msgstr "set_line_num(w) %u\n"
+
+#: vms-alpha.c:7097
+#, c-format
+msgid "set_line_num_b %u\n"
+msgstr "set_line_num_b %u\n"
+
+#: vms-alpha.c:7102
+#, c-format
+msgid "set_line_num_l %u\n"
+msgstr "set_line_num_l %u\n"
+
+#: vms-alpha.c:7107
+#, c-format
+msgid "set_abs_pc: 0x%08x\n"
+msgstr "set_abs_pc: 0x%08x\n"
+
+#: vms-alpha.c:7111
+#, c-format
+msgid "delta_pc_l: +0x%08x\n"
+msgstr "delta_pc_l: +0x%08x\n"
+
+#: vms-alpha.c:7116
+#, c-format
+msgid "term(b): 0x%02x"
+msgstr "term(b): 0x%02x"
+
+#: vms-alpha.c:7118
+#, c-format
+msgid " pc: 0x%08x\n"
+msgstr " pc: 0x%08x\n"
+
+#: vms-alpha.c:7123
+#, c-format
+msgid "term_w: 0x%04x"
+msgstr "term_w: 0x%04x"
+
+#: vms-alpha.c:7125
+#, c-format
+msgid " pc: 0x%08x\n"
+msgstr " pc: 0x%08x\n"
+
+#: vms-alpha.c:7131
+#, c-format
+msgid "delta pc +%-4d"
+msgstr "delta pc +%-4d"
+
+#: vms-alpha.c:7134
+#, c-format
+msgid " pc: 0x%08x line: %5u\n"
+msgstr " pc: 0x%08x linje: %5u\n"
+
+#: vms-alpha.c:7139
+#, c-format
+msgid " *unhandled* cmd %u\n"
+msgstr " *uhåndteret* kommando %u\n"
+
+#: vms-alpha.c:7154
+#, c-format
+msgid "source (len: %u)\n"
+msgstr "kilde (længde: %u)\n"
+
+#: vms-alpha.c:7168
+#, c-format
+msgid " declfile: len: %u, flags: %u, fileid: %u\n"
+msgstr " declfile: længde: %u, flag: %u, fil-id: %u\n"
+
+#: vms-alpha.c:7172
+#, c-format
+msgid " rms: cdt: 0x%08x %08x, ebk: 0x%08x, ffb: 0x%04x, rfo: %u\n"
+msgstr " rms: cdt: 0x%08x %08x, ebk: 0x%08x, ffb: 0x%04x, rfo: %u\n"
+
+#: vms-alpha.c:7181
+#, c-format
+msgid " filename : %.*s\n"
+msgstr " filnavn : %.*s\n"
+
+#: vms-alpha.c:7190
+#, c-format
+msgid " setfile %u\n"
+msgstr " setfile %u\n"
+
+#: vms-alpha.c:7195 vms-alpha.c:7200
+#, c-format
+msgid " setrec %u\n"
+msgstr " setrec %u\n"
+
+#: vms-alpha.c:7205 vms-alpha.c:7210
+#, c-format
+msgid " setlnum %u\n"
+msgstr " setlnum %u\n"
+
+#: vms-alpha.c:7215 vms-alpha.c:7220
+#, c-format
+msgid " deflines %u\n"
+msgstr " deflines %u\n"
+
+#: vms-alpha.c:7224
+#, c-format
+msgid " formfeed\n"
+msgstr " formfeed\n"
+
+#: vms-alpha.c:7228
+#, c-format
+msgid " *unhandled* cmd %u\n"
+msgstr " *uhåndteret* kommando %u\n"
+
+#: vms-alpha.c:7240
+#, c-format
+msgid "*unhandled* dst type %u\n"
+msgstr "*uhåndteret dst-type %u\n"
+
+#: vms-alpha.c:7272
+#, c-format
+msgid "cannot read EIHD\n"
+msgstr "kan ikke læse EIHD\n"
+
+#: vms-alpha.c:7275
+#, c-format
+msgid "EIHD: (size: %u, nbr blocks: %u)\n"
+msgstr "EIHD: (størrelse: %u, bloktal: %u)\n"
+
+#: vms-alpha.c:7278
+#, c-format
+msgid " majorid: %u, minorid: %u\n"
+msgstr " hovednr: %u, undernr: %u\n"
+
+#: vms-alpha.c:7286
+msgid "executable"
+msgstr "eksekverbar fil"
+
+#: vms-alpha.c:7289
+msgid "linkable image"
+msgstr "lænkbart aftryk"
+
+#: vms-alpha.c:7295
+#, c-format
+msgid " image type: %u (%s)"
+msgstr " aftrykstype: %u (%s)"
+
+#: vms-alpha.c:7301
+msgid "native"
+msgstr "native"
+
+#: vms-alpha.c:7304
+msgid "CLI"
+msgstr "CLI"
+
+#: vms-alpha.c:7310
+#, c-format
+msgid ", subtype: %u (%s)\n"
+msgstr ", undertype: %u (%s)\n"
+
+#: vms-alpha.c:7316
+#, c-format
+msgid " offsets: isd: %u, activ: %u, symdbg: %u, imgid: %u, patch: %u\n"
+msgstr " afsæt: isd: %u, aktiv: %u, symdbg: %u, imgid: %u, patch: %u\n"
+
+#: vms-alpha.c:7320
+#, c-format
+msgid " fixup info rva: "
+msgstr " fixup info-rva: "
+
+#: vms-alpha.c:7322
+#, c-format
+msgid ", symbol vector rva: "
+msgstr ", symbolvektor-rva: "
+
+#: vms-alpha.c:7325
+#, c-format
+msgid ""
+"\n"
+" version array off: %u\n"
+msgstr ""
+"\n"
+" versions-arrayafsæt: %u\n"
+
+#: vms-alpha.c:7329
+#, c-format
+msgid " img I/O count: %u, nbr channels: %u, req pri: %08x%08x\n"
+msgstr " img-I/O-tal: %u, antal kanaler: %u, req pri: %08x%08x\n"
+
+#: vms-alpha.c:7335
+#, c-format
+msgid " linker flags: %08x:"
+msgstr " lænkerflag: %08x:"
+
+#: vms-alpha.c:7365
+#, c-format
+msgid " ident: 0x%08x, sysver: 0x%08x, match ctrl: %u, symvect_size: %u\n"
+msgstr " ident: 0x%08x, sysver: 0x%08x, match-ktrl: %u, symvect_size: %u\n"
+
+#: vms-alpha.c:7371
+#, c-format
+msgid " BPAGE: %u"
+msgstr " BPAGE: %u"
+
+#: vms-alpha.c:7377
+#, c-format
+msgid ", ext fixup offset: %u, no_opt psect off: %u"
+msgstr ", ext-fixup-afsæt: %u, no_opt psect slået fra: %u"
+
+#: vms-alpha.c:7380
+#, c-format
+msgid ", alias: %u\n"
+msgstr ", alias: %u\n"
+
+#: vms-alpha.c:7388
+#, c-format
+msgid "system version array information:\n"
+msgstr "arrayinformation om systemversion:\n"
+
+#: vms-alpha.c:7392
+#, c-format
+msgid "cannot read EIHVN header\n"
+msgstr "kan ikke læse EIHVN-header\n"
+
+#: vms-alpha.c:7402
+#, c-format
+msgid "cannot read EIHVN version\n"
+msgstr "kan ikke læse EIHVN-version\n"
+
+#: vms-alpha.c:7405
+#, c-format
+msgid " %02u "
+msgstr " %02u "
+
+# ?
+#: vms-alpha.c:7409
+msgid "BASE_IMAGE "
+msgstr "BASE_IMAGE "
+
+#: vms-alpha.c:7412
+msgid "MEMORY_MANAGEMENT"
+msgstr "MEMORY_MANAGEMENT"
+
+#: vms-alpha.c:7415
+msgid "IO "
+msgstr "IO "
+
+#: vms-alpha.c:7418
+msgid "FILES_VOLUMES "
+msgstr "FILES_VOLUMES "
+
+#: vms-alpha.c:7421
+msgid "PROCESS_SCHED "
+msgstr "PROCESS_SCHED "
+
+#: vms-alpha.c:7424
+msgid "SYSGEN "
+msgstr "SYSGEN "
+
+#: vms-alpha.c:7427
+msgid "CLUSTERS_LOCKMGR "
+msgstr "CLUSTERS_LOCKMGR "
+
+#: vms-alpha.c:7430
+msgid "LOGICAL_NAMES "
+msgstr "LOGICAL_NAMES "
+
+#: vms-alpha.c:7433
+msgid "SECURITY "
+msgstr "SECURITY "
+
+#: vms-alpha.c:7436
+msgid "IMAGE_ACTIVATOR "
+msgstr "IMAGE_ACTIVATOR "
+
+#: vms-alpha.c:7439
+msgid "NETWORKS "
+msgstr "NETWORKS "
+
+#: vms-alpha.c:7442
+msgid "COUNTERS "
+msgstr "COUNTERS "
+
+#: vms-alpha.c:7445
+msgid "STABLE "
+msgstr "STABLE "
+
+#: vms-alpha.c:7448
+msgid "MISC "
+msgstr "MISC "
+
+#: vms-alpha.c:7451
+msgid "CPU "
+msgstr "CPU "
+
+#: vms-alpha.c:7454
+msgid "VOLATILE "
+msgstr "VOLATILE "
+
+#: vms-alpha.c:7457
+msgid "SHELL "
+msgstr "SHELL "
+
+#: vms-alpha.c:7460
+msgid "POSIX "
+msgstr "POSIX "
+
+#: vms-alpha.c:7463
+msgid "MULTI_PROCESSING "
+msgstr "MULTI_PROCESSING "
+
+#: vms-alpha.c:7466
+msgid "GALAXY "
+msgstr "GALAXY "
+
+#: vms-alpha.c:7469
+msgid "*unknown* "
+msgstr "*ukendt* "
+
+#: vms-alpha.c:7472
+#, c-format
+msgid ": %u.%u\n"
+msgstr ": %u.%u\n"
+
+#: vms-alpha.c:7485 vms-alpha.c:7744
+#, c-format
+msgid "cannot read EIHA\n"
+msgstr "kan ikke læse EIHA\n"
+
+#: vms-alpha.c:7488
+#, c-format
+msgid "Image activation: (size=%u)\n"
+msgstr "Aftryksaktivering: (størrelse=%u)\n"
+
+# Den her og de nedenstående skal tilsyneladende passe sammen med placering af kolon
+#: vms-alpha.c:7490
+#, c-format
+msgid " First address : 0x%08x 0x%08x\n"
+msgstr " Første adresse: 0x%08x 0x%08x\n"
+
+#: vms-alpha.c:7493
+#, c-format
+msgid " Second address: 0x%08x 0x%08x\n"
+msgstr " Anden adresse : 0x%08x 0x%08x\n"
+
+#: vms-alpha.c:7496
+#, c-format
+msgid " Third address : 0x%08x 0x%08x\n"
+msgstr " Tredje adresse: 0x%08x 0x%08x\n"
+
+#: vms-alpha.c:7499
+#, c-format
+msgid " Fourth address: 0x%08x 0x%08x\n"
+msgstr " Fjerde adresse: 0x%08x 0x%08x\n"
+
+#: vms-alpha.c:7502
+#, c-format
+msgid " Shared image : 0x%08x 0x%08x\n"
+msgstr " Delt aftryk : 0x%08x 0x%08x\n"
+
+#: vms-alpha.c:7513
+#, c-format
+msgid "cannot read EIHI\n"
+msgstr "kan ikke læse EIHI\n"
+
+#: vms-alpha.c:7516
+#, c-format
+msgid "Image identification: (major: %u, minor: %u)\n"
+msgstr "Aftryksidentifikation: (hoved: %u, under: %u)\n"
+
+#: vms-alpha.c:7519
+#, c-format
+msgid " image name : %.*s\n"
+msgstr " aftryksnavn : %.*s\n"
+
+#: vms-alpha.c:7521
+#, c-format
+msgid " link time : %s\n"
+msgstr " lænketidspunkt : %s\n"
+
+#: vms-alpha.c:7523
+#, c-format
+msgid " image ident : %.*s\n"
+msgstr " aftryks-id : %.*s\n"
+
+#: vms-alpha.c:7525
+#, c-format
+msgid " linker ident : %.*s\n"
+msgstr " lænker-id : %.*s\n"
+
+#: vms-alpha.c:7527
+#, c-format
+msgid " image build ident: %.*s\n"
+msgstr " aftryks bygge-id : %.*s\n"
+
+#: vms-alpha.c:7537
+#, c-format
+msgid "cannot read EIHS\n"
+msgstr "kan ikke læse EIHS\n"
+
+#: vms-alpha.c:7540
+#, c-format
+msgid "Image symbol & debug table: (major: %u, minor: %u)\n"
+msgstr "Aftrykssymbol- og fejlsøgningstabel: (hoved: %u, under: %u)\n"
+
+#: vms-alpha.c:7545
+#, c-format
+msgid " debug symbol table : vbn: %u, size: %u (0x%x)\n"
+msgstr " symboltabel til fejlsøgning : vbn: %u, størrelse: %u (0x%x)\n"
+
+#: vms-alpha.c:7549
+#, c-format
+msgid " global symbol table: vbn: %u, records: %u\n"
+msgstr " global symboltabel: vbn: %u, poster: %u\n"
+
+#: vms-alpha.c:7553
+#, c-format
+msgid " debug module table : vbn: %u, size: %u\n"
+msgstr " fejlsøgningsmodultabel : vbn: %u, størrelse: %u\n"
+
+#: vms-alpha.c:7566
+#, c-format
+msgid "cannot read EISD\n"
+msgstr "kan ikke læse EISD\n"
+
+#: vms-alpha.c:7576
+#, c-format
+msgid "Image section descriptor: (major: %u, minor: %u, size: %u, offset: %u)\n"
+msgstr "Aftrykssektionsdeskriptor: (hoved: %u, under: %u, størrelse: %u, afsæt: %u)\n"
+
+#: vms-alpha.c:7583
+#, c-format
+msgid " section: base: 0x%08x%08x size: 0x%08x\n"
+msgstr " sektion: base: 0x%08x%08x size: 0x%08x\n"
+
+#: vms-alpha.c:7588
+#, c-format
+msgid " flags: 0x%04x"
+msgstr " flag: 0x%04x"
+
+#: vms-alpha.c:7625
+#, c-format
+msgid " vbn: %u, pfc: %u, matchctl: %u type: %u ("
+msgstr " vbn: %u, pfc: %u, matchktl: %u type: %u ("
+
+#: vms-alpha.c:7631
+msgid "NORMAL"
+msgstr "NORMAL"
+
+#: vms-alpha.c:7634
+msgid "SHRFXD"
+msgstr "SHRFXD"
+
+#: vms-alpha.c:7637
+msgid "PRVFXD"
+msgstr "PRVFXD"
+
+#: vms-alpha.c:7640
+msgid "SHRPIC"
+msgstr "SHRPIC"
+
+#: vms-alpha.c:7643
+msgid "PRVPIC"
+msgstr "PRVPIC"
+
+#: vms-alpha.c:7646
+msgid "USRSTACK"
+msgstr "USRSTACK"
+
+#: vms-alpha.c:7654
+#, c-format
+msgid " ident: 0x%08x, name: %.*s\n"
+msgstr " ident: 0x%08x, navn: %.*s\n"
+
+#: vms-alpha.c:7664
+#, c-format
+msgid "cannot read DMT\n"
+msgstr "kan ikke læse DMT\n"
+
+#: vms-alpha.c:7668
+#, c-format
+msgid "Debug module table:\n"
+msgstr "Fejlsøgningsmodultabel:\n"
+
+#: vms-alpha.c:7677
+#, c-format
+msgid "cannot read DMT header\n"
+msgstr "kan ikke læse DMT-header\n"
+
+#: vms-alpha.c:7682
+#, c-format
+msgid " module offset: 0x%08x, size: 0x%08x, (%u psects)\n"
+msgstr " modulafsæt: 0x%08x, størrelse: 0x%08x, (%u psect'er)\n"
+
+#: vms-alpha.c:7692
+#, c-format
+msgid "cannot read DMT psect\n"
+msgstr "kan ikke læse DMT-psect\n"
+
+#: vms-alpha.c:7695
+#, c-format
+msgid " psect start: 0x%08x, length: %u\n"
+msgstr " psect-start: 0x%08x, længde: %u\n"
+
+#: vms-alpha.c:7708
+#, c-format
+msgid "cannot read DST\n"
+msgstr "kan ikke læse DST\n"
+
+#: vms-alpha.c:7718
+#, c-format
+msgid "cannot read GST\n"
+msgstr "kan ikke læse GST\n"
+
+#: vms-alpha.c:7722
+#, c-format
+msgid "Global symbol table:\n"
+msgstr "Global symboltabel:\n"
+
+#: vms-alpha.c:7750
+#, c-format
+msgid "Image activator fixup: (major: %u, minor: %u)\n"
+msgstr "Fixup til aftryksaktivator: (hoved: %u, under: %u)\n"
+
+#: vms-alpha.c:7753
+#, c-format
+msgid " iaflink : 0x%08x %08x\n"
+msgstr " iaflink : 0x%08x %08x\n"
+
+#: vms-alpha.c:7756
+#, c-format
+msgid " fixuplnk: 0x%08x %08x\n"
+msgstr " fixuplnk: 0x%08x %08x\n"
+
+#: vms-alpha.c:7759
+#, c-format
+msgid " size : %u\n"
+msgstr " størrelse: %u\n"
+
+#: vms-alpha.c:7761
+#, c-format
+msgid " flags: 0x%08x\n"
+msgstr " flag: 0x%08x\n"
+
+#: vms-alpha.c:7765
+#, c-format
+msgid " qrelfixoff: %5u, lrelfixoff: %5u\n"
+msgstr " qrelfixoff: %5u, lrelfixoff: %5u\n"
+
+#: vms-alpha.c:7769
+#, c-format
+msgid " qdotadroff: %5u, ldotadroff: %5u\n"
+msgstr " qdotadroff: %5u, ldotadroff: %5u\n"
+
+#: vms-alpha.c:7773
+#, c-format
+msgid " codeadroff: %5u, lpfixoff : %5u\n"
+msgstr " codeadroff: %5u, lpfixoff : %5u\n"
+
+#: vms-alpha.c:7776
+#, c-format
+msgid " chgprtoff : %5u\n"
+msgstr " chgprtoff : %5u\n"
+
+#: vms-alpha.c:7779
+#, c-format
+msgid " shlstoff : %5u, shrimgcnt : %5u\n"
+msgstr " shlstoff : %5u, shrimgcnt : %5u\n"
+
+#: vms-alpha.c:7781
+#, c-format
+msgid " shlextra : %5u, permctx : %5u\n"
+msgstr " shlextra : %5u, permctx : %5u\n"
+
+#: vms-alpha.c:7784
+#, c-format
+msgid " base_va : 0x%08x\n"
+msgstr " base_va : 0x%08x\n"
+
+#: vms-alpha.c:7786
+#, c-format
+msgid " lppsbfixoff: %5u\n"
+msgstr " lppsbfixoff: %5u\n"
+
+#: vms-alpha.c:7794
+#, c-format
+msgid " Shareable images:\n"
+msgstr " Delelige aftryk:\n"
+
+#: vms-alpha.c:7798
+#, c-format
+msgid " %u: size: %u, flags: 0x%02x, name: %.*s\n"
+msgstr " %u: størrelse: %u, flag: 0x%02x, navn: %.*s\n"
+
+#: vms-alpha.c:7805
+#, c-format
+msgid " quad-word relocation fixups:\n"
+msgstr " fixup'er til quad-word-relokeringer:\n"
+
+#: vms-alpha.c:7810
+#, c-format
+msgid " long-word relocation fixups:\n"
+msgstr " fixup'er til long-word-relokeringer:\n"
+
+#: vms-alpha.c:7815
+#, c-format
+msgid " quad-word .address reference fixups:\n"
+msgstr " fixup'er til quad-word .address-referencer:\n"
+
+#: vms-alpha.c:7820
+#, c-format
+msgid " long-word .address reference fixups:\n"
+msgstr " fixup'er til long-word .address-referencer:\n"
+
+#: vms-alpha.c:7825
+#, c-format
+msgid " Code Address Reference Fixups:\n"
+msgstr " Fixup'er til kodeadressereferencer:\n"
+
+#: vms-alpha.c:7830
+#, c-format
+msgid " Linkage Pairs Referece Fixups:\n"
+msgstr " Reference-fixup'er til lænkningspar:\n"
+
+#: vms-alpha.c:7839
+#, c-format
+msgid " Change Protection (%u entries):\n"
+msgstr " Ændringsbeskyttelse (%u elementer):\n"
+
+#: vms-alpha.c:7844
+#, c-format
+msgid " base: 0x%08x %08x, size: 0x%08x, prot: 0x%08x "
+msgstr " base: 0x%08x %08x, størrelse: 0x%08x, beskyttelse: 0x%08x "
+
+#. FIXME: we do not yet support relocatable link. It is not obvious
+#. how to do it for debug infos.
+#: vms-alpha.c:8676
+msgid "%P: relocatable link is not supported\n"
+msgstr "%P: relokérbar lænke understøttes ikke\n"
+
+#: vms-alpha.c:8746
+msgid "%P: multiple entry points: in modules %B and %B\n"
+msgstr "%P: flere indgangspunkter: i modulerne %B og %B\n"
+
+#: vms-lib.c:1421
+#, c-format
+msgid "could not open shared image '%s' from '%s'"
+msgstr "kunne ikke åbne delt aftryk \"%s\" fra \"%s\""
+
+#: vms-misc.c:360
+msgid "_bfd_vms_output_counted called with zero bytes"
+msgstr "_bfd_vms_output_counted kaldt med nul byte"
+
+#: vms-misc.c:365
+msgid "_bfd_vms_output_counted called with too many bytes"
+msgstr "_bfd_vms_output_counted kaldt med for mange byte"
+
+#: xcofflink.c:836
+#, c-format
+msgid "%s: XCOFF shared object when not producing XCOFF output"
+msgstr "%s: XCOFF delt objekt når ikke XCOFF-uddata produceres"
+
+#: xcofflink.c:857
+#, c-format
+msgid "%s: dynamic object with no .loader section"
+msgstr "%s: dynamisk objekt uden nogen .loader-sektion"
+
+#: xcofflink.c:1415
+msgid "%B: `%s' has line numbers but no enclosing section"
+msgstr "%B: \"%s\" har linjenumre, men ingen omsluttende sektion"
+
+#: xcofflink.c:1467
+msgid "%B: class %d symbol `%s' has no aux entries"
+msgstr "%B: klasse %d-symbol \"%s\" har ingen aux-poster"
+
+#: xcofflink.c:1489
+msgid "%B: symbol `%s' has unrecognized csect type %d"
+msgstr "%B: symbol \"%s\" har ukendt csect-type %d"
+
+#: xcofflink.c:1501
+msgid "%B: bad XTY_ER symbol `%s': class %d scnum %d scnlen %d"
+msgstr "%B: fejlagtigt XTY_ER-symbol \"%s\": klasse %d scnum %d scnlen %d"
+
+#: xcofflink.c:1530
+msgid "%B: XMC_TC0 symbol `%s' is class %d scnlen %d"
+msgstr "%B: XMC_TC0-symbol \"%s\" er klasse %d scnlen %d"
+
+#: xcofflink.c:1676
+msgid "%B: csect `%s' not in enclosing section"
+msgstr "%B: csect \"%s\" er ikke i omsluttende sektion"
+
+#: xcofflink.c:1783
+msgid "%B: misplaced XTY_LD `%s'"
+msgstr "%B: fejlagtigt placeret XTY_LD \"%s\""
+
+#: xcofflink.c:2102
+msgid "%B: reloc %s:%d not in csect"
+msgstr "%B: relokeringen %s:%d er ikke i csect"
+
+#: xcofflink.c:3186
+#, c-format
+msgid "%s: no such symbol"
+msgstr "%s: intet sådant symbol"
+
+#: xcofflink.c:3291
+#, c-format
+msgid "warning: attempt to export undefined symbol `%s'"
+msgstr "advarsel: forsøg på at eksportere udefineret symbol \"%s\""
+
+#: xcofflink.c:3673
+msgid "error: undefined symbol __rtinit"
+msgstr "fejl: udefineret symbol __rtinit"
+
+#: xcofflink.c:4052
+msgid "%B: loader reloc in unrecognized section `%s'"
+msgstr "%B: indlæserrelokering i ukendt sektion \"%s\""
+
+#: xcofflink.c:4063
+msgid "%B: `%s' in loader reloc but not loader sym"
+msgstr "%B: \"%s\" i indlæserrelokering, men ikke indlæsersym"
+
+#: xcofflink.c:4079
+msgid "%B: loader reloc in read-only section %A"
+msgstr "%B: indlæserrelokering i skrivebeskyttet sektion %A"
+
+#: xcofflink.c:5097
+#, c-format
+msgid "TOC overflow: 0x%lx > 0x10000; try -mminimal-toc when compiling"
+msgstr "TOC giver overløb: 0x%lx > 0x10000; prøv -mminimal-toc ved oversættelse"
+
+#: elf32-ia64.c:1110 elf64-ia64.c:1110
+msgid "%B: Can't relax br at 0x%lx in section `%A'. Please use brl or indirect branch."
+msgstr "%B: Kan ikke forenkle br ved 0x%lx i sektionen \"%A\". Brug venligst brl eller indirekte gren."
+
+#: elf32-ia64.c:2809 elf64-ia64.c:2809
+msgid "@pltoff reloc against local symbol"
+msgstr "@pltoff-relokering mod lokalt symbol"
+
+#: elf32-ia64.c:4430 elf64-ia64.c:4430
+#, c-format
+msgid "%s: short data segment overflowed (0x%lx >= 0x400000)"
+msgstr "%s: kort datasegment løb over (0x%lx >= 0x400000)"
+
+#: elf32-ia64.c:4441 elf64-ia64.c:4441
+#, c-format
+msgid "%s: __gp does not cover short data segment"
+msgstr "%s: __gp dækker ikke kort datasegment"
+
+#: elf32-ia64.c:4708 elf64-ia64.c:4708
+msgid "%B: non-pic code with imm relocation against dynamic symbol `%s'"
+msgstr "%B: ikke-pic-kode med imm-relokering mod dynamisk symbol \"%s\""
+
+#: elf32-ia64.c:4775 elf64-ia64.c:4775
+msgid "%B: @gprel relocation against dynamic symbol %s"
+msgstr "%B: @gprel-relokering mod dynamisk symbol %s"
+
+#: elf32-ia64.c:4838 elf64-ia64.c:4838
+msgid "%B: linking non-pic code in a position independent executable"
+msgstr "%B: lænker ikke-pic-kode i en positionsuafhængig eksekverbar fil"
+
+#: elf32-ia64.c:4975 elf64-ia64.c:4975
+msgid "%B: @internal branch to dynamic symbol %s"
+msgstr "%B: @intern gren til dynamisk symbol %s"
+
+#: elf32-ia64.c:4977 elf64-ia64.c:4977
+msgid "%B: speculation fixup to dynamic symbol %s"
+msgstr "%B: spekulations-fixup til dynamisk symbol %s"
+
+#: elf32-ia64.c:4979 elf64-ia64.c:4979
+msgid "%B: @pcrel relocation against dynamic symbol %s"
+msgstr "%B: @pcrel-relokering mod dynamisk symbol %s"
+
+#: elf32-ia64.c:5176 elf64-ia64.c:5176
+msgid "unsupported reloc"
+msgstr "relokeringen understøttes ikke"
+
+#: elf32-ia64.c:5214 elf64-ia64.c:5214
+msgid "%B: missing TLS section for relocation %s against `%s' at 0x%lx in section `%A'."
+msgstr "%B: manglende TLS-sektion til relokering %s mod \"%s\" ved 0x%lx i sektionen \"%A\"."
+
+#: elf32-ia64.c:5229 elf64-ia64.c:5229
+msgid "%B: Can't relax br (%s) to `%s' at 0x%lx in section `%A' with size 0x%lx (> 0x1000000)."
+msgstr "%B: Kan ikke forenkle br (%s) til \"%s\" på 0x%lx i sektionen \"%A\" med størrelsen 0x%lx (> 0x1000000)."
+
+#: elf32-ia64.c:5491 elf64-ia64.c:5491
+msgid "%B: linking trap-on-NULL-dereference with non-trapping files"
+msgstr "%B: lænker fang-ved-NULL-dereference med ikkefangende filer"
+
+#: elf32-ia64.c:5500 elf64-ia64.c:5500
+msgid "%B: linking big-endian files with little-endian files"
+msgstr "%B: lænker big-endian-filer med little endian-filer"
+
+#: elf32-ia64.c:5509 elf64-ia64.c:5509
+msgid "%B: linking 64-bit files with 32-bit files"
+msgstr "%B: lænker 64 bit-filer med 32 bit-filer"
+
+#: elf32-ia64.c:5518 elf64-ia64.c:5518
+msgid "%B: linking constant-gp files with non-constant-gp files"
+msgstr "%B: lænker konstant-gp-filer med ikke-konstant-gp-filer"
+
+#: elf32-ia64.c:5528 elf64-ia64.c:5528
+msgid "%B: linking auto-pic files with non-auto-pic files"
+msgstr "%B: lænker auto-pic-filer med ikke-auto-pic-filer"
+
+#: peigen.c:1002 pepigen.c:1002 pex64igen.c:1002
+#, c-format
+msgid "%s: line number overflow: 0x%lx > 0xffff"
+msgstr "%s: linjenummer giver overløb: 0x%lx > 0xffff"
+
+#: peigen.c:1029 pepigen.c:1029 pex64igen.c:1029
+msgid "Export Directory [.edata (or where ever we found it)]"
+msgstr "Eksportkatalog [.edata (eller hvor vi fandt det)]"
+
+#: peigen.c:1030 pepigen.c:1030 pex64igen.c:1030
+msgid "Import Directory [parts of .idata]"
+msgstr "Importkatalog [dele af .idata]"
+
+#: peigen.c:1031 pepigen.c:1031 pex64igen.c:1031
+msgid "Resource Directory [.rsrc]"
+msgstr "Resursekatalog [.rsrc]"
+
+#: peigen.c:1032 pepigen.c:1032 pex64igen.c:1032
+msgid "Exception Directory [.pdata]"
+msgstr "Undtagelseskatalog [.pdata]"
+
+#: peigen.c:1033 pepigen.c:1033 pex64igen.c:1033
+msgid "Security Directory"
+msgstr "Sikkerhedskatalog"
+
+#: peigen.c:1034 pepigen.c:1034 pex64igen.c:1034
+msgid "Base Relocation Directory [.reloc]"
+msgstr "Baserelokeringskatalog [.reloc]"
+
+#: peigen.c:1035 pepigen.c:1035 pex64igen.c:1035
+msgid "Debug Directory"
+msgstr "Fejlsøgningskatalog"
+
+#: peigen.c:1036 pepigen.c:1036 pex64igen.c:1036
+msgid "Description Directory"
+msgstr "Beskrivelseskatalog"
+
+#: peigen.c:1037 pepigen.c:1037 pex64igen.c:1037
+msgid "Special Directory"
+msgstr "Specialkatalog"
+
+#: peigen.c:1038 pepigen.c:1038 pex64igen.c:1038
+msgid "Thread Storage Directory [.tls]"
+msgstr "Trådlagringskatalog [.tls]"
+
+#: peigen.c:1039 pepigen.c:1039 pex64igen.c:1039
+msgid "Load Configuration Directory"
+msgstr "Indlæsningskonfigurationskatalog"
+
+#: peigen.c:1040 pepigen.c:1040 pex64igen.c:1040
+msgid "Bound Import Directory"
+msgstr "Katalog over bundne importer"
+
+#: peigen.c:1041 pepigen.c:1041 pex64igen.c:1041
+msgid "Import Address Table Directory"
+msgstr "Importadressetabelkatalog"
+
+#: peigen.c:1042 pepigen.c:1042 pex64igen.c:1042
+msgid "Delay Import Directory"
+msgstr "Katalog over forskinkede importer"
+
+#: peigen.c:1043 pepigen.c:1043 pex64igen.c:1043
+msgid "CLR Runtime Header"
+msgstr "CLR-runtime-header"
+
+#: peigen.c:1044 pepigen.c:1044 pex64igen.c:1044
+msgid "Reserved"
+msgstr "Reserveret"
+
+#: peigen.c:1104 pepigen.c:1104 pex64igen.c:1104
+#, c-format
+msgid ""
+"\n"
+"There is an import table, but the section containing it could not be found\n"
+msgstr ""
+"\n"
+"Der findes en importtabel, men sektionen som indeholder den kunne ikke findes\n"
+
+#: peigen.c:1109 pepigen.c:1109 pex64igen.c:1109
+#, c-format
+msgid ""
+"\n"
+"There is an import table in %s at 0x%lx\n"
+msgstr ""
+"\n"
+"Der findes en importtabel i %s på 0x%lx\n"
+
+#: peigen.c:1151 pepigen.c:1151 pex64igen.c:1151
+#, c-format
+msgid ""
+"\n"
+"Function descriptor located at the start address: %04lx\n"
+msgstr ""
+"\n"
+"Funktionsidentifikatorer fundet på startadressen: %04lx\n"
+
+#: peigen.c:1154 pepigen.c:1154 pex64igen.c:1154
+#, c-format
+msgid "\tcode-base %08lx toc (loadable/actual) %08lx/%08lx\n"
+msgstr "\tkodebase %08lx toc (indlæseligt/reelt) %08lx/%08lx\n"
+
+#: peigen.c:1162 pepigen.c:1162 pex64igen.c:1162
+#, c-format
+msgid ""
+"\n"
+"No reldata section! Function descriptor not decoded.\n"
+msgstr ""
+"\n"
+"Ingen reldata-sektion! Funktionsidentifikatorer afkodedes ikke.\n"
+
+#: peigen.c:1167 pepigen.c:1167 pex64igen.c:1167
+#, c-format
+msgid ""
+"\n"
+"The Import Tables (interpreted %s section contents)\n"
+msgstr ""
+"\n"
+"Importtabellerne (tolket indhold i %s-sektion)\n"
+
+# Hvad er thunk?
+#: peigen.c:1170 pepigen.c:1170 pex64igen.c:1170
+#, c-format
+msgid ""
+" vma: Hint Time Forward DLL First\n"
+" Table Stamp Chain Name Thunk\n"
+msgstr ""
+" vma: Tips- Tids- Fremad- DLL- Første\n"
+" tabel stempel kæde navn thunk\n"
+
+#: peigen.c:1218 pepigen.c:1218 pex64igen.c:1218
+#, c-format
+msgid ""
+"\n"
+"\tDLL Name: %s\n"
+msgstr ""
+"\n"
+"\tDLL-navn: %s\n"
+
+#: peigen.c:1229 pepigen.c:1229 pex64igen.c:1229
+#, c-format
+msgid "\tvma: Hint/Ord Member-Name Bound-To\n"
+msgstr "\tvma: Tips/Ordn Medlemsnavn Bundet til\n"
+
+#: peigen.c:1254 pepigen.c:1254 pex64igen.c:1254
+#, c-format
+msgid ""
+"\n"
+"There is a first thunk, but the section containing it could not be found\n"
+msgstr ""
+"\n"
+"Der findes en første thunk, men sektionen som indeholder den kunne ikke findes\n"
+
+#: peigen.c:1415 pepigen.c:1415 pex64igen.c:1415
+#, c-format
+msgid ""
+"\n"
+"There is an export table, but the section containing it could not be found\n"
+msgstr ""
+"\n"
+"Der findes en eksporttabel, men sektionen som indeholder den kunne ikke findes\n"
+
+#: peigen.c:1424 pepigen.c:1424 pex64igen.c:1424
+#, c-format
+msgid ""
+"\n"
+"There is an export table in %s, but it does not fit into that section\n"
+msgstr ""
+"\n"
+"Der findes en eksporttabel i %s, men den passer ikke ind i den pågældende sektion\n"
+
+#: peigen.c:1430 pepigen.c:1430 pex64igen.c:1430
+#, c-format
+msgid ""
+"\n"
+"There is an export table in %s at 0x%lx\n"
+msgstr ""
+"\n"
+"Der findes en eksporttabel i %s ved 0x%lx\n"
+
+#: peigen.c:1458 pepigen.c:1458 pex64igen.c:1458
+#, c-format
+msgid ""
+"\n"
+"The Export Tables (interpreted %s section contents)\n"
+"\n"
+msgstr ""
+"\n"
+"Eksporttabellerne (tolket indhold i %s-sektion)\n"
+
+#: peigen.c:1462 pepigen.c:1462 pex64igen.c:1462
+#, c-format
+msgid "Export Flags \t\t\t%lx\n"
+msgstr "Eksportflag \t\t\t%lx\n"
+
+#: peigen.c:1465 pepigen.c:1465 pex64igen.c:1465
+#, c-format
+msgid "Time/Date stamp \t\t%lx\n"
+msgstr "Tids-/datostempel \t\t%lx\n"
+
+#: peigen.c:1468 pepigen.c:1468 pex64igen.c:1468
+#, c-format
+msgid "Major/Minor \t\t\t%d/%d\n"
+msgstr "Større/mindre \t\t\t%d/%d\n"
+
+#: peigen.c:1471 pepigen.c:1471 pex64igen.c:1471
+#, c-format
+msgid "Name \t\t\t\t"
+msgstr "Navn \t\t\t\t"
+
+#: peigen.c:1477 pepigen.c:1477 pex64igen.c:1477
+#, c-format
+msgid "Ordinal Base \t\t\t%ld\n"
+msgstr "Ordningsbase \t\t\t%ld\n"
+
+#: peigen.c:1480 pepigen.c:1480 pex64igen.c:1480
+#, c-format
+msgid "Number in:\n"
+msgstr "Tal i:\n"
+
+#: peigen.c:1483 pepigen.c:1483 pex64igen.c:1483
+#, c-format
+msgid "\tExport Address Table \t\t%08lx\n"
+msgstr "\tEksportadressetabel \t\t%08lx\n"
+
+#: peigen.c:1487 pepigen.c:1487 pex64igen.c:1487
+#, c-format
+msgid "\t[Name Pointer/Ordinal] Table\t%08lx\n"
+msgstr "\t[Navnepeger/Ordningstal]-tabel\t%08lx\n"
+
+#: peigen.c:1490 pepigen.c:1490 pex64igen.c:1490
+#, c-format
+msgid "Table Addresses\n"
+msgstr "Tabeladresser\n"
+
+#: peigen.c:1493 pepigen.c:1493 pex64igen.c:1493
+#, c-format
+msgid "\tExport Address Table \t\t"
+msgstr "\tEksportadressetabel \t\t"
+
+#: peigen.c:1498 pepigen.c:1498 pex64igen.c:1498
+#, c-format
+msgid "\tName Pointer Table \t\t"
+msgstr "\tNavnepegertabel \t\t"
+
+#: peigen.c:1503 pepigen.c:1503 pex64igen.c:1503
+#, c-format
+msgid "\tOrdinal Table \t\t\t"
+msgstr "\tOrdningstalstabel \t\t\t"
+
+#: peigen.c:1517 pepigen.c:1517 pex64igen.c:1517
+#, c-format
+msgid ""
+"\n"
+"Export Address Table -- Ordinal Base %ld\n"
+msgstr ""
+"\n"
+"Eksportadressetabel -- Ordningsbase %ld\n"
+
+#: peigen.c:1536 pepigen.c:1536 pex64igen.c:1536
+msgid "Forwarder RVA"
+msgstr "Videresender-RVA"
+
+#: peigen.c:1547 pepigen.c:1547 pex64igen.c:1547
+msgid "Export RVA"
+msgstr "Eksport-RVA"
+
+#: peigen.c:1554 pepigen.c:1554 pex64igen.c:1554
+#, c-format
+msgid ""
+"\n"
+"[Ordinal/Name Pointer] Table\n"
+msgstr ""
+"\n"
+"[Ordningstals-/Navnepeger-]tabel\n"
+
+#: peigen.c:1614 peigen.c:1797 pepigen.c:1614 pepigen.c:1797 pex64igen.c:1614
+#: pex64igen.c:1797
+#, c-format
+msgid "Warning, .pdata section size (%ld) is not a multiple of %d\n"
+msgstr "Advarsel, størrelsen på .pdata-sektionen (%ld) er ikke en multipel af %d\n"
+
+#: peigen.c:1621 pepigen.c:1621 pex64igen.c:1621
+#, c-format
+msgid " vma:\t\t\tBegin Address End Address Unwind Info\n"
+msgstr " vma:\t\t\tStartadresse Slutadresse Tilbagespolings-information\n"
+
+#: peigen.c:1623 pepigen.c:1623 pex64igen.c:1623
+#, c-format
+msgid ""
+" vma:\t\tBegin End EH EH PrologEnd Exception\n"
+" \t\tAddress Address Handler Data Address Mask\n"
+msgstr ""
+" vma:\t\tStart- Slut- EH- EH- Prologsluts- Undtagelses-\n"
+" \t\tadresse adresse håndterer data adresse maske\n"
+
+#: peigen.c:1697 pepigen.c:1697 pex64igen.c:1697
+#, c-format
+msgid " Register save millicode"
+msgstr " Registergemnings millikode"
+
+#: peigen.c:1700 pepigen.c:1700 pex64igen.c:1700
+#, c-format
+msgid " Register restore millicode"
+msgstr " Registergenskabnings millikode"
+
+#: peigen.c:1703 pepigen.c:1703 pex64igen.c:1703
+#, c-format
+msgid " Glue code sequence"
+msgstr " Klisterkodesekvens"
+
+# Et bogstav for meget i Undtagelse og Håndtering, mon ikke det går?
+#: peigen.c:1803 pepigen.c:1803 pex64igen.c:1803
+#, c-format
+msgid ""
+" vma:\t\tBegin Prolog Function Flags Exception EH\n"
+" \t\tAddress Length Length 32b exc Handler Data\n"
+msgstr ""
+" vma:\t\tStart Prolog Funktion Flag Undtagelse EH\n"
+" \t\tAdresse Længde Længde 32b exc Håndtering Data\n"
+
+#: peigen.c:1929 pepigen.c:1929 pex64igen.c:1929
+#, c-format
+msgid ""
+"\n"
+"\n"
+"PE File Base Relocations (interpreted .reloc section contents)\n"
+msgstr ""
+"\n"
+"\n"
+"PE-filbaserelokeringer (tolket indhold i .reloc-sektionen)\n"
+
+#: peigen.c:1958 pepigen.c:1958 pex64igen.c:1958
+#, c-format
+msgid ""
+"\n"
+"Virtual Address: %08lx Chunk size %ld (0x%lx) Number of fixups %ld\n"
+msgstr ""
+"\n"
+"Virtuel adresse: %08lx Områdesstørrelse %ld (0x%lx) Antal rettelser %ld\n"
+
+#: peigen.c:1971 pepigen.c:1971 pex64igen.c:1971
+#, c-format
+msgid "\treloc %4d offset %4x [%4lx] %s"
+msgstr "\trelokering %4d afstand %4x [%4lx] %s"
+
+#. The MS dumpbin program reportedly ands with 0xff0f before
+#. printing the characteristics field. Not sure why. No reason to
+#. emulate it here.
+#: peigen.c:2010 pepigen.c:2010 pex64igen.c:2010
+#, c-format
+msgid ""
+"\n"
+"Characteristics 0x%x\n"
+msgstr ""
+"\n"
+"Karakteristik 0x%x\n"
+
+#: peigen.c:2310 pepigen.c:2310 pex64igen.c:2310
+msgid "%B: unable to fill in DataDictionary[1] because .idata$2 is missing"
+msgstr "%B: kan ikke udfylde DataDictionary[1] fordi .idata$2 mangler"
+
+#: peigen.c:2330 pepigen.c:2330 pex64igen.c:2330
+msgid "%B: unable to fill in DataDictionary[1] because .idata$4 is missing"
+msgstr "%B: kan ikke udfylde DataDictionary[1] fordi .idata$4 mangler"
+
+#: peigen.c:2351 pepigen.c:2351 pex64igen.c:2351
+msgid "%B: unable to fill in DataDictionary[12] because .idata$5 is missing"
+msgstr "%B: kan ikke udfylde DataDictionary[12] fordi .idata$5 mangler"
+
+#: peigen.c:2371 pepigen.c:2371 pex64igen.c:2371
+msgid "%B: unable to fill in DataDictionary[PE_IMPORT_ADDRESS_TABLE (12)] because .idata$6 is missing"
+msgstr "%B: kan ikke udfylde DataDictionary[PE_IMPORT_ADDRESS_TABLE (12)], da .idata$6 mangler"
+
+#: peigen.c:2413 pepigen.c:2413 pex64igen.c:2413
+msgid "%B: unable to fill in DataDictionary[PE_IMPORT_ADDRESS_TABLE(12)] because .idata$6 is missing"
+msgstr "%B: kan ikke udfylde DataDictionary[PE_IMPORT_ADDRESS_TABLE(12)], da .idata$6 mangler"
+
+#: peigen.c:2436 pepigen.c:2436 pex64igen.c:2436
+msgid "%B: unable to fill in DataDictionary[9] because __tls_used is missing"
+msgstr "%B: kan ikke udfylde DataDictionary[9], da __tls_used mangler"
+
+# src/menus.c:341
+#~ msgid "Missing IHCONST"
+#~ msgstr "IHCONST mangler"
+
+# src/menus.c:341
+#~ msgid "Missing IHIHALF"
+#~ msgstr "IHIHALF mangler"
+
+#~ msgid "missing IHCONST reloc"
+#~ msgstr "IHCONST-relokering mangler"
+
+#~ msgid "missing IHIHALF reloc"
+#~ msgstr "IHIHALF-relokering mangler"
+
+#~ msgid " first occurrence: %s: arm call to thumb"
+#~ msgstr " første forekomst: %s: arm-kald til thumb"
+
+#~ msgid " first occurrence: %s: thumb call to arm"
+#~ msgstr " første forekomst: %s: thumb-kald til arm"
+
+#~ msgid " consider relinking with --support-old-code enabled"
+#~ msgstr " overvej omlænkning med --support-old-code aktiveret"
+
+#~ msgid "reloc against unsupported section"
+#~ msgstr "relokering mod sektion som ikke understøttes"
+
+#~ msgid "Dwarf Error: DW_FORM_strp offset (%lu) greater than or equal to .debug_str size (%lu)."
+#~ msgstr "Dwarf-fejl: DW_FORM_strp-afstanden (%lu) større end eller lig med størrelsen på .debug_str (%lu)."
+
+#~ msgid "Dwarf Error: Can't find .debug_abbrev section."
+#~ msgstr "Dwarf-fejl: Kan ikke finde sektionen .debug_abbrev."
+
+#~ msgid "Dwarf Error: Abbrev offset (%lu) greater than or equal to .debug_abbrev size (%lu)."
+#~ msgstr "Dwarf-fejl: Forkortelsesafstanden (%lu) større end eller lig med størrelsen .debug_abbrev (%lu)."
+
+#~ msgid "%s: warning: unresolvable relocation against symbol `%s' from %s section"
+#~ msgstr "%s: advarsel: uløselig relokering mod symbol \"%s\" fra sektionen %s"
+
+#~ msgid "%s: Not enough room for program headers (allocated %u, need %u)"
+#~ msgstr "%s: Ikke tilstrækkeligt med plads for programhoveder (allokerede %u, behøver %u)"
+
+#~ msgid "Error: First section in segment (%s) starts at 0x%x whereas the segment starts at 0x%x"
+#~ msgstr "Fejl: Første sektion i segmentet (%s) begynder ved 0x%x mens segmentet begynder ved 0x%x"
+
+#~ msgid "%s: warning: unresolvable relocation %d against symbol `%s' from %s section"
+#~ msgstr "%s: advarsel: uløselig relokering %d mod symbol \"%s\" fra sektionen %s"
+
+#~ msgid "ERROR: %s is compiled for EABI version %d, whereas %s is compiled for version %d"
+#~ msgstr "FEJL: %s er oversat for EABI version %d, mens %s er oversat for version %d"
+
+#~ msgid "%s: unresolvable relocation %s against symbol `%s' from %s section"
+#~ msgstr "%s: uløselig relokering %s mod symbol \"%s\" fra sektionen %s"
+
+#~ msgid "%s: relocation %s should not be used when making a shared object; recompile with -fPIC"
+#~ msgstr "%s: relokeringen %s bør ikke bruges når et delt objekt oprettes; genoversæt med -fPIC"
+
+#~ msgid "%s(%s+0x%lx): fixing %s"
+#~ msgstr "%s(%s+0x%lx): retter %s"
+
+#~ msgid " [m68000]"
+#~ msgstr " [m68000]"
+
+#~ msgid "Linking mips16 objects into %s format is not supported"
+#~ msgstr "Lænkning af mips16-objekter til %s-format understøttes ikke"
+
+#~ msgid "%s: Unknown special linker type %d"
+#~ msgstr "%s: Ukendt speciallænkertype %d"
+
+#~ msgid "v850ea architecture"
+#~ msgstr "v850ea-arkitektur"
+
+#~ msgid "%s: check_relocs: unhandled reloc type %d"
+#~ msgstr "%s: check_relocs: uhåndteret relokeringstype %d"
+
+#~ msgid "%s: Section %s is too large to add hole of %ld bytes"
+#~ msgstr "%s: Sektionen %s er for stor til at stoppe hul med %ld byte i"
+
+#~ msgid "Error: out of memory"
+#~ msgstr "Fejl: ikke mere hukommelse"
+
+#~ msgid "warning: relocation against removed section; zeroing"
+#~ msgstr "advarsel: relokering mod fjernet sektion; nulstiller"
+
+#~ msgid "local symbols in discarded section %s"
+#~ msgstr "lokale symboler i bortkastet sektion %s"
+
+#~ msgid "%s: %s+0x%lx: jump to stub routine which is not jal"
+#~ msgstr "%s: %s+0x%lx: hop til stubrutine som ikke er jal"
+
+#~ msgid "%s: ISA mismatch (-mips%d) with previous modules (-mips%d)"
+#~ msgstr "%s: ISA (-mips%d) passer ikke med tidligere moduler (-mips%d)"
+
+#~ msgid "%s: ISA mismatch (%d) with previous modules (%d)"
+#~ msgstr "%s: ISA (%d) passer ikke med tidligere moduler (%d)"
+
+#~ msgid " [mips1]"
+#~ msgstr " [mips1]"
+
+#~ msgid " [mips2]"
+#~ msgstr " [mips2]"
+
+#~ msgid " [mips3]"
+#~ msgstr " [mips3]"
+
+#~ msgid " [mips4]"
+#~ msgstr " [mips4]"
+
+#~ msgid " [mips5]"
+#~ msgstr " [mips5]"
+
+#~ msgid " [mips32]"
+#~ msgstr " [mips32]"
+
+#~ msgid " [mips64]"
+#~ msgstr " [mips64]"
+
+#~ msgid " [mips16]"
+#~ msgstr " [mips16]"
+
+#~ msgid " [32bitmode]"
+#~ msgstr " [32-bittilstand]"
+
+#~ msgid "bfd_make_section (%s) failed"
+#~ msgstr "bfd_make_section (%s) mislykkedes"
+
+#~ msgid "bfd_set_section_flags (%s, %x) failed"
+#~ msgstr "bfd_set_section_flags (%s, %x) mislykkedes"
+
+#~ msgid "Size mismatch section %s=%lx, %s=%lx"
+#~ msgstr "Størrelsen passer ikke på sektion %s=%lx, %s=%lx"
+
+#~ msgid "unknown gsd/egsd subtype %d"
+#~ msgstr "ukendt gsd/egsd-undertype %d"
+
+#~ msgid "failed to enter %s"
+#~ msgstr "mislykkedes med at gå ind i %s"
+
+#~ msgid "No Mem !"
+#~ msgstr "Ingen hukommelse!"
+
+#~ msgid "%s: no symbol \"%s\""
+#~ msgstr "%s: intet symbol \"%s\""
+
+#~ msgid "reserved STO cmd %d"
+#~ msgstr "reserveret STO-kommando %d"
+
+#~ msgid "reserved OPR cmd %d"
+#~ msgstr "reserveret OPR-kommando %d"
+
+#~ msgid "reserved CTL cmd %d"
+#~ msgstr "reserveret CTL-kommando %d"
+
+#~ msgid "stack-from-image not implemented"
+#~ msgstr "stack-from-image er ikke implementeret"
+
+#~ msgid "stack-entry-mask not fully implemented"
+#~ msgstr "stack-entry-mask er ikke helt implementeret"
+
+#~ msgid "stack-local-symbol not fully implemented"
+#~ msgstr "stack-local-symbol er ikke helt implementeret"
+
+#~ msgid "stack-literal not fully implemented"
+#~ msgstr "stack-literal er ikke helt implementeret"
+
+#~ msgid "stack-local-symbol-entry-point-mask not fully implemented"
+#~ msgstr "stack-local-symbol-entry-point-mask er ikke helt implementeret"
+
+#~ msgid "obj code %d not found"
+#~ msgstr "objektkode %d kunne ikke findes"
+
+#~ msgid "%s: dynamic relocation against speculation fixup"
+#~ msgstr "%s: dynamisk relokering uden spekulationsrettelser"
+
+#~ msgid "%s: speculation fixup against undefined weak symbol"
+#~ msgstr "%s: spekulationsfix mod udefineret svagt symbol"
+
+#~ msgid "%s: reloc overflow 1: 0x%lx > 0xffff"
+#~ msgstr "%s: relokering giver overløb 1: 0x%lx > 0xffff"
diff --git a/bfd/po/es.gmo b/bfd/po/es.gmo
new file mode 100644
index 0000000..d31fab0
--- /dev/null
+++ b/bfd/po/es.gmo
Binary files differ
diff --git a/bfd/po/es.po b/bfd/po/es.po
new file mode 100644
index 0000000..cbdfe90
--- /dev/null
+++ b/bfd/po/es.po
@@ -0,0 +1,6693 @@
+# Mensajes en español para bfd 2.22.90.
+# Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
+# This file is distributed under the same license as the binutils package.
+# Cristian Othón Martínez Vera <cfuga@cfuga.mx>, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: bfd 2.22.90\n"
+"Report-Msgid-Bugs-To: bug-binutils@gnu.org\n"
+"POT-Creation-Date: 2011-10-25 11:58+0100\n"
+"PO-Revision-Date: 2012-07-27 12:29-0500\n"
+"Last-Translator: Cristian Othón Martínez Vera <cfuga@cfuga.mx>\n"
+"Language-Team: Spanish <es@li.org>\n"
+"Language: es\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: aout-adobe.c:127
+msgid "%B: Unknown section type in a.out.adobe file: %x\n"
+msgstr "%B: Tipo de sección desconocido en el fichero a.out.adobe: %x\n"
+
+#: aout-cris.c:199
+#, c-format
+msgid "%s: Invalid relocation type exported: %d"
+msgstr "%s: Se exportó un tipo de reubicación inválido: %d"
+
+#: aout-cris.c:242
+msgid "%B: Invalid relocation type imported: %d"
+msgstr "%B: Se importó un tipo de reubicación inválido: %d"
+
+#: aout-cris.c:253
+msgid "%B: Bad relocation record imported: %d"
+msgstr "%B: Se importó un registro de reubicación erróneo: %d"
+
+#: aoutx.h:1273 aoutx.h:1611
+#, c-format
+msgid "%s: can not represent section `%s' in a.out object file format"
+msgstr "%s: no se puede representar la sección `%s' en el formato de fichero objeto a.out"
+
+#: aoutx.h:1577
+#, c-format
+msgid "%s: can not represent section for symbol `%s' in a.out object file format"
+msgstr "%s: no se puede representar la sección para el símbolo `%s' en el formato de fichero objeto a.out"
+
+#: aoutx.h:1579 vms-alpha.c:7671
+msgid "*unknown*"
+msgstr "*desconocido*"
+
+#: aoutx.h:4018 aoutx.h:4344
+msgid "%P: %B: unexpected relocation type\n"
+msgstr "%P: %B: tipo de reubicación inesperado\n"
+
+#: aoutx.h:5375
+#, c-format
+msgid "%s: relocatable link from %s to %s not supported"
+msgstr "%s: no se admite el enlace reubicable de %s a %s"
+
+#: archive.c:2203
+msgid "Warning: writing archive was slow: rewriting timestamp\n"
+msgstr "Aviso: la escritura del fichero fue lenta: se reescribe la marca de tiempo\n"
+
+# ¡Uff! Si utilizáramos file=archivo, esta traducción sería imposible. cfuga
+#: archive.c:2491
+msgid "Reading archive file mod timestamp"
+msgstr "Se lee la marca de tiempo modificada del fichero en el archivo"
+
+#: archive.c:2515
+msgid "Writing updated armap timestamp"
+msgstr "Se escribe la marca de tiempo actualizada de armap"
+
+#: bfd.c:398
+msgid "No error"
+msgstr "No hay error"
+
+#: bfd.c:399
+msgid "System call error"
+msgstr "Error en la llamada al sistema"
+
+#: bfd.c:400
+msgid "Invalid bfd target"
+msgstr "Objetivo bfd inválido"
+
+#: bfd.c:401
+msgid "File in wrong format"
+msgstr "Fichero en formato erróneo"
+
+#: bfd.c:402
+msgid "Archive object file in wrong format"
+msgstr "Archivo de ficheros objeto en formato erróneo"
+
+#: bfd.c:403
+msgid "Invalid operation"
+msgstr "Operación inválida"
+
+#: bfd.c:404
+msgid "Memory exhausted"
+msgstr "Memoria agotada"
+
+#: bfd.c:405
+msgid "No symbols"
+msgstr "No hay símbolos"
+
+#: bfd.c:406
+msgid "Archive has no index; run ranlib to add one"
+msgstr "El archivo no tiene índice; ejecute ranlib para agregar uno"
+
+#: bfd.c:407
+msgid "No more archived files"
+msgstr "No hay más ficheros archivados"
+
+#: bfd.c:408
+msgid "Malformed archive"
+msgstr "Archivo malformado"
+
+#: bfd.c:409
+msgid "File format not recognized"
+msgstr "No se reconoce el formato del fichero"
+
+#: bfd.c:410
+msgid "File format is ambiguous"
+msgstr "El formato del fichero es ambiguo"
+
+#: bfd.c:411
+msgid "Section has no contents"
+msgstr "La sección no tiene contenido"
+
+#: bfd.c:412
+msgid "Nonrepresentable section on output"
+msgstr "Sección no representable en la salida"
+
+#: bfd.c:413
+msgid "Symbol needs debug section which does not exist"
+msgstr "Un símbolo requiere de una sección de depuración, la cual no existe"
+
+#: bfd.c:414
+msgid "Bad value"
+msgstr "Valor erróneo"
+
+#: bfd.c:415
+msgid "File truncated"
+msgstr "Fichero truncado"
+
+#: bfd.c:416
+msgid "File too big"
+msgstr "El fichero es demasiado grande"
+
+#: bfd.c:417
+#, c-format
+msgid "Error reading %s: %s"
+msgstr "Error al leer %s: %s"
+
+#: bfd.c:418
+msgid "#<Invalid error code>"
+msgstr "#<Código de error inválido>"
+
+#: bfd.c:945
+#, c-format
+msgid "BFD %s assertion fail %s:%d"
+msgstr "falló la aseveración BFD %s %s:%d"
+
+#: bfd.c:957
+#, c-format
+msgid "BFD %s internal error, aborting at %s line %d in %s\n"
+msgstr "error interno de BFD %s, se aborta en %s línea %d en %s\n"
+
+#: bfd.c:961
+#, c-format
+msgid "BFD %s internal error, aborting at %s line %d\n"
+msgstr "error interno de BFD %s, se aborta en %s línea %d\n"
+
+#: bfd.c:963
+msgid "Please report this bug.\n"
+msgstr "Por favor reporte este bicho.\n"
+
+#: bfdwin.c:206
+#, c-format
+msgid "not mapping: data=%lx mapped=%d\n"
+msgstr "no se mapea: datos=%lx mapeados%d\n"
+
+#: bfdwin.c:209
+#, c-format
+msgid "not mapping: env var not set\n"
+msgstr "no se mapea: no se estableció la variable de ambiente\n"
+
+#: binary.c:271
+#, c-format
+msgid "Warning: Writing section `%s' to huge (ie negative) file offset 0x%lx."
+msgstr "Aviso: Se escribe la sección `%s' a un desplazamiento de fichero grande (pe negativo) 0x%lx."
+
+#: bout.c:1146 elf-m10300.c:2063 elf32-avr.c:1654 elf32-frv.c:5734
+#: elfxx-sparc.c:2802 reloc.c:6115 reloc16.c:162 elf32-ia64.c:360
+#: elf64-ia64.c:360
+msgid "%P%F: --relax and -r may not be used together\n"
+msgstr "%P%F: --relax y -r no se pueden usar juntos\n"
+
+#: cache.c:227
+msgid "reopening %B: %s\n"
+msgstr "se reabre %B: %s\n"
+
+#: coff-alpha.c:491
+msgid ""
+"%B: Cannot handle compressed Alpha binaries.\n"
+" Use compiler flags, or objZ, to generate uncompressed binaries."
+msgstr ""
+"%B: No se pueden manejar binarios Alpha comprimidos.\n"
+" Use las opciones del compilador, o objZ, para generar binarios sin comprimir."
+
+#: coff-alpha.c:648
+msgid "%B: unknown/unsupported relocation type %d"
+msgstr "%B: tipo de reubicación %d desconocida/no admitida"
+
+#: coff-alpha.c:900 coff-alpha.c:937 coff-alpha.c:2025 coff-mips.c:1003
+msgid "GP relative relocation used when GP not defined"
+msgstr "se usó una reubicación relativa a GP cuando GP no estaba definido"
+
+#: coff-alpha.c:1502
+msgid "using multiple gp values"
+msgstr "se usan valores múltiples de gp"
+
+#: coff-alpha.c:1561
+msgid "%B: unsupported relocation: ALPHA_R_GPRELHIGH"
+msgstr "%B: tipo de reubicación no admitida: ALPHA_R_GPRELHIGH"
+
+#: coff-alpha.c:1568
+msgid "%B: unsupported relocation: ALPHA_R_GPRELLOW"
+msgstr "%B: tipo de reubicación no admitida: ALPHA_R_GPRELLOW"
+
+#: coff-alpha.c:1575 elf32-m32r.c:2484 elf64-alpha.c:4074 elf64-alpha.c:4224
+#: elf32-ia64.c:3839 elf64-ia64.c:3839
+msgid "%B: unknown relocation type %d"
+msgstr "%B: tipo de reubicación %d desconocido"
+
+#: coff-arm.c:1038
+#, c-format
+msgid "%B: unable to find THUMB glue '%s' for `%s'"
+msgstr "%B: no se puede encontrar el pegamento THUMB '%s' para `%s'"
+
+#: coff-arm.c:1067
+#, c-format
+msgid "%B: unable to find ARM glue '%s' for `%s'"
+msgstr "%B: no se puede encontrar el pegamento ARM '%s' para `%s'"
+
+#: coff-arm.c:1369 elf32-arm.c:7023
+#, c-format
+msgid ""
+"%B(%s): warning: interworking not enabled.\n"
+" first occurrence: %B: arm call to thumb"
+msgstr ""
+"%B(%s): aviso: no se activó la interoperabilidad.\n"
+" primer suceso: %B: llamada arm a thumb"
+
+#: coff-arm.c:1459
+#, c-format
+msgid ""
+"%B(%s): warning: interworking not enabled.\n"
+" first occurrence: %B: thumb call to arm\n"
+" consider relinking with --support-old-code enabled"
+msgstr ""
+"%B(%s): aviso: no se activó la interoperabilidad.\n"
+" primer suceso: %B: llamada thumb a arm\n"
+" considere reenlazar con --support-old-code activado"
+
+#: coff-arm.c:1754 coff-tic80.c:695 cofflink.c:3081
+msgid "%B: bad reloc address 0x%lx in section `%A'"
+msgstr "%B: dirección de reubicación 0x%lx errónea en la sección `%A'"
+
+#: coff-arm.c:2079
+msgid "%B: illegal symbol index in reloc: %d"
+msgstr "%B: índice de símbolos ilegal en la reubicación: %d"
+
+#: coff-arm.c:2210
+#, c-format
+msgid "error: %B is compiled for APCS-%d, whereas %B is compiled for APCS-%d"
+msgstr "error: %B está compilado para APCS-%d, mientras que %B está compilado para APCS-%d"
+
+#: coff-arm.c:2226 elf32-arm.c:15621
+#, c-format
+msgid "error: %B passes floats in float registers, whereas %B passes them in integer registers"
+msgstr "error: %B pasa números de coma flotante en registros de coma flotante, mientras que %B los pasa en registros enteros"
+
+#: coff-arm.c:2229 elf32-arm.c:15625
+#, c-format
+msgid "error: %B passes floats in integer registers, whereas %B passes them in float registers"
+msgstr "error: %B pasa números de coma flotante en registros enteros, mientras que %B los pasa en registros de coma flotante"
+
+#: coff-arm.c:2243
+#, c-format
+msgid "error: %B is compiled as position independent code, whereas target %B is absolute position"
+msgstr "error: %B está compilado como código independiente de posición, mientras que el objetivo %B es de posición absoluta"
+
+#: coff-arm.c:2246
+#, c-format
+msgid "error: %B is compiled as absolute position code, whereas target %B is position independent"
+msgstr "error: %B está compilado como código de posición absoluta, mientras que el objetivo %B es independiente de posición"
+
+#: coff-arm.c:2274 elf32-arm.c:15690
+#, c-format
+msgid "Warning: %B supports interworking, whereas %B does not"
+msgstr "Aviso: %B admite interoperabilidad, mientras que %B no"
+
+#: coff-arm.c:2277 elf32-arm.c:15696
+#, c-format
+msgid "Warning: %B does not support interworking, whereas %B does"
+msgstr "Aviso: %B no admite interoperabilidad, mientras que %B sí"
+
+#: coff-arm.c:2301
+#, c-format
+msgid "private flags = %x:"
+msgstr "opciones privadas = %x:"
+
+#: coff-arm.c:2309 elf32-arm.c:11806
+#, c-format
+msgid " [floats passed in float registers]"
+msgstr "[números de coma flotante pasados en registros de coma flotante]"
+
+#: coff-arm.c:2311
+#, c-format
+msgid " [floats passed in integer registers]"
+msgstr "[números de coma flotante pasados en registros enteros]"
+
+#: coff-arm.c:2314 elf32-arm.c:11809
+#, c-format
+msgid " [position independent]"
+msgstr "[independiente de posición]"
+
+#: coff-arm.c:2316
+#, c-format
+msgid " [absolute position]"
+msgstr "[posición absoluta]"
+
+#: coff-arm.c:2320
+#, c-format
+msgid " [interworking flag not initialised]"
+msgstr "[no se inicializó la opción de interoperabilidad]"
+
+#: coff-arm.c:2322
+#, c-format
+msgid " [interworking supported]"
+msgstr "[admite interoperabilidad]"
+
+#: coff-arm.c:2324
+#, c-format
+msgid " [interworking not supported]"
+msgstr "[no admite interoperabilidad]"
+
+#: coff-arm.c:2370 elf32-arm.c:10841
+#, c-format
+msgid "Warning: Not setting interworking flag of %B since it has already been specified as non-interworking"
+msgstr "Aviso: No se establece la opción de interoperabilidad de %B ya que se había especificado con anterioridad como no interoperable"
+
+#: coff-arm.c:2374 elf32-arm.c:10845
+#, c-format
+msgid "Warning: Clearing the interworking flag of %B due to outside request"
+msgstr "Aviso: Se limpia la opción de interoperabilidad de %B debido a una petición externa"
+
+#: coff-h8300.c:1122
+#, c-format
+msgid "cannot handle R_MEM_INDIRECT reloc when using %s output"
+msgstr "no se puede manejar la reubicación R_MEM_INDIRECT cuando se utiliza la salida %s"
+
+#: coff-i860.c:147
+#, c-format
+msgid "relocation `%s' not yet implemented"
+msgstr "la reubicación `%s' aún no se implementa"
+
+#: coff-i860.c:605 coff-tic54x.c:398 coffcode.h:5198
+msgid "%B: warning: illegal symbol index %ld in relocs"
+msgstr "%B: aviso: índice de símbolos %ld ilegal en reubicaciones"
+
+#: coff-i960.c:144 coff-i960.c:507
+msgid "uncertain calling convention for non-COFF symbol"
+msgstr "convención de llamada incierta para un símbolo que no es COFF"
+
+#: coff-m68k.c:506 elf32-bfin.c:5690 elf32-cr16.c:2897 elf32-m68k.c:4677
+msgid "unsupported reloc type"
+msgstr "no se admite el tipo de reubicación"
+
+#: coff-mips.c:688 elf32-mips.c:1516 elf32-score.c:431 elf32-score7.c:330
+#: elf64-mips.c:2618 elfn32-mips.c:2431
+msgid "GP relative relocation when _gp not defined"
+msgstr "reubicación relativa a GP cuando _gp no está definido"
+
+#: coff-or32.c:229
+msgid "Unrecognized reloc"
+msgstr "No se reconoce la reubicación"
+
+#: coff-rs6000.c:2720
+#, c-format
+msgid "%s: unsupported relocation type 0x%02x"
+msgstr "%s: no se admite el tipo de reubicación 0x%02x"
+
+#: coff-rs6000.c:2805
+#, c-format
+msgid "%s: TOC reloc at 0x%x to symbol `%s' with no TOC entry"
+msgstr "%s: reubicación de TOC en 0x%x al símbolo `%s' sin entrada TOC"
+
+#: coff-rs6000.c:3556 coff64-rs6000.c:2111
+msgid "%B: symbol `%s' has unrecognized smclas %d"
+msgstr "%B: el símbolo `%s' tiene smclas %d que no se reconoce"
+
+#: coff-sh.c:521
+#, c-format
+msgid "SH Error: unknown reloc type %d"
+msgstr "Error SH: tipo de reubicación %d desconocido"
+
+#: coff-tic4x.c:195 coff-tic54x.c:299 coff-tic80.c:458
+#, c-format
+msgid "Unrecognized reloc type 0x%x"
+msgstr "No se reconoce el tipo de reubicación 0x%x"
+
+#: coff-tic4x.c:240
+#, c-format
+msgid "%s: warning: illegal symbol index %ld in relocs"
+msgstr "%s: aviso: índice de símbolos %ld ilegal en reubicaciones"
+
+#: coff-w65.c:367
+#, c-format
+msgid "ignoring reloc %s\n"
+msgstr "se descarta la reubicación %s\n"
+
+#: coffcode.h:997
+msgid "%B: warning: COMDAT symbol '%s' does not match section name '%s'"
+msgstr "%B: aviso: el símbolo COMDAT '%s' no coincide con el nombre de sección '%s'"
+
+#. Generate a warning message rather using the 'unhandled'
+#. variable as this will allow some .sys files generate by
+#. other toolchains to be processed. See bugzilla issue 196.
+#: coffcode.h:1221
+msgid "%B: Warning: Ignoring section flag IMAGE_SCN_MEM_NOT_PAGED in section %s"
+msgstr "%B: Aviso: Se descarta la opción de sección IMAGE_SCN_MEM_NOT_PAGED en la sección %s"
+
+#: coffcode.h:1288
+msgid "%B (%s): Section flag %s (0x%x) ignored"
+msgstr "%B (%s): Se descarta la opción de sección %s (0x%x)"
+
+#: coffcode.h:2430
+#, c-format
+msgid "Unrecognized TI COFF target id '0x%x'"
+msgstr "No se reconoce el id de objetivo COFF TI '0x%x'"
+
+#: coffcode.h:2744
+msgid "%B: reloc against a non-existant symbol index: %ld"
+msgstr "%B: reubicación contra un índice de símbolo que no existe: %ld"
+
+#: coffcode.h:3302
+msgid "%B: too many sections (%d)"
+msgstr "%B: Demasiadas secciones (%d)"
+
+#: coffcode.h:3718
+msgid "%B: section %s: string table overflow at offset %ld"
+msgstr "%B: sección %s: desbordamiento de tabla de cadenas en el desplazamiento %ld"
+
+#: coffcode.h:4523
+msgid "%B: warning: line number table read failed"
+msgstr "%B: aviso: falló la lectura de tabla de números de línea"
+
+#: coffcode.h:4553
+msgid "%B: warning: illegal symbol index %ld in line numbers"
+msgstr "%B: aviso: índice de símbolos %ld ilegal en los números de línea"
+
+#: coffcode.h:4567
+msgid "%B: warning: duplicate line number information for `%s'"
+msgstr "%B: aviso: información de números de línea duplicada para `%s'"
+
+#: coffcode.h:4967
+msgid "%B: Unrecognized storage class %d for %s symbol `%s'"
+msgstr "%B: No se reconoce la clase de almacenamiento %d para %s símbolo `%s'"
+
+#: coffcode.h:5093
+msgid "warning: %B: local symbol `%s' has no section"
+msgstr "aviso: %B: el símbolo local `%s' no tiene sección"
+
+#: coffcode.h:5237
+msgid "%B: illegal relocation type %d at address 0x%lx"
+msgstr "%B: tipo de reubicación %d ilegal en la dirección 0x%lx"
+
+#: coffgen.c:1595
+msgid "%B: bad string table size %lu"
+msgstr "%B: tamaño de tabla de cadenas %lu erróneo"
+
+#: coffgen.c:2500 elflink.c:12689 linker.c:3122
+msgid "%F%P: already_linked_table: %E\n"
+msgstr "%F%P: already_linked_table: %E\n"
+
+#: cofflink.c:533 elflink.c:4323
+msgid "Warning: type of symbol `%s' changed from %d to %d in %B"
+msgstr "Aviso: el tipo del símbolo `%s' cambió de %d a %d en %B"
+
+#: cofflink.c:2329
+msgid "%B: relocs in section `%A', but it has no contents"
+msgstr "%B: reubicaciones en la sección `%A', pero no tiene contenido"
+
+#: cofflink.c:2391 elflink.c:9545
+msgid "%X`%s' referenced in section `%A' of %B: defined in discarded section `%A' of %B\n"
+msgstr "%X`%s' referido en la sección `%A' de %B: se definió en la sección descartada `%A' de %B\n"
+
+#: cofflink.c:2690 coffswap.h:826
+#, c-format
+msgid "%s: %s: reloc overflow: 0x%lx > 0xffff"
+msgstr "%s: %s: desbordamiento de reubicación: 0x%lx > 0xffff"
+
+#: cofflink.c:2699 coffswap.h:812
+#, c-format
+msgid "%s: warning: %s: line number overflow: 0x%lx > 0xffff"
+msgstr "%s: aviso: %s: desbordamiento de número de línea: 0x%lx > 0xffff"
+
+#: cpu-arm.c:189 cpu-arm.c:200
+msgid "error: %B is compiled for the EP9312, whereas %B is compiled for XScale"
+msgstr "error: %B está compilado para el EP9312, mientras que %B está compilado para XScale"
+
+#: cpu-arm.c:333
+#, c-format
+msgid "warning: unable to update contents of %s section in %s"
+msgstr "aviso: no se puede actualizar el contenido de la sección %s en %s"
+
+#: dwarf2.c:496
+#, c-format
+msgid "Dwarf Error: Can't find %s section."
+msgstr "Error de Dwarf: No se puede encontrar la sección %s."
+
+#: dwarf2.c:525
+#, c-format
+msgid "Dwarf Error: Offset (%lu) greater than or equal to %s size (%lu)."
+msgstr "Error de Dwarf: El desplazamiento (%lu) es mayor que o igual que el tamaño de %s (%lu)."
+
+#: dwarf2.c:949
+#, c-format
+msgid "Dwarf Error: Invalid or unhandled FORM value: %u."
+msgstr "Error de Dwarf: Valor de FORM sin manejar o inválido: %u."
+
+#: dwarf2.c:1200
+msgid "Dwarf Error: mangled line number section (bad file number)."
+msgstr "Error de Dwarf: sección de números de línea revuelta (número de fichero erróneo)."
+
+#: dwarf2.c:1453
+#, c-format
+msgid "Dwarf Error: Unhandled .debug_line version %d."
+msgstr "Error de Dwarf: .debug_line versión %d sin manejar."
+
+#: dwarf2.c:1475
+msgid "Dwarf Error: Invalid maximum operations per instruction."
+msgstr "Error de Dwarf: Máximo de operaciones por instrucción inválido."
+
+#: dwarf2.c:1662
+msgid "Dwarf Error: mangled line number section."
+msgstr "Error de Dwarf: sección de números de línea revuelta."
+
+#: dwarf2.c:1989 dwarf2.c:2109 dwarf2.c:2394
+#, c-format
+msgid "Dwarf Error: Could not find abbrev number %u."
+msgstr "Error de Dwarf: No se puede encontrar el número de abreviatura %u."
+
+#: dwarf2.c:2355
+#, c-format
+msgid "Dwarf Error: found dwarf version '%u', this reader only handles version 2, 3 and 4 information."
+msgstr "Error de Dwarf: se encontró la versión de dwarf '%u', este lector solamente maneja información de las versiones 2, 3 y 4."
+
+#: dwarf2.c:2362
+#, c-format
+msgid "Dwarf Error: found address size '%u', this reader can not handle sizes greater than '%u'."
+msgstr "Error de Dwarf: se encontró el tamaño de dirección '%u', este lector no puede manejar tamaños más grandes que '%u'."
+
+#: dwarf2.c:2385
+#, c-format
+msgid "Dwarf Error: Bad abbrev number: %u."
+msgstr "Error de Dwarf: Número de abreviación erróneo: %u."
+
+#: ecoff.c:1239
+#, c-format
+msgid "Unknown basic type %d"
+msgstr "Tipo básico %d desconocido"
+
+#: ecoff.c:1496
+#, c-format
+msgid ""
+"\n"
+" End+1 symbol: %ld"
+msgstr ""
+"\n"
+" Símbolo final+1: %ld"
+
+#: ecoff.c:1503 ecoff.c:1506
+#, c-format
+msgid ""
+"\n"
+" First symbol: %ld"
+msgstr ""
+"\n"
+" Primer símbolo: %ld"
+
+#: ecoff.c:1518
+#, c-format
+msgid ""
+"\n"
+" End+1 symbol: %-7ld Type: %s"
+msgstr ""
+"\n"
+" Símbolo final+1: %-7ld Tipo: %s"
+
+#: ecoff.c:1525
+#, c-format
+msgid ""
+"\n"
+" Local symbol: %ld"
+msgstr ""
+"\n"
+" Símbolo local: %ld"
+
+#: ecoff.c:1533
+#, c-format
+msgid ""
+"\n"
+" struct; End+1 symbol: %ld"
+msgstr ""
+"\n"
+" struct; símbolo final+1: %ld"
+
+#: ecoff.c:1538
+#, c-format
+msgid ""
+"\n"
+" union; End+1 symbol: %ld"
+msgstr ""
+"\n"
+" union; símbolo final+1: %ld"
+
+#: ecoff.c:1543
+#, c-format
+msgid ""
+"\n"
+" enum; End+1 symbol: %ld"
+msgstr ""
+"\n"
+" enum; símbolo final+1: %ld"
+
+#: ecoff.c:1549
+#, c-format
+msgid ""
+"\n"
+" Type: %s"
+msgstr ""
+"\n"
+" Tipo: %s"
+
+#: elf-attrs.c:569
+msgid "error: %B: Object has vendor-specific contents that must be processed by the '%s' toolchain"
+msgstr "error: %B: El objeto tiene contenido específico del vendedor que se debe procesar con la cadena de compilación '%s'"
+
+#: elf-attrs.c:578
+msgid "error: %B: Object tag '%d, %s' is incompatible with tag '%d, %s'"
+msgstr "error: %B: La etiqueta de objeto '%d, %s' es incompatible con la etiqueta '%d, %s'"
+
+#: elf-eh-frame.c:917
+msgid "%P: error in %B(%A); no .eh_frame_hdr table will be created.\n"
+msgstr "%P: error en %B(%A); no se creará la tabla .eh_frame_hdr.\n"
+
+#: elf-eh-frame.c:1189
+msgid "%P: fde encoding in %B(%A) prevents .eh_frame_hdr table being created.\n"
+msgstr "%P: la codificación fde en %B(%A) previene la creación de la tabla .eh_frame_hdr.\n"
+
+#: elf-eh-frame.c:1605
+msgid "%P: DW_EH_PE_datarel unspecified for this architecture.\n"
+msgstr "%P: DW_EH_PE_datarel sin especificar para esta arquitectura.\n"
+
+#: elf-ifunc.c:179
+msgid "%F%P: dynamic STT_GNU_IFUNC symbol `%s' with pointer equality in `%B' can not be used when making an executable; recompile with -fPIE and relink with -pie\n"
+msgstr "%F%P: el símbolo STT_GNU_IFUNC dinámico `%s' con igualdad de puntero en `%B' no se puede usar al hacer un ejecutable; recompile con -fPIE y reenlace con -pie\n"
+
+#: elf-m10200.c:450 elf-m10300.c:1563 elf32-avr.c:1221 elf32-bfin.c:3213
+#: elf32-cr16.c:1482 elf32-cr16c.c:780 elf32-cris.c:2081 elf32-crx.c:922
+#: elf32-d10v.c:509 elf32-epiphany.c:556 elf32-fr30.c:609 elf32-frv.c:4105
+#: elf32-h8300.c:509 elf32-i860.c:1211 elf32-ip2k.c:1468 elf32-iq2000.c:684
+#: elf32-lm32.c:1168 elf32-m32c.c:553 elf32-m32r.c:3106 elf32-m68hc1x.c:1138
+#: elf32-mep.c:535 elf32-microblaze.c:1231 elf32-moxie.c:282
+#: elf32-msp430.c:486 elf32-mt.c:395 elf32-openrisc.c:404 elf32-score.c:2729
+#: elf32-score7.c:2537 elf32-spu.c:5044 elf32-tilepro.c:3214 elf32-v850.c:2143
+#: elf32-xstormy16.c:935 elf64-mmix.c:1590 elfxx-tilegx.c:3577
+msgid "internal error: out of range error"
+msgstr "error interno: error fuera de rango"
+
+#: elf-m10200.c:454 elf-m10300.c:1567 elf32-avr.c:1225 elf32-bfin.c:3217
+#: elf32-cr16.c:1486 elf32-cr16c.c:784 elf32-cris.c:2085 elf32-crx.c:926
+#: elf32-d10v.c:513 elf32-fr30.c:613 elf32-frv.c:4109 elf32-h8300.c:513
+#: elf32-i860.c:1215 elf32-iq2000.c:688 elf32-lm32.c:1172 elf32-m32c.c:557
+#: elf32-m32r.c:3110 elf32-m68hc1x.c:1142 elf32-mep.c:539
+#: elf32-microblaze.c:1235 elf32-moxie.c:286 elf32-msp430.c:490
+#: elf32-openrisc.c:408 elf32-score.c:2733 elf32-score7.c:2541
+#: elf32-spu.c:5048 elf32-tilepro.c:3218 elf32-v850.c:2147
+#: elf32-xstormy16.c:939 elf64-mmix.c:1594 elfxx-mips.c:9465
+#: elfxx-tilegx.c:3581
+msgid "internal error: unsupported relocation error"
+msgstr "error interno: no se admite el error de reubicación"
+
+#: elf-m10200.c:458 elf32-cr16.c:1490 elf32-cr16c.c:788 elf32-crx.c:930
+#: elf32-d10v.c:517 elf32-h8300.c:517 elf32-lm32.c:1176 elf32-m32r.c:3114
+#: elf32-m68hc1x.c:1146 elf32-microblaze.c:1239 elf32-score.c:2737
+#: elf32-score7.c:2545 elf32-spu.c:5052
+msgid "internal error: dangerous error"
+msgstr "error interno: error peligroso"
+
+#: elf-m10200.c:462 elf-m10300.c:1580 elf32-avr.c:1233 elf32-bfin.c:3225
+#: elf32-cr16.c:1494 elf32-cr16c.c:792 elf32-cris.c:2093 elf32-crx.c:934
+#: elf32-d10v.c:521 elf32-epiphany.c:571 elf32-fr30.c:621 elf32-frv.c:4117
+#: elf32-h8300.c:521 elf32-i860.c:1223 elf32-ip2k.c:1483 elf32-iq2000.c:696
+#: elf32-lm32.c:1180 elf32-m32c.c:565 elf32-m32r.c:3118 elf32-m68hc1x.c:1150
+#: elf32-mep.c:547 elf32-microblaze.c:1243 elf32-moxie.c:294
+#: elf32-msp430.c:498 elf32-mt.c:403 elf32-openrisc.c:416 elf32-score.c:2746
+#: elf32-score7.c:2549 elf32-spu.c:5056 elf32-tilepro.c:3226 elf32-v850.c:2167
+#: elf32-xstormy16.c:947 elf64-mmix.c:1602 elfxx-tilegx.c:3589
+msgid "internal error: unknown error"
+msgstr "error interno: error desconocido"
+
+#: elf-m10300.c:1507 elf32-arm.c:10419 elf32-i386.c:4264 elf32-m32r.c:2599
+#: elf32-m68k.c:4156 elf32-s390.c:3003 elf32-sh.c:4218 elf32-tilepro.c:3117
+#: elf32-xtensa.c:3066 elf64-s390.c:2978 elf64-sh64.c:1640 elf64-x86-64.c:4110
+#: elfxx-sparc.c:3835 elfxx-tilegx.c:3500
+msgid "%B(%A+0x%lx): unresolvable %s relocation against symbol `%s'"
+msgstr "%B(%A+0x%lx): reubicación %s sin resolución contra el símbolo `%s'"
+
+#: elf-m10300.c:1572
+msgid "error: inappropriate relocation type for shared library (did you forget -fpic?)"
+msgstr "error: tipo de reubicación inapropiada para la biblioteca compartida (¿olvidó -fpic?)"
+
+#: elf-m10300.c:1575
+msgid "internal error: suspicious relocation type used in shared library"
+msgstr "error interno: se usó un tipo de reubicación sospechosa en la biblioteca compartida"
+
+#: elf-m10300.c:4372 elf32-arm.c:12800 elf32-cr16.c:2451 elf32-cris.c:3057
+#: elf32-hppa.c:1894 elf32-i370.c:503 elf32-i386.c:2182 elf32-lm32.c:1868
+#: elf32-m32r.c:1927 elf32-m68k.c:3253 elf32-s390.c:1652 elf32-sh.c:2931
+#: elf32-tic6x.c:2162 elf32-tilepro.c:1940 elf32-vax.c:1041 elf64-s390.c:1635
+#: elf64-sh64.c:3381 elf64-x86-64.c:2176 elfxx-sparc.c:2119
+#: elfxx-tilegx.c:2261
+#, c-format
+msgid "dynamic variable `%s' is zero size"
+msgstr "la variable dinámica `%s' es de tamaño cero"
+
+#: elf.c:334
+msgid "%B: invalid string offset %u >= %lu for section `%s'"
+msgstr "%B: desplazamiento de cadena inválido %u >= %lu para la sección `%s'"
+
+#: elf.c:446
+msgid "%B symbol number %lu references nonexistent SHT_SYMTAB_SHNDX section"
+msgstr "%B el número de símbolo %lu hace referencia a la sección inexistente SHT_SYMTAB_SHNDX"
+
+#: elf.c:602
+msgid "%B: Corrupt size field in group section header: 0x%lx"
+msgstr "%B: Campo de tamaño corrupto en el encabezado de la sección de grupo: 0x%lx"
+
+#: elf.c:638
+msgid "%B: invalid SHT_GROUP entry"
+msgstr "%B: entrada SHT_GROUP inválida"
+
+#: elf.c:708
+msgid "%B: no group info for section %A"
+msgstr "%B: no hay información de grupo para la sección %A"
+
+#: elf.c:737 elf.c:3121 elflink.c:10135
+msgid "%B: warning: sh_link not set for section `%A'"
+msgstr "%B: aviso: no se estableció sh_link para la sección `%A'"
+
+#: elf.c:756
+msgid "%B: sh_link [%d] in section `%A' is incorrect"
+msgstr "%B: sh_link [%d] en la sección `%A', es incorrecto"
+
+#: elf.c:791
+msgid "%B: unknown [%d] section `%s' in group [%s]"
+msgstr "%B: sección [%d] desconocida `%s' en el grupo [%s]"
+
+#: elf.c:1041
+msgid "%B: unable to initialize commpress status for section %s"
+msgstr "%B: no se puede inicializar el estado comprimido de la sección %s"
+
+#: elf.c:1061
+msgid "%B: unable to initialize decommpress status for section %s"
+msgstr "%B: no se puede inicializar el estado descomprimido de la sección %s"
+
+#: elf.c:1181
+#, c-format
+msgid ""
+"\n"
+"Program Header:\n"
+msgstr ""
+"\n"
+"Encabezado del Programa:\n"
+
+#: elf.c:1223
+#, c-format
+msgid ""
+"\n"
+"Dynamic Section:\n"
+msgstr ""
+"\n"
+"Sección Dinámica:\n"
+
+#: elf.c:1359
+#, c-format
+msgid ""
+"\n"
+"Version definitions:\n"
+msgstr ""
+"\n"
+"Definiciones de versión:\n"
+
+#: elf.c:1384
+#, c-format
+msgid ""
+"\n"
+"Version References:\n"
+msgstr ""
+"\n"
+"Referencias de versión:\n"
+
+#: elf.c:1389
+#, c-format
+msgid " required from %s:\n"
+msgstr " se requere desde %s:\n"
+
+#: elf.c:1796
+msgid "%B: invalid link %lu for reloc section %s (index %u)"
+msgstr "%B: enlace %lu inválido para la sección de reubicación %s (índice %u)"
+
+#: elf.c:1966
+msgid "%B: don't know how to handle allocated, application specific section `%s' [0x%8x]"
+msgstr "%B: no se sabe cómo manejar la sección específica alojada de la aplicación `%s' [0x%8x]"
+
+#: elf.c:1978
+msgid "%B: don't know how to handle processor specific section `%s' [0x%8x]"
+msgstr "%B: no se sabe cómo manejar la sección específica de procesador `%s' [0x%8x]"
+
+#: elf.c:1989
+msgid "%B: don't know how to handle OS specific section `%s' [0x%8x]"
+msgstr "%B: no se sabe cómo manejar la sección específica de SO `%s' [0x%8x]"
+
+#: elf.c:1999
+msgid "%B: don't know how to handle section `%s' [0x%8x]"
+msgstr "%B: no se sabe cómo manejar la sección `%s' [0x%8x]"
+
+#: elf.c:2634
+#, c-format
+msgid "warning: section `%A' type changed to PROGBITS"
+msgstr "aviso: el tipo de la sección `%A' cambió a PROGBITS"
+
+#: elf.c:3078
+msgid "%B: sh_link of section `%A' points to discarded section `%A' of `%B'"
+msgstr "%B: sh_link de la sección `%A' apunta a la sección descartada `%A' de `%B'"
+
+#: elf.c:3101
+msgid "%B: sh_link of section `%A' points to removed section `%A' of `%B'"
+msgstr "%B: sh_link de la sección `%A' apunta a la sección eliminada `%A' de `%B'"
+
+#: elf.c:4527
+msgid "%B: The first section in the PT_DYNAMIC segment is not the .dynamic section"
+msgstr "%B: La primera sección en el segmento PT_DYNAMIC no es la sección .dynamic"
+
+#: elf.c:4554
+msgid "%B: Not enough room for program headers, try linking with -N"
+msgstr "%B: No hay suficiente espacio para los encabezados del programa, pruebe enlazar con -N"
+
+#: elf.c:4641
+msgid "%B: section %A lma %#lx adjusted to %#lx"
+msgstr "%B: la sección %A lma %#lx se ajusta a %#lx"
+
+#: elf.c:4776
+msgid "%B: section `%A' can't be allocated in segment %d"
+msgstr "%B: la sección `%A' no se puede asignar en el segmento %d"
+
+#: elf.c:4824
+msgid "%B: warning: allocated section `%s' not in segment"
+msgstr "%B: aviso: la sección asignada `%s' no está en el segmento"
+
+#: elf.c:5324
+msgid "%B: symbol `%s' required but not present"
+msgstr "%B: se requiere el símbolo `%s' pero no está presente"
+
+#: elf.c:5662
+msgid "%B: warning: Empty loadable segment detected, is this intentional ?\n"
+msgstr "%B: aviso: Se detectó un segmento cargable vacío, ¿ esto es intencional ?\n"
+
+#: elf.c:6692
+#, c-format
+msgid "Unable to find equivalent output section for symbol '%s' from section '%s'"
+msgstr "No se puede encontrar la sección de salida equivalente para el símbolo '%s' de la sección '%s'"
+
+#: elf.c:7692
+msgid "%B: unsupported relocation type %s"
+msgstr "%B: no se admite el tipo de reubicación %s"
+
+#: elf32-arm.c:3617
+msgid ""
+"%B(%s): warning: interworking not enabled.\n"
+" first occurrence: %B: Thumb call to ARM"
+msgstr ""
+"%B(%s): aviso: no se activó la interoperabilidad.\n"
+" primer suceso: %B: llamada Thumb a ARM"
+
+#: elf32-arm.c:3664
+msgid ""
+"%B(%s): warning: interworking not enabled.\n"
+" first occurrence: %B: ARM call to Thumb"
+msgstr ""
+"%B(%s): aviso: no se activó la interoperabilidad.\n"
+" primer suceso: %B: llamada ARM a Thumb"
+
+#: elf32-arm.c:3878 elf32-arm.c:5315
+#, c-format
+msgid "%s: cannot create stub entry %s"
+msgstr "%s: no se puede crear la entrada de cabo %s"
+
+#: elf32-arm.c:5431
+#, c-format
+msgid "unable to find THUMB glue '%s' for '%s'"
+msgstr "no se puede encontrar el pegamento THUMB '%s' para `%s'"
+
+#: elf32-arm.c:5467
+#, c-format
+msgid "unable to find ARM glue '%s' for '%s'"
+msgstr "no se puede encontrar el pegamento ARM '%s' para `%s'"
+
+#: elf32-arm.c:6005
+msgid "%B: BE8 images only valid in big-endian mode."
+msgstr "%B: las imágenes BE8 sólo son válidas en modo big-endian."
+
+#. Give a warning, but do as the user requests anyway.
+#: elf32-arm.c:6235
+msgid "%B: warning: selected VFP11 erratum workaround is not necessary for target architecture"
+msgstr "%B: aviso: no se necesita la alternativa para evitar la errata del VFP11 seleccionado para la arquitectura objetivo"
+
+#: elf32-arm.c:6779 elf32-arm.c:6799
+msgid "%B: unable to find VFP11 veneer `%s'"
+msgstr "%B: no se puede encontrar la chapa de VFP11 `%s'"
+
+#: elf32-arm.c:6848
+#, c-format
+msgid "Invalid TARGET2 relocation type '%s'."
+msgstr "Tipo de reubicación TARGET2 '%s' inválido."
+
+#: elf32-arm.c:6933
+msgid ""
+"%B(%s): warning: interworking not enabled.\n"
+" first occurrence: %B: thumb call to arm"
+msgstr ""
+"%s(%s): aviso: no se activó la interoperabilidad.\n"
+" primer suceso: %B: llamada thumb a arm"
+
+#: elf32-arm.c:7717
+msgid "%B(%A+0x%lx):unexpected Thumb instruction '0x%x' in TLS trampoline"
+msgstr "%B(%A+0x%lx):instrucción Thumb '0x%x' inesperada en el trampolín TLS"
+
+#: elf32-arm.c:7756
+msgid "%B(%A+0x%lx):unexpected ARM instruction '0x%x' in TLS trampoline"
+msgstr "%B(%A+0x%lx):instrucción ARM '0x%x' inesperada en el trampolín TLS"
+
+#: elf32-arm.c:8209
+msgid "\\%B: Warning: Arm BLX instruction targets Arm function '%s'."
+msgstr "\\%B: Aviso: La instrucción Arm BLX apunta a la función Arm '%s'."
+
+#: elf32-arm.c:8622
+msgid "%B: Warning: Thumb BLX instruction targets thumb function '%s'."
+msgstr "%B: Aviso: La instrucción Thumb BLX apunta a la función thumb '%s'."
+
+#: elf32-arm.c:9460
+msgid "%B(%A+0x%lx):unexpected Thumb instruction '0x%x' referenced by TLS_GOTDESC"
+msgstr "%B(%A+0x%lx):instrucción Thumb '0x%x' inesperada referenciada por TLS_GOTDESC"
+
+#: elf32-arm.c:9483
+msgid "%B(%A+0x%lx):unexpected ARM instruction '0x%x' referenced by TLS_GOTDESC"
+msgstr "%B(%A+0x%lx):instrucción ARM '0x%x' inesperada referenciada por TLS_GOTDESC"
+
+#: elf32-arm.c:9512
+msgid "%B(%A+0x%lx): R_ARM_TLS_LE32 relocation not permitted in shared object"
+msgstr "%B(%A+0x%lx): la reubicación R_ARM_TLS_LE32 no se permite en objetos compartidos"
+
+#: elf32-arm.c:9727
+msgid "%B(%A+0x%lx): Only ADD or SUB instructions are allowed for ALU group relocations"
+msgstr "%B(%A+0x%lx): Sólo se permiten las instrucciones ADD o SUB en las reubicaciones de grupo ALU"
+
+#: elf32-arm.c:9767 elf32-arm.c:9854 elf32-arm.c:9937 elf32-arm.c:10022
+msgid "%B(%A+0x%lx): Overflow whilst splitting 0x%lx for group relocation %s"
+msgstr "%B(%A+0x%lx): Desborde al dividirse 0x%lx para la reubicación de grupo %s"
+
+#: elf32-arm.c:10261 elf32-sh.c:4103 elf64-sh64.c:1544
+msgid "%B(%A+0x%lx): %s relocation against SEC_MERGE section"
+msgstr "%B(%A+0x%lx): reubicación %s contra la sección SEC_MERGE"
+
+#: elf32-arm.c:10372 elf32-m68k.c:4191 elf32-xtensa.c:2802
+msgid "%B(%A+0x%lx): %s used with TLS symbol %s"
+msgstr "%B(%A+0x%lx): se usó %s con el símbolo TLS %s"
+
+#: elf32-arm.c:10373 elf32-m68k.c:4192 elf32-xtensa.c:2803
+msgid "%B(%A+0x%lx): %s used with non-TLS symbol %s"
+msgstr "%B(%A+0x%lx): se usó %s con el símbolo %s que no es TLS"
+
+#: elf32-arm.c:10453 elf32-tic6x.c:2753
+msgid "out of range"
+msgstr "fuera de rango"
+
+#: elf32-arm.c:10457 elf32-tic6x.c:2757
+msgid "unsupported relocation"
+msgstr "no se admite la reubicación"
+
+#: elf32-arm.c:10465 elf32-tic6x.c:2765
+msgid "unknown error"
+msgstr "error desconocido"
+
+#: elf32-arm.c:10890
+msgid "Warning: Clearing the interworking flag of %B because non-interworking code in %B has been linked with it"
+msgstr "Aviso: Se limpia la opción de interoperación en %B porque se ha enlazado con él código no interoperable en %B"
+
+#: elf32-arm.c:10984
+msgid "%B: Unknown mandatory EABI object attribute %d"
+msgstr "%B: Atributo de objeto EABI obligatorio %d desconocido"
+
+#: elf32-arm.c:10992
+msgid "Warning: %B: Unknown EABI object attribute %d"
+msgstr "Aviso: %B: Atributo de objeto EABI %d desconocido"
+
+#: elf32-arm.c:11173
+msgid "error: %B: Unknown CPU architecture"
+msgstr "error: %B: Arquitectura de CPU desconocida"
+
+#: elf32-arm.c:11211
+msgid "error: %B: Conflicting CPU architectures %d/%d"
+msgstr "error: %B: Arquitecturas de CPU en conflicto %d/%d"
+
+#: elf32-arm.c:11260
+msgid "Error: %B has both the current and legacy Tag_MPextension_use attributes"
+msgstr "Error: %B tiene al mismo tiempo los atributos Tag_MPextension_use actuales y antiguos"
+
+#: elf32-arm.c:11285
+msgid "error: %B uses VFP register arguments, %B does not"
+msgstr "error: %B utiliza argumentos de registro VFP, mientras que %B no"
+
+#: elf32-arm.c:11430
+msgid "error: %B: unable to merge virtualization attributes with %B"
+msgstr "error: %B: no se pueden mezclar los atributos de virtualización con %B"
+
+#: elf32-arm.c:11456
+msgid "error: %B: Conflicting architecture profiles %c/%c"
+msgstr "error: %B: Perfiles de arquitecturas en conflicto %c/%c"
+
+#: elf32-arm.c:11557
+msgid "Warning: %B: Conflicting platform configuration"
+msgstr "Aviso: %B: Configuración de plataformas en conflicto"
+
+#: elf32-arm.c:11566
+msgid "error: %B: Conflicting use of R9"
+msgstr "error: %B: Uso en conflicto de R9"
+
+#: elf32-arm.c:11578
+msgid "error: %B: SB relative addressing conflicts with use of R9"
+msgstr "error: %B: El direccionamiento relativo a SB tiene conflictos con el uso de R9"
+
+#: elf32-arm.c:11591
+msgid "warning: %B uses %u-byte wchar_t yet the output is to use %u-byte wchar_t; use of wchar_t values across objects may fail"
+msgstr "aviso: %B usa wchar_t de %u bytes aunque la salida usa wchar_t de %u bytes; el uso de valores wchar_t entre objetos puede fallar"
+
+#: elf32-arm.c:11622
+msgid "warning: %B uses %s enums yet the output is to use %s enums; use of enum values across objects may fail"
+msgstr "aviso: %B usa enums %s aunque la salida usa enums %s; el uso de valores enum entre objetos puede fallar"
+
+#: elf32-arm.c:11634
+msgid "error: %B uses iWMMXt register arguments, %B does not"
+msgstr "error: %B utiliza argumentos de registro iWMMXt, mientras que %B no"
+
+#: elf32-arm.c:11651
+msgid "error: fp16 format mismatch between %B and %B"
+msgstr "error: no coincide el formato fp16 entre %B y %B"
+
+#: elf32-arm.c:11675
+msgid "DIV usage mismatch between %B and %B"
+msgstr "no coincide el uso de DIV entre %B y %B"
+
+#: elf32-arm.c:11694
+msgid "%B has has both the current and legacy Tag_MPextension_use attributes"
+msgstr "%B tiene al mismo tiempo los atributos actuales y antiguos de Tag_MPextension"
+
+#. Ignore init flag - it may not be set, despite the flags field
+#. containing valid data.
+#. Ignore init flag - it may not be set, despite the flags field containing valid data.
+#: elf32-arm.c:11782 elf32-bfin.c:5079 elf32-cris.c:4169 elf32-m68hc1x.c:1282
+#: elf32-m68k.c:1236 elf32-score.c:3994 elf32-score7.c:3800 elf32-vax.c:529
+#: elfxx-mips.c:14103
+#, c-format
+msgid "private flags = %lx:"
+msgstr "opciones privadas = %lx:"
+
+#: elf32-arm.c:11791
+#, c-format
+msgid " [interworking enabled]"
+msgstr " [interoperabilidad activada]"
+
+#: elf32-arm.c:11799
+#, c-format
+msgid " [VFP float format]"
+msgstr " [formato de coma flotante VFP]"
+
+#: elf32-arm.c:11801
+#, c-format
+msgid " [Maverick float format]"
+msgstr " [formato de coma flotante Maverick]"
+
+#: elf32-arm.c:11803
+#, c-format
+msgid " [FPA float format]"
+msgstr " [formato de coma flotante FPA]"
+
+#: elf32-arm.c:11812
+#, c-format
+msgid " [new ABI]"
+msgstr " [ABI nuevo]"
+
+#: elf32-arm.c:11815
+#, c-format
+msgid " [old ABI]"
+msgstr " [ABI antiguo]"
+
+#: elf32-arm.c:11818
+#, c-format
+msgid " [software FP]"
+msgstr " [FP por software]"
+
+#: elf32-arm.c:11827
+#, c-format
+msgid " [Version1 EABI]"
+msgstr " [EABI Version1]"
+
+#: elf32-arm.c:11830 elf32-arm.c:11841
+#, c-format
+msgid " [sorted symbol table]"
+msgstr " [tabla de símbolos ordenados]"
+
+#: elf32-arm.c:11832 elf32-arm.c:11843
+#, c-format
+msgid " [unsorted symbol table]"
+msgstr " [tabla de símbolos sin ordenar]"
+
+#: elf32-arm.c:11838
+#, c-format
+msgid " [Version2 EABI]"
+msgstr " [EABI Version2]"
+
+#: elf32-arm.c:11846
+#, c-format
+msgid " [dynamic symbols use segment index]"
+msgstr " [los símbolos dinámicos utilizan índices de segmento]"
+
+#: elf32-arm.c:11849
+#, c-format
+msgid " [mapping symbols precede others]"
+msgstr " [el mapeo de símbolos precede a otros]"
+
+#: elf32-arm.c:11856
+#, c-format
+msgid " [Version3 EABI]"
+msgstr " [EABI Version3]"
+
+#: elf32-arm.c:11860
+#, c-format
+msgid " [Version4 EABI]"
+msgstr " [EABI Version4]"
+
+#: elf32-arm.c:11864
+#, c-format
+msgid " [Version5 EABI]"
+msgstr " [EABI Version5]"
+
+#: elf32-arm.c:11867
+#, c-format
+msgid " [BE8]"
+msgstr " [BE8]"
+
+#: elf32-arm.c:11870
+#, c-format
+msgid " [LE8]"
+msgstr " [LE8]"
+
+#: elf32-arm.c:11876
+#, c-format
+msgid " <EABI version unrecognised>"
+msgstr " <no se reconoce la versión de EABI>"
+
+#: elf32-arm.c:11883
+#, c-format
+msgid " [relocatable executable]"
+msgstr " [ejecutable reubicable]"
+
+#: elf32-arm.c:11886
+#, c-format
+msgid " [has entry point]"
+msgstr " [tiene punto de entrada]"
+
+#: elf32-arm.c:11891
+#, c-format
+msgid "<Unrecognised flag bits set>"
+msgstr "<No se reconoce el conjunto de bits de opción>"
+
+#: elf32-arm.c:12189 elf32-i386.c:1461 elf32-s390.c:1000 elf32-tic6x.c:2829
+#: elf32-tilepro.c:1336 elf32-xtensa.c:1009 elf64-s390.c:960
+#: elf64-x86-64.c:1364 elfxx-sparc.c:1371 elfxx-tilegx.c:1586
+msgid "%B: bad symbol index: %d"
+msgstr "%B: índice de símbolos erróneo: %d"
+
+#: elf32-arm.c:12337 elf64-x86-64.c:1561 elf64-x86-64.c:1732 elfxx-mips.c:8223
+msgid "%B: relocation %s against `%s' can not be used when making a shared object; recompile with -fPIC"
+msgstr "%B: no se puede usar la reubicación %s contra `%s' cuando se hace un objeto compartido; recompile con -fPIC"
+
+#: elf32-arm.c:13460
+#, c-format
+msgid "Errors encountered processing file %s"
+msgstr "Se encontraron errores al procesar el fichero %s"
+
+#: elf32-arm.c:14837
+msgid "%B: error: Cortex-A8 erratum stub is allocated in unsafe location"
+msgstr "%B: error: el cabo de errores Cortex-A8 se aloja en una ubicación insegura"
+
+#. There's not much we can do apart from complain if this
+#. happens.
+#: elf32-arm.c:14864
+msgid "%B: error: Cortex-A8 erratum stub out of range (input file too large)"
+msgstr "%B: error: el cabo de errores Cortex-A8 está fuera de rango (el fichero de entrada es demasiado grande)"
+
+#: elf32-arm.c:14958 elf32-arm.c:14980
+msgid "%B: error: VFP11 veneer out of range"
+msgstr "%B: error: la chapa VFP11 está fuera de rango"
+
+#: elf32-arm.c:15518
+msgid "error: %B is already in final BE8 format"
+msgstr "error: %B ya está en el formato BE8 final"
+
+#: elf32-arm.c:15594
+msgid "error: Source object %B has EABI version %d, but target %B has EABI version %d"
+msgstr "error: El objeto fuente %B tiene EABI versión %d, pero el objetivo %B tiene EABI versión %d"
+
+#: elf32-arm.c:15610
+msgid "error: %B is compiled for APCS-%d, whereas target %B uses APCS-%d"
+msgstr "error: %B está compilado para APCS-%d mientras que el objetivo %B usa APCS-%d"
+
+#: elf32-arm.c:15635
+msgid "error: %B uses VFP instructions, whereas %B does not"
+msgstr "error: %B utiliza instrucciones VFP, mientras que %B no"
+
+#: elf32-arm.c:15639
+msgid "error: %B uses FPA instructions, whereas %B does not"
+msgstr "error: %B utiliza instrucciones FPA, mientras que %B no"
+
+#: elf32-arm.c:15649
+msgid "error: %B uses Maverick instructions, whereas %B does not"
+msgstr "error: %B utiliza instrucciones Maverick, mientras que %B no"
+
+#: elf32-arm.c:15653
+msgid "error: %B does not use Maverick instructions, whereas %B does"
+msgstr "error: %B no utiliza instrucciones Maverick, mientras que %B sí"
+
+#: elf32-arm.c:15672
+msgid "error: %B uses software FP, whereas %B uses hardware FP"
+msgstr "error: %B utiliza FP de software, mientras que %B utiliza FP de hardware"
+
+#: elf32-arm.c:15676
+msgid "error: %B uses hardware FP, whereas %B uses software FP"
+msgstr "error: %B utiliza FP de hardware, mientras que %B utiliza FP de software"
+
+#: elf32-avr.c:1229 elf32-bfin.c:3221 elf32-cris.c:2089 elf32-epiphany.c:567
+#: elf32-fr30.c:617 elf32-frv.c:4113 elf32-i860.c:1219 elf32-ip2k.c:1479
+#: elf32-iq2000.c:692 elf32-m32c.c:561 elf32-mep.c:543 elf32-moxie.c:290
+#: elf32-msp430.c:494 elf32-mt.c:399 elf32-openrisc.c:412 elf32-tilepro.c:3222
+#: elf32-v850.c:2151 elf32-xstormy16.c:943 elf64-mmix.c:1598
+#: elfxx-tilegx.c:3585
+msgid "internal error: dangerous relocation"
+msgstr "error interno: reubicación peligrosa"
+
+#: elf32-avr.c:2415 elf32-hppa.c:598 elf32-m68hc1x.c:166
+msgid "%B: cannot create stub entry %s"
+msgstr "%B: no se puede crear la entrada de cabo %s"
+
+#: elf32-bfin.c:107 elf32-bfin.c:363
+msgid "relocation should be even number"
+msgstr "la reubicación debe ser un número non"
+
+#: elf32-bfin.c:1593
+msgid "%B(%A+0x%lx): unresolvable relocation against symbol `%s'"
+msgstr "%B(%A+0x%lx): reubicación sin resolución contra el símbolo `%s'"
+
+#: elf32-bfin.c:1626 elf32-i386.c:4307 elf32-m68k.c:4233 elf32-s390.c:3055
+#: elf64-s390.c:3030 elf64-x86-64.c:4151
+msgid "%B(%A+0x%lx): reloc against `%s': error %d"
+msgstr "%B(%A+0x%lx): reubicación contra `%s': error %d"
+
+#: elf32-bfin.c:2725
+msgid "%B: relocation at `%A+0x%x' references symbol `%s' with nonzero addend"
+msgstr "%B: la reubicación en `%A+0x%x' referencía al símbolo `%s' con adición que no es cero"
+
+#: elf32-bfin.c:2741
+msgid "relocation references symbol not defined in the module"
+msgstr "la reubicación referencía un símbolo que no está definido en el módulo"
+
+#: elf32-bfin.c:2838
+msgid "R_BFIN_FUNCDESC references dynamic symbol with nonzero addend"
+msgstr "R_BFIN_FUNCDESC referencía un símbolo dinámico con adición que no es cero"
+
+#: elf32-bfin.c:2879 elf32-bfin.c:3002
+msgid "cannot emit fixups in read-only section"
+msgstr "no se pueden emitir composturas en la sección de sólo lectura"
+
+#: elf32-bfin.c:2910 elf32-bfin.c:3040 elf32-lm32.c:1103 elf32-sh.c:5016
+msgid "cannot emit dynamic relocations in read-only section"
+msgstr "no se pueden emitir reubicaciones dinámicas en la sección de sólo lectura"
+
+#: elf32-bfin.c:2960
+msgid "R_BFIN_FUNCDESC_VALUE references dynamic symbol with nonzero addend"
+msgstr "R_BFIN_FUNCDESC_VALUE referencía un símbolo dinámico con adición que no es cero"
+
+#: elf32-bfin.c:3125
+msgid "relocations between different segments are not supported"
+msgstr "no se admiten las reubicaciones entre segmentos diferentes"
+
+#: elf32-bfin.c:3126
+msgid "warning: relocation references a different segment"
+msgstr "aviso: la reubicación referencía un segmento diferente"
+
+#: elf32-bfin.c:4971
+msgid "%B: unsupported relocation type %i"
+msgstr "%B: no se admite el tipo de reubicación %i"
+
+#: elf32-bfin.c:5125 elf32-frv.c:6808
+#, c-format
+msgid "%s: cannot link non-fdpic object file into fdpic executable"
+msgstr "%s: no se puede enlazar el fichero objeto que no es fdpic en un ejecutable fdpic"
+
+#: elf32-bfin.c:5129 elf32-frv.c:6812
+#, c-format
+msgid "%s: cannot link fdpic object file into non-fdpic executable"
+msgstr "%s: no se puede enlazar el fichero objeto fdpic en un ejecutable que no es fdpic"
+
+#: elf32-bfin.c:5283
+#, c-format
+msgid "*** check this relocation %s"
+msgstr "*** revisar esta reubicación %s"
+
+#: elf32-cris.c:1176
+msgid "%B, section %A: unresolvable relocation %s against symbol `%s'"
+msgstr "%B, sección %A: reubicación %s sin resolución contra el símbolo `%s'"
+
+#: elf32-cris.c:1238
+msgid "%B, section %A: No PLT nor GOT for relocation %s against symbol `%s'"
+msgstr "%B, sección %A: No hay PLT ni GOT para la reubicación %s contra el símbolo `%s'"
+
+#: elf32-cris.c:1240
+msgid "%B, section %A: No PLT for relocation %s against symbol `%s'"
+msgstr "%B, sección %A: No hay PLT para la reubicación %s contra el símbolo `%s'"
+
+#: elf32-cris.c:1246 elf32-cris.c:1379 elf32-cris.c:1639 elf32-cris.c:1722
+#: elf32-cris.c:1875 elf32-tic6x.c:2662
+msgid "[whose name is lost]"
+msgstr "[cuyo nombre está perdido]"
+
+#: elf32-cris.c:1365 elf32-tic6x.c:2647
+msgid "%B, section %A: relocation %s with non-zero addend %d against local symbol"
+msgstr "%B, sección %A: reubicación %s con adición %d que no es cero contra el símbolo local"
+
+#: elf32-cris.c:1373 elf32-cris.c:1716 elf32-cris.c:1869 elf32-tic6x.c:2655
+msgid "%B, section %A: relocation %s with non-zero addend %d against symbol `%s'"
+msgstr "%B, sección %A: reubicación %s con adición %d que no es cero contra el símbolo `%s'"
+
+#: elf32-cris.c:1399
+msgid "%B, section %A: relocation %s is not allowed for global symbol: `%s'"
+msgstr "%B, sección %A: no se permite la reubicación %s para el símbolo global: `%s'"
+
+#: elf32-cris.c:1415
+msgid "%B, section %A: relocation %s with no GOT created"
+msgstr "%B, sección %A: la reubicación %s sin GOT creado"
+
+#. We shouldn't get here for GCC-emitted code.
+#: elf32-cris.c:1630
+msgid "%B, section %A: relocation %s has an undefined reference to `%s', perhaps a declaration mixup?"
+msgstr "%B, sección %A: la reubicación %s tiene una referencia sin definir a `%s', ¿tal vez una confusión en la declaración?"
+
+#: elf32-cris.c:2002
+msgid "%B, section %A: relocation %s is not allowed for symbol: `%s' which is defined outside the program, perhaps a declaration mixup?"
+msgstr "%B, sección %A: no se permite la reubicación %s para el símbolo: `%s' el cual se define fuera del programa, ¿tal vez una confusión en la declaración?"
+
+#: elf32-cris.c:2055
+msgid "(too many global variables for -fpic: recompile with -fPIC)"
+msgstr "(demasiadas variables globales para -fpic: recompile con -fPIC)"
+
+#: elf32-cris.c:2062
+msgid "(thread-local data too big for -fpic or -msmall-tls: recompile with -fPIC or -mno-small-tls)"
+msgstr "(datos thread-local demasiado grandes para -fpic o -msmall-tls: recompile con -fPIC o -mno-small-tls)"
+
+#: elf32-cris.c:3261
+msgid ""
+"%B, section %A:\n"
+" v10/v32 compatible object %s must not contain a PIC relocation"
+msgstr ""
+"%B, sección %A:\n"
+" el objeto %s compatible con v10/v32 no debe contener una reubicación PIC"
+
+#: elf32-cris.c:3366
+msgid ""
+"%B, section %A:\n"
+" relocation %s not valid in a shared object; typically an option mixup, recompile with -fPIC"
+msgstr ""
+"%B, sección %A:\n"
+" la reubicación %s no es válida en un objeto compartido; es una confusión de opción típica, recompile con -fPIC"
+
+#: elf32-cris.c:3580
+msgid ""
+"%B, section %A:\n"
+" relocation %s should not be used in a shared object; recompile with -fPIC"
+msgstr ""
+"%B, sección %A:\n"
+" la reubicación %s no se debe usar en un objeto compartido; recompile con -fPIC"
+
+#: elf32-cris.c:4002
+msgid ""
+"%B, section `%A', to symbol `%s':\n"
+" relocation %s should not be used in a shared object; recompile with -fPIC"
+msgstr ""
+"%B, sección `%A', para el símbolo `%s':\n"
+" la reubicación %s no se debe usar en un objeto compartido; recompile con -fPIC"
+
+#: elf32-cris.c:4118
+msgid "Unexpected machine number"
+msgstr "Número de máquina inesperado"
+
+#: elf32-cris.c:4172
+#, c-format
+msgid " [symbols have a _ prefix]"
+msgstr " [los símbolos tiene un prefijo _]"
+
+#: elf32-cris.c:4175
+#, c-format
+msgid " [v10 and v32]"
+msgstr " [v10 y v32]"
+
+#: elf32-cris.c:4178
+#, c-format
+msgid " [v32]"
+msgstr " [v32]"
+
+#: elf32-cris.c:4223
+msgid "%B: uses _-prefixed symbols, but writing file with non-prefixed symbols"
+msgstr "%B: se usan símbolos con prefijo _, pero se escribe el fichero con símbolos sin prefijo"
+
+#: elf32-cris.c:4224
+msgid "%B: uses non-prefixed symbols, but writing file with _-prefixed symbols"
+msgstr "%B: se usan símbolos sin prefijo, pero se escribe el fichero con símbolos con prefijo _"
+
+#: elf32-cris.c:4243
+msgid "%B contains CRIS v32 code, incompatible with previous objects"
+msgstr "%B contiene código CRIS v32, incompatible con objetos previos"
+
+#: elf32-cris.c:4245
+msgid "%B contains non-CRIS-v32 code, incompatible with previous objects"
+msgstr "%B contiene código que no es CRIS v32, incompatible con objetos previos"
+
+#: elf32-dlx.c:142
+#, c-format
+msgid "BFD Link Error: branch (PC rel16) to section (%s) not supported"
+msgstr "Error de Enlazado BFD: no se admite la ramificación (PC rel16) a la sección (%s)"
+
+#: elf32-dlx.c:204
+#, c-format
+msgid "BFD Link Error: jump (PC rel26) to section (%s) not supported"
+msgstr "Error de Enlazado BFD: no se admite el salto (PC rel26) a la sección (%s)"
+
+#. Only if it's not an unresolved symbol.
+#: elf32-epiphany.c:563 elf32-ip2k.c:1475
+msgid "unsupported relocation between data/insn address spaces"
+msgstr "no se admite la reubicación entre espacios de direcciones datos/insn"
+
+#: elf32-frv.c:1509 elf32-frv.c:1658
+msgid "relocation requires zero addend"
+msgstr "la reubicación requiere una adición cero"
+
+#: elf32-frv.c:2888
+msgid "%H: relocation to `%s+%v' may have caused the error above\n"
+msgstr "%H: la reubicación a `%s+%v' tal vez causó el error anterior\n"
+
+#: elf32-frv.c:2905
+msgid "%H: relocation references symbol not defined in the module\n"
+msgstr "%H: la reubicación referencía un símbolo que no está definido en el módulo\n"
+
+#: elf32-frv.c:2981
+msgid "%H: R_FRV_GETTLSOFF not applied to a call instruction\n"
+msgstr "%H: no se aplicó R_FRV_GETTLSOFF a una instrucción call\n"
+
+#: elf32-frv.c:3022
+msgid "%H: R_FRV_GOTTLSDESC12 not applied to an lddi instruction\n"
+msgstr "%H: no se aplicó R_FRV_GOTTLSDESC12 a una instrucción lddi\n"
+
+#: elf32-frv.c:3093
+msgid "%H: R_FRV_GOTTLSDESCHI not applied to a sethi instruction\n"
+msgstr "%H: no se aplicó R_FRV_GOTTLSDESCHI a una instrucción sethi\n"
+
+#: elf32-frv.c:3130
+msgid "%H: R_FRV_GOTTLSDESCLO not applied to a setlo or setlos instruction\n"
+msgstr "%H: no se aplicó R_FRV_GOTTLSDESCLO a una instrucción setlo o setlos\n"
+
+#: elf32-frv.c:3177
+msgid "%H: R_FRV_TLSDESC_RELAX not applied to an ldd instruction\n"
+msgstr "%H: no se aplicó R_FRV_GOTTLSDESC_RELAX a una instrucción ldd\n"
+
+#: elf32-frv.c:3261
+msgid "%H: R_FRV_GETTLSOFF_RELAX not applied to a calll instruction\n"
+msgstr "%H: no se aplicó R_FRV_GETTLSOFF_RELAX a una instrucción calll\n"
+
+#: elf32-frv.c:3315
+msgid "%H: R_FRV_GOTTLSOFF12 not applied to an ldi instruction\n"
+msgstr "%H: no se aplicó R_FRV_GOTTLSOFF12 a una instrucción ldi\n"
+
+#: elf32-frv.c:3345
+msgid "%H: R_FRV_GOTTLSOFFHI not applied to a sethi instruction\n"
+msgstr "%H: no se aplicó R_FRV_GOTTLSOFFHI a una instrucción sethi\n"
+
+#: elf32-frv.c:3374
+msgid "%H: R_FRV_GOTTLSOFFLO not applied to a setlo or setlos instruction\n"
+msgstr "%H: no se aplicó R_FRV_GOTTLSOFFLO a una instrucción setlo o setlos\n"
+
+#: elf32-frv.c:3404
+msgid "%H: R_FRV_TLSOFF_RELAX not applied to an ld instruction\n"
+msgstr "%H: no se aplicó R_FRV_TLSOFF_RELAX a una instrucción ld\n"
+
+#: elf32-frv.c:3449
+msgid "%H: R_FRV_TLSMOFFHI not applied to a sethi instruction\n"
+msgstr "%H: no se aplicó R_FRV_TLSMOFFHI a una instrucción sethi\n"
+
+#: elf32-frv.c:3476
+msgid "R_FRV_TLSMOFFLO not applied to a setlo or setlos instruction\n"
+msgstr "no se aplicó R_FRV_TLSMOFFLO a una instrucción setlo o setlos\n"
+
+#: elf32-frv.c:3597
+msgid "%H: R_FRV_FUNCDESC references dynamic symbol with nonzero addend\n"
+msgstr "%H: R_FRV_FUNCDESC referencía un símbolo dinámico con adición que no es cero\n"
+
+#: elf32-frv.c:3638 elf32-frv.c:3760
+msgid "%H: cannot emit fixups in read-only section\n"
+msgstr "%H: no se pueden emitir composturas en la sección de sólo lectura\n"
+
+#: elf32-frv.c:3669 elf32-frv.c:3803
+msgid "%H: cannot emit dynamic relocations in read-only section\n"
+msgstr "%H: no se pueden emitir reubicaciones dinámicas en la sección de sólo lectura\n"
+
+#: elf32-frv.c:3718
+msgid "%H: R_FRV_FUNCDESC_VALUE references dynamic symbol with nonzero addend\n"
+msgstr "%H: R_FRV_FUNCDESC_VALUE referencía un símbolo dinámico con adición que no es cero\n"
+
+#: elf32-frv.c:3974
+msgid "%H: reloc against `%s' references a different segment\n"
+msgstr "%H: la reubicación contra `%s' referencía un segmento diferente\n"
+
+#: elf32-frv.c:4124
+msgid "%H: reloc against `%s': %s\n"
+msgstr "%H: reubicación contra `%s': %s\n"
+
+#: elf32-frv.c:6400
+msgid "%B: unsupported relocation type %i\n"
+msgstr "%B: no se admite el tipo de reubicación %i\n"
+
+#: elf32-frv.c:6722
+#, c-format
+msgid "%s: compiled with %s and linked with modules that use non-pic relocations"
+msgstr "%s: compilado con %s y enlazado con módulos que usan reubicaciones que no son pic"
+
+#: elf32-frv.c:6775 elf32-iq2000.c:845 elf32-m32c.c:807
+#, c-format
+msgid "%s: compiled with %s and linked with modules compiled with %s"
+msgstr "%s: compilado con %s y enlazado con módulos compilados con %s"
+
+#: elf32-frv.c:6787
+#, c-format
+msgid "%s: uses different unknown e_flags (0x%lx) fields than previous modules (0x%lx)"
+msgstr "%s: usa campos e_flags desconocidos (0x%lx) diferentes a aquéllos de los módulos previos (0x%lx)"
+
+#: elf32-frv.c:6837 elf32-iq2000.c:882 elf32-m32c.c:843 elf32-mt.c:576
+#: elf32-rx.c:3001
+#, c-format
+msgid "private flags = 0x%lx:"
+msgstr "opciones privadas = 0x%lx:"
+
+#: elf32-gen.c:69 elf64-gen.c:69
+msgid "%B: Relocations in generic ELF (EM: %d)"
+msgstr "%B: Reubicaciones en ELF genérico (EM: %d)"
+
+#: elf32-hppa.c:850 elf32-hppa.c:3598
+msgid "%B(%A+0x%lx): cannot reach %s, recompile with -ffunction-sections"
+msgstr "%B(%A+0x%lx): no se puede alcanzar %s, recompile con -ffuntion-sections"
+
+#: elf32-hppa.c:1284
+msgid "%B: relocation %s can not be used when making a shared object; recompile with -fPIC"
+msgstr "%B: no se puede usar la reubicación %s cuando se hace un objeto compartido; recompile con -fPIC"
+
+#: elf32-hppa.c:2791
+msgid "%B: duplicate export stub %s"
+msgstr "%B: cabo de exportación %s duplicado"
+
+#: elf32-hppa.c:3437
+msgid "%B(%A+0x%lx): %s fixup for insn 0x%x is not supported in a non-shared link"
+msgstr "%B(%A+0x%lx): la compostura %s para la insn 0x%x no se admite en un enlazado que no es compartido"
+
+#: elf32-hppa.c:4284
+msgid "%B(%A+0x%lx): cannot handle %s for %s"
+msgstr "%B(%A+0x%lx): no se puede manejar %s para %s"
+
+#: elf32-hppa.c:4603
+msgid ".got section not immediately after .plt section"
+msgstr "la sección .got no está inmediatamente después de la sección .plt"
+
+#. Unknown relocation.
+#: elf32-i386.c:373 elf32-m68k.c:384 elf32-ppc.c:1676 elf32-s390.c:379
+#: elf32-tic6x.c:2684 elf64-ppc.c:2300 elf64-s390.c:403 elf64-x86-64.c:265
+msgid "%B: invalid relocation type %d"
+msgstr "%B: tipo de reubicación %d inválido"
+
+#: elf32-i386.c:1404 elf64-x86-64.c:1308
+msgid "%B: TLS transition from %s to %s against `%s' at 0x%lx in section `%A' failed"
+msgstr "%B: falló la transición TLS de %s para %s contra `%s' en 0x%lx en la sección `%A'"
+
+#: elf32-i386.c:1549 elf32-i386.c:3244 elf64-x86-64.c:1487 elf64-x86-64.c:3125
+#: elfxx-sparc.c:3083
+msgid "%B: relocation %s against STT_GNU_IFUNC symbol `%s' isn't handled by %s"
+msgstr "%B: la reubicación %s contra el símbolo STT_GNU_IFUNC `%s' no es manejada por %s"
+
+#: elf32-i386.c:1711 elf32-s390.c:1182 elf32-sh.c:6362 elf32-tilepro.c:1434
+#: elf32-xtensa.c:1182 elf64-s390.c:1151 elfxx-sparc.c:1548
+#: elfxx-tilegx.c:1701
+msgid "%B: `%s' accessed both as normal and thread local symbol"
+msgstr "%B: se accedió `%s' como un símbolo normal y un símbolo local de hilo"
+
+#: elf32-i386.c:2539 elf64-x86-64.c:2506
+msgid "%P: %B: warning: relocation against `%s' in readonly section `%A'.\n"
+msgstr "%P: %B: aviso: reubicación contra `%s' en la sección de sólo lectura `%A'.\n"
+
+#: elf32-i386.c:2629 elf64-x86-64.c:2593
+msgid "%P: %B: warning: relocation in readonly section `%A'.\n"
+msgstr "%P: %B: aviso: reubicación en la sección de sólo lectura `%A'.\n"
+
+#: elf32-i386.c:3086 elf32-tilepro.c:2557 elfxx-tilegx.c:2871
+msgid "%B: unrecognized relocation (0x%x) in section `%A'"
+msgstr "%B: no se reconoce la dirección de reubicación (0x%lx) en la sección `%A'"
+
+#: elf32-i386.c:3494 elf64-x86-64.c:3513
+msgid "hidden symbol"
+msgstr "símbolo oculto"
+
+#: elf32-i386.c:3497 elf64-x86-64.c:3516
+msgid "internal symbol"
+msgstr "símbolo interno"
+
+#: elf32-i386.c:3500 elf64-x86-64.c:3519
+msgid "protected symbol"
+msgstr "símbolo protegido"
+
+#: elf32-i386.c:3503 elf64-x86-64.c:3522
+msgid "symbol"
+msgstr "símbolo"
+
+#: elf32-i386.c:3508
+msgid "%B: relocation R_386_GOTOFF against undefined %s `%s' can not be used when making a shared object"
+msgstr "%B: no se puede usar la reubicación R_386_GOTOFF contra %s indefinida `%s' cuando se hace un objeto compartido"
+
+#: elf32-i386.c:3518
+msgid "%B: relocation R_386_GOTOFF against protected function `%s' can not be used when making a shared object"
+msgstr "%B: no se puede usar la reubicación R_386_GOTOFF contra la función protegida `%s' cuando se hace un objeto compartido"
+
+#: elf32-i386.c:4839 elf32-tilepro.c:3467 elf64-x86-64.c:4609
+#: elfxx-tilegx.c:3847
+#, c-format
+msgid "discarded output section: `%A'"
+msgstr "se descarta la sección de salida: `%A'"
+
+#: elf32-ip2k.c:857 elf32-ip2k.c:863 elf32-ip2k.c:930 elf32-ip2k.c:936
+msgid "ip2k relaxer: switch table without complete matching relocation information."
+msgstr "relajador ip2k: tabla switch sin información completa de reubicación de coincidencias."
+
+#: elf32-ip2k.c:880 elf32-ip2k.c:963
+msgid "ip2k relaxer: switch table header corrupt."
+msgstr "relajador ip2k: encabezado de tabla switch corrupto."
+
+#: elf32-ip2k.c:1292
+#, c-format
+msgid "ip2k linker: missing page instruction at 0x%08lx (dest = 0x%08lx)."
+msgstr "enlazador ip2k: falta la instrucción de página en 0x%08lx (dest = 0x%08lx)."
+
+#: elf32-ip2k.c:1308
+#, c-format
+msgid "ip2k linker: redundant page instruction at 0x%08lx (dest = 0x%08lx)."
+msgstr "enlazador ip2k: instrucción de página redundante en 0x%08lx (dest = 0x%08lx)."
+
+#: elf32-iq2000.c:858 elf32-m32c.c:819
+#, c-format
+msgid "%s: uses different e_flags (0x%lx) fields than previous modules (0x%lx)"
+msgstr "%s: usa campos de e_flags diferentes (0x%lx) que los módulos previos (0x%lx)"
+
+#: elf32-lm32.c:706
+msgid "global pointer relative relocation when _gp not defined"
+msgstr "reubicación relativa al puntero global cuando _gp no está definido"
+
+#: elf32-lm32.c:761
+msgid "global pointer relative address out of range"
+msgstr "dirección relativa al puntero global fuera de rango"
+
+#: elf32-lm32.c:1057
+msgid "internal error: addend should be zero for R_LM32_16_GOT"
+msgstr "error interno: addend debe ser cero para R_LM32_16_GOT"
+
+#: elf32-m32r.c:1453
+msgid "SDA relocation when _SDA_BASE_ not defined"
+msgstr "reubicación SDA cuando _SDA_BASE_ no está definido"
+
+#: elf32-m32r.c:3043
+msgid "%B: The target (%s) of an %s relocation is in the wrong section (%A)"
+msgstr "%B: El objetivo (%s) de una reubicación %s está en la sección errónea (%A)"
+
+#: elf32-m32r.c:3571
+msgid "%B: Instruction set mismatch with previous modules"
+msgstr "%B: El conjunto de instrucciones no coincide con módulos previos"
+
+#: elf32-m32r.c:3592
+#, c-format
+msgid "private flags = %lx"
+msgstr "opciones privadas = %lx"
+
+#: elf32-m32r.c:3597
+#, c-format
+msgid ": m32r instructions"
+msgstr ": instrucciones m32r"
+
+#: elf32-m32r.c:3598
+#, c-format
+msgid ": m32rx instructions"
+msgstr ": instrucciones m32rx"
+
+#: elf32-m32r.c:3599
+#, c-format
+msgid ": m32r2 instructions"
+msgstr ": instrucciones m32r2"
+
+#: elf32-m68hc1x.c:1050
+#, c-format
+msgid "Reference to the far symbol `%s' using a wrong relocation may result in incorrect execution"
+msgstr "El referenciar al símbolo far `%s' usando una reubicación incorrecta puede resultar en una ejecución incorrecta"
+
+#: elf32-m68hc1x.c:1073
+#, c-format
+msgid "banked address [%lx:%04lx] (%lx) is not in the same bank as current banked address [%lx:%04lx] (%lx)"
+msgstr "la dirección almacenada [%lx:%04lx] (%lx) no está en el mismo banco que la dirección almacenada actual [%lx:%04lx] (%lx)"
+
+#: elf32-m68hc1x.c:1092
+#, c-format
+msgid "reference to a banked address [%lx:%04lx] in the normal address space at %04lx"
+msgstr "referencia a una dirección almacenada [%lx:%04lx] en el espacio normal de direcciones en %04lx"
+
+#: elf32-m68hc1x.c:1225
+msgid "%B: linking files compiled for 16-bit integers (-mshort) and others for 32-bit integers"
+msgstr "%B: se enlazan ficheros compilados con enteros de 16-bit (-mshort) y otros con enteros de 32-bit"
+
+#: elf32-m68hc1x.c:1232
+msgid "%B: linking files compiled for 32-bit double (-fshort-double) and others for 64-bit double"
+msgstr "%B: se enlazan ficheros compilados con dobles de 32-bit (-fshort-double) y otros con dobles de 64-bit"
+
+#: elf32-m68hc1x.c:1241
+msgid "%B: linking files compiled for HCS12 with others compiled for HC12"
+msgstr "%B: se enlazan ficheros compilados para HCS12, con otros compilados para HC12"
+
+#: elf32-m68hc1x.c:1257 elf32-ppc.c:4227 elf64-sparc.c:706 elfxx-mips.c:13965
+msgid "%B: uses different e_flags (0x%lx) fields than previous modules (0x%lx)"
+msgstr "%B: usa campos de e_flags diferentes (0x%lx) que los módulos previos (0x%lx)"
+
+#: elf32-m68hc1x.c:1285
+#, c-format
+msgid "[abi=32-bit int, "
+msgstr "[abi=int de 32-bit, "
+
+#: elf32-m68hc1x.c:1287
+#, c-format
+msgid "[abi=16-bit int, "
+msgstr "[abi=int de 16-bit, "
+
+#: elf32-m68hc1x.c:1290
+#, c-format
+msgid "64-bit double, "
+msgstr "doble de 64-bit, "
+
+#: elf32-m68hc1x.c:1292
+#, c-format
+msgid "32-bit double, "
+msgstr "doble de 32-bit, "
+
+#: elf32-m68hc1x.c:1295
+#, c-format
+msgid "cpu=HC11]"
+msgstr "cpu=HC11]"
+
+#: elf32-m68hc1x.c:1297
+#, c-format
+msgid "cpu=HCS12]"
+msgstr "cpu=HCS12]"
+
+#: elf32-m68hc1x.c:1299
+#, c-format
+msgid "cpu=HC12]"
+msgstr "cpu=HC12]"
+
+#: elf32-m68hc1x.c:1302
+#, c-format
+msgid " [memory=bank-model]"
+msgstr " [memoria=modelo de bancos]"
+
+#: elf32-m68hc1x.c:1304
+#, c-format
+msgid " [memory=flat]"
+msgstr " [memoria=plana]"
+
+#: elf32-m68k.c:1251 elf32-m68k.c:1252 vms-alpha.c:7314 vms-alpha.c:7329
+msgid "unknown"
+msgstr "desconocido"
+
+#: elf32-m68k.c:1715
+msgid "%B: GOT overflow: Number of relocations with 8-bit offset > %d"
+msgstr "%B: desbordamiento de GOT: Número de reubicaciones con desplazamiento de 8-bit > %d"
+
+#: elf32-m68k.c:1721
+msgid "%B: GOT overflow: Number of relocations with 8- or 16-bit offset > %d"
+msgstr "%B: desbordamiento de GOT: Número de reubicaciones con desplazamiento de 8 o 16-bit > %d"
+
+#: elf32-m68k.c:3957
+msgid "%B(%A+0x%lx): R_68K_TLS_LE32 relocation not permitted in shared object"
+msgstr "%B(%A+0x%lx): la reubicación R_68K_TLS_LE32 no se permite en objetos compartidos"
+
+#: elf32-mcore.c:99 elf32-mcore.c:442
+msgid "%B: Relocation %s (%d) is not currently supported.\n"
+msgstr "%B: Actualmente no se admite la reubicación %s (%d).\n"
+
+#: elf32-mcore.c:428
+msgid "%B: Unknown relocation type %d\n"
+msgstr "%B: Tipo de reubicación %d desconocido\n"
+
+#. Pacify gcc -Wall.
+#: elf32-mep.c:157
+#, c-format
+msgid "mep: no reloc for code %d"
+msgstr "mep: no hay reubicación para el código %d"
+
+#: elf32-mep.c:163
+#, c-format
+msgid "MeP: howto %d has type %d"
+msgstr "MeP: howto %d tiene el tipo %d"
+
+#: elf32-mep.c:648
+msgid "%B and %B are for different cores"
+msgstr "%B y %B son para núcleos diferentes"
+
+#: elf32-mep.c:665
+msgid "%B and %B are for different configurations"
+msgstr "%B y %B son para configuraciones diferentes"
+
+#: elf32-mep.c:702
+#, c-format
+msgid "private flags = 0x%lx"
+msgstr "opciones privadas = 0x%lx"
+
+#: elf32-microblaze.c:742
+#, c-format
+msgid "%s: unknown relocation type %d"
+msgstr "%s: tipo de reubicación %d desconocido"
+
+#: elf32-microblaze.c:867 elf32-microblaze.c:912
+#, c-format
+msgid "%s: The target (%s) of an %s relocation is in the wrong section (%s)"
+msgstr "%s: El objetivo (%s) de una reubicación %s está en la sección errónea (%s)"
+
+#: elf32-microblaze.c:1155 elf32-tilepro.c:2891 elfxx-sparc.c:3457
+#: elfxx-tilegx.c:3230
+msgid "%B: probably compiled without -fPIC?"
+msgstr "%B: ¿Compilado probablemente sin -fPIC?"
+
+#: elf32-microblaze.c:2074
+msgid "%B: bad relocation section name `%s'"
+msgstr "%B: nombre de sección de reubicación `%s' erróneo"
+
+#: elf32-mips.c:1549 elf64-mips.c:2683 elfn32-mips.c:2487
+msgid "literal relocation occurs for an external symbol"
+msgstr "la reubicación literal sucede para un símbolo externo"
+
+#: elf32-mips.c:1596 elf32-score.c:570 elf32-score7.c:469 elf64-mips.c:2726
+#: elfn32-mips.c:2528
+msgid "32bits gp relative relocation occurs for an external symbol"
+msgstr "la reubicación relativa a gp de 32bits sucede para un símbolo externo"
+
+#: elf32-ppc.c:1741
+#, c-format
+msgid "generic linker can't handle %s"
+msgstr "el enlazador genérico no puede manejar %s"
+
+#: elf32-ppc.c:2184
+msgid "corrupt %s section in %B"
+msgstr "sección %s corrupta en %B"
+
+#: elf32-ppc.c:2203
+msgid "unable to read in %s section from %B"
+msgstr "no se puede leer en la sección %s desde %B"
+
+#: elf32-ppc.c:2244
+msgid "warning: unable to set size of %s section in %B"
+msgstr "aviso: no se puede establecer el tamaño de la sección %s en %B"
+
+#: elf32-ppc.c:2294
+msgid "failed to allocate space for new APUinfo section."
+msgstr "no se puede reservar espacio para la nueva sección APUinfo."
+
+#: elf32-ppc.c:2313
+msgid "failed to compute new APUinfo section."
+msgstr "no se puede calcular la nueva sección APUinfo."
+
+#: elf32-ppc.c:2316
+msgid "failed to install new APUinfo section."
+msgstr "no se puede instalar la nueva sección APUinfo."
+
+#: elf32-ppc.c:3356
+msgid "%B: relocation %s cannot be used when making a shared object"
+msgstr "%B: no se puede usar la reubicación %s cuando se hace un objeto compartido"
+
+#. It does not make sense to have a procedure linkage
+#. table entry for a local symbol.
+#: elf32-ppc.c:3700
+msgid "%P: %H: %s reloc against local symbol\n"
+msgstr "%P: %H: reubicación %s contra un símbolo local\n"
+
+#: elf32-ppc.c:4039 elf32-ppc.c:4054 elfxx-mips.c:13651 elfxx-mips.c:13677
+#: elfxx-mips.c:13699 elfxx-mips.c:13725
+msgid "Warning: %B uses hard float, %B uses soft float"
+msgstr "Aviso: %B usa coma flotante hard, %B usa coma flotante soft"
+
+#: elf32-ppc.c:4042 elf32-ppc.c:4046
+msgid "Warning: %B uses double-precision hard float, %B uses single-precision hard float"
+msgstr "Aviso: %B usa coma flotante hard de doble precisión, %B usa coma flotante hard de precisión simple"
+
+#: elf32-ppc.c:4050
+msgid "Warning: %B uses soft float, %B uses single-precision hard float"
+msgstr "Aviso: %B usa coma flotante soft, %B usa coma flotante hard de precisión simple"
+
+#: elf32-ppc.c:4057 elf32-ppc.c:4061 elfxx-mips.c:13631 elfxx-mips.c:13635
+msgid "Warning: %B uses unknown floating point ABI %d"
+msgstr "Aviso: %B usa la ABI de coma flotante desconocida %d"
+
+#: elf32-ppc.c:4103 elf32-ppc.c:4107
+msgid "Warning: %B uses unknown vector ABI %d"
+msgstr "Aviso: %B usa la ABI de vector desconocida %d"
+
+#: elf32-ppc.c:4111
+msgid "Warning: %B uses vector ABI \"%s\", %B uses \"%s\""
+msgstr "Aviso: %B usa la ABI de vector \"%s\", %B usa \"%s\""
+
+#: elf32-ppc.c:4128 elf32-ppc.c:4131
+msgid "Warning: %B uses r3/r4 for small structure returns, %B uses memory"
+msgstr "Aviso: %B usa r3/r4 para devoluciones de estructura small, %B usa memoria"
+
+#: elf32-ppc.c:4134 elf32-ppc.c:4138
+msgid "Warning: %B uses unknown small structure return convention %d"
+msgstr "Aviso: %B usa la convención de devolución de estructura small %d"
+
+#: elf32-ppc.c:4192
+msgid "%B: compiled with -mrelocatable and linked with modules compiled normally"
+msgstr "%B: compilado con -mrelocatable y enlazado con módulos compilados de forma normal"
+
+#: elf32-ppc.c:4200
+msgid "%B: compiled normally and linked with modules compiled with -mrelocatable"
+msgstr "%B: compilado de forma normal y enlazado con módulos compilados con -mrelocatable"
+
+#: elf32-ppc.c:4309
+msgid "%P: bss-plt forced due to %B\n"
+msgstr "%P: se fuerza bss-plt debido a %B\n"
+
+#: elf32-ppc.c:4312
+msgid "%P: bss-plt forced by profiling\n"
+msgstr "%P: se fuerza bss-plt por análisis de perfil\n"
+
+#. Uh oh, we didn't find the expected call. We
+#. could just mark this symbol to exclude it
+#. from tls optimization but it's safer to skip
+#. the entire optimization.
+#: elf32-ppc.c:4809 elf64-ppc.c:7858
+msgid "%H arg lost __tls_get_addr, TLS optimization disabled\n"
+msgstr "%H el argumento perdió __tls_get_addr, se desactiva la optimización TLS\n"
+
+#: elf32-ppc.c:5044 elf64-ppc.c:6528
+msgid "%P: dynamic variable `%s' is zero size\n"
+msgstr "%P: la variable dinámica `%s' es de tamaño cero\n"
+
+#: elf32-ppc.c:7263 elf64-ppc.c:12675
+msgid "%P: %B: unknown relocation type %d for symbol %s\n"
+msgstr "%P: %B: tipo de reubicación %d desconocida para el símbolo %s\n"
+
+#: elf32-ppc.c:7524
+msgid "%P: %H: non-zero addend on %s reloc against `%s'\n"
+msgstr "%P: %H: adición que no es cero en la reubicación %s contra `%s'\n"
+
+#: elf32-ppc.c:7720 elf64-ppc.c:13181
+msgid "%P: %H: relocation %s for indirect function %s unsupported\n"
+msgstr "%P: %H: no se admite la reubicación %s para la función indirecta %s\n"
+
+#: elf32-ppc.c:7948 elf32-ppc.c:7978 elf32-ppc.c:8025
+msgid "%P: %B: the target (%s) of a %s relocation is in the wrong output section (%s)\n"
+msgstr "%P: %B: el objetivo (%s) de una reubicación %s está en la sección de salida errónea (%s)\n"
+
+#: elf32-ppc.c:8097
+msgid "%P: %B: relocation %s is not yet supported for symbol %s\n"
+msgstr "%P: %B: la reubicación %s aún no se admite para el símbolo %s\n"
+
+#: elf32-ppc.c:8158 elf64-ppc.c:13467
+msgid "%P: %H: unresolvable %s relocation against symbol `%s'\n"
+msgstr "%P: %H: reubicación %s sin resolución contra el símbolo `%s'\n"
+
+#: elf32-ppc.c:8205 elf64-ppc.c:13512
+msgid "%P: %H: %s reloc against `%s': error %d\n"
+msgstr "%P: %H: reubicación %s contra `%s': error %d\n"
+
+#: elf32-ppc.c:8696
+msgid "%P: %s not defined in linker created %s\n"
+msgstr "%P: no se definió %s en el %s creado por el enlazador\n"
+
+#: elf32-rx.c:563
+msgid "%B:%A: Warning: deprecated Red Hat reloc "
+msgstr "%B:%A: Aviso: reubicación Red Hat obsoleta"
+
+#. Check for unsafe relocs in PID mode. These are any relocs where
+#. an absolute address is being computed. There are special cases
+#. for relocs against symbols that are known to be referenced in
+#. crt0.o before the PID base address register has been initialised.
+#: elf32-rx.c:581
+msgid "%B(%A): unsafe PID relocation %s at 0x%08lx (against %s in %s)"
+msgstr "%B(%A): aviso: reubicación PID %s insegura en 0x%08lx (contra %s en %s)"
+
+#: elf32-rx.c:1157
+msgid "Warning: RX_SYM reloc with an unknown symbol"
+msgstr "Aviso: reubicación RX_SYM con un símbolo desconocido"
+
+#: elf32-rx.c:1324
+msgid "%B(%A): error: call to undefined function '%s'"
+msgstr "%B(%A): error: llamada a la función sin definir '%s'"
+
+#: elf32-rx.c:1338
+msgid "%B(%A): warning: unaligned access to symbol '%s' in the small data area"
+msgstr "%B(%A): aviso: acceso sin alinear al símbolo '%s' en el área de datos small"
+
+#: elf32-rx.c:1342
+msgid "%B(%A): internal error: out of range error"
+msgstr "%B(%A): error interno: error fuera de rango"
+
+#: elf32-rx.c:1346
+msgid "%B(%A): internal error: unsupported relocation error"
+msgstr "%B(%A): error interno: no se admite el error de reubicación"
+
+#: elf32-rx.c:1350
+msgid "%B(%A): internal error: dangerous relocation"
+msgstr "%B(%A): error interno: reubicación peligrosa"
+
+#: elf32-rx.c:1354
+msgid "%B(%A): internal error: unknown error"
+msgstr "%B(%A): error interno: error desconocido"
+
+#: elf32-rx.c:3004
+#, c-format
+msgid " [64-bit doubles]"
+msgstr " [dobles de 64-bit]"
+
+#: elf32-rx.c:3006
+#, c-format
+msgid " [dsp]"
+msgstr " [dsp]"
+
+#: elf32-s390.c:2200 elf64-s390.c:2187
+msgid "%B(%A+0x%lx): invalid instruction for TLS relocation %s"
+msgstr "%B(%A+0x%lx): instrucción inválida para la reubicación TLS %s"
+
+#: elf32-score.c:1520 elf32-score7.c:1379 elfxx-mips.c:3435
+msgid "not enough GOT space for local GOT entries"
+msgstr "no hay suficiente espacio GOT para entradas GOT locales"
+
+#: elf32-score.c:2742
+msgid "address not word align"
+msgstr "la dirección no está alineada a word"
+
+#: elf32-score.c:2827 elf32-score7.c:2631
+#, c-format
+msgid "%s: Malformed reloc detected for section %s"
+msgstr "%s: Se detectó una reubicación malformada para la sección %s"
+
+#: elf32-score.c:2878 elf32-score7.c:2682
+msgid "%B: CALL15 reloc at 0x%lx not against global symbol"
+msgstr "%B: la reubicación CALL15 en 0x%lx no es contra un símbolo global"
+
+#: elf32-score.c:3997 elf32-score7.c:3803
+#, c-format
+msgid " [pic]"
+msgstr " [pic]"
+
+#: elf32-score.c:4001 elf32-score7.c:3807
+#, c-format
+msgid " [fix dep]"
+msgstr " [fix dep]"
+
+#: elf32-score.c:4043 elf32-score7.c:3849
+msgid "%B: warning: linking PIC files with non-PIC files"
+msgstr "%B: aviso: se enlazan ficheros PIC con ficheros que no son PIC"
+
+#: elf32-sh-symbian.c:130
+msgid "%B: IMPORT AS directive for %s conceals previous IMPORT AS"
+msgstr "%B: la directiva IMPORT AS para %s oculta un IMPORT AS previo"
+
+#: elf32-sh-symbian.c:383
+msgid "%B: Unrecognised .directive command: %s"
+msgstr "%B: No se reconoce la orden .directive: %s"
+
+#: elf32-sh-symbian.c:504
+msgid "%B: Failed to add renamed symbol %s"
+msgstr "%B: Falló al agregar el símbolo renombrado %s"
+
+#: elf32-sh.c:568
+msgid "%B: 0x%lx: warning: bad R_SH_USES offset"
+msgstr "%B: 0x%lx: aviso: desplazamiento R_SH_USES erróneo"
+
+#: elf32-sh.c:580
+msgid "%B: 0x%lx: warning: R_SH_USES points to unrecognized insn 0x%x"
+msgstr "%B: 0x%lx: aviso: R_SH_USES señala al insn 0x%x que no se reconoce"
+
+#: elf32-sh.c:597
+msgid "%B: 0x%lx: warning: bad R_SH_USES load offset"
+msgstr "%B: 0x%lx: aviso: desplazamiento de carga R_SH_USES erróneo"
+
+#: elf32-sh.c:612
+msgid "%B: 0x%lx: warning: could not find expected reloc"
+msgstr "%B: 0x%lx: aviso: no se puede encontrar la reubicación esperada"
+
+#: elf32-sh.c:640
+msgid "%B: 0x%lx: warning: symbol in unexpected section"
+msgstr "%B: 0x%lx: aviso: símbolo en una sección inesperada"
+
+#: elf32-sh.c:766
+msgid "%B: 0x%lx: warning: could not find expected COUNT reloc"
+msgstr "%B: 0x%lx: aviso: no se puede encontrar la reubicación COUNT esperada"
+
+#: elf32-sh.c:775
+msgid "%B: 0x%lx: warning: bad count"
+msgstr "%B: 0x%lx: aviso: cuenta errónea"
+
+#: elf32-sh.c:1179 elf32-sh.c:1549
+msgid "%B: 0x%lx: fatal: reloc overflow while relaxing"
+msgstr "%B: 0x%lx: fatal: desbordamiento de reubicación durante la relajación"
+
+#: elf32-sh.c:4048 elf64-sh64.c:1514
+msgid "Unexpected STO_SH5_ISA32 on local symbol is not handled"
+msgstr "No se maneja un STO_SH5_ISA32 inesperado en un símbolo local"
+
+#: elf32-sh.c:4299
+msgid "%B: 0x%lx: fatal: unaligned branch target for relax-support relocation"
+msgstr "%B: 0x%lx: fatal: objetivo de ramificación sin alineación para la reubicación de soporte de relajamiento"
+
+#: elf32-sh.c:4332 elf32-sh.c:4347
+msgid "%B: 0x%lx: fatal: unaligned %s relocation 0x%lx"
+msgstr "%B: 0x%lx: fatal: reubicación %s sin alineación 0x%lx"
+
+#: elf32-sh.c:4361
+msgid "%B: 0x%lx: fatal: R_SH_PSHA relocation %d not in range -32..32"
+msgstr "%B: 0x%lx: fatal: la reubicación R_SH_PSHA %d no está en el rango -32..32"
+
+#: elf32-sh.c:4375
+msgid "%B: 0x%lx: fatal: R_SH_PSHL relocation %d not in range -32..32"
+msgstr "%B: 0x%lx: fatal: la reubicación R_SH_PSHL %d no está en el rango -32..32"
+
+#: elf32-sh.c:4519 elf32-sh.c:4989
+msgid "%B(%A+0x%lx): cannot emit fixup to `%s' in read-only section"
+msgstr "%B(%A+0x%lx): no se pueden emitir composturas para `%s' en la sección de sólo lectura"
+
+#: elf32-sh.c:5096
+msgid "%B(%A+0x%lx): %s relocation against external symbol \"%s\""
+msgstr "%B(%A+0x%lx): reubicación %s contra el símbolo externo \"%s\""
+
+#: elf32-sh.c:5569
+#, c-format
+msgid "%X%C: relocation to \"%s\" references a different segment\n"
+msgstr "%X%C: la reubicación de \"%s\" referencía un segmento diferente\n"
+
+#: elf32-sh.c:5575
+#, c-format
+msgid "%C: warning: relocation to \"%s\" references a different segment\n"
+msgstr "%C: aviso: la reubicación de \"%s\" referencía un segmento diferente\n"
+
+#: elf32-sh.c:6353 elf32-sh.c:6436
+msgid "%B: `%s' accessed both as normal and FDPIC symbol"
+msgstr "%B: se accedió `%s' como un símbolo normal y un símbolo FDPIC"
+
+#: elf32-sh.c:6358 elf32-sh.c:6440
+msgid "%B: `%s' accessed both as FDPIC and thread local symbol"
+msgstr "%B: se accedió `%s' como un símbolo FDPIC y un símbolo local de hilo"
+
+#: elf32-sh.c:6388
+msgid "%B: Function descriptor relocation with non-zero addend"
+msgstr "%B: Reubicación de descriptor de función con adición que no es cero"
+
+#: elf32-sh.c:6624 elf64-alpha.c:4652
+msgid "%B: TLS local exec code cannot be linked into shared objects"
+msgstr "%B: el código de ejecución local TLS no se puede enlazar en objetos compartidos"
+
+#: elf32-sh64.c:223 elf64-sh64.c:2318
+#, c-format
+msgid "%s: compiled as 32-bit object and %s is 64-bit"
+msgstr "%s: compilado como un objeto de 32-bit y %s es de 64-bit"
+
+#: elf32-sh64.c:226 elf64-sh64.c:2321
+#, c-format
+msgid "%s: compiled as 64-bit object and %s is 32-bit"
+msgstr "%s: compilado como un objeto de 64-bit y %s es de 32-bit"
+
+#: elf32-sh64.c:228 elf64-sh64.c:2323
+#, c-format
+msgid "%s: object size does not match that of target %s"
+msgstr "%s: el tamaño del objeto no coincide con el tamaño del objetivo %s"
+
+#: elf32-sh64.c:451 elf64-sh64.c:2837
+#, c-format
+msgid "%s: encountered datalabel symbol in input"
+msgstr "%s: se encontró un símbolo datalabel en la entrada"
+
+#: elf32-sh64.c:528
+msgid "PTB mismatch: a SHmedia address (bit 0 == 1)"
+msgstr "No coincide PTB: una dirección SHmedia (bit 0 == 1)"
+
+#: elf32-sh64.c:531
+msgid "PTA mismatch: a SHcompact address (bit 0 == 0)"
+msgstr "No coincide PTA: una dirección SHcompact (bit 0 == 0)"
+
+#: elf32-sh64.c:549
+#, c-format
+msgid "%s: GAS error: unexpected PTB insn with R_SH_PT_16"
+msgstr "%s: error de GAS: insn PTB inesperada con R_SH_PT_16"
+
+#: elf32-sh64.c:598
+msgid "%B: error: unaligned relocation type %d at %08x reloc %p\n"
+msgstr "%B: error: tipo de reubicación %d sin alinear en %08x reubicación %p\n"
+
+#: elf32-sh64.c:674
+#, c-format
+msgid "%s: could not write out added .cranges entries"
+msgstr "%s: no se pueden escribir las entradas .cranges agregadas"
+
+#: elf32-sh64.c:734
+#, c-format
+msgid "%s: could not write out sorted .cranges entries"
+msgstr "%s: no se pueden escribir las entradas .cranges ordenadas"
+
+#: elf32-sparc.c:90
+msgid "%B: compiled for a 64 bit system and target is 32 bit"
+msgstr "%B: compilado para un sistema de 64 bit y el objetivo es de 32 bit"
+
+#: elf32-sparc.c:103
+msgid "%B: linking little endian files with big endian files"
+msgstr "%B: se enlazan ficheros little endian con ficheros big endian"
+
+#: elf32-spu.c:719
+msgid "%X%P: overlay section %A does not start on a cache line.\n"
+msgstr "%X%P: la sección de sobreescritura %A no inicia en una línea de caché.\n"
+
+#: elf32-spu.c:727
+msgid "%X%P: overlay section %A is larger than a cache line.\n"
+msgstr "%X%P: la sección de sobreescritura %A es más grande que una línea de caché.\n"
+
+#: elf32-spu.c:747
+msgid "%X%P: overlay section %A is not in cache area.\n"
+msgstr "%X%P: la sección de sobreescritura %A no está en el área de caché.\n"
+
+#: elf32-spu.c:787
+msgid "%X%P: overlay sections %A and %A do not start at the same address.\n"
+msgstr "%X%P: las secciones de sobreescritura %A y %A no inician en la misma dirección.\n"
+
+#: elf32-spu.c:1011
+msgid "warning: call to non-function symbol %s defined in %B"
+msgstr "aviso: se llama al símbolo %s que no es función, definido en %B"
+
+#: elf32-spu.c:1361
+msgid "%A:0x%v lrlive .brinfo (%u) differs from analysis (%u)\n"
+msgstr "%A:0x%v lrlive .brinfo (%u) difiere del análisis (%u)\n"
+
+#: elf32-spu.c:1880
+msgid "%B is not allowed to define %s"
+msgstr "%B no tiene permitido definir %s"
+
+#: elf32-spu.c:1888
+#, c-format
+msgid "you are not allowed to define %s in a script"
+msgstr "no se le permite definir %s en un guión"
+
+#: elf32-spu.c:1922
+#, c-format
+msgid "%s in overlay section"
+msgstr "%s en la sección de sobreescritura"
+
+#: elf32-spu.c:1951
+msgid "overlay stub relocation overflow"
+msgstr "desbordamiento de la reubicación de cabo de sobreescritura"
+
+#: elf32-spu.c:1960
+msgid "stubs don't match calculated size"
+msgstr "los cabos no coinciden con el tamaño calculado"
+
+#: elf32-spu.c:2542
+#, c-format
+msgid "warning: %s overlaps %s\n"
+msgstr "aviso: %s sobreescribe %s\n"
+
+#: elf32-spu.c:2558
+#, c-format
+msgid "warning: %s exceeds section size\n"
+msgstr "aviso: %s excede el tamaño de la sección\n"
+
+#: elf32-spu.c:2589
+msgid "%A:0x%v not found in function table\n"
+msgstr "%A:0x%v no se encuentra en la tabla de función\n"
+
+#: elf32-spu.c:2729
+msgid "%B(%A+0x%v): call to non-code section %B(%A), analysis incomplete\n"
+msgstr "%B(%A+0x%v): se llama a la sección %B(%A) que no es de código, análisis incompleto\n"
+
+#: elf32-spu.c:3297
+#, c-format
+msgid "Stack analysis will ignore the call from %s to %s\n"
+msgstr "El análisis de pila descartará la llamada de %s a %s\n"
+
+#: elf32-spu.c:3988
+msgid " %s: 0x%v\n"
+msgstr " %s: 0x%v\n"
+
+#: elf32-spu.c:3989
+msgid "%s: 0x%v 0x%v\n"
+msgstr "%s: 0x%v 0x%v\n"
+
+#: elf32-spu.c:3994
+msgid " calls:\n"
+msgstr " llama:\n"
+
+#: elf32-spu.c:4002
+#, c-format
+msgid " %s%s %s\n"
+msgstr " %s%s %s\n"
+
+#: elf32-spu.c:4307
+#, c-format
+msgid "%s duplicated in %s\n"
+msgstr "%s duplicado en %s\n"
+
+#: elf32-spu.c:4311
+#, c-format
+msgid "%s duplicated\n"
+msgstr "%s duplicado\n"
+
+#: elf32-spu.c:4318
+msgid "sorry, no support for duplicate object files in auto-overlay script\n"
+msgstr "perdón, no se admiten ficheros objeto duplicados en el guión de sobreescritura automática\n"
+
+#: elf32-spu.c:4359
+msgid "non-overlay size of 0x%v plus maximum overlay size of 0x%v exceeds local store\n"
+msgstr "eltamaño 0x%v que no es de sobreescritura mas el tamaño de sobreescritura máximo de 0x%v excede el almacenamiento local\n"
+
+#: elf32-spu.c:4514
+msgid "%B:%A%s exceeds overlay size\n"
+msgstr "%B:%A%s excede el tamaño de sobreescritura\n"
+
+#: elf32-spu.c:4676
+msgid "Stack size for call graph root nodes.\n"
+msgstr "Tamaño de la pila para los nodos raíz del grafo de llamadas.\n"
+
+#: elf32-spu.c:4677
+msgid ""
+"\n"
+"Stack size for functions. Annotations: '*' max stack, 't' tail call\n"
+msgstr ""
+"\n"
+"Tamaño de la pila para funciones. Anotaciones: '*' max de pila, 't' llamada cola\n"
+
+#: elf32-spu.c:4687
+msgid "Maximum stack required is 0x%v\n"
+msgstr "La pila máxima requerida es 0x%v\n"
+
+#: elf32-spu.c:4778
+msgid "fatal error while creating .fixup"
+msgstr "error fatal al crear .fixup"
+
+#: elf32-spu.c:5008
+msgid "%B(%s+0x%lx): unresolvable %s relocation against symbol `%s'"
+msgstr "%B(%s+0x%lx): reubicación %s sin resolución contra el símbolo `%s'"
+
+#: elf32-tic6x.c:1602
+msgid "warning: generating a shared library containing non-PIC code"
+msgstr "aviso: se genera una biblioteca compartida que contiene código que no esPIC"
+
+#: elf32-tic6x.c:1607
+msgid "warning: generating a shared library containing non-PID code"
+msgstr "aviso: se genera una biblioteca compartida que contiene código que no es PID"
+
+#: elf32-tic6x.c:2541
+msgid "%B: SB-relative relocation but __c6xabi_DSBT_BASE not defined"
+msgstr "%B: reubicación relativa a SB pero _c6xabi_DSBT_BASE no está definido"
+
+#: elf32-tic6x.c:2761
+msgid "dangerous relocation"
+msgstr "reubicación peligrosa"
+
+#: elf32-tic6x.c:3733
+msgid "%B: error: unknown mandatory EABI object attribute %d"
+msgstr "%B: error: atributo de objeto EABI obligatorio %d desconocido"
+
+#: elf32-tic6x.c:3741
+msgid "%B: warning: unknown EABI object attribute %d"
+msgstr "%B: aviso: atributo de objeto EABI %d desconocido"
+
+#: elf32-tic6x.c:3853 elf32-tic6x.c:3861
+msgid "error: %B requires more stack alignment than %B preserves"
+msgstr "error: %B requiere más alineación de pila que la que %B preserva"
+
+#: elf32-tic6x.c:3871 elf32-tic6x.c:3880
+msgid "error: unknown Tag_ABI_array_object_alignment value in %B"
+msgstr "error: valor de Tag_ABI_array_object_alignment desconocido en %B"
+
+#: elf32-tic6x.c:3889 elf32-tic6x.c:3898
+msgid "error: unknown Tag_ABI_array_object_align_expected value in %B"
+msgstr "error: valor de Tag_ABI_array_object_align_expected desconocido en %B"
+
+#: elf32-tic6x.c:3906 elf32-tic6x.c:3913
+msgid "error: %B requires more array alignment than %B preserves"
+msgstr "error: %B requiere más alineación de matriz que la que %B preserva"
+
+#: elf32-tic6x.c:3935
+msgid "warning: %B and %B differ in wchar_t size"
+msgstr "aviso: %B y %B difieren en tamaño wchar_t"
+
+#: elf32-tic6x.c:3953
+msgid "warning: %B and %B differ in whether code is compiled for DSBT"
+msgstr "aviso: %B y %B difieren en si el código está compilado para DSBT"
+
+#: elf32-v850.c:173
+#, c-format
+msgid "Variable `%s' cannot occupy in multiple small data regions"
+msgstr "La variable `%s' no puede ocupar múltiples regiones de datos small"
+
+#: elf32-v850.c:176
+#, c-format
+msgid "Variable `%s' can only be in one of the small, zero, and tiny data regions"
+msgstr "La variable `%s' solamente puede estar en una de las regiones de datos small, zero, y tiny"
+
+#: elf32-v850.c:179
+#, c-format
+msgid "Variable `%s' cannot be in both small and zero data regions simultaneously"
+msgstr "La variable `%s' no puede estar simultáneamente en las regiones de datos small y zero"
+
+#: elf32-v850.c:182
+#, c-format
+msgid "Variable `%s' cannot be in both small and tiny data regions simultaneously"
+msgstr "La variable `%s' no puede estar simultáneamente en las regiones de datos small y tiny"
+
+#: elf32-v850.c:185
+#, c-format
+msgid "Variable `%s' cannot be in both zero and tiny data regions simultaneously"
+msgstr "La variable `%s' no puede estar simultáneamente en las regiones de datos zero y tiny"
+
+#: elf32-v850.c:483
+msgid "FAILED to find previous HI16 reloc"
+msgstr "FALLO para encontrar la reubicación HI16 previa"
+
+#: elf32-v850.c:2155
+msgid "could not locate special linker symbol __gp"
+msgstr "no se puede localizar el símbolo especial del enlazador __gp"
+
+#: elf32-v850.c:2159
+msgid "could not locate special linker symbol __ep"
+msgstr "no se puede localizar el símbolo especial del enlazador __ep"
+
+#: elf32-v850.c:2163
+msgid "could not locate special linker symbol __ctbp"
+msgstr "no se puede localizar el símbolo especial del enlazador __ctbp"
+
+#: elf32-v850.c:2341
+msgid "%B: Architecture mismatch with previous modules"
+msgstr "%B: No coincide la arquitectura con los módulos previos"
+
+#. xgettext:c-format.
+#: elf32-v850.c:2360
+#, c-format
+msgid "private flags = %lx: "
+msgstr "opciones privadas = %lx: "
+
+#: elf32-v850.c:2365
+#, c-format
+msgid "v850 architecture"
+msgstr "arquitectura v850"
+
+#: elf32-v850.c:2366
+#, c-format
+msgid "v850e architecture"
+msgstr "arquitectura v850e"
+
+#: elf32-v850.c:2367
+#, c-format
+msgid "v850e1 architecture"
+msgstr "arquitectura v850e1"
+
+#: elf32-v850.c:2368
+#, c-format
+msgid "v850e2 architecture"
+msgstr "arquitectura v850e2"
+
+#: elf32-v850.c:2369
+#, c-format
+msgid "v850e2v3 architecture"
+msgstr "arquitectura v850e2v3"
+
+#: elf32-vax.c:532
+#, c-format
+msgid " [nonpic]"
+msgstr " [no pic]"
+
+#: elf32-vax.c:535
+#, c-format
+msgid " [d-float]"
+msgstr " [flotante-d]"
+
+#: elf32-vax.c:538
+#, c-format
+msgid " [g-float]"
+msgstr " [flotante-g]"
+
+#: elf32-vax.c:655
+#, c-format
+msgid "%s: warning: GOT addend of %ld to `%s' does not match previous GOT addend of %ld"
+msgstr "%s: aviso: la adición GOT de %ld a `%s' no coincide con la adición previa GOT de %ld"
+
+#: elf32-vax.c:1585
+#, c-format
+msgid "%s: warning: PLT addend of %d to `%s' from %s section ignored"
+msgstr "%s: aviso: se descarta la adición PLT de %d a `%s' de la sección %s"
+
+#: elf32-vax.c:1712
+#, c-format
+msgid "%s: warning: %s relocation against symbol `%s' from %s section"
+msgstr "%s: aviso: reubicación %s contra el símbolo `%s' de la sección %s"
+
+#: elf32-vax.c:1718
+#, c-format
+msgid "%s: warning: %s relocation to 0x%x from %s section"
+msgstr "%s: aviso: reubicación %s a 0x%x de la sección %s"
+
+#: elf32-xstormy16.c:451 elf32-ia64.c:2336 elf64-ia64.c:2336
+msgid "non-zero addend in @fptr reloc"
+msgstr "adición que no es cero en la reubicación @fptr"
+
+#: elf32-xtensa.c:918
+msgid "%B(%A): invalid property table"
+msgstr "%B(%A): tabla de propiedades inválida"
+
+#: elf32-xtensa.c:2777
+msgid "%B(%A+0x%lx): relocation offset out of range (size=0x%x)"
+msgstr "%B(%A+0x%lx): desplazamiento de reubicación fuera de rango (tamaño=0x%x)"
+
+#: elf32-xtensa.c:2856 elf32-xtensa.c:2977
+msgid "dynamic relocation in read-only section"
+msgstr "reubicación dinámica en la sección de sólo lectura"
+
+#: elf32-xtensa.c:2953
+msgid "TLS relocation invalid without dynamic sections"
+msgstr "reubicación TLS inválida sin secciones dinámicas"
+
+#: elf32-xtensa.c:3172
+msgid "internal inconsistency in size of .got.loc section"
+msgstr "inconsistencia interna en el tamaño de la sección .got.loc"
+
+#: elf32-xtensa.c:3485
+msgid "%B: incompatible machine type. Output is 0x%x. Input is 0x%x"
+msgstr "%B: tipo de máquina incompatible. La salida es 0x%x. La entrada es 0x%x"
+
+#: elf32-xtensa.c:4714 elf32-xtensa.c:4722
+msgid "Attempt to convert L32R/CALLX to CALL failed"
+msgstr "Falló el intento de convertir L32R/CALLX a CALL"
+
+#: elf32-xtensa.c:6332 elf32-xtensa.c:6408 elf32-xtensa.c:7524
+msgid "%B(%A+0x%lx): could not decode instruction; possible configuration mismatch"
+msgstr "%B(%A+0x%lx): no se puede decodificar la instrucción; posible falta de coincidencia de la configuración"
+
+#: elf32-xtensa.c:7264
+msgid "%B(%A+0x%lx): could not decode instruction for XTENSA_ASM_SIMPLIFY relocation; possible configuration mismatch"
+msgstr "%B(%A+0x%lx): no se puede decodificar la instrucción para la reubicación XTENSA_ASM_SIMPLIFY; posible falta de coincidencia de la configuración"
+
+#: elf32-xtensa.c:9023
+msgid "invalid relocation address"
+msgstr "dirección de reubicación inválida"
+
+#: elf32-xtensa.c:9072
+msgid "overflow after relaxation"
+msgstr "desbordamiento después de la relajación"
+
+#: elf32-xtensa.c:10204
+msgid "%B(%A+0x%lx): unexpected fix for %s relocation"
+msgstr "%B(%A+0x%lx): compostura inesperada para la reubicación %s"
+
+#: elf64-alpha.c:460
+msgid "GPDISP relocation did not find ldah and lda instructions"
+msgstr "la reubicación GPDISP no encontró las instrucciones ldah y lda"
+
+#: elf64-alpha.c:2497
+msgid "%B: .got subsegment exceeds 64K (size %d)"
+msgstr "%B: el subsegmento .got excede los 64K (tamaño %d)"
+
+#: elf64-alpha.c:4387 elf64-alpha.c:4399
+msgid "%B: gp-relative relocation against dynamic symbol %s"
+msgstr "%B: reubicación relativa a gp contra el símbolo dinámico %s"
+
+#: elf64-alpha.c:4425 elf64-alpha.c:4565
+msgid "%B: pc-relative relocation against dynamic symbol %s"
+msgstr "%B: reubicación relativa a pc contra el símbolo dinámico %s"
+
+#: elf64-alpha.c:4453
+msgid "%B: change in gp: BRSGP %s"
+msgstr "%B: cambio en gp: BRSGP %s"
+
+#: elf64-alpha.c:4478
+msgid "<unknown>"
+msgstr "<desconocido>"
+
+#: elf64-alpha.c:4483
+msgid "%B: !samegp reloc against symbol without .prologue: %s"
+msgstr "%B: reubicación !samegp contra un símbolo sin .prologue: %s"
+
+#: elf64-alpha.c:4540
+msgid "%B: unhandled dynamic relocation against %s"
+msgstr "%B: reubicación dinámica sin manejar contra %s"
+
+#: elf64-alpha.c:4572
+msgid "%B: pc-relative relocation against undefined weak symbol %s"
+msgstr "%B: reubicación relativa a pc contra el símbolo débil sin definir %s"
+
+#: elf64-alpha.c:4636
+msgid "%B: dtp-relative relocation against dynamic symbol %s"
+msgstr "%B: reubicación relativa a dtp contra el símbolo dinámico %s"
+
+#: elf64-alpha.c:4659
+msgid "%B: tp-relative relocation against dynamic symbol %s"
+msgstr "%B: reubicación relativa a tp contra el símbolo dinámico %s"
+
+#: elf64-hppa.c:2083
+#, c-format
+msgid "stub entry for %s cannot load .plt, dp offset = %ld"
+msgstr "la entrada de cabo para %s no puede cargar .plt, desplazamiento dp = %ld"
+
+#: elf64-hppa.c:3275
+msgid "%B(%A+0x"
+msgstr "%B(%A+0x"
+
+#: elf64-mmix.c:1034
+msgid ""
+"invalid input relocation when producing non-ELF, non-mmo format output.\n"
+" Please use the objcopy program to convert from ELF or mmo,\n"
+" or assemble using \"-no-expand\" (for gcc, \"-Wa,-no-expand\""
+msgstr ""
+"reubicación de entrada inválida al producir el formato de salida que no\n"
+" es mmo ni ELF. Por favor utilice el programa objcopy para convertir de\n"
+" ELF o mmo, o ensamble utilizando \"-no-expand\" (para gcc, \"-Wa, -no-expand\""
+
+#: elf64-mmix.c:1218
+msgid ""
+"invalid input relocation when producing non-ELF, non-mmo format output.\n"
+" Please use the objcopy program to convert from ELF or mmo,\n"
+" or compile using the gcc-option \"-mno-base-addresses\"."
+msgstr ""
+"reubicación de entrada inválida al producir el formato de salida que no\n"
+" es mmo ni ELF. Por favor utilice el programa objcopy para converitr de\n"
+" ELF o mmo, o compile utilizando la opción de gcc \"-mno-base-addresses\"."
+
+#: elf64-mmix.c:1244
+#, c-format
+msgid ""
+"%s: Internal inconsistency error for value for\n"
+" linker-allocated global register: linked: 0x%lx%08lx != relaxed: 0x%lx%08lx\n"
+msgstr ""
+"%s: Error de inconsistencia interna para el valor para\n"
+" un registro global colocado por el enlazador: enlazado: 0x%lx%08lx != relajado: 0x%lx%08lx\n"
+
+#: elf64-mmix.c:1670
+#, c-format
+msgid "%s: base-plus-offset relocation against register symbol: (unknown) in %s"
+msgstr "%s: reubicación base-más-desplazamiento contra un símbolo de registro: (desconocido) en %s"
+
+#: elf64-mmix.c:1675
+#, c-format
+msgid "%s: base-plus-offset relocation against register symbol: %s in %s"
+msgstr "%s: reubicación base-más-desplazamiento contra un símbolo de registro: %s en %s"
+
+#: elf64-mmix.c:1719
+#, c-format
+msgid "%s: register relocation against non-register symbol: (unknown) in %s"
+msgstr "%s: reubicación de registro contra un símbolo que no es registro: (desconocido) en %s"
+
+#: elf64-mmix.c:1724
+#, c-format
+msgid "%s: register relocation against non-register symbol: %s in %s"
+msgstr "%s: reubicación de registro contra un símbolo que no es registro: %s en %s"
+
+#: elf64-mmix.c:1761
+#, c-format
+msgid "%s: directive LOCAL valid only with a register or absolute value"
+msgstr "%s: la directiva LOCAL sólo es válida con un registro o un valor absoluto"
+
+#: elf64-mmix.c:1789
+#, c-format
+msgid "%s: LOCAL directive: Register $%ld is not a local register. First global register is $%ld."
+msgstr "%s: directiva LOCAL: El registro $%ld no es un registro local. El primer registro global es $%ld."
+
+#: elf64-mmix.c:2253
+#, c-format
+msgid "%s: Error: multiple definition of `%s'; start of %s is set in a earlier linked file\n"
+msgstr "%s: Error: definición múltiple de `%s'; el inicio de %s está definido en un fichero enlazado con anterioridad\n"
+
+#: elf64-mmix.c:2311
+msgid "Register section has contents\n"
+msgstr "La sección de registros no tiene contenido\n"
+
+#: elf64-mmix.c:2503
+#, c-format
+msgid ""
+"Internal inconsistency: remaining %u != max %u.\n"
+" Please report this bug."
+msgstr ""
+"Inconsistencia interna: %u restante != %u máximo.\n"
+" Por favor reporte este bicho."
+
+#: elf64-ppc.c:4185
+msgid "%P: %B: cannot create stub entry %s\n"
+msgstr "%P: %B: no se puede crear la entrada de cabo %s\n"
+
+#: elf64-ppc.c:6518
+msgid "%P: copy reloc against `%s' requires lazy plt linking; avoid setting LD_BIND_NOW=1 or upgrade gcc\n"
+msgstr "%P: la reubicación de copia contra `%s' requiere de enlazado plt flojo; evite establecer LD_BIND_NOW=1 o actualice gcc\n"
+
+#: elf64-ppc.c:6788
+msgid "%B: undefined symbol on R_PPC64_TOCSAVE relocation"
+msgstr "%B: símbolo sin definir en la reubicación R_PPC64_TOCSAVE"
+
+#: elf64-ppc.c:6992
+msgid "%P: dynreloc miscount for %B, section %A\n"
+msgstr "%P: cuenta errónea de la reubicación dinámica de %B, sección %A\n"
+
+#: elf64-ppc.c:7076
+msgid "%B: .opd is not a regular array of opd entries"
+msgstr "%B: .opd no es una matriz regular de entradas opd"
+
+#: elf64-ppc.c:7085
+msgid "%B: unexpected reloc type %u in .opd section"
+msgstr "%B: tipo de reubicación %u inesperado en la sección .opd"
+
+#: elf64-ppc.c:7106
+msgid "%B: undefined sym `%s' in .opd section"
+msgstr "%B: símbolo `%s' sin definir en la sección .opd"
+
+#: elf64-ppc.c:7664
+msgid "%H __tls_get_addr lost arg, TLS optimization disabled\n"
+msgstr "%H se perdió el argumento __tls_get_addr, se desactiva la optimización TLS\n"
+
+#: elf64-ppc.c:8003 elf64-ppc.c:8564
+#, c-format
+msgid "%s defined on removed toc entry"
+msgstr "se definió %s en la entrada toc eliminada"
+
+#: elf64-ppc.c:8521
+msgid "%P: %H: %s relocation references optimized away TOC entry\n"
+msgstr "%P: %H: la reubicación %s referencía una entrada TOC optimizada por fuera\n"
+
+#: elf64-ppc.c:9598
+msgid "%P: cannot find opd entry toc for %s\n"
+msgstr "%P: no se puede encontrar la tabla de contenidos de la entrada opd para %s\n"
+
+#: elf64-ppc.c:9680
+msgid "%P: long branch stub `%s' offset overflow\n"
+msgstr "%P: desbordamiento del desplazamiento de stub de ramificación long `%s'\n"
+
+#: elf64-ppc.c:9739
+msgid "%P: can't find branch stub `%s'\n"
+msgstr "%P: no se puede encontrar la ramificación de cabo `%s'\n"
+
+#: elf64-ppc.c:9801 elf64-ppc.c:9943
+msgid "%P: linkage table error against `%s'\n"
+msgstr "%P: error de la tabla de enlazado contra `%s'\n"
+
+#: elf64-ppc.c:10126
+msgid "%P: can't build branch stub `%s'\n"
+msgstr "%P: no se puede construir la ramificación de cabos `%s'\n"
+
+#: elf64-ppc.c:10941
+msgid "%B section %A exceeds stub group size"
+msgstr "%B sección %A excede el tamaño de grupo de cabos"
+
+#: elf64-ppc.c:11666 elf64-ppc.c:11699
+msgid "%P: %s offset too large for .eh_frame sdata4 encoding"
+msgstr "%P: el desplazamiento %s es demasiado grande para la codificación sdata4 .eh_frame"
+
+#: elf64-ppc.c:11744
+msgid "%P: stubs don't match calculated size\n"
+msgstr "%P: los cabos no coinciden con el tamaño calculado\n"
+
+#: elf64-ppc.c:11756
+#, c-format
+msgid ""
+"linker stubs in %u group%s\n"
+" branch %lu\n"
+" toc adjust %lu\n"
+" long branch %lu\n"
+" long toc adj %lu\n"
+" plt call %lu"
+msgstr ""
+"cabos de enlazador en %u grupo%s\n"
+" rama %lu\n"
+" ajuste toc %lu\n"
+" rama long %lu\n"
+" ajuste toc long %lu\n"
+" llamada plt %lu"
+
+#: elf64-ppc.c:12042
+msgid "%P: %H: %s used with TLS symbol %s\n"
+msgstr "%P: %H: se usó %s con el símbolo TLS %s\n"
+
+#: elf64-ppc.c:12043
+msgid "%P: %H: %s used with non-TLS symbol %s\n"
+msgstr "%P: %H: se usó %s con el símbolo %s que no es TLS\n"
+
+#: elf64-ppc.c:12556
+msgid "%P: %H: automatic multiple TOCs not supported using your crt files; recompile with -mminimal-toc or upgrade gcc\n"
+msgstr "%P: %H: no se admiten los TOCs múltiples automáticos, utilizando sus ficheros crt; recompile con -mminimal-toc o actualice gcc\n"
+
+#: elf64-ppc.c:12562
+msgid "%P: %H: sibling call optimization to `%s' does not allow automatic multiple TOCs; recompile with -mminimal-toc or -fno-optimize-sibling-calls, or make `%s' extern\n"
+msgstr "%P: %H: la optimización de llamada hermana a `%s' no permite TOCs múltiples automáticos; recompile con -mminimal-toc ó -fno-optimize-sibling-calls, o vuelva `%s' externa\n"
+
+#: elf64-ppc.c:13286
+msgid "%P: %B: relocation %s is not supported for symbol %s\n"
+msgstr "%P: %B: no se admite la reubicación %s para el símbolo %s\n"
+
+#: elf64-ppc.c:13446
+msgid "%P: %H: error: %s not a multiple of %u\n"
+msgstr "%P: %H: error: %s no es un múltiplo de %u\n"
+
+#: elf64-sh64.c:1686
+#, c-format
+msgid "%s: error: unaligned relocation type %d at %08x reloc %08x\n"
+msgstr "%s: error: tipo de reubicación %d sin alinear en %08x reubicación %08x\n"
+
+#: elf64-sparc.c:446
+msgid "%B: Only registers %%g[2367] can be declared using STT_REGISTER"
+msgstr "%B: Solamente los registros %%g[2367] se pueden declarar utilizando STT_REGISTER"
+
+#: elf64-sparc.c:466
+msgid "Register %%g%d used incompatibly: %s in %B, previously %s in %B"
+msgstr "El registro %%g%d se usó de forma incompatible: %s en %B, previamente %s en %B"
+
+#: elf64-sparc.c:489
+msgid "Symbol `%s' has differing types: REGISTER in %B, previously %s in %B"
+msgstr "El símbolo `%s' tiene tipos divergentes: REGISTER en %B, previamente %s en %B"
+
+#: elf64-sparc.c:534
+msgid "Symbol `%s' has differing types: %s in %B, previously REGISTER in %B"
+msgstr "El símbolo `%s' tiene tipos divergentes: %s en %B, previamente REGISTER en %B"
+
+#: elf64-sparc.c:687
+msgid "%B: linking UltraSPARC specific with HAL specific code"
+msgstr "%B: se enlaza código específico de UltraSPARC con código específico de HAL"
+
+#: elf64-x86-64.c:1427
+msgid "%B: relocation %s against symbol `%s' isn't supported in x32 mode"
+msgstr "%B: la reubicación %s contra el símbolo `%s' no se admite en modo x32"
+
+#: elf64-x86-64.c:1656
+msgid "%B: '%s' accessed both as normal and thread local symbol"
+msgstr "%B: se accedió a '%s' como un símbolo normal y como un símbolo local de hilo"
+
+#: elf64-x86-64.c:3150
+msgid "%B: relocation %s against STT_GNU_IFUNC symbol `%s' has non-zero addend: %d"
+msgstr "%B: la reubicación %s contra el símbolo STT_GNU_IFUNC `%s' con adición que no es cero: %d"
+
+#: elf64-x86-64.c:3411
+msgid "%B: relocation R_X86_64_GOTOFF64 against protected function `%s' can not be used when making a shared object"
+msgstr "%B: no se puede usar la reubicación R_X86_64_GOTOFF contra la función protegida `%s' cuando se hace un objeto compartido"
+
+#: elf64-x86-64.c:3523
+msgid "; recompile with -fPIC"
+msgstr "; recompile con -fPIC"
+
+#: elf64-x86-64.c:3528
+msgid "%B: relocation %s against %s `%s' can not be used when making a shared object%s"
+msgstr "%B: no se puede usar la reubicación %s contra %s `%s' cuando se hace un objeto compartido%s"
+
+#: elf64-x86-64.c:3530
+msgid "%B: relocation %s against undefined %s `%s' can not be used when making a shared object%s"
+msgstr "%B: no se puede usar la reubicación %s contra %s sin definir `%s' cuando se hace un objeto compartido%s"
+
+#: elfcode.h:767
+#, c-format
+msgid "warning: %s has a corrupt string table index - ignoring"
+msgstr "aviso: %s tiene un índice de tablas de cadenas corrupto - se descarta"
+
+#: elfcode.h:1177
+#, c-format
+msgid "%s: version count (%ld) does not match symbol count (%ld)"
+msgstr "%s: la cuenta de versión (%ld) no coincide con la cuenta de símbolos (%ld)"
+
+#: elfcode.h:1431
+#, c-format
+msgid "%s(%s): relocation %d has invalid symbol index %ld"
+msgstr "%s(%s): la reubicación %d tiene un índice de símbolo %ld inválido"
+
+#: elfcore.h:312
+msgid "Warning: %B is truncated: expected core file size >= %lu, found: %lu."
+msgstr "Aviso: se truncó %B: se esperaba el tamaño de fichero core >= %lu, se encontró: %lu."
+
+#: elflink.c:1117
+msgid "%s: TLS definition in %B section %A mismatches non-TLS definition in %B section %A"
+msgstr "%s: la definición TLS en %B sección %A no coincide con la definición que no es TLS en %B sección %A"
+
+#: elflink.c:1121
+msgid "%s: TLS reference in %B mismatches non-TLS reference in %B"
+msgstr "%s: la referencia TLS en %B no coincide con la referencia que no es TLS en %B"
+
+#: elflink.c:1125
+msgid "%s: TLS definition in %B section %A mismatches non-TLS reference in %B"
+msgstr "%s: la definición TLS en %B sección %A no coincide con la referencia que no es TLS en %B"
+
+#: elflink.c:1129
+msgid "%s: TLS reference in %B mismatches non-TLS definition in %B section %A"
+msgstr "%s: la referencia TLS en %B no coincide con la definición que no es TLS en %B sección %A"
+
+#: elflink.c:1762
+msgid "%B: unexpected redefinition of indirect versioned symbol `%s'"
+msgstr "%B: redefinición inesperada del símbolo con versión indirecta `%s'"
+
+#: elflink.c:2063
+msgid "%B: version node not found for symbol %s"
+msgstr "%B: no se encuentra la versión del nodo para el símbolo %s"
+
+#: elflink.c:2154
+msgid "%B: bad reloc symbol index (0x%lx >= 0x%lx) for offset 0x%lx in section `%A'"
+msgstr "%B: índice de símbolos de reubicación inválido (0x%lx >= 0x%lx) erróneo para el desplazamiento 0x%lx en la sección `%A'"
+
+#: elflink.c:2165
+msgid "%B: non-zero symbol index (0x%lx) for offset 0x%lx in section `%A' when the object file has no symbol table"
+msgstr "%B: índice de símbolos que no es cero (0x%lx) para el desplazamiento 0x%lx) en la sección `%A' cuando el fichero objeto no tiene tabla de símbolos"
+
+#: elflink.c:2355
+msgid "%B: relocation size mismatch in %B section %A"
+msgstr "%B: el tamaño de reubicación no coincide en %B sección %A"
+
+#: elflink.c:2639
+#, c-format
+msgid "warning: type and size of dynamic symbol `%s' are not defined"
+msgstr "aviso: el tipo y tamaño del símbolo dinámico `%s' no están definidos"
+
+#: elflink.c:3391
+msgid "%P: alternate ELF machine code found (%d) in %B, expecting %d\n"
+msgstr "%P: se encontró código máquina ELF alternativo (%d) en %B, se espera %d\n"
+
+#: elflink.c:4037
+msgid "%B: %s: invalid version %u (max %d)"
+msgstr "%B: %s: versión %u inválida (máximo %d)"
+
+#: elflink.c:4073
+msgid "%B: %s: invalid needed version %d"
+msgstr "%B: %s: versión requerida %d inválida"
+
+#: elflink.c:4269
+msgid "Warning: alignment %u of common symbol `%s' in %B is greater than the alignment (%u) of its section %A"
+msgstr "Aviso: la alineación %u del símbolo común `%s' en %B es más grande que la alineación (%u) de su sección %A"
+
+#: elflink.c:4275
+msgid "Warning: alignment %u of symbol `%s' in %B is smaller than %u in %B"
+msgstr "Aviso: la alineación %u del símbolo `%s' en %B es más pequeña que %u en %B"
+
+#: elflink.c:4290
+msgid "Warning: size of symbol `%s' changed from %lu in %B to %lu in %B"
+msgstr "Aviso: el tamaño del símbolo `%s' cambió de %lu en %B a %lu en %B"
+
+#: elflink.c:4463
+msgid "%B: undefined reference to symbol '%s'"
+msgstr "%B: referencia sin definir al símbolo '%s'"
+
+#: elflink.c:4466
+msgid "note: '%s' is defined in DSO %B so try adding it to the linker command line"
+msgstr "nota: se define '%s' en DSO %B así que se tratará de agregarlo a la línea de órdenes del enlazador"
+
+#: elflink.c:5781
+#, c-format
+msgid "%s: undefined version: %s"
+msgstr "%s: versión sin definir: %s"
+
+#: elflink.c:5849
+msgid "%B: .preinit_array section is not allowed in DSO"
+msgstr "%B: no se permite la sección .preinit_array en DSO"
+
+#: elflink.c:7604
+#, c-format
+msgid "undefined %s reference in complex symbol: %s"
+msgstr "referencia %s sin definir en el símbolo complejo: %s"
+
+#: elflink.c:7758
+#, c-format
+msgid "unknown operator '%c' in complex symbol"
+msgstr "operador desconocido '%c' en el símbolo complejo"
+
+#: elflink.c:8097 elflink.c:8114 elflink.c:8151 elflink.c:8168
+msgid "%B: Unable to sort relocs - they are in more than one size"
+msgstr "%B: No se pueden ordenar las reubicaciones - son de tamaños diferentes"
+
+#: elflink.c:8128 elflink.c:8182
+msgid "%B: Unable to sort relocs - they are of an unknown size"
+msgstr "%B: No se pueden ordenar las reubicaciones - son de tamaño desconocido"
+
+#: elflink.c:8233
+msgid "Not enough memory to sort relocations"
+msgstr "No hay suficiente memoria para ordenar las reubicaciones"
+
+#: elflink.c:8426
+msgid "%B: Too many sections: %d (>= %d)"
+msgstr "%B: Demasiadas secciones: %d (>= %d)"
+
+#: elflink.c:8675
+msgid "%B: internal symbol `%s' in %B is referenced by DSO"
+msgstr "%B: el símbolo interno `%s' en %B está referenciado por DSO"
+
+#: elflink.c:8677
+msgid "%B: hidden symbol `%s' in %B is referenced by DSO"
+msgstr "%B: el símbolo oculto `%s' en %B está referenciado por DSO"
+
+#: elflink.c:8679
+msgid "%B: local symbol `%s' in %B is referenced by DSO"
+msgstr "%B: el símbolo local `%s' en %B está referenciado por DSO"
+
+#: elflink.c:8776
+msgid "%B: could not find output section %A for input section %A"
+msgstr "%B: no se puede encontrar la sección de salida %A para la sección de entrada %A"
+
+#: elflink.c:8899
+msgid "%B: protected symbol `%s' isn't defined"
+msgstr "%B: el símbolo protegido `%s' no está definido"
+
+#: elflink.c:8901
+msgid "%B: internal symbol `%s' isn't defined"
+msgstr "%B: el símbolo interno `%s' no está definido"
+
+#: elflink.c:8903
+msgid "%B: hidden symbol `%s' isn't defined"
+msgstr "%B: el símbolo oculto `%s' no está definido"
+
+#: elflink.c:9432
+msgid "error: %B: size of section %A is not multiple of address size"
+msgstr "error: %B: el tamaño de la sección %A no es un múltiplo del tamaño de la dirección"
+
+#: elflink.c:9479
+msgid "error: %B contains a reloc (0x%s) for section %A that references a non-existent global symbol"
+msgstr "error: %B contiene una reubicación (0x%s) para la sección %A que refiere a un símbolo global que no existe"
+
+#: elflink.c:10214
+msgid "%A has both ordered [`%A' in %B] and unordered [`%A' in %B] sections"
+msgstr "%A tiene tanto secciones ordenadas [`%A' en %B] como desordenadas [`%A' en %B]"
+
+#: elflink.c:10219
+#, c-format
+msgid "%A has both ordered and unordered sections"
+msgstr "%A tiene secciones tanto ordenadas como desordenadas"
+
+#: elflink.c:10784
+msgid "%B: file class %s incompatible with %s"
+msgstr "%B: el fichero de clase %s es incompatible con %s"
+
+#: elflink.c:11093 elflink.c:11137
+msgid "%B: could not find output section %s"
+msgstr "%B: no se puede encontrar la sección de salida %s"
+
+#: elflink.c:11098
+#, c-format
+msgid "warning: %s section has zero size"
+msgstr "aviso: la sección %s es de tamaño cero"
+
+#: elflink.c:11143
+#, c-format
+msgid "warning: section '%s' is being made into a note"
+msgstr "aviso: la sección '%s' se está convirtiendo en una nota"
+
+#: elflink.c:11212
+msgid "%P%X: read-only segment has dynamic relocations.\n"
+msgstr "%P%X: un segmento de sólo lectura tiene reubicaciones dinámicas.\n"
+
+#: elflink.c:11215
+msgid "%P: warning: creating a DT_TEXTREL in a shared object.\n"
+msgstr "%P: aviso: se crea un DT_TEXTREL en un objeto compartido.\n"
+
+#: elflink.c:11402
+msgid "%P%X: can not read symbols: %E\n"
+msgstr "%P%X: no se pueden leer símbolos: %E\n"
+
+#: elflink.c:11792
+msgid "Removing unused section '%s' in file '%B'"
+msgstr "Se elimina la sección sin uso '%s' en el fichero '%B'"
+
+#: elflink.c:11998
+msgid "Warning: gc-sections option ignored"
+msgstr "Aviso: se descarta la opción gc-sections"
+
+#: elflink.c:12277
+#, c-format
+msgid "Unrecognized INPUT_SECTION_FLAG %s\n"
+msgstr "No se reconoce INPUT_SECTION_FLAG %s\n"
+
+#: elfxx-mips.c:1234
+msgid "static procedure (no name)"
+msgstr "procedimiento estático (sin nombre)"
+
+#: elfxx-mips.c:5259
+msgid "MIPS16 and microMIPS functions cannot call each other"
+msgstr "las funciones MIPS16 y microMIPS no se pueden llamar unas a otras"
+
+#: elfxx-mips.c:5856
+msgid "%B: %A+0x%lx: Direct jumps between ISA modes are not allowed; consider recompiling with interlinking enabled."
+msgstr "%B: %A+0x%lx: No se permiten los saltos directos entre modos ISA; considere recompilar con el entrelazado activado."
+
+#: elfxx-mips.c:6519 elfxx-mips.c:6742
+msgid "%B: Warning: bad `%s' option size %u smaller than its header"
+msgstr "%B: Aviso: el tamaño de opción `%s' %u erróneo es más pequeño que su encabezado"
+
+#: elfxx-mips.c:7495 elfxx-mips.c:7620
+msgid "%B: Warning: cannot determine the target function for stub section `%s'"
+msgstr "%B: Aviso: no se puede determinar la función objetivo para la sección de cabo `%s'"
+
+#: elfxx-mips.c:7749
+msgid "%B: Malformed reloc detected for section %s"
+msgstr "%B: Se detectó una reubicación malformada para la sección %s"
+
+#: elfxx-mips.c:7801
+msgid "%B: GOT reloc at 0x%lx not expected in executables"
+msgstr "%B: no se esperaba la reubicación GOT en 0x%lx en ejecutables"
+
+#: elfxx-mips.c:7930
+msgid "%B: CALL16 reloc at 0x%lx not against global symbol"
+msgstr "%B: la reubicación CALL16 en 0x%lx no es contra un símbolo global"
+
+#: elfxx-mips.c:8645
+#, c-format
+msgid "non-dynamic relocations refer to dynamic symbol %s"
+msgstr "reubicaciones que no son dinámicas se refieren al símbolo dinámico %s"
+
+#: elfxx-mips.c:9347
+msgid "%B: Can't find matching LO16 reloc against `%s' for %s at 0x%lx in section `%A'"
+msgstr "%B: No se puede encontrar una reubicación LO16 coincidente contra `%s' para %s en 0x%lx en la sección `%A'"
+
+#: elfxx-mips.c:9486
+msgid "small-data section exceeds 64KB; lower small-data size limit (see option -G)"
+msgstr "la sección small-data excede los 64KB; disminuya el límite de tamaño de small-data (vea la opción -G)"
+
+#: elfxx-mips.c:9505
+msgid "JALX to a non-word-aligned address"
+msgstr "JALX a una dirección que no está alineada con word"
+
+#: elfxx-mips.c:13266
+#, c-format
+msgid "%s: illegal section name `%s'"
+msgstr "%s: nombre de sección `%s' ilegal"
+
+#: elfxx-mips.c:13645 elfxx-mips.c:13671
+msgid "Warning: %B uses -msingle-float, %B uses -mdouble-float"
+msgstr "Aviso: %B usa -msingle-float, %B usa -mdouble-float"
+
+#: elfxx-mips.c:13657 elfxx-mips.c:13713
+msgid "Warning: %B uses -msingle-float, %B uses -mips32r2 -mfp64"
+msgstr "Aviso: %B usa -msingle-float, %B usa -mips32r2 -mfp64"
+
+#: elfxx-mips.c:13683 elfxx-mips.c:13719
+msgid "Warning: %B uses -mdouble-float, %B uses -mips32r2 -mfp64"
+msgstr "Aviso: %B usa -mdouble-float, %B usa -mips32r2 -mfp64"
+
+#: elfxx-mips.c:13761
+msgid "%B: endianness incompatible with that of the selected emulation"
+msgstr "%B: la endianez es incompatible con aquella de la emulación seleccionada"
+
+#: elfxx-mips.c:13772
+msgid "%B: ABI is incompatible with that of the selected emulation"
+msgstr "%B: la ABI es incompatible con aquella de la emulación seleccionada"
+
+#: elfxx-mips.c:13856
+msgid "%B: warning: linking abicalls files with non-abicalls files"
+msgstr "%B: aviso: se enlazan ficheros de llamadas abi con ficheros que no son de llamadas abi"
+
+#: elfxx-mips.c:13873
+msgid "%B: linking 32-bit code with 64-bit code"
+msgstr "%B: se enlaza código de 32-bit con código de 64-bit"
+
+#: elfxx-mips.c:13901
+msgid "%B: linking %s module with previous %s modules"
+msgstr "%B: se enlaza el módulo %s con módulos %s previos"
+
+#: elfxx-mips.c:13924
+msgid "%B: ABI mismatch: linking %s module with previous %s modules"
+msgstr "%B: no coincide ABI: se enlaza el módulo %s con módulos %s previos"
+
+#: elfxx-mips.c:13948
+msgid "%B: ASE mismatch: linking %s module with previous %s modules"
+msgstr "%B: no coincide ASE: se enlaza el módulo %s con módulos %s previos"
+
+#: elfxx-mips.c:14106
+#, c-format
+msgid " [abi=O32]"
+msgstr " [abi=O32]"
+
+#: elfxx-mips.c:14108
+#, c-format
+msgid " [abi=O64]"
+msgstr " [abi=O64]"
+
+#: elfxx-mips.c:14110
+#, c-format
+msgid " [abi=EABI32]"
+msgstr " [abi=EABI32]"
+
+#: elfxx-mips.c:14112
+#, c-format
+msgid " [abi=EABI64]"
+msgstr " [abi=EABI64]"
+
+#: elfxx-mips.c:14114
+#, c-format
+msgid " [abi unknown]"
+msgstr " [abi desconocido]"
+
+#: elfxx-mips.c:14116
+#, c-format
+msgid " [abi=N32]"
+msgstr " [abi=N32]"
+
+#: elfxx-mips.c:14118
+#, c-format
+msgid " [abi=64]"
+msgstr " [abi=64]"
+
+#: elfxx-mips.c:14120
+#, c-format
+msgid " [no abi set]"
+msgstr " [no hay conjunto abi]"
+
+#: elfxx-mips.c:14141
+#, c-format
+msgid " [unknown ISA]"
+msgstr " [ISA desconocido]"
+
+#: elfxx-mips.c:14155
+#, c-format
+msgid " [not 32bitmode]"
+msgstr " [no es modo 32bit]"
+
+#: elfxx-sparc.c:596
+#, c-format
+msgid "invalid relocation type %d"
+msgstr "tipo de reubicación %d inválido"
+
+#: elfxx-tilegx.c:3952
+msgid "%B: Cannot link together %s and %s objects."
+msgstr "%B: No se pueden enlazar juntos los objetos %s y %s."
+
+#: i386linux.c:451 m68klinux.c:456 sparclinux.c:450
+#, c-format
+msgid "Output file requires shared library `%s'\n"
+msgstr "El fichero de salida requiere la biblioteca compartida `%s'\n"
+
+#: i386linux.c:459 m68klinux.c:464 sparclinux.c:458
+#, c-format
+msgid "Output file requires shared library `%s.so.%s'\n"
+msgstr "El fichero de salida requiere la biblioteca compartida `%s.so.%s'\n"
+
+#: i386linux.c:648 i386linux.c:698 m68klinux.c:656 m68klinux.c:704
+#: sparclinux.c:648 sparclinux.c:698
+#, c-format
+msgid "Symbol %s not defined for fixups\n"
+msgstr "El símbolo %s no está definido para composturas\n"
+
+#: i386linux.c:722 m68klinux.c:728 sparclinux.c:722
+msgid "Warning: fixup count mismatch\n"
+msgstr "Aviso: no coincide la cuenta de composturas\n"
+
+#: ieee.c:159
+#, c-format
+msgid "%s: string too long (%d chars, max 65535)"
+msgstr "%s: la cadena es demasiado larga (%d caracteres, máximo 65535)"
+
+#: ieee.c:286
+#, c-format
+msgid "%s: unrecognized symbol `%s' flags 0x%x"
+msgstr "%s: no se reconoce el símbolo `%s' opciones 0x%x"
+
+#: ieee.c:792
+msgid "%B: unimplemented ATI record %u for symbol %u"
+msgstr "%B: grabación ATI %u sin implementar para el símbolo %u"
+
+#: ieee.c:816
+msgid "%B: unexpected ATN type %d in external part"
+msgstr "%B: tipo ATN %d inesperado en la parte externa"
+
+#: ieee.c:838
+msgid "%B: unexpected type after ATN"
+msgstr "%B: tipo inesperado después de ATN"
+
+#: ihex.c:230
+msgid "%B:%d: unexpected character `%s' in Intel Hex file"
+msgstr "%B:%d: carácter `%s' inesperado en el fichero Hexadecimal de Intel"
+
+#: ihex.c:337
+msgid "%B:%u: bad checksum in Intel Hex file (expected %u, found %u)"
+msgstr "%B:%u: suma de comprobación errónea en el fichero Hexadecimal de Intel (se esperaba %u, se obtuvo %u)"
+
+#: ihex.c:392
+msgid "%B:%u: bad extended address record length in Intel Hex file"
+msgstr "%B:%u: longitud de registro de dirección extendida errónea en el fichero Hexadecimal de Intel"
+
+#: ihex.c:409
+msgid "%B:%u: bad extended start address length in Intel Hex file"
+msgstr "%B:%u: longitud de dirección de inicio extendida errónea en el fichero Hexadecimal de Intel"
+
+#: ihex.c:426
+msgid "%B:%u: bad extended linear address record length in Intel Hex file"
+msgstr "%B:%u: longitud de registro de dirección lineal extendida errónea en el fichero Hexadecimal de Intel"
+
+#: ihex.c:443
+msgid "%B:%u: bad extended linear start address length in Intel Hex file"
+msgstr "%B:%u: longitud de dirección de inicio lineal extendida errónea en el fichero Hexadecimal de Intel"
+
+#: ihex.c:460
+msgid "%B:%u: unrecognized ihex type %u in Intel Hex file"
+msgstr "%B:%u: no se reconoce el tipo ihex %u en el fichero Hexadecimal de Intel"
+
+#: ihex.c:579
+msgid "%B: internal error in ihex_read_section"
+msgstr "%B: error interno en ihex_read_section"
+
+#: ihex.c:613
+msgid "%B: bad section length in ihex_read_section"
+msgstr "%B: longitud de sección errónea en ihex_read_section"
+
+#: ihex.c:826
+#, c-format
+msgid "%s: address 0x%s out of range for Intel Hex file"
+msgstr "%s: la dirección 0x%s está fuera de rango en el fichero Hexadecimal de Intel"
+
+#: libbfd.c:863
+msgid "%B: unable to get decompressed section %A"
+msgstr "%B: no se puede obtener la sección %A descomprimida"
+
+#: libbfd.c:1012
+msgid "%B: compiled for a big endian system and target is little endian"
+msgstr "%B: compilado para un sistema big endian y el objetivo es little endian"
+
+#: libbfd.c:1014
+msgid "%B: compiled for a little endian system and target is big endian"
+msgstr "%B: compilado para un sistema little endian y el objetivo es big endian"
+
+#: libbfd.c:1043
+#, c-format
+msgid "Deprecated %s called at %s line %d in %s\n"
+msgstr "Se llamó a %s que es obsoleto en %s línea %d en %s\n"
+
+#: libbfd.c:1046
+#, c-format
+msgid "Deprecated %s called\n"
+msgstr "Se llamó a %s que es obsoleto\n"
+
+#: linker.c:1872
+msgid "%B: indirect symbol `%s' to `%s' is a loop"
+msgstr "%B: el símbolo indirecto `%s' para `%s' es un ciclo"
+
+#: linker.c:2736
+#, c-format
+msgid "Attempt to do relocatable link with %s input and %s output"
+msgstr "Se intentó hacer un enlace reubicable con entrada %s y salida %s"
+
+#: linker.c:3021
+msgid "%B: ignoring duplicate section `%A'\n"
+msgstr "%B: se descarta la sección duplicada `%A'\n"
+
+#: linker.c:3030 linker.c:3039
+msgid "%B: duplicate section `%A' has different size\n"
+msgstr "%B: la sección duplicada `%A' tiene tamaño diferente\n"
+
+#: linker.c:3047 linker.c:3052
+msgid "%B: could not read contents of section `%A'\n"
+msgstr "%B: no se puede leer el contenido de la sección `%A'\n"
+
+#: linker.c:3056
+msgid "%B: duplicate section `%A' has different contents\n"
+msgstr "%B: la sección duplicada `%A' tiene contenido diferente\n"
+
+#: mach-o.c:407
+msgid "bfd_mach_o_canonicalize_symtab: unable to load symbols"
+msgstr "bfd_mach_o_canonicalize_symtab: no se pueden cargar símbolos"
+
+#: mach-o.c:1301
+#, c-format
+msgid "unable to write unknown load command 0x%lx"
+msgstr "no se puede escribir la orden load 0x%lx desconocida"
+
+#: mach-o.c:1789
+#, c-format
+msgid "bfd_mach_o_read_symtab_symbol: unable to read %d bytes at %lu"
+msgstr "bfd_mach_o_read_symtab_symbol: no se pueden leer %d bytes en %lu"
+
+#: mach-o.c:1807
+#, c-format
+msgid "bfd_mach_o_read_symtab_symbol: name out of range (%lu >= %lu)"
+msgstr "bfd_mach_o_read_symtab_symbol: nombre fuera de rango (%lu >= %lu)"
+
+#: mach-o.c:1892
+#, c-format
+msgid "bfd_mach_o_read_symtab_symbol: symbol \"%s\" specified invalid section %d (max %lu): setting to undefined"
+msgstr "bfd_mach_o_read_symtab_symbol: el símbolo \"%s\" especificó la sección inválida %d (máximo %lu): se cambia a indefinido"
+
+#: mach-o.c:1900
+#, c-format
+msgid "bfd_mach_o_read_symtab_symbol: symbol \"%s\" is unsupported 'indirect' reference: setting to undefined"
+msgstr "bfd_mach_o_read_symtab_symbol: el símbolo \"%s\" no admite la referencia 'indirect': se cambia a indefinido"
+
+#: mach-o.c:1906
+#, c-format
+msgid "bfd_mach_o_read_symtab_symbol: symbol \"%s\" specified invalid type field 0x%x: setting to undefined"
+msgstr "bfd_mach_o_read_symtab_symbol: el símbolo \"%s\" especificó el campo de tipo 0x%x inválido: se cambia a indefinido"
+
+#: mach-o.c:1979
+msgid "bfd_mach_o_read_symtab_symbols: unable to allocate memory for symbols"
+msgstr "bfd_mach_o_read_symtab_symbols: no se puede reservar memoria para símbolos"
+
+#: mach-o.c:2014
+#, c-format
+msgid "bfd_mach_o_read_dysymtab_symbol: unable to read %lu bytes at %lu"
+msgstr "bfd_mach_o_read_dysymtab_symbol: no se pueden leer %lu bytes en %lu"
+
+#: mach-o.c:2734
+#, c-format
+msgid "unable to read unknown load command 0x%lx"
+msgstr "no se puede leer la orden load 0x%lx desconocida"
+
+#: mach-o.c:2915
+#, c-format
+msgid "bfd_mach_o_scan: unknown architecture 0x%lx/0x%lx"
+msgstr "bfd_mach_o_scan: arquitectura 0x%lx/0x%lx desconocida"
+
+#: mach-o.c:3011
+#, c-format
+msgid "unknown header byte-order value 0x%lx"
+msgstr "valor de encabezado de orden de byte 0x%lx desconocido"
+
+#: mach-o.c:3577
+msgid "Mach-O header:\n"
+msgstr "encabezado de Mach-O:\n"
+
+#: mach-o.c:3578
+#, c-format
+msgid " magic : %08lx\n"
+msgstr " magic : %08lx\n"
+
+#: mach-o.c:3579
+#, c-format
+msgid " cputype : %08lx (%s)\n"
+msgstr " tipocpu : %08lx (%s)\n"
+
+#: mach-o.c:3581
+#, c-format
+msgid " cpusubtype: %08lx\n"
+msgstr " subtipocpu: %08lx\n"
+
+#: mach-o.c:3582
+#, c-format
+msgid " filetype : %08lx (%s)\n"
+msgstr " tipofich : %08lx (%s)\n"
+
+#: mach-o.c:3585
+#, c-format
+msgid " ncmds : %08lx (%lu)\n"
+msgstr " nordenes : %08lx (%lu)\n"
+
+#: mach-o.c:3586
+#, c-format
+msgid " sizeofcmds: %08lx\n"
+msgstr " tamordenes: %08lx\n"
+
+#: mach-o.c:3587
+#, c-format
+msgid " flags : %08lx ("
+msgstr " opciones : %08lx ("
+
+#: mach-o.c:3589 vms-alpha.c:7674
+msgid ")\n"
+msgstr ")\n"
+
+#: mach-o.c:3590
+#, c-format
+msgid " reserved : %08x\n"
+msgstr " reservado : %08x\n"
+
+#: mach-o.c:3600
+msgid "Segments and Sections:\n"
+msgstr "Segmentos y Secciones:\n"
+
+#: mach-o.c:3601
+msgid " #: Segment name Section name Address\n"
+msgstr " #: Nombre segmento Nombre sección Dirección\n"
+
+#: merge.c:832
+#, c-format
+msgid "%s: access beyond end of merged section (%ld)"
+msgstr "%s: acceso más allá del final de la sección mezclada (%ld)"
+
+#: mmo.c:456
+#, c-format
+msgid "%s: No core to allocate section name %s\n"
+msgstr "%s: No hay core para asignar el nombre de sección %s\n"
+
+#: mmo.c:531
+#, c-format
+msgid "%s: No core to allocate a symbol %d bytes long\n"
+msgstr "%s: No hay core para asignar un símbolo de %d bytes de longitud\n"
+
+#: mmo.c:1187
+#, c-format
+msgid "%s: invalid mmo file: initialization value for $255 is not `Main'\n"
+msgstr "%s: fichero mmo inválido: el valor de iniciación para $255 no es `Main'\n"
+
+#: mmo.c:1332
+#, c-format
+msgid "%s: unsupported wide character sequence 0x%02X 0x%02X after symbol name starting with `%s'\n"
+msgstr "%s: no se admite la secuencia de caracteres anchos 0x%02X 0x%02X después del nombre de símbolo que inicia con `%s'\n"
+
+#: mmo.c:1565
+#, c-format
+msgid "%s: invalid mmo file: unsupported lopcode `%d'\n"
+msgstr "%s: fichero mmo inválido: no se admite el código de operación-l `%d'\n"
+
+#: mmo.c:1575
+#, c-format
+msgid "%s: invalid mmo file: expected YZ = 1 got YZ = %d for lop_quote\n"
+msgstr "%s: fichero mmo inválido: se esperaba YZ = 1 se obtuvo YZ = %d para lop_quote\n"
+
+#: mmo.c:1611
+#, c-format
+msgid "%s: invalid mmo file: expected z = 1 or z = 2, got z = %d for lop_loc\n"
+msgstr "%s: fichero mmo inválido: se esperaba z = 1 ó z = 2, se obtuvo z = %d para lop_loc\n"
+
+#: mmo.c:1657
+#, c-format
+msgid "%s: invalid mmo file: expected z = 1 or z = 2, got z = %d for lop_fixo\n"
+msgstr "%s: fichero mmo inválido: se esperaba z = 1 ó z = 2, se obtuvo z = %d para lop_fixo\n"
+
+#: mmo.c:1696
+#, c-format
+msgid "%s: invalid mmo file: expected y = 0, got y = %d for lop_fixrx\n"
+msgstr "%s: fichero mmo inválido: se esperaba y = 0, se obtuvo y = %d para lop_fixrx\n"
+
+#: mmo.c:1705
+#, c-format
+msgid "%s: invalid mmo file: expected z = 16 or z = 24, got z = %d for lop_fixrx\n"
+msgstr "%s: fichero mmo inválido: se esperaba z = 16 ó z = 24, se obtuvo z = %d para lop_fixrx\n"
+
+#: mmo.c:1728
+#, c-format
+msgid "%s: invalid mmo file: leading byte of operand word must be 0 or 1, got %d for lop_fixrx\n"
+msgstr "%s: fichero mmo inválido: el byte inicial del operando word debe ser 0 ó 1, se obtuvo %d para lop_fixrx\n"
+
+#: mmo.c:1751
+#, c-format
+msgid "%s: cannot allocate file name for file number %d, %d bytes\n"
+msgstr "%s: no se puede asignar el nombre de fichero para el número de fichero %d, %d bytes\n"
+
+#: mmo.c:1771
+#, c-format
+msgid "%s: invalid mmo file: file number %d `%s', was already entered as `%s'\n"
+msgstr "%s: fichero mmo inválido: el número de fichero %d `%s' ya se había introducido como `%s'\n"
+
+#: mmo.c:1784
+#, c-format
+msgid "%s: invalid mmo file: file name for number %d was not specified before use\n"
+msgstr "%s: fichero mmo inválido: no se especificó un nombre de fichero para el número %d antes de utilizarse\n"
+
+#: mmo.c:1890
+#, c-format
+msgid "%s: invalid mmo file: fields y and z of lop_stab non-zero, y: %d, z: %d\n"
+msgstr "%s: fichero mmo inválido: los campos y y z de lop_stab no son cero, y: %d, z: %d\n"
+
+#: mmo.c:1926
+#, c-format
+msgid "%s: invalid mmo file: lop_end not last item in file\n"
+msgstr "%s: fichero mmo inválido: lop_end no es el último elemento en el fichero\n"
+
+#: mmo.c:1939
+#, c-format
+msgid "%s: invalid mmo file: YZ of lop_end (%ld) not equal to the number of tetras to the preceding lop_stab (%ld)\n"
+msgstr "%s: fichero mmo inválido: YZ de lop_end (%ld) no es igual al número de tetras del lop_stab precedente (%ld)\n"
+
+#: mmo.c:2649
+#, c-format
+msgid "%s: invalid symbol table: duplicate symbol `%s'\n"
+msgstr "%s: tabla de símbolos inválida: símbolo `%s' duplicado\n"
+
+#: mmo.c:2889
+#, c-format
+msgid "%s: Bad symbol definition: `Main' set to %s rather than the start address %s\n"
+msgstr "%s: Definición de símbolo errónea: `Main' se estableció como %s en lugar de la dirección de inicio %s\n"
+
+#: mmo.c:2981
+#, c-format
+msgid "%s: warning: symbol table too large for mmo, larger than 65535 32-bit words: %d. Only `Main' will be emitted.\n"
+msgstr "%s: aviso: la tabla de símbolos es demasiado grande para mmo, es más grande que 65535 words de 32-bit: %d. Sólo se emitirá `Main'.\n"
+
+#: mmo.c:3026
+#, c-format
+msgid "%s: internal error, symbol table changed size from %d to %d words\n"
+msgstr "%s: error interno, la tabla de símbolos cambió de tamaño de %d a %d words\n"
+
+#: mmo.c:3078
+#, c-format
+msgid "%s: internal error, internal register section %s had contents\n"
+msgstr "%s: error interno, la sección interna de registros %s tiene contenido\n"
+
+#: mmo.c:3129
+#, c-format
+msgid "%s: no initialized registers; section length 0\n"
+msgstr "%s: no hay registros iniciados; longitud de sección 0\n"
+
+#: mmo.c:3135
+#, c-format
+msgid "%s: too many initialized registers; section length %ld\n"
+msgstr "%s: demasiados registros iniciados: longitud de sección %ld\n"
+
+#: mmo.c:3140
+#, c-format
+msgid "%s: invalid start address for initialized registers of length %ld: 0x%lx%08lx\n"
+msgstr "%s: dirección de inicio inválida para los registros inicializados de longitud %ld: 0x%lx%08lx\n"
+
+#: oasys.c:882
+#, c-format
+msgid "%s: can not represent section `%s' in oasys"
+msgstr "%s: no se puede representar la sección `%s' en oasys"
+
+#: osf-core.c:140
+#, c-format
+msgid "Unhandled OSF/1 core file section type %d\n"
+msgstr "Tipo de sección de fichero núcleo OSF/1 %d sin manejar\n"
+
+#: pe-mips.c:607
+msgid "%B: `ld -r' not supported with PE MIPS objects\n"
+msgstr "%B: `ld -r' no se admite con objetos PE MIPS\n"
+
+#. OK, at this point the following variables are set up:
+#. src = VMA of the memory we're fixing up
+#. mem = pointer to memory we're fixing up
+#. val = VMA of what we need to refer to.
+#: pe-mips.c:719
+msgid "%B: unimplemented %s\n"
+msgstr "%B: %s sin implementar\n"
+
+#: pe-mips.c:745
+msgid "%B: jump too far away\n"
+msgstr "%B: salto demasiado lejos\n"
+
+#: pe-mips.c:771
+msgid "%B: bad pair/reflo after refhi\n"
+msgstr "%B: pair/reflo erróneo después de refhi\n"
+
+#: pef.c:520
+#, c-format
+msgid "bfd_pef_scan: unknown architecture 0x%lx"
+msgstr "bfd_pef_scan: arquitectura 0x%lx desconocida"
+
+#: pei-x86_64.c:444
+#, c-format
+msgid "warning: .pdata section size (%ld) is not a multiple of %d\n"
+msgstr "aviso: el tamaño de la sección .pdata (%ld) no es un múltiplo de %d\n"
+
+#: pei-x86_64.c:448 peigen.c:1618 peigen.c:1801 pepigen.c:1618 pepigen.c:1801
+#: pex64igen.c:1618 pex64igen.c:1801
+#, c-format
+msgid ""
+"\n"
+"The Function Table (interpreted .pdata section contents)\n"
+msgstr ""
+"\n"
+"La Tabla de Funciones (se interpretaron los contenidos de la sección .pdata)\n"
+
+#: pei-x86_64.c:450
+#, c-format
+msgid "vma:\t\t\tBeginAddress\t EndAddress\t UnwindData\n"
+msgstr "vma:\t\t\tDireccInicio\t DireccFin \t InformaciónDesenvuelta\n"
+
+#. XXX code yet to be written.
+#: peicode.h:751
+msgid "%B: Unhandled import type; %x"
+msgstr "%B: Tipo de importación sin manejar; %x"
+
+#: peicode.h:756
+msgid "%B: Unrecognised import type; %x"
+msgstr "%B: No se reconocer el tipo de importación; %x"
+
+#: peicode.h:770
+msgid "%B: Unrecognised import name type; %x"
+msgstr "%B: No se reconoce el tipo de nombre de importación; %x"
+
+#: peicode.h:1166
+msgid "%B: Unrecognised machine type (0x%x) in Import Library Format archive"
+msgstr "%B: No se reconoce el tipo de máquina (0x%x) en el archivo de Formato de Importación de Bibliotecas"
+
+#: peicode.h:1178
+msgid "%B: Recognised but unhandled machine type (0x%x) in Import Library Format archive"
+msgstr "%B: Se reconoce el tipo de máquina (0x%x) pero no se maneja en el archivo de Formato de Importación de Bibliotecas"
+
+#: peicode.h:1196
+msgid "%B: size field is zero in Import Library Format header"
+msgstr "%B: el tamaño del campo es cero en el encabezado del Formato de Importación de Bibliotecas"
+
+#: peicode.h:1227
+msgid "%B: string not null terminated in ILF object file."
+msgstr "%B: cadena que no termina en null en el fichero objeto ILF."
+
+#: ppcboot.c:414
+#, c-format
+msgid ""
+"\n"
+"ppcboot header:\n"
+msgstr ""
+"\n"
+"encabezado de ppcboot:\n"
+
+#: ppcboot.c:415
+#, c-format
+msgid "Entry offset = 0x%.8lx (%ld)\n"
+msgstr "Desplazamiento de entrada = 0x%.8lx (%ld)\n"
+
+#: ppcboot.c:417
+#, c-format
+msgid "Length = 0x%.8lx (%ld)\n"
+msgstr "Longitud = 0x%.8lx (%ld)\n"
+
+#: ppcboot.c:421
+#, c-format
+msgid "Flag field = 0x%.2x\n"
+msgstr "Campo de opciones = 0x%.2x\n"
+
+#: ppcboot.c:427
+#, c-format
+msgid "Partition name = \"%s\"\n"
+msgstr "Nombre de la partición = \"%s\"\n"
+
+#: ppcboot.c:446
+#, c-format
+msgid ""
+"\n"
+"Partition[%d] start = { 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x }\n"
+msgstr ""
+"\n"
+"Partición[%d] inicio = { 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x }\n"
+
+#: ppcboot.c:452
+#, c-format
+msgid "Partition[%d] end = { 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x }\n"
+msgstr "Partición[%d] fin = { 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x }\n"
+
+#: ppcboot.c:458
+#, c-format
+msgid "Partition[%d] sector = 0x%.8lx (%ld)\n"
+msgstr "Partición[%d] sector = 0x%.8lx (%ld)\n"
+
+#: ppcboot.c:460
+#, c-format
+msgid "Partition[%d] length = 0x%.8lx (%ld)\n"
+msgstr "Partición[%d] longitud = 0x%.8lx (%ld)\n"
+
+#: reloc.c:6160
+msgid "INPUT_SECTION_FLAGS are not supported.\n"
+msgstr "No se admite INPUT_SECTION_FLAGS.\n"
+
+#: rs6000-core.c:448
+#, c-format
+msgid "%s: warning core file truncated"
+msgstr "%s: aviso de fichero core trunco"
+
+#: som.c:5471
+#, c-format
+msgid ""
+"\n"
+"Exec Auxiliary Header\n"
+msgstr ""
+"\n"
+"Encabezado Auxiliar de Ejecución\n"
+
+#: som.c:5776
+msgid "som_sizeof_headers unimplemented"
+msgstr "som_sizeof_headers sin implementar"
+
+#: srec.c:261
+msgid "%B:%d: Unexpected character `%s' in S-record file\n"
+msgstr "%B:%d: Carácter `%s' inesperado en el fichero S-record\n"
+
+#: srec.c:567 srec.c:600
+msgid "%B:%d: Bad checksum in S-record file\n"
+msgstr "%B:%d: Suma de comprobación errónea en el fichero S-record\n"
+
+#: stabs.c:279
+msgid "%B(%A+0x%lx): Stabs entry has invalid string index."
+msgstr "%B(%A+0x%lx): La entrada de cabos tiene una cadena índice inválida."
+
+#: syms.c:1079
+msgid "Unsupported .stab relocation"
+msgstr "No se admite la reubicación .stab"
+
+#: vms-alpha.c:1299
+#, c-format
+msgid "Unknown EGSD subtype %d"
+msgstr "Subtipo de EGSD %d desconocido"
+
+#: vms-alpha.c:1330
+#, c-format
+msgid "Stack overflow (%d) in _bfd_vms_push"
+msgstr "Desbordamiento de la pila (%d) en _bfd_vms_push"
+
+#: vms-alpha.c:1343
+msgid "Stack underflow in _bfd_vms_pop"
+msgstr "Desbordamiento por debajo de la pila en _bfd_vms_pop"
+
+#. These names have not yet been added to this switch statement.
+#: vms-alpha.c:1580
+#, c-format
+msgid "unknown ETIR command %d"
+msgstr "orden ETIR %d desconocida"
+
+#: vms-alpha.c:1767
+#, c-format
+msgid "bad section index in %s"
+msgstr "índice de sección erróneo en %s"
+
+#: vms-alpha.c:1780
+#, c-format
+msgid "unsupported STA cmd %s"
+msgstr "no se admite la orden STA %s"
+
+#. Insert field.
+#. Unsigned shift.
+#. Rotate.
+#. Redefine symbol to current location.
+#. Define a literal.
+#: vms-alpha.c:1956 vms-alpha.c:1987 vms-alpha.c:2234
+#, c-format
+msgid "%s: not supported"
+msgstr "%s: no se admite"
+
+#: vms-alpha.c:1962
+#, c-format
+msgid "%s: not implemented"
+msgstr "%s: sin implementar"
+
+#: vms-alpha.c:2218
+#, c-format
+msgid "invalid use of %s with contexts"
+msgstr "uso inválido de %s en contextos"
+
+#: vms-alpha.c:2252
+#, c-format
+msgid "reserved cmd %d"
+msgstr "orden %d reservada"
+
+#: vms-alpha.c:2337
+msgid "Object module NOT error-free !\n"
+msgstr "¡ El módulo objeto NO está libre de errores !\n"
+
+#: vms-alpha.c:2766
+#, c-format
+msgid "Symbol %s replaced by %s\n"
+msgstr "Se reemplazó el símbolo %s por %s\n"
+
+#: vms-alpha.c:3769
+#, c-format
+msgid "SEC_RELOC with no relocs in section %s"
+msgstr "SEC_RELOC sin reubicaciones en la sección %s"
+
+#: vms-alpha.c:3822 vms-alpha.c:4049
+#, c-format
+msgid "Size error in section %s"
+msgstr "Error de tamaño en la sección %s"
+
+#: vms-alpha.c:3991
+msgid "Spurious ALPHA_R_BSR reloc"
+msgstr "Reubicación ALPHA_R_BSR espuria"
+
+#: vms-alpha.c:4036
+#, c-format
+msgid "Unhandled relocation %s"
+msgstr "Reubicación %s sin manejar"
+
+#: vms-alpha.c:4326
+#, c-format
+msgid "unknown source command %d"
+msgstr "orden fuente %d desconocida"
+
+#: vms-alpha.c:4387
+msgid "DST__K_SET_LINUM_INCR not implemented"
+msgstr "DST__K_SET_LINUM_INCR sin implementar"
+
+#: vms-alpha.c:4393
+msgid "DST__K_SET_LINUM_INCR_W not implemented"
+msgstr "DST__K_SET_LINUM_INCR_W sin implementar"
+
+#: vms-alpha.c:4399
+msgid "DST__K_RESET_LINUM_INCR not implemented"
+msgstr "DST__K_RESET_LINUM_INCR sin implementar"
+
+#: vms-alpha.c:4405
+msgid "DST__K_BEG_STMT_MODE not implemented"
+msgstr "DST__K_BEG_STMT_MODE sin implementar"
+
+#: vms-alpha.c:4411
+msgid "DST__K_END_STMT_MODE not implemented"
+msgstr "DST__K_END_STMT_MODE sin implementar"
+
+#: vms-alpha.c:4438
+msgid "DST__K_SET_PC not implemented"
+msgstr "DST__K_SET_PC sin implementar"
+
+#: vms-alpha.c:4444
+msgid "DST__K_SET_PC_W not implemented"
+msgstr "DST__K_SET_PC_W sin implementar"
+
+#: vms-alpha.c:4450
+msgid "DST__K_SET_PC_L not implemented"
+msgstr "DST__K_SET_PC_L sin implementar"
+
+#: vms-alpha.c:4456
+msgid "DST__K_SET_STMTNUM not implemented"
+msgstr "DST__K_SET_STMTNUM sin implementar"
+
+#: vms-alpha.c:4499
+#, c-format
+msgid "unknown line command %d"
+msgstr "orden de línea %d desconocida"
+
+#: vms-alpha.c:4953 vms-alpha.c:4970 vms-alpha.c:4984 vms-alpha.c:4999
+#: vms-alpha.c:5011 vms-alpha.c:5022 vms-alpha.c:5034
+#, c-format
+msgid "Unknown reloc %s + %s"
+msgstr "Reubicación %s + %s desconocida"
+
+#: vms-alpha.c:5089
+#, c-format
+msgid "Unknown reloc %s"
+msgstr "Reubicación %s desconocida"
+
+#: vms-alpha.c:5102
+msgid "Invalid section index in ETIR"
+msgstr "Ãndice de sección inválido en ETIR"
+
+#: vms-alpha.c:5109
+msgid "Relocation for non-REL psect"
+msgstr "Reubicación para psect que no es REL"
+
+#: vms-alpha.c:5156
+#, c-format
+msgid "Unknown symbol in command %s"
+msgstr "Símbolo desconocido en la orden %s"
+
+#: vms-alpha.c:5671
+#, c-format
+msgid " EMH %u (len=%u): "
+msgstr " EMH %u (lon=%u): "
+
+#: vms-alpha.c:5680
+#, c-format
+msgid "Module header\n"
+msgstr "Encabezado de módulo\n"
+
+#: vms-alpha.c:5681
+#, c-format
+msgid " structure level: %u\n"
+msgstr " nivel estruct : %u\n"
+
+#: vms-alpha.c:5682
+#, c-format
+msgid " max record size: %u\n"
+msgstr " tam reg máximo : %u\n"
+
+#: vms-alpha.c:5685
+#, c-format
+msgid " module name : %.*s\n"
+msgstr " nombre módulo : %.*s\n"
+
+#: vms-alpha.c:5687
+#, c-format
+msgid " module version : %.*s\n"
+msgstr " versión módulo : %.*s\n"
+
+#: vms-alpha.c:5689
+#, c-format
+msgid " compile date : %.17s\n"
+msgstr " fecha compil : %.17s\n"
+
+#: vms-alpha.c:5694
+#, c-format
+msgid "Language Processor Name\n"
+msgstr "Nombre de Procesador de Lenguaje\n"
+
+#: vms-alpha.c:5695
+#, c-format
+msgid " language name: %.*s\n"
+msgstr " nombre lenguaje: %.*s\n"
+
+#: vms-alpha.c:5702
+#, c-format
+msgid "Source Files Header\n"
+msgstr "Encabezado de Ficheros Fuente\n"
+
+#: vms-alpha.c:5703
+#, c-format
+msgid " file: %.*s\n"
+msgstr " fichero: %.*s\n"
+
+#: vms-alpha.c:5710
+#, c-format
+msgid "Title Text Header\n"
+msgstr "Encabezado de Texto de Título\n"
+
+#: vms-alpha.c:5711
+#, c-format
+msgid " title: %.*s\n"
+msgstr " título: %.*s\n"
+
+#: vms-alpha.c:5718
+#, c-format
+msgid "Copyright Header\n"
+msgstr "Encabezado de Copyright\n"
+
+#: vms-alpha.c:5719
+#, c-format
+msgid " copyright: %.*s\n"
+msgstr " copyright: %.*s\n"
+
+#: vms-alpha.c:5725
+#, c-format
+msgid "unhandled emh subtype %u\n"
+msgstr "subtipo emh %u sin manejar\n"
+
+#: vms-alpha.c:5735
+#, c-format
+msgid " EEOM (len=%u):\n"
+msgstr " EEOM (lon=%u):\n"
+
+#: vms-alpha.c:5736
+#, c-format
+msgid " number of cond linkage pairs: %u\n"
+msgstr " número de pares de enlace cond: %u\n"
+
+#: vms-alpha.c:5738
+#, c-format
+msgid " completion code: %u\n"
+msgstr " código de completado: %u\n"
+
+#: vms-alpha.c:5742
+#, c-format
+msgid " transfer addr flags: 0x%02x\n"
+msgstr " ops dirección transf: 0x%02x\n"
+
+#: vms-alpha.c:5743
+#, c-format
+msgid " transfer addr psect: %u\n"
+msgstr " psect dirección transf: %u\n"
+
+#: vms-alpha.c:5745
+#, c-format
+msgid " transfer address : 0x%08x\n"
+msgstr " dirección transf : 0x%08x\n"
+
+#: vms-alpha.c:5754
+msgid " WEAK"
+msgstr " WEAK"
+
+#: vms-alpha.c:5756
+msgid " DEF"
+msgstr " DEF"
+
+#: vms-alpha.c:5758
+msgid " UNI"
+msgstr " UNI"
+
+#: vms-alpha.c:5760 vms-alpha.c:5781
+msgid " REL"
+msgstr " REL"
+
+#: vms-alpha.c:5762
+msgid " COMM"
+msgstr " COMM"
+
+#: vms-alpha.c:5764
+msgid " VECEP"
+msgstr " VECEP"
+
+#: vms-alpha.c:5766
+msgid " NORM"
+msgstr " NORM"
+
+#: vms-alpha.c:5768
+msgid " QVAL"
+msgstr " QVAL"
+
+#: vms-alpha.c:5775
+msgid " PIC"
+msgstr " PIC"
+
+#: vms-alpha.c:5777
+msgid " LIB"
+msgstr " LIB"
+
+#: vms-alpha.c:5779
+msgid " OVR"
+msgstr " OVR"
+
+#: vms-alpha.c:5783
+msgid " GBL"
+msgstr " GBL"
+
+#: vms-alpha.c:5785
+msgid " SHR"
+msgstr " SHR"
+
+#: vms-alpha.c:5787
+msgid " EXE"
+msgstr " EXE"
+
+#: vms-alpha.c:5789
+msgid " RD"
+msgstr " RD"
+
+#: vms-alpha.c:5791
+msgid " WRT"
+msgstr " WRT"
+
+#: vms-alpha.c:5793
+msgid " VEC"
+msgstr " VEC"
+
+#: vms-alpha.c:5795
+msgid " NOMOD"
+msgstr " NOMOD"
+
+#: vms-alpha.c:5797
+msgid " COM"
+msgstr " COM"
+
+#: vms-alpha.c:5799
+msgid " 64B"
+msgstr " 64B"
+
+#: vms-alpha.c:5808
+#, c-format
+msgid " EGSD (len=%u):\n"
+msgstr " EGSD (lon=%u):\n"
+
+#: vms-alpha.c:5820
+#, c-format
+msgid " EGSD entry %2u (type: %u, len: %u): "
+msgstr " entrada EGSD %2u (tipo: %u, lon: %u): "
+
+#: vms-alpha.c:5832
+#, c-format
+msgid "PSC - Program section definition\n"
+msgstr "PSC - Definición de sección de programa\n"
+
+#: vms-alpha.c:5833 vms-alpha.c:5850
+#, c-format
+msgid " alignment : 2**%u\n"
+msgstr " alineación : 2**%u\n"
+
+#: vms-alpha.c:5834 vms-alpha.c:5851
+#, c-format
+msgid " flags : 0x%04x"
+msgstr " opciones : 0x%04x"
+
+#: vms-alpha.c:5838
+#, c-format
+msgid " alloc (len): %u (0x%08x)\n"
+msgstr " aloj (lon) : %u (0x%08x)\n"
+
+#: vms-alpha.c:5839 vms-alpha.c:5896 vms-alpha.c:5945
+#, c-format
+msgid " name : %.*s\n"
+msgstr " nombre : %.*s\n"
+
+#: vms-alpha.c:5849
+#, c-format
+msgid "SPSC - Shared Image Program section def\n"
+msgstr "SPSC - def sección Programa de Imagen Compartida\n"
+
+#: vms-alpha.c:5855
+#, c-format
+msgid " alloc (len) : %u (0x%08x)\n"
+msgstr " aloj (lon) : %u (0x%08x)\n"
+
+#: vms-alpha.c:5856
+#, c-format
+msgid " image offset : 0x%08x\n"
+msgstr " despl imagen : 0x%08x\n"
+
+#: vms-alpha.c:5858
+#, c-format
+msgid " symvec offset : 0x%08x\n"
+msgstr " despl symvec : 0x%08x\n"
+
+#: vms-alpha.c:5860
+#, c-format
+msgid " name : %.*s\n"
+msgstr " name : %.*s\n"
+
+#: vms-alpha.c:5873
+#, c-format
+msgid "SYM - Global symbol definition\n"
+msgstr "SYM - Definición de símbolo global\n"
+
+#: vms-alpha.c:5874 vms-alpha.c:5934 vms-alpha.c:5955 vms-alpha.c:5974
+#, c-format
+msgid " flags: 0x%04x"
+msgstr " opciones: 0x%04x"
+
+#: vms-alpha.c:5877
+#, c-format
+msgid " psect offset: 0x%08x\n"
+msgstr " despl psect: 0x%08x\n"
+
+#: vms-alpha.c:5881
+#, c-format
+msgid " code address: 0x%08x\n"
+msgstr " dirección código: 0x%08x\n"
+
+#: vms-alpha.c:5883
+#, c-format
+msgid " psect index for entry point : %u\n"
+msgstr " índice psect para punto de entrada : %u\n"
+
+#: vms-alpha.c:5886 vms-alpha.c:5962 vms-alpha.c:5981
+#, c-format
+msgid " psect index : %u\n"
+msgstr " índice psect : %u\n"
+
+#: vms-alpha.c:5888 vms-alpha.c:5964 vms-alpha.c:5983
+#, c-format
+msgid " name : %.*s\n"
+msgstr " nombre : %.*s\n"
+
+#: vms-alpha.c:5895
+#, c-format
+msgid "SYM - Global symbol reference\n"
+msgstr "SYM - Referencia de símbolo global\n"
+
+#: vms-alpha.c:5907
+#, c-format
+msgid "IDC - Ident Consistency check\n"
+msgstr "IDC - Revisor de Consistencia de Identación\n"
+
+#: vms-alpha.c:5908
+#, c-format
+msgid " flags : 0x%08x"
+msgstr " opciones : 0x%08x"
+
+#: vms-alpha.c:5912
+#, c-format
+msgid " id match : %x\n"
+msgstr " coinc id : %x\n"
+
+#: vms-alpha.c:5914
+#, c-format
+msgid " error severity: %x\n"
+msgstr " severidad err : %x\n"
+
+#: vms-alpha.c:5917
+#, c-format
+msgid " entity name : %.*s\n"
+msgstr " nombre entidad: %.*s\n"
+
+#: vms-alpha.c:5919
+#, c-format
+msgid " object name : %.*s\n"
+msgstr " nombre objeto : %.*s\n"
+
+#: vms-alpha.c:5922
+#, c-format
+msgid " binary ident : 0x%08x\n"
+msgstr " ident binaria : 0x%08x\n"
+
+#: vms-alpha.c:5925
+#, c-format
+msgid " ascii ident : %.*s\n"
+msgstr " ident ascii : %.*s\n"
+
+#: vms-alpha.c:5933
+#, c-format
+msgid "SYMG - Universal symbol definition\n"
+msgstr "SYMG - Definición de símbolo universal\n"
+
+#: vms-alpha.c:5937
+#, c-format
+msgid " symbol vector offset: 0x%08x\n"
+msgstr " despl vector símbolo: 0x%08x\n"
+
+#: vms-alpha.c:5939
+#, c-format
+msgid " entry point: 0x%08x\n"
+msgstr " punto de entrada: 0x%08x\n"
+
+#: vms-alpha.c:5941
+#, c-format
+msgid " proc descr : 0x%08x\n"
+msgstr " descr proc : 0x%08x\n"
+
+#: vms-alpha.c:5943
+#, c-format
+msgid " psect index: %u\n"
+msgstr " índice psect: %u\n"
+
+#: vms-alpha.c:5954
+#, c-format
+msgid "SYMV - Vectored symbol definition\n"
+msgstr "SYMV - Definición de símbolo vectorizado\n"
+
+#: vms-alpha.c:5958
+#, c-format
+msgid " vector : 0x%08x\n"
+msgstr " vector : 0x%08x\n"
+
+#: vms-alpha.c:5960 vms-alpha.c:5979
+#, c-format
+msgid " psect offset: %u\n"
+msgstr " despl psect : %u\n"
+
+#: vms-alpha.c:5973
+#, c-format
+msgid "SYMM - Global symbol definition with version\n"
+msgstr "SYMM - Definición de símbolo global con versión\n"
+
+#: vms-alpha.c:5977
+#, c-format
+msgid " version mask: 0x%08x\n"
+msgstr " máscara versión: 0x%08x\n"
+
+#: vms-alpha.c:5988
+#, c-format
+msgid "unhandled egsd entry type %u\n"
+msgstr "tipo de entrada egsd %u sin manejar\n"
+
+#: vms-alpha.c:6022
+#, c-format
+msgid " linkage index: %u, replacement insn: 0x%08x\n"
+msgstr " índice enlace: %u, insn reemplazo: 0x%08x\n"
+
+#: vms-alpha.c:6025
+#, c-format
+msgid " psect idx 1: %u, offset 1: 0x%08x %08x\n"
+msgstr " ind psect 1: %u, despl 1: 0x%08x %08x\n"
+
+#: vms-alpha.c:6029
+#, c-format
+msgid " psect idx 2: %u, offset 2: 0x%08x %08x\n"
+msgstr " ind psect 2: %u, despl 2: 0x%08x %08x\n"
+
+#: vms-alpha.c:6034
+#, c-format
+msgid " psect idx 3: %u, offset 3: 0x%08x %08x\n"
+msgstr " ind psect 3: %u, despl 3: 0x%08x %08x\n"
+
+#: vms-alpha.c:6039
+#, c-format
+msgid " global name: %.*s\n"
+msgstr " nombre global: %.*s\n"
+
+#: vms-alpha.c:6049
+#, c-format
+msgid " %s (len=%u+%u):\n"
+msgstr " %s (lon=%u+%u):\n"
+
+#: vms-alpha.c:6064
+#, c-format
+msgid " (type: %3u, size: 4+%3u): "
+msgstr " (tipo: %3u, tam: 4+%3u): "
+
+#: vms-alpha.c:6068
+#, c-format
+msgid "STA_GBL (stack global) %.*s\n"
+msgstr "STA_GBL (pila global) %.*s\n"
+
+#: vms-alpha.c:6072
+#, c-format
+msgid "STA_LW (stack longword) 0x%08x\n"
+msgstr "STA_LW (pila longword) 0x%08x\n"
+
+#: vms-alpha.c:6076
+#, c-format
+msgid "STA_QW (stack quadword) 0x%08x %08x\n"
+msgstr "STA_QW (pila quadword) 0x%08x %08x\n"
+
+#: vms-alpha.c:6081
+#, c-format
+msgid "STA_PQ (stack psect base + offset)\n"
+msgstr "STA_PQ (pila psect base + despl)\n"
+
+#: vms-alpha.c:6082
+#, c-format
+msgid " psect: %u, offset: 0x%08x %08x\n"
+msgstr " psect: %u, despl: 0x%08x %08x\n"
+
+#: vms-alpha.c:6088
+#, c-format
+msgid "STA_LI (stack literal)\n"
+msgstr "STA_LI (pila literal)\n"
+
+#: vms-alpha.c:6091
+#, c-format
+msgid "STA_MOD (stack module)\n"
+msgstr "STA_MOD (pila módulo)\n"
+
+#: vms-alpha.c:6094
+#, c-format
+msgid "STA_CKARG (compare procedure argument)\n"
+msgstr "STA_CKARG (compara argumentos de procedimientos)\n"
+
+#: vms-alpha.c:6098
+#, c-format
+msgid "STO_B (store byte)\n"
+msgstr "STO_B (almacena byte)\n"
+
+#: vms-alpha.c:6101
+#, c-format
+msgid "STO_W (store word)\n"
+msgstr "STO_W (almacena word)\n"
+
+#: vms-alpha.c:6104
+#, c-format
+msgid "STO_LW (store longword)\n"
+msgstr "STO_LW (almacena longword)\n"
+
+#: vms-alpha.c:6107
+#, c-format
+msgid "STO_QW (store quadword)\n"
+msgstr "STO_QW (almacena quadword)\n"
+
+#: vms-alpha.c:6113
+#, c-format
+msgid "STO_IMMR (store immediate repeat) %u bytes\n"
+msgstr "STO_IMMR (almacena inmediato repetido) %u bytes\n"
+
+#: vms-alpha.c:6120
+#, c-format
+msgid "STO_GBL (store global) %.*s\n"
+msgstr "STO_GBL (almacena global) %.*s\n"
+
+#: vms-alpha.c:6124
+#, c-format
+msgid "STO_CA (store code address) %.*s\n"
+msgstr "STO_CA (almacena direcc código) %.*s\n"
+
+#: vms-alpha.c:6128
+#, c-format
+msgid "STO_RB (store relative branch)\n"
+msgstr "STO_RB (almacena ramif relativa)\n"
+
+#: vms-alpha.c:6131
+#, c-format
+msgid "STO_AB (store absolute branch)\n"
+msgstr "STO_AB (almacena ramif absoluta)\n"
+
+#: vms-alpha.c:6134
+#, c-format
+msgid "STO_OFF (store offset to psect)\n"
+msgstr "STO_OFF (almacena despl para psect)\n"
+
+#: vms-alpha.c:6140
+#, c-format
+msgid "STO_IMM (store immediate) %u bytes\n"
+msgstr "STO_IMM (almacena inmediato) %u bytes\n"
+
+#: vms-alpha.c:6147
+#, c-format
+msgid "STO_GBL_LW (store global longword) %.*s\n"
+msgstr "STO_GBL_LW (almacena global longword) %.*s\n"
+
+#: vms-alpha.c:6151
+#, c-format
+msgid "STO_OFF (store LP with procedure signature)\n"
+msgstr "STO_OFF (almacena LP con firma de procedimiento)\n"
+
+#: vms-alpha.c:6154
+#, c-format
+msgid "STO_BR_GBL (store branch global) *todo*\n"
+msgstr "STO_BR_GBL (almacena ramif global) *pend*\n"
+
+#: vms-alpha.c:6157
+#, c-format
+msgid "STO_BR_PS (store branch psect + offset) *todo*\n"
+msgstr "STO_BR_PS (almacena ramif psect + despl) *pend*\n"
+
+#: vms-alpha.c:6161
+#, c-format
+msgid "OPR_NOP (no-operation)\n"
+msgstr "OPR_NOP (no operación)\n"
+
+#: vms-alpha.c:6164
+#, c-format
+msgid "OPR_ADD (add)\n"
+msgstr "OPR_ADD (adición)\n"
+
+#: vms-alpha.c:6167
+#, c-format
+msgid "OPR_SUB (substract)\n"
+msgstr "OPR_SUB (sustracción)\n"
+
+#: vms-alpha.c:6170
+#, c-format
+msgid "OPR_MUL (multiply)\n"
+msgstr "OPR_MUL (multiplicación)\n"
+
+#: vms-alpha.c:6173
+#, c-format
+msgid "OPR_DIV (divide)\n"
+msgstr "OPR_DIV (división)\n"
+
+#: vms-alpha.c:6176
+#, c-format
+msgid "OPR_AND (logical and)\n"
+msgstr "OPR_AND (and lógico)\n"
+
+#: vms-alpha.c:6179
+#, c-format
+msgid "OPR_IOR (logical inclusive or)\n"
+msgstr "OPR_IOR (or lógico inclusivo)\n"
+
+#: vms-alpha.c:6182
+#, c-format
+msgid "OPR_EOR (logical exclusive or)\n"
+msgstr "OPR_EOR (or lógico exclusivo)\n"
+
+#: vms-alpha.c:6185
+#, c-format
+msgid "OPR_NEG (negate)\n"
+msgstr "OPR_NEG (negación)\n"
+
+#: vms-alpha.c:6188
+#, c-format
+msgid "OPR_COM (complement)\n"
+msgstr "OPR_COM (complemento)\n"
+
+#: vms-alpha.c:6191
+#, c-format
+msgid "OPR_INSV (insert field)\n"
+msgstr "OPR_INSV (insertar campo)\n"
+
+#: vms-alpha.c:6194
+#, c-format
+msgid "OPR_ASH (arithmetic shift)\n"
+msgstr "OPR_ASH (despl aritmético)\n"
+
+#: vms-alpha.c:6197
+#, c-format
+msgid "OPR_USH (unsigned shift)\n"
+msgstr "OPR_USH (despl sin signo)\n"
+
+#: vms-alpha.c:6200
+#, c-format
+msgid "OPR_ROT (rotate)\n"
+msgstr "OPR_ROT (rotación)\n"
+
+#: vms-alpha.c:6203
+#, c-format
+msgid "OPR_SEL (select)\n"
+msgstr "OPR_SEL (selección)\n"
+
+#: vms-alpha.c:6206
+#, c-format
+msgid "OPR_REDEF (redefine symbol to curr location)\n"
+msgstr "OPR_REDEF (redefine símbolo a la ubicación actual)\n"
+
+#: vms-alpha.c:6209
+#, c-format
+msgid "OPR_REDEF (define a literal)\n"
+msgstr "OPR_REDEF (define una literal)\n"
+
+#: vms-alpha.c:6213
+#, c-format
+msgid "STC_LP (store cond linkage pair)\n"
+msgstr "STC_LP (almacena par de enlace cond)\n"
+
+#: vms-alpha.c:6217
+#, c-format
+msgid "STC_LP_PSB (store cond linkage pair + signature)\n"
+msgstr "STC_LP_PSB (almacena par de enlace cond + firma)\n"
+
+#: vms-alpha.c:6218
+#, c-format
+msgid " linkage index: %u, procedure: %.*s\n"
+msgstr " índice enlace: %u, procedimiento: %.*s\n"
+
+#: vms-alpha.c:6221
+#, c-format
+msgid " signature: %.*s\n"
+msgstr " firma: %.*s\n"
+
+#: vms-alpha.c:6224
+#, c-format
+msgid "STC_GBL (store cond global)\n"
+msgstr "STC_GBL (almacena cond global)\n"
+
+#: vms-alpha.c:6225
+#, c-format
+msgid " linkage index: %u, global: %.*s\n"
+msgstr " índice enlace: %u, global: %.*s\n"
+
+#: vms-alpha.c:6229
+#, c-format
+msgid "STC_GCA (store cond code address)\n"
+msgstr "STC_GCA (almacena dirección de código cond)\n"
+
+#: vms-alpha.c:6230
+#, c-format
+msgid " linkage index: %u, procedure name: %.*s\n"
+msgstr " índice enlace: %u, nombre procedimiento: %.*s\n"
+
+#: vms-alpha.c:6234
+#, c-format
+msgid "STC_PS (store cond psect + offset)\n"
+msgstr "STC_PS (almacena psect cond + despl)\n"
+
+#: vms-alpha.c:6236
+#, c-format
+msgid " linkage index: %u, psect: %u, offset: 0x%08x %08x\n"
+msgstr " índice enlace: %u, psect: %u, despl: 0x%08x %08x\n"
+
+#: vms-alpha.c:6243
+#, c-format
+msgid "STC_NOP_GBL (store cond NOP at global addr)\n"
+msgstr "STC_NOP_GBL (almacena NOP cond en dirección global)\n"
+
+#: vms-alpha.c:6247
+#, c-format
+msgid "STC_NOP_PS (store cond NOP at psect + offset)\n"
+msgstr "STC_NOP_PS (almacena NOP cond en psect + despl)\n"
+
+#: vms-alpha.c:6251
+#, c-format
+msgid "STC_BSR_GBL (store cond BSR at global addr)\n"
+msgstr "STC_BSR_GBL (almacena BSR cond en dirección global)\n"
+
+#: vms-alpha.c:6255
+#, c-format
+msgid "STC_BSR_PS (store cond BSR at psect + offset)\n"
+msgstr "STC_BSR_PS (almacena BSR cond en psect + despl)\n"
+
+#: vms-alpha.c:6259
+#, c-format
+msgid "STC_LDA_GBL (store cond LDA at global addr)\n"
+msgstr "STC_LDA_GBL (almacena LDA cond en dirección global)\n"
+
+#: vms-alpha.c:6263
+#, c-format
+msgid "STC_LDA_PS (store cond LDA at psect + offset)\n"
+msgstr "STC_LDA_PS (almacena LDA cond en psect + despl)\n"
+
+#: vms-alpha.c:6267
+#, c-format
+msgid "STC_BOH_GBL (store cond BOH at global addr)\n"
+msgstr "STC_BOH_GBL (almacena BOH cond en dirección global)\n"
+
+#: vms-alpha.c:6271
+#, c-format
+msgid "STC_BOH_PS (store cond BOH at psect + offset)\n"
+msgstr "STC_BOH_PS (almacena BOH cond en psect + despl)\n"
+
+#: vms-alpha.c:6276
+#, c-format
+msgid "STC_NBH_GBL (store cond or hint at global addr)\n"
+msgstr "STC_NBH_GBL (almacena cond o pista en dirección global)\n"
+
+#: vms-alpha.c:6280
+#, c-format
+msgid "STC_NBH_PS (store cond or hint at psect + offset)\n"
+msgstr "STC_NBH_PS (almacena cond o pista en psect + despl)\n"
+
+#: vms-alpha.c:6284
+#, c-format
+msgid "CTL_SETRB (set relocation base)\n"
+msgstr "CTL_SETRB (define base de reubicación)\n"
+
+#: vms-alpha.c:6290
+#, c-format
+msgid "CTL_AUGRB (augment relocation base) %u\n"
+msgstr "CTL_AUGRB (aumenta base de reubicación) %u\n"
+
+#: vms-alpha.c:6294
+#, c-format
+msgid "CTL_DFLOC (define location)\n"
+msgstr "CTL_DFLOC (define ubicación)\n"
+
+#: vms-alpha.c:6297
+#, c-format
+msgid "CTL_STLOC (set location)\n"
+msgstr "CTL_STLOC (establece ubicación)\n"
+
+#: vms-alpha.c:6300
+#, c-format
+msgid "CTL_STKDL (stack defined location)\n"
+msgstr "CTL_STKDL (ubicación definida de pila)\n"
+
+#: vms-alpha.c:6303 vms-alpha.c:6717
+#, c-format
+msgid "*unhandled*\n"
+msgstr "*sin manejar*\n"
+
+#: vms-alpha.c:6333 vms-alpha.c:6372
+#, c-format
+msgid "cannot read GST record length\n"
+msgstr "no se puede leer la longitud del registro GST\n"
+
+#. Ill-formed.
+#: vms-alpha.c:6354
+#, c-format
+msgid "cannot find EMH in first GST record\n"
+msgstr "no se puede encontrar EMH en el primer registro GST\n"
+
+#: vms-alpha.c:6380
+#, c-format
+msgid "cannot read GST record header\n"
+msgstr "no se puede leer el encabezado del registro GST\n"
+
+#: vms-alpha.c:6393
+#, c-format
+msgid " corrupted GST\n"
+msgstr " GST corrupto\n"
+
+#: vms-alpha.c:6401
+#, c-format
+msgid "cannot read GST record\n"
+msgstr "no se puede leer el registro GST\n"
+
+#: vms-alpha.c:6430
+#, c-format
+msgid " unhandled EOBJ record type %u\n"
+msgstr " tipo de registro EOBJ %u sin manejar\n"
+
+#: vms-alpha.c:6453
+#, c-format
+msgid " bitcount: %u, base addr: 0x%08x\n"
+msgstr " cuenta bit: %u, direcc base: 0x%08x\n"
+
+#: vms-alpha.c:6466
+#, c-format
+msgid " bitmap: 0x%08x (count: %u):\n"
+msgstr " mapa bit: 0x%08x (cuenta: %u):\n"
+
+#: vms-alpha.c:6473
+#, c-format
+msgid " %08x"
+msgstr " %08x"
+
+#: vms-alpha.c:6498
+#, c-format
+msgid " image %u (%u entries)\n"
+msgstr " imagen %u (%u entradas)\n"
+
+#: vms-alpha.c:6503
+#, c-format
+msgid " offset: 0x%08x, val: 0x%08x\n"
+msgstr " despl: 0x%08x, val: 0x%08x\n"
+
+#: vms-alpha.c:6524
+#, c-format
+msgid " image %u (%u entries), offsets:\n"
+msgstr " imagen %u (%u entradas), desplazamientos:\n"
+
+#: vms-alpha.c:6531
+#, c-format
+msgid " 0x%08x"
+msgstr " 0x%08x"
+
+#. 64 bits.
+#: vms-alpha.c:6653
+#, c-format
+msgid "64 bits *unhandled*\n"
+msgstr "64 bits *sin manejar*\n"
+
+#: vms-alpha.c:6657
+#, c-format
+msgid "class: %u, dtype: %u, length: %u, pointer: 0x%08x\n"
+msgstr "clase: %u, tipod: %u, long: %u, puntero: 0x%08x\n"
+
+#: vms-alpha.c:6668
+#, c-format
+msgid "non-contiguous array of %s\n"
+msgstr "matriz no contigua de %s\n"
+
+#: vms-alpha.c:6672
+#, c-format
+msgid "dimct: %u, aflags: 0x%02x, digits: %u, scale: %u\n"
+msgstr "dimct: %u, aops: 0x%02x, dígitos: %u, escala: %u\n"
+
+#: vms-alpha.c:6676
+#, c-format
+msgid "arsize: %u, a0: 0x%08x\n"
+msgstr "artam: %u, a0: 0x%08x\n"
+
+#: vms-alpha.c:6680
+#, c-format
+msgid "Strides:\n"
+msgstr "Estribos:\n"
+
+#: vms-alpha.c:6685
+#, c-format
+msgid "[%u]: %u\n"
+msgstr "[%u]: %u\n"
+
+#: vms-alpha.c:6690
+#, c-format
+msgid "Bounds:\n"
+msgstr "Límites:\n"
+
+#: vms-alpha.c:6695
+#, c-format
+msgid "[%u]: Lower: %u, upper: %u\n"
+msgstr "[%u]: Inferior: %u, superior: %u\n"
+
+#: vms-alpha.c:6707
+#, c-format
+msgid "unaligned bit-string of %s\n"
+msgstr "cadena de bit sin alinear de %s\n"
+
+#: vms-alpha.c:6711
+#, c-format
+msgid "base: %u, pos: %u\n"
+msgstr "base: %u, pos: %u\n"
+
+#: vms-alpha.c:6731
+#, c-format
+msgid "vflags: 0x%02x, value: 0x%08x "
+msgstr "vops: 0x%02x, valor: 0x%08x "
+
+#: vms-alpha.c:6737
+#, c-format
+msgid "(no value)\n"
+msgstr "(sin valor)\n"
+
+#: vms-alpha.c:6740
+#, c-format
+msgid "(not active)\n"
+msgstr "(no activo)\n"
+
+#: vms-alpha.c:6743
+#, c-format
+msgid "(not allocated)\n"
+msgstr "(sin ubicar)\n"
+
+#: vms-alpha.c:6746
+#, c-format
+msgid "(descriptor)\n"
+msgstr "(descriptor)\n"
+
+#: vms-alpha.c:6750
+#, c-format
+msgid "(trailing value)\n"
+msgstr "(valor restante)\n"
+
+#: vms-alpha.c:6753
+#, c-format
+msgid "(value spec follows)\n"
+msgstr "(valor spec a continuación)\n"
+
+#: vms-alpha.c:6756
+#, c-format
+msgid "(at bit offset %u)\n"
+msgstr "(en el despl de bit %u)\n"
+
+#: vms-alpha.c:6759
+#, c-format
+msgid "(reg: %u, disp: %u, indir: %u, kind: "
+msgstr "(reg: %u, disp: %u, indir: %u, género: "
+
+#: vms-alpha.c:6766
+msgid "literal"
+msgstr "literal"
+
+#: vms-alpha.c:6769
+msgid "address"
+msgstr "dirección"
+
+#: vms-alpha.c:6772
+msgid "desc"
+msgstr "desc"
+
+#: vms-alpha.c:6775
+msgid "reg"
+msgstr "reg"
+
+#: vms-alpha.c:6850
+#, c-format
+msgid "Debug symbol table:\n"
+msgstr "Tabla de símbolos de depuración:\n"
+
+#: vms-alpha.c:6861
+#, c-format
+msgid "cannot read DST header\n"
+msgstr "no se puede leer el encabezado DST\n"
+
+#: vms-alpha.c:6866
+#, c-format
+msgid " type: %3u, len: %3u (at 0x%08x): "
+msgstr " tipo: %3u, lon: %3u (en 0x%08x): "
+
+#: vms-alpha.c:6880
+#, c-format
+msgid "cannot read DST symbol\n"
+msgstr "no se puede leer el símbolo DST\n"
+
+#: vms-alpha.c:6923
+#, c-format
+msgid "standard data: %s\n"
+msgstr "datos estándar: %s\n"
+
+#: vms-alpha.c:6926 vms-alpha.c:7010
+#, c-format
+msgid " name: %.*s\n"
+msgstr " nombre: %.*s\n"
+
+#: vms-alpha.c:6933
+#, c-format
+msgid "modbeg\n"
+msgstr "modini\n"
+
+#: vms-alpha.c:6934
+#, c-format
+msgid " flags: %d, language: %u, major: %u, minor: %u\n"
+msgstr " ops: %d, lenguaje: %u, mayor: %u, menor: %u\n"
+
+#: vms-alpha.c:6940 vms-alpha.c:7206
+#, c-format
+msgid " module name: %.*s\n"
+msgstr " nom módulo : %.*s\n"
+
+#: vms-alpha.c:6943
+#, c-format
+msgid " compiler : %.*s\n"
+msgstr " compilador : %.*s\n"
+
+#: vms-alpha.c:6948
+#, c-format
+msgid "modend\n"
+msgstr "modfin\n"
+
+#: vms-alpha.c:6955
+msgid "rtnbeg\n"
+msgstr "rtnini\n"
+
+#: vms-alpha.c:6956
+#, c-format
+msgid " flags: %u, address: 0x%08x, pd-address: 0x%08x\n"
+msgstr " ops: %u, dirección: 0x%08x, direcc-pd: 0x%08x\n"
+
+#: vms-alpha.c:6961
+#, c-format
+msgid " routine name: %.*s\n"
+msgstr " nom rutina : %.*s\n"
+
+#: vms-alpha.c:6969
+#, c-format
+msgid "rtnend: size 0x%08x\n"
+msgstr "rtnfin: tam 0x%08x\n"
+
+#: vms-alpha.c:6977
+#, c-format
+msgid "prolog: bkpt address 0x%08x\n"
+msgstr "prolog: dirección bkpt 0x%08x\n"
+
+#: vms-alpha.c:6985
+#, c-format
+msgid "epilog: flags: %u, count: %u\n"
+msgstr "epilog: ops: %u, cuenta: %u\n"
+
+#: vms-alpha.c:6994
+#, c-format
+msgid "blkbeg: address: 0x%08x, name: %.*s\n"
+msgstr "blkini: dirección: 0x%08x, nombre: %.*s\n"
+
+#: vms-alpha.c:7003
+#, c-format
+msgid "blkend: size: 0x%08x\n"
+msgstr "blkfin: tam: 0x%08x\n"
+
+#: vms-alpha.c:7009
+#, c-format
+msgid "typspec (len: %u)\n"
+msgstr "espectip (lon: %u)\n"
+
+#: vms-alpha.c:7016
+#, c-format
+msgid "septyp, name: %.*s\n"
+msgstr "septip, nombre: %.*s\n"
+
+#: vms-alpha.c:7025
+#, c-format
+msgid "recbeg: name: %.*s\n"
+msgstr "recini: nombre: %.*s\n"
+
+#: vms-alpha.c:7032
+#, c-format
+msgid "recend\n"
+msgstr "recfin\n"
+
+#: vms-alpha.c:7035
+#, c-format
+msgid "enumbeg, len: %u, name: %.*s\n"
+msgstr "enuini, lon: %u, nombre: %.*s\n"
+
+#: vms-alpha.c:7039
+#, c-format
+msgid "enumelt, name: %.*s\n"
+msgstr "enufin, nombre: %.*s\n"
+
+#: vms-alpha.c:7043
+#, c-format
+msgid "enumend\n"
+msgstr "enufin\n"
+
+#: vms-alpha.c:7060
+#, c-format
+msgid "discontiguous range (nbr: %u)\n"
+msgstr "rango discontinuo (nbr: %u)\n"
+
+#: vms-alpha.c:7062
+#, c-format
+msgid " address: 0x%08x, size: %u\n"
+msgstr " dirección: 0x%08x, tamaño: %u\n"
+
+#: vms-alpha.c:7072
+#, c-format
+msgid "line num (len: %u)\n"
+msgstr "num línea (lon: %u)\n"
+
+#: vms-alpha.c:7089
+#, c-format
+msgid "delta_pc_w %u\n"
+msgstr "delta_pc_w %u\n"
+
+#: vms-alpha.c:7096
+#, c-format
+msgid "incr_linum(b): +%u\n"
+msgstr "incr_linum(b): +%u\n"
+
+#: vms-alpha.c:7102
+#, c-format
+msgid "incr_linum_w: +%u\n"
+msgstr "incr_linum_w: +%u\n"
+
+#: vms-alpha.c:7108
+#, c-format
+msgid "incr_linum_l: +%u\n"
+msgstr "incr_linum_l: +%u\n"
+
+#: vms-alpha.c:7114
+#, c-format
+msgid "set_line_num(w) %u\n"
+msgstr "set_line_num(w) %u\n"
+
+#: vms-alpha.c:7119
+#, c-format
+msgid "set_line_num_b %u\n"
+msgstr "set_line_num_b %u\n"
+
+#: vms-alpha.c:7124
+#, c-format
+msgid "set_line_num_l %u\n"
+msgstr "set_line_num_l %u\n"
+
+#: vms-alpha.c:7129
+#, c-format
+msgid "set_abs_pc: 0x%08x\n"
+msgstr "set_abs_pc: 0x%08x\n"
+
+#: vms-alpha.c:7133
+#, c-format
+msgid "delta_pc_l: +0x%08x\n"
+msgstr "delta_pc_l: +0x%08x\n"
+
+#: vms-alpha.c:7138
+#, c-format
+msgid "term(b): 0x%02x"
+msgstr "term(b): 0x%02x"
+
+#: vms-alpha.c:7140
+#, c-format
+msgid " pc: 0x%08x\n"
+msgstr " pc: 0x%08x\n"
+
+#: vms-alpha.c:7145
+#, c-format
+msgid "term_w: 0x%04x"
+msgstr "term_w: 0x%04x"
+
+#: vms-alpha.c:7147
+#, c-format
+msgid " pc: 0x%08x\n"
+msgstr " pc: 0x%08x\n"
+
+#: vms-alpha.c:7153
+#, c-format
+msgid "delta pc +%-4d"
+msgstr "delta pc +%-4d"
+
+#: vms-alpha.c:7156
+#, c-format
+msgid " pc: 0x%08x line: %5u\n"
+msgstr " pc: 0x%08x línea: %5u\n"
+
+#: vms-alpha.c:7161
+#, c-format
+msgid " *unhandled* cmd %u\n"
+msgstr " *sin manejar* ord %u\n"
+
+#: vms-alpha.c:7176
+#, c-format
+msgid "source (len: %u)\n"
+msgstr "fuente (lon: %u)\n"
+
+#: vms-alpha.c:7190
+#, c-format
+msgid " declfile: len: %u, flags: %u, fileid: %u\n"
+msgstr " declfich: lon: %u, ops: %u, fichid: %u\n"
+
+#: vms-alpha.c:7194
+#, c-format
+msgid " rms: cdt: 0x%08x %08x, ebk: 0x%08x, ffb: 0x%04x, rfo: %u\n"
+msgstr " rms: cdt: 0x%08x %08x, ebk: 0x%08x, ffb: 0x%04x, rfo: %u\n"
+
+#: vms-alpha.c:7203
+#, c-format
+msgid " filename : %.*s\n"
+msgstr " nomfichero : %.*s\n"
+
+#: vms-alpha.c:7212
+#, c-format
+msgid " setfile %u\n"
+msgstr " setfile %u\n"
+
+#: vms-alpha.c:7217 vms-alpha.c:7222
+#, c-format
+msgid " setrec %u\n"
+msgstr " setrect %u\n"
+
+#: vms-alpha.c:7227 vms-alpha.c:7232
+#, c-format
+msgid " setlnum %u\n"
+msgstr " setlnum %u\n"
+
+#: vms-alpha.c:7237 vms-alpha.c:7242
+#, c-format
+msgid " deflines %u\n"
+msgstr " deflines %u\n"
+
+#: vms-alpha.c:7246
+#, c-format
+msgid " formfeed\n"
+msgstr " alimforma\n"
+
+#: vms-alpha.c:7250
+#, c-format
+msgid " *unhandled* cmd %u\n"
+msgstr " *sin manejar* ord %u\n"
+
+#: vms-alpha.c:7262
+#, c-format
+msgid "*unhandled* dst type %u\n"
+msgstr "tipo dst %u *sin manejar*\n"
+
+#: vms-alpha.c:7294
+#, c-format
+msgid "cannot read EIHD\n"
+msgstr "no se puede leer EIHD\n"
+
+#: vms-alpha.c:7297
+#, c-format
+msgid "EIHD: (size: %u, nbr blocks: %u)\n"
+msgstr "EIHD: (tamaño: %u, bloques nbr: %u)\n"
+
+#: vms-alpha.c:7300
+#, c-format
+msgid " majorid: %u, minorid: %u\n"
+msgstr " idmayor: %u, idmenor: %u\n"
+
+#: vms-alpha.c:7308
+msgid "executable"
+msgstr "ejecutable"
+
+#: vms-alpha.c:7311
+msgid "linkable image"
+msgstr "imagen enlazable"
+
+#: vms-alpha.c:7317
+#, c-format
+msgid " image type: %u (%s)"
+msgstr " tipo imagen: %u (%s)"
+
+#: vms-alpha.c:7323
+msgid "native"
+msgstr "nativa"
+
+#: vms-alpha.c:7326
+msgid "CLI"
+msgstr "CLI"
+
+#: vms-alpha.c:7332
+#, c-format
+msgid ", subtype: %u (%s)\n"
+msgstr ", subtipo: %u (%s)\n"
+
+#: vms-alpha.c:7338
+#, c-format
+msgid " offsets: isd: %u, activ: %u, symdbg: %u, imgid: %u, patch: %u\n"
+msgstr " despls: isd: %u, activ: %u, simdep: %u, idimg: %u, parche: %u\n"
+
+#: vms-alpha.c:7342
+#, c-format
+msgid " fixup info rva: "
+msgstr " info compos rva: "
+
+#: vms-alpha.c:7344
+#, c-format
+msgid ", symbol vector rva: "
+msgstr " vector símbolo rva: "
+
+#: vms-alpha.c:7347
+#, c-format
+msgid ""
+"\n"
+" version array off: %u\n"
+msgstr ""
+"\n"
+" matriz versión despl: %u\n"
+
+#: vms-alpha.c:7351
+#, c-format
+msgid " img I/O count: %u, nbr channels: %u, req pri: %08x%08x\n"
+msgstr " cuenta I/O img: %u, canales nbr: %u, pri req: %08x%08x\n"
+
+#: vms-alpha.c:7357
+#, c-format
+msgid " linker flags: %08x:"
+msgstr " opciones de enlazador: %08x:"
+
+#: vms-alpha.c:7387
+#, c-format
+msgid " ident: 0x%08x, sysver: 0x%08x, match ctrl: %u, symvect_size: %u\n"
+msgstr " ident: 0x%08x, versis: 0x%08x, ctrl coinc: %u, tam_vectsim: %u\n"
+
+#: vms-alpha.c:7393
+#, c-format
+msgid " BPAGE: %u"
+msgstr " BPAGE: %u"
+
+#: vms-alpha.c:7399
+#, c-format
+msgid ", ext fixup offset: %u, no_opt psect off: %u"
+msgstr ", ext comp despl: %u, no_opt desp psect: %u"
+
+#: vms-alpha.c:7402
+#, c-format
+msgid ", alias: %u\n"
+msgstr ", alias: %u\n"
+
+#: vms-alpha.c:7410
+#, c-format
+msgid "system version array information:\n"
+msgstr "información de matriz de versión de sistema:\n"
+
+#: vms-alpha.c:7414
+#, c-format
+msgid "cannot read EIHVN header\n"
+msgstr "no se puede leer el encabezado EIHVN\n"
+
+#: vms-alpha.c:7424
+#, c-format
+msgid "cannot read EIHVN version\n"
+msgstr "no se puede leer la versión EIHVN\n"
+
+#: vms-alpha.c:7427
+#, c-format
+msgid " %02u "
+msgstr " %02u "
+
+#: vms-alpha.c:7431
+msgid "BASE_IMAGE "
+msgstr "IMAGEN_BASE "
+
+#: vms-alpha.c:7434
+msgid "MEMORY_MANAGEMENT"
+msgstr "ADMIN_MEMORIA"
+
+#: vms-alpha.c:7437
+msgid "IO "
+msgstr "ES "
+
+#: vms-alpha.c:7440
+msgid "FILES_VOLUMES "
+msgstr "VOL_FICHEROS "
+
+#: vms-alpha.c:7443
+msgid "PROCESS_SCHED "
+msgstr "CALEND_PROCESOS "
+
+#: vms-alpha.c:7446
+msgid "SYSGEN "
+msgstr "GENSIS "
+
+#: vms-alpha.c:7449
+msgid "CLUSTERS_LOCKMGR "
+msgstr "ADMBLOQ_CLUSTERS "
+
+#: vms-alpha.c:7452
+msgid "LOGICAL_NAMES "
+msgstr "NOMBRES_LOGICOS "
+
+#: vms-alpha.c:7455
+msgid "SECURITY "
+msgstr "SEGURIDAD "
+
+#: vms-alpha.c:7458
+msgid "IMAGE_ACTIVATOR "
+msgstr "ACTIVADOR_IMAGEN "
+
+#: vms-alpha.c:7461
+msgid "NETWORKS "
+msgstr "REDES "
+
+#: vms-alpha.c:7464
+msgid "COUNTERS "
+msgstr "CONTADORES "
+
+#: vms-alpha.c:7467
+msgid "STABLE "
+msgstr "ESTABLE "
+
+#: vms-alpha.c:7470
+msgid "MISC "
+msgstr "MISC "
+
+#: vms-alpha.c:7473
+msgid "CPU "
+msgstr "CPU "
+
+#: vms-alpha.c:7476
+msgid "VOLATILE "
+msgstr "VOLÃTIL "
+
+#: vms-alpha.c:7479
+msgid "SHELL "
+msgstr "SHELL "
+
+#: vms-alpha.c:7482
+msgid "POSIX "
+msgstr "POSIX "
+
+#: vms-alpha.c:7485
+msgid "MULTI_PROCESSING "
+msgstr "MULTI_PROCESAM "
+
+#: vms-alpha.c:7488
+msgid "GALAXY "
+msgstr "GALAXIA "
+
+#: vms-alpha.c:7491
+msgid "*unknown* "
+msgstr "*desconocido* "
+
+#: vms-alpha.c:7494
+#, c-format
+msgid ": %u.%u\n"
+msgstr ": %u.%u\n"
+
+#: vms-alpha.c:7507 vms-alpha.c:7766
+#, c-format
+msgid "cannot read EIHA\n"
+msgstr "no se puede leer EIHA\n"
+
+#: vms-alpha.c:7510
+#, c-format
+msgid "Image activation: (size=%u)\n"
+msgstr "Activa imagen : (tamaño=%u)\n"
+
+#: vms-alpha.c:7512
+#, c-format
+msgid " First address : 0x%08x 0x%08x\n"
+msgstr " Primera direcc: 0x%08x 0x%08x\n"
+
+#: vms-alpha.c:7515
+#, c-format
+msgid " Second address: 0x%08x 0x%08x\n"
+msgstr " Segunda direcc: 0x%08x 0x%08x\n"
+
+#: vms-alpha.c:7518
+#, c-format
+msgid " Third address : 0x%08x 0x%08x\n"
+msgstr " Tercera direcc: 0x%08x 0x%08x\n"
+
+#: vms-alpha.c:7521
+#, c-format
+msgid " Fourth address: 0x%08x 0x%08x\n"
+msgstr " Cuarta direcc : 0x%08x 0x%08x\n"
+
+#: vms-alpha.c:7524
+#, c-format
+msgid " Shared image : 0x%08x 0x%08x\n"
+msgstr " Imagen compar : 0x%08x 0x%08x\n"
+
+#: vms-alpha.c:7535
+#, c-format
+msgid "cannot read EIHI\n"
+msgstr "no se puede leer EIHI\n"
+
+#: vms-alpha.c:7538
+#, c-format
+msgid "Image identification: (major: %u, minor: %u)\n"
+msgstr "Identificación de imagen: (mayor: %u, menor: %u)\n"
+
+#: vms-alpha.c:7541
+#, c-format
+msgid " image name : %.*s\n"
+msgstr " nombre de imagen : %.*s\n"
+
+#: vms-alpha.c:7543
+#, c-format
+msgid " link time : %s\n"
+msgstr " hora enlazado : %s\n"
+
+#: vms-alpha.c:7545
+#, c-format
+msgid " image ident : %.*s\n"
+msgstr " ident imagen : %.*s\n"
+
+#: vms-alpha.c:7547
+#, c-format
+msgid " linker ident : %.*s\n"
+msgstr " ident enlazador : %.*s\n"
+
+#: vms-alpha.c:7549
+#, c-format
+msgid " image build ident: %.*s\n"
+msgstr " ident const imagen: %.*s\n"
+
+#: vms-alpha.c:7559
+#, c-format
+msgid "cannot read EIHS\n"
+msgstr "no se puede leer EIHS\n"
+
+#: vms-alpha.c:7562
+#, c-format
+msgid "Image symbol & debug table: (major: %u, minor: %u)\n"
+msgstr "Símbolo de imagen y tabla de depuración: (mayor: %u, menor %u)\n"
+
+#: vms-alpha.c:7567
+#, c-format
+msgid " debug symbol table : vbn: %u, size: %u (0x%x)\n"
+msgstr " tabla de símbolos de depuración : vbn: %u, tam: %u (0x%x)\n"
+
+#: vms-alpha.c:7571
+#, c-format
+msgid " global symbol table: vbn: %u, records: %u\n"
+msgstr " tabla de símbolos globales : vbn: %u, registros: %u\n"
+
+#: vms-alpha.c:7575
+#, c-format
+msgid " debug module table : vbn: %u, size: %u\n"
+msgstr " tabla de módulo de depuración : vbn: %u, tam: %u\n"
+
+#: vms-alpha.c:7588
+#, c-format
+msgid "cannot read EISD\n"
+msgstr "no se puede leer EISD\n"
+
+#: vms-alpha.c:7598
+#, c-format
+msgid "Image section descriptor: (major: %u, minor: %u, size: %u, offset: %u)\n"
+msgstr "Descriptor de sección de imagen: (mayor: %u, menor: %u, tam: %u, despl: %u)\n"
+
+#: vms-alpha.c:7605
+#, c-format
+msgid " section: base: 0x%08x%08x size: 0x%08x\n"
+msgstr " sección: base: 0x%08x%08x tam: 0x%08x\n"
+
+#: vms-alpha.c:7610
+#, c-format
+msgid " flags: 0x%04x"
+msgstr " opciones: %04x"
+
+#: vms-alpha.c:7647
+#, c-format
+msgid " vbn: %u, pfc: %u, matchctl: %u type: %u ("
+msgstr " vbn: %u, pfc: %u, coincctl: %u tipo: %u ("
+
+#: vms-alpha.c:7653
+msgid "NORMAL"
+msgstr "NORMAL"
+
+#: vms-alpha.c:7656
+msgid "SHRFXD"
+msgstr "SHRFXD"
+
+#: vms-alpha.c:7659
+msgid "PRVFXD"
+msgstr "PRVFXD"
+
+#: vms-alpha.c:7662
+msgid "SHRPIC"
+msgstr "SHRPIC"
+
+#: vms-alpha.c:7665
+msgid "PRVPIC"
+msgstr "PRVPIC"
+
+#: vms-alpha.c:7668
+msgid "USRSTACK"
+msgstr "USRSTACK"
+
+#: vms-alpha.c:7676
+#, c-format
+msgid " ident: 0x%08x, name: %.*s\n"
+msgstr " ident: 0x%08x, nombre: %.*s\n"
+
+#: vms-alpha.c:7686
+#, c-format
+msgid "cannot read DMT\n"
+msgstr "no se puede leer DMT\n"
+
+#: vms-alpha.c:7690
+#, c-format
+msgid "Debug module table:\n"
+msgstr "Tabla de módulos de depuración\n"
+
+#: vms-alpha.c:7699
+#, c-format
+msgid "cannot read DMT header\n"
+msgstr "no se puede leer el encabezado DMT\n"
+
+#: vms-alpha.c:7704
+#, c-format
+msgid " module offset: 0x%08x, size: 0x%08x, (%u psects)\n"
+msgstr " despl módulo: 0x%08x, tam: 0x%08x, (%u psects)\n"
+
+#: vms-alpha.c:7714
+#, c-format
+msgid "cannot read DMT psect\n"
+msgstr "no se puede leer el psect DMT\n"
+
+#: vms-alpha.c:7717
+#, c-format
+msgid " psect start: 0x%08x, length: %u\n"
+msgstr " psect inicio: 0x%08x, long: %u\n"
+
+#: vms-alpha.c:7730
+#, c-format
+msgid "cannot read DST\n"
+msgstr "no se puede leer DST\n"
+
+#: vms-alpha.c:7740
+#, c-format
+msgid "cannot read GST\n"
+msgstr "no se puede leer GST\n"
+
+#: vms-alpha.c:7744
+#, c-format
+msgid "Global symbol table:\n"
+msgstr "Tabla de símbolos global:\n"
+
+#: vms-alpha.c:7772
+#, c-format
+msgid "Image activator fixup: (major: %u, minor: %u)\n"
+msgstr "Compostura de activador de imagen: (mayor: %u, menor: %u)\n"
+
+#: vms-alpha.c:7775
+#, c-format
+msgid " iaflink : 0x%08x %08x\n"
+msgstr " iafenl : 0x%08x %08x\n"
+
+#: vms-alpha.c:7778
+#, c-format
+msgid " fixuplnk: 0x%08x %08x\n"
+msgstr " compenl : 0x%08x %08x\n"
+
+#: vms-alpha.c:7781
+#, c-format
+msgid " size : %u\n"
+msgstr " tam : %u\n"
+
+#: vms-alpha.c:7783
+#, c-format
+msgid " flags: 0x%08x\n"
+msgstr " ops : 0x%08x\n"
+
+#: vms-alpha.c:7787
+#, c-format
+msgid " qrelfixoff: %5u, lrelfixoff: %5u\n"
+msgstr " qrelfixoff: %5u, lrelfixoff: %5u\n"
+
+#: vms-alpha.c:7791
+#, c-format
+msgid " qdotadroff: %5u, ldotadroff: %5u\n"
+msgstr " qdotadroff: %5u, ldotadroff: %5u\n"
+
+#: vms-alpha.c:7795
+#, c-format
+msgid " codeadroff: %5u, lpfixoff : %5u\n"
+msgstr " codeadroff: %5u, lpfixoff : %5u\n"
+
+#: vms-alpha.c:7798
+#, c-format
+msgid " chgprtoff : %5u\n"
+msgstr " chgprtoff : %5u\n"
+
+#: vms-alpha.c:7801
+#, c-format
+msgid " shlstoff : %5u, shrimgcnt : %5u\n"
+msgstr " shlstoff : %5u, shrimgcnt : %5u\n"
+
+#: vms-alpha.c:7803
+#, c-format
+msgid " shlextra : %5u, permctx : %5u\n"
+msgstr " shlextra : %5u, permctx : %5u\n"
+
+#: vms-alpha.c:7806
+#, c-format
+msgid " base_va : 0x%08x\n"
+msgstr " base_va : 0x%08x\n"
+
+#: vms-alpha.c:7808
+#, c-format
+msgid " lppsbfixoff: %5u\n"
+msgstr " lppsbfixoff: %5u\n"
+
+#: vms-alpha.c:7816
+#, c-format
+msgid " Shareable images:\n"
+msgstr " Imágenes compartibles:\n"
+
+#: vms-alpha.c:7820
+#, c-format
+msgid " %u: size: %u, flags: 0x%02x, name: %.*s\n"
+msgstr " %u: tam: %u, opts: 0x%02x, nombre: %.*s\n"
+
+#: vms-alpha.c:7827
+#, c-format
+msgid " quad-word relocation fixups:\n"
+msgstr " composturas de reubicación quad-word:\n"
+
+#: vms-alpha.c:7832
+#, c-format
+msgid " long-word relocation fixups:\n"
+msgstr " composturas de reubicación long-word:\n"
+
+#: vms-alpha.c:7837
+#, c-format
+msgid " quad-word .address reference fixups:\n"
+msgstr " composturas de referencia .address quad-word:\n"
+
+#: vms-alpha.c:7842
+#, c-format
+msgid " long-word .address reference fixups:\n"
+msgstr " composturas de referencia .address long-word:\n"
+
+#: vms-alpha.c:7847
+#, c-format
+msgid " Code Address Reference Fixups:\n"
+msgstr " Composturas de Referencias de Dirección de Código:\n"
+
+#: vms-alpha.c:7852
+#, c-format
+msgid " Linkage Pairs Referece Fixups:\n"
+msgstr " Composturas de Referencias de Pares de Enlazado\n"
+
+#: vms-alpha.c:7861
+#, c-format
+msgid " Change Protection (%u entries):\n"
+msgstr " Cambiar Protección (%u entradas):\n"
+
+#: vms-alpha.c:7866
+#, c-format
+msgid " base: 0x%08x %08x, size: 0x%08x, prot: 0x%08x "
+msgstr " base: 0x%08x %08x, tam: 0x%08x, prot: 0x%08x "
+
+#. FIXME: we do not yet support relocatable link. It is not obvious
+#. how to do it for debug infos.
+#: vms-alpha.c:8706
+msgid "%P: relocatable link is not supported\n"
+msgstr "%P: no se admite el enlace reubicable\n"
+
+#: vms-alpha.c:8776
+msgid "%P: multiple entry points: in modules %B and %B\n"
+msgstr "%P: puntos de entrada múltiples: en los módulos %B y %B\n"
+
+#: vms-lib.c:1423
+#, c-format
+msgid "could not open shared image '%s' from '%s'"
+msgstr "no se puede abrir la imagen compartida '%s' desde '%s'"
+
+#: vms-misc.c:360
+msgid "_bfd_vms_output_counted called with zero bytes"
+msgstr "se llamó _bfd_vms_output_counted con cero bytes"
+
+#: vms-misc.c:365
+msgid "_bfd_vms_output_counted called with too many bytes"
+msgstr "se llamó _bfd_vms_output_counted con demasiados bytes"
+
+#: xcofflink.c:836
+#, c-format
+msgid "%s: XCOFF shared object when not producing XCOFF output"
+msgstr "%s: objeto compartido XCOFF cuando no se produce salida XCOFF"
+
+#: xcofflink.c:857
+#, c-format
+msgid "%s: dynamic object with no .loader section"
+msgstr "%s: objeto dinámico sin sección .loader"
+
+#: xcofflink.c:1416
+msgid "%B: `%s' has line numbers but no enclosing section"
+msgstr "%B: `%s' tiene números de línea pero no una sección contenedora"
+
+#: xcofflink.c:1468
+msgid "%B: class %d symbol `%s' has no aux entries"
+msgstr "%B: clase %d símbolo `%s' no tiene entradas auxiliares"
+
+#: xcofflink.c:1490
+msgid "%B: symbol `%s' has unrecognized csect type %d"
+msgstr "%B: el símbolo `%s' tiene un tipo csect %d que no se reconoce"
+
+#: xcofflink.c:1502
+msgid "%B: bad XTY_ER symbol `%s': class %d scnum %d scnlen %d"
+msgstr "%B: símbolo XTY_ER `%s' erróneo: clase %d scnum %d scnlen %d"
+
+#: xcofflink.c:1531
+msgid "%B: XMC_TC0 symbol `%s' is class %d scnlen %d"
+msgstr "%B: símbolo XMC_TCO `%s' es clase %d scnlen %d"
+
+#: xcofflink.c:1677
+msgid "%B: csect `%s' not in enclosing section"
+msgstr "%B: csect `%s' no está contenido en una sección"
+
+#: xcofflink.c:1784
+msgid "%B: misplaced XTY_LD `%s'"
+msgstr "%B: XTY_LD `%s' mal ubicado"
+
+#: xcofflink.c:2103
+msgid "%B: reloc %s:%d not in csect"
+msgstr "%B: la reubicación %s:%d no está en csect"
+
+#: xcofflink.c:3194
+#, c-format
+msgid "%s: no such symbol"
+msgstr "%s: no hay tal símbolo"
+
+#: xcofflink.c:3299
+#, c-format
+msgid "warning: attempt to export undefined symbol `%s'"
+msgstr "aviso: se intenta exportar el símbolo sin definir `%s'"
+
+#: xcofflink.c:3678
+msgid "error: undefined symbol __rtinit"
+msgstr "error: símbolo __rtinit sin definir"
+
+#: xcofflink.c:4057
+msgid "%B: loader reloc in unrecognized section `%s'"
+msgstr "%B: reubicación del cargador en la sección `%s' que no se reconoce"
+
+#: xcofflink.c:4068
+msgid "%B: `%s' in loader reloc but not loader sym"
+msgstr "%B: `%s' en la reubicación del cargador pero no es un símbolo del cargador"
+
+#: xcofflink.c:4084
+msgid "%B: loader reloc in read-only section %A"
+msgstr "%B: reubicación del cargador en la sección de sólo lectura %A"
+
+#: xcofflink.c:5106
+#, c-format
+msgid "TOC overflow: 0x%lx > 0x10000; try -mminimal-toc when compiling"
+msgstr "Desbordamiento de TOC: 0x%lx > 0x10000; pruebe -mminimal-toc al compilar"
+
+#: elf32-ia64.c:628 elf64-ia64.c:628
+msgid "%B: Can't relax br at 0x%lx in section `%A'. Please use brl or indirect branch."
+msgstr "%B: No se puede relajar br en 0x%lx en la sección `%A'. Por favor use brl o ramificación indirecta."
+
+#: elf32-ia64.c:2284 elf64-ia64.c:2284
+msgid "@pltoff reloc against local symbol"
+msgstr "reubicación @pltoff contra un símbolo local"
+
+#: elf32-ia64.c:3687 elf64-ia64.c:3687
+#, c-format
+msgid "%s: short data segment overflowed (0x%lx >= 0x400000)"
+msgstr "%s: segmento de datos short desbordado (0x%lx >= 0x400000)"
+
+#: elf32-ia64.c:3698 elf64-ia64.c:3698
+#, c-format
+msgid "%s: __gp does not cover short data segment"
+msgstr "%s: __gp no cubre el segmento de datos short"
+
+#: elf32-ia64.c:3965 elf64-ia64.c:3965
+msgid "%B: non-pic code with imm relocation against dynamic symbol `%s'"
+msgstr "%B: código que no es pic con reubicación imm contra el símbolo dinámico %s"
+
+#: elf32-ia64.c:4032 elf64-ia64.c:4032
+msgid "%B: @gprel relocation against dynamic symbol %s"
+msgstr "%B: reubicación @gprel contra el símbolo dinámico %s"
+
+#: elf32-ia64.c:4095 elf64-ia64.c:4095
+msgid "%B: linking non-pic code in a position independent executable"
+msgstr "%B: se enlaza código que no es pic en un ejecutable independiente de posición"
+
+#: elf32-ia64.c:4232 elf64-ia64.c:4232
+msgid "%B: @internal branch to dynamic symbol %s"
+msgstr "%B: ramificación @internal al símbolo dinámico %s"
+
+#: elf32-ia64.c:4234 elf64-ia64.c:4234
+msgid "%B: speculation fixup to dynamic symbol %s"
+msgstr "%B: compostura de especulación al símbolo dinámico %s"
+
+#: elf32-ia64.c:4236 elf64-ia64.c:4236
+msgid "%B: @pcrel relocation against dynamic symbol %s"
+msgstr "%B: reubicación @pcrel contra el símbolo dinámico %s"
+
+#: elf32-ia64.c:4433 elf64-ia64.c:4433
+msgid "unsupported reloc"
+msgstr "no se admite la reubicación"
+
+#: elf32-ia64.c:4471 elf64-ia64.c:4471
+msgid "%B: missing TLS section for relocation %s against `%s' at 0x%lx in section `%A'."
+msgstr "%B: falta la sección TLS para la reubicación %s contra `%s' en 0x%lx en la sección `%A'."
+
+#: elf32-ia64.c:4486 elf64-ia64.c:4486
+msgid "%B: Can't relax br (%s) to `%s' at 0x%lx in section `%A' with size 0x%lx (> 0x1000000)."
+msgstr "%B: No se puede relajar br (%s) a `%s' en 0x%lx en la sección `%A' con tamaño 0x%lx (> 0x1000000)."
+
+#: elf32-ia64.c:4748 elf64-ia64.c:4748
+msgid "%B: linking trap-on-NULL-dereference with non-trapping files"
+msgstr "%B: se enlaza deferencias-captura-en-NULL con ficheros que no son de captura"
+
+#: elf32-ia64.c:4757 elf64-ia64.c:4757
+msgid "%B: linking big-endian files with little-endian files"
+msgstr "%B: se enlazan ficheros big-endian con ficheros little-endian"
+
+#: elf32-ia64.c:4766 elf64-ia64.c:4766
+msgid "%B: linking 64-bit files with 32-bit files"
+msgstr "%B: se enlazan ficheros de 64-bit con ficheros de 32-bit"
+
+#: elf32-ia64.c:4775 elf64-ia64.c:4775
+msgid "%B: linking constant-gp files with non-constant-gp files"
+msgstr "%B: se enlazan ficheros de gp constante con ficheros con gp no constante"
+
+#: elf32-ia64.c:4785 elf64-ia64.c:4785
+msgid "%B: linking auto-pic files with non-auto-pic files"
+msgstr "%B: se enlazan ficheros de pic automático con ficheros sin pic automático"
+
+#: peigen.c:1002 pepigen.c:1002 pex64igen.c:1002
+#, c-format
+msgid "%s: line number overflow: 0x%lx > 0xffff"
+msgstr "%s: desbordamiento de número de línea: 0x%lx > 0xffff"
+
+#: peigen.c:1029 pepigen.c:1029 pex64igen.c:1029
+msgid "Export Directory [.edata (or where ever we found it)]"
+msgstr "Directorio de Exportación [.edata (o donde quiera que se encuentre)]"
+
+#: peigen.c:1030 pepigen.c:1030 pex64igen.c:1030
+msgid "Import Directory [parts of .idata]"
+msgstr "Directorio de Importación [partes de .idata]"
+
+#: peigen.c:1031 pepigen.c:1031 pex64igen.c:1031
+msgid "Resource Directory [.rsrc]"
+msgstr "Directorio de Recursos [.rsrc]"
+
+#: peigen.c:1032 pepigen.c:1032 pex64igen.c:1032
+msgid "Exception Directory [.pdata]"
+msgstr "Directorio de Excepciones [.pdata]"
+
+#: peigen.c:1033 pepigen.c:1033 pex64igen.c:1033
+msgid "Security Directory"
+msgstr "Directorio de Seguridad"
+
+#: peigen.c:1034 pepigen.c:1034 pex64igen.c:1034
+msgid "Base Relocation Directory [.reloc]"
+msgstr "Directorio de Reubicación Base [.reloc]"
+
+#: peigen.c:1035 pepigen.c:1035 pex64igen.c:1035
+msgid "Debug Directory"
+msgstr "Directorio de Depuración"
+
+#: peigen.c:1036 pepigen.c:1036 pex64igen.c:1036
+msgid "Description Directory"
+msgstr "Directorio de Descripciones"
+
+#: peigen.c:1037 pepigen.c:1037 pex64igen.c:1037
+msgid "Special Directory"
+msgstr "Directorio Especial"
+
+#: peigen.c:1038 pepigen.c:1038 pex64igen.c:1038
+msgid "Thread Storage Directory [.tls]"
+msgstr "Directorio de Almacenamiento de Hilos [.tls]"
+
+#: peigen.c:1039 pepigen.c:1039 pex64igen.c:1039
+msgid "Load Configuration Directory"
+msgstr "Directorio de Carga de Configuraciones"
+
+#: peigen.c:1040 pepigen.c:1040 pex64igen.c:1040
+msgid "Bound Import Directory"
+msgstr "Directorio de Importación de Relaciones"
+
+#: peigen.c:1041 pepigen.c:1041 pex64igen.c:1041
+msgid "Import Address Table Directory"
+msgstr "Directorio de Tablas de Direcciones de Importación"
+
+#: peigen.c:1042 pepigen.c:1042 pex64igen.c:1042
+msgid "Delay Import Directory"
+msgstr "Directorio de Retardo de Importación"
+
+#: peigen.c:1043 pepigen.c:1043 pex64igen.c:1043
+msgid "CLR Runtime Header"
+msgstr "Encabezado de Tiempo de Ejecución CLR"
+
+#: peigen.c:1044 pepigen.c:1044 pex64igen.c:1044
+msgid "Reserved"
+msgstr "Reservado"
+
+#: peigen.c:1104 pepigen.c:1104 pex64igen.c:1104
+#, c-format
+msgid ""
+"\n"
+"There is an import table, but the section containing it could not be found\n"
+msgstr ""
+"\n"
+"Hay una tabla de importación, pero no se puede encontrar la sección que la contiene\n"
+
+#: peigen.c:1109 pepigen.c:1109 pex64igen.c:1109
+#, c-format
+msgid ""
+"\n"
+"There is an import table in %s at 0x%lx\n"
+msgstr ""
+"\n"
+"Hay una tabla de importación en %s en 0x%lx\n"
+
+#: peigen.c:1151 pepigen.c:1151 pex64igen.c:1151
+#, c-format
+msgid ""
+"\n"
+"Function descriptor located at the start address: %04lx\n"
+msgstr ""
+"\n"
+"Se localizó el descriptor de función en la dirección de inicio: %04lx\n"
+
+#: peigen.c:1154 pepigen.c:1154 pex64igen.c:1154
+#, c-format
+msgid "\tcode-base %08lx toc (loadable/actual) %08lx/%08lx\n"
+msgstr "\tcódigo-base %08lx tabla-de-contenidos (cargable/actual) %08lx/%08lx\n"
+
+#: peigen.c:1162 pepigen.c:1162 pex64igen.c:1162
+#, c-format
+msgid ""
+"\n"
+"No reldata section! Function descriptor not decoded.\n"
+msgstr ""
+"\n"
+"¡No está la sección reldata! No se decodificó el descriptor de función.\n"
+
+#: peigen.c:1167 pepigen.c:1167 pex64igen.c:1167
+#, c-format
+msgid ""
+"\n"
+"The Import Tables (interpreted %s section contents)\n"
+msgstr ""
+"\n"
+"Las Tablas de Importación (se interpretaron los contenidos de la sección %s)\n"
+
+#: peigen.c:1170 pepigen.c:1170 pex64igen.c:1170
+#, c-format
+msgid ""
+" vma: Hint Time Forward DLL First\n"
+" Table Stamp Chain Name Thunk\n"
+msgstr ""
+" vma: Pista Fecha Adelante DLL Primero\n"
+" Tabla Estampa Cadena Nombre Thunk\n"
+
+#: peigen.c:1218 pepigen.c:1218 pex64igen.c:1218
+#, c-format
+msgid ""
+"\n"
+"\tDLL Name: %s\n"
+msgstr ""
+"\n"
+"\tNombre de la DLL: %s\n"
+
+#: peigen.c:1229 pepigen.c:1229 pex64igen.c:1229
+#, c-format
+msgid "\tvma: Hint/Ord Member-Name Bound-To\n"
+msgstr "\tvma: Pista/Ord Nombre-Miembro Unido-A\n"
+
+#: peigen.c:1254 pepigen.c:1254 pex64igen.c:1254
+#, c-format
+msgid ""
+"\n"
+"There is a first thunk, but the section containing it could not be found\n"
+msgstr ""
+"\n"
+"Hay un thunk inicial, pero no se puede encontrar la sección que lo contiene\n"
+
+#: peigen.c:1415 pepigen.c:1415 pex64igen.c:1415
+#, c-format
+msgid ""
+"\n"
+"There is an export table, but the section containing it could not be found\n"
+msgstr ""
+"\n"
+"Hay una tabla de exportación, pero no se puede encontrar la sección que la contiene\n"
+
+#: peigen.c:1424 pepigen.c:1424 pex64igen.c:1424
+#, c-format
+msgid ""
+"\n"
+"There is an export table in %s, but it does not fit into that section\n"
+msgstr ""
+"\n"
+"Hay una tabla de exportación en %s, pero no cabe en esa sección\n"
+
+#: peigen.c:1430 pepigen.c:1430 pex64igen.c:1430
+#, c-format
+msgid ""
+"\n"
+"There is an export table in %s at 0x%lx\n"
+msgstr ""
+"\n"
+"Hay una tabla de exportación en %s en 0x%lx\n"
+
+#: peigen.c:1458 pepigen.c:1458 pex64igen.c:1458
+#, c-format
+msgid ""
+"\n"
+"The Export Tables (interpreted %s section contents)\n"
+"\n"
+msgstr ""
+"\n"
+"Las Tablas de Exportación (se interpretaron los contenidos de la sección %s)\n"
+"\n"
+
+#: peigen.c:1462 pepigen.c:1462 pex64igen.c:1462
+#, c-format
+msgid "Export Flags \t\t\t%lx\n"
+msgstr "Opciones de Exportación \t\t\t%lx\n"
+
+#: peigen.c:1465 pepigen.c:1465 pex64igen.c:1465
+#, c-format
+msgid "Time/Date stamp \t\t%lx\n"
+msgstr "marca de Hora/Fecha \t\t%lx\n"
+
+#: peigen.c:1468 pepigen.c:1468 pex64igen.c:1468
+#, c-format
+msgid "Major/Minor \t\t\t%d/%d\n"
+msgstr "Mayor/Menor \t\t\t%d/%d\n"
+
+#: peigen.c:1471 pepigen.c:1471 pex64igen.c:1471
+#, c-format
+msgid "Name \t\t\t\t"
+msgstr "Nombre \t\t\t\t"
+
+#: peigen.c:1477 pepigen.c:1477 pex64igen.c:1477
+#, c-format
+msgid "Ordinal Base \t\t\t%ld\n"
+msgstr "Base Ordinal \t\t\t%ld\n"
+
+#: peigen.c:1480 pepigen.c:1480 pex64igen.c:1480
+#, c-format
+msgid "Number in:\n"
+msgstr "Número en:\n"
+
+#: peigen.c:1483 pepigen.c:1483 pex64igen.c:1483
+#, c-format
+msgid "\tExport Address Table \t\t%08lx\n"
+msgstr "\tTabla de Exportación de Direcciones \t\t%08lx\n"
+
+#: peigen.c:1487 pepigen.c:1487 pex64igen.c:1487
+#, c-format
+msgid "\t[Name Pointer/Ordinal] Table\t%08lx\n"
+msgstr "\tTabla [Nombre Puntero/Ordinal]\t%08lx\n"
+
+#: peigen.c:1490 pepigen.c:1490 pex64igen.c:1490
+#, c-format
+msgid "Table Addresses\n"
+msgstr "Direcciones de la Tabla\n"
+
+#: peigen.c:1493 pepigen.c:1493 pex64igen.c:1493
+#, c-format
+msgid "\tExport Address Table \t\t"
+msgstr "\tTabla de Exportación de Direcciones \t\t"
+
+#: peigen.c:1498 pepigen.c:1498 pex64igen.c:1498
+#, c-format
+msgid "\tName Pointer Table \t\t"
+msgstr "\tNombre de la Tabla de Punteros \t\t"
+
+# continuar aqui
+#: peigen.c:1503 pepigen.c:1503 pex64igen.c:1503
+#, c-format
+msgid "\tOrdinal Table \t\t\t"
+msgstr "\tTabla Ordinal \t\t\t"
+
+#: peigen.c:1517 pepigen.c:1517 pex64igen.c:1517
+#, c-format
+msgid ""
+"\n"
+"Export Address Table -- Ordinal Base %ld\n"
+msgstr ""
+"\n"
+"Tabla de Exportación de Direcciones -- Base Ordinal %ld\n"
+
+#: peigen.c:1536 pepigen.c:1536 pex64igen.c:1536
+msgid "Forwarder RVA"
+msgstr "RVA Adelantador"
+
+#: peigen.c:1547 pepigen.c:1547 pex64igen.c:1547
+msgid "Export RVA"
+msgstr "RVA Exportador"
+
+#: peigen.c:1554 pepigen.c:1554 pex64igen.c:1554
+#, c-format
+msgid ""
+"\n"
+"[Ordinal/Name Pointer] Table\n"
+msgstr ""
+"\n"
+"Tabla [Puntero a Ordinal/Nombre]\n"
+
+#: peigen.c:1614 peigen.c:1797 pepigen.c:1614 pepigen.c:1797 pex64igen.c:1614
+#: pex64igen.c:1797
+#, c-format
+msgid "Warning, .pdata section size (%ld) is not a multiple of %d\n"
+msgstr "Aviso, el tamaño de la sección .pdata (%ld) no es un múltiplo de %d\n"
+
+#: peigen.c:1621 pepigen.c:1621 pex64igen.c:1621
+#, c-format
+msgid " vma:\t\t\tBegin Address End Address Unwind Info\n"
+msgstr " vma:\t\t\tDirección Inicio Dirección Fin Información Desenvuelta\n"
+
+#: peigen.c:1623 pepigen.c:1623 pex64igen.c:1623
+#, c-format
+msgid ""
+" vma:\t\tBegin End EH EH PrologEnd Exception\n"
+" \t\tAddress Address Handler Data Address Mask\n"
+msgstr ""
+" vma:\t\tInicio Fin EH EH FinPrólogo Excepción\n"
+" \t\tDirecc Direcc Asa Datos Dirección Máscara\n"
+
+#: peigen.c:1697 pepigen.c:1697 pex64igen.c:1697
+#, c-format
+msgid " Register save millicode"
+msgstr " Registro para guardar milicódigo"
+
+#: peigen.c:1700 pepigen.c:1700 pex64igen.c:1700
+#, c-format
+msgid " Register restore millicode"
+msgstr " Registro para restaurar milicódigo"
+
+#: peigen.c:1703 pepigen.c:1703 pex64igen.c:1703
+#, c-format
+msgid " Glue code sequence"
+msgstr " Secuencia de código pegamento"
+
+#: peigen.c:1803 pepigen.c:1803 pex64igen.c:1803
+#, c-format
+msgid ""
+" vma:\t\tBegin Prolog Function Flags Exception EH\n"
+" \t\tAddress Length Length 32b exc Handler Data\n"
+msgstr ""
+" vma:\t\tInicio Prólogo Función Opciones Excepción EH\n"
+" \t\tDirecc Longitud Longitud 32b exc Manejador Datos\n"
+
+#: peigen.c:1929 pepigen.c:1929 pex64igen.c:1929
+#, c-format
+msgid ""
+"\n"
+"\n"
+"PE File Base Relocations (interpreted .reloc section contents)\n"
+msgstr ""
+"\n"
+"\n"
+"Reubicaciones de Fichero Base PE (se interpretaron los contenidos de la sección .reloc)\n"
+
+#: peigen.c:1958 pepigen.c:1958 pex64igen.c:1958
+#, c-format
+msgid ""
+"\n"
+"Virtual Address: %08lx Chunk size %ld (0x%lx) Number of fixups %ld\n"
+msgstr ""
+"\n"
+"Dirección Virtual: %08lx Tamaño del trozo %ld (0x%lx) Número de composturas %ld\n"
+
+#: peigen.c:1971 pepigen.c:1971 pex64igen.c:1971
+#, c-format
+msgid "\treloc %4d offset %4x [%4lx] %s"
+msgstr "\treubicación %4d desplazamiento %4x [%4lx] %s"
+
+#. The MS dumpbin program reportedly ands with 0xff0f before
+#. printing the characteristics field. Not sure why. No reason to
+#. emulate it here.
+#: peigen.c:2010 pepigen.c:2010 pex64igen.c:2010
+#, c-format
+msgid ""
+"\n"
+"Characteristics 0x%x\n"
+msgstr ""
+"\n"
+"Características 0x%x\n"
+
+#: peigen.c:2310 pepigen.c:2310 pex64igen.c:2310
+msgid "%B: unable to fill in DataDictionary[1] because .idata$2 is missing"
+msgstr "%B: no se puede llenar DataDictionary[1] porque falta .idata$2"
+
+#: peigen.c:2330 pepigen.c:2330 pex64igen.c:2330
+msgid "%B: unable to fill in DataDictionary[1] because .idata$4 is missing"
+msgstr "%B: no se puede llenar DataDictionary[1] porque falta .idata$4"
+
+#: peigen.c:2351 pepigen.c:2351 pex64igen.c:2351
+msgid "%B: unable to fill in DataDictionary[12] because .idata$5 is missing"
+msgstr "%B: no se puede llenar DataDictionary[12] porque falta .idata$5"
+
+#: peigen.c:2371 pepigen.c:2371 pex64igen.c:2371
+msgid "%B: unable to fill in DataDictionary[PE_IMPORT_ADDRESS_TABLE (12)] because .idata$6 is missing"
+msgstr "%B: no se puede llenar DataDictionary[PE_IMPORT_ADDRESS_TABLE (12)] porque falta .idata$6"
+
+#: peigen.c:2413 pepigen.c:2413 pex64igen.c:2413
+msgid "%B: unable to fill in DataDictionary[PE_IMPORT_ADDRESS_TABLE(12)] because .idata$6 is missing"
+msgstr "%B: no se puede llenar DataDictionary[PE_IMPORT_ADDRESS_TABLE(12)] porque falta .idata$6"
+
+#: peigen.c:2438 pepigen.c:2438 pex64igen.c:2438
+msgid "%B: unable to fill in DataDictionary[9] because __tls_used is missing"
+msgstr "%B: no se puede llenar DataDictionary[9] porque falta __tls_used"
+
+#~ msgid "%B: error: taking the address of protected function '%s' cannot be done when making a shared library"
+#~ msgstr "%B: error: no se puede tomar la dirección de la función protegida '%s' cuando se hace una biblioteca compartida"
+
+#~ msgid "%B(%A+0x%lx): cannot reach %s"
+#~ msgstr "%B(%A+0x%lx): no se puede alcanzar %s"
+
+#~ msgid "%B: warning: ignoring duplicate section `%A'\n"
+#~ msgstr "%B: aviso: se descarta la sección duplicada `%A'\n"
+
+#~ msgid "%B: warning: duplicate section `%A' has different size\n"
+#~ msgstr "%B: aviso: la sección duplicada `%A' es de tamaño diferente\n"
+
+#~ msgid "relocation references a different segment"
+#~ msgstr "la reubicación referencía un segmento diferente"
+
+#~ msgid "%B: relocation type %d not implemented"
+#~ msgstr "%B: el tipo de reubicación %d aún no está implementado"
+
+#~ msgid "warning: %B and %B differ in position-dependence of data addressing"
+#~ msgstr "aviso: %B y %B difieren en el direccionamiento de datos dependiente de posición"
+
+#~ msgid "warning: %B and %B differ in position-dependence of code addressing"
+#~ msgstr "aviso: %B y %B difieren en el direccionamiento de código dependiente de posición"
+
+#~ msgid "Can't Make it a Short Jump"
+#~ msgstr "No se Puede Convertir en un Salto Corto"
+
+#~ msgid "Exceeds Long Jump Range"
+#~ msgstr "Excede el Rango de Salto Largo"
+
+#~ msgid "Absolute address Exceeds 16 bit Range"
+#~ msgstr "La dirección Absoluta Excede el Rango de 16 bit"
+
+#~ msgid "Absolute address Exceeds 8 bit Range"
+#~ msgstr "La dirección Absoluta Excede el Rango de 8 bit"
+
+#~ msgid "Unrecognized Reloc Type"
+#~ msgstr "No se reconoce el Tipo de Reubicación"
+
+#~ msgid "corrupt or empty %s section in %B"
+#~ msgstr "sección %s corrupta o vacía en %B"
+
+#~ msgid "%s: invalid DSO for symbol `%s' definition"
+#~ msgstr "%s: DSO inválido para la definición del símbolo `%s'"
+
+#~ msgid "%B: %A+0x%lx: jump to stub routine which is not jal"
+#~ msgstr "%B: %A+0x%lx: salto a una rutina cabo la cual no es jal"
+
+#~ msgid "bfd_make_section (%s) failed"
+#~ msgstr "bfd_make_section (%s) falló"
+
+#~ msgid "bfd_set_section_flags (%s, %x) failed"
+#~ msgstr "bfd_set_section_flags (%s, %x) falló"
+
+#~ msgid "Size mismatch section %s=%lx, %s=%lx"
+#~ msgstr "No coincide el tamaño de la sección %s=%lx, %s=%lx"
+
+#~ msgid "failed to enter %s"
+#~ msgstr "falló la introducción de %s"
+
+#~ msgid "No Mem !"
+#~ msgstr "¡ No hay Memoria !"
+
+#~ msgid "reserved STO cmd %d"
+#~ msgstr "orden STO %d reservada"
+
+#~ msgid "reserved OPR cmd %d"
+#~ msgstr "orden OPR %d reservada"
+
+#~ msgid "reserved CTL cmd %d"
+#~ msgstr "orden CTL %d reservada"
+
+#~ msgid "reserved STC cmd %d"
+#~ msgstr "orden STC %d reservada"
+
+#~ msgid "stack-from-image not implemented"
+#~ msgstr "pila-desde-imagen sin implementar"
+
+#~ msgid "stack-entry-mask not fully implemented"
+#~ msgstr "pila-máscara-entrada no está completamente implementado"
+
+#~ msgid "PASSMECH not fully implemented"
+#~ msgstr "PASSMECH no está completamente implementado"
+
+#~ msgid "stack-local-symbol not fully implemented"
+#~ msgstr "pila-símbolo-local no está completamente implementado"
+
+#~ msgid "stack-literal not fully implemented"
+#~ msgstr "pila-literal no está completamente implementado"
+
+#~ msgid "stack-local-symbol-entry-point-mask not fully implemented"
+#~ msgstr "pila-símbolo-local-máscara-punto-entrada no está completamente implementado"
+
+#~ msgid "%s: not fully implemented"
+#~ msgstr "%s: no está completamente implementado"
+
+#~ msgid "obj code %d not found"
+#~ msgstr "no se encontró el código objeto %d"
+
+#~ msgid "Reloc size error in section %s"
+#~ msgstr "Error del tamaño de reubicación en la sección %s"
+
+#~ msgid "ERROR: %B: Incompatible object tag '%s':%d"
+#~ msgstr "ERROR: %B: Etiqueta de objeto '%s' incompatible:%d"
+
+#~ msgid "%B(%A): warning: unresolvable relocation against symbol `%s'"
+#~ msgstr "%B(%A): aviso: reubicación sin resolución contra el símbolo `%s'"
+
+#~ msgid "%B: Internal inconsistency; no relocation section %s"
+#~ msgstr "%B: Inconsistencia interna; no se encuentra la sección de reubicación %s"
+
+#~ msgid "Could not find relocation section for %s"
+#~ msgstr "No se puede encontrar la sección de reubicación para %s"
+
+#~ msgid "%B: GOT overflow: Number of R_68K_GOT8O and R_68K_GOT16O relocations > %d"
+#~ msgstr "%B desbordamiento de GOT: Número de reubicaciones R_68K_GOT80 Y R_68K_GOT160 > %d"
+
+#~ msgid "%A link_order not found\n"
+#~ msgstr "no se encontró link_order %A\n"
+
+#~ msgid "%s: no symbol \"%s\""
+#~ msgstr "%s: no existe el símbolo \"%s\""
+
+#~ msgid "%s: loader reloc in unrecognized section `%s'"
+#~ msgstr "%s: reubicación del cargador en la sección `%s' no reconocida"
+
+#~ msgid "%s: `%s' in loader reloc but not loader sym"
+#~ msgstr "%s: `%s' en la reubicación del cargador pero no es un símbolo del cargador"
+
+#~ msgid "Dwarf Error: DW_FORM_strp offset (%lu) greater than or equal to .debug_str size (%lu)."
+#~ msgstr "Error de Dwarf: El desplazamiento DW_FROM_strp (%lu) es más grande o igual que el tamaño de .debug_str (%lu)."
+
+#~ msgid "Dwarf Error: Can't find .debug_abbrev section."
+#~ msgstr "Error de Dwarf: No se puede encontrar la sección .debug_abbrev."
+
+#~ msgid "Dwarf Error: Abbrev offset (%lu) greater than or equal to .debug_abbrev size (%lu)."
+#~ msgstr "Error de Dwarf: El desplazamiento de abreviatura (%lu) es más grande o igual que el tamaño de .debug_abbrev (%lu)."
+
+#~ msgid "Dwarf Error: Can't find .debug_ranges section."
+#~ msgstr "Error de Dwarf: No se puede encontrar lan sección .debug_ranges."
+
+#~ msgid "ERROR: %B: Conflicting definitions of wchar_t"
+#~ msgstr "ERROR: %B: Definiciones en conflicto de wchar_t"
+
+#~ msgid "%B: relocation R_X86_64_PC32 against protected function `%s' can not be used when making a shared object"
+#~ msgstr "%B: no se puede usar la reubicación R_X86_64_PC32 contra la función protegida `%' cuando se hace un objeto compartido"
+
+#~ msgid "ERROR: %B: Conflicting enum sizes"
+#~ msgstr "ERROR: %B: Tamaños de enum en conflicto"
+
+#~ msgid "Division by zero. "
+#~ msgstr "División por cero. "
+
+#~ msgid " [cpu32]"
+#~ msgstr " [cpu32]"
+
+#~ msgid " [m68000]"
+#~ msgstr " [m68000]"
+
+#~ msgid "Linking mips16 objects into %s format is not supported"
+#~ msgstr "No se admite enlazar objetos mips16 en el formato %s"
+
+#~ msgid ".glink and .plt too far apart"
+#~ msgstr ".glink y .plt están demasiado alejados"
+
+#~ msgid "%B: Not enough room for program headers (allocated %u, need %u)"
+#~ msgstr "%B: No hay suficiente espacio para los encabezados del programa (%u asignados, %u necesarios)"
+
+#~ msgid " [mips1]"
+#~ msgstr " [mips1]"
+
+#~ msgid " [mips2]"
+#~ msgstr " [mips2]"
+
+#~ msgid " [mips3]"
+#~ msgstr " [mips3]"
+
+#~ msgid " [mips4]"
+#~ msgstr " [mips4]"
+
+#~ msgid " [mips5]"
+#~ msgstr " [mips5]"
+
+#~ msgid " [mips32]"
+#~ msgstr " [mips32]"
+
+#~ msgid " [mips64]"
+#~ msgstr " [mips64]"
+
+#~ msgid " [mips32r2]"
+#~ msgstr " [mips32r2]"
+
+#~ msgid " [mips64r2]"
+#~ msgstr " [mips64r2]"
+
+#~ msgid " [mdmx]"
+#~ msgstr " [mdmx]"
+
+#~ msgid " [mips16]"
+#~ msgstr " [mips16]"
+
+#~ msgid " [32bitmode]"
+#~ msgstr " [modo 32bit]"
+
+#~ msgid "Missing IHCONST"
+#~ msgstr "IHCONST faltante"
+
+#~ msgid "Missing IHIHALF"
+#~ msgstr "IHIHALF faltante"
+
+#~ msgid "missing IHCONST reloc"
+#~ msgstr "reubicación IHCONST faltante"
+
+#~ msgid "missing IHIHALF reloc"
+#~ msgstr "reubicación IHIHALF faltante"
+
+#~ msgid "%s: warning: unresolvable relocation against symbol `%s' from %s section"
+#~ msgstr "%s: aviso: reubicación sin resolución contra el símbolo `%s' de la sección %s"
+
+#~ msgid "Symbol %s has no GOT subsection for offset 0x%x"
+#~ msgstr "El símbolo %s no tiene subsección GOT para el desplazamiento 0x%x"
+
+#~ msgid "%B: check_relocs: unhandled reloc type %d"
+#~ msgstr "%B: check_relocs: tipo de reubicación %d sin manejar"
+
+#~ msgid "%B: warning: sh_link not set for section `%S'"
+#~ msgstr "%B: aviso: no se estableció sh_link para la sección `%S'"
+
+#~ msgid " first occurrence: %s: arm call to thumb"
+#~ msgstr " primera ocurrencia: %s: llamada arm a thumb"
+
+#~ msgid " first occurrence: %s: thumb call to arm"
+#~ msgstr " primera ocurrencia: %s: llamada thumb a arm"
+
+#~ msgid " consider relinking with --support-old-code enabled"
+#~ msgstr " considere el reenlace con --support-old-code activado"
+
+#~ msgid "reloc against unsupported section"
+#~ msgstr "reubicación contra una sección no admitida"
+
+#~ msgid "Error: First section in segment (%s) starts at 0x%x whereas the segment starts at 0x%x"
+#~ msgstr "Error: La primera sección en el segmento (%s) inicia en 0x%x mientras que el segmento inicia en 0x%x"
+
+#~ msgid "ERROR: %s is compiled for EABI version %d, whereas %s is compiled for version %d"
+#~ msgstr "ERROR: %s está compilado para EABI versión %d, mientras que %s está compilado para la versión %d"
+
+#~ msgid "%s: unresolvable relocation %s against symbol `%s' from %s section"
+#~ msgstr "%s: reubicación %s sin resolución contra el símbolo `%s' de la sección %s"
+
+#~ msgid "%s: relocation %s should not be used when making a shared object; recompile with -fPIC"
+#~ msgstr "%s: no se debe usar la reubicación %s cuando se hace un objeto compartido; recompile con -fPIC"
+
+#~ msgid "%s(%s+0x%lx): fixing %s"
+#~ msgstr "%s(%s+0x%lx): fijando %s"
+
+#~ msgid "%s: unresolvable relocation against symbol `%s' from %s section"
+#~ msgstr "%s: reubicación sin resolución contra el símbolo `%s' de la sección %s"
+
+#~ msgid "%s: linking non-pic code in a shared library"
+#~ msgstr "%s: se enlaza código que no es pic en una biblioteca compartida"
+
+#~ msgid "%s: reloc overflow 1: 0x%lx > 0xffff"
+#~ msgstr "%s: desbordamiento de reubicación 1: 0x%lx > 0xffff"
+
+#~ msgid "%s: Unknown special linker type %d"
+#~ msgstr "%s: Tipo de enlazador especial %d desconocido"
+
+#~ msgid "v850ea architecture"
+#~ msgstr "arquitectura v850ea"
+
+#~ msgid "%s: Section %s is too large to add hole of %ld bytes"
+#~ msgstr "%s: La sección %s es muy grande para agregar un agujero de %ld bytes"
+
+#~ msgid "Error: out of memory"
+#~ msgstr "Error: memoria agotada"
+
+#~ msgid "warning: relocation against removed section; zeroing"
+#~ msgstr "aviso: reubicación contra una sección eliminada; se cambia a ceros"
+
+#~ msgid "local symbols in discarded section %s"
+#~ msgstr "símbolos locales en la sección descartada %s"
+
+#~ msgid "%s: ISA mismatch (-mips%d) with previous modules (-mips%d)"
+#~ msgstr "%s: no coincide el ISA (-mips%d) con módulos previos (-mips%d)"
+
+#~ msgid "%s: ISA mismatch (%d) with previous modules (%d)"
+#~ msgstr "%s: no coincide el ISA (%d) con módulos previos (%d)"
+
+#~ msgid "%s: dynamic relocation against speculation fixup"
+#~ msgstr "%s: reubicación dinámica contra una compostura de especulación"
+
+#~ msgid "%s: speculation fixup against undefined weak symbol"
+#~ msgstr "%s: compostura de especulación contra un símbolo débil indefinido"
+
+#~ msgid "\tThe Import Address Table (difference found)\n"
+#~ msgstr "\tLa Tabla de Importación de Direcciones (se encontró una diferencia)\n"
+
+#~ msgid "\t>>> Ran out of IAT members!\n"
+#~ msgstr "\t>>> ¡Se terminaron los miembros IAT!\n"
+
+#~ msgid "\tThe Import Address Table is identical\n"
+#~ msgstr "\tLa Tabla de Importación de Direcciones es idéntica\n"
+
+#~ msgid "GP relative relocation when GP not defined"
+#~ msgstr "reubicación GP relativa cuando GP no estaba definido"
+
+#~ msgid "%s: ERROR: passes floats in float registers whereas target %s uses integer registers"
+#~ msgstr "%s: ERROR: pasan números de coma flotante en registros de coma flotante mientras que el objetivo %s usa registros enteros"
+
+#~ msgid "%s: ERROR: passes floats in integer registers whereas target %s uses float registers"
+#~ msgstr "%s: ERROR: pasan números de coma flotante en registros enteros mientras que el objetivo %s usa registros de coma flotante"
+
+#~ msgid "Warning: input file %s supports interworking, whereas %s does not."
+#~ msgstr "Aviso: el fichero de entrada %s admite interoperabilidad, mientras que %s no."
+
+#~ msgid "Warning: input file %s does not support interworking, whereas %s does."
+#~ msgstr "Aviso: el fichero de entrada %s no admite interoperabilidad, mientras que %s sí."
+
+# FIXME: Revisar en el código si son abreviaturas comunes, o corresponden a
+# partes fijas dentro del programa. cfuga
+#~ msgid "AUX tagndx %ld ttlsiz 0x%lx lnnos %ld next %ld"
+#~ msgstr "AUX tagndx %ld ttlsiz 0x%lx lnnos %ld next %ld"
+
+#~ msgid "elf_symbol_from_bfd_symbol 0x%.8lx, name = %s, sym num = %d, flags = 0x%.8lx%s\n"
+#~ msgstr "elf_symbol_from_bfd_symbol 0x%.8lx, nombre = %s, núm sim = %d, opciones = 0x%.8lx%s\n"
+
+#~ msgid "Warning: Not setting interwork flag of %s since it has already been specified as non-interworking"
+#~ msgstr "Aviso: No se activa la opción de interoperación de %s ya que se había especificado como no interoperable"
+
+#~ msgid "Warning: Clearing the interwork flag of %s due to outside request"
+#~ msgstr "Aviso: Se limpia la opción de interoperación de %s debido a una petición externa"
+
+#~ msgid " [APCS-26]"
+#~ msgstr " [APCS-26]"
+
+#~ msgid " [APCS-32]"
+#~ msgstr " [APCS-32]"
+
+#~ msgid "(unknown)"
+#~ msgstr "(desconocido)"
+
+#~ msgid " previously %s in %s"
+#~ msgstr " previamente %s en %s"
+
+#~ msgid "Symbol `%s' has differing types: %s in %s"
+#~ msgstr "El símbolo `%s' tiene tipos diferentes: %s en %s"
+
+#~ msgid "ETIR_S_C_STO_GBL: no symbol \"%s\""
+#~ msgstr "ETIR_S_C_STO_GBL: no está el símbolo \"%s\""
+
+#~ msgid "ETIR_S_C_STO_CA: no symbol \"%s\""
+#~ msgstr "ETIR_S_C_STO_CA: no está el símbolo \"%s\""
+
+#~ msgid "ETIR_S_C_STO_RB/AB: Not supported"
+#~ msgstr "ETIR_S_C_STO_RB/AB: No se admite"
+
+#~ msgid "ETIR_S_C_STO_LP_PSB: Not supported"
+#~ msgstr "ETIR_S_C_STO_LP_PSB: No se admite"
+
+#~ msgid "ETIR_S_C_OPR_INSV: Not supported"
+#~ msgstr "ETIR_S_C_OPR_INSV: No se admite"
+
+#~ msgid "ETIR_S_C_OPR_USH: Not supported"
+#~ msgstr "ETIR_S_C_OPR_USH: No se admite"
+
+#~ msgid "ETIR_S_C_OPR_ROT: Not supported"
+#~ msgstr "ETIR_S_C_OPR_ROT: No se admite"
+
+#~ msgid "ETIR_S_C_OPR_REDEF: Not supported"
+#~ msgstr "ETIR_S_C_OPR_REDEF: No se admite"
+
+#~ msgid "ETIR_S_C_OPR_DFLIT: Not supported"
+#~ msgstr "ETIR_S_C_OPR_DFLIT: No se admite"
+
+#~ msgid "ETIR_S_C_STC_LP: not supported"
+#~ msgstr "ETIR_S_C_STC_LP: no se admite"
+
+#~ msgid "ETIR_S_C_STC_GBL: not supported"
+#~ msgstr "ETIR_S_C_STC_GBL: no se admite"
+
+#~ msgid "ETIR_S_C_STC_GCA: not supported"
+#~ msgstr "ETIR_S_C_STC_GCA: no se admite"
+
+#~ msgid "ETIR_S_C_STC_PS: not supported"
+#~ msgstr "ETIR_S_C_STC_PS: no se admite"
+
+#~ msgid "Unimplemented STO cmd %d"
+#~ msgstr "Orden STO %d sin implementar"
+
+#~ msgid "TIR_S_C_OPR_ASH incomplete"
+#~ msgstr "TIR_S_C_OPR_ASH incompleto"
+
+#~ msgid "TIR_S_C_OPR_USH incomplete"
+#~ msgstr "TIR_S_C_OPR_USH incompleto"
+
+#~ msgid "TIR_S_C_OPR_ROT incomplete"
+#~ msgstr "TIR_S_C_OPR_ROT incompleto"
+
+#~ msgid "TIR_S_C_OPR_REDEF not supported"
+#~ msgstr "TIR_S_C_OPR_REDEF no se admite"
+
+#~ msgid "TIR_S_C_CTL_DFLOC not fully implemented"
+#~ msgstr "TIR_S_C_CTL_DFLOC no está completamente implementado"
+
+#~ msgid "TIR_S_C_CTL_STLOC not fully implemented"
+#~ msgstr "TIR_S_C_CTL_STLOC no está completamente implementado"
+
+#~ msgid "TIR_S_C_CTL_STKDL not fully implemented"
+#~ msgstr "TIR_S_C_CTL_STKDL no está completamente implementado"
+
+#~ msgid " vma: Hint Time Forward DLL First\n"
+#~ msgstr " vma: Pista Tiempo Adelante DLL Primero\n"
+
+#~ msgid " \t\tAddress Address Handler Data Address Mask\n"
+#~ msgstr " \t\tDirección Dirección Manejador Datos Dirección Máscara\n"
+
+#~ msgid "integer"
+#~ msgstr "entero"
+
+# FIXME: Revisar el contexto en el código para confirmar esta traducción. cfuga
+#~ msgid "soft"
+#~ msgstr "suave"
+
+#~ msgid "hard"
+#~ msgstr "duro"
+
+#~ msgid "Warning: %s %s interworking, whereas %s %s"
+#~ msgstr "Aviso: %s %s interoperatibilidad, mientras que %s %s"
+
+#~ msgid "supports"
+#~ msgstr "admite"
+
+#~ msgid "does not"
+#~ msgstr "no"
+
+#~ msgid "%s(%s+0x%lx): cannot find stub entry %s"
+#~ msgstr "%s(%s+0x%lx): no se puede encontrar la entrada de cabo %s"
+
+#~ msgid "%s(%s+0x%lx): cannot relocate %s, recompile with -ffunction-sections"
+#~ msgstr "%s(%s+0x%lx): no se puede reubicar %s, recompile con -ffuncion-sections"
+
+#~ msgid "creating section symbol, name = %s, value = 0x%.8lx, index = %d, section = 0x%.8lx\n"
+#~ msgstr "se crea el símbolo de sección, nombre = %s, valor = 0x%.8lx, índice = %d, sección 0x%.8lx\n"
+
+#~ msgid " whereas segment starts at 0x%x"
+#~ msgstr " mientras que el segmento inicia en 0x%x"
diff --git a/bfd/po/fi.gmo b/bfd/po/fi.gmo
new file mode 100644
index 0000000..dd99738
--- /dev/null
+++ b/bfd/po/fi.gmo
Binary files differ
diff --git a/bfd/po/fi.po b/bfd/po/fi.po
new file mode 100644
index 0000000..7f2fa2c
--- /dev/null
+++ b/bfd/po/fi.po
@@ -0,0 +1,6918 @@
+# Finnish messages for bfd.
+# Copyright © 2007, 2009, 2010, 2011, 2012, 2014 Free Software Foundation, Inc.
+# This file is distributed under the same license as the binutils package.
+# Jorma Karvonen <karvonen.jorma@gmail.com>, 2007, 2009-2012, 2014.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: bfd 2.24.90\n"
+"Report-Msgid-Bugs-To: bug-binutils@gnu.org\n"
+"POT-Creation-Date: 2014-02-10 09:42+1030\n"
+"PO-Revision-Date: 2014-11-03 01:40+0200\n"
+"Last-Translator: Jorma Karvonen <karvonen.jorma@gmail.com>\n"
+"Language-Team: Finnish <translation-team-fi@lists.sourceforge.net>\n"
+"Language: fi\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"X-Generator: KBabel 1.11.2\n"
+
+#: aout-adobe.c:127
+msgid "%B: Unknown section type in a.out.adobe file: %x\n"
+msgstr "%B: Tuntematon lohkotyyppi â€a.out.adobeâ€-tiedostossa: %x\n"
+
+#: aout-cris.c:200
+#, c-format
+msgid "%s: Invalid relocation type exported: %d"
+msgstr "%s: Virheellinen sijoitustyyppi viety: %d"
+
+#: aout-cris.c:243
+msgid "%B: Invalid relocation type imported: %d"
+msgstr "%B: Virheellinen sijoitustyyppi tuotu: %d"
+
+#: aout-cris.c:254
+msgid "%B: Bad relocation record imported: %d"
+msgstr "%B: Väärä sijoitustietue tuotu: %d"
+
+#: aoutx.h:1273 aoutx.h:1611
+#, c-format
+msgid "%s: can not represent section `%s' in a.out object file format"
+msgstr "%s: ei voi edustaa lohkoa ’%s’ â€a.outâ€-objektitiedostomuodossa"
+
+#: aoutx.h:1577
+#, c-format
+msgid "%s: can not represent section for symbol `%s' in a.out object file format"
+msgstr "%s: ei voi edustaa lohkoa symbolille ’%s’ â€a.outâ€-objektitiedostomuodossa"
+
+#: aoutx.h:1579 vms-alpha.c:7564
+msgid "*unknown*"
+msgstr "*tuntematon*"
+
+#: aoutx.h:4018 aoutx.h:4344
+msgid "%P: %B: unexpected relocation type\n"
+msgstr "%P: %B: odottamaton sijoitustyyppi\n"
+
+#: aoutx.h:5375
+#, c-format
+msgid "%s: relocatable link from %s to %s not supported"
+msgstr "%s: sijoitettava linkki kohteesta %s kohteeseen %s ei ole tuettu"
+
+#: archive.c:2249
+msgid "Warning: writing archive was slow: rewriting timestamp\n"
+msgstr "Varoitus: arkiston kirjoitus oli hidasta: aikaleiman uudelleenkirjoitus\n"
+
+#: archive.c:2549
+msgid "Reading archive file mod timestamp"
+msgstr "Luetaan arkistotiedoston muokkausaikaleima"
+
+# Intel coff armap
+#: archive.c:2573
+msgid "Writing updated armap timestamp"
+msgstr "Kirjoitetaan päivitetty â€armapâ€-aikaleima"
+
+#: bfd.c:411
+msgid "No error"
+msgstr "Ei virhettä"
+
+#: bfd.c:412
+msgid "System call error"
+msgstr "Järjestelmäkutsuvirhe"
+
+#: bfd.c:413
+msgid "Invalid bfd target"
+msgstr "Virheellinen bfd-kohde"
+
+#: bfd.c:414
+msgid "File in wrong format"
+msgstr "Tiedosto väärässä muodossa"
+
+#: bfd.c:415
+msgid "Archive object file in wrong format"
+msgstr "Arkisto-objektitiedosto väärässä muodossa"
+
+#: bfd.c:416
+msgid "Invalid operation"
+msgstr "Virheellinen toiminta"
+
+#: bfd.c:417
+msgid "Memory exhausted"
+msgstr "Muisti loppunut"
+
+#: bfd.c:418
+msgid "No symbols"
+msgstr "Ei symboleja"
+
+#: bfd.c:419
+msgid "Archive has no index; run ranlib to add one"
+msgstr "Arkistossa ei ole hakemistoa; lisää sellainen suorittamalla ranlib"
+
+#: bfd.c:420
+msgid "No more archived files"
+msgstr "Ei enää arkistoituja tiedostoja"
+
+#: bfd.c:421
+msgid "Malformed archive"
+msgstr "Muodoltaan virheellinen arkisto"
+
+#: bfd.c:422
+msgid "DSO missing from command line"
+msgstr "DSO puuttuu komentoriviltä"
+
+#: bfd.c:423
+msgid "File format not recognized"
+msgstr "Tiedostomuotoa ei tunnistettu"
+
+#: bfd.c:424
+msgid "File format is ambiguous"
+msgstr "Tiedostomuoto ei ole yksiselitteinen"
+
+#: bfd.c:425
+msgid "Section has no contents"
+msgstr "Lohkossa ei ole sisältöä"
+
+#: bfd.c:426
+msgid "Nonrepresentable section on output"
+msgstr "Ei-edustava lohko tulosteessa"
+
+#: bfd.c:427
+msgid "Symbol needs debug section which does not exist"
+msgstr "Symboli tarvitsee vianjäljityslohkon, jota ei ole"
+
+#: bfd.c:428
+msgid "Bad value"
+msgstr "Väärä arvo"
+
+#: bfd.c:429
+msgid "File truncated"
+msgstr "Tiedosto typistetty"
+
+#: bfd.c:430
+msgid "File too big"
+msgstr "Tiedosto on liian iso"
+
+#: bfd.c:431
+#, c-format
+msgid "Error reading %s: %s"
+msgstr "Virhe luettaessa %s: %s"
+
+#: bfd.c:432
+msgid "#<Invalid error code>"
+msgstr "#<Virheellinen virhekoodi>"
+
+#: bfd.c:1046
+#, c-format
+msgid "BFD %s assertion fail %s:%d"
+msgstr "BFD %s suoritusehto epäonnistui %s:%d"
+
+#: bfd.c:1058
+#, c-format
+msgid "BFD %s internal error, aborting at %s line %d in %s\n"
+msgstr "BFD %s sisäinen virhe, keskeytetään tiedostossa %s rivillä %d funktiossa %s\n"
+
+#: bfd.c:1062
+#, c-format
+msgid "BFD %s internal error, aborting at %s line %d\n"
+msgstr "BFD %s sisäinen virhe, keskeytetään tiedostossa %s rivillä %d\n"
+
+#: bfd.c:1064
+msgid "Please report this bug.\n"
+msgstr "Ilmoita tästä virheestä.\n"
+
+#: bfdwin.c:206
+#, c-format
+msgid "not mapping: data=%lx mapped=%d\n"
+msgstr "ei kuvausta: data=%lx kuvattu=%d\n"
+
+# Ilmeisesti debug_windows-ympäristömuuttuja
+#: bfdwin.c:209
+#, c-format
+msgid "not mapping: env var not set\n"
+msgstr "ei kuvausta: ympäristömuuttuja ei ole asetettu\n"
+
+#: binary.c:271
+#, c-format
+msgid "Warning: Writing section `%s' to huge (ie negative) file offset 0x%lx."
+msgstr "Varoitus: Kirjoitetaan lohko â€%s†valtavaan (ts. negatiiviseen) tiedostosiirrososoitteeseen 0x%lx."
+
+#: bout.c:1146 elf-m10300.c:2665 elf32-avr.c:1706 elf32-frv.c:5641
+#: elf64-ia64-vms.c:354 elfxx-sparc.c:2869 reloc.c:7324 reloc16.c:160
+#: elf32-ia64.c:351 elf64-ia64.c:351
+msgid "%P%F: --relax and -r may not be used together\n"
+msgstr "%P%F: valitsimia --relax ja -r ei saa käyttää yhdessä\n"
+
+#: cache.c:253
+msgid "reopening %B: %s\n"
+msgstr "avataan uudelleen %B: %s\n"
+
+#: coff-alpha.c:452
+msgid ""
+"%B: Cannot handle compressed Alpha binaries.\n"
+" Use compiler flags, or objZ, to generate uncompressed binaries."
+msgstr ""
+"%B: Ei voi käsitellä tiivistettyjä Alpha-binaareja.\n"
+" Käytä kääntäjälippuja, tai objZ:aa, tiivistämättömien binaarien tuottamiseksi."
+
+#: coff-alpha.c:603
+msgid "%B: unknown/unsupported relocation type %d"
+msgstr "%B: tuntematon/ei-tuettu sijoitustyyppi %d"
+
+#: coff-alpha.c:852 coff-alpha.c:889 coff-alpha.c:1973 coff-mips.c:946
+msgid "GP relative relocation used when GP not defined"
+msgstr "Yleisosoitinsuhteellista sijoitusta käytetty kun yleisosoitinta ei ole määritelty"
+
+#: coff-alpha.c:1450
+msgid "using multiple gp values"
+msgstr "käytetään useita yleisosoitinarvoja"
+
+#: coff-alpha.c:1509
+msgid "%B: unsupported relocation: ALPHA_R_GPRELHIGH"
+msgstr "%B: ei-tuettu sijoitus: ALPHA_R_GPRELHIGH"
+
+#: coff-alpha.c:1516
+msgid "%B: unsupported relocation: ALPHA_R_GPRELLOW"
+msgstr "%B: ei-tuettu sijoitus: ALPHA_R_GPRELLOW"
+
+#: coff-alpha.c:1523 elf32-m32r.c:2443 elf64-alpha.c:4083 elf64-alpha.c:4233
+#: elf64-ia64-vms.c:3429 elf32-ia64.c:3836 elf64-ia64.c:3836
+msgid "%B: unknown relocation type %d"
+msgstr "%B: tuntematon sijoitustyyppi %d"
+
+#: coff-arm.c:1034
+#, c-format
+msgid "%B: unable to find THUMB glue '%s' for `%s'"
+msgstr "%B: ei löydetty THUMB-vihjettä â€%s†nimelle â€%sâ€"
+
+#: coff-arm.c:1063
+#, c-format
+msgid "%B: unable to find ARM glue '%s' for `%s'"
+msgstr "%B: ei löydetty ARM-vihjettä â€%s†nimelle â€%sâ€"
+
+#: coff-arm.c:1365 elf32-arm.c:7141
+#, c-format
+msgid ""
+"%B(%s): warning: interworking not enabled.\n"
+" first occurrence: %B: arm call to thumb"
+msgstr ""
+"%B(%s): varoitus: yhteistoimivuus vanhan koodin kanssa ei ole käytössä.\n"
+" ensimmäinen esiintymä: %B: â€armâ€-kutsu thumb-koodiin"
+
+#: coff-arm.c:1455
+#, c-format
+msgid ""
+"%B(%s): warning: interworking not enabled.\n"
+" first occurrence: %B: thumb call to arm\n"
+" consider relinking with --support-old-code enabled"
+msgstr ""
+"%B(%s): varoitus: yhteistoimivuus vanhan koodin kanssa ei ole käytössä.\n"
+" ensimmäinen esiintymä: %B: thumb-kutsu arm-koodiin\n"
+" harkitse uudelleenlinkitystä --support-old-code aktivoituna"
+
+#: coff-arm.c:1750 coff-tic80.c:673 cofflink.c:3168
+msgid "%B: bad reloc address 0x%lx in section `%A'"
+msgstr "%B: virheellinen reloc-tietueosoite 0x%lx lohkossa â€%Aâ€"
+
+#: coff-arm.c:2075
+msgid "%B: illegal symbol index in reloc: %d"
+msgstr "%B: virheellinen symboli-indeksi reloc-tietueessa: %d"
+
+#: coff-arm.c:2206
+#, c-format
+msgid "error: %B is compiled for APCS-%d, whereas %B is compiled for APCS-%d"
+msgstr "virhe: %B on käännetty APCS-%d:lle, kun taas %B on käännetty APCS-%d:lle"
+
+#: coff-arm.c:2222 elf32-arm.c:16123
+#, c-format
+msgid "error: %B passes floats in float registers, whereas %B passes them in integer registers"
+msgstr "virhe: %B välittää float-liukuluvut liukulukurekistereissa, kun taas %B välittää ne kokonaislukurekistereissa"
+
+#: coff-arm.c:2225 elf32-arm.c:16127
+#, c-format
+msgid "error: %B passes floats in integer registers, whereas %B passes them in float registers"
+msgstr "virhe: %B välittää float-liukuluvut kokonaislukurekistereissa, kun taas %B välittää ne float-liukulukurekistereissa"
+
+#: coff-arm.c:2239
+#, c-format
+msgid "error: %B is compiled as position independent code, whereas target %B is absolute position"
+msgstr "virhe: %B käännetään paikkariippumattomana koodina, kun taas kohde %B on absoluuttipaikkainen"
+
+#: coff-arm.c:2242
+#, c-format
+msgid "error: %B is compiled as absolute position code, whereas target %B is position independent"
+msgstr "virhe: %B käännetään absoluuttisella paikkakoodilla, kun taas kohde %B on paikkariippumaton"
+
+#: coff-arm.c:2270 elf32-arm.c:16192
+#, c-format
+msgid "Warning: %B supports interworking, whereas %B does not"
+msgstr "Varoitus: %B tukee yhteistoimivuutta vanhan koodin kanssa, kun taas %B ei tue"
+
+#: coff-arm.c:2273 elf32-arm.c:16198
+#, c-format
+msgid "Warning: %B does not support interworking, whereas %B does"
+msgstr "Varoitus: %B ei tue yhteistoimivuutta vanhan koodin kanssa, kun taas %B tukee"
+
+#: coff-arm.c:2297
+#, c-format
+msgid "private flags = %x:"
+msgstr "yksityiset liput = %x:"
+
+#: coff-arm.c:2305 elf32-arm.c:12119
+#, c-format
+msgid " [floats passed in float registers]"
+msgstr " [liukuluvut välitetty liukulukurekistereissä]"
+
+#: coff-arm.c:2307
+#, c-format
+msgid " [floats passed in integer registers]"
+msgstr " [liukuluvut välitetty kokonaislukurekistereissä]"
+
+#: coff-arm.c:2310 elf32-arm.c:12122
+#, c-format
+msgid " [position independent]"
+msgstr " [paikkariippumaton]"
+
+#: coff-arm.c:2312
+#, c-format
+msgid " [absolute position]"
+msgstr " [absoluuttinen paikka]"
+
+#: coff-arm.c:2316
+#, c-format
+msgid " [interworking flag not initialised]"
+msgstr " [vanhan koodin kanssa toimimisen yhteistoimivuulippua ei ole alustettu]"
+
+#: coff-arm.c:2318
+#, c-format
+msgid " [interworking supported]"
+msgstr " [yhteistoimivuutta vanhan koodin kanssa tuettu]"
+
+#: coff-arm.c:2320
+#, c-format
+msgid " [interworking not supported]"
+msgstr " [yhteistoimivuutta vanhan koodin kanssa ei tueta]"
+
+#: coff-arm.c:2366 elf32-arm.c:11104
+#, c-format
+msgid "Warning: Not setting interworking flag of %B since it has already been specified as non-interworking"
+msgstr "Varoitus: Ei aseteta %B:n lippua yhteistoimivuudesta vanhan koodin kanssa koska se on jo määritelty ei-yhteistoimivuuskohteena"
+
+#: coff-arm.c:2370 elf32-arm.c:11108
+#, c-format
+msgid "Warning: Clearing the interworking flag of %B due to outside request"
+msgstr "Varoitus: %B:n yhteistoimivuuslipun nollaus johtuu ulkopuolisesta pyynnöstä"
+
+#: coff-h8300.c:1096
+#, c-format
+msgid "cannot handle R_MEM_INDIRECT reloc when using %s output"
+msgstr "ei voi käsitellä â€R_MEM_INDIRECT relocâ€-tietuetta kun käytetään %s tulostetta"
+
+#: coff-i860.c:147
+#, c-format
+msgid "relocation `%s' not yet implemented"
+msgstr "sijoitusta â€%s†ei ole vielä toteutettu"
+
+#: coff-i860.c:605 coff-tic54x.c:365 coffcode.h:5209
+msgid "%B: warning: illegal symbol index %ld in relocs"
+msgstr "%B: varoitus: virheellinen symboli-indeksi %ld relocs-tietueissa"
+
+#: coff-i960.c:124 coff-i960.c:480
+msgid "uncertain calling convention for non-COFF symbol"
+msgstr "epävarma kutsukäytäntö ei-COFF-symbolille"
+
+#: coff-m68k.c:484 elf32-bfin.c:5556 elf32-cr16.c:2853 elf32-m68k.c:4632
+msgid "unsupported reloc type"
+msgstr "ei-tuettu reloc-tyyppi"
+
+#: coff-mips.c:636 elf32-mips.c:1637 elf32-score.c:431 elf32-score7.c:330
+#: elf64-mips.c:2925 elfn32-mips.c:2737
+msgid "GP relative relocation when _gp not defined"
+msgstr "Yleisosoitinsuhteellinen sijoitus kun â€_gp†ei ole määritelty"
+
+#: coff-or32.c:216
+msgid "Unrecognized reloc"
+msgstr "Tunnistamaton reloc-tietue"
+
+#: coff-rs6000.c:2802
+#, c-format
+msgid "%s: unsupported relocation type 0x%02x"
+msgstr "%s: ei-tuettu sijoitustyyppi 0x%02x"
+
+#: coff-rs6000.c:2887
+#, c-format
+msgid "%s: TOC reloc at 0x%x to symbol `%s' with no TOC entry"
+msgstr "%s: â€Sisältöluettelo-relocâ€-tietue osoitteessa 0x%x symboliin â€%s†ilman sisältöluettelotulokohtaa"
+
+#: coff-rs6000.c:3638 coff64-rs6000.c:2117
+msgid "%B: symbol `%s' has unrecognized smclas %d"
+msgstr "%B: symbolissa â€%s†on tunnistamaton â€smclasâ€-arvo %d"
+
+#: coff-sh.c:506
+#, c-format
+msgid "SH Error: unknown reloc type %d"
+msgstr "SH-virhe: tuntematon sijoitustyyppi %d"
+
+#: coff-tic4x.c:184 coff-tic54x.c:279 coff-tic80.c:440
+#, c-format
+msgid "Unrecognized reloc type 0x%x"
+msgstr "Tunnistamaton reloc-tyyppi 0x%x"
+
+#: coff-tic4x.c:227
+#, c-format
+msgid "%s: warning: illegal symbol index %ld in relocs"
+msgstr "%s: varoitus: virheellinen symboli-indeksi %ld relocs-tietueissa"
+
+#: coff-w65.c:355
+#, c-format
+msgid "ignoring reloc %s\n"
+msgstr "ei oteta huomioon reloc-tietuetta %s\n"
+
+# C++-kielessä on monia tilanteita, joissa kääntäjän on lähetettävä koodia tai dataa,
+# mutta se ei kykenen tunnistamaan uniikkia käännösyksikköä, mihin se tulisi lähettää.
+# C++ ABI-ryhmä on pyrkinyt ratkaisemaan tämän pulman sallimalla kääntäjän lähettää vaaditut
+# tiedot useisiin käännösyksiköihin, mikä sallii linkkerin poistaa kaikki muuta paitsi yhden
+# kopion. Tätä ominaisuutta kutsutaan useissa olemassa olevissa toteutuksissa nimellä COMDAT.
+#: coffcode.h:1005
+msgid "%B: warning: COMDAT symbol '%s' does not match section name '%s'"
+msgstr "%B: varoitus: COMDAT-symboli â€%s†ei täsmää lohkonimen â€%s†kanssa"
+
+#. Generate a warning message rather using the 'unhandled'
+#. variable as this will allow some .sys files generate by
+#. other toolchains to be processed. See bugzilla issue 196.
+#: coffcode.h:1230
+msgid "%B: Warning: Ignoring section flag IMAGE_SCN_MEM_NOT_PAGED in section %s"
+msgstr "%B: Varoitus: Ei oteta huomioon lohkolippua IMAGE_SCN_MEM_NOT_PAGED lohkossa %s"
+
+#: coffcode.h:1297
+msgid "%B (%s): Section flag %s (0x%x) ignored"
+msgstr "%B (%s): Lohkolippua %s (0x%x) ei oteta huomioon"
+
+# TI tarkoittaa luultavasti Texas Instruments
+#: coffcode.h:2439
+#, c-format
+msgid "Unrecognized TI COFF target id '0x%x'"
+msgstr "Tunnistamaton â€TI COFFâ€-kohdetunniste â€0x%xâ€"
+
+#: coffcode.h:2753
+msgid "%B: reloc against a non-existant symbol index: %ld"
+msgstr "%B: reloc-tietue käyttäen ei-olemassaolevaa symboli-indeksiä: %ld"
+
+#: coffcode.h:3311
+msgid "%B: too many sections (%d)"
+msgstr "%B: liian monia lohkoja (%d)"
+
+#: coffcode.h:3729
+msgid "%B: section %s: string table overflow at offset %ld"
+msgstr "%B: lohko %s: merkkijonotaulun ylitys siirrososoitteessa %ld"
+
+#: coffcode.h:4534
+msgid "%B: warning: line number table read failed"
+msgstr "%B: varoitus: rivinumerotaulun lukeminen ei onnistunut"
+
+#: coffcode.h:4564
+msgid "%B: warning: illegal symbol index %ld in line numbers"
+msgstr "%B: varoitus: virheellinen symboli-indeksi %ld rivinumeroissa"
+
+#: coffcode.h:4578
+msgid "%B: warning: duplicate line number information for `%s'"
+msgstr "%B: varoitus: rivinumerojen kaksoiskappaleita symbolille â€%sâ€"
+
+#: coffcode.h:4978
+msgid "%B: Unrecognized storage class %d for %s symbol `%s'"
+msgstr "%B: Tunnistamaton tallennusluokka: %d lohkonimi: %s symbolinimi: â€%sâ€"
+
+#: coffcode.h:5104
+msgid "warning: %B: local symbol `%s' has no section"
+msgstr "varoitus: %B: paikallisessa symbolissa â€%s†ei ole lohkoa"
+
+#: coffcode.h:5248
+msgid "%B: illegal relocation type %d at address 0x%lx"
+msgstr "%B: virheellinen sijoitustyyppi %d osoitteessa 0x%lx"
+
+#: coffgen.c:179 elf.c:1030
+msgid "%B: unable to initialize compress status for section %s"
+msgstr "%B: ei kyetä alustamaan tiivistystilaa lohkolle %s"
+
+#: coffgen.c:199 elf.c:1050
+msgid "%B: unable to initialize decompress status for section %s"
+msgstr "%B: ei kyetä alustamaan tiivistyksenpurkutilaa lohkolle %s"
+
+#: coffgen.c:1685
+msgid "%B: bad string table size %lu"
+msgstr "%B: virheellinen merkkijonotaulukoko %lu"
+
+#: coffgen.c:2608 elflink.c:12906 linker.c:3136
+msgid "%F%P: already_linked_table: %E\n"
+msgstr "%F%P: already_linked_table: %E\n"
+
+# Epäilen, että lähdekoodissa on virhe: tyypit ovat kaksi viimeistä parametriä.
+#: cofflink.c:533 elf64-ia64-vms.c:5173 elflink.c:4356
+msgid "Warning: type of symbol `%s' changed from %d to %d in %B"
+msgstr "Varoitus: symbolityyppi â€%s†vaihtui tyypistä %d tyyppiin %d kohteessa %B"
+
+#: cofflink.c:2416
+msgid "%B: relocs in section `%A', but it has no contents"
+msgstr "%B: relocs-tietueet lohkossa â€%Aâ€, mutta ilman sisältöä"
+
+#: cofflink.c:2478 elflink.c:9711
+msgid "%X`%s' referenced in section `%A' of %B: defined in discarded section `%A' of %B\n"
+msgstr "%Xâ€%s†viitattu lohkossa â€%A†kohteessa %B: määritelty hylätyssä lohkossa â€%A†/ %B\n"
+
+#: cofflink.c:2777 coffswap.h:826
+#, c-format
+msgid "%s: %s: reloc overflow: 0x%lx > 0xffff"
+msgstr "%s: %s: reloc-tietueylivuoto: 0x%lx > 0xffff"
+
+#: cofflink.c:2786 coffswap.h:812
+#, c-format
+msgid "%s: warning: %s: line number overflow: 0x%lx > 0xffff"
+msgstr "%s: varoitus: %s: rivinumeroylivuoto: 0x%lx > 0xffff"
+
+#: cpu-arm.c:190 cpu-arm.c:201
+msgid "error: %B is compiled for the EP9312, whereas %B is compiled for XScale"
+msgstr "virhe: %B on käännetty EP9312:lle, kun taas %B on käännetty XScalelle"
+
+#: cpu-arm.c:334
+#, c-format
+msgid "warning: unable to update contents of %s section in %s"
+msgstr "varoitus: ei voi päivittää %s-lohkon sisältöä kohteessa %s"
+
+#: dwarf2.c:514
+#, c-format
+msgid "Dwarf Error: Can't find %s section."
+msgstr "Dwarf-virhe: Ei löydy %s-lohkoa."
+
+#: dwarf2.c:543
+#, c-format
+msgid "Dwarf Error: Offset (%lu) greater than or equal to %s size (%lu)."
+msgstr "Dwarf-virhe: Siirrososoite (%lu) suurempi tai yhtäsuuri kuin %s-koko (%lu)."
+
+#: dwarf2.c:1071
+#, c-format
+msgid "Dwarf Error: Invalid or unhandled FORM value: %#x."
+msgstr "Dwarf-virhe: Virheellinen tai käsittelemätön FORM-arvo: %#x."
+
+#: dwarf2.c:1332
+msgid "Dwarf Error: mangled line number section (bad file number)."
+msgstr "Dwarf-virhe: runneltu rivinumerolohko (virheellinen tiedostonumero)."
+
+#: dwarf2.c:1590
+#, c-format
+msgid "Dwarf Error: Unhandled .debug_line version %d."
+msgstr "Dwarf-virhe: Käsittelemätön â€.debug_lineâ€-versio %d."
+
+#: dwarf2.c:1612
+msgid "Dwarf Error: Invalid maximum operations per instruction."
+msgstr "Dwarf-virhe: Virheellinen toimintojen enimmäismäärä per käsky."
+
+#: dwarf2.c:1807
+msgid "Dwarf Error: mangled line number section."
+msgstr "Dwarf-virhe: runneltu rivinumerolohko."
+
+#: dwarf2.c:2160
+#, c-format
+msgid "Dwarf Error: Unable to read alt ref %u."
+msgstr "Dwarf-virhe: Kohteen alt ref %u lukeminen epäonnistui."
+
+#: dwarf2.c:2179 dwarf2.c:2299 dwarf2.c:2595
+#, c-format
+msgid "Dwarf Error: Could not find abbrev number %u."
+msgstr "Dwarf-virhe: Ei löytynyt lyhennenumeroa %u."
+
+#: dwarf2.c:2551
+#, c-format
+msgid "Dwarf Error: found dwarf version '%u', this reader only handles version 2, 3 and 4 information."
+msgstr "Dwarf-virhe: löytyi dwarf-versio ’%u’, tämä lukija käsittelee vain version 2, 3 ja 4 tietoja."
+
+#: dwarf2.c:2560
+#, c-format
+msgid "Dwarf Error: found address size '%u', this reader can not handle sizes greater than '%u'."
+msgstr "Dwarf-virhe: löytyi osoitekoko ’%u’, tämä lukija ei voi käsitellä kokoja, jotka ovat suurempia kuin ’%u’."
+
+#: dwarf2.c:2586
+#, c-format
+msgid "Dwarf Error: Bad abbrev number: %u."
+msgstr "Dwarf-virhe: Väärä lyhennenumero: %u."
+
+#: ecoff.c:1233
+#, c-format
+msgid "Unknown basic type %d"
+msgstr "Tuntematon perustyyppi %d"
+
+#: ecoff.c:1490
+#, c-format
+msgid ""
+"\n"
+" End+1 symbol: %ld"
+msgstr ""
+"\n"
+" Loppu+1 symboli: %ld"
+
+#: ecoff.c:1497 ecoff.c:1500
+#, c-format
+msgid ""
+"\n"
+" First symbol: %ld"
+msgstr ""
+"\n"
+" Ensimmäinen symboli: %ld"
+
+#: ecoff.c:1512
+#, c-format
+msgid ""
+"\n"
+" End+1 symbol: %-7ld Type: %s"
+msgstr ""
+"\n"
+" Loppu+1 symboli: %-7ld Tyyppi: %s"
+
+#: ecoff.c:1519
+#, c-format
+msgid ""
+"\n"
+" Local symbol: %ld"
+msgstr ""
+"\n"
+" Paikallinen symboli: %ld"
+
+#: ecoff.c:1527
+#, c-format
+msgid ""
+"\n"
+" struct; End+1 symbol: %ld"
+msgstr ""
+"\n"
+" struct; Loppu+1 symboli: %ld"
+
+#: ecoff.c:1532
+#, c-format
+msgid ""
+"\n"
+" union; End+1 symbol: %ld"
+msgstr ""
+"\n"
+" union; Loppu+1 symboli: %ld"
+
+#: ecoff.c:1537
+#, c-format
+msgid ""
+"\n"
+" enum; End+1 symbol: %ld"
+msgstr ""
+"\n"
+" enum; Loppu+1 symboli: %ld"
+
+#: ecoff.c:1543
+#, c-format
+msgid ""
+"\n"
+" Type: %s"
+msgstr ""
+"\n"
+" Tyyppi: %s"
+
+#: elf-attrs.c:573
+msgid "error: %B: Object has vendor-specific contents that must be processed by the '%s' toolchain"
+msgstr "virhe: %B: Objektilla on toimittajakohtainen sisältö, joka on käsiteltävä ’%s’-työkaluketjulla"
+
+#: elf-attrs.c:582
+msgid "error: %B: Object tag '%d, %s' is incompatible with tag '%d, %s'"
+msgstr "virhe: %B: Objektitunniste ’%d, %s’ ei ole yhteensopiva tunnisteen ’%d, %s’ kanssa"
+
+#: elf-eh-frame.c:921
+msgid "%P: error in %B(%A); no .eh_frame_hdr table will be created.\n"
+msgstr "%P: virhe kohteessa %B(%A); â€.eh_frame_hdrâ€-taulua ei luotu.\n"
+
+#: elf-eh-frame.c:1193
+msgid "%P: fde encoding in %B(%A) prevents .eh_frame_hdr table being created.\n"
+msgstr "%P: fde-koodaus kohteessa %B(%A) estää â€.eh_frame_hdrâ€-taulun luomisen.\n"
+
+#: elf-eh-frame.c:1612
+msgid "%P: DW_EH_PE_datarel unspecified for this architecture.\n"
+msgstr "%P: DW_EH_PE_datarel määrittelemätön tälle arkkitehtuurille.\n"
+
+#: elf-ifunc.c:135
+msgid "%F%P: dynamic STT_GNU_IFUNC symbol `%s' with pointer equality in `%B' can not be used when making an executable; recompile with -fPIE and relink with -pie\n"
+msgstr "%F%P: dynaamista STT_GNU_IFUNC symbolia â€%s†osoitinyhtäläisyydellä kohteessa â€%B†ei voida käyttää tekemään suoritettavaa tiedostoa; käännä uudelleen valitsimella -fPIE ja linkitä uudelleen valitsemella -pie\n"
+
+#: elf-m10200.c:430 elf-m10300.c:2164 elf32-avr.c:1256 elf32-bfin.c:3220
+#: elf32-cr16.c:1484 elf32-cr16c.c:780 elf32-cris.c:2016 elf32-crx.c:922
+#: elf32-d10v.c:513 elf32-epiphany.c:557 elf32-fr30.c:589 elf32-frv.c:4039
+#: elf32-h8300.c:525 elf32-i860.c:1212 elf32-ip2k.c:1468 elf32-iq2000.c:688
+#: elf32-lm32.c:1160 elf32-m32c.c:553 elf32-m32r.c:3066 elf32-m68hc1x.c:1283
+#: elf32-mep.c:535 elf32-metag.c:1992 elf32-microblaze.c:1560
+#: elf32-moxie.c:282 elf32-mt.c:395 elf32-nds32.c:4910 elf32-openrisc.c:404
+#: elf32-score.c:2729 elf32-score7.c:2537 elf32-spu.c:5041
+#: elf32-tilepro.c:3666 elf32-v850.c:2281 elf32-xstormy16.c:936
+#: elf64-mmix.c:1538 elfxx-tilegx.c:4051
+msgid "internal error: out of range error"
+msgstr "sisäinen virhe: â€lukualueen ulkopuolellaâ€-virhe"
+
+#: elf-m10200.c:434 elf-m10300.c:2168 elf32-avr.c:1260 elf32-bfin.c:3224
+#: elf32-cr16.c:1488 elf32-cr16c.c:784 elf32-cris.c:2020 elf32-crx.c:926
+#: elf32-d10v.c:517 elf32-fr30.c:593 elf32-frv.c:4043 elf32-h8300.c:529
+#: elf32-i860.c:1216 elf32-iq2000.c:692 elf32-lm32.c:1164 elf32-m32c.c:557
+#: elf32-m32r.c:3070 elf32-m68hc1x.c:1287 elf32-mep.c:539 elf32-metag.c:1996
+#: elf32-microblaze.c:1564 elf32-moxie.c:286 elf32-msp430.c:1321
+#: elf32-nds32.c:4914 elf32-openrisc.c:408 elf32-score.c:2733
+#: elf32-score7.c:2541 elf32-spu.c:5045 elf32-tilepro.c:3670 elf32-v850.c:2285
+#: elf32-xstormy16.c:940 elf64-mmix.c:1542 elfxx-mips.c:9995
+#: elfxx-tilegx.c:4055
+msgid "internal error: unsupported relocation error"
+msgstr "sisäinen virhe: ei-tuettu sijoitusvirhe"
+
+#: elf-m10200.c:438 elf32-cr16.c:1492 elf32-cr16c.c:788 elf32-crx.c:930
+#: elf32-d10v.c:521 elf32-h8300.c:533 elf32-lm32.c:1168 elf32-m32r.c:3074
+#: elf32-m68hc1x.c:1291 elf32-microblaze.c:1568 elf32-nds32.c:4918
+#: elf32-score.c:2737 elf32-score7.c:2545 elf32-spu.c:5049
+msgid "internal error: dangerous error"
+msgstr "sisäinen virhe: vaarallinen virhe"
+
+#: elf-m10200.c:442 elf-m10300.c:2184 elf32-avr.c:1268 elf32-bfin.c:3232
+#: elf32-cr16.c:1496 elf32-cr16c.c:792 elf32-cris.c:2028 elf32-crx.c:934
+#: elf32-d10v.c:525 elf32-epiphany.c:572 elf32-fr30.c:601 elf32-frv.c:4051
+#: elf32-h8300.c:537 elf32-i860.c:1224 elf32-ip2k.c:1483 elf32-iq2000.c:700
+#: elf32-lm32.c:1172 elf32-m32c.c:565 elf32-m32r.c:3078 elf32-m68hc1x.c:1295
+#: elf32-mep.c:547 elf32-metag.c:2004 elf32-microblaze.c:1572
+#: elf32-moxie.c:294 elf32-msp430.c:1329 elf32-mt.c:403 elf32-nds32.c:4922
+#: elf32-openrisc.c:416 elf32-score.c:2746 elf32-score7.c:2549
+#: elf32-spu.c:5053 elf32-tilepro.c:3678 elf32-v850.c:2305
+#: elf32-xstormy16.c:948 elf64-mmix.c:1550 elfxx-tilegx.c:4063
+msgid "internal error: unknown error"
+msgstr "sisäinen virhe: tuntematon virhe"
+
+#: elf-m10300.c:1021
+#, c-format
+msgid "%s: Unsupported transition from %s to %s"
+msgstr "%s: Tukematon siirto kohteesta %s kohteeseen %s"
+
+#: elf-m10300.c:1213
+msgid "%B: %s' accessed both as normal and thread local symbol"
+msgstr "%B: %s’ haettu sekä normaalina että säikeisenä paikallissymbolina"
+
+#: elf-m10300.c:2108 elf32-arm.c:10632 elf32-i386.c:4363 elf32-m32r.c:2558
+#: elf32-m68k.c:4120 elf32-s390.c:3303 elf32-sh.c:4109 elf32-tilepro.c:3569
+#: elf32-xtensa.c:3063 elf64-s390.c:3229 elf64-sh64.c:1640 elf64-x86-64.c:4463
+#: elfxx-sparc.c:3904 elfxx-tilegx.c:3974
+#: /src/binutils-gdb/bfd/elfnn-aarch64.c:4450
+msgid "%B(%A+0x%lx): unresolvable %s relocation against symbol `%s'"
+msgstr "%B(%A+0x%lx): ratkaisematon %s-sijoitus käyttäen symbolia â€%sâ€"
+
+#: elf-m10300.c:2173
+msgid "error: inappropriate relocation type for shared library (did you forget -fpic?)"
+msgstr "virhe: sopimaton sijoitustyyppi jaetulle kirjastolle (unohtuiko -fpic?)"
+
+#: elf-m10300.c:2176
+msgid "%B: taking the address of protected function '%s' cannot be done when making a shared library"
+msgstr "%B: suojatun funktion ’%s’ osoitteen ottamista ei voida tehdä, kun tehdään jaettua kirjastoa"
+
+#: elf-m10300.c:2179
+msgid "internal error: suspicious relocation type used in shared library"
+msgstr "sisäinen virhe: epäilyttävää sijoitustyyppiä käytetään jaetussa kirjastossa"
+
+#: elf.c:343
+msgid "%B: invalid string offset %u >= %lu for section `%s'"
+msgstr "%B: virheellinen merkkijonosiirrososoite %u >= %lu lohkolle â€%sâ€"
+
+#: elf.c:455
+msgid "%B symbol number %lu references nonexistent SHT_SYMTAB_SHNDX section"
+msgstr "%B symbolinumero %lu viittaa puuttuvaan SHT_SYMTAB_SHNDX-lohkoon"
+
+#: elf.c:611
+msgid "%B: Corrupt size field in group section header: 0x%lx"
+msgstr "%B: Rikkinäinen kokokenttä ryhmälohko-otsakkeessa: 0x%lx"
+
+#: elf.c:647
+msgid "%B: invalid SHT_GROUP entry"
+msgstr "%B: virheellinen SHT_GROUP-tulokohta"
+
+#: elf.c:717
+msgid "%B: no group info for section %A"
+msgstr "%B: ei ryhmätietoja lohkolle %A"
+
+#: elf.c:746 elf.c:3144 elflink.c:10290
+msgid "%B: warning: sh_link not set for section `%A'"
+msgstr "%B: varoitus: sh_link-kenttää ei aseteta lohkolle â€%Aâ€"
+
+#: elf.c:765
+msgid "%B: sh_link [%d] in section `%A' is incorrect"
+msgstr "%B: sh_link [%d]-kenttä lohkossa â€%A†on virheellinen"
+
+#: elf.c:800
+msgid "%B: unknown [%d] section `%s' in group [%s]"
+msgstr "%B: tuntematon [%d] lohko â€%s†ryhmässä [%s]"
+
+#: elf.c:1174
+#, c-format
+msgid ""
+"\n"
+"Program Header:\n"
+msgstr ""
+"\n"
+"Ohjelmaotsake:\n"
+
+#: elf.c:1216
+#, c-format
+msgid ""
+"\n"
+"Dynamic Section:\n"
+msgstr ""
+"\n"
+"Dynaaminen lohko:\n"
+
+#: elf.c:1352
+#, c-format
+msgid ""
+"\n"
+"Version definitions:\n"
+msgstr ""
+"\n"
+"Versiomäärittelyt:\n"
+
+#: elf.c:1377
+#, c-format
+msgid ""
+"\n"
+"Version References:\n"
+msgstr ""
+"\n"
+"Versioviitteet:\n"
+
+#: elf.c:1382
+#, c-format
+msgid " required from %s:\n"
+msgstr " kysytty kohteesta %s:\n"
+
+#: elf.c:1807
+msgid "%B: invalid link %lu for reloc section %s (index %u)"
+msgstr "%B: virheellinen linkki %lu reloc-tietueelle %s (indeksi %u)"
+
+#: elf.c:1977
+msgid "%B: don't know how to handle allocated, application specific section `%s' [0x%8x]"
+msgstr "%B: ei tiedä kuinka käsitellä varattua, sovelluskohtaista lohkoa â€%s†[0x%8x]"
+
+#: elf.c:1989
+msgid "%B: don't know how to handle processor specific section `%s' [0x%8x]"
+msgstr "%B: ei tiedä, kuinka käsitellä prosessorikohtaista lohkoa â€%s†[0x%8x]"
+
+#: elf.c:2000
+msgid "%B: don't know how to handle OS specific section `%s' [0x%8x]"
+msgstr "%B: ei tiedä, kuinka käsitellä käyttöjärjestelmäkohtaista lohkoa â€%s†[0x%8x]"
+
+#: elf.c:2010
+msgid "%B: don't know how to handle section `%s' [0x%8x]"
+msgstr "%B: ei tiedä kuinka käsitellä lohkoa â€%s†[0x%8x]"
+
+#: elf.c:2648
+#, c-format
+msgid "warning: section `%A' type changed to PROGBITS"
+msgstr "varoitus: lohkon â€%A†tyyppi vaihtunut tyypiksi PROGBITS"
+
+#: elf.c:3015
+msgid "%B: too many sections: %u"
+msgstr "%B: liian monia lohkoja: %u"
+
+#: elf.c:3101
+msgid "%B: sh_link of section `%A' points to discarded section `%A' of `%B'"
+msgstr "%B: sh_link-lohko â€%A†osoittaa hylättyyn lohkoon â€%A†kohteessa â€%Bâ€"
+
+#: elf.c:3124
+msgid "%B: sh_link of section `%A' points to removed section `%A' of `%B'"
+msgstr "%B: sh_link-lohko â€%A†osoittaa poistettuun lohkoon â€%A†kohteessa â€%Bâ€"
+
+#: elf.c:4126
+msgid "%B: TLS sections are not adjacent:"
+msgstr "%B: TLS-lohkot eivät ole vierekkäisiä:"
+
+#: elf.c:4133
+#, c-format
+msgid "\t TLS: %A"
+msgstr "\t TLS: %A"
+
+#: elf.c:4137
+#, c-format
+msgid "\tnon-TLS: %A"
+msgstr "\tei-TLS: %A"
+
+#: elf.c:4596
+msgid "%B: The first section in the PT_DYNAMIC segment is not the .dynamic section"
+msgstr "%B: Ensimmäinen lohko PT_DYNAMIC-segmentissä ei ole â€.dynamicâ€-lohko"
+
+#: elf.c:4621
+msgid "%B: Not enough room for program headers, try linking with -N"
+msgstr "%B: Ei tarpeeksi tilaa ohjelmaotsakkeille, yritä linkittää â€-Nâ€-argumentilla"
+
+#: elf.c:4707
+msgid "%B: section %A lma %#lx adjusted to %#lx"
+msgstr "%B: lohko %A vma %#lx säädetty kohteeseen %#lx"
+
+#: elf.c:4843
+msgid "%B: section `%A' can't be allocated in segment %d"
+msgstr "%B: lohkoa â€%A†ei voida varata segmentissä %d"
+
+#: elf.c:4892
+msgid "%B: warning: allocated section `%s' not in segment"
+msgstr "%B: varoitus: varattu lohko â€%s†ei ole segmentissä"
+
+#: elf.c:5473
+msgid "%B: symbol `%s' required but not present"
+msgstr "%B: symboli â€%s†vaadittu, mutta ei ole annettu"
+
+#: elf.c:5811
+msgid "%B: warning: Empty loadable segment detected, is this intentional ?\n"
+msgstr "%B: varoitus: Tyhjä ladattava segmentti havaittu, onko tämä tarkoituksellinen ?\n"
+
+#: elf.c:6867
+#, c-format
+msgid "Unable to find equivalent output section for symbol '%s' from section '%s'"
+msgstr "Ei löydy samanlaista tulostelohkoa symbolille â€%s†lohkosta â€%sâ€"
+
+#: elf.c:7915
+msgid "%B: unsupported relocation type %s"
+msgstr "%B: ei-tuettu sijoitustyyppi %s"
+
+#: elf32-arm.c:3722 elf32-arm.c:7051
+msgid ""
+"%B(%s): warning: interworking not enabled.\n"
+" first occurrence: %B: Thumb call to ARM"
+msgstr ""
+"%B(%s): varoitus: yhteistoimivuus vanhan koodin kanssa ei ole käytössä.\n"
+" ensimmäinen esiintymä: %B: Thumb-kutsu ARM-koodiin"
+
+#: elf32-arm.c:3769
+msgid ""
+"%B(%s): warning: interworking not enabled.\n"
+" first occurrence: %B: ARM call to Thumb"
+msgstr ""
+"%B(%s): varoitus: yhteistoimivuus vanhan koodin kanssa ei ole käytössä.\n"
+" ensimmäinen esiintymä: %B: ARM-kutsu Thumb-koodiin"
+
+#: elf32-arm.c:3988 elf32-arm.c:5433
+#: /src/binutils-gdb/bfd/elfnn-aarch64.c:2324
+#, c-format
+msgid "%s: cannot create stub entry %s"
+msgstr "%s: ei voi luoda stub-tulokohtaa %s"
+
+#: elf32-arm.c:5549
+#, c-format
+msgid "unable to find THUMB glue '%s' for '%s'"
+msgstr "ei löydy THUMB-vihjettä â€%s†kohteelle â€%sâ€"
+
+#: elf32-arm.c:5585
+#, c-format
+msgid "unable to find ARM glue '%s' for '%s'"
+msgstr "ei löydy ARM-vihjettä â€%s†kohteelle â€%sâ€"
+
+#: elf32-arm.c:6123
+msgid "%B: BE8 images only valid in big-endian mode."
+msgstr "%B: BE8-vedokset ovat oikeita vain big-endian-tavujärjestyksessä."
+
+# Vector Floating Point (VFP)
+#. Give a warning, but do as the user requests anyway.
+#: elf32-arm.c:6353
+msgid "%B: warning: selected VFP11 erratum workaround is not necessary for target architecture"
+msgstr "%B: varoitus: valittu VFP11-virheenkiertotapa ei ole välttämätön kohdearkkitehtuurille"
+
+#: elf32-arm.c:6897 elf32-arm.c:6917
+msgid "%B: unable to find VFP11 veneer `%s'"
+msgstr "%B: ei löydy VFP11-julkisivua â€%sâ€"
+
+#: elf32-arm.c:6966
+#, c-format
+msgid "Invalid TARGET2 relocation type '%s'."
+msgstr "Virheellinen TARGET2-sijoitustyyppi â€%sâ€."
+
+#. PR ld/16017: Do not generate ARM instructions for
+#. the PLT if compiling for a thumb-only target.
+#.
+#. FIXME: We ought to be able to generate thumb PLT instructions...
+#: elf32-arm.c:7696
+msgid "%B: Warning: thumb mode PLT generation not currently supported"
+msgstr "%B: Varoitus: thumb-tila-PLT-tuottamista ei tällä hetkellä tueta"
+
+#: elf32-arm.c:7909
+msgid "%B(%A+0x%lx):unexpected Thumb instruction '0x%x' in TLS trampoline"
+msgstr "%B(%A+0x%lx):odottamaton Thumb-käsky ’0x%x’ TLS-trampoliinissa"
+
+#: elf32-arm.c:7948
+msgid "%B(%A+0x%lx):unexpected ARM instruction '0x%x' in TLS trampoline"
+msgstr "%B(%A+0x%lx):odottamaton ARM-käsky ’0x%x’ TLS-trampoliinissa"
+
+#: elf32-arm.c:8412
+msgid "\\%B: Warning: Arm BLX instruction targets Arm function '%s'."
+msgstr "\\%B: Varoitus: â€Arm BLXâ€-käskykohteet Arm-funktiossa â€%sâ€."
+
+#: elf32-arm.c:8831
+msgid "%B: Warning: Thumb BLX instruction targets thumb function '%s'."
+msgstr "%B: Varoitus: â€Thumb BLXâ€-käskykohteet thumb-funktiossa â€%sâ€."
+
+#: elf32-arm.c:9672
+msgid "%B(%A+0x%lx):unexpected Thumb instruction '0x%x' referenced by TLS_GOTDESC"
+msgstr "%B(%A+0x%lx):TLS_GOTDESC viittasi odottamattomaann Thumb-käskyyn ’0x%x’"
+
+#: elf32-arm.c:9695
+msgid "%B(%A+0x%lx):unexpected ARM instruction '0x%x' referenced by TLS_GOTDESC"
+msgstr "%B(%A+0x%lx):TLS_GOTDESC viittasi odottamattomaan ARM-käskyyn ’0x%x’"
+
+#: elf32-arm.c:9724
+msgid "%B(%A+0x%lx): R_ARM_TLS_LE32 relocation not permitted in shared object"
+msgstr "%B(%A+0x%lx): R_ARM_TLS_LE32-sijoitukset eivät ole sallittuja jaetuissa objekteissa"
+
+#: elf32-arm.c:9937
+msgid "%B(%A+0x%lx): Only ADD or SUB instructions are allowed for ALU group relocations"
+msgstr "%B(%A+0x%lx): Vain ADD- tai SUB-käskyt ovat sallittuja ALU-ryhmän sijoituksille"
+
+#: elf32-arm.c:9977 elf32-arm.c:10065 elf32-arm.c:10149 elf32-arm.c:10235
+msgid "%B(%A+0x%lx): Overflow whilst splitting 0x%lx for group relocation %s"
+msgstr "%B(%A+0x%lx): Ylivuoto, kun halkaistaan 0x%lx ryhmäsijoitukselle %s"
+
+#: elf32-arm.c:10474 elf32-sh.c:3994 elf64-sh64.c:1544
+msgid "%B(%A+0x%lx): %s relocation against SEC_MERGE section"
+msgstr "%B(%A+0x%lx): %s-sijoitus käyttäen SEC_MERGE-lohkoa"
+
+# TLS: transport layer security
+#: elf32-arm.c:10585 elf32-m68k.c:4155 elf32-xtensa.c:2799
+#: /src/binutils-gdb/bfd/elfnn-aarch64.c:4192
+msgid "%B(%A+0x%lx): %s used with TLS symbol %s"
+msgstr "%B(%A+0x%lx): %s käytetään TLS-symbolin %s kanssa"
+
+#: elf32-arm.c:10586 elf32-m68k.c:4156 elf32-xtensa.c:2800
+#: /src/binutils-gdb/bfd/elfnn-aarch64.c:4193
+msgid "%B(%A+0x%lx): %s used with non-TLS symbol %s"
+msgstr "%B(%A+0x%lx): %s käytetään ei-TLS-symbolin %s kanssa"
+
+#: elf32-arm.c:10666 elf32-tic6x.c:2736
+#: /src/binutils-gdb/bfd/elfnn-aarch64.c:4481
+msgid "out of range"
+msgstr "lukualueen ulkopuolella"
+
+#: elf32-arm.c:10670 elf32-nios2.c:3525 elf32-tic6x.c:2740
+#: /src/binutils-gdb/bfd/elfnn-aarch64.c:4485
+msgid "unsupported relocation"
+msgstr "ei-tuettu sijoitus"
+
+#: elf32-arm.c:10678 elf32-nios2.c:3535 elf32-tic6x.c:2748
+#: /src/binutils-gdb/bfd/elfnn-aarch64.c:4493
+msgid "unknown error"
+msgstr "tuntematon virhe"
+
+#: elf32-arm.c:11153
+msgid "Warning: Clearing the interworking flag of %B because non-interworking code in %B has been linked with it"
+msgstr "Varoitus: Nollataan %B:n vanhan koodin kanssa toimimisen yhteistoimivuuslippu, koska se on linkitetty ei-yhteistoimivuuskoodiin %B:ssa"
+
+#: elf32-arm.c:11240
+msgid "%B: Unknown mandatory EABI object attribute %d"
+msgstr "%B: Tuntematon pakollinen EABI-objektiattribuutti %d"
+
+#: elf32-arm.c:11248
+msgid "Warning: %B: Unknown EABI object attribute %d"
+msgstr "Varoitus: %B: Tuntematon EABI-objektiattribuutti %d"
+
+#: elf32-arm.c:11449
+msgid "error: %B: Unknown CPU architecture"
+msgstr "virhe: %B: Tuntematon prosessoriarkkitehtuuri"
+
+#: elf32-arm.c:11487
+msgid "error: %B: Conflicting CPU architectures %d/%d"
+msgstr "virhe: %B: Ristiriitaisia prosessoriarkkitehtuureja %d/%d"
+
+#: elf32-arm.c:11576
+msgid "Error: %B has both the current and legacy Tag_MPextension_use attributes"
+msgstr "Virhe: kohteessa %B on sekä nykyisiä että perinne-Tag_MPextension_use-attribuutteja"
+
+#: elf32-arm.c:11601
+msgid "error: %B uses VFP register arguments, %B does not"
+msgstr "virhe: %B käyttää VFP-rekisteriargumentteja, %B ei käytä"
+
+#: elf32-arm.c:11747
+msgid "error: %B: unable to merge virtualization attributes with %B"
+msgstr "virhe: %B: ei kyetä yhdistämään virtualisointiattribuutteja kohteen %B kanssa"
+
+#: elf32-arm.c:11773
+msgid "error: %B: Conflicting architecture profiles %c/%c"
+msgstr "virhe: %B: Ristiriitaisia arkkitehtuuriprofiileja %c/%c"
+
+#: elf32-arm.c:11877
+msgid "Warning: %B: Conflicting platform configuration"
+msgstr "Varoitus: %B: Ristiriitainen käyttöjärjestemäkonfiguraatio"
+
+#: elf32-arm.c:11886
+msgid "error: %B: Conflicting use of R9"
+msgstr "virhe: %B: Ristiriitainen R9:n käyttö"
+
+#: elf32-arm.c:11898
+msgid "error: %B: SB relative addressing conflicts with use of R9"
+msgstr "virhe: %B: SB-suhteellinen osoitteitus on ristiriidassa R9:n käytön kanssa"
+
+#: elf32-arm.c:11911
+msgid "warning: %B uses %u-byte wchar_t yet the output is to use %u-byte wchar_t; use of wchar_t values across objects may fail"
+msgstr "varoitus: %B käyttää %u-tavuista wchar_t-merkkiä vaikka tuloste käyttää %u-tavuista wchar_t-merkkiä; wchart_t-käyttöarvot objekteissa saattavat olla virheellisiä"
+
+#: elf32-arm.c:11942
+msgid "warning: %B uses %s enums yet the output is to use %s enums; use of enum values across objects may fail"
+msgstr "varoitus: %B käyttää %s enums-alkioita vaikka tuloste käyttää %s enums-alkioita; enum-arvojen käyttö objekteissa saattaa olla virheellinen"
+
+#: elf32-arm.c:11954
+msgid "error: %B uses iWMMXt register arguments, %B does not"
+msgstr "virhe: %B käyttää iWMMXt-rekisteriargumentteja, %B ei käytä"
+
+#: elf32-arm.c:11971
+msgid "error: fp16 format mismatch between %B and %B"
+msgstr "virhe: fp16-muototäsmäämättömyys kohteiden %B ja %B välillä"
+
+#: elf32-arm.c:12007
+msgid "%B has has both the current and legacy Tag_MPextension_use attributes"
+msgstr "kohteella %B on sekä nykyisiä että perinne-Tag_MPextension_use-attribuutteja"
+
+#. Ignore init flag - it may not be set, despite the flags field
+#. containing valid data.
+#. Ignore init flag - it may not be set, despite the flags field containing valid data.
+#. Ignore init flag - it may not be set, despite the flags field
+#. containing valid data.
+#: elf32-arm.c:12095 elf32-bfin.c:4949 elf32-cris.c:4139 elf32-m68hc1x.c:1427
+#: elf32-m68k.c:1195 elf32-score.c:4004 elf32-score7.c:3808 elf32-vax.c:529
+#: elf32-xgate.c:674 elfxx-mips.c:14955
+#: /src/binutils-gdb/bfd/elfnn-aarch64.c:4645
+#, c-format
+msgid "private flags = %lx:"
+msgstr "yksityiset liput = %lx:"
+
+#: elf32-arm.c:12104
+#, c-format
+msgid " [interworking enabled]"
+msgstr " [yhteistoimivuus vanhan koodin kanssa on käytössä]"
+
+#: elf32-arm.c:12112
+#, c-format
+msgid " [VFP float format]"
+msgstr " [vektoriliukulukumuoto]"
+
+#: elf32-arm.c:12114
+#, c-format
+msgid " [Maverick float format]"
+msgstr " [Maverick-liukulukumuoto]"
+
+#: elf32-arm.c:12116
+#, c-format
+msgid " [FPA float format]"
+msgstr " [Liukulukukiihdytin-liukulukumuoto]"
+
+#: elf32-arm.c:12125
+#, c-format
+msgid " [new ABI]"
+msgstr " [uusi ABI]"
+
+#: elf32-arm.c:12128
+#, c-format
+msgid " [old ABI]"
+msgstr " [vanha ABI]"
+
+#: elf32-arm.c:12131
+#, c-format
+msgid " [software FP]"
+msgstr " [ohjelmistoliukuluku]"
+
+#: elf32-arm.c:12140
+#, c-format
+msgid " [Version1 EABI]"
+msgstr " [Versio 1 EABI]"
+
+#: elf32-arm.c:12143 elf32-arm.c:12154
+#, c-format
+msgid " [sorted symbol table]"
+msgstr " [lajiteltu symbolitaulu]"
+
+#: elf32-arm.c:12145 elf32-arm.c:12156
+#, c-format
+msgid " [unsorted symbol table]"
+msgstr " [lajittelematon symbolitaulu]"
+
+#: elf32-arm.c:12151
+#, c-format
+msgid " [Version2 EABI]"
+msgstr " [Versio 2 EABI]"
+
+#: elf32-arm.c:12159
+#, c-format
+msgid " [dynamic symbols use segment index]"
+msgstr " [dynaamiset symbolit käyttävät segmentti-indeksiä]"
+
+#: elf32-arm.c:12162
+#, c-format
+msgid " [mapping symbols precede others]"
+msgstr " [kuvaussymbolit ylittävät tärkeydessä muut]"
+
+#: elf32-arm.c:12169
+#, c-format
+msgid " [Version3 EABI]"
+msgstr " [Versio 3 EABI]"
+
+#: elf32-arm.c:12173
+#, c-format
+msgid " [Version4 EABI]"
+msgstr " [Versio 4 EABI]"
+
+#: elf32-arm.c:12177
+#, c-format
+msgid " [Version5 EABI]"
+msgstr " [Versio 5 EABI]"
+
+#: elf32-arm.c:12180
+#, c-format
+msgid " [soft-float ABI]"
+msgstr " [ohjelmistoliukuluku-ABI]"
+
+#: elf32-arm.c:12183
+#, c-format
+msgid " [hard-float ABI]"
+msgstr " [laitteistoliukuluku-ABI]"
+
+#: elf32-arm.c:12189
+#, c-format
+msgid " [BE8]"
+msgstr " [BE8]"
+
+#: elf32-arm.c:12192
+#, c-format
+msgid " [LE8]"
+msgstr " [LE8]"
+
+#: elf32-arm.c:12198
+#, c-format
+msgid " <EABI version unrecognised>"
+msgstr " <EABI-versio tunnistamaton>"
+
+#: elf32-arm.c:12205
+#, c-format
+msgid " [relocatable executable]"
+msgstr " [sijoitettava suoritettava tiedosto]"
+
+#: elf32-arm.c:12208
+#, c-format
+msgid " [has entry point]"
+msgstr " [on tulokohta]"
+
+#: elf32-arm.c:12213 /src/binutils-gdb/bfd/elfnn-aarch64.c:4648
+#, c-format
+msgid "<Unrecognised flag bits set>"
+msgstr "<Tunnistamaton lippubittijoukko>"
+
+#: elf32-arm.c:12522 elf32-i386.c:1452 elf32-s390.c:1005 elf32-tic6x.c:2812
+#: elf32-tilepro.c:1511 elf32-xtensa.c:999 elf64-s390.c:927
+#: elf64-x86-64.c:1467 elfxx-sparc.c:1415 elfxx-tilegx.c:1728
+#: /src/binutils-gdb/bfd/elfnn-aarch64.c:5038
+msgid "%B: bad symbol index: %d"
+msgstr "%B: virheellinen symboli-indeksi: %d"
+
+#: elf32-arm.c:12674 elf32-metag.c:2283 elf64-x86-64.c:1593
+#: elf64-x86-64.c:1771 elfxx-mips.c:8482
+msgid "%B: relocation %s against `%s' can not be used when making a shared object; recompile with -fPIC"
+msgstr "%B: sijoitusta %s käyttäen â€%s†ei voida käyttää kun tehdään jaettua objektia; käännä uudelleen -fPIC-argumentilla"
+
+#: elf32-arm.c:13796
+#, c-format
+msgid "Errors encountered processing file %s"
+msgstr "Kohdattiin virheitä prosessoitaessa tiedostoa %s"
+
+#: elf32-arm.c:14230
+#, c-format
+msgid "error: required section '%s' not found in the linker script"
+msgstr "virhe: vaadittua lohkoa ’%s’ ei löytynyt linkkeriskriptistä"
+
+#: elf32-arm.c:15252
+msgid "%B: error: Cortex-A8 erratum stub is allocated in unsafe location"
+msgstr "%B: virhe: Cortex-A8 virhe-stub on varattu turvattomaan paikkaan"
+
+#. There's not much we can do apart from complain if this
+#. happens.
+#: elf32-arm.c:15279
+msgid "%B: error: Cortex-A8 erratum stub out of range (input file too large)"
+msgstr "%B: virhe: Cortex-A8 virhe-stub lukualueen ulkopuolella (syötetiedoston on liian iso)"
+
+#: elf32-arm.c:15373 elf32-arm.c:15395
+msgid "%B: error: VFP11 veneer out of range"
+msgstr "%B: virhe: VFP11-julkisivu lukualueen ulkopuolella"
+
+#: elf32-arm.c:16020
+msgid "error: %B is already in final BE8 format"
+msgstr "virhe: %B on jo lopullisessa BE8-muodossa"
+
+#: elf32-arm.c:16096
+msgid "error: Source object %B has EABI version %d, but target %B has EABI version %d"
+msgstr "virhe: Lähdeobjektissa %B on EABI-versio %d, mutta kohteessa %B on EABI-versio %d"
+
+#: elf32-arm.c:16112
+msgid "error: %B is compiled for APCS-%d, whereas target %B uses APCS-%d"
+msgstr "virhe: %B on käännetty APCS-%d:lle, kun taas kohde %B käyttää APCS-%d:ta"
+
+# Vector floating point (coprosessor)
+#: elf32-arm.c:16137
+msgid "error: %B uses VFP instructions, whereas %B does not"
+msgstr "virhe: %B käyttää vektoriliukulukukäskyjä, kun taas %B ei käytä"
+
+# Floating Point Accelerator (chip)
+#: elf32-arm.c:16141
+msgid "error: %B uses FPA instructions, whereas %B does not"
+msgstr "virhe: %B käyttää liukulukukiihdytinkäskyjä, kun taas %B ei käytä"
+
+#: elf32-arm.c:16151
+msgid "error: %B uses Maverick instructions, whereas %B does not"
+msgstr "virhe: %B käyttää Maverick-käskyjä, kun taas %B ei käytä"
+
+#: elf32-arm.c:16155
+msgid "error: %B does not use Maverick instructions, whereas %B does"
+msgstr "virhe: %B ei käytä Maverick-käskyjä, kun taas %B käyttää"
+
+#: elf32-arm.c:16174
+msgid "error: %B uses software FP, whereas %B uses hardware FP"
+msgstr "virhe: %B käyttää ohjelmistoliukulukuja, kun taas %B käyttää laitteistoliukulukuja"
+
+#: elf32-arm.c:16178
+msgid "error: %B uses hardware FP, whereas %B uses software FP"
+msgstr "virhe: %B käyttää laitteistoliukulukuja, kun taas %B käyttää ohjelmistoliukulukuja"
+
+#: elf32-avr.c:1264 elf32-bfin.c:3228 elf32-cris.c:2024 elf32-epiphany.c:568
+#: elf32-fr30.c:597 elf32-frv.c:4047 elf32-i860.c:1220 elf32-ip2k.c:1479
+#: elf32-iq2000.c:696 elf32-m32c.c:561 elf32-mep.c:543 elf32-metag.c:2000
+#: elf32-moxie.c:290 elf32-msp430.c:1325 elf32-mt.c:399 elf32-openrisc.c:412
+#: elf32-tilepro.c:3674 elf32-v850.c:2289 elf32-xstormy16.c:944
+#: elf64-mmix.c:1546 elfxx-tilegx.c:4059
+msgid "internal error: dangerous relocation"
+msgstr "sisäinen virhe: vaarallinen sijoitus"
+
+#: elf32-avr.c:2476 elf32-hppa.c:578 elf32-m68hc1x.c:160 elf32-metag.c:1197
+#: elf32-nios2.c:1357
+msgid "%B: cannot create stub entry %s"
+msgstr "%B: ei voi luoda stub-tulokohtaa %s"
+
+#: elf32-bfin.c:107 elf32-bfin.c:363
+msgid "relocation should be even number"
+msgstr "sijoituksen pitäisi olla parillinen numero"
+
+#: elf32-bfin.c:1601
+msgid "%B(%A+0x%lx): unresolvable relocation against symbol `%s'"
+msgstr "%B(%A+0x%lx): ratkaisematon sijoitus symboliin â€%sâ€"
+
+#: elf32-bfin.c:1634 elf32-i386.c:4406 elf32-m68k.c:4197 elf32-s390.c:3364
+#: elf64-s390.c:3290 elf64-x86-64.c:4506
+msgid "%B(%A+0x%lx): reloc against `%s': error %d"
+msgstr "%B(%A+0x%lx): reloc-tietue käyttäen kohdetta â€%sâ€: virhe %d"
+
+#: elf32-bfin.c:2732
+msgid "%B: relocation at `%A+0x%x' references symbol `%s' with nonzero addend"
+msgstr "%B: sijoitus kohteessa â€%A+0x%x†viittaa symboliin â€%sâ€, jossa on ei-nolla-yhteenlaskettava"
+
+#: elf32-bfin.c:2748
+msgid "relocation references symbol not defined in the module"
+msgstr "sijoitusviitteet-symboli ei ole määritelty modulissa"
+
+#: elf32-bfin.c:2845
+msgid "R_BFIN_FUNCDESC references dynamic symbol with nonzero addend"
+msgstr "R_BFIN_FUNCDESC viittaa dynaamiseen symboliin, jossa on ei-nolla-yhteenlaskettava"
+
+#: elf32-bfin.c:2886 elf32-bfin.c:3009
+msgid "cannot emit fixups in read-only section"
+msgstr "ei voi lähettää korjauksia kirjoitussuojattuun lohkoon"
+
+#: elf32-bfin.c:2917 elf32-bfin.c:3047 elf32-lm32.c:1095 elf32-sh.c:4913
+msgid "cannot emit dynamic relocations in read-only section"
+msgstr "ei voi lähettää dynaamisia sijoituksia kirjoitussuojatussa lohkossa"
+
+#: elf32-bfin.c:2967
+msgid "R_BFIN_FUNCDESC_VALUE references dynamic symbol with nonzero addend"
+msgstr "R_BFIN_FUNCDESC_VALUE viittaa dynaamiseen symboliin, jossa on ei-nolla-yhteenlaskettava"
+
+#: elf32-bfin.c:3132
+msgid "relocations between different segments are not supported"
+msgstr "sijoituksia eri segmenttien välillä ei tueta"
+
+#: elf32-bfin.c:3133
+msgid "warning: relocation references a different segment"
+msgstr "varoitus: sijoitus viittaa eri segmenttiin"
+
+#: elf32-bfin.c:4907
+msgid "%B: unsupported relocation type %i"
+msgstr "%B: ei-tuettu sijoitustyyppi %i"
+
+# The FR-V FDPIC ABI: The FDPIC register is used as a base register for accessing the global offset table (GOT) and function descriptors.
+# Yksi prosessorin rekistereistä on nimetty fdpic-rekisteriksi milloin data- ja tekstilohkot ovat sijoitettavia (eli niiden siirros ei ole vakio).
+#: elf32-bfin.c:4995 elf32-frv.c:6600
+#, c-format
+msgid "%s: cannot link non-fdpic object file into fdpic executable"
+msgstr "%s: ei voi linkittää objektitiedostoa ilman fdpic-rekisteriä suoritettavaan tiedostoon, joka käyttää fdpic-rekisteriä"
+
+#: elf32-bfin.c:4999 elf32-frv.c:6604
+#, c-format
+msgid "%s: cannot link fdpic object file into non-fdpic executable"
+msgstr "%s: ei voi linkittää fdpic-rekisteriä käyttävää objektitiedostoa suoritettavaan tiedostoon, joka ei käytä fdpic-rekisteriä"
+
+#: elf32-bfin.c:5153
+#, c-format
+msgid "*** check this relocation %s"
+msgstr "*** tarkista tämä sijoitus %s"
+
+#: elf32-cris.c:1110
+msgid "%B, section %A: unresolvable relocation %s against symbol `%s'"
+msgstr "%B, lohko %A: ratkaisematon sijoitus %s käyttäen symbolia â€%sâ€"
+
+# Procedure Linkage Table (PLT) and Global Offset Table (GOT)
+#: elf32-cris.c:1172
+msgid "%B, section %A: No PLT nor GOT for relocation %s against symbol `%s'"
+msgstr "%B, lohko %A: Ei proseduurilinkitystaulua eikä yleissiirrostaulua sijoitukselle %s käyttäen symbolia â€%sâ€"
+
+#: elf32-cris.c:1174
+msgid "%B, section %A: No PLT for relocation %s against symbol `%s'"
+msgstr "%B, lohko %A: Ei proseduurilinkitystaulua sijoituksille %s käyttäen symbolia â€%sâ€"
+
+#: elf32-cris.c:1180 elf32-cris.c:1313 elf32-cris.c:1573 elf32-cris.c:1656
+#: elf32-cris.c:1809 elf32-tic6x.c:2645
+msgid "[whose name is lost]"
+msgstr "[jonka nimi on kadonnut]"
+
+#: elf32-cris.c:1299 elf32-tic6x.c:2630
+msgid "%B, section %A: relocation %s with non-zero addend %d against local symbol"
+msgstr "%B, lohko %A: sijoitus %s ei-nolla-yhteenlaskettavalla %d käyttäen paikallista symbolia"
+
+#: elf32-cris.c:1307 elf32-cris.c:1650 elf32-cris.c:1803 elf32-tic6x.c:2638
+msgid "%B, section %A: relocation %s with non-zero addend %d against symbol `%s'"
+msgstr "%B, lohko %A: sijoitus %s ei-nolla-yhteenlaskettavalla %d käyttäen symbolia â€%sâ€"
+
+#: elf32-cris.c:1333
+msgid "%B, section %A: relocation %s is not allowed for global symbol: `%s'"
+msgstr "%B, lohko %A: sijoitusta %s ei sallita yleissymbolille: â€%sâ€"
+
+#: elf32-cris.c:1349
+msgid "%B, section %A: relocation %s with no GOT created"
+msgstr "%B, lohko %A: sijoitus %s ilman yleissiirrostaulun luontia"
+
+#. We shouldn't get here for GCC-emitted code.
+#: elf32-cris.c:1564
+msgid "%B, section %A: relocation %s has an undefined reference to `%s', perhaps a declaration mixup?"
+msgstr "%B, lohkon %A: sijoituksella %s on määrittelemätön viite â€%sâ€, ehkä esittelysekaannus?"
+
+#: elf32-cris.c:1937
+msgid "%B, section %A: relocation %s is not allowed for symbol: `%s' which is defined outside the program, perhaps a declaration mixup?"
+msgstr "%B, lohko %A: sijoitusta %s ei sallita symbolille: â€%sâ€, joka määritellään ohjelman ulkopuolella, ehkä esittelysekaannus?"
+
+#: elf32-cris.c:1990
+msgid "(too many global variables for -fpic: recompile with -fPIC)"
+msgstr "(liian monta yleismuuttujaa valitsimelle -fpic: käännä uudelleen valitsimella -fPIC)"
+
+#: elf32-cris.c:1997
+msgid "(thread-local data too big for -fpic or -msmall-tls: recompile with -fPIC or -mno-small-tls)"
+msgstr "(säikeen paikallinen data liian iso valitsimelle -fpic tai -msmall-tls: käännä uudelleen valitsimella -fPIC tai -mno-small-tls)"
+
+# position-independent code (PIC)
+#: elf32-cris.c:3234
+msgid ""
+"%B, section %A:\n"
+" v10/v32 compatible object %s must not contain a PIC relocation"
+msgstr ""
+"%B, lohko %A:\n"
+" v10/v32 yhteensopiva objekti %s ei saa sisältää paikkariippumatonta koodisijoitusta"
+
+#: elf32-cris.c:3342
+msgid ""
+"%B, section %A:\n"
+" relocation %s not valid in a shared object; typically an option mixup, recompile with -fPIC"
+msgstr ""
+"%B, lohko %A:\n"
+" sijoitusta %s ei pitäisi käyttää jaetussa objektissa; tyypillisesti valitsinsekaannus, käännä uudelleen argumentilla -fPIC"
+
+#: elf32-cris.c:3556
+msgid ""
+"%B, section %A:\n"
+" relocation %s should not be used in a shared object; recompile with -fPIC"
+msgstr ""
+"%B, lohko %A:\n"
+" sijoitusta %s ei pitäisi käyttää jaettussa objektissa; käännä uudelleen argumentilla -fPIC"
+
+#: elf32-cris.c:3978
+msgid ""
+"%B, section `%A', to symbol `%s':\n"
+" relocation %s should not be used in a shared object; recompile with -fPIC"
+msgstr ""
+"%B, lohko â€%Aâ€, symboliin â€%sâ€:\n"
+" sijoitusta %s ei pitäisi käyttää jaettussa objektissa; käännä uudelleen argumentilla -fPIC"
+
+#: elf32-cris.c:4091
+msgid "Unexpected machine number"
+msgstr "Odottamaton konenumero"
+
+#: elf32-cris.c:4142
+#, c-format
+msgid " [symbols have a _ prefix]"
+msgstr " [symboleissa on â€_â€-etuliite]"
+
+#: elf32-cris.c:4145
+#, c-format
+msgid " [v10 and v32]"
+msgstr " [v10 ja v32]"
+
+#: elf32-cris.c:4148
+#, c-format
+msgid " [v32]"
+msgstr " [v32]"
+
+#: elf32-cris.c:4191
+msgid "%B: uses _-prefixed symbols, but writing file with non-prefixed symbols"
+msgstr "%B: käyttää â€_â€-etuliitesymboleja, mutta kirjoittaa tiedoston ilman etuliitesymboleja"
+
+#: elf32-cris.c:4192
+msgid "%B: uses non-prefixed symbols, but writing file with _-prefixed symbols"
+msgstr "%B: käyttää ilman etuliitesymboleja, mutta kirjoittaa tiedoston â€_â€-etuliitesymboleilla"
+
+# CRIS v32 info: The chip with the CRIS v32 core.
+#: elf32-cris.c:4211
+msgid "%B contains CRIS v32 code, incompatible with previous objects"
+msgstr "%B sisältää â€CRIS v32â€-koodia, ei ole yhteensopiva aiempien objektien kanssa"
+
+#: elf32-cris.c:4213
+msgid "%B contains non-CRIS-v32 code, incompatible with previous objects"
+msgstr "%B ei sisällä â€CRIS-v32â€-koodia, yhteensopimaton aiempien objektien kanssa"
+
+#: elf32-dlx.c:142
+#, c-format
+msgid "BFD Link Error: branch (PC rel16) to section (%s) not supported"
+msgstr "BFD-linkitysvirhe: haaralinja (PC rel16) lohkoon (%s) ei ole tuettu"
+
+#: elf32-dlx.c:204
+#, c-format
+msgid "BFD Link Error: jump (PC rel26) to section (%s) not supported"
+msgstr "BFD-linkitysvirhe: hyppy (PC rel26) lohkoon (%s) ei ole tuettu"
+
+#. Only if it's not an unresolved symbol.
+#: elf32-epiphany.c:564 elf32-ip2k.c:1475
+msgid "unsupported relocation between data/insn address spaces"
+msgstr "ei-tuettu sijoitus data/käskyosoitetilojen välillä"
+
+#: elf32-frv.c:1460 elf32-frv.c:1609
+msgid "relocation requires zero addend"
+msgstr "sijoitus vaatii nolla-yhteenlaskettavan"
+
+#: elf32-frv.c:2822
+msgid "%H: relocation to `%s+%v' may have caused the error above\n"
+msgstr "%H: sijoitus kohteeseen â€%s+%v†saattaa olla yläpuolella olevan virheen aiheuttama\n"
+
+#: elf32-frv.c:2839
+msgid "%H: relocation references symbol not defined in the module\n"
+msgstr "%H: sijoitusviitteet-symboli ei ole määritelty modulissa\n"
+
+#: elf32-frv.c:2915
+msgid "%H: R_FRV_GETTLSOFF not applied to a call instruction\n"
+msgstr "%H: R_FRV_GETTLSOFF ei sovelleta kutsukäskyyn\n"
+
+#: elf32-frv.c:2956
+msgid "%H: R_FRV_GOTTLSDESC12 not applied to an lddi instruction\n"
+msgstr "%H: R_FRV_GOTTLSDESC12 ei sovelleta â€lddiâ€-käskyyn\n"
+
+#: elf32-frv.c:3027
+msgid "%H: R_FRV_GOTTLSDESCHI not applied to a sethi instruction\n"
+msgstr "%H: R_FRV_GOTTLSDESCHI ei sovelleta â€sethiâ€-käskyyn\n"
+
+#: elf32-frv.c:3064
+msgid "%H: R_FRV_GOTTLSDESCLO not applied to a setlo or setlos instruction\n"
+msgstr "%H: R_FRV_GOTTLSDESCLO ei sovelleta â€setloâ€- tai â€setlosâ€-käskyyn\n"
+
+#: elf32-frv.c:3111
+msgid "%H: R_FRV_TLSDESC_RELAX not applied to an ldd instruction\n"
+msgstr "%H: R_FRV_TLSDESC_RELAX ei sovelleta â€lddâ€-käskyyn\n"
+
+# msgid-virhe: calll, eli yksi ällä liikaa
+#: elf32-frv.c:3195
+msgid "%H: R_FRV_GETTLSOFF_RELAX not applied to a calll instruction\n"
+msgstr "%H: R_FRV_GETTLSOFF_RELAX ei sovelleta kutsukäskyyn\n"
+
+#: elf32-frv.c:3249
+msgid "%H: R_FRV_GOTTLSOFF12 not applied to an ldi instruction\n"
+msgstr "%H: R_FRV_GOTTLSOFF12 ei sovelleta â€ldiâ€-käskyyn\n"
+
+#: elf32-frv.c:3279
+msgid "%H: R_FRV_GOTTLSOFFHI not applied to a sethi instruction\n"
+msgstr "%H: R_FRV_GOTTLSOFFHI ei sovelleta â€sethiâ€-käskyyn\n"
+
+#: elf32-frv.c:3308
+msgid "%H: R_FRV_GOTTLSOFFLO not applied to a setlo or setlos instruction\n"
+msgstr "%H: R_FRV_GOTTLSOFFLO ei sovelleta â€setloâ€- tai â€setlosâ€-käskyyn\n"
+
+#: elf32-frv.c:3338
+msgid "%H: R_FRV_TLSOFF_RELAX not applied to an ld instruction\n"
+msgstr "%H: R_FRV_TLSOFF_RELAX ei sovelleta â€ldâ€-käskyyn\n"
+
+#: elf32-frv.c:3383
+msgid "%H: R_FRV_TLSMOFFHI not applied to a sethi instruction\n"
+msgstr "%H: R_FRV_TLSMOFFHI ei sovelleta â€sethiâ€-käskyyn\n"
+
+#: elf32-frv.c:3410
+msgid "R_FRV_TLSMOFFLO not applied to a setlo or setlos instruction\n"
+msgstr "R_FRV_TLSMOFFLO ei sovelleta â€setloâ€- tai â€setlosâ€-käskyyn\n"
+
+#: elf32-frv.c:3531
+msgid "%H: R_FRV_FUNCDESC references dynamic symbol with nonzero addend\n"
+msgstr "%H: R_FRV_FUNCDESC viittaa dynaamiseen symboliin ei-nolla-yhteenlaskettavalla\n"
+
+#: elf32-frv.c:3572 elf32-frv.c:3694
+msgid "%H: cannot emit fixups in read-only section\n"
+msgstr "%H: ei voi lähettää korjauksia kirjoitussuojattuun lohkoon\n"
+
+#: elf32-frv.c:3603 elf32-frv.c:3737
+msgid "%H: cannot emit dynamic relocations in read-only section\n"
+msgstr "%H: ei voi lähettää dynaamisia sijoituksia kirjoitussuojattussa lohkossa\n"
+
+#: elf32-frv.c:3652
+msgid "%H: R_FRV_FUNCDESC_VALUE references dynamic symbol with nonzero addend\n"
+msgstr "%H: R_FRV_FUNCDESC_VALUE viittaa dynaamiseen symboliin ei-nolla-yhteenlaskettavalla\n"
+
+#: elf32-frv.c:3908
+msgid "%H: reloc against `%s' references a different segment\n"
+msgstr "%H: sijoitus kohteeseen â€%s†viittaa eri segmenttiin\n"
+
+#: elf32-frv.c:4058
+msgid "%H: reloc against `%s': %s\n"
+msgstr "%H: reloc-tietue käyttäen kohdetta â€%sâ€: %s\n"
+
+#: elf32-frv.c:6265
+msgid "%B: unsupported relocation type %i\n"
+msgstr "%B: ei-tuettu sijoitustyyppi %i\n"
+
+#: elf32-frv.c:6514
+#, c-format
+msgid "%s: compiled with %s and linked with modules that use non-pic relocations"
+msgstr "%s: käännetty %s:n kanssa ja linkitetty paikkariippuvaisia koodisijoituksia käyttävien modulien kanssa"
+
+#: elf32-frv.c:6567 elf32-iq2000.c:828 elf32-m32c.c:812
+#, c-format
+msgid "%s: compiled with %s and linked with modules compiled with %s"
+msgstr "%s: käännetty %s:n kanssa ja linkitetty moduleihin, jotka on käännetty %s:n kanssa"
+
+#: elf32-frv.c:6579
+#, c-format
+msgid "%s: uses different unknown e_flags (0x%lx) fields than previous modules (0x%lx)"
+msgstr "%s: käyttää erilaisia tuntemattomia â€e_flags (0x%lx)â€-kenttiä kuin edelliset modulit (0x%lx)"
+
+#: elf32-frv.c:6627 elf32-iq2000.c:865 elf32-m32c.c:848 elf32-mt.c:561
+#: elf32-rl78.c:1069 elf32-rx.c:3040 elf64-ppc.c:5839
+#, c-format
+msgid "private flags = 0x%lx:"
+msgstr "yksityiset liput = 0x%lx:"
+
+#: elf32-gen.c:69 elf64-gen.c:69
+msgid "%B: Relocations in generic ELF (EM: %d)"
+msgstr "%B: Sijoituksia geneerisessä ELF (EM: %d):ssa"
+
+#: elf32-hppa.c:830 elf32-hppa.c:3592
+msgid "%B(%A+0x%lx): cannot reach %s, recompile with -ffunction-sections"
+msgstr "%B(%A+0x%lx): ei tavoita kohdetta %s, käännä uudelleen â€-ffunction-sectionsâ€-valitsimilla"
+
+#: elf32-hppa.c:1268
+msgid "%B: relocation %s can not be used when making a shared object; recompile with -fPIC"
+msgstr "%B: sijoitusta %s ei voi käyttää kun tehdään jaettua objektia; käännä uudelleen â€-fPICâ€-argumentilla"
+
+#: elf32-hppa.c:2781
+msgid "%B: duplicate export stub %s"
+msgstr "%B: vienti-stubin %s kaksoiskappale"
+
+#: elf32-hppa.c:3427
+msgid "%B(%A+0x%lx): %s fixup for insn 0x%x is not supported in a non-shared link"
+msgstr "%B(%A+0x%lx): %s korjaus käskylle 0x%x ei ole tuettu ei-jaetussa linkissä"
+
+#: elf32-hppa.c:4279
+msgid "%B(%A+0x%lx): cannot handle %s for %s"
+msgstr "%B(%A+0x%lx): ei voi käsitellä %s kohteelle %s"
+
+#: elf32-hppa.c:4598
+msgid ".got section not immediately after .plt section"
+msgstr "â€.gotâ€-alilohko ei ole välittömästi â€.pltâ€-lohkon jälkeen"
+
+#. Unknown relocation.
+#: elf32-i386.c:380 elf32-m68k.c:353 elf32-ppc.c:2035 elf32-s390.c:345
+#: elf32-tic6x.c:2667 elf64-ppc.c:2427 elf64-s390.c:371 elf64-x86-64.c:281
+msgid "%B: invalid relocation type %d"
+msgstr "%B: virheellinen sijoitustyyppi %d"
+
+#: elf32-i386.c:1394 elf64-x86-64.c:1410
+msgid "%B: TLS transition from %s to %s against `%s' at 0x%lx in section `%A' failed"
+msgstr "%B: TLS-siirros kohteesta %s kohteeseen %s käyttäen kohdetta â€%s†osoitteessa 0x%lx lohkossa â€%A†epäonnistui"
+
+#: elf32-i386.c:1642 elf32-s390.c:1233 elf32-sh.c:6263 elf32-tilepro.c:1627
+#: elf32-xtensa.c:1176 elf64-s390.c:1166 elfxx-sparc.c:1596
+#: elfxx-tilegx.c:1836
+msgid "%B: `%s' accessed both as normal and thread local symbol"
+msgstr "%B: â€%s†haettu sekä normaalina että säikeisenä paikallissymbolina"
+
+#: elf32-i386.c:2500 elf64-x86-64.c:2582
+msgid "%P: %B: warning: relocation against `%s' in readonly section `%A'.\n"
+msgstr "%P: %B: varoitus: sijoitus käyttäen kohdetta â€%s†kirjoitussuojatussa lohkossa â€%Aâ€.\n"
+
+#: elf32-i386.c:2740 elf64-x86-64.c:2820
+msgid "%P: %B: warning: relocation in readonly section `%A'.\n"
+msgstr "%P: %B: varoitus: sijoitus kirjoitussuojatussa lohkossa â€%Aâ€.\n"
+
+#: elf32-i386.c:3207 elf32-tilepro.c:2873 elf64-x86-64.c:3275
+#: elfxx-tilegx.c:3172 /src/binutils-gdb/bfd/elfnn-aarch64.c:4099
+msgid "%B: unrecognized relocation (0x%x) in section `%A'"
+msgstr "%B: tunnistamaton sijoitus (0x%x) lohkossa â€%Aâ€"
+
+#: elf32-i386.c:3368 elf64-x86-64.c:3380 elfxx-sparc.c:3150
+#: /src/binutils-gdb/bfd/elfnn-aarch64.c:3496
+msgid "%B: relocation %s against STT_GNU_IFUNC symbol `%s' isn't handled by %s"
+msgstr "%B: sijoitusta %s käyttäen kohteen STT_GNU_IFUNC-symbolia â€%s†ei käsittele %s"
+
+#: elf32-i386.c:3610 elf64-x86-64.c:3777
+msgid "hidden symbol"
+msgstr "piilotettu symboli"
+
+#: elf32-i386.c:3613 elf64-x86-64.c:3780
+msgid "internal symbol"
+msgstr "sisäinen symboli"
+
+#: elf32-i386.c:3616 elf64-x86-64.c:3783
+msgid "protected symbol"
+msgstr "suojattu symboli"
+
+#: elf32-i386.c:3619 elf64-x86-64.c:3786
+msgid "symbol"
+msgstr "symboli"
+
+#: elf32-i386.c:3624
+msgid "%B: relocation R_386_GOTOFF against undefined %s `%s' can not be used when making a shared object"
+msgstr "%B: R_386_GOTOFF-sijoitusta käyttäen määrittelemätöntä %s â€%s†ei voida käyttää kun tehdään jaettua objektia"
+
+#: elf32-i386.c:3635
+msgid "%B: relocation R_386_GOTOFF against protected function `%s' can not be used when making a shared object"
+msgstr "%B: R_386_GOTOFF-sijoitusta suojattua käyttäen funktiota â€%s†ei voida käyttää kun tehdään jaettua objektia"
+
+#: elf32-i386.c:4923 elf32-tilepro.c:3923 elf64-x86-64.c:4964
+#: elfxx-tilegx.c:4326 /src/binutils-gdb/bfd/elfnn-aarch64.c:7105
+#, c-format
+msgid "discarded output section: `%A'"
+msgstr "hylätty tulostelohko: â€%Aâ€"
+
+# Kun käskyoperandi on sen lukualueen ulkopuolella, joka sallitaan kullekin käskykentälle, assembler voi muuntaa koodin käyttämään toiminnallisesti samanlaista käskyä tai käskysekvenssiä. Tämä prosessi tunnetaan nimellä relaxation. Tätä tehdään tyypillisesti haarautumiskäskyissä, koska haarautumiskohteen etäisyyttä ei tunneta ennen linkitystä. Tavallaan tällä tavalla kumotaan lukualueen rajoitteet (constraints). Siksi olen suomentanut sen termillä avartaminen.
+#: elf32-ip2k.c:857 elf32-ip2k.c:863 elf32-ip2k.c:930 elf32-ip2k.c:936
+msgid "ip2k relaxer: switch table without complete matching relocation information."
+msgstr "ip2k-avartaja: kytkintaulu ilman täydellisesti täsmääviä sijoitustietoja."
+
+# Kun käskyoperandi on sen lukualueen ulkopuolella, joka sallitaan kullekin käskykentälle, assembler voi muuntaa koodin käyttämään toiminnallisesti samanlaista käskyä tai käskysekvenssiä. Tämä prosessi tunnetaan nimellä relaxation. Tätä tehdään tyypillisesti haarautumiskäskyissä, koska haarautumiskohteen etäisyyttä ei tunneta ennen linkitystä. Tavallaan tällä tavalla kumotaan lukualueen rajoitteet (constraints). Siksi olen suomentanut sen termillä avartaminen.
+#: elf32-ip2k.c:880 elf32-ip2k.c:963
+msgid "ip2k relaxer: switch table header corrupt."
+msgstr "ip2k-avartaja: kytkintauluotsake rikkinäinen."
+
+#: elf32-ip2k.c:1292
+#, c-format
+msgid "ip2k linker: missing page instruction at 0x%08lx (dest = 0x%08lx)."
+msgstr "ip2k-linkkeri: puuttuva sivukäsky kohteessa 0x%08lx (kohde = 0x%08lx)."
+
+#: elf32-ip2k.c:1308
+#, c-format
+msgid "ip2k linker: redundant page instruction at 0x%08lx (dest = 0x%08lx)."
+msgstr "ip2k-linkkeri: redundanssisivukäsky kohteessa 0x%08lx (kohde = 0x%08lx)."
+
+#: elf32-iq2000.c:841 elf32-m32c.c:824
+#, c-format
+msgid "%s: uses different e_flags (0x%lx) fields than previous modules (0x%lx)"
+msgstr "%s: käyttää eri â€e_flags (0x%lx)â€-kenttiä kuin edelliset modulit (0x%lx)"
+
+#: elf32-lm32.c:698 elf32-nios2.c:2191
+msgid "global pointer relative relocation when _gp not defined"
+msgstr "yleisosoitinsuhteellinen sijoitus kun â€_gp†ei ole määritelty"
+
+#: elf32-lm32.c:753 elf32-nios2.c:2623
+msgid "global pointer relative address out of range"
+msgstr "yleisosoittimen suhteellinen osoite lukualueen ulkopuolella"
+
+#: elf32-lm32.c:1049
+msgid "internal error: addend should be zero for R_LM32_16_GOT"
+msgstr "sisäinen virhe: yhteenlaskettavan pitäisi olla nolla kohteelle R_LM32_16_GOT"
+
+#: elf32-m32r.c:1453
+msgid "SDA relocation when _SDA_BASE_ not defined"
+msgstr "SDA-sijoitus kun â€_SDA_BASE_†ei ole määritelty"
+
+#: elf32-m32r.c:3003
+msgid "%B: The target (%s) of an %s relocation is in the wrong section (%A)"
+msgstr "%B: Kohteen (%s) sijoitus %s on väärässä lohkossa (%A)"
+
+#: elf32-m32r.c:3529
+msgid "%B: Instruction set mismatch with previous modules"
+msgstr "%B: Käskyjoukko ei täsmää edellisten modulien kanssa"
+
+#: elf32-m32r.c:3550 elf32-nds32.c:5636
+#, c-format
+msgid "private flags = %lx"
+msgstr "yksityiset liput = %lx"
+
+#: elf32-m32r.c:3555
+#, c-format
+msgid ": m32r instructions"
+msgstr ": m32r-käskyt"
+
+#: elf32-m32r.c:3556
+#, c-format
+msgid ": m32rx instructions"
+msgstr ": m32rx-käskyt"
+
+#: elf32-m32r.c:3557
+#, c-format
+msgid ": m32r2 instructions"
+msgstr ": m32r2-käskyt"
+
+#: elf32-m68hc1x.c:1114
+#, c-format
+msgid "Reference to the far symbol `%s' using a wrong relocation may result in incorrect execution"
+msgstr "Viite etäsymboliin â€%s†väärää sijoitusta käyttäen saattaa aiheuttaa virheellisen suorituksen"
+
+#: elf32-m68hc1x.c:1150
+#, c-format
+msgid "XGATE address (%lx) is not within shared RAM(0xE000-0xFFFF), therefore you must manually offset the address, and possibly manage the page, in your code."
+msgstr "XGATE-osoite (%lx) ei ole jaetun RAM(0xE000-0xFFFF)-muistin sisällä, siksi sinun on asetettava siirrososoite manuaalisesti, ja mahdollisesti hallittava sivu koodissasi."
+
+# memory bank: A physical section of memory.
+#: elf32-m68hc1x.c:1170
+#, c-format
+msgid "banked address [%lx:%04lx] (%lx) is not in the same bank as current banked address [%lx:%04lx] (%lx)"
+msgstr "muistilohkottu osoite [%lx:%04lx] (%lx) ei ole samassa muistilohkossa kuin nykyinen muistilohkottu osoite [%lx:%04lx] (%lx)"
+
+#: elf32-m68hc1x.c:1190
+#, c-format
+msgid "reference to a banked address [%lx:%04lx] in the normal address space at %04lx"
+msgstr "viite muistilohkottuun osoitteeseen [%lx:%04lx] tavallisessa osoitetilassa osoitteessa %04lx"
+
+#: elf32-m68hc1x.c:1237
+#, c-format
+msgid "S12 address (%lx) is not within shared RAM(0x2000-0x4000), therefore you must manually offset the address in your code"
+msgstr "S12-osoite (%lx) ei ole jaetun RAM(0x2000-0x4000)-muistin sisällä, siksi sinun on asetettava siirrososoite koodissasi manuaalisesti"
+
+#: elf32-m68hc1x.c:1370
+msgid "%B: linking files compiled for 16-bit integers (-mshort) and others for 32-bit integers"
+msgstr "%B: linkitystiedostot käännetty 16-bittisille kokonaisluvuille (-mshort) ja muut 32-bittisille kokonaisluvuille"
+
+#: elf32-m68hc1x.c:1377
+msgid "%B: linking files compiled for 32-bit double (-fshort-double) and others for 64-bit double"
+msgstr "%B: linkitystiedostot käännetty 32-bittiselle double-liukuluvulle (-fshort-double) ja muut 64-bittiselle double-liukuluvulle"
+
+#: elf32-m68hc1x.c:1386
+msgid "%B: linking files compiled for HCS12 with others compiled for HC12"
+msgstr "%B: linkitystiedostot käännetty HCS12:lle, muut käännetty HC12:lle"
+
+#: elf32-m68hc1x.c:1402 elf32-ppc.c:4776 elf64-sparc.c:706 elfxx-mips.c:14817
+msgid "%B: uses different e_flags (0x%lx) fields than previous modules (0x%lx)"
+msgstr "%B: käyttää eri â€e_flags (0x%lx)â€-kenttiä kuin edelliset modulit (0x%lx)"
+
+#: elf32-m68hc1x.c:1430 elf32-xgate.c:677
+#, c-format
+msgid "[abi=32-bit int, "
+msgstr "[abi=32-bittinen kokonaisluku, "
+
+#: elf32-m68hc1x.c:1432 elf32-xgate.c:679
+#, c-format
+msgid "[abi=16-bit int, "
+msgstr "[abi=16-bittinen kokonaisluku, "
+
+#: elf32-m68hc1x.c:1435 elf32-xgate.c:682
+#, c-format
+msgid "64-bit double, "
+msgstr "64-bittinen double-liukuluku, "
+
+#: elf32-m68hc1x.c:1437 elf32-xgate.c:684
+#, c-format
+msgid "32-bit double, "
+msgstr "32-bittinen double-liukuluku, "
+
+#: elf32-m68hc1x.c:1440
+#, c-format
+msgid "cpu=HC11]"
+msgstr "prosessori=HC11]"
+
+#: elf32-m68hc1x.c:1442
+#, c-format
+msgid "cpu=HCS12]"
+msgstr "prosessori=HCS12]"
+
+#: elf32-m68hc1x.c:1444
+#, c-format
+msgid "cpu=HC12]"
+msgstr "prosessori=HC12]"
+
+#: elf32-m68hc1x.c:1447
+#, c-format
+msgid " [memory=bank-model]"
+msgstr " [muisti=muistilohkomalli]"
+
+#: elf32-m68hc1x.c:1449
+#, c-format
+msgid " [memory=flat]"
+msgstr " [muisti=litteä]"
+
+#: elf32-m68hc1x.c:1452
+#, c-format
+msgid " [XGATE RAM offsetting]"
+msgstr " [XGATE RAM-siirrososoiteasetus]"
+
+#: elf32-m68k.c:1210 elf32-m68k.c:1211 vms-alpha.c:7207 vms-alpha.c:7222
+msgid "unknown"
+msgstr "tuntematon"
+
+#: elf32-m68k.c:1674
+msgid "%B: GOT overflow: Number of relocations with 8-bit offset > %d"
+msgstr "%B: Yleissiirrostaulun ylivuoto: 8-bittisellä siirrososoitteella varustettujen sijoitusten lukumäärä > %d"
+
+#: elf32-m68k.c:1680
+msgid "%B: GOT overflow: Number of relocations with 8- or 16-bit offset > %d"
+msgstr "%B: Yleissiirrostaulun ylivuoto: 8-bittisellä tai 16-bittisellä siirrososoitteella varustettujen sijoitusten lukumäärä > %d"
+
+#: elf32-m68k.c:3921
+msgid "%B(%A+0x%lx): R_68K_TLS_LE32 relocation not permitted in shared object"
+msgstr "%B(%A+0x%lx): R_68K_TLS_LE32-sijoitukset eivät ole sallittuja jaetuissa objekteissa"
+
+#: elf32-mcore.c:99 elf32-mcore.c:442
+msgid "%B: Relocation %s (%d) is not currently supported.\n"
+msgstr "%B: Sijoitusta %s (%d) ei tällä hetkellä tueta.\n"
+
+#: elf32-mcore.c:428
+msgid "%B: Unknown relocation type %d\n"
+msgstr "%B: Tuntematon sijoitustyyppi %d\n"
+
+#. Pacify gcc -Wall.
+#: elf32-mep.c:157
+#, c-format
+msgid "mep: no reloc for code %d"
+msgstr "mep: ei reloc-tietuetta koodille %d"
+
+#: elf32-mep.c:163
+#, c-format
+msgid "MeP: howto %d has type %d"
+msgstr "MeP: kuinka tehdä -kohteella %d on tyyppi %d"
+
+#: elf32-mep.c:632
+msgid "%B and %B are for different cores"
+msgstr "%B ja %B ovat eri käyttöjärjestelmäytimille"
+
+#: elf32-mep.c:649
+msgid "%B and %B are for different configurations"
+msgstr "%B ja %B ovat eri konfiguraatioille"
+
+#: elf32-mep.c:686
+#, c-format
+msgid "private flags = 0x%lx"
+msgstr "yksityiset liput = 0x%lx"
+
+#: elf32-metag.c:1921
+msgid "%B(%A+0x%lx): R_METAG_TLS_LE/IENONPIC relocation not permitted in shared object"
+msgstr "%B(%A+0x%lx): R_METAG_TLS_LE/IENONPIC-sijoitukset eivät ole sallittuja jaetuissa objekteissa"
+
+#: elf32-microblaze.c:950
+#, c-format
+msgid "%s: unknown relocation type %d"
+msgstr "%s: tuntematon sijoitustyyppi %d"
+
+#: elf32-microblaze.c:1076 elf32-microblaze.c:1121
+#, c-format
+msgid "%s: The target (%s) of an %s relocation is in the wrong section (%s)"
+msgstr "%s: Kohteen (%s) sijoitus %s on väärässä lohkossa (%s)"
+
+#: elf32-microblaze.c:1484 elf32-tilepro.c:3320 elfxx-sparc.c:3526
+#: elfxx-tilegx.c:3729
+msgid "%B: probably compiled without -fPIC?"
+msgstr "%B: luultavasti käännetty ilman -fPIC-argumenttia?"
+
+#: elf32-mips.c:1670 elf64-mips.c:2990 elfn32-mips.c:2793
+msgid "literal relocation occurs for an external symbol"
+msgstr "literaali sijoitus tapahtuu ulkoiselle symbolille"
+
+#: elf32-mips.c:1717 elf32-score.c:570 elf32-score7.c:469 elf64-mips.c:3033
+#: elfn32-mips.c:2834
+msgid "32bits gp relative relocation occurs for an external symbol"
+msgstr "32-bittinen yleisosoitinsuhteellinen sijoitus tapahtuu ulkoiselle symbolille"
+
+#: elf32-msp430.c:801 elf32-msp430.c:1109
+msgid "Try enabling relaxation to avoid relocation truncations"
+msgstr "Yritä ottaa käyttöön avartaminen sijoituksen typistymisien välttämiseksi"
+
+#: elf32-msp430.c:1317
+msgid "internal error: branch/jump to an odd address detected"
+msgstr "sisäinen virhe: havaittu haarautuma/hyppy parittomaan"
+
+#: elf32-msp430.c:2221
+msgid "Warning: %B: Unknown MSPABI object attribute %d"
+msgstr "Varoitus: %B: Tuntematon MSPABI-objektiattribuutti %d"
+
+# Vector floating point (coprosessor)
+#: elf32-msp430.c:2312
+msgid "error: %B uses %s instructions but %B uses %s"
+msgstr "virhe: %B käyttää %s-käskyjä, mutta %B käyttää %s"
+
+#: elf32-msp430.c:2324
+msgid "error: %B uses the %s code model whereas %B uses the %s code model"
+msgstr "virhe: %B käyttää %s-koodimallia, kun taas %B käyttää %s-koodimallia"
+
+#: elf32-msp430.c:2336
+msgid "error: %B uses the large code model but %B uses MSP430 instructions"
+msgstr "virhe: %B käyttää laajaa koodimallia, mutta %B käyttää MSP430-käskyjä"
+
+#: elf32-msp430.c:2346
+msgid "error: %B uses the %s data model whereas %B uses the %s data model"
+msgstr "virhe: %B käyttää %s-datamallia, kun taas %B käyttää %s-datamallia"
+
+#: elf32-msp430.c:2358
+msgid "error: %B uses the small code model but %B uses the %s data model"
+msgstr "virhe: %B käyttää pientä koodimallia, mutta %B käyttää %s-datamallia"
+
+#: elf32-msp430.c:2369
+msgid "error: %B uses the %s data model but %B only uses MSP430 instructions"
+msgstr "virhe: %B käyttää %s-datamallia, mutta %B käyttää vain MSP430-käskyjä"
+
+#: elf32-nds32.c:2921
+msgid "error: Can't find symbol: _SDA_BASE_."
+msgstr "virhe: Symbolia ei löytynyt: _SDA_BASE_.â€"
+
+#: elf32-nds32.c:4142
+msgid "%B: error: unknown relocation type %d."
+msgstr "%B: virhe: tuntematon sijoitustyyppi %d."
+
+#: elf32-nds32.c:4584
+#, c-format
+msgid "%s: warning: cannot deal R_NDS32_25_ABS_RELA in shared mode."
+msgstr "%s: varoitus: R_NDS32_25_ABS_RELA-käsittely jaetussa objektissa epäonnistui."
+
+#: elf32-nds32.c:4716
+msgid "%B: warning: unaligned access to GOT entry."
+msgstr "%B: varoitus: tasaamaton pääsy yleissiirrostaulukohtaan."
+
+#: elf32-nds32.c:4758
+msgid "%B: warning: relocate SDA_BASE failed."
+msgstr "%B: varoitus: SDA_BASE-sijoitus epäonnistui."
+
+#: elf32-nds32.c:4779
+msgid "%B(%A): warning: unaligned small data access of type %d."
+msgstr "%B(%A): varoitus: tasaamaton %d-tyypin small data-pääsy."
+
+#: elf32-nds32.c:5446
+msgid "%B: ISR vector size mismatch with previous modules, previous %u-byte, current %u-byte"
+msgstr "%B: ISR-vektorikokotäsmäämättömyys edelliseen moduliin, edellinen %u-tavu, nykyinen %u-tavu"
+
+#: elf32-nds32.c:5489
+msgid "%B: warning: Endian mismatch with previous modules."
+msgstr "%B: varoitus: Endian-tavujärjestystäsmäämättömyys edellisiin moduleihin."
+
+#: elf32-nds32.c:5499
+msgid "%B: warning: Older version of object file encountered, Please recompile with current tool chain."
+msgstr "%B: varoitus: Objektitiedoston vanhempi versio kohdattu, käännä uudelleen nykyisellä työkaluketjulla."
+
+#: elf32-nds32.c:5577
+msgid "%B: error: ABI mismatch with previous modules."
+msgstr "%B: virhe: ABI-täsmäämättömyys edellisten modulien kanssa."
+
+#: elf32-nds32.c:5588
+msgid "%B: error: Instruction set mismatch with previous modules."
+msgstr "%B: virhe: Käskyjoukko ei täsmää edellisten modulien kanssa."
+
+#: elf32-nds32.c:5612
+msgid "%B: warning: Incompatible elf-versions %s and %s."
+msgstr "%B: varoitus: Yhteensopimattomat elf-versiot %s ja %s."
+
+#: elf32-nds32.c:5642
+#, c-format
+msgid ": n1 instructions"
+msgstr ": n1-käskyt"
+
+#: elf32-nds32.c:5645
+#, c-format
+msgid ": n1h instructions"
+msgstr ": n1h-käskyt"
+
+#: elf32-nds32.c:8147
+msgid "%B: %s\n"
+msgstr "%B: %s\n"
+
+#: elf32-nds32.c:8449
+msgid "%B(%A): warning: relax is suppressed for sections of alignment %d-bytes > 4-byte."
+msgstr "%B(%A): varoitus: relax on vaimennettu lohkoissa, joissa tasaus %d-tavua > 4-tavu."
+
+#: elf32-nds32.c:8502
+msgid "%B: error: Cannot set _ITB_BASE_"
+msgstr "%B: virhe: _ITB_BASE_-asetus epäonnistui"
+
+#: elf32-nds32.c:11384
+msgid "%B: Nested OMIT_FP in %A."
+msgstr "%B: Sisäkkäinen OMIT_FP kohteessa %A."
+
+#: elf32-nds32.c:11401
+msgid "%B: Unmatched OMIT_FP in %A."
+msgstr "%B: Täsmäämätön OMIT_FP kohteessa %A."
+
+#: elf32-nds32.c:13357
+msgid "Linker: cannot init ex9 hash table error \n"
+msgstr "Linkkeri: ex9-tiivistetauluvirheen alustus epäonnistui\n"
+
+#: elf32-nds32.c:13790 elf32-nds32.c:13804
+msgid "Linker: error cannot fixed ex9 relocation \n"
+msgstr "Linkkeri: virhe: ex9-sijoituksen korjaus epäonnistui\n"
+
+#: elf32-nds32.c:14015
+#, c-format
+msgid "%s: warning: unaligned small data access. For entry: {%d, %d, %d}, addr = 0x%x, align = 0x%x."
+msgstr "%s: varoitus: tasaamaton small data-pääsy. Kohde: {%d, %d, %d}, osoite = 0x%x, tasaus = 0x%x."
+
+#: elf32-nds32.c:14047
+msgid "%P%F: failed creating ex9.it %s hash table: %E\n"
+msgstr "%P%F: ex9.it %s-tiivistetaulun luominen epäonnistui: %E\n"
+
+#: elf32-nios2.c:2861
+#, c-format
+msgid "global pointer relative relocation at address 0x%08x when _gp not defined\n"
+msgstr "yleisosoitinsuhteellinen sijoitus osoitteessa 0x%08x kun _gp ei ole määritelty\n"
+
+#: elf32-nios2.c:2878
+#, c-format
+msgid "Unable to reach %s (at 0x%08x) from the global pointer (at 0x%08x) because the offset (%d) is out of the allowed range, -32678 to 32767.\n"
+msgstr "Kohteen %s (osoitteessa 0x%08x) tavoittaminen yleisosoittimesta epäonnistui (osoitteessa 0x%08x) koska siirrososoite (%d) on sallitun lukualueen -32678 ... 32767 ulkopuolella.\n"
+
+#: elf32-nios2.c:3392
+msgid "%B(%A+0x%lx): R_NIOS2_TLS_LE16 relocation not permitted in shared object"
+msgstr "%B(%A+0x%lx): R_NIOS2_TLS_LE16-sijoitus ei ole sallittu jaetussa objektissa"
+
+#: elf32-nios2.c:3520
+msgid "relocation out of range"
+msgstr "sijoitus lukualueen ulkopuolella"
+
+#: elf32-nios2.c:3530 elf32-tic6x.c:2744
+msgid "dangerous relocation"
+msgstr "vaarallinen sijoitus"
+
+#: elf32-nios2.c:4529
+#, c-format
+msgid "dynamic variable `%s' is zero size"
+msgstr "dynaaminen muuttuja â€%s†on nollakokoinen"
+
+#: elf32-ppc.c:2100
+#, c-format
+msgid "generic linker can't handle %s"
+msgstr "geneerinen linkkeri ei voi käsitellä kohdetta %s"
+
+#: elf32-ppc.c:2642
+msgid "corrupt %s section in %B"
+msgstr "rikkinäinen %s-lohko kohteessa %B"
+
+#: elf32-ppc.c:2661
+msgid "unable to read in %s section from %B"
+msgstr "ei voi lukea %s-lohkoon kohteesta %B"
+
+#: elf32-ppc.c:2702
+msgid "warning: unable to set size of %s section in %B"
+msgstr "varoitus: ei voi asettaa %s-lohkon kokoa kohteessa %B"
+
+#: elf32-ppc.c:2752
+msgid "failed to allocate space for new APUinfo section."
+msgstr "ei onnistuttu varaamaan muistitilaa uudelle APUinfo-lohkolle."
+
+#: elf32-ppc.c:2771
+msgid "failed to compute new APUinfo section."
+msgstr "ei onnistuttu laskemaan uutta APUinfo-lohkoa"
+
+#: elf32-ppc.c:2774
+msgid "failed to install new APUinfo section."
+msgstr "ei onnistuttu asentamaan uutta APUinfo-lohkoa"
+
+#: elf32-ppc.c:3844
+msgid "%B: relocation %s cannot be used when making a shared object"
+msgstr "%B: sijoitusta %s ei voi käyttää kun tehdään jaettua objektia"
+
+#. It does not make sense to have a procedure linkage
+#. table entry for a local symbol.
+#: elf32-ppc.c:4218
+msgid "%P: %H: %s reloc against local symbol\n"
+msgstr "%P: %H: %s reloc-tietue käyttäen paikallista symbolia\n"
+
+#: elf32-ppc.c:4299
+msgid "%P: %H: @local call to ifunc %s\n"
+msgstr "%P: %H: @local-kutsu kohteeseen ifunc %s\n"
+
+# Otaksun tässä että hard float tarkoittaa tässä muistipaikkaa (esim. rekisteriä), joka on varattu float-tyyppisille liukuluvuille
+#: elf32-ppc.c:4588 elf32-ppc.c:4603
+msgid "Warning: %B uses hard float, %B uses soft float"
+msgstr "Varoitus: %B käyttää laitteistoliukulukua, %B käyttää ohjelmistoliukulukua"
+
+# Otaksun tässä että hard float tarkoittaa tässä muistipaikkaa (esim. rekisteriä), joka on varattu float-tyyppisille liukuluvuille
+#: elf32-ppc.c:4591 elf32-ppc.c:4595
+msgid "Warning: %B uses double-precision hard float, %B uses single-precision hard float"
+msgstr "Varoitus: %B käyttää kaksoistarkkuuden laitteistoliukulukua, %B käyttää yksittäistarkkuuden laitteistoliukulukua"
+
+# Otaksun tässä että hard float tarkoittaa tässä muistipaikkaa (esim. rekisteriä), joka on varattu float-tyyppisille liukuluvuille
+#: elf32-ppc.c:4599
+msgid "Warning: %B uses soft float, %B uses single-precision hard float"
+msgstr "Varoitus: %B käyttää ohjelmistoliukulukua, %B käyttää yksittäistarkkuuden laitteistoliukulukua"
+
+#: elf32-ppc.c:4606 elf32-ppc.c:4610
+msgid "Warning: %B uses unknown floating point ABI %d"
+msgstr "Varoitus: %B käyttää tuntematonta liukuluku-ABI:a %d"
+
+#: elf32-ppc.c:4652 elf32-ppc.c:4656
+msgid "Warning: %B uses unknown vector ABI %d"
+msgstr "Varoitus: %B käyttää tuntematonta vektori-ABI:a %d"
+
+#: elf32-ppc.c:4660
+msgid "Warning: %B uses vector ABI \"%s\", %B uses \"%s\""
+msgstr "Varoitus: %B käyttää vektori-ABI:a â€%sâ€, %B käyttää â€%sâ€"
+
+#: elf32-ppc.c:4677 elf32-ppc.c:4680
+msgid "Warning: %B uses r3/r4 for small structure returns, %B uses memory"
+msgstr "Varoitus: %B käyttää r3/r4 pienille rakennepaluille, %B käyttää muistia"
+
+#: elf32-ppc.c:4683 elf32-ppc.c:4687
+msgid "Warning: %B uses unknown small structure return convention %d"
+msgstr "Varoitus: %B käyttää tuntematonta pientä rakennepaluusopimusta %d"
+
+#: elf32-ppc.c:4741
+msgid "%B: compiled with -mrelocatable and linked with modules compiled normally"
+msgstr "%B: käännetty â€-mrelocatableâ€-argumentilla ja linkitetty tavallisesti käännetyillä moduleilla"
+
+#: elf32-ppc.c:4749
+msgid "%B: compiled normally and linked with modules compiled with -mrelocatable"
+msgstr "%B: käännetty tavallisesti ja linkitetty moduleilla, jotka on käännetty â€-mrelocatableâ€-argumentilla"
+
+#: elf32-ppc.c:4872
+msgid "%P: bss-plt forced due to %B\n"
+msgstr "%P: bss-plt-argumentti pakotettu %B:n vuoksi\n"
+
+#: elf32-ppc.c:4875
+msgid "%P: bss-plt forced by profiling\n"
+msgstr "%P: profilointi pakotti bss-plt-argumentin\n"
+
+#. Uh oh, we didn't find the expected call. We
+#. could just mark this symbol to exclude it
+#. from tls optimization but it's safer to skip
+#. the entire optimization.
+#: elf32-ppc.c:5369 elf64-ppc.c:8371
+msgid "%H arg lost __tls_get_addr, TLS optimization disabled\n"
+msgstr "%H argumentti lost __tls_get_addr, TLS otimointi poistettu käytöstä\n"
+
+#: elf32-ppc.c:7927
+msgid "%P: %B: unknown relocation type %d for symbol %s\n"
+msgstr "%P: %B: tuntematon sijoitustyyppi %d symbolille %s\n"
+
+#: elf32-ppc.c:8191
+msgid "%P: %H: non-zero addend on %s reloc against `%s'\n"
+msgstr "%P: %H: ei-nolla-yhteenlaskettava %s reloc-tietueessa käyttäen symbolia â€%sâ€\n"
+
+#: elf32-ppc.c:8389
+msgid "%P: %H: relocation %s for indirect function %s unsupported\n"
+msgstr "%P: %H: sijoitusta %s epäsuoralle funktiolle %s ei tueta\n"
+
+#: elf32-ppc.c:8646 elf32-ppc.c:8676 elf32-ppc.c:8767
+msgid "%P: %B: the target (%s) of a %s relocation is in the wrong output section (%s)\n"
+msgstr "%P: %B: kohde (%s) sijoituksessa %s on väärässä tulostelohkossa (%s)\n"
+
+#: elf32-ppc.c:8854
+msgid "%B: the target (%s) of a %s relocation is in the wrong output section (%s)"
+msgstr "%B: kohde (%s) sijoituksessa %s on väärässä tulostelohkossa (%s)"
+
+#: elf32-ppc.c:8958
+msgid "%P: %B: relocation %s is not yet supported for symbol %s\n"
+msgstr "%P: %B: sijoitus %s ei ole vielä tuettu symbolille %s\n"
+
+#: elf32-ppc.c:9038
+msgid "%P: %H: error: %s against `%s' not a multiple of %u\n"
+msgstr "%P: %H: virhe: sijoitus %s käyttäen kohdetta â€%s†ei ole %u:n kerrannainen\n"
+
+#: elf32-ppc.c:9067
+msgid "%P: %H: unresolvable %s relocation against symbol `%s'\n"
+msgstr "%P: %H: ratkaisematon %s sijoitus käyttäen symbolia â€%sâ€\n"
+
+#: elf32-ppc.c:9114
+msgid "%P: %H: %s reloc against `%s': error %d\n"
+msgstr "%P: %H: %s reloc-tietue käyttäen kohdetta â€%sâ€: virhe %d\n"
+
+#: elf32-ppc.c:9750
+msgid "%P: %s not defined in linker created %s\n"
+msgstr "%P: %s ei ole määritelty linkkerissä luodussa %s\n"
+
+#: elf32-rl78.c:784
+msgid "Warning: RL78_SYM reloc with an unknown symbol"
+msgstr "Varoitus: RL78_SYM-reloc tuntemattomalla symbolilla"
+
+#: elf32-rl78.c:952 elf32-rx.c:1324
+msgid "%B(%A): error: call to undefined function '%s'"
+msgstr "%B(%A): virhe: kutsu määrittelemättömään funktioon ’%s’"
+
+#: elf32-rl78.c:966 elf32-rx.c:1338
+msgid "%B(%A): warning: unaligned access to symbol '%s' in the small data area"
+msgstr "%B(%A): varoitus: tasaamaton pääsy symboliin ’%s’ pienellä data-alueella"
+
+#: elf32-rl78.c:970 elf32-rx.c:1342
+msgid "%B(%A): internal error: out of range error"
+msgstr "%B(%A): sisäinen virhe: â€lukualueen ulkopuolellaâ€-virhe"
+
+#: elf32-rl78.c:974 elf32-rx.c:1346
+msgid "%B(%A): internal error: unsupported relocation error"
+msgstr "%B(%A): sisäinen virhe: ei-tuettu sijoitusvirhe"
+
+#: elf32-rl78.c:978 elf32-rx.c:1350
+msgid "%B(%A): internal error: dangerous relocation"
+msgstr "%B(%A): sisäinen virhe: vaarallinen sijoitus"
+
+#: elf32-rl78.c:982 elf32-rx.c:1354
+msgid "%B(%A): internal error: unknown error"
+msgstr "%B(%A): sisäinen virhe: tuntematon virhe"
+
+#: elf32-rl78.c:1043
+msgid "RL78/G10 ABI conflict: cannot link G10 and non-G10 objects together"
+msgstr "RL78/G10 ABI-ristiriita: G10 ja ei-G10-objektien linkittäminen yhteen epäonnistui"
+
+#: elf32-rl78.c:1046 elf32-rl78.c:1049
+#, c-format
+msgid "- %s is G10, %s is not"
+msgstr "- %s on G10, %s ei ole"
+
+#: elf32-rl78.c:1072
+#, c-format
+msgid " [G10]"
+msgstr " [G10]"
+
+#: elf32-rx.c:563
+msgid "%B:%A: Warning: deprecated Red Hat reloc "
+msgstr "%B:%A: Varoitus: vanhentunut Red Hat reloc -tietue "
+
+#. Check for unsafe relocs in PID mode. These are any relocs where
+#. an absolute address is being computed. There are special cases
+#. for relocs against symbols that are known to be referenced in
+#. crt0.o before the PID base address register has been initialised.
+#: elf32-rx.c:581
+msgid "%B(%A): unsafe PID relocation %s at 0x%08lx (against %s in %s)"
+msgstr "%B(%A): turvaton PID-sijoitus %s osoitteessa 0x%08lx (käyttäen symbolia %s kohteessa %s)"
+
+#: elf32-rx.c:1157
+msgid "Warning: RX_SYM reloc with an unknown symbol"
+msgstr "Varoitus: RX_SYM-reloc tuntemattomalla symbolilla"
+
+#: elf32-s390.c:2292 elf64-s390.c:2244
+msgid "%B(%A+0x%lx): invalid instruction for TLS relocation %s"
+msgstr "%B(%A+0x%lx): virheellinen käsky TLS-sijoitukselle %s"
+
+#: elf32-score.c:1520 elf32-score7.c:1379 elfxx-mips.c:3642
+msgid "not enough GOT space for local GOT entries"
+msgstr "ei tarpeeksi yleissiirrostaulutilaa paikallisille yleissiirrostaulutulokohdille"
+
+#: elf32-score.c:2742
+msgid "address not word align"
+msgstr "osoite ei ole word-tasattu"
+
+#: elf32-score.c:2827 elf32-score7.c:2631
+#, c-format
+msgid "%s: Malformed reloc detected for section %s"
+msgstr "%s: Väärän muotoinen reloc-tietue havaittu lohkolle %s"
+
+#: elf32-score.c:2882 elf32-score7.c:2686
+msgid "%B: CALL15 reloc at 0x%lx not against global symbol"
+msgstr "%B: CALL15 reloc-tietueessa osoitteessa 0x%lx ei ole käytetty yleissymbolia"
+
+#: elf32-score.c:4007 elf32-score7.c:3811
+#, c-format
+msgid " [pic]"
+msgstr " [paikkariippumaton koodi]"
+
+#: elf32-score.c:4011 elf32-score7.c:3815
+#, c-format
+msgid " [fix dep]"
+msgstr " [korjaussyvyys]"
+
+#: elf32-score.c:4053 elf32-score7.c:3857
+msgid "%B: warning: linking PIC files with non-PIC files"
+msgstr "%B: varoitus: linkitetään paikkariippumattomia kooditiedostoja paikkariippuvaisten kooditiedostojen kanssa"
+
+#: elf32-sh-symbian.c:130
+msgid "%B: IMPORT AS directive for %s conceals previous IMPORT AS"
+msgstr "%B: â€IMPORT ASâ€-direktiivi kohteelle %s kätkee edellisen â€IMPORT ASâ€-direktiivin"
+
+#: elf32-sh-symbian.c:383
+msgid "%B: Unrecognised .directive command: %s"
+msgstr "%B: Tunnistamaton â€.directiveâ€-komento: %s"
+
+#: elf32-sh-symbian.c:500
+msgid "%B: Failed to add renamed symbol %s"
+msgstr "%B: Ei onnistuttu lisäämään uudelleennimettyä symbolia %s"
+
+#: elf32-sh.c:569
+msgid "%B: 0x%lx: warning: bad R_SH_USES offset"
+msgstr "%B: 0x%lx: varoitus: virheellinen R_SH_USES-siirrososoite"
+
+#: elf32-sh.c:581
+msgid "%B: 0x%lx: warning: R_SH_USES points to unrecognized insn 0x%x"
+msgstr "%B: 0x%lx: varoitus: R_SH_USES osoittaa tunnistamattomaan käskyyn 0x%x"
+
+#: elf32-sh.c:598
+msgid "%B: 0x%lx: warning: bad R_SH_USES load offset"
+msgstr "%B: 0x%lx: varoitus: virheellinen R_SH_USES lataussiirrososoite"
+
+#: elf32-sh.c:613
+msgid "%B: 0x%lx: warning: could not find expected reloc"
+msgstr "%B: 0x%lx: varoitus: ei voitu löytää odotettua reloc-tietuetta"
+
+#: elf32-sh.c:641
+msgid "%B: 0x%lx: warning: symbol in unexpected section"
+msgstr "%B: 0x%lx: varoitus: symboli odottamattomassa lohkossa"
+
+#: elf32-sh.c:767
+msgid "%B: 0x%lx: warning: could not find expected COUNT reloc"
+msgstr "%B: 0x%lx: varoitus: ei voitu löytää odotettua â€COUNT relocâ€-tietuetta"
+
+#: elf32-sh.c:776
+msgid "%B: 0x%lx: warning: bad count"
+msgstr "%B: 0x%lx: varoitus: virheellinen lukumäärä"
+
+# Kun käskyoperandi on sen lukualueen ulkopuolella, joka sallitaan kullekin käskykentälle, assembler voi muuntaa koodin käyttämään toiminnallisesti samanlaista käskyä tai käskysekvenssiä. Tämä prosessi tunnetaan nimellä relaxation. Tätä tehdään tyypillisesti haarautumiskäskyissä, koska haarautumiskohteen etäisyyttä ei tunneta ennen linkitystä. Tavallaan tällä tavalla kumotaan lukualueen rajoitteet (constraints). Siksi olen suomentanut sen termillä avartaminen.
+#: elf32-sh.c:1180 elf32-sh.c:1550
+msgid "%B: 0x%lx: fatal: reloc overflow while relaxing"
+msgstr "%B: 0x%lx: vakava: reloc-tietue ylivuoto avartamisen aikana"
+
+#: elf32-sh.c:3939 elf64-sh64.c:1514
+msgid "Unexpected STO_SH5_ISA32 on local symbol is not handled"
+msgstr "Odottamatonta STO_SH5_ISA32 paikallisessa symbolissa ei käsitellä"
+
+# Kun käskyoperandi on sen lukualueen ulkopuolella, joka sallitaan kullekin käskykentälle, assembler voi muuntaa koodin käyttämään toiminnallisesti samanlaista käskyä tai käskysekvenssiä. Tämä prosessi tunnetaan nimellä relaxation. Tätä tehdään tyypillisesti haarautumiskäskyissä, koska haarautumiskohteen etäisyyttä ei tunneta ennen linkitystä. Tavallaan tällä tavalla kumotaan lukualueen rajoitteet (constraints). Siksi olen suomentanut sen termillä avartaminen.
+#: elf32-sh.c:4190
+msgid "%B: 0x%lx: fatal: unaligned branch target for relax-support relocation"
+msgstr "%B: 0x%lx: vakava: tasaamaton haarautumiskohde avarrustuetulle sijoitukselle"
+
+#: elf32-sh.c:4223 elf32-sh.c:4238
+msgid "%B: 0x%lx: fatal: unaligned %s relocation 0x%lx"
+msgstr "%B: 0x%lx: vakava: tasaamaton %s sijoitus 0x%lx"
+
+#: elf32-sh.c:4252
+msgid "%B: 0x%lx: fatal: R_SH_PSHA relocation %d not in range -32..32"
+msgstr "%B: 0x%lx: vakava: R_SH_PSHA-sijoitus %d ei ole lukualueella -32..32"
+
+#: elf32-sh.c:4266
+msgid "%B: 0x%lx: fatal: R_SH_PSHL relocation %d not in range -32..32"
+msgstr "%B: 0x%lx: vakava: R_SH_PSHL-sijoitus %d ei ole lukualueella -32..32"
+
+#: elf32-sh.c:4410 elf32-sh.c:4886
+msgid "%B(%A+0x%lx): cannot emit fixup to `%s' in read-only section"
+msgstr "%B(%A+0x%lx): ei voi lähettää korjauksia kohteeseen â€%s†kirjoitussuojatussa lohkossa"
+
+#: elf32-sh.c:4993
+msgid "%B(%A+0x%lx): %s relocation against external symbol \"%s\""
+msgstr "%B(%A+0x%lx): %s sijoitus käyttäen ulkoista symbolia â€%sâ€"
+
+#: elf32-sh.c:5466
+#, c-format
+msgid "%X%C: relocation to \"%s\" references a different segment\n"
+msgstr "%X%C: sijoitus kohteeseen â€%s†viittaa eri segmenttiin\n"
+
+#: elf32-sh.c:5472
+#, c-format
+msgid "%C: warning: relocation to \"%s\" references a different segment\n"
+msgstr "%C: varoitus: sijoitus kohteeseen â€%s†viittaa eri segmenttiin\n"
+
+#: elf32-sh.c:6254 elf32-sh.c:6337
+msgid "%B: `%s' accessed both as normal and FDPIC symbol"
+msgstr "%B: â€%s†haettu sekä normaalina että FDPIC-symbolina"
+
+#: elf32-sh.c:6259 elf32-sh.c:6341
+msgid "%B: `%s' accessed both as FDPIC and thread local symbol"
+msgstr "%B: â€%s†haettu sekä FDPIC-symbolina että säikeisenä paikallissymbolina"
+
+#: elf32-sh.c:6289
+msgid "%B: Function descriptor relocation with non-zero addend"
+msgstr "%B: Funktiokuvaajasijoitus nollasta poikeavalla yhteenlaskettavalla"
+
+#: elf32-sh.c:6525 elf64-alpha.c:4661
+msgid "%B: TLS local exec code cannot be linked into shared objects"
+msgstr "%B: TLS-tyyppistä paikallista suoritettavaa koodia ei voida linkittää jaettuihin objekteihin"
+
+#: elf32-sh64.c:224 elf64-sh64.c:2318
+#, c-format
+msgid "%s: compiled as 32-bit object and %s is 64-bit"
+msgstr "%s: käännetty 32-bittisenä objektina ja %s on 64-bittinen"
+
+#: elf32-sh64.c:227 elf64-sh64.c:2321
+#, c-format
+msgid "%s: compiled as 64-bit object and %s is 32-bit"
+msgstr "%s: käännetty 64-bittisenä objektina ja %s on 32-bittinen"
+
+#: elf32-sh64.c:229 elf64-sh64.c:2323
+#, c-format
+msgid "%s: object size does not match that of target %s"
+msgstr "%s: objektikoko ei täsmää kohteen %s objektikoon kanssa"
+
+#: elf32-sh64.c:452 elf64-sh64.c:2839
+#, c-format
+msgid "%s: encountered datalabel symbol in input"
+msgstr "%s: kohdattiin datalabel-symboli syötteessä"
+
+# prepare-to-branch (PTB) instruction
+#: elf32-sh64.c:529
+msgid "PTB mismatch: a SHmedia address (bit 0 == 1)"
+msgstr "PTB-täsmäämättömyys: SHmedia-osoite (bitti 0 == 1)"
+
+#: elf32-sh64.c:532
+msgid "PTA mismatch: a SHcompact address (bit 0 == 0)"
+msgstr "PTA-täsmäämättömyys: SHcompact-osoite (bitti 0 == 0)"
+
+#: elf32-sh64.c:550
+#, c-format
+msgid "%s: GAS error: unexpected PTB insn with R_SH_PT_16"
+msgstr "%s: GAS-virhe: odottamaton PTB-käsky R_SH_PT_16-tyypillä"
+
+#: elf32-sh64.c:599
+msgid "%B: error: unaligned relocation type %d at %08x reloc %p\n"
+msgstr "%B: virhe: tasaamaton sijoitustyyppi %d siirroksessa %08x reloc-tietue %p\n"
+
+#: elf32-sh64.c:675
+#, c-format
+msgid "%s: could not write out added .cranges entries"
+msgstr "%s: ei voitu kirjoittaa lisättyjä â€.crangesâ€-tulokohtia kokonaisuudessaan"
+
+#: elf32-sh64.c:735
+#, c-format
+msgid "%s: could not write out sorted .cranges entries"
+msgstr "%s: ei voitu kirjoittaa lajiteltuja â€.crangesâ€-tulokohtia kokonaisuudessaan"
+
+#: elf32-sparc.c:90
+msgid "%B: compiled for a 64 bit system and target is 32 bit"
+msgstr "%B: käännetty 64-bittiselle järjestelmälle ja kohde on 32-bittinen"
+
+#: elf32-sparc.c:103
+msgid "%B: linking little endian files with big endian files"
+msgstr "%B: linkitetty â€little endianâ€-tiedostoja â€big endianâ€-tiedostojen kanssa"
+
+#: elf32-spu.c:716
+msgid "%X%P: overlay section %A does not start on a cache line.\n"
+msgstr "%X%P: päällyslohko %A ei ala välimuistissa olevalta riviltä.\n"
+
+#: elf32-spu.c:724
+msgid "%X%P: overlay section %A is larger than a cache line.\n"
+msgstr "%X%P: päällyslohko %A on laajempi kuin välimuistissa oleva rivi.\n"
+
+#: elf32-spu.c:744
+msgid "%X%P: overlay section %A is not in cache area.\n"
+msgstr "%X%P: päällyslohko %A ei ole välimuistialueella.\n"
+
+#: elf32-spu.c:784
+msgid "%X%P: overlay sections %A and %A do not start at the same address.\n"
+msgstr "%X%P: päällyslohkot %A ja %A eivät ala samasta osoitteesta.\n"
+
+#: elf32-spu.c:1008
+msgid "warning: call to non-function symbol %s defined in %B"
+msgstr "varoitus: kutsu ei-funktiosymboliin %s määritelty kohteessa %B"
+
+#: elf32-spu.c:1358
+msgid "%A:0x%v lrlive .brinfo (%u) differs from analysis (%u)\n"
+msgstr "%A:0x%v lrlive .brinfo (%u) eroaa analyysistä (%u)\n"
+
+#: elf32-spu.c:1877
+msgid "%B is not allowed to define %s"
+msgstr "%B ei saa määritellä kohdetta %s"
+
+#: elf32-spu.c:1885
+#, c-format
+msgid "you are not allowed to define %s in a script"
+msgstr "et saa määritellä kohdetta %s skriptissä"
+
+#: elf32-spu.c:1919
+#, c-format
+msgid "%s in overlay section"
+msgstr "%s päällyslohkossa"
+
+#: elf32-spu.c:1948
+msgid "overlay stub relocation overflow"
+msgstr "päällys-stub-sijoitusylivuoto"
+
+#: elf32-spu.c:1957
+msgid "stubs don't match calculated size"
+msgstr "stubit ei täsmää lasketun koon kanssa"
+
+#: elf32-spu.c:2539
+#, c-format
+msgid "warning: %s overlaps %s\n"
+msgstr "varoitus: %s menee päällekkäin %s:n kanssa\n"
+
+#: elf32-spu.c:2555
+#, c-format
+msgid "warning: %s exceeds section size\n"
+msgstr "varoitus: %s ylittää lohkokoon\n"
+
+#: elf32-spu.c:2586
+msgid "%A:0x%v not found in function table\n"
+msgstr "%A:0x%v ei löytynyt funktiotaulusta\n"
+
+#: elf32-spu.c:2726
+msgid "%B(%A+0x%v): call to non-code section %B(%A), analysis incomplete\n"
+msgstr "%B(%A+0x%v): kutsu ei-koodilohkoon %B(%A), analyysi ei ole täydellinen\n"
+
+#: elf32-spu.c:3294
+#, c-format
+msgid "Stack analysis will ignore the call from %s to %s\n"
+msgstr "Pinoanalyysi ei ota huomioon kutsua kohteesta %s kohteeseen %s\n"
+
+#: elf32-spu.c:3985
+msgid " %s: 0x%v\n"
+msgstr " %s: 0x%v\n"
+
+#: elf32-spu.c:3986
+msgid "%s: 0x%v 0x%v\n"
+msgstr "%s: 0x%v 0x%v\n"
+
+#: elf32-spu.c:3991
+msgid " calls:\n"
+msgstr " kutsut:\n"
+
+#: elf32-spu.c:3999
+#, c-format
+msgid " %s%s %s\n"
+msgstr " %s%s %s\n"
+
+#: elf32-spu.c:4304
+#, c-format
+msgid "%s duplicated in %s\n"
+msgstr "%s kaksoiskappale kohteessa %s\n"
+
+#: elf32-spu.c:4308
+#, c-format
+msgid "%s duplicated\n"
+msgstr "%s on tehty kahteen kertaan\n"
+
+#: elf32-spu.c:4315
+msgid "sorry, no support for duplicate object files in auto-overlay script\n"
+msgstr "ei tukea objektitiedostojen kaksoiskappaleille automaattisessa päällysskriptissä\n"
+
+#: elf32-spu.c:4356
+msgid "non-overlay size of 0x%v plus maximum overlay size of 0x%v exceeds local store\n"
+msgstr "ei-päällyksen koko 0x%v plus päällyksen maksimikoko 0x%v ylittävät paikallisen varaston\n"
+
+#: elf32-spu.c:4511
+msgid "%B:%A%s exceeds overlay size\n"
+msgstr "%B:%A%s ylittää päällyskoon\n"
+
+#: elf32-spu.c:4673
+msgid "Stack size for call graph root nodes.\n"
+msgstr "Pinokoko kutsugraafijuurinodeille.\n"
+
+# Wikipedia: A tail call is a subroutine call just before the end of a subroutine.
+#: elf32-spu.c:4674
+msgid ""
+"\n"
+"Stack size for functions. Annotations: '*' max stack, 't' tail call\n"
+msgstr ""
+"\n"
+"Pinokoko funktioille. Sivuhuomautukset: â€*†maksimipino, â€t†alikutsu\n"
+
+#: elf32-spu.c:4684
+msgid "Maximum stack required is 0x%v\n"
+msgstr "Vaadittu maksimipino on 0x%v\n"
+
+#: elf32-spu.c:4775
+msgid "fatal error while creating .fixup"
+msgstr "vakava virhe kun luodaan .fixup"
+
+#: elf32-spu.c:5005
+msgid "%B(%s+0x%lx): unresolvable %s relocation against symbol `%s'"
+msgstr "%B(%s+0x%lx): ratkaisematon %s sijoitus käyttäen symbolia â€%sâ€"
+
+#: elf32-tic6x.c:1600
+msgid "warning: generating a shared library containing non-PIC code"
+msgstr "varoitus: tuotetaan jaettu kirjasto, joka sisältää ei-PIC-koodia"
+
+#: elf32-tic6x.c:1605
+msgid "warning: generating a shared library containing non-PID code"
+msgstr "varoitus: tuotetaan jaettu kirjasto, joka sisältää ei-PID-koodia"
+
+#: elf32-tic6x.c:2524
+msgid "%B: SB-relative relocation but __c6xabi_DSBT_BASE not defined"
+msgstr "%B: SB-suhteellinen sijoitus, mutta __c6xabi_DSBT_BASE ei ole määritelty"
+
+#: elf32-tic6x.c:3648
+msgid "%B: error: unknown mandatory EABI object attribute %d"
+msgstr "%B: virhe: tuntematon pakollinen EABI-objektiattribuutti %d"
+
+#: elf32-tic6x.c:3656
+msgid "%B: warning: unknown EABI object attribute %d"
+msgstr "%B: varoitus: tuntematon EABI-objektiattribuutti %d"
+
+#: elf32-tic6x.c:3768 elf32-tic6x.c:3776
+msgid "error: %B requires more stack alignment than %B preserves"
+msgstr "virhe: %B vaatii enemmän pinotasausta kuin %B säilyttää"
+
+#: elf32-tic6x.c:3786 elf32-tic6x.c:3795
+msgid "error: unknown Tag_ABI_array_object_alignment value in %B"
+msgstr "virhe: tuntematon Tag_ABI_array_object_alignment-arvo kohteessa %B"
+
+#: elf32-tic6x.c:3804 elf32-tic6x.c:3813
+msgid "error: unknown Tag_ABI_array_object_align_expected value in %B"
+msgstr "virhe: tuntematon Tag_ABI_array_object_align_expected-arvo kohteessa %B"
+
+#: elf32-tic6x.c:3821 elf32-tic6x.c:3828
+msgid "error: %B requires more array alignment than %B preserves"
+msgstr "virhe: %B vaatii enemmän taulukkotasausta kuin %B säilyttää"
+
+#: elf32-tic6x.c:3850
+msgid "warning: %B and %B differ in wchar_t size"
+msgstr "varoitus: %B ja %B eroavat wchar_t size-koossa"
+
+#: elf32-tic6x.c:3868
+msgid "warning: %B and %B differ in whether code is compiled for DSBT"
+msgstr "varoitus: %B ja %B eroavat siinä, että koodi on käännetty kohteelle DSBT"
+
+# small data region on sama kuin .scommon data region
+#: elf32-v850.c:157
+#, c-format
+msgid "Variable `%s' cannot occupy in multiple small data regions"
+msgstr "Muuttuja â€%s†ei voi sijaita useissa â€smallâ€-data-alueissa"
+
+# small on .scommon, zero on .zcommon ja tiny on .tcommon
+#: elf32-v850.c:160
+#, c-format
+msgid "Variable `%s' can only be in one of the small, zero, and tiny data regions"
+msgstr "Muuttuja â€%s†voi olla vain yhdessä â€smallâ€-, â€zeroâ€- ja â€tinyâ€-data-alueista"
+
+#: elf32-v850.c:163
+#, c-format
+msgid "Variable `%s' cannot be in both small and zero data regions simultaneously"
+msgstr "Muuttuja â€%s†ei voi olla sekä â€smallâ€- että â€zeroâ€-data-alueissa samanaikaisesti"
+
+#: elf32-v850.c:166
+#, c-format
+msgid "Variable `%s' cannot be in both small and tiny data regions simultaneously"
+msgstr "Muuttuja â€%s†ei voi olla sekä â€smallâ€- että â€tinyâ€-data-alueissa samanaikaisesti"
+
+#: elf32-v850.c:169
+#, c-format
+msgid "Variable `%s' cannot be in both zero and tiny data regions simultaneously"
+msgstr "Muuttuja â€%s†ei voi olla sekä â€zeroâ€- että â€tinyâ€-data-alueissa samanaikaisesti"
+
+#: elf32-v850.c:467
+msgid "FAILED to find previous HI16 reloc"
+msgstr "EI ONNISTUTTU löytämään edellistä HI16 reloc-tietuetta"
+
+#: elf32-v850.c:2293
+msgid "could not locate special linker symbol __gp"
+msgstr "ei voitu paikallistaa erityistä linkkerisymbolia â€__gpâ€"
+
+#: elf32-v850.c:2297
+msgid "could not locate special linker symbol __ep"
+msgstr "ei voitu paikallistaa erityistä linkkerisymbolia â€__epâ€"
+
+#: elf32-v850.c:2301
+msgid "could not locate special linker symbol __ctbp"
+msgstr "ei voitu paikallistaa erityistä linkkerisymbolia â€__ctbpâ€"
+
+#: elf32-v850.c:2471 elf32-v850.c:2534
+msgid "%B: Architecture mismatch with previous modules"
+msgstr "%B: Arkkitehtuuri ei täsmännyt edellisten modulien kanssa"
+
+#: elf32-v850.c:2478
+msgid "%B: Alignment mismatch with previous modules"
+msgstr "%B: Tasaustäsmäämättömyys edellisiin moduleihin"
+
+#. xgettext:c-format.
+#: elf32-v850.c:2553
+#, c-format
+msgid "private flags = %lx: "
+msgstr "yksityiset liput = %lx: "
+
+#: elf32-v850.c:2558
+#, c-format
+msgid "unknown v850 architecture"
+msgstr "tuntematon v850-arkkitehtuuri"
+
+#: elf32-v850.c:2560
+#, c-format
+msgid "v850 E3 architecture"
+msgstr "v850 E3-arkkitehtuuri"
+
+#: elf32-v850.c:2562 elf32-v850.c:2572
+#, c-format
+msgid "v850 architecture"
+msgstr "v850-arkkitehtuuri"
+
+#: elf32-v850.c:2565
+#, c-format
+msgid ", 8-byte data alignment"
+msgstr ", 8-tavuinen datatasaus"
+
+#: elf32-v850.c:2573
+#, c-format
+msgid "v850e architecture"
+msgstr "v850e-arkkitehtuuri"
+
+#: elf32-v850.c:2574
+#, c-format
+msgid "v850e1 architecture"
+msgstr "v850e1-arkkitehtuuri"
+
+#: elf32-v850.c:2575
+#, c-format
+msgid "v850e2 architecture"
+msgstr "v850e2-arkkitehtuuri"
+
+#: elf32-v850.c:2576
+#, c-format
+msgid "v850e2v3 architecture"
+msgstr "v850e2v3-arkkitehtuuri"
+
+#: elf32-v850.c:2577
+#, c-format
+msgid "v850e3v5 architecture"
+msgstr "v850e3v5-arkkitehtuuri"
+
+#: elf32-vax.c:532
+#, c-format
+msgid " [nonpic]"
+msgstr " [paikkariippuvaisen koodin lippu]"
+
+#: elf32-vax.c:535
+#, c-format
+msgid " [d-float]"
+msgstr " [d-float-liukulukulippu]"
+
+#: elf32-vax.c:538
+#, c-format
+msgid " [g-float]"
+msgstr " [g-float-liukulukulippu]"
+
+#: elf32-vax.c:656
+#, c-format
+msgid "%s: warning: GOT addend of %ld to `%s' does not match previous GOT addend of %ld"
+msgstr "%s: varoitus: Yleissiirrostaulun %ld-yhteenlaskettava kohteelle â€%s†ei täsmää edellisen yleissiirrostaulun %ld-yhteenlaskettavan kanssa"
+
+#: elf32-vax.c:1543
+#, c-format
+msgid "%s: warning: PLT addend of %d to `%s' from %s section ignored"
+msgstr "%s: varoitus: %d:n PLT-yhteenlaskettavaa kohteelle â€%s†lohkosta %s ei oteta huomioon"
+
+#: elf32-vax.c:1668
+#, c-format
+msgid "%s: warning: %s relocation against symbol `%s' from %s section"
+msgstr "%s: varoitus: %s sijoitus käyttäen symbolia â€%s†%s-lohkosta"
+
+#: elf32-vax.c:1674
+#, c-format
+msgid "%s: warning: %s relocation to 0x%x from %s section"
+msgstr "%s: varoitus: %s sijoitus kohteeseen 0x%x â€%sâ€-lohkosta"
+
+#: elf32-xgate.c:686
+#, c-format
+msgid "cpu=XGATE]"
+msgstr "cpu=XGATE]"
+
+#: elf32-xgate.c:688
+#, c-format
+msgid "error reading cpu type from elf private data"
+msgstr "virhe luettaessa prosessorityyppiä elf private-datasta"
+
+#: elf32-xstormy16.c:455 elf64-ia64-vms.c:2072 elf32-ia64.c:2330
+#: elf64-ia64.c:2330
+msgid "non-zero addend in @fptr reloc"
+msgstr "ei-nolla-yhteenlaskettava â€@fptr relocâ€-tietueessa"
+
+#: elf32-xtensa.c:908
+msgid "%B(%A): invalid property table"
+msgstr "%B(%A): virheellinen ominaisuustaulu"
+
+#: elf32-xtensa.c:2774
+msgid "%B(%A+0x%lx): relocation offset out of range (size=0x%x)"
+msgstr "%B(%A+0x%lx): sijoitussiirrososoite lukualueen (koko=0x%x) ulkopuolella"
+
+#: elf32-xtensa.c:2853 elf32-xtensa.c:2974
+msgid "dynamic relocation in read-only section"
+msgstr "dynaaminen sijoitus kirjoitussuojatussa lohkossa"
+
+#: elf32-xtensa.c:2950
+msgid "TLS relocation invalid without dynamic sections"
+msgstr "TLS-siirros virheellinen ilman dynaamisia lohkoja"
+
+#: elf32-xtensa.c:3169
+msgid "internal inconsistency in size of .got.loc section"
+msgstr "sisäinen epäjohdonmukaisuus â€.got.locâ€-alilohkokoossa"
+
+#: elf32-xtensa.c:3482
+msgid "%B: incompatible machine type. Output is 0x%x. Input is 0x%x"
+msgstr "%B: yhteensopimaton konetyyppi. Tuloste on 0x%x. Syöte on 0x%x"
+
+#: elf32-xtensa.c:4713 elf32-xtensa.c:4721
+msgid "Attempt to convert L32R/CALLX to CALL failed"
+msgstr "Yritys muuttaa â€L32R/CALLXâ€-kutsu â€CALLâ€-kutsuksi ei onnistunut"
+
+#: elf32-xtensa.c:6330 elf32-xtensa.c:6406 elf32-xtensa.c:7522
+msgid "%B(%A+0x%lx): could not decode instruction; possible configuration mismatch"
+msgstr "%B(%A+0x%lx): ei voitu avata käskyä; mahdollinen konfiguraatiotäsmäämättömyys"
+
+#: elf32-xtensa.c:7262
+msgid "%B(%A+0x%lx): could not decode instruction for XTENSA_ASM_SIMPLIFY relocation; possible configuration mismatch"
+msgstr "%B(%A+0x%lx): ei voitu avata käskyä XTENSA_ASM_SIMPLIFY-sijoitukselle; mahdollinen konfiguraatiotäsmäämättömyys"
+
+#: elf32-xtensa.c:9022
+msgid "invalid relocation address"
+msgstr "virheellinen sijoitusosoite"
+
+# Kun käskyoperandi on sen lukualueen ulkopuolella, joka sallitaan kullekin käskykentälle, assembler voi muuntaa koodin käyttämään toiminnallisesti samanlaista käskyä tai käskysekvenssiä. Tämä prosessi tunnetaan nimellä relaxation. Tätä tehdään tyypillisesti haarautumiskäskyissä, koska haarautumiskohteen etäisyyttä ei tunneta ennen linkitystä. Tavallaan tällä tavalla kumotaan lukualueen rajoitteet (constraints). Siksi olen suomentanut sen termillä avartaminen.
+#: elf32-xtensa.c:9071
+msgid "overflow after relaxation"
+msgstr "ylivuoto avartamisen jälkeen"
+
+#: elf32-xtensa.c:10203
+msgid "%B(%A+0x%lx): unexpected fix for %s relocation"
+msgstr "%B(%A+0x%lx): odottamaton korjaus %s-sijoitukselle"
+
+#: elf64-alpha.c:474
+msgid "GPDISP relocation did not find ldah and lda instructions"
+msgstr "GPDISP-sijoitus ei löytänyt â€ldahâ€- ja â€ldaâ€-käskyjä"
+
+#: elf64-alpha.c:2503
+msgid "%B: .got subsegment exceeds 64K (size %d)"
+msgstr "%B: â€.gotâ€-alisegmentti ylittää 64 kilotavun rajan (koko %d)"
+
+#: elf64-alpha.c:4396 elf64-alpha.c:4408
+msgid "%B: gp-relative relocation against dynamic symbol %s"
+msgstr "%B: yleisosoitinsuhteellinen sijoitus käyttäen dynaamista symbolia %s"
+
+#: elf64-alpha.c:4434 elf64-alpha.c:4574
+msgid "%B: pc-relative relocation against dynamic symbol %s"
+msgstr "%B: ohjelmalaskurisuhteellinen sijoitus käyttäen dynaamista symbolia %s"
+
+#: elf64-alpha.c:4462
+msgid "%B: change in gp: BRSGP %s"
+msgstr "%B: vaihto yleisosoittimessa: BRSGP %s"
+
+#: elf64-alpha.c:4487
+msgid "<unknown>"
+msgstr "<tuntematon>"
+
+#: elf64-alpha.c:4492
+msgid "%B: !samegp reloc against symbol without .prologue: %s"
+msgstr "%B: â€!samegp relocâ€-tietue käyttäen symbolia ilman â€.prologueâ€-lohkoa: %s"
+
+#: elf64-alpha.c:4549
+msgid "%B: unhandled dynamic relocation against %s"
+msgstr "%B: käsittelemätön dynaaminen sijoitus käyttäen kohdetta %s"
+
+#: elf64-alpha.c:4581
+msgid "%B: pc-relative relocation against undefined weak symbol %s"
+msgstr "%B: ohjelmalaskurisuhteellinen sijoitus käyttäen määrittelemätöntä heikkoa symbolia %s"
+
+#: elf64-alpha.c:4645
+msgid "%B: dtp-relative relocation against dynamic symbol %s"
+msgstr "%B: dtp-suhteellinen sijoitus käyttäen dynaamista symbolia %s"
+
+#: elf64-alpha.c:4668
+msgid "%B: tp-relative relocation against dynamic symbol %s"
+msgstr "%B: tp-suhteellinen sijoitus käyttäen dynaamista symbolia %s"
+
+#: elf64-hppa.c:2084
+#, c-format
+msgid "stub entry for %s cannot load .plt, dp offset = %ld"
+msgstr "stub-tulokohta kohteelle %s ei voi ladata â€.pltâ€, dp-siirrososoite = %ld"
+
+#: elf64-hppa.c:3280
+msgid "%B(%A+0x%"
+msgstr "%B(%A+0x%"
+
+# Kun käskyoperandi on sen lukualueen ulkopuolella, joka sallitaan kullekin käskykentälle, assembler voi muuntaa koodin käyttämään toiminnallisesti samanlaista käskyä tai käskysekvenssiä. Tämä prosessi tunnetaan nimellä relaxation. Tätä tehdään tyypillisesti haarautumiskäskyissä, koska haarautumiskohteen etäisyyttä ei tunneta ennen linkitystä. Tavallaan tällä tavalla kumotaan lukualueen rajoitteet (constraints). Siksi olen suomentanut sen termillä avartaminen.
+#: elf64-ia64-vms.c:587 elf32-ia64.c:619 elf64-ia64.c:619
+msgid "%B: Can't relax br at 0x%lx in section `%A'. Please use brl or indirect branch."
+msgstr "%B: Ei voi avartaa br-käskyä kohteessa 0x%lx lohkossa â€%Aâ€. Käytä â€brlâ€-käskyä tai epäsuoraa haarautumista."
+
+#: elf64-ia64-vms.c:2027 elf32-ia64.c:2278 elf64-ia64.c:2278
+msgid "@pltoff reloc against local symbol"
+msgstr "â€@pltoff relocâ€-tietue käyttäen paikallista symbolia"
+
+#: elf64-ia64-vms.c:3279 elf32-ia64.c:3684 elf64-ia64.c:3684
+#, c-format
+msgid "%s: short data segment overflowed (0x%lx >= 0x400000)"
+msgstr "%s: â€shortâ€-datasegmentti ylivuotanut (0x%lx >= 0x400000)"
+
+#: elf64-ia64-vms.c:3290 elf32-ia64.c:3695 elf64-ia64.c:3695
+#, c-format
+msgid "%s: __gp does not cover short data segment"
+msgstr "%s: â€__gp†ei kata â€shortâ€-datasegmenttiä"
+
+#: elf64-ia64-vms.c:3555 elf32-ia64.c:3962 elf64-ia64.c:3962
+msgid "%B: non-pic code with imm relocation against dynamic symbol `%s'"
+msgstr "%B: paikkariippuvainen koodi välittömällä sijoituksella käyttäen dynaamista symbolia â€%sâ€"
+
+#: elf64-ia64-vms.c:3617 elf32-ia64.c:4029 elf64-ia64.c:4029
+msgid "%B: @gprel relocation against dynamic symbol %s"
+msgstr "%B: â€@gprelâ€-sijoitus käyttäen dynaamista symbolia %s"
+
+#: elf64-ia64-vms.c:3676 elf32-ia64.c:4092 elf64-ia64.c:4092
+msgid "%B: linking non-pic code in a position independent executable"
+msgstr "%B: linkitetään paikkariippuvainen koodi paikkariippumattomassa suoritettavassa tiedostossa"
+
+#: elf64-ia64-vms.c:3777 elf32-ia64.c:4229 elf64-ia64.c:4229
+msgid "%B: @internal branch to dynamic symbol %s"
+msgstr "%B: @sisäinen haarautuminen dynaamiseen symboliin %s"
+
+#: elf64-ia64-vms.c:3779 elf32-ia64.c:4231 elf64-ia64.c:4231
+msgid "%B: speculation fixup to dynamic symbol %s"
+msgstr "%B: spekulaatiokorjaus dynaamiseen symboliin %s"
+
+#: elf64-ia64-vms.c:3781 elf32-ia64.c:4233 elf64-ia64.c:4233
+msgid "%B: @pcrel relocation against dynamic symbol %s"
+msgstr "%B: â€@pcrelâ€-sijoitus käyttäen dynaamista symbolia %s"
+
+#: elf64-ia64-vms.c:3905 elf32-ia64.c:4430 elf64-ia64.c:4430
+msgid "unsupported reloc"
+msgstr "ei-tuettu reloc-tietue"
+
+#: elf64-ia64-vms.c:3942 elf32-ia64.c:4468 elf64-ia64.c:4468
+msgid "%B: missing TLS section for relocation %s against `%s' at 0x%lx in section `%A'."
+msgstr "%B: siirroksen %s puuttuva TLS-lohko käyttäen kohdetta â€%s†osoitteessa 0x%lx lohkossa â€%Aâ€."
+
+# Kun käskyoperandi on sen lukualueen ulkopuolella, joka sallitaan kullekin käskykentälle, assembler voi muuntaa koodin käyttämään toiminnallisesti samanlaista käskyä tai käskysekvenssiä. Tämä prosessi tunnetaan nimellä relaxation. Tätä tehdään tyypillisesti haarautumiskäskyissä, koska haarautumiskohteen etäisyyttä ei tunneta ennen linkitystä. Tavallaan tällä tavalla kumotaan lukualueen rajoitteet (constraints). Siksi olen suomentanut sen termillä avartaminen.
+#: elf64-ia64-vms.c:3957 elf32-ia64.c:4483 elf64-ia64.c:4483
+msgid "%B: Can't relax br (%s) to `%s' at 0x%lx in section `%A' with size 0x%lx (> 0x1000000)."
+msgstr "%B: Ei voi avartaa br-käskyä (%s) kohteelle â€%s†kohteessa 0x%lx lohkossa â€%A†koolla 0x%lx (> 0x1000000)."
+
+#: elf64-ia64-vms.c:4246 elf32-ia64.c:4745 elf64-ia64.c:4745
+msgid "%B: linking trap-on-NULL-dereference with non-trapping files"
+msgstr "%B: linkitetään keskeytysnollassa purkuviite â€ei-keskeytetäâ€-tiedostojen kanssa"
+
+#: elf64-ia64-vms.c:4255 elf32-ia64.c:4754 elf64-ia64.c:4754
+msgid "%B: linking big-endian files with little-endian files"
+msgstr "%B: linkitetään â€big-endianâ€-tiedostoja â€little-endianâ€-tiedostojen kanssa"
+
+#: elf64-ia64-vms.c:4264 elf32-ia64.c:4763 elf64-ia64.c:4763
+msgid "%B: linking 64-bit files with 32-bit files"
+msgstr "%B: linkitetään 64-bittiset tiedostot 32-bittisten tiedostojen kanssa"
+
+#: elf64-ia64-vms.c:4273 elf32-ia64.c:4772 elf64-ia64.c:4772
+msgid "%B: linking constant-gp files with non-constant-gp files"
+msgstr "%B: linkitetään vakioyleisosoitintiedostot ei-vakioiden yleisosoitintiedostojen kanssa"
+
+#: elf64-ia64-vms.c:4283 elf32-ia64.c:4782 elf64-ia64.c:4782
+msgid "%B: linking auto-pic files with non-auto-pic files"
+msgstr "%B: linkitetään automaattiset paikkariippumattomat kooditiedostot ei-automaattisten paikkariippumattomien kooditiedostojen kanssa"
+
+#: elf64-ia64-vms.c:5125 elflink.c:4299
+msgid "Warning: alignment %u of common symbol `%s' in %B is greater than the alignment (%u) of its section %A"
+msgstr "Varoitus: tasaus %u yhteissymbolissa â€%s†kohteessa %B on suurempi kuin tasaus (%u) sen lohkossa %A"
+
+#: elf64-ia64-vms.c:5131 elflink.c:4305
+msgid "Warning: alignment %u of symbol `%s' in %B is smaller than %u in %B"
+msgstr "Varoitus: tasaus %u symbolissa â€%s†kohteessa %B on pienempi kuin %u kohteessa %B"
+
+#: elf64-ia64-vms.c:5146 elflink.c:4321
+msgid "Warning: size of symbol `%s' changed from %lu in %B to %lu in %B"
+msgstr "Varoitus: symbolin â€%s†koko vaihtui koosta %lu kohteessa %B kokoon %lu kohteessa %B"
+
+#: elf64-mmix.c:986
+msgid ""
+"invalid input relocation when producing non-ELF, non-mmo format output.\n"
+" Please use the objcopy program to convert from ELF or mmo,\n"
+" or assemble using \"-no-expand\" (for gcc, \"-Wa,-no-expand\""
+msgstr ""
+"virheellinen syötesijoitus kun tuotetaan ei-ELF, ei-mmo-muotoinen tuloste.\n"
+" Käytä objcopy-ohjelmaa muuntamiseen ELF:stä tai mmo:sta,\n"
+" tai assembloi käyttäen \"-no-expand\" (gcc-kääntäjälle, \"-Wa,-no-expand\""
+
+#: elf64-mmix.c:1170
+msgid ""
+"invalid input relocation when producing non-ELF, non-mmo format output.\n"
+" Please use the objcopy program to convert from ELF or mmo,\n"
+" or compile using the gcc-option \"-mno-base-addresses\"."
+msgstr ""
+"virheellinen syötesijoitus kun tuotetaan ei-ELF, ei-mmo-muotoinen tuloste.\n"
+" Käytä objcopy-ohjelmaa muuntamiseen ELF:stä tai mmo:sta,\n"
+" tai käännä käyttäen gcc-valitsinta \"-mno-base-addresses\"."
+
+# Kun käskyoperandi on sen lukualueen ulkopuolella, joka sallitaan kullekin käskykentälle, assembler voi muuntaa koodin käyttämään toiminnallisesti samanlaista käskyä tai käskysekvenssiä. Tämä prosessi tunnetaan nimellä relaxation. Tätä tehdään tyypillisesti haarautumiskäskyissä, koska haarautumiskohteen etäisyyttä ei tunneta ennen linkitystä. Tavallaan tällä tavalla kumotaan lukualueen rajoitteet (constraints). Siksi olen suomentanut sen termillä avartaminen.
+#: elf64-mmix.c:1196
+#, c-format
+msgid ""
+"%s: Internal inconsistency error for value for\n"
+" linker-allocated global register: linked: 0x%lx%08lx != relaxed: 0x%lx%08lx\n"
+msgstr ""
+"%s: Sisäinen yhteensopimattomuusvirhe linkkerin varaamalle\n"
+" yleisrekisteriarvolle: linkitetty: 0x%lx%08lx != avarrettu: 0x%lx%08lx\n"
+
+#: elf64-mmix.c:1618
+#, c-format
+msgid "%s: base-plus-offset relocation against register symbol: (unknown) in %s"
+msgstr "%s: â€base-plus-offsetâ€-sijoitus käyttäen rekisterisymbolia: (tuntematon) kohteessa %s"
+
+#: elf64-mmix.c:1623
+#, c-format
+msgid "%s: base-plus-offset relocation against register symbol: %s in %s"
+msgstr "%s: â€base-plus-offsetâ€-sijoitus käyttäen rekisterisymbolia: %s kohteessa %s"
+
+#: elf64-mmix.c:1667
+#, c-format
+msgid "%s: register relocation against non-register symbol: (unknown) in %s"
+msgstr "%s: rekisterisijoitus käyttäen ei-rekisterisymbolia: (tuntematon) kohteessa %s"
+
+#: elf64-mmix.c:1672
+#, c-format
+msgid "%s: register relocation against non-register symbol: %s in %s"
+msgstr "%s: rekisterisijoitus käyttäen ei-rekisterisymbolia: %s kohteessa %s"
+
+#: elf64-mmix.c:1709
+#, c-format
+msgid "%s: directive LOCAL valid only with a register or absolute value"
+msgstr "%s: direktiivi LOCAL on oikea vain rekisterissä tai absoluuttiarvona"
+
+#: elf64-mmix.c:1739
+#, c-format
+msgid "%s: LOCAL directive: Register $%ld is not a local register. First global register is $%ld."
+msgstr "%s: LOCAL-direktiivi: Rekisteri $%ld ei ole paikallinen rekisteri. Ensimmäinen yleisrekisteri on $%ld."
+
+#: elf64-mmix.c:2198
+#, c-format
+msgid "%s: Error: multiple definition of `%s'; start of %s is set in a earlier linked file\n"
+msgstr "%s: Virhe: useita â€%sâ€-määrittelyjä; %s-alku on asetettu aiemmin linkitetyssä tiedostossa\n"
+
+#: elf64-mmix.c:2252
+msgid "Register section has contents\n"
+msgstr "Rekisterilohkossa on sisältö\n"
+
+#: elf64-mmix.c:2441
+#, c-format
+msgid ""
+"Internal inconsistency: remaining %u != max %u.\n"
+" Please report this bug."
+msgstr ""
+"Sisäinen yhteensopimattomuus: jäljelle jäävä %u != maksimi %u.\n"
+" Ilmoita ohjelmistovioista (englanniksi) osoitteeseen http://sourceware.org/bugzilla/."
+
+#: elf64-ppc.c:4463
+msgid "%P: %B: cannot create stub entry %s\n"
+msgstr "%P: %B: ei voi luoda stub-tulokohtaa %s\n"
+
+#: elf64-ppc.c:4810
+msgid "%P: symbol '%s' has invalid st_other for ABI version 1\n"
+msgstr "%P: symboli ’%s’ on virheellinen st_other ABI-versiolle 1\n"
+
+#: elf64-ppc.c:5170
+msgid "%P: .opd not allowed in ABI version %d\n"
+msgstr "%P: .opd ei ole sallittu ABI-versiossa %d\n"
+
+#: elf64-ppc.c:5809
+msgid "%B uses unknown e_flags 0x%lx"
+msgstr "%B käyttää tuntematonta e_flags 0x%lx"
+
+#: elf64-ppc.c:5816
+msgid "%B: ABI version %ld is not compatible with ABI version %ld output"
+msgstr "%B: ABI-versio %ld ei ole yhteensopiva ABI-version %ld tulosteen kanssa"
+
+#: elf64-ppc.c:5843
+#, c-format
+msgid " [abiv%ld]"
+msgstr " [abiv%ld]"
+
+#: elf64-ppc.c:7007
+msgid "%P: copy reloc against `%T' requires lazy plt linking; avoid setting LD_BIND_NOW=1 or upgrade gcc\n"
+msgstr "%P: kopio-reloc-tietue käyttäen â€%Tâ€:ta vaatii laiskan plt-linkityksen; vältä asettamasta LD_BIND_NOW=1 tai päivitä gcc\n"
+
+#: elf64-ppc.c:7270
+msgid "%B: undefined symbol on R_PPC64_TOCSAVE relocation"
+msgstr "%B: määrittelemätön symboli R_PPC64_TOCSAVE-sijoituksessa"
+
+#: elf64-ppc.c:7499
+msgid "%P: dynreloc miscount for %B, section %A\n"
+msgstr "%P: dynreloc-väärinlaskenta kohteelle %B, lohko %A\n"
+
+#: elf64-ppc.c:7583
+msgid "%B: .opd is not a regular array of opd entries"
+msgstr "%B: â€.opd†ei ole säännönmukainen opd-tulokohtien taulukko"
+
+#: elf64-ppc.c:7592
+msgid "%B: unexpected reloc type %u in .opd section"
+msgstr "%B: odottamaton reloc-tyyppi %u â€.opdâ€-lohkossa"
+
+#: elf64-ppc.c:7613
+msgid "%B: undefined sym `%s' in .opd section"
+msgstr "%B: määrittelemätön symboli â€%s†â€.opdâ€-lohkossa"
+
+#: elf64-ppc.c:8177
+msgid "%H __tls_get_addr lost arg, TLS optimization disabled\n"
+msgstr "%H __tls_get_addr kadotti argumentin, TLS-optimointi otettu pois käytöstä\n"
+
+#: elf64-ppc.c:8516 elf64-ppc.c:9139
+#, c-format
+msgid "%s defined on removed toc entry"
+msgstr "%s määritelty poistetussa sisällysluettelotulokohdassa"
+
+#: elf64-ppc.c:8868
+msgid "%P: %H: toc optimization is not supported for %s instruction.\n"
+msgstr "%P: %B: tulokohtasisällysluettelo-optimointia ei tueta %s-käskylle.\n"
+
+#: elf64-ppc.c:9096
+msgid "%P: %H: %s references optimized away TOC entry\n"
+msgstr "%P: %H: %s-viitteet optimoitu pois tulokohtasisällysluettelossa\n"
+
+#: elf64-ppc.c:10394
+msgid "%P: cannot find opd entry toc for `%T'\n"
+msgstr "%P: opd-kohdan tulokohtasisällysluettelon löytäminen kohteelle â€%T†epäonnistui\n"
+
+#: elf64-ppc.c:10479
+msgid "%P: long branch stub `%s' offset overflow\n"
+msgstr "%P: pitkä haarautumis-stub â€%s†siirrososoitteen ylivuoto\n"
+
+#: elf64-ppc.c:10538
+msgid "%P: can't find branch stub `%s'\n"
+msgstr "%P: ei löydy haarautumis-stub-kohdetta â€%sâ€\n"
+
+#: elf64-ppc.c:10602 elf64-ppc.c:10749 elf64-ppc.c:12416
+msgid "%P: linkage table error against `%T'\n"
+msgstr "%P: linkitystauluvirhe käyttäen kohdetta â€%Tâ€\n"
+
+#: elf64-ppc.c:10940
+msgid "%P: can't build branch stub `%s'\n"
+msgstr "%P: ei voi muodostaa haaroitus-stub-kohdetta â€%sâ€\n"
+
+#: elf64-ppc.c:11748
+msgid "%B section %A exceeds stub group size"
+msgstr "%B lohko %A ylittää stub-ryhmäkoon"
+
+#: elf64-ppc.c:12662 elf64-ppc.c:12697
+msgid "%P: %s offset too large for .eh_frame sdata4 encoding"
+msgstr "%P: %s-siirrososoite liian suuri kohteelle .eh_frame sdata4 encoding"
+
+#: elf64-ppc.c:12758
+msgid "%P: stubs don't match calculated size\n"
+msgstr "%P: stubit ei täsmää lasketun koon kanssa\n"
+
+#: elf64-ppc.c:12770
+#, c-format
+msgid ""
+"linker stubs in %u group%s\n"
+" branch %lu\n"
+" toc adjust %lu\n"
+" long branch %lu\n"
+" long toc adj %lu\n"
+" plt call %lu\n"
+" plt call toc %lu"
+msgstr ""
+"linkkeristubit %u-ryhmä%s:ssä\n"
+" haarautuminen %lu\n"
+" sisältöluettelosäätö %lu\n"
+" pitkä haarautuminen %lu\n"
+" pitkä sisältöluettelosäätö %lu\n"
+" plt-kutsu %lu\n"
+" plt-kutsusisältöluettelo %lu"
+
+# TLS: transport layer security
+#: elf64-ppc.c:13096
+msgid "%P: %H: %s used with TLS symbol `%T'\n"
+msgstr "%P: %H: %s käytetään TLS-symbolin â€%T†kanssa\n"
+
+#: elf64-ppc.c:13097
+msgid "%P: %H: %s used with non-TLS symbol `%T'\n"
+msgstr "%P: %H: %s käytetään ei-TLS-symbolin â€%T†kanssa\n"
+
+#: elf64-ppc.c:13675
+msgid "%P: %H: call to `%T' lacks nop, can't restore toc; recompile with -fPIC\n"
+msgstr "%P: %H: â€%Tâ€-kutsusta puuttuu nop, tulokohtasisältöluetteloa ei voi palauttaa; käännä uudelleen valitsimella -fPIC\n"
+
+#: elf64-ppc.c:13793
+msgid "%P: %B: unknown relocation type %d for `%T'\n"
+msgstr "%P: %B: tuntematon sijoitustyyppi %d symbolille â€%Tâ€\n"
+
+#: elf64-ppc.c:14310
+msgid "%P: %H: %s for indirect function `%T' unsupported\n"
+msgstr "%P: %H: %s epäsuoralle funktiolle â€%T†ei tueta\n"
+
+#: elf64-ppc.c:14417
+msgid "%P: %B: %s is not supported for `%T'\n"
+msgstr "%P: %B: %s ei ole tuettu kohteelle â€%Tâ€\n"
+
+#: elf64-ppc.c:14565
+msgid "%P: %H: error: %s not a multiple of %u\n"
+msgstr "%P: %H: virhe: sijoitus %s ei ole %u:n kerrannainen\n"
+
+#: elf64-ppc.c:14586
+msgid "%P: %H: unresolvable %s against `%T'\n"
+msgstr "%P: %H: ratkaisematon %s käyttäen kohdetta â€%Tâ€\n"
+
+#: elf64-ppc.c:14644
+msgid "%P: %H: %s against `%T': error %d\n"
+msgstr "%P: %H: %s käyttäen kohdetta â€%Tâ€: virhe %d\n"
+
+#: elf64-sh64.c:1686
+#, c-format
+msgid "%s: error: unaligned relocation type %d at %08x reloc %08x\n"
+msgstr "%s: virhe: tasaamaton sijoitustyyppi %d kohteessa %08x reloc-tietue %08x\n"
+
+#: elf64-sparc.c:446
+msgid "%B: Only registers %%g[2367] can be declared using STT_REGISTER"
+msgstr "%B: Vain rekisterit %%g[2367] voidaan esitellä käyttäen STT_REGISTER-symbolia"
+
+#: elf64-sparc.c:466
+msgid "Register %%g%d used incompatibly: %s in %B, previously %s in %B"
+msgstr "Rekisteriä %%g%d käytetty yhteensopimattomasti: %s kohteessa %B, aikaisemmin %s kohteessa %B"
+
+#: elf64-sparc.c:489
+msgid "Symbol `%s' has differing types: REGISTER in %B, previously %s in %B"
+msgstr "Symbolissa â€%s†on eri tyyppejä: REGISTER kohteessa %B, aiemmin %s kohteessa %B"
+
+#: elf64-sparc.c:534
+msgid "Symbol `%s' has differing types: %s in %B, previously REGISTER in %B"
+msgstr "Symbolissa â€%s†on eri tyyppejä: %s kohteessa %B, aiemmin REGISTER kohteessa %B"
+
+#: elf64-sparc.c:687
+msgid "%B: linking UltraSPARC specific with HAL specific code"
+msgstr "%B: linkitetään UltraSPARC-kohtainen HAL-kohtaisella koodilla"
+
+#: elf64-x86-64.c:1530
+msgid "%B: relocation %s against symbol `%s' isn't supported in x32 mode"
+msgstr "%B: sijoitusta %s käyttäen symbolia `%s' ei tueta x32-tilassa"
+
+#: elf64-x86-64.c:1688
+msgid "%B: '%s' accessed both as normal and thread local symbol"
+msgstr "%B: â€%s†kutsuttu sekä normaalina että säikeisenä paikallissymbolina"
+
+#: elf64-x86-64.c:3405 /src/binutils-gdb/bfd/elfnn-aarch64.c:3511
+msgid "%B: relocation %s against STT_GNU_IFUNC symbol `%s' has non-zero addend: %d"
+msgstr "%B: sijoituksella %s käyttäen kohteen STT_GNU_IFUNC-symbolia â€%s†on ei-nolla-yhteenlaskettava: %d"
+
+#: elf64-x86-64.c:3667
+msgid "%B: relocation R_X86_64_GOTOFF64 against protected function `%s' can not be used when making a shared object"
+msgstr "%B: sijoitusta R_X86_64_GOTOFF64 käyttäen suojattua funktiota â€%s†ei voida käyttää kun tehdään jaettua objektia"
+
+#: elf64-x86-64.c:3787
+msgid "; recompile with -fPIC"
+msgstr "; käännetty uudelleen -fPIC-parametrillä"
+
+#: elf64-x86-64.c:3792
+msgid "%B: relocation %s against %s `%s' can not be used when making a shared object%s"
+msgstr "%B: sijoitusta %s käyttäen kohdetta %s â€%s†ei voi käyttää kun tehdään jaettua objektia %s"
+
+#: elf64-x86-64.c:3794
+msgid "%B: relocation %s against undefined %s `%s' can not be used when making a shared object%s"
+msgstr "%B: sijoitusta %s käyttäen kohdetta %s â€%s†ei voi käyttää kun tehdään jaettua objektia %s"
+
+#: elf64-x86-64.c:3900
+msgid "%B: addend -0x%x in relocation %s against symbol `%s' at 0x%lx in section `%A' is out of range"
+msgstr "%B: yhteenlaskettava -0x%x sijoituksessa %s käyttäen symbolia â€%s†osoitteessa 0x%lx lohkossa â€%A†on lukualueen ulkopuolella"
+
+#: elf64-x86-64.c:3908
+msgid "%B: addend 0x%x in relocation %s against symbol `%s' at 0x%lx in section `%A' is out of range"
+msgstr "%B: yhteenlaskettava 0x%x sijoituksessa %s käyttäen symbolia â€%s†osoitteessa 0x%lx lohkossa â€%A†on lukualueen ulkopuolella"
+
+#: elfcode.h:760
+#, c-format
+msgid "warning: %s has a corrupt string table index - ignoring"
+msgstr "varoitus: %s:ssa on rikkinäinen merkkijonotauluindeksi - ei oteta huomioon"
+
+#: elfcode.h:1186
+#, c-format
+msgid "%s: version count (%ld) does not match symbol count (%ld)"
+msgstr "%s: versiolukumäärä (%ld) ei täsmää symbolilukumäärän (%ld) kanssa"
+
+#: elfcode.h:1440
+#, c-format
+msgid "%s(%s): relocation %d has invalid symbol index %ld"
+msgstr "%s(%s): sijoituksessa %d on virheellinen symboli-indeksi %ld"
+
+#: elfcore.h:305
+msgid "Warning: %B is truncated: expected core file size >= %lu, found: %lu."
+msgstr "Varoitus: %B typistettiin: odotettu käyttöjärjestelmäydintiedoston koko >= %lu, löytyi: %lu."
+
+#: elflink.c:1143
+msgid "%s: TLS definition in %B section %A mismatches non-TLS definition in %B section %A"
+msgstr "%s: TLS-määrittely kohteessa %B lohko %A ei täsmää ei-TLS-määrittelyn kanssa kohteessa %B lohko %A"
+
+#: elflink.c:1148
+msgid "%s: TLS reference in %B mismatches non-TLS reference in %B"
+msgstr "%s: TLS-viite kohteessa %B ei täsmää ei-TLS-viitteen kanssa kohteessa %B"
+
+#: elflink.c:1153
+msgid "%s: TLS definition in %B section %A mismatches non-TLS reference in %B"
+msgstr "%s: TLS-määrittely kohteessa %B lohko %A ei täsmää ei-TLS-viitteen kanssa kohteessa %B"
+
+#: elflink.c:1158
+msgid "%s: TLS reference in %B mismatches non-TLS definition in %B section %A"
+msgstr "%s: TLS-viite kohteessa %B ei täsmää ei-TLS-määrittelyn kanssa kohteessa %B lohko %A"
+
+#: elflink.c:1763
+msgid "%B: unexpected redefinition of indirect versioned symbol `%s'"
+msgstr "%B: epäsuoran versioidun symbolin â€%s†odottamaton uudelleenmäärittely"
+
+#: elflink.c:2066
+msgid "%B: version node not found for symbol %s"
+msgstr "%B: versiosolmua ei löydetty symbolille %s"
+
+#: elflink.c:2157
+msgid "%B: bad reloc symbol index (0x%lx >= 0x%lx) for offset 0x%lx in section `%A'"
+msgstr "%B: virheellinen reloc-tietuesymboli-indeksi (0x%lx >= 0x%lx) siirrososoitteelle 0x%lx lohkossa â€%Aâ€"
+
+#: elflink.c:2168
+msgid "%B: non-zero symbol index (0x%lx) for offset 0x%lx in section `%A' when the object file has no symbol table"
+msgstr "%B: ei-nolla symboli-indeksi (0x%lx) siirrososoitetta 0x%lx varten lohkossa â€%A†kun objektitiedostolla ei ole symbolitaulua"
+
+#: elflink.c:2358
+msgid "%B: relocation size mismatch in %B section %A"
+msgstr "%B: sijoituskokotäsmäämättömyys %B:n tulolohkossa %A"
+
+#: elflink.c:2640
+#, c-format
+msgid "warning: type and size of dynamic symbol `%s' are not defined"
+msgstr "varoitus: dynaamisen symbolin â€%s†tyyppi ja koko ei ole määritelty"
+
+# USA:ssa alternate-sanaa käytetään yleisesti, kun tarkoitetaan alternative.
+#: elflink.c:3403
+msgid "%P: alternate ELF machine code found (%d) in %B, expecting %d\n"
+msgstr "%P: vaihtoehtoinen ELF-konekoodi löydetty (%d) kohteessa %B, otetaan %d\n"
+
+#: elflink.c:4032
+msgid "%B: %s: invalid version %u (max %d)"
+msgstr "%B: %s: virheellinen versio %u (maksimi %d)"
+
+#: elflink.c:4068
+msgid "%B: %s: invalid needed version %d"
+msgstr "%B: %s: virheellinen tarvittu versio %d"
+
+#: elflink.c:4452
+msgid "%B: undefined reference to symbol '%s'"
+msgstr "%B: määrittelemätön viite symboliin ’%s’"
+
+#: elflink.c:5523
+msgid "%B: stack size specified and %s set"
+msgstr "%B: pinokoko määritelty ja %s asetettu"
+
+#: elflink.c:5526
+msgid "%B: %s not absolute"
+msgstr "%B: ei ole absoluuttinen"
+
+#: elflink.c:5824
+#, c-format
+msgid "%s: undefined version: %s"
+msgstr "%s: määrittelemätön versio: %s"
+
+#: elflink.c:5892
+msgid "%B: .preinit_array section is not allowed in DSO"
+msgstr "%B: â€.preinit_arrayâ€-lohkoa ei sallita kohteessa DSO"
+
+#: elflink.c:7657
+#, c-format
+msgid "undefined %s reference in complex symbol: %s"
+msgstr "määrittelemätön %s-viite kompleksisymbolissa: %s"
+
+#: elflink.c:7811
+#, c-format
+msgid "unknown operator '%c' in complex symbol"
+msgstr "tuntematon operaattori â€%c†kompleksisymbolissa"
+
+#: elflink.c:8165 elflink.c:8182 elflink.c:8219 elflink.c:8236
+msgid "%B: Unable to sort relocs - they are in more than one size"
+msgstr "%B: Ei voi lajitella relocs-tietueita - niitä on useampia kuin yhtä kokoa"
+
+#: elflink.c:8196 elflink.c:8250
+msgid "%B: Unable to sort relocs - they are of an unknown size"
+msgstr "%B: Ei voi lajitella relocs-tietueita - niiden koko on tuntematon"
+
+#: elflink.c:8301
+msgid "Not enough memory to sort relocations"
+msgstr "Ei tarpeeksi muistia sijoitusten lajittelemiseen"
+
+#: elflink.c:8494
+msgid "%B: Too many sections: %d (>= %d)"
+msgstr "%B: Liian monia lohkoja: %d (>= %d)"
+
+#: elflink.c:8775
+msgid "%B: internal symbol `%s' in %B is referenced by DSO"
+msgstr "%B: sisäinen symboli â€%s†kohteessa %B on DSO:n viitteenä"
+
+#: elflink.c:8777
+msgid "%B: hidden symbol `%s' in %B is referenced by DSO"
+msgstr "%B: piilotettu symboli â€%s†kohteessa %B on DSO:n viitteenä"
+
+#: elflink.c:8779
+msgid "%B: local symbol `%s' in %B is referenced by DSO"
+msgstr "%B: paikallinen symboli â€%s†kohteessa %B on DSO:n viitteenä"
+
+#: elflink.c:8890
+msgid "%B: could not find output section %A for input section %A"
+msgstr "%B: ei löytynyt tulostelohkoa %A syötelohkolle %A"
+
+#: elflink.c:9013
+msgid "%B: protected symbol `%s' isn't defined"
+msgstr "%B: suojattua symbolia â€%s†ei ole määritelty"
+
+#: elflink.c:9015
+msgid "%B: internal symbol `%s' isn't defined"
+msgstr "%B: sisäistä symbolia â€%s†ei ole määritelty"
+
+#: elflink.c:9017
+msgid "%B: hidden symbol `%s' isn't defined"
+msgstr "%B: piilotettua symbolia â€%s†ei ole määritelty"
+
+#: elflink.c:9043
+msgid "%B: No symbol version section for versioned symbol `%s'"
+msgstr "%B: Ei symboliversiolohkoa versioidulle symbolille â€%sâ€"
+
+#: elflink.c:9598
+msgid "error: %B: size of section %A is not multiple of address size"
+msgstr "virhe: %B: lohkon %A koko ei ole osoitekoon kerrannainen"
+
+#: elflink.c:9645
+msgid "error: %B contains a reloc (0x%s) for section %A that references a non-existent global symbol"
+msgstr "virhe: %B sisältää reloc-tietueen (0x%s) lohkolle %A, joka viittaa puuttuvaan yleissymboliin"
+
+#: elflink.c:10369
+msgid "%A has both ordered [`%A' in %B] and unordered [`%A' in %B] sections"
+msgstr "%A:ssa on sekä järjestettyjä [â€%A†kohteessa %B] että järjestämättömiä [â€%A†kohteessa %B] lohkoja"
+
+#: elflink.c:10374
+#, c-format
+msgid "%A has both ordered and unordered sections"
+msgstr "%A:ssa on sekä järjestettyjä että järjestämättömiä lohkoja"
+
+#: elflink.c:10982
+msgid "%B: file class %s incompatible with %s"
+msgstr "%B: tiedostoluokka %s on yhteensopimaton kohteen %s kanssa"
+
+#: elflink.c:11303 elflink.c:11347
+msgid "%B: could not find output section %s"
+msgstr "%B: ei löytynyt tulostelohkoa %s"
+
+#: elflink.c:11308
+#, c-format
+msgid "warning: %s section has zero size"
+msgstr "varoitus: %s-lohkossa on nollakoko"
+
+#: elflink.c:11353
+#, c-format
+msgid "warning: section '%s' is being made into a note"
+msgstr "varoitus: lohkosta â€%s†on tehty note-lohko"
+
+#: elflink.c:11419
+msgid "%P%X: read-only segment has dynamic relocations.\n"
+msgstr "%P%X: kirjoitussuojatussa segmentissä on dynaamisia sijoituksia.\n"
+
+#: elflink.c:11422
+msgid "%P: warning: creating a DT_TEXTREL in a shared object.\n"
+msgstr "%P: varoitus: luodaan DT_TEXTREL-tunniste jaetussa objektissa.\n"
+
+#: elflink.c:11545
+msgid "%P%X: can not read symbols: %E\n"
+msgstr "%P%X: ei voi lukea symboleja: %E\n"
+
+#: elflink.c:11989
+msgid "Removing unused section '%s' in file '%B'"
+msgstr "Poistetaan käyttämätön lohko â€%s†tiedostossa â€%Bâ€"
+
+#: elflink.c:12200
+msgid "Warning: gc-sections option ignored"
+msgstr "Varoitus: â€gc-sectionsâ€-valitsinta ei oteta huomioon"
+
+#: elflink.c:12489
+#, c-format
+msgid "Unrecognized INPUT_SECTION_FLAG %s\n"
+msgstr "Tunnistamaton INPUT_SECTION_FLAG %s\n"
+
+#: elfxx-mips.c:1419
+msgid "static procedure (no name)"
+msgstr "staattinen proseduuri (ei nimeä)"
+
+#: elfxx-mips.c:5476
+msgid "MIPS16 and microMIPS functions cannot call each other"
+msgstr "MIPS16- ja microMIPS-funktiot eivät voi kutsua toisiaan"
+
+#: elfxx-mips.c:6087
+msgid "%B: %A+0x%lx: Unsupported jump between ISA modes; consider recompiling with interlinking enabled."
+msgstr "%B: %A+0x%lx: Tukematon hyppy ISA-tilojen välillä; harkitse uudelleenkääntämistä käyttäen yhteislinkitystä."
+
+#: elfxx-mips.c:6756 elfxx-mips.c:6979
+msgid "%B: Warning: bad `%s' option size %u smaller than its header"
+msgstr "%B: Varoitus: virheellinen â€%sâ€-valitsinkoko %u pienempi kuin sen otsake"
+
+#: elfxx-mips.c:7734 elfxx-mips.c:7859
+msgid "%B: Warning: cannot determine the target function for stub section `%s'"
+msgstr "%B: Varoitus: ei voi määritellä stub-lohkon â€%s†kohdefunktiota"
+
+#: elfxx-mips.c:7990
+msgid "%B: Malformed reloc detected for section %s"
+msgstr "%B: Muodoltaan virheellinen reloc-tietue havaittu lohkossa %s"
+
+#: elfxx-mips.c:8065
+msgid "%B: GOT reloc at 0x%lx not expected in executables"
+msgstr "%B: Yleissiirrostaulu-reloc-tietue siirroksessa 0x%lx ei ole odotettu suoritettavissa tiedostoissa"
+
+#: elfxx-mips.c:8199
+msgid "%B: CALL16 reloc at 0x%lx not against global symbol"
+msgstr "%B: â€CALL16 relocâ€-tietueessa siirroksessa 0x%lx ei ole käytetty yleissymbolia"
+
+#: elfxx-mips.c:8977
+#, c-format
+msgid "non-dynamic relocations refer to dynamic symbol %s"
+msgstr "ei-dynaaminen sijoitus viittaa dynaamiseen symboliin %s"
+
+#: elfxx-mips.c:9877
+msgid "%B: Can't find matching LO16 reloc against `%s' for %s at 0x%lx in section `%A'"
+msgstr "%B: Ei löydy täsmäävää â€LO16 relocâ€-tietuetta käyttäen tulolohkoa â€%s†symbolinimelle %s kohteessa 0x%lx lohkossa â€%Aâ€"
+
+#: elfxx-mips.c:10016
+msgid "small-data section exceeds 64KB; lower small-data size limit (see option -G)"
+msgstr "â€smallâ€-datalohko ylittää 64 kilotavua; alenna â€smallâ€-datalohkon kokorajaa (katso valitsin -G)"
+
+#: elfxx-mips.c:10035
+msgid "JALX to a non-word-aligned address"
+msgstr "JALX word-tasaamattomaan osoitteeseen"
+
+#: elfxx-mips.c:10402 elfxx-mips.c:10966
+msgid "%B: `%A' offset of %ld from `%A' beyond the range of ADDIUPC"
+msgstr "%B: â€%A†%ld-siirrosoiste kohteesta â€%A†ADDIUPC-lukualueen takana"
+
+#: elfxx-mips.c:13990
+#, c-format
+msgid "%s: illegal section name `%s'"
+msgstr "%s: virheellinen lohkonimi â€%sâ€"
+
+#: elfxx-mips.c:14375 elfxx-mips.c:14381 elfxx-mips.c:14387 elfxx-mips.c:14407
+#: elfxx-mips.c:14413 elfxx-mips.c:14419 elfxx-mips.c:14441 elfxx-mips.c:14460
+#: elfxx-mips.c:14467 elfxx-mips.c:14474
+msgid "Warning: %B uses %s (set by %B), %B uses %s"
+msgstr "Varoitus: %B käyttää %s (asettaja: %B), %B käyttää %s"
+
+#: elfxx-mips.c:14394 elfxx-mips.c:14426 elfxx-mips.c:14447 elfxx-mips.c:14480
+msgid "Warning: %B uses %s (set by %B), %B uses unknown floating point ABI %d"
+msgstr "Varoitus: %B käyttää %s (asettaja: %B), %B käyttää tuntematonta liukuluku-ABI:a %d"
+
+#: elfxx-mips.c:14493 elfxx-mips.c:14501 elfxx-mips.c:14509 elfxx-mips.c:14517
+msgid "Warning: %B uses unknown floating point ABI %d (set by %B), %B uses %s"
+msgstr "Varoitus: %B käyttää tuntematonta liukuluku-ABI:a %d (asettaja: %B), %B käyttää %s"
+
+#: elfxx-mips.c:14525
+msgid "Warning: %B uses unknown floating point ABI %d (set by %B), %B uses unknown floating point ABI %d"
+msgstr "Varoitus: %B käyttää tuntematonta liukuluku-ABI:a %d (asettaja: %B), %B käyttää tuntematonta liukuluku-ABI:a %d"
+
+#: elfxx-mips.c:14548
+msgid "Warning: %B uses %s (set by %B), %B uses unknown MSA ABI %d"
+msgstr "Varoitus: %B käyttää %s (asettaja: %B), %B käyttää tuntematonta MSA ABI:a %d"
+
+#: elfxx-mips.c:14559
+msgid "Warning: %B uses unknown MSA ABI %d (set by %B), %B uses %s"
+msgstr "Varoitus: %B käyttää tuntematonta MSA ABI:a %d (asettaja: %B), %B käyttää %s"
+
+#: elfxx-mips.c:14567
+msgid "Warning: %B uses unknown MSA ABI %d (set by %B), %B uses unknown MSA ABI %d"
+msgstr "Varoitus: %B käyttää tuntematonta MSA ABI:a %d (asettaja: %B), %B käyttää tuntematonta MSA ABI:a %d"
+
+#: elfxx-mips.c:14599
+msgid "%B: endianness incompatible with that of the selected emulation"
+msgstr "%B: tavujärjestys tyypiltään sopimaton valitun emuloinnin tavujärjestystyypin kanssa"
+
+#: elfxx-mips.c:14610
+msgid "%B: ABI is incompatible with that of the selected emulation"
+msgstr "%B: ABI ei ole yhteensopiva valitun emuloinnin ABIn kanssa"
+
+#: elfxx-mips.c:14694
+msgid "%B: warning: linking abicalls files with non-abicalls files"
+msgstr "%B: varoitus: linkitetään abi-kutsutiedostoja ei-abi-kutsutiedostoihin"
+
+#: elfxx-mips.c:14711
+msgid "%B: linking 32-bit code with 64-bit code"
+msgstr "%B: linkitetään 32-bittinen koodi 64-bittisen koodin kanssa"
+
+#: elfxx-mips.c:14739 elfxx-mips.c:14802
+msgid "%B: linking %s module with previous %s modules"
+msgstr "%B: linkitetään %s-moduli edellisten %s-modulien kanssa"
+
+#: elfxx-mips.c:14762
+msgid "%B: ABI mismatch: linking %s module with previous %s modules"
+msgstr "%B: ABI-täsmäämättömyys: linkitetään %s-moduli edellisten %s-modulien kanssa"
+
+#: elfxx-mips.c:14786
+msgid "%B: ASE mismatch: linking %s module with previous %s modules"
+msgstr "%B: ASE-täsmäämättömyys: linkitetään %s-moduli edellisten %s-modulien kanssa"
+
+#: elfxx-mips.c:14958
+#, c-format
+msgid " [abi=O32]"
+msgstr " [abi=O32]"
+
+#: elfxx-mips.c:14960
+#, c-format
+msgid " [abi=O64]"
+msgstr " [abi=O64]"
+
+#: elfxx-mips.c:14962
+#, c-format
+msgid " [abi=EABI32]"
+msgstr " [abi=EABI32]"
+
+#: elfxx-mips.c:14964
+#, c-format
+msgid " [abi=EABI64]"
+msgstr " [abi=EABI64]"
+
+#: elfxx-mips.c:14966
+#, c-format
+msgid " [abi unknown]"
+msgstr " [abi tuntematon]"
+
+#: elfxx-mips.c:14968
+#, c-format
+msgid " [abi=N32]"
+msgstr " [abi=N32]"
+
+#: elfxx-mips.c:14970
+#, c-format
+msgid " [abi=64]"
+msgstr " [abi=64]"
+
+#: elfxx-mips.c:14972
+#, c-format
+msgid " [no abi set]"
+msgstr " [ei abia asetettu]"
+
+#: elfxx-mips.c:14993
+#, c-format
+msgid " [unknown ISA]"
+msgstr " [tuntematon ISA]"
+
+#: elfxx-mips.c:15013
+#, c-format
+msgid " [not 32bitmode]"
+msgstr " [ei 32-bittitila]"
+
+#: elfxx-sparc.c:640
+#, c-format
+msgid "invalid relocation type %d"
+msgstr "virheellinen sijoitustyyppi %d"
+
+#: elfxx-tilegx.c:4433
+msgid "%B: Cannot link together %s and %s objects."
+msgstr "%B: Ei voida linkittää yhteen %s- ja %s-objekteja."
+
+#: i386linux.c:418 m68klinux.c:421 sparclinux.c:414
+#, c-format
+msgid "Output file requires shared library `%s'\n"
+msgstr "Tulostetiedosto vaatii jaetun kirjaston â€%sâ€\n"
+
+#: i386linux.c:426 m68klinux.c:429 sparclinux.c:422
+#, c-format
+msgid "Output file requires shared library `%s.so.%s'\n"
+msgstr "Tulostetiedosto vaatii jaetun kirjaston â€%s.so.%sâ€\n"
+
+#: i386linux.c:613 i386linux.c:663 m68klinux.c:618 m68klinux.c:666
+#: sparclinux.c:609 sparclinux.c:659
+#, c-format
+msgid "Symbol %s not defined for fixups\n"
+msgstr "Symbolia %s ei ole määritelty korjauksia varten\n"
+
+#: i386linux.c:687 m68klinux.c:690 sparclinux.c:683
+msgid "Warning: fixup count mismatch\n"
+msgstr "Varoitus: korjauslukumäärän täsmäämättömyys\n"
+
+#: ieee.c:158
+#, c-format
+msgid "%s: string too long (%d chars, max 65535)"
+msgstr "%s: merkkijono on liian pitkä (%d merkkiä, maksimi 65535)"
+
+#: ieee.c:285
+#, c-format
+msgid "%s: unrecognized symbol `%s' flags 0x%x"
+msgstr "%s: tunnistamaton symboli â€%s†liput 0x%x"
+
+#: ieee.c:791
+msgid "%B: unimplemented ATI record %u for symbol %u"
+msgstr "%B: toteuttamaton ATI-tietue %u symbolille %u"
+
+#: ieee.c:815
+msgid "%B: unexpected ATN type %d in external part"
+msgstr "%B: odottamaton ATN-tyyppi %d ulkoisessa osassa"
+
+#: ieee.c:837
+msgid "%B: unexpected type after ATN"
+msgstr "%B: odottamaton tyyppi ATN:n jälkeen"
+
+#: ihex.c:230
+msgid "%B:%d: unexpected character `%s' in Intel Hex file"
+msgstr "%B:%d: odottamaton merkki â€%s†Intel-heksatiedostossa"
+
+#: ihex.c:337
+msgid "%B:%u: bad checksum in Intel Hex file (expected %u, found %u)"
+msgstr "%B:%u: virheellinen tarkistussumma Intel-heksatiedostossa (odotettiin %u, löydettiin %u)"
+
+#: ihex.c:392
+msgid "%B:%u: bad extended address record length in Intel Hex file"
+msgstr "%B:%u: virheellinen laajennettu osoitetietuepituus Intel-heksatiedostossa"
+
+#: ihex.c:409
+msgid "%B:%u: bad extended start address length in Intel Hex file"
+msgstr "%B:%u: virheellinen laajennettu aloitusosoitepituus Intel-heksatiedostossa"
+
+#: ihex.c:426
+msgid "%B:%u: bad extended linear address record length in Intel Hex file"
+msgstr "%B:%u: virheellinen laajennettu lineaariosoitetietuepituus Intel-heksatiedosto"
+
+#: ihex.c:443
+msgid "%B:%u: bad extended linear start address length in Intel Hex file"
+msgstr "%B:%u: virheellinen laajennettu lineaarialkuosoitepituus Intel-heksatiedostossa"
+
+#: ihex.c:460
+msgid "%B:%u: unrecognized ihex type %u in Intel Hex file"
+msgstr "%B:%u: tunnistamaton ihex-tyyppi %u Intel-heksatiedostossa"
+
+#: ihex.c:579
+msgid "%B: internal error in ihex_read_section"
+msgstr "%B: sisäinen virhe â€ihex_read_sectionâ€-lohkossa"
+
+#: ihex.c:613
+msgid "%B: bad section length in ihex_read_section"
+msgstr "%B: virheellinen lohkopituus â€ihex_read_sectionâ€-lohkossa"
+
+#: ihex.c:826
+#, c-format
+msgid "%s: address 0x%s out of range for Intel Hex file"
+msgstr "%s: osoite 0x%s lukualueen ulkopuolella Intel-heksatiedostolle"
+
+#: libbfd.c:863
+msgid "%B: unable to get decompressed section %A"
+msgstr "%B: ei kyetä hakemaan tiivistyksestä purettua lohkoa %A"
+
+#: libbfd.c:1012
+msgid "%B: compiled for a big endian system and target is little endian"
+msgstr "%B: käännetty â€big endianâ€-järjestelmälle ja kohde on â€little endianâ€"
+
+#: libbfd.c:1014
+msgid "%B: compiled for a little endian system and target is big endian"
+msgstr "%B: käännetty â€little endianâ€-järjestelmälle ja kohde on â€big endianâ€"
+
+#: libbfd.c:1043
+#, c-format
+msgid "Deprecated %s called at %s line %d in %s\n"
+msgstr "Käytöstä poistettu %s kutsuttiin tiedostossa %s rivillä %d funktiossa %s\n"
+
+#: libbfd.c:1046
+#, c-format
+msgid "Deprecated %s called\n"
+msgstr "Käytöstä poistettu %s kutsuttu\n"
+
+#: linker.c:1873
+msgid "%B: indirect symbol `%s' to `%s' is a loop"
+msgstr "%B: epäsuora symboli â€%s†kohteeseen â€%s†on silmukka"
+
+#: linker.c:2750
+#, c-format
+msgid "Attempt to do relocatable link with %s input and %s output"
+msgstr "Yritettiin tehdä sijoitettava linkki %s-syötteellä ja %s-tulosteella"
+
+#: linker.c:3035
+msgid "%B: ignoring duplicate section `%A'\n"
+msgstr "%B: ei oteta huomioon lohkon â€%A†kaksoiskappaletta\n"
+
+#: linker.c:3044 linker.c:3053
+msgid "%B: duplicate section `%A' has different size\n"
+msgstr "%B: lohkon â€%A†kaksoiskappaleessa on eri koko\n"
+
+#: linker.c:3061 linker.c:3066
+msgid "%B: could not read contents of section `%A'\n"
+msgstr "%B: ei voitu lukea lohkon â€%A†sisältöä\n"
+
+#: linker.c:3070
+msgid "%B: duplicate section `%A' has different contents\n"
+msgstr "%B: lohkon â€%A†kaksoiskappaleella on erilainen sisältö\n"
+
+#: mach-o.c:648
+msgid "bfd_mach_o_canonicalize_symtab: unable to load symbols"
+msgstr "bfd_mach_o_canonicalize_symtab: ei kyetä lataamaan symboleja"
+
+#: mach-o.c:1918
+#, c-format
+msgid "mach-o: there are too many sections (%d) maximum is 255,\n"
+msgstr "mach-o: liian monta lohkoa (%d) maksimi on 255,\n"
+
+#: mach-o.c:2017
+#, c-format
+msgid "unable to write unknown load command 0x%lx"
+msgstr "ei kyetä kirjoittamaan tuntematonta lataa-komentoa 0x%lx"
+
+#: mach-o.c:2272
+msgid "sorry: modtab, toc and extrefsyms are not yet implemented for dysymtab commands."
+msgstr "valitettavasti modtab, toc ja extrefsyms ei ole vielä toteutettu dysymtab-komennoille."
+
+#: mach-o.c:2898
+#, c-format
+msgid "bfd_mach_o_read_symtab_symbol: unable to read %d bytes at %lu"
+msgstr "bfd_mach_o_read_symtab_symbol: ei kyetä lukemaan %d tavua osoitteesta %lu"
+
+#: mach-o.c:2916
+#, c-format
+msgid "bfd_mach_o_read_symtab_symbol: name out of range (%lu >= %lu)"
+msgstr "bfd_mach_o_read_symtab_symbol: nimi lukualueen ulkopuolella (%lu >= %lu)"
+
+#: mach-o.c:2997
+#, c-format
+msgid "bfd_mach_o_read_symtab_symbol: symbol \"%s\" specified invalid section %d (max %lu): setting to undefined"
+msgstr "bfd_mach_o_read_symtab_symbol: symboli â€%s†määritellyt virheellisen lohkon %d (enintään %lu): asetus on määrittelemätön"
+
+#: mach-o.c:3013
+#, c-format
+msgid "bfd_mach_o_read_symtab_symbol: symbol \"%s\" specified invalid type field 0x%x: setting to undefined"
+msgstr "bfd_mach_o_read_symtab_symbol: symboli â€%s†määritellyt virheellisen tyyppikentän 0x%x: asetus on määrittelemätön"
+
+#: mach-o.c:3085
+msgid "bfd_mach_o_read_symtab_symbols: unable to allocate memory for symbols"
+msgstr "bfd_mach_o_read_symtab_symbols: ei kyetä varaamaan muistia symboleille"
+
+#: mach-o.c:3915
+msgid "%B: unknown load command 0x%lx"
+msgstr "%B: tuntematon latauskäsky 0x%lx"
+
+#: mach-o.c:4107
+#, c-format
+msgid "bfd_mach_o_scan: unknown architecture 0x%lx/0x%lx"
+msgstr "bfd_mach_o_scan: tuntematon arkkitehtuuri 0x%lx/0x%lx"
+
+#: mach-o.c:4204
+#, c-format
+msgid "unknown header byte-order value 0x%lx"
+msgstr "tuntematon otsaketavujärjestysarvo 0x%lx"
+
+#: merge.c:832
+#, c-format
+msgid "%s: access beyond end of merged section (%ld)"
+msgstr "%s: pääsy lomitetun lohkon (%ld) lopun yli"
+
+#: mmo.c:455
+#, c-format
+msgid "%s: No core to allocate section name %s\n"
+msgstr "%s: Ei käyttöjärjestelmäydintä lohkonimen %s varaamiseen\n"
+
+#: mmo.c:530
+#, c-format
+msgid "%s: No core to allocate a symbol %d bytes long\n"
+msgstr "%s: Ei käyttöjärjestelmäydintä symbolin varaamiseksi %d tavua pitkänä\n"
+
+#: mmo.c:1189
+#, c-format
+msgid "%s: invalid mmo file: initialization value for $255 is not `Main'\n"
+msgstr "%s: virheellinen mmo-tiedosto: alustusarvo kohteelle $255 ei ole â€Mainâ€\n"
+
+#: mmo.c:1334
+#, c-format
+msgid "%s: unsupported wide character sequence 0x%02X 0x%02X after symbol name starting with `%s'\n"
+msgstr "%s: ei-tuettu leveämerkkisekvenssi 0x%02X 0x%02X symbolinimen jälkeen alkaen arvolla â€%sâ€\n"
+
+#: mmo.c:1568
+#, c-format
+msgid "%s: invalid mmo file: unsupported lopcode `%d'\n"
+msgstr "%s: virheellinen mmo-tiedosto: ei-tuettu lopcode â€%dâ€\n"
+
+#: mmo.c:1578
+#, c-format
+msgid "%s: invalid mmo file: expected YZ = 1 got YZ = %d for lop_quote\n"
+msgstr "%s: virheellinen mmo-tiedosto: odotettu YZ = 1 saatiin YZ = %d kohteelle lop_quote\n"
+
+#: mmo.c:1614
+#, c-format
+msgid "%s: invalid mmo file: expected z = 1 or z = 2, got z = %d for lop_loc\n"
+msgstr "%s: virheellinen mmo-tiedosto: odotettiin z = 1 tai z = 2, saatiin z = %d kohteelle lop_loc\n"
+
+#: mmo.c:1660
+#, c-format
+msgid "%s: invalid mmo file: expected z = 1 or z = 2, got z = %d for lop_fixo\n"
+msgstr "%s: virheellinen mmo-tiedosto: odotettiin z = 1 tai z = 2, saatiin z = %d kohteelle lop_fixo\n"
+
+#: mmo.c:1699
+#, c-format
+msgid "%s: invalid mmo file: expected y = 0, got y = %d for lop_fixrx\n"
+msgstr "%s: virheellinen mmo-tiedosto: odotettiin y = 0, saatiin y = %d kohteelle lop_fixrx\n"
+
+#: mmo.c:1708
+#, c-format
+msgid "%s: invalid mmo file: expected z = 16 or z = 24, got z = %d for lop_fixrx\n"
+msgstr "%s: virheellinen mmo-tiedosto: odotettiin z = 16 tai z = 24, saatiin z = %d kohteelle lop_fixrx\n"
+
+#: mmo.c:1731
+#, c-format
+msgid "%s: invalid mmo file: leading byte of operand word must be 0 or 1, got %d for lop_fixrx\n"
+msgstr "%s: virheellinen mmo-tiedosto: operandisanan etutavun on oltava 0 tai 1, saatiin %d kohteelle lop_fixrx\n"
+
+#: mmo.c:1754
+#, c-format
+msgid "%s: cannot allocate file name for file number %d, %d bytes\n"
+msgstr "%s: ei voi varata tiedostonimeä tiedostonumerolle %d, %d tavua\n"
+
+#: mmo.c:1774
+#, c-format
+msgid "%s: invalid mmo file: file number %d `%s', was already entered as `%s'\n"
+msgstr "%s: virheellinen mmo-tiedosto: tiedostonumero %d â€%sâ€, oli jo kirjoitettu arvona â€%sâ€\n"
+
+#: mmo.c:1787
+#, c-format
+msgid "%s: invalid mmo file: file name for number %d was not specified before use\n"
+msgstr "%s: virheellinen mmo-tiedosto: tiedostonimi numerolle %d ei ole määritelty ennen käyttöä\n"
+
+#: mmo.c:1893
+#, c-format
+msgid "%s: invalid mmo file: fields y and z of lop_stab non-zero, y: %d, z: %d\n"
+msgstr "%s: virheellinen mmo-tiedosto: lop_stab:n kentät y ja z ovat nollasta poikkeavia, y: %d, z: %d\n"
+
+#: mmo.c:1929
+#, c-format
+msgid "%s: invalid mmo file: lop_end not last item in file\n"
+msgstr "%s: virheellinen mmo-tiedosto: lop_end ei ole viimeinen alkio tiedostossa\n"
+
+#: mmo.c:1942
+#, c-format
+msgid "%s: invalid mmo file: YZ of lop_end (%ld) not equal to the number of tetras to the preceding lop_stab (%ld)\n"
+msgstr "%s: virheellinen mmo-tiedosto: lop_end:n YZ (%ld) ei ole sama kuin tetras-numero edeltävään kohteeseen lop_stab (%ld)\n"
+
+#: mmo.c:2652
+#, c-format
+msgid "%s: invalid symbol table: duplicate symbol `%s'\n"
+msgstr "%s: virheellinen symbolitaulu: symbolin â€%s†kaksoiskappale\n"
+
+#: mmo.c:2892
+#, c-format
+msgid "%s: Bad symbol definition: `Main' set to %s rather than the start address %s\n"
+msgstr "%s: Virheellinen symbolimäärittely: â€Main†asetettu kohteeseen %s pikemmin kuin aloitusosoitteeseen %s\n"
+
+#: mmo.c:2984
+#, c-format
+msgid "%s: warning: symbol table too large for mmo, larger than 65535 32-bit words: %d. Only `Main' will be emitted.\n"
+msgstr "%s: varoitus: symbolitaulu liian laaja kohteelle mmo, laajempi kuin 65535 32-bittistä sanaa: %d. Vain â€Main†lähetetään.\n"
+
+#: mmo.c:3029
+#, c-format
+msgid "%s: internal error, symbol table changed size from %d to %d words\n"
+msgstr "%s: sisäinen virhe, symbolitaulu vaihtoi kokoa %d:sta sanasta %d sanaan\n"
+
+#: mmo.c:3081
+#, c-format
+msgid "%s: internal error, internal register section %s had contents\n"
+msgstr "%s: sisäinen virhe, sisäisessä rekisterilohkossa %s oli sisältöä\n"
+
+#: mmo.c:3132
+#, c-format
+msgid "%s: no initialized registers; section length 0\n"
+msgstr "%s: ei alustettuja rekistereitä; lohkopituus 0\n"
+
+#: mmo.c:3138
+#, c-format
+msgid "%s: too many initialized registers; section length %ld\n"
+msgstr "%s: liian monia alustettuja rekistereitä; lohkopituus %ld\n"
+
+#: mmo.c:3143
+#, c-format
+msgid "%s: invalid start address for initialized registers of length %ld: 0x%lx%08lx\n"
+msgstr "%s: virheellinen aloitusosoite alustetuille rekistereille pituudeltaan %ld: 0x%lx%08lx\n"
+
+#: oasys.c:881
+#, c-format
+msgid "%s: can not represent section `%s' in oasys"
+msgstr "%s: ei voi edustaa lohkoa â€%s†oasys-lohkossa"
+
+#: osf-core.c:128
+#, c-format
+msgid "Unhandled OSF/1 core file section type %d\n"
+msgstr "Käsittelemätön OSF/1-käyttöjärjestelmäydintiedoston lohkotyyppi %d\n"
+
+#: pe-mips.c:607
+msgid "%B: `ld -r' not supported with PE MIPS objects\n"
+msgstr "%B: â€ld -r†ei tuettu â€PE MIPSâ€-objekteilla\n"
+
+#. OK, at this point the following variables are set up:
+#. src = VMA of the memory we're fixing up
+#. mem = pointer to memory we're fixing up
+#. val = VMA of what we need to refer to.
+#: pe-mips.c:719
+msgid "%B: unimplemented %s\n"
+msgstr "%B: toteuttamaton %s\n"
+
+#: pe-mips.c:745
+msgid "%B: jump too far away\n"
+msgstr "%B: hyppy liian kauas\n"
+
+#: pe-mips.c:771
+msgid "%B: bad pair/reflo after refhi\n"
+msgstr "%B: virheellinen pari/reflo refhi:n jälkeen\n"
+
+#: pef.c:522
+#, c-format
+msgid "bfd_pef_scan: unknown architecture 0x%lx"
+msgstr "bfd_pef_scan: tuntematon arkkitehtuuri 0x%lx"
+
+#: pei-x86_64.c:469
+#, c-format
+msgid "warning: .pdata section size (%ld) is not a multiple of %d\n"
+msgstr "varoitus: â€.pdataâ€-lohkokoko (%ld) ei ole %d:n monikerta\n"
+
+#: pei-x86_64.c:474 peigen.c:1626 peigen.c:1809 pepigen.c:1626 pepigen.c:1809
+#: pex64igen.c:1626 pex64igen.c:1809
+#, c-format
+msgid ""
+"\n"
+"The Function Table (interpreted .pdata section contents)\n"
+msgstr ""
+"\n"
+"Funktiotaulu (tulkittu â€.pdataâ€-lohkosisältö)\n"
+
+#: pei-x86_64.c:476
+#, c-format
+msgid "vma:\t\t\tBeginAddress\t EndAddress\t UnwindData\n"
+msgstr "vma:\t\t\tAlkuosoite\t Loppuosoite\t Unwind-tiedot\n"
+
+#. XXX code yet to be written.
+#: peicode.h:758
+msgid "%B: Unhandled import type; %x"
+msgstr "%B: Käsittelemätön tuontityyppi; %x"
+
+#: peicode.h:763
+msgid "%B: Unrecognised import type; %x"
+msgstr "%B: Tunnistamaton tuontityyppi; %x"
+
+#: peicode.h:777
+msgid "%B: Unrecognised import name type; %x"
+msgstr "%B: Tunnistamaton tuontinimityyppi; %x"
+
+#: peicode.h:1173
+msgid "%B: Unrecognised machine type (0x%x) in Import Library Format archive"
+msgstr "%B: Tunnistamaton konetyyppi (0x%x) â€Import Library Formatâ€-arkistossa"
+
+#: peicode.h:1185
+msgid "%B: Recognised but unhandled machine type (0x%x) in Import Library Format archive"
+msgstr "%B: Tunnistettu, mutta käsittelemätön konetyyppi (0x%x) â€Import Library Formatâ€-arkistossa"
+
+#: peicode.h:1203
+msgid "%B: size field is zero in Import Library Format header"
+msgstr "%B: kokokenttä on nolla â€Import Library Formatâ€-otsakkeessa"
+
+#: peicode.h:1234
+msgid "%B: string not null terminated in ILF object file."
+msgstr "%B: merkkijonoa ei ole päätetty nollaan ILF-objektitiedostossa."
+
+#: ppcboot.c:391
+#, c-format
+msgid ""
+"\n"
+"ppcboot header:\n"
+msgstr ""
+"\n"
+"ppcboot-otsake:\n"
+
+#: ppcboot.c:392
+#, c-format
+msgid "Entry offset = 0x%.8lx (%ld)\n"
+msgstr "Tulokohtasiirrososoite = 0x%.8lx (%ld)\n"
+
+#: ppcboot.c:394
+#, c-format
+msgid "Length = 0x%.8lx (%ld)\n"
+msgstr "Pituus = 0x%.8lx (%ld)\n"
+
+#: ppcboot.c:398
+#, c-format
+msgid "Flag field = 0x%.2x\n"
+msgstr "Lippukenttä = 0x%.2x\n"
+
+#: ppcboot.c:404
+#, c-format
+msgid "Partition name = \"%s\"\n"
+msgstr "Osionimi = â€%sâ€\n"
+
+#: ppcboot.c:423
+#, c-format
+msgid ""
+"\n"
+"Partition[%d] start = { 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x }\n"
+msgstr ""
+"\n"
+"Osio[%d] alku = { 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x }\n"
+
+#: ppcboot.c:429
+#, c-format
+msgid "Partition[%d] end = { 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x }\n"
+msgstr "Osio[%d] loppu = { 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x }\n"
+
+#: ppcboot.c:435
+#, c-format
+msgid "Partition[%d] sector = 0x%.8lx (%ld)\n"
+msgstr "Osio[%d] sektori = 0x%.8lx (%ld)\n"
+
+#: ppcboot.c:437
+#, c-format
+msgid "Partition[%d] length = 0x%.8lx (%ld)\n"
+msgstr "Osio[%d] pituus = 0x%.8lx (%ld)\n"
+
+#: reloc.c:7371
+msgid "INPUT_SECTION_FLAGS are not supported.\n"
+msgstr "INPUT_SECTION_FLAGS ei ole tuettu.\n"
+
+#: reloc.c:7526
+msgid "%X%P: %B(%A): relocation \"%R\" goes out of range\n"
+msgstr "%X%P: %B(%A): sijoitus â€%R†menee lukualueen ulkopuolelle\n"
+
+#: rs6000-core.c:448
+#, c-format
+msgid "%s: warning core file truncated"
+msgstr "%s: varoitus ydintiedosto typistetty"
+
+#: som.c:5471
+#, c-format
+msgid ""
+"\n"
+"Exec Auxiliary Header\n"
+msgstr ""
+"\n"
+"Suoritettavan tiedoston apuotsake\n"
+
+#: som.c:5776
+msgid "som_sizeof_headers unimplemented"
+msgstr "som_sizeof_headers ei ole toteutettu"
+
+#: srec.c:261
+msgid "%B:%d: Unexpected character `%s' in S-record file\n"
+msgstr "%B:%d: Odottamaton merkki â€%s†S-tietuetiedostossa\n"
+
+#: srec.c:567 srec.c:600
+msgid "%B:%d: Bad checksum in S-record file\n"
+msgstr "%B:%d: Virheellinen tarkistussumma S-tietuetiedostossa\n"
+
+#: stabs.c:279
+msgid "%B(%A+0x%lx): Stabs entry has invalid string index."
+msgstr "%B(%A+0x%lx): Stabs-tulokohdassa on virheellinen merkkijonoindeksi."
+
+#: syms.c:1079
+msgid "Unsupported .stab relocation"
+msgstr "â€Ei-tuettu .stabâ€-sijoitus"
+
+#: vms-alpha.c:1294
+#, c-format
+msgid "Unknown EGSD subtype %d"
+msgstr "Tuntematon EGSD-alityyppi %d"
+
+#: vms-alpha.c:1325
+#, c-format
+msgid "Stack overflow (%d) in _bfd_vms_push"
+msgstr "Pinon ylivuoto (%d) kohteessa _bfd_vms_push"
+
+#: vms-alpha.c:1338
+msgid "Stack underflow in _bfd_vms_pop"
+msgstr "Pinon ylivuoto kohteessa _bfd_vms_pop"
+
+#. These names have not yet been added to this switch statement.
+#: vms-alpha.c:1575
+#, c-format
+msgid "unknown ETIR command %d"
+msgstr "tuntematon ETIR-komento %d"
+
+#: vms-alpha.c:1762
+#, c-format
+msgid "bad section index in %s"
+msgstr "virheellinen lohkoindeksi kohteessa %s"
+
+#: vms-alpha.c:1775
+#, c-format
+msgid "unsupported STA cmd %s"
+msgstr "ei-tuettu STA-komento %s"
+
+#. Insert field.
+#. Unsigned shift.
+#. Rotate.
+#. Redefine symbol to current location.
+#. Define a literal.
+#: vms-alpha.c:1951 vms-alpha.c:1982 vms-alpha.c:2229
+#, c-format
+msgid "%s: not supported"
+msgstr "%s: ei tuettu"
+
+#: vms-alpha.c:1957
+#, c-format
+msgid "%s: not implemented"
+msgstr "%s: ei toteutettu"
+
+#: vms-alpha.c:2213
+#, c-format
+msgid "invalid use of %s with contexts"
+msgstr "virheellinen %s-käyttö sisällöillä"
+
+#: vms-alpha.c:2247
+#, c-format
+msgid "reserved cmd %d"
+msgstr "varattu komento %d"
+
+#: vms-alpha.c:2332
+msgid "Object module NOT error-free !\n"
+msgstr "Objektimoduli EI ole virheetön !\n"
+
+#: vms-alpha.c:3657
+#, c-format
+msgid "SEC_RELOC with no relocs in section %s"
+msgstr "SEC_RELOC ilman relocs-tietueita lohkossa %s"
+
+#: vms-alpha.c:3709 vms-alpha.c:3922
+#, c-format
+msgid "Size error in section %s"
+msgstr "Kokovirhe lohkossa %s"
+
+#: vms-alpha.c:3868
+msgid "Spurious ALPHA_R_BSR reloc"
+msgstr "Väärä ALPHA_R_BSR reloc-tietue"
+
+#: vms-alpha.c:3909
+#, c-format
+msgid "Unhandled relocation %s"
+msgstr "Käsittelemätön sijoitus %s"
+
+#: vms-alpha.c:4199
+#, c-format
+msgid "unknown source command %d"
+msgstr "tuntematon lähdekomento %d"
+
+#: vms-alpha.c:4260
+msgid "DST__K_SET_LINUM_INCR not implemented"
+msgstr "DST__K_SET_LINUM_INCR ei ole toteutettu"
+
+#: vms-alpha.c:4266
+msgid "DST__K_SET_LINUM_INCR_W not implemented"
+msgstr "DST__K_SET_LINUM_INCR_W ei ole toteutettu"
+
+#: vms-alpha.c:4272
+msgid "DST__K_RESET_LINUM_INCR not implemented"
+msgstr "DST__K_RESET_LINUM_INCR ei ole toteutettu"
+
+#: vms-alpha.c:4278
+msgid "DST__K_BEG_STMT_MODE not implemented"
+msgstr "DST__K_BEG_STMT_MODE ei ole toteutettu"
+
+#: vms-alpha.c:4284
+msgid "DST__K_END_STMT_MODE not implemented"
+msgstr "DST__K_END_STMT_MODE ei ole toteutettu"
+
+#: vms-alpha.c:4311
+msgid "DST__K_SET_PC not implemented"
+msgstr "DST__K_SET_PC ei ole toteutettu"
+
+#: vms-alpha.c:4317
+msgid "DST__K_SET_PC_W not implemented"
+msgstr "DST__K_SET_PC_W ei ole toteutettu"
+
+#: vms-alpha.c:4323
+msgid "DST__K_SET_PC_L not implemented"
+msgstr "DST__K_SET_PC_L ei ole toteutettu"
+
+#: vms-alpha.c:4329
+msgid "DST__K_SET_STMTNUM not implemented"
+msgstr "DST__K_SET_STMTNUM ei ole toteutettu"
+
+#: vms-alpha.c:4372
+#, c-format
+msgid "unknown line command %d"
+msgstr "tuntematon rivikomento %d"
+
+#: vms-alpha.c:4846 vms-alpha.c:4863 vms-alpha.c:4877 vms-alpha.c:4892
+#: vms-alpha.c:4904 vms-alpha.c:4915 vms-alpha.c:4927
+#, c-format
+msgid "Unknown reloc %s + %s"
+msgstr "Tuntematon reloc-tietue %s + %s"
+
+#: vms-alpha.c:4982
+#, c-format
+msgid "Unknown reloc %s"
+msgstr "Tuntematon reloc-tietue %s"
+
+#: vms-alpha.c:4995
+msgid "Invalid section index in ETIR"
+msgstr "virheellinen lohkoindeksi kohteessa ETIR"
+
+#: vms-alpha.c:5002
+msgid "Relocation for non-REL psect"
+msgstr "Sijoitus kohteelle non-REL psect"
+
+#: vms-alpha.c:5049
+#, c-format
+msgid "Unknown symbol in command %s"
+msgstr "Tuntematon symboli komennossa %s"
+
+#: vms-alpha.c:5564
+#, c-format
+msgid " EMH %u (len=%u): "
+msgstr " EMH %u (pituus=%u): "
+
+#: vms-alpha.c:5573
+#, c-format
+msgid "Module header\n"
+msgstr "Moduliotsake\n"
+
+#: vms-alpha.c:5574
+#, c-format
+msgid " structure level: %u\n"
+msgstr " tietuetaso: %u\n"
+
+#: vms-alpha.c:5575
+#, c-format
+msgid " max record size: %u\n"
+msgstr " tietueen enimmäiskoko: %u\n"
+
+#: vms-alpha.c:5578
+#, c-format
+msgid " module name : %.*s\n"
+msgstr " modulinimi : %.*s\n"
+
+#: vms-alpha.c:5580
+#, c-format
+msgid " module version : %.*s\n"
+msgstr " moduliversio : %.*s\n"
+
+#: vms-alpha.c:5582
+#, c-format
+msgid " compile date : %.17s\n"
+msgstr " käännöspäivämäärä : %.17s\n"
+
+#: vms-alpha.c:5587
+#, c-format
+msgid "Language Processor Name\n"
+msgstr "Kielisuorittimen nimi\n"
+
+#: vms-alpha.c:5588
+#, c-format
+msgid " language name: %.*s\n"
+msgstr " kielinimi: %.*s\n"
+
+#: vms-alpha.c:5595
+#, c-format
+msgid "Source Files Header\n"
+msgstr "Lähdetiedostot-otsake\n"
+
+#: vms-alpha.c:5596
+#, c-format
+msgid " file: %.*s\n"
+msgstr " tiedosto: %.*s\n"
+
+#: vms-alpha.c:5603
+#, c-format
+msgid "Title Text Header\n"
+msgstr "Otsikkotekstiotsake\n"
+
+#: vms-alpha.c:5604
+#, c-format
+msgid " title: %.*s\n"
+msgstr " otsikko: %.*s\n"
+
+#: vms-alpha.c:5611
+#, c-format
+msgid "Copyright Header\n"
+msgstr "Copyright-otsake\n"
+
+#: vms-alpha.c:5612
+#, c-format
+msgid " copyright: %.*s\n"
+msgstr " copyright: %.*s\n"
+
+#: vms-alpha.c:5618
+#, c-format
+msgid "unhandled emh subtype %u\n"
+msgstr "käsittelemätön emh-alityyppi %u\n"
+
+#: vms-alpha.c:5628
+#, c-format
+msgid " EEOM (len=%u):\n"
+msgstr " EEOM (pituus=%u):\n"
+
+#: vms-alpha.c:5629
+#, c-format
+msgid " number of cond linkage pairs: %u\n"
+msgstr " ehdollisten linkitysparien lukumäärä: %u\n"
+
+#: vms-alpha.c:5631
+#, c-format
+msgid " completion code: %u\n"
+msgstr " täydentämiskoodi: %u\n"
+
+#: vms-alpha.c:5635
+#, c-format
+msgid " transfer addr flags: 0x%02x\n"
+msgstr " siirto-osoiteliput: 0x%02x\n"
+
+#: vms-alpha.c:5636
+#, c-format
+msgid " transfer addr psect: %u\n"
+msgstr " siirrososoite psect: %u\n"
+
+#: vms-alpha.c:5638
+#, c-format
+msgid " transfer address : 0x%08x\n"
+msgstr " siirto-osoite : 0x%08x\n"
+
+# Käännettäväksi on merkitty monia (vianjäljitys)symboleja ja vastaavia, joita ei oikeastaan pitäisi suomentaa. Joissakin kohdissa vain selväkieliset sanat on suomennettu.
+#: vms-alpha.c:5647
+msgid " WEAK"
+msgstr " WEAK"
+
+#: vms-alpha.c:5649
+msgid " DEF"
+msgstr " DEF"
+
+#: vms-alpha.c:5651
+msgid " UNI"
+msgstr " UNI"
+
+#: vms-alpha.c:5653 vms-alpha.c:5674
+msgid " REL"
+msgstr " REL"
+
+#: vms-alpha.c:5655
+msgid " COMM"
+msgstr " COMM"
+
+#: vms-alpha.c:5657
+msgid " VECEP"
+msgstr " VECEP"
+
+#: vms-alpha.c:5659
+msgid " NORM"
+msgstr " NORM"
+
+#: vms-alpha.c:5661
+msgid " QVAL"
+msgstr " QVAL"
+
+#: vms-alpha.c:5668
+msgid " PIC"
+msgstr " PIC"
+
+#: vms-alpha.c:5670
+msgid " LIB"
+msgstr " LIB"
+
+#: vms-alpha.c:5672
+msgid " OVR"
+msgstr " OVR"
+
+#: vms-alpha.c:5676
+msgid " GBL"
+msgstr " GBL"
+
+#: vms-alpha.c:5678
+msgid " SHR"
+msgstr " SHR"
+
+#: vms-alpha.c:5680
+msgid " EXE"
+msgstr " EXE"
+
+#: vms-alpha.c:5682
+msgid " RD"
+msgstr " RD"
+
+#: vms-alpha.c:5684
+msgid " WRT"
+msgstr " WRT"
+
+#: vms-alpha.c:5686
+msgid " VEC"
+msgstr " VEC"
+
+#: vms-alpha.c:5688
+msgid " NOMOD"
+msgstr " NOMOD"
+
+#: vms-alpha.c:5690
+msgid " COM"
+msgstr " COM"
+
+#: vms-alpha.c:5692
+msgid " 64B"
+msgstr " 64B"
+
+#: vms-alpha.c:5701
+#, c-format
+msgid " EGSD (len=%u):\n"
+msgstr " EGSD (pituus=%u):\n"
+
+#: vms-alpha.c:5713
+#, c-format
+msgid " EGSD entry %2u (type: %u, len: %u): "
+msgstr " EGSD tulopiste %2u (tyyppi: %u, pituus: %u): "
+
+#: vms-alpha.c:5725
+#, c-format
+msgid "PSC - Program section definition\n"
+msgstr "PSC - Ohjelmalohkomäärittely\n"
+
+#: vms-alpha.c:5726 vms-alpha.c:5743
+#, c-format
+msgid " alignment : 2**%u\n"
+msgstr " tasaus : 2**%u\n"
+
+#: vms-alpha.c:5727 vms-alpha.c:5744
+#, c-format
+msgid " flags : 0x%04x"
+msgstr " liput : 0x%04x"
+
+#: vms-alpha.c:5731
+#, c-format
+msgid " alloc (len): %u (0x%08x)\n"
+msgstr " alloc (pituus): %u (0x%08x)\n"
+
+#: vms-alpha.c:5732 vms-alpha.c:5789 vms-alpha.c:5838
+#, c-format
+msgid " name : %.*s\n"
+msgstr " nimi : %.*s\n"
+
+#: vms-alpha.c:5742
+#, c-format
+msgid "SPSC - Shared Image Program section def\n"
+msgstr "SPSC - Jaettu vedosohjelmalohkomäärittely\n"
+
+#: vms-alpha.c:5748
+#, c-format
+msgid " alloc (len) : %u (0x%08x)\n"
+msgstr " alloc (pitus) : %u (0x%08x)\n"
+
+#: vms-alpha.c:5749
+#, c-format
+msgid " image offset : 0x%08x\n"
+msgstr " vedossiirros : 0x%08x\n"
+
+#: vms-alpha.c:5751
+#, c-format
+msgid " symvec offset : 0x%08x\n"
+msgstr " symvec-siirros : 0x%08x\n"
+
+#: vms-alpha.c:5753
+#, c-format
+msgid " name : %.*s\n"
+msgstr " nimi : %.*s\n"
+
+#: vms-alpha.c:5766
+#, c-format
+msgid "SYM - Global symbol definition\n"
+msgstr "SYM - Yleinen symbolimäärittely\n"
+
+#: vms-alpha.c:5767 vms-alpha.c:5827 vms-alpha.c:5848 vms-alpha.c:5867
+#, c-format
+msgid " flags: 0x%04x"
+msgstr " liput: 0x%04x"
+
+#: vms-alpha.c:5770
+#, c-format
+msgid " psect offset: 0x%08x\n"
+msgstr " psect-siirros: 0x%08x\n"
+
+#: vms-alpha.c:5774
+#, c-format
+msgid " code address: 0x%08x\n"
+msgstr " koodiosoite: 0x%08x\n"
+
+#: vms-alpha.c:5776
+#, c-format
+msgid " psect index for entry point : %u\n"
+msgstr " psect-indeksi tulokohdalle : %u\n"
+
+#: vms-alpha.c:5779 vms-alpha.c:5855 vms-alpha.c:5874
+#, c-format
+msgid " psect index : %u\n"
+msgstr " psect-indeksi : %u\n"
+
+#: vms-alpha.c:5781 vms-alpha.c:5857 vms-alpha.c:5876
+#, c-format
+msgid " name : %.*s\n"
+msgstr " nimi : %.*s\n"
+
+#: vms-alpha.c:5788
+#, c-format
+msgid "SYM - Global symbol reference\n"
+msgstr "SYM - Yleinen symboliviite\n"
+
+#: vms-alpha.c:5800
+#, c-format
+msgid "IDC - Ident Consistency check\n"
+msgstr "IDC - Ident-johdonmukaisuustarkistus\n"
+
+#: vms-alpha.c:5801
+#, c-format
+msgid " flags : 0x%08x"
+msgstr " liput : 0x%08x"
+
+#: vms-alpha.c:5805
+#, c-format
+msgid " id match : %x\n"
+msgstr " tunnistetäsmäys: %x\n"
+
+#: vms-alpha.c:5807
+#, c-format
+msgid " error severity: %x\n"
+msgstr " virhevakavuus : %x\n"
+
+#: vms-alpha.c:5810
+#, c-format
+msgid " entity name : %.*s\n"
+msgstr " yksilönimi : %.*s\n"
+
+#: vms-alpha.c:5812
+#, c-format
+msgid " object name : %.*s\n"
+msgstr " objektinimi : %.*s\n"
+
+#: vms-alpha.c:5815
+#, c-format
+msgid " binary ident : 0x%08x\n"
+msgstr " binaari-ident : 0x%08x\n"
+
+#: vms-alpha.c:5818
+#, c-format
+msgid " ascii ident : %.*s\n"
+msgstr " ascii-ident : %.*s\n"
+
+#: vms-alpha.c:5826
+#, c-format
+msgid "SYMG - Universal symbol definition\n"
+msgstr "SYMG - Yleinen symbolimäärittely\n"
+
+#: vms-alpha.c:5830
+#, c-format
+msgid " symbol vector offset: 0x%08x\n"
+msgstr " symbolivektorisiirros: 0x%08x\n"
+
+#: vms-alpha.c:5832
+#, c-format
+msgid " entry point: 0x%08x\n"
+msgstr " tulokohta: 0x%08x\n"
+
+#: vms-alpha.c:5834
+#, c-format
+msgid " proc descr : 0x%08x\n"
+msgstr " ohjelmakuvaus : 0x%08x\n"
+
+#: vms-alpha.c:5836
+#, c-format
+msgid " psect index: %u\n"
+msgstr " psect-indeksi : %u\n"
+
+#: vms-alpha.c:5847
+#, c-format
+msgid "SYMV - Vectored symbol definition\n"
+msgstr "SYMV - Vektoroitu symbolimäärittely\n"
+
+#: vms-alpha.c:5851
+#, c-format
+msgid " vector : 0x%08x\n"
+msgstr " vektori : 0x%08x\n"
+
+#: vms-alpha.c:5853 vms-alpha.c:5872
+#, c-format
+msgid " psect offset: %u\n"
+msgstr " psect-siirros: %u\n"
+
+#: vms-alpha.c:5866
+#, c-format
+msgid "SYMM - Global symbol definition with version\n"
+msgstr "SYMM - Yleinen symbolimäärittely versiolla\n"
+
+#: vms-alpha.c:5870
+#, c-format
+msgid " version mask: 0x%08x\n"
+msgstr " versiopeite : 0x%08x\n"
+
+#: vms-alpha.c:5881
+#, c-format
+msgid "unhandled egsd entry type %u\n"
+msgstr "käsittelemätön egsd-tulokohtatyyppi %u\n"
+
+#: vms-alpha.c:5915
+#, c-format
+msgid " linkage index: %u, replacement insn: 0x%08x\n"
+msgstr " linkitysindeksi: %u, korvauskäsky: 0x%08x\n"
+
+#: vms-alpha.c:5918
+#, c-format
+msgid " psect idx 1: %u, offset 1: 0x%08x %08x\n"
+msgstr " psect idx 1: %u, siirros 1: 0x%08x %08x\n"
+
+#: vms-alpha.c:5922
+#, c-format
+msgid " psect idx 2: %u, offset 2: 0x%08x %08x\n"
+msgstr " psect idx 2: %u, siirros 2: 0x%08x %08x\n"
+
+#: vms-alpha.c:5927
+#, c-format
+msgid " psect idx 3: %u, offset 3: 0x%08x %08x\n"
+msgstr " psect idx 3: %u, siirros 3: 0x%08x %08x\n"
+
+#: vms-alpha.c:5932
+#, c-format
+msgid " global name: %.*s\n"
+msgstr " yleisnimi: %.*s\n"
+
+#: vms-alpha.c:5942
+#, c-format
+msgid " %s (len=%u+%u):\n"
+msgstr " %s (pituus=%u+%u):\n"
+
+#: vms-alpha.c:5957
+#, c-format
+msgid " (type: %3u, size: 4+%3u): "
+msgstr " (tyyppi: %3u, koko: 4+%3u): "
+
+#: vms-alpha.c:5961
+#, c-format
+msgid "STA_GBL (stack global) %.*s\n"
+msgstr "STA_GBL (pino yleinen) %.*s\n"
+
+#: vms-alpha.c:5965
+#, c-format
+msgid "STA_LW (stack longword) 0x%08x\n"
+msgstr "STA_LW (pino longword) 0x%08x\n"
+
+#: vms-alpha.c:5969
+#, c-format
+msgid "STA_QW (stack quadword) 0x%08x %08x\n"
+msgstr "STA_QW (pino quadword) 0x%08x %08x\n"
+
+#: vms-alpha.c:5974
+#, c-format
+msgid "STA_PQ (stack psect base + offset)\n"
+msgstr "STA_PQ (pino psect-kanta + siirros)\n"
+
+#: vms-alpha.c:5975
+#, c-format
+msgid " psect: %u, offset: 0x%08x %08x\n"
+msgstr " psect: %u, siirros: 0x%08x %08x\n"
+
+#: vms-alpha.c:5981
+#, c-format
+msgid "STA_LI (stack literal)\n"
+msgstr "STA_LI (pinoliteraali)\n"
+
+#: vms-alpha.c:5984
+#, c-format
+msgid "STA_MOD (stack module)\n"
+msgstr "STA_MOD (pinomoduli)\n"
+
+#: vms-alpha.c:5987
+#, c-format
+msgid "STA_CKARG (compare procedure argument)\n"
+msgstr "STA_CKARG (vertaa proseduuriargumenttia)\n"
+
+#: vms-alpha.c:5991
+#, c-format
+msgid "STO_B (store byte)\n"
+msgstr "STO_B (tallenna byte)\n"
+
+#: vms-alpha.c:5994
+#, c-format
+msgid "STO_W (store word)\n"
+msgstr "STO_W (tallenna word)\n"
+
+#: vms-alpha.c:5997
+#, c-format
+msgid "STO_LW (store longword)\n"
+msgstr "STO_LW (tallenna longword)\n"
+
+#: vms-alpha.c:6000
+#, c-format
+msgid "STO_QW (store quadword)\n"
+msgstr "STO_QW (tallenna quadword)\n"
+
+#: vms-alpha.c:6006
+#, c-format
+msgid "STO_IMMR (store immediate repeat) %u bytes\n"
+msgstr "STO_IMMR (tallenna välitön toisto) %u tavua\n"
+
+#: vms-alpha.c:6013
+#, c-format
+msgid "STO_GBL (store global) %.*s\n"
+msgstr "STO_GBL (tallenna yleinen) %.*s\n"
+
+#: vms-alpha.c:6017
+#, c-format
+msgid "STO_CA (store code address) %.*s\n"
+msgstr "STO_CA (tallenna koodiosoite) %.*s\n"
+
+#: vms-alpha.c:6021
+#, c-format
+msgid "STO_RB (store relative branch)\n"
+msgstr "STO_RB (tallenna suhteellinen haarautuminen)\n"
+
+#: vms-alpha.c:6024
+#, c-format
+msgid "STO_AB (store absolute branch)\n"
+msgstr "STO_AB (tallenna absoluuttinen haarautuminen)\n"
+
+#: vms-alpha.c:6027
+#, c-format
+msgid "STO_OFF (store offset to psect)\n"
+msgstr "STO_OFF (tallenna siirros kohteeseen psect)\n"
+
+#: vms-alpha.c:6033
+#, c-format
+msgid "STO_IMM (store immediate) %u bytes\n"
+msgstr "STO_IMM (tallenna välitön) %u tavua\n"
+
+#: vms-alpha.c:6040
+#, c-format
+msgid "STO_GBL_LW (store global longword) %.*s\n"
+msgstr "STO_GBL_LW (tallenna yleinen longword) %.*s\n"
+
+#: vms-alpha.c:6044
+#, c-format
+msgid "STO_OFF (store LP with procedure signature)\n"
+msgstr "STO_OFF (tallenna LP-proseduurituntomerkillä)\n"
+
+#: vms-alpha.c:6047
+#, c-format
+msgid "STO_BR_GBL (store branch global) *todo*\n"
+msgstr "STO_BR_GBL (tallenna haarautuminen yleinen) *todo*\n"
+
+#: vms-alpha.c:6050
+#, c-format
+msgid "STO_BR_PS (store branch psect + offset) *todo*\n"
+msgstr "STO_BR_PS (tallenna haarautuminen psect + siirros) *todo*\n"
+
+#: vms-alpha.c:6054
+#, c-format
+msgid "OPR_NOP (no-operation)\n"
+msgstr "OPR_NOP (ei-toimintoa)\n"
+
+#: vms-alpha.c:6057
+#, c-format
+msgid "OPR_ADD (add)\n"
+msgstr "OPR_ADD (lisää)\n"
+
+#: vms-alpha.c:6060
+#, c-format
+msgid "OPR_SUB (substract)\n"
+msgstr "OPR_SUB (vähennä)\n"
+
+#: vms-alpha.c:6063
+#, c-format
+msgid "OPR_MUL (multiply)\n"
+msgstr "OPR_MUL (kerro)\n"
+
+#: vms-alpha.c:6066
+#, c-format
+msgid "OPR_DIV (divide)\n"
+msgstr "OPR_DIV (jaa)\n"
+
+#: vms-alpha.c:6069
+#, c-format
+msgid "OPR_AND (logical and)\n"
+msgstr "OPR_AND (looginen ja)\n"
+
+#: vms-alpha.c:6072
+#, c-format
+msgid "OPR_IOR (logical inclusive or)\n"
+msgstr "OPR_IOR (looginen kattava tai)\n"
+
+#: vms-alpha.c:6075
+#, c-format
+msgid "OPR_EOR (logical exclusive or)\n"
+msgstr "OPR_EOR (loogisesti poissulkeva tai)\n"
+
+#: vms-alpha.c:6078
+#, c-format
+msgid "OPR_NEG (negate)\n"
+msgstr "OPR_NEG (kieltävä)\n"
+
+#: vms-alpha.c:6081
+#, c-format
+msgid "OPR_COM (complement)\n"
+msgstr "OPR_COM (komplementti)\n"
+
+#: vms-alpha.c:6084
+#, c-format
+msgid "OPR_INSV (insert field)\n"
+msgstr "OPR_INSV (lisää kenttä)\n"
+
+#: vms-alpha.c:6087
+#, c-format
+msgid "OPR_ASH (arithmetic shift)\n"
+msgstr "OPR_ASH (aritmeettinen sivuttaissiirto)\n"
+
+#: vms-alpha.c:6090
+#, c-format
+msgid "OPR_USH (unsigned shift)\n"
+msgstr "OPR_USH (etumerkitön sivuttaissiirto)\n"
+
+#: vms-alpha.c:6093
+#, c-format
+msgid "OPR_ROT (rotate)\n"
+msgstr "OPR_ROT (pyöritä)\n"
+
+#: vms-alpha.c:6096
+#, c-format
+msgid "OPR_SEL (select)\n"
+msgstr "OPR_SEL (valitse)\n"
+
+#: vms-alpha.c:6099
+#, c-format
+msgid "OPR_REDEF (redefine symbol to curr location)\n"
+msgstr "OPR_REDEF (määritä symboli uudelleen nykyiseen paikkaan)\n"
+
+#: vms-alpha.c:6102
+#, c-format
+msgid "OPR_REDEF (define a literal)\n"
+msgstr "OPR_REDEF (määritä literaali)\n"
+
+#: vms-alpha.c:6106
+#, c-format
+msgid "STC_LP (store cond linkage pair)\n"
+msgstr "STC_LP (tallenna ehdollinen linkityspari)\n"
+
+#: vms-alpha.c:6110
+#, c-format
+msgid "STC_LP_PSB (store cond linkage pair + signature)\n"
+msgstr "STC_LP_PSB (tallenna ehdollinen linkityspari + tuntomerkki)\n"
+
+#: vms-alpha.c:6111
+#, c-format
+msgid " linkage index: %u, procedure: %.*s\n"
+msgstr " linkitysindeksi: %u, proseduuri: %.*s\n"
+
+#: vms-alpha.c:6114
+#, c-format
+msgid " signature: %.*s\n"
+msgstr " tuntomerkki: %.*s\n"
+
+#: vms-alpha.c:6117
+#, c-format
+msgid "STC_GBL (store cond global)\n"
+msgstr "STC_GBL (tallenna ehdollinen yleinen)\n"
+
+#: vms-alpha.c:6118
+#, c-format
+msgid " linkage index: %u, global: %.*s\n"
+msgstr " linkitysindeksi: %u, yleinen: %.*s\n"
+
+#: vms-alpha.c:6122
+#, c-format
+msgid "STC_GCA (store cond code address)\n"
+msgstr "STC_GCA (tallenna ehdollinen koodiosoite)\n"
+
+#: vms-alpha.c:6123
+#, c-format
+msgid " linkage index: %u, procedure name: %.*s\n"
+msgstr " linkitysindeksi: %u, proseduurinimi: %.*s\n"
+
+#: vms-alpha.c:6127
+#, c-format
+msgid "STC_PS (store cond psect + offset)\n"
+msgstr "STC_PS (tallenna ehdollinen psect + siirros)\n"
+
+#: vms-alpha.c:6129
+#, c-format
+msgid " linkage index: %u, psect: %u, offset: 0x%08x %08x\n"
+msgstr " linkitysindeksi: %u, psect: %u, siirros: 0x%08x %08x\n"
+
+#: vms-alpha.c:6136
+#, c-format
+msgid "STC_NOP_GBL (store cond NOP at global addr)\n"
+msgstr "STC_NOP_GBL (tallenna ehdollinen NOP yleisosoitteessa)\n"
+
+#: vms-alpha.c:6140
+#, c-format
+msgid "STC_NOP_PS (store cond NOP at psect + offset)\n"
+msgstr "STC_NOP_PS (tallenna ehdollinen NOP kohteessa psect + siirros)\n"
+
+#: vms-alpha.c:6144
+#, c-format
+msgid "STC_BSR_GBL (store cond BSR at global addr)\n"
+msgstr "STC_BSR_GBL (tallenna ehdollinen BSR yleisosoitteessa)\n"
+
+#: vms-alpha.c:6148
+#, c-format
+msgid "STC_BSR_PS (store cond BSR at psect + offset)\n"
+msgstr "STC_BSR_PS (tallenna ehdollinen BSR kohteessa psect + siirros)\n"
+
+#: vms-alpha.c:6152
+#, c-format
+msgid "STC_LDA_GBL (store cond LDA at global addr)\n"
+msgstr "STC_LDA_GBL (tallenna ehdollinen LDA yleisosoitteessa)\n"
+
+#: vms-alpha.c:6156
+#, c-format
+msgid "STC_LDA_PS (store cond LDA at psect + offset)\n"
+msgstr "STC_LDA_PS (tallenna ehdollinen LDA kohteessa psect + siirros)\n"
+
+#: vms-alpha.c:6160
+#, c-format
+msgid "STC_BOH_GBL (store cond BOH at global addr)\n"
+msgstr "STC_BOH_GBL (tallenna ehdollinen BOH yleisosoitteessa)\n"
+
+#: vms-alpha.c:6164
+#, c-format
+msgid "STC_BOH_PS (store cond BOH at psect + offset)\n"
+msgstr "STC_BOH_PS (tallenna ehdollinen BOH kohteessa psect + siirros)\n"
+
+#: vms-alpha.c:6169
+#, c-format
+msgid "STC_NBH_GBL (store cond or hint at global addr)\n"
+msgstr "STC_NBH_GBL (tallenna ehdollinen tai vihje yleisosoitteessa)\n"
+
+#: vms-alpha.c:6173
+#, c-format
+msgid "STC_NBH_PS (store cond or hint at psect + offset)\n"
+msgstr "STC_NBH_PS (tallenna ehdollinen tai vihje kohteessa psect + siirros)\n"
+
+#: vms-alpha.c:6177
+#, c-format
+msgid "CTL_SETRB (set relocation base)\n"
+msgstr "CTL_SETRB (aseta sijoituskanta)\n"
+
+#: vms-alpha.c:6183
+#, c-format
+msgid "CTL_AUGRB (augment relocation base) %u\n"
+msgstr "CTL_AUGRB (lisäyssijoituskanta) %u\n"
+
+#: vms-alpha.c:6187
+#, c-format
+msgid "CTL_DFLOC (define location)\n"
+msgstr "CTL_DFLOC (määritä paikka)\n"
+
+#: vms-alpha.c:6190
+#, c-format
+msgid "CTL_STLOC (set location)\n"
+msgstr "CTL_STLOC (aseta paikka)\n"
+
+#: vms-alpha.c:6193
+#, c-format
+msgid "CTL_STKDL (stack defined location)\n"
+msgstr "CTL_STKDL (pinomääritelty paikka)\n"
+
+#: vms-alpha.c:6196 vms-alpha.c:6610
+#, c-format
+msgid "*unhandled*\n"
+msgstr "*käsittelemätön*\n"
+
+#: vms-alpha.c:6226 vms-alpha.c:6265
+#, c-format
+msgid "cannot read GST record length\n"
+msgstr "ei voida lukea GST-tietuepituutta\n"
+
+#. Ill-formed.
+#: vms-alpha.c:6247
+#, c-format
+msgid "cannot find EMH in first GST record\n"
+msgstr "ei voi löytää kohdetta EMH ensimmäisessä GST-tietueessa\n"
+
+#: vms-alpha.c:6273
+#, c-format
+msgid "cannot read GST record header\n"
+msgstr "ei voida lukea GST-tietueotsaketta\n"
+
+#: vms-alpha.c:6286
+#, c-format
+msgid " corrupted GST\n"
+msgstr " rikkoutunut kohde GST\n"
+
+#: vms-alpha.c:6294
+#, c-format
+msgid "cannot read GST record\n"
+msgstr "ei voida lukea GST-tietuetta\n"
+
+#: vms-alpha.c:6323
+#, c-format
+msgid " unhandled EOBJ record type %u\n"
+msgstr " käsittelemätön EOBJ-tietuetyyppi %u\n"
+
+#: vms-alpha.c:6346
+#, c-format
+msgid " bitcount: %u, base addr: 0x%08x\n"
+msgstr " bittilukumäärä: %u, perusosoite: 0x%08x\n"
+
+#: vms-alpha.c:6359
+#, c-format
+msgid " bitmap: 0x%08x (count: %u):\n"
+msgstr " bittikartta: 0x%08x (lukumäärä: %u):\n"
+
+#: vms-alpha.c:6366
+#, c-format
+msgid " %08x"
+msgstr " %08x"
+
+#: vms-alpha.c:6391
+#, c-format
+msgid " image %u (%u entries)\n"
+msgstr " vedos %u (%u alkiota)\n"
+
+#: vms-alpha.c:6396
+#, c-format
+msgid " offset: 0x%08x, val: 0x%08x\n"
+msgstr " siirros: 0x%08x, arvo: 0x%08x\n"
+
+#: vms-alpha.c:6417
+#, c-format
+msgid " image %u (%u entries), offsets:\n"
+msgstr " vedos %u (%u alkiota), siirrokset:\n"
+
+#: vms-alpha.c:6424
+#, c-format
+msgid " 0x%08x"
+msgstr " 0x%08x"
+
+#. 64 bits.
+#: vms-alpha.c:6546
+#, c-format
+msgid "64 bits *unhandled*\n"
+msgstr "64 bittinen *käsittelemätön*\n"
+
+#: vms-alpha.c:6550
+#, c-format
+msgid "class: %u, dtype: %u, length: %u, pointer: 0x%08x\n"
+msgstr "luokka: %u, dtype: %u, pituus: %u, osoitin: 0x%08x\n"
+
+#: vms-alpha.c:6561
+#, c-format
+msgid "non-contiguous array of %s\n"
+msgstr "ei-yhtenäinen %s-taulukko\n"
+
+#: vms-alpha.c:6565
+#, c-format
+msgid "dimct: %u, aflags: 0x%02x, digits: %u, scale: %u\n"
+msgstr "dimct: %u, a-liput: 0x%02x, numerot: %u, skaala: %u\n"
+
+#: vms-alpha.c:6569
+#, c-format
+msgid "arsize: %u, a0: 0x%08x\n"
+msgstr "arsize: %u, a0: 0x%08x\n"
+
+#: vms-alpha.c:6573
+#, c-format
+msgid "Strides:\n"
+msgstr "Askeleet:\n"
+
+#: vms-alpha.c:6578
+#, c-format
+msgid "[%u]: %u\n"
+msgstr "[%u]: %u\n"
+
+#: vms-alpha.c:6583
+#, c-format
+msgid "Bounds:\n"
+msgstr "Rajat:\n"
+
+#: vms-alpha.c:6588
+#, c-format
+msgid "[%u]: Lower: %u, upper: %u\n"
+msgstr "[%u]: Alempi: %u, ylempi: %u\n"
+
+#: vms-alpha.c:6600
+#, c-format
+msgid "unaligned bit-string of %s\n"
+msgstr "tasaamaton %s-bittimerkkijono\n"
+
+#: vms-alpha.c:6604
+#, c-format
+msgid "base: %u, pos: %u\n"
+msgstr "kanta: %u, paikka: %u\n"
+
+#: vms-alpha.c:6624
+#, c-format
+msgid "vflags: 0x%02x, value: 0x%08x "
+msgstr "v-liput: 0x%02x, arvo: 0x%08x "
+
+#: vms-alpha.c:6630
+#, c-format
+msgid "(no value)\n"
+msgstr "(ei arvoa)\n"
+
+#: vms-alpha.c:6633
+#, c-format
+msgid "(not active)\n"
+msgstr "(ei käytössä)\n"
+
+#: vms-alpha.c:6636
+#, c-format
+msgid "(not allocated)\n"
+msgstr "(ei varattu)\n"
+
+#: vms-alpha.c:6639
+#, c-format
+msgid "(descriptor)\n"
+msgstr "(kuvaaja)\n"
+
+#: vms-alpha.c:6643
+#, c-format
+msgid "(trailing value)\n"
+msgstr "(jälkiarvo)\n"
+
+#: vms-alpha.c:6646
+#, c-format
+msgid "(value spec follows)\n"
+msgstr "(arvomäärittely seuraa)\n"
+
+#: vms-alpha.c:6649
+#, c-format
+msgid "(at bit offset %u)\n"
+msgstr "(bittisiirroksessa %u)\n"
+
+#: vms-alpha.c:6652
+#, c-format
+msgid "(reg: %u, disp: %u, indir: %u, kind: "
+msgstr "(rekisteri: %u, sijoitus: %u, suunta: %u, tyyppi: "
+
+#: vms-alpha.c:6659
+msgid "literal"
+msgstr "literaali"
+
+#: vms-alpha.c:6662
+msgid "address"
+msgstr "osoite"
+
+#: vms-alpha.c:6665
+msgid "desc"
+msgstr "kuvaus"
+
+#: vms-alpha.c:6668
+msgid "reg"
+msgstr "rekisteri"
+
+#: vms-alpha.c:6743
+#, c-format
+msgid "Debug symbol table:\n"
+msgstr "Vianjäljityssymbolitaulu:\n"
+
+#: vms-alpha.c:6754
+#, c-format
+msgid "cannot read DST header\n"
+msgstr "ei voida lukea DST-otsaketta\n"
+
+#: vms-alpha.c:6759
+#, c-format
+msgid " type: %3u, len: %3u (at 0x%08x): "
+msgstr " tyyppi: %3u, pituus: %3u (osoitteessa 0x%08x): "
+
+#: vms-alpha.c:6773
+#, c-format
+msgid "cannot read DST symbol\n"
+msgstr "ei voida lukea DST-symbolia\n"
+
+#: vms-alpha.c:6816
+#, c-format
+msgid "standard data: %s\n"
+msgstr "vakiotiedot: %s\n"
+
+#: vms-alpha.c:6819 vms-alpha.c:6903
+#, c-format
+msgid " name: %.*s\n"
+msgstr " nimi: %.*s\n"
+
+#: vms-alpha.c:6826
+#, c-format
+msgid "modbeg\n"
+msgstr "modbeg-alku\n"
+
+#: vms-alpha.c:6827
+#, c-format
+msgid " flags: %d, language: %u, major: %u, minor: %u\n"
+msgstr " liput: %d, kieli: %u, major: %u, minor: %u\n"
+
+#: vms-alpha.c:6833 vms-alpha.c:7099
+#, c-format
+msgid " module name: %.*s\n"
+msgstr " modulinimi: %.*s\n"
+
+#: vms-alpha.c:6836
+#, c-format
+msgid " compiler : %.*s\n"
+msgstr " kääntäjä : %.*s\n"
+
+#: vms-alpha.c:6841
+#, c-format
+msgid "modend\n"
+msgstr "modend-loppu\n"
+
+#: vms-alpha.c:6848
+msgid "rtnbeg\n"
+msgstr "rtnbeg-alku\n"
+
+#: vms-alpha.c:6849
+#, c-format
+msgid " flags: %u, address: 0x%08x, pd-address: 0x%08x\n"
+msgstr " liput: %u, osoite: 0x%08x, pd-osoite: 0x%08x\n"
+
+#: vms-alpha.c:6854
+#, c-format
+msgid " routine name: %.*s\n"
+msgstr " rutiininimi: %.*s\n"
+
+#: vms-alpha.c:6862
+#, c-format
+msgid "rtnend: size 0x%08x\n"
+msgstr "rtnend-loppu: koko 0x%08x\n"
+
+#: vms-alpha.c:6870
+#, c-format
+msgid "prolog: bkpt address 0x%08x\n"
+msgstr "prolog: bkpt-osoite 0x%08x\n"
+
+#: vms-alpha.c:6878
+#, c-format
+msgid "epilog: flags: %u, count: %u\n"
+msgstr "epilog: liput: %u, lukumäärä: %u\n"
+
+#: vms-alpha.c:6887
+#, c-format
+msgid "blkbeg: address: 0x%08x, name: %.*s\n"
+msgstr "blkbeg-alku: osoite: 0x%08x, nimi: %.*s\n"
+
+#: vms-alpha.c:6896
+#, c-format
+msgid "blkend: size: 0x%08x\n"
+msgstr "blkend-loppu: koko: 0x%08x\n"
+
+#: vms-alpha.c:6902
+#, c-format
+msgid "typspec (len: %u)\n"
+msgstr "typspec (pituus: %u)\n"
+
+#: vms-alpha.c:6909
+#, c-format
+msgid "septyp, name: %.*s\n"
+msgstr "septyp, nimi: %.*s\n"
+
+#: vms-alpha.c:6918
+#, c-format
+msgid "recbeg: name: %.*s\n"
+msgstr "recbeg-alku: nimi: %.*s\n"
+
+#: vms-alpha.c:6925
+#, c-format
+msgid "recend\n"
+msgstr "recend-loppu\n"
+
+#: vms-alpha.c:6928
+#, c-format
+msgid "enumbeg, len: %u, name: %.*s\n"
+msgstr "enumbeg-alku, pituus: %u, nimi: %.*s\n"
+
+#: vms-alpha.c:6932
+#, c-format
+msgid "enumelt, name: %.*s\n"
+msgstr "enumelt, nimi: %.*s\n"
+
+#: vms-alpha.c:6936
+#, c-format
+msgid "enumend\n"
+msgstr "enumend-loppu\n"
+
+#: vms-alpha.c:6953
+#, c-format
+msgid "discontiguous range (nbr: %u)\n"
+msgstr "ei-yhtenäinen lukualue (numero: %u)\n"
+
+#: vms-alpha.c:6955
+#, c-format
+msgid " address: 0x%08x, size: %u\n"
+msgstr " osoite: 0x%08x, koko: %u\n"
+
+#: vms-alpha.c:6965
+#, c-format
+msgid "line num (len: %u)\n"
+msgstr "rivinumero (pituus: %u)\n"
+
+#: vms-alpha.c:6982
+#, c-format
+msgid "delta_pc_w %u\n"
+msgstr "delta_pc_w %u\n"
+
+#: vms-alpha.c:6989
+#, c-format
+msgid "incr_linum(b): +%u\n"
+msgstr "incr_linum(b): +%u\n"
+
+#: vms-alpha.c:6995
+#, c-format
+msgid "incr_linum_w: +%u\n"
+msgstr "incr_linum_w: +%u\n"
+
+#: vms-alpha.c:7001
+#, c-format
+msgid "incr_linum_l: +%u\n"
+msgstr "incr_linum_l: +%u\n"
+
+#: vms-alpha.c:7007
+#, c-format
+msgid "set_line_num(w) %u\n"
+msgstr "set_line_num(w) %u\n"
+
+#: vms-alpha.c:7012
+#, c-format
+msgid "set_line_num_b %u\n"
+msgstr "set_line_num_b %u\n"
+
+#: vms-alpha.c:7017
+#, c-format
+msgid "set_line_num_l %u\n"
+msgstr "set_line_num_l %u\n"
+
+#: vms-alpha.c:7022
+#, c-format
+msgid "set_abs_pc: 0x%08x\n"
+msgstr "set_abs_pc: 0x%08x\n"
+
+#: vms-alpha.c:7026
+#, c-format
+msgid "delta_pc_l: +0x%08x\n"
+msgstr "delta_pc_l: +0x%08x\n"
+
+#: vms-alpha.c:7031
+#, c-format
+msgid "term(b): 0x%02x"
+msgstr "term(b): 0x%02x"
+
+#: vms-alpha.c:7033
+#, c-format
+msgid " pc: 0x%08x\n"
+msgstr " pc: 0x%08x\n"
+
+#: vms-alpha.c:7038
+#, c-format
+msgid "term_w: 0x%04x"
+msgstr "term_w: 0x%04x"
+
+#: vms-alpha.c:7040
+#, c-format
+msgid " pc: 0x%08x\n"
+msgstr " pc: 0x%08x\n"
+
+#: vms-alpha.c:7046
+#, c-format
+msgid "delta pc +%-4d"
+msgstr "delta pc +%-4d"
+
+#: vms-alpha.c:7049
+#, c-format
+msgid " pc: 0x%08x line: %5u\n"
+msgstr " pc: 0x%08x rivi: %5u\n"
+
+#: vms-alpha.c:7054
+#, c-format
+msgid " *unhandled* cmd %u\n"
+msgstr " *käsittelemätön* komento %u\n"
+
+#: vms-alpha.c:7069
+#, c-format
+msgid "source (len: %u)\n"
+msgstr "lähde (pituus: %u)\n"
+
+#: vms-alpha.c:7083
+#, c-format
+msgid " declfile: len: %u, flags: %u, fileid: %u\n"
+msgstr " declfile: pituus: %u, liput: %u, tiedostotunniste: %u\n"
+
+#: vms-alpha.c:7087
+#, c-format
+msgid " rms: cdt: 0x%08x %08x, ebk: 0x%08x, ffb: 0x%04x, rfo: %u\n"
+msgstr " rms: cdt: 0x%08x %08x, ebk: 0x%08x, ffb: 0x%04x, rfo: %u\n"
+
+#: vms-alpha.c:7096
+#, c-format
+msgid " filename : %.*s\n"
+msgstr " tiedostonimi: %.*s\n"
+
+#: vms-alpha.c:7105
+#, c-format
+msgid " setfile %u\n"
+msgstr " setfile %u\n"
+
+#: vms-alpha.c:7110 vms-alpha.c:7115
+#, c-format
+msgid " setrec %u\n"
+msgstr " setrec %u\n"
+
+#: vms-alpha.c:7120 vms-alpha.c:7125
+#, c-format
+msgid " setlnum %u\n"
+msgstr " setlnum %u\n"
+
+#: vms-alpha.c:7130 vms-alpha.c:7135
+#, c-format
+msgid " deflines %u\n"
+msgstr " deflines %u\n"
+
+#: vms-alpha.c:7139
+#, c-format
+msgid " formfeed\n"
+msgstr " formfeed\n"
+
+#: vms-alpha.c:7143
+#, c-format
+msgid " *unhandled* cmd %u\n"
+msgstr " *käsittelemätön* komento %u\n"
+
+#: vms-alpha.c:7155
+#, c-format
+msgid "*unhandled* dst type %u\n"
+msgstr "*käsittelemätön* kohdetyyppi %u\n"
+
+#: vms-alpha.c:7187
+#, c-format
+msgid "cannot read EIHD\n"
+msgstr "ei voida lukea kohdetta EIHD\n"
+
+#: vms-alpha.c:7190
+#, c-format
+msgid "EIHD: (size: %u, nbr blocks: %u)\n"
+msgstr "EIHD: (koko: %u, nbr lohkoa: %u)\n"
+
+#: vms-alpha.c:7193
+#, c-format
+msgid " majorid: %u, minorid: %u\n"
+msgstr " majorid: %u, minorid: %u\n"
+
+#: vms-alpha.c:7201
+msgid "executable"
+msgstr "suoritettava tiedosto"
+
+#: vms-alpha.c:7204
+msgid "linkable image"
+msgstr "linkitettävä vedos"
+
+#: vms-alpha.c:7210
+#, c-format
+msgid " image type: %u (%s)"
+msgstr " vedostyyppi: %u (%s)"
+
+#: vms-alpha.c:7216
+msgid "native"
+msgstr "kotoperäinen"
+
+#: vms-alpha.c:7219
+msgid "CLI"
+msgstr "CLI"
+
+#: vms-alpha.c:7225
+#, c-format
+msgid ", subtype: %u (%s)\n"
+msgstr ", alityyppi: %u (%s)\n"
+
+#: vms-alpha.c:7231
+#, c-format
+msgid " offsets: isd: %u, activ: %u, symdbg: %u, imgid: %u, patch: %u\n"
+msgstr " siirrokset: isd: %u, activ: %u, symdbg: %u, imgid: %u, patch: %u\n"
+
+#: vms-alpha.c:7235
+#, c-format
+msgid " fixup info rva: "
+msgstr " korjaustiedot rva: "
+
+#: vms-alpha.c:7237
+#, c-format
+msgid ", symbol vector rva: "
+msgstr ", symbolivektori rva: "
+
+#: vms-alpha.c:7240
+#, c-format
+msgid ""
+"\n"
+" version array off: %u\n"
+msgstr ""
+"\n"
+" versiotaulukkosiirros: %u\n"
+
+#: vms-alpha.c:7244
+#, c-format
+msgid " img I/O count: %u, nbr channels: %u, req pri: %08x%08x\n"
+msgstr " img I/O lukumäärä: %u, kanavien lukumäärä: %u, req pri: %08x%08x\n"
+
+#: vms-alpha.c:7250
+#, c-format
+msgid " linker flags: %08x:"
+msgstr " linkkeriliput: %08x:"
+
+#: vms-alpha.c:7280
+#, c-format
+msgid " ident: 0x%08x, sysver: 0x%08x, match ctrl: %u, symvect_size: %u\n"
+msgstr " ident: 0x%08x, sysver: 0x%08x, täsmää ctrl: %u, symvect_size: %u\n"
+
+#: vms-alpha.c:7286
+#, c-format
+msgid " BPAGE: %u"
+msgstr " BPAGE: %u"
+
+#: vms-alpha.c:7292
+#, c-format
+msgid ", ext fixup offset: %u, no_opt psect off: %u"
+msgstr ", ext korjaussiirros: %u, no_opt psect -siirros: %u"
+
+#: vms-alpha.c:7295
+#, c-format
+msgid ", alias: %u\n"
+msgstr ", alias: %u\n"
+
+#: vms-alpha.c:7303
+#, c-format
+msgid "system version array information:\n"
+msgstr "järjestelmäversion taulukkotiedot:\n"
+
+#: vms-alpha.c:7307
+#, c-format
+msgid "cannot read EIHVN header\n"
+msgstr "ei voida lukea EIHVN-otsaketta\n"
+
+#: vms-alpha.c:7317
+#, c-format
+msgid "cannot read EIHVN version\n"
+msgstr "ei voida lukea EIHVN-versiota\n"
+
+#: vms-alpha.c:7320
+#, c-format
+msgid " %02u "
+msgstr " %02u "
+
+#: vms-alpha.c:7324
+msgid "BASE_IMAGE "
+msgstr "PERUS_VEDOS "
+
+#: vms-alpha.c:7327
+msgid "MEMORY_MANAGEMENT"
+msgstr "MUISTI_HALLINTA "
+
+#: vms-alpha.c:7330
+msgid "IO "
+msgstr "SIIRRÄNTÄ "
+
+#: vms-alpha.c:7333
+msgid "FILES_VOLUMES "
+msgstr "TIEDOSTOT_TALTIOT"
+
+#: vms-alpha.c:7336
+msgid "PROCESS_SCHED "
+msgstr "PROSESSI_AIKAT. "
+
+#: vms-alpha.c:7339
+msgid "SYSGEN "
+msgstr "SYSGEN "
+
+#: vms-alpha.c:7342
+msgid "CLUSTERS_LOCKMGR "
+msgstr "KLUSTERIEN_LUKOT "
+
+#: vms-alpha.c:7345
+msgid "LOGICAL_NAMES "
+msgstr "LOOGISET_NIMET "
+
+#: vms-alpha.c:7348
+msgid "SECURITY "
+msgstr "TURVALLISUUS "
+
+#: vms-alpha.c:7351
+msgid "IMAGE_ACTIVATOR "
+msgstr "VEDOS_AKTIVOIJA "
+
+#: vms-alpha.c:7354
+msgid "NETWORKS "
+msgstr "VERKOT "
+
+#: vms-alpha.c:7357
+msgid "COUNTERS "
+msgstr "LASKURIT "
+
+#: vms-alpha.c:7360
+msgid "STABLE "
+msgstr "STABIILI "
+
+#: vms-alpha.c:7363
+msgid "MISC "
+msgstr "SEKALAISET "
+
+#: vms-alpha.c:7366
+msgid "CPU "
+msgstr "PROSESSORI "
+
+#: vms-alpha.c:7369
+msgid "VOLATILE "
+msgstr "KATOAVA "
+
+#: vms-alpha.c:7372
+msgid "SHELL "
+msgstr "KUORI "
+
+#: vms-alpha.c:7375
+msgid "POSIX "
+msgstr "POSIX "
+
+#: vms-alpha.c:7378
+msgid "MULTI_PROCESSING "
+msgstr "MONI_PROSESSOINTI"
+
+#: vms-alpha.c:7381
+msgid "GALAXY "
+msgstr "GALAKSI "
+
+#: vms-alpha.c:7384
+msgid "*unknown* "
+msgstr "*tuntematon* "
+
+#: vms-alpha.c:7387
+#, c-format
+msgid ": %u.%u\n"
+msgstr ": %u.%u\n"
+
+#: vms-alpha.c:7400 vms-alpha.c:7659
+#, c-format
+msgid "cannot read EIHA\n"
+msgstr "ei voida lukea kohdetta EIHA\n"
+
+#: vms-alpha.c:7403
+#, c-format
+msgid "Image activation: (size=%u)\n"
+msgstr "Vedosaktivointi: (koko=%u)\n"
+
+#: vms-alpha.c:7405
+#, c-format
+msgid " First address : 0x%08x 0x%08x\n"
+msgstr " Ensimmäinen osoite : 0x%08x 0x%08x\n"
+
+#: vms-alpha.c:7408
+#, c-format
+msgid " Second address: 0x%08x 0x%08x\n"
+msgstr " Toinen osoite : 0x%08x 0x%08x\n"
+
+#: vms-alpha.c:7411
+#, c-format
+msgid " Third address : 0x%08x 0x%08x\n"
+msgstr " Kolmas osoite : 0x%08x 0x%08x\n"
+
+#: vms-alpha.c:7414
+#, c-format
+msgid " Fourth address: 0x%08x 0x%08x\n"
+msgstr " Neljäs osoite : 0x%08x 0x%08x\n"
+
+#: vms-alpha.c:7417
+#, c-format
+msgid " Shared image : 0x%08x 0x%08x\n"
+msgstr " Jaettu vedos : 0x%08x 0x%08x\n"
+
+#: vms-alpha.c:7428
+#, c-format
+msgid "cannot read EIHI\n"
+msgstr "ei voida lukea kohdetta EIHI\n"
+
+#: vms-alpha.c:7431
+#, c-format
+msgid "Image identification: (major: %u, minor: %u)\n"
+msgstr "Vedostunnistus: (major: %u, minor: %u)\n"
+
+#: vms-alpha.c:7434
+#, c-format
+msgid " image name : %.*s\n"
+msgstr " vedosnimi : %.*s\n"
+
+#: vms-alpha.c:7436
+#, c-format
+msgid " link time : %s\n"
+msgstr " linkitysaika : %s\n"
+
+#: vms-alpha.c:7438
+#, c-format
+msgid " image ident : %.*s\n"
+msgstr " vedossisennys : %.*s\n"
+
+#: vms-alpha.c:7440
+#, c-format
+msgid " linker ident : %.*s\n"
+msgstr " linkkeri-ident : %.*s\n"
+
+#: vms-alpha.c:7442
+#, c-format
+msgid " image build ident: %.*s\n"
+msgstr " vedoksen rakennusident: %.*s\n"
+
+#: vms-alpha.c:7452
+#, c-format
+msgid "cannot read EIHS\n"
+msgstr "ei voida lukea kohdetta EIHS\n"
+
+#: vms-alpha.c:7455
+#, c-format
+msgid "Image symbol & debug table: (major: %u, minor: %u)\n"
+msgstr "Vedossymboli- ja vianjäljitystaulu: (major: %u, minor: %u)\n"
+
+#: vms-alpha.c:7460
+#, c-format
+msgid " debug symbol table : vbn: %u, size: %u (0x%x)\n"
+msgstr " vianjäljityssymbolitaulu : vbn: %u, koko: %u (0x%x)\n"
+
+#: vms-alpha.c:7464
+#, c-format
+msgid " global symbol table: vbn: %u, records: %u\n"
+msgstr " yleinen symbolitaulu: vbn: %u, tietueet: %u\n"
+
+#: vms-alpha.c:7468
+#, c-format
+msgid " debug module table : vbn: %u, size: %u\n"
+msgstr " vianjäljitysmodulitaulu : vbn: %u, koko: %u\n"
+
+#: vms-alpha.c:7481
+#, c-format
+msgid "cannot read EISD\n"
+msgstr "ei voida lukea kohdetta EISD\n"
+
+#: vms-alpha.c:7491
+#, c-format
+msgid "Image section descriptor: (major: %u, minor: %u, size: %u, offset: %u)\n"
+msgstr "Vedoslohkokuvaaja: (major: %u, minor: %u, koko: %u, siirros: %u)\n"
+
+#: vms-alpha.c:7498
+#, c-format
+msgid " section: base: 0x%08x%08x size: 0x%08x\n"
+msgstr " lohko: kanta: 0x%08x%08x koko: 0x%08x\n"
+
+#: vms-alpha.c:7503
+#, c-format
+msgid " flags: 0x%04x"
+msgstr " liput: 0x%04x"
+
+#: vms-alpha.c:7540
+#, c-format
+msgid " vbn: %u, pfc: %u, matchctl: %u type: %u ("
+msgstr " vbn: %u, pfc: %u, matchctl: %u tyyppi: %u ("
+
+#: vms-alpha.c:7546
+msgid "NORMAL"
+msgstr "NORMAALI"
+
+#: vms-alpha.c:7549
+msgid "SHRFXD"
+msgstr "SHRFXD"
+
+#: vms-alpha.c:7552
+msgid "PRVFXD"
+msgstr "PRVFXD"
+
+#: vms-alpha.c:7555
+msgid "SHRPIC"
+msgstr "SHRPIC"
+
+#: vms-alpha.c:7558
+msgid "PRVPIC"
+msgstr "PRVPIC"
+
+#: vms-alpha.c:7561
+msgid "USRSTACK"
+msgstr "USRSTACK"
+
+#: vms-alpha.c:7567
+msgid ")\n"
+msgstr ")\n"
+
+#: vms-alpha.c:7569
+#, c-format
+msgid " ident: 0x%08x, name: %.*s\n"
+msgstr " ident: 0x%08x, nimi: %.*s\n"
+
+#: vms-alpha.c:7579
+#, c-format
+msgid "cannot read DMT\n"
+msgstr "ei voida lukea kohdetta DMT\n"
+
+#: vms-alpha.c:7583
+#, c-format
+msgid "Debug module table:\n"
+msgstr "Vianjäljitysmodulitaulu:\n"
+
+#: vms-alpha.c:7592
+#, c-format
+msgid "cannot read DMT header\n"
+msgstr "ei voida lukea DMT-otsaketta\n"
+
+#: vms-alpha.c:7597
+#, c-format
+msgid " module offset: 0x%08x, size: 0x%08x, (%u psects)\n"
+msgstr " modulisiirros: 0x%08x, koko: 0x%08x, (%u psects)\n"
+
+#: vms-alpha.c:7607
+#, c-format
+msgid "cannot read DMT psect\n"
+msgstr "ei voida lukea kohdetta DMT psect\n"
+
+#: vms-alpha.c:7610
+#, c-format
+msgid " psect start: 0x%08x, length: %u\n"
+msgstr " psect-alku: 0x%08x, pituus: %u\n"
+
+#: vms-alpha.c:7623
+#, c-format
+msgid "cannot read DST\n"
+msgstr "ei voida lukea kohdetta DST\n"
+
+#: vms-alpha.c:7633
+#, c-format
+msgid "cannot read GST\n"
+msgstr "ei voida lukea kohdetta GST\n"
+
+#: vms-alpha.c:7637
+#, c-format
+msgid "Global symbol table:\n"
+msgstr "Yleinen symbolitaulu:\n"
+
+#: vms-alpha.c:7665
+#, c-format
+msgid "Image activator fixup: (major: %u, minor: %u)\n"
+msgstr "Vedosaktivaattorikorjaus: (major: %u, minor: %u)\n"
+
+#: vms-alpha.c:7668
+#, c-format
+msgid " iaflink : 0x%08x %08x\n"
+msgstr " iaflink : 0x%08x %08x\n"
+
+#: vms-alpha.c:7671
+#, c-format
+msgid " fixuplnk: 0x%08x %08x\n"
+msgstr " fixuplnk: 0x%08x %08x\n"
+
+#: vms-alpha.c:7674
+#, c-format
+msgid " size : %u\n"
+msgstr " koko : %u\n"
+
+#: vms-alpha.c:7676
+#, c-format
+msgid " flags: 0x%08x\n"
+msgstr " liput: 0x%08x\n"
+
+#: vms-alpha.c:7680
+#, c-format
+msgid " qrelfixoff: %5u, lrelfixoff: %5u\n"
+msgstr " qrelfixoff: %5u, lrelfixoff: %5u\n"
+
+#: vms-alpha.c:7684
+#, c-format
+msgid " qdotadroff: %5u, ldotadroff: %5u\n"
+msgstr " qdotadroff: %5u, ldotadroff: %5u\n"
+
+#: vms-alpha.c:7688
+#, c-format
+msgid " codeadroff: %5u, lpfixoff : %5u\n"
+msgstr " codeadroff: %5u, lpfixoff : %5u\n"
+
+#: vms-alpha.c:7691
+#, c-format
+msgid " chgprtoff : %5u\n"
+msgstr " chgprtoff : %5u\n"
+
+#: vms-alpha.c:7694
+#, c-format
+msgid " shlstoff : %5u, shrimgcnt : %5u\n"
+msgstr " shlstoff : %5u, shrimgcnt : %5u\n"
+
+#: vms-alpha.c:7696
+#, c-format
+msgid " shlextra : %5u, permctx : %5u\n"
+msgstr " shlextra : %5u, permctx : %5u\n"
+
+#: vms-alpha.c:7699
+#, c-format
+msgid " base_va : 0x%08x\n"
+msgstr " base_va : 0x%08x\n"
+
+#: vms-alpha.c:7701
+#, c-format
+msgid " lppsbfixoff: %5u\n"
+msgstr " lppsbfixoff: %5u\n"
+
+#: vms-alpha.c:7709
+#, c-format
+msgid " Shareable images:\n"
+msgstr " Jaettavat vedokset:\n"
+
+#: vms-alpha.c:7713
+#, c-format
+msgid " %u: size: %u, flags: 0x%02x, name: %.*s\n"
+msgstr " %u: koko: %u, liput: 0x%02x, nimi: %.*s\n"
+
+#: vms-alpha.c:7720
+#, c-format
+msgid " quad-word relocation fixups:\n"
+msgstr " quad-sanaiset sijoituskorjaukset:\n"
+
+#: vms-alpha.c:7725
+#, c-format
+msgid " long-word relocation fixups:\n"
+msgstr " long-word-sijoituskorjaukset:\n"
+
+#: vms-alpha.c:7730
+#, c-format
+msgid " quad-word .address reference fixups:\n"
+msgstr " quad-word .address -viitekorjaukset:\n"
+
+#: vms-alpha.c:7735
+#, c-format
+msgid " long-word .address reference fixups:\n"
+msgstr " long-word .address -viitekorjaukset:\n"
+
+#: vms-alpha.c:7740
+#, c-format
+msgid " Code Address Reference Fixups:\n"
+msgstr " Koodiosoiteviitekorjaukset:\n"
+
+#: vms-alpha.c:7745
+#, c-format
+msgid " Linkage Pairs Reference Fixups:\n"
+msgstr " Linkitysparien viitekorjaukset:\n"
+
+#: vms-alpha.c:7754
+#, c-format
+msgid " Change Protection (%u entries):\n"
+msgstr " Vaihda suoja (%u alkiota):\n"
+
+#: vms-alpha.c:7759
+#, c-format
+msgid " base: 0x%08x %08x, size: 0x%08x, prot: 0x%08x "
+msgstr " kanta: 0x%08x %08x, koko: 0x%08x, prot: 0x%08x "
+
+#. FIXME: we do not yet support relocatable link. It is not obvious
+#. how to do it for debug infos.
+#: vms-alpha.c:8599
+msgid "%P: relocatable link is not supported\n"
+msgstr "%P: sijoitettava linkki ei ole tuettu\n"
+
+#: vms-alpha.c:8669
+msgid "%P: multiple entry points: in modules %B and %B\n"
+msgstr "%P: useita tulokohtia: moduuleissa %B ja %B\n"
+
+#: vms-lib.c:1444
+#, c-format
+msgid "could not open shared image '%s' from '%s'"
+msgstr "ei voitu avata jaettua vedosta '%s' kohteesta '%s'"
+
+#: vms-misc.c:360
+msgid "_bfd_vms_output_counted called with zero bytes"
+msgstr "_bfd_vms_output_counted kutsuttu nollatavuilla"
+
+#: vms-misc.c:365
+msgid "_bfd_vms_output_counted called with too many bytes"
+msgstr "_bfd_vms_output_counted kutsuttu liian monilla tavuilla"
+
+#: xcofflink.c:824
+#, c-format
+msgid "%s: XCOFF shared object when not producing XCOFF output"
+msgstr "%s: XCOFF jaettu objekti kun ei tuoteta XCOFF-tulostetta"
+
+#: xcofflink.c:845
+#, c-format
+msgid "%s: dynamic object with no .loader section"
+msgstr "%s: dynaaminen objekti ilman â€.loaderâ€-lohkoa"
+
+#: xcofflink.c:1404
+msgid "%B: `%s' has line numbers but no enclosing section"
+msgstr "%B: â€%s†on rivinumerot, mutta ei sulkevaa lohkoa"
+
+#: xcofflink.c:1456
+msgid "%B: class %d symbol `%s' has no aux entries"
+msgstr "%B: luokassa %d symbolissa â€%s†ei ole aputulokohtia"
+
+#: xcofflink.c:1478
+msgid "%B: symbol `%s' has unrecognized csect type %d"
+msgstr "%B: symbolissa â€%s†on tunnistamaton ohjauslohkotyyppi %d"
+
+#: xcofflink.c:1490
+msgid "%B: bad XTY_ER symbol `%s': class %d scnum %d scnlen %d"
+msgstr "%B: virheellinen XTY_ER-symboli â€%sâ€: luokka %d ohjauslohkonumero %d ohjauslohkopituus %d"
+
+#: xcofflink.c:1519
+msgid "%B: XMC_TC0 symbol `%s' is class %d scnlen %d"
+msgstr "%B: XMC_TC0-symboli â€%s†on luokka %d ohjauslohkopituus %d"
+
+#: xcofflink.c:1665
+msgid "%B: csect `%s' not in enclosing section"
+msgstr "%B: ohjauslohkoa â€%s†ei ole sulkeutuvassa lohkossa"
+
+#: xcofflink.c:1772
+msgid "%B: misplaced XTY_LD `%s'"
+msgstr "%B: väärin sijoitettu XTY_LD â€%sâ€"
+
+#: xcofflink.c:2091
+msgid "%B: reloc %s:%d not in csect"
+msgstr "%B: reloc-tietue %s:%d ei ole ohjauslohkossa"
+
+#: xcofflink.c:3182
+#, c-format
+msgid "%s: no such symbol"
+msgstr "%s: tuntematon symboli"
+
+#: xcofflink.c:3287
+#, c-format
+msgid "warning: attempt to export undefined symbol `%s'"
+msgstr "varoitus: yritettiin viedä määrittelemätön symboli â€%sâ€"
+
+#: xcofflink.c:3666
+msgid "error: undefined symbol __rtinit"
+msgstr "virhe: määrittelemätön symboli â€__rtinitâ€"
+
+#: xcofflink.c:4045
+msgid "%B: loader reloc in unrecognized section `%s'"
+msgstr "%B: â€loader relocâ€-tietue tunnistamattomassa lohkossa â€%s"
+
+#: xcofflink.c:4056
+msgid "%B: `%s' in loader reloc but not loader sym"
+msgstr "%B: â€%s†â€loader relocâ€-tietueessa, mutta ei â€loader.symâ€-binaarissa"
+
+#: xcofflink.c:4072
+msgid "%B: loader reloc in read-only section %A"
+msgstr "%B: â€loader relocâ€-tietue kirjoitussuojatussa lohkossa %A"
+
+#: xcofflink.c:5094
+#, c-format
+msgid "TOC overflow: 0x%lx > 0x10000; try -mminimal-toc when compiling"
+msgstr "Sisältöluettelon ylivuoto: 0x%lx > 0x10000; yritä â€-mminimal-toc†käännettäessä"
+
+#: peigen.c:1009 pepigen.c:1009 pex64igen.c:1009
+#, c-format
+msgid "%s: line number overflow: 0x%lx > 0xffff"
+msgstr "%s: rivinumeroylivuoto: 0x%lx > 0xffff"
+
+#: peigen.c:1036 pepigen.c:1036 pex64igen.c:1036
+msgid "Export Directory [.edata (or where ever we found it)]"
+msgstr "Vientihakemisto [.edata (tai missä sen sitten löysimmekin)]"
+
+#: peigen.c:1037 pepigen.c:1037 pex64igen.c:1037
+msgid "Import Directory [parts of .idata]"
+msgstr "Tuontihakemisto [â€.idataâ€-osat]"
+
+#: peigen.c:1038 pepigen.c:1038 pex64igen.c:1038
+msgid "Resource Directory [.rsrc]"
+msgstr "Resurssihakemisto [.rsrc]"
+
+#: peigen.c:1039 pepigen.c:1039 pex64igen.c:1039
+msgid "Exception Directory [.pdata]"
+msgstr "Poikkeushakemisto [.pdata]"
+
+#: peigen.c:1040 pepigen.c:1040 pex64igen.c:1040
+msgid "Security Directory"
+msgstr "Turvallisuushakemisto"
+
+#: peigen.c:1041 pepigen.c:1041 pex64igen.c:1041
+msgid "Base Relocation Directory [.reloc]"
+msgstr "Perussijoitushakemisto [.reloc]"
+
+#: peigen.c:1042 pepigen.c:1042 pex64igen.c:1042
+msgid "Debug Directory"
+msgstr "Virheenetsintähakemisto"
+
+#: peigen.c:1043 pepigen.c:1043 pex64igen.c:1043
+msgid "Description Directory"
+msgstr "Kuvaushakemisto"
+
+#: peigen.c:1044 pepigen.c:1044 pex64igen.c:1044
+msgid "Special Directory"
+msgstr "Erityishakemisto"
+
+#: peigen.c:1045 pepigen.c:1045 pex64igen.c:1045
+msgid "Thread Storage Directory [.tls]"
+msgstr "Säievarastohakemisto [.tls]"
+
+#: peigen.c:1046 pepigen.c:1046 pex64igen.c:1046
+msgid "Load Configuration Directory"
+msgstr "Lataa konfigurationhakemisto"
+
+#: peigen.c:1047 pepigen.c:1047 pex64igen.c:1047
+msgid "Bound Import Directory"
+msgstr "Sidottu tuontihakemisto"
+
+#: peigen.c:1048 pepigen.c:1048 pex64igen.c:1048
+msgid "Import Address Table Directory"
+msgstr "Tuontiosoitetauluhakemisto"
+
+#: peigen.c:1049 pepigen.c:1049 pex64igen.c:1049
+msgid "Delay Import Directory"
+msgstr "Viivetuontihakemisto"
+
+#: peigen.c:1050 pepigen.c:1050 pex64igen.c:1050
+msgid "CLR Runtime Header"
+msgstr "CLR ajoaikaotsake"
+
+#: peigen.c:1051 pepigen.c:1051 pex64igen.c:1051
+msgid "Reserved"
+msgstr "Varattu"
+
+#: peigen.c:1111 pepigen.c:1111 pex64igen.c:1111
+#, c-format
+msgid ""
+"\n"
+"There is an import table, but the section containing it could not be found\n"
+msgstr ""
+"\n"
+"Tuontitaulu löytyi, mutta ei lohkoa, joka sisältää sen\n"
+
+#: peigen.c:1116 pepigen.c:1116 pex64igen.c:1116
+#, c-format
+msgid ""
+"\n"
+"There is an import table in %s at 0x%lx\n"
+msgstr ""
+"\n"
+"Tuontitaulu lohkossa %s osoitteessa 0x%lx\n"
+
+#: peigen.c:1158 pepigen.c:1158 pex64igen.c:1158
+#, c-format
+msgid ""
+"\n"
+"Function descriptor located at the start address: %04lx\n"
+msgstr ""
+"\n"
+"Funktiokuvaaja sijaitsi alkuosoitteessa: %04lx\n"
+
+#: peigen.c:1161 pepigen.c:1161 pex64igen.c:1161
+#, c-format
+msgid "\tcode-base %08lx toc (loadable/actual) %08lx/%08lx\n"
+msgstr "\tkoodipohja %08lx sisältöluettelo (ladattava/todellinen) %08lx/%08lx\n"
+
+#: peigen.c:1169 pepigen.c:1169 pex64igen.c:1169
+#, c-format
+msgid ""
+"\n"
+"No reldata section! Function descriptor not decoded.\n"
+msgstr ""
+"\n"
+"Ei reldata-lohkoa! Funktiokuvaaja ei ole koodattu.\n"
+
+#: peigen.c:1174 pepigen.c:1174 pex64igen.c:1174
+#, c-format
+msgid ""
+"\n"
+"The Import Tables (interpreted %s section contents)\n"
+msgstr ""
+"\n"
+"Tuontitaulut (tulkittu %s lohkosisältö)\n"
+
+# Taulukko-otsake, jossa sanat on kahdella rivillä (ilman tavuviivaa), esimerkiksi: Vihjetaulu
+#: peigen.c:1177 pepigen.c:1177 pex64igen.c:1177
+#, c-format
+msgid ""
+" vma: Hint Time Forward DLL First\n"
+" Table Stamp Chain Name Thunk\n"
+msgstr ""
+" vma: Vihje- Aika- Jatkoläh. DLL- Ensimmäinen\n"
+" taulu leima ketju nimi Thunk-funktio\n"
+
+#: peigen.c:1225 pepigen.c:1225 pex64igen.c:1225
+#, c-format
+msgid ""
+"\n"
+"\tDLL Name: %s\n"
+msgstr ""
+"\n"
+"\tDLL-nimi: %s\n"
+
+#: peigen.c:1236 pepigen.c:1236 pex64igen.c:1236
+#, c-format
+msgid "\tvma: Hint/Ord Member-Name Bound-To\n"
+msgstr "\tvma: Vihje/Jär Jäsen-Nimi Sidottu\n"
+
+#: peigen.c:1261 pepigen.c:1261 pex64igen.c:1261
+#, c-format
+msgid ""
+"\n"
+"There is a first thunk, but the section containing it could not be found\n"
+msgstr ""
+"\n"
+"Ensimmäinen thunk-funktio löytyi, mutta ei sen sisältävää lohkoa\n"
+
+#: peigen.c:1423 pepigen.c:1423 pex64igen.c:1423
+#, c-format
+msgid ""
+"\n"
+"There is an export table, but the section containing it could not be found\n"
+msgstr ""
+"\n"
+"Vientitaulu löytyi, mutta ei sen sisältävää lohkoa\n"
+
+#: peigen.c:1432 pepigen.c:1432 pex64igen.c:1432
+#, c-format
+msgid ""
+"\n"
+"There is an export table in %s, but it does not fit into that section\n"
+msgstr ""
+"\n"
+"Vientitaulu kohteessa %s, mutta ei sovi tuohon lohkoon\n"
+
+#: peigen.c:1438 pepigen.c:1438 pex64igen.c:1438
+#, c-format
+msgid ""
+"\n"
+"There is an export table in %s at 0x%lx\n"
+msgstr ""
+"\n"
+"Vientitaulu lohkossa %s osoitteessa 0x%lx\n"
+
+#: peigen.c:1466 pepigen.c:1466 pex64igen.c:1466
+#, c-format
+msgid ""
+"\n"
+"The Export Tables (interpreted %s section contents)\n"
+"\n"
+msgstr ""
+"\n"
+"Vientitaulut (tulkittu %s lohkosisältö)\n"
+"\n"
+
+#: peigen.c:1470 pepigen.c:1470 pex64igen.c:1470
+#, c-format
+msgid "Export Flags \t\t\t%lx\n"
+msgstr "Vientiliput \t\t\t%lx\n"
+
+#: peigen.c:1473 pepigen.c:1473 pex64igen.c:1473
+#, c-format
+msgid "Time/Date stamp \t\t%lx\n"
+msgstr "Aika/Päivämääräleima \t\t%lx\n"
+
+#: peigen.c:1476 pepigen.c:1476 pex64igen.c:1476
+#, c-format
+msgid "Major/Minor \t\t\t%d/%d\n"
+msgstr "Suurempi/Pienempi \t\t\t%d/%d\n"
+
+#: peigen.c:1479 pepigen.c:1479 pex64igen.c:1479
+#, c-format
+msgid "Name \t\t\t\t"
+msgstr "Nimi \t\t\t\t"
+
+#: peigen.c:1485 pepigen.c:1485 pex64igen.c:1485
+#, c-format
+msgid "Ordinal Base \t\t\t%ld\n"
+msgstr "Järjestyslukukanta \t\t\t%ld\n"
+
+#: peigen.c:1488 pepigen.c:1488 pex64igen.c:1488
+#, c-format
+msgid "Number in:\n"
+msgstr "Numero kohteessa:\n"
+
+#: peigen.c:1491 pepigen.c:1491 pex64igen.c:1491
+#, c-format
+msgid "\tExport Address Table \t\t%08lx\n"
+msgstr "\tVientiosoitetaulu \t\t%08lx\n"
+
+#: peigen.c:1495 pepigen.c:1495 pex64igen.c:1495
+#, c-format
+msgid "\t[Name Pointer/Ordinal] Table\t%08lx\n"
+msgstr "\t[Nimiosoitin/Järjestysnumero] taulu\t%08lx\n"
+
+#: peigen.c:1498 pepigen.c:1498 pex64igen.c:1498
+#, c-format
+msgid "Table Addresses\n"
+msgstr "Tauluosoitteet\n"
+
+#: peigen.c:1501 pepigen.c:1501 pex64igen.c:1501
+#, c-format
+msgid "\tExport Address Table \t\t"
+msgstr "\tVientiosoitetaulu \t\t"
+
+#: peigen.c:1506 pepigen.c:1506 pex64igen.c:1506
+#, c-format
+msgid "\tName Pointer Table \t\t"
+msgstr "\tNimiosoitintaulu \t\t"
+
+#: peigen.c:1511 pepigen.c:1511 pex64igen.c:1511
+#, c-format
+msgid "\tOrdinal Table \t\t\t"
+msgstr "\tJärjestysnumerotaulu \t\t\t"
+
+#: peigen.c:1525 pepigen.c:1525 pex64igen.c:1525
+#, c-format
+msgid ""
+"\n"
+"Export Address Table -- Ordinal Base %ld\n"
+msgstr ""
+"\n"
+"Vientiosoitetaulu -- Järjestyslukukanta %ld\n"
+
+#: peigen.c:1544 pepigen.c:1544 pex64igen.c:1544
+msgid "Forwarder RVA"
+msgstr "Jatkolähetyksen suhteellinen muuttujaosoite"
+
+#: peigen.c:1555 pepigen.c:1555 pex64igen.c:1555
+msgid "Export RVA"
+msgstr "Viennin suhteellinen muuttujaosoite"
+
+#: peigen.c:1562 pepigen.c:1562 pex64igen.c:1562
+#, c-format
+msgid ""
+"\n"
+"[Ordinal/Name Pointer] Table\n"
+msgstr ""
+"\n"
+"[Järjestysnumero/Nimiosoitin] Taulu\n"
+
+#: peigen.c:1622 peigen.c:1805 pepigen.c:1622 pepigen.c:1805 pex64igen.c:1622
+#: pex64igen.c:1805
+#, c-format
+msgid "Warning, .pdata section size (%ld) is not a multiple of %d\n"
+msgstr "Varoitus,†.pdataâ€-lohkokoko (%ld) ei ole %d:n monikerta\n"
+
+#: peigen.c:1629 pepigen.c:1629 pex64igen.c:1629
+#, c-format
+msgid " vma:\t\t\tBegin Address End Address Unwind Info\n"
+msgstr " vma:\t\t\tAlkuosoite Loppuosoite Unwind-tiedot\n"
+
+# Taulukko-otsake, jossa sanat jakautuvat taas alekkain kahdelle riville ilman tavuviivoja
+#: peigen.c:1631 pepigen.c:1631 pex64igen.c:1631
+#, c-format
+msgid ""
+" vma:\t\tBegin End EH EH PrologEnd Exception\n"
+" \t\tAddress Address Handler Data Address Mask\n"
+msgstr ""
+" vma:\t\tAlku- Loppu- EH-käsit- EH- PrologEnd Poikkeus-\n"
+" \t\tosoite osoite telijä data osoite peite\n"
+
+#: peigen.c:1705 pepigen.c:1705 pex64igen.c:1705
+#, c-format
+msgid " Register save millicode"
+msgstr " Rekisteri tallentaa millicode-bitin"
+
+#: peigen.c:1708 pepigen.c:1708 pex64igen.c:1708
+#, c-format
+msgid " Register restore millicode"
+msgstr " Rekisteri palauttaa millicode-bitin"
+
+#: peigen.c:1711 pepigen.c:1711 pex64igen.c:1711
+#, c-format
+msgid " Glue code sequence"
+msgstr " Vihje-koodisekvenssi"
+
+#: peigen.c:1811 pepigen.c:1811 pex64igen.c:1811
+#, c-format
+msgid ""
+" vma:\t\tBegin Prolog Function Flags Exception EH\n"
+" \t\tAddress Length Length 32b exc Handler Data\n"
+msgstr ""
+" vma:\t\tAlku- Prologi- Funktio- Liput Poikkeus- EH-\n"
+" \t\tosoite pituus pituus 32b exc käsittelijä Data\n"
+
+#: peigen.c:1937 pepigen.c:1937 pex64igen.c:1937
+#, c-format
+msgid ""
+"\n"
+"\n"
+"PE File Base Relocations (interpreted .reloc section contents)\n"
+msgstr ""
+"\n"
+"\n"
+"PE-tiedostokantasijoitukset (tulkittu â€.relocâ€-lohkosisältö)\n"
+
+# Esimerkiksi välimuistissa RAM-alue koostuu usein pienistä palasista, joita kutsutaan nimellä chunk. Suomensin sen tässä sanalla alilohko
+#: peigen.c:1966 pepigen.c:1966 pex64igen.c:1966
+#, c-format
+msgid ""
+"\n"
+"Virtual Address: %08lx Chunk size %ld (0x%lx) Number of fixups %ld\n"
+msgstr ""
+"\n"
+"Virtuaaliosoite: %08lx alilohkokoko %ld (0x%lx) Korjausten lukumäärä %ld\n"
+
+#: peigen.c:1979 pepigen.c:1979 pex64igen.c:1979
+#, c-format
+msgid "\treloc %4d offset %4x [%4lx] %s"
+msgstr "\treloc-tietue %4d siirrososoite %4x [%4lx] %s"
+
+#: peigen.c:2023 pepigen.c:2023 pex64igen.c:2023
+#, c-format
+msgid "%*.s Entry: "
+msgstr "%*.s Entry: "
+
+#: peigen.c:2043 pepigen.c:2043 pex64igen.c:2043
+#, c-format
+msgid "name: [val: %08lx len %d]: "
+msgstr "nimi: [arvo: %08lx pituus %d]: "
+
+#: peigen.c:2054 pepigen.c:2054 pex64igen.c:2054
+#, c-format
+msgid "<corrupt string length: %#x>"
+msgstr "<rikkinäinen merkkijonopituus: %#x>"
+
+#: peigen.c:2057 pepigen.c:2057 pex64igen.c:2057
+#, c-format
+msgid "<corrupt string offset: %#lx>"
+msgstr "<rikkinäinen merkkijonosiirros: %#lx>"
+
+#: peigen.c:2060 pepigen.c:2060 pex64igen.c:2060
+#, c-format
+msgid "ID: %#08lx"
+msgstr "Tunniste: %#08lx"
+
+#: peigen.c:2063 pepigen.c:2063 pex64igen.c:2063
+#, c-format
+msgid ", Value: %#08lx\n"
+msgstr ", Arvo: %#08lx\n"
+
+#: peigen.c:2074 pepigen.c:2074 pex64igen.c:2074
+#, c-format
+msgid "%*.s Leaf: Addr: %#08lx, Size: %#08lx, Codepage: %d\n"
+msgstr "%*.s Lehti: Osoite: %#08lx, Koko: %#08lx, Koodisivu: %d\n"
+
+#: peigen.c:2116 pepigen.c:2116 pex64igen.c:2116
+#, c-format
+msgid " Table: Char: %d, Time: %08lx, Ver: %d/%d, Num Names: %d, IDs: %d\n"
+msgstr " Taulu: Merkki: %d, Aika: %08lx, Ver: %d/%d, Nimimäärä: %d, Tunnisteet: %d\n"
+
+#: peigen.c:2204 pepigen.c:2204 pex64igen.c:2204
+#, c-format
+msgid "Corrupt .rsrc section detected!\n"
+msgstr "Rikkinäinen .rsrc-lohko havaittu!\n"
+
+#: peigen.c:2220 pepigen.c:2220 pex64igen.c:2220
+#, c-format
+msgid ""
+"\n"
+"WARNING: Extra data in .rsrc section - it will be ignored by Windows:\n"
+msgstr ""
+"\n"
+"VAROITUS: Lisätietoja lohkossa .rsrc - Windows ohittaa ne:\n"
+
+#. The MS dumpbin program reportedly ands with 0xff0f before
+#. printing the characteristics field. Not sure why. No reason to
+#. emulate it here.
+#: peigen.c:2243 pepigen.c:2243 pex64igen.c:2243
+#, c-format
+msgid ""
+"\n"
+"Characteristics 0x%x\n"
+msgstr ""
+"\n"
+"Luonteenominaisuus 0x%x\n"
+
+#: peigen.c:3194 pepigen.c:3194 pex64igen.c:3194
+#, c-format
+msgid ".rsrc merge failure: duplicate string resource: %d"
+msgstr ".rsrc-lohkon yhdistämisvirhe: merkkijonoresurssin kaksoiskappale: %d"
+
+#: peigen.c:3329 pepigen.c:3329 pex64igen.c:3329
+msgid ".rsrc merge failure: multiple non-default manifests"
+msgstr ".rsrc-lohkon yhdistämisvirhe: useita ei-oletus-manifest-tietoja"
+
+#: peigen.c:3347 pepigen.c:3347 pex64igen.c:3347
+msgid ".rsrc merge failure: a directory matches a leaf"
+msgstr ".rsrc-lohkon yhdistämisvirhe: hakemisto täsmää lehteen"
+
+#: peigen.c:3389 pepigen.c:3389 pex64igen.c:3389
+msgid ".rsrc merge failure: duplicate leaf"
+msgstr ".rsrc-lohkon yhdistämisvirhe: lehden kaksoiskappale"
+
+#: peigen.c:3391 pepigen.c:3391 pex64igen.c:3391
+#, c-format
+msgid ".rsrc merge failure: duplicate leaf: %s"
+msgstr ".rsrc-lohkon yhdistämisvirhe: lehden kaksoiskappale: %s"
+
+#: peigen.c:3457 pepigen.c:3457 pex64igen.c:3457
+msgid ".rsrc merge failure: dirs with differing characteristics\n"
+msgstr ".rsrc-lohkon yhdistämisvirhe: hakemistot eriävillä ominaisuuksilla\n"
+
+#: peigen.c:3464 pepigen.c:3464 pex64igen.c:3464
+msgid ".rsrc merge failure: differing directory versions\n"
+msgstr ".rsrc-lohkon yhdistämisvirhe: eriävät hakemistoversiot\n"
+
+#. Corrupted .rsrc section - cannot merge.
+#: peigen.c:3537 pepigen.c:3537 pex64igen.c:3537
+#, c-format
+msgid "%s: .rsrc merge failure: corrupt .rsrc section"
+msgstr "%s: .rsrc-lohkon yhdistämisvirhe: rikkinäinen .rsrc-lohko"
+
+#: peigen.c:3673 pepigen.c:3673 pex64igen.c:3673
+msgid "%B: unable to fill in DataDictionary[1] because .idata$2 is missing"
+msgstr "%B: DataDictionary[1]:ia ei voi täyttää, koska â€.idata$2†puuttuu"
+
+#: peigen.c:3693 pepigen.c:3693 pex64igen.c:3693
+msgid "%B: unable to fill in DataDictionary[1] because .idata$4 is missing"
+msgstr "%B: DataDictionary[1]:ia ei voi täyttää, koska â€.idata$4†puuttuu"
+
+#: peigen.c:3714 pepigen.c:3714 pex64igen.c:3714
+msgid "%B: unable to fill in DataDictionary[12] because .idata$5 is missing"
+msgstr "%B: DataDictionary[12]:ia ei voi täyttää, koska â€.idata$5†puuttuu"
+
+#: peigen.c:3734 pepigen.c:3734 pex64igen.c:3734
+msgid "%B: unable to fill in DataDictionary[PE_IMPORT_ADDRESS_TABLE (12)] because .idata$6 is missing"
+msgstr "%B: DataDictionary[PE_IMPORT_ADDRESS_TABLE (12)]:ia ei voi täyttää, koska â€.idata$6†puuttuu"
+
+#: peigen.c:3776 pepigen.c:3776 pex64igen.c:3776
+msgid "%B: unable to fill in DataDictionary[PE_IMPORT_ADDRESS_TABLE(12)] because .idata$6 is missing"
+msgstr "%B: DataDictionary[PE_IMPORT_ADDRESS_TABLE(12)]:ia ei voi täyttää, koska â€.idata$6†puuttuu"
+
+#: peigen.c:3801 pepigen.c:3801 pex64igen.c:3801
+msgid "%B: unable to fill in DataDictionary[9] because __tls_used is missing"
+msgstr "%B: DataDictionary[9]:ia ei voi täyttää, koska â€__tls_used†puuttuu"
+
+#~ msgid "%B: unable to initialize commpress status for section %s"
+#~ msgstr "%B: ei kyetä alustamaan tiivistystilaa lohkolle %s"
+
+#~ msgid "%B: unable to initialize decommpress status for section %s"
+#~ msgstr "%B: ei kyetä alustamaan tiivistyksenpurkutilaa lohkolle %s"
+
+#~ msgid ""
+#~ "%B(%s): warning: interworking not enabled.\n"
+#~ " first occurrence: %B: thumb call to arm"
+#~ msgstr ""
+#~ "%B(%s): varoitus: yhteistoimivuus vanhan koodin kanssa ei ole käytössä.\n"
+#~ " ensimmäinen esiintymä: %B: thumb-kutsu arm-koodiin"
+
+#~ msgid "DIV usage mismatch between %B and %B"
+#~ msgstr "DIV-käyttötäsmäämättömyys kohteiden %B ja %B välillä"
+
+#~ msgid "%B: bad relocation section name `%s'"
+#~ msgstr "%B: virheellinen sijoituslohkonimi â€%sâ€"
+
+#~ msgid "%P: dynamic variable `%s' is zero size\n"
+#~ msgstr "%P: dynaaminen muuttuja â€%s†on nollakokoinen\n"
+
+#~ msgid " [64-bit doubles]"
+#~ msgstr " [64-bittiset double-liukuluvut]"
+
+#~ msgid " [dsp]"
+#~ msgstr " [paikkariippumaton koodi]"
+
+#~ msgid "%P: %H: automatic multiple TOCs not supported using your crt files; recompile with -mminimal-toc or upgrade gcc\n"
+#~ msgstr "%P: %H: automaattisia useita sisältöluettelotauluja ei ole tuettu crt-tiedostoissasi; käännä uudelleen â€-mminimal-tocâ€-argumentilla tai päivitä gcc\n"
+
+#~ msgid "%P: %H: sibling call optimization to `%s' does not allow automatic multiple TOCs; recompile with -mminimal-toc or -fno-optimize-sibling-calls, or make `%s' extern\n"
+#~ msgstr "%P: %H: sisarruskutsuoptimointi kohteeseen â€%s†ei salli automaattisia useita sisällysluettelotauluja; käännä uudelleen â€-mminimal-tocâ€-argumentilla tai â€-fno-optimize-sibling-callsâ€-argumentilla, tai tee kohteesta â€%s†ulkoinen\n"
+
+#~ msgid "note: '%s' is defined in DSO %B so try adding it to the linker command line"
+#~ msgstr "huomatus: ’%s’ on määritelty kohteessa DSO %B, joten yritä lisätä se linkkittäjän komentoriville"
+
+#~ msgid "Warning: %B uses -msingle-float, %B uses -mdouble-float"
+#~ msgstr "Varoitus: %B käyttää â€-msingle-floatâ€-valitsinta, %B käyttää â€-mdouble-floatâ€-valitsinta"
+
+#~ msgid "Warning: %B uses -msingle-float, %B uses -mips32r2 -mfp64"
+#~ msgstr "Varoitus: %B käyttää â€-msingle-floatâ€-valitsinta, %B käyttää â€-mips32r2 -mfp64â€-valitsimia"
+
+#~ msgid "Warning: %B uses -mdouble-float, %B uses -mips32r2 -mfp64"
+#~ msgstr "Varoitus: %B käyttää â€-mdouble-floatâ€-valitsinta, %B käyttää â€-mips32r2 -mfp64â€-valitsimia"
+
+#~ msgid "bfd_mach_o_read_symtab_symbol: symbol \"%s\" is unsupported 'indirect' reference: setting to undefined"
+#~ msgstr "bfd_mach_o_read_symtab_symbol: symboli â€%s†on tukematon ’epäsuora’ viite: asetus on määrittelemätön"
+
+#~ msgid "bfd_mach_o_read_dysymtab_symbol: unable to read %lu bytes at %lu"
+#~ msgstr "bfd_mach_o_read_dysymtab_symbol: ei kyetä lukemaan %lu tavua osoitteesta %lu"
+
+#~ msgid "Mach-O header:\n"
+#~ msgstr "Mach-O otsake:\n"
+
+#~ msgid " magic : %08lx\n"
+#~ msgstr " maaginen : %08lx\n"
+
+#~ msgid " cputype : %08lx (%s)\n"
+#~ msgstr " prosessorityyppi : %08lx (%s)\n"
+
+#~ msgid " filetype : %08lx (%s)\n"
+#~ msgstr " tiedostotyyppi : %08lx (%s)\n"
+
+#~ msgid " ncmds : %08lx (%lu)\n"
+#~ msgstr "ncmds : %08lx (%lu)\n"
+
+#~ msgid " sizeofcmds: %08lx\n"
+#~ msgstr " komentojenkoko : %08lx\n"
+
+#~ msgid " flags : %08lx ("
+#~ msgstr " liput : %08lx ("
+
+#~ msgid " reserved : %08x\n"
+#~ msgstr " varattu : %08x\n"
+
+#~ msgid "Segments and Sections:\n"
+#~ msgstr "Segmentit ja lohkot:\n"
+
+#~ msgid " #: Segment name Section name Address\n"
+#~ msgstr " #: Segmenttinimi Lohkonnimi Osoite\n"
+
+#~ msgid "Symbol %s replaced by %s\n"
+#~ msgstr "Symboli %s korvattu kohteella %s\n"
+
+#~ msgid "%B(%A+0x%lx): cannot reach %s"
+#~ msgstr "%B(%A+0x%lx): kohdetta %s ei voi tavoittaa"
+
+#~ msgid "%B: warning: ignoring duplicate section `%A'\n"
+#~ msgstr "%B: varoitus: ei oteta huomioon lohkon â€%A†kaksoiskappaletta\n"
+
+#~ msgid "%B: warning: duplicate section `%A' has different size\n"
+#~ msgstr "%B: varoitus: lohkon â€%A†kaksoiskappaleessa on eri koko\n"
+
+#~ msgid "relocation references a different segment"
+#~ msgstr "sijoitus viittaa eri segmenttiin"
+
+#~ msgid "%B: relocation type %d not implemented"
+#~ msgstr "%B: sijoitustyyppiä %d ei ole toteutettu"
+
+#~ msgid "warning: %B and %B differ in position-dependence of data addressing"
+#~ msgstr "varoitus: %B ja %B eroavat siinä, että datan osoitteet ovat paikkariippuvaisia"
+
+#~ msgid "warning: %B and %B differ in position-dependence of code addressing"
+#~ msgstr "varoitus: %B ja %B eroavat siinä, että koodin osoitteet ovat paikkariippuvaisia"
+
+#~ msgid "Can't Make it a Short Jump"
+#~ msgstr "Sitä ei voi tehdä lyhyeksi hypyksi"
+
+#~ msgid "Exceeds Long Jump Range"
+#~ msgstr "Ylittää pitkän hypyn arvoalueen"
+
+#~ msgid "Absolute address Exceeds 16 bit Range"
+#~ msgstr "Absoluuttinen osoite ylittää 16-bittialueen"
+
+#~ msgid "Absolute address Exceeds 8 bit Range"
+#~ msgstr "Absoluuttinen osoite ylittää 8-bittialueen"
+
+#~ msgid "Unrecognized Reloc Type"
+#~ msgstr "Tunnistamaton Reloc-tyyppi"
+
+#~ msgid "corrupt or empty %s section in %B"
+#~ msgstr "rikkinäinen tai tyhjä %s-lohko kohteessa %B"
+
+#~ msgid "%s: invalid DSO for symbol `%s' definition"
+#~ msgstr "%s: virheellinen DSO symbolin â€%s†määrittelylle"
+
+#~ msgid "%B: %A+0x%lx: jump to stub routine which is not jal"
+#~ msgstr "%B: %A+0x%lx: hyppää stub-rutiiniin, joka ei ole jal-käsky"
+
+#~ msgid "bfd_make_section (%s) failed"
+#~ msgstr "bfd_make_section (%s) ei onnistunut"
+
+#~ msgid "bfd_set_section_flags (%s, %x) failed"
+#~ msgstr "bfd_set_section_flags (%s, %x) ei onnistunut"
+
+#~ msgid "Size mismatch section %s=%lx, %s=%lx"
+#~ msgstr "Kokotäsmäämätön lohko %s=%lx, %s=%lx"
+
+#~ msgid "failed to enter %s"
+#~ msgstr "ei onnistuttu kirjoittamaan %s"
+
+#~ msgid "No Mem !"
+#~ msgstr "Ei muistia !"
+
+#~ msgid "reserved STO cmd %d"
+#~ msgstr "varattu STO-komento %d"
+
+#~ msgid "reserved OPR cmd %d"
+#~ msgstr "varattu OPR-komento %d"
+
+#~ msgid "reserved CTL cmd %d"
+#~ msgstr "varattu CTL-komento %d"
+
+#~ msgid "reserved STC cmd %d"
+#~ msgstr "varattu STC-komento %d"
+
+#~ msgid "stack-from-image not implemented"
+#~ msgstr "stack-from-image ei ole toteutettu"
+
+#~ msgid "stack-entry-mask not fully implemented"
+#~ msgstr "stack-entry-mask ei ole täysin toteutettu"
+
+#~ msgid "PASSMECH not fully implemented"
+#~ msgstr "PASSMECH ei ole täysin toteutettu"
+
+#~ msgid "stack-local-symbol not fully implemented"
+#~ msgstr "stack-local-symbol ei ole täysin toteutettu"
+
+#~ msgid "stack-literal not fully implemented"
+#~ msgstr "stack-literal ei ole täysin toteutettu"
+
+#~ msgid "stack-local-symbol-entry-point-mask not fully implemented"
+#~ msgstr "stack-local-symbol-entry-point-mask ei ole täysin toteutettu"
+
+#~ msgid "%s: not fully implemented"
+#~ msgstr "%s: ei ole täysin toteutettu"
+
+#~ msgid "obj code %d not found"
+#~ msgstr "obj-koodia %d ei löytynyt"
+
+#~ msgid "Reloc size error in section %s"
+#~ msgstr "Reloc-kokovirhe lohkossa %s"
+
+#~ msgid "ERROR: %B: Incompatible object tag '%s':%d"
+#~ msgstr "VIRHE: %B: Yhteensopimaton objektitunnus â€%sâ€:%d"
+
+#~ msgid "%B(%A): warning: unresolvable relocation against symbol `%s'"
+#~ msgstr "%B(%A): varoitus: ratkaisematon sijoitus käyttäen symbolia â€%sâ€"
+
+#~ msgid "%B: Internal inconsistency; no relocation section %s"
+#~ msgstr "%B: Sisäinen epäjohdonmukaisuus; ei sijoituslohkoa %s"
+
+#~ msgid "Could not find relocation section for %s"
+#~ msgstr "Ei löytynyt sijoituslohkoa kohteelle %s"
+
+#~ msgid "%B: GOT overflow: Number of R_68K_GOT8O and R_68K_GOT16O relocations > %d"
+#~ msgstr "%B: Yleissiirrostaulun ylivuoto: R_68K_GOT8O- ja R_68K_GOT16O-sijoitusten lukumäärä > %d"
+
+#~ msgid "%A link_order not found\n"
+#~ msgstr "%A link_order ei löytynyt\n"
+
+#~ msgid "%s: no symbol \"%s\""
+#~ msgstr "%s: ei symbolia â€%sâ€"
+
+#~ msgid "%s: loader reloc in unrecognized section `%s'"
+#~ msgstr "%s: â€loader relocâ€-tietue tunnistamattomassa lohkossa â€%sâ€"
+
+#~ msgid "%s: `%s' in loader reloc but not loader sym"
+#~ msgstr "%s: â€%s†â€loader relocâ€-tietueessa, mutta ei â€loader.symâ€-binaarissa"
+
+#~ msgid "Dwarf Error: DW_FORM_strp offset (%lu) greater than or equal to .debug_str size (%lu)."
+#~ msgstr "Dwarf-virhe: DW_FORM_strp siirrososoite (%lu) suurempi tai sama kuin â€.debug_strâ€-koko (%lu)."
+
+#~ msgid "Dwarf Error: Can't find .debug_abbrev section."
+#~ msgstr "Dwarf-virhe: Ei löydy â€.debug_abbrevâ€-lohkoa."
+
+#~ msgid "Dwarf Error: Abbrev offset (%lu) greater than or equal to .debug_abbrev size (%lu)."
+#~ msgstr "Dwarf-virhe: Lyhennesiirrososoite (%lu) suurempi tai sama kuin â€.debug_abbrevâ€-koko (%lu)."
+
+#~ msgid "Dwarf Error: Can't find .debug_ranges section."
+#~ msgstr "Dwarf-virhe: Ei löydy â€.debug_rangesâ€-lohkoa."
+
+#~ msgid "ERROR: %B: Conflicting definitions of wchar_t"
+#~ msgstr "VIRHE: %B: Ristiriitaisia wchar_t-määrittelyjä"
+
+#~ msgid "%B: relocation R_X86_64_PC32 against protected function `%s' can not be used when making a shared object"
+#~ msgstr "%B: sijoitusta R_X86_64_PC32 käyttäen suojattua funktiota â€%s†ei voida käyttää kun tehdään jaettua objektia"
+
+#~ msgid "R_FRV_GETTLSOFF_RELAX not applied to a call instruction"
+#~ msgstr "R_FRV_GETTLSOFF_RELAX ei sovelleta kutsukäskyyn"
+
+#~ msgid "%B: %s accessed both as normal and thread local symbol"
+#~ msgstr "%B: %s haettu sekä normaalina että säikeisenä paikallissymbolina"
+
+#~ msgid "Linker: error: Cannot fix ex9 relocation\n"
+#~ msgstr "Linkkeri: virhe: ex9-sijoituksen korjaus epäonnistui\n"
+
+#~ msgid "Linker: error: Cannot init ex9 hash table\n"
+#~ msgstr "Linkkeri: virhe: ex9-tiivistetauluvirheen alustus epäonnistui\n"
diff --git a/bfd/po/fr.gmo b/bfd/po/fr.gmo
new file mode 100644
index 0000000..176e230
--- /dev/null
+++ b/bfd/po/fr.gmo
Binary files differ
diff --git a/bfd/po/fr.po b/bfd/po/fr.po
new file mode 100644
index 0000000..83da6dc
--- /dev/null
+++ b/bfd/po/fr.po
@@ -0,0 +1,6352 @@
+# Messages français pour GNU concernant bfd.
+# Copyright (C) 2012 Free Software Foundation, Inc.
+# This file is distributed under the same license as the binutils package.
+# Michel Robitaille <robitail@IRO.UMontreal.CA>, traducteur depuis/since 1996.
+# Frédéric Marchal <fmarchal@perso.be>, 2012.
+msgid ""
+msgstr ""
+"Project-Id-Version: bfd-2.22.90\n"
+"Report-Msgid-Bugs-To: bug-binutils@gnu.org\n"
+"POT-Creation-Date: 2011-10-25 11:58+0100\n"
+"PO-Revision-Date: 2012-07-28 10:47+0200\n"
+"Last-Translator: Frédéric Marchal <fmarchal@perso.be>\n"
+"Language-Team: French <traduc@traduc.org>\n"
+"Language: fr\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n > 1);\n"
+"X-Generator: Lokalize 1.4\n"
+
+#: aout-adobe.c:127
+msgid "%B: Unknown section type in a.out.adobe file: %x\n"
+msgstr "%B: Type de section inconnu dans le fichier a.out.adobe: %x\n"
+
+#: aout-cris.c:199
+#, c-format
+msgid "%s: Invalid relocation type exported: %d"
+msgstr "%s: Type de réadressage exporté invalide: %d"
+
+#: aout-cris.c:242
+msgid "%B: Invalid relocation type imported: %d"
+msgstr "%B: Type de réadressage importé invalide: %d"
+
+#: aout-cris.c:253
+msgid "%B: Bad relocation record imported: %d"
+msgstr "%B: Mauvais enregistrement de réadressage importé: %d"
+
+#: aoutx.h:1273 aoutx.h:1611
+#, c-format
+msgid "%s: can not represent section `%s' in a.out object file format"
+msgstr "%s: ne peut représenter la section «%s» dans le fichier format objet a.out"
+
+#: aoutx.h:1577
+#, c-format
+msgid "%s: can not represent section for symbol `%s' in a.out object file format"
+msgstr "%s: ne peut représenter la section pour le symbole «%s» dans le fichier format objet a.out"
+
+#: aoutx.h:1579 vms-alpha.c:7671
+msgid "*unknown*"
+msgstr "*inconnu*"
+
+#: aoutx.h:4018 aoutx.h:4344
+msgid "%P: %B: unexpected relocation type\n"
+msgstr "%P: %B: type de réadressage non supporté\n"
+
+#: aoutx.h:5375
+#, c-format
+msgid "%s: relocatable link from %s to %s not supported"
+msgstr "%s: lien relocalisable de %s vers %s n'est pas supporté"
+
+#: archive.c:2203
+msgid "Warning: writing archive was slow: rewriting timestamp\n"
+msgstr "Attention: l'écriture de l'archive était lente: réécriture du cachet de date-heure\n"
+
+#: archive.c:2491
+msgid "Reading archive file mod timestamp"
+msgstr "Lecture du cachet date-heure modifié du fichier d'archive"
+
+#: archive.c:2515
+msgid "Writing updated armap timestamp"
+msgstr "Écriture du cachet date-heure armap mise à jour"
+
+#: bfd.c:398
+msgid "No error"
+msgstr "Pas d'erreur"
+
+#: bfd.c:399
+msgid "System call error"
+msgstr "Erreur d'appel système"
+
+#: bfd.c:400
+msgid "Invalid bfd target"
+msgstr "Cible bfd invalide"
+
+#: bfd.c:401
+msgid "File in wrong format"
+msgstr "Fichier dans un mauvais format"
+
+#: bfd.c:402
+msgid "Archive object file in wrong format"
+msgstr "Fichier objet d'archive dans un mauvais format"
+
+#: bfd.c:403
+msgid "Invalid operation"
+msgstr "Opération invalide"
+
+#: bfd.c:404
+msgid "Memory exhausted"
+msgstr "Mémoire épuisée"
+
+#: bfd.c:405
+msgid "No symbols"
+msgstr "Aucun symbole"
+
+#: bfd.c:406
+msgid "Archive has no index; run ranlib to add one"
+msgstr "L'archive n'a pas d'index; exécuter ranlib pour en ajouter un"
+
+#: bfd.c:407
+msgid "No more archived files"
+msgstr "Aucun autre fichier d'archive"
+
+#: bfd.c:408
+msgid "Malformed archive"
+msgstr "Archive mal formée"
+
+#: bfd.c:409
+msgid "File format not recognized"
+msgstr "Format de fichier non reconnu"
+
+#: bfd.c:410
+msgid "File format is ambiguous"
+msgstr "Format de fichier ambigu"
+
+#: bfd.c:411
+msgid "Section has no contents"
+msgstr "Section sans contenu"
+
+#: bfd.c:412
+msgid "Nonrepresentable section on output"
+msgstr "Section non-représentable sur la sortie"
+
+#: bfd.c:413
+msgid "Symbol needs debug section which does not exist"
+msgstr "Symboles ont besoin de la section de débug qui est inexistente"
+
+#: bfd.c:414
+msgid "Bad value"
+msgstr "Mauvaise valeur"
+
+#: bfd.c:415
+msgid "File truncated"
+msgstr "Fichier tronqué"
+
+#: bfd.c:416
+msgid "File too big"
+msgstr "Fichier trop gros"
+
+#: bfd.c:417
+#, c-format
+msgid "Error reading %s: %s"
+msgstr "Erreur lors de la lecture de %s: %s"
+
+#: bfd.c:418
+msgid "#<Invalid error code>"
+msgstr "#<Code d'erreur invalide>"
+
+#: bfd.c:945
+#, c-format
+msgid "BFD %s assertion fail %s:%d"
+msgstr "BFD assertion %s a échoué %s:%d"
+
+#: bfd.c:957
+#, c-format
+msgid "BFD %s internal error, aborting at %s line %d in %s\n"
+msgstr "BFD erreur interne %s, abandon à %s, ligne %d dans %s\n"
+
+#: bfd.c:961
+#, c-format
+msgid "BFD %s internal error, aborting at %s line %d\n"
+msgstr "BFD erreur interne %s, abandon à %s, ligne %d\n"
+
+#: bfd.c:963
+msgid "Please report this bug.\n"
+msgstr "Merci de rapporter cette anomalie.\n"
+
+#: bfdwin.c:206
+#, c-format
+msgid "not mapping: data=%lx mapped=%d\n"
+msgstr "pas de table de projection: données=%lx adresse de la table=%d\n"
+
+#: bfdwin.c:209
+#, c-format
+msgid "not mapping: env var not set\n"
+msgstr "pas de table de projection: variable d'environnement pas initialisée\n"
+
+#: binary.c:271
+#, c-format
+msgid "Warning: Writing section `%s' to huge (ie negative) file offset 0x%lx."
+msgstr "Attention: Écriture de la section «%s» vers un énorme décalage (ie négatif) dans le fichier 0x%lx."
+
+#: bout.c:1146 elf-m10300.c:2063 elf32-avr.c:1654 elf32-frv.c:5734
+#: elfxx-sparc.c:2802 reloc.c:6115 reloc16.c:162 elf32-ia64.c:360
+#: elf64-ia64.c:360
+msgid "%P%F: --relax and -r may not be used together\n"
+msgstr "%P%F: --relax et -r ne peuvent pas être utilisés en même temps\n"
+
+#: cache.c:227
+msgid "reopening %B: %s\n"
+msgstr "réouverture de %B: %s\n"
+
+#: coff-alpha.c:491
+msgid ""
+"%B: Cannot handle compressed Alpha binaries.\n"
+" Use compiler flags, or objZ, to generate uncompressed binaries."
+msgstr ""
+"%B: Les binaires compressés pour Alpha ne sont pas supportés.\n"
+" Utilisez les options du compilateur ou objZ pour produire des binaires non compressés."
+
+#: coff-alpha.c:648
+msgid "%B: unknown/unsupported relocation type %d"
+msgstr "%B: type de réadressage %d inconnu ou non supporté"
+
+#: coff-alpha.c:900 coff-alpha.c:937 coff-alpha.c:2025 coff-mips.c:1003
+msgid "GP relative relocation used when GP not defined"
+msgstr "Réadressage relatif GP utilisé alors que GP n'est pas défini"
+
+#: coff-alpha.c:1502
+msgid "using multiple gp values"
+msgstr "utilisation de valeurs gp multiples"
+
+#: coff-alpha.c:1561
+msgid "%B: unsupported relocation: ALPHA_R_GPRELHIGH"
+msgstr "%B: type de réadressage non supporté: ALPHA_R_GPRELHIGH"
+
+#: coff-alpha.c:1568
+msgid "%B: unsupported relocation: ALPHA_R_GPRELLOW"
+msgstr "%B: type de réadressage non supporté: ALPHA_R_GPRELLOW"
+
+#: coff-alpha.c:1575 elf32-m32r.c:2484 elf64-alpha.c:4074 elf64-alpha.c:4224
+#: elf32-ia64.c:3839 elf64-ia64.c:3839
+msgid "%B: unknown relocation type %d"
+msgstr "%B: type de réadressage %d inconnu"
+
+#: coff-arm.c:1038
+#, c-format
+msgid "%B: unable to find THUMB glue '%s' for `%s'"
+msgstr "%B: incapable de repérer le REPÈRE de liant «%s» pour «%s»"
+
+#: coff-arm.c:1067
+#, c-format
+msgid "%B: unable to find ARM glue '%s' for `%s'"
+msgstr "%B: incapable de repérer le liant ARM «%s» pour «%s»"
+
+#: coff-arm.c:1369 elf32-arm.c:7023
+#, c-format
+msgid ""
+"%B(%s): warning: interworking not enabled.\n"
+" first occurrence: %B: arm call to thumb"
+msgstr ""
+"%B(%s): attention: l'inter-réseautage n'est pas activé.\n"
+" première occurrence: %B: appel arm au repère"
+
+#: coff-arm.c:1459
+#, c-format
+msgid ""
+"%B(%s): warning: interworking not enabled.\n"
+" first occurrence: %B: thumb call to arm\n"
+" consider relinking with --support-old-code enabled"
+msgstr ""
+"%B(%s): attention: l'inter-réseautage n'est pas activé.\n"
+" première occurrence: %B: appel arm au repère\n"
+" reliez avec --support-old-code activé"
+
+#: coff-arm.c:1754 coff-tic80.c:695 cofflink.c:3081
+msgid "%B: bad reloc address 0x%lx in section `%A'"
+msgstr "%B: mauvaise adresse de relocalisation 0x%lx dans la section «%A»"
+
+#: coff-arm.c:2079
+msgid "%B: illegal symbol index in reloc: %d"
+msgstr "%B: symbole index illégal dans la relocalisation: %d"
+
+#: coff-arm.c:2210
+#, c-format
+msgid "error: %B is compiled for APCS-%d, whereas %B is compiled for APCS-%d"
+msgstr "erreur: %B compilé pour APCS-%d alors que %B a été compilé pour APCS-%d"
+
+#: coff-arm.c:2226 elf32-arm.c:15621
+#, c-format
+msgid "error: %B passes floats in float registers, whereas %B passes them in integer registers"
+msgstr "erreur: %B passage de valeurs en virgule flottante dans les registres FP alors que %B les passe dans les registres entiers"
+
+#: coff-arm.c:2229 elf32-arm.c:15625
+#, c-format
+msgid "error: %B passes floats in integer registers, whereas %B passes them in float registers"
+msgstr "erreur: %B passage de valeurs en virgule flottante dans les registres entiers alors que %B les passe dans les registres FP"
+
+#: coff-arm.c:2243
+#, c-format
+msgid "error: %B is compiled as position independent code, whereas target %B is absolute position"
+msgstr "erreur: %B compilé avec du code à position indépendante alors que la cible %B est à position absolue"
+
+#: coff-arm.c:2246
+#, c-format
+msgid "error: %B is compiled as absolute position code, whereas target %B is position independent"
+msgstr "erreur: %B compilé avec du code à position absolu alors que la cible %B est à position indépendante"
+
+#: coff-arm.c:2274 elf32-arm.c:15690
+#, c-format
+msgid "Warning: %B supports interworking, whereas %B does not"
+msgstr "Attention: %B supporte l'inter-réseautage, contrairement à %B"
+
+#: coff-arm.c:2277 elf32-arm.c:15696
+#, c-format
+msgid "Warning: %B does not support interworking, whereas %B does"
+msgstr "Attention: %B ne supporte pas l'inter-réseautage, contrairement à %B"
+
+#: coff-arm.c:2301
+#, c-format
+msgid "private flags = %x:"
+msgstr "fanions privés = %x:"
+
+#: coff-arm.c:2309 elf32-arm.c:11806
+#, c-format
+msgid " [floats passed in float registers]"
+msgstr " [valeurs en virgule flottante passées dans des registres de valeurs en virgule flottante]"
+
+#: coff-arm.c:2311
+#, c-format
+msgid " [floats passed in integer registers]"
+msgstr " [valeurs en virgule flottante passées dans des registres de valeurs entières]"
+
+#: coff-arm.c:2314 elf32-arm.c:11809
+#, c-format
+msgid " [position independent]"
+msgstr " [position indépendante]"
+
+#: coff-arm.c:2316
+#, c-format
+msgid " [absolute position]"
+msgstr " [position absolue]"
+
+#: coff-arm.c:2320
+#, c-format
+msgid " [interworking flag not initialised]"
+msgstr " [fanion d'inter-réseautage n'a pas été initialisé]"
+
+#: coff-arm.c:2322
+#, c-format
+msgid " [interworking supported]"
+msgstr " [inter-réseautage supporté]"
+
+#: coff-arm.c:2324
+#, c-format
+msgid " [interworking not supported]"
+msgstr " [inter-réseautage non supporté]"
+
+#: coff-arm.c:2370 elf32-arm.c:10841
+#, c-format
+msgid "Warning: Not setting interworking flag of %B since it has already been specified as non-interworking"
+msgstr "Attention: Pas d'initialisation du fanion d'inter-réseautage de %B puisqu'il a déjà été spécifié sans inter-réseautage"
+
+#: coff-arm.c:2374 elf32-arm.c:10845
+#, c-format
+msgid "Warning: Clearing the interworking flag of %B due to outside request"
+msgstr "Attention: Mise à zéro du fanion d'inter-réseautage de %B en raison d'une requête externe"
+
+#: coff-h8300.c:1122
+#, c-format
+msgid "cannot handle R_MEM_INDIRECT reloc when using %s output"
+msgstr "ne peut traiter la relocalisation R_MEM_INDIRECT lorsque %s est utilisé en sortie"
+
+#: coff-i860.c:147
+#, c-format
+msgid "relocation `%s' not yet implemented"
+msgstr "réadressage « %s » pas encore implémenté"
+
+#: coff-i860.c:605 coff-tic54x.c:398 coffcode.h:5198
+msgid "%B: warning: illegal symbol index %ld in relocs"
+msgstr "%B: attention: symbole index illégal %ld dans les relocalisations"
+
+#: coff-i960.c:144 coff-i960.c:507
+msgid "uncertain calling convention for non-COFF symbol"
+msgstr "convention d'appel incertaine pour un symbole non COFF"
+
+#: coff-m68k.c:506 elf32-bfin.c:5690 elf32-cr16.c:2897 elf32-m68k.c:4677
+msgid "unsupported reloc type"
+msgstr "type de relocalisation non supporté"
+
+#: coff-mips.c:688 elf32-mips.c:1516 elf32-score.c:431 elf32-score7.c:330
+#: elf64-mips.c:2618 elfn32-mips.c:2431
+msgid "GP relative relocation when _gp not defined"
+msgstr "réadressage relatif GP sans que _gp ne soit défini"
+
+#: coff-or32.c:229
+msgid "Unrecognized reloc"
+msgstr "Relocalisation non reconnue"
+
+#: coff-rs6000.c:2720
+#, c-format
+msgid "%s: unsupported relocation type 0x%02x"
+msgstr "%s: type de réadressage non supporté 0x%02x"
+
+#: coff-rs6000.c:2805
+#, c-format
+msgid "%s: TOC reloc at 0x%x to symbol `%s' with no TOC entry"
+msgstr "%s: table des matières des relocalisations à 0x%x pour le symbole «%s» sans aucune entrée"
+
+#: coff-rs6000.c:3556 coff64-rs6000.c:2111
+msgid "%B: symbol `%s' has unrecognized smclas %d"
+msgstr "%B: symbole «%s» a une classe smclas %d non reconnue"
+
+#: coff-sh.c:521
+#, c-format
+msgid "SH Error: unknown reloc type %d"
+msgstr "Erreur SH: type de réadressage %d inconnu"
+
+#: coff-tic4x.c:195 coff-tic54x.c:299 coff-tic80.c:458
+#, c-format
+msgid "Unrecognized reloc type 0x%x"
+msgstr "Type de relocalisation non reconnu 0x%x"
+
+#: coff-tic4x.c:240
+#, c-format
+msgid "%s: warning: illegal symbol index %ld in relocs"
+msgstr "%s: attention: symbole index illégal %ld dans les relocalisations"
+
+#: coff-w65.c:367
+#, c-format
+msgid "ignoring reloc %s\n"
+msgstr "relocalisation %s ignorée\n"
+
+#: coffcode.h:997
+msgid "%B: warning: COMDAT symbol '%s' does not match section name '%s'"
+msgstr "%B: attention: symbole COMDAT «%s» ne concorde par avec le nom de section «%s»"
+
+#. Generate a warning message rather using the 'unhandled'
+#. variable as this will allow some .sys files generate by
+#. other toolchains to be processed. See bugzilla issue 196.
+#: coffcode.h:1221
+msgid "%B: Warning: Ignoring section flag IMAGE_SCN_MEM_NOT_PAGED in section %s"
+msgstr "%B: Attention: Ignore le fanion de section IMAGE_SCN_MEM_NOT_PAGED dans la section %s"
+
+#: coffcode.h:1288
+msgid "%B (%s): Section flag %s (0x%x) ignored"
+msgstr "%B (%s): Fanion de section %s (0x%x) ignoré"
+
+#: coffcode.h:2430
+#, c-format
+msgid "Unrecognized TI COFF target id '0x%x'"
+msgstr "Identificateur de cible TI COFF non reconnu «0x%x»"
+
+#: coffcode.h:2744
+msgid "%B: reloc against a non-existant symbol index: %ld"
+msgstr "%B: relocalisation par rapport à un indexe de symbole inexistant: %ld"
+
+#: coffcode.h:3302
+msgid "%B: too many sections (%d)"
+msgstr "%B: trop de sections (%d)"
+
+#: coffcode.h:3718
+msgid "%B: section %s: string table overflow at offset %ld"
+msgstr "%B: section %s: débordement de la table de chaînes à l'offset %ld"
+
+#: coffcode.h:4523
+msgid "%B: warning: line number table read failed"
+msgstr "%B: attention: erreur lors de la lecture de la table des numéros de ligne"
+
+#: coffcode.h:4553
+msgid "%B: warning: illegal symbol index %ld in line numbers"
+msgstr "%B: attention: symbole d'index illégal %ld dans les numéros de ligne"
+
+#: coffcode.h:4567
+msgid "%B: warning: duplicate line number information for `%s'"
+msgstr "%B: attention: information de numéro de ligne dédoublée pour «%s»"
+
+#: coffcode.h:4967
+msgid "%B: Unrecognized storage class %d for %s symbol `%s'"
+msgstr "%B: Classe de stockage %d non reconnue pour %s symbole «%s»"
+
+#: coffcode.h:5093
+msgid "warning: %B: local symbol `%s' has no section"
+msgstr "attention: %B: symbole local «%s» n'a pas de section"
+
+#: coffcode.h:5237
+msgid "%B: illegal relocation type %d at address 0x%lx"
+msgstr "%B: type de réadressage %d illégal à l'adresse 0x%lx"
+
+#: coffgen.c:1595
+msgid "%B: bad string table size %lu"
+msgstr "%B: mauvaise taille de la table des chaînes %lu"
+
+#: coffgen.c:2500 elflink.c:12689 linker.c:3122
+msgid "%F%P: already_linked_table: %E\n"
+msgstr "%F%P: already_linked_table: %E\n"
+
+#: cofflink.c:533 elflink.c:4323
+msgid "Warning: type of symbol `%s' changed from %d to %d in %B"
+msgstr "Attention: type de symbole «%s» a changé de %d à %d dans %B"
+
+#: cofflink.c:2329
+msgid "%B: relocs in section `%A', but it has no contents"
+msgstr "%B: relocalisations dans la section «%A» qui est vide"
+
+#: cofflink.c:2391 elflink.c:9545
+msgid "%X`%s' referenced in section `%A' of %B: defined in discarded section `%A' of %B\n"
+msgstr "%X«%s» référencé dans la section «%A» de %B: défini dans la section abandonnée «%A» de %B\n"
+
+#: cofflink.c:2690 coffswap.h:826
+#, c-format
+msgid "%s: %s: reloc overflow: 0x%lx > 0xffff"
+msgstr "%s: %s: débordement de relocalisation: 0x%lx > 0xffff"
+
+#: cofflink.c:2699 coffswap.h:812
+#, c-format
+msgid "%s: warning: %s: line number overflow: 0x%lx > 0xffff"
+msgstr "%s: attention: %s: débordement du compteur de numéro de ligne: 0x%lx > 0xffff"
+
+#: cpu-arm.c:189 cpu-arm.c:200
+msgid "error: %B is compiled for the EP9312, whereas %B is compiled for XScale"
+msgstr "erreur: %B compilé pour EP9312 alors que %B a été compilé pour XScale"
+
+#: cpu-arm.c:333
+#, c-format
+msgid "warning: unable to update contents of %s section in %s"
+msgstr "attention: incapable de mettre à jour le contenu de la section %s dans %s"
+
+#: dwarf2.c:496
+#, c-format
+msgid "Dwarf Error: Can't find %s section."
+msgstr "Erreur DWARF: ne peut repérer la section %s"
+
+#: dwarf2.c:525
+#, c-format
+msgid "Dwarf Error: Offset (%lu) greater than or equal to %s size (%lu)."
+msgstr "Erreur DWARF: décalage de ligne (%lu) est >= à la taille de %s (%lu)"
+
+#: dwarf2.c:949
+#, c-format
+msgid "Dwarf Error: Invalid or unhandled FORM value: %u."
+msgstr "Erreur DWARF: valeur de FORME invalide ou non supportée: %u"
+
+#: dwarf2.c:1200
+msgid "Dwarf Error: mangled line number section (bad file number)."
+msgstr "Erreur DWARF: numéro de ligne de section mutilé (mauvais no. de fichier)"
+
+#: dwarf2.c:1453
+#, c-format
+msgid "Dwarf Error: Unhandled .debug_line version %d."
+msgstr "Erreur DWARF: Version .debug_line %d non prise en charge."
+
+#: dwarf2.c:1475
+msgid "Dwarf Error: Invalid maximum operations per instruction."
+msgstr "Erreur DWARF: Opérations maximum par instruction invalide."
+
+#: dwarf2.c:1662
+msgid "Dwarf Error: mangled line number section."
+msgstr "Erreur DWARF: numéro de ligne de section mutilé"
+
+#: dwarf2.c:1989 dwarf2.c:2109 dwarf2.c:2394
+#, c-format
+msgid "Dwarf Error: Could not find abbrev number %u."
+msgstr "Erreur DWARF: ne peut repérer le numéro abrégé %u"
+
+#: dwarf2.c:2355
+#, c-format
+msgid "Dwarf Error: found dwarf version '%u', this reader only handles version 2, 3 and 4 information."
+msgstr "Erreur DWARF: version DWARF trouvée «%u», ce lecteur ne supporte que les informations des versions 2, 3 et 4."
+
+#: dwarf2.c:2362
+#, c-format
+msgid "Dwarf Error: found address size '%u', this reader can not handle sizes greater than '%u'."
+msgstr "Erreur DWARF: taille d'adresse obtenue «%u», ce lecteur ne peut traiter des tailles plus grandes que «%u»."
+
+#: dwarf2.c:2385
+#, c-format
+msgid "Dwarf Error: Bad abbrev number: %u."
+msgstr "Erreur DWARF: mauvais numéro abrégé: %u"
+
+#: ecoff.c:1239
+#, c-format
+msgid "Unknown basic type %d"
+msgstr "Type de base %d inconnu"
+
+#: ecoff.c:1496
+#, c-format
+msgid ""
+"\n"
+" End+1 symbol: %ld"
+msgstr ""
+"\n"
+" Dernier+1 symbole: %ld"
+
+#: ecoff.c:1503 ecoff.c:1506
+#, c-format
+msgid ""
+"\n"
+" First symbol: %ld"
+msgstr ""
+"\n"
+" Premier symbole: %ld"
+
+#: ecoff.c:1518
+#, c-format
+msgid ""
+"\n"
+" End+1 symbol: %-7ld Type: %s"
+msgstr ""
+"\n"
+" Dernier+1 symbole: %-7ld Type: %s"
+
+#: ecoff.c:1525
+#, c-format
+msgid ""
+"\n"
+" Local symbol: %ld"
+msgstr ""
+"\n"
+" Symbole local: %ld"
+
+#: ecoff.c:1533
+#, c-format
+msgid ""
+"\n"
+" struct; End+1 symbol: %ld"
+msgstr ""
+"\n"
+" struct; Symbole Fin+1: %ld"
+
+#: ecoff.c:1538
+#, c-format
+msgid ""
+"\n"
+" union; End+1 symbol: %ld"
+msgstr ""
+"\n"
+" union; Dernier+1 symbole: %ld"
+
+#: ecoff.c:1543
+#, c-format
+msgid ""
+"\n"
+" enum; End+1 symbol: %ld"
+msgstr ""
+"\n"
+" enum; Dernier+1 symbol: %ld"
+
+#: ecoff.c:1549
+#, c-format
+msgid ""
+"\n"
+" Type: %s"
+msgstr ""
+"\n"
+" Type: %s"
+
+#: elf-attrs.c:569
+msgid "error: %B: Object has vendor-specific contents that must be processed by the '%s' toolchain"
+msgstr "erreur: %B: L'objet a un contenu spécific à un vendeur qui doit être traité par la chaîne d'outils «%s»"
+
+#: elf-attrs.c:578
+msgid "error: %B: Object tag '%d, %s' is incompatible with tag '%d, %s'"
+msgstr "erreur: %B: Étiquette d'objet «%d, %s» incompatible avec l'étiquette «%d, %s»"
+
+#: elf-eh-frame.c:917
+msgid "%P: error in %B(%A); no .eh_frame_hdr table will be created.\n"
+msgstr "%P: erreur dans %B(%A); aucune table .eh_frame_hdr ne sera créée.\n"
+
+#: elf-eh-frame.c:1189
+msgid "%P: fde encoding in %B(%A) prevents .eh_frame_hdr table being created.\n"
+msgstr "%P: encodage fde dans %B(%A) empêche la création de la table .eh_frame_hdr.\n"
+
+#: elf-eh-frame.c:1605
+msgid "%P: DW_EH_PE_datarel unspecified for this architecture.\n"
+msgstr "%P: DW_EH_PE_datarel non spécifié pour cette architecture.\n"
+
+#: elf-ifunc.c:179
+msgid "%F%P: dynamic STT_GNU_IFUNC symbol `%s' with pointer equality in `%B' can not be used when making an executable; recompile with -fPIE and relink with -pie\n"
+msgstr "%P%P: symbole dynamique STT_GNU_IFUNC «%s» avec une égalité de pointeur dans «%B» ne peut pas être utilisé lors de la création d'un exécutable. Recompilez avec -fPIE et reliez avec -pie\n"
+
+#: elf-m10200.c:450 elf-m10300.c:1563 elf32-avr.c:1221 elf32-bfin.c:3213
+#: elf32-cr16.c:1482 elf32-cr16c.c:780 elf32-cris.c:2081 elf32-crx.c:922
+#: elf32-d10v.c:509 elf32-epiphany.c:556 elf32-fr30.c:609 elf32-frv.c:4105
+#: elf32-h8300.c:509 elf32-i860.c:1211 elf32-ip2k.c:1468 elf32-iq2000.c:684
+#: elf32-lm32.c:1168 elf32-m32c.c:553 elf32-m32r.c:3106 elf32-m68hc1x.c:1138
+#: elf32-mep.c:535 elf32-microblaze.c:1231 elf32-moxie.c:282
+#: elf32-msp430.c:486 elf32-mt.c:395 elf32-openrisc.c:404 elf32-score.c:2729
+#: elf32-score7.c:2537 elf32-spu.c:5044 elf32-tilepro.c:3214 elf32-v850.c:2143
+#: elf32-xstormy16.c:935 elf64-mmix.c:1590 elfxx-tilegx.c:3577
+msgid "internal error: out of range error"
+msgstr "erreur interne: hors limite"
+
+#: elf-m10200.c:454 elf-m10300.c:1567 elf32-avr.c:1225 elf32-bfin.c:3217
+#: elf32-cr16.c:1486 elf32-cr16c.c:784 elf32-cris.c:2085 elf32-crx.c:926
+#: elf32-d10v.c:513 elf32-fr30.c:613 elf32-frv.c:4109 elf32-h8300.c:513
+#: elf32-i860.c:1215 elf32-iq2000.c:688 elf32-lm32.c:1172 elf32-m32c.c:557
+#: elf32-m32r.c:3110 elf32-m68hc1x.c:1142 elf32-mep.c:539
+#: elf32-microblaze.c:1235 elf32-moxie.c:286 elf32-msp430.c:490
+#: elf32-openrisc.c:408 elf32-score.c:2733 elf32-score7.c:2541
+#: elf32-spu.c:5048 elf32-tilepro.c:3218 elf32-v850.c:2147
+#: elf32-xstormy16.c:939 elf64-mmix.c:1594 elfxx-mips.c:9465
+#: elfxx-tilegx.c:3581
+msgid "internal error: unsupported relocation error"
+msgstr "erreur interne: erreur de réadressage non supportée"
+
+#: elf-m10200.c:458 elf32-cr16.c:1490 elf32-cr16c.c:788 elf32-crx.c:930
+#: elf32-d10v.c:517 elf32-h8300.c:517 elf32-lm32.c:1176 elf32-m32r.c:3114
+#: elf32-m68hc1x.c:1146 elf32-microblaze.c:1239 elf32-score.c:2737
+#: elf32-score7.c:2545 elf32-spu.c:5052
+msgid "internal error: dangerous error"
+msgstr "erreur interne: erreur dangereuse"
+
+#: elf-m10200.c:462 elf-m10300.c:1580 elf32-avr.c:1233 elf32-bfin.c:3225
+#: elf32-cr16.c:1494 elf32-cr16c.c:792 elf32-cris.c:2093 elf32-crx.c:934
+#: elf32-d10v.c:521 elf32-epiphany.c:571 elf32-fr30.c:621 elf32-frv.c:4117
+#: elf32-h8300.c:521 elf32-i860.c:1223 elf32-ip2k.c:1483 elf32-iq2000.c:696
+#: elf32-lm32.c:1180 elf32-m32c.c:565 elf32-m32r.c:3118 elf32-m68hc1x.c:1150
+#: elf32-mep.c:547 elf32-microblaze.c:1243 elf32-moxie.c:294
+#: elf32-msp430.c:498 elf32-mt.c:403 elf32-openrisc.c:416 elf32-score.c:2746
+#: elf32-score7.c:2549 elf32-spu.c:5056 elf32-tilepro.c:3226 elf32-v850.c:2167
+#: elf32-xstormy16.c:947 elf64-mmix.c:1602 elfxx-tilegx.c:3589
+msgid "internal error: unknown error"
+msgstr "erreur interne: erreur inconnue"
+
+#: elf-m10300.c:1507 elf32-arm.c:10419 elf32-i386.c:4264 elf32-m32r.c:2599
+#: elf32-m68k.c:4156 elf32-s390.c:3003 elf32-sh.c:4218 elf32-tilepro.c:3117
+#: elf32-xtensa.c:3066 elf64-s390.c:2978 elf64-sh64.c:1640 elf64-x86-64.c:4110
+#: elfxx-sparc.c:3835 elfxx-tilegx.c:3500
+msgid "%B(%A+0x%lx): unresolvable %s relocation against symbol `%s'"
+msgstr "%B(%A+0x%lx): réadressage %s sans solution vers le symbole « %s »"
+
+#: elf-m10300.c:1572
+msgid "error: inappropriate relocation type for shared library (did you forget -fpic?)"
+msgstr "erreur: type de réadressage inapproprié pour une librairie partagée (avez-vous oublié -fpic ?)"
+
+#: elf-m10300.c:1575
+msgid "internal error: suspicious relocation type used in shared library"
+msgstr "erreur interne: type de réadressage douteux utilisé dans une librairie partagée"
+
+#: elf-m10300.c:4372 elf32-arm.c:12800 elf32-cr16.c:2451 elf32-cris.c:3057
+#: elf32-hppa.c:1894 elf32-i370.c:503 elf32-i386.c:2182 elf32-lm32.c:1868
+#: elf32-m32r.c:1927 elf32-m68k.c:3253 elf32-s390.c:1652 elf32-sh.c:2931
+#: elf32-tic6x.c:2162 elf32-tilepro.c:1940 elf32-vax.c:1041 elf64-s390.c:1635
+#: elf64-sh64.c:3381 elf64-x86-64.c:2176 elfxx-sparc.c:2119
+#: elfxx-tilegx.c:2261
+#, c-format
+msgid "dynamic variable `%s' is zero size"
+msgstr "la variable dynamique «%s» a une taille nulle"
+
+#: elf.c:334
+msgid "%B: invalid string offset %u >= %lu for section `%s'"
+msgstr "%B: chaîne de décalage invalide %u >= %lu pour la section «%s»"
+
+#: elf.c:446
+msgid "%B symbol number %lu references nonexistent SHT_SYMTAB_SHNDX section"
+msgstr "%B le symbole numéro %lu fait référence à une section SHT_SYMTAB_SHNDX inexistante"
+
+#: elf.c:602
+msgid "%B: Corrupt size field in group section header: 0x%lx"
+msgstr "%B: Champ de taille corrompu dans l'en-tête du groupe de section: 0x%lx"
+
+#: elf.c:638
+msgid "%B: invalid SHT_GROUP entry"
+msgstr "%B: entrée SHT_GROUP invalide"
+
+#: elf.c:708
+msgid "%B: no group info for section %A"
+msgstr "%B: aucune info de groupe pour la section %A"
+
+#: elf.c:737 elf.c:3121 elflink.c:10135
+msgid "%B: warning: sh_link not set for section `%A'"
+msgstr "%B: attention: sh_link n'a pas de valeur pour la section «%A»"
+
+#: elf.c:756
+msgid "%B: sh_link [%d] in section `%A' is incorrect"
+msgstr "%B: sh_link [%d] n'est pas correct dans la section «%A»"
+
+#: elf.c:791
+msgid "%B: unknown [%d] section `%s' in group [%s]"
+msgstr "%B: [%d] inconnu dans la section «%s» du groupe [%s]"
+
+#: elf.c:1041
+msgid "%B: unable to initialize commpress status for section %s"
+msgstr "%B: impossible d'initialiser le statut de compression de la section %s"
+
+#: elf.c:1061
+msgid "%B: unable to initialize decommpress status for section %s"
+msgstr "%B: impossible d'initialiser le statut de décompression de la section %s"
+
+#: elf.c:1181
+#, c-format
+msgid ""
+"\n"
+"Program Header:\n"
+msgstr ""
+"\n"
+"En-tête de programme:\n"
+
+#: elf.c:1223
+#, c-format
+msgid ""
+"\n"
+"Dynamic Section:\n"
+msgstr ""
+"\n"
+"Section dynamique:\n"
+
+#: elf.c:1359
+#, c-format
+msgid ""
+"\n"
+"Version definitions:\n"
+msgstr ""
+"\n"
+"Définitions des versions:\n"
+
+#: elf.c:1384
+#, c-format
+msgid ""
+"\n"
+"Version References:\n"
+msgstr ""
+"\n"
+"Références de version:\n"
+
+#: elf.c:1389
+#, c-format
+msgid " required from %s:\n"
+msgstr " requis par %s:\n"
+
+#: elf.c:1796
+msgid "%B: invalid link %lu for reloc section %s (index %u)"
+msgstr "%B: lien invalide %lu pour la section de relocalisation %s (index %u)"
+
+#: elf.c:1966
+msgid "%B: don't know how to handle allocated, application specific section `%s' [0x%8x]"
+msgstr "%B: je ne sais pas comment traiter la section «%s» [0x%8x] allouée et spécifique à l'application"
+
+#: elf.c:1978
+msgid "%B: don't know how to handle processor specific section `%s' [0x%8x]"
+msgstr "%B: je ne sais pas comment traiter la section «%s» [0x%8x] spécifique au processeur"
+
+#: elf.c:1989
+msgid "%B: don't know how to handle OS specific section `%s' [0x%8x]"
+msgstr "%B: je ne sais pas comment traiter la section «%s» [0x%8x] spécifique au système d'exploitation"
+
+#: elf.c:1999
+msgid "%B: don't know how to handle section `%s' [0x%8x]"
+msgstr "%B: je ne sais pas comment traiter la section «%s» [0x%8x]"
+
+#: elf.c:2634
+#, c-format
+msgid "warning: section `%A' type changed to PROGBITS"
+msgstr "attention: type de la section «%A» changé en PROGBITS"
+
+#: elf.c:3078
+msgid "%B: sh_link of section `%A' points to discarded section `%A' of `%B'"
+msgstr "%B: le sh_link de la section «%A» pointe vers la section abandonnée «%A» de «%B»"
+
+#: elf.c:3101
+msgid "%B: sh_link of section `%A' points to removed section `%A' of `%B'"
+msgstr "%B: le sh_link de la section «%A» pointe vers la section supprimée «%A» de «%B»"
+
+#: elf.c:4527
+msgid "%B: The first section in the PT_DYNAMIC segment is not the .dynamic section"
+msgstr "%B: La première section dans le segment PT_DYNAMIC n'est pas la section .dynamic"
+
+#: elf.c:4554
+msgid "%B: Not enough room for program headers, try linking with -N"
+msgstr "%B: Pas suffisamment d'espace pour les en-têtes du programme, essayer l'option -N"
+
+#: elf.c:4641
+msgid "%B: section %A lma %#lx adjusted to %#lx"
+msgstr "%B: section %A avec lma %#lx ajustée à %#lx"
+
+#: elf.c:4776
+msgid "%B: section `%A' can't be allocated in segment %d"
+msgstr "%B: la section «%A» ne peut pas être allouée dans le segment %d"
+
+#: elf.c:4824
+msgid "%B: warning: allocated section `%s' not in segment"
+msgstr "%B: attention: section allouée «%s» n'est pas dans le segment"
+
+#: elf.c:5324
+msgid "%B: symbol `%s' required but not present"
+msgstr "%B: symbole «%s» requis mais absent"
+
+#: elf.c:5662
+msgid "%B: warning: Empty loadable segment detected, is this intentional ?\n"
+msgstr "%B: attention: segment chargeable vide détecté, est-ce intentionnel ?\n"
+
+#: elf.c:6692
+#, c-format
+msgid "Unable to find equivalent output section for symbol '%s' from section '%s'"
+msgstr "Incapable de trouver un équivalent pour le symbole «%s» de la section «%s»"
+
+#: elf.c:7692
+msgid "%B: unsupported relocation type %s"
+msgstr "%B: type de réadressage %s non supporté"
+
+#: elf32-arm.c:3617
+msgid ""
+"%B(%s): warning: interworking not enabled.\n"
+" first occurrence: %B: Thumb call to ARM"
+msgstr ""
+"%B(%s): attention: l'inter-réseautage n'est pas activé.\n"
+" première occurrence: %B: appel de repère vers ARM"
+
+#: elf32-arm.c:3664
+msgid ""
+"%B(%s): warning: interworking not enabled.\n"
+" first occurrence: %B: ARM call to Thumb"
+msgstr ""
+"%B(%s): attention: l'inter-réseautage n'est pas activé.\n"
+" première occurrence: %B: appel ARM vers repère"
+
+#: elf32-arm.c:3878 elf32-arm.c:5315
+#, c-format
+msgid "%s: cannot create stub entry %s"
+msgstr "%s: ne peut créer l'entrée d'ébauche %s"
+
+#: elf32-arm.c:5431
+#, c-format
+msgid "unable to find THUMB glue '%s' for '%s'"
+msgstr "incapable de repérer le REPÈRE de liant «%s» pour «%s»"
+
+#: elf32-arm.c:5467
+#, c-format
+msgid "unable to find ARM glue '%s' for '%s'"
+msgstr "incapable de repérer le liant ARM «%s» pour «%s»"
+
+#: elf32-arm.c:6005
+msgid "%B: BE8 images only valid in big-endian mode."
+msgstr "%B: les images BE8 ne sont valables qu'en mode gros boutiste."
+
+#. Give a warning, but do as the user requests anyway.
+#: elf32-arm.c:6235
+msgid "%B: warning: selected VFP11 erratum workaround is not necessary for target architecture"
+msgstr "%B: attention: le palliatif VFP11 n'est pas nécessaire avec l'architecture cible"
+
+#: elf32-arm.c:6779 elf32-arm.c:6799
+msgid "%B: unable to find VFP11 veneer `%s'"
+msgstr "%B: incapable de trouver le vernis VFP11 «%s»"
+
+#: elf32-arm.c:6848
+#, c-format
+msgid "Invalid TARGET2 relocation type '%s'."
+msgstr "Type de réadressage TARGET2 « %s » invalide"
+
+#: elf32-arm.c:6933
+msgid ""
+"%B(%s): warning: interworking not enabled.\n"
+" first occurrence: %B: thumb call to arm"
+msgstr ""
+"%B(%s): attention: l'inter-réseautage n'est pas activé.\n"
+" première occurrence: %B: appel de repère vers arm"
+
+#: elf32-arm.c:7717
+msgid "%B(%A+0x%lx):unexpected Thumb instruction '0x%x' in TLS trampoline"
+msgstr "%B(%A+0x%lx): instruction Thumb « 0x%x » inattendue dans le trampoline TLS"
+
+#: elf32-arm.c:7756
+msgid "%B(%A+0x%lx):unexpected ARM instruction '0x%x' in TLS trampoline"
+msgstr "%B(%A+0x%lx): instruction ARM « 0x%x » inattendue dans le trampoline TLS"
+
+#: elf32-arm.c:8209
+msgid "\\%B: Warning: Arm BLX instruction targets Arm function '%s'."
+msgstr "\\%B: Attention: instruction Arm BLX vise la fonction Arm «%s»."
+
+#: elf32-arm.c:8622
+msgid "%B: Warning: Thumb BLX instruction targets thumb function '%s'."
+msgstr "%B: Attention: instruction de repérage BLX vise la fonction de repérage «%s»."
+
+#: elf32-arm.c:9460
+msgid "%B(%A+0x%lx):unexpected Thumb instruction '0x%x' referenced by TLS_GOTDESC"
+msgstr "%B(%A+0x%lx): instruction Thumb « 0x%x » inattendue référencée par TLS_GOTDESC"
+
+#: elf32-arm.c:9483
+msgid "%B(%A+0x%lx):unexpected ARM instruction '0x%x' referenced by TLS_GOTDESC"
+msgstr "%B(%A+0x%lx): instruction ARM '0x%x' inattendue référencée par TLS_GOTDESC"
+
+#: elf32-arm.c:9512
+msgid "%B(%A+0x%lx): R_ARM_TLS_LE32 relocation not permitted in shared object"
+msgstr "%B(%A+0x%lx): réadressage R_ARM_TLS_LE32 pas permis dans un objet partagé"
+
+#: elf32-arm.c:9727
+msgid "%B(%A+0x%lx): Only ADD or SUB instructions are allowed for ALU group relocations"
+msgstr "%B(%A+0x%lx): Seuls ADD ou SUB sont permis dans les réadressages du groupe ALU"
+
+#: elf32-arm.c:9767 elf32-arm.c:9854 elf32-arm.c:9937 elf32-arm.c:10022
+msgid "%B(%A+0x%lx): Overflow whilst splitting 0x%lx for group relocation %s"
+msgstr "%B(%A+0x%lx): Débordement en scindant 0x%lx pour le réadressage du groupe %s"
+
+#: elf32-arm.c:10261 elf32-sh.c:4103 elf64-sh64.c:1544
+msgid "%B(%A+0x%lx): %s relocation against SEC_MERGE section"
+msgstr "%B(%A+0x%lx): %s réadressage vers une section SEC_MERGE"
+
+#: elf32-arm.c:10372 elf32-m68k.c:4191 elf32-xtensa.c:2802
+msgid "%B(%A+0x%lx): %s used with TLS symbol %s"
+msgstr "%B(%A+0x%lx): %s utilisé avec le symbole TLS %s"
+
+#: elf32-arm.c:10373 elf32-m68k.c:4192 elf32-xtensa.c:2803
+msgid "%B(%A+0x%lx): %s used with non-TLS symbol %s"
+msgstr "%B(%A+0x%lx): %s utilisé avec le symbole non-TLS %s"
+
+#: elf32-arm.c:10453 elf32-tic6x.c:2753
+msgid "out of range"
+msgstr "hors limite"
+
+#: elf32-arm.c:10457 elf32-tic6x.c:2757
+msgid "unsupported relocation"
+msgstr "réadressage non supporté"
+
+#: elf32-arm.c:10465 elf32-tic6x.c:2765
+msgid "unknown error"
+msgstr "erreur inconnue"
+
+#: elf32-arm.c:10890
+msgid "Warning: Clearing the interworking flag of %B because non-interworking code in %B has been linked with it"
+msgstr "Attention: mise à zéro du fanion d'inter-réseautage %B en raison du code sans inter-réseautage dans %B lié avec lui"
+
+#: elf32-arm.c:10984
+msgid "%B: Unknown mandatory EABI object attribute %d"
+msgstr "%B: L'attribut d'objet EABI obligatoire %d est manquant"
+
+#: elf32-arm.c:10992
+msgid "Warning: %B: Unknown EABI object attribute %d"
+msgstr "Attention: %B: Attribut d'objet EABI %d inconnu"
+
+#: elf32-arm.c:11173
+msgid "error: %B: Unknown CPU architecture"
+msgstr "erreur: %B: Architecture CPU inconnue"
+
+#: elf32-arm.c:11211
+msgid "error: %B: Conflicting CPU architectures %d/%d"
+msgstr "erreur: %B: Architectures CPU conflictuelles %d/%d"
+
+#: elf32-arm.c:11260
+msgid "Error: %B has both the current and legacy Tag_MPextension_use attributes"
+msgstr "Erreur: %B utilise les deux attributs Tag_MPextension_use actuel et hérité"
+
+#: elf32-arm.c:11285
+msgid "error: %B uses VFP register arguments, %B does not"
+msgstr "erreur: %B passe les paramètres dans un registre VFP alors que %B ne le fait pas"
+
+#: elf32-arm.c:11430
+msgid "error: %B: unable to merge virtualization attributes with %B"
+msgstr "erreur: %B: impossible de fusionner les attributs de visualisation avec %B"
+
+#: elf32-arm.c:11456
+msgid "error: %B: Conflicting architecture profiles %c/%c"
+msgstr "erreur: %B: Profils d'architecture conflictuels %c/%c"
+
+#: elf32-arm.c:11557
+msgid "Warning: %B: Conflicting platform configuration"
+msgstr "Attention: %B: Configuration de platforme conflictuelle"
+
+#: elf32-arm.c:11566
+msgid "error: %B: Conflicting use of R9"
+msgstr "erreur: %B: Utilisation conflictuelle de R9"
+
+#: elf32-arm.c:11578
+msgid "error: %B: SB relative addressing conflicts with use of R9"
+msgstr "erreur: %B: Adressage relatif SB entre en conflit avec l'utilisation de R9"
+
+#: elf32-arm.c:11591
+msgid "warning: %B uses %u-byte wchar_t yet the output is to use %u-byte wchar_t; use of wchar_t values across objects may fail"
+msgstr "attention: %B utilise des wchar_t de %u octets alors que la sortie doit utiliser des wchar_t de %u octets. L'utilisation de wchar_t entre objets peu échouer"
+
+#: elf32-arm.c:11622
+msgid "warning: %B uses %s enums yet the output is to use %s enums; use of enum values across objects may fail"
+msgstr "attantion: %B utilise des enums %s alors que la sortie doit utiliser des enums %s. L'utilisation des valeurs enum entre objets peu échouer"
+
+#: elf32-arm.c:11634
+msgid "error: %B uses iWMMXt register arguments, %B does not"
+msgstr "erreur: %B passe les paramètres dans le registre iWMMXt contrairement à %B"
+
+#: elf32-arm.c:11651
+msgid "error: fp16 format mismatch between %B and %B"
+msgstr "erreur: désaccord de format fp16 entre %B et %B"
+
+#: elf32-arm.c:11675
+msgid "DIV usage mismatch between %B and %B"
+msgstr "incohérence d'utilisation de DIV entre %B et %B"
+
+#: elf32-arm.c:11694
+msgid "%B has has both the current and legacy Tag_MPextension_use attributes"
+msgstr "%B utilise les deux attributs Tag_MPextension_use actuel et hérité"
+
+#. Ignore init flag - it may not be set, despite the flags field
+#. containing valid data.
+#. Ignore init flag - it may not be set, despite the flags field containing valid data.
+#: elf32-arm.c:11782 elf32-bfin.c:5079 elf32-cris.c:4169 elf32-m68hc1x.c:1282
+#: elf32-m68k.c:1236 elf32-score.c:3994 elf32-score7.c:3800 elf32-vax.c:529
+#: elfxx-mips.c:14103
+#, c-format
+msgid "private flags = %lx:"
+msgstr "fanions privés = %lx"
+
+#: elf32-arm.c:11791
+#, c-format
+msgid " [interworking enabled]"
+msgstr " [inter-réseautage autorisé]"
+
+#: elf32-arm.c:11799
+#, c-format
+msgid " [VFP float format]"
+msgstr " [format flottant VFP]"
+
+#: elf32-arm.c:11801
+#, c-format
+msgid " [Maverick float format]"
+msgstr " [format flottant Maverick]"
+
+#: elf32-arm.c:11803
+#, c-format
+msgid " [FPA float format]"
+msgstr " [format flottant FPA]"
+
+#: elf32-arm.c:11812
+#, c-format
+msgid " [new ABI]"
+msgstr " [nouvel ABI]"
+
+#: elf32-arm.c:11815
+#, c-format
+msgid " [old ABI]"
+msgstr " [ancien ABI]"
+
+#: elf32-arm.c:11818
+#, c-format
+msgid " [software FP]"
+msgstr " [virgule flottante logiciel]"
+
+#: elf32-arm.c:11827
+#, c-format
+msgid " [Version1 EABI]"
+msgstr " [Version1 EABI]"
+
+#: elf32-arm.c:11830 elf32-arm.c:11841
+#, c-format
+msgid " [sorted symbol table]"
+msgstr " [table des symboles triés]"
+
+#: elf32-arm.c:11832 elf32-arm.c:11843
+#, c-format
+msgid " [unsorted symbol table]"
+msgstr " [table des symboles non triés]"
+
+#: elf32-arm.c:11838
+#, c-format
+msgid " [Version2 EABI]"
+msgstr " [Version2 EABI]"
+
+#: elf32-arm.c:11846
+#, c-format
+msgid " [dynamic symbols use segment index]"
+msgstr " [symboles dynamiques utilisent un index de segment]"
+
+#: elf32-arm.c:11849
+#, c-format
+msgid " [mapping symbols precede others]"
+msgstr " [mapping de symboles précèdes les autres]"
+
+#: elf32-arm.c:11856
+#, c-format
+msgid " [Version3 EABI]"
+msgstr " [Version3 EABI]"
+
+#: elf32-arm.c:11860
+#, c-format
+msgid " [Version4 EABI]"
+msgstr " [Version4 EABI]"
+
+#: elf32-arm.c:11864
+#, c-format
+msgid " [Version5 EABI]"
+msgstr " [Version5 EABI]"
+
+#: elf32-arm.c:11867
+#, c-format
+msgid " [BE8]"
+msgstr " [BE8]"
+
+#: elf32-arm.c:11870
+#, c-format
+msgid " [LE8]"
+msgstr " [LE8]"
+
+#: elf32-arm.c:11876
+#, c-format
+msgid " <EABI version unrecognised>"
+msgstr " <Version EABI non reconnue>"
+
+#: elf32-arm.c:11883
+#, c-format
+msgid " [relocatable executable]"
+msgstr " [exécutables relocalisés]"
+
+#: elf32-arm.c:11886
+#, c-format
+msgid " [has entry point]"
+msgstr " [a des points d'entrées]"
+
+#: elf32-arm.c:11891
+#, c-format
+msgid "<Unrecognised flag bits set>"
+msgstr "<Bits de fanions non reconnus>"
+
+#: elf32-arm.c:12189 elf32-i386.c:1461 elf32-s390.c:1000 elf32-tic6x.c:2829
+#: elf32-tilepro.c:1336 elf32-xtensa.c:1009 elf64-s390.c:960
+#: elf64-x86-64.c:1364 elfxx-sparc.c:1371 elfxx-tilegx.c:1586
+msgid "%B: bad symbol index: %d"
+msgstr "%B: symbole index erroné: %d"
+
+#: elf32-arm.c:12337 elf64-x86-64.c:1561 elf64-x86-64.c:1732 elfxx-mips.c:8223
+msgid "%B: relocation %s against `%s' can not be used when making a shared object; recompile with -fPIC"
+msgstr "%B: réadressage de %s en vertu de « %s » ne peut être utilisé lors de la création d'un objet partagé; recompilez avec -fPIC"
+
+#: elf32-arm.c:13460
+#, c-format
+msgid "Errors encountered processing file %s"
+msgstr "Erreurs rencontrées pendant le traitement du fichier %s"
+
+#: elf32-arm.c:14837
+msgid "%B: error: Cortex-A8 erratum stub is allocated in unsafe location"
+msgstr "%B: erreur: L'ébauche d'erratum du Cortex A8 est allouée à un emplacement peu sûr"
+
+#. There's not much we can do apart from complain if this
+#. happens.
+#: elf32-arm.c:14864
+msgid "%B: error: Cortex-A8 erratum stub out of range (input file too large)"
+msgstr "%B: erreur: L'ébauche d'erratum du Cortex A8 est hors limite (fichier d'entrée trop grand)"
+
+#: elf32-arm.c:14958 elf32-arm.c:14980
+msgid "%B: error: VFP11 veneer out of range"
+msgstr "%B: erreur: vernis VFP11 hors limite"
+
+#: elf32-arm.c:15518
+msgid "error: %B is already in final BE8 format"
+msgstr "erreur: %B est déjà au format final BE8"
+
+#: elf32-arm.c:15594
+msgid "error: Source object %B has EABI version %d, but target %B has EABI version %d"
+msgstr "erreur: L'objet source %B a l'EABI version %d alors que la cible %B a l'EABI version %d"
+
+#: elf32-arm.c:15610
+msgid "error: %B is compiled for APCS-%d, whereas target %B uses APCS-%d"
+msgstr "erreur: %B compilé pour APCS-%d alors que la cible %B utilise APCS-%d"
+
+#: elf32-arm.c:15635
+msgid "error: %B uses VFP instructions, whereas %B does not"
+msgstr "erreur: %B utilise les instructions VFP alors que %B ne les utilise pas"
+
+#: elf32-arm.c:15639
+msgid "error: %B uses FPA instructions, whereas %B does not"
+msgstr "erreur: %B utilise les instructions FPA alors que %B ne les utilise pas"
+
+#: elf32-arm.c:15649
+msgid "error: %B uses Maverick instructions, whereas %B does not"
+msgstr "erreur: %B utilise les instructions Maverick alors que %B ne les utilise pas"
+
+#: elf32-arm.c:15653
+msgid "error: %B does not use Maverick instructions, whereas %B does"
+msgstr "erreur: %B n'utilise pas les instructions Maverick alors que %B les utilise"
+
+#: elf32-arm.c:15672
+msgid "error: %B uses software FP, whereas %B uses hardware FP"
+msgstr "erreur: %B utilise le logiciel pour virgule flottante alors que %B utilise le matériel pour virgule flottante"
+
+#: elf32-arm.c:15676
+msgid "error: %B uses hardware FP, whereas %B uses software FP"
+msgstr "erreur: %B utilise le matériel pour virgule flottante alors que %B utilise le logiciel pour virgule flottante"
+
+#: elf32-avr.c:1229 elf32-bfin.c:3221 elf32-cris.c:2089 elf32-epiphany.c:567
+#: elf32-fr30.c:617 elf32-frv.c:4113 elf32-i860.c:1219 elf32-ip2k.c:1479
+#: elf32-iq2000.c:692 elf32-m32c.c:561 elf32-mep.c:543 elf32-moxie.c:290
+#: elf32-msp430.c:494 elf32-mt.c:399 elf32-openrisc.c:412 elf32-tilepro.c:3222
+#: elf32-v850.c:2151 elf32-xstormy16.c:943 elf64-mmix.c:1598
+#: elfxx-tilegx.c:3585
+msgid "internal error: dangerous relocation"
+msgstr "erreur interne: réadressage dangereux"
+
+#: elf32-avr.c:2415 elf32-hppa.c:598 elf32-m68hc1x.c:166
+msgid "%B: cannot create stub entry %s"
+msgstr "%B: ne peut créer l'entrée de l'ébauche %s"
+
+#: elf32-bfin.c:107 elf32-bfin.c:363
+msgid "relocation should be even number"
+msgstr "le réadressage devrait être un nombre paire"
+
+#: elf32-bfin.c:1593
+msgid "%B(%A+0x%lx): unresolvable relocation against symbol `%s'"
+msgstr "%B(%A+0x%lx): réadressage sans solution vers le symbole « %s »"
+
+#: elf32-bfin.c:1626 elf32-i386.c:4307 elf32-m68k.c:4233 elf32-s390.c:3055
+#: elf64-s390.c:3030 elf64-x86-64.c:4151
+msgid "%B(%A+0x%lx): reloc against `%s': error %d"
+msgstr "%B(%A+0x%lx): relocalisation vers «%s»: erreur %d"
+
+#: elf32-bfin.c:2725
+msgid "%B: relocation at `%A+0x%x' references symbol `%s' with nonzero addend"
+msgstr "%B: réadressage à « %A+0x%x » fait référence au symbole « %s » avec un opérande non nul"
+
+#: elf32-bfin.c:2741
+msgid "relocation references symbol not defined in the module"
+msgstr "le réadressage fait référence à un symbole non défini dans le module"
+
+#: elf32-bfin.c:2838
+msgid "R_BFIN_FUNCDESC references dynamic symbol with nonzero addend"
+msgstr "R_BFIN_FUNCDESC fait référence à un symbole dynamique avec un opérande non nul"
+
+#: elf32-bfin.c:2879 elf32-bfin.c:3002
+msgid "cannot emit fixups in read-only section"
+msgstr "impossible d'apporter des corrections dans une section en lecture seule"
+
+#: elf32-bfin.c:2910 elf32-bfin.c:3040 elf32-lm32.c:1103 elf32-sh.c:5016
+msgid "cannot emit dynamic relocations in read-only section"
+msgstr "impossible d'éditer les réadressages dynamiques dans une section en lecture seule"
+
+#: elf32-bfin.c:2960
+msgid "R_BFIN_FUNCDESC_VALUE references dynamic symbol with nonzero addend"
+msgstr "R_BFIN_FUNCDESC_VALUE fait référence à un symbole dynamique avec un opérande non nul"
+
+#: elf32-bfin.c:3125
+msgid "relocations between different segments are not supported"
+msgstr "les réadressages entre segments différents ne sont pas supportés"
+
+#: elf32-bfin.c:3126
+msgid "warning: relocation references a different segment"
+msgstr "attention: réadressage fait référence à un segment différent"
+
+#: elf32-bfin.c:4971
+msgid "%B: unsupported relocation type %i"
+msgstr "%B: type de réadressage %i non supporté"
+
+#: elf32-bfin.c:5125 elf32-frv.c:6808
+#, c-format
+msgid "%s: cannot link non-fdpic object file into fdpic executable"
+msgstr "%s: ne peut lier un fichier objet non fdpic dans un exécutable fdpic"
+
+#: elf32-bfin.c:5129 elf32-frv.c:6812
+#, c-format
+msgid "%s: cannot link fdpic object file into non-fdpic executable"
+msgstr "%s: ne peut lier un fichier objet fdpic dans un exécutable non fdpic"
+
+#: elf32-bfin.c:5283
+#, c-format
+msgid "*** check this relocation %s"
+msgstr "*** vérifiez ce réadressage %s"
+
+#: elf32-cris.c:1176
+msgid "%B, section %A: unresolvable relocation %s against symbol `%s'"
+msgstr "%B, section %A: réadressage %s non résolu sur le symbole « %s »"
+
+#: elf32-cris.c:1238
+msgid "%B, section %A: No PLT nor GOT for relocation %s against symbol `%s'"
+msgstr "%B, section %a: Pas de PLT ni de GOT pour réadresser %s sur le symbole « %s »"
+
+#: elf32-cris.c:1240
+msgid "%B, section %A: No PLT for relocation %s against symbol `%s'"
+msgstr "%B, section %A: Pas de PLT pour réadresser %s sur le symbole « %s »"
+
+#: elf32-cris.c:1246 elf32-cris.c:1379 elf32-cris.c:1639 elf32-cris.c:1722
+#: elf32-cris.c:1875 elf32-tic6x.c:2662
+msgid "[whose name is lost]"
+msgstr "[dont le nom est perdu]"
+
+#: elf32-cris.c:1365 elf32-tic6x.c:2647
+msgid "%B, section %A: relocation %s with non-zero addend %d against local symbol"
+msgstr "%B, section %A: réadressage de %s avec un opérande non nul %d sur le symbole local"
+
+#: elf32-cris.c:1373 elf32-cris.c:1716 elf32-cris.c:1869 elf32-tic6x.c:2655
+msgid "%B, section %A: relocation %s with non-zero addend %d against symbol `%s'"
+msgstr "%B, section %A: réadressage de %s avec un opérande non nul %d sur le symbole « %s »"
+
+#: elf32-cris.c:1399
+msgid "%B, section %A: relocation %s is not allowed for global symbol: `%s'"
+msgstr "%B, section %A: le réadressage de %s n'est pas permis pour le symbole global: « %s »"
+
+#: elf32-cris.c:1415
+msgid "%B, section %A: relocation %s with no GOT created"
+msgstr "%B, section %A: réadressage de %s sans GOT"
+
+#. We shouldn't get here for GCC-emitted code.
+#: elf32-cris.c:1630
+msgid "%B, section %A: relocation %s has an undefined reference to `%s', perhaps a declaration mixup?"
+msgstr "%B, section %A: réadressage de %s a une référence non définie vers « %s », peut-être un mélange dans les déclarations ?"
+
+#: elf32-cris.c:2002
+msgid "%B, section %A: relocation %s is not allowed for symbol: `%s' which is defined outside the program, perhaps a declaration mixup?"
+msgstr "%B, section %A: réadressage de %s n'est pas permis pour le symbole « %s » qui est défini en dehors du programme, peut-être un mélange dans les déclarations ?"
+
+#: elf32-cris.c:2055
+msgid "(too many global variables for -fpic: recompile with -fPIC)"
+msgstr "(trop de variables globales pour -fpic: recompilez avec -fPIC)"
+
+#: elf32-cris.c:2062
+msgid "(thread-local data too big for -fpic or -msmall-tls: recompile with -fPIC or -mno-small-tls)"
+msgstr "(donnée locale au thread trop grande pour -fpic or -msmall-tls: recompilez avec -fPIC ou -mno-small-tls)"
+
+#: elf32-cris.c:3261
+msgid ""
+"%B, section %A:\n"
+" v10/v32 compatible object %s must not contain a PIC relocation"
+msgstr ""
+"%B, section %A:\n"
+" l'objet compatible v10/v32 %s ne peut pas contenir de réadressage PIC"
+
+#: elf32-cris.c:3366
+msgid ""
+"%B, section %A:\n"
+" relocation %s not valid in a shared object; typically an option mixup, recompile with -fPIC"
+msgstr ""
+"%B, section %A:\n"
+" réadressage de %s pas valable dans un objet partagé; typiquement un mélange dans les options. Recompilez avec -fPIC"
+
+#: elf32-cris.c:3580
+msgid ""
+"%B, section %A:\n"
+" relocation %s should not be used in a shared object; recompile with -fPIC"
+msgstr ""
+"%B, section %A:\n"
+" réadressage de %s ne devrait pas être utilisé dans un objet partagé; recompilez avec -fPIC"
+
+#: elf32-cris.c:4002
+msgid ""
+"%B, section `%A', to symbol `%s':\n"
+" relocation %s should not be used in a shared object; recompile with -fPIC"
+msgstr ""
+"%B, section «%A», vers le symbole «%s»:\n"
+" réadressage de %s ne devrait pas être utilisé dans un objet partagé; recompilez avec -fPIC"
+
+#: elf32-cris.c:4118
+msgid "Unexpected machine number"
+msgstr "Numéro de machine inattendu"
+
+#: elf32-cris.c:4172
+#, c-format
+msgid " [symbols have a _ prefix]"
+msgstr " [symboles sont préfixés par « _ »]"
+
+#: elf32-cris.c:4175
+#, c-format
+msgid " [v10 and v32]"
+msgstr " [v10 et v32]"
+
+#: elf32-cris.c:4178
+#, c-format
+msgid " [v32]"
+msgstr " [v32]"
+
+#: elf32-cris.c:4223
+msgid "%B: uses _-prefixed symbols, but writing file with non-prefixed symbols"
+msgstr "%B: utilise des symboles préfixés par _ mais écrits les symboles sans préfixes dans le fichier"
+
+#: elf32-cris.c:4224
+msgid "%B: uses non-prefixed symbols, but writing file with _-prefixed symbols"
+msgstr "%B: utilise des symboles sans préfixe mais ajoute le préfixe _ aux symboles dans le fichier"
+
+#: elf32-cris.c:4243
+msgid "%B contains CRIS v32 code, incompatible with previous objects"
+msgstr "%B contient du code CRIS v32 incompatible avec les objets précédents"
+
+#: elf32-cris.c:4245
+msgid "%B contains non-CRIS-v32 code, incompatible with previous objects"
+msgstr "%B contient du code non CRIS v32 incompatible avec les objets précédents"
+
+#: elf32-dlx.c:142
+#, c-format
+msgid "BFD Link Error: branch (PC rel16) to section (%s) not supported"
+msgstr "Erreur de liaison BFD: branchement (PC rel16) à la section (%s) n'est pas supporté"
+
+#: elf32-dlx.c:204
+#, c-format
+msgid "BFD Link Error: jump (PC rel26) to section (%s) not supported"
+msgstr "Erreur de liaison BFD: saut (PC rel26) à la section (%s) n'est pas supporté"
+
+#. Only if it's not an unresolved symbol.
+#: elf32-epiphany.c:563 elf32-ip2k.c:1475
+msgid "unsupported relocation between data/insn address spaces"
+msgstr "réadressage non supporté entre les espaces d'adresses data/insn"
+
+#: elf32-frv.c:1509 elf32-frv.c:1658
+msgid "relocation requires zero addend"
+msgstr "le réadressage exige un opérande nul"
+
+#: elf32-frv.c:2888
+msgid "%H: relocation to `%s+%v' may have caused the error above\n"
+msgstr "%H: le réadressage en « %s+%v » peut avoir causé le problème ci-dessus\n"
+
+#: elf32-frv.c:2905
+msgid "%H: relocation references symbol not defined in the module\n"
+msgstr "%H: le réadressage fait référence à un symbole non défini dans le module\n"
+
+#: elf32-frv.c:2981
+msgid "%H: R_FRV_GETTLSOFF not applied to a call instruction\n"
+msgstr "%H: R_FRV_GETTLSOFF pas appliqué à une instruction d'appel\n"
+
+#: elf32-frv.c:3022
+msgid "%H: R_FRV_GOTTLSDESC12 not applied to an lddi instruction\n"
+msgstr "%H: R_FRV_GOTTLSDESC12 pas appliqué à une instruction lddi\n"
+
+#: elf32-frv.c:3093
+msgid "%H: R_FRV_GOTTLSDESCHI not applied to a sethi instruction\n"
+msgstr "%H: R_FRV_GOTTLSDESCHI pas appliqué à une instruction sethi\n"
+
+#: elf32-frv.c:3130
+msgid "%H: R_FRV_GOTTLSDESCLO not applied to a setlo or setlos instruction\n"
+msgstr "%H: R_FRV_GOTTLSDESCLO pas appliqué à une instruction setlo ou setlos\n"
+
+#: elf32-frv.c:3177
+msgid "%H: R_FRV_TLSDESC_RELAX not applied to an ldd instruction\n"
+msgstr "%H: R_FRV_TLSDESC_RELAX pas appliqué à une instruction ldd\n"
+
+#: elf32-frv.c:3261
+msgid "%H: R_FRV_GETTLSOFF_RELAX not applied to a calll instruction\n"
+msgstr "%H: R_FRV_GETTLSOFF_RELAX pas appliqué à une instruction calll\n"
+
+#: elf32-frv.c:3315
+msgid "%H: R_FRV_GOTTLSOFF12 not applied to an ldi instruction\n"
+msgstr "%H: R_FRV_GOTTLSOFF12 pas appliqué à une instruction ldi\n"
+
+#: elf32-frv.c:3345
+msgid "%H: R_FRV_GOTTLSOFFHI not applied to a sethi instruction\n"
+msgstr "%H: R_FRV_GOTTLSOFFHI pas appliqué à une instruction sethi\n"
+
+#: elf32-frv.c:3374
+msgid "%H: R_FRV_GOTTLSOFFLO not applied to a setlo or setlos instruction\n"
+msgstr "%H: R_FRV_GOTTLSOFFLO pas appliqué à une instruction setlo ou setlos\n"
+
+#: elf32-frv.c:3404
+msgid "%H: R_FRV_TLSOFF_RELAX not applied to an ld instruction\n"
+msgstr "%H: R_FRV_TLSOFF_RELAX pas appliqué à une instruction ld\n"
+
+#: elf32-frv.c:3449
+msgid "%H: R_FRV_TLSMOFFHI not applied to a sethi instruction\n"
+msgstr "%H: R_FRV_TLSMOFFHI pas appliqué à une instruction sethi\n"
+
+#: elf32-frv.c:3476
+msgid "R_FRV_TLSMOFFLO not applied to a setlo or setlos instruction\n"
+msgstr "R_FRV_TLSMOFFLO pas appliqué à une instruction setlo ou setlos\n"
+
+#: elf32-frv.c:3597
+msgid "%H: R_FRV_FUNCDESC references dynamic symbol with nonzero addend\n"
+msgstr "%H: R_FRV_FUNCDESC fait référence à un symbole dynamique avec un opérande non nul\n"
+
+#: elf32-frv.c:3638 elf32-frv.c:3760
+msgid "%H: cannot emit fixups in read-only section\n"
+msgstr "%H: impossible d'apporter des corrections dans une section en lecture seule\n"
+
+#: elf32-frv.c:3669 elf32-frv.c:3803
+msgid "%H: cannot emit dynamic relocations in read-only section\n"
+msgstr "%H: impossible d'éditer les réadressages dynamiques dans une section en lecture seule\n"
+
+#: elf32-frv.c:3718
+msgid "%H: R_FRV_FUNCDESC_VALUE references dynamic symbol with nonzero addend\n"
+msgstr "%H: R_FRV_FUNCDESC_VALUE fait référence à un symbole dynamique avec un opérande non nul\n"
+
+#: elf32-frv.c:3974
+msgid "%H: reloc against `%s' references a different segment\n"
+msgstr "%H: le réadressage sur « %s » fait référence à un segment différent\n"
+
+#: elf32-frv.c:4124
+msgid "%H: reloc against `%s': %s\n"
+msgstr "%H: réadressage sur « %s »: %s\n"
+
+#: elf32-frv.c:6400
+msgid "%B: unsupported relocation type %i\n"
+msgstr "%B: type de réadressage %i non supporté\n"
+
+#: elf32-frv.c:6722
+#, c-format
+msgid "%s: compiled with %s and linked with modules that use non-pic relocations"
+msgstr "%s: compilé avec %s et lié avec les modules qui utilisent le réadressage non PIC"
+
+#: elf32-frv.c:6775 elf32-iq2000.c:845 elf32-m32c.c:807
+#, c-format
+msgid "%s: compiled with %s and linked with modules compiled with %s"
+msgstr "%s: compilé avec %s et lié avec les modules compilés avec %s"
+
+#: elf32-frv.c:6787
+#, c-format
+msgid "%s: uses different unknown e_flags (0x%lx) fields than previous modules (0x%lx)"
+msgstr "%s: utilise différents champs e_flags (0x%lx) que les modules précédents (0x%lx)"
+
+#: elf32-frv.c:6837 elf32-iq2000.c:882 elf32-m32c.c:843 elf32-mt.c:576
+#: elf32-rx.c:3001
+#, c-format
+msgid "private flags = 0x%lx:"
+msgstr "fanions privés = 0x%lx:"
+
+#: elf32-gen.c:69 elf64-gen.c:69
+msgid "%B: Relocations in generic ELF (EM: %d)"
+msgstr "%B: Réadressages en format ELF générique (EM: %d)"
+
+#: elf32-hppa.c:850 elf32-hppa.c:3598
+msgid "%B(%A+0x%lx): cannot reach %s, recompile with -ffunction-sections"
+msgstr "%B(%A+0x%lx): ne peut atteindre %s, recompilez avec -ffunction-sections"
+
+#: elf32-hppa.c:1284
+msgid "%B: relocation %s can not be used when making a shared object; recompile with -fPIC"
+msgstr "%B: réadressage de %s ne peut être utilisé lors de la création d'un objet partagé; recompilez avec -fPIC"
+
+#: elf32-hppa.c:2791
+msgid "%B: duplicate export stub %s"
+msgstr "%B: ébauche d'exportation en double %s"
+
+#: elf32-hppa.c:3437
+msgid "%B(%A+0x%lx): %s fixup for insn 0x%x is not supported in a non-shared link"
+msgstr "%B(%A+0x%lx): correction %s pour insn 0x%x n'est pas supporté dans un lien non partagé"
+
+#: elf32-hppa.c:4284
+msgid "%B(%A+0x%lx): cannot handle %s for %s"
+msgstr "%B(%A+0x%lx): ne sait pas traiter %s pour %s"
+
+#: elf32-hppa.c:4603
+msgid ".got section not immediately after .plt section"
+msgstr "section .got pas immédiatement après la section .plt"
+
+#. Unknown relocation.
+#: elf32-i386.c:373 elf32-m68k.c:384 elf32-ppc.c:1676 elf32-s390.c:379
+#: elf32-tic6x.c:2684 elf64-ppc.c:2300 elf64-s390.c:403 elf64-x86-64.c:265
+msgid "%B: invalid relocation type %d"
+msgstr "%B: type de réadressage %d invalide"
+
+#: elf32-i386.c:1404 elf64-x86-64.c:1308
+msgid "%B: TLS transition from %s to %s against `%s' at 0x%lx in section `%A' failed"
+msgstr "%B: Échec de la transition TLS de %s vers %s sur «%s» à 0x%lx dans la section «%A»"
+
+#: elf32-i386.c:1549 elf32-i386.c:3244 elf64-x86-64.c:1487 elf64-x86-64.c:3125
+#: elfxx-sparc.c:3083
+msgid "%B: relocation %s against STT_GNU_IFUNC symbol `%s' isn't handled by %s"
+msgstr "%B: le réadressage %s sur le symbole STT_GNU_IFUNC « %s » n'est pas géré par %s"
+
+#: elf32-i386.c:1711 elf32-s390.c:1182 elf32-sh.c:6362 elf32-tilepro.c:1434
+#: elf32-xtensa.c:1182 elf64-s390.c:1151 elfxx-sparc.c:1548
+#: elfxx-tilegx.c:1701
+msgid "%B: `%s' accessed both as normal and thread local symbol"
+msgstr "%B: «%s» accédé à la fois comme symbole normal et comme symbole locale au thread"
+
+#: elf32-i386.c:2539 elf64-x86-64.c:2506
+msgid "%P: %B: warning: relocation against `%s' in readonly section `%A'.\n"
+msgstr "%P: %B: attention: réadressage sur « %s » dans la section en lecture seule « %A ».\n"
+
+#: elf32-i386.c:2629 elf64-x86-64.c:2593
+msgid "%P: %B: warning: relocation in readonly section `%A'.\n"
+msgstr "%P: %B: attention: réadressage dans la section « %A » en lecture seule.\n"
+
+#: elf32-i386.c:3086 elf32-tilepro.c:2557 elfxx-tilegx.c:2871
+msgid "%B: unrecognized relocation (0x%x) in section `%A'"
+msgstr "%B: réadressage inconnu (0x%x) dans la section « %A »"
+
+#: elf32-i386.c:3494 elf64-x86-64.c:3513
+msgid "hidden symbol"
+msgstr "symbole caché"
+
+#: elf32-i386.c:3497 elf64-x86-64.c:3516
+msgid "internal symbol"
+msgstr "symbole interne"
+
+#: elf32-i386.c:3500 elf64-x86-64.c:3519
+msgid "protected symbol"
+msgstr "symbole protégé"
+
+#: elf32-i386.c:3503 elf64-x86-64.c:3522
+msgid "symbol"
+msgstr "symbole"
+
+#: elf32-i386.c:3508
+msgid "%B: relocation R_386_GOTOFF against undefined %s `%s' can not be used when making a shared object"
+msgstr "%B: réadressage R_386_GOTOFF sur le symbole %s « %s » non défini ne peut pas être utilisé lors de la création d'un objet partagé"
+
+#: elf32-i386.c:3518
+msgid "%B: relocation R_386_GOTOFF against protected function `%s' can not be used when making a shared object"
+msgstr "%B: réadressage R_386_GOTOFF vers la fonction protégée « %s » ne peut pas être utilisé lors de la création d'un objet partagé"
+
+#: elf32-i386.c:4839 elf32-tilepro.c:3467 elf64-x86-64.c:4609
+#: elfxx-tilegx.c:3847
+#, c-format
+msgid "discarded output section: `%A'"
+msgstr "section de sortie rejetée: «%A»"
+
+#: elf32-ip2k.c:857 elf32-ip2k.c:863 elf32-ip2k.c:930 elf32-ip2k.c:936
+msgid "ip2k relaxer: switch table without complete matching relocation information."
+msgstr "relâche ip2k: table de commutation sans concordance complète des informations de réadressage"
+
+#: elf32-ip2k.c:880 elf32-ip2k.c:963
+msgid "ip2k relaxer: switch table header corrupt."
+msgstr "relâche ip2k: en-tête de table de commutation corrompue"
+
+#: elf32-ip2k.c:1292
+#, c-format
+msgid "ip2k linker: missing page instruction at 0x%08lx (dest = 0x%08lx)."
+msgstr "liaison ip2k: instruction de page manquante à 0x%08lx (cible = 0x%08lx)."
+
+#: elf32-ip2k.c:1308
+#, c-format
+msgid "ip2k linker: redundant page instruction at 0x%08lx (dest = 0x%08lx)."
+msgstr "liaison ip2k: instruction de page redondante à 0x%08lx (cible = 0x%08lx)."
+
+#: elf32-iq2000.c:858 elf32-m32c.c:819
+#, c-format
+msgid "%s: uses different e_flags (0x%lx) fields than previous modules (0x%lx)"
+msgstr "%s: utilise des champs e_flags (0x%lx) différents des modules précédents (0x%lx)"
+
+#: elf32-lm32.c:706
+msgid "global pointer relative relocation when _gp not defined"
+msgstr "réadressage relatif au pointeur global sans que _gp ne soit défini"
+
+#: elf32-lm32.c:761
+msgid "global pointer relative address out of range"
+msgstr "adresse relative du pointeur global hors limites"
+
+#: elf32-lm32.c:1057
+msgid "internal error: addend should be zero for R_LM32_16_GOT"
+msgstr "erreur interne: opérande devrait être zéro pour R_LM32_16_GOT"
+
+#: elf32-m32r.c:1453
+msgid "SDA relocation when _SDA_BASE_ not defined"
+msgstr "réadressage SDA alors que _SDA_BASE_ n'est pas défini"
+
+#: elf32-m32r.c:3043
+msgid "%B: The target (%s) of an %s relocation is in the wrong section (%A)"
+msgstr "%B: la cible (%s) du réadressage %s est dans la mauvaise section (%A)"
+
+#: elf32-m32r.c:3571
+msgid "%B: Instruction set mismatch with previous modules"
+msgstr "%B: jeu d'instructions ne concorde par avec les modules précédents"
+
+#: elf32-m32r.c:3592
+#, c-format
+msgid "private flags = %lx"
+msgstr "fanions privés = %lx"
+
+#: elf32-m32r.c:3597
+#, c-format
+msgid ": m32r instructions"
+msgstr ": instructions m32r"
+
+#: elf32-m32r.c:3598
+#, c-format
+msgid ": m32rx instructions"
+msgstr ": instruction m32rx"
+
+#: elf32-m32r.c:3599
+#, c-format
+msgid ": m32r2 instructions"
+msgstr ": instructions m32r2"
+
+#: elf32-m68hc1x.c:1050
+#, c-format
+msgid "Reference to the far symbol `%s' using a wrong relocation may result in incorrect execution"
+msgstr "Référence à un symbole far « %s » utilisant le mauvais réadressage peut provoquer une exécution incorrecte"
+
+#: elf32-m68hc1x.c:1073
+#, c-format
+msgid "banked address [%lx:%04lx] (%lx) is not in the same bank as current banked address [%lx:%04lx] (%lx)"
+msgstr "banque d'adresses [%lx:%04lx] (%lx) n'es pas dans la même banque que la banque courante d'adresses [%lx:%04lx] (%lx)"
+
+#: elf32-m68hc1x.c:1092
+#, c-format
+msgid "reference to a banked address [%lx:%04lx] in the normal address space at %04lx"
+msgstr "référence à une banque d'adresses [%lx:%04lx] dans l'espace normal d'adresses à %04lx"
+
+#: elf32-m68hc1x.c:1225
+msgid "%B: linking files compiled for 16-bit integers (-mshort) and others for 32-bit integers"
+msgstr "%B: fichiers liés compilés pour des entiers de 16 bits (-mshort) et d'autres pour des entiers de 32 bits"
+
+#: elf32-m68hc1x.c:1232
+msgid "%B: linking files compiled for 32-bit double (-fshort-double) and others for 64-bit double"
+msgstr "%B: fichiers liés compilés pour des doubles de 32 bits (-fshort-double) et d'autres pour des doubles de 64 bits"
+
+#: elf32-m68hc1x.c:1241
+msgid "%B: linking files compiled for HCS12 with others compiled for HC12"
+msgstr "%B: certains fichiers liés compilés pour HCS12 avec d'autres compilés pour HC12"
+
+#: elf32-m68hc1x.c:1257 elf32-ppc.c:4227 elf64-sparc.c:706 elfxx-mips.c:13965
+msgid "%B: uses different e_flags (0x%lx) fields than previous modules (0x%lx)"
+msgstr "%B: utilise des champs e_flags (0x%lx) différents des modules précédents (0x%lx)"
+
+#: elf32-m68hc1x.c:1285
+#, c-format
+msgid "[abi=32-bit int, "
+msgstr "[abi=32-bit int, "
+
+#: elf32-m68hc1x.c:1287
+#, c-format
+msgid "[abi=16-bit int, "
+msgstr "[abi=16-bit int, "
+
+#: elf32-m68hc1x.c:1290
+#, c-format
+msgid "64-bit double, "
+msgstr "double de 64 bits, "
+
+#: elf32-m68hc1x.c:1292
+#, c-format
+msgid "32-bit double, "
+msgstr "double de 32 bits, "
+
+#: elf32-m68hc1x.c:1295
+#, c-format
+msgid "cpu=HC11]"
+msgstr "cpu=HC11]"
+
+#: elf32-m68hc1x.c:1297
+#, c-format
+msgid "cpu=HCS12]"
+msgstr "cpu=HCS12]"
+
+#: elf32-m68hc1x.c:1299
+#, c-format
+msgid "cpu=HC12]"
+msgstr "cpu=HC12]"
+
+#: elf32-m68hc1x.c:1302
+#, c-format
+msgid " [memory=bank-model]"
+msgstr " [memory=bank-model]"
+
+#: elf32-m68hc1x.c:1304
+#, c-format
+msgid " [memory=flat]"
+msgstr " [memory=flat]"
+
+#: elf32-m68k.c:1251 elf32-m68k.c:1252 vms-alpha.c:7314 vms-alpha.c:7329
+msgid "unknown"
+msgstr "inconnu"
+
+#: elf32-m68k.c:1715
+msgid "%B: GOT overflow: Number of relocations with 8-bit offset > %d"
+msgstr "%B: débordement GOT: Nombre de réadressages avec des offsets de 8 bits > %d"
+
+#: elf32-m68k.c:1721
+msgid "%B: GOT overflow: Number of relocations with 8- or 16-bit offset > %d"
+msgstr "%B: débordement GOT: Nombre de réadressages avec des offsets de 8 ou 16 bits > %d"
+
+#: elf32-m68k.c:3957
+msgid "%B(%A+0x%lx): R_68K_TLS_LE32 relocation not permitted in shared object"
+msgstr "%B(%A+0x%lx): réadressage R_68K_TLS_LE32 pas permis dans un objet partagé"
+
+#: elf32-mcore.c:99 elf32-mcore.c:442
+msgid "%B: Relocation %s (%d) is not currently supported.\n"
+msgstr "%B: Réadressage %s (%d) n'est pas actuellement supporté.\n"
+
+#: elf32-mcore.c:428
+msgid "%B: Unknown relocation type %d\n"
+msgstr "%B: Type de réadressage %d inconnu\n"
+
+#. Pacify gcc -Wall.
+#: elf32-mep.c:157
+#, c-format
+msgid "mep: no reloc for code %d"
+msgstr "mep: pas de réadressage pour le code %d"
+
+#: elf32-mep.c:163
+#, c-format
+msgid "MeP: howto %d has type %d"
+msgstr "MeP: le howto %d a le type %d"
+
+#: elf32-mep.c:648
+msgid "%B and %B are for different cores"
+msgstr "%B et %B sont pour des noyaux différents"
+
+#: elf32-mep.c:665
+msgid "%B and %B are for different configurations"
+msgstr "%B et %B sont pour des configurations différentes"
+
+#: elf32-mep.c:702
+#, c-format
+msgid "private flags = 0x%lx"
+msgstr "fanions privés = 0x%lx"
+
+#: elf32-microblaze.c:742
+#, c-format
+msgid "%s: unknown relocation type %d"
+msgstr "%s: type de réadressage %d inconnu"
+
+#: elf32-microblaze.c:867 elf32-microblaze.c:912
+#, c-format
+msgid "%s: The target (%s) of an %s relocation is in the wrong section (%s)"
+msgstr "%s: la cible (%s) du réadressage %s est dans la mauvaise section (%s)"
+
+#: elf32-microblaze.c:1155 elf32-tilepro.c:2891 elfxx-sparc.c:3457
+#: elfxx-tilegx.c:3230
+msgid "%B: probably compiled without -fPIC?"
+msgstr "%B: probablement compilé sans -fPIC?"
+
+#: elf32-microblaze.c:2074
+msgid "%B: bad relocation section name `%s'"
+msgstr "%B: nom de section de réadressage erroné « %s »"
+
+#: elf32-mips.c:1549 elf64-mips.c:2683 elfn32-mips.c:2487
+msgid "literal relocation occurs for an external symbol"
+msgstr "réadressage littéral rencontré pour un symbole externe"
+
+#: elf32-mips.c:1596 elf32-score.c:570 elf32-score7.c:469 elf64-mips.c:2726
+#: elfn32-mips.c:2528
+msgid "32bits gp relative relocation occurs for an external symbol"
+msgstr "réadressage relatif gp 32bits rencontré pour un symbole externe"
+
+#: elf32-ppc.c:1741
+#, c-format
+msgid "generic linker can't handle %s"
+msgstr "liaison générique ne peut traiter %s"
+
+#: elf32-ppc.c:2184
+msgid "corrupt %s section in %B"
+msgstr "section %s corrompue dans %B"
+
+#: elf32-ppc.c:2203
+msgid "unable to read in %s section from %B"
+msgstr "incapable de lire dans la section %s à partir de %B"
+
+#: elf32-ppc.c:2244
+msgid "warning: unable to set size of %s section in %B"
+msgstr "attention: incapable d'initialiser la taille de la section %s dans %B"
+
+#: elf32-ppc.c:2294
+msgid "failed to allocate space for new APUinfo section."
+msgstr "échec d'allocation d'espace pour une nouvelle section APUinfo"
+
+#: elf32-ppc.c:2313
+msgid "failed to compute new APUinfo section."
+msgstr "échec d'évaluation de la nouvelle section APUinfo"
+
+#: elf32-ppc.c:2316
+msgid "failed to install new APUinfo section."
+msgstr "échec d'installation de la nouvelle section APUinfo"
+
+#: elf32-ppc.c:3356
+msgid "%B: relocation %s cannot be used when making a shared object"
+msgstr "%B: réadressage %s ne peut être utilisé lors de la création d'un objet partagé"
+
+#. It does not make sense to have a procedure linkage
+#. table entry for a local symbol.
+#: elf32-ppc.c:3700
+msgid "%P: %H: %s reloc against local symbol\n"
+msgstr "%P: %H: %s réadressé par rapport à un symbole local\n"
+
+#: elf32-ppc.c:4039 elf32-ppc.c:4054 elfxx-mips.c:13651 elfxx-mips.c:13677
+#: elfxx-mips.c:13699 elfxx-mips.c:13725
+msgid "Warning: %B uses hard float, %B uses soft float"
+msgstr "Attention: %B utilise la virgule flottante matérielle, %B utilise la virgule flottante logicielle"
+
+#: elf32-ppc.c:4042 elf32-ppc.c:4046
+msgid "Warning: %B uses double-precision hard float, %B uses single-precision hard float"
+msgstr "Attention: %B utilise la virgule flottante double précision matérielle, %B utilise la virgule flottante simple précision matérielle"
+
+#: elf32-ppc.c:4050
+msgid "Warning: %B uses soft float, %B uses single-precision hard float"
+msgstr "Attention: %B utilise la virgule flottante logicielle, %B utilise la virgule flottante simple précision matérielle"
+
+#: elf32-ppc.c:4057 elf32-ppc.c:4061 elfxx-mips.c:13631 elfxx-mips.c:13635
+msgid "Warning: %B uses unknown floating point ABI %d"
+msgstr "Attention: %B utilise l'ABI inconnu %d pour la gestion des virgules flottantes"
+
+#: elf32-ppc.c:4103 elf32-ppc.c:4107
+msgid "Warning: %B uses unknown vector ABI %d"
+msgstr "Attention: %B utilise l'ABI inconnu %d pour les vecteurs"
+
+#: elf32-ppc.c:4111
+msgid "Warning: %B uses vector ABI \"%s\", %B uses \"%s\""
+msgstr "Attention: %B utilise l'ABI de vecteurs «%s», %B utilise «%s»"
+
+#: elf32-ppc.c:4128 elf32-ppc.c:4131
+msgid "Warning: %B uses r3/r4 for small structure returns, %B uses memory"
+msgstr "Attention: %B utilise r3/r4 pour les retours de petites structures, %B utilise la mémoire"
+
+#: elf32-ppc.c:4134 elf32-ppc.c:4138
+msgid "Warning: %B uses unknown small structure return convention %d"
+msgstr "Attention: %B utilise la convention inconnue %d pour le retour des petites structures"
+
+#: elf32-ppc.c:4192
+msgid "%B: compiled with -mrelocatable and linked with modules compiled normally"
+msgstr "%B: compilé avec -mrelocatable et fait l'édition de lien avec les modules compilés normalement"
+
+#: elf32-ppc.c:4200
+msgid "%B: compiled normally and linked with modules compiled with -mrelocatable"
+msgstr "%B: compilé normalement et fait l'édition de lien avec les modules compilés avec -mrelocatable"
+
+#: elf32-ppc.c:4309
+msgid "%P: bss-plt forced due to %B\n"
+msgstr "%P: bss-plt forcé à cause de %B\n"
+
+#: elf32-ppc.c:4312
+msgid "%P: bss-plt forced by profiling\n"
+msgstr "%P: bss-plt forcé par le profilage\n"
+
+#. Uh oh, we didn't find the expected call. We
+#. could just mark this symbol to exclude it
+#. from tls optimization but it's safer to skip
+#. the entire optimization.
+#: elf32-ppc.c:4809 elf64-ppc.c:7858
+msgid "%H arg lost __tls_get_addr, TLS optimization disabled\n"
+msgstr "%H l'argument a perdu __tls_get_addr, optimisation TLS désactivée\n"
+
+#: elf32-ppc.c:5044 elf64-ppc.c:6528
+msgid "%P: dynamic variable `%s' is zero size\n"
+msgstr "%P: la variable dynamique « %s » a une taille nulle\n"
+
+#: elf32-ppc.c:7263 elf64-ppc.c:12675
+msgid "%P: %B: unknown relocation type %d for symbol %s\n"
+msgstr "%P: %B: type de réadressage %d inconnu pour le symbole %s\n"
+
+#: elf32-ppc.c:7524
+msgid "%P: %H: non-zero addend on %s reloc against `%s'\n"
+msgstr "%P: %H: opérande non nul sur le réadressage %s par rapport à « %s »\n"
+
+#: elf32-ppc.c:7720 elf64-ppc.c:13181
+msgid "%P: %H: relocation %s for indirect function %s unsupported\n"
+msgstr "%P: %H: réadressage %s non supporté pour la fonction indirecte %s\n"
+
+#: elf32-ppc.c:7948 elf32-ppc.c:7978 elf32-ppc.c:8025
+msgid "%P: %B: the target (%s) of a %s relocation is in the wrong output section (%s)\n"
+msgstr "%P: %B: la cible (%s) d'un réadressage %s est dans la mauvaise section de sortie (%s)\n"
+
+#: elf32-ppc.c:8097
+msgid "%P: %B: relocation %s is not yet supported for symbol %s\n"
+msgstr "%P: %B: réadressage %s n'est pas encore supporté pour le symbole %s\n"
+
+#: elf32-ppc.c:8158 elf64-ppc.c:13467
+msgid "%P: %H: unresolvable %s relocation against symbol `%s'\n"
+msgstr "%P: %H: réadressage %s sans solution par rapport au symbole « %s »\n"
+
+#: elf32-ppc.c:8205 elf64-ppc.c:13512
+msgid "%P: %H: %s reloc against `%s': error %d\n"
+msgstr "%P: %H: réadressage %s vers « %s »: erreur %d\n"
+
+#: elf32-ppc.c:8696
+msgid "%P: %s not defined in linker created %s\n"
+msgstr "%P: %s pas défini dans %s créé par l'éditeur de liens\n"
+
+#: elf32-rx.c:563
+msgid "%B:%A: Warning: deprecated Red Hat reloc "
+msgstr "%B:%A: Attention: relocalisation Red Hat réprouvée "
+
+#. Check for unsafe relocs in PID mode. These are any relocs where
+#. an absolute address is being computed. There are special cases
+#. for relocs against symbols that are known to be referenced in
+#. crt0.o before the PID base address register has been initialised.
+#: elf32-rx.c:581
+msgid "%B(%A): unsafe PID relocation %s at 0x%08lx (against %s in %s)"
+msgstr "%B(%A): réadressage PID %s non sûr à 0x%08lx (sur %s dans %s)"
+
+#: elf32-rx.c:1157
+msgid "Warning: RX_SYM reloc with an unknown symbol"
+msgstr "Attention: Relocalistaion RX_SYM avec un symbole inconnu"
+
+#: elf32-rx.c:1324
+msgid "%B(%A): error: call to undefined function '%s'"
+msgstr "%B(%A): erreur: appel à la fonction non définie «%s»"
+
+#: elf32-rx.c:1338
+msgid "%B(%A): warning: unaligned access to symbol '%s' in the small data area"
+msgstr "%B(%A): attention: accès non aligné au symbole «%s» dans la zone des petites données"
+
+#: elf32-rx.c:1342
+msgid "%B(%A): internal error: out of range error"
+msgstr "%B(%A): erreur interne: hors limite"
+
+#: elf32-rx.c:1346
+msgid "%B(%A): internal error: unsupported relocation error"
+msgstr "%B(%A): erreur interne: réadressage non supporté"
+
+#: elf32-rx.c:1350
+msgid "%B(%A): internal error: dangerous relocation"
+msgstr "%B(%A): erreur interne: réadressage dangereux"
+
+#: elf32-rx.c:1354
+msgid "%B(%A): internal error: unknown error"
+msgstr "%B(%A): erreur interne: erreur inconnue"
+
+#: elf32-rx.c:3004
+#, c-format
+msgid " [64-bit doubles]"
+msgstr " [doubles de 64 bits]"
+
+#: elf32-rx.c:3006
+#, c-format
+msgid " [dsp]"
+msgstr " [dsp]"
+
+#: elf32-s390.c:2200 elf64-s390.c:2187
+msgid "%B(%A+0x%lx): invalid instruction for TLS relocation %s"
+msgstr "%B(%A+0x%lx): instruction invalide pour le réadressage TLS %s"
+
+#: elf32-score.c:1520 elf32-score7.c:1379 elfxx-mips.c:3435
+msgid "not enough GOT space for local GOT entries"
+msgstr "pas suffisamment d'espace GOT pour les entrées locales GOT"
+
+#: elf32-score.c:2742
+msgid "address not word align"
+msgstr "adresse pas alignée sur un mot"
+
+#: elf32-score.c:2827 elf32-score7.c:2631
+#, c-format
+msgid "%s: Malformed reloc detected for section %s"
+msgstr "%s: relocalisation mal composée détectée dans la section %s"
+
+#: elf32-score.c:2878 elf32-score7.c:2682
+msgid "%B: CALL15 reloc at 0x%lx not against global symbol"
+msgstr "%B: appel CALL15 de relocalisation à 0x%lx n'est pas appliqué sur un symbole global"
+
+#: elf32-score.c:3997 elf32-score7.c:3803
+#, c-format
+msgid " [pic]"
+msgstr " [pic]"
+
+#: elf32-score.c:4001 elf32-score7.c:3807
+#, c-format
+msgid " [fix dep]"
+msgstr " [fix dep]"
+
+#: elf32-score.c:4043 elf32-score7.c:3849
+msgid "%B: warning: linking PIC files with non-PIC files"
+msgstr "%B: attention: édition de liens des fichiers PIC avec des fichiers non PIC"
+
+#: elf32-sh-symbian.c:130
+msgid "%B: IMPORT AS directive for %s conceals previous IMPORT AS"
+msgstr "%B: la directive IMPORT AS de %s masque l'IMPORT AS précédent"
+
+#: elf32-sh-symbian.c:383
+msgid "%B: Unrecognised .directive command: %s"
+msgstr "%B: Commande .directive non reconnue: %s"
+
+#: elf32-sh-symbian.c:504
+msgid "%B: Failed to add renamed symbol %s"
+msgstr "%B: Échec de l'ajout du symbole renommé %s"
+
+#: elf32-sh.c:568
+msgid "%B: 0x%lx: warning: bad R_SH_USES offset"
+msgstr "%B: 0x%lx: attention: mauvais décalage pour R_SH_USES"
+
+#: elf32-sh.c:580
+msgid "%B: 0x%lx: warning: R_SH_USES points to unrecognized insn 0x%x"
+msgstr "%B: 0x%lx: attention: R_SH_USES pointe vers un insn inconnu 0x%x"
+
+#: elf32-sh.c:597
+msgid "%B: 0x%lx: warning: bad R_SH_USES load offset"
+msgstr "%B: 0x%lx: attention: mauvais décalage de chargement R_SH_USES"
+
+#: elf32-sh.c:612
+msgid "%B: 0x%lx: warning: could not find expected reloc"
+msgstr "%B: 0x%lx: attention: ne peut repérer la relocalisation attendue"
+
+#: elf32-sh.c:640
+msgid "%B: 0x%lx: warning: symbol in unexpected section"
+msgstr "%B: 0x%lx: attention: symbole dans une section inattendue"
+
+#: elf32-sh.c:766
+msgid "%B: 0x%lx: warning: could not find expected COUNT reloc"
+msgstr "%B: 0x%lx: attention: ne peut repérer le compteur de relocalisation attendu"
+
+#: elf32-sh.c:775
+msgid "%B: 0x%lx: warning: bad count"
+msgstr "%B: 0x%lx: attention: mauvais décompte"
+
+#: elf32-sh.c:1179 elf32-sh.c:1549
+msgid "%B: 0x%lx: fatal: reloc overflow while relaxing"
+msgstr "%B: 0x%lx: erreur fatale: débordement de relocalisation lors des relâches"
+
+#: elf32-sh.c:4048 elf64-sh64.c:1514
+msgid "Unexpected STO_SH5_ISA32 on local symbol is not handled"
+msgstr "STO_SH5_ISA32 inattendu sur le symbole local n'est pas traité"
+
+#: elf32-sh.c:4299
+msgid "%B: 0x%lx: fatal: unaligned branch target for relax-support relocation"
+msgstr "%B: 0x%lx: fatal: cible de branchement non alignée pour un réadressage de type relax-support"
+
+#: elf32-sh.c:4332 elf32-sh.c:4347
+msgid "%B: 0x%lx: fatal: unaligned %s relocation 0x%lx"
+msgstr "%B: 0x%lx: fatal: réadressage %s non aligné 0x%lx"
+
+#: elf32-sh.c:4361
+msgid "%B: 0x%lx: fatal: R_SH_PSHA relocation %d not in range -32..32"
+msgstr "%B: 0x%lx: fatal: réadressage R_SH_PSHA %d pas dans l'intervalle -32..32"
+
+#: elf32-sh.c:4375
+msgid "%B: 0x%lx: fatal: R_SH_PSHL relocation %d not in range -32..32"
+msgstr "%B: 0x%lx: fatal: réadressage R_SH_PSHL %d n'est pas dans l'intervalle -32..32"
+
+#: elf32-sh.c:4519 elf32-sh.c:4989
+msgid "%B(%A+0x%lx): cannot emit fixup to `%s' in read-only section"
+msgstr "%B(%A+0x%lx): impossible d'apporter des corrections à «%s» dans une section en lecture seule"
+
+#: elf32-sh.c:5096
+msgid "%B(%A+0x%lx): %s relocation against external symbol \"%s\""
+msgstr "%B(%A+0x%lx): %s réadressage vers le symbole externe « %s »"
+
+#: elf32-sh.c:5569
+#, c-format
+msgid "%X%C: relocation to \"%s\" references a different segment\n"
+msgstr "%X%C: le réadressage vers « %s » fait référence à un segment différent\n"
+
+#: elf32-sh.c:5575
+#, c-format
+msgid "%C: warning: relocation to \"%s\" references a different segment\n"
+msgstr "%C: attention: réadressage vers « %s » fait référence à un segment différent\n"
+
+#: elf32-sh.c:6353 elf32-sh.c:6436
+msgid "%B: `%s' accessed both as normal and FDPIC symbol"
+msgstr "%B: «%s» accédé à la fois comme symbole normal et comme symbole FDPIC"
+
+#: elf32-sh.c:6358 elf32-sh.c:6440
+msgid "%B: `%s' accessed both as FDPIC and thread local symbol"
+msgstr "%B: «%s» accédé à la fois comme symbole FDPIC et comme symbole local au thread"
+
+#: elf32-sh.c:6388
+msgid "%B: Function descriptor relocation with non-zero addend"
+msgstr "%B: Descripteur de fonction réadressé avec un opérande non nul"
+
+#: elf32-sh.c:6624 elf64-alpha.c:4652
+msgid "%B: TLS local exec code cannot be linked into shared objects"
+msgstr "%B: code exécutable local TLS ne peut être lié en objets partagés"
+
+#: elf32-sh64.c:223 elf64-sh64.c:2318
+#, c-format
+msgid "%s: compiled as 32-bit object and %s is 64-bit"
+msgstr "%s: compilé comme un objet de 32 bits et %s est de 64 bits"
+
+#: elf32-sh64.c:226 elf64-sh64.c:2321
+#, c-format
+msgid "%s: compiled as 64-bit object and %s is 32-bit"
+msgstr "%s: compilé comme un objet de 64 bits et %s est de 32 bits"
+
+#: elf32-sh64.c:228 elf64-sh64.c:2323
+#, c-format
+msgid "%s: object size does not match that of target %s"
+msgstr "%s: taille de l'objet ne concorde pas avec la taille de la cible %s"
+
+#: elf32-sh64.c:451 elf64-sh64.c:2837
+#, c-format
+msgid "%s: encountered datalabel symbol in input"
+msgstr "%s: rencontre du symbole d'une étiquette de donnée dans l'entrée"
+
+#: elf32-sh64.c:528
+msgid "PTB mismatch: a SHmedia address (bit 0 == 1)"
+msgstr "Non concordance PTB: adresse SHmedia (bit 0 == 1)"
+
+#: elf32-sh64.c:531
+msgid "PTA mismatch: a SHcompact address (bit 0 == 0)"
+msgstr "Non concordance PTA: adresse SHcompact (bit 0 == 0)"
+
+#: elf32-sh64.c:549
+#, c-format
+msgid "%s: GAS error: unexpected PTB insn with R_SH_PT_16"
+msgstr "%s: Erreur GAS: insn PTB inattendue avec R_SH_PT_16"
+
+#: elf32-sh64.c:598
+msgid "%B: error: unaligned relocation type %d at %08x reloc %p\n"
+msgstr "%B: erreur: type de réadressage %d non aligné à %08x réadressé %p\n"
+
+#: elf32-sh64.c:674
+#, c-format
+msgid "%s: could not write out added .cranges entries"
+msgstr "%s: ne peut écrire en sortie des entrées .cranges ajoutées"
+
+#: elf32-sh64.c:734
+#, c-format
+msgid "%s: could not write out sorted .cranges entries"
+msgstr "%s: ne peut écrire en sortie des entrées .cranges triées"
+
+#: elf32-sparc.c:90
+msgid "%B: compiled for a 64 bit system and target is 32 bit"
+msgstr "%B: compilé pour un système à 64 bits et la cible est de 32 bits"
+
+#: elf32-sparc.c:103
+msgid "%B: linking little endian files with big endian files"
+msgstr "%B: édition de liens pour des fichiers à octets de poids faible avec des fichiers à octets de poids fort"
+
+#: elf32-spu.c:719
+msgid "%X%P: overlay section %A does not start on a cache line.\n"
+msgstr "%X%P: recouvrement de la section %A ne démarre pas sur une ligne de cache.\n"
+
+#: elf32-spu.c:727
+msgid "%X%P: overlay section %A is larger than a cache line.\n"
+msgstr "%X%P: recouvrement de la section %A est plus grand que la ligne de cache.\n"
+
+#: elf32-spu.c:747
+msgid "%X%P: overlay section %A is not in cache area.\n"
+msgstr "%X%P: recouvrement de la section %A n'est pas dans une zone de cache.\n"
+
+#: elf32-spu.c:787
+msgid "%X%P: overlay sections %A and %A do not start at the same address.\n"
+msgstr "%X%P: recouvrement des sections %A et %A ne commencent pas à la même adresse.\n"
+
+#: elf32-spu.c:1011
+msgid "warning: call to non-function symbol %s defined in %B"
+msgstr "attention: appel au symbole %s défini dans %B qui n'est pas une fonction"
+
+#: elf32-spu.c:1361
+msgid "%A:0x%v lrlive .brinfo (%u) differs from analysis (%u)\n"
+msgstr "%A:0x%v le lrlive .brinfo (%u) diffère de celui de l'analyse (%u)\n"
+
+#: elf32-spu.c:1880
+msgid "%B is not allowed to define %s"
+msgstr "%B ne peut pas définir %s"
+
+#: elf32-spu.c:1888
+#, c-format
+msgid "you are not allowed to define %s in a script"
+msgstr "vous ne pouvez pas définir %s dans un script"
+
+#: elf32-spu.c:1922
+#, c-format
+msgid "%s in overlay section"
+msgstr "%s dans une section de recouvrement"
+
+#: elf32-spu.c:1951
+msgid "overlay stub relocation overflow"
+msgstr "débordement du réadressage de l'ébauche de recouvrement"
+
+#: elf32-spu.c:1960
+msgid "stubs don't match calculated size"
+msgstr "taille des ébauches ne concorde pas avec la taille calculée"
+
+#: elf32-spu.c:2542
+#, c-format
+msgid "warning: %s overlaps %s\n"
+msgstr "attention: %s recouvre %s\n"
+
+#: elf32-spu.c:2558
+#, c-format
+msgid "warning: %s exceeds section size\n"
+msgstr "attention: %s dépasse la taille de la section\n"
+
+#: elf32-spu.c:2589
+msgid "%A:0x%v not found in function table\n"
+msgstr "%A:%0x%v pas trouvé dans la table de fonctions\n"
+
+#: elf32-spu.c:2729
+msgid "%B(%A+0x%v): call to non-code section %B(%A), analysis incomplete\n"
+msgstr "%B(%A+0x%v): appel à la section non exécutable %B(%A), analyse incomplète\n"
+
+#: elf32-spu.c:3297
+#, c-format
+msgid "Stack analysis will ignore the call from %s to %s\n"
+msgstr "L'analyse de la pile ignorera l'appel de %s à %s\n"
+
+#: elf32-spu.c:3988
+msgid " %s: 0x%v\n"
+msgstr " %s: 0x%v\n"
+
+#: elf32-spu.c:3989
+msgid "%s: 0x%v 0x%v\n"
+msgstr "%s: 0x%v 0x%v\n"
+
+#: elf32-spu.c:3994
+msgid " calls:\n"
+msgstr " appels:\n"
+
+#: elf32-spu.c:4002
+#, c-format
+msgid " %s%s %s\n"
+msgstr " %s%s %s\n"
+
+#: elf32-spu.c:4307
+#, c-format
+msgid "%s duplicated in %s\n"
+msgstr "%s dupliqué dans %s\n"
+
+#: elf32-spu.c:4311
+#, c-format
+msgid "%s duplicated\n"
+msgstr "%s dupliqué\n"
+
+#: elf32-spu.c:4318
+msgid "sorry, no support for duplicate object files in auto-overlay script\n"
+msgstr "désolé, pas de support des fichiers objet dupliqués dans un script auto-overlay\n"
+
+#: elf32-spu.c:4359
+msgid "non-overlay size of 0x%v plus maximum overlay size of 0x%v exceeds local store\n"
+msgstr "la taille de non recouvrement de 0x%v plus la taille maximum de recouvrement de 0x%v dépasse l'espace local\n"
+
+#: elf32-spu.c:4514
+msgid "%B:%A%s exceeds overlay size\n"
+msgstr "%B:%A%s dépasse la taille de recouvrement\n"
+
+#: elf32-spu.c:4676
+msgid "Stack size for call graph root nodes.\n"
+msgstr "Taille de la pile des nœuds racine du graph d'appel.\n"
+
+#: elf32-spu.c:4677
+msgid ""
+"\n"
+"Stack size for functions. Annotations: '*' max stack, 't' tail call\n"
+msgstr ""
+"\n"
+"Taille de la pile pour les fonctions. Annotations: «*» pile max, «t» appel de queue\n"
+
+#: elf32-spu.c:4687
+msgid "Maximum stack required is 0x%v\n"
+msgstr "Pile maximum requise est 0x%v\n"
+
+#: elf32-spu.c:4778
+msgid "fatal error while creating .fixup"
+msgstr "erreur fatale lors de la création de .fixup"
+
+#: elf32-spu.c:5008
+msgid "%B(%s+0x%lx): unresolvable %s relocation against symbol `%s'"
+msgstr "%B(%A+0x%lx): réadressage %s sans solution vers le symbole « %s »"
+
+#: elf32-tic6x.c:1602
+msgid "warning: generating a shared library containing non-PIC code"
+msgstr "attention: production d'une librairie partagée contenant du code non-PIC"
+
+#: elf32-tic6x.c:1607
+msgid "warning: generating a shared library containing non-PID code"
+msgstr "attention: production d'une librairie partagée contenant du code non-PID"
+
+#: elf32-tic6x.c:2541
+msgid "%B: SB-relative relocation but __c6xabi_DSBT_BASE not defined"
+msgstr "%B: réadressage relatif à SB mais __c6xabi_DSBT_BASE n'est pas défini"
+
+#: elf32-tic6x.c:2761
+msgid "dangerous relocation"
+msgstr "réadressage dangereux"
+
+#: elf32-tic6x.c:3733
+msgid "%B: error: unknown mandatory EABI object attribute %d"
+msgstr "%B: erreur: l'attribut d'objet EABI obligatoire %d est manquant"
+
+#: elf32-tic6x.c:3741
+msgid "%B: warning: unknown EABI object attribute %d"
+msgstr "%B: attention: attribut d'objet EABI %d inconnu"
+
+#: elf32-tic6x.c:3853 elf32-tic6x.c:3861
+msgid "error: %B requires more stack alignment than %B preserves"
+msgstr "erreur: %B nécessite un plus grand alignement de pile que ce que %B préserve"
+
+#: elf32-tic6x.c:3871 elf32-tic6x.c:3880
+msgid "error: unknown Tag_ABI_array_object_alignment value in %B"
+msgstr "erreur: valeur Tag_ABI_array_object_alignment inconnue dans %B"
+
+#: elf32-tic6x.c:3889 elf32-tic6x.c:3898
+msgid "error: unknown Tag_ABI_array_object_align_expected value in %B"
+msgstr "erreur: valeur Tag_ABI_array_object_align_expected inconnue dans %B"
+
+#: elf32-tic6x.c:3906 elf32-tic6x.c:3913
+msgid "error: %B requires more array alignment than %B preserves"
+msgstr "erreur: %B nécessite un plus grand alignement de tableau que ce que %B préserve"
+
+#: elf32-tic6x.c:3935
+msgid "warning: %B and %B differ in wchar_t size"
+msgstr "attention: %B et %B on des tailles de wchar_t différentes"
+
+#: elf32-tic6x.c:3953
+msgid "warning: %B and %B differ in whether code is compiled for DSBT"
+msgstr "attention: %B et %B ne sont pas d'accord sur la compilation du code pour DSBT"
+
+#: elf32-v850.c:173
+#, c-format
+msgid "Variable `%s' cannot occupy in multiple small data regions"
+msgstr "Variable «%s» ne peut occuper de multiples petites régions de données"
+
+#: elf32-v850.c:176
+#, c-format
+msgid "Variable `%s' can only be in one of the small, zero, and tiny data regions"
+msgstr "Variable «%s» peut seulement être dans une région de données petite, zéro ou minuscule"
+
+#: elf32-v850.c:179
+#, c-format
+msgid "Variable `%s' cannot be in both small and zero data regions simultaneously"
+msgstr "Variable «%s» ne peut être dans une région de données petite et zéro à la fois"
+
+#: elf32-v850.c:182
+#, c-format
+msgid "Variable `%s' cannot be in both small and tiny data regions simultaneously"
+msgstr "Variable «%s» ne peut être dans une région de données petite et minuscule à la fois"
+
+#: elf32-v850.c:185
+#, c-format
+msgid "Variable `%s' cannot be in both zero and tiny data regions simultaneously"
+msgstr "Variable «%s» ne peut être dans une région de données zéro et minuscule à la fois"
+
+#: elf32-v850.c:483
+msgid "FAILED to find previous HI16 reloc"
+msgstr "ÉCHEC de repérage du réadressage HI16 précédent"
+
+#: elf32-v850.c:2155
+msgid "could not locate special linker symbol __gp"
+msgstr "ne peut repérer le symbole spécial d'édition de lien __gp"
+
+#: elf32-v850.c:2159
+msgid "could not locate special linker symbol __ep"
+msgstr "ne peut repérer le symbole spécial d'édition de lien __ep"
+
+#: elf32-v850.c:2163
+msgid "could not locate special linker symbol __ctbp"
+msgstr "ne peut repérer le symbole spécial d'édition de lien __ctbp"
+
+#: elf32-v850.c:2341
+msgid "%B: Architecture mismatch with previous modules"
+msgstr "%B: L'architecture ne concorde pas avec les modules précédents"
+
+#. xgettext:c-format.
+#: elf32-v850.c:2360
+#, c-format
+msgid "private flags = %lx: "
+msgstr "fanions privés = %lx: "
+
+#: elf32-v850.c:2365
+#, c-format
+msgid "v850 architecture"
+msgstr "architecture v850"
+
+#: elf32-v850.c:2366
+#, c-format
+msgid "v850e architecture"
+msgstr "architecture v850e"
+
+#: elf32-v850.c:2367
+#, c-format
+msgid "v850e1 architecture"
+msgstr "architecture v850e1"
+
+#: elf32-v850.c:2368
+#, c-format
+msgid "v850e2 architecture"
+msgstr "architecture v850e2"
+
+#: elf32-v850.c:2369
+#, c-format
+msgid "v850e2v3 architecture"
+msgstr "architecture v850e2v3"
+
+#: elf32-vax.c:532
+#, c-format
+msgid " [nonpic]"
+msgstr " [nonpic]"
+
+#: elf32-vax.c:535
+#, c-format
+msgid " [d-float]"
+msgstr " [d-float]"
+
+#: elf32-vax.c:538
+#, c-format
+msgid " [g-float]"
+msgstr " [g-float]"
+
+#: elf32-vax.c:655
+#, c-format
+msgid "%s: warning: GOT addend of %ld to `%s' does not match previous GOT addend of %ld"
+msgstr "%s: attention: ajout GOT de %ld à «%s» ne concorde par avec l'ajout GOT précédent de %ld"
+
+#: elf32-vax.c:1585
+#, c-format
+msgid "%s: warning: PLT addend of %d to `%s' from %s section ignored"
+msgstr "%s: attention: ignore l'ajout PLT de %d à «%s» de la section %s"
+
+#: elf32-vax.c:1712
+#, c-format
+msgid "%s: warning: %s relocation against symbol `%s' from %s section"
+msgstr "%s: attention: réadressage %s vers le symbole « %s » de la section %s"
+
+#: elf32-vax.c:1718
+#, c-format
+msgid "%s: warning: %s relocation to 0x%x from %s section"
+msgstr "%s: attention: réadressage %s vers 0x%x de la section %s"
+
+#: elf32-xstormy16.c:451 elf32-ia64.c:2336 elf64-ia64.c:2336
+msgid "non-zero addend in @fptr reloc"
+msgstr "ajout non nul dans la relocalisation @fptr"
+
+#: elf32-xtensa.c:918
+msgid "%B(%A): invalid property table"
+msgstr "%B(%A): table de propriété invalide"
+
+#: elf32-xtensa.c:2777
+msgid "%B(%A+0x%lx): relocation offset out of range (size=0x%x)"
+msgstr "%B(%A+0x%lx): décalage de réadressage hors limite (taille=0x%x)"
+
+#: elf32-xtensa.c:2856 elf32-xtensa.c:2977
+msgid "dynamic relocation in read-only section"
+msgstr "réadressage dynamique dans une section en lecture seule"
+
+#: elf32-xtensa.c:2953
+msgid "TLS relocation invalid without dynamic sections"
+msgstr "réadressage TLS incorrecte sans section dynamique"
+
+#: elf32-xtensa.c:3172
+msgid "internal inconsistency in size of .got.loc section"
+msgstr "incohérence interne dans la taille de la section .got.loc"
+
+#: elf32-xtensa.c:3485
+msgid "%B: incompatible machine type. Output is 0x%x. Input is 0x%x"
+msgstr "%B: type de machine incompatible. Sortie est 0x%x. Entrée est 0x%x"
+
+#: elf32-xtensa.c:4714 elf32-xtensa.c:4722
+msgid "Attempt to convert L32R/CALLX to CALL failed"
+msgstr "Échec de la tentative de convertir L32R/CALLX en CALL"
+
+#: elf32-xtensa.c:6332 elf32-xtensa.c:6408 elf32-xtensa.c:7524
+msgid "%B(%A+0x%lx): could not decode instruction; possible configuration mismatch"
+msgstr "%B(%A+0x%lx): l'instruction ne peut pas être décodée; la configuration est peut-être erronée"
+
+#: elf32-xtensa.c:7264
+msgid "%B(%A+0x%lx): could not decode instruction for XTENSA_ASM_SIMPLIFY relocation; possible configuration mismatch"
+msgstr "%B(%A+0x%lx): l'instruction ne peut pas être décodée pour un réadressage XTENSA_ASM_SIMPLIFY; la configuration est peut-être erronée"
+
+#: elf32-xtensa.c:9023
+msgid "invalid relocation address"
+msgstr "adresse de réadressage incorrecte"
+
+#: elf32-xtensa.c:9072
+msgid "overflow after relaxation"
+msgstr "débordement après la relâche"
+
+#: elf32-xtensa.c:10204
+msgid "%B(%A+0x%lx): unexpected fix for %s relocation"
+msgstr "%B(%A+0x%lx): correction inattendue pour le réadressage %s"
+
+#: elf64-alpha.c:460
+msgid "GPDISP relocation did not find ldah and lda instructions"
+msgstr "le réadressage GPDISP n'a pas repéré les instructions ldah et lda"
+
+#: elf64-alpha.c:2497
+msgid "%B: .got subsegment exceeds 64K (size %d)"
+msgstr "%B: le sous-segment .got excède 64K (taille %d)"
+
+#: elf64-alpha.c:4387 elf64-alpha.c:4399
+msgid "%B: gp-relative relocation against dynamic symbol %s"
+msgstr "%B: réadressage relatif au gp vers le symbole dynamique %s"
+
+#: elf64-alpha.c:4425 elf64-alpha.c:4565
+msgid "%B: pc-relative relocation against dynamic symbol %s"
+msgstr "%B: réadressage relatif au PC vers le symbole dynamique %s"
+
+#: elf64-alpha.c:4453
+msgid "%B: change in gp: BRSGP %s"
+msgstr "%B: changé dans le GP: BRSGP %s"
+
+#: elf64-alpha.c:4478
+msgid "<unknown>"
+msgstr "<inconnu>"
+
+#: elf64-alpha.c:4483
+msgid "%B: !samegp reloc against symbol without .prologue: %s"
+msgstr "%B: relocalisation !samegp vers le symbole sans .prologue: %s"
+
+#: elf64-alpha.c:4540
+msgid "%B: unhandled dynamic relocation against %s"
+msgstr "%B: réadressage dynamique non traité vers %s"
+
+#: elf64-alpha.c:4572
+msgid "%B: pc-relative relocation against undefined weak symbol %s"
+msgstr "%B: réadressage relatif au PC vers le symbole faible non défini %s"
+
+#: elf64-alpha.c:4636
+msgid "%B: dtp-relative relocation against dynamic symbol %s"
+msgstr "%B: réadressage relatif au dtp vers le symbole dynamique %s"
+
+#: elf64-alpha.c:4659
+msgid "%B: tp-relative relocation against dynamic symbol %s"
+msgstr "%B: réadressage relatif au tp vers le symbole dynamique %s"
+
+#: elf64-hppa.c:2083
+#, c-format
+msgid "stub entry for %s cannot load .plt, dp offset = %ld"
+msgstr "entrée de l'ébauche pour %s ne peut charger .plt, décalage dp = %ld"
+
+#: elf64-hppa.c:3275
+msgid "%B(%A+0x"
+msgstr "%B(%A+0x"
+
+#: elf64-mmix.c:1034
+msgid ""
+"invalid input relocation when producing non-ELF, non-mmo format output.\n"
+" Please use the objcopy program to convert from ELF or mmo,\n"
+" or assemble using \"-no-expand\" (for gcc, \"-Wa,-no-expand\""
+msgstr ""
+"réadressage d'entrée invalide en produisant un format de sortie non ELF et non mmo.\n"
+" Veuillez utiliser le programme objcopy pour convertir de ELF ou mmo,\n"
+" ou assembler en utilisant « -no-expand » (pour gcc, « -Wa,-no-expand »"
+
+#: elf64-mmix.c:1218
+msgid ""
+"invalid input relocation when producing non-ELF, non-mmo format output.\n"
+" Please use the objcopy program to convert from ELF or mmo,\n"
+" or compile using the gcc-option \"-mno-base-addresses\"."
+msgstr ""
+"réadressage d'entrée invalide en produisant un format de sortie non ELF et non mmo.\n"
+" Veuillez utiliser le programme objcopy pour convertir de ELF ou mmo,\n"
+" ou compiler en utilisant l'option gcc « -mno-base-addresses »."
+
+#: elf64-mmix.c:1244
+#, c-format
+msgid ""
+"%s: Internal inconsistency error for value for\n"
+" linker-allocated global register: linked: 0x%lx%08lx != relaxed: 0x%lx%08lx\n"
+msgstr ""
+"%s: erreur d'incohérence interne pour la valeur du registre global\n"
+" alloué à l'édition de lien: lié: 0x%lx%08lx != relâché: 0x%lx%08lx\n"
+
+#: elf64-mmix.c:1670
+#, c-format
+msgid "%s: base-plus-offset relocation against register symbol: (unknown) in %s"
+msgstr "%s: réadressage base plus décalage vers le symbole registre: (inconnu) dans %s"
+
+#: elf64-mmix.c:1675
+#, c-format
+msgid "%s: base-plus-offset relocation against register symbol: %s in %s"
+msgstr "%s: réadressage base plus décalage vers le symbole registre: %s dans %s"
+
+#: elf64-mmix.c:1719
+#, c-format
+msgid "%s: register relocation against non-register symbol: (unknown) in %s"
+msgstr "%s: réadressage de registre vers le symbole non-registre: (inconnu) dans %s"
+
+#: elf64-mmix.c:1724
+#, c-format
+msgid "%s: register relocation against non-register symbol: %s in %s"
+msgstr "%s: réadressage de registre vers le symbole non-registre: %s dans %s"
+
+#: elf64-mmix.c:1761
+#, c-format
+msgid "%s: directive LOCAL valid only with a register or absolute value"
+msgstr "%s: directive LOCAL valide seulement avec un registre ou une valeur absolue"
+
+#: elf64-mmix.c:1789
+#, c-format
+msgid "%s: LOCAL directive: Register $%ld is not a local register. First global register is $%ld."
+msgstr "%s: directive LOCAL: registre $%ld n'est pas un registre local. Premier registre global est $%ld."
+
+#: elf64-mmix.c:2253
+#, c-format
+msgid "%s: Error: multiple definition of `%s'; start of %s is set in a earlier linked file\n"
+msgstr "%s: erreur: multiple définitions de «%s»; début de %s est initialisé dans un précédent fichier lié\n"
+
+#: elf64-mmix.c:2311
+msgid "Register section has contents\n"
+msgstr "Registre de section contient\n"
+
+#: elf64-mmix.c:2503
+#, c-format
+msgid ""
+"Internal inconsistency: remaining %u != max %u.\n"
+" Please report this bug."
+msgstr ""
+"Inconsistence interne: reste %u != max %u.\n"
+" Merci de rapporter cette anomalie."
+
+#: elf64-ppc.c:4185
+msgid "%P: %B: cannot create stub entry %s\n"
+msgstr "%P: %B: ne peut créer l'entrée de l'ébauche %s\n"
+
+#: elf64-ppc.c:6518
+msgid "%P: copy reloc against `%s' requires lazy plt linking; avoid setting LD_BIND_NOW=1 or upgrade gcc\n"
+msgstr "%P: la copie du réadressage sur « %s » nécessite un lien plt paresseux; évitez de mettre LD_BIND_NOW=1 ou mettez à jour gcc\n"
+
+#: elf64-ppc.c:6788
+msgid "%B: undefined symbol on R_PPC64_TOCSAVE relocation"
+msgstr "%B: symbole indéfini sur le réadressage R_PPC64_TOCSAVE"
+
+#: elf64-ppc.c:6992
+msgid "%P: dynreloc miscount for %B, section %A\n"
+msgstr "%P: erreur de décompte de réadressage dynamique pour %B, section %A\n"
+
+#: elf64-ppc.c:7076
+msgid "%B: .opd is not a regular array of opd entries"
+msgstr "%B: .opd n'est pas un tableau régulier d'entrées opd"
+
+#: elf64-ppc.c:7085
+msgid "%B: unexpected reloc type %u in .opd section"
+msgstr "%B: type de relocalisation %u inattendu dans la section .opd"
+
+#: elf64-ppc.c:7106
+msgid "%B: undefined sym `%s' in .opd section"
+msgstr "%B: symbole «%s» indéfini dans la section .opd"
+
+#: elf64-ppc.c:7664
+msgid "%H __tls_get_addr lost arg, TLS optimization disabled\n"
+msgstr "%H __tls_get_addr a perdu l'argument, optimisation TLS désactivée\n"
+
+#: elf64-ppc.c:8003 elf64-ppc.c:8564
+#, c-format
+msgid "%s defined on removed toc entry"
+msgstr "%s défini dans une entrée toc supprimée"
+
+#: elf64-ppc.c:8521
+msgid "%P: %H: %s relocation references optimized away TOC entry\n"
+msgstr "%P: %H: le réadressage %s fait référence à une entrée TOC supprimée par l'optimisation\n"
+
+#: elf64-ppc.c:9598
+msgid "%P: cannot find opd entry toc for %s\n"
+msgstr "%P: l'entrée toc de opd non trouvée pour %s\n"
+
+#: elf64-ppc.c:9680
+msgid "%P: long branch stub `%s' offset overflow\n"
+msgstr "%P: débordement de l'offset du branchement long de l'ébauche « %s »\n"
+
+#: elf64-ppc.c:9739
+msgid "%P: can't find branch stub `%s'\n"
+msgstr "%P: ne peut repérer l'ébauche de branchement « %s »\n"
+
+#: elf64-ppc.c:9801 elf64-ppc.c:9943
+msgid "%P: linkage table error against `%s'\n"
+msgstr "%P: erreur de la table de liaison vers « %s »\n"
+
+#: elf64-ppc.c:10126
+msgid "%P: can't build branch stub `%s'\n"
+msgstr "%P: ne peut construire l'ébauche de branchement « %s »\n"
+
+#: elf64-ppc.c:10941
+msgid "%B section %A exceeds stub group size"
+msgstr "%B section %A dépasse la taille du groupe d'ébauche"
+
+#: elf64-ppc.c:11666 elf64-ppc.c:11699
+msgid "%P: %s offset too large for .eh_frame sdata4 encoding"
+msgstr "%P: décalage %s trop grand pour l'encodage .eh_frame sdata4"
+
+#: elf64-ppc.c:11744
+msgid "%P: stubs don't match calculated size\n"
+msgstr "%P: taille des ébauches ne concorde pas avec la taille calculée\n"
+
+#: elf64-ppc.c:11756
+#, c-format
+msgid ""
+"linker stubs in %u group%s\n"
+" branch %lu\n"
+" toc adjust %lu\n"
+" long branch %lu\n"
+" long toc adj %lu\n"
+" plt call %lu"
+msgstr ""
+"éditeur de liens des ébauches dans %u groupe%s\n"
+" branchements %lu\n"
+" ajustements toc %lu\n"
+" long branchements %lu\n"
+" long ajustements toc %lu\n"
+" appels plt %lu"
+
+#: elf64-ppc.c:12042
+msgid "%P: %H: %s used with TLS symbol %s\n"
+msgstr "%P: %H: %s utilisé avec le symbole TLS %s\n"
+
+#: elf64-ppc.c:12043
+msgid "%P: %H: %s used with non-TLS symbol %s\n"
+msgstr "%P: %H: %s utilisé avec le symbole non-TLS %s\n"
+
+#: elf64-ppc.c:12556
+msgid "%P: %H: automatic multiple TOCs not supported using your crt files; recompile with -mminimal-toc or upgrade gcc\n"
+msgstr "%P: %H: TOC multiples et automatiques non supportées utilisant votre fichier crt; recompilez avec -mminimal-toc ou mettez à jour gcc\n"
+
+#: elf64-ppc.c:12562
+msgid "%P: %H: sibling call optimization to `%s' does not allow automatic multiple TOCs; recompile with -mminimal-toc or -fno-optimize-sibling-calls, or make `%s' extern\n"
+msgstr "%P: %H: l'optimisation sœurs des appels vers « %s » n'autorise pas de TOC multiples et automatiques; recompilez avec -mminimal-toc ou -fno-optimize-sibling-calls, ou rendez « %s » externe\n"
+
+#: elf64-ppc.c:13286
+msgid "%P: %B: relocation %s is not supported for symbol %s\n"
+msgstr "%P: %B: réadressage %s n'est pas supportée pour le symbole %s\n"
+
+#: elf64-ppc.c:13446
+msgid "%P: %H: error: %s not a multiple of %u\n"
+msgstr "%P: %H: erreur: %s n'est pas un multiple de %u\n"
+
+#: elf64-sh64.c:1686
+#, c-format
+msgid "%s: error: unaligned relocation type %d at %08x reloc %08x\n"
+msgstr "%s: erreur: type de réadressage %d non aligné à %08x réadressé`%08x\n"
+
+#: elf64-sparc.c:446
+msgid "%B: Only registers %%g[2367] can be declared using STT_REGISTER"
+msgstr "%B: Seuls les registres %%g[2367] peuvent être déclarés en utilisant les registres STT_REGISTER"
+
+#: elf64-sparc.c:466
+msgid "Register %%g%d used incompatibly: %s in %B, previously %s in %B"
+msgstr "Registre %%g%d utilisé de manière incompatible: %s dans %B précédemment %s dans %B"
+
+#: elf64-sparc.c:489
+msgid "Symbol `%s' has differing types: REGISTER in %B, previously %s in %B"
+msgstr "Symbole «%s» a des types qui diffèrent: REGISTRE dans %B, précédemment %s dans %B"
+
+#: elf64-sparc.c:534
+msgid "Symbol `%s' has differing types: %s in %B, previously REGISTER in %B"
+msgstr "Symbole «%s» a des types qui diffèrent: %s dans %B, précédemment REGISTRE dans %B"
+
+#: elf64-sparc.c:687
+msgid "%B: linking UltraSPARC specific with HAL specific code"
+msgstr "%B: édition de liens spécifiques pour UltraSPARC avec du code spécifique HAL"
+
+#: elf64-x86-64.c:1427
+msgid "%B: relocation %s against symbol `%s' isn't supported in x32 mode"
+msgstr "%B: le réadressage %s sur le symbole « %s » n'est pas supporté en mode x32"
+
+#: elf64-x86-64.c:1656
+msgid "%B: '%s' accessed both as normal and thread local symbol"
+msgstr "%B: symbole «%s» accédé à la fois comme normal et comme local au thread"
+
+#: elf64-x86-64.c:3150
+msgid "%B: relocation %s against STT_GNU_IFUNC symbol `%s' has non-zero addend: %d"
+msgstr "%B: le réadressage %s vers le symbole STT_GNU_IFUNC « %s » a l'opérande non nul: %d"
+
+#: elf64-x86-64.c:3411
+msgid "%B: relocation R_X86_64_GOTOFF64 against protected function `%s' can not be used when making a shared object"
+msgstr "%B: réadressage R_X86_64_GOTOFF64 vers la fonction protégée « %s » ne peut pas être utilisé lors de la création d'un objet partagé"
+
+#: elf64-x86-64.c:3523
+msgid "; recompile with -fPIC"
+msgstr "; recompilé avec -fPIC"
+
+#: elf64-x86-64.c:3528
+msgid "%B: relocation %s against %s `%s' can not be used when making a shared object%s"
+msgstr "%B: réadressage %s vers %s « %s » ne peut pas être utilisé en créant un objet partagé %s"
+
+#: elf64-x86-64.c:3530
+msgid "%B: relocation %s against undefined %s `%s' can not be used when making a shared object%s"
+msgstr "%B: réadressage %s vers le %s non défini « %s » ne peut pas être utilisé en créant un objet partagé %s"
+
+#: elfcode.h:767
+#, c-format
+msgid "warning: %s has a corrupt string table index - ignoring"
+msgstr "attention: %s a un index de table de chaînes corrompu - ignoré"
+
+#: elfcode.h:1177
+#, c-format
+msgid "%s: version count (%ld) does not match symbol count (%ld)"
+msgstr "%s: compteur de version (%ld) ne concorde pas avec le symbole du compteur (%ld)"
+
+#: elfcode.h:1431
+#, c-format
+msgid "%s(%s): relocation %d has invalid symbol index %ld"
+msgstr "%s(%s): réadressage %d a un index de symbole %ld invalide"
+
+#: elfcore.h:312
+msgid "Warning: %B is truncated: expected core file size >= %lu, found: %lu."
+msgstr "Attention: %B est tronqué: taille attendue du cœur du fichier >= %lu, obtenu: %lu."
+
+#: elflink.c:1117
+msgid "%s: TLS definition in %B section %A mismatches non-TLS definition in %B section %A"
+msgstr "%s: définition TLS dans %B section %A ne correspond pas à la définition non TLS dans %B section %A"
+
+#: elflink.c:1121
+msgid "%s: TLS reference in %B mismatches non-TLS reference in %B"
+msgstr "%s: référence TLS dans %B ne correspond pas à la référence non TLS dans %B"
+
+#: elflink.c:1125
+msgid "%s: TLS definition in %B section %A mismatches non-TLS reference in %B"
+msgstr "%s: définition TLS dans %B section %A ne correspond pas à la référence TLS dans %B"
+
+#: elflink.c:1129
+msgid "%s: TLS reference in %B mismatches non-TLS definition in %B section %A"
+msgstr "%s: référence TLS dans %B ne correspond pas à la définition non TLS dans %B section %A"
+
+#: elflink.c:1762
+msgid "%B: unexpected redefinition of indirect versioned symbol `%s'"
+msgstr "%B: attention: redéfinition inattendue du symbole indirect avec version «%s»"
+
+#: elflink.c:2063
+msgid "%B: version node not found for symbol %s"
+msgstr "%B: version du nœud pas trouvée pour le symbole %s"
+
+#: elflink.c:2154
+msgid "%B: bad reloc symbol index (0x%lx >= 0x%lx) for offset 0x%lx in section `%A'"
+msgstr "%B: mauvais index de relocalisation du symbole (0x%lx >= 0x%lx) pour l'offset 0x%lx de la section «%A»"
+
+#: elflink.c:2165
+msgid "%B: non-zero symbol index (0x%lx) for offset 0x%lx in section `%A' when the object file has no symbol table"
+msgstr "%B: index de symbole non nul (0x%lx) pour l'offset 0x%lx de la section «%A» quand le fichier objet n'a pas de table de symboles"
+
+#: elflink.c:2355
+msgid "%B: relocation size mismatch in %B section %A"
+msgstr "%B: taille du réadressage ne concorde pas dans %B section %A"
+
+#: elflink.c:2639
+#, c-format
+msgid "warning: type and size of dynamic symbol `%s' are not defined"
+msgstr "attention: type et taille du symbole dynamique «%s» ne sont pas définis"
+
+#: elflink.c:3391
+msgid "%P: alternate ELF machine code found (%d) in %B, expecting %d\n"
+msgstr "%P: code machine ELF alternatif trouvé (%d) dans %B, %d est attendu\n"
+
+#: elflink.c:4037
+msgid "%B: %s: invalid version %u (max %d)"
+msgstr "%B: %s: version invalide %u (max %d)"
+
+#: elflink.c:4073
+msgid "%B: %s: invalid needed version %d"
+msgstr "%B: %s: version requise invalide %d"
+
+#: elflink.c:4269
+msgid "Warning: alignment %u of common symbol `%s' in %B is greater than the alignment (%u) of its section %A"
+msgstr "Attention: alignement %u du symbole commun «%s» dans %B est plus grand que l'alignement (%u) de sa section %A"
+
+#: elflink.c:4275
+msgid "Warning: alignment %u of symbol `%s' in %B is smaller than %u in %B"
+msgstr "Attention: alignement %u du symbole «%s» dans %B est plus petit que %u dans %B"
+
+#: elflink.c:4290
+msgid "Warning: size of symbol `%s' changed from %lu in %B to %lu in %B"
+msgstr "Attention: taille du symbole «%s» a changé de %lu dans %B à %lu dans %B"
+
+#: elflink.c:4463
+msgid "%B: undefined reference to symbol '%s'"
+msgstr "%B: référence au symbole non défini «%s»"
+
+#: elflink.c:4466
+msgid "note: '%s' is defined in DSO %B so try adding it to the linker command line"
+msgstr "note: «%s» est défini dans le DSO %B donc essayez de l'ajouter à la ligne de commande du lieur"
+
+#: elflink.c:5781
+#, c-format
+msgid "%s: undefined version: %s"
+msgstr "%s: version non définie: %s"
+
+#: elflink.c:5849
+msgid "%B: .preinit_array section is not allowed in DSO"
+msgstr "%B: section .preinit_array n'est pas permise dans DSO"
+
+#: elflink.c:7604
+#, c-format
+msgid "undefined %s reference in complex symbol: %s"
+msgstr "référence %s non définie dans le symbole complexe: %s"
+
+#: elflink.c:7758
+#, c-format
+msgid "unknown operator '%c' in complex symbol"
+msgstr "opérateur «%c» inconnu dans le symbole complexe"
+
+#: elflink.c:8097 elflink.c:8114 elflink.c:8151 elflink.c:8168
+msgid "%B: Unable to sort relocs - they are in more than one size"
+msgstr "%B: Impossible de trier les relocalisations - plusieurs tailles rencontrées"
+
+#: elflink.c:8128 elflink.c:8182
+msgid "%B: Unable to sort relocs - they are of an unknown size"
+msgstr "%B: Impossible de trier les relocalisations - leur taille est inconnue"
+
+#: elflink.c:8233
+msgid "Not enough memory to sort relocations"
+msgstr "Pas assez de mémoire pour trier les réadressages"
+
+#: elflink.c:8426
+msgid "%B: Too many sections: %d (>= %d)"
+msgstr "%B: Trop de sections: %d (>= %d)"
+
+#: elflink.c:8675
+msgid "%B: internal symbol `%s' in %B is referenced by DSO"
+msgstr "%B: symbole interne « %s » dans %B est référencé par DSO"
+
+#: elflink.c:8677
+msgid "%B: hidden symbol `%s' in %B is referenced by DSO"
+msgstr "%B: symbole caché « %s » dans %B est référencé par DSO"
+
+#: elflink.c:8679
+msgid "%B: local symbol `%s' in %B is referenced by DSO"
+msgstr "%B: symbole local « %s » dans %B est référencé par DSO"
+
+#: elflink.c:8776
+msgid "%B: could not find output section %A for input section %A"
+msgstr "%B: ne peut repérer la section de sortie %A pour la section d'entrée %A"
+
+#: elflink.c:8899
+msgid "%B: protected symbol `%s' isn't defined"
+msgstr "%B: symbole protégé « %s » n'est pas défini"
+
+#: elflink.c:8901
+msgid "%B: internal symbol `%s' isn't defined"
+msgstr "%B: symbole interne « %s » n'est pas défini"
+
+#: elflink.c:8903
+msgid "%B: hidden symbol `%s' isn't defined"
+msgstr "%B: symbole caché « %s » n'est pas défini"
+
+#: elflink.c:9432
+msgid "error: %B: size of section %A is not multiple of address size"
+msgstr "erreur: %B: le réadressage de la section %A n'est pas un multiple de la taille des adresses"
+
+#: elflink.c:9479
+msgid "error: %B contains a reloc (0x%s) for section %A that references a non-existent global symbol"
+msgstr "erreur: %B contient une relocalisation (0x%s) pour la section %A qui fait référence à un symbole global inexistant"
+
+#: elflink.c:10214
+msgid "%A has both ordered [`%A' in %B] and unordered [`%A' in %B] sections"
+msgstr "%A a, à la fois, des sections ordonnées [«%A» dans %B] et désordonnées [«%A» dans %B]"
+
+#: elflink.c:10219
+#, c-format
+msgid "%A has both ordered and unordered sections"
+msgstr "%A a, à la fois, des sections ordonnées et désordonnées"
+
+#: elflink.c:10784
+msgid "%B: file class %s incompatible with %s"
+msgstr "%B: classe de fichier %s incompatible avec %s"
+
+#: elflink.c:11093 elflink.c:11137
+msgid "%B: could not find output section %s"
+msgstr "%B: ne peut repérer la section de sortie %s"
+
+#: elflink.c:11098
+#, c-format
+msgid "warning: %s section has zero size"
+msgstr "attention: section %s a une taille nulle"
+
+#: elflink.c:11143
+#, c-format
+msgid "warning: section '%s' is being made into a note"
+msgstr "attention: section « %s » changé en une note"
+
+#: elflink.c:11212
+msgid "%P%X: read-only segment has dynamic relocations.\n"
+msgstr "%P%X: segment en lecture seule a des réadressages dynamiques.\n"
+
+#: elflink.c:11215
+msgid "%P: warning: creating a DT_TEXTREL in a shared object.\n"
+msgstr "%P: attention: création d'un DT_TEXTREL dans un objet partagé.\n"
+
+#: elflink.c:11402
+msgid "%P%X: can not read symbols: %E\n"
+msgstr "%P%X: ne peut pas lire les symboles: %E\n"
+
+#: elflink.c:11792
+msgid "Removing unused section '%s' in file '%B'"
+msgstr "Suppression de la section inutilisée «%s» dans le fichier «%B»"
+
+#: elflink.c:11998
+msgid "Warning: gc-sections option ignored"
+msgstr "Attention: l'option de la section gc est ignorée"
+
+#: elflink.c:12277
+#, c-format
+msgid "Unrecognized INPUT_SECTION_FLAG %s\n"
+msgstr "INPUT_SECTION_FLAG %s non reconnu\n"
+
+#: elfxx-mips.c:1234
+msgid "static procedure (no name)"
+msgstr "procédure statique (sans name)"
+
+#: elfxx-mips.c:5259
+msgid "MIPS16 and microMIPS functions cannot call each other"
+msgstr "Des fonctions MIPS16 et microMIPS ne peuvent pas s'appeler l'une l'autre"
+
+#: elfxx-mips.c:5856
+msgid "%B: %A+0x%lx: Direct jumps between ISA modes are not allowed; consider recompiling with interlinking enabled."
+msgstr "%B: %A+0x%lx: Les sauts directs entre modes ISA ne sont pas permis; envisagez de recompiler avec l'interliage activé."
+
+#: elfxx-mips.c:6519 elfxx-mips.c:6742
+msgid "%B: Warning: bad `%s' option size %u smaller than its header"
+msgstr "%B: Attention: mauvaise «%s» taille d'option %u plus petite que son en-tête"
+
+#: elfxx-mips.c:7495 elfxx-mips.c:7620
+msgid "%B: Warning: cannot determine the target function for stub section `%s'"
+msgstr "%B: Attention: ne peut pas déterminer la fonction cible de la section d'ébauche «%s»"
+
+#: elfxx-mips.c:7749
+msgid "%B: Malformed reloc detected for section %s"
+msgstr "%B: relocalisation mal composée détectée dans la section %s"
+
+#: elfxx-mips.c:7801
+msgid "%B: GOT reloc at 0x%lx not expected in executables"
+msgstr "%B: relocalisation GOT à 0x%lx pas attendue dans les executables"
+
+#: elfxx-mips.c:7930
+msgid "%B: CALL16 reloc at 0x%lx not against global symbol"
+msgstr "%B: appel CALL16 de relocalisation à 0x%lx qui n'est pas pour un symbole global"
+
+#: elfxx-mips.c:8645
+#, c-format
+msgid "non-dynamic relocations refer to dynamic symbol %s"
+msgstr "réadressages non dynamiques font référence au symbole dynamique %s"
+
+#: elfxx-mips.c:9347
+msgid "%B: Can't find matching LO16 reloc against `%s' for %s at 0x%lx in section `%A'"
+msgstr "%B: Ne trouve pas de relocalisation LO16 correspondante vers «%s» pour %s à 0x%lx de la section «%A»"
+
+#: elfxx-mips.c:9486
+msgid "small-data section exceeds 64KB; lower small-data size limit (see option -G)"
+msgstr "la taille des petites données de la section dépasse 64KB; abaissez la limite de taille des petites données (voyez l'option -G)"
+
+#: elfxx-mips.c:9505
+msgid "JALX to a non-word-aligned address"
+msgstr "JALX vers une adresse non alignée sur un mot"
+
+#: elfxx-mips.c:13266
+#, c-format
+msgid "%s: illegal section name `%s'"
+msgstr "%s: nom illégal de section «%s»"
+
+#: elfxx-mips.c:13645 elfxx-mips.c:13671
+msgid "Warning: %B uses -msingle-float, %B uses -mdouble-float"
+msgstr "Attention: %B utilise -msingle-float, %B utilise -mdouble-float"
+
+#: elfxx-mips.c:13657 elfxx-mips.c:13713
+msgid "Warning: %B uses -msingle-float, %B uses -mips32r2 -mfp64"
+msgstr "Attention: %B utilise -msingle-float, %B utilise -mips32r2 -mfp64"
+
+#: elfxx-mips.c:13683 elfxx-mips.c:13719
+msgid "Warning: %B uses -mdouble-float, %B uses -mips32r2 -mfp64"
+msgstr "Attention: %B utilise -mdouble-float, %B utilise -mips32r2 -mfp64"
+
+#: elfxx-mips.c:13761
+msgid "%B: endianness incompatible with that of the selected emulation"
+msgstr "%B: système de poids fort ou faible incompatible avec celui sélectionné pour l'émulation"
+
+#: elfxx-mips.c:13772
+msgid "%B: ABI is incompatible with that of the selected emulation"
+msgstr "%B: ABI est incompatible avec celui sélectionné pour l'émulation"
+
+#: elfxx-mips.c:13856
+msgid "%B: warning: linking abicalls files with non-abicalls files"
+msgstr "%B: attention: édition de liens des fichiers abicalls avec des fichiers non abicalls"
+
+#: elfxx-mips.c:13873
+msgid "%B: linking 32-bit code with 64-bit code"
+msgstr "%B: édition de liens de code 32 bits avec du code 64 bits"
+
+#: elfxx-mips.c:13901
+msgid "%B: linking %s module with previous %s modules"
+msgstr "%B: édition de liens du module %s avec les modules précédents %s"
+
+#: elfxx-mips.c:13924
+msgid "%B: ABI mismatch: linking %s module with previous %s modules"
+msgstr "%B: ABI ne concorde pas: édition de lien du module %s avec les modules précédents %s"
+
+#: elfxx-mips.c:13948
+msgid "%B: ASE mismatch: linking %s module with previous %s modules"
+msgstr "%B: ASE ne concorde pas: édition de lien du module %s avec les modules précédents %s"
+
+#: elfxx-mips.c:14106
+#, c-format
+msgid " [abi=O32]"
+msgstr " [abi=O32]"
+
+#: elfxx-mips.c:14108
+#, c-format
+msgid " [abi=O64]"
+msgstr " [abi=O64]"
+
+#: elfxx-mips.c:14110
+#, c-format
+msgid " [abi=EABI32]"
+msgstr " [abi=EABI32]"
+
+#: elfxx-mips.c:14112
+#, c-format
+msgid " [abi=EABI64]"
+msgstr " [abi=EABI64]"
+
+#: elfxx-mips.c:14114
+#, c-format
+msgid " [abi unknown]"
+msgstr " [abi inconnu]"
+
+#: elfxx-mips.c:14116
+#, c-format
+msgid " [abi=N32]"
+msgstr " [abi=N32]"
+
+#: elfxx-mips.c:14118
+#, c-format
+msgid " [abi=64]"
+msgstr " [abi=64]"
+
+#: elfxx-mips.c:14120
+#, c-format
+msgid " [no abi set]"
+msgstr " [aucun jeu abi]"
+
+#: elfxx-mips.c:14141
+#, c-format
+msgid " [unknown ISA]"
+msgstr " [ISA inconnu]"
+
+#: elfxx-mips.c:14155
+#, c-format
+msgid " [not 32bitmode]"
+msgstr " [aucun mode 32 bits]"
+
+#: elfxx-sparc.c:596
+#, c-format
+msgid "invalid relocation type %d"
+msgstr "type de réadressage %d invalide"
+
+#: elfxx-tilegx.c:3952
+msgid "%B: Cannot link together %s and %s objects."
+msgstr "%B: Ne peut lier ensemble les objets %s et %s."
+
+#: i386linux.c:451 m68klinux.c:456 sparclinux.c:450
+#, c-format
+msgid "Output file requires shared library `%s'\n"
+msgstr "La sortie requiert la librairie partagée «%s»\n"
+
+#: i386linux.c:459 m68klinux.c:464 sparclinux.c:458
+#, c-format
+msgid "Output file requires shared library `%s.so.%s'\n"
+msgstr "Le fichier de sortie requiert une librairie partagée «%s.so.%s»\n"
+
+#: i386linux.c:648 i386linux.c:698 m68klinux.c:656 m68klinux.c:704
+#: sparclinux.c:648 sparclinux.c:698
+#, c-format
+msgid "Symbol %s not defined for fixups\n"
+msgstr "Symbole %s n'est pas défini pour les corrections\n"
+
+#: i386linux.c:722 m68klinux.c:728 sparclinux.c:722
+msgid "Warning: fixup count mismatch\n"
+msgstr "Attention: nombre de corrections en désaccord\n"
+
+#: ieee.c:159
+#, c-format
+msgid "%s: string too long (%d chars, max 65535)"
+msgstr "%s: chaîne trop longue (%d caractères, max 65535)"
+
+#: ieee.c:286
+#, c-format
+msgid "%s: unrecognized symbol `%s' flags 0x%x"
+msgstr "%s: symbole non reconnue «%s» fanions 0x%x"
+
+#: ieee.c:792
+msgid "%B: unimplemented ATI record %u for symbol %u"
+msgstr "%B: enregistrement ATI non implanté %u pour le symbole %u"
+
+#: ieee.c:816
+msgid "%B: unexpected ATN type %d in external part"
+msgstr "%B: type ATN %d inattendu dans la partie externe"
+
+#: ieee.c:838
+msgid "%B: unexpected type after ATN"
+msgstr "%B: type inattendu après ATN"
+
+#: ihex.c:230
+msgid "%B:%d: unexpected character `%s' in Intel Hex file"
+msgstr "%B:%d: caractère inattendu «%s» dans le fichier Intel hexadécimal"
+
+#: ihex.c:337
+msgid "%B:%u: bad checksum in Intel Hex file (expected %u, found %u)"
+msgstr "%B:%u: somme de contrôle erronée dans le fichier Intel hexadécimal (attendu %u, obtenu %u)"
+
+#: ihex.c:392
+msgid "%B:%u: bad extended address record length in Intel Hex file"
+msgstr "%B:%u: longueur erronée de l'enregistrement d'adresse étendue dans le fichier Intel hexadécimal"
+
+#: ihex.c:409
+msgid "%B:%u: bad extended start address length in Intel Hex file"
+msgstr "%B:%u: longueur erronée d'adresse étendue de début dans le fichier Intel hexadécimal"
+
+#: ihex.c:426
+msgid "%B:%u: bad extended linear address record length in Intel Hex file"
+msgstr "%B:%u: longueur erronée de l'enregistrement d'adresse étendue linéaire dans le fichier Intel hexadécimal"
+
+#: ihex.c:443
+msgid "%B:%u: bad extended linear start address length in Intel Hex file"
+msgstr "%B:%u: longueur erronée d'adresse étendue linéraire de début dans le fichier Intel hexadécimal"
+
+#: ihex.c:460
+msgid "%B:%u: unrecognized ihex type %u in Intel Hex file"
+msgstr "%B:%u: type ihex %u non reconnu dans le fichier Intel hexadécima"
+
+#: ihex.c:579
+msgid "%B: internal error in ihex_read_section"
+msgstr "%B: erreur interne dans ihex_read_section"
+
+#: ihex.c:613
+msgid "%B: bad section length in ihex_read_section"
+msgstr "%B: longuer erronée de section dans ihex_read_section"
+
+#: ihex.c:826
+#, c-format
+msgid "%s: address 0x%s out of range for Intel Hex file"
+msgstr "%s: adresse 0x%s hors limite pour le fichier Intel hexadécimal"
+
+#: libbfd.c:863
+msgid "%B: unable to get decompressed section %A"
+msgstr "%B: impossible d'obtenir la section décompressée %A"
+
+#: libbfd.c:1012
+msgid "%B: compiled for a big endian system and target is little endian"
+msgstr ""
+"%B: compilé pour un système à octets de poids fort alors que la cible\n"
+"est un système à octets de poids faible"
+
+#: libbfd.c:1014
+msgid "%B: compiled for a little endian system and target is big endian"
+msgstr ""
+"%B: compilé pour un système à octets de poids faible alors que la cible\n"
+"est un système à octets de poids fort"
+
+#: libbfd.c:1043
+#, c-format
+msgid "Deprecated %s called at %s line %d in %s\n"
+msgstr "%s déprécié appelé à %s dans la ligne %d dans %s\n"
+
+#: libbfd.c:1046
+#, c-format
+msgid "Deprecated %s called\n"
+msgstr "%s appel déprécié\n"
+
+#: linker.c:1872
+msgid "%B: indirect symbol `%s' to `%s' is a loop"
+msgstr "%B: symbole indirect «%s» vers «%s» est une boucle"
+
+#: linker.c:2736
+#, c-format
+msgid "Attempt to do relocatable link with %s input and %s output"
+msgstr "Tentative de relocalisation d'un lien avec %s à l'entrée et %s à la sortie"
+
+#: linker.c:3021
+msgid "%B: ignoring duplicate section `%A'\n"
+msgstr "%B: ignore les sections dupliquées « %A »\n"
+
+#: linker.c:3030 linker.c:3039
+msgid "%B: duplicate section `%A' has different size\n"
+msgstr "%B: section dupliquée « %A » avec des tailles différentes\n"
+
+#: linker.c:3047 linker.c:3052
+msgid "%B: could not read contents of section `%A'\n"
+msgstr "%B: ne peut pas lire le contenu de la section « %A »\n"
+
+#: linker.c:3056
+msgid "%B: duplicate section `%A' has different contents\n"
+msgstr "%B: section dupliquée « %A » a des contenus différents\n"
+
+#: mach-o.c:407
+msgid "bfd_mach_o_canonicalize_symtab: unable to load symbols"
+msgstr "bfd_mach_o_canonicalize_symtab: impossible de charger les symboles"
+
+#: mach-o.c:1301
+#, c-format
+msgid "unable to write unknown load command 0x%lx"
+msgstr "impossible d'écrire la commande de chargement inconnue 0x%lx"
+
+#: mach-o.c:1789
+#, c-format
+msgid "bfd_mach_o_read_symtab_symbol: unable to read %d bytes at %lu"
+msgstr "bfd_mach_o_read_symtab_symbol: impossible de lire %d octets à %lu"
+
+#: mach-o.c:1807
+#, c-format
+msgid "bfd_mach_o_read_symtab_symbol: name out of range (%lu >= %lu)"
+msgstr "bfd_mach_o_read_symtab_symbol: nom hors limites (%lu >= %lu)"
+
+#: mach-o.c:1892
+#, c-format
+msgid "bfd_mach_o_read_symtab_symbol: symbol \"%s\" specified invalid section %d (max %lu): setting to undefined"
+msgstr "bfd_mach_o_read_symtab_symbol: le symbole « %s » spécifie la section %d invalide (max %lu): laissé non défini"
+
+#: mach-o.c:1900
+#, c-format
+msgid "bfd_mach_o_read_symtab_symbol: symbol \"%s\" is unsupported 'indirect' reference: setting to undefined"
+msgstr "bfd_mach_o_read_symtab_symbol: symbole « %s » a la référence non supportée « indirect »: laissé non défini"
+
+#: mach-o.c:1906
+#, c-format
+msgid "bfd_mach_o_read_symtab_symbol: symbol \"%s\" specified invalid type field 0x%x: setting to undefined"
+msgstr "bfd_mach_o_read_symtab_symbol: symbole « %s » spécifie le champ de type 0x%x invalide: laissé non défini"
+
+#: mach-o.c:1979
+msgid "bfd_mach_o_read_symtab_symbols: unable to allocate memory for symbols"
+msgstr "bfd_mach_o_read_symtab_symbols: impossible d'allouer la mémoire pour les symboles"
+
+#: mach-o.c:2014
+#, c-format
+msgid "bfd_mach_o_read_dysymtab_symbol: unable to read %lu bytes at %lu"
+msgstr "bfd_mach_o_read_dysymtab_symbol: impossible de lire %lu octets à %lu"
+
+#: mach-o.c:2734
+#, c-format
+msgid "unable to read unknown load command 0x%lx"
+msgstr "impossible de lire la commande de chargement inconnue 0x%lx"
+
+#: mach-o.c:2915
+#, c-format
+msgid "bfd_mach_o_scan: unknown architecture 0x%lx/0x%lx"
+msgstr "bfd_mach_o_scan: architecture 0x%lx/0x%lx inconnue"
+
+#: mach-o.c:3011
+#, c-format
+msgid "unknown header byte-order value 0x%lx"
+msgstr "valeur d'ordre des octets de l'en-tête 0x%lx est inconnue"
+
+#: mach-o.c:3577
+msgid "Mach-O header:\n"
+msgstr "En-tête Mach-O:\n"
+
+#: mach-o.c:3578
+#, c-format
+msgid " magic : %08lx\n"
+msgstr " magique : %08lx\n"
+
+#: mach-o.c:3579
+#, c-format
+msgid " cputype : %08lx (%s)\n"
+msgstr " typecpu : %08lx (%s)\n"
+
+#: mach-o.c:3581
+#, c-format
+msgid " cpusubtype: %08lx\n"
+msgstr " soustypecpu: %08lx\n"
+
+#: mach-o.c:3582
+#, c-format
+msgid " filetype : %08lx (%s)\n"
+msgstr " typefichier: %08lx (%s)\n"
+
+#: mach-o.c:3585
+#, c-format
+msgid " ncmds : %08lx (%lu)\n"
+msgstr " ncmds : %08lx (%lu)\n"
+
+#: mach-o.c:3586
+#, c-format
+msgid " sizeofcmds: %08lx\n"
+msgstr " taillecmds: %08lx\n"
+
+#: mach-o.c:3587
+#, c-format
+msgid " flags : %08lx ("
+msgstr " fanions : %08lx ("
+
+#: mach-o.c:3589 vms-alpha.c:7674
+msgid ")\n"
+msgstr ")\n"
+
+#: mach-o.c:3590
+#, c-format
+msgid " reserved : %08x\n"
+msgstr " réservé : %08x\n"
+
+#: mach-o.c:3600
+msgid "Segments and Sections:\n"
+msgstr "Segments et Sections:\n"
+
+#: mach-o.c:3601
+msgid " #: Segment name Section name Address\n"
+msgstr " #: Nom segment Nom section Adresse\n"
+
+#: merge.c:832
+#, c-format
+msgid "%s: access beyond end of merged section (%ld)"
+msgstr "%s: accès au-delà de la fin de la section fusionnée (%ld)"
+
+#: mmo.c:456
+#, c-format
+msgid "%s: No core to allocate section name %s\n"
+msgstr "%s: pas de corps pour allouer un nom de section %s\n"
+
+#: mmo.c:531
+#, c-format
+msgid "%s: No core to allocate a symbol %d bytes long\n"
+msgstr "%s: pas de corps pour allouer un symbole de %d octets de longueur\n"
+
+#: mmo.c:1187
+#, c-format
+msgid "%s: invalid mmo file: initialization value for $255 is not `Main'\n"
+msgstr "%s: fichier mmo invalide: valeur d'initialisation pour $255 n'est pas «Main»\n"
+
+#: mmo.c:1332
+#, c-format
+msgid "%s: unsupported wide character sequence 0x%02X 0x%02X after symbol name starting with `%s'\n"
+msgstr "%s: séquence de caractères large 0x%02X 0x%02X non supportée après le nom de symbole débutant par «%s»\n"
+
+#: mmo.c:1565
+#, c-format
+msgid "%s: invalid mmo file: unsupported lopcode `%d'\n"
+msgstr "%s: fichier mmo invalide: lopcode «%d» non supporté\n"
+
+#: mmo.c:1575
+#, c-format
+msgid "%s: invalid mmo file: expected YZ = 1 got YZ = %d for lop_quote\n"
+msgstr "%s: fichier mmo invalide: attendu YZ = 1 obtenu YZ = %d pour lop_quote\n"
+
+#: mmo.c:1611
+#, c-format
+msgid "%s: invalid mmo file: expected z = 1 or z = 2, got z = %d for lop_loc\n"
+msgstr "%s: fichier mmo invalide: attendu z = 1 ou z = 2, obtenu z = %d pour lop_loc\n"
+
+#: mmo.c:1657
+#, c-format
+msgid "%s: invalid mmo file: expected z = 1 or z = 2, got z = %d for lop_fixo\n"
+msgstr "%s: fichier mmo invalide: attendu z = 1 ou z = 2, obtenu z = %d pour lop_fixo\n"
+
+#: mmo.c:1696
+#, c-format
+msgid "%s: invalid mmo file: expected y = 0, got y = %d for lop_fixrx\n"
+msgstr "%s: fichier mmo invalide: attendu y = 0, obtenu y = %d pour lop_fixrx\n"
+
+#: mmo.c:1705
+#, c-format
+msgid "%s: invalid mmo file: expected z = 16 or z = 24, got z = %d for lop_fixrx\n"
+msgstr "%s: fichier mmo invalide: attendu z = 16 ou z = 24, obtenu z = %d pour lop_fixrx\n"
+
+#: mmo.c:1728
+#, c-format
+msgid "%s: invalid mmo file: leading byte of operand word must be 0 or 1, got %d for lop_fixrx\n"
+msgstr "%s: fichier mmo invalide: octet de tête du mot de l'opérande doit être 0 ou 1, obtenu %d pour lop_fixrx\n"
+
+#: mmo.c:1751
+#, c-format
+msgid "%s: cannot allocate file name for file number %d, %d bytes\n"
+msgstr "%s: ne paut pas allouer un nom de ficheir pour le no. de fichier %d, %d octets\n"
+
+#: mmo.c:1771
+#, c-format
+msgid "%s: invalid mmo file: file number %d `%s', was already entered as `%s'\n"
+msgstr "%s: fichier mmo invalide: no. de fichier %d «%s», a déjà été entré en tant que «%s»\n"
+
+#: mmo.c:1784
+#, c-format
+msgid "%s: invalid mmo file: file name for number %d was not specified before use\n"
+msgstr "%s: fichier mmo invalide: nom de fichier %d n'a pas été spécifié avant son utilisation\n"
+
+#: mmo.c:1890
+#, c-format
+msgid "%s: invalid mmo file: fields y and z of lop_stab non-zero, y: %d, z: %d\n"
+msgstr "%s: fichier mmo invalide: champs y et z de lop_stab non nul, y: %d, z: %d\n"
+
+#: mmo.c:1926
+#, c-format
+msgid "%s: invalid mmo file: lop_end not last item in file\n"
+msgstr "%s: fichier mmo invalide: lop_end n'est pas le dernier élement dans le fichier\n"
+
+#: mmo.c:1939
+#, c-format
+msgid "%s: invalid mmo file: YZ of lop_end (%ld) not equal to the number of tetras to the preceding lop_stab (%ld)\n"
+msgstr "%s: fichier mmo invalide: YZ de lop_end (%ld) n'est pas égal au nombre de tetras du lop_stab précédent (%ld)\n"
+
+#: mmo.c:2649
+#, c-format
+msgid "%s: invalid symbol table: duplicate symbol `%s'\n"
+msgstr "%s: table de symboles invalide: symbole «%s» dupliqué\n"
+
+#: mmo.c:2889
+#, c-format
+msgid "%s: Bad symbol definition: `Main' set to %s rather than the start address %s\n"
+msgstr "%s: Définition de symbole erronée: «Main» initialisé à %s au lieu de l'adresse de départ %s\n"
+
+#: mmo.c:2981
+#, c-format
+msgid "%s: warning: symbol table too large for mmo, larger than 65535 32-bit words: %d. Only `Main' will be emitted.\n"
+msgstr "%s: attention: table de symboles trop grande pour mmo, plus grande que 65535 mots de 32 bits: %d. Seul «Main» sera produit.\n"
+
+#: mmo.c:3026
+#, c-format
+msgid "%s: internal error, symbol table changed size from %d to %d words\n"
+msgstr "%s: erreur interne, table de symbole a changé de taille de %d à %d mots\n"
+
+#: mmo.c:3078
+#, c-format
+msgid "%s: internal error, internal register section %s had contents\n"
+msgstr "%s: erreur interne, registre interne de section %s contient quelque chose\n"
+
+#: mmo.c:3129
+#, c-format
+msgid "%s: no initialized registers; section length 0\n"
+msgstr "%s: pas de registre initialisé; section de longeur 0\n"
+
+#: mmo.c:3135
+#, c-format
+msgid "%s: too many initialized registers; section length %ld\n"
+msgstr "%s: trop de resigstres initialisés; longueur de section %ld\n"
+
+#: mmo.c:3140
+#, c-format
+msgid "%s: invalid start address for initialized registers of length %ld: 0x%lx%08lx\n"
+msgstr "%s: adresse de départ invalide pour des registres initialisés de longueur %ld: 0x%lx%08lx\n"
+
+#: oasys.c:882
+#, c-format
+msgid "%s: can not represent section `%s' in oasys"
+msgstr "%s: ne peut représenter la section «%s» dans oasys"
+
+#: osf-core.c:140
+#, c-format
+msgid "Unhandled OSF/1 core file section type %d\n"
+msgstr "Type de section de fichier core OSF/1 %d non traité\n"
+
+#: pe-mips.c:607
+msgid "%B: `ld -r' not supported with PE MIPS objects\n"
+msgstr "%B: «ld -r» non supporté avec les objets PE MIPS\n"
+
+#. OK, at this point the following variables are set up:
+#. src = VMA of the memory we're fixing up
+#. mem = pointer to memory we're fixing up
+#. val = VMA of what we need to refer to.
+#: pe-mips.c:719
+msgid "%B: unimplemented %s\n"
+msgstr "%B: non implanté %s\n"
+
+#: pe-mips.c:745
+msgid "%B: jump too far away\n"
+msgstr "%B: le saut va trop loin\n"
+
+#: pe-mips.c:771
+msgid "%B: bad pair/reflo after refhi\n"
+msgstr "%B: pairage erronée pair/reflo après refhi\n"
+
+#: pef.c:520
+#, c-format
+msgid "bfd_pef_scan: unknown architecture 0x%lx"
+msgstr "bfd_pef_scan: architecture 0x%lx inconnue"
+
+#: pei-x86_64.c:444
+#, c-format
+msgid "warning: .pdata section size (%ld) is not a multiple of %d\n"
+msgstr "attention, taille de la section .pdata (%ld) n'est pas un multiple de %d\n"
+
+#: pei-x86_64.c:448 peigen.c:1618 peigen.c:1801 pepigen.c:1618 pepigen.c:1801
+#: pex64igen.c:1618 pex64igen.c:1801
+#, c-format
+msgid ""
+"\n"
+"The Function Table (interpreted .pdata section contents)\n"
+msgstr ""
+"\n"
+"La table de fonctions (interprétation du contenu de la section .pdata)\n"
+
+#: pei-x86_64.c:450
+#, c-format
+msgid "vma:\t\t\tBeginAddress\t EndAddress\t UnwindData\n"
+msgstr " vma:\t\t\tAdresse Début\t Adresse Fin\t Unwind Info\n"
+
+#. XXX code yet to be written.
+#: peicode.h:751
+msgid "%B: Unhandled import type; %x"
+msgstr "%B: type d'importation non traitée; %x"
+
+#: peicode.h:756
+msgid "%B: Unrecognised import type; %x"
+msgstr "%B: type d'importation non reconnu; %x"
+
+#: peicode.h:770
+msgid "%B: Unrecognised import name type; %x"
+msgstr "%B: type de nom d'importation non reconnu: %x"
+
+#: peicode.h:1166
+msgid "%B: Unrecognised machine type (0x%x) in Import Library Format archive"
+msgstr "%B: type de machine non reconnu (0x%x) dans l'archive de librairie de formats d'importation"
+
+#: peicode.h:1178
+msgid "%B: Recognised but unhandled machine type (0x%x) in Import Library Format archive"
+msgstr "%B: type de machine reconnue mais non traitée (0x%x) dans l'archive da la librairie de formats d'importation"
+
+#: peicode.h:1196
+msgid "%B: size field is zero in Import Library Format header"
+msgstr "%B: taille du champ est zéro dans l'en-tête de la librairie de formats d'importation"
+
+#: peicode.h:1227
+msgid "%B: string not null terminated in ILF object file."
+msgstr "%B: chaîne n'est pas terminée par un zéro dans le fichier objet ILF."
+
+#: ppcboot.c:414
+#, c-format
+msgid ""
+"\n"
+"ppcboot header:\n"
+msgstr ""
+"\n"
+"En-têtes ppcboot:\n"
+
+#: ppcboot.c:415
+#, c-format
+msgid "Entry offset = 0x%.8lx (%ld)\n"
+msgstr "Décalage de l'entrée= 0x%.8lx (%ld)\n"
+
+#: ppcboot.c:417
+#, c-format
+msgid "Length = 0x%.8lx (%ld)\n"
+msgstr "Longueur = 0x%.8lx (%ld)\n"
+
+#: ppcboot.c:421
+#, c-format
+msgid "Flag field = 0x%.2x\n"
+msgstr "Champ de fanion = 0x%.2x\n"
+
+#: ppcboot.c:427
+#, c-format
+msgid "Partition name = \"%s\"\n"
+msgstr "Nom de partition = «%s»\n"
+
+#: ppcboot.c:446
+#, c-format
+msgid ""
+"\n"
+"Partition[%d] start = { 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x }\n"
+msgstr ""
+"\n"
+"Début de partition[%d] = { 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x }\n"
+
+#: ppcboot.c:452
+#, c-format
+msgid "Partition[%d] end = { 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x }\n"
+msgstr "Fin de la partition[%d] = { 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x }\n"
+
+#: ppcboot.c:458
+#, c-format
+msgid "Partition[%d] sector = 0x%.8lx (%ld)\n"
+msgstr "Secteur de la partition[%d] = 0x%.8lx (%ld)\n"
+
+#: ppcboot.c:460
+#, c-format
+msgid "Partition[%d] length = 0x%.8lx (%ld)\n"
+msgstr "Longueur de la partition[%d] = 0x%.8lx (%ld)\n"
+
+#: reloc.c:6160
+msgid "INPUT_SECTION_FLAGS are not supported.\n"
+msgstr "INPUT_SECTION_FLAGS pas supportés.\n"
+
+#: rs6000-core.c:448
+#, c-format
+msgid "%s: warning core file truncated"
+msgstr "%s: fichier core d'avertissement tronqué"
+
+#: som.c:5471
+#, c-format
+msgid ""
+"\n"
+"Exec Auxiliary Header\n"
+msgstr ""
+"\n"
+"En-tête auxiliaire de l'exec\n"
+
+#: som.c:5776
+msgid "som_sizeof_headers unimplemented"
+msgstr "som_sizeof_headers non implémenté"
+
+#: srec.c:261
+msgid "%B:%d: Unexpected character `%s' in S-record file\n"
+msgstr "%B:%d: caractère inattendu «%s» dans le fichier S-record\n"
+
+#: srec.c:567 srec.c:600
+msgid "%B:%d: Bad checksum in S-record file\n"
+msgstr "%B:%d: Mauvaise somme de contrôle dans le fichier S-record\n"
+
+#: stabs.c:279
+msgid "%B(%A+0x%lx): Stabs entry has invalid string index."
+msgstr "%B(%A+0x%lx): Entrée des ébauches a un indexe de chaîne invalide"
+
+#: syms.c:1079
+msgid "Unsupported .stab relocation"
+msgstr "Réadressage du .stab non supporté"
+
+#: vms-alpha.c:1299
+#, c-format
+msgid "Unknown EGSD subtype %d"
+msgstr "Sous type EGSD %d inconnu"
+
+#: vms-alpha.c:1330
+#, c-format
+msgid "Stack overflow (%d) in _bfd_vms_push"
+msgstr "Débordement de la pile (%d) dans _bfd_vms_push"
+
+#: vms-alpha.c:1343
+msgid "Stack underflow in _bfd_vms_pop"
+msgstr "Sous dépilage de la pile dans _bfd_vms_pop"
+
+#. These names have not yet been added to this switch statement.
+#: vms-alpha.c:1580
+#, c-format
+msgid "unknown ETIR command %d"
+msgstr "commande ETIR %d inconnue"
+
+#: vms-alpha.c:1767
+#, c-format
+msgid "bad section index in %s"
+msgstr "index de section erronée dans %s"
+
+#: vms-alpha.c:1780
+#, c-format
+msgid "unsupported STA cmd %s"
+msgstr "commande STA %s non supportée"
+
+#. Insert field.
+#. Unsigned shift.
+#. Rotate.
+#. Redefine symbol to current location.
+#. Define a literal.
+#: vms-alpha.c:1956 vms-alpha.c:1987 vms-alpha.c:2234
+#, c-format
+msgid "%s: not supported"
+msgstr "%s: pas supporté"
+
+#: vms-alpha.c:1962
+#, c-format
+msgid "%s: not implemented"
+msgstr "%s: non implémenté"
+
+#: vms-alpha.c:2218
+#, c-format
+msgid "invalid use of %s with contexts"
+msgstr "utilisation incorrecte de %s avec des contextes"
+
+#: vms-alpha.c:2252
+#, c-format
+msgid "reserved cmd %d"
+msgstr "commande %d réservée"
+
+#: vms-alpha.c:2337
+msgid "Object module NOT error-free !\n"
+msgstr "Module objet N'EST PAS sans erreur !\n"
+
+#: vms-alpha.c:2766
+#, c-format
+msgid "Symbol %s replaced by %s\n"
+msgstr "Symbole %s remplacé par %s\n"
+
+#: vms-alpha.c:3769
+#, c-format
+msgid "SEC_RELOC with no relocs in section %s"
+msgstr "SEC_RELOC sans relocalisation dans la section %s"
+
+#: vms-alpha.c:3822 vms-alpha.c:4049
+#, c-format
+msgid "Size error in section %s"
+msgstr "Erreur de taille dans la section %s"
+
+#: vms-alpha.c:3991
+msgid "Spurious ALPHA_R_BSR reloc"
+msgstr "Relocalisation ALPHA_R_BSR parasite"
+
+#: vms-alpha.c:4036
+#, c-format
+msgid "Unhandled relocation %s"
+msgstr "Réadressage %s non traité"
+
+#: vms-alpha.c:4326
+#, c-format
+msgid "unknown source command %d"
+msgstr "commande source %d inconnue"
+
+#: vms-alpha.c:4387
+msgid "DST__K_SET_LINUM_INCR not implemented"
+msgstr "DST__K_SET_LINUM_INCR pas implémenté"
+
+#: vms-alpha.c:4393
+msgid "DST__K_SET_LINUM_INCR_W not implemented"
+msgstr "DST__K_SET_LINUM_INCR_W pas implémenté"
+
+#: vms-alpha.c:4399
+msgid "DST__K_RESET_LINUM_INCR not implemented"
+msgstr "DST__K_RESET_LINUM_INCR pas implémenté"
+
+#: vms-alpha.c:4405
+msgid "DST__K_BEG_STMT_MODE not implemented"
+msgstr "DST__K_BEG_STMT_MODE pas implémenté"
+
+#: vms-alpha.c:4411
+msgid "DST__K_END_STMT_MODE not implemented"
+msgstr "DST__K_END_STMT_MODE pas implémenté"
+
+#: vms-alpha.c:4438
+msgid "DST__K_SET_PC not implemented"
+msgstr "DST__K_SET_PC pas implémenté"
+
+#: vms-alpha.c:4444
+msgid "DST__K_SET_PC_W not implemented"
+msgstr "DST__K_SET_PC_W pas implémenté"
+
+#: vms-alpha.c:4450
+msgid "DST__K_SET_PC_L not implemented"
+msgstr "DST__K_SET_PC_L pas implémenté"
+
+#: vms-alpha.c:4456
+msgid "DST__K_SET_STMTNUM not implemented"
+msgstr "DST__K_SET_STMTNUM pas implémenté"
+
+#: vms-alpha.c:4499
+#, c-format
+msgid "unknown line command %d"
+msgstr "commande de ligne %d inconnue"
+
+#: vms-alpha.c:4953 vms-alpha.c:4970 vms-alpha.c:4984 vms-alpha.c:4999
+#: vms-alpha.c:5011 vms-alpha.c:5022 vms-alpha.c:5034
+#, c-format
+msgid "Unknown reloc %s + %s"
+msgstr "Relocalisation %s + %s inconnue"
+
+#: vms-alpha.c:5089
+#, c-format
+msgid "Unknown reloc %s"
+msgstr "Relocalisation %s inconnue"
+
+#: vms-alpha.c:5102
+msgid "Invalid section index in ETIR"
+msgstr "Index de section incorrect dans ETIR"
+
+#: vms-alpha.c:5109
+msgid "Relocation for non-REL psect"
+msgstr "Réadressage pour psect non-REL"
+
+#: vms-alpha.c:5156
+#, c-format
+msgid "Unknown symbol in command %s"
+msgstr "Symbole inconnu dans la commande %s"
+
+#: vms-alpha.c:5671
+#, c-format
+msgid " EMH %u (len=%u): "
+msgstr " EMH %u (long=%u): "
+
+#: vms-alpha.c:5680
+#, c-format
+msgid "Module header\n"
+msgstr "En-tête module\n"
+
+#: vms-alpha.c:5681
+#, c-format
+msgid " structure level: %u\n"
+msgstr " niveau de structure: %u\n"
+
+#: vms-alpha.c:5682
+#, c-format
+msgid " max record size: %u\n"
+msgstr " taille max d'enregistrement: %u\n"
+
+#: vms-alpha.c:5685
+#, c-format
+msgid " module name : %.*s\n"
+msgstr " nom du module : %.*s\n"
+
+#: vms-alpha.c:5687
+#, c-format
+msgid " module version : %.*s\n"
+msgstr " version du module : %.*s\n"
+
+#: vms-alpha.c:5689
+#, c-format
+msgid " compile date : %.17s\n"
+msgstr " date de compilation : %.17s\n"
+
+#: vms-alpha.c:5694
+#, c-format
+msgid "Language Processor Name\n"
+msgstr "Nom du Processeur de Langage\n"
+
+#: vms-alpha.c:5695
+#, c-format
+msgid " language name: %.*s\n"
+msgstr " nom du language: %.*s\n"
+
+#: vms-alpha.c:5702
+#, c-format
+msgid "Source Files Header\n"
+msgstr "En-tête des fichiers sources\n"
+
+#: vms-alpha.c:5703
+#, c-format
+msgid " file: %.*s\n"
+msgstr " fichier: %.*s\n"
+
+#: vms-alpha.c:5710
+#, c-format
+msgid "Title Text Header\n"
+msgstr "En-tête du texte du titre\n"
+
+#: vms-alpha.c:5711
+#, c-format
+msgid " title: %.*s\n"
+msgstr " titre: %.*s\n"
+
+#: vms-alpha.c:5718
+#, c-format
+msgid "Copyright Header\n"
+msgstr "En-tête du copyright\n"
+
+#: vms-alpha.c:5719
+#, c-format
+msgid " copyright: %.*s\n"
+msgstr " copyright: %.*s\n"
+
+#: vms-alpha.c:5725
+#, c-format
+msgid "unhandled emh subtype %u\n"
+msgstr "sous-type emh %u non pris en charge\n"
+
+#: vms-alpha.c:5735
+#, c-format
+msgid " EEOM (len=%u):\n"
+msgstr " EEOM (long=%u):\n"
+
+#: vms-alpha.c:5736
+#, c-format
+msgid " number of cond linkage pairs: %u\n"
+msgstr " nombre de paires de liaisons cond: %u\n"
+
+#: vms-alpha.c:5738
+#, c-format
+msgid " completion code: %u\n"
+msgstr " code de complétion: %u\n"
+
+#: vms-alpha.c:5742
+#, c-format
+msgid " transfer addr flags: 0x%02x\n"
+msgstr " fanions de transfert d'adr: 0x%02x\n"
+
+#: vms-alpha.c:5743
+#, c-format
+msgid " transfer addr psect: %u\n"
+msgstr " psect transert adr: %u\n"
+
+#: vms-alpha.c:5745
+#, c-format
+msgid " transfer address : 0x%08x\n"
+msgstr " adresse de transert: 0x%08x\n"
+
+#: vms-alpha.c:5754
+msgid " WEAK"
+msgstr " FAIBLE"
+
+#: vms-alpha.c:5756
+msgid " DEF"
+msgstr " DEF"
+
+#: vms-alpha.c:5758
+msgid " UNI"
+msgstr " UNI"
+
+#: vms-alpha.c:5760 vms-alpha.c:5781
+msgid " REL"
+msgstr " REL"
+
+#: vms-alpha.c:5762
+msgid " COMM"
+msgstr " COMM"
+
+#: vms-alpha.c:5764
+msgid " VECEP"
+msgstr " VECEP"
+
+#: vms-alpha.c:5766
+msgid " NORM"
+msgstr " NORM"
+
+#: vms-alpha.c:5768
+msgid " QVAL"
+msgstr " QVAL"
+
+#: vms-alpha.c:5775
+msgid " PIC"
+msgstr " PIC"
+
+#: vms-alpha.c:5777
+msgid " LIB"
+msgstr " LIB"
+
+#: vms-alpha.c:5779
+msgid " OVR"
+msgstr " OVR"
+
+#: vms-alpha.c:5783
+msgid " GBL"
+msgstr " GBL"
+
+#: vms-alpha.c:5785
+msgid " SHR"
+msgstr " SHR"
+
+#: vms-alpha.c:5787
+msgid " EXE"
+msgstr " EXE"
+
+#: vms-alpha.c:5789
+msgid " RD"
+msgstr " RD"
+
+#: vms-alpha.c:5791
+msgid " WRT"
+msgstr " WRT"
+
+#: vms-alpha.c:5793
+msgid " VEC"
+msgstr " VEC"
+
+#: vms-alpha.c:5795
+msgid " NOMOD"
+msgstr " NOMOD"
+
+#: vms-alpha.c:5797
+msgid " COM"
+msgstr " COM"
+
+#: vms-alpha.c:5799
+msgid " 64B"
+msgstr " 64B"
+
+#: vms-alpha.c:5808
+#, c-format
+msgid " EGSD (len=%u):\n"
+msgstr " EGSD (long=%u):\n"
+
+#: vms-alpha.c:5820
+#, c-format
+msgid " EGSD entry %2u (type: %u, len: %u): "
+msgstr " entrée EGSD %2u (type: %u, long: %u): "
+
+#: vms-alpha.c:5832
+#, c-format
+msgid "PSC - Program section definition\n"
+msgstr "PSC - Définition de section du programme\n"
+
+#: vms-alpha.c:5833 vms-alpha.c:5850
+#, c-format
+msgid " alignment : 2**%u\n"
+msgstr " alignement : 2**%u\n"
+
+#: vms-alpha.c:5834 vms-alpha.c:5851
+#, c-format
+msgid " flags : 0x%04x"
+msgstr " fanions : 0x%04x"
+
+#: vms-alpha.c:5838
+#, c-format
+msgid " alloc (len): %u (0x%08x)\n"
+msgstr " alloc (long): %u (0x%08x)\n"
+
+#: vms-alpha.c:5839 vms-alpha.c:5896 vms-alpha.c:5945
+#, c-format
+msgid " name : %.*s\n"
+msgstr " nom : %.*s\n"
+
+#: vms-alpha.c:5849
+#, c-format
+msgid "SPSC - Shared Image Program section def\n"
+msgstr "SPSC - Def de section de l'image partagée du programme\n"
+
+#: vms-alpha.c:5855
+#, c-format
+msgid " alloc (len) : %u (0x%08x)\n"
+msgstr " alloc (long) : %u (0x%08x)\n"
+
+#: vms-alpha.c:5856
+#, c-format
+msgid " image offset : 0x%08x\n"
+msgstr " offset d'image: 0x%08x\n"
+
+#: vms-alpha.c:5858
+#, c-format
+msgid " symvec offset : 0x%08x\n"
+msgstr " offset symvec : 0x%08x\n"
+
+#: vms-alpha.c:5860
+#, c-format
+msgid " name : %.*s\n"
+msgstr " nom : %.*s\n"
+
+#: vms-alpha.c:5873
+#, c-format
+msgid "SYM - Global symbol definition\n"
+msgstr "SYM - Définition du symbol global\n"
+
+#: vms-alpha.c:5874 vms-alpha.c:5934 vms-alpha.c:5955 vms-alpha.c:5974
+#, c-format
+msgid " flags: 0x%04x"
+msgstr " fanions: 0x%04x"
+
+#: vms-alpha.c:5877
+#, c-format
+msgid " psect offset: 0x%08x\n"
+msgstr " offset psect: 0x%08x\n"
+
+#: vms-alpha.c:5881
+#, c-format
+msgid " code address: 0x%08x\n"
+msgstr " adresse code: 0x%08x\n"
+
+#: vms-alpha.c:5883
+#, c-format
+msgid " psect index for entry point : %u\n"
+msgstr " index psect pour point d'entrée: %u\n"
+
+#: vms-alpha.c:5886 vms-alpha.c:5962 vms-alpha.c:5981
+#, c-format
+msgid " psect index : %u\n"
+msgstr " index psect : %u\n"
+
+#: vms-alpha.c:5888 vms-alpha.c:5964 vms-alpha.c:5983
+#, c-format
+msgid " name : %.*s\n"
+msgstr " nom : %.*s\n"
+
+#: vms-alpha.c:5895
+#, c-format
+msgid "SYM - Global symbol reference\n"
+msgstr "SYM - Référence du symbol globaux\n"
+
+#: vms-alpha.c:5907
+#, c-format
+msgid "IDC - Ident Consistency check\n"
+msgstr "IDC - Vérification de la consistance d'identité\n"
+
+#: vms-alpha.c:5908
+#, c-format
+msgid " flags : 0x%08x"
+msgstr " fanions : 0x%08x"
+
+#: vms-alpha.c:5912
+#, c-format
+msgid " id match : %x\n"
+msgstr " correspondance id : %x\n"
+
+#: vms-alpha.c:5914
+#, c-format
+msgid " error severity: %x\n"
+msgstr " sévérité d'erreur: %x\n"
+
+#: vms-alpha.c:5917
+#, c-format
+msgid " entity name : %.*s\n"
+msgstr " nom d'entité : %.*s\n"
+
+#: vms-alpha.c:5919
+#, c-format
+msgid " object name : %.*s\n"
+msgstr " nom d'objet : %.*s\n"
+
+#: vms-alpha.c:5922
+#, c-format
+msgid " binary ident : 0x%08x\n"
+msgstr " ident binaire : 0x%08x\n"
+
+#: vms-alpha.c:5925
+#, c-format
+msgid " ascii ident : %.*s\n"
+msgstr " ident ascii : %.*s\n"
+
+#: vms-alpha.c:5933
+#, c-format
+msgid "SYMG - Universal symbol definition\n"
+msgstr "SYMG - Définition de symbole universel\n"
+
+#: vms-alpha.c:5937
+#, c-format
+msgid " symbol vector offset: 0x%08x\n"
+msgstr " offset vecteur symbole: 0x%08x\n"
+
+#: vms-alpha.c:5939
+#, c-format
+msgid " entry point: 0x%08x\n"
+msgstr " point d'entrée: 0x%08x\n"
+
+#: vms-alpha.c:5941
+#, c-format
+msgid " proc descr : 0x%08x\n"
+msgstr " descr proc : 0x%08x\n"
+
+#: vms-alpha.c:5943
+#, c-format
+msgid " psect index: %u\n"
+msgstr " index psect: %u\n"
+
+#: vms-alpha.c:5954
+#, c-format
+msgid "SYMV - Vectored symbol definition\n"
+msgstr "SYMV - Définition symbole vectorisé\n"
+
+#: vms-alpha.c:5958
+#, c-format
+msgid " vector : 0x%08x\n"
+msgstr " vecteur : 0x%08x\n"
+
+#: vms-alpha.c:5960 vms-alpha.c:5979
+#, c-format
+msgid " psect offset: %u\n"
+msgstr " offset psect: %u\n"
+
+#: vms-alpha.c:5973
+#, c-format
+msgid "SYMM - Global symbol definition with version\n"
+msgstr "SYMM - Définition de symbole globale avec version\n"
+
+#: vms-alpha.c:5977
+#, c-format
+msgid " version mask: 0x%08x\n"
+msgstr " masque de version: 0x%08x\n"
+
+#: vms-alpha.c:5988
+#, c-format
+msgid "unhandled egsd entry type %u\n"
+msgstr "type d'entrée egsd %u non supporté\n"
+
+#: vms-alpha.c:6022
+#, c-format
+msgid " linkage index: %u, replacement insn: 0x%08x\n"
+msgstr " index de liaison: %u, instruction de remplacement: 0x%08x\n"
+
+#: vms-alpha.c:6025
+#, c-format
+msgid " psect idx 1: %u, offset 1: 0x%08x %08x\n"
+msgstr " index psect 1: %u, offset 1: 0x%08x %08x\n"
+
+#: vms-alpha.c:6029
+#, c-format
+msgid " psect idx 2: %u, offset 2: 0x%08x %08x\n"
+msgstr " index psect 2: %u, offset 2: 0x%08x %08x\n"
+
+#: vms-alpha.c:6034
+#, c-format
+msgid " psect idx 3: %u, offset 3: 0x%08x %08x\n"
+msgstr " index psect 3: %u, offset 3: 0x%08x %08x\n"
+
+#: vms-alpha.c:6039
+#, c-format
+msgid " global name: %.*s\n"
+msgstr " nom global: %.*s\n"
+
+#: vms-alpha.c:6049
+#, c-format
+msgid " %s (len=%u+%u):\n"
+msgstr " %s (long=%u+%u):\n"
+
+#: vms-alpha.c:6064
+#, c-format
+msgid " (type: %3u, size: 4+%3u): "
+msgstr " (type: %3u, taille: 4+%3u): "
+
+#: vms-alpha.c:6068
+#, c-format
+msgid "STA_GBL (stack global) %.*s\n"
+msgstr "STA_GBL (pile globals) %.*s\n"
+
+#: vms-alpha.c:6072
+#, c-format
+msgid "STA_LW (stack longword) 0x%08x\n"
+msgstr "STA_LW (pile mot long) 0x%08x\n"
+
+#: vms-alpha.c:6076
+#, c-format
+msgid "STA_QW (stack quadword) 0x%08x %08x\n"
+msgstr "STA_QW (pile quad mot) 0x%08x %08x\n"
+
+#: vms-alpha.c:6081
+#, c-format
+msgid "STA_PQ (stack psect base + offset)\n"
+msgstr "STA_PQ (base pile psect + offset)\n"
+
+#: vms-alpha.c:6082
+#, c-format
+msgid " psect: %u, offset: 0x%08x %08x\n"
+msgstr " psect: %u, offset: 0x%08x %08x\n"
+
+#: vms-alpha.c:6088
+#, c-format
+msgid "STA_LI (stack literal)\n"
+msgstr "STA_LI (pile literale)\n"
+
+#: vms-alpha.c:6091
+#, c-format
+msgid "STA_MOD (stack module)\n"
+msgstr "STA_MOD (pile module)\n"
+
+#: vms-alpha.c:6094
+#, c-format
+msgid "STA_CKARG (compare procedure argument)\n"
+msgstr "STA_CKARG (compare les arguments de la procédure)\n"
+
+#: vms-alpha.c:6098
+#, c-format
+msgid "STO_B (store byte)\n"
+msgstr "STO_B (stocke octet)\n"
+
+#: vms-alpha.c:6101
+#, c-format
+msgid "STO_W (store word)\n"
+msgstr "STO_W (stocke mot)\n"
+
+#: vms-alpha.c:6104
+#, c-format
+msgid "STO_LW (store longword)\n"
+msgstr "STO_LW (stocke mot long)\n"
+
+#: vms-alpha.c:6107
+#, c-format
+msgid "STO_QW (store quadword)\n"
+msgstr "STO_QW (stocke quad mot)\n"
+
+#: vms-alpha.c:6113
+#, c-format
+msgid "STO_IMMR (store immediate repeat) %u bytes\n"
+msgstr "STO_IMMR (stock répétition immédiate) %u octets\n"
+
+#: vms-alpha.c:6120
+#, c-format
+msgid "STO_GBL (store global) %.*s\n"
+msgstr "STO_GBL (stocke globale) %.*s\n"
+
+#: vms-alpha.c:6124
+#, c-format
+msgid "STO_CA (store code address) %.*s\n"
+msgstr "STO_CA (stock adresse code) %.*s\n"
+
+#: vms-alpha.c:6128
+#, c-format
+msgid "STO_RB (store relative branch)\n"
+msgstr "STO_RB (stocke branche relative)\n"
+
+#: vms-alpha.c:6131
+#, c-format
+msgid "STO_AB (store absolute branch)\n"
+msgstr "STO_AB (stocke branche absolue)\n"
+
+#: vms-alpha.c:6134
+#, c-format
+msgid "STO_OFF (store offset to psect)\n"
+msgstr "STO_OFF (stocke offset de psect)\n"
+
+#: vms-alpha.c:6140
+#, c-format
+msgid "STO_IMM (store immediate) %u bytes\n"
+msgstr "STO_IMM (stocke immediat) %u octets\n"
+
+#: vms-alpha.c:6147
+#, c-format
+msgid "STO_GBL_LW (store global longword) %.*s\n"
+msgstr "STO_GBL_LW (stocke mot long global) %.*s\n"
+
+#: vms-alpha.c:6151
+#, c-format
+msgid "STO_OFF (store LP with procedure signature)\n"
+msgstr "STO_OFF (stocke LP avec la signature de la procédure)\n"
+
+#: vms-alpha.c:6154
+#, c-format
+msgid "STO_BR_GBL (store branch global) *todo*\n"
+msgstr "STO_BR_GBL (stocke branche globale) *todo*\n"
+
+#: vms-alpha.c:6157
+#, c-format
+msgid "STO_BR_PS (store branch psect + offset) *todo*\n"
+msgstr "STO_BR_PS (stocke branche psect + offset) *todo*\n"
+
+#: vms-alpha.c:6161
+#, c-format
+msgid "OPR_NOP (no-operation)\n"
+msgstr "OPR_NOP (pas d'operation)\n"
+
+#: vms-alpha.c:6164
+#, c-format
+msgid "OPR_ADD (add)\n"
+msgstr "OPR_ADD (ajout)\n"
+
+#: vms-alpha.c:6167
+#, c-format
+msgid "OPR_SUB (substract)\n"
+msgstr "OPR_SUB (soustraction)\n"
+
+#: vms-alpha.c:6170
+#, c-format
+msgid "OPR_MUL (multiply)\n"
+msgstr "OPR_MUL (multiplication)\n"
+
+#: vms-alpha.c:6173
+#, c-format
+msgid "OPR_DIV (divide)\n"
+msgstr "OPR_DIV (division)\n"
+
+#: vms-alpha.c:6176
+#, c-format
+msgid "OPR_AND (logical and)\n"
+msgstr "OPR_AND (et logique)\n"
+
+#: vms-alpha.c:6179
+#, c-format
+msgid "OPR_IOR (logical inclusive or)\n"
+msgstr "OPR_IOR (ou inclusif logique)\n"
+
+#: vms-alpha.c:6182
+#, c-format
+msgid "OPR_EOR (logical exclusive or)\n"
+msgstr "OPR_EOR (ou exclusif logique)\n"
+
+#: vms-alpha.c:6185
+#, c-format
+msgid "OPR_NEG (negate)\n"
+msgstr "OPR_NEG (négation)\n"
+
+#: vms-alpha.c:6188
+#, c-format
+msgid "OPR_COM (complement)\n"
+msgstr "OPR_COM (complément)\n"
+
+#: vms-alpha.c:6191
+#, c-format
+msgid "OPR_INSV (insert field)\n"
+msgstr "OPR_INSV (insertion champ)\n"
+
+#: vms-alpha.c:6194
+#, c-format
+msgid "OPR_ASH (arithmetic shift)\n"
+msgstr "OPR_ASH (décalage arithmetique)\n"
+
+#: vms-alpha.c:6197
+#, c-format
+msgid "OPR_USH (unsigned shift)\n"
+msgstr "OPR_USH (décalage non signé)\n"
+
+#: vms-alpha.c:6200
+#, c-format
+msgid "OPR_ROT (rotate)\n"
+msgstr "OPR_ROT (rotation)\n"
+
+#: vms-alpha.c:6203
+#, c-format
+msgid "OPR_SEL (select)\n"
+msgstr "OPR_SEL (selection)\n"
+
+#: vms-alpha.c:6206
+#, c-format
+msgid "OPR_REDEF (redefine symbol to curr location)\n"
+msgstr "OPR_REDEF (redéfini le symbole à la position actuelle)\n"
+
+#: vms-alpha.c:6209
+#, c-format
+msgid "OPR_REDEF (define a literal)\n"
+msgstr "OPR_REDEF (définir un litéral)\n"
+
+#: vms-alpha.c:6213
+#, c-format
+msgid "STC_LP (store cond linkage pair)\n"
+msgstr "STC_LP (stocke pair de liaison cond)\n"
+
+#: vms-alpha.c:6217
+#, c-format
+msgid "STC_LP_PSB (store cond linkage pair + signature)\n"
+msgstr "STC_LP_PSB (stocke pair de liaison cond + signature)\n"
+
+#: vms-alpha.c:6218
+#, c-format
+msgid " linkage index: %u, procedure: %.*s\n"
+msgstr " index liaison: %u, procédure: %.*s\n"
+
+#: vms-alpha.c:6221
+#, c-format
+msgid " signature: %.*s\n"
+msgstr " signature: %.*s\n"
+
+#: vms-alpha.c:6224
+#, c-format
+msgid "STC_GBL (store cond global)\n"
+msgstr "STC_GBL (stocke cond globale)\n"
+
+#: vms-alpha.c:6225
+#, c-format
+msgid " linkage index: %u, global: %.*s\n"
+msgstr " index liaison: %u, globale: %.*s\n"
+
+#: vms-alpha.c:6229
+#, c-format
+msgid "STC_GCA (store cond code address)\n"
+msgstr "STC_GCA (stocke adresse code cond)\n"
+
+#: vms-alpha.c:6230
+#, c-format
+msgid " linkage index: %u, procedure name: %.*s\n"
+msgstr " index liaison: %u, nom procédure: %.*s\n"
+
+#: vms-alpha.c:6234
+#, c-format
+msgid "STC_PS (store cond psect + offset)\n"
+msgstr "STC_PS (stocke psect cond + offset)\n"
+
+#: vms-alpha.c:6236
+#, c-format
+msgid " linkage index: %u, psect: %u, offset: 0x%08x %08x\n"
+msgstr " index liaison: %u, psect: %u, offset: 0x%08x %08x\n"
+
+#: vms-alpha.c:6243
+#, c-format
+msgid "STC_NOP_GBL (store cond NOP at global addr)\n"
+msgstr "STC_NOP_GBL (stocke NOP cond à l'adresse globale)\n"
+
+#: vms-alpha.c:6247
+#, c-format
+msgid "STC_NOP_PS (store cond NOP at psect + offset)\n"
+msgstr "STC_NOP_PS (stocke NOP cond à psect + offset)\n"
+
+#: vms-alpha.c:6251
+#, c-format
+msgid "STC_BSR_GBL (store cond BSR at global addr)\n"
+msgstr "STC_BSR_GBL (stocke BSR cond à l'adresse globale)\n"
+
+#: vms-alpha.c:6255
+#, c-format
+msgid "STC_BSR_PS (store cond BSR at psect + offset)\n"
+msgstr "STC_BSR_PS (stocke BSR cond à psect + offset)\n"
+
+#: vms-alpha.c:6259
+#, c-format
+msgid "STC_LDA_GBL (store cond LDA at global addr)\n"
+msgstr "STC_LDA_GBL (stocke LDA cond à l'adresse globale)\n"
+
+#: vms-alpha.c:6263
+#, c-format
+msgid "STC_LDA_PS (store cond LDA at psect + offset)\n"
+msgstr "STC_LDA_PS (stocke LDA cond à psect + offset)\n"
+
+#: vms-alpha.c:6267
+#, c-format
+msgid "STC_BOH_GBL (store cond BOH at global addr)\n"
+msgstr "STC_BOH_GBL (stocke BOH cond à l'adresse globale)\n"
+
+#: vms-alpha.c:6271
+#, c-format
+msgid "STC_BOH_PS (store cond BOH at psect + offset)\n"
+msgstr "STC_BOH_PS (stocke BOH cond à psect + offset)\n"
+
+#: vms-alpha.c:6276
+#, c-format
+msgid "STC_NBH_GBL (store cond or hint at global addr)\n"
+msgstr "STC_NBH_GBL (stocke cond ou suggestion à l'adresse globale)\n"
+
+#: vms-alpha.c:6280
+#, c-format
+msgid "STC_NBH_PS (store cond or hint at psect + offset)\n"
+msgstr "STC_NBH_PS (stocke cond or suggestion à psect + offset)\n"
+
+#: vms-alpha.c:6284
+#, c-format
+msgid "CTL_SETRB (set relocation base)\n"
+msgstr "CTL_SETRB (fixe la base du réadressage)\n"
+
+#: vms-alpha.c:6290
+#, c-format
+msgid "CTL_AUGRB (augment relocation base) %u\n"
+msgstr "CTL_AUGRB (augmente la base du réadressage) %u\n"
+
+#: vms-alpha.c:6294
+#, c-format
+msgid "CTL_DFLOC (define location)\n"
+msgstr "CTL_DFLOC (définir position)\n"
+
+#: vms-alpha.c:6297
+#, c-format
+msgid "CTL_STLOC (set location)\n"
+msgstr "CTL_STLOC (fixer position)\n"
+
+#: vms-alpha.c:6300
+#, c-format
+msgid "CTL_STKDL (stack defined location)\n"
+msgstr "CTL_STKDL (position définie dans la pile)\n"
+
+#: vms-alpha.c:6303 vms-alpha.c:6717
+#, c-format
+msgid "*unhandled*\n"
+msgstr "*non pris en charge*\n"
+
+#: vms-alpha.c:6333 vms-alpha.c:6372
+#, c-format
+msgid "cannot read GST record length\n"
+msgstr "impossible de lire la longueur de l'enregistrement GST\n"
+
+#. Ill-formed.
+#: vms-alpha.c:6354
+#, c-format
+msgid "cannot find EMH in first GST record\n"
+msgstr "impossible de trouver le EMH dans le premier enregistrement GST\n"
+
+#: vms-alpha.c:6380
+#, c-format
+msgid "cannot read GST record header\n"
+msgstr "impossible de lire l'en-tête de l'enregistrement GST\n"
+
+#: vms-alpha.c:6393
+#, c-format
+msgid " corrupted GST\n"
+msgstr " GST corrompu\n"
+
+#: vms-alpha.c:6401
+#, c-format
+msgid "cannot read GST record\n"
+msgstr "ne peut lire l'enregistrement GST\n"
+
+#: vms-alpha.c:6430
+#, c-format
+msgid " unhandled EOBJ record type %u\n"
+msgstr " type d'enregistrement EOBJ %u non supporté\n"
+
+#: vms-alpha.c:6453
+#, c-format
+msgid " bitcount: %u, base addr: 0x%08x\n"
+msgstr " décompte des bits: %u, adr base: 0x%08x\n"
+
+#: vms-alpha.c:6466
+#, c-format
+msgid " bitmap: 0x%08x (count: %u):\n"
+msgstr " carte des bits: 0x%08x (occurrence: %u):\n"
+
+#: vms-alpha.c:6473
+#, c-format
+msgid " %08x"
+msgstr " %08x"
+
+#: vms-alpha.c:6498
+#, c-format
+msgid " image %u (%u entries)\n"
+msgstr " image %u (%u entrées)\n"
+
+#: vms-alpha.c:6503
+#, c-format
+msgid " offset: 0x%08x, val: 0x%08x\n"
+msgstr " offset: 0x%08x, val: 0x%08x\n"
+
+#: vms-alpha.c:6524
+#, c-format
+msgid " image %u (%u entries), offsets:\n"
+msgstr " image %u (%u entrées), offsets:\n"
+
+#: vms-alpha.c:6531
+#, c-format
+msgid " 0x%08x"
+msgstr " 0x%08x"
+
+#. 64 bits.
+#: vms-alpha.c:6653
+#, c-format
+msgid "64 bits *unhandled*\n"
+msgstr "64 bits *non supporté*\n"
+
+#: vms-alpha.c:6657
+#, c-format
+msgid "class: %u, dtype: %u, length: %u, pointer: 0x%08x\n"
+msgstr "classe: %u, dtype: %u, longueur: %u, pointeur: 0x%08x\n"
+
+#: vms-alpha.c:6668
+#, c-format
+msgid "non-contiguous array of %s\n"
+msgstr "table de %s non contiguë\n"
+
+#: vms-alpha.c:6672
+#, c-format
+msgid "dimct: %u, aflags: 0x%02x, digits: %u, scale: %u\n"
+msgstr "dimct: %u, aflags: 0x%02x, digits: %u, échelle: %u\n"
+
+#: vms-alpha.c:6676
+#, c-format
+msgid "arsize: %u, a0: 0x%08x\n"
+msgstr "arsize: %u, a0: 0x%08x\n"
+
+#: vms-alpha.c:6680
+#, c-format
+msgid "Strides:\n"
+msgstr "Pas:\n"
+
+#: vms-alpha.c:6685
+#, c-format
+msgid "[%u]: %u\n"
+msgstr "[%u]: %u\n"
+
+#: vms-alpha.c:6690
+#, c-format
+msgid "Bounds:\n"
+msgstr "Limites:\n"
+
+#: vms-alpha.c:6695
+#, c-format
+msgid "[%u]: Lower: %u, upper: %u\n"
+msgstr "[%u]: Inférieure: %u, supérieure: %u\n"
+
+#: vms-alpha.c:6707
+#, c-format
+msgid "unaligned bit-string of %s\n"
+msgstr "chaine de bits de %s désalignée\n"
+
+#: vms-alpha.c:6711
+#, c-format
+msgid "base: %u, pos: %u\n"
+msgstr "base: %u, pos: %u\n"
+
+#: vms-alpha.c:6731
+#, c-format
+msgid "vflags: 0x%02x, value: 0x%08x "
+msgstr "vflags: 0x%02x, valeur: 0x%08x "
+
+#: vms-alpha.c:6737
+#, c-format
+msgid "(no value)\n"
+msgstr "(pas de valeur)\n"
+
+#: vms-alpha.c:6740
+#, c-format
+msgid "(not active)\n"
+msgstr "(pas active)\n"
+
+#: vms-alpha.c:6743
+#, c-format
+msgid "(not allocated)\n"
+msgstr "(pas allouée)\n"
+
+#: vms-alpha.c:6746
+#, c-format
+msgid "(descriptor)\n"
+msgstr "(descripteur)\n"
+
+#: vms-alpha.c:6750
+#, c-format
+msgid "(trailing value)\n"
+msgstr "(valeur postérieure)\n"
+
+#: vms-alpha.c:6753
+#, c-format
+msgid "(value spec follows)\n"
+msgstr "(spécificités de la valeur suivent)\n"
+
+#: vms-alpha.c:6756
+#, c-format
+msgid "(at bit offset %u)\n"
+msgstr "(à l'offset de bit %u)\n"
+
+#: vms-alpha.c:6759
+#, c-format
+msgid "(reg: %u, disp: %u, indir: %u, kind: "
+msgstr "(reg: %u, aff: %u, indir: %u, type: "
+
+#: vms-alpha.c:6766
+msgid "literal"
+msgstr "litérale"
+
+#: vms-alpha.c:6769
+msgid "address"
+msgstr "adresse"
+
+#: vms-alpha.c:6772
+msgid "desc"
+msgstr "desc"
+
+#: vms-alpha.c:6775
+msgid "reg"
+msgstr "reg"
+
+#: vms-alpha.c:6850
+#, c-format
+msgid "Debug symbol table:\n"
+msgstr "Table des symboles de debug:\n"
+
+#: vms-alpha.c:6861
+#, c-format
+msgid "cannot read DST header\n"
+msgstr "impossible de lire l'en-tête DST\n"
+
+#: vms-alpha.c:6866
+#, c-format
+msgid " type: %3u, len: %3u (at 0x%08x): "
+msgstr " type: %3u, long: %3u (à 0x%08x): "
+
+#: vms-alpha.c:6880
+#, c-format
+msgid "cannot read DST symbol\n"
+msgstr "ne peut lire le symbole DST\n"
+
+#: vms-alpha.c:6923
+#, c-format
+msgid "standard data: %s\n"
+msgstr "données standards: %s\n"
+
+#: vms-alpha.c:6926 vms-alpha.c:7010
+#, c-format
+msgid " name: %.*s\n"
+msgstr " nom: %.*s\n"
+
+#: vms-alpha.c:6933
+#, c-format
+msgid "modbeg\n"
+msgstr "début module\n"
+
+#: vms-alpha.c:6934
+#, c-format
+msgid " flags: %d, language: %u, major: %u, minor: %u\n"
+msgstr " fanions: %d, language: %u, majeur: %u, mineur: %u\n"
+
+#: vms-alpha.c:6940 vms-alpha.c:7206
+#, c-format
+msgid " module name: %.*s\n"
+msgstr " nom du module: %.*s\n"
+
+#: vms-alpha.c:6943
+#, c-format
+msgid " compiler : %.*s\n"
+msgstr " compilateur : %.*s\n"
+
+#: vms-alpha.c:6948
+#, c-format
+msgid "modend\n"
+msgstr "fin module\n"
+
+#: vms-alpha.c:6955
+msgid "rtnbeg\n"
+msgstr "début rtn\n"
+
+#: vms-alpha.c:6956
+#, c-format
+msgid " flags: %u, address: 0x%08x, pd-address: 0x%08x\n"
+msgstr " fanions: %u, adresse: 0x%08x, pd-adresse: 0x%08x\n"
+
+#: vms-alpha.c:6961
+#, c-format
+msgid " routine name: %.*s\n"
+msgstr " nom routine : %.*s\n"
+
+#: vms-alpha.c:6969
+#, c-format
+msgid "rtnend: size 0x%08x\n"
+msgstr "fin rtn: taille 0x%08x\n"
+
+#: vms-alpha.c:6977
+#, c-format
+msgid "prolog: bkpt address 0x%08x\n"
+msgstr "prologue: adresse bkpt 0x%08x\n"
+
+#: vms-alpha.c:6985
+#, c-format
+msgid "epilog: flags: %u, count: %u\n"
+msgstr "épilogue: fanions: %u, nombre: %u\n"
+
+#: vms-alpha.c:6994
+#, c-format
+msgid "blkbeg: address: 0x%08x, name: %.*s\n"
+msgstr "début blk: adresse: 0x%08x, nom: %.*s\n"
+
+#: vms-alpha.c:7003
+#, c-format
+msgid "blkend: size: 0x%08x\n"
+msgstr "fin blk: taille: 0x%08x\n"
+
+#: vms-alpha.c:7009
+#, c-format
+msgid "typspec (len: %u)\n"
+msgstr "typspec (long: %u)\n"
+
+#: vms-alpha.c:7016
+#, c-format
+msgid "septyp, name: %.*s\n"
+msgstr "septyp, nom: %.*s\n"
+
+#: vms-alpha.c:7025
+#, c-format
+msgid "recbeg: name: %.*s\n"
+msgstr "début rec: nom: %.*s\n"
+
+#: vms-alpha.c:7032
+#, c-format
+msgid "recend\n"
+msgstr "fin rec\n"
+
+#: vms-alpha.c:7035
+#, c-format
+msgid "enumbeg, len: %u, name: %.*s\n"
+msgstr "début énumération, long: %u, nom: %.*s\n"
+
+#: vms-alpha.c:7039
+#, c-format
+msgid "enumelt, name: %.*s\n"
+msgstr "énumération éléments, nom: %.*s\n"
+
+#: vms-alpha.c:7043
+#, c-format
+msgid "enumend\n"
+msgstr "fin énumération\n"
+
+#: vms-alpha.c:7060
+#, c-format
+msgid "discontiguous range (nbr: %u)\n"
+msgstr "plage discontinue (nbr: %u)\n"
+
+#: vms-alpha.c:7062
+#, c-format
+msgid " address: 0x%08x, size: %u\n"
+msgstr " adresse: 0x%08x, taille: %u\n"
+
+#: vms-alpha.c:7072
+#, c-format
+msgid "line num (len: %u)\n"
+msgstr "num ligne (long: %u)\n"
+
+#: vms-alpha.c:7089
+#, c-format
+msgid "delta_pc_w %u\n"
+msgstr "delta_pc_w %u\n"
+
+#: vms-alpha.c:7096
+#, c-format
+msgid "incr_linum(b): +%u\n"
+msgstr "incr_linum(b): +%u\n"
+
+#: vms-alpha.c:7102
+#, c-format
+msgid "incr_linum_w: +%u\n"
+msgstr "incr_linum_w: +%u\n"
+
+#: vms-alpha.c:7108
+#, c-format
+msgid "incr_linum_l: +%u\n"
+msgstr "incr_linum_l: +%u\n"
+
+#: vms-alpha.c:7114
+#, c-format
+msgid "set_line_num(w) %u\n"
+msgstr "set_line_num(w) %u\n"
+
+#: vms-alpha.c:7119
+#, c-format
+msgid "set_line_num_b %u\n"
+msgstr "set_line_num_b %u\n"
+
+#: vms-alpha.c:7124
+#, c-format
+msgid "set_line_num_l %u\n"
+msgstr "set_line_num_l %u\n"
+
+#: vms-alpha.c:7129
+#, c-format
+msgid "set_abs_pc: 0x%08x\n"
+msgstr "set_abs_pc: 0x%08x\n"
+
+#: vms-alpha.c:7133
+#, c-format
+msgid "delta_pc_l: +0x%08x\n"
+msgstr "delta_pc_l: +0x%08x\n"
+
+#: vms-alpha.c:7138
+#, c-format
+msgid "term(b): 0x%02x"
+msgstr "term(b): 0x%02x"
+
+#: vms-alpha.c:7140
+#, c-format
+msgid " pc: 0x%08x\n"
+msgstr " pc: 0x%08x\n"
+
+#: vms-alpha.c:7145
+#, c-format
+msgid "term_w: 0x%04x"
+msgstr "term_w: 0x%04x"
+
+#: vms-alpha.c:7147
+#, c-format
+msgid " pc: 0x%08x\n"
+msgstr " pc: 0x%08x\n"
+
+#: vms-alpha.c:7153
+#, c-format
+msgid "delta pc +%-4d"
+msgstr "delta pc +%-4d"
+
+#: vms-alpha.c:7156
+#, c-format
+msgid " pc: 0x%08x line: %5u\n"
+msgstr " pc: 0x%08x ligne: %5u\n"
+
+#: vms-alpha.c:7161
+#, c-format
+msgid " *unhandled* cmd %u\n"
+msgstr " cmd %u *non gérée*\n"
+
+#: vms-alpha.c:7176
+#, c-format
+msgid "source (len: %u)\n"
+msgstr "source (long: %u)\n"
+
+#: vms-alpha.c:7190
+#, c-format
+msgid " declfile: len: %u, flags: %u, fileid: %u\n"
+msgstr " declfile: long: %u, fanions: %u, id fichier: %u\n"
+
+#: vms-alpha.c:7194
+#, c-format
+msgid " rms: cdt: 0x%08x %08x, ebk: 0x%08x, ffb: 0x%04x, rfo: %u\n"
+msgstr " rms: cdt: 0x%08x %08x, ebk: 0x%08x, ffb: 0x%04x, rfo: %u\n"
+
+#: vms-alpha.c:7203
+#, c-format
+msgid " filename : %.*s\n"
+msgstr " nom fichier: %.*s\n"
+
+#: vms-alpha.c:7212
+#, c-format
+msgid " setfile %u\n"
+msgstr " setfile %u\n"
+
+#: vms-alpha.c:7217 vms-alpha.c:7222
+#, c-format
+msgid " setrec %u\n"
+msgstr " setrec %u\n"
+
+#: vms-alpha.c:7227 vms-alpha.c:7232
+#, c-format
+msgid " setlnum %u\n"
+msgstr " setlnum %u\n"
+
+#: vms-alpha.c:7237 vms-alpha.c:7242
+#, c-format
+msgid " deflines %u\n"
+msgstr " deflines %u\n"
+
+#: vms-alpha.c:7246
+#, c-format
+msgid " formfeed\n"
+msgstr " formfeed\n"
+
+#: vms-alpha.c:7250
+#, c-format
+msgid " *unhandled* cmd %u\n"
+msgstr " cmd %u *non gérée*\n"
+
+#: vms-alpha.c:7262
+#, c-format
+msgid "*unhandled* dst type %u\n"
+msgstr "type dst %u *non géré*\n"
+
+#: vms-alpha.c:7294
+#, c-format
+msgid "cannot read EIHD\n"
+msgstr "ne peut lire EIHD\n"
+
+#: vms-alpha.c:7297
+#, c-format
+msgid "EIHD: (size: %u, nbr blocks: %u)\n"
+msgstr "EIHD: (taille: %u, nbr blocs: %u)\n"
+
+#: vms-alpha.c:7300
+#, c-format
+msgid " majorid: %u, minorid: %u\n"
+msgstr " id majeur: %u, id mineur: %u\n"
+
+#: vms-alpha.c:7308
+msgid "executable"
+msgstr "exécutable"
+
+#: vms-alpha.c:7311
+msgid "linkable image"
+msgstr "image liable"
+
+#: vms-alpha.c:7317
+#, c-format
+msgid " image type: %u (%s)"
+msgstr " type image: %u (%s)"
+
+#: vms-alpha.c:7323
+msgid "native"
+msgstr "natif"
+
+#: vms-alpha.c:7326
+msgid "CLI"
+msgstr "CLI"
+
+#: vms-alpha.c:7332
+#, c-format
+msgid ", subtype: %u (%s)\n"
+msgstr ", sous-type: %u (%s)\n"
+
+#: vms-alpha.c:7338
+#, c-format
+msgid " offsets: isd: %u, activ: %u, symdbg: %u, imgid: %u, patch: %u\n"
+msgstr " offsets: isd: %u, actif: %u, debug symbol: %u, id image: %u, patch: %u\n"
+
+#: vms-alpha.c:7342
+#, c-format
+msgid " fixup info rva: "
+msgstr " correctif info rva: "
+
+#: vms-alpha.c:7344
+#, c-format
+msgid ", symbol vector rva: "
+msgstr ", vecteur de symbol rva: "
+
+#: vms-alpha.c:7347
+#, c-format
+msgid ""
+"\n"
+" version array off: %u\n"
+msgstr ""
+"\n"
+" offset tableau version: %u\n"
+
+#: vms-alpha.c:7351
+#, c-format
+msgid " img I/O count: %u, nbr channels: %u, req pri: %08x%08x\n"
+msgstr " décompte E/S img: %u, nbr canaux: %u, priv req: %08x%08x\n"
+
+#: vms-alpha.c:7357
+#, c-format
+msgid " linker flags: %08x:"
+msgstr " fanions lieur: %08x:"
+
+#: vms-alpha.c:7387
+#, c-format
+msgid " ident: 0x%08x, sysver: 0x%08x, match ctrl: %u, symvect_size: %u\n"
+msgstr " ident: 0x%08x, ver sys: 0x%08x, apparier ctrl: %u, taille vectsym: %u\n"
+
+#: vms-alpha.c:7393
+#, c-format
+msgid " BPAGE: %u"
+msgstr " BPAGE: %u"
+
+#: vms-alpha.c:7399
+#, c-format
+msgid ", ext fixup offset: %u, no_opt psect off: %u"
+msgstr ", offset correctif étendu: %u, offset no_opt psect: %u"
+
+#: vms-alpha.c:7402
+#, c-format
+msgid ", alias: %u\n"
+msgstr ", alias: %u\n"
+
+#: vms-alpha.c:7410
+#, c-format
+msgid "system version array information:\n"
+msgstr "information sur table de version système:\n"
+
+#: vms-alpha.c:7414
+#, c-format
+msgid "cannot read EIHVN header\n"
+msgstr "ne peut lire l'en-tête EIHVN\n"
+
+#: vms-alpha.c:7424
+#, c-format
+msgid "cannot read EIHVN version\n"
+msgstr "ne peut lire la version EIHVN\n"
+
+#: vms-alpha.c:7427
+#, c-format
+msgid " %02u "
+msgstr " %02u "
+
+#: vms-alpha.c:7431
+msgid "BASE_IMAGE "
+msgstr "BASE_IMAGE "
+
+#: vms-alpha.c:7434
+msgid "MEMORY_MANAGEMENT"
+msgstr "MEMORY_MANAGEMENT"
+
+#: vms-alpha.c:7437
+msgid "IO "
+msgstr "IO "
+
+#: vms-alpha.c:7440
+msgid "FILES_VOLUMES "
+msgstr "FILES_VOLUMES "
+
+#: vms-alpha.c:7443
+msgid "PROCESS_SCHED "
+msgstr "PROCESS_SCHED "
+
+#: vms-alpha.c:7446
+msgid "SYSGEN "
+msgstr "SYSGEN "
+
+#: vms-alpha.c:7449
+msgid "CLUSTERS_LOCKMGR "
+msgstr "CLUSTERS_LOCKMGR "
+
+#: vms-alpha.c:7452
+msgid "LOGICAL_NAMES "
+msgstr "LOGICAL_NAMES "
+
+#: vms-alpha.c:7455
+msgid "SECURITY "
+msgstr "SECURITY "
+
+#: vms-alpha.c:7458
+msgid "IMAGE_ACTIVATOR "
+msgstr "IMAGE_ACTIVATOR "
+
+#: vms-alpha.c:7461
+msgid "NETWORKS "
+msgstr "NETWORKS "
+
+#: vms-alpha.c:7464
+msgid "COUNTERS "
+msgstr "COUNTERS "
+
+#: vms-alpha.c:7467
+msgid "STABLE "
+msgstr "STABLE "
+
+#: vms-alpha.c:7470
+msgid "MISC "
+msgstr "MISC "
+
+#: vms-alpha.c:7473
+msgid "CPU "
+msgstr "CPU "
+
+#: vms-alpha.c:7476
+msgid "VOLATILE "
+msgstr "VOLATILE "
+
+#: vms-alpha.c:7479
+msgid "SHELL "
+msgstr "SHELL "
+
+#: vms-alpha.c:7482
+msgid "POSIX "
+msgstr "POSIX "
+
+#: vms-alpha.c:7485
+msgid "MULTI_PROCESSING "
+msgstr "MULTI_PROCESSING "
+
+#: vms-alpha.c:7488
+msgid "GALAXY "
+msgstr "GALAXY "
+
+#: vms-alpha.c:7491
+msgid "*unknown* "
+msgstr "*inconnu* "
+
+#: vms-alpha.c:7494
+#, c-format
+msgid ": %u.%u\n"
+msgstr ": %u.%u\n"
+
+#: vms-alpha.c:7507 vms-alpha.c:7766
+#, c-format
+msgid "cannot read EIHA\n"
+msgstr "ne peut lire EIHA\n"
+
+#: vms-alpha.c:7510
+#, c-format
+msgid "Image activation: (size=%u)\n"
+msgstr "Activation de l'image: (taille=%u)\n"
+
+#: vms-alpha.c:7512
+#, c-format
+msgid " First address : 0x%08x 0x%08x\n"
+msgstr " Première adresse : 0x%08x 0x%08x\n"
+
+#: vms-alpha.c:7515
+#, c-format
+msgid " Second address: 0x%08x 0x%08x\n"
+msgstr " Deuxième adresse : 0x%08x 0x%08x\n"
+
+#: vms-alpha.c:7518
+#, c-format
+msgid " Third address : 0x%08x 0x%08x\n"
+msgstr " Troisième adresse: 0x%08x 0x%08x\n"
+
+#: vms-alpha.c:7521
+#, c-format
+msgid " Fourth address: 0x%08x 0x%08x\n"
+msgstr " Quatrième adresse: 0x%08x 0x%08x\n"
+
+#: vms-alpha.c:7524
+#, c-format
+msgid " Shared image : 0x%08x 0x%08x\n"
+msgstr " Image partagée : 0x%08x 0x%08x\n"
+
+#: vms-alpha.c:7535
+#, c-format
+msgid "cannot read EIHI\n"
+msgstr "ne peut lire EIHI\n"
+
+#: vms-alpha.c:7538
+#, c-format
+msgid "Image identification: (major: %u, minor: %u)\n"
+msgstr "Identification d'image: (majeur: %u, mineur: %u)\n"
+
+#: vms-alpha.c:7541
+#, c-format
+msgid " image name : %.*s\n"
+msgstr " nom de l'image : %.*s\n"
+
+#: vms-alpha.c:7543
+#, c-format
+msgid " link time : %s\n"
+msgstr " heure de liaison : %s\n"
+
+#: vms-alpha.c:7545
+#, c-format
+msgid " image ident : %.*s\n"
+msgstr " ident image : %.*s\n"
+
+#: vms-alpha.c:7547
+#, c-format
+msgid " linker ident : %.*s\n"
+msgstr " ident lieur : %.*s\n"
+
+#: vms-alpha.c:7549
+#, c-format
+msgid " image build ident: %.*s\n"
+msgstr " ident construction image: %.*s\n"
+
+#: vms-alpha.c:7559
+#, c-format
+msgid "cannot read EIHS\n"
+msgstr "ne peut lire EIHS\n"
+
+#: vms-alpha.c:7562
+#, c-format
+msgid "Image symbol & debug table: (major: %u, minor: %u)\n"
+msgstr "Image des symboles et table debug: (majeur: %u, mineur: %u)\n"
+
+#: vms-alpha.c:7567
+#, c-format
+msgid " debug symbol table : vbn: %u, size: %u (0x%x)\n"
+msgstr " table des symboles de debug : vbn: %u, taille: %u (0x%x)\n"
+
+#: vms-alpha.c:7571
+#, c-format
+msgid " global symbol table: vbn: %u, records: %u\n"
+msgstr " table des symboles globale: vbn: %u, enregistrements: %u\n"
+
+#: vms-alpha.c:7575
+#, c-format
+msgid " debug module table : vbn: %u, size: %u\n"
+msgstr " table des modules de debug: vbn: %u, taille: %u\n"
+
+#: vms-alpha.c:7588
+#, c-format
+msgid "cannot read EISD\n"
+msgstr "ne peut lire EISD\n"
+
+#: vms-alpha.c:7598
+#, c-format
+msgid "Image section descriptor: (major: %u, minor: %u, size: %u, offset: %u)\n"
+msgstr "Descripteur de section d'image: (majeur: %u, mineur: %u, taille: %u, offset: %u)\n"
+
+#: vms-alpha.c:7605
+#, c-format
+msgid " section: base: 0x%08x%08x size: 0x%08x\n"
+msgstr " section: base: 0x%08x%08x taille: 0x%08x\n"
+
+#: vms-alpha.c:7610
+#, c-format
+msgid " flags: 0x%04x"
+msgstr " fanions: 0x%04x"
+
+#: vms-alpha.c:7647
+#, c-format
+msgid " vbn: %u, pfc: %u, matchctl: %u type: %u ("
+msgstr " vbn: %u, pfc: %u, matchctl: %u type: %u ("
+
+#: vms-alpha.c:7653
+msgid "NORMAL"
+msgstr "NORMAL"
+
+#: vms-alpha.c:7656
+msgid "SHRFXD"
+msgstr "SHRFXD"
+
+#: vms-alpha.c:7659
+msgid "PRVFXD"
+msgstr "PRVFXD"
+
+#: vms-alpha.c:7662
+msgid "SHRPIC"
+msgstr "SHRPIC"
+
+#: vms-alpha.c:7665
+msgid "PRVPIC"
+msgstr "PRVPIC"
+
+#: vms-alpha.c:7668
+msgid "USRSTACK"
+msgstr "USRSTACK"
+
+#: vms-alpha.c:7676
+#, c-format
+msgid " ident: 0x%08x, name: %.*s\n"
+msgstr " ident: 0x%08x, nom: %.*s\n"
+
+#: vms-alpha.c:7686
+#, c-format
+msgid "cannot read DMT\n"
+msgstr "ne peut lire DMT\n"
+
+#: vms-alpha.c:7690
+#, c-format
+msgid "Debug module table:\n"
+msgstr "Table de debug du module:\n"
+
+#: vms-alpha.c:7699
+#, c-format
+msgid "cannot read DMT header\n"
+msgstr "ne peut lire l'en-tête DMT\n"
+
+#: vms-alpha.c:7704
+#, c-format
+msgid " module offset: 0x%08x, size: 0x%08x, (%u psects)\n"
+msgstr " offset du module: 0x%08x, taille: 0x%08x, (%u psects)\n"
+
+#: vms-alpha.c:7714
+#, c-format
+msgid "cannot read DMT psect\n"
+msgstr "ne peut lire le psect DMT\n"
+
+#: vms-alpha.c:7717
+#, c-format
+msgid " psect start: 0x%08x, length: %u\n"
+msgstr " début psect: 0x%08x, longueur: %u\n"
+
+#: vms-alpha.c:7730
+#, c-format
+msgid "cannot read DST\n"
+msgstr "ne peut lire DST\n"
+
+#: vms-alpha.c:7740
+#, c-format
+msgid "cannot read GST\n"
+msgstr "ne peut lire GST\n"
+
+#: vms-alpha.c:7744
+#, c-format
+msgid "Global symbol table:\n"
+msgstr "Table des symboles globaux:\n"
+
+#: vms-alpha.c:7772
+#, c-format
+msgid "Image activator fixup: (major: %u, minor: %u)\n"
+msgstr "Correction de l'activateur de l'image: (majeur: %u, mineur: %u)\n"
+
+#: vms-alpha.c:7775
+#, c-format
+msgid " iaflink : 0x%08x %08x\n"
+msgstr " lien iaf : 0x%08x %08x\n"
+
+#: vms-alpha.c:7778
+#, c-format
+msgid " fixuplnk: 0x%08x %08x\n"
+msgstr " lien correctif: 0x%08x %08x\n"
+
+#: vms-alpha.c:7781
+#, c-format
+msgid " size : %u\n"
+msgstr " taille : %u\n"
+
+#: vms-alpha.c:7783
+#, c-format
+msgid " flags: 0x%08x\n"
+msgstr " fanions: 0x%08x\n"
+
+#: vms-alpha.c:7787
+#, c-format
+msgid " qrelfixoff: %5u, lrelfixoff: %5u\n"
+msgstr " qrelfixoff: %5u, lrelfixoff: %5u\n"
+
+#: vms-alpha.c:7791
+#, c-format
+msgid " qdotadroff: %5u, ldotadroff: %5u\n"
+msgstr " qdotadroff: %5u, ldotadroff: %5u\n"
+
+#: vms-alpha.c:7795
+#, c-format
+msgid " codeadroff: %5u, lpfixoff : %5u\n"
+msgstr " codeadroff: %5u, lpfixoff : %5u\n"
+
+#: vms-alpha.c:7798
+#, c-format
+msgid " chgprtoff : %5u\n"
+msgstr " chgprtoff : %5u\n"
+
+#: vms-alpha.c:7801
+#, c-format
+msgid " shlstoff : %5u, shrimgcnt : %5u\n"
+msgstr " shlstoff : %5u, shrimgcnt : %5u\n"
+
+#: vms-alpha.c:7803
+#, c-format
+msgid " shlextra : %5u, permctx : %5u\n"
+msgstr " shlextra : %5u, permctx : %5u\n"
+
+#: vms-alpha.c:7806
+#, c-format
+msgid " base_va : 0x%08x\n"
+msgstr " base_va : 0x%08x\n"
+
+#: vms-alpha.c:7808
+#, c-format
+msgid " lppsbfixoff: %5u\n"
+msgstr " lppsbfixoff: %5u\n"
+
+#: vms-alpha.c:7816
+#, c-format
+msgid " Shareable images:\n"
+msgstr " Images partageables:\n"
+
+#: vms-alpha.c:7820
+#, c-format
+msgid " %u: size: %u, flags: 0x%02x, name: %.*s\n"
+msgstr " %u: taille: %u, fanions: 0x%02x, nom: %.*s\n"
+
+#: vms-alpha.c:7827
+#, c-format
+msgid " quad-word relocation fixups:\n"
+msgstr " correctifs du réadressage des quad-mots:\n"
+
+#: vms-alpha.c:7832
+#, c-format
+msgid " long-word relocation fixups:\n"
+msgstr " correctifs du réadressage des mots longs:\n"
+
+#: vms-alpha.c:7837
+#, c-format
+msgid " quad-word .address reference fixups:\n"
+msgstr " correctifs des références quad-mots «.address»:\n"
+
+#: vms-alpha.c:7842
+#, c-format
+msgid " long-word .address reference fixups:\n"
+msgstr " correctifs des références mots longs «.address»:\n"
+
+#: vms-alpha.c:7847
+#, c-format
+msgid " Code Address Reference Fixups:\n"
+msgstr " Correctifs des références des adresses de code:\n"
+
+#: vms-alpha.c:7852
+#, c-format
+msgid " Linkage Pairs Referece Fixups:\n"
+msgstr " Correctifs des références des paires de liaison:\n"
+
+#: vms-alpha.c:7861
+#, c-format
+msgid " Change Protection (%u entries):\n"
+msgstr " Changement de protection (%u entrées):\n"
+
+#: vms-alpha.c:7866
+#, c-format
+msgid " base: 0x%08x %08x, size: 0x%08x, prot: 0x%08x "
+msgstr " base: 0x%08x %08x, taille: 0x%08x, prot: 0x%08x "
+
+#. FIXME: we do not yet support relocatable link. It is not obvious
+#. how to do it for debug infos.
+#: vms-alpha.c:8706
+msgid "%P: relocatable link is not supported\n"
+msgstr "%P: lien relocalisable pas supporté\n"
+
+#: vms-alpha.c:8776
+msgid "%P: multiple entry points: in modules %B and %B\n"
+msgstr "%P: points d'entrée multiples: dans les modules %B et %B\n"
+
+#: vms-lib.c:1423
+#, c-format
+msgid "could not open shared image '%s' from '%s'"
+msgstr "n'a pas su ouvrir l'image partagée «%s» de «%s»"
+
+#: vms-misc.c:360
+msgid "_bfd_vms_output_counted called with zero bytes"
+msgstr "_bfd_vms_output_counted appelé avec un compte de zéro octet"
+
+#: vms-misc.c:365
+msgid "_bfd_vms_output_counted called with too many bytes"
+msgstr "_bfd_vms_output_counted appelé avec trop d'octets"
+
+#: xcofflink.c:836
+#, c-format
+msgid "%s: XCOFF shared object when not producing XCOFF output"
+msgstr "%s: objet XCOFF partagé alors qu'on ne produit pas de sortie XCOFF"
+
+#: xcofflink.c:857
+#, c-format
+msgid "%s: dynamic object with no .loader section"
+msgstr "%s: objet dynamique sans section .loader"
+
+#: xcofflink.c:1416
+msgid "%B: `%s' has line numbers but no enclosing section"
+msgstr "%B: «%s» contient des numéros de lignes mais de section d'encadrement"
+
+#: xcofflink.c:1468
+msgid "%B: class %d symbol `%s' has no aux entries"
+msgstr "%B: classe %d symbole «%s» n'a pas d'entrée auxiliaire"
+
+#: xcofflink.c:1490
+msgid "%B: symbol `%s' has unrecognized csect type %d"
+msgstr "%B: symbole «%s» a un type csect %d non reconnu"
+
+#: xcofflink.c:1502
+msgid "%B: bad XTY_ER symbol `%s': class %d scnum %d scnlen %d"
+msgstr "%B: symbole XTY_ER «%s» erroné: classe %d scnum %d scnlen %d"
+
+#: xcofflink.c:1531
+msgid "%B: XMC_TC0 symbol `%s' is class %d scnlen %d"
+msgstr "%B: XMC_TC0 symbol «%s» est la classe %d scnlen %d"
+
+#: xcofflink.c:1677
+msgid "%B: csect `%s' not in enclosing section"
+msgstr "%B: csect «%s» n'est pas dans un section d'encadrement"
+
+#: xcofflink.c:1784
+msgid "%B: misplaced XTY_LD `%s'"
+msgstr "%B: XTY_LD «%s» mal placé"
+
+#: xcofflink.c:2103
+msgid "%B: reloc %s:%d not in csect"
+msgstr "%B: relocalisation %s:%d n'est pas dans csect"
+
+#: xcofflink.c:3194
+#, c-format
+msgid "%s: no such symbol"
+msgstr "%s: pas de tel symbole"
+
+#: xcofflink.c:3299
+#, c-format
+msgid "warning: attempt to export undefined symbol `%s'"
+msgstr "attention: tentative d'exportation d'un symbole non défini «%s»"
+
+#: xcofflink.c:3678
+msgid "error: undefined symbol __rtinit"
+msgstr "erreur: symbole __rtinit non défini"
+
+#: xcofflink.c:4057
+msgid "%B: loader reloc in unrecognized section `%s'"
+msgstr "%B: chargeur de relocalisation dans une section non reconnnue «%s»"
+
+#: xcofflink.c:4068
+msgid "%B: `%s' in loader reloc but not loader sym"
+msgstr "%B: «%s» est dans le chargeur de relocalisation mais pas dans celui des symboles"
+
+#: xcofflink.c:4084
+msgid "%B: loader reloc in read-only section %A"
+msgstr "%B: chargeur de relocalisation dans la section %A en lecture seule"
+
+#: xcofflink.c:5106
+#, c-format
+msgid "TOC overflow: 0x%lx > 0x10000; try -mminimal-toc when compiling"
+msgstr "Débordement de la table des entrées: 0x%lx > 0x10000; essayez l'option -mminimal-toc à la compilation"
+
+#: elf32-ia64.c:628 elf64-ia64.c:628
+msgid "%B: Can't relax br at 0x%lx in section `%A'. Please use brl or indirect branch."
+msgstr "%B: Ne peut relâcher br à 0x%lx dans la section «%A». Veuillez utiliser brl ou un branchement indirect."
+
+#: elf32-ia64.c:2284 elf64-ia64.c:2284
+msgid "@pltoff reloc against local symbol"
+msgstr "relocalisation @pltoff vers un symbole local"
+
+#: elf32-ia64.c:3687 elf64-ia64.c:3687
+#, c-format
+msgid "%s: short data segment overflowed (0x%lx >= 0x400000)"
+msgstr "%s: débordement du segment de données court (0x%lx >= 0x400000)"
+
+#: elf32-ia64.c:3698 elf64-ia64.c:3698
+#, c-format
+msgid "%s: __gp does not cover short data segment"
+msgstr "%s: __gp ne couvre pas le segment de données court"
+
+#: elf32-ia64.c:3965 elf64-ia64.c:3965
+msgid "%B: non-pic code with imm relocation against dynamic symbol `%s'"
+msgstr "%B: code non pic avec des réadressages imm vers le symbole dynamique « %s »"
+
+#: elf32-ia64.c:4032 elf64-ia64.c:4032
+msgid "%B: @gprel relocation against dynamic symbol %s"
+msgstr "%B: réadressage @gprel vers le symbole dynamique %s"
+
+#: elf32-ia64.c:4095 elf64-ia64.c:4095
+msgid "%B: linking non-pic code in a position independent executable"
+msgstr "%B: liaison de code non-pic dans un exécutable à position indépendante"
+
+#: elf32-ia64.c:4232 elf64-ia64.c:4232
+msgid "%B: @internal branch to dynamic symbol %s"
+msgstr "%B: branchement @internal vers le symbole dynamique %s"
+
+#: elf32-ia64.c:4234 elf64-ia64.c:4234
+msgid "%B: speculation fixup to dynamic symbol %s"
+msgstr "%B: spéculation d'ajustements vers le symbole dynamique %s"
+
+#: elf32-ia64.c:4236 elf64-ia64.c:4236
+msgid "%B: @pcrel relocation against dynamic symbol %s"
+msgstr "%B: réadressage @pcrel vers le symbole dynamique %s"
+
+#: elf32-ia64.c:4433 elf64-ia64.c:4433
+msgid "unsupported reloc"
+msgstr "relocalisation non supportée"
+
+#: elf32-ia64.c:4471 elf64-ia64.c:4471
+msgid "%B: missing TLS section for relocation %s against `%s' at 0x%lx in section `%A'."
+msgstr "%B: setion TLS manquante pour le réadressage %s vers « %s » à 0x%lx dans la section « %A »."
+
+#: elf32-ia64.c:4486 elf64-ia64.c:4486
+msgid "%B: Can't relax br (%s) to `%s' at 0x%lx in section `%A' with size 0x%lx (> 0x1000000)."
+msgstr "%B:Ne peut pas relâcher br (%s) sur «%s» à 0x%lx dans la section «%A» avec la taille 0x%lx (> 0x1000000)."
+
+#: elf32-ia64.c:4748 elf64-ia64.c:4748
+msgid "%B: linking trap-on-NULL-dereference with non-trapping files"
+msgstr "%B: édition de liens trap-on-NULL-dereference avec des fichiers non-trapping"
+
+#: elf32-ia64.c:4757 elf64-ia64.c:4757
+msgid "%B: linking big-endian files with little-endian files"
+msgstr "%B: édition de liens entre des fichiers à octets de poids fort et des fichiers à octets de poids faible"
+
+#: elf32-ia64.c:4766 elf64-ia64.c:4766
+msgid "%B: linking 64-bit files with 32-bit files"
+msgstr "%B: édition de liens entre fichiers 64 bits et fichiers 32 bits"
+
+#: elf32-ia64.c:4775 elf64-ia64.c:4775
+msgid "%B: linking constant-gp files with non-constant-gp files"
+msgstr "%B: édition de liens entre fichiers constant-gp et fichiers non-constant-gp"
+
+#: elf32-ia64.c:4785 elf64-ia64.c:4785
+msgid "%B: linking auto-pic files with non-auto-pic files"
+msgstr "%B: édition de liens entre fichiers auto-pic et fichiers non-auto-pic"
+
+#: peigen.c:1002 pepigen.c:1002 pex64igen.c:1002
+#, c-format
+msgid "%s: line number overflow: 0x%lx > 0xffff"
+msgstr "%s: débordement du nombre de lignes: 0x%lx > 0xffff"
+
+#: peigen.c:1029 pepigen.c:1029 pex64igen.c:1029
+msgid "Export Directory [.edata (or where ever we found it)]"
+msgstr "Répertoire d'exportation [.edata (ou là où il a été trouvé)]"
+
+#: peigen.c:1030 pepigen.c:1030 pex64igen.c:1030
+msgid "Import Directory [parts of .idata]"
+msgstr "Répertoire d'importation [faisant partie de .idata]"
+
+#: peigen.c:1031 pepigen.c:1031 pex64igen.c:1031
+msgid "Resource Directory [.rsrc]"
+msgstr "Répertoire des resources [.rsrc]"
+
+#: peigen.c:1032 pepigen.c:1032 pex64igen.c:1032
+msgid "Exception Directory [.pdata]"
+msgstr "Répertoire des exceptions [.pdata]"
+
+#: peigen.c:1033 pepigen.c:1033 pex64igen.c:1033
+msgid "Security Directory"
+msgstr "Répertoire de la sécurité"
+
+#: peigen.c:1034 pepigen.c:1034 pex64igen.c:1034
+msgid "Base Relocation Directory [.reloc]"
+msgstr "Répertoire de base du réadressage [.reloc]"
+
+#: peigen.c:1035 pepigen.c:1035 pex64igen.c:1035
+msgid "Debug Directory"
+msgstr "Répertoire de débug"
+
+#: peigen.c:1036 pepigen.c:1036 pex64igen.c:1036
+msgid "Description Directory"
+msgstr "Répertoire de description"
+
+#: peigen.c:1037 pepigen.c:1037 pex64igen.c:1037
+msgid "Special Directory"
+msgstr "Répertoire spécial"
+
+#: peigen.c:1038 pepigen.c:1038 pex64igen.c:1038
+msgid "Thread Storage Directory [.tls]"
+msgstr "Répertoire des files de stockage [.tls]"
+
+#: peigen.c:1039 pepigen.c:1039 pex64igen.c:1039
+msgid "Load Configuration Directory"
+msgstr "Répertoire de chargement de configuration"
+
+#: peigen.c:1040 pepigen.c:1040 pex64igen.c:1040
+msgid "Bound Import Directory"
+msgstr "Répertoire des importations limitées"
+
+#: peigen.c:1041 pepigen.c:1041 pex64igen.c:1041
+msgid "Import Address Table Directory"
+msgstr "Répertoire de la table d'adresse d'importation"
+
+#: peigen.c:1042 pepigen.c:1042 pex64igen.c:1042
+msgid "Delay Import Directory"
+msgstr "Répertoire des délais d'importation"
+
+#: peigen.c:1043 pepigen.c:1043 pex64igen.c:1043
+msgid "CLR Runtime Header"
+msgstr "En-tête exécutable CLR"
+
+#: peigen.c:1044 pepigen.c:1044 pex64igen.c:1044
+msgid "Reserved"
+msgstr "Réservé"
+
+#: peigen.c:1104 pepigen.c:1104 pex64igen.c:1104
+#, c-format
+msgid ""
+"\n"
+"There is an import table, but the section containing it could not be found\n"
+msgstr ""
+"\n"
+"Il y a une table d'importation, mais la section la contenant ne peut être repérée\n"
+
+#: peigen.c:1109 pepigen.c:1109 pex64igen.c:1109
+#, c-format
+msgid ""
+"\n"
+"There is an import table in %s at 0x%lx\n"
+msgstr ""
+"\n"
+"Il y a une table d'importation dans %s à 0x%lx\n"
+
+#: peigen.c:1151 pepigen.c:1151 pex64igen.c:1151
+#, c-format
+msgid ""
+"\n"
+"Function descriptor located at the start address: %04lx\n"
+msgstr ""
+"\n"
+"Descripteur de fonction localisé à l'adresse de départ: %04lx\n"
+
+#: peigen.c:1154 pepigen.c:1154 pex64igen.c:1154
+#, c-format
+msgid "\tcode-base %08lx toc (loadable/actual) %08lx/%08lx\n"
+msgstr "\tcode-base %08lx tab. des entrées (chargeable/actuel) %08lx/%08lx\n"
+
+#: peigen.c:1162 pepigen.c:1162 pex64igen.c:1162
+#, c-format
+msgid ""
+"\n"
+"No reldata section! Function descriptor not decoded.\n"
+msgstr ""
+"\n"
+"Pas de section reldata! Descripteur de fonction pas décodé.\n"
+
+#: peigen.c:1167 pepigen.c:1167 pex64igen.c:1167
+#, c-format
+msgid ""
+"\n"
+"The Import Tables (interpreted %s section contents)\n"
+msgstr ""
+"\n"
+"Les tables d'importation (contenus interprété de la section %s)\n"
+
+#: peigen.c:1170 pepigen.c:1170 pex64igen.c:1170
+#, c-format
+msgid ""
+" vma: Hint Time Forward DLL First\n"
+" Table Stamp Chain Name Thunk\n"
+msgstr ""
+" vma: Hint Temps Avant DLL Premier\n"
+" Table Estampil. Chaîne Nom Thunk\n"
+
+#: peigen.c:1218 pepigen.c:1218 pex64igen.c:1218
+#, c-format
+msgid ""
+"\n"
+"\tDLL Name: %s\n"
+msgstr ""
+"\n"
+"\tNom DLL: %s\n"
+
+#: peigen.c:1229 pepigen.c:1229 pex64igen.c:1229
+#, c-format
+msgid "\tvma: Hint/Ord Member-Name Bound-To\n"
+msgstr "\tvma: Hint/Ord Membre Lien\n"
+
+#: peigen.c:1254 pepigen.c:1254 pex64igen.c:1254
+#, c-format
+msgid ""
+"\n"
+"There is a first thunk, but the section containing it could not be found\n"
+msgstr ""
+"\n"
+"Il y a un premier «thunk», mais la section le contenant ne peut être repérée\n"
+
+#: peigen.c:1415 pepigen.c:1415 pex64igen.c:1415
+#, c-format
+msgid ""
+"\n"
+"There is an export table, but the section containing it could not be found\n"
+msgstr ""
+"\n"
+"Il y a une table d'exportation, mais la section la contenant n'a pu être repérée\n"
+
+#: peigen.c:1424 pepigen.c:1424 pex64igen.c:1424
+#, c-format
+msgid ""
+"\n"
+"There is an export table in %s, but it does not fit into that section\n"
+msgstr ""
+"\n"
+"Il y a une table d'exportation dans %s, mais elle ne rentre pas dans la section\n"
+
+#: peigen.c:1430 pepigen.c:1430 pex64igen.c:1430
+#, c-format
+msgid ""
+"\n"
+"There is an export table in %s at 0x%lx\n"
+msgstr ""
+"\n"
+"Il y a une table d'exportation dans %s à 0x%lx\n"
+
+#: peigen.c:1458 pepigen.c:1458 pex64igen.c:1458
+#, c-format
+msgid ""
+"\n"
+"The Export Tables (interpreted %s section contents)\n"
+"\n"
+msgstr ""
+"\n"
+"Les tables d'exportation (contenus interprété de la section %s)\n"
+"\n"
+
+#: peigen.c:1462 pepigen.c:1462 pex64igen.c:1462
+#, c-format
+msgid "Export Flags \t\t\t%lx\n"
+msgstr "Fanion d'exportation \t\t\t%lx\n"
+
+#: peigen.c:1465 pepigen.c:1465 pex64igen.c:1465
+#, c-format
+msgid "Time/Date stamp \t\t%lx\n"
+msgstr "Tampon Heure/Date \t\t%lx\n"
+
+#: peigen.c:1468 pepigen.c:1468 pex64igen.c:1468
+#, c-format
+msgid "Major/Minor \t\t\t%d/%d\n"
+msgstr "Majeur/Mineur \t\t\t%d/%d\n"
+
+#: peigen.c:1471 pepigen.c:1471 pex64igen.c:1471
+#, c-format
+msgid "Name \t\t\t\t"
+msgstr "Nom \t\t\t\t"
+
+#: peigen.c:1477 pepigen.c:1477 pex64igen.c:1477
+#, c-format
+msgid "Ordinal Base \t\t\t%ld\n"
+msgstr "base de nombre ordinal \t\t\t%ld\n"
+
+#: peigen.c:1480 pepigen.c:1480 pex64igen.c:1480
+#, c-format
+msgid "Number in:\n"
+msgstr "Numéro dans:\n"
+
+#: peigen.c:1483 pepigen.c:1483 pex64igen.c:1483
+#, c-format
+msgid "\tExport Address Table \t\t%08lx\n"
+msgstr "\tTable d'adresses d'exportation \t\t%08lx\n"
+
+#: peigen.c:1487 pepigen.c:1487 pex64igen.c:1487
+#, c-format
+msgid "\t[Name Pointer/Ordinal] Table\t%08lx\n"
+msgstr "\tTable [Nom pointeur/Nombre ordinal]\t%08lx\n"
+
+#: peigen.c:1490 pepigen.c:1490 pex64igen.c:1490
+#, c-format
+msgid "Table Addresses\n"
+msgstr "Table d'adresses\n"
+
+#: peigen.c:1493 pepigen.c:1493 pex64igen.c:1493
+#, c-format
+msgid "\tExport Address Table \t\t"
+msgstr "\tTable d'adresse d'exportation \t\t"
+
+#: peigen.c:1498 pepigen.c:1498 pex64igen.c:1498
+#, c-format
+msgid "\tName Pointer Table \t\t"
+msgstr "\tTable des noms de pointeurs \t\t"
+
+#: peigen.c:1503 pepigen.c:1503 pex64igen.c:1503
+#, c-format
+msgid "\tOrdinal Table \t\t\t"
+msgstr "\tTable des ordinals \t\t\t"
+
+#: peigen.c:1517 pepigen.c:1517 pex64igen.c:1517
+#, c-format
+msgid ""
+"\n"
+"Export Address Table -- Ordinal Base %ld\n"
+msgstr ""
+"\n"
+"Table d'adresses d'exportation -- base de nombre ordinal %ld\n"
+
+#: peigen.c:1536 pepigen.c:1536 pex64igen.c:1536
+msgid "Forwarder RVA"
+msgstr "Adresseur RVA"
+
+#: peigen.c:1547 pepigen.c:1547 pex64igen.c:1547
+msgid "Export RVA"
+msgstr "Exportation RVA"
+
+#: peigen.c:1554 pepigen.c:1554 pex64igen.c:1554
+#, c-format
+msgid ""
+"\n"
+"[Ordinal/Name Pointer] Table\n"
+msgstr ""
+"\n"
+"Table [Ordinal/Nom de pointeur]\n"
+
+#: peigen.c:1614 peigen.c:1797 pepigen.c:1614 pepigen.c:1797 pex64igen.c:1614
+#: pex64igen.c:1797
+#, c-format
+msgid "Warning, .pdata section size (%ld) is not a multiple of %d\n"
+msgstr "Attention, taille de la section .pdata (%ld) n'est pas un multiple de %d\n"
+
+#: peigen.c:1621 pepigen.c:1621 pex64igen.c:1621
+#, c-format
+msgid " vma:\t\t\tBegin Address End Address Unwind Info\n"
+msgstr " vma:\t\t\tDébut Adresse Fin Adresse Unwind Info\n"
+
+#: peigen.c:1623 pepigen.c:1623 pex64igen.c:1623
+#, c-format
+msgid ""
+" vma:\t\tBegin End EH EH PrologEnd Exception\n"
+" \t\tAddress Address Handler Data Address Mask\n"
+msgstr ""
+" vma:\t\tDébut Fin EH EH FinProlog Exception\n"
+" \t\tAdresse Adresse Handler Données Adresse Masque\n"
+
+#: peigen.c:1697 pepigen.c:1697 pex64igen.c:1697
+#, c-format
+msgid " Register save millicode"
+msgstr " Registre a préservé le millicode"
+
+#: peigen.c:1700 pepigen.c:1700 pex64igen.c:1700
+#, c-format
+msgid " Register restore millicode"
+msgstr " Registre a restauré le millicode"
+
+#: peigen.c:1703 pepigen.c:1703 pex64igen.c:1703
+#, c-format
+msgid " Glue code sequence"
+msgstr " Séquence du code de liants"
+
+#: peigen.c:1803 pepigen.c:1803 pex64igen.c:1803
+#, c-format
+msgid ""
+" vma:\t\tBegin Prolog Function Flags Exception EH\n"
+" \t\tAddress Length Length 32b exc Handler Data\n"
+msgstr ""
+" vma:\t\tDébut Long. Long. Fanions Gestion. EH\n"
+" \t\tAdresse Prolog. Fonction 32b exc Exception Données\n"
+
+#: peigen.c:1929 pepigen.c:1929 pex64igen.c:1929
+#, c-format
+msgid ""
+"\n"
+"\n"
+"PE File Base Relocations (interpreted .reloc section contents)\n"
+msgstr ""
+"\n"
+"\n"
+"Fichier de base des réadressages PE (contenus interprétés de la section .reloc)\n"
+
+#: peigen.c:1958 pepigen.c:1958 pex64igen.c:1958
+#, c-format
+msgid ""
+"\n"
+"Virtual Address: %08lx Chunk size %ld (0x%lx) Number of fixups %ld\n"
+msgstr ""
+"\n"
+"Adresse virtuelle: %08lx taille des morceaux %ld (0x%lx) nombre de correctifs %ld\n"
+
+#: peigen.c:1971 pepigen.c:1971 pex64igen.c:1971
+#, c-format
+msgid "\treloc %4d offset %4x [%4lx] %s"
+msgstr "\trelocalisation %4d décalage %4x [%4lx] %s"
+
+#. The MS dumpbin program reportedly ands with 0xff0f before
+#. printing the characteristics field. Not sure why. No reason to
+#. emulate it here.
+#: peigen.c:2010 pepigen.c:2010 pex64igen.c:2010
+#, c-format
+msgid ""
+"\n"
+"Characteristics 0x%x\n"
+msgstr ""
+"\n"
+"Caractéristiques 0x%x\n"
+
+#: peigen.c:2310 pepigen.c:2310 pex64igen.c:2310
+msgid "%B: unable to fill in DataDictionary[1] because .idata$2 is missing"
+msgstr "%B: impossible de remplir DataDictionary[1] car .idata$2 est manquant"
+
+#: peigen.c:2330 pepigen.c:2330 pex64igen.c:2330
+msgid "%B: unable to fill in DataDictionary[1] because .idata$4 is missing"
+msgstr "%B: impossible de remplir DataDictionary[1] car .idata$4 est manquant"
+
+#: peigen.c:2351 pepigen.c:2351 pex64igen.c:2351
+msgid "%B: unable to fill in DataDictionary[12] because .idata$5 is missing"
+msgstr "%B: impossible de remplir DataDictionary[12] car .idata$5 est manquant"
+
+#: peigen.c:2371 pepigen.c:2371 pex64igen.c:2371
+msgid "%B: unable to fill in DataDictionary[PE_IMPORT_ADDRESS_TABLE (12)] because .idata$6 is missing"
+msgstr "%B: impossible de remplir DataDictionary[PE_IMPORT_ADDRESS_TABLE (12)] car .idata$6 est manquant"
+
+#: peigen.c:2413 pepigen.c:2413 pex64igen.c:2413
+msgid "%B: unable to fill in DataDictionary[PE_IMPORT_ADDRESS_TABLE(12)] because .idata$6 is missing"
+msgstr "%B: impossible de remplir DataDictionary[PE_IMPORT_ADDRESS_TABLE(12)] car .idata$6 est manquant"
+
+#: peigen.c:2438 pepigen.c:2438 pex64igen.c:2438
+msgid "%B: unable to fill in DataDictionary[9] because __tls_used is missing"
+msgstr "%B: impossible de remplir DataDictionary[9] car __tls_used est manquant"
+
+#~ msgid "%B: error: taking the address of protected function '%s' cannot be done when making a shared library"
+#~ msgstr "%B: erreur: l'adresse de la fonction protégée « %s » ne peut être prise lors de la création d'une librairie partagée"
+
+#~ msgid "%B(%A+0x%lx): cannot reach %s"
+#~ msgstr "%B(%A+0x%lx): ne peut atteindre %s"
+
+#~ msgid "%B: warning: ignoring duplicate section `%A'\n"
+#~ msgstr "%B: attention: ignore la section dupliquée «%A»\n"
+
+#~ msgid "%B: warning: duplicate section `%A' has different size\n"
+#~ msgstr "%B: attention: section dupliquée «%A» avec des tailles différentes\n"
+
+#~ msgid "relocation references a different segment"
+#~ msgstr "la relocalisation fait référence à un segment différent"
+
+#~ msgid "%B: relocation type %d not implemented"
+#~ msgstr "%B: relocalisation de type %d pas implémentée"
+
+#~ msgid "warning: %B and %B differ in position-dependence of data addressing"
+#~ msgstr "attention: %B et %B divergent sur la dépendance de la position de l'adressage des données"
+
+#~ msgid "warning: %B and %B differ in position-dependence of code addressing"
+#~ msgstr "attention: %B et %B divergent sur la dépendance de la position de l'adressage du code"
+
+#~ msgid "Can't Make it a Short Jump"
+#~ msgstr "Impossible d'en faire un Saut Court"
+
+#~ msgid "Exceeds Long Jump Range"
+#~ msgstr "Portée dépassée pour le Saut Long"
+
+#~ msgid "Absolute address Exceeds 16 bit Range"
+#~ msgstr "L'adresse absolue déborde sur 16 bits"
+
+#~ msgid "Absolute address Exceeds 8 bit Range"
+#~ msgstr "L'adresse absolue déborde sur 8 bits"
+
+#~ msgid "Unrecognized Reloc Type"
+#~ msgstr "Type de relocalisation non reconnu"
+
+#~ msgid "corrupt or empty %s section in %B"
+#~ msgstr "section %s vide ou corrompue dans %B"
+
+#~ msgid "%s: invalid DSO for symbol `%s' definition"
+#~ msgstr "%s: DSO incorrect pour la définition du symbole «%s»"
+
+#~ msgid "%B: %A+0x%lx: jump to stub routine which is not jal"
+#~ msgstr "%B: %A+0x%lx: saut vers la routine dans la partie de l'ébauche (stub) qui n'est pas jal"
+
+#~ msgid "bfd_make_section (%s) failed"
+#~ msgstr "Échec de bfd_make_section (%s)"
+
+#~ msgid "bfd_set_section_flags (%s, %x) failed"
+#~ msgstr "bfd_set_section_flags (%s, %x) a échoué"
+
+#~ msgid "Size mismatch section %s=%lx, %s=%lx"
+#~ msgstr "Taille de section ne concorde pas %s=%lx, %s=%lx"
+
+#~ msgid "failed to enter %s"
+#~ msgstr "échec d'insertion de %s"
+
+#~ msgid "No Mem !"
+#~ msgstr "Mémoire épuisée!"
+
+#~ msgid "reserved STO cmd %d"
+#~ msgstr "commande STO %d réservée"
+
+#~ msgid "reserved OPR cmd %d"
+#~ msgstr "commande OPR %d réservée"
+
+#~ msgid "reserved CTL cmd %d"
+#~ msgstr "commande CTL %d réservée"
+
+#~ msgid "reserved STC cmd %d"
+#~ msgstr "commande STC %d réservée"
+
+#~ msgid "stack-from-image not implemented"
+#~ msgstr "pile depuis l'image non implémentée"
+
+#~ msgid "stack-entry-mask not fully implemented"
+#~ msgstr "masque de pile d'entrée pas complètement implémenté"
+
+#~ msgid "PASSMECH not fully implemented"
+#~ msgstr "PASSMECH pas complètement implémenté"
+
+#~ msgid "stack-local-symbol not fully implemented"
+#~ msgstr "symbole local de pile pas complètement implémenté"
+
+#~ msgid "stack-literal not fully implemented"
+#~ msgstr "litéral de pile pas complètement implémenté"
+
+#~ msgid "stack-local-symbol-entry-point-mask not fully implemented"
+#~ msgstr "masque du symbole local de point d'entrée de pile pas complètement implémenté"
+
+#~ msgid "%s: not fully implemented"
+#~ msgstr "%s: pas complètement implémenté"
+
+#~ msgid "obj code %d not found"
+#~ msgstr "code objet %d non repéré"
+
+#~ msgid "Reloc size error in section %s"
+#~ msgstr "Erreur de taille de relocalisation dans la section %s"
diff --git a/bfd/po/id.gmo b/bfd/po/id.gmo
new file mode 100644
index 0000000..46b2f30
--- /dev/null
+++ b/bfd/po/id.gmo
Binary files differ
diff --git a/bfd/po/id.po b/bfd/po/id.po
new file mode 100644
index 0000000..018d716
--- /dev/null
+++ b/bfd/po/id.po
@@ -0,0 +1,4163 @@
+# Pesan Bahasa Indonesia untuk BFD
+# Copyright (C) 2008 Free Software Foundation, Inc.
+# This file is distributed under the same license as the binutils package.
+# Arif E. Nugroho <arif_endro@yahoo.com>, 2008, 2009.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: bfd 2.20\n"
+"Report-Msgid-Bugs-To: bug-binutils@gnu.org\n"
+"POT-Creation-Date: 2009-09-07 14:05+0200\n"
+"PO-Revision-Date: 2009-11-11 08:00+0700\n"
+"Last-Translator: Arif E. Nugroho <arif_endro@yahoo.com>\n"
+"Language-Team: Indonesian <translation-team-id@lists.sourceforge.net>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=ISO-8859-1\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: aout-adobe.c:127
+msgid "%B: Unknown section type in a.out.adobe file: %x\n"
+msgstr "%B: Tipe bagian tidak diketahui dalam berkas a.out.adobe: %x\n"
+
+#: aout-cris.c:204
+#, c-format
+msgid "%s: Invalid relocation type exported: %d"
+msgstr "%s: Tipe relokasi tidak valid terekspor: %d"
+
+#: aout-cris.c:247
+msgid "%B: Invalid relocation type imported: %d"
+msgstr "%B: Tipe relokasi tidak valid terimpor: %d"
+
+#: aout-cris.c:258
+msgid "%B: Bad relocation record imported: %d"
+msgstr "%B: Catatan relokasi buruk terimpor: %d"
+
+#: aoutx.h:1271 aoutx.h:1609
+#, c-format
+msgid "%s: can not represent section `%s' in a.out object file format"
+msgstr "%s: tidak dapat merepresentasikan bagian `%s' dalam a.out objek format berkas"
+
+#: aoutx.h:1575
+#, c-format
+msgid "%s: can not represent section for symbol `%s' in a.out object file format"
+msgstr "%s: tidak dapat merepresentasikan bagian untuk simbol `%s' dalam format berkas a.out objek"
+
+#: aoutx.h:1577
+msgid "*unknown*"
+msgstr "*tidak diketahui*"
+
+#: aoutx.h:3994 aoutx.h:4320
+msgid "%P: %B: unexpected relocation type\n"
+msgstr "%P: %B: tipe relokasi tidak diduga\n"
+
+#: aoutx.h:5354
+#, c-format
+msgid "%s: relocatable link from %s to %s not supported"
+msgstr "%s: link relokasi dari %s ke %s tidak didukung"
+
+#: archive.c:2056
+msgid "Warning: writing archive was slow: rewriting timestamp\n"
+msgstr "Peringatan: penulisan archive lambat: menulis ulang timestamp\n"
+
+#: archive.c:2342
+msgid "Reading archive file mod timestamp"
+msgstr "Membaca berkas mod timestamp archive"
+
+#: archive.c:2366
+msgid "Writing updated armap timestamp"
+msgstr "Menulis armap timestamp terupdate"
+
+#: bfd.c:375
+msgid "No error"
+msgstr "Tidak error"
+
+#: bfd.c:376
+msgid "System call error"
+msgstr "Pemanggilan sistem error"
+
+#: bfd.c:377
+msgid "Invalid bfd target"
+msgstr "Target bfd tidak valid"
+
+#: bfd.c:378
+msgid "File in wrong format"
+msgstr "Berkas dalam format salah"
+
+#: bfd.c:379
+msgid "Archive object file in wrong format"
+msgstr "Archive berkas objek dalam format salah"
+
+#: bfd.c:380
+msgid "Invalid operation"
+msgstr "Operasi tidak valid"
+
+#: bfd.c:381
+msgid "Memory exhausted"
+msgstr "Kehabisan memori"
+
+#: bfd.c:382
+msgid "No symbols"
+msgstr "Bukan simbol"
+
+#: bfd.c:383
+msgid "Archive has no index; run ranlib to add one"
+msgstr "Archive tidak memiliki indek; jalankan ranlib untuk menambahkan satu"
+
+#: bfd.c:384
+msgid "No more archived files"
+msgstr "Tidak lagi berkas yang ter-archive"
+
+#: bfd.c:385
+msgid "Malformed archive"
+msgstr "Archive tidak terformat"
+
+#: bfd.c:386
+msgid "File format not recognized"
+msgstr "Berkas format tidak dikenal"
+
+#: bfd.c:387
+msgid "File format is ambiguous"
+msgstr "Berkas format ambigu"
+
+#: bfd.c:388
+msgid "Section has no contents"
+msgstr "Bagian tidak memiliki isi"
+
+#: bfd.c:389
+msgid "Nonrepresentable section on output"
+msgstr "Bagian tidak dapat direpresentasikan di keluaran"
+
+#: bfd.c:390
+msgid "Symbol needs debug section which does not exist"
+msgstr "Simbol membutuhkan bagian debug yang mana bagian tersebut tidak ada"
+
+#: bfd.c:391
+msgid "Bad value"
+msgstr "Nilai buruk"
+
+#: bfd.c:392
+msgid "File truncated"
+msgstr "Berkas terpotong"
+
+#: bfd.c:393
+msgid "File too big"
+msgstr "Berkas terlalu besar"
+
+#: bfd.c:394
+#, c-format
+msgid "Error reading %s: %s"
+msgstr "Error membaca %s: %s"
+
+#: bfd.c:395
+msgid "#<Invalid error code>"
+msgstr "#<Kode error tidak valid>"
+
+#: bfd.c:919
+#, c-format
+msgid "BFD %s assertion fail %s:%d"
+msgstr "BFD %s assertion gagal %s:%d"
+
+#: bfd.c:931
+#, c-format
+msgid "BFD %s internal error, aborting at %s line %d in %s\n"
+msgstr "BFD %s error internal, menggagalkan di %s baris %d dalam %s\n"
+
+#: bfd.c:935
+#, c-format
+msgid "BFD %s internal error, aborting at %s line %d\n"
+msgstr "BFD %s error internal, menggagalkan di %s baris %d\n"
+
+#: bfd.c:937
+msgid "Please report this bug.\n"
+msgstr "Tolong laporkan bug ini.\n"
+
+#: bfdwin.c:206
+#, c-format
+msgid "not mapping: data=%lx mapped=%d\n"
+msgstr "tidak termap: data=%lx mapped=%d\n"
+
+#: bfdwin.c:209
+#, c-format
+msgid "not mapping: env var not set\n"
+msgstr "tidak termap; env var tidak terset\n"
+
+#: binary.c:284
+#, c-format
+msgid "Warning: Writing section `%s' to huge (ie negative) file offset 0x%lx."
+msgstr "Peringatan: Menulis bagian `%s' terlalu besar (ie negatif) berkas ofset 0x%lx."
+
+#: bout.c:1150 elf-m10300.c:2078 elf32-avr.c:1639 elf32-frv.c:5743
+#: elf32-xtensa.c:6639 elfxx-sparc.c:2456 reloc.c:5386 reloc16.c:162
+#: vms.c:1918 elf32-ia64.c:788 elf64-ia64.c:788
+msgid "%P%F: --relax and -r may not be used together\n"
+msgstr "%P%F: --relax dan -r tidak boleh digunakan secara bersamaan\n"
+
+#: cache.c:226
+msgid "reopening %B: %s\n"
+msgstr "membuka kembali %B: %s\n"
+
+#: coff-alpha.c:490
+msgid ""
+"%B: Cannot handle compressed Alpha binaries.\n"
+" Use compiler flags, or objZ, to generate uncompressed binaries."
+msgstr ""
+"%B: Tidak dapat menangani binari yang dikompres Alpha.\n"
+" Menggunakan tanda kompiler, atau objZ, untuk menghasilkan binari tidak terkompres."
+
+#: coff-alpha.c:647
+msgid "%B: unknown/unsupported relocation type %d"
+msgstr "%B; tidak diketahui/tidak didukung tipe relokasi %d"
+
+#: coff-alpha.c:899 coff-alpha.c:936 coff-alpha.c:2024 coff-mips.c:1003
+msgid "GP relative relocation used when GP not defined"
+msgstr "GP relatif relokasi digunakan ketika GP tidak didefinisikan"
+
+#: coff-alpha.c:1501
+msgid "using multiple gp values"
+msgstr "menggunakan nilai gp multiple"
+
+#: coff-alpha.c:1560
+msgid "%B: unsupported relocation: ALPHA_R_GPRELHIGH"
+msgstr "%B: relokasi tidak didukung: ALPHA_R_GPRELHIGH"
+
+#: coff-alpha.c:1567
+msgid "%B: unsupported relocation: ALPHA_R_GPRELLOW"
+msgstr "%B: relokasi tidak didukung: ALPHA_R_GPRELLOW"
+
+#: coff-alpha.c:1574 elf32-m32r.c:2477 elf64-alpha.c:3943 elf64-alpha.c:4098
+#: elf32-ia64.c:4462 elf64-ia64.c:4462
+msgid "%B: unknown relocation type %d"
+msgstr "%B: tipe relokasi %d tidak diketahui"
+
+#: coff-arm.c:1039
+#, c-format
+msgid "%B: unable to find THUMB glue '%s' for `%s'"
+msgstr "%B: tidak dapat menemukan lem THUMB '%s' untuk `%s'"
+
+#: coff-arm.c:1068
+#, c-format
+msgid "%B: unable to find ARM glue '%s' for `%s'"
+msgstr "%B: tidak dapat menemukan lem ARM '%s' untuk `%s'"
+
+#: coff-arm.c:1370 elf32-arm.c:6372
+#, c-format
+msgid ""
+"%B(%s): warning: interworking not enabled.\n"
+" first occurrence: %B: arm call to thumb"
+msgstr ""
+"%B(%s): peringatan: antar-kerja tidak diaktifkan.\n"
+" pertemuan pertama: %B: arm panggil ke thumb"
+
+#: coff-arm.c:1460
+#, c-format
+msgid ""
+"%B(%s): warning: interworking not enabled.\n"
+" first occurrence: %B: thumb call to arm\n"
+" consider relinking with --support-old-code enabled"
+msgstr ""
+"%B(%s): peringatan: antar-kerja tidak diaktifkan.\n"
+" pertemuan pertama: %B: panggilan thumb ke arm\n"
+" pertimbangkan relinking dengan --support-old-code aktif"
+
+#: coff-arm.c:1755 coff-tic80.c:695 cofflink.c:3027
+msgid "%B: bad reloc address 0x%lx in section `%A'"
+msgstr "%B: alamat relokasi buruk 0x%lx dalam bagian `%A'"
+
+#: coff-arm.c:2080
+msgid "%B: illegal symbol index in reloc: %d"
+msgstr "%B: indek simbol ilegal dalam relokasi: %d"
+
+#: coff-arm.c:2211
+#, c-format
+msgid "error: %B is compiled for APCS-%d, whereas %B is compiled for APCS-%d"
+msgstr "error: %B dikompile untuk APCS-%d, dimana %B dikompile untuk APCS-%d"
+
+#: coff-arm.c:2227 elf32-arm.c:10327
+#, c-format
+msgid "error: %B passes floats in float registers, whereas %B passes them in integer registers"
+msgstr "error: %B melewati float dalam register float, dimana %B melewatinya register integer"
+
+#: coff-arm.c:2230 elf32-arm.c:10331
+#, c-format
+msgid "error: %B passes floats in integer registers, whereas %B passes them in float registers"
+msgstr "error: %B melewati float dalam register integer, dimana %B melewatinya float register"
+
+#: coff-arm.c:2244
+#, c-format
+msgid "error: %B is compiled as position independent code, whereas target %B is absolute position"
+msgstr "error: %B dikompile sebagai kode bebas posisi, dimana target %B yang memiliki posisi absolute"
+
+#: coff-arm.c:2247
+#, c-format
+msgid "error: %B is compiled as absolute position code, whereas target %B is position independent"
+msgstr "error: %B dikompile sebagai kode absolute posisi, dimana target %B adalah bebas posisi"
+
+#: coff-arm.c:2275 elf32-arm.c:10396
+#, c-format
+msgid "Warning: %B supports interworking, whereas %B does not"
+msgstr "Peringatan: %B mendukung antar-kerja, dimana %B tidak"
+
+#: coff-arm.c:2278 elf32-arm.c:10402
+#, c-format
+msgid "Warning: %B does not support interworking, whereas %B does"
+msgstr "Peringatan: %B tidak mendukung antar-kerja, dimana %B ya"
+
+#: coff-arm.c:2302
+#, c-format
+msgid "private flags = %x:"
+msgstr "tanda private = %x:"
+
+#: coff-arm.c:2310 elf32-arm.c:10453
+#, c-format
+msgid " [floats passed in float registers]"
+msgstr " [floats melewati dalam register float]"
+
+#: coff-arm.c:2312
+#, c-format
+msgid " [floats passed in integer registers]"
+msgstr " [float melewati register integer]"
+
+#: coff-arm.c:2315 elf32-arm.c:10456
+#, c-format
+msgid " [position independent]"
+msgstr " [bebas posisi]"
+
+#: coff-arm.c:2317
+#, c-format
+msgid " [absolute position]"
+msgstr " [absolute posisi]"
+
+#: coff-arm.c:2321
+#, c-format
+msgid " [interworking flag not initialised]"
+msgstr " [tanda antar-kerja tidak terinisialisasi]"
+
+#: coff-arm.c:2323
+#, c-format
+msgid " [interworking supported]"
+msgstr " [antar-kerja didukung]"
+
+#: coff-arm.c:2325
+#, c-format
+msgid " [interworking not supported]"
+msgstr " [antar-kerja tidak didukung]"
+
+#: coff-arm.c:2371 elf32-arm.c:9360
+#, c-format
+msgid "Warning: Not setting interworking flag of %B since it has already been specified as non-interworking"
+msgstr "Peringatan: Tidak menset tanda antar-kerja dari %B karena itu telah terspesifikasi sebagai bukan-antar-kerja"
+
+#: coff-arm.c:2375 elf32-arm.c:9364
+#, c-format
+msgid "Warning: Clearing the interworking flag of %B due to outside request"
+msgstr "Peringatan: Menghapus tanda antar-kerja dari %B karena diluar permintaan"
+
+#: coff-h8300.c:1122
+#, c-format
+msgid "cannot handle R_MEM_INDIRECT reloc when using %s output"
+msgstr "tidak dapat menangani R_MEM_INDIRECT relokasi ketika menggunakan keluaran %s"
+
+#: coff-i860.c:147
+#, c-format
+msgid "Relocation `%s' not yet implemented\n"
+msgstr "Relokasi `%s' belum terimplementasi\n"
+
+#: coff-i860.c:605 coff-tic54x.c:398 coffcode.h:5143
+msgid "%B: warning: illegal symbol index %ld in relocs"
+msgstr "%B: peringatan: indek simbol ilegal %ld dalam relokasi"
+
+#: coff-i960.c:143 coff-i960.c:506
+msgid "uncertain calling convention for non-COFF symbol"
+msgstr "tidak tentu pemanggilan konvensi untuk non-COFF simbol"
+
+#: coff-m68k.c:506 elf32-bfin.c:5693 elf32-cr16.c:2965 elf32-m68k.c:4615
+msgid "unsupported reloc type"
+msgstr "tipe relokasi tidak didukung"
+
+#: coff-maxq.c:126
+msgid "Can't Make it a Short Jump"
+msgstr "Tidak dapat membuka ini sebuah lompatan pendek"
+
+#: coff-maxq.c:191
+msgid "Exceeds Long Jump Range"
+msgstr "Melewati jangkauan lompatan panjang"
+
+#: coff-maxq.c:202 coff-maxq.c:276
+msgid "Absolute address Exceeds 16 bit Range"
+msgstr "Alamat absolut melewati jangkauan 16 bit"
+
+#: coff-maxq.c:240
+msgid "Absolute address Exceeds 8 bit Range"
+msgstr "Alamat absolute melewati jangkauan 8 bit"
+
+#: coff-maxq.c:333
+msgid "Unrecognized Reloc Type"
+msgstr "Tipe relokasi tidak dikenal"
+
+#: coff-mips.c:688 elf32-mips.c:1014 elf32-score.c:441 elf32-score7.c:341
+#: elf64-mips.c:2018 elfn32-mips.c:1832
+msgid "GP relative relocation when _gp not defined"
+msgstr "GP relokasi relatif ketika _gp tidak terdefinisi"
+
+#: coff-or32.c:229
+msgid "Unrecognized reloc"
+msgstr "Relokasi tidak dikenal"
+
+#: coff-rs6000.c:2787
+#, c-format
+msgid "%s: unsupported relocation type 0x%02x"
+msgstr "%s: tipe relokasi tidak didukung 0x%02x"
+
+#: coff-rs6000.c:2880
+#, c-format
+msgid "%s: TOC reloc at 0x%x to symbol `%s' with no TOC entry"
+msgstr "%s: TOC relokasi di 0x%x untuk simbol `%s' dengan tidak ada masukan TOC"
+
+#: coff-rs6000.c:3646 coff64-rs6000.c:2168
+msgid "%B: symbol `%s' has unrecognized smclas %d"
+msgstr "%B: simbol `%s' memiliki smclas tidak dikenal %d"
+
+#: coff-tic4x.c:195 coff-tic54x.c:299 coff-tic80.c:458
+#, c-format
+msgid "Unrecognized reloc type 0x%x"
+msgstr "Tipe relokasi tidak dikenal 0x%x"
+
+#: coff-tic4x.c:240
+#, c-format
+msgid "%s: warning: illegal symbol index %ld in relocs"
+msgstr "%s: peringatan: indek simbol ilegal %ld dalam relokasi"
+
+#: coff-w65.c:367
+#, c-format
+msgid "ignoring reloc %s\n"
+msgstr "mengabaikan relokasi %s\n"
+
+#: coffcode.h:960
+msgid "%B: warning: COMDAT symbol '%s' does not match section name '%s'"
+msgstr "%B: peringatan: COMDAT simbol '%s' tidak cocok dengan nama bagian '%s'"
+
+#. Generate a warning message rather using the 'unhandled'
+#. variable as this will allow some .sys files generate by
+#. other toolchains to be processed. See bugzilla issue 196.
+#: coffcode.h:1176
+msgid "%B: Warning: Ignoring section flag IMAGE_SCN_MEM_NOT_PAGED in section %s"
+msgstr "%B: Peringatan: Mengabaikan tanda bagian IMAGE_SCN_MEM_NOT_PAGED dalam bagian %s"
+
+#: coffcode.h:1240
+msgid "%B (%s): Section flag %s (0x%x) ignored"
+msgstr "%B (%s): Tanda bagian %s (0x%x) diabaikan"
+
+#: coffcode.h:2382
+#, c-format
+msgid "Unrecognized TI COFF target id '0x%x'"
+msgstr "Target id '0x%x' TI COFF tidak dikenal"
+
+#: coffcode.h:2696
+msgid "%B: reloc against a non-existant symbol index: %ld"
+msgstr "%B: relokasi terhadap simbol indek yang tidak ada: %ld"
+
+#: coffcode.h:3669
+msgid "%B: section %s: string table overflow at offset %ld"
+msgstr "%B: bagian %s: tabel string overflow di offset %ld"
+
+#: coffcode.h:4477
+msgid "%B: warning: line number table read failed"
+msgstr "%B: peringatan: pembacaan tabel nomor baris gagal"
+
+#: coffcode.h:4507
+msgid "%B: warning: illegal symbol index %ld in line numbers"
+msgstr "%B: peringatan: simbol index %ld ilegal dalam nomor baris"
+
+#: coffcode.h:4521
+msgid "%B: warning: duplicate line number information for `%s'"
+msgstr "%B: peringatan: duplikasi informasi nomor baris untuk `%s'"
+
+#: coffcode.h:4912
+msgid "%B: Unrecognized storage class %d for %s symbol `%s'"
+msgstr "%B: kelas %d penyimpanan tidak dikenal untuk %s simbol `%s'"
+
+#: coffcode.h:5038
+msgid "warning: %B: local symbol `%s' has no section"
+msgstr "peringatan: %B: simbol lokal `%s' tidak memiliki bagian"
+
+#: coffcode.h:5181
+msgid "%B: illegal relocation type %d at address 0x%lx"
+msgstr "%B: tipe relokasi %d ilegal di alamat 0x%lx"
+
+#: coffgen.c:1571
+msgid "%B: bad string table size %lu"
+msgstr "%B: string buruk ukuran tabel %lu"
+
+#: cofflink.c:513 elflink.c:4307
+msgid "Warning: type of symbol `%s' changed from %d to %d in %B"
+msgstr "Peringatan: tipe dari simbole `%s' berubah dari %d ke %d dalam %B"
+
+#: cofflink.c:2305
+msgid "%B: relocs in section `%A', but it has no contents"
+msgstr "%B: relokasi dalam bagian `%A', tetapi ini tidak memiliki isi"
+
+#: cofflink.c:2636 coffswap.h:826
+#, c-format
+msgid "%s: %s: reloc overflow: 0x%lx > 0xffff"
+msgstr "%s: %s: relokasi overflow: 0x%lx > 0xffff"
+
+#: cofflink.c:2645 coffswap.h:812
+#, c-format
+msgid "%s: warning: %s: line number overflow: 0x%lx > 0xffff"
+msgstr "%s: peringatan: %s: nomor baris overflow: 0x%lx > 0xffff"
+
+#: cpu-arm.c:189 cpu-arm.c:200
+msgid "error: %B is compiled for the EP9312, whereas %B is compiled for XScale"
+msgstr "error: %B dikompile untuk EP9312, dimana %B dikompile untuk XScale"
+
+#: cpu-arm.c:332
+#, c-format
+msgid "warning: unable to update contents of %s section in %s"
+msgstr "peringatan: tidak dapat mengupdate isi dari %s bagian dalam %s"
+
+#: dwarf2.c:430
+#, c-format
+msgid "Dwarf Error: Can't find %s section."
+msgstr "Dwarf Error: Tidak dapat menemukan bagian %s."
+
+#: dwarf2.c:457
+#, c-format
+msgid "Dwarf Error: unable to decompress %s section."
+msgstr "Dwarf Error: tidak dapat mengekstrak bagian %s."
+
+#: dwarf2.c:468
+#, c-format
+msgid "Dwarf Error: Offset (%lu) greater than or equal to %s size (%lu)."
+msgstr "Dwarf Error: Ofset (%lu) lebih besar atau sama dengan %s ukuran (%lu)."
+
+#: dwarf2.c:865
+#, c-format
+msgid "Dwarf Error: Invalid or unhandled FORM value: %u."
+msgstr "Dwarf Error: Tidak valid atau nilai FORM tidak tertangani: %u."
+
+#: dwarf2.c:1079
+msgid "Dwarf Error: mangled line number section (bad file number)."
+msgstr "Dwarf Error: mangled bagian nomor baris (nomor berkas buruk)."
+
+#: dwarf2.c:1413
+msgid "Dwarf Error: mangled line number section."
+msgstr "Dwarf Error: mangled bagian nomor baris."
+
+#: dwarf2.c:1760 dwarf2.c:1867 dwarf2.c:2139
+#, c-format
+msgid "Dwarf Error: Could not find abbrev number %u."
+msgstr "Dwarf Error: Tidak dapat menemukan nomor singkat %u."
+
+#: dwarf2.c:2100
+#, c-format
+msgid "Dwarf Error: found dwarf version '%u', this reader only handles version 2 and 3 information."
+msgstr "Dwarf Error: menemukan versi dwarf '%u', pembaca ini hanya menangani informasi versi 2 dan 3."
+
+#: dwarf2.c:2107
+#, c-format
+msgid "Dwarf Error: found address size '%u', this reader can not handle sizes greater than '%u'."
+msgstr "Dwarf Error: menemukan ukuran alamat '%u', pembaca ini tidak dapat menangani ukuran lebih besar dari '%u'."
+
+#: dwarf2.c:2130
+#, c-format
+msgid "Dwarf Error: Bad abbrev number: %u."
+msgstr "Dwarf Error: Nomor singkat buruk: %u."
+
+#: ecoff.c:1238
+#, c-format
+msgid "Unknown basic type %d"
+msgstr "Tipe dasar %d tidak diketahui"
+
+#: ecoff.c:1495
+#, c-format
+msgid ""
+"\n"
+" End+1 symbol: %ld"
+msgstr ""
+"\n"
+" Simbol End+1: %ld"
+
+#: ecoff.c:1502 ecoff.c:1505
+#, c-format
+msgid ""
+"\n"
+" First symbol: %ld"
+msgstr ""
+"\n"
+" Simbol pertama: %ld"
+
+#: ecoff.c:1517
+#, c-format
+msgid ""
+"\n"
+" End+1 symbol: %-7ld Type: %s"
+msgstr ""
+"\n"
+" Simbol End+1: %-7ld Tipe: %s"
+
+#: ecoff.c:1524
+#, c-format
+msgid ""
+"\n"
+" Local symbol: %ld"
+msgstr ""
+"\n"
+" Simbol lokal: %ld"
+
+#: ecoff.c:1532
+#, c-format
+msgid ""
+"\n"
+" struct; End+1 symbol: %ld"
+msgstr ""
+"\n"
+" struct; simbol End+1: %ld"
+
+#: ecoff.c:1537
+#, c-format
+msgid ""
+"\n"
+" union; End+1 symbol: %ld"
+msgstr ""
+"\n"
+" union: End+1 simbol: %ld"
+
+#: ecoff.c:1542
+#, c-format
+msgid ""
+"\n"
+" enum; End+1 symbol: %ld"
+msgstr ""
+"\n"
+" enum; End+1 simbol: %ld"
+
+#: ecoff.c:1548
+#, c-format
+msgid ""
+"\n"
+" Type: %s"
+msgstr ""
+"\n"
+" Tipe: %s"
+
+#: elf-attrs.c:567
+msgid "error: %B: Must be processed by '%s' toolchain"
+msgstr "error: %B: Harus diproses dengan '%s' toolchain"
+
+#: elf-attrs.c:575
+msgid "error: %B: Object tag '%d, %s' is incompatible with tag '%d, %s'"
+msgstr "error: %B: Objek tag '%d, %s' tidak kompatibel dengan tag '%d, %s'"
+
+#: elf-eh-frame.c:884
+msgid "%P: error in %B(%A); no .eh_frame_hdr table will be created.\n"
+msgstr "%P: error dalam %B(%A); tidak ada .eh_frame_hdr tabel yang akan dibuat.\n"
+
+#: elf-eh-frame.c:1122
+msgid "%P: fde encoding in %B(%A) prevents .eh_frame_hdr table being created.\n"
+msgstr "%P: fde enkoding dalam %B(%A) menjaga .eh_frame_hdr tabel untuk dibuat.\n"
+
+#: elf-ifunc.c:179
+msgid "%F%P: dynamic STT_GNU_IFUNC symbol `%s' with pointer equality in `%B' can not be used when making an executable; recompile with -fPIE and relink with -pie\n"
+msgstr "%F%P: dynamic STT_GNU_IFUNC simbol '%s' dengan penunjuk persamaan dalam `%B' tidak dapat digunakan ketika membuat sebuah pelaksana; rekompilasi dengan -fPIE dan hubungkan kembali dengan -pie\n"
+
+#: elf-m10200.c:456 elf-m10300.c:1575 elf32-avr.c:1251 elf32-bfin.c:3200
+#: elf32-cr16.c:1517 elf32-cr16c.c:790 elf32-cris.c:2089 elf32-crx.c:933
+#: elf32-d10v.c:516 elf32-fr30.c:616 elf32-frv.c:4114 elf32-h8300.c:516
+#: elf32-i860.c:1218 elf32-ip2k.c:1499 elf32-iq2000.c:691 elf32-lm32.c:1171
+#: elf32-m32c.c:560 elf32-m32r.c:3102 elf32-m68hc1x.c:1136 elf32-mep.c:541
+#: elf32-microblaze.c:1226 elf32-moxie.c:291 elf32-msp430.c:493 elf32-mt.c:402
+#: elf32-openrisc.c:411 elf32-score.c:2752 elf32-score7.c:2591
+#: elf32-spu.c:5045 elf32-v850.c:1701 elf32-xstormy16.c:948 elf64-mmix.c:1533
+msgid "internal error: out of range error"
+msgstr "internal error: diluar jangkauan error"
+
+#: elf-m10200.c:460 elf-m10300.c:1579 elf32-avr.c:1255 elf32-bfin.c:3204
+#: elf32-cr16.c:1521 elf32-cr16c.c:794 elf32-cris.c:2093 elf32-crx.c:937
+#: elf32-d10v.c:520 elf32-fr30.c:620 elf32-frv.c:4118 elf32-h8300.c:520
+#: elf32-i860.c:1222 elf32-iq2000.c:695 elf32-lm32.c:1175 elf32-m32c.c:564
+#: elf32-m32r.c:3106 elf32-m68hc1x.c:1140 elf32-mep.c:545
+#: elf32-microblaze.c:1230 elf32-moxie.c:295 elf32-msp430.c:497
+#: elf32-openrisc.c:415 elf32-score.c:2756 elf32-score7.c:2595
+#: elf32-spu.c:5049 elf32-v850.c:1705 elf32-xstormy16.c:952 elf64-mmix.c:1537
+#: elfxx-mips.c:9103
+msgid "internal error: unsupported relocation error"
+msgstr "internal error: relokasi tidak didukung error"
+
+#: elf-m10200.c:464 elf32-cr16.c:1525 elf32-cr16c.c:798 elf32-crx.c:941
+#: elf32-d10v.c:524 elf32-h8300.c:524 elf32-lm32.c:1179 elf32-m32r.c:3110
+#: elf32-m68hc1x.c:1144 elf32-microblaze.c:1234 elf32-score.c:2760
+#: elf32-score7.c:2599 elf32-spu.c:5053
+msgid "internal error: dangerous error"
+msgstr "internal error error berbahaya"
+
+#: elf-m10200.c:468 elf-m10300.c:1592 elf32-avr.c:1263 elf32-bfin.c:3212
+#: elf32-cr16.c:1529 elf32-cr16c.c:802 elf32-cris.c:2101 elf32-crx.c:945
+#: elf32-d10v.c:528 elf32-fr30.c:628 elf32-frv.c:4126 elf32-h8300.c:528
+#: elf32-i860.c:1230 elf32-ip2k.c:1514 elf32-iq2000.c:703 elf32-lm32.c:1183
+#: elf32-m32c.c:572 elf32-m32r.c:3114 elf32-m68hc1x.c:1148 elf32-mep.c:553
+#: elf32-microblaze.c:1238 elf32-moxie.c:303 elf32-msp430.c:505 elf32-mt.c:410
+#: elf32-openrisc.c:423 elf32-score.c:2769 elf32-score7.c:2603
+#: elf32-spu.c:5057 elf32-v850.c:1725 elf32-xstormy16.c:960 elf64-mmix.c:1545
+msgid "internal error: unknown error"
+msgstr "internal error: error tidak diketahui"
+
+#: elf-m10300.c:1512 elf32-arm.c:8963 elf32-i386.c:3984 elf32-m32r.c:2588
+#: elf32-m68k.c:4099 elf32-ppc.c:7906 elf32-s390.c:3015 elf32-sh.c:3429
+#: elf32-xtensa.c:3027 elf64-ppc.c:12063 elf64-s390.c:2974 elf64-sh64.c:1648
+#: elf64-x86-64.c:3657 elfxx-sparc.c:3317
+msgid "%B(%A+0x%lx): unresolvable %s relocation against symbol `%s'"
+msgstr "%B(%A+0x%lx): tidak teresolf %s relokasi terhadap simbol `%s'"
+
+#: elf-m10300.c:1584
+msgid "error: inappropriate relocation type for shared library (did you forget -fpic?)"
+msgstr "error: tipe relokasi tidak sesuai untuk shared library (apakah anda lupa -fpic?)"
+
+#: elf-m10300.c:1587
+msgid "internal error: suspicious relocation type used in shared library"
+msgstr "internal erro: suspicious tipe relokasi digunakan dalam shared library"
+
+#: elf-m10300.c:4385 elf32-arm.c:11346 elf32-cr16.c:2519 elf32-cris.c:3030
+#: elf32-hppa.c:1891 elf32-i370.c:506 elf32-i386.c:1975 elf32-lm32.c:1873
+#: elf32-m32r.c:1921 elf32-m68k.c:3188 elf32-ppc.c:4953 elf32-s390.c:1650
+#: elf32-sh.c:2574 elf32-vax.c:1052 elf64-ppc.c:6348 elf64-s390.c:1623
+#: elf64-sh64.c:3396 elf64-x86-64.c:1821 elfxx-sparc.c:1802
+#, c-format
+msgid "dynamic variable `%s' is zero size"
+msgstr "variabel dinamik `%s' memiliki ukuran nol"
+
+#: elf.c:329
+msgid "%B: invalid string offset %u >= %lu for section `%s'"
+msgstr "%B: string ofset tidak valid %u >= %lu untuk bagian `%s'"
+
+#: elf.c:439
+msgid "%B symbol number %lu references nonexistent SHT_SYMTAB_SHNDX section"
+msgstr "%B nomor simbol %lu referensi tidak ada SHT_SYMTAB_SHNDX bagian"
+
+#: elf.c:595
+msgid "%B: Corrupt size field in group section header: 0x%lx"
+msgstr "%B: Ukuran bagian korup dalam grup bagian kepala: 0x%lx"
+
+#: elf.c:631
+msgid "%B: invalid SHT_GROUP entry"
+msgstr "%B: masukan SHT_GROUP tidak valid"
+
+#: elf.c:701
+msgid "%B: no group info for section %A"
+msgstr "%B: tidak ada informasi grup untuk bagian %A"
+
+#: elf.c:730 elf.c:2960 elflink.c:9912
+msgid "%B: warning: sh_link not set for section `%A'"
+msgstr "%B: peringatan: sh_link tidak diset untuk bagian `%A'"
+
+#: elf.c:749
+msgid "%B: sh_link [%d] in section `%A' is incorrect"
+msgstr "%B: sh_link [%ld] dalam bagian `%A' tidak benar"
+
+#: elf.c:784
+msgid "%B: unknown [%d] section `%s' in group [%s]"
+msgstr "%B: tidak diketahui [%d] bagian `%s' dalam grup [%s]"
+
+#: elf.c:1104
+#, c-format
+msgid ""
+"\n"
+"Program Header:\n"
+msgstr ""
+"\n"
+"Kepala Aplikasi:\n"
+
+#: elf.c:1146
+#, c-format
+msgid ""
+"\n"
+"Dynamic Section:\n"
+msgstr ""
+"\n"
+"Bagian Dinamis:\n"
+
+#: elf.c:1282
+#, c-format
+msgid ""
+"\n"
+"Version definitions:\n"
+msgstr ""
+"\n"
+"Definisi Versi:\n"
+
+#: elf.c:1307
+#, c-format
+msgid ""
+"\n"
+"Version References:\n"
+msgstr ""
+"\n"
+"Referensi Versi:\n"
+
+#: elf.c:1312
+#, c-format
+msgid " required from %s:\n"
+msgstr " dibutuhkan dari %s:\n"
+
+#: elf.c:1702
+msgid "%B: invalid link %lu for reloc section %s (index %u)"
+msgstr "%B: link tidak valid %lu untuk bagian relokasi %s (indek %u)"
+
+#: elf.c:1870
+msgid "%B: don't know how to handle allocated, application specific section `%s' [0x%8x]"
+msgstr "%B: tidak tahu bagaimana menangani alokasi, bagian spesifik aplikasi `%s' [0x%8x]"
+
+#: elf.c:1882
+msgid "%B: don't know how to handle processor specific section `%s' [0x%8x]"
+msgstr "%B: tidak tahu bagaimana menangani bagian spesifik prosesor `%s' [0x%8x]"
+
+#: elf.c:1893
+msgid "%B: don't know how to handle OS specific section `%s' [0x%8x]"
+msgstr "%B: tidak tahu bagaimana menangani bagian spesifik OS `%s' [0x%8x]"
+
+#: elf.c:1903
+msgid "%B: don't know how to handle section `%s' [0x%8x]"
+msgstr "%B: tidak tahu bagaimana menangani bagian `%s' [0x%8x]"
+
+#: elf.c:2500
+#, c-format
+msgid "warning: section `%A' type changed to PROGBITS"
+msgstr "peringatan: bagian `%A' tipe berubah ke PROGBITS"
+
+#: elf.c:2917
+msgid "%B: sh_link of section `%A' points to discarded section `%A' of `%B'"
+msgstr "%B: sh_link dari bagian `%A' menunjuk ke bagian terbuang `%A' dari `%B'"
+
+#: elf.c:2940
+msgid "%B: sh_link of section `%A' points to removed section `%A' of `%B'"
+msgstr "%B: sh_link dari bagian `%A' menunjuk ke bagian terhapus `%A' dari `%B'"
+
+#: elf.c:4311
+msgid "%B: The first section in the PT_DYNAMIC segment is not the .dynamic section"
+msgstr "%B: bagian pertama dalam segmen PT_DYNAMIC tidak dalam bagian .dynamic"
+
+#: elf.c:4338
+msgid "%B: Not enough room for program headers, try linking with -N"
+msgstr "%B: tidak cukup ruang untuk kepala aplikasi, coba linking dengan -N"
+
+#: elf.c:4420
+msgid "%B: section %A vma 0x%lx overlaps previous sections"
+msgstr "%B: bagian %A vma 0x%lx overlaps bagian sebelumnya"
+
+#: elf.c:4515
+msgid "%B: section `%A' can't be allocated in segment %d"
+msgstr "%B: bagian `%A' tidak dapat dialokasikan dalam segmen %d"
+
+#: elf.c:4565
+msgid "%B: warning: allocated section `%s' not in segment"
+msgstr "%B: peringatan: alokasi bagian `%s' tidak dalam segmen"
+
+#: elf.c:5065
+msgid "%B: symbol `%s' required but not present"
+msgstr "%B: simbol `%s' dibutuhkan tetapi tidak ada"
+
+#: elf.c:5404
+msgid "%B: warning: Empty loadable segment detected, is this intentional ?\n"
+msgstr "%B: peringatan: loadable segmen kosong terdeteksi, apakah ini sengaja ?\n"
+
+#: elf.c:6370
+#, c-format
+msgid "Unable to find equivalent output section for symbol '%s' from section '%s'"
+msgstr "Tidak dapat menemukan bagian keluaran ekuivalen untuk simbol '%s' dari bagian '%s'"
+
+#: elf.c:7356
+msgid "%B: unsupported relocation type %s"
+msgstr "%B: tipe relokasi tidak didukung %s"
+
+#: elf32-arm.c:3149
+msgid ""
+"%B(%s): warning: interworking not enabled.\n"
+" first occurrence: %B: Thumb call to ARM"
+msgstr ""
+"%B(%s): peringatan: antar-kerja tidak aktif.\n"
+" pertemuan pertama: %B: Thumb call ke ARM"
+
+#: elf32-arm.c:3190
+msgid ""
+"%B(%s): warning: interworking not enabled.\n"
+" first occurrence: %B: ARM call to Thumb"
+msgstr ""
+"%B(%s): peringatan: antar-kerja tidak diaktifkan.\n"
+" pertemuan pertama: %B: ARM panggil ke Thumb"
+
+#: elf32-arm.c:3387 elf32-arm.c:4692
+#, c-format
+msgid "%s: cannot create stub entry %s"
+msgstr "%s: tidak dapat membuat masukan stub %s"
+
+#: elf32-arm.c:4804
+#, c-format
+msgid "unable to find THUMB glue '%s' for '%s'"
+msgstr "tidak dapat menemukan THUMB lem '%s' untuk '%s'"
+
+#: elf32-arm.c:4838
+#, c-format
+msgid "unable to find ARM glue '%s' for '%s'"
+msgstr "tidak dapat menemukan ARM lem '%s' untuk '%s'"
+
+#: elf32-arm.c:5365
+msgid "%B: BE8 images only valid in big-endian mode."
+msgstr "%B: hanya images BE8 valid dalam mode big-endian."
+
+#. Give a warning, but do as the user requests anyway.
+#: elf32-arm.c:5590
+msgid "%B: warning: selected VFP11 erratum workaround is not necessary for target architecture"
+msgstr "%B: peringatan: memilih VFP11 erratum penyelesaian adalah tidak diperlukan untuk arsitektur target"
+
+#: elf32-arm.c:6130 elf32-arm.c:6150
+msgid "%B: unable to find VFP11 veneer `%s'"
+msgstr "%B: tidak dapat menemukan VFP11 veneer `%s'"
+
+#: elf32-arm.c:6196
+#, c-format
+msgid "Invalid TARGET2 relocation type '%s'."
+msgstr "Tipe relokasi '%s' TARGET2 tidak valid."
+
+#: elf32-arm.c:6281
+msgid ""
+"%B(%s): warning: interworking not enabled.\n"
+" first occurrence: %B: thumb call to arm"
+msgstr ""
+"%B(%s): peringatan: antar-kerja tidak aktif.\n"
+" pertemuan pertama: %B: thumb call ke arm"
+
+#: elf32-arm.c:7003
+msgid "\\%B: Warning: Arm BLX instruction targets Arm function '%s'."
+msgstr "\\%B: Peringatan: Arm BLK instruksi target Arm fungsi '%s'."
+
+#: elf32-arm.c:7405
+msgid "%B: Warning: Thumb BLX instruction targets thumb function '%s'."
+msgstr "%B: Peringatan: Thumb BLX instruksi target thumb fungsi '%s'."
+
+#: elf32-arm.c:8085
+msgid "%B(%A+0x%lx): R_ARM_TLS_LE32 relocation not permitted in shared object"
+msgstr "%B(%A+0x%lx): R_ARM_TLS_LE32 relokasi tidak diperbolehkan dalam objek terbagi"
+
+#: elf32-arm.c:8300
+msgid "%B(%A+0x%lx): Only ADD or SUB instructions are allowed for ALU group relocations"
+msgstr "%B(%A+0x%lx): Hanya ADD atau SUB instruksi yang diperbolehkan untuk grup ALU relokasi"
+
+#: elf32-arm.c:8340 elf32-arm.c:8427 elf32-arm.c:8510 elf32-arm.c:8595
+msgid "%B(%A+0x%lx): Overflow whilst splitting 0x%lx for group relocation %s"
+msgstr "%B(%A+0x%lx): Overflow ketika membagi 0x%lx untuk relokasi grup %s"
+
+#: elf32-arm.c:8821 elf32-sh.c:3325 elf64-sh64.c:1556
+msgid "%B(%A+0x%lx): %s relocation against SEC_MERGE section"
+msgstr "%B(%A+0x%lx): %s relokasi terhadap bagian SEC_MERGE"
+
+#: elf32-arm.c:8939 elf32-m68k.c:4134 elf32-xtensa.c:2765 elf64-ppc.c:10743
+msgid "%B(%A+0x%lx): %s used with TLS symbol %s"
+msgstr "%B(%A+0x%lx): %s digunakan dengan simbol TLS %s"
+
+#: elf32-arm.c:8940 elf32-m68k.c:4135 elf32-xtensa.c:2766 elf64-ppc.c:10744
+msgid "%B(%A+0x%lx): %s used with non-TLS symbol %s"
+msgstr "%B(%A+0x%lx): %s digunakan dengan simbol bukan-TLS %s"
+
+#: elf32-arm.c:8997
+msgid "out of range"
+msgstr "diluar jangkauan"
+
+#: elf32-arm.c:9001
+msgid "unsupported relocation"
+msgstr "relokasi tidak didukung"
+
+#: elf32-arm.c:9009
+msgid "unknown error"
+msgstr "error tidak diketahui"
+
+#: elf32-arm.c:9409
+msgid "Warning: Clearing the interworking flag of %B because non-interworking code in %B has been linked with it"
+msgstr "Peringatan: Menghapus tanda antar-kerja dari %B karena bukan kode antar-kerja dalam %B telah dihubungkan dengan itu"
+
+#: elf32-arm.c:9652
+msgid "error: %B: Unknown CPU architecture"
+msgstr "error: %B: Arsitektur CPU tidak diketahui"
+
+#: elf32-arm.c:9690
+msgid "error: %B: Conflicting CPU architectures %d/%d"
+msgstr "error: %B: Profil arsitektur konflik %c/%c"
+
+#: elf32-arm.c:9747
+msgid "error: %B uses VFP register arguments, %B does not"
+msgstr "error: %B menggunakan reguster argumen VFP, %B tidak"
+
+#: elf32-arm.c:9897
+msgid "error: %B: Conflicting architecture profiles %c/%c"
+msgstr "error: %B: Profil arsitektur konflik %c/%c"
+
+#: elf32-arm.c:9921
+msgid "Warning: %B: Conflicting platform configuration"
+msgstr "Peringatan: %B: Konflik konfigurasi platform"
+
+#: elf32-arm.c:9930
+msgid "error: %B: Conflicting use of R9"
+msgstr "error: %B: Konflik penggunaan R9"
+
+#: elf32-arm.c:9942
+msgid "error: %B: SB relative addressing conflicts with use of R9"
+msgstr "error: %B: SB pengalamatan relatif konflik dengan penggunaan dari R9"
+
+#: elf32-arm.c:9955
+msgid "warning: %B uses %u-byte wchar_t yet the output is to use %u-byte wchar_t; use of wchar_t values across objects may fail"
+msgstr "peringatan: %B menggunakan %u-byte wchar_t tapi keluaran menggunakan %u-byte wchar_t; menggunakan nilai wchar_t melewati objek mungkin gagal"
+
+#: elf32-arm.c:9986
+msgid "warning: %B uses %s enums yet the output is to use %s enums; use of enum values across objects may fail"
+msgstr "peringatan: %B menggunakan %s enums tapi keluaran menggunakan %s enums; menggunakan nilai dari enum dari objek mungkin gagal"
+
+#: elf32-arm.c:9998
+msgid "error: %B uses iWMMXt register arguments, %B does not"
+msgstr "error: %B menggunakan iWMMXt argumen register, %B tidak"
+
+#: elf32-arm.c:10020
+msgid "error: fp16 format mismatch between %B and %B"
+msgstr "error: fp16 format tidak cocok diantara %B dan %B"
+
+#: elf32-arm.c:10063 elf32-arm.c:10156
+msgid "%B: Unknown mandatory EABI object attribute %d"
+msgstr "%B: atribut objek wajib EABI tidak diketahui %d"
+
+#: elf32-arm.c:10071 elf32-arm.c:10164
+msgid "Warning: %B: Unknown EABI object attribute %d"
+msgstr "Peringatan: %B: atribut objek EABI tidak diketahui %d"
+
+#: elf32-arm.c:10224
+msgid "error: %B is already in final BE8 format"
+msgstr "error: %B telah dalam format akhir BE8"
+
+#: elf32-arm.c:10300
+msgid "error: Source object %B has EABI version %d, but target %B has EABI version %d"
+msgstr "error: Sumber objek %B memiliki versi EABI %d, tetapi target %B memiliki versi EABI %d"
+
+#: elf32-arm.c:10316
+msgid "error: %B is compiled for APCS-%d, whereas target %B uses APCS-%d"
+msgstr "error: %B dikompile untuk APCS-%d, dimana target %B menggunakan APCS-%d"
+
+#: elf32-arm.c:10341
+msgid "error: %B uses VFP instructions, whereas %B does not"
+msgstr "error: %B menggunakan VFP instruksi, dimana %B tidak"
+
+#: elf32-arm.c:10345
+msgid "error: %B uses FPA instructions, whereas %B does not"
+msgstr "error: %B menggunakan FPA instruksi, dimana %B tidak"
+
+#: elf32-arm.c:10355
+msgid "error: %B uses Maverick instructions, whereas %B does not"
+msgstr "error: %B menggunakan Maverick instruksi, dimana %B tidak"
+
+#: elf32-arm.c:10359
+msgid "error: %B does not use Maverick instructions, whereas %B does"
+msgstr "error: %B tidak menggunakan Maveric instruksi, dimana %B menggunakan"
+
+#: elf32-arm.c:10378
+msgid "error: %B uses software FP, whereas %B uses hardware FP"
+msgstr "error: %B menggunakan software FP, dimana %B menggunakan hardware FP"
+
+#: elf32-arm.c:10382
+msgid "error: %B uses hardware FP, whereas %B uses software FP"
+msgstr "error: %B menggunakan hardware FP, dimana %B menggunakan software FP"
+
+#. Ignore init flag - it may not be set, despite the flags field
+#. containing valid data.
+#. Ignore init flag - it may not be set, despite the flags field containing valid data.
+#: elf32-arm.c:10429 elf32-bfin.c:5082 elf32-cris.c:4110 elf32-m68hc1x.c:1280
+#: elf32-m68k.c:1169 elf32-score.c:4039 elf32-score7.c:3876 elf32-vax.c:540
+#: elfxx-mips.c:12755
+#, c-format
+msgid "private flags = %lx:"
+msgstr "tanda private = %lx:"
+
+#: elf32-arm.c:10438
+#, c-format
+msgid " [interworking enabled]"
+msgstr " [antar-kerja aktif]"
+
+#: elf32-arm.c:10446
+#, c-format
+msgid " [VFP float format]"
+msgstr " [VFP float format]"
+
+#: elf32-arm.c:10448
+#, c-format
+msgid " [Maverick float format]"
+msgstr " [Maverick float format]"
+
+#: elf32-arm.c:10450
+#, c-format
+msgid " [FPA float format]"
+msgstr " [FPA float format]"
+
+#: elf32-arm.c:10459
+#, c-format
+msgid " [new ABI]"
+msgstr " [ABI baru]"
+
+#: elf32-arm.c:10462
+#, c-format
+msgid " [old ABI]"
+msgstr " [ABI lama]"
+
+#: elf32-arm.c:10465
+#, c-format
+msgid " [software FP]"
+msgstr " [software FP]"
+
+#: elf32-arm.c:10474
+#, c-format
+msgid " [Version1 EABI]"
+msgstr " [EABI Versi 1]"
+
+#: elf32-arm.c:10477 elf32-arm.c:10488
+#, c-format
+msgid " [sorted symbol table]"
+msgstr " [simbol tabel terurut]"
+
+#: elf32-arm.c:10479 elf32-arm.c:10490
+#, c-format
+msgid " [unsorted symbol table]"
+msgstr " [simbol tabel tidak terurut]"
+
+#: elf32-arm.c:10485
+#, c-format
+msgid " [Version2 EABI]"
+msgstr " [EABI Versi 2]"
+
+#: elf32-arm.c:10493
+#, c-format
+msgid " [dynamic symbols use segment index]"
+msgstr " [simbol dinamis menggunakan segmen indek]"
+
+#: elf32-arm.c:10496
+#, c-format
+msgid " [mapping symbols precede others]"
+msgstr " [simbol map mendahului yang lain]"
+
+#: elf32-arm.c:10503
+#, c-format
+msgid " [Version3 EABI]"
+msgstr " [EABI Versi 3]"
+
+#: elf32-arm.c:10507
+#, c-format
+msgid " [Version4 EABI]"
+msgstr " [EABI Versi 4]"
+
+#: elf32-arm.c:10511
+#, c-format
+msgid " [Version5 EABI]"
+msgstr " [EABI Versi 5]"
+
+#: elf32-arm.c:10514
+#, c-format
+msgid " [BE8]"
+msgstr " [BE8]"
+
+#: elf32-arm.c:10517
+#, c-format
+msgid " [LE8]"
+msgstr " [LE8]"
+
+#: elf32-arm.c:10523
+#, c-format
+msgid " <EABI version unrecognised>"
+msgstr " <EABI versi tidak dikenal>"
+
+#: elf32-arm.c:10530
+#, c-format
+msgid " [relocatable executable]"
+msgstr " [relocatable executable]"
+
+#: elf32-arm.c:10533
+#, c-format
+msgid " [has entry point]"
+msgstr " [memiliki titik masuk]"
+
+#: elf32-arm.c:10538
+#, c-format
+msgid "<Unrecognised flag bits set>"
+msgstr "<Tanda bit tidak dikenal terset>"
+
+#: elf32-arm.c:10783 elf32-i386.c:1300 elf32-s390.c:998 elf32-xtensa.c:1000
+#: elf64-s390.c:952 elf64-x86-64.c:1082 elfxx-sparc.c:1121
+msgid "%B: bad symbol index: %d"
+msgstr "%B: memiliki indek simbol: %d"
+
+#: elf32-arm.c:10904 elf64-x86-64.c:1242 elf64-x86-64.c:1411 elfxx-mips.c:7870
+msgid "%B: relocation %s against `%s' can not be used when making a shared object; recompile with -fPIC"
+msgstr "%B: relokasi %s terhadap `%s' tidak dapat digunkan ketika membuat sebuah objek terbagi; rekompile dengan -fPIC"
+
+#: elf32-arm.c:11893
+#, c-format
+msgid "Errors encountered processing file %s"
+msgstr "Errors ditemui dalam pemrosesan berkas %s"
+
+#: elf32-arm.c:13339
+msgid "%B: error: Cortex-A8 erratum stub is allocated in unsafe location"
+msgstr "%B: error: Cortex-A8 erratum stub dialokasikan dalam lokasi yang tidak aman"
+
+#. There's not much we can do apart from complain if this
+#. happens.
+#: elf32-arm.c:13366
+msgid "%B: error: Cortex-A8 erratum stub out of range (input file too large)"
+msgstr "%B: error: Cortex-A8 erratum stub diluar dari jangkauan (berkas masukan terlalu besar)"
+
+#: elf32-arm.c:13457 elf32-arm.c:13479
+msgid "%B: error: VFP11 veneer out of range"
+msgstr "%B: error: VFP11 veneer diluar jangkauan"
+
+#: elf32-avr.c:1259 elf32-bfin.c:3208 elf32-cris.c:2097 elf32-fr30.c:624
+#: elf32-frv.c:4122 elf32-i860.c:1226 elf32-ip2k.c:1510 elf32-iq2000.c:699
+#: elf32-m32c.c:568 elf32-mep.c:549 elf32-moxie.c:299 elf32-msp430.c:501
+#: elf32-mt.c:406 elf32-openrisc.c:419 elf32-v850.c:1709 elf32-xstormy16.c:956
+#: elf64-mmix.c:1541
+msgid "internal error: dangerous relocation"
+msgstr "internal error: relokasi berbahaya"
+
+#: elf32-avr.c:2409 elf32-hppa.c:605 elf32-m68hc1x.c:165 elf64-ppc.c:4141
+msgid "%B: cannot create stub entry %s"
+msgstr "%B: tidak dapat membuat masukan stub %s"
+
+#: elf32-bfin.c:1581
+msgid "%B(%A+0x%lx): unresolvable relocation against symbol `%s'"
+msgstr "%B(%A+0x%lx): relokasi tidak teresolf terhadap simbol `%s'"
+
+#: elf32-bfin.c:1614 elf32-i386.c:4026 elf32-m68k.c:4176 elf32-s390.c:3067
+#: elf64-s390.c:3026 elf64-x86-64.c:3697
+msgid "%B(%A+0x%lx): reloc against `%s': error %d"
+msgstr "%B(%A+0x%lx): relokasi terhadap `%s': error %d"
+
+#: elf32-bfin.c:2714
+msgid "%B: relocation at `%A+0x%x' references symbol `%s' with nonzero addend"
+msgstr "%B: relokasi di `%A+0x%x' simbol referensi `%s' dengan bukan nol ditambahkan"
+
+#: elf32-bfin.c:2728 elf32-frv.c:2904
+msgid "relocation references symbol not defined in the module"
+msgstr "relokasi referensi simbol tidak didefinisikan dalam modul"
+
+#: elf32-bfin.c:2825
+msgid "R_BFIN_FUNCDESC references dynamic symbol with nonzero addend"
+msgstr "R_BFIN_FUNCDESC referensi simbol dinamis dengan bukan nol ditambahkan"
+
+#: elf32-bfin.c:2866 elf32-bfin.c:2989 elf32-frv.c:3641 elf32-frv.c:3762
+msgid "cannot emit fixups in read-only section"
+msgstr "tidak dapat mengeluarkan fixups dalam bagian baca-saja"
+
+#: elf32-bfin.c:2897 elf32-bfin.c:3027 elf32-frv.c:3672 elf32-frv.c:3806
+#: elf32-lm32.c:1104
+msgid "cannot emit dynamic relocations in read-only section"
+msgstr "tidak dapat mengeluarkan relokasi dinamis dalam bagian baca-saja"
+
+#: elf32-bfin.c:2947
+msgid "R_BFIN_FUNCDESC_VALUE references dynamic symbol with nonzero addend"
+msgstr "R_BFIN_FUNCDESC_VALUE referensi simbol dinamis dengan bukan nol ditambahkan"
+
+#: elf32-bfin.c:3112
+msgid "relocations between different segments are not supported"
+msgstr "relokasi diantara segmen berbeda tidak didukung"
+
+#: elf32-bfin.c:3113
+msgid "warning: relocation references a different segment"
+msgstr "peringatan: relokasi referensi sebuah segmen berbeda"
+
+#: elf32-bfin.c:4974 elf32-frv.c:6408
+msgid "%B: unsupported relocation type %i"
+msgstr "%B: tipe relokasi %i tidak didukung"
+
+#: elf32-bfin.c:5127 elf32-frv.c:6816
+#, c-format
+msgid "%s: cannot link non-fdpic object file into fdpic executable"
+msgstr "%s: tidak dapat menghubungkan berkas objek bukan-fdpic kedalam aplikasi fdpic"
+
+#: elf32-bfin.c:5131 elf32-frv.c:6820
+#, c-format
+msgid "%s: cannot link fdpic object file into non-fdpic executable"
+msgstr "%s: tidak dapat menghubungkan berkas objek fdpic kedalam aplikasi bukan-fdpic"
+
+#: elf32-cris.c:1169
+msgid "%B, section %A: unresolvable relocation %s against symbol `%s'"
+msgstr "%B, bagian %A: relokasi tidak teresolf %s terhadap simbol `%s'"
+
+#: elf32-cris.c:1238
+msgid "%B, section %A: No PLT nor GOT for relocation %s against symbol `%s'"
+msgstr "%B, bagian %A: Bukan PLT atau GOT untuk relokasi %s terhadap simbol `%s'"
+
+#: elf32-cris.c:1240
+msgid "%B, section %A: No PLT for relocation %s against symbol `%s'"
+msgstr "%B, bagian %A: Bukan PLT untuk relokasi %s terhadap simbol `%s'"
+
+#: elf32-cris.c:1246 elf32-cris.c:1379 elf32-cris.c:1641 elf32-cris.c:1730
+#: elf32-cris.c:1883
+msgid "[whose name is lost]"
+msgstr "[yang namanya hilang]"
+
+#: elf32-cris.c:1365
+msgid "%B, section %A: relocation %s with non-zero addend %d against local symbol"
+msgstr "%B, bagian %A: relokasi %s dengan bukan-nol ditambahkan %d terhadap simbol lokal"
+
+#: elf32-cris.c:1373 elf32-cris.c:1724 elf32-cris.c:1877
+msgid "%B, section %A: relocation %s with non-zero addend %d against symbol `%s'"
+msgstr "%B, bagian %A: relokasi %s dengan bukan-nol ditambakan %d terhadap simbol `%s'"
+
+#: elf32-cris.c:1399
+msgid "%B, section %A: relocation %s is not allowed for global symbol: `%s'"
+msgstr "%B, bagian %A: relokasi %s tidak diperbolehkan untuk simbol global: `%s'"
+
+#: elf32-cris.c:1415
+msgid "%B, section %A: relocation %s with no GOT created"
+msgstr "%B, bagian %A: relokasi %s dengan tidak GOT dibuat"
+
+#. We shouldn't get here for GCC-emitted code.
+#: elf32-cris.c:1632
+msgid "%B, section %A: relocation %s has an undefined reference to `%s', perhaps a declaration mixup?"
+msgstr "%B, bagian %A: relokasi %s memiliki sebuah referensi tidak terdefinisi ke `%s', mungkin sebuah kesalahan deklarasi?"
+
+#: elf32-cris.c:2010
+msgid "%B, section %A: relocation %s is not allowed for symbol: `%s' which is defined outside the program, perhaps a declaration mixup?"
+msgstr "%B, bagian %A: relokasi %s tidak diperbolehkan untuk simbol global: `%s' yang didefinisikan diluar aplikasi, mungkin sebuah kesalahan deklarasi?"
+
+#: elf32-cris.c:2063
+msgid "(too many global variables for -fpic: recompile with -fPIC)"
+msgstr "(terlalu banyak variabel global untuk -fpic: rekompilasi dengan -fPIC)"
+
+#: elf32-cris.c:2070
+msgid "(thread-local data too big for -fpic or -msmall-tls: recompile with -fPIC or -mno-small-tls)"
+msgstr "(thread-local data terlalu besar untuk -fpic atau -msmall-tls: rekompilasi dengan -fPIC atau -mno-small-tls)"
+
+#: elf32-cris.c:3204
+msgid ""
+"%B, section %A:\n"
+" v10/v32 compatible object %s must not contain a PIC relocation"
+msgstr ""
+"%B, bagian %A:\n"
+" v10/v32 objek kompatibel %s harus berisi sebuah relokasi PIC"
+
+#: elf32-cris.c:3309
+msgid ""
+"%B, section %A:\n"
+" relocation %s not valid in a shared object; typically an option mixup, recompile with -fPIC"
+msgstr ""
+"%B, bagian %A:\n"
+" relokasi %s tidak valid dalam sebuah objek terbagi; umumnya sebuah kesalahan pilihan, rekompile dengan -fPIC"
+
+#: elf32-cris.c:3523
+msgid ""
+"%B, section %A:\n"
+" relocation %s should not be used in a shared object; recompile with -fPIC"
+msgstr ""
+"%B, bagian %A:\n"
+" relokasi %s seharusnya digunakan dalam sebuah objek terbagi; rekompile dengan -fPIC"
+
+#: elf32-cris.c:3940
+msgid ""
+"%B, section `%A', to symbol `%s':\n"
+" relocation %s should not be used in a shared object; recompile with -fPIC"
+msgstr ""
+"%B, bagian `%A', ke simbol `%s':\n"
+" relokasi %s seharusnya digunakan dalam sebuah objek terbagi; rekompilasi dengan -fPIC"
+
+#: elf32-cris.c:4059
+msgid "Unexpected machine number"
+msgstr "Nomor mesin tidak terduga"
+
+#: elf32-cris.c:4113
+#, c-format
+msgid " [symbols have a _ prefix]"
+msgstr " [simbol memiliki sebuah awalan _]"
+
+#: elf32-cris.c:4116
+#, c-format
+msgid " [v10 and v32]"
+msgstr " [v10 dan v32]"
+
+#: elf32-cris.c:4119
+#, c-format
+msgid " [v32]"
+msgstr " [v32]"
+
+#: elf32-cris.c:4164
+msgid "%B: uses _-prefixed symbols, but writing file with non-prefixed symbols"
+msgstr "%B: menggunakan awalan _ simbol, tetapi menulis berkas dengan simbol tanpa awalan"
+
+#: elf32-cris.c:4165
+msgid "%B: uses non-prefixed symbols, but writing file with _-prefixed symbols"
+msgstr "%B: menggunakan simbol tanpa awalan, tetapi menulis berkas dengan simbol awalan _"
+
+#: elf32-cris.c:4184
+msgid "%B contains CRIS v32 code, incompatible with previous objects"
+msgstr "%B berisi kode CRIS v32, tidak kompatibel dengan objek sebelumnya"
+
+#: elf32-cris.c:4186
+msgid "%B contains non-CRIS-v32 code, incompatible with previous objects"
+msgstr "%B berisi kode bukan CRIS v32, tidak kompatibel dengan objek sebelumnya"
+
+#: elf32-frv.c:1507 elf32-frv.c:1656
+msgid "relocation requires zero addend"
+msgstr "relokasi membutuhkan penambahan nol"
+
+#: elf32-frv.c:2891
+msgid "%B(%A+0x%x): relocation to `%s+%x' may have caused the error above"
+msgstr "%B(%A+0x%x): relokasi ke `%s+%x' mungkin menyebabkan error diatas"
+
+#: elf32-frv.c:2980
+msgid "R_FRV_GETTLSOFF not applied to a call instruction"
+msgstr "R_FRV_GETTLSOFF tidak teraplikasi untuk sebuah panggilan instruksi"
+
+#: elf32-frv.c:3022
+msgid "R_FRV_GOTTLSDESC12 not applied to an lddi instruction"
+msgstr "R_FRV_GOTTLSDESC12 tidak teraplikasi untuk sebuah instruksi lddi"
+
+#: elf32-frv.c:3093
+msgid "R_FRV_GOTTLSDESCHI not applied to a sethi instruction"
+msgstr "R_FRV_GOTTLSDESCHI tidak teraplikasi untuk sebuah instruksi sethi"
+
+#: elf32-frv.c:3130
+msgid "R_FRV_GOTTLSDESCLO not applied to a setlo or setlos instruction"
+msgstr "R_FRV_GOTTLSDESCLO tidak teraplikasi untuk sebuah instruksi setlo atau setlos"
+
+#: elf32-frv.c:3178
+msgid "R_FRV_TLSDESC_RELAX not applied to an ldd instruction"
+msgstr "R_FRV_TLSDESC_RELAX tidak teraplikasi untuk sebuah instruksi ldd"
+
+#: elf32-frv.c:3262
+msgid "R_FRV_GETTLSOFF_RELAX not applied to a calll instruction"
+msgstr "R_FRV_GETTLSOFF_RELAX tidak teraplikasi untuk sebuah instruksi calll"
+
+#: elf32-frv.c:3317
+msgid "R_FRV_GOTTLSOFF12 not applied to an ldi instruction"
+msgstr "R_FRV_GETTLSOFF12 tidak teraplikasi untuk sebuah instruksi ldi"
+
+#: elf32-frv.c:3347
+msgid "R_FRV_GOTTLSOFFHI not applied to a sethi instruction"
+msgstr "R_FRV_GOTTLSOFFHI tidak teraplikasi untuk sebuah instruksi sethi"
+
+#: elf32-frv.c:3376
+msgid "R_FRV_GOTTLSOFFLO not applied to a setlo or setlos instruction"
+msgstr "R_FRV_GOTTLSOFFLO tidak teraplikasi untuk sebuah instruksi setlo atau setlos"
+
+#: elf32-frv.c:3407
+msgid "R_FRV_TLSOFF_RELAX not applied to an ld instruction"
+msgstr "R_FRV_TLSOFF_RELAX tidak teraplikasi untuk sebuah instruksi ld"
+
+#: elf32-frv.c:3452
+msgid "R_FRV_TLSMOFFHI not applied to a sethi instruction"
+msgstr "R_FRV_TLSMOFFHI tidak teraplikasi untuk sebuah instruksi sethi"
+
+#: elf32-frv.c:3479
+msgid "R_FRV_TLSMOFFLO not applied to a setlo or setlos instruction"
+msgstr "R_FRV_TLSMOFFLO tidak teraplikasi untuk sebuah instruksi setlo atau setlos"
+
+#: elf32-frv.c:3600
+msgid "R_FRV_FUNCDESC references dynamic symbol with nonzero addend"
+msgstr "R_FRV_FUNCDESC referensi simbol dinamis dengan penambahan bukan nol"
+
+#: elf32-frv.c:3720
+msgid "R_FRV_FUNCDESC_VALUE references dynamic symbol with nonzero addend"
+msgstr "R_FRV_FUNCDESC_VALUE referensi simbol dinamis dengan penambahan bukan nol"
+
+#: elf32-frv.c:3977 elf32-frv.c:4133
+msgid "%B(%A+0x%lx): reloc against `%s': %s"
+msgstr "%B(%A+0x%lx): relokasi terhadap `%s': %s"
+
+#: elf32-frv.c:3979 elf32-frv.c:3983
+msgid "relocation references a different segment"
+msgstr "relokasi referensi ke segmen berbeda"
+
+#: elf32-frv.c:6730
+#, c-format
+msgid "%s: compiled with %s and linked with modules that use non-pic relocations"
+msgstr "%s: terkompile dengan %s dan terhubung dengan modul yang menggunakan relokasi bukan-pic"
+
+#: elf32-frv.c:6783 elf32-iq2000.c:852 elf32-m32c.c:814
+#, c-format
+msgid "%s: compiled with %s and linked with modules compiled with %s"
+msgstr "%s: terkompile dengan %s dan terhubung dengan modul terkompile dengan %s"
+
+#: elf32-frv.c:6795
+#, c-format
+msgid "%s: uses different unknown e_flags (0x%lx) fields than previous modules (0x%lx)"
+msgstr "%s: menggunakan bagian e_flags (0x%lx) berbeda yang tidak dikenal dari modul sebelumnya (0x%lx)"
+
+#: elf32-frv.c:6845 elf32-iq2000.c:889 elf32-m32c.c:850 elf32-mt.c:583
+#, c-format
+msgid "private flags = 0x%lx:"
+msgstr "private flags = 0x%lx:"
+
+#: elf32-gen.c:69 elf64-gen.c:69
+msgid "%B: Relocations in generic ELF (EM: %d)"
+msgstr "%B: Relokasi dalam ELF standar (EM: %d)"
+
+#: elf32-hppa.c:854 elf32-hppa.c:3570
+msgid "%B(%A+0x%lx): cannot reach %s, recompile with -ffunction-sections"
+msgstr "%B(%A+0x%lx): tidak dapat mencapai %s, rekompile dengan -ffunction-sections"
+
+#: elf32-hppa.c:1286
+msgid "%B: relocation %s can not be used when making a shared object; recompile with -fPIC"
+msgstr "%B: relokasi %s tidak dapat digunakan ketika membuat sebuah objek terbagi; rekompile dengan -fPIC"
+
+#: elf32-hppa.c:2780
+msgid "%B: duplicate export stub %s"
+msgstr "%B: duplikasi export stub %s"
+
+#: elf32-hppa.c:3406
+msgid "%B(%A+0x%lx): %s fixup for insn 0x%x is not supported in a non-shared link"
+msgstr "%B(%A+0x%lx): %s fixup untuk insn 0x%x tidak didukung dalam sebuah sambunga tidak terbagi"
+
+#: elf32-hppa.c:4260
+msgid "%B(%A+0x%lx): cannot handle %s for %s"
+msgstr "%B(%A+0x%lx): tidak dapat menangani %s untuk %s"
+
+#: elf32-hppa.c:4567
+msgid ".got section not immediately after .plt section"
+msgstr "bagian .got tidak mengikuti bagian .plt"
+
+#: elf32-i386.c:371 elf32-ppc.c:1666 elf32-s390.c:379 elf64-ppc.c:2283
+#: elf64-s390.c:403 elf64-x86-64.c:234
+msgid "%B: invalid relocation type %d"
+msgstr "%B: tipe relokasi %d tidak valid"
+
+#: elf32-i386.c:1246 elf64-x86-64.c:1029
+msgid "%B: TLS transition from %s to %s against `%s' at 0x%lx in section `%A' failed"
+msgstr "%B: TLS transisi dari %s ke %s terhadap `%s' di 0x%lx dalam bagian `%A' gagal"
+
+#: elf32-i386.c:1387 elf32-i386.c:2970 elf64-x86-64.c:1171 elf64-x86-64.c:2680
+msgid "%B: relocation %s against STT_GNU_IFUNC symbol `%s' isn't handled by %s"
+msgstr "%B: relokasi %s terhadap STT_GNU_IFUNC simbol `%s' tidak ditangani oleh %s"
+
+#: elf32-i386.c:1548 elf32-s390.c:1180 elf32-sh.c:5065 elf32-xtensa.c:1173
+#: elf64-s390.c:1143 elfxx-sparc.c:1257
+msgid "%B: `%s' accessed both as normal and thread local symbol"
+msgstr "%B: `%s' terakses kedua sebagai normal dan memperlakukan lokal simbol"
+
+#: elf32-i386.c:2805
+msgid "%B: unrecognized relocation (0x%x) in section `%A'"
+msgstr "%B: relokasi tidak dikenal (0x%x) dalam bagian `%A'"
+
+#: elf32-i386.c:3219 elf64-x86-64.c:3081
+msgid "hidden symbol"
+msgstr "simbol tersembunyi"
+
+#: elf32-i386.c:3222 elf64-x86-64.c:3084
+msgid "internal symbol"
+msgstr "internal simbol"
+
+#: elf32-i386.c:3225 elf64-x86-64.c:3087
+msgid "protected symbol"
+msgstr "simbol terproteksi"
+
+#: elf32-i386.c:3228 elf64-x86-64.c:3090
+msgid "symbol"
+msgstr "simbol"
+
+#: elf32-i386.c:3233
+msgid "%B: relocation R_386_GOTOFF against undefined %s `%s' can not be used when making a shared object"
+msgstr "%B: relokasi R_386_GOTOFF terhadap %s `%s' tidak terdefinisi tidak dapat digunakan ketika membuah sebuah objek terbagi"
+
+#: elf32-i386.c:3243
+msgid "%B: relocation R_386_GOTOFF against protected function `%s' can not be used when making a shared object"
+msgstr "%B: relokasi R_386_GOTOFF terhadap fungsi terproteksi `%s' tidak dapat digunakan ketika membuat sebuah objek terbagi"
+
+#: elf32-ip2k.c:868 elf32-ip2k.c:874 elf32-ip2k.c:941 elf32-ip2k.c:947
+msgid "ip2k relaxer: switch table without complete matching relocation information."
+msgstr "ip2k relaxer: tabel switch tanpa pencocokan informasi relokasi lengkap."
+
+#: elf32-ip2k.c:891 elf32-ip2k.c:974
+msgid "ip2k relaxer: switch table header corrupt."
+msgstr "ip2k relaxer: switch tabel header terkorupsi."
+
+#: elf32-ip2k.c:1316
+#, c-format
+msgid "ip2k linker: missing page instruction at 0x%08lx (dest = 0x%08lx)."
+msgstr "ip2k linker: hilang halaman instruksi di 0x%08lx (dest = 0x%08lx)."
+
+#: elf32-ip2k.c:1332
+#, c-format
+msgid "ip2k linker: redundant page instruction at 0x%08lx (dest = 0x%08lx)."
+msgstr "ip2k linker: redundant halaman instruksi di 0x%08lx (dest = 0x%08lx)."
+
+#. Only if it's not an unresolved symbol.
+#: elf32-ip2k.c:1506
+msgid "unsupported relocation between data/insn address spaces"
+msgstr "relokasi tidak didukung diantara data/insn ruang alamat"
+
+#: elf32-iq2000.c:865 elf32-m32c.c:826
+#, c-format
+msgid "%s: uses different e_flags (0x%lx) fields than previous modules (0x%lx)"
+msgstr "%s: menggunakan e_flags (0x%lx) field berbeda dari modul sebelumnya (0x%lx)"
+
+#: elf32-lm32.c:698
+msgid "global pointer relative relocation when _gp not defined"
+msgstr "penunjuk global relokasi relatif waktu _gp tidak terdefinisi"
+
+#: elf32-lm32.c:753
+msgid "global pointer relative address out of range"
+msgstr "penunjuk global alamat relatif diluar dari jangkauan"
+
+#: elf32-lm32.c:1058
+msgid "internal error: addend should be zero for R_LM32_16_GOT"
+msgstr "kesalahan internal: addend seharusnya nol untuk R_LM32_16_GOT"
+
+#: elf32-m32r.c:1453
+msgid "SDA relocation when _SDA_BASE_ not defined"
+msgstr "SDA relokasi ketika _SDA_BASE_ tidak terdefinisi"
+
+#: elf32-m32r.c:3039
+msgid "%B: The target (%s) of an %s relocation is in the wrong section (%A)"
+msgstr "%B: Target (%s) dari sebuah %s relokasi berada dalam bagian yang salah (%A)"
+
+#: elf32-m32r.c:3567
+msgid "%B: Instruction set mismatch with previous modules"
+msgstr "%B: Set Instruksi tidak cocok dengan modul sebelumnya"
+
+#: elf32-m32r.c:3588
+#, c-format
+msgid "private flags = %lx"
+msgstr "private flags = %lx"
+
+#: elf32-m32r.c:3593
+#, c-format
+msgid ": m32r instructions"
+msgstr ": m32r instruksi"
+
+#: elf32-m32r.c:3594
+#, c-format
+msgid ": m32rx instructions"
+msgstr ": m32rx instruksi"
+
+#: elf32-m32r.c:3595
+#, c-format
+msgid ": m32r2 instructions"
+msgstr ": m32r2 instruksi"
+
+#: elf32-m68hc1x.c:1048
+#, c-format
+msgid "Reference to the far symbol `%s' using a wrong relocation may result in incorrect execution"
+msgstr "Referensi ke simbol jauh `%s' menggunakan relokasi salah mungkin akan menghasilkan eksekusi salah"
+
+#: elf32-m68hc1x.c:1071
+#, c-format
+msgid "banked address [%lx:%04lx] (%lx) is not in the same bank as current banked address [%lx:%04lx] (%lx)"
+msgstr "banked address [%lx:%04lx] (%lx) tidak dalam bank yang sama seperti dalam alamat bank sekarang [%lx:%04lx] (%lx)"
+
+#: elf32-m68hc1x.c:1090
+#, c-format
+msgid "reference to a banked address [%lx:%04lx] in the normal address space at %04lx"
+msgstr "referensi ke alamat bank [%lx:%04lx] dalam ruang alamat normal di %04lx"
+
+#: elf32-m68hc1x.c:1223
+msgid "%B: linking files compiled for 16-bit integers (-mshort) and others for 32-bit integers"
+msgstr "%B: menghubungkan berkas yang dikompile untuk 16-bit integer (-mshort) dan yang lain untuk 32-bit integer"
+
+#: elf32-m68hc1x.c:1230
+msgid "%B: linking files compiled for 32-bit double (-fshort-double) and others for 64-bit double"
+msgstr "%B: menghubungkan berkas yang dikompile untuk 32-bit double (-fshort-double) dan yang lain untuk 64-bit double"
+
+#: elf32-m68hc1x.c:1239
+msgid "%B: linking files compiled for HCS12 with others compiled for HC12"
+msgstr "%B: menghubungkan berkas dikompile untuk HCS12 dengan yang lain dikompile untuk HC12"
+
+#: elf32-m68hc1x.c:1255 elf32-ppc.c:4255 elf64-sparc.c:698 elfxx-mips.c:12617
+msgid "%B: uses different e_flags (0x%lx) fields than previous modules (0x%lx)"
+msgstr "%B: menggunakan field e_flags (0x%lx) berbeda dari modul sebelumnya (0x%lx)"
+
+#: elf32-m68hc1x.c:1283
+#, c-format
+msgid "[abi=32-bit int, "
+msgstr "[abi=32-bit int, "
+
+#: elf32-m68hc1x.c:1285
+#, c-format
+msgid "[abi=16-bit int, "
+msgstr "[abi=16-bit int, "
+
+#: elf32-m68hc1x.c:1288
+#, c-format
+msgid "64-bit double, "
+msgstr "64-bit double, "
+
+#: elf32-m68hc1x.c:1290
+#, c-format
+msgid "32-bit double, "
+msgstr "32-bit double, "
+
+#: elf32-m68hc1x.c:1293
+#, c-format
+msgid "cpu=HC11]"
+msgstr "cpu=HC11]"
+
+#: elf32-m68hc1x.c:1295
+#, c-format
+msgid "cpu=HCS12]"
+msgstr "cpu=HCS12]"
+
+#: elf32-m68hc1x.c:1297
+#, c-format
+msgid "cpu=HC12]"
+msgstr "cpu=HC12]"
+
+#: elf32-m68hc1x.c:1300
+#, c-format
+msgid " [memory=bank-model]"
+msgstr " [memory=bank-model]"
+
+#: elf32-m68hc1x.c:1302
+#, c-format
+msgid " [memory=flat]"
+msgstr " [memory=flat]"
+
+#: elf32-m68k.c:1184 elf32-m68k.c:1185
+msgid "unknown"
+msgstr "tidak dikenal"
+
+#: elf32-m68k.c:1645
+msgid "%B: GOT overflow: Number of relocations with 8-bit offset > %d"
+msgstr "%B: GOT overflow: Jumlah dari relokasi dengan offset 8-bit > %d"
+
+#: elf32-m68k.c:1651
+msgid "%B: GOT overflow: Number of relocations with 8- or 16-bit offset > %d"
+msgstr "%B: GOT overflow: Jumlah dari relokasi dengan offset 8- atau 16-bit > %d"
+
+#: elf32-m68k.c:3902
+msgid "%B(%A+0x%lx): R_68K_TLS_LE32 relocation not permitted in shared object"
+msgstr "%B(%A+0x%lx): R_68K_TLS_LE32 relokasi tidak diperbolehkan dalam objek terbagi"
+
+#: elf32-mcore.c:99 elf32-mcore.c:442
+msgid "%B: Relocation %s (%d) is not currently supported.\n"
+msgstr "%B: Relokasi %s (%d) saat ini tidak didukung.\n"
+
+#: elf32-mcore.c:428
+msgid "%B: Unknown relocation type %d\n"
+msgstr "%B: Tipe relokasi %d tidak dikenal\n"
+
+#: elf32-mep.c:654
+msgid "%B and %B are for different cores"
+msgstr "%B dan %B adalah untuk cores berbeda"
+
+#: elf32-mep.c:671
+msgid "%B and %B are for different configurations"
+msgstr "%B dan %B adalah untuk konfigurasi berbeda"
+
+#: elf32-mep.c:708
+#, c-format
+msgid "private flags = 0x%lx"
+msgstr "private flags = 0x%lx"
+
+#: elf32-microblaze.c:737
+#, c-format
+msgid "%s: unknown relocation type %d"
+msgstr "%s: tipe relokasi %d tidak diketahui"
+
+#: elf32-microblaze.c:862 elf32-microblaze.c:907
+#, c-format
+msgid "%s: The target (%s) of an %s relocation is in the wrong section (%s)"
+msgstr "%s: Target (%s) dari sebuah %s relokasi berada dalam bagian yang salah (%s)"
+
+#: elf32-microblaze.c:1150 elfxx-sparc.c:2957
+msgid "%B: probably compiled without -fPIC?"
+msgstr "%B: mungkin dikompile tanpa -fPIC?"
+
+#: elf32-microblaze.c:2086 elflink.c:12444
+msgid "%B: bad relocation section name `%s'"
+msgstr "%B: relokasi bagian nama `%s' buruk"
+
+#: elf32-mips.c:1045 elf64-mips.c:2083 elfn32-mips.c:1888
+msgid "literal relocation occurs for an external symbol"
+msgstr "literal relokasi terjadi untuk simbol eksternal"
+
+#: elf32-mips.c:1085 elf32-score.c:580 elf32-score7.c:480 elf64-mips.c:2126
+#: elfn32-mips.c:1929
+msgid "32bits gp relative relocation occurs for an external symbol"
+msgstr "32bit gp relative relokasi terjadi untuk sebuah simbol eksternal"
+
+#: elf32-ppc.c:1731
+#, c-format
+msgid "generic linker can't handle %s"
+msgstr "linker generik tidak dapat menangani %s"
+
+#: elf32-ppc.c:2211
+msgid "corrupt or empty %s section in %B"
+msgstr "korup atau kosong %s bagian dalam %B"
+
+#: elf32-ppc.c:2218
+msgid "unable to read in %s section from %B"
+msgstr "tidak dapat membaca dalam bagian %s dari %B"
+
+#: elf32-ppc.c:2224
+msgid "corrupt %s section in %B"
+msgstr "korup bagian %s dalam %B"
+
+#: elf32-ppc.c:2267
+msgid "warning: unable to set size of %s section in %B"
+msgstr "peringatan: tidak dapat menset ukuran bagian %s dalam %B"
+
+#: elf32-ppc.c:2315
+msgid "failed to allocate space for new APUinfo section."
+msgstr "gagal mengalokasikan ruang untuk bagian baru APUinfo."
+
+#: elf32-ppc.c:2334
+msgid "failed to compute new APUinfo section."
+msgstr "gagal untuk menghitung bagian baru APUinfo."
+
+#: elf32-ppc.c:2337
+msgid "failed to install new APUinfo section."
+msgstr "gagal untuk memasang bagian baru APUinfo."
+
+#: elf32-ppc.c:3364
+msgid "%B: relocation %s cannot be used when making a shared object"
+msgstr "%B: relokasi %s tidak dapat digunakan ketika membuat sebuah objek terbagi"
+
+#. It does not make sense to have a procedure linkage
+#. table entry for a local symbol.
+#: elf32-ppc.c:3723
+msgid "%B(%A+0x%lx): %s reloc against local symbol"
+msgstr "%B(%A+0x%lx): %s relokasi terhadap simbol lokal"
+
+#: elf32-ppc.c:4067 elf32-ppc.c:4082 elfxx-mips.c:12324 elfxx-mips.c:12350
+#: elfxx-mips.c:12372 elfxx-mips.c:12398
+msgid "Warning: %B uses hard float, %B uses soft float"
+msgstr "Peringatan: %B menggunakan hard float, %B menggunakan soft float"
+
+#: elf32-ppc.c:4070 elf32-ppc.c:4074
+msgid "Warning: %B uses double-precision hard float, %B uses single-precision hard float"
+msgstr "Peringatan: %B menggunakan double-precision hard float, %B menggunakan single-precision hard float"
+
+#: elf32-ppc.c:4078
+msgid "Warning: %B uses soft float, %B uses single-precision hard float"
+msgstr "Peringatan: %B menggunakan soft float, %B menggunakan single-precision hard float"
+
+#: elf32-ppc.c:4085 elf32-ppc.c:4089 elfxx-mips.c:12304 elfxx-mips.c:12308
+msgid "Warning: %B uses unknown floating point ABI %d"
+msgstr "Peringatan: %B menggunkaan floating point ABI %d"
+
+#: elf32-ppc.c:4131 elf32-ppc.c:4135
+msgid "Warning: %B uses unknown vector ABI %d"
+msgstr "Peringatan: %B menggunakan vector ABI %d tidak dikenal"
+
+#: elf32-ppc.c:4139
+msgid "Warning: %B uses vector ABI \"%s\", %B uses \"%s\""
+msgstr "Peringatan: %B menggunakan vector ABI \"%s\", %B menggunakan \"%s\""
+
+#: elf32-ppc.c:4156 elf32-ppc.c:4159
+msgid "Warning: %B uses r3/r4 for small structure returns, %B uses memory"
+msgstr "Peringatan: %B menggunakan r3/34 untuk arsitektur kembali kecil, %B menggunakan memori"
+
+#: elf32-ppc.c:4162 elf32-ppc.c:4166
+msgid "Warning: %B uses unknown small structure return convention %d"
+msgstr "Peringatan: %B menggunakan konvensi struktur kembali kecil %d tidak diketahui"
+
+#: elf32-ppc.c:4220
+msgid "%B: compiled with -mrelocatable and linked with modules compiled normally"
+msgstr "%B: dikompile dengan -mrelocatable dan dihubungkan dengan module yang dikompile secara normal"
+
+#: elf32-ppc.c:4228
+msgid "%B: compiled normally and linked with modules compiled with -mrelocatable"
+msgstr "%B: dikompile secara normal dan dihubungkan dengan modul yang dikompile dengan -mrelocatable"
+
+#: elf32-ppc.c:4314
+msgid "Using bss-plt due to %B"
+msgstr "Menggunakan bss-plt karena %B"
+
+#: elf32-ppc.c:7056 elf64-ppc.c:11364
+msgid "%B: unknown relocation type %d for symbol %s"
+msgstr "%B: tipe relokasi %d tidak dikenal untuk simbol %s"
+
+#: elf32-ppc.c:7316
+msgid "%B(%A+0x%lx): non-zero addend on %s reloc against `%s'"
+msgstr "%B(%A+0x%lx): bukan-nol ditambahkan di %s relokasi terhadap `%s'"
+
+#: elf32-ppc.c:7499 elf64-ppc.c:11854
+msgid "%B(%A+0x%lx): relocation %s for indirect function %s unsupported"
+msgstr "%B(%A+0x%lx): Relokasi %s untuk fungsi tidak langsung %s tidak didukung."
+
+#: elf32-ppc.c:7709 elf32-ppc.c:7736 elf32-ppc.c:7787
+msgid "%B: the target (%s) of a %s relocation is in the wrong output section (%s)"
+msgstr "%B: target (%s) dari sebuah relokasi %s berada dalam daerah keluaran salah (%s)"
+
+#: elf32-ppc.c:7847
+msgid "%B: relocation %s is not yet supported for symbol %s."
+msgstr "%B: relokasi %s tidak didukung untuk simbol %s."
+
+#: elf32-ppc.c:7955 elf64-ppc.c:12110
+msgid "%B(%A+0x%lx): %s reloc against `%s': error %d"
+msgstr "%B(%A+0x%lx): %s relokasi terhadap `%s': error %d"
+
+#: elf32-ppc.c:8423
+#, c-format
+msgid "%s not defined in linker created %s"
+msgstr "%s tidak didefinisikan dalam %s yang dibuat oleh penyambung"
+
+#: elf32-s390.c:2207 elf64-s390.c:2179
+msgid "%B(%A+0x%lx): invalid instruction for TLS relocation %s"
+msgstr "%B(%A+0x%lx): instruksi tidak valid untuk relokasi TLS %s"
+
+#: elf32-score.c:1533 elf32-score7.c:1424 elfxx-mips.c:3299
+msgid "not enough GOT space for local GOT entries"
+msgstr "tidak cukup ruang GOT untuk masukan lokal GOT"
+
+#: elf32-score.c:2765
+msgid "address not word align"
+msgstr "alamat tidak selaras dengan ukuran word"
+
+#: elf32-score.c:2850 elf32-score7.c:2685
+#, c-format
+msgid "%s: Malformed reloc detected for section %s"
+msgstr "%s: relokasi malformat terdeteksi untuk bagian %s"
+
+#: elf32-score.c:2901 elf32-score7.c:2736
+msgid "%B: CALL15 reloc at 0x%lx not against global symbol"
+msgstr "%B: CALL15 relokasi di 0x%lx tidak terhadap simbol global"
+
+#: elf32-score.c:4042 elf32-score7.c:3879
+#, c-format
+msgid " [pic]"
+msgstr " [pic]"
+
+#: elf32-score.c:4046 elf32-score7.c:3883
+#, c-format
+msgid " [fix dep]"
+msgstr " [fix dep]"
+
+#: elf32-score.c:4088 elf32-score7.c:3925
+msgid "%B: warning: linking PIC files with non-PIC files"
+msgstr "%B: peringatan: menghubungkan berkas PIC dengan berkas bukan-PIC"
+
+#: elf32-sh-symbian.c:130
+msgid "%B: IMPORT AS directive for %s conceals previous IMPORT AS"
+msgstr "%B: IMPORT SEBAGAI direktif untuk %s menyembunyikan IMPORT SEBAGAI sebelumnya"
+
+#: elf32-sh-symbian.c:383
+msgid "%B: Unrecognised .directive command: %s"
+msgstr "%B: Perintah .directive tidak dikenal: %s"
+
+#: elf32-sh-symbian.c:503
+msgid "%B: Failed to add renamed symbol %s"
+msgstr "%B: Gagal menambahkan simbol diubah namanya %s"
+
+#: elf32-sh.c:533
+msgid "%B: 0x%lx: warning: bad R_SH_USES offset"
+msgstr "%B: 0x%lx: peringatan: ofset R_SH_USES buruk"
+
+#: elf32-sh.c:545
+msgid "%B: 0x%lx: warning: R_SH_USES points to unrecognized insn 0x%x"
+msgstr "%B: 0x%lx: peringatan: R_SH_USES titik tidak dikenal insn 0x%x"
+
+#: elf32-sh.c:562
+msgid "%B: 0x%lx: warning: bad R_SH_USES load offset"
+msgstr "%B: 0x%lx: peringatan: ofset R_SH_USES beban buruk"
+
+#: elf32-sh.c:577
+msgid "%B: 0x%lx: warning: could not find expected reloc"
+msgstr "%B: 0x%lx: peringatan: tidak dapat menemukan relokasi yang diperkirakan"
+
+#: elf32-sh.c:605
+msgid "%B: 0x%lx: warning: symbol in unexpected section"
+msgstr "%B: 0x%lx: peringatan: simbol dalam bagian yang tidak diperkirakan"
+
+#: elf32-sh.c:731
+msgid "%B: 0x%lx: warning: could not find expected COUNT reloc"
+msgstr "%B: 0x%lx: peringatan: tidak dapat menemukan COUNT relokasi"
+
+#: elf32-sh.c:740
+msgid "%B: 0x%lx: warning: bad count"
+msgstr "%B: 0x%lx: peringatan: jumlah buruk"
+
+#: elf32-sh.c:1144 elf32-sh.c:1514
+msgid "%B: 0x%lx: fatal: reloc overflow while relaxing"
+msgstr "%B: 0x%lx: fatal: relokasi overflow ketika relaxing"
+
+#: elf32-sh.c:3270 elf64-sh64.c:1526
+msgid "Unexpected STO_SH5_ISA32 on local symbol is not handled"
+msgstr "Tidak diperkirakan STO_SH5_ISA32 di simbol lokal tidak ditangani"
+
+#: elf32-sh.c:3507
+msgid "%B: 0x%lx: fatal: unaligned branch target for relax-support relocation"
+msgstr "%B: 0x%lx: fatal: unaligned branch target untuk relax-support relokasi"
+
+#: elf32-sh.c:3540 elf32-sh.c:3555
+msgid "%B: 0x%lx: fatal: unaligned %s relocation 0x%lx"
+msgstr "%B: 0x%lx: fatal: unaligned %s relokasi 0x%lx"
+
+#: elf32-sh.c:3569
+msgid "%B: 0x%lx: fatal: R_SH_PSHA relocation %d not in range -32..32"
+msgstr "%B: 0x%lx: fatal: R_SH_PSHA relokasi %d tidak dalam jangkauan -32..32"
+
+#: elf32-sh.c:3583
+msgid "%B: 0x%lx: fatal: R_SH_PSHL relocation %d not in range -32..32"
+msgstr "%B: 0x%lx: fatal: R_SH_PSHL relokasi %d tidak dalam jangkauan -32..32"
+
+#: elf32-sh.c:5256 elf64-alpha.c:4525
+msgid "%B: TLS local exec code cannot be linked into shared objects"
+msgstr "%B: TLS lokal exec kode tidak dapat dihubungkan dalam objek terbagi"
+
+#: elf32-sh64.c:222 elf64-sh64.c:2333
+#, c-format
+msgid "%s: compiled as 32-bit object and %s is 64-bit"
+msgstr "%s: dikompile sebagai 32-bit objek dan %s adalah 64-bit"
+
+#: elf32-sh64.c:225 elf64-sh64.c:2336
+#, c-format
+msgid "%s: compiled as 64-bit object and %s is 32-bit"
+msgstr "%s: dikompile sebagai 64-bit objek dan %s adalah 32-bit"
+
+#: elf32-sh64.c:227 elf64-sh64.c:2338
+#, c-format
+msgid "%s: object size does not match that of target %s"
+msgstr "%s: ukuran objek tidak cocok dari target %s"
+
+#: elf32-sh64.c:450 elf64-sh64.c:2852
+#, c-format
+msgid "%s: encountered datalabel symbol in input"
+msgstr "%s: ditemui datalabel simbol dalam masukan"
+
+#: elf32-sh64.c:527
+msgid "PTB mismatch: a SHmedia address (bit 0 == 1)"
+msgstr "PTB tidak cocok: sebuah SHmedia alamat (bit 0 ==1)"
+
+#: elf32-sh64.c:530
+msgid "PTA mismatch: a SHcompact address (bit 0 == 0)"
+msgstr "PTA tidak cocok: sebuah SHcompact alamat (bit 0 == 0)"
+
+#: elf32-sh64.c:548
+#, c-format
+msgid "%s: GAS error: unexpected PTB insn with R_SH_PT_16"
+msgstr "%s: GAS error: tidak diduga PTB insn dengan R_SH_PT_16"
+
+#: elf32-sh64.c:597
+msgid "%B: error: unaligned relocation type %d at %08x reloc %p\n"
+msgstr "%B: error: tipe relokasi unaligned %d di %08x relokasi %p\n"
+
+#: elf32-sh64.c:673
+#, c-format
+msgid "%s: could not write out added .cranges entries"
+msgstr "%s: tidak dapat menulis masukan tambahan .cranges"
+
+#: elf32-sh64.c:733
+#, c-format
+msgid "%s: could not write out sorted .cranges entries"
+msgstr "%s: tidak dapat menulis masukan terurut .cranges"
+
+#: elf32-sparc.c:89
+msgid "%B: compiled for a 64 bit system and target is 32 bit"
+msgstr "%B: dikompile untuk sebuah sistem 64 bit dan target adalah 32 bit"
+
+#: elf32-sparc.c:102
+msgid "%B: linking little endian files with big endian files"
+msgstr "%B: menghubungkan berkas little endian dengan berkas big endian"
+
+#: elf32-spu.c:723
+msgid "%X%P: overlay section %A does not start on a cache line.\n"
+msgstr "%X%P: bagian overlay %A jangan diawali di sebuah baris cache.\n"
+
+#: elf32-spu.c:731
+msgid "%X%P: overlay section %A is larger than a cache line.\n"
+msgstr "%X%P: bagian overlay %A lebih besar daripada baris cache.\n"
+
+#: elf32-spu.c:751
+msgid "%X%P: overlay section %A is not in cache area.\n"
+msgstr "%X%P: bagian overlay %A tidak berada dalam daerah cache.\n"
+
+#: elf32-spu.c:791
+msgid "%X%P: overlay sections %A and %A do not start at the same address.\n"
+msgstr "%X%P: bagian overlay %A dan %A jangan diawali di alamat yang sama.\n"
+
+#: elf32-spu.c:1015
+msgid "warning: call to non-function symbol %s defined in %B"
+msgstr "peringatan: panggilan bukan-fungsi simbol %s didefinisikan dalam %B"
+
+#: elf32-spu.c:1365
+msgid "%A:0x%v lrlive .brinfo (%u) differs from analysis (%u)\n"
+msgstr "%A:0x%v lrlive .brinfo (%u) berbeda dari analisa (%u)\n"
+
+#: elf32-spu.c:1884
+msgid "%B is not allowed to define %s"
+msgstr "%B tidak diperbolehkan untuk didefinisikan %s"
+
+#: elf32-spu.c:1892
+#, c-format
+msgid "you are not allowed to define %s in a script"
+msgstr "anda tidak diperbolehkan untuk mendefinisikan %s dalam sebuah script"
+
+#: elf32-spu.c:1926
+#, c-format
+msgid "%s in overlay section"
+msgstr "%s dalam daerah overlay"
+
+#: elf32-spu.c:1955
+msgid "overlay stub relocation overflow"
+msgstr "relokasi stub overlay overflow"
+
+#: elf32-spu.c:1964 elf64-ppc.c:10441
+msgid "stubs don't match calculated size"
+msgstr "stub tidak cocok dengan ukuran yang dihitung"
+
+#: elf32-spu.c:2546
+#, c-format
+msgid "warning: %s overlaps %s\n"
+msgstr "peringatan: %s timpang tindih %s\n"
+
+#: elf32-spu.c:2562
+#, c-format
+msgid "warning: %s exceeds section size\n"
+msgstr "peringatan: %s melebihi ukuran daerah\n"
+
+#: elf32-spu.c:2593
+msgid "%A:0x%v not found in function table\n"
+msgstr "%A:0x%v tidak ditemukan dalam tabel fungsi\n"
+
+#: elf32-spu.c:2740
+msgid "%B(%A+0x%v): call to non-code section %B(%A), analysis incomplete\n"
+msgstr "%B(%A+0x%v): panggilan untuk daerah bukan-kode %B(%A), analysis tidak lengkap\n"
+
+#: elf32-spu.c:3297
+#, c-format
+msgid "Stack analysis will ignore the call from %s to %s\n"
+msgstr "Stack analysis akan mengabaikan panggilan dari %s ke %s\n"
+
+#: elf32-spu.c:3988
+msgid " %s: 0x%v\n"
+msgstr " %s: 0x%v\n"
+
+#: elf32-spu.c:3989
+msgid "%s: 0x%v 0x%v\n"
+msgstr "%s: 0x%v 0x%v\n"
+
+#: elf32-spu.c:3994
+msgid " calls:\n"
+msgstr " panggilan:\n"
+
+#: elf32-spu.c:4002
+#, c-format
+msgid " %s%s %s\n"
+msgstr " %s%s %s\n"
+
+#: elf32-spu.c:4304
+#, c-format
+msgid "%s duplicated in %s\n"
+msgstr "%s duplikasi dalam %s\n"
+
+#: elf32-spu.c:4308
+#, c-format
+msgid "%s duplicated\n"
+msgstr "%s duplikasi\n"
+
+#: elf32-spu.c:4315
+msgid "sorry, no support for duplicate object files in auto-overlay script\n"
+msgstr "maaf, tidak ada dukungan untuk duplikasi berkas objek dalam auto-overlay script\n"
+
+#: elf32-spu.c:4356
+msgid "non-overlay size of 0x%v plus maximum overlay size of 0x%v exceeds local store\n"
+msgstr "ukuran non-overlay dari 0x%v plus maksimul overlay size dari 0x%v melebihi lokal store\n"
+
+#: elf32-spu.c:4512
+msgid "%B:%A%s exceeds overlay size\n"
+msgstr "%B:%A%s melebihi ukuran overlay\n"
+
+#: elf32-spu.c:4669
+msgid "Stack size for call graph root nodes.\n"
+msgstr "Ukuran stack untuk panggilan graph titik root.\n"
+
+#: elf32-spu.c:4670
+msgid ""
+"\n"
+"Stack size for functions. Annotations: '*' max stack, 't' tail call\n"
+msgstr ""
+"\n"
+"Ukuran stack untuk fungsi. Anotasi: '*' max stack, 't' tail call\n"
+
+#: elf32-spu.c:4680
+msgid "Maximum stack required is 0x%v\n"
+msgstr "Maksimal stack dibutuhkan adalah 0x%v\n"
+
+#: elf32-spu.c:4771
+msgid "fatal error while creating .fixup"
+msgstr "kesalahan fatal ketika membuat .fixup"
+
+#: elf32-spu.c:5009
+msgid "%B(%s+0x%lx): unresolvable %s relocation against symbol `%s'"
+msgstr "%B(%s=0x%lx): tidak teresolf %s relokasi terhadap simbol `%s'"
+
+#: elf32-v850.c:163
+#, c-format
+msgid "Variable `%s' cannot occupy in multiple small data regions"
+msgstr "Variabel `%s' tidak dapat mengisi dalam beberapa daerah data kecil"
+
+#: elf32-v850.c:166
+#, c-format
+msgid "Variable `%s' can only be in one of the small, zero, and tiny data regions"
+msgstr "Variabel `%s' hanya dapat berada dalam satu dari kecil, nol, dan sangat kecil daerah data"
+
+#: elf32-v850.c:169
+#, c-format
+msgid "Variable `%s' cannot be in both small and zero data regions simultaneously"
+msgstr "Variabel `%s' tidak dapat berada dalam kecil dan nol daerah data secara bersamaan"
+
+#: elf32-v850.c:172
+#, c-format
+msgid "Variable `%s' cannot be in both small and tiny data regions simultaneously"
+msgstr "Variabel `%s' tidak dapat berada dalam kecil dan sangat kecil daerah data secara bersamaan"
+
+#: elf32-v850.c:175
+#, c-format
+msgid "Variable `%s' cannot be in both zero and tiny data regions simultaneously"
+msgstr "variabel `%s' tidak dapat dalam nol dan kecil daerah data secara bersamaan"
+
+#: elf32-v850.c:478
+#, c-format
+msgid "FAILED to find previous HI16 reloc\n"
+msgstr "GAGAL untuk menemukan relokasi HI16 sebelumnya\n"
+
+#: elf32-v850.c:1713
+msgid "could not locate special linker symbol __gp"
+msgstr "tidak dapat menemukan simbol linker spesial __gp"
+
+#: elf32-v850.c:1717
+msgid "could not locate special linker symbol __ep"
+msgstr "tidak dapat menemukan simbol linker spesial __ep"
+
+#: elf32-v850.c:1721
+msgid "could not locate special linker symbol __ctbp"
+msgstr "tidak dapat menemukan simbol linker spesial __ctbp"
+
+#: elf32-v850.c:1871
+msgid "%B: Architecture mismatch with previous modules"
+msgstr "%B: Arsitektur tidak cocok dengan modul sebelumnya"
+
+#: elf32-v850.c:1890
+#, c-format
+msgid "private flags = %lx: "
+msgstr "private flags = %lx: "
+
+#: elf32-v850.c:1895
+#, c-format
+msgid "v850 architecture"
+msgstr "v850 arsitektur"
+
+#: elf32-v850.c:1896
+#, c-format
+msgid "v850e architecture"
+msgstr "v850e arsitektur"
+
+#: elf32-v850.c:1897
+#, c-format
+msgid "v850e1 architecture"
+msgstr "v850e1 arsitektur"
+
+#: elf32-vax.c:543
+#, c-format
+msgid " [nonpic]"
+msgstr " [bukan-pic]"
+
+#: elf32-vax.c:546
+#, c-format
+msgid " [d-float]"
+msgstr " [d-float]"
+
+#: elf32-vax.c:549
+#, c-format
+msgid " [g-float]"
+msgstr " [g-float]"
+
+#: elf32-vax.c:666
+#, c-format
+msgid "%s: warning: GOT addend of %ld to `%s' does not match previous GOT addend of %ld"
+msgstr "%s: peringatan: GOT ditambahkan dari %ld ke `%s' tidak cocok dengan penambahan GOT sebelumnya dari %ld"
+
+#: elf32-vax.c:1608
+#, c-format
+msgid "%s: warning: PLT addend of %d to `%s' from %s section ignored"
+msgstr "%s: peringatan: PLT ditambahkan dari %d ke `%s' dari %s bagian diabaikan"
+
+#: elf32-vax.c:1735
+#, c-format
+msgid "%s: warning: %s relocation against symbol `%s' from %s section"
+msgstr "%s: peringatan: %s relokasi terhadap simbol `%s' dari bagian %s"
+
+#: elf32-vax.c:1741
+#, c-format
+msgid "%s: warning: %s relocation to 0x%x from %s section"
+msgstr "%s: peringatan: relokasi %s ke 0x%x dari daerah %s"
+
+#: elf32-xstormy16.c:451 elf32-ia64.c:2791 elf64-ia64.c:2791
+msgid "non-zero addend in @fptr reloc"
+msgstr "bukan-nol ditambahkan dalam @fptr relokasi"
+
+#: elf32-xtensa.c:912
+msgid "%B(%A): invalid property table"
+msgstr "%B(%A): tabel properti tidak valid"
+
+#: elf32-xtensa.c:2740
+msgid "%B(%A+0x%lx): relocation offset out of range (size=0x%x)"
+msgstr "%B(%A+0x%lx): ofset relokasi diluar jangkauan (size=0x%x)"
+
+#: elf32-xtensa.c:2819 elf32-xtensa.c:2940
+msgid "dynamic relocation in read-only section"
+msgstr "relokasi dinamis dalam bagian baca-saja"
+
+#: elf32-xtensa.c:2916
+msgid "TLS relocation invalid without dynamic sections"
+msgstr "relokasi TLS tidak valid tanpa bagian dinamis"
+
+#: elf32-xtensa.c:3133
+msgid "internal inconsistency in size of .got.loc section"
+msgstr "internal tidak konsisten dalam ukuran dari daerah .got.loc"
+
+#: elf32-xtensa.c:3443
+msgid "%B: incompatible machine type. Output is 0x%x. Input is 0x%x"
+msgstr "%B: tipe mesin tidak kompatibel. Keluaran adalah 0x%x. Masukan adalah 0x%x"
+
+#: elf32-xtensa.c:4672 elf32-xtensa.c:4680
+msgid "Attempt to convert L32R/CALLX to CALL failed"
+msgstr "Mencoba untuk mengubah L32R/CALLX ke CALL gagal"
+
+#: elf32-xtensa.c:6290 elf32-xtensa.c:6366 elf32-xtensa.c:7486
+msgid "%B(%A+0x%lx): could not decode instruction; possible configuration mismatch"
+msgstr "%B(%A+0x%lx): tidak dapat mendeko instruksi; mungkin konfigurasi tidak cocok"
+
+#: elf32-xtensa.c:7226
+msgid "%B(%A+0x%lx): could not decode instruction for XTENSA_ASM_SIMPLIFY relocation; possible configuration mismatch"
+msgstr "%B(%A+0x%lx): tidak dapat mendeko instruksi untuk XTENSA_ASM_SIMPLIFY relokasi; mungkin konfigurasi tidak cocok"
+
+#: elf32-xtensa.c:8987
+msgid "invalid relocation address"
+msgstr "alamat relokasi tidak valid"
+
+#: elf32-xtensa.c:9036
+msgid "overflow after relaxation"
+msgstr "overflow setelah relaksasi"
+
+#: elf32-xtensa.c:10167
+msgid "%B(%A+0x%lx): unexpected fix for %s relocation"
+msgstr "%B(%A+0x%lx): unexpected fix untuk relokasi %s"
+
+#: elf64-alpha.c:452
+msgid "GPDISP relocation did not find ldah and lda instructions"
+msgstr "GPDISP relokasi tidak dapat menemukan instruksi ldah dan lda"
+
+#: elf64-alpha.c:2389
+msgid "%B: .got subsegment exceeds 64K (size %d)"
+msgstr "%B: .got subsegmen melebihi 64K (size %d)"
+
+#: elf64-alpha.c:4269 elf64-alpha.c:4281
+msgid "%B: gp-relative relocation against dynamic symbol %s"
+msgstr "%B: gp-relative relokasi terhadap simbol dinamis %s"
+
+#: elf64-alpha.c:4307 elf64-alpha.c:4442
+msgid "%B: pc-relative relocation against dynamic symbol %s"
+msgstr "%B: pc-relative relokasi terhadap simbol dinamis %s"
+
+#: elf64-alpha.c:4335
+msgid "%B: change in gp: BRSGP %s"
+msgstr "%B: perubahan dalam gp: BRSGP %s"
+
+#: elf64-alpha.c:4360
+msgid "<unknown>"
+msgstr "<tidak dikenal>"
+
+#: elf64-alpha.c:4365
+msgid "%B: !samegp reloc against symbol without .prologue: %s"
+msgstr "%B: !samegp relokasi terhadap simbol tanpa .prologue: %s"
+
+#: elf64-alpha.c:4417
+msgid "%B: unhandled dynamic relocation against %s"
+msgstr "%B: relokasi dinamis tidak ditangani terhadap %s"
+
+#: elf64-alpha.c:4449
+msgid "%B: pc-relative relocation against undefined weak symbol %s"
+msgstr "%B: pc-relative relokasi terhadap simbol lemah tidak terdefinisi %s"
+
+#: elf64-alpha.c:4509
+msgid "%B: dtp-relative relocation against dynamic symbol %s"
+msgstr "%B: dtp-relative relokasi terhadap simbol dinamis %s"
+
+#: elf64-alpha.c:4532
+msgid "%B: tp-relative relocation against dynamic symbol %s"
+msgstr "%B: tp-relative relokasi terhadap simbol dinamis %s"
+
+#: elf64-hppa.c:2091
+#, c-format
+msgid "stub entry for %s cannot load .plt, dp offset = %ld"
+msgstr "masukan stub untuk %s tidak dapat diload .plt, dp ofset = %ld"
+
+#: elf64-hppa.c:3273
+msgid "%B(%A+0x%lx): cannot reach %s"
+msgstr "%B(%A+0x%lx): tidak dapat mencapai %s"
+
+#: elf64-mmix.c:1177
+#, c-format
+msgid ""
+"%s: Internal inconsistency error for value for\n"
+" linker-allocated global register: linked: 0x%lx%08lx != relaxed: 0x%lx%08lx\n"
+msgstr ""
+"%s: Internal tidak konsisten error untuk nilai untuk\n"
+" linker-allocated global register: terhubung: 0x%lx%08lx != relaxed: 0x%lx%08lx\n"
+
+#: elf64-mmix.c:1618
+#, c-format
+msgid "%s: base-plus-offset relocation against register symbol: (unknown) in %s"
+msgstr "%s: base-plus-offset relokasi terhadap simbol register: (tidak diketahui) dalam %s"
+
+#: elf64-mmix.c:1623
+#, c-format
+msgid "%s: base-plus-offset relocation against register symbol: %s in %s"
+msgstr "%s: base-plus-offset relokasi terhadap simbol register: %s dalam %s"
+
+#: elf64-mmix.c:1667
+#, c-format
+msgid "%s: register relocation against non-register symbol: (unknown) in %s"
+msgstr "%s: register relokasi terhadap non-register simbol: (tidak diketahui) dalam %s"
+
+#: elf64-mmix.c:1672
+#, c-format
+msgid "%s: register relocation against non-register symbol: %s in %s"
+msgstr "%s: register relokasi terhadap bukan-register simbol: %s dalam %s"
+
+#: elf64-mmix.c:1709
+#, c-format
+msgid "%s: directive LOCAL valid only with a register or absolute value"
+msgstr "%s: direktif LOKAL hanya valid dengan sebuah register atau nilai absolut"
+
+#: elf64-mmix.c:1737
+#, c-format
+msgid "%s: LOCAL directive: Register $%ld is not a local register. First global register is $%ld."
+msgstr "%s: LOKAL direktif: Register $%ld bukan sebuah lokal register. Pertama global registar adala $%ld."
+
+#: elf64-mmix.c:2201
+#, c-format
+msgid "%s: Error: multiple definition of `%s'; start of %s is set in a earlier linked file\n"
+msgstr "%s: Error: multiple definisi dari `%s'; awal dari %s adalah diset dalam sebuah sebelum berkas terlink\n"
+
+#: elf64-mmix.c:2259
+msgid "Register section has contents\n"
+msgstr "Daerah register memiliki isi\n"
+
+#: elf64-mmix.c:2451
+#, c-format
+msgid ""
+"Internal inconsistency: remaining %u != max %u.\n"
+" Please report this bug."
+msgstr ""
+"Internal tidak konsisten: sisa %u != max %u.\n"
+" Tolong laporkan bug ini."
+
+#: elf64-ppc.c:2691 libbfd.c:978
+msgid "%B: compiled for a big endian system and target is little endian"
+msgstr "%B: dikompile untuk sebuah sistem big endian dan target adalah little endian"
+
+#: elf64-ppc.c:2694 libbfd.c:980
+msgid "%B: compiled for a little endian system and target is big endian"
+msgstr "%B: dikompile untuk sebuah sistem little endian dan target adalah big endian"
+
+#: elf64-ppc.c:6338
+#, c-format
+msgid "copy reloc against `%s' requires lazy plt linking; avoid setting LD_BIND_NOW=1 or upgrade gcc"
+msgstr "salin relokasi terhadap `%s' membutuhkan lazy plt linking; hindari konfigurasi LD_BIND_NOW=1 atau upgrade gcc"
+
+#: elf64-ppc.c:6767
+msgid "dynreloc miscount for %B, section %A"
+msgstr "dynareloc miscount untuk %B, bagian %A"
+
+#: elf64-ppc.c:6851
+msgid "%B: .opd is not a regular array of opd entries"
+msgstr "%B: .opd adalah bukan array regular dari masukan opd"
+
+#: elf64-ppc.c:6860
+msgid "%B: unexpected reloc type %u in .opd section"
+msgstr "%B: tipe relokasi %u tidak diduga dalam bagian .opd"
+
+#: elf64-ppc.c:6881
+msgid "%B: undefined sym `%s' in .opd section"
+msgstr "%B: tidak terdefinisi simbol `%s' dalam bagian .opd"
+
+#: elf64-ppc.c:7640 elf64-ppc.c:8017
+#, c-format
+msgid "%s defined in removed toc entry"
+msgstr "%s terdefinisi dalam masukan toc terhapus"
+
+#: elf64-ppc.c:8910
+#, c-format
+msgid "long branch stub `%s' offset overflow"
+msgstr "stub brach panjang `%s' ofset overflow"
+
+#: elf64-ppc.c:8969
+#, c-format
+msgid "can't find branch stub `%s'"
+msgstr "tidak dapat menemukan branch stub `%s'"
+
+#: elf64-ppc.c:9031 elf64-ppc.c:9169
+#, c-format
+msgid "linkage table error against `%s'"
+msgstr "linkage tabel error terhadap `%s'"
+
+#: elf64-ppc.c:9326
+#, c-format
+msgid "can't build branch stub `%s'"
+msgstr "tidak dapat membuat branch stub `%s'"
+
+#: elf64-ppc.c:9799
+msgid "%B section %A exceeds stub group size"
+msgstr "%B bagian %A melebihi ukuran grup stub"
+
+#: elf64-ppc.c:10453
+#, c-format
+msgid ""
+"linker stubs in %u group%s\n"
+" branch %lu\n"
+" toc adjust %lu\n"
+" long branch %lu\n"
+" long toc adj %lu\n"
+" plt call %lu"
+msgstr ""
+"linker stubs dalam %u grup %s\n"
+" cabang %lu\n"
+" toc adjust %lu\n"
+" cabang panjang %lu\n"
+" long toc adj %lu\n"
+" plt call %lu"
+
+#: elf64-ppc.c:11252
+msgid "%B(%A+0x%lx): automatic multiple TOCs not supported using your crt files; recompile with -mminimal-toc or upgrade gcc"
+msgstr "%B(%A+0x%lx): otomatis multiple TOC tidak didukung menggunakan berkas crt anda; rekompile dengan -mminimal-toc atau upgrade gcc"
+
+#: elf64-ppc.c:11260
+msgid "%B(%A+0x%lx): sibling call optimization to `%s' does not allow automatic multiple TOCs; recompile with -mminimal-toc or -fno-optimize-sibling-calls, or make `%s' extern"
+msgstr "%B(%A+0x%lx): sibling call optimization ke `%s' tidak membolehkan otomatis multiple TOC; rekompile dengan -mminimal-toc atau -fno-optimize-sibling-calls, atau buat `%s' extern"
+
+#: elf64-ppc.c:11961
+msgid "%B: relocation %s is not supported for symbol %s."
+msgstr "%B: relokasi %s tidak didukung untuk simbol %s."
+
+#: elf64-ppc.c:12044
+msgid "%B: error: relocation %s not a multiple of %d"
+msgstr "%B: error: relokasi %s bukan multiple dari %d"
+
+#: elf64-sh64.c:1701
+#, c-format
+msgid "%s: error: unaligned relocation type %d at %08x reloc %08x\n"
+msgstr "%s: error: tipe relokasi %d unaligned di %08x relokasi %08x\n"
+
+#: elf64-sparc.c:439
+msgid "%B: Only registers %%g[2367] can be declared using STT_REGISTER"
+msgstr "%B: Hanya register %%g[2367] dapat dideklarasikan menggunakan STT_REGISTER"
+
+#: elf64-sparc.c:459
+msgid "Register %%g%d used incompatibly: %s in %B, previously %s in %B"
+msgstr "Register %%g%d digunakan tidak kompatibel: %s dalam %B, sebelumnya %s dalam %B"
+
+#: elf64-sparc.c:482
+msgid "Symbol `%s' has differing types: REGISTER in %B, previously %s in %B"
+msgstr "Simbol `%s' memiliki tipe berbeda: REGISTER dalam %B, sebelumnya %s dalam %B"
+
+#: elf64-sparc.c:527
+msgid "Symbol `%s' has differing types: %s in %B, previously REGISTER in %B"
+msgstr "Simbol `%s' memiliki tipe berbeda: %s dalam %B, sebelumnya REGISTER dalam %B"
+
+#: elf64-sparc.c:679
+msgid "%B: linking UltraSPARC specific with HAL specific code"
+msgstr "%B: menghubungkan UltraSPARC spesifik dengan HAL spesifik kode"
+
+#: elf64-x86-64.c:1337
+msgid "%B: '%s' accessed both as normal and thread local symbol"
+msgstr "%B: '%s' keduanya diakses secara normal dan thread simbol lokal"
+
+#: elf64-x86-64.c:2701
+msgid "%B: relocation %s against STT_GNU_IFUNC symbol `%s' has non-zero addend: %d"
+msgstr "%B: relokasi %s terhadap STT_GNU_IFUNC simbol `%s' memiliki addend bukan-nol: %d"
+
+#: elf64-x86-64.c:2980
+msgid "%B: relocation R_X86_64_GOTOFF64 against protected function `%s' can not be used when making a shared object"
+msgstr "%B: relokasi R_X86_64_GOTOFF64 terhadap fungsi terproteksi `%s' tidak dapat digunakan ketika membuat sebuah objek terbagi"
+
+#: elf64-x86-64.c:3091
+msgid "; recompile with -fPIC"
+msgstr "; rekompile dengan -fPIC"
+
+#: elf64-x86-64.c:3096
+msgid "%B: relocation %s against %s `%s' can not be used when making a shared object%s"
+msgstr "%B: relokasi %s terhadap %s `%s' tidak dapat digunakan ketika membuat sebuah objek terbagi%s"
+
+#: elf64-x86-64.c:3098
+msgid "%B: relocation %s against undefined %s `%s' can not be used when making a shared object%s"
+msgstr "%B: relokasi %s terhadap tidak terdefinisi %s `%s' tidak dapat digunakan ketika membuat sebuah objek terbagi %s"
+
+#: elfcode.h:795
+#, c-format
+msgid "warning: %s has a corrupt string table index - ignoring"
+msgstr "peringatan: %s memiliki sebuah string tabel korup index - diabaikan"
+
+#: elfcode.h:1201
+#, c-format
+msgid "%s: version count (%ld) does not match symbol count (%ld)"
+msgstr "%s: versi terhitung (%ld) tidak cocok dengan simbol terhitung (%ld)"
+
+#: elfcode.h:1441
+#, c-format
+msgid "%s(%s): relocation %d has invalid symbol index %ld"
+msgstr "%s(%s): relokasi %d memiliki indek simbol tidak valid %ld"
+
+#: elfcore.h:251
+msgid "Warning: %B is truncated: expected core file size >= %lu, found: %lu."
+msgstr "Peringatan: %B terpotong: diperkirakan ukuran berkas core >= %lu, ditemukan: %lu."
+
+#: elflink.c:1113
+msgid "%s: TLS definition in %B section %A mismatches non-TLS definition in %B section %A"
+msgstr "%s: TLS definisi dalam %B bagian %A tidak cocok bukan-TLS definisi dalam %B bagian %A"
+
+#: elflink.c:1117
+msgid "%s: TLS reference in %B mismatches non-TLS reference in %B"
+msgstr "%s: TLS referensi dalam %B tidak cocok bukan-TLS referensi dalam %B"
+
+#: elflink.c:1121
+msgid "%s: TLS definition in %B section %A mismatches non-TLS reference in %B"
+msgstr "%s: TLS definisi dalam %B bagian %A tidak cocok bukan-TLS referensi dalam %B"
+
+#: elflink.c:1125
+msgid "%s: TLS reference in %B mismatches non-TLS definition in %B section %A"
+msgstr "%s: TLS referensi dalam %B tidak cocok bukan-TLS definisi dalam %B bagian %A"
+
+#: elflink.c:1764
+msgid "%B: unexpected redefinition of indirect versioned symbol `%s'"
+msgstr "%B: tidak diduga redefinisi dari indirek versioned simbol `%s'"
+
+#: elflink.c:2077
+msgid "%B: version node not found for symbol %s"
+msgstr "%B: titik versi tidak ditemukan untuk simbol %s"
+
+#: elflink.c:2167
+msgid "%B: bad reloc symbol index (0x%lx >= 0x%lx) for offset 0x%lx in section `%A'"
+msgstr "%B: bad relokasi simbol indeks (0x%lx >= 0x%lx) untuk ofset 0x%lx dalam daerah `%A'"
+
+#: elflink.c:2178
+msgid "%B: non-zero symbol index (0x%lx) for offset 0x%lx in section `%A' when the object file has no symbol table"
+msgstr "%B: bukan-nol simbol indeks (0x%lx) untuk offset 0x%lx dalam bagian `%A' ketika berkas objek tidak memiliki tabel simbol"
+
+#: elflink.c:2375
+msgid "%B: relocation size mismatch in %B section %A"
+msgstr "%B: ukuran relokasi tidak cocok dalam %B bagian %A"
+
+#: elflink.c:2678
+#, c-format
+msgid "warning: type and size of dynamic symbol `%s' are not defined"
+msgstr "peringatan: tipe dan ukuran dari simbol dinamis `%s' tidak terdefinisi"
+
+#: elflink.c:3424
+msgid "%P: alternate ELF machine code found (%d) in %B, expecting %d\n"
+msgstr "%P: kode mesin alternatif untuk ELF ditemukan (%d) dalam %B, diduga %d\n"
+
+#: elflink.c:4032
+msgid "%B: %s: invalid version %u (max %d)"
+msgstr "%B: %s: versi %u tidak valid (max %d)"
+
+#: elflink.c:4068
+msgid "%B: %s: invalid needed version %d"
+msgstr "%B: %s: tidak valid dibutuhkan versi %d"
+
+#: elflink.c:4253
+msgid "Warning: alignment %u of common symbol `%s' in %B is greater than the alignment (%u) of its section %A"
+msgstr "Peringatan: alignmen %u dari simbol umum `%s' dalam %B adalah lebih besar daripada alignment (%u) dari bagian ini %A"
+
+#: elflink.c:4259
+msgid "Warning: alignment %u of symbol `%s' in %B is smaller than %u in %B"
+msgstr "Peringatan: alignment %u dari simbol `%s' dalam %B adalah lebih kecil daripada %u dalam %B"
+
+#: elflink.c:4274
+msgid "Warning: size of symbol `%s' changed from %lu in %B to %lu in %B"
+msgstr "Peringatan: ukuran dari simbol `%s' berubah dari %lu dalam %B ke %lu dalam %B"
+
+#: elflink.c:4438
+#, c-format
+msgid "%s: invalid DSO for symbol `%s' definition"
+msgstr "%s: tidak valid DSO untuk simbol `%s' definisi"
+
+#: elflink.c:5688
+#, c-format
+msgid "%s: undefined version: %s"
+msgstr "%s: versi tidak terdefinisi: %s"
+
+#: elflink.c:5756
+msgid "%B: .preinit_array section is not allowed in DSO"
+msgstr "%B: .preinit_array bagian tidak diperbolehkan dalam DSO"
+
+#: elflink.c:7484
+#, c-format
+msgid "undefined %s reference in complex symbol: %s"
+msgstr "undefined %s referensi dalam simbol kompleks: %s"
+
+#: elflink.c:7638
+#, c-format
+msgid "unknown operator '%c' in complex symbol"
+msgstr "operator tidak diketahui '%c' dalam simbol kompleks"
+
+#: elflink.c:7976 elflink.c:7993 elflink.c:8030 elflink.c:8047
+msgid "%B: Unable to sort relocs - they are in more than one size"
+msgstr "%B: Tidak dapat mengurutkan relokasi - mereka berada dalam lebih dari satu ukuran"
+
+#: elflink.c:8007 elflink.c:8061
+msgid "%B: Unable to sort relocs - they are of an unknown size"
+msgstr "%B: Tidak dapat mengurutkan relokasi - mereka dari ukuran yang tidak diketahui"
+
+#: elflink.c:8112
+msgid "Not enough memory to sort relocations"
+msgstr "Tidak cukup memori untuk mengurutkan relokasi"
+
+#: elflink.c:8304
+msgid "%B: Too many sections: %d (>= %d)"
+msgstr "%B: Terlalu banyak bagian: %d (>= %d)"
+
+#: elflink.c:8540
+msgid "%B: %s symbol `%s' in %B is referenced by DSO"
+msgstr "%B: %s simbol `%s' dalam %B adalah direferensikan oleh DSO"
+
+#: elflink.c:8625
+msgid "%B: could not find output section %A for input section %A"
+msgstr "%B: tidak dapat menemukan bagian keluaran %A untuk daerah masukan %A"
+
+#: elflink.c:8745
+msgid "%B: %s symbol `%s' isn't defined"
+msgstr "%B: %s simbol `%s' tidak didefinisikan"
+
+#: elflink.c:9301
+msgid "error: %B contains a reloc (0x%s) for section %A that references a non-existent global symbol"
+msgstr "error: %B berisi sebuah relokasi (0x%s) untuk daerah %A yang mereferensikan sebuah bukan-exist simbol global"
+
+#: elflink.c:9366
+msgid "%X`%s' referenced in section `%A' of %B: defined in discarded section `%A' of %B\n"
+msgstr "%X`%s' direferensikan dalam daerah `%A' dari %B: didefinisikan dalam daerah diabaikan `%A' dari %B\n"
+
+#: elflink.c:9991
+msgid "%A has both ordered [`%A' in %B] and unordered [`%A' in %B] sections"
+msgstr "%A memiliki keduanya terurut [`%A' dalam %B] dan daerah tidak terurut [`%A' dalam %B]"
+
+#: elflink.c:9996
+#, c-format
+msgid "%A has both ordered and unordered sections"
+msgstr "%A memiliki daerah terurut dan tidak terurut"
+
+#: elflink.c:10872 elflink.c:10916
+msgid "%B: could not find output section %s"
+msgstr "%B: tidak dapat menemukan daerah keluaran %s"
+
+#: elflink.c:10877
+#, c-format
+msgid "warning: %s section has zero size"
+msgstr "peringatan: %s daerah memiliki ukuran nol"
+
+#: elflink.c:10982
+msgid "%P: warning: creating a DT_TEXTREL in a shared object.\n"
+msgstr "%P: peringatan: membuat sebuah DT_TEXTREL dalam sebuah objek terbagi.\n"
+
+#: elflink.c:11165
+msgid "%P%X: can not read symbols: %E\n"
+msgstr "%P%X: tidak dapat membaca simbol: %E\n"
+
+#: elflink.c:11483
+msgid "Removing unused section '%s' in file '%B'"
+msgstr "Menghapus daerah tidak digunakan '%s' dalam berkas '%B'"
+
+#: elflink.c:11695
+msgid "Warning: gc-sections option ignored"
+msgstr "Peringatan: gc-sections pilihan diabaikan"
+
+#: elflink.c:12242
+msgid "%B: ignoring duplicate section `%A'"
+msgstr "%B: peringatan daerah duplikasi `%A'"
+
+#: elflink.c:12249 elflink.c:12256
+msgid "%B: duplicate section `%A' has different size"
+msgstr "%B: daerah duplikasi `%A' memiliki ukuran berbeda"
+
+#: elflink.c:12264 elflink.c:12269
+msgid "%B: warning: could not read contents of section `%A'"
+msgstr "%B: peringatan: tidak dapat membaca isi dari daerah `%A'"
+
+#: elflink.c:12273
+msgid "%B: warning: duplicate section `%A' has different contents"
+msgstr "%B: peringatan: duplikasi daerah `%A' memiliki isi berbeda"
+
+#: elflink.c:12374 linker.c:3098
+msgid "%F%P: already_linked_table: %E\n"
+msgstr "%F%P: already_linked_table: %E\n"
+
+#: elfxx-mips.c:1222
+msgid "static procedure (no name)"
+msgstr "prosedur statis (tidak bernama)"
+
+#: elfxx-mips.c:5588
+msgid "%B: %A+0x%lx: jump to stub routine which is not jal"
+msgstr "%B: %A+0x%lx: lompat ke routine stub dimana bukan jal"
+
+#: elfxx-mips.c:6235 elfxx-mips.c:6458
+msgid "%B: Warning: bad `%s' option size %u smaller than its header"
+msgstr "%B: Peringatan: pilihan `%s' buruk ukuran %u lebih kecil dari headernya"
+
+#: elfxx-mips.c:7205 elfxx-mips.c:7330
+msgid "%B: Warning: cannot determine the target function for stub section `%s'"
+msgstr "%B: Peringatan: tidak dapat menentukan fungsi terget untuk daerah stub `%s'"
+
+#: elfxx-mips.c:7459
+msgid "%B: Malformed reloc detected for section %s"
+msgstr "%B: Malformed relokasi terdeteksi untuk daerah %s"
+
+#: elfxx-mips.c:7499
+msgid "%B: GOT reloc at 0x%lx not expected in executables"
+msgstr "%B: GOT relokasi di 0x%lx tidak diduga dalam aplikasi"
+
+#: elfxx-mips.c:7602
+msgid "%B: CALL16 reloc at 0x%lx not against global symbol"
+msgstr "%B: CALL16 relokasi di 0x%lx tidak terhadap simbol global"
+
+#: elfxx-mips.c:8280
+#, c-format
+msgid "non-dynamic relocations refer to dynamic symbol %s"
+msgstr "bukan-dinamis relokasi refer ke simbol dinamis %s"
+
+#: elfxx-mips.c:8985
+msgid "%B: Can't find matching LO16 reloc against `%s' for %s at 0x%lx in section `%A'"
+msgstr "%B: Tidak dapat menemukan cocok LO16 relokasi terhadap `%s' untuk %s di 0x%lx di daerah `%A'"
+
+#: elfxx-mips.c:9124
+msgid "small-data section exceeds 64KB; lower small-data size limit (see option -G)"
+msgstr "daerah data-kecil melebihi 64KB; dibawah data-kecil batas ukuran (lihat pilihan -G)"
+
+#: elfxx-mips.c:11940
+#, c-format
+msgid "%s: illegal section name `%s'"
+msgstr "%s: nama daerah `%s' ilegal"
+
+#: elfxx-mips.c:12318 elfxx-mips.c:12344
+msgid "Warning: %B uses -msingle-float, %B uses -mdouble-float"
+msgstr "Peringatan: %B menggunakan 0msingle-float, %B menggunakan -mdouble-float"
+
+#: elfxx-mips.c:12330 elfxx-mips.c:12386
+msgid "Warning: %B uses -msingle-float, %B uses -mips32r2 -mfp64"
+msgstr "Peringatan: %B menggunakan -msingle-float, %B menggunakan -mips32r2 -mfp64"
+
+#: elfxx-mips.c:12356 elfxx-mips.c:12392
+msgid "Warning: %B uses -mdouble-float, %B uses -mips32r2 -mfp64"
+msgstr "Peringatan: %B menggunakan -mdouble-float, %B menggunakan -mips32r2 -mfp64"
+
+#: elfxx-mips.c:12434
+msgid "%B: endianness incompatible with that of the selected emulation"
+msgstr "%B: endianness tidak kompatibel dengan yang dipilih di emulasi"
+
+#: elfxx-mips.c:12445
+msgid "%B: ABI is incompatible with that of the selected emulation"
+msgstr "%B: ABI tidak kompatibel dengan yang dipilih di emulasi"
+
+#: elfxx-mips.c:12526
+msgid "%B: warning: linking abicalls files with non-abicalls files"
+msgstr "%B: peringatan: menghubungkan berkas abicalls dengan berkas bukan-abicalls"
+
+#: elfxx-mips.c:12543
+msgid "%B: linking 32-bit code with 64-bit code"
+msgstr "%B: menghubungkan 32-bit kode dengan 64-bit kode"
+
+#: elfxx-mips.c:12571
+msgid "%B: linking %s module with previous %s modules"
+msgstr "%B: menghubungkan %s modul dengan modul %s sebelumnya"
+
+#: elfxx-mips.c:12594
+msgid "%B: ABI mismatch: linking %s module with previous %s modules"
+msgstr "%B: ABI tidak cocok: menghubungkan modul %s dengan modul %s sebelumnya"
+
+#: elfxx-mips.c:12758
+#, c-format
+msgid " [abi=O32]"
+msgstr " [abi=032]"
+
+#: elfxx-mips.c:12760
+#, c-format
+msgid " [abi=O64]"
+msgstr " [abi=064]"
+
+#: elfxx-mips.c:12762
+#, c-format
+msgid " [abi=EABI32]"
+msgstr " [abi=EABI32]"
+
+#: elfxx-mips.c:12764
+#, c-format
+msgid " [abi=EABI64]"
+msgstr " [abi=EABI64]"
+
+#: elfxx-mips.c:12766
+#, c-format
+msgid " [abi unknown]"
+msgstr " [abi tidak diketahui]"
+
+#: elfxx-mips.c:12768
+#, c-format
+msgid " [abi=N32]"
+msgstr " [abi=N32]"
+
+#: elfxx-mips.c:12770
+#, c-format
+msgid " [abi=64]"
+msgstr " [abi=64]"
+
+#: elfxx-mips.c:12772
+#, c-format
+msgid " [no abi set]"
+msgstr " [bukan abi set]"
+
+#: elfxx-mips.c:12793
+#, c-format
+msgid " [unknown ISA]"
+msgstr " [ISA tidak diketahui]"
+
+#: elfxx-mips.c:12804
+#, c-format
+msgid " [not 32bitmode]"
+msgstr " [bukan 32bitmode]"
+
+#: elfxx-sparc.c:440
+#, c-format
+msgid "invalid relocation type %d"
+msgstr "tipe relokasi %d tidak valid"
+
+#: i386linux.c:455 m68klinux.c:459 sparclinux.c:453
+#, c-format
+msgid "Output file requires shared library `%s'\n"
+msgstr "Berkas keluaran membutuhkan library terbagi `%s'\n"
+
+#: i386linux.c:463 m68klinux.c:467 sparclinux.c:461
+#, c-format
+msgid "Output file requires shared library `%s.so.%s'\n"
+msgstr "Berkas keluaran membutuhkan library terbagi `%s.so.%s'\n"
+
+#: i386linux.c:652 i386linux.c:702 m68klinux.c:659 m68klinux.c:707
+#: sparclinux.c:651 sparclinux.c:701
+#, c-format
+msgid "Symbol %s not defined for fixups\n"
+msgstr "Simbol %s tidak terdefinisi untuk fixups\n"
+
+#: i386linux.c:726 m68klinux.c:731 sparclinux.c:725
+msgid "Warning: fixup count mismatch\n"
+msgstr "Peringatan: jumlah fixup tidak cocok\n"
+
+#: ieee.c:159
+#, c-format
+msgid "%s: string too long (%d chars, max 65535)"
+msgstr "%s: string terlalu panjang (%d chars, max 65535)"
+
+#: ieee.c:286
+#, c-format
+msgid "%s: unrecognized symbol `%s' flags 0x%x"
+msgstr "%s: simbol tidak dikenal `%s' flags 0x%x"
+
+#: ieee.c:788
+msgid "%B: unimplemented ATI record %u for symbol %u"
+msgstr "%B: tidak terimplementasi ATI record %u untuk simbol %u"
+
+#: ieee.c:812
+msgid "%B: unexpected ATN type %d in external part"
+msgstr "%B: tipe ATN %d tidak diduga dalam bagian luar"
+
+#: ieee.c:834
+msgid "%B: unexpected type after ATN"
+msgstr "%B: tidak diduga tipe sesudah ATN"
+
+#: ihex.c:230
+msgid "%B:%d: unexpected character `%s' in Intel Hex file"
+msgstr "%B:%d: tidak diduga karakter `%s' dalam berkas Intel Hex"
+
+#: ihex.c:337
+msgid "%B:%u: bad checksum in Intel Hex file (expected %u, found %u)"
+msgstr "%B:%u: checksum buruk dalam berkas Intel Hex (diperkirakan %u, ditemukan %u)"
+
+#: ihex.c:392
+msgid "%B:%u: bad extended address record length in Intel Hex file"
+msgstr "%B:%u: buruk extended alamat panjang record dalam berkas Intel Hex"
+
+#: ihex.c:409
+msgid "%B:%u: bad extended start address length in Intel Hex file"
+msgstr "%B:%u: buruk extended awal panjang alamat dalam berkas Intel Hex "
+
+#: ihex.c:426
+msgid "%B:%u: bad extended linear address record length in Intel Hex file"
+msgstr "%B:%u: buruk extended alamat linear panjang record dalam berkas Intel Hex"
+
+#: ihex.c:443
+msgid "%B:%u: bad extended linear start address length in Intel Hex file"
+msgstr "%B:%u: buruk extended panjang awal alamat linear dalam berkas Intel Hex"
+
+#: ihex.c:460
+msgid "%B:%u: unrecognized ihex type %u in Intel Hex file"
+msgstr "%B:%u: tidak dikenal ihex tipe %u dalam berkas Intel Hex"
+
+#: ihex.c:579
+msgid "%B: internal error in ihex_read_section"
+msgstr "%B: internal error dalam ihex_read_section"
+
+#: ihex.c:613
+msgid "%B: bad section length in ihex_read_section"
+msgstr "%B: buruk panjang bagian dalam ihex_read_section"
+
+#: ihex.c:825
+#, c-format
+msgid "%s: address 0x%s out of range for Intel Hex file"
+msgstr "%s: alamat 0x%s diluar jangkauan untuk berkas Intel Hex"
+
+#: libbfd.c:1008
+#, c-format
+msgid "Deprecated %s called at %s line %d in %s\n"
+msgstr "Deprecated %s dipanggil di %s baris %d dalam %s\n"
+
+#: libbfd.c:1011
+#, c-format
+msgid "Deprecated %s called\n"
+msgstr "Deprecated %s dipanggil\n"
+
+#: linker.c:1874
+msgid "%B: indirect symbol `%s' to `%s' is a loop"
+msgstr "%B: indirect simbol `%s' ke `%s' adalah sebuah loop"
+
+#: linker.c:2740
+#, c-format
+msgid "Attempt to do relocatable link with %s input and %s output"
+msgstr "Mencoba untuk merelokasi link dengan masukan %s dan keluaran %s"
+
+#: linker.c:3065
+msgid "%B: warning: ignoring duplicate section `%A'\n"
+msgstr "%B: peringatan: mengabaikan bagiann terduplikasi `%A'\n"
+
+#: linker.c:3079
+msgid "%B: warning: duplicate section `%A' has different size\n"
+msgstr "%B: peringatan: bagian terduplikasi `%A' memiliki ukuran berbeda\n"
+
+#: mach-o.c:3195
+#, c-format
+msgid "Mach-O header:\n"
+msgstr "Kepala Mach-O:\n"
+
+#: mach-o.c:3196
+#, c-format
+msgid " magic : %08lx\n"
+msgstr " majik : %08lx\n"
+
+#: mach-o.c:3197
+#, c-format
+msgid " cputype : %08lx (%s)\n"
+msgstr " tipe-cpu : %08lx (%s)\n"
+
+#: mach-o.c:3199
+#, c-format
+msgid " cpusubtype: %08lx\n"
+msgstr " subtipecpu: %08lx\n"
+
+#: mach-o.c:3200
+#, c-format
+msgid " filetype : %08lx (%s)\n"
+msgstr " tipe-berkas : %08lx (%s)\n"
+
+#: mach-o.c:3203
+#, c-format
+msgid " ncmds : %08lx\n"
+msgstr " ncmds : %08lx\n"
+
+#: mach-o.c:3204
+#, c-format
+msgid " sizeofcmds: %08lx\n"
+msgstr " besardariperintah: %08lx\n"
+
+#: mach-o.c:3205
+#, c-format
+msgid " flags : %08lx ("
+msgstr " tanda : %08lx ("
+
+#: mach-o.c:3207
+#, c-format
+msgid ")\n"
+msgstr ")\n"
+
+#: mach-o.c:3208
+#, c-format
+msgid " reserved : %08x\n"
+msgstr " direserve : %08x\n"
+
+#: mach-o.c:3218
+#, c-format
+msgid "Segments and Sections:\n"
+msgstr "Bagian dan Daerah:\n"
+
+#: mach-o.c:3219
+#, c-format
+msgid " #: Segment name Section name Address\n"
+msgstr " #: Nama bagian Nama daerah Alamat\n"
+
+#: merge.c:829
+#, c-format
+msgid "%s: access beyond end of merged section (%ld)"
+msgstr "%s: akses diluar dari daerah merged (%ld)"
+
+#: mmo.c:456
+#, c-format
+msgid "%s: No core to allocate section name %s\n"
+msgstr "%s: Tidak ada core untuk alokasi daerah nama %s\n"
+
+#: mmo.c:531
+#, c-format
+msgid "%s: No core to allocate a symbol %d bytes long\n"
+msgstr "%s: Tidak ada core untuk alokasi sebuah simbol %d bytes long\n"
+
+#: mmo.c:1187
+#, c-format
+msgid "%s: invalid mmo file: initialization value for $255 is not `Main'\n"
+msgstr "%s: berkas mmo tidak valid: nilai inisialisasi untuk $255 bukan `Main'\n"
+
+#: mmo.c:1332
+#, c-format
+msgid "%s: unsupported wide character sequence 0x%02X 0x%02X after symbol name starting with `%s'\n"
+msgstr "%s: tidak didukung dengan urutan karakter lebar 0x%02X 0x%02X sesudah nama simbol dimulai dengan `%s'\n"
+
+#: mmo.c:1566
+#, c-format
+msgid "%s: invalid mmo file: unsupported lopcode `%d'\n"
+msgstr "%s: berkas mmo tidak valid: lopcode tidak didukung `%d'\n"
+
+#: mmo.c:1576
+#, c-format
+msgid "%s: invalid mmo file: expected YZ = 1 got YZ = %d for lop_quote\n"
+msgstr "%s: berka mmo tidak valid: diduga YZ = 1 diperoleh YZ = %d untuk lop_quote\n"
+
+#: mmo.c:1612
+#, c-format
+msgid "%s: invalid mmo file: expected z = 1 or z = 2, got z = %d for lop_loc\n"
+msgstr "%s: berkas mmo tidak valid: diduga z = 1 atau z = 2, diperoleh z = %d untuk lop_loc\n"
+
+#: mmo.c:1658
+#, c-format
+msgid "%s: invalid mmo file: expected z = 1 or z = 2, got z = %d for lop_fixo\n"
+msgstr "%s: berkas mmo tidak valid: diduga z = 1 atau z = 2, diperoleh z = %d untuk lop_fixo\n"
+
+#: mmo.c:1697
+#, c-format
+msgid "%s: invalid mmo file: expected y = 0, got y = %d for lop_fixrx\n"
+msgstr "%s: berkas mmo tidak valid: diduga y = 0, diperoleh y = %d untuk lop_fixrx\n"
+
+#: mmo.c:1706
+#, c-format
+msgid "%s: invalid mmo file: expected z = 16 or z = 24, got z = %d for lop_fixrx\n"
+msgstr "%s: berkas mmo tidak valid: diduga z = 16 atau z = 24, diperoleh z = %d untuk lop_fixrx\n"
+
+#: mmo.c:1729
+#, c-format
+msgid "%s: invalid mmo file: leading byte of operand word must be 0 or 1, got %d for lop_fixrx\n"
+msgstr "%s: berkas mmo tidak valid: awalan byte dari kata operand harus 0 atau 1, diperoleh %d untuk lop_fixrx\n"
+
+#: mmo.c:1752
+#, c-format
+msgid "%s: cannot allocate file name for file number %d, %d bytes\n"
+msgstr "%s: tidak dapat mengalokasikan nama berkas untuk nomor berkas %d, %d bytes\n"
+
+#: mmo.c:1772
+#, c-format
+msgid "%s: invalid mmo file: file number %d `%s', was already entered as `%s'\n"
+msgstr "%s: berkas mmo tidak valid: nomor berkas %d `%s', telah dimasukan sebagai `%s'\n"
+
+#: mmo.c:1785
+#, c-format
+msgid "%s: invalid mmo file: file name for number %d was not specified before use\n"
+msgstr "%s: berkas mmo tidak valid: nama berkas untuk nomor %d telah dispesifikasikan sebelum digunakan\n"
+
+#: mmo.c:1892
+#, c-format
+msgid "%s: invalid mmo file: fields y and z of lop_stab non-zero, y: %d, z: %d\n"
+msgstr "%s: berkas mmo tidak valid: daerah y dan z dari lop_stab bukan-nol, y: %d, z: %d\n"
+
+#: mmo.c:1928
+#, c-format
+msgid "%s: invalid mmo file: lop_end not last item in file\n"
+msgstr "%s: berkas mmo tidak valid: lop_end bukan item terakhir dalam berkas\n"
+
+#: mmo.c:1941
+#, c-format
+msgid "%s: invalid mmo file: YZ of lop_end (%ld) not equal to the number of tetras to the preceding lop_stab (%ld)\n"
+msgstr "%s: berkas mmo tidak valid: YZ dari lop_end (%ld) tidak sama dengan jumlah dari tetras yang mengawali lop_stab (%ld)\n"
+
+#: mmo.c:2651
+#, c-format
+msgid "%s: invalid symbol table: duplicate symbol `%s'\n"
+msgstr "%s: tabel simbol tidak valid: duplikasi simbol `%s'\n"
+
+#: mmo.c:2894
+#, c-format
+msgid "%s: Bad symbol definition: `Main' set to %s rather than the start address %s\n"
+msgstr "%s: Definisi simbol buruk: `Main' di set ke %s daripada ke awal alamat %s\n"
+
+#: mmo.c:2986
+#, c-format
+msgid "%s: warning: symbol table too large for mmo, larger than 65535 32-bit words: %d. Only `Main' will be emitted.\n"
+msgstr "%s: Peringatan: tabel simbol terlalu besar untuk mmo, lebih besar daripada 65535 32-bit words: %d. Hanya `Main' yang akan dikeluarkan.\n"
+
+#: mmo.c:3031
+#, c-format
+msgid "%s: internal error, symbol table changed size from %d to %d words\n"
+msgstr "%s: internal error, tabel simbol berubah ukuran dari %d ke %d kata\n"
+
+#: mmo.c:3083
+#, c-format
+msgid "%s: internal error, internal register section %s had contents\n"
+msgstr "%s: internal error, daerah internal register %s memiliki isi\n"
+
+#: mmo.c:3134
+#, c-format
+msgid "%s: no initialized registers; section length 0\n"
+msgstr "%s: tidak ada register yang terinisialisasi; panjang daerah 0\n"
+
+#: mmo.c:3140
+#, c-format
+msgid "%s: too many initialized registers; section length %ld\n"
+msgstr "%s: terlalu banyak register yang terinisialisasi; panjang daerah %ld\n"
+
+#: mmo.c:3145
+#, c-format
+msgid "%s: invalid start address for initialized registers of length %ld: 0x%lx%08lx\n"
+msgstr "%s: awal alaman tidak valid untuk register terinisialisasi dari panjang %ld: 0x%lx%08lx\n"
+
+#: oasys.c:881
+#, c-format
+msgid "%s: can not represent section `%s' in oasys"
+msgstr "%s: tidak dapat merepresentasikan daerah `%s' dalam oasys"
+
+#: osf-core.c:139
+#, c-format
+msgid "Unhandled OSF/1 core file section type %d\n"
+msgstr "Tidak tertangani berkas core OSF/1 daerah tipe %d\n"
+
+#: pe-mips.c:613
+msgid "%B: `ld -r' not supported with PE MIPS objects\n"
+msgstr "%B: `ld -r' tidak didukung dengan PE MIPS objek\n"
+
+#. OK, at this point the following variables are set up:
+#. src = VMA of the memory we're fixing up
+#. mem = pointer to memory we're fixing up
+#. val = VMA of what we need to refer to.
+#: pe-mips.c:729
+msgid "%B: unimplemented %s\n"
+msgstr "%B: tidak terimplementasi %s\n"
+
+#: pe-mips.c:755
+msgid "%B: jump too far away\n"
+msgstr "%B: lompat terlalu jauh\n"
+
+#: pe-mips.c:781
+msgid "%B: bad pair/reflo after refhi\n"
+msgstr "%B: pasangan/reflo buruk setelah refhi\n"
+
+#: pei-x86_64.c:465
+#, c-format
+msgid "warning: .pdata section size (%ld) is not a multiple of %d\n"
+msgstr "peringatan: besar (%ld) daerah .pdata tidak dalam kelipatan dari %d\n"
+
+#: pei-x86_64.c:469 peigen.c:1620 peigen.c:1799 pepigen.c:1620 pepigen.c:1799
+#: pex64igen.c:1620 pex64igen.c:1799
+#, c-format
+msgid ""
+"\n"
+"The Function Table (interpreted .pdata section contents)\n"
+msgstr ""
+"\n"
+"Tabel Fungsi (diinterpretasikan isi daerah .pdata)\n"
+
+#: pei-x86_64.c:471
+#, c-format
+msgid "vma:\t\t\tBeginAddress\t EndAddress\t UnwindData\n"
+msgstr " vma:\t\t\tAlamatAwal \t AlamatAkhir\t UnwindData\n"
+
+#. XXX code yet to be written.
+#: peicode.h:752
+msgid "%B: Unhandled import type; %x"
+msgstr "%B: Tipe impor tidak tertangani; %x"
+
+#: peicode.h:757
+msgid "%B: Unrecognised import type; %x"
+msgstr "%B: Tipe impor tidak dikenal; %x"
+
+#: peicode.h:771
+msgid "%B: Unrecognised import name type; %x"
+msgstr "%B: Nama tipe impor tidak dikenal; %x"
+
+#: peicode.h:1154
+msgid "%B: Unrecognised machine type (0x%x) in Import Library Format archive"
+msgstr "%B: Tipe mesin (0x%x) tidak dikenal dalam Import Library Format archive"
+
+#: peicode.h:1166
+msgid "%B: Recognised but unhandled machine type (0x%x) in Import Library Format archive"
+msgstr "%B: Dikenal tetapi tidak tertangani tipe mesin (0x%x) dalam Import Library Format archive"
+
+#: peicode.h:1184
+msgid "%B: size field is zero in Import Library Format header"
+msgstr "%B: besar field adalah nol dalam Import Library Format header"
+
+#: peicode.h:1215
+msgid "%B: string not null terminated in ILF object file."
+msgstr "%B: string tidak diakhiri kosong dalam berkas objek ILF."
+
+#: ppcboot.c:414
+#, c-format
+msgid ""
+"\n"
+"ppcboot header:\n"
+msgstr ""
+"\n"
+"ppcboot header:\n"
+
+#: ppcboot.c:415
+#, c-format
+msgid "Entry offset = 0x%.8lx (%ld)\n"
+msgstr "Ofset masukan = 0x%.8lx (%ld)\n"
+
+#: ppcboot.c:417
+#, c-format
+msgid "Length = 0x%.8lx (%ld)\n"
+msgstr "Panjang = 0x%.8lx (%ld)\n"
+
+#: ppcboot.c:421
+#, c-format
+msgid "Flag field = 0x%.2x\n"
+msgstr "Tanda daerah = 0x%.2x\n"
+
+#: ppcboot.c:427
+#, c-format
+msgid "Partition name = \"%s\"\n"
+msgstr "Nama partisi = \"%s\"\n"
+
+#: ppcboot.c:446
+#, c-format
+msgid ""
+"\n"
+"Partition[%d] start = { 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x }\n"
+msgstr ""
+"\n"
+"Awal partisi[%d] = { 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x }\n"
+
+#: ppcboot.c:452
+#, c-format
+msgid "Partition[%d] end = { 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x }\n"
+msgstr "Akhir partisi[%d] = { 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x }\n"
+
+#: ppcboot.c:458
+#, c-format
+msgid "Partition[%d] sector = 0x%.8lx (%ld)\n"
+msgstr "Daerah partisi[%d] = 0x%.8lx (%ld)\n"
+
+#: ppcboot.c:460
+#, c-format
+msgid "Partition[%d] length = 0x%.8lx (%ld)\n"
+msgstr "Panjang partisi[%d] = 0x%.8lx (%ld)\n"
+
+#: som.c:5114
+#, c-format
+msgid ""
+"\n"
+"Exec Auxiliary Header\n"
+msgstr ""
+"\n"
+"Tambahan exec header\n"
+
+#: som.c:5417
+msgid "som_sizeof_headers unimplemented"
+msgstr "som_sizeof_headers tidak terimplementasi"
+
+#: srec.c:261
+msgid "%B:%d: Unexpected character `%s' in S-record file\n"
+msgstr "%B:%d: Karakter `%s' tidak diduga dalam berkas S-record\n"
+
+#: srec.c:567 srec.c:600
+msgid "%B:%d: Bad checksum in S-record file\n"
+msgstr "%B:%d: Checksum buruk dalam berkas S-record\n"
+
+#: stabs.c:279
+msgid "%B(%A+0x%lx): Stabs entry has invalid string index."
+msgstr "%B(%A+0x%lx): Masukan stabs memiliki index string tidak valid."
+
+#: syms.c:1079
+msgid "Unsupported .stab relocation"
+msgstr "Relokasi .stab tidak didukung"
+
+#: vms-gsd.c:350
+#, c-format
+msgid "bfd_make_section (%s) failed"
+msgstr "bfd_make_section (%s) gagal"
+
+#: vms-gsd.c:365
+#, c-format
+msgid "bfd_set_section_flags (%s, %x) failed"
+msgstr "bfd_set_section_flags (%s, %x) gagal"
+
+#: vms-gsd.c:399
+#, c-format
+msgid "Size mismatch section %s=%lx, %s=%lx"
+msgstr "Ukuran tidak cocok daerah %s=%lx, %s=%lx"
+
+#: vms-gsd.c:754
+#, c-format
+msgid "Unknown GSD/EGSD subtype %d"
+msgstr "tidak diketahui GDS/EGSD subtype %d"
+
+#: vms-hdr.c:364
+msgid "Object module NOT error-free !\n"
+msgstr "Modul objek Tidak bebas-error !\n"
+
+#: vms-hdr.c:878
+#, c-format
+msgid "unknown source command %d"
+msgstr "sumber perintah %d tidak diketahui"
+
+#: vms-hdr.c:951
+msgid "DST_S_C_SET_LINUM_INCR not implemented"
+msgstr "DST_S_C_SET_LINUM_INCR belum diimplementasikan"
+
+#: vms-hdr.c:957
+msgid "DST_S_C_SET_LINUM_INCR_W not implemented"
+msgstr "DST_S_C_SET_LINUM_INCR_W belum diimplementasikan"
+
+#: vms-hdr.c:963
+msgid "DST_S_C_RESET_LINUM_INCR not implemented"
+msgstr "DST_S_C_RESET_LINUM_INCR belum diimplementasikan"
+
+#: vms-hdr.c:969
+msgid "DST_S_C_BEG_STMT_MODE not implemented"
+msgstr "DST_S_C_BEG_STMT_MODE belum diimplementasikan"
+
+#: vms-hdr.c:975
+msgid "DST_S_C_END_STMT_MODE not implemented"
+msgstr "DST_S_C_END_STMT_MODE belum diimplementasikan"
+
+#: vms-hdr.c:1008
+msgid "DST_S_C_SET_PC not implemented"
+msgstr "DST_S_C_SET_PC belum diimplementasikan"
+
+#: vms-hdr.c:1014
+msgid "DST_S_C_SET_PC_W not implemented"
+msgstr "DST_S_C_SET_PC_W belum diimplementasikan"
+
+#: vms-hdr.c:1020
+msgid "DST_S_C_SET_PC_L not implemented"
+msgstr "DST_S_C_SET_PC_L belum diimplementasikan"
+
+#: vms-hdr.c:1026
+msgid "DST_S_C_SET_STMTNUM not implemented"
+msgstr "DST_S_C_SET_STMTNUM belum diimplementasikan"
+
+#: vms-hdr.c:1079
+#, c-format
+msgid "unknown line command %d"
+msgstr "baris perintah %d tidak diketahui"
+
+#: vms-misc.c:588
+#, c-format
+msgid "Stack overflow (%d) in _bfd_vms_push"
+msgstr "Stack overflow (%d) dalam _bfd_vms_push"
+
+#: vms-misc.c:603
+msgid "Stack underflow in _bfd_vms_pop"
+msgstr "Stack underflow dalam _bfd_vms_pop"
+
+#: vms-misc.c:844
+msgid "_bfd_vms_output_counted called with zero bytes"
+msgstr "_bfd_vms_output_counted dipanggil dengan zero bytes"
+
+#: vms-misc.c:849
+msgid "_bfd_vms_output_counted called with too many bytes"
+msgstr "_bfd_vms_output_counted dipanggil dengan terlalu banyak bytes"
+
+#: vms-misc.c:967
+#, c-format
+msgid "Symbol %s replaced by %s\n"
+msgstr "Simbol %s digantikan oleh %s\n"
+
+#: vms-misc.c:1026
+#, c-format
+msgid "failed to enter %s"
+msgstr "gagal untuk memasuki %s"
+
+#: vms-tir.c:83
+msgid "No Mem !"
+msgstr "Tidak ada Memori !"
+
+#. These names have not yet been added to this switch statement.
+#: vms-tir.c:346
+#, c-format
+msgid "unknown ETIR command %d"
+msgstr "perintah ETIR %d tidak diketahui"
+
+#: vms-tir.c:440
+#, c-format
+msgid "bad section index in %s"
+msgstr "Indek daerah buruk dalam %s"
+
+#: vms-tir.c:459
+#, c-format
+msgid "unsupported STA cmd %s"
+msgstr "perintah %s STA tidak didukung"
+
+#: vms-tir.c:464 vms-tir.c:1304
+#, c-format
+msgid "reserved STA cmd %d"
+msgstr "perintah %d STA direserve"
+
+#. Unsigned shift.
+#. Rotate.
+#. Redefine symbol to current location.
+#. Define a literal.
+#: vms-tir.c:655 vms-tir.c:774 vms-tir.c:894 vms-tir.c:1624
+#, c-format
+msgid "%s: not supported"
+msgstr "%s: tidak didukung"
+
+#: vms-tir.c:661 vms-tir.c:1481
+#, c-format
+msgid "%s: not implemented"
+msgstr "%s: tidak terimplementasi"
+
+#: vms-tir.c:666 vms-tir.c:1485
+#, c-format
+msgid "reserved STO cmd %d"
+msgstr "reserved STO perintah %d"
+
+#: vms-tir.c:789 vms-tir.c:1629
+#, c-format
+msgid "reserved OPR cmd %d"
+msgstr "reserved OPR perintah %d"
+
+#: vms-tir.c:852 vms-tir.c:1693
+#, c-format
+msgid "reserved CTL cmd %d"
+msgstr "reserved CTL perintah %d"
+
+#: vms-tir.c:966
+#, c-format
+msgid "reserved STC cmd %d"
+msgstr "perintah %d direserve"
+
+#. stack byte from image
+#. arg: none.
+#: vms-tir.c:1212
+msgid "stack-from-image not implemented"
+msgstr "stack-from-image tidak terimplementasi"
+
+#: vms-tir.c:1230
+msgid "stack-entry-mask not fully implemented"
+msgstr "stack-entry-mask tidak terimplementasi secara penuh"
+
+#. 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.
+#: vms-tir.c:1244
+msgid "PASSMECH not fully implemented"
+msgstr "PASSMECH tidak terimplementasi secara penuh"
+
+#: vms-tir.c:1263
+msgid "stack-local-symbol not fully implemented"
+msgstr "stack-local-symbol tidak terimplementasi secara penuh"
+
+#: vms-tir.c:1276
+msgid "stack-literal not fully implemented"
+msgstr "stack-literal tidak terimplementasi secara penuh"
+
+#: vms-tir.c:1297
+msgid "stack-local-symbol-entry-point-mask not fully implemented"
+msgstr "stack-local-symbol-entry-point-mask tidak terimplementasi secara penuh"
+
+#: vms-tir.c:1571 vms-tir.c:1583 vms-tir.c:1595 vms-tir.c:1607 vms-tir.c:1672
+#: vms-tir.c:1680 vms-tir.c:1688
+#, c-format
+msgid "%s: not fully implemented"
+msgstr "%s: tidak terimplementasi secara penuh"
+
+#: vms-tir.c:1746
+#, c-format
+msgid "obj code %d not found"
+msgstr "obj kode %d tidak ditemukan"
+
+#: vms-tir.c:2019
+#, c-format
+msgid "Reloc size error in section %s"
+msgstr "Kesalahan ukuran relokasi dalam daerah %s"
+
+#: vms-tir.c:2112 vms-tir.c:2129 vms-tir.c:2147 vms-tir.c:2159 vms-tir.c:2170
+#: vms-tir.c:2182
+#, c-format
+msgid "Unknown reloc %s + %s"
+msgstr "Relokasi %s + %s tidak diketahui"
+
+#: vms-tir.c:2249
+#, c-format
+msgid "Unknown symbol %s in command %s"
+msgstr "Simbol %s tidak diketahui dalam perintah %s"
+
+#: vms-tir.c:2504
+#, c-format
+msgid "SEC_RELOC with no relocs in section %s"
+msgstr "SEC_RELOC dengan tidak ada relokasi dalam daerah %s"
+
+#: vms-tir.c:2556 vms-tir.c:2783
+#, c-format
+msgid "Size error in section %s"
+msgstr "Kesalahan ukuran dalam daerah %s"
+
+#: vms-tir.c:2725
+msgid "Spurious ALPHA_R_BSR reloc"
+msgstr "Spurious ALPHA_R_BSR relokasi"
+
+#: vms-tir.c:2770
+#, c-format
+msgid "Unhandled relocation %s"
+msgstr "Relokasi %s tidak tertangani"
+
+#: xcofflink.c:836
+#, c-format
+msgid "%s: XCOFF shared object when not producing XCOFF output"
+msgstr "%s: XCOFF objek shared ketika tidak menghasilkan keluaran XCOFF"
+
+#: xcofflink.c:857
+#, c-format
+msgid "%s: dynamic object with no .loader section"
+msgstr "%s: objek dinamis dengan tidak ada daerah .loader"
+
+#: xcofflink.c:1415
+msgid "%B: `%s' has line numbers but no enclosing section"
+msgstr "%B: `%s' memiliki nomor baris tetapi tidak ditutupi daerah"
+
+#: xcofflink.c:1467
+msgid "%B: class %d symbol `%s' has no aux entries"
+msgstr "%B: kelas %d simbol `%s' tidak memiliki tambahan masukan"
+
+#: xcofflink.c:1489
+msgid "%B: symbol `%s' has unrecognized csect type %d"
+msgstr "%B: simbol `%s' memiliki tipe %d csect tidak dikenal"
+
+#: xcofflink.c:1501
+msgid "%B: bad XTY_ER symbol `%s': class %d scnum %d scnlen %d"
+msgstr "%B: simbol XTY_ER buruk `%s': kelas %d scnum %d scnlen %d"
+
+#: xcofflink.c:1530
+msgid "%B: XMC_TC0 symbol `%s' is class %d scnlen %d"
+msgstr "%B: XMC_TC0 simbol `%s' adalah kelas %d scnlen %d"
+
+#: xcofflink.c:1676
+msgid "%B: csect `%s' not in enclosing section"
+msgstr "%B: csect `%s' tidak dalam lingkup daerah"
+
+#: xcofflink.c:1783
+msgid "%B: misplaced XTY_LD `%s'"
+msgstr "%B: salah tempat XTY_LD `%s'"
+
+#: xcofflink.c:2102
+msgid "%B: reloc %s:%d not in csect"
+msgstr "%B: relokasi %s:%d tidak dalam csect"
+
+#: xcofflink.c:3177
+#, c-format
+msgid "%s: no such symbol"
+msgstr "%s: tidak ada simbol seperti itu"
+
+#: xcofflink.c:3282
+#, c-format
+msgid "warning: attempt to export undefined symbol `%s'"
+msgstr "peringatan: mencoba untuk mengekspor simbol tidak terdefinisi `%s'"
+
+#: xcofflink.c:3664
+msgid "error: undefined symbol __rtinit"
+msgstr "error: simbol tidak terdefinisi __rtinit"
+
+#: xcofflink.c:4041
+msgid "%B: loader reloc in unrecognized section `%s'"
+msgstr "%B: loader relokasi dalam daerah tidak dikenal `%s'"
+
+#: xcofflink.c:4052
+msgid "%B: `%s' in loader reloc but not loader sym"
+msgstr "%B: `%s' dalam relokasi loader tetapi bukan loader sym"
+
+#: xcofflink.c:4068
+msgid "%B: loader reloc in read-only section %A"
+msgstr "%B: loader relokasi dalam daerah baca-saja %A"
+
+#: xcofflink.c:5086
+#, c-format
+msgid "TOC overflow: 0x%lx > 0x10000; try -mminimal-toc when compiling"
+msgstr "TOC overflow: 0x%lx > 0x10000; coba -mminimal-toc ketika mengkompile"
+
+#: elf32-ia64.c:1050 elf64-ia64.c:1050
+msgid "%B: Can't relax br at 0x%lx in section `%A'. Please use brl or indirect branch."
+msgstr "%B: Tidak dapat relaks br di 0x%lx dalam daerah `%A'. Tolong gunakan brl atau indirect branch."
+
+#: elf32-ia64.c:2739 elf64-ia64.c:2739
+msgid "@pltoff reloc against local symbol"
+msgstr "@pltoff relokasi terhadap simbol lokal"
+
+#: elf32-ia64.c:4314 elf64-ia64.c:4314
+#, c-format
+msgid "%s: short data segment overflowed (0x%lx >= 0x400000)"
+msgstr "%s: short data segment overflowed (0x%lx >= 0x400000)"
+
+#: elf32-ia64.c:4325 elf64-ia64.c:4325
+#, c-format
+msgid "%s: __gp does not cover short data segment"
+msgstr "%s: __gp tidak meliputi segmen data pendek"
+
+#: elf32-ia64.c:4595 elf64-ia64.c:4595
+msgid "%B: non-pic code with imm relocation against dynamic symbol `%s'"
+msgstr "%B: bukan-pic kode dengan relokasi imm terhadap simbol dinamis `%s'"
+
+#: elf32-ia64.c:4662 elf64-ia64.c:4662
+msgid "%B: @gprel relocation against dynamic symbol %s"
+msgstr "%B: @gprel relokasi terhadap simbol dinamis %s"
+
+#: elf32-ia64.c:4725 elf64-ia64.c:4725
+msgid "%B: linking non-pic code in a position independent executable"
+msgstr "%B: menghubungkan dengan kode bukan-pic dalam sebuah executable bebas posisi"
+
+#: elf32-ia64.c:4862 elf64-ia64.c:4862
+msgid "%B: @internal branch to dynamic symbol %s"
+msgstr "%B: @internal branck ke simbol dinamis %s"
+
+#: elf32-ia64.c:4864 elf64-ia64.c:4864
+msgid "%B: speculation fixup to dynamic symbol %s"
+msgstr "%B: spekulasi fixup ke simbol dinamis %s"
+
+#: elf32-ia64.c:4866 elf64-ia64.c:4866
+msgid "%B: @pcrel relocation against dynamic symbol %s"
+msgstr "%B: @pcrel relokasi terhadap simbol dinamis %s"
+
+#: elf32-ia64.c:5063 elf64-ia64.c:5063
+msgid "unsupported reloc"
+msgstr "relokasi tidak didukung"
+
+#: elf32-ia64.c:5101 elf64-ia64.c:5101
+msgid "%B: missing TLS section for relocation %s against `%s' at 0x%lx in section `%A'."
+msgstr "%B: hilang daerah TLS untuk relokasi %s terhadap `%s' di 0x%lx dalam daerah `%A'."
+
+#: elf32-ia64.c:5116 elf64-ia64.c:5116
+msgid "%B: Can't relax br (%s) to `%s' at 0x%lx in section `%A' with size 0x%lx (> 0x1000000)."
+msgstr "%B: Tidak dapat relaks br (%s) ke `%s' di 0x%lx dalam daerah `%A' dengan ukuran 0x%lx (> 0x1000000)."
+
+#: elf32-ia64.c:5372 elf64-ia64.c:5372
+msgid "%B: linking trap-on-NULL-dereference with non-trapping files"
+msgstr "%B: menghubungkan trap-on-NULL-dereference dengan berkas bukan-trapping"
+
+#: elf32-ia64.c:5381 elf64-ia64.c:5381
+msgid "%B: linking big-endian files with little-endian files"
+msgstr "%B: menghubungkan berkas big-endian dengan berkas little-endian"
+
+#: elf32-ia64.c:5390 elf64-ia64.c:5390
+msgid "%B: linking 64-bit files with 32-bit files"
+msgstr "%B: menghubungkan berkas 64-bit dengan berkas 32-bit"
+
+#: elf32-ia64.c:5399 elf64-ia64.c:5399
+msgid "%B: linking constant-gp files with non-constant-gp files"
+msgstr "%B: menghubungkan berkas constant-gp dengan berkas bukan-constant-gp"
+
+#: elf32-ia64.c:5409 elf64-ia64.c:5409
+msgid "%B: linking auto-pic files with non-auto-pic files"
+msgstr "%B: menghubungkan berkas auto-pic dengan berkas non-auto-pic"
+
+#: peigen.c:999 pepigen.c:999 pex64igen.c:999
+#, c-format
+msgid "%s: line number overflow: 0x%lx > 0xffff"
+msgstr "%s: nomor baris overflow: 0x%lx > 0xffff"
+
+#: peigen.c:1026 pepigen.c:1026 pex64igen.c:1026
+msgid "Export Directory [.edata (or where ever we found it)]"
+msgstr "Direktori expor [.edata (atau dimanapun kita menemukannya)]"
+
+#: peigen.c:1027 pepigen.c:1027 pex64igen.c:1027
+msgid "Import Directory [parts of .idata]"
+msgstr "Impor Direktori [bagian dari .idata]"
+
+#: peigen.c:1028 pepigen.c:1028 pex64igen.c:1028
+msgid "Resource Directory [.rsrc]"
+msgstr "Resource Direktori [.rsrc]"
+
+#: peigen.c:1029 pepigen.c:1029 pex64igen.c:1029
+msgid "Exception Directory [.pdata]"
+msgstr "Exception Direktori [.pdata]"
+
+#: peigen.c:1030 pepigen.c:1030 pex64igen.c:1030
+msgid "Security Directory"
+msgstr "Direktori Keamanan"
+
+#: peigen.c:1031 pepigen.c:1031 pex64igen.c:1031
+msgid "Base Relocation Directory [.reloc]"
+msgstr "Dasar Relokasi Direktori [.reloc]"
+
+#: peigen.c:1032 pepigen.c:1032 pex64igen.c:1032
+msgid "Debug Directory"
+msgstr "Debug Direktori"
+
+#: peigen.c:1033 pepigen.c:1033 pex64igen.c:1033
+msgid "Description Directory"
+msgstr "Direktori Penjelasan"
+
+#: peigen.c:1034 pepigen.c:1034 pex64igen.c:1034
+msgid "Special Directory"
+msgstr "Direktori Spesial"
+
+#: peigen.c:1035 pepigen.c:1035 pex64igen.c:1035
+msgid "Thread Storage Directory [.tls]"
+msgstr "Thread Storage Direktori [.tls]"
+
+#: peigen.c:1036 pepigen.c:1036 pex64igen.c:1036
+msgid "Load Configuration Directory"
+msgstr "Direktori Konfigurasi Beban"
+
+#: peigen.c:1037 pepigen.c:1037 pex64igen.c:1037
+msgid "Bound Import Directory"
+msgstr "Direktori Bound Impor"
+
+#: peigen.c:1038 pepigen.c:1038 pex64igen.c:1038
+msgid "Import Address Table Directory"
+msgstr "Direktori Impor Tabel Alamat"
+
+#: peigen.c:1039 pepigen.c:1039 pex64igen.c:1039
+msgid "Delay Import Directory"
+msgstr "Delay Impor Direktori"
+
+#: peigen.c:1040 pepigen.c:1040 pex64igen.c:1040
+msgid "CLR Runtime Header"
+msgstr "CLR Runtime Header"
+
+#: peigen.c:1041 pepigen.c:1041 pex64igen.c:1041
+msgid "Reserved"
+msgstr "Reserved"
+
+#: peigen.c:1101 pepigen.c:1101 pex64igen.c:1101
+#, c-format
+msgid ""
+"\n"
+"There is an import table, but the section containing it could not be found\n"
+msgstr ""
+"\n"
+"Ada tabel impor, tetapi daerah yang berisi itu tidak dapat ditemukan\n"
+
+#: peigen.c:1106 pepigen.c:1106 pex64igen.c:1106
+#, c-format
+msgid ""
+"\n"
+"There is an import table in %s at 0x%lx\n"
+msgstr ""
+"\n"
+"Ada impor tabel di %s pada 0x%lx\n"
+
+#: peigen.c:1149 pepigen.c:1149 pex64igen.c:1149
+#, c-format
+msgid ""
+"\n"
+"Function descriptor located at the start address: %04lx\n"
+msgstr ""
+"\n"
+"Deskripsi fungsi ditempatkan di awal alamat: %04lx\n"
+
+#: peigen.c:1152 pepigen.c:1152 pex64igen.c:1152
+#, c-format
+msgid "\tcode-base %08lx toc (loadable/actual) %08lx/%08lx\n"
+msgstr "\tcode-base %08lx toc (loadable/actual) %08lx/%08lx\n"
+
+#: peigen.c:1160 pepigen.c:1160 pex64igen.c:1160
+#, c-format
+msgid ""
+"\n"
+"No reldata section! Function descriptor not decoded.\n"
+msgstr ""
+"\n"
+"Tidak ada daerah reldata! Deskripsi fungsi tidak terdekode.\n"
+
+#: peigen.c:1165 pepigen.c:1165 pex64igen.c:1165
+#, c-format
+msgid ""
+"\n"
+"The Import Tables (interpreted %s section contents)\n"
+msgstr ""
+"\n"
+"Tabel Impor (diinterpretasikan isi daerah %s)\n"
+
+#: peigen.c:1168 pepigen.c:1168 pex64igen.c:1168
+#, c-format
+msgid ""
+" vma: Hint Time Forward DLL First\n"
+" Table Stamp Chain Name Thunk\n"
+msgstr ""
+"vma: Tips Waktu Forward DLL Pertama\n"
+" Tabel Stamp Rantai Nama Thunk\n"
+
+#: peigen.c:1216 pepigen.c:1216 pex64igen.c:1216
+#, c-format
+msgid ""
+"\n"
+"\tDLL Name: %s\n"
+msgstr ""
+"\n"
+"\tNama DLL: %s\n"
+
+#: peigen.c:1227 pepigen.c:1227 pex64igen.c:1227
+#, c-format
+msgid "\tvma: Hint/Ord Member-Name Bound-To\n"
+msgstr "\tvma: Tips/Ord Nama-Anggota Terikat-Ke\n"
+
+#: peigen.c:1252 pepigen.c:1252 pex64igen.c:1252
+#, c-format
+msgid ""
+"\n"
+"There is a first thunk, but the section containing it could not be found\n"
+msgstr ""
+"\n"
+"Ada thunk pertama, tetapi daerah yang berisi itu tidak dapat ditemukan\n"
+
+#: peigen.c:1417 pepigen.c:1417 pex64igen.c:1417
+#, c-format
+msgid ""
+"\n"
+"There is an export table, but the section containing it could not be found\n"
+msgstr ""
+"\n"
+"Ada tabel expor, tetapi daerah yang berisi itu tidak dapat ditemukan\n"
+
+#: peigen.c:1426 pepigen.c:1426 pex64igen.c:1426
+#, c-format
+msgid ""
+"\n"
+"There is an export table in %s, but it does not fit into that section\n"
+msgstr ""
+"\n"
+"Ada tabel expor dalam %s, tetapi ini tidak masuk dalam daerah itu\n"
+
+#: peigen.c:1432 pepigen.c:1432 pex64igen.c:1432
+#, c-format
+msgid ""
+"\n"
+"There is an export table in %s at 0x%lx\n"
+msgstr ""
+"\n"
+"Ada sebuah tabel expor dalam %s di 0x%lx\n"
+
+#: peigen.c:1460 pepigen.c:1460 pex64igen.c:1460
+#, c-format
+msgid ""
+"\n"
+"The Export Tables (interpreted %s section contents)\n"
+"\n"
+msgstr ""
+"\n"
+"Tabel expor (diinterpretasikan isi daerah %s)\n"
+
+#: peigen.c:1464 pepigen.c:1464 pex64igen.c:1464
+#, c-format
+msgid "Export Flags \t\t\t%lx\n"
+msgstr "Tanda Expor \t\t\t%lx\n"
+
+#: peigen.c:1467 pepigen.c:1467 pex64igen.c:1467
+#, c-format
+msgid "Time/Date stamp \t\t%lx\n"
+msgstr "Waktu/Tanggal stamp \t\t%lx\n"
+
+#: peigen.c:1470 pepigen.c:1470 pex64igen.c:1470
+#, c-format
+msgid "Major/Minor \t\t\t%d/%d\n"
+msgstr "Mayor/Minor \t\t\t%d/%d\n"
+
+#: peigen.c:1473 pepigen.c:1473 pex64igen.c:1473
+#, c-format
+msgid "Name \t\t\t\t"
+msgstr "Nama \t\t\t\t"
+
+#: peigen.c:1479 pepigen.c:1479 pex64igen.c:1479
+#, c-format
+msgid "Ordinal Base \t\t\t%ld\n"
+msgstr "Dasar Ordinal \t\t\t%ld\n"
+
+#: peigen.c:1482 pepigen.c:1482 pex64igen.c:1482
+#, c-format
+msgid "Number in:\n"
+msgstr "Nomor dalam:\n"
+
+#: peigen.c:1485 pepigen.c:1485 pex64igen.c:1485
+#, c-format
+msgid "\tExport Address Table \t\t%08lx\n"
+msgstr "\tTabel Alamat Expor \t\t%08lx\n"
+
+#: peigen.c:1489 pepigen.c:1489 pex64igen.c:1489
+#, c-format
+msgid "\t[Name Pointer/Ordinal] Table\t%08lx\n"
+msgstr "\t[Nama Pointer/Ordinal] Tabel\t%08lx\n"
+
+#: peigen.c:1492 pepigen.c:1492 pex64igen.c:1492
+#, c-format
+msgid "Table Addresses\n"
+msgstr "Tabel Alamat\n"
+
+#: peigen.c:1495 pepigen.c:1495 pex64igen.c:1495
+#, c-format
+msgid "\tExport Address Table \t\t"
+msgstr "\tTabel Alamat Expor \t\t"
+
+#: peigen.c:1500 pepigen.c:1500 pex64igen.c:1500
+#, c-format
+msgid "\tName Pointer Table \t\t"
+msgstr "\tTabel Nama Pointer \t\t"
+
+#: peigen.c:1505 pepigen.c:1505 pex64igen.c:1505
+#, c-format
+msgid "\tOrdinal Table \t\t\t"
+msgstr "\tTabel Ordinal \t\t\t"
+
+#: peigen.c:1519 pepigen.c:1519 pex64igen.c:1519
+#, c-format
+msgid ""
+"\n"
+"Export Address Table -- Ordinal Base %ld\n"
+msgstr ""
+"\n"
+"Tabel Alamat Expor -- Ordinal Base %ld\n"
+
+#: peigen.c:1538 pepigen.c:1538 pex64igen.c:1538
+msgid "Forwarder RVA"
+msgstr "Forwarder RVA"
+
+#: peigen.c:1549 pepigen.c:1549 pex64igen.c:1549
+msgid "Export RVA"
+msgstr "Expor RVA"
+
+#: peigen.c:1556 pepigen.c:1556 pex64igen.c:1556
+#, c-format
+msgid ""
+"\n"
+"[Ordinal/Name Pointer] Table\n"
+msgstr ""
+"\n"
+"[Ordinal/Nama Pointer] Tabel\n"
+
+#: peigen.c:1616 peigen.c:1795 pepigen.c:1616 pepigen.c:1795 pex64igen.c:1616
+#: pex64igen.c:1795
+#, c-format
+msgid "Warning, .pdata section size (%ld) is not a multiple of %d\n"
+msgstr "Peringatan, besar (%ld) daerah .pdata tidak dalam kelipatan dari %d\n"
+
+#: peigen.c:1623 pepigen.c:1623 pex64igen.c:1623
+#, c-format
+msgid " vma:\t\t\tBegin Address End Address Unwind Info\n"
+msgstr " vma:\t\t\tAwal Alamat Akhir Alamat Unwind Informasi\n"
+
+#: peigen.c:1625 pepigen.c:1625 pex64igen.c:1625
+#, c-format
+msgid ""
+" vma:\t\tBegin End EH EH PrologEnd Exception\n"
+" \t\tAddress Address Handler Data Address Mask\n"
+msgstr ""
+" vma:\t\tAwal Akhir EH EH PrologEnd Exception\n"
+" \t\tAlamat Alamat Handler Data Alamat Topeng\n"
+
+#: peigen.c:1695 pepigen.c:1695 pex64igen.c:1695
+#, c-format
+msgid " Register save millicode"
+msgstr " Register simpan millicode"
+
+#: peigen.c:1698 pepigen.c:1698 pex64igen.c:1698
+#, c-format
+msgid " Register restore millicode"
+msgstr " Register restore millicode"
+
+#: peigen.c:1701 pepigen.c:1701 pex64igen.c:1701
+#, c-format
+msgid " Glue code sequence"
+msgstr " Urutan kode pengikat"
+
+#: peigen.c:1801 pepigen.c:1801 pex64igen.c:1801
+#, c-format
+msgid ""
+" vma:\t\tBegin Prolog Function Flags Exception EH\n"
+" \t\tAddress Length Length 32b exc Handler Data\n"
+msgstr ""
+" vma:\t\tMulai Prolog Fungsi Flags Exception EH\n"
+" \t\tAlamat Panjang Panjang 32b exc Handler Data\n"
+
+#: peigen.c:1933 pepigen.c:1933 pex64igen.c:1933
+#, c-format
+msgid ""
+"\n"
+"\n"
+"PE File Base Relocations (interpreted .reloc section contents)\n"
+msgstr ""
+"\n"
+"\n"
+"Berkas Dasar Relokasi PE (diinterpretasikan isi daerah .reloc)\n"
+
+#: peigen.c:1963 pepigen.c:1963 pex64igen.c:1963
+#, c-format
+msgid ""
+"\n"
+"Virtual Address: %08lx Chunk size %ld (0x%lx) Number of fixups %ld\n"
+msgstr ""
+"\n"
+"Alamat Maya: %08lx Besar potongan %ld (0x%lx) Jumlah dari perbaikan %ld\n"
+
+#: peigen.c:1976 pepigen.c:1976 pex64igen.c:1976
+#, c-format
+msgid "\treloc %4d offset %4x [%4lx] %s"
+msgstr "\trelokasi %4d ofset %4x [%4lx] %s"
+
+#. The MS dumpbin program reportedly ands with 0xff0f before
+#. printing the characteristics field. Not sure why. No reason to
+#. emulate it here.
+#: peigen.c:2015 pepigen.c:2015 pex64igen.c:2015
+#, c-format
+msgid ""
+"\n"
+"Characteristics 0x%x\n"
+msgstr ""
+"\n"
+"Karakteristik 0x%x\n"
+
+#: peigen.c:2292 pepigen.c:2292 pex64igen.c:2292
+msgid "%B: unable to fill in DataDictionary[1] because .idata$2 is missing"
+msgstr "%B: tidak dapat mengisi dalam DataDictionary[1] karena .idata$2 hilang"
+
+#: peigen.c:2312 pepigen.c:2312 pex64igen.c:2312
+msgid "%B: unable to fill in DataDictionary[1] because .idata$4 is missing"
+msgstr "%B: tidak dapat mengisi dalam DataDictionary[1] karena .data$4 hilang"
+
+#: peigen.c:2333 pepigen.c:2333 pex64igen.c:2333
+msgid "%B: unable to fill in DataDictionary[12] because .idata$5 is missing"
+msgstr "%B: tidak dapat mengisi dalam DataDictionary[12] karena .idata$5 hilang"
+
+#: peigen.c:2353 pepigen.c:2353 pex64igen.c:2353
+msgid "%B: unable to fill in DataDictionary[PE_IMPORT_ADDRESS_TABLE (12)] because .idata$6 is missing"
+msgstr "%B: tidak dapat mengisi dalam DataDictionary[PE_IMPORT_ADDRESS_TABLE (12)] karena .idata$6 hilang"
+
+#: peigen.c:2375 pepigen.c:2375 pex64igen.c:2375
+msgid "%B: unable to fill in DataDictionary[9] because __tls_used is missing"
+msgstr "%B: tidak dapat mengisi dalam DataDictionary[9] karena __tls_used hilang"
+
+#~ msgid "ERROR: %B: Incompatible object tag '%s':%d"
+#~ msgstr "ERROR: %B: Tanda objek tidak kompatibel '%s':%d"
+
+#~ msgid "%B(%A): warning: unresolvable relocation against symbol `%s'"
+#~ msgstr "%B(%A): peringatan: tidak teresolf relokasi terhadap simbol `%s'"
+
+#~ msgid "%B: Internal inconsistency; no relocation section %s"
+#~ msgstr "%B: Internal tidak konsisten; bagian %s tidak bisa direlokasi"
+
+#~ msgid "Could not find relocation section for %s"
+#~ msgstr "Tidak dapat menemukan bagian relokasi untuk %s"
+
+#~ msgid "%B: GOT overflow: Number of R_68K_GOT8O and R_68K_GOT16O relocations > %d"
+#~ msgstr "%B: Memperoleh overflow: Jumlah dari R_68K_GOT80 dan R_68K_GOT160 relokasi > %d"
+
+#~ msgid "%A link_order not found\n"
+#~ msgstr "%A link_order tidak ditemukan\n"
+
+#~ msgid "%s: no symbol \"%s\""
+#~ msgstr "%s: tidak ada simbol \"%s\""
+
+#~ msgid "%s: loader reloc in unrecognized section `%s'"
+#~ msgstr "%s: loader relokasi dalam daerah `%s' tidak dikenal"
+
+#~ msgid "%s: `%s' in loader reloc but not loader sym"
+#~ msgstr "%s: `%s' dalam relokasi loader tetapi bukan loader sym"
diff --git a/bfd/po/ja.gmo b/bfd/po/ja.gmo
new file mode 100644
index 0000000..321f833
--- /dev/null
+++ b/bfd/po/ja.gmo
Binary files differ
diff --git a/bfd/po/ja.po b/bfd/po/ja.po
new file mode 100644
index 0000000..9f36883
--- /dev/null
+++ b/bfd/po/ja.po
@@ -0,0 +1,6182 @@
+# Japanese message for bfd
+# This file is distributed under the same license as the binutils package.
+# Copyright (C) 2001, 2010 Free Software Foundation, Inc.
+# Daisuke Yamashita <yamad@mb.infoweb.ne.jp>, 2001
+# Yasuaki Taniguchi <yasuakit@gmail.com>, 2010.
+msgid ""
+msgstr ""
+"Project-Id-Version: bfd 2.21.53\n"
+"Report-Msgid-Bugs-To: bug-binutils@gnu.org\n"
+"POT-Creation-Date: 2011-06-02 14:25+0100\n"
+"PO-Revision-Date: 2011-10-23 16:09+0900\n"
+"Last-Translator: Yasuaki Taniguchi <yasuakit@gmail.com>\n"
+"Language-Team: Japanese <translation-team-ja@lists.sourceforge.net>\n"
+"Language: ja\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nulurals=1; plural=0;\n"
+
+# BFD 内ã§åˆ©ç”¨ã•ã‚Œã‚‹æ›¸å¼æ–‡å­—列ã«ã¤ã„ã¦ã¯ bfd/bfd.c ã‚’å‚ç…§ã—ã¦ãã ã•ã„。
+# BFD ã®æ›¸å¼æ–‡å­—列ã§ã¯ä½ç½®ãƒ‘ラメータ (%1$A, %2$B ç­‰) ãŒä½¿ç”¨å‡ºæ¥ãªã„ã®ã§æ³¨æ„ã—ã¦ãã ã•ã„。
+# フラグ㌠c-format ã¨ãªã£ã¦ã„ã¦ã‚‚ã€%A, %B ã®å†…部ã§åˆ©ç”¨ã•ã‚Œã¦ã„る書å¼å¤‰æ›ã§
+# ä½ç½®ãŒå¤‰æ›´ã«ãªã‚‹å ´åˆãŒã‚ã‚Šã¾ã™ã€‚
+# C 標準ã®æ›¸å¼æ–‡å­—ã®ã¿ä½¿ç”¨ã•ã‚Œã¦ã„ã‚‹å ´åˆã§ã‚‚ _bfd_default_error_handler() ã®ä»•æ§˜å¤‰æ›´ãªã©ã«ã‚ˆã‚Š
+# 動作ã—ãªããªã‚‹å ´åˆãŒã‚ã‚‹ã®ã§ä½ç½®ãƒ‘ラメータを使用ã—ãªã„ã“ã¨ã‚’推奨ã—ã¾ã™ã€‚
+# - 2010/12/27 binutils-2.20.90 ã§æ›¸å¼æ–‡å­—列ã®ä½ç½®ãƒ‘ラメータãŒå‹•ä½œã—ãªã„ã“ã¨ã‚’ç¢ºèª (è°·å£)
+#
+#: aout-adobe.c:127
+msgid "%B: Unknown section type in a.out.adobe file: %x\n"
+msgstr "%B: a.out.adobe ファイルã«ä¸æ˜Žãªã‚»ã‚¯ã‚·ãƒ§ãƒ³åž‹ãŒã‚ã‚Šã¾ã™: %x\n"
+
+#: aout-cris.c:199
+#, c-format
+msgid "%s: Invalid relocation type exported: %d"
+msgstr "%s: エクスãƒãƒ¼ãƒˆã•ã‚ŒãŸå†é…置型ãŒç„¡åŠ¹ã§ã™: %d"
+
+#: aout-cris.c:242
+msgid "%B: Invalid relocation type imported: %d"
+msgstr "%B: インãƒãƒ¼ãƒˆã•ã‚ŒãŸå†é…置型ãŒç„¡åŠ¹ã§ã™: %d"
+
+#: aout-cris.c:253
+msgid "%B: Bad relocation record imported: %d"
+msgstr "%B: インãƒãƒ¼ãƒˆã•ã‚ŒãŸå†é…置レコードãŒèª¤ã£ã¦ã„ã¾ã™: %d"
+
+#: aoutx.h:1273 aoutx.h:1611
+#, c-format
+msgid "%s: can not represent section `%s' in a.out object file format"
+msgstr "%s: a.out オブジェクトファイル形å¼ã§ã¯ã‚»ã‚¯ã‚·ãƒ§ãƒ³ `%s' を表ç¾ã§ãã¾ã›ã‚“"
+
+#: aoutx.h:1577
+#, c-format
+msgid "%s: can not represent section for symbol `%s' in a.out object file format"
+msgstr "%s: a.out オブジェクトファイル形å¼ã§ã¯ã‚·ãƒ³ãƒœãƒ« `%s' 用ã®ã‚»ã‚¯ã‚·ãƒ§ãƒ³ã‚’表ç¾ã§ãã¾ã›ã‚“"
+
+#: aoutx.h:1579 vms-alpha.c:7668
+msgid "*unknown*"
+msgstr "*ä¸æ˜Ž*"
+
+#: aoutx.h:4017 aoutx.h:4343
+msgid "%P: %B: unexpected relocation type\n"
+msgstr "%P: %B: 予期ã—ãªã„å†é…置タイプã§ã™\n"
+
+#: aoutx.h:5374
+#, c-format
+msgid "%s: relocatable link from %s to %s not supported"
+msgstr "%s: %s ã‹ã‚‰ %s ã¸ã®å†é…ç½®å¯èƒ½ãƒªãƒ³ã‚¯ã¯ã‚µãƒãƒ¼ãƒˆã•ã‚Œã¦ã„ã¾ã›ã‚“"
+
+#: archive.c:2194
+msgid "Warning: writing archive was slow: rewriting timestamp\n"
+msgstr "警告: 書庫ã¸ã®æ›¸ãè¾¼ã¿ãŒé…ã‚Œã¾ã—ãŸ: タイムスタンプを書ãæ›ãˆã¾ã™\n"
+
+#: archive.c:2482
+msgid "Reading archive file mod timestamp"
+msgstr "書庫ファイルã®æ›´æ–°æ—¥æ™‚を読ã¿è¾¼ã‚“ã§ã„ã¾ã™"
+
+#: archive.c:2506
+msgid "Writing updated armap timestamp"
+msgstr "æ›´æ–°ã•ã‚ŒãŸ armap 日時を書ãè¾¼ã¿ä¸­ã§ã™"
+
+#: bfd.c:398
+msgid "No error"
+msgstr "エラーã¯ã‚ã‚Šã¾ã›ã‚“"
+
+#: bfd.c:399
+msgid "System call error"
+msgstr "システムコールエラー"
+
+#: bfd.c:400
+msgid "Invalid bfd target"
+msgstr "無効㪠bfd ターゲットã§ã™"
+
+#: bfd.c:401
+msgid "File in wrong format"
+msgstr "誤ã£ãŸå½¢å¼ã®ãƒ•ã‚¡ã‚¤ãƒ«ã§ã™"
+
+#: bfd.c:402
+msgid "Archive object file in wrong format"
+msgstr "誤ã£ãŸå½¢å¼ã®ã‚ªãƒ–ジェクトファイル書庫ã§ã™"
+
+#: bfd.c:403
+msgid "Invalid operation"
+msgstr "無効ãªæ“作ã§ã™"
+
+#: bfd.c:404
+msgid "Memory exhausted"
+msgstr "メモリを使ã„æžœãŸã—ã¾ã—ãŸ"
+
+#: bfd.c:405
+msgid "No symbols"
+msgstr "シンボルãŒã‚ã‚Šã¾ã›ã‚“"
+
+#: bfd.c:406
+msgid "Archive has no index; run ranlib to add one"
+msgstr "書庫ã«ç´¢å¼•ãŒã‚ã‚Šã¾ã›ã‚“。追加ã™ã‚‹ãŸã‚ã« ranlib を実行ã—ã¦ãã ã•ã„"
+
+#: bfd.c:407
+msgid "No more archived files"
+msgstr "ã“れ以上書庫ファイルã¯ã‚ã‚Šã¾ã›ã‚“"
+
+#: bfd.c:408
+msgid "Malformed archive"
+msgstr "ä¸æ­£ãªå½¢å¼ã®æ›¸åº«ã§ã™"
+
+#: bfd.c:409
+msgid "File format not recognized"
+msgstr "ファイル形å¼ãŒèªè­˜ã§ãã¾ã›ã‚“"
+
+#: bfd.c:410
+msgid "File format is ambiguous"
+msgstr "ファイル形å¼ãŒæ›–昧ã§ã™"
+
+#: bfd.c:411
+msgid "Section has no contents"
+msgstr "セクションã«å†…容ãŒã‚ã‚Šã¾ã›ã‚“"
+
+#: bfd.c:412
+msgid "Nonrepresentable section on output"
+msgstr "出力ã«å¯¾å¿œã™ã‚‹ã‚»ã‚¯ã‚·ãƒ§ãƒ³ãŒã‚ã‚Šã¾ã›ã‚“"
+
+#: bfd.c:413
+msgid "Symbol needs debug section which does not exist"
+msgstr "存在ã—ã¦ã„ãªã„デãƒãƒƒã‚°ã‚»ã‚¯ã‚·ãƒ§ãƒ³ã‚’シンボルãŒå¿…è¦ã¨ã—ã¦ã„ã¾ã™"
+
+#: bfd.c:414
+msgid "Bad value"
+msgstr "ä¸æ­£ãªå€¤ã§ã™"
+
+#: bfd.c:415
+msgid "File truncated"
+msgstr "ファイルãŒé€”切れã¦ã„ã¾ã™"
+
+#: bfd.c:416
+msgid "File too big"
+msgstr "ファイルãŒå¤§ãã™ãŽã¾ã™"
+
+#: bfd.c:417
+#, c-format
+msgid "Error reading %s: %s"
+msgstr "%s を読ã¿è¾¼ã¿ä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ: %s"
+
+#: bfd.c:418
+msgid "#<Invalid error code>"
+msgstr "#<無効ãªã‚¨ãƒ©ãƒ¼ã‚³ãƒ¼ãƒ‰>"
+
+#: bfd.c:945
+#, c-format
+msgid "BFD %s assertion fail %s:%d"
+msgstr "BFD %s アサーション失敗 %s:%d"
+
+#: bfd.c:957
+#, c-format
+msgid "BFD %s internal error, aborting at %s line %d in %s\n"
+msgstr "BFD %s 内部エラー。ä½ç½® %sã€è¡Œ %dã€%s 内ã§ä¸­æ­¢ã—ã¾ã—ãŸ\n"
+
+#: bfd.c:961
+#, c-format
+msgid "BFD %s internal error, aborting at %s line %d\n"
+msgstr "BFD %s 内部エラー。ä½ç½® %sã€è¡Œ %d ã§ä¸­æ­¢ã—ã¾ã—ãŸ\n"
+
+#: bfd.c:963
+msgid "Please report this bug.\n"
+msgstr "ã“ã®ãƒã‚°ã‚’報告ã—ã¦ãã ã•ã„。\n"
+
+#: bfdwin.c:206
+#, c-format
+msgid "not mapping: data=%lx mapped=%d\n"
+msgstr "マップã—ã¾ã›ã‚“: データ=%lx マップ済=%d\n"
+
+#: bfdwin.c:209
+#, c-format
+msgid "not mapping: env var not set\n"
+msgstr "マップã—ã¾ã›ã‚“: 環境変数ãŒè¨­å®šã•ã‚Œã¦ã„ã¾ã›ã‚“\n"
+
+#: binary.c:271
+#, c-format
+msgid "Warning: Writing section `%s' to huge (ie negative) file offset 0x%lx."
+msgstr "警告: セクション `%s' ã§å·¨å¤§ãª (例: è² æ•°) ファイルオフセット 0x%lx ã¸ã®æ›¸ãè¾¼ã¿ã§ã™"
+
+#: bout.c:1146 elf-m10300.c:2075 elf32-avr.c:1654 elf32-frv.c:5731
+#: elfxx-sparc.c:2796 reloc.c:5677 reloc16.c:162 elf32-ia64.c:360
+#: elf64-ia64.c:360
+msgid "%P%F: --relax and -r may not be used together\n"
+msgstr "%P%F: --relax ãŠã‚ˆã³ -r ã¯åŒæ™‚ã«ä½¿ç”¨ã§ãã¾ã›ã‚“\n"
+
+#: cache.c:226
+msgid "reopening %B: %s\n"
+msgstr "%B ã‚’å†ã‚ªãƒ¼ãƒ—ンã—ã¦ã„ã¾ã™: %s\n"
+
+#: coff-alpha.c:491
+msgid ""
+"%B: Cannot handle compressed Alpha binaries.\n"
+" Use compiler flags, or objZ, to generate uncompressed binaries."
+msgstr ""
+"%B: 圧縮ã•ã‚ŒãŸ Alpha ãƒã‚¤ãƒŠãƒªã‚’扱ã†ã“ã¨ãŒã§ãã¾ã›ã‚“。\n"
+" コンパイラã®ãƒ•ãƒ©ã‚°ã¾ãŸã¯ objZ ã§éžåœ§ç¸®ã®ãƒã‚¤ãƒŠãƒªã‚’作æˆã—ã¦ãã ã•ã„。"
+
+#: coff-alpha.c:648
+msgid "%B: unknown/unsupported relocation type %d"
+msgstr "%B: ä¸æ˜Ž/サãƒãƒ¼ãƒˆã•ã‚Œãªã„å†é…置型 %d ã§ã™"
+
+#: coff-alpha.c:900 coff-alpha.c:937 coff-alpha.c:2025 coff-mips.c:1003
+msgid "GP relative relocation used when GP not defined"
+msgstr "GP ãŒæœªå®šç¾©ã®æ™‚ã« GP 関連å†é…ç½®ãŒä½¿ã‚ã‚Œã¾ã—ãŸ"
+
+#: coff-alpha.c:1502
+msgid "using multiple gp values"
+msgstr "複数㮠gp 値を使用ã—ã¦ã„ã¾ã™"
+
+#: coff-alpha.c:1561
+msgid "%B: unsupported relocation: ALPHA_R_GPRELHIGH"
+msgstr "%B: サãƒãƒ¼ãƒˆã•ã‚Œã¦ã„ãªã„å†é…ç½®ã§ã™: ALPHA_R_GPRELHIGH"
+
+#: coff-alpha.c:1568
+msgid "%B: unsupported relocation: ALPHA_R_GPRELLOW"
+msgstr "%B: サãƒãƒ¼ãƒˆã•ã‚Œã¦ã„ãªã„å†é…ç½®ã§ã™: ALPHA_R_GPRELLOW"
+
+#: coff-alpha.c:1575 elf32-m32r.c:2493 elf64-alpha.c:4079 elf64-alpha.c:4228
+#: elf32-ia64.c:3845 elf64-ia64.c:3845
+msgid "%B: unknown relocation type %d"
+msgstr "%B: ä¸æ˜Žãªå†é…置型 %d ã§ã™"
+
+#: coff-arm.c:1038
+#, c-format
+msgid "%B: unable to find THUMB glue '%s' for `%s'"
+msgstr "%B: Thumb 糊 '%s' (`%s' 用) ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“"
+
+#: coff-arm.c:1067
+#, c-format
+msgid "%B: unable to find ARM glue '%s' for `%s'"
+msgstr "%B: ARM 糊 '%s' (`%s' 用) ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“"
+
+#: coff-arm.c:1369 elf32-arm.c:6980
+#, c-format
+msgid ""
+"%B(%s): warning: interworking not enabled.\n"
+" first occurrence: %B: arm call to thumb"
+msgstr ""
+"%B(%s): 警告: ARM/Thumb 命令相互利用ãŒæœ‰åŠ¹ã«ãªã£ã¦ã„ã¾ã›ã‚“。\n"
+" 最åˆã®å‡ºç¾ç®‡æ‰€: %B: Thumb を呼ã³å‡ºã™ ARM 命令"
+
+#: coff-arm.c:1459
+#, c-format
+msgid ""
+"%B(%s): warning: interworking not enabled.\n"
+" first occurrence: %B: thumb call to arm\n"
+" consider relinking with --support-old-code enabled"
+msgstr ""
+"%B(%s): 警告: ARM/Thumb 命令相互利用ãŒæœ‰åŠ¹ã«ãªã£ã¦ã„ã¾ã›ã‚“。\n"
+" 最åˆã®å‡ºç¾ç®‡æ‰€: %B: ARM を呼ã³å‡ºã™ Thumb 命令\n"
+" --support-old-code を有効ã«ã—ã¦å†ãƒªãƒ³ã‚¯ã™ã‚‹ã“ã¨ã‚’検討ã—ã¦ãã ã•ã„"
+
+#: coff-arm.c:1754 coff-tic80.c:695 cofflink.c:3081
+msgid "%B: bad reloc address 0x%lx in section `%A'"
+msgstr "%B: 誤ã£ãŸå†é…置アドレス 0x%lx ãŒã‚»ã‚¯ã‚·ãƒ§ãƒ³ `%A' 内ã«ã‚ã‚Šã¾ã™"
+
+#: coff-arm.c:2079
+msgid "%B: illegal symbol index in reloc: %d"
+msgstr "%B: å†é…置内ã®ã‚·ãƒ³ãƒœãƒ«ç´¢å¼•ãŒä¸æ­£ã§ã™: %d"
+
+#: coff-arm.c:2210
+#, c-format
+msgid "error: %B is compiled for APCS-%d, whereas %B is compiled for APCS-%d"
+msgstr "エラー: %B 㯠APCS-%d ã«å¯¾ã—ã¦ã‚³ãƒ³ãƒ‘イルã•ã‚Œã¦ã„ã‚‹ã«ã‚‚ã‹ã‹ã‚らãšã€ %B 㯠APCS-%d ã«å¯¾ã—ã¦ã‚³ãƒ³ãƒ‘イルã•ã‚Œã¦ã„ã¾ã™"
+
+#: coff-arm.c:2226 elf32-arm.c:15580
+#, c-format
+msgid "error: %B passes floats in float registers, whereas %B passes them in integer registers"
+msgstr "エラー: %B ã¯æµ®å‹•å°æ•°ã‚’浮動å°æ•°ãƒ¬ã‚¸ã‚¹ã‚¿ã«æ¸¡ã—ã¦ã„ã‚‹ã«ã‚‚ã‹ã‹ã‚らãšã€ %B ã¯æµ®å‹•å°æ•°ã‚’整数レジスタã«æ¸¡ã—ã¦ã„ã¾ã™"
+
+#: coff-arm.c:2229 elf32-arm.c:15584
+#, c-format
+msgid "error: %B passes floats in integer registers, whereas %B passes them in float registers"
+msgstr "エラー: %B ã¯æµ®å‹•å°æ•°ã‚’整数レジスタã«æ¸¡ã—ã¦ã„ã‚‹ã«ã‚‚ã‹ã‹ã‚らãšã€ %B ã¯æµ®å‹•å°æ•°ã‚’浮動å°æ•°ãƒ¬ã‚¸ã‚¹ã‚¿ã«æ¸¡ã—ã¦ã„ã¾ã™"
+
+#: coff-arm.c:2243
+#, c-format
+msgid "error: %B is compiled as position independent code, whereas target %B is absolute position"
+msgstr "エラー: %B ã¯ä½ç½®éžä¾å­˜ã‚³ãƒ¼ãƒ‰ã¨ã—ã¦ã‚³ãƒ³ãƒ‘イルã•ã‚Œã¦ã„ã‚‹ã«ã‚‚é–¢ã‚らãšã€ã‚¿ãƒ¼ã‚²ãƒƒãƒˆ %B ã¯çµ¶å¯¾ä½ç½®ã‚³ãƒ¼ãƒ‰ã«ãªã£ã¦ã„ã¾ã™"
+
+#: coff-arm.c:2246
+#, c-format
+msgid "error: %B is compiled as absolute position code, whereas target %B is position independent"
+msgstr "エラー: %B ã¯çµ¶å¯¾ä½ç½®ã‚³ãƒ¼ãƒ‰ã¨ã—ã¦ã‚³ãƒ³ãƒ‘イルã•ã‚Œã¦ã„ã‚‹ã«ã‚‚ã‹ã‹ã‚らãšã€ã‚¿ãƒ¼ã‚²ãƒƒãƒˆ %B ã¯ä½ç½®éžä¾å­˜ã‚³ãƒ¼ãƒ‰ã«ãªã£ã¦ã„ã¾ã™"
+
+#: coff-arm.c:2274 elf32-arm.c:15649
+#, c-format
+msgid "Warning: %B supports interworking, whereas %B does not"
+msgstr "警告: %B 㯠ARM/Thumb 命令相互利用をサãƒãƒ¼ãƒˆã—ã¦ã„ã‚‹ã«ã‚‚ã‹ã‹ã‚らãšã€ %B ã¯ã‚µãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“"
+
+#: coff-arm.c:2277 elf32-arm.c:15655
+#, c-format
+msgid "Warning: %B does not support interworking, whereas %B does"
+msgstr "警告: %B 㯠ARM/Thumb 命令相互利用をサãƒãƒ¼ãƒˆã—ã¦ã„ãªã„ã«ã‚‚ã‹ã‹ã‚らãšã€ %B ã¯ã‚µãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã™"
+
+#: coff-arm.c:2301
+#, c-format
+msgid "private flags = %x:"
+msgstr "private フラグ = %x:"
+
+#: coff-arm.c:2309 elf32-arm.c:11752
+#, c-format
+msgid " [floats passed in float registers]"
+msgstr " [浮動å°æ•°ãŒæµ®å‹•å°æ•°ãƒ¬ã‚¸ã‚¹ã‚¿ã«æ¸¡ã•ã‚Œã¾ã—ãŸ]"
+
+#: coff-arm.c:2311
+#, c-format
+msgid " [floats passed in integer registers]"
+msgstr " [浮動å°æ•°ãŒæ•´æ•°ãƒ¬ã‚¸ã‚¹ã‚¿ã«æ¸¡ã•ã‚Œã¾ã—ãŸ]"
+
+#: coff-arm.c:2314 elf32-arm.c:11755
+#, c-format
+msgid " [position independent]"
+msgstr " [ä½ç½®éžä¾å­˜]"
+
+#: coff-arm.c:2316
+#, c-format
+msgid " [absolute position]"
+msgstr " [絶対ä½ç½®]"
+
+#: coff-arm.c:2320
+#, c-format
+msgid " [interworking flag not initialised]"
+msgstr " [ARM/Thumb 命令相互利用ã®ãƒ•ãƒ©ã‚°ã¯åˆæœŸåŒ–ã•ã‚Œã¦ã„ã¾ã›ã‚“]"
+
+#: coff-arm.c:2322
+#, c-format
+msgid " [interworking supported]"
+msgstr " [ARM/Thumb 命令相互利用ãŒã‚µãƒãƒ¼ãƒˆã•ã‚Œã¦ã„ã¾ã™]"
+
+#: coff-arm.c:2324
+#, c-format
+msgid " [interworking not supported]"
+msgstr " [ARM/Thumb 命令相互利用ã¯ã‚µãƒãƒ¼ãƒˆã•ã‚Œã¦ã„ã¾ã›ã‚“]"
+
+#: coff-arm.c:2370 elf32-arm.c:10787
+#, c-format
+msgid "Warning: Not setting interworking flag of %B since it has already been specified as non-interworking"
+msgstr "警告: ARM/Thumb 命令相互利用をã—ãªã„よã†ã«æ—¢ã«æŒ‡å®šã•ã‚Œã¦ã„ã‚‹ãŸã‚〠%B ã® ARM/Thumb 命令相互利用フラグを設定ã—ã¾ã›ã‚“"
+
+#: coff-arm.c:2374 elf32-arm.c:10791
+#, c-format
+msgid "Warning: Clearing the interworking flag of %B due to outside request"
+msgstr "警告: è¦æ±‚外ã®ãŸã‚ %s ã® ARM/Thumb 命令相互利用フラグをクリアã—ã¾ã™"
+
+#: coff-h8300.c:1122
+#, c-format
+msgid "cannot handle R_MEM_INDIRECT reloc when using %s output"
+msgstr "%s 出力を利用ã—ã¦ã„る時ã«ã¯ R_MEM_INDIRECT å†é…置を扱ãˆã¾ã›ã‚“"
+
+#: coff-i860.c:147
+#, c-format
+msgid "relocation `%s' not yet implemented"
+msgstr "å†é…ç½® `%s' ã¯ã¾ã å®Ÿè£…ã•ã‚Œã¦ã„ã¾ã›ã‚“"
+
+#: coff-i860.c:605 coff-tic54x.c:398 coffcode.h:5192
+msgid "%B: warning: illegal symbol index %ld in relocs"
+msgstr "%B: 警告: ä¸æ­£ãªã‚·ãƒ³ãƒœãƒ«ç´¢å¼• %ld ãŒå†é…置領域内ã«ã‚ã‚Šã¾ã™"
+
+#: coff-i960.c:143 coff-i960.c:506
+msgid "uncertain calling convention for non-COFF symbol"
+msgstr "éž COFF シンボルã«å¯¾ã™ã‚‹å‘¼ã³å‡ºã—è¦ç´„ãŒä¸ç¢ºå®šã§ã™"
+
+#: coff-m68k.c:506 elf32-bfin.c:5689 elf32-cr16.c:2897 elf32-m68k.c:4677
+msgid "unsupported reloc type"
+msgstr "サãƒãƒ¼ãƒˆã•ã‚Œã¦ã„ãªã„å†é…置型ã§ã™"
+
+#: coff-mips.c:688 elf32-mips.c:1014 elf32-score.c:430 elf32-score7.c:330
+#: elf64-mips.c:2019 elfn32-mips.c:1832
+msgid "GP relative relocation when _gp not defined"
+msgstr "GP 関連ã®å†é…置㌠_gp ãŒæœªå®šç¾©ã®æ™‚点ã§ç¾ã‚Œã¾ã—ãŸ"
+
+#: coff-or32.c:229
+msgid "Unrecognized reloc"
+msgstr "èªè­˜ã§ããªã„å†é…ç½®ã§ã™"
+
+#: coff-rs6000.c:2676
+#, c-format
+msgid "%s: unsupported relocation type 0x%02x"
+msgstr "%s: å†é…置型 0x%02x ã¯ã‚µãƒãƒ¼ãƒˆã•ã‚Œã¦ã„ã¾ã›ã‚“"
+
+#: coff-rs6000.c:2761
+#, c-format
+msgid "%s: TOC reloc at 0x%x to symbol `%s' with no TOC entry"
+msgstr "%s: TOC å†é…ç½®(0x%x, シンボル `%s') ã« TOC エントリãŒã‚ã‚Šã¾ã›ã‚“"
+
+#: coff-rs6000.c:3512 coff64-rs6000.c:2111
+msgid "%B: symbol `%s' has unrecognized smclas %d"
+msgstr "%B: シンボル `%s' ã¯èªè­˜ã§ããªã„ smclas %d ã‚’æŒã£ã¦ã„ã¾ã™"
+
+#: coff-sh.c:521
+#, c-format
+msgid "SH Error: unknown reloc type %d"
+msgstr "SH エラー: ä¸æ˜Žãªå†é…置型 %d ã§ã™"
+
+#: coff-tic4x.c:195 coff-tic54x.c:299 coff-tic80.c:458
+#, c-format
+msgid "Unrecognized reloc type 0x%x"
+msgstr "èªè­˜ã§ããªã„å†é…置型 0x%x ã§ã™"
+
+#: coff-tic4x.c:240
+#, c-format
+msgid "%s: warning: illegal symbol index %ld in relocs"
+msgstr "%s: 警告: ä¸æ­£ãªã‚·ãƒ³ãƒœãƒ«ç´¢å¼• %ld ãŒå†é…置領域内ã«ã‚ã‚Šã¾ã™"
+
+#: coff-w65.c:367
+#, c-format
+msgid "ignoring reloc %s\n"
+msgstr "å†é…ç½® %s を無視ã—ã¦ã„ã¾ã™\n"
+
+#: coffcode.h:991
+msgid "%B: warning: COMDAT symbol '%s' does not match section name '%s'"
+msgstr "%B: 警告: COMDAT シンボル '%s' ã¯ã‚»ã‚¯ã‚·ãƒ§ãƒ³å '%s' ã«é©åˆã—ã¾ã›ã‚“"
+
+#. Generate a warning message rather using the 'unhandled'
+#. variable as this will allow some .sys files generate by
+#. other toolchains to be processed. See bugzilla issue 196.
+#: coffcode.h:1215
+msgid "%B: Warning: Ignoring section flag IMAGE_SCN_MEM_NOT_PAGED in section %s"
+msgstr "%B: 警告: セクション %s 内㮠IMAGE_SCN_MEM_NOT_PAGED セクションフラグを無視ã—ã¦ã„ã¾ã™"
+
+#: coffcode.h:1282
+msgid "%B (%s): Section flag %s (0x%x) ignored"
+msgstr "%B (%s): セクションフラグ %s (0x%x) を無視ã—ã¾ã—ãŸ"
+
+#: coffcode.h:2424
+#, c-format
+msgid "Unrecognized TI COFF target id '0x%x'"
+msgstr "TI COFF ターゲット id '0x%x' ã‚’èªè­˜ã§ãã¾ã›ã‚“"
+
+#: coffcode.h:2738
+msgid "%B: reloc against a non-existant symbol index: %ld"
+msgstr "%B: 存在ã—ãªã„シンボル索引ã«å¯¾ã™ã‚‹å†é…ç½®ã§ã™: %ld"
+
+#: coffcode.h:3296
+msgid "%B: too many sections (%d)"
+msgstr "%B: セクションãŒå¤šã™ãŽã¾ã™ (%d)"
+
+#: coffcode.h:3712
+msgid "%B: section %s: string table overflow at offset %ld"
+msgstr "%B: セクション %s: オフセット %ld ã§æ–‡å­—列表ãŒæº¢ã‚Œã¾ã—ãŸ"
+
+#: coffcode.h:4517
+msgid "%B: warning: line number table read failed"
+msgstr "%B: 警告: 行番å·è¡¨ã®èª­ã¿è¾¼ã¿ã«å¤±æ•—ã—ã¾ã—ãŸ"
+
+#: coffcode.h:4547
+msgid "%B: warning: illegal symbol index %ld in line numbers"
+msgstr "%B: 警告: 無効ãªã‚·ãƒ³ãƒœãƒ«ç´¢å¼• %ld ãŒè¡Œç•ªå·ä¸­ã«ã‚ã‚Šã¾ã™"
+
+#: coffcode.h:4561
+msgid "%B: warning: duplicate line number information for `%s'"
+msgstr "%B: 警告: `%s' ã«å¯¾ã™ã‚‹è¡Œç•ªå·æƒ…å ±ãŒé‡è¤‡ã—ã¦ã„ã¾ã™"
+
+#: coffcode.h:4961
+msgid "%B: Unrecognized storage class %d for %s symbol `%s'"
+msgstr "%B: èªè­˜ã§ããªã„記憶域クラス %d (%s シンボル `%s' 用) ã§ã™"
+
+#: coffcode.h:5087
+msgid "warning: %B: local symbol `%s' has no section"
+msgstr "警告: %B: 局所シンボル `%s' ãŒã‚»ã‚¯ã‚·ãƒ§ãƒ³ã‚’æŒã£ã¦ã„ã¾ã›ã‚“"
+
+#: coffcode.h:5231
+msgid "%B: illegal relocation type %d at address 0x%lx"
+msgstr "%B: ä¸æ­£ãªå†é…置型 %d ãŒã‚¢ãƒ‰ãƒ¬ã‚¹ 0x%lx ã«ã‚ã‚Šã¾ã™"
+
+#: coffgen.c:1578
+msgid "%B: bad string table size %lu"
+msgstr "%s: 文字列表サイズ %lu ãŒèª¤ã£ã¦ã„ã¾ã™"
+
+#: cofflink.c:533 elflink.c:4353
+msgid "Warning: type of symbol `%s' changed from %d to %d in %B"
+msgstr "警告: シンボル `%s' ã®åž‹ãŒ %d ã‹ã‚‰ %d ã« %B 内ã§å¤‰æ›´ã•ã‚Œã¾ã—ãŸ"
+
+#: cofflink.c:2330
+msgid "%B: relocs in section `%A', but it has no contents"
+msgstr "%B: セクション `%A' ã«å†é…置領域ãŒã‚ã‚Šã¾ã™ãŒã€ä¸­èº«ãŒã‚ã‚Šã¾ã›ã‚“"
+
+#: cofflink.c:2392 elflink.c:9554
+msgid "%X`%s' referenced in section `%A' of %B: defined in discarded section `%A' of %B\n"
+msgstr "%X`%s' 㧠`%A' セクション (%B 内) ã§å‚ç…§ã•ã‚Œã¦ã„ã‚‹ã‚‚ã®: 破棄ã•ã‚ŒãŸã‚»ã‚¯ã‚·ãƒ§ãƒ³ `%A' (%B 内) ã§å®šç¾©ã•ã‚Œã¦ã„ã¾ã™\n"
+
+#: cofflink.c:2690 coffswap.h:826
+#, c-format
+msgid "%s: %s: reloc overflow: 0x%lx > 0xffff"
+msgstr "%s: %s: å†é…置領域ãŒæº¢ã‚Œã¾ã—ãŸ: 0x%lx > 0xffff"
+
+#: cofflink.c:2699 coffswap.h:812
+#, c-format
+msgid "%s: warning: %s: line number overflow: 0x%lx > 0xffff"
+msgstr "%s: 警告: %s: 行番å·ãŒæº¢ã‚Œã¾ã—ãŸ: 0x%lx > 0xffff"
+
+#: cpu-arm.c:189 cpu-arm.c:200
+msgid "error: %B is compiled for the EP9312, whereas %B is compiled for XScale"
+msgstr "エラー: %B 㯠EP9312 ã«å¯¾ã—ã¦ã‚³ãƒ³ãƒ‘イルã•ã‚Œã¦ã„ã‚‹ã«ã‚‚ã‹ã‹ã‚らãšã€ %B 㯠XScale ã«å¯¾ã—ã¦ã‚³ãƒ³ãƒ‘イルã•ã‚Œã¦ã„ã¾ã™"
+
+#: cpu-arm.c:333
+#, c-format
+msgid "warning: unable to update contents of %s section in %s"
+msgstr "警告: %s セクション (%s 内) ã®å†…容を更新ã§ãã¾ã›ã‚“"
+
+#: dwarf2.c:490
+#, c-format
+msgid "Dwarf Error: Can't find %s section."
+msgstr "Dwarf エラー: %s セクションãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“。"
+
+#: dwarf2.c:518
+#, c-format
+msgid "Dwarf Error: Offset (%lu) greater than or equal to %s size (%lu)."
+msgstr "Dwarf エラー: オフセット (%lu) ㌠%s ã®ã‚µã‚¤ã‚º (%lu) 以上ã§ã™ã€‚"
+
+#: dwarf2.c:940
+#, c-format
+msgid "Dwarf Error: Invalid or unhandled FORM value: %u."
+msgstr "Dwarf エラー: 無効ã¾ãŸã¯æ‰±ãˆãªã„ FORM 値ã§ã™: %u"
+
+#: dwarf2.c:1191
+msgid "Dwarf Error: mangled line number section (bad file number)."
+msgstr "Dwarf エラー: 行番å·ã‚»ã‚¯ã‚·ãƒ§ãƒ³ãŒå¤‰å½¢ã•ã‚Œã¾ã—ãŸï¼ˆä¸æ­£ãªãƒ•ã‚¡ã‚¤ãƒ«ç•ªå·ï¼‰ã€‚"
+
+#: dwarf2.c:1443
+#, c-format
+msgid "Dwarf Error: Unhandled .debug_line version %d."
+msgstr "Dwarf エラー: .debug_line ãƒãƒ¼ã‚¸ãƒ§ãƒ³ %d を扱ãˆã¾ã›ã‚“ã§ã—ãŸã€‚"
+
+#: dwarf2.c:1465
+msgid "Dwarf Error: Invalid maximum operations per instruction."
+msgstr "Dwarf エラー: 無効ãªå‘½ä»¤ã”ã¨ã®æœ€å¤§æ“作数ã§ã™ã€‚"
+
+#: dwarf2.c:1652
+msgid "Dwarf Error: mangled line number section."
+msgstr "Dwarf エラー: 行番å·ã‚»ã‚¯ã‚·ãƒ§ãƒ³ãŒå¤‰å½¢ã•ã‚Œã¾ã—ãŸã€‚"
+
+#: dwarf2.c:1978 dwarf2.c:2098 dwarf2.c:2383
+#, c-format
+msgid "Dwarf Error: Could not find abbrev number %u."
+msgstr "Dwarf エラー: abbrev ç•ªå· %u ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸã€‚"
+
+#: dwarf2.c:2344
+#, c-format
+msgid "Dwarf Error: found dwarf version '%u', this reader only handles version 2, 3 and 4 information."
+msgstr "Dwarf エラー: dwarf ãƒãƒ¼ã‚¸ãƒ§ãƒ³ '%u' ãŒè¦‹ã¤ã‹ã‚Šã¾ã—ãŸãŒã€ã“ã®å‡¦ç†ç³»ã¯ãƒãƒ¼ã‚¸ãƒ§ãƒ³ 2, 3 ãŠã‚ˆã³ 4 ã®æƒ…å ±ã—ã‹èª­ã¿è¾¼ã‚ã¾ã›ã‚“。"
+
+#: dwarf2.c:2351
+#, c-format
+msgid "Dwarf Error: found address size '%u', this reader can not handle sizes greater than '%u'."
+msgstr "Dwarf エラー: アドレスサイズ '%u' ãŒè¦‹ã¤ã‹ã‚Šã¾ã—ãŸãŒã€ã“ã®å‡¦ç†ç³»ã¯ã‚µã‚¤ã‚º '%u' より大ãã„サイズを扱ãˆã¾ã›ã‚“。"
+
+#: dwarf2.c:2374
+#, c-format
+msgid "Dwarf Error: Bad abbrev number: %u."
+msgstr "Dwarf エラー: ä¸æ­£ãª abbrev 番å·ã§ã™: %u"
+
+#: ecoff.c:1237
+#, c-format
+msgid "Unknown basic type %d"
+msgstr "基本型 %d ãŒä¸æ˜Žã§ã™"
+
+#: ecoff.c:1494
+#, c-format
+msgid ""
+"\n"
+" End+1 symbol: %ld"
+msgstr ""
+"\n"
+" End+1 シンボル: %ld"
+
+#: ecoff.c:1501 ecoff.c:1504
+#, c-format
+msgid ""
+"\n"
+" First symbol: %ld"
+msgstr ""
+"\n"
+" 最åˆã®ã‚·ãƒ³ãƒœãƒ«: %ld"
+
+#: ecoff.c:1516
+#, c-format
+msgid ""
+"\n"
+" End+1 symbol: %-7ld Type: %s"
+msgstr ""
+"\n"
+" End+1 シンボル: %-7ld タイプ: %s"
+
+#: ecoff.c:1523
+#, c-format
+msgid ""
+"\n"
+" Local symbol: %ld"
+msgstr ""
+"\n"
+" 局所シンボル: %ld"
+
+#: ecoff.c:1531
+#, c-format
+msgid ""
+"\n"
+" struct; End+1 symbol: %ld"
+msgstr ""
+"\n"
+" struct; End+1 シンボル: %ld"
+
+#: ecoff.c:1536
+#, c-format
+msgid ""
+"\n"
+" union; End+1 symbol: %ld"
+msgstr ""
+"\n"
+" union; End+1 シンボル: %ld"
+
+#: ecoff.c:1541
+#, c-format
+msgid ""
+"\n"
+" enum; End+1 symbol: %ld"
+msgstr ""
+"\n"
+" enum; End+1 シンボル: %ld"
+
+#: ecoff.c:1547
+#, c-format
+msgid ""
+"\n"
+" Type: %s"
+msgstr ""
+"\n"
+" åž‹: %s"
+
+#: elf-attrs.c:569
+msgid "error: %B: Object has vendor-specific contents that must be processed by the '%s' toolchain"
+msgstr "エラー: %B: オブジェクトã«ã¯ãƒ™ãƒ³ãƒ€å›ºæœ‰ã®å†…容ãŒã‚ã‚Š '%s' ツール群ã§å‡¦ç†ã•ã‚Œãªã‘ã‚Œã°ã„ã‘ã¾ã›ã‚“"
+
+#: elf-attrs.c:578
+msgid "error: %B: Object tag '%d, %s' is incompatible with tag '%d, %s'"
+msgstr "エラー: %B: オブジェクトタグ '%d, %s' ã¯ã‚¿ã‚° '%d, %s' ã¨äº’æ›æ€§ãŒã‚ã‚Šã¾ã›ã‚“"
+
+#: elf-eh-frame.c:913
+msgid "%P: error in %B(%A); no .eh_frame_hdr table will be created.\n"
+msgstr "%P: %B(%A) 内ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚.eh_frame_hdr 表ã¯ä½œæˆã•ã‚Œã¾ã›ã‚“。\n"
+
+#: elf-eh-frame.c:1165
+msgid "%P: fde encoding in %B(%A) prevents .eh_frame_hdr table being created.\n"
+msgstr "%P: %B(%A) 内㮠fde エンコード㯠.eh_frame_hdr 表ã®ä½œæˆã‚’阻害ã—ã¾ã™ã€‚\n"
+
+#: elf-eh-frame.c:1583
+msgid "%P: DW_EH_PE_datarel unspecified for this architecture.\n"
+msgstr "%P: ã“ã®ã‚¢ãƒ¼ã‚­ãƒ†ã‚¯ãƒãƒ£ç”¨ã«ã¯ DW_EH_PE_datarel ã¯æŒ‡å®šã•ã‚Œã¦ã„ã¾ã›ã‚“\n"
+
+#: elf-ifunc.c:179
+msgid "%F%P: dynamic STT_GNU_IFUNC symbol `%s' with pointer equality in `%B' can not be used when making an executable; recompile with -fPIE and relink with -pie\n"
+msgstr "%F%P: ãƒã‚¤ãƒ³ã‚¿ãŒç­‰ã—ã„å‹•çš„ STT_GNU_IFUNC シンボル `%s' (`%B' 内) ã¯å®Ÿè¡Œãƒ•ã‚¡ã‚¤ãƒ«ã‚’作æˆã™ã‚‹æ™‚ã«ä½¿ç”¨ã§ãã¾ã›ã‚“。-fPIE を付ã‘ã¦å†ã‚³ãƒ³ãƒ‘イルã—ãŸå¾Œã€-pie を付ã‘ã¦ãƒªãƒ³ã‚¯ã—ã¦ãã ã•ã„\n"
+
+#: elf-m10200.c:450 elf-m10300.c:1571 elf32-avr.c:1221 elf32-bfin.c:3209
+#: elf32-cr16.c:1482 elf32-cr16c.c:780 elf32-cris.c:2077 elf32-crx.c:922
+#: elf32-d10v.c:509 elf32-fr30.c:609 elf32-frv.c:4102 elf32-h8300.c:509
+#: elf32-i860.c:1211 elf32-ip2k.c:1468 elf32-iq2000.c:684 elf32-lm32.c:1168
+#: elf32-m32c.c:553 elf32-m32r.c:3111 elf32-m68hc1x.c:1138 elf32-mep.c:535
+#: elf32-microblaze.c:1231 elf32-moxie.c:282 elf32-msp430.c:486 elf32-mt.c:395
+#: elf32-openrisc.c:404 elf32-score.c:2731 elf32-score7.c:2540
+#: elf32-spu.c:5042 elf32-v850.c:2143 elf32-xstormy16.c:941 elf64-mmix.c:1522
+msgid "internal error: out of range error"
+msgstr "内部エラー: 範囲外エラーã§ã™"
+
+#: elf-m10200.c:454 elf-m10300.c:1575 elf32-avr.c:1225 elf32-bfin.c:3213
+#: elf32-cr16.c:1486 elf32-cr16c.c:784 elf32-cris.c:2081 elf32-crx.c:926
+#: elf32-d10v.c:513 elf32-fr30.c:613 elf32-frv.c:4106 elf32-h8300.c:513
+#: elf32-i860.c:1215 elf32-iq2000.c:688 elf32-lm32.c:1172 elf32-m32c.c:557
+#: elf32-m32r.c:3115 elf32-m68hc1x.c:1142 elf32-mep.c:539
+#: elf32-microblaze.c:1235 elf32-moxie.c:286 elf32-msp430.c:490
+#: elf32-openrisc.c:408 elf32-score.c:2735 elf32-score7.c:2544
+#: elf32-spu.c:5046 elf32-v850.c:2147 elf32-xstormy16.c:945 elf64-mmix.c:1526
+#: elfxx-mips.c:9193
+msgid "internal error: unsupported relocation error"
+msgstr "内部エラー: 未サãƒãƒ¼ãƒˆã®å†é…置エラー"
+
+#: elf-m10200.c:458 elf32-cr16.c:1490 elf32-cr16c.c:788 elf32-crx.c:930
+#: elf32-d10v.c:517 elf32-h8300.c:517 elf32-lm32.c:1176 elf32-m32r.c:3119
+#: elf32-m68hc1x.c:1146 elf32-microblaze.c:1239 elf32-score.c:2739
+#: elf32-score7.c:2548 elf32-spu.c:5050
+msgid "internal error: dangerous error"
+msgstr "内部エラー: å±é™ºãªã‚¨ãƒ©ãƒ¼"
+
+#: elf-m10200.c:462 elf-m10300.c:1591 elf32-avr.c:1233 elf32-bfin.c:3221
+#: elf32-cr16.c:1494 elf32-cr16c.c:792 elf32-cris.c:2089 elf32-crx.c:934
+#: elf32-d10v.c:521 elf32-fr30.c:621 elf32-frv.c:4114 elf32-h8300.c:521
+#: elf32-i860.c:1223 elf32-ip2k.c:1483 elf32-iq2000.c:696 elf32-lm32.c:1180
+#: elf32-m32c.c:565 elf32-m32r.c:3123 elf32-m68hc1x.c:1150 elf32-mep.c:547
+#: elf32-microblaze.c:1243 elf32-moxie.c:294 elf32-msp430.c:498 elf32-mt.c:403
+#: elf32-openrisc.c:416 elf32-score.c:2748 elf32-score7.c:2552
+#: elf32-spu.c:5054 elf32-v850.c:2167 elf32-xstormy16.c:953 elf64-mmix.c:1534
+msgid "internal error: unknown error"
+msgstr "内部エラー: ä¸æ˜Žãªã‚¨ãƒ©ãƒ¼"
+
+#: elf-m10300.c:1515 elf32-arm.c:10365 elf32-i386.c:4107 elf32-m32r.c:2604
+#: elf32-m68k.c:4156 elf32-s390.c:3010 elf32-sh.c:4223 elf32-xtensa.c:3067
+#: elf64-s390.c:2985 elf64-sh64.c:1636 elf64-x86-64.c:3882 elfxx-sparc.c:3807
+msgid "%B(%A+0x%lx): unresolvable %s relocation against symbol `%s'"
+msgstr "%B(%A+0x%lx): 解決ã§ããªã„ %s å†é…ç½® (シンボル `%s' ã«å¯¾ã™ã‚‹) ã§ã™"
+
+#: elf-m10300.c:1580
+msgid "error: inappropriate relocation type for shared library (did you forget -fpic?)"
+msgstr "エラー: 共有ライブラリã«å¯¾ã™ã‚‹ä¸é©åˆ‡ãªå†é…置型ã§ã™ (-fpic を忘れã¦ã„ã¾ã›ã‚“ã‹?)"
+
+#: elf-m10300.c:1583
+msgid "%B: error: taking the address of protected function '%s' cannot be done when making a shared library"
+msgstr "%B: エラー: ä¿è­·ã•ã‚ŒãŸé–¢æ•° '%s' ã®ã‚¢ãƒ‰ãƒ¬ã‚¹ã¯å…±æœ‰ãƒ©ã‚¤ãƒ–ラリ作æˆæ™‚ã«ã¯å–å¾—ã§ãã¾ã›ã‚“"
+
+#: elf-m10300.c:1586
+msgid "internal error: suspicious relocation type used in shared library"
+msgstr "内部エラー: 共有ライブラリ内ã«ç–‘å•ã®æ®‹ã‚‹å†é…置型ãŒä½¿ç”¨ã•ã‚Œã¦ã„ã¾ã™"
+
+#: elf-m10300.c:4384 elf32-arm.c:12743 elf32-cr16.c:2451 elf32-cris.c:3044
+#: elf32-hppa.c:1894 elf32-i370.c:503 elf32-i386.c:2043 elf32-lm32.c:1868
+#: elf32-m32r.c:1927 elf32-m68k.c:3252 elf32-s390.c:1652 elf32-sh.c:2931
+#: elf32-tic6x.c:2160 elf32-vax.c:1040 elf64-s390.c:1635 elf64-sh64.c:3377
+#: elf64-x86-64.c:1985 elfxx-sparc.c:2104
+#, c-format
+msgid "dynamic variable `%s' is zero size"
+msgstr "動的変数 `%s' ã®ã‚µã‚¤ã‚ºãŒ 0 ã§ã™"
+
+#: elf.c:334
+msgid "%B: invalid string offset %u >= %lu for section `%s'"
+msgstr "%B: 無効ãªæ–‡å­—列オフセット %u >= %lu (セクション `%s' 用) ã§ã™"
+
+#: elf.c:446
+msgid "%B symbol number %lu references nonexistent SHT_SYMTAB_SHNDX section"
+msgstr "%B ã‚·ãƒ³ãƒœãƒ«ç•ªå· %lu ãŒå­˜åœ¨ã—ãªã„ SHT_SYMTAB_SHNDX セクションをå‚ç…§ã—ã¦ã„ã¾ã™"
+
+#: elf.c:602
+msgid "%B: Corrupt size field in group section header: 0x%lx"
+msgstr "%B: グループセクションヘッダ内ã«å£Šã‚ŒãŸã‚µã‚¤ã‚ºãƒ•ã‚£ãƒ¼ãƒ«ãƒ‰ãŒã‚ã‚Šã¾ã™: 0x%lx"
+
+#: elf.c:638
+msgid "%B: invalid SHT_GROUP entry"
+msgstr "%B: 無効㪠SHT_GROUP エントリã§ã™"
+
+#: elf.c:708
+msgid "%B: no group info for section %A"
+msgstr "%B: セクション %A ã«ã‚°ãƒ«ãƒ¼ãƒ—情報ãŒã‚ã‚Šã¾ã›ã‚“"
+
+#: elf.c:737 elf.c:3121 elflink.c:10144
+msgid "%B: warning: sh_link not set for section `%A'"
+msgstr "%B: 警告: セクション `%A' ã«å¯¾ã™ã‚‹ sh_link ãŒè¨­å®šã•ã‚Œã¦ã„ã¾ã›ã‚“"
+
+#: elf.c:756
+msgid "%B: sh_link [%d] in section `%A' is incorrect"
+msgstr "%B: sh_link [%d] (セクション `%A' 内) ã«èª¤ã‚ŠãŒã‚ã‚Šã¾ã™"
+
+#: elf.c:791
+msgid "%B: unknown [%d] section `%s' in group [%s]"
+msgstr "%B: ä¸æ˜Žãª [%d] セクション `%s' ãŒã‚°ãƒ«ãƒ¼ãƒ— [%s] 内ã«ã‚ã‚Šã¾ã™ "
+
+#: elf.c:1041
+msgid "%B: unable to initialize commpress status for section %s"
+msgstr "%B: セクション %s ã«å¯¾ã™ã‚‹åœ§ç¸®çŠ¶æ…‹ã‚’åˆæœŸåŒ–ã§ãã¾ã›ã‚“"
+
+#: elf.c:1061
+msgid "%B: unable to initialize decommpress status for section %s"
+msgstr "%B: セクション %s ã«å¯¾ã™ã‚‹ä¼¸å¼µçŠ¶æ…‹ã‚’åˆæœŸåŒ–ã§ãã¾ã›ã‚“"
+
+#: elf.c:1181
+#, c-format
+msgid ""
+"\n"
+"Program Header:\n"
+msgstr ""
+"\n"
+"プログラムヘッダ:\n"
+
+#: elf.c:1223
+#, c-format
+msgid ""
+"\n"
+"Dynamic Section:\n"
+msgstr ""
+"\n"
+"動的セクション:\n"
+
+#: elf.c:1359
+#, c-format
+msgid ""
+"\n"
+"Version definitions:\n"
+msgstr ""
+"\n"
+"ãƒãƒ¼ã‚¸ãƒ§ãƒ³å®šç¾©:\n"
+
+#: elf.c:1384
+#, c-format
+msgid ""
+"\n"
+"Version References:\n"
+msgstr ""
+"\n"
+"ãƒãƒ¼ã‚¸ãƒ§ãƒ³å‚ç…§:\n"
+
+#: elf.c:1389
+#, c-format
+msgid " required from %s:\n"
+msgstr " %s ã‹ã‚‰ã®è¦æ±‚:\n"
+
+#: elf.c:1796
+msgid "%B: invalid link %lu for reloc section %s (index %u)"
+msgstr "%B: 無効ãªãƒªãƒ³ã‚¯ %lu (å†é…置セクション %s 用) ã§ã™ (索引 %u)"
+
+#: elf.c:1966
+msgid "%B: don't know how to handle allocated, application specific section `%s' [0x%8x]"
+msgstr "%B: 割り当ã¦æ¸ˆã¿ã®ã‚¢ãƒ—リケーション固有ã®ã‚»ã‚¯ã‚·ãƒ§ãƒ³ `%s' [0x%8x] を扱ã†æ–¹æ³•ãŒåˆ†ã‹ã‚Šã¾ã›ã‚“"
+
+#: elf.c:1978
+msgid "%B: don't know how to handle processor specific section `%s' [0x%8x]"
+msgstr "%B: プロセッサ固有ã®ã‚»ã‚¯ã‚·ãƒ§ãƒ³ `%s' [0x%8x] を扱ã†æ–¹æ³•ãŒåˆ†ã‹ã‚Šã¾ã›ã‚“"
+
+#: elf.c:1989
+msgid "%B: don't know how to handle OS specific section `%s' [0x%8x]"
+msgstr "%B: OS 固有ã®ã‚»ã‚¯ã‚·ãƒ§ãƒ³ `%s' [0x%8x] を扱ã†æ–¹æ³•ãŒåˆ†ã‹ã‚Šã¾ã›ã‚“"
+
+#: elf.c:1999
+msgid "%B: don't know how to handle section `%s' [0x%8x]"
+msgstr "%B: セクション `%s' [0x%8x] を扱ã†æ–¹æ³•ãŒåˆ†ã‹ã‚Šã¾ã›ã‚“"
+
+#: elf.c:2634
+#, c-format
+msgid "warning: section `%A' type changed to PROGBITS"
+msgstr "警告: セクション `%A' ã®åž‹ãŒ PROGBITS ã«å¤‰æ›´ã•ã‚Œã¾ã—ãŸ"
+
+#: elf.c:3078
+msgid "%B: sh_link of section `%A' points to discarded section `%A' of `%B'"
+msgstr "%B: セクション `%A' ã® sh_link ãŒç ´æ£„ã•ã‚ŒãŸã‚»ã‚¯ã‚·ãƒ§ãƒ³ `%A' (`%B' 内) を指ã—ã¦ã„ã¾ã™"
+
+#: elf.c:3101
+msgid "%B: sh_link of section `%A' points to removed section `%A' of `%B'"
+msgstr "%B: セクション `%A' ã® sh_link ㌠削除ã•ã‚ŒãŸã‚»ã‚¯ã‚·ãƒ§ãƒ³ `%A' (`%B' 内) を指ã—ã¦ã„ã¾ã™ "
+
+#: elf.c:4527
+msgid "%B: The first section in the PT_DYNAMIC segment is not the .dynamic section"
+msgstr "%B: PT_DYNAMIC セグメントã®æœ€åˆã®ã‚»ã‚¯ã‚·ãƒ§ãƒ³ãŒ .dynamic セクションã§ã¯ã‚ã‚Šã¾ã›ã‚“"
+
+#: elf.c:4554
+msgid "%B: Not enough room for program headers, try linking with -N"
+msgstr "%B: プログラムヘッダ用ã®ç©ºé–“ãŒä¸å分ã§ã™ã€‚-N を付ã‘ã¦ãƒªãƒ³ã‚¯ã—ã¦ã¿ã¦ãã ã•ã„"
+
+#: elf.c:4641
+msgid "%B: section %A lma %#lx adjusted to %#lx"
+msgstr "%B: セクション %A ã® lma %#lx ㌠%#lx ã«èª¿ç¯€ã•ã‚Œã¾ã—ãŸ"
+
+#: elf.c:4774
+msgid "%B: section `%A' can't be allocated in segment %d"
+msgstr "%B: セクション `%A' をセグメント %d 内ã§å‰²ã‚Šå½“ã¦ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“"
+
+#: elf.c:4822
+msgid "%B: warning: allocated section `%s' not in segment"
+msgstr "%B: 警告: 割り当ã¦æ¸ˆã¿ã®ã‚»ã‚¯ã‚·ãƒ§ãƒ³ `%s' ãŒã‚»ã‚°ãƒ¡ãƒ³ãƒˆå†…ã«ã‚ã‚Šã¾ã›ã‚“"
+
+#: elf.c:5322
+msgid "%B: symbol `%s' required but not present"
+msgstr "%B: シンボル `%s' ãŒè¦æ±‚ã•ã‚Œã¾ã—ãŸãŒå­˜åœ¨ã—ã¾ã›ã‚“"
+
+#: elf.c:5660
+msgid "%B: warning: Empty loadable segment detected, is this intentional ?\n"
+msgstr "%B: 警告: 空ã®ãƒ­ãƒ¼ãƒ‰å¯èƒ½ã‚»ã‚°ãƒ¡ãƒ³ãƒˆãŒæ¤œå‡ºã•ã‚Œã¾ã—ãŸã€‚ã“ã‚Œã¯æ„図ã—ãŸã‚‚ã®ã§ã™ã‹?\n"
+
+#: elf.c:6688
+#, c-format
+msgid "Unable to find equivalent output section for symbol '%s' from section '%s'"
+msgstr "シンボル '%s' 用ã®ç­‰ä¾¡ãªå‡ºåŠ›ã‚»ã‚¯ã‚·ãƒ§ãƒ³ã‚’セクション '%s' ã‹ã‚‰è¦‹ã¤ã‘ã‚‹ã“ã¨ãŒå‡ºæ¥ã¾ã›ã‚“"
+
+#: elf.c:7684
+msgid "%B: unsupported relocation type %s"
+msgstr "%B: サãƒãƒ¼ãƒˆã•ã‚Œã¦ã„ãªã„å†é…置型 %s ã§ã™"
+
+#: elf32-arm.c:3590
+msgid ""
+"%B(%s): warning: interworking not enabled.\n"
+" first occurrence: %B: Thumb call to ARM"
+msgstr ""
+"%B(%s): 警告: ARM/Thumb 命令相互利用ãŒæœ‰åŠ¹ã§ã¯ã‚ã‚Šã¾ã›ã‚“\n"
+" 最åˆã®å‡ºç¾ç®‡æ‰€: %B: ARM を呼ã³å‡ºã™ Thumb 命令"
+
+#: elf32-arm.c:3637
+msgid ""
+"%B(%s): warning: interworking not enabled.\n"
+" first occurrence: %B: ARM call to Thumb"
+msgstr ""
+"%B(%s): 警告: ARM/Thumb 命令相互利用ãŒæœ‰åŠ¹ã§ã¯ã‚ã‚Šã¾ã›ã‚“\n"
+" 最åˆã®å‡ºç¾ç®‡æ‰€: %B: Thumb を呼ã³å‡ºã™ ARM 命令"
+
+#: elf32-arm.c:3849 elf32-arm.c:5286
+#, c-format
+msgid "%s: cannot create stub entry %s"
+msgstr "%s: スタブエントリ %s を作æˆã§ãã¾ã›ã‚“"
+
+#: elf32-arm.c:5402
+#, c-format
+msgid "unable to find THUMB glue '%s' for '%s'"
+msgstr "Thumb 糊 '%s' ('%s' 用) ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“"
+
+#: elf32-arm.c:5438
+#, c-format
+msgid "unable to find ARM glue '%s' for '%s'"
+msgstr "ARM 糊 '%s' ('%s' 用) ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“"
+
+#: elf32-arm.c:5964
+msgid "%B: BE8 images only valid in big-endian mode."
+msgstr "%B: BE8 イメージã¯ãƒ“ッグエンディアンモードã§ã®ã¿æœ‰åŠ¹ã§ã™"
+
+#. Give a warning, but do as the user requests anyway.
+#: elf32-arm.c:6194
+msgid "%B: warning: selected VFP11 erratum workaround is not necessary for target architecture"
+msgstr "%B: 警告: é¸æŠžã•ã‚ŒãŸ VFP11 エラッタ回é¿ã¯ã‚¿ãƒ¼ã‚²ãƒƒãƒˆã‚¢ãƒ¼ã‚­ãƒ†ã‚¯ãƒãƒ£ã§ã¯å¿…è¦ã§ã¯ã‚ã‚Šã¾ã›ã‚“"
+
+#: elf32-arm.c:6738 elf32-arm.c:6758
+msgid "%B: unable to find VFP11 veneer `%s'"
+msgstr ""
+
+#: elf32-arm.c:6806
+#, c-format
+msgid "Invalid TARGET2 relocation type '%s'."
+msgstr "無効㪠TARGET2 å†é…置型 '%s' ã§ã™ã€‚"
+
+#: elf32-arm.c:6890
+msgid ""
+"%B(%s): warning: interworking not enabled.\n"
+" first occurrence: %B: thumb call to arm"
+msgstr ""
+"%B(%s): 警告: ARM/Thumb 命令相互利用ãŒæœ‰åŠ¹ã§ã¯ã‚ã‚Šã¾ã›ã‚“\n"
+" 最åˆã®å‡ºç¾ç®‡æ‰€: %B: ARM を呼ã³å‡ºã™ Thumb 命令"
+
+#: elf32-arm.c:7674
+msgid "%B(%A+0x%lx):unexpected Thumb instruction '0x%x' in TLS trampoline"
+msgstr "%B(%A+0x%lx): TLS トランãƒãƒªãƒ³å†…ã«äºˆæœŸã—ãªã„ Thumb 命令 '0x%x' ãŒã‚ã‚Šã¾ã™"
+
+#: elf32-arm.c:7713
+msgid "%B(%A+0x%lx):unexpected ARM instruction '0x%x' in TLS trampoline"
+msgstr "%B(%A+0x%lx): TLS トランãƒãƒªãƒ³å†…ã«äºˆæœŸã—ãªã„ ARM 命令 '0x%x' ãŒã‚ã‚Šã¾ã™"
+
+#: elf32-arm.c:8166
+msgid "\\%B: Warning: Arm BLX instruction targets Arm function '%s'."
+msgstr "\\%B: 警告: ARM ã® BLX 命令㌠ARM 関数 '%s' を指ã—ã¦ã„ã¾ã™ã€‚"
+
+#: elf32-arm.c:8575
+msgid "%B: Warning: Thumb BLX instruction targets thumb function '%s'."
+msgstr "%B: 警告: Thumb ã® BLX 命令㌠Thumb 関数 '%s' を指ã—ã¦ã„ã¾ã™ã€‚"
+
+#: elf32-arm.c:9408
+msgid "%B(%A+0x%lx):unexpected Thumb instruction '0x%x' referenced by TLS_GOTDESC"
+msgstr "%B(%A+0x%lx): 予期ã—ãªã„ Thumb 命令 '0x%x' ㌠TLS_GOTDESC ã«ã‚ˆã£ã¦å‚ç…§ã•ã‚Œã¦ã„ã¾ã™"
+
+#: elf32-arm.c:9431
+msgid "%B(%A+0x%lx):unexpected ARM instruction '0x%x' referenced by TLS_GOTDESC"
+msgstr "%B(%A+0x%lx): 予期ã—ãªã„ ARM 命令 '0x%x' ㌠TLS_GOTDESC ã«ã‚ˆã£ã¦å‚ç…§ã•ã‚Œã¦ã„ã¾ã™"
+
+#: elf32-arm.c:9460
+msgid "%B(%A+0x%lx): R_ARM_TLS_LE32 relocation not permitted in shared object"
+msgstr "%B(%A+0x%lx): R_ARM_TLS_LE32 å†é…ç½®ã¯å…±æœ‰ã‚ªãƒ–ジェクト内ã§ã¯è¨±å¯ã•ã‚Œã¦ã„ã¾ã›ã‚“"
+
+#: elf32-arm.c:9675
+msgid "%B(%A+0x%lx): Only ADD or SUB instructions are allowed for ALU group relocations"
+msgstr "%B(%A+0x%lx): ALU グループå†é…ç½®ã«å¯¾ã—ã¦ã¯ ADD ã¾ãŸã¯ SUB 命令ã®ã¿è¨±å¯ã•ã‚Œã¦ã„ã¾ã™"
+
+#: elf32-arm.c:9715 elf32-arm.c:9802 elf32-arm.c:9885 elf32-arm.c:9970
+msgid "%B(%A+0x%lx): Overflow whilst splitting 0x%lx for group relocation %s"
+msgstr "%B(%A+0x%lx): 0x%lx をクループå†é…ç½® %s 用ã«åˆ†å‰²ä¸­ã«ã‚ªãƒ¼ãƒãƒ¼ãƒ•ãƒ­ãƒ¼ã—ã¾ã—ãŸ"
+
+#: elf32-arm.c:10209 elf32-sh.c:4112 elf64-sh64.c:1544
+msgid "%B(%A+0x%lx): %s relocation against SEC_MERGE section"
+msgstr "%B(%A+0x%lx): SEC_MERGE セクションã«å¯¾ã™ã‚‹ %s å†é…ç½®ã§ã™"
+
+#: elf32-arm.c:10320 elf32-m68k.c:4191 elf32-xtensa.c:2805
+msgid "%B(%A+0x%lx): %s used with TLS symbol %s"
+msgstr "%B(%A+0x%lx): %s ㌠TLS シンボル %s ã¨ä½µã›ã¦ä½¿ç”¨ã•ã‚Œã¾ã—ãŸ"
+
+#: elf32-arm.c:10321 elf32-m68k.c:4192 elf32-xtensa.c:2806
+msgid "%B(%A+0x%lx): %s used with non-TLS symbol %s"
+msgstr "%B(%A+0x%lx): %s ㌠TLS ã§ã¯ãªã„シンボル %s ã¨ä½µã›ã¦ä½¿ç”¨ã•ã‚Œã¾ã—ãŸ"
+
+#: elf32-arm.c:10399 elf32-tic6x.c:2751
+msgid "out of range"
+msgstr "範囲外"
+
+#: elf32-arm.c:10403 elf32-tic6x.c:2755
+msgid "unsupported relocation"
+msgstr "サãƒãƒ¼ãƒˆã•ã‚Œã¦ã„ãªã„å†é…ç½®"
+
+#: elf32-arm.c:10411 elf32-tic6x.c:2763
+msgid "unknown error"
+msgstr "ä¸æ˜Žãªã‚¨ãƒ©ãƒ¼"
+
+#: elf32-arm.c:10836
+msgid "Warning: Clearing the interworking flag of %B because non-interworking code in %B has been linked with it"
+msgstr "警告: %B ã® ARM/Thumb 命令相互利用フラグをクリアã—ã¦ã„ã¾ã™ (%B 内ã®éž ARM/Thumb 命令相互利用コードãŒãƒªãƒ³ã‚¯ã•ã‚ŒãŸãŸã‚)"
+
+#: elf32-arm.c:10930
+msgid "%B: Unknown mandatory EABI object attribute %d"
+msgstr "%B: ä¸æ˜Žãªå¿…é ˆ EABI オブジェクト属性 %d ã§ã™"
+
+#: elf32-arm.c:10938
+msgid "Warning: %B: Unknown EABI object attribute %d"
+msgstr "警告: %B: ä¸æ˜ŽãªEABI オブジェクト属性 %d ã§ã™"
+
+#: elf32-arm.c:11119
+msgid "error: %B: Unknown CPU architecture"
+msgstr "エラー: %B: ä¸æ˜Žãª CPU アーキテクãƒãƒ£ã§ã™"
+
+#: elf32-arm.c:11157
+msgid "error: %B: Conflicting CPU architectures %d/%d"
+msgstr "エラー: %B: CPU アーキテクãƒãƒ£ %d/%d ãŒç«¶åˆã—ã¦ã„ã¾ã™"
+
+#: elf32-arm.c:11206
+msgid "Error: %B has both the current and legacy Tag_MPextension_use attributes"
+msgstr "エラー: %B ã¯ç¾åœ¨ã¨æ˜”ã® Tag_MPextension_use 属性を両方ã¨ã‚‚æŒã£ã¦ã„ã¾ã™"
+
+#: elf32-arm.c:11231
+msgid "error: %B uses VFP register arguments, %B does not"
+msgstr "エラー: %B 㯠VFP レジスタ引数を使用ã—ã¦ã„ã¾ã™ãŒã€%B ã¯ä½¿ç”¨ã—ã¦ã„ã¾ã›ã‚“"
+
+#: elf32-arm.c:11376
+msgid "error: %B: unable to merge virtualization attributes with %B"
+msgstr "エラー: %B: 仮想属性を %B ã¨ä½µåˆã§ãã¾ã›ã‚“"
+
+#: elf32-arm.c:11402
+msgid "error: %B: Conflicting architecture profiles %c/%c"
+msgstr "エラー: %B: アーキテクãƒãƒ£ãƒ—ロファイル %c/%c ãŒç«¶åˆã—ã¦ã„ã¾ã™"
+
+#: elf32-arm.c:11503
+msgid "Warning: %B: Conflicting platform configuration"
+msgstr "警告: %B: プラットフォーム設定ãŒç«¶åˆã—ã¦ã„ã¾ã™"
+
+#: elf32-arm.c:11512
+msgid "error: %B: Conflicting use of R9"
+msgstr "エラー: %B: R9 ã®ä½¿ç”¨ãŒç«¶åˆã—ã¦ã„ã¾ã™"
+
+#: elf32-arm.c:11524
+msgid "error: %B: SB relative addressing conflicts with use of R9"
+msgstr "error: %B: SB 相対アドレスã®ä½¿ç”¨ã¯ R9 ã®ä½¿ç”¨ã¨ç«¶åˆã—ã¦ã„ã¾ã™"
+
+#: elf32-arm.c:11537
+msgid "warning: %B uses %u-byte wchar_t yet the output is to use %u-byte wchar_t; use of wchar_t values across objects may fail"
+msgstr "警告: %B 㯠%u ãƒã‚¤ãƒˆã® wchar_t を使用ã—ã¦ã„ã¾ã™ãŒã€å‡ºåŠ›ã¯ %u ãƒã‚¤ãƒˆã® wchar_t を使用ã—ã¦ã„ã¾ã™ã€‚オブジェクトをã¾ãŸãŒã‚‹ wchar_t 値ã®ä½¿ç”¨ã¯å¤±æ•—ã™ã‚‹ã‹ã‚‚ã—ã‚Œã¾ã›ã‚“"
+
+#: elf32-arm.c:11568
+msgid "warning: %B uses %s enums yet the output is to use %s enums; use of enum values across objects may fail"
+msgstr "警告: %B 㯠%s enum を使用ã—ã¦ã„ã¾ã™ãŒã€å‡ºåŠ›ã¯ %s enum を使用ã—ã¾ã™ã€‚オブジェクトをã¾ãŸãŒã‚‹ enum 値ã®ä½¿ç”¨ã¯å¤±æ•—ã™ã‚‹ã‹ã‚‚ã—ã‚Œã¾ã›ã‚“"
+
+#: elf32-arm.c:11580
+msgid "error: %B uses iWMMXt register arguments, %B does not"
+msgstr "エラー: %B 㯠iWMMXt レジスタ引数を使用ã—ã¦ã„ã¾ã™ãŒã€ %B ã¯ä½¿ç”¨ã—ã¦ã„ã¾ã›ã‚“"
+
+#: elf32-arm.c:11597
+msgid "error: fp16 format mismatch between %B and %B"
+msgstr "エラー: fp16 ã®å½¢å¼ãŒ %B 㨠%B ã®é–“ã§ä¸€è‡´ã—ã¾ã›ã‚“"
+
+#: elf32-arm.c:11621
+msgid "DIV usage mismatch between %B and %B"
+msgstr "DIV ã®ä½¿ç”¨æ³•ãŒ %B 㨠%B ã®é–“ã§ä¸€è‡´ã—ã¾ã›ã‚“"
+
+#: elf32-arm.c:11640
+msgid "%B has has both the current and legacy Tag_MPextension_use attributes"
+msgstr "%B ã¯ç¾åœ¨ã¨æ˜”ã®ã® Tag_MPextension_use 属性をæŒã£ã¦ã„ã¾ã™"
+
+#. Ignore init flag - it may not be set, despite the flags field
+#. containing valid data.
+#. Ignore init flag - it may not be set, despite the flags field containing valid data.
+#: elf32-arm.c:11728 elf32-bfin.c:5075 elf32-cris.c:4162 elf32-m68hc1x.c:1282
+#: elf32-m68k.c:1235 elf32-score.c:3996 elf32-score7.c:3803 elf32-vax.c:528
+#: elfxx-mips.c:12857
+#, c-format
+msgid "private flags = %lx:"
+msgstr "private フラグ = %lx:"
+
+#: elf32-arm.c:11737
+#, c-format
+msgid " [interworking enabled]"
+msgstr " [ARM/Thumb 命令相互利用ã¯æœ‰åŠ¹]"
+
+#: elf32-arm.c:11745
+#, c-format
+msgid " [VFP float format]"
+msgstr " [VFP 浮動å°æ•°å½¢å¼]"
+
+#: elf32-arm.c:11747
+#, c-format
+msgid " [Maverick float format]"
+msgstr " [Maverick 浮動å°æ•°å½¢å¼]"
+
+#: elf32-arm.c:11749
+#, c-format
+msgid " [FPA float format]"
+msgstr " [FPA 浮動å°æ•°å½¢å¼]"
+
+#: elf32-arm.c:11758
+#, c-format
+msgid " [new ABI]"
+msgstr " [æ–° ABI]"
+
+#: elf32-arm.c:11761
+#, c-format
+msgid " [old ABI]"
+msgstr " [æ—§ ABI]"
+
+#: elf32-arm.c:11764
+#, c-format
+msgid " [software FP]"
+msgstr " [ソフトウェア浮動å°æ•°ç‚¹]"
+
+#: elf32-arm.c:11773
+#, c-format
+msgid " [Version1 EABI]"
+msgstr " [ãƒãƒ¼ã‚¸ãƒ§ãƒ³ 1 EABI]"
+
+#: elf32-arm.c:11776 elf32-arm.c:11787
+#, c-format
+msgid " [sorted symbol table]"
+msgstr " [ソート済シンボル表]"
+
+#: elf32-arm.c:11778 elf32-arm.c:11789
+#, c-format
+msgid " [unsorted symbol table]"
+msgstr " [未ソートシンボル表]"
+
+#: elf32-arm.c:11784
+#, c-format
+msgid " [Version2 EABI]"
+msgstr " [ãƒãƒ¼ã‚¸ãƒ§ãƒ³ 2 EABI]"
+
+#: elf32-arm.c:11792
+#, c-format
+msgid " [dynamic symbols use segment index]"
+msgstr ""
+
+#: elf32-arm.c:11795
+#, c-format
+msgid " [mapping symbols precede others]"
+msgstr ""
+
+#: elf32-arm.c:11802
+#, c-format
+msgid " [Version3 EABI]"
+msgstr " [ãƒãƒ¼ã‚¸ãƒ§ãƒ³ 3 EABI]"
+
+#: elf32-arm.c:11806
+#, c-format
+msgid " [Version4 EABI]"
+msgstr " [ãƒãƒ¼ã‚¸ãƒ§ãƒ³ 4 EABI]"
+
+#: elf32-arm.c:11810
+#, c-format
+msgid " [Version5 EABI]"
+msgstr " [ãƒãƒ¼ã‚¸ãƒ§ãƒ³ 5 EABI]"
+
+#: elf32-arm.c:11813
+#, c-format
+msgid " [BE8]"
+msgstr " [BE8]"
+
+#: elf32-arm.c:11816
+#, c-format
+msgid " [LE8]"
+msgstr " [LE8]"
+
+#: elf32-arm.c:11822
+#, c-format
+msgid " <EABI version unrecognised>"
+msgstr " <EABI ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‚’èªè­˜ã§ãã¾ã›ã‚“>"
+
+#: elf32-arm.c:11829
+#, c-format
+msgid " [relocatable executable]"
+msgstr " [å†é…ç½®å¯èƒ½å®Ÿè¡Œãƒ•ã‚¡ã‚¤ãƒ«]"
+
+#: elf32-arm.c:11832
+#, c-format
+msgid " [has entry point]"
+msgstr " [エントリãƒã‚¤ãƒ³ãƒˆã‚’æŒã£ã¦ã„ã¾ã™]"
+
+#: elf32-arm.c:11837
+#, c-format
+msgid "<Unrecognised flag bits set>"
+msgstr "<フラグビットセットをèªè­˜ã§ãã¾ã›ã‚“>"
+
+#: elf32-arm.c:12135 elf32-i386.c:1323 elf32-s390.c:1000 elf32-tic6x.c:2827
+#: elf32-xtensa.c:1009 elf64-s390.c:960 elf64-x86-64.c:1172 elfxx-sparc.c:1370
+msgid "%B: bad symbol index: %d"
+msgstr "%B: シンボル索引ã«èª¤ã‚ŠãŒã‚ã‚Šã¾ã™: %d"
+
+#: elf32-arm.c:12283 elf64-x86-64.c:1370 elf64-x86-64.c:1541 elfxx-mips.c:7949
+msgid "%B: relocation %s against `%s' can not be used when making a shared object; recompile with -fPIC"
+msgstr "%B: å†é…ç½® %s (`%s' ã«å¯¾ã™ã‚‹) ã¯å…±æœ‰ã‚ªãƒ–ジェクト作æˆæ™‚ã«ã¯ä½¿ç”¨ã§ãã¾ã›ã‚“。-fPIC を付ã‘ã¦å†ã‚³ãƒ³ãƒ‘イルã—ã¦ãã ã•ã„。"
+
+#: elf32-arm.c:13412
+#, c-format
+msgid "Errors encountered processing file %s"
+msgstr "ファイル %s を処ç†ä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ"
+
+#: elf32-arm.c:14795
+msgid "%B: error: Cortex-A8 erratum stub is allocated in unsafe location"
+msgstr "%B: エラー: Cortex-A8 エラッタスタブãŒå®‰å…¨ã§ãªã„ä½ç½®ã«é…ç½®ã•ã‚Œã¦ã„ã¾ã™"
+
+#. There's not much we can do apart from complain if this
+#. happens.
+#: elf32-arm.c:14822
+msgid "%B: error: Cortex-A8 erratum stub out of range (input file too large)"
+msgstr "%B: エラー: Cortex-A8 エラッタスタブãŒç¯„囲外ã§ã™ (入力ファイルãŒå¤§ãã™ãŽã¾ã™)"
+
+#: elf32-arm.c:14916 elf32-arm.c:14938
+msgid "%B: error: VFP11 veneer out of range"
+msgstr ""
+
+#: elf32-arm.c:15477
+msgid "error: %B is already in final BE8 format"
+msgstr "エラー: %B ã¯æ—¢ã«æœ€çµ‚ BE8 å½¢å¼ã§ã™"
+
+#: elf32-arm.c:15553
+msgid "error: Source object %B has EABI version %d, but target %B has EABI version %d"
+msgstr "エラー: ソースオブジェクト %B 㯠EABI ãƒãƒ¼ã‚¸ãƒ§ãƒ³ %d ã§ã™ãŒã€ã‚¿ãƒ¼ã‚²ãƒƒãƒˆ %B 㯠EABI ãƒãƒ¼ã‚¸ãƒ§ãƒ³ %d ã§ã™"
+
+#: elf32-arm.c:15569
+msgid "error: %B is compiled for APCS-%d, whereas target %B uses APCS-%d"
+msgstr "エラー: %B 㯠APCS-%d ã«å¯¾ã—ã¦ã‚³ãƒ³ãƒ‘イルã•ã‚Œã¦ã„ã¾ã™ã€‚一方ターゲット %B 㯠APCS-%d を使用ã—ã¦ã„ã¾ã™"
+
+#: elf32-arm.c:15594
+msgid "error: %B uses VFP instructions, whereas %B does not"
+msgstr "error: %B 㯠VFP 命令を使用ã—ã¦ã„ã¾ã™ã€‚一方 %B ã¯ä½¿ç”¨ã—ã¦ã„ã¾ã›ã‚“"
+
+#: elf32-arm.c:15598
+msgid "error: %B uses FPA instructions, whereas %B does not"
+msgstr "エラー: %B 㯠FPA 命令を使用ã—ã¦ã„ã¾ã™ã€‚一方 %B ã¯ä½¿ç”¨ã—ã¦ã„ã¾ã›ã‚“"
+
+#: elf32-arm.c:15608
+msgid "error: %B uses Maverick instructions, whereas %B does not"
+msgstr "エラー: %B 㯠Maverick 命令を使用ã—ã¦ã„ã¾ã™ã€‚一方 %B ã¯ä½¿ç”¨ã—ã¦ã„ã¾ã›ã‚“"
+
+#: elf32-arm.c:15612
+msgid "error: %B does not use Maverick instructions, whereas %B does"
+msgstr "エラー: %B 㯠Maverick 命令を使用ã—ã¦ã„ã¾ã›ã‚“。一方 %B ã¯ä½¿ç”¨ã—ã¦ã„ã¾ã™"
+
+#: elf32-arm.c:15631
+msgid "error: %B uses software FP, whereas %B uses hardware FP"
+msgstr "エラー: %B ã¯ã‚½ãƒ•ãƒˆã‚¦ã‚§ã‚¢æµ®å‹•å°æ•°ç‚¹ã‚’使用ã—ã¦ã„ã¾ã™ã€‚一方 %B ã¯ãƒãƒ¼ãƒ‰ã‚¦ã‚§ã‚¢æµ®å‹•å°æ•°ç‚¹ã‚’使用ã—ã¦ã„ã¾ã™"
+
+#: elf32-arm.c:15635
+msgid "error: %B uses hardware FP, whereas %B uses software FP"
+msgstr "エラー: %B ã¯ãƒãƒ¼ãƒ‰ã‚¦ã‚§ã‚¢æµ®å‹•å°æ•°ç‚¹ã‚’使用ã—ã¦ã„ã¾ã™ã€‚一方 %B ã¯ã‚½ãƒ•ãƒˆã‚¦ã‚§ã‚¢æµ®å‹•å°æ•°ç‚¹ã‚’使用ã—ã¦ã„ã¾ã™"
+
+#: elf32-avr.c:1229 elf32-bfin.c:3217 elf32-cris.c:2085 elf32-fr30.c:617
+#: elf32-frv.c:4110 elf32-i860.c:1219 elf32-ip2k.c:1479 elf32-iq2000.c:692
+#: elf32-m32c.c:561 elf32-mep.c:543 elf32-moxie.c:290 elf32-msp430.c:494
+#: elf32-mt.c:399 elf32-openrisc.c:412 elf32-v850.c:2151 elf32-xstormy16.c:949
+#: elf64-mmix.c:1530
+msgid "internal error: dangerous relocation"
+msgstr "内部エラー: å±é™ºãªå†é…ç½®ã§ã™"
+
+#: elf32-avr.c:2415 elf32-hppa.c:598 elf32-m68hc1x.c:166
+msgid "%B: cannot create stub entry %s"
+msgstr "%B: スタブエントリ %s を作æˆã§ãã¾ã›ã‚“"
+
+#: elf32-bfin.c:107 elf32-bfin.c:363
+msgid "relocation should be even number"
+msgstr ""
+
+#: elf32-bfin.c:1591
+msgid "%B(%A+0x%lx): unresolvable relocation against symbol `%s'"
+msgstr "%B(%A+0x%lx): シンボル `%s' ã«å¯¾ã™ã‚‹è§£æ±ºã§ããªã„å†é…ç½®ã§ã™"
+
+#: elf32-bfin.c:1624 elf32-i386.c:4150 elf32-m68k.c:4233 elf32-s390.c:3062
+#: elf64-s390.c:3037 elf64-x86-64.c:3923
+msgid "%B(%A+0x%lx): reloc against `%s': error %d"
+msgstr "%B(%A+0x%lx): `%s' ã«å¯¾ã™ã‚‹å†é…ç½®: エラー %d"
+
+#: elf32-bfin.c:2723
+msgid "%B: relocation at `%A+0x%x' references symbol `%s' with nonzero addend"
+msgstr ""
+
+#: elf32-bfin.c:2737
+msgid "relocation references symbol not defined in the module"
+msgstr "å†é…ç½®ãŒãƒ¢ã‚¸ãƒ¥ãƒ¼ãƒ«å†…ã§å®šç¾©ã•ã‚Œã¦ã„ãªã„シンボルをå‚ç…§ã—ã¦ã„ã¾ã™"
+
+#: elf32-bfin.c:2834
+msgid "R_BFIN_FUNCDESC references dynamic symbol with nonzero addend"
+msgstr ""
+
+#: elf32-bfin.c:2875 elf32-bfin.c:2998
+msgid "cannot emit fixups in read-only section"
+msgstr "読ã¿è¾¼ã¿å°‚用セクション内ã§ä¿®æ­£ã‚’è¡Œã†ã“ã¨ãŒã§ãã¾ã›ã‚“"
+
+#: elf32-bfin.c:2906 elf32-bfin.c:3036 elf32-lm32.c:1103 elf32-sh.c:5021
+msgid "cannot emit dynamic relocations in read-only section"
+msgstr "読ã¿è¾¼ã¿å°‚用セクション内ã§å‹•çš„å†é…置を行ã†ã“ã¨ãŒã§ãã¾ã›ã‚“"
+
+#: elf32-bfin.c:2956
+msgid "R_BFIN_FUNCDESC_VALUE references dynamic symbol with nonzero addend"
+msgstr ""
+
+#: elf32-bfin.c:3121
+msgid "relocations between different segments are not supported"
+msgstr "ç•°ãªã‚‹ã‚»ã‚°ãƒ¡ãƒ³ãƒˆé–“ã®å†é…ç½®ã¯ã‚µãƒãƒ¼ãƒˆã•ã‚Œã¦ã„ã¾ã›ã‚“"
+
+#: elf32-bfin.c:3122
+msgid "warning: relocation references a different segment"
+msgstr "警告: å†é…ç½®ãŒç•°ãªã‚‹ã‚»ã‚°ãƒ¡ãƒ³ãƒˆã‚’å‚ç…§ã—ã¦ã„ã¾ã™"
+
+#: elf32-bfin.c:4967
+msgid "%B: unsupported relocation type %i"
+msgstr "%B: サãƒãƒ¼ãƒˆã•ã‚Œã¦ã„ãªã„å†é…置型 %i ã§ã™"
+
+#: elf32-bfin.c:5121 elf32-frv.c:6805
+#, c-format
+msgid "%s: cannot link non-fdpic object file into fdpic executable"
+msgstr "%s: fdpic 実行ファイル内ã«éž fdpic オブジェクトをリンクã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“"
+
+#: elf32-bfin.c:5125 elf32-frv.c:6809
+#, c-format
+msgid "%s: cannot link fdpic object file into non-fdpic executable"
+msgstr "%s: éž fdpic 実行ファイル内㫠fdpic オブジェクトをリンクã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“"
+
+#: elf32-bfin.c:5279
+#, c-format
+msgid "*** check this relocation %s"
+msgstr "*** å†é…ç½® %s を確èªã—ã¦ãã ã•ã„"
+
+#: elf32-cris.c:1172
+msgid "%B, section %A: unresolvable relocation %s against symbol `%s'"
+msgstr "%B セクション %A: 解決ã§ããªã„å†é…ç½® %s (シンボル `%s' ã«å¯¾ã™ã‚‹) ã§ã™"
+
+#: elf32-cris.c:1234
+msgid "%B, section %A: No PLT nor GOT for relocation %s against symbol `%s'"
+msgstr "%B, セクション %A: å†é…ç½® %s (シンボル `%s' ã«å¯¾ã™ã‚‹) ã«é–¢ã™ã‚‹ PLT ã¾ãŸã¯ GOT ãŒã‚ã‚Šã¾ã›ã‚“"
+
+#: elf32-cris.c:1236
+msgid "%B, section %A: No PLT for relocation %s against symbol `%s'"
+msgstr "%B, セクション %A: å†é…ç½® %s (シンボル `%s' ã«å¯¾ã™ã‚‹) ã«é–¢ã™ã‚‹ PLT ãŒã‚ã‚Šã¾ã›ã‚“"
+
+#: elf32-cris.c:1242 elf32-cris.c:1375 elf32-cris.c:1635 elf32-cris.c:1718
+#: elf32-cris.c:1871 elf32-tic6x.c:2660
+msgid "[whose name is lost]"
+msgstr "[åå‰ãŒç„¡ããªã£ã¦ã„ã¾ã™]"
+
+#: elf32-cris.c:1361 elf32-tic6x.c:2645
+msgid "%B, section %A: relocation %s with non-zero addend %d against local symbol"
+msgstr ""
+
+#: elf32-cris.c:1369 elf32-cris.c:1712 elf32-cris.c:1865 elf32-tic6x.c:2653
+msgid "%B, section %A: relocation %s with non-zero addend %d against symbol `%s'"
+msgstr ""
+
+#: elf32-cris.c:1395
+msgid "%B, section %A: relocation %s is not allowed for global symbol: `%s'"
+msgstr "%Bã€ã‚»ã‚¯ã‚·ãƒ§ãƒ³ %A: å†é…ç½® %s ã¯å¤§åŸŸã‚·ãƒ³ãƒœãƒ«ã«å¯¾ã—ã¦è¨±å¯ã•ã‚Œã¦ã„ã¾ã›ã‚“: `%s'"
+
+#: elf32-cris.c:1411
+msgid "%B, section %A: relocation %s with no GOT created"
+msgstr "%Bã€ã‚»ã‚¯ã‚·ãƒ§ãƒ³ %A: GOT ãŒç„¡ã„å†é…ç½® %s ãŒä½œæˆã•ã‚Œã¾ã—ãŸ"
+
+#. We shouldn't get here for GCC-emitted code.
+#: elf32-cris.c:1626
+msgid "%B, section %A: relocation %s has an undefined reference to `%s', perhaps a declaration mixup?"
+msgstr "%Bã€ã‚»ã‚¯ã‚·ãƒ§ãƒ³ %A: å†é…ç½® %s ã«ã¯æœªå®šç¾©ã® `%s' ã¸ã®å‚ç…§ãŒã‚ã‚Šã¾ã™ã€‚ãŠãらã宣言ãŒæ··ä¹±ã—ã¦ã„ã¾ã™ã€‚"
+
+#: elf32-cris.c:1998
+msgid "%B, section %A: relocation %s is not allowed for symbol: `%s' which is defined outside the program, perhaps a declaration mixup?"
+msgstr "%Bã€ã‚»ã‚¯ã‚·ãƒ§ãƒ³ %A: å†é…ç½® %s ã¯ã‚·ãƒ³ãƒœãƒ«ç”¨ã¨ã—ã¦ã¯è¨±å¯ã•ã‚Œã¦ã„ã¾ã›ã‚“: `%s' ã¯ãƒ—ログラム外ã§å®šç¾©ã•ã‚Œã¦ã„ã¾ã™ã€‚ãŠãらã宣言ãŒæ··ä¹±ã—ã¦ã„ã¾ã™ã€‚"
+
+#: elf32-cris.c:2051
+msgid "(too many global variables for -fpic: recompile with -fPIC)"
+msgstr "(-fpic ã«å¯¾ã™ã‚‹å¤§åŸŸå¤‰æ•°ãŒå¤šã™ãŽã¾ã™: -fPIC を付ã‘ã¦å†ã‚³ãƒ³ãƒ‘イルをã—ã¦ãã ã•ã„)"
+
+#: elf32-cris.c:2058
+msgid "(thread-local data too big for -fpic or -msmall-tls: recompile with -fPIC or -mno-small-tls)"
+msgstr "(-fpic ã¾ãŸã¯ -msmall-tls ã«å¯¾ã™ã‚‹ã‚¹ãƒ¬ãƒƒãƒ‰å±€æ‰€ãƒ‡ãƒ¼ã‚¿ãŒå¤§ãã™ãŽã¾ã™: -fPIC ã¾ãŸã¯ -mno-small-tls を付ã‘ã¦å†ã‚³ãƒ³ãƒ‘イルã—ã¦ãã ã•ã„)"
+
+#: elf32-cris.c:3248
+msgid ""
+"%B, section %A:\n"
+" v10/v32 compatible object %s must not contain a PIC relocation"
+msgstr ""
+"%Bã€ã‚»ã‚¯ã‚·ãƒ§ãƒ³ %A:\n"
+" v10/v32 互æ›ã‚ªãƒ–ジェクト %s 㯠PIC å†é…置をå«ã‚“ã§ã„ã¦ã¯ã„ã‘ã¾ã›ã‚“"
+
+#: elf32-cris.c:3353
+msgid ""
+"%B, section %A:\n"
+" relocation %s not valid in a shared object; typically an option mixup, recompile with -fPIC"
+msgstr ""
+"%Bã€ã‚»ã‚¯ã‚·ãƒ§ãƒ³ %A:\n"
+" å†é…ç½® %s ã¯å…±æœ‰ã‚ªãƒ–ジェクト内ã§ã¯ç„¡åŠ¹ã§ã™ã€‚通常ã¯ã‚ªãƒ—ションãŒæ··ä¹±ã—ã¦ã„ã¾ã™ã€‚-fPIC を付ã‘ã¦å†ã‚³ãƒ³ãƒ‘イルã—ã¦ãã ã•ã„"
+
+#: elf32-cris.c:3567
+msgid ""
+"%B, section %A:\n"
+" relocation %s should not be used in a shared object; recompile with -fPIC"
+msgstr ""
+"%Bã€ã‚»ã‚¯ã‚·ãƒ§ãƒ³ %A:\n"
+" å†é…ç½® %s ã¯å…±æœ‰ã‚ªãƒ–ジェクト内ã§ä½¿ç”¨ã™ã¹ãã§ã¯ã‚ã‚Šã¾ã›ã‚“。-fPIC を付ã‘ã¦å†ã‚³ãƒ³ãƒ‘イルã—ã¦ãã ã•ã„"
+
+#: elf32-cris.c:3992
+msgid ""
+"%B, section `%A', to symbol `%s':\n"
+" relocation %s should not be used in a shared object; recompile with -fPIC"
+msgstr ""
+"%Bã€ã‚»ã‚¯ã‚·ãƒ§ãƒ³ `%A'ã€ã‚·ãƒ³ãƒœãƒ« `%s' ã«é–¢ã—ã¦:\n"
+" å†é…ç½® %s ã¯å…±æœ‰ã‚ªãƒ–ジェクト内ã§ä½¿ç”¨ã™ã¹ãã§ã¯ã‚ã‚Šã¾ã›ã‚“。-fPIC を付ã‘ã¦å†ã‚³ãƒ³ãƒ‘イルã—ã¦ãã ã•ã„"
+
+#: elf32-cris.c:4111
+msgid "Unexpected machine number"
+msgstr "予期ã—ãªã„マシン番å·ã§ã™"
+
+#: elf32-cris.c:4165
+#, c-format
+msgid " [symbols have a _ prefix]"
+msgstr " [ _ 接頭辞ã¤ãシンボル]"
+
+#: elf32-cris.c:4168
+#, c-format
+msgid " [v10 and v32]"
+msgstr " [v10 ãŠã‚ˆã³ v32]"
+
+#: elf32-cris.c:4171
+#, c-format
+msgid " [v32]"
+msgstr " [v32]"
+
+#: elf32-cris.c:4216
+msgid "%B: uses _-prefixed symbols, but writing file with non-prefixed symbols"
+msgstr "%B: _ 接頭辞付ãシンボルを使用ã—ã¦ã„ã¾ã™ãŒã€ãƒ•ã‚¡ã‚¤ãƒ«ã«ã¯ _ 接頭辞無ã—シンボルã¨ã—ã¦æ›¸ãè¾¼ã¿ã¾ã™"
+
+#: elf32-cris.c:4217
+msgid "%B: uses non-prefixed symbols, but writing file with _-prefixed symbols"
+msgstr "%B: _ 接頭辞無ã—シンボルを使用ã—ã¦ã„ã¾ã™ãŒã€ãƒ•ã‚¡ã‚¤ãƒ«ã«ã¯ _ 接頭辞付ãシンボルã¨ã—ã¦æ›¸ãè¾¼ã¿ã¾ã™"
+
+#: elf32-cris.c:4236
+msgid "%B contains CRIS v32 code, incompatible with previous objects"
+msgstr "%B ã«ã¯ CRIS v32 コードãŒå«ã¾ã‚Œã¦ã„ã¾ã™ã€‚ã“ã‚Œã¯å‰ã®ã‚ªãƒ–ジェクトã¨äº’æ›æ€§ãŒã‚ã‚Šã¾ã›ã‚“"
+
+#: elf32-cris.c:4238
+msgid "%B contains non-CRIS-v32 code, incompatible with previous objects"
+msgstr "%B ã«ã¯éž-CRIS-v32 コードãŒå«ã¾ã‚Œã¦ã„ã¾ã™ã€‚ã“ã‚Œã¯å‰ã®ã‚ªãƒ–ジェクトã¨äº’æ›æ€§ãŒã‚ã‚Šã¾ã›ã‚“"
+
+#: elf32-dlx.c:142
+#, c-format
+msgid "BFD Link Error: branch (PC rel16) to section (%s) not supported"
+msgstr "BFD リンクエラー: セクション (%s) ã¸ã®åˆ†å² (PC rel16) ã¯ã‚µãƒãƒ¼ãƒˆã•ã‚Œã¦ã„ã¾ã›ã‚“"
+
+#: elf32-dlx.c:204
+#, c-format
+msgid "BFD Link Error: jump (PC rel26) to section (%s) not supported"
+msgstr "BFD リンクエラー: セクション (%s) ã¸ã®ã‚¸ãƒ£ãƒ³ãƒ— (PC rel26) ã¯ã‚µãƒãƒ¼ãƒˆã•ã‚Œã¦ã„ã¾ã›ã‚“"
+
+#: elf32-frv.c:1509 elf32-frv.c:1658
+msgid "relocation requires zero addend"
+msgstr ""
+
+#: elf32-frv.c:2888
+msgid "%H: relocation to `%s+%v' may have caused the error above\n"
+msgstr "%H: `%s+%v' ã¸ã®å†é…ç½®ãŒä¸Šã®ã‚¨ãƒ©ãƒ¼ã®åŽŸå› ã‹ã‚‚ã—ã‚Œã¾ã›ã‚“\n"
+
+#: elf32-frv.c:2902
+msgid "%H: relocation references symbol not defined in the module\n"
+msgstr "%H: å†é…ç½®ãŒãƒ¢ã‚¸ãƒ¥ãƒ¼ãƒ«å†…ã§å®šç¾©ã•ã‚Œã¦ã„ãªã„シンボルをå‚ç…§ã—ã¦ã„ã¾ã™\n"
+
+#: elf32-frv.c:2978
+msgid "%H: R_FRV_GETTLSOFF not applied to a call instruction\n"
+msgstr "%H: R_FRV_GETTLSOFF 㯠call 命令ã«ã¯é©ç”¨ã•ã‚Œã¾ã›ã‚“\n"
+
+#: elf32-frv.c:3019
+msgid "%H: R_FRV_GOTTLSDESC12 not applied to an lddi instruction\n"
+msgstr "%H: R_FRV_GOTTLSDESC12 㯠lddi 命令ã«ã¯é©ç”¨ã•ã‚Œã¾ã›ã‚“\n"
+
+#: elf32-frv.c:3090
+msgid "%H: R_FRV_GOTTLSDESCHI not applied to a sethi instruction\n"
+msgstr "%H: R_FRV_GOTTLSDESCHI 㯠sethi 命令ã«ã¯é©ç”¨ã•ã‚Œã¾ã›ã‚“\n"
+
+#: elf32-frv.c:3127
+msgid "%H: R_FRV_GOTTLSDESCLO not applied to a setlo or setlos instruction\n"
+msgstr "%H: R_FRV_GOTTLSDESCLO 㯠setlo ã¾ãŸã¯ setlos 命令ã«ã¯é©ç”¨ã•ã‚Œã¾ã›ã‚“\n"
+
+#: elf32-frv.c:3174
+msgid "%H: R_FRV_TLSDESC_RELAX not applied to an ldd instruction\n"
+msgstr "%H: R_FRV_TLSDESC_RELAX 㯠ldd 命令ã«ã¯é©ç”¨ã•ã‚Œã¾ã›ã‚“\n"
+
+#: elf32-frv.c:3258
+msgid "%H: R_FRV_GETTLSOFF_RELAX not applied to a calll instruction\n"
+msgstr "%H: R_FRV_GETTLSOFF_RELAX 㯠calll 命令ã«ã¯é©ç”¨ã•ã‚Œã¾ã›ã‚“\n"
+
+#: elf32-frv.c:3312
+msgid "%H: R_FRV_GOTTLSOFF12 not applied to an ldi instruction\n"
+msgstr "%H: R_FRV_GOTTLSOFF12 㯠ldi 命令ã«ã¯é©ç”¨ã•ã‚Œã¾ã›ã‚“\n"
+
+#: elf32-frv.c:3342
+msgid "%H: R_FRV_GOTTLSOFFHI not applied to a sethi instruction\n"
+msgstr "%H: R_FRV_GOTTLSOFFHI 㯠sethi 命令ã«ã¯é©ç”¨ã•ã‚Œã¾ã›ã‚“\n"
+
+#: elf32-frv.c:3371
+msgid "%H: R_FRV_GOTTLSOFFLO not applied to a setlo or setlos instruction\n"
+msgstr "%H: R_FRV_GOTTLSOFFLO 㯠setlo ã¾ãŸã¯ setlos 命令ã«ã¯é©ç”¨ã•ã‚Œã¾ã›ã‚“\n"
+
+#: elf32-frv.c:3401
+msgid "%H: R_FRV_TLSOFF_RELAX not applied to an ld instruction\n"
+msgstr "%H: R_FRV_TLSOFF_RELAX 㯠ld 命令ã«ã¯é©ç”¨ã•ã‚Œã¾ã›ã‚“\n"
+
+#: elf32-frv.c:3446
+msgid "%H: R_FRV_TLSMOFFHI not applied to a sethi instruction\n"
+msgstr "%H: R_FRV_TLSMOFFHI 㯠sethi 命令ã«ã¯é©ç”¨ã•ã‚Œã¾ã›ã‚“\n"
+
+#: elf32-frv.c:3473
+msgid "R_FRV_TLSMOFFLO not applied to a setlo or setlos instruction\n"
+msgstr "R_FRV_TLSMOFFLO 㯠setlo ã¾ãŸã¯ setlos 命令ã«ã¯é©ç”¨ã•ã‚Œã¾ã›ã‚“\n"
+
+#: elf32-frv.c:3594
+msgid "%H: R_FRV_FUNCDESC references dynamic symbol with nonzero addend\n"
+msgstr ""
+
+#: elf32-frv.c:3635 elf32-frv.c:3757
+msgid "%H: cannot emit fixups in read-only section\n"
+msgstr "%H: 読ã¿è¾¼ã¿å°‚用セクション内ã§ä¿®æ­£ã‚’è¡Œã†ã“ã¨ãŒã§ãã¾ã›ã‚“\n"
+
+#: elf32-frv.c:3666 elf32-frv.c:3800
+msgid "%H: cannot emit dynamic relocations in read-only section\n"
+msgstr "%H: 読ã¿è¾¼ã¿å°‚用セクション内ã§å‹•çš„å†é…置を行ã†ã“ã¨ãŒã§ãã¾ã›ã‚“\n"
+
+#: elf32-frv.c:3715
+msgid "%H: R_FRV_FUNCDESC_VALUE references dynamic symbol with nonzero addend\n"
+msgstr ""
+
+#: elf32-frv.c:3971
+msgid "%H: reloc against `%s' references a different segment\n"
+msgstr "%H: `%s' ã¸ã®å†é…ç½®ãŒç•°ãªã‚‹ã‚»ã‚°ãƒ¡ãƒ³ãƒˆã‚’å‚ç…§ã—ã¦ã„ã¾ã™\n"
+
+#: elf32-frv.c:4121
+msgid "%H: reloc against `%s': %s\n"
+msgstr "%H: `%s' ã«å¯¾ã™ã‚‹å†é…ç½®: %s\n"
+
+#: elf32-frv.c:6397
+msgid "%B: unsupported relocation type %i\n"
+msgstr "%B: サãƒãƒ¼ãƒˆã•ã‚Œã¦ã„ãªã„å†é…置型 %i ã§ã™\n"
+
+#: elf32-frv.c:6719
+#, c-format
+msgid "%s: compiled with %s and linked with modules that use non-pic relocations"
+msgstr "%s: %s 付ãã§ã‚³ãƒ³ãƒ‘イルã•ã‚Œã¦ã„ã¾ã™ãŒã€éž pic å†é…置を使用ã™ã‚‹ãƒ¢ã‚¸ãƒ¥ãƒ¼ãƒ«ã¨ãƒªãƒ³ã‚¯ã—ã¦ã„ã¾ã™"
+
+#: elf32-frv.c:6772 elf32-iq2000.c:845 elf32-m32c.c:807
+#, c-format
+msgid "%s: compiled with %s and linked with modules compiled with %s"
+msgstr "%s: %s 付ãã§ã‚³ãƒ³ãƒ‘イルã•ã‚Œã¦ã„ã¾ã™ãŒã€ %s 付ãã§ã‚³ãƒ³ãƒ‘イルã—ãŸãƒ¢ã‚¸ãƒ¥ãƒ¼ãƒ«ã¨ãƒªãƒ³ã‚¯ã—ã¦ã„ã¾ã™"
+
+#: elf32-frv.c:6784
+#, c-format
+msgid "%s: uses different unknown e_flags (0x%lx) fields than previous modules (0x%lx)"
+msgstr "%s: ä¸æ˜Žãª e_flags (0x%lx) フィールドを使用ã—ã¦ã„ã¾ã™ã€‚ã“ã‚Œã¯å‰ã®ãƒ¢ã‚¸ãƒ¥ãƒ¼ãƒ«ã¨ç•°ãªã‚‹ãƒ•ã‚£ãƒ¼ãƒ«ãƒ‰ (0x%lx) ã§ã™"
+
+#: elf32-frv.c:6834 elf32-iq2000.c:882 elf32-m32c.c:843 elf32-mt.c:576
+#: elf32-rx.c:2937
+#, c-format
+msgid "private flags = 0x%lx:"
+msgstr "private フラグ = 0x%lx:"
+
+#: elf32-gen.c:69 elf64-gen.c:69
+msgid "%B: Relocations in generic ELF (EM: %d)"
+msgstr "%B: 一般的㪠ELF 内ã®å†é…ç½® (EM: %d)"
+
+#: elf32-hppa.c:850 elf32-hppa.c:3610
+msgid "%B(%A+0x%lx): cannot reach %s, recompile with -ffunction-sections"
+msgstr "%B(%A+0x%lx): %s ã«å±Šãã¾ã›ã‚“。-ffunction-sections を付ã‘ã¦å†ã‚³ãƒ³ãƒ‘イルã—ã¦ãã ã•ã„"
+
+#: elf32-hppa.c:1284
+msgid "%B: relocation %s can not be used when making a shared object; recompile with -fPIC"
+msgstr "%B: å†é…ç½® %s ã¯å…±æœ‰ã‚ªãƒ–ジェクトを作æˆã™ã‚‹ã¨ãã«ã¯ä½¿ãˆã¾ã›ã‚“。-fPIC を付ã‘ã¦å†ã‚³ãƒ³ãƒ‘イルã—ã¦ãã ã•ã„"
+
+#: elf32-hppa.c:2803
+msgid "%B: duplicate export stub %s"
+msgstr "%B: export スタブ %s ãŒé‡è¤‡ã—ã¦ã„ã¾ã™"
+
+#: elf32-hppa.c:3449
+msgid "%B(%A+0x%lx): %s fixup for insn 0x%x is not supported in a non-shared link"
+msgstr "%B(%A+0x%lx): %s 修正 (命令 0x%x 用) ã¯éžå…±æœ‰ãƒªãƒ³ã‚¯ã§ã¯ã‚µãƒãƒ¼ãƒˆã•ã‚Œã¦ã„ã¾ã›ã‚“"
+
+#: elf32-hppa.c:4296
+msgid "%B(%A+0x%lx): cannot handle %s for %s"
+msgstr "%B(%A+0x%lx): %s (%s) ã‚’å–り扱ãˆã¾ã›ã‚“"
+
+#: elf32-hppa.c:4608
+msgid ".got section not immediately after .plt section"
+msgstr ".got セクション㌠.plt セクションã®ç›´å¾Œã«ã‚ã‚Šã¾ã›ã‚“"
+
+#. Unknown relocation.
+#: elf32-i386.c:372 elf32-m68k.c:383 elf32-ppc.c:1675 elf32-s390.c:379
+#: elf32-tic6x.c:2682 elf64-ppc.c:2285 elf64-s390.c:403 elf64-x86-64.c:243
+msgid "%B: invalid relocation type %d"
+msgstr "%B: 無効ãªå†é…置型 %d ã§ã™"
+
+#: elf32-i386.c:1266 elf64-x86-64.c:1116
+msgid "%B: TLS transition from %s to %s against `%s' at 0x%lx in section `%A' failed"
+msgstr "%B: %s ã‹ã‚‰ %s ã¸ã®TLS 移行 (`%s' ã«å¯¾ã™ã‚‹ã€ä½ç½® 0x%lxã€ã‚»ã‚¯ã‚·ãƒ§ãƒ³ `%A' 内) ã«å¤±æ•—ã—ã¾ã—ãŸ"
+
+#: elf32-i386.c:1411 elf32-i386.c:3090 elf64-x86-64.c:1296 elf64-x86-64.c:2909
+#: elfxx-sparc.c:3077
+msgid "%B: relocation %s against STT_GNU_IFUNC symbol `%s' isn't handled by %s"
+msgstr "%B: å†é…ç½® %s (STT_GNU_IFUNC シンボル `%s' ã«å¯¾ã™ã‚‹) 㯠%s ã«ã‚ˆã£ã¦å–り扱ã‚ã‚Œã¾ã›ã‚“"
+
+#: elf32-i386.c:1573 elf32-s390.c:1182 elf32-sh.c:6367 elf32-xtensa.c:1182
+#: elf64-s390.c:1151 elfxx-sparc.c:1547
+msgid "%B: `%s' accessed both as normal and thread local symbol"
+msgstr "%B: `%s' ãŒé€šå¸¸ã®ã‚·ãƒ³ãƒœãƒ«ã¨ã‚¹ãƒ¬ãƒƒãƒ‰å±€æ‰€ã‚·ãƒ³ãƒœãƒ«ã«ã‚¢ã‚¯ã‚»ã‚¹ã—ã¾ã—ãŸ"
+
+#: elf32-i386.c:2405 elf64-x86-64.c:2320
+msgid "%P: %B: warning: relocation against `%s' in readonly section `%A'.\n"
+msgstr "%P: %B: 警告: `%s' ã«å¯¾ã™ã‚‹å†é…ç½® (読ã¿å–り専用セクション `%A' ã‹ã‚‰) ã§ã™ã€‚\n"
+
+#: elf32-i386.c:2496 elf64-x86-64.c:2407
+msgid "%P: %B: warning: relocation in readonly section `%A'.\n"
+msgstr "%P: %B: 警告: 読ã¿å–り専用セクション `%A' ã«ã‚ã‚‹å†é…ç½®ã§ã™ã€‚\n"
+
+#: elf32-i386.c:2932
+msgid "%B: unrecognized relocation (0x%x) in section `%A'"
+msgstr "%B: èªè­˜ã§ããªã„å†é…ç½® (0x%x) ãŒã‚»ã‚¯ã‚·ãƒ§ãƒ³ `%A' ã«ã‚ã‚Šã¾ã™"
+
+#: elf32-i386.c:3339 elf64-x86-64.c:3295
+msgid "hidden symbol"
+msgstr "éš ã•ã‚ŒãŸã‚·ãƒ³ãƒœãƒ«"
+
+#: elf32-i386.c:3342 elf64-x86-64.c:3298
+msgid "internal symbol"
+msgstr "内部シンボル"
+
+#: elf32-i386.c:3345 elf64-x86-64.c:3301
+msgid "protected symbol"
+msgstr "ä¿è­·ã•ã‚ŒãŸã‚·ãƒ³ãƒœãƒ«"
+
+#: elf32-i386.c:3348 elf64-x86-64.c:3304
+msgid "symbol"
+msgstr "シンボル"
+
+#: elf32-i386.c:3353
+msgid "%B: relocation R_386_GOTOFF against undefined %s `%s' can not be used when making a shared object"
+msgstr "%B: 未定義ã®%s `%s' ã«å¯¾ã™ã‚‹å†é…ç½® R_386_GOTOFF ã¯å…±æœ‰ã‚ªãƒ–ジェクト作æˆæ™‚ã«ã¯ä½¿ç”¨ã§ãã¾ã›ã‚“"
+
+#: elf32-i386.c:3363
+msgid "%B: relocation R_386_GOTOFF against protected function `%s' can not be used when making a shared object"
+msgstr "%B: 未定義ã®ä¿è­·ã•ã‚ŒãŸé–¢æ•° `%s' ã«å¯¾ã™ã‚‹å†é…ç½® R_386_GOTOFF ã¯å…±æœ‰ã‚ªãƒ–ジェクト作æˆæ™‚ã«ã¯ä½¿ç”¨ã§ãã¾ã›ã‚“"
+
+#: elf32-i386.c:4660 elf64-x86-64.c:4378
+#, c-format
+msgid "discarded output section: `%A'"
+msgstr "破棄ã•ã‚ŒãŸå‡ºåŠ›ã‚»ã‚¯ã‚·ãƒ§ãƒ³: `%A'"
+
+#: elf32-ip2k.c:857 elf32-ip2k.c:863 elf32-ip2k.c:930 elf32-ip2k.c:936
+msgid "ip2k relaxer: switch table without complete matching relocation information."
+msgstr "ip2k relaxer: 完全ã«ä¸€è‡´ã™ã‚‹å†é…置情報ãŒç„¡ã„ switch 表ã§ã™ã€‚"
+
+#: elf32-ip2k.c:880 elf32-ip2k.c:963
+msgid "ip2k relaxer: switch table header corrupt."
+msgstr "ip2k relaxer: switch 表ヘッダãŒç ´æã—ã¦ã„ã¾ã™ã€‚"
+
+#: elf32-ip2k.c:1292
+#, c-format
+msgid "ip2k linker: missing page instruction at 0x%08lx (dest = 0x%08lx)."
+msgstr ""
+
+#: elf32-ip2k.c:1308
+#, c-format
+msgid "ip2k linker: redundant page instruction at 0x%08lx (dest = 0x%08lx)."
+msgstr ""
+
+#. Only if it's not an unresolved symbol.
+#: elf32-ip2k.c:1475
+msgid "unsupported relocation between data/insn address spaces"
+msgstr "データアドレス空間ã¨å‘½ä»¤ã‚¢ãƒ‰ãƒ¬ã‚¹ç©ºé–“ã®é–“ã®å†é…ç½®ã¯ã‚µãƒãƒ¼ãƒˆã•ã‚Œã¦ã„ã¾ã›ã‚“"
+
+#: elf32-iq2000.c:858 elf32-m32c.c:819
+#, c-format
+msgid "%s: uses different e_flags (0x%lx) fields than previous modules (0x%lx)"
+msgstr "%s: 使用ã—ã¦ã„ã‚‹ e_flags(0x%lx) ãŒä»¥å‰ã®ãƒ¢ã‚¸ãƒ¥ãƒ¼ãƒ« (0x%lx) ã¨ç•°ãªã£ã¦ã„ã¾ã™"
+
+#: elf32-lm32.c:706
+msgid "global pointer relative relocation when _gp not defined"
+msgstr "_gp ãŒæœªå®šç¾©ã®æ™‚ã«å¤§åŸŸãƒã‚¤ãƒ³ã‚¿é–¢é€£å†é…ç½®ãŒã‚ã‚Šã¾ã™"
+
+#: elf32-lm32.c:761
+msgid "global pointer relative address out of range"
+msgstr "大域ãƒã‚¤ãƒ³ã‚¿é–¢é€£ã‚¢ãƒ‰ãƒ¬ã‚¹ãŒç¯„囲外ã§ã™"
+
+#: elf32-lm32.c:1057
+msgid "internal error: addend should be zero for R_LM32_16_GOT"
+msgstr ""
+
+#: elf32-m32r.c:1453
+msgid "SDA relocation when _SDA_BASE_ not defined"
+msgstr "_SDA_BASE_ ãŒæœªå®šç¾©ã®æ™‚点ã§ã® SDA å†é…ç½®ã§ã™"
+
+#: elf32-m32r.c:3048
+msgid "%B: The target (%s) of an %s relocation is in the wrong section (%A)"
+msgstr "%B: ターゲット %s (%s å†é…ç½®ã®) ãŒé–“é•ã£ãŸã‚»ã‚¯ã‚·ãƒ§ãƒ³ (%A) 内ã«ã‚ã‚Šã¾ã™"
+
+#: elf32-m32r.c:3576
+msgid "%B: Instruction set mismatch with previous modules"
+msgstr "%B: 命令セットãŒä»¥å‰ã®ãƒ¢ã‚¸ãƒ¥ãƒ¼ãƒ«ã¨é©åˆã—ã¾ã›ã‚“"
+
+#: elf32-m32r.c:3597
+#, c-format
+msgid "private flags = %lx"
+msgstr "private フラグ = %lx"
+
+#: elf32-m32r.c:3602
+#, c-format
+msgid ": m32r instructions"
+msgstr ": m32r 命令"
+
+#: elf32-m32r.c:3603
+#, c-format
+msgid ": m32rx instructions"
+msgstr ": m32rx 命令"
+
+#: elf32-m32r.c:3604
+#, c-format
+msgid ": m32r2 instructions"
+msgstr ": m32r2 命令"
+
+#: elf32-m68hc1x.c:1050
+#, c-format
+msgid "Reference to the far symbol `%s' using a wrong relocation may result in incorrect execution"
+msgstr "é–“é•ã£ãŸå†é…置を利用ã—ãŸé ã„シンボル `%s' ã¸ã®å‚ç…§ã¯æ­£ã—ããªã„実行çµæžœã«ãªã‚‹ã‹ã‚‚ã—ã‚Œã¾ã›ã‚“"
+
+#: elf32-m68hc1x.c:1073
+#, c-format
+msgid "banked address [%lx:%04lx] (%lx) is not in the same bank as current banked address [%lx:%04lx] (%lx)"
+msgstr ""
+
+#: elf32-m68hc1x.c:1092
+#, c-format
+msgid "reference to a banked address [%lx:%04lx] in the normal address space at %04lx"
+msgstr ""
+
+#: elf32-m68hc1x.c:1225
+msgid "%B: linking files compiled for 16-bit integers (-mshort) and others for 32-bit integers"
+msgstr "%B: リンク中ã®ãƒ•ã‚¡ã‚¤ãƒ«ã¯ 16 ビット整数用 (-mshort) ã«ã‚³ãƒ³ãƒ‘イルã•ã‚Œã¾ã—ãŸãŒã€ä»–ã®ã‚‚ã®ã¯ 32 ビット整数用ã§ã™"
+
+#: elf32-m68hc1x.c:1232
+msgid "%B: linking files compiled for 32-bit double (-fshort-double) and others for 64-bit double"
+msgstr "%B: リンク中ã®ãƒ•ã‚¡ã‚¤ãƒ«ã¯ 32 ビットå€ç²¾åº¦æµ®å‹•å°æ•°ç”¨ (-fshort-double) ã«ã‚³ãƒ³ãƒ‘イルã•ã‚Œã¾ã—ãŸãŒã€ä»–ã®ã‚‚ã®ã¯ 64 ビットå€ç²¾åº¦æµ®å‹•å°æ•°ç”¨ã§ã™"
+
+#: elf32-m68hc1x.c:1241
+msgid "%B: linking files compiled for HCS12 with others compiled for HC12"
+msgstr "%B: リンク中ã®ãƒ•ã‚¡ã‚¤ãƒ«ã¯ HCS12 用ã«ã‚³ãƒ³ãƒ‘イルã•ã‚Œã¾ã—ãŸãŒã€ä»–ã®ã‚‚ã®ã¯ HC12 用ã§ã™"
+
+#: elf32-m68hc1x.c:1257 elf32-ppc.c:4214 elf64-sparc.c:705 elfxx-mips.c:12719
+msgid "%B: uses different e_flags (0x%lx) fields than previous modules (0x%lx)"
+msgstr "%B: 使用ã—ã¦ã„ã‚‹ e_flags (0x%lx) ãŒå‰ã®ãƒ¢ã‚¸ãƒ¥ãƒ¼ãƒ« (0x%lx) ã¨ç•°ãªã‚Šã¾ã™"
+
+#: elf32-m68hc1x.c:1285
+#, c-format
+msgid "[abi=32-bit int, "
+msgstr "[abi=32-ビット整数, "
+
+#: elf32-m68hc1x.c:1287
+#, c-format
+msgid "[abi=16-bit int, "
+msgstr "[abi=16-ビット整数, "
+
+#: elf32-m68hc1x.c:1290
+#, c-format
+msgid "64-bit double, "
+msgstr "64-ビットå€ç²¾åº¦æµ®å‹•å°æ•°, "
+
+#: elf32-m68hc1x.c:1292
+#, c-format
+msgid "32-bit double, "
+msgstr "32-ビットå€ç²¾åº¦æµ®å‹•å°æ•°, "
+
+#: elf32-m68hc1x.c:1295
+#, c-format
+msgid "cpu=HC11]"
+msgstr "cpu=HC11]"
+
+#: elf32-m68hc1x.c:1297
+#, c-format
+msgid "cpu=HCS12]"
+msgstr "cpu=HCS12]"
+
+#: elf32-m68hc1x.c:1299
+#, c-format
+msgid "cpu=HC12]"
+msgstr "cpu=HC12]"
+
+#: elf32-m68hc1x.c:1302
+#, c-format
+msgid " [memory=bank-model]"
+msgstr " [memory=bank-model]"
+
+#: elf32-m68hc1x.c:1304
+#, c-format
+msgid " [memory=flat]"
+msgstr " [memory=flat]"
+
+#: elf32-m68k.c:1250 elf32-m68k.c:1251 vms-alpha.c:7311 vms-alpha.c:7326
+msgid "unknown"
+msgstr "ä¸æ˜Ž"
+
+#: elf32-m68k.c:1714
+msgid "%B: GOT overflow: Number of relocations with 8-bit offset > %d"
+msgstr "%B: GOT オーãƒãƒ¼ãƒ•ãƒ­ãƒ¼: 8ビットオフセットをæŒã¤å†é…ç½®ã®æ•°ãŒ %d より大ãã„ã§ã™"
+
+#: elf32-m68k.c:1720
+msgid "%B: GOT overflow: Number of relocations with 8- or 16-bit offset > %d"
+msgstr "%B: GOT オーãƒãƒ¼ãƒ•ãƒ­ãƒ¼: 8 ビットã¾ãŸã¯ 16 ビットオフセットをæŒã¤å†é…ç½®ã®æ•°ãŒ > %d より大ãã„ã§ã™"
+
+#: elf32-m68k.c:3959
+msgid "%B(%A+0x%lx): R_68K_TLS_LE32 relocation not permitted in shared object"
+msgstr "%B(%A+0x%lx): R_68K_TLS_LE32 å†é…ç½®ã¯å…±æœ‰ã‚ªãƒ–ジェクト内ã§ã¯è¨±å¯ã•ã‚Œã¦ã„ã¾ã›ã‚“"
+
+#: elf32-mcore.c:99 elf32-mcore.c:442
+msgid "%B: Relocation %s (%d) is not currently supported.\n"
+msgstr "%B: å†é…ç½® %s (%d) ã¯ç¾åœ¨ã®ã¨ã“ã‚サãƒãƒ¼ãƒˆã•ã‚Œã¦ã„ã¾ã›ã‚“。\n"
+
+#: elf32-mcore.c:428
+msgid "%B: Unknown relocation type %d\n"
+msgstr "%B: ä¸æ˜Žãªå†é…置型 %d ã§ã™\n"
+
+#. Pacify gcc -Wall.
+#: elf32-mep.c:157
+#, c-format
+msgid "mep: no reloc for code %d"
+msgstr "mep: コード %d 用ã®å†é…ç½®ãŒã‚ã‚Šã¾ã›ã‚“"
+
+#: elf32-mep.c:163
+#, c-format
+msgid "MeP: howto %d has type %d"
+msgstr ""
+
+#: elf32-mep.c:648
+msgid "%B and %B are for different cores"
+msgstr "%B ãŠã‚ˆã³ %B ã¯ç•°ãªã‚‹ã‚³ã‚¢ã«å¯¾ã™ã‚‹ã‚‚ã®ã§ã™"
+
+#: elf32-mep.c:665
+msgid "%B and %B are for different configurations"
+msgstr "%B ãŠã‚ˆã³ %B ã¯ç•°ãªã‚‹è¨­å®šã«å¯¾ã™ã‚‹ã‚‚ã®ã§ã™"
+
+#: elf32-mep.c:702
+#, c-format
+msgid "private flags = 0x%lx"
+msgstr "private フラグ = 0x%lx"
+
+#: elf32-microblaze.c:742
+#, c-format
+msgid "%s: unknown relocation type %d"
+msgstr "%s: å†é…置型 %d ãŒä¸æ˜Žã§ã™"
+
+#: elf32-microblaze.c:867 elf32-microblaze.c:912
+#, c-format
+msgid "%s: The target (%s) of an %s relocation is in the wrong section (%s)"
+msgstr "%s: ターゲット (%s, %s å†é…ç½®) ãŒé–“é•ã£ãŸã‚»ã‚¯ã‚·ãƒ§ãƒ³ (%s) 内ã«ã‚ã‚Šã¾ã™"
+
+#: elf32-microblaze.c:1155 elfxx-sparc.c:3451
+msgid "%B: probably compiled without -fPIC?"
+msgstr "%B: æらã -fPIC を付ã‘ãšã«ã‚³ãƒ³ãƒ‘イルã—ãŸã®ã§ã¯?"
+
+#: elf32-microblaze.c:2074
+msgid "%B: bad relocation section name `%s'"
+msgstr "%B: 誤ã£ãŸå†é…置セクションå `%s' ã§ã™"
+
+#: elf32-mips.c:1045 elf64-mips.c:2084 elfn32-mips.c:1888
+msgid "literal relocation occurs for an external symbol"
+msgstr "リテラルå†é…ç½®ãŒå¤–部シンボル用ã«ç™ºç”Ÿã—ã¾ã—ãŸ"
+
+#: elf32-mips.c:1085 elf32-score.c:569 elf32-score7.c:469 elf64-mips.c:2127
+#: elfn32-mips.c:1929
+msgid "32bits gp relative relocation occurs for an external symbol"
+msgstr "32ビット gp 関連å†é…ç½®ãŒå¤–部シンボル用ã«ç™ºç”Ÿã—ã¾ã—ãŸ"
+
+#: elf32-ppc.c:1740
+#, c-format
+msgid "generic linker can't handle %s"
+msgstr "一般的リンカ㯠%s を扱ãˆã¾ã›ã‚“"
+
+#: elf32-ppc.c:2183
+msgid "corrupt %s section in %B"
+msgstr "%s セクション (%B 内) ãŒç ´æã—ã¦ã„ã¾ã™"
+
+#: elf32-ppc.c:2202
+msgid "unable to read in %s section from %B"
+msgstr "%s セクションを %B ã‹ã‚‰èª­ã¿è¾¼ã‚ã¾ã›ã‚“"
+
+#: elf32-ppc.c:2243
+msgid "warning: unable to set size of %s section in %B"
+msgstr "警告: %s セクション (%B 内) ã®ã‚µã‚¤ã‚ºã‚’設定ã§ãã¾ã›ã‚“"
+
+#: elf32-ppc.c:2293
+msgid "failed to allocate space for new APUinfo section."
+msgstr "æ–°ã—ã„ APUinfo セクション用ã®ç©ºé–“割り当ã¦ã«å¤±æ•—ã—ã¾ã—ãŸ"
+
+#: elf32-ppc.c:2312
+msgid "failed to compute new APUinfo section."
+msgstr "æ–°ã—ã„ APUinfo セクションã®è¨ˆç®—ã«å¤±æ•—ã—ã¾ã—ãŸ"
+
+#: elf32-ppc.c:2315
+msgid "failed to install new APUinfo section."
+msgstr "æ–°ã—ã„ APUinfo セクションã®ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã«å¤±æ•—ã—ã¾ã—ãŸ"
+
+#: elf32-ppc.c:3343
+msgid "%B: relocation %s cannot be used when making a shared object"
+msgstr "%B: å†é…ç½® %s ã¯å…±æœ‰ãƒ©ã‚¤ãƒ–ラリ作æˆæ™‚ã«ã¯ä½¿ç”¨ã§ãã¾ã›ã‚“"
+
+#. It does not make sense to have a procedure linkage
+#. table entry for a local symbol.
+#: elf32-ppc.c:3687
+msgid "%H: %s reloc against local symbol\n"
+msgstr "%H: 局所シンボルã«å¯¾ã™ã‚‹ %s å†é…ç½®ã§ã™\n"
+
+#: elf32-ppc.c:4026 elf32-ppc.c:4041 elfxx-mips.c:12423 elfxx-mips.c:12449
+#: elfxx-mips.c:12471 elfxx-mips.c:12497
+msgid "Warning: %B uses hard float, %B uses soft float"
+msgstr "警告: %B ã¯ãƒãƒ¼ãƒ‰ã‚¦ã‚§ã‚¢æµ®å‹•å°æ•°ã‚’使用ã—ã¦ã„ã¾ã™ã€‚%B ã¯ã‚½ãƒ•ãƒˆã‚¦ã‚§ã‚¢æµ®å‹•å°æ•°ã‚’利用ã—ã¦ã„ã¾ã™"
+
+#: elf32-ppc.c:4029 elf32-ppc.c:4033
+msgid "Warning: %B uses double-precision hard float, %B uses single-precision hard float"
+msgstr "警告: %B ã¯ãƒãƒ¼ãƒ‰ã‚¦ã‚§ã‚¢å€ç²¾åº¦æµ®å‹•å°æ•°ã‚’使用ã—ã¦ã„ã¾ã™ã€‚%B ã¯ãƒãƒ¼ãƒ‰ã‚¦ã‚§ã‚¢å˜ç²¾åº¦æµ®å‹•å°æ•°ã‚’使用ã—ã¦ã„ã¾ã™"
+
+#: elf32-ppc.c:4037
+msgid "Warning: %B uses soft float, %B uses single-precision hard float"
+msgstr "警告: %B ã¯ã‚½ãƒ•ãƒˆã‚¦ã‚§ã‚¢æµ®å‹•å°æ•°ã‚’使用ã—ã¦ã„ã¾ã™ã€‚%B ã¯ãƒãƒ¼ãƒ‰ã‚¦ã‚§ã‚¢å˜ç²¾åº¦æµ®å‹•å°æ•°ã‚’使用ã—ã¦ã„ã¾ã™"
+
+#: elf32-ppc.c:4044 elf32-ppc.c:4048 elfxx-mips.c:12403 elfxx-mips.c:12407
+msgid "Warning: %B uses unknown floating point ABI %d"
+msgstr "警告: %B ã¯ä¸æ˜Žãªæµ®å‹•å°æ•°ç‚¹ ABI %d を使用ã—ã¦ã„ã¾ã™"
+
+#: elf32-ppc.c:4090 elf32-ppc.c:4094
+msgid "Warning: %B uses unknown vector ABI %d"
+msgstr "警告: %B ã¯ä¸æ˜Žãªãƒ™ã‚¯ãƒˆãƒ« ABI %d を使用ã—ã¦ã„ã¾ã™"
+
+#: elf32-ppc.c:4098
+msgid "Warning: %B uses vector ABI \"%s\", %B uses \"%s\""
+msgstr "警告: %B ã¯ãƒ™ã‚¯ãƒˆãƒ« ABI \"%s\" を使用ã—ã¦ã„ã¾ã™ã€‚%B ã¯ãƒ™ã‚¯ãƒˆãƒ« ABI \"%s\" を使用ã—ã¦ã„ã¾ã™"
+
+#: elf32-ppc.c:4115 elf32-ppc.c:4118
+msgid "Warning: %B uses r3/r4 for small structure returns, %B uses memory"
+msgstr "警告: %B ã¯å°ã•ãªæ§‹é€ ä½“ã®æˆ»ã‚Šå€¤ã« r3/r4 を使用ã—ã¦ã„ã¾ã™ã€‚%B ã¯ãƒ¡ãƒ¢ãƒªã‚’使用ã—ã¦ã„ã¾ã™"
+
+#: elf32-ppc.c:4121 elf32-ppc.c:4125
+msgid "Warning: %B uses unknown small structure return convention %d"
+msgstr "警告: %B ã¯ä¸æ˜Žãªå°ã•ãªæ§‹é€ ä½“æˆ»ã‚Šå€¤å¤‰æ› %d を使用ã—ã¦ã„ã¾ã™"
+
+#: elf32-ppc.c:4179
+msgid "%B: compiled with -mrelocatable and linked with modules compiled normally"
+msgstr "%B: -mrelocatable を付ã‘ã¦ã‚³ãƒ³ãƒ‘イルã•ã‚ŒãŸã‚‚ã®ã¨æ™®é€šã«ã‚³ãƒ³ãƒ‘イルã•ã‚ŒãŸãƒ¢ã‚¸ãƒ¥ãƒ¼ãƒ«ã¨ã‚’リンクã—ã¾ã—ãŸ"
+
+#: elf32-ppc.c:4187
+msgid "%B: compiled normally and linked with modules compiled with -mrelocatable"
+msgstr "%B: 普通ã«ã‚³ãƒ³ãƒ‘イルã•ã‚ŒãŸã‚‚ã®ã¨ -mrelocatable を付ã‘ã¦ã‚³ãƒ³ãƒ‘イルã•ã‚ŒãŸãƒ¢ã‚¸ãƒ¥ãƒ¼ãƒ«ã¨ã‚’リンクã—ã¾ã—ãŸ"
+
+#: elf32-ppc.c:4275
+msgid "Using bss-plt due to %B"
+msgstr "%B ã®ãŸã‚ã« bss-plt を使用ã—ã¦ã„ã¾ã™"
+
+#. Uh oh, we didn't find the expected call. We
+#. could just mark this symbol to exclude it
+#. from tls optimization but it's safer to skip
+#. the entire optimization.
+#: elf32-ppc.c:4771 elf64-ppc.c:7778
+msgid "%H arg lost __tls_get_addr, TLS optimization disabled\n"
+msgstr "%H 引数㫠__tls_get_addr ãŒç„¡ããªã‚Šã¾ã—ãŸã€‚TLS 最é©åŒ–ã¯ç„¡åŠ¹ã«ãªã‚Šã¾ã™\n"
+
+#: elf32-ppc.c:5006 elf64-ppc.c:6494
+#, c-format
+msgid "dynamic variable `%s' is zero size\n"
+msgstr "動的変数 `%s' ã®ã‚µã‚¤ã‚ºãŒ 0 ã§ã™\n"
+
+#: elf32-ppc.c:7204 elf64-ppc.c:12431
+msgid "%B: unknown relocation type %d for symbol %s\n"
+msgstr "%B: ä¸æ˜Žãªå†é…置型 %d (シンボル %s 用) ã§ã™\n"
+
+#: elf32-ppc.c:7465
+msgid "%H: non-zero addend on %s reloc against `%s'\n"
+msgstr ""
+
+#: elf32-ppc.c:7661 elf64-ppc.c:12936
+msgid "%H: relocation %s for indirect function %s unsupported\n"
+msgstr "%H: å†é…ç½® %s (間接関数 %s 用) ã¯ã‚µãƒãƒ¼ãƒˆã•ã‚Œã¦ã„ã¾ã›ã‚“\n"
+
+#: elf32-ppc.c:7889 elf32-ppc.c:7919 elf32-ppc.c:7966
+msgid "%B: the target (%s) of a %s relocation is in the wrong output section (%s)\n"
+msgstr "%B: ターゲット (%s) (%s å†é…ç½®ã®) ã¯é–“é•ã£ãŸå‡ºåŠ›ã‚»ã‚¯ã‚·ãƒ§ãƒ³ (%s) 内ã«ã‚ã‚Šã¾ã™\n"
+
+#: elf32-ppc.c:8038
+msgid "%B: relocation %s is not yet supported for symbol %s\n"
+msgstr "%B: å†é…ç½® %s (シンボル %s 用) ã¯ã¾ã ã‚µãƒãƒ¼ãƒˆã•ã‚Œã¦ã„ã¾ã›ã‚“\n"
+
+#: elf32-ppc.c:8097 elf64-ppc.c:13237
+msgid "%H: unresolvable %s relocation against symbol `%s'\n"
+msgstr "%H: 解決ã§ããªã„ %s å†é…ç½® (シンボル `%s' ã«å¯¾ã™ã‚‹) ã§ã™\n"
+
+#: elf32-ppc.c:8144 elf64-ppc.c:13282
+msgid "%H: %s reloc against `%s': error %d\n"
+msgstr "%H: %s å†é…ç½® (`%s' ã«å¯¾ã™ã‚‹): エラー %d\n"
+
+#: elf32-ppc.c:8635
+#, c-format
+msgid "%s not defined in linker created %s\n"
+msgstr "%s ã¯ãƒªãƒ³ã‚«ãŒä½œæˆã—㟠%s 内ã§ã¯å®šç¾©ã•ã‚Œã¦ã„ã¾ã›ã‚“\n"
+
+#: elf32-rx.c:553
+msgid "%B:%A: Warning: deprecated Red Hat reloc "
+msgstr "%B:%A: 警告: 廃止ã•ã‚ŒãŸ Red Hat å†é…ç½®ã§ã™ "
+
+#: elf32-rx.c:1095
+msgid "Warning: RX_SYM reloc with an unknown symbol"
+msgstr "警告: ä¸æ˜Žãªã‚·ãƒ³ãƒœãƒ«ãŒã‚ã‚‹ RX_SYM å†é…ç½®ã§ã™"
+
+#: elf32-rx.c:1260
+msgid "%B(%A): error: call to undefined function '%s'"
+msgstr "%B(%A): エラー: 定義ã•ã‚Œã¦ã„ãªã„関数 '%s' ã®å‘¼ã³å‡ºã—ã§ã™"
+
+#: elf32-rx.c:1274
+msgid "%B(%A): warning: unaligned access to symbol '%s' in the small data area"
+msgstr "%B(%A): 警告: small データ領域内ã«ã‚·ãƒ³ãƒœãƒ« '%s' ã¸ã®æ•´åˆ—ã•ã‚Œã¦ã„ãªã„アクセスãŒã‚ã‚Šã¾ã™"
+
+#: elf32-rx.c:1278
+msgid "%B(%A): internal error: out of range error"
+msgstr "%B(%A): 内部エラー: 範囲外エラーã§ã™"
+
+#: elf32-rx.c:1282
+msgid "%B(%A): internal error: unsupported relocation error"
+msgstr "%B(%A): 内部エラー: サãƒãƒ¼ãƒˆã•ã‚Œã¦ã„ãªã„å†é…置エラーã§ã™"
+
+#: elf32-rx.c:1286
+msgid "%B(%A): internal error: dangerous relocation"
+msgstr "%B(%A): 内部エラー: å±é™ºãªå†é…ç½®ã§ã™"
+
+#: elf32-rx.c:1290
+msgid "%B(%A): internal error: unknown error"
+msgstr "%B(%A): 内部エラー: ä¸æ˜Žãªã‚¨ãƒ©ãƒ¼ã§ã™"
+
+#: elf32-rx.c:2940
+#, c-format
+msgid " [64-bit doubles]"
+msgstr " [64 ビットå€ç²¾åº¦æµ®å‹•å°æ•°]"
+
+#: elf32-rx.c:2942
+#, c-format
+msgid " [dsp]"
+msgstr " [dsp]"
+
+#: elf32-s390.c:2209 elf64-s390.c:2196
+msgid "%B(%A+0x%lx): invalid instruction for TLS relocation %s"
+msgstr "%B(%A+0x%lx): TLS å†é…ç½® %s 用ã®ç„¡åŠ¹ãªå‘½ä»¤ã§ã™"
+
+#: elf32-score.c:1522 elf32-score7.c:1382 elfxx-mips.c:3324
+msgid "not enough GOT space for local GOT entries"
+msgstr "局所 GOT エントリ用㮠GOT 空間ãŒä¸å分ã§ã™"
+
+#: elf32-score.c:2744
+msgid "address not word align"
+msgstr "アドレス㌠WORD ã«æ•´åˆ—ã•ã‚Œã¦ã„ã¾ã›ã‚“"
+
+#: elf32-score.c:2829 elf32-score7.c:2634
+#, c-format
+msgid "%s: Malformed reloc detected for section %s"
+msgstr "%s: セクション %s ã«å¯¾ã™ã‚‹èª¤ã£ãŸå½¢å¼ã®å†é…ç½®ãŒæ¤œå‡ºã•ã‚Œã¾ã—ãŸ"
+
+#: elf32-score.c:2880 elf32-score7.c:2685
+msgid "%B: CALL15 reloc at 0x%lx not against global symbol"
+msgstr "%B: ä½ç½® 0x%lx ã«ã‚ã‚‹ CALL15 å†é…ç½®ãŒå¤§åŸŸã‚·ãƒ³ãƒœãƒ«ã«å¯¾ã™ã‚‹ã‚‚ã®ã§ã¯ã‚ã‚Šã¾ã›ã‚“"
+
+#: elf32-score.c:3999 elf32-score7.c:3806
+#, c-format
+msgid " [pic]"
+msgstr " [pic]"
+
+#: elf32-score.c:4003 elf32-score7.c:3810
+#, c-format
+msgid " [fix dep]"
+msgstr ""
+
+#: elf32-score.c:4045 elf32-score7.c:3852
+msgid "%B: warning: linking PIC files with non-PIC files"
+msgstr "%B: 警告: PIC ファイルã«éž PIC ファイルをリンクã—ã¦ã„ã¾ã™"
+
+#: elf32-sh-symbian.c:130
+msgid "%B: IMPORT AS directive for %s conceals previous IMPORT AS"
+msgstr "%B: %s 用㮠IMPORT AS 指示ãŒå‰ã® IMPORT AS 指示を隠ã—ã¾ã™"
+
+#: elf32-sh-symbian.c:383
+msgid "%B: Unrecognised .directive command: %s"
+msgstr "%B: èªè­˜ã§ããªã„ .directive コマンドã§ã™: %s"
+
+#: elf32-sh-symbian.c:504
+msgid "%B: Failed to add renamed symbol %s"
+msgstr "%B: åå‰ã‚’変更ã—ãŸã‚·ãƒ³ãƒœãƒ« %s を追加ã™ã‚‹ã®ã«å¤±æ•—ã—ã¾ã—ãŸ"
+
+#: elf32-sh.c:568
+msgid "%B: 0x%lx: warning: bad R_SH_USES offset"
+msgstr "%B: 0x%lx: 警告: 誤ã£ãŸ R_SH_USES オフセットã§ã™"
+
+#: elf32-sh.c:580
+msgid "%B: 0x%lx: warning: R_SH_USES points to unrecognized insn 0x%x"
+msgstr "%B: 0x%lx: 警告: R_SH_USES ãŒèªè­˜ã§ããªã„命令 0x%x を指ã—ã¦ã„ã¾ã™"
+
+#: elf32-sh.c:597
+msgid "%B: 0x%lx: warning: bad R_SH_USES load offset"
+msgstr "%B: 0x%lx: 警告: 誤ã£ãŸ R_SH_USES ロードオフセットã§ã™"
+
+#: elf32-sh.c:612
+msgid "%B: 0x%lx: warning: could not find expected reloc"
+msgstr "%B: 0x%lx: 警告: 予期ã•ã‚Œã‚‹å†é…置を見ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸ"
+
+#: elf32-sh.c:640
+msgid "%B: 0x%lx: warning: symbol in unexpected section"
+msgstr "%B: 0x%lx: 警告: 予期ã—ãªã„セクション内ã«ã‚·ãƒ³ãƒœãƒ«ãŒã‚ã‚Šã¾ã™"
+
+#: elf32-sh.c:766
+msgid "%B: 0x%lx: warning: could not find expected COUNT reloc"
+msgstr "%B: 0x%lx: 警告: 予期ã•ã‚Œã‚‹ COUNT å†é…ç½®ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸ"
+
+#: elf32-sh.c:775
+msgid "%B: 0x%lx: warning: bad count"
+msgstr "%B: 0x%lx: 警告: 誤ã£ãŸ count ã§ã™"
+
+#: elf32-sh.c:1179 elf32-sh.c:1549
+msgid "%B: 0x%lx: fatal: reloc overflow while relaxing"
+msgstr "%B: 0x%lx: 致命的: 緩和中ã«å†é…ç½®ãŒæº¢ã‚Œã¾ã—ãŸ"
+
+#: elf32-sh.c:4057 elf64-sh64.c:1514
+msgid "Unexpected STO_SH5_ISA32 on local symbol is not handled"
+msgstr "局所シンボルã«é–¢ã™ã‚‹äºˆæœŸã—ãªã„ STO_SH5_ISA32 ã¯å–り扱ã‚ã‚Œã¾ã›ã‚“"
+
+#: elf32-sh.c:4304
+msgid "%B: 0x%lx: fatal: unaligned branch target for relax-support relocation"
+msgstr "%B: 0x%lx: 致命的: 緩和をサãƒãƒ¼ãƒˆã™ã‚‹å†é…置用ã®åˆ†å²ã‚¿ãƒ¼ã‚²ãƒƒãƒˆãŒæ•´åˆ—ã•ã‚Œã¦ã„ã¾ã›ã‚“"
+
+#: elf32-sh.c:4337 elf32-sh.c:4352
+msgid "%B: 0x%lx: fatal: unaligned %s relocation 0x%lx"
+msgstr "%B: 0x%lx: 致命的: 整列ã•ã‚Œã¦ã„ãªã„ %s å†é…ç½® 0x%lx ã§ã™"
+
+#: elf32-sh.c:4366
+msgid "%B: 0x%lx: fatal: R_SH_PSHA relocation %d not in range -32..32"
+msgstr "%B: 0x%lx: 致命的: R_SH_PSHA å†é…ç½® %d ㌠-32..32 ã®ç¯„囲内ã«ã‚ã‚Šã¾ã›ã‚“"
+
+#: elf32-sh.c:4380
+msgid "%B: 0x%lx: fatal: R_SH_PSHL relocation %d not in range -32..32"
+msgstr "%B: 0x%lx: 致命的: R_SH_PSHL å†é…ç½® %d ㌠-32..32 ã®ã®ç¯„囲内ã«ã‚ã‚Šã¾ã›ã‚“"
+
+#: elf32-sh.c:4524 elf32-sh.c:4994
+msgid "%B(%A+0x%lx): cannot emit fixup to `%s' in read-only section"
+msgstr "%B(%A+0x%lx): 読ã¿å–り専用セクション内ã«ã‚ã‚‹ `%s' ã¸ã®ä¿®æ­£ã‚’発行ã§ãã¾ã›ã‚“"
+
+#: elf32-sh.c:5101
+msgid "%B(%A+0x%lx): %s relocation against external symbol \"%s\""
+msgstr "%B(%A+0x%lx): %s å†é…ç½® (外部シンボル \"%s\" ã«å¯¾ã™ã‚‹) ã§ã™"
+
+#: elf32-sh.c:5574
+#, c-format
+msgid "%X%C: relocation to \"%s\" references a different segment\n"
+msgstr "%X%C: \"%s\" ã¸ã®å†é…ç½®ãŒç•°ãªã‚‹ã‚»ã‚°ãƒ¡ãƒ³ãƒˆã‚’å‚ç…§ã—ã¦ã„ã¾ã™\n"
+
+#: elf32-sh.c:5580
+#, c-format
+msgid "%C: warning: relocation to \"%s\" references a different segment\n"
+msgstr "%C: 警告: \"%s\" ã¸ã®å†é…ç½®ãŒç•°ãªã‚‹ã‚»ã‚°ãƒ¡ãƒ³ãƒˆã‚’å‚ç…§ã—ã¦ã„ã¾ã™\n"
+
+#: elf32-sh.c:6358 elf32-sh.c:6441
+msgid "%B: `%s' accessed both as normal and FDPIC symbol"
+msgstr "%B: `%s' ãŒé€šå¸¸ã®ã‚·ãƒ³ãƒœãƒ«ã¨ FDPIC シンボルã®ä¸¡æ–¹ã¨ã—ã¦ã‚¢ã‚¯ã‚»ã‚¹ã•ã‚Œã¾ã—ãŸ"
+
+#: elf32-sh.c:6363 elf32-sh.c:6445
+msgid "%B: `%s' accessed both as FDPIC and thread local symbol"
+msgstr "%B: `%s' ㌠FDPIC シンボルã¨å±€æ‰€ã‚·ãƒ³ãƒœãƒ«ã®ä¸¡æ–¹ã¨ã—ã¦ã‚¢ã‚¯ã‚»ã‚¹ã•ã‚Œã¾ã—ãŸ"
+
+#: elf32-sh.c:6393
+msgid "%B: Function descriptor relocation with non-zero addend"
+msgstr ""
+
+#: elf32-sh.c:6629 elf64-alpha.c:4648
+msgid "%B: TLS local exec code cannot be linked into shared objects"
+msgstr "%B: TLS 局所実行コードã¯å…±æœ‰ã‚ªãƒ–ジェクト内ã«ãƒªãƒ³ã‚¯ã§ãã¾ã›ã‚“"
+
+#: elf32-sh64.c:223 elf64-sh64.c:2314
+#, c-format
+msgid "%s: compiled as 32-bit object and %s is 64-bit"
+msgstr "%s: 32-bit オブジェクトã¨ã—ã¦ã‚³ãƒ³ãƒ‘イルã•ã‚Œã¾ã—ãŸãŒ %s 㯠64 ビットã¨ã—ã¦ã‚³ãƒ³ãƒ‘イルã•ã‚Œã¾ã—ãŸ"
+
+#: elf32-sh64.c:226 elf64-sh64.c:2317
+#, c-format
+msgid "%s: compiled as 64-bit object and %s is 32-bit"
+msgstr "%s: 64 ビットオブジェクトã¨ã—ã¦ã‚³ãƒ³ãƒ‘イルã•ã‚Œã¾ã—ãŸãŒ %s ã¯32 ビットオブジェクトã¨ã—ã¦ã‚³ãƒ³ãƒ‘イルã•ã‚Œã¾ã—ãŸ"
+
+#: elf32-sh64.c:228 elf64-sh64.c:2319
+#, c-format
+msgid "%s: object size does not match that of target %s"
+msgstr "%s: オブジェクトサイズã¯ã‚¿ãƒ¼ã‚²ãƒƒãƒˆ %s ã«é©åˆã—ã¾ã›ã‚“"
+
+#: elf32-sh64.c:451 elf64-sh64.c:2833
+#, c-format
+msgid "%s: encountered datalabel symbol in input"
+msgstr ""
+
+#: elf32-sh64.c:528
+msgid "PTB mismatch: a SHmedia address (bit 0 == 1)"
+msgstr "PTB ä¸ä¸€è‡´: SHmedia アドレス (ビット0 == 1)"
+
+#: elf32-sh64.c:531
+msgid "PTA mismatch: a SHcompact address (bit 0 == 0)"
+msgstr "PTA ä¸ä¸€è‡´: SHcompact アドレス (ビット0 == 0)"
+
+#: elf32-sh64.c:549
+#, c-format
+msgid "%s: GAS error: unexpected PTB insn with R_SH_PT_16"
+msgstr "%s: GAS エラー: 予期ã—ãªã„ PTB 命令 (R_SH_PT_16 付ã) ã§ã™"
+
+#: elf32-sh64.c:598
+msgid "%B: error: unaligned relocation type %d at %08x reloc %p\n"
+msgstr "%B: エラー: 整列ã•ã‚Œã¦ã„ãªã„å†é…置型 %d ã§ã™ (ä½ç½® %08xã€å†é…ç½® %p)\n"
+
+#: elf32-sh64.c:674
+#, c-format
+msgid "%s: could not write out added .cranges entries"
+msgstr "%s: 追加ã•ã‚ŒãŸ .cranges エントリを書ã出ã›ã¾ã›ã‚“ã§ã—ãŸ"
+
+#: elf32-sh64.c:734
+#, c-format
+msgid "%s: could not write out sorted .cranges entries"
+msgstr "%s: ソートã•ã‚ŒãŸ .cranges エントリを書ã出ã›ã¾ã›ã‚“ã§ã—ãŸ"
+
+#: elf32-sparc.c:89
+msgid "%B: compiled for a 64 bit system and target is 32 bit"
+msgstr "%B: 64 ビットシステム用ã«ã‚³ãƒ³ãƒ‘イルã•ã‚Œã¾ã—ãŸãŒã‚¿ãƒ¼ã‚²ãƒƒãƒˆãŒ 32 ビットã§ã™"
+
+#: elf32-sparc.c:102
+msgid "%B: linking little endian files with big endian files"
+msgstr "%B: リトルエンディアンã®ãƒ•ã‚¡ã‚¤ãƒ«ã¨ãƒ“ッグエンディアンã®ãƒ•ã‚¡ã‚¤ãƒ«ã¨ã‚’リンクã—ã¦ã„ã¾ã™"
+
+#: elf32-spu.c:719
+msgid "%X%P: overlay section %A does not start on a cache line.\n"
+msgstr ""
+
+#: elf32-spu.c:727
+msgid "%X%P: overlay section %A is larger than a cache line.\n"
+msgstr ""
+
+#: elf32-spu.c:747
+msgid "%X%P: overlay section %A is not in cache area.\n"
+msgstr ""
+
+#: elf32-spu.c:787
+msgid "%X%P: overlay sections %A and %A do not start at the same address.\n"
+msgstr ""
+
+#: elf32-spu.c:1011
+msgid "warning: call to non-function symbol %s defined in %B"
+msgstr "警告: éžé–¢æ•°ã‚·ãƒ³ãƒœãƒ« %s (%B 内ã§å®šç¾©ã•ã‚ŒãŸ) ã®å‘¼ã³å‡ºã—ã§ã™"
+
+#: elf32-spu.c:1361
+msgid "%A:0x%v lrlive .brinfo (%u) differs from analysis (%u)\n"
+msgstr "%A:0x%v lrlive .brinfo (%u) ã¯åˆ†æžå†…容 (%u) ã¨ç•°ãªã‚Šã¾ã™\n"
+
+#: elf32-spu.c:1880
+msgid "%B is not allowed to define %s"
+msgstr "%B 㯠%s を定義ã™ã‚‹ã“ã¨ã¯è¨±å¯ã•ã‚Œã¦ã„ã¾ã›ã‚“"
+
+#: elf32-spu.c:1888
+#, c-format
+msgid "you are not allowed to define %s in a script"
+msgstr "スクリプト内㧠%s を定義ã™ã‚‹ã“ã¨ã¯è¨±å¯ã•ã‚Œã¦ã„ã¾ã›ã‚“"
+
+#: elf32-spu.c:1922
+#, c-format
+msgid "%s in overlay section"
+msgstr ""
+
+#: elf32-spu.c:1951
+msgid "overlay stub relocation overflow"
+msgstr ""
+
+#: elf32-spu.c:1960
+msgid "stubs don't match calculated size"
+msgstr "スタブãŒè¨ˆç®—ã—ãŸã‚µã‚¤ã‚ºã¨ä¸€è‡´ã—ã¦ã„ã¾ã›ã‚“"
+
+#: elf32-spu.c:2542
+#, c-format
+msgid "warning: %s overlaps %s\n"
+msgstr "警告: %s ㌠%s ã¨é‡ãªã‚Šåˆã£ã¦ã„ã¾ã™\n"
+
+#: elf32-spu.c:2558
+#, c-format
+msgid "warning: %s exceeds section size\n"
+msgstr "警告: %s ãŒã‚»ã‚¯ã‚·ãƒ§ãƒ³é•·ã‚’超ãˆã¦ã„ã¾ã™\n"
+
+#: elf32-spu.c:2589
+msgid "%A:0x%v not found in function table\n"
+msgstr "%A:0x%v ãŒé–¢æ•°è¡¨å†…ã«è¦‹ã¤ã‹ã‚Šã¾ã›ã‚“\n"
+
+#: elf32-spu.c:2729
+msgid "%B(%A+0x%v): call to non-code section %B(%A), analysis incomplete\n"
+msgstr "%B(%A+0x%v): éžã‚³ãƒ¼ãƒ‰ã‚»ã‚¯ã‚·ãƒ§ãƒ³ %B(%A) ã®å‘¼ã³å‡ºã—ã§ã™ã€‚分æžãŒä¸å®Œå…¨ã§ã™\n"
+
+#: elf32-spu.c:3297
+#, c-format
+msgid "Stack analysis will ignore the call from %s to %s\n"
+msgstr "スタック分æžã¯ %s ã‹ã‚‰ %s ã¸ã®å‘¼ã³å‡ºã—ã§ç„¡è¦–ã•ã‚Œã¾ã™\n"
+
+#: elf32-spu.c:3988
+msgid " %s: 0x%v\n"
+msgstr " %s: 0x%v\n"
+
+#: elf32-spu.c:3989
+msgid "%s: 0x%v 0x%v\n"
+msgstr "%s: 0x%v 0x%v\n"
+
+#: elf32-spu.c:3994
+msgid " calls:\n"
+msgstr " 呼ã³å‡ºã—:\n"
+
+#: elf32-spu.c:4002
+#, c-format
+msgid " %s%s %s\n"
+msgstr " %s%s %s\n"
+
+#: elf32-spu.c:4307
+#, c-format
+msgid "%s duplicated in %s\n"
+msgstr "%s ㌠%s 内ã§é‡è¤‡ã—ã¦ã„ã¾ã™\n"
+
+#: elf32-spu.c:4311
+#, c-format
+msgid "%s duplicated\n"
+msgstr "%s ãŒé‡è¤‡ã—ã¦ã„ã¾ã™\n"
+
+#: elf32-spu.c:4318
+msgid "sorry, no support for duplicate object files in auto-overlay script\n"
+msgstr ""
+
+#: elf32-spu.c:4359
+msgid "non-overlay size of 0x%v plus maximum overlay size of 0x%v exceeds local store\n"
+msgstr ""
+
+#: elf32-spu.c:4514
+msgid "%B:%A%s exceeds overlay size\n"
+msgstr ""
+
+#: elf32-spu.c:4676
+msgid "Stack size for call graph root nodes.\n"
+msgstr ""
+
+#: elf32-spu.c:4677
+msgid ""
+"\n"
+"Stack size for functions. Annotations: '*' max stack, 't' tail call\n"
+msgstr ""
+
+#: elf32-spu.c:4687
+msgid "Maximum stack required is 0x%v\n"
+msgstr "è¦æ±‚ã•ã‚Œã‚‹æœ€å¤§ã‚¹ã‚¿ãƒƒã‚¯ã¯ 0x%v ã§ã™\n"
+
+#: elf32-spu.c:4778
+msgid "fatal error while creating .fixup"
+msgstr ".fixup 作æˆä¸­ã«è‡´å‘½çš„エラーãŒç™ºç”Ÿã—ã¾ã—ãŸ"
+
+#: elf32-spu.c:5006
+msgid "%B(%s+0x%lx): unresolvable %s relocation against symbol `%s'"
+msgstr "%B(%s+0x%lx): 解決ã§ããªã„ %s å†é…ç½® (シンボル `%s' ã«å¯¾ã™ã‚‹) ã§ã™"
+
+#: elf32-tic6x.c:1602
+msgid "warning: generating a shared library containing non-PIC code"
+msgstr "警告: éž PIC コードをå«ã‚€å…±æœ‰ãƒ©ã‚¤ãƒ–ラリを生æˆã—ã¦ã„ã¾ã™"
+
+#: elf32-tic6x.c:1607
+msgid "warning: generating a shared library containing non-PID code"
+msgstr "警告: éž PID コードをå«ã‚€å…±æœ‰ãƒ©ã‚¤ãƒ–ラリを生æˆã—ã¦ã„ã¾ã™"
+
+#: elf32-tic6x.c:2539
+msgid "%B: SB-relative relocation but __c6xabi_DSBT_BASE not defined"
+msgstr "%B: SB ã«é–¢é€£ã—ãŸå†é…ç½®ã§ã™ãŒã€__c6xabi_DSBT_BASE ãŒå®šç¾©ã•ã‚Œã¦ã„ã¾ã›ã‚“"
+
+#: elf32-tic6x.c:2759
+msgid "dangerous relocation"
+msgstr "å±é™ºãªå†é…ç½®ã§ã™"
+
+#: elf32-tic6x.c:3740
+msgid "%B: error: unknown mandatory EABI object attribute %d"
+msgstr "%B: エラー: ä¸æ˜Žãªå¿…é ˆ EABI オブジェクト属性 %d ã§ã™"
+
+#: elf32-tic6x.c:3748
+msgid "%B: warning: unknown EABI object attribute %d"
+msgstr "%B: 警告: ä¸æ˜ŽãªEABI オブジェクト属性 %d ã§ã™"
+
+#: elf32-tic6x.c:3860 elf32-tic6x.c:3868
+msgid "error: %B requires more stack alignment than %B preserves"
+msgstr "error: %B 㯠%B ãŒä¿æŒã—ã¦ã„るより大ããªã‚¹ã‚¿ãƒƒã‚¯æ•´åˆ—ã‚’å¿…è¦ã¨ã—ã¾ã™"
+
+#: elf32-tic6x.c:3878 elf32-tic6x.c:3887
+msgid "error: unknown Tag_ABI_array_object_alignment value in %B"
+msgstr "エラー: %B 内ã§ä¸æ˜Žãª Tag_ABI_array_object_alignment 値ã§ã™"
+
+#: elf32-tic6x.c:3896 elf32-tic6x.c:3905
+msgid "error: unknown Tag_ABI_array_object_align_expected value in %B"
+msgstr "エラー: %B 内ã§ä¸æ˜Žãª Tag_ABI_array_object_align_expected 値ã§ã™"
+
+#: elf32-tic6x.c:3913 elf32-tic6x.c:3920
+msgid "error: %B requires more array alignment than %B preserves"
+msgstr "エラー: %B 㯠%B ãŒä¿æŒã—ã¦ã„るより大ããªé…列整列を必è¦ã¨ã—ã¾ã™"
+
+#: elf32-tic6x.c:3942
+msgid "warning: %B and %B differ in wchar_t size"
+msgstr "警告: %B 㨠%B 㧠wchar_t サイズãŒç•°ãªã‚Šã¾ã™"
+
+#: elf32-tic6x.c:3960
+msgid "warning: %B and %B differ in whether code is compiled for DSBT"
+msgstr "警告: %B 㨠%B ã§ã‚³ãƒ¼ãƒ‰ãŒ DSBT 用ã«ã‚³ãƒ³ãƒ‘イルã•ã‚ŒãŸã‹ãŒç•°ãªã‚Šã¾ã™"
+
+#: elf32-v850.c:173
+#, c-format
+msgid "Variable `%s' cannot occupy in multiple small data regions"
+msgstr "変数 `%s' ã¯è¤‡æ•°ã® small データ領域をå æœ‰ã™ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“"
+
+#: elf32-v850.c:176
+#, c-format
+msgid "Variable `%s' can only be in one of the small, zero, and tiny data regions"
+msgstr "変数 `%s' 㯠small, zero åŠã³ tiny データ領域ã®å†…一ã¤ã«ã®ã¿ç½®ãã“ã¨ãŒã§ãã¾ã™"
+
+#: elf32-v850.c:179
+#, c-format
+msgid "Variable `%s' cannot be in both small and zero data regions simultaneously"
+msgstr "変数 `%s' ã‚’ small 㨠zero データ領域ã¸åŒæ™‚ã«ç½®ãã“ã¨ã¯ã§ãã¾ã›ã‚“"
+
+#: elf32-v850.c:182
+#, c-format
+msgid "Variable `%s' cannot be in both small and tiny data regions simultaneously"
+msgstr "変数 `%s' ã‚’ small 㨠tiny データ領域ã¸åŒæ™‚ã«ç½®ãã“ã¨ã¯ã§ãã¾ã›ã‚“"
+
+#: elf32-v850.c:185
+#, c-format
+msgid "Variable `%s' cannot be in both zero and tiny data regions simultaneously"
+msgstr "変数 `%s' 㯠zero 㨠tiny データ領域ã¸åŒæ™‚ã«ç½®ãã“ã¨ã¯ã§ãã¾ã›ã‚“"
+
+#: elf32-v850.c:483
+msgid "FAILED to find previous HI16 reloc"
+msgstr "以å‰ã® HI16 å†é…置を見ã¤ã‘られã¾ã›ã‚“ã§ã—ãŸ"
+
+#: elf32-v850.c:2155
+msgid "could not locate special linker symbol __gp"
+msgstr "特殊リンカシンボル __gp ã®ä½ç½®ã‚’特定ã§ãã¾ã›ã‚“ã§ã—ãŸ"
+
+#: elf32-v850.c:2159
+msgid "could not locate special linker symbol __ep"
+msgstr "特殊リンカシンボル __ep ã®ä½ç½®ã‚’特定ã§ãã¾ã›ã‚“ã§ã—ãŸ"
+
+#: elf32-v850.c:2163
+msgid "could not locate special linker symbol __ctbp"
+msgstr "特殊リンカシンボル __ctbp ã®ä½ç½®ã‚’特定ã§ãã¾ã›ã‚“ã§ã—ãŸ"
+
+#: elf32-v850.c:2341
+msgid "%B: Architecture mismatch with previous modules"
+msgstr "%B: å‰ã®ãƒ¢ã‚¸ãƒ¥ãƒ¼ãƒ«ã¨ã‚¢ãƒ¼ã‚­ãƒ†ã‚¯ãƒãƒ£ãŒä¸€è‡´ã—ã¾ã›ã‚“"
+
+#. xgettext:c-format.
+#: elf32-v850.c:2360
+#, c-format
+msgid "private flags = %lx: "
+msgstr "private フラグ = %lx: "
+
+#: elf32-v850.c:2365
+#, c-format
+msgid "v850 architecture"
+msgstr "v850 アーキテクãƒãƒ£"
+
+#: elf32-v850.c:2366
+#, c-format
+msgid "v850e architecture"
+msgstr "v850e アーキテクãƒãƒ£"
+
+#: elf32-v850.c:2367
+#, c-format
+msgid "v850e1 architecture"
+msgstr "v850e1 アーキテクãƒãƒ£"
+
+#: elf32-v850.c:2368
+#, c-format
+msgid "v850e2 architecture"
+msgstr "v850e2 アーキテクãƒãƒ£"
+
+#: elf32-v850.c:2369
+#, c-format
+msgid "v850e2v3 architecture"
+msgstr "v850e2v3 アーキテクãƒãƒ£"
+
+#: elf32-vax.c:531
+#, c-format
+msgid " [nonpic]"
+msgstr ""
+
+#: elf32-vax.c:534
+#, c-format
+msgid " [d-float]"
+msgstr ""
+
+#: elf32-vax.c:537
+#, c-format
+msgid " [g-float]"
+msgstr ""
+
+#: elf32-vax.c:654
+#, c-format
+msgid "%s: warning: GOT addend of %ld to `%s' does not match previous GOT addend of %ld"
+msgstr ""
+
+#: elf32-vax.c:1587
+#, c-format
+msgid "%s: warning: PLT addend of %d to `%s' from %s section ignored"
+msgstr ""
+
+#: elf32-vax.c:1714
+#, c-format
+msgid "%s: warning: %s relocation against symbol `%s' from %s section"
+msgstr "%s: 警告: %s å†é…ç½® (シンボル `%s' ã«å¯¾ã™ã‚‹ %s セクションã‹ã‚‰) ã§ã™"
+
+#: elf32-vax.c:1720
+#, c-format
+msgid "%s: warning: %s relocation to 0x%x from %s section"
+msgstr "%s: 警告: %s å†é…ç½® (0x%x 㸠%s セクションã‹ã‚‰) ã§ã™"
+
+#: elf32-xstormy16.c:451 elf32-ia64.c:2342 elf64-ia64.c:2342
+msgid "non-zero addend in @fptr reloc"
+msgstr ""
+
+#: elf32-xtensa.c:918
+msgid "%B(%A): invalid property table"
+msgstr "%B(%A): 無効ãªãƒ—ロパティ表ã§ã™"
+
+#: elf32-xtensa.c:2780
+msgid "%B(%A+0x%lx): relocation offset out of range (size=0x%x)"
+msgstr "%B(%A+0x%lx): å†é…置オフセットãŒç¯„囲外ã§ã™ (サイズ=0x%x)"
+
+#: elf32-xtensa.c:2859 elf32-xtensa.c:2980
+msgid "dynamic relocation in read-only section"
+msgstr "å‹•çš„å†é…ç½®ãŒèª­ã¿è¾¼ã¿å°‚用セクションã«ã‚ã‚Šã¾ã™"
+
+#: elf32-xtensa.c:2956
+msgid "TLS relocation invalid without dynamic sections"
+msgstr "動的セクションãŒãªã„å ´åˆã¯ TLS å†é…ç½®ã¯ç„¡åŠ¹ã§ã™"
+
+#: elf32-xtensa.c:3173
+msgid "internal inconsistency in size of .got.loc section"
+msgstr ".got.loc セクションã®ã‚µã‚¤ã‚ºã«å†…部一貫性ãŒã‚ã‚Šã¾ã›ã‚“"
+
+#: elf32-xtensa.c:3486
+msgid "%B: incompatible machine type. Output is 0x%x. Input is 0x%x"
+msgstr "%B: 互æ›æ€§ã®ãªã„マシン型ã§ã™ã€‚出力㯠0x%xã€å…¥åŠ›ã¯ 0x%x ã§ã™"
+
+#: elf32-xtensa.c:4715 elf32-xtensa.c:4723
+msgid "Attempt to convert L32R/CALLX to CALL failed"
+msgstr "L32R/CALLX ã‹ã‚‰ CALL ã¸ã®å¤‰æ›ã®è©¦ã¿ã«å¤±æ•—ã—ã¾ã—ãŸ"
+
+#: elf32-xtensa.c:6333 elf32-xtensa.c:6409 elf32-xtensa.c:7525
+msgid "%B(%A+0x%lx): could not decode instruction; possible configuration mismatch"
+msgstr "%B(%A+0x%lx): 命令をデコードã§ãã¾ã›ã‚“。設定ãŒé©åˆã—ã¦ã„ãªã„å¯èƒ½æ€§ãŒã‚ã‚Šã¾ã™"
+
+#: elf32-xtensa.c:7265
+msgid "%B(%A+0x%lx): could not decode instruction for XTENSA_ASM_SIMPLIFY relocation; possible configuration mismatch"
+msgstr "%B(%A+0x%lx): XTENSA_ASM_SIMPLIFY å†é…置用ã®å‘½ä»¤ã‚’デコードã§ãã¾ã›ã‚“。設定ãŒé©åˆã—ã¦ã„ãªã„å¯èƒ½æ€§ãŒã‚ã‚Šã¾ã™"
+
+#: elf32-xtensa.c:9024
+msgid "invalid relocation address"
+msgstr "無効ãªå†é…置アドレスã§ã™"
+
+#: elf32-xtensa.c:9073
+msgid "overflow after relaxation"
+msgstr "緩和後ã«ã‚ªãƒ¼ãƒãƒ¼ãƒ•ãƒ­ãƒ¼ã—ã¾ã—ãŸ"
+
+#: elf32-xtensa.c:10205
+msgid "%B(%A+0x%lx): unexpected fix for %s relocation"
+msgstr "%B(%A+0x%lx): %s å†é…置用ã®äºˆæœŸã—ãªã„修正ã§ã™"
+
+#: elf64-alpha.c:460
+msgid "GPDISP relocation did not find ldah and lda instructions"
+msgstr "GPDISP å†é…置㌠ldah 㨠lda 命令を見ã¤ã‘ã¾ã›ã‚“ã§ã—ãŸ"
+
+#: elf64-alpha.c:2495
+msgid "%B: .got subsegment exceeds 64K (size %d)"
+msgstr "%B: .got サブセグメント㌠64K を超ãˆã¦ã„ã¾ã™ (サイズ %d)"
+
+#: elf64-alpha.c:4392 elf64-alpha.c:4404
+msgid "%B: gp-relative relocation against dynamic symbol %s"
+msgstr "%B: 動的シンボル %s ã«å¯¾ã™ã‚‹ gp 関連å†é…ç½®ã§ã™"
+
+#: elf64-alpha.c:4430 elf64-alpha.c:4565
+msgid "%B: pc-relative relocation against dynamic symbol %s"
+msgstr "%B: 動的シンボル %s ã«å¯¾ã™ã‚‹ pc 関連å†é…ç½®ã§ã™"
+
+#: elf64-alpha.c:4458
+msgid "%B: change in gp: BRSGP %s"
+msgstr "%B: gp 内ã«å¤‰æ›´ãŒã‚ã‚Šã¾ã™: BRSGP %s"
+
+#: elf64-alpha.c:4483
+msgid "<unknown>"
+msgstr "<ä¸æ˜Ž>"
+
+#: elf64-alpha.c:4488
+msgid "%B: !samegp reloc against symbol without .prologue: %s"
+msgstr "%B: .prologue ãŒç„¡ã„シンボルã«å¯¾ã™ã‚‹ !samegp å†é…ç½®ã§ã™: %s"
+
+#: elf64-alpha.c:4540
+msgid "%B: unhandled dynamic relocation against %s"
+msgstr "%B: %s ã«å¯¾ã™ã‚‹å–り扱ã‚ã‚Œãªã„å‹•çš„å†é…ç½®ã§ã™"
+
+#: elf64-alpha.c:4572
+msgid "%B: pc-relative relocation against undefined weak symbol %s"
+msgstr "%B: 未定義ã®å¼±ã„シンボル %s ã«å¯¾ã™ã‚‹ pc 関連ã®å†é…ç½®ã§ã™"
+
+#: elf64-alpha.c:4632
+msgid "%B: dtp-relative relocation against dynamic symbol %s"
+msgstr "%B: 動的シンボル %s ã«å¯¾ã™ã‚‹ dtp 関連ã®å†é…ç½®ã§ã™"
+
+#: elf64-alpha.c:4655
+msgid "%B: tp-relative relocation against dynamic symbol %s"
+msgstr "%B: 動的シンボル %s ã«å¯¾ã™ã‚‹ tp 関連ã®å†é…ç½®ã§ã™"
+
+#: elf64-hppa.c:2094
+#, c-format
+msgid "stub entry for %s cannot load .plt, dp offset = %ld"
+msgstr "%s 用ã®ã‚¹ã‚¿ãƒ–エントリ㯠.plt をロードã§ãã¾ã›ã‚“。 dp オフセット = %ld"
+
+#: elf64-hppa.c:3292
+msgid "%B(%A+0x%lx): cannot reach %s"
+msgstr "%B(%A+0x%lx): %s ã¾ã§åˆ°é”ã§ãã¾ã›ã‚“"
+
+#: elf64-mmix.c:1177
+#, c-format
+msgid ""
+"%s: Internal inconsistency error for value for\n"
+" linker-allocated global register: linked: 0x%lx%08lx != relaxed: 0x%lx%08lx\n"
+msgstr "%s: リンカã®é…ç½®ã—ãŸå¤§åŸŸãƒ¬ã‚¸ã‚¹ã‚¿ã®å€¤ã®å†…部一貫性ãŒä¿ãŸã‚Œã¦ã„ãªã„エラーã§ã™: リンク: 0x%lx%08lx != ç·©å’Œ: 0x%lx%08lx\n"
+
+#: elf64-mmix.c:1607
+#, c-format
+msgid "%s: base-plus-offset relocation against register symbol: (unknown) in %s"
+msgstr "%s: レジスタシンボルã«å¯¾ã™ã‚‹ base-plus-offset å†é…ç½®ã§ã™: (ä¸æ˜Ž) (%s 内)"
+
+#: elf64-mmix.c:1612
+#, c-format
+msgid "%s: base-plus-offset relocation against register symbol: %s in %s"
+msgstr "%s: レジスタシンボルã«å¯¾ã™ã‚‹ base-plus-offset å†é…ç½®ã§ã™: %s (%s 内)"
+
+#: elf64-mmix.c:1656
+#, c-format
+msgid "%s: register relocation against non-register symbol: (unknown) in %s"
+msgstr "%s: éžãƒ¬ã‚¸ã‚¹ã‚¿ã‚·ãƒ³ãƒœãƒ«ã«å¯¾ã™ã‚‹ãƒ¬ã‚¸ã‚¹ã‚¿å†é…ç½®ã§ã™: (ä¸æ˜Ž) (%s 内)"
+
+#: elf64-mmix.c:1661
+#, c-format
+msgid "%s: register relocation against non-register symbol: %s in %s"
+msgstr "%s: éžãƒ¬ã‚¸ã‚¹ã‚¿ã‚·ãƒ³ãƒœãƒ«ã«å¯¾ã™ã‚‹ãƒ¬ã‚¸ã‚¹ã‚¿å†é…ç½®ã§ã™: %s (%s 内)"
+
+#: elf64-mmix.c:1698
+#, c-format
+msgid "%s: directive LOCAL valid only with a register or absolute value"
+msgstr "%s: LOCAL 指示ã¯ãƒ¬ã‚¸ã‚¹ã‚¿ã¾ãŸã¯çµ¶å¯¾å€¤ã«å¯¾ã—ã¦ã®ã¿æœ‰åŠ¹ã§ã™"
+
+#: elf64-mmix.c:1726
+#, c-format
+msgid "%s: LOCAL directive: Register $%ld is not a local register. First global register is $%ld."
+msgstr "%s: LOCAL 指示: レジスタ $%ld ã¯å±€æ‰€ãƒ¬ã‚¸ã‚¹ã‚¿ã§ã¯ã‚ã‚Šã¾ã›ã‚“。最åˆã®å¤§åŸŸãƒ¬ã‚¸ã‚¹ã‚¿ã¯ $%ld ã§ã™ã€‚"
+
+#: elf64-mmix.c:2190
+#, c-format
+msgid "%s: Error: multiple definition of `%s'; start of %s is set in a earlier linked file\n"
+msgstr "%s: エラー: `%s' ãŒè¤‡æ•°å®šç¾©ã•ã‚Œã¦ã„ã¾ã™; %s ã®é–‹å§‹ã¯å…ˆã«ãƒªãƒ³ã‚¯ã•ã‚ŒãŸãƒ•ã‚¡ã‚¤ãƒ«ã«è¨­å®šã•ã‚Œã¾ã™\n"
+
+#: elf64-mmix.c:2248
+msgid "Register section has contents\n"
+msgstr "レジスタセクションã«å†…容ãŒã‚ã‚Šã¾ã™\n"
+
+#: elf64-mmix.c:2440
+#, c-format
+msgid ""
+"Internal inconsistency: remaining %u != max %u.\n"
+" Please report this bug."
+msgstr ""
+"内部一貫性ãŒä¿ãŸã‚Œã¦ã„ã¾ã›ã‚“: 残り %u != 最大 %u。\n"
+" ã“ã®ãƒã‚°ã‚’報告ã—ã¦ãã ã•ã„。"
+
+#: elf64-ppc.c:2744 libbfd.c:1012
+msgid "%B: compiled for a big endian system and target is little endian"
+msgstr "%B: ビッグエンディアンシステム用ã«ã‚³ãƒ³ãƒ‘イルã•ã‚Œã¾ã—ãŸãŒã€ã‚¿ãƒ¼ã‚²ãƒƒãƒˆã¯ãƒªãƒˆãƒ«ã‚¨ãƒ³ãƒ‡ã‚£ã‚¢ãƒ³ã§ã™"
+
+#: elf64-ppc.c:2747 libbfd.c:1014
+msgid "%B: compiled for a little endian system and target is big endian"
+msgstr "%B: リトルエンディアンシステム用ã«ã‚³ãƒ³ãƒ‘イルã•ã‚Œã¾ã—ãŸãŒã€ã‚¿ãƒ¼ã‚²ãƒƒãƒˆã¯ãƒ“ッグエンディアンã§ã™"
+
+#: elf64-ppc.c:4160
+msgid "%B: cannot create stub entry %s\n"
+msgstr "%B: スタブエントリ %s を作æˆã§ãã¾ã›ã‚“\n"
+
+#: elf64-ppc.c:6484
+#, c-format
+msgid "copy reloc against `%s' requires lazy plt linking; avoid setting LD_BIND_NOW=1 or upgrade gcc\n"
+msgstr ""
+
+#: elf64-ppc.c:6912
+msgid "dynreloc miscount for %B, section %A\n"
+msgstr "å‹•çš„å†é…置数ãŒåˆã„ã¾ã›ã‚“ (ファイル %B, セクション %A)\n"
+
+#: elf64-ppc.c:6996
+msgid "%B: .opd is not a regular array of opd entries"
+msgstr "%B: .opd 㯠opd エントリã®é€šå¸¸é…列ã§ã¯ã‚ã‚Šã¾ã›ã‚“"
+
+#: elf64-ppc.c:7005
+msgid "%B: unexpected reloc type %u in .opd section"
+msgstr "%B: .opd セクション内ã«äºˆæœŸã—ãªã„å†é…置型 %u ã§ã™"
+
+#: elf64-ppc.c:7026
+msgid "%B: undefined sym `%s' in .opd section"
+msgstr "%B: .opd セクション内ã«æœªå®šç¾©ã‚·ãƒ³ãƒœãƒ« `%s' ã§ã™"
+
+#: elf64-ppc.c:7584
+msgid "%H __tls_get_addr lost arg, TLS optimization disabled\n"
+msgstr "%H __tls_get_addr ã®å¼•æ•°ãŒå¤±ã‚ã‚Œã¾ã—ãŸã€‚TLS 最é©åŒ–ã¯ç„¡åŠ¹ã«ãªã‚Šã¾ã™\n"
+
+#: elf64-ppc.c:7929 elf64-ppc.c:8450
+#, c-format
+msgid "%s defined on removed toc entry"
+msgstr "削除ã•ã‚ŒãŸ toc エントリ㧠%s ãŒå®šç¾©ã•ã‚Œã¦ã„ã¾ã™"
+
+#: elf64-ppc.c:9474
+#, c-format
+msgid "cannot find opd entry toc for %s\n"
+msgstr ""
+
+#: elf64-ppc.c:9556
+#, c-format
+msgid "long branch stub `%s' offset overflow\n"
+msgstr "é•·ã„分å²ã‚¹ã‚¿ãƒ– `%s' ã®ã‚ªãƒ•ã‚»ãƒƒãƒˆãŒã‚ªãƒ¼ãƒãƒ¼ãƒ•ãƒ­ãƒ¼ã—ã¾ã—ãŸ\n"
+
+#: elf64-ppc.c:9615
+#, c-format
+msgid "can't find branch stub `%s'\n"
+msgstr "分å²ã‚¹ã‚¿ãƒ– `%s' ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“\n"
+
+#: elf64-ppc.c:9677 elf64-ppc.c:9819
+#, c-format
+msgid "linkage table error against `%s'\n"
+msgstr "`%s' ã«å¯¾ã™ã‚‹ãƒªãƒ³ã‚¯è¡¨ã‚¨ãƒ©ãƒ¼ã§ã™\n"
+
+#: elf64-ppc.c:9993
+#, c-format
+msgid "can't build branch stub `%s'\n"
+msgstr "分å²ã‚¹ã‚¿ãƒ– `%s' を構築ã§ãã¾ã›ã‚“\n"
+
+#: elf64-ppc.c:10814
+msgid "%B section %A exceeds stub group size"
+msgstr "%B セクション %A ã¯ã‚¹ã‚¿ãƒ–グループサイズを超éŽã—ã¦ã„ã¾ã™"
+
+#: elf64-ppc.c:11457
+msgid "stubs don't match calculated size\n"
+msgstr "スタブãŒè¨ˆç®—ã—ãŸã‚µã‚¤ã‚ºã¨ä¸€è‡´ã—ã¦ã„ã¾ã›ã‚“\n"
+
+#: elf64-ppc.c:11469
+#, c-format
+msgid ""
+"linker stubs in %u group%s\n"
+" branch %lu\n"
+" toc adjust %lu\n"
+" long branch %lu\n"
+" long toc adj %lu\n"
+" plt call %lu"
+msgstr ""
+"%u グループ%s 内ã®ãƒªãƒ³ã‚¯ã‚¹ã‚¿ãƒ–\n"
+" åˆ†å² %lu\n"
+" toc 調整 %lu\n"
+" é•·åˆ†å² %lu\n"
+" 長 toc 調整 %lu\n"
+" plt 呼ã³å‡ºã— %lu"
+
+#: elf64-ppc.c:11819
+msgid "%H: %s used with TLS symbol %s\n"
+msgstr "%H: %s ㌠TLS シンボル %s ã¨ä½µã›ã¦ä½¿ç”¨ã•ã‚Œã¾ã—ãŸ\n"
+
+#: elf64-ppc.c:11820
+msgid "%H: %s used with non-TLS symbol %s\n"
+msgstr "%H: %s ãŒéž-TLS シンボル %s ã¨ä½µã›ã¦ä½¿ç”¨ã•ã‚Œã¾ã—ãŸ\n"
+
+#: elf64-ppc.c:12318
+msgid "%H: automatic multiple TOCs not supported using your crt files; recompile with -mminimal-toc or upgrade gcc\n"
+msgstr "%H: 自動的ãªè¤‡æ•° TOC ã¯ä½¿ç”¨ã—ã¦ã„ã‚‹ crt ファイルã§ã¯ã‚µãƒãƒ¼ãƒˆã•ã‚Œã¦ã„ã¾ã›ã‚“。 -mminimal-toc を付ã‘ã¦å†ã‚³ãƒ³ãƒ‘イルã™ã‚‹ã‹ã€ gcc をアップグレードã—ã¦ãã ã•ã„\n"
+
+#: elf64-ppc.c:12324
+msgid "%H: sibling call optimization to `%s' does not allow automatic multiple TOCs; recompile with -mminimal-toc or -fno-optimize-sibling-calls, or make `%s' extern\n"
+msgstr ""
+
+#: elf64-ppc.c:13041
+msgid "%B: relocation %s is not supported for symbol %s\n"
+msgstr "%B: å†é…ç½® %s (シンボル %s 用) ã¯ã‚µãƒãƒ¼ãƒˆã•ã‚Œã¦ã„ã¾ã›ã‚“\n"
+
+#: elf64-ppc.c:13218
+msgid "%H: error: %s not a multiple of %u\n"
+msgstr "%H: エラー: %s ㌠%u ã®å€æ•°ã§ã¯ã‚ã‚Šã¾ã›ã‚“\n"
+
+#: elf64-sh64.c:1682
+#, c-format
+msgid "%s: error: unaligned relocation type %d at %08x reloc %08x\n"
+msgstr "%s: エラー: 整列ã•ã‚Œã¦ã„ãªã„å†é…置型 %d ã§ã™ (ä½ç½® %08xã€å†é…ç½® %08x)\n"
+
+#: elf64-sparc.c:445
+msgid "%B: Only registers %%g[2367] can be declared using STT_REGISTER"
+msgstr "%B: STT_REGISTER を使ã†ã¨å®£è¨€ã§ãã‚‹ã®ã¯ãƒ¬ã‚¸ã‚¹ã‚¿ %%g[2367] ã ã‘ã§ã™"
+
+#: elf64-sparc.c:465
+msgid "Register %%g%d used incompatibly: %s in %B, previously %s in %B"
+msgstr "レジスタ %%g%d ãŒäº’æ›æ€§ã®ãªã„方法ã§ä½¿ç”¨ã•ã‚Œã¦ã„ã¾ã™: %s (%B 内)ã§ã™ãŒã€å‰ã¯ %s (%B 内) ã§ã™"
+
+#: elf64-sparc.c:488
+msgid "Symbol `%s' has differing types: REGISTER in %B, previously %s in %B"
+msgstr "シンボル `%s' ãŒç•°ãªã‚‹åž‹ã‚’æŒã£ã¦ã„ã¾ã™: REGISTER (%B 内) ã§ã™ãŒã€å‰ã¯ %s (%B 内) ã§ã™"
+
+#: elf64-sparc.c:533
+msgid "Symbol `%s' has differing types: %s in %B, previously REGISTER in %B"
+msgstr "シンボル `%s' ãŒç•°ãªã‚‹åž‹ã‚’æŒã£ã¦ã„ã¾ã™: %s (%B 内) ã§ã™ãŒã€å‰ã¯ REGISTER (%B 内) ã§ã™"
+
+#: elf64-sparc.c:686
+msgid "%B: linking UltraSPARC specific with HAL specific code"
+msgstr "%B: UltraSPARC 特有ã®ã‚³ãƒ¼ãƒ‰ã¨ HAL 特有ã®ã‚³ãƒ¼ãƒ‰ã‚’リンクã—ã¦ã„ã¾ã™"
+
+#: elf64-x86-64.c:1236
+msgid "%B: relocation %s against symbol `%s' isn't supported in x32 mode"
+msgstr "%B: å†é…ç½® %s (シンボル `%s' ã«å¯¾ã™ã‚‹) 㯠x32 モードã§ã¯ã‚µãƒãƒ¼ãƒˆã•ã‚Œã¾ã›ã‚“"
+
+#: elf64-x86-64.c:1465
+msgid "%B: '%s' accessed both as normal and thread local symbol"
+msgstr "%B: '%s' ãŒé€šå¸¸ã‚·ãƒ³ãƒœãƒ«ã¨ã‚¹ãƒ¬ãƒƒãƒ‰å±€æ‰€ã‚·ãƒ³ãƒœãƒ«ã®ä¸¡æ–¹ã¨ã—ã¦ã‚¢ã‚¯ã‚»ã‚¹ã•ã‚Œã¾ã—ãŸ"
+
+#: elf64-x86-64.c:2934
+msgid "%B: relocation %s against STT_GNU_IFUNC symbol `%s' has non-zero addend: %d"
+msgstr ""
+
+#: elf64-x86-64.c:3193
+msgid "%B: relocation R_X86_64_GOTOFF64 against protected function `%s' can not be used when making a shared object"
+msgstr "%B: ä¿è­·ã•ã‚ŒãŸé–¢æ•° `%s' ã«å¯¾ã™ã‚‹å†é…ç½® R_X86_64_GOTOFF64 ã¯å…±æœ‰ã‚ªãƒ–ジェクト作æˆæ™‚ã«ã¯ä½¿ç”¨å‡ºæ¥ã¾ã›ã‚“"
+
+#: elf64-x86-64.c:3305
+msgid "; recompile with -fPIC"
+msgstr "。 -fPIC を付ã‘ã¦å†ã‚³ãƒ³ãƒ‘イルã—ã¦ãã ã•ã„。"
+
+#: elf64-x86-64.c:3310
+msgid "%B: relocation %s against %s `%s' can not be used when making a shared object%s"
+msgstr "%B: å†é…ç½® %s (%s `%s' ã«å¯¾ã™ã‚‹) ã¯å…±æœ‰ã‚ªãƒ–ジェクト作æˆæ™‚ã«ã¯ä½¿ç”¨å‡ºæ¥ã¾ã›ã‚“%s"
+
+#: elf64-x86-64.c:3312
+msgid "%B: relocation %s against undefined %s `%s' can not be used when making a shared object%s"
+msgstr "%B: å†é…ç½® %s (未定義 %s `%s' ã«å¯¾ã™ã‚‹) ã¯å…±æœ‰ã‚ªãƒ–ジェクト作æˆæ™‚ã«ã¯ä½¿ç”¨å‡ºæ¥ã¾ã›ã‚“%s"
+
+#: elfcode.h:827
+#, c-format
+msgid "warning: %s has a corrupt string table index - ignoring"
+msgstr "警告: %s ã¯ç ´æã—ãŸæ–‡å­—列表索引をæŒã£ã¦ã„ã¾ã™ã€‚無視ã—ã¦ã„ã¾ã™"
+
+#: elfcode.h:1237
+#, c-format
+msgid "%s: version count (%ld) does not match symbol count (%ld)"
+msgstr "%s: ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‚«ã‚¦ãƒ³ãƒˆ (%ld) ãŒã‚·ãƒ³ãƒœãƒ«ã‚«ã‚¦ãƒ³ãƒˆ (%ld) ã¨ä¸€è‡´ã—ã¾ã›ã‚“"
+
+#: elfcode.h:1491
+#, c-format
+msgid "%s(%s): relocation %d has invalid symbol index %ld"
+msgstr "%s(%s): å†é…ç½® %d ãŒç„¡åŠ¹ãªã‚·ãƒ³ãƒœãƒ«ç´¢å¼• %ld ã‚’æŒã£ã¦ã„ã¾ã™"
+
+#: elfcore.h:312
+msgid "Warning: %B is truncated: expected core file size >= %lu, found: %lu."
+msgstr "警告: %B ã¯åˆ‡ã‚Šè©°ã‚られã¦ã„ã¾ã™: 予期ã•ã‚Œã‚‹ã‚³ã‚¢ãƒ•ã‚¡ã‚¤ãƒ«ã‚µã‚¤ã‚º >= %lu。見ã¤ã‹ã£ãŸã‚µã‚¤ã‚º: %lu。"
+
+#: elflink.c:1119
+msgid "%s: TLS definition in %B section %A mismatches non-TLS definition in %B section %A"
+msgstr "%s: %B 内セクション %A ã® TLS 定義ã¯ã€%B 内セクション %A ã®éž TLS 定義ã¨ä¸€è‡´ã—ã¾ã›ã‚“"
+
+#: elflink.c:1123
+msgid "%s: TLS reference in %B mismatches non-TLS reference in %B"
+msgstr "%s: %B 内㮠TLS å‚照㯠%B 内ã®éž TLS å‚ç…§ã¨ä¸€è‡´ã—ã¾ã›ã‚“"
+
+#: elflink.c:1127
+msgid "%s: TLS definition in %B section %A mismatches non-TLS reference in %B"
+msgstr "%s: %B 内セクション %A ã® TLS 定義㯠%B 内ã®éž TLS å‚ç…§ã¨ä¸€è‡´ã—ã¾ã›ã‚“"
+
+#: elflink.c:1131
+msgid "%s: TLS reference in %B mismatches non-TLS definition in %B section %A"
+msgstr "%s: %B 内㮠TLS å‚照㯠%B 内セクション %A ã®éž TLS 定義ã¨ä¸€è‡´ã—ã¾ã›ã‚“"
+
+#: elflink.c:1764
+msgid "%B: unexpected redefinition of indirect versioned symbol `%s'"
+msgstr "%B: 間接ãƒãƒ¼ã‚¸ãƒ§ãƒ³ä»˜ãシンボル `%s' ã®äºˆæœŸã—ãªã„å†å®šç¾©ã§ã™"
+
+#: elflink.c:2077
+msgid "%B: version node not found for symbol %s"
+msgstr "%B: シンボル %s 用ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ãƒŽãƒ¼ãƒ‰ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“"
+
+#: elflink.c:2167
+msgid "%B: bad reloc symbol index (0x%lx >= 0x%lx) for offset 0x%lx in section `%A'"
+msgstr "%B: 誤ã£ãŸå†é…置シンボル索引 (0x%lx >= 0x%lx) (オフセット 0x%lxã€ã‚»ã‚¯ã‚·ãƒ§ãƒ³ `%A' 内用) ã§ã™"
+
+#: elflink.c:2178
+msgid "%B: non-zero symbol index (0x%lx) for offset 0x%lx in section `%A' when the object file has no symbol table"
+msgstr "%B: オブジェクトファイルã«ã‚·ãƒ³ãƒœãƒ«è¡¨ãŒç„¡ã„ã«ã‚‚ã‹ã‹ã‚らãšã€ 0 ã§ãªã„シンボル索引 (0x%lx) (オフセット 0x%lxã€ã‚»ã‚¯ã‚·ãƒ§ãƒ³ `%A' 内) ãŒã‚ã‚Šã¾ã™"
+
+#: elflink.c:2368
+msgid "%B: relocation size mismatch in %B section %A"
+msgstr "%B: å†é…置サイズãŒä¸€è‡´ã—ã¾ã›ã‚“ (%B 内セクション %A)"
+
+#: elflink.c:2663
+#, c-format
+msgid "warning: type and size of dynamic symbol `%s' are not defined"
+msgstr "警告: 動的シンボル `%s' ã®åž‹ã¨ã‚µã‚¤ã‚ºãŒå®šç¾©ã•ã‚Œã¦ã„ã¾ã›ã‚“"
+
+#: elflink.c:3421
+msgid "%P: alternate ELF machine code found (%d) in %B, expecting %d\n"
+msgstr "%P: 代替 ELF マシンコード (%d) ㌠%B 内ã§è¦‹ã¤ã‹ã‚Šã¾ã—ãŸã€‚予期ã•ã‚Œã‚‹ã®ã¯ %d ã§ã™\n"
+
+#: elflink.c:4067
+msgid "%B: %s: invalid version %u (max %d)"
+msgstr "%B: %s: 無効ãªãƒãƒ¼ã‚¸ãƒ§ãƒ³ %u (最大 %d)"
+
+#: elflink.c:4103
+msgid "%B: %s: invalid needed version %d"
+msgstr "%B: %s: 無効ãªå¿…è¦ã¨ã•ã‚Œã‚‹ãƒãƒ¼ã‚¸ãƒ§ãƒ³ %d ã§ã™"
+
+#: elflink.c:4299
+msgid "Warning: alignment %u of common symbol `%s' in %B is greater than the alignment (%u) of its section %A"
+msgstr "警告: 整列 %u (共通シンボル `%s' ã®ã€%B 内) ã¯æ•´åˆ— %u (セクション %A) より大ãã„ã§ã™"
+
+#: elflink.c:4305
+msgid "Warning: alignment %u of symbol `%s' in %B is smaller than %u in %B"
+msgstr "警告: 整列 %u (シンボル `%s' ã®ã€%B 内) ㌠%u (%B 内) よりå°ã•ã„ã§ã™"
+
+#: elflink.c:4320
+msgid "Warning: size of symbol `%s' changed from %lu in %B to %lu in %B"
+msgstr "警告: シンボル `%s' ã®ã‚µã‚¤ã‚ºãŒ %lu (%B 内) ã‹ã‚‰ %lu (%B 内) ã«å¤‰æ›´ã•ã‚Œã¾ã—ãŸ"
+
+#: elflink.c:4489
+msgid "%B: undefined reference to symbol '%s'"
+msgstr "%B: シンボル '%s' ã¸ã®æœªå®šç¾©å‚ç…§ã§ã™"
+
+#: elflink.c:4492
+msgid "note: '%s' is defined in DSO %B so try adding it to the linker command line"
+msgstr "注: '%s' 㯠DSO %B 内ã§å®šç¾©ã•ã‚Œã¦ã„ã‚‹ã®ã§ãƒªãƒ³ã‚«ã®ã‚³ãƒžãƒ³ãƒ‰ãƒ©ã‚¤ãƒ³ã«è¿½åŠ ã—ã¦ã¿ã¦ãã ã•ã„"
+
+#: elflink.c:5795
+#, c-format
+msgid "%s: undefined version: %s"
+msgstr "%s: 未定義ãƒãƒ¼ã‚¸ãƒ§ãƒ³: %s"
+
+#: elflink.c:5863
+msgid "%B: .preinit_array section is not allowed in DSO"
+msgstr "%B: .preinit_array セクション㯠DSO 内ã§ã¯è¨±å¯ã•ã‚Œã¦ã„ã¾ã›ã‚“"
+
+#: elflink.c:7617
+#, c-format
+msgid "undefined %s reference in complex symbol: %s"
+msgstr ""
+
+#: elflink.c:7771
+#, c-format
+msgid "unknown operator '%c' in complex symbol"
+msgstr ""
+
+#: elflink.c:8110 elflink.c:8127 elflink.c:8164 elflink.c:8181
+msgid "%B: Unable to sort relocs - they are in more than one size"
+msgstr "%B: å†é…置をソートã§ãã¾ã›ã‚“。2個以上ã®ã‚µã‚¤ã‚ºã«ãªã£ã¦ã„ã¾ã™"
+
+#: elflink.c:8141 elflink.c:8195
+msgid "%B: Unable to sort relocs - they are of an unknown size"
+msgstr "%B: å†é…置をソートã§ãã¾ã›ã‚“。ä¸æ˜Žãªã‚µã‚¤ã‚ºã§ã™ã€‚"
+
+#: elflink.c:8246
+msgid "Not enough memory to sort relocations"
+msgstr "å†é…置をソートã™ã‚‹ãŸã‚ã®å分ãªãƒ¡ãƒ¢ãƒªãŒã‚ã‚Šã¾ã›ã‚“"
+
+#: elflink.c:8439
+msgid "%B: Too many sections: %d (>= %d)"
+msgstr "%B: セクションãŒå¤šã™ãŽã¾ã™: %d (>= %d)"
+
+#: elflink.c:8686
+msgid "%B: internal symbol `%s' in %B is referenced by DSO"
+msgstr "%B: 内部シンボル `%s' (%B 内) 㯠DSO ã«ã‚ˆã£ã¦å‚ç…§ã•ã‚Œã¦ã„ã¾ã™"
+
+#: elflink.c:8688
+msgid "%B: hidden symbol `%s' in %B is referenced by DSO"
+msgstr "%B: éš ã•ã‚ŒãŸã‚·ãƒ³ãƒœãƒ« `%s' (%B 内) 㯠DSO ã«ã‚ˆã£ã¦å‚ç…§ã•ã‚Œã¦ã„ã¾ã™"
+
+#: elflink.c:8690
+msgid "%B: local symbol `%s' in %B is referenced by DSO"
+msgstr "%B: 局所シンボル `%s' (%B 内) 㯠DSO ã«ã‚ˆã£ã¦å‚ç…§ã•ã‚Œã¦ã„ã¾ã™"
+
+#: elflink.c:8785
+msgid "%B: could not find output section %A for input section %A"
+msgstr "%B: 出力セクション %A (入力セクション %A 用) ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸ"
+
+#: elflink.c:8908
+msgid "%B: protected symbol `%s' isn't defined"
+msgstr "%B: ä¿è­·ã•ã‚ŒãŸã‚·ãƒ³ãƒœãƒ« `%s' ãŒå®šç¾©ã•ã‚Œã¦ã„ã¾ã›ã‚“"
+
+#: elflink.c:8910
+msgid "%B: internal symbol `%s' isn't defined"
+msgstr "%B: 内部シンボル `%s' ãŒå®šç¾©ã•ã‚Œã¦ã„ã¾ã›ã‚“"
+
+#: elflink.c:8912
+msgid "%B: hidden symbol `%s' isn't defined"
+msgstr "%B: éš ã•ã‚ŒãŸã‚·ãƒ³ãƒœãƒ« `%s' ãŒå®šç¾©ã•ã‚Œã¦ã„ã¾ã›ã‚“"
+
+#: elflink.c:9441
+msgid "error: %B: size of section %A is not multiple of address size"
+msgstr "エラー: %B: セクション %A ã®ã‚µã‚¤ã‚ºãŒã‚¢ãƒ‰ãƒ¬ã‚¹ã‚µã‚¤ã‚ºã®å€æ•°ã§ã¯ã‚ã‚Šã¾ã›ã‚“"
+
+#: elflink.c:9488
+msgid "error: %B contains a reloc (0x%s) for section %A that references a non-existent global symbol"
+msgstr "エラー: %B ã«ã¯å­˜åœ¨ã—ãªã„大域シンボルをå‚ç…§ã™ã‚‹å†é…ç½® (0x%s) (セクション %A 用) ãŒå«ã¾ã‚Œã¾ã™"
+
+#: elflink.c:10223
+msgid "%A has both ordered [`%A' in %B] and unordered [`%A' in %B] sections"
+msgstr "%A ã«ã¯é †åºä»˜ã [`%A' (%B 内) ] ã¨é †åºç„¡ã— [`%A' (%B 内)] セクションã®ä¸¡æ–¹ãŒã‚ã‚Šã¾ã™"
+
+#: elflink.c:10228
+#, c-format
+msgid "%A has both ordered and unordered sections"
+msgstr "%A ã«ã¯é †åºä»˜ãã¨é †åºç„¡ã—セクションã®ä¸¡æ–¹ãŒã‚ã‚Šã¾ã™"
+
+#: elflink.c:10793
+msgid "%B: file class %s incompatible with %s"
+msgstr "%B: ファイルクラス %s 㯠%s ã¨äº’æ›æ€§ãŒã‚ã‚Šã¾ã›ã‚“"
+
+#: elflink.c:11104 elflink.c:11148
+msgid "%B: could not find output section %s"
+msgstr "%B: 出力セクション %s ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸ"
+
+#: elflink.c:11109
+#, c-format
+msgid "warning: %s section has zero size"
+msgstr "警告: %s セクションã®ã‚µã‚¤ã‚ºãŒ 0 ã§ã™"
+
+#: elflink.c:11214
+msgid "%P: warning: creating a DT_TEXTREL in a shared object.\n"
+msgstr "%P: 警告: 共有オブジェクト内㫠DT_TEXTREL を作æˆã—ã¦ã„ã¾ã™\n"
+
+#: elflink.c:11401
+msgid "%P%X: can not read symbols: %E\n"
+msgstr "%P%X: シンボルを読ã¿è¾¼ã‚ã¾ã›ã‚“: %E\n"
+
+#: elflink.c:11750
+msgid "Removing unused section '%s' in file '%B'"
+msgstr "使用ã•ã‚Œãªã„セクション '%s' (ファイル '%B' 内) を削除ã—ã¦ã„ã¾ã™"
+
+#: elflink.c:11962
+msgid "Warning: gc-sections option ignored"
+msgstr "警告: gc-sections オプションã¯ç„¡è¦–ã•ã‚Œã¾ã—ãŸ"
+
+#: elflink.c:12511
+msgid "%B: ignoring duplicate section `%A'"
+msgstr "%B: é‡è¤‡ã—ãŸã‚»ã‚¯ã‚·ãƒ§ãƒ³ `%A' を無視ã—ã¦ã„ã¾ã™"
+
+#: elflink.c:12518 elflink.c:12525
+msgid "%B: duplicate section `%A' has different size"
+msgstr "%B: é‡è¤‡ã—ãŸã‚»ã‚¯ã‚·ãƒ§ãƒ³ `%A' ãŒç•°ãªã‚‹ã‚µã‚¤ã‚ºã§ã™"
+
+#: elflink.c:12533 elflink.c:12538
+msgid "%B: warning: could not read contents of section `%A'"
+msgstr "%B: 警告: セクション `%A' ã®ä¸­èº«ã‚’読ã¿è¾¼ã‚ã¾ã›ã‚“"
+
+#: elflink.c:12542
+msgid "%B: warning: duplicate section `%A' has different contents"
+msgstr "%B: 警告: é‡è¤‡ã—ãŸã‚»ã‚¯ã‚·ãƒ§ãƒ³ `%A' ã®ä¸­èº«ãŒç•°ãªã‚Šã¾ã™"
+
+#: elflink.c:12643 linker.c:3086
+msgid "%F%P: already_linked_table: %E\n"
+msgstr "%F%P: already_linked_table: %E\n"
+
+#: elfxx-mips.c:1221
+msgid "static procedure (no name)"
+msgstr "é™çš„プロシージャ(åå‰ç„¡ã—)"
+
+#: elfxx-mips.c:5628
+msgid "%B: %A+0x%lx: Direct jumps between ISA modes are not allowed; consider recompiling with interlinking enabled."
+msgstr "%B: %A+0x%lx: ISA モード間ã®ç›´æŽ¥ã®ã‚¸ãƒ£ãƒ³ãƒ—ã¯è¨±å¯ã•ã‚Œã¦ã„ã¾ã›ã‚“。相互リンクを有効ã«ã—ã¦å†ã‚³ãƒ³ãƒ‘イルã—ã¦ã¿ã¦ãã ã•ã„"
+
+#: elfxx-mips.c:6288 elfxx-mips.c:6511
+msgid "%B: Warning: bad `%s' option size %u smaller than its header"
+msgstr "%B: 警告: é–“é•ã£ãŸ `%s' オプションサイズ %u ã§ã™ (ヘッダよりå°ã•ã„ã§ã™)"
+
+#: elfxx-mips.c:7262 elfxx-mips.c:7387
+msgid "%B: Warning: cannot determine the target function for stub section `%s'"
+msgstr "%B: 警告: スタブセクション `%s' 用ã®ã‚¿ãƒ¼ã‚²ãƒƒãƒˆé–¢æ•°ã‚’決定ã§ãã¾ã›ã‚“"
+
+#: elfxx-mips.c:7516
+msgid "%B: Malformed reloc detected for section %s"
+msgstr "%B: セクション %s ã«å¯¾ã™ã‚‹ãŠã‹ã—ãªå†é…ç½®ãŒæ¤œå‡ºã•ã‚Œã¾ã—ãŸ"
+
+#: elfxx-mips.c:7556
+msgid "%B: GOT reloc at 0x%lx not expected in executables"
+msgstr "%B: ä½ç½® 0x%lx ã«å®Ÿè¡Œãƒ•ã‚¡ã‚¤ãƒ«å†…ã§ã¯äºˆæœŸã•ã‚Œãªã„ GOT å†é…ç½®ãŒã‚ã‚Šã¾ã™"
+
+#: elfxx-mips.c:7678
+msgid "%B: CALL16 reloc at 0x%lx not against global symbol"
+msgstr "%B: ä½ç½® 0x%lx ã® CALL16 å†é…ç½®ã¯å¤§åŸŸã‚·ãƒ³ãƒœãƒ«ã«å¯¾ã—ã¦ã§ã¯ã‚ã‚Šã¾ã›ã‚“"
+
+#: elfxx-mips.c:8372
+#, c-format
+msgid "non-dynamic relocations refer to dynamic symbol %s"
+msgstr "éžå‹•çš„å†é…ç½®ãŒå‹•çš„å†é…ç½® %s ã‚’å‚ç…§ã—ã¦ã„ã¾ã™"
+
+#: elfxx-mips.c:9075
+msgid "%B: Can't find matching LO16 reloc against `%s' for %s at 0x%lx in section `%A'"
+msgstr ""
+
+#: elfxx-mips.c:9214
+msgid "small-data section exceeds 64KB; lower small-data size limit (see option -G)"
+msgstr ""
+
+#: elfxx-mips.c:12038
+#, c-format
+msgid "%s: illegal section name `%s'"
+msgstr "%s: ä¸æ­£ãªã‚»ã‚¯ã‚·ãƒ§ãƒ³å `%s' ã§ã™"
+
+#: elfxx-mips.c:12417 elfxx-mips.c:12443
+msgid "Warning: %B uses -msingle-float, %B uses -mdouble-float"
+msgstr "警告: %B 㯠-msingle-float を使用ã—ã¦ã„ã¾ã™ã€‚%B 㯠-mdouble-float を使用ã—ã¦ã„ã¾ã™"
+
+#: elfxx-mips.c:12429 elfxx-mips.c:12485
+msgid "Warning: %B uses -msingle-float, %B uses -mips32r2 -mfp64"
+msgstr "警告: %B 㯠-msingle-float を使用ã—ã¦ã„ã¾ã™ã€‚%B 㯠-mips32r2 -mfp64 を使用ã—ã¦ã„ã¾ã™"
+
+#: elfxx-mips.c:12455 elfxx-mips.c:12491
+msgid "Warning: %B uses -mdouble-float, %B uses -mips32r2 -mfp64"
+msgstr "警告: %B 㯠-mdouble-float を使用ã—ã¦ã„ã¾ã™ã€‚%B 㯠-mips32r2 -mfp64 を使用ã—ã¦ã„ã¾ã™"
+
+#: elfxx-mips.c:12533
+msgid "%B: endianness incompatible with that of the selected emulation"
+msgstr "%B: é¸æŠžã—ãŸã‚¨ãƒŸãƒ¥ãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³ã¨ã‚¨ãƒ³ãƒ‡ã‚£ã‚¢ãƒ³ã®äº’æ›æ€§ãŒã‚ã‚Šã¾ã›ã‚“"
+
+#: elfxx-mips.c:12544
+msgid "%B: ABI is incompatible with that of the selected emulation"
+msgstr "%B: é¸æŠžã—ãŸã‚¨ãƒŸãƒ¥ãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³ã¨ABI ã®äº’æ›æ€§ãŒã‚ã‚Šã¾ã›ã‚“"
+
+#: elfxx-mips.c:12628
+msgid "%B: warning: linking abicalls files with non-abicalls files"
+msgstr "%B: 警告: abicalls ファイルã¨éž abicalls ファイルをリンクã—ã¦ã„ã¾ã™"
+
+#: elfxx-mips.c:12645
+msgid "%B: linking 32-bit code with 64-bit code"
+msgstr "%B: 32 ビットコード㨠64 ビットコードをリンクã—ã¦ã„ã¾ã™"
+
+#: elfxx-mips.c:12673
+msgid "%B: linking %s module with previous %s modules"
+msgstr "%B: %s モジュールをå‰ã® %s モジュールã¨ãƒªãƒ³ã‚¯ã—ã¦ã„ã¾ã™"
+
+#: elfxx-mips.c:12696
+msgid "%B: ABI mismatch: linking %s module with previous %s modules"
+msgstr "%B: ABI ãŒä¸€è‡´ã—ã¾ã›ã‚“: %s モジュールをå‰ã® %s モジュールã¨ãƒªãƒ³ã‚¯ã—ã¦ã„ã¾ã™"
+
+#: elfxx-mips.c:12860
+#, c-format
+msgid " [abi=O32]"
+msgstr " [abi=O32]"
+
+#: elfxx-mips.c:12862
+#, c-format
+msgid " [abi=O64]"
+msgstr " [abi=O64]"
+
+#: elfxx-mips.c:12864
+#, c-format
+msgid " [abi=EABI32]"
+msgstr " [abi=EABI32]"
+
+#: elfxx-mips.c:12866
+#, c-format
+msgid " [abi=EABI64]"
+msgstr " [abi=EABI64]"
+
+#: elfxx-mips.c:12868
+#, c-format
+msgid " [abi unknown]"
+msgstr " [abi unknown]"
+
+#: elfxx-mips.c:12870
+#, c-format
+msgid " [abi=N32]"
+msgstr " [abi=N32]"
+
+#: elfxx-mips.c:12872
+#, c-format
+msgid " [abi=64]"
+msgstr " [abi=64]"
+
+#: elfxx-mips.c:12874
+#, c-format
+msgid " [no abi set]"
+msgstr ""
+
+#: elfxx-mips.c:12895
+#, c-format
+msgid " [unknown ISA]"
+msgstr " [ä¸æ˜Žãª ISA]"
+
+#: elfxx-mips.c:12906
+#, c-format
+msgid " [not 32bitmode]"
+msgstr " [éž 32 ビットモード]"
+
+#: elfxx-sparc.c:595
+#, c-format
+msgid "invalid relocation type %d"
+msgstr "無効ãªå†é…置型 %d ã§ã™"
+
+#: i386linux.c:454 m68klinux.c:458 sparclinux.c:452
+#, c-format
+msgid "Output file requires shared library `%s'\n"
+msgstr "出力ファイルã¯å…±æœ‰ãƒ©ã‚¤ãƒ–ラリ `%s' ã‚’å¿…è¦ã¨ã—ã¦ã„ã¾ã™\n"
+
+#: i386linux.c:462 m68klinux.c:466 sparclinux.c:460
+#, c-format
+msgid "Output file requires shared library `%s.so.%s'\n"
+msgstr "出力ファイルã¯å…±æœ‰ãƒ©ã‚¤ãƒ–ラリ `%s.so.%s' ã‚’å¿…è¦ã¨ã—ã¦ã„ã¾ã™\n"
+
+#: i386linux.c:651 i386linux.c:701 m68klinux.c:658 m68klinux.c:706
+#: sparclinux.c:650 sparclinux.c:700
+#, c-format
+msgid "Symbol %s not defined for fixups\n"
+msgstr "シンボル %s 㯠fixup 用ã«å®šç¾©ã•ã‚Œã¦ã„ã¾ã›ã‚“\n"
+
+#: i386linux.c:725 m68klinux.c:730 sparclinux.c:724
+msgid "Warning: fixup count mismatch\n"
+msgstr "警告: fixup カウントãŒä¸€è‡´ã—ã¾ã›ã‚“\n"
+
+#: ieee.c:159
+#, c-format
+msgid "%s: string too long (%d chars, max 65535)"
+msgstr "%s: 文字列ãŒé•·ã™ãŽã¾ã™ (%d 文字, 最大 65535)"
+
+#: ieee.c:286
+#, c-format
+msgid "%s: unrecognized symbol `%s' flags 0x%x"
+msgstr "%s: シンボル `%s' フラグ 0x%x ã‚’èªè­˜ã§ãã¾ã›ã‚“"
+
+#: ieee.c:792
+msgid "%B: unimplemented ATI record %u for symbol %u"
+msgstr "%B: ATI レコード %u (シンボル %u 用) ã¯å®Ÿè£…ã•ã‚Œã¦ã„ã¾ã›ã‚“"
+
+#: ieee.c:816
+msgid "%B: unexpected ATN type %d in external part"
+msgstr "%B: 予期ã—ãªã„ ATN åž‹ %d ㌠external 部分ã«ã‚ã‚Šã¾ã™"
+
+#: ieee.c:838
+msgid "%B: unexpected type after ATN"
+msgstr "%B: ATN ã®å¾Œã«äºˆæœŸã—ãªã„åž‹ã§ã™"
+
+#: ihex.c:230
+msgid "%B:%d: unexpected character `%s' in Intel Hex file"
+msgstr "%B:%d: Intel Hex ファイル内ã«äºˆæœŸã—ãªã„文字 `%s' ãŒã‚ã‚Šã¾ã™"
+
+#: ihex.c:337
+msgid "%B:%u: bad checksum in Intel Hex file (expected %u, found %u)"
+msgstr "%B:%u: Intel Hex ファイル内ã®ãƒã‚§ãƒƒã‚¯ã‚µãƒ ãŒé–“é•ã£ã¦ã„ã¾ã™ (予期ã•ã‚Œã‚‹ã®ã¯ %uã€å®Ÿéš›ã¯ %u)"
+
+#: ihex.c:392
+msgid "%B:%u: bad extended address record length in Intel Hex file"
+msgstr "%B:%u: Intel Hex ファイル内ã«é–“é•ã£ãŸæ‹¡å¼µã‚¢ãƒ‰ãƒ¬ã‚¹ãƒ¬ã‚³ãƒ¼ãƒ‰ãŒã‚ã‚Šã¾ã™"
+
+#: ihex.c:409
+msgid "%B:%u: bad extended start address length in Intel Hex file"
+msgstr "%B:%u: Intel Hex ファイル内ã«é–“é•ã£ãŸæ‹¡å¼µé–‹å§‹ã‚¢ãƒ‰ãƒ¬ã‚¹é•·ãŒã‚ã‚Šã¾ã™"
+
+#: ihex.c:426
+msgid "%B:%u: bad extended linear address record length in Intel Hex file"
+msgstr "%B:%u: Intel Hex ファイル内ã«é–“é•ã£ãŸæ‹¡å¼µç·šå½¢ã‚¢ãƒ‰ãƒ¬ã‚¹ãƒ¬ã‚³ãƒ¼ãƒ‰é•·ãŒã‚ã‚Šã¾ã™"
+
+#: ihex.c:443
+msgid "%B:%u: bad extended linear start address length in Intel Hex file"
+msgstr "%B:%u: Intel Hex ファイル内ã«é–“é•ã£ãŸæ‹¡å¼µç·šå½¢é–‹å§‹ã‚¢ãƒ‰ãƒ¬ã‚¹é•·ãŒã‚ã‚Šã¾ã™"
+
+#: ihex.c:460
+msgid "%B:%u: unrecognized ihex type %u in Intel Hex file"
+msgstr "%B:%u: Intel Hex ファイル内ã§èªè­˜ã§ããªã„ ihex åž‹ %u ã§ã™"
+
+#: ihex.c:579
+msgid "%B: internal error in ihex_read_section"
+msgstr "%B: ihex_read_section 内ã§å†…部エラーã§ã™"
+
+#: ihex.c:613
+msgid "%B: bad section length in ihex_read_section"
+msgstr "%B: ihex_read_section 内ã§é–“é•ã£ãŸã‚»ã‚¯ã‚·ãƒ§ãƒ³é•·ã§ã™"
+
+#: ihex.c:826
+#, c-format
+msgid "%s: address 0x%s out of range for Intel Hex file"
+msgstr "%s: アドレス 0x%s 㯠Intel Hex ファイルã®ç¯„囲外ã§ã™"
+
+#: libbfd.c:863
+msgid "%B: unable to get decompressed section %A"
+msgstr "%B: 伸張ã—ãŸã‚»ã‚¯ã‚·ãƒ§ãƒ³ %A ã‚’å–å¾—ã§ãã¾ã›ã‚“"
+
+#: libbfd.c:1043
+#, c-format
+msgid "Deprecated %s called at %s line %d in %s\n"
+msgstr "廃止ã•ã‚ŒãŸ %s ãŒå‘¼ã°ã‚Œã¾ã—㟠(ä½ç½® %sã€è¡Œ %d〠%s 内)\n"
+
+#: libbfd.c:1046
+#, c-format
+msgid "Deprecated %s called\n"
+msgstr "廃止ã•ã‚ŒãŸ %s ãŒå‘¼ã°ã‚Œã¾ã—ãŸ\n"
+
+#: linker.c:1859
+msgid "%B: indirect symbol `%s' to `%s' is a loop"
+msgstr "%B: 間接シンボル `%s' (`%s' ã¸) ãŒå¾ªç’°ã—ã¦ã„ã¾ã™"
+
+#: linker.c:2726
+#, c-format
+msgid "Attempt to do relocatable link with %s input and %s output"
+msgstr "%s 入力㨠%s 出力をå†é…ç½®å¯èƒ½ãƒªãƒ³ã‚¯ã—よã†ã¨è©¦ã¿ã¾ã—ãŸ"
+
+#: linker.c:3053
+msgid "%B: warning: ignoring duplicate section `%A'\n"
+msgstr "%B: 警告: é‡è¤‡ã—ã¦ã„るセクション `%A' を無視ã—ã¦ã„ã¾ã™\n"
+
+#: linker.c:3067
+msgid "%B: warning: duplicate section `%A' has different size\n"
+msgstr "%B: 警告: é‡è¤‡ã—ã¦ã„るセクション `%A' ãŒç•°ãªã‚‹ã‚µã‚¤ã‚ºã§ã™\n"
+
+#: mach-o.c:381
+msgid "bfd_mach_o_canonicalize_symtab: unable to load symbols"
+msgstr "bfd_mach_o_canonicalize_symtab: シンボルをロードã§ãã¾ã›ã‚“"
+
+#: mach-o.c:1253
+#, c-format
+msgid "unable to write unknown load command 0x%lx"
+msgstr "ä¸æ˜Žãªãƒ­ãƒ¼ãƒ‰ã‚³ãƒžãƒ³ãƒ‰ 0x%lx を書ãè¾¼ã‚ã¾ã›ã‚“"
+
+#: mach-o.c:1654
+#, c-format
+msgid "bfd_mach_o_read_symtab_symbol: unable to read %d bytes at %lu"
+msgstr "bfd_mach_o_read_symtab_symbol: %d ãƒã‚¤ãƒˆ(ä½ç½® %lu ) を読ã¿è¾¼ã‚ã¾ã›ã‚“"
+
+#: mach-o.c:1671
+#, c-format
+msgid "bfd_mach_o_read_symtab_symbol: symbol name out of range (%lu >= %lu)"
+msgstr "bfd_mach_o_read_symtab_symbol: シンボルåãŒç¯„囲外 (%lu >= %lu) ã§ã™"
+
+#: mach-o.c:1756
+#, c-format
+msgid "bfd_mach_o_read_symtab_symbol: symbol \"%s\" specified invalid section %d (max %lu): setting to undefined"
+msgstr "bfd_mach_o_read_symtab_symbol: シンボル \"%s\" ãŒç„¡åŠ¹ãªã‚»ã‚¯ã‚·ãƒ§ãƒ³ %d (最大 %lu) ã«æŒ‡å®šã•ã‚Œã¦ã„ã¾ã™: 未定義ã«è¨­å®šã•ã‚Œã¾ã—ãŸ"
+
+#: mach-o.c:1764
+#, c-format
+msgid "bfd_mach_o_read_symtab_symbol: symbol \"%s\" is unsupported 'indirect' reference: setting to undefined"
+msgstr "bfd_mach_o_read_symtab_symbol: シンボル \"%s\" ã¯ã‚µãƒãƒ¼ãƒˆã•ã‚Œã¦ã„ãªã„ '間接' å‚ç…§ã§ã™: 未定義ã«è¨­å®šã•ã‚Œã¾ã—ãŸ"
+
+#: mach-o.c:1770
+#, c-format
+msgid "bfd_mach_o_read_symtab_symbol: symbol \"%s\" specified invalid type field 0x%x: setting to undefined"
+msgstr "bfd_mach_o_read_symtab_symbol: シンボル \"%s\" ã¯ç„¡åŠ¹ãªã‚¿ã‚¤ãƒ—フィールド 0x%x ã«æŒ‡å®šã•ã‚Œã¦ã„ã¾ã™: 未定義ã«è¨­å®šã•ã‚Œã¾ã—ãŸ"
+
+#: mach-o.c:1840
+msgid "bfd_mach_o_read_symtab_symbols: unable to allocate memory for symbols"
+msgstr "bfd_mach_o_read_symtab_symbols: シンボル用ã®ãƒ¡ãƒ¢ãƒªã‚’é…ç½®ã§ãã¾ã›ã‚“"
+
+#: mach-o.c:1874
+#, c-format
+msgid "bfd_mach_o_read_dysymtab_symbol: unable to read %lu bytes at %lu"
+msgstr "bfd_mach_o_read_dysymtab_symbol: %lu ãƒã‚¤ãƒˆ (ä½ç½® %lu) を読ã¿è¾¼ã‚ã¾ã›ã‚“"
+
+#: mach-o.c:2556
+#, c-format
+msgid "unable to read unknown load command 0x%lx"
+msgstr "ä¸æ˜Žãªã‚³ãƒžãƒ³ãƒ‰ 0x%lx をロードã§ãã¾ã›ã‚“"
+
+#: mach-o.c:2736
+#, c-format
+msgid "bfd_mach_o_scan: unknown architecture 0x%lx/0x%lx"
+msgstr "bfd_mach_o_scan: ä¸æ˜Žãªã‚¢ãƒ¼ã‚­ãƒ†ã‚¯ãƒãƒ£ 0x%lx/0x%lx ã§ã™"
+
+#: mach-o.c:2832
+#, c-format
+msgid "unknown header byte-order value 0x%lx"
+msgstr "ä¸æ˜Žãªãƒ˜ãƒƒãƒ€ãƒã‚¤ãƒˆé †ã®å€¤ 0x%lx ã§ã™"
+
+#: mach-o.c:3402
+msgid "Mach-O header:\n"
+msgstr "Mach-O ヘッダ:\n"
+
+#: mach-o.c:3403
+#, c-format
+msgid " magic : %08lx\n"
+msgstr " マジック番å·: %08lx\n"
+
+#: mach-o.c:3404
+#, c-format
+msgid " cputype : %08lx (%s)\n"
+msgstr " CPU タイプ : %08lx (%s)\n"
+
+#: mach-o.c:3406
+#, c-format
+msgid " cpusubtype: %08lx\n"
+msgstr " CPU サブタイプ: %08lx\n"
+
+#: mach-o.c:3407
+#, c-format
+msgid " filetype : %08lx (%s)\n"
+msgstr " ファイルタイプ: %08lx (%s)\n"
+
+#: mach-o.c:3410
+#, c-format
+msgid " ncmds : %08lx (%lu)\n"
+msgstr " コマンド数 : %08lx (%lu)\n"
+
+#: mach-o.c:3411
+#, c-format
+msgid " sizeofcmds: %08lx\n"
+msgstr " コマンドサイズ: %08lx\n"
+
+#: mach-o.c:3412
+#, c-format
+msgid " flags : %08lx ("
+msgstr " フラグ : %08lx ("
+
+#: mach-o.c:3414 vms-alpha.c:7671
+msgid ")\n"
+msgstr ")\n"
+
+#: mach-o.c:3415
+#, c-format
+msgid " reserved : %08x\n"
+msgstr " 予約 : %08x\n"
+
+#: mach-o.c:3425
+msgid "Segments and Sections:\n"
+msgstr "セグメントã¨ã‚»ã‚¯ã‚·ãƒ§ãƒ³:\n"
+
+#: mach-o.c:3426
+msgid " #: Segment name Section name Address\n"
+msgstr " #: セグメントå セクションå アドレス\n"
+
+#: merge.c:832
+#, c-format
+msgid "%s: access beyond end of merged section (%ld)"
+msgstr "%s: ä½µåˆã—ãŸã‚»ã‚¯ã‚·ãƒ§ãƒ³ã®çµ‚端 (%ld) を超ãˆãŸã‚¢ã‚¯ã‚»ã‚¹ã§ã™"
+
+#: mmo.c:456
+#, c-format
+msgid "%s: No core to allocate section name %s\n"
+msgstr "%s: セクションå %s を割り当ã¦ã‚‹ãŸã‚ã®ã‚³ã‚¢ãŒã‚ã‚Šã¾ã›ã‚“\n"
+
+#: mmo.c:531
+#, c-format
+msgid "%s: No core to allocate a symbol %d bytes long\n"
+msgstr "%s: %d ãƒã‚¤ãƒˆé•·ã®ã‚·ãƒ³ãƒœãƒ«ã‚’割り当ã¦ã‚‹ãŸã‚ã®ã‚³ã‚¢ãŒã‚ã‚Šã¾ã›ã‚“\n"
+
+#: mmo.c:1187
+#, c-format
+msgid "%s: invalid mmo file: initialization value for $255 is not `Main'\n"
+msgstr "%s: 無効㪠mmo ファイル: $255 ã®åˆæœŸå€¤ãŒ `Main' ã§ã¯ã‚ã‚Šã¾ã›ã‚“\n"
+
+#: mmo.c:1332
+#, c-format
+msgid "%s: unsupported wide character sequence 0x%02X 0x%02X after symbol name starting with `%s'\n"
+msgstr "%s: サãƒãƒ¼ãƒˆã•ã‚Œã¦ã„ãªã„ワイド文字シーケンス 0x%02X 0x%02X ㌠`%s' ã§é–‹å§‹ã™ã‚‹ã‚·ãƒ³ãƒœãƒ«åã®å¾Œã«ã‚ã‚Šã¾ã™\n"
+
+#: mmo.c:1565
+#, c-format
+msgid "%s: invalid mmo file: unsupported lopcode `%d'\n"
+msgstr "%s: 無効㪠mmo ファイルã§ã™: サãƒãƒ¼ãƒˆã•ã‚Œã¦ã„ãªã„ lopcode `%d' ã§ã™\n"
+
+#: mmo.c:1575
+#, c-format
+msgid "%s: invalid mmo file: expected YZ = 1 got YZ = %d for lop_quote\n"
+msgstr "%s: 無効㪠mmo ファイルã§ã™: lop_quote ã¨ã—ã¦äºˆæœŸã•ã‚Œã‚‹ã®ã¯YZ = 1 ã§ã™ãŒã€å–å¾—ã•ã‚ŒãŸã®ã¯ YZ = %d ã§ã™\n"
+
+#: mmo.c:1611
+#, c-format
+msgid "%s: invalid mmo file: expected z = 1 or z = 2, got z = %d for lop_loc\n"
+msgstr "%s: 無効㪠mmo ファイルã§ã™: lop_loc ã¨ã—ã¦äºˆæœŸã•ã‚Œã‚‹ã®ã¯ z = 1 ã¾ãŸã¯ z = 2 ã§ã™ãŒã€å–å¾—ã•ã‚ŒãŸã®ã¯ z = %d ã§ã™\n"
+
+#: mmo.c:1657
+#, c-format
+msgid "%s: invalid mmo file: expected z = 1 or z = 2, got z = %d for lop_fixo\n"
+msgstr "%s: 無効㪠mmo ファイルã§ã™: lop_fixo ã¨ã—ã¦äºˆæœŸã•ã‚Œã‚‹ã®ã¯ z = 1 ã¾ãŸã¯ z = 2ã§ã™ãŒã€å–å¾—ã•ã‚ŒãŸã®ã¯ got z = %d ã§ã™\n"
+
+#: mmo.c:1696
+#, c-format
+msgid "%s: invalid mmo file: expected y = 0, got y = %d for lop_fixrx\n"
+msgstr "%s: 無効㪠mmo ファイルã§ã™: lop_fixrx ã¨ã—ã¦äºˆæœŸã•ã‚Œã‚‹ã®ã¯ y = 0 ã§ã™ãŒã€å–å¾—ã•ã‚ŒãŸã®ã¯ y = %d ã§ã™\n"
+
+#: mmo.c:1705
+#, c-format
+msgid "%s: invalid mmo file: expected z = 16 or z = 24, got z = %d for lop_fixrx\n"
+msgstr "%s: 無効㪠mmo ファイルã§ã™: lop_fixrx ã¨ã—ã¦äºˆæœŸã•ã‚Œã‚‹ã®ã¯ z = 16 ã¾ãŸã¯ z = 24 ã§ã™ãŒã€å–å¾—ã•ã‚ŒãŸã®ã¯ z = %d ã§ã™\n"
+
+#: mmo.c:1728
+#, c-format
+msgid "%s: invalid mmo file: leading byte of operand word must be 0 or 1, got %d for lop_fixrx\n"
+msgstr "%s: 無効㪠mmo ファイルã§ã™: lop_fixrx 用ã®è¢«æ¼”ç®—å­ãƒ¯ãƒ¼ãƒ‰ã®å…ˆé ­ãƒã‚¤ãƒˆã¯ 0 ã¾ãŸã¯ 1 ã§ãªã‘ã‚Œã°ã„ã‘ã¾ã›ã‚“ãŒã€å–å¾—ã•ã‚ŒãŸã®ã¯ %d ã§ã™\n"
+
+#: mmo.c:1751
+#, c-format
+msgid "%s: cannot allocate file name for file number %d, %d bytes\n"
+msgstr ""
+
+#: mmo.c:1771
+#, c-format
+msgid "%s: invalid mmo file: file number %d `%s', was already entered as `%s'\n"
+msgstr ""
+
+#: mmo.c:1784
+#, c-format
+msgid "%s: invalid mmo file: file name for number %d was not specified before use\n"
+msgstr ""
+
+#: mmo.c:1890
+#, c-format
+msgid "%s: invalid mmo file: fields y and z of lop_stab non-zero, y: %d, z: %d\n"
+msgstr ""
+
+#: mmo.c:1926
+#, c-format
+msgid "%s: invalid mmo file: lop_end not last item in file\n"
+msgstr "%s: 無効㪠mmo ファイルã§ã™: lop_end ãŒãƒ•ã‚¡ã‚¤ãƒ«å†…ã®æœ€å¾Œã®è¦ç´ ã§ã¯ã‚ã‚Šã¾ã›ã‚“\n"
+
+#: mmo.c:1939
+#, c-format
+msgid "%s: invalid mmo file: YZ of lop_end (%ld) not equal to the number of tetras to the preceding lop_stab (%ld)\n"
+msgstr ""
+
+#: mmo.c:2649
+#, c-format
+msgid "%s: invalid symbol table: duplicate symbol `%s'\n"
+msgstr "%s: 無効ãªã‚·ãƒ³ãƒœãƒ«è¡¨ã§ã™: é‡è¤‡ã—ãŸã‚·ãƒ³ãƒœãƒ« `%s' ãŒã‚ã‚Šã¾ã™\n"
+
+#: mmo.c:2889
+#, c-format
+msgid "%s: Bad symbol definition: `Main' set to %s rather than the start address %s\n"
+msgstr ""
+
+#: mmo.c:2981
+#, c-format
+msgid "%s: warning: symbol table too large for mmo, larger than 65535 32-bit words: %d. Only `Main' will be emitted.\n"
+msgstr ""
+
+#: mmo.c:3026
+#, c-format
+msgid "%s: internal error, symbol table changed size from %d to %d words\n"
+msgstr "%s: 内部エラーã€ã‚·ãƒ³ãƒœãƒ«è¡¨ã®ã‚µã‚¤ã‚ºãŒ %d ワードã‹ã‚‰ %d ワードã«å¤‰æ›´ã•ã‚Œã¾ã—ãŸ\n"
+
+#: mmo.c:3078
+#, c-format
+msgid "%s: internal error, internal register section %s had contents\n"
+msgstr "%s: 内部エラーã€å†…部レジスタセクション %s ã¯å†…容をæŒã¡ã¾ã™\n"
+
+#: mmo.c:3129
+#, c-format
+msgid "%s: no initialized registers; section length 0\n"
+msgstr "%s: åˆæœŸåŒ–ã•ã‚ŒãŸãƒ¬ã‚¸ã‚¹ã‚¿ãŒã‚ã‚Šã¾ã›ã‚“。セクション長㯠0 ã§ã™\n"
+
+#: mmo.c:3135
+#, c-format
+msgid "%s: too many initialized registers; section length %ld\n"
+msgstr "%s: åˆæœŸåŒ–ã•ã‚ŒãŸãƒ¬ã‚¸ã‚¹ã‚¿ãŒå¤šã™ãŽã¾ã™ã€‚セクション長㯠%ld ã§ã™\n"
+
+#: mmo.c:3140
+#, c-format
+msgid "%s: invalid start address for initialized registers of length %ld: 0x%lx%08lx\n"
+msgstr "%s: é•·ã• %ld ã®åˆæœŸåŒ–ã•ã‚ŒãŸãƒ¬ã‚¸ã‚¹ã‚¿ç”¨ã®ç„¡åŠ¹ãªé–‹å§‹ã‚¢ãƒ‰ãƒ¬ã‚¹ã§ã™ : 0x%lx%08lx\n"
+
+#: oasys.c:882
+#, c-format
+msgid "%s: can not represent section `%s' in oasys"
+msgstr "%s: oasys ã§ã¯ã‚»ã‚¯ã‚·ãƒ§ãƒ³ `%s' を表ç¾ã§ãã¾ã›ã‚“"
+
+#: osf-core.c:140
+#, c-format
+msgid "Unhandled OSF/1 core file section type %d\n"
+msgstr "å–り扱ã‚ã‚Œãªã„ OSF/1 コアファイルセクション型 %d ã§ã™\n"
+
+#: pe-mips.c:607
+msgid "%B: `ld -r' not supported with PE MIPS objects\n"
+msgstr "%B: `ld -r' 㯠PE MIPS オブジェクトã¨ä½µã›ã¦ä½¿ç”¨ã§ãã¾ã›ã‚“\n"
+
+#. OK, at this point the following variables are set up:
+#. src = VMA of the memory we're fixing up
+#. mem = pointer to memory we're fixing up
+#. val = VMA of what we need to refer to.
+#: pe-mips.c:719
+msgid "%B: unimplemented %s\n"
+msgstr "%B: 未実装㮠%s ã§ã™\n"
+
+#: pe-mips.c:745
+msgid "%B: jump too far away\n"
+msgstr "%B: ジャンプ先ãŒé ã™ãŽã¾ã™\n"
+
+#: pe-mips.c:771
+msgid "%B: bad pair/reflo after refhi\n"
+msgstr "%B: 誤ã£ãŸ pair/reflo ㌠refhi ã®å¾Œã‚ã«ã‚ã‚Šã¾ã™\n"
+
+#: pef.c:519
+#, c-format
+msgid "bfd_pef_scan: unknown architecture 0x%lx"
+msgstr ""
+
+#: pei-x86_64.c:444
+#, c-format
+msgid "warning: .pdata section size (%ld) is not a multiple of %d\n"
+msgstr "警告: .pdata セクションサイズ (%ld) ㌠%d ã®å€æ•°ã§ã¯ã‚ã‚Šã¾ã›ã‚“\n"
+
+#: pei-x86_64.c:448 peigen.c:1618 peigen.c:1801 pepigen.c:1618 pepigen.c:1801
+#: pex64igen.c:1618 pex64igen.c:1801
+#, c-format
+msgid ""
+"\n"
+"The Function Table (interpreted .pdata section contents)\n"
+msgstr ""
+"\n"
+"関数表 (.pdata セクションã®å†…容を解釈)\n"
+
+#: pei-x86_64.c:450
+#, c-format
+msgid "vma:\t\t\tBeginAddress\t EndAddress\t UnwindData\n"
+msgstr ""
+
+#. XXX code yet to be written.
+#: peicode.h:751
+msgid "%B: Unhandled import type; %x"
+msgstr "%B: å–り扱ãˆãªã„インãƒãƒ¼ãƒˆåž‹ %x ã§ã™"
+
+#: peicode.h:756
+msgid "%B: Unrecognised import type; %x"
+msgstr "%B: èªè­˜ã§ããªã„インãƒãƒ¼ãƒˆåž‹ %x ã§ã™"
+
+#: peicode.h:770
+msgid "%B: Unrecognised import name type; %x"
+msgstr "%B: èªè­˜ã§ããªã„インãƒãƒ¼ãƒˆåå‰åž‹ %x ã§ã™"
+
+#: peicode.h:1162
+msgid "%B: Unrecognised machine type (0x%x) in Import Library Format archive"
+msgstr "%B: インãƒãƒ¼ãƒˆãƒ©ã‚¤ãƒ–ラリ形å¼æ›¸åº«ã®ãƒžã‚·ãƒ³åž‹ (0x%x) ã¯èªè­˜ã§ãã¾ã›ã‚“"
+
+#: peicode.h:1174
+msgid "%B: Recognised but unhandled machine type (0x%x) in Import Library Format archive"
+msgstr "%B: インãƒãƒ¼ãƒˆãƒ©ã‚¤ãƒ–ラリ形å¼æ›¸åº«ã®ãƒžã‚·ãƒ³åž‹ (0x%x) ã¯èªè­˜ã§ãã¾ã™ãŒæ‰±ãˆã¾ã›ã‚“"
+
+#: peicode.h:1192
+msgid "%B: size field is zero in Import Library Format header"
+msgstr "%B: インãƒãƒ¼ãƒˆãƒ©ã‚¤ãƒ–ラリ形å¼ãƒ˜ãƒƒãƒ€å†…ã®ã‚µã‚¤ã‚ºãƒ•ã‚£ãƒ¼ãƒ«ãƒ‰ãŒ 0 ã§ã™"
+
+#: peicode.h:1223
+msgid "%B: string not null terminated in ILF object file."
+msgstr "%B: ILF オブジェクトファイル内ã®æ–‡å­—列㌠null ã§çµ‚端ã•ã‚Œã¦ã„ã¾ã›ã‚“。"
+
+#: ppcboot.c:414
+#, c-format
+msgid ""
+"\n"
+"ppcboot header:\n"
+msgstr ""
+"\n"
+"ppcboot ヘッダ:\n"
+
+#: ppcboot.c:415
+#, c-format
+msgid "Entry offset = 0x%.8lx (%ld)\n"
+msgstr "エントリオフセット = 0x%.8lx (%ld)\n"
+
+#: ppcboot.c:417
+#, c-format
+msgid "Length = 0x%.8lx (%ld)\n"
+msgstr "é•·ã• = 0x%.8lx (%ld)\n"
+
+#: ppcboot.c:421
+#, c-format
+msgid "Flag field = 0x%.2x\n"
+msgstr "フラグフィールド = 0x%.2x\n"
+
+#: ppcboot.c:427
+#, c-format
+msgid "Partition name = \"%s\"\n"
+msgstr "領域å = \"%s\"\n"
+
+#: ppcboot.c:446
+#, c-format
+msgid ""
+"\n"
+"Partition[%d] start = { 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x }\n"
+msgstr ""
+"\n"
+"領域[%d] ã®é–‹å§‹ = { 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x }\n"
+
+#: ppcboot.c:452
+#, c-format
+msgid "Partition[%d] end = { 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x }\n"
+msgstr "領域[%d] ã®æœ«å°¾ = { 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x }\n"
+
+#: ppcboot.c:458
+#, c-format
+msgid "Partition[%d] sector = 0x%.8lx (%ld)\n"
+msgstr "領域[%d] セクタ = 0x%.8lx (%ld)\n"
+
+#: ppcboot.c:460
+#, c-format
+msgid "Partition[%d] length = 0x%.8lx (%ld)\n"
+msgstr "領域[%d] 長㕠= 0x%.8lx (%ld)\n"
+
+#: rs6000-core.c:448
+#, c-format
+msgid "%s: warning core file truncated"
+msgstr ""
+
+#: som.c:5471
+#, c-format
+msgid ""
+"\n"
+"Exec Auxiliary Header\n"
+msgstr ""
+"\n"
+"実行補助ヘッダ\n"
+
+#: som.c:5776
+msgid "som_sizeof_headers unimplemented"
+msgstr "som_sizeof_headers ã¯æœªå®Ÿè£…ã§ã™"
+
+#: srec.c:261
+msgid "%B:%d: Unexpected character `%s' in S-record file\n"
+msgstr "%B:%d: S-record ファイル内ã«äºˆæœŸã—ãªã„文字 `%s' ãŒã‚ã‚Šã¾ã™\n"
+
+#: srec.c:567 srec.c:600
+msgid "%B:%d: Bad checksum in S-record file\n"
+msgstr "%B:%d: S-record ファイル内ã®ãƒã‚§ãƒƒã‚¯ã‚µãƒ ãŒèª¤ã£ã¦ã„ã¾ã™\n"
+
+#: stabs.c:279
+msgid "%B(%A+0x%lx): Stabs entry has invalid string index."
+msgstr ""
+
+#: syms.c:1079
+msgid "Unsupported .stab relocation"
+msgstr ".stab å†é…ç½®ã¯ã‚µãƒãƒ¼ãƒˆã•ã‚Œã¦ã„ã¾ã›ã‚“"
+
+#: vms-alpha.c:1299
+#, c-format
+msgid "Unknown EGSD subtype %d"
+msgstr "ä¸æ˜Žãª EGSD サブタイプ %d ã§ã™"
+
+#: vms-alpha.c:1330
+#, c-format
+msgid "Stack overflow (%d) in _bfd_vms_push"
+msgstr "_bfd_vms_push ã§ã‚¹ã‚¿ãƒƒã‚¯ã‚ªãƒ¼ãƒãƒ¼ãƒ•ãƒ­ãƒ¼(%d)ã—ã¾ã—ãŸ"
+
+#: vms-alpha.c:1343
+msgid "Stack underflow in _bfd_vms_pop"
+msgstr "_bfd_vms_pop ã§ã‚¹ã‚¿ãƒƒã‚¯ã‚¢ãƒ³ãƒ€ãƒ¼ãƒ•ãƒ­ãƒ¼ã—ã¾ã—ãŸ"
+
+#. These names have not yet been added to this switch statement.
+#: vms-alpha.c:1580
+#, c-format
+msgid "unknown ETIR command %d"
+msgstr "ä¸æ˜Žãª ETIR コマンド %d ã§ã™"
+
+#: vms-alpha.c:1767
+#, c-format
+msgid "bad section index in %s"
+msgstr ""
+
+#: vms-alpha.c:1780
+#, c-format
+msgid "unsupported STA cmd %s"
+msgstr "サãƒãƒ¼ãƒˆã•ã‚Œã¦ã„ãªã„ STA cmd %s ã§ã™"
+
+#. Insert field.
+#. Unsigned shift.
+#. Rotate.
+#. Redefine symbol to current location.
+#. Define a literal.
+#: vms-alpha.c:1956 vms-alpha.c:1987 vms-alpha.c:2234
+#, c-format
+msgid "%s: not supported"
+msgstr "%s: サãƒãƒ¼ãƒˆã•ã‚Œã¦ã„ã¾ã›ã‚“"
+
+#: vms-alpha.c:1962
+#, c-format
+msgid "%s: not implemented"
+msgstr "%s: 実装ã•ã‚Œã¦ã„ã¾ã›ã‚“"
+
+#: vms-alpha.c:2218
+#, c-format
+msgid "invalid use of %s with contexts"
+msgstr ""
+
+#: vms-alpha.c:2252
+#, c-format
+msgid "reserved cmd %d"
+msgstr "予約ã•ã‚ŒãŸ cmd %d ã§ã™"
+
+#: vms-alpha.c:2337
+msgid "Object module NOT error-free !\n"
+msgstr "オブジェクトモジュールãŒã‚¨ãƒ©ãƒ¼ç„¡ã—ã§ã¯ã‚ã‚Šã¾ã›ã‚“!\n"
+
+#: vms-alpha.c:2766
+#, c-format
+msgid "Symbol %s replaced by %s\n"
+msgstr "シンボル %s 㯠%s ã§ç½®ãæ›ãˆã‚‰ã‚Œã¾ã—ãŸ\n"
+
+#: vms-alpha.c:3769
+#, c-format
+msgid "SEC_RELOC with no relocs in section %s"
+msgstr "セクション %s 内ã«å†é…ç½®ãŒç„¡ã„ SEC_RELOC ãŒã‚ã‚Šã¾ã™"
+
+#: vms-alpha.c:3822 vms-alpha.c:4053
+#, c-format
+msgid "Size error in section %s"
+msgstr "セクション %s 内ã§ã‚µã‚¤ã‚ºã‚¨ãƒ©ãƒ¼ã§ã™"
+
+#: vms-alpha.c:3992
+msgid "Spurious ALPHA_R_BSR reloc"
+msgstr "ç–‘ã‚ã—ã„ ALPHA_R_BSR å†é…ç½®ã§ã™"
+
+#: vms-alpha.c:4040
+#, c-format
+msgid "Unhandled relocation %s"
+msgstr "å–り扱ã‚ã‚Œãªã„å†é…ç½® %s ã§ã™"
+
+#: vms-alpha.c:4330
+#, c-format
+msgid "unknown source command %d"
+msgstr "ä¸æ˜Žãªã‚½ãƒ¼ã‚¹ã‚³ãƒžãƒ³ãƒ‰ %d ã§ã™"
+
+#: vms-alpha.c:4391
+msgid "DST__K_SET_LINUM_INCR not implemented"
+msgstr "DST__K_SET_LINUM_INCR ã¯å®Ÿè£…ã•ã‚Œã¦ã„ã¾ã›ã‚“"
+
+#: vms-alpha.c:4397
+msgid "DST__K_SET_LINUM_INCR_W not implemented"
+msgstr "DST__K_SET_LINUM_INCR_W ã¯å®Ÿè£…ã•ã‚Œã¦ã„ã¾ã›ã‚“"
+
+#: vms-alpha.c:4403
+msgid "DST__K_RESET_LINUM_INCR not implemented"
+msgstr "DST__K_RESET_LINUM_INCR ã¯å®Ÿè£…ã•ã‚Œã¦ã„ã¾ã›ã‚“"
+
+#: vms-alpha.c:4409
+msgid "DST__K_BEG_STMT_MODE not implemented"
+msgstr "DST__K_BEG_STMT_MODE ã¯å®Ÿè£…ã•ã‚Œã¦ã„ã¾ã›ã‚“"
+
+#: vms-alpha.c:4415
+msgid "DST__K_END_STMT_MODE not implemented"
+msgstr "DST__K_END_STMT_MODE ã¯å®Ÿè£…ã•ã‚Œã¦ã„ã¾ã›ã‚“"
+
+#: vms-alpha.c:4442
+msgid "DST__K_SET_PC not implemented"
+msgstr "DST__K_SET_PC ã¯å®Ÿè£…ã•ã‚Œã¦ã„ã¾ã›ã‚“"
+
+#: vms-alpha.c:4448
+msgid "DST__K_SET_PC_W not implemented"
+msgstr "DST__K_SET_PC_W ã¯å®Ÿè£…ã•ã‚Œã¦ã„ã¾ã›ã‚“"
+
+#: vms-alpha.c:4454
+msgid "DST__K_SET_PC_L not implemented"
+msgstr "DST__K_SET_PC_L ã¯å®Ÿè£…ã•ã‚Œã¦ã„ã¾ã›ã‚“"
+
+#: vms-alpha.c:4460
+msgid "DST__K_SET_STMTNUM not implemented"
+msgstr "DST__K_SET_STMTNUM ã¯å®Ÿè£…ã•ã‚Œã¦ã„ã¾ã›ã‚“"
+
+#: vms-alpha.c:4503
+#, c-format
+msgid "unknown line command %d"
+msgstr "ä¸æ˜Žãªè¡Œã‚³ãƒžãƒ³ãƒ‰ %d ã§ã™"
+
+#: vms-alpha.c:4957 vms-alpha.c:4974 vms-alpha.c:4988 vms-alpha.c:5003
+#: vms-alpha.c:5015 vms-alpha.c:5026 vms-alpha.c:5038
+#, c-format
+msgid "Unknown reloc %s + %s"
+msgstr "ä¸æ˜Žãªå†é…ç½® %s + %s ã§ã™"
+
+#: vms-alpha.c:5093
+#, c-format
+msgid "Unknown reloc %s"
+msgstr "ä¸æ˜Žãªå†é…ç½® %s ã§ã™"
+
+#: vms-alpha.c:5106
+msgid "Invalid section index in ETIR"
+msgstr "ETIR 内ã«ç„¡åŠ¹ãªã‚»ã‚¯ã‚·ãƒ§ãƒ³ç´¢å¼•ãŒã‚ã‚Šã¾ã™ã€‚"
+
+#: vms-alpha.c:5153
+#, c-format
+msgid "Unknown symbol in command %s"
+msgstr "コマンド %s 内ã®ä¸æ˜Žãªã‚·ãƒ³ãƒœãƒ«ã§ã™"
+
+#: vms-alpha.c:5668
+#, c-format
+msgid " EMH %u (len=%u): "
+msgstr " EMH %u (é•·ã•=%u): "
+
+#: vms-alpha.c:5677
+#, c-format
+msgid "Module header\n"
+msgstr "モジュールヘッダ\n"
+
+#: vms-alpha.c:5678
+#, c-format
+msgid " structure level: %u\n"
+msgstr " 構造体レベル : %u\n"
+
+#: vms-alpha.c:5679
+#, c-format
+msgid " max record size: %u\n"
+msgstr " 最大レコードサイズ: %u\n"
+
+#: vms-alpha.c:5682
+#, c-format
+msgid " module name : %.*s\n"
+msgstr " モジュールå : %.*s\n"
+
+#: vms-alpha.c:5684
+#, c-format
+msgid " module version : %.*s\n"
+msgstr " モジュールãƒãƒ¼ã‚¸ãƒ§ãƒ³: %.*s\n"
+
+#: vms-alpha.c:5686
+#, c-format
+msgid " compile date : %.17s\n"
+msgstr " コンパイル日 : %.17s\n"
+
+#: vms-alpha.c:5691
+#, c-format
+msgid "Language Processor Name\n"
+msgstr "言語処ç†ç³»å\n"
+
+#: vms-alpha.c:5692
+#, c-format
+msgid " language name: %.*s\n"
+msgstr " 言語å : %.*s\n"
+
+#: vms-alpha.c:5699
+#, c-format
+msgid "Source Files Header\n"
+msgstr "ソースファイルヘッダ\n"
+
+#: vms-alpha.c:5700
+#, c-format
+msgid " file: %.*s\n"
+msgstr " ファイル: %.*s\n"
+
+#: vms-alpha.c:5707
+#, c-format
+msgid "Title Text Header\n"
+msgstr "タイトルテキストヘッダ\n"
+
+#: vms-alpha.c:5708
+#, c-format
+msgid " title: %.*s\n"
+msgstr " タイトル: %.*s\n"
+
+#: vms-alpha.c:5715
+#, c-format
+msgid "Copyright Header\n"
+msgstr "著作権ヘッダ\n"
+
+#: vms-alpha.c:5716
+#, c-format
+msgid " copyright: %.*s\n"
+msgstr " 著作権 : %.*s\n"
+
+#: vms-alpha.c:5722
+#, c-format
+msgid "unhandled emh subtype %u\n"
+msgstr "å–り扱ãˆãªã„ emh サブタイプ %u ã§ã™\n"
+
+#: vms-alpha.c:5732
+#, c-format
+msgid " EEOM (len=%u):\n"
+msgstr " EEOM (é•·ã•=%u):\n"
+
+#: vms-alpha.c:5733
+#, c-format
+msgid " number of cond linkage pairs: %u\n"
+msgstr ""
+
+#: vms-alpha.c:5735
+#, c-format
+msgid " completion code: %u\n"
+msgstr ""
+
+#: vms-alpha.c:5739
+#, c-format
+msgid " transfer addr flags: 0x%02x\n"
+msgstr ""
+
+#: vms-alpha.c:5740
+#, c-format
+msgid " transfer addr psect: %u\n"
+msgstr ""
+
+#: vms-alpha.c:5742
+#, c-format
+msgid " transfer address : 0x%08x\n"
+msgstr ""
+
+#: vms-alpha.c:5751
+msgid " WEAK"
+msgstr " WEAK"
+
+#: vms-alpha.c:5753
+msgid " DEF"
+msgstr " DEF"
+
+#: vms-alpha.c:5755
+msgid " UNI"
+msgstr " UNI"
+
+#: vms-alpha.c:5757 vms-alpha.c:5778
+msgid " REL"
+msgstr " REL"
+
+#: vms-alpha.c:5759
+msgid " COMM"
+msgstr " COMM"
+
+#: vms-alpha.c:5761
+msgid " VECEP"
+msgstr " VECEP"
+
+#: vms-alpha.c:5763
+msgid " NORM"
+msgstr " NORM"
+
+#: vms-alpha.c:5765
+msgid " QVAL"
+msgstr " QVAL"
+
+#: vms-alpha.c:5772
+msgid " PIC"
+msgstr " PIC"
+
+#: vms-alpha.c:5774
+msgid " LIB"
+msgstr " LIB"
+
+#: vms-alpha.c:5776
+msgid " OVR"
+msgstr " OVR"
+
+#: vms-alpha.c:5780
+msgid " GBL"
+msgstr " GBL"
+
+#: vms-alpha.c:5782
+msgid " SHR"
+msgstr " SHR"
+
+#: vms-alpha.c:5784
+msgid " EXE"
+msgstr " EXE"
+
+#: vms-alpha.c:5786
+msgid " RD"
+msgstr " RD"
+
+#: vms-alpha.c:5788
+msgid " WRT"
+msgstr " WRT"
+
+#: vms-alpha.c:5790
+msgid " VEC"
+msgstr " VEC"
+
+#: vms-alpha.c:5792
+msgid " NOMOD"
+msgstr " NOMOD"
+
+#: vms-alpha.c:5794
+msgid " COM"
+msgstr " COM"
+
+#: vms-alpha.c:5796
+msgid " 64B"
+msgstr " 64B"
+
+#: vms-alpha.c:5805
+#, c-format
+msgid " EGSD (len=%u):\n"
+msgstr " EGSD (é•·ã•=%u):\n"
+
+#: vms-alpha.c:5817
+#, c-format
+msgid " EGSD entry %2u (type: %u, len: %u): "
+msgstr " EGSD エントリ %2u (åž‹: %u, é•·ã•: %u): "
+
+#: vms-alpha.c:5829
+#, c-format
+msgid "PSC - Program section definition\n"
+msgstr "PSC - プログラムセクション定義\n"
+
+#: vms-alpha.c:5830 vms-alpha.c:5847
+#, c-format
+msgid " alignment : 2**%u\n"
+msgstr " 整列 : 2**%u\n"
+
+#: vms-alpha.c:5831 vms-alpha.c:5848
+#, c-format
+msgid " flags : 0x%04x"
+msgstr " フラグ : 0x%04x"
+
+#: vms-alpha.c:5835
+#, c-format
+msgid " alloc (len): %u (0x%08x)\n"
+msgstr ""
+
+#: vms-alpha.c:5836 vms-alpha.c:5893 vms-alpha.c:5942
+#, c-format
+msgid " name : %.*s\n"
+msgstr " åå‰ : %.*s\n"
+
+#: vms-alpha.c:5846
+#, c-format
+msgid "SPSC - Shared Image Program section def\n"
+msgstr "SPSC - 共有イメージプログラムセクション定義\n"
+
+#: vms-alpha.c:5852
+#, c-format
+msgid " alloc (len) : %u (0x%08x)\n"
+msgstr ""
+
+#: vms-alpha.c:5853
+#, c-format
+msgid " image offset : 0x%08x\n"
+msgstr " イメージオフセット : 0x%08x\n"
+
+#: vms-alpha.c:5855
+#, c-format
+msgid " symvec offset : 0x%08x\n"
+msgstr ""
+
+#: vms-alpha.c:5857
+#, c-format
+msgid " name : %.*s\n"
+msgstr " åå‰ : %.*s\n"
+
+#: vms-alpha.c:5870
+#, c-format
+msgid "SYM - Global symbol definition\n"
+msgstr "SYM - 大域シンボル定義\n"
+
+#: vms-alpha.c:5871 vms-alpha.c:5931 vms-alpha.c:5952 vms-alpha.c:5971
+#, c-format
+msgid " flags: 0x%04x"
+msgstr " フラグ: 0x%04x"
+
+#: vms-alpha.c:5874
+#, c-format
+msgid " psect offset: 0x%08x\n"
+msgstr " psect オフセット: 0x%08x\n"
+
+#: vms-alpha.c:5878
+#, c-format
+msgid " code address: 0x%08x\n"
+msgstr " コードアドレス: 0x%08x\n"
+
+#: vms-alpha.c:5880
+#, c-format
+msgid " psect index for entry point : %u\n"
+msgstr ""
+
+#: vms-alpha.c:5883 vms-alpha.c:5959 vms-alpha.c:5978
+#, c-format
+msgid " psect index : %u\n"
+msgstr " psect 索引 : %u\n"
+
+#: vms-alpha.c:5885 vms-alpha.c:5961 vms-alpha.c:5980
+#, c-format
+msgid " name : %.*s\n"
+msgstr " åå‰ : %.*s\n"
+
+#: vms-alpha.c:5892
+#, c-format
+msgid "SYM - Global symbol reference\n"
+msgstr "SYM - 大域シンボルå‚ç…§\n"
+
+#: vms-alpha.c:5904
+#, c-format
+msgid "IDC - Ident Consistency check\n"
+msgstr ""
+
+#: vms-alpha.c:5905
+#, c-format
+msgid " flags : 0x%08x"
+msgstr " フラグ : 0x%08x"
+
+#: vms-alpha.c:5909
+#, c-format
+msgid " id match : %x\n"
+msgstr ""
+
+#: vms-alpha.c:5911
+#, c-format
+msgid " error severity: %x\n"
+msgstr ""
+
+#: vms-alpha.c:5914
+#, c-format
+msgid " entity name : %.*s\n"
+msgstr " エントリå : %.*s\n"
+
+#: vms-alpha.c:5916
+#, c-format
+msgid " object name : %.*s\n"
+msgstr " オブジェクトå: %.*s\n"
+
+#: vms-alpha.c:5919
+#, c-format
+msgid " binary ident : 0x%08x\n"
+msgstr ""
+
+#: vms-alpha.c:5922
+#, c-format
+msgid " ascii ident : %.*s\n"
+msgstr ""
+
+#: vms-alpha.c:5930
+#, c-format
+msgid "SYMG - Universal symbol definition\n"
+msgstr "SYMG - ユニãƒãƒ¼ã‚µãƒ«ã‚·ãƒ³ãƒœãƒ«å®šç¾©\n"
+
+#: vms-alpha.c:5934
+#, c-format
+msgid " symbol vector offset: 0x%08x\n"
+msgstr " シンボルベクトルオフセット: 0x%08x\n"
+
+#: vms-alpha.c:5936
+#, c-format
+msgid " entry point: 0x%08x\n"
+msgstr " エントリãƒã‚¤ãƒ³ãƒˆ: 0x%08x\n"
+
+#: vms-alpha.c:5938
+#, c-format
+msgid " proc descr : 0x%08x\n"
+msgstr ""
+
+#: vms-alpha.c:5940
+#, c-format
+msgid " psect index: %u\n"
+msgstr ""
+
+#: vms-alpha.c:5951
+#, c-format
+msgid "SYMV - Vectored symbol definition\n"
+msgstr "SYMV - ベクトル化ã•ã‚ŒãŸã‚·ãƒ³ãƒœãƒ«å®šç¾©\n"
+
+#: vms-alpha.c:5955
+#, c-format
+msgid " vector : 0x%08x\n"
+msgstr " ベクトル : 0x%08x\n"
+
+#: vms-alpha.c:5957 vms-alpha.c:5976
+#, c-format
+msgid " psect offset: %u\n"
+msgstr ""
+
+#: vms-alpha.c:5970
+#, c-format
+msgid "SYMM - Global symbol definition with version\n"
+msgstr "SYMM - ãƒãƒ¼ã‚¸ãƒ§ãƒ³ä»˜ã大域シンボル定義\n"
+
+#: vms-alpha.c:5974
+#, c-format
+msgid " version mask: 0x%08x\n"
+msgstr ""
+
+#: vms-alpha.c:5985
+#, c-format
+msgid "unhandled egsd entry type %u\n"
+msgstr ""
+
+#: vms-alpha.c:6019
+#, c-format
+msgid " linkage index: %u, replacement insn: 0x%08x\n"
+msgstr ""
+
+#: vms-alpha.c:6022
+#, c-format
+msgid " psect idx 1: %u, offset 1: 0x%08x %08x\n"
+msgstr ""
+
+#: vms-alpha.c:6026
+#, c-format
+msgid " psect idx 2: %u, offset 2: 0x%08x %08x\n"
+msgstr ""
+
+#: vms-alpha.c:6031
+#, c-format
+msgid " psect idx 3: %u, offset 3: 0x%08x %08x\n"
+msgstr ""
+
+#: vms-alpha.c:6036
+#, c-format
+msgid " global name: %.*s\n"
+msgstr ""
+
+#: vms-alpha.c:6046
+#, c-format
+msgid " %s (len=%u+%u):\n"
+msgstr ""
+
+#: vms-alpha.c:6061
+#, c-format
+msgid " (type: %3u, size: 4+%3u): "
+msgstr ""
+
+#: vms-alpha.c:6065
+#, c-format
+msgid "STA_GBL (stack global) %.*s\n"
+msgstr ""
+
+#: vms-alpha.c:6069
+#, c-format
+msgid "STA_LW (stack longword) 0x%08x\n"
+msgstr ""
+
+#: vms-alpha.c:6073
+#, c-format
+msgid "STA_QW (stack quadword) 0x%08x %08x\n"
+msgstr ""
+
+#: vms-alpha.c:6078
+#, c-format
+msgid "STA_PQ (stack psect base + offset)\n"
+msgstr ""
+
+#: vms-alpha.c:6079
+#, c-format
+msgid " psect: %u, offset: 0x%08x %08x\n"
+msgstr ""
+
+#: vms-alpha.c:6085
+#, c-format
+msgid "STA_LI (stack literal)\n"
+msgstr ""
+
+#: vms-alpha.c:6088
+#, c-format
+msgid "STA_MOD (stack module)\n"
+msgstr ""
+
+#: vms-alpha.c:6091
+#, c-format
+msgid "STA_CKARG (compare procedure argument)\n"
+msgstr ""
+
+#: vms-alpha.c:6095
+#, c-format
+msgid "STO_B (store byte)\n"
+msgstr ""
+
+#: vms-alpha.c:6098
+#, c-format
+msgid "STO_W (store word)\n"
+msgstr ""
+
+#: vms-alpha.c:6101
+#, c-format
+msgid "STO_LW (store longword)\n"
+msgstr ""
+
+#: vms-alpha.c:6104
+#, c-format
+msgid "STO_QW (store quadword)\n"
+msgstr ""
+
+#: vms-alpha.c:6110
+#, c-format
+msgid "STO_IMMR (store immediate repeat) %u bytes\n"
+msgstr ""
+
+#: vms-alpha.c:6117
+#, c-format
+msgid "STO_GBL (store global) %.*s\n"
+msgstr ""
+
+#: vms-alpha.c:6121
+#, c-format
+msgid "STO_CA (store code address) %.*s\n"
+msgstr ""
+
+#: vms-alpha.c:6125
+#, c-format
+msgid "STO_RB (store relative branch)\n"
+msgstr ""
+
+#: vms-alpha.c:6128
+#, c-format
+msgid "STO_AB (store absolute branch)\n"
+msgstr ""
+
+#: vms-alpha.c:6131
+#, c-format
+msgid "STO_OFF (store offset to psect)\n"
+msgstr ""
+
+#: vms-alpha.c:6137
+#, c-format
+msgid "STO_IMM (store immediate) %u bytes\n"
+msgstr ""
+
+#: vms-alpha.c:6144
+#, c-format
+msgid "STO_GBL_LW (store global longword) %.*s\n"
+msgstr ""
+
+#: vms-alpha.c:6148
+#, c-format
+msgid "STO_OFF (store LP with procedure signature)\n"
+msgstr ""
+
+#: vms-alpha.c:6151
+#, c-format
+msgid "STO_BR_GBL (store branch global) *todo*\n"
+msgstr ""
+
+#: vms-alpha.c:6154
+#, c-format
+msgid "STO_BR_PS (store branch psect + offset) *todo*\n"
+msgstr ""
+
+#: vms-alpha.c:6158
+#, c-format
+msgid "OPR_NOP (no-operation)\n"
+msgstr ""
+
+#: vms-alpha.c:6161
+#, c-format
+msgid "OPR_ADD (add)\n"
+msgstr ""
+
+#: vms-alpha.c:6164
+#, c-format
+msgid "OPR_SUB (substract)\n"
+msgstr ""
+
+#: vms-alpha.c:6167
+#, c-format
+msgid "OPR_MUL (multiply)\n"
+msgstr ""
+
+#: vms-alpha.c:6170
+#, c-format
+msgid "OPR_DIV (divide)\n"
+msgstr ""
+
+#: vms-alpha.c:6173
+#, c-format
+msgid "OPR_AND (logical and)\n"
+msgstr ""
+
+#: vms-alpha.c:6176
+#, c-format
+msgid "OPR_IOR (logical inclusive or)\n"
+msgstr ""
+
+#: vms-alpha.c:6179
+#, c-format
+msgid "OPR_EOR (logical exclusive or)\n"
+msgstr ""
+
+#: vms-alpha.c:6182
+#, c-format
+msgid "OPR_NEG (negate)\n"
+msgstr ""
+
+#: vms-alpha.c:6185
+#, c-format
+msgid "OPR_COM (complement)\n"
+msgstr ""
+
+#: vms-alpha.c:6188
+#, c-format
+msgid "OPR_INSV (insert field)\n"
+msgstr ""
+
+#: vms-alpha.c:6191
+#, c-format
+msgid "OPR_ASH (arithmetic shift)\n"
+msgstr ""
+
+#: vms-alpha.c:6194
+#, c-format
+msgid "OPR_USH (unsigned shift)\n"
+msgstr ""
+
+#: vms-alpha.c:6197
+#, c-format
+msgid "OPR_ROT (rotate)\n"
+msgstr ""
+
+#: vms-alpha.c:6200
+#, c-format
+msgid "OPR_SEL (select)\n"
+msgstr ""
+
+#: vms-alpha.c:6203
+#, c-format
+msgid "OPR_REDEF (redefine symbol to curr location)\n"
+msgstr ""
+
+#: vms-alpha.c:6206
+#, c-format
+msgid "OPR_REDEF (define a literal)\n"
+msgstr ""
+
+#: vms-alpha.c:6210
+#, c-format
+msgid "STC_LP (store cond linkage pair)\n"
+msgstr ""
+
+#: vms-alpha.c:6214
+#, c-format
+msgid "STC_LP_PSB (store cond linkage pair + signature)\n"
+msgstr ""
+
+#: vms-alpha.c:6215
+#, c-format
+msgid " linkage index: %u, procedure: %.*s\n"
+msgstr ""
+
+#: vms-alpha.c:6218
+#, c-format
+msgid " signature: %.*s\n"
+msgstr ""
+
+#: vms-alpha.c:6221
+#, c-format
+msgid "STC_GBL (store cond global)\n"
+msgstr ""
+
+#: vms-alpha.c:6222
+#, c-format
+msgid " linkage index: %u, global: %.*s\n"
+msgstr ""
+
+#: vms-alpha.c:6226
+#, c-format
+msgid "STC_GCA (store cond code address)\n"
+msgstr ""
+
+#: vms-alpha.c:6227
+#, c-format
+msgid " linkage index: %u, procedure name: %.*s\n"
+msgstr ""
+
+#: vms-alpha.c:6231
+#, c-format
+msgid "STC_PS (store cond psect + offset)\n"
+msgstr ""
+
+#: vms-alpha.c:6233
+#, c-format
+msgid " linkage index: %u, psect: %u, offset: 0x%08x %08x\n"
+msgstr ""
+
+#: vms-alpha.c:6240
+#, c-format
+msgid "STC_NOP_GBL (store cond NOP at global addr)\n"
+msgstr ""
+
+#: vms-alpha.c:6244
+#, c-format
+msgid "STC_NOP_PS (store cond NOP at psect + offset)\n"
+msgstr ""
+
+#: vms-alpha.c:6248
+#, c-format
+msgid "STC_BSR_GBL (store cond BSR at global addr)\n"
+msgstr ""
+
+#: vms-alpha.c:6252
+#, c-format
+msgid "STC_BSR_PS (store cond BSR at psect + offset)\n"
+msgstr ""
+
+#: vms-alpha.c:6256
+#, c-format
+msgid "STC_LDA_GBL (store cond LDA at global addr)\n"
+msgstr ""
+
+#: vms-alpha.c:6260
+#, c-format
+msgid "STC_LDA_PS (store cond LDA at psect + offset)\n"
+msgstr ""
+
+#: vms-alpha.c:6264
+#, c-format
+msgid "STC_BOH_GBL (store cond BOH at global addr)\n"
+msgstr ""
+
+#: vms-alpha.c:6268
+#, c-format
+msgid "STC_BOH_PS (store cond BOH at psect + offset)\n"
+msgstr ""
+
+#: vms-alpha.c:6273
+#, c-format
+msgid "STC_NBH_GBL (store cond or hint at global addr)\n"
+msgstr ""
+
+#: vms-alpha.c:6277
+#, c-format
+msgid "STC_NBH_PS (store cond or hint at psect + offset)\n"
+msgstr ""
+
+#: vms-alpha.c:6281
+#, c-format
+msgid "CTL_SETRB (set relocation base)\n"
+msgstr ""
+
+#: vms-alpha.c:6287
+#, c-format
+msgid "CTL_AUGRB (augment relocation base) %u\n"
+msgstr ""
+
+#: vms-alpha.c:6291
+#, c-format
+msgid "CTL_DFLOC (define location)\n"
+msgstr "CTL_DFLOC (定義ä½ç½®)\n"
+
+#: vms-alpha.c:6294
+#, c-format
+msgid "CTL_STLOC (set location)\n"
+msgstr ""
+
+#: vms-alpha.c:6297
+#, c-format
+msgid "CTL_STKDL (stack defined location)\n"
+msgstr "CTL_STKDL (スタック定義ä½ç½®)\n"
+
+#: vms-alpha.c:6300 vms-alpha.c:6714
+#, c-format
+msgid "*unhandled*\n"
+msgstr ""
+
+#: vms-alpha.c:6330 vms-alpha.c:6369
+#, c-format
+msgid "cannot read GST record length\n"
+msgstr "GST レコード長を読ã¿è¾¼ã‚ã¾ã›ã‚“\n"
+
+#. Ill-formed.
+#: vms-alpha.c:6351
+#, c-format
+msgid "cannot find EMH in first GST record\n"
+msgstr ""
+
+#: vms-alpha.c:6377
+#, c-format
+msgid "cannot read GST record header\n"
+msgstr "GST レコードヘッダを読ã¿è¾¼ã‚ã¾ã›ã‚“\n"
+
+#: vms-alpha.c:6390
+#, c-format
+msgid " corrupted GST\n"
+msgstr " ç ´æã—ã¦ã„ã‚‹ GST ã§ã™\n"
+
+#: vms-alpha.c:6398
+#, c-format
+msgid "cannot read GST record\n"
+msgstr "GST レコードを読ã¿è¾¼ã‚ã¾ã›ã‚“\n"
+
+#: vms-alpha.c:6427
+#, c-format
+msgid " unhandled EOBJ record type %u\n"
+msgstr "扱ãˆãªã„ EOBJ レコード型 %u ã§ã™\n"
+
+#: vms-alpha.c:6450
+#, c-format
+msgid " bitcount: %u, base addr: 0x%08x\n"
+msgstr ""
+
+#: vms-alpha.c:6463
+#, c-format
+msgid " bitmap: 0x%08x (count: %u):\n"
+msgstr ""
+
+#: vms-alpha.c:6470
+#, c-format
+msgid " %08x"
+msgstr " %08x"
+
+#: vms-alpha.c:6495
+#, c-format
+msgid " image %u (%u entries)\n"
+msgstr ""
+
+#: vms-alpha.c:6500
+#, c-format
+msgid " offset: 0x%08x, val: 0x%08x\n"
+msgstr ""
+
+#: vms-alpha.c:6521
+#, c-format
+msgid " image %u (%u entries), offsets:\n"
+msgstr ""
+
+#: vms-alpha.c:6528
+#, c-format
+msgid " 0x%08x"
+msgstr ""
+
+#. 64 bits.
+#: vms-alpha.c:6650
+#, c-format
+msgid "64 bits *unhandled*\n"
+msgstr ""
+
+#: vms-alpha.c:6654
+#, c-format
+msgid "class: %u, dtype: %u, length: %u, pointer: 0x%08x\n"
+msgstr ""
+
+#: vms-alpha.c:6665
+#, c-format
+msgid "non-contiguous array of %s\n"
+msgstr ""
+
+#: vms-alpha.c:6669
+#, c-format
+msgid "dimct: %u, aflags: 0x%02x, digits: %u, scale: %u\n"
+msgstr ""
+
+#: vms-alpha.c:6673
+#, c-format
+msgid "arsize: %u, a0: 0x%08x\n"
+msgstr ""
+
+#: vms-alpha.c:6677
+#, c-format
+msgid "Strides:\n"
+msgstr ""
+
+#: vms-alpha.c:6682
+#, c-format
+msgid "[%u]: %u\n"
+msgstr ""
+
+#: vms-alpha.c:6687
+#, c-format
+msgid "Bounds:\n"
+msgstr ""
+
+#: vms-alpha.c:6692
+#, c-format
+msgid "[%u]: Lower: %u, upper: %u\n"
+msgstr ""
+
+#: vms-alpha.c:6704
+#, c-format
+msgid "unaligned bit-string of %s\n"
+msgstr ""
+
+#: vms-alpha.c:6708
+#, c-format
+msgid "base: %u, pos: %u\n"
+msgstr ""
+
+#: vms-alpha.c:6728
+#, c-format
+msgid "vflags: 0x%02x, value: 0x%08x "
+msgstr ""
+
+#: vms-alpha.c:6734
+#, c-format
+msgid "(no value)\n"
+msgstr "(値無ã—)\n"
+
+#: vms-alpha.c:6737
+#, c-format
+msgid "(not active)\n"
+msgstr ""
+
+#: vms-alpha.c:6740
+#, c-format
+msgid "(not allocated)\n"
+msgstr "(未割り当ã¦)\n"
+
+#: vms-alpha.c:6743
+#, c-format
+msgid "(descriptor)\n"
+msgstr "(記述å­)\n"
+
+#: vms-alpha.c:6747
+#, c-format
+msgid "(trailing value)\n"
+msgstr "(後続ã®å€¤)\n"
+
+#: vms-alpha.c:6750
+#, c-format
+msgid "(value spec follows)\n"
+msgstr ""
+
+#: vms-alpha.c:6753
+#, c-format
+msgid "(at bit offset %u)\n"
+msgstr ""
+
+#: vms-alpha.c:6756
+#, c-format
+msgid "(reg: %u, disp: %u, indir: %u, kind: "
+msgstr ""
+
+#: vms-alpha.c:6763
+msgid "literal"
+msgstr ""
+
+#: vms-alpha.c:6766
+msgid "address"
+msgstr "アドレス"
+
+#: vms-alpha.c:6769
+msgid "desc"
+msgstr ""
+
+#: vms-alpha.c:6772
+msgid "reg"
+msgstr ""
+
+#: vms-alpha.c:6847
+#, c-format
+msgid "Debug symbol table:\n"
+msgstr "デãƒãƒƒã‚°ã‚·ãƒ³ãƒœãƒ«è¡¨:\n"
+
+#: vms-alpha.c:6858
+#, c-format
+msgid "cannot read DST header\n"
+msgstr ""
+
+#: vms-alpha.c:6863
+#, c-format
+msgid " type: %3u, len: %3u (at 0x%08x): "
+msgstr ""
+
+#: vms-alpha.c:6877
+#, c-format
+msgid "cannot read DST symbol\n"
+msgstr ""
+
+#: vms-alpha.c:6920
+#, c-format
+msgid "standard data: %s\n"
+msgstr ""
+
+#: vms-alpha.c:6923 vms-alpha.c:7007
+#, c-format
+msgid " name: %.*s\n"
+msgstr " åå‰: %.*s\n"
+
+#: vms-alpha.c:6930
+#, c-format
+msgid "modbeg\n"
+msgstr ""
+
+#: vms-alpha.c:6931
+#, c-format
+msgid " flags: %d, language: %u, major: %u, minor: %u\n"
+msgstr ""
+
+#: vms-alpha.c:6937 vms-alpha.c:7203
+#, c-format
+msgid " module name: %.*s\n"
+msgstr " モジュールå: %.*s\n"
+
+#: vms-alpha.c:6940
+#, c-format
+msgid " compiler : %.*s\n"
+msgstr " コンパイラ : %.*s\n"
+
+#: vms-alpha.c:6945
+#, c-format
+msgid "modend\n"
+msgstr ""
+
+#: vms-alpha.c:6952
+msgid "rtnbeg\n"
+msgstr ""
+
+#: vms-alpha.c:6953
+#, c-format
+msgid " flags: %u, address: 0x%08x, pd-address: 0x%08x\n"
+msgstr ""
+
+#: vms-alpha.c:6958
+#, c-format
+msgid " routine name: %.*s\n"
+msgstr ""
+
+#: vms-alpha.c:6966
+#, c-format
+msgid "rtnend: size 0x%08x\n"
+msgstr ""
+
+#: vms-alpha.c:6974
+#, c-format
+msgid "prolog: bkpt address 0x%08x\n"
+msgstr ""
+
+#: vms-alpha.c:6982
+#, c-format
+msgid "epilog: flags: %u, count: %u\n"
+msgstr ""
+
+#: vms-alpha.c:6991
+#, c-format
+msgid "blkbeg: address: 0x%08x, name: %.*s\n"
+msgstr ""
+
+#: vms-alpha.c:7000
+#, c-format
+msgid "blkend: size: 0x%08x\n"
+msgstr ""
+
+#: vms-alpha.c:7006
+#, c-format
+msgid "typspec (len: %u)\n"
+msgstr ""
+
+#: vms-alpha.c:7013
+#, c-format
+msgid "septyp, name: %.*s\n"
+msgstr ""
+
+#: vms-alpha.c:7022
+#, c-format
+msgid "recbeg: name: %.*s\n"
+msgstr ""
+
+#: vms-alpha.c:7029
+#, c-format
+msgid "recend\n"
+msgstr ""
+
+#: vms-alpha.c:7032
+#, c-format
+msgid "enumbeg, len: %u, name: %.*s\n"
+msgstr ""
+
+#: vms-alpha.c:7036
+#, c-format
+msgid "enumelt, name: %.*s\n"
+msgstr ""
+
+#: vms-alpha.c:7040
+#, c-format
+msgid "enumend\n"
+msgstr ""
+
+#: vms-alpha.c:7057
+#, c-format
+msgid "discontiguous range (nbr: %u)\n"
+msgstr ""
+
+#: vms-alpha.c:7059
+#, c-format
+msgid " address: 0x%08x, size: %u\n"
+msgstr ""
+
+#: vms-alpha.c:7069
+#, c-format
+msgid "line num (len: %u)\n"
+msgstr ""
+
+#: vms-alpha.c:7086
+#, c-format
+msgid "delta_pc_w %u\n"
+msgstr ""
+
+#: vms-alpha.c:7093
+#, c-format
+msgid "incr_linum(b): +%u\n"
+msgstr ""
+
+#: vms-alpha.c:7099
+#, c-format
+msgid "incr_linum_w: +%u\n"
+msgstr ""
+
+#: vms-alpha.c:7105
+#, c-format
+msgid "incr_linum_l: +%u\n"
+msgstr ""
+
+#: vms-alpha.c:7111
+#, c-format
+msgid "set_line_num(w) %u\n"
+msgstr ""
+
+#: vms-alpha.c:7116
+#, c-format
+msgid "set_line_num_b %u\n"
+msgstr ""
+
+#: vms-alpha.c:7121
+#, c-format
+msgid "set_line_num_l %u\n"
+msgstr ""
+
+#: vms-alpha.c:7126
+#, c-format
+msgid "set_abs_pc: 0x%08x\n"
+msgstr ""
+
+#: vms-alpha.c:7130
+#, c-format
+msgid "delta_pc_l: +0x%08x\n"
+msgstr ""
+
+#: vms-alpha.c:7135
+#, c-format
+msgid "term(b): 0x%02x"
+msgstr ""
+
+#: vms-alpha.c:7137
+#, c-format
+msgid " pc: 0x%08x\n"
+msgstr ""
+
+#: vms-alpha.c:7142
+#, c-format
+msgid "term_w: 0x%04x"
+msgstr ""
+
+#: vms-alpha.c:7144
+#, c-format
+msgid " pc: 0x%08x\n"
+msgstr ""
+
+#: vms-alpha.c:7150
+#, c-format
+msgid "delta pc +%-4d"
+msgstr ""
+
+#: vms-alpha.c:7153
+#, c-format
+msgid " pc: 0x%08x line: %5u\n"
+msgstr " pc: 0x%08x 行: %5u\n"
+
+#: vms-alpha.c:7158
+#, c-format
+msgid " *unhandled* cmd %u\n"
+msgstr ""
+
+#: vms-alpha.c:7173
+#, c-format
+msgid "source (len: %u)\n"
+msgstr ""
+
+#: vms-alpha.c:7187
+#, c-format
+msgid " declfile: len: %u, flags: %u, fileid: %u\n"
+msgstr ""
+
+#: vms-alpha.c:7191
+#, c-format
+msgid " rms: cdt: 0x%08x %08x, ebk: 0x%08x, ffb: 0x%04x, rfo: %u\n"
+msgstr ""
+
+#: vms-alpha.c:7200
+#, c-format
+msgid " filename : %.*s\n"
+msgstr " ファイルå : %.*s\n"
+
+#: vms-alpha.c:7209
+#, c-format
+msgid " setfile %u\n"
+msgstr ""
+
+#: vms-alpha.c:7214 vms-alpha.c:7219
+#, c-format
+msgid " setrec %u\n"
+msgstr ""
+
+#: vms-alpha.c:7224 vms-alpha.c:7229
+#, c-format
+msgid " setlnum %u\n"
+msgstr ""
+
+#: vms-alpha.c:7234 vms-alpha.c:7239
+#, c-format
+msgid " deflines %u\n"
+msgstr ""
+
+#: vms-alpha.c:7243
+#, c-format
+msgid " formfeed\n"
+msgstr ""
+
+#: vms-alpha.c:7247
+#, c-format
+msgid " *unhandled* cmd %u\n"
+msgstr ""
+
+#: vms-alpha.c:7259
+#, c-format
+msgid "*unhandled* dst type %u\n"
+msgstr ""
+
+#: vms-alpha.c:7291
+#, c-format
+msgid "cannot read EIHD\n"
+msgstr ""
+
+#: vms-alpha.c:7294
+#, c-format
+msgid "EIHD: (size: %u, nbr blocks: %u)\n"
+msgstr ""
+
+#: vms-alpha.c:7297
+#, c-format
+msgid " majorid: %u, minorid: %u\n"
+msgstr ""
+
+#: vms-alpha.c:7305
+msgid "executable"
+msgstr ""
+
+#: vms-alpha.c:7308
+msgid "linkable image"
+msgstr ""
+
+#: vms-alpha.c:7314
+#, c-format
+msgid " image type: %u (%s)"
+msgstr ""
+
+#: vms-alpha.c:7320
+msgid "native"
+msgstr ""
+
+#: vms-alpha.c:7323
+msgid "CLI"
+msgstr ""
+
+#: vms-alpha.c:7329
+#, c-format
+msgid ", subtype: %u (%s)\n"
+msgstr ""
+
+#: vms-alpha.c:7335
+#, c-format
+msgid " offsets: isd: %u, activ: %u, symdbg: %u, imgid: %u, patch: %u\n"
+msgstr ""
+
+#: vms-alpha.c:7339
+#, c-format
+msgid " fixup info rva: "
+msgstr ""
+
+#: vms-alpha.c:7341
+#, c-format
+msgid ", symbol vector rva: "
+msgstr ""
+
+#: vms-alpha.c:7344
+#, c-format
+msgid ""
+"\n"
+" version array off: %u\n"
+msgstr ""
+
+#: vms-alpha.c:7348
+#, c-format
+msgid " img I/O count: %u, nbr channels: %u, req pri: %08x%08x\n"
+msgstr ""
+
+#: vms-alpha.c:7354
+#, c-format
+msgid " linker flags: %08x:"
+msgstr " リンカフラグ: %08x:"
+
+#: vms-alpha.c:7384
+#, c-format
+msgid " ident: 0x%08x, sysver: 0x%08x, match ctrl: %u, symvect_size: %u\n"
+msgstr ""
+
+#: vms-alpha.c:7390
+#, c-format
+msgid " BPAGE: %u"
+msgstr ""
+
+#: vms-alpha.c:7396
+#, c-format
+msgid ", ext fixup offset: %u, no_opt psect off: %u"
+msgstr ""
+
+#: vms-alpha.c:7399
+#, c-format
+msgid ", alias: %u\n"
+msgstr ""
+
+#: vms-alpha.c:7407
+#, c-format
+msgid "system version array information:\n"
+msgstr "システムãƒãƒ¼ã‚¸ãƒ§ãƒ³é…列情報:\n"
+
+#: vms-alpha.c:7411
+#, c-format
+msgid "cannot read EIHVN header\n"
+msgstr "EIHVN ヘッダを読ã¿è¾¼ã‚ã¾ã›ã‚“\n"
+
+#: vms-alpha.c:7421
+#, c-format
+msgid "cannot read EIHVN version\n"
+msgstr "EIHVN ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‚’読ã¿è¾¼ã‚ã¾ã›ã‚“\n"
+
+#: vms-alpha.c:7424
+#, c-format
+msgid " %02u "
+msgstr ""
+
+#: vms-alpha.c:7428
+msgid "BASE_IMAGE "
+msgstr ""
+
+#: vms-alpha.c:7431
+msgid "MEMORY_MANAGEMENT"
+msgstr ""
+
+#: vms-alpha.c:7434
+msgid "IO "
+msgstr ""
+
+#: vms-alpha.c:7437
+msgid "FILES_VOLUMES "
+msgstr ""
+
+#: vms-alpha.c:7440
+msgid "PROCESS_SCHED "
+msgstr ""
+
+#: vms-alpha.c:7443
+msgid "SYSGEN "
+msgstr ""
+
+#: vms-alpha.c:7446
+msgid "CLUSTERS_LOCKMGR "
+msgstr ""
+
+#: vms-alpha.c:7449
+msgid "LOGICAL_NAMES "
+msgstr ""
+
+#: vms-alpha.c:7452
+msgid "SECURITY "
+msgstr ""
+
+#: vms-alpha.c:7455
+msgid "IMAGE_ACTIVATOR "
+msgstr ""
+
+#: vms-alpha.c:7458
+msgid "NETWORKS "
+msgstr ""
+
+#: vms-alpha.c:7461
+msgid "COUNTERS "
+msgstr ""
+
+#: vms-alpha.c:7464
+msgid "STABLE "
+msgstr ""
+
+#: vms-alpha.c:7467
+msgid "MISC "
+msgstr ""
+
+#: vms-alpha.c:7470
+msgid "CPU "
+msgstr ""
+
+#: vms-alpha.c:7473
+msgid "VOLATILE "
+msgstr ""
+
+#: vms-alpha.c:7476
+msgid "SHELL "
+msgstr ""
+
+#: vms-alpha.c:7479
+msgid "POSIX "
+msgstr ""
+
+#: vms-alpha.c:7482
+msgid "MULTI_PROCESSING "
+msgstr ""
+
+#: vms-alpha.c:7485
+msgid "GALAXY "
+msgstr ""
+
+#: vms-alpha.c:7488
+msgid "*unknown* "
+msgstr "*ä¸æ˜Ž* "
+
+#: vms-alpha.c:7491
+#, c-format
+msgid ": %u.%u\n"
+msgstr ""
+
+#: vms-alpha.c:7504 vms-alpha.c:7763
+#, c-format
+msgid "cannot read EIHA\n"
+msgstr "EIHA を読ã¿è¾¼ã‚ã¾ã›ã‚“\n"
+
+#: vms-alpha.c:7507
+#, c-format
+msgid "Image activation: (size=%u)\n"
+msgstr ""
+
+#: vms-alpha.c:7509
+#, c-format
+msgid " First address : 0x%08x 0x%08x\n"
+msgstr " 1番目ã®ã‚¢ãƒ‰ãƒ¬ã‚¹: 0x%08x 0x%08x\n"
+
+#: vms-alpha.c:7512
+#, c-format
+msgid " Second address: 0x%08x 0x%08x\n"
+msgstr " 2番目ã®ã‚¢ãƒ‰ãƒ¬ã‚¹: 0x%08x 0x%08x\n"
+
+#: vms-alpha.c:7515
+#, c-format
+msgid " Third address : 0x%08x 0x%08x\n"
+msgstr " 3番目ã®ã‚¢ãƒ‰ãƒ¬ã‚¹: 0x%08x 0x%08x\n"
+
+#: vms-alpha.c:7518
+#, c-format
+msgid " Fourth address: 0x%08x 0x%08x\n"
+msgstr " 4番目ã®ã‚¢ãƒ‰ãƒ¬ã‚¹: 0x%08x 0x%08x\n"
+
+#: vms-alpha.c:7521
+#, c-format
+msgid " Shared image : 0x%08x 0x%08x\n"
+msgstr " 共有イメージ : 0x%08x 0x%08x\n"
+
+#: vms-alpha.c:7532
+#, c-format
+msgid "cannot read EIHI\n"
+msgstr "EIHI を読ã¿è¾¼ã‚ã¾ã›ã‚“\n"
+
+#: vms-alpha.c:7535
+#, c-format
+msgid "Image identification: (major: %u, minor: %u)\n"
+msgstr ""
+
+#: vms-alpha.c:7538
+#, c-format
+msgid " image name : %.*s\n"
+msgstr " イメージå : %.*s\n"
+
+#: vms-alpha.c:7540
+#, c-format
+msgid " link time : %s\n"
+msgstr " リンク時刻 : %s\n"
+
+#: vms-alpha.c:7542
+#, c-format
+msgid " image ident : %.*s\n"
+msgstr ""
+
+#: vms-alpha.c:7544
+#, c-format
+msgid " linker ident : %.*s\n"
+msgstr ""
+
+#: vms-alpha.c:7546
+#, c-format
+msgid " image build ident: %.*s\n"
+msgstr ""
+
+#: vms-alpha.c:7556
+#, c-format
+msgid "cannot read EIHS\n"
+msgstr "EIHS を読ã¿è¾¼ã‚ã¾ã›ã‚“\n"
+
+#: vms-alpha.c:7559
+#, c-format
+msgid "Image symbol & debug table: (major: %u, minor: %u)\n"
+msgstr "イメージシンボル&デãƒãƒƒã‚°è¡¨: (メジャー: %uã€ãƒžã‚¤ãƒŠãƒ¼: %u)\n"
+
+#: vms-alpha.c:7564
+#, c-format
+msgid " debug symbol table : vbn: %u, size: %u (0x%x)\n"
+msgstr " デãƒãƒƒã‚°ã‚·ãƒ³ãƒœãƒ«è¡¨ : vbn: %uã€ã‚µã‚¤ã‚º: %u (0x%x)\n"
+
+#: vms-alpha.c:7568
+#, c-format
+msgid " global symbol table: vbn: %u, records: %u\n"
+msgstr " 大域シンボル表 : vbn: %uã€ãƒ¬ã‚³ãƒ¼ãƒ‰: %u\n"
+
+#: vms-alpha.c:7572
+#, c-format
+msgid " debug module table : vbn: %u, size: %u\n"
+msgstr " デãƒãƒƒã‚°ãƒ¢ã‚¸ãƒ¥ãƒ¼ãƒ«è¡¨: vbn: %uã€ã‚µã‚¤ã‚º: %u\n"
+
+#: vms-alpha.c:7585
+#, c-format
+msgid "cannot read EISD\n"
+msgstr "EISD を読ã¿è¾¼ã‚ã¾ã›ã‚“\n"
+
+#: vms-alpha.c:7595
+#, c-format
+msgid "Image section descriptor: (major: %u, minor: %u, size: %u, offset: %u)\n"
+msgstr "イメージセクション記述å­: (メジャー: %uã€ãƒžã‚¤ãƒŠãƒ¼: %uã€ã‚µã‚¤ã‚º: %uã€ã‚ªãƒ•ã‚»ãƒƒãƒˆ: %u)\n"
+
+#: vms-alpha.c:7602
+#, c-format
+msgid " section: base: 0x%08x%08x size: 0x%08x\n"
+msgstr ""
+
+#: vms-alpha.c:7607
+#, c-format
+msgid " flags: 0x%04x"
+msgstr "フラグ: 0x%04x"
+
+#: vms-alpha.c:7644
+#, c-format
+msgid " vbn: %u, pfc: %u, matchctl: %u type: %u ("
+msgstr ""
+
+#: vms-alpha.c:7650
+msgid "NORMAL"
+msgstr "NORMAL"
+
+#: vms-alpha.c:7653
+msgid "SHRFXD"
+msgstr "SHRFXD"
+
+#: vms-alpha.c:7656
+msgid "PRVFXD"
+msgstr "PRVFXD"
+
+#: vms-alpha.c:7659
+msgid "SHRPIC"
+msgstr "SHRPIC"
+
+#: vms-alpha.c:7662
+msgid "PRVPIC"
+msgstr "PRVPIC"
+
+#: vms-alpha.c:7665
+msgid "USRSTACK"
+msgstr "USRSTACK"
+
+#: vms-alpha.c:7673
+#, c-format
+msgid " ident: 0x%08x, name: %.*s\n"
+msgstr ""
+
+#: vms-alpha.c:7683
+#, c-format
+msgid "cannot read DMT\n"
+msgstr "DMT を読ã¿è¾¼ã‚ã¾ã›ã‚“\n"
+
+#: vms-alpha.c:7687
+#, c-format
+msgid "Debug module table:\n"
+msgstr "デãƒãƒƒã‚°ãƒ¢ã‚¸ãƒ¥ãƒ¼ãƒ«è¡¨:\n"
+
+#: vms-alpha.c:7696
+#, c-format
+msgid "cannot read DMT header\n"
+msgstr "DMT ヘッダを読ã¿è¾¼ã‚ã¾ã›ã‚“\n"
+
+#: vms-alpha.c:7701
+#, c-format
+msgid " module offset: 0x%08x, size: 0x%08x, (%u psects)\n"
+msgstr " モジュールオフセット: 0x%08x, サイズ: 0x%08x, (%u psects)\n"
+
+#: vms-alpha.c:7711
+#, c-format
+msgid "cannot read DMT psect\n"
+msgstr "DMT psect を読ã¿è¾¼ã‚ã¾ã›ã‚“\n"
+
+#: vms-alpha.c:7714
+#, c-format
+msgid " psect start: 0x%08x, length: %u\n"
+msgstr " psect 開始: 0x%08x, é•·ã•: %u\n"
+
+#: vms-alpha.c:7727
+#, c-format
+msgid "cannot read DST\n"
+msgstr "DST を読ã¿è¾¼ã‚ã¾ã›ã‚“\n"
+
+#: vms-alpha.c:7737
+#, c-format
+msgid "cannot read GST\n"
+msgstr "GST を読ã¿è¾¼ã‚ã¾ã›ã‚“\n"
+
+#: vms-alpha.c:7741
+#, c-format
+msgid "Global symbol table:\n"
+msgstr "大域シンボル表:\n"
+
+#: vms-alpha.c:7769
+#, c-format
+msgid "Image activator fixup: (major: %u, minor: %u)\n"
+msgstr ""
+
+#: vms-alpha.c:7772
+#, c-format
+msgid " iaflink : 0x%08x %08x\n"
+msgstr " iaflink : 0x%08x %08x\n"
+
+#: vms-alpha.c:7775
+#, c-format
+msgid " fixuplnk: 0x%08x %08x\n"
+msgstr " fixuplnk: 0x%08x %08x\n"
+
+#: vms-alpha.c:7778
+#, c-format
+msgid " size : %u\n"
+msgstr " サイズ: %u\n"
+
+#: vms-alpha.c:7780
+#, c-format
+msgid " flags: 0x%08x\n"
+msgstr " フラグ: 0x%08x\n"
+
+#: vms-alpha.c:7784
+#, c-format
+msgid " qrelfixoff: %5u, lrelfixoff: %5u\n"
+msgstr " qrelfixoff: %5u, lrelfixoff: %5u\n"
+
+#: vms-alpha.c:7788
+#, c-format
+msgid " qdotadroff: %5u, ldotadroff: %5u\n"
+msgstr " qdotadroff: %5u, ldotadroff: %5u\n"
+
+#: vms-alpha.c:7792
+#, c-format
+msgid " codeadroff: %5u, lpfixoff : %5u\n"
+msgstr " codeadroff: %5u, lpfixoff : %5u\n"
+
+#: vms-alpha.c:7795
+#, c-format
+msgid " chgprtoff : %5u\n"
+msgstr " chgprtoff : %5u\n"
+
+#: vms-alpha.c:7798
+#, c-format
+msgid " shlstoff : %5u, shrimgcnt : %5u\n"
+msgstr " shlstoff : %5u, shrimgcnt : %5u\n"
+
+#: vms-alpha.c:7800
+#, c-format
+msgid " shlextra : %5u, permctx : %5u\n"
+msgstr " shlextra : %5u, permctx : %5u\n"
+
+#: vms-alpha.c:7803
+#, c-format
+msgid " base_va : 0x%08x\n"
+msgstr " base_va : 0x%08x\n"
+
+#: vms-alpha.c:7805
+#, c-format
+msgid " lppsbfixoff: %5u\n"
+msgstr " lppsbfixoff: %5u\n"
+
+#: vms-alpha.c:7813
+#, c-format
+msgid " Shareable images:\n"
+msgstr " 共有å¯èƒ½ã‚¤ãƒ¡ãƒ¼ã‚¸:\n"
+
+#: vms-alpha.c:7817
+#, c-format
+msgid " %u: size: %u, flags: 0x%02x, name: %.*s\n"
+msgstr " %u: サイズ: %u, フラグ: 0x%02x, åå‰: %.*s\n"
+
+#: vms-alpha.c:7824
+#, c-format
+msgid " quad-word relocation fixups:\n"
+msgstr " 4å€ãƒ¯ãƒ¼ãƒ‰å†é…置修正:\n"
+
+#: vms-alpha.c:7829
+#, c-format
+msgid " long-word relocation fixups:\n"
+msgstr " 長ワードå†é…置修正:\n"
+
+#: vms-alpha.c:7834
+#, c-format
+msgid " quad-word .address reference fixups:\n"
+msgstr " 4å€ãƒ¯ãƒ¼ãƒ‰ .address å‚照修正:\n"
+
+#: vms-alpha.c:7839
+#, c-format
+msgid " long-word .address reference fixups:\n"
+msgstr " 長ワード .address å‚照修正:\n"
+
+#: vms-alpha.c:7844
+#, c-format
+msgid " Code Address Reference Fixups:\n"
+msgstr " コードアドレスå‚照修正:\n"
+
+#: vms-alpha.c:7849
+#, c-format
+msgid " Linkage Pairs Referece Fixups:\n"
+msgstr ""
+
+#: vms-alpha.c:7858
+#, c-format
+msgid " Change Protection (%u entries):\n"
+msgstr ""
+
+#: vms-alpha.c:7863
+#, c-format
+msgid " base: 0x%08x %08x, size: 0x%08x, prot: 0x%08x "
+msgstr " ベース: 0x%08x %08x, サイズ: 0x%08x, prot: 0x%08x "
+
+#. FIXME: we do not yet support relocatable link. It is not obvious
+#. how to do it for debug infos.
+#: vms-alpha.c:8694
+msgid "%P: relocatable link is not supported\n"
+msgstr "%P: å†é…ç½®å¯èƒ½ãƒªãƒ³ã‚¯ã¯ã‚µãƒãƒ¼ãƒˆã•ã‚Œã¦ã„ã¾ã›ã‚“\n"
+
+#: vms-alpha.c:8764
+msgid "%P: multiple entry points: in modules %B and %B\n"
+msgstr "%P: 複数ã®ã‚¨ãƒ³ãƒˆãƒªãƒã‚¤ãƒ³ãƒˆ: モジュール %B 内㨠%B 内\n"
+
+#: vms-lib.c:1421
+#, c-format
+msgid "could not open shared image '%s' from '%s'"
+msgstr "共有イメージ '%s' ('%s' ã‹ã‚‰) ã‚’é–‹ãã“ã¨ãŒã§ãã¾ã›ã‚“"
+
+#: vms-misc.c:360
+msgid "_bfd_vms_output_counted called with zero bytes"
+msgstr "_bfd_vms_output_counted ãŒã‚¼ãƒ­ãƒã‚¤ãƒˆã§å‘¼ã³å‡ºã•ã‚Œã¾ã—ãŸ"
+
+#: vms-misc.c:365
+msgid "_bfd_vms_output_counted called with too many bytes"
+msgstr "_bfd_vms_output_counted 呼ã³å‡ºã—時ã®ãƒã‚¤ãƒˆæ•°ãŒå¤§ãã™ãŽã¾ã™"
+
+#: xcofflink.c:836
+#, c-format
+msgid "%s: XCOFF shared object when not producing XCOFF output"
+msgstr "%s: XCOFF ㌠XCOFF 出力生æˆæ™‚以外ã«ã‚ªãƒ–ジェクトを共有ã—ã¾ã—ãŸ"
+
+#: xcofflink.c:857
+#, c-format
+msgid "%s: dynamic object with no .loader section"
+msgstr "%s: 動的オブジェクト㫠.loader セクションãŒã‚ã‚Šã¾ã›ã‚“"
+
+#: xcofflink.c:1416
+msgid "%B: `%s' has line numbers but no enclosing section"
+msgstr "%B: `%s' ã¯è¡Œç•ªå·ã‚’æŒã¡ã¾ã™ãŒã€ã‚»ã‚¯ã‚·ãƒ§ãƒ³ã‚’囲ã„込んã§ã„ã¾ã›ã‚“"
+
+#: xcofflink.c:1468
+msgid "%B: class %d symbol `%s' has no aux entries"
+msgstr "%B: クラス %d シンボル `%s' ã¯è£œåŠ©ã‚¨ãƒ³ãƒˆãƒªã‚’æŒã£ã¦ã„ã¾ã›ã‚“"
+
+#: xcofflink.c:1490
+msgid "%B: symbol `%s' has unrecognized csect type %d"
+msgstr "%B: シンボル `%s' ãŒèªè­˜ã§ããªã„ csect åž‹ %d ã‚’æŒã£ã¦ã„ã¾ã™"
+
+#: xcofflink.c:1502
+msgid "%B: bad XTY_ER symbol `%s': class %d scnum %d scnlen %d"
+msgstr "%B: é–“é•ã£ãŸ XTY_ER シンボル `%s': クラス %d scnum %d scnlen %d"
+
+#: xcofflink.c:1531
+msgid "%B: XMC_TC0 symbol `%s' is class %d scnlen %d"
+msgstr "%B: XMC_TC0 シンボル `%s' 㯠class %d scnlen %d ã§ã™"
+
+#: xcofflink.c:1677
+msgid "%B: csect `%s' not in enclosing section"
+msgstr "%B: csect `%s' ãŒã‚»ã‚¯ã‚·ãƒ§ãƒ³ã®å›²ã¿ã®ä¸­ã«ã‚ã‚Šã¾ã›ã‚“"
+
+#: xcofflink.c:1784
+msgid "%B: misplaced XTY_LD `%s'"
+msgstr "%B: é–“é•ã£ãŸä½ç½®ã«ã‚ã‚‹ XTY_LD `%s' ã§ã™"
+
+#: xcofflink.c:2103
+msgid "%B: reloc %s:%d not in csect"
+msgstr "%B: å†é…ç½® %s:%d ㌠csect 内ã«ã‚ã‚Šã¾ã›ã‚“"
+
+#: xcofflink.c:3194
+#, c-format
+msgid "%s: no such symbol"
+msgstr "%s: ãã®ã‚ˆã†ãªã‚·ãƒ³ãƒœãƒ«ã¯ã‚ã‚Šã¾ã›ã‚“"
+
+#: xcofflink.c:3299
+#, c-format
+msgid "warning: attempt to export undefined symbol `%s'"
+msgstr "警告: 未定義シンボル `%s' をエクスãƒãƒ¼ãƒˆã—よã†ã¨ã—ã¦ã„ã¾ã™"
+
+#: xcofflink.c:3681
+msgid "error: undefined symbol __rtinit"
+msgstr "エラー: 未定義シンボル __rtinit ã§ã™"
+
+#: xcofflink.c:4060
+msgid "%B: loader reloc in unrecognized section `%s'"
+msgstr "%B: èªè­˜ã§ããªã„セクション `%s' 内ã«ã‚るローダå†é…ç½®ã§ã™"
+
+#: xcofflink.c:4071
+msgid "%B: `%s' in loader reloc but not loader sym"
+msgstr "%B: ローダå†é…置内㫠`%s' ãŒã‚ã‚Šã¾ã™ãŒãƒ­ãƒ¼ãƒ€ã‚·ãƒ³ãƒœãƒ«ãŒã‚ã‚Šã¾ã›ã‚“"
+
+#: xcofflink.c:4087
+msgid "%B: loader reloc in read-only section %A"
+msgstr "%B: 読ã¿è¾¼ã¿å°‚用セクション %A 内ã«ã‚るローダå†é…ç½®ã§ã™"
+
+#: xcofflink.c:5109
+#, c-format
+msgid "TOC overflow: 0x%lx > 0x10000; try -mminimal-toc when compiling"
+msgstr "TOC オーãƒãƒ¼ãƒ•ãƒ­ãƒ¼: 0x%lx > 0x10000 -- コンパイル時㫠-mminimal-toc を試ã—ã¾ã—ょã†"
+
+#: elf32-ia64.c:628 elf64-ia64.c:628
+msgid "%B: Can't relax br at 0x%lx in section `%A'. Please use brl or indirect branch."
+msgstr ""
+
+#: elf32-ia64.c:2290 elf64-ia64.c:2290
+msgid "@pltoff reloc against local symbol"
+msgstr "局所シンボルã«å¯¾ã™ã‚‹ @pltoff å†é…ç½®ã§ã™"
+
+#: elf32-ia64.c:3693 elf64-ia64.c:3693
+#, c-format
+msgid "%s: short data segment overflowed (0x%lx >= 0x400000)"
+msgstr "%s: 短ã„データセグメントãŒæº¢ã‚Œã¾ã—㟠(0x%lx >= 0x400000)"
+
+#: elf32-ia64.c:3704 elf64-ia64.c:3704
+#, c-format
+msgid "%s: __gp does not cover short data segment"
+msgstr ""
+
+#: elf32-ia64.c:3971 elf64-ia64.c:3971
+msgid "%B: non-pic code with imm relocation against dynamic symbol `%s'"
+msgstr "%B: 動的シンボル `%s' ã«å¯¾ã™ã‚‹ iim å†é…置付ãéž pic コードã§ã™"
+
+#: elf32-ia64.c:4038 elf64-ia64.c:4038
+msgid "%B: @gprel relocation against dynamic symbol %s"
+msgstr "%B: 動的シンボル %s ã«å¯¾ã™ã‚‹ @gprel å†é…ç½®ã§ã™"
+
+#: elf32-ia64.c:4101 elf64-ia64.c:4101
+msgid "%B: linking non-pic code in a position independent executable"
+msgstr "%B: ä½ç½®éžä¾å­˜å®Ÿè¡Œãƒ•ã‚¡ã‚¤ãƒ«å†…ã«éž pic コードをリンクã—ã¦ã„ã¾ã™"
+
+#: elf32-ia64.c:4238 elf64-ia64.c:4238
+msgid "%B: @internal branch to dynamic symbol %s"
+msgstr "%B: 動的シンボル %s ã¸ã® @internal 分å²ã§ã™"
+
+#: elf32-ia64.c:4240 elf64-ia64.c:4240
+msgid "%B: speculation fixup to dynamic symbol %s"
+msgstr ""
+
+#: elf32-ia64.c:4242 elf64-ia64.c:4242
+msgid "%B: @pcrel relocation against dynamic symbol %s"
+msgstr "%B: 動的シンボル %s ã«å¯¾ã™ã‚‹ @pcrel å†é…ç½®ã§ã™"
+
+#: elf32-ia64.c:4439 elf64-ia64.c:4439
+msgid "unsupported reloc"
+msgstr "サãƒãƒ¼ãƒˆã•ã‚Œã¦ã„ãªã„å†é…ç½®ã§ã™"
+
+#: elf32-ia64.c:4477 elf64-ia64.c:4477
+msgid "%B: missing TLS section for relocation %s against `%s' at 0x%lx in section `%A'."
+msgstr "%B: å†é…ç½® %s (`%s' ã«å¯¾ã™ã‚‹ã€ä½ç½® 0x%lxã€ã‚»ã‚¯ã‚·ãƒ§ãƒ³ `%A') 用㮠TLS セクションãŒã‚ã‚Šã¾ã›ã‚“。"
+
+#: elf32-ia64.c:4492 elf64-ia64.c:4492
+msgid "%B: Can't relax br (%s) to `%s' at 0x%lx in section `%A' with size 0x%lx (> 0x1000000)."
+msgstr ""
+
+#: elf32-ia64.c:4754 elf64-ia64.c:4754
+msgid "%B: linking trap-on-NULL-dereference with non-trapping files"
+msgstr ""
+
+#: elf32-ia64.c:4763 elf64-ia64.c:4763
+msgid "%B: linking big-endian files with little-endian files"
+msgstr "%B: ビッグエンディアンã®ãƒ•ã‚¡ã‚¤ãƒ«ã¨ãƒªãƒˆãƒ«ã‚¨ãƒ³ãƒ‡ã‚£ã‚¢ãƒ³ã®ãƒ•ã‚¡ã‚¤ãƒ«ã‚’リンクã—ã¦ã„ã¾ã™"
+
+#: elf32-ia64.c:4772 elf64-ia64.c:4772
+msgid "%B: linking 64-bit files with 32-bit files"
+msgstr "%B: 64 ビットファイル㨠32 ビットファイルをリンクã—ã¦ã„ã¾ã™"
+
+#: elf32-ia64.c:4781 elf64-ia64.c:4781
+msgid "%B: linking constant-gp files with non-constant-gp files"
+msgstr "%B: 定数 gp ファイルã¨éžå®šæ•° gp ファイルをリンクã—ã¦ã„ã¾ã™"
+
+#: elf32-ia64.c:4791 elf64-ia64.c:4791
+msgid "%B: linking auto-pic files with non-auto-pic files"
+msgstr "%B: 自動 pic ファイルã¨éžè‡ªå‹• pic ファイルをリンクã—ã¦ã„ã¾ã™"
+
+#: peigen.c:1002 pepigen.c:1002 pex64igen.c:1002
+#, c-format
+msgid "%s: line number overflow: 0x%lx > 0xffff"
+msgstr "%s: 行番å·ãŒæº¢ã‚Œã¾ã—ãŸ: 0x%lx > 0xffff"
+
+#: peigen.c:1029 pepigen.c:1029 pex64igen.c:1029
+msgid "Export Directory [.edata (or where ever we found it)]"
+msgstr "エクスãƒãƒ¼ãƒˆãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒª [.edata (ã¾ãŸã¯ã“ã“ã¾ã§ã«è¦‹ã¤ã‹ã£ãŸå ´æ‰€)]"
+
+#: peigen.c:1030 pepigen.c:1030 pex64igen.c:1030
+msgid "Import Directory [parts of .idata]"
+msgstr "インãƒãƒ¼ãƒˆãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒª [.idata ã®éƒ¨åˆ†]"
+
+#: peigen.c:1031 pepigen.c:1031 pex64igen.c:1031
+msgid "Resource Directory [.rsrc]"
+msgstr "リソースディレクトリ [.rsrc]"
+
+#: peigen.c:1032 pepigen.c:1032 pex64igen.c:1032
+msgid "Exception Directory [.pdata]"
+msgstr "例外ディレクトリ [.pdata]"
+
+#: peigen.c:1033 pepigen.c:1033 pex64igen.c:1033
+msgid "Security Directory"
+msgstr "セキュリティディレクトリ"
+
+#: peigen.c:1034 pepigen.c:1034 pex64igen.c:1034
+msgid "Base Relocation Directory [.reloc]"
+msgstr "基本å†é…置ディレクトリ [.reloc]"
+
+#: peigen.c:1035 pepigen.c:1035 pex64igen.c:1035
+msgid "Debug Directory"
+msgstr "デãƒãƒƒã‚°ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒª"
+
+#: peigen.c:1036 pepigen.c:1036 pex64igen.c:1036
+msgid "Description Directory"
+msgstr "記述å­ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒª"
+
+#: peigen.c:1037 pepigen.c:1037 pex64igen.c:1037
+msgid "Special Directory"
+msgstr "スペシャルディレクトリ"
+
+#: peigen.c:1038 pepigen.c:1038 pex64igen.c:1038
+msgid "Thread Storage Directory [.tls]"
+msgstr "スレッド記憶ディレクトリ [.tls]"
+
+#: peigen.c:1039 pepigen.c:1039 pex64igen.c:1039
+msgid "Load Configuration Directory"
+msgstr "ロード設定ディレクトリ"
+
+#: peigen.c:1040 pepigen.c:1040 pex64igen.c:1040
+msgid "Bound Import Directory"
+msgstr "境界 Import ディレクトリ"
+
+#: peigen.c:1041 pepigen.c:1041 pex64igen.c:1041
+msgid "Import Address Table Directory"
+msgstr "インãƒãƒ¼ãƒˆã‚¢ãƒ‰ãƒ¬ã‚¹è¡¨ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒª"
+
+#: peigen.c:1042 pepigen.c:1042 pex64igen.c:1042
+msgid "Delay Import Directory"
+msgstr "é…延インãƒãƒ¼ãƒˆãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒª"
+
+#: peigen.c:1043 pepigen.c:1043 pex64igen.c:1043
+msgid "CLR Runtime Header"
+msgstr "CLR ランタイムヘッダ"
+
+#: peigen.c:1044 pepigen.c:1044 pex64igen.c:1044
+msgid "Reserved"
+msgstr "予約済"
+
+#: peigen.c:1104 pepigen.c:1104 pex64igen.c:1104
+#, c-format
+msgid ""
+"\n"
+"There is an import table, but the section containing it could not be found\n"
+msgstr ""
+"\n"
+"インãƒãƒ¼ãƒˆè¡¨ãŒã‚ã‚Šã¾ã™ãŒã€ã“ã“ã‚’å«ã‚“ã§ã„るセクションを見ã¤ã‘られã¾ã›ã‚“ã§ã—ãŸ\n"
+
+#: peigen.c:1109 pepigen.c:1109 pex64igen.c:1109
+#, c-format
+msgid ""
+"\n"
+"There is an import table in %s at 0x%lx\n"
+msgstr ""
+"\n"
+"%s 内㮠0x%lx ã«ã‚¤ãƒ³ãƒãƒ¼ãƒˆè¡¨ãŒã‚ã‚Šã¾ã™\n"
+
+#: peigen.c:1151 pepigen.c:1151 pex64igen.c:1151
+#, c-format
+msgid ""
+"\n"
+"Function descriptor located at the start address: %04lx\n"
+msgstr ""
+"\n"
+"開始アドレスã«ä½ç½®ã—ã¦ã„る関数記述å­: %04lx\n"
+
+#: peigen.c:1154 pepigen.c:1154 pex64igen.c:1154
+#, c-format
+msgid "\tcode-base %08lx toc (loadable/actual) %08lx/%08lx\n"
+msgstr "\tコードベース %08lx toc (loadable/actual) %08lx/%08lx\n"
+
+#: peigen.c:1162 pepigen.c:1162 pex64igen.c:1162
+#, c-format
+msgid ""
+"\n"
+"No reldata section! Function descriptor not decoded.\n"
+msgstr ""
+"\n"
+"reldata セクションãŒã‚ã‚Šã¾ã›ã‚“! 関数記述å­ãŒãƒ‡ã‚³ãƒ¼ãƒ‰ã•ã‚Œã¾ã›ã‚“ã§ã—ãŸã€‚\n"
+
+#: peigen.c:1167 pepigen.c:1167 pex64igen.c:1167
+#, c-format
+msgid ""
+"\n"
+"The Import Tables (interpreted %s section contents)\n"
+msgstr ""
+"\n"
+"インãƒãƒ¼ãƒˆè¡¨ ( %sセクションã®å†…容を解釈)\n"
+
+#: peigen.c:1170 pepigen.c:1170 pex64igen.c:1170
+#, c-format
+msgid ""
+" vma: Hint Time Forward DLL First\n"
+" Table Stamp Chain Name Thunk\n"
+msgstr ""
+" vma: Hint Time Forward DLL First\n"
+" Table Stamp Chain Name Thunk\n"
+
+#: peigen.c:1218 pepigen.c:1218 pex64igen.c:1218
+#, c-format
+msgid ""
+"\n"
+"\tDLL Name: %s\n"
+msgstr ""
+"\n"
+"\tDLL å: %s\n"
+
+#: peigen.c:1229 pepigen.c:1229 pex64igen.c:1229
+#, c-format
+msgid "\tvma: Hint/Ord Member-Name Bound-To\n"
+msgstr ""
+
+#: peigen.c:1254 pepigen.c:1254 pex64igen.c:1254
+#, c-format
+msgid ""
+"\n"
+"There is a first thunk, but the section containing it could not be found\n"
+msgstr ""
+
+#: peigen.c:1415 pepigen.c:1415 pex64igen.c:1415
+#, c-format
+msgid ""
+"\n"
+"There is an export table, but the section containing it could not be found\n"
+msgstr ""
+"\n"
+"エクスãƒãƒ¼ãƒˆè¡¨ãŒã‚ã‚Šã¾ã™ãŒã€ãれをå«ã‚€ã‚»ã‚¯ã‚·ãƒ§ãƒ³ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸ\n"
+
+#: peigen.c:1424 pepigen.c:1424 pex64igen.c:1424
+#, c-format
+msgid ""
+"\n"
+"There is an export table in %s, but it does not fit into that section\n"
+msgstr ""
+"\n"
+"%s 内ã«ã‚¨ã‚¯ã‚¹ãƒãƒ¼ãƒˆè¡¨ãŒã‚ã‚Šã¾ã™ãŒã€ãã®ã‚»ã‚¯ã‚·ãƒ§ãƒ³å†…ã«å…¥ã‚Šã¾ã›ã‚“\n"
+
+#: peigen.c:1430 pepigen.c:1430 pex64igen.c:1430
+#, c-format
+msgid ""
+"\n"
+"There is an export table in %s at 0x%lx\n"
+msgstr ""
+"\n"
+"%s ã® 0x%lx ã«ã‚¨ã‚¯ã‚¹ãƒãƒ¼ãƒˆè¡¨ãŒã‚ã‚Šã¾ã™\n"
+
+#: peigen.c:1458 pepigen.c:1458 pex64igen.c:1458
+#, c-format
+msgid ""
+"\n"
+"The Export Tables (interpreted %s section contents)\n"
+"\n"
+msgstr ""
+"\n"
+"エクスãƒãƒ¼ãƒˆè¡¨ (%s セクションã®å†…容を解釈)\n"
+"\n"
+
+#: peigen.c:1462 pepigen.c:1462 pex64igen.c:1462
+#, c-format
+msgid "Export Flags \t\t\t%lx\n"
+msgstr "エクスãƒãƒ¼ãƒˆãƒ•ãƒ©ã‚° \t\t\t%lx\n"
+
+#: peigen.c:1465 pepigen.c:1465 pex64igen.c:1465
+#, c-format
+msgid "Time/Date stamp \t\t%lx\n"
+msgstr "時刻/日付スタンプ \t\t%lx\n"
+
+#: peigen.c:1468 pepigen.c:1468 pex64igen.c:1468
+#, c-format
+msgid "Major/Minor \t\t\t%d/%d\n"
+msgstr "Major/Minor \t\t\t%d/%d\n"
+
+#: peigen.c:1471 pepigen.c:1471 pex64igen.c:1471
+#, c-format
+msgid "Name \t\t\t\t"
+msgstr "åå‰ \t\t\t\t"
+
+#: peigen.c:1477 pepigen.c:1477 pex64igen.c:1477
+#, c-format
+msgid "Ordinal Base \t\t\t%ld\n"
+msgstr "åºæ•°ãƒ™ãƒ¼ã‚¹ \t\t\t%ld\n"
+
+#: peigen.c:1480 pepigen.c:1480 pex64igen.c:1480
+#, c-format
+msgid "Number in:\n"
+msgstr "å„種ã®æ•°å€¤:\n"
+
+#: peigen.c:1483 pepigen.c:1483 pex64igen.c:1483
+#, c-format
+msgid "\tExport Address Table \t\t%08lx\n"
+msgstr "\tExport アドレステーブル\t\t%08lx\n"
+
+#: peigen.c:1487 pepigen.c:1487 pex64igen.c:1487
+#, c-format
+msgid "\t[Name Pointer/Ordinal] Table\t%08lx\n"
+msgstr "\t[åå‰ãƒã‚¤ãƒ³ã‚¿/åºæ•°] テーブル\t%08lx\n"
+
+#: peigen.c:1490 pepigen.c:1490 pex64igen.c:1490
+#, c-format
+msgid "Table Addresses\n"
+msgstr "表アドレス\n"
+
+#: peigen.c:1493 pepigen.c:1493 pex64igen.c:1493
+#, c-format
+msgid "\tExport Address Table \t\t"
+msgstr "\tエクスãƒãƒ¼ãƒˆã‚¢ãƒ‰ãƒ¬ã‚¹è¡¨\t\t"
+
+#: peigen.c:1498 pepigen.c:1498 pex64igen.c:1498
+#, c-format
+msgid "\tName Pointer Table \t\t"
+msgstr "\tåå‰ãƒã‚¤ãƒ³ã‚¿ãƒ†ãƒ¼ãƒ–ル \t\t"
+
+#: peigen.c:1503 pepigen.c:1503 pex64igen.c:1503
+#, c-format
+msgid "\tOrdinal Table \t\t\t"
+msgstr "\tåºæ•°ãƒ†ãƒ¼ãƒ–ル \t\t\t"
+
+#: peigen.c:1517 pepigen.c:1517 pex64igen.c:1517
+#, c-format
+msgid ""
+"\n"
+"Export Address Table -- Ordinal Base %ld\n"
+msgstr ""
+"\n"
+"Export アドレステーブル -- åºæ•°ãƒ™ãƒ¼ã‚¹ %ld\n"
+
+#: peigen.c:1536 pepigen.c:1536 pex64igen.c:1536
+msgid "Forwarder RVA"
+msgstr "Forwarder RVA"
+
+#: peigen.c:1547 pepigen.c:1547 pex64igen.c:1547
+msgid "Export RVA"
+msgstr "Export RVA"
+
+#: peigen.c:1554 pepigen.c:1554 pex64igen.c:1554
+#, c-format
+msgid ""
+"\n"
+"[Ordinal/Name Pointer] Table\n"
+msgstr ""
+"\n"
+"[åºæ•°/åå‰ãƒã‚¤ãƒ³ã‚¿] テーブル\n"
+
+#: peigen.c:1614 peigen.c:1797 pepigen.c:1614 pepigen.c:1797 pex64igen.c:1614
+#: pex64igen.c:1797
+#, c-format
+msgid "Warning, .pdata section size (%ld) is not a multiple of %d\n"
+msgstr "警告ã€.pdata セクションサイズ (%ld) ㌠%d ã®å€æ•°ã§ã¯ã‚ã‚Šã¾ã›ã‚“\n"
+
+#: peigen.c:1621 pepigen.c:1621 pex64igen.c:1621
+#, c-format
+msgid " vma:\t\t\tBegin Address End Address Unwind Info\n"
+msgstr " vma:\t\t\t開始アドレス 終了アドレス Unwind 情報\n"
+
+#: peigen.c:1623 pepigen.c:1623 pex64igen.c:1623
+#, c-format
+msgid ""
+" vma:\t\tBegin End EH EH PrologEnd Exception\n"
+" \t\tAddress Address Handler Data Address Mask\n"
+msgstr ""
+" vma:\t\t開始 終了 EH EH PrologEnd 例外\n"
+" \t\tアドレス アドレス ãƒãƒ³ãƒ‰ãƒ© データ アドレス マスク\n"
+
+#: peigen.c:1697 pepigen.c:1697 pex64igen.c:1697
+#, c-format
+msgid " Register save millicode"
+msgstr " レジスタä¿å­˜ãƒŸãƒªã‚³ãƒ¼ãƒ‰"
+
+#: peigen.c:1700 pepigen.c:1700 pex64igen.c:1700
+#, c-format
+msgid " Register restore millicode"
+msgstr " レジスタ復元ミリコード"
+
+#: peigen.c:1703 pepigen.c:1703 pex64igen.c:1703
+#, c-format
+msgid " Glue code sequence"
+msgstr " グルーコード列"
+
+#: peigen.c:1803 pepigen.c:1803 pex64igen.c:1803
+#, c-format
+msgid ""
+" vma:\t\tBegin Prolog Function Flags Exception EH\n"
+" \t\tAddress Length Length 32b exc Handler Data\n"
+msgstr ""
+" vma:\t\t開始 Prolog 関数 フラグ 例外 EH\n"
+" \t\tアドレス é•· é•· 32b exc ãƒãƒ³ãƒ‰ãƒ© データ\n"
+
+#: peigen.c:1929 pepigen.c:1929 pex64igen.c:1929
+#, c-format
+msgid ""
+"\n"
+"\n"
+"PE File Base Relocations (interpreted .reloc section contents)\n"
+msgstr ""
+"\n"
+"\n"
+"PE ファイルベースå†é…ç½® (.reloc セクションã®å†…容を解釈)\n"
+
+#: peigen.c:1958 pepigen.c:1958 pex64igen.c:1958
+#, c-format
+msgid ""
+"\n"
+"Virtual Address: %08lx Chunk size %ld (0x%lx) Number of fixups %ld\n"
+msgstr ""
+"\n"
+"仮想アドレス: %08lx ãƒãƒ£ãƒ³ã‚¯ã‚µã‚¤ã‚º %ld (0x%lx) fixups ã®å€‹æ•° %ld\n"
+
+#: peigen.c:1971 pepigen.c:1971 pex64igen.c:1971
+#, c-format
+msgid "\treloc %4d offset %4x [%4lx] %s"
+msgstr "\treloc %4d オフセット %4x [%4lx] %s"
+
+#. The MS dumpbin program reportedly ands with 0xff0f before
+#. printing the characteristics field. Not sure why. No reason to
+#. emulate it here.
+#: peigen.c:2010 pepigen.c:2010 pex64igen.c:2010
+#, c-format
+msgid ""
+"\n"
+"Characteristics 0x%x\n"
+msgstr ""
+"\n"
+"固有 0x%x\n"
+
+#: peigen.c:2310 pepigen.c:2310 pex64igen.c:2310
+msgid "%B: unable to fill in DataDictionary[1] because .idata$2 is missing"
+msgstr "%B: .idata$2 ãŒç„¡ã„ãŸã‚ DataDictionary[1] を埋ã‚ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“"
+
+#: peigen.c:2330 pepigen.c:2330 pex64igen.c:2330
+msgid "%B: unable to fill in DataDictionary[1] because .idata$4 is missing"
+msgstr "%B: .idata$4 ãŒç„¡ã„ãŸã‚ DataDictionary[1] を埋ã‚ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“"
+
+#: peigen.c:2351 pepigen.c:2351 pex64igen.c:2351
+msgid "%B: unable to fill in DataDictionary[12] because .idata$5 is missing"
+msgstr "%B: .idata$5 ãŒç„¡ã„ãŸã‚ DataDictionary[12] を埋ã‚ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“"
+
+#: peigen.c:2371 pepigen.c:2371 pex64igen.c:2371
+msgid "%B: unable to fill in DataDictionary[PE_IMPORT_ADDRESS_TABLE (12)] because .idata$6 is missing"
+msgstr "%B: .idata$6 ãŒç„¡ã„ãŸã‚ DataDictionary[PE_IMPORT_ADDRESS_TABLE (12)] を埋ã‚ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“"
+
+#: peigen.c:2413 pepigen.c:2413 pex64igen.c:2413
+msgid "%B: unable to fill in DataDictionary[PE_IMPORT_ADDRESS_TABLE(12)] because .idata$6 is missing"
+msgstr "%B: .idata$6 ãŒç„¡ã„ãŸã‚ DataDictionary[PE_IMPORT_ADDRESS_TABLE(12)] を埋ã‚ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“"
+
+#: peigen.c:2438 pepigen.c:2438 pex64igen.c:2438
+msgid "%B: unable to fill in DataDictionary[9] because __tls_used is missing"
+msgstr "%B: __tls_used ãŒç„¡ã„ãŸã‚ DataDictionary[9] を埋ã‚ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“"
+
+#~ msgid "%B: relocation type %d not implemented"
+#~ msgstr "%B: å†é…置型 %d ã¯å®Ÿè£…ã•ã‚Œã¦ã„ã¾ã›ã‚“"
+
+#~ msgid "warning: %B and %B differ in position-dependence of data addressing"
+#~ msgstr "警告: %B 㨠%B ã§ãƒ‡ãƒ¼ã‚¿ã‚¢ãƒ‰ãƒ¬ã‚¹å‰²ã‚Šå½“ã¦ã«é–¢ã™ã‚‹ä½ç½®ä¾å­˜æ€§ãŒç•°ãªã‚Šã¾ã™"
+
+#~ msgid "warning: %B and %B differ in position-dependence of code addressing"
+#~ msgstr "警告: %B 㨠%B ã§ã‚³ãƒ¼ãƒ‰ã‚¢ãƒ‰ãƒ¬ã‚¹å‰²ã‚Šå½“ã¦ã«é–¢ã™ã‚‹ä½ç½®ä¾å­˜æ€§ãŒç•°ãªã‚Šã¾ã™"
diff --git a/bfd/po/ro.gmo b/bfd/po/ro.gmo
new file mode 100644
index 0000000..8621928
--- /dev/null
+++ b/bfd/po/ro.gmo
Binary files differ
diff --git a/bfd/po/ro.po b/bfd/po/ro.po
new file mode 100644
index 0000000..5706e4f
--- /dev/null
+++ b/bfd/po/ro.po
@@ -0,0 +1,3026 @@
+# Mesajele în limba românã pentru pachetul bfd.
+# Copyright (C) 2003 Free Software Foundation, Inc.
+# Eugen Hoanca <eugenh@urban-grafx.ro>, 2003.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: bfd 2.14rel030712\n"
+"POT-Creation-Date: 2003-07-11 13:53+0930\n"
+"PO-Revision-Date: 2003-11-25 08:39+0200\n"
+"Last-Translator: Eugen Hoanca <eugenh@urban-grafx.ro>\n"
+"Language-Team: Romanian <translation-team-ro@lists.sourceforge.net>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=ISO-8859-2\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: aout-adobe.c:204
+#, c-format
+msgid "%s: Unknown section type in a.out.adobe file: %x\n"
+msgstr "%s: Tip secþiune necunoscut în fiºier adobe a.out: %x\n"
+
+#: aout-cris.c:207
+#, c-format
+msgid "%s: Invalid relocation type exported: %d"
+msgstr "%s: Tip de relocare exportat invalid: %d"
+
+#: aout-cris.c:251
+#, c-format
+msgid "%s: Invalid relocation type imported: %d"
+msgstr "%s: Tip de relocare importat invalid: %d"
+
+#: aout-cris.c:262
+#, c-format
+msgid "%s: Bad relocation record imported: %d"
+msgstr "%s: Înregistrare de relocare greºitã importatã: %d"
+
+#: aoutx.h:1295 aoutx.h:1716
+#, c-format
+msgid "%s: can not represent section `%s' in a.out object file format"
+msgstr "%s: nu se poate reprezenta secþiunea `%s' în format de fiºier obiect a.out"
+
+#: aoutx.h:1682
+#, c-format
+msgid "%s: can not represent section for symbol `%s' in a.out object file format"
+msgstr "%s: nu se poate reprezenta secþiunea pentru simbolul `%s' în formatul de fiºier obiect a.out"
+
+#: aoutx.h:1684
+msgid "*unknown*"
+msgstr "*necunoscut*"
+
+#: aoutx.h:3776
+#, c-format
+msgid "%s: relocatable link from %s to %s not supported"
+msgstr "%s: legãtura relocalizabilã din %s cãtre %s nesuportatã"
+
+#: archive.c:1751
+msgid "Warning: writing archive was slow: rewriting timestamp\n"
+msgstr "Avertisment: scrierea arhivei a fost lentã: se rescrie marcajul de timp(timestamp)\n"
+
+#: archive.c:2014
+msgid "Reading archive file mod timestamp"
+msgstr "Citirea fiºierului arhivã mod marcaj de timp"
+
+#: archive.c:2040
+msgid "Writing updated armap timestamp"
+msgstr "Scriere marcaj de timp armap înnoit"
+
+#: bfd.c:280
+msgid "No error"
+msgstr "Nici o eroare"
+
+#: bfd.c:281
+msgid "System call error"
+msgstr "Eroare apel sistem"
+
+#: bfd.c:282
+msgid "Invalid bfd target"
+msgstr "Þintã bfd invalidã"
+
+#: bfd.c:283
+msgid "File in wrong format"
+msgstr "Fiºier în format eronat"
+
+#: bfd.c:284
+msgid "Archive object file in wrong format"
+msgstr "Fiºier obiect arhivã în format eronat"
+
+#: bfd.c:285
+msgid "Invalid operation"
+msgstr "Operaþie invalidã"
+
+#: bfd.c:286
+msgid "Memory exhausted"
+msgstr "Memorie plinã"
+
+#: bfd.c:287
+msgid "No symbols"
+msgstr "Nici un simbol"
+
+#: bfd.c:288
+msgid "Archive has no index; run ranlib to add one"
+msgstr "Arhiva nu are nici un index.; rulaþi ranlib pentru a adãuga unul"
+
+#: bfd.c:289
+msgid "No more archived files"
+msgstr "Nu mai existã fiºiere arhivate"
+
+#: bfd.c:290
+msgid "Malformed archive"
+msgstr "Arhivã malformatã"
+
+#: bfd.c:291
+msgid "File format not recognized"
+msgstr "Formatul de fiºier nu a fost recunoscut"
+
+#: bfd.c:292
+msgid "File format is ambiguous"
+msgstr "Formatul de fiºier este ambiguu"
+
+#: bfd.c:293
+msgid "Section has no contents"
+msgstr "Secþiunea nu are conþinut"
+
+#: bfd.c:294
+msgid "Nonrepresentable section on output"
+msgstr "Secþiune de output nereprezentabilã"
+
+#: bfd.c:295
+msgid "Symbol needs debug section which does not exist"
+msgstr "Simbolul necesitã secþiune de debug care nu existã"
+
+#: bfd.c:296
+msgid "Bad value"
+msgstr "Valoare eronatã"
+
+#: bfd.c:297
+msgid "File truncated"
+msgstr "Fiºier trunchiat"
+
+#: bfd.c:298
+msgid "File too big"
+msgstr "Fiºier prea mare"
+
+#: bfd.c:299
+msgid "#<Invalid error code>"
+msgstr "#<Cod invalid de eroare>"
+
+#: bfd.c:687
+#, c-format
+msgid "BFD %s assertion fail %s:%d"
+msgstr "Aserþiunea BFD %s a eºuat %s:%d"
+
+#: bfd.c:703
+#, c-format
+msgid "BFD %s internal error, aborting at %s line %d in %s\n"
+msgstr "Eroare interna BFD %s, se renunþã la %s linia %d în %s\n"
+
+#: bfd.c:707
+#, c-format
+msgid "BFD %s internal error, aborting at %s line %d\n"
+msgstr "Eroare internã BFD %s, se renunþã la %s linia %d\n"
+
+#: bfd.c:709
+msgid "Please report this bug.\n"
+msgstr "Vã rugãm raportaþi acest bug.\n"
+
+#: bfdwin.c:202
+#, c-format
+msgid "not mapping: data=%lx mapped=%d\n"
+msgstr "nu se mapeazã: data=%lx mapat =%d\n"
+
+#: bfdwin.c:205
+msgid "not mapping: env var not set\n"
+msgstr "nu se mapeazã: variabila env nu este setatã\n"
+
+#: binary.c:306
+#, c-format
+msgid "Warning: Writing section `%s' to huge (ie negative) file offset 0x%lx."
+msgstr "Avertisment: Scrierea secþiunii `%s' spre offset de fiºier imens (sau negativ) 0x%lx"
+
+#: coff-a29k.c:120
+msgid "Missing IHCONST"
+msgstr "IHCONST lipsã"
+
+#: coff-a29k.c:181
+msgid "Missing IHIHALF"
+msgstr "IHHALF lipsã"
+
+#: coff-a29k.c:213 coff-or32.c:236
+msgid "Unrecognized reloc"
+msgstr "Reloc necunoscut"
+
+#: coff-a29k.c:409
+msgid "missing IHCONST reloc"
+msgstr "IHCONST reloc lipsã"
+
+#: coff-a29k.c:499
+msgid "missing IHIHALF reloc"
+msgstr "IHIHALF reloc lipsã"
+
+#: coff-alpha.c:884 coff-alpha.c:921 coff-alpha.c:1992 coff-mips.c:1397
+msgid "GP relative relocation used when GP not defined"
+msgstr "Relocare relativã GP folositã când GP nu este definit"
+
+#: coff-alpha.c:1488
+msgid "using multiple gp values"
+msgstr "folosire de valori multiple gp"
+
+#: coff-arm.c:1066 elf32-arm.h:294
+#, c-format
+msgid "%s: unable to find THUMB glue '%s' for `%s'"
+msgstr "%s: nu s-a putut gãsi legãtura(glue) THUMB `%s' pentru `%s'"
+
+#: coff-arm.c:1096 elf32-arm.h:329
+#, c-format
+msgid "%s: unable to find ARM glue '%s' for `%s'"
+msgstr "%s: nu s-a putut gãsi legãtura(glue) ARM `%s' pentru `%s'"
+
+#: coff-arm.c:1394 coff-arm.c:1489 elf32-arm.h:892 elf32-arm.h:999
+#, c-format
+msgid "%s(%s): warning: interworking not enabled."
+msgstr "%s(%s): avertisment: interlucrul(interworking) nu este activat"
+
+#: coff-arm.c:1398 elf32-arm.h:1002
+#, c-format
+msgid " first occurrence: %s: arm call to thumb"
+msgstr " prima gãsire: %s: apelare braþ(arm) cãtre deget(thumb)"
+
+#: coff-arm.c:1493 elf32-arm.h:895
+#, c-format
+msgid " first occurrence: %s: thumb call to arm"
+msgstr " prima gãsire: %s: apelare deget(thumb) cãtre braþ(arm)"
+
+#: coff-arm.c:1496
+msgid " consider relinking with --support-old-code enabled"
+msgstr " luaþi în considerare relinkuirea cu --support-old-code activat"
+
+#: coff-arm.c:1788 coff-tic80.c:687 cofflink.c:3038
+#, c-format
+msgid "%s: bad reloc address 0x%lx in section `%s'"
+msgstr "%s: adresã eronatã de relocare 0x%lx în secþiunea `%s'"
+
+#: coff-arm.c:2132
+#, c-format
+msgid "%s: illegal symbol index in reloc: %d"
+msgstr "%s: index ilegal de simbol în reloc: %d"
+
+#: coff-arm.c:2265
+#, c-format
+msgid "ERROR: %s is compiled for APCS-%d, whereas %s is compiled for APCS-%d"
+msgstr "EROARE: %s este compilat pentru APCS-%d, pe când %s e compilat pentru APCS-%d"
+
+#: coff-arm.c:2280 elf32-arm.h:2328
+#, c-format
+msgid "ERROR: %s passes floats in float registers, whereas %s passes them in integer registers"
+msgstr "EROARE: %s trimite float în regiºtrii de float, pe când %s îi trimite în regiºtrii de integer"
+
+#: coff-arm.c:2283 elf32-arm.h:2333
+#, c-format
+msgid "ERROR: %s passes floats in integer registers, whereas %s passes them in float registers"
+msgstr "EROARE: %s trimite integer în regiºtrii de integer, pe când %s îi trimite în regiºtrii de float"
+
+#: coff-arm.c:2298
+#, c-format
+msgid "ERROR: %s is compiled as position independent code, whereas target %s is absolute position"
+msgstr "EROARE: %s este compilat ca ºi cod independent de poziþie,pe când þinta %seste poziþie absolutã"
+
+#: coff-arm.c:2301
+#, c-format
+msgid "ERROR: %s is compiled as absolute position code, whereas target %s is position independent"
+msgstr "EROARE: %s este compilat ca ºi cod poziþie absolutã,pe când þinta %seste independentã de poziþie"
+
+#: coff-arm.c:2330 elf32-arm.h:2405
+#, c-format
+msgid "Warning: %s supports interworking, whereas %s does not"
+msgstr "Avertisment: %s suportã interlucru(interworking), pe când %s nu suportã"
+
+#: coff-arm.c:2333 elf32-arm.h:2412
+#, c-format
+msgid "Warning: %s does not support interworking, whereas %s does"
+msgstr "Avertisment: %s nu suportã interlucru(interworking), pe când %s suportã"
+
+#: coff-arm.c:2360
+#, c-format
+msgid "private flags = %x:"
+msgstr "marcaje(flags) private = %x:"
+
+#: coff-arm.c:2368 elf32-arm.h:2467
+msgid " [floats passed in float registers]"
+msgstr " [floats trecuþi în regiºtri de float]"
+
+#: coff-arm.c:2370
+msgid " [floats passed in integer registers]"
+msgstr " [floats trecuþi în regiºtrii de integer]"
+
+#: coff-arm.c:2373 elf32-arm.h:2470
+msgid " [position independent]"
+msgstr "[ independent de poziþie]"
+
+#: coff-arm.c:2375
+msgid " [absolute position]"
+msgstr " [poziþie absolutã]"
+
+#: coff-arm.c:2379
+msgid " [interworking flag not initialised]"
+msgstr " [marcajul(flag) de interlucru(interworking) nu este iniþializat]"
+
+#: coff-arm.c:2381
+msgid " [interworking supported]"
+msgstr " [interlucru(interworking) suportat]"
+
+#: coff-arm.c:2383
+msgid " [interworking not supported]"
+msgstr " [interlucru(interworking) nesuportat]"
+
+#: coff-arm.c:2431 elf32-arm.h:2150
+#, c-format
+msgid "Warning: Not setting interworking flag of %s since it has already been specified as non-interworking"
+msgstr "Avertisment: Nu se seteazã marcajul(flagu) de interlucru(interworking) al %s atâta timp cât a fost specificat ca non-interlucru(interworking)"
+
+#: coff-arm.c:2435 elf32-arm.h:2154
+#, c-format
+msgid "Warning: Clearing the interworking flag of %s due to outside request"
+msgstr "Avertisment: Se ºterge marcajul(flag) de interlucru(interworking) al %s datoritã unei cereri din afarã"
+
+#: coff-h8300.c:1096
+#, c-format
+msgid "cannot handle R_MEM_INDIRECT reloc when using %s output"
+msgstr "nu am putut mainpula(handle) relocarea R_MEM_INDIRECT în folosirea ieºirii(output) %s"
+
+#: coff-i960.c:137 coff-i960.c:486
+msgid "uncertain calling convention for non-COFF symbol"
+msgstr "convenþie de apelare nesigurã pentru simbol non-COFF"
+
+#: coff-m68k.c:482 coff-mips.c:2394 elf32-m68k.c:2193 elf32-mips.c:1783
+msgid "unsupported reloc type"
+msgstr "tip de relocare nesuportat"
+
+#: coff-mips.c:839 elf32-mips.c:1088 elf64-mips.c:1590 elfn32-mips.c:1554
+msgid "GP relative relocation when _gp not defined"
+msgstr "Relocare relativã GP atâta timp cât _gp nu este definit"
+
+#. No other sections should appear in -membedded-pic
+#. code.
+#: coff-mips.c:2431
+msgid "reloc against unsupported section"
+msgstr "relocare pe o secþiune nesuportatã"
+
+#: coff-mips.c:2439
+msgid "reloc not properly aligned"
+msgstr "relocare incorect aliniatã"
+
+#: coff-rs6000.c:2790
+#, c-format
+msgid "%s: unsupported relocation type 0x%02x"
+msgstr "%s: tip de relocare nesuportat 0x%02x"
+
+#: coff-rs6000.c:2883
+#, c-format
+msgid "%s: TOC reloc at 0x%x to symbol `%s' with no TOC entry"
+msgstr "%s: relocare TOC la 0x%x cãtre simbolul `%s' fãrã nici o intrare TOC"
+
+#: coff-rs6000.c:3616 coff64-rs6000.c:2109
+#, c-format
+msgid "%s: symbol `%s' has unrecognized smclas %d"
+msgstr "%s: simbolul `%s' are un smclas necunoscut %d"
+
+#: coff-tic4x.c:170 coff-tic54x.c:288 coff-tic80.c:450
+#, c-format
+msgid "Unrecognized reloc type 0x%x"
+msgstr "Tip de relocare necunoscut 0x%x"
+
+#: coff-tic4x.c:218 coff-tic54x.c:373 coffcode.h:5045
+#, c-format
+msgid "%s: warning: illegal symbol index %ld in relocs"
+msgstr "%s: avertisment: index ilegal de simbol %ld în relocãri"
+
+#: coff-w65.c:364
+#, c-format
+msgid "ignoring reloc %s\n"
+msgstr "se ignorã reloc %s\n"
+
+#: coffcode.h:1108
+#, c-format
+msgid "%s (%s): Section flag %s (0x%x) ignored"
+msgstr "%s (%s): Marcajul(flag) de secþiune %s (0x%x) ignorat"
+
+#: coffcode.h:2214
+#, c-format
+msgid "Unrecognized TI COFF target id '0x%x'"
+msgstr "Id þintã TI COFF necunoscut `0x%x'"
+
+#: coffcode.h:4437
+#, c-format
+msgid "%s: warning: illegal symbol index %ld in line numbers"
+msgstr "%s: avertisment: index ilegal de simbol %ld în numãrul de linii"
+
+#: coffcode.h:4451
+#, c-format
+msgid "%s: warning: duplicate line number information for `%s'"
+msgstr "%s: avertisment: informaþie duplicat a numãrului de linii pentru `%s'"
+
+#: coffcode.h:4805
+#, c-format
+msgid "%s: Unrecognized storage class %d for %s symbol `%s'"
+msgstr "%s: Clasã de depozitare(storage) %d necunoscutã pentru %s simbolul `%s'"
+
+#: coffcode.h:4938
+#, c-format
+msgid "warning: %s: local symbol `%s' has no section"
+msgstr "avertisment: %s: simbolul local `%s' nu are secþiune"
+
+#: coffcode.h:5083
+#, c-format
+msgid "%s: illegal relocation type %d at address 0x%lx"
+msgstr "%s: tip ilegal de relocare %d la adresa 0x%lx"
+
+#: coffgen.c:1666
+#, c-format
+msgid "%s: bad string table size %lu"
+msgstr "%s: mãrime tabel ºiruri invalidã %lu"
+
+#: cofflink.c:538 elflink.h:1276
+#, c-format
+msgid "Warning: type of symbol `%s' changed from %d to %d in %s"
+msgstr "Avertisment: tipul de simbol `%s' schimbat de la %d la %d în %s"
+
+#: cofflink.c:2328
+#, c-format
+msgid "%s: relocs in section `%s', but it has no contents"
+msgstr "%s: relocãri în secþiunea `%s', dar fãrã conþinut"
+
+#: cofflink.c:2671 coffswap.h:890
+#, c-format
+msgid "%s: %s: reloc overflow: 0x%lx > 0xffff"
+msgstr "%s: %s: depãºire(overflow) de relocãri: 0x%lx > 0xffff"
+
+#: cofflink.c:2680 coffswap.h:876
+#, c-format
+msgid "%s: warning: %s: line number overflow: 0x%lx > 0xffff"
+msgstr "%s: avertisment: %s: depãºire(overflow) numãr de linii: 0x%lx > 0xffff"
+
+#: cpu-arm.c:196 cpu-arm.c:206
+#, c-format
+msgid "ERROR: %s is compiled for the EP9312, whereas %s is compiled for XScale"
+msgstr "EROARE: %s este compilat pentru EP9312, pe când %s e compilat pentru XScale"
+
+#: cpu-arm.c:344
+#, c-format
+msgid "warning: unable to update contents of %s section in %s"
+msgstr "avertisment: imposibil de adus la zi(update) conþinutul secþiunii %s în %s"
+
+#: dwarf2.c:380
+msgid "Dwarf Error: Can't find .debug_str section."
+msgstr "Eroare Pitic(Dwarf): Nu pot gãsi secþiunea debug_str"
+
+#: dwarf2.c:397
+#, c-format
+msgid "Dwarf Error: DW_FORM_strp offset (%lu) greater than or equal to .debug_str size (%lu)."
+msgstr "Eroare Pitic(Dwarf): DW_FORM_strp offset (%lu) mai mare sau egalã cu mãrimea .debug_str (%lu)."
+
+#: dwarf2.c:541
+msgid "Dwarf Error: Can't find .debug_abbrev section."
+msgstr "Eroare Pitic(Dwarf): Nu pot gãsi secþiunea debug_abbrev."
+
+#: dwarf2.c:556
+#, c-format
+msgid "Dwarf Error: Abbrev offset (%lu) greater than or equal to .debug_abbrev size (%lu)."
+msgstr "Eroare Pitic(Dwarf): Offset abbrev(%lu) mai mare sau egal cu mãrimea .debug_abbrev (%lu)."
+
+#: dwarf2.c:756
+#, c-format
+msgid "Dwarf Error: Invalid or unhandled FORM value: %u."
+msgstr "Eroare Pitic(Dwarf): Valoare FORM invalidã sau nemanipulabilã: %u."
+
+#: dwarf2.c:933
+msgid "Dwarf Error: mangled line number section (bad file number)."
+msgstr "Eroare Pitic(Dwarf): secþiune numãr de linii trunchiatã (numãr fiºier eronat)"
+
+#: dwarf2.c:1032
+msgid "Dwarf Error: Can't find .debug_line section."
+msgstr "Eroare Pitic(Dwarf): Nu pot gãsi secþiunea debug_line."
+
+#: dwarf2.c:1049
+#, c-format
+msgid "Dwarf Error: Line offset (%lu) greater than or equal to .debug_line size (%lu)."
+msgstr "Eroare Pitic(Dwarf): Offsetul de linie (%lu) mai mare sau egal cu mãrimea .debug_line (%lu)"
+
+#: dwarf2.c:1255
+msgid "Dwarf Error: mangled line number section."
+msgstr "Eroare Pitic(Dwarf): secþiune trunchiatã numãr de linii"
+
+#: dwarf2.c:1470 dwarf2.c:1620
+#, c-format
+msgid "Dwarf Error: Could not find abbrev number %u."
+msgstr "Eroare Pitic(Dwarf): Nu am putut gãsi numãrul abbrev: %u."
+
+#: dwarf2.c:1581
+#, c-format
+msgid "Dwarf Error: found dwarf version '%u', this reader only handles version 2 information."
+msgstr "Eroare Pitic(Dwarf): S-a gãsit dwarf versiunea `%u', acest cititor manipuleazã doar informaþii ale versiunii 2."
+
+#: dwarf2.c:1588
+#, c-format
+msgid "Dwarf Error: found address size '%u', this reader can not handle sizes greater than '%u'."
+msgstr "Eroare Pitic(Dwarf): s-a gãsit adresa mãrimea `%u', acest cititor nu poate manipula mãrimi mai mari decât `%u'"
+
+#: dwarf2.c:1611
+#, c-format
+msgid "Dwarf Error: Bad abbrev number: %u."
+msgstr "Eroare Pitic(Dwarf): Numãr invalid de abbrev: %u"
+
+#: ecoff.c:1339
+#, c-format
+msgid "Unknown basic type %d"
+msgstr "Tip de bazã necunoscut %d"
+
+#: ecoff.c:1599
+#, c-format
+msgid ""
+"\n"
+" End+1 symbol: %ld"
+msgstr ""
+"\n"
+" Simbol Sfârºit+1: %ld"
+
+#: ecoff.c:1606 ecoff.c:1609
+#, c-format
+msgid ""
+"\n"
+" First symbol: %ld"
+msgstr ""
+"\n"
+" Primul simbol: %ld"
+
+#: ecoff.c:1621
+#, c-format
+msgid ""
+"\n"
+" End+1 symbol: %-7ld Type: %s"
+msgstr ""
+"\n"
+" Simbol Sfârºit+1: %-7ld Tip: %s"
+
+#: ecoff.c:1628
+#, c-format
+msgid ""
+"\n"
+" Local symbol: %ld"
+msgstr ""
+"\n"
+" Simbol local: %ld"
+
+#: ecoff.c:1636
+#, c-format
+msgid ""
+"\n"
+" struct; End+1 symbol: %ld"
+msgstr ""
+"\n"
+" struct; Simbol Sfârºit+1: %ld"
+
+#: ecoff.c:1641
+#, c-format
+msgid ""
+"\n"
+" union; End+1 symbol: %ld"
+msgstr ""
+"\n"
+" uniune; Simbol Sfârºit+1: %ld"
+
+#: ecoff.c:1646
+#, c-format
+msgid ""
+"\n"
+" enum; End+1 symbol: %ld"
+msgstr ""
+"\n"
+" enum; Simbol Sfârºit+1: %ld"
+
+#: ecoff.c:1652
+#, c-format
+msgid ""
+"\n"
+" Type: %s"
+msgstr ""
+"\n"
+" Tip: %s"
+
+#: elf-hppa.h:1458 elf-hppa.h:1491 elf-m10300.c:1628 elf64-sh64.c:1704
+#, c-format
+msgid "%s: warning: unresolvable relocation against symbol `%s' from %s section"
+msgstr "%s: avertisment: relocare nerezolvabilã pe simbolul `%s; din secþiunea `%s'"
+
+#: elf-m10200.c:442 elf-m10300.c:1695 elf32-arm.h:2088 elf32-avr.c:812
+#: elf32-cris.c:1390 elf32-d10v.c:570 elf32-fr30.c:634 elf32-frv.c:815
+#: elf32-h8300.c:528 elf32-i860.c:1028 elf32-ip2k.c:1586 elf32-iq2000.c:699
+#: elf32-m32r.c:1283 elf32-m68hc1x.c:1305 elf32-msp430.c:510
+#: elf32-openrisc.c:436 elf32-v850.c:1777 elf32-xstormy16.c:976
+#: elf64-mmix.c:1332
+msgid "internal error: out of range error"
+msgstr "eroare internã: eroare depãºire de domeniu(out of range)"
+
+#: elf-m10200.c:446 elf-m10300.c:1699 elf32-arm.h:2092 elf32-avr.c:816
+#: elf32-cris.c:1394 elf32-d10v.c:574 elf32-fr30.c:638 elf32-frv.c:819
+#: elf32-h8300.c:532 elf32-i860.c:1032 elf32-iq2000.c:703 elf32-m32r.c:1287
+#: elf32-m68hc1x.c:1309 elf32-msp430.c:514 elf32-openrisc.c:440
+#: elf32-v850.c:1781 elf32-xstormy16.c:980 elf64-mmix.c:1336 elfxx-mips.c:6452
+msgid "internal error: unsupported relocation error"
+msgstr "eroare internã: eroare de relocare nesuportatã"
+
+#: elf-m10200.c:450 elf-m10300.c:1703 elf32-arm.h:2096 elf32-d10v.c:578
+#: elf32-h8300.c:536 elf32-m32r.c:1291 elf32-m68hc1x.c:1313
+msgid "internal error: dangerous error"
+msgstr "eroare internã: eroare periculoasã"
+
+#: elf-m10200.c:454 elf-m10300.c:1707 elf32-arm.h:2100 elf32-avr.c:824
+#: elf32-cris.c:1402 elf32-d10v.c:582 elf32-fr30.c:646 elf32-frv.c:827
+#: elf32-h8300.c:540 elf32-i860.c:1040 elf32-ip2k.c:1601 elf32-iq2000.c:711
+#: elf32-m32r.c:1295 elf32-m68hc1x.c:1317 elf32-msp430.c:522
+#: elf32-openrisc.c:448 elf32-v850.c:1801 elf32-xstormy16.c:988
+#: elf64-mmix.c:1344
+msgid "internal error: unknown error"
+msgstr "eroare internã: eroare necunoscutã"
+
+#: elf.c:372
+#, c-format
+msgid "%s: invalid string offset %u >= %lu for section `%s'"
+msgstr "%s: offset de ºir invalid %u >= %lu pentru secþiunea `%s'"
+
+#: elf.c:624
+#, c-format
+msgid "%s: invalid SHT_GROUP entry"
+msgstr "%s: intrare SHT_GROUP invalidã"
+
+#: elf.c:695
+#, c-format
+msgid "%s: no group info for section %s"
+msgstr "%s nu existã informaþii de grup pentru secþiunea %s"
+
+#: elf.c:1055
+msgid ""
+"\n"
+"Program Header:\n"
+msgstr ""
+"\n"
+"Header Program:\n"
+
+#: elf.c:1106
+msgid ""
+"\n"
+"Dynamic Section:\n"
+msgstr ""
+"\n"
+"Secþiune Dinamicã:\n"
+
+#: elf.c:1235
+msgid ""
+"\n"
+"Version definitions:\n"
+msgstr ""
+"\n"
+"Definiþii de versiune:\n"
+
+#: elf.c:1258
+msgid ""
+"\n"
+"Version References:\n"
+msgstr ""
+"\n"
+"Referinþe Versiune:\n"
+
+#: elf.c:1263
+#, c-format
+msgid " required from %s:\n"
+msgstr " cerute de %s:\n"
+
+#: elf.c:1944
+#, c-format
+msgid "%s: invalid link %lu for reloc section %s (index %u)"
+msgstr "%s: link invalid %lu pentru secþiunea de relocare %s (index %u)"
+
+#: elf.c:3686
+#, c-format
+msgid "%s: Not enough room for program headers (allocated %u, need %u)"
+msgstr "%s: Memorie insuficientã pentru headerele programului (alocatã %u, necesarã %u)"
+
+#: elf.c:3791
+#, c-format
+msgid "%s: Not enough room for program headers, try linking with -N"
+msgstr "%s: Memorie insuficientã pentru headerele programului, încercaþi linkuirea cu -N"
+
+#: elf.c:3922
+#, c-format
+msgid "Error: First section in segment (%s) starts at 0x%x whereas the segment starts at 0x%x"
+msgstr "Eroare: prima secþiune în segment (%s) începe la 0x%x pe când segmentul începe la 0x%x"
+
+#: elf.c:4242
+#, c-format
+msgid "%s: warning: allocated section `%s' not in segment"
+msgstr "%s: avertisment: secþiunea alocatã `%s' nu este în segment"
+
+#: elf.c:4566
+#, c-format
+msgid "%s: symbol `%s' required but not present"
+msgstr "%s: simbolul `%s' necesar, dar nu este prezent"
+
+#: elf.c:4854
+#, c-format
+msgid "%s: warning: Empty loadable segment detected, is this intentional ?\n"
+msgstr "%s: avertisment: S-a detectat segment încãrcabil vid, este intenþionat ?\n"
+
+#: elf.c:5485
+#, c-format
+msgid "Unable to find equivalent output section for symbol '%s' from section '%s'"
+msgstr "Nnu am putut gãsi secþiunea de output echivalentã pentru simbolul '%s' din secþiunea '%s'"
+
+#: elf.c:6298
+#, c-format
+msgid "%s: unsupported relocation type %s"
+msgstr "%s: tip de relocare nesuportat: %s"
+
+#: elf32-arm.h:1228
+#, c-format
+msgid "%s: Warning: Arm BLX instruction targets Arm function '%s'."
+msgstr "%s: Avertisment: BLX Arm are ca þintã funcþia Arm `%s'."
+
+#: elf32-arm.h:1424
+#, c-format
+msgid "%s: Warning: Thumb BLX instruction targets thumb function '%s'."
+msgstr "%s: Avertisment: BLX Thumb are ca þintã funcþia thumb `%s'."
+
+#: elf32-arm.h:1918 elf32-sh.c:4706 elf64-sh64.c:1613
+#, c-format
+msgid "%s(%s+0x%lx): %s relocation against SEC_MERGE section"
+msgstr "%s(%s+0x%lx): %s relocare pe secþiunea SEC_MERGE"
+
+#: elf32-arm.h:2012
+#, c-format
+msgid "%s: warning: unresolvable relocation %d against symbol `%s' from %s section"
+msgstr "%s: avertisment: relocare nerezolvabilã %d pe simbolul `%s' din secþiunea %s"
+
+#: elf32-arm.h:2202
+#, c-format
+msgid "Warning: Clearing the interworking flag of %s because non-interworking code in %s has been linked with it"
+msgstr "Avertisment: Se ºterge marcajul(flag) de interlucru(interworking) al %s deoarece împreunã cu el a fost linkuit cod non-interlucru în %s"
+
+#: elf32-arm.h:2302
+#, c-format
+msgid "ERROR: %s is compiled for EABI version %d, whereas %s is compiled for version %d"
+msgstr "EROARE: %s este compilat pentru EABI versiunea %d, pe când %s este compilat pentru versiunea %d"
+
+#: elf32-arm.h:2316
+#, c-format
+msgid "ERROR: %s is compiled for APCS-%d, whereas target %s uses APCS-%d"
+msgstr "EROARE: %s este compilat pentru APCS-%d, pe când þinta %s foloseºte APCS-%d"
+
+#: elf32-arm.h:2344
+#, c-format
+msgid "ERROR: %s uses VFP instructions, whereas %s does not"
+msgstr "EROARE: %s foloseºte instrucþiuni VFP, pe când %s nu le foloseºte"
+
+#: elf32-arm.h:2349
+#, c-format
+msgid "ERROR: %s uses FPA instructions, whereas %s does not"
+msgstr "EROARE: %s foloseºte instrucþiuni FPA, pe când %s nu le foloseºte"
+
+#: elf32-arm.h:2360 elf32-arm.h:2365
+#, c-format
+msgid "ERROR: %s uses Maverick instructions, whereas %s does not"
+msgstr "EROARE: %s foloseºte instrucþiuni Maverick, pe când %s nu le foloseºte"
+
+#: elf32-arm.h:2385
+#, c-format
+msgid "ERROR: %s uses software FP, whereas %s uses hardware FP"
+msgstr "EROARE: %s foloseºte FP software, pe când %s foloseºte FP hardware"
+
+#: elf32-arm.h:2390
+#, c-format
+msgid "ERROR: %s uses hardware FP, whereas %s uses software FP"
+msgstr "EROARE: %s foloseºte FP hardware, pe când %s foloseºte FP software"
+
+#. Ignore init flag - it may not be set, despite the flags field
+#. containing valid data.
+#: elf32-arm.h:2443 elf32-cris.c:2975 elf32-m68hc1x.c:1459 elf32-m68k.c:397
+#: elf32-vax.c:546 elfxx-mips.c:9238
+#, c-format
+msgid "private flags = %lx:"
+msgstr "marcaje(flags) private = %lx:"
+
+#: elf32-arm.h:2452
+msgid " [interworking enabled]"
+msgstr " [interlucru(interworking) activat]"
+
+#: elf32-arm.h:2460
+msgid " [VFP float format]"
+msgstr " [format float VFP]"
+
+#: elf32-arm.h:2462
+msgid " [Maverick float format]"
+msgstr " [format float Maverick]"
+
+#: elf32-arm.h:2464
+msgid " [FPA float format]"
+msgstr " [format float FPA]"
+
+#: elf32-arm.h:2473
+msgid " [new ABI]"
+msgstr " [ABI nou]"
+
+#: elf32-arm.h:2476
+msgid " [old ABI]"
+msgstr " [ABI vechi]"
+
+#: elf32-arm.h:2479
+msgid " [software FP]"
+msgstr " [FP software]"
+
+#: elf32-arm.h:2488
+msgid " [Version1 EABI]"
+msgstr " [EABI Versiunea1]"
+
+#: elf32-arm.h:2491 elf32-arm.h:2502
+msgid " [sorted symbol table]"
+msgstr " [tabelã sortatã de simboluri]"
+
+#: elf32-arm.h:2493 elf32-arm.h:2504
+msgid " [unsorted symbol table]"
+msgstr " [tabelã de simboluri nesortatã]"
+
+#: elf32-arm.h:2499
+msgid " [Version2 EABI]"
+msgstr " [EABI Versiunea2]"
+
+#: elf32-arm.h:2507
+msgid " [dynamic symbols use segment index]"
+msgstr " [simbolurile dinamice folosesc index de segment]"
+
+#: elf32-arm.h:2510
+msgid " [mapping symbols precede others]"
+msgstr " [simbolurile de mapare le precedeazã pe celelalte]"
+
+#: elf32-arm.h:2517
+msgid " <EABI version unrecognised>"
+msgstr " <versiune necunoscutã EABI>"
+
+#: elf32-arm.h:2524
+msgid " [relocatable executable]"
+msgstr " [executabil relocabil]"
+
+#: elf32-arm.h:2527
+msgid " [has entry point]"
+msgstr " [are punct de intrare]"
+
+#: elf32-arm.h:2532
+msgid "<Unrecognised flag bits set>"
+msgstr "<setare biþi de marcaj(flag) necunoscutã>"
+
+#: elf32-avr.c:820 elf32-cris.c:1398 elf32-fr30.c:642 elf32-frv.c:823
+#: elf32-i860.c:1036 elf32-ip2k.c:1597 elf32-iq2000.c:707 elf32-msp430.c:518
+#: elf32-openrisc.c:444 elf32-v850.c:1785 elf32-xstormy16.c:984
+#: elf64-mmix.c:1340
+msgid "internal error: dangerous relocation"
+msgstr "eroare internã: relocare periculoasã"
+
+#: elf32-cris.c:931
+#, c-format
+msgid "%s: unresolvable relocation %s against symbol `%s' from %s section"
+msgstr "%s: relocare nerezolvabilã %s pe simbolul `%s' din secþiunea `%s'"
+
+#: elf32-cris.c:993
+#, c-format
+msgid "%s: No PLT nor GOT for relocation %s against symbol `%s' from %s section"
+msgstr "%s:Nu existã nici PLT nici GOR pentru relocarea %s pe simbolul `%s' din secþiunea %s"
+
+#: elf32-cris.c:996 elf32-cris.c:1122
+msgid "[whose name is lost]"
+msgstr "[al cãrui nume s-a pierdut]"
+
+#: elf32-cris.c:1111
+#, c-format
+msgid "%s: relocation %s with non-zero addend %d against local symbol from %s section"
+msgstr "%s: relocarea %s cu adãugarea diferitã de zero %d pe simbolul local din secþiunea %s"
+
+#: elf32-cris.c:1118
+#, c-format
+msgid "%s: relocation %s with non-zero addend %d against symbol `%s' from %s section"
+msgstr "%s: relocarea %s cu adãugare non-zero %d pe simbolul `%s' din secþiunea %s"
+
+#: elf32-cris.c:1143
+#, c-format
+msgid "%s: relocation %s is not allowed for global symbol: `%s' from %s section"
+msgstr "%s: relocarea %s nu este permisã pentru simbolul global `%s' din secþiunea %s"
+
+#: elf32-cris.c:1158
+#, c-format
+msgid "%s: relocation %s in section %s with no GOT created"
+msgstr "%s: relocarea %s din secþiunea %s fãrã GOT creat"
+
+#: elf32-cris.c:1277
+#, c-format
+msgid "%s: Internal inconsistency; no relocation section %s"
+msgstr "%s: Inconsistenþã internã, nu existã secþiunea de relocare %s"
+
+#: elf32-cris.c:2500
+#, c-format
+msgid ""
+"%s, section %s:\n"
+" relocation %s should not be used in a shared object; recompile with -fPIC"
+msgstr ""
+"%s, secþiunea %s:\n"
+" relocarea %s n-ar trebui folositã într-un shared object; recompilaþi cu -fPIC"
+
+#: elf32-cris.c:2978
+msgid " [symbols have a _ prefix]"
+msgstr " [simbolurile au un _prefix]"
+
+#: elf32-cris.c:3017
+#, c-format
+msgid "%s: uses _-prefixed symbols, but writing file with non-prefixed symbols"
+msgstr "%s: se folosesc simbolurile _-prefixate, dar se scrie fiºierul cu simboluri neprefixate"
+
+#: elf32-cris.c:3018
+#, c-format
+msgid "%s: uses non-prefixed symbols, but writing file with _-prefixed symbols"
+msgstr "%s: se folosesc simboluri neprefixate, dar se scrie fiºierul cu simboluri _-prefixate"
+
+#: elf32-frv.c:1223
+#, c-format
+msgid "%s: compiled with %s and linked with modules that use non-pic relocations"
+msgstr "%s: compilat cu %s ºi linkuit cu module care folosesc relocaþii non-pic"
+
+#: elf32-frv.c:1273 elf32-iq2000.c:895
+#, c-format
+msgid "%s: compiled with %s and linked with modules compiled with %s"
+msgstr "%s: compilat cu %s ºi linkuit cu module compilate cu %s"
+
+#: elf32-frv.c:1285
+#, c-format
+msgid "%s: uses different unknown e_flags (0x%lx) fields than previous modules (0x%lx)"
+msgstr "%s: foloseºte câmpuri marcaje e_flags (0x%lx) diferite de modulele anterioare (0x%lx)"
+
+#: elf32-frv.c:1321 elf32-iq2000.c:933
+#, c-format
+msgid "private flags = 0x%lx:"
+msgstr "marcaje(flags) private = 0x%lx"
+
+#: elf32-gen.c:83 elf64-gen.c:82
+#, c-format
+msgid "%s: Relocations in generic ELF (EM: %d)"
+msgstr "%s: Relocãri în ELF generic (EM: %d)"
+
+#: elf32-hppa.c:672 elf32-m68hc1x.c:176 elf64-ppc.c:3118
+#, c-format
+msgid "%s: cannot create stub entry %s"
+msgstr "%s: nu se poate crea intrarea trunchiatã %s"
+
+#: elf32-hppa.c:957 elf32-hppa.c:3538
+#, c-format
+msgid "%s(%s+0x%lx): cannot reach %s, recompile with -ffunction-sections"
+msgstr "%s(%s+0x%lx): nu se poate gãsi %s, recompilaþi cu -ffunction-sections"
+
+#: elf32-hppa.c:1340 elf64-x86-64.c:672 elf64-x86-64.c:797
+#, c-format
+msgid "%s: relocation %s can not be used when making a shared object; recompile with -fPIC"
+msgstr "%s: relocarea %s nu poate fi utilizatã când se face un shared object, recompilaþicu -fPIC"
+
+#: elf32-hppa.c:1360
+#, c-format
+msgid "%s: relocation %s should not be used when making a shared object; recompile with -fPIC"
+msgstr "%s: relocarea %s nu ar trebui utilizatã când se face un shared object, recompilaþicu -fPIC"
+
+#: elf32-hppa.c:1553
+#, c-format
+msgid "Could not find relocation section for %s"
+msgstr "Nu se poate gãsi secþiunea de relocare pentru %s"
+
+#: elf32-hppa.c:2828
+#, c-format
+msgid "%s: duplicate export stub %s"
+msgstr "%s: exportare de ciot(stub) duplicatã %s"
+
+#: elf32-hppa.c:3416
+#, c-format
+msgid "%s(%s+0x%lx): fixing %s"
+msgstr "%s(%s+0x%lx): se fixeazã %s"
+
+#: elf32-hppa.c:4039
+#, c-format
+msgid "%s(%s+0x%lx): cannot handle %s for %s"
+msgstr "%s(%s+0x%lx): nu pot manipula %s pentru %s"
+
+#: elf32-hppa.c:4357
+msgid ".got section not immediately after .plt section"
+msgstr "secþiunea .got nu urmeazã imediat dupã secþiunea .plt"
+
+#: elf32-i386.c:326
+#, c-format
+msgid "%s: invalid relocation type %d"
+msgstr "%s: tip de relocare invalid %d"
+
+#: elf32-i386.c:841 elf32-s390.c:990 elf32-sparc.c:887 elf32-xtensa.c:637
+#: elf64-s390.c:943 elf64-x86-64.c:650
+#, c-format
+msgid "%s: bad symbol index: %d"
+msgstr "%s:index de simboluri invalid: %d"
+
+#: elf32-i386.c:949 elf32-s390.c:1168 elf32-sh.c:6426 elf32-sparc.c:1011
+#: elf64-s390.c:1129
+#, c-format
+msgid "%s: `%s' accessed both as normal and thread local symbol"
+msgstr "%s: `%s' accesate ºi ca simboluri locale normale ºi ca simboluri locale pe fire (thread)"
+
+#: elf32-i386.c:1064 elf32-s390.c:1279 elf64-ppc.c:3929 elf64-s390.c:1243
+#: elf64-x86-64.c:886
+#, c-format
+msgid "%s: bad relocation section name `%s'"
+msgstr "%s: nume secþiune relocare invalid `%s'"
+
+#: elf32-i386.c:2908 elf32-m68k.c:1757 elf32-s390.c:3022 elf32-sparc.c:2879
+#: elf32-xtensa.c:2193 elf64-s390.c:3018 elf64-sparc.c:2664
+#: elf64-x86-64.c:2452
+#, c-format
+msgid "%s(%s+0x%lx): unresolvable relocation against symbol `%s'"
+msgstr "%s(%s+0x%lx): relocare nerezolvabilã pe simbolul `%s'"
+
+#: elf32-i386.c:2947 elf32-m68k.c:1796 elf32-s390.c:3072 elf64-s390.c:3068
+#: elf64-x86-64.c:2490
+#, c-format
+msgid "%s(%s+0x%lx): reloc against `%s': error %d"
+msgstr "%s(%s+0x%lx): relocare pe `%s': eroare %d"
+
+#: elf32-ip2k.c:565 elf32-ip2k.c:571 elf32-ip2k.c:734 elf32-ip2k.c:740
+msgid "ip2k relaxer: switch table without complete matching relocation information."
+msgstr "ip2k relaxer: schimbare de tabel fãrã potrivirea completã a informaþiei de relocare."
+
+#: elf32-ip2k.c:588 elf32-ip2k.c:767
+msgid "ip2k relaxer: switch table header corrupt."
+msgstr "ip2k relaxer: headerul tablelului de schimbare este corupt."
+
+#: elf32-ip2k.c:1395
+#, c-format
+msgid "ip2k linker: missing page instruction at 0x%08lx (dest = 0x%08lx)."
+msgstr "ip2k linker: lipseºte instrucþiunea de paginã la 0x%08lx (dest = 0x%08lx)."
+
+#: elf32-ip2k.c:1409
+#, c-format
+msgid "ip2k linker: redundant page instruction at 0x%08lx (dest = 0x%08lx)."
+msgstr "ip2k linker: instrucþiune redundantã de paginã la 0x%08lx (dest = 0x%08lx)."
+
+#. Only if it's not an unresolved symbol.
+#: elf32-ip2k.c:1593
+msgid "unsupported relocation between data/insn address spaces"
+msgstr "relocare nesuportatã între datã/spaþiu adresã insn"
+
+#: elf32-iq2000.c:907 elf32-m68hc1x.c:1431 elf32-ppc.c:2175 elf64-sparc.c:3072
+#: elfxx-mips.c:9195
+#, c-format
+msgid "%s: uses different e_flags (0x%lx) fields than previous modules (0x%lx)"
+msgstr "%s: foloseºte câmpuri de marcaje e_flags (0x%lx) diferite de modulele anterioare (0x%lx)"
+
+#: elf32-m32r.c:930
+msgid "SDA relocation when _SDA_BASE_ not defined"
+msgstr "Relocare SDA când _SDA_BASE_ nu este definit"
+
+#: elf32-m32r.c:1018 elf64-alpha.c:4279 elf64-alpha.c:4407 elf32-ia64.c:3958
+#: elf64-ia64.c:3958
+#, c-format
+msgid "%s: unknown relocation type %d"
+msgstr "%s: tip necunoscut de relocare %d"
+
+#: elf32-m32r.c:1226
+#, c-format
+msgid "%s: The target (%s) of an %s relocation is in the wrong section (%s)"
+msgstr "%s: Þinta (%s) unei relocãri %s este în secþiunea nepotrivitã (%s)"
+
+#: elf32-m32r.c:1952
+#, c-format
+msgid "%s: Instruction set mismatch with previous modules"
+msgstr "%s: Setul de instrucþiuni nu se potriveºte cu modulele anterioare"
+
+#: elf32-m32r.c:1975
+#, c-format
+msgid "private flags = %lx"
+msgstr "marcaje (flags) private = %lx"
+
+#: elf32-m32r.c:1980
+msgid ": m32r instructions"
+msgstr ": instrucþiuni m32r"
+
+#: elf32-m32r.c:1981
+msgid ": m32rx instructions"
+msgstr ": instrucþiuni m32rx"
+
+#: elf32-m68hc1x.c:1217
+#, c-format
+msgid "Reference to the far symbol `%s' using a wrong relocation may result in incorrect execution"
+msgstr "Referinþa la simbolul depãrtat `%s' folosind o relocare invalidã poate duce la execuþie incorectã"
+
+#: elf32-m68hc1x.c:1240
+#, c-format
+msgid "banked address [%lx:%04lx] (%lx) is not in the same bank as current banked address [%lx:%04lx] (%lx)"
+msgstr "adresa banked [%lx:%04lx] (%lx) nu este în acelaºi bank precum adresa banked curentã [%lx:%04lx] (%lx)"
+
+#: elf32-m68hc1x.c:1259
+#, c-format
+msgid "reference to a banked address [%lx:%04lx] in the normal address space at %04lx"
+msgstr "referinþã la adresa banked [%lx:%04lx] în spaþiul normal de adresã la %04lx"
+
+#: elf32-m68hc1x.c:1396
+#, c-format
+msgid "%s: linking files compiled for 16-bit integers (-mshort) and others for 32-bit integers"
+msgstr "%s: linkuire a fiºierelor compilate pentru întregi(integers) pe 16-biþi (-mshort) ºi a celorlalte pentru întregi(integers) pe 32-biþi"
+
+#: elf32-m68hc1x.c:1404
+#, c-format
+msgid "%s: linking files compiled for 32-bit double (-fshort-double) and others for 64-bit double"
+msgstr "%s: linkuire a fiºierelor compilate pentru double pe 32-biþi (-fshort-double) ºi a celorlalte pentru double pe 64-biþi"
+
+#: elf32-m68hc1x.c:1414
+#, c-format
+msgid "%s: linking files compiled for HCS12 with others compiled for HC12"
+msgstr "%s:linkuire a fiºierelor compilate pentru HCS12 cu celelalte compilate pentru HC12"
+
+#: elf32-m68hc1x.c:1462
+msgid "[abi=32-bit int, "
+msgstr "[abi=32-bit int, "
+
+#: elf32-m68hc1x.c:1464
+msgid "[abi=16-bit int, "
+msgstr "[abi=16-bit int, "
+
+#: elf32-m68hc1x.c:1467
+msgid "64-bit double, "
+msgstr "double pe 64-biþi, "
+
+#: elf32-m68hc1x.c:1469
+msgid "32-bit double, "
+msgstr "double pe 32-biþi, "
+
+#: elf32-m68hc1x.c:1472
+msgid "cpu=HC11]"
+msgstr "cpu=HC11]"
+
+#: elf32-m68hc1x.c:1474
+msgid "cpu=HCS12]"
+msgstr "cpu=HCS12]"
+
+#: elf32-m68hc1x.c:1476
+msgid "cpu=HC12]"
+msgstr "cpu=HC12]"
+
+#: elf32-m68hc1x.c:1479
+msgid " [memory=bank-model]"
+msgstr " [memorie=mod-bank]"
+
+#: elf32-m68hc1x.c:1481
+msgid " [memory=flat]"
+msgstr " [memorie=întinsã(flat)]"
+
+#: elf32-m68k.c:400
+msgid " [cpu32]"
+msgstr " [cpu32]"
+
+#: elf32-m68k.c:403
+msgid " [m68000]"
+msgstr " [m68000]"
+
+#: elf32-mcore.c:353 elf32-mcore.c:456
+#, c-format
+msgid "%s: Relocation %s (%d) is not currently supported.\n"
+msgstr "%s: Relocarea %s (%d) nu este încã suportatã.\n"
+
+#: elf32-mcore.c:441
+#, c-format
+msgid "%s: Unknown relocation type %d\n"
+msgstr "%s: Tip necunoscut de relocare %d\n"
+
+#: elf32-mips.c:1170 elf64-mips.c:1717 elfn32-mips.c:1664
+msgid "32bits gp relative relocation occurs for an external symbol"
+msgstr "relocarea relativã gp 32bits are loc pe un simbol extern"
+
+#: elf32-mips.c:1314 elf64-mips.c:1830 elfn32-mips.c:1783
+#, c-format
+msgid "Linking mips16 objects into %s format is not supported"
+msgstr "Linkuirea obiectelor mips16 în formatul %s nu este suportatã"
+
+#: elf32-ppc.c:2056
+#, c-format
+msgid "generic linker can't handle %s"
+msgstr "linkerul generic nu poate manipula(handle) %s"
+
+#: elf32-ppc.c:2138
+#, c-format
+msgid "%s: compiled with -mrelocatable and linked with modules compiled normally"
+msgstr "%s: compilat cu -mrelocatable ºi linkuit cu module compilate normal"
+
+#: elf32-ppc.c:2147
+#, c-format
+msgid "%s: compiled normally and linked with modules compiled with -mrelocatable"
+msgstr "%s: compilat normal ºi linkuite cu module compilate cu -mrelocatable"
+
+#: elf32-ppc.c:3413
+#, c-format
+msgid "%s: relocation %s cannot be used when making a shared object"
+msgstr "%s: relocarea %s nu poate fi folositã când se creazã un shared object"
+
+#. It does not make sense to have a procedure linkage
+#. table entry for a local symbol.
+#: elf32-ppc.c:3619
+#, c-format
+msgid "%s(%s+0x%lx): %s reloc against local symbol"
+msgstr "relocare %s(%s+0x%lx): %s pe simbol local"
+
+#: elf32-ppc.c:4862 elf64-ppc.c:7789
+#, c-format
+msgid "%s: unknown relocation type %d for symbol %s"
+msgstr "%s: tip de relocare %d necunoscut pentru simbolul %s"
+
+#: elf32-ppc.c:5113
+#, c-format
+msgid "%s(%s+0x%lx): non-zero addend on %s reloc against `%s'"
+msgstr "%s(%s+0x%lx): adãugare non-zero în relocarea %s pentru `%s'"
+
+#: elf32-ppc.c:5399 elf32-ppc.c:5425 elf32-ppc.c:5484
+#, c-format
+msgid "%s: the target (%s) of a %s relocation is in the wrong output section (%s)"
+msgstr "%s: þinta (%s) unei relocãri %s este într-o secþiune invalidã de output (%s)"
+
+#: elf32-ppc.c:5539
+#, c-format
+msgid "%s: relocation %s is not yet supported for symbol %s."
+msgstr "%s: relocarea %s nu este încã suportatã pentru simbolul %s."
+
+#: elf32-ppc.c:5594 elf64-ppc.c:8461
+#, c-format
+msgid "%s(%s+0x%lx): unresolvable %s relocation against symbol `%s'"
+msgstr "%s(%s+0x%lx): relocare nerezolvabilã %s pe simbolul `%s'"
+
+#: elf32-ppc.c:5644 elf64-ppc.c:8507
+#, c-format
+msgid "%s(%s+0x%lx): %s reloc against `%s': error %d"
+msgstr "%s(%s+0x%lx):relocarea %s pe `%s': eroare %d"
+
+#: elf32-ppc.c:5888
+#, c-format
+msgid "corrupt or empty %s section in %s"
+msgstr "secþiune %s coruptã sau vidã în %s"
+
+#: elf32-ppc.c:5895
+#, c-format
+msgid "unable to read in %s section from %s"
+msgstr "nu se poate citi în secþiunea %s din %s"
+
+#: elf32-ppc.c:5901
+#, c-format
+msgid "corrupt %s section in %s"
+msgstr "secþiune coruptã %s în %s"
+
+#: elf32-ppc.c:5944
+#, c-format
+msgid "warning: unable to set size of %s section in %s"
+msgstr "avertisment: nu se poate seta mãrimea secþiunii %s în %s"
+
+#: elf32-ppc.c:5994
+msgid "failed to allocate space for new APUinfo section."
+msgstr "nu s-a putut aloca spaþiu pentru secþiunea nouã APUinfo."
+
+#: elf32-ppc.c:6013
+msgid "failed to compute new APUinfo section."
+msgstr "nu s-a putut calcula(compute) secþiunea nouã APUinfo."
+
+#: elf32-ppc.c:6016
+msgid "failed to install new APUinfo section."
+msgstr "nu s-a putut instala secþiunea APUinfo nouã."
+
+#: elf32-s390.c:2256 elf64-s390.c:2226
+#, c-format
+msgid "%s(%s+0x%lx): invalid instruction for TLS relocation %s"
+msgstr "%s(%s+0x%lx): instrucþiune invalidã pentur relocarea TLS %s"
+
+#: elf32-sh.c:2103
+#, c-format
+msgid "%s: 0x%lx: warning: bad R_SH_USES offset"
+msgstr "%s: 0x%lx: avertisment: offset R_SH_USES invalid"
+
+#: elf32-sh.c:2115
+#, c-format
+msgid "%s: 0x%lx: warning: R_SH_USES points to unrecognized insn 0x%x"
+msgstr "%s: 0x%lx: avertisment: R_SH_USES trimite cãtre insn necunoscut 0x%x"
+
+#: elf32-sh.c:2132
+#, c-format
+msgid "%s: 0x%lx: warning: bad R_SH_USES load offset"
+msgstr "%s: 0x%lx: avertisment:offset de încãrcare R_SH_USES invalid"
+
+#: elf32-sh.c:2147
+#, c-format
+msgid "%s: 0x%lx: warning: could not find expected reloc"
+msgstr "%s: 0x%lx: avertismetn: nu s-a putut gãsi relocarea aºteptatã"
+
+#: elf32-sh.c:2175
+#, c-format
+msgid "%s: 0x%lx: warning: symbol in unexpected section"
+msgstr "%s: 0x%lx: avertisment: simbol în secþiune neaºteptatã"
+
+#: elf32-sh.c:2300
+#, c-format
+msgid "%s: 0x%lx: warning: could not find expected COUNT reloc"
+msgstr "%s: 0x%lx: avertisment: nu s-a putut gãsi relocarea COUNT aºteptatã"
+
+#: elf32-sh.c:2309
+#, c-format
+msgid "%s: 0x%lx: warning: bad count"
+msgstr "%s: 0x%lx: avertisment: numãrãtoare(count) invalidã"
+
+#: elf32-sh.c:2712 elf32-sh.c:3088
+#, c-format
+msgid "%s: 0x%lx: fatal: reloc overflow while relaxing"
+msgstr "%s: 0x%lx: fatal: relocare depãºitã(overflow) în timpul relaxãrii"
+
+#: elf32-sh.c:4654 elf64-sh64.c:1585
+msgid "Unexpected STO_SH5_ISA32 on local symbol is not handled"
+msgstr "STO_SH5_ISA32 neaºteptat pe simbol local ce nu poate fi manipulat"
+
+#: elf32-sh.c:4809
+#, c-format
+msgid "%s: unresolvable relocation against symbol `%s' from %s section"
+msgstr "%s: relocare nerezolvabilã pe simbolul '%s' din secþiunea `%s'"
+
+#: elf32-sh.c:4881
+#, c-format
+msgid "%s: 0x%lx: fatal: unaligned branch target for relax-support relocation"
+msgstr "%s: 0x%lx: fatal: ramurã þintã nealiniatã pentru relocare cu suport de relaxare"
+
+#: elf32-sh.c:6627 elf64-alpha.c:4848
+#, c-format
+msgid "%s: TLS local exec code cannot be linked into shared objects"
+msgstr "%s: codul local executabil TLS nu poate fi linkuit în shared objects"
+
+#: elf32-sh64.c:221 elf64-sh64.c:2407
+#, c-format
+msgid "%s: compiled as 32-bit object and %s is 64-bit"
+msgstr "%s: compilat ca obiect pe 32-biþi ºi %s este pe 64-biþi"
+
+#: elf32-sh64.c:224 elf64-sh64.c:2410
+#, c-format
+msgid "%s: compiled as 64-bit object and %s is 32-bit"
+msgstr "%s: compilat ca obiect pe 64-biþi ºi %s este pe 32-biþi"
+
+#: elf32-sh64.c:226 elf64-sh64.c:2412
+#, c-format
+msgid "%s: object size does not match that of target %s"
+msgstr "%s: mãrimea obiectului nu se potriveºte cu cea a þintei %s"
+
+#: elf32-sh64.c:461 elf64-sh64.c:2990
+#, c-format
+msgid "%s: encountered datalabel symbol in input"
+msgstr "%s: s-a întâlnit un simbol etichetãdate(datalabel) în intrare(input)"
+
+#: elf32-sh64.c:544
+msgid "PTB mismatch: a SHmedia address (bit 0 == 1)"
+msgstr "nepotrivire PTB: o adresã SHmedia (bit 0 == 1)"
+
+#: elf32-sh64.c:547
+msgid "PTA mismatch: a SHcompact address (bit 0 == 0)"
+msgstr "nepotrivire PTA: o adresã SHcompact (bit 0 == 0)"
+
+#: elf32-sh64.c:565
+#, c-format
+msgid "%s: GAS error: unexpected PTB insn with R_SH_PT_16"
+msgstr "%s: eroare GASr: PTB insn neaºteptat cu R_SH_PT_16"
+
+#: elf32-sh64.c:614 elf64-sh64.c:1748
+#, c-format
+msgid "%s: error: unaligned relocation type %d at %08x reloc %08x\n"
+msgstr "%s: eroare: tip de reloare nealiniat %d la %08x relocarea %08x\n"
+
+#: elf32-sh64.c:698
+#, c-format
+msgid "%s: could not write out added .cranges entries"
+msgstr "%s: nu am putut scrie intrãrile .cranges adãugate"
+
+#: elf32-sh64.c:760
+#, c-format
+msgid "%s: could not write out sorted .cranges entries"
+msgstr "%s: nu am putut scrie intrãrile .cranges sortate"
+
+#: elf32-sparc.c:2521 elf64-sparc.c:2314
+#, c-format
+msgid "%s: probably compiled without -fPIC?"
+msgstr "%s: probabil compilat fãrã -fPIC?"
+
+#: elf32-sparc.c:3348
+#, c-format
+msgid "%s: compiled for a 64 bit system and target is 32 bit"
+msgstr "%s: compilat pentru un sistem 64 biþi ºi þinta fiind pe 32 biþi"
+
+#: elf32-sparc.c:3362
+#, c-format
+msgid "%s: linking little endian files with big endian files"
+msgstr "%s: linkuire fiºiere little endian files cu fiºiere big endian"
+
+#: elf32-v850.c:753
+#, c-format
+msgid "Variable `%s' cannot occupy in multiple small data regions"
+msgstr "Variabila `%s' nu poate ocupa regiuni multiple de date mici"
+
+#: elf32-v850.c:756
+#, c-format
+msgid "Variable `%s' can only be in one of the small, zero, and tiny data regions"
+msgstr "Variabila `%s' nu poate sã fie în una din regiunile mici, zero sau micuþe"
+
+#: elf32-v850.c:759
+#, c-format
+msgid "Variable `%s' cannot be in both small and zero data regions simultaneously"
+msgstr "Variabila `%s' nu poate fi simultan ºi în regiuni de date mici ºi de date zero"
+
+#: elf32-v850.c:762
+#, c-format
+msgid "Variable `%s' cannot be in both small and tiny data regions simultaneously"
+msgstr "Variabila `%s' nu poate fi simultan ºi în regiuni de date mici ºi de date micuþe"
+
+#: elf32-v850.c:765
+#, c-format
+msgid "Variable `%s' cannot be in both zero and tiny data regions simultaneously"
+msgstr "Variabila `%s' nu poate fi simultan ºi în regiuni de date zero ºi de date micuþe"
+
+#: elf32-v850.c:1144
+msgid "FAILED to find previous HI16 reloc\n"
+msgstr "EªUARE în gãsirea relocãrii anterioare HI16\n"
+
+#: elf32-v850.c:1789
+msgid "could not locate special linker symbol __gp"
+msgstr "nu am putut localiza simbolul special de linker __gp"
+
+#: elf32-v850.c:1793
+msgid "could not locate special linker symbol __ep"
+msgstr "nu am putut localiza simbolul special de linker __ep"
+
+#: elf32-v850.c:1797
+msgid "could not locate special linker symbol __ctbp"
+msgstr "nu am putut localiza simbolul special de linker __ctbp"
+
+#: elf32-v850.c:1963
+#, c-format
+msgid "%s: Architecture mismatch with previous modules"
+msgstr "%s: Arhitectura nu se potriveºte cu modulele anterioare"
+
+#: elf32-v850.c:1983
+#, c-format
+msgid "private flags = %lx: "
+msgstr "marcaje(flags) private=- %lx: "
+
+#: elf32-v850.c:1988
+msgid "v850 architecture"
+msgstr "arhitecturã v850"
+
+#: elf32-v850.c:1989
+msgid "v850e architecture"
+msgstr "arhitecturã v850e"
+
+#: elf32-vax.c:549
+msgid " [nonpic]"
+msgstr " [nonpic]"
+
+#: elf32-vax.c:552
+msgid " [d-float]"
+msgstr " [d-float]"
+
+#: elf32-vax.c:555
+msgid " [g-float]"
+msgstr " [g-float]"
+
+#: elf32-vax.c:663
+#, c-format
+msgid "%s: warning: GOT addend of %ld to `%s' does not match previous GOT addend of %ld"
+msgstr "%s: avertisment: adãugarea GOT a %ld în `%s' nu se potriveºte adãugãrii GOT anterioare a %ld"
+
+#: elf32-vax.c:1667
+#, c-format
+msgid "%s: warning: PLT addend of %d to `%s' from %s section ignored"
+msgstr "%s: avertisment: adãugarea PLT a %d în `%s' din secþiunea %s ignoratã"
+
+#: elf32-vax.c:1802
+#, c-format
+msgid "%s: warning: %s relocation against symbol `%s' from %s section"
+msgstr "%s: avertisment: relocare %s pentru simbolul `%s' din secþiunea %s"
+
+#: elf32-vax.c:1808
+#, c-format
+msgid "%s: warning: %s relocation to 0x%x from %s section"
+msgstr "%s: avertisment: relocare %s spre 0x%x din secþiunea %s"
+
+#: elf32-xstormy16.c:462 elf32-ia64.c:2450 elf64-ia64.c:2450
+msgid "non-zero addend in @fptr reloc"
+msgstr "adãugare non-zero în relocare @fptr"
+
+#: elf64-alpha.c:1108
+msgid "GPDISP relocation did not find ldah and lda instructions"
+msgstr "relocarea GPDISP nu a gãsit instrucþiuni ldah ºi lda"
+
+#: elf64-alpha.c:3731
+#, c-format
+msgid "%s: .got subsegment exceeds 64K (size %d)"
+msgstr "%s: .subsegmentul got depãseºte 64K (size %d)"
+
+#: elf64-alpha.c:4602 elf64-alpha.c:4614
+#, c-format
+msgid "%s: gp-relative relocation against dynamic symbol %s"
+msgstr "%s: relocare relativã-gp pentru simbolul %s"
+
+#: elf64-alpha.c:4640 elf64-alpha.c:4773
+#, c-format
+msgid "%s: pc-relative relocation against dynamic symbol %s"
+msgstr "%s: relocare relativã pc pentru simbolul dinamic %s"
+
+#: elf64-alpha.c:4668
+#, c-format
+msgid "%s: change in gp: BRSGP %s"
+msgstr "%s: schimbare în gp: BRSGP %s"
+
+#: elf64-alpha.c:4693
+msgid "<unknown>"
+msgstr "<necunoscut>"
+
+#: elf64-alpha.c:4698
+#, c-format
+msgid "%s: !samegp reloc against symbol without .prologue: %s"
+msgstr "%s: !samegp reloc apentru simbol fãrã .prologue: %s"
+
+#: elf64-alpha.c:4749
+#, c-format
+msgid "%s: unhandled dynamic relocation against %s"
+msgstr "%s: relocare dinamicã nemanipulabilã pentru %s"
+
+#: elf64-alpha.c:4832
+#, c-format
+msgid "%s: dtp-relative relocation against dynamic symbol %s"
+msgstr "%s: relocare relativã-dtp pentru simbolul dinamic %s"
+
+#: elf64-alpha.c:4855
+#, c-format
+msgid "%s: tp-relative relocation against dynamic symbol %s"
+msgstr "%s: relocare relativã-tp pentru simbolul dinamic %s"
+
+#: elf64-hppa.c:2086
+#, c-format
+msgid "stub entry for %s cannot load .plt, dp offset = %ld"
+msgstr "intrarea trunchiatã pentru %s nu poate încãrca .plt, offset dp = %ld"
+
+#: elf64-mmix.c:1032
+#, c-format
+msgid ""
+"%s: Internal inconsistency error for value for\n"
+" linker-allocated global register: linked: 0x%lx%08lx != relaxed: 0x%lx%08lx\n"
+msgstr ""
+"%s: eroare internã de inconsistenþã pentru valoarea\n"
+"registrului global alocat de linker: linkuit: 0x%lx%08lx != relaxat: 0x%lx%08lx\n"
+
+#: elf64-mmix.c:1416
+#, c-format
+msgid "%s: base-plus-offset relocation against register symbol: (unknown) in %s"
+msgstr "%s:relocare-offset-bazã-plus pentru simbolul registru: (necunoscut) în %s"
+
+#: elf64-mmix.c:1421
+#, c-format
+msgid "%s: base-plus-offset relocation against register symbol: %s in %s"
+msgstr "%s:relocare-offset-bazã-plus pentru simbolul registru: %s în %s"
+
+#: elf64-mmix.c:1465
+#, c-format
+msgid "%s: register relocation against non-register symbol: (unknown) in %s"
+msgstr "%s:relocare registru pentru simbolul non-registru: (necunoscut) în %s"
+
+#: elf64-mmix.c:1470
+#, c-format
+msgid "%s: register relocation against non-register symbol: %s in %s"
+msgstr "%s:relocare registru pentru simbolul non-registru: %s în %s"
+
+#: elf64-mmix.c:1507
+#, c-format
+msgid "%s: directive LOCAL valid only with a register or absolute value"
+msgstr "%s: directiva LOCAL este validã doar cu un registru sau o valoare absolutã"
+
+#: elf64-mmix.c:1535
+#, c-format
+msgid "%s: LOCAL directive: Register $%ld is not a local register. First global register is $%ld."
+msgstr "%s: directivã LOCAL: Registrulr $%ld nu este un registru local. Primul registru global $%ld."
+
+#: elf64-mmix.c:1994
+#, c-format
+msgid "%s: Error: multiple definition of `%s'; start of %s is set in a earlier linked file\n"
+msgstr "%s: Eroare: definiþii multiple ale `%s'; începutul lui %s este setat într-un fiºierlinkuit anterior\n"
+
+#: elf64-mmix.c:2053
+msgid "Register section has contents\n"
+msgstr "Secþiunea registru nu are conþinut\n"
+
+#: elf64-mmix.c:2216
+#, c-format
+msgid ""
+"Internal inconsistency: remaining %u != max %u.\n"
+" Please report this bug."
+msgstr ""
+"Inconsistenþã internã: rãmâne %u ! = max %u\n"
+" Vã rugãm raportaþi acest bug."
+
+#: elf64-ppc.c:2388 libbfd.c:831
+#, c-format
+msgid "%s: compiled for a big endian system and target is little endian"
+msgstr "%s: compilat pentru un sistem big endiat iar þinta este little endian"
+
+#: elf64-ppc.c:2391 libbfd.c:833
+#, c-format
+msgid "%s: compiled for a little endian system and target is big endian"
+msgstr "%s: compilat pentru un sistem little endiat iar þinta este big endian"
+
+#: elf64-ppc.c:4857
+#, c-format
+msgid "%s: unexpected reloc type %u in .opd section"
+msgstr "%s: tip de relocare neaºteptat %u în secþiune .opd"
+
+#: elf64-ppc.c:4877
+#, c-format
+msgid "%s: .opd is not a regular array of opd entries"
+msgstr "%s: .opd nu este un domeniu(array) de intrãri opd"
+
+#: elf64-ppc.c:4897
+#, c-format
+msgid "%s: undefined sym `%s' in .opd section"
+msgstr "%s: sym nedefinit `%s' în secþiune .opd"
+
+#: elf64-ppc.c:6136
+#, c-format
+msgid "can't find branch stub `%s'"
+msgstr "nu pot gãsi ramura trunchiatã `%s'"
+
+#: elf64-ppc.c:6175 elf64-ppc.c:6250
+#, c-format
+msgid "linkage table error against `%s'"
+msgstr "eroare tabel de linkuire pentru `%s'"
+
+#: elf64-ppc.c:6340
+#, c-format
+msgid "can't build branch stub `%s'"
+msgstr "nu se poate construi ramura trunchiatã `%s'"
+
+#: elf64-ppc.c:7047
+msgid ".glink and .plt too far apart"
+msgstr ".glink ºi .plt prea departe unul de altul"
+
+#: elf64-ppc.c:7135
+msgid "stubs don't match calculated size"
+msgstr "trunchierile(stubs) sunt în neconcordanþã cu mãrimea calculatã"
+
+#: elf64-ppc.c:7147
+#, c-format
+msgid ""
+"linker stubs in %u groups\n"
+" branch %lu\n"
+" toc adjust %lu\n"
+" long branch %lu\n"
+" long toc adj %lu\n"
+" plt call %lu"
+msgstr ""
+"trunchieri(stubs) de linker în grupurile %u\n"
+" ramurã %lu\n"
+" ajustare toc %lu\n"
+" ramurã lungã %lu\n"
+" ajust. lungã toc %lu\n"
+" apelare plt %lu"
+
+#: elf64-ppc.c:7723
+#, c-format
+msgid "%s(%s+0x%lx): automatic multiple TOCs not supported using your crt files; recompile with -mminimal-toc or upgrade gcc"
+msgstr "%s(%s+0x%lx): TOCuri multiple nu sunt suportateîn folosirea fiºierelor voastre crt; recompilaþi cu -mminimal-toc sau upgradaþi gcc"
+
+#: elf64-ppc.c:7731
+#, c-format
+msgid "%s(%s+0x%lx): sibling call optimization to `%s' does not allow automatic multiple TOCs; recompile with -mminimal-toc or -fno-optimize-sibling-calls, or make `%s' extern"
+msgstr "%s(%s+0 x%lx): optimizare apelare sibling pentru `%s' nu permite automatTOCuri multiple; recompilaþi cu -mminimal-toc sau -fno-optimize-sibling-calls, sau faceþi(make) `%s' extern"
+
+#: elf64-ppc.c:8329
+#, c-format
+msgid "%s: relocation %s is not supported for symbol %s."
+msgstr "%s: relocarea %s nu este suportatã pentru simbolul %s."
+
+#: elf64-ppc.c:8408
+#, c-format
+msgid "%s: error: relocation %s not a multiple of %d"
+msgstr "%s: eroare: relocarea %s nu este multiplu de %d"
+
+#: elf64-sparc.c:1370
+#, c-format
+msgid "%s: check_relocs: unhandled reloc type %d"
+msgstr "%s: check_relocs: tip de relocare nemanipulabil %d"
+
+#: elf64-sparc.c:1407
+#, c-format
+msgid "%s: Only registers %%g[2367] can be declared using STT_REGISTER"
+msgstr "%s: Doar regiºtrii %%g[2367] pot fi declaraþi folosind STT_REGISTER"
+
+#: elf64-sparc.c:1427
+#, c-format
+msgid "Register %%g%d used incompatibly: %s in %s, previously %s in %s"
+msgstr "Registrul %%g%d a folosit incompatibilitãþi: %s în %s, anterior %s în %s"
+
+#: elf64-sparc.c:1450
+#, c-format
+msgid "Symbol `%s' has differing types: REGISTER in %s, previously %s in %s"
+msgstr "Simbolul `%s' are tipuri diferenþiate: REGISTER în %s, anterior %s în %s"
+
+#: elf64-sparc.c:1496
+#, c-format
+msgid "Symbol `%s' has differing types: %s in %s, previously REGISTER in %s"
+msgstr "Simbolul `%s' are tipuri diferenþiate: %s în %s, anterior REGISTER în %s"
+
+#: elf64-sparc.c:3053
+#, c-format
+msgid "%s: linking UltraSPARC specific with HAL specific code"
+msgstr "%s: linkuire cod specific UltraSPARC cu cod specific HAL"
+
+#: elf64-x86-64.c:739
+#, c-format
+msgid "%s: %s' accessed both as normal and thread local symbol"
+msgstr "%s: `%s' accesate ºi ca simboluri locale normale ºi ca simboluri locale pe fire (thread)"
+
+#: elfcode.h:1113
+#, c-format
+msgid "%s: version count (%ld) does not match symbol count (%ld)"
+msgstr "%s: numãrul versiunii(%ld) nu se potriveºte cu numãrul simbolului (%ld)"
+
+#: elfcode.h:1342
+#, c-format
+msgid "%s(%s): relocation %d has invalid symbol index %ld"
+msgstr "%s(%s): relocarea %d are indexul de simbol invalid %ld"
+
+#: elflink.c:1456
+#, c-format
+msgid "%s: warning: unexpected redefinition of indirect versioned symbol `%s'"
+msgstr "%s: avertisment: redefinire neaºteptatã a simbolului indirect cu versiune(versioned) `%s'"
+
+#: elflink.c:1807
+#, c-format
+msgid "%s: undefined versioned symbol name %s"
+msgstr "%s: nume de simbol versiune %s nedefinit"
+
+#: elflink.c:2142
+#, c-format
+msgid "%s: relocation size mismatch in %s section %s"
+msgstr "%s: nepotrivire a mãrimii de relocare în %s secþiunea %s"
+
+#: elflink.c:2434
+#, c-format
+msgid "warning: type and size of dynamic symbol `%s' are not defined"
+msgstr "avertisment: tipul ºi mãrimea simbolului dinamic `%s' nu sunt definite"
+
+#: elflink.h:1022
+#, c-format
+msgid "%s: %s: invalid version %u (max %d)"
+msgstr "%s: %s: versiune invalidã %u (max %d)"
+
+#: elflink.h:1063
+#, c-format
+msgid "%s: %s: invalid needed version %d"
+msgstr "%s: %s: versiune necesarã %d invalidã"
+
+#: elflink.h:1238
+#, c-format
+msgid "Warning: alignment %u of symbol `%s' in %s is smaller than %u in %s"
+msgstr "Avertisment: alinierea %u al simbolului `%s' din %s este mai micã decât %u în %s"
+
+#: elflink.h:1252
+#, c-format
+msgid "Warning: size of symbol `%s' changed from %lu in %s to %lu in %s"
+msgstr "Avertisment: mãrimea simbolului `%s' a fost schimbatã din %lu din %s în %lu din %s"
+
+#: elflink.h:2160
+#, c-format
+msgid "%s: undefined version: %s"
+msgstr "%s:versiune %s nedefinitã"
+
+#: elflink.h:2226
+#, c-format
+msgid "%s: .preinit_array section is not allowed in DSO"
+msgstr "%s: secþiunea .preinit_array section nu este permisã în DSO"
+
+#: elflink.h:3078
+msgid "Not enough memory to sort relocations"
+msgstr "Nu existã memorie suficientã pentru a sorta relocãrile"
+
+#: elflink.h:3958 elflink.h:4001
+#, c-format
+msgid "%s: could not find output section %s"
+msgstr "%s: nu s-a putut gãsi secþiunea de output %s"
+
+#: elflink.h:3964
+#, c-format
+msgid "warning: %s section has zero size"
+msgstr "avertisment: secþiunea %s are mãrime zero"
+
+#: elflink.h:4483
+#, c-format
+msgid "%s: %s symbol `%s' in %s is referenced by DSO"
+msgstr "%s: %s simbolul `%s' în %s este referit de DSO"
+
+#: elflink.h:4564
+#, c-format
+msgid "%s: could not find output section %s for input section %s"
+msgstr "%s: nu am putut gãsi secþiunea de output %s pentru secþiunea de input %s"
+
+#: elflink.h:4666
+#, c-format
+msgid "%s: %s symbol `%s' isn't defined"
+msgstr "%s: %s simbolul `%s' nu este definit"
+
+#: elflink.h:5053 elflink.h:5095
+msgid "%T: discarded in section `%s' from %s\n"
+msgstr "%T: abandonat(discarded) în secþiunea `%s' din %s\n"
+
+#: elfxx-mips.c:887
+msgid "static procedure (no name)"
+msgstr "procedurã staticã (fãrã nume)"
+
+#: elfxx-mips.c:1897
+msgid "not enough GOT space for local GOT entries"
+msgstr "nu existã destul spaþiu GOT pentru intrãrile GOT locale"
+
+#: elfxx-mips.c:3691
+#, c-format
+msgid "%s: %s+0x%lx: jump to stub routine which is not jal"
+msgstr "%s: %s+0x%lx: salt la rutinã ciot(stub) ce nu este jal"
+
+#: elfxx-mips.c:5192
+#, c-format
+msgid "%s: Malformed reloc detected for section %s"
+msgstr "%s: Relocare malformatã detectatã pentru secþiunea %s"
+
+#: elfxx-mips.c:5266
+#, c-format
+msgid "%s: CALL16 reloc at 0x%lx not against global symbol"
+msgstr "%s: relocarea CALL16 la 0x%lx nu este pe simbolul global"
+
+#: elfxx-mips.c:8692
+#, c-format
+msgid "%s: illegal section name `%s'"
+msgstr "%s: nume ilegal de secþiune `%s'"
+
+#: elfxx-mips.c:9025
+#, c-format
+msgid "%s: endianness incompatible with that of the selected emulation"
+msgstr "%s: endianness incompatibilã cu aceea a emulaþiei selectate"
+
+#: elfxx-mips.c:9037
+#, c-format
+msgid "%s: ABI is incompatible with that of the selected emulation"
+msgstr "%s: ABI este incompatibil cu cel al emulaþiei selectate"
+
+#: elfxx-mips.c:9104
+#, c-format
+msgid "%s: warning: linking PIC files with non-PIC files"
+msgstr "%s: avertisment: linkuire de fiºiere PIC cu fiºiere non-PIC"
+
+#: elfxx-mips.c:9121
+#, c-format
+msgid "%s: linking 32-bit code with 64-bit code"
+msgstr "%s: linkuire cod 32-biþi cu cod 64-biþi"
+
+#: elfxx-mips.c:9149
+#, c-format
+msgid "%s: linking %s module with previous %s modules"
+msgstr "%s: linkuire a modulului %s cu modulele%s anterioare"
+
+#: elfxx-mips.c:9172
+#, c-format
+msgid "%s: ABI mismatch: linking %s module with previous %s modules"
+msgstr "%s: nepotrivire ABI: linkuire modul %s cu module %s anterioare"
+
+#: elfxx-mips.c:9241
+msgid " [abi=O32]"
+msgstr " [abi=O32]"
+
+#: elfxx-mips.c:9243
+msgid " [abi=O64]"
+msgstr " [abi=O64]"
+
+#: elfxx-mips.c:9245
+msgid " [abi=EABI32]"
+msgstr " [abi=EABI32]"
+
+#: elfxx-mips.c:9247
+msgid " [abi=EABI64]"
+msgstr " [abi=EABI64]"
+
+#: elfxx-mips.c:9249
+msgid " [abi unknown]"
+msgstr " [abi necunoscut]"
+
+#: elfxx-mips.c:9251
+msgid " [abi=N32]"
+msgstr " [abi=N32]"
+
+#: elfxx-mips.c:9253
+msgid " [abi=64]"
+msgstr " [abi=64]"
+
+#: elfxx-mips.c:9255
+msgid " [no abi set]"
+msgstr " [abi nesetat]"
+
+#: elfxx-mips.c:9258
+msgid " [mips1]"
+msgstr " [mips1]"
+
+#: elfxx-mips.c:9260
+msgid " [mips2]"
+msgstr " [mips2]"
+
+#: elfxx-mips.c:9262
+msgid " [mips3]"
+msgstr " [mips3]"
+
+#: elfxx-mips.c:9264
+msgid " [mips4]"
+msgstr " [mips4]"
+
+#: elfxx-mips.c:9266
+msgid " [mips5]"
+msgstr " [mips5]"
+
+#: elfxx-mips.c:9268
+msgid " [mips32]"
+msgstr " [mips32]"
+
+#: elfxx-mips.c:9270
+msgid " [mips64]"
+msgstr " [mips64]"
+
+#: elfxx-mips.c:9272
+msgid " [mips32r2]"
+msgstr " [mips32r2]"
+
+#: elfxx-mips.c:9274
+msgid " [unknown ISA]"
+msgstr " [ISA necunoscut]"
+
+#: elfxx-mips.c:9277
+msgid " [mdmx]"
+msgstr " [mdmx]"
+
+#: elfxx-mips.c:9280
+msgid " [mips16]"
+msgstr " [mips16]"
+
+#: elfxx-mips.c:9283
+msgid " [32bitmode]"
+msgstr " [mod32biþi]"
+
+#: elfxx-mips.c:9285
+msgid " [not 32bitmode]"
+msgstr " [non-mod32biþi]"
+
+#: i386linux.c:457 m68klinux.c:461 sparclinux.c:458
+#, c-format
+msgid "Output file requires shared library `%s'\n"
+msgstr "Fiºierul de output necesitã biblioteca globalã(shared) `%s'\n"
+
+#: i386linux.c:465 m68klinux.c:469 sparclinux.c:466
+#, c-format
+msgid "Output file requires shared library `%s.so.%s'\n"
+msgstr "Fiºierul de output necesitã biblioteca globalã(shared) `%s'.so.`%s'\n"
+
+#: i386linux.c:654 i386linux.c:704 m68klinux.c:661 m68klinux.c:709
+#: sparclinux.c:656 sparclinux.c:706
+#, c-format
+msgid "Symbol %s not defined for fixups\n"
+msgstr "Simbolul %s nu este definit pentru acceptare(fixups)\n"
+
+#: i386linux.c:728 m68klinux.c:733 sparclinux.c:730
+msgid "Warning: fixup count mismatch\n"
+msgstr "Avertisment: nepotrivire numãrãtori acceptare(fixup)\n"
+
+#: ieee.c:293
+#, c-format
+msgid "%s: string too long (%d chars, max 65535)"
+msgstr "%s: ºir prea lung (%d caractere, max 65535)"
+
+#: ieee.c:428
+#, c-format
+msgid "%s: unrecognized symbol `%s' flags 0x%x"
+msgstr "%s: simbol necunoscut `%s' marcaje(flags) 0x%x"
+
+#: ieee.c:938
+#, c-format
+msgid "%s: unimplemented ATI record %u for symbol %u"
+msgstr "%s: înregistrare ATI neimplementatã %u pe simbolul %u"
+
+#: ieee.c:963
+#, c-format
+msgid "%s: unexpected ATN type %d in external part"
+msgstr "%s: tip ATN neaºteptat %d în parte externã"
+
+#: ieee.c:985
+#, c-format
+msgid "%s: unexpected type after ATN"
+msgstr "%s: tip neaºteptat dupã ATN"
+
+#: ihex.c:264
+#, c-format
+msgid "%s:%d: unexpected character `%s' in Intel Hex file\n"
+msgstr "%s:%d: caracter neaºteptat `%s' în fiºier Intel Hex\n"
+
+#: ihex.c:372
+#, c-format
+msgid "%s:%u: bad checksum in Intel Hex file (expected %u, found %u)"
+msgstr "%s:%u: checksum invalid în fiºier Intel Hex (se aºtepta %u, s-a gãsit %u)"
+
+#: ihex.c:426
+#, c-format
+msgid "%s:%u: bad extended address record length in Intel Hex file"
+msgstr "%s: %u: mãrime înregistrare a adresei extinse invalidã în fiºier Intel Hex"
+
+#: ihex.c:443
+#, c-format
+msgid "%s:%u: bad extended start address length in Intel Hex file"
+msgstr "%s: %u: mãrime adresã de start extinsã invalidã în fiºier Intel Hex"
+
+#: ihex.c:460
+#, c-format
+msgid "%s:%u: bad extended linear address record length in Intel Hex file"
+msgstr "%s: %u: mãrime înregistrare a adresei lineare extinse invalidã în fiºier Intel Hex"
+
+#: ihex.c:477
+#, c-format
+msgid "%s:%u: bad extended linear start address length in Intel Hex file"
+msgstr "%s: %u: mãrime adresã linearã de start extinsã invalidã în fiºier Intel Hex"
+
+#: ihex.c:494
+#, c-format
+msgid "%s:%u: unrecognized ihex type %u in Intel Hex file\n"
+msgstr "%s: %u: tip ihex necunoscut %u în fiºier Intel Hex\n"
+
+#: ihex.c:619
+#, c-format
+msgid "%s: internal error in ihex_read_section"
+msgstr "%s: eroare internã în ihex_read_section"
+
+#: ihex.c:654
+#, c-format
+msgid "%s: bad section length in ihex_read_section"
+msgstr "%s: mãrime secþiune invalidã în ihex_read_section"
+
+#: ihex.c:872
+#, c-format
+msgid "%s: address 0x%s out of range for Intel Hex file"
+msgstr "%s: adresa 0x%s este în afara domeniului(range) pentru fiºierul Intel Hex"
+
+#: libbfd.c:861
+#, c-format
+msgid "Deprecated %s called at %s line %d in %s\n"
+msgstr "%s învechitã apelatã la %s linia %d în %s\n"
+
+#: libbfd.c:864
+#, c-format
+msgid "Deprecated %s called\n"
+msgstr "%s învechitã apelatã\n"
+
+#: linker.c:1829
+#, c-format
+msgid "%s: indirect symbol `%s' to `%s' is a loop"
+msgstr "%s: simbolul indirect `%s' pentru `%s' este o buclã"
+
+#: linker.c:2697
+#, c-format
+msgid "Attempt to do relocatable link with %s input and %s output"
+msgstr "Încercare de a crea un link relocabil cu input %s ºi output %s"
+
+#: merge.c:896
+#, c-format
+msgid "%s: access beyond end of merged section (%ld + %ld)"
+msgstr "%s: acces dincolo de sfârºitul secþiunii concatenate(merged) (%ld + %ld)"
+
+#: mmo.c:503
+#, c-format
+msgid "%s: No core to allocate section name %s\n"
+msgstr "%s:Nu existã nucleu(core) pentru a aloca numele de secþiune %s\n"
+
+#: mmo.c:579
+#, c-format
+msgid "%s: No core to allocate a symbol %d bytes long\n"
+msgstr "%s: Nu existã nucleu(core) pentru a aloca un simbol lung de %d octeþi\n"
+
+#: mmo.c:1287
+#, c-format
+msgid "%s: invalid mmo file: initialization value for $255 is not `Main'\n"
+msgstr "%s: fiºier mmo invalid: valoare de iniþializare pentru $255 nu este 'Main'\n"
+
+#: mmo.c:1433
+#, c-format
+msgid "%s: unsupported wide character sequence 0x%02X 0x%02X after symbol name starting with `%s'\n"
+msgstr "%s: secvenþã mare(wide) de caractere 0x%02X 0x%02X nesuportatã dupã numele de simbol care începe cu `%s'\n"
+
+#: mmo.c:1674
+#, c-format
+msgid "%s: invalid mmo file: unsupported lopcode `%d'\n"
+msgstr "%s: fiºier mmo invalid: lopcode `%d' nesuportat\n"
+
+#: mmo.c:1684
+#, c-format
+msgid "%s: invalid mmo file: expected YZ = 1 got YZ = %d for lop_quote\n"
+msgstr "%s: fiºier mmo invalid: pentru lop_quote se aºtepta YZ = 1 s-a primit YZ= %d\n"
+
+#: mmo.c:1720
+#, c-format
+msgid "%s: invalid mmo file: expected z = 1 or z = 2, got z = %d for lop_loc\n"
+msgstr "%s: fiºier mmo invalid: pentru lop_loc se aºtepta z =1 sau z = 2 s-a primit z = %d\n"
+
+#: mmo.c:1766
+#, c-format
+msgid "%s: invalid mmo file: expected z = 1 or z = 2, got z = %d for lop_fixo\n"
+msgstr "%s: fiºier mmo invalid: pentru lop_fixo se aºtepta z =1 sau z = 2 s-a primit z = %d\n"
+
+#: mmo.c:1805
+#, c-format
+msgid "%s: invalid mmo file: expected y = 0, got y = %d for lop_fixrx\n"
+msgstr "%s: fiºier mmo invalid: pentru lop_fixrx se aºtepta y =0 s-a primit y = %d\n"
+
+#: mmo.c:1814
+#, c-format
+msgid "%s: invalid mmo file: expected z = 16 or z = 24, got z = %d for lop_fixrx\n"
+msgstr "%s: fiºier mmo invalid: pentru lop_fixrx se aºtepta z =16 sau z = 24 s-a primit z = %d\n"
+
+#: mmo.c:1837
+#, c-format
+msgid "%s: invalid mmo file: leading byte of operand word must be 0 or 1, got %d for lop_fixrx\n"
+msgstr "%s: fiºier mmo invalid: pentru lop_fixrx octetul de înceout al operandului word trebuie sã fie 0 sau 1, s-a primit %d\n"
+
+#: mmo.c:1860
+#, c-format
+msgid "%s: cannot allocate file name for file number %d, %d bytes\n"
+msgstr "%s: nu se poate aloca nume fiºier pentru fiºierul numãrul %d, %d octeþi\n"
+
+#: mmo.c:1880
+#, c-format
+msgid "%s: invalid mmo file: file number %d `%s', was already entered as `%s'\n"
+msgstr "%s: fiºier mmo invalid: fiºierul numãrul %d `%s' a fost deja introdus ca `%s'\n"
+
+#: mmo.c:1893
+#, c-format
+msgid "%s: invalid mmo file: file name for number %d was not specified before use\n"
+msgstr "%s: fiºier mmo invalid: numele de fiºier pentru numãrul %d nu a fost specificat înainte de folosire\n"
+
+#: mmo.c:1999
+#, c-format
+msgid "%s: invalid mmo file: fields y and z of lop_stab non-zero, y: %d, z: %d\n"
+msgstr "%s: fiºier mmo invalid: câmpurile y ºi z ale lop_stab sunt non-zero: y: %d, z: %d\n"
+
+#: mmo.c:2035
+#, c-format
+msgid "%s: invalid mmo file: lop_end not last item in file\n"
+msgstr "%s: fiºier mmo invalid: lop_end nu este ultimul element în fiºier\n"
+
+#: mmo.c:2048
+#, c-format
+msgid "%s: invalid mmo file: YZ of lop_end (%ld) not equal to the number of tetras to the preceding lop_stab (%ld)\n"
+msgstr "%s: fiºier mmo invalid: YZ al lop_end (%ld) nu este egal cu numerele tetras ale lop_stab precedent (%ld)\n"
+
+#: mmo.c:2698
+#, c-format
+msgid "%s: invalid symbol table: duplicate symbol `%s'\n"
+msgstr "%s: tabelã de simboluri invalidã: simbol `%s' duplicat\n"
+
+#: mmo.c:2949
+#, c-format
+msgid "%s: Bad symbol definition: `Main' set to %s rather than the start address %s\n"
+msgstr "%s: Definire invalidã de simbol: `Main' setat la %s în loc de adresa de start %s\n"
+
+#: mmo.c:3039
+#, c-format
+msgid "%s: warning: symbol table too large for mmo, larger than 65535 32-bit words: %d. Only `Main' will be emitted.\n"
+msgstr "%s: avertisment: tabela de simboluri prea mare pentru mmo, mai mare decâd 65535 cuvinte pe 32 de biþi: %d. Doar 'Main' va fi emis.\n"
+
+#: mmo.c:3084
+#, c-format
+msgid "%s: internal error, symbol table changed size from %d to %d words\n"
+msgstr "%s: eroare internã, tabela de simboluri ºi-a schimbat mãrimea din %d în %d cuvinte\n"
+
+#: mmo.c:3139
+#, c-format
+msgid "%s: internal error, internal register section %s had contents\n"
+msgstr "%s: eroare internã, secþiunea de regiºtri internã %s nu are conþinut\n"
+
+#: mmo.c:3191
+#, c-format
+msgid "%s: no initialized registers; section length 0\n"
+msgstr "%s: nu existã regiºtri iniþializaþi; lungime secþiune 0\n"
+
+#: mmo.c:3197
+#, c-format
+msgid "%s: too many initialized registers; section length %ld\n"
+msgstr "%s: prea mulþi regiºtri iniþializaþi; lungime secþiune %ld\n"
+
+#: mmo.c:3202
+#, c-format
+msgid "%s: invalid start address for initialized registers of length %ld: 0x%lx%08lx\n"
+msgstr "%s: adresã de start invalidã pentru regiºtrii iniþializaþi de lungime %ld: 0x%lx%08lx\n"
+
+#: oasys.c:1052
+#, c-format
+msgid "%s: can not represent section `%s' in oasys"
+msgstr "%s: nu se poate reprezenta secþiune `%s' în oasys"
+
+#: osf-core.c:137
+#, c-format
+msgid "Unhandled OSF/1 core file section type %d\n"
+msgstr "Tip nemanipulabil %d de fiºier nucleu(core) OSF/1\n"
+
+#: pe-mips.c:659
+#, c-format
+msgid "%s: `ld -r' not supported with PE MIPS objects\n"
+msgstr "%s: `ld -r' nu este suportat cu obiecte PE MIPS\n"
+
+#. OK, at this point the following variables are set up:
+#. src = VMA of the memory we're fixing up
+#. mem = pointer to memory we're fixing up
+#. val = VMA of what we need to refer to
+#.
+#: pe-mips.c:795
+#, c-format
+msgid "%s: unimplemented %s\n"
+msgstr "%s: %s neimplementat\n"
+
+#: pe-mips.c:821
+#, c-format
+msgid "%s: jump too far away\n"
+msgstr "%s: salt prea departe(far away)\n"
+
+#: pe-mips.c:848
+#, c-format
+msgid "%s: bad pair/reflo after refhi\n"
+msgstr "%s: pair/reflo invalid dupã refhi\n"
+
+#. XXX code yet to be written.
+#: peicode.h:787
+#, c-format
+msgid "%s: Unhandled import type; %x"
+msgstr "%s: Tip import nemanipulabil; %x"
+
+#: peicode.h:792
+#, c-format
+msgid "%s: Unrecognised import type; %x"
+msgstr "%s: Tip import necunoscut; %x"
+
+#: peicode.h:806
+#, c-format
+msgid "%s: Unrecognised import name type; %x"
+msgstr "%s: Tip nume import necunoscut; %x"
+
+#: peicode.h:1164
+#, c-format
+msgid "%s: Unrecognised machine type (0x%x) in Import Library Format archive"
+msgstr "%s: Tip maºinã necunoscut (0x%x) în arhiva Import Library Format"
+
+#: peicode.h:1176
+#, c-format
+msgid "%s: Recognised but unhandled machine type (0x%x) in Import Library Format archive"
+msgstr "%s: Tip de maºinã recunoscut dar nemanipulabil (0x%x) în arhiva Import Library Format"
+
+#: peicode.h:1193
+#, c-format
+msgid "%s: size field is zero in Import Library Format header"
+msgstr "%s: mãrimea câmpului din headerul Import Library Format este zero"
+
+#: peicode.h:1224
+#, c-format
+msgid "%s: string not null terminated in ILF object file."
+msgstr "%s: ºirul nenul terminat în fiºier obiect ILF."
+
+#: ppcboot.c:416
+msgid ""
+"\n"
+"ppcboot header:\n"
+msgstr ""
+"\n"
+"header ppcboot:\n"
+
+#: ppcboot.c:417
+#, c-format
+msgid "Entry offset = 0x%.8lx (%ld)\n"
+msgstr "Offset intrare = 0x%.8lx (%ld)\n"
+
+#: ppcboot.c:418
+#, c-format
+msgid "Length = 0x%.8lx (%ld)\n"
+msgstr "Lungime = 0x%.8lx (%ld)\n"
+
+#: ppcboot.c:421
+#, c-format
+msgid "Flag field = 0x%.2x\n"
+msgstr "Câmp Marcaj(Flag) = 0x%.2x\n"
+
+#: ppcboot.c:427
+#, c-format
+msgid "Partition name = \"%s\"\n"
+msgstr "Nume Partiþie = \"%s\"\n"
+
+#: ppcboot.c:446
+#, c-format
+msgid ""
+"\n"
+"Partition[%d] start = { 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x }\n"
+msgstr ""
+"\n"
+"Start Partiþie[%d] = { 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x }\n"
+
+#: ppcboot.c:452
+#, c-format
+msgid "Partition[%d] end = { 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x }\n"
+msgstr "Sfârºit Partiþie[%d] = { 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x }\n"
+
+#: ppcboot.c:458
+#, c-format
+msgid "Partition[%d] sector = 0x%.8lx (%ld)\n"
+msgstr "Sector Partiþie[%d] sector = 0x%.8lx (%ld)\n"
+
+#: ppcboot.c:459
+#, c-format
+msgid "Partition[%d] length = 0x%.8lx (%ld)\n"
+msgstr "Mãrime Partiþie[%d] = 0x%.8lx (%ld)\n"
+
+#: som.c:5422
+msgid "som_sizeof_headers unimplemented"
+msgstr "som_sizeof_headers neimplementatã"
+
+#: srec.c:302
+#, c-format
+msgid "%s:%d: Unexpected character `%s' in S-record file\n"
+msgstr "%s:%d: Caracter neaºteptat `%s'în fiºier S-record\n"
+
+#: stabs.c:319
+#, c-format
+msgid "%s(%s+0x%lx): Stabs entry has invalid string index."
+msgstr "%s(%s+0x%lx): Intrarea bruscã(stab) are index ºir invalid."
+
+#: syms.c:1019
+msgid "Unsupported .stab relocation"
+msgstr "Relocare .stab nesuportatã"
+
+#: vms-gsd.c:356
+#, c-format
+msgid "bfd_make_section (%s) failed"
+msgstr "bfd_make_section (%s) eºuatã"
+
+#: vms-gsd.c:371
+#, c-format
+msgid "bfd_set_section_flags (%s, %x) failed"
+msgstr "bfd_set_section_flags (%s, %x) eºuatã"
+
+#: vms-gsd.c:407
+#, c-format
+msgid "Size mismatch section %s=%lx, %s=%lx"
+msgstr "Mãrime nepotrivitã secþiune %s=%lx, %s=%lx"
+
+#: vms-gsd.c:704
+#, c-format
+msgid "unknown gsd/egsd subtype %d"
+msgstr "subtip %d gsd/egsd necunoscut"
+
+#: vms-hdr.c:408
+msgid "Object module NOT error-free !\n"
+msgstr "Modul obiect CU erori !\n"
+
+#: vms-misc.c:541
+#, c-format
+msgid "Stack overflow (%d) in _bfd_vms_push"
+msgstr "Depãºire(overflow) de stivã(%d) în bfd_vms_push"
+
+#: vms-misc.c:559
+msgid "Stack underflow in _bfd_vms_pop"
+msgstr "Subfolosire(underflow) a stivei _bfd_vms_pop"
+
+#: vms-misc.c:918
+msgid "_bfd_vms_output_counted called with zero bytes"
+msgstr "_bfd_vms_output_counted apelat cu zero octeþi"
+
+#: vms-misc.c:923
+msgid "_bfd_vms_output_counted called with too many bytes"
+msgstr "_bfd_vms_output_counted apelat cu prea mulþi octeþi"
+
+#: vms-misc.c:1054
+#, c-format
+msgid "Symbol %s replaced by %s\n"
+msgstr "Simbolul %s înlocuit de %s\n"
+
+#: vms-misc.c:1117
+#, c-format
+msgid "failed to enter %s"
+msgstr "Eºec în introducerea %s"
+
+#: vms-tir.c:102
+msgid "No Mem !"
+msgstr "Nu mai existã Mem !"
+
+#: vms-tir.c:383
+#, c-format
+msgid "bad section index in %s"
+msgstr "index de secþiune invalid în %s"
+
+#: vms-tir.c:396
+#, c-format
+msgid "unsupported STA cmd %s"
+msgstr "cmd STA %s nesuportatã"
+
+#: vms-tir.c:401 vms-tir.c:1261
+#, c-format
+msgid "reserved STA cmd %d"
+msgstr "cmd STA %d rezervatã"
+
+#: vms-tir.c:512 vms-tir.c:535
+#, c-format
+msgid "%s: no symbol \"%s\""
+msgstr "%s: nu existã simbolul \"%s\""
+
+#. unsigned shift
+#. rotate
+#. Redefine symbol to current location.
+#. Define a literal.
+#: vms-tir.c:602 vms-tir.c:714 vms-tir.c:824 vms-tir.c:842 vms-tir.c:850
+#: vms-tir.c:859 vms-tir.c:1584
+#, c-format
+msgid "%s: not supported"
+msgstr "%s: nesuportat"
+
+#: vms-tir.c:607 vms-tir.c:1439
+#, c-format
+msgid "%s: not implemented"
+msgstr "%s: neimplementat"
+
+#: vms-tir.c:611 vms-tir.c:1443
+#, c-format
+msgid "reserved STO cmd %d"
+msgstr "cmd STO %d rezervatã"
+
+#: vms-tir.c:729 vms-tir.c:1589
+#, c-format
+msgid "reserved OPR cmd %d"
+msgstr "cmd OPR %d rezervatã"
+
+#: vms-tir.c:797 vms-tir.c:1653
+#, c-format
+msgid "reserved CTL cmd %d"
+msgstr "cmd CTL %d rezervatã"
+
+#. stack byte from image
+#. arg: none.
+#: vms-tir.c:1169
+msgid "stack-from-image not implemented"
+msgstr "stack-from-image neimplementatã"
+
+#: vms-tir.c:1187
+msgid "stack-entry-mask not fully implemented"
+msgstr "stack-entry-mask neimplementatã complet"
+
+#. 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.
+#: vms-tir.c:1201
+msgid "PASSMECH not fully implemented"
+msgstr "PASSMECH neimplementatã complet"
+
+#: vms-tir.c:1220
+msgid "stack-local-symbol not fully implemented"
+msgstr "stack-local-symbol neimplementatã complet"
+
+#: vms-tir.c:1233
+msgid "stack-literal not fully implemented"
+msgstr "stack-literal neimplementatã complet"
+
+#: vms-tir.c:1254
+msgid "stack-local-symbol-entry-point-mask not fully implemented"
+msgstr "stack-local-symbol-entry-point-mask neimplementatã complet"
+
+#: vms-tir.c:1531 vms-tir.c:1543 vms-tir.c:1555 vms-tir.c:1567 vms-tir.c:1632
+#: vms-tir.c:1640 vms-tir.c:1648
+#, c-format
+msgid "%s: not fully implemented"
+msgstr "%s: neimplementatã complet"
+
+#: vms-tir.c:1705
+#, c-format
+msgid "obj code %d not found"
+msgstr "codul abj %d nu a fost gãsit"
+
+#: vms-tir.c:2043
+#, c-format
+msgid "SEC_RELOC with no relocs in section %s"
+msgstr "SEC_RELOC fãrã relocãri în secþiunea %s"
+
+#: vms-tir.c:2331
+#, c-format
+msgid "Unhandled relocation %s"
+msgstr "Relocare nemanipulabilã %s"
+
+#: xcofflink.c:1244
+#, c-format
+msgid "%s: `%s' has line numbers but no enclosing section"
+msgstr "%s: `%s' are numere de linii dar nici o secþiune de închidere"
+
+#: xcofflink.c:1297
+#, c-format
+msgid "%s: class %d symbol `%s' has no aux entries"
+msgstr "%s: clasa %d simbolul `%s' nu are intrãri aux"
+
+#: xcofflink.c:1320
+#, c-format
+msgid "%s: symbol `%s' has unrecognized csect type %d"
+msgstr "%s: simbolul `%s' are tip necunoscut csect %d"
+
+#: xcofflink.c:1332
+#, c-format
+msgid "%s: bad XTY_ER symbol `%s': class %d scnum %d scnlen %d"
+msgstr "%s: simbol XTY_ER invalid `%s': clasa %d scnum %d scnlen %d"
+
+#: xcofflink.c:1368
+#, c-format
+msgid "%s: XMC_TC0 symbol `%s' is class %d scnlen %d"
+msgstr "%s: simblul XMC_TC0 `%s' este clasa %d scnlen %d"
+
+#: xcofflink.c:1520
+#, c-format
+msgid "%s: csect `%s' not in enclosing section"
+msgstr "%s: csect `%s' nu este în secþiunea de închidere"
+
+#: xcofflink.c:1627
+#, c-format
+msgid "%s: misplaced XTY_LD `%s'"
+msgstr "%s:XTY_LD `%s' rãtãcit"
+
+#: xcofflink.c:1958
+#, c-format
+msgid "%s: reloc %s:%d not in csect"
+msgstr "%s: relocarea %s:%d nu este în csect"
+
+#: xcofflink.c:2095
+#, c-format
+msgid "%s: XCOFF shared object when not producing XCOFF output"
+msgstr "%s: XCOFF shared object neproducând output XCOFF"
+
+#: xcofflink.c:2116
+#, c-format
+msgid "%s: dynamic object with no .loader section"
+msgstr "%s: obiect dinamic fãrã secþiune .loader"
+
+#: xcofflink.c:2761
+#, c-format
+msgid "%s: no such symbol"
+msgstr "%s: nu existã acest simbol"
+
+#: xcofflink.c:2894
+msgid "error: undefined symbol __rtinit"
+msgstr "eroare: simbol __rtinit nedefinit"
+
+#: xcofflink.c:3455
+#, c-format
+msgid "warning: attempt to export undefined symbol `%s'"
+msgstr "avertisment: încercare de exportare a simbolului nedefinit `%s'"
+
+#: xcofflink.c:4448
+#, c-format
+msgid "TOC overflow: 0x%lx > 0x10000; try -mminimal-toc when compiling"
+msgstr "suprasolicitare(overflow) TOC: 0x%lx > 0x10000; încercaþi -mminimal-toc la compilare"
+
+#: xcofflink.c:5288 xcofflink.c:5755 xcofflink.c:5817 xcofflink.c:6119
+#, c-format
+msgid "%s: loader reloc in unrecognized section `%s'"
+msgstr "%s: relocare loader în secþiune necunoscutã `%s'"
+
+#: xcofflink.c:5310 xcofflink.c:6130
+#, c-format
+msgid "%s: `%s' in loader reloc but not loader sym"
+msgstr "%s: `%s' în relocare loader dar nu în loader sym"
+
+#: xcofflink.c:5325
+#, c-format
+msgid "%s: loader reloc in read-only section %s"
+msgstr "%s: relocare loader în secþiunea doar-în-citire %s"
+
+#: elf32-ia64.c:2392 elf64-ia64.c:2392
+msgid "@pltoff reloc against local symbol"
+msgstr "relocare @pltoff pe simbol local"
+
+#: elf32-ia64.c:3804 elf64-ia64.c:3804
+#, c-format
+msgid "%s: short data segment overflowed (0x%lx >= 0x400000)"
+msgstr "%s: segment de date scurt depãºit(overflowed) (0x%lx >= 0x400000)"
+
+#: elf32-ia64.c:3815 elf64-ia64.c:3815
+#, c-format
+msgid "%s: __gp does not cover short data segment"
+msgstr "%s: __gp nu acoperã segmentul de date scurte"
+
+#: elf32-ia64.c:4131 elf64-ia64.c:4131
+#, c-format
+msgid "%s: linking non-pic code in a shared library"
+msgstr "%s: linkuire cod non-pic într-o bibliotecã globalã(shared)"
+
+#: elf32-ia64.c:4164 elf64-ia64.c:4164
+#, c-format
+msgid "%s: @gprel relocation against dynamic symbol %s"
+msgstr "%s: relocare @gprel pe simbolul dinamic %s"
+
+#: elf32-ia64.c:4224 elf64-ia64.c:4224
+#, c-format
+msgid "%s: linking non-pic code in a position independent executable"
+msgstr "%s: linkuire cod non-pic într-un executabil independent de poziþie"
+
+#: elf32-ia64.c:4363 elf64-ia64.c:4363
+#, c-format
+msgid "%s: @internal branch to dynamic symbol %s"
+msgstr "%s: ramurã @internal cãtre simbolul dinamic %s"
+
+#: elf32-ia64.c:4365 elf64-ia64.c:4365
+#, c-format
+msgid "%s: speculation fixup to dynamic symbol %s"
+msgstr "%s: rezolvare de speculaþie cãtre simbolul dinamic %s"
+
+#: elf32-ia64.c:4367 elf64-ia64.c:4367
+#, c-format
+msgid "%s: @pcrel relocation against dynamic symbol %s"
+msgstr "%s: relocare @pcrell pe simbolul dinamic %s"
+
+#: elf32-ia64.c:4579 elf64-ia64.c:4579
+msgid "unsupported reloc"
+msgstr "relocare nesuportatã"
+
+#: elf32-ia64.c:4858 elf64-ia64.c:4858
+#, c-format
+msgid "%s: linking trap-on-NULL-dereference with non-trapping files"
+msgstr "%s: linkuire trap-on-NULL-dereference cu fiºiere non-trapping"
+
+#: elf32-ia64.c:4867 elf64-ia64.c:4867
+#, c-format
+msgid "%s: linking big-endian files with little-endian files"
+msgstr "%s: linkuire fiºiere big-endiancu fiºiere little-endian"
+
+#: elf32-ia64.c:4876 elf64-ia64.c:4876
+#, c-format
+msgid "%s: linking 64-bit files with 32-bit files"
+msgstr "%s: linkuire fiºiere pe 64-biþi cu fiºiere pe 32-biþi"
+
+#: elf32-ia64.c:4885 elf64-ia64.c:4885
+#, c-format
+msgid "%s: linking constant-gp files with non-constant-gp files"
+msgstr "%s: linkuire fiºiere constant-gp cu fiºiere non-constant-gp"
+
+#: elf32-ia64.c:4895 elf64-ia64.c:4895
+#, c-format
+msgid "%s: linking auto-pic files with non-auto-pic files"
+msgstr "%s: linkuire fiºiere auto-pic cu fiºiere non-auto-pic"
+
+#: peigen.c:985 pepigen.c:985
+#, c-format
+msgid "%s: line number overflow: 0x%lx > 0xffff"
+msgstr "%s: depãºire(overflow) numãr linii: 0x%lx > 0xffff"
+
+#: peigen.c:1002 pepigen.c:1002
+#, c-format
+msgid "%s: reloc overflow 1: 0x%lx > 0xffff"
+msgstr "%s: depãºire(overflow) relocare 1: 0x%lx > 0xffff"
+
+#: peigen.c:1016 pepigen.c:1016
+msgid "Export Directory [.edata (or where ever we found it)]"
+msgstr "Director Exportare [.edata (sau oriunde se gãseºte)]"
+
+#: peigen.c:1017 pepigen.c:1017
+msgid "Import Directory [parts of .idata]"
+msgstr "Director Importare [ pãrþi ale .idata]"
+
+#: peigen.c:1018 pepigen.c:1018
+msgid "Resource Directory [.rsrc]"
+msgstr "Director Resursã [.rsrc]"
+
+#: peigen.c:1019 pepigen.c:1019
+msgid "Exception Directory [.pdata]"
+msgstr "Director Excepþie [.pdata]"
+
+#: peigen.c:1020 pepigen.c:1020
+msgid "Security Directory"
+msgstr "Director Securitate"
+
+#: peigen.c:1021 pepigen.c:1021
+msgid "Base Relocation Directory [.reloc]"
+msgstr "Director Relocare de Bazã [.reloc]"
+
+#: peigen.c:1022 pepigen.c:1022
+msgid "Debug Directory"
+msgstr "Director Debug"
+
+#: peigen.c:1023 pepigen.c:1023
+msgid "Description Directory"
+msgstr "Director Descriere"
+
+#: peigen.c:1024 pepigen.c:1024
+msgid "Special Directory"
+msgstr "Director Special"
+
+#: peigen.c:1025 pepigen.c:1025
+msgid "Thread Storage Directory [.tls]"
+msgstr "Director Depozitare Fire(Thread) [.tls]"
+
+#: peigen.c:1026 pepigen.c:1026
+msgid "Load Configuration Directory"
+msgstr "Director Încãrcare Configuraþie"
+
+#: peigen.c:1027 pepigen.c:1027
+msgid "Bound Import Directory"
+msgstr "Director Importare de Graniþã(Bound)"
+
+#: peigen.c:1028 pepigen.c:1028
+msgid "Import Address Table Directory"
+msgstr "Director Importare Tabelã de Adrese"
+
+#: peigen.c:1029 pepigen.c:1029
+msgid "Delay Import Directory"
+msgstr "Director Importare Întârziere"
+
+#: peigen.c:1030 peigen.c:1031 pepigen.c:1030 pepigen.c:1031
+msgid "Reserved"
+msgstr "Rezervat"
+
+#: peigen.c:1094 pepigen.c:1094
+msgid ""
+"\n"
+"There is an import table, but the section containing it could not be found\n"
+msgstr ""
+"\n"
+"Existã o tabelã de importare, dar secþiunea care o conþine n-a putut fi gãsitã\n"
+
+#: peigen.c:1099 pepigen.c:1099
+#, c-format
+msgid ""
+"\n"
+"There is an import table in %s at 0x%lx\n"
+msgstr ""
+"\n"
+"Existã o tabelã de importare în %s la 0x%lx\n"
+
+#: peigen.c:1136 pepigen.c:1136
+#, c-format
+msgid ""
+"\n"
+"Function descriptor located at the start address: %04lx\n"
+msgstr ""
+"\n"
+"Descriptorul de funcþie localizat la adresa de start: %04lx\n"
+
+#: peigen.c:1139 pepigen.c:1139
+#, c-format
+msgid "\tcode-base %08lx toc (loadable/actual) %08lx/%08lx\n"
+msgstr "\tcode-base %08lx toc (încãrcabil/actual) %08lx/%08lx\n"
+
+#: peigen.c:1145 pepigen.c:1145
+msgid ""
+"\n"
+"No reldata section! Function descriptor not decoded.\n"
+msgstr ""
+"\n"
+"Nu existã secþiune reldata! Descriptorul de funcþie nu este decodat.\n"
+
+#: peigen.c:1150 pepigen.c:1150
+#, c-format
+msgid ""
+"\n"
+"The Import Tables (interpreted %s section contents)\n"
+msgstr ""
+"\n"
+"Tabelele de Importare (interpretat conþinutul secþiunii %s)\n"
+
+#: peigen.c:1153 pepigen.c:1153
+msgid ""
+" vma: Hint Time Forward DLL First\n"
+" Table Stamp Chain Name Thunk\n"
+msgstr ""
+" vma: Sugestie Timp Înaintare DLL Primul\n"
+" Tabel Marcaj Lanþ Nume Thunk\n"
+
+#: peigen.c:1204 pepigen.c:1204
+#, c-format
+msgid ""
+"\n"
+"\tDLL Name: %s\n"
+msgstr ""
+"\n"
+"\tNume DLL: %s\n"
+
+#: peigen.c:1215 pepigen.c:1215
+msgid "\tvma: Hint/Ord Member-Name Bound-To\n"
+msgstr "\tvma: Sugestie/Ord Membru-Nume Salt-La\n"
+
+#: peigen.c:1240 pepigen.c:1240
+msgid ""
+"\n"
+"There is a first thunk, but the section containing it could not be found\n"
+msgstr ""
+"\n"
+"Existã un prim thunk, dar secþiunea care îl conþine nu poate fi gãsitã\n"
+
+#: peigen.c:1380 pepigen.c:1380
+msgid ""
+"\n"
+"There is an export table, but the section containing it could not be found\n"
+msgstr ""
+"\n"
+"Existã o tabelã de export, dar secþiunea ce o conþine nu poate fi gãsitã\n"
+
+#: peigen.c:1385 pepigen.c:1385
+#, c-format
+msgid ""
+"\n"
+"There is an export table in %s at 0x%lx\n"
+msgstr ""
+"\n"
+"Existã o tabelã de exportare în %s la 0x%lx\n"
+
+#: peigen.c:1416 pepigen.c:1416
+#, c-format
+msgid ""
+"\n"
+"The Export Tables (interpreted %s section contents)\n"
+"\n"
+msgstr ""
+"\n"
+"Tabelele de Exportare (interpretare conþinut secþiune %s)\n"
+"\n"
+
+#: peigen.c:1420 pepigen.c:1420
+#, c-format
+msgid "Export Flags \t\t\t%lx\n"
+msgstr "Marcaje(Flags) Exportare \t\t\t%lx\n"
+
+#: peigen.c:1423 pepigen.c:1423
+#, c-format
+msgid "Time/Date stamp \t\t%lx\n"
+msgstr "Marcaj(stamp) Orã/Datã \t\t%lx\n"
+
+#: peigen.c:1426 pepigen.c:1426
+#, c-format
+msgid "Major/Minor \t\t\t%d/%d\n"
+msgstr "Major/Minor \t\t\t%d/%d\n"
+
+#: peigen.c:1429 pepigen.c:1429
+msgid "Name \t\t\t\t"
+msgstr "Nume \t\t\t\t"
+
+#: peigen.c:1435 pepigen.c:1435
+#, c-format
+msgid "Ordinal Base \t\t\t%ld\n"
+msgstr "Bazã Ordinalã \t\t\t%ld\n"
+
+#: peigen.c:1438 pepigen.c:1438
+msgid "Number in:\n"
+msgstr "Numãr în:\n"
+
+#: peigen.c:1441 pepigen.c:1441
+#, c-format
+msgid "\tExport Address Table \t\t%08lx\n"
+msgstr "\t Tabelã Exportare Adrese \t\t%08lx\n"
+
+#: peigen.c:1445 pepigen.c:1445
+#, c-format
+msgid "\t[Name Pointer/Ordinal] Table\t%08lx\n"
+msgstr "\tTabelã [Nume Pointer/Ordinal]\t%08lx\n"
+
+#: peigen.c:1448 pepigen.c:1448
+msgid "Table Addresses\n"
+msgstr "Adrese Tabelã\n"
+
+#: peigen.c:1451 pepigen.c:1451
+msgid "\tExport Address Table \t\t"
+msgstr "\tTabelã Exportare de Adrese \t\t"
+
+#: peigen.c:1456 pepigen.c:1456
+msgid "\tName Pointer Table \t\t"
+msgstr "\tNume Pointer Tabelã \t\t"
+
+#: peigen.c:1461 pepigen.c:1461
+msgid "\tOrdinal Table \t\t\t"
+msgstr "\tOrdinal Tabelã \t\t\t"
+
+#: peigen.c:1476 pepigen.c:1476
+#, c-format
+msgid ""
+"\n"
+"Export Address Table -- Ordinal Base %ld\n"
+msgstr ""
+"\n"
+"Tabelã Exportare de Adrese -- Bazã Ordinalã %ld\n"
+
+#: peigen.c:1495 pepigen.c:1495
+msgid "Forwarder RVA"
+msgstr "Trimiþãtor(Forwarder) RVA"
+
+#: peigen.c:1506 pepigen.c:1506
+msgid "Export RVA"
+msgstr "Exportare RVA"
+
+#: peigen.c:1513 pepigen.c:1513
+msgid ""
+"\n"
+"[Ordinal/Name Pointer] Table\n"
+msgstr ""
+"\n"
+"[Ordinal/Nume Pointer] Tabelã\n"
+
+#: peigen.c:1568 pepigen.c:1568
+#, c-format
+msgid "Warning, .pdata section size (%ld) is not a multiple of %d\n"
+msgstr "Avertisment, mãrimea secþiunii .pdata (%ld) nu este multiplu de %d\n"
+
+#: peigen.c:1572 pepigen.c:1572
+msgid ""
+"\n"
+"The Function Table (interpreted .pdata section contents)\n"
+msgstr ""
+"\n"
+"Tabela de Funcþii (interpretare conþinut secþiune .pdata)\n"
+
+#: peigen.c:1575 pepigen.c:1575
+msgid " vma:\t\t\tBegin Address End Address Unwind Info\n"
+msgstr " vma:\t\t\tAdresã Început Adresã Sfârºit Info Unwind\n"
+
+#: peigen.c:1577 pepigen.c:1577
+msgid ""
+" vma:\t\tBegin End EH EH PrologEnd Exception\n"
+" \t\tAddress Address Handler Data Address Mask\n"
+msgstr ""
+" vma:\t\tÎnceput Sfârºit EH EH PrologSfârºit Excepþii\n"
+" \t\tAdresã Adresã Manipulant Date Adresã Mascã\n"
+
+#: peigen.c:1647 pepigen.c:1647
+msgid " Register save millicode"
+msgstr " Registrul salveazã millicode "
+
+#: peigen.c:1650 pepigen.c:1650
+msgid " Register restore millicode"
+msgstr "Registrul reface millicode"
+
+#: peigen.c:1653 pepigen.c:1653
+msgid " Glue code sequence"
+msgstr "Secvenþã de cod lipitã(glue)"
+
+#: peigen.c:1705 pepigen.c:1705
+msgid ""
+"\n"
+"\n"
+"PE File Base Relocations (interpreted .reloc section contents)\n"
+msgstr ""
+"\n"
+"\n"
+"Relocãri Bazã Fiºier PE (interpretare conþinut secþiune .reloc)\n"
+
+#: peigen.c:1735 pepigen.c:1735
+#, c-format
+msgid ""
+"\n"
+"Virtual Address: %08lx Chunk size %ld (0x%lx) Number of fixups %ld\n"
+msgstr ""
+"\n"
+"Adresã Virtualã: %08lx Mãrime Trunchiere %ld (0x%lx) Numãr acceptãri %ld\n"
+
+#: peigen.c:1748 pepigen.c:1748
+#, c-format
+msgid "\treloc %4d offset %4x [%4lx] %s"
+msgstr "\trelocarea %4d offset %4x [%4lx] %s"
+
+#. The MS dumpbin program reportedly ands with 0xff0f before
+#. printing the characteristics field. Not sure why. No reason to
+#. emulate it here.
+#: peigen.c:1788 pepigen.c:1788
+#, c-format
+msgid ""
+"\n"
+"Characteristics 0x%x\n"
+msgstr ""
+"\n"
+"Caracteristici 0x%x\n"
+
+#~ msgid "%s: Unknown special linker type %d"
+#~ msgstr "%s: Tip special necunoscut de linker %d"
+
+#~ msgid "v850ea architecture"
+#~ msgstr "arhitecturã v850ea"
+
+#~ msgid "%s: Section %s is too large to add hole of %ld bytes"
+#~ msgstr "%s: Secþiunea %s este prea mare pentru a adãuga o gaurã de %ld octeþi"
+
+#~ msgid "Error: out of memory"
+#~ msgstr "Eroare: memorie plinã"
+
+#~ msgid "warning: relocation against removed section; zeroing"
+#~ msgstr "avertisment: relocare pe secþiune eliminatã; se umple cu zero(zeroing)"
+
+#~ msgid "warning: relocation against removed section"
+#~ msgstr "avertisment: relocare pe secþiune eliminatã"
+
+#~ msgid "local symbols in discarded section %s"
+#~ msgstr "simboluri locale în secþiunea îndepãrtatã(discarded) %s"
+
+#~ msgid "%s: linking abicalls files with non-abicalls files"
+#~ msgstr "%s: linkuire fiºiere abicalls cu fiºiere non-abicalls"
+
+#~ msgid "%s: ISA mismatch (-mips%d) with previous modules (-mips%d)"
+#~ msgstr "%s: nepotrivire ISA (-mips%d) cu modulele anterioare (-mips%d)"
+
+#~ msgid "%s: ISA mismatch (%d) with previous modules (%d)"
+#~ msgstr "%s: nepotrivire ISA (%d) cu modulele anterioare (%d)"
+
+#~ msgid "%s: dynamic relocation against speculation fixup"
+#~ msgstr "%s: relocare dinamicã pe acceptare(fixup) speculativã"
+
+#~ msgid "%s: speculation fixup against undefined weak symbol"
+#~ msgstr "%s: speculaþie acceptare(fixup) pe simbol ambiguu(weak) nedefinit"
diff --git a/bfd/po/ru.gmo b/bfd/po/ru.gmo
new file mode 100644
index 0000000..9dd8b47
--- /dev/null
+++ b/bfd/po/ru.gmo
Binary files differ
diff --git a/bfd/po/ru.po b/bfd/po/ru.po
new file mode 100644
index 0000000..bd29081
--- /dev/null
+++ b/bfd/po/ru.po
@@ -0,0 +1,6350 @@
+# translation of bfd-2.20.ru.po to Russian
+# Copyright (C) 2003, 2005, 2006, 2009 Free Software Foundation, Inc.
+# This file is distributed under the same license as the binutils package.
+#
+# Yuri Kozlov <yuray@komyakino.ru>, 2009, 2010, 2011, 2012.
+msgid ""
+msgstr ""
+"Project-Id-Version: bfd 2.22.90\n"
+"Report-Msgid-Bugs-To: bug-binutils@gnu.org\n"
+"POT-Creation-Date: 2011-10-25 11:58+0100\n"
+"PO-Revision-Date: 2012-07-29 11:48+0400\n"
+"Last-Translator: Yuri Kozlov <yuray@komyakino.ru>\n"
+"Language-Team: Russian <gnu@mx.ru>\n"
+"Language: ru\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Generator: Lokalize 1.4\n"
+"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
+
+#: aout-adobe.c:127
+msgid "%B: Unknown section type in a.out.adobe file: %x\n"
+msgstr "%B: неизвеÑтный тип раздела в файле a.out.adobe: %x\n"
+
+#: aout-cris.c:199
+#, c-format
+msgid "%s: Invalid relocation type exported: %d"
+msgstr "%s: ÑкÑпортирован неверный тип перемещениÑ: %d"
+
+#: aout-cris.c:242
+msgid "%B: Invalid relocation type imported: %d"
+msgstr "%s: Импортирован неверный тип перемещениÑ: %d"
+
+#: aout-cris.c:253
+msgid "%B: Bad relocation record imported: %d"
+msgstr "%B: Импортирована Ð½ÐµÐºÐ¾Ñ€Ñ€ÐµÐºÑ‚Ð½Ð°Ñ Ð·Ð°Ð¿Ð¸ÑÑŒ о перемещении: %d"
+
+#: aoutx.h:1273 aoutx.h:1611
+#, c-format
+msgid "%s: can not represent section `%s' in a.out object file format"
+msgstr "%s: Ð½ÐµÐ»ÑŒÐ·Ñ Ð¿Ñ€ÐµÐ´Ñтавить раздел «%s» в объектном файле формата a.out"
+
+#: aoutx.h:1577
+#, c-format
+msgid "%s: can not represent section for symbol `%s' in a.out object file format"
+msgstr "%s: Ð½ÐµÐ»ÑŒÐ·Ñ Ð¿Ñ€ÐµÐ´Ñтавить раздел Ð´Ð»Ñ Ñимвола «%s» в объектном файле формата a.out"
+
+#: aoutx.h:1579 vms-alpha.c:7671
+msgid "*unknown*"
+msgstr "*неизвеÑтно*"
+
+#: aoutx.h:4018 aoutx.h:4344
+msgid "%P: %B: unexpected relocation type\n"
+msgstr "%P: %B: неожиданный тип перемещениÑ\n"
+
+#: aoutx.h:5375
+#, c-format
+msgid "%s: relocatable link from %s to %s not supported"
+msgstr "%s: Ð¿ÐµÑ€ÐµÐ¼ÐµÑ‰Ð°ÐµÐ¼Ð°Ñ ÑÑылка из %s в %s не поддерживаетÑÑ"
+
+#: archive.c:2203
+msgid "Warning: writing archive was slow: rewriting timestamp\n"
+msgstr "Предупреждение: Ð¼ÐµÐ´Ð»ÐµÐ½Ð½Ð°Ñ Ð·Ð°Ð¿Ð¸ÑÑŒ в архив: обновлÑетÑÑ Ð¼ÐµÑ‚ÐºÐ° времени\n"
+
+#: archive.c:2491
+msgid "Reading archive file mod timestamp"
+msgstr "Чтение метки времени архивного файла mod"
+
+#: archive.c:2515
+msgid "Writing updated armap timestamp"
+msgstr "ЗапиÑÑŒ обновлённой метки времени armap"
+
+#: bfd.c:398
+msgid "No error"
+msgstr "Ðет ошибки"
+
+#: bfd.c:399
+msgid "System call error"
+msgstr "Ошибка ÑиÑтемного вызова"
+
+#: bfd.c:400
+msgid "Invalid bfd target"
+msgstr "ÐÐµÐ²ÐµÑ€Ð½Ð°Ñ Ñ†ÐµÐ»ÑŒ bfd"
+
+#: bfd.c:401
+msgid "File in wrong format"
+msgstr "Файл в неправильном формате"
+
+#: bfd.c:402
+msgid "Archive object file in wrong format"
+msgstr "Ðрхивный объектный файл в неправильном формате"
+
+#: bfd.c:403
+msgid "Invalid operation"
+msgstr "ÐÐµÐ²ÐµÑ€Ð½Ð°Ñ Ð¾Ð¿ÐµÑ€Ð°Ñ†Ð¸Ñ"
+
+#: bfd.c:404
+msgid "Memory exhausted"
+msgstr "ЗакончилаÑÑŒ памÑÑ‚ÑŒ"
+
+#: bfd.c:405
+msgid "No symbols"
+msgstr "Ðет Ñимволов"
+
+#: bfd.c:406
+msgid "Archive has no index; run ranlib to add one"
+msgstr "Ðрхив без индекÑа; запуÑк ranlib Ð´Ð»Ñ ÑозданиÑ"
+
+#: bfd.c:407
+msgid "No more archived files"
+msgstr "Ðрхивные файлы закончилиÑÑŒ"
+
+#: bfd.c:408
+msgid "Malformed archive"
+msgstr "ИÑкажённый архив"
+
+#: bfd.c:409
+msgid "File format not recognized"
+msgstr "Формат файла не раÑпознан"
+
+#: bfd.c:410
+msgid "File format is ambiguous"
+msgstr "Формат файла неоднозначен"
+
+#: bfd.c:411
+msgid "Section has no contents"
+msgstr "Раздел не имеет Ñодержимого"
+
+#: bfd.c:412
+msgid "Nonrepresentable section on output"
+msgstr "Раздел, непредÑтавимый Ð´Ð»Ñ Ð²Ñ‹Ð²Ð¾Ð´Ð°"
+
+#: bfd.c:413
+msgid "Symbol needs debug section which does not exist"
+msgstr "Ð”Ð»Ñ Ñимвола требуетÑÑ Ð¾Ñ‚Ð»Ð°Ð´Ð¾Ñ‡Ð½Ñ‹Ð¹ раздел, но его не ÑущеÑтвует"
+
+#: bfd.c:414
+msgid "Bad value"
+msgstr "Ðекорректное значение"
+
+#: bfd.c:415
+msgid "File truncated"
+msgstr "Файл уÑечён"
+
+#: bfd.c:416
+msgid "File too big"
+msgstr "Файл Ñлишком большой"
+
+#: bfd.c:417
+#, c-format
+msgid "Error reading %s: %s"
+msgstr "Ошибка Ñ‡Ñ‚ÐµÐ½Ð¸Ñ %s: %s"
+
+#: bfd.c:418
+msgid "#<Invalid error code>"
+msgstr "#<Ðеверный код ошибки>"
+
+#: bfd.c:945
+#, c-format
+msgid "BFD %s assertion fail %s:%d"
+msgstr "Оператор ÐºÐ¾Ð½Ñ‚Ñ€Ð¾Ð»Ñ BFD %s обнаружил ошибку %s:%d"
+
+#: bfd.c:957
+#, c-format
+msgid "BFD %s internal error, aborting at %s line %d in %s\n"
+msgstr "ВнутреннÑÑ Ð¾ÑˆÐ¸Ð±ÐºÐ° BFD %s, оÑтанов на %s, Ñтрока %d в %s\n"
+
+#: bfd.c:961
+#, c-format
+msgid "BFD %s internal error, aborting at %s line %d\n"
+msgstr "ВнутреннÑÑ Ð¾ÑˆÐ¸Ð±ÐºÐ° BFD %s, оÑтанов на %s, Ñтрока %d\n"
+
+#: bfd.c:963
+msgid "Please report this bug.\n"
+msgstr "ПожалуйÑта, Ñообщите об Ñтой ошибке.\n"
+
+#: bfdwin.c:206
+#, c-format
+msgid "not mapping: data=%lx mapped=%d\n"
+msgstr "не отображено: данные=%lx отображено=%d\n"
+
+#: bfdwin.c:209
+#, c-format
+msgid "not mapping: env var not set\n"
+msgstr "не отображено: Ð¿ÐµÑ€ÐµÐ¼ÐµÐ½Ð½Ð°Ñ env не задана\n"
+
+#: binary.c:271
+#, c-format
+msgid "Warning: Writing section `%s' to huge (ie negative) file offset 0x%lx."
+msgstr "Предупреждение: ВыполнÑетÑÑ Ð·Ð°Ð¿Ð¸ÑÑŒ раздела «%s» в файл по огромному (Ñ‚.е. отрицательному) Ñмещению 0x%lx."
+
+#: bout.c:1146 elf-m10300.c:2063 elf32-avr.c:1654 elf32-frv.c:5734
+#: elfxx-sparc.c:2802 reloc.c:6115 reloc16.c:162 elf32-ia64.c:360
+#: elf64-ia64.c:360
+msgid "%P%F: --relax and -r may not be used together\n"
+msgstr "%P%F: --relax и -r Ð½ÐµÐ»ÑŒÐ·Ñ Ð¸Ñпользовать вмеÑте\n"
+
+#: cache.c:227
+msgid "reopening %B: %s\n"
+msgstr "переоткрываетÑÑ %B: %s\n"
+
+#: coff-alpha.c:491
+msgid ""
+"%B: Cannot handle compressed Alpha binaries.\n"
+" Use compiler flags, or objZ, to generate uncompressed binaries."
+msgstr ""
+"%B: Ðе удалоÑÑŒ обработать Ñжатые двоичные файлы Alpha.\n"
+" Ð”Ð»Ñ ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ð½ÐµÑжатых файлов иÑпользуйте параметры компилÑтора или objZ."
+
+#: coff-alpha.c:648
+msgid "%B: unknown/unsupported relocation type %d"
+msgstr "%B: неизвеÑтный/неподдерживаемый тип Ð¿ÐµÑ€ÐµÐ¼ÐµÑ‰ÐµÐ½Ð¸Ñ %d"
+
+#: coff-alpha.c:900 coff-alpha.c:937 coff-alpha.c:2025 coff-mips.c:1003
+msgid "GP relative relocation used when GP not defined"
+msgstr "ИÑпользовано отноÑительное перемещение GP, но GP не определена"
+
+#: coff-alpha.c:1502
+msgid "using multiple gp values"
+msgstr "иÑпользуетÑÑ Ð½ÐµÑколько значений gp"
+
+#: coff-alpha.c:1561
+msgid "%B: unsupported relocation: ALPHA_R_GPRELHIGH"
+msgstr "%B: неподдерживаемое перемещение: ALPHA_R_GPRELHIGH"
+
+#: coff-alpha.c:1568
+msgid "%B: unsupported relocation: ALPHA_R_GPRELLOW"
+msgstr "%B: неподдерживаемое перемещение: ALPHA_R_GPRELLOW"
+
+#: coff-alpha.c:1575 elf32-m32r.c:2484 elf64-alpha.c:4074 elf64-alpha.c:4224
+#: elf32-ia64.c:3839 elf64-ia64.c:3839
+msgid "%B: unknown relocation type %d"
+msgstr "%B: неизвеÑтный тип перемещениÑ: %d"
+
+#: coff-arm.c:1038
+#, c-format
+msgid "%B: unable to find THUMB glue '%s' for `%s'"
+msgstr "%B: не удалоÑÑŒ найти THUMB-Ñклейку «%s» Ð´Ð»Ñ Â«%s»"
+
+#: coff-arm.c:1067
+#, c-format
+msgid "%B: unable to find ARM glue '%s' for `%s'"
+msgstr "%B: не удалоÑÑŒ найти ARM-Ñклейку «%s» Ð´Ð»Ñ Â«%s»"
+
+#: coff-arm.c:1369 elf32-arm.c:7023
+#, c-format
+msgid ""
+"%B(%s): warning: interworking not enabled.\n"
+" first occurrence: %B: arm call to thumb"
+msgstr ""
+"%B(%s): предупреждение: ÑовмеÑÑ‚Ð½Ð°Ñ Ñ€Ð°Ð±Ð¾Ñ‚Ð° не включена.\n"
+" первое упоминание: %B: arm-вызов в thumb"
+
+#: coff-arm.c:1459
+#, c-format
+msgid ""
+"%B(%s): warning: interworking not enabled.\n"
+" first occurrence: %B: thumb call to arm\n"
+" consider relinking with --support-old-code enabled"
+msgstr ""
+"%B(%s): предупреждение: ÑовмеÑÑ‚Ð½Ð°Ñ Ñ€Ð°Ð±Ð¾Ñ‚Ð° не включена.\n"
+" первое упоминание: %B: thumb-вызов в arm\n"
+" выполните переÑборку Ñ Ð²ÐºÐ»ÑŽÑ‡Ñ‘Ð½Ð½Ñ‹Ð¼ параметром --support-old-code"
+
+#: coff-arm.c:1754 coff-tic80.c:695 cofflink.c:3081
+msgid "%B: bad reloc address 0x%lx in section `%A'"
+msgstr "%B: неправильный Ð°Ð´Ñ€ÐµÑ Ð¿ÐµÑ€ÐµÐ¼ÐµÑ‰ÐµÐ½Ð¸Ñ 0x%lx в разделе «%A»"
+
+#: coff-arm.c:2079
+msgid "%B: illegal symbol index in reloc: %d"
+msgstr "%B: недопуÑтимый Ñимвольный Ð¸Ð½Ð´ÐµÐºÑ Ð² перемещении: %d"
+
+#: coff-arm.c:2210
+#, c-format
+msgid "error: %B is compiled for APCS-%d, whereas %B is compiled for APCS-%d"
+msgstr "ошибка: %B Ñобран Ð´Ð»Ñ APCS-%d, в то Ð²Ñ€ÐµÐ¼Ñ ÐºÐ°Ðº %B Ñобран Ð´Ð»Ñ APCS-%d"
+
+#: coff-arm.c:2226 elf32-arm.c:15621
+#, c-format
+msgid "error: %B passes floats in float registers, whereas %B passes them in integer registers"
+msgstr "ошибка: %B передаёт чиÑла Ñ Ð¿Ð»Ð°Ð²Ð°ÑŽÑ‰ÐµÐ¹ точкой в региÑтрах Ñ Ð¿Ð»Ð°Ð²Ð°ÑŽÑ‰ÐµÐ¹ точкой, в то Ð²Ñ€ÐµÐ¼Ñ ÐºÐ°Ðº %B передаёт их в целочиÑленных региÑтрах"
+
+#: coff-arm.c:2229 elf32-arm.c:15625
+#, c-format
+msgid "error: %B passes floats in integer registers, whereas %B passes them in float registers"
+msgstr "ошибка: %B передаёт чиÑла в целочиÑленных региÑтрах, в то Ð²Ñ€ÐµÐ¼Ñ ÐºÐ°Ðº %B передаёт их в региÑтрах Ñ Ð¿Ð»Ð°Ð²Ð°ÑŽÑ‰ÐµÐ¹ точкой"
+
+#: coff-arm.c:2243
+#, c-format
+msgid "error: %B is compiled as position independent code, whereas target %B is absolute position"
+msgstr "ошибка: %B Ñкомпилирован как позиционно-незавиÑимый код, в то Ð²Ñ€ÐµÐ¼Ñ ÐºÐ°Ðº целью %B ÑвлÑетÑÑ ÐºÐ¾Ð´ Ñ Ð°Ð±Ñолютной позицией"
+
+#: coff-arm.c:2246
+#, c-format
+msgid "error: %B is compiled as absolute position code, whereas target %B is position independent"
+msgstr "ошибка: %B Ñкомпилирован как код Ñ Ð°Ð±Ñолютной позицией, в то Ð²Ñ€ÐµÐ¼Ñ ÐºÐ°Ðº целью %B ÑвлÑетÑÑ Ð¿Ð¾Ð·Ð¸Ñ†Ð¸Ð¾Ð½Ð½Ð¾-незавиÑимый код"
+
+#: coff-arm.c:2274 elf32-arm.c:15690
+#, c-format
+msgid "Warning: %B supports interworking, whereas %B does not"
+msgstr "Предупреждение: %B поддерживает ÑовмеÑтную работу, в то Ð²Ñ€ÐµÐ¼Ñ ÐºÐ°Ðº %B нет"
+
+#: coff-arm.c:2277 elf32-arm.c:15696
+#, c-format
+msgid "Warning: %B does not support interworking, whereas %B does"
+msgstr "Предупреждение: %B не поддерживает ÑовмеÑтную работу, в то Ð²Ñ€ÐµÐ¼Ñ ÐºÐ°Ðº %B поддерживает"
+
+#: coff-arm.c:2301
+#, c-format
+msgid "private flags = %x:"
+msgstr "ÑобÑтвенные флаги = %x:"
+
+#: coff-arm.c:2309 elf32-arm.c:11806
+#, c-format
+msgid " [floats passed in float registers]"
+msgstr " [чиÑла Ñ Ð¿Ð»Ð°Ð²Ð°ÑŽÑ‰ÐµÐ¹ точкой передаютÑÑ Ð² региÑтрах Ñ Ð¿Ð»Ð°Ð²Ð°ÑŽÑ‰ÐµÐ¹ точкой]"
+
+#: coff-arm.c:2311
+#, c-format
+msgid " [floats passed in integer registers]"
+msgstr " [чиÑла Ñ Ð¿Ð»Ð°Ð²Ð°ÑŽÑ‰ÐµÐ¹ точкой передаютÑÑ Ð² целочиÑленных региÑтрах]"
+
+#: coff-arm.c:2314 elf32-arm.c:11809
+#, c-format
+msgid " [position independent]"
+msgstr " [позиционно-незавиÑимый]"
+
+#: coff-arm.c:2316
+#, c-format
+msgid " [absolute position]"
+msgstr " [Ñ Ð¾Ð¿Ñ€ÐµÐ´ÐµÐ»Ñ‘Ð½Ð½Ð¾Ð¹ позицией]"
+
+#: coff-arm.c:2320
+#, c-format
+msgid " [interworking flag not initialised]"
+msgstr " [флаг ÑовмеÑтной работы не уÑтановлен]"
+
+#: coff-arm.c:2322
+#, c-format
+msgid " [interworking supported]"
+msgstr " [поддерживаетÑÑ ÑовмеÑÑ‚Ð½Ð°Ñ Ñ€Ð°Ð±Ð¾Ñ‚Ð°]"
+
+#: coff-arm.c:2324
+#, c-format
+msgid " [interworking not supported]"
+msgstr " [ÑовмеÑÑ‚Ð½Ð°Ñ Ñ€Ð°Ð±Ð¾Ñ‚Ð° не поддерживаетÑÑ]"
+
+#: coff-arm.c:2370 elf32-arm.c:10841
+#, c-format
+msgid "Warning: Not setting interworking flag of %B since it has already been specified as non-interworking"
+msgstr "Предупреждение: Флаг ÑовмеÑтной работы Ð´Ð»Ñ %B не уÑтанавливаетÑÑ, так как так как он уже указывает на неÑовмеÑтную работу"
+
+#: coff-arm.c:2374 elf32-arm.c:10845
+#, c-format
+msgid "Warning: Clearing the interworking flag of %B due to outside request"
+msgstr "Предупреждение: ОчищаетÑÑ Ñ„Ð»Ð°Ð³ ÑовмеÑтной работы Ð´Ð»Ñ %B по внешнему запроÑу"
+
+#: coff-h8300.c:1122
+#, c-format
+msgid "cannot handle R_MEM_INDIRECT reloc when using %s output"
+msgstr "невозможно обработать перемещение R_MEM_INDIRECT, еÑли Ð´Ð»Ñ Ð²Ñ‹Ð²Ð¾Ð´Ð° иÑпользуетÑÑ %s"
+
+#: coff-i860.c:147
+#, c-format
+msgid "relocation `%s' not yet implemented"
+msgstr "перемещение «%s» пока не реализовано"
+
+#: coff-i860.c:605 coff-tic54x.c:398 coffcode.h:5198
+msgid "%B: warning: illegal symbol index %ld in relocs"
+msgstr "%B: предупреждение: недопуÑтимый Ñимвольный Ð¸Ð½Ð´ÐµÐºÑ %ld в перемещениÑÑ…"
+
+#: coff-i960.c:144 coff-i960.c:507
+msgid "uncertain calling convention for non-COFF symbol"
+msgstr "неÑÑное Ñоглашение о вызове Ð´Ð»Ñ Ð½Ðµ-COFF Ñимвола"
+
+#: coff-m68k.c:506 elf32-bfin.c:5690 elf32-cr16.c:2897 elf32-m68k.c:4677
+msgid "unsupported reloc type"
+msgstr "неподдерживаемый тип перемещениÑ"
+
+#: coff-mips.c:688 elf32-mips.c:1516 elf32-score.c:431 elf32-score7.c:330
+#: elf64-mips.c:2618 elfn32-mips.c:2431
+msgid "GP relative relocation when _gp not defined"
+msgstr "ОтноÑительное перемещение GP, но _gp не определена"
+
+#: coff-or32.c:229
+msgid "Unrecognized reloc"
+msgstr "ÐераÑпознанное перемещение"
+
+#: coff-rs6000.c:2720
+#, c-format
+msgid "%s: unsupported relocation type 0x%02x"
+msgstr "%s: неподдерживаемый тип Ð¿ÐµÑ€ÐµÐ¼ÐµÑ‰ÐµÐ½Ð¸Ñ 0x%02x"
+
+#: coff-rs6000.c:2805
+#, c-format
+msgid "%s: TOC reloc at 0x%x to symbol `%s' with no TOC entry"
+msgstr "%s: перемещение TOC по адреÑу 0x%x Ñимвола «%s» без Ñлемента TOC"
+
+#: coff-rs6000.c:3556 coff64-rs6000.c:2111
+msgid "%B: symbol `%s' has unrecognized smclas %d"
+msgstr "%B: Ñимвол «%s» имеет нераÑпознанный smclas %d"
+
+#: coff-sh.c:521
+#, c-format
+msgid "SH Error: unknown reloc type %d"
+msgstr "Ошибка SH: неизвеÑтный тип Ð¿ÐµÑ€ÐµÐ¼ÐµÑ‰ÐµÐ½Ð¸Ñ %d"
+
+#: coff-tic4x.c:195 coff-tic54x.c:299 coff-tic80.c:458
+#, c-format
+msgid "Unrecognized reloc type 0x%x"
+msgstr "ÐераÑпознанный тип Ð¿ÐµÑ€ÐµÐ¼ÐµÑ‰ÐµÐ½Ð¸Ñ 0x%x"
+
+#: coff-tic4x.c:240
+#, c-format
+msgid "%s: warning: illegal symbol index %ld in relocs"
+msgstr "%s: предупреждение: в перемещениÑÑ… недопуÑтимый Ñимвольный Ð¸Ð½Ð´ÐµÐºÑ %ld"
+
+#: coff-w65.c:367
+#, c-format
+msgid "ignoring reloc %s\n"
+msgstr "игнорируетÑÑ Ð¿ÐµÑ€ÐµÐ¼ÐµÑ‰ÐµÐ½Ð¸Ðµ %s\n"
+
+#: coffcode.h:997
+msgid "%B: warning: COMDAT symbol '%s' does not match section name '%s'"
+msgstr "%B: предупреждение: COMDAT Ñимвол '%s' не ÑоответÑтвует имени раздела '%s'"
+
+#. Generate a warning message rather using the 'unhandled'
+#. variable as this will allow some .sys files generate by
+#. other toolchains to be processed. See bugzilla issue 196.
+#: coffcode.h:1221
+msgid "%B: Warning: Ignoring section flag IMAGE_SCN_MEM_NOT_PAGED in section %s"
+msgstr "%B: Предупреждение: ИгнорируетÑÑ Ñ„Ð»Ð°Ð³ раздела IMAGE_SCN_MEM_NOT_PAGED в разделе %s"
+
+#: coffcode.h:1288
+msgid "%B (%s): Section flag %s (0x%x) ignored"
+msgstr "%B (%s): ИгнорируетÑÑ Ñ„Ð»Ð°Ð³ раздела %s (0x%x)"
+
+#: coffcode.h:2430
+#, c-format
+msgid "Unrecognized TI COFF target id '0x%x'"
+msgstr "ÐераÑпознанный идентификатор цели TI COFF '0x%x'"
+
+#: coffcode.h:2744
+msgid "%B: reloc against a non-existant symbol index: %ld"
+msgstr "%B: перемещение по неÑущеÑтвующему Ñимвольному индекÑу: %ld"
+
+#: coffcode.h:3302
+msgid "%B: too many sections (%d)"
+msgstr "%B: Ñлишком много разделов: (%d)"
+
+#: coffcode.h:3718
+msgid "%B: section %s: string table overflow at offset %ld"
+msgstr "%B: раздел %s: переполнение таблицы Ñтрок по Ñмещению %d"
+
+#: coffcode.h:4523
+msgid "%B: warning: line number table read failed"
+msgstr "%B: предупреждение: не удалоÑÑŒ прочитать таблицу номеров Ñтрок"
+
+#: coffcode.h:4553
+msgid "%B: warning: illegal symbol index %ld in line numbers"
+msgstr "%B: предупреждение: недопуÑтимый Ñимвольный Ð¸Ð½Ð´ÐµÐºÑ %ld в номерах Ñтрок"
+
+#: coffcode.h:4567
+msgid "%B: warning: duplicate line number information for `%s'"
+msgstr "%B: предупреждение: повторÑющаÑÑÑ Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¾ номере Ñтроки Ð´Ð»Ñ Â«%s»"
+
+#: coffcode.h:4967
+msgid "%B: Unrecognized storage class %d for %s symbol `%s'"
+msgstr "%B: ÐераÑпознанный клаÑÑ Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ %d Ð´Ð»Ñ %s, Ñимвол «%s»"
+
+#: coffcode.h:5093
+msgid "warning: %B: local symbol `%s' has no section"
+msgstr "предупреждение: %B: локальный Ñимвол «%s» не имеет раздела"
+
+#: coffcode.h:5237
+msgid "%B: illegal relocation type %d at address 0x%lx"
+msgstr "%B: недопуÑтимый тип Ð¿ÐµÑ€ÐµÐ¼ÐµÑ‰ÐµÐ½Ð¸Ñ %d по адреÑу 0x%lx"
+
+#: coffgen.c:1595
+msgid "%B: bad string table size %lu"
+msgstr "%B: неправильный размер таблицы Ñтрок %lu"
+
+#: coffgen.c:2500 elflink.c:12689 linker.c:3122
+msgid "%F%P: already_linked_table: %E\n"
+msgstr "%F%P: already_linked_table: %E\n"
+
+#: cofflink.c:533 elflink.c:4323
+msgid "Warning: type of symbol `%s' changed from %d to %d in %B"
+msgstr "Предупреждение: в %B изменён тип Ñимвола «%s» Ñ %d на %d"
+
+#: cofflink.c:2329
+msgid "%B: relocs in section `%A', but it has no contents"
+msgstr "%B: Ð¿ÐµÑ€ÐµÐ¼ÐµÑ‰ÐµÐ½Ð¸Ñ Ð² разделе «%A», но он не имеет Ñодержимого"
+
+#: cofflink.c:2391 elflink.c:9545
+msgid "%X`%s' referenced in section `%A' of %B: defined in discarded section `%A' of %B\n"
+msgstr "%X«%s» указывает в раздел «%A» из %B: определён в отброшенном разделе «%A» из %B\n"
+
+#: cofflink.c:2690 coffswap.h:826
+#, c-format
+msgid "%s: %s: reloc overflow: 0x%lx > 0xffff"
+msgstr "%s: %s: переполнение перемещениÑ: 0x%lx > 0xffff"
+
+#: cofflink.c:2699 coffswap.h:812
+#, c-format
+msgid "%s: warning: %s: line number overflow: 0x%lx > 0xffff"
+msgstr "%s: предупреждение: %s: переполнение номера Ñтроки: 0x%lx > 0xffff"
+
+#: cpu-arm.c:189 cpu-arm.c:200
+msgid "error: %B is compiled for the EP9312, whereas %B is compiled for XScale"
+msgstr "ошибка: %B Ñкомпилирован Ð´Ð»Ñ EP9312, в то Ð²Ñ€ÐµÐ¼Ñ ÐºÐ°Ðº %B Ñкомпилирован Ð´Ð»Ñ XScale"
+
+#: cpu-arm.c:333
+#, c-format
+msgid "warning: unable to update contents of %s section in %s"
+msgstr "предупреждение: не удалоÑÑŒ обновить Ñодержимое раздела %s в %s"
+
+#: dwarf2.c:496
+#, c-format
+msgid "Dwarf Error: Can't find %s section."
+msgstr "Ошибка в dwarf: Раздел %s не найден."
+
+#: dwarf2.c:525
+#, c-format
+msgid "Dwarf Error: Offset (%lu) greater than or equal to %s size (%lu)."
+msgstr "Ошибка в dwarf: Смещение (%lu) больше или равно размеру %s (%lu)."
+
+#: dwarf2.c:949
+#, c-format
+msgid "Dwarf Error: Invalid or unhandled FORM value: %u."
+msgstr "Ошибка в dwarf: ÐедопуÑтимое или необработанное значение FORM: %u."
+
+#: dwarf2.c:1200
+msgid "Dwarf Error: mangled line number section (bad file number)."
+msgstr "Ошибка в dwarf: иÑкажённый раздел номеров Ñтрок (неверный номер файла)."
+
+#: dwarf2.c:1453
+#, c-format
+msgid "Dwarf Error: Unhandled .debug_line version %d."
+msgstr "Ошибка в dwarf: Ð½ÐµÐ¾Ð±Ñ€Ð°Ð±Ð¾Ñ‚Ð°Ð½Ð½Ð°Ñ Ð²ÐµÑ€ÑÐ¸Ñ %d у .debug_line."
+
+#: dwarf2.c:1475
+msgid "Dwarf Error: Invalid maximum operations per instruction."
+msgstr "Ошибка в dwarf: неверное макÑимальное количеÑтво операций на инÑтрукцию."
+
+#: dwarf2.c:1662
+msgid "Dwarf Error: mangled line number section."
+msgstr "Ошибка в dwarf: иÑкажённый раздел номеров Ñтрок."
+
+#: dwarf2.c:1989 dwarf2.c:2109 dwarf2.c:2394
+#, c-format
+msgid "Dwarf Error: Could not find abbrev number %u."
+msgstr "Ошибка в dwarf: Ðевозможно найти укороченный номер %u."
+
+#: dwarf2.c:2355
+#, c-format
+msgid "Dwarf Error: found dwarf version '%u', this reader only handles version 2, 3 and 4 information."
+msgstr "Ошибка в dwarf: найдена верÑÐ¸Ñ dwarf «%u», Ñ‚ÐµÐºÑƒÑ‰Ð°Ñ Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ Ñ‡Ñ‚ÐµÐ½Ð¸Ñ Ð¿Ð¾Ð½Ð¸Ð¼Ð°ÐµÑ‚ только верÑии 2, 3 и 4."
+
+#: dwarf2.c:2362
+#, c-format
+msgid "Dwarf Error: found address size '%u', this reader can not handle sizes greater than '%u'."
+msgstr "Ошибка в dwarf: найден размер адреÑа «%u», Ñ‚ÐµÐºÑƒÑ‰Ð°Ñ Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ Ñ‡Ñ‚ÐµÐ½Ð¸Ñ Ð½Ðµ умеет работать Ñ Ñ€Ð°Ð·Ð¼ÐµÑ€Ð°Ð¼Ð¸ более чем «%u»."
+
+#: dwarf2.c:2385
+#, c-format
+msgid "Dwarf Error: Bad abbrev number: %u."
+msgstr "Ошибка в dwarf: Ðеверный укороченный номер: %u."
+
+#: ecoff.c:1239
+#, c-format
+msgid "Unknown basic type %d"
+msgstr "ÐеизвеÑтный начальный тип %d"
+
+#: ecoff.c:1496
+#, c-format
+msgid ""
+"\n"
+" End+1 symbol: %ld"
+msgstr ""
+"\n"
+" Символ End+1: %ld"
+
+#: ecoff.c:1503 ecoff.c:1506
+#, c-format
+msgid ""
+"\n"
+" First symbol: %ld"
+msgstr ""
+"\n"
+" Первый Ñимвол: %ld"
+
+#: ecoff.c:1518
+#, c-format
+msgid ""
+"\n"
+" End+1 symbol: %-7ld Type: %s"
+msgstr ""
+"\n"
+" Символ End+1: %-7ld Тип: %s"
+
+#: ecoff.c:1525
+#, c-format
+msgid ""
+"\n"
+" Local symbol: %ld"
+msgstr ""
+"\n"
+" Локальный Ñимвол: %ld"
+
+#: ecoff.c:1533
+#, c-format
+msgid ""
+"\n"
+" struct; End+1 symbol: %ld"
+msgstr ""
+"\n"
+" struct; Ñимвол End+1: %ld"
+
+#: ecoff.c:1538
+#, c-format
+msgid ""
+"\n"
+" union; End+1 symbol: %ld"
+msgstr ""
+"\n"
+" union; Ñимвол End+1: %ld"
+
+#: ecoff.c:1543
+#, c-format
+msgid ""
+"\n"
+" enum; End+1 symbol: %ld"
+msgstr ""
+"\n"
+" enum; Ñимвол End+1: %ld"
+
+#: ecoff.c:1549
+#, c-format
+msgid ""
+"\n"
+" Type: %s"
+msgstr ""
+"\n"
+" Тип: %s"
+
+#: elf-attrs.c:569
+msgid "error: %B: Object has vendor-specific contents that must be processed by the '%s' toolchain"
+msgstr "ошибка: %B: объект Ñодержит Ñпециальное Ñодержимое производителÑ, которое должно обрабатыватьÑÑ Ð¸Ð½Ñтрументами Ñборки «%s»"
+
+#: elf-attrs.c:578
+msgid "error: %B: Object tag '%d, %s' is incompatible with tag '%d, %s'"
+msgstr "error: %B: Объектный тег «%d, %s» неÑовмеÑтим Ñ Ñ‚ÐµÐ³Ð¾Ð¼ «%d, %s»"
+
+#: elf-eh-frame.c:917
+msgid "%P: error in %B(%A); no .eh_frame_hdr table will be created.\n"
+msgstr "%P: ошибка в %B(%A); таблиц .eh_frame_hdr Ñоздана не будет.\n"
+
+#: elf-eh-frame.c:1189
+msgid "%P: fde encoding in %B(%A) prevents .eh_frame_hdr table being created.\n"
+msgstr "%P: из-за кодировки fde в %B(%A) таблица .eh_frame_hdr Ñоздана не будет.\n"
+
+#: elf-eh-frame.c:1605
+msgid "%P: DW_EH_PE_datarel unspecified for this architecture.\n"
+msgstr "%P: DW_EH_PE_datarel не определена Ð´Ð»Ñ Ñтой архитектуры.\n"
+
+#: elf-ifunc.c:179
+msgid "%F%P: dynamic STT_GNU_IFUNC symbol `%s' with pointer equality in `%B' can not be used when making an executable; recompile with -fPIE and relink with -pie\n"
+msgstr "%F%P: динамичеÑкий STT_GNU_IFUNC Ñимвол «%s» Ñ Ð¾Ð´Ð¸Ð½Ð°ÐºÐ¾Ð²Ñ‹Ð¼ указателем в «%B» Ð½ÐµÐ»ÑŒÐ·Ñ Ð¸Ñпользовать при Ñоздании иÑполнÑемого файла; перекомпилируйте Ñ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ð¾Ð¼ -fPIE и перекомпонуйте Ñ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ð¾Ð¼ -pie\n"
+
+#: elf-m10200.c:450 elf-m10300.c:1563 elf32-avr.c:1221 elf32-bfin.c:3213
+#: elf32-cr16.c:1482 elf32-cr16c.c:780 elf32-cris.c:2081 elf32-crx.c:922
+#: elf32-d10v.c:509 elf32-epiphany.c:556 elf32-fr30.c:609 elf32-frv.c:4105
+#: elf32-h8300.c:509 elf32-i860.c:1211 elf32-ip2k.c:1468 elf32-iq2000.c:684
+#: elf32-lm32.c:1168 elf32-m32c.c:553 elf32-m32r.c:3106 elf32-m68hc1x.c:1138
+#: elf32-mep.c:535 elf32-microblaze.c:1231 elf32-moxie.c:282
+#: elf32-msp430.c:486 elf32-mt.c:395 elf32-openrisc.c:404 elf32-score.c:2729
+#: elf32-score7.c:2537 elf32-spu.c:5044 elf32-tilepro.c:3214 elf32-v850.c:2143
+#: elf32-xstormy16.c:935 elf64-mmix.c:1590 elfxx-tilegx.c:3577
+msgid "internal error: out of range error"
+msgstr "внутреннÑÑ Ð¾ÑˆÐ¸Ð±ÐºÐ°: ошибка выхода из диапазона"
+
+#: elf-m10200.c:454 elf-m10300.c:1567 elf32-avr.c:1225 elf32-bfin.c:3217
+#: elf32-cr16.c:1486 elf32-cr16c.c:784 elf32-cris.c:2085 elf32-crx.c:926
+#: elf32-d10v.c:513 elf32-fr30.c:613 elf32-frv.c:4109 elf32-h8300.c:513
+#: elf32-i860.c:1215 elf32-iq2000.c:688 elf32-lm32.c:1172 elf32-m32c.c:557
+#: elf32-m32r.c:3110 elf32-m68hc1x.c:1142 elf32-mep.c:539
+#: elf32-microblaze.c:1235 elf32-moxie.c:286 elf32-msp430.c:490
+#: elf32-openrisc.c:408 elf32-score.c:2733 elf32-score7.c:2541
+#: elf32-spu.c:5048 elf32-tilepro.c:3218 elf32-v850.c:2147
+#: elf32-xstormy16.c:939 elf64-mmix.c:1594 elfxx-mips.c:9465
+#: elfxx-tilegx.c:3581
+msgid "internal error: unsupported relocation error"
+msgstr "внутреннÑÑ Ð¾ÑˆÐ¸Ð±ÐºÐ°: ошибка неподдерживаемого перемещениÑ"
+
+#: elf-m10200.c:458 elf32-cr16.c:1490 elf32-cr16c.c:788 elf32-crx.c:930
+#: elf32-d10v.c:517 elf32-h8300.c:517 elf32-lm32.c:1176 elf32-m32r.c:3114
+#: elf32-m68hc1x.c:1146 elf32-microblaze.c:1239 elf32-score.c:2737
+#: elf32-score7.c:2545 elf32-spu.c:5052
+msgid "internal error: dangerous error"
+msgstr "внутреннÑÑ Ð¾ÑˆÐ¸Ð±ÐºÐ°: ошибка риÑка"
+
+#: elf-m10200.c:462 elf-m10300.c:1580 elf32-avr.c:1233 elf32-bfin.c:3225
+#: elf32-cr16.c:1494 elf32-cr16c.c:792 elf32-cris.c:2093 elf32-crx.c:934
+#: elf32-d10v.c:521 elf32-epiphany.c:571 elf32-fr30.c:621 elf32-frv.c:4117
+#: elf32-h8300.c:521 elf32-i860.c:1223 elf32-ip2k.c:1483 elf32-iq2000.c:696
+#: elf32-lm32.c:1180 elf32-m32c.c:565 elf32-m32r.c:3118 elf32-m68hc1x.c:1150
+#: elf32-mep.c:547 elf32-microblaze.c:1243 elf32-moxie.c:294
+#: elf32-msp430.c:498 elf32-mt.c:403 elf32-openrisc.c:416 elf32-score.c:2746
+#: elf32-score7.c:2549 elf32-spu.c:5056 elf32-tilepro.c:3226 elf32-v850.c:2167
+#: elf32-xstormy16.c:947 elf64-mmix.c:1602 elfxx-tilegx.c:3589
+msgid "internal error: unknown error"
+msgstr "внутреннÑÑ Ð¾ÑˆÐ¸Ð±ÐºÐ°: неизвеÑÑ‚Ð½Ð°Ñ Ð¾ÑˆÐ¸Ð±ÐºÐ°"
+
+#: elf-m10300.c:1507 elf32-arm.c:10419 elf32-i386.c:4264 elf32-m32r.c:2599
+#: elf32-m68k.c:4156 elf32-s390.c:3003 elf32-sh.c:4218 elf32-tilepro.c:3117
+#: elf32-xtensa.c:3066 elf64-s390.c:2978 elf64-sh64.c:1640 elf64-x86-64.c:4110
+#: elfxx-sparc.c:3835 elfxx-tilegx.c:3500
+msgid "%B(%A+0x%lx): unresolvable %s relocation against symbol `%s'"
+msgstr "%B(%A+0x%lx): неразрешимое перемещение %s отноÑительно Ñимвола «%s»"
+
+#: elf-m10300.c:1572
+msgid "error: inappropriate relocation type for shared library (did you forget -fpic?)"
+msgstr "ошибка: неподходÑщий тип Ð¿ÐµÑ€ÐµÐ¼ÐµÑ‰ÐµÐ½Ð¸Ñ Ð´Ð»Ñ Ð¾Ð±Ñ‰ÐµÐ¹ библиотеки (не указан -fpic?)"
+
+#: elf-m10300.c:1575
+msgid "internal error: suspicious relocation type used in shared library"
+msgstr "внутреннÑÑ Ð¾ÑˆÐ¸Ð±ÐºÐ°: подозрительный тип Ð¿ÐµÑ€ÐµÐ¼ÐµÑ‰ÐµÐ½Ð¸Ñ Ð² общей библиотеке"
+
+#: elf-m10300.c:4372 elf32-arm.c:12800 elf32-cr16.c:2451 elf32-cris.c:3057
+#: elf32-hppa.c:1894 elf32-i370.c:503 elf32-i386.c:2182 elf32-lm32.c:1868
+#: elf32-m32r.c:1927 elf32-m68k.c:3253 elf32-s390.c:1652 elf32-sh.c:2931
+#: elf32-tic6x.c:2162 elf32-tilepro.c:1940 elf32-vax.c:1041 elf64-s390.c:1635
+#: elf64-sh64.c:3381 elf64-x86-64.c:2176 elfxx-sparc.c:2119
+#: elfxx-tilegx.c:2261
+#, c-format
+msgid "dynamic variable `%s' is zero size"
+msgstr "динамичеÑÐºÐ°Ñ Ð¿ÐµÑ€ÐµÐ¼ÐµÐ½Ð½Ð°Ñ Â«%s» имеет нулевой размер"
+
+#: elf.c:334
+msgid "%B: invalid string offset %u >= %lu for section `%s'"
+msgstr "%B: недопуÑтимое Ñмещение Ñтроки %u >= %lu Ð´Ð»Ñ Ñ€Ð°Ð·Ð´ÐµÐ»Ð° «%s»"
+
+#: elf.c:446
+msgid "%B symbol number %lu references nonexistent SHT_SYMTAB_SHNDX section"
+msgstr "%B Ñимвольный номер %lu ÑÑылаетÑÑ Ð½Ð° неÑущеÑтвующий раздел SHT_SYMTAB_SHNDX"
+
+#: elf.c:602
+msgid "%B: Corrupt size field in group section header: 0x%lx"
+msgstr "%B: Повреждённое поле размера в заголовке раздела групп: 0x%lx"
+
+#: elf.c:638
+msgid "%B: invalid SHT_GROUP entry"
+msgstr "%B: недопуÑтимый Ñлемент SHT_GROUP"
+
+#: elf.c:708
+msgid "%B: no group info for section %A"
+msgstr "%B: нет информации о группе Ð´Ð»Ñ Ñ€Ð°Ð·Ð´ÐµÐ»Ð° %A"
+
+#: elf.c:737 elf.c:3121 elflink.c:10135
+msgid "%B: warning: sh_link not set for section `%A'"
+msgstr "%B: предупреждение: не задан sh_link Ð´Ð»Ñ Ñ€Ð°Ð·Ð´ÐµÐ»Ð° «%A»"
+
+#: elf.c:756
+msgid "%B: sh_link [%d] in section `%A' is incorrect"
+msgstr "%B: некорректный sh_link [%d] в разделе «%A»"
+
+#: elf.c:791
+msgid "%B: unknown [%d] section `%s' in group [%s]"
+msgstr "%B: неизвеÑтный [%d] раздел «%s» в группе [%s]"
+
+#: elf.c:1041
+msgid "%B: unable to initialize commpress status for section %s"
+msgstr "%B: не удалоÑÑŒ инициализировать ÑоÑтоÑние ÑÐ¶Ð°Ñ‚Ð¸Ñ Ñ€Ð°Ð·Ð´ÐµÐ»Ð° %s"
+
+#: elf.c:1061
+msgid "%B: unable to initialize decommpress status for section %s"
+msgstr "%B: не удалоÑÑŒ инициализировать ÑоÑтоÑние Ñ€Ð°Ð·Ð¶Ð°Ñ‚Ð¸Ñ Ñ€Ð°Ð·Ð´ÐµÐ»Ð° %s"
+
+#: elf.c:1181
+#, c-format
+msgid ""
+"\n"
+"Program Header:\n"
+msgstr ""
+"\n"
+"Заголовок программы:\n"
+
+#: elf.c:1223
+#, c-format
+msgid ""
+"\n"
+"Dynamic Section:\n"
+msgstr ""
+"\n"
+"ДинамичеÑкий раздел:\n"
+
+#: elf.c:1359
+#, c-format
+msgid ""
+"\n"
+"Version definitions:\n"
+msgstr ""
+"\n"
+"ОбъÑÐ²Ð»ÐµÐ½Ð¸Ñ Ð²ÐµÑ€Ñий:\n"
+
+#: elf.c:1384
+#, c-format
+msgid ""
+"\n"
+"Version References:\n"
+msgstr ""
+"\n"
+"ВерÑии ÑÑылок:\n"
+
+#: elf.c:1389
+#, c-format
+msgid " required from %s:\n"
+msgstr " требуетÑÑ Ð¸Ð· %s:\n"
+
+#: elf.c:1796
+msgid "%B: invalid link %lu for reloc section %s (index %u)"
+msgstr "%B: недопуÑÑ‚Ð¸Ð¼Ð°Ñ ÑÑылка %lu Ð´Ð»Ñ Ñ€Ð°Ð·Ð´ÐµÐ»Ð° перемещений %s (Ð¸Ð½Ð´ÐµÐºÑ %u)"
+
+#: elf.c:1966
+msgid "%B: don't know how to handle allocated, application specific section `%s' [0x%8x]"
+msgstr "%B: неизвеÑтно как обработать размещённый, Ñпециальный раздел Ð¿Ñ€Ð¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Â«%s» [0x%8x]"
+
+#: elf.c:1978
+msgid "%B: don't know how to handle processor specific section `%s' [0x%8x]"
+msgstr "%B: неизвеÑтно как обработать Ñпециальный раздел процеÑÑора «%s» [0x%8x]"
+
+#: elf.c:1989
+msgid "%B: don't know how to handle OS specific section `%s' [0x%8x]"
+msgstr "%B: неизвеÑтно как обработать Ñпециальный раздел ОС «%s» [0x%8x]"
+
+#: elf.c:1999
+msgid "%B: don't know how to handle section `%s' [0x%8x]"
+msgstr "%B: неизвеÑтно как обработать раздел «%s» [0x%8x]"
+
+#: elf.c:2634
+#, c-format
+msgid "warning: section `%A' type changed to PROGBITS"
+msgstr "предупреждение: тип раздела «%A» изменён на PROGBITS"
+
+#: elf.c:3078
+msgid "%B: sh_link of section `%A' points to discarded section `%A' of `%B'"
+msgstr "%B: sh_link раздела «%A» указывает на отброшенный раздел «%A» из «%B»"
+
+#: elf.c:3101
+msgid "%B: sh_link of section `%A' points to removed section `%A' of `%B'"
+msgstr "%B: sh_link раздела «%A» указывает на удалённый раздел «%A» из «%B»"
+
+#: elf.c:4527
+msgid "%B: The first section in the PT_DYNAMIC segment is not the .dynamic section"
+msgstr "%B: Первый раздел в Ñегменте PT_DYNAMIC не ÑвлÑетÑÑ Ñ€Ð°Ð·Ð´ÐµÐ»Ð¾Ð¼ .dynamic"
+
+#: elf.c:4554
+msgid "%B: Not enough room for program headers, try linking with -N"
+msgstr "%B: ÐедоÑтаточно меÑта Ð´Ð»Ñ Ð·Ð°Ð³Ð¾Ð»Ð¾Ð²ÐºÐ¾Ð² программы, попытайтеÑÑŒ Ñкомпоновать Ñ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ð¾Ð¼ -N"
+
+#: elf.c:4641
+msgid "%B: section %A lma %#lx adjusted to %#lx"
+msgstr "%B: lma %#lx раздела %A подогнано к %#lx"
+
+#: elf.c:4776
+msgid "%B: section `%A' can't be allocated in segment %d"
+msgstr "%B: раздел «%A» не может быть раÑпределён в Ñегмент %d"
+
+#: elf.c:4824
+msgid "%B: warning: allocated section `%s' not in segment"
+msgstr "%B: предупреждение: раÑпределённый раздел «%s» не в Ñегменте"
+
+#: elf.c:5324
+msgid "%B: symbol `%s' required but not present"
+msgstr "%B: требуетÑÑ Ñимвол «%s», но он отÑутÑтвует"
+
+#: elf.c:5662
+msgid "%B: warning: Empty loadable segment detected, is this intentional ?\n"
+msgstr "%B: предупреждение: Обнаружен пуÑтой загружаемый Ñегмент, Ñто так задумывалоÑÑŒ?\n"
+
+#: elf.c:6692
+#, c-format
+msgid "Unable to find equivalent output section for symbol '%s' from section '%s'"
+msgstr "Ðе удалоÑÑŒ найти подходÑщее меÑто вывода Ð´Ð»Ñ Ñимвола '%s' из раздела '%s'"
+
+#: elf.c:7692
+msgid "%B: unsupported relocation type %s"
+msgstr "%B: неподдерживаемый тип Ð¿ÐµÑ€ÐµÐ¼ÐµÑ‰ÐµÐ½Ð¸Ñ %s"
+
+#: elf32-arm.c:3617
+msgid ""
+"%B(%s): warning: interworking not enabled.\n"
+" first occurrence: %B: Thumb call to ARM"
+msgstr ""
+"%B(%s): предупреждение: ÑовмеÑÑ‚Ð½Ð°Ñ Ñ€Ð°Ð±Ð¾Ñ‚Ð° не включена.\n"
+" первое упоминание: %B: Thumb-вызов в ARM"
+
+#: elf32-arm.c:3664
+msgid ""
+"%B(%s): warning: interworking not enabled.\n"
+" first occurrence: %B: ARM call to Thumb"
+msgstr ""
+"%B(%s): предупреждение: ÑовмеÑÑ‚Ð½Ð°Ñ Ñ€Ð°Ð±Ð¾Ñ‚Ð° не включена.\n"
+" первое упоминание: %B: ARM-вызов в Thumb"
+
+#: elf32-arm.c:3878 elf32-arm.c:5315
+#, c-format
+msgid "%s: cannot create stub entry %s"
+msgstr "%s: невозможно Ñоздать Ñлемент заглушки %s"
+
+#: elf32-arm.c:5431
+#, c-format
+msgid "unable to find THUMB glue '%s' for '%s'"
+msgstr "не удалоÑÑŒ найти THUMB-Ñклейку '%s' Ð´Ð»Ñ '%s'"
+
+#: elf32-arm.c:5467
+#, c-format
+msgid "unable to find ARM glue '%s' for '%s'"
+msgstr "не удалоÑÑŒ найти ARM-Ñклейку '%s' Ð´Ð»Ñ '%s'"
+
+#: elf32-arm.c:6005
+msgid "%B: BE8 images only valid in big-endian mode."
+msgstr "%B: образы BE8 разрешены только в режиме big-endian."
+
+#. Give a warning, but do as the user requests anyway.
+#: elf32-arm.c:6235
+msgid "%B: warning: selected VFP11 erratum workaround is not necessary for target architecture"
+msgstr "%B: предупреждение: выбранный обход ошибки VFP11 не требуетÑÑ Ð´Ð»Ñ Ñ†ÐµÐ»ÐµÐ²Ð¾Ð¹ архитектуры"
+
+#: elf32-arm.c:6779 elf32-arm.c:6799
+msgid "%B: unable to find VFP11 veneer `%s'"
+msgstr "%B: невозможно найти Ñклейку VFP11 «%s»"
+
+#: elf32-arm.c:6848
+#, c-format
+msgid "Invalid TARGET2 relocation type '%s'."
+msgstr "ÐедопуÑтимый в TARGET2 тип Ð¿ÐµÑ€ÐµÐ¼ÐµÑ‰ÐµÐ½Ð¸Ñ Â«%s»."
+
+#: elf32-arm.c:6933
+msgid ""
+"%B(%s): warning: interworking not enabled.\n"
+" first occurrence: %B: thumb call to arm"
+msgstr ""
+"%B(%s): предупреждение: interworking not enabled.\n"
+" первое упоминание: %B: thumb-вызов в arm"
+
+#: elf32-arm.c:7717
+msgid "%B(%A+0x%lx):unexpected Thumb instruction '0x%x' in TLS trampoline"
+msgstr "%B(%A+0x%lx): Ð½ÐµÐ¾Ð¶Ð¸Ð´Ð°ÐµÐ¼Ð°Ñ Thumb-инÑÑ‚Ñ€ÑƒÐºÑ†Ð¸Ñ Â«0x%x» в трамплине TLS"
+
+#: elf32-arm.c:7756
+msgid "%B(%A+0x%lx):unexpected ARM instruction '0x%x' in TLS trampoline"
+msgstr "%B(%A+0x%lx): Ð½ÐµÐ¾Ð¶Ð¸Ð´Ð°ÐµÐ¼Ð°Ñ ARM-инÑÑ‚Ñ€ÑƒÐºÑ†Ð¸Ñ Â«0x%x» в трамплине TLS"
+
+#: elf32-arm.c:8209
+msgid "\\%B: Warning: Arm BLX instruction targets Arm function '%s'."
+msgstr "\\%B: Предупреждение: Arm инÑÑ‚Ñ€ÑƒÐºÑ†Ð¸Ñ BLX в функции Arm '%s'."
+
+#: elf32-arm.c:8622
+msgid "%B: Warning: Thumb BLX instruction targets thumb function '%s'."
+msgstr "\\%B: Предупреждение: Thumb инÑÑ‚Ñ€ÑƒÐºÑ†Ð¸Ñ BLX в функции thumb '%s'."
+
+#: elf32-arm.c:9460
+msgid "%B(%A+0x%lx):unexpected Thumb instruction '0x%x' referenced by TLS_GOTDESC"
+msgstr "%B(%A+0x%lx): Ð½ÐµÐ¾Ð¶Ð¸Ð´Ð°ÐµÐ¼Ð°Ñ Thumb-инÑÑ‚Ñ€ÑƒÐºÑ†Ð¸Ñ Â«0x%x», на которую ÑÑылаетÑÑ TLS_GOTDESC"
+
+#: elf32-arm.c:9483
+msgid "%B(%A+0x%lx):unexpected ARM instruction '0x%x' referenced by TLS_GOTDESC"
+msgstr "%B(%A+0x%lx): Ð½ÐµÐ¾Ð¶Ð¸Ð´Ð°ÐµÐ¼Ð°Ñ ARM-инÑÑ‚Ñ€ÑƒÐºÑ†Ð¸Ñ Â«0x%x», на которую ÑÑылаетÑÑ TLS_GOTDESC"
+
+#: elf32-arm.c:9512
+msgid "%B(%A+0x%lx): R_ARM_TLS_LE32 relocation not permitted in shared object"
+msgstr "%B(%A+0x%lx): перемещение R_ARM_TLS_LE32 не разрешено Ð´Ð»Ñ Ð¾Ð±Ñ‰ÐµÐ³Ð¾ объекта"
+
+#: elf32-arm.c:9727
+msgid "%B(%A+0x%lx): Only ADD or SUB instructions are allowed for ALU group relocations"
+msgstr "%B(%A+0x%lx): Ð’ группе перемещений ALU разрешена только инÑÑ‚Ñ€ÑƒÐºÑ†Ð¸Ñ ADD или SUB"
+
+#: elf32-arm.c:9767 elf32-arm.c:9854 elf32-arm.c:9937 elf32-arm.c:10022
+msgid "%B(%A+0x%lx): Overflow whilst splitting 0x%lx for group relocation %s"
+msgstr "%B(%A+0x%lx): Переполнение во Ð²Ñ€ÐµÐ¼Ñ Ñ€Ð°Ð·Ð´ÐµÐ»ÐµÐ½Ð¸Ñ 0x%lx Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÐ¼ÐµÑ‰ÐµÐ½Ð¸Ðµ группы %s"
+
+#: elf32-arm.c:10261 elf32-sh.c:4103 elf64-sh64.c:1544
+msgid "%B(%A+0x%lx): %s relocation against SEC_MERGE section"
+msgstr "%B(%A+0x%lx): %s перемещение в разделе SEC_MERGE"
+
+#: elf32-arm.c:10372 elf32-m68k.c:4191 elf32-xtensa.c:2802
+msgid "%B(%A+0x%lx): %s used with TLS symbol %s"
+msgstr "%B(%A+0x%lx): %s иÑпользуетÑÑ Ñ TLS-Ñимволом %s"
+
+#: elf32-arm.c:10373 elf32-m68k.c:4192 elf32-xtensa.c:2803
+msgid "%B(%A+0x%lx): %s used with non-TLS symbol %s"
+msgstr "%B(%A+0x%lx): %s иÑпользуетÑÑ Ñ Ð½Ðµ-TLS Ñимволом %s"
+
+#: elf32-arm.c:10453 elf32-tic6x.c:2753
+msgid "out of range"
+msgstr "вне диапазона"
+
+#: elf32-arm.c:10457 elf32-tic6x.c:2757
+msgid "unsupported relocation"
+msgstr "неподдерживаемое перемещение"
+
+#: elf32-arm.c:10465 elf32-tic6x.c:2765
+msgid "unknown error"
+msgstr "неизвеÑÑ‚Ð½Ð°Ñ Ð¾ÑˆÐ¸Ð±ÐºÐ°"
+
+#: elf32-arm.c:10890
+msgid "Warning: Clearing the interworking flag of %B because non-interworking code in %B has been linked with it"
+msgstr "Предупреждение: Ð¡Ð±Ñ€Ð¾Ñ Ñ„Ð»Ð°Ð³Ð° ÑовмеÑтной работы %B, как Ñ Ð½Ð¸Ð¼ был Ñкомпонован код без ÑовмеÑтной работы из %B"
+
+#: elf32-arm.c:10984
+msgid "%B: Unknown mandatory EABI object attribute %d"
+msgstr "%B: ÐеизвеÑтный обÑзательный атрибут EABI-объекта %d"
+
+#: elf32-arm.c:10992
+msgid "Warning: %B: Unknown EABI object attribute %d"
+msgstr "Предупреждение: %B: ÐеизвеÑтный атрибут EABI-объекта %d"
+
+#: elf32-arm.c:11173
+msgid "error: %B: Unknown CPU architecture"
+msgstr "ошибка: %B: ÐеизвеÑÑ‚Ð½Ð°Ñ Ð¿Ñ€Ð¾Ñ†ÐµÑÑÐ¾Ñ€Ð½Ð°Ñ Ð°Ñ€Ñ…Ð¸Ñ‚ÐµÐºÑ‚ÑƒÑ€Ð°"
+
+#: elf32-arm.c:11211
+msgid "error: %B: Conflicting CPU architectures %d/%d"
+msgstr "ошибка: %B: Противоречащие архитектурные профили %d/%d"
+
+#: elf32-arm.c:11260
+msgid "Error: %B has both the current and legacy Tag_MPextension_use attributes"
+msgstr "Ошибка: %B Ñодержит одновременно и текущий и уÑтаревший атрибут Tag_MPextension_use"
+
+#: elf32-arm.c:11285
+msgid "error: %B uses VFP register arguments, %B does not"
+msgstr "ошибка: %B иÑпользует региÑтровые аргументы VFP, а %B не иÑпользует"
+
+#: elf32-arm.c:11430
+msgid "error: %B: unable to merge virtualization attributes with %B"
+msgstr "ошибка: %B: не удалоÑÑŒ объединить атрибуты виртуализации Ñ %B"
+
+#: elf32-arm.c:11456
+msgid "error: %B: Conflicting architecture profiles %c/%c"
+msgstr "ошибка: %B: противоречащие архитектурные профили %c/%c"
+
+#: elf32-arm.c:11557
+msgid "Warning: %B: Conflicting platform configuration"
+msgstr "Предупреждение: %B: Противоречивые наÑтройки платформы"
+
+#: elf32-arm.c:11566
+msgid "error: %B: Conflicting use of R9"
+msgstr "ошибка: %B: Противоречащее иÑпользование R9"
+
+#: elf32-arm.c:11578
+msgid "error: %B: SB relative addressing conflicts with use of R9"
+msgstr "ошибка: %B: противоречащее иÑпользование отноÑительной адреÑации SB и R9"
+
+#: elf32-arm.c:11591
+msgid "warning: %B uses %u-byte wchar_t yet the output is to use %u-byte wchar_t; use of wchar_t values across objects may fail"
+msgstr "предупреждение: %B иÑпользует %u-байтовый wchar_t, Ñ…Ð¾Ñ‚Ñ ÑƒÐ¶Ðµ иÑпользовалÑÑ %u-байтовый wchar_t; иÑпользование значений wchar_t в разных объектах может привеÑти к ошибке"
+
+#: elf32-arm.c:11622
+msgid "warning: %B uses %s enums yet the output is to use %s enums; use of enum values across objects may fail"
+msgstr "предупреждение: %B иÑпользует %s enum, Ñ…Ð¾Ñ‚Ñ ÑƒÐ¶Ðµ иÑпользовалÑÑ %s enum; иÑпользование значений enum в разных объектах может привеÑти к ошибке"
+
+#: elf32-arm.c:11634
+msgid "error: %B uses iWMMXt register arguments, %B does not"
+msgstr "ошибка: %B иÑпользует региÑтровые аргументы iWMMXt, а %B не иÑпользует"
+
+#: elf32-arm.c:11651
+msgid "error: fp16 format mismatch between %B and %B"
+msgstr "ошибка: формат fp16 раÑходитÑÑ Ð² %B и %B"
+
+#: elf32-arm.c:11675
+msgid "DIV usage mismatch between %B and %B"
+msgstr "ИÑпользование DIV раÑходитÑÑ Ð² %B и %B"
+
+#: elf32-arm.c:11694
+msgid "%B has has both the current and legacy Tag_MPextension_use attributes"
+msgstr "%B Ñодержит одновременно и текущий и уÑтаревший атрибут Tag_MPextension_use"
+
+#. Ignore init flag - it may not be set, despite the flags field
+#. containing valid data.
+#. Ignore init flag - it may not be set, despite the flags field containing valid data.
+#: elf32-arm.c:11782 elf32-bfin.c:5079 elf32-cris.c:4169 elf32-m68hc1x.c:1282
+#: elf32-m68k.c:1236 elf32-score.c:3994 elf32-score7.c:3800 elf32-vax.c:529
+#: elfxx-mips.c:14103
+#, c-format
+msgid "private flags = %lx:"
+msgstr "ÑобÑтвенные флаги = %lx:"
+
+#: elf32-arm.c:11791
+#, c-format
+msgid " [interworking enabled]"
+msgstr " [ÑовмеÑÑ‚Ð½Ð°Ñ Ñ€Ð°Ð±Ð¾Ñ‚Ð° включена]"
+
+#: elf32-arm.c:11799
+#, c-format
+msgid " [VFP float format]"
+msgstr " [VFP формат плавающей точки]"
+
+#: elf32-arm.c:11801
+#, c-format
+msgid " [Maverick float format]"
+msgstr " [Maverick формат плавающей точки]"
+
+#: elf32-arm.c:11803
+#, c-format
+msgid " [FPA float format]"
+msgstr " [FPA формат плавающей точки]"
+
+#: elf32-arm.c:11812
+#, c-format
+msgid " [new ABI]"
+msgstr " [новый ABI]"
+
+#: elf32-arm.c:11815
+#, c-format
+msgid " [old ABI]"
+msgstr " [Ñтарый ABI]"
+
+#: elf32-arm.c:11818
+#, c-format
+msgid " [software FP]"
+msgstr " [Ð¿Ñ€Ð¾Ð³Ñ€Ð°Ð¼Ð¼Ð½Ð°Ñ FP]"
+
+#: elf32-arm.c:11827
+#, c-format
+msgid " [Version1 EABI]"
+msgstr " [ВерÑиÑ1 EABI]"
+
+#: elf32-arm.c:11830 elf32-arm.c:11841
+#, c-format
+msgid " [sorted symbol table]"
+msgstr " [отÑÐ¾Ñ€Ñ‚Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð½Ð°Ñ Ñ‚Ð°Ð±Ð»Ð¸Ñ†Ð° Ñимволов]"
+
+#: elf32-arm.c:11832 elf32-arm.c:11843
+#, c-format
+msgid " [unsorted symbol table]"
+msgstr " [неÑÐ¾Ñ€Ñ‚Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð½Ð°Ñ Ñ‚Ð°Ð±Ð»Ð¸Ñ†Ð° Ñимволов]"
+
+#: elf32-arm.c:11838
+#, c-format
+msgid " [Version2 EABI]"
+msgstr " [ВерÑиÑ2 EABI]"
+
+#: elf32-arm.c:11846
+#, c-format
+msgid " [dynamic symbols use segment index]"
+msgstr " [динамичеÑкие Ñимволы иÑпользуют Ñегментный индекÑ]"
+
+#: elf32-arm.c:11849
+#, c-format
+msgid " [mapping symbols precede others]"
+msgstr " [проецируемые Ñимволы указываютÑÑ Ñ€Ð°Ð½ÑŒÑˆÐµ]"
+
+#: elf32-arm.c:11856
+#, c-format
+msgid " [Version3 EABI]"
+msgstr " [ВерÑиÑ3 EABI]"
+
+#: elf32-arm.c:11860
+#, c-format
+msgid " [Version4 EABI]"
+msgstr " [ВерÑиÑ4 EABI]"
+
+#: elf32-arm.c:11864
+#, c-format
+msgid " [Version5 EABI]"
+msgstr " [ВерÑиÑ5 EABI]"
+
+#: elf32-arm.c:11867
+#, c-format
+msgid " [BE8]"
+msgstr " [BE8]"
+
+#: elf32-arm.c:11870
+#, c-format
+msgid " [LE8]"
+msgstr " [LE8]"
+
+#: elf32-arm.c:11876
+#, c-format
+msgid " <EABI version unrecognised>"
+msgstr " <нераÑÐ¿Ð¾Ð·Ð½Ð°Ð½Ð½Ð°Ñ Ð²ÐµÑ€ÑÐ¸Ñ EABI>"
+
+#: elf32-arm.c:11883
+#, c-format
+msgid " [relocatable executable]"
+msgstr " [перемещаемый иÑполнÑемый]"
+
+#: elf32-arm.c:11886
+#, c-format
+msgid " [has entry point]"
+msgstr " [имеет точку входа]"
+
+#: elf32-arm.c:11891
+#, c-format
+msgid "<Unrecognised flag bits set>"
+msgstr "<ÐераÑпознанный набор битов флага>"
+
+#: elf32-arm.c:12189 elf32-i386.c:1461 elf32-s390.c:1000 elf32-tic6x.c:2829
+#: elf32-tilepro.c:1336 elf32-xtensa.c:1009 elf64-s390.c:960
+#: elf64-x86-64.c:1364 elfxx-sparc.c:1371 elfxx-tilegx.c:1586
+msgid "%B: bad symbol index: %d"
+msgstr "%B: неправильный Ñимвольный индекÑ: %d"
+
+#: elf32-arm.c:12337 elf64-x86-64.c:1561 elf64-x86-64.c:1732 elfxx-mips.c:8223
+msgid "%B: relocation %s against `%s' can not be used when making a shared object; recompile with -fPIC"
+msgstr "%B: перемещение %s Ð´Ð»Ñ Â«%s» не может иÑпользоватьÑÑ Ð¿Ñ€Ð¸ Ñоздании общего объекта; перекомпилируйте Ñ -fPIC"
+
+#: elf32-arm.c:13460
+#, c-format
+msgid "Errors encountered processing file %s"
+msgstr "При обработке файла %s обнаружены ошибки"
+
+#: elf32-arm.c:14837
+msgid "%B: error: Cortex-A8 erratum stub is allocated in unsafe location"
+msgstr "%B: ошибка: заглушка Ð´Ð»Ñ Ð¾ÑˆÐ¸Ð±ÐºÐ¸ Cortex-A8 раÑположена в небезопаÑном меÑте"
+
+#. There's not much we can do apart from complain if this
+#. happens.
+#: elf32-arm.c:14864
+msgid "%B: error: Cortex-A8 erratum stub out of range (input file too large)"
+msgstr "%B: ошибка: заглушка Ð´Ð»Ñ Ð¾ÑˆÐ¸Ð±ÐºÐ¸ Cortex-A8 находитÑÑ Ð²Ð½Ðµ диапазона (Ñлишком большой входной файл)"
+
+#: elf32-arm.c:14958 elf32-arm.c:14980
+msgid "%B: error: VFP11 veneer out of range"
+msgstr "%B: ошибка: Ñклейка VFP11 вне диапазона"
+
+#: elf32-arm.c:15518
+msgid "error: %B is already in final BE8 format"
+msgstr "ошибка: %B уже в конечном формате BE8"
+
+#: elf32-arm.c:15594
+msgid "error: Source object %B has EABI version %d, but target %B has EABI version %d"
+msgstr "ошибка: Объект-иÑточник %B имеет верÑию EABI %d, а цель %B имеет верÑию EABI %d"
+
+#: elf32-arm.c:15610
+msgid "error: %B is compiled for APCS-%d, whereas target %B uses APCS-%d"
+msgstr "ошибка: %B Ñкомпилирован Ð´Ð»Ñ APCS-%d, в то Ð²Ñ€ÐµÐ¼Ñ ÐºÐ°Ðº цель %B иÑпользует APCS-%d"
+
+#: elf32-arm.c:15635
+msgid "error: %B uses VFP instructions, whereas %B does not"
+msgstr "ошибка: %B иÑпользует инÑтрукции VFP, в то Ð²Ñ€ÐµÐ¼Ñ ÐºÐ°Ðº %B не иÑпользует"
+
+#: elf32-arm.c:15639
+msgid "error: %B uses FPA instructions, whereas %B does not"
+msgstr "ошибка: %B иÑпользует инÑтрукции FPA, в то Ð²Ñ€ÐµÐ¼Ñ ÐºÐ°Ðº %B не иÑпользует"
+
+#: elf32-arm.c:15649
+msgid "error: %B uses Maverick instructions, whereas %B does not"
+msgstr "ошибка: %B иÑпользует инÑтрукции Maverick, в то Ð²Ñ€ÐµÐ¼Ñ ÐºÐ°Ðº %B не иÑпользует"
+
+#: elf32-arm.c:15653
+msgid "error: %B does not use Maverick instructions, whereas %B does"
+msgstr "ошибка: %B не иÑпользует инÑтрукции Maverick, в то Ð²Ñ€ÐµÐ¼Ñ ÐºÐ°Ðº %B иÑпользует"
+
+#: elf32-arm.c:15672
+msgid "error: %B uses software FP, whereas %B uses hardware FP"
+msgstr "ошибка: %B иÑпользует программную FP, в то Ð²Ñ€ÐµÐ¼Ñ ÐºÐ°Ðº %B иÑпользует аппаратную FP"
+
+#: elf32-arm.c:15676
+msgid "error: %B uses hardware FP, whereas %B uses software FP"
+msgstr "ошибка: %B иÑпользует аппаратную FP, в то Ð²Ñ€ÐµÐ¼Ñ ÐºÐ°Ðº %B иÑпользует программную FP"
+
+#: elf32-avr.c:1229 elf32-bfin.c:3221 elf32-cris.c:2089 elf32-epiphany.c:567
+#: elf32-fr30.c:617 elf32-frv.c:4113 elf32-i860.c:1219 elf32-ip2k.c:1479
+#: elf32-iq2000.c:692 elf32-m32c.c:561 elf32-mep.c:543 elf32-moxie.c:290
+#: elf32-msp430.c:494 elf32-mt.c:399 elf32-openrisc.c:412 elf32-tilepro.c:3222
+#: elf32-v850.c:2151 elf32-xstormy16.c:943 elf64-mmix.c:1598
+#: elfxx-tilegx.c:3585
+msgid "internal error: dangerous relocation"
+msgstr "внутреннÑÑ Ð¾ÑˆÐ¸Ð±ÐºÐ°: опаÑное перемещение"
+
+#: elf32-avr.c:2415 elf32-hppa.c:598 elf32-m68hc1x.c:166
+msgid "%B: cannot create stub entry %s"
+msgstr "%B: невозможно Ñоздать Ñлемент заглушки %s"
+
+#: elf32-bfin.c:107 elf32-bfin.c:363
+msgid "relocation should be even number"
+msgstr "значение Ð¿ÐµÑ€ÐµÐ¼ÐµÑ‰ÐµÐ½Ð¸Ñ Ð´Ð¾Ð»Ð¶Ð½Ð¾ быть чётным чиÑлом"
+
+#: elf32-bfin.c:1593
+msgid "%B(%A+0x%lx): unresolvable relocation against symbol `%s'"
+msgstr "%B(%A+0x%lx): неразрешимое перемещение отноÑительно Ñимвола «%s»"
+
+#: elf32-bfin.c:1626 elf32-i386.c:4307 elf32-m68k.c:4233 elf32-s390.c:3055
+#: elf64-s390.c:3030 elf64-x86-64.c:4151
+msgid "%B(%A+0x%lx): reloc against `%s': error %d"
+msgstr "%B(%A+0x%lx): перемещение к «%s»: ошибка %d"
+
+#: elf32-bfin.c:2725
+msgid "%B: relocation at `%A+0x%x' references symbol `%s' with nonzero addend"
+msgstr "%B: перемещение «%A+0x%x» ÑÑылаетÑÑ Ð½Ð° Ñимвол «%s» Ñ Ð½ÐµÐ½ÑƒÐ»ÐµÐ²Ñ‹Ð¼ добавлением"
+
+#: elf32-bfin.c:2741
+msgid "relocation references symbol not defined in the module"
+msgstr "перемещение указывает на неопределённый Ñимвол в модуле"
+
+#: elf32-bfin.c:2838
+msgid "R_BFIN_FUNCDESC references dynamic symbol with nonzero addend"
+msgstr "R_BFIN_FUNCDESC указывает на динамичеÑкий Ñимвол Ñ Ð½ÐµÐ½ÑƒÐ»ÐµÐ²Ñ‹Ð¼ добавлением"
+
+#: elf32-bfin.c:2879 elf32-bfin.c:3002
+msgid "cannot emit fixups in read-only section"
+msgstr "невозможно Ñгенерировать меÑÑ‚Ð¾Ð¿Ð¾Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ð² разделе только Ð´Ð»Ñ Ñ‡Ñ‚ÐµÐ½Ð¸Ñ"
+
+#: elf32-bfin.c:2910 elf32-bfin.c:3040 elf32-lm32.c:1103 elf32-sh.c:5016
+msgid "cannot emit dynamic relocations in read-only section"
+msgstr "невозможно Ñгенерировать динамичеÑкие Ð¿ÐµÑ€ÐµÐ¼ÐµÑ‰ÐµÐ½Ð¸Ñ Ð² разделе только Ð´Ð»Ñ Ñ‡Ñ‚ÐµÐ½Ð¸Ñ"
+
+#: elf32-bfin.c:2960
+msgid "R_BFIN_FUNCDESC_VALUE references dynamic symbol with nonzero addend"
+msgstr "R_BFIN_FUNCDESC_VALUE указывает на динамичеÑкий Ñимвол Ñ Ð½ÐµÐ½ÑƒÐ»ÐµÐ²Ñ‹Ð¼ добавлением"
+
+#: elf32-bfin.c:3125
+msgid "relocations between different segments are not supported"
+msgstr "Ð¿ÐµÑ€ÐµÐ¼ÐµÑ‰ÐµÐ½Ð¸Ñ Ð¼ÐµÐ¶Ð´Ñƒ различными Ñегментами не поддерживаютÑÑ"
+
+#: elf32-bfin.c:3126
+msgid "warning: relocation references a different segment"
+msgstr "предупреждение: перемещение ÑÑылаетÑÑ Ð½Ð° другой Ñегмент"
+
+#: elf32-bfin.c:4971
+msgid "%B: unsupported relocation type %i"
+msgstr "%B: неподдерживаемый тип Ð¿ÐµÑ€ÐµÐ¼ÐµÑ‰ÐµÐ½Ð¸Ñ %i"
+
+#: elf32-bfin.c:5125 elf32-frv.c:6808
+#, c-format
+msgid "%s: cannot link non-fdpic object file into fdpic executable"
+msgstr "%s: невозможно Ñкомпоновать не-fdpic объектный файл в иÑполнÑемый fdpic"
+
+#: elf32-bfin.c:5129 elf32-frv.c:6812
+#, c-format
+msgid "%s: cannot link fdpic object file into non-fdpic executable"
+msgstr "%s: невозможно Ñкомпоновать fdpic объектный файл в иÑполнÑемый не-fdpic"
+
+#: elf32-bfin.c:5283
+#, c-format
+msgid "*** check this relocation %s"
+msgstr "*** проверьте Ñто перемещение %s"
+
+#: elf32-cris.c:1176
+msgid "%B, section %A: unresolvable relocation %s against symbol `%s'"
+msgstr "%B, раздел %A: неразрешимое перемещение %s у Ñимвола «%s»"
+
+#: elf32-cris.c:1238
+msgid "%B, section %A: No PLT nor GOT for relocation %s against symbol `%s'"
+msgstr "%B, раздел %A: Ðет ни PLT ни GOT Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÐ¼ÐµÑ‰ÐµÐ½Ð¸Ñ %s у Ñимвола «%s»"
+
+#: elf32-cris.c:1240
+msgid "%B, section %A: No PLT for relocation %s against symbol `%s'"
+msgstr "%B, раздел %A: Ðет PLT Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÐ¼ÐµÑ‰ÐµÐ½Ð¸Ñ %s у Ñимвола «%s»"
+
+#: elf32-cris.c:1246 elf32-cris.c:1379 elf32-cris.c:1639 elf32-cris.c:1722
+#: elf32-cris.c:1875 elf32-tic6x.c:2662
+msgid "[whose name is lost]"
+msgstr "[чьё Ð¸Ð¼Ñ Ð¿Ð¾Ñ‚ÐµÑ€Ñно]"
+
+#: elf32-cris.c:1365 elf32-tic6x.c:2647
+msgid "%B, section %A: relocation %s with non-zero addend %d against local symbol"
+msgstr "%B, раздел %A: перемещение %s Ñ Ð½ÐµÐ½ÑƒÐ»ÐµÐ²Ñ‹Ð¼ добавлением %d у локального Ñимвола"
+
+#: elf32-cris.c:1373 elf32-cris.c:1716 elf32-cris.c:1869 elf32-tic6x.c:2655
+msgid "%B, section %A: relocation %s with non-zero addend %d against symbol `%s'"
+msgstr "%B, раздел %A: перемещение %s Ñ Ð½ÐµÐ½ÑƒÐ»ÐµÐ²Ñ‹Ð¼ добавлением %d у Ñимвола «%s»"
+
+#: elf32-cris.c:1399
+msgid "%B, section %A: relocation %s is not allowed for global symbol: `%s'"
+msgstr "%B, раздел %A: перемещение %s не разрешено Ð´Ð»Ñ Ð³Ð»Ð¾Ð±Ð°Ð»ÑŒÐ½Ð¾Ð³Ð¾ Ñимвола: «%s»"
+
+#: elf32-cris.c:1415
+msgid "%B, section %A: relocation %s with no GOT created"
+msgstr "%B, раздел %A: перемещение %s без Ñозданного GOT"
+
+#. We shouldn't get here for GCC-emitted code.
+#: elf32-cris.c:1630
+msgid "%B, section %A: relocation %s has an undefined reference to `%s', perhaps a declaration mixup?"
+msgstr "%B, раздел %A: перемещение %s имеет неопределённую ÑÑылку на «%s»; возможно, Ñмешение объÑвлений?"
+
+#: elf32-cris.c:2002
+msgid "%B, section %A: relocation %s is not allowed for symbol: `%s' which is defined outside the program, perhaps a declaration mixup?"
+msgstr "%B, раздел %A: перемещение %s не разрешено Ð´Ð»Ñ Ñимвола: «%s», который определён вне программы; возможно, Ñмешение объÑвлений?"
+
+#: elf32-cris.c:2055
+msgid "(too many global variables for -fpic: recompile with -fPIC)"
+msgstr "(Ñлишком много глобальных переменных Ð´Ð»Ñ -fpic: перекомпилируйте Ñ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ð¾Ð¼ -fPIC)"
+
+#: elf32-cris.c:2062
+msgid "(thread-local data too big for -fpic or -msmall-tls: recompile with -fPIC or -mno-small-tls)"
+msgstr "(локальный данные нити Ñлишком велики Ð´Ð»Ñ -fpic или -msmall-tls: перекомпилируйте Ñ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ð¾Ð¼ -fPIC или -mno-small-tls)"
+
+#: elf32-cris.c:3261
+msgid ""
+"%B, section %A:\n"
+" v10/v32 compatible object %s must not contain a PIC relocation"
+msgstr ""
+"%B, раздел %A:\n"
+" v10/v32 ÑовмеÑтимый объект %s не должен Ñодержать Ð¿ÐµÑ€ÐµÐ¼ÐµÑ‰ÐµÐ½Ð¸Ñ PIC"
+
+#: elf32-cris.c:3366
+msgid ""
+"%B, section %A:\n"
+" relocation %s not valid in a shared object; typically an option mixup, recompile with -fPIC"
+msgstr ""
+"%B, раздел %A:\n"
+" перемещение %s не должно иÑпользоватьÑÑ Ð² общем объекте; возможно, Ñмешение параметров, перекомпилируйте Ñ -fPIC"
+
+#: elf32-cris.c:3580
+msgid ""
+"%B, section %A:\n"
+" relocation %s should not be used in a shared object; recompile with -fPIC"
+msgstr ""
+"%B, раздел %A:\n"
+" перемещение %s не должно иÑпользоватьÑÑ Ð² общем объекте; перекомпилируйте Ñ -fPIC"
+
+#: elf32-cris.c:4002
+msgid ""
+"%B, section `%A', to symbol `%s':\n"
+" relocation %s should not be used in a shared object; recompile with -fPIC"
+msgstr ""
+"%B, раздел «%A», к Ñимволу «%s»:\n"
+" перемещение %s не должно иÑпользоватьÑÑ Ð² общем объекте; перекомпилируйте Ñ -fPIC"
+
+#: elf32-cris.c:4118
+msgid "Unexpected machine number"
+msgstr "Ðеожидаемое машинное чиÑло"
+
+#: elf32-cris.c:4172
+#, c-format
+msgid " [symbols have a _ prefix]"
+msgstr " [Ñимволы Ñодержат Ð¿Ñ€ÐµÑ„Ð¸ÐºÑ _]"
+
+#: elf32-cris.c:4175
+#, c-format
+msgid " [v10 and v32]"
+msgstr " [v10 и v32]"
+
+#: elf32-cris.c:4178
+#, c-format
+msgid " [v32]"
+msgstr " [v32]"
+
+#: elf32-cris.c:4223
+msgid "%B: uses _-prefixed symbols, but writing file with non-prefixed symbols"
+msgstr "%B: иÑпользуютÑÑ Ñимволы Ñ Ð¿Ñ€ÐµÑ„Ð¸ÐºÑом _, но в файл запиÑываютÑÑ Ñимволы без префикÑов"
+
+#: elf32-cris.c:4224
+msgid "%B: uses non-prefixed symbols, but writing file with _-prefixed symbols"
+msgstr "%B: иÑпользуютÑÑ Ñимволы без префикÑа _, но в файл запиÑываютÑÑ Ñимволы Ñ Ð¿Ñ€ÐµÑ„Ð¸ÐºÑом _"
+
+#: elf32-cris.c:4243
+msgid "%B contains CRIS v32 code, incompatible with previous objects"
+msgstr "%B Ñодержит код CRIS v32, который не ÑовмеÑтим Ñ Ð¿Ñ€ÐµÐ´Ñ‹Ð´ÑƒÑ‰Ð¸Ð¼Ð¸ объектами"
+
+#: elf32-cris.c:4245
+msgid "%B contains non-CRIS-v32 code, incompatible with previous objects"
+msgstr "%B Ñодержит код не-CRIS v32, который не ÑовмеÑтим Ñ Ð¿Ñ€ÐµÐ´Ñ‹Ð´ÑƒÑ‰Ð¸Ð¼Ð¸ объектами"
+
+#: elf32-dlx.c:142
+#, c-format
+msgid "BFD Link Error: branch (PC rel16) to section (%s) not supported"
+msgstr "Ошибка компоновки BFD: ветвление (PC rel16) в раздел (%s) не поддерживаетÑÑ"
+
+#: elf32-dlx.c:204
+#, c-format
+msgid "BFD Link Error: jump (PC rel26) to section (%s) not supported"
+msgstr "Ошибка компоновки BFD: прыжок (PC rel26) в раздел (%s) не поддерживаетÑÑ"
+
+#. Only if it's not an unresolved symbol.
+#: elf32-epiphany.c:563 elf32-ip2k.c:1475
+msgid "unsupported relocation between data/insn address spaces"
+msgstr "неподдерживаемое перемещение между адреÑным проÑтранÑтвом данных/insn"
+
+#: elf32-frv.c:1509 elf32-frv.c:1658
+msgid "relocation requires zero addend"
+msgstr "Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÐ¼ÐµÑ‰ÐµÐ½Ð¸Ñ Ñ‚Ñ€ÐµÐ±ÑƒÐµÑ‚ÑÑ Ð½ÑƒÐ»ÐµÐ²Ð¾Ðµ добавление"
+
+#: elf32-frv.c:2888
+msgid "%H: relocation to `%s+%v' may have caused the error above\n"
+msgstr "%H: перемещение в «%s+%v» может быть вызвано предыдущей ошибкой\n"
+
+#: elf32-frv.c:2905
+msgid "%H: relocation references symbol not defined in the module\n"
+msgstr "%H: перемещение указывает на неопределённый Ñимвол в модуле\n"
+
+#: elf32-frv.c:2981
+msgid "%H: R_FRV_GETTLSOFF not applied to a call instruction\n"
+msgstr "%H: R_FRV_GETTLSOFF не применимо Ð´Ð»Ñ Ð¸Ð½Ñтрукции call\n"
+
+#: elf32-frv.c:3022
+msgid "%H: R_FRV_GOTTLSDESC12 not applied to an lddi instruction\n"
+msgstr "%H R_FRV_GOTTLSDESC12 не применимо Ð´Ð»Ñ Ð¸Ð½Ñтрукции lddi\n"
+
+#: elf32-frv.c:3093
+msgid "%H: R_FRV_GOTTLSDESCHI not applied to a sethi instruction\n"
+msgstr "%H: R_FRV_GOTTLSDESCHI не применимо Ð´Ð»Ñ Ð¸Ð½Ñтрукции sethi\n"
+
+#: elf32-frv.c:3130
+msgid "%H: R_FRV_GOTTLSDESCLO not applied to a setlo or setlos instruction\n"
+msgstr "%H: R_FRV_GOTTLSDESCLO не применимо Ð´Ð»Ñ Ð¸Ð½Ñтрукции setlo или setlos\n"
+
+#: elf32-frv.c:3177
+msgid "%H: R_FRV_TLSDESC_RELAX not applied to an ldd instruction\n"
+msgstr "%H: R_FRV_TLSDESC_RELAX не применимо Ð´Ð»Ñ Ð¸Ð½Ñтрукции ldd\n"
+
+#: elf32-frv.c:3261
+msgid "%H: R_FRV_GETTLSOFF_RELAX not applied to a calll instruction\n"
+msgstr "%H: R_FRV_GETTLSOFF_RELAX не применимо Ð´Ð»Ñ Ð¸Ð½Ñтрукции calll\n"
+
+#: elf32-frv.c:3315
+msgid "%H: R_FRV_GOTTLSOFF12 not applied to an ldi instruction\n"
+msgstr "%H: R_FRV_GOTTLSOFF12 не применимо Ð´Ð»Ñ Ð¸Ð½Ñтрукции ldi\n"
+
+#: elf32-frv.c:3345
+msgid "%H: R_FRV_GOTTLSOFFHI not applied to a sethi instruction\n"
+msgstr "%H: R_FRV_GOTTLSOFFHI не применимо Ð´Ð»Ñ Ð¸Ð½Ñтрукции sethi\n"
+
+#: elf32-frv.c:3374
+msgid "%H: R_FRV_GOTTLSOFFLO not applied to a setlo or setlos instruction\n"
+msgstr "%H: R_FRV_GOTTLSOFFLO не применимо Ð´Ð»Ñ Ð¸Ð½Ñтрукции setlo или setlos\n"
+
+#: elf32-frv.c:3404
+msgid "%H: R_FRV_TLSOFF_RELAX not applied to an ld instruction\n"
+msgstr "%H: R_FRV_TLSOFF_RELAX не применимо Ð´Ð»Ñ Ð¸Ð½Ñтрукции ld\n"
+
+#: elf32-frv.c:3449
+msgid "%H: R_FRV_TLSMOFFHI not applied to a sethi instruction\n"
+msgstr "%H: R_FRV_TLSMOFFHI не применимо Ð´Ð»Ñ Ð¸Ð½Ñтрукции sethi\n"
+
+#: elf32-frv.c:3476
+msgid "R_FRV_TLSMOFFLO not applied to a setlo or setlos instruction\n"
+msgstr "R_FRV_TLSMOFFLO не применимо Ð´Ð»Ñ Ð¸Ð½Ñтрукции setlo или setlos\n"
+
+#: elf32-frv.c:3597
+msgid "%H: R_FRV_FUNCDESC references dynamic symbol with nonzero addend\n"
+msgstr "%H: R_FRV_FUNCDESC указывает на динамичеÑкий Ñимвол Ñ Ð½ÐµÐ½ÑƒÐ»ÐµÐ²Ñ‹Ð¼ добавлением\n"
+
+#: elf32-frv.c:3638 elf32-frv.c:3760
+msgid "%H: cannot emit fixups in read-only section\n"
+msgstr "%H: невозможно Ñгенерировать меÑÑ‚Ð¾Ð¿Ð¾Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ð² разделе только Ð´Ð»Ñ Ñ‡Ñ‚ÐµÐ½Ð¸Ñ\n"
+
+#: elf32-frv.c:3669 elf32-frv.c:3803
+msgid "%H: cannot emit dynamic relocations in read-only section\n"
+msgstr "%H: невозможно Ñгенерировать динамичеÑкие Ð¿ÐµÑ€ÐµÐ¼ÐµÑ‰ÐµÐ½Ð¸Ñ Ð² разделе только Ð´Ð»Ñ Ñ‡Ñ‚ÐµÐ½Ð¸Ñ\n"
+
+#: elf32-frv.c:3718
+msgid "%H: R_FRV_FUNCDESC_VALUE references dynamic symbol with nonzero addend\n"
+msgstr "%H: R_FRV_FUNCDESC_VALUE указывает на динамичеÑкий Ñимвол Ñ Ð½ÐµÐ½ÑƒÐ»ÐµÐ²Ñ‹Ð¼ добавлением\n"
+
+#: elf32-frv.c:3974
+msgid "%H: reloc against `%s' references a different segment\n"
+msgstr "%H: перемещение указывает на ÑÑылки «%s» другого Ñегмента\n"
+
+#: elf32-frv.c:4124
+msgid "%H: reloc against `%s': %s\n"
+msgstr "%H: перемещение указывает на «%s»: %s\n"
+
+#: elf32-frv.c:6400
+msgid "%B: unsupported relocation type %i\n"
+msgstr "%B: неподдерживаемый тип Ð¿ÐµÑ€ÐµÐ¼ÐµÑ‰ÐµÐ½Ð¸Ñ %i\n"
+
+#: elf32-frv.c:6722
+#, c-format
+msgid "%s: compiled with %s and linked with modules that use non-pic relocations"
+msgstr "%s: компилируетÑÑ Ñ %s и компонуетÑÑ Ñ Ð¼Ð¾Ð´ÑƒÐ»Ñми, в которых иÑпользуютÑÑ Ð½Ðµ-pic перемещениÑ"
+
+#: elf32-frv.c:6775 elf32-iq2000.c:845 elf32-m32c.c:807
+#, c-format
+msgid "%s: compiled with %s and linked with modules compiled with %s"
+msgstr "%s: компилируетÑÑ Ñ %s и компонуетÑÑ Ñ Ð¼Ð¾Ð´ÑƒÐ»Ñми, Ñкомпилированными Ñ %s"
+
+#: elf32-frv.c:6787
+#, c-format
+msgid "%s: uses different unknown e_flags (0x%lx) fields than previous modules (0x%lx)"
+msgstr "%s: иÑпользует другие неизвеÑтные флаги e_flags (0x%lx) чем предыдущие модули (0x%lx)"
+
+#: elf32-frv.c:6837 elf32-iq2000.c:882 elf32-m32c.c:843 elf32-mt.c:576
+#: elf32-rx.c:3001
+#, c-format
+msgid "private flags = 0x%lx:"
+msgstr "ÑобÑтвенные флаги = 0x%lx:"
+
+#: elf32-gen.c:69 elf64-gen.c:69
+msgid "%B: Relocations in generic ELF (EM: %d)"
+msgstr "%B: ÐŸÐµÑ€ÐµÐ¼ÐµÑ‰ÐµÐ½Ð¸Ñ Ð² универÑальном ELF (EM: %d)"
+
+#: elf32-hppa.c:850 elf32-hppa.c:3598
+msgid "%B(%A+0x%lx): cannot reach %s, recompile with -ffunction-sections"
+msgstr "%B(%A+0x%lx): невозможно доÑтичь %s, перекомпилируйте Ñ -ffunction-sections"
+
+#: elf32-hppa.c:1284
+msgid "%B: relocation %s can not be used when making a shared object; recompile with -fPIC"
+msgstr "%B: перемещение %s не может иÑпользоватьÑÑ Ð¿Ñ€Ð¸ Ñоздании общего объекта; перекомпилируйте Ñ -fPIC"
+
+#: elf32-hppa.c:2791
+msgid "%B: duplicate export stub %s"
+msgstr "%B: повторный ÑкÑпорт заглушки %s"
+
+#: elf32-hppa.c:3437
+msgid "%B(%A+0x%lx): %s fixup for insn 0x%x is not supported in a non-shared link"
+msgstr "%B(%A+0x%lx): %s меÑтоположение Ð´Ð»Ñ insn 0x%x не поддерживаетÑÑ Ð² общей ÑÑылке"
+
+#: elf32-hppa.c:4284
+msgid "%B(%A+0x%lx): cannot handle %s for %s"
+msgstr "%B(%A+0x%lx): невозможно обработать %s Ð´Ð»Ñ %s"
+
+#: elf32-hppa.c:4603
+msgid ".got section not immediately after .plt section"
+msgstr "раздел .got не может ÑтоÑÑ‚ÑŒ Ñразу поÑле раздела .plt"
+
+#. Unknown relocation.
+#: elf32-i386.c:373 elf32-m68k.c:384 elf32-ppc.c:1676 elf32-s390.c:379
+#: elf32-tic6x.c:2684 elf64-ppc.c:2300 elf64-s390.c:403 elf64-x86-64.c:265
+msgid "%B: invalid relocation type %d"
+msgstr "%B: неверный тип Ð¿ÐµÑ€ÐµÐ¼ÐµÑ‰ÐµÐ½Ð¸Ñ %d"
+
+#: elf32-i386.c:1404 elf64-x86-64.c:1308
+msgid "%B: TLS transition from %s to %s against `%s' at 0x%lx in section `%A' failed"
+msgstr "%B: TLS-переход из %s в %s Ð´Ð»Ñ Â«%s» по 0x%lx в разделе «%A» завершилÑÑ Ð½ÐµÑƒÐ´Ð°Ñ‡Ð½Ð¾"
+
+#: elf32-i386.c:1549 elf32-i386.c:3244 elf64-x86-64.c:1487 elf64-x86-64.c:3125
+#: elfxx-sparc.c:3083
+msgid "%B: relocation %s against STT_GNU_IFUNC symbol `%s' isn't handled by %s"
+msgstr "%B: перемещение %s вмеÑте Ñ STT_GNU_IFUNC Ñимволом «%s» не обрабатываетÑÑ %s"
+
+#: elf32-i386.c:1711 elf32-s390.c:1182 elf32-sh.c:6362 elf32-tilepro.c:1434
+#: elf32-xtensa.c:1182 elf64-s390.c:1151 elfxx-sparc.c:1548
+#: elfxx-tilegx.c:1701
+msgid "%B: `%s' accessed both as normal and thread local symbol"
+msgstr "%B: «%s» доÑтупен как обычный и как локальный Ð´Ð»Ñ Ð½Ð¸Ñ‚Ð¸ Ñимвол"
+
+#: elf32-i386.c:2539 elf64-x86-64.c:2506
+msgid "%P: %B: warning: relocation against `%s' in readonly section `%A'.\n"
+msgstr "%P: %B: предупреждение: перемещение указывает на «%s» из раздела только Ð´Ð»Ñ Ñ‡Ñ‚ÐµÐ½Ð¸Ñ Â«%A».\n"
+
+#: elf32-i386.c:2629 elf64-x86-64.c:2593
+msgid "%P: %B: warning: relocation in readonly section `%A'.\n"
+msgstr "P: %B: предупреждение: перемещение в разделе только Ð´Ð»Ñ Ñ‡Ñ‚ÐµÐ½Ð¸Ñ Â«%A».\n"
+
+#: elf32-i386.c:3086 elf32-tilepro.c:2557 elfxx-tilegx.c:2871
+msgid "%B: unrecognized relocation (0x%x) in section `%A'"
+msgstr "%B: нераÑпознанное перемещение (0x%x) в разделе «%A»"
+
+#: elf32-i386.c:3494 elf64-x86-64.c:3513
+msgid "hidden symbol"
+msgstr "Ñкрытый Ñимвол"
+
+#: elf32-i386.c:3497 elf64-x86-64.c:3516
+msgid "internal symbol"
+msgstr "внутренний Ñимвол"
+
+#: elf32-i386.c:3500 elf64-x86-64.c:3519
+msgid "protected symbol"
+msgstr "защищённый Ñимвол"
+
+#: elf32-i386.c:3503 elf64-x86-64.c:3522
+msgid "symbol"
+msgstr "Ñимвол"
+
+#: elf32-i386.c:3508
+msgid "%B: relocation R_386_GOTOFF against undefined %s `%s' can not be used when making a shared object"
+msgstr "%B: перемещение R_386_GOTOFF Ð´Ð»Ñ Ð½ÐµÐ¾Ð¿Ñ€ÐµÐ´ÐµÐ»Ñ‘Ð½Ð½Ð¾Ð³Ð¾ %s «%s» не может иÑпользоватьÑÑ Ð¿Ñ€Ð¸ Ñоздании общего объекта"
+
+#: elf32-i386.c:3518
+msgid "%B: relocation R_386_GOTOFF against protected function `%s' can not be used when making a shared object"
+msgstr "%B: перемещение R_386_GOTOFF Ð´Ð»Ñ Ð·Ð°Ñ‰Ð¸Ñ‰Ñ‘Ð½Ð½Ð¾Ð¹ функции «%s» не может иÑпользоватьÑÑ Ð¿Ñ€Ð¸ Ñоздании общего объекта"
+
+#: elf32-i386.c:4839 elf32-tilepro.c:3467 elf64-x86-64.c:4609
+#: elfxx-tilegx.c:3847
+#, c-format
+msgid "discarded output section: `%A'"
+msgstr "отброшенный выходной раздел: «%A»"
+
+#: elf32-ip2k.c:857 elf32-ip2k.c:863 elf32-ip2k.c:930 elf32-ip2k.c:936
+msgid "ip2k relaxer: switch table without complete matching relocation information."
+msgstr "ip2k relaxer: таблица переключений без полного ÑÐ¾Ð²Ð¿Ð°Ð´ÐµÐ½Ð¸Ñ Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ð¸ о перемещении."
+
+#: elf32-ip2k.c:880 elf32-ip2k.c:963
+msgid "ip2k relaxer: switch table header corrupt."
+msgstr "ip2k relaxer: иÑпорчен заголовок у таблицы переключений."
+
+#: elf32-ip2k.c:1292
+#, c-format
+msgid "ip2k linker: missing page instruction at 0x%08lx (dest = 0x%08lx)."
+msgstr "ip2k linker: отÑутÑтвует Ñтраница инÑтрукций по адреÑу 0x%08lx (назнач = 0x%08lx)."
+
+#: elf32-ip2k.c:1308
+#, c-format
+msgid "ip2k linker: redundant page instruction at 0x%08lx (dest = 0x%08lx)."
+msgstr "ip2k linker: повторÑющаÑÑÑ Ñтраница инÑтрукций по адреÑу 0x%08lx (назнач = 0x%08lx)."
+
+#: elf32-iq2000.c:858 elf32-m32c.c:819
+#, c-format
+msgid "%s: uses different e_flags (0x%lx) fields than previous modules (0x%lx)"
+msgstr "%s: иÑпользует другие неизвеÑтные флаги e_flags (0x%lx) чем предыдущие модули (0x%lx)"
+
+#: elf32-lm32.c:706
+msgid "global pointer relative relocation when _gp not defined"
+msgstr "глобальный указатель отноÑительно перемещениÑ, но _gp не определена"
+
+#: elf32-lm32.c:761
+msgid "global pointer relative address out of range"
+msgstr "глобальный указатель отноÑительно адреÑа вне диапазона"
+
+#: elf32-lm32.c:1057
+msgid "internal error: addend should be zero for R_LM32_16_GOT"
+msgstr "внутреннÑÑ Ð¾ÑˆÐ¸Ð±ÐºÐ°: добавление должно быть нулём Ð´Ð»Ñ R_LM32_16_GOT"
+
+#: elf32-m32r.c:1453
+msgid "SDA relocation when _SDA_BASE_ not defined"
+msgstr "перемещение SDA, но _SDA_BASE_ не определена"
+
+#: elf32-m32r.c:3043
+msgid "%B: The target (%s) of an %s relocation is in the wrong section (%A)"
+msgstr "%B: Цель (%s) Ð¿ÐµÑ€ÐµÐ¼ÐµÑ‰ÐµÐ½Ð¸Ñ %s в ошибочном разделе (%A)"
+
+#: elf32-m32r.c:3571
+msgid "%B: Instruction set mismatch with previous modules"
+msgstr "%B: Ðабор инÑтрукций не Ñовпадает Ñ Ð½Ð°Ð±Ð¾Ñ€Ð¾Ð¼ у предыдущих модулей"
+
+#: elf32-m32r.c:3592
+#, c-format
+msgid "private flags = %lx"
+msgstr "ÑобÑтвенные флаги = %lx"
+
+#: elf32-m32r.c:3597
+#, c-format
+msgid ": m32r instructions"
+msgstr ": инÑтрукции m32r"
+
+#: elf32-m32r.c:3598
+#, c-format
+msgid ": m32rx instructions"
+msgstr ": инÑтрукции m32rx"
+
+#: elf32-m32r.c:3599
+#, c-format
+msgid ": m32r2 instructions"
+msgstr ": инÑтрукции m32r2"
+
+#: elf32-m68hc1x.c:1050
+#, c-format
+msgid "Reference to the far symbol `%s' using a wrong relocation may result in incorrect execution"
+msgstr "Указание на дальний Ñимвол «%s» Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ ошибочного Ð¿ÐµÑ€ÐµÐ¼ÐµÑ‰ÐµÐ½Ð¸Ñ Ð¼Ð¾Ð¶ÐµÑ‚ привеÑти к неправильному выполнению"
+
+#: elf32-m68hc1x.c:1073
+#, c-format
+msgid "banked address [%lx:%04lx] (%lx) is not in the same bank as current banked address [%lx:%04lx] (%lx)"
+msgstr "банкируемый Ð°Ð´Ñ€ÐµÑ [%lx:%04lx] (%lx) не Ñовпадает Ñ Ð±Ð°Ð½ÐºÐ¾Ð¼ текущего банкируемого адреÑа [%lx:%04lx] (%lx)"
+
+#: elf32-m68hc1x.c:1092
+#, c-format
+msgid "reference to a banked address [%lx:%04lx] in the normal address space at %04lx"
+msgstr "ÑÑылка на банкируемый Ð°Ð´Ñ€ÐµÑ [%lx:%04lx] в обычном адреÑном проÑтранÑтве по адреÑу %04lx"
+
+#: elf32-m68hc1x.c:1225
+msgid "%B: linking files compiled for 16-bit integers (-mshort) and others for 32-bit integers"
+msgstr "%B: компоновка файлов, Ñкомпилированных Ð´Ð»Ñ 16-битных целых (-mshort), Ñ Ñ„Ð°Ð¹Ð»Ð°Ð¼Ð¸, Ñкомпилированными Ð´Ð»Ñ 32-битных целых"
+
+#: elf32-m68hc1x.c:1232
+msgid "%B: linking files compiled for 32-bit double (-fshort-double) and others for 64-bit double"
+msgstr "%B: компоновка файлов, Ñкомпилированных Ð´Ð»Ñ 32-битных double (-fshort-double), Ñ Ñ„Ð°Ð¹Ð»Ð°Ð¼Ð¸, Ñкомпилированными Ð´Ð»Ñ 64-битных double"
+
+#: elf32-m68hc1x.c:1241
+msgid "%B: linking files compiled for HCS12 with others compiled for HC12"
+msgstr "%B: компоновка файлов, Ñкомпилированных Ð´Ð»Ñ HCS12, Ñ Ñ„Ð°Ð¹Ð»Ð°Ð¼Ð¸, Ñкомпилированными Ð´Ð»Ñ HC12"
+
+#: elf32-m68hc1x.c:1257 elf32-ppc.c:4227 elf64-sparc.c:706 elfxx-mips.c:13965
+msgid "%B: uses different e_flags (0x%lx) fields than previous modules (0x%lx)"
+msgstr "%B: иÑпользует другие неизвеÑтные флаги e_flags (0x%lx), чем предыдущие модули (0x%lx)"
+
+#: elf32-m68hc1x.c:1285
+#, c-format
+msgid "[abi=32-bit int, "
+msgstr "[abi=32-битное int, "
+
+#: elf32-m68hc1x.c:1287
+#, c-format
+msgid "[abi=16-bit int, "
+msgstr "[abi=16-битное int, "
+
+#: elf32-m68hc1x.c:1290
+#, c-format
+msgid "64-bit double, "
+msgstr "64-битное double, "
+
+#: elf32-m68hc1x.c:1292
+#, c-format
+msgid "32-bit double, "
+msgstr "32-битное double, "
+
+#: elf32-m68hc1x.c:1295
+#, c-format
+msgid "cpu=HC11]"
+msgstr "ЦП=HC11]"
+
+#: elf32-m68hc1x.c:1297
+#, c-format
+msgid "cpu=HCS12]"
+msgstr "ЦП=HCS12]"
+
+#: elf32-m68hc1x.c:1299
+#, c-format
+msgid "cpu=HC12]"
+msgstr "ЦП=HC12]"
+
+#: elf32-m68hc1x.c:1302
+#, c-format
+msgid " [memory=bank-model]"
+msgstr " [памÑÑ‚ÑŒ=модель Ñ Ð±Ð°Ð½ÐºÐ°Ð¼Ð¸]"
+
+#: elf32-m68hc1x.c:1304
+#, c-format
+msgid " [memory=flat]"
+msgstr " [памÑÑ‚ÑŒ=плоÑкаÑ]"
+
+#: elf32-m68k.c:1251 elf32-m68k.c:1252 vms-alpha.c:7314 vms-alpha.c:7329
+msgid "unknown"
+msgstr "неизвеÑтно"
+
+#: elf32-m68k.c:1715
+msgid "%B: GOT overflow: Number of relocations with 8-bit offset > %d"
+msgstr "%B: переполнение GOT: КоличеÑтво перемещений Ñ 8-битным Ñмещением > %d"
+
+#: elf32-m68k.c:1721
+msgid "%B: GOT overflow: Number of relocations with 8- or 16-bit offset > %d"
+msgstr "%B: переполнение GOT: КоличеÑтво перемещений Ñ 8-ми или 16-битным Ñмещением > %d"
+
+#: elf32-m68k.c:3957
+msgid "%B(%A+0x%lx): R_68K_TLS_LE32 relocation not permitted in shared object"
+msgstr "%B(%A+0x%lx): перемещение R_68K_TLS_LE32 не разрешено Ð´Ð»Ñ Ð¾Ð±Ñ‰ÐµÐ³Ð¾ объекта"
+
+#: elf32-mcore.c:99 elf32-mcore.c:442
+msgid "%B: Relocation %s (%d) is not currently supported.\n"
+msgstr "%B: Перемещение %s (%d) в данный момент не поддерживаетÑÑ.\n"
+
+#: elf32-mcore.c:428
+msgid "%B: Unknown relocation type %d\n"
+msgstr "%B: ÐеизвеÑтный тип Ð¿ÐµÑ€ÐµÐ¼ÐµÑ‰ÐµÐ½Ð¸Ñ %d\n"
+
+#. Pacify gcc -Wall.
+#: elf32-mep.c:157
+#, c-format
+msgid "mep: no reloc for code %d"
+msgstr "mep: нет Ð¿ÐµÑ€ÐµÐ¼ÐµÑ‰ÐµÐ½Ð¸Ñ Ð´Ð»Ñ ÐºÐ¾Ð´Ð° %d"
+
+#: elf32-mep.c:163
+#, c-format
+msgid "MeP: howto %d has type %d"
+msgstr "MeP: howto %d имеет тип %d"
+
+#: elf32-mep.c:648
+msgid "%B and %B are for different cores"
+msgstr "%B и %B Ð´Ð»Ñ Ñ€Ð°Ð·Ð½Ñ‹Ñ… Ñдер"
+
+#: elf32-mep.c:665
+msgid "%B and %B are for different configurations"
+msgstr "%B и %B Ð´Ð»Ñ Ñ€Ð°Ð·Ð½Ñ‹Ñ… конфигураций"
+
+#: elf32-mep.c:702
+#, c-format
+msgid "private flags = 0x%lx"
+msgstr "ÑобÑтвенные флаги = 0x%lx"
+
+#: elf32-microblaze.c:742
+#, c-format
+msgid "%s: unknown relocation type %d"
+msgstr "%s: неизвеÑтный тип Ð¿ÐµÑ€ÐµÐ¼ÐµÑ‰ÐµÐ½Ð¸Ñ %d"
+
+#: elf32-microblaze.c:867 elf32-microblaze.c:912
+#, c-format
+msgid "%s: The target (%s) of an %s relocation is in the wrong section (%s)"
+msgstr "%s: Цель (%s) Ð¿ÐµÑ€ÐµÐ¼ÐµÑ‰ÐµÐ½Ð¸Ñ %s в ошибочном разделе (%s)"
+
+#: elf32-microblaze.c:1155 elf32-tilepro.c:2891 elfxx-sparc.c:3457
+#: elfxx-tilegx.c:3230
+msgid "%B: probably compiled without -fPIC?"
+msgstr "%B: вероÑтно, компилÑÑ†Ð¸Ñ Ð±ÐµÐ· -fPIC?"
+
+#: elf32-microblaze.c:2074
+msgid "%B: bad relocation section name `%s'"
+msgstr "%B: неправильное Ð¸Ð¼Ñ Ð¿ÐµÑ€ÐµÐ¼ÐµÑ‰Ð°ÐµÐ¼Ð¾Ð³Ð¾ раздела «%s»"
+
+#: elf32-mips.c:1549 elf64-mips.c:2683 elfn32-mips.c:2487
+msgid "literal relocation occurs for an external symbol"
+msgstr "Ð´Ð»Ñ Ð²Ð½ÐµÑˆÐ½ÐµÐ³Ð¾ Ñимвола обнаружено конÑтантное перемещение"
+
+#: elf32-mips.c:1596 elf32-score.c:570 elf32-score7.c:469 elf64-mips.c:2726
+#: elfn32-mips.c:2528
+msgid "32bits gp relative relocation occurs for an external symbol"
+msgstr "Ð´Ð»Ñ Ð²Ð½ÐµÑˆÐ½ÐµÐ³Ð¾ Ñимвола обнаружено 32—битное отноÑительное перемещение"
+
+#: elf32-ppc.c:1741
+#, c-format
+msgid "generic linker can't handle %s"
+msgstr "универÑальный компоновщик не Ñмог обработать %s"
+
+#: elf32-ppc.c:2184
+msgid "corrupt %s section in %B"
+msgstr "повреждённый раздел %s в %B"
+
+#: elf32-ppc.c:2203
+msgid "unable to read in %s section from %B"
+msgstr "не удалоÑÑŒ прочитать раздел %s из %B"
+
+#: elf32-ppc.c:2244
+msgid "warning: unable to set size of %s section in %B"
+msgstr "предупреждение: не удалоÑÑŒ уÑтановить размер раздела %s в %B"
+
+#: elf32-ppc.c:2294
+msgid "failed to allocate space for new APUinfo section."
+msgstr "не удалоÑÑŒ выделить меÑто Ð´Ð»Ñ Ð½Ð¾Ð²Ð¾Ð³Ð¾ раздела APUinfo."
+
+#: elf32-ppc.c:2313
+msgid "failed to compute new APUinfo section."
+msgstr "не удалоÑÑŒ вычиÑлить новый раздел APUinfo."
+
+#: elf32-ppc.c:2316
+msgid "failed to install new APUinfo section."
+msgstr "не удалоÑÑŒ уÑтановить новый раздел APUinfo."
+
+#: elf32-ppc.c:3356
+msgid "%B: relocation %s cannot be used when making a shared object"
+msgstr "%B: раздел %s не может иÑпользоватьÑÑ Ð¿Ñ€Ð¸ Ñоздании общего объекта"
+
+#. It does not make sense to have a procedure linkage
+#. table entry for a local symbol.
+#: elf32-ppc.c:3700
+msgid "%P: %H: %s reloc against local symbol\n"
+msgstr "%P: %H: перемещение %s Ð´Ð»Ñ Ð»Ð¾ÐºÐ°Ð»ÑŒÐ½Ð¾Ð³Ð¾ Ñимвола\n"
+
+#: elf32-ppc.c:4039 elf32-ppc.c:4054 elfxx-mips.c:13651 elfxx-mips.c:13677
+#: elfxx-mips.c:13699 elfxx-mips.c:13725
+msgid "Warning: %B uses hard float, %B uses soft float"
+msgstr "Предупреждение: %B иÑпользует аппаратную плавающую точку, %B иÑпользует программную плавающую точку"
+
+#: elf32-ppc.c:4042 elf32-ppc.c:4046
+msgid "Warning: %B uses double-precision hard float, %B uses single-precision hard float"
+msgstr "Предупреждение: %B иÑпользует аппаратную плавающую точку двойной точноÑти, %B иÑпользует аппаратную плавающую точку одинарной точноÑти"
+
+#: elf32-ppc.c:4050
+msgid "Warning: %B uses soft float, %B uses single-precision hard float"
+msgstr "Предупреждение: %B иÑпользует программную плавающую точку, %B аппаратную плавающую точку одинарной точноÑти"
+
+#: elf32-ppc.c:4057 elf32-ppc.c:4061 elfxx-mips.c:13631 elfxx-mips.c:13635
+msgid "Warning: %B uses unknown floating point ABI %d"
+msgstr "Предупреждение: %B иÑпользует неизвеÑтный ABI плавающей точки %d"
+
+#: elf32-ppc.c:4103 elf32-ppc.c:4107
+msgid "Warning: %B uses unknown vector ABI %d"
+msgstr "Предупреждение: %B иÑпользует неизвеÑтный ABI векторов %d"
+
+#: elf32-ppc.c:4111
+msgid "Warning: %B uses vector ABI \"%s\", %B uses \"%s\""
+msgstr "Предупреждение: %B иÑпользует ABI векторов \"%s\", %B иÑпользует \"%s\""
+
+#: elf32-ppc.c:4128 elf32-ppc.c:4131
+msgid "Warning: %B uses r3/r4 for small structure returns, %B uses memory"
+msgstr "Предупреждение: %B иÑпользует r3/r4 Ð´Ð»Ñ Ð²Ð¾Ð·Ð²Ñ€Ð°Ñ‚Ð° маленькой Ñтруктуры, %B иÑпользует памÑÑ‚ÑŒ"
+
+#: elf32-ppc.c:4134 elf32-ppc.c:4138
+msgid "Warning: %B uses unknown small structure return convention %d"
+msgstr "Предупреждение: %B иÑпользует неизвеÑтное Ñоглашение %d по возврату маленькой Ñтруктуры"
+
+#: elf32-ppc.c:4192
+msgid "%B: compiled with -mrelocatable and linked with modules compiled normally"
+msgstr "%B: Ñкомпилирована Ñ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ð¾Ð¼ -mrelocatable и нормально Ñкомпонована Ñо Ñкомпилированными модулÑми"
+
+#: elf32-ppc.c:4200
+msgid "%B: compiled normally and linked with modules compiled with -mrelocatable"
+msgstr "%B: нормально Ñкомпилирована и Ñкомпонована Ñ Ð¼Ð¾Ð´ÑƒÐ»Ñми, Ñкомпилированными Ñ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ð¾Ð¼ -mrelocatable"
+
+#: elf32-ppc.c:4309
+msgid "%P: bss-plt forced due to %B\n"
+msgstr "%P: bss-plt иÑпользуетÑÑ Ð¸Ð·-за %B\n"
+
+#: elf32-ppc.c:4312
+msgid "%P: bss-plt forced by profiling\n"
+msgstr "%P: bss-plt иÑпользуетÑÑ Ð¸Ð·-за профилированиÑ\n"
+
+#. Uh oh, we didn't find the expected call. We
+#. could just mark this symbol to exclude it
+#. from tls optimization but it's safer to skip
+#. the entire optimization.
+#: elf32-ppc.c:4809 elf64-ppc.c:7858
+msgid "%H arg lost __tls_get_addr, TLS optimization disabled\n"
+msgstr "%H аргумент lost __tls_get_addr, Ð¾Ð¿Ñ‚Ð¸Ð¼Ð¸Ð·Ð°Ñ†Ð¸Ñ TLS выключена\n"
+
+#: elf32-ppc.c:5044 elf64-ppc.c:6528
+msgid "%P: dynamic variable `%s' is zero size\n"
+msgstr "%P: динамичеÑÐºÐ°Ñ Ð¿ÐµÑ€ÐµÐ¼ÐµÐ½Ð½Ð°Ñ Â«%s» имеет нулевой размер\n"
+
+#: elf32-ppc.c:7263 elf64-ppc.c:12675
+msgid "%P: %B: unknown relocation type %d for symbol %s\n"
+msgstr "%P: %B: неизвеÑтный тип Ð¿ÐµÑ€ÐµÐ¼ÐµÑ‰ÐµÐ½Ð¸Ñ %d Ð´Ð»Ñ Ñимвола %s\n"
+
+#: elf32-ppc.c:7524
+msgid "%P: %H: non-zero addend on %s reloc against `%s'\n"
+msgstr "%P: %H: ненулевое добавление в перемещении %s Ð´Ð»Ñ Â«%s»\n"
+
+#: elf32-ppc.c:7720 elf64-ppc.c:13181
+msgid "%P: %H: relocation %s for indirect function %s unsupported\n"
+msgstr "%P: %H: перемещение %s Ð´Ð»Ñ Ð½ÐµÑвного вызова функции %s не поддерживаетÑÑ\n"
+
+#: elf32-ppc.c:7948 elf32-ppc.c:7978 elf32-ppc.c:8025
+msgid "%P: %B: the target (%s) of a %s relocation is in the wrong output section (%s)\n"
+msgstr "%P: %B: назначение (%s) Ð¿ÐµÑ€ÐµÐ¼ÐµÑ‰ÐµÐ½Ð¸Ñ %s в ошибочный выходной раздел (%s)\n"
+
+#: elf32-ppc.c:8097
+msgid "%P: %B: relocation %s is not yet supported for symbol %s\n"
+msgstr "%P: %B: перемещение %s пока не поддерживаетÑÑ Ð´Ð»Ñ Ñимвола %s\n"
+
+#: elf32-ppc.c:8158 elf64-ppc.c:13467
+msgid "%P: %H: unresolvable %s relocation against symbol `%s'\n"
+msgstr "%P: %H: неразрешимое перемещение %s отноÑительно Ð´Ð»Ñ Ñимвола «%s»\n"
+
+#: elf32-ppc.c:8205 elf64-ppc.c:13512
+msgid "%P: %H: %s reloc against `%s': error %d\n"
+msgstr "%P: %H: перемещение %s Ð´Ð»Ñ Â«%s»: ошибка %d\n"
+
+#: elf32-ppc.c:8696
+msgid "%P: %s not defined in linker created %s\n"
+msgstr "%P: %s не определено в компоновщике, Ñозданном %s\n"
+
+#: elf32-rx.c:563
+msgid "%B:%A: Warning: deprecated Red Hat reloc "
+msgstr "%B:%A: предупреждение: уÑтаревшее перемещение Red Hat "
+
+#. Check for unsafe relocs in PID mode. These are any relocs where
+#. an absolute address is being computed. There are special cases
+#. for relocs against symbols that are known to be referenced in
+#. crt0.o before the PID base address register has been initialised.
+#: elf32-rx.c:581
+msgid "%B(%A): unsafe PID relocation %s at 0x%08lx (against %s in %s)"
+msgstr "%B(%A): небезопаÑное перемещение PID %s по адреÑу 0x%08lx (отноÑительно %s в %s)"
+
+#: elf32-rx.c:1157
+msgid "Warning: RX_SYM reloc with an unknown symbol"
+msgstr "Предупреждение: перемещение RX_SYM Ñ Ð½ÐµÐ¸Ð·Ð²ÐµÑтным Ñимволом"
+
+#: elf32-rx.c:1324
+msgid "%B(%A): error: call to undefined function '%s'"
+msgstr "%B(%A): ошибка: вызов неопределённой функции «%s»"
+
+#: elf32-rx.c:1338
+msgid "%B(%A): warning: unaligned access to symbol '%s' in the small data area"
+msgstr "%B(%A): предупреждение: невыровненный доÑтуп к Ñимволу «%s» в малой облаÑти данных"
+
+#: elf32-rx.c:1342
+msgid "%B(%A): internal error: out of range error"
+msgstr "%B(%A): внутреннÑÑ Ð¾ÑˆÐ¸Ð±ÐºÐ°: ошибка выхода из диапазона"
+
+#: elf32-rx.c:1346
+msgid "%B(%A): internal error: unsupported relocation error"
+msgstr "%B(%A): внутреннÑÑ Ð¾ÑˆÐ¸Ð±ÐºÐ°: ошибка неподдерживаемого перемещениÑ"
+
+#: elf32-rx.c:1350
+msgid "%B(%A): internal error: dangerous relocation"
+msgstr "%B(%A): внутреннÑÑ Ð¾ÑˆÐ¸Ð±ÐºÐ°: опаÑное перемещение"
+
+#: elf32-rx.c:1354
+msgid "%B(%A): internal error: unknown error"
+msgstr "%B(%A): внутреннÑÑ Ð¾ÑˆÐ¸Ð±ÐºÐ°: неизвеÑÑ‚Ð½Ð°Ñ Ð¾ÑˆÐ¸Ð±ÐºÐ°"
+
+#: elf32-rx.c:3004
+#, c-format
+msgid " [64-bit doubles]"
+msgstr "[64-битные double]"
+
+#: elf32-rx.c:3006
+#, c-format
+msgid " [dsp]"
+msgstr " [dsp]"
+
+#: elf32-s390.c:2200 elf64-s390.c:2187
+msgid "%B(%A+0x%lx): invalid instruction for TLS relocation %s"
+msgstr "%B(%A+0x%lx): недопуÑÑ‚Ð¸Ð¼Ð°Ñ Ð¸Ð½ÑÑ‚Ñ€ÑƒÐºÑ†Ð¸Ñ Ð´Ð»Ñ TLS-Ð¿ÐµÑ€ÐµÐ¼ÐµÑ‰ÐµÐ½Ð¸Ñ %s"
+
+#: elf32-score.c:1520 elf32-score7.c:1379 elfxx-mips.c:3435
+msgid "not enough GOT space for local GOT entries"
+msgstr "недоÑтаточно проÑтранÑтва GOT Ð´Ð»Ñ Ð»Ð¾ÐºÐ°Ð»ÑŒÐ½Ñ‹Ñ… Ñлементов GOT"
+
+#: elf32-score.c:2742
+msgid "address not word align"
+msgstr "Ð°Ð´Ñ€ÐµÑ Ð½Ðµ выровнен по границе Ñлова"
+
+#: elf32-score.c:2827 elf32-score7.c:2631
+#, c-format
+msgid "%s: Malformed reloc detected for section %s"
+msgstr "%s: Обнаружено иÑкажённое перемещение Ð´Ð»Ñ Ñ€Ð°Ð·Ð´ÐµÐ»Ð° %s"
+
+#: elf32-score.c:2878 elf32-score7.c:2682
+msgid "%B: CALL15 reloc at 0x%lx not against global symbol"
+msgstr "%B: перемещение CALL15 по адреÑу 0x%lx не Ð´Ð»Ñ Ð³Ð»Ð¾Ð±Ð°Ð»ÑŒÐ½Ð¾Ð³Ð¾ Ñимвола"
+
+#: elf32-score.c:3997 elf32-score7.c:3803
+#, c-format
+msgid " [pic]"
+msgstr " [pic]"
+
+#: elf32-score.c:4001 elf32-score7.c:3807
+#, c-format
+msgid " [fix dep]"
+msgstr " [fix dep]"
+
+#: elf32-score.c:4043 elf32-score7.c:3849
+msgid "%B: warning: linking PIC files with non-PIC files"
+msgstr "%B: предупреждение: выполнÑетÑÑ ÐºÐ¾Ð¼Ð¿Ð¾Ð½Ð¾Ð²ÐºÐ° PIC-файлов Ñ Ð½Ðµ-PIC файлами"
+
+#: elf32-sh-symbian.c:130
+msgid "%B: IMPORT AS directive for %s conceals previous IMPORT AS"
+msgstr "%B: директива IMPORT AS Ð´Ð»Ñ %s ÑкрываетÑÑ Ð¿Ñ€ÐµÐ´Ñ‹Ð´ÑƒÑ‰ÐµÐ¹ IMPORT AS"
+
+#: elf32-sh-symbian.c:383
+msgid "%B: Unrecognised .directive command: %s"
+msgstr "%B: ÐераÑÐ¿Ð¾Ð·Ð½Ð°Ð½Ð½Ð°Ñ ÐºÐ¾Ð¼Ð°Ð½Ð´Ð° .directive: %s"
+
+#: elf32-sh-symbian.c:504
+msgid "%B: Failed to add renamed symbol %s"
+msgstr "%B: Ðе удалоÑÑŒ добавить переименованный Ñимвол %s"
+
+#: elf32-sh.c:568
+msgid "%B: 0x%lx: warning: bad R_SH_USES offset"
+msgstr "%B: 0x%lx: предупреждение: неправильное Ñмещение R_SH_USES"
+
+#: elf32-sh.c:580
+msgid "%B: 0x%lx: warning: R_SH_USES points to unrecognized insn 0x%x"
+msgstr "%B: 0x%lx: предупреждение: R_SH_USES указывает на нераÑпознанный insn 0x%x"
+
+#: elf32-sh.c:597
+msgid "%B: 0x%lx: warning: bad R_SH_USES load offset"
+msgstr "%B: 0x%lx: предупреждение: неправильное загрузочное Ñмещение R_SH_USES"
+
+#: elf32-sh.c:612
+msgid "%B: 0x%lx: warning: could not find expected reloc"
+msgstr "%B: 0x%lx: предупреждение: невозможно найти ожидаемое перемещение"
+
+#: elf32-sh.c:640
+msgid "%B: 0x%lx: warning: symbol in unexpected section"
+msgstr "%B: 0x%lx: предупреждение: Ñимвол в неожиданном разделе"
+
+#: elf32-sh.c:766
+msgid "%B: 0x%lx: warning: could not find expected COUNT reloc"
+msgstr "%B: 0x%lx: предупреждение: невозможно найти ожидаемое перемещение COUNT"
+
+#: elf32-sh.c:775
+msgid "%B: 0x%lx: warning: bad count"
+msgstr "%B: 0x%lx: предупреждение: неправильный Ñчётчик"
+
+#: elf32-sh.c:1179 elf32-sh.c:1549
+msgid "%B: 0x%lx: fatal: reloc overflow while relaxing"
+msgstr "%B: 0x%lx: оÑтанов: переполнение Ð¿ÐµÑ€ÐµÐ¼ÐµÑ‰ÐµÐ½Ð¸Ñ Ð¿Ñ€Ð¸ оÑлаблении"
+
+#: elf32-sh.c:4048 elf64-sh64.c:1514
+msgid "Unexpected STO_SH5_ISA32 on local symbol is not handled"
+msgstr "Ðеожиданное STO_SH5_ISA32 локального Ñимвола не обрабатываетÑÑ"
+
+#: elf32-sh.c:4299
+msgid "%B: 0x%lx: fatal: unaligned branch target for relax-support relocation"
+msgstr "%B: 0x%lx: оÑтанов: невыровненное назначение Ð²ÐµÑ‚Ð²Ð»ÐµÐ½Ð¸Ñ Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÐ¼ÐµÑ‰ÐµÐ½Ð¸Ñ Ñ Ð¿Ð¾Ð´Ð´ÐµÑ€Ð¶ÐºÐ¾Ð¹ оÑлаблениÑ"
+
+#: elf32-sh.c:4332 elf32-sh.c:4347
+msgid "%B: 0x%lx: fatal: unaligned %s relocation 0x%lx"
+msgstr "%B: 0x%lx: оÑтанов: невыровненное %s перемещение 0x%lx"
+
+#: elf32-sh.c:4361
+msgid "%B: 0x%lx: fatal: R_SH_PSHA relocation %d not in range -32..32"
+msgstr "%B: 0x%lx: оÑтанов: R_SH_PSHA перемещение %d вне диапазона -32..32"
+
+#: elf32-sh.c:4375
+msgid "%B: 0x%lx: fatal: R_SH_PSHL relocation %d not in range -32..32"
+msgstr "%B: 0x%lx: оÑтанов: R_SH_PSHL перемещение %d вне диапазона -32..32"
+
+#: elf32-sh.c:4519 elf32-sh.c:4989
+msgid "%B(%A+0x%lx): cannot emit fixup to `%s' in read-only section"
+msgstr "%B(%A+0x%lx): невозможно Ñгенерировать меÑтоположение к «%s» в разделе только Ð´Ð»Ñ Ñ‡Ñ‚ÐµÐ½Ð¸Ñ"
+
+#: elf32-sh.c:5096
+msgid "%B(%A+0x%lx): %s relocation against external symbol \"%s\""
+msgstr "%B(%A+0x%lx): перемещение %s Ð´Ð»Ñ Ð²Ð½ÐµÑˆÐ½ÐµÐ³Ð¾ Ñимвола «%s»"
+
+#: elf32-sh.c:5569
+#, c-format
+msgid "%X%C: relocation to \"%s\" references a different segment\n"
+msgstr "%X%C: перемещение указывает на ÑÑылки «%s» другого Ñегмента\n"
+
+#: elf32-sh.c:5575
+#, c-format
+msgid "%C: warning: relocation to \"%s\" references a different segment\n"
+msgstr "%C: предупреждение: перемещение указывает на ÑÑылки «%s» другого Ñегмента\n"
+
+#: elf32-sh.c:6353 elf32-sh.c:6436
+msgid "%B: `%s' accessed both as normal and FDPIC symbol"
+msgstr "%B: «%s» доÑтупен как обычный и как FDPIC Ñимвол"
+
+#: elf32-sh.c:6358 elf32-sh.c:6440
+msgid "%B: `%s' accessed both as FDPIC and thread local symbol"
+msgstr "%B: «%s» доÑтупен как FDPIC и как локальный Ñимвол нити"
+
+#: elf32-sh.c:6388
+msgid "%B: Function descriptor relocation with non-zero addend"
+msgstr "%B: перемещение деÑкриптора функции Ñ Ð½ÐµÐ½ÑƒÐ»ÐµÐ²Ñ‹Ð¼ добавлением"
+
+#: elf32-sh.c:6624 elf64-alpha.c:4652
+msgid "%B: TLS local exec code cannot be linked into shared objects"
+msgstr "%B: локальный иÑполнÑемый код TLS не может быть Ñкомпонован Ñ Ð¾Ð±Ñ‰Ð¸Ð¼Ð¸ объектами"
+
+#: elf32-sh64.c:223 elf64-sh64.c:2318
+#, c-format
+msgid "%s: compiled as 32-bit object and %s is 64-bit"
+msgstr "%s: Ñкомпилирован как 32-битный объект, а %s 64-битный"
+
+#: elf32-sh64.c:226 elf64-sh64.c:2321
+#, c-format
+msgid "%s: compiled as 64-bit object and %s is 32-bit"
+msgstr "%s: Ñкомпилирован как 64-битный объект, а %s 32-битный"
+
+#: elf32-sh64.c:228 elf64-sh64.c:2323
+#, c-format
+msgid "%s: object size does not match that of target %s"
+msgstr "%s: размер объекта не ÑоответÑтвует Ñтой цели %s"
+
+#: elf32-sh64.c:451 elf64-sh64.c:2837
+#, c-format
+msgid "%s: encountered datalabel symbol in input"
+msgstr "%s: во входных данных обнаружен Ñимвол метки данных"
+
+#: elf32-sh64.c:528
+msgid "PTB mismatch: a SHmedia address (bit 0 == 1)"
+msgstr "неÑовпадение PTB: Ð°Ð´Ñ€ÐµÑ SHmedia (бит 0 == 1)"
+
+#: elf32-sh64.c:531
+msgid "PTA mismatch: a SHcompact address (bit 0 == 0)"
+msgstr "неÑовпадение PTA: Ð°Ð´Ñ€ÐµÑ SHcompact (бит 0 == 0)"
+
+#: elf32-sh64.c:549
+#, c-format
+msgid "%s: GAS error: unexpected PTB insn with R_SH_PT_16"
+msgstr "%s: ошибка GAS: неожиданный PTB insn Ñ R_SH_PT_16"
+
+#: elf32-sh64.c:598
+msgid "%B: error: unaligned relocation type %d at %08x reloc %p\n"
+msgstr "%B: ошибка: невыровненный тип Ð¿ÐµÑ€ÐµÐ¼ÐµÑ‰ÐµÐ½Ð¸Ñ %d по адреÑу %08x перемещение %p\n"
+
+#: elf32-sh64.c:674
+#, c-format
+msgid "%s: could not write out added .cranges entries"
+msgstr "%s: не удалоÑÑŒ запиÑать добавленные Ñлементы .cranges"
+
+#: elf32-sh64.c:734
+#, c-format
+msgid "%s: could not write out sorted .cranges entries"
+msgstr "%s: не удалоÑÑŒ запиÑать отÑортированные Ñлементы .cranges"
+
+#: elf32-sparc.c:90
+msgid "%B: compiled for a 64 bit system and target is 32 bit"
+msgstr "%B: Ñкомпилирован Ð´Ð»Ñ 64-битной ÑиÑтемы, а цель 32-битнаÑ"
+
+#: elf32-sparc.c:103
+msgid "%B: linking little endian files with big endian files"
+msgstr "%B: производитÑÑ ÐºÐ¾Ð¼Ð¿Ð¾Ð½Ð¾Ð²ÐºÐ° файлов Ñ Ð¾Ð±Ñ€Ð°Ñ‚Ð½Ñ‹Ð¼ порÑдком байт Ñ Ñ„Ð°Ð¹Ð»Ð°Ð¼Ð¸ Ñ Ð¿Ñ€Ñмым порÑдком байт"
+
+#: elf32-spu.c:719
+msgid "%X%P: overlay section %A does not start on a cache line.\n"
+msgstr "%X%P: раздел Ð¾Ð²ÐµÑ€Ð»ÐµÑ %A не начинаетÑÑ Ñо Ñтроки кÑша.\n"
+
+#: elf32-spu.c:727
+msgid "%X%P: overlay section %A is larger than a cache line.\n"
+msgstr "%X%P: раздел Ð¾Ð²ÐµÑ€Ð»ÐµÑ %A больше Ñтроки кÑша.\n"
+
+#: elf32-spu.c:747
+msgid "%X%P: overlay section %A is not in cache area.\n"
+msgstr "%X%P: раздел Ð¾Ð²ÐµÑ€Ð»ÐµÑ %A не в облаÑти кÑша.\n"
+
+#: elf32-spu.c:787
+msgid "%X%P: overlay sections %A and %A do not start at the same address.\n"
+msgstr "%X%P: разделы оверлеев %A и %A не начинаютÑÑ Ñ Ð¾Ð´Ð¸Ð½Ð°ÐºÐ¾Ð²Ð¾Ð³Ð¾ адреÑа.\n"
+
+#: elf32-spu.c:1011
+msgid "warning: call to non-function symbol %s defined in %B"
+msgstr "предупреждение: в %B определён вызов Ñимвола не-функции %s"
+
+#: elf32-spu.c:1361
+msgid "%A:0x%v lrlive .brinfo (%u) differs from analysis (%u)\n"
+msgstr "%A:0x%v lrlive .brinfo (%u) отличаетÑÑ Ð¾Ñ‚ анализируемого (%u)\n"
+
+#: elf32-spu.c:1880
+msgid "%B is not allowed to define %s"
+msgstr "%B не разрешает определÑÑ‚ÑŒ %s"
+
+#: elf32-spu.c:1888
+#, c-format
+msgid "you are not allowed to define %s in a script"
+msgstr "вам не разрешено определÑÑ‚ÑŒ %s в Ñценарии"
+
+#: elf32-spu.c:1922
+#, c-format
+msgid "%s in overlay section"
+msgstr "%s в разделе оверлеев"
+
+#: elf32-spu.c:1951
+msgid "overlay stub relocation overflow"
+msgstr "переполнение оверлейной заглушки перемещениÑ"
+
+#: elf32-spu.c:1960
+msgid "stubs don't match calculated size"
+msgstr "заглушка не ÑоответÑтвует вычиÑленному размеру"
+
+#: elf32-spu.c:2542
+#, c-format
+msgid "warning: %s overlaps %s\n"
+msgstr "предупреждение: %s перекрываетÑÑ Ñ %s\n"
+
+#: elf32-spu.c:2558
+#, c-format
+msgid "warning: %s exceeds section size\n"
+msgstr "предупреждение: %s превышает размер раздела\n"
+
+#: elf32-spu.c:2589
+msgid "%A:0x%v not found in function table\n"
+msgstr "%A:0x%v не найдена в таблице функций\n"
+
+#: elf32-spu.c:2729
+msgid "%B(%A+0x%v): call to non-code section %B(%A), analysis incomplete\n"
+msgstr "%B(%A+0x%v): вызов не кодового раздела %B(%A), анализ не полон\n"
+
+#: elf32-spu.c:3297
+#, c-format
+msgid "Stack analysis will ignore the call from %s to %s\n"
+msgstr "Ð’ анализе Ñтека будет игнорироватьÑÑ Ð²Ñ‹Ð·Ð¾Ð² из %s в %s\n"
+
+#: elf32-spu.c:3988
+msgid " %s: 0x%v\n"
+msgstr " %s: 0x%v\n"
+
+#: elf32-spu.c:3989
+msgid "%s: 0x%v 0x%v\n"
+msgstr "%s: 0x%v 0x%v\n"
+
+#: elf32-spu.c:3994
+msgid " calls:\n"
+msgstr " вызовы:\n"
+
+#: elf32-spu.c:4002
+#, c-format
+msgid " %s%s %s\n"
+msgstr " %s%s %s\n"
+
+#: elf32-spu.c:4307
+#, c-format
+msgid "%s duplicated in %s\n"
+msgstr "%s повторÑетÑÑ Ð² %s\n"
+
+#: elf32-spu.c:4311
+#, c-format
+msgid "%s duplicated\n"
+msgstr "%s повторÑетÑÑ\n"
+
+#: elf32-spu.c:4318
+msgid "sorry, no support for duplicate object files in auto-overlay script\n"
+msgstr "поддержка повторÑющихÑÑ Ð¾Ð±ÑŠÐµÐºÑ‚Ð½Ñ‹Ñ… файлов в Ñценарии auto-overlay пока не Ñделана\n"
+
+#: elf32-spu.c:4359
+msgid "non-overlay size of 0x%v plus maximum overlay size of 0x%v exceeds local store\n"
+msgstr "не оверлейный размер 0x%v Ð¿Ð»ÑŽÑ Ð¼Ð°ÐºÑимальный размер Ð¾Ð²ÐµÑ€Ð»ÐµÑ 0x%v превышает локальное хранилище\n"
+
+#: elf32-spu.c:4514
+msgid "%B:%A%s exceeds overlay size\n"
+msgstr "%B:%A%s превышает размер оверлеÑ\n"
+
+#: elf32-spu.c:4676
+msgid "Stack size for call graph root nodes.\n"
+msgstr "Размер Ñтека Ð´Ð»Ñ Ð²Ñ‹Ð·Ð¾Ð²Ð° графа корневых узлов.\n"
+
+#: elf32-spu.c:4677
+msgid ""
+"\n"
+"Stack size for functions. Annotations: '*' max stack, 't' tail call\n"
+msgstr ""
+"\n"
+"Размер Ñтека Ð´Ð»Ñ Ñ„ÑƒÐ½ÐºÑ†Ð¸Ð¹. ПримечаниÑ: '*' Ð¼Ð°ÐºÑ Ñтек, 't' хвоÑтовой вызов\n"
+
+#: elf32-spu.c:4687
+msgid "Maximum stack required is 0x%v\n"
+msgstr "Ð”Ð»Ñ Ð¼Ð°ÐºÑимального Ñтека требуетÑÑ 0x%v\n"
+
+#: elf32-spu.c:4778
+msgid "fatal error while creating .fixup"
+msgstr "неиÑÐ¿Ñ€Ð°Ð²Ð¸Ð¼Ð°Ñ Ð¾ÑˆÐ¸Ð±ÐºÐ° при Ñоздании .fixup"
+
+#: elf32-spu.c:5008
+msgid "%B(%s+0x%lx): unresolvable %s relocation against symbol `%s'"
+msgstr "%B(%s+0x%lx): неразрешённое перемещение %s Ð´Ð»Ñ Ñимвола «%s»"
+
+#: elf32-tic6x.c:1602
+msgid "warning: generating a shared library containing non-PIC code"
+msgstr "предупреждение: Ð³ÐµÐ½ÐµÑ€Ð°Ñ†Ð¸Ñ Ð¾Ð±Ñ‰ÐµÐ¹ библиотеки Ñодержащей не-PIC код"
+
+#: elf32-tic6x.c:1607
+msgid "warning: generating a shared library containing non-PID code"
+msgstr "предупреждение: Ð³ÐµÐ½ÐµÑ€Ð°Ñ†Ð¸Ñ Ð¾Ð±Ñ‰ÐµÐ¹ библиотеки Ñодержащей не-PID код"
+
+#: elf32-tic6x.c:2541
+msgid "%B: SB-relative relocation but __c6xabi_DSBT_BASE not defined"
+msgstr "%B: отноÑительное перемещение SB, но __c6xabi_DSBT_BASE не определён"
+
+#: elf32-tic6x.c:2761
+msgid "dangerous relocation"
+msgstr "опаÑное перемещение"
+
+#: elf32-tic6x.c:3733
+msgid "%B: error: unknown mandatory EABI object attribute %d"
+msgstr "%B: ошибка: неизвеÑтный обÑзательный атрибут EABI-объекта %d"
+
+#: elf32-tic6x.c:3741
+msgid "%B: warning: unknown EABI object attribute %d"
+msgstr "%B: предупреждение: неизвеÑтный атрибут EABI-объекта %d"
+
+#: elf32-tic6x.c:3853 elf32-tic6x.c:3861
+msgid "error: %B requires more stack alignment than %B preserves"
+msgstr "ошибка: Ð´Ð»Ñ %B требуетÑÑ Ð±Ð¾Ð»ÑŒÑˆÐµÐµ выравнивание Ñтека, чем Ñохранено в %B"
+
+#: elf32-tic6x.c:3871 elf32-tic6x.c:3880
+msgid "error: unknown Tag_ABI_array_object_alignment value in %B"
+msgstr "ошибка: неизвеÑтное значение Tag_ABI_array_object_alignment в %B"
+
+#: elf32-tic6x.c:3889 elf32-tic6x.c:3898
+msgid "error: unknown Tag_ABI_array_object_align_expected value in %B"
+msgstr "ошибка: неизвеÑтное значение Tag_ABI_array_object_align_expected в %B"
+
+#: elf32-tic6x.c:3906 elf32-tic6x.c:3913
+msgid "error: %B requires more array alignment than %B preserves"
+msgstr "ошибка: Ð´Ð»Ñ %B требуетÑÑ Ð±Ð¾Ð»ÑŒÑˆÐµÐµ выравнивание маÑÑива, чем Ñохранено в %B"
+
+#: elf32-tic6x.c:3935
+msgid "warning: %B and %B differ in wchar_t size"
+msgstr "предупреждение: в %B и %B различаетÑÑ Ñ€Ð°Ð·Ð¼ÐµÑ€ wchar_t"
+
+#: elf32-tic6x.c:3953
+msgid "warning: %B and %B differ in whether code is compiled for DSBT"
+msgstr "предупреждение: в %B и %B по-разному Ñкомпилирован код Ð´Ð»Ñ DSBT"
+
+#: elf32-v850.c:173
+#, c-format
+msgid "Variable `%s' cannot occupy in multiple small data regions"
+msgstr "ÐŸÐµÑ€ÐµÐ¼ÐµÐ½Ð½Ð°Ñ Â«%s» не может занимать неÑколько маленьких облаÑтей данных"
+
+#: elf32-v850.c:176
+#, c-format
+msgid "Variable `%s' can only be in one of the small, zero, and tiny data regions"
+msgstr "ÐŸÐµÑ€ÐµÐ¼ÐµÐ½Ð½Ð°Ñ Â«%s» может быть только в одном из маленьких, нулевых и крошечных облаÑтей данных"
+
+#: elf32-v850.c:179
+#, c-format
+msgid "Variable `%s' cannot be in both small and zero data regions simultaneously"
+msgstr "ÐŸÐµÑ€ÐµÐ¼ÐµÐ½Ð½Ð°Ñ Â«%s» не может быть в маленьких и нулевых облаÑÑ‚ÑÑ… данных одновременно"
+
+#: elf32-v850.c:182
+#, c-format
+msgid "Variable `%s' cannot be in both small and tiny data regions simultaneously"
+msgstr "ÐŸÐµÑ€ÐµÐ¼ÐµÐ½Ð½Ð°Ñ Â«%s» не может быть в маленьких и крошечных облаÑÑ‚ÑÑ… данных одновременно"
+
+#: elf32-v850.c:185
+#, c-format
+msgid "Variable `%s' cannot be in both zero and tiny data regions simultaneously"
+msgstr "ÐŸÐµÑ€ÐµÐ¼ÐµÐ½Ð½Ð°Ñ Â«%s» не может быть в нулевых и крошечных облаÑÑ‚ÑÑ… данных одновременно"
+
+#: elf32-v850.c:483
+msgid "FAILED to find previous HI16 reloc"
+msgstr "ÐЕ УДÐЛОСЬ найти предыдущее перемещение HI16"
+
+#: elf32-v850.c:2155
+msgid "could not locate special linker symbol __gp"
+msgstr "невозможно отыÑкать Ñпециальный Ñимвол компоновки __gp"
+
+#: elf32-v850.c:2159
+msgid "could not locate special linker symbol __ep"
+msgstr "невозможно отыÑкать Ñпециальный Ñимвол компоновки __ep"
+
+#: elf32-v850.c:2163
+msgid "could not locate special linker symbol __ctbp"
+msgstr "невозможно отыÑкать Ñпециальный Ñимвол компоновки __ctbp"
+
+#: elf32-v850.c:2341
+msgid "%B: Architecture mismatch with previous modules"
+msgstr "%B: Ðрхитектура не Ñовпадает Ñ Ð¿Ñ€ÐµÐ´Ñ‹Ð´ÑƒÑ‰Ð¸Ð¼Ð¸ модулÑми"
+
+#. xgettext:c-format.
+#: elf32-v850.c:2360
+#, c-format
+msgid "private flags = %lx: "
+msgstr "ÑобÑтвенные флаги = %lx: "
+
+#: elf32-v850.c:2365
+#, c-format
+msgid "v850 architecture"
+msgstr "архитектура v850"
+
+#: elf32-v850.c:2366
+#, c-format
+msgid "v850e architecture"
+msgstr "архитектура v850e"
+
+#: elf32-v850.c:2367
+#, c-format
+msgid "v850e1 architecture"
+msgstr "архитектура v850e1"
+
+#: elf32-v850.c:2368
+#, c-format
+msgid "v850e2 architecture"
+msgstr "архитектура v850e2"
+
+#: elf32-v850.c:2369
+#, c-format
+msgid "v850e2v3 architecture"
+msgstr "архитектура v850e2v3"
+
+#: elf32-vax.c:532
+#, c-format
+msgid " [nonpic]"
+msgstr " [не-pic]"
+
+#: elf32-vax.c:535
+#, c-format
+msgid " [d-float]"
+msgstr " [d-float]"
+
+#: elf32-vax.c:538
+#, c-format
+msgid " [g-float]"
+msgstr " [g-float]"
+
+#: elf32-vax.c:655
+#, c-format
+msgid "%s: warning: GOT addend of %ld to `%s' does not match previous GOT addend of %ld"
+msgstr "%s: предупреждение: добавление GOT из %ld к «%s» не Ñовпадает Ñ Ð¿Ñ€ÐµÐ´Ñ‹Ð´ÑƒÑ‰Ð¸Ð¼ добавлением GOT из %ld"
+
+#: elf32-vax.c:1585
+#, c-format
+msgid "%s: warning: PLT addend of %d to `%s' from %s section ignored"
+msgstr "%s: предупреждение: добавление PLT из %d к «%s» из раздела %s игнорируетÑÑ"
+
+#: elf32-vax.c:1712
+#, c-format
+msgid "%s: warning: %s relocation against symbol `%s' from %s section"
+msgstr "%s: предупреждение: перемещение %s Ð´Ð»Ñ Ñимвола «%s» из раздела %s"
+
+#: elf32-vax.c:1718
+#, c-format
+msgid "%s: warning: %s relocation to 0x%x from %s section"
+msgstr "%s: предупреждение: перемещение %s к 0x%x из раздела %s"
+
+#: elf32-xstormy16.c:451 elf32-ia64.c:2336 elf64-ia64.c:2336
+msgid "non-zero addend in @fptr reloc"
+msgstr "ненулевое добавление в перемещение @fptr"
+
+#: elf32-xtensa.c:918
+msgid "%B(%A): invalid property table"
+msgstr "%B(%A): недопуÑÑ‚Ð¸Ð¼Ð°Ñ Ñ‚Ð°Ð±Ð»Ð¸Ñ†Ð° ÑвойÑтв"
+
+#: elf32-xtensa.c:2777
+msgid "%B(%A+0x%lx): relocation offset out of range (size=0x%x)"
+msgstr "%B(%A+0x%lx): Ñмещение Ð¿ÐµÑ€ÐµÐ¼ÐµÑ‰ÐµÐ½Ð¸Ñ Ð²Ð½Ðµ диапазона (размер=0x%x)"
+
+#: elf32-xtensa.c:2856 elf32-xtensa.c:2977
+msgid "dynamic relocation in read-only section"
+msgstr "динамичеÑкое перемещение в разделе только Ð´Ð»Ñ Ñ‡Ñ‚ÐµÐ½Ð¸Ñ"
+
+#: elf32-xtensa.c:2953
+msgid "TLS relocation invalid without dynamic sections"
+msgstr "TLS-перемещение недопуÑтимо без динамичеÑких разделов"
+
+#: elf32-xtensa.c:3172
+msgid "internal inconsistency in size of .got.loc section"
+msgstr "внутреннÑÑ Ð½ÐµÑоглаÑованноÑÑ‚ÑŒ размера раздела .got.loc"
+
+#: elf32-xtensa.c:3485
+msgid "%B: incompatible machine type. Output is 0x%x. Input is 0x%x"
+msgstr "%B: неÑовмеÑтимый машинный тип. Выходной 0x%x. Входной 0x%x"
+
+#: elf32-xtensa.c:4714 elf32-xtensa.c:4722
+msgid "Attempt to convert L32R/CALLX to CALL failed"
+msgstr "Попытка Ð¿Ñ€ÐµÐ¾Ð±Ñ€Ð°Ð·Ð¾Ð²Ð°Ð½Ð¸Ñ L32R/CALLX в CALL завершилаÑÑŒ неудачно"
+
+#: elf32-xtensa.c:6332 elf32-xtensa.c:6408 elf32-xtensa.c:7524
+msgid "%B(%A+0x%lx): could not decode instruction; possible configuration mismatch"
+msgstr "%B(%A+0x%lx): невозможно декодировать инÑтрукцию; возможно неÑовпадение конфигурации"
+
+#: elf32-xtensa.c:7264
+msgid "%B(%A+0x%lx): could not decode instruction for XTENSA_ASM_SIMPLIFY relocation; possible configuration mismatch"
+msgstr "%B(%A+0x%lx): невозможно декодировать инÑтрукцию Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÐ¼ÐµÑ‰ÐµÐ½Ð¸Ñ XTENSA_ASM_SIMPLIFY; возможно неÑовпадение конфигурации"
+
+#: elf32-xtensa.c:9023
+msgid "invalid relocation address"
+msgstr "недопуÑтимый Ð°Ð´Ñ€ÐµÑ Ð¿ÐµÑ€ÐµÐ¼ÐµÑ‰ÐµÐ½Ð¸Ñ"
+
+#: elf32-xtensa.c:9072
+msgid "overflow after relaxation"
+msgstr "переполнение поÑле оÑлаблениÑ"
+
+#: elf32-xtensa.c:10204
+msgid "%B(%A+0x%lx): unexpected fix for %s relocation"
+msgstr "%B(%A+0x%lx): неожиданное назначение Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÐ¼ÐµÑ‰ÐµÐ½Ð¸Ñ %s"
+
+#: elf64-alpha.c:460
+msgid "GPDISP relocation did not find ldah and lda instructions"
+msgstr "Ðе найдены инÑтрукции ldah и lda Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÐ¼ÐµÑ‰ÐµÐ½Ð¸Ñ GPDISP"
+
+#: elf64-alpha.c:2497
+msgid "%B: .got subsegment exceeds 64K (size %d)"
+msgstr "%B: подраздел .got превышает 64K (размер %d)"
+
+#: elf64-alpha.c:4387 elf64-alpha.c:4399
+msgid "%B: gp-relative relocation against dynamic symbol %s"
+msgstr "%B: gp-отноÑительное перемещение Ð´Ð»Ñ Ð´Ð¸Ð½Ð°Ð¼Ð¸Ñ‡ÐµÑкого Ñимвола %s"
+
+#: elf64-alpha.c:4425 elf64-alpha.c:4565
+msgid "%B: pc-relative relocation against dynamic symbol %s"
+msgstr "%B: pc-отноÑительное перемещение Ð´Ð»Ñ Ð´Ð¸Ð½Ð°Ð¼Ð¸Ñ‡ÐµÑкого Ñимвола %s"
+
+#: elf64-alpha.c:4453
+msgid "%B: change in gp: BRSGP %s"
+msgstr "%B: изменение в gp: BRSGP %s"
+
+#: elf64-alpha.c:4478
+msgid "<unknown>"
+msgstr "<неизвеÑтно>"
+
+#: elf64-alpha.c:4483
+msgid "%B: !samegp reloc against symbol without .prologue: %s"
+msgstr "%B: перемещение !samegp Ð´Ð»Ñ Ñимвола без .prologue: %s"
+
+#: elf64-alpha.c:4540
+msgid "%B: unhandled dynamic relocation against %s"
+msgstr "%B: необработанное динамичеÑкое перемещение Ð´Ð»Ñ %s"
+
+#: elf64-alpha.c:4572
+msgid "%B: pc-relative relocation against undefined weak symbol %s"
+msgstr "%B: pc-отноÑительное перемещение Ð´Ð»Ñ Ð½ÐµÐ¾Ð¿Ñ€ÐµÐ´ÐµÐ»Ñ‘Ð½Ð½Ð¾Ð³Ð¾ Ñлабого Ñимвола %s"
+
+#: elf64-alpha.c:4636
+msgid "%B: dtp-relative relocation against dynamic symbol %s"
+msgstr "%B: dtp-отноÑительное перемещение Ð´Ð»Ñ Ð´Ð¸Ð½Ð°Ð¼Ð¸Ñ‡ÐµÑкого Ñимвола %s"
+
+#: elf64-alpha.c:4659
+msgid "%B: tp-relative relocation against dynamic symbol %s"
+msgstr "%B: tp-отноÑительное перемещение Ð´Ð»Ñ Ð´Ð¸Ð½Ð°Ð¼Ð¸Ñ‡ÐµÑкого Ñимвола %s"
+
+#: elf64-hppa.c:2083
+#, c-format
+msgid "stub entry for %s cannot load .plt, dp offset = %ld"
+msgstr "Ñлемент заглушки Ð´Ð»Ñ %s не может загрузить .plt, Ñмещение dp = %ld"
+
+#: elf64-hppa.c:3275
+msgid "%B(%A+0x"
+msgstr "%B(%A+0x"
+
+#: elf64-mmix.c:1034
+msgid ""
+"invalid input relocation when producing non-ELF, non-mmo format output.\n"
+" Please use the objcopy program to convert from ELF or mmo,\n"
+" or assemble using \"-no-expand\" (for gcc, \"-Wa,-no-expand\""
+msgstr ""
+"неправильное входное перемещение при Ñоздании вывода в формате не-ELF и не-mmo.\n"
+" ИÑпользуйте программу objcopy Ð´Ð»Ñ Ð¿Ñ€ÐµÐ¾Ð±Ñ€Ð°Ð·Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¸Ð· ELF или mmo,\n"
+" или компилируйте Ñ Â«-no-expand» (Ð´Ð»Ñ gcc, «-Wa,-no-expand»"
+
+#: elf64-mmix.c:1218
+msgid ""
+"invalid input relocation when producing non-ELF, non-mmo format output.\n"
+" Please use the objcopy program to convert from ELF or mmo,\n"
+" or compile using the gcc-option \"-mno-base-addresses\"."
+msgstr ""
+"неправильное входное перемещение при Ñоздании вывода в формате не-ELF и не-mmo.\n"
+" ИÑпользуйте программу objcopy Ð´Ð»Ñ Ð¿Ñ€ÐµÐ¾Ð±Ñ€Ð°Ð·Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¸Ð· ELF или mmo,\n"
+" или компилируйте Ñ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ð¾Ð¼ gcc «-mno-base-addresses»."
+
+#: elf64-mmix.c:1244
+#, c-format
+msgid ""
+"%s: Internal inconsistency error for value for\n"
+" linker-allocated global register: linked: 0x%lx%08lx != relaxed: 0x%lx%08lx\n"
+msgstr ""
+"%s: Ошибка внутреннего неÑоответÑÑ‚Ð²Ð¸Ñ Ð´Ð»Ñ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ\n"
+" глобального региÑтра назначаемого компоновщиком: Ñкомпонован: 0x%lx%08lx != оÑлаблен: 0x%lx%08lx\n"
+
+#: elf64-mmix.c:1670
+#, c-format
+msgid "%s: base-plus-offset relocation against register symbol: (unknown) in %s"
+msgstr "%s: перемещение база-плюÑ-Ñмещение Ð´Ð»Ñ Ñ€ÐµÐ³Ð¸Ñтрового Ñимвола: (неизвеÑтно) в %s"
+
+#: elf64-mmix.c:1675
+#, c-format
+msgid "%s: base-plus-offset relocation against register symbol: %s in %s"
+msgstr "%s: перемещение база-плюÑ-Ñмещение Ð´Ð»Ñ Ñ€ÐµÐ³Ð¸Ñтрового Ñимвола: %s в %s"
+
+#: elf64-mmix.c:1719
+#, c-format
+msgid "%s: register relocation against non-register symbol: (unknown) in %s"
+msgstr "%s: региÑтровое перемещение Ð´Ð»Ñ Ð½ÐµÑ€ÐµÐ³Ð¸Ñтрового Ñимвола: (неизвеÑтно) в %s"
+
+#: elf64-mmix.c:1724
+#, c-format
+msgid "%s: register relocation against non-register symbol: %s in %s"
+msgstr "%s: региÑтровое перемещение Ð´Ð»Ñ Ð½ÐµÑ€ÐµÐ³Ð¸Ñтрового Ñимвола: %s в %s"
+
+#: elf64-mmix.c:1761
+#, c-format
+msgid "%s: directive LOCAL valid only with a register or absolute value"
+msgstr "%s: директива LOCAL разрешена только Ñ Ñ€ÐµÐ³Ð¸Ñтром или абÑолютным значением"
+
+#: elf64-mmix.c:1789
+#, c-format
+msgid "%s: LOCAL directive: Register $%ld is not a local register. First global register is $%ld."
+msgstr "%s: директива LOCAL: РегиÑÑ‚Ñ€ $%ld не ÑвлÑетÑÑ Ð»Ð¾ÐºÐ°Ð»ÑŒÐ½Ñ‹Ð¼ региÑтром. Первый глобальный региÑÑ‚Ñ€: $%ld."
+
+#: elf64-mmix.c:2253
+#, c-format
+msgid "%s: Error: multiple definition of `%s'; start of %s is set in a earlier linked file\n"
+msgstr "%s: Ошибка: множеÑтвенные объÑÐ²Ð»ÐµÐ½Ð¸Ñ Â«%s»; начало %s уÑтановлено в ранее Ñкомпонованном файле\n"
+
+#: elf64-mmix.c:2311
+msgid "Register section has contents\n"
+msgstr "Ð’ региÑтровом разделе имеетÑÑ Ñодержимое\n"
+
+#: elf64-mmix.c:2503
+#, c-format
+msgid ""
+"Internal inconsistency: remaining %u != max %u.\n"
+" Please report this bug."
+msgstr ""
+"Внутреннее противоречие: оÑтаётÑÑ %u != Ð¼Ð°ÐºÑ %u.\n"
+" Сообщите об ошибке."
+
+#: elf64-ppc.c:4185
+msgid "%P: %B: cannot create stub entry %s\n"
+msgstr "%P: %B: невозможно Ñоздать Ñлемент заглушки %s\n"
+
+#: elf64-ppc.c:6518
+msgid "%P: copy reloc against `%s' requires lazy plt linking; avoid setting LD_BIND_NOW=1 or upgrade gcc\n"
+msgstr "%P: копирование Ð¿ÐµÑ€ÐµÐ¼ÐµÑ‰ÐµÐ½Ð¸Ñ Ð´Ð»Ñ Â«%s» требует ленивой plt-компоновки; не задавайте LD_BIND_NOW=1 или обновите gcc\n"
+
+#: elf64-ppc.c:6788
+msgid "%B: undefined symbol on R_PPC64_TOCSAVE relocation"
+msgstr "%B: неопределённый Ñимвол по перемещению R_PPC64_TOCSAVE"
+
+#: elf64-ppc.c:6992
+msgid "%P: dynreloc miscount for %B, section %A\n"
+msgstr "%P: ошибка в вычиÑлении dynreloc %B, раздел %A\n"
+
+#: elf64-ppc.c:7076
+msgid "%B: .opd is not a regular array of opd entries"
+msgstr "%B: .opd не ÑвлÑетÑÑ Ð¾Ð±Ñ‹Ñ‡Ð½Ñ‹Ð¼ маÑÑивом Ñлементов opd"
+
+#: elf64-ppc.c:7085
+msgid "%B: unexpected reloc type %u in .opd section"
+msgstr "%B: неожиданный тип Ð¿ÐµÑ€ÐµÐ¼ÐµÑ‰ÐµÐ½Ð¸Ñ %u в разделе .opd"
+
+#: elf64-ppc.c:7106
+msgid "%B: undefined sym `%s' in .opd section"
+msgstr "%B: неопределённый Ñимвол «%s» в разделе .opd"
+
+#: elf64-ppc.c:7664
+msgid "%H __tls_get_addr lost arg, TLS optimization disabled\n"
+msgstr "%H __tls_get_addr без аргумента, Ð¾Ð¿Ñ‚Ð¸Ð¼Ð¸Ð·Ð°Ñ†Ð¸Ñ TLS выключена\n"
+
+#: elf64-ppc.c:8003 elf64-ppc.c:8564
+#, c-format
+msgid "%s defined on removed toc entry"
+msgstr "%s определён на удалённом Ñлементе toc"
+
+#: elf64-ppc.c:8521
+msgid "%P: %H: %s relocation references optimized away TOC entry\n"
+msgstr "%P: %H: перемещение %s ÑÑылаетÑÑ Ð½Ð° удалённый оптимизатором Ñлемент TOC\n"
+
+#: elf64-ppc.c:9598
+msgid "%P: cannot find opd entry toc for %s\n"
+msgstr "%P: не удалоÑÑŒ найти opd Ñлемента toc Ð´Ð»Ñ %s\n"
+
+#: elf64-ppc.c:9680
+msgid "%P: long branch stub `%s' offset overflow\n"
+msgstr "%P: переполнение ÑÐ¼ÐµÑ‰ÐµÐ½Ð¸Ñ Ð·Ð°Ð³Ð»ÑƒÑˆÐºÐ¸ длинного Ð²ÐµÑ‚Ð²Ð»ÐµÐ½Ð¸Ñ Â«%s»\n"
+
+#: elf64-ppc.c:9739
+msgid "%P: can't find branch stub `%s'\n"
+msgstr "%P: не найдена заглушка Ð²ÐµÑ‚Ð²Ð»ÐµÐ½Ð¸Ñ Â«%s»\n"
+
+#: elf64-ppc.c:9801 elf64-ppc.c:9943
+msgid "%P: linkage table error against `%s'\n"
+msgstr "%P: ошибка в таблице компоновки Ð´Ð»Ñ Â«%s»\n"
+
+#: elf64-ppc.c:10126
+msgid "%P: can't build branch stub `%s'\n"
+msgstr "%P: невозможно Ñобрать заглушку Ð²ÐµÑ‚Ð²Ð»ÐµÐ½Ð¸Ñ Â«%s»\n"
+
+#: elf64-ppc.c:10941
+msgid "%B section %A exceeds stub group size"
+msgstr "%B раздел %A превышает групповой размер заглушки"
+
+#: elf64-ppc.c:11666 elf64-ppc.c:11699
+msgid "%P: %s offset too large for .eh_frame sdata4 encoding"
+msgstr "%P: Ñмещение %s Ñлишком больше Ð´Ð»Ñ ÐºÐ¾Ð´Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ sdata4 в .eh_frame"
+
+#: elf64-ppc.c:11744
+msgid "%P: stubs don't match calculated size\n"
+msgstr "%P: заглушки не ÑоответÑтвуют вычиÑленному размеру\n"
+
+#: elf64-ppc.c:11756
+#, c-format
+msgid ""
+"linker stubs in %u group%s\n"
+" branch %lu\n"
+" toc adjust %lu\n"
+" long branch %lu\n"
+" long toc adj %lu\n"
+" plt call %lu"
+msgstr ""
+"заглушки компоновщика в %u группе%s\n"
+" ветвление %lu\n"
+" иÑправление toc %lu\n"
+" длинное ветвление %lu\n"
+" иÑправление длинного long %lu\n"
+" plt-вызов %lu"
+
+#: elf64-ppc.c:12042
+msgid "%P: %H: %s used with TLS symbol %s\n"
+msgstr "%P: %H: %s иÑпользуетÑÑ Ñ TLS-Ñимволом %s\n"
+
+#: elf64-ppc.c:12043
+msgid "%P: %H: %s used with non-TLS symbol %s\n"
+msgstr "%P: %H: %s иÑпользуетÑÑ Ñ Ð½Ðµ-TLS Ñимволом %s\n"
+
+#: elf64-ppc.c:12556
+msgid "%P: %H: automatic multiple TOCs not supported using your crt files; recompile with -mminimal-toc or upgrade gcc\n"
+msgstr "%P: %H: автоматичеÑкие множеÑтвенные TOC не поддерживаютÑÑ Ñ‡ÐµÑ€ÐµÐ· ваши файлы crt; перекомпилируйте Ñ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ð¾Ð¼ -mminimal-toc или обновите gcc\n"
+
+#: elf64-ppc.c:12562
+msgid "%P: %H: sibling call optimization to `%s' does not allow automatic multiple TOCs; recompile with -mminimal-toc or -fno-optimize-sibling-calls, or make `%s' extern\n"
+msgstr "%P: %H: Ð¾Ð¿Ñ‚Ð¸Ð¼Ð¸Ð·Ð°Ñ†Ð¸Ñ Ð¾Ð´Ð½Ð¾ÑƒÑ€Ð¾Ð²Ð½ÐµÐ²Ñ‹Ñ… вызовов к «%s» не позволÑет автоматичеÑкие множеÑтвенные TOC; перекомпилируйте Ñ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ð¾Ð¼ -mminimal-toc или -fno-optimize-sibling-calls, или Ñоздайте внешний «%s»\n"
+
+#: elf64-ppc.c:13286
+msgid "%P: %B: relocation %s is not supported for symbol %s\n"
+msgstr "%P: %B: перемещение %s не поддерживаетÑÑ Ð´Ð»Ñ Ñимвола %s\n"
+
+#: elf64-ppc.c:13446
+msgid "%P: %H: error: %s not a multiple of %u\n"
+msgstr "%P: %H: ошибка: %s не кратно %u\n"
+
+#: elf64-sh64.c:1686
+#, c-format
+msgid "%s: error: unaligned relocation type %d at %08x reloc %08x\n"
+msgstr "%s: ошибка: невыровненный тип Ð¿ÐµÑ€ÐµÐ¼ÐµÑ‰ÐµÐ½Ð¸Ñ %d по адреÑу %08x перемещение %08x\n"
+
+#: elf64-sparc.c:446
+msgid "%B: Only registers %%g[2367] can be declared using STT_REGISTER"
+msgstr "%B: Только региÑтры %%g[2367] могут объÑвлÑÑ‚ÑŒÑÑ Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ STT_REGISTER"
+
+#: elf64-sparc.c:466
+msgid "Register %%g%d used incompatibly: %s in %B, previously %s in %B"
+msgstr "ÐеÑовмеÑтимое иÑпользование региÑтра %%g%d: %s в %B, ранее %s в %B"
+
+#: elf64-sparc.c:489
+msgid "Symbol `%s' has differing types: REGISTER in %B, previously %s in %B"
+msgstr "Символ «%s» имеет различные типы: REGISTER в %B, ранее %s в %B"
+
+#: elf64-sparc.c:534
+msgid "Symbol `%s' has differing types: %s in %B, previously REGISTER in %B"
+msgstr "Символ «%s» имеет различные типы: %s в %B, ранее REGISTER в %B"
+
+#: elf64-sparc.c:687
+msgid "%B: linking UltraSPARC specific with HAL specific code"
+msgstr "%B: UltraSPARC-ÑÐ¿ÐµÑ†Ð¸Ñ„Ð¸Ñ‡Ð½Ð°Ñ ÐºÐ¾Ð¼Ð¿Ð¾Ð½Ð¾Ð²ÐºÐ° Ñ HAL-Ñпецифичным кодом"
+
+#: elf64-x86-64.c:1427
+msgid "%B: relocation %s against symbol `%s' isn't supported in x32 mode"
+msgstr "%B: перемещение %s Ð´Ð»Ñ Ñимвола «%s» не поддерживаетÑÑ Ð² режиме x32"
+
+#: elf64-x86-64.c:1656
+msgid "%B: '%s' accessed both as normal and thread local symbol"
+msgstr "%B: «%s» доÑтупен как обычный и как локальный Ð´Ð»Ñ Ð½Ð¸Ñ‚Ð¸ Ñимвол"
+
+#: elf64-x86-64.c:3150
+msgid "%B: relocation %s against STT_GNU_IFUNC symbol `%s' has non-zero addend: %d"
+msgstr "%B: перемещение %s вмеÑте Ñ STT_GNU_IFUNC Ñимволом «%s» имеет ненулевое добавление: %d"
+
+#: elf64-x86-64.c:3411
+msgid "%B: relocation R_X86_64_GOTOFF64 against protected function `%s' can not be used when making a shared object"
+msgstr "%B: перемещение R_X86_64_GOTOFF64 Ð´Ð»Ñ Ð·Ð°Ñ‰Ð¸Ñ‰Ñ‘Ð½Ð½Ð¾Ð¹ функции «%s» не может иÑпользоватьÑÑ Ð¿Ñ€Ð¸ Ñоздании общего объекта"
+
+#: elf64-x86-64.c:3523
+msgid "; recompile with -fPIC"
+msgstr "; перекомпилируйте Ñ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ð¾Ð¼ -fPIC"
+
+#: elf64-x86-64.c:3528
+msgid "%B: relocation %s against %s `%s' can not be used when making a shared object%s"
+msgstr "%B: перемещение %s Ð´Ð»Ñ %s «%s» не может иÑпользоватьÑÑ Ð¿Ñ€Ð¸ Ñоздании общего объекта(ов)"
+
+#: elf64-x86-64.c:3530
+msgid "%B: relocation %s against undefined %s `%s' can not be used when making a shared object%s"
+msgstr "%B: перемещение %s Ð´Ð»Ñ Ð½ÐµÐ¾Ð¿Ñ€ÐµÐ´ÐµÐ»Ñ‘Ð½Ð½Ð¾Ð³Ð¾ %s «%s» не может иÑпользоватьÑÑ Ð¿Ñ€Ð¸ Ñоздании общего объекта(ов)"
+
+#: elfcode.h:767
+#, c-format
+msgid "warning: %s has a corrupt string table index - ignoring"
+msgstr "предупреждение: у %s повреждена таблица индекÑов Ñтрок — игнорируетÑÑ"
+
+#: elfcode.h:1177
+#, c-format
+msgid "%s: version count (%ld) does not match symbol count (%ld)"
+msgstr "%s: Ñчётчик верÑии (%ld) не Ñовпадает Ñо Ñчётчиком Ñимвола (%ld)"
+
+#: elfcode.h:1431
+#, c-format
+msgid "%s(%s): relocation %d has invalid symbol index %ld"
+msgstr "%s(%s): перемещение %d имеет недопуÑтимый Ð¸Ð½Ð´ÐµÐºÑ Ñимвола %ld"
+
+#: elfcore.h:312
+msgid "Warning: %B is truncated: expected core file size >= %lu, found: %lu."
+msgstr "Предупреждение: %B уÑечён: ожидалÑÑ Ñ€Ð°Ð·Ð¼ÐµÑ€ Ñдра файла >= %lu, найдено: %lu."
+
+#: elflink.c:1117
+msgid "%s: TLS definition in %B section %A mismatches non-TLS definition in %B section %A"
+msgstr "%s: TLS-определение в %B раздела %A не Ñовпадает Ñ Ð½Ðµ-TLS определением в %B раздела %A"
+
+#: elflink.c:1121
+msgid "%s: TLS reference in %B mismatches non-TLS reference in %B"
+msgstr "%s: TLS-ÑÑылка в %B не Ñовпадает Ñ Ð½Ðµ-TLS ÑÑылкой в %B"
+
+#: elflink.c:1125
+msgid "%s: TLS definition in %B section %A mismatches non-TLS reference in %B"
+msgstr "%s: TLS-определение в %B раздела %A не Ñовпадает Ñ Ð½Ðµ-TLS ÑÑылкой в %B"
+
+#: elflink.c:1129
+msgid "%s: TLS reference in %B mismatches non-TLS definition in %B section %A"
+msgstr "%s: TLS-ÑÑылка в %B не Ñовпадает Ñ Ð½Ðµ-TLS определением в %B раздела %A"
+
+#: elflink.c:1762
+msgid "%B: unexpected redefinition of indirect versioned symbol `%s'"
+msgstr "%B: неожиданное переопределение коÑвенного верÑионного Ñимвола «%s»"
+
+#: elflink.c:2063
+msgid "%B: version node not found for symbol %s"
+msgstr "%B: верÑÐ¸Ñ ÑƒÐ·Ð»Ð° не найдена Ð´Ð»Ñ Ñимвола %s"
+
+#: elflink.c:2154
+msgid "%B: bad reloc symbol index (0x%lx >= 0x%lx) for offset 0x%lx in section `%A'"
+msgstr "%B: неправильный Ð¸Ð½Ð´ÐµÐºÑ Ð¿ÐµÑ€ÐµÐ¼ÐµÑ‰Ð°ÐµÐ¼Ð¾Ð³Ð¾ Ñимвола (0x%lx >= 0x%lx) Ð´Ð»Ñ ÑÐ¼ÐµÑ‰ÐµÐ½Ð¸Ñ 0x%lx в разделе «%A»"
+
+#: elflink.c:2165
+msgid "%B: non-zero symbol index (0x%lx) for offset 0x%lx in section `%A' when the object file has no symbol table"
+msgstr "%B: ненулевой Ð¸Ð½Ð´ÐµÐºÑ Ñимвола (0x%lx) Ð´Ð»Ñ ÑÐ¼ÐµÑ‰ÐµÐ½Ð¸Ñ 0x%lx в разделе «%A», в то Ð²Ñ€ÐµÐ¼Ñ ÐºÐ°Ðº в объектном файле нет таблицы Ñимволов"
+
+#: elflink.c:2355
+msgid "%B: relocation size mismatch in %B section %A"
+msgstr "%B: размер Ð¿ÐµÑ€ÐµÐ¼ÐµÑ‰ÐµÐ½Ð¸Ñ Ð½Ðµ Ñовпадает в %B раздела %A"
+
+#: elflink.c:2639
+#, c-format
+msgid "warning: type and size of dynamic symbol `%s' are not defined"
+msgstr "предупреждение: тип и размер динамичеÑкого Ñимвола «%s» не определён"
+
+#: elflink.c:3391
+msgid "%P: alternate ELF machine code found (%d) in %B, expecting %d\n"
+msgstr "%P: обнаружен альтернативный машинный код ELF (%d) в %B, ожидаетÑÑ %d\n"
+
+#: elflink.c:4037
+msgid "%B: %s: invalid version %u (max %d)"
+msgstr "%B: %s: недопуÑÑ‚Ð¸Ð¼Ð°Ñ Ð²ÐµÑ€ÑÐ¸Ñ %u (Ð¼Ð°ÐºÑ %d)"
+
+#: elflink.c:4073
+msgid "%B: %s: invalid needed version %d"
+msgstr "%B: %s: недопуÑÑ‚Ð¸Ð¼Ð°Ñ Ð½ÐµÐ¾Ð±Ñ…Ð¾Ð´Ð¸Ð¼Ð°Ñ Ð²ÐµÑ€ÑÐ¸Ñ %d"
+
+#: elflink.c:4269
+msgid "Warning: alignment %u of common symbol `%s' in %B is greater than the alignment (%u) of its section %A"
+msgstr "Предупреждение: выравнивание %u общего Ñимвола «%s» в %B больше, чем выравнивание (%u) его раздела %A"
+
+#: elflink.c:4275
+msgid "Warning: alignment %u of symbol `%s' in %B is smaller than %u in %B"
+msgstr "Предупреждение: выравнивание %u Ñимвола «%s» в %B меньше, чем %u в %B"
+
+#: elflink.c:4290
+msgid "Warning: size of symbol `%s' changed from %lu in %B to %lu in %B"
+msgstr "Предупреждение: размер Ñимвола «%s» изменилÑÑ Ñ %lu в %B на %lu в %B"
+
+#: elflink.c:4463
+msgid "%B: undefined reference to symbol '%s'"
+msgstr "%B: Ð½ÐµÐ¾Ð¿Ñ€ÐµÐ´ÐµÐ»Ñ‘Ð½Ð½Ð°Ñ ÑÑылка на Ñимвол «%s»"
+
+#: elflink.c:4466
+msgid "note: '%s' is defined in DSO %B so try adding it to the linker command line"
+msgstr "замечание: «%s» определён в DSO %B, попробуйте добавить его в командную Ñтроку компоновщика"
+
+#: elflink.c:5781
+#, c-format
+msgid "%s: undefined version: %s"
+msgstr "%s: Ð½ÐµÐ¾Ð¿Ñ€ÐµÐ´ÐµÐ»Ñ‘Ð½Ð½Ð°Ñ Ð²ÐµÑ€ÑиÑ: %s"
+
+#: elflink.c:5849
+msgid "%B: .preinit_array section is not allowed in DSO"
+msgstr "%B: раздел .preinit_array не разрешаетÑÑ Ð² DSO"
+
+#: elflink.c:7604
+#, c-format
+msgid "undefined %s reference in complex symbol: %s"
+msgstr "Ð½ÐµÐ¾Ð¿Ñ€ÐµÐ´ÐµÐ»Ñ‘Ð½Ð½Ð°Ñ ÑÑылка %s в Ñложном Ñимволе: %s"
+
+#: elflink.c:7758
+#, c-format
+msgid "unknown operator '%c' in complex symbol"
+msgstr "неизвеÑтный оператор '%c' в Ñложном Ñимволе"
+
+#: elflink.c:8097 elflink.c:8114 elflink.c:8151 elflink.c:8168
+msgid "%B: Unable to sort relocs - they are in more than one size"
+msgstr "%B: Ðевозможно отÑортировать Ð¿ÐµÑ€ÐµÐ¼ÐµÑ‰ÐµÐ½Ð¸Ñ - они разных размеров"
+
+#: elflink.c:8128 elflink.c:8182
+msgid "%B: Unable to sort relocs - they are of an unknown size"
+msgstr "%B: Ðевозможно отÑортировать Ð¿ÐµÑ€ÐµÐ¼ÐµÑ‰ÐµÐ½Ð¸Ñ - они неизвеÑтного размера"
+
+#: elflink.c:8233
+msgid "Not enough memory to sort relocations"
+msgstr "ÐедоÑтаточно памÑти Ð´Ð»Ñ Ñортировки перемещений"
+
+#: elflink.c:8426
+msgid "%B: Too many sections: %d (>= %d)"
+msgstr "%B: Слишком много разделов: %d (>= %d)"
+
+#: elflink.c:8675
+msgid "%B: internal symbol `%s' in %B is referenced by DSO"
+msgstr "%B: на внутренний Ñимвол «%s» из %B ÑÑылаютÑÑ Ð¸Ð· DSO"
+
+#: elflink.c:8677
+msgid "%B: hidden symbol `%s' in %B is referenced by DSO"
+msgstr "%B: на Ñкрытый Ñимвол «%s» из %B ÑÑылаютÑÑ Ð¸Ð· DSO"
+
+#: elflink.c:8679
+msgid "%B: local symbol `%s' in %B is referenced by DSO"
+msgstr "%B: на локальный Ñимвол «%s» из %B ÑÑылаютÑÑ Ð¸Ð· DSO"
+
+#: elflink.c:8776
+msgid "%B: could not find output section %A for input section %A"
+msgstr "%B: невозможно найти выходной раздел %A Ð´Ð»Ñ Ð²Ñ…Ð¾Ð´Ð½Ð¾Ð³Ð¾ раздела %A"
+
+#: elflink.c:8899
+msgid "%B: protected symbol `%s' isn't defined"
+msgstr "%B: защищённый Ñимвол «%s» не определён"
+
+#: elflink.c:8901
+msgid "%B: internal symbol `%s' isn't defined"
+msgstr "%B: внутренний Ñимвол «%s» не определён"
+
+#: elflink.c:8903
+msgid "%B: hidden symbol `%s' isn't defined"
+msgstr "%B: Ñкрытый Ñимвол «%s» не определён"
+
+#: elflink.c:9432
+msgid "error: %B: size of section %A is not multiple of address size"
+msgstr "ошибка: %B: размер раздела %A не кратен размеру адреÑа"
+
+#: elflink.c:9479
+msgid "error: %B contains a reloc (0x%s) for section %A that references a non-existent global symbol"
+msgstr "ошибка: %B Ñодержит перемещение (0x%s) Ð´Ð»Ñ Ñ€Ð°Ð·Ð´ÐµÐ»Ð° %A, который ÑÑылаетÑÑ Ð½Ð° неÑущеÑтвующий глобальный Ñимвол"
+
+#: elflink.c:10214
+msgid "%A has both ordered [`%A' in %B] and unordered [`%A' in %B] sections"
+msgstr "%A Ñодержит упорÑдоченные [«%A» в %B] и неупорÑдоченные [«%A» в %B] разделы"
+
+#: elflink.c:10219
+#, c-format
+msgid "%A has both ordered and unordered sections"
+msgstr "%A Ñодержит упорÑдоченные и неупорÑдоченные разделы"
+
+#: elflink.c:10784
+msgid "%B: file class %s incompatible with %s"
+msgstr "%B: файловый клаÑÑ %s неÑовмеÑтим Ñ %s"
+
+#: elflink.c:11093 elflink.c:11137
+msgid "%B: could not find output section %s"
+msgstr "%B: невозможно найти выходной раздел %s"
+
+#: elflink.c:11098
+#, c-format
+msgid "warning: %s section has zero size"
+msgstr "предупреждение: раздел %s имеет нулевой размер"
+
+#: elflink.c:11143
+#, c-format
+msgid "warning: section '%s' is being made into a note"
+msgstr "предупреждение: раздел «%s» преобразуетÑÑ Ð² примечание"
+
+#: elflink.c:11212
+msgid "%P%X: read-only segment has dynamic relocations.\n"
+msgstr "%P%X: в Ñегменте, доÑтупном только Ð´Ð»Ñ Ñ‡Ñ‚ÐµÐ½Ð¸Ñ, ÑодержатÑÑ Ð´Ð¸Ð½Ð°Ð¼Ð¸Ñ‡ÐµÑкие перемещениÑ.\n"
+
+#: elflink.c:11215
+msgid "%P: warning: creating a DT_TEXTREL in a shared object.\n"
+msgstr "%P: предупреждение: ÑоздаётÑÑ DT_TEXTREL в общем объекте.\n"
+
+#: elflink.c:11402
+msgid "%P%X: can not read symbols: %E\n"
+msgstr "%P%X: невозможно прочитать Ñимволы: %E\n"
+
+#: elflink.c:11792
+msgid "Removing unused section '%s' in file '%B'"
+msgstr "УдалÑетÑÑ Ð½ÐµÐ¸Ñпользуемый раздел '%s' в файле '%B'"
+
+#: elflink.c:11998
+msgid "Warning: gc-sections option ignored"
+msgstr "Предупреждение: параметр gc-sections игнорируетÑÑ"
+
+#: elflink.c:12277
+#, c-format
+msgid "Unrecognized INPUT_SECTION_FLAG %s\n"
+msgstr "ÐераÑпознанный INPUT_SECTION_FLAG %s\n"
+
+#: elfxx-mips.c:1234
+msgid "static procedure (no name)"
+msgstr "ÑтатичеÑÐºÐ°Ñ Ð¿Ñ€Ð¾Ñ†ÐµÐ´ÑƒÑ€Ð° (без имени)"
+
+#: elfxx-mips.c:5259
+msgid "MIPS16 and microMIPS functions cannot call each other"
+msgstr "Функции MIPS16 и microMIPS не могут вызывать друг друга"
+
+#: elfxx-mips.c:5856
+msgid "%B: %A+0x%lx: Direct jumps between ISA modes are not allowed; consider recompiling with interlinking enabled."
+msgstr "%B: %A+0x%lx: прÑмые переходы между режимами ISA недопуÑтимы; попробуйте перекомпилировать Ñ Ð²ÐºÐ»ÑŽÑ‡Ñ‘Ð½Ð½Ð¾Ð¹ увÑзкой."
+
+#: elfxx-mips.c:6519 elfxx-mips.c:6742
+msgid "%B: Warning: bad `%s' option size %u smaller than its header"
+msgstr "%B: предупреждение: размер параметра «%s» (%u) меньше, чем его заголовок"
+
+#: elfxx-mips.c:7495 elfxx-mips.c:7620
+msgid "%B: Warning: cannot determine the target function for stub section `%s'"
+msgstr "%B: Предупреждение: невозможно определить функцию Ð½Ð°Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ Ð´Ð»Ñ Ñ€Ð°Ð·Ð´ÐµÐ»Ð° заглушки «%s»"
+
+#: elfxx-mips.c:7749
+msgid "%B: Malformed reloc detected for section %s"
+msgstr "%B: Обнаружено иÑкажённое перемещение в разделе %s"
+
+#: elfxx-mips.c:7801
+msgid "%B: GOT reloc at 0x%lx not expected in executables"
+msgstr "%B: перемещение GOT по адреÑу 0x%lx не ожидаетÑÑ Ð² иÑполнÑемых файлах"
+
+#: elfxx-mips.c:7930
+msgid "%B: CALL16 reloc at 0x%lx not against global symbol"
+msgstr "%B: перемещение CALL16 по адреÑу 0x%lx не предназначено Ð´Ð»Ñ Ð³Ð»Ð¾Ð±Ð°Ð»ÑŒÐ½Ð¾Ð³Ð¾ Ñимвола"
+
+#: elfxx-mips.c:8645
+#, c-format
+msgid "non-dynamic relocations refer to dynamic symbol %s"
+msgstr "не-динамичеÑкие Ð¿ÐµÑ€ÐµÐ¼ÐµÑ‰ÐµÐ½Ð¸Ñ ÑƒÐºÐ°Ð·Ñ‹Ð²Ð°ÑŽÑ‚ на динамичеÑкий Ñимвол %s"
+
+#: elfxx-mips.c:9347
+msgid "%B: Can't find matching LO16 reloc against `%s' for %s at 0x%lx in section `%A'"
+msgstr "%B: Ðевозможно найти подходÑщее LO16 перемещение у «%s» Ð´Ð»Ñ %s по адреÑу 0x%lx в разделе «%A»"
+
+#: elfxx-mips.c:9486
+msgid "small-data section exceeds 64KB; lower small-data size limit (see option -G)"
+msgstr "раздел small-data превышает 64КБ — нижний предел small-data (Ñм. параметр -G)"
+
+#: elfxx-mips.c:9505
+msgid "JALX to a non-word-aligned address"
+msgstr "ВыполнÑетÑÑ JALX в адреÑ, невыровненный по границе Ñлова"
+
+#: elfxx-mips.c:13266
+#, c-format
+msgid "%s: illegal section name `%s'"
+msgstr "%s: недопуÑтимое Ð¸Ð¼Ñ Ñ€Ð°Ð·Ð´ÐµÐ»Ð° «%s»"
+
+#: elfxx-mips.c:13645 elfxx-mips.c:13671
+msgid "Warning: %B uses -msingle-float, %B uses -mdouble-float"
+msgstr "Предупреждение: %B иÑпользует -msingle-float, %B иÑпользует -mdouble-float"
+
+#: elfxx-mips.c:13657 elfxx-mips.c:13713
+msgid "Warning: %B uses -msingle-float, %B uses -mips32r2 -mfp64"
+msgstr "Предупреждение: %B иÑпользует -msingle-float, %B иÑпользует -mips32r2 -mfp64"
+
+#: elfxx-mips.c:13683 elfxx-mips.c:13719
+msgid "Warning: %B uses -mdouble-float, %B uses -mips32r2 -mfp64"
+msgstr "Предупреждение: %B иÑпользует -mdouble-float, %B иÑпользует -mips32r2 -mfp64"
+
+#: elfxx-mips.c:13761
+msgid "%B: endianness incompatible with that of the selected emulation"
+msgstr "%B: порÑдок байт не ÑовмеÑтим Ñ Ð²Ñ‹Ð±Ñ€Ð°Ð½Ð½Ñ‹Ð¼ в ÑмулÑции"
+
+#: elfxx-mips.c:13772
+msgid "%B: ABI is incompatible with that of the selected emulation"
+msgstr "%B: ABI не ÑовмеÑтим Ñ Ð²Ñ‹Ð±Ñ€Ð°Ð½Ð½Ñ‹Ð¼ в ÑмулÑции"
+
+#: elfxx-mips.c:13856
+msgid "%B: warning: linking abicalls files with non-abicalls files"
+msgstr "%B: предупреждение: компоновка файлов abicalls Ñ Ñ„Ð°Ð¹Ð»Ð°Ð¼Ð¸ не-abicalls"
+
+#: elfxx-mips.c:13873
+msgid "%B: linking 32-bit code with 64-bit code"
+msgstr "%B: компоновка 32-битного кода Ñ 64-битным кодом"
+
+#: elfxx-mips.c:13901
+msgid "%B: linking %s module with previous %s modules"
+msgstr "%B: компоновка Ð¼Ð¾Ð´ÑƒÐ»Ñ %s Ñ Ð¿Ñ€ÐµÐ´Ñ‹Ð´ÑƒÑ‰Ð¸Ð¼Ð¸ модулÑми %s"
+
+#: elfxx-mips.c:13924
+msgid "%B: ABI mismatch: linking %s module with previous %s modules"
+msgstr "%B: неÑовпадение ABI: компоновка Ð¼Ð¾Ð´ÑƒÐ»Ñ %s Ñ Ð¿Ñ€ÐµÐ´Ñ‹Ð´ÑƒÑ‰Ð¸Ð¼Ð¸ модулÑми %s"
+
+#: elfxx-mips.c:13948
+msgid "%B: ASE mismatch: linking %s module with previous %s modules"
+msgstr "%B: неÑовпадение ASE: компоновка Ð¼Ð¾Ð´ÑƒÐ»Ñ %s Ñ Ð¿Ñ€ÐµÐ´Ñ‹Ð´ÑƒÑ‰Ð¸Ð¼Ð¸ модулÑми %s"
+
+#: elfxx-mips.c:14106
+#, c-format
+msgid " [abi=O32]"
+msgstr " [abi=O32]"
+
+#: elfxx-mips.c:14108
+#, c-format
+msgid " [abi=O64]"
+msgstr " [abi=O64]"
+
+#: elfxx-mips.c:14110
+#, c-format
+msgid " [abi=EABI32]"
+msgstr " [abi=EABI32]"
+
+#: elfxx-mips.c:14112
+#, c-format
+msgid " [abi=EABI64]"
+msgstr " [abi=EABI64]"
+
+#: elfxx-mips.c:14114
+#, c-format
+msgid " [abi unknown]"
+msgstr " [abi неизвеÑтен]"
+
+#: elfxx-mips.c:14116
+#, c-format
+msgid " [abi=N32]"
+msgstr " [abi=N32]"
+
+#: elfxx-mips.c:14118
+#, c-format
+msgid " [abi=64]"
+msgstr " [abi=64]"
+
+#: elfxx-mips.c:14120
+#, c-format
+msgid " [no abi set]"
+msgstr " [abi не задан]"
+
+#: elfxx-mips.c:14141
+#, c-format
+msgid " [unknown ISA]"
+msgstr " [неизвеÑтный ISA]"
+
+#: elfxx-mips.c:14155
+#, c-format
+msgid " [not 32bitmode]"
+msgstr " [не 32-битный режим]"
+
+#: elfxx-sparc.c:596
+#, c-format
+msgid "invalid relocation type %d"
+msgstr "недопуÑтимый тип Ð¿ÐµÑ€ÐµÐ¼ÐµÑ‰ÐµÐ½Ð¸Ñ %d"
+
+#: elfxx-tilegx.c:3952
+msgid "%B: Cannot link together %s and %s objects."
+msgstr "%B: невозможно Ñкомпоновать объекты %s и %s вмеÑте."
+
+#: i386linux.c:451 m68klinux.c:456 sparclinux.c:450
+#, c-format
+msgid "Output file requires shared library `%s'\n"
+msgstr "Ð”Ð»Ñ Ð²Ñ‹Ñ…Ð¾Ð´Ð½Ð¾Ð³Ð¾ файла требуетÑÑ Ð¾Ð±Ñ‰Ð°Ñ Ð±Ð¸Ð±Ð»Ð¸Ð¾Ñ‚ÐµÐºÐ° «%s»\n"
+
+#: i386linux.c:459 m68klinux.c:464 sparclinux.c:458
+#, c-format
+msgid "Output file requires shared library `%s.so.%s'\n"
+msgstr "Ð”Ð»Ñ Ð²Ñ‹Ñ…Ð¾Ð´Ð½Ð¾Ð³Ð¾ файла требуетÑÑ Ð¾Ð±Ñ‰Ð°Ñ Ð±Ð¸Ð±Ð»Ð¸Ð¾Ñ‚ÐµÐºÐ° «%s.so.%s»\n"
+
+#: i386linux.c:648 i386linux.c:698 m68klinux.c:656 m68klinux.c:704
+#: sparclinux.c:648 sparclinux.c:698
+#, c-format
+msgid "Symbol %s not defined for fixups\n"
+msgstr "Символ %s не определён Ð´Ð»Ñ Ð¼ÐµÑтоположений\n"
+
+#: i386linux.c:722 m68klinux.c:728 sparclinux.c:722
+msgid "Warning: fixup count mismatch\n"
+msgstr "Предупреждение: не Ñовпадает Ñчётчик меÑтоположениÑ\n"
+
+#: ieee.c:159
+#, c-format
+msgid "%s: string too long (%d chars, max 65535)"
+msgstr "%s: Ñлишком Ð´Ð»Ð¸Ð½Ð½Ð°Ñ Ñтрока (%d Ñимволов, макÑ. 65535)"
+
+#: ieee.c:286
+#, c-format
+msgid "%s: unrecognized symbol `%s' flags 0x%x"
+msgstr "%s: нераÑпознанные флаги Ñимвола «%s» (0x%x)"
+
+#: ieee.c:792
+msgid "%B: unimplemented ATI record %u for symbol %u"
+msgstr "%B: Ð½ÐµÑ€ÐµÐ°Ð»Ð¸Ð·Ð¾Ð²Ð°Ð½Ð½Ð°Ñ ATI-запиÑÑŒ %u Ð´Ð»Ñ Ñимвола %u"
+
+#: ieee.c:816
+msgid "%B: unexpected ATN type %d in external part"
+msgstr "%B: неожиданный ATN-тип %d во внешней чаÑти"
+
+#: ieee.c:838
+msgid "%B: unexpected type after ATN"
+msgstr "%B: неожиданный тип поÑле ATN"
+
+#: ihex.c:230
+msgid "%B:%d: unexpected character `%s' in Intel Hex file"
+msgstr "%B:%d: неожиданный Ñимвол «%s» в Intel Hex файле"
+
+#: ihex.c:337
+msgid "%B:%u: bad checksum in Intel Hex file (expected %u, found %u)"
+msgstr "%B:%u: Ð½ÐµÐ¿Ñ€Ð°Ð²Ð¸Ð»ÑŒÐ½Ð°Ñ ÐºÐ¾Ð½Ñ‚Ñ€Ð¾Ð»ÑŒÐ½Ð°Ñ Ñумма в Intel Hex файле (должна быть %u, получена %u)"
+
+#: ihex.c:392
+msgid "%B:%u: bad extended address record length in Intel Hex file"
+msgstr "%B:%u: Ð½ÐµÐ¿Ñ€Ð°Ð²Ð¸Ð»ÑŒÐ½Ð°Ñ Ð´Ð»Ð¸Ð½Ð° запиÑи раÑширенного адреÑа в Intel Hex файле"
+
+#: ihex.c:409
+msgid "%B:%u: bad extended start address length in Intel Hex file"
+msgstr "%B:%u: Ð½ÐµÐ¿Ñ€Ð°Ð²Ð¸Ð»ÑŒÐ½Ð°Ñ Ð´Ð»Ð¸Ð½Ð° раÑширенного начального адреÑа в Intel Hex файле"
+
+#: ihex.c:426
+msgid "%B:%u: bad extended linear address record length in Intel Hex file"
+msgstr "%B:%u: Ð½ÐµÐ¿Ñ€Ð°Ð²Ð¸Ð»ÑŒÐ½Ð°Ñ Ð´Ð»Ð¸Ð½Ð° запиÑи раÑширенного прÑмолинейного адреÑа в Intel Hex файле"
+
+#: ihex.c:443
+msgid "%B:%u: bad extended linear start address length in Intel Hex file"
+msgstr "%B:%u: Ð½ÐµÐ¿Ñ€Ð°Ð²Ð¸Ð»ÑŒÐ½Ð°Ñ Ð´Ð»Ð¸Ð½Ð° раÑширенного прÑмолинейного начального адреÑа в Intel Hex файле"
+
+#: ihex.c:460
+msgid "%B:%u: unrecognized ihex type %u in Intel Hex file"
+msgstr "%B:%u: нераÑпознанный ihex-тип %u в Intel Hex файле"
+
+#: ihex.c:579
+msgid "%B: internal error in ihex_read_section"
+msgstr "%B: внутреннÑÑ Ð¾ÑˆÐ¸Ð±ÐºÐ° в ihex_read_section"
+
+#: ihex.c:613
+msgid "%B: bad section length in ihex_read_section"
+msgstr "%B: Ð½ÐµÐ¿Ñ€Ð°Ð²Ð¸Ð»ÑŒÐ½Ð°Ñ Ð´Ð»Ð¸Ð½Ð° раздела в ihex_read_section"
+
+#: ihex.c:826
+#, c-format
+msgid "%s: address 0x%s out of range for Intel Hex file"
+msgstr "%s: Ð°Ð´Ñ€ÐµÑ 0x%s вне диапазона Ð´Ð»Ñ Intel Hex файла"
+
+#: libbfd.c:863
+msgid "%B: unable to get decompressed section %A"
+msgstr "Ошибка в dwarf: не удалоÑÑŒ получить раÑжатый раздел %A"
+
+#: libbfd.c:1012
+msgid "%B: compiled for a big endian system and target is little endian"
+msgstr "%B: Ñкомпилировано Ð´Ð»Ñ ÑиÑтемы Ñ Ð¿Ñ€Ñмым порÑдком байт, а цель Ñ Ð¾Ð±Ñ€Ð°Ñ‚Ð½Ñ‹Ð¼ порÑдком байт"
+
+#: libbfd.c:1014
+msgid "%B: compiled for a little endian system and target is big endian"
+msgstr "%B: Ñкомпилировано Ð´Ð»Ñ ÑиÑтемы Ñ Ð¾Ð±Ñ€Ð°Ñ‚Ð½Ñ‹Ð¼ порÑдком байт, а цель Ñ Ð¿Ñ€Ñмым порÑдком байт"
+
+#: libbfd.c:1043
+#, c-format
+msgid "Deprecated %s called at %s line %d in %s\n"
+msgstr "Вызван нерекомендуемый %s Ñ€Ñдом Ñ %s в Ñтроке %d в %s\n"
+
+#: libbfd.c:1046
+#, c-format
+msgid "Deprecated %s called\n"
+msgstr "Вызван нерекомендуемый %s\n"
+
+#: linker.c:1872
+msgid "%B: indirect symbol `%s' to `%s' is a loop"
+msgstr "%B: коÑвенный Ñимвол «%s» к «%s» Ñоздаёт зацикливание"
+
+#: linker.c:2736
+#, c-format
+msgid "Attempt to do relocatable link with %s input and %s output"
+msgstr "Попытка Ñделать перемещаемую ÑÑылку Ñ Ð²Ñ…Ð¾Ð´Ð¾Ð¼ %s и выходом %s"
+
+#: linker.c:3021
+msgid "%B: ignoring duplicate section `%A'\n"
+msgstr "%B: игнорируетÑÑ Ð¿Ð¾Ð²Ñ‚Ð¾Ñ€ÑющийÑÑ Ñ€Ð°Ð·Ð´ÐµÐ» «%A»\n"
+
+#: linker.c:3030 linker.c:3039
+msgid "%B: duplicate section `%A' has different size\n"
+msgstr "%B: повторÑющийÑÑ Ñ€Ð°Ð·Ð´ÐµÐ» «%A» имеет другой размер\n"
+
+#: linker.c:3047 linker.c:3052
+msgid "%B: could not read contents of section `%A'\n"
+msgstr "%B: предупреждение: невозможно прочитать Ñодержимое раздела «%A»\n"
+
+#: linker.c:3056
+msgid "%B: duplicate section `%A' has different contents\n"
+msgstr "%B: предупреждение: повторÑющийÑÑ Ñ€Ð°Ð·Ð´ÐµÐ» «%A» имеет другое Ñодержимое\n"
+
+#: mach-o.c:407
+msgid "bfd_mach_o_canonicalize_symtab: unable to load symbols"
+msgstr "bfd_mach_o_canonicalize_symtab: невозможно загрузить Ñимволы"
+
+#: mach-o.c:1301
+#, c-format
+msgid "unable to write unknown load command 0x%lx"
+msgstr "невозможно запиÑать неизвеÑтную команду загрузки 0x%lx"
+
+#: mach-o.c:1789
+#, c-format
+msgid "bfd_mach_o_read_symtab_symbol: unable to read %d bytes at %lu"
+msgstr "bfd_mach_o_read_symtab_symbol: невозможно прочитать %d байт из %lu"
+
+#: mach-o.c:1807
+#, c-format
+msgid "bfd_mach_o_read_symtab_symbol: name out of range (%lu >= %lu)"
+msgstr "bfd_mach_o_read_symtab_symbol: Ð¸Ð¼Ñ Ð²Ð½Ðµ диапазона (%lu >= %lu)"
+
+#: mach-o.c:1892
+#, c-format
+msgid "bfd_mach_o_read_symtab_symbol: symbol \"%s\" specified invalid section %d (max %lu): setting to undefined"
+msgstr "bfd_mach_o_read_symtab_symbol: Ñимвол «%s» указывает на неверный раздел %d (макÑимальное значение %lu): наÑтройка не определена"
+
+#: mach-o.c:1900
+#, c-format
+msgid "bfd_mach_o_read_symtab_symbol: symbol \"%s\" is unsupported 'indirect' reference: setting to undefined"
+msgstr "bfd_mach_o_read_symtab_symbol: Ñимвол «%s» ÑвлÑетÑÑ Ð½ÐµÐ¿Ð¾Ð´Ð´ÐµÑ€Ð¶Ð¸Ð²Ð°ÐµÐ¼Ð¾Ð¹ «неÑвной» ÑÑылкой: наÑтройка не определена"
+
+#: mach-o.c:1906
+#, c-format
+msgid "bfd_mach_o_read_symtab_symbol: symbol \"%s\" specified invalid type field 0x%x: setting to undefined"
+msgstr "bfd_mach_o_read_symtab_symbol: Ñимвол «%s» указывает на неверный тип Ð¿Ð¾Ð»Ñ 0x%x: наÑтройка не определена"
+
+#: mach-o.c:1979
+msgid "bfd_mach_o_read_symtab_symbols: unable to allocate memory for symbols"
+msgstr "bfd_mach_o_read_symtab_symbols: невозможно выделить памÑÑ‚ÑŒ Ð´Ð»Ñ Ñимволов"
+
+#: mach-o.c:2014
+#, c-format
+msgid "bfd_mach_o_read_dysymtab_symbol: unable to read %lu bytes at %lu"
+msgstr "bfd_mach_o_read_dysymtab_symbol: невозможно прочитать %lu байт из %lu"
+
+#: mach-o.c:2734
+#, c-format
+msgid "unable to read unknown load command 0x%lx"
+msgstr "невозможно прочитать неизвеÑтную команду загрузки 0x%lx"
+
+#: mach-o.c:2915
+#, c-format
+msgid "bfd_mach_o_scan: unknown architecture 0x%lx/0x%lx"
+msgstr "bfd_mach_o_scan: неизвеÑÑ‚Ð½Ð°Ñ Ð°Ñ€Ñ…Ð¸Ñ‚ÐµÐºÑ‚ÑƒÑ€Ð° 0x%lx/0x%lx"
+
+#: mach-o.c:3011
+#, c-format
+msgid "unknown header byte-order value 0x%lx"
+msgstr "неизвеÑтное значение порÑдка байт в заголовке 0x%lx"
+
+#: mach-o.c:3577
+msgid "Mach-O header:\n"
+msgstr "заголовок Mach-O:\n"
+
+#: mach-o.c:3578
+#, c-format
+msgid " magic : %08lx\n"
+msgstr " отл.призн : %08lx\n"
+
+#: mach-o.c:3579
+#, c-format
+msgid " cputype : %08lx (%s)\n"
+msgstr " тип ЦП : %08lx (%s)\n"
+
+#: mach-o.c:3581
+#, c-format
+msgid " cpusubtype: %08lx\n"
+msgstr " подтип ЦП : %08lx\n"
+
+#: mach-o.c:3582
+#, c-format
+msgid " filetype : %08lx (%s)\n"
+msgstr " тип файла : %08lx (%s)\n"
+
+#: mach-o.c:3585
+#, c-format
+msgid " ncmds : %08lx (%lu)\n"
+msgstr " ч_кмнд : %08lx (%lu)\n"
+
+#: mach-o.c:3586
+#, c-format
+msgid " sizeofcmds: %08lx\n"
+msgstr " разм_кмнд : %08lx\n"
+
+#: mach-o.c:3587
+#, c-format
+msgid " flags : %08lx ("
+msgstr " флаги : %08lx ("
+
+#: mach-o.c:3589 vms-alpha.c:7674
+msgid ")\n"
+msgstr ")\n"
+
+#: mach-o.c:3590
+#, c-format
+msgid " reserved : %08x\n"
+msgstr " зарезерв : %08x\n"
+
+#: mach-o.c:3600
+msgid "Segments and Sections:\n"
+msgstr "Сегменты и разделы:\n"
+
+#: mach-o.c:3601
+msgid " #: Segment name Section name Address\n"
+msgstr ""
+" #: Segment name Section name Address\n"
+" #: Ðазвание Ñегм Ðазвание раздела ÐдреÑ\n"
+
+#: merge.c:832
+#, c-format
+msgid "%s: access beyond end of merged section (%ld)"
+msgstr "%s: доÑтуп за конец объединённого раздела (%ld)"
+
+#: mmo.c:456
+#, c-format
+msgid "%s: No core to allocate section name %s\n"
+msgstr "%s: Ðет оÑÐ½Ð¾Ð²Ð°Ð½Ð¸Ñ Ð´Ð»Ñ Ð²Ñ‹Ð´ÐµÐ»ÐµÐ½Ð¸Ñ Ð¸Ð¼ÐµÐ½Ð¸ раздела %s\n"
+
+#: mmo.c:531
+#, c-format
+msgid "%s: No core to allocate a symbol %d bytes long\n"
+msgstr "%s: Ðет оÑÐ½Ð¾Ð²Ð°Ð½Ð¸Ñ Ð´Ð»Ñ Ð²Ñ‹Ð´ÐµÐ»ÐµÐ½Ð¸Ñ Ñимвольных %d байт\n"
+
+#: mmo.c:1187
+#, c-format
+msgid "%s: invalid mmo file: initialization value for $255 is not `Main'\n"
+msgstr "%s: недопуÑтимый mmo-файл: инициализационное значение Ð´Ð»Ñ $255 не равно «Main»\n"
+
+#: mmo.c:1332
+#, c-format
+msgid "%s: unsupported wide character sequence 0x%02X 0x%02X after symbol name starting with `%s'\n"
+msgstr "%s: Ð½ÐµÐ¿Ð¾Ð´Ð´ÐµÑ€Ð¶Ð¸Ð²Ð°ÐµÐ¼Ð°Ñ Ð¿Ð¾ÑледовательноÑÑ‚ÑŒ широких Ñимволов 0x%02X 0x%02X поÑле имени Ñимвола, начинающегоÑÑ Ñ Â«%s»\n"
+
+#: mmo.c:1565
+#, c-format
+msgid "%s: invalid mmo file: unsupported lopcode `%d'\n"
+msgstr "%s: недопуÑтимый mmo-файл: неподдерживаемый lopcode «%d»\n"
+
+#: mmo.c:1575
+#, c-format
+msgid "%s: invalid mmo file: expected YZ = 1 got YZ = %d for lop_quote\n"
+msgstr "%s: недопуÑтимый mmo-файл: ожидалоÑÑŒ YZ = 1, получено YZ = %d Ð´Ð»Ñ lop_quote\n"
+
+#: mmo.c:1611
+#, c-format
+msgid "%s: invalid mmo file: expected z = 1 or z = 2, got z = %d for lop_loc\n"
+msgstr "%s: недопуÑтимый mmo-файл: ожидалоÑÑŒ z = 1 или z = 2, получено z = %d Ð´Ð»Ñ lop_loc\n"
+
+#: mmo.c:1657
+#, c-format
+msgid "%s: invalid mmo file: expected z = 1 or z = 2, got z = %d for lop_fixo\n"
+msgstr "%s: недопуÑтимый mmo-файл: ожидалоÑÑŒ z = 1 или z = 2, получено z = %d Ð´Ð»Ñ lop_fixo\n"
+
+#: mmo.c:1696
+#, c-format
+msgid "%s: invalid mmo file: expected y = 0, got y = %d for lop_fixrx\n"
+msgstr "%s: недопуÑтимый mmo-файл: ожидалоÑÑŒ y = 0, получено y = %d Ð´Ð»Ñ lop_fixrx\n"
+
+#: mmo.c:1705
+#, c-format
+msgid "%s: invalid mmo file: expected z = 16 or z = 24, got z = %d for lop_fixrx\n"
+msgstr "%s: недопуÑтимый mmo-файл: ожидалоÑÑŒ z = 16 или z = 24, получено z = %d Ð´Ð»Ñ lop_fixrx\n"
+
+#: mmo.c:1728
+#, c-format
+msgid "%s: invalid mmo file: leading byte of operand word must be 0 or 1, got %d for lop_fixrx\n"
+msgstr "%s: недопуÑтимый mmo-файл: начальный байт Ñлова операнда должен быть равен 0 или 1, получено %d Ð´Ð»Ñ lop_fixrx\n"
+
+#: mmo.c:1751
+#, c-format
+msgid "%s: cannot allocate file name for file number %d, %d bytes\n"
+msgstr "%s: невозможно выделить меÑто Ð´Ð»Ñ Ð¸Ð¼ÐµÐ½Ð¸ файла к файлу Ñ Ð½Ð¾Ð¼ÐµÑ€Ð¾Ð¼ %d, %d байт\n"
+
+#: mmo.c:1771
+#, c-format
+msgid "%s: invalid mmo file: file number %d `%s', was already entered as `%s'\n"
+msgstr "%s: недопуÑтимый mmo-файл: номер файла %d «%s», был уже введён как «%s»\n"
+
+#: mmo.c:1784
+#, c-format
+msgid "%s: invalid mmo file: file name for number %d was not specified before use\n"
+msgstr "%s: недопуÑтимый mmo-файл: Ð¸Ð¼Ñ Ñ„Ð°Ð¹Ð»Ð° Ð´Ð»Ñ Ð½Ð¾Ð¼ÐµÑ€Ð° %d не указано перед иÑпользованием\n"
+
+#: mmo.c:1890
+#, c-format
+msgid "%s: invalid mmo file: fields y and z of lop_stab non-zero, y: %d, z: %d\n"
+msgstr "%s: недопуÑтимый mmo-файл: Ð¿Ð¾Ð»Ñ y и z в lop_stab не равны нулю, y: %d, z: %d\n"
+
+#: mmo.c:1926
+#, c-format
+msgid "%s: invalid mmo file: lop_end not last item in file\n"
+msgstr "%s: недопуÑтимый mmo-файл: lop_end не поÑледний Ñлемент в файле\n"
+
+#: mmo.c:1939
+#, c-format
+msgid "%s: invalid mmo file: YZ of lop_end (%ld) not equal to the number of tetras to the preceding lop_stab (%ld)\n"
+msgstr "%s: недопуÑтимый mmo-файл: YZ в lop_end (%ld) не равно чиÑлу тетрад в указанной ранее lop_stab (%ld)\n"
+
+#: mmo.c:2649
+#, c-format
+msgid "%s: invalid symbol table: duplicate symbol `%s'\n"
+msgstr "%s: ошибка в таблице Ñимволов: повторÑющийÑÑ Ñимвол «%s»\n"
+
+#: mmo.c:2889
+#, c-format
+msgid "%s: Bad symbol definition: `Main' set to %s rather than the start address %s\n"
+msgstr "%s: Ðеверное определение Ñимвола: «Main» уÑтановлена в %s, а не в начальный Ð°Ð´Ñ€ÐµÑ %s\n"
+
+#: mmo.c:2981
+#, c-format
+msgid "%s: warning: symbol table too large for mmo, larger than 65535 32-bit words: %d. Only `Main' will be emitted.\n"
+msgstr "%s: предупреждение: таблица Ñимволов Ñлишком Ð±Ð¾Ð»ÑŒÑˆÐ°Ñ Ð´Ð»Ñ mmo, больше чем 65535 32-битных Ñлов: %d. Будет выделена только «Main».\n"
+
+#: mmo.c:3026
+#, c-format
+msgid "%s: internal error, symbol table changed size from %d to %d words\n"
+msgstr "%s: внутреннÑÑ Ð¾ÑˆÐ¸Ð±ÐºÐ°, у таблицы Ñимволов изменилÑÑ Ñ€Ð°Ð·Ð¼ÐµÑ€ Ñ %d Ñлов до %d\n"
+
+#: mmo.c:3078
+#, c-format
+msgid "%s: internal error, internal register section %s had contents\n"
+msgstr "%s: внутреннÑÑ Ð¾ÑˆÐ¸Ð±ÐºÐ°, внутренний раздел региÑтров %s Ñодержит данные\n"
+
+#: mmo.c:3129
+#, c-format
+msgid "%s: no initialized registers; section length 0\n"
+msgstr "%s:нет инициализированных региÑтров; длина раздела равна 0\n"
+
+#: mmo.c:3135
+#, c-format
+msgid "%s: too many initialized registers; section length %ld\n"
+msgstr "%s: Ñлишком много инициализированных региÑтров; длина раздела равна %ld\n"
+
+#: mmo.c:3140
+#, c-format
+msgid "%s: invalid start address for initialized registers of length %ld: 0x%lx%08lx\n"
+msgstr "%s: недопуÑтимый начальный Ð°Ð´Ñ€ÐµÑ Ð´Ð»Ñ Ð¸Ð½Ð¸Ñ†Ð¸Ð°Ð»Ð¸Ð·Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð½Ñ‹Ñ… региÑтров длины %ld: 0x%lx%08lx\n"
+
+#: oasys.c:882
+#, c-format
+msgid "%s: can not represent section `%s' in oasys"
+msgstr "%s: невозможно предÑтавить раздел «%s» в oasys"
+
+#: osf-core.c:140
+#, c-format
+msgid "Unhandled OSF/1 core file section type %d\n"
+msgstr "Ðеобработанный файл Ñдра OSF/1 раздела Ñ Ñ‚Ð¸Ð¿Ð¾Ð¼ %d\n"
+
+#: pe-mips.c:607
+msgid "%B: `ld -r' not supported with PE MIPS objects\n"
+msgstr "%B: «ld -r» не поддерживаетÑÑ Ñ Ð¾Ð±ÑŠÐµÐºÑ‚Ð°Ð¼Ð¸ PE MIPS\n"
+
+#. OK, at this point the following variables are set up:
+#. src = VMA of the memory we're fixing up
+#. mem = pointer to memory we're fixing up
+#. val = VMA of what we need to refer to.
+#: pe-mips.c:719
+msgid "%B: unimplemented %s\n"
+msgstr "%B: не реализовано %s\n"
+
+#: pe-mips.c:745
+msgid "%B: jump too far away\n"
+msgstr "%B: точка перехода Ñлишком далеко\n"
+
+#: pe-mips.c:771
+msgid "%B: bad pair/reflo after refhi\n"
+msgstr "%B: Ð½ÐµÐ²ÐµÑ€Ð½Ð°Ñ pair/reflo поÑле refhi\n"
+
+#: pef.c:520
+#, c-format
+msgid "bfd_pef_scan: unknown architecture 0x%lx"
+msgstr "bfd_pef_scan: неизвеÑÑ‚Ð½Ð°Ñ Ð°Ñ€Ñ…Ð¸Ñ‚ÐµÐºÑ‚ÑƒÑ€Ð° 0x%lx"
+
+#: pei-x86_64.c:444
+#, c-format
+msgid "warning: .pdata section size (%ld) is not a multiple of %d\n"
+msgstr "предупреждение: размер раздела .pdata (%ld) не кратен %d\n"
+
+#: pei-x86_64.c:448 peigen.c:1618 peigen.c:1801 pepigen.c:1618 pepigen.c:1801
+#: pex64igen.c:1618 pex64igen.c:1801
+#, c-format
+msgid ""
+"\n"
+"The Function Table (interpreted .pdata section contents)\n"
+msgstr ""
+"\n"
+"Таблица функций (обработан раздел .pdata)\n"
+
+#: pei-x86_64.c:450
+#, c-format
+msgid "vma:\t\t\tBeginAddress\t EndAddress\t UnwindData\n"
+msgstr "vma:\t\t\tÐач Ð°Ð´Ñ€ÐµÑ \t Кон адреÑ\t РаÑкр данные\n"
+
+#. XXX code yet to be written.
+#: peicode.h:751
+msgid "%B: Unhandled import type; %x"
+msgstr "%B: Ðеобработанный тип импорта; %x"
+
+#: peicode.h:756
+msgid "%B: Unrecognised import type; %x"
+msgstr "%B: ÐераÑпознанный тип импорта; %x"
+
+#: peicode.h:770
+msgid "%B: Unrecognised import name type; %x"
+msgstr "%B: ÐераÑпознанный именной тип импорта; %x"
+
+#: peicode.h:1166
+msgid "%B: Unrecognised machine type (0x%x) in Import Library Format archive"
+msgstr "%B: ÐераÑпознанный машинный тип (0x%x) в архиве Import Library Format"
+
+#: peicode.h:1178
+msgid "%B: Recognised but unhandled machine type (0x%x) in Import Library Format archive"
+msgstr "%B: РаÑпознан, но не обработан машинный тип (0x%x) в архиве Import Library Format"
+
+#: peicode.h:1196
+msgid "%B: size field is zero in Import Library Format header"
+msgstr "%B: размер Ð¿Ð¾Ð»Ñ Ñ€Ð°Ð²ÐµÐ½ нулю в заголовке Import Library Format"
+
+#: peicode.h:1227
+msgid "%B: string not null terminated in ILF object file."
+msgstr "%B: Ñтрока не заканчиваетÑÑ Ð½ÑƒÐ»Ñ‘Ð¼ в объектном файле ILF."
+
+#: ppcboot.c:414
+#, c-format
+msgid ""
+"\n"
+"ppcboot header:\n"
+msgstr ""
+"\n"
+"заголовок ppcboot:\n"
+
+#: ppcboot.c:415
+#, c-format
+msgid "Entry offset = 0x%.8lx (%ld)\n"
+msgstr "Ðачальное Ñмещение = 0x%.8lx (%ld)\n"
+
+#: ppcboot.c:417
+#, c-format
+msgid "Length = 0x%.8lx (%ld)\n"
+msgstr "Длина = 0x%.8lx (%ld)\n"
+
+#: ppcboot.c:421
+#, c-format
+msgid "Flag field = 0x%.2x\n"
+msgstr "Поле флагов = 0x%.2x\n"
+
+#: ppcboot.c:427
+#, c-format
+msgid "Partition name = \"%s\"\n"
+msgstr "Ð˜Ð¼Ñ Ñ€Ð°Ð·Ð´ÐµÐ»Ð° = \"%s\"\n"
+
+#: ppcboot.c:446
+#, c-format
+msgid ""
+"\n"
+"Partition[%d] start = { 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x }\n"
+msgstr ""
+"\n"
+"Ðачало раздела[%d] = { 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x }\n"
+
+#: ppcboot.c:452
+#, c-format
+msgid "Partition[%d] end = { 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x }\n"
+msgstr "Конец раздела[%d] = { 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x }\n"
+
+#: ppcboot.c:458
+#, c-format
+msgid "Partition[%d] sector = 0x%.8lx (%ld)\n"
+msgstr "Сектор раздела[%d] = 0x%.8lx (%ld)\n"
+
+#: ppcboot.c:460
+#, c-format
+msgid "Partition[%d] length = 0x%.8lx (%ld)\n"
+msgstr "Длина раздела[%d] = 0x%.8lx (%ld)\n"
+
+#: reloc.c:6160
+msgid "INPUT_SECTION_FLAGS are not supported.\n"
+msgstr "INPUT_SECTION_FLAGS не поддерживаетÑÑ.\n"
+
+#: rs6000-core.c:448
+#, c-format
+msgid "%s: warning core file truncated"
+msgstr "%s: предупреждение: файл core уÑечён"
+
+#: som.c:5471
+#, c-format
+msgid ""
+"\n"
+"Exec Auxiliary Header\n"
+msgstr ""
+"\n"
+"Ð’Ñпомогательный заголовок Exec\n"
+
+#: som.c:5776
+msgid "som_sizeof_headers unimplemented"
+msgstr "som_sizeof_headers не реализован"
+
+#: srec.c:261
+msgid "%B:%d: Unexpected character `%s' in S-record file\n"
+msgstr "%B:%d: Ðеожиданный Ñимвол «%s» в файле S-record\n"
+
+#: srec.c:567 srec.c:600
+msgid "%B:%d: Bad checksum in S-record file\n"
+msgstr "%B:%d: ÐÐµÐ²ÐµÑ€Ð½Ð°Ñ ÐºÐ¾Ð½Ñ‚Ñ€Ð¾Ð»ÑŒÐ½Ð°Ñ Ñумма в файле S-record\n"
+
+#: stabs.c:279
+msgid "%B(%A+0x%lx): Stabs entry has invalid string index."
+msgstr "%B(%A+0x%lx): Элемент Stabs имеет недопуÑтимый Ð¸Ð½Ð´ÐµÐºÑ Ñтроки."
+
+#: syms.c:1079
+msgid "Unsupported .stab relocation"
+msgstr "Ðеподдерживаемое перемещение .stab"
+
+#: vms-alpha.c:1299
+#, c-format
+msgid "Unknown EGSD subtype %d"
+msgstr "ÐеизвеÑтный подтип EGSD %d"
+
+#: vms-alpha.c:1330
+#, c-format
+msgid "Stack overflow (%d) in _bfd_vms_push"
+msgstr "Переполнение Ñтека (%d) в _bfd_vms_push"
+
+#: vms-alpha.c:1343
+msgid "Stack underflow in _bfd_vms_pop"
+msgstr "Выход за нижнюю границу Ñтека в _bfd_vms_pop"
+
+#. These names have not yet been added to this switch statement.
+#: vms-alpha.c:1580
+#, c-format
+msgid "unknown ETIR command %d"
+msgstr "неизвеÑÑ‚Ð½Ð°Ñ ETIR команда %d"
+
+#: vms-alpha.c:1767
+#, c-format
+msgid "bad section index in %s"
+msgstr "неверный Ð¸Ð½Ð´ÐµÐºÑ Ñ€Ð°Ð·Ð´ÐµÐ»Ð° в %s"
+
+#: vms-alpha.c:1780
+#, c-format
+msgid "unsupported STA cmd %s"
+msgstr "неподдерживаемый STA cmd %s"
+
+#. Insert field.
+#. Unsigned shift.
+#. Rotate.
+#. Redefine symbol to current location.
+#. Define a literal.
+#: vms-alpha.c:1956 vms-alpha.c:1987 vms-alpha.c:2234
+#, c-format
+msgid "%s: not supported"
+msgstr "%s: не поддерживаетÑÑ"
+
+#: vms-alpha.c:1962
+#, c-format
+msgid "%s: not implemented"
+msgstr "%s: не реализовано"
+
+#: vms-alpha.c:2218
+#, c-format
+msgid "invalid use of %s with contexts"
+msgstr "неправильное иÑпользование %s Ñ ÐºÐ¾Ð½Ñ‚ÐµÐºÑтами"
+
+#: vms-alpha.c:2252
+#, c-format
+msgid "reserved cmd %d"
+msgstr "зарезервированный cmd %d"
+
+#: vms-alpha.c:2337
+msgid "Object module NOT error-free !\n"
+msgstr "Объектный модуль ÐЕ error-free !\n"
+
+#: vms-alpha.c:2766
+#, c-format
+msgid "Symbol %s replaced by %s\n"
+msgstr "Символ %s заменён на %s\n"
+
+#: vms-alpha.c:3769
+#, c-format
+msgid "SEC_RELOC with no relocs in section %s"
+msgstr "SEC_RELOC без перемещений в разделе %s"
+
+#: vms-alpha.c:3822 vms-alpha.c:4049
+#, c-format
+msgid "Size error in section %s"
+msgstr "Ошибка размера в разделе %s"
+
+#: vms-alpha.c:3991
+msgid "Spurious ALPHA_R_BSR reloc"
+msgstr "Ðетипичное перемещение ALPHA_R_BSR"
+
+#: vms-alpha.c:4036
+#, c-format
+msgid "Unhandled relocation %s"
+msgstr "Ðеобработанное перемещение %s"
+
+#: vms-alpha.c:4326
+#, c-format
+msgid "unknown source command %d"
+msgstr "неизвеÑÑ‚Ð½Ð°Ñ Ð¸ÑÑ…Ð¾Ð´Ð½Ð°Ñ ÐºÐ¾Ð¼Ð°Ð½Ð´Ð° %d"
+
+#: vms-alpha.c:4387
+msgid "DST__K_SET_LINUM_INCR not implemented"
+msgstr "DST__K_SET_LINUM_INCR не реализован"
+
+#: vms-alpha.c:4393
+msgid "DST__K_SET_LINUM_INCR_W not implemented"
+msgstr "DST__K_SET_LINUM_INCR_W не реализован"
+
+#: vms-alpha.c:4399
+msgid "DST__K_RESET_LINUM_INCR not implemented"
+msgstr "DST__K_RESET_LINUM_INCR не реализован"
+
+#: vms-alpha.c:4405
+msgid "DST__K_BEG_STMT_MODE not implemented"
+msgstr "DST__K_BEG_STMT_MODE не реализован"
+
+#: vms-alpha.c:4411
+msgid "DST__K_END_STMT_MODE not implemented"
+msgstr "DST__K_END_STMT_MODE не реализован"
+
+#: vms-alpha.c:4438
+msgid "DST__K_SET_PC not implemented"
+msgstr "DST__K_SET_PC не реализован"
+
+#: vms-alpha.c:4444
+msgid "DST__K_SET_PC_W not implemented"
+msgstr "DST__K_SET_PC_W не реализован"
+
+#: vms-alpha.c:4450
+msgid "DST__K_SET_PC_L not implemented"
+msgstr "DST__K_SET_PC_L не реализован"
+
+#: vms-alpha.c:4456
+msgid "DST__K_SET_STMTNUM not implemented"
+msgstr "DST__K_SET_STMTNUM не реализован"
+
+#: vms-alpha.c:4499
+#, c-format
+msgid "unknown line command %d"
+msgstr "неизвеÑÑ‚Ð½Ð°Ñ Ñтрока команды %d"
+
+#: vms-alpha.c:4953 vms-alpha.c:4970 vms-alpha.c:4984 vms-alpha.c:4999
+#: vms-alpha.c:5011 vms-alpha.c:5022 vms-alpha.c:5034
+#, c-format
+msgid "Unknown reloc %s + %s"
+msgstr "ÐеизвеÑтное перемещение %s + %s"
+
+#: vms-alpha.c:5089
+#, c-format
+msgid "Unknown reloc %s"
+msgstr "ÐеизвеÑтное перемещение %s"
+
+#: vms-alpha.c:5102
+msgid "Invalid section index in ETIR"
+msgstr "Ðеверный Ð¸Ð½Ð´ÐµÐºÑ Ñ€Ð°Ð·Ð´ÐµÐ»Ð° в ETIR"
+
+#: vms-alpha.c:5109
+msgid "Relocation for non-REL psect"
+msgstr "Перемещение Ð´Ð»Ñ Ð½Ðµ-REL psect"
+
+#: vms-alpha.c:5156
+#, c-format
+msgid "Unknown symbol in command %s"
+msgstr "ÐеизвеÑтный Ñимвол в команде %s"
+
+#: vms-alpha.c:5671
+#, c-format
+msgid " EMH %u (len=%u): "
+msgstr " EMH %u (len=%u): "
+
+#: vms-alpha.c:5680
+#, c-format
+msgid "Module header\n"
+msgstr "Заголовок модулÑ\n"
+
+#: vms-alpha.c:5681
+#, c-format
+msgid " structure level: %u\n"
+msgstr " уровень Ñтруктуры : %u\n"
+
+#: vms-alpha.c:5682
+#, c-format
+msgid " max record size: %u\n"
+msgstr " макÑ. размер запиÑи: %u\n"
+
+#: vms-alpha.c:5685
+#, c-format
+msgid " module name : %.*s\n"
+msgstr " Ð¸Ð¼Ñ Ð¼Ð¾Ð´ÑƒÐ»Ñ : %.*s\n"
+
+#: vms-alpha.c:5687
+#, c-format
+msgid " module version : %.*s\n"
+msgstr " верÑÐ¸Ñ Ð¼Ð¾Ð´ÑƒÐ»Ñ : %.*s\n"
+
+#: vms-alpha.c:5689
+#, c-format
+msgid " compile date : %.17s\n"
+msgstr " дата компилÑции : %.17s\n"
+
+#: vms-alpha.c:5694
+#, c-format
+msgid "Language Processor Name\n"
+msgstr "Ðазвание процеÑÑорного Ñзыка\n"
+
+#: vms-alpha.c:5695
+#, c-format
+msgid " language name: %.*s\n"
+msgstr " название Ñзыка : %.*s\n"
+
+#: vms-alpha.c:5702
+#, c-format
+msgid "Source Files Header\n"
+msgstr "Заголовок иÑходных файлов\n"
+
+#: vms-alpha.c:5703
+#, c-format
+msgid " file: %.*s\n"
+msgstr " файл: %.*s\n"
+
+#: vms-alpha.c:5710
+#, c-format
+msgid "Title Text Header\n"
+msgstr "Заголовок Ð½Ð°Ð·Ð²Ð°Ð½Ð¸Ñ Ñ‚ÐµÐºÑта\n"
+
+#: vms-alpha.c:5711
+#, c-format
+msgid " title: %.*s\n"
+msgstr " название : %.*s\n"
+
+#: vms-alpha.c:5718
+#, c-format
+msgid "Copyright Header\n"
+msgstr "Заголовок авторÑкого права\n"
+
+#: vms-alpha.c:5719
+#, c-format
+msgid " copyright: %.*s\n"
+msgstr " авторÑкое право: %.*s\n"
+
+#: vms-alpha.c:5725
+#, c-format
+msgid "unhandled emh subtype %u\n"
+msgstr "необработанный подтип emh %u\n"
+
+#: vms-alpha.c:5735
+#, c-format
+msgid " EEOM (len=%u):\n"
+msgstr " EEOM (len=%u):\n"
+
+#: vms-alpha.c:5736
+#, c-format
+msgid " number of cond linkage pairs: %u\n"
+msgstr " кол-во уÑловно компонуемых пар: %u\n"
+
+#: vms-alpha.c:5738
+#, c-format
+msgid " completion code: %u\n"
+msgstr " завершённый код: %u\n"
+
+#: vms-alpha.c:5742
+#, c-format
+msgid " transfer addr flags: 0x%02x\n"
+msgstr " адреÑа передачи flags: 0x%02x\n"
+
+#: vms-alpha.c:5743
+#, c-format
+msgid " transfer addr psect: %u\n"
+msgstr " Ð°Ð´Ñ€ÐµÑ Ð¿ÐµÑ€ÐµÐ´Ð°Ñ‡Ð¸ psect: %u\n"
+
+#: vms-alpha.c:5745
+#, c-format
+msgid " transfer address : 0x%08x\n"
+msgstr " Ð°Ð´Ñ€ÐµÑ Ð¿ÐµÑ€ÐµÐ´Ð°Ñ‡Ð¸ : 0x%08x\n"
+
+#: vms-alpha.c:5754
+msgid " WEAK"
+msgstr " WEAK"
+
+#: vms-alpha.c:5756
+msgid " DEF"
+msgstr " DEF"
+
+#: vms-alpha.c:5758
+msgid " UNI"
+msgstr " UNI"
+
+#: vms-alpha.c:5760 vms-alpha.c:5781
+msgid " REL"
+msgstr " REL"
+
+#: vms-alpha.c:5762
+msgid " COMM"
+msgstr " COMM"
+
+#: vms-alpha.c:5764
+msgid " VECEP"
+msgstr " VECEP"
+
+#: vms-alpha.c:5766
+msgid " NORM"
+msgstr " NORM"
+
+#: vms-alpha.c:5768
+msgid " QVAL"
+msgstr " QVAL"
+
+#: vms-alpha.c:5775
+msgid " PIC"
+msgstr " PIC"
+
+#: vms-alpha.c:5777
+msgid " LIB"
+msgstr " LIB"
+
+#: vms-alpha.c:5779
+msgid " OVR"
+msgstr " OVR"
+
+#: vms-alpha.c:5783
+msgid " GBL"
+msgstr " GBL"
+
+#: vms-alpha.c:5785
+msgid " SHR"
+msgstr " SHR"
+
+#: vms-alpha.c:5787
+msgid " EXE"
+msgstr " EXE"
+
+#: vms-alpha.c:5789
+msgid " RD"
+msgstr " RD"
+
+#: vms-alpha.c:5791
+msgid " WRT"
+msgstr " WRT"
+
+#: vms-alpha.c:5793
+msgid " VEC"
+msgstr " VEC"
+
+#: vms-alpha.c:5795
+msgid " NOMOD"
+msgstr " NOMOD"
+
+#: vms-alpha.c:5797
+msgid " COM"
+msgstr " COM"
+
+#: vms-alpha.c:5799
+msgid " 64B"
+msgstr " 64B"
+
+#: vms-alpha.c:5808
+#, c-format
+msgid " EGSD (len=%u):\n"
+msgstr " EGSD (len=%u):\n"
+
+#: vms-alpha.c:5820
+#, c-format
+msgid " EGSD entry %2u (type: %u, len: %u): "
+msgstr " запиÑÑŒ EGSD %2u (тип: %u, длина: %u): "
+
+#: vms-alpha.c:5832
+#, c-format
+msgid "PSC - Program section definition\n"
+msgstr "PSC - определение программного раздела\n"
+
+#: vms-alpha.c:5833 vms-alpha.c:5850
+#, c-format
+msgid " alignment : 2**%u\n"
+msgstr " выравнивание : 2**%u\n"
+
+#: vms-alpha.c:5834 vms-alpha.c:5851
+#, c-format
+msgid " flags : 0x%04x"
+msgstr " флаги : 0x%04x"
+
+#: vms-alpha.c:5838
+#, c-format
+msgid " alloc (len): %u (0x%08x)\n"
+msgstr " alloc (len): %u (0x%08x)\n"
+
+#: vms-alpha.c:5839 vms-alpha.c:5896 vms-alpha.c:5945
+#, c-format
+msgid " name : %.*s\n"
+msgstr " Ð¸Ð¼Ñ : %.*s\n"
+
+#: vms-alpha.c:5849
+#, c-format
+msgid "SPSC - Shared Image Program section def\n"
+msgstr "SPSC — определение программного раздела общего образа\n"
+
+#: vms-alpha.c:5855
+#, c-format
+msgid " alloc (len) : %u (0x%08x)\n"
+msgstr " alloc (len) : %u (0x%08x)\n"
+
+#: vms-alpha.c:5856
+#, c-format
+msgid " image offset : 0x%08x\n"
+msgstr " Ñмещение образа : 0x%08x\n"
+
+#: vms-alpha.c:5858
+#, c-format
+msgid " symvec offset : 0x%08x\n"
+msgstr " Ñмещение symvec: 0x%08x\n"
+
+#: vms-alpha.c:5860
+#, c-format
+msgid " name : %.*s\n"
+msgstr " Ð¸Ð¼Ñ : %.*s\n"
+
+#: vms-alpha.c:5873
+#, c-format
+msgid "SYM - Global symbol definition\n"
+msgstr "SYM - определение глобальных Ñимволов\n"
+
+#: vms-alpha.c:5874 vms-alpha.c:5934 vms-alpha.c:5955 vms-alpha.c:5974
+#, c-format
+msgid " flags: 0x%04x"
+msgstr " флаги: 0x%04x"
+
+#: vms-alpha.c:5877
+#, c-format
+msgid " psect offset: 0x%08x\n"
+msgstr " Ñмещение psect: 0x%08x\n"
+
+#: vms-alpha.c:5881
+#, c-format
+msgid " code address: 0x%08x\n"
+msgstr " Ð°Ð´Ñ€ÐµÑ ÐºÐ¾Ð´Ð°: 0x%08x\n"
+
+#: vms-alpha.c:5883
+#, c-format
+msgid " psect index for entry point : %u\n"
+msgstr " Ð¸Ð½Ð´ÐµÐºÑ psect Ð´Ð»Ñ Ñ‚Ð¾Ñ‡ÐºÐ¸ входа: %u\n"
+
+#: vms-alpha.c:5886 vms-alpha.c:5962 vms-alpha.c:5981
+#, c-format
+msgid " psect index : %u\n"
+msgstr " Ð¸Ð½Ð´ÐµÐºÑ psect: %u\n"
+
+#: vms-alpha.c:5888 vms-alpha.c:5964 vms-alpha.c:5983
+#, c-format
+msgid " name : %.*s\n"
+msgstr " Ð¸Ð¼Ñ : %.*s\n"
+
+#: vms-alpha.c:5895
+#, c-format
+msgid "SYM - Global symbol reference\n"
+msgstr "SYM - ÑÑылки глобальных Ñимволов\n"
+
+#: vms-alpha.c:5907
+#, c-format
+msgid "IDC - Ident Consistency check\n"
+msgstr "IDC - проверка идентификатора целоÑтноÑти\n"
+
+#: vms-alpha.c:5908
+#, c-format
+msgid " flags : 0x%08x"
+msgstr " флаги : 0x%08x"
+
+#: vms-alpha.c:5912
+#, c-format
+msgid " id match : %x\n"
+msgstr " id ÑоответÑÑ‚Ð²Ð¸Ñ : %x\n"
+
+#: vms-alpha.c:5914
+#, c-format
+msgid " error severity: %x\n"
+msgstr " ÑерьёзноÑÑ‚ÑŒ ошибки: %x\n"
+
+#: vms-alpha.c:5917
+#, c-format
+msgid " entity name : %.*s\n"
+msgstr " название категории: %.*s\n"
+
+#: vms-alpha.c:5919
+#, c-format
+msgid " object name : %.*s\n"
+msgstr " Ð¸Ð¼Ñ Ð¾Ð±ÑŠÐµÐºÑ‚Ð°: %.*s\n"
+
+#: vms-alpha.c:5922
+#, c-format
+msgid " binary ident : 0x%08x\n"
+msgstr " двоичный идентификатор: 0x%08x\n"
+
+#: vms-alpha.c:5925
+#, c-format
+msgid " ascii ident : %.*s\n"
+msgstr " ascii-идентификатор: %.*s\n"
+
+#: vms-alpha.c:5933
+#, c-format
+msgid "SYMG - Universal symbol definition\n"
+msgstr "SYMG - определение универÑальных Ñимволов\n"
+
+#: vms-alpha.c:5937
+#, c-format
+msgid " symbol vector offset: 0x%08x\n"
+msgstr " Ñмещение Ñимвольного вектора: 0x%08x\n"
+
+#: vms-alpha.c:5939
+#, c-format
+msgid " entry point: 0x%08x\n"
+msgstr " точка входа: 0x%08x\n"
+
+#: vms-alpha.c:5941
+#, c-format
+msgid " proc descr : 0x%08x\n"
+msgstr " proc descr : 0x%08x\n"
+
+#: vms-alpha.c:5943
+#, c-format
+msgid " psect index: %u\n"
+msgstr " Ð¸Ð½Ð´ÐµÐºÑ psect: %u\n"
+
+#: vms-alpha.c:5954
+#, c-format
+msgid "SYMV - Vectored symbol definition\n"
+msgstr "SYMV - определение векторных Ñимволов\n"
+
+#: vms-alpha.c:5958
+#, c-format
+msgid " vector : 0x%08x\n"
+msgstr " вектор : 0x%08x\n"
+
+#: vms-alpha.c:5960 vms-alpha.c:5979
+#, c-format
+msgid " psect offset: %u\n"
+msgstr " Ñмещение psect: %u\n"
+
+#: vms-alpha.c:5973
+#, c-format
+msgid "SYMM - Global symbol definition with version\n"
+msgstr "SYMM - определение глобальных Ñимволов Ñ Ð²ÐµÑ€Ñией\n"
+
+#: vms-alpha.c:5977
+#, c-format
+msgid " version mask: 0x%08x\n"
+msgstr " маÑка верÑии: 0x%08x\n"
+
+#: vms-alpha.c:5988
+#, c-format
+msgid "unhandled egsd entry type %u\n"
+msgstr "необработанный egsd-Ñлемент типа %u\n"
+
+#: vms-alpha.c:6022
+#, c-format
+msgid " linkage index: %u, replacement insn: 0x%08x\n"
+msgstr " Ð¸Ð½Ð´ÐµÐºÑ ÐºÐ¾Ð¼Ð¿Ð¾Ð½Ð¾Ð²ÐºÐ¸: %u, заменитель insn: 0x%08x\n"
+
+#: vms-alpha.c:6025
+#, c-format
+msgid " psect idx 1: %u, offset 1: 0x%08x %08x\n"
+msgstr " 1-й Ð¸Ð½Ð´ÐµÐºÑ psect: %u, 1-е Ñмещение: 0x%08x %08x\n"
+
+#: vms-alpha.c:6029
+#, c-format
+msgid " psect idx 2: %u, offset 2: 0x%08x %08x\n"
+msgstr " 2-й Ð¸Ð½Ð´ÐµÐºÑ psect: %u, 2-е Ñмещение: 0x%08x %08x\n"
+
+#: vms-alpha.c:6034
+#, c-format
+msgid " psect idx 3: %u, offset 3: 0x%08x %08x\n"
+msgstr " 3-й Ð¸Ð½Ð´ÐµÐºÑ psect: %u, 3-е Ñмещение: 0x%08x %08x\n"
+
+#: vms-alpha.c:6039
+#, c-format
+msgid " global name: %.*s\n"
+msgstr " глобальное имÑ: %.*s\n"
+
+#: vms-alpha.c:6049
+#, c-format
+msgid " %s (len=%u+%u):\n"
+msgstr " %s (len=%u+%u):\n"
+
+#: vms-alpha.c:6064
+#, c-format
+msgid " (type: %3u, size: 4+%3u): "
+msgstr " (тип: %3u, размер: 4+%3u): "
+
+#: vms-alpha.c:6068
+#, c-format
+msgid "STA_GBL (stack global) %.*s\n"
+msgstr "STA_GBL (глобальный Ñтек) %.*s\n"
+
+#: vms-alpha.c:6072
+#, c-format
+msgid "STA_LW (stack longword) 0x%08x\n"
+msgstr "STA_LW (Ñтек длинных Ñлов) 0x%08x\n"
+
+#: vms-alpha.c:6076
+#, c-format
+msgid "STA_QW (stack quadword) 0x%08x %08x\n"
+msgstr "STA_QW (Ñтек четверных Ñлов) 0x%08x %08x\n"
+
+#: vms-alpha.c:6081
+#, c-format
+msgid "STA_PQ (stack psect base + offset)\n"
+msgstr "STA_PQ (Ñтек psect база + Ñмещение)\n"
+
+#: vms-alpha.c:6082
+#, c-format
+msgid " psect: %u, offset: 0x%08x %08x\n"
+msgstr " psect: %u, Ñмещение: 0x%08x %08x\n"
+
+#: vms-alpha.c:6088
+#, c-format
+msgid "STA_LI (stack literal)\n"
+msgstr "STA_LI (Ñтек литерала)\n"
+
+#: vms-alpha.c:6091
+#, c-format
+msgid "STA_MOD (stack module)\n"
+msgstr "STA_MOD (Ñтек модулей)\n"
+
+#: vms-alpha.c:6094
+#, c-format
+msgid "STA_CKARG (compare procedure argument)\n"
+msgstr "STA_CKARG (аргумент процедуры ÑравнениÑ)\n"
+
+#: vms-alpha.c:6098
+#, c-format
+msgid "STO_B (store byte)\n"
+msgstr "STO_B (хранимый байт)\n"
+
+#: vms-alpha.c:6101
+#, c-format
+msgid "STO_W (store word)\n"
+msgstr "STO_W (хранимое Ñлово)\n"
+
+#: vms-alpha.c:6104
+#, c-format
+msgid "STO_LW (store longword)\n"
+msgstr "STO_LW (хранимое длинное Ñлово)\n"
+
+#: vms-alpha.c:6107
+#, c-format
+msgid "STO_QW (store quadword)\n"
+msgstr "STO_QW (хранимое учетверённое Ñлово)\n"
+
+#: vms-alpha.c:6113
+#, c-format
+msgid "STO_IMMR (store immediate repeat) %u bytes\n"
+msgstr "STO_IMMR (хранимый непоÑредÑтвенный повтор) %u байт\n"
+
+#: vms-alpha.c:6120
+#, c-format
+msgid "STO_GBL (store global) %.*s\n"
+msgstr "STO_GBL (Ñ…Ñ€Ð°Ð½Ð¸Ð¼Ð°Ñ Ð³Ð»Ð¾Ð±Ð°Ð»ÑŒÐ½Ð°Ñ) %.*s\n"
+
+#: vms-alpha.c:6124
+#, c-format
+msgid "STO_CA (store code address) %.*s\n"
+msgstr "STO_CA (хранимый Ð°Ð´Ñ€ÐµÑ ÐºÐ¾Ð´Ð°) %.*s\n"
+
+#: vms-alpha.c:6128
+#, c-format
+msgid "STO_RB (store relative branch)\n"
+msgstr "STO_RB (хранимое отноÑительное ветвление)\n"
+
+#: vms-alpha.c:6131
+#, c-format
+msgid "STO_AB (store absolute branch)\n"
+msgstr "STO_AB (хранимое абÑолютное ветвление)\n"
+
+#: vms-alpha.c:6134
+#, c-format
+msgid "STO_OFF (store offset to psect)\n"
+msgstr "STO_OFF (хранимое Ñмещение на psect)\n"
+
+#: vms-alpha.c:6140
+#, c-format
+msgid "STO_IMM (store immediate) %u bytes\n"
+msgstr "STO_IMM (Ñ…Ñ€Ð°Ð½Ð¸Ð¼Ð°Ñ Ð½ÐµÐ¿Ð¾ÑредÑтвенно) %u байт\n"
+
+#: vms-alpha.c:6147
+#, c-format
+msgid "STO_GBL_LW (store global longword) %.*s\n"
+msgstr "STO_GBL_LW (хранимое глобальное длинное Ñлово) %.*s\n"
+
+#: vms-alpha.c:6151
+#, c-format
+msgid "STO_OFF (store LP with procedure signature)\n"
+msgstr "STO_OFF (хранимый LP Ñ Ñигнатурой процедуры)\n"
+
+#: vms-alpha.c:6154
+#, c-format
+msgid "STO_BR_GBL (store branch global) *todo*\n"
+msgstr "STO_BR_GBL (хранимое глобальное ветвление) *todo*\n"
+
+#: vms-alpha.c:6157
+#, c-format
+msgid "STO_BR_PS (store branch psect + offset) *todo*\n"
+msgstr "STO_BR_PS (хранимое ветвление psect + Ñмещение) *todo*\n"
+
+#: vms-alpha.c:6161
+#, c-format
+msgid "OPR_NOP (no-operation)\n"
+msgstr "OPR_NOP (нет операции)\n"
+
+#: vms-alpha.c:6164
+#, c-format
+msgid "OPR_ADD (add)\n"
+msgstr "OPR_ADD (Ñложение)\n"
+
+#: vms-alpha.c:6167
+#, c-format
+msgid "OPR_SUB (substract)\n"
+msgstr "OPR_SUB (вычитание)\n"
+
+#: vms-alpha.c:6170
+#, c-format
+msgid "OPR_MUL (multiply)\n"
+msgstr "OPR_MUL (умножение)\n"
+
+#: vms-alpha.c:6173
+#, c-format
+msgid "OPR_DIV (divide)\n"
+msgstr "OPR_DIV (деление)\n"
+
+#: vms-alpha.c:6176
+#, c-format
+msgid "OPR_AND (logical and)\n"
+msgstr "OPR_AND (логичеÑкое и)\n"
+
+#: vms-alpha.c:6179
+#, c-format
+msgid "OPR_IOR (logical inclusive or)\n"
+msgstr "OPR_IOR (логичеÑкое включающее или)\n"
+
+#: vms-alpha.c:6182
+#, c-format
+msgid "OPR_EOR (logical exclusive or)\n"
+msgstr "OPR_EOR (логичеÑкое не включающее или)\n"
+
+#: vms-alpha.c:6185
+#, c-format
+msgid "OPR_NEG (negate)\n"
+msgstr "OPR_NEG (инверÑиÑ)\n"
+
+#: vms-alpha.c:6188
+#, c-format
+msgid "OPR_COM (complement)\n"
+msgstr "OPR_COM (дополнение)\n"
+
+#: vms-alpha.c:6191
+#, c-format
+msgid "OPR_INSV (insert field)\n"
+msgstr "OPR_INSV (поле вÑтавки)\n"
+
+#: vms-alpha.c:6194
+#, c-format
+msgid "OPR_ASH (arithmetic shift)\n"
+msgstr "OPR_ASH (арифметичеÑкий Ñдвиг)\n"
+
+#: vms-alpha.c:6197
+#, c-format
+msgid "OPR_USH (unsigned shift)\n"
+msgstr "OPR_USH (беззнаковый Ñдвиг)\n"
+
+#: vms-alpha.c:6200
+#, c-format
+msgid "OPR_ROT (rotate)\n"
+msgstr "OPR_ROT (цикличеÑкий Ñдвиг)\n"
+
+#: vms-alpha.c:6203
+#, c-format
+msgid "OPR_SEL (select)\n"
+msgstr "OPR_SEL (выбор)\n"
+
+#: vms-alpha.c:6206
+#, c-format
+msgid "OPR_REDEF (redefine symbol to curr location)\n"
+msgstr "OPR_REDEF (переопределение Ñимвола в текущей позиции)\n"
+
+#: vms-alpha.c:6209
+#, c-format
+msgid "OPR_REDEF (define a literal)\n"
+msgstr "OPR_REDEF (определение литерала)\n"
+
+#: vms-alpha.c:6213
+#, c-format
+msgid "STC_LP (store cond linkage pair)\n"
+msgstr "STC_LP (Ñ…Ñ€Ð°Ð½Ð¸Ð¼Ð°Ñ ÑƒÑловно ÐºÐ¾Ð¼Ð¿Ð¾Ð½ÑƒÐµÐ¼Ð°Ñ Ð¿Ð°Ñ€Ð°)\n"
+
+#: vms-alpha.c:6217
+#, c-format
+msgid "STC_LP_PSB (store cond linkage pair + signature)\n"
+msgstr "STC_LP_PSB (Ñ…Ñ€Ð°Ð½Ð¸Ð¼Ð°Ñ ÑƒÑловно ÐºÐ¾Ð¼Ð¿Ð¾Ð½ÑƒÐµÐ¼Ð°Ñ Ð¿Ð°Ñ€Ð° + Ñигнатура)\n"
+
+#: vms-alpha.c:6218
+#, c-format
+msgid " linkage index: %u, procedure: %.*s\n"
+msgstr " Ð¸Ð½Ð´ÐµÐºÑ ÐºÐ¾Ð¼Ð¿Ð¾Ð½Ð¾Ð²ÐºÐ¸: %u, процедура: %.*s\n"
+
+#: vms-alpha.c:6221
+#, c-format
+msgid " signature: %.*s\n"
+msgstr " Ñигнатура: %.*s\n"
+
+#: vms-alpha.c:6224
+#, c-format
+msgid "STC_GBL (store cond global)\n"
+msgstr "STC_GBL (Ñ…Ñ€Ð°Ð½Ð¸Ð¼Ð°Ñ Ð³Ð»Ð¾Ð±Ð°Ð»ÑŒÐ½Ð¾Ðµ уÑловие)\n"
+
+#: vms-alpha.c:6225
+#, c-format
+msgid " linkage index: %u, global: %.*s\n"
+msgstr " Ð¸Ð½Ð´ÐµÐºÑ ÐºÐ¾Ð¼Ð¿Ð¾Ð½Ð¾Ð²ÐºÐ¸: %u, глобальный: %.*s\n"
+
+#: vms-alpha.c:6229
+#, c-format
+msgid "STC_GCA (store cond code address)\n"
+msgstr "STC_GCA (хранимый Ð°Ð´Ñ€ÐµÑ ÑƒÑловного кода)\n"
+
+#: vms-alpha.c:6230
+#, c-format
+msgid " linkage index: %u, procedure name: %.*s\n"
+msgstr " Ð¸Ð½Ð´ÐµÐºÑ ÐºÐ¾Ð¼Ð¿Ð¾Ð½Ð¾Ð²ÐºÐ¸: %u, Ð¸Ð¼Ñ Ð¿Ñ€Ð¾Ñ†ÐµÐ´ÑƒÑ€Ñ‹: %.*s\n"
+
+#: vms-alpha.c:6234
+#, c-format
+msgid "STC_PS (store cond psect + offset)\n"
+msgstr "STC_PS (хранимое уÑловие psect + Ñмещение)\n"
+
+#: vms-alpha.c:6236
+#, c-format
+msgid " linkage index: %u, psect: %u, offset: 0x%08x %08x\n"
+msgstr " Ð¸Ð½Ð´ÐµÐºÑ ÐºÐ¾Ð¼Ð¿Ð¾Ð½Ð¾Ð²ÐºÐ¸: %u, psect: %u, Ñмещение: 0x%08x %08x\n"
+
+#: vms-alpha.c:6243
+#, c-format
+msgid "STC_NOP_GBL (store cond NOP at global addr)\n"
+msgstr "STC_NOP_GBL (хранимое уÑловие NOP по глобальному адреÑу)\n"
+
+#: vms-alpha.c:6247
+#, c-format
+msgid "STC_NOP_PS (store cond NOP at psect + offset)\n"
+msgstr "STC_NOP_PS (хранимое уÑловие NOP по psect + Ñмещение)\n"
+
+#: vms-alpha.c:6251
+#, c-format
+msgid "STC_BSR_GBL (store cond BSR at global addr)\n"
+msgstr "STC_BSR_GBL (хранимое уÑловие BSR по глобальному адреÑу)\n"
+
+#: vms-alpha.c:6255
+#, c-format
+msgid "STC_BSR_PS (store cond BSR at psect + offset)\n"
+msgstr "STC_BSR_PS (хранимое уÑловие BSR по psect + Ñмещение)\n"
+
+#: vms-alpha.c:6259
+#, c-format
+msgid "STC_LDA_GBL (store cond LDA at global addr)\n"
+msgstr "STC_LDA_GBL (хранимое уÑловие LDA по глобальному адреÑу)\n"
+
+#: vms-alpha.c:6263
+#, c-format
+msgid "STC_LDA_PS (store cond LDA at psect + offset)\n"
+msgstr "STC_LDA_PS (хранимое уÑловие LDA по psect + Ñмещение)\n"
+
+#: vms-alpha.c:6267
+#, c-format
+msgid "STC_BOH_GBL (store cond BOH at global addr)\n"
+msgstr "STC_BOH_GBL (хранимое уÑловие BOH по глобальному адреÑу)\n"
+
+#: vms-alpha.c:6271
+#, c-format
+msgid "STC_BOH_PS (store cond BOH at psect + offset)\n"
+msgstr "STC_BOH_PS (хранимое уÑловие BOH по psect + Ñмещение)\n"
+
+#: vms-alpha.c:6276
+#, c-format
+msgid "STC_NBH_GBL (store cond or hint at global addr)\n"
+msgstr "STC_NBH_GBL (хранимое уÑловие или указание по глобальному адреÑу)\n"
+
+#: vms-alpha.c:6280
+#, c-format
+msgid "STC_NBH_PS (store cond or hint at psect + offset)\n"
+msgstr "STC_NBH_PS (хранимое уÑловие или указание по psect + Ñмещение)\n"
+
+#: vms-alpha.c:6284
+#, c-format
+msgid "CTL_SETRB (set relocation base)\n"
+msgstr "CTL_SETRB (уÑтановка базы перемещениÑ)\n"
+
+#: vms-alpha.c:6290
+#, c-format
+msgid "CTL_AUGRB (augment relocation base) %u\n"
+msgstr "CTL_AUGRB (дополнение базы перемещениÑ) %u\n"
+
+#: vms-alpha.c:6294
+#, c-format
+msgid "CTL_DFLOC (define location)\n"
+msgstr "CTL_DFLOC (определение положениÑ)\n"
+
+#: vms-alpha.c:6297
+#, c-format
+msgid "CTL_STLOC (set location)\n"
+msgstr "CTL_STLOC (задание положениÑ)\n"
+
+#: vms-alpha.c:6300
+#, c-format
+msgid "CTL_STKDL (stack defined location)\n"
+msgstr "CTL_STKDL (положение определÑемое Ñтеком)\n"
+
+#: vms-alpha.c:6303 vms-alpha.c:6717
+#, c-format
+msgid "*unhandled*\n"
+msgstr "*не обработано*\n"
+
+#: vms-alpha.c:6333 vms-alpha.c:6372
+#, c-format
+msgid "cannot read GST record length\n"
+msgstr "не удалоÑÑŒ прочитать длину запиÑи GST\n"
+
+#. Ill-formed.
+#: vms-alpha.c:6354
+#, c-format
+msgid "cannot find EMH in first GST record\n"
+msgstr "не удалоÑÑŒ найти EMH в первой запиÑи GST\n"
+
+#: vms-alpha.c:6380
+#, c-format
+msgid "cannot read GST record header\n"
+msgstr "не удалоÑÑŒ прочитать заголовок запиÑи GST\n"
+
+#: vms-alpha.c:6393
+#, c-format
+msgid " corrupted GST\n"
+msgstr " повреждённый GST\n"
+
+#: vms-alpha.c:6401
+#, c-format
+msgid "cannot read GST record\n"
+msgstr "не удалоÑÑŒ прочитать запиÑÑŒ GST\n"
+
+#: vms-alpha.c:6430
+#, c-format
+msgid " unhandled EOBJ record type %u\n"
+msgstr " необработанный тип запиÑи EOBJ %u\n"
+
+#: vms-alpha.c:6453
+#, c-format
+msgid " bitcount: %u, base addr: 0x%08x\n"
+msgstr " Ñчётчик бит: %u, базовый адреÑ: 0x%08x\n"
+
+#: vms-alpha.c:6466
+#, c-format
+msgid " bitmap: 0x%08x (count: %u):\n"
+msgstr " bitmap: 0x%08x (Ñчётчик: %u):\n"
+
+#: vms-alpha.c:6473
+#, c-format
+msgid " %08x"
+msgstr " %08x"
+
+#: vms-alpha.c:6498
+#, c-format
+msgid " image %u (%u entries)\n"
+msgstr " образ %u (%u Ñлементов)\n"
+
+#: vms-alpha.c:6503
+#, c-format
+msgid " offset: 0x%08x, val: 0x%08x\n"
+msgstr " Ñмещение: 0x%08x, значение: 0x%08x\n"
+
+#: vms-alpha.c:6524
+#, c-format
+msgid " image %u (%u entries), offsets:\n"
+msgstr " образ %u (%u Ñлементов), ÑмещениÑ:\n"
+
+#: vms-alpha.c:6531
+#, c-format
+msgid " 0x%08x"
+msgstr " 0x%08x"
+
+#. 64 bits.
+#: vms-alpha.c:6653
+#, c-format
+msgid "64 bits *unhandled*\n"
+msgstr "64 бита *не обработано*\n"
+
+#: vms-alpha.c:6657
+#, c-format
+msgid "class: %u, dtype: %u, length: %u, pointer: 0x%08x\n"
+msgstr "клаÑÑ: %u, dtype: %u, длина: %u, указатель: 0x%08x\n"
+
+#: vms-alpha.c:6668
+#, c-format
+msgid "non-contiguous array of %s\n"
+msgstr "неÑвÑзный маÑÑив %s\n"
+
+#: vms-alpha.c:6672
+#, c-format
+msgid "dimct: %u, aflags: 0x%02x, digits: %u, scale: %u\n"
+msgstr "dimct: %u, aflags: 0x%02x, цифр: %u, шкала: %u\n"
+
+#: vms-alpha.c:6676
+#, c-format
+msgid "arsize: %u, a0: 0x%08x\n"
+msgstr "arsize: %u, a0: 0x%08x\n"
+
+#: vms-alpha.c:6680
+#, c-format
+msgid "Strides:\n"
+msgstr "Шаги:\n"
+
+#: vms-alpha.c:6685
+#, c-format
+msgid "[%u]: %u\n"
+msgstr "[%u]: %u\n"
+
+#: vms-alpha.c:6690
+#, c-format
+msgid "Bounds:\n"
+msgstr "Границы:\n"
+
+#: vms-alpha.c:6695
+#, c-format
+msgid "[%u]: Lower: %u, upper: %u\n"
+msgstr "[%u]: нижнÑÑ: %u, верхнÑÑ: %u\n"
+
+#: vms-alpha.c:6707
+#, c-format
+msgid "unaligned bit-string of %s\n"
+msgstr "Ð½ÐµÐ²Ñ‹Ñ€Ð¾Ð²Ð½ÐµÐ½Ð½Ð°Ñ Ñтрока бит %s\n"
+
+#: vms-alpha.c:6711
+#, c-format
+msgid "base: %u, pos: %u\n"
+msgstr "база: %u, позициÑ: %u\n"
+
+#: vms-alpha.c:6731
+#, c-format
+msgid "vflags: 0x%02x, value: 0x%08x "
+msgstr "vflags: 0x%02x, значение: 0x%08x "
+
+#: vms-alpha.c:6737
+#, c-format
+msgid "(no value)\n"
+msgstr "(нет значениÑ)\n"
+
+#: vms-alpha.c:6740
+#, c-format
+msgid "(not active)\n"
+msgstr "(не активно)\n"
+
+#: vms-alpha.c:6743
+#, c-format
+msgid "(not allocated)\n"
+msgstr "(не выделено)\n"
+
+#: vms-alpha.c:6746
+#, c-format
+msgid "(descriptor)\n"
+msgstr "(деÑкриптор)\n"
+
+#: vms-alpha.c:6750
+#, c-format
+msgid "(trailing value)\n"
+msgstr "(конечное значение)\n"
+
+#: vms-alpha.c:6753
+#, c-format
+msgid "(value spec follows)\n"
+msgstr "(далее значение Ñпецификации)\n"
+
+#: vms-alpha.c:6756
+#, c-format
+msgid "(at bit offset %u)\n"
+msgstr "(по битовому Ñмещению %u)\n"
+
+#: vms-alpha.c:6759
+#, c-format
+msgid "(reg: %u, disp: %u, indir: %u, kind: "
+msgstr "(reg: %u, disp: %u, indir: %u, kind: "
+
+#: vms-alpha.c:6766
+msgid "literal"
+msgstr "литерал"
+
+#: vms-alpha.c:6769
+msgid "address"
+msgstr "адреÑ"
+
+#: vms-alpha.c:6772
+msgid "desc"
+msgstr "деÑк"
+
+#: vms-alpha.c:6775
+msgid "reg"
+msgstr "рег"
+
+#: vms-alpha.c:6850
+#, c-format
+msgid "Debug symbol table:\n"
+msgstr "Таблица Ñимволов отладки:\n"
+
+#: vms-alpha.c:6861
+#, c-format
+msgid "cannot read DST header\n"
+msgstr "не удалоÑÑŒ прочитать заголовок DST\n"
+
+#: vms-alpha.c:6866
+#, c-format
+msgid " type: %3u, len: %3u (at 0x%08x): "
+msgstr " тип: %3u, длина: %3u (по 0x%08x): "
+
+#: vms-alpha.c:6880
+#, c-format
+msgid "cannot read DST symbol\n"
+msgstr "не удалоÑÑŒ прочитать Ñимвол DST\n"
+
+#: vms-alpha.c:6923
+#, c-format
+msgid "standard data: %s\n"
+msgstr "Ñтандартные данные: %s\n"
+
+#: vms-alpha.c:6926 vms-alpha.c:7010
+#, c-format
+msgid " name: %.*s\n"
+msgstr " имÑ: %.*s\n"
+
+#: vms-alpha.c:6933
+#, c-format
+msgid "modbeg\n"
+msgstr "modbeg\n"
+
+#: vms-alpha.c:6934
+#, c-format
+msgid " flags: %d, language: %u, major: %u, minor: %u\n"
+msgstr " флаги: %d, Ñзык: %u, Ñтарший: %u, младший: %u\n"
+
+#: vms-alpha.c:6940 vms-alpha.c:7206
+#, c-format
+msgid " module name: %.*s\n"
+msgstr " Ð¸Ð¼Ñ Ð¼Ð¾Ð´ÑƒÐ»Ñ: %.*s\n"
+
+#: vms-alpha.c:6943
+#, c-format
+msgid " compiler : %.*s\n"
+msgstr " компилÑтор : %.*s\n"
+
+#: vms-alpha.c:6948
+#, c-format
+msgid "modend\n"
+msgstr "modend\n"
+
+#: vms-alpha.c:6955
+msgid "rtnbeg\n"
+msgstr "rtnbeg\n"
+
+#: vms-alpha.c:6956
+#, c-format
+msgid " flags: %u, address: 0x%08x, pd-address: 0x%08x\n"
+msgstr " флаги: %u, адреÑ: 0x%08x, pd-адреÑ: 0x%08x\n"
+
+#: vms-alpha.c:6961
+#, c-format
+msgid " routine name: %.*s\n"
+msgstr " Ð¸Ð¼Ñ Ð¿Ñ€Ð¾Ñ†ÐµÐ´ÑƒÑ€Ñ‹: %.*s\n"
+
+#: vms-alpha.c:6969
+#, c-format
+msgid "rtnend: size 0x%08x\n"
+msgstr "rtnend: размер 0x%08x\n"
+
+#: vms-alpha.c:6977
+#, c-format
+msgid "prolog: bkpt address 0x%08x\n"
+msgstr "пролог: Ð°Ð´Ñ€ÐµÑ bkpt 0x%08x\n"
+
+#: vms-alpha.c:6985
+#, c-format
+msgid "epilog: flags: %u, count: %u\n"
+msgstr "Ñпилог: флаги: %u, Ñчётчик: %u\n"
+
+#: vms-alpha.c:6994
+#, c-format
+msgid "blkbeg: address: 0x%08x, name: %.*s\n"
+msgstr "blkbeg: адреÑ: 0x%08x, имÑ: %.*s\n"
+
+#: vms-alpha.c:7003
+#, c-format
+msgid "blkend: size: 0x%08x\n"
+msgstr "blkend: размер: 0x%08x\n"
+
+#: vms-alpha.c:7009
+#, c-format
+msgid "typspec (len: %u)\n"
+msgstr "typspec (длина: %u)\n"
+
+#: vms-alpha.c:7016
+#, c-format
+msgid "septyp, name: %.*s\n"
+msgstr "septyp, имÑ: %.*s\n"
+
+#: vms-alpha.c:7025
+#, c-format
+msgid "recbeg: name: %.*s\n"
+msgstr "recbeg: имÑ: %.*s\n"
+
+#: vms-alpha.c:7032
+#, c-format
+msgid "recend\n"
+msgstr "recend\n"
+
+#: vms-alpha.c:7035
+#, c-format
+msgid "enumbeg, len: %u, name: %.*s\n"
+msgstr "enumbeg, длина: %u, имÑ: %.*s\n"
+
+#: vms-alpha.c:7039
+#, c-format
+msgid "enumelt, name: %.*s\n"
+msgstr "enumelt, имÑ: %.*s\n"
+
+#: vms-alpha.c:7043
+#, c-format
+msgid "enumend\n"
+msgstr "enumend\n"
+
+#: vms-alpha.c:7060
+#, c-format
+msgid "discontiguous range (nbr: %u)\n"
+msgstr "неÑмежный диапазон (nbr: %u)\n"
+
+#: vms-alpha.c:7062
+#, c-format
+msgid " address: 0x%08x, size: %u\n"
+msgstr " адреÑ: 0x%08x, размер: %u\n"
+
+#: vms-alpha.c:7072
+#, c-format
+msgid "line num (len: %u)\n"
+msgstr "номер Ñтроки (длина: %u)\n"
+
+#: vms-alpha.c:7089
+#, c-format
+msgid "delta_pc_w %u\n"
+msgstr "delta_pc_w %u\n"
+
+#: vms-alpha.c:7096
+#, c-format
+msgid "incr_linum(b): +%u\n"
+msgstr "incr_linum(b): +%u\n"
+
+#: vms-alpha.c:7102
+#, c-format
+msgid "incr_linum_w: +%u\n"
+msgstr "incr_linum_w: +%u\n"
+
+#: vms-alpha.c:7108
+#, c-format
+msgid "incr_linum_l: +%u\n"
+msgstr "incr_linum_l: +%u\n"
+
+#: vms-alpha.c:7114
+#, c-format
+msgid "set_line_num(w) %u\n"
+msgstr "set_line_num(w) %u\n"
+
+#: vms-alpha.c:7119
+#, c-format
+msgid "set_line_num_b %u\n"
+msgstr "set_line_num_b %u\n"
+
+#: vms-alpha.c:7124
+#, c-format
+msgid "set_line_num_l %u\n"
+msgstr "set_line_num_l %u\n"
+
+#: vms-alpha.c:7129
+#, c-format
+msgid "set_abs_pc: 0x%08x\n"
+msgstr "set_abs_pc: 0x%08x\n"
+
+#: vms-alpha.c:7133
+#, c-format
+msgid "delta_pc_l: +0x%08x\n"
+msgstr "delta_pc_l: +0x%08x\n"
+
+#: vms-alpha.c:7138
+#, c-format
+msgid "term(b): 0x%02x"
+msgstr "term(b): 0x%02x"
+
+#: vms-alpha.c:7140
+#, c-format
+msgid " pc: 0x%08x\n"
+msgstr " pc: 0x%08x\n"
+
+#: vms-alpha.c:7145
+#, c-format
+msgid "term_w: 0x%04x"
+msgstr "term_w: 0x%04x"
+
+#: vms-alpha.c:7147
+#, c-format
+msgid " pc: 0x%08x\n"
+msgstr " pc: 0x%08x\n"
+
+#: vms-alpha.c:7153
+#, c-format
+msgid "delta pc +%-4d"
+msgstr "delta pc +%-4d"
+
+#: vms-alpha.c:7156
+#, c-format
+msgid " pc: 0x%08x line: %5u\n"
+msgstr " pc: 0x%08x Ñтрока: %5u\n"
+
+#: vms-alpha.c:7161
+#, c-format
+msgid " *unhandled* cmd %u\n"
+msgstr " *необработаннаÑ* команда %u\n"
+
+#: vms-alpha.c:7176
+#, c-format
+msgid "source (len: %u)\n"
+msgstr "иÑточник (длина: %u)\n"
+
+#: vms-alpha.c:7190
+#, c-format
+msgid " declfile: len: %u, flags: %u, fileid: %u\n"
+msgstr " declfile: длина: %u, флаги: %u, fileid: %u\n"
+
+#: vms-alpha.c:7194
+#, c-format
+msgid " rms: cdt: 0x%08x %08x, ebk: 0x%08x, ffb: 0x%04x, rfo: %u\n"
+msgstr " rms: cdt: 0x%08x %08x, ebk: 0x%08x, ffb: 0x%04x, rfo: %u\n"
+
+#: vms-alpha.c:7203
+#, c-format
+msgid " filename : %.*s\n"
+msgstr " Ð¸Ð¼Ñ Ñ„Ð°Ð¹Ð»Ð° : %.*s\n"
+
+#: vms-alpha.c:7212
+#, c-format
+msgid " setfile %u\n"
+msgstr " setfile %u\n"
+
+#: vms-alpha.c:7217 vms-alpha.c:7222
+#, c-format
+msgid " setrec %u\n"
+msgstr " setrec %u\n"
+
+#: vms-alpha.c:7227 vms-alpha.c:7232
+#, c-format
+msgid " setlnum %u\n"
+msgstr " setlnum %u\n"
+
+#: vms-alpha.c:7237 vms-alpha.c:7242
+#, c-format
+msgid " deflines %u\n"
+msgstr " deflines %u\n"
+
+#: vms-alpha.c:7246
+#, c-format
+msgid " formfeed\n"
+msgstr " formfeed\n"
+
+#: vms-alpha.c:7250
+#, c-format
+msgid " *unhandled* cmd %u\n"
+msgstr " *необработаннаÑ* команда %u\n"
+
+#: vms-alpha.c:7262
+#, c-format
+msgid "*unhandled* dst type %u\n"
+msgstr "*необработанный* тип Ð½Ð°Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ %u\n"
+
+#: vms-alpha.c:7294
+#, c-format
+msgid "cannot read EIHD\n"
+msgstr "не удалоÑÑŒ прочитать EIHD\n"
+
+#: vms-alpha.c:7297
+#, c-format
+msgid "EIHD: (size: %u, nbr blocks: %u)\n"
+msgstr "EIHD: (размер: %u, nbr блоков: %u)\n"
+
+#: vms-alpha.c:7300
+#, c-format
+msgid " majorid: %u, minorid: %u\n"
+msgstr " majorid: %u, minorid: %u\n"
+
+#: vms-alpha.c:7308
+msgid "executable"
+msgstr "иÑполнÑемый"
+
+#: vms-alpha.c:7311
+msgid "linkable image"
+msgstr "компонуемый образ"
+
+#: vms-alpha.c:7317
+#, c-format
+msgid " image type: %u (%s)"
+msgstr " тип образа: %u (%s)"
+
+#: vms-alpha.c:7323
+msgid "native"
+msgstr "родной"
+
+#: vms-alpha.c:7326
+msgid "CLI"
+msgstr "CLI"
+
+#: vms-alpha.c:7332
+#, c-format
+msgid ", subtype: %u (%s)\n"
+msgstr ", подтип: %u (%s)\n"
+
+#: vms-alpha.c:7338
+#, c-format
+msgid " offsets: isd: %u, activ: %u, symdbg: %u, imgid: %u, patch: %u\n"
+msgstr " ÑмещениÑ: isd: %u, activ: %u, symdbg: %u, imgid: %u, patch: %u\n"
+
+#: vms-alpha.c:7342
+#, c-format
+msgid " fixup info rva: "
+msgstr " fixup info rva: "
+
+#: vms-alpha.c:7344
+#, c-format
+msgid ", symbol vector rva: "
+msgstr ", Ñимвольный вектор rva: "
+
+#: vms-alpha.c:7347
+#, c-format
+msgid ""
+"\n"
+" version array off: %u\n"
+msgstr ""
+"\n"
+" Ñмещение маÑÑива верÑий: %u\n"
+
+#: vms-alpha.c:7351
+#, c-format
+msgid " img I/O count: %u, nbr channels: %u, req pri: %08x%08x\n"
+msgstr " img I/O count: %u, nbr channels: %u, req pri: %08x%08x\n"
+
+#: vms-alpha.c:7357
+#, c-format
+msgid " linker flags: %08x:"
+msgstr " флаги компоновщика: %08x:"
+
+#: vms-alpha.c:7387
+#, c-format
+msgid " ident: 0x%08x, sysver: 0x%08x, match ctrl: %u, symvect_size: %u\n"
+msgstr " ident: 0x%08x, sysver: 0x%08x, match ctrl: %u, symvect_size: %u\n"
+
+#: vms-alpha.c:7393
+#, c-format
+msgid " BPAGE: %u"
+msgstr " BPAGE: %u"
+
+#: vms-alpha.c:7399
+#, c-format
+msgid ", ext fixup offset: %u, no_opt psect off: %u"
+msgstr ", ext fixup offset: %u, no_opt psect off: %u"
+
+#: vms-alpha.c:7402
+#, c-format
+msgid ", alias: %u\n"
+msgstr ", пÑевдоним: %u\n"
+
+#: vms-alpha.c:7410
+#, c-format
+msgid "system version array information:\n"
+msgstr "маÑÑив информации верÑии ÑиÑтемы:\n"
+
+#: vms-alpha.c:7414
+#, c-format
+msgid "cannot read EIHVN header\n"
+msgstr "не удалоÑÑŒ прочитать заголовок EIHVN\n"
+
+#: vms-alpha.c:7424
+#, c-format
+msgid "cannot read EIHVN version\n"
+msgstr "не удалоÑÑŒ прочитать верÑию EIHVN\n"
+
+#: vms-alpha.c:7427
+#, c-format
+msgid " %02u "
+msgstr " %02u "
+
+#: vms-alpha.c:7431
+msgid "BASE_IMAGE "
+msgstr "BASE_IMAGE "
+
+#: vms-alpha.c:7434
+msgid "MEMORY_MANAGEMENT"
+msgstr "MEMORY_MANAGEMENT"
+
+#: vms-alpha.c:7437
+msgid "IO "
+msgstr "IO "
+
+#: vms-alpha.c:7440
+msgid "FILES_VOLUMES "
+msgstr "FILES_VOLUMES "
+
+#: vms-alpha.c:7443
+msgid "PROCESS_SCHED "
+msgstr "PROCESS_SCHED "
+
+#: vms-alpha.c:7446
+msgid "SYSGEN "
+msgstr "SYSGEN "
+
+#: vms-alpha.c:7449
+msgid "CLUSTERS_LOCKMGR "
+msgstr "CLUSTERS_LOCKMGR "
+
+#: vms-alpha.c:7452
+msgid "LOGICAL_NAMES "
+msgstr "LOGICAL_NAMES "
+
+#: vms-alpha.c:7455
+msgid "SECURITY "
+msgstr "SECURITY "
+
+#: vms-alpha.c:7458
+msgid "IMAGE_ACTIVATOR "
+msgstr "IMAGE_ACTIVATOR "
+
+#: vms-alpha.c:7461
+msgid "NETWORKS "
+msgstr "NETWORKS "
+
+#: vms-alpha.c:7464
+msgid "COUNTERS "
+msgstr "COUNTERS "
+
+#: vms-alpha.c:7467
+msgid "STABLE "
+msgstr "STABLE "
+
+#: vms-alpha.c:7470
+msgid "MISC "
+msgstr "MISC "
+
+#: vms-alpha.c:7473
+msgid "CPU "
+msgstr "CPU "
+
+#: vms-alpha.c:7476
+msgid "VOLATILE "
+msgstr "VOLATILE "
+
+#: vms-alpha.c:7479
+msgid "SHELL "
+msgstr "SHELL "
+
+#: vms-alpha.c:7482
+msgid "POSIX "
+msgstr "POSIX "
+
+#: vms-alpha.c:7485
+msgid "MULTI_PROCESSING "
+msgstr "MULTI_PROCESSING "
+
+#: vms-alpha.c:7488
+msgid "GALAXY "
+msgstr "GALAXY "
+
+#: vms-alpha.c:7491
+msgid "*unknown* "
+msgstr "*неизвеÑтно* "
+
+#: vms-alpha.c:7494
+#, c-format
+msgid ": %u.%u\n"
+msgstr ": %u.%u\n"
+
+#: vms-alpha.c:7507 vms-alpha.c:7766
+#, c-format
+msgid "cannot read EIHA\n"
+msgstr "не удалоÑÑŒ прочитать EIHA\n"
+
+#: vms-alpha.c:7510
+#, c-format
+msgid "Image activation: (size=%u)\n"
+msgstr "ÐÐºÑ‚Ð¸Ð²Ð°Ñ†Ð¸Ñ Ð¾Ð±Ñ€Ð°Ð·Ð°: (размер=%u)\n"
+
+#: vms-alpha.c:7512
+#, c-format
+msgid " First address : 0x%08x 0x%08x\n"
+msgstr " Первый адреÑ: 0x%08x 0x%08x\n"
+
+#: vms-alpha.c:7515
+#, c-format
+msgid " Second address: 0x%08x 0x%08x\n"
+msgstr " Второй адреÑ: 0x%08x 0x%08x\n"
+
+#: vms-alpha.c:7518
+#, c-format
+msgid " Third address : 0x%08x 0x%08x\n"
+msgstr " Третий адреÑ: 0x%08x 0x%08x\n"
+
+#: vms-alpha.c:7521
+#, c-format
+msgid " Fourth address: 0x%08x 0x%08x\n"
+msgstr " Четвёртый адреÑ: 0x%08x 0x%08x\n"
+
+#: vms-alpha.c:7524
+#, c-format
+msgid " Shared image : 0x%08x 0x%08x\n"
+msgstr " Общий образ: 0x%08x 0x%08x\n"
+
+#: vms-alpha.c:7535
+#, c-format
+msgid "cannot read EIHI\n"
+msgstr "не удалоÑÑŒ прочитать EIHI\n"
+
+#: vms-alpha.c:7538
+#, c-format
+msgid "Image identification: (major: %u, minor: %u)\n"
+msgstr "Ð˜Ð´ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ†Ð¸Ñ Ð¾Ð±Ñ€Ð°Ð·Ð°: (Ñтарший: %u, младший: %u)\n"
+
+#: vms-alpha.c:7541
+#, c-format
+msgid " image name : %.*s\n"
+msgstr " Ð¸Ð¼Ñ Ð¾Ð±Ñ€Ð°Ð·Ð° : %.*s\n"
+
+#: vms-alpha.c:7543
+#, c-format
+msgid " link time : %s\n"
+msgstr " Ð²Ñ€ÐµÐ¼Ñ ÐºÐ¾Ð¼Ð¿Ð¾Ð½Ð¾Ð²ÐºÐ¸ : %s\n"
+
+#: vms-alpha.c:7545
+#, c-format
+msgid " image ident : %.*s\n"
+msgstr " идент-р образа : %.*s\n"
+
+#: vms-alpha.c:7547
+#, c-format
+msgid " linker ident : %.*s\n"
+msgstr " идент-р компоновщика: %.*s\n"
+
+#: vms-alpha.c:7549
+#, c-format
+msgid " image build ident: %.*s\n"
+msgstr " идент-Ñ€ Ñборки образа: %.*s\n"
+
+#: vms-alpha.c:7559
+#, c-format
+msgid "cannot read EIHS\n"
+msgstr "не удалоÑÑŒ прочитать EIHS\n"
+
+#: vms-alpha.c:7562
+#, c-format
+msgid "Image symbol & debug table: (major: %u, minor: %u)\n"
+msgstr "Таблица Ñимволов & отладки образа: (Ñтарший: %u, младший: %u)\n"
+
+#: vms-alpha.c:7567
+#, c-format
+msgid " debug symbol table : vbn: %u, size: %u (0x%x)\n"
+msgstr " таблица отладочных Ñимволов: vbn: %u, размер: %u (0x%x)\n"
+
+#: vms-alpha.c:7571
+#, c-format
+msgid " global symbol table: vbn: %u, records: %u\n"
+msgstr " Ð³Ð»Ð¾Ð±Ð°Ð»ÑŒÐ½Ð°Ñ Ñ‚Ð°Ð±Ð»Ð¸Ñ†Ð° Ñимволов: vbn: %u, запиÑей: %u\n"
+
+#: vms-alpha.c:7575
+#, c-format
+msgid " debug module table : vbn: %u, size: %u\n"
+msgstr " таблица отладочных модулей: vbn: %u, размер: %u\n"
+
+#: vms-alpha.c:7588
+#, c-format
+msgid "cannot read EISD\n"
+msgstr "не удалоÑÑŒ прочитать EISD\n"
+
+#: vms-alpha.c:7598
+#, c-format
+msgid "Image section descriptor: (major: %u, minor: %u, size: %u, offset: %u)\n"
+msgstr "ДеÑкриптор раздела образа: (Ñтарший: %u, младший: %u, размер: %u, Ñмещение: %u)\n"
+
+#: vms-alpha.c:7605
+#, c-format
+msgid " section: base: 0x%08x%08x size: 0x%08x\n"
+msgstr " раздел: база: 0x%08x%08x размер: 0x%08x\n"
+
+#: vms-alpha.c:7610
+#, c-format
+msgid " flags: 0x%04x"
+msgstr " флаги: 0x%04x"
+
+#: vms-alpha.c:7647
+#, c-format
+msgid " vbn: %u, pfc: %u, matchctl: %u type: %u ("
+msgstr " vbn: %u, pfc: %u, matchctl: %u тип: %u ("
+
+#: vms-alpha.c:7653
+msgid "NORMAL"
+msgstr "NORMAL"
+
+#: vms-alpha.c:7656
+msgid "SHRFXD"
+msgstr "SHRFXD"
+
+#: vms-alpha.c:7659
+msgid "PRVFXD"
+msgstr "PRVFXD"
+
+#: vms-alpha.c:7662
+msgid "SHRPIC"
+msgstr "SHRPIC"
+
+#: vms-alpha.c:7665
+msgid "PRVPIC"
+msgstr "PRVPIC"
+
+#: vms-alpha.c:7668
+msgid "USRSTACK"
+msgstr "USRSTACK"
+
+#: vms-alpha.c:7676
+#, c-format
+msgid " ident: 0x%08x, name: %.*s\n"
+msgstr " иден-Ñ€: 0x%08x, имÑ: %.*s\n"
+
+#: vms-alpha.c:7686
+#, c-format
+msgid "cannot read DMT\n"
+msgstr "не удалоÑÑŒ прочитать DMT\n"
+
+#: vms-alpha.c:7690
+#, c-format
+msgid "Debug module table:\n"
+msgstr "Таблица отладочных модулей:\n"
+
+#: vms-alpha.c:7699
+#, c-format
+msgid "cannot read DMT header\n"
+msgstr "не удалоÑÑŒ прочитать заголовок DMT\n"
+
+#: vms-alpha.c:7704
+#, c-format
+msgid " module offset: 0x%08x, size: 0x%08x, (%u psects)\n"
+msgstr " Ñмещение модулÑ: 0x%08x, размер: 0x%08x, (%u psects)\n"
+
+#: vms-alpha.c:7714
+#, c-format
+msgid "cannot read DMT psect\n"
+msgstr "не удалоÑÑŒ прочитать DMT psect\n"
+
+#: vms-alpha.c:7717
+#, c-format
+msgid " psect start: 0x%08x, length: %u\n"
+msgstr " начало psect: 0x%08x, длина: %u\n"
+
+#: vms-alpha.c:7730
+#, c-format
+msgid "cannot read DST\n"
+msgstr "не удалоÑÑŒ прочитать DST\n"
+
+#: vms-alpha.c:7740
+#, c-format
+msgid "cannot read GST\n"
+msgstr "не удалоÑÑŒ прочитать GST\n"
+
+#: vms-alpha.c:7744
+#, c-format
+msgid "Global symbol table:\n"
+msgstr "Таблица глобальных Ñимволов:\n"
+
+#: vms-alpha.c:7772
+#, c-format
+msgid "Image activator fixup: (major: %u, minor: %u)\n"
+msgstr "Ðктиватор меÑÑ‚Ð¾Ð¿Ð¾Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ð¾Ð±Ñ€Ð°Ð·Ð°: (Ñтарший: %u, младший: %u)\n"
+
+#: vms-alpha.c:7775
+#, c-format
+msgid " iaflink : 0x%08x %08x\n"
+msgstr " iaflink : 0x%08x %08x\n"
+
+#: vms-alpha.c:7778
+#, c-format
+msgid " fixuplnk: 0x%08x %08x\n"
+msgstr " fixuplnk: 0x%08x %08x\n"
+
+#: vms-alpha.c:7781
+#, c-format
+msgid " size : %u\n"
+msgstr " размер: %u\n"
+
+#: vms-alpha.c:7783
+#, c-format
+msgid " flags: 0x%08x\n"
+msgstr " флаги: 0x%08x\n"
+
+#: vms-alpha.c:7787
+#, c-format
+msgid " qrelfixoff: %5u, lrelfixoff: %5u\n"
+msgstr " qrelfixoff: %5u, lrelfixoff: %5u\n"
+
+#: vms-alpha.c:7791
+#, c-format
+msgid " qdotadroff: %5u, ldotadroff: %5u\n"
+msgstr " qdotadroff: %5u, ldotadroff: %5u\n"
+
+#: vms-alpha.c:7795
+#, c-format
+msgid " codeadroff: %5u, lpfixoff : %5u\n"
+msgstr " codeadroff: %5u, lpfixoff : %5u\n"
+
+#: vms-alpha.c:7798
+#, c-format
+msgid " chgprtoff : %5u\n"
+msgstr " chgprtoff : %5u\n"
+
+#: vms-alpha.c:7801
+#, c-format
+msgid " shlstoff : %5u, shrimgcnt : %5u\n"
+msgstr " shlstoff : %5u, shrimgcnt : %5u\n"
+
+#: vms-alpha.c:7803
+#, c-format
+msgid " shlextra : %5u, permctx : %5u\n"
+msgstr " shlextra : %5u, permctx : %5u\n"
+
+#: vms-alpha.c:7806
+#, c-format
+msgid " base_va : 0x%08x\n"
+msgstr " base_va : 0x%08x\n"
+
+#: vms-alpha.c:7808
+#, c-format
+msgid " lppsbfixoff: %5u\n"
+msgstr " lppsbfixoff: %5u\n"
+
+#: vms-alpha.c:7816
+#, c-format
+msgid " Shareable images:\n"
+msgstr " Общие образы:\n"
+
+#: vms-alpha.c:7820
+#, c-format
+msgid " %u: size: %u, flags: 0x%02x, name: %.*s\n"
+msgstr " %u: размер: %u, флаги: 0x%02x, имÑ: %.*s\n"
+
+#: vms-alpha.c:7827
+#, c-format
+msgid " quad-word relocation fixups:\n"
+msgstr " четверное Ñлово перемещаемых меÑтоположений:\n"
+
+#: vms-alpha.c:7832
+#, c-format
+msgid " long-word relocation fixups:\n"
+msgstr " длинное Ñлово перемещаемых меÑтоположений:\n"
+
+#: vms-alpha.c:7837
+#, c-format
+msgid " quad-word .address reference fixups:\n"
+msgstr " четверное Ñлово ÑÑылочных меÑтоположений .address:\n"
+
+#: vms-alpha.c:7842
+#, c-format
+msgid " long-word .address reference fixups:\n"
+msgstr " длинное Ñлово ÑÑылочных меÑтоположений .address:\n"
+
+#: vms-alpha.c:7847
+#, c-format
+msgid " Code Address Reference Fixups:\n"
+msgstr " СÑылочные меÑÑ‚Ð¾Ð¿Ð¾Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ð°Ð´Ñ€ÐµÑа кода:\n"
+
+#: vms-alpha.c:7852
+#, c-format
+msgid " Linkage Pairs Referece Fixups:\n"
+msgstr " СÑылочные меÑÑ‚Ð¾Ð¿Ð¾Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ ÐºÐ¾Ð¼Ð¿Ð¾Ð½ÑƒÐµÐ¼Ñ‹Ñ… пар:\n"
+
+#: vms-alpha.c:7861
+#, c-format
+msgid " Change Protection (%u entries):\n"
+msgstr " Изменение защиты (%u Ñлементов):\n"
+
+#: vms-alpha.c:7866
+#, c-format
+msgid " base: 0x%08x %08x, size: 0x%08x, prot: 0x%08x "
+msgstr " база: 0x%08x %08x, размер: 0x%08x, prot: 0x%08x "
+
+#. FIXME: we do not yet support relocatable link. It is not obvious
+#. how to do it for debug infos.
+#: vms-alpha.c:8706
+msgid "%P: relocatable link is not supported\n"
+msgstr "%P: Ð¿ÐµÑ€ÐµÐ¼ÐµÑ‰Ð°ÐµÐ¼Ð°Ñ ÑÑылка не поддерживаетÑÑ\n"
+
+#: vms-alpha.c:8776
+msgid "%P: multiple entry points: in modules %B and %B\n"
+msgstr "%P: неÑколько точек входа: в модулÑÑ… %B и %B\n"
+
+#: vms-lib.c:1423
+#, c-format
+msgid "could not open shared image '%s' from '%s'"
+msgstr "не удалоÑÑŒ открыть общий образ «%s» из «%s»"
+
+#: vms-misc.c:360
+msgid "_bfd_vms_output_counted called with zero bytes"
+msgstr "Вызов _bfd_vms_output_counted Ñ Ð½ÑƒÐ»ÐµÐ²Ñ‹Ð¼ количеÑтвом байт"
+
+#: vms-misc.c:365
+msgid "_bfd_vms_output_counted called with too many bytes"
+msgstr "Вызов _bfd_vms_output_counted Ñо Ñлишком большим количеÑтвом байт"
+
+#: xcofflink.c:836
+#, c-format
+msgid "%s: XCOFF shared object when not producing XCOFF output"
+msgstr "%s: общий объект XCOFF без ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ð²Ñ‹Ð²Ð¾Ð´Ð° XCOFF"
+
+#: xcofflink.c:857
+#, c-format
+msgid "%s: dynamic object with no .loader section"
+msgstr "%s: динамичеÑкий объект без раздела .loader"
+
+#: xcofflink.c:1416
+msgid "%B: `%s' has line numbers but no enclosing section"
+msgstr "%B: «%s» Ñодержит номера Ñтрок, но в обрамлÑющем разделе"
+
+#: xcofflink.c:1468
+msgid "%B: class %d symbol `%s' has no aux entries"
+msgstr "%B: клаÑÑ %d Ñимвола «%s» не имеет Ñлементов aux"
+
+#: xcofflink.c:1490
+msgid "%B: symbol `%s' has unrecognized csect type %d"
+msgstr "%B: Ñимвол «%s» имеет нераÑпознанный тип csect: %d"
+
+#: xcofflink.c:1502
+msgid "%B: bad XTY_ER symbol `%s': class %d scnum %d scnlen %d"
+msgstr "%B: неверный Ñимвол XTY_ER «%s»: клаÑÑ %d scnum %d scnlen %d"
+
+#: xcofflink.c:1531
+msgid "%B: XMC_TC0 symbol `%s' is class %d scnlen %d"
+msgstr "%B: Ñимвол XMC_TC0 «%s» ÑвлÑетÑÑ ÐºÐ»Ð°ÑÑом %d scnlen %d"
+
+#: xcofflink.c:1677
+msgid "%B: csect `%s' not in enclosing section"
+msgstr "%B: csect «%s» не в обрамлÑющем разделе"
+
+#: xcofflink.c:1784
+msgid "%B: misplaced XTY_LD `%s'"
+msgstr "%B: неправильно раÑположенный XTY_LD «%s»"
+
+#: xcofflink.c:2103
+msgid "%B: reloc %s:%d not in csect"
+msgstr "%B: перемещение %s:%d не в csect"
+
+#: xcofflink.c:3194
+#, c-format
+msgid "%s: no such symbol"
+msgstr "%s: нет такого Ñимвола"
+
+#: xcofflink.c:3299
+#, c-format
+msgid "warning: attempt to export undefined symbol `%s'"
+msgstr "предупреждение: попытка ÑкÑпортировать неопределённый Ñимвол «%s»"
+
+#: xcofflink.c:3678
+msgid "error: undefined symbol __rtinit"
+msgstr "ошибка: неопределённый Ñимвол __rtinit"
+
+#: xcofflink.c:4057
+msgid "%B: loader reloc in unrecognized section `%s'"
+msgstr "%B: перемещение загрузчика в нераÑпознанном разделе «%s»"
+
+#: xcofflink.c:4068
+msgid "%B: `%s' in loader reloc but not loader sym"
+msgstr "%B: «%s» в перемещении загрузчика, но не Ñимволе загрузчика"
+
+#: xcofflink.c:4084
+msgid "%B: loader reloc in read-only section %A"
+msgstr "%B: перемещение загрузчика в разделе %A, доÑтупном только Ð´Ð»Ñ Ñ‡Ñ‚ÐµÐ½Ð¸Ñ"
+
+#: xcofflink.c:5106
+#, c-format
+msgid "TOC overflow: 0x%lx > 0x10000; try -mminimal-toc when compiling"
+msgstr "переполнение TOC: 0x%lx > 0x10000; попробуйте Ñкомпилировать Ñ -mminimal-toc"
+
+#: elf32-ia64.c:628 elf64-ia64.c:628
+msgid "%B: Can't relax br at 0x%lx in section `%A'. Please use brl or indirect branch."
+msgstr "%B: Ðевозможно оÑлабить br по адреÑу 0x%lx в разделе «%A». ИÑпользуйте brl или коÑвенное ветвление."
+
+#: elf32-ia64.c:2284 elf64-ia64.c:2284
+msgid "@pltoff reloc against local symbol"
+msgstr "перемещение @pltoff Ð´Ð»Ñ Ð»Ð¾ÐºÐ°Ð»ÑŒÐ½Ð¾Ð³Ð¾ Ñимвола"
+
+#: elf32-ia64.c:3687 elf64-ia64.c:3687
+#, c-format
+msgid "%s: short data segment overflowed (0x%lx >= 0x400000)"
+msgstr "%s: переполнение короткого Ñегмента данных (0x%lx >= 0x400000)"
+
+#: elf32-ia64.c:3698 elf64-ia64.c:3698
+#, c-format
+msgid "%s: __gp does not cover short data segment"
+msgstr "%s: __gp не покрывает короткий Ñегмент данных"
+
+#: elf32-ia64.c:3965 elf64-ia64.c:3965
+msgid "%B: non-pic code with imm relocation against dynamic symbol `%s'"
+msgstr "%B: не-pic код Ñ Ð¿ÐµÑ€ÐµÐ¼ÐµÑ‰ÐµÐ½Ð¸ÐµÐ¼ imm Ð´Ð»Ñ Ð´Ð¸Ð½Ð°Ð¼Ð¸Ñ‡ÐµÑкого Ñимвола «%s»"
+
+#: elf32-ia64.c:4032 elf64-ia64.c:4032
+msgid "%B: @gprel relocation against dynamic symbol %s"
+msgstr "%B: перемещение @gprel Ð´Ð»Ñ Ð´Ð¸Ð½Ð°Ð¼Ð¸Ñ‡ÐµÑкого Ñимвола %s"
+
+#: elf32-ia64.c:4095 elf64-ia64.c:4095
+msgid "%B: linking non-pic code in a position independent executable"
+msgstr "%B: компоновка не-pic кода в позиционно-незавиÑимый иÑполнÑемый"
+
+#: elf32-ia64.c:4232 elf64-ia64.c:4232
+msgid "%B: @internal branch to dynamic symbol %s"
+msgstr "%B: ветвление @internal к динамичеÑкому Ñимволу %s"
+
+#: elf32-ia64.c:4234 elf64-ia64.c:4234
+msgid "%B: speculation fixup to dynamic symbol %s"
+msgstr "%B: догадка меÑÑ‚Ð¾Ð¿Ð¾Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ð´Ð¸Ð½Ð°Ð¼Ð¸Ñ‡ÐµÑкого Ñимвола %s"
+
+#: elf32-ia64.c:4236 elf64-ia64.c:4236
+msgid "%B: @pcrel relocation against dynamic symbol %s"
+msgstr "%B: перемещение @pcrel Ð´Ð»Ñ Ð´Ð¸Ð½Ð°Ð¼Ð¸Ñ‡ÐµÑкого Ñимвола %s"
+
+#: elf32-ia64.c:4433 elf64-ia64.c:4433
+msgid "unsupported reloc"
+msgstr "неподдерживаемое перемещение"
+
+#: elf32-ia64.c:4471 elf64-ia64.c:4471
+msgid "%B: missing TLS section for relocation %s against `%s' at 0x%lx in section `%A'."
+msgstr "%B: отÑутÑтвует TLS-раздел Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÐ¼ÐµÑ‰ÐµÐ½Ð¸Ñ %s Ð´Ð»Ñ Â«%s» по адреÑу 0x%lx в разделе «%A»."
+
+#: elf32-ia64.c:4486 elf64-ia64.c:4486
+msgid "%B: Can't relax br (%s) to `%s' at 0x%lx in section `%A' with size 0x%lx (> 0x1000000)."
+msgstr "%B: Ðевозможно оÑлабить br (%s) до «%s» по адреÑу 0x%lx в разделе «%A» Ñ Ñ€Ð°Ð·Ð¼ÐµÑ€Ð¾Ð¼ 0x%lx (> 0x1000000)."
+
+#: elf32-ia64.c:4748 elf64-ia64.c:4748
+msgid "%B: linking trap-on-NULL-dereference with non-trapping files"
+msgstr "%B: компоновка trap-on-NULL-dereference Ñ Ð½Ðµ-trapping файлами"
+
+#: elf32-ia64.c:4757 elf64-ia64.c:4757
+msgid "%B: linking big-endian files with little-endian files"
+msgstr "%B: компоновка файлов Ñ Ð¿Ñ€Ñмым порÑдком байт Ñ Ñ„Ð°Ð¹Ð»Ð°Ð¼Ð¸ Ñ Ð¾Ð±Ñ€Ð°Ñ‚Ð½Ñ‹Ð¼ порÑдком байт"
+
+#: elf32-ia64.c:4766 elf64-ia64.c:4766
+msgid "%B: linking 64-bit files with 32-bit files"
+msgstr "%B: компоновка 64-битных файлов Ñ 32-битными файлами"
+
+#: elf32-ia64.c:4775 elf64-ia64.c:4775
+msgid "%B: linking constant-gp files with non-constant-gp files"
+msgstr "%B: компоновка constant-gp файлов Ñ Ð½Ðµ-constant-gp файлами"
+
+#: elf32-ia64.c:4785 elf64-ia64.c:4785
+msgid "%B: linking auto-pic files with non-auto-pic files"
+msgstr "%B: компоновка auto-pic файлов Ñ Ð½Ðµ-auto-pic файлами"
+
+#: peigen.c:1002 pepigen.c:1002 pex64igen.c:1002
+#, c-format
+msgid "%s: line number overflow: 0x%lx > 0xffff"
+msgstr "%s: переполнение номеров Ñтрок: 0x%lx > 0xffff"
+
+#: peigen.c:1029 pepigen.c:1029 pex64igen.c:1029
+msgid "Export Directory [.edata (or where ever we found it)]"
+msgstr "Каталог ÑкÑпорта [.edata (или где он нашёлÑÑ)]"
+
+#: peigen.c:1030 pepigen.c:1030 pex64igen.c:1030
+msgid "Import Directory [parts of .idata]"
+msgstr "Каталог импорта [чаÑÑ‚ÑŒ .idata]"
+
+#: peigen.c:1031 pepigen.c:1031 pex64igen.c:1031
+msgid "Resource Directory [.rsrc]"
+msgstr "Каталог реÑурÑов [.rsrc]"
+
+#: peigen.c:1032 pepigen.c:1032 pex64igen.c:1032
+msgid "Exception Directory [.pdata]"
+msgstr "Каталог иÑключений [.pdata]"
+
+#: peigen.c:1033 pepigen.c:1033 pex64igen.c:1033
+msgid "Security Directory"
+msgstr "Каталог безопаÑноÑти"
+
+#: peigen.c:1034 pepigen.c:1034 pex64igen.c:1034
+msgid "Base Relocation Directory [.reloc]"
+msgstr "Каталог базового Ð¿ÐµÑ€ÐµÐ¼ÐµÑ‰ÐµÐ½Ð¸Ñ [.reloc]"
+
+#: peigen.c:1035 pepigen.c:1035 pex64igen.c:1035
+msgid "Debug Directory"
+msgstr "Каталог отладки"
+
+#: peigen.c:1036 pepigen.c:1036 pex64igen.c:1036
+msgid "Description Directory"
+msgstr "Каталог опиÑаний"
+
+#: peigen.c:1037 pepigen.c:1037 pex64igen.c:1037
+msgid "Special Directory"
+msgstr "Специальный каталог"
+
+#: peigen.c:1038 pepigen.c:1038 pex64igen.c:1038
+msgid "Thread Storage Directory [.tls]"
+msgstr "Каталог хранилища нитей [.tls]"
+
+#: peigen.c:1039 pepigen.c:1039 pex64igen.c:1039
+msgid "Load Configuration Directory"
+msgstr "Каталог загрузки конфигурации"
+
+#: peigen.c:1040 pepigen.c:1040 pex64igen.c:1040
+msgid "Bound Import Directory"
+msgstr "Каталог обÑзательного импорта"
+
+#: peigen.c:1041 pepigen.c:1041 pex64igen.c:1041
+msgid "Import Address Table Directory"
+msgstr "Каталог таблицы импорта адреÑов"
+
+#: peigen.c:1042 pepigen.c:1042 pex64igen.c:1042
+msgid "Delay Import Directory"
+msgstr "Каталог отложенного импорта"
+
+#: peigen.c:1043 pepigen.c:1043 pex64igen.c:1043
+msgid "CLR Runtime Header"
+msgstr "Заголовок времени Ð²Ñ‹Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ CLR"
+
+#: peigen.c:1044 pepigen.c:1044 pex64igen.c:1044
+msgid "Reserved"
+msgstr "Зарезервировано"
+
+#: peigen.c:1104 pepigen.c:1104 pex64igen.c:1104
+#, c-format
+msgid ""
+"\n"
+"There is an import table, but the section containing it could not be found\n"
+msgstr ""
+"\n"
+"СущеÑтвует таблица импорта, но не найден раздел, в котором она ÑодержитÑÑ\n"
+
+#: peigen.c:1109 pepigen.c:1109 pex64igen.c:1109
+#, c-format
+msgid ""
+"\n"
+"There is an import table in %s at 0x%lx\n"
+msgstr ""
+"\n"
+"Ð’ %s имеетÑÑ Ñ‚Ð°Ð±Ð»Ð¸Ñ†Ð° импорта по адреÑу 0x%lx\n"
+
+#: peigen.c:1151 pepigen.c:1151 pex64igen.c:1151
+#, c-format
+msgid ""
+"\n"
+"Function descriptor located at the start address: %04lx\n"
+msgstr ""
+"\n"
+"Ðачальный Ð°Ð´Ñ€ÐµÑ Ð¾Ð¿Ð¸ÑÐ°Ñ‚ÐµÐ»Ñ Ñ„ÑƒÐ½ÐºÑ†Ð¸Ð¸: %04lx\n"
+
+#: peigen.c:1154 pepigen.c:1154 pex64igen.c:1154
+#, c-format
+msgid "\tcode-base %08lx toc (loadable/actual) %08lx/%08lx\n"
+msgstr "\tcode-base %08lx toc (загружаемый/реальный) %08lx/%08lx\n"
+
+#: peigen.c:1162 pepigen.c:1162 pex64igen.c:1162
+#, c-format
+msgid ""
+"\n"
+"No reldata section! Function descriptor not decoded.\n"
+msgstr ""
+"\n"
+"Ðет раздела reldata! ОпиÑатель функции не раÑшифрован.\n"
+
+#: peigen.c:1167 pepigen.c:1167 pex64igen.c:1167
+#, c-format
+msgid ""
+"\n"
+"The Import Tables (interpreted %s section contents)\n"
+msgstr ""
+"\n"
+"Таблицы импорта (обработан раздел %s)\n"
+
+#: peigen.c:1170 pepigen.c:1170 pex64igen.c:1170
+#, c-format
+msgid ""
+" vma: Hint Time Forward DLL First\n"
+" Table Stamp Chain Name Thunk\n"
+msgstr ""
+" vma: Таблица Отметка Цепочка Ð˜Ð¼Ñ ÐŸÐµÑ€Ð²Ñ‹Ð¹\n"
+" Указаний Времени ПереÑылки DLL Шлюз\n"
+
+#: peigen.c:1218 pepigen.c:1218 pex64igen.c:1218
+#, c-format
+msgid ""
+"\n"
+"\tDLL Name: %s\n"
+msgstr ""
+"\n"
+"\tÐ˜Ð¼Ñ DLL: %s\n"
+
+#: peigen.c:1229 pepigen.c:1229 pex64igen.c:1229
+#, c-format
+msgid "\tvma: Hint/Ord Member-Name Bound-To\n"
+msgstr "\tvma: Hint/Ord ИмÑ-Ñлемента ПривÑзан-к\n"
+
+#: peigen.c:1254 pepigen.c:1254 pex64igen.c:1254
+#, c-format
+msgid ""
+"\n"
+"There is a first thunk, but the section containing it could not be found\n"
+msgstr ""
+"\n"
+"СущеÑтвует первый шлюз, но не найден раздел, в котором он ÑодержитÑÑ\n"
+
+#: peigen.c:1415 pepigen.c:1415 pex64igen.c:1415
+#, c-format
+msgid ""
+"\n"
+"There is an export table, but the section containing it could not be found\n"
+msgstr ""
+"\n"
+"СущеÑтвует таблица ÑкÑпорта, но не найден раздел, в котором она ÑодержитÑÑ\n"
+
+#: peigen.c:1424 pepigen.c:1424 pex64igen.c:1424
+#, c-format
+msgid ""
+"\n"
+"There is an export table in %s, but it does not fit into that section\n"
+msgstr ""
+"\n"
+"СущеÑтвует таблица ÑкÑпорта в %s, но она не помещаетÑÑ Ð² Ñтот раздел\n"
+
+#: peigen.c:1430 pepigen.c:1430 pex64igen.c:1430
+#, c-format
+msgid ""
+"\n"
+"There is an export table in %s at 0x%lx\n"
+msgstr ""
+"\n"
+"СущеÑтвует таблица ÑкÑпорта в %s по адреÑу 0x%lx\n"
+
+#: peigen.c:1458 pepigen.c:1458 pex64igen.c:1458
+#, c-format
+msgid ""
+"\n"
+"The Export Tables (interpreted %s section contents)\n"
+"\n"
+msgstr ""
+"\n"
+"Таблицы ÑкÑпорта (обработан раздел %s)\n"
+"\n"
+
+#: peigen.c:1462 pepigen.c:1462 pex64igen.c:1462
+#, c-format
+msgid "Export Flags \t\t\t%lx\n"
+msgstr "Флаги ÑкÑпорта \t\t\t%lx\n"
+
+#: peigen.c:1465 pepigen.c:1465 pex64igen.c:1465
+#, c-format
+msgid "Time/Date stamp \t\t%lx\n"
+msgstr "Метка времени/даты \t\t%lx\n"
+
+#: peigen.c:1468 pepigen.c:1468 pex64igen.c:1468
+#, c-format
+msgid "Major/Minor \t\t\t%d/%d\n"
+msgstr "Старший/Младший \t\t\t%d/%d\n"
+
+#: peigen.c:1471 pepigen.c:1471 pex64igen.c:1471
+#, c-format
+msgid "Name \t\t\t\t"
+msgstr "Ð˜Ð¼Ñ \t\t\t\t"
+
+#: peigen.c:1477 pepigen.c:1477 pex64igen.c:1477
+#, c-format
+msgid "Ordinal Base \t\t\t%ld\n"
+msgstr "Ðачальный порÑдковый номер \t\t\t%ld\n"
+
+#: peigen.c:1480 pepigen.c:1480 pex64igen.c:1480
+#, c-format
+msgid "Number in:\n"
+msgstr "Ðомер в:\n"
+
+#: peigen.c:1483 pepigen.c:1483 pex64igen.c:1483
+#, c-format
+msgid "\tExport Address Table \t\t%08lx\n"
+msgstr "\tТаблица ÑкÑпортируемых адреÑов \t\t%08lx\n"
+
+#: peigen.c:1487 pepigen.c:1487 pex64igen.c:1487
+#, c-format
+msgid "\t[Name Pointer/Ordinal] Table\t%08lx\n"
+msgstr "\tТаблица [указателей имён/порÑдковых номеров]\t%08lx\n"
+
+#: peigen.c:1490 pepigen.c:1490 pex64igen.c:1490
+#, c-format
+msgid "Table Addresses\n"
+msgstr "Таблица адреÑов\n"
+
+#: peigen.c:1493 pepigen.c:1493 pex64igen.c:1493
+#, c-format
+msgid "\tExport Address Table \t\t"
+msgstr "\tТаблица ÑкÑпортируемых адреÑов \t\t"
+
+#: peigen.c:1498 pepigen.c:1498 pex64igen.c:1498
+#, c-format
+msgid "\tName Pointer Table \t\t"
+msgstr "\tТаблица указателей имён \t\t"
+
+#: peigen.c:1503 pepigen.c:1503 pex64igen.c:1503
+#, c-format
+msgid "\tOrdinal Table \t\t\t"
+msgstr "\tТаблица порÑдковых номеров \t\t\t"
+
+#: peigen.c:1517 pepigen.c:1517 pex64igen.c:1517
+#, c-format
+msgid ""
+"\n"
+"Export Address Table -- Ordinal Base %ld\n"
+msgstr ""
+"\n"
+"Таблица ÑкÑпортируемых адреÑов -- Ðачальный порÑдковый номер %ld\n"
+
+#: peigen.c:1536 pepigen.c:1536 pex64igen.c:1536
+msgid "Forwarder RVA"
+msgstr "ПереадреÑуемый RVA"
+
+#: peigen.c:1547 pepigen.c:1547 pex64igen.c:1547
+msgid "Export RVA"
+msgstr "ЭкÑпортируемый RVA"
+
+#: peigen.c:1554 pepigen.c:1554 pex64igen.c:1554
+#, c-format
+msgid ""
+"\n"
+"[Ordinal/Name Pointer] Table\n"
+msgstr ""
+"\n"
+"Таблица [порÑдковых номеров/указателей имён]\n"
+
+#: peigen.c:1614 peigen.c:1797 pepigen.c:1614 pepigen.c:1797 pex64igen.c:1614
+#: pex64igen.c:1797
+#, c-format
+msgid "Warning, .pdata section size (%ld) is not a multiple of %d\n"
+msgstr "Внимание, размер раздела .pdata (%ld) не кратен %d\n"
+
+#: peigen.c:1621 pepigen.c:1621 pex64igen.c:1621
+#, c-format
+msgid " vma:\t\t\tBegin Address End Address Unwind Info\n"
+msgstr " vma:\t\t\tÐачальный Ð°Ð´Ñ€ÐµÑ ÐšÐ¾Ð½ÐµÑ‡Ð½Ñ‹Ð¹ Ð°Ð´Ñ€ÐµÑ Ð Ð°ÑÐºÑ€Ñ‹Ð²Ð°ÑŽÑ‰Ð°Ñ Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ\n"
+
+#: peigen.c:1623 pepigen.c:1623 pex64igen.c:1623
+#, c-format
+msgid ""
+" vma:\t\tBegin End EH EH PrologEnd Exception\n"
+" \t\tAddress Address Handler Data Address Mask\n"
+msgstr ""
+" vma:\t\tÐачальный Конечный EH EH ÐÐ´Ñ€ÐµÑ ÐœÐ°Ñка\n"
+" \t\tÐÐ´Ñ€ÐµÑ ÐÐ´Ñ€ÐµÑ ÐžÐ±Ñ€Ð°Ð±Ð¾Ñ‚Ñ‡Ð¸Ðº Данные КонцаПролога ИÑключениÑ\n"
+
+#: peigen.c:1697 pepigen.c:1697 pex64igen.c:1697
+#, c-format
+msgid " Register save millicode"
+msgstr " Милликод ÑÐ¾Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ Ñ€ÐµÐ³Ð¸Ñтра"
+
+#: peigen.c:1700 pepigen.c:1700 pex64igen.c:1700
+#, c-format
+msgid " Register restore millicode"
+msgstr " Милликод воÑÑÑ‚Ð°Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ñ€ÐµÐ³Ð¸Ñтра"
+
+#: peigen.c:1703 pepigen.c:1703 pex64igen.c:1703
+#, c-format
+msgid " Glue code sequence"
+msgstr " ПоÑледовательноÑÑ‚ÑŒ ÑвÑзующего кода"
+
+#: peigen.c:1803 pepigen.c:1803 pex64igen.c:1803
+#, c-format
+msgid ""
+" vma:\t\tBegin Prolog Function Flags Exception EH\n"
+" \t\tAddress Length Length 32b exc Handler Data\n"
+msgstr ""
+" vma:\t\tÐачальный Длина Длина Флаги Обработчик EH\n"
+" \t\tÐÐ´Ñ€ÐµÑ ÐŸÑ€Ð¾Ð»Ð¾Ð³Ð° Функции 32b exc ИÑключений Данные\n"
+
+#: peigen.c:1929 pepigen.c:1929 pex64igen.c:1929
+#, c-format
+msgid ""
+"\n"
+"\n"
+"PE File Base Relocations (interpreted .reloc section contents)\n"
+msgstr ""
+"\n"
+"\n"
+"Ðачало перемещений в PE-файле (обработан раздел .reloc)\n"
+
+#: peigen.c:1958 pepigen.c:1958 pex64igen.c:1958
+#, c-format
+msgid ""
+"\n"
+"Virtual Address: %08lx Chunk size %ld (0x%lx) Number of fixups %ld\n"
+msgstr ""
+"\n"
+"Виртуальный адреÑ: %08lx Размер блока %ld (0x%lx) ЧиÑло меÑтоположений %ld\n"
+
+#: peigen.c:1971 pepigen.c:1971 pex64igen.c:1971
+#, c-format
+msgid "\treloc %4d offset %4x [%4lx] %s"
+msgstr "\tперемещение %4d Ñмещение %4x [%4lx] %s"
+
+#. The MS dumpbin program reportedly ands with 0xff0f before
+#. printing the characteristics field. Not sure why. No reason to
+#. emulate it here.
+#: peigen.c:2010 pepigen.c:2010 pex64igen.c:2010
+#, c-format
+msgid ""
+"\n"
+"Characteristics 0x%x\n"
+msgstr ""
+"\n"
+"ХарактериÑтики 0x%x\n"
+
+#: peigen.c:2310 pepigen.c:2310 pex64igen.c:2310
+msgid "%B: unable to fill in DataDictionary[1] because .idata$2 is missing"
+msgstr "%B: невозможно заполнить DataDictionary[1], так как отÑутÑтвует .idata$2"
+
+#: peigen.c:2330 pepigen.c:2330 pex64igen.c:2330
+msgid "%B: unable to fill in DataDictionary[1] because .idata$4 is missing"
+msgstr "%B: невозможно заполнить DataDictionary[1], так как отÑутÑтвует .idata$4"
+
+#: peigen.c:2351 pepigen.c:2351 pex64igen.c:2351
+msgid "%B: unable to fill in DataDictionary[12] because .idata$5 is missing"
+msgstr "%B: невозможно заполнить DataDictionary[12], так как отÑутÑтвует .idata$5"
+
+#: peigen.c:2371 pepigen.c:2371 pex64igen.c:2371
+msgid "%B: unable to fill in DataDictionary[PE_IMPORT_ADDRESS_TABLE (12)] because .idata$6 is missing"
+msgstr "%B: невозможно заполнить DataDictionary[PE_IMPORT_ADDRESS_TABLE (12)], так как отÑутÑтвует .idata$6"
+
+#: peigen.c:2413 pepigen.c:2413 pex64igen.c:2413
+msgid "%B: unable to fill in DataDictionary[PE_IMPORT_ADDRESS_TABLE(12)] because .idata$6 is missing"
+msgstr "%B: невозможно заполнить DataDictionary[PE_IMPORT_ADDRESS_TABLE(12)], так как отÑутÑтвует .idata$6"
+
+#: peigen.c:2438 pepigen.c:2438 pex64igen.c:2438
+msgid "%B: unable to fill in DataDictionary[9] because __tls_used is missing"
+msgstr "%B: невозможно заполнить DataDictionary[9], так как отÑутÑтвует __tls_used"
+
+#~ msgid "%B: error: taking the address of protected function '%s' cannot be done when making a shared library"
+#~ msgstr "%B: ошибка: получение адреÑа защищённой функции «%s» не может быть выполнено при Ñоздании общей библиотеки"
+
+#~ msgid "%B(%A+0x%lx): cannot reach %s"
+#~ msgstr "%B(%A+0x%lx): невозможно добратьÑÑ Ð´Ð¾ %s"
+
+#~ msgid "%B: warning: ignoring duplicate section `%A'\n"
+#~ msgstr "%B: предупреждение: игнорируетÑÑ Ð¿Ð¾Ð²Ñ‚Ð¾Ñ€ÑющийÑÑ Ñ€Ð°Ð·Ð´ÐµÐ» «%A»\n"
+
+#~ msgid "%B: warning: duplicate section `%A' has different size\n"
+#~ msgstr "%B: предупреждение: повторÑющийÑÑ Ñ€Ð°Ð·Ð´ÐµÐ» «%A» имеет другой размер\n"
+
+#~ msgid "relocation references a different segment"
+#~ msgstr "перемещение указывает на другой Ñегмент"
+
+#~ msgid "%B: relocation type %d not implemented"
+#~ msgstr "%B: тип Ð¿ÐµÑ€ÐµÐ¼ÐµÑ‰ÐµÐ½Ð¸Ñ Â«%s» не реализован"
+
+#~ msgid "warning: %B and %B differ in position-dependence of data addressing"
+#~ msgstr "предупреждение: в %B и %B различаетÑÑ Ð°Ð´Ñ€ÐµÑÐ°Ñ†Ð¸Ñ Ð½ÐµÐ·Ð°Ð²Ð¸Ñимых по Ð¿Ð¾Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ð´Ð°Ð½Ð½Ñ‹Ñ…"
+
+#~ msgid "warning: %B and %B differ in position-dependence of code addressing"
+#~ msgstr "предупреждение: в %B и %B различаетÑÑ Ð°Ð´Ñ€ÐµÑÐ°Ñ†Ð¸Ñ Ð½ÐµÐ·Ð°Ð²Ð¸Ñимого по Ð¿Ð¾Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ ÐºÐ¾Ð´Ð°"
+
+#~ msgid "Can't Make it a Short Jump"
+#~ msgstr "Ðевозможно выполнить короткий переход (Short Jump)"
+
+#~ msgid "Exceeds Long Jump Range"
+#~ msgstr "Превышен диапазон длинного перехода (Long Jump)"
+
+#~ msgid "Absolute address Exceeds 16 bit Range"
+#~ msgstr "ÐбÑолютный Ð°Ð´Ñ€ÐµÑ Ð²Ñ‹Ñ…Ð¾Ð´Ð¸Ñ‚ за 16-битный диапазон"
+
+#~ msgid "Absolute address Exceeds 8 bit Range"
+#~ msgstr "ÐбÑолютный Ð°Ð´Ñ€ÐµÑ Ð²Ñ‹Ñ…Ð¾Ð´Ð¸Ñ‚ за 8-битный диапазон"
+
+#~ msgid "Unrecognized Reloc Type"
+#~ msgstr "Ðе раÑпознан тип Ð¿ÐµÑ€ÐµÐ¼ÐµÑ‰ÐµÐ½Ð¸Ñ (Reloc Type)"
+
+#~ msgid "corrupt or empty %s section in %B"
+#~ msgstr "повреждённый или пуÑтой раздел %s в %B"
+
+#~ msgid "%s: invalid DSO for symbol `%s' definition"
+#~ msgstr "%s: недопуÑтимый DSO Ð´Ð»Ñ Ð¾Ð¿Ñ€ÐµÐ´ÐµÐ»ÐµÐ½Ð¸Ñ Ñимвола `%s'"
+
+#~ msgid "%B: %A+0x%lx: jump to stub routine which is not jal"
+#~ msgstr "%B: %A+0x%lx: переход в процедуру заглушки, ÐºÐ¾Ñ‚Ð¾Ñ€Ð°Ñ Ð½Ðµ не ÑвлÑетÑÑ jal (Jump And Link)"
+
+#~ msgid "bfd_make_section (%s) failed"
+#~ msgstr "bfd_make_section (%s) завершилаÑÑŒ неудачно"
+
+#~ msgid "bfd_set_section_flags (%s, %x) failed"
+#~ msgstr "bfd_set_section_flags (%s, %x) завершилаÑÑŒ неудачно"
+
+#~ msgid "Size mismatch section %s=%lx, %s=%lx"
+#~ msgstr "ÐеÑовпадение размера раздела %s=%lx, %s=%lx"
+
+#~ msgid "failed to enter %s"
+#~ msgstr "не удалоÑÑŒ войти %s"
+
+#~ msgid "No Mem !"
+#~ msgstr "Ðет Mem !"
+
+#~ msgid "reserved STO cmd %d"
+#~ msgstr "зарезервированный STO cmd %d"
+
+#~ msgid "reserved OPR cmd %d"
+#~ msgstr "зарезервированный OPR cmd %d"
+
+#~ msgid "reserved CTL cmd %d"
+#~ msgstr "зарезервированный CTL cmd %d"
+
+#~ msgid "reserved STC cmd %d"
+#~ msgstr "зарезервированный STC cmd %d"
+
+#~ msgid "stack-from-image not implemented"
+#~ msgstr "stack-from-image не реализован"
+
+#~ msgid "stack-entry-mask not fully implemented"
+#~ msgstr "stack-entry-mask реализован не полноÑтью"
+
+#~ msgid "PASSMECH not fully implemented"
+#~ msgstr "PASSMECH реализован не полноÑтью"
+
+#~ msgid "stack-local-symbol not fully implemented"
+#~ msgstr "stack-local-symbol реализован не полноÑтью"
+
+#~ msgid "stack-literal not fully implemented"
+#~ msgstr "stack-literal реализован не полноÑтью"
+
+#~ msgid "stack-local-symbol-entry-point-mask not fully implemented"
+#~ msgstr "stack-local-symbol-entry-point-mask реализован не полноÑтью"
+
+#~ msgid "%s: not fully implemented"
+#~ msgstr "%s: реализовано не полноÑтью"
+
+#~ msgid "obj code %d not found"
+#~ msgstr "объектный код %d не найден"
+
+#~ msgid "Reloc size error in section %s"
+#~ msgstr "Ошибка размера Ð¿ÐµÑ€ÐµÐ¼ÐµÑ‰ÐµÐ½Ð¸Ñ Ð² разделе %s"
diff --git a/bfd/po/rw.gmo b/bfd/po/rw.gmo
new file mode 100644
index 0000000..49d9e2f
--- /dev/null
+++ b/bfd/po/rw.gmo
Binary files differ
diff --git a/bfd/po/rw.po b/bfd/po/rw.po
new file mode 100644
index 0000000..42525d4
--- /dev/null
+++ b/bfd/po/rw.po
@@ -0,0 +1,3101 @@
+# translation of bfd to Kinyarwanda.
+# Copyright (C) 2005 Free Software Foundation, Inc.
+# This file is distributed under the same license as the bfd package.
+# Steve Murphy <murf@e-tools.com>, 2005
+# Steve performed initial rough translation from compendium built from translations provided by the following translators:
+# Philibert Ndandali <ndandali@yahoo.fr>, 2005.
+# Viateur MUGENZI <muvia1@yahoo.fr>, 2005.
+# Noëlla Mupole <s24211045@tuks.co.za>, 2005.
+# Carole Karema <karemacarole@hotmail.com>, 2005.
+# JEAN BAPTISTE NGENDAHAYO <ngenda_denis@yahoo.co.uk>, 2005.
+# Augustin KIBERWA <akiberwa@yahoo.co.uk>, 2005.
+# Donatien NSENGIYUMVA <ndonatienuk@yahoo.co.uk>, 2005.
+# Antoine Bigirimana <antoine@e-tools.com>, 2005.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: bfd 2.15\n"
+"POT-Creation-Date: 2003-07-17 14:52+0100\n"
+"PO-Revision-Date: 2005-04-03 10:55-0700\n"
+"Last-Translator: Steven Michael Murphy <murf@e-tools.com>\n"
+"Language-Team: Kinyarwanda <translation-team-rw@lists.sourceforge.net>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: aout-adobe.c:204
+#, fuzzy, c-format
+msgid "%s: Unknown section type in a.out.adobe file: %x\n"
+msgstr "%s:Inyuma."
+
+#: aout-cris.c:207
+#, fuzzy, c-format
+msgid "%s: Invalid relocation type exported: %d"
+msgstr "%s:Ubwoko"
+
+#: aout-cris.c:251
+#, fuzzy, c-format
+msgid "%s: Invalid relocation type imported: %d"
+msgstr "%s:Ubwoko cyavuye ahandi/ cyatumijwe"
+
+#: aout-cris.c:262
+#, fuzzy, c-format
+msgid "%s: Bad relocation record imported: %d"
+msgstr "%s:Icyabitswe cyavuye ahandi/ cyatumijwe"
+
+#: aoutx.h:1295 aoutx.h:1716
+#, fuzzy, c-format
+msgid "%s: can not represent section `%s' in a.out object file format"
+msgstr "%s:OYA Icyiciro in a Inyuma Igikoresho IDOSIYE Imiterere"
+
+#: aoutx.h:1682
+#, fuzzy, c-format
+msgid "%s: can not represent section for symbol `%s' in a.out object file format"
+msgstr "%s:OYA Icyiciro kugirango IKIMENYETSO in a Inyuma Igikoresho IDOSIYE Imiterere"
+
+#: aoutx.h:1684
+#, fuzzy
+msgid "*unknown*"
+msgstr "*Itazwi>"
+
+#: aoutx.h:3776
+#, fuzzy, c-format
+msgid "%s: relocatable link from %s to %s not supported"
+msgstr "%s:Ihuza Bivuye Kuri OYA"
+
+#: archive.c:1751
+#, fuzzy
+msgid "Warning: writing archive was slow: rewriting timestamp\n"
+msgstr "Buhoro"
+
+#: archive.c:2014
+#, fuzzy
+msgid "Reading archive file mod timestamp"
+msgstr "IDOSIYE MOD"
+
+#: archive.c:2040
+msgid "Writing updated armap timestamp"
+msgstr ""
+
+# padmin/source\padialog.src:RID_AFMERROR_OK.text
+#: bfd.c:280
+msgid "No error"
+msgstr "Nta kosa"
+
+#: bfd.c:281
+#, fuzzy
+msgid "System call error"
+msgstr "Ikosa"
+
+#: bfd.c:282
+#, fuzzy
+msgid "Invalid bfd target"
+msgstr "Intego"
+
+#: bfd.c:283
+#, fuzzy
+msgid "File in wrong format"
+msgstr "Idosiye in Imiterere"
+
+#: bfd.c:284
+#, fuzzy
+msgid "Archive object file in wrong format"
+msgstr "Igikoresho IDOSIYE in Imiterere"
+
+#: bfd.c:285
+msgid "Invalid operation"
+msgstr ""
+
+#: bfd.c:286
+msgid "Memory exhausted"
+msgstr ""
+
+#: bfd.c:287
+#, fuzzy
+msgid "No symbols"
+msgstr "Ibimenyetso"
+
+#: bfd.c:288
+#, fuzzy
+msgid "Archive has no index; run ranlib to add one"
+msgstr "Oya Umubarendanga Gukoresha Kuri Kongeramo"
+
+#: bfd.c:289
+#, fuzzy
+msgid "No more archived files"
+msgstr "Birenzeho Idosiye"
+
+#: bfd.c:290
+msgid "Malformed archive"
+msgstr ""
+
+#: bfd.c:291
+#, fuzzy
+msgid "File format not recognized"
+msgstr "Idosiye Imiterere OYA"
+
+#: bfd.c:292
+#, fuzzy
+msgid "File format is ambiguous"
+msgstr "Idosiye Imiterere ni"
+
+#: bfd.c:293
+#, fuzzy
+msgid "Section has no contents"
+msgstr "Oya Ibigize"
+
+#: bfd.c:294
+#, fuzzy
+msgid "Nonrepresentable section on output"
+msgstr "Icyiciro ku Ibisohoka"
+
+#: bfd.c:295
+#, fuzzy
+msgid "Symbol needs debug section which does not exist"
+msgstr "Kosora amakosa Icyiciro OYA"
+
+#: bfd.c:296
+#, fuzzy
+msgid "Bad value"
+msgstr "Agaciro"
+
+#: bfd.c:297
+#, fuzzy
+msgid "File truncated"
+msgstr "Idosiye"
+
+#: bfd.c:298
+#, fuzzy
+msgid "File too big"
+msgstr "Idosiye"
+
+#: bfd.c:299
+#, fuzzy
+msgid "#<Invalid error code>"
+msgstr "#<Ikosa ITEGEKONGENGA"
+
+#: bfd.c:687
+#, c-format
+msgid "BFD %s assertion fail %s:%d"
+msgstr ""
+
+#: bfd.c:703
+#, fuzzy, c-format
+msgid "BFD %s internal error, aborting at %s line %d in %s\n"
+msgstr "By'imbere Ikosa ku Umurongo in"
+
+#: bfd.c:707
+#, fuzzy, c-format
+msgid "BFD %s internal error, aborting at %s line %d\n"
+msgstr "By'imbere Ikosa ku Umurongo"
+
+#: bfd.c:709
+#, fuzzy
+msgid "Please report this bug.\n"
+msgstr "Icyegeranyo iyi"
+
+#: bfdwin.c:202
+#, fuzzy, c-format
+msgid "not mapping: data=%lx mapped=%d\n"
+msgstr "OYA Igereranya Ibyatanzwe"
+
+#: bfdwin.c:205
+#, fuzzy
+msgid "not mapping: env var not set\n"
+msgstr "OYA Igereranya VAR OYA"
+
+#: binary.c:306
+#, fuzzy, c-format
+msgid "Warning: Writing section `%s' to huge (ie negative) file offset 0x%lx."
+msgstr "Icyiciro Kuri IDOSIYE Nta- boneza"
+
+#: coff-rs6000.c:3616 coff64-rs6000.c:2109
+#, fuzzy, c-format
+msgid "%s: symbol `%s' has unrecognized smclas %d"
+msgstr "%s:IKIMENYETSO"
+
+#: coff-a29k.c:120
+msgid "Missing IHCONST"
+msgstr ""
+
+#: coff-a29k.c:181
+msgid "Missing IHIHALF"
+msgstr ""
+
+#: coff-a29k.c:213 coff-or32.c:236
+msgid "Unrecognized reloc"
+msgstr ""
+
+#: coff-a29k.c:409
+#, fuzzy
+msgid "missing IHCONST reloc"
+msgstr "Ibuze"
+
+#: coff-a29k.c:499
+#, fuzzy
+msgid "missing IHIHALF reloc"
+msgstr "Ibuze"
+
+#: coff-alpha.c:884 coff-alpha.c:921 coff-alpha.c:1992 coff-mips.c:1397
+#, fuzzy
+msgid "GP relative relocation used when GP not defined"
+msgstr "Bifitanye isano Ryari: OYA"
+
+#: coff-alpha.c:1488
+#, fuzzy
+msgid "using multiple gp values"
+msgstr "ikoresha Igikubo Uduciro"
+
+#: coff-arm.c:1066 elf32-arm.h:294
+#, fuzzy, c-format
+msgid "%s: unable to find THUMB glue '%s' for `%s'"
+msgstr "%s:Kuri Gushaka kugirango"
+
+#: coff-arm.c:1096 elf32-arm.h:329
+#, fuzzy, c-format
+msgid "%s: unable to find ARM glue '%s' for `%s'"
+msgstr "%s:Kuri Gushaka kugirango"
+
+#: coff-arm.c:1394 coff-arm.c:1489 elf32-arm.h:892 elf32-arm.h:999
+#, fuzzy, c-format
+msgid "%s(%s): warning: interworking not enabled."
+msgstr "%s(%s):Iburira OYA Bikora"
+
+#: coff-arm.c:1398 elf32-arm.h:1002
+#, fuzzy, c-format
+msgid " first occurrence: %s: arm call to thumb"
+msgstr "Itangira ukugaragara Kuri"
+
+#: coff-arm.c:1493 elf32-arm.h:895
+#, fuzzy, c-format
+msgid " first occurrence: %s: thumb call to arm"
+msgstr "Itangira ukugaragara Kuri"
+
+#: coff-arm.c:1496
+#, fuzzy
+msgid " consider relinking with --support-old-code enabled"
+msgstr "Na: Gushigikira ki/ bishaje ITEGEKONGENGA Bikora"
+
+#: coff-arm.c:1788 coff-tic80.c:687 cofflink.c:3038
+#, fuzzy, c-format
+msgid "%s: bad reloc address 0x%lx in section `%s'"
+msgstr "%s:Aderesi in Icyiciro"
+
+#: coff-arm.c:2132
+#, fuzzy, c-format
+msgid "%s: illegal symbol index in reloc: %d"
+msgstr "%s:IKIMENYETSO Umubarendanga in"
+
+#: coff-arm.c:2265
+#, fuzzy, c-format
+msgid "ERROR: %s is compiled for APCS-%d, whereas %s is compiled for APCS-%d"
+msgstr "ni kugirango ni kugirango"
+
+#: coff-arm.c:2280 elf32-arm.h:2328
+#, fuzzy, c-format
+msgid "ERROR: %s passes floats in float registers, whereas %s passes them in integer registers"
+msgstr "in Kureremba in Umubare wuzuye"
+
+#: coff-arm.c:2283 elf32-arm.h:2333
+#, fuzzy, c-format
+msgid "ERROR: %s passes floats in integer registers, whereas %s passes them in float registers"
+msgstr "in Umubare wuzuye in Kureremba"
+
+#: coff-arm.c:2298
+#, fuzzy, c-format
+msgid "ERROR: %s is compiled as position independent code, whereas target %s is absolute position"
+msgstr "ni Nka Ibirindiro ITEGEKONGENGA Intego ni Ibirindiro"
+
+#: coff-arm.c:2301
+#, fuzzy, c-format
+msgid "ERROR: %s is compiled as absolute position code, whereas target %s is position independent"
+msgstr "ni Nka Ibirindiro ITEGEKONGENGA Intego ni Ibirindiro"
+
+#: coff-arm.c:2330 elf32-arm.h:2405
+#, fuzzy, c-format
+msgid "Warning: %s supports interworking, whereas %s does not"
+msgstr "OYA"
+
+#: coff-arm.c:2333 elf32-arm.h:2412
+#, fuzzy, c-format
+msgid "Warning: %s does not support interworking, whereas %s does"
+msgstr "OYA Gushigikira"
+
+#: coff-arm.c:2360
+#, fuzzy, c-format
+msgid "private flags = %x:"
+msgstr "By'umwihariko Amabendera"
+
+#: coff-arm.c:2368 elf32-arm.h:2467
+#, fuzzy
+msgid " [floats passed in float registers]"
+msgstr "[in Kureremba"
+
+#: coff-arm.c:2370
+#, fuzzy
+msgid " [floats passed in integer registers]"
+msgstr "[in Umubare wuzuye"
+
+#: coff-arm.c:2373 elf32-arm.h:2470
+#, fuzzy
+msgid " [position independent]"
+msgstr "[Ibirindiro"
+
+#: coff-arm.c:2375
+#, fuzzy
+msgid " [absolute position]"
+msgstr "[Ibirindiro"
+
+#: coff-arm.c:2379
+#, fuzzy
+msgid " [interworking flag not initialised]"
+msgstr "[Ibendera OYA"
+
+#: coff-arm.c:2381
+msgid " [interworking supported]"
+msgstr ""
+
+#: coff-arm.c:2383
+#, fuzzy
+msgid " [interworking not supported]"
+msgstr "[OYA"
+
+#: coff-arm.c:2431 elf32-arm.h:2150
+#, fuzzy, c-format
+msgid "Warning: Not setting interworking flag of %s since it has already been specified as non-interworking"
+msgstr "Igenamiterere Ibendera Bya guhera Nka"
+
+#: coff-arm.c:2435 elf32-arm.h:2154
+#, fuzzy, c-format
+msgid "Warning: Clearing the interworking flag of %s due to outside request"
+msgstr "i Ibendera Bya Kuri Hanze Kubaza..."
+
+#: coffcode.h:1108
+#, fuzzy, c-format
+msgid "%s (%s): Section flag %s (0x%x) ignored"
+msgstr "%s(%s):Ibendera"
+
+#: coffcode.h:2214
+#, fuzzy, c-format
+msgid "Unrecognized TI COFF target id '0x%x'"
+msgstr "Intego ID"
+
+#: coffcode.h:4439
+#, fuzzy, c-format
+msgid "%s: warning: illegal symbol index %ld in line numbers"
+msgstr "%s:Iburira IKIMENYETSO Umubarendanga in Umurongo Imibare"
+
+#: coffcode.h:4453
+#, fuzzy, c-format
+msgid "%s: warning: duplicate line number information for `%s'"
+msgstr "%s:Iburira Gusubiramo Umurongo Umubare Ibisobanuro kugirango"
+
+#: coffcode.h:4807
+#, fuzzy, c-format
+msgid "%s: Unrecognized storage class %d for %s symbol `%s'"
+msgstr "%s:ishuri kugirango IKIMENYETSO"
+
+#: coffcode.h:4940
+#, fuzzy, c-format
+msgid "warning: %s: local symbol `%s' has no section"
+msgstr "Iburira IKIMENYETSO Oya Icyiciro"
+
+#: coff-tic4x.c:218 coff-tic54x.c:373 coffcode.h:5047
+#, fuzzy, c-format
+msgid "%s: warning: illegal symbol index %ld in relocs"
+msgstr "%s:Iburira IKIMENYETSO Umubarendanga in"
+
+#: coffcode.h:5085
+#, fuzzy, c-format
+msgid "%s: illegal relocation type %d at address 0x%lx"
+msgstr "%s:Ubwoko ku Aderesi"
+
+#: coffgen.c:1666
+#, fuzzy, c-format
+msgid "%s: bad string table size %lu"
+msgstr "%s:Ikurikiranyanyuguti imbonerahamwe# Ingano"
+
+#: coff-h8300.c:1047
+#, fuzzy, c-format
+msgid "cannot handle R_MEM_INDIRECT reloc when using %s output"
+msgstr "Ryari: ikoresha Ibisohoka"
+
+#: coff-i960.c:137 coff-i960.c:486
+#, fuzzy
+msgid "uncertain calling convention for non-COFF symbol"
+msgstr "kugirango IKIMENYETSO"
+
+#: cofflink.c:538 elflink.h:1276
+#, fuzzy, c-format
+msgid "Warning: type of symbol `%s' changed from %d to %d in %s"
+msgstr "Ubwoko Bya IKIMENYETSO Byahinduwe Bivuye Kuri in"
+
+#: cofflink.c:2328
+#, fuzzy, c-format
+msgid "%s: relocs in section `%s', but it has no contents"
+msgstr "%s:in Icyiciro Oya Ibigize"
+
+#: cofflink.c:2671 coffswap.h:890
+#, fuzzy, c-format
+msgid "%s: %s: reloc overflow: 0x%lx > 0xffff"
+msgstr "%s:%s:Byarenze urugero"
+
+#: cofflink.c:2680 coffswap.h:876
+#, fuzzy, c-format
+msgid "%s: warning: %s: line number overflow: 0x%lx > 0xffff"
+msgstr "%s:Iburira Umurongo Umubare Byarenze urugero"
+
+#: coff-m68k.c:482 coff-mips.c:2394 elf32-m68k.c:2193 elf32-mips.c:1783
+#, fuzzy
+msgid "unsupported reloc type"
+msgstr "Ubwoko"
+
+#: coff-mips.c:839 elf32-mips.c:1088 elf64-mips.c:1590 elfn32-mips.c:1554
+#, fuzzy
+msgid "GP relative relocation when _gp not defined"
+msgstr "Bifitanye isano Ryari: OYA"
+
+#. No other sections should appear in -membedded-pic
+#. code.
+#: coff-mips.c:2431
+#, fuzzy
+msgid "reloc against unsupported section"
+msgstr "Icyiciro"
+
+#: coff-mips.c:2439
+#, fuzzy
+msgid "reloc not properly aligned"
+msgstr "OYA"
+
+#: coff-rs6000.c:2790
+#, fuzzy, c-format
+msgid "%s: unsupported relocation type 0x%02x"
+msgstr "%s:Ubwoko"
+
+#: coff-rs6000.c:2883
+#, fuzzy, c-format
+msgid "%s: TOC reloc at 0x%x to symbol `%s' with no TOC entry"
+msgstr "%s:ku Kuri IKIMENYETSO Na: Oya Icyinjijwe"
+
+#: coff-tic4x.c:170 coff-tic54x.c:288 coff-tic80.c:450
+#, fuzzy, c-format
+msgid "Unrecognized reloc type 0x%x"
+msgstr "Ubwoko"
+
+#: coff-w65.c:364
+#, c-format
+msgid "ignoring reloc %s\n"
+msgstr ""
+
+#: cpu-arm.c:196 cpu-arm.c:206
+#, fuzzy, c-format
+msgid "ERROR: %s is compiled for the EP9312, whereas %s is compiled for XScale"
+msgstr "ni kugirango i ni kugirango"
+
+#: cpu-arm.c:344
+#, fuzzy, c-format
+msgid "warning: unable to update contents of %s section in %s"
+msgstr "Iburira Kuri Kuvugurura Ibigize Bya Icyiciro in"
+
+#: dwarf2.c:380
+#, fuzzy
+msgid "Dwarf Error: Can't find .debug_str section."
+msgstr "Gushaka Icyiciro"
+
+#: dwarf2.c:397
+#, fuzzy, c-format
+msgid "Dwarf Error: DW_FORM_strp offset (%lu) greater than or equal to .debug_str size (%lu)."
+msgstr "Nta- boneza Biruta Cyangwa bingana Kuri Ingano"
+
+#: dwarf2.c:541
+#, fuzzy
+msgid "Dwarf Error: Can't find .debug_abbrev section."
+msgstr "Gushaka Icyiciro"
+
+#: dwarf2.c:556
+#, fuzzy, c-format
+msgid "Dwarf Error: Abbrev offset (%lu) greater than or equal to .debug_abbrev size (%lu)."
+msgstr "Nta- boneza Biruta Cyangwa bingana Kuri Ingano"
+
+#: dwarf2.c:756
+#, fuzzy, c-format
+msgid "Dwarf Error: Invalid or unhandled FORM value: %u."
+msgstr "Cyangwa Agaciro"
+
+#: dwarf2.c:933
+#, fuzzy
+msgid "Dwarf Error: mangled line number section (bad file number)."
+msgstr "Umurongo Umubare Icyiciro IDOSIYE Umubare"
+
+#: dwarf2.c:1032
+#, fuzzy
+msgid "Dwarf Error: Can't find .debug_line section."
+msgstr "Gushaka Icyiciro"
+
+#: dwarf2.c:1049
+#, fuzzy, c-format
+msgid "Dwarf Error: Line offset (%lu) greater than or equal to .debug_line size (%lu)."
+msgstr "Nta- boneza Biruta Cyangwa bingana Kuri Ingano"
+
+#: dwarf2.c:1255
+#, fuzzy
+msgid "Dwarf Error: mangled line number section."
+msgstr "Umurongo Umubare Icyiciro"
+
+#: dwarf2.c:1470 dwarf2.c:1620
+#, fuzzy, c-format
+msgid "Dwarf Error: Could not find abbrev number %u."
+msgstr "OYA Gushaka Umubare"
+
+#: dwarf2.c:1581
+#, fuzzy, c-format
+msgid "Dwarf Error: found dwarf version '%u', this reader only handles version 2 information."
+msgstr "Byabonetse Verisiyo iyi Verisiyo 2. Ibisobanuro"
+
+#: dwarf2.c:1588
+#, fuzzy, c-format
+msgid "Dwarf Error: found address size '%u', this reader can not handle sizes greater than '%u'."
+msgstr "Byabonetse Aderesi Ingano iyi OYA Biruta"
+
+#: dwarf2.c:1611
+#, fuzzy, c-format
+msgid "Dwarf Error: Bad abbrev number: %u."
+msgstr "Umubare"
+
+#: ecoff.c:1339
+#, fuzzy, c-format
+msgid "Unknown basic type %d"
+msgstr "BASIC Ubwoko"
+
+#: ecoff.c:1599
+#, fuzzy, c-format
+msgid ""
+"\n"
+" End+1 symbol: %ld"
+msgstr "Impera 1. IKIMENYETSO"
+
+#: ecoff.c:1606 ecoff.c:1609
+#, fuzzy, c-format
+msgid ""
+"\n"
+" First symbol: %ld"
+msgstr "IKIMENYETSO"
+
+#: ecoff.c:1621
+#, fuzzy, c-format
+msgid ""
+"\n"
+" End+1 symbol: %-7ld Type: %s"
+msgstr "Impera 1. IKIMENYETSO"
+
+#: ecoff.c:1628
+#, fuzzy, c-format
+msgid ""
+"\n"
+" Local symbol: %ld"
+msgstr "IKIMENYETSO"
+
+#: ecoff.c:1636
+#, fuzzy, c-format
+msgid ""
+"\n"
+" struct; End+1 symbol: %ld"
+msgstr "Impera 1. IKIMENYETSO"
+
+#: ecoff.c:1641
+#, fuzzy, c-format
+msgid ""
+"\n"
+" union; End+1 symbol: %ld"
+msgstr "Ihuza Impera 1. IKIMENYETSO"
+
+#: ecoff.c:1646
+#, fuzzy, c-format
+msgid ""
+"\n"
+" enum; End+1 symbol: %ld"
+msgstr "Impera 1. IKIMENYETSO"
+
+# #-#-#-#-# dbaccess.pot (PACKAGE VERSION) #-#-#-#-#
+# #-#-#-#-# dbaccess.pot (PACKAGE VERSION) #-#-#-#-#
+#: ecoff.c:1652
+#, fuzzy, c-format
+msgid ""
+"\n"
+" Type: %s"
+msgstr "Ubwoko"
+
+#: elf32-arm.h:1228
+#, fuzzy, c-format
+msgid "%s: Warning: Arm BLX instruction targets Arm function '%s'."
+msgstr "%s:Umumaro"
+
+#: elf32-arm.h:1424
+#, fuzzy, c-format
+msgid "%s: Warning: Thumb BLX instruction targets thumb function '%s'."
+msgstr "%s:Umumaro"
+
+#: elf32-arm.h:1918 elf32-sh.c:4706 elf64-sh64.c:1613
+#, fuzzy, c-format
+msgid "%s(%s+0x%lx): %s relocation against SEC_MERGE section"
+msgstr "%s(%s+0x%lx):%sIcyiciro"
+
+#: elf32-arm.h:2012
+#, fuzzy, c-format
+msgid "%s: warning: unresolvable relocation %d against symbol `%s' from %s section"
+msgstr "%s:Iburira IKIMENYETSO Bivuye Icyiciro"
+
+#: elf-m10200.c:442 elf-m10300.c:1695 elf32-arm.h:2088 elf32-avr.c:812
+#: elf32-cris.c:1390 elf32-d10v.c:482 elf32-fr30.c:634 elf32-frv.c:815
+#: elf32-h8300.c:509 elf32-i860.c:1028 elf32-ip2k.c:1586 elf32-iq2000.c:699
+#: elf32-m32r.c:1283 elf32-m68hc1x.c:1305 elf32-msp430.c:510
+#: elf32-openrisc.c:436 elf32-v850.c:1777 elf32-xstormy16.c:976
+#: elf64-mmix.c:1332
+#, fuzzy
+msgid "internal error: out of range error"
+msgstr "By'imbere Ikosa Inyuma Bya Urutonde Ikosa"
+
+#: elf-m10200.c:446 elf-m10300.c:1699 elf32-arm.h:2092 elf32-avr.c:816
+#: elf32-cris.c:1394 elf32-d10v.c:486 elf32-fr30.c:638 elf32-frv.c:819
+#: elf32-h8300.c:513 elf32-i860.c:1032 elf32-iq2000.c:703 elf32-m32r.c:1287
+#: elf32-m68hc1x.c:1309 elf32-msp430.c:514 elf32-openrisc.c:440
+#: elf32-v850.c:1781 elf32-xstormy16.c:980 elf64-mmix.c:1336 elfxx-mips.c:6452
+#, fuzzy
+msgid "internal error: unsupported relocation error"
+msgstr "By'imbere Ikosa Ikosa"
+
+#: elf-m10200.c:450 elf-m10300.c:1703 elf32-arm.h:2096 elf32-d10v.c:490
+#: elf32-h8300.c:517 elf32-m32r.c:1291 elf32-m68hc1x.c:1313
+#, fuzzy
+msgid "internal error: dangerous error"
+msgstr "By'imbere Ikosa Ikosa"
+
+#: elf-m10200.c:454 elf-m10300.c:1707 elf32-arm.h:2100 elf32-avr.c:824
+#: elf32-cris.c:1402 elf32-d10v.c:494 elf32-fr30.c:646 elf32-frv.c:827
+#: elf32-h8300.c:521 elf32-i860.c:1040 elf32-ip2k.c:1601 elf32-iq2000.c:711
+#: elf32-m32r.c:1295 elf32-m68hc1x.c:1317 elf32-msp430.c:522
+#: elf32-openrisc.c:448 elf32-v850.c:1801 elf32-xstormy16.c:988
+#: elf64-mmix.c:1344
+#, fuzzy
+msgid "internal error: unknown error"
+msgstr "By'imbere Ikosa Kitazwi Ikosa"
+
+#: elf32-arm.h:2202
+#, fuzzy, c-format
+msgid "Warning: Clearing the interworking flag of %s because non-interworking code in %s has been linked with it"
+msgstr "i Ibendera Bya ITEGEKONGENGA in Na:"
+
+#: elf32-arm.h:2302
+#, fuzzy, c-format
+msgid "ERROR: %s is compiled for EABI version %d, whereas %s is compiled for version %d"
+msgstr "ni kugirango Verisiyo ni kugirango Verisiyo"
+
+#: elf32-arm.h:2316
+#, fuzzy, c-format
+msgid "ERROR: %s is compiled for APCS-%d, whereas target %s uses APCS-%d"
+msgstr "ni kugirango Intego"
+
+#: elf32-arm.h:2344
+#, fuzzy, c-format
+msgid "ERROR: %s uses VFP instructions, whereas %s does not"
+msgstr "Amabwiriza OYA"
+
+#: elf32-arm.h:2349
+#, fuzzy, c-format
+msgid "ERROR: %s uses FPA instructions, whereas %s does not"
+msgstr "Amabwiriza OYA"
+
+#: elf32-arm.h:2360 elf32-arm.h:2365
+#, fuzzy, c-format
+msgid "ERROR: %s uses Maverick instructions, whereas %s does not"
+msgstr "Amabwiriza OYA"
+
+#: elf32-arm.h:2385
+#, c-format
+msgid "ERROR: %s uses software FP, whereas %s uses hardware FP"
+msgstr ""
+
+#: elf32-arm.h:2390
+#, c-format
+msgid "ERROR: %s uses hardware FP, whereas %s uses software FP"
+msgstr ""
+
+#. Ignore init flag - it may not be set, despite the flags field
+#. containing valid data.
+#: elf32-arm.h:2443 elf32-cris.c:2975 elf32-m68hc1x.c:1459 elf32-m68k.c:397
+#: elf32-vax.c:546 elfxx-mips.c:9240
+#, fuzzy, c-format
+msgid "private flags = %lx:"
+msgstr "By'umwihariko Amabendera"
+
+#: elf32-arm.h:2452
+#, fuzzy
+msgid " [interworking enabled]"
+msgstr "[Bikora"
+
+#: elf32-arm.h:2460
+#, fuzzy
+msgid " [VFP float format]"
+msgstr "[Kureremba Imiterere"
+
+#: elf32-arm.h:2462
+#, fuzzy
+msgid " [Maverick float format]"
+msgstr "[Kureremba Imiterere"
+
+#: elf32-arm.h:2464
+#, fuzzy
+msgid " [FPA float format]"
+msgstr "[Kureremba Imiterere"
+
+#: elf32-arm.h:2473
+#, fuzzy
+msgid " [new ABI]"
+msgstr "[Gishya"
+
+#: elf32-arm.h:2476
+#, fuzzy
+msgid " [old ABI]"
+msgstr "[ki/ bishaje"
+
+#: elf32-arm.h:2479
+msgid " [software FP]"
+msgstr ""
+
+#: elf32-arm.h:2488
+msgid " [Version1 EABI]"
+msgstr ""
+
+#: elf32-arm.h:2491 elf32-arm.h:2502
+#, fuzzy
+msgid " [sorted symbol table]"
+msgstr "[bishunguwe IKIMENYETSO imbonerahamwe#"
+
+#: elf32-arm.h:2493 elf32-arm.h:2504
+#, fuzzy
+msgid " [unsorted symbol table]"
+msgstr "[bitashunguye IKIMENYETSO imbonerahamwe#"
+
+#: elf32-arm.h:2499
+msgid " [Version2 EABI]"
+msgstr ""
+
+#: elf32-arm.h:2507
+#, fuzzy
+msgid " [dynamic symbols use segment index]"
+msgstr "[Ibimenyetso Gukoresha Umubarendanga"
+
+#: elf32-arm.h:2510
+#, fuzzy
+msgid " [mapping symbols precede others]"
+msgstr "[Igereranya Ibimenyetso Ibindi"
+
+#: elf32-arm.h:2517
+#, fuzzy
+msgid " <EABI version unrecognised>"
+msgstr "<Verisiyo"
+
+#: elf32-arm.h:2524
+msgid " [relocatable executable]"
+msgstr ""
+
+#: elf32-arm.h:2527
+#, fuzzy
+msgid " [has entry point]"
+msgstr "[Icyinjijwe Akadomo"
+
+#: elf32-arm.h:2532
+#, fuzzy
+msgid "<Unrecognised flag bits set>"
+msgstr "<Ibendera Gushyiraho"
+
+#: elf32-avr.c:820 elf32-cris.c:1398 elf32-fr30.c:642 elf32-frv.c:823
+#: elf32-i860.c:1036 elf32-ip2k.c:1597 elf32-iq2000.c:707 elf32-msp430.c:518
+#: elf32-openrisc.c:444 elf32-v850.c:1785 elf32-xstormy16.c:984
+#: elf64-mmix.c:1340
+#, fuzzy
+msgid "internal error: dangerous relocation"
+msgstr "By'imbere Ikosa"
+
+#: elf32-cris.c:931
+#, fuzzy, c-format
+msgid "%s: unresolvable relocation %s against symbol `%s' from %s section"
+msgstr "%s:IKIMENYETSO Bivuye Icyiciro"
+
+#: elf32-cris.c:993
+#, fuzzy, c-format
+msgid "%s: No PLT nor GOT for relocation %s against symbol `%s' from %s section"
+msgstr "%s:kugirango IKIMENYETSO Bivuye Icyiciro"
+
+#: elf32-cris.c:996 elf32-cris.c:1122
+#, fuzzy
+msgid "[whose name is lost]"
+msgstr "[bya Izina: ni"
+
+#: elf32-cris.c:1111
+#, fuzzy, c-format
+msgid "%s: relocation %s with non-zero addend %d against local symbol from %s section"
+msgstr "%s:Na: Zeru IKIMENYETSO Bivuye Icyiciro"
+
+#: elf32-cris.c:1118
+#, fuzzy, c-format
+msgid "%s: relocation %s with non-zero addend %d against symbol `%s' from %s section"
+msgstr "%s:Na: Zeru IKIMENYETSO Bivuye Icyiciro"
+
+#: elf32-cris.c:1143
+#, fuzzy, c-format
+msgid "%s: relocation %s is not allowed for global symbol: `%s' from %s section"
+msgstr "%s:ni OYA kugirango IKIMENYETSO Bivuye Icyiciro"
+
+#: elf32-cris.c:1158
+#, fuzzy, c-format
+msgid "%s: relocation %s in section %s with no GOT created"
+msgstr "%s:in Icyiciro Na: Oya Byaremwe"
+
+#: elf32-cris.c:1277
+#, fuzzy, c-format
+msgid "%s: Internal inconsistency; no relocation section %s"
+msgstr "%s:Oya Icyiciro"
+
+#: elf32-cris.c:2500
+#, fuzzy, c-format
+msgid ""
+"%s, section %s:\n"
+" relocation %s should not be used in a shared object; recompile with -fPIC"
+msgstr "%s,Icyiciro OYA in a Igikoresho Na:"
+
+#: elf32-cris.c:2978
+#, fuzzy
+msgid " [symbols have a _ prefix]"
+msgstr "[Ibimenyetso a Imbanziriza"
+
+#: elf32-cris.c:3017
+#, fuzzy, c-format
+msgid "%s: uses _-prefixed symbols, but writing file with non-prefixed symbols"
+msgstr "%s:Ibimenyetso IDOSIYE Na: Ibimenyetso"
+
+#: elf32-cris.c:3018
+#, fuzzy, c-format
+msgid "%s: uses non-prefixed symbols, but writing file with _-prefixed symbols"
+msgstr "%s:Ibimenyetso IDOSIYE Na: Ibimenyetso"
+
+#: elf32-frv.c:1223
+#, fuzzy, c-format
+msgid "%s: compiled with %s and linked with modules that use non-pic relocations"
+msgstr "%s:Na: Na Na: Modire Gukoresha"
+
+#: elf32-frv.c:1273 elf32-iq2000.c:895
+#, fuzzy, c-format
+msgid "%s: compiled with %s and linked with modules compiled with %s"
+msgstr "%s:Na: Na Na: Modire Na:"
+
+#: elf32-frv.c:1285
+#, fuzzy, c-format
+msgid "%s: uses different unknown e_flags (0x%lx) fields than previous modules (0x%lx)"
+msgstr "%s:Kitazwi Imyanya Ibanjirije Modire"
+
+#: elf32-frv.c:1321 elf32-iq2000.c:933
+#, fuzzy, c-format
+msgid "private flags = 0x%lx:"
+msgstr "By'umwihariko Amabendera"
+
+#: elf32-gen.c:83 elf64-gen.c:82
+#, fuzzy, c-format
+msgid "%s: Relocations in generic ELF (EM: %d)"
+msgstr "%s:in Gifitanye isano"
+
+#: elf32-hppa.c:672 elf32-m68hc1x.c:176 elf64-ppc.c:3118
+#, fuzzy, c-format
+msgid "%s: cannot create stub entry %s"
+msgstr "%s:Kurema Icyinjijwe"
+
+#: elf32-hppa.c:957 elf32-hppa.c:3538
+#, fuzzy, c-format
+msgid "%s(%s+0x%lx): cannot reach %s, recompile with -ffunction-sections"
+msgstr "%s(%s+0x%lx):Na: Ibyatoranyijwe"
+
+#: elf32-hppa.c:1340 elf64-x86-64.c:672 elf64-x86-64.c:797
+#, fuzzy, c-format
+msgid "%s: relocation %s can not be used when making a shared object; recompile with -fPIC"
+msgstr "%s:OYA Ryari: a Igikoresho Na:"
+
+#: elf32-hppa.c:1360
+#, fuzzy, c-format
+msgid "%s: relocation %s should not be used when making a shared object; recompile with -fPIC"
+msgstr "%s:OYA Ryari: a Igikoresho Na:"
+
+#: elf32-hppa.c:1553
+#, fuzzy, c-format
+msgid "Could not find relocation section for %s"
+msgstr "OYA Gushaka Icyiciro kugirango"
+
+#: elf32-hppa.c:2828
+#, fuzzy, c-format
+msgid "%s: duplicate export stub %s"
+msgstr "%s:Gusubiramo Kohereza"
+
+#: elf32-hppa.c:3416
+#, c-format
+msgid "%s(%s+0x%lx): fixing %s"
+msgstr ""
+
+#: elf32-hppa.c:4039
+#, fuzzy, c-format
+msgid "%s(%s+0x%lx): cannot handle %s for %s"
+msgstr "%s(%s+0x%lx):kugirango"
+
+#: elf32-hppa.c:4357
+#, fuzzy
+msgid ".got section not immediately after .plt section"
+msgstr ""
+".Project- Id- Version: basctl\n"
+"POT- Creation- Date: 2003- 12- 07 17: 13+ 02\n"
+"PO- Revision- Date: 2004- 11- 04 10: 13- 0700\n"
+"Last- Translator: Language- Team:< en@ li. org> MIME- Version: 1. 0\n"
+"Content- Type: text/ plain; charset= UTF- 8\n"
+"Content- Transfer- Encoding: 8bit\n"
+"X- Generator: KBabel 1. 0\n"
+"."
+
+#: elf32-i386.c:326
+#, fuzzy, c-format
+msgid "%s: invalid relocation type %d"
+msgstr "%s:Sibyo Ubwoko"
+
+#: elf32-i386.c:841 elf32-s390.c:990 elf32-sparc.c:887 elf32-xtensa.c:637
+#: elf64-s390.c:943 elf64-x86-64.c:650
+#, fuzzy, c-format
+msgid "%s: bad symbol index: %d"
+msgstr "%s:IKIMENYETSO Umubarendanga"
+
+#: elf32-i386.c:949 elf32-s390.c:1168 elf32-sh.c:6426 elf32-sparc.c:1011
+#: elf64-s390.c:1129
+#, fuzzy, c-format
+msgid "%s: `%s' accessed both as normal and thread local symbol"
+msgstr "%s:`%s'birabonetse Byombi Nka Bisanzwe Na Urudodo IKIMENYETSO"
+
+#: elf32-i386.c:1064 elf32-s390.c:1279 elf64-ppc.c:3929 elf64-s390.c:1243
+#: elf64-x86-64.c:886
+#, fuzzy, c-format
+msgid "%s: bad relocation section name `%s'"
+msgstr "%s:Icyiciro Izina:"
+
+#: elf32-i386.c:2908 elf32-m68k.c:1757 elf32-s390.c:3022 elf32-sparc.c:2879
+#: elf32-xtensa.c:2193 elf64-s390.c:3018 elf64-sparc.c:2664
+#: elf64-x86-64.c:2452
+#, fuzzy, c-format
+msgid "%s(%s+0x%lx): unresolvable relocation against symbol `%s'"
+msgstr "%s(%s+0x%lx):IKIMENYETSO"
+
+#: elf32-i386.c:2947 elf32-m68k.c:1796 elf32-s390.c:3072 elf64-s390.c:3068
+#: elf64-x86-64.c:2490
+#, fuzzy, c-format
+msgid "%s(%s+0x%lx): reloc against `%s': error %d"
+msgstr "%s(%s+0x%lx):Ikosa"
+
+#: elf32-ip2k.c:565 elf32-ip2k.c:571 elf32-ip2k.c:734 elf32-ip2k.c:740
+#, fuzzy
+msgid "ip2k relaxer: switch table without complete matching relocation information."
+msgstr "Hindura imbonerahamwe# Byuzuye Ibisobanuro"
+
+#: elf32-ip2k.c:588 elf32-ip2k.c:767
+#, fuzzy
+msgid "ip2k relaxer: switch table header corrupt."
+msgstr "Hindura imbonerahamwe# Umutwempangano"
+
+#: elf32-ip2k.c:1395
+#, fuzzy, c-format
+msgid "ip2k linker: missing page instruction at 0x%08lx (dest = 0x%08lx)."
+msgstr "Ibuze Ipaji ku"
+
+#: elf32-ip2k.c:1409
+#, fuzzy, c-format
+msgid "ip2k linker: redundant page instruction at 0x%08lx (dest = 0x%08lx)."
+msgstr "Ipaji ku"
+
+#. Only if it's not an unresolved symbol.
+#: elf32-ip2k.c:1593
+#, fuzzy
+msgid "unsupported relocation between data/insn address spaces"
+msgstr "hagati Ibyatanzwe Aderesi Imyanya"
+
+#: elf32-iq2000.c:907 elf32-m68hc1x.c:1431 elf32-ppc.c:2175 elf64-sparc.c:3072
+#: elfxx-mips.c:9197
+#, fuzzy, c-format
+msgid "%s: uses different e_flags (0x%lx) fields than previous modules (0x%lx)"
+msgstr "%s:Imyanya Ibanjirije Modire"
+
+#: elf32-m32r.c:930
+#, fuzzy
+msgid "SDA relocation when _SDA_BASE_ not defined"
+msgstr "Ryari: OYA"
+
+#: elf32-ia64.c:3817 elf32-m32r.c:1018 elf64-alpha.c:4279 elf64-alpha.c:4407
+#: elf64-ia64.c:3817
+#, fuzzy, c-format
+msgid "%s: unknown relocation type %d"
+msgstr "%s:Kitazwi Ubwoko"
+
+#: elf32-m32r.c:1226
+#, fuzzy, c-format
+msgid "%s: The target (%s) of an %s relocation is in the wrong section (%s)"
+msgstr "%s:Intego Bya ni in i Icyiciro"
+
+#: elf32-m32r.c:1952
+#, fuzzy, c-format
+msgid "%s: Instruction set mismatch with previous modules"
+msgstr "%s:Gushyiraho Na: Ibanjirije Modire"
+
+#: elf32-m32r.c:1975
+#, fuzzy, c-format
+msgid "private flags = %lx"
+msgstr "By'umwihariko Amabendera"
+
+#: elf32-m32r.c:1980
+#, fuzzy
+msgid ": m32r instructions"
+msgstr ":Amabwiriza"
+
+#: elf32-m32r.c:1981
+#, fuzzy
+msgid ": m32rx instructions"
+msgstr ":Amabwiriza"
+
+#: elf32-m68hc1x.c:1217
+#, fuzzy, c-format
+msgid "Reference to the far symbol `%s' using a wrong relocation may result in incorrect execution"
+msgstr "Kuri i IKIMENYETSO ikoresha a Gicurasi Igisubizo in"
+
+#: elf32-m68hc1x.c:1240
+#, fuzzy, c-format
+msgid "banked address [%lx:%04lx] (%lx) is not in the same bank as current banked address [%lx:%04lx] (%lx)"
+msgstr "Aderesi ni OYA in i Nka KIGEZWEHO Aderesi"
+
+#: elf32-m68hc1x.c:1259
+#, fuzzy, c-format
+msgid "reference to a banked address [%lx:%04lx] in the normal address space at %04lx"
+msgstr "Indango Kuri a Aderesi in i Bisanzwe Aderesi Umwanya ku"
+
+#: elf32-m68hc1x.c:1396
+#, fuzzy, c-format
+msgid "%s: linking files compiled for 16-bit integers (-mshort) and others for 32-bit integers"
+msgstr "%s:Impuza Idosiye kugirango Na Ibindi kugirango"
+
+#: elf32-m68hc1x.c:1404
+#, fuzzy, c-format
+msgid "%s: linking files compiled for 32-bit double (-fshort-double) and others for 64-bit double"
+msgstr "%s:Impuza Idosiye kugirango MAHARAKUBIRI MAHARAKUBIRI Na Ibindi kugirango MAHARAKUBIRI"
+
+#: elf32-m68hc1x.c:1414
+#, fuzzy, c-format
+msgid "%s: linking files compiled for HCS12 with others compiled for HC12"
+msgstr "%s:Impuza Idosiye kugirango Na: Ibindi kugirango"
+
+#: elf32-m68hc1x.c:1462
+#, fuzzy
+msgid "[abi=32-bit int, "
+msgstr "[INT"
+
+#: elf32-m68hc1x.c:1464
+#, fuzzy
+msgid "[abi=16-bit int, "
+msgstr "[INT"
+
+#: elf32-m68hc1x.c:1467
+#, fuzzy
+msgid "64-bit double, "
+msgstr "MAHARAKUBIRI"
+
+#: elf32-m68hc1x.c:1469
+#, fuzzy
+msgid "32-bit double, "
+msgstr "MAHARAKUBIRI"
+
+#: elf32-m68hc1x.c:1472
+#, fuzzy
+msgid "cpu=HC11]"
+msgstr "CPU"
+
+#: elf32-m68hc1x.c:1474
+#, fuzzy
+msgid "cpu=HCS12]"
+msgstr "CPU"
+
+#: elf32-m68hc1x.c:1476
+#, fuzzy
+msgid "cpu=HC12]"
+msgstr "CPU"
+
+#: elf32-m68hc1x.c:1479
+#, fuzzy
+msgid " [memory=bank-model]"
+msgstr "[Ububiko Urugero"
+
+#: elf32-m68hc1x.c:1481
+#, fuzzy
+msgid " [memory=flat]"
+msgstr "[Ububiko Kirambuye"
+
+#: elf32-m68k.c:400
+msgid " [cpu32]"
+msgstr ""
+
+#: elf32-m68k.c:403
+msgid " [m68000]"
+msgstr ""
+
+#: elf32-mcore.c:353 elf32-mcore.c:456
+#, fuzzy, c-format
+msgid "%s: Relocation %s (%d) is not currently supported.\n"
+msgstr "%s:ni OYA"
+
+#: elf32-mcore.c:441
+#, fuzzy, c-format
+msgid "%s: Unknown relocation type %d\n"
+msgstr "%s:Ubwoko"
+
+#: elf32-mips.c:1170 elf64-mips.c:1717 elfn32-mips.c:1664
+#, fuzzy
+msgid "32bits gp relative relocation occurs for an external symbol"
+msgstr "Bifitanye isano kugirango external IKIMENYETSO"
+
+#: elf32-mips.c:1314 elf64-mips.c:1830 elfn32-mips.c:1783
+#, fuzzy, c-format
+msgid "Linking mips16 objects into %s format is not supported"
+msgstr "Ibintu Imiterere ni OYA"
+
+#: elf32-ppc.c:2056
+#, fuzzy, c-format
+msgid "generic linker can't handle %s"
+msgstr "Gifitanye isano"
+
+#: elf32-ppc.c:2138
+#, fuzzy, c-format
+msgid "%s: compiled with -mrelocatable and linked with modules compiled normally"
+msgstr "%s:Na: Na Na: Modire"
+
+#: elf32-ppc.c:2147
+#, fuzzy, c-format
+msgid "%s: compiled normally and linked with modules compiled with -mrelocatable"
+msgstr "%s:Na Na: Modire Na:"
+
+#: elf32-ppc.c:3413
+#, fuzzy, c-format
+msgid "%s: relocation %s cannot be used when making a shared object"
+msgstr "%s:Ryari: a Igikoresho"
+
+#. It does not make sense to have a procedure linkage
+#. table entry for a local symbol.
+#: elf32-ppc.c:3619
+#, fuzzy, c-format
+msgid "%s(%s+0x%lx): %s reloc against local symbol"
+msgstr "%s(%s+0x%lx):%sIKIMENYETSO"
+
+#: elf32-ppc.c:4862 elf64-ppc.c:7789
+#, fuzzy, c-format
+msgid "%s: unknown relocation type %d for symbol %s"
+msgstr "%s:Kitazwi Ubwoko kugirango IKIMENYETSO"
+
+#: elf32-ppc.c:5113
+#, fuzzy, c-format
+msgid "%s(%s+0x%lx): non-zero addend on %s reloc against `%s'"
+msgstr "%s(%s+0x%lx):Zeru ku"
+
+#: elf32-ppc.c:5399 elf32-ppc.c:5425 elf32-ppc.c:5484
+#, fuzzy, c-format
+msgid "%s: the target (%s) of a %s relocation is in the wrong output section (%s)"
+msgstr "%s:i Intego Bya a ni in i Ibisohoka Icyiciro"
+
+#: elf32-ppc.c:5539
+#, fuzzy, c-format
+msgid "%s: relocation %s is not yet supported for symbol %s."
+msgstr "%s:ni OYA kugirango IKIMENYETSO"
+
+#: elf32-ppc.c:5594 elf64-ppc.c:8461
+#, fuzzy, c-format
+msgid "%s(%s+0x%lx): unresolvable %s relocation against symbol `%s'"
+msgstr "%s(%s+0x%lx):IKIMENYETSO"
+
+#: elf32-ppc.c:5644 elf64-ppc.c:8507
+#, fuzzy, c-format
+msgid "%s(%s+0x%lx): %s reloc against `%s': error %d"
+msgstr "%s(%s+0x%lx):%sIkosa"
+
+#: elf32-ppc.c:5888
+#, fuzzy, c-format
+msgid "corrupt or empty %s section in %s"
+msgstr "Cyangwa ubusa Icyiciro in"
+
+#: elf32-ppc.c:5895
+#, fuzzy, c-format
+msgid "unable to read in %s section from %s"
+msgstr "Kuri Gusoma in Icyiciro Bivuye"
+
+#: elf32-ppc.c:5901
+#, fuzzy, c-format
+msgid "corrupt %s section in %s"
+msgstr "Icyiciro in"
+
+#: elf32-ppc.c:5944
+#, fuzzy, c-format
+msgid "warning: unable to set size of %s section in %s"
+msgstr "Iburira Kuri Gushyiraho Ingano Bya Icyiciro in"
+
+#: elf32-ppc.c:5994
+#, fuzzy
+msgid "failed to allocate space for new APUinfo section."
+msgstr "Byanze Kuri Umwanya kugirango Gishya Icyiciro"
+
+#: elf32-ppc.c:6013
+#, fuzzy
+msgid "failed to compute new APUinfo section."
+msgstr "Byanze Kuri Gishya Icyiciro"
+
+#: elf32-ppc.c:6016
+#, fuzzy
+msgid "failed to install new APUinfo section."
+msgstr "Byanze Kuri Kwinjiza porogaramu Gishya Icyiciro"
+
+#: elf32-s390.c:2256 elf64-s390.c:2226
+#, fuzzy, c-format
+msgid "%s(%s+0x%lx): invalid instruction for TLS relocation %s"
+msgstr "%s(%s+0x%lx):Sibyo kugirango"
+
+#: elf32-sh64.c:221 elf64-sh64.c:2407
+#, fuzzy, c-format
+msgid "%s: compiled as 32-bit object and %s is 64-bit"
+msgstr "%s:Nka Igikoresho Na ni"
+
+#: elf32-sh64.c:224 elf64-sh64.c:2410
+#, fuzzy, c-format
+msgid "%s: compiled as 64-bit object and %s is 32-bit"
+msgstr "%s:Nka Igikoresho Na ni"
+
+#: elf32-sh64.c:226 elf64-sh64.c:2412
+#, fuzzy, c-format
+msgid "%s: object size does not match that of target %s"
+msgstr "%s:Igikoresho Ingano OYA BIHUYE Bya Intego"
+
+#: elf32-sh64.c:461 elf64-sh64.c:2990
+#, fuzzy, c-format
+msgid "%s: encountered datalabel symbol in input"
+msgstr "%s:IKIMENYETSO in Iyinjiza"
+
+#: elf32-sh64.c:544
+#, fuzzy
+msgid "PTB mismatch: a SHmedia address (bit 0 == 1)"
+msgstr "a Aderesi 0 1."
+
+#: elf32-sh64.c:547
+#, fuzzy
+msgid "PTA mismatch: a SHcompact address (bit 0 == 0)"
+msgstr "a Aderesi 0 0"
+
+#: elf32-sh64.c:565
+#, fuzzy, c-format
+msgid "%s: GAS error: unexpected PTB insn with R_SH_PT_16"
+msgstr "%s:Ikosa Na:"
+
+#: elf32-sh64.c:614 elf64-sh64.c:1748
+#, fuzzy, c-format
+msgid "%s: error: unaligned relocation type %d at %08x reloc %08x\n"
+msgstr "%s:Ikosa Ubwoko ku"
+
+#: elf32-sh64.c:698
+#, fuzzy, c-format
+msgid "%s: could not write out added .cranges entries"
+msgstr "%s:OYA Kwandika Inyuma Kyongewe Ibyinjijwe"
+
+#: elf32-sh64.c:760
+#, fuzzy, c-format
+msgid "%s: could not write out sorted .cranges entries"
+msgstr "%s:OYA Kwandika Inyuma bishunguwe Ibyinjijwe"
+
+#: elf32-sh.c:2103
+#, fuzzy, c-format
+msgid "%s: 0x%lx: warning: bad R_SH_USES offset"
+msgstr "%s:Iburira Nta- boneza"
+
+#: elf32-sh.c:2115
+#, fuzzy, c-format
+msgid "%s: 0x%lx: warning: R_SH_USES points to unrecognized insn 0x%x"
+msgstr "%s:Iburira Utudomo Kuri"
+
+#: elf32-sh.c:2132
+#, fuzzy, c-format
+msgid "%s: 0x%lx: warning: bad R_SH_USES load offset"
+msgstr "%s:Iburira Ibirimo Nta- boneza"
+
+#: elf32-sh.c:2147
+#, fuzzy, c-format
+msgid "%s: 0x%lx: warning: could not find expected reloc"
+msgstr "%s:Iburira OYA Gushaka Ikitezwe:"
+
+#: elf32-sh.c:2175
+#, fuzzy, c-format
+msgid "%s: 0x%lx: warning: symbol in unexpected section"
+msgstr "%s:Iburira IKIMENYETSO in Icyiciro"
+
+#: elf32-sh.c:2300
+#, fuzzy, c-format
+msgid "%s: 0x%lx: warning: could not find expected COUNT reloc"
+msgstr "%s:Iburira OYA Gushaka Ikitezwe:"
+
+#: elf32-sh.c:2309
+#, fuzzy, c-format
+msgid "%s: 0x%lx: warning: bad count"
+msgstr "%s:Iburira IBARA"
+
+#: elf32-sh.c:2712 elf32-sh.c:3088
+#, fuzzy, c-format
+msgid "%s: 0x%lx: fatal: reloc overflow while relaxing"
+msgstr "%s:Byarenze urugero"
+
+#: elf32-sh.c:4654 elf64-sh64.c:1585
+#, fuzzy
+msgid "Unexpected STO_SH5_ISA32 on local symbol is not handled"
+msgstr "ku IKIMENYETSO ni OYA"
+
+#: elf32-sh.c:4809
+#, fuzzy, c-format
+msgid "%s: unresolvable relocation against symbol `%s' from %s section"
+msgstr "%s:IKIMENYETSO Bivuye Icyiciro"
+
+#: elf32-sh.c:4881
+#, fuzzy, c-format
+msgid "%s: 0x%lx: fatal: unaligned branch target for relax-support relocation"
+msgstr "%s:Intego kugirango Gushigikira"
+
+#: elf32-sh.c:6627 elf64-alpha.c:4848
+#, fuzzy, c-format
+msgid "%s: TLS local exec code cannot be linked into shared objects"
+msgstr "%s:ITEGEKONGENGA Ibintu"
+
+#: elf32-sparc.c:2521 elf64-sparc.c:2314
+#, c-format
+msgid "%s: probably compiled without -fPIC?"
+msgstr ""
+
+#: elf32-sparc.c:3348
+#, fuzzy, c-format
+msgid "%s: compiled for a 64 bit system and target is 32 bit"
+msgstr "%s:kugirango a Sisitemu Na Intego ni"
+
+#: elf32-sparc.c:3362
+#, fuzzy, c-format
+msgid "%s: linking little endian files with big endian files"
+msgstr "%s:Impuza Idosiye Na: Idosiye"
+
+#: elf32-v850.c:753
+#, fuzzy, c-format
+msgid "Variable `%s' cannot occupy in multiple small data regions"
+msgstr "in Igikubo Gitoya Ibyatanzwe"
+
+#: elf32-v850.c:756
+#, fuzzy, c-format
+msgid "Variable `%s' can only be in one of the small, zero, and tiny data regions"
+msgstr "in Bya i Gitoya Zeru Na Bito Ibyatanzwe"
+
+#: elf32-v850.c:759
+#, fuzzy, c-format
+msgid "Variable `%s' cannot be in both small and zero data regions simultaneously"
+msgstr "in Byombi Gitoya Na Zeru Ibyatanzwe"
+
+#: elf32-v850.c:762
+#, fuzzy, c-format
+msgid "Variable `%s' cannot be in both small and tiny data regions simultaneously"
+msgstr "in Byombi Gitoya Na Bito Ibyatanzwe"
+
+#: elf32-v850.c:765
+#, fuzzy, c-format
+msgid "Variable `%s' cannot be in both zero and tiny data regions simultaneously"
+msgstr "in Byombi Zeru Na Bito Ibyatanzwe"
+
+#: elf32-v850.c:1144
+#, fuzzy
+msgid "FAILED to find previous HI16 reloc\n"
+msgstr "Kuri Gushaka Ibanjirije"
+
+#: elf32-v850.c:1789
+#, fuzzy
+msgid "could not locate special linker symbol __gp"
+msgstr "OYA Bidasanzwe IKIMENYETSO"
+
+#: elf32-v850.c:1793
+#, fuzzy
+msgid "could not locate special linker symbol __ep"
+msgstr "OYA Bidasanzwe IKIMENYETSO"
+
+#: elf32-v850.c:1797
+#, fuzzy
+msgid "could not locate special linker symbol __ctbp"
+msgstr "OYA Bidasanzwe IKIMENYETSO"
+
+#: elf32-v850.c:1963
+#, fuzzy, c-format
+msgid "%s: Architecture mismatch with previous modules"
+msgstr "%s:Na: Ibanjirije Modire"
+
+#: elf32-v850.c:1983
+#, fuzzy, c-format
+msgid "private flags = %lx: "
+msgstr "By'umwihariko Amabendera"
+
+#: elf32-v850.c:1988
+msgid "v850 architecture"
+msgstr ""
+
+#: elf32-v850.c:1989
+msgid "v850e architecture"
+msgstr ""
+
+#: elf32-vax.c:549
+msgid " [nonpic]"
+msgstr ""
+
+#: elf32-vax.c:552
+#, fuzzy
+msgid " [d-float]"
+msgstr "[D Kureremba"
+
+#: elf32-vax.c:555
+#, fuzzy
+msgid " [g-float]"
+msgstr "[g Kureremba"
+
+#: elf32-vax.c:663
+#, fuzzy, c-format
+msgid "%s: warning: GOT addend of %ld to `%s' does not match previous GOT addend of %ld"
+msgstr "%s:Iburira Bya Kuri OYA BIHUYE Ibanjirije Bya"
+
+#: elf32-vax.c:1667
+#, fuzzy, c-format
+msgid "%s: warning: PLT addend of %d to `%s' from %s section ignored"
+msgstr "%s:Iburira Bya Kuri Bivuye Icyiciro"
+
+#: elf32-vax.c:1802
+#, fuzzy, c-format
+msgid "%s: warning: %s relocation against symbol `%s' from %s section"
+msgstr "%s:Iburira IKIMENYETSO Bivuye Icyiciro"
+
+#: elf32-vax.c:1808
+#, fuzzy, c-format
+msgid "%s: warning: %s relocation to 0x%x from %s section"
+msgstr "%s:Iburira Kuri Bivuye Icyiciro"
+
+#: elf32-ia64.c:2326 elf32-xstormy16.c:462 elf64-ia64.c:2326
+#, fuzzy
+msgid "non-zero addend in @fptr reloc"
+msgstr "Zeru in"
+
+#: elf64-alpha.c:1108
+#, fuzzy
+msgid "GPDISP relocation did not find ldah and lda instructions"
+msgstr "OYA Gushaka Na Amabwiriza"
+
+#: elf64-alpha.c:3731
+#, fuzzy, c-format
+msgid "%s: .got subsegment exceeds 64K (size %d)"
+msgstr ""
+"%s:.Project- Id- Version: basctl\n"
+"POT- Creation- Date: 2003- 12- 07 17: 13+ 02\n"
+"PO- Revision- Date: 2004- 11- 04 10: 13- 0700\n"
+"Last- Translator: Language- Team:< en@ li. org> MIME- Version: 1. 0\n"
+"Content- Type: text/ plain; charset= UTF- 8\n"
+"Content- Transfer- Encoding: 8bit\n"
+"X- Generator: KBabel 1. 0\n"
+"."
+
+#: elf64-alpha.c:4602 elf64-alpha.c:4614
+#, fuzzy, c-format
+msgid "%s: gp-relative relocation against dynamic symbol %s"
+msgstr "%s:Bifitanye isano IKIMENYETSO"
+
+#: elf64-alpha.c:4640 elf64-alpha.c:4773
+#, fuzzy, c-format
+msgid "%s: pc-relative relocation against dynamic symbol %s"
+msgstr "%s:Bifitanye isano IKIMENYETSO"
+
+#: elf64-alpha.c:4668
+#, fuzzy, c-format
+msgid "%s: change in gp: BRSGP %s"
+msgstr "%s:Guhindura>> in"
+
+#: elf64-alpha.c:4693
+#, fuzzy
+msgid "<unknown>"
+msgstr "<Itazwi>"
+
+#: elf64-alpha.c:4698
+#, fuzzy, c-format
+msgid "%s: !samegp reloc against symbol without .prologue: %s"
+msgstr "%s:!IKIMENYETSO"
+
+#: elf64-alpha.c:4749
+#, c-format
+msgid "%s: unhandled dynamic relocation against %s"
+msgstr ""
+
+#: elf64-alpha.c:4832
+#, fuzzy, c-format
+msgid "%s: dtp-relative relocation against dynamic symbol %s"
+msgstr "%s:Bifitanye isano IKIMENYETSO"
+
+#: elf64-alpha.c:4855
+#, fuzzy, c-format
+msgid "%s: tp-relative relocation against dynamic symbol %s"
+msgstr "%s:Bifitanye isano IKIMENYETSO"
+
+#: elf64-hppa.c:2086
+#, fuzzy, c-format
+msgid "stub entry for %s cannot load .plt, dp offset = %ld"
+msgstr "Icyinjijwe kugirango Ibirimo Nta- boneza"
+
+#: elf64-mmix.c:1032
+#, fuzzy, c-format
+msgid ""
+"%s: Internal inconsistency error for value for\n"
+" linker-allocated global register: linked: 0x%lx%08lx != relaxed: 0x%lx%08lx\n"
+msgstr "%s:Ikosa kugirango Agaciro Kwiyandikisha"
+
+#: elf64-mmix.c:1416
+#, fuzzy, c-format
+msgid "%s: base-plus-offset relocation against register symbol: (unknown) in %s"
+msgstr "%s:SHINGIRO Guteranya Nta- boneza Kwiyandikisha IKIMENYETSO Kitazwi in"
+
+#: elf64-mmix.c:1421
+#, fuzzy, c-format
+msgid "%s: base-plus-offset relocation against register symbol: %s in %s"
+msgstr "%s:SHINGIRO Guteranya Nta- boneza Kwiyandikisha IKIMENYETSO in"
+
+#: elf64-mmix.c:1465
+#, fuzzy, c-format
+msgid "%s: register relocation against non-register symbol: (unknown) in %s"
+msgstr "%s:Kwiyandikisha Kwiyandikisha IKIMENYETSO Kitazwi in"
+
+#: elf64-mmix.c:1470
+#, fuzzy, c-format
+msgid "%s: register relocation against non-register symbol: %s in %s"
+msgstr "%s:Kwiyandikisha Kwiyandikisha IKIMENYETSO in"
+
+#: elf64-mmix.c:1507
+#, fuzzy, c-format
+msgid "%s: directive LOCAL valid only with a register or absolute value"
+msgstr "%s:Byemewe Na: a Kwiyandikisha Cyangwa Agaciro"
+
+#: elf64-mmix.c:1535
+#, fuzzy, c-format
+msgid "%s: LOCAL directive: Register $%ld is not a local register. First global register is $%ld."
+msgstr "%s:ni OYA a Kwiyandikisha Kwiyandikisha ni"
+
+#: elf64-mmix.c:1994
+#, fuzzy, c-format
+msgid "%s: Error: multiple definition of `%s'; start of %s is set in a earlier linked file\n"
+msgstr "%s:Igikubo Insobanuro Bya Gutangira Bya ni Gushyiraho in a"
+
+#: elf64-mmix.c:2053
+#, fuzzy
+msgid "Register section has contents\n"
+msgstr "Icyiciro"
+
+#: elf64-mmix.c:2216
+#, fuzzy, c-format
+msgid ""
+"Internal inconsistency: remaining %u != max %u.\n"
+" Please report this bug."
+msgstr "KININI Icyegeranyo iyi"
+
+#: elf64-ppc.c:2388 libbfd.c:831
+#, fuzzy, c-format
+msgid "%s: compiled for a big endian system and target is little endian"
+msgstr "%s:kugirango a Sisitemu Na Intego ni"
+
+#: elf64-ppc.c:2391 libbfd.c:833
+#, fuzzy, c-format
+msgid "%s: compiled for a little endian system and target is big endian"
+msgstr "%s:kugirango a Sisitemu Na Intego ni"
+
+#: elf64-ppc.c:4857
+#, fuzzy, c-format
+msgid "%s: unexpected reloc type %u in .opd section"
+msgstr "%s:Ubwoko in Icyiciro"
+
+#: elf64-ppc.c:4877
+#, fuzzy, c-format
+msgid "%s: .opd is not a regular array of opd entries"
+msgstr ""
+"%s:.Project- Id- Version: basctl\n"
+"POT- Creation- Date: 2003- 12- 07 17: 13+ 02\n"
+"PO- Revision- Date: 2004- 11- 04 10: 13- 0700\n"
+"Last- Translator: Language- Team:< en@ li. org> MIME- Version: 1. 0\n"
+"Content- Type: text/ plain; charset= UTF- 8\n"
+"Content- Transfer- Encoding: 8bit\n"
+"X- Generator: KBabel 1. 0\n"
+"."
+
+#: elf64-ppc.c:4897
+#, fuzzy, c-format
+msgid "%s: undefined sym `%s' in .opd section"
+msgstr "%s:kidasobanuye in Icyiciro"
+
+#: elf64-ppc.c:6136
+#, fuzzy, c-format
+msgid "can't find branch stub `%s'"
+msgstr "Gushaka"
+
+#: elf64-ppc.c:6175 elf64-ppc.c:6250
+#, fuzzy, c-format
+msgid "linkage table error against `%s'"
+msgstr "imbonerahamwe# Ikosa"
+
+#: elf64-ppc.c:6340
+#, c-format
+msgid "can't build branch stub `%s'"
+msgstr ""
+
+#: elf64-ppc.c:7047
+#, fuzzy
+msgid ".glink and .plt too far apart"
+msgstr ""
+".Project- Id- Version: basctl\n"
+"POT- Creation- Date: 2003- 12- 07 17: 13+ 02\n"
+"PO- Revision- Date: 2004- 11- 04 10: 13- 0700\n"
+"Last- Translator: Language- Team:< en@ li. org> MIME- Version: 1. 0\n"
+"Content- Type: text/ plain; charset= UTF- 8\n"
+"Content- Transfer- Encoding: 8bit\n"
+"X- Generator: KBabel 1. 0\n"
+"."
+
+#: elf64-ppc.c:7135
+#, fuzzy
+msgid "stubs don't match calculated size"
+msgstr "BIHUYE Ingano"
+
+#: elf64-ppc.c:7147
+#, fuzzy, c-format
+msgid ""
+"linker stubs in %u groups\n"
+" branch %lu\n"
+" toc adjust %lu\n"
+" long branch %lu\n"
+" long toc adj %lu\n"
+" plt call %lu"
+msgstr "in"
+
+#: elf64-ppc.c:7723
+#, fuzzy, c-format
+msgid "%s(%s+0x%lx): automatic multiple TOCs not supported using your crt files; recompile with -mminimal-toc or upgrade gcc"
+msgstr "%s(%s+0x%lx):Byikoresha Igikubo OYA ikoresha Idosiye Na: Cyangwa"
+
+#: elf64-ppc.c:7731
+#, fuzzy, c-format
+msgid "%s(%s+0x%lx): sibling call optimization to `%s' does not allow automatic multiple TOCs; recompile with -mminimal-toc or -fno-optimize-sibling-calls, or make `%s' extern"
+msgstr "%s(%s+0x%lx):Kuri OYA Kwemerera Byikoresha Igikubo Na: Cyangwa Kugeza ku ndunduro Amahamagara: Cyangwa Ubwoko"
+
+#: elf64-ppc.c:8329
+#, fuzzy, c-format
+msgid "%s: relocation %s is not supported for symbol %s."
+msgstr "%s:ni OYA kugirango IKIMENYETSO"
+
+#: elf64-ppc.c:8408
+#, fuzzy, c-format
+msgid "%s: error: relocation %s not a multiple of %d"
+msgstr "%s:Ikosa OYA a Igikubo Bya"
+
+#: elf-hppa.h:1458 elf-hppa.h:1491 elf-m10300.c:1628 elf64-sh64.c:1704
+#, fuzzy, c-format
+msgid "%s: warning: unresolvable relocation against symbol `%s' from %s section"
+msgstr "%s:Iburira IKIMENYETSO Bivuye Icyiciro"
+
+#: elf64-sparc.c:1370
+#, fuzzy, c-format
+msgid "%s: check_relocs: unhandled reloc type %d"
+msgstr "%s:Ubwoko"
+
+#: elf64-sparc.c:1407
+#, fuzzy, c-format
+msgid "%s: Only registers %%g[2367] can be declared using STT_REGISTER"
+msgstr "%s:ikoresha"
+
+#: elf64-sparc.c:1427
+#, fuzzy, c-format
+msgid "Register %%g%d used incompatibly: %s in %s, previously %s in %s"
+msgstr "in in"
+
+#: elf64-sparc.c:1450
+#, fuzzy, c-format
+msgid "Symbol `%s' has differing types: REGISTER in %s, previously %s in %s"
+msgstr "in in"
+
+#: elf64-sparc.c:1496
+#, fuzzy, c-format
+msgid "Symbol `%s' has differing types: %s in %s, previously REGISTER in %s"
+msgstr "in in"
+
+#: elf64-sparc.c:3053
+#, fuzzy, c-format
+msgid "%s: linking UltraSPARC specific with HAL specific code"
+msgstr "%s:Impuza Na: ITEGEKONGENGA"
+
+#: elf64-x86-64.c:739
+#, fuzzy, c-format
+msgid "%s: %s' accessed both as normal and thread local symbol"
+msgstr "%s:%s'birabonetse Byombi Nka Bisanzwe Na Urudodo IKIMENYETSO"
+
+#: elf.c:372
+#, fuzzy, c-format
+msgid "%s: invalid string offset %u >= %lu for section `%s'"
+msgstr "%s:Sibyo Ikurikiranyanyuguti Nta- boneza kugirango Icyiciro"
+
+#: elf.c:624
+#, fuzzy, c-format
+msgid "%s: invalid SHT_GROUP entry"
+msgstr "%s:Sibyo Icyinjijwe"
+
+#: elf.c:695
+#, fuzzy, c-format
+msgid "%s: no group info for section %s"
+msgstr "%s:Oya Itsinda Ibisobanuro kugirango Icyiciro"
+
+#: elf.c:1055
+msgid ""
+"\n"
+"Program Header:\n"
+msgstr ""
+
+#: elf.c:1106
+msgid ""
+"\n"
+"Dynamic Section:\n"
+msgstr ""
+
+#: elf.c:1235
+msgid ""
+"\n"
+"Version definitions:\n"
+msgstr ""
+
+#: elf.c:1258
+msgid ""
+"\n"
+"Version References:\n"
+msgstr ""
+
+#: elf.c:1263
+#, fuzzy, c-format
+msgid " required from %s:\n"
+msgstr "Bya ngombwa Bivuye"
+
+#: elf.c:1944
+#, fuzzy, c-format
+msgid "%s: invalid link %lu for reloc section %s (index %u)"
+msgstr "%s:Sibyo Ihuza kugirango Icyiciro Umubarendanga"
+
+#: elf.c:3686
+#, fuzzy, c-format
+msgid "%s: Not enough room for program headers (allocated %u, need %u)"
+msgstr "%s:kugirango Porogaramu Imitwe"
+
+#: elf.c:3791
+#, fuzzy, c-format
+msgid "%s: Not enough room for program headers, try linking with -N"
+msgstr "%s:kugirango Porogaramu Imitwe Impuza Na:"
+
+#: elf.c:3922
+#, fuzzy, c-format
+msgid "Error: First section in segment (%s) starts at 0x%x whereas the segment starts at 0x%x"
+msgstr "Icyiciro in ku i ku"
+
+#: elf.c:4242
+#, fuzzy, c-format
+msgid "%s: warning: allocated section `%s' not in segment"
+msgstr "%s:Iburira Icyiciro OYA in"
+
+#: elf.c:4566
+#, fuzzy, c-format
+msgid "%s: symbol `%s' required but not present"
+msgstr "%s:IKIMENYETSO Bya ngombwa OYA"
+
+#: elf.c:4854
+#, fuzzy, c-format
+msgid "%s: warning: Empty loadable segment detected, is this intentional ?\n"
+msgstr "%s:Iburira ni iyi"
+
+#: elf.c:5485
+#, fuzzy, c-format
+msgid "Unable to find equivalent output section for symbol '%s' from section '%s'"
+msgstr "Kuri Gushaka Ibisohoka Icyiciro kugirango IKIMENYETSO Bivuye Icyiciro"
+
+#: elf.c:6298
+#, fuzzy, c-format
+msgid "%s: unsupported relocation type %s"
+msgstr "%s:Ubwoko"
+
+#: elfcode.h:1113
+#, fuzzy, c-format
+msgid "%s: version count (%ld) does not match symbol count (%ld)"
+msgstr "%s:Verisiyo IBARA OYA BIHUYE IKIMENYETSO IBARA"
+
+#: elfcode.h:1342
+#, fuzzy, c-format
+msgid "%s(%s): relocation %d has invalid symbol index %ld"
+msgstr "%s(%s):Sibyo IKIMENYETSO Umubarendanga"
+
+#: elflink.c:1456
+#, fuzzy, c-format
+msgid "%s: warning: unexpected redefinition of indirect versioned symbol `%s'"
+msgstr "%s:Iburira Bya BUZIGUYE IKIMENYETSO"
+
+#: elflink.c:1807
+#, fuzzy, c-format
+msgid "%s: undefined versioned symbol name %s"
+msgstr "%s:kidasobanuye IKIMENYETSO Izina:"
+
+#: elflink.c:2142
+#, fuzzy, c-format
+msgid "%s: relocation size mismatch in %s section %s"
+msgstr "%s:Ingano in Icyiciro"
+
+#: elflink.c:2434
+#, fuzzy, c-format
+msgid "warning: type and size of dynamic symbol `%s' are not defined"
+msgstr "Iburira Ubwoko Na Ingano Bya IKIMENYETSO OYA"
+
+#: elflink.h:1022
+#, fuzzy, c-format
+msgid "%s: %s: invalid version %u (max %d)"
+msgstr "%s:%s:Sibyo Verisiyo KININI"
+
+#: elflink.h:1063
+#, fuzzy, c-format
+msgid "%s: %s: invalid needed version %d"
+msgstr "%s:%s:Sibyo Verisiyo"
+
+#: elflink.h:1238
+#, fuzzy, c-format
+msgid "Warning: alignment %u of symbol `%s' in %s is smaller than %u in %s"
+msgstr "Itunganya Bya IKIMENYETSO in ni Gitoya in"
+
+#: elflink.h:1252
+#, fuzzy, c-format
+msgid "Warning: size of symbol `%s' changed from %lu in %s to %lu in %s"
+msgstr "Ingano Bya IKIMENYETSO Byahinduwe Bivuye in Kuri in"
+
+#: elflink.h:2160
+#, fuzzy, c-format
+msgid "%s: undefined version: %s"
+msgstr "%s:kidasobanuye Verisiyo"
+
+#: elflink.h:2226
+#, fuzzy, c-format
+msgid "%s: .preinit_array section is not allowed in DSO"
+msgstr ""
+"%s:.Project- Id- Version: basctl\n"
+"POT- Creation- Date: 2003- 12- 07 17: 13+ 02\n"
+"PO- Revision- Date: 2004- 11- 04 10: 13- 0700\n"
+"Last- Translator: Language- Team:< en@ li. org> MIME- Version: 1. 0\n"
+"Content- Type: text/ plain; charset= UTF- 8\n"
+"Content- Transfer- Encoding: 8bit\n"
+"X- Generator: KBabel 1. 0\n"
+"."
+
+#: elflink.h:3078
+#, fuzzy
+msgid "Not enough memory to sort relocations"
+msgstr "Ububiko Kuri Ishungura"
+
+#: elflink.h:3958 elflink.h:4001
+#, fuzzy, c-format
+msgid "%s: could not find output section %s"
+msgstr "%s:OYA Gushaka Ibisohoka Icyiciro"
+
+#: elflink.h:3964
+#, fuzzy, c-format
+msgid "warning: %s section has zero size"
+msgstr "Iburira Icyiciro Zeru Ingano"
+
+#: elflink.h:4483
+#, fuzzy, c-format
+msgid "%s: %s symbol `%s' in %s is referenced by DSO"
+msgstr "%s:%sIKIMENYETSO in ni ku"
+
+#: elflink.h:4564
+#, fuzzy, c-format
+msgid "%s: could not find output section %s for input section %s"
+msgstr "%s:OYA Gushaka Ibisohoka Icyiciro kugirango Iyinjiza Icyiciro"
+
+#: elflink.h:4666
+#, fuzzy, c-format
+msgid "%s: %s symbol `%s' isn't defined"
+msgstr "%s:%sIKIMENYETSO si"
+
+#: elflink.h:5053 elflink.h:5095
+#, fuzzy
+msgid "%T: discarded in section `%s' from %s\n"
+msgstr "%T:in Icyiciro Bivuye"
+
+#: elfxx-mips.c:887
+#, fuzzy
+msgid "static procedure (no name)"
+msgstr "Oya Izina:"
+
+#: elfxx-mips.c:1897
+#, fuzzy
+msgid "not enough GOT space for local GOT entries"
+msgstr "OYA Umwanya kugirango Ibyinjijwe"
+
+#: elfxx-mips.c:3691
+#, fuzzy, c-format
+msgid "%s: %s+0x%lx: jump to stub routine which is not jal"
+msgstr "%s:%s+0x%lx:Simbuka Kuri ni OYA"
+
+#: elfxx-mips.c:5192
+#, fuzzy, c-format
+msgid "%s: Malformed reloc detected for section %s"
+msgstr "%s:kugirango Icyiciro"
+
+#: elfxx-mips.c:5266
+#, fuzzy, c-format
+msgid "%s: CALL16 reloc at 0x%lx not against global symbol"
+msgstr "%s:ku OYA IKIMENYETSO"
+
+#: elfxx-mips.c:8693
+#, fuzzy, c-format
+msgid "%s: illegal section name `%s'"
+msgstr "%s:Icyiciro Izina:"
+
+#: elfxx-mips.c:9027
+#, fuzzy, c-format
+msgid "%s: endianness incompatible with that of the selected emulation"
+msgstr "%s:Na: Bya i Byahiswemo"
+
+#: elfxx-mips.c:9039
+#, fuzzy, c-format
+msgid "%s: ABI is incompatible with that of the selected emulation"
+msgstr "%s:ni Na: Bya i Byahiswemo"
+
+#: elfxx-mips.c:9106
+#, fuzzy, c-format
+msgid "%s: warning: linking PIC files with non-PIC files"
+msgstr "%s:Iburira Impuza Idosiye Na: Idosiye"
+
+#: elfxx-mips.c:9123
+#, fuzzy, c-format
+msgid "%s: linking 32-bit code with 64-bit code"
+msgstr "%s:Impuza ITEGEKONGENGA Na: ITEGEKONGENGA"
+
+#: elfxx-mips.c:9151
+#, fuzzy, c-format
+msgid "%s: linking %s module with previous %s modules"
+msgstr "%s:Impuza Modire Na: Ibanjirije Modire"
+
+#: elfxx-mips.c:9174
+#, fuzzy, c-format
+msgid "%s: ABI mismatch: linking %s module with previous %s modules"
+msgstr "%s:Impuza Modire Na: Ibanjirije Modire"
+
+#: elfxx-mips.c:9243
+msgid " [abi=O32]"
+msgstr ""
+
+#: elfxx-mips.c:9245
+msgid " [abi=O64]"
+msgstr ""
+
+#: elfxx-mips.c:9247
+msgid " [abi=EABI32]"
+msgstr ""
+
+#: elfxx-mips.c:9249
+msgid " [abi=EABI64]"
+msgstr ""
+
+#: elfxx-mips.c:9251
+#, fuzzy
+msgid " [abi unknown]"
+msgstr "[Kitazwi"
+
+#: elfxx-mips.c:9253
+msgid " [abi=N32]"
+msgstr ""
+
+#: elfxx-mips.c:9255
+msgid " [abi=64]"
+msgstr ""
+
+#: elfxx-mips.c:9257
+#, fuzzy
+msgid " [no abi set]"
+msgstr "[Oya Gushyiraho"
+
+#: elfxx-mips.c:9260
+msgid " [mips1]"
+msgstr ""
+
+#: elfxx-mips.c:9262
+msgid " [mips2]"
+msgstr ""
+
+#: elfxx-mips.c:9264
+msgid " [mips3]"
+msgstr ""
+
+#: elfxx-mips.c:9266
+msgid " [mips4]"
+msgstr ""
+
+#: elfxx-mips.c:9268
+msgid " [mips5]"
+msgstr ""
+
+#: elfxx-mips.c:9270
+msgid " [mips32]"
+msgstr ""
+
+#: elfxx-mips.c:9272
+msgid " [mips64]"
+msgstr ""
+
+#: elfxx-mips.c:9274
+msgid " [mips32r2]"
+msgstr ""
+
+#: elfxx-mips.c:9276
+#, fuzzy
+msgid " [unknown ISA]"
+msgstr "[Kitazwi"
+
+#: elfxx-mips.c:9279
+msgid " [mdmx]"
+msgstr ""
+
+#: elfxx-mips.c:9282
+msgid " [mips16]"
+msgstr ""
+
+#: elfxx-mips.c:9285
+msgid " [32bitmode]"
+msgstr ""
+
+#: elfxx-mips.c:9287
+#, fuzzy
+msgid " [not 32bitmode]"
+msgstr "[OYA"
+
+#: i386linux.c:457 m68klinux.c:461 sparclinux.c:458
+#, fuzzy, c-format
+msgid "Output file requires shared library `%s'\n"
+msgstr "IDOSIYE Isomero"
+
+#: i386linux.c:465 m68klinux.c:469 sparclinux.c:466
+#, fuzzy, c-format
+msgid "Output file requires shared library `%s.so.%s'\n"
+msgstr "IDOSIYE Isomero"
+
+#: i386linux.c:654 i386linux.c:704 m68klinux.c:661 m68klinux.c:709
+#: sparclinux.c:656 sparclinux.c:706
+#, fuzzy, c-format
+msgid "Symbol %s not defined for fixups\n"
+msgstr "OYA kugirango"
+
+#: i386linux.c:728 m68klinux.c:733 sparclinux.c:730
+#, fuzzy
+msgid "Warning: fixup count mismatch\n"
+msgstr "IBARA"
+
+#: ieee.c:293
+#, fuzzy, c-format
+msgid "%s: string too long (%d chars, max 65535)"
+msgstr "%s:Ikurikiranyanyuguti KININI"
+
+#: ieee.c:428
+#, fuzzy, c-format
+msgid "%s: unrecognized symbol `%s' flags 0x%x"
+msgstr "%s:IKIMENYETSO Amabendera"
+
+#: ieee.c:938
+#, fuzzy, c-format
+msgid "%s: unimplemented ATI record %u for symbol %u"
+msgstr "%s:Icyabitswe kugirango IKIMENYETSO"
+
+#: ieee.c:963
+#, fuzzy, c-format
+msgid "%s: unexpected ATN type %d in external part"
+msgstr "%s:Ubwoko in external"
+
+#: ieee.c:985
+#, fuzzy, c-format
+msgid "%s: unexpected type after ATN"
+msgstr "%s:Ubwoko Nyuma"
+
+#: ihex.c:264
+#, fuzzy, c-format
+msgid "%s:%d: unexpected character `%s' in Intel Hex file\n"
+msgstr "%s:%d:Inyuguti in"
+
+#: ihex.c:372
+#, fuzzy, c-format
+msgid "%s:%u: bad checksum in Intel Hex file (expected %u, found %u)"
+msgstr "%s:%u:in IDOSIYE Ikitezwe: Byabonetse"
+
+#: ihex.c:426
+#, fuzzy, c-format
+msgid "%s:%u: bad extended address record length in Intel Hex file"
+msgstr "%s:%u:Byongerewe... Aderesi Icyabitswe Uburebure in IDOSIYE"
+
+#: ihex.c:443
+#, fuzzy, c-format
+msgid "%s:%u: bad extended start address length in Intel Hex file"
+msgstr "%s:%u:Byongerewe... Gutangira Aderesi Uburebure in IDOSIYE"
+
+#: ihex.c:460
+#, fuzzy, c-format
+msgid "%s:%u: bad extended linear address record length in Intel Hex file"
+msgstr "%s:%u:Byongerewe... By'umurongo Aderesi Icyabitswe Uburebure in IDOSIYE"
+
+#: ihex.c:477
+#, fuzzy, c-format
+msgid "%s:%u: bad extended linear start address length in Intel Hex file"
+msgstr "%s:%u:Byongerewe... By'umurongo Gutangira Aderesi Uburebure in IDOSIYE"
+
+#: ihex.c:494
+#, fuzzy, c-format
+msgid "%s:%u: unrecognized ihex type %u in Intel Hex file\n"
+msgstr "%s:%u:Ubwoko in"
+
+#: ihex.c:619
+#, fuzzy, c-format
+msgid "%s: internal error in ihex_read_section"
+msgstr "%s:By'imbere Ikosa in"
+
+#: ihex.c:654
+#, fuzzy, c-format
+msgid "%s: bad section length in ihex_read_section"
+msgstr "%s:Icyiciro Uburebure in"
+
+#: ihex.c:872
+#, fuzzy, c-format
+msgid "%s: address 0x%s out of range for Intel Hex file"
+msgstr "%s:Aderesi Inyuma Bya Urutonde kugirango IDOSIYE"
+
+#: libbfd.c:861
+#, fuzzy, c-format
+msgid "Deprecated %s called at %s line %d in %s\n"
+msgstr "ku Umurongo in"
+
+#: libbfd.c:864
+#, c-format
+msgid "Deprecated %s called\n"
+msgstr ""
+
+#: linker.c:1829
+#, fuzzy, c-format
+msgid "%s: indirect symbol `%s' to `%s' is a loop"
+msgstr "%s:BUZIGUYE IKIMENYETSO Kuri ni a"
+
+#: linker.c:2697
+#, fuzzy, c-format
+msgid "Attempt to do relocatable link with %s input and %s output"
+msgstr "Kuri Ihuza Na: Iyinjiza Na Ibisohoka"
+
+#: merge.c:896
+#, fuzzy, c-format
+msgid "%s: access beyond end of merged section (%ld + %ld)"
+msgstr "%s:Impera Bya Icyiciro"
+
+#: mmo.c:503
+#, fuzzy, c-format
+msgid "%s: No core to allocate section name %s\n"
+msgstr "%s:Kuri Icyiciro Izina:"
+
+#: mmo.c:579
+#, fuzzy, c-format
+msgid "%s: No core to allocate a symbol %d bytes long\n"
+msgstr "%s:Kuri a IKIMENYETSO Bayite"
+
+#: mmo.c:1287
+#, fuzzy, c-format
+msgid "%s: invalid mmo file: initialization value for $255 is not `Main'\n"
+msgstr "%s:Sibyo IDOSIYE Agaciro kugirango ni OYA"
+
+#: mmo.c:1433
+#, fuzzy, c-format
+msgid "%s: unsupported wide character sequence 0x%02X 0x%02X after symbol name starting with `%s'\n"
+msgstr "%s:Inyuguti Nyuma IKIMENYETSO Izina: Na:"
+
+#: mmo.c:1674
+#, fuzzy, c-format
+msgid "%s: invalid mmo file: unsupported lopcode `%d'\n"
+msgstr "%s:Sibyo IDOSIYE"
+
+#: mmo.c:1684
+#, fuzzy, c-format
+msgid "%s: invalid mmo file: expected YZ = 1 got YZ = %d for lop_quote\n"
+msgstr "%s:Sibyo IDOSIYE Ikitezwe: 1. kugirango"
+
+#: mmo.c:1720
+#, fuzzy, c-format
+msgid "%s: invalid mmo file: expected z = 1 or z = 2, got z = %d for lop_loc\n"
+msgstr "%s:Sibyo IDOSIYE Ikitezwe: Z 1. Cyangwa Z 2. Z kugirango"
+
+#: mmo.c:1766
+#, fuzzy, c-format
+msgid "%s: invalid mmo file: expected z = 1 or z = 2, got z = %d for lop_fixo\n"
+msgstr "%s:Sibyo IDOSIYE Ikitezwe: Z 1. Cyangwa Z 2. Z kugirango"
+
+#: mmo.c:1805
+#, fuzzy, c-format
+msgid "%s: invalid mmo file: expected y = 0, got y = %d for lop_fixrx\n"
+msgstr "%s:Sibyo IDOSIYE Ikitezwe: Y 0 Y kugirango"
+
+#: mmo.c:1814
+#, fuzzy, c-format
+msgid "%s: invalid mmo file: expected z = 16 or z = 24, got z = %d for lop_fixrx\n"
+msgstr "%s:Sibyo IDOSIYE Ikitezwe: Z Cyangwa Z Z kugirango"
+
+#: mmo.c:1837
+#, fuzzy, c-format
+msgid "%s: invalid mmo file: leading byte of operand word must be 0 or 1, got %d for lop_fixrx\n"
+msgstr "%s:Sibyo IDOSIYE Nyobora Bayite Bya ijambo 0 Cyangwa 1. kugirango"
+
+#: mmo.c:1860
+#, fuzzy, c-format
+msgid "%s: cannot allocate file name for file number %d, %d bytes\n"
+msgstr "%s:IDOSIYE Izina: kugirango IDOSIYE Umubare"
+
+#: mmo.c:1880
+#, fuzzy, c-format
+msgid "%s: invalid mmo file: file number %d `%s', was already entered as `%s'\n"
+msgstr "%s:Sibyo IDOSIYE IDOSIYE Umubare Nka"
+
+#: mmo.c:1893
+#, fuzzy, c-format
+msgid "%s: invalid mmo file: file name for number %d was not specified before use\n"
+msgstr "%s:Sibyo IDOSIYE IDOSIYE Izina: kugirango Umubare OYA Mbere"
+
+#: mmo.c:1999
+#, fuzzy, c-format
+msgid "%s: invalid mmo file: fields y and z of lop_stab non-zero, y: %d, z: %d\n"
+msgstr "%s:Sibyo IDOSIYE Imyanya Y Na Z Bya Zeru Y Z"
+
+#: mmo.c:2035
+#, fuzzy, c-format
+msgid "%s: invalid mmo file: lop_end not last item in file\n"
+msgstr "%s:Sibyo IDOSIYE OYA Iheruka Ikintu in"
+
+#: mmo.c:2048
+#, fuzzy, c-format
+msgid "%s: invalid mmo file: YZ of lop_end (%ld) not equal to the number of tetras to the preceding lop_stab (%ld)\n"
+msgstr "%s:Sibyo IDOSIYE Bya OYA bingana Kuri i Umubare Bya Kuri i"
+
+#: mmo.c:2698
+#, fuzzy, c-format
+msgid "%s: invalid symbol table: duplicate symbol `%s'\n"
+msgstr "%s:Sibyo IKIMENYETSO imbonerahamwe# Gusubiramo IKIMENYETSO"
+
+#: mmo.c:2949
+#, fuzzy, c-format
+msgid "%s: Bad symbol definition: `Main' set to %s rather than the start address %s\n"
+msgstr "%s:IKIMENYETSO Insobanuro Gushyiraho Kuri i Gutangira Aderesi"
+
+#: mmo.c:3039
+#, fuzzy, c-format
+msgid "%s: warning: symbol table too large for mmo, larger than 65535 32-bit words: %d. Only `Main' will be emitted.\n"
+msgstr "%s:Iburira IKIMENYETSO imbonerahamwe# Binini kugirango Kinini Amagambo"
+
+#: mmo.c:3084
+#, fuzzy, c-format
+msgid "%s: internal error, symbol table changed size from %d to %d words\n"
+msgstr "%s:By'imbere Ikosa IKIMENYETSO imbonerahamwe# Byahinduwe Ingano Bivuye Kuri"
+
+#: mmo.c:3139
+#, fuzzy, c-format
+msgid "%s: internal error, internal register section %s had contents\n"
+msgstr "%s:By'imbere Ikosa By'imbere Kwiyandikisha Icyiciro"
+
+#: mmo.c:3191
+#, fuzzy, c-format
+msgid "%s: no initialized registers; section length 0\n"
+msgstr "%s:Oya Icyiciro Uburebure"
+
+#: mmo.c:3197
+#, fuzzy, c-format
+msgid "%s: too many initialized registers; section length %ld\n"
+msgstr "%s:Icyiciro Uburebure"
+
+#: mmo.c:3202
+#, fuzzy, c-format
+msgid "%s: invalid start address for initialized registers of length %ld: 0x%lx%08lx\n"
+msgstr "%s:Sibyo Gutangira Aderesi kugirango Bya Uburebure"
+
+#: oasys.c:1052
+#, fuzzy, c-format
+msgid "%s: can not represent section `%s' in oasys"
+msgstr "%s:OYA Icyiciro in"
+
+#: osf-core.c:137
+#, fuzzy, c-format
+msgid "Unhandled OSF/1 core file section type %d\n"
+msgstr "1. IDOSIYE Icyiciro Ubwoko"
+
+#. XXX code yet to be written.
+#: peicode.h:787
+#, fuzzy, c-format
+msgid "%s: Unhandled import type; %x"
+msgstr "%s:Kuzana Ubwoko"
+
+#: peicode.h:792
+#, fuzzy, c-format
+msgid "%s: Unrecognised import type; %x"
+msgstr "%s:Kuzana Ubwoko"
+
+#: peicode.h:806
+#, fuzzy, c-format
+msgid "%s: Unrecognised import name type; %x"
+msgstr "%s:Kuzana Izina: Ubwoko"
+
+#: peicode.h:1164
+#, fuzzy, c-format
+msgid "%s: Unrecognised machine type (0x%x) in Import Library Format archive"
+msgstr "%s:Ubwoko in"
+
+#: peicode.h:1176
+#, fuzzy, c-format
+msgid "%s: Recognised but unhandled machine type (0x%x) in Import Library Format archive"
+msgstr "%s:Ubwoko in"
+
+#: peicode.h:1193
+#, fuzzy, c-format
+msgid "%s: size field is zero in Import Library Format header"
+msgstr "%s:Ingano Umwanya ni Zeru in Umutwempangano"
+
+#: peicode.h:1224
+#, fuzzy, c-format
+msgid "%s: string not null terminated in ILF object file."
+msgstr "%s:Ikurikiranyanyuguti OYA NTAGIHARI in Igikoresho IDOSIYE"
+
+#: pe-mips.c:659
+#, fuzzy, c-format
+msgid "%s: `ld -r' not supported with PE MIPS objects\n"
+msgstr "%s:`OYA Na:"
+
+#. OK, at this point the following variables are set up:
+#. src = VMA of the memory we're fixing up
+#. mem = pointer to memory we're fixing up
+#. val = VMA of what we need to refer to
+#.
+#: pe-mips.c:795
+#, c-format
+msgid "%s: unimplemented %s\n"
+msgstr ""
+
+#: pe-mips.c:821
+#, fuzzy, c-format
+msgid "%s: jump too far away\n"
+msgstr "%s:Simbuka"
+
+#: pe-mips.c:848
+#, fuzzy, c-format
+msgid "%s: bad pair/reflo after refhi\n"
+msgstr "%s:Nyuma"
+
+#: ppcboot.c:416
+#, fuzzy
+msgid ""
+"\n"
+"ppcboot header:\n"
+msgstr "Umutwempangano"
+
+#: ppcboot.c:417
+#, fuzzy, c-format
+msgid "Entry offset = 0x%.8lx (%ld)\n"
+msgstr "Nta- boneza"
+
+#: ppcboot.c:418
+#, c-format
+msgid "Length = 0x%.8lx (%ld)\n"
+msgstr ""
+
+#: ppcboot.c:421
+#, fuzzy, c-format
+msgid "Flag field = 0x%.2x\n"
+msgstr "Umwanya"
+
+#: ppcboot.c:427
+#, fuzzy, c-format
+msgid "Partition name = \"%s\"\n"
+msgstr "Izina:"
+
+#: ppcboot.c:446
+#, fuzzy, c-format
+msgid ""
+"\n"
+"Partition[%d] start = { 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x }\n"
+msgstr "Gutangira"
+
+#: ppcboot.c:452
+#, fuzzy, c-format
+msgid "Partition[%d] end = { 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x }\n"
+msgstr "Impera"
+
+#: ppcboot.c:458
+#, c-format
+msgid "Partition[%d] sector = 0x%.8lx (%ld)\n"
+msgstr ""
+
+#: ppcboot.c:459
+#, fuzzy, c-format
+msgid "Partition[%d] length = 0x%.8lx (%ld)\n"
+msgstr "Uburebure"
+
+#: som.c:5422
+msgid "som_sizeof_headers unimplemented"
+msgstr ""
+
+#: srec.c:302
+#, fuzzy, c-format
+msgid "%s:%d: Unexpected character `%s' in S-record file\n"
+msgstr "%s:%d:Inyuguti in Icyabitswe"
+
+#: stabs.c:319
+#, fuzzy, c-format
+msgid "%s(%s+0x%lx): Stabs entry has invalid string index."
+msgstr "%s(%s+0x%lx):Icyinjijwe Sibyo Ikurikiranyanyuguti Umubarendanga"
+
+#: syms.c:1019
+msgid "Unsupported .stab relocation"
+msgstr ""
+
+#: vms-gsd.c:356
+#, fuzzy, c-format
+msgid "bfd_make_section (%s) failed"
+msgstr "Byanze"
+
+#: vms-gsd.c:371
+#, fuzzy, c-format
+msgid "bfd_set_section_flags (%s, %x) failed"
+msgstr "Byanze"
+
+#: vms-gsd.c:407
+#, fuzzy, c-format
+msgid "Size mismatch section %s=%lx, %s=%lx"
+msgstr "Icyiciro"
+
+#: vms-gsd.c:704
+#, fuzzy, c-format
+msgid "unknown gsd/egsd subtype %d"
+msgstr "Kitazwi"
+
+#: vms-hdr.c:408
+#, fuzzy
+msgid "Object module NOT error-free !\n"
+msgstr "Modire Ikosa Kigenga"
+
+#: vms-misc.c:541
+#, fuzzy, c-format
+msgid "Stack overflow (%d) in _bfd_vms_push"
+msgstr "Byarenze urugero in"
+
+#: vms-misc.c:559
+#, fuzzy
+msgid "Stack underflow in _bfd_vms_pop"
+msgstr "in"
+
+#: vms-misc.c:918
+#, fuzzy
+msgid "_bfd_vms_output_counted called with zero bytes"
+msgstr "Na: Zeru Bayite"
+
+#: vms-misc.c:923
+#, fuzzy
+msgid "_bfd_vms_output_counted called with too many bytes"
+msgstr "Na: Bayite"
+
+#: vms-misc.c:1054
+#, fuzzy, c-format
+msgid "Symbol %s replaced by %s\n"
+msgstr "ku"
+
+#: vms-misc.c:1117
+#, fuzzy, c-format
+msgid "failed to enter %s"
+msgstr "Byanze Kuri Injiza"
+
+#: vms-tir.c:102
+msgid "No Mem !"
+msgstr ""
+
+#: vms-tir.c:383
+#, fuzzy, c-format
+msgid "bad section index in %s"
+msgstr "Icyiciro Umubarendanga in"
+
+#: vms-tir.c:396
+#, fuzzy, c-format
+msgid "unsupported STA cmd %s"
+msgstr "Cmd+"
+
+#: vms-tir.c:401 vms-tir.c:1261
+#, fuzzy, c-format
+msgid "reserved STA cmd %d"
+msgstr "Cmd+"
+
+#: vms-tir.c:512 vms-tir.c:535
+#, fuzzy, c-format
+msgid "%s: no symbol \"%s\""
+msgstr "%s:Oya IKIMENYETSO"
+
+#. unsigned shift
+#. rotate
+#. Redefine symbol to current location.
+#. Define a literal.
+#: vms-tir.c:602 vms-tir.c:714 vms-tir.c:824 vms-tir.c:842 vms-tir.c:850
+#: vms-tir.c:859 vms-tir.c:1584
+#, fuzzy, c-format
+msgid "%s: not supported"
+msgstr "%s:OYA"
+
+#: vms-tir.c:607 vms-tir.c:1439
+#, fuzzy, c-format
+msgid "%s: not implemented"
+msgstr "%s:OYA"
+
+#: vms-tir.c:611 vms-tir.c:1443
+#, fuzzy, c-format
+msgid "reserved STO cmd %d"
+msgstr "Cmd+"
+
+#: vms-tir.c:729 vms-tir.c:1589
+#, fuzzy, c-format
+msgid "reserved OPR cmd %d"
+msgstr "Cmd+"
+
+#: vms-tir.c:797 vms-tir.c:1653
+#, fuzzy, c-format
+msgid "reserved CTL cmd %d"
+msgstr "Cmd+"
+
+#. stack byte from image
+#. arg: none.
+#: vms-tir.c:1169
+#, fuzzy
+msgid "stack-from-image not implemented"
+msgstr "Bivuye Ishusho OYA"
+
+#: vms-tir.c:1187
+#, fuzzy
+msgid "stack-entry-mask not fully implemented"
+msgstr "Icyinjijwe OYA"
+
+#. 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.
+#: vms-tir.c:1201
+#, fuzzy
+msgid "PASSMECH not fully implemented"
+msgstr "OYA"
+
+#: vms-tir.c:1220
+#, fuzzy
+msgid "stack-local-symbol not fully implemented"
+msgstr "IKIMENYETSO OYA"
+
+#: vms-tir.c:1233
+#, fuzzy
+msgid "stack-literal not fully implemented"
+msgstr "OYA"
+
+#: vms-tir.c:1254
+#, fuzzy
+msgid "stack-local-symbol-entry-point-mask not fully implemented"
+msgstr "IKIMENYETSO Icyinjijwe Akadomo OYA"
+
+#: vms-tir.c:1531 vms-tir.c:1543 vms-tir.c:1555 vms-tir.c:1567 vms-tir.c:1632
+#: vms-tir.c:1640 vms-tir.c:1648
+#, fuzzy, c-format
+msgid "%s: not fully implemented"
+msgstr "%s:OYA"
+
+#: vms-tir.c:1705
+#, fuzzy, c-format
+msgid "obj code %d not found"
+msgstr "ITEGEKONGENGA OYA Byabonetse"
+
+#: vms-tir.c:2043
+#, fuzzy, c-format
+msgid "SEC_RELOC with no relocs in section %s"
+msgstr "Na: Oya in Icyiciro"
+
+#: vms-tir.c:2331
+#, c-format
+msgid "Unhandled relocation %s"
+msgstr ""
+
+#: xcofflink.c:1244
+#, fuzzy, c-format
+msgid "%s: `%s' has line numbers but no enclosing section"
+msgstr "%s:`%s'Umurongo Imibare Oya Icyiciro"
+
+#: xcofflink.c:1297
+#, fuzzy, c-format
+msgid "%s: class %d symbol `%s' has no aux entries"
+msgstr "%s:ishuri IKIMENYETSO Oya Ibyinjijwe"
+
+#: xcofflink.c:1320
+#, fuzzy, c-format
+msgid "%s: symbol `%s' has unrecognized csect type %d"
+msgstr "%s:IKIMENYETSO Ubwoko"
+
+#: xcofflink.c:1332
+#, fuzzy, c-format
+msgid "%s: bad XTY_ER symbol `%s': class %d scnum %d scnlen %d"
+msgstr "%s:IKIMENYETSO ishuri"
+
+#: xcofflink.c:1368
+#, fuzzy, c-format
+msgid "%s: XMC_TC0 symbol `%s' is class %d scnlen %d"
+msgstr "%s:IKIMENYETSO ni ishuri"
+
+#: xcofflink.c:1520
+#, fuzzy, c-format
+msgid "%s: csect `%s' not in enclosing section"
+msgstr "%s:OYA in Icyiciro"
+
+#: xcofflink.c:1627
+#, c-format
+msgid "%s: misplaced XTY_LD `%s'"
+msgstr ""
+
+#: xcofflink.c:1958
+#, fuzzy, c-format
+msgid "%s: reloc %s:%d not in csect"
+msgstr "%s:OYA in"
+
+#: xcofflink.c:2095
+#, fuzzy, c-format
+msgid "%s: XCOFF shared object when not producing XCOFF output"
+msgstr "%s:Igikoresho Ryari: OYA Ibisohoka"
+
+#: xcofflink.c:2116
+#, fuzzy, c-format
+msgid "%s: dynamic object with no .loader section"
+msgstr "%s:Igikoresho Na: Oya Icyiciro"
+
+#: xcofflink.c:2761
+#, fuzzy, c-format
+msgid "%s: no such symbol"
+msgstr "%s:Oya IKIMENYETSO"
+
+#: xcofflink.c:2894
+#, fuzzy
+msgid "error: undefined symbol __rtinit"
+msgstr "Ikosa kidasobanuye IKIMENYETSO"
+
+#: xcofflink.c:3455
+#, fuzzy, c-format
+msgid "warning: attempt to export undefined symbol `%s'"
+msgstr "Iburira Kuri Kohereza kidasobanuye IKIMENYETSO"
+
+#: xcofflink.c:4448
+#, fuzzy, c-format
+msgid "TOC overflow: 0x%lx > 0x10000; try -mminimal-toc when compiling"
+msgstr "Byarenze urugero Ryari:"
+
+#: xcofflink.c:5288 xcofflink.c:5755 xcofflink.c:5817 xcofflink.c:6119
+#, fuzzy, c-format
+msgid "%s: loader reloc in unrecognized section `%s'"
+msgstr "%s:in Icyiciro"
+
+#: xcofflink.c:5310 xcofflink.c:6130
+#, fuzzy, c-format
+msgid "%s: `%s' in loader reloc but not loader sym"
+msgstr "%s:`%s'in OYA"
+
+#: xcofflink.c:5325
+#, fuzzy, c-format
+msgid "%s: loader reloc in read-only section %s"
+msgstr "%s:in Gusoma Icyiciro"
+
+#: elf32-ia64.c:2271 elf64-ia64.c:2271
+#, fuzzy
+msgid "@pltoff reloc against local symbol"
+msgstr "@IKIMENYETSO"
+
+#: elf32-ia64.c:3663 elf64-ia64.c:3663
+#, fuzzy, c-format
+msgid "%s: short data segment overflowed (0x%lx >= 0x400000)"
+msgstr "%s:Ibyatanzwe"
+
+#: elf32-ia64.c:3674 elf64-ia64.c:3674
+#, fuzzy, c-format
+msgid "%s: __gp does not cover short data segment"
+msgstr "%s:_OYA Ibyatanzwe"
+
+#: elf32-ia64.c:3986 elf64-ia64.c:3986
+#, fuzzy, c-format
+msgid "%s: linking non-pic code in a shared library"
+msgstr "%s:Impuza ITEGEKONGENGA in a Isomero"
+
+#: elf32-ia64.c:4017 elf64-ia64.c:4017
+#, fuzzy, c-format
+msgid "%s: @gprel relocation against dynamic symbol %s"
+msgstr "%s:@IKIMENYETSO"
+
+#: elf32-ia64.c:4077 elf64-ia64.c:4077
+#, fuzzy, c-format
+msgid "%s: linking non-pic code in a position independent executable"
+msgstr "%s:Impuza ITEGEKONGENGA in a Ibirindiro"
+
+#: elf32-ia64.c:4214 elf64-ia64.c:4214
+#, fuzzy, c-format
+msgid "%s: @internal branch to dynamic symbol %s"
+msgstr "%s:@By'imbere Kuri IKIMENYETSO"
+
+#: elf32-ia64.c:4216 elf64-ia64.c:4216
+#, fuzzy, c-format
+msgid "%s: speculation fixup to dynamic symbol %s"
+msgstr "%s:Kuri IKIMENYETSO"
+
+#: elf32-ia64.c:4218 elf64-ia64.c:4218
+#, fuzzy, c-format
+msgid "%s: @pcrel relocation against dynamic symbol %s"
+msgstr "%s:@IKIMENYETSO"
+
+#: elf32-ia64.c:4430 elf64-ia64.c:4430
+msgid "unsupported reloc"
+msgstr ""
+
+#: elf32-ia64.c:4709 elf64-ia64.c:4709
+#, fuzzy, c-format
+msgid "%s: linking trap-on-NULL-dereference with non-trapping files"
+msgstr "%s:Impuza ku Na: Idosiye"
+
+#: elf32-ia64.c:4718 elf64-ia64.c:4718
+#, fuzzy, c-format
+msgid "%s: linking big-endian files with little-endian files"
+msgstr "%s:Impuza Idosiye Na: Idosiye"
+
+#: elf32-ia64.c:4727 elf64-ia64.c:4727
+#, fuzzy, c-format
+msgid "%s: linking 64-bit files with 32-bit files"
+msgstr "%s:Impuza Idosiye Na: Idosiye"
+
+#: elf32-ia64.c:4736 elf64-ia64.c:4736
+#, fuzzy, c-format
+msgid "%s: linking constant-gp files with non-constant-gp files"
+msgstr "%s:Impuza Idosiye Na: Idosiye"
+
+#: elf32-ia64.c:4746 elf64-ia64.c:4746
+#, fuzzy, c-format
+msgid "%s: linking auto-pic files with non-auto-pic files"
+msgstr "%s:Impuza Ikiyega Idosiye Na: Ikiyega Idosiye"
+
+#: peigen.c:985 pepigen.c:985
+#, fuzzy, c-format
+msgid "%s: line number overflow: 0x%lx > 0xffff"
+msgstr "%s:Umurongo Umubare Byarenze urugero"
+
+#: peigen.c:1002 pepigen.c:1002
+#, fuzzy, c-format
+msgid "%s: reloc overflow 1: 0x%lx > 0xffff"
+msgstr "%s:Byarenze urugero 1."
+
+#: peigen.c:1016 pepigen.c:1016
+#, fuzzy
+msgid "Export Directory [.edata (or where ever we found it)]"
+msgstr "Cyangwa Twebwe Byabonetse"
+
+#: peigen.c:1017 pepigen.c:1017
+#, fuzzy
+msgid "Import Directory [parts of .idata]"
+msgstr "Bya"
+
+#: peigen.c:1018 pepigen.c:1018
+msgid "Resource Directory [.rsrc]"
+msgstr ""
+
+#: peigen.c:1019 pepigen.c:1019
+msgid "Exception Directory [.pdata]"
+msgstr ""
+
+#: peigen.c:1020 pepigen.c:1020
+msgid "Security Directory"
+msgstr ""
+
+#: peigen.c:1021 pepigen.c:1021
+#, fuzzy
+msgid "Base Relocation Directory [.reloc]"
+msgstr "Base"
+
+#: peigen.c:1022 pepigen.c:1022
+msgid "Debug Directory"
+msgstr ""
+
+#: peigen.c:1023 pepigen.c:1023
+msgid "Description Directory"
+msgstr ""
+
+#: peigen.c:1024 pepigen.c:1024
+msgid "Special Directory"
+msgstr ""
+
+#: peigen.c:1025 pepigen.c:1025
+#, fuzzy
+msgid "Thread Storage Directory [.tls]"
+msgstr "TLS"
+
+#: peigen.c:1026 pepigen.c:1026
+msgid "Load Configuration Directory"
+msgstr ""
+
+#: peigen.c:1027 pepigen.c:1027
+msgid "Bound Import Directory"
+msgstr ""
+
+#: peigen.c:1028 pepigen.c:1028
+msgid "Import Address Table Directory"
+msgstr ""
+
+#: peigen.c:1029 pepigen.c:1029
+msgid "Delay Import Directory"
+msgstr ""
+
+#: peigen.c:1030 peigen.c:1031 pepigen.c:1030 pepigen.c:1031
+msgid "Reserved"
+msgstr ""
+
+#: peigen.c:1094 pepigen.c:1094
+#, fuzzy
+msgid ""
+"\n"
+"There is an import table, but the section containing it could not be found\n"
+msgstr "ni Kuzana imbonerahamwe# i Icyiciro OYA"
+
+#: peigen.c:1099 pepigen.c:1099
+#, fuzzy, c-format
+msgid ""
+"\n"
+"There is an import table in %s at 0x%lx\n"
+msgstr "ni Kuzana imbonerahamwe# in ku"
+
+#: peigen.c:1136 pepigen.c:1136
+#, fuzzy, c-format
+msgid ""
+"\n"
+"Function descriptor located at the start address: %04lx\n"
+msgstr "ku i Gutangira Aderesi"
+
+#: peigen.c:1139 pepigen.c:1139
+#, fuzzy, c-format
+msgid "\tcode-base %08lx toc (loadable/actual) %08lx/%08lx\n"
+msgstr "ITEGEKONGENGA SHINGIRO"
+
+#: peigen.c:1145 pepigen.c:1145
+#, fuzzy
+msgid ""
+"\n"
+"No reldata section! Function descriptor not decoded.\n"
+msgstr "Icyiciro OYA"
+
+#: peigen.c:1150 pepigen.c:1150
+#, fuzzy, c-format
+msgid ""
+"\n"
+"The Import Tables (interpreted %s section contents)\n"
+msgstr "Icyiciro Ibigize"
+
+#: peigen.c:1153 pepigen.c:1153
+msgid ""
+" vma: Hint Time Forward DLL First\n"
+" Table Stamp Chain Name Thunk\n"
+msgstr ""
+
+#: peigen.c:1204 pepigen.c:1204
+#, c-format
+msgid ""
+"\n"
+"\tDLL Name: %s\n"
+msgstr ""
+
+#: peigen.c:1215 pepigen.c:1215
+msgid "\tvma: Hint/Ord Member-Name Bound-To\n"
+msgstr ""
+
+#: peigen.c:1240 pepigen.c:1240
+#, fuzzy
+msgid ""
+"\n"
+"There is a first thunk, but the section containing it could not be found\n"
+msgstr "ni a Itangira i Icyiciro OYA"
+
+#: peigen.c:1380 pepigen.c:1380
+#, fuzzy
+msgid ""
+"\n"
+"There is an export table, but the section containing it could not be found\n"
+msgstr "ni Kohereza imbonerahamwe# i Icyiciro OYA"
+
+#: peigen.c:1385 pepigen.c:1385
+#, fuzzy, c-format
+msgid ""
+"\n"
+"There is an export table in %s at 0x%lx\n"
+msgstr "ni Kohereza imbonerahamwe# in ku"
+
+#: peigen.c:1416 pepigen.c:1416
+#, fuzzy, c-format
+msgid ""
+"\n"
+"The Export Tables (interpreted %s section contents)\n"
+"\n"
+msgstr "Icyiciro Ibigize"
+
+#: peigen.c:1420 pepigen.c:1420
+#, c-format
+msgid "Export Flags \t\t\t%lx\n"
+msgstr ""
+
+#: peigen.c:1423 pepigen.c:1423
+#, c-format
+msgid "Time/Date stamp \t\t%lx\n"
+msgstr ""
+
+#: peigen.c:1426 pepigen.c:1426
+#, c-format
+msgid "Major/Minor \t\t\t%d/%d\n"
+msgstr ""
+
+#: peigen.c:1429 pepigen.c:1429
+#, fuzzy
+msgid "Name \t\t\t\t"
+msgstr "Izina"
+
+#: peigen.c:1435 pepigen.c:1435
+#, fuzzy, c-format
+msgid "Ordinal Base \t\t\t%ld\n"
+msgstr "Base"
+
+#: peigen.c:1438 pepigen.c:1438
+#, fuzzy
+msgid "Number in:\n"
+msgstr "in"
+
+#: peigen.c:1441 pepigen.c:1441
+#, c-format
+msgid "\tExport Address Table \t\t%08lx\n"
+msgstr ""
+
+#: peigen.c:1445 pepigen.c:1445
+#, c-format
+msgid "\t[Name Pointer/Ordinal] Table\t%08lx\n"
+msgstr ""
+
+#: peigen.c:1448 pepigen.c:1448
+msgid "Table Addresses\n"
+msgstr ""
+
+#: peigen.c:1451 pepigen.c:1451
+msgid "\tExport Address Table \t\t"
+msgstr ""
+
+#: peigen.c:1456 pepigen.c:1456
+msgid "\tName Pointer Table \t\t"
+msgstr ""
+
+#: peigen.c:1461 pepigen.c:1461
+msgid "\tOrdinal Table \t\t\t"
+msgstr ""
+
+#: peigen.c:1476 pepigen.c:1476
+#, fuzzy, c-format
+msgid ""
+"\n"
+"Export Address Table -- Ordinal Base %ld\n"
+msgstr "Base"
+
+#: peigen.c:1495 pepigen.c:1495
+msgid "Forwarder RVA"
+msgstr ""
+
+#: peigen.c:1506 pepigen.c:1506
+msgid "Export RVA"
+msgstr ""
+
+#: peigen.c:1513 pepigen.c:1513
+msgid ""
+"\n"
+"[Ordinal/Name Pointer] Table\n"
+msgstr ""
+
+#: peigen.c:1568 pepigen.c:1568
+#, fuzzy, c-format
+msgid "Warning, .pdata section size (%ld) is not a multiple of %d\n"
+msgstr "Icyiciro Ingano ni OYA a Igikubo Bya"
+
+#: peigen.c:1572 pepigen.c:1572
+#, fuzzy
+msgid ""
+"\n"
+"The Function Table (interpreted .pdata section contents)\n"
+msgstr "Icyiciro Ibigize"
+
+#: peigen.c:1575 pepigen.c:1575
+#, fuzzy
+msgid " vma:\t\t\tBegin Address End Address Unwind Info\n"
+msgstr "Impera"
+
+#: peigen.c:1577 pepigen.c:1577
+#, fuzzy
+msgid ""
+" vma:\t\tBegin End EH EH PrologEnd Exception\n"
+" \t\tAddress Address Handler Data Address Mask\n"
+msgstr "Impera"
+
+#: peigen.c:1647 pepigen.c:1647
+#, fuzzy
+msgid " Register save millicode"
+msgstr "Kubika"
+
+#: peigen.c:1650 pepigen.c:1650
+#, fuzzy
+msgid " Register restore millicode"
+msgstr "Kugarura"
+
+#: peigen.c:1653 pepigen.c:1653
+#, fuzzy
+msgid " Glue code sequence"
+msgstr "ITEGEKONGENGA"
+
+#: peigen.c:1705 pepigen.c:1705
+#, fuzzy
+msgid ""
+"\n"
+"\n"
+"PE File Base Relocations (interpreted .reloc section contents)\n"
+msgstr "Idosiye Base Icyiciro Ibigize"
+
+#: peigen.c:1735 pepigen.c:1735
+#, fuzzy, c-format
+msgid ""
+"\n"
+"Virtual Address: %08lx Chunk size %ld (0x%lx) Number of fixups %ld\n"
+msgstr "Ingano Bya"
+
+#: peigen.c:1748 pepigen.c:1748
+#, fuzzy, c-format
+msgid "\treloc %4d offset %4x [%4lx] %s"
+msgstr "Nta- boneza"
+
+#. The MS dumpbin program reportedly ands with 0xff0f before
+#. printing the characteristics field. Not sure why. No reason to
+#. emulate it here.
+#: peigen.c:1788 pepigen.c:1788
+#, c-format
+msgid ""
+"\n"
+"Characteristics 0x%x\n"
+msgstr ""
diff --git a/bfd/po/sv.gmo b/bfd/po/sv.gmo
new file mode 100644
index 0000000..e746ec0
--- /dev/null
+++ b/bfd/po/sv.gmo
Binary files differ
diff --git a/bfd/po/sv.po b/bfd/po/sv.po
new file mode 100644
index 0000000..e0b667c
--- /dev/null
+++ b/bfd/po/sv.po
@@ -0,0 +1,3221 @@
+# Swedish messages for bfd.
+# Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
+# Christian Rose <menthos@menthos.com>, 2001, 2002, 2003.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: bfd 2.14rel030712\n"
+"POT-Creation-Date: 2003-07-11 13:53+0930\n"
+"PO-Revision-Date: 2003-08-14 22:40+0200\n"
+"Last-Translator: Christian Rose <menthos@menthos.com>\n"
+"Language-Team: Swedish <sv@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=iso-8859-1\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: aout-adobe.c:204
+#, c-format
+msgid "%s: Unknown section type in a.out.adobe file: %x\n"
+msgstr "%s: Okänd sektionstyp i a.out.adobe-fil: %x\n"
+
+#: aout-cris.c:207
+#, c-format
+msgid "%s: Invalid relocation type exported: %d"
+msgstr "%s: Ogiltig omlokaliseringstyp exporterad: %d"
+
+#: aout-cris.c:251
+#, c-format
+msgid "%s: Invalid relocation type imported: %d"
+msgstr "%s: Ogiltig omlokaliseringstyp importerad: %d"
+
+#: aout-cris.c:262
+#, c-format
+msgid "%s: Bad relocation record imported: %d"
+msgstr "%s: Felaktig omlokaliseringstyp importerad: %d"
+
+#: aoutx.h:1295 aoutx.h:1716
+#, c-format
+msgid "%s: can not represent section `%s' in a.out object file format"
+msgstr "%s: kan inte representera sektionen \"%s\" i a.out-objektfilformat"
+
+#: aoutx.h:1682
+#, c-format
+msgid "%s: can not represent section for symbol `%s' in a.out object file format"
+msgstr "%s: kan inte representera sektion för symbolen \"%s\" i a.out-objektfilformat"
+
+#: aoutx.h:1684
+msgid "*unknown*"
+msgstr "*okänd*"
+
+#: aoutx.h:3776
+#, c-format
+msgid "%s: relocatable link from %s to %s not supported"
+msgstr "%s: omlokaliseringsbar länk från %s till %s stöds inte"
+
+#: archive.c:1751
+msgid "Warning: writing archive was slow: rewriting timestamp\n"
+msgstr "Varning: arkivskrivning var långsam: skriver om tidsstämpel\n"
+
+#: archive.c:2014
+msgid "Reading archive file mod timestamp"
+msgstr "Läser arkivfilens modifieringstidsstämpel"
+
+#: archive.c:2040
+msgid "Writing updated armap timestamp"
+msgstr "Skriver uppdaterad armap-tidsstämpel"
+
+#: bfd.c:280
+msgid "No error"
+msgstr "Inget fel"
+
+#: bfd.c:281
+msgid "System call error"
+msgstr "Systemanropsfel"
+
+#: bfd.c:282
+msgid "Invalid bfd target"
+msgstr "Ogiltigt bfd-mål"
+
+#: bfd.c:283
+msgid "File in wrong format"
+msgstr "Filen är i fel format"
+
+#: bfd.c:284
+msgid "Archive object file in wrong format"
+msgstr "Arkivobjektfil är i fel format"
+
+#: bfd.c:285
+msgid "Invalid operation"
+msgstr "Ogiltig åtgärd"
+
+#: bfd.c:286
+msgid "Memory exhausted"
+msgstr "Minnet är slut"
+
+#: bfd.c:287
+msgid "No symbols"
+msgstr "Inga symboler"
+
+#: bfd.c:288
+msgid "Archive has no index; run ranlib to add one"
+msgstr "Arkivet har inget index; kör ranlib för att lägga till ett"
+
+#: bfd.c:289
+msgid "No more archived files"
+msgstr "Inga fler arkiverade filer"
+
+#: bfd.c:290
+msgid "Malformed archive"
+msgstr "Trasigt arkiv"
+
+#: bfd.c:291
+msgid "File format not recognized"
+msgstr "Filformatet känns inte igen"
+
+#: bfd.c:292
+msgid "File format is ambiguous"
+msgstr "Filformatet är tvetydigt"
+
+#: bfd.c:293
+msgid "Section has no contents"
+msgstr "Sektionen har inget innehåll"
+
+#: bfd.c:294
+msgid "Nonrepresentable section on output"
+msgstr "Ickerepresenterbar sektion i utdata"
+
+#: bfd.c:295
+msgid "Symbol needs debug section which does not exist"
+msgstr "Symbolen kräver felsökningssektion som inte finns"
+
+#: bfd.c:296
+msgid "Bad value"
+msgstr "Felaktigt värde"
+
+#: bfd.c:297
+msgid "File truncated"
+msgstr "Filen trunkerad"
+
+#: bfd.c:298
+msgid "File too big"
+msgstr "Filen är för stor"
+
+#: bfd.c:299
+msgid "#<Invalid error code>"
+msgstr "#<Ogiltig felkod>"
+
+#: bfd.c:687
+#, c-format
+msgid "BFD %s assertion fail %s:%d"
+msgstr "BFD %s-försäkran misslyckades %s:%d"
+
+#: bfd.c:703
+#, c-format
+msgid "BFD %s internal error, aborting at %s line %d in %s\n"
+msgstr "Internt BFD %s-fel, avbryter vid %s rad %d i %s\n"
+
+#: bfd.c:707
+#, c-format
+msgid "BFD %s internal error, aborting at %s line %d\n"
+msgstr "Internt BFD %s-fel, avbryter vid %s rad %d\n"
+
+#: bfd.c:709
+msgid "Please report this bug.\n"
+msgstr "Rapportera gärna detta fel.\n"
+
+#: bfdwin.c:202
+#, c-format
+msgid "not mapping: data=%lx mapped=%d\n"
+msgstr "mappar inte: data=%lx mappat=%d\n"
+
+#: bfdwin.c:205
+msgid "not mapping: env var not set\n"
+msgstr "mappar inte: miljövariabel är inte satt\n"
+
+#: binary.c:306
+#, c-format
+msgid "Warning: Writing section `%s' to huge (ie negative) file offset 0x%lx."
+msgstr "Varning: Skrivning av sektionen \"%s\" till enormt (dvs negativt) avlägsen byte 0x%lx."
+
+# src/menus.c:341
+#: coff-a29k.c:120
+msgid "Missing IHCONST"
+msgstr "IHCONST saknas"
+
+# src/menus.c:341
+#: coff-a29k.c:181
+msgid "Missing IHIHALF"
+msgstr "IHIHALF saknas"
+
+#: coff-a29k.c:213 coff-or32.c:236
+msgid "Unrecognized reloc"
+msgstr "Okänd omlokalisering"
+
+#: coff-a29k.c:409
+msgid "missing IHCONST reloc"
+msgstr "IHCONST-omlokalisering saknas"
+
+#: coff-a29k.c:499
+msgid "missing IHIHALF reloc"
+msgstr "IHIHALF-omlokalisering saknas"
+
+#: coff-alpha.c:884 coff-alpha.c:921 coff-alpha.c:1992 coff-mips.c:1397
+msgid "GP relative relocation used when GP not defined"
+msgstr "GP-relativ omlokalisering användes då GP inte är definierad"
+
+#: coff-alpha.c:1488
+msgid "using multiple gp values"
+msgstr "använder flera gp-värden"
+
+#: coff-arm.c:1066 elf32-arm.h:294
+#, c-format
+msgid "%s: unable to find THUMB glue '%s' for `%s'"
+msgstr "%s: kunde inte hitta THUMB-klistret \"%s\" till \"%s\""
+
+#: coff-arm.c:1096 elf32-arm.h:329
+#, c-format
+msgid "%s: unable to find ARM glue '%s' for `%s'"
+msgstr "%s: kunde inte hitta ARM-klistret \"%s\" till \"%s\""
+
+#: coff-arm.c:1394 coff-arm.c:1489 elf32-arm.h:892 elf32-arm.h:999
+#, c-format
+msgid "%s(%s): warning: interworking not enabled."
+msgstr "%s(%s): varning: samverkande är inte aktiverat."
+
+#: coff-arm.c:1398 elf32-arm.h:1002
+#, c-format
+msgid " first occurrence: %s: arm call to thumb"
+msgstr " första förekomst: %s: arm-anrop till thumb"
+
+#: coff-arm.c:1493 elf32-arm.h:895
+#, c-format
+msgid " first occurrence: %s: thumb call to arm"
+msgstr " första förekomst: %s: thumb-anrop till arm"
+
+#: coff-arm.c:1496
+msgid " consider relinking with --support-old-code enabled"
+msgstr " överväg omlänkning med --support-old-code aktiverat"
+
+#: coff-arm.c:1788 coff-tic80.c:687 cofflink.c:3038
+#, c-format
+msgid "%s: bad reloc address 0x%lx in section `%s'"
+msgstr "%s: felaktig omlokaliseringsadress 0x%lx i sektionen \"%s\""
+
+#: coff-arm.c:2132
+#, c-format
+msgid "%s: illegal symbol index in reloc: %d"
+msgstr "%s: otillåtet symbolindex i omlokalisering: %d"
+
+#: coff-arm.c:2265
+#, c-format
+msgid "ERROR: %s is compiled for APCS-%d, whereas %s is compiled for APCS-%d"
+msgstr "FEL: %s kompilerad för APCS-%d, medan %s är kompilerad för APCS-%d"
+
+#: coff-arm.c:2280 elf32-arm.h:2328
+#, c-format
+msgid "ERROR: %s passes floats in float registers, whereas %s passes them in integer registers"
+msgstr "FEL: %s skickar flyttal i flyttalsregister, medan %s skickar dem i heltalsregister"
+
+#: coff-arm.c:2283 elf32-arm.h:2333
+#, c-format
+msgid "ERROR: %s passes floats in integer registers, whereas %s passes them in float registers"
+msgstr "FEL: %s skickar flyttal i heltalsregister, medan %s skickar dem i flyttalsregister"
+
+#: coff-arm.c:2298
+#, c-format
+msgid "ERROR: %s is compiled as position independent code, whereas target %s is absolute position"
+msgstr "FEL: %s är kompilerad som positionsoberoende kod, medan målet %s har absolut position"
+
+#: coff-arm.c:2301
+#, c-format
+msgid "ERROR: %s is compiled as absolute position code, whereas target %s is position independent"
+msgstr "FEL: %s är kompilerad som kod med absolut position, medan målet %s är positionsoberoende"
+
+#: coff-arm.c:2330 elf32-arm.h:2405
+#, c-format
+msgid "Warning: %s supports interworking, whereas %s does not"
+msgstr "Varning: %s stöder samverkande, medan %s däremot inte gör det"
+
+#: coff-arm.c:2333 elf32-arm.h:2412
+#, c-format
+msgid "Warning: %s does not support interworking, whereas %s does"
+msgstr "Varning: %s stöder inte samverkande, medan %s däremot gör det"
+
+#: coff-arm.c:2360
+#, c-format
+msgid "private flags = %x:"
+msgstr "privata flaggor = %x:"
+
+#: coff-arm.c:2368 elf32-arm.h:2467
+msgid " [floats passed in float registers]"
+msgstr " [flyttal skickade i flyttalsregister]"
+
+#: coff-arm.c:2370
+msgid " [floats passed in integer registers]"
+msgstr " [flyttal skickade i heltalsregister]"
+
+#: coff-arm.c:2373 elf32-arm.h:2470
+msgid " [position independent]"
+msgstr " [positionsoberoende]"
+
+#: coff-arm.c:2375
+msgid " [absolute position]"
+msgstr " [absolut position]"
+
+#: coff-arm.c:2379
+msgid " [interworking flag not initialised]"
+msgstr " [samverkandeflagga är inte initierad]"
+
+#: coff-arm.c:2381
+msgid " [interworking supported]"
+msgstr " [samverkan stöds]"
+
+#: coff-arm.c:2383
+msgid " [interworking not supported]"
+msgstr " [samverkan stöds inte]"
+
+#: coff-arm.c:2431 elf32-arm.h:2150
+#, c-format
+msgid "Warning: Not setting interworking flag of %s since it has already been specified as non-interworking"
+msgstr "Varning: Ställer inte in samverkansflaggan för %s eftersom den redan har angivits som inte samverkande"
+
+#: coff-arm.c:2435 elf32-arm.h:2154
+#, c-format
+msgid "Warning: Clearing the interworking flag of %s due to outside request"
+msgstr "Varning: Stänger av samverkansflaggan för %s på grund av begäran utifrån"
+
+#: coff-h8300.c:1096
+#, c-format
+msgid "cannot handle R_MEM_INDIRECT reloc when using %s output"
+msgstr "kan inte hantera R_MEM_INDIRECT-omlokalisering vid användning av %s-utdata"
+
+#: coff-i960.c:137 coff-i960.c:486
+msgid "uncertain calling convention for non-COFF symbol"
+msgstr "osäker anropskonvention för icke-COFF-symbol"
+
+#: coff-m68k.c:482 coff-mips.c:2394 elf32-m68k.c:2193 elf32-mips.c:1783
+msgid "unsupported reloc type"
+msgstr "omlokaliseringstypen stöds inte"
+
+#: coff-mips.c:839 elf32-mips.c:1088 elf64-mips.c:1590 elfn32-mips.c:1554
+msgid "GP relative relocation when _gp not defined"
+msgstr "GP-relativ omlokalisering då _gp inte var definierat"
+
+#. No other sections should appear in -membedded-pic
+#. code.
+#: coff-mips.c:2431
+msgid "reloc against unsupported section"
+msgstr "omlokalisering mot sektion som inte stöds"
+
+#: coff-mips.c:2439
+msgid "reloc not properly aligned"
+msgstr "omlokalisering inte på jämn gräns"
+
+#: coff-rs6000.c:2790
+#, c-format
+msgid "%s: unsupported relocation type 0x%02x"
+msgstr "%s: omlokaliseringstypen 0x%02x stöds inte"
+
+#: coff-rs6000.c:2883
+#, c-format
+msgid "%s: TOC reloc at 0x%x to symbol `%s' with no TOC entry"
+msgstr "%s: TOC-omlokalisering vid 0x%x till symbolen \"%s\" utan någon TOC-post"
+
+#: coff-rs6000.c:3616 coff64-rs6000.c:2109
+#, c-format
+msgid "%s: symbol `%s' has unrecognized smclas %d"
+msgstr "%s: symbolen \"%s\" har okänd smclas %d"
+
+#: coff-tic4x.c:170 coff-tic54x.c:288 coff-tic80.c:450
+#, c-format
+msgid "Unrecognized reloc type 0x%x"
+msgstr "Okänd omlokaliseringstyp 0x%x"
+
+#: coff-tic4x.c:218 coff-tic54x.c:373 coffcode.h:5045
+#, c-format
+msgid "%s: warning: illegal symbol index %ld in relocs"
+msgstr "%s: varning: otillåtet symbolindex %ld i omlokaliseringarna"
+
+#: coff-w65.c:364
+#, c-format
+msgid "ignoring reloc %s\n"
+msgstr "ignorerar omlokalisering %s\n"
+
+#: coffcode.h:1108
+#, c-format
+msgid "%s (%s): Section flag %s (0x%x) ignored"
+msgstr "%s (%s): Sektionsflaggan %s (0x%x) ignorerades"
+
+#: coffcode.h:2214
+#, c-format
+msgid "Unrecognized TI COFF target id '0x%x'"
+msgstr "Okänt TI COFF-målid \"0x%x\""
+
+#: coffcode.h:4437
+#, c-format
+msgid "%s: warning: illegal symbol index %ld in line numbers"
+msgstr "%s: varning: otillåtet symbolindex %ld i radnummer"
+
+#: coffcode.h:4451
+#, c-format
+msgid "%s: warning: duplicate line number information for `%s'"
+msgstr "%s: varning: dubbel radnummersinformation för \"%s\""
+
+#: coffcode.h:4805
+#, c-format
+msgid "%s: Unrecognized storage class %d for %s symbol `%s'"
+msgstr "%s: Okänd lagringsklass %d för %s-symbolen \"%s\""
+
+#: coffcode.h:4938
+#, c-format
+msgid "warning: %s: local symbol `%s' has no section"
+msgstr "varning: %s: lokala symbolen \"%s\" har ingen sektion"
+
+#: coffcode.h:5083
+#, c-format
+msgid "%s: illegal relocation type %d at address 0x%lx"
+msgstr "%s: otillåten omlokaliseringstyp %d på adress 0x%lx"
+
+#: coffgen.c:1666
+#, c-format
+msgid "%s: bad string table size %lu"
+msgstr "%s: felaktig strängtabellstorlek %lu"
+
+#: cofflink.c:538 elflink.h:1276
+#, c-format
+msgid "Warning: type of symbol `%s' changed from %d to %d in %s"
+msgstr "Varning: typen på symbolen \"%s\" ändrades från %d till %d i %s"
+
+#: cofflink.c:2328
+#, c-format
+msgid "%s: relocs in section `%s', but it has no contents"
+msgstr "%s: omlokaliseringar i sektionen \"%s\", men den har inget innehåll"
+
+#: cofflink.c:2671 coffswap.h:890
+#, c-format
+msgid "%s: %s: reloc overflow: 0x%lx > 0xffff"
+msgstr "%s: %s: omlokalisering ger överspill: 0x%lx > 0xffff"
+
+#: cofflink.c:2680 coffswap.h:876
+#, c-format
+msgid "%s: warning: %s: line number overflow: 0x%lx > 0xffff"
+msgstr "%s: varning: %s: radnummer ger överspill: 0x%lx > 0xffff"
+
+#: cpu-arm.c:196 cpu-arm.c:206
+#, c-format
+msgid "ERROR: %s is compiled for the EP9312, whereas %s is compiled for XScale"
+msgstr "FEL: %s kompilerad för EP9312, medan %s är kompilerad för XScale"
+
+#: cpu-arm.c:344
+#, c-format
+msgid "warning: unable to update contents of %s section in %s"
+msgstr "varning: kan inte uppdatera innehållet i %s-sektion i %s"
+
+#: dwarf2.c:380
+msgid "Dwarf Error: Can't find .debug_str section."
+msgstr "Dwarf-fel: Kan inte hitta sektionen .debug_str."
+
+#: dwarf2.c:397
+#, c-format
+msgid "Dwarf Error: DW_FORM_strp offset (%lu) greater than or equal to .debug_str size (%lu)."
+msgstr "Dwarf-fel: DW_FORM_strp-avståndet (%lu) större än eller lika med storleken på .debug_str (%lu)."
+
+#: dwarf2.c:541
+msgid "Dwarf Error: Can't find .debug_abbrev section."
+msgstr "Dwarf-fel: Kan inte hitta sektionen .debug_abbrev."
+
+#: dwarf2.c:556
+#, c-format
+msgid "Dwarf Error: Abbrev offset (%lu) greater than or equal to .debug_abbrev size (%lu)."
+msgstr "Dwarf-fel: Förkortningsavståndet (%lu) större än eller lika med storleken .debug_abbrev (%lu)."
+
+#: dwarf2.c:756
+#, c-format
+msgid "Dwarf Error: Invalid or unhandled FORM value: %u."
+msgstr "Dwarf-fel: Ogiltig eller ohanterat FORM-värde: %u."
+
+#: dwarf2.c:933
+msgid "Dwarf Error: mangled line number section (bad file number)."
+msgstr "Dwarf-fel: trasig radnummerssektion (felaktigt filnummer)."
+
+#: dwarf2.c:1032
+msgid "Dwarf Error: Can't find .debug_line section."
+msgstr "Dwarf-fel: Kan inte hitta sektionen .debug_line."
+
+#: dwarf2.c:1049
+#, c-format
+msgid "Dwarf Error: Line offset (%lu) greater than or equal to .debug_line size (%lu)."
+msgstr "Dwarf-fel: Radavståndet (%lu) större än eller lika med storleken .debug_line (%lu)."
+
+#: dwarf2.c:1255
+msgid "Dwarf Error: mangled line number section."
+msgstr "Dwarf-fel: trasig radnummerssektion."
+
+#: dwarf2.c:1470 dwarf2.c:1620
+#, c-format
+msgid "Dwarf Error: Could not find abbrev number %u."
+msgstr "Dwarf-fel: Kunde inte hitta förkortningsnumret %u."
+
+#: dwarf2.c:1581
+#, c-format
+msgid "Dwarf Error: found dwarf version '%u', this reader only handles version 2 information."
+msgstr "Dwarf-fel: hittade dwarf version \"%u\", denna läsare hanterar endast information från version 2."
+
+#: dwarf2.c:1588
+#, c-format
+msgid "Dwarf Error: found address size '%u', this reader can not handle sizes greater than '%u'."
+msgstr "Dwarf-fel: hittade adresstorleken \"%u\", denna läsare kan inte hantera storlekar större än \"%u\"."
+
+#: dwarf2.c:1611
+#, c-format
+msgid "Dwarf Error: Bad abbrev number: %u."
+msgstr "Dwarf-fel: Felaktigt förkortningsnummer: %u."
+
+#: ecoff.c:1339
+#, c-format
+msgid "Unknown basic type %d"
+msgstr "Okänd grundtyp %d"
+
+#: ecoff.c:1599
+#, c-format
+msgid ""
+"\n"
+" End+1 symbol: %ld"
+msgstr ""
+"\n"
+" Symbol slut+1: %ld"
+
+#: ecoff.c:1606 ecoff.c:1609
+#, c-format
+msgid ""
+"\n"
+" First symbol: %ld"
+msgstr ""
+"\n"
+" Första symbolen: %ld"
+
+#: ecoff.c:1621
+#, c-format
+msgid ""
+"\n"
+" End+1 symbol: %-7ld Type: %s"
+msgstr ""
+"\n"
+" Symbol slut+1: %-7ld Typ: %s"
+
+#: ecoff.c:1628
+#, c-format
+msgid ""
+"\n"
+" Local symbol: %ld"
+msgstr ""
+"\n"
+" Lokal symbol: %ld"
+
+#: ecoff.c:1636
+#, c-format
+msgid ""
+"\n"
+" struct; End+1 symbol: %ld"
+msgstr ""
+"\n"
+" struct; symbol slut+1: %ld"
+
+#: ecoff.c:1641
+#, c-format
+msgid ""
+"\n"
+" union; End+1 symbol: %ld"
+msgstr ""
+"\n"
+" union; symbol slut+1: %ld"
+
+#: ecoff.c:1646
+#, c-format
+msgid ""
+"\n"
+" enum; End+1 symbol: %ld"
+msgstr ""
+"\n"
+" enum; symbol slut+1: %ld"
+
+#: ecoff.c:1652
+#, c-format
+msgid ""
+"\n"
+" Type: %s"
+msgstr ""
+"\n"
+" Typ: %s"
+
+#: elf-hppa.h:1458 elf-hppa.h:1491 elf-m10300.c:1628 elf64-sh64.c:1704
+#, c-format
+msgid "%s: warning: unresolvable relocation against symbol `%s' from %s section"
+msgstr "%s: varning: olöslig omlokalisering mot symbolen \"%s\" från sektionen %s"
+
+#: elf-m10200.c:442 elf-m10300.c:1695 elf32-arm.h:2088 elf32-avr.c:812
+#: elf32-cris.c:1390 elf32-d10v.c:570 elf32-fr30.c:634 elf32-frv.c:815
+#: elf32-h8300.c:528 elf32-i860.c:1028 elf32-ip2k.c:1586 elf32-iq2000.c:699
+#: elf32-m32r.c:1283 elf32-m68hc1x.c:1305 elf32-msp430.c:510
+#: elf32-openrisc.c:436 elf32-v850.c:1777 elf32-xstormy16.c:976
+#: elf64-mmix.c:1332
+msgid "internal error: out of range error"
+msgstr "internt fel: utanför intervallet"
+
+#: elf-m10200.c:446 elf-m10300.c:1699 elf32-arm.h:2092 elf32-avr.c:816
+#: elf32-cris.c:1394 elf32-d10v.c:574 elf32-fr30.c:638 elf32-frv.c:819
+#: elf32-h8300.c:532 elf32-i860.c:1032 elf32-iq2000.c:703 elf32-m32r.c:1287
+#: elf32-m68hc1x.c:1309 elf32-msp430.c:514 elf32-openrisc.c:440
+#: elf32-v850.c:1781 elf32-xstormy16.c:980 elf64-mmix.c:1336 elfxx-mips.c:6452
+msgid "internal error: unsupported relocation error"
+msgstr "internt fel: omlokaliseringen stöds inte"
+
+#: elf-m10200.c:450 elf-m10300.c:1703 elf32-arm.h:2096 elf32-d10v.c:578
+#: elf32-h8300.c:536 elf32-m32r.c:1291 elf32-m68hc1x.c:1313
+msgid "internal error: dangerous error"
+msgstr "internt fel: farligt fel"
+
+#: elf-m10200.c:454 elf-m10300.c:1707 elf32-arm.h:2100 elf32-avr.c:824
+#: elf32-cris.c:1402 elf32-d10v.c:582 elf32-fr30.c:646 elf32-frv.c:827
+#: elf32-h8300.c:540 elf32-i860.c:1040 elf32-ip2k.c:1601 elf32-iq2000.c:711
+#: elf32-m32r.c:1295 elf32-m68hc1x.c:1317 elf32-msp430.c:522
+#: elf32-openrisc.c:448 elf32-v850.c:1801 elf32-xstormy16.c:988
+#: elf64-mmix.c:1344
+msgid "internal error: unknown error"
+msgstr "internt fel: okänt fel"
+
+#: elf.c:372
+#, c-format
+msgid "%s: invalid string offset %u >= %lu for section `%s'"
+msgstr "%s: ogiltigt strängavstånd %u >= %lu för sektionen \"%s\""
+
+#: elf.c:624
+#, c-format
+msgid "%s: invalid SHT_GROUP entry"
+msgstr "%s: ogiltig SHT_GROUP-post"
+
+#: elf.c:695
+#, c-format
+msgid "%s: no group info for section %s"
+msgstr "%s: ingen gruppinformation för sektionen %s"
+
+#: elf.c:1055
+msgid ""
+"\n"
+"Program Header:\n"
+msgstr ""
+"\n"
+"Programhuvud:\n"
+
+#: elf.c:1106
+msgid ""
+"\n"
+"Dynamic Section:\n"
+msgstr ""
+"\n"
+"Dynamisk sektion:\n"
+
+#: elf.c:1235
+msgid ""
+"\n"
+"Version definitions:\n"
+msgstr ""
+"\n"
+"Versionsdefinitioner:\n"
+
+#: elf.c:1258
+msgid ""
+"\n"
+"Version References:\n"
+msgstr ""
+"\n"
+"Versionsreferenser:\n"
+
+#: elf.c:1263
+#, c-format
+msgid " required from %s:\n"
+msgstr " krävs från %s:\n"
+
+#: elf.c:1944
+#, c-format
+msgid "%s: invalid link %lu for reloc section %s (index %u)"
+msgstr "%s: ogiltig länk %lu för omlokaliseringssektion %s (index %u)"
+
+#: elf.c:3686
+#, c-format
+msgid "%s: Not enough room for program headers (allocated %u, need %u)"
+msgstr "%s: Inte tillräckligt med utrymme för programhuvuden (allokerade %u, behöver %u)"
+
+#: elf.c:3791
+#, c-format
+msgid "%s: Not enough room for program headers, try linking with -N"
+msgstr "%s: Inte tillräckligt med utrymme för programhuvuden, försök att länka med -N"
+
+#: elf.c:3922
+#, c-format
+msgid "Error: First section in segment (%s) starts at 0x%x whereas the segment starts at 0x%x"
+msgstr "Fel: Första sektionen i segmentet (%s) börjar vid 0x%x medan segmentet börjar med 0x%x"
+
+#: elf.c:4242
+#, c-format
+msgid "%s: warning: allocated section `%s' not in segment"
+msgstr "%s: varning: allokerad sektion \"%s\" inte i segment"
+
+#: elf.c:4566
+#, c-format
+msgid "%s: symbol `%s' required but not present"
+msgstr "%s: symbolen \"%s\" krävs men finns inte med"
+
+#: elf.c:4854
+#, c-format
+msgid "%s: warning: Empty loadable segment detected, is this intentional ?\n"
+msgstr "%s: varning: Tomt inläsningsbart segment upptäckt, är detta meningen?\n"
+
+#: elf.c:5485
+#, c-format
+msgid "Unable to find equivalent output section for symbol '%s' from section '%s'"
+msgstr "Kan inte hitta ekvivalent utdatasektion för symbolen \"%s\" från sektionen \"%s\""
+
+#: elf.c:6298
+#, c-format
+msgid "%s: unsupported relocation type %s"
+msgstr "%s: omlokaliseringstypen %s stöds inte"
+
+#: elf32-arm.h:1228
+#, c-format
+msgid "%s: Warning: Arm BLX instruction targets Arm function '%s'."
+msgstr "%s: Varning: Arm BLX-instruktion använder Arm-funktionen \"%s\" som mål."
+
+#: elf32-arm.h:1424
+#, c-format
+msgid "%s: Warning: Thumb BLX instruction targets thumb function '%s'."
+msgstr "%s: Varning: Thumb BLX-instruktionen använder thumb-funktionen \"%s\" som mål."
+
+#: elf32-arm.h:1918 elf32-sh.c:4706 elf64-sh64.c:1613
+#, c-format
+msgid "%s(%s+0x%lx): %s relocation against SEC_MERGE section"
+msgstr "%s(%s+0x%lx): %s omlokalisering mot SEC_MERGE-sektion"
+
+#: elf32-arm.h:2012
+#, c-format
+msgid "%s: warning: unresolvable relocation %d against symbol `%s' from %s section"
+msgstr "%s: varning: olöslig omlokalisering %d mot symbolen \"%s\" från sektionen %s"
+
+#: elf32-arm.h:2202
+#, c-format
+msgid "Warning: Clearing the interworking flag of %s because non-interworking code in %s has been linked with it"
+msgstr "Varning: Stänger av samverkandeflaggan i %s eftersom icke-samverkande kod i %s har länkats med det"
+
+#: elf32-arm.h:2302
+#, c-format
+msgid "ERROR: %s is compiled for EABI version %d, whereas %s is compiled for version %d"
+msgstr "FEL: %s är kompilerad för EABI version %d, medan %s är kompilerad för version %d"
+
+#: elf32-arm.h:2316
+#, c-format
+msgid "ERROR: %s is compiled for APCS-%d, whereas target %s uses APCS-%d"
+msgstr "FEL: %s är kompilerad för APCS-%d, medan målet %s använder APCS-%d"
+
+#: elf32-arm.h:2344
+#, c-format
+msgid "ERROR: %s uses VFP instructions, whereas %s does not"
+msgstr "FEL: %s använder VFP-instruktioner, men det gör inte %s"
+
+#: elf32-arm.h:2349
+#, c-format
+msgid "ERROR: %s uses FPA instructions, whereas %s does not"
+msgstr "FEL: %s använder FPA-instruktioner, men det gör inte %s"
+
+#: elf32-arm.h:2360 elf32-arm.h:2365
+#, c-format
+msgid "ERROR: %s uses Maverick instructions, whereas %s does not"
+msgstr "FEL: %s använder Maverick-instruktioner, men det gör inte %s"
+
+#: elf32-arm.h:2385
+#, c-format
+msgid "ERROR: %s uses software FP, whereas %s uses hardware FP"
+msgstr "FEL: %s använder programvaruflyttal, medan %s använder hårdvaruflyttal"
+
+#: elf32-arm.h:2390
+#, c-format
+msgid "ERROR: %s uses hardware FP, whereas %s uses software FP"
+msgstr "FEL: %s använder hårdvaruflyttal, medan %s använder programvaruflyttal"
+
+#. Ignore init flag - it may not be set, despite the flags field
+#. containing valid data.
+#: elf32-arm.h:2443 elf32-cris.c:2975 elf32-m68hc1x.c:1459 elf32-m68k.c:397
+#: elf32-vax.c:546 elfxx-mips.c:9238
+#, c-format
+msgid "private flags = %lx:"
+msgstr "privata flaggor = %lx:"
+
+#: elf32-arm.h:2452
+msgid " [interworking enabled]"
+msgstr " [samverkande är aktiverat]"
+
+#: elf32-arm.h:2460
+msgid " [VFP float format]"
+msgstr " [VFP-flyttalsformat]"
+
+#: elf32-arm.h:2462
+msgid " [Maverick float format]"
+msgstr " [Maverick-flyttalsformat]"
+
+#: elf32-arm.h:2464
+msgid " [FPA float format]"
+msgstr " [FPA-flyttalsformat]"
+
+#: elf32-arm.h:2473
+msgid " [new ABI]"
+msgstr " [nytt ABI]"
+
+#: elf32-arm.h:2476
+msgid " [old ABI]"
+msgstr " [gammalt ABI]"
+
+#: elf32-arm.h:2479
+msgid " [software FP]"
+msgstr " [programvaru-FP]"
+
+#: elf32-arm.h:2488
+msgid " [Version1 EABI]"
+msgstr " [Version1 EABI]"
+
+#: elf32-arm.h:2491 elf32-arm.h:2502
+msgid " [sorted symbol table]"
+msgstr " [sorterad symboltabell]"
+
+#: elf32-arm.h:2493 elf32-arm.h:2504
+msgid " [unsorted symbol table]"
+msgstr " [osorterad symboltabell]"
+
+#: elf32-arm.h:2499
+msgid " [Version2 EABI]"
+msgstr " [Version2 EABI]"
+
+#: elf32-arm.h:2507
+msgid " [dynamic symbols use segment index]"
+msgstr " [dynamiska symboler använder segmentindex]"
+
+#: elf32-arm.h:2510
+msgid " [mapping symbols precede others]"
+msgstr " [mappsymboler har företräde före andra]"
+
+#: elf32-arm.h:2517
+msgid " <EABI version unrecognised>"
+msgstr " <EABI-version känns inte igen>"
+
+#: elf32-arm.h:2524
+msgid " [relocatable executable]"
+msgstr " [omlokaliseringsbar körbar fil]"
+
+#: elf32-arm.h:2527
+msgid " [has entry point]"
+msgstr " [har startpunkt]"
+
+#: elf32-arm.h:2532
+msgid "<Unrecognised flag bits set>"
+msgstr "<Okända flaggbitar satta>"
+
+#: elf32-avr.c:820 elf32-cris.c:1398 elf32-fr30.c:642 elf32-frv.c:823
+#: elf32-i860.c:1036 elf32-ip2k.c:1597 elf32-iq2000.c:707 elf32-msp430.c:518
+#: elf32-openrisc.c:444 elf32-v850.c:1785 elf32-xstormy16.c:984
+#: elf64-mmix.c:1340
+msgid "internal error: dangerous relocation"
+msgstr "internt fel: farlig omlokalisering"
+
+#: elf32-cris.c:931
+#, c-format
+msgid "%s: unresolvable relocation %s against symbol `%s' from %s section"
+msgstr "%s: olöslig omlokalisering %s mot symbolen \"%s\" från sektionen %s"
+
+#: elf32-cris.c:993
+#, c-format
+msgid "%s: No PLT nor GOT for relocation %s against symbol `%s' from %s section"
+msgstr "%s: Varken någon PLT eller GOT för omlokalisering %s mot symbolen \"%s\" från sektionen %s"
+
+#: elf32-cris.c:996 elf32-cris.c:1122
+msgid "[whose name is lost]"
+msgstr "[vars namn tappats bort]"
+
+#: elf32-cris.c:1111
+#, c-format
+msgid "%s: relocation %s with non-zero addend %d against local symbol from %s section"
+msgstr "%s: omlokalisering %s med icke-tomt addendum %d mot lokal symbol från sektionen %s"
+
+#: elf32-cris.c:1118
+#, c-format
+msgid "%s: relocation %s with non-zero addend %d against symbol `%s' from %s section"
+msgstr "%s: omlokalisering %s med icke-tomt addendum %d mot symbolen \"%s\" från sektionen %s"
+
+#: elf32-cris.c:1143
+#, c-format
+msgid "%s: relocation %s is not allowed for global symbol: `%s' from %s section"
+msgstr "%s: omlokaliseringen %s är inte tillåten för global symbol: \"%s\" från sektionen %s"
+
+#: elf32-cris.c:1158
+#, c-format
+msgid "%s: relocation %s in section %s with no GOT created"
+msgstr "%s: omlokalisering %s i sektionen %s utan GOT skapad"
+
+#: elf32-cris.c:1277
+#, c-format
+msgid "%s: Internal inconsistency; no relocation section %s"
+msgstr "%s: Intern inkonsistens; ingen omlokaliseringssektion %s"
+
+#: elf32-cris.c:2500
+#, c-format
+msgid ""
+"%s, section %s:\n"
+" relocation %s should not be used in a shared object; recompile with -fPIC"
+msgstr ""
+"%s, sektion %s:\n"
+" omlokaliseringen %s bör inte användas i ett delat objekt; kompilera om med -fPIC"
+
+#: elf32-cris.c:2978
+msgid " [symbols have a _ prefix]"
+msgstr " [symboler har ett _-prefix]"
+
+#: elf32-cris.c:3017
+#, c-format
+msgid "%s: uses _-prefixed symbols, but writing file with non-prefixed symbols"
+msgstr "%s: använder symboler med _-prefix, men skriver fil med symboler utan prefix"
+
+#: elf32-cris.c:3018
+#, c-format
+msgid "%s: uses non-prefixed symbols, but writing file with _-prefixed symbols"
+msgstr "%s: använder symboler utan prefix, men skriver fil med symboler med _-prefix"
+
+#: elf32-frv.c:1223
+#, c-format
+msgid "%s: compiled with %s and linked with modules that use non-pic relocations"
+msgstr "%s: kompilerad med %s och länkad med moduler som använder icke-pic-omlokalisering"
+
+#: elf32-frv.c:1273 elf32-iq2000.c:895
+#, c-format
+msgid "%s: compiled with %s and linked with modules compiled with %s"
+msgstr "%s: kompilerad med %s och länkad med moduler som kompilerats med %s"
+
+#: elf32-frv.c:1285
+#, c-format
+msgid "%s: uses different unknown e_flags (0x%lx) fields than previous modules (0x%lx)"
+msgstr "%s: använder andra okända e_flags-fält (0x%lx) än tidigare moduler (0x%lx)"
+
+#: elf32-frv.c:1321 elf32-iq2000.c:933
+#, c-format
+msgid "private flags = 0x%lx:"
+msgstr "privata flaggor = 0x%lx:"
+
+#: elf32-gen.c:83 elf64-gen.c:82
+#, c-format
+msgid "%s: Relocations in generic ELF (EM: %d)"
+msgstr "%s: Omlokalisering i allmän ELF (EM: %d)"
+
+#: elf32-hppa.c:672 elf32-m68hc1x.c:176 elf64-ppc.c:3118
+#, c-format
+msgid "%s: cannot create stub entry %s"
+msgstr "%s: kan inte skapa stubbstarten %s"
+
+#: elf32-hppa.c:957 elf32-hppa.c:3538
+#, c-format
+msgid "%s(%s+0x%lx): cannot reach %s, recompile with -ffunction-sections"
+msgstr "%s(%s+0x%lx): kan inte nå %s, kompilera om med -ffunction-sections"
+
+#: elf32-hppa.c:1340 elf64-x86-64.c:672 elf64-x86-64.c:797
+#, c-format
+msgid "%s: relocation %s can not be used when making a shared object; recompile with -fPIC"
+msgstr "%s: omlokaliseringen %s kan inte användas då ett delat objekt skapas; kompilera om med -fPIC"
+
+#: elf32-hppa.c:1360
+#, c-format
+msgid "%s: relocation %s should not be used when making a shared object; recompile with -fPIC"
+msgstr "%s: omlokaliseringen %s bör inte användas då ett delat objekt skapas; kompilera om med -fPIC"
+
+#: elf32-hppa.c:1553
+#, c-format
+msgid "Could not find relocation section for %s"
+msgstr "Kunde inte hitta omlokaliseringssektion för %s"
+
+#: elf32-hppa.c:2828
+#, c-format
+msgid "%s: duplicate export stub %s"
+msgstr "%s: dubbel exportstubb %s"
+
+#: elf32-hppa.c:3416
+#, c-format
+msgid "%s(%s+0x%lx): fixing %s"
+msgstr "%s(%s+0x%lx): fixar %s"
+
+#: elf32-hppa.c:4039
+#, c-format
+msgid "%s(%s+0x%lx): cannot handle %s for %s"
+msgstr "%s(%s+0x%lx): kan inte hantera %s för %s"
+
+#: elf32-hppa.c:4357
+msgid ".got section not immediately after .plt section"
+msgstr ".got-sektionen följer inte omedelbart efter .plt-sektion"
+
+#: elf32-i386.c:326
+#, c-format
+msgid "%s: invalid relocation type %d"
+msgstr "%s: ogiltig omlokaliseringstyp %d"
+
+#: elf32-i386.c:841 elf32-s390.c:990 elf32-sparc.c:887 elf32-xtensa.c:637
+#: elf64-s390.c:943 elf64-x86-64.c:650
+#, c-format
+msgid "%s: bad symbol index: %d"
+msgstr "%s: felaktigt symbolindex: %d"
+
+#: elf32-i386.c:949 elf32-s390.c:1168 elf32-sh.c:6426 elf32-sparc.c:1011
+#: elf64-s390.c:1129
+#, c-format
+msgid "%s: `%s' accessed both as normal and thread local symbol"
+msgstr "%s: \"%s\" anropad både som lokal normal symbol och lokal trådsymbol"
+
+#: elf32-i386.c:1064 elf32-s390.c:1279 elf64-ppc.c:3929 elf64-s390.c:1243
+#: elf64-x86-64.c:886
+#, c-format
+msgid "%s: bad relocation section name `%s'"
+msgstr "%s: felaktig omlokaliseringssektionsnamn \"%s\""
+
+#: elf32-i386.c:2908 elf32-m68k.c:1757 elf32-s390.c:3022 elf32-sparc.c:2879
+#: elf32-xtensa.c:2193 elf64-s390.c:3018 elf64-sparc.c:2664
+#: elf64-x86-64.c:2452
+#, c-format
+msgid "%s(%s+0x%lx): unresolvable relocation against symbol `%s'"
+msgstr "%s(%s+0x%lx): olöslig omlokalisering mot symbolen \"%s\""
+
+#: elf32-i386.c:2947 elf32-m68k.c:1796 elf32-s390.c:3072 elf64-s390.c:3068
+#: elf64-x86-64.c:2490
+#, c-format
+msgid "%s(%s+0x%lx): reloc against `%s': error %d"
+msgstr "%s(%s+0x%lx): omlokalisering mot \"%s\": fel %d"
+
+#: elf32-ip2k.c:565 elf32-ip2k.c:571 elf32-ip2k.c:734 elf32-ip2k.c:740
+msgid "ip2k relaxer: switch table without complete matching relocation information."
+msgstr "ip2k-relaxerare: switchtabell utan helt matchande omlokaliseringsinformation."
+
+#: elf32-ip2k.c:588 elf32-ip2k.c:767
+msgid "ip2k relaxer: switch table header corrupt."
+msgstr "ip2k-relaxerare: switchtabellshuvud trasigt."
+
+#: elf32-ip2k.c:1395
+#, c-format
+msgid "ip2k linker: missing page instruction at 0x%08lx (dest = 0x%08lx)."
+msgstr "ip2k-länkare: sidinstruktion saknas vid 0x%08lx (dest = 0x%08lx)."
+
+#: elf32-ip2k.c:1409
+#, c-format
+msgid "ip2k linker: redundant page instruction at 0x%08lx (dest = 0x%08lx)."
+msgstr "ip2k-länkare: redundant sidinstruktion vid 0x%08lx (dest = 0x%08lx)."
+
+#. Only if it's not an unresolved symbol.
+#: elf32-ip2k.c:1593
+msgid "unsupported relocation between data/insn address spaces"
+msgstr "omlokalisering mellan data/-instruktionsadressutrymmen stöds inte"
+
+#: elf32-iq2000.c:907 elf32-m68hc1x.c:1431 elf32-ppc.c:2175 elf64-sparc.c:3072
+#: elfxx-mips.c:9195
+#, c-format
+msgid "%s: uses different e_flags (0x%lx) fields than previous modules (0x%lx)"
+msgstr "%s: använder andra e_flags-fält (0x%lx) än tidigare moduler (0x%lx)"
+
+#: elf32-m32r.c:930
+msgid "SDA relocation when _SDA_BASE_ not defined"
+msgstr "SDA-omlokalisering då _SDA_BASE_ inte är definierat"
+
+#: elf32-m32r.c:1018 elf64-alpha.c:4279 elf64-alpha.c:4407 elf32-ia64.c:3958
+#: elf64-ia64.c:3958
+#, c-format
+msgid "%s: unknown relocation type %d"
+msgstr "%s: okänd omlokaliseringstyp %d"
+
+#: elf32-m32r.c:1226
+#, c-format
+msgid "%s: The target (%s) of an %s relocation is in the wrong section (%s)"
+msgstr "%s: Målet (%s) för en %s-omlokalisering är i fel sektion (%s)"
+
+#: elf32-m32r.c:1952
+#, c-format
+msgid "%s: Instruction set mismatch with previous modules"
+msgstr "%s: Instruktionsuppsättning passar inte med tidigare moduler"
+
+#: elf32-m32r.c:1975
+#, c-format
+msgid "private flags = %lx"
+msgstr "privata flaggor = %lx"
+
+#: elf32-m32r.c:1980
+msgid ": m32r instructions"
+msgstr ": m32r-instruktioner"
+
+#: elf32-m32r.c:1981
+msgid ": m32rx instructions"
+msgstr ": m32rx-instruktioner"
+
+#: elf32-m68hc1x.c:1217
+#, c-format
+msgid "Reference to the far symbol `%s' using a wrong relocation may result in incorrect execution"
+msgstr "Referens till den avlägsna symbolen \"%s\" med hjälp av en felaktig omlokalisering kan resultera i felaktig exekvering"
+
+#: elf32-m68hc1x.c:1240
+#, c-format
+msgid "banked address [%lx:%04lx] (%lx) is not in the same bank as current banked address [%lx:%04lx] (%lx)"
+msgstr "bankad adress [%lx:%04lx] (%lx) är inte i samma bank som den aktuella bankade adressen [%lx:%04lx] (%lx)"
+
+#: elf32-m68hc1x.c:1259
+#, c-format
+msgid "reference to a banked address [%lx:%04lx] in the normal address space at %04lx"
+msgstr "referens till en bankad adress [%lx:%04lx] i det normala adressutrymmet vid %04lx"
+
+#: elf32-m68hc1x.c:1396
+#, c-format
+msgid "%s: linking files compiled for 16-bit integers (-mshort) and others for 32-bit integers"
+msgstr "%s: länkar filer kompilerade för 16-bitars heltal (-mshort) och andra för 32-bitars heltal"
+
+#: elf32-m68hc1x.c:1404
+#, c-format
+msgid "%s: linking files compiled for 32-bit double (-fshort-double) and others for 64-bit double"
+msgstr "%s: länkar filer kompilerade för 32-bitars dubbelprecisionsflyttal (-fshort-double) och andra för 64-bitars dubbelprecisionsflyttal"
+
+#: elf32-m68hc1x.c:1414
+#, c-format
+msgid "%s: linking files compiled for HCS12 with others compiled for HC12"
+msgstr "%s: länkar filer kompilerade för HCS12 med andra kompilerade för HC12"
+
+#: elf32-m68hc1x.c:1462
+msgid "[abi=32-bit int, "
+msgstr "[abi=32-bitars heltal, "
+
+#: elf32-m68hc1x.c:1464
+msgid "[abi=16-bit int, "
+msgstr "[abi=16-bitars heltal, "
+
+#: elf32-m68hc1x.c:1467
+msgid "64-bit double, "
+msgstr "64-bitars dubbelprecisionsflyttal, "
+
+#: elf32-m68hc1x.c:1469
+msgid "32-bit double, "
+msgstr "32-bitars dubbelprecisionsflyttal, "
+
+#: elf32-m68hc1x.c:1472
+msgid "cpu=HC11]"
+msgstr "cpu=HC11]"
+
+#: elf32-m68hc1x.c:1474
+msgid "cpu=HCS12]"
+msgstr "cpu=HCS12]"
+
+#: elf32-m68hc1x.c:1476
+msgid "cpu=HC12]"
+msgstr "cpu=HC12]"
+
+#: elf32-m68hc1x.c:1479
+msgid " [memory=bank-model]"
+msgstr " [memory=bank-modell]"
+
+#: elf32-m68hc1x.c:1481
+msgid " [memory=flat]"
+msgstr " [memory=platt]"
+
+#: elf32-m68k.c:400
+msgid " [cpu32]"
+msgstr " [cpu32]"
+
+#: elf32-m68k.c:403
+msgid " [m68000]"
+msgstr " [m68000]"
+
+#: elf32-mcore.c:353 elf32-mcore.c:456
+#, c-format
+msgid "%s: Relocation %s (%d) is not currently supported.\n"
+msgstr "%s: Omlokalisering %s (%d) stöds för närvarande inte.\n"
+
+#: elf32-mcore.c:441
+#, c-format
+msgid "%s: Unknown relocation type %d\n"
+msgstr "%s: Okänd omlokaliseringstyp %d\n"
+
+#: elf32-mips.c:1170 elf64-mips.c:1717 elfn32-mips.c:1664
+msgid "32bits gp relative relocation occurs for an external symbol"
+msgstr "32-bitars gp-relativ omlokalisering förekom för en extern symbol"
+
+#: elf32-mips.c:1314 elf64-mips.c:1830 elfn32-mips.c:1783
+#, c-format
+msgid "Linking mips16 objects into %s format is not supported"
+msgstr "Länkning av mips16-objekt till %s-format stöds inte"
+
+#: elf32-ppc.c:2056
+#, c-format
+msgid "generic linker can't handle %s"
+msgstr "allmän länkare kan inte hantera %s"
+
+#: elf32-ppc.c:2138
+#, c-format
+msgid "%s: compiled with -mrelocatable and linked with modules compiled normally"
+msgstr "%s: kompilerad med -mrelocatable och länkad med moduler som kompilerats normalt"
+
+#: elf32-ppc.c:2147
+#, c-format
+msgid "%s: compiled normally and linked with modules compiled with -mrelocatable"
+msgstr "%s: kompilerad normalt och länkad med moduler som kompilerats med -mrelocatable"
+
+#: elf32-ppc.c:3413
+#, c-format
+msgid "%s: relocation %s cannot be used when making a shared object"
+msgstr "%s: omlokaliseringen %s kan inte användas då ett delat objekt skapas"
+
+#. It does not make sense to have a procedure linkage
+#. table entry for a local symbol.
+#: elf32-ppc.c:3619
+#, c-format
+msgid "%s(%s+0x%lx): %s reloc against local symbol"
+msgstr "%s(%s+0x%lx): %s-omlokalisering mot lokal symbol"
+
+#: elf32-ppc.c:4862 elf64-ppc.c:7789
+#, c-format
+msgid "%s: unknown relocation type %d for symbol %s"
+msgstr "%s: okänd omlokaliseringstyp %d för symbolen %s"
+
+#: elf32-ppc.c:5113
+#, c-format
+msgid "%s(%s+0x%lx): non-zero addend on %s reloc against `%s'"
+msgstr "%s(%s+0x%lx): icke-tomt addendum på %s-omlokalisering mot \"%s\""
+
+#: elf32-ppc.c:5399 elf32-ppc.c:5425 elf32-ppc.c:5484
+#, c-format
+msgid "%s: the target (%s) of a %s relocation is in the wrong output section (%s)"
+msgstr "%s: målet (%s) för en %s-omlokalisering är i fel utdatasektion (%s)"
+
+#: elf32-ppc.c:5539
+#, c-format
+msgid "%s: relocation %s is not yet supported for symbol %s."
+msgstr "%s: omlokaliseringen %s stöds inte än för symbolen %s."
+
+#: elf32-ppc.c:5594 elf64-ppc.c:8461
+#, c-format
+msgid "%s(%s+0x%lx): unresolvable %s relocation against symbol `%s'"
+msgstr "%s(%s+0x%lx): olöslig %s-omlokalisering mot symbolen \"%s\""
+
+#: elf32-ppc.c:5644 elf64-ppc.c:8507
+#, c-format
+msgid "%s(%s+0x%lx): %s reloc against `%s': error %d"
+msgstr "%s(%s+0x%lx): %s-omlokalisering mot \"%s\": fel %d"
+
+#: elf32-ppc.c:5888
+#, c-format
+msgid "corrupt or empty %s section in %s"
+msgstr "trasig eller tom %s-sektion i %s"
+
+#: elf32-ppc.c:5895
+#, c-format
+msgid "unable to read in %s section from %s"
+msgstr "kan inte läsa in %s-sektion från %s"
+
+#: elf32-ppc.c:5901
+#, c-format
+msgid "corrupt %s section in %s"
+msgstr "trasig %s-sektion i %s"
+
+#: elf32-ppc.c:5944
+#, c-format
+msgid "warning: unable to set size of %s section in %s"
+msgstr "varning: kan inte ställa in storleken för sektionen %s i %s"
+
+#: elf32-ppc.c:5994
+msgid "failed to allocate space for new APUinfo section."
+msgstr "misslyckades med att allokera utrymme för ny APUinfo-sektion."
+
+#: elf32-ppc.c:6013
+msgid "failed to compute new APUinfo section."
+msgstr "misslyckades med att beräkna ny APUinfo-sektion."
+
+#: elf32-ppc.c:6016
+msgid "failed to install new APUinfo section."
+msgstr "misslyckades med att installera ny APUinfo-sektion."
+
+#: elf32-s390.c:2256 elf64-s390.c:2226
+#, c-format
+msgid "%s(%s+0x%lx): invalid instruction for TLS relocation %s"
+msgstr "%s(%s+0x%lx): ogiltig instruktion för TLS-omlokalisering %s"
+
+#: elf32-sh.c:2103
+#, c-format
+msgid "%s: 0x%lx: warning: bad R_SH_USES offset"
+msgstr "%s: 0x%lx: varning: felaktigt R_SH_USES-avstånd"
+
+#: elf32-sh.c:2115
+#, c-format
+msgid "%s: 0x%lx: warning: R_SH_USES points to unrecognized insn 0x%x"
+msgstr "%s: 0x%lx: varning: R_SH_USES pekar till okänd instruktion 0x%x"
+
+#: elf32-sh.c:2132
+#, c-format
+msgid "%s: 0x%lx: warning: bad R_SH_USES load offset"
+msgstr "%s: 0x%lx: varning: felaktigt R_SH_USES-inläsningsavstånd"
+
+#: elf32-sh.c:2147
+#, c-format
+msgid "%s: 0x%lx: warning: could not find expected reloc"
+msgstr "%s: 0x%lx: varning: kunde inte hitta förväntad omlokalisering"
+
+#: elf32-sh.c:2175
+#, c-format
+msgid "%s: 0x%lx: warning: symbol in unexpected section"
+msgstr "%s: 0x%lx: varning: symbol i oväntad sektion"
+
+#: elf32-sh.c:2300
+#, c-format
+msgid "%s: 0x%lx: warning: could not find expected COUNT reloc"
+msgstr "%s: 0x%lx: varning: kunde inte hitta förväntad COUNT-omlokalisering"
+
+#: elf32-sh.c:2309
+#, c-format
+msgid "%s: 0x%lx: warning: bad count"
+msgstr "%s: 0x%lx: varning: felaktigt antal"
+
+#: elf32-sh.c:2712 elf32-sh.c:3088
+#, c-format
+msgid "%s: 0x%lx: fatal: reloc overflow while relaxing"
+msgstr "%s: 0x%lx: ödesdigert: omlokalisering ger överspill vid förenklingen"
+
+#: elf32-sh.c:4654 elf64-sh64.c:1585
+msgid "Unexpected STO_SH5_ISA32 on local symbol is not handled"
+msgstr "Oväntat STO_SH5_ISA32 på lokal symbol hanteras inte"
+
+#: elf32-sh.c:4809
+#, c-format
+msgid "%s: unresolvable relocation against symbol `%s' from %s section"
+msgstr "%s: olöslig omlokalisering mot symbolen \"%s\" från sektionen %s"
+
+#: elf32-sh.c:4881
+#, c-format
+msgid "%s: 0x%lx: fatal: unaligned branch target for relax-support relocation"
+msgstr "%s: 0x%lx: ödesdigert: ojusterat grenmål för omlokalisering för förenklingsstöd"
+
+#: elf32-sh.c:6627 elf64-alpha.c:4848
+#, c-format
+msgid "%s: TLS local exec code cannot be linked into shared objects"
+msgstr "%s: lokal TLS-exekveringskod kan inte länkas in i delade objekt"
+
+#: elf32-sh64.c:221 elf64-sh64.c:2407
+#, c-format
+msgid "%s: compiled as 32-bit object and %s is 64-bit"
+msgstr "%s: kompilerat som 32-bitarsobjekt och %s är 64-bitars"
+
+#: elf32-sh64.c:224 elf64-sh64.c:2410
+#, c-format
+msgid "%s: compiled as 64-bit object and %s is 32-bit"
+msgstr "%s: kompilerat som 64-bitarsobjekt och %s är 32-bitars"
+
+#: elf32-sh64.c:226 elf64-sh64.c:2412
+#, c-format
+msgid "%s: object size does not match that of target %s"
+msgstr "%s: objektstorleken stämmer inte överens med den hos målet %s"
+
+#: elf32-sh64.c:461 elf64-sh64.c:2990
+#, c-format
+msgid "%s: encountered datalabel symbol in input"
+msgstr "%s: påträffade dataetikettssymbol i indata"
+
+#: elf32-sh64.c:544
+msgid "PTB mismatch: a SHmedia address (bit 0 == 1)"
+msgstr "PTB passar inte: en SHmedia-adress (bit 0 == 1)"
+
+#: elf32-sh64.c:547
+msgid "PTA mismatch: a SHcompact address (bit 0 == 0)"
+msgstr "PTA passar inte: en SHcompact-adress (bit 0 == 0)"
+
+#: elf32-sh64.c:565
+#, c-format
+msgid "%s: GAS error: unexpected PTB insn with R_SH_PT_16"
+msgstr "%s: GAS-fel: oväntad PTB-instruktion med R_SH_PT_16"
+
+#: elf32-sh64.c:614 elf64-sh64.c:1748
+#, c-format
+msgid "%s: error: unaligned relocation type %d at %08x reloc %08x\n"
+msgstr "%s: fel: ojusterad omlokaliseringstyp %d på %08x omlokalisering %08x\n"
+
+#: elf32-sh64.c:698
+#, c-format
+msgid "%s: could not write out added .cranges entries"
+msgstr "%s: kunde inte skriva ut tillagda .cranges-poster"
+
+#: elf32-sh64.c:760
+#, c-format
+msgid "%s: could not write out sorted .cranges entries"
+msgstr "%s: kunde inte skriva ut sorterade cranges-poster"
+
+#: elf32-sparc.c:2521 elf64-sparc.c:2314
+#, c-format
+msgid "%s: probably compiled without -fPIC?"
+msgstr "%s: troligen kompilerad utan -fPIC?"
+
+#: elf32-sparc.c:3348
+#, c-format
+msgid "%s: compiled for a 64 bit system and target is 32 bit"
+msgstr "%s: kompilerat för ett 64-bitarssystem och målet är 32-bitars"
+
+#: elf32-sparc.c:3362
+#, c-format
+msgid "%s: linking little endian files with big endian files"
+msgstr "%s: länkar little endian-filer med big endian-filer"
+
+#: elf32-v850.c:753
+#, c-format
+msgid "Variable `%s' cannot occupy in multiple small data regions"
+msgstr "Variabel \"%s\" kan inte befinna sig i flera små dataområden"
+
+#: elf32-v850.c:756
+#, c-format
+msgid "Variable `%s' can only be in one of the small, zero, and tiny data regions"
+msgstr "Variabel \"%s\" kan bara vara i ett av de små, tomma och pyttesmå dataområdena"
+
+#: elf32-v850.c:759
+#, c-format
+msgid "Variable `%s' cannot be in both small and zero data regions simultaneously"
+msgstr "Variabel \"%s\" kan inte vara i både små och tomma dataområden samtidigt"
+
+#: elf32-v850.c:762
+#, c-format
+msgid "Variable `%s' cannot be in both small and tiny data regions simultaneously"
+msgstr "Variabel \"%s\" kan inte vara i både små och pyttesmå dataområden samtidigt"
+
+#: elf32-v850.c:765
+#, c-format
+msgid "Variable `%s' cannot be in both zero and tiny data regions simultaneously"
+msgstr "Variabel \"%s\" kan inte vara i både tomma och pyttesmå dataområden samtidigt"
+
+#: elf32-v850.c:1144
+msgid "FAILED to find previous HI16 reloc\n"
+msgstr "MISSLYCKADES med att hitta tidigare HI16-omlokalisering\n"
+
+#: elf32-v850.c:1789
+msgid "could not locate special linker symbol __gp"
+msgstr "kunde inte lokalisera speciell länkarsymbol __gp"
+
+#: elf32-v850.c:1793
+msgid "could not locate special linker symbol __ep"
+msgstr "kunde inte lokalisera speciell länkarsymbol __ep"
+
+#: elf32-v850.c:1797
+msgid "could not locate special linker symbol __ctbp"
+msgstr "kunde inte lokalisera speciell länkarsymbol __ctbp"
+
+#: elf32-v850.c:1963
+#, c-format
+msgid "%s: Architecture mismatch with previous modules"
+msgstr "%s: Arkitekturen passar inte ihop med tidigare moduler"
+
+#: elf32-v850.c:1983
+#, c-format
+msgid "private flags = %lx: "
+msgstr "privata flaggor = %lx: "
+
+#: elf32-v850.c:1988
+msgid "v850 architecture"
+msgstr "v850-arkitektur"
+
+#: elf32-v850.c:1989
+msgid "v850e architecture"
+msgstr "v850e-arkitektur"
+
+#: elf32-vax.c:549
+msgid " [nonpic]"
+msgstr " [icke-pic]"
+
+#: elf32-vax.c:552
+msgid " [d-float]"
+msgstr " [d-flyttal]"
+
+#: elf32-vax.c:555
+msgid " [g-float]"
+msgstr " [g-flyttal]"
+
+#: elf32-vax.c:663
+#, c-format
+msgid "%s: warning: GOT addend of %ld to `%s' does not match previous GOT addend of %ld"
+msgstr "%s: varning: GOT-addendum %ld till \"%s\" stämmer inte överens med tidigare GOT-addendum %ld"
+
+#: elf32-vax.c:1667
+#, c-format
+msgid "%s: warning: PLT addend of %d to `%s' from %s section ignored"
+msgstr "%s: varning: PLT-addendum %d till \"%s\" från sektionen %s ignorerades"
+
+#: elf32-vax.c:1802
+#, c-format
+msgid "%s: warning: %s relocation against symbol `%s' from %s section"
+msgstr "%s: varning: %s-omlokalisering mot symbolen \"%s\" från sektionen %s"
+
+#: elf32-vax.c:1808
+#, c-format
+msgid "%s: warning: %s relocation to 0x%x from %s section"
+msgstr "%s: varning: %s-omlokalisering till 0x%x från sektionen %s"
+
+#: elf32-xstormy16.c:462 elf32-ia64.c:2450 elf64-ia64.c:2450
+msgid "non-zero addend in @fptr reloc"
+msgstr "icke-tomt addendum i @fptr-omlokalisering"
+
+#: elf64-alpha.c:1108
+msgid "GPDISP relocation did not find ldah and lda instructions"
+msgstr "GPDISP-omlokalisering hittade inga ldah- och lda-instruktioner"
+
+#: elf64-alpha.c:3731
+#, c-format
+msgid "%s: .got subsegment exceeds 64K (size %d)"
+msgstr "%s: .got-subsegment överskrider 64 kB (storlek %d)"
+
+#: elf64-alpha.c:4602 elf64-alpha.c:4614
+#, c-format
+msgid "%s: gp-relative relocation against dynamic symbol %s"
+msgstr "%s: gp-relativ omlokalisering mot dynamiska symbolen %s"
+
+#: elf64-alpha.c:4640 elf64-alpha.c:4773
+#, c-format
+msgid "%s: pc-relative relocation against dynamic symbol %s"
+msgstr "%s: pc-relativ omlokalisering mot dynamiska symbolen %s"
+
+#: elf64-alpha.c:4668
+#, c-format
+msgid "%s: change in gp: BRSGP %s"
+msgstr "%s: ändring i gp: BRSGP %s"
+
+#: elf64-alpha.c:4693
+msgid "<unknown>"
+msgstr "<okänd>"
+
+#: elf64-alpha.c:4698
+#, c-format
+msgid "%s: !samegp reloc against symbol without .prologue: %s"
+msgstr "%s: !samegp-omlokalisering mot symbol utan .prologue: %s"
+
+#: elf64-alpha.c:4749
+#, c-format
+msgid "%s: unhandled dynamic relocation against %s"
+msgstr "%s: ohanterad dynamisk omlokalisering mot %s"
+
+#: elf64-alpha.c:4832
+#, c-format
+msgid "%s: dtp-relative relocation against dynamic symbol %s"
+msgstr "%s: dtp-relativ omlokalisering mot dynamiska symbolen %s"
+
+#: elf64-alpha.c:4855
+#, c-format
+msgid "%s: tp-relative relocation against dynamic symbol %s"
+msgstr "%s: tp-relativ omlokalisering mot dynamiska symbolen %s"
+
+#: elf64-hppa.c:2086
+#, c-format
+msgid "stub entry for %s cannot load .plt, dp offset = %ld"
+msgstr "stubbpost för %s kan inte läsa in .plt, dp-avstånd = %ld"
+
+#: elf64-mmix.c:1032
+#, c-format
+msgid ""
+"%s: Internal inconsistency error for value for\n"
+" linker-allocated global register: linked: 0x%lx%08lx != relaxed: 0x%lx%08lx\n"
+msgstr ""
+"%s: Intern inkkonsistensfel för värdet för\n"
+" länkarallokerat globalt register: länkat: 0x%lx%08lx != avslappnat: 0x%lx%08lx\n"
+
+#: elf64-mmix.c:1416
+#, c-format
+msgid "%s: base-plus-offset relocation against register symbol: (unknown) in %s"
+msgstr "%s: bas-plus-avståndsomlokalisering mot registersymbol: (okänd) i %s"
+
+#: elf64-mmix.c:1421
+#, c-format
+msgid "%s: base-plus-offset relocation against register symbol: %s in %s"
+msgstr "%s: bas-plus-avståndsomlokalisering mot registersymbol: %s i %s"
+
+#: elf64-mmix.c:1465
+#, c-format
+msgid "%s: register relocation against non-register symbol: (unknown) in %s"
+msgstr "%s: registeromlokalisering mot icke-registersymbol: (okänd) i %s"
+
+#: elf64-mmix.c:1470
+#, c-format
+msgid "%s: register relocation against non-register symbol: %s in %s"
+msgstr "%s: registeromlokalisering mot icke-registersymbol: %s i %s"
+
+#: elf64-mmix.c:1507
+#, c-format
+msgid "%s: directive LOCAL valid only with a register or absolute value"
+msgstr "%s: LOCAL-direktivet är endast giltigt med ett register eller absolutvärde"
+
+#: elf64-mmix.c:1535
+#, c-format
+msgid "%s: LOCAL directive: Register $%ld is not a local register. First global register is $%ld."
+msgstr "%s: LOCAL-direktiv: Register $%ld är inte ett lokalt register. Första globala registret är $%ld."
+
+#: elf64-mmix.c:1994
+#, c-format
+msgid "%s: Error: multiple definition of `%s'; start of %s is set in a earlier linked file\n"
+msgstr "%s: Fel: flera definitioner av \"%s\"; början på %s är inställd i en tidigare länkad fil\n"
+
+#: elf64-mmix.c:2053
+msgid "Register section has contents\n"
+msgstr "Registersektion har innehåll\n"
+
+#: elf64-mmix.c:2216
+#, c-format
+msgid ""
+"Internal inconsistency: remaining %u != max %u.\n"
+" Please report this bug."
+msgstr ""
+"Intern inkonsekvens: återstående %u != max %u.\n"
+" Rapportera gärna detta fel."
+
+#: elf64-ppc.c:2388 libbfd.c:831
+#, c-format
+msgid "%s: compiled for a big endian system and target is little endian"
+msgstr "%s: kompilerad för big endian-system och målet är little endian"
+
+#: elf64-ppc.c:2391 libbfd.c:833
+#, c-format
+msgid "%s: compiled for a little endian system and target is big endian"
+msgstr "%s: kompilerad för ett little endian-system och målet är big endian"
+
+#: elf64-ppc.c:4857
+#, c-format
+msgid "%s: unexpected reloc type %u in .opd section"
+msgstr "%s: oväntad omlokaliseringstyp %u i .opd-sektion"
+
+#: elf64-ppc.c:4877
+#, c-format
+msgid "%s: .opd is not a regular array of opd entries"
+msgstr "%s: .opd är inte en vanlig vektor med opd-poster"
+
+#: elf64-ppc.c:4897
+#, c-format
+msgid "%s: undefined sym `%s' in .opd section"
+msgstr "%s: odefinierad symbol \"%s\" i .opd-sektion"
+
+#: elf64-ppc.c:6136
+#, c-format
+msgid "can't find branch stub `%s'"
+msgstr "kan inte hitta grenstubb \"%s\""
+
+#: elf64-ppc.c:6175 elf64-ppc.c:6250
+#, c-format
+msgid "linkage table error against `%s'"
+msgstr "länktabellsfel mot \"%s\""
+
+#: elf64-ppc.c:6340
+#, c-format
+msgid "can't build branch stub `%s'"
+msgstr "kan inte bygga grenstubb \"%s\""
+
+#: elf64-ppc.c:7047
+msgid ".glink and .plt too far apart"
+msgstr ".glink och .plt för långt ifrån varandra"
+
+#: elf64-ppc.c:7135
+msgid "stubs don't match calculated size"
+msgstr "stubbar stämmer inte överens med beräknad storlek"
+
+#: elf64-ppc.c:7147
+#, c-format
+msgid ""
+"linker stubs in %u groups\n"
+" branch %lu\n"
+" toc adjust %lu\n"
+" long branch %lu\n"
+" long toc adj %lu\n"
+" plt call %lu"
+msgstr ""
+"länkarstubbar i %u grupper\n"
+" gren %lu\n"
+" toc-justering %lu\n"
+" lång gren %lu\n"
+" lång toc-just. %lu\n"
+" plt-anrop %lu"
+
+#: elf64-ppc.c:7723
+#, c-format
+msgid "%s(%s+0x%lx): automatic multiple TOCs not supported using your crt files; recompile with -mminimal-toc or upgrade gcc"
+msgstr "%s(%s+0x%lx): flera automatiska TOC stöds inte vid användning av dina crt-filer; kompilera om med -mminimal-toc eller uppgradera gcc"
+
+#: elf64-ppc.c:7731
+#, c-format
+msgid "%s(%s+0x%lx): sibling call optimization to `%s' does not allow automatic multiple TOCs; recompile with -mminimal-toc or -fno-optimize-sibling-calls, or make `%s' extern"
+msgstr "%s(%s+0x%lx): syskonanropsoptimering till \"%s\" stöder inte flera automatiska TOC; kompilera om med -mminimal-toc eller -fno-optimize-sibling-calls, eller gör \"%s\" extern"
+
+#: elf64-ppc.c:8329
+#, c-format
+msgid "%s: relocation %s is not supported for symbol %s."
+msgstr "%s: omlokaliseringen %s stöds inte för symbolen %s."
+
+#: elf64-ppc.c:8408
+#, c-format
+msgid "%s: error: relocation %s not a multiple of %d"
+msgstr "%s: fel: omlokaliseringen %s är inte en multipel av %d"
+
+#: elf64-sparc.c:1370
+#, c-format
+msgid "%s: check_relocs: unhandled reloc type %d"
+msgstr "%s: check_relocs: ohanterad omlokaliseringstyp %d"
+
+#: elf64-sparc.c:1407
+#, c-format
+msgid "%s: Only registers %%g[2367] can be declared using STT_REGISTER"
+msgstr "%s: Endast register %%g[2367] kan deklareras med STT_REGISTER"
+
+#: elf64-sparc.c:1427
+#, c-format
+msgid "Register %%g%d used incompatibly: %s in %s, previously %s in %s"
+msgstr "Register %%g%d används inkompatibelt: %s i %s, tidigare %s i %s"
+
+#: elf64-sparc.c:1450
+#, c-format
+msgid "Symbol `%s' has differing types: REGISTER in %s, previously %s in %s"
+msgstr "Symbolen \"%s\" har olika typer: REGISTER i %s, tidigare %s i %s"
+
+#: elf64-sparc.c:1496
+#, c-format
+msgid "Symbol `%s' has differing types: %s in %s, previously REGISTER in %s"
+msgstr "Symbolen \"%s\" har olika typer: %s i %s, tidigare REGISTER i %s"
+
+#: elf64-sparc.c:3053
+#, c-format
+msgid "%s: linking UltraSPARC specific with HAL specific code"
+msgstr "%s: länkar UltraSPARC-specifik med HAL-specifik kod"
+
+#: elf64-x86-64.c:739
+#, c-format
+msgid "%s: %s' accessed both as normal and thread local symbol"
+msgstr "%s: \"%s\" anropad både som lokal normal symbol och lokal trådsymbol"
+
+#: elfcode.h:1113
+#, c-format
+msgid "%s: version count (%ld) does not match symbol count (%ld)"
+msgstr "%s: versionsantal (%ld) stämmer inte med symbolantal (%ld)"
+
+#: elfcode.h:1342
+#, c-format
+msgid "%s(%s): relocation %d has invalid symbol index %ld"
+msgstr "%s(%s): omlokalisering %d har ogiltigt symbolindex %ld"
+
+#: elflink.c:1456
+#, c-format
+msgid "%s: warning: unexpected redefinition of indirect versioned symbol `%s'"
+msgstr "%s: varning: oväntad omdefinition av indirekt versionsangiven symbol \"%s\""
+
+#: elflink.c:1807
+#, c-format
+msgid "%s: undefined versioned symbol name %s"
+msgstr "%s: odefinierat symbolnamn med version %s"
+
+#: elflink.c:2142
+#, c-format
+msgid "%s: relocation size mismatch in %s section %s"
+msgstr "%s: omlokaliseringsstorleken stämmer inte överens i %s, sektion %s"
+
+#: elflink.c:2434
+#, c-format
+msgid "warning: type and size of dynamic symbol `%s' are not defined"
+msgstr "varning: typen och storleken på dynamiska symbolen \"%s\" är inte definierade"
+
+#: elflink.h:1022
+#, c-format
+msgid "%s: %s: invalid version %u (max %d)"
+msgstr "%s: %s: ogiltig version %u (max %d)"
+
+#: elflink.h:1063
+#, c-format
+msgid "%s: %s: invalid needed version %d"
+msgstr "%s: %s: ogiltig krävd version %d"
+
+#: elflink.h:1238
+#, c-format
+msgid "Warning: alignment %u of symbol `%s' in %s is smaller than %u in %s"
+msgstr "Varning: justeringen %u på symbolen \"%s\" i %s är mindre än %u i %s"
+
+#: elflink.h:1252
+#, c-format
+msgid "Warning: size of symbol `%s' changed from %lu in %s to %lu in %s"
+msgstr "Varning: storleken på symbolen \"%s\" ändrades från %lu i %s till %lu i %s"
+
+#: elflink.h:2160
+#, c-format
+msgid "%s: undefined version: %s"
+msgstr "%s: odefinierad version: %s"
+
+#: elflink.h:2226
+#, c-format
+msgid "%s: .preinit_array section is not allowed in DSO"
+msgstr "%s: .preinit_array-sektionen är inte tillåten i DSO"
+
+#: elflink.h:3078
+msgid "Not enough memory to sort relocations"
+msgstr "Inte tillräckligt med minne för att sortera omlokaliseringar"
+
+#: elflink.h:3958 elflink.h:4001
+#, c-format
+msgid "%s: could not find output section %s"
+msgstr "%s: kunde inte hitta utdatasektionen %s"
+
+#: elflink.h:3964
+#, c-format
+msgid "warning: %s section has zero size"
+msgstr "varning: sektionen %s har nollstorlek"
+
+#: elflink.h:4483
+#, c-format
+msgid "%s: %s symbol `%s' in %s is referenced by DSO"
+msgstr "%s: %s-symbolen \"%s\" i %s refereras till av DSO"
+
+#: elflink.h:4564
+#, c-format
+msgid "%s: could not find output section %s for input section %s"
+msgstr "%s: kunde inte hitta utdatasektionen %s för indatasektionen %s"
+
+#: elflink.h:4666
+#, c-format
+msgid "%s: %s symbol `%s' isn't defined"
+msgstr "%s: %s-symbolen \"%s\" är inte definierad"
+
+#: elflink.h:5053 elflink.h:5095
+msgid "%T: discarded in section `%s' from %s\n"
+msgstr "%T: bortkastade i sektionen \"%s\" från %s\n"
+
+#: elfxx-mips.c:887
+msgid "static procedure (no name)"
+msgstr "statisk procedur (inget namn)"
+
+#: elfxx-mips.c:1897
+msgid "not enough GOT space for local GOT entries"
+msgstr "inte tillräckligt med GOT-utrymme för lokala GOT-poster"
+
+#: elfxx-mips.c:3691
+#, c-format
+msgid "%s: %s+0x%lx: jump to stub routine which is not jal"
+msgstr "%s: %s+0x%lx: hoppa till stubbrutin som inte är jal"
+
+#: elfxx-mips.c:5192
+#, c-format
+msgid "%s: Malformed reloc detected for section %s"
+msgstr "%s: Felaktig omlokalisering för sektion %s upptäckt"
+
+#: elfxx-mips.c:5266
+#, c-format
+msgid "%s: CALL16 reloc at 0x%lx not against global symbol"
+msgstr "%s: CALL16-omlokalisering vid 0x%lx är inte mot global symbol"
+
+#: elfxx-mips.c:8692
+#, c-format
+msgid "%s: illegal section name `%s'"
+msgstr "%s: ogiltigt sektionsnamn \"%s\""
+
+#: elfxx-mips.c:9025
+#, c-format
+msgid "%s: endianness incompatible with that of the selected emulation"
+msgstr "%s: endianness inkompatibel med den för den valda emuleringen"
+
+#: elfxx-mips.c:9037
+#, c-format
+msgid "%s: ABI is incompatible with that of the selected emulation"
+msgstr "%s: ABI är inkompatibelt med den för den valda emuleringen"
+
+#: elfxx-mips.c:9104
+#, c-format
+msgid "%s: warning: linking PIC files with non-PIC files"
+msgstr "%s: varning: länkar PIC-filer med icke-PIC-filer"
+
+#: elfxx-mips.c:9121
+#, c-format
+msgid "%s: linking 32-bit code with 64-bit code"
+msgstr "%s: länkar 32-bitarskod med 64-bitarskod"
+
+#: elfxx-mips.c:9149
+#, c-format
+msgid "%s: linking %s module with previous %s modules"
+msgstr "%s: länkar %s-modul med tidigare %s-moduler"
+
+#: elfxx-mips.c:9172
+#, c-format
+msgid "%s: ABI mismatch: linking %s module with previous %s modules"
+msgstr "%s: ABI passar inte: länkar %s-modul med tidigare %s-moduler"
+
+#: elfxx-mips.c:9241
+msgid " [abi=O32]"
+msgstr " [abi=O32]"
+
+#: elfxx-mips.c:9243
+msgid " [abi=O64]"
+msgstr " [abi=O64]"
+
+#: elfxx-mips.c:9245
+msgid " [abi=EABI32]"
+msgstr " [abi=EABI32]"
+
+#: elfxx-mips.c:9247
+msgid " [abi=EABI64]"
+msgstr " [abi=EABI64]"
+
+#: elfxx-mips.c:9249
+msgid " [abi unknown]"
+msgstr " [okänt abi]"
+
+#: elfxx-mips.c:9251
+msgid " [abi=N32]"
+msgstr " [abi=N32]"
+
+#: elfxx-mips.c:9253
+msgid " [abi=64]"
+msgstr " [abi=64]"
+
+#: elfxx-mips.c:9255
+msgid " [no abi set]"
+msgstr " [inget abi inställt]"
+
+#: elfxx-mips.c:9258
+msgid " [mips1]"
+msgstr " [mips1]"
+
+#: elfxx-mips.c:9260
+msgid " [mips2]"
+msgstr " [mips2]"
+
+#: elfxx-mips.c:9262
+msgid " [mips3]"
+msgstr " [mips3]"
+
+#: elfxx-mips.c:9264
+msgid " [mips4]"
+msgstr " [mips4]"
+
+#: elfxx-mips.c:9266
+msgid " [mips5]"
+msgstr " [mips5]"
+
+#: elfxx-mips.c:9268
+msgid " [mips32]"
+msgstr " [mips32]"
+
+#: elfxx-mips.c:9270
+msgid " [mips64]"
+msgstr " [mips64]"
+
+#: elfxx-mips.c:9272
+msgid " [mips32r2]"
+msgstr " [mips32r2]"
+
+#: elfxx-mips.c:9274
+msgid " [unknown ISA]"
+msgstr " [okänd ISA]"
+
+#: elfxx-mips.c:9277
+msgid " [mdmx]"
+msgstr " [mdmx]"
+
+#: elfxx-mips.c:9280
+msgid " [mips16]"
+msgstr " [mips16]"
+
+#: elfxx-mips.c:9283
+msgid " [32bitmode]"
+msgstr " [32-bitarsläge]"
+
+#: elfxx-mips.c:9285
+msgid " [not 32bitmode]"
+msgstr " [inte 32-bitarsläge]"
+
+#: i386linux.c:457 m68klinux.c:461 sparclinux.c:458
+#, c-format
+msgid "Output file requires shared library `%s'\n"
+msgstr "Utdatafilen kräver delade biblioteket \"%s\"\n"
+
+#: i386linux.c:465 m68klinux.c:469 sparclinux.c:466
+#, c-format
+msgid "Output file requires shared library `%s.so.%s'\n"
+msgstr "Utdatafilen kräver delade biblioteket \"%s.so.%s\"\n"
+
+#: i386linux.c:654 i386linux.c:704 m68klinux.c:661 m68klinux.c:709
+#: sparclinux.c:656 sparclinux.c:706
+#, c-format
+msgid "Symbol %s not defined for fixups\n"
+msgstr "Symbolen %s är inte definierad för fixar\n"
+
+#: i386linux.c:728 m68klinux.c:733 sparclinux.c:730
+msgid "Warning: fixup count mismatch\n"
+msgstr "Varning: antalet fixar stämmer inte\n"
+
+#: ieee.c:293
+#, c-format
+msgid "%s: string too long (%d chars, max 65535)"
+msgstr "%s: strängen är för lång (%d tecken, max 65535)"
+
+#: ieee.c:428
+#, c-format
+msgid "%s: unrecognized symbol `%s' flags 0x%x"
+msgstr "%s: okänd symbol \"%s\" flaggor 0x%x"
+
+#: ieee.c:938
+#, c-format
+msgid "%s: unimplemented ATI record %u for symbol %u"
+msgstr "%s: inte implementerad ATI-post %u för symbolen %u"
+
+#: ieee.c:963
+#, c-format
+msgid "%s: unexpected ATN type %d in external part"
+msgstr "%s: oväntad ATN-typ %d i extern del"
+
+#: ieee.c:985
+#, c-format
+msgid "%s: unexpected type after ATN"
+msgstr "%s: oväntad typ efter ATN"
+
+#: ihex.c:264
+#, c-format
+msgid "%s:%d: unexpected character `%s' in Intel Hex file\n"
+msgstr "%s:%d: oväntat tecken \"%s\" i hexadecimal Intel-fil\n"
+
+#: ihex.c:372
+#, c-format
+msgid "%s:%u: bad checksum in Intel Hex file (expected %u, found %u)"
+msgstr "%s:%u: felaktig kontrollsumma i hexadecimal Intel-fil (förväntade %u, hittade %u)"
+
+#: ihex.c:426
+#, c-format
+msgid "%s:%u: bad extended address record length in Intel Hex file"
+msgstr "%s:%u: felaktig längd på post för utökad adress i hexadecimal Intel-fil"
+
+#: ihex.c:443
+#, c-format
+msgid "%s:%u: bad extended start address length in Intel Hex file"
+msgstr "%s:%u: felaktig längd på utökad startadress i hexadecimal Intel-fil"
+
+#: ihex.c:460
+#, c-format
+msgid "%s:%u: bad extended linear address record length in Intel Hex file"
+msgstr "%s:%u: felaktig längd på post för utökad linjär adress i hexadecimal Intel-fil"
+
+#: ihex.c:477
+#, c-format
+msgid "%s:%u: bad extended linear start address length in Intel Hex file"
+msgstr "%s:%u: felaktig längd på post för utökad linjär startadress i hexadecimal Intel-fil"
+
+#: ihex.c:494
+#, c-format
+msgid "%s:%u: unrecognized ihex type %u in Intel Hex file\n"
+msgstr "%s:%u: okänd ihex-typ %u i hexadecimal Intel-fil\n"
+
+#: ihex.c:619
+#, c-format
+msgid "%s: internal error in ihex_read_section"
+msgstr "%s: internt fel i ihex_read_section"
+
+#: ihex.c:654
+#, c-format
+msgid "%s: bad section length in ihex_read_section"
+msgstr "%s: felaktig sektionslängd i ihex_read_sektion"
+
+#: ihex.c:872
+#, c-format
+msgid "%s: address 0x%s out of range for Intel Hex file"
+msgstr "%s: adressen 0x%s är utanför intervallet för hexadecimal Intel-fil"
+
+#: libbfd.c:861
+#, c-format
+msgid "Deprecated %s called at %s line %d in %s\n"
+msgstr "Föråldrad %s anropad vid %s rad %d i %s\n"
+
+#: libbfd.c:864
+#, c-format
+msgid "Deprecated %s called\n"
+msgstr "Föråldrad %s anropad\n"
+
+#: linker.c:1829
+#, c-format
+msgid "%s: indirect symbol `%s' to `%s' is a loop"
+msgstr "%s: indirekt symbol \"%s\" till \"%s\" är en slinga"
+
+#: linker.c:2697
+#, c-format
+msgid "Attempt to do relocatable link with %s input and %s output"
+msgstr "Försök att göra en omlokaliseringsbar länk med %s-indata och %s-utdata"
+
+#: merge.c:896
+#, c-format
+msgid "%s: access beyond end of merged section (%ld + %ld)"
+msgstr "%s: åtkomst bortom slut på sammanslagen sektion (%ld + %ld)"
+
+#: mmo.c:503
+#, c-format
+msgid "%s: No core to allocate section name %s\n"
+msgstr "%s: Ingen kärna för att allokera sektionsnamn %s\n"
+
+#: mmo.c:579
+#, c-format
+msgid "%s: No core to allocate a symbol %d bytes long\n"
+msgstr "%s: Ingen kärna för att allokera en %d byte lång symbol\n"
+
+#: mmo.c:1287
+#, c-format
+msgid "%s: invalid mmo file: initialization value for $255 is not `Main'\n"
+msgstr "%s: ogiltig mmo-fil: initieringsvärde för $255 är inte \"Main\"\n"
+
+#: mmo.c:1433
+#, c-format
+msgid "%s: unsupported wide character sequence 0x%02X 0x%02X after symbol name starting with `%s'\n"
+msgstr "%s: bred teckensekvens som inte stöds 0x%02X 0x%02X efter symbolnamnet som börjar med \"%s\"\n"
+
+#: mmo.c:1674
+#, c-format
+msgid "%s: invalid mmo file: unsupported lopcode `%d'\n"
+msgstr "%s: ogiltig mmo-fil: lopkod \"%d\" stöds inte\n"
+
+#: mmo.c:1684
+#, c-format
+msgid "%s: invalid mmo file: expected YZ = 1 got YZ = %d for lop_quote\n"
+msgstr "%s: ogiltig mmo-fil: förväntade YZ = 1 fick YZ = %d för lop_quote\n"
+
+#: mmo.c:1720
+#, c-format
+msgid "%s: invalid mmo file: expected z = 1 or z = 2, got z = %d for lop_loc\n"
+msgstr "%s: ogiltig mmo-fil: förväntade z = 1 eller z = 2, fick z = %d för lop_loc\n"
+
+#: mmo.c:1766
+#, c-format
+msgid "%s: invalid mmo file: expected z = 1 or z = 2, got z = %d for lop_fixo\n"
+msgstr "%s: ogiltig mmo-fil: förväntade z = 1 eller z = 2, fick z = %d för lop_fixo\n"
+
+#: mmo.c:1805
+#, c-format
+msgid "%s: invalid mmo file: expected y = 0, got y = %d for lop_fixrx\n"
+msgstr "%s: ogiltig mmo-fil: förväntade y = 0, fick y = %d för lop_fixrx\n"
+
+#: mmo.c:1814
+#, c-format
+msgid "%s: invalid mmo file: expected z = 16 or z = 24, got z = %d for lop_fixrx\n"
+msgstr "%s: ogiltig mmo-fil: förväntade z = 16 eller z = 24, fick z = %d för lop_fixr\n"
+
+#: mmo.c:1837
+#, c-format
+msgid "%s: invalid mmo file: leading byte of operand word must be 0 or 1, got %d for lop_fixrx\n"
+msgstr "%s: ogiltig mmo-fil: inledande byte i operandord måste vara 0 eller 1, fick %d för lop_fixrx\n"
+
+#: mmo.c:1860
+#, c-format
+msgid "%s: cannot allocate file name for file number %d, %d bytes\n"
+msgstr "%s: kan inte allokera filnamn för fil nummer %d, %d byte\n"
+
+#: mmo.c:1880
+#, c-format
+msgid "%s: invalid mmo file: file number %d `%s', was already entered as `%s'\n"
+msgstr "%s: ogiltig mmo-fil: fil nummer %d \"%s\", var redan angiven som \"%s\"\n"
+
+#: mmo.c:1893
+#, c-format
+msgid "%s: invalid mmo file: file name for number %d was not specified before use\n"
+msgstr "%s: ogiltig mmo-fil: filnamnet för nummer %d angavs inte innan användning\n"
+
+#: mmo.c:1999
+#, c-format
+msgid "%s: invalid mmo file: fields y and z of lop_stab non-zero, y: %d, z: %d\n"
+msgstr "%s: ogiltig mmo-fil: fälten y och z i lop_stab är icke-tomma, y: %d, z: %d\n"
+
+#: mmo.c:2035
+#, c-format
+msgid "%s: invalid mmo file: lop_end not last item in file\n"
+msgstr "%s: ogiltig mmo-fil: lop_end är inte sista objektet i fil\n"
+
+#: mmo.c:2048
+#, c-format
+msgid "%s: invalid mmo file: YZ of lop_end (%ld) not equal to the number of tetras to the preceding lop_stab (%ld)\n"
+msgstr "%s: ogiltig mmo-fil: YZ i lop_end (%ld) är inte lika med antalet tetra till den föregående lop_stab (%ld)\n"
+
+#: mmo.c:2698
+#, c-format
+msgid "%s: invalid symbol table: duplicate symbol `%s'\n"
+msgstr "%s: ogiltig symboltabell: dublettsymbol \"%s\"\n"
+
+#: mmo.c:2949
+#, c-format
+msgid "%s: Bad symbol definition: `Main' set to %s rather than the start address %s\n"
+msgstr "%s: Felaktig symboldefinition: \"Main\" är inställd till %s istället för startadressen %s\n"
+
+#: mmo.c:3039
+#, c-format
+msgid "%s: warning: symbol table too large for mmo, larger than 65535 32-bit words: %d. Only `Main' will be emitted.\n"
+msgstr "%s: varning: symboltabellen är för stor för mmo, större än 65535 32-bitars ord: %d. Endast \"Main\" kommer att skickas.\n"
+
+#: mmo.c:3084
+#, c-format
+msgid "%s: internal error, symbol table changed size from %d to %d words\n"
+msgstr "%s: internt fel, symboltabellen ändrade storlek från %d till %d ord\n"
+
+#: mmo.c:3139
+#, c-format
+msgid "%s: internal error, internal register section %s had contents\n"
+msgstr "%s: internt fel, interna registersektionen %s hade innehåll\n"
+
+#: mmo.c:3191
+#, c-format
+msgid "%s: no initialized registers; section length 0\n"
+msgstr "%s: inga initierade register; sektionslängd 0\n"
+
+#: mmo.c:3197
+#, c-format
+msgid "%s: too many initialized registers; section length %ld\n"
+msgstr "%s: för många initierade register; sektionslängd %ld\n"
+
+#: mmo.c:3202
+#, c-format
+msgid "%s: invalid start address for initialized registers of length %ld: 0x%lx%08lx\n"
+msgstr "%s: ogiltig startadress för initierade register med längden %ld: 0x%lx%08lx\n"
+
+#: oasys.c:1052
+#, c-format
+msgid "%s: can not represent section `%s' in oasys"
+msgstr "%s: kan inte representera sektionen \"%s\" i oasys"
+
+#: osf-core.c:137
+#, c-format
+msgid "Unhandled OSF/1 core file section type %d\n"
+msgstr "Ohanterad sektionstyp %d för OSF/1-minnesfil\n"
+
+#: pe-mips.c:659
+#, c-format
+msgid "%s: `ld -r' not supported with PE MIPS objects\n"
+msgstr "%s: \"ld -r\" stöds inte med PE MIPS-objekt\n"
+
+#. OK, at this point the following variables are set up:
+#. src = VMA of the memory we're fixing up
+#. mem = pointer to memory we're fixing up
+#. val = VMA of what we need to refer to
+#.
+#: pe-mips.c:795
+#, c-format
+msgid "%s: unimplemented %s\n"
+msgstr "%s: oimplementerat %s\n"
+
+#: pe-mips.c:821
+#, c-format
+msgid "%s: jump too far away\n"
+msgstr "%s: hopp för långt bort\n"
+
+#: pe-mips.c:848
+#, c-format
+msgid "%s: bad pair/reflo after refhi\n"
+msgstr "%s: felaktigt par/reflo efter refhi\n"
+
+#. XXX code yet to be written.
+#: peicode.h:787
+#, c-format
+msgid "%s: Unhandled import type; %x"
+msgstr "%s: Ohanterad importtyp; %x"
+
+#: peicode.h:792
+#, c-format
+msgid "%s: Unrecognised import type; %x"
+msgstr "%s: Okänd importtyp; %x"
+
+#: peicode.h:806
+#, c-format
+msgid "%s: Unrecognised import name type; %x"
+msgstr "%s: Okänd importnamnstyp; %x"
+
+#: peicode.h:1164
+#, c-format
+msgid "%s: Unrecognised machine type (0x%x) in Import Library Format archive"
+msgstr "%s: Okänd maskintyp (0x%x) i Import Library Format-arkiv"
+
+#: peicode.h:1176
+#, c-format
+msgid "%s: Recognised but unhandled machine type (0x%x) in Import Library Format archive"
+msgstr "%s: Känd men ohanterad maskintyp (0x%x) i Import Library Format-arkiv"
+
+#: peicode.h:1193
+#, c-format
+msgid "%s: size field is zero in Import Library Format header"
+msgstr "%s: storleksfältet är noll i Import Library Format-huvud"
+
+#: peicode.h:1224
+#, c-format
+msgid "%s: string not null terminated in ILF object file."
+msgstr "%s: sträng inte nollterminerad i ILF-objektfil."
+
+#: ppcboot.c:416
+msgid ""
+"\n"
+"ppcboot header:\n"
+msgstr ""
+"\n"
+"ppcboot-huvud:\n"
+
+#: ppcboot.c:417
+#, c-format
+msgid "Entry offset = 0x%.8lx (%ld)\n"
+msgstr "Startavstånd = 0x%.8lx (%ld)\n"
+
+#: ppcboot.c:418
+#, c-format
+msgid "Length = 0x%.8lx (%ld)\n"
+msgstr "Längd = 0x%.8lx (%ld)\n"
+
+#: ppcboot.c:421
+#, c-format
+msgid "Flag field = 0x%.2x\n"
+msgstr "Flaggfält = 0x%.2x\n"
+
+#: ppcboot.c:427
+#, c-format
+msgid "Partition name = \"%s\"\n"
+msgstr "Partitionsnamn = \"%s\"\n"
+
+#: ppcboot.c:446
+#, c-format
+msgid ""
+"\n"
+"Partition[%d] start = { 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x }\n"
+msgstr ""
+"\n"
+"Start på partition[%d] = { 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x }\n"
+
+#: ppcboot.c:452
+#, c-format
+msgid "Partition[%d] end = { 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x }\n"
+msgstr "Slut på partition[%d] = { 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x }\n"
+
+#: ppcboot.c:458
+#, c-format
+msgid "Partition[%d] sector = 0x%.8lx (%ld)\n"
+msgstr "Sektor för partition[%d] = 0x%.8lx (%ld)\n"
+
+#: ppcboot.c:459
+#, c-format
+msgid "Partition[%d] length = 0x%.8lx (%ld)\n"
+msgstr "Längd på partition[%d] = 0x%.8lx (%ld)\n"
+
+#: som.c:5422
+msgid "som_sizeof_headers unimplemented"
+msgstr "som_sizeof_headers är inte implementerat"
+
+#: srec.c:302
+#, c-format
+msgid "%s:%d: Unexpected character `%s' in S-record file\n"
+msgstr "%s:%d: Oväntat tecken \"%s\" i S-postfil\n"
+
+# Vad är stabs?
+#: stabs.c:319
+#, c-format
+msgid "%s(%s+0x%lx): Stabs entry has invalid string index."
+msgstr "%s(%s+0x%lx): Stabbpost har ogiltigt strängindex."
+
+#: syms.c:1019
+msgid "Unsupported .stab relocation"
+msgstr ".stab-omlokalisering som inte stöds"
+
+#: vms-gsd.c:356
+#, c-format
+msgid "bfd_make_section (%s) failed"
+msgstr "bfd_make_section (%s) misslyckades"
+
+#: vms-gsd.c:371
+#, c-format
+msgid "bfd_set_section_flags (%s, %x) failed"
+msgstr "bfd_set_section_flags (%s, %x) misslyckades"
+
+#: vms-gsd.c:407
+#, c-format
+msgid "Size mismatch section %s=%lx, %s=%lx"
+msgstr "Storleken passar inte på sektion %s=%lx, %s=%lx"
+
+#: vms-gsd.c:704
+#, c-format
+msgid "unknown gsd/egsd subtype %d"
+msgstr "okänd gsd/egsd-undertyp %d"
+
+#: vms-hdr.c:408
+msgid "Object module NOT error-free !\n"
+msgstr "Objektmodulen INTE felfri!\n"
+
+#: vms-misc.c:541
+#, c-format
+msgid "Stack overflow (%d) in _bfd_vms_push"
+msgstr "Stacken ger överspill (%d) i _bfd_vms_push"
+
+#: vms-misc.c:559
+msgid "Stack underflow in _bfd_vms_pop"
+msgstr "Stacken ger underspill i _bfd_vms_pop"
+
+#: vms-misc.c:918
+msgid "_bfd_vms_output_counted called with zero bytes"
+msgstr "_bfd_vms_output_counted anropad med noll byte"
+
+#: vms-misc.c:923
+msgid "_bfd_vms_output_counted called with too many bytes"
+msgstr "_bfd_vms_output_counted called anropad med för många byte"
+
+#: vms-misc.c:1054
+#, c-format
+msgid "Symbol %s replaced by %s\n"
+msgstr "Symbolen %s ersatt med %s\n"
+
+#: vms-misc.c:1117
+#, c-format
+msgid "failed to enter %s"
+msgstr "misslyckades med att gå in i %s"
+
+#: vms-tir.c:102
+msgid "No Mem !"
+msgstr "Inget minne!"
+
+#: vms-tir.c:383
+#, c-format
+msgid "bad section index in %s"
+msgstr "felaktigt sektionsindex i %s"
+
+#: vms-tir.c:396
+#, c-format
+msgid "unsupported STA cmd %s"
+msgstr "STA-kommando %s stöds inte"
+
+#: vms-tir.c:401 vms-tir.c:1261
+#, c-format
+msgid "reserved STA cmd %d"
+msgstr "reserverat STA-kommando %d"
+
+#: vms-tir.c:512 vms-tir.c:535
+#, c-format
+msgid "%s: no symbol \"%s\""
+msgstr "%s: ingen symbol \"%s\""
+
+#. unsigned shift
+#. rotate
+#. Redefine symbol to current location.
+#. Define a literal.
+#: vms-tir.c:602 vms-tir.c:714 vms-tir.c:824 vms-tir.c:842 vms-tir.c:850
+#: vms-tir.c:859 vms-tir.c:1584
+#, c-format
+msgid "%s: not supported"
+msgstr "%s: stöds inte"
+
+#: vms-tir.c:607 vms-tir.c:1439
+#, c-format
+msgid "%s: not implemented"
+msgstr "%s: inte implementerad"
+
+#: vms-tir.c:611 vms-tir.c:1443
+#, c-format
+msgid "reserved STO cmd %d"
+msgstr "reserverat STO-kommando %d"
+
+#: vms-tir.c:729 vms-tir.c:1589
+#, c-format
+msgid "reserved OPR cmd %d"
+msgstr "reserverat OPR-kommando %d"
+
+#: vms-tir.c:797 vms-tir.c:1653
+#, c-format
+msgid "reserved CTL cmd %d"
+msgstr "reserverat CTL-kommando %d"
+
+#. stack byte from image
+#. arg: none.
+#: vms-tir.c:1169
+msgid "stack-from-image not implemented"
+msgstr "stack-from-image är inte implementerat"
+
+#: vms-tir.c:1187
+msgid "stack-entry-mask not fully implemented"
+msgstr "stack-entry-mask är inte helt implementerat"
+
+#. 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.
+#: vms-tir.c:1201
+msgid "PASSMECH not fully implemented"
+msgstr "PASSMECH är inte helt implementerat"
+
+#: vms-tir.c:1220
+msgid "stack-local-symbol not fully implemented"
+msgstr "stack-local-symbol är inte helt implementerat"
+
+#: vms-tir.c:1233
+msgid "stack-literal not fully implemented"
+msgstr "stack-literal är inte helt implementerat"
+
+#: vms-tir.c:1254
+msgid "stack-local-symbol-entry-point-mask not fully implemented"
+msgstr "stack-local-symbol-entry-point-mask är inte helt implementerat"
+
+#: vms-tir.c:1531 vms-tir.c:1543 vms-tir.c:1555 vms-tir.c:1567 vms-tir.c:1632
+#: vms-tir.c:1640 vms-tir.c:1648
+#, c-format
+msgid "%s: not fully implemented"
+msgstr "%s: inte helt implementerat"
+
+#: vms-tir.c:1705
+#, c-format
+msgid "obj code %d not found"
+msgstr "objektkod %d kunde inte hittas"
+
+#: vms-tir.c:2043
+#, c-format
+msgid "SEC_RELOC with no relocs in section %s"
+msgstr "SEC_RELOC utan omlokaliseringar i sektion %s"
+
+#: vms-tir.c:2331
+#, c-format
+msgid "Unhandled relocation %s"
+msgstr "Ohanterad omlokalisering %s"
+
+#: xcofflink.c:1244
+#, c-format
+msgid "%s: `%s' has line numbers but no enclosing section"
+msgstr "%s: \"%s\" har radnummer men ingen inneslutande sektion"
+
+#: xcofflink.c:1297
+#, c-format
+msgid "%s: class %d symbol `%s' has no aux entries"
+msgstr "%s: klass %d-symbolen \"%s\" har inga yttre poster"
+
+#: xcofflink.c:1320
+#, c-format
+msgid "%s: symbol `%s' has unrecognized csect type %d"
+msgstr "%s: symbolen \"%s\" har okänd csect-typ %d"
+
+#: xcofflink.c:1332
+#, c-format
+msgid "%s: bad XTY_ER symbol `%s': class %d scnum %d scnlen %d"
+msgstr "%s: felaktig XTY_ER-symbol \"%s\": klass %d scnum %d scnlen %d"
+
+#: xcofflink.c:1368
+#, c-format
+msgid "%s: XMC_TC0 symbol `%s' is class %d scnlen %d"
+msgstr "%s: XMC_TC0-symbolen \"%s\" är klass %d scnlen %d"
+
+#: xcofflink.c:1520
+#, c-format
+msgid "%s: csect `%s' not in enclosing section"
+msgstr "%s: csect \"%s\" är inte i inneslutande sektion"
+
+#: xcofflink.c:1627
+#, c-format
+msgid "%s: misplaced XTY_LD `%s'"
+msgstr "%s: felaktigt placerat XTY_LD \"%s\""
+
+#: xcofflink.c:1958
+#, c-format
+msgid "%s: reloc %s:%d not in csect"
+msgstr "%s: omlokaliseringen %s:%d är inte i csect"
+
+#: xcofflink.c:2095
+#, c-format
+msgid "%s: XCOFF shared object when not producing XCOFF output"
+msgstr "%s: XCOFF delade objekt när inte XCOFF-utdata produceras"
+
+#: xcofflink.c:2116
+#, c-format
+msgid "%s: dynamic object with no .loader section"
+msgstr "%s: dynamiskt objekt utan någon .loader-sektion"
+
+#: xcofflink.c:2761
+#, c-format
+msgid "%s: no such symbol"
+msgstr "%s: ingen sådan symbol"
+
+#: xcofflink.c:2894
+msgid "error: undefined symbol __rtinit"
+msgstr "fel: odefinierad symbol __rtinit"
+
+#: xcofflink.c:3455
+#, c-format
+msgid "warning: attempt to export undefined symbol `%s'"
+msgstr "varning: försök att exportera odefinierade symbolen \"%s\""
+
+#: xcofflink.c:4448
+#, c-format
+msgid "TOC overflow: 0x%lx > 0x10000; try -mminimal-toc when compiling"
+msgstr "TOC ger överspill: 0x%lx > 0x10000; prova -mminimal-toc vid kompilering"
+
+#: xcofflink.c:5288 xcofflink.c:5755 xcofflink.c:5817 xcofflink.c:6119
+#, c-format
+msgid "%s: loader reloc in unrecognized section `%s'"
+msgstr "%s: inläsaromlokalisering i okända sektionen \"%s\""
+
+#: xcofflink.c:5310 xcofflink.c:6130
+#, c-format
+msgid "%s: `%s' in loader reloc but not loader sym"
+msgstr "%s: \"%s\" i inläsaromlokalisering men inte inläsarsym"
+
+#: xcofflink.c:5325
+#, c-format
+msgid "%s: loader reloc in read-only section %s"
+msgstr "%s: inläsaromlokalisering i skrivskyddade sektionen %s"
+
+#: elf32-ia64.c:2392 elf64-ia64.c:2392
+msgid "@pltoff reloc against local symbol"
+msgstr "@pltoff-omlokalisering mot lokal symbol"
+
+#: elf32-ia64.c:3804 elf64-ia64.c:3804
+#, c-format
+msgid "%s: short data segment overflowed (0x%lx >= 0x400000)"
+msgstr "%s: kort datasegment spillde över (0x%lx >= 0x400000)"
+
+#: elf32-ia64.c:3815 elf64-ia64.c:3815
+#, c-format
+msgid "%s: __gp does not cover short data segment"
+msgstr "%s: __gp täcker inte kort datasegment"
+
+#: elf32-ia64.c:4131 elf64-ia64.c:4131
+#, c-format
+msgid "%s: linking non-pic code in a shared library"
+msgstr "%s: länkar icke-pic-kod i delat bibliotek"
+
+#: elf32-ia64.c:4164 elf64-ia64.c:4164
+#, c-format
+msgid "%s: @gprel relocation against dynamic symbol %s"
+msgstr "%s: @gprel-omlokalisering mot dynamiska symbolen %s"
+
+#: elf32-ia64.c:4224 elf64-ia64.c:4224
+#, c-format
+msgid "%s: linking non-pic code in a position independent executable"
+msgstr "%s: länkar icke-pic-kod i en positionsoberoende körbar fil"
+
+#: elf32-ia64.c:4363 elf64-ia64.c:4363
+#, c-format
+msgid "%s: @internal branch to dynamic symbol %s"
+msgstr "%s: @internal-gren till dynamiska symbolen %s"
+
+#: elf32-ia64.c:4365 elf64-ia64.c:4365
+#, c-format
+msgid "%s: speculation fixup to dynamic symbol %s"
+msgstr "%s: spekulationsfix till dynamiska symbolen %s"
+
+#: elf32-ia64.c:4367 elf64-ia64.c:4367
+#, c-format
+msgid "%s: @pcrel relocation against dynamic symbol %s"
+msgstr "%s: @pcrel-omlokalisering mot dynamiska symbolen %s"
+
+#: elf32-ia64.c:4579 elf64-ia64.c:4579
+msgid "unsupported reloc"
+msgstr "omlokaliseringen stöds inte"
+
+#: elf32-ia64.c:4858 elf64-ia64.c:4858
+#, c-format
+msgid "%s: linking trap-on-NULL-dereference with non-trapping files"
+msgstr "%s: länkar fånga-vid-NULL-dereferens med ickefångande filer"
+
+#: elf32-ia64.c:4867 elf64-ia64.c:4867
+#, c-format
+msgid "%s: linking big-endian files with little-endian files"
+msgstr "%s: länkar big endian-filer med little endian-filer"
+
+#: elf32-ia64.c:4876 elf64-ia64.c:4876
+#, c-format
+msgid "%s: linking 64-bit files with 32-bit files"
+msgstr "%s: länkar 64-bitarsfiler med 32-bitarsfiler"
+
+#: elf32-ia64.c:4885 elf64-ia64.c:4885
+#, c-format
+msgid "%s: linking constant-gp files with non-constant-gp files"
+msgstr "%s: länkar konstant-gp-filer med icke-konstant-gp-filer"
+
+#: elf32-ia64.c:4895 elf64-ia64.c:4895
+#, c-format
+msgid "%s: linking auto-pic files with non-auto-pic files"
+msgstr "%s: länkar auto-pic-filer med icke-auto-pic-filer"
+
+#: peigen.c:985 pepigen.c:985
+#, c-format
+msgid "%s: line number overflow: 0x%lx > 0xffff"
+msgstr "%s: radnummer ger överspill: 0x%lx > 0xffff"
+
+#: peigen.c:1002 pepigen.c:1002
+#, c-format
+msgid "%s: reloc overflow 1: 0x%lx > 0xffff"
+msgstr "%s: omlokalisering ger överspill 1: 0x%lx > 0xffff"
+
+#: peigen.c:1016 pepigen.c:1016
+msgid "Export Directory [.edata (or where ever we found it)]"
+msgstr "Exportkatalog [.edata (eller där vi hittade det)]"
+
+#: peigen.c:1017 pepigen.c:1017
+msgid "Import Directory [parts of .idata]"
+msgstr "Importkatalog [delar av .idata]"
+
+#: peigen.c:1018 pepigen.c:1018
+msgid "Resource Directory [.rsrc]"
+msgstr "Resurskatalog [.rsrc]"
+
+#: peigen.c:1019 pepigen.c:1019
+msgid "Exception Directory [.pdata]"
+msgstr "Undantagskatalog [.pdata]"
+
+#: peigen.c:1020 pepigen.c:1020
+msgid "Security Directory"
+msgstr "Säkerhetskatalog"
+
+#: peigen.c:1021 pepigen.c:1021
+msgid "Base Relocation Directory [.reloc]"
+msgstr "Basomlokaliseringskatalog [.reloc]"
+
+#: peigen.c:1022 pepigen.c:1022
+msgid "Debug Directory"
+msgstr "Felsökningskatalog"
+
+#: peigen.c:1023 pepigen.c:1023
+msgid "Description Directory"
+msgstr "Beskrivningskatalog"
+
+#: peigen.c:1024 pepigen.c:1024
+msgid "Special Directory"
+msgstr "Specialkatalog"
+
+#: peigen.c:1025 pepigen.c:1025
+msgid "Thread Storage Directory [.tls]"
+msgstr "Trådlagringskatalog [.tls]"
+
+#: peigen.c:1026 pepigen.c:1026
+msgid "Load Configuration Directory"
+msgstr "Inläsningskonfigurationskatalog"
+
+#: peigen.c:1027 pepigen.c:1027
+msgid "Bound Import Directory"
+msgstr "Katalog över bundna importer"
+
+#: peigen.c:1028 pepigen.c:1028
+msgid "Import Address Table Directory"
+msgstr "Importadresstabellkatalog"
+
+#: peigen.c:1029 pepigen.c:1029
+msgid "Delay Import Directory"
+msgstr "Katalog över fördröjda importer"
+
+#: peigen.c:1030 peigen.c:1031 pepigen.c:1030 pepigen.c:1031
+msgid "Reserved"
+msgstr "Reserverad"
+
+#: peigen.c:1094 pepigen.c:1094
+msgid ""
+"\n"
+"There is an import table, but the section containing it could not be found\n"
+msgstr ""
+"\n"
+"Det finns en importtabell, men sektionen som innehåller den kunde inte hittas\n"
+
+#: peigen.c:1099 pepigen.c:1099
+#, c-format
+msgid ""
+"\n"
+"There is an import table in %s at 0x%lx\n"
+msgstr ""
+"\n"
+"Det finns en importtabell i %s på 0x%lx\n"
+
+#: peigen.c:1136 pepigen.c:1136
+#, c-format
+msgid ""
+"\n"
+"Function descriptor located at the start address: %04lx\n"
+msgstr ""
+"\n"
+"Funktionsidentifierare hittad på startadressen: %04lx\n"
+
+#: peigen.c:1139 pepigen.c:1139
+#, c-format
+msgid "\tcode-base %08lx toc (loadable/actual) %08lx/%08lx\n"
+msgstr "\tkodbas %08lx toc (inläsningsbar/verklig) %08lx/%08lx\n"
+
+#: peigen.c:1145 pepigen.c:1145
+msgid ""
+"\n"
+"No reldata section! Function descriptor not decoded.\n"
+msgstr ""
+"\n"
+"Ingen reldata-sektion! Funktionsidentifierare avkodades inte.\n"
+
+#: peigen.c:1150 pepigen.c:1150
+#, c-format
+msgid ""
+"\n"
+"The Import Tables (interpreted %s section contents)\n"
+msgstr ""
+"\n"
+"Importtabellerna (tolkade innehåll i %s-sektion)\n"
+
+# Vad är thunk?
+#: peigen.c:1153 pepigen.c:1153
+msgid ""
+" vma: Hint Time Forward DLL First\n"
+" Table Stamp Chain Name Thunk\n"
+msgstr ""
+" vma: Tips- Tids- Framåt- DLL- Första\n"
+" tabell stämpel kedja namn thunk\n"
+
+#: peigen.c:1204 pepigen.c:1204
+#, c-format
+msgid ""
+"\n"
+"\tDLL Name: %s\n"
+msgstr ""
+"\n"
+"\tDLL-namn: %s\n"
+
+#: peigen.c:1215 pepigen.c:1215
+msgid "\tvma: Hint/Ord Member-Name Bound-To\n"
+msgstr "\tvma: Tips/Ordn Medlemsnamn Bundet till\n"
+
+#: peigen.c:1240 pepigen.c:1240
+msgid ""
+"\n"
+"There is a first thunk, but the section containing it could not be found\n"
+msgstr ""
+"\n"
+"Det finns en första thunk, men sektionen som innehåller den kunde inte hittas\n"
+
+#: peigen.c:1380 pepigen.c:1380
+msgid ""
+"\n"
+"There is an export table, but the section containing it could not be found\n"
+msgstr ""
+"\n"
+"Det finns en exporttabell, men sektionen som innehåller den kunde inte hittas\n"
+
+#: peigen.c:1385 pepigen.c:1385
+#, c-format
+msgid ""
+"\n"
+"There is an export table in %s at 0x%lx\n"
+msgstr ""
+"\n"
+"Det finns en exporttabell i %s vid 0x%lx\n"
+
+#: peigen.c:1416 pepigen.c:1416
+#, c-format
+msgid ""
+"\n"
+"The Export Tables (interpreted %s section contents)\n"
+"\n"
+msgstr ""
+"\n"
+"Exporttabellerna (tolkade innehåll i %s-sektion)\n"
+
+#: peigen.c:1420 pepigen.c:1420
+#, c-format
+msgid "Export Flags \t\t\t%lx\n"
+msgstr "Exportflaggor \t\t\t%lx\n"
+
+#: peigen.c:1423 pepigen.c:1423
+#, c-format
+msgid "Time/Date stamp \t\t%lx\n"
+msgstr "Tid-/Datumstämpel \t\t%lx\n"
+
+#: peigen.c:1426 pepigen.c:1426
+#, c-format
+msgid "Major/Minor \t\t\t%d/%d\n"
+msgstr "Övre/Undre \t\t\t%d/%d\n"
+
+#: peigen.c:1429 pepigen.c:1429
+msgid "Name \t\t\t\t"
+msgstr "Namn \t\t\t\t"
+
+#: peigen.c:1435 pepigen.c:1435
+#, c-format
+msgid "Ordinal Base \t\t\t%ld\n"
+msgstr "Ordningsbas \t\t\t%ld\n"
+
+#: peigen.c:1438 pepigen.c:1438
+msgid "Number in:\n"
+msgstr "Tal i:\n"
+
+#: peigen.c:1441 pepigen.c:1441
+#, c-format
+msgid "\tExport Address Table \t\t%08lx\n"
+msgstr "\tExportadresstabell \t\t%08lx\n"
+
+#: peigen.c:1445 pepigen.c:1445
+#, c-format
+msgid "\t[Name Pointer/Ordinal] Table\t%08lx\n"
+msgstr "\t[Namnpekare/Ordningstal]-tabell\t%08lx\n"
+
+#: peigen.c:1448 pepigen.c:1448
+msgid "Table Addresses\n"
+msgstr "Tabelladresser\n"
+
+#: peigen.c:1451 pepigen.c:1451
+msgid "\tExport Address Table \t\t"
+msgstr "\tExportadresstabell \t\t"
+
+#: peigen.c:1456 pepigen.c:1456
+msgid "\tName Pointer Table \t\t"
+msgstr "\tNamnpekartabell \t\t"
+
+#: peigen.c:1461 pepigen.c:1461
+msgid "\tOrdinal Table \t\t\t"
+msgstr "\tOrdningstalstabell \t\t\t"
+
+#: peigen.c:1476 pepigen.c:1476
+#, c-format
+msgid ""
+"\n"
+"Export Address Table -- Ordinal Base %ld\n"
+msgstr ""
+"\n"
+"Exportadresstabell -- Orningsbas %ld\n"
+
+#: peigen.c:1495 pepigen.c:1495
+msgid "Forwarder RVA"
+msgstr "Vidarebefordrar-RVA"
+
+#: peigen.c:1506 pepigen.c:1506
+msgid "Export RVA"
+msgstr "Export-RVA"
+
+#: peigen.c:1513 pepigen.c:1513
+msgid ""
+"\n"
+"[Ordinal/Name Pointer] Table\n"
+msgstr ""
+"\n"
+"[Ordningstals-/Namnpekar-]tabell\n"
+
+#: peigen.c:1568 pepigen.c:1568
+#, c-format
+msgid "Warning, .pdata section size (%ld) is not a multiple of %d\n"
+msgstr "Varning, storleken på .pdata-sektionen (%ld) är inte en multipel av %d\n"
+
+#: peigen.c:1572 pepigen.c:1572
+msgid ""
+"\n"
+"The Function Table (interpreted .pdata section contents)\n"
+msgstr ""
+"\n"
+"Funktionstabellen (tolkade innehåll från .pdata-sektionen)\n"
+
+#: peigen.c:1575 pepigen.c:1575
+msgid " vma:\t\t\tBegin Address End Address Unwind Info\n"
+msgstr " vma:\t\t\tStartadress Slutadress Ospola information\n"
+
+#: peigen.c:1577 pepigen.c:1577
+msgid ""
+" vma:\t\tBegin End EH EH PrologEnd Exception\n"
+" \t\tAddress Address Handler Data Address Mask\n"
+msgstr ""
+" vma:\t\tStart- Slut- EH- EH- Prologsluts- Undantags-\n"
+" \t\tadress adress hanterare data adress mask\n"
+
+#: peigen.c:1647 pepigen.c:1647
+msgid " Register save millicode"
+msgstr " Registerspara millikod"
+
+#: peigen.c:1650 pepigen.c:1650
+msgid " Register restore millicode"
+msgstr " Registeråterställ millikod"
+
+#: peigen.c:1653 pepigen.c:1653
+msgid " Glue code sequence"
+msgstr " Klisterkodsekvens"
+
+#: peigen.c:1705 pepigen.c:1705
+msgid ""
+"\n"
+"\n"
+"PE File Base Relocations (interpreted .reloc section contents)\n"
+msgstr ""
+"\n"
+"\n"
+"PE-filbasomlokaliseringar (tolkat innehåll i .reloc-sektionen)\n"
+
+#: peigen.c:1735 pepigen.c:1735
+#, c-format
+msgid ""
+"\n"
+"Virtual Address: %08lx Chunk size %ld (0x%lx) Number of fixups %ld\n"
+msgstr ""
+"\n"
+"Virtuell adress: %08lx Områdesstorlek %ld (0x%lx) Antal fixar %ld\n"
+
+#: peigen.c:1748 pepigen.c:1748
+#, c-format
+msgid "\treloc %4d offset %4x [%4lx] %s"
+msgstr "\tomlokalisering %4d avstånd %4x [%4lx] %s"
+
+#. The MS dumpbin program reportedly ands with 0xff0f before
+#. printing the characteristics field. Not sure why. No reason to
+#. emulate it here.
+#: peigen.c:1788 pepigen.c:1788
+#, c-format
+msgid ""
+"\n"
+"Characteristics 0x%x\n"
+msgstr ""
+"\n"
+"Karakteristik 0x%x\n"
+
+#~ msgid "%s: Unknown special linker type %d"
+#~ msgstr "%s: Okänd speciallänkartyp %d"
+
+#~ msgid "v850ea architecture"
+#~ msgstr "v850ea-arkitektur"
+
+#~ msgid "%s: Section %s is too large to add hole of %ld bytes"
+#~ msgstr "%s: Sektionen %s är för stor för att stoppa hål med %ld byte i"
+
+#~ msgid "Error: out of memory"
+#~ msgstr "Fel: slut på minne"
+
+#~ msgid "warning: relocation against removed section; zeroing"
+#~ msgstr "varning: omlokalisering mot borttagen sektion; nollställer"
+
+#~ msgid "warning: relocation against removed section"
+#~ msgstr "varning: omlokalisering mot borttagen sektion"
+
+#~ msgid "local symbols in discarded section %s"
+#~ msgstr "lokala symboler i bortkastade sektionen %s"
+
+#~ msgid "%s: linking abicalls files with non-abicalls files"
+#~ msgstr "%s: länkar abicalls-filer med icke-abicalls-filer"
+
+#~ msgid "%s: ISA mismatch (-mips%d) with previous modules (-mips%d)"
+#~ msgstr "%s: ISA (-mips%d) passar inte med tidigare moduler (-mips%d)"
+
+#~ msgid "%s: ISA mismatch (%d) with previous modules (%d)"
+#~ msgstr "%s: ISA (%d) passar inte med tidigare moduler (%d)"
+
+#~ msgid "%s: dynamic relocation against speculation fixup"
+#~ msgstr "%s: dynamisk omlokalisering utan spekulationsfixar"
+
+#~ msgid "%s: speculation fixup against undefined weak symbol"
+#~ msgstr "%s: spekulationsfix mot odefinierad svag symbol"
+
+#~ msgid "\tThe Import Address Table (difference found)\n"
+#~ msgstr "\tImportadresstabellen (skillnad hittad)\n"
+
+#~ msgid "\t>>> Ran out of IAT members!\n"
+#~ msgstr "\t>>> Slut på IAT-medlemmar!\n"
+
+#~ msgid "\tThe Import Address Table is identical\n"
+#~ msgstr "\tImportadresstabellen är identisk\n"
+
+# Ska vara blanksteg här tror jag
+#~ msgid "BFD %sinternal error, aborting at %s line %d\n"
+#~ msgstr "Internt BFD %s-fel, avbryter vid %s rad %d\n"
+
+#~ msgid "GP relative relocation when GP not defined"
+#~ msgstr "GP-relativ omlokalisering då GP inte är definierad"
+
+#~ msgid "%s: ERROR: passes floats in float registers whereas target %s uses integer registers"
+#~ msgstr "%s: FEL: skickar flyttal i flyttalsregister där målet %s istället använder heltalsregister"
+
+#~ msgid "%s: ERROR: passes floats in integer registers whereas target %s uses float registers"
+#~ msgstr "%s: FEL: skickar flyttal i heltalsregister där målet %s istället använder flyttalsregister"
+
+#~ msgid "Warning: input file %s supports interworking, whereas %s does not."
+#~ msgstr "Varning: indatafilen %s stöder samverkande, medan %s däremot inte gör det."
+
+#~ msgid "Warning: input file %s does not support interworking, whereas %s does."
+#~ msgstr "Varning: indatafilen %s stöder inte samverkande, medan %s däremot gör det."
+
+#~ msgid "AUX tagndx %ld ttlsiz 0x%lx lnnos %ld next %ld"
+#~ msgstr "AUX tagndx %ld ttlsiz 0x%lx radnummer %ld nästa %ld"
+
+#~ msgid "elf_symbol_from_bfd_symbol 0x%.8lx, name = %s, sym num = %d, flags = 0x%.8lx%s\n"
+#~ msgstr "elf_symbol_from_bfd_symbol 0x%.8lx, namn = %s, symbolnr = %d, flaggor = 0x%.8lx%s\n"
+
+#~ msgid "Warning: Not setting interwork flag of %s since it has already been specified as non-interworking"
+#~ msgstr "Varning: Ställer inte in samverkandeflaggan för %s eftersom den redan har angivits som inte samverkande"
+
+#~ msgid "Warning: Clearing the interwork flag of %s due to outside request"
+#~ msgstr "Varning: Stänger av samverkandeflaggan för %s på grund av utomstående begäran"
+
+#~ msgid " [APCS-26]"
+#~ msgstr " [APCS-26]"
+
+#~ msgid " [APCS-32]"
+#~ msgstr " [APCS-32]"
+
+#~ msgid "(unknown)"
+#~ msgstr "(okänd)"
+
+# Skumt!
+#~ msgid " previously %s in %s"
+#~ msgstr " tidigare %s i %s"
+
+#~ msgid "Symbol `%s' has differing types: %s in %s"
+#~ msgstr "Symbolen \"%s\" har olika typer: %s i %s"
+
+# Alla dessa känns onödiga, borde rapporteras
+#~ msgid "ETIR_S_C_STO_GBL: no symbol \"%s\""
+#~ msgstr "ETIR_S_C_STO_GBL: ingen symbol \"%s\""
+
+#~ msgid "ETIR_S_C_STO_CA: no symbol \"%s\""
+#~ msgstr "ETIR_S_C_STO_CA: ingen symbol \"%s\""
+
+#~ msgid "ETIR_S_C_STO_RB/AB: Not supported"
+#~ msgstr "ETIR_S_C_STO_RB/AB: Stöds inte"
+
+#~ msgid "ETIR_S_C_STO_LP_PSB: Not supported"
+#~ msgstr "ETIR_S_C_STO_LP_PSB: Stöds inte"
+
+#~ msgid "ETIR_S_C_STO_HINT_GBL: not implemented"
+#~ msgstr "ETIR_S_C_STO_HINT_GBL: inte implementerat"
+
+#~ msgid "ETIR_S_C_STO_HINT_PS: not implemented"
+#~ msgstr "ETIR_S_C_STO_HINT_PS: inte implementerat"
+
+#~ msgid "ETIR_S_C_OPR_INSV: Not supported"
+#~ msgstr "ETIR_S_C_OPR_INSV: Stöds inte"
+
+#~ msgid "ETIR_S_C_OPR_USH: Not supported"
+#~ msgstr "ETIR_S_C_OPR_USH: Stöds inte"
+
+#~ msgid "ETIR_S_C_OPR_ROT: Not supported"
+#~ msgstr "ETIR_S_C_OPR_ROT: Stöds inte"
+
+#~ msgid "ETIR_S_C_OPR_REDEF: Not supported"
+#~ msgstr "ETIR_S_C_OPR_REDEF: Stöds inte"
+
+#~ msgid "ETIR_S_C_OPR_DFLIT: Not supported"
+#~ msgstr "ETIR_S_C_OPR_DFLIT: Stöds inte"
+
+#~ msgid "ETIR_S_C_STC_LP: not supported"
+#~ msgstr "ETIR_S_C_STC_LP: stöds inte"
+
+#~ msgid "ETIR_S_C_STC_GBL: not supported"
+#~ msgstr "ETIR_S_C_STC_GBL: stöds inte"
+
+#~ msgid "ETIR_S_C_STC_GCA: not supported"
+#~ msgstr "ETIR_S_C_STC_GCA: stöds inte"
+
+#~ msgid "ETIR_S_C_STC_PS: not supported"
+#~ msgstr "ETIR_S_C_STC_PS: stöds inte"
+
+#~ msgid "Unimplemented STO cmd %d"
+#~ msgstr "Oimplementerat STO-kommando %d"
+
+#~ msgid "TIR_S_C_OPR_ASH incomplete"
+#~ msgstr "TIR_S_C_OPR_ASH ofullständigt"
+
+#~ msgid "TIR_S_C_OPR_USH incomplete"
+#~ msgstr "TIR_S_C_OPR_USH ofullständigt"
+
+#~ msgid "TIR_S_C_OPR_ROT incomplete"
+#~ msgstr "TIR_S_C_OPR_ROT ofullständigt"
+
+#~ msgid "TIR_S_C_OPR_REDEF not supported"
+#~ msgstr "TIR_S_C_OPR_REDEF stöds inte"
+
+#~ msgid "TIR_S_C_OPR_DFLIT not supported"
+#~ msgstr "TIR_S_C_OPR_DFLIT stöds inte"
+
+#~ msgid "TIR_S_C_CTL_DFLOC not fully implemented"
+#~ msgstr "TIR_S_C_CTL_DFLOC är inte fullständigt implementerat"
+
+#~ msgid "TIR_S_C_CTL_STLOC not fully implemented"
+#~ msgstr "TIR_S_C_CTL_STLOC är inte fullständigt implementerat"
+
+#~ msgid "TIR_S_C_CTL_STKDL not fully implemented"
+#~ msgstr "TIR_S_C_CTL_STKDL är inte fulständigt implementerat"
+
+# This is broken
+#
+# fprintf (file,
+# _("\nThe Import Tables (interpreted %s section contents)\n"),
+# section->name);
+# fprintf (file,
+# _(" vma: Hint Time Forward DLL First\n"));
+# fprintf (file,
+# _(" Table Stamp Chain Name Thunk\n"));
+#
+#~ msgid " vma: Hint Time Forward DLL First\n"
+#~ msgstr " vma: Tips- Tids- V.bef.- DLL- Första\n"
+
+#~ msgid " \t\tAddress Address Handler Data Address Mask\n"
+#~ msgstr " \t\tadress adress hanterare data adress mask\n"
+
+#~ msgid "integer"
+#~ msgstr "heltal"
+
+#~ msgid "float"
+#~ msgstr "flyttal"
+
+#~ msgid "soft"
+#~ msgstr "mjuk"
+
+#~ msgid "hard"
+#~ msgstr "hård"
+
+# _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"));
+#
+# This is broken
+#
+# Don't split a sentence like this, use multiple full messages instead
+#
+#~ msgid "Warning: %s %s interworking, whereas %s %s"
+#~ msgstr "Varning: %s %s samverkande, medan %s %s"
+
+#~ msgid "supports"
+#~ msgstr "stöder"
+
+#~ msgid "does not"
+#~ msgstr "inte gör det"
+
+#~ msgid "does"
+#~ msgstr "gör det"
+
+#~ msgid "%s(%s+0x%lx): cannot find stub entry %s"
+#~ msgstr "%s(%s+0x%lx): kan inte hitta stubbstarten %s"
+
+#~ msgid "%s(%s+0x%lx): cannot relocate %s, recompile with -ffunction-sections"
+#~ msgstr "%s(%s+0x%lx): kan inte omlokalisera %s, kompilera om med -ffunction-sections"
+
+#~ msgid "creating section symbol, name = %s, value = 0x%.8lx, index = %d, section = 0x%.8lx\n"
+#~ msgstr "skapar sektionssymbol, namn = %s, värde = 0x%.8lx, index = %d, sektion = 0x%.8lx\n"
+
+# Hmm
+#~ msgid " whereas segment starts at 0x%x"
+#~ msgstr " där segmentet börjar vid 0x%x"
diff --git a/bfd/po/tr.gmo b/bfd/po/tr.gmo
new file mode 100644
index 0000000..74c0ea8
--- /dev/null
+++ b/bfd/po/tr.gmo
Binary files differ
diff --git a/bfd/po/tr.po b/bfd/po/tr.po
new file mode 100644
index 0000000..11630c6
--- /dev/null
+++ b/bfd/po/tr.po
@@ -0,0 +1,3193 @@
+# translation of bfd-2.14rel030712.tr.po to Turkish
+# Copyright (C) 2003 Free Software Foundation, Inc.
+# Deniz Akkus Kanca <deniz@arayan.com>, 2001,2003.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: bfd 2.14rel030712\n"
+"POT-Creation-Date: 2003-07-11 13:53+0930\n"
+"PO-Revision-Date: 2003-07-13 22:07+0300\n"
+"Last-Translator: Deniz Akkus Kanca <deniz@arayan.com>\n"
+"Language-Team: Turkish <gnu-tr-u12a@lists.sourceforge.net>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Generator: KBabel 1.0\n"
+
+#: aout-adobe.c:204
+#, c-format
+msgid "%s: Unknown section type in a.out.adobe file: %x\n"
+msgstr "%s: a.out.adobe dosyasında bilinmeyen bölüm türü: %x\n"
+
+#: aout-cris.c:207
+#, c-format
+msgid "%s: Invalid relocation type exported: %d"
+msgstr "%s: Geçersiz yer değiştirme türü ihraç edilmiş: %d"
+
+#: aout-cris.c:251
+#, c-format
+msgid "%s: Invalid relocation type imported: %d"
+msgstr "%s: Geçersiz yer değiştirme türü ithal edilmiş: %d"
+
+#: aout-cris.c:262
+#, c-format
+msgid "%s: Bad relocation record imported: %d"
+msgstr "%s: Geçersiz yer değiştirme kaydı ithal edilmiş: %d"
+
+#: aoutx.h:1295 aoutx.h:1716
+#, c-format
+msgid "%s: can not represent section `%s' in a.out object file format"
+msgstr "%s: `%s' bölümü a.out nesne dosya biçeminde gösterilemez"
+
+#: aoutx.h:1682
+#, c-format
+msgid "%s: can not represent section for symbol `%s' in a.out object file format"
+msgstr "%s: `%s' sembol bölümü a.out nesne dosyasında gösterilemez"
+
+#: aoutx.h:1684
+msgid "*unknown*"
+msgstr "*bilinmeyen*"
+
+#: aoutx.h:3776
+#, c-format
+msgid "%s: relocatable link from %s to %s not supported"
+msgstr "%s: %s'dan %s'ya yeri deÄŸiÅŸtirilebilen baÄŸ desteklenmiyor"
+
+#: archive.c:1751
+msgid "Warning: writing archive was slow: rewriting timestamp\n"
+msgstr "Uyarı: arşiv yazma işlemi yavaş: zaman damgası yeniden yazılıyor\n"
+
+#: archive.c:2014
+msgid "Reading archive file mod timestamp"
+msgstr "Arşiv dosyası değişim zaman damgası okunuyor"
+
+#: archive.c:2040
+msgid "Writing updated armap timestamp"
+msgstr "Güncellenmiş armap zaman damgası yazılıyor"
+
+#: bfd.c:280
+msgid "No error"
+msgstr "Hata yok"
+
+#: bfd.c:281
+msgid "System call error"
+msgstr "Sistem çağrı hatası"
+
+#: bfd.c:282
+msgid "Invalid bfd target"
+msgstr "Geçersiz bfd hedefi"
+
+#: bfd.c:283
+msgid "File in wrong format"
+msgstr "Dosya yanlış biçemde"
+
+#: bfd.c:284
+msgid "Archive object file in wrong format"
+msgstr "Arşiv nesne dosyası yanlış biçemde"
+
+#: bfd.c:285
+msgid "Invalid operation"
+msgstr "Geçersiz işlem"
+
+#: bfd.c:286
+msgid "Memory exhausted"
+msgstr "Bellek tükendi"
+
+#: bfd.c:287
+msgid "No symbols"
+msgstr "Sembol yok"
+
+#: bfd.c:288
+msgid "Archive has no index; run ranlib to add one"
+msgstr "Arşivin indeksi yok; ranlib çalıştırarak indeks ekleyin"
+
+#: bfd.c:289
+msgid "No more archived files"
+msgstr "BaÅŸka arÅŸivlenmiÅŸ dosya yok"
+
+#: bfd.c:290
+msgid "Malformed archive"
+msgstr "Bozuk arÅŸiv"
+
+#: bfd.c:291
+msgid "File format not recognized"
+msgstr "Dosya biçemi tanınmıyor"
+
+#: bfd.c:292
+msgid "File format is ambiguous"
+msgstr "Dosya biçemi belirsiz"
+
+#: bfd.c:293
+msgid "Section has no contents"
+msgstr "Bölümde içerik yok"
+
+#: bfd.c:294
+msgid "Nonrepresentable section on output"
+msgstr "Çıktıda gösterilemeyen bölüm"
+
+#: bfd.c:295
+msgid "Symbol needs debug section which does not exist"
+msgstr "Sembol, olmayan hata ayıklama bölümünü istiyor"
+
+#: bfd.c:296
+msgid "Bad value"
+msgstr "Geçersiz değer"
+
+#: bfd.c:297
+msgid "File truncated"
+msgstr "Dosya budandı"
+
+#: bfd.c:298
+msgid "File too big"
+msgstr "Dosya fazla büyük"
+
+#: bfd.c:299
+msgid "#<Invalid error code>"
+msgstr "#<Geçersiz hata kodu>"
+
+#: bfd.c:687
+#, c-format
+msgid "BFD %s assertion fail %s:%d"
+msgstr "BFD %s, olumlama başarısız %s:%d"
+
+#: bfd.c:703
+#, c-format
+msgid "BFD %s internal error, aborting at %s line %d in %s\n"
+msgstr "BFD %s iç hatası, %s'da, %d satırı, %s içerisinde işlem durduruldu\n"
+
+#: bfd.c:707
+#, c-format
+msgid "BFD %s internal error, aborting at %s line %d\n"
+msgstr "BFD %s iç hatası, %s, %d satırında işlem durduruldu\n"
+
+#: bfd.c:709
+msgid "Please report this bug.\n"
+msgstr "Lütfen bu hatayı bildirin.\n"
+
+#: bfdwin.c:202
+#, c-format
+msgid "not mapping: data=%lx mapped=%d\n"
+msgstr "eÅŸlenmeyen: veri=%lx eÅŸleÅŸen=%d\n"
+
+#: bfdwin.c:205
+msgid "not mapping: env var not set\n"
+msgstr "eşlenmeyen: çevre değişkeni atanmamış\n"
+
+#: binary.c:306
+#, c-format
+msgid "Warning: Writing section `%s' to huge (ie negative) file offset 0x%lx."
+msgstr "Uyarı: `%s' bölümü çok büyük (negatif) dosya göreli konumu 0x%lx'e yazılıyor."
+
+#: coff-a29k.c:120
+msgid "Missing IHCONST"
+msgstr "IHCONST yok"
+
+#: coff-a29k.c:181
+msgid "Missing IHIHALF"
+msgstr "IHIHALF yok"
+
+#: coff-a29k.c:213 coff-or32.c:236
+msgid "Unrecognized reloc"
+msgstr "Tanınmayan yer değiştirme"
+
+#: coff-a29k.c:409
+msgid "missing IHCONST reloc"
+msgstr "eksik IHCONST yer deÄŸiÅŸtirmesi"
+
+#: coff-a29k.c:499
+msgid "missing IHIHALF reloc"
+msgstr "eksik IHIHALF yer deÄŸiÅŸtirmesi"
+
+#: coff-alpha.c:884 coff-alpha.c:921 coff-alpha.c:1992 coff-mips.c:1397
+msgid "GP relative relocation used when GP not defined"
+msgstr "GP tanımlanmamışken GP göreli yer değiştirmesi kullanılmış"
+
+#: coff-alpha.c:1488
+msgid "using multiple gp values"
+msgstr "birden fazla gp değeri kullanılıyor"
+
+#: coff-arm.c:1066 elf32-arm.h:294
+#, c-format
+msgid "%s: unable to find THUMB glue '%s' for `%s'"
+msgstr "%1$s: `%3$s' için THUMB birleştiricisi '%2$s' bulunamadı "
+
+#: coff-arm.c:1096 elf32-arm.h:329
+#, c-format
+msgid "%s: unable to find ARM glue '%s' for `%s'"
+msgstr "%1$s: `%3$s' için ARM birleştiricisi '%2$s' bulunamadı"
+
+#: coff-arm.c:1394 coff-arm.c:1489 elf32-arm.h:892 elf32-arm.h:999
+#, c-format
+msgid "%s(%s): warning: interworking not enabled."
+msgstr "%s(%s): uyarı: beraber çalışma kipi etkin değil."
+
+#: coff-arm.c:1398 elf32-arm.h:1002
+#, c-format
+msgid " first occurrence: %s: arm call to thumb"
+msgstr " ilk ortaya çıkış: %s: thumb'a arm'dan çağrı"
+
+#: coff-arm.c:1493 elf32-arm.h:895
+#, c-format
+msgid " first occurrence: %s: thumb call to arm"
+msgstr " ilk ortaya çıkış: %s: arm'a thumb'dan çağrı"
+
+#: coff-arm.c:1496
+msgid " consider relinking with --support-old-code enabled"
+msgstr " --support-old-code seçeneği ile yeniden bağlamayı deneyin"
+
+#: coff-arm.c:1788 coff-tic80.c:687 cofflink.c:3038
+#, c-format
+msgid "%s: bad reloc address 0x%lx in section `%s'"
+msgstr "%1$s: `%3$s' bölümünde geçersiz yer değiştirme adresi 0x%2$lx"
+
+#: coff-arm.c:2132
+#, c-format
+msgid "%s: illegal symbol index in reloc: %d"
+msgstr "%s: yer değiştirmede geçersiz sembol indeksi: %d"
+
+#: coff-arm.c:2265
+#, c-format
+msgid "ERROR: %s is compiled for APCS-%d, whereas %s is compiled for APCS-%d"
+msgstr "Hata: %s APCS-%d için derlenmiş, fakat %s APCS-%d için derlenmiş"
+
+#: coff-arm.c:2280 elf32-arm.h:2328
+#, c-format
+msgid "ERROR: %s passes floats in float registers, whereas %s passes them in integer registers"
+msgstr ""
+"Hata: %s kayan sayıları kayan sayı yazmaçlarında geçiriyor, \n"
+" fakat %s tamsayı yazmaçlarında geçiriyor"
+
+#: coff-arm.c:2283 elf32-arm.h:2333
+#, c-format
+msgid "ERROR: %s passes floats in integer registers, whereas %s passes them in float registers"
+msgstr ""
+"Hata: %s kayan sayıları tamsayı yazmaçlarında geçiriyor, \n"
+" fakat %s kayan sayı yazmaçlarında geçiriyor"
+
+#: coff-arm.c:2298
+#, c-format
+msgid "ERROR: %s is compiled as position independent code, whereas target %s is absolute position"
+msgstr "HATA: %s yerden bağımsız kod olarak derlendi, fakat hedef %s yere bağımlı"
+
+#: coff-arm.c:2301
+#, c-format
+msgid "ERROR: %s is compiled as absolute position code, whereas target %s is position independent"
+msgstr "HATA: %s yere bağımlı kod olarak derlendi, fakat hedef %s yerden bağımsız"
+
+#: coff-arm.c:2330 elf32-arm.h:2405
+#, c-format
+msgid "Warning: %s supports interworking, whereas %s does not"
+msgstr "Uyarı: %s girdi dosyası beraber çalışmayı destekliyor, fakat %s desteklemiyor."
+
+#: coff-arm.c:2333 elf32-arm.h:2412
+#, c-format
+msgid "Warning: %s does not support interworking, whereas %s does"
+msgstr "Uyarı: %s girdi dosyası beraber çalışmayı desteklemiyor, fakat %s destekliyor."
+
+#: coff-arm.c:2360
+#, c-format
+msgid "private flags = %x:"
+msgstr "özel bayraklar = %x:"
+
+#: coff-arm.c:2368 elf32-arm.h:2467
+msgid " [floats passed in float registers]"
+msgstr " [kayan sayılar kayan yazmaçlarda geçirildi]"
+
+#: coff-arm.c:2370
+msgid " [floats passed in integer registers]"
+msgstr " [kayan sayılar tamsayı yazmaçlarda geçirildi]"
+
+#: coff-arm.c:2373 elf32-arm.h:2470
+msgid " [position independent]"
+msgstr " [yerden bağımsız]"
+
+#: coff-arm.c:2375
+msgid " [absolute position]"
+msgstr " [yere bağımlı]"
+
+#: coff-arm.c:2379
+msgid " [interworking flag not initialised]"
+msgstr " [beraber çalışma bayrağına öndeğer atanmamış]"
+
+#: coff-arm.c:2381
+msgid " [interworking supported]"
+msgstr " [beraber çalışma destekleniyor]"
+
+#: coff-arm.c:2383
+msgid " [interworking not supported]"
+msgstr " [beraber çalışma desteklenmiyor]"
+
+#: coff-arm.c:2431 elf32-arm.h:2150
+#, c-format
+msgid "Warning: Not setting interworking flag of %s since it has already been specified as non-interworking"
+msgstr "Uyarı: %s beraber çalışma bayrağı atanmadı, çünkü beraber çalışma olmayacağı önceden belirtilmiş"
+
+#: coff-arm.c:2435 elf32-arm.h:2154
+#, c-format
+msgid "Warning: Clearing the interworking flag of %s due to outside request"
+msgstr "Uyarı: %s beraber çalışma bayrağı dış istek üzerine temizlendi"
+
+#: coff-h8300.c:1096
+#, c-format
+msgid "cannot handle R_MEM_INDIRECT reloc when using %s output"
+msgstr "%s çıktısı kullanılırken R_MEM_INDIRECT yerdeğiştirmesi kullanılamıyor"
+
+#: coff-i960.c:137 coff-i960.c:486
+msgid "uncertain calling convention for non-COFF symbol"
+msgstr "COFF olmayan sembol için belirsiz çağrı davranışı"
+
+#: coff-m68k.c:482 coff-mips.c:2394 elf32-m68k.c:2193 elf32-mips.c:1783
+msgid "unsupported reloc type"
+msgstr "desteklenmeyen yer değiştirme türü"
+
+#: coff-mips.c:839 elf32-mips.c:1088 elf64-mips.c:1590 elfn32-mips.c:1554
+msgid "GP relative relocation when _gp not defined"
+msgstr "_gp tanımsız iken GP göreli yer değiştirmesi"
+
+#. No other sections should appear in -membedded-pic
+#. code.
+#: coff-mips.c:2431
+msgid "reloc against unsupported section"
+msgstr "desteklenmeyen bölümde yer değiştirme"
+
+#: coff-mips.c:2439
+msgid "reloc not properly aligned"
+msgstr "yer değiştirme doğru hizalanmamış"
+
+#: coff-rs6000.c:2790
+#, c-format
+msgid "%s: unsupported relocation type 0x%02x"
+msgstr "%s: desteklenmeyen yükleyici yerdeğişimi 0x%02x"
+
+#: coff-rs6000.c:2883
+#, c-format
+msgid "%s: TOC reloc at 0x%x to symbol `%s' with no TOC entry"
+msgstr "%s: 0x%x'da TOC girdisi olmayan `%s' sembolüne TOC yerdeğişimi"
+
+#: coff-rs6000.c:3616 coff64-rs6000.c:2109
+#, c-format
+msgid "%s: symbol `%s' has unrecognized smclas %d"
+msgstr "%s: `%s' sembolünde bilinmeyen %d var"
+
+#: coff-tic4x.c:170 coff-tic54x.c:288 coff-tic80.c:450
+#, c-format
+msgid "Unrecognized reloc type 0x%x"
+msgstr "Bilinmeyen yer değiştirme türü 0x%x"
+
+#: coff-tic4x.c:218 coff-tic54x.c:373 coffcode.h:5045
+#, c-format
+msgid "%s: warning: illegal symbol index %ld in relocs"
+msgstr "%s: uyarı: yer değiştirmelerde geçersiz sembol indeksi %ld"
+
+#: coff-w65.c:364
+#, c-format
+msgid "ignoring reloc %s\n"
+msgstr "yer değiştirme %s yoksayıldı\n"
+
+#: coffcode.h:1108
+#, c-format
+msgid "%s (%s): Section flag %s (0x%x) ignored"
+msgstr "%s (%s): Bölüm bayrağı %s (0x%x) yoksayıldı"
+
+#: coffcode.h:2214
+#, c-format
+msgid "Unrecognized TI COFF target id '0x%x'"
+msgstr "Tanınmayan TI COFF hedef kimliği '0x%x'"
+
+#: coffcode.h:4437
+#, c-format
+msgid "%s: warning: illegal symbol index %ld in line numbers"
+msgstr "%s: uyarı: satır numaralarında geçersiz sembol indeksi %ld"
+
+#: coffcode.h:4451
+#, c-format
+msgid "%s: warning: duplicate line number information for `%s'"
+msgstr "%s: uyarı: `%s' için tekrarlanmış satır numarası bilgisi"
+
+#: coffcode.h:4805
+#, c-format
+msgid "%s: Unrecognized storage class %d for %s symbol `%s'"
+msgstr "%1$s: %3$s sembolü `%4$s' için bilinmeyen saklama sınıfı %2$d"
+
+#: coffcode.h:4938
+#, c-format
+msgid "warning: %s: local symbol `%s' has no section"
+msgstr "uyarı: %s: `%s' yerel sembolünün bölümü yok"
+
+#: coffcode.h:5083
+#, c-format
+msgid "%s: illegal relocation type %d at address 0x%lx"
+msgstr "%1$s: 0x%3$lx adresinde geçersiz yer değiştirme türü %2$d"
+
+#: coffgen.c:1666
+#, c-format
+msgid "%s: bad string table size %lu"
+msgstr "%s: geçersiz dizge tablo boyu %lu"
+
+#: cofflink.c:538 elflink.h:1276
+#, c-format
+msgid "Warning: type of symbol `%s' changed from %d to %d in %s"
+msgstr "Uyarı: %4$s içerisinde `%1$s' sembolünün türü %2$d'den %3$d'e değiştirildi"
+
+#: cofflink.c:2328
+#, c-format
+msgid "%s: relocs in section `%s', but it has no contents"
+msgstr "%s: `%s' bölümünde yer değiştirmeler mevcut, fakat içi boş"
+
+#: cofflink.c:2671 coffswap.h:890
+#, c-format
+msgid "%s: %s: reloc overflow: 0x%lx > 0xffff"
+msgstr "%s: %s: yer değiştirme taşması: 0x%lx > 0xffff"
+
+#: cofflink.c:2680 coffswap.h:876
+#, c-format
+msgid "%s: warning: %s: line number overflow: 0x%lx > 0xffff"
+msgstr "%s: uyarı: %s: satır numarası taşması: 0x%lx > 0xffff"
+
+#: cpu-arm.c:196 cpu-arm.c:206
+#, c-format
+msgid "ERROR: %s is compiled for the EP9312, whereas %s is compiled for XScale"
+msgstr "Hata: %s EP9312 için derlenmiş, fakat %s XScale için derlenmiş"
+
+#: cpu-arm.c:344
+#, c-format
+msgid "warning: unable to update contents of %s section in %s"
+msgstr "uyarı: %2$s içinde %1$s bölümünün içeriği güncellenemedi"
+
+#: dwarf2.c:380
+msgid "Dwarf Error: Can't find .debug_str section."
+msgstr "Dwarf Hatası: .debug_str bölümü bulunamadı."
+
+#: dwarf2.c:397
+#, c-format
+msgid "Dwarf Error: DW_FORM_strp offset (%lu) greater than or equal to .debug_str size (%lu)."
+msgstr ""
+"Dwarf Hatası: DW_FORM_strp göreli konumu (%lu) .debug_str boyutundan (%lu) \n"
+" daha büyük veya eşit."
+
+#: dwarf2.c:541
+msgid "Dwarf Error: Can't find .debug_abbrev section."
+msgstr "Dwarf Hatası: .debug_abbrev bölümü bulunamadı."
+
+#: dwarf2.c:556
+#, c-format
+msgid "Dwarf Error: Abbrev offset (%lu) greater than or equal to .debug_abbrev size (%lu)."
+msgstr ""
+"Dwarf Hatası: Kısaltma göreli konumu (%lu) kısaltma boyutundan (%lu) \n"
+" daha büyük veya eşit."
+
+#: dwarf2.c:756
+#, c-format
+msgid "Dwarf Error: Invalid or unhandled FORM value: %u."
+msgstr "Dwarf Hatası: Geçersiz veya desteklenmeyen FORM değeri: %u."
+
+#: dwarf2.c:933
+msgid "Dwarf Error: mangled line number section (bad file number)."
+msgstr "Dwarf Hatası: bozulmuş satır numarası bölümü (geçersiz dosya numarası)."
+
+#: dwarf2.c:1032
+msgid "Dwarf Error: Can't find .debug_line section."
+msgstr "Dwarf Hatası: .debug_line bölümü bulunamadı."
+
+#: dwarf2.c:1049
+#, c-format
+msgid "Dwarf Error: Line offset (%lu) greater than or equal to .debug_line size (%lu)."
+msgstr ""
+"Dwarf Hatası: Satır göreli konumu (%lu) satır boyutundan (%lu)\n"
+" daha büyük veya eşit."
+
+#: dwarf2.c:1255
+msgid "Dwarf Error: mangled line number section."
+msgstr "Dwarf Hatası: bozuk satır numarası bölümü."
+
+#: dwarf2.c:1470 dwarf2.c:1620
+#, c-format
+msgid "Dwarf Error: Could not find abbrev number %u."
+msgstr "Dwarf Hatası: Kısaltma numarası %u bulunamadı."
+
+#: dwarf2.c:1581
+#, c-format
+msgid "Dwarf Error: found dwarf version '%u', this reader only handles version 2 information."
+msgstr "Dwarf Hatası: dwarf sürümü '%u' bulundu, bu okuyucu yalnızca sürüm 2 bilgisini anlayabiliyor."
+
+#: dwarf2.c:1588
+#, c-format
+msgid "Dwarf Error: found address size '%u', this reader can not handle sizes greater than '%u'."
+msgstr "Dwarf Hatası: adres boyu '%u' bulundu, bu okuyucu '%u'dan daha büyük boyları okuyamıyor."
+
+#: dwarf2.c:1611
+#, c-format
+msgid "Dwarf Error: Bad abbrev number: %u."
+msgstr "Dwarf Hatası: Geçersiz kısaltma numarası: %u."
+
+#: ecoff.c:1339
+#, c-format
+msgid "Unknown basic type %d"
+msgstr "Bilinmeyen temel tür %d"
+
+#: ecoff.c:1599
+#, c-format
+msgid ""
+"\n"
+" End+1 symbol: %ld"
+msgstr ""
+"\n"
+" Son+1 sembolü: %ld"
+
+#: ecoff.c:1606 ecoff.c:1609
+#, c-format
+msgid ""
+"\n"
+" First symbol: %ld"
+msgstr ""
+"\n"
+" Ä°lk sembol: %ld"
+
+#: ecoff.c:1621
+#, c-format
+msgid ""
+"\n"
+" End+1 symbol: %-7ld Type: %s"
+msgstr ""
+"\n"
+" Son+1 sembolü: %-7ld Tür: %s"
+
+#: ecoff.c:1628
+#, c-format
+msgid ""
+"\n"
+" Local symbol: %ld"
+msgstr ""
+"\n"
+" Yerel sembol: %ld"
+
+#: ecoff.c:1636
+#, c-format
+msgid ""
+"\n"
+" struct; End+1 symbol: %ld"
+msgstr ""
+"\n"
+" yapı; Son+1 sembolü: %ld"
+
+#: ecoff.c:1641
+#, c-format
+msgid ""
+"\n"
+" union; End+1 symbol: %ld"
+msgstr ""
+"\n"
+" birleşim; Son+1 sembolü: %ld"
+
+#: ecoff.c:1646
+#, c-format
+msgid ""
+"\n"
+" enum; End+1 symbol: %ld"
+msgstr ""
+"\n"
+" enum; Son+1 sembolü: %ld"
+
+#: ecoff.c:1652
+#, c-format
+msgid ""
+"\n"
+" Type: %s"
+msgstr ""
+"\n"
+" Tür: %s"
+
+#: elf-hppa.h:1458 elf-hppa.h:1491 elf-m10300.c:1628 elf64-sh64.c:1704
+#, c-format
+msgid "%s: warning: unresolvable relocation against symbol `%s' from %s section"
+msgstr "%1$s: uyarı: %3$s bölümünden `%2$s' sembolüne çözümlenemeyen yer değişimi"
+
+#: elf-m10200.c:442 elf-m10300.c:1695 elf32-arm.h:2088 elf32-avr.c:812
+#: elf32-cris.c:1390 elf32-d10v.c:570 elf32-fr30.c:634 elf32-frv.c:815
+#: elf32-h8300.c:528 elf32-i860.c:1028 elf32-ip2k.c:1586 elf32-iq2000.c:699
+#: elf32-m32r.c:1283 elf32-m68hc1x.c:1305 elf32-msp430.c:510
+#: elf32-openrisc.c:436 elf32-v850.c:1777 elf32-xstormy16.c:976
+#: elf64-mmix.c:1332
+msgid "internal error: out of range error"
+msgstr "iç hata: kapsam dışı hatası"
+
+#: elf-m10200.c:446 elf-m10300.c:1699 elf32-arm.h:2092 elf32-avr.c:816
+#: elf32-cris.c:1394 elf32-d10v.c:574 elf32-fr30.c:638 elf32-frv.c:819
+#: elf32-h8300.c:532 elf32-i860.c:1032 elf32-iq2000.c:703 elf32-m32r.c:1287
+#: elf32-m68hc1x.c:1309 elf32-msp430.c:514 elf32-openrisc.c:440
+#: elf32-v850.c:1781 elf32-xstormy16.c:980 elf64-mmix.c:1336 elfxx-mips.c:6452
+msgid "internal error: unsupported relocation error"
+msgstr "iç hata: desteklenmeyen yer değişim hatası"
+
+#: elf-m10200.c:450 elf-m10300.c:1703 elf32-arm.h:2096 elf32-d10v.c:578
+#: elf32-h8300.c:536 elf32-m32r.c:1291 elf32-m68hc1x.c:1313
+msgid "internal error: dangerous error"
+msgstr "iç hata: ölümcül hata"
+
+#: elf-m10200.c:454 elf-m10300.c:1707 elf32-arm.h:2100 elf32-avr.c:824
+#: elf32-cris.c:1402 elf32-d10v.c:582 elf32-fr30.c:646 elf32-frv.c:827
+#: elf32-h8300.c:540 elf32-i860.c:1040 elf32-ip2k.c:1601 elf32-iq2000.c:711
+#: elf32-m32r.c:1295 elf32-m68hc1x.c:1317 elf32-msp430.c:522
+#: elf32-openrisc.c:448 elf32-v850.c:1801 elf32-xstormy16.c:988
+#: elf64-mmix.c:1344
+msgid "internal error: unknown error"
+msgstr "iç hata: bilinmeyen hata"
+
+#: elf.c:372
+#, c-format
+msgid "%s: invalid string offset %u >= %lu for section `%s'"
+msgstr "%1$s: `%4$s' bölümünde geçersiz dizge göreli konumu %2$u >= %3$lu"
+
+#: elf.c:624
+#, c-format
+msgid "%s: invalid SHT_GROUP entry"
+msgstr "%s: geçersiz SHT_GROUP girdisi"
+
+#: elf.c:695
+#, c-format
+msgid "%s: no group info for section %s"
+msgstr "%s: %s bölümünde grup bilgisi yok"
+
+#: elf.c:1055
+msgid ""
+"\n"
+"Program Header:\n"
+msgstr ""
+"\n"
+"Yazılım Başlığı:\n"
+
+#: elf.c:1106
+msgid ""
+"\n"
+"Dynamic Section:\n"
+msgstr ""
+"\n"
+"Dinamik Bölüm:\n"
+
+#: elf.c:1235
+msgid ""
+"\n"
+"Version definitions:\n"
+msgstr ""
+"\n"
+"Sürüm tanımları:\n"
+
+#: elf.c:1258
+msgid ""
+"\n"
+"Version References:\n"
+msgstr ""
+"\n"
+"Sürüm Referansları:\n"
+
+#: elf.c:1263
+#, c-format
+msgid " required from %s:\n"
+msgstr " %s'den isteniyor:\n"
+
+#: elf.c:1944
+#, c-format
+msgid "%s: invalid link %lu for reloc section %s (index %u)"
+msgstr "%1$s: yerdeğişim bölümü %3$s (indeks %4$u) için geçersiz bağ %2$lu"
+
+#: elf.c:3686
+#, c-format
+msgid "%s: Not enough room for program headers (allocated %u, need %u)"
+msgstr "%s: Yazılım başlıkları için yeterli yer yok (%u ayrıldı, %u gerekli)"
+
+#: elf.c:3791
+#, c-format
+msgid "%s: Not enough room for program headers, try linking with -N"
+msgstr "%s: yazılım başlıkları için gerekli yer yok, -N ile bağlamayı deneyin"
+
+#: elf.c:3922
+#, c-format
+msgid "Error: First section in segment (%s) starts at 0x%x whereas the segment starts at 0x%x"
+msgstr "Hata: Parçadaki (%s) ilk bölüm 0x%x'de, parça ise 0x%x'de başlıyor"
+
+#: elf.c:4242
+#, c-format
+msgid "%s: warning: allocated section `%s' not in segment"
+msgstr "%s: uyarı: ayrılmış `%s' bölümü parça içinde değil"
+
+#: elf.c:4566
+#, c-format
+msgid "%s: symbol `%s' required but not present"
+msgstr "%s: `%s' sembolü gerekli fakat mevcut değil"
+
+#: elf.c:4854
+#, c-format
+msgid "%s: warning: Empty loadable segment detected, is this intentional ?\n"
+msgstr "%s: uyarı: Boş yüklenebilir parça bulundu, bu isteyerek mi yapılıyor?\n"
+
+#: elf.c:5485
+#, c-format
+msgid "Unable to find equivalent output section for symbol '%s' from section '%s'"
+msgstr "'%2$s' bölümünden '%1$s' sembolü için eşdeğer çıktı bölümü bulunamadı"
+
+#: elf.c:6298
+#, c-format
+msgid "%s: unsupported relocation type %s"
+msgstr "%s: desteklenmeyen yerdeğişim türü %s"
+
+#: elf32-arm.h:1228
+#, c-format
+msgid "%s: Warning: Arm BLX instruction targets Arm function '%s'."
+msgstr "%s: Uyarı: Arm BLX işlemi Arm işlevi '%s' hedefliyor."
+
+#: elf32-arm.h:1424
+#, c-format
+msgid "%s: Warning: Thumb BLX instruction targets thumb function '%s'."
+msgstr "%s: Uyarı: Thumb BLX işlemi thumb işlevi '%s'ı hedefliyor."
+
+#: elf32-arm.h:1918 elf32-sh.c:4706 elf64-sh64.c:1613
+#, c-format
+msgid "%s(%s+0x%lx): %s relocation against SEC_MERGE section"
+msgstr "%s(%s+0x%lx): SEC_MERGE bölümüne %s yerdeğişimi"
+
+#: elf32-arm.h:2012
+#, c-format
+msgid "%s: warning: unresolvable relocation %d against symbol `%s' from %s section"
+msgstr "%1$s: uyarı: %4$s bölümünden `%3$s' sembolüne çözümlenemeyen %2$d yer değişimi"
+
+#: elf32-arm.h:2202
+#, c-format
+msgid "Warning: Clearing the interworking flag of %s because non-interworking code in %s has been linked with it"
+msgstr "Uyarı: %2$s'deki beraber çalışmaz kod ona bağlandığı için %1$s'nin beraber çalışma bayrağı temizlendi"
+
+#: elf32-arm.h:2302
+#, c-format
+msgid "ERROR: %s is compiled for EABI version %d, whereas %s is compiled for version %d"
+msgstr "Hata: %s EABI sürüm %d için derlenmiş, fakat %s %d sürümü için derlenmiş"
+
+#: elf32-arm.h:2316
+#, c-format
+msgid "ERROR: %s is compiled for APCS-%d, whereas target %s uses APCS-%d"
+msgstr "HATA: %s, APCS-%d için derlenmiş fakat hedef %s APCS-%d kullanıyor"
+
+#: elf32-arm.h:2344
+#, c-format
+msgid "ERROR: %s uses VFP instructions, whereas %s does not"
+msgstr "Hata: %s VFP işlemi kullanıyor, fakat %s kullanmıyor"
+
+#: elf32-arm.h:2349
+#, c-format
+msgid "ERROR: %s uses FPA instructions, whereas %s does not"
+msgstr "Hata: %s FPA işlemi kullanıyor, fakat %s kullanmıyor"
+
+#: elf32-arm.h:2360 elf32-arm.h:2365
+#, c-format
+msgid "ERROR: %s uses Maverick instructions, whereas %s does not"
+msgstr "Hata: %s Maverick işlemi kullanıyor, fakat %s kullanmıyor"
+
+#: elf32-arm.h:2385
+#, c-format
+msgid "ERROR: %s uses software FP, whereas %s uses hardware FP"
+msgstr ""
+"Hata: %s yazılımda kayan sayı kullanıyor,\n"
+" fakat %s donanımda kayan sayı kullanıyor"
+
+#: elf32-arm.h:2390
+#, c-format
+msgid "ERROR: %s uses hardware FP, whereas %s uses software FP"
+msgstr ""
+"Hata: %s donanımda kayan sayı kullanıyor,\n"
+" fakat %s yazılımda kayan sayı kullanıyor"
+
+#. Ignore init flag - it may not be set, despite the flags field
+#. containing valid data.
+#: elf32-arm.h:2443 elf32-cris.c:2975 elf32-m68hc1x.c:1459 elf32-m68k.c:397
+#: elf32-vax.c:546 elfxx-mips.c:9238
+#, c-format
+msgid "private flags = %lx:"
+msgstr "özel bayraklar = %lx:"
+
+#: elf32-arm.h:2452
+msgid " [interworking enabled]"
+msgstr " [beraber çalışma etkinleştirilmiş]"
+
+#: elf32-arm.h:2460
+msgid " [VFP float format]"
+msgstr " [VFP kayan nokta biçemi]"
+
+#: elf32-arm.h:2462
+msgid " [Maverick float format]"
+msgstr " [Maverick kayan nokta biçemi]"
+
+#: elf32-arm.h:2464
+msgid " [FPA float format]"
+msgstr " [FPA kayan nokta biçemi]"
+
+#: elf32-arm.h:2473
+msgid " [new ABI]"
+msgstr " [yeni ABI]"
+
+#: elf32-arm.h:2476
+msgid " [old ABI]"
+msgstr " [eski ABI]"
+
+#: elf32-arm.h:2479
+msgid " [software FP]"
+msgstr " [yazılım FP]"
+
+#: elf32-arm.h:2488
+msgid " [Version1 EABI]"
+msgstr " [Sürüm1 EABI]"
+
+#: elf32-arm.h:2491 elf32-arm.h:2502
+msgid " [sorted symbol table]"
+msgstr " [sıralanmış sembol tablosu]"
+
+#: elf32-arm.h:2493 elf32-arm.h:2504
+msgid " [unsorted symbol table]"
+msgstr " [sıralanmamış sembol tablosu]"
+
+#: elf32-arm.h:2499
+msgid " [Version2 EABI]"
+msgstr " [Sürüm2 EABI]"
+
+#: elf32-arm.h:2507
+msgid " [dynamic symbols use segment index]"
+msgstr " [dinamik semboller bölüm indeksini kullanıyor]"
+
+#: elf32-arm.h:2510
+msgid " [mapping symbols precede others]"
+msgstr " [eşleşme sembolleri diğerlerinden önceliklidir]"
+
+#: elf32-arm.h:2517
+msgid " <EABI version unrecognised>"
+msgstr " <EABI sürümü bilinmiyor>"
+
+#: elf32-arm.h:2524
+msgid " [relocatable executable]"
+msgstr " [yer deÄŸiÅŸtirebilir uygulama]"
+
+#: elf32-arm.h:2527
+msgid " [has entry point]"
+msgstr " [girdi noktası var]"
+
+#: elf32-arm.h:2532
+msgid "<Unrecognised flag bits set>"
+msgstr "<Bilinmeyen bayrak bitleri atanmış>"
+
+#: elf32-avr.c:820 elf32-cris.c:1398 elf32-fr30.c:642 elf32-frv.c:823
+#: elf32-i860.c:1036 elf32-ip2k.c:1597 elf32-iq2000.c:707 elf32-msp430.c:518
+#: elf32-openrisc.c:444 elf32-v850.c:1785 elf32-xstormy16.c:984
+#: elf64-mmix.c:1340
+msgid "internal error: dangerous relocation"
+msgstr "iç hata: tehlikeli yer değişim"
+
+#: elf32-cris.c:931
+#, c-format
+msgid "%s: unresolvable relocation %s against symbol `%s' from %s section"
+msgstr "%1$s: uyarı: %4$s bölümünden `%3$s' sembolüne çözümlenemeyen %2$s yer değişimi"
+
+#: elf32-cris.c:993
+#, c-format
+msgid "%s: No PLT nor GOT for relocation %s against symbol `%s' from %s section"
+msgstr "%1$s: %4$s bölümünden `%3$s' sembolüne %2$s yer değişimi için PLT veya GOT yok"
+
+#: elf32-cris.c:996 elf32-cris.c:1122
+msgid "[whose name is lost]"
+msgstr "[adı kaybolmuş]"
+
+#: elf32-cris.c:1111
+#, c-format
+msgid "%s: relocation %s with non-zero addend %d against local symbol from %s section"
+msgstr ""
+"%1$s: %4$s bölümünden yerel sembol sıfır olmayan %3$d eklemesi ile\n"
+" %2$s yerdeÄŸiÅŸimi"
+
+#: elf32-cris.c:1118
+#, c-format
+msgid "%s: relocation %s with non-zero addend %d against symbol `%s' from %s section"
+msgstr "%1$s: %5$s bölümünden `%4$s' sembolüne sıfır olmayan %3$d eklemesi ile %2$s yerdeğişimi"
+
+#: elf32-cris.c:1143
+#, c-format
+msgid "%s: relocation %s is not allowed for global symbol: `%s' from %s section"
+msgstr "%1$s: %4$s bölümünden %3$s evrensel sembolü için %2$s yerdeğişimi yapılamaz"
+
+#: elf32-cris.c:1158
+#, c-format
+msgid "%s: relocation %s in section %s with no GOT created"
+msgstr "%1$s: `%3$s' bölümünde %2$s yer değiştirmesi mevcut, fakat GOT oluşturulmamış"
+
+#: elf32-cris.c:1277
+#, c-format
+msgid "%s: Internal inconsistency; no relocation section %s"
+msgstr "%s: İç tutarsızlık; %s yerdeğişim bölümü yok"
+
+#: elf32-cris.c:2500
+#, c-format
+msgid ""
+"%s, section %s:\n"
+" relocation %s should not be used in a shared object; recompile with -fPIC"
+msgstr ""
+"%s, %s bölümü:\n"
+" %s yer değişimi paylaşımlı nesne oluştururken kullanılamaz;\n"
+" -fPIC ile yeniden derleyin"
+
+#: elf32-cris.c:2978
+msgid " [symbols have a _ prefix]"
+msgstr " [semboller _ önekine sahip]"
+
+#: elf32-cris.c:3017
+#, c-format
+msgid "%s: uses _-prefixed symbols, but writing file with non-prefixed symbols"
+msgstr "%s: _-önekli sembolleri kullanıyor, fakat dosyaya öneksiz sembolleri yazıyor"
+
+#: elf32-cris.c:3018
+#, c-format
+msgid "%s: uses non-prefixed symbols, but writing file with _-prefixed symbols"
+msgstr "%s: öneksiz sembolleri kullanıyor, fakat dosyaya _-önekli sembolleri yazıyor"
+
+#: elf32-frv.c:1223
+#, c-format
+msgid "%s: compiled with %s and linked with modules that use non-pic relocations"
+msgstr "%s: %s ile derlendi ve normal derlenmiş modüllerle bağlandı"
+
+#: elf32-frv.c:1273 elf32-iq2000.c:895
+#, c-format
+msgid "%s: compiled with %s and linked with modules compiled with %s"
+msgstr "%s: %s ile derlendi ve %s ile derlenmiş modüllerle bağlandı"
+
+#: elf32-frv.c:1285
+#, c-format
+msgid "%s: uses different unknown e_flags (0x%lx) fields than previous modules (0x%lx)"
+msgstr "%s: önceki modüllerden farklı bilinmeyen e_flags (0x%lx) alanları kullanılıyor (0x%lx)"
+
+#: elf32-frv.c:1321 elf32-iq2000.c:933
+#, c-format
+msgid "private flags = 0x%lx:"
+msgstr "özel bayraklar = 0x%lx:"
+
+#: elf32-gen.c:83 elf64-gen.c:82
+#, c-format
+msgid "%s: Relocations in generic ELF (EM: %d)"
+msgstr "%s: Normal ELF'de yerdeÄŸiÅŸimler (EM: %d)"
+
+#: elf32-hppa.c:672 elf32-m68hc1x.c:176 elf64-ppc.c:3118
+#, c-format
+msgid "%s: cannot create stub entry %s"
+msgstr "%s: koçan girişi %s oluşturulamadı"
+
+#: elf32-hppa.c:957 elf32-hppa.c:3538
+#, c-format
+msgid "%s(%s+0x%lx): cannot reach %s, recompile with -ffunction-sections"
+msgstr "%s(%s+0x%lx): %s'e ulaşılamadı, -ffunction-sections ile derleyin"
+
+#: elf32-hppa.c:1340 elf64-x86-64.c:672 elf64-x86-64.c:797
+#, c-format
+msgid "%s: relocation %s can not be used when making a shared object; recompile with -fPIC"
+msgstr "%s: %s yer değişimi paylaşımlı nesne oluşturulurken kullanılamaz; -fPIC ile yeniden derleyin"
+
+#: elf32-hppa.c:1360
+#, c-format
+msgid "%s: relocation %s should not be used when making a shared object; recompile with -fPIC"
+msgstr "%s: %s yer değişimi paylaşımlı nesne oluştururken kullanılamaz; -fPIC ile yeniden derleyin"
+
+#: elf32-hppa.c:1553
+#, c-format
+msgid "Could not find relocation section for %s"
+msgstr "%s için yer değiştirme bölümü bulunamadı"
+
+#: elf32-hppa.c:2828
+#, c-format
+msgid "%s: duplicate export stub %s"
+msgstr "%s: birden fazla ihraç koçanı %s"
+
+#: elf32-hppa.c:3416
+#, c-format
+msgid "%s(%s+0x%lx): fixing %s"
+msgstr "%s(%s+0x%lx): %s düzeltiliyor"
+
+#: elf32-hppa.c:4039
+#, c-format
+msgid "%s(%s+0x%lx): cannot handle %s for %s"
+msgstr "%1$s(%2$s+0x%3$lx): %5$s için %4$s işlenemedi"
+
+#: elf32-hppa.c:4357
+msgid ".got section not immediately after .plt section"
+msgstr ".got bölümü .plt bölümünün hemen arkasında değil"
+
+#: elf32-i386.c:326
+#, c-format
+msgid "%s: invalid relocation type %d"
+msgstr "%s: geçersiz yer değişim türü %d"
+
+#: elf32-i386.c:841 elf32-s390.c:990 elf32-sparc.c:887 elf32-xtensa.c:637
+#: elf64-s390.c:943 elf64-x86-64.c:650
+#, c-format
+msgid "%s: bad symbol index: %d"
+msgstr "%s: geçersiz sembol indeksi: %d"
+
+#: elf32-i386.c:949 elf32-s390.c:1168 elf32-sh.c:6426 elf32-sparc.c:1011
+#: elf64-s390.c:1129
+#, c-format
+msgid "%s: `%s' accessed both as normal and thread local symbol"
+msgstr "%s: `%s'a hem normal, hem de dal yerel sembolü olarak erişildi"
+
+#: elf32-i386.c:1064 elf32-s390.c:1279 elf64-ppc.c:3929 elf64-s390.c:1243
+#: elf64-x86-64.c:886
+#, c-format
+msgid "%s: bad relocation section name `%s'"
+msgstr "%s: geçersiz yerdeğişim bölümü adı `%s'"
+
+#: elf32-i386.c:2908 elf32-m68k.c:1757 elf32-s390.c:3022 elf32-sparc.c:2879
+#: elf32-xtensa.c:2193 elf64-s390.c:3018 elf64-sparc.c:2664
+#: elf64-x86-64.c:2452
+#, c-format
+msgid "%s(%s+0x%lx): unresolvable relocation against symbol `%s'"
+msgstr "%s(%s+0x%lx): `%s' sembolüne çözümlenemeyen yer değişimi"
+
+#: elf32-i386.c:2947 elf32-m68k.c:1796 elf32-s390.c:3072 elf64-s390.c:3068
+#: elf64-x86-64.c:2490
+#, c-format
+msgid "%s(%s+0x%lx): reloc against `%s': error %d"
+msgstr "%s(%s+0x%lx): %s'e yer değişimi: %d hatası"
+
+#: elf32-ip2k.c:565 elf32-ip2k.c:571 elf32-ip2k.c:734 elf32-ip2k.c:740
+msgid "ip2k relaxer: switch table without complete matching relocation information."
+msgstr "ip2k esneticisi: tamamen eÅŸleÅŸen yerdeÄŸiÅŸim bilgisi olmadan tabloyu deÄŸiÅŸtirir."
+
+#: elf32-ip2k.c:588 elf32-ip2k.c:767
+msgid "ip2k relaxer: switch table header corrupt."
+msgstr "ip2k esneticisi: değişiklik tablosu başlığı bozuk."
+
+#: elf32-ip2k.c:1395
+#, c-format
+msgid "ip2k linker: missing page instruction at 0x%08lx (dest = 0x%08lx)."
+msgstr "ip2k bağlayıcısı: 0x%08lx adresinde sayfa işlemi eksik (hedef = 0x%08lx)."
+
+#: elf32-ip2k.c:1409
+#, c-format
+msgid "ip2k linker: redundant page instruction at 0x%08lx (dest = 0x%08lx)."
+msgstr "ip2k bağlayıcısı: 0x%08lx adresinde gereksiz sayfa işlemi (hedef = 0x%08lx)."
+
+#. Only if it's not an unresolved symbol.
+#: elf32-ip2k.c:1593
+msgid "unsupported relocation between data/insn address spaces"
+msgstr "veri/işlem adres yerleri arasında desteklenmeyen yerdeğişim"
+
+#: elf32-iq2000.c:907 elf32-m68hc1x.c:1431 elf32-ppc.c:2175 elf64-sparc.c:3072
+#: elfxx-mips.c:9195
+#, c-format
+msgid "%s: uses different e_flags (0x%lx) fields than previous modules (0x%lx)"
+msgstr "%1$s: önceki modüllerden (0x%3$lx) farklı e_flags (0x%2$lx) alanları kullanılıyor"
+
+#: elf32-m32r.c:930
+msgid "SDA relocation when _SDA_BASE_ not defined"
+msgstr "_SDA_BASE_ tanımlanmamış iken SDA yer değişimi"
+
+#: elf32-m32r.c:1018 elf64-alpha.c:4279 elf64-alpha.c:4407 elf32-ia64.c:3958
+#: elf64-ia64.c:3958
+#, c-format
+msgid "%s: unknown relocation type %d"
+msgstr "%s: bilinmeyen yer değişim türü %d"
+
+#: elf32-m32r.c:1226
+#, c-format
+msgid "%s: The target (%s) of an %s relocation is in the wrong section (%s)"
+msgstr "%1$s: Bir %3$s yer değişiminin hedefi (%2$s) yanlış bölümde (%4$s)"
+
+#: elf32-m32r.c:1952
+#, c-format
+msgid "%s: Instruction set mismatch with previous modules"
+msgstr "%s: Önceki modüllerle işlem uyuşmazlığı"
+
+#: elf32-m32r.c:1975
+#, c-format
+msgid "private flags = %lx"
+msgstr "özel bayraklar = %lx"
+
+#: elf32-m32r.c:1980
+msgid ": m32r instructions"
+msgstr ": m32r iÅŸlemleri"
+
+#: elf32-m32r.c:1981
+msgid ": m32rx instructions"
+msgstr ": m32rx iÅŸlemleri"
+
+#: elf32-m68hc1x.c:1217
+#, c-format
+msgid "Reference to the far symbol `%s' using a wrong relocation may result in incorrect execution"
+msgstr "Uzak sembol `%s''ye yanlış bir yerdeğişim ile referans yanlış işlemeye yol açabilir."
+
+#: elf32-m68hc1x.c:1240
+#, c-format
+msgid "banked address [%lx:%04lx] (%lx) is not in the same bank as current banked address [%lx:%04lx] (%lx)"
+msgstr "saklanmış adres [%lx:%04lx] (%lx) şimdiki saklanmış adres [%lx:%04lx] (%lx) ile aynı saklama bankında değil"
+
+#: elf32-m68hc1x.c:1259
+#, c-format
+msgid "reference to a banked address [%lx:%04lx] in the normal address space at %04lx"
+msgstr "%3$04lx normal adresinde saklanmış adres [%1$lx:%2$04lx]'e referans var"
+
+#: elf32-m68hc1x.c:1396
+#, c-format
+msgid "%s: linking files compiled for 16-bit integers (-mshort) and others for 32-bit integers"
+msgstr "%s: 16-bit tamsayı için derlenmiş (-mshort) dosyalar, 32 bit tamsayı için derlenmiş başka dosyalarla bağlanıyor"
+
+#: elf32-m68hc1x.c:1404
+#, c-format
+msgid "%s: linking files compiled for 32-bit double (-fshort-double) and others for 64-bit double"
+msgstr "%s: 32-bit double (-fshort-double) için derlenmiş dosyalar 64-bit double için derlenmiş dosyalarla bağlanıyor"
+
+#: elf32-m68hc1x.c:1414
+#, c-format
+msgid "%s: linking files compiled for HCS12 with others compiled for HC12"
+msgstr "%s: HCS12 için derlenmiş dosyalar HC12 için derlenmiş dosyalarla bağlanıyor"
+
+#: elf32-m68hc1x.c:1462
+msgid "[abi=32-bit int, "
+msgstr "[abi=32-bit int, "
+
+#: elf32-m68hc1x.c:1464
+msgid "[abi=16-bit int, "
+msgstr "[abi=16-bit int, "
+
+#: elf32-m68hc1x.c:1467
+msgid "64-bit double, "
+msgstr "64-bit double, "
+
+#: elf32-m68hc1x.c:1469
+msgid "32-bit double, "
+msgstr "32-bit double, "
+
+#: elf32-m68hc1x.c:1472
+msgid "cpu=HC11]"
+msgstr "cpu=HC11]"
+
+#: elf32-m68hc1x.c:1474
+msgid "cpu=HCS12]"
+msgstr "cpu=HCS12]"
+
+#: elf32-m68hc1x.c:1476
+msgid "cpu=HC12]"
+msgstr "cpu=HC12]"
+
+#: elf32-m68hc1x.c:1479
+msgid " [memory=bank-model]"
+msgstr " [bellek=bank türü]"
+
+#: elf32-m68hc1x.c:1481
+msgid " [memory=flat]"
+msgstr " [bellek=düz]"
+
+#: elf32-m68k.c:400
+msgid " [cpu32]"
+msgstr " [cpu32]"
+
+#: elf32-m68k.c:403
+msgid " [m68000]"
+msgstr " [m68000]"
+
+#: elf32-mcore.c:353 elf32-mcore.c:456
+#, c-format
+msgid "%s: Relocation %s (%d) is not currently supported.\n"
+msgstr "%s: %s (%d) yer değişimi henüz desteklenmiyor.\n"
+
+#: elf32-mcore.c:441
+#, c-format
+msgid "%s: Unknown relocation type %d\n"
+msgstr "%s: Bilinmeyen yer değişim türü %d\n"
+
+#: elf32-mips.c:1170 elf64-mips.c:1717 elfn32-mips.c:1664
+msgid "32bits gp relative relocation occurs for an external symbol"
+msgstr "32 bitlik gp göreceli yer değişim bir dış sembol için yapılıyor"
+
+#: elf32-mips.c:1314 elf64-mips.c:1830 elfn32-mips.c:1783
+#, c-format
+msgid "Linking mips16 objects into %s format is not supported"
+msgstr "mips16 nesnelerini %s biçemine bağlamak desteklenmiyor"
+
+#: elf32-ppc.c:2056
+#, c-format
+msgid "generic linker can't handle %s"
+msgstr "jenerik bağlayıcı %s desteklemiyor"
+
+#: elf32-ppc.c:2138
+#, c-format
+msgid "%s: compiled with -mrelocatable and linked with modules compiled normally"
+msgstr "%s: -mrelocatable ile derlendi ve normal derlenmiş modüllerle bağlandı"
+
+#: elf32-ppc.c:2147
+#, c-format
+msgid "%s: compiled normally and linked with modules compiled with -mrelocatable"
+msgstr "%s: normal derlendi ve -mrelocatable ile derlenmiş modüllere bağlandı"
+
+#: elf32-ppc.c:3413
+#, c-format
+msgid "%s: relocation %s cannot be used when making a shared object"
+msgstr "%s: %s yerdeğişimi paylaşımlı nesne oluşturulurken kullanılamaz"
+
+#. It does not make sense to have a procedure linkage
+#. table entry for a local symbol.
+#: elf32-ppc.c:3619
+#, c-format
+msgid "%s(%s+0x%lx): %s reloc against local symbol"
+msgstr "%s(%s+0x%lx): %s yerel sembole yerdeÄŸiÅŸimi"
+
+#: elf32-ppc.c:4862 elf64-ppc.c:7789
+#, c-format
+msgid "%s: unknown relocation type %d for symbol %s"
+msgstr "%1$s: %3$s sembolü için bilinmeyen %2$d türünde yerdeğişimi"
+
+#: elf32-ppc.c:5113
+#, c-format
+msgid "%s(%s+0x%lx): non-zero addend on %s reloc against `%s'"
+msgstr "%1$s(%2$s+0x%3$lx): %5$s'ye yerdeğişimde `%4$s'de sıfır olmayan ekleme"
+
+#: elf32-ppc.c:5399 elf32-ppc.c:5425 elf32-ppc.c:5484
+#, c-format
+msgid "%s: the target (%s) of a %s relocation is in the wrong output section (%s)"
+msgstr "%1$s: %3$s yerdeğişiminin hedefi (%2$s) yanlış çıktı bölümünde (%4$s)"
+
+#: elf32-ppc.c:5539
+#, c-format
+msgid "%s: relocation %s is not yet supported for symbol %s."
+msgstr "%s: %s yerdeğişimi %s sembolü için henüz desteklenmiyor."
+
+#: elf32-ppc.c:5594 elf64-ppc.c:8461
+#, c-format
+msgid "%s(%s+0x%lx): unresolvable %s relocation against symbol `%s'"
+msgstr "%1$s(%2$s+0x%3$lx): `%5$s' sembolüne çözümlenemeyen yer değişimi %4$s"
+
+#: elf32-ppc.c:5644 elf64-ppc.c:8507
+#, c-format
+msgid "%s(%s+0x%lx): %s reloc against `%s': error %d"
+msgstr "%1$s(%2$s+0x%3$lx): %5$s'e %4$s yer değişimi: %6$d hatası"
+
+#: elf32-ppc.c:5888
+#, c-format
+msgid "corrupt or empty %s section in %s"
+msgstr "%2$s içinde bozuk veya boş %1$s bölümü"
+
+#: elf32-ppc.c:5895
+#, c-format
+msgid "unable to read in %s section from %s"
+msgstr "%s bölümü %s'den okunamadı"
+
+#: elf32-ppc.c:5901
+#, c-format
+msgid "corrupt %s section in %s"
+msgstr "%2$s içinde bozuk %1$s bölümü"
+
+#: elf32-ppc.c:5944
+#, c-format
+msgid "warning: unable to set size of %s section in %s"
+msgstr "uyarı: %2$s içinde %1$s bölümünün boyu atanamadı"
+
+#: elf32-ppc.c:5994
+msgid "failed to allocate space for new APUinfo section."
+msgstr "yeni APUinfo bölümü için yer ayrılamadı."
+
+#: elf32-ppc.c:6013
+msgid "failed to compute new APUinfo section."
+msgstr "yeni APUinfo bölümü hesaplanamadı."
+
+#: elf32-ppc.c:6016
+msgid "failed to install new APUinfo section."
+msgstr "yeni APUinfo bölümü kurulamadı."
+
+#: elf32-s390.c:2256 elf64-s390.c:2226
+#, c-format
+msgid "%s(%s+0x%lx): invalid instruction for TLS relocation %s"
+msgstr "%s(%s+0x%lx): TLS yerdeğişimi %s için geçersiz işlem"
+
+#: elf32-sh.c:2103
+#, c-format
+msgid "%s: 0x%lx: warning: bad R_SH_USES offset"
+msgstr "%s: 0x%lx: uyarı: hatalı R_SH_USES göreli konumu"
+
+#: elf32-sh.c:2115
+#, c-format
+msgid "%s: 0x%lx: warning: R_SH_USES points to unrecognized insn 0x%x"
+msgstr "%s: 0x%lx: uyarı: R_SH_USES bilinmeyen insn 0x%x'ı imliyor"
+
+#: elf32-sh.c:2132
+#, c-format
+msgid "%s: 0x%lx: warning: bad R_SH_USES load offset"
+msgstr "%s: 0x%lx: uyarı: hatalı R_SH_USES yükleme göreli konumu"
+
+#: elf32-sh.c:2147
+#, c-format
+msgid "%s: 0x%lx: warning: could not find expected reloc"
+msgstr "%s: 0x%lx: uyarı: beklenen yerdeğişim bulunamadı"
+
+#: elf32-sh.c:2175
+#, c-format
+msgid "%s: 0x%lx: warning: symbol in unexpected section"
+msgstr "%s: 0x%lx: uyarı: beklenmeyen bölümde sembol"
+
+#: elf32-sh.c:2300
+#, c-format
+msgid "%s: 0x%lx: warning: could not find expected COUNT reloc"
+msgstr "%s: 0x%lx: uyarı: beklenen COUNT yerdeğişimi bulunamadı"
+
+#: elf32-sh.c:2309
+#, c-format
+msgid "%s: 0x%lx: warning: bad count"
+msgstr "%s: 0x%lx: uyarı: hatalı sayım"
+
+#: elf32-sh.c:2712 elf32-sh.c:3088
+#, c-format
+msgid "%s: 0x%lx: fatal: reloc overflow while relaxing"
+msgstr "%s: 0x%lx: ölümcül: gevşetilirken yerdeğişim taşması"
+
+#: elf32-sh.c:4654 elf64-sh64.c:1585
+msgid "Unexpected STO_SH5_ISA32 on local symbol is not handled"
+msgstr "Yerel sembolde STO_SH5_ISA32 desteklenmiyor"
+
+#: elf32-sh.c:4809
+#, c-format
+msgid "%s: unresolvable relocation against symbol `%s' from %s section"
+msgstr "%1$s: %3$s bölümünden `%2$s' sembolüne çözümlenemeyen yer değişimi"
+
+#: elf32-sh.c:4881
+#, c-format
+msgid "%s: 0x%lx: fatal: unaligned branch target for relax-support relocation"
+msgstr "%s: 0x%lx: ölümcül: gevşetme destek yerdeğişimi için hizalanmamış dal"
+
+#: elf32-sh.c:6627 elf64-alpha.c:4848
+#, c-format
+msgid "%s: TLS local exec code cannot be linked into shared objects"
+msgstr "%s: TLS yerel çalıştırma kodu paylaşımlı nesnelere bağlanamaz"
+
+#: elf32-sh64.c:221 elf64-sh64.c:2407
+#, c-format
+msgid "%s: compiled as 32-bit object and %s is 64-bit"
+msgstr "%s: 32 bitlik sistem için derlenmiş ve %s 64 bit"
+
+#: elf32-sh64.c:224 elf64-sh64.c:2410
+#, c-format
+msgid "%s: compiled as 64-bit object and %s is 32-bit"
+msgstr "%s: 64 bitlik sistem için derlenmiş ve %s 32 bit"
+
+#: elf32-sh64.c:226 elf64-sh64.c:2412
+#, c-format
+msgid "%s: object size does not match that of target %s"
+msgstr "%s: nesne boyu hedef %s'nin boyuyla eÅŸleÅŸmiyor"
+
+#: elf32-sh64.c:461 elf64-sh64.c:2990
+#, c-format
+msgid "%s: encountered datalabel symbol in input"
+msgstr "%s: girdide veri etiketi sembolüne rastlandı"
+
+#: elf32-sh64.c:544
+msgid "PTB mismatch: a SHmedia address (bit 0 == 1)"
+msgstr "PTB uyumsuzluÄŸu: SHmedia adresi (bit 0 == 1)"
+
+#: elf32-sh64.c:547
+msgid "PTA mismatch: a SHcompact address (bit 0 == 0)"
+msgstr "PTA uyumsuzluÄŸu: SHcompact adresi (bit 0 == 0)"
+
+#: elf32-sh64.c:565
+#, c-format
+msgid "%s: GAS error: unexpected PTB insn with R_SH_PT_16"
+msgstr "%s: GAS hatası: R_SH_PT_16 içeren PTB yönergesi beklenmiyordu"
+
+#: elf32-sh64.c:614 elf64-sh64.c:1748
+#, c-format
+msgid "%s: error: unaligned relocation type %d at %08x reloc %08x\n"
+msgstr "%1$s: %3$08x ve %4$08x yerdeğiştirmesinde hizalanmamış yer değiştirme türü %2$d\n"
+
+#: elf32-sh64.c:698
+#, c-format
+msgid "%s: could not write out added .cranges entries"
+msgstr "%s: eklenen .cranges girdileri yazılamadı"
+
+#: elf32-sh64.c:760
+#, c-format
+msgid "%s: could not write out sorted .cranges entries"
+msgstr "%s: sıralanmış .cranges girdileri yazılamadı"
+
+#: elf32-sparc.c:2521 elf64-sparc.c:2314
+#, c-format
+msgid "%s: probably compiled without -fPIC?"
+msgstr "%s: acaba -fPIC olmaksızın mı derlenmiş?"
+
+#: elf32-sparc.c:3348
+#, c-format
+msgid "%s: compiled for a 64 bit system and target is 32 bit"
+msgstr "%s: 64 bitlik sistem için derlenmiş ve hedef 32 bit"
+
+#: elf32-sparc.c:3362
+#, c-format
+msgid "%s: linking little endian files with big endian files"
+msgstr "%s: küçük sonlu dosyalar büyük sonlu dosyalarla bağlanıyor"
+
+#: elf32-v850.c:753
+#, c-format
+msgid "Variable `%s' cannot occupy in multiple small data regions"
+msgstr "`%s' değişkeni birden fazla küçük veri sahasını kapsayamaz"
+
+#: elf32-v850.c:756
+#, c-format
+msgid "Variable `%s' can only be in one of the small, zero, and tiny data regions"
+msgstr "`%s' değişkeni küçük, sıfır ve ufak veri sahalarından yalnız birinde olabilir"
+
+#: elf32-v850.c:759
+#, c-format
+msgid "Variable `%s' cannot be in both small and zero data regions simultaneously"
+msgstr "`%s' değişkeni aynı anda hem küçük hem sıfır veri sahalarında bulunamaz"
+
+#: elf32-v850.c:762
+#, c-format
+msgid "Variable `%s' cannot be in both small and tiny data regions simultaneously"
+msgstr "`%s' değişkeni aynı anda hem küçük hem ufak veri sahalarında bulunamaz"
+
+#: elf32-v850.c:765
+#, c-format
+msgid "Variable `%s' cannot be in both zero and tiny data regions simultaneously"
+msgstr "`%s' değişkeni aynı anda hem sıfır hem ufak veri sahalarında bulunamaz"
+
+#: elf32-v850.c:1144
+msgid "FAILED to find previous HI16 reloc\n"
+msgstr "önceki HI16 yerdeğişimi BULUNAMADI\n"
+
+#: elf32-v850.c:1789
+msgid "could not locate special linker symbol __gp"
+msgstr "özel bağlayıcı sembolü __gp bulunamadı"
+
+#: elf32-v850.c:1793
+msgid "could not locate special linker symbol __ep"
+msgstr "özel bağlayıcı sembolü __ep bulunamadı"
+
+#: elf32-v850.c:1797
+msgid "could not locate special linker symbol __ctbp"
+msgstr "özel bağlayıcı sembolü __ctbp bulunamadı"
+
+#: elf32-v850.c:1963
+#, c-format
+msgid "%s: Architecture mismatch with previous modules"
+msgstr "%s: Önceki modüllerle platform uyumsuzluğu"
+
+#: elf32-v850.c:1983
+#, c-format
+msgid "private flags = %lx: "
+msgstr "özel bayraklar = %lx:"
+
+#: elf32-v850.c:1988
+msgid "v850 architecture"
+msgstr "v850 platformu"
+
+#: elf32-v850.c:1989
+msgid "v850e architecture"
+msgstr "v850e platformu"
+
+#: elf32-vax.c:549
+msgid " [nonpic]"
+msgstr " [nonpic]"
+
+#: elf32-vax.c:552
+msgid " [d-float]"
+msgstr " [d-float]"
+
+#: elf32-vax.c:555
+msgid " [g-float]"
+msgstr " [g-float]"
+
+#: elf32-vax.c:663
+#, c-format
+msgid "%s: warning: GOT addend of %ld to `%s' does not match previous GOT addend of %ld"
+msgstr "%1$s: uyarı: `%3$s'ye GOT %2$ld eklentisi bir önceki %4$ld GOT eklentisiyle eşleşmiyor"
+
+#: elf32-vax.c:1667
+#, c-format
+msgid "%s: warning: PLT addend of %d to `%s' from %s section ignored"
+msgstr "%1$s: uyarı: %4$s bölümünden `%3$s' sembolüne PLT eklentisi %2$d yok sayıldı"
+
+#: elf32-vax.c:1802
+#, c-format
+msgid "%s: warning: %s relocation against symbol `%s' from %s section"
+msgstr "%1$s: uyarı: %4$s bölümünden `%3$s' sembolüne %2$s yer değişimi"
+
+#: elf32-vax.c:1808
+#, c-format
+msgid "%s: warning: %s relocation to 0x%x from %s section"
+msgstr "%1$s: uyarı: %4$s bölümünden 0x%3$x'e %2$s yer değişimi"
+
+#: elf32-xstormy16.c:462 elf32-ia64.c:2450 elf64-ia64.c:2450
+msgid "non-zero addend in @fptr reloc"
+msgstr "@fptr yerdeğişiminde sıfır olmayan eklenti"
+
+#: elf64-alpha.c:1108
+msgid "GPDISP relocation did not find ldah and lda instructions"
+msgstr "GPDISP yerdeğişimi ldah ve lda işlemlerini bulamadı"
+
+#: elf64-alpha.c:3731
+#, c-format
+msgid "%s: .got subsegment exceeds 64K (size %d)"
+msgstr "%s: .got alt parçası 64K'yı aşıyor (boy %d)"
+
+#: elf64-alpha.c:4602 elf64-alpha.c:4614
+#, c-format
+msgid "%s: gp-relative relocation against dynamic symbol %s"
+msgstr "%s: %s dinamik sembolüne gp göreceli yer değişimi"
+
+#: elf64-alpha.c:4640 elf64-alpha.c:4773
+#, c-format
+msgid "%s: pc-relative relocation against dynamic symbol %s"
+msgstr "%s: %s dinamik sembolüne pc göreceli yer değişimi"
+
+#: elf64-alpha.c:4668
+#, c-format
+msgid "%s: change in gp: BRSGP %s"
+msgstr "%s: gp içinde değişiklik: BRSGP %s"
+
+#: elf64-alpha.c:4693
+msgid "<unknown>"
+msgstr "<bilinmeyen>"
+
+#: elf64-alpha.c:4698
+#, c-format
+msgid "%s: !samegp reloc against symbol without .prologue: %s"
+msgstr "%s: .prologue olmaksızın sembole !samegp yerdeğişimi: %s"
+
+#: elf64-alpha.c:4749
+#, c-format
+msgid "%s: unhandled dynamic relocation against %s"
+msgstr "%s: %s'e desteklenmeyen dinamik yerdeÄŸiÅŸim"
+
+#: elf64-alpha.c:4832
+#, c-format
+msgid "%s: dtp-relative relocation against dynamic symbol %s"
+msgstr "%s: %s dinamik sembolüne dtp göreceli yer değişimi"
+
+#: elf64-alpha.c:4855
+#, c-format
+msgid "%s: tp-relative relocation against dynamic symbol %s"
+msgstr "%s: %s dinamik sembolüne tp göreceli yer değişimi"
+
+#: elf64-hppa.c:2086
+#, c-format
+msgid "stub entry for %s cannot load .plt, dp offset = %ld"
+msgstr "%s için koçan girdisi .plt'yi yükleyemedi, dp görecesi = %ld"
+
+#: elf64-mmix.c:1032
+#, c-format
+msgid ""
+"%s: Internal inconsistency error for value for\n"
+" linker-allocated global register: linked: 0x%lx%08lx != relaxed: 0x%lx%08lx\n"
+msgstr ""
+"%s: bağlayıcı tarafından ayrılmış global yazmaç değeri için iç tutarsızlık hatası:\n"
+" 0x%lx%08lx != gevÅŸetilmiÅŸ: 0x%lx%08lx\n"
+
+#: elf64-mmix.c:1416
+#, c-format
+msgid "%s: base-plus-offset relocation against register symbol: (unknown) in %s"
+msgstr "%s: yazmaç sembolüne temel artı görece yerdeğişimi: %s içinde (bilinmeyen)"
+
+#: elf64-mmix.c:1421
+#, c-format
+msgid "%s: base-plus-offset relocation against register symbol: %s in %s"
+msgstr "%1$s: yazmaç sembolüne temel artı görece yerdeğişimi: %3$s içinde %2$s"
+
+#: elf64-mmix.c:1465
+#, c-format
+msgid "%s: register relocation against non-register symbol: (unknown) in %s"
+msgstr "%s: yazmaç olmayan sembole yazmaç yerdeğişimi: %s içinde (bilinmeyen)"
+
+#: elf64-mmix.c:1470
+#, c-format
+msgid "%s: register relocation against non-register symbol: %s in %s"
+msgstr "%1$s: yazmaç olmayan sembole yazmaç yerdeğişimi: %3$s içinde %2$s"
+
+#: elf64-mmix.c:1507
+#, c-format
+msgid "%s: directive LOCAL valid only with a register or absolute value"
+msgstr "%s: YEREL (LOCAL) yönergesi yalnız bir yazmaç veya kesin değerle geçerlidir"
+
+#: elf64-mmix.c:1535
+#, c-format
+msgid "%s: LOCAL directive: Register $%ld is not a local register. First global register is $%ld."
+msgstr ""
+"%s: YEREL (LOCAL) yönergesi: $%ld yazmacı yerel yazmaç değil.\n"
+" İlk evrensel yazmaç: $%ld."
+
+#: elf64-mmix.c:1994
+#, c-format
+msgid "%s: Error: multiple definition of `%s'; start of %s is set in a earlier linked file\n"
+msgstr ""
+"%s: Hata: `%s' birden fazla defa tanımlanmış; %s'nin başlangıcı daha önce\n"
+" baÄŸlanan bir dosyada.\n"
+
+#: elf64-mmix.c:2053
+msgid "Register section has contents\n"
+msgstr "Yazmaç bölümünde içerik yok\n"
+
+#: elf64-mmix.c:2216
+#, c-format
+msgid ""
+"Internal inconsistency: remaining %u != max %u.\n"
+" Please report this bug."
+msgstr ""
+"İç uyumsuzluk: kalan %u != maksimum %u. \n"
+" Lütfen bu hatayı bildirin."
+
+#: elf64-ppc.c:2388 libbfd.c:831
+#, c-format
+msgid "%s: compiled for a big endian system and target is little endian"
+msgstr "%s: büyük sonlu sistem için derlenmiş ve hedef küçük sonlu"
+
+#: elf64-ppc.c:2391 libbfd.c:833
+#, c-format
+msgid "%s: compiled for a little endian system and target is big endian"
+msgstr "%s: küçük sonlu sistem için derlenmiş ve hedef büyük sonlu"
+
+#: elf64-ppc.c:4857
+#, c-format
+msgid "%s: unexpected reloc type %u in .opd section"
+msgstr "%s: opd bölümünde beklenmeyen yerdeğişim türü %u"
+
+#: elf64-ppc.c:4877
+#, c-format
+msgid "%s: .opd is not a regular array of opd entries"
+msgstr "%s: opd, opd girdilerinin düzenli dizisi değil"
+
+#: elf64-ppc.c:4897
+#, c-format
+msgid "%s: undefined sym `%s' in .opd section"
+msgstr "%s: opd bölümünde tanımlanmamış `%s' sembolü"
+
+#: elf64-ppc.c:6136
+#, c-format
+msgid "can't find branch stub `%s'"
+msgstr "`%s' dal koçanı bulunamadı"
+
+#: elf64-ppc.c:6175 elf64-ppc.c:6250
+#, c-format
+msgid "linkage table error against `%s'"
+msgstr "`%s'ye bağlama tablosu hatası"
+
+#: elf64-ppc.c:6340
+#, c-format
+msgid "can't build branch stub `%s'"
+msgstr "`%s' dal koçanı derlenemedi"
+
+#: elf64-ppc.c:7047
+msgid ".glink and .plt too far apart"
+msgstr " glink ve plt birbirine fazla uzak"
+
+#: elf64-ppc.c:7135
+msgid "stubs don't match calculated size"
+msgstr "koçanlar hesaplanan boyla eşleşmiyor"
+
+#: elf64-ppc.c:7147
+#, c-format
+msgid ""
+"linker stubs in %u groups\n"
+" branch %lu\n"
+" toc adjust %lu\n"
+" long branch %lu\n"
+" long toc adj %lu\n"
+" plt call %lu"
+msgstr ""
+"%u grupta bağlayıcı koçanları\n"
+" dal %lu\n"
+" toc ayarlama %lu\n"
+" uzun dal %lu\n"
+" uzun toc ayar%lu\n"
+" plt çağrısı %lu"
+
+#: elf64-ppc.c:7723
+#, c-format
+msgid "%s(%s+0x%lx): automatic multiple TOCs not supported using your crt files; recompile with -mminimal-toc or upgrade gcc"
+msgstr "%s(%s+0x%lx): otomatik çoklu TOC sizin crt dosyalarınızı kullanarak desteklenmez; -mminimal-toc kullanarak yeniden derleyin veya gcc'de sürüm yükseltmesi yapın"
+
+#: elf64-ppc.c:7731
+#, c-format
+msgid "%s(%s+0x%lx): sibling call optimization to `%s' does not allow automatic multiple TOCs; recompile with -mminimal-toc or -fno-optimize-sibling-calls, or make `%s' extern"
+msgstr "%s(%s+0x%lx): `%s'e kardeş çağrı iyileştirmesi otomatik çoklu TOCa izin vermez; -mminimal-toc veya -fno-optimize-sibling-calls ile yeniden derleyin, veya make `%s' extern"
+
+#: elf64-ppc.c:8329
+#, c-format
+msgid "%s: relocation %s is not supported for symbol %s."
+msgstr "%s: %s yerdeğişimi %s sembolü için desteklenmiyor."
+
+#: elf64-ppc.c:8408
+#, c-format
+msgid "%s: error: relocation %s not a multiple of %d"
+msgstr "%s: hata: %s yerdeğişimi %d'nin katı değil"
+
+#: elf64-sparc.c:1370
+#, c-format
+msgid "%s: check_relocs: unhandled reloc type %d"
+msgstr "%s: check_relocs: desteklenmeyen yerdeğişim türü %d"
+
+#: elf64-sparc.c:1407
+#, c-format
+msgid "%s: Only registers %%g[2367] can be declared using STT_REGISTER"
+msgstr "%s: Yalnız %%g[2367] yazmaçları STT_REGISTER ile bildirilebilir"
+
+#: elf64-sparc.c:1427
+#, c-format
+msgid "Register %%g%d used incompatibly: %s in %s, previously %s in %s"
+msgstr "%%g%1$d yazmacı uyumsuz kullanılmış: %3$s içinde %2$s, daha önce %5$s içinde %4$s idi"
+
+#: elf64-sparc.c:1450
+#, c-format
+msgid "Symbol `%s' has differing types: REGISTER in %s, previously %s in %s"
+msgstr "`%1$s' sembolünün farklı türleri var: %2$s içinde REGISTER (yazmaç), daha önce %4$s içinde %3$s"
+
+#: elf64-sparc.c:1496
+#, c-format
+msgid "Symbol `%s' has differing types: %s in %s, previously REGISTER in %s"
+msgstr ""
+"`%1$s' sembolünün farklı türleri var: %3$s içinde %2$s, \n"
+" daha önce %4$s içinde REGISTER (yazmaç)"
+
+#: elf64-sparc.c:3053
+#, c-format
+msgid "%s: linking UltraSPARC specific with HAL specific code"
+msgstr "%s: UltraSPARC'a özel kod HAL'e özel kod ile bağlanıyor"
+
+#: elf64-x86-64.c:739
+#, c-format
+msgid "%s: %s' accessed both as normal and thread local symbol"
+msgstr "%s: `%s'a hem normal, hem de iplikçik yerel sembolü olarak erişildi"
+
+#: elfcode.h:1113
+#, c-format
+msgid "%s: version count (%ld) does not match symbol count (%ld)"
+msgstr "%s: sürüm sayısı (%ld) sembol sayısı (%ld) ile eşleşmiyor"
+
+#: elfcode.h:1342
+#, c-format
+msgid "%s(%s): relocation %d has invalid symbol index %ld"
+msgstr "%s(%s): %d yerdeğişimi geçersiz sembol indeksi %ld'ye sahip"
+
+#: elflink.c:1456
+#, c-format
+msgid "%s: warning: unexpected redefinition of indirect versioned symbol `%s'"
+msgstr "%s: uyarı: endirekt sürümlü sembol `%s' için beklenmeyen yeniden tanımlama"
+
+#: elflink.c:1807
+#, c-format
+msgid "%s: undefined versioned symbol name %s"
+msgstr "%s: sürümlü sembol ismi %s tanımlı değil"
+
+#: elflink.c:2142
+#, c-format
+msgid "%s: relocation size mismatch in %s section %s"
+msgstr "%1$s: %3$s bölümünde %2$s içinde yerdeğişim boy uyuşmazlığı"
+
+#: elflink.c:2434
+#, c-format
+msgid "warning: type and size of dynamic symbol `%s' are not defined"
+msgstr "uyarı: `%s' dinamik sembolünün türü ve boyu tanımlı değil"
+
+#: elflink.h:1022
+#, c-format
+msgid "%s: %s: invalid version %u (max %d)"
+msgstr "%s: %s: geçersiz sürüm %u (maksimum %d)"
+
+#: elflink.h:1063
+#, c-format
+msgid "%s: %s: invalid needed version %d"
+msgstr "%s: %s: geçersiz gerekli sürüm %d"
+
+#: elflink.h:1238
+#, c-format
+msgid "Warning: alignment %u of symbol `%s' in %s is smaller than %u in %s"
+msgstr "Uyarı: %3$s içinde `%2$s' sembolünün %1$u hizalaması %5$s içinde %4$u'dan daha küçük"
+
+#: elflink.h:1252
+#, c-format
+msgid "Warning: size of symbol `%s' changed from %lu in %s to %lu in %s"
+msgstr "Uyarı: `%1$s' sembolünün boyu %3$s içinde %2$lu'dan %5$s içinde %4$lu'ya değişti"
+
+#: elflink.h:2160
+#, c-format
+msgid "%s: undefined version: %s"
+msgstr "%s: tanımsız sürüm: %s"
+
+#: elflink.h:2226
+#, c-format
+msgid "%s: .preinit_array section is not allowed in DSO"
+msgstr "%s: DSO içinde preinit_array'e izin verilmiyor"
+
+#: elflink.h:3078
+msgid "Not enough memory to sort relocations"
+msgstr "Yerdeğişimleri sıralamak için gerekli bellek yok"
+
+#: elflink.h:3958 elflink.h:4001
+#, c-format
+msgid "%s: could not find output section %s"
+msgstr "%s: çıktı bölümü %s bulunamadı"
+
+#: elflink.h:3964
+#, c-format
+msgid "warning: %s section has zero size"
+msgstr "uyarı: %s bölümü sıfır boyunda"
+
+#: elflink.h:4483
+#, c-format
+msgid "%s: %s symbol `%s' in %s is referenced by DSO"
+msgstr "%1$s: %4$s içinde %2$s sembolü `%3$s' DSO tarafından referans ediliyor"
+
+#: elflink.h:4564
+#, c-format
+msgid "%s: could not find output section %s for input section %s"
+msgstr "%1$s: girdi bölümü %3$s için çıktı bölümü %2$s bulunamadı"
+
+#: elflink.h:4666
+#, c-format
+msgid "%s: %s symbol `%s' isn't defined"
+msgstr "%s: %s sembol `%s' tanımlı değil"
+
+#: elflink.h:5053 elflink.h:5095
+msgid "%T: discarded in section `%s' from %s\n"
+msgstr "%1$T: %3$s `%2$s' bölümünde atıldı\n"
+
+#: elfxx-mips.c:887
+msgid "static procedure (no name)"
+msgstr "statik altyordam (isimsiz)"
+
+#: elfxx-mips.c:1897
+msgid "not enough GOT space for local GOT entries"
+msgstr "yerel GOT girdileri için yeterli GOT yeri yok"
+
+#: elfxx-mips.c:3691
+#, c-format
+msgid "%s: %s+0x%lx: jump to stub routine which is not jal"
+msgstr "%s: %s+0x%lx: jal olmayan koçan yordamına sıçrama"
+
+#: elfxx-mips.c:5192
+#, c-format
+msgid "%s: Malformed reloc detected for section %s"
+msgstr "%s: %s bölümü için geçersiz yer değişim bulundu"
+
+#: elfxx-mips.c:5266
+#, c-format
+msgid "%s: CALL16 reloc at 0x%lx not against global symbol"
+msgstr "%s: 0x%lx'deki CALL16 yerdeğişimi evrensel sembole göre değil"
+
+#: elfxx-mips.c:8692
+#, c-format
+msgid "%s: illegal section name `%s'"
+msgstr "%s: geçersiz bölüm adı `%s'"
+
+#: elfxx-mips.c:9025
+#, c-format
+msgid "%s: endianness incompatible with that of the selected emulation"
+msgstr "%s: seçilen öykünüm ile sonluluk uyumlu değil"
+
+#: elfxx-mips.c:9037
+#, c-format
+msgid "%s: ABI is incompatible with that of the selected emulation"
+msgstr "%s: ABI, seçilen öykünümle uyumlu değil"
+
+#: elfxx-mips.c:9104
+#, c-format
+msgid "%s: warning: linking PIC files with non-PIC files"
+msgstr "%s: uyarı: PIC dosyaları PIC olmayan dosyalarla bağlanıyor"
+
+#: elfxx-mips.c:9121
+#, c-format
+msgid "%s: linking 32-bit code with 64-bit code"
+msgstr "%s: 64 bitlik dosyalar 32 bitlik dosyalarla bağlanıyor"
+
+#: elfxx-mips.c:9149
+#, c-format
+msgid "%s: linking %s module with previous %s modules"
+msgstr "%s: %s modülü önceki %s modülle bağlanıyor"
+
+#: elfxx-mips.c:9172
+#, c-format
+msgid "%s: ABI mismatch: linking %s module with previous %s modules"
+msgstr "%s: ABI uyumsuzluğu: %s modülü önceki %s modülle bağlanıyor"
+
+#: elfxx-mips.c:9241
+msgid " [abi=O32]"
+msgstr " [abi=O32]"
+
+#: elfxx-mips.c:9243
+msgid " [abi=O64]"
+msgstr " [abi=O64]"
+
+#: elfxx-mips.c:9245
+msgid " [abi=EABI32]"
+msgstr " [abi=EABI32]"
+
+#: elfxx-mips.c:9247
+msgid " [abi=EABI64]"
+msgstr " [abi=EABI64]"
+
+#: elfxx-mips.c:9249
+msgid " [abi unknown]"
+msgstr " [abi bilinmiyor]"
+
+#: elfxx-mips.c:9251
+msgid " [abi=N32]"
+msgstr " [abi=N32]"
+
+#: elfxx-mips.c:9253
+msgid " [abi=64]"
+msgstr " [abi=64]"
+
+#: elfxx-mips.c:9255
+msgid " [no abi set]"
+msgstr " [abi atanmamış]"
+
+#: elfxx-mips.c:9258
+msgid " [mips1]"
+msgstr " [mips1]"
+
+#: elfxx-mips.c:9260
+msgid " [mips2]"
+msgstr " [mips2]"
+
+#: elfxx-mips.c:9262
+msgid " [mips3]"
+msgstr " [mips3]"
+
+#: elfxx-mips.c:9264
+msgid " [mips4]"
+msgstr " [mips4]"
+
+#: elfxx-mips.c:9266
+msgid " [mips5]"
+msgstr " [mips5]"
+
+#: elfxx-mips.c:9268
+msgid " [mips32]"
+msgstr " [mips32]"
+
+#: elfxx-mips.c:9270
+msgid " [mips64]"
+msgstr " [mips64]"
+
+#: elfxx-mips.c:9272
+msgid " [mips32r2]"
+msgstr " [mips32r2]"
+
+#: elfxx-mips.c:9274
+msgid " [unknown ISA]"
+msgstr " [bilinmeyen ISA]"
+
+#: elfxx-mips.c:9277
+msgid " [mdmx]"
+msgstr " [mdmx]"
+
+#: elfxx-mips.c:9280
+msgid " [mips16]"
+msgstr " [mips16]"
+
+#: elfxx-mips.c:9283
+msgid " [32bitmode]"
+msgstr " [32bitkipi]"
+
+#: elfxx-mips.c:9285
+msgid " [not 32bitmode]"
+msgstr " [32bitkipi deÄŸil]"
+
+#: i386linux.c:457 m68klinux.c:461 sparclinux.c:458
+#, c-format
+msgid "Output file requires shared library `%s'\n"
+msgstr "Çıktı dosyası için paylaşımlı kitaplık `%s' gerekli\n"
+
+#: i386linux.c:465 m68klinux.c:469 sparclinux.c:466
+#, c-format
+msgid "Output file requires shared library `%s.so.%s'\n"
+msgstr "Çıktı dosyası için paylaşımlı kitaplık `%s.so.%s' gerekli\n"
+
+#: i386linux.c:654 i386linux.c:704 m68klinux.c:661 m68klinux.c:709
+#: sparclinux.c:656 sparclinux.c:706
+#, c-format
+msgid "Symbol %s not defined for fixups\n"
+msgstr "%s sembolü düzeltmeler için tanımlı değil\n"
+
+#: i386linux.c:728 m68klinux.c:733 sparclinux.c:730
+msgid "Warning: fixup count mismatch\n"
+msgstr "Uyarı: düzeltme sayı uyumsuzluğu\n"
+
+#: ieee.c:293
+#, c-format
+msgid "%s: string too long (%d chars, max 65535)"
+msgstr "%s: dizge fazla uzun (%d karakter, en fazla 65535)"
+
+#: ieee.c:428
+#, c-format
+msgid "%s: unrecognized symbol `%s' flags 0x%x"
+msgstr "%s: bilinmeyen `%s' sembol bayrakları 0x%x"
+
+#: ieee.c:938
+#, c-format
+msgid "%s: unimplemented ATI record %u for symbol %u"
+msgstr "%1$s: %3$u sembolü için desteklenmeyen ATI kaydı %2$u"
+
+#: ieee.c:963
+#, c-format
+msgid "%s: unexpected ATN type %d in external part"
+msgstr "%s: dış parçada beklenmeyen ATN türü %d"
+
+#: ieee.c:985
+#, c-format
+msgid "%s: unexpected type after ATN"
+msgstr "%s: ATN'den sonra beklenmeyen tür"
+
+#: ihex.c:264
+#, c-format
+msgid "%s:%d: unexpected character `%s' in Intel Hex file\n"
+msgstr "%s:%d: Intel Onaltılık dosyasında beklenmeyen `%s' karakteri\n"
+
+#: ihex.c:372
+#, c-format
+msgid "%s:%u: bad checksum in Intel Hex file (expected %u, found %u)"
+msgstr ""
+"%s:%u: Intel Onaltılık dosyasında hatalı sağlama toplamı\n"
+" (%u beklendi, %u bulundu)"
+
+#: ihex.c:426
+#, c-format
+msgid "%s:%u: bad extended address record length in Intel Hex file"
+msgstr "%s:%u: Intel Onaltılık dosyasında hatalı uzun adres kaydı uzunluğu"
+
+#: ihex.c:443
+#, c-format
+msgid "%s:%u: bad extended start address length in Intel Hex file"
+msgstr "%s:%u: Intel Onaltılık dosyasında hatalı uzun başlangıç adresi uzunluğu"
+
+#: ihex.c:460
+#, c-format
+msgid "%s:%u: bad extended linear address record length in Intel Hex file"
+msgstr "%s:%u: Intel Onaltılık dosyasında hatalı uzun lineer adres kaydı uzunluğu"
+
+#: ihex.c:477
+#, c-format
+msgid "%s:%u: bad extended linear start address length in Intel Hex file"
+msgstr "%s:%u: Intel Onaltılık dosyasında hatalı uzun lineer başlangıç adres uzunluğu"
+
+#: ihex.c:494
+#, c-format
+msgid "%s:%u: unrecognized ihex type %u in Intel Hex file\n"
+msgstr "%s:%u: Intel Onaltılık dosyasında bilinmeyen onaltılık türü %u\n"
+
+#: ihex.c:619
+#, c-format
+msgid "%s: internal error in ihex_read_section"
+msgstr "%s: ihex_read_section'da iç hata"
+
+#: ihex.c:654
+#, c-format
+msgid "%s: bad section length in ihex_read_section"
+msgstr "%s: ihex_read_section'da hatalı bölüm uzunluğu"
+
+#: ihex.c:872
+#, c-format
+msgid "%s: address 0x%s out of range for Intel Hex file"
+msgstr "%s: Intex Onaltılık dosyası için 0x%s adresi kapsamdışı"
+
+#: libbfd.c:861
+#, c-format
+msgid "Deprecated %s called at %s line %d in %s\n"
+msgstr "Geçersizleşmiş %s, %s'da, %d satırı, %s içerisinde çağrıldı\n"
+
+#: libbfd.c:864
+#, c-format
+msgid "Deprecated %s called\n"
+msgstr "Geçerliliği kalkmış %s çağrıldı\n"
+
+#: linker.c:1829
+#, c-format
+msgid "%s: indirect symbol `%s' to `%s' is a loop"
+msgstr "%1$s: `%3$s'den endirekt sembol `%2$s'e çevrim"
+
+#: linker.c:2697
+#, c-format
+msgid "Attempt to do relocatable link with %s input and %s output"
+msgstr "%s girdi ve %s çıktısı ile yerdeğişimli bağ deneniyor"
+
+#: merge.c:896
+#, c-format
+msgid "%s: access beyond end of merged section (%ld + %ld)"
+msgstr "%s: karıştırılmış bölümün sonundan ileride erişim (%ld + %ld)"
+
+#: mmo.c:503
+#, c-format
+msgid "%s: No core to allocate section name %s\n"
+msgstr "%s: %s bölüm adını ayıracak `core' yok\n"
+
+#: mmo.c:579
+#, c-format
+msgid "%s: No core to allocate a symbol %d bytes long\n"
+msgstr "%s: %d bayt uzunluğunda bir sembole yer ayırmak için `core' yok\n"
+
+#: mmo.c:1287
+#, c-format
+msgid "%s: invalid mmo file: initialization value for $255 is not `Main'\n"
+msgstr "%s: geçersiz mmo dosyası: $255 için başlangıç değeri `Main' değil\n"
+
+#: mmo.c:1433
+#, c-format
+msgid "%s: unsupported wide character sequence 0x%02X 0x%02X after symbol name starting with `%s'\n"
+msgstr ""
+"%1$s: `%4$s' ile başlayan sembol adından sonra desteklenmeyen\n"
+" geniÅŸ karakter dizisi 0x%2$02X 0x%3$02X\n"
+
+#: mmo.c:1674
+#, c-format
+msgid "%s: invalid mmo file: unsupported lopcode `%d'\n"
+msgstr "%s: geçersiz mmo dosyası: desteklenmeyen lopkod `%d'\n"
+
+#: mmo.c:1684
+#, c-format
+msgid "%s: invalid mmo file: expected YZ = 1 got YZ = %d for lop_quote\n"
+msgstr "%s: geçersiz mmo dosyası: YZ = 1 beklendi, lop_quote için YZ = %d bulundu\n"
+
+#: mmo.c:1720
+#, c-format
+msgid "%s: invalid mmo file: expected z = 1 or z = 2, got z = %d for lop_loc\n"
+msgstr ""
+"%s: geçersiz mmo dosyası: z = 1 veya z = 2 beklendi, \n"
+" lop_loc için z = %d bulundu\n"
+
+#: mmo.c:1766
+#, c-format
+msgid "%s: invalid mmo file: expected z = 1 or z = 2, got z = %d for lop_fixo\n"
+msgstr "%s: geçersiz mmo dosyası: z = 1 veya z = 2 beklendi; lop_fixo için z = %d bulundu\n"
+
+#: mmo.c:1805
+#, c-format
+msgid "%s: invalid mmo file: expected y = 0, got y = %d for lop_fixrx\n"
+msgstr "%s: geçersiz mmo dosyası: y = 0 beklendi; lop_fixrx için y = %d bulundu\n"
+
+#: mmo.c:1814
+#, c-format
+msgid "%s: invalid mmo file: expected z = 16 or z = 24, got z = %d for lop_fixrx\n"
+msgstr ""
+"%s: geçersiz mmo dosyası: z = 16 veya z = 24 beklendi;\n"
+" lop_fixrx için z = %d bulundu\n"
+
+#: mmo.c:1837
+#, c-format
+msgid "%s: invalid mmo file: leading byte of operand word must be 0 or 1, got %d for lop_fixrx\n"
+msgstr ""
+"%s: geçersiz mmo dosyası: işlenen word'un ilk baytı 0 veya 1 olmalı; \n"
+" lop_fixrx için %d bulundu\n"
+
+#: mmo.c:1860
+#, c-format
+msgid "%s: cannot allocate file name for file number %d, %d bytes\n"
+msgstr "%s: %d sayılı dosya için dosya adı ayrılamadı, %d bayt\n"
+
+#: mmo.c:1880
+#, c-format
+msgid "%s: invalid mmo file: file number %d `%s', was already entered as `%s'\n"
+msgstr "%s: geçersiz mmo dosyası: %d sayılı dosya, `%s', zaten `%s' olarak girilmiş\n"
+
+#: mmo.c:1893
+#, c-format
+msgid "%s: invalid mmo file: file name for number %d was not specified before use\n"
+msgstr ""
+"%s: geçersiz mmo dosyası: %d sayısı için dosya adı kullanımdan\n"
+" önce belirtilmemiş\n"
+
+#: mmo.c:1999
+#, c-format
+msgid "%s: invalid mmo file: fields y and z of lop_stab non-zero, y: %d, z: %d\n"
+msgstr ""
+"%s: geçersiz mmo dosyası: lop_stab'in y ve z alanları sıfır değil;\n"
+" y: %d, z: %d\n"
+
+#: mmo.c:2035
+#, c-format
+msgid "%s: invalid mmo file: lop_end not last item in file\n"
+msgstr "%s: geçersiz mmo dosyası: lop_end dosyadaki son girdi değil\n"
+
+#: mmo.c:2048
+#, c-format
+msgid "%s: invalid mmo file: YZ of lop_end (%ld) not equal to the number of tetras to the preceding lop_stab (%ld)\n"
+msgstr ""
+"%s: geçersiz mmo dosyası: lop_end'in YZ'si (%ld); bir önceki \n"
+" lop_stab'in (%ld) dörtlü sayısına eşit değil\n"
+
+#: mmo.c:2698
+#, c-format
+msgid "%s: invalid symbol table: duplicate symbol `%s'\n"
+msgstr "%s: geçersiz sembol tablosu: tekrarlanmış sembol `%s'\n"
+
+#: mmo.c:2949
+#, c-format
+msgid "%s: Bad symbol definition: `Main' set to %s rather than the start address %s\n"
+msgstr ""
+"%1$s: Hatalı sembol tanımı: `Main' başlangıç adresi %3$s yerine \n"
+" %2$s olarak tanımlanmış\n"
+
+#: mmo.c:3039
+#, c-format
+msgid "%s: warning: symbol table too large for mmo, larger than 65535 32-bit words: %d. Only `Main' will be emitted.\n"
+msgstr ""
+"%s: uyarı: sembol tablosu mmo için fazla büyük, 65535 32-bit word'den\n"
+" fazla: %d. Yalnız `Main' üretilecek. \n"
+
+#: mmo.c:3084
+#, c-format
+msgid "%s: internal error, symbol table changed size from %d to %d words\n"
+msgstr "%s: iç hata, sembol tablosu büyüklüğü %d'den %d word'e değişti\n"
+
+#: mmo.c:3139
+#, c-format
+msgid "%s: internal error, internal register section %s had contents\n"
+msgstr "%s: iç hata, %s iç yazmaç bölümü içerik taşıyor\n"
+
+#: mmo.c:3191
+#, c-format
+msgid "%s: no initialized registers; section length 0\n"
+msgstr "%s: ilklenen yazmaç yok; bölüm uzunluğu 0\n"
+
+#: mmo.c:3197
+#, c-format
+msgid "%s: too many initialized registers; section length %ld\n"
+msgstr "%s: çok fazla ilklenmiş yazmaç; bölüm uzunluğu %ld\n"
+
+#: mmo.c:3202
+#, c-format
+msgid "%s: invalid start address for initialized registers of length %ld: 0x%lx%08lx\n"
+msgstr "%s: %ld uzunluğunda ilklenmiş yazmaçlar için hatalı başlangıç adresi: 0x%lx%08lx\n"
+
+#: oasys.c:1052
+#, c-format
+msgid "%s: can not represent section `%s' in oasys"
+msgstr "%s: oasys'de `%s' bölümü gösterilemiyor"
+
+#: osf-core.c:137
+#, c-format
+msgid "Unhandled OSF/1 core file section type %d\n"
+msgstr "Desteklenmeyen OSF/1 core dosyası bölüm türü %d\n"
+
+#: pe-mips.c:659
+#, c-format
+msgid "%s: `ld -r' not supported with PE MIPS objects\n"
+msgstr "%s: `ld -r' PE MIPS nesneleri ile birlikte desteklenmiyor\n"
+
+#. OK, at this point the following variables are set up:
+#. src = VMA of the memory we're fixing up
+#. mem = pointer to memory we're fixing up
+#. val = VMA of what we need to refer to
+#.
+#: pe-mips.c:795
+#, c-format
+msgid "%s: unimplemented %s\n"
+msgstr "%s: tamamlanmamış %s\n"
+
+#: pe-mips.c:821
+#, c-format
+msgid "%s: jump too far away\n"
+msgstr "%s: sıçrama fazla uzak\n"
+
+#: pe-mips.c:848
+#, c-format
+msgid "%s: bad pair/reflo after refhi\n"
+msgstr "%s: refhi'den sonra hatalı çift/reflo\n"
+
+#. XXX code yet to be written.
+#: peicode.h:787
+#, c-format
+msgid "%s: Unhandled import type; %x"
+msgstr "%s: Desteklenmeyen ithal türü; %x"
+
+#: peicode.h:792
+#, c-format
+msgid "%s: Unrecognised import type; %x"
+msgstr "%s: Tanınmayan ithal türü; %x"
+
+#: peicode.h:806
+#, c-format
+msgid "%s: Unrecognised import name type; %x"
+msgstr "%s: Tanınmayan ithal isim türü; %x"
+
+#: peicode.h:1164
+#, c-format
+msgid "%s: Unrecognised machine type (0x%x) in Import Library Format archive"
+msgstr "%s: İthal Kitaplık Biçem (ILF) arşivinde tanınmayan makina türü (0x%x) "
+
+#: peicode.h:1176
+#, c-format
+msgid "%s: Recognised but unhandled machine type (0x%x) in Import Library Format archive"
+msgstr "%s: İthal Kitaplık Biçem (ILF) arşivinde bilinen fakat desteklenmeyen makina türü (0x%x)"
+
+#: peicode.h:1193
+#, c-format
+msgid "%s: size field is zero in Import Library Format header"
+msgstr "%s: İthal Kitaplık Biçem (ILF) başlığında boy alanı sıfır"
+
+#: peicode.h:1224
+#, c-format
+msgid "%s: string not null terminated in ILF object file."
+msgstr "%s: ILF nesne dosyasında dizge boş değerle sonlanmamış."
+
+#: ppcboot.c:416
+msgid ""
+"\n"
+"ppcboot header:\n"
+msgstr ""
+"\n"
+"ppcboot başlığı:\n"
+
+#: ppcboot.c:417
+#, c-format
+msgid "Entry offset = 0x%.8lx (%ld)\n"
+msgstr "Girdi göreli konumu = 0x%.8lx (%ld)\n"
+
+#: ppcboot.c:418
+#, c-format
+msgid "Length = 0x%.8lx (%ld)\n"
+msgstr "Uzunluk = 0x%.8lx (%ld)\n"
+
+#: ppcboot.c:421
+#, c-format
+msgid "Flag field = 0x%.2x\n"
+msgstr "Bayrak alanı = 0x%.2x\n"
+
+#: ppcboot.c:427
+#, c-format
+msgid "Partition name = \"%s\"\n"
+msgstr "Bölüm adı = \"%s\"\n"
+
+#: ppcboot.c:446
+#, c-format
+msgid ""
+"\n"
+"Partition[%d] start = { 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x }\n"
+msgstr ""
+"\n"
+"Bölüm[%d] başlangıcı = { 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x }\n"
+
+#: ppcboot.c:452
+#, c-format
+msgid "Partition[%d] end = { 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x }\n"
+msgstr "Bölüm[%d] sonu = { 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x }\n"
+
+#: ppcboot.c:458
+#, c-format
+msgid "Partition[%d] sector = 0x%.8lx (%ld)\n"
+msgstr "Bölüm[%d] sektörü = 0x%.8lx (%ld)\n"
+
+#: ppcboot.c:459
+#, c-format
+msgid "Partition[%d] length = 0x%.8lx (%ld)\n"
+msgstr "Bölüm[%d] uzunluğu = 0x%.8lx (%ld)\n"
+
+#: som.c:5422
+msgid "som_sizeof_headers unimplemented"
+msgstr "som_sizeof_headers tamamlanmamış"
+
+#: srec.c:302
+#, c-format
+msgid "%s:%d: Unexpected character `%s' in S-record file\n"
+msgstr "%s:%d: S-kayıt dosyasında beklenmeyen `%s' karakteri\n"
+
+#: stabs.c:319
+#, c-format
+msgid "%s(%s+0x%lx): Stabs entry has invalid string index."
+msgstr "%s(%s+0x%lx): Stabs girdisinde geçersiz dizge indeksi."
+
+#: syms.c:1019
+msgid "Unsupported .stab relocation"
+msgstr "Desteklenmeyen .stab yerdeÄŸiÅŸimi"
+
+#: vms-gsd.c:356
+#, c-format
+msgid "bfd_make_section (%s) failed"
+msgstr "bfd_make_section (%s) başarısız"
+
+#: vms-gsd.c:371
+#, c-format
+msgid "bfd_set_section_flags (%s, %x) failed"
+msgstr "bfd_set_section_flags (%s, %x) başarısız"
+
+#: vms-gsd.c:407
+#, c-format
+msgid "Size mismatch section %s=%lx, %s=%lx"
+msgstr "Boy uyumsuzluğu bölümü %s=%lx, %s=%lx"
+
+#: vms-gsd.c:704
+#, c-format
+msgid "unknown gsd/egsd subtype %d"
+msgstr "bilinmeyen gsd/egsd alt türü %d"
+
+#: vms-hdr.c:408
+msgid "Object module NOT error-free !\n"
+msgstr "Nesne modülü hatasız DEĞİL !\n"
+
+#: vms-misc.c:541
+#, c-format
+msgid "Stack overflow (%d) in _bfd_vms_push"
+msgstr "_bfd_vms_push'da yığıt taşması (%d)"
+
+#: vms-misc.c:559
+msgid "Stack underflow in _bfd_vms_pop"
+msgstr "_bfd_vms_pop'da yığıt alt taşması"
+
+#: vms-misc.c:918
+msgid "_bfd_vms_output_counted called with zero bytes"
+msgstr "_bfd_vms_output_counted sıfır bayt ile çağrıldı"
+
+#: vms-misc.c:923
+msgid "_bfd_vms_output_counted called with too many bytes"
+msgstr "_bfd_vms_output_counted fazla bayt ile çağrıldı"
+
+#: vms-misc.c:1054
+#, c-format
+msgid "Symbol %s replaced by %s\n"
+msgstr "%s sembolü %s ile değiştirildi\n"
+
+#: vms-misc.c:1117
+#, c-format
+msgid "failed to enter %s"
+msgstr "%s'e giriş başarısız"
+
+#: vms-tir.c:102
+msgid "No Mem !"
+msgstr "Hafıza Yok !"
+
+#: vms-tir.c:383
+#, c-format
+msgid "bad section index in %s"
+msgstr "%s içinde hatalı bölüm indeksi"
+
+#: vms-tir.c:396
+#, c-format
+msgid "unsupported STA cmd %s"
+msgstr "Desteklenmeyen STA komutu %s"
+
+#: vms-tir.c:401 vms-tir.c:1261
+#, c-format
+msgid "reserved STA cmd %d"
+msgstr "Ayrılmış STA komutu %d"
+
+#: vms-tir.c:512 vms-tir.c:535
+#, c-format
+msgid "%s: no symbol \"%s\""
+msgstr "%s: \"%s\" sembolü yok"
+
+#. unsigned shift
+#. rotate
+#. Redefine symbol to current location.
+#. Define a literal.
+#: vms-tir.c:602 vms-tir.c:714 vms-tir.c:824 vms-tir.c:842 vms-tir.c:850
+#: vms-tir.c:859 vms-tir.c:1584
+#, c-format
+msgid "%s: not supported"
+msgstr "%s: desteklenmiyor"
+
+#: vms-tir.c:607 vms-tir.c:1439
+#, c-format
+msgid "%s: not implemented"
+msgstr "%s: tamamlanmamış"
+
+#: vms-tir.c:611 vms-tir.c:1443
+#, c-format
+msgid "reserved STO cmd %d"
+msgstr "Ayrılmış STO komutu %d"
+
+#: vms-tir.c:729 vms-tir.c:1589
+#, c-format
+msgid "reserved OPR cmd %d"
+msgstr "Ayrılmış OPR komutu %d"
+
+#: vms-tir.c:797 vms-tir.c:1653
+#, c-format
+msgid "reserved CTL cmd %d"
+msgstr "Ayrılmış CTL komutu %d"
+
+#. stack byte from image
+#. arg: none.
+#: vms-tir.c:1169
+msgid "stack-from-image not implemented"
+msgstr "Görüntüden-yığıt tamamlanmamış"
+
+#: vms-tir.c:1187
+msgid "stack-entry-mask not fully implemented"
+msgstr "Yığın girdi maskı tamamlanmamış"
+
+#. 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.
+#: vms-tir.c:1201
+msgid "PASSMECH not fully implemented"
+msgstr "PASSMECH tamamlanmamış"
+
+#: vms-tir.c:1220
+msgid "stack-local-symbol not fully implemented"
+msgstr "Yerel sembol yığıtı tamamlanmamış"
+
+#: vms-tir.c:1233
+msgid "stack-literal not fully implemented"
+msgstr "Yığıt sabiti tamamlanmamış"
+
+#: vms-tir.c:1254
+msgid "stack-local-symbol-entry-point-mask not fully implemented"
+msgstr "Yığın yerel sembol girdi noktası maskı tamamlanmamış"
+
+#: vms-tir.c:1531 vms-tir.c:1543 vms-tir.c:1555 vms-tir.c:1567 vms-tir.c:1632
+#: vms-tir.c:1640 vms-tir.c:1648
+#, c-format
+msgid "%s: not fully implemented"
+msgstr "%s: tamamlanmamış"
+
+#: vms-tir.c:1705
+#, c-format
+msgid "obj code %d not found"
+msgstr "Nesne kodu %d bulunmadı"
+
+#: vms-tir.c:2043
+#, c-format
+msgid "SEC_RELOC with no relocs in section %s"
+msgstr "%s bölümünde yerdeğişim olmaksızın SEC_RELOC"
+
+#: vms-tir.c:2331
+#, c-format
+msgid "Unhandled relocation %s"
+msgstr "Desteklenmeyen yerdeÄŸiÅŸim %s"
+
+#: xcofflink.c:1244
+#, c-format
+msgid "%s: `%s' has line numbers but no enclosing section"
+msgstr "%s: `%s' satır numaralarına sahip fakat onu içeren bölümü yok"
+
+#: xcofflink.c:1297
+#, c-format
+msgid "%s: class %d symbol `%s' has no aux entries"
+msgstr "%s: sınıf %d sembol `%s'un alternatif girdileri yok"
+
+#: xcofflink.c:1320
+#, c-format
+msgid "%s: symbol `%s' has unrecognized csect type %d"
+msgstr "%s: `%s' sembolünde bilinmeyen csect türü %d var"
+
+#: xcofflink.c:1332
+#, c-format
+msgid "%s: bad XTY_ER symbol `%s': class %d scnum %d scnlen %d"
+msgstr "%s: hatalı XTY_ER sembolü `%s': sınıf %d scnum %d scnlen %d"
+
+#: xcofflink.c:1368
+#, c-format
+msgid "%s: XMC_TC0 symbol `%s' is class %d scnlen %d"
+msgstr "%s: XMC_TC0 sembolü `%s': sınıf %d scnlen %d"
+
+#: xcofflink.c:1520
+#, c-format
+msgid "%s: csect `%s' not in enclosing section"
+msgstr "%s: csect `%s' onu içeren bölümde değil"
+
+#: xcofflink.c:1627
+#, c-format
+msgid "%s: misplaced XTY_LD `%s'"
+msgstr "%s: XTY_LD `%s'yanlış yerde"
+
+#: xcofflink.c:1958
+#, c-format
+msgid "%s: reloc %s:%d not in csect"
+msgstr "%s: yerdeğişim %s:%d csect içinde değil"
+
+#: xcofflink.c:2095
+#, c-format
+msgid "%s: XCOFF shared object when not producing XCOFF output"
+msgstr "%s: XCOFF çıktısı oluşturulmazken XCOFF paylaşımlı nesnesi"
+
+#: xcofflink.c:2116
+#, c-format
+msgid "%s: dynamic object with no .loader section"
+msgstr "%s: .loader bölümü olmayan dinamik nesne"
+
+#: xcofflink.c:2761
+#, c-format
+msgid "%s: no such symbol"
+msgstr "%s: böyle bir sembol yok"
+
+#: xcofflink.c:2894
+msgid "error: undefined symbol __rtinit"
+msgstr "hata: tanımlanmamış sembol __rtinit"
+
+#: xcofflink.c:3455
+#, c-format
+msgid "warning: attempt to export undefined symbol `%s'"
+msgstr "uyarı: tanımlanmamış `%s' sembolünü ihraç denemesi"
+
+#: xcofflink.c:4448
+#, c-format
+msgid "TOC overflow: 0x%lx > 0x10000; try -mminimal-toc when compiling"
+msgstr "TOC taşması: 0x%lx > 0x10000; -mminimal-toc ile derlemeyi deneyin"
+
+#: xcofflink.c:5288 xcofflink.c:5755 xcofflink.c:5817 xcofflink.c:6119
+#, c-format
+msgid "%s: loader reloc in unrecognized section `%s'"
+msgstr "%s: bilinmeyen `%s' bölümünde yükleyici yerdeğişimi"
+
+#: xcofflink.c:5310 xcofflink.c:6130
+#, c-format
+msgid "%s: `%s' in loader reloc but not loader sym"
+msgstr "%s: `%s' yükleyici yerdeğişiminde fakat yükleyici sembolü değil"
+
+#: xcofflink.c:5325
+#, c-format
+msgid "%s: loader reloc in read-only section %s"
+msgstr "%s: %s salt-okunur bölümünde yükleyici yerdeğişimi"
+
+#: elf32-ia64.c:2392 elf64-ia64.c:2392
+msgid "@pltoff reloc against local symbol"
+msgstr "yerel sembole @pltoff yerdegisimi"
+
+#: elf32-ia64.c:3804 elf64-ia64.c:3804
+#, c-format
+msgid "%s: short data segment overflowed (0x%lx >= 0x400000)"
+msgstr "%s: kısa veri bölümünde taşma (0x%lx >= 0x400000)"
+
+#: elf32-ia64.c:3815 elf64-ia64.c:3815
+#, c-format
+msgid "%s: __gp does not cover short data segment"
+msgstr "%s: __gp kısa veri bölümünü kapsamıyor"
+
+#: elf32-ia64.c:4131 elf64-ia64.c:4131
+#, c-format
+msgid "%s: linking non-pic code in a shared library"
+msgstr "%s: pic olmayan kod paylaşmalı kitaplıkta bağlanıyor"
+
+#: elf32-ia64.c:4164 elf64-ia64.c:4164
+#, c-format
+msgid "%s: @gprel relocation against dynamic symbol %s"
+msgstr "%s: %s dinamik sembolüne @gprel yerdeğişimi"
+
+#: elf32-ia64.c:4224 elf64-ia64.c:4224
+#, c-format
+msgid "%s: linking non-pic code in a position independent executable"
+msgstr "%s: pic olmayan kod yer bağımsız uygulamaya bağlanıyor"
+
+#: elf32-ia64.c:4363 elf64-ia64.c:4363
+#, c-format
+msgid "%s: @internal branch to dynamic symbol %s"
+msgstr "%s: %s dinamik sembolüne @internal dalı"
+
+#: elf32-ia64.c:4365 elf64-ia64.c:4365
+#, c-format
+msgid "%s: speculation fixup to dynamic symbol %s"
+msgstr "%s: %s dinamik sembolüne spekülasyon düzeltmesi"
+
+#: elf32-ia64.c:4367 elf64-ia64.c:4367
+#, c-format
+msgid "%s: @pcrel relocation against dynamic symbol %s"
+msgstr "%s: %s dinamik sembolüne @pcrel yerdeğişimi"
+
+#: elf32-ia64.c:4579 elf64-ia64.c:4579
+msgid "unsupported reloc"
+msgstr "desteklenmeyen yerdeÄŸiÅŸim"
+
+#: elf32-ia64.c:4858 elf64-ia64.c:4858
+#, c-format
+msgid "%s: linking trap-on-NULL-dereference with non-trapping files"
+msgstr "%s: NULL-halinde-tuzakla karşı-başvurusu tuzaklamayan dosyalarla bağlandı"
+
+#: elf32-ia64.c:4867 elf64-ia64.c:4867
+#, c-format
+msgid "%s: linking big-endian files with little-endian files"
+msgstr "%s: büyük sonlu dosyalar küçük sonlu dosyalarla bağlanıyor"
+
+#: elf32-ia64.c:4876 elf64-ia64.c:4876
+#, c-format
+msgid "%s: linking 64-bit files with 32-bit files"
+msgstr "%s: 64 bitlik dosyalar 32 bitlik dosyalarla bağlanıyor"
+
+#: elf32-ia64.c:4885 elf64-ia64.c:4885
+#, c-format
+msgid "%s: linking constant-gp files with non-constant-gp files"
+msgstr "%s: constant-gp dosyaları constant-gp olmayan dosyalarla bağlanıyor"
+
+#: elf32-ia64.c:4895 elf64-ia64.c:4895
+#, c-format
+msgid "%s: linking auto-pic files with non-auto-pic files"
+msgstr "%s: auto-pic dosyaları auto-pic olmayan dosyalarla bağlanıyor"
+
+#: peigen.c:985 pepigen.c:985
+#, c-format
+msgid "%s: line number overflow: 0x%lx > 0xffff"
+msgstr "%s: satır numarası taşması: 0x%lx > 0xffff"
+
+#: peigen.c:1002 pepigen.c:1002
+#, c-format
+msgid "%s: reloc overflow 1: 0x%lx > 0xffff"
+msgstr "%s: yerdeğişim taşması 1: 0x%lx > 0xffff"
+
+#: peigen.c:1016 pepigen.c:1016
+msgid "Export Directory [.edata (or where ever we found it)]"
+msgstr "İhraç Dizini [.edata (veya nerede bulundu ise)]"
+
+#: peigen.c:1017 pepigen.c:1017
+msgid "Import Directory [parts of .idata]"
+msgstr "İthal Dizini [.idata'nın parçaları]"
+
+#: peigen.c:1018 pepigen.c:1018
+msgid "Resource Directory [.rsrc]"
+msgstr "Kaynak Dizini [.rsrc]"
+
+#: peigen.c:1019 pepigen.c:1019
+msgid "Exception Directory [.pdata]"
+msgstr "Ä°stisna Dizini [.pdata]"
+
+#: peigen.c:1020 pepigen.c:1020
+msgid "Security Directory"
+msgstr "Güvenlik Dizini"
+
+#: peigen.c:1021 pepigen.c:1021
+msgid "Base Relocation Directory [.reloc]"
+msgstr "Temel YerdeÄŸiÅŸim Dizini [.reloc]"
+
+#: peigen.c:1022 pepigen.c:1022
+msgid "Debug Directory"
+msgstr "Hata Ayıklama Dizini"
+
+#: peigen.c:1023 pepigen.c:1023
+msgid "Description Directory"
+msgstr "Açıklama Dizini"
+
+#: peigen.c:1024 pepigen.c:1024
+msgid "Special Directory"
+msgstr "Özel Dizin"
+
+#: peigen.c:1025 pepigen.c:1025
+msgid "Thread Storage Directory [.tls]"
+msgstr "Dal Saklama Dizini [.tls]"
+
+#: peigen.c:1026 pepigen.c:1026
+msgid "Load Configuration Directory"
+msgstr "Ayar Yükleme Dizini"
+
+#: peigen.c:1027 pepigen.c:1027
+msgid "Bound Import Directory"
+msgstr "Sınır İthal Dizini"
+
+#: peigen.c:1028 pepigen.c:1028
+msgid "Import Address Table Directory"
+msgstr "Adres Tablosu Ä°thal Dizini"
+
+#: peigen.c:1029 pepigen.c:1029
+msgid "Delay Import Directory"
+msgstr "Gecikmeli Ä°thal Dizini"
+
+#: peigen.c:1030 peigen.c:1031 pepigen.c:1030 pepigen.c:1031
+msgid "Reserved"
+msgstr "Ayrılmış"
+
+#: peigen.c:1094 pepigen.c:1094
+msgid ""
+"\n"
+"There is an import table, but the section containing it could not be found\n"
+msgstr ""
+"\n"
+"Bir ithal tablosu var, fakat onu içeren bölüm bulunamadı\n"
+
+#: peigen.c:1099 pepigen.c:1099
+#, c-format
+msgid ""
+"\n"
+"There is an import table in %s at 0x%lx\n"
+msgstr ""
+"\n"
+"%s içerisinde 0x%lx'de bir ithal tablosu var\n"
+
+#: peigen.c:1136 pepigen.c:1136
+#, c-format
+msgid ""
+"\n"
+"Function descriptor located at the start address: %04lx\n"
+msgstr ""
+"\n"
+"Başlangıç adresinde işlev betimleyicisi bulundu: %04lx\n"
+
+#: peigen.c:1139 pepigen.c:1139
+#, c-format
+msgid "\tcode-base %08lx toc (loadable/actual) %08lx/%08lx\n"
+msgstr "\tkod temeli %08lx toc (yüklenebilir/gerçek) %08lx/%08lx\n"
+
+#: peigen.c:1145 pepigen.c:1145
+msgid ""
+"\n"
+"No reldata section! Function descriptor not decoded.\n"
+msgstr ""
+"\n"
+"Reldata bölümü yok! İşlev betimleyicisi çözümlenemedi.\n"
+
+#: peigen.c:1150 pepigen.c:1150
+#, c-format
+msgid ""
+"\n"
+"The Import Tables (interpreted %s section contents)\n"
+msgstr ""
+"\n"
+"İthal Tabloları (%s bölüm içeriği çözümlendi)\n"
+
+#: peigen.c:1153 pepigen.c:1153
+msgid ""
+" vma: Hint Time Forward DLL First\n"
+" Table Stamp Chain Name Thunk\n"
+msgstr ""
+" vma: Ä°pucu Zaman Ä°leri DLL Ä°lk\n"
+" Tablo Damga Zincir İsim Parça\n"
+
+#: peigen.c:1204 pepigen.c:1204
+#, c-format
+msgid ""
+"\n"
+"\tDLL Name: %s\n"
+msgstr ""
+"\n"
+"\tDLL Adı: %s\n"
+
+#: peigen.c:1215 pepigen.c:1215
+msgid "\tvma: Hint/Ord Member-Name Bound-To\n"
+msgstr "\tvma: İpucu/Sıra Üye-Adı Sınır\n"
+
+#: peigen.c:1240 pepigen.c:1240
+msgid ""
+"\n"
+"There is a first thunk, but the section containing it could not be found\n"
+msgstr ""
+"\n"
+"Bir ilk parça var, fakat onu içeren bölüm bulunamadı\n"
+
+#: peigen.c:1380 pepigen.c:1380
+msgid ""
+"\n"
+"There is an export table, but the section containing it could not be found\n"
+msgstr ""
+"\n"
+"Bir ihraç tablosu var, fakat onu içeren bölüm bulunamadı\n"
+
+#: peigen.c:1385 pepigen.c:1385
+#, c-format
+msgid ""
+"\n"
+"There is an export table in %s at 0x%lx\n"
+msgstr ""
+"\n"
+"%s içinde 0x%lx'de bir ihraç tablosu var\n"
+
+#: peigen.c:1416 pepigen.c:1416
+#, c-format
+msgid ""
+"\n"
+"The Export Tables (interpreted %s section contents)\n"
+"\n"
+msgstr ""
+"\n"
+"İhraç Tabloları (%s bölüm içeriği çözümlendi)\n"
+"\n"
+
+#: peigen.c:1420 pepigen.c:1420
+#, c-format
+msgid "Export Flags \t\t\t%lx\n"
+msgstr "İhraç Bayrakları \t\t\t%lx\n"
+
+#: peigen.c:1423 pepigen.c:1423
+#, c-format
+msgid "Time/Date stamp \t\t%lx\n"
+msgstr "Saat/Tarih damgası \t\t%lx\n"
+
+#: peigen.c:1426 pepigen.c:1426
+#, c-format
+msgid "Major/Minor \t\t\t%d/%d\n"
+msgstr "Majör/Minör \t\t\t%d/%d\n"
+
+#: peigen.c:1429 pepigen.c:1429
+msgid "Name \t\t\t\t"
+msgstr "Ä°sim \t\t\t\t"
+
+#: peigen.c:1435 pepigen.c:1435
+#, c-format
+msgid "Ordinal Base \t\t\t%ld\n"
+msgstr "Onluk Sistem \t\t\t%ld\n"
+
+#: peigen.c:1438 pepigen.c:1438
+msgid "Number in:\n"
+msgstr "Sayı içinde:\n"
+
+#: peigen.c:1441 pepigen.c:1441
+#, c-format
+msgid "\tExport Address Table \t\t%08lx\n"
+msgstr "\tİhraç Adres Tablosu \t\t%08lx\n"
+
+#: peigen.c:1445 pepigen.c:1445
+#, c-format
+msgid "\t[Name Pointer/Ordinal] Table\t%08lx\n"
+msgstr "\t[İsim Gösterge/Onluk] Tablo\t%08lx\n"
+
+#: peigen.c:1448 pepigen.c:1448
+msgid "Table Addresses\n"
+msgstr "Tablo Adresleri\n"
+
+#: peigen.c:1451 pepigen.c:1451
+msgid "\tExport Address Table \t\t"
+msgstr "\tİhraç Adres Tablosu \t\t"
+
+#: peigen.c:1456 pepigen.c:1456
+msgid "\tName Pointer Table \t\t"
+msgstr "\tİsim Gösterge Tablosu \t\t"
+
+#: peigen.c:1461 pepigen.c:1461
+msgid "\tOrdinal Table \t\t\t"
+msgstr "\tOnluk Tablo \t\t\t"
+
+#: peigen.c:1476 pepigen.c:1476
+#, c-format
+msgid ""
+"\n"
+"Export Address Table -- Ordinal Base %ld\n"
+msgstr ""
+"\n"
+"İhraç Adres Tablosu -- Onluk Sistem %ld\n"
+
+#: peigen.c:1495 pepigen.c:1495
+msgid "Forwarder RVA"
+msgstr "RVA Yönlendiricisi"
+
+#: peigen.c:1506 pepigen.c:1506
+msgid "Export RVA"
+msgstr "RVA İhracı"
+
+#: peigen.c:1513 pepigen.c:1513
+msgid ""
+"\n"
+"[Ordinal/Name Pointer] Table\n"
+msgstr ""
+"\n"
+"[Onluk/İsim Gösterge] Tablosu\n"
+
+#: peigen.c:1568 pepigen.c:1568
+#, c-format
+msgid "Warning, .pdata section size (%ld) is not a multiple of %d\n"
+msgstr "Uyarı, .pdata bölüm boyu (%ld) %d'nin katı değil\n"
+
+#: peigen.c:1572 pepigen.c:1572
+msgid ""
+"\n"
+"The Function Table (interpreted .pdata section contents)\n"
+msgstr ""
+"\n"
+"İşlev Tablosu (.pdata bölüm içeriği çözümlendi)\n"
+
+#: peigen.c:1575 pepigen.c:1575
+msgid " vma:\t\t\tBegin Address End Address Unwind Info\n"
+msgstr " vma:\t\t\tBaşlangıç Adresi Sonlanma Adresi Geri Al Bilgisi\n"
+
+#: peigen.c:1577 pepigen.c:1577
+msgid ""
+" vma:\t\tBegin End EH EH PrologEnd Exception\n"
+" \t\tAddress Address Handler Data Address Mask\n"
+msgstr ""
+" vma:\t\tBaÅŸl. Son EH EH PrologSon Ä°stisna\n"
+" \t\tAdres Adres Yakalay Veri Adres Maske\n"
+
+#: peigen.c:1647 pepigen.c:1647
+msgid " Register save millicode"
+msgstr " Yazma milikodunu kaydet"
+
+#: peigen.c:1650 pepigen.c:1650
+msgid " Register restore millicode"
+msgstr " Geri alma milikodunu kaydet"
+
+#: peigen.c:1653 pepigen.c:1653
+msgid " Glue code sequence"
+msgstr " BirleÅŸtirici kod dizisi"
+
+#: peigen.c:1705 pepigen.c:1705
+msgid ""
+"\n"
+"\n"
+"PE File Base Relocations (interpreted .reloc section contents)\n"
+msgstr ""
+"\n"
+"\n"
+"PE Dosya Temel Yerdeğişimi (.reloc bölüm içeriği çözümlendi)\n"
+
+#: peigen.c:1735 pepigen.c:1735
+#, c-format
+msgid ""
+"\n"
+"Virtual Address: %08lx Chunk size %ld (0x%lx) Number of fixups %ld\n"
+msgstr ""
+"\n"
+"Sanal Adres: %08lx Parça boyu %ld (0x%lx) Düzeltme Sayısı %ld\n"
+
+#: peigen.c:1748 pepigen.c:1748
+#, c-format
+msgid "\treloc %4d offset %4x [%4lx] %s"
+msgstr "\tyer değişim %4d göreli konum %4x [%4lx] %s"
+
+#. The MS dumpbin program reportedly ands with 0xff0f before
+#. printing the characteristics field. Not sure why. No reason to
+#. emulate it here.
+#: peigen.c:1788 pepigen.c:1788
+#, c-format
+msgid ""
+"\n"
+"Characteristics 0x%x\n"
+msgstr ""
+"\n"
+"Özellikler 0x%x\n"
+
+#~ msgid "%s: Unknown special linker type %d"
+#~ msgstr "%s: Bilinmeyen özel bağlayıcı türü %d"
+
+#~ msgid "v850ea architecture"
+#~ msgstr "v850ea platformu"
+
+#~ msgid "%s: Section %s is too large to add hole of %ld bytes"
+#~ msgstr "%s: %s bölümü içine %ld baytlık bir delik koymak için fazla büyük"
+
+#~ msgid "Error: out of memory"
+#~ msgstr "Hata: bellek tükendi"
+
+#~ msgid "warning: relocation against removed section; zeroing"
+#~ msgstr "uyarı: silinmiş bölüme yer değişim; sıfırlandı"
+
+#~ msgid "warning: relocation against removed section"
+#~ msgstr "%1$s: silinmiş bölüme yerdeğişim"
+
+#~ msgid "local symbols in discarded section %s"
+#~ msgstr "atılmış %s bölümünde yerel semboller"
+
+#~ msgid "%s: linking abicalls files with non-abicalls files"
+#~ msgstr "%s: abicalls dosyaları abicalls olmayan dosyalarla bağlanıyor"
+
+#~ msgid "%s: ISA mismatch (-mips%d) with previous modules (-mips%d)"
+#~ msgstr "%1$s: Önceki modüllerle (-mips%3$d) ile ISA uyumsuzluğu (-mips%2$d)"
+
+#~ msgid "%s: ISA mismatch (%d) with previous modules (%d)"
+#~ msgstr "%1$s: Önceki modüllerle (%3$d) ile ISA uyumsuzluğu (%2$d)"
+
+#~ msgid "%s: dynamic relocation against speculation fixup"
+#~ msgstr "%s: kuşkulu düzeltmeye dinamik yerdeğişim"
+
+#~ msgid "%s: speculation fixup against undefined weak symbol"
+#~ msgstr "%s: tanımlanmamış gevşek sembole tartışmalı düzeltme"
+
+#~ msgid "GP relative relocation when GP not defined"
+#~ msgstr "GP tanımlanmamışken GP göreli yer değiştirmesi"
+
+#~ msgid "%s: ERROR: passes floats in float registers whereas target %s uses integer registers"
+#~ msgstr "%s: HATA: kayan sayıları kayan yazmaçlarda geçiriyor fakat hedef %s tamsayı yazmaç kullanıyor"
+
+#~ msgid "%s: ERROR: passes floats in integer registers whereas target %s uses float registers"
+#~ msgstr "%s: HATA: kayan sayıları tamsayı yazmaçlarda geçiriyor fakat hedef %s kayan yazmaç kullanıyor"
+
+#~ msgid "Warning: input file %s supports interworking, whereas %s does not."
+#~ msgstr "Uyarı: %s girdi dosyası beraber çalışmayı destekliyor, fakat %s desteklemiyor."
+
+#~ msgid "Warning: input file %s does not support interworking, whereas %s does."
+#~ msgstr "Uyarı: %s girdi dosyası beraber çalışmayı desteklemiyor, fakat %s destekliyor."
+
+#~ msgid "AUX tagndx %ld ttlsiz 0x%lx lnnos %ld next %ld"
+#~ msgstr "AUX tagndx %ld ttlsiz 0x%lx lnnos %ld sonraki %ld"
+
+#~ msgid "elf_symbol_from_bfd_symbol 0x%.8lx, name = %s, sym num = %d, flags = 0x%.8lx%s\n"
+#~ msgstr "bfd sembolünden elf sembolü:0x%.8lx, isim= %s, sem num = %d, bayrak = 0x%.8lx%s\n"
+
+#~ msgid "Warning: Not setting interwork flag of %s since it has already been specified as non-interworking"
+#~ msgstr "Uyarı: beraber çalışmaz diye önceden belirtilmiş olduğundan %s'nin beraber çalışma bayrağı atanmadı"
+
+#~ msgid "Warning: Clearing the interwork flag of %s due to outside request"
+#~ msgstr "Uyarı: Dış isteğe uyularak %s'nin beraber çalışma bayrağı temizlendi"
+
+#~ msgid " [APCS-26]"
+#~ msgstr " [APCS-26]"
+
+#~ msgid " [APCS-32]"
+#~ msgstr " [APCS-32]"
+
+#~ msgid "(unknown)"
+#~ msgstr "(bilinmeyen)"
+
+#~ msgid " previously %s in %s"
+#~ msgstr " daha önce %2$s içinde %1$s"
+
+#~ msgid "ETIR_S_C_STO_GBL: no symbol \"%s\""
+#~ msgstr "ETIR_S_C_STO_GBL: sembol yok \"%s\""
+
+#~ msgid "ETIR_S_C_STO_CA: no symbol \"%s\""
+#~ msgstr "ETIR_S_C_STO_CA: sembol yok \"%s\""
+
+#~ msgid "ETIR_S_C_STO_RB/AB: Not supported"
+#~ msgstr "ETIR_S_C_STO_RB/AB: Desteklenmiyor"
+
+#~ msgid "ETIR_S_C_STO_LP_PSB: Not supported"
+#~ msgstr "ETIR_S_C_STO_LP_PSB: Desteklenmiyor"
+
+#~ msgid "ETIR_S_C_STO_HINT_GBL: not implemented"
+#~ msgstr "ETIR_S_C_STO_HINT_GBL: tamamlanmamış"
+
+#~ msgid "ETIR_S_C_STO_HINT_PS: not implemented"
+#~ msgstr "ETIR_S_C_STO_HINT_PS: tamamlanmamış"
+
+#~ msgid "ETIR_S_C_OPR_INSV: Not supported"
+#~ msgstr "ETIR_S_C_OPR_INSV: Desteklenmiyor"
+
+#~ msgid "ETIR_S_C_OPR_USH: Not supported"
+#~ msgstr "ETIR_S_C_OPR_USH: Desteklenmiyor"
+
+#~ msgid "ETIR_S_C_OPR_ROT: Not supported"
+#~ msgstr "ETIR_S_C_OPR_ROT: Desteklenmiyor"
+
+#~ msgid "ETIR_S_C_OPR_REDEF: Not supported"
+#~ msgstr "ETIR_S_C_OPR_REDEF: Desteklenmiyor"
+
+#~ msgid "ETIR_S_C_OPR_DFLIT: Not supported"
+#~ msgstr "ETIR_S_C_OPR_DFLIT: Desteklenmiyor"
+
+#~ msgid "ETIR_S_C_STC_GBL: not supported"
+#~ msgstr "ETIR_S_C_STC_GBL: desteklenmiyor"
+
+#~ msgid "ETIR_S_C_STC_GCA: not supported"
+#~ msgstr "ETIR_S_C_STC_GCA: desteklenmiyor"
+
+#~ msgid "ETIR_S_C_STC_PS: not supported"
+#~ msgstr "ETIR_S_C_STC_PS: desteklenmiyor"
+
+#~ msgid "Unimplemented STO cmd %d"
+#~ msgstr "Tamamlanmamış STO komutu %d"
+
+#~ msgid "TIR_S_C_OPR_ASH incomplete"
+#~ msgstr "TIR_S_C_OPR_ASH tamamlanmamış"
+
+#~ msgid "TIR_S_C_OPR_USH incomplete"
+#~ msgstr "TIR_S_C_OPR_USH tamamlanmamış"
+
+#~ msgid "TIR_S_C_OPR_ROT incomplete"
+#~ msgstr "TIR_S_C_OPR_ROT tamamlanmamış"
+
+#~ msgid "TIR_S_C_OPR_REDEF not supported"
+#~ msgstr "TIR_S_C_OPR_REDEF desteklenmiyor"
+
+#~ msgid "TIR_S_C_OPR_DFLIT not supported"
+#~ msgstr "TIR_S_C_OPR_DFLIT desteklenmiyor"
+
+#~ msgid "TIR_S_C_CTL_DFLOC not fully implemented"
+#~ msgstr "TIR_S_C_CTL_DFLOC tamamlanmamış"
+
+#~ msgid "TIR_S_C_CTL_STLOC not fully implemented"
+#~ msgstr "TIR_S_C_CTL_STLOC tamamlanmamış"
+
+#~ msgid "TIR_S_C_CTL_STKDL not fully implemented"
+#~ msgstr "TIR_S_C_CTL_STKDL tamamlanmamış"
+
+#~ msgid " vma: Hint Time Forward DLL First\n"
+#~ msgstr " vma: Ä°pucu Zaman Ä°leri DLL Ä°lk\n"
+
+#~ msgid "\tThe Import Address Table (difference found)\n"
+#~ msgstr "\tÄ°thal Adres Tablosu (fark bulundu)\n"
+
+#~ msgid "\t>>> Ran out of IAT members!\n"
+#~ msgstr "\t>>> IAT üyeleri bitti!\n"
+
+#~ msgid "\tThe Import Address Table is identical\n"
+#~ msgstr "\tİthal Adres Tablosu aynı\n"
+
+#~ msgid " \t\tAddress Address Handler Data Address Mask\n"
+#~ msgstr " \t\tAdres Adres Yön. Veri Adres Mask\n"
diff --git a/bfd/po/uk.gmo b/bfd/po/uk.gmo
new file mode 100644
index 0000000..9c85a90
--- /dev/null
+++ b/bfd/po/uk.gmo
Binary files differ
diff --git a/bfd/po/uk.po b/bfd/po/uk.po
new file mode 100644
index 0000000..644f436
--- /dev/null
+++ b/bfd/po/uk.po
@@ -0,0 +1,6256 @@
+# bfd Ukrainian translation
+# Copyright (C) 2012 Free Software Foundation, Inc.
+# This file is distributed under the same license as the binutils package.
+#
+# Yuri Chornoivan <yurchor@ukr.net>, 2012.
+msgid ""
+msgstr ""
+"Project-Id-Version: bfd 2.22.90\n"
+"Report-Msgid-Bugs-To: bug-binutils@gnu.org\n"
+"POT-Creation-Date: 2011-10-25 11:58+0100\n"
+"PO-Revision-Date: 2012-09-09 21:27+0300\n"
+"Last-Translator: Yuri Chornoivan <yurchor@ukr.net>\n"
+"Language-Team: Ukrainian <translation-team-uk@lists.sourceforge.net>\n"
+"Language: uk\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
+"X-Generator: Lokalize 1.5\n"
+
+#: aout-adobe.c:127
+msgid "%B: Unknown section type in a.out.adobe file: %x\n"
+msgstr "%B: невідомий тип розділу у файлі a.out.adobe: %x\n"
+
+#: aout-cris.c:199
+#, c-format
+msgid "%s: Invalid relocation type exported: %d"
+msgstr "%s: екÑпортовано некоректний тип переÑуваннÑ: %d"
+
+#: aout-cris.c:242
+msgid "%B: Invalid relocation type imported: %d"
+msgstr "%B: імпортовано некоректний тип переÑуваннÑ: %d"
+
+#: aout-cris.c:253
+msgid "%B: Bad relocation record imported: %d"
+msgstr "%B: імпортовано помилковий Ð·Ð°Ð¿Ð¸Ñ Ð¿ÐµÑ€ÐµÑуваннÑ: %d"
+
+#: aoutx.h:1273 aoutx.h:1611
+#, c-format
+msgid "%s: can not represent section `%s' in a.out object file format"
+msgstr "%s: Ð²Ñ–Ð´Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ñ€Ð¾Ð·Ð´Ñ–Ð»Ñƒ «%s» у форматі об’єктних файлів a.out неможливе"
+
+#: aoutx.h:1577
+#, c-format
+msgid "%s: can not represent section for symbol `%s' in a.out object file format"
+msgstr "%s: Ð²Ñ–Ð´Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ñ€Ð¾Ð·Ð´Ñ–Ð»Ñƒ Ð´Ð»Ñ Ñимволу «%s» у форматі об’єктних файлів a.out неможливе"
+
+#: aoutx.h:1579 vms-alpha.c:7671
+msgid "*unknown*"
+msgstr "*невідомо*"
+
+#: aoutx.h:4018 aoutx.h:4344
+msgid "%P: %B: unexpected relocation type\n"
+msgstr "%P: %B: неочікуваний тип переÑуваннÑ\n"
+
+#: aoutx.h:5375
+#, c-format
+msgid "%s: relocatable link from %s to %s not supported"
+msgstr "%s: підтримки придатних до переÑÑƒÐ²Ð°Ð½Ð½Ñ Ð¿Ð¾Ñилань з %s до %s не передбачено"
+
+#: archive.c:2203
+msgid "Warning: writing archive was slow: rewriting timestamp\n"
+msgstr "ПопередженнÑ: запиÑÑƒÐ²Ð°Ð½Ð½Ñ Ð°Ñ€Ñ…Ñ–Ð²Ñƒ було повільним: перезапиÑуємо чаÑову позначку\n"
+
+#: archive.c:2491
+msgid "Reading archive file mod timestamp"
+msgstr "Ð§Ð¸Ñ‚Ð°Ð½Ð½Ñ Ñ‡Ð°Ñової позначки mod архівного файла"
+
+#: archive.c:2515
+msgid "Writing updated armap timestamp"
+msgstr "ЗапиÑÑƒÐ²Ð°Ð½Ð½Ñ Ð¾Ð½Ð¾Ð²Ð»ÐµÐ½Ð¾Ñ— чаÑової позначки armap"
+
+#: bfd.c:398
+msgid "No error"
+msgstr "Ðемає помилок"
+
+#: bfd.c:399
+msgid "System call error"
+msgstr "Помилка ÑиÑтемного виклику"
+
+#: bfd.c:400
+msgid "Invalid bfd target"
+msgstr "Ðекоректне Ð¿Ñ€Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ bfd"
+
+#: bfd.c:401
+msgid "File in wrong format"
+msgstr "Файл у помилковому форматі"
+
+#: bfd.c:402
+msgid "Archive object file in wrong format"
+msgstr "Ðрхівний об’єктний файл у помилковому форматі"
+
+#: bfd.c:403
+msgid "Invalid operation"
+msgstr "Ðекоректна діÑ"
+
+#: bfd.c:404
+msgid "Memory exhausted"
+msgstr "Пам’ÑÑ‚ÑŒ вичерпано"
+
+#: bfd.c:405
+msgid "No symbols"
+msgstr "Ðемає Ñимволів"
+
+#: bfd.c:406
+msgid "Archive has no index; run ranlib to add one"
+msgstr "У архіві немає покажчика; запуÑÑ‚Ñ–Ñ‚ÑŒ ranlib, щоб його додати"
+
+#: bfd.c:407
+msgid "No more archived files"
+msgstr "Більше архівованих файлів немає"
+
+#: bfd.c:408
+msgid "Malformed archive"
+msgstr "Ðрхів з пошкодженим форматуваннÑм"
+
+#: bfd.c:409
+msgid "File format not recognized"
+msgstr "Формат файла не розпізнано"
+
+#: bfd.c:410
+msgid "File format is ambiguous"
+msgstr "Формат файла є неоднозначним"
+
+#: bfd.c:411
+msgid "Section has no contents"
+msgstr "Розділ не має вміÑту"
+
+#: bfd.c:412
+msgid "Nonrepresentable section on output"
+msgstr "Розділ, непридатний Ð´Ð»Ñ Ð²Ð¸Ð²ÐµÐ´ÐµÐ½Ð½Ñ Ð´Ð°Ð½Ð¸Ñ…"
+
+#: bfd.c:413
+msgid "Symbol needs debug section which does not exist"
+msgstr "Символ потребує розділу діагноÑтики, Ñкого не Ñ–Ñнує"
+
+#: bfd.c:414
+msgid "Bad value"
+msgstr "помилкове значеннÑ"
+
+#: bfd.c:415
+msgid "File truncated"
+msgstr "Файл обрізано"
+
+#: bfd.c:416
+msgid "File too big"
+msgstr "Файл є надто великим"
+
+#: bfd.c:417
+#, c-format
+msgid "Error reading %s: %s"
+msgstr "Помилка під Ñ‡Ð°Ñ Ñ‡Ð¸Ñ‚Ð°Ð½Ð½Ñ %s: %s"
+
+#: bfd.c:418
+msgid "#<Invalid error code>"
+msgstr "#<некоректний код помилки>"
+
+#: bfd.c:945
+#, c-format
+msgid "BFD %s assertion fail %s:%d"
+msgstr "Оператором контролю BFD %s виÑвлено помилку %s:%d"
+
+#: bfd.c:957
+#, c-format
+msgid "BFD %s internal error, aborting at %s line %d in %s\n"
+msgstr "Ð’Ð½ÑƒÑ‚Ñ€Ñ–ÑˆÐ½Ñ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ° BFD %s, перериваємо роботу у %s, Ñ€Ñдок %d у %s\n"
+
+#: bfd.c:961
+#, c-format
+msgid "BFD %s internal error, aborting at %s line %d\n"
+msgstr "Ð’Ð½ÑƒÑ‚Ñ€Ñ–ÑˆÐ½Ñ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ° BFD %s, перериваємо роботу у %s, Ñ€Ñдок %d\n"
+
+#: bfd.c:963
+msgid "Please report this bug.\n"
+msgstr "Будь лаÑка, повідомте про цю ваду.\n"
+
+#: bfdwin.c:206
+#, c-format
+msgid "not mapping: data=%lx mapped=%d\n"
+msgstr "не відображено: дані=%lx відображено=%d\n"
+
+#: bfdwin.c:209
+#, c-format
+msgid "not mapping: env var not set\n"
+msgstr "не відображено: не вÑтановлено змінну Ñередовища var\n"
+
+#: binary.c:271
+#, c-format
+msgid "Warning: Writing section `%s' to huge (ie negative) file offset 0x%lx."
+msgstr "ПопередженнÑ: виконуєтьÑÑ Ð·Ð°Ð¿Ð¸Ñ Ñ€Ð¾Ð·Ð´Ñ–Ð»Ñƒ «%s» за надто великим (тобто від’ємним) відÑтупом у файлі, 0x%lx."
+
+#: bout.c:1146 elf-m10300.c:2063 elf32-avr.c:1654 elf32-frv.c:5734
+#: elfxx-sparc.c:2802 reloc.c:6115 reloc16.c:162 elf32-ia64.c:360
+#: elf64-ia64.c:360
+msgid "%P%F: --relax and -r may not be used together\n"
+msgstr "%P%F: --relax Ñ– -r не можна викориÑтовувати одночаÑно\n"
+
+#: cache.c:227
+msgid "reopening %B: %s\n"
+msgstr "повторне Ð²Ñ–Ð´ÐºÑ€Ð¸Ñ‚Ñ‚Ñ %B: %s\n"
+
+#: coff-alpha.c:491
+msgid ""
+"%B: Cannot handle compressed Alpha binaries.\n"
+" Use compiler flags, or objZ, to generate uncompressed binaries."
+msgstr ""
+"%B: обробка ÑтиÑнутих двійкових файлів Alpha неможлива.\n"
+" СкориÑтайтеÑÑ Ð¿Ñ€Ð°Ð¿Ð¾Ñ€Ñ†Ñми компілÑтора або objZ Ð´Ð»Ñ ÑÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ð½ÐµÑтиÑнених двійкових файлів."
+
+#: coff-alpha.c:648
+msgid "%B: unknown/unsupported relocation type %d"
+msgstr "%B: невідомий або непідтримуваний тип переÑÑƒÐ²Ð°Ð½Ð½Ñ %d"
+
+#: coff-alpha.c:900 coff-alpha.c:937 coff-alpha.c:2025 coff-mips.c:1003
+msgid "GP relative relocation used when GP not defined"
+msgstr "ВикориÑтано відноÑне переÑÑƒÐ²Ð°Ð½Ð½Ñ GP, втім, GP не визначено"
+
+#: coff-alpha.c:1502
+msgid "using multiple gp values"
+msgstr "викориÑтовуєтьÑÑ Ð´ÐµÐºÑ–Ð»ÑŒÐºÐ° значень gp"
+
+#: coff-alpha.c:1561
+msgid "%B: unsupported relocation: ALPHA_R_GPRELHIGH"
+msgstr "%B: переÑуваннÑ, підтримки Ñкого не передбачено: ALPHA_R_GPRELHIGH"
+
+#: coff-alpha.c:1568
+msgid "%B: unsupported relocation: ALPHA_R_GPRELLOW"
+msgstr "%B: переÑуваннÑ, підтримки Ñкого не передбачено: ALPHA_R_GPRELLOW"
+
+#: coff-alpha.c:1575 elf32-m32r.c:2484 elf64-alpha.c:4074 elf64-alpha.c:4224
+#: elf32-ia64.c:3839 elf64-ia64.c:3839
+msgid "%B: unknown relocation type %d"
+msgstr "%B: невідомий тип переÑÑƒÐ²Ð°Ð½Ð½Ñ %d"
+
+#: coff-arm.c:1038
+#, c-format
+msgid "%B: unable to find THUMB glue '%s' for `%s'"
+msgstr "%B: не вдалоÑÑ Ð·Ð½Ð°Ð¹Ñ‚Ð¸ Ñклейку THUMB «%s» Ð´Ð»Ñ Â«%s»"
+
+#: coff-arm.c:1067
+#, c-format
+msgid "%B: unable to find ARM glue '%s' for `%s'"
+msgstr "%B: не вдалоÑÑ Ð·Ð½Ð°Ð¹Ñ‚Ð¸ Ñклейку ARM «%s» Ð´Ð»Ñ Â«%s»"
+
+#: coff-arm.c:1369 elf32-arm.c:7023
+#, c-format
+msgid ""
+"%B(%s): warning: interworking not enabled.\n"
+" first occurrence: %B: arm call to thumb"
+msgstr ""
+"%B(%s): попередженнÑ: ÑуміÑну роботу не увімкнено.\n"
+" перша згадка: %B: виклик arm до thumb"
+
+#: coff-arm.c:1459
+#, c-format
+msgid ""
+"%B(%s): warning: interworking not enabled.\n"
+" first occurrence: %B: thumb call to arm\n"
+" consider relinking with --support-old-code enabled"
+msgstr ""
+"%B(%s): попередженнÑ: ÑуміÑну роботу не увімкнено.\n"
+" перша згадка: %B: виклик arm до arm\n"
+" Ñпробуйте повторне Ð¾Ð±â€™Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Ð· увімкненим --support-old-code"
+
+#: coff-arm.c:1754 coff-tic80.c:695 cofflink.c:3081
+msgid "%B: bad reloc address 0x%lx in section `%A'"
+msgstr "%B: помилкова адреÑа переÑÑƒÐ²Ð°Ð½Ð½Ñ 0x%lx у розділі «%A»"
+
+#: coff-arm.c:2079
+msgid "%B: illegal symbol index in reloc: %d"
+msgstr "%B: некоректний Ñ–Ð½Ð´ÐµÐºÑ Ñимволу у переÑуванні: %d"
+
+#: coff-arm.c:2210
+#, c-format
+msgid "error: %B is compiled for APCS-%d, whereas %B is compiled for APCS-%d"
+msgstr "помилка: %B зібрано Ð´Ð»Ñ APCS-%d, а %B зібрано Ð´Ð»Ñ APCS-%d"
+
+#: coff-arm.c:2226 elf32-arm.c:15621
+#, c-format
+msgid "error: %B passes floats in float registers, whereas %B passes them in integer registers"
+msgstr "помилка: %B передає чиÑла з рухомою комою до регіÑтрів, а %B передає Ñ—Ñ… у цілочиÑельні регіÑтри"
+
+#: coff-arm.c:2229 elf32-arm.c:15625
+#, c-format
+msgid "error: %B passes floats in integer registers, whereas %B passes them in float registers"
+msgstr "помилка: %B передає цілі чиÑла до регіÑтрів, а %B передає Ñ—Ñ… у регіÑтри чиÑел з рухомою комою"
+
+#: coff-arm.c:2243
+#, c-format
+msgid "error: %B is compiled as position independent code, whereas target %B is absolute position"
+msgstr "помилка: %B зібрано Ñк код з незалежним позиціюваннÑм, а Ð¿Ñ€Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ %B визначено у форматі абÑолютної позиції"
+
+#: coff-arm.c:2246
+#, c-format
+msgid "error: %B is compiled as absolute position code, whereas target %B is position independent"
+msgstr "помилка: %B зібрано Ñк код з абÑолютним позиціюваннÑм, а Ð¿Ñ€Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ %B визначено у форматі незалежної позиції"
+
+#: coff-arm.c:2274 elf32-arm.c:15690
+#, c-format
+msgid "Warning: %B supports interworking, whereas %B does not"
+msgstr "ПопередженнÑ: у %B передбачено ÑуміÑну роботу, а у %B не передбачено"
+
+#: coff-arm.c:2277 elf32-arm.c:15696
+#, c-format
+msgid "Warning: %B does not support interworking, whereas %B does"
+msgstr "ПопередженнÑ: у %B не передбачено ÑуміÑної роботи, а у %B передбачено"
+
+#: coff-arm.c:2301
+#, c-format
+msgid "private flags = %x:"
+msgstr "закриті прапорці = %x:"
+
+#: coff-arm.c:2309 elf32-arm.c:11806
+#, c-format
+msgid " [floats passed in float registers]"
+msgstr " [чиÑла з рухомою комою передано до регіÑтрів чиÑел з рухомою комою]"
+
+#: coff-arm.c:2311
+#, c-format
+msgid " [floats passed in integer registers]"
+msgstr " [чиÑла з рухомою комою передано до цілочиÑельних регіÑтрів]"
+
+#: coff-arm.c:2314 elf32-arm.c:11809
+#, c-format
+msgid " [position independent]"
+msgstr " [незалежний від позиції]"
+
+#: coff-arm.c:2316
+#, c-format
+msgid " [absolute position]"
+msgstr " [з абÑолютним позиціюваннÑм]"
+
+#: coff-arm.c:2320
+#, c-format
+msgid " [interworking flag not initialised]"
+msgstr " [прапорець ÑуміÑної роботи не ініціалізовано]"
+
+#: coff-arm.c:2322
+#, c-format
+msgid " [interworking supported]"
+msgstr " [підтримуєтьÑÑ ÑуміÑна робота]"
+
+#: coff-arm.c:2324
+#, c-format
+msgid " [interworking not supported]"
+msgstr " [ÑуміÑна робота не підтримуєтьÑÑ]"
+
+#: coff-arm.c:2370 elf32-arm.c:10841
+#, c-format
+msgid "Warning: Not setting interworking flag of %B since it has already been specified as non-interworking"
+msgstr "ПопередженнÑ: прапорець ÑуміÑної роботи у %B не вÑтановлено, оÑкільки його вже було визначено так, щоб він заборонÑв ÑуміÑну роботу"
+
+#: coff-arm.c:2374 elf32-arm.c:10845
+#, c-format
+msgid "Warning: Clearing the interworking flag of %B due to outside request"
+msgstr "ПопередженнÑ: знÑто прапорець ÑуміÑної роботи у %B у відповідь на запит ззовні"
+
+#: coff-h8300.c:1122
+#, c-format
+msgid "cannot handle R_MEM_INDIRECT reloc when using %s output"
+msgstr "переÑÑƒÐ²Ð°Ð½Ð½Ñ Ð½ÐµÐ¼Ð¾Ð¶Ð»Ð¸Ð²Ð¾ обробити R_MEM_INDIRECT, Ñкщо викориÑтано Ð²Ð¸Ð²ÐµÐ´ÐµÐ½Ð½Ñ Ð´Ð¾ %s"
+
+#: coff-i860.c:147
+#, c-format
+msgid "relocation `%s' not yet implemented"
+msgstr "переÑÑƒÐ²Ð°Ð½Ð½Ñ Â«%s» ще не реалізовано"
+
+#: coff-i860.c:605 coff-tic54x.c:398 coffcode.h:5198
+msgid "%B: warning: illegal symbol index %ld in relocs"
+msgstr "%B: попередженнÑ: некоректний Ñ–Ð½Ð´ÐµÐºÑ Ñимволу %ld у переÑуваннÑÑ…"
+
+#: coff-i960.c:144 coff-i960.c:507
+msgid "uncertain calling convention for non-COFF symbol"
+msgstr "непевні правила виклику Ð´Ð»Ñ Ñимволу поза COFF"
+
+#: coff-m68k.c:506 elf32-bfin.c:5690 elf32-cr16.c:2897 elf32-m68k.c:4677
+msgid "unsupported reloc type"
+msgstr "непідтримуваний тип переÑуваннÑ"
+
+#: coff-mips.c:688 elf32-mips.c:1516 elf32-score.c:431 elf32-score7.c:330
+#: elf64-mips.c:2618 elfn32-mips.c:2431
+msgid "GP relative relocation when _gp not defined"
+msgstr "відноÑне переÑÑƒÐ²Ð°Ð½Ð½Ñ GP, але _gp не визначено"
+
+#: coff-or32.c:229
+msgid "Unrecognized reloc"
+msgstr "Ðерозпізнане переÑуваннÑ"
+
+#: coff-rs6000.c:2720
+#, c-format
+msgid "%s: unsupported relocation type 0x%02x"
+msgstr "%s: непідтримуваний тип переÑÑƒÐ²Ð°Ð½Ð½Ñ 0x%02x"
+
+#: coff-rs6000.c:2805
+#, c-format
+msgid "%s: TOC reloc at 0x%x to symbol `%s' with no TOC entry"
+msgstr "%s: переÑÑƒÐ²Ð°Ð½Ð½Ñ TOC за адреÑою 0x%x до Ñимволу «%s», Ñкий немає запиÑу у TOC"
+
+#: coff-rs6000.c:3556 coff64-rs6000.c:2111
+msgid "%B: symbol `%s' has unrecognized smclas %d"
+msgstr "%B: Ñимвол «%s» належить до нерозпізнаного smclas %d"
+
+#: coff-sh.c:521
+#, c-format
+msgid "SH Error: unknown reloc type %d"
+msgstr "Помилка SH: невідомий тип переÑуваннÑ, %d"
+
+#: coff-tic4x.c:195 coff-tic54x.c:299 coff-tic80.c:458
+#, c-format
+msgid "Unrecognized reloc type 0x%x"
+msgstr "Ðерозпізнаний тип переÑÑƒÐ²Ð°Ð½Ð½Ñ 0x%x"
+
+#: coff-tic4x.c:240
+#, c-format
+msgid "%s: warning: illegal symbol index %ld in relocs"
+msgstr "%s: попередженнÑ: некоректний Ñ–Ð½Ð´ÐµÐºÑ Ñимволу %ld у переÑуваннÑÑ…"
+
+#: coff-w65.c:367
+#, c-format
+msgid "ignoring reloc %s\n"
+msgstr "ігноруємо переÑÑƒÐ²Ð°Ð½Ð½Ñ %s\n"
+
+#: coffcode.h:997
+msgid "%B: warning: COMDAT symbol '%s' does not match section name '%s'"
+msgstr "%B: попередженнÑ: Ñимвол COMDAT «%s» не відповідає назві розділу «%s»"
+
+#. Generate a warning message rather using the 'unhandled'
+#. variable as this will allow some .sys files generate by
+#. other toolchains to be processed. See bugzilla issue 196.
+#: coffcode.h:1221
+msgid "%B: Warning: Ignoring section flag IMAGE_SCN_MEM_NOT_PAGED in section %s"
+msgstr "%B: попередженнÑ: ігноруємо прапорець розділу IMAGE_SCN_MEM_NOT_PAGED у розділі %s"
+
+#: coffcode.h:1288
+msgid "%B (%s): Section flag %s (0x%x) ignored"
+msgstr "%B (%s): прапорець розділу %s (0x%x) проігноровано"
+
+#: coffcode.h:2430
+#, c-format
+msgid "Unrecognized TI COFF target id '0x%x'"
+msgstr "Ðерозпізнаний ідентифікатор Ð¿Ñ€Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ TI COFF, «0x%x»"
+
+#: coffcode.h:2744
+msgid "%B: reloc against a non-existant symbol index: %ld"
+msgstr "%B: переÑÑƒÐ²Ð°Ð½Ð½Ñ Ð·Ð° неÑтвореним індекÑом Ñимволу: %ld"
+
+#: coffcode.h:3302
+msgid "%B: too many sections (%d)"
+msgstr "%B: занадто багато розділів (%d)"
+
+#: coffcode.h:3718
+msgid "%B: section %s: string table overflow at offset %ld"
+msgstr "%B: розділ %s: Ð¿ÐµÑ€ÐµÐ¿Ð¾Ð²Ð½ÐµÐ½Ð½Ñ Ñ‚Ð°Ð±Ð»Ð¸Ñ†Ñ– Ñ€Ñдків за відÑтупом %ld"
+
+#: coffcode.h:4523
+msgid "%B: warning: line number table read failed"
+msgstr "%B: попередженнÑ: помилка Ñ‡Ð¸Ñ‚Ð°Ð½Ð½Ñ Ð· таблиці номерів Ñ€Ñдків"
+
+#: coffcode.h:4553
+msgid "%B: warning: illegal symbol index %ld in line numbers"
+msgstr "%B: попередженнÑ: некоректний Ñ–Ð½Ð´ÐµÐºÑ Ñимволу %ld у номерах Ñ€Ñдків"
+
+#: coffcode.h:4567
+msgid "%B: warning: duplicate line number information for `%s'"
+msgstr "%B: попередженнÑ: Ð´ÑƒÐ±Ð»ÑŽÐ²Ð°Ð½Ð½Ñ Ð´Ð°Ð½Ð¸Ñ… щодо номерів Ñ€Ñдків Ð´Ð»Ñ Â«%s»"
+
+#: coffcode.h:4967
+msgid "%B: Unrecognized storage class %d for %s symbol `%s'"
+msgstr "%B: невідомий ÐºÐ»Ð°Ñ Ð·Ð±ÐµÑ€Ñ–Ð³Ð°Ð½Ð½Ñ Ð´Ð°Ð½Ð¸Ñ… %d Ð´Ð»Ñ Ñимволу %s «%s»"
+
+#: coffcode.h:5093
+msgid "warning: %B: local symbol `%s' has no section"
+msgstr "попередженнÑ: %B: локальний Ñимвол «%s» не має розділу"
+
+#: coffcode.h:5237
+msgid "%B: illegal relocation type %d at address 0x%lx"
+msgstr "%B: некоректний тип переÑÑƒÐ²Ð°Ð½Ð½Ñ %d за адреÑою 0x%lx"
+
+#: coffgen.c:1595
+msgid "%B: bad string table size %lu"
+msgstr "%B: помилковий розмір таблиці Ñ€Ñдків %lu"
+
+#: coffgen.c:2500 elflink.c:12689 linker.c:3122
+msgid "%F%P: already_linked_table: %E\n"
+msgstr "%F%P: already_linked_table: %E\n"
+
+#: cofflink.c:533 elflink.c:4323
+msgid "Warning: type of symbol `%s' changed from %d to %d in %B"
+msgstr "ПопередженнÑ: тип Ñимволу «%s» змінено з %d на %d у %B"
+
+#: cofflink.c:2329
+msgid "%B: relocs in section `%A', but it has no contents"
+msgstr "%B: переÑÑƒÐ²Ð°Ð½Ð½Ñ Ñƒ розділі «%A», але у цьому розділі немає зміÑту"
+
+#: cofflink.c:2391 elflink.c:9545
+msgid "%X`%s' referenced in section `%A' of %B: defined in discarded section `%A' of %B\n"
+msgstr "Ðа %X«%s» поÑилаєтьÑÑ Ñ€Ð¾Ð·Ð´Ñ–Ð» «%A» %B: визначено у відкинутому розділі «%A» %B\n"
+
+#: cofflink.c:2690 coffswap.h:826
+#, c-format
+msgid "%s: %s: reloc overflow: 0x%lx > 0xffff"
+msgstr "%s: %s: Ð¿ÐµÑ€ÐµÐ¿Ð¾Ð²Ð½ÐµÐ½Ð½Ñ Ð¿Ñ–Ð´ Ñ‡Ð°Ñ Ð¿ÐµÑ€ÐµÑуваннÑ: 0x%lx > 0xffff"
+
+#: cofflink.c:2699 coffswap.h:812
+#, c-format
+msgid "%s: warning: %s: line number overflow: 0x%lx > 0xffff"
+msgstr "%s: попередженнÑ: %s: Ð¿ÐµÑ€ÐµÐ¿Ð¾Ð²Ð½ÐµÐ½Ð½Ñ Ð½Ð¾Ð¼ÐµÑ€Ð° Ñ€Ñдка: 0x%lx > 0xffff"
+
+#: cpu-arm.c:189 cpu-arm.c:200
+msgid "error: %B is compiled for the EP9312, whereas %B is compiled for XScale"
+msgstr "помилка: B зібрано Ð´Ð»Ñ EP9312, а %B зібрано Ð´Ð»Ñ XScale"
+
+#: cpu-arm.c:333
+#, c-format
+msgid "warning: unable to update contents of %s section in %s"
+msgstr "попередженнÑ: не вдалоÑÑ Ð¾Ð½Ð¾Ð²Ð¸Ñ‚Ð¸ зміÑÑ‚ розділу %s у %s"
+
+#: dwarf2.c:496
+#, c-format
+msgid "Dwarf Error: Can't find %s section."
+msgstr "Помилка dwarf: не вдалоÑÑ Ð·Ð½Ð°Ð¹Ñ‚Ð¸ розділ %s."
+
+#: dwarf2.c:525
+#, c-format
+msgid "Dwarf Error: Offset (%lu) greater than or equal to %s size (%lu)."
+msgstr "Помилка dwarf: відÑтуп (%lu) Ñ” більшим або рівним за розмір %s (%lu)."
+
+#: dwarf2.c:949
+#, c-format
+msgid "Dwarf Error: Invalid or unhandled FORM value: %u."
+msgstr "Помилка dwarf: некоректне або непридатне до обробки Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ FORM: %u."
+
+#: dwarf2.c:1200
+msgid "Dwarf Error: mangled line number section (bad file number)."
+msgstr "Помилка dwarf: пошкоджений розділ номерів Ñ€Ñдків (помилковий номер файла)."
+
+#: dwarf2.c:1453
+#, c-format
+msgid "Dwarf Error: Unhandled .debug_line version %d."
+msgstr "Помилка dwarf: непридатна до обробки верÑÑ–Ñ .debug_line, %d."
+
+#: dwarf2.c:1475
+msgid "Dwarf Error: Invalid maximum operations per instruction."
+msgstr "Помилка dwarf: некоректна макÑимальна кількіÑÑ‚ÑŒ дій на команду."
+
+#: dwarf2.c:1662
+msgid "Dwarf Error: mangled line number section."
+msgstr "Помилка dwarf: пошкоджений розділ номерів Ñ€Ñдків."
+
+#: dwarf2.c:1989 dwarf2.c:2109 dwarf2.c:2394
+#, c-format
+msgid "Dwarf Error: Could not find abbrev number %u."
+msgstr "Помилка dwarf: не вдалоÑÑ Ð·Ð½Ð°Ð¹Ñ‚Ð¸ Ñкорочений номер %u."
+
+#: dwarf2.c:2355
+#, c-format
+msgid "Dwarf Error: found dwarf version '%u', this reader only handles version 2, 3 and 4 information."
+msgstr "Помилка dwarf: виÑвлено верÑÑ–ÑŽ dwarf «%u», але у цій функції Ñ‡Ð¸Ñ‚Ð°Ð½Ð½Ñ Ð¿ÐµÑ€ÐµÐ´Ð±Ð°Ñ‡ÐµÐ½Ð¾ обробку лише верÑій даних 2, 3 Ñ– 4."
+
+#: dwarf2.c:2362
+#, c-format
+msgid "Dwarf Error: found address size '%u', this reader can not handle sizes greater than '%u'."
+msgstr "Помилка у dwarf: виÑвлено розмір адреÑи «%u», втім у функції Ñ‡Ð¸Ñ‚Ð°Ð½Ð½Ñ Ð½Ðµ передбачено розмірів, що перевищують «%u»."
+
+#: dwarf2.c:2385
+#, c-format
+msgid "Dwarf Error: Bad abbrev number: %u."
+msgstr "Помилка dwarf: помилковий Ñкорочений номер: %u."
+
+#: ecoff.c:1239
+#, c-format
+msgid "Unknown basic type %d"
+msgstr "Ðевідомий оÑновний тип %d"
+
+#: ecoff.c:1496
+#, c-format
+msgid ""
+"\n"
+" End+1 symbol: %ld"
+msgstr ""
+"\n"
+" Символ за кінцем: %ld"
+
+#: ecoff.c:1503 ecoff.c:1506
+#, c-format
+msgid ""
+"\n"
+" First symbol: %ld"
+msgstr ""
+"\n"
+" Перший Ñимвол: %ld"
+
+#: ecoff.c:1518
+#, c-format
+msgid ""
+"\n"
+" End+1 symbol: %-7ld Type: %s"
+msgstr ""
+"\n"
+" Символ за кінцем: %-7ld Тип: %s"
+
+#: ecoff.c:1525
+#, c-format
+msgid ""
+"\n"
+" Local symbol: %ld"
+msgstr ""
+"\n"
+" Локальний Ñимвол: %ld"
+
+#: ecoff.c:1533
+#, c-format
+msgid ""
+"\n"
+" struct; End+1 symbol: %ld"
+msgstr ""
+"\n"
+" struct; Ñимвол за кінцем: %ld"
+
+#: ecoff.c:1538
+#, c-format
+msgid ""
+"\n"
+" union; End+1 symbol: %ld"
+msgstr ""
+"\n"
+" union; Ñимвол за кінцем: %ld"
+
+#: ecoff.c:1543
+#, c-format
+msgid ""
+"\n"
+" enum; End+1 symbol: %ld"
+msgstr ""
+"\n"
+" enum; Ñимвол за кінцем: %ld"
+
+#: ecoff.c:1549
+#, c-format
+msgid ""
+"\n"
+" Type: %s"
+msgstr ""
+"\n"
+" Тип: %s"
+
+#: elf-attrs.c:569
+msgid "error: %B: Object has vendor-specific contents that must be processed by the '%s' toolchain"
+msgstr "помилка: %B: у об’єкті міÑÑ‚ÑÑ‚ÑŒÑÑ Ð´Ð°Ð½Ñ– у Ñпецифічному форматі, ці дані має бути оброблено набором інÑтрументів «%s»"
+
+#: elf-attrs.c:578
+msgid "error: %B: Object tag '%d, %s' is incompatible with tag '%d, %s'"
+msgstr "помилка: %B: мітка об’єкта «%d, %s» неÑуміÑна з міткою «%d, %s»"
+
+#: elf-eh-frame.c:917
+msgid "%P: error in %B(%A); no .eh_frame_hdr table will be created.\n"
+msgstr "%P: помилка у %B(%A); таблицю .eh_frame_hdr не буде Ñтворено.\n"
+
+#: elf-eh-frame.c:1189
+msgid "%P: fde encoding in %B(%A) prevents .eh_frame_hdr table being created.\n"
+msgstr "%P: ÐºÐ¾Ð´ÑƒÐ²Ð°Ð½Ð½Ñ fde у %B(%A) перешкоджає Ñтворенню таблиці .eh_frame_hdr.\n"
+
+#: elf-eh-frame.c:1605
+msgid "%P: DW_EH_PE_datarel unspecified for this architecture.\n"
+msgstr "%P: DW_EH_PE_datarel не визначено Ð´Ð»Ñ Ñ†Ñ–Ñ”Ñ— архітектури.\n"
+
+#: elf-ifunc.c:179
+msgid "%F%P: dynamic STT_GNU_IFUNC symbol `%s' with pointer equality in `%B' can not be used when making an executable; recompile with -fPIE and relink with -pie\n"
+msgstr "%F%P: динамічний Ñимвол STT_GNU_IFUNC «%s» з рівніÑÑ‚ÑŽ вказівників у «%B» не можна викориÑтовувати під Ñ‡Ð°Ñ ÑÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ð²Ð¸ÐºÐ¾Ð½ÑƒÐ²Ð°Ð½Ð¾Ð³Ð¾ файла; виконайте повторну компілÑцію з -fPIE Ñ– повторне ÐºÐ¾Ð¼Ð¿Ð¾Ð½ÑƒÐ²Ð°Ð½Ð½Ñ -pie\n"
+
+#: elf-m10200.c:450 elf-m10300.c:1563 elf32-avr.c:1221 elf32-bfin.c:3213
+#: elf32-cr16.c:1482 elf32-cr16c.c:780 elf32-cris.c:2081 elf32-crx.c:922
+#: elf32-d10v.c:509 elf32-epiphany.c:556 elf32-fr30.c:609 elf32-frv.c:4105
+#: elf32-h8300.c:509 elf32-i860.c:1211 elf32-ip2k.c:1468 elf32-iq2000.c:684
+#: elf32-lm32.c:1168 elf32-m32c.c:553 elf32-m32r.c:3106 elf32-m68hc1x.c:1138
+#: elf32-mep.c:535 elf32-microblaze.c:1231 elf32-moxie.c:282
+#: elf32-msp430.c:486 elf32-mt.c:395 elf32-openrisc.c:404 elf32-score.c:2729
+#: elf32-score7.c:2537 elf32-spu.c:5044 elf32-tilepro.c:3214 elf32-v850.c:2143
+#: elf32-xstormy16.c:935 elf64-mmix.c:1590 elfxx-tilegx.c:3577
+msgid "internal error: out of range error"
+msgstr "Ð²Ð½ÑƒÑ‚Ñ€Ñ–ÑˆÐ½Ñ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ°: вихід за межі діапазону"
+
+#: elf-m10200.c:454 elf-m10300.c:1567 elf32-avr.c:1225 elf32-bfin.c:3217
+#: elf32-cr16.c:1486 elf32-cr16c.c:784 elf32-cris.c:2085 elf32-crx.c:926
+#: elf32-d10v.c:513 elf32-fr30.c:613 elf32-frv.c:4109 elf32-h8300.c:513
+#: elf32-i860.c:1215 elf32-iq2000.c:688 elf32-lm32.c:1172 elf32-m32c.c:557
+#: elf32-m32r.c:3110 elf32-m68hc1x.c:1142 elf32-mep.c:539
+#: elf32-microblaze.c:1235 elf32-moxie.c:286 elf32-msp430.c:490
+#: elf32-openrisc.c:408 elf32-score.c:2733 elf32-score7.c:2541
+#: elf32-spu.c:5048 elf32-tilepro.c:3218 elf32-v850.c:2147
+#: elf32-xstormy16.c:939 elf64-mmix.c:1594 elfxx-mips.c:9465
+#: elfxx-tilegx.c:3581
+msgid "internal error: unsupported relocation error"
+msgstr "Ð²Ð½ÑƒÑ‚Ñ€Ñ–ÑˆÐ½Ñ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ°: непідтримувана помилка переÑуваннÑ"
+
+#: elf-m10200.c:458 elf32-cr16.c:1490 elf32-cr16c.c:788 elf32-crx.c:930
+#: elf32-d10v.c:517 elf32-h8300.c:517 elf32-lm32.c:1176 elf32-m32r.c:3114
+#: elf32-m68hc1x.c:1146 elf32-microblaze.c:1239 elf32-score.c:2737
+#: elf32-score7.c:2545 elf32-spu.c:5052
+msgid "internal error: dangerous error"
+msgstr "Ð²Ð½ÑƒÑ‚Ñ€Ñ–ÑˆÐ½Ñ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ°: небезпечна помилка"
+
+#: elf-m10200.c:462 elf-m10300.c:1580 elf32-avr.c:1233 elf32-bfin.c:3225
+#: elf32-cr16.c:1494 elf32-cr16c.c:792 elf32-cris.c:2093 elf32-crx.c:934
+#: elf32-d10v.c:521 elf32-epiphany.c:571 elf32-fr30.c:621 elf32-frv.c:4117
+#: elf32-h8300.c:521 elf32-i860.c:1223 elf32-ip2k.c:1483 elf32-iq2000.c:696
+#: elf32-lm32.c:1180 elf32-m32c.c:565 elf32-m32r.c:3118 elf32-m68hc1x.c:1150
+#: elf32-mep.c:547 elf32-microblaze.c:1243 elf32-moxie.c:294
+#: elf32-msp430.c:498 elf32-mt.c:403 elf32-openrisc.c:416 elf32-score.c:2746
+#: elf32-score7.c:2549 elf32-spu.c:5056 elf32-tilepro.c:3226 elf32-v850.c:2167
+#: elf32-xstormy16.c:947 elf64-mmix.c:1602 elfxx-tilegx.c:3589
+msgid "internal error: unknown error"
+msgstr "Ð²Ð½ÑƒÑ‚Ñ€Ñ–ÑˆÐ½Ñ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ°: невідома помилка"
+
+#: elf-m10300.c:1507 elf32-arm.c:10419 elf32-i386.c:4264 elf32-m32r.c:2599
+#: elf32-m68k.c:4156 elf32-s390.c:3003 elf32-sh.c:4218 elf32-tilepro.c:3117
+#: elf32-xtensa.c:3066 elf64-s390.c:2978 elf64-sh64.c:1640 elf64-x86-64.c:4110
+#: elfxx-sparc.c:3835 elfxx-tilegx.c:3500
+msgid "%B(%A+0x%lx): unresolvable %s relocation against symbol `%s'"
+msgstr "%B(%A+0x%lx): нерозв’Ñзне переÑÑƒÐ²Ð°Ð½Ð½Ñ %s щодо Ñимволу «%s»"
+
+#: elf-m10300.c:1572
+msgid "error: inappropriate relocation type for shared library (did you forget -fpic?)"
+msgstr "помилка: невідповідний тип переÑÑƒÐ²Ð°Ð½Ð½Ñ Ð´Ð»Ñ Ð±Ñ–Ð±Ð»Ñ–Ð¾Ñ‚ÐµÐºÐ¸ Ñпільного викориÑÑ‚Ð°Ð½Ð½Ñ (забули -fpic?)"
+
+#: elf-m10300.c:1575
+msgid "internal error: suspicious relocation type used in shared library"
+msgstr "Ð²Ð½ÑƒÑ‚Ñ€Ñ–ÑˆÐ½Ñ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ°: підозріливий тип переÑÑƒÐ²Ð°Ð½Ð½Ñ Ñƒ бібліотеці Ñпільного викориÑтаннÑ"
+
+#: elf-m10300.c:4372 elf32-arm.c:12800 elf32-cr16.c:2451 elf32-cris.c:3057
+#: elf32-hppa.c:1894 elf32-i370.c:503 elf32-i386.c:2182 elf32-lm32.c:1868
+#: elf32-m32r.c:1927 elf32-m68k.c:3253 elf32-s390.c:1652 elf32-sh.c:2931
+#: elf32-tic6x.c:2162 elf32-tilepro.c:1940 elf32-vax.c:1041 elf64-s390.c:1635
+#: elf64-sh64.c:3381 elf64-x86-64.c:2176 elfxx-sparc.c:2119
+#: elfxx-tilegx.c:2261
+#, c-format
+msgid "dynamic variable `%s' is zero size"
+msgstr "динамічна змінна «%s» має нульовий розмір"
+
+#: elf.c:334
+msgid "%B: invalid string offset %u >= %lu for section `%s'"
+msgstr "%B: некоректний відÑтуп Ñ€Ñдка, %u >= %lu, Ð´Ð»Ñ Ñ€Ð¾Ð·Ð´Ñ–Ð»Ñƒ «%s»"
+
+#: elf.c:446
+msgid "%B symbol number %lu references nonexistent SHT_SYMTAB_SHNDX section"
+msgstr "%B номер Ñимволу %lu поÑилаєтьÑÑ Ð½Ð° розділ SHT_SYMTAB_SHNDX, Ñкого не Ñ–Ñнує"
+
+#: elf.c:602
+msgid "%B: Corrupt size field in group section header: 0x%lx"
+msgstr "%B: пошкоджені дані Ð¿Ð¾Ð»Ñ Ñ€Ð¾Ð·Ð¼Ñ–Ñ€Ñƒ у заголовку розділу груп: 0x%lx"
+
+#: elf.c:638
+msgid "%B: invalid SHT_GROUP entry"
+msgstr "%B: некоректний Ð·Ð°Ð¿Ð¸Ñ SHT_GROUP"
+
+#: elf.c:708
+msgid "%B: no group info for section %A"
+msgstr "%B: немає даних щодо групи Ð´Ð»Ñ Ñ€Ð¾Ð·Ð´Ñ–Ð»Ñƒ %A"
+
+#: elf.c:737 elf.c:3121 elflink.c:10135
+msgid "%B: warning: sh_link not set for section `%A'"
+msgstr "%B: попередженнÑ: не вÑтановлено sh_link Ð´Ð»Ñ Ñ€Ð¾Ð·Ð´Ñ–Ð»Ñƒ «%A»"
+
+#: elf.c:756
+msgid "%B: sh_link [%d] in section `%A' is incorrect"
+msgstr "%B: sh_link [%d] у розділі «%A» є некоректним"
+
+#: elf.c:791
+msgid "%B: unknown [%d] section `%s' in group [%s]"
+msgstr "%B: невідомий [%d] розділ «%s» у групі [%s]"
+
+#: elf.c:1041
+msgid "%B: unable to initialize commpress status for section %s"
+msgstr "%B: не вдалоÑÑ Ñ–Ð½Ñ–Ñ†Ñ–Ð°Ð»Ñ–Ð·ÑƒÐ²Ð°Ñ‚Ð¸ Ñтан ÑтиÑÐºÐ°Ð½Ð½Ñ Ð´Ð»Ñ Ñ€Ð¾Ð·Ð´Ñ–Ð»Ñƒ %s"
+
+#: elf.c:1061
+msgid "%B: unable to initialize decommpress status for section %s"
+msgstr "%B: не вдалоÑÑ Ñ–Ð½Ñ–Ñ†Ñ–Ð°Ð»Ñ–Ð·ÑƒÐ²Ð°Ñ‚Ð¸ Ñтан Ñ€Ð¾Ð·Ð¿Ð°ÐºÑƒÐ²Ð°Ð½Ð½Ñ Ð´Ð»Ñ Ñ€Ð¾Ð·Ð´Ñ–Ð»Ñƒ %s"
+
+#: elf.c:1181
+#, c-format
+msgid ""
+"\n"
+"Program Header:\n"
+msgstr ""
+"\n"
+"Заголовок програми:\n"
+
+#: elf.c:1223
+#, c-format
+msgid ""
+"\n"
+"Dynamic Section:\n"
+msgstr ""
+"\n"
+"Динамічний розділ:\n"
+
+#: elf.c:1359
+#, c-format
+msgid ""
+"\n"
+"Version definitions:\n"
+msgstr ""
+"\n"
+"Ð’Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð²ÐµÑ€Ñій:\n"
+
+#: elf.c:1384
+#, c-format
+msgid ""
+"\n"
+"Version References:\n"
+msgstr ""
+"\n"
+"ПоÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð½Ð° верÑÑ–Ñ—:\n"
+
+#: elf.c:1389
+#, c-format
+msgid " required from %s:\n"
+msgstr " потрібні %s:\n"
+
+#: elf.c:1796
+msgid "%B: invalid link %lu for reloc section %s (index %u)"
+msgstr "%B: некоректне поÑÐ¸Ð»Ð°Ð½Ð½Ñ %lu Ð´Ð»Ñ Ñ€Ð¾Ð·Ð´Ñ–Ð»Ñƒ переÑÑƒÐ²Ð°Ð½Ð½Ñ %s (Ñ–Ð½Ð´ÐµÐºÑ %u)"
+
+#: elf.c:1966
+msgid "%B: don't know how to handle allocated, application specific section `%s' [0x%8x]"
+msgstr "%B: ÑпоÑіб обробки розміщеного невідомий, Ñпецифічний Ð´Ð»Ñ Ð¿Ñ€Ð¾Ð³Ñ€Ð°Ð¼Ð¸ розділ «%s» [0x%8x]"
+
+#: elf.c:1978
+msgid "%B: don't know how to handle processor specific section `%s' [0x%8x]"
+msgstr "%B: ÑпоÑіб обробки Ñпецифічного Ð´Ð»Ñ Ð¿Ñ€Ð¾Ñ†ÐµÑора розділу `%s' [0x%8x] невідомий"
+
+#: elf.c:1989
+msgid "%B: don't know how to handle OS specific section `%s' [0x%8x]"
+msgstr "%B: ÑпоÑіб обробки Ñпецифічного Ð´Ð»Ñ ÐžÐ¡ розділу «%s» [0x%8x] невідомий"
+
+#: elf.c:1999
+msgid "%B: don't know how to handle section `%s' [0x%8x]"
+msgstr "%B: ÑпоÑіб обробки розділу «%s» [0x%8x] невідомий"
+
+#: elf.c:2634
+#, c-format
+msgid "warning: section `%A' type changed to PROGBITS"
+msgstr "попередженнÑ: тип розділу «%A» змінено на PROGBITS"
+
+#: elf.c:3078
+msgid "%B: sh_link of section `%A' points to discarded section `%A' of `%B'"
+msgstr "%B: sh_link розділу «%A» вказує на відкинутий розділ «%A» «%B»"
+
+#: elf.c:3101
+msgid "%B: sh_link of section `%A' points to removed section `%A' of `%B'"
+msgstr "%B: sh_link розділу «%A» вказує на вилучений розділ «%A» «%B»"
+
+#: elf.c:4527
+msgid "%B: The first section in the PT_DYNAMIC segment is not the .dynamic section"
+msgstr "%B: перший розділ у Ñегменті PT_DYNAMIC не Ñ” розділом .dynamic"
+
+#: elf.c:4554
+msgid "%B: Not enough room for program headers, try linking with -N"
+msgstr "%B: недоÑтатньо міÑÑ†Ñ Ð´Ð»Ñ Ð·Ð°Ð³Ð¾Ð»Ð¾Ð²ÐºÑ–Ð² програми, Ñпробуйте виконати ÐºÐ¾Ð¼Ð¿Ð¾Ð½ÑƒÐ²Ð°Ð½Ð½Ñ Ð· -N"
+
+#: elf.c:4641
+msgid "%B: section %A lma %#lx adjusted to %#lx"
+msgstr "%B: lma %#lx розділу %A Ñкориговано до %#lx"
+
+#: elf.c:4776
+msgid "%B: section `%A' can't be allocated in segment %d"
+msgstr "%B: розділ «%A» не може бути розподілено у Ñегменті %d"
+
+#: elf.c:4824
+msgid "%B: warning: allocated section `%s' not in segment"
+msgstr "%B: попередженнÑ: розподілений розділ «%s» перебуває за межами Ñегмента"
+
+#: elf.c:5324
+msgid "%B: symbol `%s' required but not present"
+msgstr "%B: потрібен Ñимвол «%s», але його немає"
+
+#: elf.c:5662
+msgid "%B: warning: Empty loadable segment detected, is this intentional ?\n"
+msgstr "%B: попередженнÑ: виÑвлено порожній завантажувальний Ñегмент, так Ñ– треба?\n"
+
+#: elf.c:6692
+#, c-format
+msgid "Unable to find equivalent output section for symbol '%s' from section '%s'"
+msgstr "Ðе вдалоÑÑ Ð·Ð½Ð°Ð¹Ñ‚Ð¸ рівноцінний розділ Ð²Ð¸Ð²ÐµÐ´ÐµÐ½Ð½Ñ Ð´Ð°Ð½Ð¸Ñ… Ð´Ð»Ñ Ñимволу «%s» з розділу «%s»"
+
+#: elf.c:7692
+msgid "%B: unsupported relocation type %s"
+msgstr "%B: непідтримуваний тип переÑÑƒÐ²Ð°Ð½Ð½Ñ %s"
+
+#: elf32-arm.c:3617
+msgid ""
+"%B(%s): warning: interworking not enabled.\n"
+" first occurrence: %B: Thumb call to ARM"
+msgstr ""
+"%B(%s): попередженнÑ: ÑуміÑну роботу не увімкнено.\n"
+" перша згадка: %B: виклик thumb до ARM"
+
+#: elf32-arm.c:3664
+msgid ""
+"%B(%s): warning: interworking not enabled.\n"
+" first occurrence: %B: ARM call to Thumb"
+msgstr ""
+"%B(%s): попередженнÑ: ÑуміÑну роботу не увімкнено.\n"
+" перша згадка: %B: виклик ARM до Thumb"
+
+#: elf32-arm.c:3878 elf32-arm.c:5315
+#, c-format
+msgid "%s: cannot create stub entry %s"
+msgstr "%s: не вдалоÑÑ Ñтворити шаблонний Ð·Ð°Ð¿Ð¸Ñ %s"
+
+#: elf32-arm.c:5431
+#, c-format
+msgid "unable to find THUMB glue '%s' for '%s'"
+msgstr "не вдалоÑÑ Ð·Ð½Ð°Ð¹Ñ‚Ð¸ Ñклейку THUMB «%s» Ð´Ð»Ñ Â«%s»"
+
+#: elf32-arm.c:5467
+#, c-format
+msgid "unable to find ARM glue '%s' for '%s'"
+msgstr "не вдалоÑÑ Ð·Ð½Ð°Ð¹Ñ‚Ð¸ Ñклейку ARM «%s» Ð´Ð»Ñ Â«%s»"
+
+#: elf32-arm.c:6005
+msgid "%B: BE8 images only valid in big-endian mode."
+msgstr "%B: образи BE8 є чинними лише у режимі big-endian."
+
+#. Give a warning, but do as the user requests anyway.
+#: elf32-arm.c:6235
+msgid "%B: warning: selected VFP11 erratum workaround is not necessary for target architecture"
+msgstr "%B: попередженнÑ: вибраний ÑпоÑіб ÑƒÐ½Ð¸ÐºÐ½ÐµÐ½Ð½Ñ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ¸ VFP11 не Ñ” необхідним Ð´Ð»Ñ Ð°Ñ€Ñ…Ñ–Ñ‚ÐµÐºÑ‚ÑƒÑ€Ð¸ призначеннÑ"
+
+#: elf32-arm.c:6779 elf32-arm.c:6799
+msgid "%B: unable to find VFP11 veneer `%s'"
+msgstr "%B: не вдалоÑÑ Ð·Ð½Ð°Ð¹Ñ‚Ð¸ обгортку VFP11 «%s»"
+
+#: elf32-arm.c:6848
+#, c-format
+msgid "Invalid TARGET2 relocation type '%s'."
+msgstr "Ðекоректний тип переÑÑƒÐ²Ð°Ð½Ð½Ñ Ñƒ TARGET2, «%s»."
+
+#: elf32-arm.c:6933
+msgid ""
+"%B(%s): warning: interworking not enabled.\n"
+" first occurrence: %B: thumb call to arm"
+msgstr ""
+"%B(%s): попередженнÑ: ÑуміÑну роботу не увімкнено.\n"
+" перша згадка: %B: виклик thumb до arm"
+
+#: elf32-arm.c:7717
+msgid "%B(%A+0x%lx):unexpected Thumb instruction '0x%x' in TLS trampoline"
+msgstr "%B(%A+0x%lx): неочікувана команда Thumb, «0x%x», у трампліні TLS"
+
+#: elf32-arm.c:7756
+msgid "%B(%A+0x%lx):unexpected ARM instruction '0x%x' in TLS trampoline"
+msgstr "%B(%A+0x%lx): неочікувана команда ARM, «0x%x», у трампліні TLS"
+
+#: elf32-arm.c:8209
+msgid "\\%B: Warning: Arm BLX instruction targets Arm function '%s'."
+msgstr "\\%B: попередженнÑ: команда Arm BLX вказує на функцію Arm «%s»."
+
+#: elf32-arm.c:8622
+msgid "%B: Warning: Thumb BLX instruction targets thumb function '%s'."
+msgstr "%B: попередженнÑ: команда Thumb BLX вказує на функцію Arm «%s»."
+
+#: elf32-arm.c:9460
+msgid "%B(%A+0x%lx):unexpected Thumb instruction '0x%x' referenced by TLS_GOTDESC"
+msgstr "%B(%A+0x%lx): неочікувана команда Thumb, «0x%x», на Ñку поÑилаєтьÑÑ TLS_GOTDESC"
+
+#: elf32-arm.c:9483
+msgid "%B(%A+0x%lx):unexpected ARM instruction '0x%x' referenced by TLS_GOTDESC"
+msgstr "%B(%A+0x%lx): неочікувана команда ARM, «0x%x», на Ñку поÑилаєтьÑÑ TLS_GOTDESC"
+
+#: elf32-arm.c:9512
+msgid "%B(%A+0x%lx): R_ARM_TLS_LE32 relocation not permitted in shared object"
+msgstr "%B(%A+0x%lx): переÑÑƒÐ²Ð°Ð½Ð½Ñ R_ARM_TLS_LE32 у об’єкті Ñпільного викориÑÑ‚Ð°Ð½Ð½Ñ Ð·Ð°Ð±Ð¾Ñ€Ð¾Ð½ÐµÐ½Ð¾"
+
+#: elf32-arm.c:9727
+msgid "%B(%A+0x%lx): Only ADD or SUB instructions are allowed for ALU group relocations"
+msgstr "%B(%A+0x%lx): Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÑувань груп ALU можна викориÑтовувати лише команди ADD або SUB"
+
+#: elf32-arm.c:9767 elf32-arm.c:9854 elf32-arm.c:9937 elf32-arm.c:10022
+msgid "%B(%A+0x%lx): Overflow whilst splitting 0x%lx for group relocation %s"
+msgstr "%B(%A+0x%lx): Ð¿ÐµÑ€ÐµÐ¿Ð¾Ð²Ð½ÐµÐ½Ð½Ñ Ð¿Ñ–Ð´ Ñ‡Ð°Ñ Ñпроби поділу 0x%lx з метою групового переÑÑƒÐ²Ð°Ð½Ð½Ñ %s"
+
+#: elf32-arm.c:10261 elf32-sh.c:4103 elf64-sh64.c:1544
+msgid "%B(%A+0x%lx): %s relocation against SEC_MERGE section"
+msgstr "%B(%A+0x%lx): переÑÑƒÐ²Ð°Ð½Ð½Ñ %s щодо розділу SEC_MERGE"
+
+#: elf32-arm.c:10372 elf32-m68k.c:4191 elf32-xtensa.c:2802
+msgid "%B(%A+0x%lx): %s used with TLS symbol %s"
+msgstr "%B(%A+0x%lx): %s викориÑтовуєтьÑÑ Ð· Ñимволом TLS %s"
+
+#: elf32-arm.c:10373 elf32-m68k.c:4192 elf32-xtensa.c:2803
+msgid "%B(%A+0x%lx): %s used with non-TLS symbol %s"
+msgstr "%B(%A+0x%lx): %s викориÑтовуєтьÑÑ Ð· Ñимволом поза TLS %s"
+
+#: elf32-arm.c:10453 elf32-tic6x.c:2753
+msgid "out of range"
+msgstr "поза діапазоном"
+
+#: elf32-arm.c:10457 elf32-tic6x.c:2757
+msgid "unsupported relocation"
+msgstr "непідтримуване переÑуваннÑ"
+
+#: elf32-arm.c:10465 elf32-tic6x.c:2765
+msgid "unknown error"
+msgstr "невідома помилка"
+
+#: elf32-arm.c:10890
+msgid "Warning: Clearing the interworking flag of %B because non-interworking code in %B has been linked with it"
+msgstr "ПопередженнÑ: знÑто прапорець ÑуміÑної роботи у %B, оÑкільки з ним компонуєтьÑÑ ÐºÐ¾Ð´, Ñкий непридатний до Ñпільної роботи, у %B"
+
+#: elf32-arm.c:10984
+msgid "%B: Unknown mandatory EABI object attribute %d"
+msgstr "%B: невідомий обов’Ñзковий атрибути об’єкта EABI %d"
+
+#: elf32-arm.c:10992
+msgid "Warning: %B: Unknown EABI object attribute %d"
+msgstr "ПопередженнÑ: %B: невідомий атрибут об’єкта EABI %d"
+
+#: elf32-arm.c:11173
+msgid "error: %B: Unknown CPU architecture"
+msgstr "помилка: %B: невідома архітектура процеÑора"
+
+#: elf32-arm.c:11211
+msgid "error: %B: Conflicting CPU architectures %d/%d"
+msgstr "помилка: %B: конфлікт архітектур процеÑорів %d/%d"
+
+#: elf32-arm.c:11260
+msgid "Error: %B has both the current and legacy Tag_MPextension_use attributes"
+msgstr "Помилка: Ð´Ð»Ñ %B визначено одразу обидва атрибути Tag_MPextension_use, current Ñ– legacy"
+
+#: elf32-arm.c:11285
+msgid "error: %B uses VFP register arguments, %B does not"
+msgstr "помилка: у %B викориÑтовуютьÑÑ Ð°Ñ€Ð³ÑƒÐ¼ÐµÐ½Ñ‚Ð¸ регіÑтри VFP, а у %B — ні"
+
+#: elf32-arm.c:11430
+msgid "error: %B: unable to merge virtualization attributes with %B"
+msgstr "помилка: %B: Ð¾Ð±â€™Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Ð°Ñ‚Ñ€Ð¸Ð±ÑƒÑ‚Ñ–Ð² віртуалізації з %B неможливе"
+
+#: elf32-arm.c:11456
+msgid "error: %B: Conflicting architecture profiles %c/%c"
+msgstr "помилка: %B: конфлікт профілів архітектур, %c/%c"
+
+#: elf32-arm.c:11557
+msgid "Warning: %B: Conflicting platform configuration"
+msgstr "ПопередженнÑ: %B: конфлікт налаштувань платформ"
+
+#: elf32-arm.c:11566
+msgid "error: %B: Conflicting use of R9"
+msgstr "помилка: %B: конфлікт у викориÑтанні R9"
+
+#: elf32-arm.c:11578
+msgid "error: %B: SB relative addressing conflicts with use of R9"
+msgstr "помилка: %B: викориÑÑ‚Ð°Ð½Ð½Ñ Ð²Ñ–Ð´Ð½Ð¾Ñної адреÑації SB конфліктує з викориÑтаннÑм R9"
+
+#: elf32-arm.c:11591
+msgid "warning: %B uses %u-byte wchar_t yet the output is to use %u-byte wchar_t; use of wchar_t values across objects may fail"
+msgstr "попередженнÑ: у %B викориÑтовуєтьÑÑ %u-байтовий wchar_t, хоча у виведенні викориÑтовуєтьÑÑ %u-байтовий wchar_t; викориÑÑ‚Ð°Ð½Ð½Ñ Ð·Ð½Ð°Ñ‡ÐµÐ½ÑŒ wchar_t між об’єктами може зазнати невдачі"
+
+#: elf32-arm.c:11622
+msgid "warning: %B uses %s enums yet the output is to use %s enums; use of enum values across objects may fail"
+msgstr "попередженнÑ: у %B викориÑтовуютьÑÑ Ð¿ÐµÑ€ÐµÐ»Ñ–ÐºÐ¸ %s, хоча у виведенні викориÑтовуютьÑÑ Ð¿ÐµÑ€ÐµÐ»Ñ–ÐºÐ¸ %s; викориÑÑ‚Ð°Ð½Ð½Ñ Ð·Ð½Ð°Ñ‡ÐµÐ½ÑŒ переліків між об’єктами може зазнати невдачі"
+
+#: elf32-arm.c:11634
+msgid "error: %B uses iWMMXt register arguments, %B does not"
+msgstr "помилка: у %B викориÑтовуютьÑÑ Ð°Ñ€Ð³ÑƒÐ¼ÐµÐ½Ñ‚Ð¸-регіÑтри iWMMXt, а у %B — ні"
+
+#: elf32-arm.c:11651
+msgid "error: fp16 format mismatch between %B and %B"
+msgstr "помилка: розбіжноÑÑ‚Ñ– у визначенні Ñ„Ð¾Ñ€Ð¼Ð°Ñ‚ÑƒÐ²Ð°Ð½Ð½Ñ fp16 між %B та %B"
+
+#: elf32-arm.c:11675
+msgid "DIV usage mismatch between %B and %B"
+msgstr "розбіжноÑÑ‚Ñ– у викориÑтанні DIV між %B та %B"
+
+#: elf32-arm.c:11694
+msgid "%B has has both the current and legacy Tag_MPextension_use attributes"
+msgstr "Ð´Ð»Ñ %B визначено одразу обидва атрибути Tag_MPextension_use, current Ñ– legacy"
+
+#. Ignore init flag - it may not be set, despite the flags field
+#. containing valid data.
+#. Ignore init flag - it may not be set, despite the flags field containing valid data.
+#: elf32-arm.c:11782 elf32-bfin.c:5079 elf32-cris.c:4169 elf32-m68hc1x.c:1282
+#: elf32-m68k.c:1236 elf32-score.c:3994 elf32-score7.c:3800 elf32-vax.c:529
+#: elfxx-mips.c:14103
+#, c-format
+msgid "private flags = %lx:"
+msgstr "закриті прапорці = %lx:"
+
+#: elf32-arm.c:11791
+#, c-format
+msgid " [interworking enabled]"
+msgstr " [увімкнено ÑуміÑну роботу]"
+
+#: elf32-arm.c:11799
+#, c-format
+msgid " [VFP float format]"
+msgstr " [формат float VFP]"
+
+#: elf32-arm.c:11801
+#, c-format
+msgid " [Maverick float format]"
+msgstr " [формат float Maverick]"
+
+#: elf32-arm.c:11803
+#, c-format
+msgid " [FPA float format]"
+msgstr " [формат float FPA]"
+
+#: elf32-arm.c:11812
+#, c-format
+msgid " [new ABI]"
+msgstr " [новий ABI]"
+
+#: elf32-arm.c:11815
+#, c-format
+msgid " [old ABI]"
+msgstr " [Ñтарий ABI]"
+
+#: elf32-arm.c:11818
+#, c-format
+msgid " [software FP]"
+msgstr " [програмна FP]"
+
+#: elf32-arm.c:11827
+#, c-format
+msgid " [Version1 EABI]"
+msgstr " [ВерÑÑ–Ñ1 EABI]"
+
+#: elf32-arm.c:11830 elf32-arm.c:11841
+#, c-format
+msgid " [sorted symbol table]"
+msgstr " [впорÑдкована Ñ‚Ð°Ð±Ð»Ð¸Ñ†Ñ Ñимволів]"
+
+#: elf32-arm.c:11832 elf32-arm.c:11843
+#, c-format
+msgid " [unsorted symbol table]"
+msgstr " [невпорÑдкована Ñ‚Ð°Ð±Ð»Ð¸Ñ†Ñ Ñимволів]"
+
+#: elf32-arm.c:11838
+#, c-format
+msgid " [Version2 EABI]"
+msgstr " [ВерÑÑ–Ñ2 EABI]"
+
+#: elf32-arm.c:11846
+#, c-format
+msgid " [dynamic symbols use segment index]"
+msgstr " [динамічні Ñимволи викориÑтовують Ñ–Ð½Ð´ÐµÐºÑ Ñегмента]"
+
+#: elf32-arm.c:11849
+#, c-format
+msgid " [mapping symbols precede others]"
+msgstr " [Ñимволи Ð²Ñ–Ð´Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ Ð¿ÐµÑ€ÐµÐ´ÑƒÑŽÑ‚ÑŒ іншим]"
+
+#: elf32-arm.c:11856
+#, c-format
+msgid " [Version3 EABI]"
+msgstr " [ВерÑÑ–Ñ3 EABI]"
+
+#: elf32-arm.c:11860
+#, c-format
+msgid " [Version4 EABI]"
+msgstr " [ВерÑÑ–Ñ4 EABI]"
+
+#: elf32-arm.c:11864
+#, c-format
+msgid " [Version5 EABI]"
+msgstr " [ВерÑÑ–Ñ5 EABI]"
+
+#: elf32-arm.c:11867
+#, c-format
+msgid " [BE8]"
+msgstr " [BE8]"
+
+#: elf32-arm.c:11870
+#, c-format
+msgid " [LE8]"
+msgstr " [LE8]"
+
+#: elf32-arm.c:11876
+#, c-format
+msgid " <EABI version unrecognised>"
+msgstr " <нерозпізнана верÑÑ–Ñ EABI>"
+
+#: elf32-arm.c:11883
+#, c-format
+msgid " [relocatable executable]"
+msgstr " [придатний до переÑÑƒÐ²Ð°Ð½Ð½Ñ Ð²Ð¸ÐºÐ¾Ð½ÑƒÐ²Ð°Ð½Ð¸Ð¹ файл]"
+
+#: elf32-arm.c:11886
+#, c-format
+msgid " [has entry point]"
+msgstr " [має вхідну точку]"
+
+#: elf32-arm.c:11891
+#, c-format
+msgid "<Unrecognised flag bits set>"
+msgstr "<Ðерозпізнаний набір бітів прапорців>"
+
+#: elf32-arm.c:12189 elf32-i386.c:1461 elf32-s390.c:1000 elf32-tic6x.c:2829
+#: elf32-tilepro.c:1336 elf32-xtensa.c:1009 elf64-s390.c:960
+#: elf64-x86-64.c:1364 elfxx-sparc.c:1371 elfxx-tilegx.c:1586
+msgid "%B: bad symbol index: %d"
+msgstr "%B: помилковий Ñ–Ð½Ð´ÐµÐºÑ Ñимволу: %d"
+
+#: elf32-arm.c:12337 elf64-x86-64.c:1561 elf64-x86-64.c:1732 elfxx-mips.c:8223
+msgid "%B: relocation %s against `%s' can not be used when making a shared object; recompile with -fPIC"
+msgstr "%B: переÑÑƒÐ²Ð°Ð½Ð½Ñ %s щодо «%s» не можна викориÑтовувати під Ñ‡Ð°Ñ ÑÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ð¾Ð±â€™Ñ”ÐºÑ‚Ð° Ñпільного викориÑтаннÑ; повторно зберіть з -fPIC"
+
+#: elf32-arm.c:13460
+#, c-format
+msgid "Errors encountered processing file %s"
+msgstr "Під Ñ‡Ð°Ñ Ð¾Ð±Ñ€Ð¾Ð±ÐºÐ¸ файла ÑталиÑÑ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ¸, %s"
+
+#: elf32-arm.c:14837
+msgid "%B: error: Cortex-A8 erratum stub is allocated in unsafe location"
+msgstr "%B: помилка: замінник Ð´Ð»Ñ Ð¾Ð±Ñ€Ð¾Ð±Ð½Ð¸ÐºÐ° помилки Cortex-A8 розташовано за небезпечною адреÑою"
+
+#. There's not much we can do apart from complain if this
+#. happens.
+#: elf32-arm.c:14864
+msgid "%B: error: Cortex-A8 erratum stub out of range (input file too large)"
+msgstr "%B: помилка: замінник Ð´Ð»Ñ Ð¾Ð±Ñ€Ð¾Ð±Ð½Ð¸ÐºÐ° помилки Cortex-A8 перебуває поза доÑтупним діапазоном (файл вхідних даних Ñ” надто великим)"
+
+#: elf32-arm.c:14958 elf32-arm.c:14980
+msgid "%B: error: VFP11 veneer out of range"
+msgstr "%B: помилка: обгортка VFP11 поза діапазоном"
+
+#: elf32-arm.c:15518
+msgid "error: %B is already in final BE8 format"
+msgstr "помилка: %B вже зберігаєтьÑÑ Ñƒ оÑтаточному форматі BE8"
+
+#: elf32-arm.c:15594
+msgid "error: Source object %B has EABI version %d, but target %B has EABI version %d"
+msgstr "помилка: об’єкт-джерело, %B, викориÑтовує верÑÑ–ÑŽ EABI %d, а призначеннÑ, %B, викориÑтовує верÑÑ–ÑŽ EABI %d"
+
+#: elf32-arm.c:15610
+msgid "error: %B is compiled for APCS-%d, whereas target %B uses APCS-%d"
+msgstr "помилка: %B зібрано Ð´Ð»Ñ APCS-%d, тоді Ñк %B викориÑтовує APCS-%d"
+
+#: elf32-arm.c:15635
+msgid "error: %B uses VFP instructions, whereas %B does not"
+msgstr "помилка: у %B викориÑтовуютьÑÑ ÐºÐ¾Ð¼Ð°Ð½Ð´Ð¸ VFP, а у %B — ні"
+
+#: elf32-arm.c:15639
+msgid "error: %B uses FPA instructions, whereas %B does not"
+msgstr "помилка: у %B викориÑтовуютьÑÑ ÐºÐ¾Ð¼Ð°Ð½Ð´Ð¸ FPA, а у %B — ні"
+
+#: elf32-arm.c:15649
+msgid "error: %B uses Maverick instructions, whereas %B does not"
+msgstr "помилка: у %B викориÑтовуютьÑÑ ÐºÐ¾Ð¼Ð°Ð½Ð´Ð¸ Maverick, а у %B — ні"
+
+#: elf32-arm.c:15653
+msgid "error: %B does not use Maverick instructions, whereas %B does"
+msgstr "помилка: у %B не викориÑтовуютьÑÑ ÐºÐ¾Ð¼Ð°Ð½Ð´Ð¸ Maverick, а у %B — так"
+
+#: elf32-arm.c:15672
+msgid "error: %B uses software FP, whereas %B uses hardware FP"
+msgstr "помилка: у %B викориÑтовуютьÑÑ Ð¿Ñ€Ð¾Ð³Ñ€Ð°Ð¼Ð½Ñ– FP, а у %B — апаратні FP"
+
+#: elf32-arm.c:15676
+msgid "error: %B uses hardware FP, whereas %B uses software FP"
+msgstr "помилка: у %B викориÑтовуютьÑÑ Ð°Ð¿Ð°Ñ€Ð°Ñ‚Ð½Ñ– FP, а у %B — програмні FP"
+
+#: elf32-avr.c:1229 elf32-bfin.c:3221 elf32-cris.c:2089 elf32-epiphany.c:567
+#: elf32-fr30.c:617 elf32-frv.c:4113 elf32-i860.c:1219 elf32-ip2k.c:1479
+#: elf32-iq2000.c:692 elf32-m32c.c:561 elf32-mep.c:543 elf32-moxie.c:290
+#: elf32-msp430.c:494 elf32-mt.c:399 elf32-openrisc.c:412 elf32-tilepro.c:3222
+#: elf32-v850.c:2151 elf32-xstormy16.c:943 elf64-mmix.c:1598
+#: elfxx-tilegx.c:3585
+msgid "internal error: dangerous relocation"
+msgstr "Ð²Ð½ÑƒÑ‚Ñ€Ñ–ÑˆÐ½Ñ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ°: небезпечне переÑуваннÑ"
+
+#: elf32-avr.c:2415 elf32-hppa.c:598 elf32-m68hc1x.c:166
+msgid "%B: cannot create stub entry %s"
+msgstr "%B: не вдалоÑÑ Ñтворити шаблонний Ð·Ð°Ð¿Ð¸Ñ %s"
+
+#: elf32-bfin.c:107 elf32-bfin.c:363
+msgid "relocation should be even number"
+msgstr "переÑÑƒÐ²Ð°Ð½Ð½Ñ Ð¼Ð°Ñ” бути вказано парним чиÑлом"
+
+#: elf32-bfin.c:1593
+msgid "%B(%A+0x%lx): unresolvable relocation against symbol `%s'"
+msgstr "B(%A+0x%lx): нерозв’Ñзне переÑÑƒÐ²Ð°Ð½Ð½Ñ Ñ‰Ð¾Ð´Ð¾ Ñимволу «%s»"
+
+#: elf32-bfin.c:1626 elf32-i386.c:4307 elf32-m68k.c:4233 elf32-s390.c:3055
+#: elf64-s390.c:3030 elf64-x86-64.c:4151
+msgid "%B(%A+0x%lx): reloc against `%s': error %d"
+msgstr "%B(%A+0x%lx): переÑÑƒÐ²Ð°Ð½Ð½Ñ Ñ‰Ð¾Ð´Ð¾ «%s»: помилка %d"
+
+#: elf32-bfin.c:2725
+msgid "%B: relocation at `%A+0x%x' references symbol `%s' with nonzero addend"
+msgstr "%B: переÑÑƒÐ²Ð°Ð½Ð½Ñ Ñƒ «%A+0x%x» поÑилаєтьÑÑ Ð½Ð° Ñимвол «%s» з ненульовим доданком"
+
+#: elf32-bfin.c:2741
+msgid "relocation references symbol not defined in the module"
+msgstr "переÑÑƒÐ²Ð°Ð½Ð½Ñ Ð¿Ð¾ÑилаєтьÑÑ Ð½Ð° Ñимвол, Ñкий не визначено у модулі"
+
+#: elf32-bfin.c:2838
+msgid "R_BFIN_FUNCDESC references dynamic symbol with nonzero addend"
+msgstr "R_BFIN_FUNCDESC поÑилаєтьÑÑ Ð½Ð° динамічний Ñимвол з ненульовим доданком"
+
+#: elf32-bfin.c:2879 elf32-bfin.c:3002
+msgid "cannot emit fixups in read-only section"
+msgstr "не можна викориÑтовувати адреÑну прив’Ñзку у розділі, придатному лише Ð´Ð»Ñ Ñ‡Ð¸Ñ‚Ð°Ð½Ð½Ñ"
+
+#: elf32-bfin.c:2910 elf32-bfin.c:3040 elf32-lm32.c:1103 elf32-sh.c:5016
+msgid "cannot emit dynamic relocations in read-only section"
+msgstr "не можна викориÑтовувати динамічні переÑÑƒÐ²Ð°Ð½Ð½Ñ Ñƒ розділі, призначеному лише Ð´Ð»Ñ Ñ‡Ð¸Ñ‚Ð°Ð½Ð½Ñ"
+
+#: elf32-bfin.c:2960
+msgid "R_BFIN_FUNCDESC_VALUE references dynamic symbol with nonzero addend"
+msgstr "R_BFIN_FUNCDESC_VALUE поÑилаєтьÑÑ Ð½Ð° динамічний Ñимвол з ненульовим доданком"
+
+#: elf32-bfin.c:3125
+msgid "relocations between different segments are not supported"
+msgstr "підтримки переÑÑƒÐ²Ð°Ð½Ð½Ñ Ð¼Ñ–Ð¶ різними Ñегментами не передбачено"
+
+#: elf32-bfin.c:3126
+msgid "warning: relocation references a different segment"
+msgstr "попередженнÑ: у переÑуванні виÑвлено поÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð½Ð° інший Ñегмент"
+
+#: elf32-bfin.c:4971
+msgid "%B: unsupported relocation type %i"
+msgstr "%B: непідтримуваний тип переÑÑƒÐ²Ð°Ð½Ð½Ñ %i"
+
+#: elf32-bfin.c:5125 elf32-frv.c:6808
+#, c-format
+msgid "%s: cannot link non-fdpic object file into fdpic executable"
+msgstr "%s: не можна компонувати об’єктний файл не-fdpic до виконуваного файла fdpic"
+
+#: elf32-bfin.c:5129 elf32-frv.c:6812
+#, c-format
+msgid "%s: cannot link fdpic object file into non-fdpic executable"
+msgstr "%s: не можна компонувати об’єктний файл fdpic до виконуваного файла не-fdpic"
+
+#: elf32-bfin.c:5283
+#, c-format
+msgid "*** check this relocation %s"
+msgstr "*** перевірте це переÑуваннÑ: %s"
+
+#: elf32-cris.c:1176
+msgid "%B, section %A: unresolvable relocation %s against symbol `%s'"
+msgstr "%B, розділ %A: нерозв’Ñзне переÑÑƒÐ²Ð°Ð½Ð½Ñ %s щодо Ñимволу «%s»"
+
+#: elf32-cris.c:1238
+msgid "%B, section %A: No PLT nor GOT for relocation %s against symbol `%s'"
+msgstr "%B, розділ %A: немає ні PLT, ні GOT Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÑÑƒÐ²Ð°Ð½Ð½Ñ %s щодо Ñимволу «%s»"
+
+#: elf32-cris.c:1240
+msgid "%B, section %A: No PLT for relocation %s against symbol `%s'"
+msgstr "%B, розділ %A: немає PLT Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÑÑƒÐ²Ð°Ð½Ð½Ñ %s щодо Ñимволу «%s»"
+
+#: elf32-cris.c:1246 elf32-cris.c:1379 elf32-cris.c:1639 elf32-cris.c:1722
+#: elf32-cris.c:1875 elf32-tic6x.c:2662
+msgid "[whose name is lost]"
+msgstr "[чию назву втрачено]"
+
+#: elf32-cris.c:1365 elf32-tic6x.c:2647
+msgid "%B, section %A: relocation %s with non-zero addend %d against local symbol"
+msgstr "%B, розділ %A: переÑÑƒÐ²Ð°Ð½Ð½Ñ %s з ненульовим доданком, %d, щодо локального Ñимволу"
+
+#: elf32-cris.c:1373 elf32-cris.c:1716 elf32-cris.c:1869 elf32-tic6x.c:2655
+msgid "%B, section %A: relocation %s with non-zero addend %d against symbol `%s'"
+msgstr "%B, розділ %A: переÑÑƒÐ²Ð°Ð½Ð½Ñ %s з ненульовим доданком, %d, щодо Ñимволу «%s»"
+
+#: elf32-cris.c:1399
+msgid "%B, section %A: relocation %s is not allowed for global symbol: `%s'"
+msgstr "%B, розділ %A: не можна виконувати переÑÑƒÐ²Ð°Ð½Ð½Ñ %s Ð´Ð»Ñ Ð·Ð°Ð³Ð°Ð»ÑŒÐ½Ð¾Ð³Ð¾ Ñимволу: «%s»"
+
+#: elf32-cris.c:1415
+msgid "%B, section %A: relocation %s with no GOT created"
+msgstr "%B, розділ %A: переÑÑƒÐ²Ð°Ð½Ð½Ñ %s без Ñтвореного GOT"
+
+#. We shouldn't get here for GCC-emitted code.
+#: elf32-cris.c:1630
+msgid "%B, section %A: relocation %s has an undefined reference to `%s', perhaps a declaration mixup?"
+msgstr "%B, розділ %A: у переÑуванні %s Ñ” невизначене поÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð½Ð° «%s», можливо, адреÑна прив’Ñзка оголошеннÑ?"
+
+#: elf32-cris.c:2002
+msgid "%B, section %A: relocation %s is not allowed for symbol: `%s' which is defined outside the program, perhaps a declaration mixup?"
+msgstr "%B, розділ %A: не можна виконувати переÑÑƒÐ²Ð°Ð½Ð½Ñ %s Ð´Ð»Ñ Ñимволу «%s», Ñкий визначено поза програмою. Можливо, помилка у оголошенні?"
+
+#: elf32-cris.c:2055
+msgid "(too many global variables for -fpic: recompile with -fPIC)"
+msgstr "(забагато загальних змінних Ð´Ð»Ñ -fpic: виконайте повторне Ð·Ð±Ð¸Ñ€Ð°Ð½Ð½Ñ Ð· -fPIC)"
+
+#: elf32-cris.c:2062
+msgid "(thread-local data too big for -fpic or -msmall-tls: recompile with -fPIC or -mno-small-tls)"
+msgstr "(дані локального потоку Ñ” надто великими Ð´Ð»Ñ -fpic або -msmall-tls: повторно зберіть з -fPIC або -mno-small-tls)"
+
+#: elf32-cris.c:3261
+msgid ""
+"%B, section %A:\n"
+" v10/v32 compatible object %s must not contain a PIC relocation"
+msgstr ""
+"%B, розділ %A:\n"
+" об’єкт верÑÑ–Ñ— 10/32, %s, не повинен міÑтити переÑÑƒÐ²Ð°Ð½Ð½Ñ PIC"
+
+#: elf32-cris.c:3366
+msgid ""
+"%B, section %A:\n"
+" relocation %s not valid in a shared object; typically an option mixup, recompile with -fPIC"
+msgstr ""
+"%B, розділ %A:\n"
+" переÑÑƒÐ²Ð°Ð½Ð½Ñ %s не Ñ” коректним у Ñпільному об’єкті; типовою причиною Ñ” конфлікт параметрів, перекомпілюйте з -fPIC"
+
+#: elf32-cris.c:3580
+msgid ""
+"%B, section %A:\n"
+" relocation %s should not be used in a shared object; recompile with -fPIC"
+msgstr ""
+"%B, розділ %A:\n"
+" переÑÑƒÐ²Ð°Ð½Ð½Ñ %s не Ñлід викориÑтовувати у Ñпільному об’єкті; перекомпілюйте з -fPIC"
+
+#: elf32-cris.c:4002
+msgid ""
+"%B, section `%A', to symbol `%s':\n"
+" relocation %s should not be used in a shared object; recompile with -fPIC"
+msgstr ""
+"%B, розділ «%A» до Ñимволу «%s»:\n"
+" переÑÑƒÐ²Ð°Ð½Ð½Ñ %s не Ñлід викориÑтовувати у Ñпільному об’єкті; перекомпілюйте з -fPIC"
+
+#: elf32-cris.c:4118
+msgid "Unexpected machine number"
+msgstr "Ðеочікуваний номер машини"
+
+#: elf32-cris.c:4172
+#, c-format
+msgid " [symbols have a _ prefix]"
+msgstr " [Ñимволи міÑÑ‚ÑÑ‚ÑŒ Ð¿Ñ€ÐµÑ„Ñ–ÐºÑ _]"
+
+#: elf32-cris.c:4175
+#, c-format
+msgid " [v10 and v32]"
+msgstr " [v10 та v32]"
+
+#: elf32-cris.c:4178
+#, c-format
+msgid " [v32]"
+msgstr " [v32]"
+
+#: elf32-cris.c:4223
+msgid "%B: uses _-prefixed symbols, but writing file with non-prefixed symbols"
+msgstr "%B: викориÑтовуютьÑÑ Ñимволи з префікÑом «_», але виконуєтьÑÑ Ð·Ð°Ð¿Ð¸Ñ Ñ„Ð°Ð¹Ð»Ð° з Ñимволами без префікÑів"
+
+#: elf32-cris.c:4224
+msgid "%B: uses non-prefixed symbols, but writing file with _-prefixed symbols"
+msgstr "%B: викориÑтовуютьÑÑ Ñимволи без префікÑа «_», але виконуєтьÑÑ Ð·Ð°Ð¿Ð¸Ñ Ñ„Ð°Ð¹Ð»Ð° з Ñимволами з префікÑами «_»"
+
+#: elf32-cris.c:4243
+msgid "%B contains CRIS v32 code, incompatible with previous objects"
+msgstr "у %B міÑтитьÑÑ ÐºÐ¾Ð´ v32 CRIS, неÑуміÑний з попередніми об’єктами"
+
+#: elf32-cris.c:4245
+msgid "%B contains non-CRIS-v32 code, incompatible with previous objects"
+msgstr "у %B міÑтитьÑÑ ÐºÐ¾Ð´, Ñкий не Ñ” кодом v32 CRIS, неÑуміÑний з попередніми об’єктами"
+
+#: elf32-dlx.c:142
+#, c-format
+msgid "BFD Link Error: branch (PC rel16) to section (%s) not supported"
+msgstr "Помилка ÐºÐ¾Ð¼Ð¿Ð¾Ð½ÑƒÐ²Ð°Ð½Ð½Ñ BFD: Ð²Ñ–Ð´Ð³Ð°Ð»ÑƒÐ¶ÐµÐ½Ð½Ñ (PC rel16) до розділу (%s) не підтримуєтьÑÑ"
+
+#: elf32-dlx.c:204
+#, c-format
+msgid "BFD Link Error: jump (PC rel26) to section (%s) not supported"
+msgstr "Помилка ÐºÐ¾Ð¼Ð¿Ð¾Ð½ÑƒÐ²Ð°Ð½Ð½Ñ BFD: не передбачено підтримки переходу (PC rel26) до розділу (%s)"
+
+#. Only if it's not an unresolved symbol.
+#: elf32-epiphany.c:563 elf32-ip2k.c:1475
+msgid "unsupported relocation between data/insn address spaces"
+msgstr "непідтримуване переÑÑƒÐ²Ð°Ð½Ð½Ñ Ð¼Ñ–Ð¶ проÑторами Ð°Ð´Ñ€ÐµÑ data та insn"
+
+#: elf32-frv.c:1509 elf32-frv.c:1658
+msgid "relocation requires zero addend"
+msgstr "Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÑÑƒÐ²Ð°Ð½Ð½Ñ Ð¿Ð¾Ñ‚Ñ€Ñ–Ð±ÐµÐ½ нульовий доданок"
+
+#: elf32-frv.c:2888
+msgid "%H: relocation to `%s+%v' may have caused the error above\n"
+msgstr "%H: Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð¿Ñ€Ð¾ помилку, наведене вище, можливо Ñпричинене переÑуваннÑм до «%s+%v»\n"
+
+#: elf32-frv.c:2905
+msgid "%H: relocation references symbol not defined in the module\n"
+msgstr "%H: переÑÑƒÐ²Ð°Ð½Ð½Ñ Ð¿Ð¾ÑилаєтьÑÑ Ð½Ð° Ñимвол, Ñкий не визначено у модулі\n"
+
+#: elf32-frv.c:2981
+msgid "%H: R_FRV_GETTLSOFF not applied to a call instruction\n"
+msgstr "%H: R_FRV_GETTLSOFF Ñ” незаÑтоÑовним до команди виклику (call)\n"
+
+#: elf32-frv.c:3022
+msgid "%H: R_FRV_GOTTLSDESC12 not applied to an lddi instruction\n"
+msgstr "%H: R_FRV_GOTTLSDESC12 Ñ” незаÑтоÑовним до команди lddi\n"
+
+#: elf32-frv.c:3093
+msgid "%H: R_FRV_GOTTLSDESCHI not applied to a sethi instruction\n"
+msgstr "%H: R_FRV_GOTTLSDESCHI Ñ” незаÑтоÑовним до команди sethi\n"
+
+#: elf32-frv.c:3130
+msgid "%H: R_FRV_GOTTLSDESCLO not applied to a setlo or setlos instruction\n"
+msgstr "%H: R_FRV_GOTTLSDESCLO Ñ” незаÑтоÑовним до команди setlo або setlos\n"
+
+#: elf32-frv.c:3177
+msgid "%H: R_FRV_TLSDESC_RELAX not applied to an ldd instruction\n"
+msgstr "%H: R_FRV_TLSDESC_RELAX Ñ” незаÑтоÑовним до команди ldd\n"
+
+#: elf32-frv.c:3261
+msgid "%H: R_FRV_GETTLSOFF_RELAX not applied to a calll instruction\n"
+msgstr "%H: R_FRV_GETTLSOFF_RELAX Ñ” незаÑтоÑовним до команди calll\n"
+
+#: elf32-frv.c:3315
+msgid "%H: R_FRV_GOTTLSOFF12 not applied to an ldi instruction\n"
+msgstr "%H: R_FRV_GOTTLSOFF12 Ñ” незаÑтоÑовним до команди ldi\n"
+
+#: elf32-frv.c:3345
+msgid "%H: R_FRV_GOTTLSOFFHI not applied to a sethi instruction\n"
+msgstr "%H: R_FRV_GOTTLSOFFHI Ñ” незаÑтоÑовним до команди sethi\n"
+
+#: elf32-frv.c:3374
+msgid "%H: R_FRV_GOTTLSOFFLO not applied to a setlo or setlos instruction\n"
+msgstr "%H: R_FRV_GOTTLSOFFLO Ñ” незаÑтоÑовним до команди setlo або setlos\n"
+
+#: elf32-frv.c:3404
+msgid "%H: R_FRV_TLSOFF_RELAX not applied to an ld instruction\n"
+msgstr "%H: R_FRV_TLSOFF_RELAX Ñ” незаÑтоÑовним до команди ld\n"
+
+#: elf32-frv.c:3449
+msgid "%H: R_FRV_TLSMOFFHI not applied to a sethi instruction\n"
+msgstr "%H: R_FRV_TLSMOFFHI Ñ” незаÑтоÑовним до команди sethi\n"
+
+#: elf32-frv.c:3476
+msgid "R_FRV_TLSMOFFLO not applied to a setlo or setlos instruction\n"
+msgstr "R_FRV_TLSMOFFLO Ñ” незаÑтоÑовним до команди setlo або setlos\n"
+
+#: elf32-frv.c:3597
+msgid "%H: R_FRV_FUNCDESC references dynamic symbol with nonzero addend\n"
+msgstr "%H: R_FRV_FUNCDESC поÑилаєтьÑÑ Ð½Ð° динамічний Ñимвол з ненульовим доданком\n"
+
+#: elf32-frv.c:3638 elf32-frv.c:3760
+msgid "%H: cannot emit fixups in read-only section\n"
+msgstr "%H: не можна викориÑтовувати адреÑну прив’Ñзку у розділі, придатному лише Ð´Ð»Ñ Ñ‡Ð¸Ñ‚Ð°Ð½Ð½Ñ\n"
+
+#: elf32-frv.c:3669 elf32-frv.c:3803
+msgid "%H: cannot emit dynamic relocations in read-only section\n"
+msgstr "%H: не можна викориÑтовувати динамічні переÑÑƒÐ²Ð°Ð½Ð½Ñ Ñƒ розділі, призначеному лише Ð´Ð»Ñ Ñ‡Ð¸Ñ‚Ð°Ð½Ð½Ñ\n"
+
+#: elf32-frv.c:3718
+msgid "%H: R_FRV_FUNCDESC_VALUE references dynamic symbol with nonzero addend\n"
+msgstr "%H: R_FRV_FUNCDESC_VALUE поÑилаєтьÑÑ Ð½Ð° динамічний Ñимвол з ненульовим доданком\n"
+
+#: elf32-frv.c:3974
+msgid "%H: reloc against `%s' references a different segment\n"
+msgstr "%H: переÑÑƒÐ²Ð°Ð½Ð½Ñ Ñ‰Ð¾Ð´Ð¾ «%s» поÑилаєтьÑÑ Ð½Ð° інший Ñегмент\n"
+
+#: elf32-frv.c:4124
+msgid "%H: reloc against `%s': %s\n"
+msgstr "%H: переÑÑƒÐ²Ð°Ð½Ð½Ñ Ñ‰Ð¾Ð´Ð¾ «%s»: %s\n"
+
+#: elf32-frv.c:6400
+msgid "%B: unsupported relocation type %i\n"
+msgstr "%B: непідтримуваний тип переÑÑƒÐ²Ð°Ð½Ð½Ñ %i\n"
+
+#: elf32-frv.c:6722
+#, c-format
+msgid "%s: compiled with %s and linked with modules that use non-pic relocations"
+msgstr "%s: зібрано з %s Ñ– Ñкомпоновано з модулÑми, у Ñких викориÑтовуютьÑÑ Ð¿ÐµÑ€ÐµÑÑƒÐ²Ð°Ð½Ð½Ñ Ð½Ðµ-pic"
+
+#: elf32-frv.c:6775 elf32-iq2000.c:845 elf32-m32c.c:807
+#, c-format
+msgid "%s: compiled with %s and linked with modules compiled with %s"
+msgstr "%s: зібрано з %s Ñ– Ñкомпоновано з модулÑми, зібраними з %s"
+
+#: elf32-frv.c:6787
+#, c-format
+msgid "%s: uses different unknown e_flags (0x%lx) fields than previous modules (0x%lx)"
+msgstr "%s: викориÑтовуютьÑÑ Ñ–Ð½ÑˆÑ– невідомі Ð¿Ð¾Ð»Ñ e_flags (0x%lx) ніж у попередніх модулÑÑ… (0x%lx)"
+
+#: elf32-frv.c:6837 elf32-iq2000.c:882 elf32-m32c.c:843 elf32-mt.c:576
+#: elf32-rx.c:3001
+#, c-format
+msgid "private flags = 0x%lx:"
+msgstr "закриті прапорці = 0x%lx:"
+
+#: elf32-gen.c:69 elf64-gen.c:69
+msgid "%B: Relocations in generic ELF (EM: %d)"
+msgstr "%B: переÑÑƒÐ²Ð°Ð½Ð½Ñ Ñƒ типовому ELF (EM: %d)"
+
+#: elf32-hppa.c:850 elf32-hppa.c:3598
+msgid "%B(%A+0x%lx): cannot reach %s, recompile with -ffunction-sections"
+msgstr "%B(%A+0x%lx): не вдалоÑÑ Ð´Ð¾ÑÑгти %s, повторно зберіть з -ffunction-sections"
+
+#: elf32-hppa.c:1284
+msgid "%B: relocation %s can not be used when making a shared object; recompile with -fPIC"
+msgstr "%B: переÑÑƒÐ²Ð°Ð½Ð½Ñ %s не можна викориÑтовувати під Ñ‡Ð°Ñ ÑÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ð¾Ð±â€™Ñ”ÐºÑ‚Ð° Ñпільного викориÑтаннÑ; повторно зберіть з -fPIC"
+
+#: elf32-hppa.c:2791
+msgid "%B: duplicate export stub %s"
+msgstr "%B: Ð´ÑƒÐ±Ð»ÑŽÐ²Ð°Ð½Ð½Ñ ÑˆÐ°Ð±Ð»Ð¾Ð½Ð° екÑÐ¿Ð¾Ñ€Ñ‚ÑƒÐ²Ð°Ð½Ð½Ñ %s"
+
+#: elf32-hppa.c:3437
+msgid "%B(%A+0x%lx): %s fixup for insn 0x%x is not supported in a non-shared link"
+msgstr "%B(%A+0x%lx): підтримки адреÑної прив’Ñзки %s Ð´Ð»Ñ Ñ–Ð½Ñтрукції 0x%x не передбачено у поÑиланні неÑпільного викориÑтаннÑ"
+
+#: elf32-hppa.c:4284
+msgid "%B(%A+0x%lx): cannot handle %s for %s"
+msgstr "%B(%A+0x%lx): не вдалоÑÑ Ð¾Ð±Ñ€Ð¾Ð±Ð¸Ñ‚Ð¸ %s Ð´Ð»Ñ %s"
+
+#: elf32-hppa.c:4603
+msgid ".got section not immediately after .plt section"
+msgstr "Розділ .got не перебуває одразу за розділом .plt"
+
+#. Unknown relocation.
+#: elf32-i386.c:373 elf32-m68k.c:384 elf32-ppc.c:1676 elf32-s390.c:379
+#: elf32-tic6x.c:2684 elf64-ppc.c:2300 elf64-s390.c:403 elf64-x86-64.c:265
+msgid "%B: invalid relocation type %d"
+msgstr "%B: некоректний тип переÑÑƒÐ²Ð°Ð½Ð½Ñ %d"
+
+#: elf32-i386.c:1404 elf64-x86-64.c:1308
+msgid "%B: TLS transition from %s to %s against `%s' at 0x%lx in section `%A' failed"
+msgstr "%B: перенеÑÐµÐ½Ð½Ñ TLS з %s до %s щодо «%s» у 0x%lx у розділі «%A» зазнало невдачі"
+
+#: elf32-i386.c:1549 elf32-i386.c:3244 elf64-x86-64.c:1487 elf64-x86-64.c:3125
+#: elfxx-sparc.c:3083
+msgid "%B: relocation %s against STT_GNU_IFUNC symbol `%s' isn't handled by %s"
+msgstr "%B: переÑÑƒÐ²Ð°Ð½Ð½Ñ %s щодо Ñимволу STT_GNU_IFUNC «%s» не оброблÑєтьÑÑ %s"
+
+#: elf32-i386.c:1711 elf32-s390.c:1182 elf32-sh.c:6362 elf32-tilepro.c:1434
+#: elf32-xtensa.c:1182 elf64-s390.c:1151 elfxx-sparc.c:1548
+#: elfxx-tilegx.c:1701
+msgid "%B: `%s' accessed both as normal and thread local symbol"
+msgstr "%B: доÑтуп до «%s» виконуєтьÑÑ Ñк до звичайного Ñимволу, так Ñ– до локального Ð´Ð»Ñ Ð¿Ð¾Ñ‚Ð¾ÐºÑƒ Ð²Ð¸ÐºÐ¾Ð½Ð°Ð½Ð½Ñ Ñимволу"
+
+#: elf32-i386.c:2539 elf64-x86-64.c:2506
+msgid "%P: %B: warning: relocation against `%s' in readonly section `%A'.\n"
+msgstr "%P: %B: попередженнÑ: переÑÑƒÐ²Ð°Ð½Ð½Ñ Ñ‰Ð¾Ð´Ð¾ «%s» у придатному лише Ð´Ð»Ñ Ñ‡Ð¸Ñ‚Ð°Ð½Ð½Ñ Ñ€Ð¾Ð·Ð´Ñ–Ð»Ñ– «%A».\n"
+
+#: elf32-i386.c:2629 elf64-x86-64.c:2593
+msgid "%P: %B: warning: relocation in readonly section `%A'.\n"
+msgstr "%P: %B: попередженнÑ: переÑÑƒÐ²Ð°Ð½Ð½Ñ Ñƒ розділі, придатному лише Ð´Ð»Ñ Ñ‡Ð¸Ñ‚Ð°Ð½Ð½Ñ Â«%A».\n"
+
+#: elf32-i386.c:3086 elf32-tilepro.c:2557 elfxx-tilegx.c:2871
+msgid "%B: unrecognized relocation (0x%x) in section `%A'"
+msgstr "%B: нерозпізнане переÑÑƒÐ²Ð°Ð½Ð½Ñ (0x%x) у розділі «%A»"
+
+#: elf32-i386.c:3494 elf64-x86-64.c:3513
+msgid "hidden symbol"
+msgstr "прихований Ñимвол"
+
+#: elf32-i386.c:3497 elf64-x86-64.c:3516
+msgid "internal symbol"
+msgstr "внутрішній Ñимвол"
+
+#: elf32-i386.c:3500 elf64-x86-64.c:3519
+msgid "protected symbol"
+msgstr "захищений Ñимвол"
+
+#: elf32-i386.c:3503 elf64-x86-64.c:3522
+msgid "symbol"
+msgstr "Ñимвол"
+
+#: elf32-i386.c:3508
+msgid "%B: relocation R_386_GOTOFF against undefined %s `%s' can not be used when making a shared object"
+msgstr "B: переÑÑƒÐ²Ð°Ð½Ð½Ñ R_386_GOTOFF щодо невизначеного %s, «%s», не можна викориÑтовувати під Ñ‡Ð°Ñ ÑÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ð¾Ð±â€™Ñ”ÐºÑ‚Ð° Ñпільного викориÑтаннÑ"
+
+#: elf32-i386.c:3518
+msgid "%B: relocation R_386_GOTOFF against protected function `%s' can not be used when making a shared object"
+msgstr "%B: не можна викориÑтовувати R_386_GOTOFF переÑÑƒÐ²Ð°Ð½Ð½Ñ Ñ‰Ð¾Ð´Ð¾ захищеної функції «%s» під Ñ‡Ð°Ñ ÑÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ð¾Ð±â€™Ñ”ÐºÑ‚Ð° Ñпільного викориÑтаннÑ"
+
+#: elf32-i386.c:4839 elf32-tilepro.c:3467 elf64-x86-64.c:4609
+#: elfxx-tilegx.c:3847
+#, c-format
+msgid "discarded output section: `%A'"
+msgstr "відкинуто розділ Ð²Ð¸Ð²ÐµÐ´ÐµÐ½Ð½Ñ Ð´Ð°Ð½Ð¸Ñ…: «%A»"
+
+#: elf32-ip2k.c:857 elf32-ip2k.c:863 elf32-ip2k.c:930 elf32-ip2k.c:936
+msgid "ip2k relaxer: switch table without complete matching relocation information."
+msgstr "Оптимізатор розміру ip2k: Ñ‚Ð°Ð±Ð»Ð¸Ñ†Ñ Ð¿ÐµÑ€ÐµÐ¼Ð¸ÐºÐ°Ð½ÑŒ без повних даних щодо відповідноÑÑ‚Ñ– переÑувань."
+
+#: elf32-ip2k.c:880 elf32-ip2k.c:963
+msgid "ip2k relaxer: switch table header corrupt."
+msgstr "Оптимізатор розміру ip2k: пошкоджено заголовок таблиці перемикань"
+
+#: elf32-ip2k.c:1292
+#, c-format
+msgid "ip2k linker: missing page instruction at 0x%08lx (dest = 0x%08lx)."
+msgstr "компонувальник ip2k: не виÑтачає інÑтрукції щодо Ñторінки у 0x%08lx (Ð¿Ñ€Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ = 0x%08lx)."
+
+#: elf32-ip2k.c:1308
+#, c-format
+msgid "ip2k linker: redundant page instruction at 0x%08lx (dest = 0x%08lx)."
+msgstr "компонувальник ip2k: зайва інÑÑ‚Ñ€ÑƒÐºÑ†Ñ–Ñ Ñ‰Ð¾Ð´Ð¾ Ñторінки у 0x%08lx (Ð¿Ñ€Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ = 0x%08lx)."
+
+#: elf32-iq2000.c:858 elf32-m32c.c:819
+#, c-format
+msgid "%s: uses different e_flags (0x%lx) fields than previous modules (0x%lx)"
+msgstr "%s: викориÑтовуютьÑÑ Ñ–Ð½ÑˆÑ– Ð¿Ð¾Ð»Ñ e_flags (0x%lx) ніж у попередніх модулÑÑ… (0x%lx)"
+
+#: elf32-lm32.c:706
+msgid "global pointer relative relocation when _gp not defined"
+msgstr "відноÑне перенеÑÐµÐ½Ð½Ñ Ð·Ð°Ð³Ð°Ð»ÑŒÐ½Ð¾Ð³Ð¾ вказівника без Ð²Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ _gp"
+
+#: elf32-lm32.c:761
+msgid "global pointer relative address out of range"
+msgstr "відноÑна адреÑа загального вказівника лежить за межами дозволеного діапазону"
+
+#: elf32-lm32.c:1057
+msgid "internal error: addend should be zero for R_LM32_16_GOT"
+msgstr "Ð²Ð½ÑƒÑ‚Ñ€Ñ–ÑˆÐ½Ñ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ°: доданок має бути нульовим Ð´Ð»Ñ R_LM32_16_GOT"
+
+#: elf32-m32r.c:1453
+msgid "SDA relocation when _SDA_BASE_ not defined"
+msgstr "перенеÑÐµÐ½Ð½Ñ SDA без Ð²Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ _SDA_BASE_"
+
+#: elf32-m32r.c:3043
+msgid "%B: The target (%s) of an %s relocation is in the wrong section (%A)"
+msgstr ""
+"%B: Ð¿Ñ€Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ (%s) переÑÑƒÐ²Ð°Ð½Ð½Ñ %s перебуває у помилковому розділі (%A)\n"
+")"
+
+#: elf32-m32r.c:3571
+msgid "%B: Instruction set mismatch with previous modules"
+msgstr "%B: невідповідніÑÑ‚ÑŒ набору команду цього Ð¼Ð¾Ð´ÑƒÐ»Ñ Ð½Ð°Ð±Ð¾Ñ€Ð°Ð¼ команд попередніх модулів"
+
+#: elf32-m32r.c:3592
+#, c-format
+msgid "private flags = %lx"
+msgstr "закриті прапорці = %lx"
+
+#: elf32-m32r.c:3597
+#, c-format
+msgid ": m32r instructions"
+msgstr ": команди m32r"
+
+#: elf32-m32r.c:3598
+#, c-format
+msgid ": m32rx instructions"
+msgstr ": команди m32rx"
+
+#: elf32-m32r.c:3599
+#, c-format
+msgid ": m32r2 instructions"
+msgstr ": команди m32r2"
+
+#: elf32-m68hc1x.c:1050
+#, c-format
+msgid "Reference to the far symbol `%s' using a wrong relocation may result in incorrect execution"
+msgstr "ПоÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð½Ð° віддалений Ñимвол «%s», що викориÑтовує помилкове переÑуваннÑ, може призвеÑти до помилок у виконанні."
+
+#: elf32-m68hc1x.c:1073
+#, c-format
+msgid "banked address [%lx:%04lx] (%lx) is not in the same bank as current banked address [%lx:%04lx] (%lx)"
+msgstr "занеÑена до банку адреÑа [%lx:%04lx] (%lx) не перебуває у одному банку з поточною адреÑою, занеÑеною до банку, [%lx:%04lx] (%lx)"
+
+#: elf32-m68hc1x.c:1092
+#, c-format
+msgid "reference to a banked address [%lx:%04lx] in the normal address space at %04lx"
+msgstr "поÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð½Ð° занеÑену до банку адреÑу [%lx:%04lx] у звичайному проÑторі адреÑ, %04lx"
+
+#: elf32-m68hc1x.c:1225
+msgid "%B: linking files compiled for 16-bit integers (-mshort) and others for 32-bit integers"
+msgstr "%B: компоновані файли зібрано Ð´Ð»Ñ 16-бітових цілих (-mshort), а решту файлів — Ð´Ð»Ñ 32-бітових цілих чиÑел"
+
+#: elf32-m68hc1x.c:1232
+msgid "%B: linking files compiled for 32-bit double (-fshort-double) and others for 64-bit double"
+msgstr "%B: компоновані файли зібрано Ð´Ð»Ñ 32-бітових дійÑних чиÑел з подвійною точніÑÑ‚ÑŽ (-fshort-double), а інші — Ð´Ð»Ñ 64-бітових дійÑних чиÑел з подвійною точніÑÑ‚ÑŽ."
+
+#: elf32-m68hc1x.c:1241
+msgid "%B: linking files compiled for HCS12 with others compiled for HC12"
+msgstr "%B: компоновані файли зібрано Ð´Ð»Ñ HCS12, інші ж — Ð´Ð»Ñ HC12"
+
+#: elf32-m68hc1x.c:1257 elf32-ppc.c:4227 elf64-sparc.c:706 elfxx-mips.c:13965
+msgid "%B: uses different e_flags (0x%lx) fields than previous modules (0x%lx)"
+msgstr "%B: викориÑтовуютьÑÑ Ñ–Ð½ÑˆÑ– Ð¿Ð¾Ð»Ñ e_flags (0x%lx) ніж у попередніх модулÑÑ… (0x%lx)"
+
+#: elf32-m68hc1x.c:1285
+#, c-format
+msgid "[abi=32-bit int, "
+msgstr "[abi=32-бітове ціле, "
+
+#: elf32-m68hc1x.c:1287
+#, c-format
+msgid "[abi=16-bit int, "
+msgstr "[abi=16-бітове ціле, "
+
+#: elf32-m68hc1x.c:1290
+#, c-format
+msgid "64-bit double, "
+msgstr "64-бітове double, "
+
+#: elf32-m68hc1x.c:1292
+#, c-format
+msgid "32-bit double, "
+msgstr "32-бітове double, "
+
+#: elf32-m68hc1x.c:1295
+#, c-format
+msgid "cpu=HC11]"
+msgstr "процеÑор=HC11]"
+
+#: elf32-m68hc1x.c:1297
+#, c-format
+msgid "cpu=HCS12]"
+msgstr "процеÑор=HCS12]"
+
+#: elf32-m68hc1x.c:1299
+#, c-format
+msgid "cpu=HC12]"
+msgstr "процеÑор=HC12]"
+
+#: elf32-m68hc1x.c:1302
+#, c-format
+msgid " [memory=bank-model]"
+msgstr " [пам’ÑÑ‚ÑŒ=модель з банками]"
+
+#: elf32-m68hc1x.c:1304
+#, c-format
+msgid " [memory=flat]"
+msgstr " [пам’ÑÑ‚ÑŒ=плоÑка модель]"
+
+#: elf32-m68k.c:1251 elf32-m68k.c:1252 vms-alpha.c:7314 vms-alpha.c:7329
+msgid "unknown"
+msgstr "невідомо"
+
+#: elf32-m68k.c:1715
+msgid "%B: GOT overflow: Number of relocations with 8-bit offset > %d"
+msgstr "%B: Ð¿ÐµÑ€ÐµÐ¿Ð¾Ð²Ð½ÐµÐ½Ð½Ñ GOT: кількіÑÑ‚ÑŒ переÑувань з 8-бітовим відÑтупом > %d"
+
+#: elf32-m68k.c:1721
+msgid "%B: GOT overflow: Number of relocations with 8- or 16-bit offset > %d"
+msgstr "%B: Ð¿ÐµÑ€ÐµÐ¿Ð¾Ð²Ð½ÐµÐ½Ð½Ñ GOT: кількіÑÑ‚ÑŒ переÑувань з 8- або 16-бітовим відÑтупом > %d"
+
+#: elf32-m68k.c:3957
+msgid "%B(%A+0x%lx): R_68K_TLS_LE32 relocation not permitted in shared object"
+msgstr "%B(%A+0x%lx): переÑÑƒÐ²Ð°Ð½Ð½Ñ R_68K_TLS_LE32 у об’єкті Ñпільного викориÑÑ‚Ð°Ð½Ð½Ñ Ð·Ð°Ð±Ð¾Ñ€Ð¾Ð½ÐµÐ½Ð¾"
+
+#: elf32-mcore.c:99 elf32-mcore.c:442
+msgid "%B: Relocation %s (%d) is not currently supported.\n"
+msgstr "%B: підтримки переÑÑƒÐ²Ð°Ð½Ð½Ñ %s (%d) у поточній верÑÑ–Ñ— не передбачено.\n"
+
+#: elf32-mcore.c:428
+msgid "%B: Unknown relocation type %d\n"
+msgstr "%B: невідомий тип переÑÑƒÐ²Ð°Ð½Ð½Ñ %d\n"
+
+#. Pacify gcc -Wall.
+#: elf32-mep.c:157
+#, c-format
+msgid "mep: no reloc for code %d"
+msgstr "mep: немає переÑÑƒÐ²Ð°Ð½Ð½Ñ Ð´Ð»Ñ ÐºÐ¾Ð´Ñƒ %d"
+
+#: elf32-mep.c:163
+#, c-format
+msgid "MeP: howto %d has type %d"
+msgstr "MeP: howto %d належить до типу %d"
+
+#: elf32-mep.c:648
+msgid "%B and %B are for different cores"
+msgstr "%B Ñ– %B призначено Ð´Ð»Ñ Ñ€Ñ–Ð·Ð½Ð¸Ñ… Ñдер"
+
+#: elf32-mep.c:665
+msgid "%B and %B are for different configurations"
+msgstr "%B Ñ– %B призначено Ð´Ð»Ñ Ñ€Ñ–Ð·Ð½Ð¸Ñ… конфігурацій"
+
+#: elf32-mep.c:702
+#, c-format
+msgid "private flags = 0x%lx"
+msgstr "закриті прапорці = 0x%lx"
+
+#: elf32-microblaze.c:742
+#, c-format
+msgid "%s: unknown relocation type %d"
+msgstr "%s: невідомий тип переÑÑƒÐ²Ð°Ð½Ð½Ñ %d"
+
+#: elf32-microblaze.c:867 elf32-microblaze.c:912
+#, c-format
+msgid "%s: The target (%s) of an %s relocation is in the wrong section (%s)"
+msgstr ""
+"%s: Ð¿Ñ€Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ (%s) переÑÑƒÐ²Ð°Ð½Ð½Ñ %s перебуває у помилковому розділі (%s)\n"
+")"
+
+#: elf32-microblaze.c:1155 elf32-tilepro.c:2891 elfxx-sparc.c:3457
+#: elfxx-tilegx.c:3230
+msgid "%B: probably compiled without -fPIC?"
+msgstr "%B: ймовірно зібрано без -fPIC?"
+
+#: elf32-microblaze.c:2074
+msgid "%B: bad relocation section name `%s'"
+msgstr "%B: помилкова назва розділу Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÑÑƒÐ²Ð°Ð½Ð½Ñ Â«%s»"
+
+#: elf32-mips.c:1549 elf64-mips.c:2683 elfn32-mips.c:2487
+msgid "literal relocation occurs for an external symbol"
+msgstr "відбуваєтьÑÑ Ð±ÑƒÐºÐ²Ð°Ð»ÑŒÐ½Ðµ переÑÑƒÐ²Ð°Ð½Ð½Ñ Ð´Ð»Ñ Ð·Ð¾Ð²Ð½Ñ–ÑˆÐ½ÑŒÐ¾Ð³Ð¾ Ñимволу"
+
+#: elf32-mips.c:1596 elf32-score.c:570 elf32-score7.c:469 elf64-mips.c:2726
+#: elfn32-mips.c:2528
+msgid "32bits gp relative relocation occurs for an external symbol"
+msgstr "відбуваєтьÑÑ 32-бітове відноÑне gp-переÑÑƒÐ²Ð°Ð½Ð½Ñ Ð´Ð»Ñ Ð·Ð¾Ð²Ð½Ñ–ÑˆÐ½ÑŒÐ¾Ð³Ð¾ Ñимволу"
+
+#: elf32-ppc.c:1741
+#, c-format
+msgid "generic linker can't handle %s"
+msgstr "типовий компонувальник не може оброблÑти %s"
+
+#: elf32-ppc.c:2184
+msgid "corrupt %s section in %B"
+msgstr "пошкоджений розділ %s у %B"
+
+#: elf32-ppc.c:2203
+msgid "unable to read in %s section from %B"
+msgstr "Ñ‡Ð¸Ñ‚Ð°Ð½Ð½Ñ Ñƒ розділі %s неможливе з %B"
+
+#: elf32-ppc.c:2244
+msgid "warning: unable to set size of %s section in %B"
+msgstr "попередженнÑ: не вдалоÑÑ Ð²Ñтановити Ð´Ð»Ñ Ñ€Ð¾Ð·Ð¼Ñ–Ñ€Ñƒ розділу %s Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ %B"
+
+#: elf32-ppc.c:2294
+msgid "failed to allocate space for new APUinfo section."
+msgstr "не вдалоÑÑ Ñ€Ð¾Ð·Ð¼Ñ–Ñтити новий розділ APUinfo."
+
+#: elf32-ppc.c:2313
+msgid "failed to compute new APUinfo section."
+msgstr "не вдалоÑÑ Ð¾Ð±Ñ‡Ð¸Ñлити новий розділ APUinfo."
+
+#: elf32-ppc.c:2316
+msgid "failed to install new APUinfo section."
+msgstr "не вдалоÑÑ Ð²Ñтановити новий розділ APUinfo."
+
+#: elf32-ppc.c:3356
+msgid "%B: relocation %s cannot be used when making a shared object"
+msgstr "%B: переÑÑƒÐ²Ð°Ð½Ð½Ñ %s не можна викориÑтовувати під Ñ‡Ð°Ñ ÑÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ð¾Ð±â€™Ñ”ÐºÑ‚Ð° Ñпільного викориÑтаннÑ"
+
+#. It does not make sense to have a procedure linkage
+#. table entry for a local symbol.
+#: elf32-ppc.c:3700
+msgid "%P: %H: %s reloc against local symbol\n"
+msgstr "%P: %H: %s переÑÑƒÐ²Ð°Ð½Ð½Ñ Ð·Ð° локальним Ñимволом\n"
+
+#: elf32-ppc.c:4039 elf32-ppc.c:4054 elfxx-mips.c:13651 elfxx-mips.c:13677
+#: elfxx-mips.c:13699 elfxx-mips.c:13725
+msgid "Warning: %B uses hard float, %B uses soft float"
+msgstr "ПопередженнÑ: у %B викориÑтовуєтьÑÑ Ð°Ð¿Ð°Ñ€Ð°Ñ‚Ð½Ð° підтримка дійÑних чиÑел, а у %B — програмна"
+
+#: elf32-ppc.c:4042 elf32-ppc.c:4046
+msgid "Warning: %B uses double-precision hard float, %B uses single-precision hard float"
+msgstr "ПопередженнÑ: у %B викориÑтовуєтьÑÑ Ð°Ð¿Ð°Ñ€Ð°Ñ‚Ð½Ð° підтримка дійÑних чиÑел з подвійною точніÑÑ‚ÑŽ, а у %B — апаратна підтримка Ð´Ð»Ñ Ð´Ñ–Ð¹Ñних чиÑел з одинарною точніÑÑ‚ÑŽ"
+
+#: elf32-ppc.c:4050
+msgid "Warning: %B uses soft float, %B uses single-precision hard float"
+msgstr "ПопередженнÑ: у %B викориÑтовуєтьÑÑ Ð¿Ñ€Ð¾Ð³Ñ€Ð°Ð¼Ð½Ð° підтримка дійÑних чиÑел, а у %B — апаратна підтримка Ð´Ð»Ñ Ð´Ñ–Ð¹Ñних чиÑел з одинарною точніÑÑ‚ÑŽ"
+
+#: elf32-ppc.c:4057 elf32-ppc.c:4061 elfxx-mips.c:13631 elfxx-mips.c:13635
+msgid "Warning: %B uses unknown floating point ABI %d"
+msgstr "ПопередженнÑ: %B викориÑтовує невідомий ABI роботи з чиÑлами з рухомою крапкою, %d"
+
+#: elf32-ppc.c:4103 elf32-ppc.c:4107
+msgid "Warning: %B uses unknown vector ABI %d"
+msgstr "ПопередженнÑ: %B викориÑтовує невідомий векторний ABI %d"
+
+#: elf32-ppc.c:4111
+msgid "Warning: %B uses vector ABI \"%s\", %B uses \"%s\""
+msgstr "ПопередженнÑ: у %B викориÑтовуєтьÑÑ Ð²ÐµÐºÑ‚Ð¾Ñ€Ð½Ð¸Ð¹ ABI «%s», а у %B — «%s»"
+
+#: elf32-ppc.c:4128 elf32-ppc.c:4131
+msgid "Warning: %B uses r3/r4 for small structure returns, %B uses memory"
+msgstr "ПопередженнÑ: у %B r3/r4 викориÑтовуєтьÑÑ Ð´Ð»Ñ Ð¿Ð¾Ð²ÐµÑ€Ð½ÐµÐ½Ð½Ñ Ð¼Ð°Ð»Ð¸Ñ… Ñтруктур, а у %B Ð´Ð»Ñ Ñ†ÑŒÐ¾Ð³Ð¾ викориÑтовуєтьÑÑ Ð¿Ð°Ð¼â€™ÑÑ‚ÑŒ"
+
+#: elf32-ppc.c:4134 elf32-ppc.c:4138
+msgid "Warning: %B uses unknown small structure return convention %d"
+msgstr "ПопередженнÑ: у %B викориÑтано невідому угоду, %d, щодо Ð¿Ð¾Ð²ÐµÑ€Ð½ÐµÐ½Ð½Ñ Ð¼Ð°Ð»ÐµÐ½ÑŒÐºÐ¸Ñ… Ñтруктур"
+
+#: elf32-ppc.c:4192
+msgid "%B: compiled with -mrelocatable and linked with modules compiled normally"
+msgstr "%B: зібрано з -mrelocatable Ñ– Ñкомпоновано з модулÑми, зібраними у звичайному режимі"
+
+#: elf32-ppc.c:4200
+msgid "%B: compiled normally and linked with modules compiled with -mrelocatable"
+msgstr "%B: зібрано у звичайному режимі Ñ– Ñкомпоновано з модулÑми, зібраними з -mrelocatable"
+
+#: elf32-ppc.c:4309
+msgid "%P: bss-plt forced due to %B\n"
+msgstr "%P: примуÑово викориÑтано bss-plt через %B\n"
+
+#: elf32-ppc.c:4312
+msgid "%P: bss-plt forced by profiling\n"
+msgstr "%P: профілюваннÑм примуÑово визначено bss-plt\n"
+
+#. Uh oh, we didn't find the expected call. We
+#. could just mark this symbol to exclude it
+#. from tls optimization but it's safer to skip
+#. the entire optimization.
+#: elf32-ppc.c:4809 elf64-ppc.c:7858
+msgid "%H arg lost __tls_get_addr, TLS optimization disabled\n"
+msgstr "%H: у аргументів не виÑтачає __tls_get_addr, оптимізацію TLS вимкнено.\n"
+
+#: elf32-ppc.c:5044 elf64-ppc.c:6528
+msgid "%P: dynamic variable `%s' is zero size\n"
+msgstr "%P: динамічна змінна «%s» має нульовий розмір\n"
+
+#: elf32-ppc.c:7263 elf64-ppc.c:12675
+msgid "%P: %B: unknown relocation type %d for symbol %s\n"
+msgstr "%P: %B: невідомий тип переÑÑƒÐ²Ð°Ð½Ð½Ñ %d Ð´Ð»Ñ Ñимволу %s\n"
+
+#: elf32-ppc.c:7524
+msgid "%P: %H: non-zero addend on %s reloc against `%s'\n"
+msgstr "%P: %H: ненульовий додаток до переÑÑƒÐ²Ð°Ð½Ð½Ñ %s щодо «%s»\n"
+
+#: elf32-ppc.c:7720 elf64-ppc.c:13181
+msgid "%P: %H: relocation %s for indirect function %s unsupported\n"
+msgstr "%P: %H: підтримки переÑÑƒÐ²Ð°Ð½Ð½Ñ %s опоÑередкованої функції %s не передбачено\n"
+
+#: elf32-ppc.c:7948 elf32-ppc.c:7978 elf32-ppc.c:8025
+msgid "%P: %B: the target (%s) of a %s relocation is in the wrong output section (%s)\n"
+msgstr "%P: %B: Ð¿Ñ€Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ (%s) переÑÑƒÐ²Ð°Ð½Ð½Ñ %s перебуває у помилковому розділі Ð²Ð¸Ð²ÐµÐ´ÐµÐ½Ð½Ñ (%s)\n"
+
+#: elf32-ppc.c:8097
+msgid "%P: %B: relocation %s is not yet supported for symbol %s\n"
+msgstr "%P: %B: підтримки переÑÑƒÐ²Ð°Ð½Ð½Ñ %s Ð´Ð»Ñ Ñимволу %s ще не передбачено\n"
+
+#: elf32-ppc.c:8158 elf64-ppc.c:13467
+msgid "%P: %H: unresolvable %s relocation against symbol `%s'\n"
+msgstr "%P: %H: нерозв’Ñзне переÑÑƒÐ²Ð°Ð½Ð½Ñ %s щодо Ñимволу «%s»\n"
+
+#: elf32-ppc.c:8205 elf64-ppc.c:13512
+msgid "%P: %H: %s reloc against `%s': error %d\n"
+msgstr "%P: %H: переÑÑƒÐ²Ð°Ð½Ð½Ñ %s щодо «%s»: помилка %d\n"
+
+#: elf32-ppc.c:8696
+msgid "%P: %s not defined in linker created %s\n"
+msgstr "%P: %s не визначено у компонувальнику, Ñтвореному %s\n"
+
+#: elf32-rx.c:563
+msgid "%B:%A: Warning: deprecated Red Hat reloc "
+msgstr "%B:%A: попередженнÑ: заÑтарілий формат переÑÑƒÐ²Ð°Ð½Ð½Ñ Red Hat "
+
+#. Check for unsafe relocs in PID mode. These are any relocs where
+#. an absolute address is being computed. There are special cases
+#. for relocs against symbols that are known to be referenced in
+#. crt0.o before the PID base address register has been initialised.
+#: elf32-rx.c:581
+msgid "%B(%A): unsafe PID relocation %s at 0x%08lx (against %s in %s)"
+msgstr "%B(%A): небезпечне переÑÑƒÐ²Ð°Ð½Ð½Ñ PID %s до 0x%08lx (щодо %s у %s)"
+
+#: elf32-rx.c:1157
+msgid "Warning: RX_SYM reloc with an unknown symbol"
+msgstr "ПопередженнÑ: переÑÑƒÐ²Ð°Ð½Ð½Ñ RX_SYM з невідомим Ñимволом"
+
+#: elf32-rx.c:1324
+msgid "%B(%A): error: call to undefined function '%s'"
+msgstr "%B(%A): помилка: виклик невизначеної функції «%s»"
+
+#: elf32-rx.c:1338
+msgid "%B(%A): warning: unaligned access to symbol '%s' in the small data area"
+msgstr "%B(%A): попередженнÑ: невирівнÑний доÑтуп до Ñимволу «%s» у малій облаÑÑ‚Ñ– даних"
+
+#: elf32-rx.c:1342
+msgid "%B(%A): internal error: out of range error"
+msgstr "%B(%A): Ð²Ð½ÑƒÑ‚Ñ€Ñ–ÑˆÐ½Ñ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ°: вихід за межі діапазону"
+
+#: elf32-rx.c:1346
+msgid "%B(%A): internal error: unsupported relocation error"
+msgstr "%B(%A): Ð²Ð½ÑƒÑ‚Ñ€Ñ–ÑˆÐ½Ñ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ°: непідтримувана помилка переÑуваннÑ"
+
+#: elf32-rx.c:1350
+msgid "%B(%A): internal error: dangerous relocation"
+msgstr "%B(%A): Ð²Ð½ÑƒÑ‚Ñ€Ñ–ÑˆÐ½Ñ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ°: небезпечне переÑуваннÑ"
+
+#: elf32-rx.c:1354
+msgid "%B(%A): internal error: unknown error"
+msgstr "%B(%A): Ð²Ð½ÑƒÑ‚Ñ€Ñ–ÑˆÐ½Ñ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ°: невідома помилка"
+
+#: elf32-rx.c:3004
+#, c-format
+msgid " [64-bit doubles]"
+msgstr " [64-бітові double]"
+
+#: elf32-rx.c:3006
+#, c-format
+msgid " [dsp]"
+msgstr " [dsp]"
+
+#: elf32-s390.c:2200 elf64-s390.c:2187
+msgid "%B(%A+0x%lx): invalid instruction for TLS relocation %s"
+msgstr "%B(%A+0x%lx): некоректна інÑÑ‚Ñ€ÑƒÐºÑ†Ñ–Ñ Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÑÑƒÐ²Ð°Ð½Ð½Ñ TLS %s"
+
+#: elf32-score.c:1520 elf32-score7.c:1379 elfxx-mips.c:3435
+msgid "not enough GOT space for local GOT entries"
+msgstr "недоÑтатньо проÑтору GOT Ð´Ð»Ñ Ð»Ð¾ÐºÐ°Ð»ÑŒÐ½Ð¸Ñ… запиÑів GOT"
+
+#: elf32-score.c:2742
+msgid "address not word align"
+msgstr "адреÑу не вирівнÑно за межею Ñлова"
+
+#: elf32-score.c:2827 elf32-score7.c:2631
+#, c-format
+msgid "%s: Malformed reloc detected for section %s"
+msgstr "%s: Ð´Ð»Ñ Ñ€Ð¾Ð·Ð´Ñ–Ð»Ñƒ %s виÑвлено помилку у форматуванні перенеÑеннÑ"
+
+#: elf32-score.c:2878 elf32-score7.c:2682
+msgid "%B: CALL15 reloc at 0x%lx not against global symbol"
+msgstr "%B: переÑÑƒÐ²Ð°Ð½Ð½Ñ CALL15 у 0x%lx не відноÑно загального Ñимволу"
+
+#: elf32-score.c:3997 elf32-score7.c:3803
+#, c-format
+msgid " [pic]"
+msgstr " [pic]"
+
+#: elf32-score.c:4001 elf32-score7.c:3807
+#, c-format
+msgid " [fix dep]"
+msgstr " [фікÑ. розт.]"
+
+#: elf32-score.c:4043 elf32-score7.c:3849
+msgid "%B: warning: linking PIC files with non-PIC files"
+msgstr "%B: попередженнÑ: ÐºÐ¾Ð¼Ð¿Ð¾Ð½ÑƒÐ²Ð°Ð½Ð½Ñ Ñ„Ð°Ð¹Ð»Ñ–Ð² PIC з файлами, Ñкі не Ñ” файлами PIC"
+
+#: elf32-sh-symbian.c:130
+msgid "%B: IMPORT AS directive for %s conceals previous IMPORT AS"
+msgstr "%B: директива IMPORT AS Ð´Ð»Ñ %s приховує попередню директиву IMPORT AS"
+
+#: elf32-sh-symbian.c:383
+msgid "%B: Unrecognised .directive command: %s"
+msgstr "%B: нерозпізнана команда .directive: %s"
+
+#: elf32-sh-symbian.c:504
+msgid "%B: Failed to add renamed symbol %s"
+msgstr "%B: не вдалоÑÑ Ð´Ð¾Ð´Ð°Ñ‚Ð¸ перейменований Ñимвол %s"
+
+#: elf32-sh.c:568
+msgid "%B: 0x%lx: warning: bad R_SH_USES offset"
+msgstr "%B: 0x%lx: попередженнÑ: помилковий відÑтуп R_SH_USES"
+
+#: elf32-sh.c:580
+msgid "%B: 0x%lx: warning: R_SH_USES points to unrecognized insn 0x%x"
+msgstr "%B: 0x%lx: попередженнÑ: R_SH_USES вказує на нерозпізнану інÑтрукцію 0x%x"
+
+#: elf32-sh.c:597
+msgid "%B: 0x%lx: warning: bad R_SH_USES load offset"
+msgstr "%B: 0x%lx: попередженнÑ: помилковий відÑтуп Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ R_SH_USES"
+
+#: elf32-sh.c:612
+msgid "%B: 0x%lx: warning: could not find expected reloc"
+msgstr "%B: 0x%lx: попередженнÑ: не вдалоÑÑ Ð·Ð½Ð°Ð¹Ñ‚Ð¸ очікуване переÑуваннÑ"
+
+#: elf32-sh.c:640
+msgid "%B: 0x%lx: warning: symbol in unexpected section"
+msgstr "%B: 0x%lx: попередженнÑ: Ñимвол у неочікуваному розділі"
+
+#: elf32-sh.c:766
+msgid "%B: 0x%lx: warning: could not find expected COUNT reloc"
+msgstr "%B: 0x%lx: попередженнÑ: не вдалоÑÑ Ð·Ð½Ð°Ð¹Ñ‚Ð¸ очікуване переÑÑƒÐ²Ð°Ð½Ð½Ñ COUNT"
+
+#: elf32-sh.c:775
+msgid "%B: 0x%lx: warning: bad count"
+msgstr "%B: 0x%lx: попередженнÑ: помилковий лічильник"
+
+#: elf32-sh.c:1179 elf32-sh.c:1549
+msgid "%B: 0x%lx: fatal: reloc overflow while relaxing"
+msgstr "%B: 0x%lx: критична помилка: Ð¿ÐµÑ€ÐµÐ¿Ð¾Ð²Ð½ÐµÐ½Ð½Ñ Ð¿ÐµÑ€ÐµÑÑƒÐ²Ð°Ð½Ð½Ñ Ð¿Ñ–Ð´ Ñ‡Ð°Ñ Ð¾Ð¿Ñ‚Ð¸Ð¼Ñ–Ð·Ð°Ñ†Ñ–Ñ— розміру"
+
+#: elf32-sh.c:4048 elf64-sh64.c:1514
+msgid "Unexpected STO_SH5_ISA32 on local symbol is not handled"
+msgstr "Ðеочікувану команду STO_SH5_ISA32 над локальним Ñимволом не оброблено"
+
+#: elf32-sh.c:4299
+msgid "%B: 0x%lx: fatal: unaligned branch target for relax-support relocation"
+msgstr "%B: 0x%lx: критична помилка: невирівнÑне розгалужене Ð¿Ñ€Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÑÑƒÐ²Ð°Ð½Ð½Ñ Ð· підтримкою оптимізації розміру"
+
+#: elf32-sh.c:4332 elf32-sh.c:4347
+msgid "%B: 0x%lx: fatal: unaligned %s relocation 0x%lx"
+msgstr "%B: 0x%lx: критична помилка: невирівнÑне переÑÑƒÐ²Ð°Ð½Ð½Ñ %s, 0x%lx"
+
+#: elf32-sh.c:4361
+msgid "%B: 0x%lx: fatal: R_SH_PSHA relocation %d not in range -32..32"
+msgstr "%B: 0x%lx: критична помилка: переÑÑƒÐ²Ð°Ð½Ð½Ñ R_SH_PSHA %d не у діапазоні -32..32"
+
+#: elf32-sh.c:4375
+msgid "%B: 0x%lx: fatal: R_SH_PSHL relocation %d not in range -32..32"
+msgstr "%B: 0x%lx: критична помилка: переÑÑƒÐ²Ð°Ð½Ð½Ñ R_SH_PSHL %d не у діапазоні -32..32"
+
+#: elf32-sh.c:4519 elf32-sh.c:4989
+msgid "%B(%A+0x%lx): cannot emit fixup to `%s' in read-only section"
+msgstr "%B(%A+0x%lx): не можна викориÑтовувати адреÑну прив’Ñзку до «%s» у розділі, придатному лише Ð´Ð»Ñ Ñ‡Ð¸Ñ‚Ð°Ð½Ð½Ñ"
+
+#: elf32-sh.c:5096
+msgid "%B(%A+0x%lx): %s relocation against external symbol \"%s\""
+msgstr "%B(%A+0x%lx): переÑÑƒÐ²Ð°Ð½Ð½Ñ %s за зовнішнім Ñимволом «%s»"
+
+#: elf32-sh.c:5569
+#, c-format
+msgid "%X%C: relocation to \"%s\" references a different segment\n"
+msgstr "%X%C: переÑÑƒÐ²Ð°Ð½Ð½Ñ Ð·Ð° «%s» поÑилаєтьÑÑ Ð½Ð° інший Ñегмент\n"
+
+#: elf32-sh.c:5575
+#, c-format
+msgid "%C: warning: relocation to \"%s\" references a different segment\n"
+msgstr "%C: попередженнÑ: переÑÑƒÐ²Ð°Ð½Ð½Ñ Ð·Ð° «%s» поÑилаєтьÑÑ Ð½Ð° інший Ñегмент\n"
+
+#: elf32-sh.c:6353 elf32-sh.c:6436
+msgid "%B: `%s' accessed both as normal and FDPIC symbol"
+msgstr "%B: доÑтуп до «%s» виконуєтьÑÑ Ñк до звичайного Ñимволу та Ñимволу FDPIC"
+
+#: elf32-sh.c:6358 elf32-sh.c:6440
+msgid "%B: `%s' accessed both as FDPIC and thread local symbol"
+msgstr "%B: доÑтуп до «%s» виконуєтьÑÑ Ñк до Ñимволу FDPIC, так Ñ– до локального Ð´Ð»Ñ Ð¿Ð¾Ñ‚Ð¾ÐºÑƒ Ð²Ð¸ÐºÐ¾Ð½Ð°Ð½Ð½Ñ Ñимволу"
+
+#: elf32-sh.c:6388
+msgid "%B: Function descriptor relocation with non-zero addend"
+msgstr "%B: переÑÑƒÐ²Ð°Ð½Ð½Ñ Ð´ÐµÑкриптора функції з ненульовим доданком"
+
+#: elf32-sh.c:6624 elf64-alpha.c:4652
+msgid "%B: TLS local exec code cannot be linked into shared objects"
+msgstr "%B: виконуваний код локального TLS не можна компонувати у об’єкти Ñпільного викориÑтаннÑ"
+
+#: elf32-sh64.c:223 elf64-sh64.c:2318
+#, c-format
+msgid "%s: compiled as 32-bit object and %s is 64-bit"
+msgstr "%s: зібрано Ñк 32- бітовий об’єкт, а %s Ñ” 64-бітовим"
+
+#: elf32-sh64.c:226 elf64-sh64.c:2321
+#, c-format
+msgid "%s: compiled as 64-bit object and %s is 32-bit"
+msgstr "%s: зібрано Ñк 64-бітовий об’єкт, а %s Ñ” 32-бітовим"
+
+#: elf32-sh64.c:228 elf64-sh64.c:2323
+#, c-format
+msgid "%s: object size does not match that of target %s"
+msgstr "%s: розмір об’єкта не збігаєтьÑÑ Ð· розміром Ð¿Ñ€Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ %s"
+
+#: elf32-sh64.c:451 elf64-sh64.c:2837
+#, c-format
+msgid "%s: encountered datalabel symbol in input"
+msgstr "%s: виÑвлено Ñимвол мітки даних у вхідних даних"
+
+#: elf32-sh64.c:528
+msgid "PTB mismatch: a SHmedia address (bit 0 == 1)"
+msgstr "ÐевідповідніÑÑ‚ÑŒ PTB: адреÑа SHmedia (біт 0 == 1)"
+
+#: elf32-sh64.c:531
+msgid "PTA mismatch: a SHcompact address (bit 0 == 0)"
+msgstr "ÐевідповідніÑÑ‚ÑŒ PTA: адреÑа SHcompact (біт 0 == 0)"
+
+#: elf32-sh64.c:549
+#, c-format
+msgid "%s: GAS error: unexpected PTB insn with R_SH_PT_16"
+msgstr "%s: помилка GAS: неочікувана інÑÑ‚Ñ€ÑƒÐºÑ†Ñ–Ñ PTB з R_SH_PT_16"
+
+#: elf32-sh64.c:598
+msgid "%B: error: unaligned relocation type %d at %08x reloc %p\n"
+msgstr "%B: помилка: невирівнÑний тип переÑÑƒÐ²Ð°Ð½Ð½Ñ %d у %08x, переÑÑƒÐ²Ð°Ð½Ð½Ñ %p\n"
+
+#: elf32-sh64.c:674
+#, c-format
+msgid "%s: could not write out added .cranges entries"
+msgstr "%s: не вдалоÑÑ Ð²Ð¸ÐºÐ¾Ð½Ð°Ñ‚Ð¸ Ð·Ð°Ð¿Ð¸Ñ Ð´Ð¾Ð´Ð°Ð½Ð¸Ñ… запиÑів .cranges"
+
+#: elf32-sh64.c:734
+#, c-format
+msgid "%s: could not write out sorted .cranges entries"
+msgstr "%s: не вдалоÑÑ Ð²Ð¸ÐºÐ¾Ð½Ð°Ñ‚Ð¸ Ð·Ð°Ð¿Ð¸Ñ Ð²Ð¿Ð¾Ñ€Ñдкованих запиÑів .cranges"
+
+#: elf32-sparc.c:90
+msgid "%B: compiled for a 64 bit system and target is 32 bit"
+msgstr "%B: зібрано Ð´Ð»Ñ 64-бітової ÑиÑтеми, ÑиÑтемою ж Ð¿Ñ€Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ñ” 32-бітова"
+
+#: elf32-sparc.c:103
+msgid "%B: linking little endian files with big endian files"
+msgstr "%B: ÐºÐ¾Ð¼Ð¿Ð¾Ð½ÑƒÐ²Ð°Ð½Ð½Ñ Ñ„Ð°Ð¹Ð»Ñ–Ð² зі зворотним порÑдком байтів з файлами з прÑмим порÑдком байтів"
+
+#: elf32-spu.c:719
+msgid "%X%P: overlay section %A does not start on a cache line.\n"
+msgstr "%X%P: розділ накладки %A не починаєтьÑÑ Ð· Ñ€Ñдка кешуваннÑ.\n"
+
+#: elf32-spu.c:727
+msgid "%X%P: overlay section %A is larger than a cache line.\n"
+msgstr "%X%P: розділ накладки %A Ñ” більшим за Ñ€Ñдок кешуваннÑ.\n"
+
+#: elf32-spu.c:747
+msgid "%X%P: overlay section %A is not in cache area.\n"
+msgstr "%X%P: розділ накладки %A не перебуває у облаÑÑ‚Ñ– кешуваннÑ.\n"
+
+#: elf32-spu.c:787
+msgid "%X%P: overlay sections %A and %A do not start at the same address.\n"
+msgstr "%X%P: розділи, що накладаютьÑÑ, %A Ñ– %A, не починаютьÑÑ Ð·Ð° одною адреÑою.\n"
+
+#: elf32-spu.c:1011
+msgid "warning: call to non-function symbol %s defined in %B"
+msgstr "попередженнÑ: виклик нефункціонального Ñимволу, %s, визначеного у %B"
+
+#: elf32-spu.c:1361
+msgid "%A:0x%v lrlive .brinfo (%u) differs from analysis (%u)\n"
+msgstr "%A:0x%v .brinfo lrlive (%u) відрізнÑєтьÑÑ Ð²Ñ–Ð´ визначеного шлÑхом аналізу (%u)\n"
+
+#: elf32-spu.c:1880
+msgid "%B is not allowed to define %s"
+msgstr "%B не може визначати %s"
+
+#: elf32-spu.c:1888
+#, c-format
+msgid "you are not allowed to define %s in a script"
+msgstr "не можна визначати %s у Ñкрипті"
+
+#: elf32-spu.c:1922
+#, c-format
+msgid "%s in overlay section"
+msgstr "%s у розділі накладки"
+
+#: elf32-spu.c:1951
+msgid "overlay stub relocation overflow"
+msgstr "Ð¿ÐµÑ€ÐµÐ¿Ð¾Ð²Ð½ÐµÐ½Ð½Ñ Ð¿Ñ–Ð´ Ñ‡Ð°Ñ Ð¿ÐµÑ€ÐµÑÑƒÐ²Ð°Ð½Ð½Ñ ÑˆÐ°Ð±Ð»Ð¾Ð½Ð° накладки"
+
+#: elf32-spu.c:1960
+msgid "stubs don't match calculated size"
+msgstr "шаблони не відповідають обчиÑленому розміру"
+
+#: elf32-spu.c:2542
+#, c-format
+msgid "warning: %s overlaps %s\n"
+msgstr "попередженнÑ: %s перекриває %s\n"
+
+#: elf32-spu.c:2558
+#, c-format
+msgid "warning: %s exceeds section size\n"
+msgstr "попередженнÑ: %s перевищує розмір розділу\n"
+
+#: elf32-spu.c:2589
+msgid "%A:0x%v not found in function table\n"
+msgstr "%A:0x%v не знайдено у таблиці функцій\n"
+
+#: elf32-spu.c:2729
+msgid "%B(%A+0x%v): call to non-code section %B(%A), analysis incomplete\n"
+msgstr "%B(%A+0x%v): виклик розділу, Ñкий не міÑтить код, %B(%A), аналіз Ñ” неповним\n"
+
+#: elf32-spu.c:3297
+#, c-format
+msgid "Stack analysis will ignore the call from %s to %s\n"
+msgstr "Під Ñ‡Ð°Ñ Ð°Ð½Ð°Ð»Ñ–Ð·Ñƒ Ñтека буде проігноровано виклик з %s до %s\n"
+
+#: elf32-spu.c:3988
+msgid " %s: 0x%v\n"
+msgstr " %s: 0x%v\n"
+
+#: elf32-spu.c:3989
+msgid "%s: 0x%v 0x%v\n"
+msgstr "%s: 0x%v 0x%v\n"
+
+#: elf32-spu.c:3994
+msgid " calls:\n"
+msgstr " виклики:\n"
+
+#: elf32-spu.c:4002
+#, c-format
+msgid " %s%s %s\n"
+msgstr " %s%s %s\n"
+
+#: elf32-spu.c:4307
+#, c-format
+msgid "%s duplicated in %s\n"
+msgstr "%s повторюєтьÑÑ Ñƒ %s\n"
+
+#: elf32-spu.c:4311
+#, c-format
+msgid "%s duplicated\n"
+msgstr "%s дубльовано\n"
+
+#: elf32-spu.c:4318
+msgid "sorry, no support for duplicate object files in auto-overlay script\n"
+msgstr "вибачте, у Ñкрипті автоматичного Ð½Ð°ÐºÐ»Ð°Ð´Ð°Ð½Ð½Ñ Ð½Ðµ передбачено підтримки Ð´ÑƒÐ±Ð»ÑŽÐ²Ð°Ð½Ð½Ñ Ð¾Ð±â€™Ñ”ÐºÑ‚Ð½Ð¸Ñ… файлів.\n"
+
+#: elf32-spu.c:4359
+msgid "non-overlay size of 0x%v plus maximum overlay size of 0x%v exceeds local store\n"
+msgstr "Ñума розміру 0x%v без оверлею та макÑимального розміру оверлею 0x%v перевищують міÑткіÑÑ‚ÑŒ локального Ñховища даних\n"
+
+#: elf32-spu.c:4514
+msgid "%B:%A%s exceeds overlay size\n"
+msgstr "%B:%A%s перевищує розмір накладки\n"
+
+#: elf32-spu.c:4676
+msgid "Stack size for call graph root nodes.\n"
+msgstr "Розмір Ñтека Ð´Ð»Ñ ÐºÐ¾Ñ€ÐµÐ½ÐµÐ²Ð¸Ñ… вузлів графу викликів.\n"
+
+#: elf32-spu.c:4677
+msgid ""
+"\n"
+"Stack size for functions. Annotations: '*' max stack, 't' tail call\n"
+msgstr ""
+"\n"
+"Розмір Ñтека Ð´Ð»Ñ Ñ„ÑƒÐ½ÐºÑ†Ñ–Ð¹. ПозначеннÑ: «*» макÑимальна Ð¿Ð¾Ð·Ð¸Ñ†Ñ–Ñ Ñƒ Ñтеку, «t» хвоÑтовий виклик\n"
+
+#: elf32-spu.c:4687
+msgid "Maximum stack required is 0x%v\n"
+msgstr "МакÑимальний потрібний розмір Ñтека — 0x%v\n"
+
+#: elf32-spu.c:4778
+msgid "fatal error while creating .fixup"
+msgstr "критична помилка під Ñ‡Ð°Ñ Ñпроби ÑÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ .fixup"
+
+#: elf32-spu.c:5008
+msgid "%B(%s+0x%lx): unresolvable %s relocation against symbol `%s'"
+msgstr "%B(%s+0x%lx): нерозв’Ñзне переÑÑƒÐ²Ð°Ð½Ð½Ñ %s щодо Ñимволу «%s»"
+
+#: elf32-tic6x.c:1602
+msgid "warning: generating a shared library containing non-PIC code"
+msgstr "попередженнÑ: ÑтворюєтьÑÑ Ð±Ñ–Ð±Ð»Ñ–Ð¾Ñ‚ÐµÐºÐ° Ñпільного викориÑтаннÑ, Ñка міÑтить код, неÑуміÑний з PIC"
+
+#: elf32-tic6x.c:1607
+msgid "warning: generating a shared library containing non-PID code"
+msgstr "попередженнÑ: ÑтворюєтьÑÑ Ð±Ñ–Ð±Ð»Ñ–Ð¾Ñ‚ÐµÐºÐ° Ñпільного викориÑтаннÑ, Ñка міÑтить код, неÑуміÑний з PID"
+
+#: elf32-tic6x.c:2541
+msgid "%B: SB-relative relocation but __c6xabi_DSBT_BASE not defined"
+msgstr "%B: переÑÑƒÐ²Ð°Ð½Ð½Ñ Ð²Ñ–Ð´Ð½Ð¾Ñно SB, але __c6xabi_DSBT_BASE не визначено"
+
+#: elf32-tic6x.c:2761
+msgid "dangerous relocation"
+msgstr "небезпечне переÑуваннÑ"
+
+#: elf32-tic6x.c:3733
+msgid "%B: error: unknown mandatory EABI object attribute %d"
+msgstr "%B: помилка: невідомий обов’Ñзковий атрибути об’єкта EABI, %d"
+
+#: elf32-tic6x.c:3741
+msgid "%B: warning: unknown EABI object attribute %d"
+msgstr "%B: попередженнÑ: невідомий атрибут об’єкта EABI, %d"
+
+#: elf32-tic6x.c:3853 elf32-tic6x.c:3861
+msgid "error: %B requires more stack alignment than %B preserves"
+msgstr "помилка: %B потребує більшого Ð²Ð¸Ñ€Ñ–Ð²Ð½ÑŽÐ²Ð°Ð½Ð½Ñ Ñтека, ніж збережено у %B"
+
+#: elf32-tic6x.c:3871 elf32-tic6x.c:3880
+msgid "error: unknown Tag_ABI_array_object_alignment value in %B"
+msgstr "помилка: невідоме Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Tag_ABI_array_object_alignment у %B"
+
+#: elf32-tic6x.c:3889 elf32-tic6x.c:3898
+msgid "error: unknown Tag_ABI_array_object_align_expected value in %B"
+msgstr "помилка: невідоме Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Tag_ABI_array_object_align_expected у %B"
+
+#: elf32-tic6x.c:3906 elf32-tic6x.c:3913
+msgid "error: %B requires more array alignment than %B preserves"
+msgstr "помилка: %B потребує більшого Ð²Ð¸Ñ€Ñ–Ð²Ð½ÑŽÐ²Ð°Ð½Ð½Ñ Ð¼Ð°Ñиву, ніж збережено у %B"
+
+#: elf32-tic6x.c:3935
+msgid "warning: %B and %B differ in wchar_t size"
+msgstr "попередженнÑ: %B Ñ– %B відрізнÑÑŽÑ‚ÑŒÑÑ Ð·Ð° розміром wchar_t"
+
+#: elf32-tic6x.c:3953
+msgid "warning: %B and %B differ in whether code is compiled for DSBT"
+msgstr "попередженнÑ: %B Ñ– %B відрізнÑÑŽÑ‚ÑŒÑÑ Ð·Ð° тим, чи було Ñ—Ñ… зібрано Ð´Ð»Ñ DSBT"
+
+#: elf32-v850.c:173
+#, c-format
+msgid "Variable `%s' cannot occupy in multiple small data regions"
+msgstr "Змінна «%s» не може займати декілька малих облаÑтей даних"
+
+#: elf32-v850.c:176
+#, c-format
+msgid "Variable `%s' can only be in one of the small, zero, and tiny data regions"
+msgstr "Змінну «%s» можна зберігати лише у одній з малих, нульових Ñ– малюÑіньких облаÑтей даних"
+
+#: elf32-v850.c:179
+#, c-format
+msgid "Variable `%s' cannot be in both small and zero data regions simultaneously"
+msgstr "Змінна «%s» не може зберігатиÑÑ Ñƒ малій Ñ– нульовій облаÑÑ‚Ñ– даних одночаÑно"
+
+#: elf32-v850.c:182
+#, c-format
+msgid "Variable `%s' cannot be in both small and tiny data regions simultaneously"
+msgstr "Змінна «%s» не може зберігатиÑÑ Ñƒ малій Ñ– малюÑінькій облаÑÑ‚Ñ– даних одночаÑно"
+
+#: elf32-v850.c:185
+#, c-format
+msgid "Variable `%s' cannot be in both zero and tiny data regions simultaneously"
+msgstr "Змінна «%s» не може зберігатиÑÑ Ñƒ нульовій Ñ– малюÑінькій облаÑÑ‚Ñ– даних одночаÑно"
+
+#: elf32-v850.c:483
+msgid "FAILED to find previous HI16 reloc"
+msgstr "ÐЕ ВДÐЛОСЯ знайти попереднє переÑÑƒÐ²Ð°Ð½Ð½Ñ HI16"
+
+#: elf32-v850.c:2155
+msgid "could not locate special linker symbol __gp"
+msgstr "не вдалоÑÑ Ð·Ð½Ð°Ð¹Ñ‚Ð¸ Ñпеціальний Ñимвол компонувальника __gp"
+
+#: elf32-v850.c:2159
+msgid "could not locate special linker symbol __ep"
+msgstr "не вдалоÑÑ Ð·Ð½Ð°Ð¹Ñ‚Ð¸ Ñпеціальний Ñимвол компонувальника __ep"
+
+#: elf32-v850.c:2163
+msgid "could not locate special linker symbol __ctbp"
+msgstr "не вдалоÑÑ Ð·Ð½Ð°Ð¹Ñ‚Ð¸ Ñпеціальний Ñимвол компонувальника __ctbp"
+
+#: elf32-v850.c:2341
+msgid "%B: Architecture mismatch with previous modules"
+msgstr "%B: невідповідніÑÑ‚ÑŒ архітектур з попередніми модулÑми"
+
+#. xgettext:c-format.
+#: elf32-v850.c:2360
+#, c-format
+msgid "private flags = %lx: "
+msgstr "закриті прапорці = %lx: "
+
+#: elf32-v850.c:2365
+#, c-format
+msgid "v850 architecture"
+msgstr "архітектура v850"
+
+#: elf32-v850.c:2366
+#, c-format
+msgid "v850e architecture"
+msgstr "архітектура v850e"
+
+#: elf32-v850.c:2367
+#, c-format
+msgid "v850e1 architecture"
+msgstr "архітектура v850e1"
+
+#: elf32-v850.c:2368
+#, c-format
+msgid "v850e2 architecture"
+msgstr "архітектура v850e2"
+
+#: elf32-v850.c:2369
+#, c-format
+msgid "v850e2v3 architecture"
+msgstr "архітектура v850e2v3"
+
+#: elf32-vax.c:532
+#, c-format
+msgid " [nonpic]"
+msgstr " [не-pic]"
+
+#: elf32-vax.c:535
+#, c-format
+msgid " [d-float]"
+msgstr " [d-float]"
+
+#: elf32-vax.c:538
+#, c-format
+msgid " [g-float]"
+msgstr " [g-float]"
+
+#: elf32-vax.c:655
+#, c-format
+msgid "%s: warning: GOT addend of %ld to `%s' does not match previous GOT addend of %ld"
+msgstr "%s: попередженнÑ: доданок GOT %ld до «%s» не відповідає попередньому доданку GOT %ld"
+
+#: elf32-vax.c:1585
+#, c-format
+msgid "%s: warning: PLT addend of %d to `%s' from %s section ignored"
+msgstr "%s: попередженнÑ: доданок PLT %d до «%s» з розділу %s проігноровано"
+
+#: elf32-vax.c:1712
+#, c-format
+msgid "%s: warning: %s relocation against symbol `%s' from %s section"
+msgstr "%s: попередженнÑ: переÑÑƒÐ²Ð°Ð½Ð½Ñ %s відноÑно Ñимволу «%s» з розділу %s"
+
+#: elf32-vax.c:1718
+#, c-format
+msgid "%s: warning: %s relocation to 0x%x from %s section"
+msgstr "%s: попередженнÑ: переÑÑƒÐ²Ð°Ð½Ð½Ñ %s до 0x%x з розділу %s"
+
+#: elf32-xstormy16.c:451 elf32-ia64.c:2336 elf64-ia64.c:2336
+msgid "non-zero addend in @fptr reloc"
+msgstr "ненульовий доданок у переÑуванні @fptr"
+
+#: elf32-xtensa.c:918
+msgid "%B(%A): invalid property table"
+msgstr "%B(%A): некоректна Ñ‚Ð°Ð±Ð»Ð¸Ñ†Ñ Ð²Ð»Ð°ÑтивоÑтей"
+
+#: elf32-xtensa.c:2777
+msgid "%B(%A+0x%lx): relocation offset out of range (size=0x%x)"
+msgstr "%B(%A+0x%lx): відÑтуп переÑÑƒÐ²Ð°Ð½Ð½Ñ Ð¿Ð¾Ð·Ð° діапазоном (розмір=0x%x)"
+
+#: elf32-xtensa.c:2856 elf32-xtensa.c:2977
+msgid "dynamic relocation in read-only section"
+msgstr "динамічне переÑÑƒÐ²Ð°Ð½Ð½Ñ Ñƒ розділі, призначеному лише Ð´Ð»Ñ Ñ‡Ð¸Ñ‚Ð°Ð½Ð½Ñ"
+
+#: elf32-xtensa.c:2953
+msgid "TLS relocation invalid without dynamic sections"
+msgstr "ПереÑÑƒÐ²Ð°Ð½Ð½Ñ TLS Ñ” некоректним без динамічних розділів"
+
+#: elf32-xtensa.c:3172
+msgid "internal inconsistency in size of .got.loc section"
+msgstr "Ð²Ð½ÑƒÑ‚Ñ€Ñ–ÑˆÐ½Ñ Ð½ÐµÐ¿Ð¾ÑлідовніÑÑ‚ÑŒ у розмірах розділу .got.loc"
+
+#: elf32-xtensa.c:3485
+msgid "%B: incompatible machine type. Output is 0x%x. Input is 0x%x"
+msgstr "%B: неÑуміÑні типи архітектур. Ð’Ð¸Ð²ÐµÐ´ÐµÐ½Ð½Ñ â€” 0x%x. Вхідні дані — 0x%x"
+
+#: elf32-xtensa.c:4714 elf32-xtensa.c:4722
+msgid "Attempt to convert L32R/CALLX to CALL failed"
+msgstr "Спроба Ð¿ÐµÑ€ÐµÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ L32R/CALLX на CALL зазнала невдачі"
+
+#: elf32-xtensa.c:6332 elf32-xtensa.c:6408 elf32-xtensa.c:7524
+msgid "%B(%A+0x%lx): could not decode instruction; possible configuration mismatch"
+msgstr "%B(%A+0x%lx): не вдалоÑÑ Ð´ÐµÐºÐ¾Ð´ÑƒÐ²Ð°Ñ‚Ð¸ інÑтрукцію, можлива невідповідніÑÑ‚ÑŒ конфігурацій"
+
+#: elf32-xtensa.c:7264
+msgid "%B(%A+0x%lx): could not decode instruction for XTENSA_ASM_SIMPLIFY relocation; possible configuration mismatch"
+msgstr "%B(%A+0x%lx): не вдалоÑÑ Ð´ÐµÐºÐ¾Ð´ÑƒÐ²Ð°Ñ‚Ð¸ інÑтрукцію Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÑÑƒÐ²Ð°Ð½Ð½Ñ XTENSA_ASM_SIMPLIFY, можлива невідповідніÑÑ‚ÑŒ конфігурацій"
+
+#: elf32-xtensa.c:9023
+msgid "invalid relocation address"
+msgstr "некоректна адреÑа переÑуваннÑ"
+
+#: elf32-xtensa.c:9072
+msgid "overflow after relaxation"
+msgstr "Ð¿ÐµÑ€ÐµÐ¿Ð¾Ð²Ð½ÐµÐ½Ð½Ñ Ð¿Ñ–ÑÐ»Ñ Ð¾Ð¿Ñ‚Ð¸Ð¼Ñ–Ð·Ð°Ñ†Ñ–Ñ— розміру"
+
+#: elf32-xtensa.c:10204
+msgid "%B(%A+0x%lx): unexpected fix for %s relocation"
+msgstr "%B(%A+0x%lx): неочікуване Ð²Ð¸Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð½Ñ Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÑÑƒÐ²Ð°Ð½Ð½Ñ %s"
+
+#: elf64-alpha.c:460
+msgid "GPDISP relocation did not find ldah and lda instructions"
+msgstr "ПереÑуваннÑм GPDISP не знайдено інÑтрукції ldah Ñ– lda"
+
+#: elf64-alpha.c:2497
+msgid "%B: .got subsegment exceeds 64K (size %d)"
+msgstr "%B: розмір підÑегмента .got перевищує 64кБ (розмір — %d)"
+
+#: elf64-alpha.c:4387 elf64-alpha.c:4399
+msgid "%B: gp-relative relocation against dynamic symbol %s"
+msgstr "%B: gp-відноÑне переÑÑƒÐ²Ð°Ð½Ð½Ñ Ñ‰Ð¾Ð´Ð¾ динамічного Ñимволу %s"
+
+#: elf64-alpha.c:4425 elf64-alpha.c:4565
+msgid "%B: pc-relative relocation against dynamic symbol %s"
+msgstr "%B: pc-відноÑне переÑÑƒÐ²Ð°Ð½Ð½Ñ Ñ‰Ð¾Ð´Ð¾ динамічного Ñимволу %s"
+
+#: elf64-alpha.c:4453
+msgid "%B: change in gp: BRSGP %s"
+msgstr "%B: зміна у gp: BRSGP %s"
+
+#: elf64-alpha.c:4478
+msgid "<unknown>"
+msgstr "<невідома>"
+
+#: elf64-alpha.c:4483
+msgid "%B: !samegp reloc against symbol without .prologue: %s"
+msgstr "%B: переÑÑƒÐ²Ð°Ð½Ð½Ñ !samegp щодо Ñимволу без .prologue: %s"
+
+#: elf64-alpha.c:4540
+msgid "%B: unhandled dynamic relocation against %s"
+msgstr "%B: непридатне до обробки динамічне переÑÑƒÐ²Ð°Ð½Ð½Ñ Ñ‰Ð¾Ð´Ð¾ %s"
+
+#: elf64-alpha.c:4572
+msgid "%B: pc-relative relocation against undefined weak symbol %s"
+msgstr "%B: pc-відноÑне переÑÑƒÐ²Ð°Ð½Ð½Ñ Ñ‰Ð¾Ð´Ð¾ невизначеного Ñлабкого Ñимволу %s"
+
+#: elf64-alpha.c:4636
+msgid "%B: dtp-relative relocation against dynamic symbol %s"
+msgstr "%B: dtp-відноÑне переÑÑƒÐ²Ð°Ð½Ð½Ñ Ñ‰Ð¾Ð´Ð¾ динамічного Ñимволу %s"
+
+#: elf64-alpha.c:4659
+msgid "%B: tp-relative relocation against dynamic symbol %s"
+msgstr "%B: tp-відноÑне переÑÑƒÐ²Ð°Ð½Ð½Ñ Ñ‰Ð¾Ð´Ð¾ динамічного Ñимволу %s"
+
+#: elf64-hppa.c:2083
+#, c-format
+msgid "stub entry for %s cannot load .plt, dp offset = %ld"
+msgstr "шаблон запиÑу Ð´Ð»Ñ %s не можна завантажувати .plt, відÑтуп dp = %ld"
+
+#: elf64-hppa.c:3275
+msgid "%B(%A+0x"
+msgstr "%B(%A+0x"
+
+#: elf64-mmix.c:1034
+msgid ""
+"invalid input relocation when producing non-ELF, non-mmo format output.\n"
+" Please use the objcopy program to convert from ELF or mmo,\n"
+" or assemble using \"-no-expand\" (for gcc, \"-Wa,-no-expand\""
+msgstr ""
+"некоректне вхідне переÑÑƒÐ²Ð°Ð½Ð½Ñ Ð¿Ñ–Ð´ Ñ‡Ð°Ñ ÑÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ð´Ð°Ð½Ð¸Ñ… не у\n"
+" форматі ELF Ñ– Ð²Ð¸Ð²ÐµÐ´ÐµÐ½Ð½Ñ Ð´Ð°Ð½Ð¸Ñ… не у форматі mmo.\n"
+" Будь лаÑка, ÑкориÑтайтеÑÑ Ð¿Ñ€Ð¾Ð³Ñ€Ð°Ð¼Ð¾ÑŽ objcopy Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ\n"
+" даних з ELF або mmo або зберіть з викориÑтаннÑм «-no-expand»\n"
+" (Ð´Ð»Ñ gcc «-Wa,-no-expand»)"
+
+#: elf64-mmix.c:1218
+msgid ""
+"invalid input relocation when producing non-ELF, non-mmo format output.\n"
+" Please use the objcopy program to convert from ELF or mmo,\n"
+" or compile using the gcc-option \"-mno-base-addresses\"."
+msgstr ""
+"некоректне вхідне переÑÑƒÐ²Ð°Ð½Ð½Ñ Ð¿Ñ–Ð´ Ñ‡Ð°Ñ ÑÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ð´Ð°Ð½Ð¸Ñ… не у\n"
+" форматі ELF Ñ– Ð²Ð¸Ð²ÐµÐ´ÐµÐ½Ð½Ñ Ð´Ð°Ð½Ð¸Ñ… не у форматі mmo.\n"
+" Будь лаÑка, ÑкориÑтайтеÑÑ Ð¿Ñ€Ð¾Ð³Ñ€Ð°Ð¼Ð¾ÑŽ objcopy Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ\n"
+" даних з ELF або mmo або зберіть з викориÑтаннÑм параметра gcc\n"
+" «-mno-base-addresses»."
+
+#: elf64-mmix.c:1244
+#, c-format
+msgid ""
+"%s: Internal inconsistency error for value for\n"
+" linker-allocated global register: linked: 0x%lx%08lx != relaxed: 0x%lx%08lx\n"
+msgstr ""
+"%s: помилка через внутрішню непоÑлідовніÑÑ‚ÑŒ Ð´Ð»Ñ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ\n"
+" розміщеного компонувальником загального регіÑтра: компоновано: 0x%lx%08lx != розміщено: 0x%lx%08lx\n"
+
+#: elf64-mmix.c:1670
+#, c-format
+msgid "%s: base-plus-offset relocation against register symbol: (unknown) in %s"
+msgstr "%s: переÑÑƒÐ²Ð°Ð½Ð½Ñ Ð¾Ñнова-плюÑ-відÑтуп щодо Ñимволу регіÑтру: (невідоме) у %s"
+
+#: elf64-mmix.c:1675
+#, c-format
+msgid "%s: base-plus-offset relocation against register symbol: %s in %s"
+msgstr "%s: переÑÑƒÐ²Ð°Ð½Ð½Ñ Ð¾Ñнова-плюÑ-відÑтуп щодо Ñимволу регіÑтру: %s у %s"
+
+#: elf64-mmix.c:1719
+#, c-format
+msgid "%s: register relocation against non-register symbol: (unknown) in %s"
+msgstr "%s: переÑÑƒÐ²Ð°Ð½Ð½Ñ Ñ€ÐµÐ³Ñ–Ñтрів щодо Ñимволу, Ñкий не перебуває у регіÑтрі: (невідоме) у %s"
+
+#: elf64-mmix.c:1724
+#, c-format
+msgid "%s: register relocation against non-register symbol: %s in %s"
+msgstr "%s: переÑÑƒÐ²Ð°Ð½Ð½Ñ Ñ€ÐµÐ³Ñ–Ñтрів щодо Ñимволу, Ñкий не перебуває у регіÑтрі: %s у %s"
+
+#: elf64-mmix.c:1761
+#, c-format
+msgid "%s: directive LOCAL valid only with a register or absolute value"
+msgstr "%s: директиву LOCAL можна викориÑтовувати лише зі значеннÑми у регіÑтрах або абÑолютними значеннÑми"
+
+#: elf64-mmix.c:1789
+#, c-format
+msgid "%s: LOCAL directive: Register $%ld is not a local register. First global register is $%ld."
+msgstr "%s: директива LOCAL: регіÑÑ‚Ñ€ $%ld не Ñ” локальним регіÑтром. Першим загальним регіÑтром Ñ” $%ld."
+
+#: elf64-mmix.c:2253
+#, c-format
+msgid "%s: Error: multiple definition of `%s'; start of %s is set in a earlier linked file\n"
+msgstr "%s: помилка: декілька визначень «%s»; початок %s вÑтановлено у раніше Ñкомпонований файл\n"
+
+#: elf64-mmix.c:2311
+msgid "Register section has contents\n"
+msgstr "У розділі регіÑтрів міÑÑ‚ÑÑ‚ÑŒÑÑ Ð´Ð°Ð½Ñ–\n"
+
+#: elf64-mmix.c:2503
+#, c-format
+msgid ""
+"Internal inconsistency: remaining %u != max %u.\n"
+" Please report this bug."
+msgstr ""
+"Ð’Ð½ÑƒÑ‚Ñ€Ñ–ÑˆÐ½Ñ Ð½ÐµÑƒÐ·Ð³Ð¾Ð´Ð¶ÐµÐ½Ñ–ÑÑ‚ÑŒ: залишилоÑÑ %u != макÑ. %u.\n"
+" Будь лаÑка, повідомте про цю ваду."
+
+#: elf64-ppc.c:4185
+msgid "%P: %B: cannot create stub entry %s\n"
+msgstr "%P: %B: не вдалоÑÑ Ñтворити шаблонний Ð·Ð°Ð¿Ð¸Ñ %s\n"
+
+#: elf64-ppc.c:6518
+msgid "%P: copy reloc against `%s' requires lazy plt linking; avoid setting LD_BIND_NOW=1 or upgrade gcc\n"
+msgstr "%P: ÐºÐ¾Ð¿Ñ–ÑŽÐ²Ð°Ð½Ð½Ñ Ð¿ÐµÑ€ÐµÑÑƒÐ²Ð°Ð½Ð½Ñ Ñ‰Ð¾Ð´Ð¾ «%s» потребує відкладеного ÐºÐ¾Ð¼Ð¿Ð¾Ð½ÑƒÐ²Ð°Ð½Ð½Ñ plt; не вÑтановлюйте LD_BIND_NOW=1 або оновіть gcc\n"
+
+#: elf64-ppc.c:6788
+msgid "%B: undefined symbol on R_PPC64_TOCSAVE relocation"
+msgstr "%B: невизначений Ñимвол у переÑуванні R_PPC64_TOCSAVE"
+
+#: elf64-ppc.c:6992
+msgid "%P: dynreloc miscount for %B, section %A\n"
+msgstr "%P: помилки у обчиÑленні динамічного переÑÑƒÐ²Ð°Ð½Ð½Ñ Ð´Ð»Ñ %B, розділ %A\n"
+
+#: elf64-ppc.c:7076
+msgid "%B: .opd is not a regular array of opd entries"
+msgstr "%B: .opd не Ñ” звичайним маÑивом запиÑів opd"
+
+#: elf64-ppc.c:7085
+msgid "%B: unexpected reloc type %u in .opd section"
+msgstr "%B: неочікуваний тип переÑуваннÑ, %u, у розділі .opd"
+
+#: elf64-ppc.c:7106
+msgid "%B: undefined sym `%s' in .opd section"
+msgstr "%B: невизначений Ñимвол, «%s» у розділі .opd"
+
+#: elf64-ppc.c:7664
+msgid "%H __tls_get_addr lost arg, TLS optimization disabled\n"
+msgstr "%H __tls_get_addr втрачено аргумент, оптимізацію TLS вимкнено\n"
+
+#: elf64-ppc.c:8003 elf64-ppc.c:8564
+#, c-format
+msgid "%s defined on removed toc entry"
+msgstr "%s визначено у вилученому запиÑÑ– toc"
+
+#: elf64-ppc.c:8521
+msgid "%P: %H: %s relocation references optimized away TOC entry\n"
+msgstr "%P: %H: переÑÑƒÐ²Ð°Ð½Ð½Ñ %s поÑилаєтьÑÑ Ð½Ð° уÑунутий у результаті оптимізації Ð·Ð°Ð¿Ð¸Ñ TOC\n"
+
+#: elf64-ppc.c:9598
+msgid "%P: cannot find opd entry toc for %s\n"
+msgstr "%P: не вдалоÑÑ Ð·Ð½Ð°Ð¹Ñ‚Ð¸ Ð·Ð°Ð¿Ð¸Ñ opd у toc Ð´Ð»Ñ %s\n"
+
+#: elf64-ppc.c:9680
+msgid "%P: long branch stub `%s' offset overflow\n"
+msgstr "%P: Ð¿ÐµÑ€ÐµÐ¿Ð¾Ð²Ð½ÐµÐ½Ð½Ñ Ð²Ñ–Ð´Ñтупу шаблона довгої гілки, «%s»\n"
+
+#: elf64-ppc.c:9739
+msgid "%P: can't find branch stub `%s'\n"
+msgstr "%P: не вдалоÑÑ Ð·Ð½Ð°Ð¹Ñ‚Ð¸ шаблон Ñ€Ð¾Ð·Ð³Ð°Ð»ÑƒÐ¶ÐµÐ½Ð½Ñ Â«%s»\n"
+
+#: elf64-ppc.c:9801 elf64-ppc.c:9943
+msgid "%P: linkage table error against `%s'\n"
+msgstr "%P: помилка у таблиці ÐºÐ¾Ð¼Ð¿Ð¾Ð½ÑƒÐ²Ð°Ð½Ð½Ñ Ñ‰Ð¾Ð´Ð¾ «%s»\n"
+
+#: elf64-ppc.c:10126
+msgid "%P: can't build branch stub `%s'\n"
+msgstr "%P: не вдалоÑÑ Ð¿Ð¾Ð±ÑƒÐ´ÑƒÐ²Ð°Ñ‚Ð¸ шаблон Ñ€Ð¾Ð·Ð³Ð°Ð»ÑƒÐ¶ÐµÐ½Ð½Ñ Â«%s»\n"
+
+#: elf64-ppc.c:10941
+msgid "%B section %A exceeds stub group size"
+msgstr "Розділ %B, %A, перевищує розміри групи шаблонів"
+
+#: elf64-ppc.c:11666 elf64-ppc.c:11699
+msgid "%P: %s offset too large for .eh_frame sdata4 encoding"
+msgstr "%P: відÑтуп %s Ñ” надто великим Ð´Ð»Ñ ÐºÐ¾Ð´ÑƒÐ²Ð°Ð½Ð½Ñ sdata4 .eh_frame"
+
+#: elf64-ppc.c:11744
+msgid "%P: stubs don't match calculated size\n"
+msgstr "%P: шаблони не відповідають обчиÑленому розміру\n"
+
+#: elf64-ppc.c:11756
+#, c-format
+msgid ""
+"linker stubs in %u group%s\n"
+" branch %lu\n"
+" toc adjust %lu\n"
+" long branch %lu\n"
+" long toc adj %lu\n"
+" plt call %lu"
+msgstr ""
+"шаблони компонувальника у %u групах %s\n"
+" гілка %lu\n"
+" кориг. toc %lu\n"
+" довга гілка %lu\n"
+" д. кор. toc %lu\n"
+" plt-виклик %lu"
+
+#: elf64-ppc.c:12042
+msgid "%P: %H: %s used with TLS symbol %s\n"
+msgstr "%P: %H: %s викориÑтовуєтьÑÑ Ð· Ñимволом TLS %s\n"
+
+#: elf64-ppc.c:12043
+msgid "%P: %H: %s used with non-TLS symbol %s\n"
+msgstr "%P: %H: %s викориÑтовуєтьÑÑ Ð· Ñимволом поза TLS %s\n"
+
+#: elf64-ppc.c:12556
+msgid "%P: %H: automatic multiple TOCs not supported using your crt files; recompile with -mminimal-toc or upgrade gcc\n"
+msgstr "%P: %H: автоматичне ÑÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ð´ÐµÐºÑ–Ð»ÑŒÐºÐ¾Ñ… TOC не можна виконати на оÑнові ваших файлів crt; виконайте повторне Ð·Ð±Ð¸Ñ€Ð°Ð½Ð½Ñ Ð· -mminimal-toc або оновіть gcc\n"
+
+#: elf64-ppc.c:12562
+msgid "%P: %H: sibling call optimization to `%s' does not allow automatic multiple TOCs; recompile with -mminimal-toc or -fno-optimize-sibling-calls, or make `%s' extern\n"
+msgstr "%P: %H: у разі викориÑÑ‚Ð°Ð½Ð½Ñ Ð¾Ð¿Ñ‚Ð¸Ð¼Ñ–Ð·Ð°Ñ†Ñ–Ñ— викликів однакових функцій Ð´Ð»Ñ Â«%s» не даÑÑ‚ÑŒ змоги Ñтворити декілька TOC; виконайте повторне Ð·Ð±Ð¸Ñ€Ð°Ð½Ð½Ñ Ð· -mminimal-toc або -fno-optimize-sibling-calls чи зробіть «%s» зовнішньою (extern)\n"
+
+#: elf64-ppc.c:13286
+msgid "%P: %B: relocation %s is not supported for symbol %s\n"
+msgstr "%P: %B: підтримки переÑÑƒÐ²Ð°Ð½Ð½Ñ %s Ð´Ð»Ñ Ñимволу %s не передбачено\n"
+
+#: elf64-ppc.c:13446
+msgid "%P: %H: error: %s not a multiple of %u\n"
+msgstr "%P: %H: помилка: %s не є кратним до %u\n"
+
+#: elf64-sh64.c:1686
+#, c-format
+msgid "%s: error: unaligned relocation type %d at %08x reloc %08x\n"
+msgstr "%s: помилка: невирівнÑний тип переÑÑƒÐ²Ð°Ð½Ð½Ñ %d у %08x, переÑÑƒÐ²Ð°Ð½Ð½Ñ %08x\n"
+
+#: elf64-sparc.c:446
+msgid "%B: Only registers %%g[2367] can be declared using STT_REGISTER"
+msgstr "%B: за допомогою STT_REGISTER можна оголошувати лише регіÑтри %%g[2367]"
+
+#: elf64-sparc.c:466
+msgid "Register %%g%d used incompatibly: %s in %B, previously %s in %B"
+msgstr "ÐеÑуміÑне викориÑÑ‚Ð°Ð½Ð½Ñ Ñ€ÐµÐ³Ñ–Ñтру %%g%d: %s у %B, раніше викориÑтано %s у %B"
+
+#: elf64-sparc.c:489
+msgid "Symbol `%s' has differing types: REGISTER in %B, previously %s in %B"
+msgstr "Символ «%s» належить до різних типів: REGISTER у %B і %s раніше у %B"
+
+#: elf64-sparc.c:534
+msgid "Symbol `%s' has differing types: %s in %B, previously REGISTER in %B"
+msgstr "Символ «s» належить до різних типів: %s у %B і REGISTER раніше у %B"
+
+#: elf64-sparc.c:687
+msgid "%B: linking UltraSPARC specific with HAL specific code"
+msgstr "%B: ÐºÐ¾Ð¼Ð¿Ð¾Ð½ÑƒÐ²Ð°Ð½Ð½Ñ UltraSPARC-Ñпецифічного та HAL-Ñпецифічного коду"
+
+#: elf64-x86-64.c:1427
+msgid "%B: relocation %s against symbol `%s' isn't supported in x32 mode"
+msgstr "%B: підтримки переÑÑƒÐ²Ð°Ð½Ð½Ñ %s щодо Ñимволу «%s» у режимі x32 не передбачено"
+
+#: elf64-x86-64.c:1656
+msgid "%B: '%s' accessed both as normal and thread local symbol"
+msgstr "'%B: доÑтуп до «%s» виконуєтьÑÑ Ñк до звичайного Ñимволу та локального Ð´Ð»Ñ Ð¿Ð¾Ñ‚Ð¾ÐºÑƒ Ð²Ð¸ÐºÐ¾Ð½Ð°Ð½Ð½Ñ Ñимволу"
+
+#: elf64-x86-64.c:3150
+msgid "%B: relocation %s against STT_GNU_IFUNC symbol `%s' has non-zero addend: %d"
+msgstr "%B: переÑÑƒÐ²Ð°Ð½Ð½Ñ %s щодо Ñимволу STT_GNU_IFUNC, «%s», міÑтить ненульовий доданок: %d"
+
+#: elf64-x86-64.c:3411
+msgid "%B: relocation R_X86_64_GOTOFF64 against protected function `%s' can not be used when making a shared object"
+msgstr "%B: не можна викориÑтовувати R_X86_64_GOTOFF64 переÑÑƒÐ²Ð°Ð½Ð½Ñ Ñ‰Ð¾Ð´Ð¾ захищеної функції «%s» під Ñ‡Ð°Ñ ÑÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ð¾Ð±â€™Ñ”ÐºÑ‚Ð° Ñпільного викориÑтаннÑ"
+
+#: elf64-x86-64.c:3523
+msgid "; recompile with -fPIC"
+msgstr "; виконайте повторне Ð·Ð±Ð¸Ñ€Ð°Ð½Ð½Ñ Ð· -fPIC"
+
+#: elf64-x86-64.c:3528
+msgid "%B: relocation %s against %s `%s' can not be used when making a shared object%s"
+msgstr "%B: переÑÑƒÐ²Ð°Ð½Ð½Ñ %s щодо %s, «%s», не можна викориÑтовувати під Ñ‡Ð°Ñ ÑÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ð¾Ð±â€™Ñ”ÐºÑ‚Ð° Ñпільного викориÑтаннÑ%s"
+
+#: elf64-x86-64.c:3530
+msgid "%B: relocation %s against undefined %s `%s' can not be used when making a shared object%s"
+msgstr "%B: переÑÑƒÐ²Ð°Ð½Ð½Ñ %s щодо невизначеного %s, «%s», не можна викориÑтовувати під Ñ‡Ð°Ñ ÑÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ð¾Ð±â€™Ñ”ÐºÑ‚Ð° Ñпільного викориÑтаннÑ%s"
+
+#: elfcode.h:767
+#, c-format
+msgid "warning: %s has a corrupt string table index - ignoring"
+msgstr "попередженнÑ: покажчик таблиці Ñ€Ñдків %s пошкоджено — ігноруєтьÑÑ"
+
+#: elfcode.h:1177
+#, c-format
+msgid "%s: version count (%ld) does not match symbol count (%ld)"
+msgstr "%s: лічильник верÑÑ–Ñ— (%ld) не збігаєтьÑÑ Ð· лічильником Ñимволу (%ld)"
+
+#: elfcode.h:1431
+#, c-format
+msgid "%s(%s): relocation %d has invalid symbol index %ld"
+msgstr "%s(%s): переÑÑƒÐ²Ð°Ð½Ð½Ñ %d міÑтить некоректний Ñ–Ð½Ð´ÐµÐºÑ Ñимволу, %ld"
+
+#: elfcore.h:312
+msgid "Warning: %B is truncated: expected core file size >= %lu, found: %lu."
+msgstr "ПопередженнÑ: %B обрізано: очікуваний розмір оÑновного файла >= %lu, виÑвлено: %lu."
+
+#: elflink.c:1117
+msgid "%s: TLS definition in %B section %A mismatches non-TLS definition in %B section %A"
+msgstr "%s: Ð²Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ TLS у %B, розділ %A, не збігаєтьÑÑ Ð· визначеннÑм не-TLS у розділі %B %A"
+
+#: elflink.c:1121
+msgid "%s: TLS reference in %B mismatches non-TLS reference in %B"
+msgstr "%s: поÑÐ¸Ð»Ð°Ð½Ð½Ñ TLS у %B не збігаєтьÑÑ Ð· поÑиланнÑм не-TLS у %B"
+
+#: elflink.c:1125
+msgid "%s: TLS definition in %B section %A mismatches non-TLS reference in %B"
+msgstr "%s: Ð²Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ TLS у %B, розділ %A, не збігаєтьÑÑ Ð· поÑиланнÑм не-TLS у розділі %B, %A"
+
+#: elflink.c:1129
+msgid "%s: TLS reference in %B mismatches non-TLS definition in %B section %A"
+msgstr "%s: поÑÐ¸Ð»Ð°Ð½Ð½Ñ TLS у %B не збігаєтьÑÑ Ð· визначеннÑм не-TLS у розділі %B %A"
+
+#: elflink.c:1762
+msgid "%B: unexpected redefinition of indirect versioned symbol `%s'"
+msgstr "%B: неочікуване Ð¿ÐµÑ€ÐµÐ²Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ñимволу з непрÑмим визначеннÑм верÑÑ–Ñ—, «%s»"
+
+#: elflink.c:2063
+msgid "%B: version node not found for symbol %s"
+msgstr "%B: не знайдено вузла верÑÑ–Ñ— Ð´Ð»Ñ Ñимволу %s"
+
+#: elflink.c:2154
+msgid "%B: bad reloc symbol index (0x%lx >= 0x%lx) for offset 0x%lx in section `%A'"
+msgstr "%B: помилковий Ñ–Ð½Ð´ÐµÐºÑ Ñимволу переÑÑƒÐ²Ð°Ð½Ð½Ñ (0x%lx >= 0x%lx) Ð´Ð»Ñ Ð²Ñ–Ð´Ñтупу 0x%lx у розділі «%A»"
+
+#: elflink.c:2165
+msgid "%B: non-zero symbol index (0x%lx) for offset 0x%lx in section `%A' when the object file has no symbol table"
+msgstr "%B: ненульовий Ñ–Ð½Ð´ÐµÐºÑ Ñимволу (0x%lx) Ð´Ð»Ñ Ð²Ñ–Ð´Ñтупу 0x%lx у розділі «%A», але у об’єктному файлі немає таблиці Ñимволів"
+
+#: elflink.c:2355
+msgid "%B: relocation size mismatch in %B section %A"
+msgstr "%B: невідповідніÑÑ‚ÑŒ розміру переÑÑƒÐ²Ð°Ð½Ð½Ñ Ñƒ розділі %B %A"
+
+#: elflink.c:2639
+#, c-format
+msgid "warning: type and size of dynamic symbol `%s' are not defined"
+msgstr "попередженнÑ: тип Ñ– розмір динамічного Ñимволу «%s» не визначено"
+
+#: elflink.c:3391
+msgid "%P: alternate ELF machine code found (%d) in %B, expecting %d\n"
+msgstr "%P: виÑвлено альтернативний машинний код ELF (%d) у %B, очікувалоÑÑ %d\n"
+
+#: elflink.c:4037
+msgid "%B: %s: invalid version %u (max %d)"
+msgstr "%B: %s: некоректна верÑÑ–Ñ, %u (макÑимум — %d)"
+
+#: elflink.c:4073
+msgid "%B: %s: invalid needed version %d"
+msgstr "%B: %s: некоректний Ð·Ð°Ð¿Ð¸Ñ Ð¿Ð¾Ñ‚Ñ€Ñ–Ð±Ð½Ð¾Ñ— верÑÑ–Ñ— %d"
+
+#: elflink.c:4269
+msgid "Warning: alignment %u of common symbol `%s' in %B is greater than the alignment (%u) of its section %A"
+msgstr "ПопередженнÑ: Ð²Ð¸Ñ€Ñ–Ð²Ð½ÑŽÐ²Ð°Ð½Ð½Ñ %u загального Ñимволу «%s» у %B перевищує Ð²Ð¸Ñ€Ñ–Ð²Ð½ÑŽÐ²Ð°Ð½Ð½Ñ (%u) його розділу %A"
+
+#: elflink.c:4275
+msgid "Warning: alignment %u of symbol `%s' in %B is smaller than %u in %B"
+msgstr "ПопередженнÑ: Ð²Ð¸Ñ€Ñ–Ð²Ð½ÑŽÐ²Ð°Ð½Ð½Ñ %u Ñимволу «%s» у %B Ñ” меншим за %u у %B"
+
+#: elflink.c:4290
+msgid "Warning: size of symbol `%s' changed from %lu in %B to %lu in %B"
+msgstr "ПопередженнÑ: розмір Ñимволу «%s» змінено з %lu у %B на %lu у %B"
+
+#: elflink.c:4463
+msgid "%B: undefined reference to symbol '%s'"
+msgstr "%B: невизначене поÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð½Ð° Ñимвол «%s»"
+
+#: elflink.c:4466
+msgid "note: '%s' is defined in DSO %B so try adding it to the linker command line"
+msgstr "зауваженнÑ: «%s» визначено у %B DSO, отже Ñпробуємо додати його до командного Ñ€Ñдка компонувальника"
+
+#: elflink.c:5781
+#, c-format
+msgid "%s: undefined version: %s"
+msgstr "%s: невизначена верÑÑ–Ñ: %s"
+
+#: elflink.c:5849
+msgid "%B: .preinit_array section is not allowed in DSO"
+msgstr "%B: не можна викориÑтовувати розділ .preinit_array у DSO"
+
+#: elflink.c:7604
+#, c-format
+msgid "undefined %s reference in complex symbol: %s"
+msgstr "невизначене поÑиланнÑ, %s, у Ñкладеному Ñимволі: %s"
+
+#: elflink.c:7758
+#, c-format
+msgid "unknown operator '%c' in complex symbol"
+msgstr "невідомий оператор, «%c», у Ñкладеному Ñимволі"
+
+#: elflink.c:8097 elflink.c:8114 elflink.c:8151 elflink.c:8168
+msgid "%B: Unable to sort relocs - they are in more than one size"
+msgstr "%B: не вдалоÑÑ Ð²Ð¿Ð¾Ñ€Ñдкувати переÑуваннÑ: їхні розміри не Ñ” однаковими"
+
+#: elflink.c:8128 elflink.c:8182
+msgid "%B: Unable to sort relocs - they are of an unknown size"
+msgstr "%B: не вдалоÑÑ Ð²Ð¿Ð¾Ñ€Ñдкувати переÑуваннÑ: їхні розміри невідомі"
+
+#: elflink.c:8233
+msgid "Not enough memory to sort relocations"
+msgstr "ÐедоÑтатньо пам’ÑÑ‚Ñ– Ð´Ð»Ñ Ð²Ð¿Ð¾Ñ€ÑÐ´ÐºÐ¾Ð²ÑƒÐ²Ð°Ð½Ð½Ñ Ð¿ÐµÑ€ÐµÑувань"
+
+#: elflink.c:8426
+msgid "%B: Too many sections: %d (>= %d)"
+msgstr "%B: забагато розділів: %d (>= %d)"
+
+#: elflink.c:8675
+msgid "%B: internal symbol `%s' in %B is referenced by DSO"
+msgstr "%B: на внутрішній Ñимвол «%s» у %B Ñ–Ñнує поÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð· DSO"
+
+#: elflink.c:8677
+msgid "%B: hidden symbol `%s' in %B is referenced by DSO"
+msgstr "%B: на прихований Ñимвол «%s» у %B Ñ–Ñнує поÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð· DSO"
+
+#: elflink.c:8679
+msgid "%B: local symbol `%s' in %B is referenced by DSO"
+msgstr "%B: на локальний Ñимвол «%s» у %B Ñ–Ñнує поÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð· DSO"
+
+#: elflink.c:8776
+msgid "%B: could not find output section %A for input section %A"
+msgstr "%B: не вдалоÑÑ Ð·Ð½Ð°Ð¹Ñ‚Ð¸ розділ Ð²Ð¸Ð²ÐµÐ´ÐµÐ½Ð½Ñ Ð´Ð°Ð½Ð¸Ñ… %A Ð´Ð»Ñ Ñ€Ð¾Ð·Ð´Ñ–Ð»Ñƒ Ð²Ð²ÐµÐ´ÐµÐ½Ð½Ñ Ð´Ð°Ð½Ð¸Ñ… %A"
+
+#: elflink.c:8899
+msgid "%B: protected symbol `%s' isn't defined"
+msgstr "%B: захищений Ñимвол «%s» не визначено"
+
+#: elflink.c:8901
+msgid "%B: internal symbol `%s' isn't defined"
+msgstr "%B: внутрішній Ñимвол «%s» не визначено"
+
+#: elflink.c:8903
+msgid "%B: hidden symbol `%s' isn't defined"
+msgstr "%B: прихований Ñимвол «%s» не визначено"
+
+#: elflink.c:9432
+msgid "error: %B: size of section %A is not multiple of address size"
+msgstr "помилка: %B: розмір розділу %A не Ñ” кратним до розміру адреÑи"
+
+#: elflink.c:9479
+msgid "error: %B contains a reloc (0x%s) for section %A that references a non-existent global symbol"
+msgstr "помилка: %B міÑтить переÑÑƒÐ²Ð°Ð½Ð½Ñ (0x%s) Ð´Ð»Ñ Ñ€Ð¾Ð·Ð´Ñ–Ð»Ñƒ %A, Ñке поÑилаєтьÑÑ Ð½Ð° загальний Ñимвол, Ñкого не Ñ–Ñнує"
+
+#: elflink.c:10214
+msgid "%A has both ordered [`%A' in %B] and unordered [`%A' in %B] sections"
+msgstr "%A міÑтить одразу впорÑдкований [«%A» у %B] Ñ– невпорÑдкований [«%A» у %B] розділи"
+
+#: elflink.c:10219
+#, c-format
+msgid "%A has both ordered and unordered sections"
+msgstr "%A міÑтить одразу впорÑдкований Ñ– невпорÑдкований розділи"
+
+#: elflink.c:10784
+msgid "%B: file class %s incompatible with %s"
+msgstr "%B: ÐºÐ»Ð°Ñ Ñ„Ð°Ð¹Ð»Ñ–Ð² %s Ñ” неÑуміÑним з %s"
+
+#: elflink.c:11093 elflink.c:11137
+msgid "%B: could not find output section %s"
+msgstr "%B: не вдалоÑÑ Ð·Ð½Ð°Ð¹Ñ‚Ð¸ розділ Ð²Ð¸Ð²ÐµÐ´ÐµÐ½Ð½Ñ Ð´Ð°Ð½Ð¸Ñ…, %s"
+
+#: elflink.c:11098
+#, c-format
+msgid "warning: %s section has zero size"
+msgstr "попередженнÑ: розмір розділу %s Ñ” нульовим"
+
+#: elflink.c:11143
+#, c-format
+msgid "warning: section '%s' is being made into a note"
+msgstr "попередженнÑ: розділ «%s» перетворено на нотатку"
+
+#: elflink.c:11212
+msgid "%P%X: read-only segment has dynamic relocations.\n"
+msgstr "%P%X: Ñегмент, призначений лише Ð´Ð»Ñ Ñ‡Ð¸Ñ‚Ð°Ð½Ð½Ñ, міÑтить динамічні переÑуваннÑ.\n"
+
+#: elflink.c:11215
+msgid "%P: warning: creating a DT_TEXTREL in a shared object.\n"
+msgstr "%P: попередженнÑ: Ñтворюємо DT_TEXTREL у об’єкті Ñпільного викориÑтаннÑ.\n"
+
+#: elflink.c:11402
+msgid "%P%X: can not read symbols: %E\n"
+msgstr "%P%X: не вдалоÑÑ Ð¿Ñ€Ð¾Ñ‡Ð¸Ñ‚Ð°Ñ‚Ð¸ Ñимволи: %E\n"
+
+#: elflink.c:11792
+msgid "Removing unused section '%s' in file '%B'"
+msgstr "Вилучаємо невикориÑтовуваний розділ «%s» у файлі «%B»"
+
+#: elflink.c:11998
+msgid "Warning: gc-sections option ignored"
+msgstr "ПопередженнÑ: параметр gc-sections проігноровано"
+
+#: elflink.c:12277
+#, c-format
+msgid "Unrecognized INPUT_SECTION_FLAG %s\n"
+msgstr "Ðерозпізнаний INPUT_SECTION_FLAG, %s\n"
+
+#: elfxx-mips.c:1234
+msgid "static procedure (no name)"
+msgstr "Ñтатична процедура (без назви)"
+
+#: elfxx-mips.c:5259
+msgid "MIPS16 and microMIPS functions cannot call each other"
+msgstr "Функції MIPS16 і microMIPS не можуть викликати одна одну"
+
+#: elfxx-mips.c:5856
+msgid "%B: %A+0x%lx: Direct jumps between ISA modes are not allowed; consider recompiling with interlinking enabled."
+msgstr "%B: %A+0x%lx: безпоÑередні переходи між режимами ISA заборонено; варто виконати повторне Ð·Ð±Ð¸Ñ€Ð°Ð½Ð½Ñ Ð· увімкненим взаємним компонуваннÑм."
+
+#: elfxx-mips.c:6519 elfxx-mips.c:6742
+msgid "%B: Warning: bad `%s' option size %u smaller than its header"
+msgstr "%B: попередженнÑ: помилковий розмір «%s», %u, менший за його заголовок"
+
+#: elfxx-mips.c:7495 elfxx-mips.c:7620
+msgid "%B: Warning: cannot determine the target function for stub section `%s'"
+msgstr "%B: попередженнÑ: не вдалоÑÑ Ð²Ð¸Ð·Ð½Ð°Ñ‡Ð¸Ñ‚Ð¸ функцію Ð¿Ñ€Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð´Ð»Ñ Ñ€Ð¾Ð·Ð´Ñ–Ð»Ñƒ шаблона, «%s»"
+
+#: elfxx-mips.c:7749
+msgid "%B: Malformed reloc detected for section %s"
+msgstr "%B: Ð´Ð»Ñ Ñ€Ð¾Ð·Ð´Ñ–Ð»Ñƒ %s виÑвлено помилку у форматуванні перенеÑеннÑ"
+
+#: elfxx-mips.c:7801
+msgid "%B: GOT reloc at 0x%lx not expected in executables"
+msgstr "%B: переÑÑƒÐ²Ð°Ð½Ð½Ñ GOT у 0x%lx Ñ” неочікуваним у виконуваних файлах"
+
+#: elfxx-mips.c:7930
+msgid "%B: CALL16 reloc at 0x%lx not against global symbol"
+msgstr "%B: переÑÑƒÐ²Ð°Ð½Ð½Ñ CALL16 у 0x%lx не відноÑно загального Ñимволу"
+
+#: elfxx-mips.c:8645
+#, c-format
+msgid "non-dynamic relocations refer to dynamic symbol %s"
+msgstr "нединамічні переÑÑƒÐ²Ð°Ð½Ð½Ñ Ð¿Ð¾ÑилаютьÑÑ Ð½Ð° динамічний Ñимвол, %s"
+
+#: elfxx-mips.c:9347
+msgid "%B: Can't find matching LO16 reloc against `%s' for %s at 0x%lx in section `%A'"
+msgstr "%B: не вдалоÑÑ Ð·Ð½Ð°Ð¹Ñ‚Ð¸ відповідне переÑÑƒÐ²Ð°Ð½Ð½Ñ LO16 щодо «%s» Ð´Ð»Ñ %s у 0x%lx у розділі «%A»"
+
+#: elfxx-mips.c:9486
+msgid "small-data section exceeds 64KB; lower small-data size limit (see option -G)"
+msgstr "розділ малих даних перевищує 64 кБ; нижчий за Ð¾Ð±Ð¼ÐµÐ¶ÐµÐ½Ð½Ñ Ñ€Ð¾Ð·Ð¼Ñ–Ñ€Ñƒ малих даних (див. параметр -G)"
+
+#: elfxx-mips.c:9505
+msgid "JALX to a non-word-aligned address"
+msgstr "JALX до не вирівнÑної за Ñловом адреÑи"
+
+#: elfxx-mips.c:13266
+#, c-format
+msgid "%s: illegal section name `%s'"
+msgstr "%s: некоректна назва розділу, «%s»"
+
+#: elfxx-mips.c:13645 elfxx-mips.c:13671
+msgid "Warning: %B uses -msingle-float, %B uses -mdouble-float"
+msgstr "ПопередженнÑ: у %B викориÑтано -msingle-float, а у %B — -mdouble-float"
+
+#: elfxx-mips.c:13657 elfxx-mips.c:13713
+msgid "Warning: %B uses -msingle-float, %B uses -mips32r2 -mfp64"
+msgstr "ПопередженнÑ: у %B викориÑтано -msingle-float, а у %B — -mips32r2 -mfp64"
+
+#: elfxx-mips.c:13683 elfxx-mips.c:13719
+msgid "Warning: %B uses -mdouble-float, %B uses -mips32r2 -mfp64"
+msgstr "ПопередженнÑ: у %B викориÑтано -mdouble-float, а у %B — -mips32r2 -mfp64"
+
+#: elfxx-mips.c:13761
+msgid "%B: endianness incompatible with that of the selected emulation"
+msgstr "%B: порÑдок байтів Ñ” неÑуміÑним з порÑдком байтів вибраної емулÑції"
+
+#: elfxx-mips.c:13772
+msgid "%B: ABI is incompatible with that of the selected emulation"
+msgstr "%B: ABI Ñ” неÑуміÑним з ABI вибраної емулÑції"
+
+#: elfxx-mips.c:13856
+msgid "%B: warning: linking abicalls files with non-abicalls files"
+msgstr "%B: попередженнÑ: ÐºÐ¾Ð¼Ð¿Ð¾Ð½ÑƒÐ²Ð°Ð½Ð½Ñ Ñ„Ð°Ð¹Ð»Ñ–Ð² abicalls з файлами без abicalls"
+
+#: elfxx-mips.c:13873
+msgid "%B: linking 32-bit code with 64-bit code"
+msgstr "%B: ÐºÐ¾Ð¼Ð¿Ð¾Ð½ÑƒÐ²Ð°Ð½Ð½Ñ 32-бітового коду з 64-бітовим кодом"
+
+#: elfxx-mips.c:13901
+msgid "%B: linking %s module with previous %s modules"
+msgstr "%B: компонуємо модуль %s з попередніми модулÑми %s"
+
+#: elfxx-mips.c:13924
+msgid "%B: ABI mismatch: linking %s module with previous %s modules"
+msgstr "%B: невідповідніÑÑ‚ÑŒ ABI: ÐºÐ¾Ð¼Ð¿Ð¾Ð½ÑƒÐ²Ð°Ð½Ð½Ñ Ð¼Ð¾Ð´ÑƒÐ»Ñ %s з попередніми модулÑми %s"
+
+#: elfxx-mips.c:13948
+msgid "%B: ASE mismatch: linking %s module with previous %s modules"
+msgstr "%B: невідповідніÑÑ‚ÑŒ ASE: ÐºÐ¾Ð¼Ð¿Ð¾Ð½ÑƒÐ²Ð°Ð½Ð½Ñ Ð¼Ð¾Ð´ÑƒÐ»Ñ %s з попередніми модулÑми %s"
+
+#: elfxx-mips.c:14106
+#, c-format
+msgid " [abi=O32]"
+msgstr " [abi=O32]"
+
+#: elfxx-mips.c:14108
+#, c-format
+msgid " [abi=O64]"
+msgstr " [abi=O64]"
+
+#: elfxx-mips.c:14110
+#, c-format
+msgid " [abi=EABI32]"
+msgstr " [abi=EABI32]"
+
+#: elfxx-mips.c:14112
+#, c-format
+msgid " [abi=EABI64]"
+msgstr " [abi=EABI64]"
+
+#: elfxx-mips.c:14114
+#, c-format
+msgid " [abi unknown]"
+msgstr " [невідомий abi]"
+
+#: elfxx-mips.c:14116
+#, c-format
+msgid " [abi=N32]"
+msgstr " [abi=N32]"
+
+#: elfxx-mips.c:14118
+#, c-format
+msgid " [abi=64]"
+msgstr " [abi=64]"
+
+#: elfxx-mips.c:14120
+#, c-format
+msgid " [no abi set]"
+msgstr " [не вÑтановлено abi]"
+
+#: elfxx-mips.c:14141
+#, c-format
+msgid " [unknown ISA]"
+msgstr " [невідомий ISA]"
+
+#: elfxx-mips.c:14155
+#, c-format
+msgid " [not 32bitmode]"
+msgstr " [не 32-біт.режим]"
+
+#: elfxx-sparc.c:596
+#, c-format
+msgid "invalid relocation type %d"
+msgstr "некоректний тип переÑÑƒÐ²Ð°Ð½Ð½Ñ %d"
+
+#: elfxx-tilegx.c:3952
+msgid "%B: Cannot link together %s and %s objects."
+msgstr "%B: не вдалоÑÑ Ñкомпонувати об’єкти %s та %s."
+
+#: i386linux.c:451 m68klinux.c:456 sparclinux.c:450
+#, c-format
+msgid "Output file requires shared library `%s'\n"
+msgstr "Файлу-результату потрібна бібліотека Ñпільного викориÑÑ‚Ð°Ð½Ð½Ñ Â«%s»\n"
+
+#: i386linux.c:459 m68klinux.c:464 sparclinux.c:458
+#, c-format
+msgid "Output file requires shared library `%s.so.%s'\n"
+msgstr "Файлу-результату потрібна бібліотека Ñпільного викориÑÑ‚Ð°Ð½Ð½Ñ Â«%s.so.%s»\n"
+
+#: i386linux.c:648 i386linux.c:698 m68klinux.c:656 m68klinux.c:704
+#: sparclinux.c:648 sparclinux.c:698
+#, c-format
+msgid "Symbol %s not defined for fixups\n"
+msgstr "Символ %s не визначено Ð´Ð»Ñ Ð°Ð´Ñ€ÐµÑних прив’Ñзок\n"
+
+#: i386linux.c:722 m68klinux.c:728 sparclinux.c:722
+msgid "Warning: fixup count mismatch\n"
+msgstr "ПопередженнÑ: невідповідніÑÑ‚ÑŒ кількоÑÑ‚Ñ– адреÑних прив’Ñзок\n"
+
+#: ieee.c:159
+#, c-format
+msgid "%s: string too long (%d chars, max 65535)"
+msgstr "%s: занадто довгий Ñ€Ñдок (%d Ñимволів, макÑ. к-Ñ‚ÑŒ — 65535)"
+
+#: ieee.c:286
+#, c-format
+msgid "%s: unrecognized symbol `%s' flags 0x%x"
+msgstr "%s: нерозпізнані прапорці Ñимволу «%s», 0x%x"
+
+#: ieee.c:792
+msgid "%B: unimplemented ATI record %u for symbol %u"
+msgstr "%B: нереалізований Ð·Ð°Ð¿Ð¸Ñ ATI, %u, Ð´Ð»Ñ Ñимволу %u"
+
+#: ieee.c:816
+msgid "%B: unexpected ATN type %d in external part"
+msgstr "%B: неочікуваний тип ATN, %d, у зовнішній чаÑтині"
+
+#: ieee.c:838
+msgid "%B: unexpected type after ATN"
+msgstr "%B: неочікуваний тип піÑÐ»Ñ ATN"
+
+#: ihex.c:230
+msgid "%B:%d: unexpected character `%s' in Intel Hex file"
+msgstr "%B:%d: неочікуваний Ñимвол «%s» у шіÑтнадцÑтковому файлі Intel"
+
+#: ihex.c:337
+msgid "%B:%u: bad checksum in Intel Hex file (expected %u, found %u)"
+msgstr "%B:%u: помилкова контрольна Ñума у шіÑтнадцÑтковому файлі Intel (очікувалоÑÑ %u, виÑвлено %u)"
+
+#: ihex.c:392
+msgid "%B:%u: bad extended address record length in Intel Hex file"
+msgstr "%B:%u: помилкова довжина запиÑу розширеної адреÑи у шіÑтнадцÑтковому файлі Intel"
+
+#: ihex.c:409
+msgid "%B:%u: bad extended start address length in Intel Hex file"
+msgstr "%B:%u: помилкова довжина розширеної початкової адреÑи у шіÑтнадцÑтковому файлі Intel"
+
+#: ihex.c:426
+msgid "%B:%u: bad extended linear address record length in Intel Hex file"
+msgstr "%B:%u: помилкова довжина запиÑу розширеної лінійної адреÑи у шіÑтнадцÑтковому файлі Intel"
+
+#: ihex.c:443
+msgid "%B:%u: bad extended linear start address length in Intel Hex file"
+msgstr "%B:%u: помилкова довжина розширеної лінійної початкової адреÑи у шіÑтнадцÑтковому файлі Intel"
+
+#: ihex.c:460
+msgid "%B:%u: unrecognized ihex type %u in Intel Hex file"
+msgstr "%B:%u: невідомий тип ihex %u у шіÑтнадцÑтковому файлі Intel"
+
+#: ihex.c:579
+msgid "%B: internal error in ihex_read_section"
+msgstr "%B: Ð²Ð½ÑƒÑ‚Ñ€Ñ–ÑˆÐ½Ñ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ° у ihex_read_section"
+
+#: ihex.c:613
+msgid "%B: bad section length in ihex_read_section"
+msgstr "%B: помилкова довжина розділу у ihex_read_section"
+
+#: ihex.c:826
+#, c-format
+msgid "%s: address 0x%s out of range for Intel Hex file"
+msgstr "%s: адреÑа 0x%s перебуває за межами шіÑтнадцÑткового файла Intel"
+
+#: libbfd.c:863
+msgid "%B: unable to get decompressed section %A"
+msgstr "%B: не вдалоÑÑ Ð¾Ñ‚Ñ€Ð¸Ð¼Ð°Ñ‚Ð¸ розпакований розділ %A"
+
+#: libbfd.c:1012
+msgid "%B: compiled for a big endian system and target is little endian"
+msgstr "%B: зібрано Ð´Ð»Ñ ÑиÑтеми з прÑмим порÑдком байтів, а призначеннÑм Ñ” ÑиÑтема зі зворотним порÑдком байтів"
+
+#: libbfd.c:1014
+msgid "%B: compiled for a little endian system and target is big endian"
+msgstr "%B: зібрано Ð´Ð»Ñ ÑиÑтеми зі зворотним порÑдком байтів, а призначеннÑм Ñ” ÑиÑтема зі прÑмим порÑдком байтів"
+
+#: libbfd.c:1043
+#, c-format
+msgid "Deprecated %s called at %s line %d in %s\n"
+msgstr "Викликано заÑтарілу %s у %s, Ñ€Ñдок %d у %s\n"
+
+#: libbfd.c:1046
+#, c-format
+msgid "Deprecated %s called\n"
+msgstr "Викликано заÑтарілу %s\n"
+
+#: linker.c:1872
+msgid "%B: indirect symbol `%s' to `%s' is a loop"
+msgstr "%B: опоÑередкований Ñимвол «%s» Ð´Ð»Ñ Â«%s» Ñ” циклом"
+
+#: linker.c:2736
+#, c-format
+msgid "Attempt to do relocatable link with %s input and %s output"
+msgstr "Спроба ÑÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ð·Ð²â€™Ñзку переÑÑƒÐ²Ð°Ð½Ð½Ñ Ð· вхідним %s Ñ– вихідним %s"
+
+#: linker.c:3021
+msgid "%B: ignoring duplicate section `%A'\n"
+msgstr "%B: ігноруємо дублікат розділу «%A»\n"
+
+#: linker.c:3030 linker.c:3039
+msgid "%B: duplicate section `%A' has different size\n"
+msgstr "%B: дублікат розділу «%A» має інший розмір\n"
+
+#: linker.c:3047 linker.c:3052
+msgid "%B: could not read contents of section `%A'\n"
+msgstr "%B: не вдалоÑÑ Ð¿Ñ€Ð¾Ñ‡Ð¸Ñ‚Ð°Ñ‚Ð¸ вміÑÑ‚ розділу «%A»\n"
+
+#: linker.c:3056
+msgid "%B: duplicate section `%A' has different contents\n"
+msgstr "%B: дублікат розділу «%A» має інший вміÑÑ‚\n"
+
+#: mach-o.c:407
+msgid "bfd_mach_o_canonicalize_symtab: unable to load symbols"
+msgstr "bfd_mach_o_canonicalize_symtab: не вдалоÑÑ Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶Ð¸Ñ‚Ð¸ Ñимволи"
+
+#: mach-o.c:1301
+#, c-format
+msgid "unable to write unknown load command 0x%lx"
+msgstr "не вдалоÑÑ Ð·Ð°Ð¿Ð¸Ñати невідому команду завантаженнÑ, 0x%lx"
+
+#: mach-o.c:1789
+#, c-format
+msgid "bfd_mach_o_read_symtab_symbol: unable to read %d bytes at %lu"
+msgstr "bfd_mach_o_read_symtab_symbol: не вдалоÑÑ Ð¿Ñ€Ð¾Ñ‡Ð¸Ñ‚Ð°Ñ‚Ð¸ %d байтів у %lu"
+
+#: mach-o.c:1807
+#, c-format
+msgid "bfd_mach_o_read_symtab_symbol: name out of range (%lu >= %lu)"
+msgstr "bfd_mach_o_read_symtab_symbol: назва за межами доÑтупного діапазону (%lu >= %lu)"
+
+#: mach-o.c:1892
+#, c-format
+msgid "bfd_mach_o_read_symtab_symbol: symbol \"%s\" specified invalid section %d (max %lu): setting to undefined"
+msgstr "bfd_mach_o_read_symtab_symbol: Ñимвол «%s» визначає некоректний розділ %d (max %lu): вÑтановлюємо у невизначене значеннÑ"
+
+#: mach-o.c:1900
+#, c-format
+msgid "bfd_mach_o_read_symtab_symbol: symbol \"%s\" is unsupported 'indirect' reference: setting to undefined"
+msgstr "bfd_mach_o_read_symtab_symbol: Ñимвол «%s» Ñ” непідтримуваним поÑиланнÑм «indirect»: вÑтановлюємо у невизначене значеннÑ"
+
+#: mach-o.c:1906
+#, c-format
+msgid "bfd_mach_o_read_symtab_symbol: symbol \"%s\" specified invalid type field 0x%x: setting to undefined"
+msgstr "bfd_mach_o_read_symtab_symbol: Ñимвол «%s» визначає некоректний тип Ð¿Ð¾Ð»Ñ 0x%x: вÑтановлюємо у невизначене значеннÑ"
+
+#: mach-o.c:1979
+msgid "bfd_mach_o_read_symtab_symbols: unable to allocate memory for symbols"
+msgstr "bfd_mach_o_read_symtab_symbols: не вдалоÑÑ Ð¾Ñ‚Ñ€Ð¸Ð¼Ð°Ñ‚Ð¸ облаÑÑ‚ÑŒ пам’ÑÑ‚Ñ– Ð´Ð»Ñ Ñимволів"
+
+#: mach-o.c:2014
+#, c-format
+msgid "bfd_mach_o_read_dysymtab_symbol: unable to read %lu bytes at %lu"
+msgstr "bfd_mach_o_read_dysymtab_symbol: не вдалоÑÑ Ð¿Ñ€Ð¾Ñ‡Ð¸Ñ‚Ð°Ñ‚Ð¸ %lu байтів з %lu"
+
+#: mach-o.c:2734
+#, c-format
+msgid "unable to read unknown load command 0x%lx"
+msgstr "не вдалоÑÑ Ð¿Ñ€Ð¾Ñ‡Ð¸Ñ‚Ð°Ñ‚Ð¸ невідому команду завантаженнÑ, 0x%lx"
+
+#: mach-o.c:2915
+#, c-format
+msgid "bfd_mach_o_scan: unknown architecture 0x%lx/0x%lx"
+msgstr "bfd_mach_o_scan: невідома архітектура, 0x%lx/0x%lx"
+
+#: mach-o.c:3011
+#, c-format
+msgid "unknown header byte-order value 0x%lx"
+msgstr "невідоме Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð¿Ð¾Ñ€Ñдку байтів у заголовку, 0x%lx"
+
+#: mach-o.c:3577
+msgid "Mach-O header:\n"
+msgstr "заголовок Mach-O:\n"
+
+#: mach-o.c:3578
+#, c-format
+msgid " magic : %08lx\n"
+msgstr " magic : %08lx\n"
+
+#: mach-o.c:3579
+#, c-format
+msgid " cputype : %08lx (%s)\n"
+msgstr " тип проц. : %08lx (%s)\n"
+
+#: mach-o.c:3581
+#, c-format
+msgid " cpusubtype: %08lx\n"
+msgstr " підтип проц.: %08lx\n"
+
+#: mach-o.c:3582
+#, c-format
+msgid " filetype : %08lx (%s)\n"
+msgstr " тип файла : %08lx (%s)\n"
+
+#: mach-o.c:3585
+#, c-format
+msgid " ncmds : %08lx (%lu)\n"
+msgstr " кть_команд: %08lx (%lu)\n"
+
+#: mach-o.c:3586
+#, c-format
+msgid " sizeofcmds: %08lx\n"
+msgstr " розмір_кмд: %08lx\n"
+
+#: mach-o.c:3587
+#, c-format
+msgid " flags : %08lx ("
+msgstr " прапорці : %08lx ("
+
+#: mach-o.c:3589 vms-alpha.c:7674
+msgid ")\n"
+msgstr ")\n"
+
+#: mach-o.c:3590
+#, c-format
+msgid " reserved : %08x\n"
+msgstr " зарезерв. : %08x\n"
+
+#: mach-o.c:3600
+msgid "Segments and Sections:\n"
+msgstr "Сегменти і розділи:\n"
+
+#: mach-o.c:3601
+msgid " #: Segment name Section name Address\n"
+msgstr " #: Ðазва Ñегмента Ðазва розділу ÐдреÑа\n"
+
+#: merge.c:832
+#, c-format
+msgid "%s: access beyond end of merged section (%ld)"
+msgstr "%s: доÑтуп за кінцем об’єднаного розділу (%ld)"
+
+#: mmo.c:456
+#, c-format
+msgid "%s: No core to allocate section name %s\n"
+msgstr "%s: немає оÑнови Ð´Ð»Ñ Ð¾Ñ‚Ñ€Ð¸Ð¼Ð°Ð½Ð½Ñ Ð½Ð°Ð·Ð²Ð¸ розділу %s\n"
+
+#: mmo.c:531
+#, c-format
+msgid "%s: No core to allocate a symbol %d bytes long\n"
+msgstr "%s: немає оÑнови Ð´Ð»Ñ Ð¾Ñ‚Ñ€Ð¸Ð¼Ð°Ð½Ð½Ñ Ñимволу довжиною %d байтів\n"
+
+#: mmo.c:1187
+#, c-format
+msgid "%s: invalid mmo file: initialization value for $255 is not `Main'\n"
+msgstr "%s: некоректний файл mmo: Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ñ–Ð½Ñ–Ñ†Ñ–Ð°Ð»Ñ–Ð·Ð°Ñ†Ñ–Ñ— Ð´Ð»Ñ $255 не дорівнює «Main»\n"
+
+#: mmo.c:1332
+#, c-format
+msgid "%s: unsupported wide character sequence 0x%02X 0x%02X after symbol name starting with `%s'\n"
+msgstr "%s: непідтримувана широка поÑлідовніÑÑ‚ÑŒ Ñимволів 0x%02X 0x%02X піÑÐ»Ñ Ð½Ð°Ð·Ð²Ð¸ Ñимволу, починаючи з «%s»\n"
+
+#: mmo.c:1565
+#, c-format
+msgid "%s: invalid mmo file: unsupported lopcode `%d'\n"
+msgstr "%s: некоректний файл mmo: непідтримуване Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ lopcode, «%d»\n"
+
+#: mmo.c:1575
+#, c-format
+msgid "%s: invalid mmo file: expected YZ = 1 got YZ = %d for lop_quote\n"
+msgstr "%s: некоректний файл mmo: очікувалоÑÑ YZ = 1, отримано YZ = %d Ð´Ð»Ñ lop_quote\n"
+
+#: mmo.c:1611
+#, c-format
+msgid "%s: invalid mmo file: expected z = 1 or z = 2, got z = %d for lop_loc\n"
+msgstr "%s: некоректний файл mmo: очікувалоÑÑ z = 1 або z = 2, отримано z = %d Ð´Ð»Ñ lop_loc\n"
+
+#: mmo.c:1657
+#, c-format
+msgid "%s: invalid mmo file: expected z = 1 or z = 2, got z = %d for lop_fixo\n"
+msgstr "%s: некоректний файл mmo: очікувалоÑÑ z = 1 або z = 2, отримано z = %d Ð´Ð»Ñ lop_fixo\n"
+
+#: mmo.c:1696
+#, c-format
+msgid "%s: invalid mmo file: expected y = 0, got y = %d for lop_fixrx\n"
+msgstr "%s: некоректний файл mmo: очікувалоÑÑ y=0, отримано y = %d Ð´Ð»Ñ lop_fixrx\n"
+
+#: mmo.c:1705
+#, c-format
+msgid "%s: invalid mmo file: expected z = 16 or z = 24, got z = %d for lop_fixrx\n"
+msgstr "%s: некоректний файл mmo: очікувалоÑÑ z = 16 або z = 24, отримано z = %d Ð´Ð»Ñ lop_fixrx\n"
+
+#: mmo.c:1728
+#, c-format
+msgid "%s: invalid mmo file: leading byte of operand word must be 0 or 1, got %d for lop_fixrx\n"
+msgstr "%s: некоректний файл mmo: початковим байтом Ñлова оператора має бути 0 або 1, отримано ж %d Ð´Ð»Ñ lop_fixrx\n"
+
+#: mmo.c:1751
+#, c-format
+msgid "%s: cannot allocate file name for file number %d, %d bytes\n"
+msgstr "%s: не вдалоÑÑ Ñ€Ð¾Ð·Ð¼Ñ–Ñтити назву файла Ð´Ð»Ñ Ñ„Ð°Ð¹Ð»Ð° з номером %d, %d байтів\n"
+
+#: mmo.c:1771
+#, c-format
+msgid "%s: invalid mmo file: file number %d `%s', was already entered as `%s'\n"
+msgstr "%s: некоректний файл mmo: номер файла %d, «%s», уже здійÑнено вхід Ñк у «%s»\n"
+
+#: mmo.c:1784
+#, c-format
+msgid "%s: invalid mmo file: file name for number %d was not specified before use\n"
+msgstr "%s: некоректний файл mmo: назву файла Ð´Ð»Ñ Ð½Ð¾Ð¼ÐµÑ€Ð° %d не було вказано до викориÑтаннÑ\n"
+
+#: mmo.c:1890
+#, c-format
+msgid "%s: invalid mmo file: fields y and z of lop_stab non-zero, y: %d, z: %d\n"
+msgstr "%s: некоректний файл mmo: Ð¿Ð¾Ð»Ñ y Ñ– z lop_stab Ñ” ненульовими, y: %d, z: %d\n"
+
+#: mmo.c:1926
+#, c-format
+msgid "%s: invalid mmo file: lop_end not last item in file\n"
+msgstr "%s: некоректний файл mmo: lop_end не Ñ” оÑтаннім запиÑом у файлі\n"
+
+#: mmo.c:1939
+#, c-format
+msgid "%s: invalid mmo file: YZ of lop_end (%ld) not equal to the number of tetras to the preceding lop_stab (%ld)\n"
+msgstr "%s: некоректний файл mmo: YZ lop_end (%ld) не дорівнює кількоÑÑ‚Ñ– тетрад до попереднього lop_stab (%ld)\n"
+
+#: mmo.c:2649
+#, c-format
+msgid "%s: invalid symbol table: duplicate symbol `%s'\n"
+msgstr "%s: некоректна Ñ‚Ð°Ð±Ð»Ð¸Ñ†Ñ Ñимволів: Ð´ÑƒÐ±Ð»ÑŽÐ²Ð°Ð½Ð½Ñ Ñимволу «%s»\n"
+
+#: mmo.c:2889
+#, c-format
+msgid "%s: Bad symbol definition: `Main' set to %s rather than the start address %s\n"
+msgstr "%s: помилкове Ð²Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ñимволу: «Main» вÑтановлено у %s, а не у початкову адреÑу %s\n"
+
+#: mmo.c:2981
+#, c-format
+msgid "%s: warning: symbol table too large for mmo, larger than 65535 32-bit words: %d. Only `Main' will be emitted.\n"
+msgstr "%s: попередженнÑ: Ñ‚Ð°Ð±Ð»Ð¸Ñ†Ñ Ñимволів Ñ” надто великою Ð´Ð»Ñ mmo, Ñ—Ñ— розмір перевищує 65535 32-бітових Ñлова: %d. Буде випущено лише «Main».\n"
+
+#: mmo.c:3026
+#, c-format
+msgid "%s: internal error, symbol table changed size from %d to %d words\n"
+msgstr "%s: Ð²Ð½ÑƒÑ‚Ñ€Ñ–ÑˆÐ½Ñ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ°, змінено розмір таблиці Ñимволів з %d до %d Ñлів\n"
+
+#: mmo.c:3078
+#, c-format
+msgid "%s: internal error, internal register section %s had contents\n"
+msgstr "%s: Ð²Ð½ÑƒÑ‚Ñ€Ñ–ÑˆÐ½Ñ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ°, внутрішній розділ регіÑтрів, %s, міÑтив дані\n"
+
+#: mmo.c:3129
+#, c-format
+msgid "%s: no initialized registers; section length 0\n"
+msgstr "%s: немає ініціалізованих регіÑтрів, довжина розділу дорівнює 0\n"
+
+#: mmo.c:3135
+#, c-format
+msgid "%s: too many initialized registers; section length %ld\n"
+msgstr "%s: занадто багато ініціалізованих регіÑтрів; довжина розділу — %ld\n"
+
+#: mmo.c:3140
+#, c-format
+msgid "%s: invalid start address for initialized registers of length %ld: 0x%lx%08lx\n"
+msgstr "%s: некоректна початкова адреÑа Ð´Ð»Ñ Ñ–Ð½Ñ–Ñ†Ñ–Ð°Ð»Ñ–Ð·Ð¾Ð²Ð°Ð½Ð¸Ñ… регіÑтрів довжини %ld: 0x%lx%08lx\n"
+
+#: oasys.c:882
+#, c-format
+msgid "%s: can not represent section `%s' in oasys"
+msgstr "%s: Ð²Ñ–Ð´Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ñ€Ð¾Ð·Ð´Ñ–Ð»Ñƒ «%s» у форматі oasys неможливе"
+
+#: osf-core.c:140
+#, c-format
+msgid "Unhandled OSF/1 core file section type %d\n"
+msgstr "Ðепридатни до обробки тип розділу файла core OSF/1, %d\n"
+
+#: pe-mips.c:607
+msgid "%B: `ld -r' not supported with PE MIPS objects\n"
+msgstr "%B: підтримки «ld -r» з об’єктами PE MIPS не передбачено\n"
+
+#. OK, at this point the following variables are set up:
+#. src = VMA of the memory we're fixing up
+#. mem = pointer to memory we're fixing up
+#. val = VMA of what we need to refer to.
+#: pe-mips.c:719
+msgid "%B: unimplemented %s\n"
+msgstr "%B: нереалізований %s\n"
+
+#: pe-mips.c:745
+msgid "%B: jump too far away\n"
+msgstr "%B: занадто далекий перехід\n"
+
+#: pe-mips.c:771
+msgid "%B: bad pair/reflo after refhi\n"
+msgstr "%B: помилкове pair/reflo піÑÐ»Ñ refhi\n"
+
+#: pef.c:520
+#, c-format
+msgid "bfd_pef_scan: unknown architecture 0x%lx"
+msgstr "bfd_pef_scan: невідома архітектура, 0x%lx"
+
+#: pei-x86_64.c:444
+#, c-format
+msgid "warning: .pdata section size (%ld) is not a multiple of %d\n"
+msgstr "попередженнÑ: розмір розділу .pdata (%ld) не Ñ” кратним до %d\n"
+
+#: pei-x86_64.c:448 peigen.c:1618 peigen.c:1801 pepigen.c:1618 pepigen.c:1801
+#: pex64igen.c:1618 pex64igen.c:1801
+#, c-format
+msgid ""
+"\n"
+"The Function Table (interpreted .pdata section contents)\n"
+msgstr ""
+"\n"
+"Ð¢Ð°Ð±Ð»Ð¸Ñ†Ñ Ñ„ÑƒÐ½ÐºÑ†Ñ–Ð¹ (оброблений вміÑÑ‚ розділу .pdata)\n"
+
+#: pei-x86_64.c:450
+#, c-format
+msgid "vma:\t\t\tBeginAddress\t EndAddress\t UnwindData\n"
+msgstr "vma:\t\t\tПочаткÐдреÑа\t КінцÐдреÑаs\t ДаніUnwind\n"
+
+#. XXX code yet to be written.
+#: peicode.h:751
+msgid "%B: Unhandled import type; %x"
+msgstr "%B: непридатний до обробки тип імпортуваннÑ; %x"
+
+#: peicode.h:756
+msgid "%B: Unrecognised import type; %x"
+msgstr "%B: нерозпізнаний тип імпортуваннÑ; %x"
+
+#: peicode.h:770
+msgid "%B: Unrecognised import name type; %x"
+msgstr "%B: нерозпізнана назва імпортуваннÑ; %x"
+
+#: peicode.h:1166
+msgid "%B: Unrecognised machine type (0x%x) in Import Library Format archive"
+msgstr "%B: нерозпізнаний тип архітектури (0x%x) у архіві Import Library Format"
+
+#: peicode.h:1178
+msgid "%B: Recognised but unhandled machine type (0x%x) in Import Library Format archive"
+msgstr "%B: розпізнаний, але непридатний до обробки тип архітектури (0x%x) у архіві Import Library Format"
+
+#: peicode.h:1196
+msgid "%B: size field is zero in Import Library Format header"
+msgstr "%B: у заголовку Import Library Format поле розміру є нульовим"
+
+#: peicode.h:1227
+msgid "%B: string not null terminated in ILF object file."
+msgstr "%B: у об’єктному файлі ILF Ñ€Ñдок не завершуєтьÑÑ Ð½ÑƒÐ»ÑŒÐ¾Ð²Ð¸Ð¼ Ñимволом."
+
+#: ppcboot.c:414
+#, c-format
+msgid ""
+"\n"
+"ppcboot header:\n"
+msgstr ""
+"\n"
+"Заголовок ppcboot:\n"
+
+#: ppcboot.c:415
+#, c-format
+msgid "Entry offset = 0x%.8lx (%ld)\n"
+msgstr "ВідÑтуп входу = 0x%.8lx (%ld)\n"
+
+#: ppcboot.c:417
+#, c-format
+msgid "Length = 0x%.8lx (%ld)\n"
+msgstr "Довжина = 0x%.8lx (%ld)\n"
+
+#: ppcboot.c:421
+#, c-format
+msgid "Flag field = 0x%.2x\n"
+msgstr "Поле прапорців = 0x%.2x\n"
+
+#: ppcboot.c:427
+#, c-format
+msgid "Partition name = \"%s\"\n"
+msgstr "Ðазва розділу = \"%s\"\n"
+
+#: ppcboot.c:446
+#, c-format
+msgid ""
+"\n"
+"Partition[%d] start = { 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x }\n"
+msgstr ""
+"\n"
+"Початок розділу[%d] = { 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x }\n"
+
+#: ppcboot.c:452
+#, c-format
+msgid "Partition[%d] end = { 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x }\n"
+msgstr "Кінець розділу[%d] = { 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x }\n"
+
+#: ppcboot.c:458
+#, c-format
+msgid "Partition[%d] sector = 0x%.8lx (%ld)\n"
+msgstr "Сектор розділу[%d] = 0x%.8lx (%ld)\n"
+
+#: ppcboot.c:460
+#, c-format
+msgid "Partition[%d] length = 0x%.8lx (%ld)\n"
+msgstr "Довжина розділу[%d] = 0x%.8lx (%ld)\n"
+
+#: reloc.c:6160
+msgid "INPUT_SECTION_FLAGS are not supported.\n"
+msgstr "Підтримки INPUT_SECTION_FLAGS не передбачено.\n"
+
+#: rs6000-core.c:448
+#, c-format
+msgid "%s: warning core file truncated"
+msgstr "%s: попередженнÑ: файл core обрізано"
+
+#: som.c:5471
+#, c-format
+msgid ""
+"\n"
+"Exec Auxiliary Header\n"
+msgstr ""
+"\n"
+"Допоміжний заголовок виконаннÑ\n"
+
+#: som.c:5776
+msgid "som_sizeof_headers unimplemented"
+msgstr "som_sizeof_headers не реалізовано"
+
+#: srec.c:261
+msgid "%B:%d: Unexpected character `%s' in S-record file\n"
+msgstr "%B:%d: неочікуваний Ñимвол «%s» у файлі запиÑів S\n"
+
+#: srec.c:567 srec.c:600
+msgid "%B:%d: Bad checksum in S-record file\n"
+msgstr "%B:%d: помилкова контрольна Ñума у файлі запиÑів S\n"
+
+#: stabs.c:279
+msgid "%B(%A+0x%lx): Stabs entry has invalid string index."
+msgstr "%B(%A+0x%lx): Ð·Ð°Ð¿Ð¸Ñ Ñ‚Ð°Ð±Ð»Ð¸Ñ†Ñ– stabs міÑтить некоректний Ñ–Ð½Ð´ÐµÐºÑ Ñ€Ñдка."
+
+#: syms.c:1079
+msgid "Unsupported .stab relocation"
+msgstr "Ðепідтримуване переÑÑƒÐ²Ð°Ð½Ð½Ñ .stab"
+
+#: vms-alpha.c:1299
+#, c-format
+msgid "Unknown EGSD subtype %d"
+msgstr "Ðевідомий підтип EGSD, %d"
+
+#: vms-alpha.c:1330
+#, c-format
+msgid "Stack overflow (%d) in _bfd_vms_push"
+msgstr "ÐŸÐµÑ€ÐµÐ¿Ð¾Ð²Ð½ÐµÐ½Ð½Ñ Ñтека (%d) у _bfd_vms_push"
+
+#: vms-alpha.c:1343
+msgid "Stack underflow in _bfd_vms_pop"
+msgstr "ÐŸÐµÑ€ÐµÐ¿Ð¾Ð²Ð½ÐµÐ½Ð½Ñ Ñтека у _bfd_vms_pop"
+
+#. These names have not yet been added to this switch statement.
+#: vms-alpha.c:1580
+#, c-format
+msgid "unknown ETIR command %d"
+msgstr "невідома команда ETIR, %d"
+
+#: vms-alpha.c:1767
+#, c-format
+msgid "bad section index in %s"
+msgstr "помилковий номер розділу у %s"
+
+#: vms-alpha.c:1780
+#, c-format
+msgid "unsupported STA cmd %s"
+msgstr "непідтримувана команда STA, %s"
+
+#. Insert field.
+#. Unsigned shift.
+#. Rotate.
+#. Redefine symbol to current location.
+#. Define a literal.
+#: vms-alpha.c:1956 vms-alpha.c:1987 vms-alpha.c:2234
+#, c-format
+msgid "%s: not supported"
+msgstr "%s: підтримки не передбачено"
+
+#: vms-alpha.c:1962
+#, c-format
+msgid "%s: not implemented"
+msgstr "%s: не реалізовано"
+
+#: vms-alpha.c:2218
+#, c-format
+msgid "invalid use of %s with contexts"
+msgstr "некоректне викориÑÑ‚Ð°Ð½Ð½Ñ %s з контекÑтами"
+
+#: vms-alpha.c:2252
+#, c-format
+msgid "reserved cmd %d"
+msgstr "зарезервована команда %d"
+
+#: vms-alpha.c:2337
+msgid "Object module NOT error-free !\n"
+msgstr "У об’єктному модулі міÑÑ‚ÑÑ‚ÑŒÑÑ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ¸!\n"
+
+#: vms-alpha.c:2766
+#, c-format
+msgid "Symbol %s replaced by %s\n"
+msgstr "Символ %s замінено на %s\n"
+
+#: vms-alpha.c:3769
+#, c-format
+msgid "SEC_RELOC with no relocs in section %s"
+msgstr "SEC_RELOC без переÑувань у розділі %s"
+
+#: vms-alpha.c:3822 vms-alpha.c:4049
+#, c-format
+msgid "Size error in section %s"
+msgstr "Помилка у розмірі у розділі %s"
+
+#: vms-alpha.c:3991
+msgid "Spurious ALPHA_R_BSR reloc"
+msgstr "Фальшиве переÑÑƒÐ²Ð°Ð½Ð½Ñ ALPHA_R_BSR"
+
+#: vms-alpha.c:4036
+#, c-format
+msgid "Unhandled relocation %s"
+msgstr "Ðепридатне до обробки переÑÑƒÐ²Ð°Ð½Ð½Ñ %s"
+
+#: vms-alpha.c:4326
+#, c-format
+msgid "unknown source command %d"
+msgstr "невідома початкова команда %d"
+
+#: vms-alpha.c:4387
+msgid "DST__K_SET_LINUM_INCR not implemented"
+msgstr "DST__K_SET_LINUM_INCR не реалізовано"
+
+#: vms-alpha.c:4393
+msgid "DST__K_SET_LINUM_INCR_W not implemented"
+msgstr "DST__K_SET_LINUM_INCR_W не реалізовано"
+
+#: vms-alpha.c:4399
+msgid "DST__K_RESET_LINUM_INCR not implemented"
+msgstr "DST__K_RESET_LINUM_INCR не реалізовано"
+
+#: vms-alpha.c:4405
+msgid "DST__K_BEG_STMT_MODE not implemented"
+msgstr "DST__K_BEG_STMT_MODE не реалізовано"
+
+#: vms-alpha.c:4411
+msgid "DST__K_END_STMT_MODE not implemented"
+msgstr "DST__K_END_STMT_MODE не реалізовано"
+
+#: vms-alpha.c:4438
+msgid "DST__K_SET_PC not implemented"
+msgstr "DST__K_SET_PC не реалізовано"
+
+#: vms-alpha.c:4444
+msgid "DST__K_SET_PC_W not implemented"
+msgstr "DST__K_SET_PC_W не реалізовано"
+
+#: vms-alpha.c:4450
+msgid "DST__K_SET_PC_L not implemented"
+msgstr "DST__K_SET_PC_L не реалізовано"
+
+#: vms-alpha.c:4456
+msgid "DST__K_SET_STMTNUM not implemented"
+msgstr "DST__K_SET_STMTNUM не реалізовано"
+
+#: vms-alpha.c:4499
+#, c-format
+msgid "unknown line command %d"
+msgstr "невідома Ñ€Ñдкова команда %d"
+
+#: vms-alpha.c:4953 vms-alpha.c:4970 vms-alpha.c:4984 vms-alpha.c:4999
+#: vms-alpha.c:5011 vms-alpha.c:5022 vms-alpha.c:5034
+#, c-format
+msgid "Unknown reloc %s + %s"
+msgstr "Ðевідоме переÑÑƒÐ²Ð°Ð½Ð½Ñ %s + %s"
+
+#: vms-alpha.c:5089
+#, c-format
+msgid "Unknown reloc %s"
+msgstr "Ðевідоме переÑÑƒÐ²Ð°Ð½Ð½Ñ %s"
+
+#: vms-alpha.c:5102
+msgid "Invalid section index in ETIR"
+msgstr "Ðекоректний номер розділу у ETIR"
+
+#: vms-alpha.c:5109
+msgid "Relocation for non-REL psect"
+msgstr "ПереÑÑƒÐ²Ð°Ð½Ð½Ñ Ð´Ð»Ñ psect, Ñкий не Ñ” REL"
+
+#: vms-alpha.c:5156
+#, c-format
+msgid "Unknown symbol in command %s"
+msgstr "Ðевідомий Ñимвол у команді %s"
+
+#: vms-alpha.c:5671
+#, c-format
+msgid " EMH %u (len=%u): "
+msgstr " EMH %u (довж=%u): "
+
+#: vms-alpha.c:5680
+#, c-format
+msgid "Module header\n"
+msgstr "Заголовок модулÑ\n"
+
+#: vms-alpha.c:5681
+#, c-format
+msgid " structure level: %u\n"
+msgstr " рівень Ñтрукт. : %u\n"
+
+#: vms-alpha.c:5682
+#, c-format
+msgid " max record size: %u\n"
+msgstr " макÑ. розм. запиÑу: %u\n"
+
+#: vms-alpha.c:5685
+#, c-format
+msgid " module name : %.*s\n"
+msgstr " назва Ð¼Ð¾Ð´ÑƒÐ»Ñ : %.*s\n"
+
+#: vms-alpha.c:5687
+#, c-format
+msgid " module version : %.*s\n"
+msgstr " верÑÑ–Ñ Ð¼Ð¾Ð´ÑƒÐ»Ñ : %.*s\n"
+
+#: vms-alpha.c:5689
+#, c-format
+msgid " compile date : %.17s\n"
+msgstr " дата Ð·Ð±Ð¸Ñ€Ð°Ð½Ð½Ñ : %.17s\n"
+
+#: vms-alpha.c:5694
+#, c-format
+msgid "Language Processor Name\n"
+msgstr "Ðазва обробника мови\n"
+
+#: vms-alpha.c:5695
+#, c-format
+msgid " language name: %.*s\n"
+msgstr " назва мови : %.*s\n"
+
+#: vms-alpha.c:5702
+#, c-format
+msgid "Source Files Header\n"
+msgstr "Заголовок файлів коду\n"
+
+#: vms-alpha.c:5703
+#, c-format
+msgid " file: %.*s\n"
+msgstr " файл: %.*s\n"
+
+#: vms-alpha.c:5710
+#, c-format
+msgid "Title Text Header\n"
+msgstr "Заголовок титульного текÑту\n"
+
+#: vms-alpha.c:5711
+#, c-format
+msgid " title: %.*s\n"
+msgstr " заголовок: %.*s\n"
+
+#: vms-alpha.c:5718
+#, c-format
+msgid "Copyright Header\n"
+msgstr "Заголовок авторÑьких прав\n"
+
+#: vms-alpha.c:5719
+#, c-format
+msgid " copyright: %.*s\n"
+msgstr " авторÑькі права: %.*s\n"
+
+#: vms-alpha.c:5725
+#, c-format
+msgid "unhandled emh subtype %u\n"
+msgstr "непридатний до обробки підтип emh, %u\n"
+
+#: vms-alpha.c:5735
+#, c-format
+msgid " EEOM (len=%u):\n"
+msgstr " EEOM (довж=%u):\n"
+
+#: vms-alpha.c:5736
+#, c-format
+msgid " number of cond linkage pairs: %u\n"
+msgstr " кількіÑÑ‚ÑŒ пар умовного компонуваннÑ: %u\n"
+
+#: vms-alpha.c:5738
+#, c-format
+msgid " completion code: %u\n"
+msgstr " код завершеннÑ: %u\n"
+
+#: vms-alpha.c:5742
+#, c-format
+msgid " transfer addr flags: 0x%02x\n"
+msgstr " прапорці Ð¿ÐµÑ€ÐµÐ´Ð°Ð²Ð°Ð½Ð½Ñ Ð°Ð´Ñ€ÐµÑи: 0x%02x\n"
+
+#: vms-alpha.c:5743
+#, c-format
+msgid " transfer addr psect: %u\n"
+msgstr " psect Ð¿ÐµÑ€ÐµÐ´Ð°Ð²Ð°Ð½Ð½Ñ Ð°Ð´Ñ€ÐµÑи: %u\n"
+
+#: vms-alpha.c:5745
+#, c-format
+msgid " transfer address : 0x%08x\n"
+msgstr " адреÑа перенеÑÐµÐ½Ð½Ñ : 0x%08x\n"
+
+#: vms-alpha.c:5754
+msgid " WEAK"
+msgstr " WEAK"
+
+#: vms-alpha.c:5756
+msgid " DEF"
+msgstr " DEF"
+
+#: vms-alpha.c:5758
+msgid " UNI"
+msgstr " UNI"
+
+#: vms-alpha.c:5760 vms-alpha.c:5781
+msgid " REL"
+msgstr " REL"
+
+#: vms-alpha.c:5762
+msgid " COMM"
+msgstr " COMM"
+
+#: vms-alpha.c:5764
+msgid " VECEP"
+msgstr " VECEP"
+
+#: vms-alpha.c:5766
+msgid " NORM"
+msgstr " NORM"
+
+#: vms-alpha.c:5768
+msgid " QVAL"
+msgstr " QVAL"
+
+#: vms-alpha.c:5775
+msgid " PIC"
+msgstr " PIC"
+
+#: vms-alpha.c:5777
+msgid " LIB"
+msgstr " LIB"
+
+#: vms-alpha.c:5779
+msgid " OVR"
+msgstr " OVR"
+
+#: vms-alpha.c:5783
+msgid " GBL"
+msgstr " GBL"
+
+#: vms-alpha.c:5785
+msgid " SHR"
+msgstr " SHR"
+
+#: vms-alpha.c:5787
+msgid " EXE"
+msgstr " EXE"
+
+#: vms-alpha.c:5789
+msgid " RD"
+msgstr " RD"
+
+#: vms-alpha.c:5791
+msgid " WRT"
+msgstr " WRT"
+
+#: vms-alpha.c:5793
+msgid " VEC"
+msgstr " VEC"
+
+#: vms-alpha.c:5795
+msgid " NOMOD"
+msgstr " NOMOD"
+
+#: vms-alpha.c:5797
+msgid " COM"
+msgstr " COM"
+
+#: vms-alpha.c:5799
+msgid " 64B"
+msgstr " 64B"
+
+#: vms-alpha.c:5808
+#, c-format
+msgid " EGSD (len=%u):\n"
+msgstr " EGSD (довж=%u):\n"
+
+#: vms-alpha.c:5820
+#, c-format
+msgid " EGSD entry %2u (type: %u, len: %u): "
+msgstr " Ð·Ð°Ð¿Ð¸Ñ EGSD %2u (тип: %u, довж: %u): "
+
+#: vms-alpha.c:5832
+#, c-format
+msgid "PSC - Program section definition\n"
+msgstr "PSC — Ð²Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ñ€Ð¾Ð·Ð´Ñ–Ð»Ñƒ програми\n"
+
+#: vms-alpha.c:5833 vms-alpha.c:5850
+#, c-format
+msgid " alignment : 2**%u\n"
+msgstr " вирівнюваннÑ: 2**%u\n"
+
+#: vms-alpha.c:5834 vms-alpha.c:5851
+#, c-format
+msgid " flags : 0x%04x"
+msgstr " прапорці : 0x%04x"
+
+#: vms-alpha.c:5838
+#, c-format
+msgid " alloc (len): %u (0x%08x)\n"
+msgstr " alloc (довжина): %u (0x%08x)\n"
+
+#: vms-alpha.c:5839 vms-alpha.c:5896 vms-alpha.c:5945
+#, c-format
+msgid " name : %.*s\n"
+msgstr " назва : %.*s\n"
+
+#: vms-alpha.c:5849
+#, c-format
+msgid "SPSC - Shared Image Program section def\n"
+msgstr "SPSC — Ð²Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð¿Ñ€Ð¾Ð³Ñ€Ð°Ð¼Ð½Ð¾Ð³Ð¾ розділу Ñпільного образу\n"
+
+#: vms-alpha.c:5855
+#, c-format
+msgid " alloc (len) : %u (0x%08x)\n"
+msgstr " alloc (довжина): %u (0x%08x)\n"
+
+#: vms-alpha.c:5856
+#, c-format
+msgid " image offset : 0x%08x\n"
+msgstr " відÑтуп образу: 0x%08x\n"
+
+#: vms-alpha.c:5858
+#, c-format
+msgid " symvec offset : 0x%08x\n"
+msgstr " зÑув symvec : 0x%08x\n"
+
+#: vms-alpha.c:5860
+#, c-format
+msgid " name : %.*s\n"
+msgstr " назва : %.*s\n"
+
+#: vms-alpha.c:5873
+#, c-format
+msgid "SYM - Global symbol definition\n"
+msgstr "SYM — Ð²Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð·Ð°Ð³Ð°Ð»ÑŒÐ½Ð¸Ñ… Ñимволів\n"
+
+#: vms-alpha.c:5874 vms-alpha.c:5934 vms-alpha.c:5955 vms-alpha.c:5974
+#, c-format
+msgid " flags: 0x%04x"
+msgstr " прапорці: 0x%04x"
+
+#: vms-alpha.c:5877
+#, c-format
+msgid " psect offset: 0x%08x\n"
+msgstr " відÑтуп psect: 0x%08x\n"
+
+#: vms-alpha.c:5881
+#, c-format
+msgid " code address: 0x%08x\n"
+msgstr " адреÑа коду: 0x%08x\n"
+
+#: vms-alpha.c:5883
+#, c-format
+msgid " psect index for entry point : %u\n"
+msgstr " Ñ–Ð½Ð´ÐµÐºÑ psect Ð´Ð»Ñ Ñ‚Ð¾Ñ‡ÐºÐ¸ входженнÑ: %u\n"
+
+#: vms-alpha.c:5886 vms-alpha.c:5962 vms-alpha.c:5981
+#, c-format
+msgid " psect index : %u\n"
+msgstr " Ñ–Ð½Ð´ÐµÐºÑ psect: %u\n"
+
+#: vms-alpha.c:5888 vms-alpha.c:5964 vms-alpha.c:5983
+#, c-format
+msgid " name : %.*s\n"
+msgstr " назва : %.*s\n"
+
+#: vms-alpha.c:5895
+#, c-format
+msgid "SYM - Global symbol reference\n"
+msgstr "SYM — поÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð½Ð° загальні Ñимволи\n"
+
+#: vms-alpha.c:5907
+#, c-format
+msgid "IDC - Ident Consistency check\n"
+msgstr "IDC — перевірка коректноÑÑ‚Ñ– ідентифікаторів\n"
+
+#: vms-alpha.c:5908
+#, c-format
+msgid " flags : 0x%08x"
+msgstr " прапорці : 0x%08x"
+
+#: vms-alpha.c:5912
+#, c-format
+msgid " id match : %x\n"
+msgstr " ід. відповідноÑÑ‚Ñ–: %x\n"
+
+#: vms-alpha.c:5914
+#, c-format
+msgid " error severity: %x\n"
+msgstr " критичніÑÑ‚ÑŒ помилки: %x\n"
+
+#: vms-alpha.c:5917
+#, c-format
+msgid " entity name : %.*s\n"
+msgstr " назва елемента: %.*s\n"
+
+#: vms-alpha.c:5919
+#, c-format
+msgid " object name : %.*s\n"
+msgstr " назва об’єкта : %.*s\n"
+
+#: vms-alpha.c:5922
+#, c-format
+msgid " binary ident : 0x%08x\n"
+msgstr " двійк. ідент. : 0x%08x\n"
+
+#: vms-alpha.c:5925
+#, c-format
+msgid " ascii ident : %.*s\n"
+msgstr " ідент. ascii : %.*s\n"
+
+#: vms-alpha.c:5933
+#, c-format
+msgid "SYMG - Universal symbol definition\n"
+msgstr "SYMG — УніверÑальне Ð²Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ñимволів\n"
+
+#: vms-alpha.c:5937
+#, c-format
+msgid " symbol vector offset: 0x%08x\n"
+msgstr " зÑув вектора Ñимволів: 0x%08x\n"
+
+#: vms-alpha.c:5939
+#, c-format
+msgid " entry point: 0x%08x\n"
+msgstr " точка входу: 0x%08x\n"
+
+#: vms-alpha.c:5941
+#, c-format
+msgid " proc descr : 0x%08x\n"
+msgstr " деÑкр. процеÑу: 0x%08x\n"
+
+#: vms-alpha.c:5943
+#, c-format
+msgid " psect index: %u\n"
+msgstr " Ñ–Ð½Ð´ÐµÐºÑ psect: %u\n"
+
+#: vms-alpha.c:5954
+#, c-format
+msgid "SYMV - Vectored symbol definition\n"
+msgstr "SYMV — Ð²Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð²ÐµÐºÑ‚Ð¾Ñ€Ð¸Ð·Ð¾Ð²Ð°Ð½Ð¾Ð³Ð¾ Ñимволу\n"
+
+#: vms-alpha.c:5958
+#, c-format
+msgid " vector : 0x%08x\n"
+msgstr " вектор : 0x%08x\n"
+
+#: vms-alpha.c:5960 vms-alpha.c:5979
+#, c-format
+msgid " psect offset: %u\n"
+msgstr " відÑтуп psect: %u\n"
+
+#: vms-alpha.c:5973
+#, c-format
+msgid "SYMM - Global symbol definition with version\n"
+msgstr "SYMM — Ð²Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð·Ð°Ð³Ð°Ð»ÑŒÐ½Ð¾Ð³Ð¾ Ñимволу з верÑією\n"
+
+#: vms-alpha.c:5977
+#, c-format
+msgid " version mask: 0x%08x\n"
+msgstr " маÑка верÑÑ–Ñ—: 0x%08x\n"
+
+#: vms-alpha.c:5988
+#, c-format
+msgid "unhandled egsd entry type %u\n"
+msgstr "непридатний до обробки тип запиÑу egsd, %u\n"
+
+#: vms-alpha.c:6022
+#, c-format
+msgid " linkage index: %u, replacement insn: 0x%08x\n"
+msgstr " Ñ–Ð½Ð´ÐµÐºÑ ÐºÐ¾Ð¼Ð¿Ð¾Ð½ÑƒÐ²Ð°Ð½Ð½Ñ: %u, інÑтрукціÑ-замінник: 0x%08x\n"
+
+#: vms-alpha.c:6025
+#, c-format
+msgid " psect idx 1: %u, offset 1: 0x%08x %08x\n"
+msgstr " інд. psect 1: %u, відÑтуп 1: 0x%08x %08x\n"
+
+#: vms-alpha.c:6029
+#, c-format
+msgid " psect idx 2: %u, offset 2: 0x%08x %08x\n"
+msgstr " інд. psect 2: %u, відÑтуп 2: 0x%08x %08x\n"
+
+#: vms-alpha.c:6034
+#, c-format
+msgid " psect idx 3: %u, offset 3: 0x%08x %08x\n"
+msgstr " інд. psect 3: %u, відÑтуп 3: 0x%08x %08x\n"
+
+#: vms-alpha.c:6039
+#, c-format
+msgid " global name: %.*s\n"
+msgstr " загальна назва: %.*s\n"
+
+#: vms-alpha.c:6049
+#, c-format
+msgid " %s (len=%u+%u):\n"
+msgstr " %s (довж=%u+%u):\n"
+
+#: vms-alpha.c:6064
+#, c-format
+msgid " (type: %3u, size: 4+%3u): "
+msgstr " (тип: %3u, розмір: 4+%3u): "
+
+#: vms-alpha.c:6068
+#, c-format
+msgid "STA_GBL (stack global) %.*s\n"
+msgstr "STA_GBL (загальний Ñтек) %.*s\n"
+
+#: vms-alpha.c:6072
+#, c-format
+msgid "STA_LW (stack longword) 0x%08x\n"
+msgstr "STA_LW (Ñтек довгих Ñлів) 0x%08x\n"
+
+#: vms-alpha.c:6076
+#, c-format
+msgid "STA_QW (stack quadword) 0x%08x %08x\n"
+msgstr "STA_QW (Ñтек четверних Ñлів) 0x%08x %08x\n"
+
+#: vms-alpha.c:6081
+#, c-format
+msgid "STA_PQ (stack psect base + offset)\n"
+msgstr "STA_PQ (Ñтек оÑнови psect + зÑув)\n"
+
+#: vms-alpha.c:6082
+#, c-format
+msgid " psect: %u, offset: 0x%08x %08x\n"
+msgstr " psect: %u, зÑув: 0x%08x %08x\n"
+
+#: vms-alpha.c:6088
+#, c-format
+msgid "STA_LI (stack literal)\n"
+msgstr "STA_LI (Ñтек літералів)\n"
+
+#: vms-alpha.c:6091
+#, c-format
+msgid "STA_MOD (stack module)\n"
+msgstr "STA_MOD (Ñтек модулів)\n"
+
+#: vms-alpha.c:6094
+#, c-format
+msgid "STA_CKARG (compare procedure argument)\n"
+msgstr "STA_CKARG (аргумент процедури порівнÑннÑ)\n"
+
+#: vms-alpha.c:6098
+#, c-format
+msgid "STO_B (store byte)\n"
+msgstr "STO_B (збережений байт)\n"
+
+#: vms-alpha.c:6101
+#, c-format
+msgid "STO_W (store word)\n"
+msgstr "STO_W (збережене Ñлово)\n"
+
+#: vms-alpha.c:6104
+#, c-format
+msgid "STO_LW (store longword)\n"
+msgstr "STO_LW (збережене longword)\n"
+
+#: vms-alpha.c:6107
+#, c-format
+msgid "STO_QW (store quadword)\n"
+msgstr "STO_QW (збережене quadword)\n"
+
+#: vms-alpha.c:6113
+#, c-format
+msgid "STO_IMMR (store immediate repeat) %u bytes\n"
+msgstr "STO_IMMR (збережене негайне повтореннÑ) %u байтів\n"
+
+#: vms-alpha.c:6120
+#, c-format
+msgid "STO_GBL (store global) %.*s\n"
+msgstr "STO_GBL (загальне збереженнÑ) %.*s\n"
+
+#: vms-alpha.c:6124
+#, c-format
+msgid "STO_CA (store code address) %.*s\n"
+msgstr "STO_CA (збережена адреÑа коду) %.*s\n"
+
+#: vms-alpha.c:6128
+#, c-format
+msgid "STO_RB (store relative branch)\n"
+msgstr "STO_RB (збережене відноÑне відгалуженнÑ)\n"
+
+#: vms-alpha.c:6131
+#, c-format
+msgid "STO_AB (store absolute branch)\n"
+msgstr "STO_AB (збережене абÑолютне відгалуженнÑ)\n"
+
+#: vms-alpha.c:6134
+#, c-format
+msgid "STO_OFF (store offset to psect)\n"
+msgstr "STO_OFF (збережений зÑув щодо psect)\n"
+
+#: vms-alpha.c:6140
+#, c-format
+msgid "STO_IMM (store immediate) %u bytes\n"
+msgstr "STO_IMM (негайне збереженнÑ) %u байт\n"
+
+#: vms-alpha.c:6147
+#, c-format
+msgid "STO_GBL_LW (store global longword) %.*s\n"
+msgstr "STO_GBL_LW (збережене загальне longword) %.*s\n"
+
+#: vms-alpha.c:6151
+#, c-format
+msgid "STO_OFF (store LP with procedure signature)\n"
+msgstr "STO_OFF (Ð·Ð±ÐµÑ€ÐµÐ¶ÐµÐ½Ð½Ñ LP з підпиÑом підпрограми)\n"
+
+#: vms-alpha.c:6154
+#, c-format
+msgid "STO_BR_GBL (store branch global) *todo*\n"
+msgstr "STO_BR_GBL (збережене загальне відгалуженнÑ) *ще не реалізовано*\n"
+
+#: vms-alpha.c:6157
+#, c-format
+msgid "STO_BR_PS (store branch psect + offset) *todo*\n"
+msgstr "STO_BR_PS (збережений psect Ð²Ñ–Ð´Ð³Ð°Ð»ÑƒÐ¶ÐµÐ½Ð½Ñ + зÑув) *ще не реалізовано*\n"
+
+#: vms-alpha.c:6161
+#, c-format
+msgid "OPR_NOP (no-operation)\n"
+msgstr "OPR_NOP (без операції)\n"
+
+#: vms-alpha.c:6164
+#, c-format
+msgid "OPR_ADD (add)\n"
+msgstr "OPR_ADD (додаваннÑ)\n"
+
+#: vms-alpha.c:6167
+#, c-format
+msgid "OPR_SUB (substract)\n"
+msgstr "OPR_SUB (відніманнÑ)\n"
+
+#: vms-alpha.c:6170
+#, c-format
+msgid "OPR_MUL (multiply)\n"
+msgstr "OPR_MUL (множеннÑ)\n"
+
+#: vms-alpha.c:6173
+#, c-format
+msgid "OPR_DIV (divide)\n"
+msgstr "OPR_DIV (діленнÑ)\n"
+
+#: vms-alpha.c:6176
+#, c-format
+msgid "OPR_AND (logical and)\n"
+msgstr "OPR_AND (логічне «І»)\n"
+
+#: vms-alpha.c:6179
+#, c-format
+msgid "OPR_IOR (logical inclusive or)\n"
+msgstr "OPR_IOR (логічне включне «ÐБО»)\n"
+
+#: vms-alpha.c:6182
+#, c-format
+msgid "OPR_EOR (logical exclusive or)\n"
+msgstr "OPR_EOR (логічне виключне «ÐБО»)\n"
+
+#: vms-alpha.c:6185
+#, c-format
+msgid "OPR_NEG (negate)\n"
+msgstr "OPR_NEG (запереченнÑ)\n"
+
+#: vms-alpha.c:6188
+#, c-format
+msgid "OPR_COM (complement)\n"
+msgstr "OPR_COM (доповненнÑ)\n"
+
+#: vms-alpha.c:6191
+#, c-format
+msgid "OPR_INSV (insert field)\n"
+msgstr "OPR_INSV (вÑÑ‚Ð°Ð²Ð»ÐµÐ½Ð½Ñ Ð¿Ð¾Ð»Ñ)\n"
+
+#: vms-alpha.c:6194
+#, c-format
+msgid "OPR_ASH (arithmetic shift)\n"
+msgstr "OPR_ASH (арифметичний зÑув)\n"
+
+#: vms-alpha.c:6197
+#, c-format
+msgid "OPR_USH (unsigned shift)\n"
+msgstr "OPR_USH (беззнаковий зÑув)\n"
+
+#: vms-alpha.c:6200
+#, c-format
+msgid "OPR_ROT (rotate)\n"
+msgstr "OPR_ROT (циклічний зÑув)\n"
+
+#: vms-alpha.c:6203
+#, c-format
+msgid "OPR_SEL (select)\n"
+msgstr "OPR_SEL (вибір)\n"
+
+#: vms-alpha.c:6206
+#, c-format
+msgid "OPR_REDEF (redefine symbol to curr location)\n"
+msgstr "OPR_REDEF (Ð¿ÐµÑ€ÐµÐ²Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ñимволу до поточної позиції)\n"
+
+#: vms-alpha.c:6209
+#, c-format
+msgid "OPR_REDEF (define a literal)\n"
+msgstr "OPR_REDEF (Ð²Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð»Ñ–Ñ‚ÐµÑ€Ð°Ð»Ð°)\n"
+
+#: vms-alpha.c:6213
+#, c-format
+msgid "STC_LP (store cond linkage pair)\n"
+msgstr "STC_LP (збережена пара умовного компонуваннÑ)\n"
+
+#: vms-alpha.c:6217
+#, c-format
+msgid "STC_LP_PSB (store cond linkage pair + signature)\n"
+msgstr "STC_LP_PSB (збережена пара умовного ÐºÐ¾Ð¼Ð¿Ð¾Ð½ÑƒÐ²Ð°Ð½Ð½Ñ + підпиÑ)\n"
+
+#: vms-alpha.c:6218
+#, c-format
+msgid " linkage index: %u, procedure: %.*s\n"
+msgstr " Ñ–Ð½Ð´ÐµÐºÑ ÐºÐ¾Ð¼Ð¿Ð¾Ð½ÑƒÐ²Ð°Ð½Ð½Ñ: %u, процедура: %.*s\n"
+
+#: vms-alpha.c:6221
+#, c-format
+msgid " signature: %.*s\n"
+msgstr " підпиÑ: %.*s\n"
+
+#: vms-alpha.c:6224
+#, c-format
+msgid "STC_GBL (store cond global)\n"
+msgstr "STC_GBL (збережена загальна умова)\n"
+
+#: vms-alpha.c:6225
+#, c-format
+msgid " linkage index: %u, global: %.*s\n"
+msgstr " Ñ–Ð½Ð´ÐµÐºÑ ÐºÐ¾Ð¼Ð¿Ð¾Ð½ÑƒÐ²Ð°Ð½Ð½Ñ: %u, загальний: %.*s\n"
+
+#: vms-alpha.c:6229
+#, c-format
+msgid "STC_GCA (store cond code address)\n"
+msgstr "STC_GCA (збережена адреÑа умовного коду)\n"
+
+#: vms-alpha.c:6230
+#, c-format
+msgid " linkage index: %u, procedure name: %.*s\n"
+msgstr " Ñ–Ð½Ð´ÐµÐºÑ ÐºÐ¾Ð¼Ð¿Ð¾Ð½ÑƒÐ²Ð°Ð½Ð½Ñ: %u, назва підпрограми: %.*s\n"
+
+#: vms-alpha.c:6234
+#, c-format
+msgid "STC_PS (store cond psect + offset)\n"
+msgstr "STC_PS (збережений умовний psect + зÑув)\n"
+
+#: vms-alpha.c:6236
+#, c-format
+msgid " linkage index: %u, psect: %u, offset: 0x%08x %08x\n"
+msgstr " Ñ–Ð½Ð´ÐµÐºÑ ÐºÐ¾Ð¼Ð¿Ð¾Ð½ÑƒÐ²Ð°Ð½Ð½Ñ: %u, psect: %u, зÑув: 0x%08x %08x\n"
+
+#: vms-alpha.c:6243
+#, c-format
+msgid "STC_NOP_GBL (store cond NOP at global addr)\n"
+msgstr "STC_NOP_GBL (збережений умовний NOP за загальною адреÑою)\n"
+
+#: vms-alpha.c:6247
+#, c-format
+msgid "STC_NOP_PS (store cond NOP at psect + offset)\n"
+msgstr "STC_NOP_PS (збережений умовний NOP за psect + зÑув)\n"
+
+#: vms-alpha.c:6251
+#, c-format
+msgid "STC_BSR_GBL (store cond BSR at global addr)\n"
+msgstr "STC_BSR_GBL (збережений умовний BSR за загальною адреÑою)\n"
+
+#: vms-alpha.c:6255
+#, c-format
+msgid "STC_BSR_PS (store cond BSR at psect + offset)\n"
+msgstr "STC_BSR_PS (збережений умовний BSR за psect + зÑув)\n"
+
+#: vms-alpha.c:6259
+#, c-format
+msgid "STC_LDA_GBL (store cond LDA at global addr)\n"
+msgstr "STC_LDA_GBL (збережений умовний LDA за загальною адреÑою)\n"
+
+#: vms-alpha.c:6263
+#, c-format
+msgid "STC_LDA_PS (store cond LDA at psect + offset)\n"
+msgstr "STC_LDA_PS (збережена умовна LDA за psect + зÑув)\n"
+
+#: vms-alpha.c:6267
+#, c-format
+msgid "STC_BOH_GBL (store cond BOH at global addr)\n"
+msgstr "STC_BOH_GBL (збережений умовний BOH за загальною адреÑою)\n"
+
+#: vms-alpha.c:6271
+#, c-format
+msgid "STC_BOH_PS (store cond BOH at psect + offset)\n"
+msgstr "STC_BOH_PS (збережений умовний BOH за psect + зÑув)\n"
+
+#: vms-alpha.c:6276
+#, c-format
+msgid "STC_NBH_GBL (store cond or hint at global addr)\n"
+msgstr "STC_NBH_GBL (збережена умова або вказівка за загальною адреÑою)\n"
+
+#: vms-alpha.c:6280
+#, c-format
+msgid "STC_NBH_PS (store cond or hint at psect + offset)\n"
+msgstr "STC_NBH_PS (збережена умова або вказівка за psect + зÑув)\n"
+
+#: vms-alpha.c:6284
+#, c-format
+msgid "CTL_SETRB (set relocation base)\n"
+msgstr "CTL_SETRB (вÑÑ‚Ð°Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð¾Ñнови переÑуваннÑ)\n"
+
+#: vms-alpha.c:6290
+#, c-format
+msgid "CTL_AUGRB (augment relocation base) %u\n"
+msgstr "CTL_AUGRB (Ñ€Ð¾Ð·ÑˆÐ¸Ñ€ÐµÐ½Ð½Ñ Ð¾Ñнови переÑуваннÑ) %u\n"
+
+#: vms-alpha.c:6294
+#, c-format
+msgid "CTL_DFLOC (define location)\n"
+msgstr "CTL_DFLOC (визначити розташуваннÑ)\n"
+
+#: vms-alpha.c:6297
+#, c-format
+msgid "CTL_STLOC (set location)\n"
+msgstr "CTL_STLOC (вказати розташуваннÑ)\n"
+
+#: vms-alpha.c:6300
+#, c-format
+msgid "CTL_STKDL (stack defined location)\n"
+msgstr "CTL_STKDL (розташуваннÑ, визначене Ñтеком)\n"
+
+#: vms-alpha.c:6303 vms-alpha.c:6717
+#, c-format
+msgid "*unhandled*\n"
+msgstr "*не оброблено*\n"
+
+#: vms-alpha.c:6333 vms-alpha.c:6372
+#, c-format
+msgid "cannot read GST record length\n"
+msgstr "не вдалоÑÑ Ð¿Ñ€Ð¾Ñ‡Ð¸Ñ‚Ð°Ñ‚Ð¸ довжину запиÑу GST\n"
+
+#. Ill-formed.
+#: vms-alpha.c:6354
+#, c-format
+msgid "cannot find EMH in first GST record\n"
+msgstr "не вдалоÑÑ Ð·Ð½Ð°Ð¹Ñ‚Ð¸ EMH у першому запиÑÑ– GST\n"
+
+#: vms-alpha.c:6380
+#, c-format
+msgid "cannot read GST record header\n"
+msgstr "не вдалоÑÑ Ð¿Ñ€Ð¾Ñ‡Ð¸Ñ‚Ð°Ñ‚Ð¸ заголовок запиÑу GST\n"
+
+#: vms-alpha.c:6393
+#, c-format
+msgid " corrupted GST\n"
+msgstr " пошкоджений GST\n"
+
+#: vms-alpha.c:6401
+#, c-format
+msgid "cannot read GST record\n"
+msgstr "не вдалоÑÑ Ð¿Ñ€Ð¾Ñ‡Ð¸Ñ‚Ð°Ñ‚Ð¸ Ð·Ð°Ð¿Ð¸Ñ GST\n"
+
+#: vms-alpha.c:6430
+#, c-format
+msgid " unhandled EOBJ record type %u\n"
+msgstr " непридатний до обробки тип запиÑу EOBJ, %u\n"
+
+#: vms-alpha.c:6453
+#, c-format
+msgid " bitcount: %u, base addr: 0x%08x\n"
+msgstr " кількіÑÑ‚ÑŒ бітів: %u, базова адреÑа: 0x%08x\n"
+
+#: vms-alpha.c:6466
+#, c-format
+msgid " bitmap: 0x%08x (count: %u):\n"
+msgstr " бітовий образ: 0x%08x (лічильник: %u):\n"
+
+#: vms-alpha.c:6473
+#, c-format
+msgid " %08x"
+msgstr " %08x"
+
+#: vms-alpha.c:6498
+#, c-format
+msgid " image %u (%u entries)\n"
+msgstr " образ %u (%u запиÑів)\n"
+
+#: vms-alpha.c:6503
+#, c-format
+msgid " offset: 0x%08x, val: 0x%08x\n"
+msgstr " відÑтуп: 0x%08x, значеннÑ: 0x%08x\n"
+
+#: vms-alpha.c:6524
+#, c-format
+msgid " image %u (%u entries), offsets:\n"
+msgstr " образ %u (%u запиÑів), відÑтупи:\n"
+
+#: vms-alpha.c:6531
+#, c-format
+msgid " 0x%08x"
+msgstr " 0x%08x"
+
+#. 64 bits.
+#: vms-alpha.c:6653
+#, c-format
+msgid "64 bits *unhandled*\n"
+msgstr "64 біти *не оброблÑєтьÑÑ*\n"
+
+#: vms-alpha.c:6657
+#, c-format
+msgid "class: %u, dtype: %u, length: %u, pointer: 0x%08x\n"
+msgstr "клаÑ: %u, dtype: %u, довжина: %u, вказівник: 0x%08x\n"
+
+#: vms-alpha.c:6668
+#, c-format
+msgid "non-contiguous array of %s\n"
+msgstr "розривний маÑив %s\n"
+
+#: vms-alpha.c:6672
+#, c-format
+msgid "dimct: %u, aflags: 0x%02x, digits: %u, scale: %u\n"
+msgstr "dimct: %u, aflags: 0x%02x, цифр: %u, шкала: %u\n"
+
+#: vms-alpha.c:6676
+#, c-format
+msgid "arsize: %u, a0: 0x%08x\n"
+msgstr "arsize: %u, a0: 0x%08x\n"
+
+#: vms-alpha.c:6680
+#, c-format
+msgid "Strides:\n"
+msgstr "Кроки:\n"
+
+#: vms-alpha.c:6685
+#, c-format
+msgid "[%u]: %u\n"
+msgstr "[%u]: %u\n"
+
+#: vms-alpha.c:6690
+#, c-format
+msgid "Bounds:\n"
+msgstr "Межі:\n"
+
+#: vms-alpha.c:6695
+#, c-format
+msgid "[%u]: Lower: %u, upper: %u\n"
+msgstr "[%u]: нижнÑ: %u, верхнÑ: %u\n"
+
+#: vms-alpha.c:6707
+#, c-format
+msgid "unaligned bit-string of %s\n"
+msgstr "невирівнÑний бітовий Ñ€Ñдок %s\n"
+
+#: vms-alpha.c:6711
+#, c-format
+msgid "base: %u, pos: %u\n"
+msgstr "оÑнова: %u, позиціÑ: %u\n"
+
+#: vms-alpha.c:6731
+#, c-format
+msgid "vflags: 0x%02x, value: 0x%08x "
+msgstr "vflags: 0x%02x, значеннÑ: 0x%08x "
+
+#: vms-alpha.c:6737
+#, c-format
+msgid "(no value)\n"
+msgstr "(нема значеннÑ)\n"
+
+#: vms-alpha.c:6740
+#, c-format
+msgid "(not active)\n"
+msgstr "(неактивне)\n"
+
+#: vms-alpha.c:6743
+#, c-format
+msgid "(not allocated)\n"
+msgstr "(не розміщено)\n"
+
+#: vms-alpha.c:6746
+#, c-format
+msgid "(descriptor)\n"
+msgstr "(деÑкриптор)\n"
+
+#: vms-alpha.c:6750
+#, c-format
+msgid "(trailing value)\n"
+msgstr "(хвоÑтове значеннÑ)\n"
+
+#: vms-alpha.c:6753
+#, c-format
+msgid "(value spec follows)\n"
+msgstr "(далі ÑÐ¿ÐµÑ†Ð¸Ñ„Ñ–ÐºÐ°Ñ†Ñ–Ñ Ð·Ð½Ð°Ñ‡ÐµÐ½ÑŒ)\n"
+
+#: vms-alpha.c:6756
+#, c-format
+msgid "(at bit offset %u)\n"
+msgstr "(за відÑтупом у бітах %u)\n"
+
+#: vms-alpha.c:6759
+#, c-format
+msgid "(reg: %u, disp: %u, indir: %u, kind: "
+msgstr "(рег: %u, disp: %u, indir: %u, тип: "
+
+#: vms-alpha.c:6766
+msgid "literal"
+msgstr "літерал"
+
+#: vms-alpha.c:6769
+msgid "address"
+msgstr "адреÑа"
+
+#: vms-alpha.c:6772
+msgid "desc"
+msgstr "деÑк"
+
+#: vms-alpha.c:6775
+msgid "reg"
+msgstr "рег"
+
+#: vms-alpha.c:6850
+#, c-format
+msgid "Debug symbol table:\n"
+msgstr "Ð¢Ð°Ð±Ð»Ð¸Ñ†Ñ Ñимволів зневаджуваннÑ:\n"
+
+#: vms-alpha.c:6861
+#, c-format
+msgid "cannot read DST header\n"
+msgstr "не вдалоÑÑ Ð¿Ñ€Ð¾Ñ‡Ð¸Ñ‚Ð°Ñ‚Ð¸ заголовок DST\n"
+
+#: vms-alpha.c:6866
+#, c-format
+msgid " type: %3u, len: %3u (at 0x%08x): "
+msgstr " тип: %3u, довжина: %3u (за 0x%08x): "
+
+#: vms-alpha.c:6880
+#, c-format
+msgid "cannot read DST symbol\n"
+msgstr "не вдалоÑÑ Ð¿Ñ€Ð¾Ñ‡Ð¸Ñ‚Ð°Ñ‚Ð¸ Ñимвол DST\n"
+
+#: vms-alpha.c:6923
+#, c-format
+msgid "standard data: %s\n"
+msgstr "Ñтандартні дані: %s\n"
+
+#: vms-alpha.c:6926 vms-alpha.c:7010
+#, c-format
+msgid " name: %.*s\n"
+msgstr " назва: %.*s\n"
+
+#: vms-alpha.c:6933
+#, c-format
+msgid "modbeg\n"
+msgstr "modbeg\n"
+
+#: vms-alpha.c:6934
+#, c-format
+msgid " flags: %d, language: %u, major: %u, minor: %u\n"
+msgstr " прапорці: %d, мова: %u, Ñтарший: %u, молодший: %u\n"
+
+#: vms-alpha.c:6940 vms-alpha.c:7206
+#, c-format
+msgid " module name: %.*s\n"
+msgstr " назва модулÑ: %.*s\n"
+
+#: vms-alpha.c:6943
+#, c-format
+msgid " compiler : %.*s\n"
+msgstr " компілÑтор : %.*s\n"
+
+#: vms-alpha.c:6948
+#, c-format
+msgid "modend\n"
+msgstr "modend\n"
+
+#: vms-alpha.c:6955
+msgid "rtnbeg\n"
+msgstr "rtnbeg\n"
+
+#: vms-alpha.c:6956
+#, c-format
+msgid " flags: %u, address: 0x%08x, pd-address: 0x%08x\n"
+msgstr " прапорці: %u, адреÑа: 0x%08x, pd-адреÑа: 0x%08x\n"
+
+#: vms-alpha.c:6961
+#, c-format
+msgid " routine name: %.*s\n"
+msgstr " назва процедури: %.*s\n"
+
+#: vms-alpha.c:6969
+#, c-format
+msgid "rtnend: size 0x%08x\n"
+msgstr "rtnend: розмір 0x%08x\n"
+
+#: vms-alpha.c:6977
+#, c-format
+msgid "prolog: bkpt address 0x%08x\n"
+msgstr "пролог: адреÑа bkpt 0x%08x\n"
+
+#: vms-alpha.c:6985
+#, c-format
+msgid "epilog: flags: %u, count: %u\n"
+msgstr "епілог: прапорці: %u, лічильник: %u\n"
+
+#: vms-alpha.c:6994
+#, c-format
+msgid "blkbeg: address: 0x%08x, name: %.*s\n"
+msgstr "blkbeg: адреÑа: 0x%08x, назва: %.*s\n"
+
+#: vms-alpha.c:7003
+#, c-format
+msgid "blkend: size: 0x%08x\n"
+msgstr "blkend: розмір: 0x%08x\n"
+
+#: vms-alpha.c:7009
+#, c-format
+msgid "typspec (len: %u)\n"
+msgstr "typspec (довж.: %u)\n"
+
+#: vms-alpha.c:7016
+#, c-format
+msgid "septyp, name: %.*s\n"
+msgstr "septyp, назва: %.*s\n"
+
+#: vms-alpha.c:7025
+#, c-format
+msgid "recbeg: name: %.*s\n"
+msgstr "recbeg: назва: %.*s\n"
+
+#: vms-alpha.c:7032
+#, c-format
+msgid "recend\n"
+msgstr "recend\n"
+
+#: vms-alpha.c:7035
+#, c-format
+msgid "enumbeg, len: %u, name: %.*s\n"
+msgstr "enumbeg, довжина: %u, назва: %.*s\n"
+
+#: vms-alpha.c:7039
+#, c-format
+msgid "enumelt, name: %.*s\n"
+msgstr "enumelt, назва: %.*s\n"
+
+#: vms-alpha.c:7043
+#, c-format
+msgid "enumend\n"
+msgstr "enumend\n"
+
+#: vms-alpha.c:7060
+#, c-format
+msgid "discontiguous range (nbr: %u)\n"
+msgstr "розривний діапазон (nbr: %u)\n"
+
+#: vms-alpha.c:7062
+#, c-format
+msgid " address: 0x%08x, size: %u\n"
+msgstr " адреÑа: 0x%08x, розмір: %u\n"
+
+#: vms-alpha.c:7072
+#, c-format
+msgid "line num (len: %u)\n"
+msgstr "номер Ñ€Ñдка (довжина: %u)\n"
+
+#: vms-alpha.c:7089
+#, c-format
+msgid "delta_pc_w %u\n"
+msgstr "delta_pc_w %u\n"
+
+#: vms-alpha.c:7096
+#, c-format
+msgid "incr_linum(b): +%u\n"
+msgstr "incr_linum(b): +%u\n"
+
+#: vms-alpha.c:7102
+#, c-format
+msgid "incr_linum_w: +%u\n"
+msgstr "incr_linum_w: +%u\n"
+
+#: vms-alpha.c:7108
+#, c-format
+msgid "incr_linum_l: +%u\n"
+msgstr "incr_linum_l: +%u\n"
+
+#: vms-alpha.c:7114
+#, c-format
+msgid "set_line_num(w) %u\n"
+msgstr "set_line_num(w) %u\n"
+
+#: vms-alpha.c:7119
+#, c-format
+msgid "set_line_num_b %u\n"
+msgstr "set_line_num_b %u\n"
+
+#: vms-alpha.c:7124
+#, c-format
+msgid "set_line_num_l %u\n"
+msgstr "set_line_num_l %u\n"
+
+#: vms-alpha.c:7129
+#, c-format
+msgid "set_abs_pc: 0x%08x\n"
+msgstr "set_abs_pc: 0x%08x\n"
+
+#: vms-alpha.c:7133
+#, c-format
+msgid "delta_pc_l: +0x%08x\n"
+msgstr "delta_pc_l: +0x%08x\n"
+
+#: vms-alpha.c:7138
+#, c-format
+msgid "term(b): 0x%02x"
+msgstr "term(b): 0x%02x"
+
+#: vms-alpha.c:7140
+#, c-format
+msgid " pc: 0x%08x\n"
+msgstr " pc: 0x%08x\n"
+
+#: vms-alpha.c:7145
+#, c-format
+msgid "term_w: 0x%04x"
+msgstr "term_w: 0x%04x"
+
+#: vms-alpha.c:7147
+#, c-format
+msgid " pc: 0x%08x\n"
+msgstr " pc: 0x%08x\n"
+
+#: vms-alpha.c:7153
+#, c-format
+msgid "delta pc +%-4d"
+msgstr "приріÑÑ‚ pc +%-4d"
+
+#: vms-alpha.c:7156
+#, c-format
+msgid " pc: 0x%08x line: %5u\n"
+msgstr " pc: 0x%08x Ñ€Ñдок: %5u\n"
+
+#: vms-alpha.c:7161
+#, c-format
+msgid " *unhandled* cmd %u\n"
+msgstr " *непридатна* команда %u\n"
+
+#: vms-alpha.c:7176
+#, c-format
+msgid "source (len: %u)\n"
+msgstr "джерело (довжина: %u)\n"
+
+#: vms-alpha.c:7190
+#, c-format
+msgid " declfile: len: %u, flags: %u, fileid: %u\n"
+msgstr " declfile: довжина: %u, прапорці: %u, ід. файла: %u\n"
+
+#: vms-alpha.c:7194
+#, c-format
+msgid " rms: cdt: 0x%08x %08x, ebk: 0x%08x, ffb: 0x%04x, rfo: %u\n"
+msgstr " rms: cdt: 0x%08x %08x, ebk: 0x%08x, ffb: 0x%04x, rfo: %u\n"
+
+#: vms-alpha.c:7203
+#, c-format
+msgid " filename : %.*s\n"
+msgstr " назва файла: %.*s\n"
+
+#: vms-alpha.c:7212
+#, c-format
+msgid " setfile %u\n"
+msgstr " setfile %u\n"
+
+#: vms-alpha.c:7217 vms-alpha.c:7222
+#, c-format
+msgid " setrec %u\n"
+msgstr " setrec %u\n"
+
+#: vms-alpha.c:7227 vms-alpha.c:7232
+#, c-format
+msgid " setlnum %u\n"
+msgstr " setlnum %u\n"
+
+#: vms-alpha.c:7237 vms-alpha.c:7242
+#, c-format
+msgid " deflines %u\n"
+msgstr " deflines %u\n"
+
+#: vms-alpha.c:7246
+#, c-format
+msgid " formfeed\n"
+msgstr " formfeed\n"
+
+#: vms-alpha.c:7250
+#, c-format
+msgid " *unhandled* cmd %u\n"
+msgstr " *непридатна* команда %u\n"
+
+#: vms-alpha.c:7262
+#, c-format
+msgid "*unhandled* dst type %u\n"
+msgstr "*непридатний* тип призначеннÑ, %u\n"
+
+#: vms-alpha.c:7294
+#, c-format
+msgid "cannot read EIHD\n"
+msgstr "не вдалоÑÑ Ð¿Ñ€Ð¾Ñ‡Ð¸Ñ‚Ð°Ñ‚Ð¸ EIHD\n"
+
+#: vms-alpha.c:7297
+#, c-format
+msgid "EIHD: (size: %u, nbr blocks: %u)\n"
+msgstr "EIHD: (розмір: %u, кількіÑÑ‚ÑŒ блоків: %u)\n"
+
+#: vms-alpha.c:7300
+#, c-format
+msgid " majorid: %u, minorid: %u\n"
+msgstr " majorid: %u, minorid: %u\n"
+
+#: vms-alpha.c:7308
+msgid "executable"
+msgstr "виконуваний"
+
+#: vms-alpha.c:7311
+msgid "linkable image"
+msgstr "компонований образ"
+
+#: vms-alpha.c:7317
+#, c-format
+msgid " image type: %u (%s)"
+msgstr " тип образу: %u (%s)"
+
+#: vms-alpha.c:7323
+msgid "native"
+msgstr "Ñтандартний"
+
+#: vms-alpha.c:7326
+msgid "CLI"
+msgstr "CLI"
+
+#: vms-alpha.c:7332
+#, c-format
+msgid ", subtype: %u (%s)\n"
+msgstr ", підтип: %u (%s)\n"
+
+#: vms-alpha.c:7338
+#, c-format
+msgid " offsets: isd: %u, activ: %u, symdbg: %u, imgid: %u, patch: %u\n"
+msgstr " зÑуви: isd: %u, activ: %u, symdbg: %u, imgid: %u, patch: %u\n"
+
+#: vms-alpha.c:7342
+#, c-format
+msgid " fixup info rva: "
+msgstr " дані щодо прив’Ñзки rva: "
+
+#: vms-alpha.c:7344
+#, c-format
+msgid ", symbol vector rva: "
+msgstr ", вектор Ñимволів rva: "
+
+#: vms-alpha.c:7347
+#, c-format
+msgid ""
+"\n"
+" version array off: %u\n"
+msgstr ""
+"\n"
+" відÑтуп маÑиву верÑÑ–Ñ—: %u\n"
+
+#: vms-alpha.c:7351
+#, c-format
+msgid " img I/O count: %u, nbr channels: %u, req pri: %08x%08x\n"
+msgstr " лічильник введеннÑ-Ð²Ð¸Ð²ÐµÐ´ÐµÐ½Ð½Ñ Ð¾Ð±Ñ€Ð°Ð·Ñƒ: %u, к-Ñ‚ÑŒ каналів: %u, пріоритетніÑÑ‚ÑŒ: %08x%08x\n"
+
+#: vms-alpha.c:7357
+#, c-format
+msgid " linker flags: %08x:"
+msgstr " прапорці компонувальника: %08x:"
+
+#: vms-alpha.c:7387
+#, c-format
+msgid " ident: 0x%08x, sysver: 0x%08x, match ctrl: %u, symvect_size: %u\n"
+msgstr " ident: 0x%08x, sysver: 0x%08x, match ctrl: %u, symvect_size: %u\n"
+
+#: vms-alpha.c:7393
+#, c-format
+msgid " BPAGE: %u"
+msgstr " BPAGE: %u"
+
+#: vms-alpha.c:7399
+#, c-format
+msgid ", ext fixup offset: %u, no_opt psect off: %u"
+msgstr ", зÑув розшир. прив’зÑки: %u, зÑув psect no_opt: %u"
+
+#: vms-alpha.c:7402
+#, c-format
+msgid ", alias: %u\n"
+msgstr ", пÑевдонім: %u\n"
+
+#: vms-alpha.c:7410
+#, c-format
+msgid "system version array information:\n"
+msgstr "маÑив даних щодо верÑÑ–Ñ— ÑиÑтеми:\n"
+
+#: vms-alpha.c:7414
+#, c-format
+msgid "cannot read EIHVN header\n"
+msgstr "не вдалоÑÑ Ð¿Ñ€Ð¾Ñ‡Ð¸Ñ‚Ð°Ñ‚Ð¸ заголовок EIHVN\n"
+
+#: vms-alpha.c:7424
+#, c-format
+msgid "cannot read EIHVN version\n"
+msgstr "не вдалоÑÑ Ð¿Ñ€Ð¾Ñ‡Ð¸Ñ‚Ð°Ñ‚Ð¸ верÑÑ–ÑŽ EIHVN\n"
+
+#: vms-alpha.c:7427
+#, c-format
+msgid " %02u "
+msgstr " %02u "
+
+#: vms-alpha.c:7431
+msgid "BASE_IMAGE "
+msgstr "BASE_IMAGE "
+
+#: vms-alpha.c:7434
+msgid "MEMORY_MANAGEMENT"
+msgstr "MEMORY_MANAGEMENT"
+
+#: vms-alpha.c:7437
+msgid "IO "
+msgstr "IO "
+
+#: vms-alpha.c:7440
+msgid "FILES_VOLUMES "
+msgstr "FILES_VOLUMES "
+
+#: vms-alpha.c:7443
+msgid "PROCESS_SCHED "
+msgstr "PROCESS_SCHED "
+
+#: vms-alpha.c:7446
+msgid "SYSGEN "
+msgstr "SYSGEN "
+
+#: vms-alpha.c:7449
+msgid "CLUSTERS_LOCKMGR "
+msgstr "CLUSTERS_LOCKMGR "
+
+#: vms-alpha.c:7452
+msgid "LOGICAL_NAMES "
+msgstr "LOGICAL_NAMES "
+
+#: vms-alpha.c:7455
+msgid "SECURITY "
+msgstr "SECURITY "
+
+#: vms-alpha.c:7458
+msgid "IMAGE_ACTIVATOR "
+msgstr "IMAGE_ACTIVATOR "
+
+#: vms-alpha.c:7461
+msgid "NETWORKS "
+msgstr "NETWORKS "
+
+#: vms-alpha.c:7464
+msgid "COUNTERS "
+msgstr "COUNTERS "
+
+#: vms-alpha.c:7467
+msgid "STABLE "
+msgstr "STABLE "
+
+#: vms-alpha.c:7470
+msgid "MISC "
+msgstr "MISC "
+
+#: vms-alpha.c:7473
+msgid "CPU "
+msgstr "CPU "
+
+#: vms-alpha.c:7476
+msgid "VOLATILE "
+msgstr "VOLATILE "
+
+#: vms-alpha.c:7479
+msgid "SHELL "
+msgstr "SHELL "
+
+#: vms-alpha.c:7482
+msgid "POSIX "
+msgstr "POSIX "
+
+#: vms-alpha.c:7485
+msgid "MULTI_PROCESSING "
+msgstr "MULTI_PROCESSING "
+
+#: vms-alpha.c:7488
+msgid "GALAXY "
+msgstr "GALAXY "
+
+#: vms-alpha.c:7491
+msgid "*unknown* "
+msgstr "*невідомо* "
+
+#: vms-alpha.c:7494
+#, c-format
+msgid ": %u.%u\n"
+msgstr ": %u.%u\n"
+
+#: vms-alpha.c:7507 vms-alpha.c:7766
+#, c-format
+msgid "cannot read EIHA\n"
+msgstr "не вдалоÑÑ Ð¿Ñ€Ð¾Ñ‡Ð¸Ñ‚Ð°Ñ‚Ð¸ EIHA\n"
+
+#: vms-alpha.c:7510
+#, c-format
+msgid "Image activation: (size=%u)\n"
+msgstr "ÐÐºÑ‚Ð¸Ð²Ð°Ñ†Ñ–Ñ Ð¾Ð±Ñ€Ð°Ð·Ñƒ: (розмір=%u)\n"
+
+#: vms-alpha.c:7512
+#, c-format
+msgid " First address : 0x%08x 0x%08x\n"
+msgstr " Перша адреÑа: 0x%08x 0x%08x\n"
+
+#: vms-alpha.c:7515
+#, c-format
+msgid " Second address: 0x%08x 0x%08x\n"
+msgstr " Друга адреÑа: 0x%08x 0x%08x\n"
+
+#: vms-alpha.c:7518
+#, c-format
+msgid " Third address : 0x%08x 0x%08x\n"
+msgstr " Ð¢Ñ€ÐµÑ‚Ñ Ð°Ð´Ñ€ÐµÑа: 0x%08x 0x%08x\n"
+
+#: vms-alpha.c:7521
+#, c-format
+msgid " Fourth address: 0x%08x 0x%08x\n"
+msgstr " Четверта адреÑа: 0x%08x 0x%08x\n"
+
+#: vms-alpha.c:7524
+#, c-format
+msgid " Shared image : 0x%08x 0x%08x\n"
+msgstr " Спільний образ: 0x%08x 0x%08x\n"
+
+#: vms-alpha.c:7535
+#, c-format
+msgid "cannot read EIHI\n"
+msgstr "не вдалоÑÑ Ð¿Ñ€Ð¾Ñ‡Ð¸Ñ‚Ð°Ñ‚Ð¸ EIHI\n"
+
+#: vms-alpha.c:7538
+#, c-format
+msgid "Image identification: (major: %u, minor: %u)\n"
+msgstr "Ð†Ð´ÐµÐ½Ñ‚Ð¸Ñ„Ñ–ÐºÐ°Ñ†Ñ–Ñ Ð¾Ð±Ñ€Ð°Ð·Ñƒ: (Ñтарший: %u, молодший: %u)\n"
+
+#: vms-alpha.c:7541
+#, c-format
+msgid " image name : %.*s\n"
+msgstr " назва образу : %.*s\n"
+
+#: vms-alpha.c:7543
+#, c-format
+msgid " link time : %s\n"
+msgstr " Ñ‡Ð°Ñ ÐºÐ¾Ð¼Ð¿Ð¾Ð½ÑƒÐ²Ð°Ð½Ð½Ñ : %s\n"
+
+#: vms-alpha.c:7545
+#, c-format
+msgid " image ident : %.*s\n"
+msgstr " ід. образу : %.*s\n"
+
+#: vms-alpha.c:7547
+#, c-format
+msgid " linker ident : %.*s\n"
+msgstr " ід. компонувальника: %.*s\n"
+
+#: vms-alpha.c:7549
+#, c-format
+msgid " image build ident: %.*s\n"
+msgstr " ідентифікатор Ð·Ð±Ð¸Ñ€Ð°Ð½Ð½Ñ Ð¾Ð±Ñ€Ð°Ð·Ñƒ: %.*s\n"
+
+#: vms-alpha.c:7559
+#, c-format
+msgid "cannot read EIHS\n"
+msgstr "не вдалоÑÑ Ð¿Ñ€Ð¾Ñ‡Ð¸Ñ‚Ð°Ñ‚Ð¸ EIHS\n"
+
+#: vms-alpha.c:7562
+#, c-format
+msgid "Image symbol & debug table: (major: %u, minor: %u)\n"
+msgstr "Ð¢Ð°Ð±Ð»Ð¸Ñ†Ñ Ñимволів Ñ– діагноÑтики образу (оÑновна: %u, модифікаціÑ: %u)\n"
+
+#: vms-alpha.c:7567
+#, c-format
+msgid " debug symbol table : vbn: %u, size: %u (0x%x)\n"
+msgstr " Ñ‚Ð°Ð±Ð»Ð¸Ñ†Ñ Ð´Ñ–Ð°Ð³Ð½Ð¾Ñтичних Ñимволів: vbn: %u, розмір: %u (0x%x)\n"
+
+#: vms-alpha.c:7571
+#, c-format
+msgid " global symbol table: vbn: %u, records: %u\n"
+msgstr " Ñ‚Ð°Ð±Ð»Ð¸Ñ†Ñ Ð·Ð°Ð³Ð°Ð»ÑŒÐ½Ð¸Ñ… Ñимволів: vbn: %u, запиÑів: %u\n"
+
+#: vms-alpha.c:7575
+#, c-format
+msgid " debug module table : vbn: %u, size: %u\n"
+msgstr " Ñ‚Ð°Ð±Ð»Ð¸Ñ†Ñ Ð´Ñ–Ð°Ð³Ð½Ð¾Ñтики модулів: vbn: %u, розмір: %u\n"
+
+#: vms-alpha.c:7588
+#, c-format
+msgid "cannot read EISD\n"
+msgstr "не вдалоÑÑ Ð¿Ñ€Ð¾Ñ‡Ð¸Ñ‚Ð°Ñ‚Ð¸ EISD\n"
+
+#: vms-alpha.c:7598
+#, c-format
+msgid "Image section descriptor: (major: %u, minor: %u, size: %u, offset: %u)\n"
+msgstr "ДеÑкриптор розділу образу: (оÑновна: %u, модифікаціÑ: %u, розмір: %u, відÑтуп: %u)\n"
+
+#: vms-alpha.c:7605
+#, c-format
+msgid " section: base: 0x%08x%08x size: 0x%08x\n"
+msgstr " розділ: оÑнова: 0x%08x%08x розмір: 0x%08x\n"
+
+#: vms-alpha.c:7610
+#, c-format
+msgid " flags: 0x%04x"
+msgstr " прапорці: 0x%04x"
+
+#: vms-alpha.c:7647
+#, c-format
+msgid " vbn: %u, pfc: %u, matchctl: %u type: %u ("
+msgstr " vbn: %u, pfc: %u, matchctl: %u тип: %u ("
+
+#: vms-alpha.c:7653
+msgid "NORMAL"
+msgstr "NORMAL"
+
+#: vms-alpha.c:7656
+msgid "SHRFXD"
+msgstr "SHRFXD"
+
+#: vms-alpha.c:7659
+msgid "PRVFXD"
+msgstr "PRVFXD"
+
+#: vms-alpha.c:7662
+msgid "SHRPIC"
+msgstr "SHRPIC"
+
+#: vms-alpha.c:7665
+msgid "PRVPIC"
+msgstr "PRVPIC"
+
+#: vms-alpha.c:7668
+msgid "USRSTACK"
+msgstr "USRSTACK"
+
+#: vms-alpha.c:7676
+#, c-format
+msgid " ident: 0x%08x, name: %.*s\n"
+msgstr " ідентифікатор: 0x%08x, назва: %.*s\n"
+
+#: vms-alpha.c:7686
+#, c-format
+msgid "cannot read DMT\n"
+msgstr "не вдалоÑÑ Ð¿Ñ€Ð¾Ñ‡Ð¸Ñ‚Ð°Ñ‚Ð¸ DMT\n"
+
+#: vms-alpha.c:7690
+#, c-format
+msgid "Debug module table:\n"
+msgstr "Ð¢Ð°Ð±Ð»Ð¸Ñ†Ñ Ð´Ñ–Ð°Ð³Ð½Ð¾Ñтичних Ñимволів:\n"
+
+#: vms-alpha.c:7699
+#, c-format
+msgid "cannot read DMT header\n"
+msgstr "не вдалоÑÑ Ð¿Ñ€Ð¾Ñ‡Ð¸Ñ‚Ð°Ñ‚Ð¸ заголовок DMT\n"
+
+#: vms-alpha.c:7704
+#, c-format
+msgid " module offset: 0x%08x, size: 0x%08x, (%u psects)\n"
+msgstr " відÑтуп модулÑ: 0x%08x, розмір: 0x%08x, (%u psect)\n"
+
+#: vms-alpha.c:7714
+#, c-format
+msgid "cannot read DMT psect\n"
+msgstr "не вдалоÑÑ Ð¿Ñ€Ð¾Ñ‡Ð¸Ñ‚Ð°Ñ‚Ð¸ psect DMT\n"
+
+#: vms-alpha.c:7717
+#, c-format
+msgid " psect start: 0x%08x, length: %u\n"
+msgstr " початок psect: 0x%08x, довжина: %u\n"
+
+#: vms-alpha.c:7730
+#, c-format
+msgid "cannot read DST\n"
+msgstr "не вдалоÑÑ Ð¿Ñ€Ð¾Ñ‡Ð¸Ñ‚Ð°Ñ‚Ð¸ DST\n"
+
+#: vms-alpha.c:7740
+#, c-format
+msgid "cannot read GST\n"
+msgstr "не вдалоÑÑ Ð¿Ñ€Ð¾Ñ‡Ð¸Ñ‚Ð°Ñ‚Ð¸ GST\n"
+
+#: vms-alpha.c:7744
+#, c-format
+msgid "Global symbol table:\n"
+msgstr "Ð¢Ð°Ð±Ð»Ð¸Ñ†Ñ Ð·Ð°Ð³Ð°Ð»ÑŒÐ½Ð¸Ñ… Ñимволів:\n"
+
+#: vms-alpha.c:7772
+#, c-format
+msgid "Image activator fixup: (major: %u, minor: %u)\n"
+msgstr "Прив’Ñзка адреÑи активатора образу: (оÑновна: %u, модифікаціÑ: %u)\n"
+
+#: vms-alpha.c:7775
+#, c-format
+msgid " iaflink : 0x%08x %08x\n"
+msgstr " iaflink : 0x%08x %08x\n"
+
+#: vms-alpha.c:7778
+#, c-format
+msgid " fixuplnk: 0x%08x %08x\n"
+msgstr " fixuplnk: 0x%08x %08x\n"
+
+#: vms-alpha.c:7781
+#, c-format
+msgid " size : %u\n"
+msgstr " розмір: %u\n"
+
+#: vms-alpha.c:7783
+#, c-format
+msgid " flags: 0x%08x\n"
+msgstr " прапорці: 0x%08x\n"
+
+#: vms-alpha.c:7787
+#, c-format
+msgid " qrelfixoff: %5u, lrelfixoff: %5u\n"
+msgstr " qrelfixoff: %5u, lrelfixoff: %5u\n"
+
+#: vms-alpha.c:7791
+#, c-format
+msgid " qdotadroff: %5u, ldotadroff: %5u\n"
+msgstr " qdotadroff: %5u, ldotadroff: %5u\n"
+
+#: vms-alpha.c:7795
+#, c-format
+msgid " codeadroff: %5u, lpfixoff : %5u\n"
+msgstr " codeadroff: %5u, lpfixoff : %5u\n"
+
+#: vms-alpha.c:7798
+#, c-format
+msgid " chgprtoff : %5u\n"
+msgstr " chgprtoff : %5u\n"
+
+#: vms-alpha.c:7801
+#, c-format
+msgid " shlstoff : %5u, shrimgcnt : %5u\n"
+msgstr " shlstoff : %5u, shrimgcnt : %5u\n"
+
+#: vms-alpha.c:7803
+#, c-format
+msgid " shlextra : %5u, permctx : %5u\n"
+msgstr " shlextra : %5u, permctx : %5u\n"
+
+#: vms-alpha.c:7806
+#, c-format
+msgid " base_va : 0x%08x\n"
+msgstr " base_va : 0x%08x\n"
+
+#: vms-alpha.c:7808
+#, c-format
+msgid " lppsbfixoff: %5u\n"
+msgstr " lppsbfixoff: %5u\n"
+
+#: vms-alpha.c:7816
+#, c-format
+msgid " Shareable images:\n"
+msgstr " Образи Ñпільного викориÑтаннÑ:\n"
+
+#: vms-alpha.c:7820
+#, c-format
+msgid " %u: size: %u, flags: 0x%02x, name: %.*s\n"
+msgstr " %u: розмір: %u, прапорці: 0x%02x, назва: %.*s\n"
+
+#: vms-alpha.c:7827
+#, c-format
+msgid " quad-word relocation fixups:\n"
+msgstr " прив’Ñзки переÑувань у чотири Ñлова:\n"
+
+#: vms-alpha.c:7832
+#, c-format
+msgid " long-word relocation fixups:\n"
+msgstr " прив’Ñзки переÑувань у довге Ñлово:\n"
+
+#: vms-alpha.c:7837
+#, c-format
+msgid " quad-word .address reference fixups:\n"
+msgstr " прив’Ñзки поÑилань .address у чотири Ñлова:\n"
+
+#: vms-alpha.c:7842
+#, c-format
+msgid " long-word .address reference fixups:\n"
+msgstr " прив’Ñзки поÑилань .address у довге Ñлово:\n"
+
+#: vms-alpha.c:7847
+#, c-format
+msgid " Code Address Reference Fixups:\n"
+msgstr " Прив’Ñзки Ð°Ð´Ñ€ÐµÑ ÐºÐ¾Ð´Ñƒ:\n"
+
+#: vms-alpha.c:7852
+#, c-format
+msgid " Linkage Pairs Referece Fixups:\n"
+msgstr " Прив’Ñзки поÑилань на пари компонуваннÑ:\n"
+
+#: vms-alpha.c:7861
+#, c-format
+msgid " Change Protection (%u entries):\n"
+msgstr " Зміна захиÑту (%u запиÑи):\n"
+
+#: vms-alpha.c:7866
+#, c-format
+msgid " base: 0x%08x %08x, size: 0x%08x, prot: 0x%08x "
+msgstr " оÑн.: 0x%08x %08x, розм: 0x%08x, зах.: 0x%08x "
+
+#. FIXME: we do not yet support relocatable link. It is not obvious
+#. how to do it for debug infos.
+#: vms-alpha.c:8706
+msgid "%P: relocatable link is not supported\n"
+msgstr "%P: підтримки ÐºÐ¾Ð¼Ð¿Ð¾Ð½ÑƒÐ²Ð°Ð½Ð½Ñ Ð· можливіÑÑ‚ÑŽ переÑÑƒÐ²Ð°Ð½Ð½Ñ Ð½Ðµ передбачено\n"
+
+#: vms-alpha.c:8776
+msgid "%P: multiple entry points: in modules %B and %B\n"
+msgstr "%P: декілька точок входженнÑ: у модулÑÑ… %B Ñ– %B\n"
+
+#: vms-lib.c:1423
+#, c-format
+msgid "could not open shared image '%s' from '%s'"
+msgstr "не вдалоÑÑ Ð²Ñ–Ð´ÐºÑ€Ð¸Ñ‚Ð¸ образ Ñпільного викориÑÑ‚Ð°Ð½Ð½Ñ Â«%s» з «%s»"
+
+#: vms-misc.c:360
+msgid "_bfd_vms_output_counted called with zero bytes"
+msgstr "_bfd_vms_output_counted викликано Ð´Ð»Ñ Ð½ÑƒÐ»ÑŒÐ¾Ð²Ð¾Ñ— кількоÑÑ‚Ñ– байтів"
+
+#: vms-misc.c:365
+msgid "_bfd_vms_output_counted called with too many bytes"
+msgstr "_bfd_vms_output_counted викликано Ð´Ð»Ñ Ð·Ð°Ð½Ð°Ð´Ñ‚Ð¾ великої кількоÑÑ‚Ñ– байтів"
+
+#: xcofflink.c:836
+#, c-format
+msgid "%s: XCOFF shared object when not producing XCOFF output"
+msgstr "%s: Ñпільний об’єкт XCOFF, хоча дані XCOFF не ÑтворюютьÑÑ"
+
+#: xcofflink.c:857
+#, c-format
+msgid "%s: dynamic object with no .loader section"
+msgstr "%s: динамічний об’єкт без розділу .loader"
+
+#: xcofflink.c:1416
+msgid "%B: `%s' has line numbers but no enclosing section"
+msgstr "%B: «%s» міÑтить номери Ñ€Ñдків, але не міÑтить завершального розділу"
+
+#: xcofflink.c:1468
+msgid "%B: class %d symbol `%s' has no aux entries"
+msgstr "%B: ÐºÐ»Ð°Ñ %d, Ñимвол «%s» не має допоміжних запиÑів"
+
+#: xcofflink.c:1490
+msgid "%B: symbol `%s' has unrecognized csect type %d"
+msgstr "B: Ñимвол «%s» належить до нерозпізнаного типу csect %d"
+
+#: xcofflink.c:1502
+msgid "%B: bad XTY_ER symbol `%s': class %d scnum %d scnlen %d"
+msgstr "%B: помилковий Ñимвол XTY_ER «%s»: ÐºÐ»Ð°Ñ %d, номер розділу %d, довжина розділу %d"
+
+#: xcofflink.c:1531
+msgid "%B: XMC_TC0 symbol `%s' is class %d scnlen %d"
+msgstr "%B: Ñимвол XMC_TC0 «%s» Ñ” клаÑом %d, довжина розділу %d"
+
+#: xcofflink.c:1677
+msgid "%B: csect `%s' not in enclosing section"
+msgstr "%B: csect «%s» не у завершальному розділі"
+
+#: xcofflink.c:1784
+msgid "%B: misplaced XTY_LD `%s'"
+msgstr "%B: помилкове Ñ€Ð¾Ð·Ñ‚Ð°ÑˆÑƒÐ²Ð°Ð½Ð½Ñ XTY_LD «%s»"
+
+#: xcofflink.c:2103
+msgid "%B: reloc %s:%d not in csect"
+msgstr "%B: переÑÑƒÐ²Ð°Ð½Ð½Ñ %s:%d не у csect"
+
+#: xcofflink.c:3194
+#, c-format
+msgid "%s: no such symbol"
+msgstr "%s: немає такого Ñимволу"
+
+#: xcofflink.c:3299
+#, c-format
+msgid "warning: attempt to export undefined symbol `%s'"
+msgstr "попередженнÑ: Ñпроба екÑÐ¿Ð¾Ñ€Ñ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð½ÐµÐ²Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¾Ð³Ð¾ Ñимволу «%s»"
+
+#: xcofflink.c:3678
+msgid "error: undefined symbol __rtinit"
+msgstr "помилка: невизначений Ñимвол __rtinit"
+
+#: xcofflink.c:4057
+msgid "%B: loader reloc in unrecognized section `%s'"
+msgstr "%B: переÑÑƒÐ²Ð°Ð½Ð½Ñ Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÑƒÐ²Ð°Ñ‡Ð° у нерозпізнаному розділі «%s»"
+
+#: xcofflink.c:4068
+msgid "%B: `%s' in loader reloc but not loader sym"
+msgstr "%B: «%s» у переÑуванні завантажувача, але не у Ñимволах завантаженнÑ"
+
+#: xcofflink.c:4084
+msgid "%B: loader reloc in read-only section %A"
+msgstr "%B: переÑÑƒÐ²Ð°Ð½Ð½Ñ Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÑƒÐ²Ð°Ñ‡Ð° у розділі, призначеному лише Ð´Ð»Ñ Ñ‡Ð¸Ñ‚Ð°Ð½Ð½Ñ, %A"
+
+#: xcofflink.c:5106
+#, c-format
+msgid "TOC overflow: 0x%lx > 0x10000; try -mminimal-toc when compiling"
+msgstr "ÐŸÐµÑ€ÐµÐ¿Ð¾Ð²Ð½ÐµÐ½Ð½Ñ TOC: 0x%lx > 0x10000; Ñпробуйте параметр -mminimal-toc під Ñ‡Ð°Ñ Ð·Ð±Ð¸Ñ€Ð°Ð½Ð½Ñ"
+
+#: elf32-ia64.c:628 elf64-ia64.c:628
+msgid "%B: Can't relax br at 0x%lx in section `%A'. Please use brl or indirect branch."
+msgstr "%B: не вдалоÑÑ Ð¾Ð¿Ñ‚Ð¸Ð¼Ñ–Ð·ÑƒÐ²Ð°Ñ‚Ð¸ br за адреÑою 0x%lx у розділі «%A». Будь лаÑка, ÑкориÑтайтеÑÑ brl або непрÑмим відгалуженнÑм."
+
+#: elf32-ia64.c:2284 elf64-ia64.c:2284
+msgid "@pltoff reloc against local symbol"
+msgstr "переÑÑƒÐ²Ð°Ð½Ð½Ñ @pltoff щодо локального Ñимволу"
+
+#: elf32-ia64.c:3687 elf64-ia64.c:3687
+#, c-format
+msgid "%s: short data segment overflowed (0x%lx >= 0x400000)"
+msgstr "%s: переповнено короткий Ñегмент даних (0x%lx >= 0x400000)"
+
+#: elf32-ia64.c:3698 elf64-ia64.c:3698
+#, c-format
+msgid "%s: __gp does not cover short data segment"
+msgstr "%s: __gp не вкриває короткого Ñегмента даних"
+
+#: elf32-ia64.c:3965 elf64-ia64.c:3965
+msgid "%B: non-pic code with imm relocation against dynamic symbol `%s'"
+msgstr "%B: не-pic код з переÑуваннÑм imm щодо динамічного Ñимволу «%s»"
+
+#: elf32-ia64.c:4032 elf64-ia64.c:4032
+msgid "%B: @gprel relocation against dynamic symbol %s"
+msgstr "%B: переÑÑƒÐ²Ð°Ð½Ð½Ñ @gprel щодо динамічного Ñимволу %s"
+
+#: elf32-ia64.c:4095 elf64-ia64.c:4095
+msgid "%B: linking non-pic code in a position independent executable"
+msgstr "%B: ÐºÐ¾Ð¼Ð¿Ð¾Ð½ÑƒÐ²Ð°Ð½Ð½Ñ Ð½Ðµ-pic коду у виконуваному файлі з незалежним позиціюваннÑм"
+
+#: elf32-ia64.c:4232 elf64-ia64.c:4232
+msgid "%B: @internal branch to dynamic symbol %s"
+msgstr "%B: Ð²Ñ–Ð´Ð³Ð°Ð»ÑƒÐ¶ÐµÐ½Ð½Ñ @internal до динамічного Ñимволу %s"
+
+#: elf32-ia64.c:4234 elf64-ia64.c:4234
+msgid "%B: speculation fixup to dynamic symbol %s"
+msgstr "%B: здогадка щодо адреÑної прив’Ñзки до динамічного Ñимволу %s"
+
+#: elf32-ia64.c:4236 elf64-ia64.c:4236
+msgid "%B: @pcrel relocation against dynamic symbol %s"
+msgstr "%B: переÑÑƒÐ²Ð°Ð½Ð½Ñ @pcrel щодо динамічного Ñимволу %s"
+
+#: elf32-ia64.c:4433 elf64-ia64.c:4433
+msgid "unsupported reloc"
+msgstr "непідтримуване переÑуваннÑ"
+
+#: elf32-ia64.c:4471 elf64-ia64.c:4471
+msgid "%B: missing TLS section for relocation %s against `%s' at 0x%lx in section `%A'."
+msgstr "%B: не виÑтачає розділу TLS Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÑÑƒÐ²Ð°Ð½Ð½Ñ %s щодо «%s» за адреÑою 0x%lx у розділі «%A»."
+
+#: elf32-ia64.c:4486 elf64-ia64.c:4486
+msgid "%B: Can't relax br (%s) to `%s' at 0x%lx in section `%A' with size 0x%lx (> 0x1000000)."
+msgstr "%B: не вдалоÑÑ Ð¾Ð¿Ñ‚Ð¸Ð¼Ñ–Ð·ÑƒÐ²Ð°Ñ‚Ð¸ br (%s) до «%s» за адреÑою 0x%lx у розділі «%A» з розміром 0x%lx (> 0x1000000)."
+
+#: elf32-ia64.c:4748 elf64-ia64.c:4748
+msgid "%B: linking trap-on-NULL-dereference with non-trapping files"
+msgstr "%B: ÐºÐ¾Ð¼Ð¿Ð¾Ð½ÑƒÐ²Ð°Ð½Ð½Ñ trap-on-NULL-dereference з файлами без Ð·Ð°Ñ…Ð¾Ð¿Ð»ÐµÐ½Ð½Ñ (trapping)"
+
+#: elf32-ia64.c:4757 elf64-ia64.c:4757
+msgid "%B: linking big-endian files with little-endian files"
+msgstr "%B: ÐºÐ¾Ð¼Ð¿Ð¾Ð½ÑƒÐ²Ð°Ð½Ð½Ñ Ñ„Ð°Ð¹Ð»Ñ–Ð² зі прÑмим порÑдком байтів з файлами зі зворотним порÑдком байтів"
+
+#: elf32-ia64.c:4766 elf64-ia64.c:4766
+msgid "%B: linking 64-bit files with 32-bit files"
+msgstr "%B: ÐºÐ¾Ð¼Ð¿Ð¾Ð½ÑƒÐ²Ð°Ð½Ð½Ñ 64-бітових файлів з 32-бітовими файлами"
+
+#: elf32-ia64.c:4775 elf64-ia64.c:4775
+msgid "%B: linking constant-gp files with non-constant-gp files"
+msgstr "%B: ÐºÐ¾Ð¼Ð¿Ð¾Ð½ÑƒÐ²Ð°Ð½Ð½Ñ Ñ„Ð°Ð¹Ð»Ñ–Ð² зі Ñталим gp з файлами зі змінним gp"
+
+#: elf32-ia64.c:4785 elf64-ia64.c:4785
+msgid "%B: linking auto-pic files with non-auto-pic files"
+msgstr "%B: ÐºÐ¾Ð¼Ð¿Ð¾Ð½ÑƒÐ²Ð°Ð½Ð½Ñ Ñ„Ð°Ð¹Ð»Ñ–Ð² з автоматичним pic з файлами без автоматичного pic"
+
+#: peigen.c:1002 pepigen.c:1002 pex64igen.c:1002
+#, c-format
+msgid "%s: line number overflow: 0x%lx > 0xffff"
+msgstr "%s: Ð¿ÐµÑ€ÐµÐ¿Ð¾Ð²Ð½ÐµÐ½Ð½Ñ Ð½Ð¾Ð¼ÐµÑ€Ñ–Ð² Ñ€Ñдків; 0x%lx > 0xffff"
+
+#: peigen.c:1029 pepigen.c:1029 pex64igen.c:1029
+msgid "Export Directory [.edata (or where ever we found it)]"
+msgstr "Каталог екÑÐ¿Ð¾Ñ€Ñ‚ÑƒÐ²Ð°Ð½Ð½Ñ [.edata (або інше міÑце, де його знайдено)]"
+
+#: peigen.c:1030 pepigen.c:1030 pex64igen.c:1030
+msgid "Import Directory [parts of .idata]"
+msgstr "Каталог Ñ–Ð¼Ð¿Ð¾Ñ€Ñ‚ÑƒÐ²Ð°Ð½Ð½Ñ [чаÑтини .idata]"
+
+#: peigen.c:1031 pepigen.c:1031 pex64igen.c:1031
+msgid "Resource Directory [.rsrc]"
+msgstr "Каталог реÑурÑів [.rsrc]"
+
+#: peigen.c:1032 pepigen.c:1032 pex64igen.c:1032
+msgid "Exception Directory [.pdata]"
+msgstr "Каталог виключень [.pdata]"
+
+#: peigen.c:1033 pepigen.c:1033 pex64igen.c:1033
+msgid "Security Directory"
+msgstr "Каталог захиÑту"
+
+#: peigen.c:1034 pepigen.c:1034 pex64igen.c:1034
+msgid "Base Relocation Directory [.reloc]"
+msgstr "Каталог базового переÑÑƒÐ²Ð°Ð½Ð½Ñ [.reloc]"
+
+#: peigen.c:1035 pepigen.c:1035 pex64igen.c:1035
+msgid "Debug Directory"
+msgstr "Каталог діагноÑтики"
+
+#: peigen.c:1036 pepigen.c:1036 pex64igen.c:1036
+msgid "Description Directory"
+msgstr "Каталог опиÑів"
+
+#: peigen.c:1037 pepigen.c:1037 pex64igen.c:1037
+msgid "Special Directory"
+msgstr "ОÑобливий каталог"
+
+#: peigen.c:1038 pepigen.c:1038 pex64igen.c:1038
+msgid "Thread Storage Directory [.tls]"
+msgstr "Каталог Ð·Ð±ÐµÑ€Ñ–Ð³Ð°Ð½Ð½Ñ Ð¿Ð¾Ñ‚Ð¾ÐºÑ–Ð² [.tls]"
+
+#: peigen.c:1039 pepigen.c:1039 pex64igen.c:1039
+msgid "Load Configuration Directory"
+msgstr "Каталог Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ Ð½Ð°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½ÑŒ"
+
+#: peigen.c:1040 pepigen.c:1040 pex64igen.c:1040
+msgid "Bound Import Directory"
+msgstr "Каталог вимушеного імпортуваннÑ"
+
+#: peigen.c:1041 pepigen.c:1041 pex64igen.c:1041
+msgid "Import Address Table Directory"
+msgstr "Каталог Ñ–Ð¼Ð¿Ð¾Ñ€Ñ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ñ‚Ð°Ð±Ð»Ð¸Ñ†Ñ– адреÑ"
+
+#: peigen.c:1042 pepigen.c:1042 pex64igen.c:1042
+msgid "Delay Import Directory"
+msgstr "Каталог відкладеного імпортуваннÑ"
+
+#: peigen.c:1043 pepigen.c:1043 pex64igen.c:1043
+msgid "CLR Runtime Header"
+msgstr "Динамічний заголовок CLR"
+
+#: peigen.c:1044 pepigen.c:1044 pex64igen.c:1044
+msgid "Reserved"
+msgstr "Зарезервовано"
+
+#: peigen.c:1104 pepigen.c:1104 pex64igen.c:1104
+#, c-format
+msgid ""
+"\n"
+"There is an import table, but the section containing it could not be found\n"
+msgstr ""
+"\n"
+"ІÑнує Ñ‚Ð°Ð±Ð»Ð¸Ñ†Ñ Ñ–Ð¼Ð¿Ð¾Ñ€Ñ‚ÑƒÐ²Ð°Ð½Ð½Ñ, але розділу, що Ñ—Ñ— міÑтить не знайдено\n"
+
+#: peigen.c:1109 pepigen.c:1109 pex64igen.c:1109
+#, c-format
+msgid ""
+"\n"
+"There is an import table in %s at 0x%lx\n"
+msgstr ""
+"\n"
+"У %s зберігаєтьÑÑ Ñ‚Ð°Ð±Ð»Ð¸Ñ†Ñ Ñ–Ð¼Ð¿Ð¾Ñ€Ñ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ñƒ 0x%lx\n"
+
+#: peigen.c:1151 pepigen.c:1151 pex64igen.c:1151
+#, c-format
+msgid ""
+"\n"
+"Function descriptor located at the start address: %04lx\n"
+msgstr ""
+"\n"
+"ДеÑкриптор функції розташовано за початковою адреÑою %04lx\n"
+
+#: peigen.c:1154 pepigen.c:1154 pex64igen.c:1154
+#, c-format
+msgid "\tcode-base %08lx toc (loadable/actual) %08lx/%08lx\n"
+msgstr "\ttoc оÑнови коду %08lx (завантажуваний/дійÑний) %08lx/%08lx\n"
+
+#: peigen.c:1162 pepigen.c:1162 pex64igen.c:1162
+#, c-format
+msgid ""
+"\n"
+"No reldata section! Function descriptor not decoded.\n"
+msgstr ""
+"\n"
+"Ðемає розділу reldata! ДеÑкриптор функції не розшифровано.\n"
+
+#: peigen.c:1167 pepigen.c:1167 pex64igen.c:1167
+#, c-format
+msgid ""
+"\n"
+"The Import Tables (interpreted %s section contents)\n"
+msgstr ""
+"\n"
+"Таблиці Ñ–Ð¼Ð¿Ð¾Ñ€Ñ‚ÑƒÐ²Ð°Ð½Ð½Ñ (оброблений вміÑÑ‚ розділу %s)\n"
+
+#: peigen.c:1170 pepigen.c:1170 pex64igen.c:1170
+#, c-format
+msgid ""
+" vma: Hint Time Forward DLL First\n"
+" Table Stamp Chain Name Thunk\n"
+msgstr ""
+" vma: Ð¢Ð°Ð±Ð»Ð¸Ñ†Ñ Ð§Ð°Ñова Ланцюжок Ðазва Перший\n"
+" вказ. Позначка ÑпрÑм. DLL шлюз\n"
+
+#: peigen.c:1218 pepigen.c:1218 pex64igen.c:1218
+#, c-format
+msgid ""
+"\n"
+"\tDLL Name: %s\n"
+msgstr ""
+"\n"
+"\tÐазва DLL: %s\n"
+
+#: peigen.c:1229 pepigen.c:1229 pex64igen.c:1229
+#, c-format
+msgid "\tvma: Hint/Ord Member-Name Bound-To\n"
+msgstr "\tvma: Вказ/Пор Ðазва-елемента Прив’Ñзано-до\n"
+
+#: peigen.c:1254 pepigen.c:1254 pex64igen.c:1254
+#, c-format
+msgid ""
+"\n"
+"There is a first thunk, but the section containing it could not be found\n"
+msgstr ""
+"\n"
+"ІÑнує Ð·Ð°Ð¿Ð¸Ñ Ð¿ÐµÑ€ÑˆÐ¾Ð³Ð¾ переходу, але розділу, що його міÑтить не знайдено\n"
+
+#: peigen.c:1415 pepigen.c:1415 pex64igen.c:1415
+#, c-format
+msgid ""
+"\n"
+"There is an export table, but the section containing it could not be found\n"
+msgstr ""
+"\n"
+"ІÑнує Ð·Ð°Ð¿Ð¸Ñ Ñ‚Ð°Ð±Ð»Ð¸Ñ†Ñ– екÑпортуваннÑ, але розділу, що Ñ—Ñ— міÑтить не знайдено\n"
+
+#: peigen.c:1424 pepigen.c:1424 pex64igen.c:1424
+#, c-format
+msgid ""
+"\n"
+"There is an export table in %s, but it does not fit into that section\n"
+msgstr ""
+"\n"
+"У %s зберігаєтьÑÑ Ñ‚Ð°Ð±Ð»Ð¸Ñ†Ñ ÐµÐºÑпортуваннÑ, але Ñ—Ñ— не можна вміÑтити у цьому розділі\n"
+
+#: peigen.c:1430 pepigen.c:1430 pex64igen.c:1430
+#, c-format
+msgid ""
+"\n"
+"There is an export table in %s at 0x%lx\n"
+msgstr ""
+"\n"
+"У %s зберігаєтьÑÑ Ñ‚Ð°Ð±Ð»Ð¸Ñ†Ñ ÐµÐºÑÐ¿Ð¾Ñ€Ñ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ñƒ 0x%lx\n"
+
+#: peigen.c:1458 pepigen.c:1458 pex64igen.c:1458
+#, c-format
+msgid ""
+"\n"
+"The Export Tables (interpreted %s section contents)\n"
+"\n"
+msgstr ""
+"\n"
+"Таблиці екÑÐ¿Ð¾Ñ€Ñ‚ÑƒÐ²Ð°Ð½Ð½Ñ (оброблений вміÑÑ‚ розділу %s)\n"
+
+#: peigen.c:1462 pepigen.c:1462 pex64igen.c:1462
+#, c-format
+msgid "Export Flags \t\t\t%lx\n"
+msgstr "Прапорці екÑпортуваннÑ\t\t%lx\n"
+
+#: peigen.c:1465 pepigen.c:1465 pex64igen.c:1465
+#, c-format
+msgid "Time/Date stamp \t\t%lx\n"
+msgstr "Позначка чаÑу/дати\t\t%lx\n"
+
+#: peigen.c:1468 pepigen.c:1468 pex64igen.c:1468
+#, c-format
+msgid "Major/Minor \t\t\t%d/%d\n"
+msgstr "ОÑновна/ÐœÐ¾Ð´Ð¸Ñ„Ñ–ÐºÐ°Ñ†Ñ–Ñ \t\t\t%d/%d\n"
+
+#: peigen.c:1471 pepigen.c:1471 pex64igen.c:1471
+#, c-format
+msgid "Name \t\t\t\t"
+msgstr "Ðазва\t\t\t\t"
+
+#: peigen.c:1477 pepigen.c:1477 pex64igen.c:1477
+#, c-format
+msgid "Ordinal Base \t\t\t%ld\n"
+msgstr "ОÑнова впорÑдковуваннÑ\t\t%ld\n"
+
+#: peigen.c:1480 pepigen.c:1480 pex64igen.c:1480
+#, c-format
+msgid "Number in:\n"
+msgstr "Ðомер у:\n"
+
+#: peigen.c:1483 pepigen.c:1483 pex64igen.c:1483
+#, c-format
+msgid "\tExport Address Table \t\t%08lx\n"
+msgstr "\tÐ¢Ð°Ð±Ð»Ð¸Ñ†Ñ ÐµÐºÑпортованих Ð°Ð´Ñ€ÐµÑ \t\t%08lx\n"
+
+#: peigen.c:1487 pepigen.c:1487 pex64igen.c:1487
+#, c-format
+msgid "\t[Name Pointer/Ordinal] Table\t%08lx\n"
+msgstr "\tÐ¢Ð°Ð±Ð»Ð¸Ñ†Ñ [вказівників назв/порÑдкових номерів]\t%08lx\n"
+
+#: peigen.c:1490 pepigen.c:1490 pex64igen.c:1490
+#, c-format
+msgid "Table Addresses\n"
+msgstr "Табличні адреÑи\n"
+
+#: peigen.c:1493 pepigen.c:1493 pex64igen.c:1493
+#, c-format
+msgid "\tExport Address Table \t\t"
+msgstr "\tÐ¢Ð°Ð±Ð»Ð¸Ñ†Ñ ÐµÐºÑпортованих Ð°Ð´Ñ€ÐµÑ \t\t"
+
+#: peigen.c:1498 pepigen.c:1498 pex64igen.c:1498
+#, c-format
+msgid "\tName Pointer Table \t\t"
+msgstr "\tÐ¢Ð°Ð±Ð»Ð¸Ñ†Ñ Ð²ÐºÐ°Ð·Ñ–Ð²Ð½Ð¸ÐºÑ–Ð² на назви \t\t"
+
+#: peigen.c:1503 pepigen.c:1503 pex64igen.c:1503
+#, c-format
+msgid "\tOrdinal Table \t\t\t"
+msgstr "\tÐ¢Ð°Ð±Ð»Ð¸Ñ†Ñ Ð½Ð¾Ð¼ÐµÑ€Ñ–Ð² \t\t\t"
+
+#: peigen.c:1517 pepigen.c:1517 pex64igen.c:1517
+#, c-format
+msgid ""
+"\n"
+"Export Address Table -- Ordinal Base %ld\n"
+msgstr ""
+"\n"
+"Ð¢Ð°Ð±Ð»Ð¸Ñ†Ñ ÐµÐºÑпортованих Ð°Ð´Ñ€ÐµÑ â€” оÑнова порÑдкових номерів: %ld\n"
+
+#: peigen.c:1536 pepigen.c:1536 pex64igen.c:1536
+msgid "Forwarder RVA"
+msgstr "ПереÑпрÑмовний RVA"
+
+#: peigen.c:1547 pepigen.c:1547 pex64igen.c:1547
+msgid "Export RVA"
+msgstr "ЕкÑпортований RVA"
+
+#: peigen.c:1554 pepigen.c:1554 pex64igen.c:1554
+#, c-format
+msgid ""
+"\n"
+"[Ordinal/Name Pointer] Table\n"
+msgstr ""
+"\n"
+"Ð¢Ð°Ð±Ð»Ð¸Ñ†Ñ [порÑдкових номерів/вказівників на назви]\n"
+
+#: peigen.c:1614 peigen.c:1797 pepigen.c:1614 pepigen.c:1797 pex64igen.c:1614
+#: pex64igen.c:1797
+#, c-format
+msgid "Warning, .pdata section size (%ld) is not a multiple of %d\n"
+msgstr "ПопередженнÑ: розмір розділу .pdata (%ld) не Ñ” кратним до %d\n"
+
+#: peigen.c:1621 pepigen.c:1621 pex64igen.c:1621
+#, c-format
+msgid " vma:\t\t\tBegin Address End Address Unwind Info\n"
+msgstr " vma:\t\t\tПочат. адреÑа Кінц. адреÑа Дані unwind\n"
+
+#: peigen.c:1623 pepigen.c:1623 pex64igen.c:1623
+#, c-format
+msgid ""
+" vma:\t\tBegin End EH EH PrologEnd Exception\n"
+" \t\tAddress Address Handler Data Address Mask\n"
+msgstr ""
+" vma:\t\tПоч. Кінц. Обробник Дані ÐдреÑа МаÑка\n"
+" \t\tадреÑа адреÑа EH EH кінц. прол.виключеннÑ\n"
+
+#: peigen.c:1697 pepigen.c:1697 pex64igen.c:1697
+#, c-format
+msgid " Register save millicode"
+msgstr " Мілікод Ð·Ð±ÐµÑ€ÐµÐ¶ÐµÐ½Ð½Ñ Ñ€ÐµÐ³Ñ–Ñтра"
+
+#: peigen.c:1700 pepigen.c:1700 pex64igen.c:1700
+#, c-format
+msgid " Register restore millicode"
+msgstr " Мілікод Ð²Ñ–Ð´Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ñ€ÐµÐ³Ñ–Ñтра"
+
+#: peigen.c:1703 pepigen.c:1703 pex64igen.c:1703
+#, c-format
+msgid " Glue code sequence"
+msgstr " ПоÑлідовніÑÑ‚ÑŒ з’єднувального коду"
+
+#: peigen.c:1803 pepigen.c:1803 pex64igen.c:1803
+#, c-format
+msgid ""
+" vma:\t\tBegin Prolog Function Flags Exception EH\n"
+" \t\tAddress Length Length 32b exc Handler Data\n"
+msgstr ""
+" vma:\t\tПоч. Довжина Довжина Прапорці Обробник Дані\n"
+" \t\tадреÑа прологу функції 32б вик. виключень EH\n"
+
+#: peigen.c:1929 pepigen.c:1929 pex64igen.c:1929
+#, c-format
+msgid ""
+"\n"
+"\n"
+"PE File Base Relocations (interpreted .reloc section contents)\n"
+msgstr ""
+"\n"
+"\n"
+"ПереÑÑƒÐ²Ð°Ð½Ð½Ñ Ñ‰Ð¾Ð´Ð¾ оÑнови файла PE (оброблений вміÑÑ‚ розділу .reloc)\n"
+
+#: peigen.c:1958 pepigen.c:1958 pex64igen.c:1958
+#, c-format
+msgid ""
+"\n"
+"Virtual Address: %08lx Chunk size %ld (0x%lx) Number of fixups %ld\n"
+msgstr ""
+"\n"
+"Віртуальна адреÑа: %08lx, розмір фрагмента: %ld (0x%lx), кількіÑÑ‚ÑŒ прив’Ñзок: %ld\n"
+
+#: peigen.c:1971 pepigen.c:1971 pex64igen.c:1971
+#, c-format
+msgid "\treloc %4d offset %4x [%4lx] %s"
+msgstr "\tпереÑÑƒÐ²Ð°Ð½Ð½Ñ %4d відÑтуп %4x [%4lx] %s"
+
+#. The MS dumpbin program reportedly ands with 0xff0f before
+#. printing the characteristics field. Not sure why. No reason to
+#. emulate it here.
+#: peigen.c:2010 pepigen.c:2010 pex64igen.c:2010
+#, c-format
+msgid ""
+"\n"
+"Characteristics 0x%x\n"
+msgstr ""
+"\n"
+"ХарактериÑтики 0x%x\n"
+
+#: peigen.c:2310 pepigen.c:2310 pex64igen.c:2310
+msgid "%B: unable to fill in DataDictionary[1] because .idata$2 is missing"
+msgstr "%B: не вдалоÑÑ Ð·Ð°Ð¿Ð¾Ð²Ð½Ð¸Ñ‚Ð¸ DataDictionary[1], оÑкільки не виÑтачає .idata$2"
+
+#: peigen.c:2330 pepigen.c:2330 pex64igen.c:2330
+msgid "%B: unable to fill in DataDictionary[1] because .idata$4 is missing"
+msgstr "%B: не вдалоÑÑ Ð·Ð°Ð¿Ð¾Ð²Ð½Ð¸Ñ‚Ð¸ DataDictionary[1], оÑкільки не виÑтачає .idata$4"
+
+#: peigen.c:2351 pepigen.c:2351 pex64igen.c:2351
+msgid "%B: unable to fill in DataDictionary[12] because .idata$5 is missing"
+msgstr "%B: не вдалоÑÑ Ð·Ð°Ð¿Ð¾Ð²Ð½Ð¸Ñ‚Ð¸ DataDictionary[12], оÑкільки не виÑтачає .idata$5"
+
+#: peigen.c:2371 pepigen.c:2371 pex64igen.c:2371
+msgid "%B: unable to fill in DataDictionary[PE_IMPORT_ADDRESS_TABLE (12)] because .idata$6 is missing"
+msgstr "%B: не вдалоÑÑ Ð·Ð°Ð¿Ð¾Ð²Ð½Ð¸Ñ‚Ð¸ DataDictionary[PE_IMPORT_ADDRESS_TABLE (12)], оÑкільки не виÑтачає .idata$6"
+
+#: peigen.c:2413 pepigen.c:2413 pex64igen.c:2413
+msgid "%B: unable to fill in DataDictionary[PE_IMPORT_ADDRESS_TABLE(12)] because .idata$6 is missing"
+msgstr "%B: не вдалоÑÑ Ð·Ð°Ð¿Ð¾Ð²Ð½Ð¸Ñ‚Ð¸ DataDictionary[PE_IMPORT_ADDRESS_TABLE(12)], оÑкільки .idata$6 не виÑтачає"
+
+#: peigen.c:2438 pepigen.c:2438 pex64igen.c:2438
+msgid "%B: unable to fill in DataDictionary[9] because __tls_used is missing"
+msgstr "%B: не вдалоÑÑ Ð·Ð°Ð¿Ð¾Ð²Ð½Ð¸Ñ‚Ð¸ DataDictionary[9], оÑкільки не виÑтачає __tls_used"
+
+#~ msgid "%B: error: taking the address of protected function '%s' cannot be done when making a shared library"
+#~ msgstr "%B: помилка: не можна виконувати Ð¾Ñ‚Ñ€Ð¸Ð¼Ð°Ð½Ð½Ñ Ð°Ð´Ñ€ÐµÑи захищеної функції «%s» під Ñ‡Ð°Ñ ÑÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ð±Ñ–Ð±Ð»Ñ–Ð¾Ñ‚ÐµÐºÐ¸ Ñпільного викориÑтаннÑ"
diff --git a/bfd/po/vi.gmo b/bfd/po/vi.gmo
new file mode 100644
index 0000000..0687a74
--- /dev/null
+++ b/bfd/po/vi.gmo
Binary files differ
diff --git a/bfd/po/vi.po b/bfd/po/vi.po
new file mode 100644
index 0000000..4f62e60
--- /dev/null
+++ b/bfd/po/vi.po
@@ -0,0 +1,6344 @@
+# Vietnamese translation for BFD.
+# Copyright © 2012 Free Software Foundation, Inc.
+# This file is distributed under the same license as the binutils package.
+# Phan Vĩnh Thịnh <teppi@gmail.com>, 2005.
+# Clytie Siddall <clytie@riverland.net.au>, 2008-2010.
+# Trần Ngá»c Quân <vnwildman@gmail.com>, 2012.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: bfd-2.22.90\n"
+"Report-Msgid-Bugs-To: bug-binutils@gnu.org\n"
+"POT-Creation-Date: 2011-10-25 11:58+0100\n"
+"PO-Revision-Date: 2012-08-15 14:47+0700\n"
+"Last-Translator: Trần Ngá»c Quân <vnwildman@gmail.com>\n"
+"Language-Team: Vietnamese <translation-team-vi@lists.sourceforge.net>\n"
+"Language: vi\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+"X-Generator: LocFactoryEditor 1.8\n"
+"X-Poedit-Language: Vietnamese\n"
+"X-Poedit-Country: VIET NAM\n"
+"X-Poedit-SourceCharset: utf-8\n"
+
+#: aout-adobe.c:127
+msgid "%B: Unknown section type in a.out.adobe file: %x\n"
+msgstr "%B: Không rõ kiểu phần trong tập tin a.out.adobe: %x\n"
+
+#: aout-cris.c:199
+#, c-format
+msgid "%s: Invalid relocation type exported: %d"
+msgstr "%s: Äã xuất kiểu định vị lại không hợp lệ: %d"
+
+#: aout-cris.c:242
+msgid "%B: Invalid relocation type imported: %d"
+msgstr "%B: Äã nhập kiểu định vị lại không hợp lệ: %d"
+
+#: aout-cris.c:253
+msgid "%B: Bad relocation record imported: %d"
+msgstr "%B: Äã nhập mục ghi định vị lại sai: %d"
+
+#: aoutx.h:1273 aoutx.h:1611
+#, c-format
+msgid "%s: can not represent section `%s' in a.out object file format"
+msgstr "%s: không thể đại diện phân \"%s\" trong định dạng tập tin đối tượng a.out"
+
+#: aoutx.h:1577
+#, c-format
+msgid "%s: can not represent section for symbol `%s' in a.out object file format"
+msgstr "%s: không thể đại diện phân cho ký hiệu \"%s\" trong định dạng tập tin đối tượng a.ou"
+
+#: aoutx.h:1579 vms-alpha.c:7671
+msgid "*unknown*"
+msgstr "• không rõ •"
+
+#: aoutx.h:4018 aoutx.h:4344
+msgid "%P: %B: unexpected relocation type\n"
+msgstr "%P: %B: kiểu định vị lại bất thÆ°á»ng\n"
+
+#: aoutx.h:5375
+#, c-format
+msgid "%s: relocatable link from %s to %s not supported"
+msgstr "%s: không hỗ trợ liên kết có khả năng định vị lại từ %s sang %s"
+
+#: archive.c:2203
+msgid "Warning: writing archive was slow: rewriting timestamp\n"
+msgstr "Cảnh báo: ghi kho quá chậm nên Ä‘ang ghi lại nhãn thá»i gian\n"
+
+#: archive.c:2491
+msgid "Reading archive file mod timestamp"
+msgstr "Äang Ä‘á»c nhãn thá»i gian sá»­a đổi tập tin kho"
+
+#: archive.c:2515
+msgid "Writing updated armap timestamp"
+msgstr "Äang ghi nhãn thá»i gian armap đã cập nhật"
+
+#: bfd.c:398
+msgid "No error"
+msgstr "Không có lỗi"
+
+#: bfd.c:399
+msgid "System call error"
+msgstr "Lá»—i gá»i hệ thống"
+
+#: bfd.c:400
+msgid "Invalid bfd target"
+msgstr "Äích bfd không hợp lệ"
+
+#: bfd.c:401
+msgid "File in wrong format"
+msgstr "Tập tin có định dạng không đúng"
+
+#: bfd.c:402
+msgid "Archive object file in wrong format"
+msgstr "Tập tin đối tượng kho có định dạng không đúng"
+
+#: bfd.c:403
+msgid "Invalid operation"
+msgstr "Thao tác không hợp lệ"
+
+#: bfd.c:404
+msgid "Memory exhausted"
+msgstr "Cạn bộ nhớ"
+
+#: bfd.c:405
+msgid "No symbols"
+msgstr "Không có ký hiệu"
+
+#: bfd.c:406
+msgid "Archive has no index; run ranlib to add one"
+msgstr "Kho không có chỉ mục: hãy chạy ranlib để thêm"
+
+#: bfd.c:407
+msgid "No more archived files"
+msgstr "Không còn có tập tin đã lưu trữ nào nữa"
+
+#: bfd.c:408
+msgid "Malformed archive"
+msgstr "Kho dạng sai"
+
+#: bfd.c:409
+msgid "File format not recognized"
+msgstr "Không nhận ra định dạng tập tin"
+
+#: bfd.c:410
+msgid "File format is ambiguous"
+msgstr "Äịnh dạng tập tin mÆ¡ hồ"
+
+#: bfd.c:411
+msgid "Section has no contents"
+msgstr "Phần không có nội dung"
+
+#: bfd.c:412
+msgid "Nonrepresentable section on output"
+msgstr "Kết xuất có phần không thể đại diện được"
+
+#: bfd.c:413
+msgid "Symbol needs debug section which does not exist"
+msgstr "Ký hiệu cần phần gỡ lỗi mà không tồn tại"
+
+#: bfd.c:414
+msgid "Bad value"
+msgstr "Giá trị sai"
+
+#: bfd.c:415
+msgid "File truncated"
+msgstr "Tập tin bị cắt ngắn"
+
+#: bfd.c:416
+msgid "File too big"
+msgstr "Tập tin quá lớn"
+
+#: bfd.c:417
+#, c-format
+msgid "Error reading %s: %s"
+msgstr "Gặp lá»—i khi Ä‘á»c %s: %s"
+
+#: bfd.c:418
+msgid "#<Invalid error code>"
+msgstr "#<mã lỗi không hợp lệ>"
+
+#: bfd.c:945
+#, c-format
+msgid "BFD %s assertion fail %s:%d"
+msgstr "BFD %s khắng định bị lỗi %s:%d"
+
+#: bfd.c:957
+#, c-format
+msgid "BFD %s internal error, aborting at %s line %d in %s\n"
+msgstr "BFD %s lỗi nội bộ nên hủy bỠtại %s dòng %d trong %s\n"
+
+#: bfd.c:961
+#, c-format
+msgid "BFD %s internal error, aborting at %s line %d\n"
+msgstr "BFD %s lỗi nội bộ nên hủy bỠtại %s dòng %d\n"
+
+#: bfd.c:963
+msgid "Please report this bug.\n"
+msgstr "Hãy thông báo lỗi này.\n"
+
+#: bfdwin.c:206
+#, c-format
+msgid "not mapping: data=%lx mapped=%d\n"
+msgstr "không đang ánh xạ: dữ liệu=%lx đã ánh xạ=%d\n"
+
+#: bfdwin.c:209
+#, c-format
+msgid "not mapping: env var not set\n"
+msgstr "không Ä‘ang ánh xạ: chÆ°a đặt biến môi trÆ°á»ng\n"
+
+#: binary.c:271
+#, c-format
+msgid "Warning: Writing section `%s' to huge (ie negative) file offset 0x%lx."
+msgstr "Cảnh báo: đang ghi phần \"%s\" vào khoảng bù tập tin rất lớn (tức là âm) 0x%lx."
+
+#: bout.c:1146 elf-m10300.c:2063 elf32-avr.c:1654 elf32-frv.c:5734
+#: elfxx-sparc.c:2802 reloc.c:6115 reloc16.c:162 elf32-ia64.c:360
+#: elf64-ia64.c:360
+msgid "%P%F: --relax and -r may not be used together\n"
+msgstr "%P%F: không thể dùng vá»›i nhau hai tuỳ chá»n \"--relax\" và \"-r\"\n"
+
+#: cache.c:227
+msgid "reopening %B: %s\n"
+msgstr "đang mở lại %B: %s\n"
+
+#: coff-alpha.c:491
+msgid ""
+"%B: Cannot handle compressed Alpha binaries.\n"
+" Use compiler flags, or objZ, to generate uncompressed binaries."
+msgstr ""
+"%B: Không thể xử lý tập tin nhị phân Alpha chưa được nén.\n"
+"\tHãy dùng các cỠbiên dịch, hoặc objZ, để tạo tập tin nhị phân chưa được nén."
+
+#: coff-alpha.c:648
+msgid "%B: unknown/unsupported relocation type %d"
+msgstr "%B: kiểu định vị lại không rõ hoặc không được hỗ trợ: %d"
+
+#: coff-alpha.c:900 coff-alpha.c:937 coff-alpha.c:2025 coff-mips.c:1003
+msgid "GP relative relocation used when GP not defined"
+msgstr "Chưa xác định GP thì sử dụng định vị lại tương đối GP"
+
+#: coff-alpha.c:1502
+msgid "using multiple gp values"
+msgstr "Ä‘ang dùng nhiá»u giá trị GP"
+
+#: coff-alpha.c:1561
+msgid "%B: unsupported relocation: ALPHA_R_GPRELHIGH"
+msgstr "%B: định vị lại không được hỗ trợ: ALPHA_R_GPRELHIGH"
+
+#: coff-alpha.c:1568
+msgid "%B: unsupported relocation: ALPHA_R_GPRELLOW"
+msgstr "%B: định vị lại không được hỗ trợ: ALPHA_R_GPRELLOW"
+
+#: coff-alpha.c:1575 elf32-m32r.c:2484 elf64-alpha.c:4074 elf64-alpha.c:4224
+#: elf32-ia64.c:3839 elf64-ia64.c:3839
+msgid "%B: unknown relocation type %d"
+msgstr "%B: không rõ kiểu định vị lại %d"
+
+#: coff-arm.c:1038
+#, c-format
+msgid "%B: unable to find THUMB glue '%s' for `%s'"
+msgstr "%B: không tìm thấy keo hồ THUMB \"%s\" cho \"%s\""
+
+#: coff-arm.c:1067
+#, c-format
+msgid "%B: unable to find ARM glue '%s' for `%s'"
+msgstr "%B: không tìm thấy keo hồ ARM \"%s\" cho \"%s\""
+
+#: coff-arm.c:1369 elf32-arm.c:7023
+#, c-format
+msgid ""
+"%B(%s): warning: interworking not enabled.\n"
+" first occurrence: %B: arm call to thumb"
+msgstr ""
+"%B(%s): cảnh báo: chưa bật dùng ảnh hưởng lẫn nhau.\n"
+" lần xuất hiện đầu tiên: %B: gá»i arm tá»›i thumb"
+
+#: coff-arm.c:1459
+#, c-format
+msgid ""
+"%B(%s): warning: interworking not enabled.\n"
+" first occurrence: %B: thumb call to arm\n"
+" consider relinking with --support-old-code enabled"
+msgstr ""
+"%B(%s): cảnh báo: chưa bật dùng ảnh hưởng lẫn nhau.\n"
+" lần xuất hiện đầu tiên: %B: gá»i thumb tá»›i arm\n"
+" coi như liên kết lại với \"--support-old-code\" được bật"
+
+#: coff-arm.c:1754 coff-tic80.c:695 cofflink.c:3081
+msgid "%B: bad reloc address 0x%lx in section `%A'"
+msgstr "%B: địa chỉ định vị lại sai 0x%lx trong phần \"%A\""
+
+#: coff-arm.c:2079
+msgid "%B: illegal symbol index in reloc: %d"
+msgstr "%B: chỉ mục ký hiệu cấm trong định vị lại: %d"
+
+#: coff-arm.c:2210
+#, c-format
+msgid "error: %B is compiled for APCS-%d, whereas %B is compiled for APCS-%d"
+msgstr "lỗi: %B được biên dịch cho APCS-%d, còn %B được biên dịch cho APCS-%d"
+
+#: coff-arm.c:2226 elf32-arm.c:15621
+#, c-format
+msgid "error: %B passes floats in float registers, whereas %B passes them in integer registers"
+msgstr "lỗi: %B gửi trôi qua trong thanh ghi trôi, còn %B gửi chúng qua trong thanh ghi số nguyên"
+
+#: coff-arm.c:2229 elf32-arm.c:15625
+#, c-format
+msgid "error: %B passes floats in integer registers, whereas %B passes them in float registers"
+msgstr "lỗi: %B gửi trôi qua trong thanh ghi số nguyên, còn %B gửi chúng qua trong thanh ghi trôi"
+
+#: coff-arm.c:2243
+#, c-format
+msgid "error: %B is compiled as position independent code, whereas target %B is absolute position"
+msgstr "lỗi: %B được biên dịch như mã không phụ thuộc vào vị trí, còn %B là vị trí tuyệt đối"
+
+#: coff-arm.c:2246
+#, c-format
+msgid "error: %B is compiled as absolute position code, whereas target %B is position independent"
+msgstr "lỗi: %B được biên dịch như mã vị trí tuyệt đối, còn %B không phụ thuộc vào vị trí"
+
+#: coff-arm.c:2274 elf32-arm.c:15690
+#, c-format
+msgid "Warning: %B supports interworking, whereas %B does not"
+msgstr "Cảnh báo: %B hỗ trợ ảnh hưởng lẫn nhau, còn %B thì không"
+
+#: coff-arm.c:2277 elf32-arm.c:15696
+#, c-format
+msgid "Warning: %B does not support interworking, whereas %B does"
+msgstr "Cảnh báo: %B không hỗ trợ ảnh hưởng lẫn nhau, còn %B thì có"
+
+#: coff-arm.c:2301
+#, c-format
+msgid "private flags = %x:"
+msgstr "các cỠriêng = %x:"
+
+#: coff-arm.c:2309 elf32-arm.c:11806
+#, c-format
+msgid " [floats passed in float registers]"
+msgstr " [các trôi được gửi qua trong thanh ghi trôi]"
+
+#: coff-arm.c:2311
+#, c-format
+msgid " [floats passed in integer registers]"
+msgstr " [các trôi được gửi qua trong thanh ghi số nguyên]"
+
+#: coff-arm.c:2314 elf32-arm.c:11809
+#, c-format
+msgid " [position independent]"
+msgstr " [không phụ thuộc vào vị trí]"
+
+#: coff-arm.c:2316
+#, c-format
+msgid " [absolute position]"
+msgstr " [vị trí tuyệt đối]"
+
+#: coff-arm.c:2320
+#, c-format
+msgid " [interworking flag not initialised]"
+msgstr " [chưa sở khởi cỠảnh hưởng lẫn nhau]"
+
+#: coff-arm.c:2322
+#, c-format
+msgid " [interworking supported]"
+msgstr " [hỗ trợ ảnh hưởng lẫn nhau]"
+
+#: coff-arm.c:2324
+#, c-format
+msgid " [interworking not supported]"
+msgstr " [không hỗ trợ ảnh hưởng lẫn nhau]"
+
+#: coff-arm.c:2370 elf32-arm.c:10841
+#, c-format
+msgid "Warning: Not setting interworking flag of %B since it has already been specified as non-interworking"
+msgstr "Cảnh báo: không đang đặt cỠảnh hưởng lẫn nhau của %B vì nó đã được xác định là không ảnh hưởng lẫn nhau"
+
+#: coff-arm.c:2374 elf32-arm.c:10845
+#, c-format
+msgid "Warning: Clearing the interworking flag of %B due to outside request"
+msgstr "Cảnh báo: Äang xoá cỠảnh hưởng lẫn nhau của %B theo yêu cầu bên ngoài"
+
+#: coff-h8300.c:1122
+#, c-format
+msgid "cannot handle R_MEM_INDIRECT reloc when using %s output"
+msgstr "không thể xử lý định vị lại R_MEM_INDIRECT khi sử dụng kết xuất %s"
+
+#: coff-i860.c:147
+#, c-format
+msgid "relocation `%s' not yet implemented"
+msgstr "tái định vị `%s' vẫn chưa được viết"
+
+#: coff-i860.c:605 coff-tic54x.c:398 coffcode.h:5198
+msgid "%B: warning: illegal symbol index %ld in relocs"
+msgstr "%B: cảnh báo: chỉ mục ký hiệu cấm %ld trong định vị lại"
+
+#: coff-i960.c:144 coff-i960.c:507
+msgid "uncertain calling convention for non-COFF symbol"
+msgstr "quy Æ°á»›c gá»i không chắc chắn cho ký hiệu khác COFF"
+
+#: coff-m68k.c:506 elf32-bfin.c:5690 elf32-cr16.c:2897 elf32-m68k.c:4677
+msgid "unsupported reloc type"
+msgstr "kiểu định vị lại không được hỗ trợ"
+
+#: coff-mips.c:688 elf32-mips.c:1516 elf32-score.c:431 elf32-score7.c:330
+#: elf64-mips.c:2618 elfn32-mips.c:2431
+msgid "GP relative relocation when _gp not defined"
+msgstr "Có định vị lại tương đối GP khi chưa xác định _gp"
+
+#: coff-or32.c:229
+msgid "Unrecognized reloc"
+msgstr "Äịnh vị lại không được nhận ra"
+
+#: coff-rs6000.c:2720
+#, c-format
+msgid "%s: unsupported relocation type 0x%02x"
+msgstr "%s: kiểu định vị lại không được hỗ trợ 0x%02x"
+
+#: coff-rs6000.c:2805
+#, c-format
+msgid "%s: TOC reloc at 0x%x to symbol `%s' with no TOC entry"
+msgstr "%s: định vị lại TOC tại 0x%x tới ký hiệu \"%s\" không có mục nhập TOC"
+
+#: coff-rs6000.c:3556 coff64-rs6000.c:2111
+msgid "%B: symbol `%s' has unrecognized smclas %d"
+msgstr "%B: ký tự \"%s\" có smclas không nhận ra %d"
+
+#: coff-sh.c:521
+#, c-format
+msgid "SH Error: unknown reloc type %d"
+msgstr "Lỗi SH: không rõ kiểu reloc %d"
+
+#: coff-tic4x.c:195 coff-tic54x.c:299 coff-tic80.c:458
+#, c-format
+msgid "Unrecognized reloc type 0x%x"
+msgstr "Không nhận ra kiểu định vị lại 0x%x"
+
+#: coff-tic4x.c:240
+#, c-format
+msgid "%s: warning: illegal symbol index %ld in relocs"
+msgstr "%s: cảnh báo: chỉ mục ký hiệu cấm %ld trong các định vị lại"
+
+#: coff-w65.c:367
+#, c-format
+msgid "ignoring reloc %s\n"
+msgstr "Äang lá» Ä‘i định vị lại %s\n"
+
+#: coffcode.h:997
+msgid "%B: warning: COMDAT symbol '%s' does not match section name '%s'"
+msgstr "%B: cảnh báo: ký hiệu COMDAT \"%s\" không tương ứng vơi tên phần \"%s\""
+
+#. Generate a warning message rather using the 'unhandled'
+#. variable as this will allow some .sys files generate by
+#. other toolchains to be processed. See bugzilla issue 196.
+#: coffcode.h:1221
+msgid "%B: Warning: Ignoring section flag IMAGE_SCN_MEM_NOT_PAGED in section %s"
+msgstr "%B: Cảnh báo: Äang lá» Ä‘i cá» của phần IMAGE_SCN_MEM_NOT_PAGED trong phần %s"
+
+#: coffcode.h:1288
+msgid "%B (%s): Section flag %s (0x%x) ignored"
+msgstr "%B (%s): Äã lá» Ä‘i cá» của phần %s (0x%x)"
+
+#: coffcode.h:2430
+#, c-format
+msgid "Unrecognized TI COFF target id '0x%x'"
+msgstr "Không nhận ra mã số đích TI COFF \"0x%x\""
+
+#: coffcode.h:2744
+msgid "%B: reloc against a non-existant symbol index: %ld"
+msgstr "%B: định vị lại so với một chỉ mục ký hiệu không tồn tại: %ld"
+
+#: coffcode.h:3302
+msgid "%B: too many sections (%d)"
+msgstr "%B: Quá nhiá»u phần: %d (%d)"
+
+#: coffcode.h:3718
+msgid "%B: section %s: string table overflow at offset %ld"
+msgstr "%B: phần %s: tràn bảng chuỗi ở hiệu %ld"
+
+#: coffcode.h:4523
+msgid "%B: warning: line number table read failed"
+msgstr "%B: Cảnh bảo: lá»—i Ä‘á»c bảng số thứ tá»± dòng"
+
+#: coffcode.h:4553
+msgid "%B: warning: illegal symbol index %ld in line numbers"
+msgstr "%B: cảnh báo: chỉ mục ký hiệu cấm %ld trong các số thứ tự dòng"
+
+#: coffcode.h:4567
+msgid "%B: warning: duplicate line number information for `%s'"
+msgstr "%B: cảnh báo: thông tin số thứ tự dòng trùng đối với \"%s\""
+
+#: coffcode.h:4967
+msgid "%B: Unrecognized storage class %d for %s symbol `%s'"
+msgstr "%B: Không nhận ra hạng lưu trữ %d cho ký hiệu %s \"%s\""
+
+#: coffcode.h:5093
+msgid "warning: %B: local symbol `%s' has no section"
+msgstr "cảnh báo: %B: ký hiệu cục bộ \"%s\" không có phần đoạn"
+
+#: coffcode.h:5237
+msgid "%B: illegal relocation type %d at address 0x%lx"
+msgstr "%B: kiểu định vị lại cấm %d ở địa chỉ 0x%lx"
+
+#: coffgen.c:1595
+msgid "%B: bad string table size %lu"
+msgstr "%B: kích cỡ bảng chuỗi sai %lu"
+
+#: coffgen.c:2500 elflink.c:12689 linker.c:3122
+msgid "%F%P: already_linked_table: %E\n"
+msgstr "%F%P: already_linked_table: %E\n"
+
+#: cofflink.c:533 elflink.c:4323
+msgid "Warning: type of symbol `%s' changed from %d to %d in %B"
+msgstr "Cảnh báo: kiểu ký hiệu \"%s\" bị thay đổi từ %d thành %d trong %B"
+
+#: cofflink.c:2329
+msgid "%B: relocs in section `%A', but it has no contents"
+msgstr "%B: định vị lại trong phần \"%A\", nhưng nó không có nội dung"
+
+#: cofflink.c:2391 elflink.c:9545
+msgid "%X`%s' referenced in section `%A' of %B: defined in discarded section `%A' of %B\n"
+msgstr "%X\"%s\" được tham chiếu trong phần \"%A\" của %B: được định nghĩa trong phần bị hủy \"%A\" của %B\n"
+
+#: cofflink.c:2690 coffswap.h:826
+#, c-format
+msgid "%s: %s: reloc overflow: 0x%lx > 0xffff"
+msgstr "%s: %s: tràn định vị lại: 0x%lx > 0xffff"
+
+#: cofflink.c:2699 coffswap.h:812
+#, c-format
+msgid "%s: warning: %s: line number overflow: 0x%lx > 0xffff"
+msgstr "%s: cảnh báo: %s: tràn số thứ tự dòng: 0x%lx > 0xffff"
+
+#: cpu-arm.c:189 cpu-arm.c:200
+msgid "error: %B is compiled for the EP9312, whereas %B is compiled for XScale"
+msgstr "lỗi: %B được biên dịch cho EP9312, còn %B được biên dịch cho XScale"
+
+#: cpu-arm.c:333
+#, c-format
+msgid "warning: unable to update contents of %s section in %s"
+msgstr "cảnh báo: không thể cập nhật nội dung của phần %s trong %s"
+
+#: dwarf2.c:496
+#, c-format
+msgid "Dwarf Error: Can't find %s section."
+msgstr "Lỗi Dwarf: không tìm thấy phần %s."
+
+#: dwarf2.c:525
+#, c-format
+msgid "Dwarf Error: Offset (%lu) greater than or equal to %s size (%lu)."
+msgstr "Lỗi Dwarf: Khoảng bù dòng (%lu) lớn hơn hoặc bằng kích cỡ %s (%lu)."
+
+#: dwarf2.c:949
+#, c-format
+msgid "Dwarf Error: Invalid or unhandled FORM value: %u."
+msgstr "Lỗi Dwarf: Giá trị FORM sai hoặc chưa được xử lý: %u."
+
+#: dwarf2.c:1200
+msgid "Dwarf Error: mangled line number section (bad file number)."
+msgstr "Lỗi Dwarf: phần số thứ tự dòng đã rối (số thứ tự tập tin sai)."
+
+#: dwarf2.c:1453
+#, c-format
+msgid "Dwarf Error: Unhandled .debug_line version %d."
+msgstr "Lỗi Dwarf: Phiên bản .debug_line chưa được quản lý %d."
+
+#: dwarf2.c:1475
+msgid "Dwarf Error: Invalid maximum operations per instruction."
+msgstr "Lỗi Dwarf: Số thao tác trên mỗi chỉ lệnh tối đa không hợp lệ."
+
+#: dwarf2.c:1662
+msgid "Dwarf Error: mangled line number section."
+msgstr "Lỗi Dwarf: phần số thứ tự dòng đã rối."
+
+#: dwarf2.c:1989 dwarf2.c:2109 dwarf2.c:2394
+#, c-format
+msgid "Dwarf Error: Could not find abbrev number %u."
+msgstr "Lỗi Dwarf: Không tìm thấy số viết tắt %u."
+
+#: dwarf2.c:2355
+#, c-format
+msgid "Dwarf Error: found dwarf version '%u', this reader only handles version 2, 3 and 4 information."
+msgstr "Lá»—i Dwarf: tìm thấy dwarf phiên bản \"%u\", nhÆ°ng trình Ä‘á»c này chỉ có thể nắm bắt được thông tin của phiên bản 2, 3 và 4."
+
+#: dwarf2.c:2362
+#, c-format
+msgid "Dwarf Error: found address size '%u', this reader can not handle sizes greater than '%u'."
+msgstr "Lá»—i Dwarf: tìm thấy kích cỡ địa chỉ \"%u\", nhÆ°ng trình Ä‘á»c này không Ä‘iá»u khiển được kích cỡ lá»›n hÆ¡n \"%u\"."
+
+#: dwarf2.c:2385
+#, c-format
+msgid "Dwarf Error: Bad abbrev number: %u."
+msgstr "Lỗi Dwarf: Số viết tắt sai: %u."
+
+#: ecoff.c:1239
+#, c-format
+msgid "Unknown basic type %d"
+msgstr "Không rõ kiểu cơ bản %d"
+
+#: ecoff.c:1496
+#, c-format
+msgid ""
+"\n"
+" End+1 symbol: %ld"
+msgstr ""
+"\n"
+" Ký hiệu End+1: %ld"
+
+#: ecoff.c:1503 ecoff.c:1506
+#, c-format
+msgid ""
+"\n"
+" First symbol: %ld"
+msgstr ""
+"\n"
+" Ký hiệu đầu tiên: %ld"
+
+#: ecoff.c:1518
+#, c-format
+msgid ""
+"\n"
+" End+1 symbol: %-7ld Type: %s"
+msgstr ""
+"\n"
+" Ký hiệu End+1: %-7ld Kiểu: %s"
+
+#: ecoff.c:1525
+#, c-format
+msgid ""
+"\n"
+" Local symbol: %ld"
+msgstr ""
+"\n"
+" Ký hiệu cục bộ: %ld"
+
+#: ecoff.c:1533
+#, c-format
+msgid ""
+"\n"
+" struct; End+1 symbol: %ld"
+msgstr ""
+"\n"
+" cấu trúc; ký hiệu End+1: %ld"
+
+#: ecoff.c:1538
+#, c-format
+msgid ""
+"\n"
+" union; End+1 symbol: %ld"
+msgstr ""
+"\n"
+" kết hợp; ký hiệu End+1: %ld"
+
+#: ecoff.c:1543
+#, c-format
+msgid ""
+"\n"
+" enum; End+1 symbol: %ld"
+msgstr ""
+"\n"
+" đếm; ký hiệu End+1: %ld"
+
+#: ecoff.c:1549
+#, c-format
+msgid ""
+"\n"
+" Type: %s"
+msgstr ""
+"\n"
+" Kiểu: %s"
+
+#: elf-attrs.c:569
+msgid "error: %B: Object has vendor-specific contents that must be processed by the '%s' toolchain"
+msgstr "lá»—i: %B: Äối tượng có ná»™i dung \"vendor-specific\" phải được xá»­ lý bởi toolchain '%s'"
+
+#: elf-attrs.c:578
+msgid "error: %B: Object tag '%d, %s' is incompatible with tag '%d, %s'"
+msgstr "lỗi: %B: thẻ đối tượng \"%d, %s\" không tương thích với thẻ \"%d, %s\""
+
+#: elf-eh-frame.c:917
+msgid "%P: error in %B(%A); no .eh_frame_hdr table will be created.\n"
+msgstr "%P: gặp lỗi trong %B(%A); sẽ không tạo bảng .eh_frame_hdr nào.\n"
+
+#: elf-eh-frame.c:1189
+msgid "%P: fde encoding in %B(%A) prevents .eh_frame_hdr table being created.\n"
+msgstr "%P: biên mã fde trong %B(%A) thì ngăn cản tạo bảng .eh_frame_hdr.\n"
+
+#: elf-eh-frame.c:1605
+msgid "%P: DW_EH_PE_datarel unspecified for this architecture.\n"
+msgstr "%P: DW_EH_PE_datarel chưa định nghĩa cho kiến trúc này.\n"
+
+#: elf-ifunc.c:179
+msgid "%F%P: dynamic STT_GNU_IFUNC symbol `%s' with pointer equality in `%B' can not be used when making an executable; recompile with -fPIE and relink with -pie\n"
+msgstr "%F%P: ký hiệu STT_GNU_IFUNC động \"%s\" với tình trạng chất lượng con trỠtrong \"%B\" thì không dùng được khi tạo bản thực thi; hãy biên dịch lại với \"-fPIE\" và liên kết lại với \"-pie\"\n"
+
+#: elf-m10200.c:450 elf-m10300.c:1563 elf32-avr.c:1221 elf32-bfin.c:3213
+#: elf32-cr16.c:1482 elf32-cr16c.c:780 elf32-cris.c:2081 elf32-crx.c:922
+#: elf32-d10v.c:509 elf32-epiphany.c:556 elf32-fr30.c:609 elf32-frv.c:4105
+#: elf32-h8300.c:509 elf32-i860.c:1211 elf32-ip2k.c:1468 elf32-iq2000.c:684
+#: elf32-lm32.c:1168 elf32-m32c.c:553 elf32-m32r.c:3106 elf32-m68hc1x.c:1138
+#: elf32-mep.c:535 elf32-microblaze.c:1231 elf32-moxie.c:282
+#: elf32-msp430.c:486 elf32-mt.c:395 elf32-openrisc.c:404 elf32-score.c:2729
+#: elf32-score7.c:2537 elf32-spu.c:5044 elf32-tilepro.c:3214 elf32-v850.c:2143
+#: elf32-xstormy16.c:935 elf64-mmix.c:1590 elfxx-tilegx.c:3577
+msgid "internal error: out of range error"
+msgstr "lỗi nội bộ: lỗi ở ngoại phạm vi"
+
+#: elf-m10200.c:454 elf-m10300.c:1567 elf32-avr.c:1225 elf32-bfin.c:3217
+#: elf32-cr16.c:1486 elf32-cr16c.c:784 elf32-cris.c:2085 elf32-crx.c:926
+#: elf32-d10v.c:513 elf32-fr30.c:613 elf32-frv.c:4109 elf32-h8300.c:513
+#: elf32-i860.c:1215 elf32-iq2000.c:688 elf32-lm32.c:1172 elf32-m32c.c:557
+#: elf32-m32r.c:3110 elf32-m68hc1x.c:1142 elf32-mep.c:539
+#: elf32-microblaze.c:1235 elf32-moxie.c:286 elf32-msp430.c:490
+#: elf32-openrisc.c:408 elf32-score.c:2733 elf32-score7.c:2541
+#: elf32-spu.c:5048 elf32-tilepro.c:3218 elf32-v850.c:2147
+#: elf32-xstormy16.c:939 elf64-mmix.c:1594 elfxx-mips.c:9465
+#: elfxx-tilegx.c:3581
+msgid "internal error: unsupported relocation error"
+msgstr "lỗi nội bộ: lỗi định vị lại không được hỗ trợ"
+
+#: elf-m10200.c:458 elf32-cr16.c:1490 elf32-cr16c.c:788 elf32-crx.c:930
+#: elf32-d10v.c:517 elf32-h8300.c:517 elf32-lm32.c:1176 elf32-m32r.c:3114
+#: elf32-m68hc1x.c:1146 elf32-microblaze.c:1239 elf32-score.c:2737
+#: elf32-score7.c:2545 elf32-spu.c:5052
+msgid "internal error: dangerous error"
+msgstr "lỗi nội bộ: lỗi nguy hiểm"
+
+#: elf-m10200.c:462 elf-m10300.c:1580 elf32-avr.c:1233 elf32-bfin.c:3225
+#: elf32-cr16.c:1494 elf32-cr16c.c:792 elf32-cris.c:2093 elf32-crx.c:934
+#: elf32-d10v.c:521 elf32-epiphany.c:571 elf32-fr30.c:621 elf32-frv.c:4117
+#: elf32-h8300.c:521 elf32-i860.c:1223 elf32-ip2k.c:1483 elf32-iq2000.c:696
+#: elf32-lm32.c:1180 elf32-m32c.c:565 elf32-m32r.c:3118 elf32-m68hc1x.c:1150
+#: elf32-mep.c:547 elf32-microblaze.c:1243 elf32-moxie.c:294
+#: elf32-msp430.c:498 elf32-mt.c:403 elf32-openrisc.c:416 elf32-score.c:2746
+#: elf32-score7.c:2549 elf32-spu.c:5056 elf32-tilepro.c:3226 elf32-v850.c:2167
+#: elf32-xstormy16.c:947 elf64-mmix.c:1602 elfxx-tilegx.c:3589
+msgid "internal error: unknown error"
+msgstr "lỗi nội bộ: lỗi không rõ"
+
+#: elf-m10300.c:1507 elf32-arm.c:10419 elf32-i386.c:4264 elf32-m32r.c:2599
+#: elf32-m68k.c:4156 elf32-s390.c:3003 elf32-sh.c:4218 elf32-tilepro.c:3117
+#: elf32-xtensa.c:3066 elf64-s390.c:2978 elf64-sh64.c:1640 elf64-x86-64.c:4110
+#: elfxx-sparc.c:3835 elfxx-tilegx.c:3500
+msgid "%B(%A+0x%lx): unresolvable %s relocation against symbol `%s'"
+msgstr "%B(%A+0x%lx): định vị lại không thể giải quyết %s đối với ký hiệu \"%s\""
+
+#: elf-m10300.c:1572
+msgid "error: inappropriate relocation type for shared library (did you forget -fpic?)"
+msgstr "lỗi: kiểu định vị lại không thích hợp cho thư viện chia sẻ (bạn đã quên đặt -fpic không?)"
+
+#: elf-m10300.c:1575
+msgid "internal error: suspicious relocation type used in shared library"
+msgstr "lỗi nội bộ: kiểu định vị lại đáng ngỠđược dùng trong thư viện chia sẻ"
+
+#: elf-m10300.c:4372 elf32-arm.c:12800 elf32-cr16.c:2451 elf32-cris.c:3057
+#: elf32-hppa.c:1894 elf32-i370.c:503 elf32-i386.c:2182 elf32-lm32.c:1868
+#: elf32-m32r.c:1927 elf32-m68k.c:3253 elf32-s390.c:1652 elf32-sh.c:2931
+#: elf32-tic6x.c:2162 elf32-tilepro.c:1940 elf32-vax.c:1041 elf64-s390.c:1635
+#: elf64-sh64.c:3381 elf64-x86-64.c:2176 elfxx-sparc.c:2119
+#: elfxx-tilegx.c:2261
+#, c-format
+msgid "dynamic variable `%s' is zero size"
+msgstr "biến động \"%s\" có kích cỡ số không"
+
+#: elf.c:334
+msgid "%B: invalid string offset %u >= %lu for section `%s'"
+msgstr "%B: khoảng bù chuỗi không hợp lệ %u≥%lu cho phần \"%s\""
+
+#: elf.c:446
+msgid "%B symbol number %lu references nonexistent SHT_SYMTAB_SHNDX section"
+msgstr "%B số thứ tự ký hiệu %lu tham chiếu đến phần SHT_SYMTAB_SHNDX không tồn tại"
+
+#: elf.c:602
+msgid "%B: Corrupt size field in group section header: 0x%lx"
+msgstr "%B: TrÆ°á»ng kích cỡ bị há»ng trong phần đầu của phần nhóm: 0x%lx"
+
+#: elf.c:638
+msgid "%B: invalid SHT_GROUP entry"
+msgstr "%B: mục nhập SHT_GROUP không hợp lệ"
+
+#: elf.c:708
+msgid "%B: no group info for section %A"
+msgstr "%B: không có thông tin nhóm vỠphần %A"
+
+#: elf.c:737 elf.c:3121 elflink.c:10135
+msgid "%B: warning: sh_link not set for section `%A'"
+msgstr "%B: cảnh báo: \"sh_link\" chưa được đặt cho phần \"%A\""
+
+#: elf.c:756
+msgid "%B: sh_link [%d] in section `%A' is incorrect"
+msgstr "%B: sh_link [%d] không đúng trong phần \"%A\""
+
+#: elf.c:791
+msgid "%B: unknown [%d] section `%s' in group [%s]"
+msgstr "%B: không rõ [%d] phần \"%s\" trong nhóm [%s]"
+
+#: elf.c:1041
+msgid "%B: unable to initialize commpress status for section %s"
+msgstr "%B: không thể khởi tạo trạng thái nén cho phần %s"
+
+#: elf.c:1061
+msgid "%B: unable to initialize decommpress status for section %s"
+msgstr "%B: không thể khởi tạo trạng thái giải nén cho phần %s"
+
+#: elf.c:1181
+#, c-format
+msgid ""
+"\n"
+"Program Header:\n"
+msgstr ""
+"\n"
+"Phần đầu chương trình:\n"
+
+#: elf.c:1223
+#, c-format
+msgid ""
+"\n"
+"Dynamic Section:\n"
+msgstr ""
+"\n"
+"Phần động:\n"
+
+#: elf.c:1359
+#, c-format
+msgid ""
+"\n"
+"Version definitions:\n"
+msgstr ""
+"\n"
+"Phần định nghĩa phiên bản:\n"
+
+#: elf.c:1384
+#, c-format
+msgid ""
+"\n"
+"Version References:\n"
+msgstr ""
+"\n"
+"Tham chiếu phiên bản:\n"
+
+#: elf.c:1389
+#, c-format
+msgid " required from %s:\n"
+msgstr " cần thiết từ %s:\n"
+
+#: elf.c:1796
+msgid "%B: invalid link %lu for reloc section %s (index %u)"
+msgstr "%B: liên kết không hợp lệ %lu cho phần định vị lại %s (chỉ mục %u)"
+
+#: elf.c:1966
+msgid "%B: don't know how to handle allocated, application specific section `%s' [0x%8x]"
+msgstr "%B: không biết cách xử lý phần đã cấp phát mà đặc trưng cho ứng dụng \"%s\" [0x%8x]"
+
+#: elf.c:1978
+msgid "%B: don't know how to handle processor specific section `%s' [0x%8x]"
+msgstr "%B: không biết cách xử lý phần đặc trưng cho bộ xử lý \"%s\" [0x%8x]"
+
+#: elf.c:1989
+msgid "%B: don't know how to handle OS specific section `%s' [0x%8x]"
+msgstr "%B: không biết cách xá»­ lý phần đặc trÆ°ng cho HÄH \"%s\" [0x%8x]"
+
+#: elf.c:1999
+msgid "%B: don't know how to handle section `%s' [0x%8x]"
+msgstr "%B: không biết cách xử lý phần \"%s\" [0x%8x]"
+
+#: elf.c:2634
+#, c-format
+msgid "warning: section `%A' type changed to PROGBITS"
+msgstr "cảnh báo: phần \"%A\" có kiểu bị thay đổi thành PROGBITS"
+
+#: elf.c:3078
+msgid "%B: sh_link of section `%A' points to discarded section `%A' of `%B'"
+msgstr "%B: sh_link của phần \"%A\" chỉ tới phần bị hủy \"%A\" của \"%B\""
+
+#: elf.c:3101
+msgid "%B: sh_link of section `%A' points to removed section `%A' of `%B'"
+msgstr "%B: sh_link của phần \"%A\" chỉ tới phần bị gỡ bỠ\"%A\" của \"%B\""
+
+#: elf.c:4527
+msgid "%B: The first section in the PT_DYNAMIC segment is not the .dynamic section"
+msgstr "%B: Phần thứ nhất trong đoạn PT_DYNAMIC không phải là phần .dynamic"
+
+#: elf.c:4554
+msgid "%B: Not enough room for program headers, try linking with -N"
+msgstr "%B: Không đủ sức chứa cho các phần đầu của chương trình: hãy thử liên kết với \"-N\""
+
+#: elf.c:4641
+msgid "%B: section %A lma %#lx adjusted to %#lx"
+msgstr "%B: phần %A lma %#lx được sửa thành %#lx"
+
+#: elf.c:4776
+msgid "%B: section `%A' can't be allocated in segment %d"
+msgstr "%B: phần \"%A\" không thể được cấp phát trong đoạn %d"
+
+#: elf.c:4824
+msgid "%B: warning: allocated section `%s' not in segment"
+msgstr "%B: cảnh báo: phần đã cấp phát \"%s\" không nằm trong đoạn"
+
+#: elf.c:5324
+msgid "%B: symbol `%s' required but not present"
+msgstr "%B: ký hiệu \"%s\" cần thiết mà không có"
+
+#: elf.c:5662
+msgid "%B: warning: Empty loadable segment detected, is this intentional ?\n"
+msgstr "%B: cảnh báo: Phát hiện má»™t Ä‘oạn rá»—ng có thể nạp được: trÆ°á»ng hợp này có ý định trÆ°á»›c không?\n"
+
+#: elf.c:6692
+#, c-format
+msgid "Unable to find equivalent output section for symbol '%s' from section '%s'"
+msgstr "Không tìm thấy phần kết xuất tương đương cho ký hiệu \"%s\" từ phần \"%s\""
+
+#: elf.c:7692
+msgid "%B: unsupported relocation type %s"
+msgstr "%B: kiểu định vị lại không được hỗ trợ %s"
+
+#: elf32-arm.c:3617
+msgid ""
+"%B(%s): warning: interworking not enabled.\n"
+" first occurrence: %B: Thumb call to ARM"
+msgstr ""
+"%B(%s): cảnh báo: chưa bật dùng ảnh hưởng lẫn nhau.\n"
+" lần xuất hiện đầu: %B: thumb gá»i tá»›i ARM"
+
+#: elf32-arm.c:3664
+msgid ""
+"%B(%s): warning: interworking not enabled.\n"
+" first occurrence: %B: ARM call to Thumb"
+msgstr ""
+"%B(%s): cảnh báo: chưa bật dùng ảnh hưởng lẫn nhau.\n"
+" lần xuất hiện đầu tiên: %B: gá»i ARM tá»›i Thumb"
+
+#: elf32-arm.c:3878 elf32-arm.c:5315
+#, c-format
+msgid "%s: cannot create stub entry %s"
+msgstr "%s: không thể tạo mục nhập mẩu %s"
+
+#: elf32-arm.c:5431
+#, c-format
+msgid "unable to find THUMB glue '%s' for '%s'"
+msgstr "không tìm thấy keo hồ THUMB \"%s\" cho \"%s\""
+
+#: elf32-arm.c:5467
+#, c-format
+msgid "unable to find ARM glue '%s' for '%s'"
+msgstr "không tìm thấy keo hồ ARM \"%s\" cho \"%s\""
+
+#: elf32-arm.c:6005
+msgid "%B: BE8 images only valid in big-endian mode."
+msgstr "%B: hình ảnh BE8 chỉ đúng trong chế độ vỠcuối lớn."
+
+#. Give a warning, but do as the user requests anyway.
+#: elf32-arm.c:6235
+msgid "%B: warning: selected VFP11 erratum workaround is not necessary for target architecture"
+msgstr "%B: cảnh báo: sá»± khắc phúc các lá»—i VFP11 đã chá»n không cần thiết cho kiến trúc đích"
+
+#: elf32-arm.c:6779 elf32-arm.c:6799
+msgid "%B: unable to find VFP11 veneer `%s'"
+msgstr "%B: không tìm thấy lớp gỗ mặt VFP11 \"%s\""
+
+#: elf32-arm.c:6848
+#, c-format
+msgid "Invalid TARGET2 relocation type '%s'."
+msgstr "Kiểu định vị lại TARGET2 không hợp lệ \"%s\""
+
+#: elf32-arm.c:6933
+msgid ""
+"%B(%s): warning: interworking not enabled.\n"
+" first occurrence: %B: thumb call to arm"
+msgstr ""
+"%B(%s): cảnh báo: chưa bật dùng ảnh hưởng lẫn nhau.\n"
+" lần xuất hiện đầu: %B: thumb gá»i tá»›i arm"
+
+#: elf32-arm.c:7717
+msgid "%B(%A+0x%lx):unexpected Thumb instruction '0x%x' in TLS trampoline"
+msgstr "%B(%A+0x%lx):chỉ lệnh Thumb không mong đợi '0x%x' trong 'TLS trampoline'"
+
+#: elf32-arm.c:7756
+msgid "%B(%A+0x%lx):unexpected ARM instruction '0x%x' in TLS trampoline"
+msgstr "%B(%A+0x%lx):chỉ lệnh ARM không mong đợi '0x%x' trong 'TLS trampoline'"
+
+#: elf32-arm.c:8209
+msgid "\\%B: Warning: Arm BLX instruction targets Arm function '%s'."
+msgstr "\\%B: Cảnh báo: Chỉ dẫn Arm BLX đăt mục tiêu hàm Arm \"%s\"."
+
+#: elf32-arm.c:8622
+msgid "%B: Warning: Thumb BLX instruction targets thumb function '%s'."
+msgstr "%B: Cảnh báo: Chỉ dẫn Thumb BLX đăt mục tiêu hàm thumb \"%s\"."
+
+#: elf32-arm.c:9460
+msgid "%B(%A+0x%lx):unexpected Thumb instruction '0x%x' referenced by TLS_GOTDESC"
+msgstr "%B(%A+0x%lx):không mong đợi chỉ lệnh Thumb '0x%x' được tham chiếu bởi TLS_GOTDESC"
+
+#: elf32-arm.c:9483
+msgid "%B(%A+0x%lx):unexpected ARM instruction '0x%x' referenced by TLS_GOTDESC"
+msgstr "%B(%A+0x%lx):không mong đợi chỉ lệnh ARM '0x%x' được tham chiếu bởi TLS_GOTDESC"
+
+#: elf32-arm.c:9512
+msgid "%B(%A+0x%lx): R_ARM_TLS_LE32 relocation not permitted in shared object"
+msgstr "%B(%A+0x%lx): R_ARM_TLS_LE32 không cho phép định vị lại trong đối tượng dùng chung"
+
+#: elf32-arm.c:9727
+msgid "%B(%A+0x%lx): Only ADD or SUB instructions are allowed for ALU group relocations"
+msgstr "%B(%A+0x%lx): Chỉ cho phép chỉ dẫn kiểu ADD (cộng) hoặc SUB (trừ) khi định vị lại nhóm ALU"
+
+#: elf32-arm.c:9767 elf32-arm.c:9854 elf32-arm.c:9937 elf32-arm.c:10022
+msgid "%B(%A+0x%lx): Overflow whilst splitting 0x%lx for group relocation %s"
+msgstr "%B(%A+0x%lx): Tràn trong khi tách ra 0x%lx để định vị lại nhóm %s"
+
+#: elf32-arm.c:10261 elf32-sh.c:4103 elf64-sh64.c:1544
+msgid "%B(%A+0x%lx): %s relocation against SEC_MERGE section"
+msgstr "%B(%A+0x%lx): %s định vị lại đối lại phần SEC_MERGE"
+
+#: elf32-arm.c:10372 elf32-m68k.c:4191 elf32-xtensa.c:2802
+msgid "%B(%A+0x%lx): %s used with TLS symbol %s"
+msgstr "%B(%A+0x%lx): %s được dùng với ký hiệu TLS %s"
+
+#: elf32-arm.c:10373 elf32-m68k.c:4192 elf32-xtensa.c:2803
+msgid "%B(%A+0x%lx): %s used with non-TLS symbol %s"
+msgstr "%B(%A+0x%lx): %s được dùng với ký hiệu khác TLS %s"
+
+#: elf32-arm.c:10453 elf32-tic6x.c:2753
+msgid "out of range"
+msgstr "ở ngoại phạm vi"
+
+#: elf32-arm.c:10457 elf32-tic6x.c:2757
+msgid "unsupported relocation"
+msgstr "định vị lại không được hỗ trợ"
+
+#: elf32-arm.c:10465 elf32-tic6x.c:2765
+msgid "unknown error"
+msgstr "lỗi không rõ"
+
+#: elf32-arm.c:10890
+msgid "Warning: Clearing the interworking flag of %B because non-interworking code in %B has been linked with it"
+msgstr "Cảnh báo: Äang xóa cỠảnh hưởng lẫn nhau của %B vì mã không ảnh hưởng lẫn nhau trong %B đã được liên kết vá»›i nó"
+
+#: elf32-arm.c:10984
+msgid "%B: Unknown mandatory EABI object attribute %d"
+msgstr "%B: Không rõ thuộc tính đối tượng EABI %d"
+
+#: elf32-arm.c:10992
+msgid "Warning: %B: Unknown EABI object attribute %d"
+msgstr "Cảnh báo: %B: Không rõ thuộc tính đối tượng EABI %d"
+
+#: elf32-arm.c:11173
+msgid "error: %B: Unknown CPU architecture"
+msgstr "lỗi: %B: không rõ kiến trúc CPU"
+
+#: elf32-arm.c:11211
+msgid "error: %B: Conflicting CPU architectures %d/%d"
+msgstr "lỗi: %B: Các kiến trúc CPU xung đột với nhau %d/%d"
+
+#: elf32-arm.c:11260
+msgid "Error: %B has both the current and legacy Tag_MPextension_use attributes"
+msgstr "Lỗi: %B có cả hai thuộc tính Tag_MPextension_use hiện nay và cũ"
+
+#: elf32-arm.c:11285
+msgid "error: %B uses VFP register arguments, %B does not"
+msgstr "lỗi: %B sử dụng các đối số thanh ghi VFP, còn %B thì không"
+
+#: elf32-arm.c:11430
+msgid "error: %B: unable to merge virtualization attributes with %B"
+msgstr "lỗi: %B: không thể hòa trộng thuộc tính ảo hóa với %B"
+
+#: elf32-arm.c:11456
+msgid "error: %B: Conflicting architecture profiles %c/%c"
+msgstr "lỗi: %B: Các hồ sơ kiến trúc xung đột với nhau %c/%c"
+
+#: elf32-arm.c:11557
+msgid "Warning: %B: Conflicting platform configuration"
+msgstr "Cảnh báo: %B: cấu trúc ná»n tảng xung Ä‘á»™t"
+
+#: elf32-arm.c:11566
+msgid "error: %B: Conflicting use of R9"
+msgstr "lỗi; %B: Dùng R9 một cách xung đột"
+
+#: elf32-arm.c:11578
+msgid "error: %B: SB relative addressing conflicts with use of R9"
+msgstr "lỗi: %B: đạt địa chỉ tương đối SB cũng xung đột với cách dùng R9"
+
+#: elf32-arm.c:11591
+msgid "warning: %B uses %u-byte wchar_t yet the output is to use %u-byte wchar_t; use of wchar_t values across objects may fail"
+msgstr "cảnh báo: %B dùng wchar_t %u-byte, còn kết xuất nên dùng wchar_t %u-byte; vì vậy có thể không thành công dùng giá trị wchar_t qua các đối tượng"
+
+#: elf32-arm.c:11622
+msgid "warning: %B uses %s enums yet the output is to use %s enums; use of enum values across objects may fail"
+msgstr "cảnh báo: %B dùng sự đếm %s, còn kết xuất nên dùng sự đếm %s; vì vậy có thể không thành công dùng giá trị đếm qua các đối tượng"
+
+#: elf32-arm.c:11634
+msgid "error: %B uses iWMMXt register arguments, %B does not"
+msgstr "lỗi: %B sử dụng các đối số thanh ghi iWMMXt, còn %B thì không"
+
+#: elf32-arm.c:11651
+msgid "error: fp16 format mismatch between %B and %B"
+msgstr "lỗi: định dạng fp16 không tương ứng giữa %B và %B"
+
+#: elf32-arm.c:11675
+msgid "DIV usage mismatch between %B and %B"
+msgstr "cách dùng DIV không khớp nhau giữa %B và %B"
+
+#: elf32-arm.c:11694
+msgid "%B has has both the current and legacy Tag_MPextension_use attributes"
+msgstr "%B có cả hai thuộc tính hiện nay và cũ là Tag_MPextension_use"
+
+#. Ignore init flag - it may not be set, despite the flags field
+#. containing valid data.
+#. Ignore init flag - it may not be set, despite the flags field containing valid data.
+#: elf32-arm.c:11782 elf32-bfin.c:5079 elf32-cris.c:4169 elf32-m68hc1x.c:1282
+#: elf32-m68k.c:1236 elf32-score.c:3994 elf32-score7.c:3800 elf32-vax.c:529
+#: elfxx-mips.c:14103
+#, c-format
+msgid "private flags = %lx:"
+msgstr "các cỠriêng = %lx:"
+
+#: elf32-arm.c:11791
+#, c-format
+msgid " [interworking enabled]"
+msgstr " [ảnh hưởng lẫn nhau đã bật]"
+
+#: elf32-arm.c:11799
+#, c-format
+msgid " [VFP float format]"
+msgstr " [Äịnh dạng trôi VFP]"
+
+#: elf32-arm.c:11801
+#, c-format
+msgid " [Maverick float format]"
+msgstr " [Äịnh dạng trôi Maverick]"
+
+#: elf32-arm.c:11803
+#, c-format
+msgid " [FPA float format]"
+msgstr " [Äịnh dạng trôi FPA]"
+
+#: elf32-arm.c:11812
+#, c-format
+msgid " [new ABI]"
+msgstr " [ABI má»›i]"
+
+#: elf32-arm.c:11815
+#, c-format
+msgid " [old ABI]"
+msgstr " [ABI cũ]"
+
+#: elf32-arm.c:11818
+#, c-format
+msgid " [software FP]"
+msgstr " [FP phần má»m]"
+
+#: elf32-arm.c:11827
+#, c-format
+msgid " [Version1 EABI]"
+msgstr " [EABI phiên bản 1]"
+
+#: elf32-arm.c:11830 elf32-arm.c:11841
+#, c-format
+msgid " [sorted symbol table]"
+msgstr " [bảng ký hiệu đã sắp xếp]"
+
+#: elf32-arm.c:11832 elf32-arm.c:11843
+#, c-format
+msgid " [unsorted symbol table]"
+msgstr " [bảng ký hiệu chưa sắp xếp]"
+
+#: elf32-arm.c:11838
+#, c-format
+msgid " [Version2 EABI]"
+msgstr " [EABI phiên bản 2]"
+
+#: elf32-arm.c:11846
+#, c-format
+msgid " [dynamic symbols use segment index]"
+msgstr " [các ký hiệu động sử dụng chỉ mục đoạn]"
+
+#: elf32-arm.c:11849
+#, c-format
+msgid " [mapping symbols precede others]"
+msgstr " [ký hiệu ánh xạ đứng trước]"
+
+#: elf32-arm.c:11856
+#, c-format
+msgid " [Version3 EABI]"
+msgstr " [EABI phiên bản 3]"
+
+#: elf32-arm.c:11860
+#, c-format
+msgid " [Version4 EABI]"
+msgstr " [EABI phiên bản 4]"
+
+#: elf32-arm.c:11864
+#, c-format
+msgid " [Version5 EABI]"
+msgstr " [EABI phiên bản 5]"
+
+#: elf32-arm.c:11867
+#, c-format
+msgid " [BE8]"
+msgstr " [BE8]"
+
+#: elf32-arm.c:11870
+#, c-format
+msgid " [LE8]"
+msgstr " [LE8]"
+
+#: elf32-arm.c:11876
+#, c-format
+msgid " <EABI version unrecognised>"
+msgstr "<Phiên bản EABI không được nhận ra>"
+
+#: elf32-arm.c:11883
+#, c-format
+msgid " [relocatable executable]"
+msgstr " [tập tin có thể thực hiện và định vị lại]"
+
+#: elf32-arm.c:11886
+#, c-format
+msgid " [has entry point]"
+msgstr " [có điểm vào]"
+
+#: elf32-arm.c:11891
+#, c-format
+msgid "<Unrecognised flag bits set>"
+msgstr "<Các bit cỠkhông được nhận ra đã được đặt>"
+
+#: elf32-arm.c:12189 elf32-i386.c:1461 elf32-s390.c:1000 elf32-tic6x.c:2829
+#: elf32-tilepro.c:1336 elf32-xtensa.c:1009 elf64-s390.c:960
+#: elf64-x86-64.c:1364 elfxx-sparc.c:1371 elfxx-tilegx.c:1586
+msgid "%B: bad symbol index: %d"
+msgstr "%B: chỉ mục ký hiệu sai: %d"
+
+#: elf32-arm.c:12337 elf64-x86-64.c:1561 elf64-x86-64.c:1732 elfxx-mips.c:8223
+msgid "%B: relocation %s against `%s' can not be used when making a shared object; recompile with -fPIC"
+msgstr "%B: định vị lại %s so với \"%s\" không thể được dùng khi tạo một đối tượng chia sẻ; hãy biên dịch lại với \"-fPIC\""
+
+#: elf32-arm.c:13460
+#, c-format
+msgid "Errors encountered processing file %s"
+msgstr "Gặp lỗi khi xử lý tập tin %s"
+
+#: elf32-arm.c:14837
+msgid "%B: error: Cortex-A8 erratum stub is allocated in unsafe location"
+msgstr "%B: lỗi: mẩu mục lỗi Cortex-A8 được cấp phát ở vị trí không an toàn"
+
+#. There's not much we can do apart from complain if this
+#. happens.
+#: elf32-arm.c:14864
+msgid "%B: error: Cortex-A8 erratum stub out of range (input file too large)"
+msgstr "%B: lỗi: mẩu mục lỗi Cortex-A8 ở ngoại phạm vi (tập tin nhập quá dài)"
+
+#: elf32-arm.c:14958 elf32-arm.c:14980
+msgid "%B: error: VFP11 veneer out of range"
+msgstr "%B: lỗi: lớp gỗ mặt VFP11 ở ngoại phạm vi"
+
+#: elf32-arm.c:15518
+msgid "error: %B is already in final BE8 format"
+msgstr "lỗi: %B đã theo định dạng BE8 cuối cùng"
+
+#: elf32-arm.c:15594
+msgid "error: Source object %B has EABI version %d, but target %B has EABI version %d"
+msgstr "lá»—i: Äối tượng nguồn %B có phiên bản EABI %d, còn đích %B có phiên bản EABI %d"
+
+#: elf32-arm.c:15610
+msgid "error: %B is compiled for APCS-%d, whereas target %B uses APCS-%d"
+msgstr "lỗi: %B được biên dịch cho APCS-%d, còn đích %B sử dụng APCS-%d"
+
+#: elf32-arm.c:15635
+msgid "error: %B uses VFP instructions, whereas %B does not"
+msgstr "lỗi: %B sử dụng chỉ dẫn VFP, còn %B thì không"
+
+#: elf32-arm.c:15639
+msgid "error: %B uses FPA instructions, whereas %B does not"
+msgstr "lỗi: %B sử dụng chỉ dẫn FPA, còn %B thì không"
+
+#: elf32-arm.c:15649
+msgid "error: %B uses Maverick instructions, whereas %B does not"
+msgstr "lỗi: %B sử dụng chỉ dẫn Maverick, còn %B thì không"
+
+#: elf32-arm.c:15653
+msgid "error: %B does not use Maverick instructions, whereas %B does"
+msgstr "lỗi: %B không sử dụng chỉ dẫn Maverick, còn %B thì có"
+
+#: elf32-arm.c:15672
+msgid "error: %B uses software FP, whereas %B uses hardware FP"
+msgstr "lá»—i: %B sá»­ dụng FP phần má»m, còn %B sá»­ dụng FP phần cứng"
+
+#: elf32-arm.c:15676
+msgid "error: %B uses hardware FP, whereas %B uses software FP"
+msgstr "lá»—i: %B sá»­ dụng FP phần cứng, còn %B sá»­ dụng FP phần má»m"
+
+#: elf32-avr.c:1229 elf32-bfin.c:3221 elf32-cris.c:2089 elf32-epiphany.c:567
+#: elf32-fr30.c:617 elf32-frv.c:4113 elf32-i860.c:1219 elf32-ip2k.c:1479
+#: elf32-iq2000.c:692 elf32-m32c.c:561 elf32-mep.c:543 elf32-moxie.c:290
+#: elf32-msp430.c:494 elf32-mt.c:399 elf32-openrisc.c:412 elf32-tilepro.c:3222
+#: elf32-v850.c:2151 elf32-xstormy16.c:943 elf64-mmix.c:1598
+#: elfxx-tilegx.c:3585
+msgid "internal error: dangerous relocation"
+msgstr "lỗi nội bộ: định vị lại nguy hiểm"
+
+#: elf32-avr.c:2415 elf32-hppa.c:598 elf32-m68hc1x.c:166
+msgid "%B: cannot create stub entry %s"
+msgstr "%B: không thể tạo mục nhập mẩu %s"
+
+#: elf32-bfin.c:107 elf32-bfin.c:363
+msgid "relocation should be even number"
+msgstr "tái định vị phải là số chẵn"
+
+#: elf32-bfin.c:1593
+msgid "%B(%A+0x%lx): unresolvable relocation against symbol `%s'"
+msgstr "%B(%A+0x%lx): định vị lại không thể giải quyết đối với ký hiệu \"%s\""
+
+#: elf32-bfin.c:1626 elf32-i386.c:4307 elf32-m68k.c:4233 elf32-s390.c:3055
+#: elf64-s390.c:3030 elf64-x86-64.c:4151
+msgid "%B(%A+0x%lx): reloc against `%s': error %d"
+msgstr "%B(%A+0x%lx): định vị lại đối với \"%s\": lỗi %d"
+
+#: elf32-bfin.c:2725
+msgid "%B: relocation at `%A+0x%x' references symbol `%s' with nonzero addend"
+msgstr "%B: định vị lại ở \"%A+0x%x\" tham chiếu đến ký hiệu \"%s\" với số hạng khác không"
+
+#: elf32-bfin.c:2741
+msgid "relocation references symbol not defined in the module"
+msgstr "định vị lại tham chiếu đến ký hiệu không được định nghĩa trong mô-đun"
+
+#: elf32-bfin.c:2838
+msgid "R_BFIN_FUNCDESC references dynamic symbol with nonzero addend"
+msgstr "R_FRV_FUNCDESC tham chiếu đến ký hiệu động với số hạng khác không"
+
+#: elf32-bfin.c:2879 elf32-bfin.c:3002
+msgid "cannot emit fixups in read-only section"
+msgstr "Không thể phát ra sá»± sá»­a chữa trong phần chỉ Ä‘á»c"
+
+#: elf32-bfin.c:2910 elf32-bfin.c:3040 elf32-lm32.c:1103 elf32-sh.c:5016
+msgid "cannot emit dynamic relocations in read-only section"
+msgstr "không thể phát ra định vị lại Ä‘á»™ng trong phần chỉ Ä‘á»c"
+
+#: elf32-bfin.c:2960
+msgid "R_BFIN_FUNCDESC_VALUE references dynamic symbol with nonzero addend"
+msgstr "R_FRV_FUNCDESC_VALUE tham chiếu đến ký hiệu động với số hạng khác không"
+
+#: elf32-bfin.c:3125
+msgid "relocations between different segments are not supported"
+msgstr "không hỗ trợ định vị lại giữa các đoạn khác nhau"
+
+#: elf32-bfin.c:3126
+msgid "warning: relocation references a different segment"
+msgstr "cảnh báo: định vị lại tham chiếu đến một đoạn khác"
+
+#: elf32-bfin.c:4971
+msgid "%B: unsupported relocation type %i"
+msgstr "%B: kiểu định vị lại không được hỗ trợ %i"
+
+#: elf32-bfin.c:5125 elf32-frv.c:6808
+#, c-format
+msgid "%s: cannot link non-fdpic object file into fdpic executable"
+msgstr "%s: không thể liên kết tập tin đối tượng khác fdpic vào tập tin fdpic có thể thực hiện"
+
+#: elf32-bfin.c:5129 elf32-frv.c:6812
+#, c-format
+msgid "%s: cannot link fdpic object file into non-fdpic executable"
+msgstr "%s: không thể liên kết tập tin đối tượng khác fdpic vào tập tin khác fdpic có thể thực hiện"
+
+#: elf32-bfin.c:5283
+#, c-format
+msgid "*** check this relocation %s"
+msgstr "*** kiểm tra tái phân bổ này %s"
+
+#: elf32-cris.c:1176
+msgid "%B, section %A: unresolvable relocation %s against symbol `%s'"
+msgstr "%B, phần %A: định vị lại không thể giải quyết %s đối với ký hiệu \"%s\""
+
+#: elf32-cris.c:1238
+msgid "%B, section %A: No PLT nor GOT for relocation %s against symbol `%s'"
+msgstr "%B, phần %A: Không có PLT hoặc GOT cho định vị lại %s đối với ký hiệu \"%s\""
+
+#: elf32-cris.c:1240
+msgid "%B, section %A: No PLT for relocation %s against symbol `%s'"
+msgstr "%B, phần %A: Không có PLT cho định vị lại %s đối với ký hiệu \"%s\""
+
+#: elf32-cris.c:1246 elf32-cris.c:1379 elf32-cris.c:1639 elf32-cris.c:1722
+#: elf32-cris.c:1875 elf32-tic6x.c:2662
+msgid "[whose name is lost]"
+msgstr "[mất tên của ai]"
+
+#: elf32-cris.c:1365 elf32-tic6x.c:2647
+msgid "%B, section %A: relocation %s with non-zero addend %d against local symbol"
+msgstr "%B, phần %A: định vị lại %s với số hạng khác không %d đối với ký hiệu cục bộ"
+
+#: elf32-cris.c:1373 elf32-cris.c:1716 elf32-cris.c:1869 elf32-tic6x.c:2655
+msgid "%B, section %A: relocation %s with non-zero addend %d against symbol `%s'"
+msgstr "%B, phần %A: định vị lại %s với số hạng khác không %d đối với ký hiệu \"%s\""
+
+#: elf32-cris.c:1399
+msgid "%B, section %A: relocation %s is not allowed for global symbol: `%s'"
+msgstr "%B, phần %A: định vị lại %s không được phép cho ký hiệu toàn cục: \"%s\""
+
+#: elf32-cris.c:1415
+msgid "%B, section %A: relocation %s with no GOT created"
+msgstr "%B, phần %A: đã tạo định vị lại %s không có GOT"
+
+#. We shouldn't get here for GCC-emitted code.
+#: elf32-cris.c:1630
+msgid "%B, section %A: relocation %s has an undefined reference to `%s', perhaps a declaration mixup?"
+msgstr "%B: phần %A: sự định vị lại $s có một thàm chiếu chưa xác định đến \"%s\", có thể khai báo không rõ ?"
+
+#: elf32-cris.c:2002
+msgid "%B, section %A: relocation %s is not allowed for symbol: `%s' which is defined outside the program, perhaps a declaration mixup?"
+msgstr "%B, phần %A: sự định vị lại %s không được phép cho ký hiệu \"%s\" mà được xác định bên ngoài chương trình, có thể khai báo không rõ ?"
+
+#: elf32-cris.c:2055
+msgid "(too many global variables for -fpic: recompile with -fPIC)"
+msgstr "(quá nhiá»u biến toàn cục đối vá»›i \"-fpic\": hãy biên dịch lại vá»›i \"-fPIC\")"
+
+#: elf32-cris.c:2062
+msgid "(thread-local data too big for -fpic or -msmall-tls: recompile with -fPIC or -mno-small-tls)"
+msgstr "(dữ liệu cục bộ với mạch cũng quá lớn đối với \"fpic\" hoặc \"-msmall-tls\": hãy biên dịch lại với \"-fPIC\" hay \"-mno-small-tls\")"
+
+#: elf32-cris.c:3261
+msgid ""
+"%B, section %A:\n"
+" v10/v32 compatible object %s must not contain a PIC relocation"
+msgstr ""
+"%B, phần %A:\n"
+" đối tượng tương thích v10/v32 %s không được chứa định vị lại PIC"
+
+#: elf32-cris.c:3366
+msgid ""
+"%B, section %A:\n"
+" relocation %s not valid in a shared object; typically an option mixup, recompile with -fPIC"
+msgstr ""
+"%B, phần %A:\n"
+" không được sá»­ dụng sá»± định vị lại %s trong má»™t đối tượng chia sẻ; bình thÆ°á»ng do khai báo không rõ, hãy biên dịch lại vá»›i \"-fPIC\""
+
+#: elf32-cris.c:3580
+msgid ""
+"%B, section %A:\n"
+" relocation %s should not be used in a shared object; recompile with -fPIC"
+msgstr ""
+"%B, phần %A:\n"
+" không được sử dụng sự định vị lại %s trong một đối tượng chia sẻ; hãy biên dịch lại với \"-fPIC\""
+
+#: elf32-cris.c:4002
+msgid ""
+"%B, section `%A', to symbol `%s':\n"
+" relocation %s should not be used in a shared object; recompile with -fPIC"
+msgstr ""
+"%B, phần \"%A\", tới ký hiệu \"%s\":\n"
+" không được sử dụng sự định vị lại %s trong một đối tượng chia sẻ; hãy biên dịch lại với \"-fPIC\""
+
+#: elf32-cris.c:4118
+msgid "Unexpected machine number"
+msgstr "Số thứ tá»± máy bất thÆ°á»ng"
+
+#: elf32-cris.c:4172
+#, c-format
+msgid " [symbols have a _ prefix]"
+msgstr " [ký hiệu có má»™t tiá»n tố _]"
+
+#: elf32-cris.c:4175
+#, c-format
+msgid " [v10 and v32]"
+msgstr " [v10 và v32]"
+
+#: elf32-cris.c:4178
+#, c-format
+msgid " [v32]"
+msgstr " [v32]"
+
+#: elf32-cris.c:4223
+msgid "%B: uses _-prefixed symbols, but writing file with non-prefixed symbols"
+msgstr "%B: dùng ký hiệu tiá»n tố _, nhÆ°ng Ä‘ang ghi tập tin vá»›i ký hiệu không phải tiá»n tố"
+
+#: elf32-cris.c:4224
+msgid "%B: uses non-prefixed symbols, but writing file with _-prefixed symbols"
+msgstr "%B: dùng ký hiệu không phải tiá»n tố, nhÆ°ng Ä‘ang ghi tập tin vá»›i ký hiệu có tiá»n tố _"
+
+#: elf32-cris.c:4243
+msgid "%B contains CRIS v32 code, incompatible with previous objects"
+msgstr "%B chứa mã CRIS v32, không tương thích với các đối tượng trước"
+
+#: elf32-cris.c:4245
+msgid "%B contains non-CRIS-v32 code, incompatible with previous objects"
+msgstr "%B chứa mã khác CRIS v32, không tương thích với các đối tượng trước"
+
+#: elf32-dlx.c:142
+#, c-format
+msgid "BFD Link Error: branch (PC rel16) to section (%s) not supported"
+msgstr "BFD Lỗi liên kết: rẽ nhánh (PC rel16) tới phần (%s) không được hỗ trợ"
+
+#: elf32-dlx.c:204
+#, c-format
+msgid "BFD Link Error: jump (PC rel26) to section (%s) not supported"
+msgstr "BFD Lỗi liên kết: nhảy (PC rel16) tới phần (%s) không được hỗ trợ"
+
+#. Only if it's not an unresolved symbol.
+#: elf32-epiphany.c:563 elf32-ip2k.c:1475
+msgid "unsupported relocation between data/insn address spaces"
+msgstr "gặp định vị lại không được hỗ trợ giữa vùng địa chỉ kiểu dữ liệu và chỉ dẫn"
+
+#: elf32-frv.c:1509 elf32-frv.c:1658
+msgid "relocation requires zero addend"
+msgstr "định vị lại cần thiết số hạng số không"
+
+#: elf32-frv.c:2888
+msgid "%H: relocation to `%s+%v' may have caused the error above\n"
+msgstr "%H: định vị lại tới \"%s+%x\" có thể gây ra lỗi trên\n"
+
+#: elf32-frv.c:2905
+msgid "%H: relocation references symbol not defined in the module\n"
+msgstr "%H: định vị lại tham chiếu đến ký hiệu không được định nghĩa trong mô-đun\n"
+
+#: elf32-frv.c:2981
+msgid "%H: R_FRV_GETTLSOFF not applied to a call instruction\n"
+msgstr "%H: R_FRV_GETTLSOFF không áp dụng tới một chỉ dẫn call\n"
+
+#: elf32-frv.c:3022
+msgid "%H: R_FRV_GOTTLSDESC12 not applied to an lddi instruction\n"
+msgstr "%H: R_FRV_GOTTLSDESC12 không áp dụng tới một chỉ dẫn lddi\n"
+
+#: elf32-frv.c:3093
+msgid "%H: R_FRV_GOTTLSDESCHI not applied to a sethi instruction\n"
+msgstr "%H: R_FRV_GOTTLSDESCHI không áp dụng tới một chỉ dẫn sethi\n"
+
+#: elf32-frv.c:3130
+msgid "%H: R_FRV_GOTTLSDESCLO not applied to a setlo or setlos instruction\n"
+msgstr "%H: R_FRV_GOTTLSDESCLO không áp dụng tới một chỉ dẫn setlo hay setlos\n"
+
+#: elf32-frv.c:3177
+msgid "%H: R_FRV_TLSDESC_RELAX not applied to an ldd instruction\n"
+msgstr "%H: R_FRV_TLSDESC_RELAX không áp dụng tới một chỉ dẫn ldd\n"
+
+#: elf32-frv.c:3261
+msgid "%H: R_FRV_GETTLSOFF_RELAX not applied to a calll instruction\n"
+msgstr "%H: R_FRV_GETTLSOFF_RELAX không áp dụng tới một chỉ dẫn calll\n"
+
+#: elf32-frv.c:3315
+msgid "%H: R_FRV_GOTTLSOFF12 not applied to an ldi instruction\n"
+msgstr "%H: R_FRV_GOTTLSOFF12 không áp dụng tới một chỉ dẫn ldi\n"
+
+#: elf32-frv.c:3345
+msgid "%H: R_FRV_GOTTLSOFFHI not applied to a sethi instruction\n"
+msgstr "%H: R_FRV_GOTTLSOFFHI không áp dụng tới một chỉ dẫn sethi\n"
+
+#: elf32-frv.c:3374
+msgid "%H: R_FRV_GOTTLSOFFLO not applied to a setlo or setlos instruction\n"
+msgstr "%H: R_FRV_GOTTLSOFFLO không áp dụng tới một chỉ dẫn setlo hay setlos\n"
+
+#: elf32-frv.c:3404
+msgid "%H: R_FRV_TLSOFF_RELAX not applied to an ld instruction\n"
+msgstr "%H: R_FRV_TLSOFF_RELAX không áp dụng tới một chỉ dẫn ld\n"
+
+#: elf32-frv.c:3449
+msgid "%H: R_FRV_TLSMOFFHI not applied to a sethi instruction\n"
+msgstr "%H: R_FRV_TLSMOFFHI không áp dụng tới một chỉ dẫn sethi\n"
+
+#: elf32-frv.c:3476
+msgid "R_FRV_TLSMOFFLO not applied to a setlo or setlos instruction\n"
+msgstr "R_FRV_TLSMOFFLO không áp dụng tới một chỉ dẫn setlo hay setlos\n"
+
+#: elf32-frv.c:3597
+msgid "%H: R_FRV_FUNCDESC references dynamic symbol with nonzero addend\n"
+msgstr "%H: R_FRV_FUNCDESC tham chiếu đến ký hiệu động với số hạng khác không\n"
+
+#: elf32-frv.c:3638 elf32-frv.c:3760
+msgid "%H: cannot emit fixups in read-only section\n"
+msgstr "%H: không thể phát ra sá»± sá»­a chữa trong phần chỉ Ä‘á»c\n"
+
+#: elf32-frv.c:3669 elf32-frv.c:3803
+msgid "%H: cannot emit dynamic relocations in read-only section\n"
+msgstr "%H: không thể phát ra định vị lại Ä‘á»™ng trong phần chỉ Ä‘á»c\n"
+
+#: elf32-frv.c:3718
+msgid "%H: R_FRV_FUNCDESC_VALUE references dynamic symbol with nonzero addend\n"
+msgstr "%H: R_FRV_FUNCDESC_VALUE tham chiếu đến ký hiệu động với số hạng khác không\n"
+
+#: elf32-frv.c:3974
+msgid "%H: reloc against `%s' references a different segment\n"
+msgstr "%H: định vị lại tham chiếu `%s' đến một đoạn khác\n"
+
+#: elf32-frv.c:4124
+msgid "%H: reloc against `%s': %s\n"
+msgstr "%H: reloc lại `%s': %s\n"
+
+#: elf32-frv.c:6400
+msgid "%B: unsupported relocation type %i\n"
+msgstr "%B: kiểu định vị lại không được hỗ trợ %i\n"
+
+#: elf32-frv.c:6722
+#, c-format
+msgid "%s: compiled with %s and linked with modules that use non-pic relocations"
+msgstr "%s: biên dịch với %s và liên kết với môđun sử dụng định vị lại khác pic"
+
+#: elf32-frv.c:6775 elf32-iq2000.c:845 elf32-m32c.c:807
+#, c-format
+msgid "%s: compiled with %s and linked with modules compiled with %s"
+msgstr "%s: biên dịch với %s và liên kết với môđun biên dịch với %s"
+
+#: elf32-frv.c:6787
+#, c-format
+msgid "%s: uses different unknown e_flags (0x%lx) fields than previous modules (0x%lx)"
+msgstr "%s: sá»­ dụng trÆ°á»ng e_flags không rõ (0x%lx) khác vá»›i moÄ‘un trÆ°á»›c (0x%lx)"
+
+#: elf32-frv.c:6837 elf32-iq2000.c:882 elf32-m32c.c:843 elf32-mt.c:576
+#: elf32-rx.c:3001
+#, c-format
+msgid "private flags = 0x%lx:"
+msgstr "các cỠriêng = 0x%lx:"
+
+#: elf32-gen.c:69 elf64-gen.c:69
+msgid "%B: Relocations in generic ELF (EM: %d)"
+msgstr "%B: Äịnh vị lại trong ELF chung (EM: %d)"
+
+#: elf32-hppa.c:850 elf32-hppa.c:3598
+msgid "%B(%A+0x%lx): cannot reach %s, recompile with -ffunction-sections"
+msgstr "%B(%A+0x%lx): không thể tới %s, hãy biên dịch lại với \"-ffunction-sections\""
+
+#: elf32-hppa.c:1284
+msgid "%B: relocation %s can not be used when making a shared object; recompile with -fPIC"
+msgstr "%B: không dùng được định vị lại %s khi tạo một đối tượng chia sẽ, hãy biên dịch lại với \"-fPIC\""
+
+#: elf32-hppa.c:2791
+msgid "%B: duplicate export stub %s"
+msgstr "%B: mẩu xuất trùng %s"
+
+#: elf32-hppa.c:3437
+msgid "%B(%A+0x%lx): %s fixup for insn 0x%x is not supported in a non-shared link"
+msgstr "%B(%A+0x%lx): %s sự sửa chữa cho chỉ dẫn 0x%x không được hỗ trợ trong một liên kết không chia sẻ"
+
+#: elf32-hppa.c:4284
+msgid "%B(%A+0x%lx): cannot handle %s for %s"
+msgstr "%B(%A+0x%lx): không thể xử lý %s cho %s"
+
+#: elf32-hppa.c:4603
+msgid ".got section not immediately after .plt section"
+msgstr "Phần .got không nằm ngay sau phần .pit"
+
+#. Unknown relocation.
+#: elf32-i386.c:373 elf32-m68k.c:384 elf32-ppc.c:1676 elf32-s390.c:379
+#: elf32-tic6x.c:2684 elf64-ppc.c:2300 elf64-s390.c:403 elf64-x86-64.c:265
+msgid "%B: invalid relocation type %d"
+msgstr "%B: kiểu định vị lại không hợp lệ %d"
+
+#: elf32-i386.c:1404 elf64-x86-64.c:1308
+msgid "%B: TLS transition from %s to %s against `%s' at 0x%lx in section `%A' failed"
+msgstr "%B: không thành công chuyển tiếp TLS từ %s sang %s đối với \"%s\" ở 0x%lx trong phần \"%A\""
+
+#: elf32-i386.c:1549 elf32-i386.c:3244 elf64-x86-64.c:1487 elf64-x86-64.c:3125
+#: elfxx-sparc.c:3083
+msgid "%B: relocation %s against STT_GNU_IFUNC symbol `%s' isn't handled by %s"
+msgstr "%B: sự định vị lại %s đối với ký hiệu STT_GNU_IFUNC \"%s\" không phải được %s quản lý"
+
+#: elf32-i386.c:1711 elf32-s390.c:1182 elf32-sh.c:6362 elf32-tilepro.c:1434
+#: elf32-xtensa.c:1182 elf64-s390.c:1151 elfxx-sparc.c:1548
+#: elfxx-tilegx.c:1701
+msgid "%B: `%s' accessed both as normal and thread local symbol"
+msgstr "%B: đã truy cập \"%s\" theo ký hiệu cả hai kiểu bình thÆ°á»ng và cục bá»™ cho mạch"
+
+#: elf32-i386.c:2539 elf64-x86-64.c:2506
+msgid "%P: %B: warning: relocation against `%s' in readonly section `%A'.\n"
+msgstr "%P: %B: cảnh báo: định vị lại dá»±a vào %s trong phần chỉ Ä‘á»c `%A'.\n"
+
+#: elf32-i386.c:2629 elf64-x86-64.c:2593
+msgid "%P: %B: warning: relocation in readonly section `%A'.\n"
+msgstr "%P: %B: cảnh báo: tái định vị trong phần chỉ Ä‘á»c `%A'.\n"
+
+#: elf32-i386.c:3086 elf32-tilepro.c:2557 elfxx-tilegx.c:2871
+msgid "%B: unrecognized relocation (0x%x) in section `%A'"
+msgstr "%B: định vị lại không được nhận ra (0x%x) trong phần \"%A\""
+
+#: elf32-i386.c:3494 elf64-x86-64.c:3513
+msgid "hidden symbol"
+msgstr "ký hiệu bị ẩn"
+
+#: elf32-i386.c:3497 elf64-x86-64.c:3516
+msgid "internal symbol"
+msgstr "ký hiệu nội bộ"
+
+#: elf32-i386.c:3500 elf64-x86-64.c:3519
+msgid "protected symbol"
+msgstr "ký hiệu bị bảo vệ"
+
+#: elf32-i386.c:3503 elf64-x86-64.c:3522
+msgid "symbol"
+msgstr "ký hiệu"
+
+#: elf32-i386.c:3508
+msgid "%B: relocation R_386_GOTOFF against undefined %s `%s' can not be used when making a shared object"
+msgstr "%B: không dùng được định vị lại R_386_GOTOFF đối với %s chưa xác định \"%s\" khi tạo một đối tượng chia sẻ"
+
+#: elf32-i386.c:3518
+msgid "%B: relocation R_386_GOTOFF against protected function `%s' can not be used when making a shared object"
+msgstr "%B: không dùng được định vị lại R_386_GOTOFF đối với hàm số đã bảo vệ \"%s\" khi tạo một đối tượng chia sẻ"
+
+#: elf32-i386.c:4839 elf32-tilepro.c:3467 elf64-x86-64.c:4609
+#: elfxx-tilegx.c:3847
+#, c-format
+msgid "discarded output section: `%A'"
+msgstr "phần kết xuất bị bỠqua: `%A'"
+
+#: elf32-ip2k.c:857 elf32-ip2k.c:863 elf32-ip2k.c:930 elf32-ip2k.c:936
+msgid "ip2k relaxer: switch table without complete matching relocation information."
+msgstr "trình giảm nhẹ ip2k: chuyển đổi bảng mà không có thông tin định vị lại hoàn thành."
+
+#: elf32-ip2k.c:880 elf32-ip2k.c:963
+msgid "ip2k relaxer: switch table header corrupt."
+msgstr "trình giảm nhẹ ip2k: bảng chuyển đổi có phần đầu bị há»ng."
+
+#: elf32-ip2k.c:1292
+#, c-format
+msgid "ip2k linker: missing page instruction at 0x%08lx (dest = 0x%08lx)."
+msgstr "trình liên kết ip2k: thiếu chỉ dẫn trang tại 0x%08lx (đích = 0x%08lx)."
+
+#: elf32-ip2k.c:1308
+#, c-format
+msgid "ip2k linker: redundant page instruction at 0x%08lx (dest = 0x%08lx)."
+msgstr "trình liên kết ip2k: thừa chủ dẫn trang tại 0x%08lx (đích = 0x%08lx)."
+
+#: elf32-iq2000.c:858 elf32-m32c.c:819
+#, c-format
+msgid "%s: uses different e_flags (0x%lx) fields than previous modules (0x%lx)"
+msgstr "%s: sá»­ dụng trÆ°á»ng e_flags (0x%lx) khác vá»›i mo-Ä‘un trÆ°á»›c (0x%lx)"
+
+#: elf32-lm32.c:706
+msgid "global pointer relative relocation when _gp not defined"
+msgstr "có định vị lại tương đối với con trỠtoàn cục khi chưa xác định _gp"
+
+#: elf32-lm32.c:761
+msgid "global pointer relative address out of range"
+msgstr "địa chỉ tương đối với con trỠtoàn cục vẫn ở ngoại phạm vi"
+
+#: elf32-lm32.c:1057
+msgid "internal error: addend should be zero for R_LM32_16_GOT"
+msgstr "lỗi nội bộ: phần cộng nên là số không cho R_LM32_16_GOT"
+
+#: elf32-m32r.c:1453
+msgid "SDA relocation when _SDA_BASE_ not defined"
+msgstr "định vị lại SDA khi chưa xác định _SDA_BASE_"
+
+#: elf32-m32r.c:3043
+msgid "%B: The target (%s) of an %s relocation is in the wrong section (%A)"
+msgstr "%B: Äích (%s) của má»™t định vị lại %s nằm trong phần sai (%A)"
+
+#: elf32-m32r.c:3571
+msgid "%B: Instruction set mismatch with previous modules"
+msgstr "%B: Bộ chỉ dẫn không tương ứng với các mô-đun trước"
+
+#: elf32-m32r.c:3592
+#, c-format
+msgid "private flags = %lx"
+msgstr "các cỠriêng — %lx"
+
+#: elf32-m32r.c:3597
+#, c-format
+msgid ": m32r instructions"
+msgstr ": chỉ dẫn m32r"
+
+#: elf32-m32r.c:3598
+#, c-format
+msgid ": m32rx instructions"
+msgstr ": chỉ dẫn m32rx"
+
+#: elf32-m32r.c:3599
+#, c-format
+msgid ": m32r2 instructions"
+msgstr ": chỉ dẫn m32r2"
+
+#: elf32-m68hc1x.c:1050
+#, c-format
+msgid "Reference to the far symbol `%s' using a wrong relocation may result in incorrect execution"
+msgstr "Tham chiếu đến ký hiệu ở xa \"%s\" khi sử dụng một định vị lại sai thì có thể dẫn đến sự thực hiện sai"
+
+#: elf32-m68hc1x.c:1073
+#, c-format
+msgid "banked address [%lx:%04lx] (%lx) is not in the same bank as current banked address [%lx:%04lx] (%lx)"
+msgstr "địa chỉ đã đặt vào khối nhá»› [%lx:%04lx] (%lx) không trong cùng khối nhá»› vá»›i địa chỉ được đặt hiện thá»i vào khối nhá»› [%lx:%04lx] (%lx)"
+
+#: elf32-m68hc1x.c:1092
+#, c-format
+msgid "reference to a banked address [%lx:%04lx] in the normal address space at %04lx"
+msgstr "tham chiếu đến má»™t địa chỉ đã đặt vào khối nhá»› [%lx:%04lx] trong vùng địa chỉ thông thÆ°á»ng tại %04lx"
+
+#: elf32-m68hc1x.c:1225
+msgid "%B: linking files compiled for 16-bit integers (-mshort) and others for 32-bit integers"
+msgstr "%B: đang liên kết các tập tin được biên dịch cho số nguyên 16 bit (-mshort) và các tập tin khác cho số nguyên 32 bit"
+
+#: elf32-m68hc1x.c:1232
+msgid "%B: linking files compiled for 32-bit double (-fshort-double) and others for 64-bit double"
+msgstr "%B: đang liên kết các tập tin được biên dịch 32 bit đôi (-mshort) và các tập tin khác cho 64 bit đôi"
+
+#: elf32-m68hc1x.c:1241
+msgid "%B: linking files compiled for HCS12 with others compiled for HC12"
+msgstr "%B: đang liên kết tập tin được biên dịch cho HCS12 với các tập tin khác biên dịch cho HC12"
+
+#: elf32-m68hc1x.c:1257 elf32-ppc.c:4227 elf64-sparc.c:706 elfxx-mips.c:13965
+msgid "%B: uses different e_flags (0x%lx) fields than previous modules (0x%lx)"
+msgstr "%B: sá»­ dụng trÆ°á»ng e_flags (0x%lx) khác vá»›i mo-Ä‘un trÆ°á»›c (0x%lx)"
+
+#: elf32-m68hc1x.c:1285
+#, c-format
+msgid "[abi=32-bit int, "
+msgstr "[abi=số nguyên 32-bit, "
+
+#: elf32-m68hc1x.c:1287
+#, c-format
+msgid "[abi=16-bit int, "
+msgstr "[abi=số nguyên 16-bit, "
+
+#: elf32-m68hc1x.c:1290
+#, c-format
+msgid "64-bit double, "
+msgstr "64-bit đôi, "
+
+#: elf32-m68hc1x.c:1292
+#, c-format
+msgid "32-bit double, "
+msgstr "32-bit đôi, "
+
+#: elf32-m68hc1x.c:1295
+#, c-format
+msgid "cpu=HC11]"
+msgstr "cpu=HC11]"
+
+#: elf32-m68hc1x.c:1297
+#, c-format
+msgid "cpu=HCS12]"
+msgstr "cpu=HCS12]"
+
+#: elf32-m68hc1x.c:1299
+#, c-format
+msgid "cpu=HC12]"
+msgstr "cpu=HC12]"
+
+#: elf32-m68hc1x.c:1302
+#, c-format
+msgid " [memory=bank-model]"
+msgstr " [bộ nhớ=chế độ khối]"
+
+#: elf32-m68hc1x.c:1304
+#, c-format
+msgid " [memory=flat]"
+msgstr " [bộ nhớ=phẳng]"
+
+#: elf32-m68k.c:1251 elf32-m68k.c:1252 vms-alpha.c:7314 vms-alpha.c:7329
+msgid "unknown"
+msgstr "không rõ"
+
+#: elf32-m68k.c:1715
+msgid "%B: GOT overflow: Number of relocations with 8-bit offset > %d"
+msgstr "%B: tràn GOT: số các sự định vị lại với hiệu 8-bit > %d"
+
+#: elf32-m68k.c:1721
+msgid "%B: GOT overflow: Number of relocations with 8- or 16-bit offset > %d"
+msgstr "%B: tràn GOT: số các sự định vị lại với hiệu 8-bit hay 16-bit > %d"
+
+#: elf32-m68k.c:3957
+msgid "%B(%A+0x%lx): R_68K_TLS_LE32 relocation not permitted in shared object"
+msgstr "%B(%A+0x%lx): R_68K_TLS_LE32 không cho phép định vị lại trong đối tượng chia sẻ"
+
+#: elf32-mcore.c:99 elf32-mcore.c:442
+msgid "%B: Relocation %s (%d) is not currently supported.\n"
+msgstr "%B: Äịnh vị lại %s (%d) hiện thá»i không được há»— trợ.\n"
+
+#: elf32-mcore.c:428
+msgid "%B: Unknown relocation type %d\n"
+msgstr "%B: Kiểu định vị lại không rõ %d\n"
+
+#. Pacify gcc -Wall.
+#: elf32-mep.c:157
+#, c-format
+msgid "mep: no reloc for code %d"
+msgstr "mep: không reloc cho mã %d"
+
+#: elf32-mep.c:163
+#, c-format
+msgid "MeP: howto %d has type %d"
+msgstr "MeP: sao %d có kiểu %d"
+
+#: elf32-mep.c:648
+msgid "%B and %B are for different cores"
+msgstr "%B và %B dành cho lõi khác nhau"
+
+#: elf32-mep.c:665
+msgid "%B and %B are for different configurations"
+msgstr "%B và %B dành cho cấu hình khác nhau"
+
+#: elf32-mep.c:702
+#, c-format
+msgid "private flags = 0x%lx"
+msgstr "các cỠriêng = 0x%lx"
+
+#: elf32-microblaze.c:742
+#, c-format
+msgid "%s: unknown relocation type %d"
+msgstr "%s: không rõ loại định vị lại %d"
+
+#: elf32-microblaze.c:867 elf32-microblaze.c:912
+#, c-format
+msgid "%s: The target (%s) of an %s relocation is in the wrong section (%s)"
+msgstr "%s: Äích (%s) của má»™t sá»± định vị lại %s nằm trong phần không đúng (%s)"
+
+#: elf32-microblaze.c:1155 elf32-tilepro.c:2891 elfxx-sparc.c:3457
+#: elfxx-tilegx.c:3230
+msgid "%B: probably compiled without -fPIC?"
+msgstr "%B: rất có thể được biên dịch không có \"-fPIC\" ?"
+
+#: elf32-microblaze.c:2074
+msgid "%B: bad relocation section name `%s'"
+msgstr "%B: tên phần định vị lại sai \"%s\""
+
+#: elf32-mips.c:1549 elf64-mips.c:2683 elfn32-mips.c:2487
+msgid "literal relocation occurs for an external symbol"
+msgstr "định vị lại nghĩa chữ xảy ra cho một ký hiệu bên ngoài"
+
+#: elf32-mips.c:1596 elf32-score.c:570 elf32-score7.c:469 elf64-mips.c:2726
+#: elfn32-mips.c:2528
+msgid "32bits gp relative relocation occurs for an external symbol"
+msgstr "định vị lại tương đối 32-bit gp xảy ra cho một ký hiệu bên ngoài"
+
+#: elf32-ppc.c:1741
+#, c-format
+msgid "generic linker can't handle %s"
+msgstr "trình liên kết chung không thể xử lý %s"
+
+#: elf32-ppc.c:2184
+msgid "corrupt %s section in %B"
+msgstr "phần %s bị há»ng trong %b"
+
+#: elf32-ppc.c:2203
+msgid "unable to read in %s section from %B"
+msgstr "không thể Ä‘á»c trong phần %s từ %B"
+
+#: elf32-ppc.c:2244
+msgid "warning: unable to set size of %s section in %B"
+msgstr "cảnh báo: không thể đặt kích cỡ của phần %s trong %B"
+
+#: elf32-ppc.c:2294
+msgid "failed to allocate space for new APUinfo section."
+msgstr "lỗi cấp phát sức chứa cho phần thông tin APUinfo mới."
+
+#: elf32-ppc.c:2313
+msgid "failed to compute new APUinfo section."
+msgstr "lỗi tính phần thông tin APUinfo mới."
+
+#: elf32-ppc.c:2316
+msgid "failed to install new APUinfo section."
+msgstr "lỗi cài đặt phần thông tin APUinfo mới."
+
+#: elf32-ppc.c:3356
+msgid "%B: relocation %s cannot be used when making a shared object"
+msgstr "%B: không dùng được định vị lại %s khi tạo một đối tượng chia sẻ"
+
+#. It does not make sense to have a procedure linkage
+#. table entry for a local symbol.
+#: elf32-ppc.c:3700
+msgid "%P: %H: %s reloc against local symbol\n"
+msgstr "%P: %H: %s reloc dựa vào ký hiệu nội bộ\n"
+
+#: elf32-ppc.c:4039 elf32-ppc.c:4054 elfxx-mips.c:13651 elfxx-mips.c:13677
+#: elfxx-mips.c:13699 elfxx-mips.c:13725
+msgid "Warning: %B uses hard float, %B uses soft float"
+msgstr "Cảnh báo: %B dùng trôi cứng, còn %B dùng trôi má»m"
+
+#: elf32-ppc.c:4042 elf32-ppc.c:4046
+msgid "Warning: %B uses double-precision hard float, %B uses single-precision hard float"
+msgstr "Cảnh báo: %B dùng trôi cứng chính xác đôi, còn %B dùng trôi cứng chính xác đơn"
+
+#: elf32-ppc.c:4050
+msgid "Warning: %B uses soft float, %B uses single-precision hard float"
+msgstr "Cảnh báo: %B dùng trôi má»m, còn %B dùng trôi cứng chính xác Ä‘Æ¡n"
+
+#: elf32-ppc.c:4057 elf32-ppc.c:4061 elfxx-mips.c:13631 elfxx-mips.c:13635
+msgid "Warning: %B uses unknown floating point ABI %d"
+msgstr "Cảnh báo: %B dùng điểm trôi không rõ ABI %d"
+
+#: elf32-ppc.c:4103 elf32-ppc.c:4107
+msgid "Warning: %B uses unknown vector ABI %d"
+msgstr "Cảnh báo: %B dùng véc-tơ không nhận ra ABI %d"
+
+#: elf32-ppc.c:4111
+msgid "Warning: %B uses vector ABI \"%s\", %B uses \"%s\""
+msgstr "Cảnh báo: %B dùng véc-tơ ABI \"%s\", còn %B dùng \"%s\""
+
+#: elf32-ppc.c:4128 elf32-ppc.c:4131
+msgid "Warning: %B uses r3/r4 for small structure returns, %B uses memory"
+msgstr "Cảnh báo: %B dùng r3/r4 để trả lại cấu trúc nhá», %B dùng phần nhá»›"
+
+#: elf32-ppc.c:4134 elf32-ppc.c:4138
+msgid "Warning: %B uses unknown small structure return convention %d"
+msgstr "Cảnh báo: %B dùng quy ước trả lại cấu trúc nhỠkhông rõ %d"
+
+#: elf32-ppc.c:4192
+msgid "%B: compiled with -mrelocatable and linked with modules compiled normally"
+msgstr "%B: đã biên dịch vá»›i \"-mrelocatable\" và đã liên kết vá»›i các môđun biên dịch bình thÆ°á»ng"
+
+#: elf32-ppc.c:4200
+msgid "%B: compiled normally and linked with modules compiled with -mrelocatable"
+msgstr "%B: đã biên dịch bình thÆ°á»ng và đã liên kết vá»›i các môđun biên dịch vá»›i \"-mrelocatable\""
+
+#: elf32-ppc.c:4309
+msgid "%P: bss-plt forced due to %B\n"
+msgstr "%P: bss-plt bị ép buộc bởi vì %B\n"
+
+#: elf32-ppc.c:4312
+msgid "%P: bss-plt forced by profiling\n"
+msgstr "%P: bss-plt được ép buộc bởi 'profiling'\n"
+
+#. Uh oh, we didn't find the expected call. We
+#. could just mark this symbol to exclude it
+#. from tls optimization but it's safer to skip
+#. the entire optimization.
+#: elf32-ppc.c:4809 elf64-ppc.c:7858
+msgid "%H arg lost __tls_get_addr, TLS optimization disabled\n"
+msgstr "%H arg lost __tls_get_addr, tối ưu hóa TLS bị tắt\n"
+
+#: elf32-ppc.c:5044 elf64-ppc.c:6528
+msgid "%P: dynamic variable `%s' is zero size\n"
+msgstr "%P: biến kiểu động `%s' có kích thước là không\n"
+
+#: elf32-ppc.c:7263 elf64-ppc.c:12675
+msgid "%P: %B: unknown relocation type %d for symbol %s\n"
+msgstr "%P: %B: không rõ kiểu tái định vị %d cho ký hiệu %s\n"
+
+#: elf32-ppc.c:7524
+msgid "%P: %H: non-zero addend on %s reloc against `%s'\n"
+msgstr "%P: %H: số hạng khác không trên reloc %s dựa vào `%s'\n"
+
+#: elf32-ppc.c:7720 elf64-ppc.c:13181
+msgid "%P: %H: relocation %s for indirect function %s unsupported\n"
+msgstr "%P: %H: tái ịnh vị lại %s cho hàm gián tiếp %s không được hỗ trợ\n"
+
+#: elf32-ppc.c:7948 elf32-ppc.c:7978 elf32-ppc.c:8025
+msgid "%P: %B: the target (%s) of a %s relocation is in the wrong output section (%s)\n"
+msgstr "%P: %B: đích (%s) của một định vị lại %s nằm trong phần kết xuất không đúng (%s)\n"
+
+#: elf32-ppc.c:8097
+msgid "%P: %B: relocation %s is not yet supported for symbol %s\n"
+msgstr "%P: %B: tái định vị %s thì vẫn chưa được hỗ trợ cho ký hiệu %s\n"
+
+#: elf32-ppc.c:8158 elf64-ppc.c:13467
+msgid "%P: %H: unresolvable %s relocation against symbol `%s'\n"
+msgstr "%P: %H: không đáp ứng được tái định vị %s dựa vào ký hiệu `%s'\n"
+
+#: elf32-ppc.c:8205 elf64-ppc.c:13512
+msgid "%P: %H: %s reloc against `%s': error %d\n"
+msgstr "%P: %H: %s reloc lại `%s': lỗi %d\n"
+
+#: elf32-ppc.c:8696
+msgid "%P: %s not defined in linker created %s\n"
+msgstr "%P: %s chưa được định nghĩa trong bộ liên kết đã tạo ra %s\n"
+
+#: elf32-rx.c:563
+msgid "%B:%A: Warning: deprecated Red Hat reloc "
+msgstr "%B:%A: Cảnh báo: không tán thành reloc kiểu Red Hat"
+
+#. Check for unsafe relocs in PID mode. These are any relocs where
+#. an absolute address is being computed. There are special cases
+#. for relocs against symbols that are known to be referenced in
+#. crt0.o before the PID base address register has been initialised.
+#: elf32-rx.c:581
+msgid "%B(%A): unsafe PID relocation %s at 0x%08lx (against %s in %s)"
+msgstr "%B(%A): tái định vị PID không an toàn %s tại 0x%08lx (dựa vào %s trong %s)"
+
+#: elf32-rx.c:1157
+msgid "Warning: RX_SYM reloc with an unknown symbol"
+msgstr "Cảnh báo: RX_SYM reloc với một ký hiệu chưa được biết đến"
+
+#: elf32-rx.c:1324
+msgid "%B(%A): error: call to undefined function '%s'"
+msgstr "%B(%A): lá»—i: gá»i hàm chÆ°a được định nghÄ©a '%s'"
+
+#: elf32-rx.c:1338
+msgid "%B(%A): warning: unaligned access to symbol '%s' in the small data area"
+msgstr "%B(%A): cảnh báo: unaligned access to symbol '%s' trong vùng dữ liệu nhá»"
+
+#: elf32-rx.c:1342
+msgid "%B(%A): internal error: out of range error"
+msgstr "%B(%A): lỗi nội bộ: lỗi ngoại phạm vi"
+
+#: elf32-rx.c:1346
+msgid "%B(%A): internal error: unsupported relocation error"
+msgstr "%B(%A): lỗi nội bộ: lỗi định vị lại không được hỗ trợ"
+
+#: elf32-rx.c:1350
+msgid "%B(%A): internal error: dangerous relocation"
+msgstr "%B(%A): lỗi nội bộ: định vị lại nguy hiểm"
+
+#: elf32-rx.c:1354
+msgid "%B(%A): internal error: unknown error"
+msgstr "%B(%A): lỗi nội bộ: lỗi không rõ"
+
+#: elf32-rx.c:3004
+#, c-format
+msgid " [64-bit doubles]"
+msgstr " [64-bit kép]"
+
+#: elf32-rx.c:3006
+#, c-format
+msgid " [dsp]"
+msgstr " [dsp]"
+
+#: elf32-s390.c:2200 elf64-s390.c:2187
+msgid "%B(%A+0x%lx): invalid instruction for TLS relocation %s"
+msgstr "%B(%A+0x%lx): chỉ dẫn không hợp lệ cho định vị lại TLS %s"
+
+#: elf32-score.c:1520 elf32-score7.c:1379 elfxx-mips.c:3435
+msgid "not enough GOT space for local GOT entries"
+msgstr "không đủ sức chứa GOT cho các mục nhập GOT cục bộ"
+
+#: elf32-score.c:2742
+msgid "address not word align"
+msgstr "địa chỉ không sắp hàng từ"
+
+#: elf32-score.c:2827 elf32-score7.c:2631
+#, c-format
+msgid "%s: Malformed reloc detected for section %s"
+msgstr "%s: định vị lại dạng sai được phát hiện cho phần %s"
+
+#: elf32-score.c:2878 elf32-score7.c:2682
+msgid "%B: CALL15 reloc at 0x%lx not against global symbol"
+msgstr "%B: CALL15 định vị lại tại 0x%lx không phải so với ký hiệu toàn cục"
+
+#: elf32-score.c:3997 elf32-score7.c:3803
+#, c-format
+msgid " [pic]"
+msgstr " [ảnh]"
+
+#: elf32-score.c:4001 elf32-score7.c:3807
+#, c-format
+msgid " [fix dep]"
+msgstr " [sửa quan hệ phụ thuộc]"
+
+#: elf32-score.c:4043 elf32-score7.c:3849
+msgid "%B: warning: linking PIC files with non-PIC files"
+msgstr "%B: cảnh báo: đang liên kết tập tin PIC với tập tin khác PIC"
+
+#: elf32-sh-symbian.c:130
+msgid "%B: IMPORT AS directive for %s conceals previous IMPORT AS"
+msgstr "%B: chỉ thị IMPORT AS (nhập dạng) cho %s cũng ẩn chỉ thị IMPORT AS trước"
+
+#: elf32-sh-symbian.c:383
+msgid "%B: Unrecognised .directive command: %s"
+msgstr "%B: Không nhận ra câu lệnh .directive: %s"
+
+#: elf32-sh-symbian.c:504
+msgid "%B: Failed to add renamed symbol %s"
+msgstr "%B: Lỗi thêm ký hiệu đã đặt tên lại %s"
+
+#: elf32-sh.c:568
+msgid "%B: 0x%lx: warning: bad R_SH_USES offset"
+msgstr "%B: 0x%lx: cảnh báo: khoảng bù R_SH_USES sai"
+
+#: elf32-sh.c:580
+msgid "%B: 0x%lx: warning: R_SH_USES points to unrecognized insn 0x%x"
+msgstr "%B: 0x%lx: cảnh báo: R_SH_USES chỉ tới một chỉ dẫn không nhận ra 0x%x"
+
+#: elf32-sh.c:597
+msgid "%B: 0x%lx: warning: bad R_SH_USES load offset"
+msgstr "%B: 0x%lx: cảnh báo: khoảng bù nạp R_SH_USES sai"
+
+#: elf32-sh.c:612
+msgid "%B: 0x%lx: warning: could not find expected reloc"
+msgstr "%B: 0x%lx: cảnh báo: không tìm thấy định vị lại mong đợi"
+
+#: elf32-sh.c:640
+msgid "%B: 0x%lx: warning: symbol in unexpected section"
+msgstr "%B: 0x%lx: cảnh báo: ký hiệu nằm trong phần bất thÆ°á»ng"
+
+#: elf32-sh.c:766
+msgid "%B: 0x%lx: warning: could not find expected COUNT reloc"
+msgstr "%B: 0x%lx: cảnh báo: không tìm thấy định vị lại COUNT (đếm) mong đợi"
+
+#: elf32-sh.c:775
+msgid "%B: 0x%lx: warning: bad count"
+msgstr "%B: 0x%lx: cảnh báo: đếm sai"
+
+#: elf32-sh.c:1179 elf32-sh.c:1549
+msgid "%B: 0x%lx: fatal: reloc overflow while relaxing"
+msgstr "%B: 0x%lx: lỗi nặng: tràn định vị lại trong khi giảm nhẹ"
+
+#: elf32-sh.c:4048 elf64-sh64.c:1514
+msgid "Unexpected STO_SH5_ISA32 on local symbol is not handled"
+msgstr "Không xử lý được STO_SH5_ISA32 không mong đợi trên ký hiệu cục bộ"
+
+#: elf32-sh.c:4299
+msgid "%B: 0x%lx: fatal: unaligned branch target for relax-support relocation"
+msgstr "%B: 0x%lx: lỗi nặng: có đích nhánh chưa sắp hàng cho định vị lại hỗ trợ giảm nhẹ"
+
+#: elf32-sh.c:4332 elf32-sh.c:4347
+msgid "%B: 0x%lx: fatal: unaligned %s relocation 0x%lx"
+msgstr "%B: 0x%lx: lỗi nặng: định vị lại %s chưa sắp hàng 0x%lx"
+
+#: elf32-sh.c:4361
+msgid "%B: 0x%lx: fatal: R_SH_PSHA relocation %d not in range -32..32"
+msgstr "%B: 0x%lx: lỗi nặng: R_SH_PSHA định vị lại %d không nằm trong phạm vi -32..32"
+
+#: elf32-sh.c:4375
+msgid "%B: 0x%lx: fatal: R_SH_PSHL relocation %d not in range -32..32"
+msgstr "%B: 0x%lx: lỗi nặng: R_SH_PSHL định vị lại %d không nằm trong phạm vi -32..32"
+
+#: elf32-sh.c:4519 elf32-sh.c:4989
+msgid "%B(%A+0x%lx): cannot emit fixup to `%s' in read-only section"
+msgstr "%B(%A+0x%lx): không thể phát ra sá»± sá»­a chữa cho`%s' trong phần chỉ Ä‘á»c"
+
+#: elf32-sh.c:5096
+msgid "%B(%A+0x%lx): %s relocation against external symbol \"%s\""
+msgstr "%B(%A+0x%lx): tái định vị %s dựa trên ký hiệu bên ngoài \"%s\""
+
+#: elf32-sh.c:5569
+#, c-format
+msgid "%X%C: relocation to \"%s\" references a different segment\n"
+msgstr "%X%C: định vị lại \"%s\" tham chiếu đến một segment (đoạn) khác\n"
+
+#: elf32-sh.c:5575
+#, c-format
+msgid "%C: warning: relocation to \"%s\" references a different segment\n"
+msgstr "%C: cảnh báo: định vị lại \"%s\" tham chiếu đến một đoạn khác\n"
+
+#: elf32-sh.c:6353 elf32-sh.c:6436
+msgid "%B: `%s' accessed both as normal and FDPIC symbol"
+msgstr "%B: `%s' đã được truy cập theo cả hai kiểu bình thÆ°á»ng và ký hiệu FDPIC"
+
+#: elf32-sh.c:6358 elf32-sh.c:6440
+msgid "%B: `%s' accessed both as FDPIC and thread local symbol"
+msgstr "%B: \"%s\" đã được truy cập theo cả hai kiểu ký hiệu FDPIC và cục bộ cho tuyến trình"
+
+#: elf32-sh.c:6388
+msgid "%B: Function descriptor relocation with non-zero addend"
+msgstr "%B: Tái định vị bộ mô tả hàm với số hạng khác-không"
+
+#: elf32-sh.c:6624 elf64-alpha.c:4652
+msgid "%B: TLS local exec code cannot be linked into shared objects"
+msgstr "%B: mã thực hiện cục bộ TLS không thể được liên kết vào đối tượng chia sẻ"
+
+#: elf32-sh64.c:223 elf64-sh64.c:2318
+#, c-format
+msgid "%s: compiled as 32-bit object and %s is 64-bit"
+msgstr "%s: biên dịch như một đối tượng 32-bit và %s là 64-bit"
+
+#: elf32-sh64.c:226 elf64-sh64.c:2321
+#, c-format
+msgid "%s: compiled as 64-bit object and %s is 32-bit"
+msgstr "%s: biên dịch như một đối tượng 64-bit và %s là 32-bit"
+
+#: elf32-sh64.c:228 elf64-sh64.c:2323
+#, c-format
+msgid "%s: object size does not match that of target %s"
+msgstr "%s: kích cỡ đối tượng không tương ứng với kích cỡ của đích %s"
+
+#: elf32-sh64.c:451 elf64-sh64.c:2837
+#, c-format
+msgid "%s: encountered datalabel symbol in input"
+msgstr "%s: gặp ký hiệu nhãn dữ liệu trong dữ liệu nhập vào"
+
+#: elf32-sh64.c:528
+msgid "PTB mismatch: a SHmedia address (bit 0 == 1)"
+msgstr "Sai khớp PTB: một địa chỉ SHmedia (bit 0 == 1)"
+
+#: elf32-sh64.c:531
+msgid "PTA mismatch: a SHcompact address (bit 0 == 0)"
+msgstr "Sai khớp PTA: một địa chỉ SHcompact (bit 0 == 0)"
+
+#: elf32-sh64.c:549
+#, c-format
+msgid "%s: GAS error: unexpected PTB insn with R_SH_PT_16"
+msgstr "%s: Lá»—i GAS: chỉ dẫn PTB bất thÆ°á»ng vá»›i R_SH_PT_16"
+
+#: elf32-sh64.c:598
+msgid "%B: error: unaligned relocation type %d at %08x reloc %p\n"
+msgstr "%B: lỗi: kiểu định vị lại chưa sắp hàng %d tại %08x định vị lại %p\n"
+
+#: elf32-sh64.c:674
+#, c-format
+msgid "%s: could not write out added .cranges entries"
+msgstr "%s: không thể ghi ra các mục nhập .cranges đã thêm"
+
+#: elf32-sh64.c:734
+#, c-format
+msgid "%s: could not write out sorted .cranges entries"
+msgstr "%s: không thể ghi ra các mục nhập .cranges đã sắp xếp"
+
+#: elf32-sparc.c:90
+msgid "%B: compiled for a 64 bit system and target is 32 bit"
+msgstr "%B: được biên dịch cho hệ thống 64-bit, còn đích là 32-bit"
+
+#: elf32-sparc.c:103
+msgid "%B: linking little endian files with big endian files"
+msgstr "%B: đang liên kết tập tin vỠcuối nhỠvới tập tin vỠcuối lớn"
+
+#: elf32-spu.c:719
+msgid "%X%P: overlay section %A does not start on a cache line.\n"
+msgstr "%X%P: phần phủ %A không bắt đầu ở một dòng nhớ tạm.\n"
+
+#: elf32-spu.c:727
+msgid "%X%P: overlay section %A is larger than a cache line.\n"
+msgstr "%X%P: phần phủ %A lớn hơn một dòng nhớ tạm.\n"
+
+#: elf32-spu.c:747
+msgid "%X%P: overlay section %A is not in cache area.\n"
+msgstr "%X%P: phần phủ %A không phải trong vùng nhớ tạm.\n"
+
+#: elf32-spu.c:787
+msgid "%X%P: overlay sections %A and %A do not start at the same address.\n"
+msgstr "%X%P: hai phần phủ %A và %A không bắt đầu ở cùng một địa chỉ.\n"
+
+#: elf32-spu.c:1011
+msgid "warning: call to non-function symbol %s defined in %B"
+msgstr "cảnh báo: cuá»™c gá»i ký hiệu khác hàm %s được xác định trong %B"
+
+#: elf32-spu.c:1361
+msgid "%A:0x%v lrlive .brinfo (%u) differs from analysis (%u)\n"
+msgstr "%A:0x%v lrlive .brinfo (%u) khác với phân tích (%u)\n"
+
+#: elf32-spu.c:1880
+msgid "%B is not allowed to define %s"
+msgstr "không cho phép %B xác định %s"
+
+#: elf32-spu.c:1888
+#, c-format
+msgid "you are not allowed to define %s in a script"
+msgstr "không cho phép bạn xác định %s trong một văn lệnh"
+
+#: elf32-spu.c:1922
+#, c-format
+msgid "%s in overlay section"
+msgstr "%s trong phần phủ"
+
+#: elf32-spu.c:1951
+msgid "overlay stub relocation overflow"
+msgstr "tràn định vị lại mẩu phủ"
+
+#: elf32-spu.c:1960
+msgid "stubs don't match calculated size"
+msgstr "các mẩu không tương ứng với kích cỡ đã tính"
+
+#: elf32-spu.c:2542
+#, c-format
+msgid "warning: %s overlaps %s\n"
+msgstr "cảnh báo: %s đè lên %s\n"
+
+#: elf32-spu.c:2558
+#, c-format
+msgid "warning: %s exceeds section size\n"
+msgstr "cảnh báo: %s vượt quá kích cỡ phần\n"
+
+#: elf32-spu.c:2589
+msgid "%A:0x%v not found in function table\n"
+msgstr "%A:0x%v không tìm thấy trong bảng hàm\n"
+
+#: elf32-spu.c:2729
+msgid "%B(%A+0x%v): call to non-code section %B(%A), analysis incomplete\n"
+msgstr "%B(%A+0x%v): gá»i phần khác mã %B(%A), chÆ°a phân tích hoàn toàn\n"
+
+#: elf32-spu.c:3297
+#, c-format
+msgid "Stack analysis will ignore the call from %s to %s\n"
+msgstr "Tiến trình phân tích đống sẽ bá» qua cuá»™c gá»i từ %s cho %s\n"
+
+#: elf32-spu.c:3988
+msgid " %s: 0x%v\n"
+msgstr " %s: 0x%v\n"
+
+#: elf32-spu.c:3989
+msgid "%s: 0x%v 0x%v\n"
+msgstr "%s: 0x%v 0x%v\n"
+
+#: elf32-spu.c:3994
+msgid " calls:\n"
+msgstr " cuá»™c gá»i:\n"
+
+#: elf32-spu.c:4002
+#, c-format
+msgid " %s%s %s\n"
+msgstr " %s%s %s\n"
+
+#: elf32-spu.c:4307
+#, c-format
+msgid "%s duplicated in %s\n"
+msgstr "%s bị nhân đôi trong %s\n"
+
+#: elf32-spu.c:4311
+#, c-format
+msgid "%s duplicated\n"
+msgstr "%s bị nhân đôi\n"
+
+#: elf32-spu.c:4318
+msgid "sorry, no support for duplicate object files in auto-overlay script\n"
+msgstr "tiếc là văn lệnh tự động phủ không hỗ trợ tập tin đối tượng tăng đôi\n"
+
+#: elf32-spu.c:4359
+msgid "non-overlay size of 0x%v plus maximum overlay size of 0x%v exceeds local store\n"
+msgstr "kích cỡ khác phủ 0x%v cộng với kích cỡ phủ tối đa 0x%v thì vượt quá kho cục bộ\n"
+
+#: elf32-spu.c:4514
+msgid "%B:%A%s exceeds overlay size\n"
+msgstr "%B:%A%s vượt quá kích cỡ phủ\n"
+
+#: elf32-spu.c:4676
+msgid "Stack size for call graph root nodes.\n"
+msgstr "Kích cỡ đống cho các nút thông tin gốc đồ thị cuá»™c gá»i.\n"
+
+#: elf32-spu.c:4677
+msgid ""
+"\n"
+"Stack size for functions. Annotations: '*' max stack, 't' tail call\n"
+msgstr ""
+"\n"
+"Kích cỡ đống cho hàm, Ghi chú:\n"
+" *\tđống tối đa\n"
+" t\tcuá»™c gá»i Ä‘uôi\n"
+
+#: elf32-spu.c:4687
+msgid "Maximum stack required is 0x%v\n"
+msgstr "Äống tối Ä‘a cần thiết là 0x%v\n"
+
+#: elf32-spu.c:4778
+msgid "fatal error while creating .fixup"
+msgstr "gặp lá»—i nghiêm trá»ng trong khi tạo .fixup"
+
+#: elf32-spu.c:5008
+msgid "%B(%s+0x%lx): unresolvable %s relocation against symbol `%s'"
+msgstr "%B(%s+0x%lx): không thể giải quyết định vị lại %s so với ký hiệu \"%s\""
+
+#: elf32-tic6x.c:1602
+msgid "warning: generating a shared library containing non-PIC code"
+msgstr "cảnh báo: đang tạo thư viện liên kết động có chứa mã non-PIC"
+
+#: elf32-tic6x.c:1607
+msgid "warning: generating a shared library containing non-PID code"
+msgstr "cảnh báo: đang tạo thư viện liên kết động có chứa mã non-PID"
+
+#: elf32-tic6x.c:2541
+msgid "%B: SB-relative relocation but __c6xabi_DSBT_BASE not defined"
+msgstr "%B: tái định vị SB-liên-quan nhưng __c6xabi_DSBT_BASE lại chưa được định nghĩa"
+
+#: elf32-tic6x.c:2761
+msgid "dangerous relocation"
+msgstr "định vị lại nguy hiểm"
+
+#: elf32-tic6x.c:3733
+msgid "%B: error: unknown mandatory EABI object attribute %d"
+msgstr "%B: lỗi: không rõ thuộc tính đối tượng EABI %d"
+
+#: elf32-tic6x.c:3741
+msgid "%B: warning: unknown EABI object attribute %d"
+msgstr "%B: cảnh báo: không rõ thuộc tính đối tượng EABI %d"
+
+#: elf32-tic6x.c:3853 elf32-tic6x.c:3861
+msgid "error: %B requires more stack alignment than %B preserves"
+msgstr "lá»—i: %B yêu cầu stack sắp hàng nhiá»u hÆ¡n %B dá»± trữ"
+
+#: elf32-tic6x.c:3871 elf32-tic6x.c:3880
+msgid "error: unknown Tag_ABI_array_object_alignment value in %B"
+msgstr "lỗi: không hiểu giá trị Tag_ABI_array_object_alignment trong %B"
+
+#: elf32-tic6x.c:3889 elf32-tic6x.c:3898
+msgid "error: unknown Tag_ABI_array_object_align_expected value in %B"
+msgstr "lỗi: không hiểu giá trị Tag_ABI_array_object_align_expected trong %B"
+
+#: elf32-tic6x.c:3906 elf32-tic6x.c:3913
+msgid "error: %B requires more array alignment than %B preserves"
+msgstr "lá»—i: %B yêu cầu mảng sắp hàng nhiá»u hÆ¡n %B dá»± trữ"
+
+#: elf32-tic6x.c:3935
+msgid "warning: %B and %B differ in wchar_t size"
+msgstr "cảnh báo: %B và %B có kích thước wchar_t khác nhau"
+
+#: elf32-tic6x.c:3953
+msgid "warning: %B and %B differ in whether code is compiled for DSBT"
+msgstr "cảnh báo: %B và %B khác nhau ở chỗ mà mã được dịch cho DSBT"
+
+#: elf32-v850.c:173
+#, c-format
+msgid "Variable `%s' cannot occupy in multiple small data regions"
+msgstr "Biến \"%s\" không thể chiếm nhiá»u vùng dữ liệu nhá»"
+
+#: elf32-v850.c:176
+#, c-format
+msgid "Variable `%s' can only be in one of the small, zero, and tiny data regions"
+msgstr "Biến \"%s\" chỉ có thể nằm trong má»™t của vùng dữ liệu kiểu nhá», số không và rất nhá»"
+
+#: elf32-v850.c:179
+#, c-format
+msgid "Variable `%s' cannot be in both small and zero data regions simultaneously"
+msgstr "Biến \"%s\" không thể nằm đồng thá»i trong cả hai vùng dữ liệu kiểu nhá» và số không"
+
+#: elf32-v850.c:182
+#, c-format
+msgid "Variable `%s' cannot be in both small and tiny data regions simultaneously"
+msgstr "Biến \"%s\" không thể nằm đồng thá»i trong cả hai vùng dữ liệu kiểu nhá» và rất nhá»"
+
+#: elf32-v850.c:185
+#, c-format
+msgid "Variable `%s' cannot be in both zero and tiny data regions simultaneously"
+msgstr "Biến \"%s\" không thể nằm đồng thá»i trong cả hai vùng dữ liệu kiểu rất nhá» và số không"
+
+#: elf32-v850.c:483
+msgid "FAILED to find previous HI16 reloc"
+msgstr "LỖI tìm định vị lại HI16 trước"
+
+#: elf32-v850.c:2155
+msgid "could not locate special linker symbol __gp"
+msgstr "không tìm thấy ký hiệu liên kết đặc biệt __gp"
+
+#: elf32-v850.c:2159
+msgid "could not locate special linker symbol __ep"
+msgstr "không tìm thấy ký hiệu liên kết đặc biệt __ep"
+
+#: elf32-v850.c:2163
+msgid "could not locate special linker symbol __ctbp"
+msgstr "không tìm thấy ký hiệu liên kết đặc biệt __ctbp"
+
+#: elf32-v850.c:2341
+msgid "%B: Architecture mismatch with previous modules"
+msgstr "%B: sai khớp kiến trúc với mô-đun khác"
+
+#. xgettext:c-format.
+#: elf32-v850.c:2360
+#, c-format
+msgid "private flags = %lx: "
+msgstr "các cỠriêng — %lx: "
+
+#: elf32-v850.c:2365
+#, c-format
+msgid "v850 architecture"
+msgstr "Kiến trúc v850"
+
+#: elf32-v850.c:2366
+#, c-format
+msgid "v850e architecture"
+msgstr "Kiến trúc v850e"
+
+#: elf32-v850.c:2367
+#, c-format
+msgid "v850e1 architecture"
+msgstr "Kiến trúc v850e1"
+
+#: elf32-v850.c:2368
+#, c-format
+msgid "v850e2 architecture"
+msgstr "Kiến trúc v850e2"
+
+#: elf32-v850.c:2369
+#, c-format
+msgid "v850e2v3 architecture"
+msgstr "Kiến trúc v850e2v3"
+
+#: elf32-vax.c:532
+#, c-format
+msgid " [nonpic]"
+msgstr " [khác pic]"
+
+#: elf32-vax.c:535
+#, c-format
+msgid " [d-float]"
+msgstr " [trôi d]"
+
+#: elf32-vax.c:538
+#, c-format
+msgid " [g-float]"
+msgstr " [trôi g]"
+
+#: elf32-vax.c:655
+#, c-format
+msgid "%s: warning: GOT addend of %ld to `%s' does not match previous GOT addend of %ld"
+msgstr "%s: cảnh báo: số hạng GOT của %ld cho \"%s\" không tương ứng với số hạng GOT trước của %ld"
+
+#: elf32-vax.c:1585
+#, c-format
+msgid "%s: warning: PLT addend of %d to `%s' from %s section ignored"
+msgstr "%s: cảnh báo: số hạng PLT của %d cho \"%s\" từ phần %s bị bỠqua"
+
+#: elf32-vax.c:1712
+#, c-format
+msgid "%s: warning: %s relocation against symbol `%s' from %s section"
+msgstr "%s: cảnh báo: định vị lại %s so với ký hiệu \"%s\" từ phần %s"
+
+#: elf32-vax.c:1718
+#, c-format
+msgid "%s: warning: %s relocation to 0x%x from %s section"
+msgstr "%s: cảnh báo: định vị lại %s sang 0x%x từ phần %s"
+
+#: elf32-xstormy16.c:451 elf32-ia64.c:2336 elf64-ia64.c:2336
+msgid "non-zero addend in @fptr reloc"
+msgstr "số hạng khác không trong định vị lại @fptr"
+
+#: elf32-xtensa.c:918
+msgid "%B(%A): invalid property table"
+msgstr "%B(%A): bảng thuộc tính sai"
+
+#: elf32-xtensa.c:2777
+msgid "%B(%A+0x%lx): relocation offset out of range (size=0x%x)"
+msgstr "%B(%A+0x%lx): khoảng bù định vị lại ở ngoại phạm vi (kích cỡ=0x%x)"
+
+#: elf32-xtensa.c:2856 elf32-xtensa.c:2977
+msgid "dynamic relocation in read-only section"
+msgstr "định vị lại Ä‘á»™ng trong vùng chỉ Ä‘á»c"
+
+#: elf32-xtensa.c:2953
+msgid "TLS relocation invalid without dynamic sections"
+msgstr "Äịnh vị lại TLS không hợp lệ mà không có phần Ä‘á»™ng"
+
+#: elf32-xtensa.c:3172
+msgid "internal inconsistency in size of .got.loc section"
+msgstr "sự mâu thuẫn nội bộ trong kích cỡ của phần .got.loc"
+
+#: elf32-xtensa.c:3485
+msgid "%B: incompatible machine type. Output is 0x%x. Input is 0x%x"
+msgstr "%B: kiểu máy không tương thích. Kết xuất là 0x%x. Dữ liệu nhập vào là 0x%x."
+
+#: elf32-xtensa.c:4714 elf32-xtensa.c:4722
+msgid "Attempt to convert L32R/CALLX to CALL failed"
+msgstr "Lỗi thử chuyển đổi L32R/CALLX sang CALL"
+
+#: elf32-xtensa.c:6332 elf32-xtensa.c:6408 elf32-xtensa.c:7524
+msgid "%B(%A+0x%lx): could not decode instruction; possible configuration mismatch"
+msgstr "%B(%A+0x%lx): không thể giải mã chỉ dẫn; có thể sai khớp cấu hình"
+
+#: elf32-xtensa.c:7264
+msgid "%B(%A+0x%lx): could not decode instruction for XTENSA_ASM_SIMPLIFY relocation; possible configuration mismatch"
+msgstr "%B(%A+0x%lx): không thể giải mã chỉ dẫn cho định vị lại XTENSA_ASM_SIMPLIFY; có thể sai khớp cấu hình"
+
+#: elf32-xtensa.c:9023
+msgid "invalid relocation address"
+msgstr "địa chỉ định vị lại không hợp lệ"
+
+#: elf32-xtensa.c:9072
+msgid "overflow after relaxation"
+msgstr "tràn sau khi giảm nhẹ"
+
+#: elf32-xtensa.c:10204
+msgid "%B(%A+0x%lx): unexpected fix for %s relocation"
+msgstr "%B(%A+0x%lx): sá»­a chữa bất thÆ°á»ng cho định vị lại %s"
+
+#: elf64-alpha.c:460
+msgid "GPDISP relocation did not find ldah and lda instructions"
+msgstr "Äịnh vị lại GPDISP không tìm thấy các chỉ dẫn ldah và lda"
+
+#: elf64-alpha.c:2497
+msgid "%B: .got subsegment exceeds 64K (size %d)"
+msgstr "%B: đoạn phụ .got vượt quá 64 K (kích cỡ %d)"
+
+#: elf64-alpha.c:4387 elf64-alpha.c:4399
+msgid "%B: gp-relative relocation against dynamic symbol %s"
+msgstr "%B: định vị lại tương đối với gp (gp-relative) so với ký hiệu động %s"
+
+#: elf64-alpha.c:4425 elf64-alpha.c:4565
+msgid "%B: pc-relative relocation against dynamic symbol %s"
+msgstr "%B: định vị lại tương đối với pc (pc-relative) so với ký hiệu động %s"
+
+#: elf64-alpha.c:4453
+msgid "%B: change in gp: BRSGP %s"
+msgstr "%B: thay đổi trong gp: BRSGP %s"
+
+#: elf64-alpha.c:4478
+msgid "<unknown>"
+msgstr "<không rõ>"
+
+#: elf64-alpha.c:4483
+msgid "%B: !samegp reloc against symbol without .prologue: %s"
+msgstr "%B: định vị lại !samegp so với ký hiệu không có .prologue: %s"
+
+#: elf64-alpha.c:4540
+msgid "%B: unhandled dynamic relocation against %s"
+msgstr "%B: không xử lý được định vị lại động so với %s"
+
+#: elf64-alpha.c:4572
+msgid "%B: pc-relative relocation against undefined weak symbol %s"
+msgstr "%B: định vị lại tương đối với pc (pc-relative) so với ký hiệu yếu chưa được xác định %s"
+
+#: elf64-alpha.c:4636
+msgid "%B: dtp-relative relocation against dynamic symbol %s"
+msgstr "%B: định vị lại tương đối với dtp (dtp-relative) so với ký hiệu động %s"
+
+#: elf64-alpha.c:4659
+msgid "%B: tp-relative relocation against dynamic symbol %s"
+msgstr "%B: định vị lại tương đối với tp (tp-relative) so với ký hiệu động %s"
+
+#: elf64-hppa.c:2083
+#, c-format
+msgid "stub entry for %s cannot load .plt, dp offset = %ld"
+msgstr "mục nhập mẩu cho %s không thể nạp .plt, khoảng bù dp = %ld"
+
+#: elf64-hppa.c:3275
+msgid "%B(%A+0x"
+msgstr "%B(%A+0x"
+
+#: elf64-mmix.c:1034
+msgid ""
+"invalid input relocation when producing non-ELF, non-mmo format output.\n"
+" Please use the objcopy program to convert from ELF or mmo,\n"
+" or assemble using \"-no-expand\" (for gcc, \"-Wa,-no-expand\""
+msgstr ""
+"tái định vị kết xuất không hợp lệ khi sản sinh kết xuất định dạng non-ELF, non-mmo.\n"
+" Xin hãy sử dụng chương trình objcopy để chuyển từ ELF hoặc mmo,\n"
+" hoặc sử dụng assemble \"-no-expand\" (cho gcc, \"-Wa,-no-expand\""
+
+#: elf64-mmix.c:1218
+msgid ""
+"invalid input relocation when producing non-ELF, non-mmo format output.\n"
+" Please use the objcopy program to convert from ELF or mmo,\n"
+" or compile using the gcc-option \"-mno-base-addresses\"."
+msgstr ""
+"tái định vị kết xuất không hợp lệ khi sản sinh kết xuất định dạng non-ELF, non-mmo.\n"
+" Xin hãy sử dụng chương trình objcopy để chuyển từ ELF hoặc mmo,\n"
+" hoặc dịch sá»­ dụng tùy-chá»n-gcc \"-mno-base-addresses\"."
+
+#: elf64-mmix.c:1244
+#, c-format
+msgid ""
+"%s: Internal inconsistency error for value for\n"
+" linker-allocated global register: linked: 0x%lx%08lx != relaxed: 0x%lx%08lx\n"
+msgstr ""
+"%s: Gặp lỗi mâu thuẫn nội bộ cho giá trị của thanh ghi toàn cục\n"
+"cấp phát cho bộ liên kết:\n"
+"đã liên kết: 0x%lx%08lx != đã giảm nhẹ: 0x%lx%08lx\n"
+
+#: elf64-mmix.c:1670
+#, c-format
+msgid "%s: base-plus-offset relocation against register symbol: (unknown) in %s"
+msgstr "%s: định vị lại base-plus-offset so với ký hiệu thanh ghi: (không rõ) trong %s"
+
+#: elf64-mmix.c:1675
+#, c-format
+msgid "%s: base-plus-offset relocation against register symbol: %s in %s"
+msgstr "%s: định vị lại base-plus-offset so với ký hiệu thanh ghi: %s trong %s"
+
+#: elf64-mmix.c:1719
+#, c-format
+msgid "%s: register relocation against non-register symbol: (unknown) in %s"
+msgstr "%s: định vị lại thanh ghi so với ký hiệu khác thanh ghi: (không rõ) trong %s"
+
+#: elf64-mmix.c:1724
+#, c-format
+msgid "%s: register relocation against non-register symbol: %s in %s"
+msgstr "%s: định vị lại thanh ghi so với ký hiệu khác thanh ghi: %s trong %s"
+
+#: elf64-mmix.c:1761
+#, c-format
+msgid "%s: directive LOCAL valid only with a register or absolute value"
+msgstr "%s: chỉ thị LOCAL (cục bộ) hợp lệ chỉ với một thanh ghi hoặc giá trị tuyệt đối"
+
+#: elf64-mmix.c:1789
+#, c-format
+msgid "%s: LOCAL directive: Register $%ld is not a local register. First global register is $%ld."
+msgstr ""
+"%s: chỉ thị LOCAL (cục bộ): Thanh ghi $%ld không phải là một thanh ghi cục bộ.\n"
+"Thanh ghi toàn cục thứ nhất là $%ld."
+
+#: elf64-mmix.c:2253
+#, c-format
+msgid "%s: Error: multiple definition of `%s'; start of %s is set in a earlier linked file\n"
+msgstr ""
+"%s: Lá»—i: định nghÄ©a nhiá»u lần \"%s\"; đầu của %s được đặt\n"
+"trong một tập tin đã liên kết sớm hơn\n"
+
+#: elf64-mmix.c:2311
+msgid "Register section has contents\n"
+msgstr "Phần thanh ghi có nội dung\n"
+
+#: elf64-mmix.c:2503
+#, c-format
+msgid ""
+"Internal inconsistency: remaining %u != max %u.\n"
+" Please report this bug."
+msgstr ""
+"Sự mâu thuẫn nội bộ: còn lại %u != tối đa %u.\n"
+" Hãy thông báo lỗi này."
+
+#: elf64-ppc.c:4185
+msgid "%P: %B: cannot create stub entry %s\n"
+msgstr "%P: %B: không thể tạo mục gốc %s\n"
+
+#: elf64-ppc.c:6518
+msgid "%P: copy reloc against `%s' requires lazy plt linking; avoid setting LD_BIND_NOW=1 or upgrade gcc\n"
+msgstr "%P: sao chép reloc (định vị lại) \"%s\" thì cần thiết chức năng liên kết plt uể oải; hãy tránh đặt LD_BIND_NOW=1, hoặc nâng cấp GCC\n"
+
+#: elf64-ppc.c:6788
+msgid "%B: undefined symbol on R_PPC64_TOCSAVE relocation"
+msgstr "%B: ký hiệu chưa định nghĩa trong tái định vị R_PPC64_TOCSAVE"
+
+#: elf64-ppc.c:6992
+msgid "%P: dynreloc miscount for %B, section %A\n"
+msgstr "%P: dynreloc (cấp phát động) tính sai %B, phần %A\n"
+
+#: elf64-ppc.c:7076
+msgid "%B: .opd is not a regular array of opd entries"
+msgstr "%B: .opd không phải là một mảng chính quy các mục nhập opd"
+
+#: elf64-ppc.c:7085
+msgid "%B: unexpected reloc type %u in .opd section"
+msgstr "%B: gặp kiểu định vị lại bất thÆ°á»ng %u trong phần .opd"
+
+#: elf64-ppc.c:7106
+msgid "%B: undefined sym `%s' in .opd section"
+msgstr "%B: gặp sym (liên kết má»m?) chÆ°a được xác định \"%s\" trong phần .opd"
+
+#: elf64-ppc.c:7664
+msgid "%H __tls_get_addr lost arg, TLS optimization disabled\n"
+msgstr "%H __tls_get_addr mất đối số, tối ưu hóa TLS bị tắt\n"
+
+#: elf64-ppc.c:8003 elf64-ppc.c:8564
+#, c-format
+msgid "%s defined on removed toc entry"
+msgstr "%s đã định nghÄ©a trên mục của mục lục đã bị gỡ bá»"
+
+#: elf64-ppc.c:8521
+msgid "%P: %H: %s relocation references optimized away TOC entry\n"
+msgstr "%P: %H: %s tái định vị tham chiếu tối ưu hóa theo mục TOC\n"
+
+#: elf64-ppc.c:9598
+msgid "%P: cannot find opd entry toc for %s\n"
+msgstr "%P: không tìm thấy mục opd toc(mục lục) cho %s\n"
+
+#: elf64-ppc.c:9680
+msgid "%P: long branch stub `%s' offset overflow\n"
+msgstr "%P: mẩu nhánh dài \"%s\" tràn khoảng bù\n"
+
+#: elf64-ppc.c:9739
+msgid "%P: can't find branch stub `%s'\n"
+msgstr "%P: không tìm thấy nhánh gốc `%s'\n"
+
+#: elf64-ppc.c:9801 elf64-ppc.c:9943
+msgid "%P: linkage table error against `%s'\n"
+msgstr "%P: bảng liên kết lại sai `%s'\n"
+
+#: elf64-ppc.c:10126
+msgid "%P: can't build branch stub `%s'\n"
+msgstr "%P: không thể xây dựng nhánh gốc `%s'\n"
+
+#: elf64-ppc.c:10941
+msgid "%B section %A exceeds stub group size"
+msgstr "%B phần %A vượt quá kích cỡ nhóm mẩu"
+
+#: elf64-ppc.c:11666 elf64-ppc.c:11699
+msgid "%P: %s offset too large for .eh_frame sdata4 encoding"
+msgstr "%P: %s giá trị bù quá lớn cho mã hóa '.eh_frame sdata4'"
+
+#: elf64-ppc.c:11744
+msgid "%P: stubs don't match calculated size\n"
+msgstr "%P: các mẩu (stubs) không tương ứng với kích cỡ đã tính\n"
+
+#: elf64-ppc.c:11756
+#, c-format
+msgid ""
+"linker stubs in %u group%s\n"
+" branch %lu\n"
+" toc adjust %lu\n"
+" long branch %lu\n"
+" long toc adj %lu\n"
+" plt call %lu"
+msgstr ""
+"các mẩu liên kết trong nhóm %u%s\n"
+" nhánh\t\t\t\t%lu\n"
+" Ä‘iá»u chỉnh toc\t\t%lu\n"
+" nhánh dài\t\t\t%lu\n"
+" Ä‘iá»u chỉnh toc dài\t\t%lu\n"
+" cuá»™c gá»i pit\t\t\t%lu"
+
+#: elf64-ppc.c:12042
+msgid "%P: %H: %s used with TLS symbol %s\n"
+msgstr "%P: %H: %s được sử dụng với ký hiệu TLS %s\n"
+
+#: elf64-ppc.c:12043
+msgid "%P: %H: %s used with non-TLS symbol %s\n"
+msgstr "%P: %H: %s được sử dụng với ký hiệu không-phải-TLS %s\n"
+
+#: elf64-ppc.c:12556
+msgid "%P: %H: automatic multiple TOCs not supported using your crt files; recompile with -mminimal-toc or upgrade gcc\n"
+msgstr "%P: %H: tá»± Ä‘á»™ng tạo nhiá»u TOC không được há»— trợ khi dùng các tập tin CRT của bạn; hãy biên dịch lại vá»›i \"-mminimal-toc\", hoặc nâng cấp GCC\n"
+
+#: elf64-ppc.c:12562
+msgid "%P: %H: sibling call optimization to `%s' does not allow automatic multiple TOCs; recompile with -mminimal-toc or -fno-optimize-sibling-calls, or make `%s' extern\n"
+msgstr "%P: %H: tối Æ°u hoá cuá»™c gá»i cùng chá»— (sibling) cho \"%s\" không cho phép tá»± Ä‘á»™ng tạo nhiá»u TOC; hãy biên dịch lại vá»›i \"-mminimal-toc\" hoặc \"-fno-optimize-sibling-calls\", hoặc làm cho \"%s\" bên ngoài\n"
+
+#: elf64-ppc.c:13286
+msgid "%P: %B: relocation %s is not supported for symbol %s\n"
+msgstr "%P: %B: tái định vị %s không được hỗ trợ cho ký hiệu %s\n"
+
+#: elf64-ppc.c:13446
+msgid "%P: %H: error: %s not a multiple of %u\n"
+msgstr "%P: %H: lỗi: %s không phải là bội số của %u\n"
+
+#: elf64-sh64.c:1686
+#, c-format
+msgid "%s: error: unaligned relocation type %d at %08x reloc %08x\n"
+msgstr "%s: lỗi: kiểu định vị lại chưa sắp hàng %d ở %08x định vị lại %08x\n"
+
+#: elf64-sparc.c:446
+msgid "%B: Only registers %%g[2367] can be declared using STT_REGISTER"
+msgstr "%B: Chỉ các thanh ghi %%g[2367] có thể được tuyên bố dùng STT_REGISTER"
+
+#: elf64-sparc.c:466
+msgid "Register %%g%d used incompatibly: %s in %B, previously %s in %B"
+msgstr "Thanh ghi %%g%d được dùng một cách không tương thích: %s trong %B, trước là %s trong %b"
+
+#: elf64-sparc.c:489
+msgid "Symbol `%s' has differing types: REGISTER in %B, previously %s in %B"
+msgstr "Ký hiệu \"%s\" có các kiểu khác hau: REGISTER (thanh ghi) trong %B, trước là %s trong %B"
+
+#: elf64-sparc.c:534
+msgid "Symbol `%s' has differing types: %s in %B, previously REGISTER in %B"
+msgstr "Ký hiệu \"%s\" có các kiểu khác hau: %s trong %b, trước là REGISTER (thanh ghi) trong %B"
+
+#: elf64-sparc.c:687
+msgid "%B: linking UltraSPARC specific with HAL specific code"
+msgstr "%B: đang liên kết UltraSPARC dứt khoát với mã đặc trưng cho HAL"
+
+#: elf64-x86-64.c:1427
+msgid "%B: relocation %s against symbol `%s' isn't supported in x32 mode"
+msgstr "%B: sự định vị lại %s dựa vào ký hiệu \"%s\" không được hỗ trợ trong chế độ x32"
+
+#: elf64-x86-64.c:1656
+msgid "%B: '%s' accessed both as normal and thread local symbol"
+msgstr "%B; \"%s\" được truy cập nhÆ° là ký hiệu cả hai kiểu bình thÆ°á»ng và mạch cục bá»™"
+
+#: elf64-x86-64.c:3150
+msgid "%B: relocation %s against STT_GNU_IFUNC symbol `%s' has non-zero addend: %d"
+msgstr "%B: sự định vị lại %s đối với ký hiệu STT_GNU_IFUNC \"%s\" có phần cộng khác số không: %d"
+
+#: elf64-x86-64.c:3411
+msgid "%B: relocation R_X86_64_GOTOFF64 against protected function `%s' can not be used when making a shared object"
+msgstr "%B: định vị lại R_X86_64_GOTOFF64 so với hàm đã bảo vệ \"%s\" thì không thể được dùng khi tạo một đối tượng chia sẻ"
+
+#: elf64-x86-64.c:3523
+msgid "; recompile with -fPIC"
+msgstr "; biên dịch lại với \"-fPIC\""
+
+#: elf64-x86-64.c:3528
+msgid "%B: relocation %s against %s `%s' can not be used when making a shared object%s"
+msgstr "%B: không dùng được định vị lại %s đối với %s \"%s\" khi tạo một đối tượng chia sẻ %s"
+
+#: elf64-x86-64.c:3530
+msgid "%B: relocation %s against undefined %s `%s' can not be used when making a shared object%s"
+msgstr "%B: không dùng được định vị lại %s đối với %s chưa xác định \"%s\" khi tạo một đối tượng chia sẻ %s"
+
+#: elfcode.h:767
+#, c-format
+msgid "warning: %s has a corrupt string table index - ignoring"
+msgstr "cảnh báo: %s có má»™t chỉ mục bảng chuá»—i bị há»ng: nên bá» qua"
+
+#: elfcode.h:1177
+#, c-format
+msgid "%s: version count (%ld) does not match symbol count (%ld)"
+msgstr "%s: số đếm phiên bản (%ld) không tương ứng với số đếm ký hiệu (%ld)"
+
+#: elfcode.h:1431
+#, c-format
+msgid "%s(%s): relocation %d has invalid symbol index %ld"
+msgstr "%s(%s): định vị lại %d có chỉ mục ký hiệu không hợp lệ %ld"
+
+#: elfcore.h:312
+msgid "Warning: %B is truncated: expected core file size >= %lu, found: %lu."
+msgstr "Cảnh báo: %B bị cắt ngắn: kích cỡ tập tin lõi mong đợi ≥%lu còn tìm %lu."
+
+#: elflink.c:1117
+msgid "%s: TLS definition in %B section %A mismatches non-TLS definition in %B section %A"
+msgstr "%s: lá»i định nghÄ©a TLS trong %B phần %A không tÆ°Æ¡ng ứng vá»›i lá»i định nghÄ©a TLS trong %B phần %A"
+
+#: elflink.c:1121
+msgid "%s: TLS reference in %B mismatches non-TLS reference in %B"
+msgstr "%s: lá»i định nghÄ©a TLS trong %B không tÆ°Æ¡ng ứng vá»›i lá»i định nghÄ©a khác TLS trong %B"
+
+#: elflink.c:1125
+msgid "%s: TLS definition in %B section %A mismatches non-TLS reference in %B"
+msgstr "%s: lá»i định nghÄ©a TLS trong %B phần %A không tÆ°Æ¡ng ứng vá»›i lá»i định nghÄ©a khác TLS trong %B"
+
+#: elflink.c:1129
+msgid "%s: TLS reference in %B mismatches non-TLS definition in %B section %A"
+msgstr "%s: lá»i định nghÄ©a TLS trong %B không tÆ°Æ¡ng ứng vá»›i lá»i định nghÄ©a khác TLS trong %B phần %A"
+
+#: elflink.c:1762
+msgid "%B: unexpected redefinition of indirect versioned symbol `%s'"
+msgstr "%B: gặp lá»i định nghÄ©a lại bất thÆ°á»ng của ký hiệu gián tiếp đặt phiên bản \"%s\""
+
+#: elflink.c:2063
+msgid "%B: version node not found for symbol %s"
+msgstr "%B: không tìm thấy nút thông tin phiên bản cho ký hiệu %s"
+
+#: elflink.c:2154
+msgid "%B: bad reloc symbol index (0x%lx >= 0x%lx) for offset 0x%lx in section `%A'"
+msgstr "%B: chỉ mục ký hiệu định vị lại sai (0x%lx ≥ 0x%lx) cho khoảng bù 0x%lx trong phần \"%A\""
+
+#: elflink.c:2165
+msgid "%B: non-zero symbol index (0x%lx) for offset 0x%lx in section `%A' when the object file has no symbol table"
+msgstr "%B: chỉ mục ký hiệu khác số không (0x%lx) cho hiệu 0x%lx trong phần \"%A\" mà tập tin đối tượng không có bảng ký hiệu"
+
+#: elflink.c:2355
+msgid "%B: relocation size mismatch in %B section %A"
+msgstr "%B: sai khớp kích cỡ định vị lại trong %B phần %A"
+
+#: elflink.c:2639
+#, c-format
+msgid "warning: type and size of dynamic symbol `%s' are not defined"
+msgstr "cảnh báo: chưa xác định kiểu và kích cỡ của ký hiệu động \"%s\""
+
+#: elflink.c:3391
+msgid "%P: alternate ELF machine code found (%d) in %B, expecting %d\n"
+msgstr "%P: mã máy ELF luân phiên được tìm (%d) trong %B, còn mong đợi %d\n"
+
+#: elflink.c:4037
+msgid "%B: %s: invalid version %u (max %d)"
+msgstr "%B: %s: phiên bản không hợp lệ %u (tối đa %d)"
+
+#: elflink.c:4073
+msgid "%B: %s: invalid needed version %d"
+msgstr "%B: %s: phiên bản cần thiết mà không hợp lệ %d"
+
+#: elflink.c:4269
+msgid "Warning: alignment %u of common symbol `%s' in %B is greater than the alignment (%u) of its section %A"
+msgstr "Cảnh báo: vị trí sắp hàng %u của ký hiệu dùng chung \"%s\" trong %B là lớn hơn vị trí sắp hàng (%u) của phần %A của nó"
+
+#: elflink.c:4275
+msgid "Warning: alignment %u of symbol `%s' in %B is smaller than %u in %B"
+msgstr "Cảnh báo: vị trí sắp hàng %u của ký hiệu \"%s\" trong %B là nhỠhơn %u trong %B"
+
+#: elflink.c:4290
+msgid "Warning: size of symbol `%s' changed from %lu in %B to %lu in %B"
+msgstr "Cảnh báo: kích cỡ của ký hiệu \"%s\" đã thay đổi từ %lu trong %B thành %lu trong %B"
+
+#: elflink.c:4463
+msgid "%B: undefined reference to symbol '%s'"
+msgstr "%B: chưa định nghĩa tham chiếu đến ký hiệu '%s'"
+
+#: elflink.c:4466
+msgid "note: '%s' is defined in DSO %B so try adding it to the linker command line"
+msgstr "chú ý: '%s' được định nghĩa trong DSO %B do đó hãy thử thêm nó vào trong dòng lệnh của bộ liên kết"
+
+#: elflink.c:5781
+#, c-format
+msgid "%s: undefined version: %s"
+msgstr "%s: phiên bản chưa được xác định: %s"
+
+#: elflink.c:5849
+msgid "%B: .preinit_array section is not allowed in DSO"
+msgstr "%B: không cho phép phần \".preinit_array\" trong DSO"
+
+#: elflink.c:7604
+#, c-format
+msgid "undefined %s reference in complex symbol: %s"
+msgstr "gặp tham chiếu %s chưa được xác định trong ký hiệu phức tạp %s"
+
+#: elflink.c:7758
+#, c-format
+msgid "unknown operator '%c' in complex symbol"
+msgstr "không rõ toán tử \"%c\" trong ký hiệu phức tạp"
+
+#: elflink.c:8097 elflink.c:8114 elflink.c:8151 elflink.c:8168
+msgid "%B: Unable to sort relocs - they are in more than one size"
+msgstr "%B: Không thể sắp xếp các sự định vị lại: chúng có kích cỡ khác nhau"
+
+#: elflink.c:8128 elflink.c:8182
+msgid "%B: Unable to sort relocs - they are of an unknown size"
+msgstr "%B: Không thể sắp xếp các sự định vị lại: chúng có kích cỡ không rõ"
+
+#: elflink.c:8233
+msgid "Not enough memory to sort relocations"
+msgstr "Không đủ bộ nhớ để sắp xếp các sự định vị lại"
+
+#: elflink.c:8426
+msgid "%B: Too many sections: %d (>= %d)"
+msgstr "%B: Quá nhiá»u phần: %d (≥ %d)"
+
+#: elflink.c:8675
+msgid "%B: internal symbol `%s' in %B is referenced by DSO"
+msgstr "%B: ký hiệu nội tại \"%s\" trong %B được DSO tham chiếu"
+
+#: elflink.c:8677
+msgid "%B: hidden symbol `%s' in %B is referenced by DSO"
+msgstr "%B: ký hiệu ẩn `%s' trong %B được DSO tham chiếu"
+
+#: elflink.c:8679
+msgid "%B: local symbol `%s' in %B is referenced by DSO"
+msgstr "%B: ký hiệu nội bộ `%s' trong %B được tham chiếu bởi DSO"
+
+#: elflink.c:8776
+msgid "%B: could not find output section %A for input section %A"
+msgstr "%B: không thể tìm thấy phần kết xuất %A cho phần dữ liệu nhập vào %A"
+
+#: elflink.c:8899
+msgid "%B: protected symbol `%s' isn't defined"
+msgstr "%B: ký hiệu được bảo vệ `%s' chưa được định nghĩa"
+
+#: elflink.c:8901
+msgid "%B: internal symbol `%s' isn't defined"
+msgstr "%B: ký hiệu nội tại `%s' chưa được định nghĩa"
+
+#: elflink.c:8903
+msgid "%B: hidden symbol `%s' isn't defined"
+msgstr "%B: ký hiệu ẩn `%s' chưa được định nghĩa"
+
+#: elflink.c:9432
+msgid "error: %B: size of section %A is not multiple of address size"
+msgstr "lỗi: %B: kích thước của phần %A không phải là bội số của kích thước địa chỉ"
+
+#: elflink.c:9479
+msgid "error: %B contains a reloc (0x%s) for section %A that references a non-existent global symbol"
+msgstr "lỗi: %B chứa một định vị lại (0x%s) cho phần %A mà tham chiếu đến một ký hiệu toàn cục không tồn tại"
+
+#: elflink.c:10214
+msgid "%A has both ordered [`%A' in %B] and unordered [`%A' in %B] sections"
+msgstr "%A có phần cả hai được sắp xếp [\"%A\" trong %B] và chưa sắp xếp [\"%A\" trong %B]"
+
+#: elflink.c:10219
+#, c-format
+msgid "%A has both ordered and unordered sections"
+msgstr "%A có phần cả hai được sắp xếp và chưa sắp xếp"
+
+#: elflink.c:10784
+msgid "%B: file class %s incompatible with %s"
+msgstr "%B: lớp tập tin %s không tương thích với %s"
+
+#: elflink.c:11093 elflink.c:11137
+msgid "%B: could not find output section %s"
+msgstr "%B: không tìm thấy phần kết xuất %s"
+
+#: elflink.c:11098
+#, c-format
+msgid "warning: %s section has zero size"
+msgstr "cảnh báo: phần %s có kích cỡ số không"
+
+#: elflink.c:11143
+#, c-format
+msgid "warning: section '%s' is being made into a note"
+msgstr "cảnh báo: phần \"%s\" bị làm thành một ghi chú"
+
+#: elflink.c:11212
+msgid "%P%X: read-only segment has dynamic relocations.\n"
+msgstr "%P%X: Ä‘oạn chỉ cho Ä‘á»c có tái định vị Ä‘á»™ng.\n"
+
+#: elflink.c:11215
+msgid "%P: warning: creating a DT_TEXTREL in a shared object.\n"
+msgstr "%P: cảnh báo: đang tạo một DT_TEXTREL trong một đối tượng chia sẻ.\n"
+
+#: elflink.c:11402
+msgid "%P%X: can not read symbols: %E\n"
+msgstr "%P%X: không thể Ä‘á»c các ký hiệu: %E\n"
+
+#: elflink.c:11792
+msgid "Removing unused section '%s' in file '%B'"
+msgstr "Äang gỡ bá» phần không dùng \"%s\" trong tập tin \"%B\""
+
+#: elflink.c:11998
+msgid "Warning: gc-sections option ignored"
+msgstr "Cảnh báo: tùy chá»n gc-sections bị bá» qua"
+
+#: elflink.c:12277
+#, c-format
+msgid "Unrecognized INPUT_SECTION_FLAG %s\n"
+msgstr "Không thừa nhận INPUT_SECTION_FLAG %s\n"
+
+#: elfxx-mips.c:1234
+msgid "static procedure (no name)"
+msgstr "thủ tục tĩnh (không có tên)"
+
+#: elfxx-mips.c:5259
+msgid "MIPS16 and microMIPS functions cannot call each other"
+msgstr "hàm MIPS16 và microMIPS không được gợi lẫn nhau"
+
+#: elfxx-mips.c:5856
+msgid "%B: %A+0x%lx: Direct jumps between ISA modes are not allowed; consider recompiling with interlinking enabled."
+msgstr "%B: %A+0x%lx: Nhảy trực tiếp giữa các chế độ ISA là không được phép; cân nhắc việc dịch lại với liên kết móc nối được bật."
+
+#: elfxx-mips.c:6519 elfxx-mips.c:6742
+msgid "%B: Warning: bad `%s' option size %u smaller than its header"
+msgstr "%B: Cảnh báo: kích cỡ tùy chá»n \"%s\" sai: nhá» hÆ¡n phần đầu của nó"
+
+#: elfxx-mips.c:7495 elfxx-mips.c:7620
+msgid "%B: Warning: cannot determine the target function for stub section `%s'"
+msgstr "%B: cảnh báo: không thể quyết định hàm đích cho phần mẩu \"%s\""
+
+#: elfxx-mips.c:7749
+msgid "%B: Malformed reloc detected for section %s"
+msgstr "%B: Phát hiện sự định vị lại dạng sai cho phần %s"
+
+#: elfxx-mips.c:7801
+msgid "%B: GOT reloc at 0x%lx not expected in executables"
+msgstr "%B: định vị lại GOT ở 0x%lx không mong đợi trong tập tin có khả năng thực hiện"
+
+#: elfxx-mips.c:7930
+msgid "%B: CALL16 reloc at 0x%lx not against global symbol"
+msgstr "%B: định vị lại CALL16 ở 0x%lx không phải so với ký hiệu toàn cục"
+
+#: elfxx-mips.c:8645
+#, c-format
+msgid "non-dynamic relocations refer to dynamic symbol %s"
+msgstr "định vị lại khác động cũng tham chiếu đến ký hiệu động %s"
+
+#: elfxx-mips.c:9347
+msgid "%B: Can't find matching LO16 reloc against `%s' for %s at 0x%lx in section `%A'"
+msgstr "%B: Không tìm thấy định vị lại LO16 tương ứng so với \"%s\" cho %s ở 0x%lx trong phần \"%A\""
+
+#: elfxx-mips.c:9486
+msgid "small-data section exceeds 64KB; lower small-data size limit (see option -G)"
+msgstr "Phần small-data (dữ liệu nhá») vượt quá 64 KB; hãy giảm giá»›i hạn dữ liệu nhá» (xem tùy chá»n \"-G\")"
+
+#: elfxx-mips.c:9505
+msgid "JALX to a non-word-aligned address"
+msgstr "JALX cho địa chỉ 'non-word-aligned'"
+
+#: elfxx-mips.c:13266
+#, c-format
+msgid "%s: illegal section name `%s'"
+msgstr "%s: tên phần cấm \"%s\""
+
+#: elfxx-mips.c:13645 elfxx-mips.c:13671
+msgid "Warning: %B uses -msingle-float, %B uses -mdouble-float"
+msgstr "Cảnh báo: %B dùng \"-msingle-float\", còn %B dùng \"-mdouble-float\""
+
+#: elfxx-mips.c:13657 elfxx-mips.c:13713
+msgid "Warning: %B uses -msingle-float, %B uses -mips32r2 -mfp64"
+msgstr "Cảnh báo: %B dùng \"-msingle-float\", còn %B dùng \"-mips32r2 -mfp64\""
+
+#: elfxx-mips.c:13683 elfxx-mips.c:13719
+msgid "Warning: %B uses -mdouble-float, %B uses -mips32r2 -mfp64"
+msgstr "Cảnh báo: %B dùng \"-mdouble-float\", còn %B dùng \"-mips32r2 -mfp64\""
+
+#: elfxx-mips.c:13761
+msgid "%B: endianness incompatible with that of the selected emulation"
+msgstr "%B: tình trạng vá» cuối không tÆ°Æ¡ng thích vá»›i cái của bản mô phá»ng đã chá»n"
+
+#: elfxx-mips.c:13772
+msgid "%B: ABI is incompatible with that of the selected emulation"
+msgstr "%B: ABI không tÆ°Æ¡ng thích vá»›i cái của bản mô phá»ng đã chá»n"
+
+#: elfxx-mips.c:13856
+msgid "%B: warning: linking abicalls files with non-abicalls files"
+msgstr "%B: cảnh báo: đang liên kết tập tin abicalls với tập tin khác abicalls"
+
+#: elfxx-mips.c:13873
+msgid "%B: linking 32-bit code with 64-bit code"
+msgstr "%B: đang liên kết mã 32-bit với mã 64-bit"
+
+#: elfxx-mips.c:13901
+msgid "%B: linking %s module with previous %s modules"
+msgstr "%B: đang liên kết mô-đun %s với các mô-đun %s trước"
+
+#: elfxx-mips.c:13924
+msgid "%B: ABI mismatch: linking %s module with previous %s modules"
+msgstr "%B: sai khớp ABI: đang liên kết mô-đun %s với các mô-đun %s trước"
+
+#: elfxx-mips.c:13948
+msgid "%B: ASE mismatch: linking %s module with previous %s modules"
+msgstr "%B: ASE không khớp: liên kết %s mô-đun với mô-đun %s trước đó"
+
+#: elfxx-mips.c:14106
+#, c-format
+msgid " [abi=O32]"
+msgstr " [abi=O32]"
+
+#: elfxx-mips.c:14108
+#, c-format
+msgid " [abi=O64]"
+msgstr " [abi=O64]"
+
+#: elfxx-mips.c:14110
+#, c-format
+msgid " [abi=EABI32]"
+msgstr " [abi=EABI32]"
+
+#: elfxx-mips.c:14112
+#, c-format
+msgid " [abi=EABI64]"
+msgstr " [abi=EABI64]"
+
+#: elfxx-mips.c:14114
+#, c-format
+msgid " [abi unknown]"
+msgstr " [abi không rõ]"
+
+#: elfxx-mips.c:14116
+#, c-format
+msgid " [abi=N32]"
+msgstr " [abi=N32]"
+
+#: elfxx-mips.c:14118
+#, c-format
+msgid " [abi=64]"
+msgstr " [abi=64]"
+
+#: elfxx-mips.c:14120
+#, c-format
+msgid " [no abi set]"
+msgstr " [chưa đặt abi]"
+
+#: elfxx-mips.c:14141
+#, c-format
+msgid " [unknown ISA]"
+msgstr " [không rõ ISA]"
+
+#: elfxx-mips.c:14155
+#, c-format
+msgid " [not 32bitmode]"
+msgstr " [không phải 32bitmode]"
+
+#: elfxx-sparc.c:596
+#, c-format
+msgid "invalid relocation type %d"
+msgstr "kiểu định vị lại không hợp lệ %d"
+
+#: elfxx-tilegx.c:3952
+msgid "%B: Cannot link together %s and %s objects."
+msgstr "%B: Không thể liên kết hai đối tượng %s và %s với nhau."
+
+#: i386linux.c:451 m68klinux.c:456 sparclinux.c:450
+#, c-format
+msgid "Output file requires shared library `%s'\n"
+msgstr "Tập tin kết xuất cần thiết thư viện chia sẻ \"%s\"\n"
+
+#: i386linux.c:459 m68klinux.c:464 sparclinux.c:458
+#, c-format
+msgid "Output file requires shared library `%s.so.%s'\n"
+msgstr "Tập tin kết xuất cần thiết thư viện chia sẻ \"%s.so.%s\"\n"
+
+#: i386linux.c:648 i386linux.c:698 m68klinux.c:656 m68klinux.c:704
+#: sparclinux.c:648 sparclinux.c:698
+#, c-format
+msgid "Symbol %s not defined for fixups\n"
+msgstr "Ký hiệu %s chưa được xác định để sửa chữa\n"
+
+#: i386linux.c:722 m68klinux.c:728 sparclinux.c:722
+msgid "Warning: fixup count mismatch\n"
+msgstr "Cảnh báo: sai khớp số đếm sự sửa chữa\n"
+
+#: ieee.c:159
+#, c-format
+msgid "%s: string too long (%d chars, max 65535)"
+msgstr "%s: chuỗi quá dài (%d ký tự, tối đa 65535)"
+
+#: ieee.c:286
+#, c-format
+msgid "%s: unrecognized symbol `%s' flags 0x%x"
+msgstr "%s: không nhận ra ký hiêu \"%s\" các cỠ0x%x"
+
+#: ieee.c:792
+msgid "%B: unimplemented ATI record %u for symbol %u"
+msgstr "%B: mục ghi ATI %u chưa được thực hiện đối với ký hiệu %u"
+
+#: ieee.c:816
+msgid "%B: unexpected ATN type %d in external part"
+msgstr "%B: gặp kiểu ATN bất thÆ°á»ng %d trong phần bên ngoài"
+
+#: ieee.c:838
+msgid "%B: unexpected type after ATN"
+msgstr "%B: gặp kiểu bất thÆ°á»ng đằng sau ATN"
+
+#: ihex.c:230
+msgid "%B:%d: unexpected character `%s' in Intel Hex file"
+msgstr "%B:%d: gặp ký tá»± bất thÆ°á»ng trong tập tin thập lục Intel"
+
+#: ihex.c:337
+msgid "%B:%u: bad checksum in Intel Hex file (expected %u, found %u)"
+msgstr "%B:%d: gặp tổng kiểm sai trong tập tin thập lục Intel (đợi %u còn tìm %u)"
+
+#: ihex.c:392
+msgid "%B:%u: bad extended address record length in Intel Hex file"
+msgstr "%B:%d: gặp chiá»u dài mục ghi địa chỉ đã mở rá»™ng sai trong tập tin thập lục Intel"
+
+#: ihex.c:409
+msgid "%B:%u: bad extended start address length in Intel Hex file"
+msgstr "%B:%d: gặp chiá»u dài địa chỉ đầu đã mở rá»™ng sai trong tập tin thập lục Intel"
+
+#: ihex.c:426
+msgid "%B:%u: bad extended linear address record length in Intel Hex file"
+msgstr "%B:%d: gặp chiá»u dài mục ghi địa chỉ tuyến đã mở rá»™ng sai trong tập tin thập lục Intel"
+
+#: ihex.c:443
+msgid "%B:%u: bad extended linear start address length in Intel Hex file"
+msgstr "%B:%d: gặp chiá»u dài địa chỉ tuyến đã mở rá»™ng sai trong tập tin thập lục Intel"
+
+#: ihex.c:460
+msgid "%B:%u: unrecognized ihex type %u in Intel Hex file"
+msgstr "%B:%d: gặp kiểu ihex không được nhận ra %u trong tập tin thập lục Intel"
+
+#: ihex.c:579
+msgid "%B: internal error in ihex_read_section"
+msgstr "%B: gặp lỗi nội bộ trong ihex_read_section"
+
+#: ihex.c:613
+msgid "%B: bad section length in ihex_read_section"
+msgstr "%B: gặp chiá»u dài phần sai trong ihex_read_section"
+
+#: ihex.c:826
+#, c-format
+msgid "%s: address 0x%s out of range for Intel Hex file"
+msgstr "%s: địa chỉ 0x%s ở ngoại phạm vi đối với tập tin thập lục Intel"
+
+#: libbfd.c:863
+msgid "%B: unable to get decompressed section %A"
+msgstr "%B: không thể lấy phần được giải nén %A"
+
+#: libbfd.c:1012
+msgid "%B: compiled for a big endian system and target is little endian"
+msgstr "%B: được biên dịch cho má»™t hệ thống vá» cuối lá»›n, còn đích vá» cuối nhá»"
+
+#: libbfd.c:1014
+msgid "%B: compiled for a little endian system and target is big endian"
+msgstr "%B: được biên dịch cho má»™t hệ thống vá» cuối nhá», còn đích vá» cuối lá»›n"
+
+#: libbfd.c:1043
+#, c-format
+msgid "Deprecated %s called at %s line %d in %s\n"
+msgstr "%s bị phản đối được gá»i tại dòng %s %d trong %s\n"
+
+#: libbfd.c:1046
+#, c-format
+msgid "Deprecated %s called\n"
+msgstr "%s bị phản đối được gá»i\n"
+
+#: linker.c:1872
+msgid "%B: indirect symbol `%s' to `%s' is a loop"
+msgstr "%B: ký hiệu gián tiếp \"%s\" tới \"%s\" thì tạo một vòng lặp"
+
+#: linker.c:2736
+#, c-format
+msgid "Attempt to do relocatable link with %s input and %s output"
+msgstr "Thử làm liên kết có khả năng định vị lại với đầu vào %s và đầu ra %s"
+
+#: linker.c:3021
+msgid "%B: ignoring duplicate section `%A'\n"
+msgstr "%B: đang bỠqua phần trùng \"%A\"\n"
+
+#: linker.c:3030 linker.c:3039
+msgid "%B: duplicate section `%A' has different size\n"
+msgstr "%B: phần trùng \"%A\" có kích cỡ khác\n"
+
+#: linker.c:3047 linker.c:3052
+msgid "%B: could not read contents of section `%A'\n"
+msgstr "%B: không thể Ä‘á»c ná»™i dung của phần \"%A\"\n"
+
+#: linker.c:3056
+msgid "%B: duplicate section `%A' has different contents\n"
+msgstr "%B: phần trùng `%A' có nội dung khác\n"
+
+#: mach-o.c:407
+msgid "bfd_mach_o_canonicalize_symtab: unable to load symbols"
+msgstr "bfd_mach_o_canonicalize_symtab: không thể tải các ký hiệu"
+
+#: mach-o.c:1301
+#, c-format
+msgid "unable to write unknown load command 0x%lx"
+msgstr "không thể ghi lệnh tải chưa được biết 0x%lx"
+
+#: mach-o.c:1789
+#, c-format
+msgid "bfd_mach_o_read_symtab_symbol: unable to read %d bytes at %lu"
+msgstr "bfd_mach_o_read_symtab_symbol: không thể Ä‘á»c %d byte tại %lu"
+
+#: mach-o.c:1807
+#, c-format
+msgid "bfd_mach_o_read_symtab_symbol: name out of range (%lu >= %lu)"
+msgstr "bfd_mach_o_read_symtab_symbol: tên ngoài phạm vi (%lu >= %lu)"
+
+#: mach-o.c:1892
+#, c-format
+msgid "bfd_mach_o_read_symtab_symbol: symbol \"%s\" specified invalid section %d (max %lu): setting to undefined"
+msgstr "bfd_mach_o_read_symtab_symbol: ký hiệu \"%s\" đã chỉ ra phần không hợp lệ %d (tối đa %lu): đang đặt thành chưa định nghĩa"
+
+#: mach-o.c:1900
+#, c-format
+msgid "bfd_mach_o_read_symtab_symbol: symbol \"%s\" is unsupported 'indirect' reference: setting to undefined"
+msgstr "bfd_mach_o_read_symtab_symbol: ký hiệu \"%s\" không được hỗ trợ tham chiếu 'indirect': đặt thành chưa định nghĩa"
+
+#: mach-o.c:1906
+#, c-format
+msgid "bfd_mach_o_read_symtab_symbol: symbol \"%s\" specified invalid type field 0x%x: setting to undefined"
+msgstr "bfd_mach_o_read_symtab_symbol: ký hiệu \"%s\" đã chỉ định sai kiểu tại trÆ°á»ng 0x%x: đặt thành chÆ°a định nghÄ©a"
+
+#: mach-o.c:1979
+msgid "bfd_mach_o_read_symtab_symbols: unable to allocate memory for symbols"
+msgstr "bfd_mach_o_read_symtab_symbols: không thể cấp phát bộ nhớ cho các ký hiệu"
+
+#: mach-o.c:2014
+#, c-format
+msgid "bfd_mach_o_read_dysymtab_symbol: unable to read %lu bytes at %lu"
+msgstr "bfd_mach_o_read_dysymtab_symbol: không thể Ä‘á»c %lu byte tại %lu"
+
+#: mach-o.c:2734
+#, c-format
+msgid "unable to read unknown load command 0x%lx"
+msgstr "không thể Ä‘á»c lệnh tải chÆ°a được biết 0x%lx"
+
+#: mach-o.c:2915
+#, c-format
+msgid "bfd_mach_o_scan: unknown architecture 0x%lx/0x%lx"
+msgstr "bfd_mach_o_scan: kiến trúc chưa được biết đến 0x%lx/0x%lx"
+
+#: mach-o.c:3011
+#, c-format
+msgid "unknown header byte-order value 0x%lx"
+msgstr "không hiểu giá trị thứ-tự-byte trong phần đầu 0x%lx"
+
+#: mach-o.c:3577
+msgid "Mach-O header:\n"
+msgstr "Phần đầu Mach-O:\n"
+
+#: mach-o.c:3578
+#, c-format
+msgid " magic : %08lx\n"
+msgstr " ma thuật : %08lx\n"
+
+#: mach-o.c:3579
+#, c-format
+msgid " cputype : %08lx (%s)\n"
+msgstr " kiểu CPU : %08lx (%s)\n"
+
+#: mach-o.c:3581
+#, c-format
+msgid " cpusubtype: %08lx\n"
+msgstr " kiểu phụ CPU: %08lx\n"
+
+#: mach-o.c:3582
+#, c-format
+msgid " filetype : %08lx (%s)\n"
+msgstr " kiểu tập tin : %08lx (%s)\n"
+
+#: mach-o.c:3585
+#, c-format
+msgid " ncmds : %08lx (%lu)\n"
+msgstr " ncmds : %08lx (%lu)\n"
+
+#: mach-o.c:3586
+#, c-format
+msgid " sizeofcmds: %08lx\n"
+msgstr " kích cỡ cmds: %08lx\n"
+
+#: mach-o.c:3587
+#, c-format
+msgid " flags : %08lx ("
+msgstr " cá» : %08lx ("
+
+#: mach-o.c:3589 vms-alpha.c:7674
+msgid ")\n"
+msgstr ")\n"
+
+#: mach-o.c:3590
+#, c-format
+msgid " reserved : %08x\n"
+msgstr " dành riêng : %08x\n"
+
+#: mach-o.c:3600
+msgid "Segments and Sections:\n"
+msgstr "Äoạn và Phần:\n"
+
+#: mach-o.c:3601
+msgid " #: Segment name Section name Address\n"
+msgstr " #: Tên Ä‘oạn Tên phần Äịa chỉ\n"
+
+#: merge.c:832
+#, c-format
+msgid "%s: access beyond end of merged section (%ld)"
+msgstr "%s: truy cập vượt quá kết thúc của phần đã gộp lại (%ld)"
+
+#: mmo.c:456
+#, c-format
+msgid "%s: No core to allocate section name %s\n"
+msgstr "%s: Không có lõi nào để cấp phát tên phần %s\n"
+
+#: mmo.c:531
+#, c-format
+msgid "%s: No core to allocate a symbol %d bytes long\n"
+msgstr "%s: Không có lõi nào để cấp phát má»™t ký hiệu có chiá»u dài %d byte\n"
+
+#: mmo.c:1187
+#, c-format
+msgid "%s: invalid mmo file: initialization value for $255 is not `Main'\n"
+msgstr "%s: tập tin mmo không hợp lệ: giá trị khởi tạo cho $255 không phải là \"Main\" (chính)\n"
+
+#: mmo.c:1332
+#, c-format
+msgid "%s: unsupported wide character sequence 0x%02X 0x%02X after symbol name starting with `%s'\n"
+msgstr "%s: dãy ký tự rộng không được hỗ trợ 0x%02X 0x%02X đằng sau tên ký hiệu bắt đầu với \"%s\"\n"
+
+#: mmo.c:1565
+#, c-format
+msgid "%s: invalid mmo file: unsupported lopcode `%d'\n"
+msgstr "%s: tập tin mmo không hợp lệ: mã lop không được hỗ trợ \"%d\"\n"
+
+#: mmo.c:1575
+#, c-format
+msgid "%s: invalid mmo file: expected YZ = 1 got YZ = %d for lop_quote\n"
+msgstr "%s: tập tin mmo không hợp lệ: đợi YZ=1, còn nhận YZ=%d đối với lop_quote (trích dẫn)\n"
+
+#: mmo.c:1611
+#, c-format
+msgid "%s: invalid mmo file: expected z = 1 or z = 2, got z = %d for lop_loc\n"
+msgstr "%s: tập tin mmo không hợp lệ: đợi z=1 hoặc z=2, còn nhận z=%d đối với lop_loc (định vị)\n"
+
+#: mmo.c:1657
+#, c-format
+msgid "%s: invalid mmo file: expected z = 1 or z = 2, got z = %d for lop_fixo\n"
+msgstr "%s: tập tin mmo không hợp lệ: đợi z=1 hoặc z=2, còn nhận z=%d đối với lop_fixo\n"
+
+#: mmo.c:1696
+#, c-format
+msgid "%s: invalid mmo file: expected y = 0, got y = %d for lop_fixrx\n"
+msgstr "%s: tập tin mmo không hợp lệ: đợi y=0, còn nhận y=%d cho lop_fixrx\n"
+
+#: mmo.c:1705
+#, c-format
+msgid "%s: invalid mmo file: expected z = 16 or z = 24, got z = %d for lop_fixrx\n"
+msgstr "%s: tập tin mmo không hợp lệ: đợi z=16 hoặc z=24, còn nhận z=%d đối với lop_fixrx\n"
+
+#: mmo.c:1728
+#, c-format
+msgid "%s: invalid mmo file: leading byte of operand word must be 0 or 1, got %d for lop_fixrx\n"
+msgstr "%s: tập tin mmo không hợp lệ: byte đứng đầu của tên số hạng phải là 0 hoặc 1, còn nhận %d đối với lop_fixrx\n"
+
+#: mmo.c:1751
+#, c-format
+msgid "%s: cannot allocate file name for file number %d, %d bytes\n"
+msgstr "%s: không thể cấp phát tên tập tin cho tên số %d, %d byte\n"
+
+#: mmo.c:1771
+#, c-format
+msgid "%s: invalid mmo file: file number %d `%s', was already entered as `%s'\n"
+msgstr "%s: tập tin mmo không hợp lệ: tập tin số %d \"%s\" đã được nhập vào dạng \"%s\"\n"
+
+#: mmo.c:1784
+#, c-format
+msgid "%s: invalid mmo file: file name for number %d was not specified before use\n"
+msgstr "%s: tập tin mmo không hợp lệ: tên tập tin cho số %d đã không được ghi rõ trước khi dùng\n"
+
+#: mmo.c:1890
+#, c-format
+msgid "%s: invalid mmo file: fields y and z of lop_stab non-zero, y: %d, z: %d\n"
+msgstr "%s: tập tin mmo không hợp lệ: hai trÆ°á»ng y và z của lop_stab không phải là số không, y: %d, z: %d\n"
+
+#: mmo.c:1926
+#, c-format
+msgid "%s: invalid mmo file: lop_end not last item in file\n"
+msgstr "%s: tập tin mmo không hợp lệ: lop_end không phải là mục cuối cùng trong tập tin\n"
+
+#: mmo.c:1939
+#, c-format
+msgid "%s: invalid mmo file: YZ of lop_end (%ld) not equal to the number of tetras to the preceding lop_stab (%ld)\n"
+msgstr "%s: tập tin mmo không hợp lệ: YZ của lop_end (%ld) không phải bằng với số tetra tới lop_stab đi trước (%ld)\n"
+
+#: mmo.c:2649
+#, c-format
+msgid "%s: invalid symbol table: duplicate symbol `%s'\n"
+msgstr "%s: bảng ký hiệu không hợp lệ: ký hiệu trùng \"%s\"\n"
+
+#: mmo.c:2889
+#, c-format
+msgid "%s: Bad symbol definition: `Main' set to %s rather than the start address %s\n"
+msgstr "%s: Sai xác định ký hiệu: \"Main\" (chính) được đặt thành %s hơn là địa chỉ đầu %s\n"
+
+#: mmo.c:2981
+#, c-format
+msgid "%s: warning: symbol table too large for mmo, larger than 65535 32-bit words: %d. Only `Main' will be emitted.\n"
+msgstr "%s: cảnh báo: bảng ký hiệu quá lớn cho mmo, lớn hơn 65535 từ 32-bit: %d, nên chỉ phát ra \"Main\" (chính).\n"
+
+#: mmo.c:3026
+#, c-format
+msgid "%s: internal error, symbol table changed size from %d to %d words\n"
+msgstr "%s: gặp lỗi nội bộ: bảng ký hiệu đã thay đổi kích cỡ từ %d thành %d từ\n"
+
+#: mmo.c:3078
+#, c-format
+msgid "%s: internal error, internal register section %s had contents\n"
+msgstr "%s: gặp lỗi nội bộ: phần thanh ghi nội bộ %s có nội dung\n"
+
+#: mmo.c:3129
+#, c-format
+msgid "%s: no initialized registers; section length 0\n"
+msgstr "%s: không có thanh ghi đã khởi tạo, chiá»u dài phần 0\n"
+
+#: mmo.c:3135
+#, c-format
+msgid "%s: too many initialized registers; section length %ld\n"
+msgstr "%s: quá nhiá»u thanh ghi đã khởi tạo ; chiá»u dài phần %ld\n"
+
+#: mmo.c:3140
+#, c-format
+msgid "%s: invalid start address for initialized registers of length %ld: 0x%lx%08lx\n"
+msgstr "%s: địa chỉ đầu không hợp lệ cho các thanh ghi đã khởi tạo có chiá»u dài %ld: 0x%lx% 08lx\n"
+
+#: oasys.c:882
+#, c-format
+msgid "%s: can not represent section `%s' in oasys"
+msgstr "%s: không thể đại diện phần \"%s\" theo oasys"
+
+#: osf-core.c:140
+#, c-format
+msgid "Unhandled OSF/1 core file section type %d\n"
+msgstr "Kiểu phần tập tin lõi OSF/1 không được quản lý %d\n"
+
+#: pe-mips.c:607
+msgid "%B: `ld -r' not supported with PE MIPS objects\n"
+msgstr "%B: \"ld -r\" không được hỗ trợ với đối tượng MIPS PE\n"
+
+#. OK, at this point the following variables are set up:
+#. src = VMA of the memory we're fixing up
+#. mem = pointer to memory we're fixing up
+#. val = VMA of what we need to refer to.
+#: pe-mips.c:719
+msgid "%B: unimplemented %s\n"
+msgstr "%B: %s chưa được thực hiện\n"
+
+#: pe-mips.c:745
+msgid "%B: jump too far away\n"
+msgstr "%B: bước nhảy quá xa\n"
+
+#: pe-mips.c:771
+msgid "%B: bad pair/reflo after refhi\n"
+msgstr "%B: pair/reflo sai đằng sau refhi\n"
+
+#: pef.c:520
+#, c-format
+msgid "bfd_pef_scan: unknown architecture 0x%lx"
+msgstr "bfd_pef_scan: kiến trúc chưa được biết đến 0x%lx"
+
+#: pei-x86_64.c:444
+#, c-format
+msgid "warning: .pdata section size (%ld) is not a multiple of %d\n"
+msgstr "cảnh báo: kích cỡ phần .pdata (%ld) không phải là bội số cho %d\n"
+
+#: pei-x86_64.c:448 peigen.c:1618 peigen.c:1801 pepigen.c:1618 pepigen.c:1801
+#: pex64igen.c:1618 pex64igen.c:1801
+#, c-format
+msgid ""
+"\n"
+"The Function Table (interpreted .pdata section contents)\n"
+msgstr ""
+"\n"
+"Bảng Hàm (phiên dịch nội dung phần .pdata)\n"
+
+#: pei-x86_64.c:450
+#, c-format
+msgid "vma:\t\t\tBeginAddress\t EndAddress\t UnwindData\n"
+msgstr "vma:\t\t\tÄịa chi đầu Äịa chỉ cuối Thông tin tháo ra\n"
+
+#. XXX code yet to be written.
+#: peicode.h:751
+msgid "%B: Unhandled import type; %x"
+msgstr "%B: Kiểu nhập không được quản lý; %x"
+
+#: peicode.h:756
+msgid "%B: Unrecognised import type; %x"
+msgstr "%B: Kiểu nhập không được nhận ra; %x"
+
+#: peicode.h:770
+msgid "%B: Unrecognised import name type; %x"
+msgstr "%B: Kiểu tên nhập không được nhận ra; %x"
+
+#: peicode.h:1166
+msgid "%B: Unrecognised machine type (0x%x) in Import Library Format archive"
+msgstr "%B: Kiểu máy không được nhận ra (0x%x) trong kho lÆ°u Äịnh dạng ThÆ° viện Nhập"
+
+#: peicode.h:1178
+msgid "%B: Recognised but unhandled machine type (0x%x) in Import Library Format archive"
+msgstr "%B: Kiểu máy được nhận ra còn không được quản lý (0x%x) trong kho lÆ°u Äịnh dạng ThÆ° viện Nhập"
+
+#: peicode.h:1196
+msgid "%B: size field is zero in Import Library Format header"
+msgstr "%B: trÆ°á»ng kích cỡ là số không trong phần đầu Äịnh dạng ThÆ° viện Nhập"
+
+#: peicode.h:1227
+msgid "%B: string not null terminated in ILF object file."
+msgstr "%B: chuỗi không phải kết thúc vô hiệu lực trong tập tin đối tượng ILF. "
+
+#: ppcboot.c:414
+#, c-format
+msgid ""
+"\n"
+"ppcboot header:\n"
+msgstr ""
+"\n"
+"Phần đầu ppcboot:\n"
+
+#: ppcboot.c:415
+#, c-format
+msgid "Entry offset = 0x%.8lx (%ld)\n"
+msgstr "Khoảng bù vào = 0x%.8lx (%ld)\n"
+
+#: ppcboot.c:417
+#, c-format
+msgid "Length = 0x%.8lx (%ld)\n"
+msgstr "Dài = 0x%.8lx (%ld)\n"
+
+#: ppcboot.c:421
+#, c-format
+msgid "Flag field = 0x%.2x\n"
+msgstr "TrÆ°á»ng cá» = 0x%.2x\n"
+
+#: ppcboot.c:427
+#, c-format
+msgid "Partition name = \"%s\"\n"
+msgstr "Tên phân vùng = \"%s\"\n"
+
+#: ppcboot.c:446
+#, c-format
+msgid ""
+"\n"
+"Partition[%d] start = { 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x }\n"
+msgstr ""
+"\n"
+"Phân vùng[%d] đầu = { 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x }\n"
+
+#: ppcboot.c:452
+#, c-format
+msgid "Partition[%d] end = { 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x }\n"
+msgstr "Phân vùng[%d] cuối = { 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x }\n"
+
+#: ppcboot.c:458
+#, c-format
+msgid "Partition[%d] sector = 0x%.8lx (%ld)\n"
+msgstr "Phân vùng[%d] rãnh ghi = 0x%.8lx (%ld)\n"
+
+#: ppcboot.c:460
+#, c-format
+msgid "Partition[%d] length = 0x%.8lx (%ld)\n"
+msgstr "Phân vùng[%d] dài = 0x%.8lx (%ld)\n"
+
+#: reloc.c:6160
+msgid "INPUT_SECTION_FLAGS are not supported.\n"
+msgstr "INPUT_SECTION_FLAGS không được hỗ trợ.\n"
+
+#: rs6000-core.c:448
+#, c-format
+msgid "%s: warning core file truncated"
+msgstr "%s: cảnh bảo lõi tập tin bị cắt ngắn"
+
+#: som.c:5471
+#, c-format
+msgid ""
+"\n"
+"Exec Auxiliary Header\n"
+msgstr ""
+"\n"
+"Phần đầu phụ thực hiện\n"
+
+#: som.c:5776
+msgid "som_sizeof_headers unimplemented"
+msgstr "som_sizeof_headers chưa được thực hiện"
+
+#: srec.c:261
+msgid "%B:%d: Unexpected character `%s' in S-record file\n"
+msgstr "%B:%d Gặp ký tá»± bất thÆ°á»ng \"%s\" trong tập tin S-record\n"
+
+#: srec.c:567 srec.c:600
+msgid "%B:%d: Bad checksum in S-record file\n"
+msgstr "%B:%d: sai tổng kiểm trong tập tin S-record\n"
+
+#: stabs.c:279
+msgid "%B(%A+0x%lx): Stabs entry has invalid string index."
+msgstr "%B(%A+0x%lx): Mục nhập Stabs có chỉ mục chuỗi không hợp lệ."
+
+#: syms.c:1079
+msgid "Unsupported .stab relocation"
+msgstr "Äịnh vị lại .stab không được há»— trợ"
+
+#: vms-alpha.c:1299
+#, c-format
+msgid "Unknown EGSD subtype %d"
+msgstr "Không hiểu kiểu phụ EGSD %d"
+
+#: vms-alpha.c:1330
+#, c-format
+msgid "Stack overflow (%d) in _bfd_vms_push"
+msgstr "Tràn đống (%d) trong _bfd_vms_push"
+
+#: vms-alpha.c:1343
+msgid "Stack underflow in _bfd_vms_pop"
+msgstr "Trán ngược đống trong _bfd_vms_pop"
+
+#. These names have not yet been added to this switch statement.
+#: vms-alpha.c:1580
+#, c-format
+msgid "unknown ETIR command %d"
+msgstr "không rõ câu lệnh ETIR %d"
+
+#: vms-alpha.c:1767
+#, c-format
+msgid "bad section index in %s"
+msgstr "chỉ mục phần sai trong %s"
+
+#: vms-alpha.c:1780
+#, c-format
+msgid "unsupported STA cmd %s"
+msgstr "câu lệnh STA không được hỗ trợ %s"
+
+#. Insert field.
+#. Unsigned shift.
+#. Rotate.
+#. Redefine symbol to current location.
+#. Define a literal.
+#: vms-alpha.c:1956 vms-alpha.c:1987 vms-alpha.c:2234
+#, c-format
+msgid "%s: not supported"
+msgstr "%s: không được hỗ trợ"
+
+#: vms-alpha.c:1962
+#, c-format
+msgid "%s: not implemented"
+msgstr "%s: chưa được thực hiện"
+
+#: vms-alpha.c:2218
+#, c-format
+msgid "invalid use of %s with contexts"
+msgstr "sử dụng sai %s với các ngữ cảnh"
+
+#: vms-alpha.c:2252
+#, c-format
+msgid "reserved cmd %d"
+msgstr "cmd (lệnh) đảo ngược %d"
+
+#: vms-alpha.c:2337
+msgid "Object module NOT error-free !\n"
+msgstr "Mô-đun đối tượng KHÔNG phải miễn lỗi !\n"
+
+#: vms-alpha.c:2766
+#, c-format
+msgid "Symbol %s replaced by %s\n"
+msgstr "Ký hiệu %s đã bị thay thế bằng %s\n"
+
+#: vms-alpha.c:3769
+#, c-format
+msgid "SEC_RELOC with no relocs in section %s"
+msgstr "SEC_RELOC không có định vị lại trong phần %s"
+
+#: vms-alpha.c:3822 vms-alpha.c:4049
+#, c-format
+msgid "Size error in section %s"
+msgstr "Gặp lỗi kích cỡ trong phần %s"
+
+#: vms-alpha.c:3991
+msgid "Spurious ALPHA_R_BSR reloc"
+msgstr "Gặp sự định vị lại ALPHA_R_BSR giả"
+
+#: vms-alpha.c:4036
+#, c-format
+msgid "Unhandled relocation %s"
+msgstr "Äịnh vị lại không được quản lý %s"
+
+#: vms-alpha.c:4326
+#, c-format
+msgid "unknown source command %d"
+msgstr "không rõ câu lệnh nguồn %d"
+
+#: vms-alpha.c:4387
+msgid "DST__K_SET_LINUM_INCR not implemented"
+msgstr "DST__K_SET_LINUM_INCR chưa được thực hiện"
+
+#: vms-alpha.c:4393
+msgid "DST__K_SET_LINUM_INCR_W not implemented"
+msgstr "DST__K_SET_LINUM_INCR_W chưa được thực hiện"
+
+#: vms-alpha.c:4399
+msgid "DST__K_RESET_LINUM_INCR not implemented"
+msgstr "DST__K_RESET_LINUM_INCR not implemented"
+
+#: vms-alpha.c:4405
+msgid "DST__K_BEG_STMT_MODE not implemented"
+msgstr "DST__K_BEG_STMT_MODE chưa được thực hiện"
+
+#: vms-alpha.c:4411
+msgid "DST__K_END_STMT_MODE not implemented"
+msgstr "DST__K_END_STMT_MODE chưa được thực hiện"
+
+#: vms-alpha.c:4438
+msgid "DST__K_SET_PC not implemented"
+msgstr "DST__K_SET_PC chưa được thực hiện"
+
+#: vms-alpha.c:4444
+msgid "DST__K_SET_PC_W not implemented"
+msgstr "DST__K_SET_PC_W chưa được thực hiện"
+
+#: vms-alpha.c:4450
+msgid "DST__K_SET_PC_L not implemented"
+msgstr "DST__K_SET_PC_L chưa được thực hiện"
+
+#: vms-alpha.c:4456
+msgid "DST__K_SET_STMTNUM not implemented"
+msgstr "DST__K_SET_STMTNUM chưa được thực hiện"
+
+#: vms-alpha.c:4499
+#, c-format
+msgid "unknown line command %d"
+msgstr "không rõ câu lệnh dòng %d"
+
+#: vms-alpha.c:4953 vms-alpha.c:4970 vms-alpha.c:4984 vms-alpha.c:4999
+#: vms-alpha.c:5011 vms-alpha.c:5022 vms-alpha.c:5034
+#, c-format
+msgid "Unknown reloc %s + %s"
+msgstr "Không rõ sự định vị lại %s + %s"
+
+#: vms-alpha.c:5089
+#, c-format
+msgid "Unknown reloc %s"
+msgstr "Không rõ reloc %s"
+
+#: vms-alpha.c:5102
+msgid "Invalid section index in ETIR"
+msgstr "Phần bảng mục lục không hợp lệ trong ETIR"
+
+#: vms-alpha.c:5109
+msgid "Relocation for non-REL psect"
+msgstr "Tái định vị cho 'non-REL psect'"
+
+#: vms-alpha.c:5156
+#, c-format
+msgid "Unknown symbol in command %s"
+msgstr "Không rõ ký hiệu trong lệnh %s"
+
+#: vms-alpha.c:5671
+#, c-format
+msgid " EMH %u (len=%u): "
+msgstr " EMH %u (dài=%u): "
+
+#: vms-alpha.c:5680
+#, c-format
+msgid "Module header\n"
+msgstr "Äầu của mô-Ä‘un\n"
+
+#: vms-alpha.c:5681
+#, c-format
+msgid " structure level: %u\n"
+msgstr " mức cấu trúc: %u\n"
+
+#: vms-alpha.c:5682
+#, c-format
+msgid " max record size: %u\n"
+msgstr " kích thước bản ghi tối đa: %u\n"
+
+#: vms-alpha.c:5685
+#, c-format
+msgid " module name : %.*s\n"
+msgstr " tên mô-đun : %.*s\n"
+
+#: vms-alpha.c:5687
+#, c-format
+msgid " module version : %.*s\n"
+msgstr " phiên bản môđun : %.*s\n"
+
+#: vms-alpha.c:5689
+#, c-format
+msgid " compile date : %.17s\n"
+msgstr " ngày dịch : %.17s\n"
+
+#: vms-alpha.c:5694
+#, c-format
+msgid "Language Processor Name\n"
+msgstr "Tên ngôn ngữ bộ vi xử lý\n"
+
+#: vms-alpha.c:5695
+#, c-format
+msgid " language name: %.*s\n"
+msgstr " tên ngôn ngữ: %.*s\n"
+
+#: vms-alpha.c:5702
+#, c-format
+msgid "Source Files Header\n"
+msgstr "Äầu của tập tin nguồn\n"
+
+#: vms-alpha.c:5703
+#, c-format
+msgid " file: %.*s\n"
+msgstr " tập tin: %.*s\n"
+
+#: vms-alpha.c:5710
+#, c-format
+msgid "Title Text Header\n"
+msgstr "Phần đầu Chữ Tiêu Ä‘á»\n"
+
+#: vms-alpha.c:5711
+#, c-format
+msgid " title: %.*s\n"
+msgstr " tiêu Ä‘á»: %.*s\n"
+
+#: vms-alpha.c:5718
+#, c-format
+msgid "Copyright Header\n"
+msgstr "Phần bản quyá»n\n"
+
+#: vms-alpha.c:5719
+#, c-format
+msgid " copyright: %.*s\n"
+msgstr " tác quyá»n: %.*s\n"
+
+#: vms-alpha.c:5725
+#, c-format
+msgid "unhandled emh subtype %u\n"
+msgstr "kiểu phụ emh chưa được quản lý %u\n"
+
+#: vms-alpha.c:5735
+#, c-format
+msgid " EEOM (len=%u):\n"
+msgstr " EEOM (dài=%u):\n"
+
+#: vms-alpha.c:5736
+#, c-format
+msgid " number of cond linkage pairs: %u\n"
+msgstr " số lượng của cặp liên kết \"cond\": %u\n"
+
+#: vms-alpha.c:5738
+#, c-format
+msgid " completion code: %u\n"
+msgstr " mã đầy đủ: %u\n"
+
+#: vms-alpha.c:5742
+#, c-format
+msgid " transfer addr flags: 0x%02x\n"
+msgstr " cỠchuyển đổi địa chỉ: 0x%02x\n"
+
+#: vms-alpha.c:5743
+#, c-format
+msgid " transfer addr psect: %u\n"
+msgstr " chuyển đổi \"addr psect\": %u\n"
+
+#: vms-alpha.c:5745
+#, c-format
+msgid " transfer address : 0x%08x\n"
+msgstr " địa chỉ chuyển đổi : 0x%08x\n"
+
+#: vms-alpha.c:5754
+msgid " WEAK"
+msgstr " WEAK"
+
+#: vms-alpha.c:5756
+msgid " DEF"
+msgstr " DEF"
+
+#: vms-alpha.c:5758
+msgid " UNI"
+msgstr " UNI"
+
+#: vms-alpha.c:5760 vms-alpha.c:5781
+msgid " REL"
+msgstr " REL"
+
+#: vms-alpha.c:5762
+msgid " COMM"
+msgstr " COMM"
+
+#: vms-alpha.c:5764
+msgid " VECEP"
+msgstr " VECEP"
+
+#: vms-alpha.c:5766
+msgid " NORM"
+msgstr " NORM"
+
+#: vms-alpha.c:5768
+msgid " QVAL"
+msgstr " QVAL"
+
+#: vms-alpha.c:5775
+msgid " PIC"
+msgstr " PIC"
+
+#: vms-alpha.c:5777
+msgid " LIB"
+msgstr " LIB"
+
+#: vms-alpha.c:5779
+msgid " OVR"
+msgstr " OVR"
+
+#: vms-alpha.c:5783
+msgid " GBL"
+msgstr " GBL"
+
+#: vms-alpha.c:5785
+msgid " SHR"
+msgstr " SHR"
+
+#: vms-alpha.c:5787
+msgid " EXE"
+msgstr " EXE"
+
+#: vms-alpha.c:5789
+msgid " RD"
+msgstr " RD"
+
+#: vms-alpha.c:5791
+msgid " WRT"
+msgstr " WRT"
+
+#: vms-alpha.c:5793
+msgid " VEC"
+msgstr " VEC"
+
+#: vms-alpha.c:5795
+msgid " NOMOD"
+msgstr " NOMOD"
+
+#: vms-alpha.c:5797
+msgid " COM"
+msgstr " COM"
+
+#: vms-alpha.c:5799
+msgid " 64B"
+msgstr " 64B"
+
+#: vms-alpha.c:5808
+#, c-format
+msgid " EGSD (len=%u):\n"
+msgstr " EGSD (dài=%u):\n"
+
+#: vms-alpha.c:5820
+#, c-format
+msgid " EGSD entry %2u (type: %u, len: %u): "
+msgstr " mục EGSD %2u (kiểu: %u, dài: %u): "
+
+#: vms-alpha.c:5832
+#, c-format
+msgid "PSC - Program section definition\n"
+msgstr "PSC - Phần định nghĩa chương trình\n"
+
+#: vms-alpha.c:5833 vms-alpha.c:5850
+#, c-format
+msgid " alignment : 2**%u\n"
+msgstr " sắp hàng : 2**%u\n"
+
+#: vms-alpha.c:5834 vms-alpha.c:5851
+#, c-format
+msgid " flags : 0x%04x"
+msgstr " cá» : 0x%04x"
+
+#: vms-alpha.c:5838
+#, c-format
+msgid " alloc (len): %u (0x%08x)\n"
+msgstr " alloc (dài): %u (0x%08x)\n"
+
+#: vms-alpha.c:5839 vms-alpha.c:5896 vms-alpha.c:5945
+#, c-format
+msgid " name : %.*s\n"
+msgstr " tên : %.*s\n"
+
+#: vms-alpha.c:5849
+#, c-format
+msgid "SPSC - Shared Image Program section def\n"
+msgstr "SPSC - Phần định nghĩa ảnh chương trình được chia sẻ \n"
+
+#: vms-alpha.c:5855
+#, c-format
+msgid " alloc (len) : %u (0x%08x)\n"
+msgstr " alloc (dài) : %u (0x%08x)\n"
+
+#: vms-alpha.c:5856
+#, c-format
+msgid " image offset : 0x%08x\n"
+msgstr " khoảng bù ảnh : 0x%08x\n"
+
+#: vms-alpha.c:5858
+#, c-format
+msgid " symvec offset : 0x%08x\n"
+msgstr " khoảng bù symvec: 0x%08x\n"
+
+#: vms-alpha.c:5860
+#, c-format
+msgid " name : %.*s\n"
+msgstr " tên : %.*s\n"
+
+#: vms-alpha.c:5873
+#, c-format
+msgid "SYM - Global symbol definition\n"
+msgstr "SYM - Äịnh nghÄ©a ký hiệu toàn cục\n"
+
+#: vms-alpha.c:5874 vms-alpha.c:5934 vms-alpha.c:5955 vms-alpha.c:5974
+#, c-format
+msgid " flags: 0x%04x"
+msgstr " các cá»: 0x%04x"
+
+#: vms-alpha.c:5877
+#, c-format
+msgid " psect offset: 0x%08x\n"
+msgstr " khoảng bù psect: 0x%08x\n"
+
+#: vms-alpha.c:5881
+#, c-format
+msgid " code address: 0x%08x\n"
+msgstr " địa chỉ mã: 0x%08x\n"
+
+#: vms-alpha.c:5883
+#, c-format
+msgid " psect index for entry point : %u\n"
+msgstr " mục lục psect cho điểm vào : %u\n"
+
+#: vms-alpha.c:5886 vms-alpha.c:5962 vms-alpha.c:5981
+#, c-format
+msgid " psect index : %u\n"
+msgstr " chỉ mục psect : %u\n"
+
+#: vms-alpha.c:5888 vms-alpha.c:5964 vms-alpha.c:5983
+#, c-format
+msgid " name : %.*s\n"
+msgstr " tên : %.*s\n"
+
+#: vms-alpha.c:5895
+#, c-format
+msgid "SYM - Global symbol reference\n"
+msgstr "SYM - Tham chiếu ký hiệu toàn cục\n"
+
+#: vms-alpha.c:5907
+#, c-format
+msgid "IDC - Ident Consistency check\n"
+msgstr "IDC - Kiểm tra tính nhất quán Ident\n"
+
+#: vms-alpha.c:5908
+#, c-format
+msgid " flags : 0x%08x"
+msgstr " các cỠ: 0x%08x"
+
+#: vms-alpha.c:5912
+#, c-format
+msgid " id match : %x\n"
+msgstr " id khá»›p : %x\n"
+
+#: vms-alpha.c:5914
+#, c-format
+msgid " error severity: %x\n"
+msgstr " lá»—i nghiêm trá»ng: %x\n"
+
+#: vms-alpha.c:5917
+#, c-format
+msgid " entity name : %.*s\n"
+msgstr " tên thực thể : %.*s\n"
+
+#: vms-alpha.c:5919
+#, c-format
+msgid " object name : %.*s\n"
+msgstr " tên đối tượng : %.*s\n"
+
+#: vms-alpha.c:5922
+#, c-format
+msgid " binary ident : 0x%08x\n"
+msgstr " ident nhị phân : 0x%08x\n"
+
+#: vms-alpha.c:5925
+#, c-format
+msgid " ascii ident : %.*s\n"
+msgstr " ascii ident : %.*s\n"
+
+#: vms-alpha.c:5933
+#, c-format
+msgid "SYMG - Universal symbol definition\n"
+msgstr "SYMG - Äịnh nghÄ©a ký hiệu toàn cục\n"
+
+#: vms-alpha.c:5937
+#, c-format
+msgid " symbol vector offset: 0x%08x\n"
+msgstr " khoảng bù véc-tơ ký hiệu: 0x%08x\n"
+
+#: vms-alpha.c:5939
+#, c-format
+msgid " entry point: 0x%08x\n"
+msgstr " điểm vào: 0x%08x\n"
+
+#: vms-alpha.c:5941
+#, c-format
+msgid " proc descr : 0x%08x\n"
+msgstr " proc descr : 0x%08x\n"
+
+#: vms-alpha.c:5943
+#, c-format
+msgid " psect index: %u\n"
+msgstr " psect index: %u\n"
+
+#: vms-alpha.c:5954
+#, c-format
+msgid "SYMV - Vectored symbol definition\n"
+msgstr "SYMV - Äịnh nghÄ©a ký hiệu véc-tÆ¡\n"
+
+#: vms-alpha.c:5958
+#, c-format
+msgid " vector : 0x%08x\n"
+msgstr " véc-tơ : 0x%08x\n"
+
+#: vms-alpha.c:5960 vms-alpha.c:5979
+#, c-format
+msgid " psect offset: %u\n"
+msgstr " khoảng bù psect: %u\n"
+
+#: vms-alpha.c:5973
+#, c-format
+msgid "SYMM - Global symbol definition with version\n"
+msgstr "SYMM - Äịnh nghÄ©a ký hiệu toàn cục cùng vá»›i phiên bản\n"
+
+#: vms-alpha.c:5977
+#, c-format
+msgid " version mask: 0x%08x\n"
+msgstr " mặt nạ phiên bản: 0x%08x\n"
+
+#: vms-alpha.c:5988
+#, c-format
+msgid "unhandled egsd entry type %u\n"
+msgstr "egsd kiểu mục vào chưa được quản lý %u\n"
+
+#: vms-alpha.c:6022
+#, c-format
+msgid " linkage index: %u, replacement insn: 0x%08x\n"
+msgstr " mục lục liên kết: %u, thay thế insn: 0x%08x\n"
+
+#: vms-alpha.c:6025
+#, c-format
+msgid " psect idx 1: %u, offset 1: 0x%08x %08x\n"
+msgstr " psect idx 1: %u, khoảng bù 1: 0x%08x %08x\n"
+
+#: vms-alpha.c:6029
+#, c-format
+msgid " psect idx 2: %u, offset 2: 0x%08x %08x\n"
+msgstr " psect idx 2: %u, khoảng bù 2: 0x%08x %08x\n"
+
+#: vms-alpha.c:6034
+#, c-format
+msgid " psect idx 3: %u, offset 3: 0x%08x %08x\n"
+msgstr " psect idx 3: %u, khoảng bù 3: 0x%08x %08x\n"
+
+#: vms-alpha.c:6039
+#, c-format
+msgid " global name: %.*s\n"
+msgstr " tên toàn cục: %.*s\n"
+
+#: vms-alpha.c:6049
+#, c-format
+msgid " %s (len=%u+%u):\n"
+msgstr " %s (dài=%u+%u):\n"
+
+#: vms-alpha.c:6064
+#, c-format
+msgid " (type: %3u, size: 4+%3u): "
+msgstr " (kiểu: %3u, kích thước: 4+%3u): "
+
+#: vms-alpha.c:6068
+#, c-format
+msgid "STA_GBL (stack global) %.*s\n"
+msgstr "STA_GBL (stack toàn cục) %.*s\n"
+
+#: vms-alpha.c:6072
+#, c-format
+msgid "STA_LW (stack longword) 0x%08x\n"
+msgstr "STA_LW (stack longword, từ dài) 0x%08x\n"
+
+#: vms-alpha.c:6076
+#, c-format
+msgid "STA_QW (stack quadword) 0x%08x %08x\n"
+msgstr "STA_QW (stack quadword, bốn từ) 0x%08x %08x\n"
+
+#: vms-alpha.c:6081
+#, c-format
+msgid "STA_PQ (stack psect base + offset)\n"
+msgstr "STA_PQ (stack psect cơ sở + khoảng bù)\n"
+
+#: vms-alpha.c:6082
+#, c-format
+msgid " psect: %u, offset: 0x%08x %08x\n"
+msgstr " psect: %u, khoảng bù: 0x%08x %08x\n"
+
+#: vms-alpha.c:6088
+#, c-format
+msgid "STA_LI (stack literal)\n"
+msgstr "STA_LI (stack văn bản)\n"
+
+#: vms-alpha.c:6091
+#, c-format
+msgid "STA_MOD (stack module)\n"
+msgstr "STA_MOD (stack mô-đun)\n"
+
+#: vms-alpha.c:6094
+#, c-format
+msgid "STA_CKARG (compare procedure argument)\n"
+msgstr "STA_CKARG (so sánh đối số thủ tục)\n"
+
+#: vms-alpha.c:6098
+#, c-format
+msgid "STO_B (store byte)\n"
+msgstr "STO_B (lÆ°u byte)\n"
+
+#: vms-alpha.c:6101
+#, c-format
+msgid "STO_W (store word)\n"
+msgstr "STO_W (lÆ°u word)\n"
+
+#: vms-alpha.c:6104
+#, c-format
+msgid "STO_LW (store longword)\n"
+msgstr "STO_LW (store longword, từ dài)\n"
+
+#: vms-alpha.c:6107
+#, c-format
+msgid "STO_QW (store quadword)\n"
+msgstr "STO_QW (store quadword, bốn từ)\n"
+
+#: vms-alpha.c:6113
+#, c-format
+msgid "STO_IMMR (store immediate repeat) %u bytes\n"
+msgstr "STO_IMMR (store immediate repeat) %u bytes\n"
+
+#: vms-alpha.c:6120
+#, c-format
+msgid "STO_GBL (store global) %.*s\n"
+msgstr "STO_GBL (store toàn cục) %.*s\n"
+
+#: vms-alpha.c:6124
+#, c-format
+msgid "STO_CA (store code address) %.*s\n"
+msgstr "STO_CA (store code address) %.*s\n"
+
+#: vms-alpha.c:6128
+#, c-format
+msgid "STO_RB (store relative branch)\n"
+msgstr "STO_RB (store relative branch)\n"
+
+#: vms-alpha.c:6131
+#, c-format
+msgid "STO_AB (store absolute branch)\n"
+msgstr "STO_AB (store absolute branch)\n"
+
+#: vms-alpha.c:6134
+#, c-format
+msgid "STO_OFF (store offset to psect)\n"
+msgstr "STO_OFF (khoảng bù store để psect)\n"
+
+#: vms-alpha.c:6140
+#, c-format
+msgid "STO_IMM (store immediate) %u bytes\n"
+msgstr "STO_IMM (store trực tiếp) %u byte\n"
+
+#: vms-alpha.c:6147
+#, c-format
+msgid "STO_GBL_LW (store global longword) %.*s\n"
+msgstr "STO_GBL_LW (store từ dài, longword, toàn cục) %.*s\n"
+
+#: vms-alpha.c:6151
+#, c-format
+msgid "STO_OFF (store LP with procedure signature)\n"
+msgstr "STO_OFF (store LP với tín hiệu thủ tục)\n"
+
+#: vms-alpha.c:6154
+#, c-format
+msgid "STO_BR_GBL (store branch global) *todo*\n"
+msgstr "STO_BR_GBL (store nhánh toàn cục) *phải làm*\n"
+
+#: vms-alpha.c:6157
+#, c-format
+msgid "STO_BR_PS (store branch psect + offset) *todo*\n"
+msgstr "STO_BR_PS (store nhánh psect + khoảng bù) *phải làm*\n"
+
+#: vms-alpha.c:6161
+#, c-format
+msgid "OPR_NOP (no-operation)\n"
+msgstr "OPR_NOP (không làm gì)\n"
+
+#: vms-alpha.c:6164
+#, c-format
+msgid "OPR_ADD (add)\n"
+msgstr "OPR_ADD (cá»™ng)\n"
+
+#: vms-alpha.c:6167
+#, c-format
+msgid "OPR_SUB (substract)\n"
+msgstr "OPR_SUB (trừ)\n"
+
+#: vms-alpha.c:6170
+#, c-format
+msgid "OPR_MUL (multiply)\n"
+msgstr "OPR_MUL (nhân)\n"
+
+#: vms-alpha.c:6173
+#, c-format
+msgid "OPR_DIV (divide)\n"
+msgstr "OPR_DIV (chia)\n"
+
+#: vms-alpha.c:6176
+#, c-format
+msgid "OPR_AND (logical and)\n"
+msgstr "OPR_AND (phép và lôgíc)\n"
+
+#: vms-alpha.c:6179
+#, c-format
+msgid "OPR_IOR (logical inclusive or)\n"
+msgstr "OPR_IOR (phép lô-gíc inclusive or)\n"
+
+#: vms-alpha.c:6182
+#, c-format
+msgid "OPR_EOR (logical exclusive or)\n"
+msgstr "OPR_EOR (phép lô-gíc exclusive or)\n"
+
+#: vms-alpha.c:6185
+#, c-format
+msgid "OPR_NEG (negate)\n"
+msgstr "OPR_NEG (âm)\n"
+
+#: vms-alpha.c:6188
+#, c-format
+msgid "OPR_COM (complement)\n"
+msgstr "OPR_COM (bù)\n"
+
+#: vms-alpha.c:6191
+#, c-format
+msgid "OPR_INSV (insert field)\n"
+msgstr "OPR_INSV (chèn thêm trÆ°á»ng)\n"
+
+#: vms-alpha.c:6194
+#, c-format
+msgid "OPR_ASH (arithmetic shift)\n"
+msgstr "OPR_ASH (dịch số há»c)\n"
+
+#: vms-alpha.c:6197
+#, c-format
+msgid "OPR_USH (unsigned shift)\n"
+msgstr "OPR_USH (dịch không dấu)\n"
+
+#: vms-alpha.c:6200
+#, c-format
+msgid "OPR_ROT (rotate)\n"
+msgstr "OPR_ROT (quay)\n"
+
+#: vms-alpha.c:6203
+#, c-format
+msgid "OPR_SEL (select)\n"
+msgstr "OPR_SEL (tuyển)\n"
+
+#: vms-alpha.c:6206
+#, c-format
+msgid "OPR_REDEF (redefine symbol to curr location)\n"
+msgstr "OPR_REDEF (redefine symbol to curr location)\n"
+
+#: vms-alpha.c:6209
+#, c-format
+msgid "OPR_REDEF (define a literal)\n"
+msgstr "OPR_REDEF (định nghĩa một đoạn văn\n"
+
+#: vms-alpha.c:6213
+#, c-format
+msgid "STC_LP (store cond linkage pair)\n"
+msgstr "STC_LP (store cond linkage pair)\n"
+
+#: vms-alpha.c:6217
+#, c-format
+msgid "STC_LP_PSB (store cond linkage pair + signature)\n"
+msgstr "STC_LP_PSB (store cond linkage pair + signature)\n"
+
+#: vms-alpha.c:6218
+#, c-format
+msgid " linkage index: %u, procedure: %.*s\n"
+msgstr " mục lục liên kết: %u, thủ tục: %.*s\n"
+
+#: vms-alpha.c:6221
+#, c-format
+msgid " signature: %.*s\n"
+msgstr " chữ ký: %.*s\n"
+
+#: vms-alpha.c:6224
+#, c-format
+msgid "STC_GBL (store cond global)\n"
+msgstr "STC_GBL (store cond toàn cục)\n"
+
+#: vms-alpha.c:6225
+#, c-format
+msgid " linkage index: %u, global: %.*s\n"
+msgstr " mục lục liên kết: %u, toàn cục: %.*s\n"
+
+#: vms-alpha.c:6229
+#, c-format
+msgid "STC_GCA (store cond code address)\n"
+msgstr "STC_GCA (store cond địa chỉ mã)\n"
+
+#: vms-alpha.c:6230
+#, c-format
+msgid " linkage index: %u, procedure name: %.*s\n"
+msgstr " mục lục liên kết: %u, tên thủ tục: %.*s\n"
+
+#: vms-alpha.c:6234
+#, c-format
+msgid "STC_PS (store cond psect + offset)\n"
+msgstr "STC_PS (store cond psect + khoảng bù)\n"
+
+#: vms-alpha.c:6236
+#, c-format
+msgid " linkage index: %u, psect: %u, offset: 0x%08x %08x\n"
+msgstr " mục lục liên kết: %u, psect: %u, khoảng bù: 0x%08x %08x\n"
+
+#: vms-alpha.c:6243
+#, c-format
+msgid "STC_NOP_GBL (store cond NOP at global addr)\n"
+msgstr "STC_NOP_GBL (store cond NOP tại địa chỉ toàn cục)\n"
+
+#: vms-alpha.c:6247
+#, c-format
+msgid "STC_NOP_PS (store cond NOP at psect + offset)\n"
+msgstr "STC_NOP_PS (store cond NOP tại psect + khoảng bù)\n"
+
+#: vms-alpha.c:6251
+#, c-format
+msgid "STC_BSR_GBL (store cond BSR at global addr)\n"
+msgstr "STC_BSR_GBL (store cond BSR ở địa chỉ toàn cục)\n"
+
+#: vms-alpha.c:6255
+#, c-format
+msgid "STC_BSR_PS (store cond BSR at psect + offset)\n"
+msgstr "STC_BSR_PS (store cond BSR tại psect + khoảng bù)\n"
+
+#: vms-alpha.c:6259
+#, c-format
+msgid "STC_LDA_GBL (store cond LDA at global addr)\n"
+msgstr "STC_LDA_GBL (store cond LDA tại địa chỉ toàn cục)\n"
+
+#: vms-alpha.c:6263
+#, c-format
+msgid "STC_LDA_PS (store cond LDA at psect + offset)\n"
+msgstr "STC_LDA_PS (store cond LDA tại psect + khoảng bù)\n"
+
+#: vms-alpha.c:6267
+#, c-format
+msgid "STC_BOH_GBL (store cond BOH at global addr)\n"
+msgstr "STC_BOH_GBL (store cond BOH tại địa chỉ toàn cục)\n"
+
+#: vms-alpha.c:6271
+#, c-format
+msgid "STC_BOH_PS (store cond BOH at psect + offset)\n"
+msgstr "STC_BOH_PS (store cond BOH tại psect + khoảng bù)\n"
+
+#: vms-alpha.c:6276
+#, c-format
+msgid "STC_NBH_GBL (store cond or hint at global addr)\n"
+msgstr "STC_NBH_GBL (store cond hoặc hint tại địa chỉ toàn cục)\n"
+
+#: vms-alpha.c:6280
+#, c-format
+msgid "STC_NBH_PS (store cond or hint at psect + offset)\n"
+msgstr "STC_NBH_PS (store cond hoặc hint tại psect + khoảng bù)\n"
+
+#: vms-alpha.c:6284
+#, c-format
+msgid "CTL_SETRB (set relocation base)\n"
+msgstr "CTL_SETRB (set relocation base)\n"
+
+#: vms-alpha.c:6290
+#, c-format
+msgid "CTL_AUGRB (augment relocation base) %u\n"
+msgstr "CTL_AUGRB (augment relocation base) %u\n"
+
+#: vms-alpha.c:6294
+#, c-format
+msgid "CTL_DFLOC (define location)\n"
+msgstr "CTL_DFLOC (định nghĩa vị trí)\n"
+
+#: vms-alpha.c:6297
+#, c-format
+msgid "CTL_STLOC (set location)\n"
+msgstr "CTL_STLOC (đặt vị trí)\n"
+
+#: vms-alpha.c:6300
+#, c-format
+msgid "CTL_STKDL (stack defined location)\n"
+msgstr "CTL_STKDL (vị trí đã định nghĩa stack)\n"
+
+#: vms-alpha.c:6303 vms-alpha.c:6717
+#, c-format
+msgid "*unhandled*\n"
+msgstr "*không được quản lý*\n"
+
+#: vms-alpha.c:6333 vms-alpha.c:6372
+#, c-format
+msgid "cannot read GST record length\n"
+msgstr "không thể Ä‘á»c Ä‘á»™ dài bản ghi GST\n"
+
+#. Ill-formed.
+#: vms-alpha.c:6354
+#, c-format
+msgid "cannot find EMH in first GST record\n"
+msgstr "không tìm thấy EMH trong bản ghi đầu tiên của GST\n"
+
+#: vms-alpha.c:6380
+#, c-format
+msgid "cannot read GST record header\n"
+msgstr "không thể Ä‘á»c bản ghi phần đầu GST\n"
+
+#: vms-alpha.c:6393
+#, c-format
+msgid " corrupted GST\n"
+msgstr " GST bị há»ng\n"
+
+#: vms-alpha.c:6401
+#, c-format
+msgid "cannot read GST record\n"
+msgstr "không thể Ä‘á»c bản ghi GST\n"
+
+#: vms-alpha.c:6430
+#, c-format
+msgid " unhandled EOBJ record type %u\n"
+msgstr " EOBJ kiểu bản ghi chưa được quản lý %u\n"
+
+#: vms-alpha.c:6453
+#, c-format
+msgid " bitcount: %u, base addr: 0x%08x\n"
+msgstr " sốbít: %u, địachỉcơsở: 0x%08x\n"
+
+#: vms-alpha.c:6466
+#, c-format
+msgid " bitmap: 0x%08x (count: %u):\n"
+msgstr " bitmap: 0x%08x (số lượng: %u):\n"
+
+#: vms-alpha.c:6473
+#, c-format
+msgid " %08x"
+msgstr " %08x"
+
+#: vms-alpha.c:6498
+#, c-format
+msgid " image %u (%u entries)\n"
+msgstr " ảnh %u (%u mục)\n"
+
+#: vms-alpha.c:6503
+#, c-format
+msgid " offset: 0x%08x, val: 0x%08x\n"
+msgstr " khoảng bù: 0x%08x, val: 0x%08x\n"
+
+#: vms-alpha.c:6524
+#, c-format
+msgid " image %u (%u entries), offsets:\n"
+msgstr " ảnh %u (%u mục), khoảng bù:\n"
+
+#: vms-alpha.c:6531
+#, c-format
+msgid " 0x%08x"
+msgstr " 0x%08x"
+
+#. 64 bits.
+#: vms-alpha.c:6653
+#, c-format
+msgid "64 bits *unhandled*\n"
+msgstr "64 bits *chưa được nắm giữ*\n"
+
+#: vms-alpha.c:6657
+#, c-format
+msgid "class: %u, dtype: %u, length: %u, pointer: 0x%08x\n"
+msgstr "lá»›p: %u, dtype: %u, Ä‘á»™ dài: %u, con trá»: 0x%08x\n"
+
+#: vms-alpha.c:6668
+#, c-format
+msgid "non-contiguous array of %s\n"
+msgstr "mảng không kỠnhau của %s\n"
+
+#: vms-alpha.c:6672
+#, c-format
+msgid "dimct: %u, aflags: 0x%02x, digits: %u, scale: %u\n"
+msgstr "dimct: %u, aflags: 0x%02x, digits: %u, scale: %u\n"
+
+#: vms-alpha.c:6676
+#, c-format
+msgid "arsize: %u, a0: 0x%08x\n"
+msgstr "arsize: %u, a0: 0x%08x\n"
+
+#: vms-alpha.c:6680
+#, c-format
+msgid "Strides:\n"
+msgstr "Bước dài:\n"
+
+#: vms-alpha.c:6685
+#, c-format
+msgid "[%u]: %u\n"
+msgstr "[%u]: %u\n"
+
+#: vms-alpha.c:6690
+#, c-format
+msgid "Bounds:\n"
+msgstr "Các giới hạn:\n"
+
+#: vms-alpha.c:6695
+#, c-format
+msgid "[%u]: Lower: %u, upper: %u\n"
+msgstr "[%u]: thÆ°á»ng: %u, hoa: %u\n"
+
+#: vms-alpha.c:6707
+#, c-format
+msgid "unaligned bit-string of %s\n"
+msgstr "chuỗi-bit chưa được căn chỉnh của %s\n"
+
+#: vms-alpha.c:6711
+#, c-format
+msgid "base: %u, pos: %u\n"
+msgstr "cơ sở: %u, vịtrí: %u\n"
+
+#: vms-alpha.c:6731
+#, c-format
+msgid "vflags: 0x%02x, value: 0x%08x "
+msgstr "vflags: 0x%02x, giá trị: 0x%08x "
+
+#: vms-alpha.c:6737
+#, c-format
+msgid "(no value)\n"
+msgstr "(không có giá trị)\n"
+
+#: vms-alpha.c:6740
+#, c-format
+msgid "(not active)\n"
+msgstr "(không hoạt động)\n"
+
+#: vms-alpha.c:6743
+#, c-format
+msgid "(not allocated)\n"
+msgstr "(chưa được cấp phát)\n"
+
+#: vms-alpha.c:6746
+#, c-format
+msgid "(descriptor)\n"
+msgstr "(bộ mô tả)\n"
+
+#: vms-alpha.c:6750
+#, c-format
+msgid "(trailing value)\n"
+msgstr "(giá trị của dấu vết)\n"
+
+#: vms-alpha.c:6753
+#, c-format
+msgid "(value spec follows)\n"
+msgstr "(giá trị spec sau đây)\n"
+
+#: vms-alpha.c:6756
+#, c-format
+msgid "(at bit offset %u)\n"
+msgstr "(tại bít bù %u)\n"
+
+#: vms-alpha.c:6759
+#, c-format
+msgid "(reg: %u, disp: %u, indir: %u, kind: "
+msgstr "(reg: %u, disp: %u, indir: %u, kind: "
+
+#: vms-alpha.c:6766
+msgid "literal"
+msgstr "văn chương"
+
+#: vms-alpha.c:6769
+msgid "address"
+msgstr "địa chỉ"
+
+#: vms-alpha.c:6772
+msgid "desc"
+msgstr "desc"
+
+#: vms-alpha.c:6775
+msgid "reg"
+msgstr "reg"
+
+#: vms-alpha.c:6850
+#, c-format
+msgid "Debug symbol table:\n"
+msgstr "Bảng ký hiệu gỡ lỗi:\n"
+
+#: vms-alpha.c:6861
+#, c-format
+msgid "cannot read DST header\n"
+msgstr "không thể Ä‘á»c DST header\n"
+
+#: vms-alpha.c:6866
+#, c-format
+msgid " type: %3u, len: %3u (at 0x%08x): "
+msgstr " kiểu: %3u, dài: %3u (tại 0x%08x): "
+
+#: vms-alpha.c:6880
+#, c-format
+msgid "cannot read DST symbol\n"
+msgstr "không thể Ä‘á»c ký hiệu DST\n"
+
+#: vms-alpha.c:6923
+#, c-format
+msgid "standard data: %s\n"
+msgstr "dữ liệu chuẩn: %s\n"
+
+#: vms-alpha.c:6926 vms-alpha.c:7010
+#, c-format
+msgid " name: %.*s\n"
+msgstr " tên: %.*s\n"
+
+#: vms-alpha.c:6933
+#, c-format
+msgid "modbeg\n"
+msgstr "modbeg\n"
+
+#: vms-alpha.c:6934
+#, c-format
+msgid " flags: %d, language: %u, major: %u, minor: %u\n"
+msgstr " cá»: %d, ngôn ngữ: %u, số lá»›n: %u, số nhá»: %u\n"
+
+#: vms-alpha.c:6940 vms-alpha.c:7206
+#, c-format
+msgid " module name: %.*s\n"
+msgstr " tên mô-đun : %.*s\n"
+
+#: vms-alpha.c:6943
+#, c-format
+msgid " compiler : %.*s\n"
+msgstr " trình dịch : %.*s\n"
+
+#: vms-alpha.c:6948
+#, c-format
+msgid "modend\n"
+msgstr "modend\n"
+
+#: vms-alpha.c:6955
+msgid "rtnbeg\n"
+msgstr "rtnbeg\n"
+
+#: vms-alpha.c:6956
+#, c-format
+msgid " flags: %u, address: 0x%08x, pd-address: 0x%08x\n"
+msgstr " cá»: %u, địa chỉ: 0x%08x, địa chỉ pd: 0x%08x\n"
+
+#: vms-alpha.c:6961
+#, c-format
+msgid " routine name: %.*s\n"
+msgstr " tên thủ tục: %.*s\n"
+
+#: vms-alpha.c:6969
+#, c-format
+msgid "rtnend: size 0x%08x\n"
+msgstr "rtnend: kích thước 0x%08x\n"
+
+#: vms-alpha.c:6977
+#, c-format
+msgid "prolog: bkpt address 0x%08x\n"
+msgstr "prolog: địa chỉ bkpt 0x%08x\n"
+
+#: vms-alpha.c:6985
+#, c-format
+msgid "epilog: flags: %u, count: %u\n"
+msgstr "epilog: cá»: %u, số lượng: %u\n"
+
+#: vms-alpha.c:6994
+#, c-format
+msgid "blkbeg: address: 0x%08x, name: %.*s\n"
+msgstr "blkbeg: địa chỉ: 0x%08x, tên: %.*s\n"
+
+#: vms-alpha.c:7003
+#, c-format
+msgid "blkend: size: 0x%08x\n"
+msgstr "blkend: kích thước: 0x%08x\n"
+
+#: vms-alpha.c:7009
+#, c-format
+msgid "typspec (len: %u)\n"
+msgstr "typspec (dài: %u)\n"
+
+#: vms-alpha.c:7016
+#, c-format
+msgid "septyp, name: %.*s\n"
+msgstr "septyp, tên: %.*s\n"
+
+#: vms-alpha.c:7025
+#, c-format
+msgid "recbeg: name: %.*s\n"
+msgstr "recbeg: tên: %.*s\n"
+
+#: vms-alpha.c:7032
+#, c-format
+msgid "recend\n"
+msgstr "recend\n"
+
+#: vms-alpha.c:7035
+#, c-format
+msgid "enumbeg, len: %u, name: %.*s\n"
+msgstr "enumbeg, dài: %u, tên: %.*s\n"
+
+#: vms-alpha.c:7039
+#, c-format
+msgid "enumelt, name: %.*s\n"
+msgstr "enumelt, tên: %.*s\n"
+
+#: vms-alpha.c:7043
+#, c-format
+msgid "enumend\n"
+msgstr "enumend\n"
+
+#: vms-alpha.c:7060
+#, c-format
+msgid "discontiguous range (nbr: %u)\n"
+msgstr "vùng không tiếp giáp nhau (nbr: %u)\n"
+
+#: vms-alpha.c:7062
+#, c-format
+msgid " address: 0x%08x, size: %u\n"
+msgstr " địa chỉ: 0x%08x, kích thước: %u\n"
+
+#: vms-alpha.c:7072
+#, c-format
+msgid "line num (len: %u)\n"
+msgstr "số dòng (dài: %u)\n"
+
+#: vms-alpha.c:7089
+#, c-format
+msgid "delta_pc_w %u\n"
+msgstr "delta_pc_w %u\n"
+
+#: vms-alpha.c:7096
+#, c-format
+msgid "incr_linum(b): +%u\n"
+msgstr "incr_linum(b): +%u\n"
+
+#: vms-alpha.c:7102
+#, c-format
+msgid "incr_linum_w: +%u\n"
+msgstr "incr_linum_w: +%u\n"
+
+#: vms-alpha.c:7108
+#, c-format
+msgid "incr_linum_l: +%u\n"
+msgstr "incr_linum_l: +%u\n"
+
+#: vms-alpha.c:7114
+#, c-format
+msgid "set_line_num(w) %u\n"
+msgstr "set_line_num(w) %u\n"
+
+#: vms-alpha.c:7119
+#, c-format
+msgid "set_line_num_b %u\n"
+msgstr "set_line_num_b %u\n"
+
+#: vms-alpha.c:7124
+#, c-format
+msgid "set_line_num_l %u\n"
+msgstr "set_line_num_l %u\n"
+
+#: vms-alpha.c:7129
+#, c-format
+msgid "set_abs_pc: 0x%08x\n"
+msgstr "set_abs_pc: 0x%08x\n"
+
+#: vms-alpha.c:7133
+#, c-format
+msgid "delta_pc_l: +0x%08x\n"
+msgstr "delta_pc_l: +0x%08x\n"
+
+#: vms-alpha.c:7138
+#, c-format
+msgid "term(b): 0x%02x"
+msgstr "term(b): 0x%02x"
+
+#: vms-alpha.c:7140
+#, c-format
+msgid " pc: 0x%08x\n"
+msgstr " pc: 0x%08x\n"
+
+#: vms-alpha.c:7145
+#, c-format
+msgid "term_w: 0x%04x"
+msgstr "term_w: 0x%04x"
+
+#: vms-alpha.c:7147
+#, c-format
+msgid " pc: 0x%08x\n"
+msgstr " pc: 0x%08x\n"
+
+#: vms-alpha.c:7153
+#, c-format
+msgid "delta pc +%-4d"
+msgstr "delta pc +%-4d"
+
+#: vms-alpha.c:7156
+#, c-format
+msgid " pc: 0x%08x line: %5u\n"
+msgstr " pc: 0x%08x line: %5u\n"
+
+#: vms-alpha.c:7161
+#, c-format
+msgid " *unhandled* cmd %u\n"
+msgstr " cmd (lệnh) *chưa được cầm* %u\n"
+
+#: vms-alpha.c:7176
+#, c-format
+msgid "source (len: %u)\n"
+msgstr "nguồn (dài: %u)\n"
+
+#: vms-alpha.c:7190
+#, c-format
+msgid " declfile: len: %u, flags: %u, fileid: %u\n"
+msgstr " declfile: len: %u, cá»: %u, fileid: %u\n"
+
+#: vms-alpha.c:7194
+#, c-format
+msgid " rms: cdt: 0x%08x %08x, ebk: 0x%08x, ffb: 0x%04x, rfo: %u\n"
+msgstr " rms: cdt: 0x%08x %08x, ebk: 0x%08x, ffb: 0x%04x, rfo: %u\n"
+
+#: vms-alpha.c:7203
+#, c-format
+msgid " filename : %.*s\n"
+msgstr " tên tập tin : %.*s\n"
+
+#: vms-alpha.c:7212
+#, c-format
+msgid " setfile %u\n"
+msgstr " setfile %u\n"
+
+#: vms-alpha.c:7217 vms-alpha.c:7222
+#, c-format
+msgid " setrec %u\n"
+msgstr " setrec %u\n"
+
+#: vms-alpha.c:7227 vms-alpha.c:7232
+#, c-format
+msgid " setlnum %u\n"
+msgstr " setlnum %u\n"
+
+#: vms-alpha.c:7237 vms-alpha.c:7242
+#, c-format
+msgid " deflines %u\n"
+msgstr " deflines %u\n"
+
+#: vms-alpha.c:7246
+#, c-format
+msgid " formfeed\n"
+msgstr " formfeed\n"
+
+#: vms-alpha.c:7250
+#, c-format
+msgid " *unhandled* cmd %u\n"
+msgstr " cmd (lệnh) *chưa được cầm* %u\n"
+
+#: vms-alpha.c:7262
+#, c-format
+msgid "*unhandled* dst type %u\n"
+msgstr "kiểu dst *chưa được cầm* %u\n"
+
+#: vms-alpha.c:7294
+#, c-format
+msgid "cannot read EIHD\n"
+msgstr "không thể Ä‘á»c EIHD\n"
+
+#: vms-alpha.c:7297
+#, c-format
+msgid "EIHD: (size: %u, nbr blocks: %u)\n"
+msgstr "EIHD: (kích thước: %u, khối nbr: %u)\n"
+
+#: vms-alpha.c:7300
+#, c-format
+msgid " majorid: %u, minorid: %u\n"
+msgstr " sốlá»›n: %u, sốnhá»: %u\n"
+
+#: vms-alpha.c:7308
+msgid "executable"
+msgstr "có thể thực thi"
+
+#: vms-alpha.c:7311
+msgid "linkable image"
+msgstr "ảnh có thể liên kết"
+
+#: vms-alpha.c:7317
+#, c-format
+msgid " image type: %u (%s)"
+msgstr " kiểu ảnh: %u (%s)"
+
+#: vms-alpha.c:7323
+msgid "native"
+msgstr "tự nhiên"
+
+#: vms-alpha.c:7326
+msgid "CLI"
+msgstr "CLI"
+
+#: vms-alpha.c:7332
+#, c-format
+msgid ", subtype: %u (%s)\n"
+msgstr ", kiểucon: %u (%s)\n"
+
+#: vms-alpha.c:7338
+#, c-format
+msgid " offsets: isd: %u, activ: %u, symdbg: %u, imgid: %u, patch: %u\n"
+msgstr " khoảng bù: isd: %u, activ: %u, symdbg: %u, imgid: %u, vá: %u\n"
+
+#: vms-alpha.c:7342
+#, c-format
+msgid " fixup info rva: "
+msgstr " sửa thông tin rva: "
+
+#: vms-alpha.c:7344
+#, c-format
+msgid ", symbol vector rva: "
+msgstr ", véc-tơ ký hiệu rva: "
+
+#: vms-alpha.c:7347
+#, c-format
+msgid ""
+"\n"
+" version array off: %u\n"
+msgstr ""
+"\n"
+" mảng phiên bản vị tắt: %u\n"
+
+#: vms-alpha.c:7351
+#, c-format
+msgid " img I/O count: %u, nbr channels: %u, req pri: %08x%08x\n"
+msgstr " số lượng img V/R: %u, các kênh nbr: %u, req pri: %08x%08x\n"
+
+#: vms-alpha.c:7357
+#, c-format
+msgid " linker flags: %08x:"
+msgstr " cỠliên kết: %08x:"
+
+#: vms-alpha.c:7387
+#, c-format
+msgid " ident: 0x%08x, sysver: 0x%08x, match ctrl: %u, symvect_size: %u\n"
+msgstr " ident: 0x%08x, sysver: 0x%08x, match ctrl: %u, symvect_size: %u\n"
+
+#: vms-alpha.c:7393
+#, c-format
+msgid " BPAGE: %u"
+msgstr " BPAGE: %u"
+
+#: vms-alpha.c:7399
+#, c-format
+msgid ", ext fixup offset: %u, no_opt psect off: %u"
+msgstr ", khoảng bù sửa chữa ext: %u, no_opt psect tắt: %u"
+
+#: vms-alpha.c:7402
+#, c-format
+msgid ", alias: %u\n"
+msgstr ", bí danh: %u\n"
+
+#: vms-alpha.c:7410
+#, c-format
+msgid "system version array information:\n"
+msgstr "thông tin vỠphiên bản của mảng từ hệ thống\n"
+
+#: vms-alpha.c:7414
+#, c-format
+msgid "cannot read EIHVN header\n"
+msgstr "không thể Ä‘á»c EIHVN header\n"
+
+#: vms-alpha.c:7424
+#, c-format
+msgid "cannot read EIHVN version\n"
+msgstr "không thể Ä‘á»c phiên bản EIHVN\n"
+
+#: vms-alpha.c:7427
+#, c-format
+msgid " %02u "
+msgstr " %02u "
+
+#: vms-alpha.c:7431
+msgid "BASE_IMAGE "
+msgstr "BASE_IMAGE "
+
+#: vms-alpha.c:7434
+msgid "MEMORY_MANAGEMENT"
+msgstr "MEMORY_MANAGEMENT"
+
+#: vms-alpha.c:7437
+msgid "IO "
+msgstr "VR"
+
+#: vms-alpha.c:7440
+msgid "FILES_VOLUMES "
+msgstr "FILES_VOLUMES "
+
+#: vms-alpha.c:7443
+msgid "PROCESS_SCHED "
+msgstr "PROCESS_SCHED "
+
+#: vms-alpha.c:7446
+msgid "SYSGEN "
+msgstr "SYSGEN "
+
+#: vms-alpha.c:7449
+msgid "CLUSTERS_LOCKMGR "
+msgstr "CLUSTERS_LOCKMGR "
+
+#: vms-alpha.c:7452
+msgid "LOGICAL_NAMES "
+msgstr "LOGICAL_NAMES "
+
+#: vms-alpha.c:7455
+msgid "SECURITY "
+msgstr "SECURITY "
+
+#: vms-alpha.c:7458
+msgid "IMAGE_ACTIVATOR "
+msgstr "IMAGE_ACTIVATOR "
+
+#: vms-alpha.c:7461
+msgid "NETWORKS "
+msgstr "NETWORKS "
+
+#: vms-alpha.c:7464
+msgid "COUNTERS "
+msgstr "COUNTERS "
+
+#: vms-alpha.c:7467
+msgid "STABLE "
+msgstr "STABLE "
+
+#: vms-alpha.c:7470
+msgid "MISC "
+msgstr "MISC "
+
+#: vms-alpha.c:7473
+msgid "CPU "
+msgstr "CPU "
+
+#: vms-alpha.c:7476
+msgid "VOLATILE "
+msgstr "VOLATILE "
+
+#: vms-alpha.c:7479
+msgid "SHELL "
+msgstr "SHELL "
+
+#: vms-alpha.c:7482
+msgid "POSIX "
+msgstr "POSIX "
+
+#: vms-alpha.c:7485
+msgid "MULTI_PROCESSING "
+msgstr "MULTI_PROCESSING "
+
+#: vms-alpha.c:7488
+msgid "GALAXY "
+msgstr "GALAXY "
+
+#: vms-alpha.c:7491
+msgid "*unknown* "
+msgstr "• không rõ •"
+
+#: vms-alpha.c:7494
+#, c-format
+msgid ": %u.%u\n"
+msgstr ": %u.%u\n"
+
+#: vms-alpha.c:7507 vms-alpha.c:7766
+#, c-format
+msgid "cannot read EIHA\n"
+msgstr "không thể Ä‘á»c EIHA\n"
+
+#: vms-alpha.c:7510
+#, c-format
+msgid "Image activation: (size=%u)\n"
+msgstr "Hoạt hóa ảnh: (kích thước=%u)\n"
+
+#: vms-alpha.c:7512
+#, c-format
+msgid " First address : 0x%08x 0x%08x\n"
+msgstr " Äịa chỉ đầu tiên : 0x%08x 0x%08x\n"
+
+#: vms-alpha.c:7515
+#, c-format
+msgid " Second address: 0x%08x 0x%08x\n"
+msgstr "Äịa chỉ thứ hai: 0x%08x 0x%08x\n"
+
+#: vms-alpha.c:7518
+#, c-format
+msgid " Third address : 0x%08x 0x%08x\n"
+msgstr "Äịa chỉ thứ ba : 0x%08x 0x%08x\n"
+
+#: vms-alpha.c:7521
+#, c-format
+msgid " Fourth address: 0x%08x 0x%08x\n"
+msgstr "Äịa chỉ thứ tÆ°: 0x%08x 0x%08x\n"
+
+#: vms-alpha.c:7524
+#, c-format
+msgid " Shared image : 0x%08x 0x%08x\n"
+msgstr "Ảnh được chia sẻ : 0x%08x 0x%08x\n"
+
+#: vms-alpha.c:7535
+#, c-format
+msgid "cannot read EIHI\n"
+msgstr "không thể Ä‘á»c EIHI\n"
+
+#: vms-alpha.c:7538
+#, c-format
+msgid "Image identification: (major: %u, minor: %u)\n"
+msgstr "Äịnh danh ảnh: (số lá»›n: %u, số nhá»: %u)\n"
+
+#: vms-alpha.c:7541
+#, c-format
+msgid " image name : %.*s\n"
+msgstr " tên ảnh : %.*s\n"
+
+#: vms-alpha.c:7543
+#, c-format
+msgid " link time : %s\n"
+msgstr " thá»i gian liên kết : %s\n"
+
+#: vms-alpha.c:7545
+#, c-format
+msgid " image ident : %.*s\n"
+msgstr " ident ảnh : %.*s\n"
+
+#: vms-alpha.c:7547
+#, c-format
+msgid " linker ident : %.*s\n"
+msgstr " ident bộ liên kết : %.*s\n"
+
+#: vms-alpha.c:7549
+#, c-format
+msgid " image build ident: %.*s\n"
+msgstr " ident dựng ảnh: %.*s\n"
+
+#: vms-alpha.c:7559
+#, c-format
+msgid "cannot read EIHS\n"
+msgstr "không thể Ä‘á»c EIHS\n"
+
+#: vms-alpha.c:7562
+#, c-format
+msgid "Image symbol & debug table: (major: %u, minor: %u)\n"
+msgstr "Ký hiệu ảnh & bảng gỡ lá»—i: (sốlá»›n: %u, sốnhá»: %u)\n"
+
+#: vms-alpha.c:7567
+#, c-format
+msgid " debug symbol table : vbn: %u, size: %u (0x%x)\n"
+msgstr " gỡ lỗi bảng ký hiệu : vbn: %u, kích thước: %u (0x%x)\n"
+
+#: vms-alpha.c:7571
+#, c-format
+msgid " global symbol table: vbn: %u, records: %u\n"
+msgstr " bảng ký hiệu toàn cục: vbn: %u, bản ghi: %u\n"
+
+#: vms-alpha.c:7575
+#, c-format
+msgid " debug module table : vbn: %u, size: %u\n"
+msgstr " gỡ lỗi bảng mô-đun : vbn: %u, kích thước: %u\n"
+
+#: vms-alpha.c:7588
+#, c-format
+msgid "cannot read EISD\n"
+msgstr "không thể Ä‘á»c EISD\n"
+
+#: vms-alpha.c:7598
+#, c-format
+msgid "Image section descriptor: (major: %u, minor: %u, size: %u, offset: %u)\n"
+msgstr "Bá»™ mô tả phần ảnh: (số lá»›n: %u, số nhá»: %u, kích thÆ°á»›c: %u, khoảng bù: %u)\n"
+
+#: vms-alpha.c:7605
+#, c-format
+msgid " section: base: 0x%08x%08x size: 0x%08x\n"
+msgstr " phần: base: 0x%08x%08x kích thước: 0x%08x\n"
+
+#: vms-alpha.c:7610
+#, c-format
+msgid " flags: 0x%04x"
+msgstr " các cá»: 0x%04x"
+
+#: vms-alpha.c:7647
+#, c-format
+msgid " vbn: %u, pfc: %u, matchctl: %u type: %u ("
+msgstr " vbn: %u, pfc: %u, matchctl: %u kiểu: %u ("
+
+#: vms-alpha.c:7653
+msgid "NORMAL"
+msgstr "BÌNH-THƯỜNG"
+
+#: vms-alpha.c:7656
+msgid "SHRFXD"
+msgstr "SHRFXD"
+
+#: vms-alpha.c:7659
+msgid "PRVFXD"
+msgstr "PRVFXD"
+
+#: vms-alpha.c:7662
+msgid "SHRPIC"
+msgstr "SHRPIC"
+
+#: vms-alpha.c:7665
+msgid "PRVPIC"
+msgstr "PRVPIC"
+
+#: vms-alpha.c:7668
+msgid "USRSTACK"
+msgstr "USRSTACK"
+
+#: vms-alpha.c:7676
+#, c-format
+msgid " ident: 0x%08x, name: %.*s\n"
+msgstr " ident: 0x%08x, tên: %.*s\n"
+
+#: vms-alpha.c:7686
+#, c-format
+msgid "cannot read DMT\n"
+msgstr "không thể Ä‘á»c DMT\n"
+
+#: vms-alpha.c:7690
+#, c-format
+msgid "Debug module table:\n"
+msgstr "Bảng gỡ lỗi mô-đun:\n"
+
+#: vms-alpha.c:7699
+#, c-format
+msgid "cannot read DMT header\n"
+msgstr "không thể Ä‘á»c DMT header\n"
+
+#: vms-alpha.c:7704
+#, c-format
+msgid " module offset: 0x%08x, size: 0x%08x, (%u psects)\n"
+msgstr " khoảng bù mô-đun: 0x%08x, kích thước: 0x%08x, (%u psects)\n"
+
+#: vms-alpha.c:7714
+#, c-format
+msgid "cannot read DMT psect\n"
+msgstr "không thể Ä‘á»c DMT psect\n"
+
+#: vms-alpha.c:7717
+#, c-format
+msgid " psect start: 0x%08x, length: %u\n"
+msgstr " psect bắt đầu: 0x%08x, độ dài: %u\n"
+
+#: vms-alpha.c:7730
+#, c-format
+msgid "cannot read DST\n"
+msgstr "không thể Ä‘á»c DST\n"
+
+#: vms-alpha.c:7740
+#, c-format
+msgid "cannot read GST\n"
+msgstr "không thể Ä‘á»c GST\n"
+
+#: vms-alpha.c:7744
+#, c-format
+msgid "Global symbol table:\n"
+msgstr "Bảng ký hiệu toàn cục: \n"
+
+#: vms-alpha.c:7772
+#, c-format
+msgid "Image activator fixup: (major: %u, minor: %u)\n"
+msgstr "Sá»­a chữa ảnh hoạt Ä‘á»™ng: (sốlá»›n: %u, sốnhá»: %u)\n"
+
+#: vms-alpha.c:7775
+#, c-format
+msgid " iaflink : 0x%08x %08x\n"
+msgstr " iaflink : 0x%08x %08x\n"
+
+#: vms-alpha.c:7778
+#, c-format
+msgid " fixuplnk: 0x%08x %08x\n"
+msgstr " fixuplnk: 0x%08x %08x\n"
+
+#: vms-alpha.c:7781
+#, c-format
+msgid " size : %u\n"
+msgstr " kích thước : %u\n"
+
+#: vms-alpha.c:7783
+#, c-format
+msgid " flags: 0x%08x\n"
+msgstr " các cá»: 0x%08x\n"
+
+#: vms-alpha.c:7787
+#, c-format
+msgid " qrelfixoff: %5u, lrelfixoff: %5u\n"
+msgstr " qrelfixoff: %5u, lrelfixoff: %5u\n"
+
+#: vms-alpha.c:7791
+#, c-format
+msgid " qdotadroff: %5u, ldotadroff: %5u\n"
+msgstr " qdotadroff: %5u, ldotadroff: %5u\n"
+
+#: vms-alpha.c:7795
+#, c-format
+msgid " codeadroff: %5u, lpfixoff : %5u\n"
+msgstr " codeadroff: %5u, lpfixoff : %5u\n"
+
+#: vms-alpha.c:7798
+#, c-format
+msgid " chgprtoff : %5u\n"
+msgstr " chgprtoff : %5u\n"
+
+#: vms-alpha.c:7801
+#, c-format
+msgid " shlstoff : %5u, shrimgcnt : %5u\n"
+msgstr " shlstoff : %5u, shrimgcnt : %5u\n"
+
+#: vms-alpha.c:7803
+#, c-format
+msgid " shlextra : %5u, permctx : %5u\n"
+msgstr " shlextra : %5u, permctx : %5u\n"
+
+#: vms-alpha.c:7806
+#, c-format
+msgid " base_va : 0x%08x\n"
+msgstr " base_va : 0x%08x\n"
+
+#: vms-alpha.c:7808
+#, c-format
+msgid " lppsbfixoff: %5u\n"
+msgstr " lppsbfixoff: %5u\n"
+
+#: vms-alpha.c:7816
+#, c-format
+msgid " Shareable images:\n"
+msgstr "Ảnh có thể chia sẻ:\n"
+
+#: vms-alpha.c:7820
+#, c-format
+msgid " %u: size: %u, flags: 0x%02x, name: %.*s\n"
+msgstr " %u: kích thÆ°á»›c: %u, cá»: 0x%02x, tên: %.*s\n"
+
+#: vms-alpha.c:7827
+#, c-format
+msgid " quad-word relocation fixups:\n"
+msgstr " sửa chữa tái định vị quad-word (bốn từ):\n"
+
+#: vms-alpha.c:7832
+#, c-format
+msgid " long-word relocation fixups:\n"
+msgstr " sửa chữa tái định vị long-word (hai từ):\n"
+
+#: vms-alpha.c:7837
+#, c-format
+msgid " quad-word .address reference fixups:\n"
+msgstr " sửa chữa tham chiếu .địachỉ quad-word (bốn từ):\n"
+
+#: vms-alpha.c:7842
+#, c-format
+msgid " long-word .address reference fixups:\n"
+msgstr " sửa chữa tham chiếu .địachỉ long-word (hai từ):\n"
+
+#: vms-alpha.c:7847
+#, c-format
+msgid " Code Address Reference Fixups:\n"
+msgstr " Sửa chữa tham chiếu địa chỉ mã:\n"
+
+#: vms-alpha.c:7852
+#, c-format
+msgid " Linkage Pairs Referece Fixups:\n"
+msgstr "Sửa chữ Tham chiếu Liên kết cặp:\n"
+
+#: vms-alpha.c:7861
+#, c-format
+msgid " Change Protection (%u entries):\n"
+msgstr " Bảo vệ Thay đổi (%u mục):\n"
+
+#: vms-alpha.c:7866
+#, c-format
+msgid " base: 0x%08x %08x, size: 0x%08x, prot: 0x%08x "
+msgstr " ná»n: 0x%08x %08x, kích thÆ°á»›c: 0x%08x, prot: 0x%08x "
+
+#. FIXME: we do not yet support relocatable link. It is not obvious
+#. how to do it for debug infos.
+#: vms-alpha.c:8706
+msgid "%P: relocatable link is not supported\n"
+msgstr "%P: liên kết có khả năng tái định vị không được hỗ trợ\n"
+
+#: vms-alpha.c:8776
+msgid "%P: multiple entry points: in modules %B and %B\n"
+msgstr "%P: chỉ vào nhiá»u Ä‘iểm: trong mô-Ä‘un %B và %B\n"
+
+#: vms-lib.c:1423
+#, c-format
+msgid "could not open shared image '%s' from '%s'"
+msgstr "không thể mở ảnh được chia sẻ '%s' từ '%s'"
+
+#: vms-misc.c:360
+msgid "_bfd_vms_output_counted called with zero bytes"
+msgstr "_bfd_vms_output_counted được gá»i vá»›i số không byte"
+
+#: vms-misc.c:365
+msgid "_bfd_vms_output_counted called with too many bytes"
+msgstr "_bfd_vms_output_counted được gá»i vá»›i quá nhiá»u byte"
+
+#: xcofflink.c:836
+#, c-format
+msgid "%s: XCOFF shared object when not producing XCOFF output"
+msgstr "%s: có đối tượng dùng chung XCOFF khi không xuất dữ liệu XCOFF"
+
+#: xcofflink.c:857
+#, c-format
+msgid "%s: dynamic object with no .loader section"
+msgstr "%s đối tượng động không có phần .loader"
+
+#: xcofflink.c:1416
+msgid "%B: `%s' has line numbers but no enclosing section"
+msgstr "%B: \"%s\" có số thứ tá»± dòng mà không có phần bao bá»c"
+
+#: xcofflink.c:1468
+msgid "%B: class %d symbol `%s' has no aux entries"
+msgstr "%B: hạng %d ký hiệu \"%s\" không có mục nhập phụ"
+
+#: xcofflink.c:1490
+msgid "%B: symbol `%s' has unrecognized csect type %d"
+msgstr "%B: ký hiệu \"%s\" có kiểu csect không được nhận ra %d"
+
+#: xcofflink.c:1502
+msgid "%B: bad XTY_ER symbol `%s': class %d scnum %d scnlen %d"
+msgstr "%B: ký hiệu XTY_ER sai \"%s\" hạng %d scnum %d scnlen %d"
+
+#: xcofflink.c:1531
+msgid "%B: XMC_TC0 symbol `%s' is class %d scnlen %d"
+msgstr "%B: ký hiệu XMC_TC0 \"%s\" là hạng %d scnlen %d"
+
+#: xcofflink.c:1677
+msgid "%B: csect `%s' not in enclosing section"
+msgstr "%B: csect \"%s\" không phải trong phần bao bá»c"
+
+#: xcofflink.c:1784
+msgid "%B: misplaced XTY_LD `%s'"
+msgstr "%B: không đúng chỗ XTY_LD \"%s\""
+
+#: xcofflink.c:2103
+msgid "%B: reloc %s:%d not in csect"
+msgstr "%B: định vị lại %s:%d không phải trong csect"
+
+#: xcofflink.c:3194
+#, c-format
+msgid "%s: no such symbol"
+msgstr "%s: không có ký hiệu như vậy"
+
+#: xcofflink.c:3299
+#, c-format
+msgid "warning: attempt to export undefined symbol `%s'"
+msgstr "cảnh báo: thử xuất ký hiệu chưa được xác định \"%s\""
+
+#: xcofflink.c:3678
+msgid "error: undefined symbol __rtinit"
+msgstr "lỗi: chưa xác định ký hiệu __rtinit"
+
+#: xcofflink.c:4057
+msgid "%B: loader reloc in unrecognized section `%s'"
+msgstr "%B: gặp sự định vị lại bộ nạp trong phần không được nhận ra \"%s\""
+
+#: xcofflink.c:4068
+msgid "%B: `%s' in loader reloc but not loader sym"
+msgstr "%B: \"%s\" trong định vị lại bá»™ nạp nhÆ°ng không phải liên kết má»m đến bá»™ nạp"
+
+#: xcofflink.c:4084
+msgid "%B: loader reloc in read-only section %A"
+msgstr "%B: định vị lại bá»™ nạp trong phần chỉ Ä‘á»c %A"
+
+#: xcofflink.c:5106
+#, c-format
+msgid "TOC overflow: 0x%lx > 0x10000; try -mminimal-toc when compiling"
+msgstr "Tràn TOC: 0x%lx > 0x10000; hãy thử \"-mminimal-toc\" khi biên dịch"
+
+#: elf32-ia64.c:628 elf64-ia64.c:628
+msgid "%B: Can't relax br at 0x%lx in section `%A'. Please use brl or indirect branch."
+msgstr "%B: Không thể giảm nhẹ br ở 0x%lx trong phần \"%A\". Hãy dùng brl hoặc nhánh gián tiếp."
+
+#: elf32-ia64.c:2284 elf64-ia64.c:2284
+msgid "@pltoff reloc against local symbol"
+msgstr "định vị lại @pltoff so với ký hiệu cục bộ"
+
+#: elf32-ia64.c:3687 elf64-ia64.c:3687
+#, c-format
+msgid "%s: short data segment overflowed (0x%lx >= 0x400000)"
+msgstr "%s: tràn đoạn dữ liệu ngắn (0x%lx ≥ 0x400000)"
+
+#: elf32-ia64.c:3698 elf64-ia64.c:3698
+#, c-format
+msgid "%s: __gp does not cover short data segment"
+msgstr "%s: __gp không trải ra đoạn dữ liệu ngắn"
+
+#: elf32-ia64.c:3965 elf64-ia64.c:3965
+msgid "%B: non-pic code with imm relocation against dynamic symbol `%s'"
+msgstr "%B: mã khác pic với định vị lại imm so với ký hiệu động \"%s\""
+
+#: elf32-ia64.c:4032 elf64-ia64.c:4032
+msgid "%B: @gprel relocation against dynamic symbol %s"
+msgstr "%B: định vị lại @gprel so với ký hiệu động \"%s\""
+
+#: elf32-ia64.c:4095 elf64-ia64.c:4095
+msgid "%B: linking non-pic code in a position independent executable"
+msgstr "%B: đang liên kết mã khác pin trong một tập tin có khả năng thực hiện mà không phụ thuộc vào vị trí"
+
+#: elf32-ia64.c:4232 elf64-ia64.c:4232
+msgid "%B: @internal branch to dynamic symbol %s"
+msgstr "%B: nhánh @internal (nội bộ) tới ký hiệu động %s"
+
+#: elf32-ia64.c:4234 elf64-ia64.c:4234
+msgid "%B: speculation fixup to dynamic symbol %s"
+msgstr "%B: sự sửa chữa suy đoán so với ký hiệu động %s"
+
+#: elf32-ia64.c:4236 elf64-ia64.c:4236
+msgid "%B: @pcrel relocation against dynamic symbol %s"
+msgstr "%B: định vị lại @pcrel so với ký hiệu động %s"
+
+#: elf32-ia64.c:4433 elf64-ia64.c:4433
+msgid "unsupported reloc"
+msgstr "định vị lại không được hỗ trợ"
+
+#: elf32-ia64.c:4471 elf64-ia64.c:4471
+msgid "%B: missing TLS section for relocation %s against `%s' at 0x%lx in section `%A'."
+msgstr "%B: thiếu phần TLS để định vị lại %s đối với \"%s\" ở 0x%lx trong phần \"%A\"."
+
+#: elf32-ia64.c:4486 elf64-ia64.c:4486
+msgid "%B: Can't relax br (%s) to `%s' at 0x%lx in section `%A' with size 0x%lx (> 0x1000000)."
+msgstr "%B: Không thể giảm nhẹ br (%s) tới \"%s\" tại 0x%lx trong phần \"%A\" với kích cỡ 0x%lx (> 0x1000000)."
+
+#: elf32-ia64.c:4748 elf64-ia64.c:4748
+msgid "%B: linking trap-on-NULL-dereference with non-trapping files"
+msgstr "%B: đang liên kết trap-on-NULL-dereference với tập tin không đặt bẫy"
+
+#: elf32-ia64.c:4757 elf64-ia64.c:4757
+msgid "%B: linking big-endian files with little-endian files"
+msgstr "%B: Ä‘ang liên kết tập tin vá» cuối lá»›n vá»›i tập tin vá» cuối nhá»"
+
+#: elf32-ia64.c:4766 elf64-ia64.c:4766
+msgid "%B: linking 64-bit files with 32-bit files"
+msgstr "%B: đang liên kết tập tin 64-bit với tập tin 32-bit"
+
+#: elf32-ia64.c:4775 elf64-ia64.c:4775
+msgid "%B: linking constant-gp files with non-constant-gp files"
+msgstr "%B: đang liên kết tập tin constant-gp với tập tin non-constant-gp"
+
+#: elf32-ia64.c:4785 elf64-ia64.c:4785
+msgid "%B: linking auto-pic files with non-auto-pic files"
+msgstr "%B: đang liên kết tập tin auto-pic với tập tin non-auto-pic"
+
+#: peigen.c:1002 pepigen.c:1002 pex64igen.c:1002
+#, c-format
+msgid "%s: line number overflow: 0x%lx > 0xffff"
+msgstr "%s: tràn số thứ tự dòng: 0x%lx > 0xffff"
+
+#: peigen.c:1029 pepigen.c:1029 pex64igen.c:1029
+msgid "Export Directory [.edata (or where ever we found it)]"
+msgstr "Thư mục Xuất [.edata (hoặc ở nơi nào chúng ta đã tìm nó)]"
+
+#: peigen.c:1030 pepigen.c:1030 pex64igen.c:1030
+msgid "Import Directory [parts of .idata]"
+msgstr "Thư mục Nhập [các phần của .idata]"
+
+#: peigen.c:1031 pepigen.c:1031 pex64igen.c:1031
+msgid "Resource Directory [.rsrc]"
+msgstr "Thư mục Tài nguyên [.rsrc]"
+
+#: peigen.c:1032 pepigen.c:1032 pex64igen.c:1032
+msgid "Exception Directory [.pdata]"
+msgstr "Thư mục Ngoại lệ [.pdata]"
+
+#: peigen.c:1033 pepigen.c:1033 pex64igen.c:1033
+msgid "Security Directory"
+msgstr "Thư mục Bảo mật"
+
+#: peigen.c:1034 pepigen.c:1034 pex64igen.c:1034
+msgid "Base Relocation Directory [.reloc]"
+msgstr "ThÆ° mục Äịnh vị lại CÆ¡ bản [.reloc]"
+
+#: peigen.c:1035 pepigen.c:1035 pex64igen.c:1035
+msgid "Debug Directory"
+msgstr "Thư mục Gỡ lỗi"
+
+#: peigen.c:1036 pepigen.c:1036 pex64igen.c:1036
+msgid "Description Directory"
+msgstr "Thư mục Mô tả"
+
+#: peigen.c:1037 pepigen.c:1037 pex64igen.c:1037
+msgid "Special Directory"
+msgstr "ThÆ° mục Äặc biệt"
+
+#: peigen.c:1038 pepigen.c:1038 pex64igen.c:1038
+msgid "Thread Storage Directory [.tls]"
+msgstr "Thư mục Lưu trữ Mạch [.tls]"
+
+#: peigen.c:1039 pepigen.c:1039 pex64igen.c:1039
+msgid "Load Configuration Directory"
+msgstr "Thư mục Cấu hình Nạp"
+
+#: peigen.c:1040 pepigen.c:1040 pex64igen.c:1040
+msgid "Bound Import Directory"
+msgstr "ThÆ° mục Nhập đã Äóng kết"
+
+#: peigen.c:1041 pepigen.c:1041 pex64igen.c:1041
+msgid "Import Address Table Directory"
+msgstr "ThÆ° mục Bảng Äịa chỉ Nhập"
+
+#: peigen.c:1042 pepigen.c:1042 pex64igen.c:1042
+msgid "Delay Import Directory"
+msgstr "Thư mục Nhập Hoãn"
+
+#: peigen.c:1043 pepigen.c:1043 pex64igen.c:1043
+msgid "CLR Runtime Header"
+msgstr "Phần đầu Lúc chạy CLR"
+
+#: peigen.c:1044 pepigen.c:1044 pex64igen.c:1044
+msgid "Reserved"
+msgstr "Dành riêng"
+
+#: peigen.c:1104 pepigen.c:1104 pex64igen.c:1104
+#, c-format
+msgid ""
+"\n"
+"There is an import table, but the section containing it could not be found\n"
+msgstr ""
+"\n"
+"Có một bảng nhập, nhưng không tìm thấy phần chứa nó\n"
+
+#: peigen.c:1109 pepigen.c:1109 pex64igen.c:1109
+#, c-format
+msgid ""
+"\n"
+"There is an import table in %s at 0x%lx\n"
+msgstr ""
+"\n"
+"Có một bảng nhập trong %s tại 0x%lx\n"
+
+#: peigen.c:1151 pepigen.c:1151 pex64igen.c:1151
+#, c-format
+msgid ""
+"\n"
+"Function descriptor located at the start address: %04lx\n"
+msgstr ""
+"\n"
+"Bộ mô tả hàm được tìm tại địa chỉ đầu: %04lx\n"
+
+#: peigen.c:1154 pepigen.c:1154 pex64igen.c:1154
+#, c-format
+msgid "\tcode-base %08lx toc (loadable/actual) %08lx/%08lx\n"
+msgstr "\tcơ bản mã %08lx toc (nạp được/thật) %08lx/%08lx\n"
+
+#: peigen.c:1162 pepigen.c:1162 pex64igen.c:1162
+#, c-format
+msgid ""
+"\n"
+"No reldata section! Function descriptor not decoded.\n"
+msgstr ""
+"\n"
+"Không có phần reldata ! Vì thế chưa giải mã bộ mô tả hàm.\n"
+
+#: peigen.c:1167 pepigen.c:1167 pex64igen.c:1167
+#, c-format
+msgid ""
+"\n"
+"The Import Tables (interpreted %s section contents)\n"
+msgstr ""
+"\n"
+"Các Bảng Nhập (phiên dịch %s nội dung phần)\n"
+
+#: peigen.c:1170 pepigen.c:1170 pex64igen.c:1170
+#, c-format
+msgid ""
+" vma: Hint Time Forward DLL First\n"
+" Table Stamp Chain Name Thunk\n"
+msgstr ""
+" vma: Gợi ý Giá» Tiếp DLL Äầu\n"
+" Bảng Nhãn Dây Tên Thunk\n"
+
+#: peigen.c:1218 pepigen.c:1218 pex64igen.c:1218
+#, c-format
+msgid ""
+"\n"
+"\tDLL Name: %s\n"
+msgstr ""
+"\n"
+"\tTên DLL: %s\n"
+
+#: peigen.c:1229 pepigen.c:1229 pex64igen.c:1229
+#, c-format
+msgid "\tvma: Hint/Ord Member-Name Bound-To\n"
+msgstr "\tvma: Gợi_ý/Thứ_tá»± Tên_thành_viên Äóng_kết_vá»›i\n"
+
+#: peigen.c:1254 pepigen.c:1254 pex64igen.c:1254
+#, c-format
+msgid ""
+"\n"
+"There is a first thunk, but the section containing it could not be found\n"
+msgstr ""
+"\n"
+"Có một thunk đầu tiên, nhưng không tìm thấy phần chứa nó\n"
+
+#: peigen.c:1415 pepigen.c:1415 pex64igen.c:1415
+#, c-format
+msgid ""
+"\n"
+"There is an export table, but the section containing it could not be found\n"
+msgstr ""
+"\n"
+"Có một bảng xuất, nhưng không tìm thấy phần chứa nó\n"
+
+#: peigen.c:1424 pepigen.c:1424 pex64igen.c:1424
+#, c-format
+msgid ""
+"\n"
+"There is an export table in %s, but it does not fit into that section\n"
+msgstr ""
+"\n"
+"Có một bảng xuất trong %s, nhưng nó không vừa trong phần đó\n"
+
+#: peigen.c:1430 pepigen.c:1430 pex64igen.c:1430
+#, c-format
+msgid ""
+"\n"
+"There is an export table in %s at 0x%lx\n"
+msgstr ""
+"\n"
+"Có một bảng xuất trong %s tại 0x%lx\n"
+
+#: peigen.c:1458 pepigen.c:1458 pex64igen.c:1458
+#, c-format
+msgid ""
+"\n"
+"The Export Tables (interpreted %s section contents)\n"
+"\n"
+msgstr ""
+"\n"
+"Các Bảng Xuất (phiên dịch %s nội dung phần)\n"
+
+#: peigen.c:1462 pepigen.c:1462 pex64igen.c:1462
+#, c-format
+msgid "Export Flags \t\t\t%lx\n"
+msgstr "CỠxuất \t\t\t%lx\n"
+
+#: peigen.c:1465 pepigen.c:1465 pex64igen.c:1465
+#, c-format
+msgid "Time/Date stamp \t\t%lx\n"
+msgstr "Nhãn Ngày/GiỠ\t\t%lx\n"
+
+#: peigen.c:1468 pepigen.c:1468 pex64igen.c:1468
+#, c-format
+msgid "Major/Minor \t\t\t%d/%d\n"
+msgstr "Chính/Phụ \t\t\t%d/%d\n"
+
+#: peigen.c:1471 pepigen.c:1471 pex64igen.c:1471
+#, c-format
+msgid "Name \t\t\t\t"
+msgstr "Tên \t\t\t\t"
+
+#: peigen.c:1477 pepigen.c:1477 pex64igen.c:1477
+#, c-format
+msgid "Ordinal Base \t\t\t%ld\n"
+msgstr "Cơ bản thứ tự \t\t\t%ld\n"
+
+#: peigen.c:1480 pepigen.c:1480 pex64igen.c:1480
+#, c-format
+msgid "Number in:\n"
+msgstr "Số trong:\n"
+
+#: peigen.c:1483 pepigen.c:1483 pex64igen.c:1483
+#, c-format
+msgid "\tExport Address Table \t\t%08lx\n"
+msgstr "\tBảng Äịa chỉ Xuất \t\t%08lx\n"
+
+#: peigen.c:1487 pepigen.c:1487 pex64igen.c:1487
+#, c-format
+msgid "\t[Name Pointer/Ordinal] Table\t%08lx\n"
+msgstr "\t[Cái_chỉ_tên/Thứ_tự] Bảng\t%08lx\n"
+
+#: peigen.c:1490 pepigen.c:1490 pex64igen.c:1490
+#, c-format
+msgid "Table Addresses\n"
+msgstr "Äịa chỉ bảng\n"
+
+#: peigen.c:1493 pepigen.c:1493 pex64igen.c:1493
+#, c-format
+msgid "\tExport Address Table \t\t"
+msgstr "\tBảng Äịa chỉ Xuất \t\t"
+
+#: peigen.c:1498 pepigen.c:1498 pex64igen.c:1498
+#, c-format
+msgid "\tName Pointer Table \t\t"
+msgstr "\tBảng Cái Chỉ Tên \t\t"
+
+#: peigen.c:1503 pepigen.c:1503 pex64igen.c:1503
+#, c-format
+msgid "\tOrdinal Table \t\t\t"
+msgstr "\tBảng Thứ Tự \t\t\t"
+
+#: peigen.c:1517 pepigen.c:1517 pex64igen.c:1517
+#, c-format
+msgid ""
+"\n"
+"Export Address Table -- Ordinal Base %ld\n"
+msgstr ""
+"\n"
+"Bảng Äịa chỉ Xuất — CÆ¡ bản Thứ tá»± %ld\n"
+
+#: peigen.c:1536 pepigen.c:1536 pex64igen.c:1536
+msgid "Forwarder RVA"
+msgstr "Bộ chuyển tiếp RVA"
+
+#: peigen.c:1547 pepigen.c:1547 pex64igen.c:1547
+msgid "Export RVA"
+msgstr "Xuất RVA"
+
+#: peigen.c:1554 pepigen.c:1554 pex64igen.c:1554
+#, c-format
+msgid ""
+"\n"
+"[Ordinal/Name Pointer] Table\n"
+msgstr ""
+"\n"
+"Bảng [Cái chỉ Thứ tự/Tên]\n"
+
+#: peigen.c:1614 peigen.c:1797 pepigen.c:1614 pepigen.c:1797 pex64igen.c:1614
+#: pex64igen.c:1797
+#, c-format
+msgid "Warning, .pdata section size (%ld) is not a multiple of %d\n"
+msgstr "Cảnh báo: kích cỡ phần .pdata (%ld) không phải là bội số cho %d\n"
+
+#: peigen.c:1621 pepigen.c:1621 pex64igen.c:1621
+#, c-format
+msgid " vma:\t\t\tBegin Address End Address Unwind Info\n"
+msgstr " vma:\t\t\tÄịa chi đầu Äịa chỉ cuối Thông tin tháo ra\n"
+
+#: peigen.c:1623 pepigen.c:1623 pex64igen.c:1623
+#, c-format
+msgid ""
+" vma:\t\tBegin End EH EH PrologEnd Exception\n"
+" \t\tAddress Address Handler Data Address Mask\n"
+msgstr ""
+" vma:\t\tÄầu Cuối EH EH PrologEnd Ngoại lệ\n"
+" \t\tÄịa chỉ Äịa chỉ Bá»™ quản lý Dữ liệu Äịa chỉ Mặt nạ\n"
+
+#: peigen.c:1697 pepigen.c:1697 pex64igen.c:1697
+#, c-format
+msgid " Register save millicode"
+msgstr " Mili-mã lưu thanh ghi"
+
+#: peigen.c:1700 pepigen.c:1700 pex64igen.c:1700
+#, c-format
+msgid " Register restore millicode"
+msgstr " Mili-mã phục hồi thanh ghi"
+
+#: peigen.c:1703 pepigen.c:1703 pex64igen.c:1703
+#, c-format
+msgid " Glue code sequence"
+msgstr " Dãy mã nối lại"
+
+#: peigen.c:1803 pepigen.c:1803 pex64igen.c:1803
+#, c-format
+msgid ""
+" vma:\t\tBegin Prolog Function Flags Exception EH\n"
+" \t\tAddress Length Length 32b exc Handler Data\n"
+msgstr ""
+" vma:\t\tÄầu Prolog Cá» hàm Ngoại lệ EH\n"
+" \t\tÄịa chỉ Dài Dài 32b exc Quản lý Dữ liệu\n"
+
+#: peigen.c:1929 pepigen.c:1929 pex64igen.c:1929
+#, c-format
+msgid ""
+"\n"
+"\n"
+"PE File Base Relocations (interpreted .reloc section contents)\n"
+msgstr ""
+"\n"
+"\n"
+"Äịnh vị lại cÆ¡ bản tập tin PE (phiên dịch ná»™i dung phần .reloc)\n"
+
+#: peigen.c:1958 pepigen.c:1958 pex64igen.c:1958
+#, c-format
+msgid ""
+"\n"
+"Virtual Address: %08lx Chunk size %ld (0x%lx) Number of fixups %ld\n"
+msgstr ""
+"\n"
+"Äịa chỉ ảo: %08lx Kích cỡ khúc %ld (0x%lx) Số sá»± sá»­a chữa %ld\n"
+
+#: peigen.c:1971 pepigen.c:1971 pex64igen.c:1971
+#, c-format
+msgid "\treloc %4d offset %4x [%4lx] %s"
+msgstr "\tđịnh vị lại %4d bù %4x [%4lx] %s"
+
+#. The MS dumpbin program reportedly ands with 0xff0f before
+#. printing the characteristics field. Not sure why. No reason to
+#. emulate it here.
+#: peigen.c:2010 pepigen.c:2010 pex64igen.c:2010
+#, c-format
+msgid ""
+"\n"
+"Characteristics 0x%x\n"
+msgstr ""
+"\n"
+"Äặc tính 0x%x\n"
+
+#: peigen.c:2310 pepigen.c:2310 pex64igen.c:2310
+msgid "%B: unable to fill in DataDictionary[1] because .idata$2 is missing"
+msgstr "%B: không thể Ä‘iá»n vào DataDictionary[1] vì .idata$2 còn thiếu"
+
+#: peigen.c:2330 pepigen.c:2330 pex64igen.c:2330
+msgid "%B: unable to fill in DataDictionary[1] because .idata$4 is missing"
+msgstr "%B: không thể Ä‘iá»n vào DataDictionary[1] vì .idata$4 còn thiếu"
+
+#: peigen.c:2351 pepigen.c:2351 pex64igen.c:2351
+msgid "%B: unable to fill in DataDictionary[12] because .idata$5 is missing"
+msgstr "%B: không thể Ä‘iá»n vào DataDictionary[12] vì .idata$5 còn thiếu"
+
+#: peigen.c:2371 pepigen.c:2371 pex64igen.c:2371
+msgid "%B: unable to fill in DataDictionary[PE_IMPORT_ADDRESS_TABLE (12)] because .idata$6 is missing"
+msgstr "%B: không thể Ä‘iá»n vào DataDictionary[PE_IMPORT_ADDRESS_TABLE (12)] vì .idata$6 còn thiếu"
+
+#: peigen.c:2413 pepigen.c:2413 pex64igen.c:2413
+msgid "%B: unable to fill in DataDictionary[PE_IMPORT_ADDRESS_TABLE(12)] because .idata$6 is missing"
+msgstr "%B: không thể Ä‘iá»n vào DataDictionary[PE_IMPORT_ADDRESS_TABLE (12)] bởi vì .idata$6 còn thiếu"
+
+#: peigen.c:2438 pepigen.c:2438 pex64igen.c:2438
+msgid "%B: unable to fill in DataDictionary[9] because __tls_used is missing"
+msgstr "%B: không thể Ä‘iá»n vào DataDictionary[9] vì __tls_used còn thiếu"
+
+#~ msgid "Can't Make it a Short Jump"
+#~ msgstr "Không thể làm nó một bước nhảy ngắn"
+
+#~ msgid "Exceeds Long Jump Range"
+#~ msgstr "Vượt quá phạm vi bước nhảy dài"
+
+#~ msgid "Absolute address Exceeds 16 bit Range"
+#~ msgstr "Äịa chỉ tuyệt đối vượt quá phạm vi 16 bit"
+
+#~ msgid "Absolute address Exceeds 8 bit Range"
+#~ msgstr "Äịa chỉ tuyệt đối vượt quá phạm vi 8 bit"
+
+#~ msgid "Unrecognized Reloc Type"
+#~ msgstr "Kiểu định vị lại không được nhận ra"
+
+#~ msgid "corrupt or empty %s section in %B"
+#~ msgstr "Gặp phần %s bị há»ng hoặc còn rá»—ng trong %B"
+
+#~ msgid "%B(%A+0x%lx): cannot reach %s"
+#~ msgstr "%B(%A+0x%lx): không thể tới %s"
+
+#~ msgid "%s: invalid DSO for symbol `%s' definition"
+#~ msgstr "%s: DSO không hợp lệ cho lá»i định nghÄ©a ký hiệu \"%s\""
+
+#~ msgid "%B: %A+0x%lx: jump to stub routine which is not jal"
+#~ msgstr "%B: %A+0x%lx: nhảy tới hàm mẩu mà không phải jal"
+
+#~ msgid "%B: warning: ignoring duplicate section `%A'\n"
+#~ msgstr "%B: cảnh báo: đang bỠqua phần trùng \"%A\"\n"
+
+#~ msgid "%B: warning: duplicate section `%A' has different size\n"
+#~ msgstr "%B: cảnh báo: phần trùng \"%A\" có kích cỡ khác\n"
+
+#~ msgid "bfd_make_section (%s) failed"
+#~ msgstr "bfd_make_section (%s) bị lỗi"
+
+#~ msgid "bfd_set_section_flags (%s, %x) failed"
+#~ msgstr "bfd_set_section_flags (%s, %x) bị lỗi"
+
+#~ msgid "Size mismatch section %s=%lx, %s=%lx"
+#~ msgstr "Sai khớp phần %s=%lx, %s=%lx"
+
+#~ msgid "failed to enter %s"
+#~ msgstr "lỗi vào %s"
+
+#~ msgid "No Mem !"
+#~ msgstr "Không có Mem !"
+
+#~ msgid "reserved STO cmd %d"
+#~ msgstr "câu lệnh STO dành riêng %d"
+
+#~ msgid "reserved OPR cmd %d"
+#~ msgstr "câu lệnh OPR dành riêng %d"
+
+#~ msgid "reserved CTL cmd %d"
+#~ msgstr "câu lệnh CTL dành riêng %d"
+
+#~ msgid "reserved STC cmd %d"
+#~ msgstr "câu lệnh STC dành riêng %d"
+
+#~ msgid "stack-from-image not implemented"
+#~ msgstr "stack-from-image chưa được thực hiện"
+
+#~ msgid "stack-entry-mask not fully implemented"
+#~ msgstr "stack-entry-mask chưa được thực hiện hoàn toàn"
+
+#~ msgid "PASSMECH not fully implemented"
+#~ msgstr "PASSMECH chưa được thực hiện hoàn toàn"
+
+#~ msgid "stack-local-symbol not fully implemented"
+#~ msgstr "stack-local-symbol chưa được thực hiện hoàn toàn"
+
+#~ msgid "stack-literal not fully implemented"
+#~ msgstr "stack-literal chưa được thực hiện hoàn toàn"
+
+#~ msgid "stack-local-symbol-entry-point-mask not fully implemented"
+#~ msgstr "stack-local-symbol-entry-point-mask chưa được thực hiện hoàn toàn"
+
+#~ msgid "%s: not fully implemented"
+#~ msgstr "%s: chưa được thực hiện hoàn toàn"
+
+#~ msgid "obj code %d not found"
+#~ msgstr "Không tìm thấy mã đối tượng %d"
+
+#~ msgid "Reloc size error in section %s"
+#~ msgstr "Gặp lỗi kích cỡ sự định vị lại trong phần %s"
diff --git a/bfd/po/zh_CN.gmo b/bfd/po/zh_CN.gmo
new file mode 100644
index 0000000..6599886
--- /dev/null
+++ b/bfd/po/zh_CN.gmo
Binary files differ
diff --git a/bfd/po/zh_CN.po b/bfd/po/zh_CN.po
new file mode 100644
index 0000000..6e0fb10
--- /dev/null
+++ b/bfd/po/zh_CN.po
@@ -0,0 +1,2702 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) 2003 Free Software Foundation, Inc.
+# Wang Li <charles@linux.net.cn>, 2003.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: bfd 2.12.91\n"
+"POT-Creation-Date: 2002-07-23 15:55-0400\n"
+"PO-Revision-Date: 2003-03-11 09:46+0800\n"
+"Last-Translator: Wang Li <charles@linux.net.cn>\n"
+"Language-Team: Chinese (simplified) <i18n-zh@googlegroups.com>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=gb2312\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: aout-adobe.c:197
+#, c-format
+msgid "%s: Unknown section type in a.out.adobe file: %x\n"
+msgstr "%s£ºa.out.adobe ÎļþÖнڵÄÀàÐÍδ֪£º%x\n"
+
+#: aout-cris.c:208
+#, c-format
+msgid "%s: Invalid relocation type exported: %d"
+msgstr "%s£ºµ¼³öÎÞЧµÄÖض¨Î»ÀàÐÍ£º%d"
+
+#: aout-cris.c:252
+#, c-format
+msgid "%s: Invalid relocation type imported: %d"
+msgstr "%s£ºµ¼ÈëÎÞЧµÄÖض¨Î»ÀàÐÍ£º%d"
+
+#: aout-cris.c:263
+#, c-format
+msgid "%s: Bad relocation record imported: %d"
+msgstr "%s£ºµ¼Èë´íÎóµÄÖض¨Î»¼Ç¼£º%d"
+
+#: aoutx.h:1282 aoutx.h:1699
+#, c-format
+msgid "%s: can not represent section `%s' in a.out object file format"
+msgstr "%s£ºÎÞ·¨ÔÚ a.out ¶ÔÏóÎļþ¸ñʽÖбíʾ½Ú¡°%s¡±"
+
+#: aoutx.h:1669
+#, c-format
+msgid "%s: can not represent section for symbol `%s' in a.out object file format"
+msgstr "%s£ºÎÞ·¨ÔÚ a.out ¶ÔÏóÎļþ¸ñʽÖÐΪ·ûºÅ¡°%s¡±±íʾ½Ú"
+
+#: aoutx.h:1671
+msgid "*unknown*"
+msgstr "*δ֪*"
+
+#: aoutx.h:3732
+#, c-format
+msgid "%s: relocateable link from %s to %s not supported"
+msgstr "%s£º²»Ö§³Ö´Ó %s µ½ %s µÄ¿ÉÖض¨Î»µÄÁ¬½Ó"
+
+#: archive.c:1826
+msgid "Warning: writing archive was slow: rewriting timestamp\n"
+msgstr "¾¯¸æ£ºÐ´Èë¹éµµ¹ýÂý£ºÖØÐÂдÈëʱ¼ä´Á\n"
+
+#: archive.c:2093
+msgid "Reading archive file mod timestamp"
+msgstr "ÕýÔÚ¶ÁÈëÎļþÐÞ¸Äʱ¼ä´Á"
+
+#. FIXME: bfd can't call perror.
+#: archive.c:2120
+msgid "Writing updated armap timestamp"
+msgstr "ÕýÔÚ¸üРarmap ʱ¼ä´Á"
+
+#: bfd.c:274
+msgid "No error"
+msgstr "ÎÞ´íÎó"
+
+#: bfd.c:275
+msgid "System call error"
+msgstr "ϵͳµ÷ÓôíÎó"
+
+#: bfd.c:276
+msgid "Invalid bfd target"
+msgstr "ÎÞЧµÄ bfd Ä¿±ê"
+
+#: bfd.c:277
+msgid "File in wrong format"
+msgstr "Îļþ¸ñʽ´íÎó"
+
+#: bfd.c:278
+msgid "Archive object file in wrong format"
+msgstr "¹éµµÄ¿±êÎļþ¸ñʽ´íÎó"
+
+#: bfd.c:279
+msgid "Invalid operation"
+msgstr "ÎÞЧµÄ²Ù×÷"
+
+#: bfd.c:280
+msgid "Memory exhausted"
+msgstr "ÄÚ´æºÄ¾¡"
+
+#: bfd.c:281
+msgid "No symbols"
+msgstr "ÎÞ·ûºÅ"
+
+#: bfd.c:282
+msgid "Archive has no index; run ranlib to add one"
+msgstr "¹éµµÃ»ÓÐË÷Òý£»ÔËÐÐ ranlib ÒÔÌí¼ÓÒ»¸ö"
+
+#: bfd.c:283
+msgid "No more archived files"
+msgstr "ûÓиü¶àµÄ¹éµµÎļþ"
+
+#: bfd.c:284
+msgid "Malformed archive"
+msgstr "»ûÐεĹ鵵"
+
+#: bfd.c:285
+msgid "File format not recognized"
+msgstr "²»¿Éʶ±ðµÄÎļþ¸ñʽ"
+
+#: bfd.c:286
+msgid "File format is ambiguous"
+msgstr "¶þÒåÐÔµÄÎļþ¸ñʽ"
+
+#: bfd.c:287
+msgid "Section has no contents"
+msgstr "½ÚûÓÐÄÚÈÝ"
+
+#: bfd.c:288
+msgid "Nonrepresentable section on output"
+msgstr "Êä³ö²»¿É±íʾµÄ½Ú"
+
+#: bfd.c:289
+msgid "Symbol needs debug section which does not exist"
+msgstr "·ûºÅÐèÒª²»´æÔڵĵ÷ÊÔ½Ú"
+
+#: bfd.c:290
+msgid "Bad value"
+msgstr "´íÎóµÄÖµ"
+
+#: bfd.c:291
+msgid "File truncated"
+msgstr "Îļþ±»½Ø¶Ï"
+
+#: bfd.c:292
+msgid "File too big"
+msgstr "Îļþ¹ý´ó"
+
+#: bfd.c:293
+msgid "#<Invalid error code>"
+msgstr "#<ÎÞЧµÄ´íÎóÂë>"
+
+#: bfd.c:700
+#, c-format
+msgid "BFD %s assertion fail %s:%d"
+msgstr "BFD %s ¶ÏÑÔʧ°Ü %s£º%d"
+
+#: bfd.c:719
+#, c-format
+msgid "BFD %s internal error, aborting at %s line %d in %s\n"
+msgstr "BFD %1$s ÄÚ²¿´íÎó£¬Òì³£ÖÐÖ¹ÓÚ %4$s µÄ %3$d ÐÐµÄ %2$s\n"
+
+#: bfd.c:723
+#, c-format
+msgid "BFD %s internal error, aborting at %s line %d\n"
+msgstr "BFD %1$s ÄÚ²¿´íÎó£¬Òì³£ÖÐÖ¹ÓÚ %3$d ÐÐµÄ %2$s\n"
+
+#: bfd.c:725
+msgid "Please report this bug.\n"
+msgstr "Ç뱨¸æ¸Ã BUG¡£\n"
+
+#: binary.c:306
+#, c-format
+msgid "Warning: Writing section `%s' to huge (ie negative) file offset 0x%lx."
+msgstr "¾¯¸æ£º½«½Ú¡°%s¡±Ð´Èë¹ý´ó(ÀýÈ縺Êý)ÎļþÆ«ÒÆÁ¿µÄλÖà 0x%lx¡£"
+
+#: coff-a29k.c:119
+msgid "Missing IHCONST"
+msgstr "ÒÅʧ IHCONST"
+
+#: coff-a29k.c:180
+msgid "Missing IHIHALF"
+msgstr "ÒÅʧ IHIHALF"
+
+#: coff-a29k.c:212 coff-or32.c:229
+msgid "Unrecognized reloc"
+msgstr "ÎÞ·¨Ê¶±ðµÄÖض¨Î»"
+
+#: coff-a29k.c:408
+msgid "missing IHCONST reloc"
+msgstr "ÒÅʧ IHCONST Öض¨Î»"
+
+#: coff-a29k.c:498
+msgid "missing IHIHALF reloc"
+msgstr "ÒÅʧ IHIHALF Öض¨Î»"
+
+#: coff-alpha.c:881 coff-alpha.c:918 coff-alpha.c:1989 coff-mips.c:1432
+msgid "GP relative relocation used when GP not defined"
+msgstr "ÔÚ GP 䶨ÒåµÄÇé¿öÏÂʹÓÃÁË GP Ïà¶ÔÖض¨Î»"
+
+#: coff-alpha.c:1485
+msgid "using multiple gp values"
+msgstr "ʹÓÃÁ˶à¸ö GP Öµ"
+
+#: coff-arm.c:1066 elf32-arm.h:285
+#, c-format
+msgid "%s: unable to find THUMB glue '%s' for `%s'"
+msgstr ""
+
+#: coff-arm.c:1096 elf32-arm.h:320
+#, c-format
+msgid "%s: unable to find ARM glue '%s' for `%s'"
+msgstr ""
+
+#: coff-arm.c:1391 coff-arm.c:1486 elf32-arm.h:887 elf32-arm.h:991
+#, c-format
+msgid "%s(%s): warning: interworking not enabled."
+msgstr ""
+
+#: coff-arm.c:1395 elf32-arm.h:994
+#, c-format
+msgid " first occurrence: %s: arm call to thumb"
+msgstr ""
+
+#: coff-arm.c:1490 elf32-arm.h:890
+#, c-format
+msgid " first occurrence: %s: thumb call to arm"
+msgstr ""
+
+#: coff-arm.c:1493
+msgid " consider relinking with --support-old-code enabled"
+msgstr " ³¢ÊÔÆôÓà --support-old-code ÖØÐÂÁ¬½Ó"
+
+#: coff-arm.c:1785 coff-tic80.c:686 cofflink.c:3031
+#, c-format
+msgid "%s: bad reloc address 0x%lx in section `%s'"
+msgstr ""
+
+#: coff-arm.c:2127
+#, c-format
+msgid "%s: illegal symbol index in reloc: %d"
+msgstr "%s£ºÖض¨Î»ÖзǷ¨µÄ·ûºÅË÷Òý£º%d"
+
+#: coff-arm.c:2255
+#, c-format
+msgid "ERROR: %s is compiled for APCS-%d, whereas %s is compiled for APCS-%d"
+msgstr "´íÎó£º%s ÊÇΪ APCS-%d ±àÒëµÄ£¬¶ø %s ÊÇΪ APCS-%d ±àÒëµÄ"
+
+#: coff-arm.c:2270 elf32-arm.h:2297
+#, c-format
+msgid "ERROR: %s passes floats in float registers, whereas %s passes them in integer registers"
+msgstr "´íÎó£º%s ÔÚ¸¡µã¼Ä´æÆ÷Öд«µÝ¸¡µãÊý£¬¶ø %s ÔÚÕûÊý¼Ä´æÆ÷Öд«µÝËüÃÇ"
+
+#: coff-arm.c:2273 elf32-arm.h:2302
+#, c-format
+msgid "ERROR: %s passes floats in integer registers, whereas %s passes them in float registers"
+msgstr "´íÎó£º%s ÔÚÕûÊý¼Ä´æÆ÷Öд«µÝ¸¡µãÊý£¬¶ø %s ÔÚ¸¡µãÊý¼Ä´æÆ÷Öд«µÝËüÃÇ"
+
+#: coff-arm.c:2288
+#, c-format
+msgid "ERROR: %s is compiled as position independent code, whereas target %s is absolute position"
+msgstr "´íÎó£º%s ±»±àÒëΪλÖÃÎ޹شúÂ룬¶øÄ¿±ê %s ²ÉÓþø¶ÔλÖÃ"
+
+#: coff-arm.c:2291
+#, c-format
+msgid "ERROR: %s is compiled as absolute position code, whereas target %s is position independent"
+msgstr "´íÎó£º%s ±»±àÒëΪ¾ø¶ÔλÖôúÂ룬¶øÄ¿±ê %s ÊÇλÖÃÎ޹صÄ"
+
+#: coff-arm.c:2320 elf32-arm.h:2358
+#, c-format
+msgid "Warning: %s supports interworking, whereas %s does not"
+msgstr "¾¯¸æ£º%s Ö§³Ö»¥²Ù×÷£¬¶ø %s ²»Ö§³Ö"
+
+#: coff-arm.c:2323 elf32-arm.h:2365
+#, c-format
+msgid "Warning: %s does not support interworking, whereas %s does"
+msgstr "¾¯¸æ£º%s ²»Ö§³Ö»¥²Ù×÷£¬¶ø %s Ö§³Ö"
+
+#: coff-arm.c:2350
+#, c-format
+msgid "private flags = %x:"
+msgstr "˽ÓбêÖ¾ = %x£º"
+
+#: coff-arm.c:2358 elf32-arm.h:2418
+msgid " [floats passed in float registers]"
+msgstr " [ÔÚ¸¡µã¼Ä´æÆ÷Öд«µÝ¸¡µãÊý]"
+
+#: coff-arm.c:2360
+msgid " [floats passed in integer registers]"
+msgstr " [ÔÚÕûÊý¼Ä´æÆ÷Öд«µÝ¸¡µãÊý]"
+
+#: coff-arm.c:2363 elf32-arm.h:2421
+msgid " [position independent]"
+msgstr " [λÖÃÎÞ¹Ø]"
+
+#: coff-arm.c:2365
+msgid " [absolute position]"
+msgstr " [¾ø¶ÔλÖÃ]"
+
+#: coff-arm.c:2369
+msgid " [interworking flag not initialised]"
+msgstr " [»¥²Ù×÷±ê־δ³õʼ»¯]"
+
+#: coff-arm.c:2371
+msgid " [interworking supported]"
+msgstr " [Ö§³Ö»¥²Ù×÷]"
+
+#: coff-arm.c:2373
+msgid " [interworking not supported]"
+msgstr " [²»Ö§³Ö»¥²Ù×÷]"
+
+#: coff-arm.c:2421 elf32-arm.h:2124
+#, c-format
+msgid "Warning: Not setting interworking flag of %s since it has already been specified as non-interworking"
+msgstr "¾¯¸æ£ºÓÉÓÚ %s ÒѾ­±»Ö¸¶¨Îª²»¿É»¥²Ù×÷µÄ£¬Òò¶øûÓÐÉ趨»¥²Ù×÷±êÖ¾"
+
+#: coff-arm.c:2425 elf32-arm.h:2128
+#, c-format
+msgid "Warning: Clearing the interworking flag of %s due to outside request"
+msgstr "¾¯¸æ£ºÕýÔÚ¸ù¾ÝÍâ½çÇëÇóÇå³ý %s µÄ»¥²Ù×÷±êÖ¾"
+
+#: coff-i960.c:136 coff-i960.c:485
+msgid "uncertain calling convention for non-COFF symbol"
+msgstr "¹ØÓÚ·Ç-COFF ·ûºÅ²»È·¶¨µÄµ÷ÓÃÔ¼¶¨"
+
+#: coff-m68k.c:481 coff-mips.c:2429 elf32-m68k.c:2157 elf32-mips.c:1844
+msgid "unsupported reloc type"
+msgstr "²»Ö§³ÖµÄÖض¨Î»ÀàÐÍ"
+
+#: coff-mips.c:874 elf32-mips.c:1062 elf64-mips.c:1609
+msgid "GP relative relocation when _gp not defined"
+msgstr ""
+
+#. No other sections should appear in -membedded-pic
+#. code.
+#: coff-mips.c:2466
+msgid "reloc against unsupported section"
+msgstr "¹ØÓÚ²»Ö§³Ö½ÚµÄÖض¨Î»"
+
+#: coff-mips.c:2474
+msgid "reloc not properly aligned"
+msgstr "Öض¨Î»Ã»ÓÐÕýÈ·¶ÔÆë"
+
+#: coff-rs6000.c:2766
+#, c-format
+msgid "%s: unsupported relocation type 0x%02x"
+msgstr "%s£º²»Ö§³ÖµÄÖض¨Î»ÀàÐÍ 0x%02x"
+
+#: coff-rs6000.c:2859
+#, c-format
+msgid "%s: TOC reloc at 0x%x to symbol `%s' with no TOC entry"
+msgstr ""
+
+#: coff-rs6000.c:3590 coff64-rs6000.c:2091
+#, c-format
+msgid "%s: symbol `%s' has unrecognized smclas %d"
+msgstr ""
+
+#: coff-tic54x.c:279 coff-tic80.c:449
+#, c-format
+msgid "Unrecognized reloc type 0x%x"
+msgstr "ÎÞ·¨Ê¶±ðµÄÖض¨Î»ÀàÐÍ 0x%x"
+
+#: coff-tic54x.c:390 coffcode.h:4974
+#, c-format
+msgid "%s: warning: illegal symbol index %ld in relocs"
+msgstr "%s£º¾¯¸æ£ºÖض¨Î»ÖзǷ¨µÄ·ûºÅË÷Òý %ld"
+
+#: coff-w65.c:363
+#, c-format
+msgid "ignoring reloc %s\n"
+msgstr "ÕýÔÚºöÂÔÖض¨Î» %s\n"
+
+#: coffcode.h:1086
+#, c-format
+msgid "%s (%s): Section flag %s (0x%x) ignored"
+msgstr "%s (%s)£ººöÂÔ½Ú±êÖ¾ %s (0x%x)"
+
+#: coffcode.h:2143
+#, c-format
+msgid "Unrecognized TI COFF target id '0x%x'"
+msgstr "ÎÞ·¨Ê¶±ðµÄ TI COFF Ä¿±ê id ¡°0x%x¡±"
+
+#: coffcode.h:4365
+#, c-format
+msgid "%s: warning: illegal symbol index %ld in line numbers"
+msgstr "%s£º¾¯¸æ£ºÐкÅÖеķǷ¨·ûºÅË÷Òý %ld"
+
+#: coffcode.h:4379
+#, c-format
+msgid "%s: warning: duplicate line number information for `%s'"
+msgstr "%s£º¾¯¸æ£ºÎª¡°%s¡±¸´ÖÆÐкÅÐÅÏ¢"
+
+#: coffcode.h:4736
+#, c-format
+msgid "%s: Unrecognized storage class %d for %s symbol `%s'"
+msgstr ""
+
+#: coffcode.h:4867
+#, c-format
+msgid "warning: %s: local symbol `%s' has no section"
+msgstr "¾¯¸æ£º%s£º±¾µØ·ûºÅ¡°%s¡±Ã»ÓнÚ"
+
+#: coffcode.h:5012
+#, c-format
+msgid "%s: illegal relocation type %d at address 0x%lx"
+msgstr "%1$s£ºÎ»ÓÚµØÖ· 0x%3$lx ´¦µÄ·Ç·¨Öض¨Î»ÀàÐÍ %2$d"
+
+#: coffgen.c:1661
+#, c-format
+msgid "%s: bad string table size %lu"
+msgstr "%s£º×Ö·û´®±íµÄ´óС´íÎó %lu"
+
+#: cofflink.c:534 elflink.h:1912
+#, c-format
+msgid "Warning: type of symbol `%s' changed from %d to %d in %s"
+msgstr "¾¯¸æ£º%4$s ÖеķûºÅ¡°%1$s¡±µÄÀàÐÍÓÉ %2$d ±äΪ %3$d"
+
+#: cofflink.c:2321
+#, c-format
+msgid "%s: relocs in section `%s', but it has no contents"
+msgstr ""
+
+#: cofflink.c:2664 coffswap.h:877
+#, c-format
+msgid "%s: %s: reloc overflow: 0x%lx > 0xffff"
+msgstr "%s£º%s£ºÖض¨Î»Òç³ö£º0x%lx > 0xffff"
+
+#: cofflink.c:2673 coffswap.h:864
+#, c-format
+msgid "%s: warning: %s: line number overflow: 0x%lx > 0xffff"
+msgstr "%s£º¾¯¸æ£º%s£ºÐкÅÒç³ö£º0x%lx > 0xffff"
+
+#: dwarf2.c:382
+msgid "Dwarf Error: Can't find .debug_str section."
+msgstr "С´íÎó£ºÎÞ·¨ÕÒµ½ .debug_str ½Ú¡£"
+
+#: dwarf2.c:399
+#, c-format
+msgid "Dwarf Error: DW_FORM_strp offset (%lu) greater than or equal to .debug_str size (%lu)."
+msgstr ""
+
+#: dwarf2.c:543
+msgid "Dwarf Error: Can't find .debug_abbrev section."
+msgstr "С´íÎó£ºÎÞ·¨ÕÒµ½ .debug_abbrev ½Ú¡£"
+
+#: dwarf2.c:560
+#, c-format
+msgid "Dwarf Error: Abbrev offset (%lu) greater than or equal to .debug_abbrev size (%lu)."
+msgstr ""
+
+#: dwarf2.c:757
+#, c-format
+msgid "Dwarf Error: Invalid or unhandled FORM value: %u."
+msgstr "С´íÎó£ºÎÞЧ»òδ´¦ÀíµÄ±íµ¥Öµ£º%u¡£"
+
+#: dwarf2.c:852
+msgid "Dwarf Error: mangled line number section (bad file number)."
+msgstr ""
+
+#: dwarf2.c:938
+msgid "Dwarf Error: Can't find .debug_line section."
+msgstr "С´íÎó£ºÎÞ·¨ÕÒµ½ .debug_line ½Ú¡£"
+
+#: dwarf2.c:961
+#, c-format
+msgid "Dwarf Error: Line offset (%lu) greater than or equal to .debug_line size (%lu)."
+msgstr ""
+
+#: dwarf2.c:1159
+msgid "Dwarf Error: mangled line number section."
+msgstr ""
+
+#: dwarf2.c:1355 dwarf2.c:1566
+#, c-format
+msgid "Dwarf Error: Could not find abbrev number %u."
+msgstr ""
+
+#: dwarf2.c:1527
+#, c-format
+msgid "Dwarf Error: found dwarf version '%u', this reader only handles version 2 information."
+msgstr ""
+
+#: dwarf2.c:1534
+#, c-format
+msgid "Dwarf Error: found address size '%u', this reader can not handle sizes greater than '%u'."
+msgstr ""
+
+#: dwarf2.c:1557
+#, c-format
+msgid "Dwarf Error: Bad abbrev number: %u."
+msgstr "С´íÎ󣺴íÎóµÄËõд±àºÅ£º%u¡£"
+
+#: ecoff.c:1318
+#, c-format
+msgid "Unknown basic type %d"
+msgstr "δ֪µÄ»ù±¾ÀàÐÍ %d"
+
+#: ecoff.c:1578
+#, c-format
+msgid ""
+"\n"
+" End+1 symbol: %ld"
+msgstr ""
+"\n"
+" End+1 ·ûºÅ£º%ld"
+
+#: ecoff.c:1585 ecoff.c:1588
+#, c-format
+msgid ""
+"\n"
+" First symbol: %ld"
+msgstr ""
+"\n"
+" µÚÒ»¸ö·ûºÅ£º%ld"
+
+#: ecoff.c:1600
+#, c-format
+msgid ""
+"\n"
+" End+1 symbol: %-7ld Type: %s"
+msgstr ""
+"\n"
+" End+1 ·ûºÅ£º%-7ld ÀàÐÍ£º%s"
+
+#: ecoff.c:1607
+#, c-format
+msgid ""
+"\n"
+" Local symbol: %ld"
+msgstr ""
+"\n"
+" ±¾µØ·ûºÅ£º%ld"
+
+#: ecoff.c:1615
+#, c-format
+msgid ""
+"\n"
+" struct; End+1 symbol: %ld"
+msgstr ""
+"\n"
+" ½á¹¹£»End+1 ·ûºÅ£º%ld"
+
+#: ecoff.c:1620
+#, c-format
+msgid ""
+"\n"
+" union; End+1 symbol: %ld"
+msgstr ""
+"\n"
+" ÁªºÏ£»End+1 ·ûºÅ£º%ld"
+
+#: ecoff.c:1625
+#, c-format
+msgid ""
+"\n"
+" enum; End+1 symbol: %ld"
+msgstr ""
+"\n"
+" ö¾Ù£»End+1 ·ûºÅ£º%ld"
+
+#: ecoff.c:1631
+#, c-format
+msgid ""
+"\n"
+" Type: %s"
+msgstr ""
+"\n"
+" ÀàÐÍ£º%s"
+
+#: elf-hppa.h:1476 elf-hppa.h:1509 elf32-ppc.c:3091 elf32-sh.c:4213
+#: elf64-sh64.c:1659
+#, c-format
+msgid "%s: warning: unresolvable relocation against symbol `%s' from %s section"
+msgstr "%1$s£º¾¯¸æ£ºÀ´×Ô %3$s ½ÚµÄ¹ØÓÚ·ûºÅ¡°%2$s¡±µÄ²»¿É½âÎöµÄÖض¨Î»"
+
+#: elf-m10200.c:446 elf-m10300.c:656 elf32-arm.h:2084 elf32-avr.c:833
+#: elf32-cris.c:1403 elf32-d10v.c:481 elf32-fr30.c:635 elf32-frv.c:809
+#: elf32-h8300.c:548 elf32-i860.c:1031 elf32-m32r.c:1278 elf32-openrisc.c:439
+#: elf32-v850.c:1691 elf32-xstormy16.c:933 elf64-mmix.c:1302
+msgid "internal error: out of range error"
+msgstr "ÄÚ²¿´íÎ󣺳¬³ö·¶Î§´íÎó"
+
+#: elf-m10200.c:450 elf-m10300.c:660 elf32-arm.h:2088 elf32-avr.c:837
+#: elf32-cris.c:1407 elf32-d10v.c:485 elf32-fr30.c:639 elf32-frv.c:813
+#: elf32-h8300.c:552 elf32-i860.c:1035 elf32-m32r.c:1282 elf32-openrisc.c:443
+#: elf32-v850.c:1695 elf32-xstormy16.c:937 elf64-mmix.c:1306 elfxx-mips.c:5264
+msgid "internal error: unsupported relocation error"
+msgstr "ÄÚ²¿´íÎ󣺲»Ö§³ÖµÄÖض¨Î»´íÎó"
+
+#: elf-m10200.c:454 elf-m10300.c:664 elf32-arm.h:2092 elf32-d10v.c:489
+#: elf32-h8300.c:556 elf32-m32r.c:1286
+msgid "internal error: dangerous error"
+msgstr "ÄÚ²¿´íÎó£ºÎ£ÏյĴíÎó"
+
+#: elf-m10200.c:458 elf-m10300.c:668 elf32-arm.h:2096 elf32-avr.c:845
+#: elf32-cris.c:1415 elf32-d10v.c:493 elf32-fr30.c:647 elf32-frv.c:821
+#: elf32-h8300.c:560 elf32-i860.c:1043 elf32-m32r.c:1290 elf32-openrisc.c:451
+#: elf32-v850.c:1715 elf32-xstormy16.c:945 elf64-mmix.c:1314
+msgid "internal error: unknown error"
+msgstr "ÄÚ²¿´íÎó£ºÎ´ÖªµÄ´íÎó"
+
+#: elf.c:343
+#, c-format
+msgid "%s: invalid string offset %u >= %lu for section `%s'"
+msgstr ""
+
+#: elf.c:589
+#, c-format
+msgid "%s: invalid SHT_GROUP entry"
+msgstr "%s£ºÎÞЧµÄ SHT_GROUP ÌõÄ¿"
+
+#: elf.c:660
+#, c-format
+msgid "%s: no group info for section %s"
+msgstr "%s£ºÃ»ÓйØÓÚ½Ú %s µÄ×éÐÅÏ¢"
+
+#: elf.c:1023
+msgid ""
+"\n"
+"Program Header:\n"
+msgstr ""
+"\n"
+"³ÌÐòÍ·£º\n"
+
+#: elf.c:1073
+msgid ""
+"\n"
+"Dynamic Section:\n"
+msgstr ""
+"\n"
+"¶¯Ì¬½Ú£º\n"
+
+#: elf.c:1202
+msgid ""
+"\n"
+"Version definitions:\n"
+msgstr ""
+"\n"
+"°æ±¾¶¨Ò壺\n"
+
+#: elf.c:1225
+msgid ""
+"\n"
+"Version References:\n"
+msgstr ""
+"\n"
+"°æ±¾ÒýÓãº\n"
+
+#: elf.c:1230
+#, c-format
+msgid " required from %s:\n"
+msgstr ""
+
+#: elf.c:1902
+#, c-format
+msgid "%s: invalid link %lu for reloc section %s (index %u)"
+msgstr ""
+
+#: elf.c:3603
+#, c-format
+msgid "%s: Not enough room for program headers (allocated %u, need %u)"
+msgstr "%s£ºÃ»ÓÐ×ã¹»µÄ¿Õ¼ä±£´æ³ÌÐòÍ·£¨·ÖÅä %u£¬ÐèÒª %u£©"
+
+#: elf.c:3708
+#, c-format
+msgid "%s: Not enough room for program headers, try linking with -N"
+msgstr "%s£ºÃ»ÓÐ×ã¹»µÄ¿Õ¼ä±£´æ³ÌÐòÍ·£¬ÊÔÓà -N ½øÐÐÁ¬½Ó"
+
+#: elf.c:3833
+#, c-format
+msgid "Error: First section in segment (%s) starts at 0x%x whereas the segment starts at 0x%x"
+msgstr "´íÎ󣺶Π(%s) ÖеĵÚÒ»¸ö½Ú¿ªÊ¼ÓÚ 0x%x£¬È»¶ø¶Î¿ªÊ¼ÓÚ 0x%x"
+
+#: elf.c:4148
+#, c-format
+msgid "%s: warning: allocated section `%s' not in segment"
+msgstr "%s£º¾¯¸æ£ºÒÑ·ÖÅäµÄ½Ú¡°%s¡±²»ÔÚ¶ÎÖÐ"
+
+#: elf.c:4472
+#, c-format
+msgid "%s: symbol `%s' required but not present"
+msgstr "%s£º±ØÐèµÄ·ûºÅ¡°%s¡±²»´æÔÚ"
+
+#: elf.c:4749
+#, c-format
+msgid "%s: warning: Empty loadable segment detected, is this intentional ?\n"
+msgstr "%s£º¾¯¸æ£º·¢ÏֿյĿÉ×°Èë¶Î£¬ËüÊÇÄÚ²¿µÄ£¿\n"
+
+#: elf.c:6193
+#, c-format
+msgid "%s: unsupported relocation type %s"
+msgstr "%s£º²»Ö§³ÖµÄÖض¨Î»µÄÀàÐÍ %s"
+
+#: elf32-arm.h:1221
+#, c-format
+msgid "%s: Warning: Arm BLX instruction targets Arm function '%s'."
+msgstr ""
+
+#: elf32-arm.h:1417
+#, c-format
+msgid "%s: Warning: Thumb BLX instruction targets thumb function '%s'."
+msgstr ""
+
+#: elf32-arm.h:1914 elf32-sh.c:4125
+#, c-format
+msgid "%s(%s+0x%lx): %s relocation against SEC_MERGE section"
+msgstr "%s(%s+0x%lx)£º¹ØÓÚ SEC_MERGE ½ÚµÄÖض¨Î» %s"
+
+#: elf32-arm.h:2008
+#, c-format
+msgid "%s: warning: unresolvable relocation %d against symbol `%s' from %s section"
+msgstr ""
+
+#: elf32-arm.h:2176
+#, c-format
+msgid "Warning: Clearing the interworking flag of %s because non-interworking code in %s has been linked with it"
+msgstr ""
+
+#: elf32-arm.h:2271
+#, c-format
+msgid "ERROR: %s is compiled for EABI version %d, whereas %s is compiled for version %d"
+msgstr "´íÎó£º%s ÊÇΪ EABI °æ±¾ %d ±àÒëµÄ£¬¶ø %s ÔòÊÇΪ°æ±¾ %d ±àÒëµÄ"
+
+#: elf32-arm.h:2285
+#, c-format
+msgid "ERROR: %s is compiled for APCS-%d, whereas target %s uses APCS-%d"
+msgstr "´íÎó£º%s ÊÇΪ APCS-%d ±àÒëµÄ£¬¶øÄ¿±ê %s ʹÓà APCS-%d"
+
+#: elf32-arm.h:2313
+#, c-format
+msgid "ERROR: %s uses VFP instructions, whereas %s uses FPA instructions"
+msgstr "´íÎó£º%s ʹÓà VFP Ö¸Á¶ø %s ʹÓà FPA Ö¸Áî"
+
+#: elf32-arm.h:2318
+#, c-format
+msgid "ERROR: %s uses FPA instructions, whereas %s uses VFP instructions"
+msgstr "´íÎó£º%s ʹÓà FPA Ö¸Á¶ø %s ʹÓà VFP Ö¸Áî"
+
+#: elf32-arm.h:2338
+#, c-format
+msgid "ERROR: %s uses software FP, whereas %s uses hardware FP"
+msgstr "´íÎó£º%s ʹÓÃÈí¼þ FP£¬¶ø %s ʹÓÃÓ²¼þ FP"
+
+#: elf32-arm.h:2343
+#, c-format
+msgid "ERROR: %s uses hardware FP, whereas %s uses software FP"
+msgstr "´íÎó£º%s ʹÓÃÓ²¼þ FP£¬¶ø %s ʹÓÃÈí¼þ FP"
+
+#. Ignore init flag - it may not be set, despite the flags field
+#. containing valid data.
+#: elf32-arm.h:2396 elf32-cris.c:2988 elf32-m68k.c:410 elf32-vax.c:543
+#: elfxx-mips.c:7756
+#, c-format
+msgid "private flags = %lx:"
+msgstr "˽ÓбêÖ¾ = %lx£º"
+
+#: elf32-arm.h:2405
+msgid " [interworking enabled]"
+msgstr " [ÆôÓû¥²Ù×÷]"
+
+#: elf32-arm.h:2413
+msgid " [VFP float format]"
+msgstr " [VFP ¸¡µã¸ñʽ]"
+
+#: elf32-arm.h:2415
+msgid " [FPA float format]"
+msgstr " [FPA ¸¡µã¸ñʽ]"
+
+#: elf32-arm.h:2424
+msgid " [new ABI]"
+msgstr " [ÐÂ ABI]"
+
+#: elf32-arm.h:2427
+msgid " [old ABI]"
+msgstr " [¾É ABI]"
+
+#: elf32-arm.h:2430
+msgid " [software FP]"
+msgstr " [Èí¼þ FP]"
+
+#: elf32-arm.h:2438
+msgid " [Version1 EABI]"
+msgstr " [°æ±¾1 EABI]"
+
+#: elf32-arm.h:2441 elf32-arm.h:2452
+msgid " [sorted symbol table]"
+msgstr " [ÅÅÐò¹ýµÄ·ûºÅ±í]"
+
+#: elf32-arm.h:2443 elf32-arm.h:2454
+msgid " [unsorted symbol table]"
+msgstr " [δÅÅÐòµÄ·ûºÅ±í]"
+
+#: elf32-arm.h:2449
+msgid " [Version2 EABI]"
+msgstr " [°æ±¾2 EABI]"
+
+#: elf32-arm.h:2457
+msgid " [dynamic symbols use segment index]"
+msgstr " [¶¯Ì¬·ûºÅʹÓöÎË÷Òý]"
+
+#: elf32-arm.h:2460
+msgid " [mapping symbols precede others]"
+msgstr ""
+
+#: elf32-arm.h:2467
+msgid " <EABI version unrecognised>"
+msgstr " <²»¿Éʶ±ðµÄ EABI °æ±¾>"
+
+#: elf32-arm.h:2474
+msgid " [relocatable executable]"
+msgstr " [¿ÉÖØж¨Î»µÄ¿ÉÖ´ÐгÌÐò]"
+
+#: elf32-arm.h:2477
+msgid " [has entry point]"
+msgstr " [º¬ÓÐÈë¿Úµã]"
+
+#: elf32-arm.h:2482
+msgid "<Unrecognised flag bits set>"
+msgstr "<ÎÞ·¨Ê¶±ðµÄ±ê־λ¼¯ºÏ>"
+
+#: elf32-avr.c:841 elf32-cris.c:1411 elf32-fr30.c:643 elf32-frv.c:817
+#: elf32-i860.c:1039 elf32-openrisc.c:447 elf32-v850.c:1699
+#: elf32-xstormy16.c:941 elf64-mmix.c:1310
+msgid "internal error: dangerous relocation"
+msgstr "ÄÚ²¿´íÎó£ºÎ£ÏÕµÄÖض¨Î»"
+
+#: elf32-cris.c:949
+#, c-format
+msgid "%s: unresolvable relocation %s against symbol `%s' from %s section"
+msgstr "%1$s£ºÀ´×Ô %4$s ½ÚµÄ¹ØÓÚ·ûºÅ¡°%3$s¡±µÄÎÞ·¨½âÎöµÄÖض¨Î» %2$s"
+
+#: elf32-cris.c:1012
+#, c-format
+msgid "%s: No PLT nor GOT for relocation %s against symbol `%s' from %s section"
+msgstr ""
+
+#: elf32-cris.c:1015 elf32-cris.c:1141
+msgid "[whose name is lost]"
+msgstr ""
+
+#: elf32-cris.c:1130
+#, c-format
+msgid "%s: relocation %s with non-zero addend %d against local symbol from %s section"
+msgstr ""
+
+#: elf32-cris.c:1137
+#, c-format
+msgid "%s: relocation %s with non-zero addend %d against symbol `%s' from %s section"
+msgstr ""
+
+#: elf32-cris.c:1155
+#, c-format
+msgid "%s: relocation %s is not allowed for global symbol: `%s' from %s section"
+msgstr ""
+
+#: elf32-cris.c:1170
+#, c-format
+msgid "%s: relocation %s in section %s with no GOT created"
+msgstr ""
+
+#: elf32-cris.c:1288
+#, c-format
+msgid "%s: Internal inconsistency; no relocation section %s"
+msgstr "%s£ºÄÚ²¿²»Ò»Ö£»Ã»ÓÐÖض¨Î»½Ú %s"
+
+#: elf32-cris.c:2514
+#, c-format
+msgid ""
+"%s, section %s:\n"
+" relocation %s should not be used in a shared object; recompile with -fPIC"
+msgstr ""
+
+#: elf32-cris.c:2991
+msgid " [symbols have a _ prefix]"
+msgstr " [·ûºÅÓиö _ ǰ׺]"
+
+#: elf32-cris.c:3030
+#, c-format
+msgid "%s: uses _-prefixed symbols, but writing file with non-prefixed symbols"
+msgstr "%s£ºÊ¹Óôø _ ǰ׺µÄ·ûºÅ£¬µ«ÒÔÎÞǰ׺·ûºÅдÈëÎļþ"
+
+#: elf32-cris.c:3031
+#, c-format
+msgid "%s: uses non-prefixed symbols, but writing file with _-prefixed symbols"
+msgstr "%s£ºÊ¹ÓÃÎÞǰ׺·ûºÅ£¬µ«ÒÔ´ø _ ǰ׺µÄ·ûºÅдÈëÎļþ"
+
+#: elf32-frv.c:1217
+#, c-format
+msgid "%s: compiled with %s and linked with modules that use non-pic relocations"
+msgstr ""
+
+#: elf32-frv.c:1267
+#, c-format
+msgid "%s: compiled with %s and linked with modules compiled with %s"
+msgstr "%s£ºÒÔ %s ±àÒ벢ͬÒÔ %s ±àÒëµÄÄ£¿éÁ¬½Ó"
+
+#: elf32-frv.c:1279
+#, c-format
+msgid "%s: uses different unknown e_flags (0x%lx) fields than previous modules (0x%lx)"
+msgstr ""
+
+#: elf32-frv.c:1315
+#, c-format
+msgid "private flags = 0x%lx:"
+msgstr "˽ÓбêÖ¾ = 0x%lx£º"
+
+#: elf32-gen.c:82 elf64-gen.c:82
+#, c-format
+msgid "%s: Relocations in generic ELF (EM: %d)"
+msgstr ""
+
+#: elf32-hppa.c:671 elf64-ppc.c:2323
+#, c-format
+msgid "%s: cannot create stub entry %s"
+msgstr ""
+
+#: elf32-hppa.c:956 elf32-hppa.c:3555
+#, c-format
+msgid "%s(%s+0x%lx): cannot reach %s, recompile with -ffunction-sections"
+msgstr ""
+
+#: elf32-hppa.c:1338 elf64-x86-64.c:673
+#, c-format
+msgid "%s: relocation %s can not be used when making a shared object; recompile with -fPIC"
+msgstr ""
+
+#: elf32-hppa.c:1358
+#, c-format
+msgid "%s: relocation %s should not be used when making a shared object; recompile with -fPIC"
+msgstr ""
+
+#: elf32-hppa.c:1551
+#, c-format
+msgid "Could not find relocation section for %s"
+msgstr "ÎÞ·¨Îª %s ÕÒµ½Öض¨Î»½Ú"
+
+#: elf32-hppa.c:2855
+#, c-format
+msgid "%s: duplicate export stub %s"
+msgstr ""
+
+#: elf32-hppa.c:3433
+#, c-format
+msgid "%s(%s+0x%lx): fixing %s"
+msgstr "%s(%s+0x%lx)£ºÕýÔÚÐÞ¸´ %s"
+
+#: elf32-hppa.c:4080
+#, c-format
+msgid "%s(%s+0x%lx): cannot handle %s for %s"
+msgstr ""
+
+#: elf32-hppa.c:4393
+msgid ".got section not immediately after .plt section"
+msgstr ".got ½Ú²»Äܽô½ÓÔÚ .plt ½ÚÖ®ºó"
+
+#: elf32-i386.c:379
+#, c-format
+msgid "%s: invalid relocation type %d"
+msgstr "%s£ºÎÞЧµÄÖض¨Î»ÀàÐÍ %d"
+
+#: elf32-i386.c:876 elf32-s390.c:649 elf64-s390.c:595 elf64-x86-64.c:591
+#, c-format
+msgid "%s: bad symbol index: %d"
+msgstr "%s£º´íÎóµÄ·ûºÅË÷Òý£º%d"
+
+#: elf32-i386.c:948
+#, c-format
+msgid "%s: `%s' accessed both as normal and thread local symbol"
+msgstr ""
+
+#: elf32-i386.c:1072 elf32-s390.c:808 elf64-ppc.c:2827 elf64-s390.c:759
+#: elf64-x86-64.c:761
+#, c-format
+msgid "%s: bad relocation section name `%s'"
+msgstr "%s£º´íÎóµÄÖض¨Î»½ÚÃû³Æ¡°%s¡±"
+
+#: elf32-i386.c:1159 elf64-alpha.c:4768
+#, c-format
+msgid "%s: TLS local exec code cannot be linked into shared objects"
+msgstr ""
+
+#: elf32-i386.c:2747 elf32-s390.c:1981 elf32-sparc.c:1571 elf64-ppc.c:5918
+#: elf64-s390.c:1945 elf64-sparc.c:2578 elf64-x86-64.c:1948
+#, c-format
+msgid "%s(%s+0x%lx): unresolvable relocation against symbol `%s'"
+msgstr ""
+
+#: elf32-i386.c:2784 elf32-s390.c:2019 elf64-ppc.c:5977 elf64-s390.c:1983
+#: elf64-x86-64.c:1986
+#, c-format
+msgid "%s(%s+0x%lx): reloc against `%s': error %d"
+msgstr ""
+
+#: elf32-m32r.c:924
+msgid "SDA relocation when _SDA_BASE_ not defined"
+msgstr "ÔÚ _SDA_BASE_ 䶨Òåʱ³öÏÖ SDA Öض¨Î»"
+
+#: elf32-ia64.c:3687 elf32-m32r.c:1013 elf32-ppc.c:2987 elf64-alpha.c:4185
+#: elf64-alpha.c:4313 elf64-ia64.c:3687
+#, c-format
+msgid "%s: unknown relocation type %d"
+msgstr "%s£ºÎ´ÖªµÄÖض¨Î»ÀàÐÍ %d"
+
+#: elf32-m32r.c:1221
+#, c-format
+msgid "%s: The target (%s) of an %s relocation is in the wrong section (%s)"
+msgstr ""
+
+#: elf32-m32r.c:1947
+#, c-format
+msgid "%s: Instruction set mismatch with previous modules"
+msgstr ""
+
+#: elf32-m32r.c:1970
+#, c-format
+msgid "private flags = %lx"
+msgstr "˽ÓбêÖ¾ = %lx"
+
+#: elf32-m32r.c:1975
+msgid ": m32r instructions"
+msgstr "£ºm32r Ö¸Áî"
+
+#: elf32-m32r.c:1976
+msgid ": m32rx instructions"
+msgstr "£ºm32rx Ö¸Áî"
+
+#: elf32-m68k.c:413
+msgid " [cpu32]"
+msgstr " [cpu32]"
+
+#: elf32-m68k.c:416
+msgid " [m68000]"
+msgstr " [m68000]"
+
+#: elf32-mcore.c:354 elf32-mcore.c:457
+#, c-format
+msgid "%s: Relocation %s (%d) is not currently supported.\n"
+msgstr ""
+
+#: elf32-mcore.c:442
+#, c-format
+msgid "%s: Unknown relocation type %d\n"
+msgstr "%s£ºÎ´ÖªµÄÖض¨Î»ÀàÐÍ %d\n"
+
+#: elf32-mips.c:1152 elf64-mips.c:1783
+msgid "32bits gp relative relocation occurs for an external symbol"
+msgstr ""
+
+#: elf32-mips.c:1301
+#, c-format
+msgid "Linking mips16 objects into %s format is not supported"
+msgstr "½« mips16 Ä¿±êÎļþÁ¬½Óµ½ %s ¸ñʽÊDz»Ö§³ÖµÄ"
+
+#: elf32-ppc.c:1460
+#, c-format
+msgid "%s: compiled with -mrelocatable and linked with modules compiled normally"
+msgstr ""
+
+#: elf32-ppc.c:1468
+#, c-format
+msgid "%s: compiled normally and linked with modules compiled with -mrelocatable"
+msgstr ""
+
+#: elf32-ppc.c:1494 elf64-sparc.c:2989 elfxx-mips.c:7713
+#, c-format
+msgid "%s: uses different e_flags (0x%lx) fields than previous modules (0x%lx)"
+msgstr ""
+
+#: elf32-ppc.c:1592
+#, c-format
+msgid "%s: Unknown special linker type %d"
+msgstr "%s£ºÎ´ÖªµÄÌض¨Á¬½ÓÆ÷ÀàÐÍ %d"
+
+#: elf32-ppc.c:2273 elf32-ppc.c:2307 elf32-ppc.c:2342
+#, c-format
+msgid "%s: relocation %s cannot be used when making a shared object"
+msgstr "%s£º´´½¨¹²ÏíÄ¿±êÎļþʱ²»ÄÜʹÓÃÖض¨Î» %s"
+
+#: elf32-ppc.c:3126 elf64-ppc.c:5473
+#, c-format
+msgid "%s: unknown relocation type %d for symbol %s"
+msgstr "%1$s£º¹ØÓÚ·ûºÅ %3$s µÄδ֪Öض¨Î»ÀàÐÍ %2$d"
+
+#: elf32-ppc.c:3482 elf32-ppc.c:3503 elf32-ppc.c:3553
+#, c-format
+msgid "%s: The target (%s) of a %s relocation is in the wrong output section (%s)"
+msgstr ""
+
+#: elf32-ppc.c:3619
+#, c-format
+msgid "%s: Relocation %s is not yet supported for symbol %s."
+msgstr "%s£ºÉв»Ö§³Ö¹ØÓÚ·ûºÅ %s µÄÖض¨Î» %s¡£"
+
+#: elf32-sh.c:1964
+#, c-format
+msgid "%s: 0x%lx: warning: bad R_SH_USES offset"
+msgstr "%s£º0x%lx£º¾¯¸æ£º´íÎóµÄ R_SH_USES Æ«ÒÆÁ¿"
+
+#: elf32-sh.c:1976
+#, c-format
+msgid "%s: 0x%lx: warning: R_SH_USES points to unrecognized insn 0x%x"
+msgstr "%s£º0x%lx£º¾¯¸æ£ºR_SH_USES Ö¸ÏòÎÞ·¨Ê¶±ðµÄÖ¸Áî 0x%x"
+
+#: elf32-sh.c:1993
+#, c-format
+msgid "%s: 0x%lx: warning: bad R_SH_USES load offset"
+msgstr "%s£º0x%lx£º¾¯¸æ£º´íÎóµÄ R_SH_USES ×°ÈëÆ«ÒÆÁ¿"
+
+#: elf32-sh.c:2008
+#, c-format
+msgid "%s: 0x%lx: warning: could not find expected reloc"
+msgstr "%s£º0x%lx£º¾¯¸æ£ºÎÞ·¨ÕÒµ½Ô¤ÆÚµÄÖض¨Î»"
+
+#: elf32-sh.c:2036
+#, c-format
+msgid "%s: 0x%lx: warning: symbol in unexpected section"
+msgstr "%s£º0x%lx£º¾¯¸æ£ºÒâÍâ½ÚÖгöÏÖ·ûºÅ"
+
+#: elf32-sh.c:2153
+#, c-format
+msgid "%s: 0x%lx: warning: could not find expected COUNT reloc"
+msgstr "%s£º0x%lx£º¾¯¸æ£ºÎÞ·¨ÕÒµ½Ô¤ÆÚµÄ COUNT Öض¨Î»"
+
+#: elf32-sh.c:2162
+#, c-format
+msgid "%s: 0x%lx: warning: bad count"
+msgstr "%s£º0x%lx£º¾¯¸æ£º´íÎó¼ÆÊý"
+
+#: elf32-sh.c:2550 elf32-sh.c:2926
+#, c-format
+msgid "%s: 0x%lx: fatal: reloc overflow while relaxing"
+msgstr ""
+
+#: elf32-sh.c:4073 elf64-sh64.c:1576
+msgid "Unexpected STO_SH5_ISA32 on local symbol is not handled"
+msgstr ""
+
+#: elf32-sh.c:4284
+#, c-format
+msgid "%s: 0x%lx: fatal: unaligned branch target for relax-support relocation"
+msgstr ""
+
+#: elf32-sh64.c:203 elf64-sh64.c:2364
+#, c-format
+msgid "%s: compiled as 32-bit object and %s is 64-bit"
+msgstr "%s£º±àÒëΪ 32-λĿ±êÎļþµ« %s ÊÇ 64-λµÄ"
+
+#: elf32-sh64.c:206 elf64-sh64.c:2367
+#, c-format
+msgid "%s: compiled as 64-bit object and %s is 32-bit"
+msgstr "%s£º±àÒëΪ 64-λĿ±êÎļþµ« %s ÊÇ 32-λµÄ"
+
+#: elf32-sh64.c:208 elf64-sh64.c:2369
+#, c-format
+msgid "%s: object size does not match that of target %s"
+msgstr "%s£ºÄ¿±êÎļþ´óСºÍÄ¿±ê %s ²»Æ¥Åä"
+
+#: elf32-sh64.c:440 elf64-sh64.c:2941
+#, c-format
+msgid "%s: encountered datalabel symbol in input"
+msgstr "%s£ºÔÚÊäÈëÖÐÓöµ½Êý¾Ý±êÇ©·ûºÅ"
+
+#: elf32-sh64.c:523
+msgid "PTB mismatch: a SHmedia address (bit 0 == 1)"
+msgstr "PTB ²»Æ¥Å䣺SHmedia µØÖ· (λ 0 == 1)"
+
+#: elf32-sh64.c:526
+msgid "PTA mismatch: a SHcompact address (bit 0 == 0)"
+msgstr "PTA ²»Æ¥Å䣺SHcompact µØÖ· (λ 0 == 0)"
+
+#: elf32-sh64.c:544
+#, c-format
+msgid "%s: GAS error: unexpected PTB insn with R_SH_PT_16"
+msgstr "%s£ºGAS ´íÎó£ºÒâÍâµÄ´øÓÐ R_SH_PT_16 µÄ PTB Ö¸Áî"
+
+#: elf32-sh64.c:593 elf64-sh64.c:1703
+#, c-format
+msgid "%s: error: unaligned relocation type %d at %08x reloc %08x\n"
+msgstr ""
+
+#: elf32-sh64.c:677
+#, c-format
+msgid "%s: could not write out added .cranges entries"
+msgstr "%s£ºÎÞ·¨Ð´³ö .cranges ÌõÄ¿"
+
+#: elf32-sh64.c:739
+#, c-format
+msgid "%s: could not write out sorted .cranges entries"
+msgstr "%s£ºÎÞ·¨Ð´³ö¾­ÅÅÐòµÄ .cranges ÌõÄ¿"
+
+#: elf32-sparc.c:1535 elf64-sparc.c:2224
+#, c-format
+msgid "%s: probably compiled without -fPIC?"
+msgstr ""
+
+#: elf32-sparc.c:2002
+#, c-format
+msgid "%s: compiled for a 64 bit system and target is 32 bit"
+msgstr "%s£ºÎª 64 λϵͳ±àÒ뵫Ŀ±êƽ̨ÊÇ 32 λµÄ"
+
+#: elf32-sparc.c:2016
+#, c-format
+msgid "%s: linking little endian files with big endian files"
+msgstr "%s£ºÁ¬½ÓС¶ËÎļþºÍ´ó¶ËÎļþ"
+
+#: elf32-v850.c:682
+#, c-format
+msgid "Variable `%s' cannot occupy in multiple small data regions"
+msgstr "±äÁ¿¡°%s¡±²»ÄÜÕ¼¾Ý¶à¸öСÊý¾ÝÇø"
+
+#: elf32-v850.c:685
+#, c-format
+msgid "Variable `%s' can only be in one of the small, zero, and tiny data regions"
+msgstr "±äÁ¿¡°%s¡±Ö»ÄܳöÏÖÔÚСÊý¾ÝÇø¡¢ÁãÊý¾ÝÇø¡¢Î¢Êý¾ÝÇøÖ®Ò»"
+
+#: elf32-v850.c:688
+#, c-format
+msgid "Variable `%s' cannot be in both small and zero data regions simultaneously"
+msgstr "±äÁ¿¡°%s¡±²»ÄÜͬʱ³öÏÖÔÚСÊý¾ÝÇøºÍÁãÊý¾ÝÇø"
+
+#: elf32-v850.c:691
+#, c-format
+msgid "Variable `%s' cannot be in both small and tiny data regions simultaneously"
+msgstr "±äÁ¿¡°%s¡±²»ÄÜͬʱ³öÏÖÔÚСÊý¾ÝÇøºÍ΢Êý¾ÝÇø"
+
+#: elf32-v850.c:694
+#, c-format
+msgid "Variable `%s' cannot be in both zero and tiny data regions simultaneously"
+msgstr "±äÁ¿¡°%s¡±²»ÄÜͬʱ³öÏÖÔÚÁãÊý¾ÝÇøºÍ΢Êý¾ÝÇø"
+
+#: elf32-v850.c:1072
+msgid "FAILED to find previous HI16 reloc\n"
+msgstr "Ñ°ÕÒÉÏÒ»¸ö HI16 Öض¨Î»Ê§°Ü\n"
+
+#: elf32-v850.c:1703
+msgid "could not locate special linker symbol __gp"
+msgstr "ÎÞ·¨¶¨Î»ÌØÊâÁ¬½ÓÆ÷·ûºÅ __gp"
+
+#: elf32-v850.c:1707
+msgid "could not locate special linker symbol __ep"
+msgstr "ÎÞ·¨¶¨Î»ÌØÊâÁ¬½ÓÆ÷·ûºÅ __ep"
+
+#: elf32-v850.c:1711
+msgid "could not locate special linker symbol __ctbp"
+msgstr "ÎÞ·¨¶¨Î»ÌØÊâÁª»úÆ÷·ûºÅ __ctbp"
+
+#: elf32-v850.c:1875
+#, c-format
+msgid "%s: Architecture mismatch with previous modules"
+msgstr "%s£ºÌåϵ½á¹¹Í¬Ç°Ò»¸öÄ£¿é²»Æ¥Åä"
+
+#: elf32-v850.c:1895
+#, c-format
+msgid "private flags = %lx: "
+msgstr "˽ÓбêÖ¾ = %lx£º"
+
+#: elf32-v850.c:1900
+msgid "v850 architecture"
+msgstr "v850 Ìåϵ½á¹¹"
+
+#: elf32-v850.c:1901
+msgid "v850e architecture"
+msgstr "v850e Ìåϵ½á¹¹"
+
+#: elf32-v850.c:1902
+msgid "v850ea architecture"
+msgstr "v850ea Ìåϵ½á¹¹"
+
+#: elf32-vax.c:546
+msgid " [nonpic]"
+msgstr ""
+
+#: elf32-vax.c:549
+msgid " [d-float]"
+msgstr ""
+
+#: elf32-vax.c:552
+msgid " [g-float]"
+msgstr ""
+
+#: elf32-vax.c:674
+#, c-format
+msgid "%s: warning: GOT addend of %ld to `%s' does not match previous GOT addend of %ld"
+msgstr ""
+
+#: elf32-vax.c:1679
+#, c-format
+msgid "%s: warning: PLT addend of %d to `%s' from %s section ignored"
+msgstr ""
+
+#: elf32-vax.c:1814
+#, c-format
+msgid "%s: warning: %s relocation against symbol `%s' from %s section"
+msgstr ""
+
+#: elf32-vax.c:1820
+#, c-format
+msgid "%s: warning: %s relocation to 0x%x from %s section"
+msgstr ""
+
+#: elf32-ia64.c:2280 elf32-xstormy16.c:414 elf64-ia64.c:2280
+msgid "non-zero addend in @fptr reloc"
+msgstr ""
+
+#: elf64-alpha.c:1097
+msgid "GPDISP relocation did not find ldah and lda instructions"
+msgstr "GPDISP Öض¨Î»ÎÞ·¨ÕÒµ½ ldah ºÍ lda Ö¸Áî"
+
+#: elf64-alpha.c:3675
+#, c-format
+msgid "%s: .got subsegment exceeds 64K (size %d)"
+msgstr "%s£º.got ×Ó½Ú³¬¹ýÁË 64K (´óС %d)"
+
+#: elf64-alpha.c:4498 elf64-alpha.c:4510
+#, c-format
+msgid "%s: gp-relative relocation against dynamic symbol %s"
+msgstr ""
+
+#: elf64-alpha.c:4536 elf64-alpha.c:4676
+#, c-format
+msgid "%s: pc-relative relocation against dynamic symbol %s"
+msgstr ""
+
+#: elf64-alpha.c:4564
+#, c-format
+msgid "%s: change in gp: BRSGP %s"
+msgstr ""
+
+#: elf64-alpha.c:4589
+msgid "<unknown>"
+msgstr "<δ֪>"
+
+#: elf64-alpha.c:4594
+#, c-format
+msgid "%s: !samegp reloc against symbol without .prologue: %s"
+msgstr ""
+
+#: elf64-alpha.c:4639
+#, c-format
+msgid "%s: unhandled dynamic relocation against %s"
+msgstr "%s£ºÎ´´¦ÀíµÄ¹ØÓÚ %s µÄ¶¯Ì¬Öض¨Î»"
+
+#: elf64-alpha.c:4752
+#, c-format
+msgid "%s: dtp-relative relocation against dynamic symbol %s"
+msgstr ""
+
+#: elf64-alpha.c:4775
+#, c-format
+msgid "%s: tp-relative relocation against dynamic symbol %s"
+msgstr ""
+
+#: elf64-hppa.c:2080
+#, c-format
+msgid "stub entry for %s cannot load .plt, dp offset = %ld"
+msgstr ""
+
+#: elf64-mmix.c:1002
+#, c-format
+msgid ""
+"%s: Internal inconsistency error for value for\n"
+" linker-allocated global register: linked: 0x%lx%08lx != relaxed: 0x%lx%08lx\n"
+msgstr ""
+
+#: elf64-mmix.c:1386
+#, c-format
+msgid "%s: base-plus-offset relocation against register symbol: (unknown) in %s"
+msgstr ""
+
+#: elf64-mmix.c:1391
+#, c-format
+msgid "%s: base-plus-offset relocation against register symbol: %s in %s"
+msgstr ""
+
+#: elf64-mmix.c:1435
+#, c-format
+msgid "%s: register relocation against non-register symbol: (unknown) in %s"
+msgstr ""
+
+#: elf64-mmix.c:1440
+#, c-format
+msgid "%s: register relocation against non-register symbol: %s in %s"
+msgstr ""
+
+#: elf64-mmix.c:1477
+#, c-format
+msgid "%s: directive LOCAL valid only with a register or absolute value"
+msgstr "%s£ºÖ¸Áî LOCAL Ö»¶Ô¼Ä´æÆ÷»ò¾ø¶ÔÖµÓÐЧ"
+
+#: elf64-mmix.c:1505
+#, c-format
+msgid "%s: LOCAL directive: Register $%ld is not a local register. First global register is $%ld."
+msgstr "%s£ºLOCAL Ö¸Á¼Ä´æÆ÷ $%ld ²»ÊDZ¾µØ¼Ä´æÆ÷¡£ µÚÒ»¸öÈ«¾Ö¼Ä´æÆ÷ÊÇ $%ld¡£"
+
+#: elf64-mmix.c:1965
+#, c-format
+msgid "%s: Error: multiple definition of `%s'; start of %s is set in a earlier linked file\n"
+msgstr "%s£º´íÎó£ºÖظ´¶¨Òå¡°%s¡±£»%s µÄÆðµãÔÚ´ËÇ°Á¬½ÓµÄÎļþÖÐÒÑÉ趨\n"
+
+#: elf64-mmix.c:2024
+msgid "Register section has contents\n"
+msgstr "¼Ä´æÆ÷½ÚÓÐÄÚÈÝ\n"
+
+#: elf64-mmix.c:2186
+#, c-format
+msgid ""
+"Internal inconsistency: remaining %u != max %u.\n"
+" Please report this bug."
+msgstr ""
+"ÄÚ²¿²»Ò»Ö£ºÊ£Óà %u != ×î´ó %u¡£\n"
+" Ç뱨¸æ¸Ã bug¡£"
+
+#: elf64-ppc.c:1669 libbfd.c:1435
+#, c-format
+msgid "%s: compiled for a big endian system and target is little endian"
+msgstr "%s£ºÎª´ó¶Ëϵͳ±àÒ뵫Ŀ±êƽ̨ÊÇС¶ËµÄ"
+
+#: elf64-ppc.c:1671 libbfd.c:1437
+#, c-format
+msgid "%s: compiled for a little endian system and target is big endian"
+msgstr "%s£ºÎªÐ¡¶Ëϵͳ±àÒ뵫Ŀ±êƽ̨ÊÇ´ó¶ËµÄ"
+
+#: elf64-ppc.c:3610
+#, c-format
+msgid "%s: unexpected reloc type %u in .opd section"
+msgstr "%s£º.opd ½ÚÖÐÒâÍâµÄÖض¨Î»ÀàÐÍ %u"
+
+#: elf64-ppc.c:3630
+#, c-format
+msgid "%s: .opd is not a regular array of opd entries"
+msgstr "%s£º.opd ²»ÊÇ opd ÌõÄ¿µÄÆÕͨÊý×é"
+
+#: elf64-ppc.c:3672
+#, c-format
+msgid "%s: undefined sym `%s' in .opd section"
+msgstr "%s£º.opd ½ÚÖÐ䶨ÒåµÄ¡°%s¡±"
+
+#: elf64-ppc.c:4397
+#, c-format
+msgid "can't find branch stub `%s'"
+msgstr ""
+
+#: elf64-ppc.c:4436 elf64-ppc.c:4501
+#, c-format
+msgid "linkage table error against `%s'"
+msgstr ""
+
+#: elf64-ppc.c:4573
+#, c-format
+msgid "can't build branch stub `%s'"
+msgstr ""
+
+#: elf64-ppc.c:5179
+msgid "stubs don't match calculated size"
+msgstr ""
+
+#: elf64-ppc.c:5828
+#, c-format
+msgid "%s: Relocation %s is not supported for symbol %s."
+msgstr "%s£ºÖض¨Î» %s ²»Ö§³Ö·ûºÅ %s¡£"
+
+#: elf64-ppc.c:5872
+#, c-format
+msgid "%s: error: relocation %s not a multiple of 4"
+msgstr "%s£º´íÎó£ºÖض¨Î» %s ²»ÊÇ 4 µÄ±¶Êý"
+
+#: elf64-sparc.c:1280
+#, c-format
+msgid "%s: check_relocs: unhandled reloc type %d"
+msgstr "%s£ºcheck_relocs£ºÎ´´¦ÀíµÄÖض¨Î»ÀàÐÍ %d"
+
+#: elf64-sparc.c:1317
+#, c-format
+msgid "%s: Only registers %%g[2367] can be declared using STT_REGISTER"
+msgstr "%s£ºÖ»ÓмĴæÆ÷ %%g[2367] ¿ÉÒÔÓà STT_REGISTER À´ÉùÃ÷"
+
+#: elf64-sparc.c:1337
+#, c-format
+msgid "Register %%g%d used incompatibly: %s in %s, previously %s in %s"
+msgstr "²»¼æÈݵØʹÓüĴæÆ÷ %%g%1$d£ºÔÚ %3$s ÖÐΪ %2$s£¬ÔÚÇ°ÃæµÄ %5$s ÖÐΪ %4$s"
+
+#: elf64-sparc.c:1360
+#, c-format
+msgid "Symbol `%s' has differing types: REGISTER in %s, previously %s in %s"
+msgstr "·ûºÅ¡°%1$s¡±µÄÀàÐͲ»Í¬£º%2$s ÖÐΪ¼Ä´æÆ÷£¬ÔÚÇ°ÃæµÄ %4$s ÖÐΪ %3$s"
+
+#: elf64-sparc.c:1406
+#, c-format
+msgid "Symbol `%s' has differing types: %s in %s, previously REGISTER in %s"
+msgstr ""
+
+#: elf64-sparc.c:2970
+#, c-format
+msgid "%s: linking UltraSPARC specific with HAL specific code"
+msgstr ""
+
+#: elfcode.h:1198
+#, c-format
+msgid "%s: version count (%ld) does not match symbol count (%ld)"
+msgstr "%s£º°æ±¾¼ÆÊý (%ld) ÎÞ·¨Æ¥Åä·ûºÅ¼ÆÊý (%ld)"
+
+#: elflink.c:440
+#, c-format
+msgid "%s: Section %s is too large to add hole of %ld bytes"
+msgstr ""
+
+#: elflink.h:1090
+#, c-format
+msgid "%s: warning: unexpected redefinition of `%s'"
+msgstr "%s£º¾¯¸æ£ºÒâÍâµÄÖØж¨Òå¡°%s¡±"
+
+#: elflink.h:1727
+#, c-format
+msgid "%s: %s: invalid version %u (max %d)"
+msgstr "%s£º%s£ºÎÞЧµÄ°æ±¾ %u (×î´ó %d)"
+
+#: elflink.h:1768
+#, c-format
+msgid "%s: %s: invalid needed version %d"
+msgstr "%s£º%s£ºÎÞЧµÄ±Ø±¸°æ±¾ %d"
+
+#: elflink.h:1890
+#, c-format
+msgid "Warning: size of symbol `%s' changed from %lu to %lu in %s"
+msgstr "¾¯¸æ£º%4$s ÖеķûºÅ¡°%1$s¡±µÄ´óСÓÉ %2$lu ±äΪ %3$lu"
+
+#: elflink.h:3174
+#, c-format
+msgid "%s: .preinit_array section is not allowed in DSO"
+msgstr "%s£ºDSO Öв»ÔÊÐí³öÏÖ .preinit_array ½Ú"
+
+#: elflink.h:4030
+#, c-format
+msgid "warning: type and size of dynamic symbol `%s' are not defined"
+msgstr "¾¯¸æ£º¶¯Ì¬·ûºÅ¡°%s¡±µÄÀàÐͺʹóС䶨Òå"
+
+#: elflink.h:4345
+#, c-format
+msgid "%s: undefined versioned symbol name %s"
+msgstr "%s£ºÎ´¶¨ÒåµÄÓа汾·ûºÅÃû %s"
+
+#: elflink.h:4611 elflink.h:4619 elflink.h:6508 elflink.h:7600
+msgid "Error: out of memory"
+msgstr "´íÎó£ºÃ»ÓÐÄÚ´æ"
+
+#: elflink.h:4781
+msgid "Not enough memory to sort relocations"
+msgstr "ûÓÐ×ã¹»µÄÄÚ´æ½øÐÐÖض¨Î»ÅÅÐò"
+
+#: elflink.h:5682 elflink.h:5725
+#, c-format
+msgid "%s: could not find output section %s"
+msgstr "%s£ºÎÞ·¨ÕÒµ½Êä³ö½Ú %s"
+
+#: elflink.h:5688
+#, c-format
+msgid "warning: %s section has zero size"
+msgstr "¾¯¸æ£º%s ½ÚµÄ´óСΪÁã"
+
+#: elflink.h:6275
+#, c-format
+msgid "%s: could not find output section %s for input section %s"
+msgstr "%1$s£ºÎÞ·¨ÎªÊäÈë½Ú %3$s ÕÒµ½Êä³ö½Ú %2$s"
+
+#: elflink.h:6486
+#, c-format
+msgid "%s: relocation size mismatch in %s section %s"
+msgstr ""
+
+#: elflink.h:6849
+msgid "warning: relocation against removed section; zeroing"
+msgstr "¾¯¸æ£º¹ØÓÚÒÑɾ³ýµÄ½ÚµÄÖض¨Î»£»ÕýÔÚÇåÁã"
+
+#: elflink.h:6879
+msgid "warning: relocation against removed section"
+msgstr "¾¯¸æ£º¹ØÓÚÒÑɾ³ýµÄ½ÚµÄÖض¨Î»"
+
+#: elflink.h:6892
+#, c-format
+msgid "local symbols in discarded section %s"
+msgstr "ÒѽûÓÃµÄ½Ú %s Öеı¾µØ·ûºÅ"
+
+#: elfxx-mips.c:734
+msgid "static procedure (no name)"
+msgstr "¾²Ì¬¹ý³Ì (ÎÞÃû³Æ)"
+
+#: elfxx-mips.c:1601
+msgid "not enough GOT space for local GOT entries"
+msgstr "ûÓÐ×ã¹»µÄ GOT ¿Õ¼äÓÃÓÚ GOT ÌõÄ¿"
+
+#: elfxx-mips.c:2750
+#, c-format
+msgid "%s: %s+0x%lx: jump to stub routine which is not jal"
+msgstr ""
+
+#: elfxx-mips.c:4270
+#, c-format
+msgid "%s: Malformed reloc detected for section %s"
+msgstr ""
+
+#: elfxx-mips.c:4348
+#, c-format
+msgid "%s: CALL16 reloc at 0x%lx not against global symbol"
+msgstr ""
+
+#: elfxx-mips.c:7301
+#, c-format
+msgid "%s: illegal section name `%s'"
+msgstr "%s£º·Ç·¨µÄ½ÚÃû¡°%s¡±"
+
+#: elfxx-mips.c:7615
+#, c-format
+msgid "%s: linking PIC files with non-PIC files"
+msgstr "%s£º½« PIC Îļþͬ·Ç-PIC ÎļþÁ¬½Ó"
+
+#: elfxx-mips.c:7625
+#, c-format
+msgid "%s: linking abicalls files with non-abicalls files"
+msgstr ""
+
+#: elfxx-mips.c:7654
+#, c-format
+msgid "%s: ISA mismatch (-mips%d) with previous modules (-mips%d)"
+msgstr "%s£ºISA (-mips%d) ͬǰÃæµÄÄ£¿é(-mips%d)²»Æ¥Åä"
+
+#: elfxx-mips.c:7676
+#, c-format
+msgid "%s: ISA mismatch (%d) with previous modules (%d)"
+msgstr "%s£ºISA (%d) ͬǰÃæµÄÄ£¿é (%d) ²»Æ¥Åä"
+
+#: elfxx-mips.c:7699
+#, c-format
+msgid "%s: ABI mismatch: linking %s module with previous %s modules"
+msgstr "%s£ºABI ²»Æ¥Å䣺ÕýÔÚ½«Ä£¿é %s ͬǰһ¸öÄ£¿é %s ½øÐÐÁ¬½Ó"
+
+#: elfxx-mips.c:7759
+msgid " [abi=O32]"
+msgstr " [abi=O32]"
+
+#: elfxx-mips.c:7761
+msgid " [abi=O64]"
+msgstr " [abi=O64]"
+
+#: elfxx-mips.c:7763
+msgid " [abi=EABI32]"
+msgstr " [abi=EABI32]"
+
+#: elfxx-mips.c:7765
+msgid " [abi=EABI64]"
+msgstr " [abi=EABI64]"
+
+#: elfxx-mips.c:7767
+msgid " [abi unknown]"
+msgstr " [abi δ֪]"
+
+#: elfxx-mips.c:7769
+msgid " [abi=N32]"
+msgstr " [abi=N32]"
+
+#: elfxx-mips.c:7771
+msgid " [abi=64]"
+msgstr " [abi=64]"
+
+#: elfxx-mips.c:7773
+msgid " [no abi set]"
+msgstr ""
+
+#: elfxx-mips.c:7776
+msgid " [mips1]"
+msgstr " [mips1]"
+
+#: elfxx-mips.c:7778
+msgid " [mips2]"
+msgstr " [mips2]"
+
+#: elfxx-mips.c:7780
+msgid " [mips3]"
+msgstr " [mips3]"
+
+#: elfxx-mips.c:7782
+msgid " [mips4]"
+msgstr " [mips4]"
+
+#: elfxx-mips.c:7784
+msgid " [mips5]"
+msgstr " [mips5]"
+
+#: elfxx-mips.c:7786
+msgid " [mips32]"
+msgstr " [mips32]"
+
+#: elfxx-mips.c:7788
+msgid " [mips64]"
+msgstr " [mips64]"
+
+#: elfxx-mips.c:7790
+msgid " [unknown ISA]"
+msgstr " [δ֪µÄ ISA]"
+
+#: elfxx-mips.c:7793
+msgid " [mdmx]"
+msgstr " [mdmx]"
+
+#: elfxx-mips.c:7796
+msgid " [mips16]"
+msgstr " [mips16]"
+
+#: elfxx-mips.c:7799
+msgid " [32bitmode]"
+msgstr " [32λģʽ]"
+
+#: elfxx-mips.c:7801
+msgid " [not 32bitmode]"
+msgstr " [·Ç 32λģʽ]"
+
+#: i386linux.c:458 m68klinux.c:462 sparclinux.c:459
+#, c-format
+msgid "Output file requires shared library `%s'\n"
+msgstr "Êä³öÎļþÐèÒª¹²Ïí¿â¡°%s¡±\n"
+
+#: i386linux.c:466 m68klinux.c:470 sparclinux.c:467
+#, c-format
+msgid "Output file requires shared library `%s.so.%s'\n"
+msgstr "Êä³öÎļþÐèÒª¹²Ïí¿â¡°%s.so.%s¡±\n"
+
+#: i386linux.c:655 i386linux.c:705 m68klinux.c:662 m68klinux.c:710
+#: sparclinux.c:657 sparclinux.c:707
+#, c-format
+msgid "Symbol %s not defined for fixups\n"
+msgstr ""
+
+#: i386linux.c:729 m68klinux.c:734 sparclinux.c:731
+msgid "Warning: fixup count mismatch\n"
+msgstr ""
+
+#: ieee.c:235
+#, c-format
+msgid "%s: string too long (%d chars, max 65535)"
+msgstr "%s£º×Ö·û´®¹ý³¤ (%d ×Ö·û£¬×î´ó 65535)"
+
+#: ieee.c:365
+#, c-format
+msgid "%s: unrecognized symbol `%s' flags 0x%x"
+msgstr "%s£ºÎÞ·¨Ê¶±ðµÄ¡°%s¡±±êÖ¾ 0x%x"
+
+#: ieee.c:877
+#, c-format
+msgid "%s: unimplemented ATI record %u for symbol %u"
+msgstr ""
+
+#: ieee.c:902
+#, c-format
+msgid "%s: unexpected ATN type %d in external part"
+msgstr ""
+
+#: ieee.c:924
+#, c-format
+msgid "%s: unexpected type after ATN"
+msgstr "%s£ºATN Ö®ºó³öÏÖÒâÍâµÄÀàÐÍ"
+
+#: ihex.c:258
+#, c-format
+msgid "%s:%d: unexpected character `%s' in Intel Hex file\n"
+msgstr "%s£º%d£ºIntel Ê®Áù½øÖÆÎļþÖеÄÒâÍâ×Ö·û¡°%s\n"
+
+#: ihex.c:366
+#, c-format
+msgid "%s:%u: bad checksum in Intel Hex file (expected %u, found %u)"
+msgstr "%s£º%u£ºIntel Ê®Áù½øÖÆÎļþÖеÄУÑéºÍ´íÎó (ӦΪ %u¡¢ÊµÎª %u)"
+
+#: ihex.c:420
+#, c-format
+msgid "%s:%u: bad extended address record length in Intel Hex file"
+msgstr ""
+
+#: ihex.c:437
+#, c-format
+msgid "%s:%u: bad extended start address length in Intel Hex file"
+msgstr ""
+
+#: ihex.c:454
+#, c-format
+msgid "%s:%u: bad extended linear address record length in Intel Hex file"
+msgstr ""
+
+#: ihex.c:471
+#, c-format
+msgid "%s:%u: bad extended linear start address length in Intel Hex file"
+msgstr ""
+
+#: ihex.c:488
+#, c-format
+msgid "%s:%u: unrecognized ihex type %u in Intel Hex file\n"
+msgstr ""
+
+#: ihex.c:607
+#, c-format
+msgid "%s: internal error in ihex_read_section"
+msgstr ""
+
+#: ihex.c:642
+#, c-format
+msgid "%s: bad section length in ihex_read_section"
+msgstr ""
+
+#: ihex.c:860
+#, c-format
+msgid "%s: address 0x%s out of range for Intel Hex file"
+msgstr ""
+
+#: libbfd.c:492
+#, c-format
+msgid "not mapping: data=%lx mapped=%d\n"
+msgstr ""
+
+#: libbfd.c:495
+msgid "not mapping: env var not set\n"
+msgstr ""
+
+#: libbfd.c:1466
+#, c-format
+msgid "Deprecated %s called at %s line %d in %s\n"
+msgstr ""
+
+#: libbfd.c:1469
+#, c-format
+msgid "Deprecated %s called\n"
+msgstr ""
+
+#: linker.c:1873
+#, c-format
+msgid "%s: indirect symbol `%s' to `%s' is a loop"
+msgstr ""
+
+#: linker.c:2776
+#, c-format
+msgid "Attempt to do relocateable link with %s input and %s output"
+msgstr ""
+
+#: merge.c:892
+#, c-format
+msgid "%s: access beyond end of merged section (%ld + %ld)"
+msgstr ""
+
+#: mmo.c:460
+#, c-format
+msgid "%s: No core to allocate section name %s\n"
+msgstr ""
+
+#: mmo.c:536
+#, c-format
+msgid "%s: No core to allocate a symbol %d bytes long\n"
+msgstr ""
+
+#: mmo.c:1245
+#, c-format
+msgid "%s: invalid mmo file: initialization value for $255 is not `Main'\n"
+msgstr ""
+
+#: mmo.c:1391
+#, c-format
+msgid "%s: unsupported wide character sequence 0x%02X 0x%02X after symbol name starting with `%s'\n"
+msgstr ""
+
+#: mmo.c:1633
+#, c-format
+msgid "%s: invalid mmo file: unsupported lopcode `%d'\n"
+msgstr ""
+
+#: mmo.c:1643
+#, c-format
+msgid "%s: invalid mmo file: expected YZ = 1 got YZ = %d for lop_quote\n"
+msgstr ""
+
+#: mmo.c:1679
+#, c-format
+msgid "%s: invalid mmo file: expected z = 1 or z = 2, got z = %d for lop_loc\n"
+msgstr ""
+
+#: mmo.c:1725
+#, c-format
+msgid "%s: invalid mmo file: expected z = 1 or z = 2, got z = %d for lop_fixo\n"
+msgstr ""
+
+#: mmo.c:1764
+#, c-format
+msgid "%s: invalid mmo file: expected y = 0, got y = %d for lop_fixrx\n"
+msgstr ""
+
+#: mmo.c:1773
+#, c-format
+msgid "%s: invalid mmo file: expected z = 16 or z = 24, got z = %d for lop_fixrx\n"
+msgstr ""
+
+#: mmo.c:1796
+#, c-format
+msgid "%s: invalid mmo file: leading byte of operand word must be 0 or 1, got %d for lop_fixrx\n"
+msgstr ""
+
+#: mmo.c:1819
+#, c-format
+msgid "%s: cannot allocate file name for file number %d, %d bytes\n"
+msgstr ""
+
+#: mmo.c:1839
+#, c-format
+msgid "%s: invalid mmo file: file number %d `%s', was already entered as `%s'\n"
+msgstr ""
+
+#: mmo.c:1852
+#, c-format
+msgid "%s: invalid mmo file: file name for number %d was not specified before use\n"
+msgstr ""
+
+#: mmo.c:1958
+#, c-format
+msgid "%s: invalid mmo file: fields y and z of lop_stab non-zero, y: %d, z: %d\n"
+msgstr ""
+
+#: mmo.c:1994
+#, c-format
+msgid "%s: invalid mmo file: lop_end not last item in file\n"
+msgstr ""
+
+#: mmo.c:2007
+#, c-format
+msgid "%s: invalid mmo file: YZ of lop_end (%ld) not equal to the number of tetras to the preceding lop_stab (%ld)\n"
+msgstr ""
+
+#: mmo.c:2670
+#, c-format
+msgid "%s: invalid symbol table: duplicate symbol `%s'\n"
+msgstr ""
+
+#: mmo.c:2921
+#, c-format
+msgid "%s: Bad symbol definition: `Main' set to %s rather than the start address %s\n"
+msgstr ""
+
+#: mmo.c:3011
+#, c-format
+msgid "%s: warning: symbol table too large for mmo, larger than 65535 32-bit words: %d. Only `Main' will be emitted.\n"
+msgstr ""
+
+#: mmo.c:3056
+#, c-format
+msgid "%s: internal error, symbol table changed size from %d to %d words\n"
+msgstr ""
+
+#: mmo.c:3111
+#, c-format
+msgid "%s: internal error, internal register section %s had contents\n"
+msgstr ""
+
+#: mmo.c:3163
+#, c-format
+msgid "%s: no initialized registers; section length 0\n"
+msgstr ""
+
+#: mmo.c:3169
+#, c-format
+msgid "%s: too many initialized registers; section length %ld\n"
+msgstr ""
+
+#: mmo.c:3174
+#, c-format
+msgid "%s: invalid start address for initialized registers of length %ld: 0x%lx%08lx\n"
+msgstr ""
+
+#: oasys.c:1029
+#, c-format
+msgid "%s: can not represent section `%s' in oasys"
+msgstr ""
+
+#: osf-core.c:132
+#, c-format
+msgid "Unhandled OSF/1 core file section type %d\n"
+msgstr ""
+
+#: pe-mips.c:658
+#, c-format
+msgid "%s: `ld -r' not supported with PE MIPS objects\n"
+msgstr ""
+
+#. OK, at this point the following variables are set up:
+#. src = VMA of the memory we're fixing up
+#. mem = pointer to memory we're fixing up
+#. val = VMA of what we need to refer to
+#.
+#: pe-mips.c:794
+#, c-format
+msgid "%s: unimplemented %s\n"
+msgstr "%s£ºÎ´ÊµÏÖµÄ %s\n"
+
+#: pe-mips.c:820
+#, c-format
+msgid "%s: jump too far away\n"
+msgstr "%s£ºÌøת¹ýÔ¶\n"
+
+#: pe-mips.c:847
+#, c-format
+msgid "%s: bad pair/reflo after refhi\n"
+msgstr ""
+
+#. XXX code yet to be written.
+#: peicode.h:785
+#, c-format
+msgid "%s: Unhandled import type; %x"
+msgstr "%s£ºÎ´´¦ÀíµÄµ¼ÈëÀàÐÍ£»%x"
+
+#: peicode.h:790
+#, c-format
+msgid "%s: Unrecognised import type; %x"
+msgstr "%s£ºÎ´Ê¶±ðµÄµ¼ÈëÀàÐÍ£»%x"
+
+#: peicode.h:804
+#, c-format
+msgid "%s: Unrecognised import name type; %x"
+msgstr "%s£ºÎ´Ê¶±ðµÄµ¼ÈëÃû×ÖÀàÐÍ£»%x"
+
+#: peicode.h:1162
+#, c-format
+msgid "%s: Unrecognised machine type (0x%x) in Import Library Format archive"
+msgstr ""
+
+#: peicode.h:1174
+#, c-format
+msgid "%s: Recognised but unhandled machine type (0x%x) in Import Library Format archive"
+msgstr ""
+
+#: peicode.h:1191
+#, c-format
+msgid "%s: size field is zero in Import Library Format header"
+msgstr ""
+
+#: peicode.h:1219
+#, c-format
+msgid "%s: string not null terminated in ILF object file."
+msgstr ""
+
+#: ppcboot.c:416
+msgid ""
+"\n"
+"ppcboot header:\n"
+msgstr ""
+
+#: ppcboot.c:417
+#, c-format
+msgid "Entry offset = 0x%.8lx (%ld)\n"
+msgstr "ÌõÄ¿Æ«ÒÆÁ¿ = 0x%.8lx (%ld)\n"
+
+#: ppcboot.c:418
+#, c-format
+msgid "Length = 0x%.8lx (%ld)\n"
+msgstr "³¤¶È = 0x%.8lx (%ld)\n"
+
+#: ppcboot.c:421
+#, c-format
+msgid "Flag field = 0x%.2x\n"
+msgstr "±êÖ¾Óò = 0x%.2x\n"
+
+#: ppcboot.c:427
+#, c-format
+msgid "Partition name = \"%s\"\n"
+msgstr "·ÖÇøÃû = \"%s\"\n"
+
+#: ppcboot.c:446
+#, c-format
+msgid ""
+"\n"
+"Partition[%d] start = { 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x }\n"
+msgstr ""
+"\n"
+"·ÖÇø[%d] Æðµã = { 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x }\n"
+
+#: ppcboot.c:452
+#, c-format
+msgid "Partition[%d] end = { 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x }\n"
+msgstr "·ÖÇø[%d] ÖÕµã = { 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x }\n"
+
+#: ppcboot.c:458
+#, c-format
+msgid "Partition[%d] sector = 0x%.8lx (%ld)\n"
+msgstr "·ÖÇø[%d] ÉÈÇø = 0x%.8lx (%ld)\n"
+
+#: ppcboot.c:459
+#, c-format
+msgid "Partition[%d] length = 0x%.8lx (%ld)\n"
+msgstr "·ÖÇø[%d] ³¤¶È = 0x%.8lx (%ld)\n"
+
+#: som.c:5398
+msgid "som_sizeof_headers unimplemented"
+msgstr ""
+
+#: srec.c:301
+#, c-format
+msgid "%s:%d: Unexpected character `%s' in S-record file\n"
+msgstr ""
+
+#: stabs.c:319
+#, c-format
+msgid "%s(%s+0x%lx): Stabs entry has invalid string index."
+msgstr ""
+
+#: syms.c:1044
+msgid "Unsupported .stab relocation"
+msgstr "²»Ö§³ÖµÄ .stab Öض¨Î»"
+
+#: vms-gsd.c:356
+#, c-format
+msgid "bfd_make_section (%s) failed"
+msgstr ""
+
+#: vms-gsd.c:371
+#, c-format
+msgid "bfd_set_section_flags (%s, %x) failed"
+msgstr ""
+
+#: vms-gsd.c:407
+#, c-format
+msgid "Size mismatch section %s=%lx, %s=%lx"
+msgstr ""
+
+#: vms-gsd.c:702
+#, c-format
+msgid "unknown gsd/egsd subtype %d"
+msgstr ""
+
+#: vms-hdr.c:406
+msgid "Object module NOT error-free !\n"
+msgstr ""
+
+#: vms-misc.c:543
+#, c-format
+msgid "Stack overflow (%d) in _bfd_vms_push"
+msgstr ""
+
+#: vms-misc.c:561
+msgid "Stack underflow in _bfd_vms_pop"
+msgstr ""
+
+#: vms-misc.c:919
+msgid "_bfd_vms_output_counted called with zero bytes"
+msgstr ""
+
+#: vms-misc.c:924
+msgid "_bfd_vms_output_counted called with too many bytes"
+msgstr ""
+
+#: vms-misc.c:1055
+#, c-format
+msgid "Symbol %s replaced by %s\n"
+msgstr ""
+
+#: vms-misc.c:1117
+#, c-format
+msgid "failed to enter %s"
+msgstr ""
+
+#: vms-tir.c:81
+msgid "No Mem !"
+msgstr ""
+
+#: vms-tir.c:362
+#, c-format
+msgid "bad section index in %s"
+msgstr "%s ÖеĴíÎó½ÚË÷Òý"
+
+#: vms-tir.c:375
+#, c-format
+msgid "unsupported STA cmd %s"
+msgstr "²»Ö§³ÖµÄ STA ÃüÁî %s"
+
+#: vms-tir.c:380 vms-tir.c:1240
+#, c-format
+msgid "reserved STA cmd %d"
+msgstr ""
+
+#: vms-tir.c:491 vms-tir.c:514
+#, c-format
+msgid "%s: no symbol \"%s\""
+msgstr ""
+
+#. unsigned shift
+#. rotate
+#. Redefine symbol to current location.
+#. Define a literal.
+#: vms-tir.c:581 vms-tir.c:693 vms-tir.c:803 vms-tir.c:821 vms-tir.c:829
+#: vms-tir.c:838 vms-tir.c:1563
+#, c-format
+msgid "%s: not supported"
+msgstr "%s£º²»Ö§³Ö"
+
+#: vms-tir.c:586 vms-tir.c:1418
+#, c-format
+msgid "%s: not implemented"
+msgstr "%s£ºÎ´ÊµÏÖ"
+
+#: vms-tir.c:590 vms-tir.c:1422
+#, c-format
+msgid "reserved STO cmd %d"
+msgstr "±£ÁôµÄ STO ÃüÁî %d"
+
+#: vms-tir.c:708 vms-tir.c:1568
+#, c-format
+msgid "reserved OPR cmd %d"
+msgstr "±£ÁôµÄ OPR ÃüÁî %d"
+
+#: vms-tir.c:776 vms-tir.c:1632
+#, c-format
+msgid "reserved CTL cmd %d"
+msgstr "±£ÁôµÄ CTL ÃüÁî %d"
+
+#. stack byte from image
+#. arg: none.
+#: vms-tir.c:1148
+msgid "stack-from-image not implemented"
+msgstr "δʵÏÖ stack-from-image"
+
+#: vms-tir.c:1166
+msgid "stack-entry-mask not fully implemented"
+msgstr "ÉÐδÍêȫʵÏÖ stack-entry-mask"
+
+#. 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.
+#: vms-tir.c:1180
+msgid "PASSMECH not fully implemented"
+msgstr "ÉÐδÍêȫʵÏÖ PASSMECH"
+
+#: vms-tir.c:1199
+msgid "stack-local-symbol not fully implemented"
+msgstr "ÉÐδÍêȫʵÏÖ stack-local-symbol"
+
+#: vms-tir.c:1212
+msgid "stack-literal not fully implemented"
+msgstr "ÉÐδÍêȫʵÏÖ stack-literal"
+
+#: vms-tir.c:1233
+msgid "stack-local-symbol-entry-point-mask not fully implemented"
+msgstr "ÉÐδÍêȫʵÏÖ stack-local-symbol-entry-point-mask"
+
+#: vms-tir.c:1510 vms-tir.c:1522 vms-tir.c:1534 vms-tir.c:1546 vms-tir.c:1611
+#: vms-tir.c:1619 vms-tir.c:1627
+#, c-format
+msgid "%s: not fully implemented"
+msgstr "%s£ºÉÐδÍêȫʵÏÖ"
+
+#: vms-tir.c:1684
+#, c-format
+msgid "obj code %d not found"
+msgstr ""
+
+#: vms-tir.c:2019
+#, c-format
+msgid "SEC_RELOC with no relocs in section %s"
+msgstr ""
+
+#: vms-tir.c:2307
+#, c-format
+msgid "Unhandled relocation %s"
+msgstr "δ´¦ÀíµÄÖض¨Î» %s"
+
+#: xcofflink.c:1243
+#, c-format
+msgid "%s: `%s' has line numbers but no enclosing section"
+msgstr ""
+
+#: xcofflink.c:1296
+#, c-format
+msgid "%s: class %d symbol `%s' has no aux entries"
+msgstr ""
+
+#: xcofflink.c:1319
+#, c-format
+msgid "%s: symbol `%s' has unrecognized csect type %d"
+msgstr ""
+
+#: xcofflink.c:1331
+#, c-format
+msgid "%s: bad XTY_ER symbol `%s': class %d scnum %d scnlen %d"
+msgstr ""
+
+#: xcofflink.c:1367
+#, c-format
+msgid "%s: XMC_TC0 symbol `%s' is class %d scnlen %d"
+msgstr ""
+
+#: xcofflink.c:1519
+#, c-format
+msgid "%s: csect `%s' not in enclosing section"
+msgstr ""
+
+#: xcofflink.c:1626
+#, c-format
+msgid "%s: misplaced XTY_LD `%s'"
+msgstr ""
+
+#: xcofflink.c:1957
+#, c-format
+msgid "%s: reloc %s:%d not in csect"
+msgstr ""
+
+#: xcofflink.c:2092
+#, c-format
+msgid "%s: XCOFF shared object when not producing XCOFF output"
+msgstr ""
+
+#: xcofflink.c:2113
+#, c-format
+msgid "%s: dynamic object with no .loader section"
+msgstr ""
+
+#: xcofflink.c:2758
+#, c-format
+msgid "%s: no such symbol"
+msgstr ""
+
+#: xcofflink.c:2891
+msgid "error: undefined symbol __rtinit"
+msgstr "´íÎó£ºÎ´¶¨ÒåµÄ·ûºÅ __rtinit"
+
+#: xcofflink.c:3453
+#, c-format
+msgid "warning: attempt to export undefined symbol `%s'"
+msgstr "¾¯¸æ£ºÊÔͼµ¼³ö䶨ÒåµÄ·ûºÅ¡°%s¡±"
+
+#: xcofflink.c:4447
+#, c-format
+msgid "TOC overflow: 0x%lx > 0x10000; try -mminimal-toc when compiling"
+msgstr ""
+
+#: xcofflink.c:5287 xcofflink.c:5756 xcofflink.c:5818 xcofflink.c:6119
+#, c-format
+msgid "%s: loader reloc in unrecognized section `%s'"
+msgstr ""
+
+#: xcofflink.c:5309 xcofflink.c:6130
+#, c-format
+msgid "%s: `%s' in loader reloc but not loader sym"
+msgstr ""
+
+#: xcofflink.c:5324
+#, c-format
+msgid "%s: loader reloc in read-only section %s"
+msgstr ""
+
+#: elf32-ia64.c:2222 elf64-ia64.c:2222
+msgid "@pltoff reloc against local symbol"
+msgstr ""
+
+#: elf32-ia64.c:3562 elf64-ia64.c:3562
+#, c-format
+msgid "%s: short data segment overflowed (0x%lx >= 0x400000)"
+msgstr ""
+
+#: elf32-ia64.c:3573 elf64-ia64.c:3573
+#, c-format
+msgid "%s: __gp does not cover short data segment"
+msgstr ""
+
+#: elf32-ia64.c:3858 elf64-ia64.c:3858
+#, c-format
+msgid "%s: linking non-pic code in a shared library"
+msgstr ""
+
+#: elf32-ia64.c:3891 elf64-ia64.c:3891
+#, c-format
+msgid "%s: @gprel relocation against dynamic symbol %s"
+msgstr ""
+
+#: elf32-ia64.c:4030 elf64-ia64.c:4030
+#, c-format
+msgid "%s: dynamic relocation against speculation fixup"
+msgstr ""
+
+#: elf32-ia64.c:4038 elf64-ia64.c:4038
+#, c-format
+msgid "%s: speculation fixup against undefined weak symbol"
+msgstr ""
+
+#: elf32-ia64.c:4271 elf64-ia64.c:4271
+msgid "unsupported reloc"
+msgstr "²»Ö§³ÖµÄÖض¨Î»"
+
+#: elf32-ia64.c:4551 elf64-ia64.c:4551
+#, c-format
+msgid "%s: linking trap-on-NULL-dereference with non-trapping files"
+msgstr ""
+
+#: elf32-ia64.c:4560 elf64-ia64.c:4560
+#, c-format
+msgid "%s: linking big-endian files with little-endian files"
+msgstr "%s£º½«´ó¶ËÎļþͬС¶ËÎļþ"
+
+#: elf32-ia64.c:4569 elf64-ia64.c:4569
+#, c-format
+msgid "%s: linking 64-bit files with 32-bit files"
+msgstr "%s£º½« 64-λÎļþͬ 32-λÎļþÁ¬½Ó"
+
+#: elf32-ia64.c:4578 elf64-ia64.c:4578
+#, c-format
+msgid "%s: linking constant-gp files with non-constant-gp files"
+msgstr ""
+
+#: elf32-ia64.c:4588 elf64-ia64.c:4588
+#, c-format
+msgid "%s: linking auto-pic files with non-auto-pic files"
+msgstr ""
+
+#: peigen.c:962 pepigen.c:962
+#, c-format
+msgid "%s: line number overflow: 0x%lx > 0xffff"
+msgstr "%s£ºÐкÅÒç³ö£º0x%lx > 0xffff"
+
+#: peigen.c:979 pepigen.c:979
+#, c-format
+msgid "%s: reloc overflow 1: 0x%lx > 0xffff"
+msgstr ""
+
+#: peigen.c:993 pepigen.c:993
+msgid "Export Directory [.edata (or where ever we found it)]"
+msgstr "µ¼³öĿ¼ [.edata (»òÕßÆäËüÈκÎÄÜÕÒµ½ËüµÄµØ·½)]"
+
+#: peigen.c:994 pepigen.c:994
+msgid "Import Directory [parts of .idata]"
+msgstr "µ¼ÈëĿ¼ [.idata µÄÒ»²¿·Ö]"
+
+#: peigen.c:995 pepigen.c:995
+msgid "Resource Directory [.rsrc]"
+msgstr "×ÊԴĿ¼ [.rsrc]"
+
+#: peigen.c:996 pepigen.c:996
+msgid "Exception Directory [.pdata]"
+msgstr ""
+
+#: peigen.c:997 pepigen.c:997
+msgid "Security Directory"
+msgstr "°²È«Ä¿Â¼"
+
+#: peigen.c:998 pepigen.c:998
+msgid "Base Relocation Directory [.reloc]"
+msgstr ""
+
+#: peigen.c:999 pepigen.c:999
+msgid "Debug Directory"
+msgstr "µ÷ÊÔĿ¼"
+
+#: peigen.c:1000 pepigen.c:1000
+msgid "Description Directory"
+msgstr "ÃèÊöĿ¼"
+
+#: peigen.c:1001 pepigen.c:1001
+msgid "Special Directory"
+msgstr "ÌØÊâĿ¼"
+
+#: peigen.c:1002 pepigen.c:1002
+msgid "Thread Storage Directory [.tls]"
+msgstr "Ï̴߳洢Ŀ¼ [.tls]"
+
+#: peigen.c:1003 pepigen.c:1003
+msgid "Load Configuration Directory"
+msgstr "×°ÈëÅäÖÃĿ¼"
+
+#: peigen.c:1004 pepigen.c:1004
+msgid "Bound Import Directory"
+msgstr ""
+
+#: peigen.c:1005 pepigen.c:1005
+msgid "Import Address Table Directory"
+msgstr "µ¼ÈëµØÖ·±íĿ¼"
+
+#: peigen.c:1006 pepigen.c:1006
+msgid "Delay Import Directory"
+msgstr "ÑÓ³Ùµ¼ÈëĿ¼"
+
+#: peigen.c:1007 peigen.c:1008 pepigen.c:1007 pepigen.c:1008
+msgid "Reserved"
+msgstr "±£Áô"
+
+#: peigen.c:1071 pepigen.c:1071
+msgid ""
+"\n"
+"There is an import table, but the section containing it could not be found\n"
+msgstr ""
+
+#: peigen.c:1076 pepigen.c:1076
+#, c-format
+msgid ""
+"\n"
+"There is an import table in %s at 0x%lx\n"
+msgstr ""
+
+#: peigen.c:1113 pepigen.c:1113
+#, c-format
+msgid ""
+"\n"
+"Function descriptor located at the start address: %04lx\n"
+msgstr ""
+
+#: peigen.c:1116 pepigen.c:1116
+#, c-format
+msgid "\tcode-base %08lx toc (loadable/actual) %08lx/%08lx\n"
+msgstr ""
+
+#: peigen.c:1122 pepigen.c:1122
+msgid ""
+"\n"
+"No reldata section! Function descriptor not decoded.\n"
+msgstr ""
+
+#: peigen.c:1127 pepigen.c:1127
+#, c-format
+msgid ""
+"\n"
+"The Import Tables (interpreted %s section contents)\n"
+msgstr ""
+
+#: peigen.c:1130 pepigen.c:1130
+msgid ""
+" vma: Hint Time Forward DLL First\n"
+" Table Stamp Chain Name Thunk\n"
+msgstr ""
+
+#: peigen.c:1181 pepigen.c:1181
+#, c-format
+msgid ""
+"\n"
+"\tDLL Name: %s\n"
+msgstr ""
+"\n"
+"\tDLL Ãû³Æ£º%s\n"
+
+#: peigen.c:1192 pepigen.c:1192
+msgid "\tvma: Hint/Ord Member-Name Bound-To\n"
+msgstr ""
+
+#: peigen.c:1217 pepigen.c:1217
+msgid ""
+"\n"
+"There is a first thunk, but the section containing it could not be found\n"
+msgstr ""
+
+#: peigen.c:1357 pepigen.c:1357
+msgid ""
+"\n"
+"There is an export table, but the section containing it could not be found\n"
+msgstr ""
+
+#: peigen.c:1362 pepigen.c:1362
+#, c-format
+msgid ""
+"\n"
+"There is an export table in %s at 0x%lx\n"
+msgstr ""
+"\n"
+"%s Öеĵ¼³ö±íλÓÚ 0x%lx\n"
+
+#: peigen.c:1393 pepigen.c:1393
+#, c-format
+msgid ""
+"\n"
+"The Export Tables (interpreted %s section contents)\n"
+"\n"
+msgstr ""
+
+#: peigen.c:1397 pepigen.c:1397
+#, c-format
+msgid "Export Flags \t\t\t%lx\n"
+msgstr "µ¼³ö±êÖ¾ \t\t\t%lx\n"
+
+#: peigen.c:1400 pepigen.c:1400
+#, c-format
+msgid "Time/Date stamp \t\t%lx\n"
+msgstr "ÈÕÆÚ/ʱ¼ä´Á \t\t%lx\n"
+
+#: peigen.c:1403 pepigen.c:1403
+#, c-format
+msgid "Major/Minor \t\t\t%d/%d\n"
+msgstr ""
+
+#: peigen.c:1406 pepigen.c:1406
+msgid "Name \t\t\t\t"
+msgstr "Ãû³Æ \t\t\t\t"
+
+#: peigen.c:1412 pepigen.c:1412
+#, c-format
+msgid "Ordinal Base \t\t\t%ld\n"
+msgstr ""
+
+#: peigen.c:1415 pepigen.c:1415
+msgid "Number in:\n"
+msgstr ""
+
+#: peigen.c:1418 pepigen.c:1418
+#, c-format
+msgid "\tExport Address Table \t\t%08lx\n"
+msgstr ""
+
+#: peigen.c:1422 pepigen.c:1422
+#, c-format
+msgid "\t[Name Pointer/Ordinal] Table\t%08lx\n"
+msgstr ""
+
+#: peigen.c:1425 pepigen.c:1425
+msgid "Table Addresses\n"
+msgstr "±íµØÖ·\n"
+
+#: peigen.c:1428 pepigen.c:1428
+msgid "\tExport Address Table \t\t"
+msgstr "\tµ¼³öµØÖ·±í \t\t"
+
+#: peigen.c:1433 pepigen.c:1433
+msgid "\tName Pointer Table \t\t"
+msgstr "\tÃû³ÆÖ¸Õë±í \t\t"
+
+#: peigen.c:1438 pepigen.c:1438
+msgid "\tOrdinal Table \t\t\t"
+msgstr ""
+
+#: peigen.c:1453 pepigen.c:1453
+#, c-format
+msgid ""
+"\n"
+"Export Address Table -- Ordinal Base %ld\n"
+msgstr ""
+
+#: peigen.c:1472 pepigen.c:1472
+msgid "Forwarder RVA"
+msgstr ""
+
+#: peigen.c:1483 pepigen.c:1483
+msgid "Export RVA"
+msgstr "µ¼³ö RVA"
+
+#: peigen.c:1490 pepigen.c:1490
+msgid ""
+"\n"
+"[Ordinal/Name Pointer] Table\n"
+msgstr ""
+
+#: peigen.c:1545 pepigen.c:1545
+#, c-format
+msgid "Warning, .pdata section size (%ld) is not a multiple of %d\n"
+msgstr ""
+
+#: peigen.c:1549 pepigen.c:1549
+msgid ""
+"\n"
+"The Function Table (interpreted .pdata section contents)\n"
+msgstr ""
+
+#: peigen.c:1552 pepigen.c:1552
+msgid " vma:\t\t\tBegin Address End Address Unwind Info\n"
+msgstr ""
+
+#: peigen.c:1554 pepigen.c:1554
+msgid ""
+" vma:\t\tBegin End EH EH PrologEnd Exception\n"
+" \t\tAddress Address Handler Data Address Mask\n"
+msgstr ""
+
+#: peigen.c:1624 pepigen.c:1624
+msgid " Register save millicode"
+msgstr ""
+
+#: peigen.c:1627 pepigen.c:1627
+msgid " Register restore millicode"
+msgstr ""
+
+#: peigen.c:1630 pepigen.c:1630
+msgid " Glue code sequence"
+msgstr ""
+
+#: peigen.c:1682 pepigen.c:1682
+msgid ""
+"\n"
+"\n"
+"PE File Base Relocations (interpreted .reloc section contents)\n"
+msgstr ""
+
+#: peigen.c:1712 pepigen.c:1712
+#, c-format
+msgid ""
+"\n"
+"Virtual Address: %08lx Chunk size %ld (0x%lx) Number of fixups %ld\n"
+msgstr ""
+
+#: peigen.c:1725 pepigen.c:1725
+#, c-format
+msgid "\treloc %4d offset %4x [%4lx] %s"
+msgstr ""
+
+#. The MS dumpbin program reportedly ands with 0xff0f before
+#. printing the characteristics field. Not sure why. No reason to
+#. emulate it here.
+#: peigen.c:1765 pepigen.c:1765
+#, c-format
+msgid ""
+"\n"
+"Characteristics 0x%x\n"
+msgstr ""
diff --git a/bfd/ppcboot.c b/bfd/ppcboot.c
new file mode 100644
index 0000000..9ee8ab5
--- /dev/null
+++ b/bfd/ppcboot.c
@@ -0,0 +1,526 @@
+/* BFD back-end for PPCbug boot records.
+ Copyright (C) 1996-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, 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 "sysdep.h"
+#include "safe-ctype.h"
+#include "bfd.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 */
+}
+#ifdef __GNUC__
+ __attribute__ ((packed))
+#endif
+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
+
+#define ppcboot_set_tdata(abfd, ptr) ((abfd)->tdata.any = (ptr))
+#define ppcboot_get_tdata(abfd) ((ppcboot_data_t *) ((abfd)->tdata.any))
+
+/* Create a ppcboot object. Invoked via bfd_set_format. */
+
+static bfd_boolean
+ppcboot_mkobject (bfd *abfd)
+{
+ if (!ppcboot_get_tdata (abfd))
+ {
+ bfd_size_type amt = sizeof (ppcboot_data_t);
+ ppcboot_set_tdata (abfd, bfd_zalloc (abfd, amt));
+ }
+
+ return TRUE;
+}
+
+
+/* Set the architecture to PowerPC */
+static bfd_boolean
+ppcboot_set_arch_mach (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 (bfd *abfd)
+{
+ struct stat statbuf;
+ asection *sec;
+ ppcboot_hdr_t hdr;
+ size_t i;
+ ppcboot_data_t *tdata;
+ flagword flags;
+
+ 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_bread (&hdr, (bfd_size_type) sizeof (hdr), 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. */
+ flags = SEC_ALLOC | SEC_LOAD | SEC_DATA | SEC_CODE | SEC_HAS_CONTENTS;
+ sec = bfd_make_section_with_flags (abfd, ".data", flags);
+ if (sec == NULL)
+ return NULL;
+ sec->vma = 0;
+ sec->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 (&tdata->header, &hdr, sizeof (ppcboot_hdr_t));
+
+ ppcboot_set_arch_mach (abfd, bfd_arch_powerpc, 0L);
+ 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 bfd_boolean
+ppcboot_get_section_contents (bfd *abfd,
+ asection *section ATTRIBUTE_UNUSED,
+ void * location,
+ file_ptr offset,
+ bfd_size_type count)
+{
+ if (bfd_seek (abfd, offset + (file_ptr) sizeof (ppcboot_hdr_t), SEEK_SET) != 0
+ || bfd_bread (location, 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 (bfd *abfd ATTRIBUTE_UNUSED)
+{
+ return (PPCBOOT_SYMS + 1) * sizeof (asymbol *);
+}
+
+
+/* Create a symbol name based on the bfd's filename. */
+
+static char *
+mangle_name (bfd *abfd, char *suffix)
+{
+ bfd_size_type 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 (*p))
+ *p = '_';
+
+ return buf;
+}
+
+
+/* Return the symbol table. */
+
+static long
+ppcboot_canonicalize_symtab (bfd *abfd, asymbol **alocation)
+{
+ asection *sec = ppcboot_get_tdata (abfd)->sec;
+ asymbol *syms;
+ unsigned int i;
+ bfd_size_type amt = PPCBOOT_SYMS * sizeof (asymbol);
+
+ syms = (asymbol *) bfd_alloc (abfd, amt);
+ 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->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->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;
+}
+
+#define ppcboot_make_empty_symbol _bfd_generic_make_empty_symbol
+#define ppcboot_print_symbol _bfd_nosymbols_print_symbol
+
+/* Get information about a symbol. */
+
+static void
+ppcboot_get_symbol_info (bfd *ignore_abfd ATTRIBUTE_UNUSED,
+ asymbol *symbol,
+ symbol_info *ret)
+{
+ bfd_symbol_info (symbol, ret);
+}
+
+#define ppcboot_bfd_is_target_special_symbol \
+ ((bfd_boolean (*) (bfd *, asymbol *)) bfd_false)
+#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_find_line _bfd_nosymbols_find_line
+#define ppcboot_find_inliner_info _bfd_nosymbols_find_inliner_info
+#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
+
+/* Write section contents of a ppcboot file. */
+
+static bfd_boolean
+ppcboot_set_section_contents (bfd *abfd,
+ asection *sec,
+ const void * 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 (bfd *abfd ATTRIBUTE_UNUSED,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED)
+{
+ return sizeof (ppcboot_hdr_t);
+}
+
+
+/* Print out the program headers. */
+
+static bfd_boolean
+ppcboot_bfd_print_private_bfd_data (bfd *abfd, void * farg)
+{
+ FILE *f = (FILE *)farg;
+ ppcboot_data_t *tdata = ppcboot_get_tdata (abfd);
+ long entry_offset = bfd_getl_signed_32 (tdata->header.entry_offset);
+ long length = bfd_getl_signed_32 (tdata->header.length);
+ int i;
+
+ fprintf (f, _("\nppcboot header:\n"));
+ fprintf (f, _("Entry offset = 0x%.8lx (%ld)\n"),
+ (unsigned long) entry_offset, entry_offset);
+ fprintf (f, _("Length = 0x%.8lx (%ld)\n"),
+ (unsigned long) 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 (tdata->header.partition[i].sector_begin);
+ long sector_length = bfd_getl_signed_32 (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, (unsigned long) sector_begin, sector_begin);
+ fprintf (f, _("Partition[%d] length = 0x%.8lx (%ld)\n"),
+ i, (unsigned long) 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_lookup_section_flags bfd_generic_lookup_section_flags
+#define ppcboot_bfd_merge_sections bfd_generic_merge_sections
+#define ppcboot_bfd_is_group_section bfd_generic_is_group_section
+#define ppcboot_bfd_discard_group bfd_generic_discard_group
+#define ppcboot_section_already_linked \
+ _bfd_generic_section_already_linked
+#define ppcboot_bfd_define_common_symbol bfd_generic_define_common_symbol
+#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_link_just_syms _bfd_generic_link_just_syms
+#define ppcboot_bfd_copy_link_hash_symbol_type \
+ _bfd_generic_copy_link_hash_symbol_type
+#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_copy_private_header_data _bfd_generic_bfd_copy_private_header_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 powerpc_boot_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 */
+ 0, /* match priority. */
+ 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 (_bfd_norelocs),
+ BFD_JUMP_TABLE_WRITE (ppcboot),
+ BFD_JUMP_TABLE_LINK (ppcboot),
+ BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
+
+ NULL,
+
+ NULL
+};
diff --git a/bfd/ptrace-core.c b/bfd/ptrace-core.c
new file mode 100644
index 0000000..723f4a4
--- /dev/null
+++ b/bfd/ptrace-core.c
@@ -0,0 +1,217 @@
+/* BFD backend for core files which use the ptrace_user structure
+ Copyright (C) 1993-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#ifdef PTRACE_CORE
+
+#include "sysdep.h"
+#include "bfd.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 (bfd *abfd);
+char * ptrace_unix_core_file_failing_command (bfd *abfd);
+int ptrace_unix_core_file_failing_signal (bfd *abfd);
+#define ptrace_unix_core_file_matches_executable_p generic_core_file_matches_executable_p
+#define ptrace_unix_core_file_pid _bfd_nocore_core_file_pid
+static void swap_abort (void);
+
+const bfd_target *
+ptrace_unix_core_file_p (bfd *abfd)
+{
+ int val;
+ struct ptrace_user u;
+ struct trad_core_struct *rawptr;
+ bfd_size_type amt;
+ flagword flags;
+
+ val = bfd_bread ((void *)&u, (bfd_size_type) 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. */
+ amt = sizeof (struct trad_core_struct);
+ rawptr = (struct trad_core_struct *) bfd_zalloc (abfd, amt);
+
+ 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. */
+
+ flags = SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS;
+ core_stacksec (abfd) = bfd_make_section_anyway_with_flags (abfd, ".stack",
+ flags);
+ if (core_stacksec (abfd) == NULL)
+ goto fail;
+ core_datasec (abfd) = bfd_make_section_anyway_with_flags (abfd, ".data",
+ flags);
+ if (core_datasec (abfd) == NULL)
+ goto fail;
+ core_regsec (abfd) = bfd_make_section_anyway_with_flags (abfd, ".reg",
+ SEC_HAS_CONTENTS);
+ if (core_regsec (abfd) == NULL)
+ goto fail;
+
+ /* 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_datasec (abfd)->size = u.pt_dsize;
+ core_stacksec (abfd)->size = u.pt_ssize;
+ core_regsec (abfd)->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;
+
+ return abfd->xvec;
+
+ fail:
+ bfd_release (abfd, abfd->tdata.any);
+ abfd->tdata.any = NULL;
+ bfd_section_list_clear (abfd);
+ return NULL;
+}
+
+char *
+ptrace_unix_core_file_failing_command (bfd *abfd)
+{
+ char *com = abfd->tdata.trad_core_data->u.pt_comm;
+
+ if (*com)
+ return com;
+ else
+ return 0;
+}
+
+int
+ptrace_unix_core_file_failing_signal (bfd *abfd)
+{
+ return abfd->tdata.trad_core_data->u.pt_sigframe.sig_num;
+}
+
+/* If somebody calls any byte-swapping routines, shoot them. */
+static void
+swap_abort (void)
+{
+ abort (); /* This way doesn't require any declaration for ANSI to fuck up */
+}
+
+#define NO_GET ((bfd_vma (*) (const void *)) swap_abort)
+#define NO_PUT ((void (*) (bfd_vma, void *)) swap_abort)
+#define NO_GETS ((bfd_signed_vma (*) (const void *)) swap_abort)
+#define NO_GET64 ((bfd_uint64_t (*) (const void *)) swap_abort)
+#define NO_PUT64 ((void (*) (bfd_uint64_t, void *)) swap_abort)
+#define NO_GETS64 ((bfd_int64_t (*) (const void *)) swap_abort)
+
+const bfd_target core_ptrace_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_GET64, NO_GETS64, NO_PUT64, /* 64 bit data */
+ NO_GET, NO_GETS, NO_PUT, /* 32 bit data */
+ NO_GET, NO_GETS, NO_PUT, /* 16 bit data */
+ NO_GET64, NO_GETS64, NO_PUT64, /* 64 bit hdrs */
+ NO_GET, NO_GETS, NO_PUT, /* 32 bit hdrs */
+ NO_GET, NO_GETS, 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),
+
+ NULL,
+
+ NULL /* backend_data */
+ };
+
+#endif /* PTRACE_CORE */
diff --git a/bfd/reloc.c b/bfd/reloc.c
new file mode 100644
index 0000000..dc47173
--- /dev/null
+++ b/bfd/reloc.c
@@ -0,0 +1,7673 @@
+/* BFD support for handling relocation entries.
+ Copyright (C) 1990-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+/*
+SECTION
+ Relocations
+
+ BFD maintains relocations in much the same way it maintains
+ symbols: they are left alone until required, then read in
+ en-masse 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 "sysdep.h"
+#include "bfd.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 bfd_symbol **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
+ <<canonicalize_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 value overflows when considered as a signed
+. number one bit larger than the field. ie. A bitfield of N bits
+. is allowed to represent -2**n to 2**n-1. *}
+. complain_overflow_bitfield,
+.
+. {* Complain if the value overflows when considered as a 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 bfd_symbol; {* 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;
+.
+. {* The relocation is relative to the field being relocated. *}
+. bfd_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 accommodated (e.g., i960 callj
+. instructions). *}
+. bfd_reloc_status_type (*special_function)
+. (bfd *, arelent *, struct bfd_symbol *, void *, asection *,
+. bfd *, char **);
+.
+. {* The textual name of the relocation type. *}
+. char *name;
+.
+. {* Some formats record a relocation addend in the section contents
+. rather than with the relocation. For ELF formats this is the
+. distinction between USE_REL and USE_RELA (though the code checks
+. for USE_REL == 1/0). The value of this field is TRUE if the
+. addend is recorded with the section contents; when performing a
+. partial link (ld -r) the section contents (the data) will be
+. modified. The value of this field is FALSE if addends are
+. recorded with the relocation (in arelent.addend); when performing
+. a partial link the relocation will be modified.
+. All relocations for all ELF USE_RELA targets should set this field
+. to FALSE (values of TRUE should be looked on with suspicion).
+. However, the converse is not true: not all relocations of all ELF
+. USE_REL targets set this field to TRUE. Why this is so is peculiar
+. to each particular target. For relocs that aren't used in partial
+. links (e.g. GOT stuff) it doesn't matter what this is set to. *}
+. bfd_boolean partial_inplace;
+.
+. {* src_mask selects the part of the instruction (or data) to be used
+. in the relocation sum. If the target relocations don't have an
+. addend in the reloc, eg. ELF USE_REL, src_mask will normally equal
+. dst_mask to extract the addend from the section contents. If
+. relocations do have an addend in the reloc, eg. ELF USE_RELA, this
+. field should be zero. Non-zero values for ELF USE_RELA targets are
+. bogus as in those cases the value in the dst_mask part of the
+. section contents should be treated as garbage. *}
+. bfd_vma src_mask;
+.
+. {* dst_mask selects which parts of the instruction (or data) are
+. replaced with a relocated value. *}
+. 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. *}
+. bfd_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
+ This is used to fill in an empty howto entry in an array.
+
+.#define EMPTY_HOWTO(C) \
+. HOWTO ((C), 0, 0, 0, FALSE, 0, complain_overflow_dont, NULL, \
+. NULL, FALSE, 0, 0, FALSE)
+.
+
+DESCRIPTION
+ Helper routine to turn a symbol into a relocation value.
+
+.#define HOWTO_PREPARE(relocation, symbol) \
+. { \
+. if (symbol != 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 (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 (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;
+
+ /* 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);
+ signmask = ~fieldmask;
+ addrmask = N_ONES (addrsize) | (fieldmask << rightshift);
+ a = (relocation & addrmask) >> rightshift;
+
+ 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. */
+ signmask = ~ (fieldmask >> 1);
+ /* Fall thru */
+
+ case complain_overflow_bitfield:
+ /* Bitfields are sometimes signed, sometimes unsigned. We
+ explicitly allow an address wrap too, which means a bitfield
+ of n bits is allowed to store -2**n to 2**n-1. Thus overflow
+ if the value has some, but not all, bits set outside the
+ field. */
+ 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. */
+ if ((a & signmask) != 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,
+ void *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 (bfd *abfd,
+ arelent *reloc_entry,
+ void *data,
+ asection *input_section,
+ bfd *output_bfd,
+ char **error_message)
+{
+ bfd_vma relocation;
+ bfd_reloc_status_type flag = bfd_reloc_ok;
+ bfd_size_type octets = reloc_entry->address * bfd_octets_per_byte (abfd);
+ 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 != NULL)
+ {
+ reloc_entry->address += input_section->output_offset;
+ return bfd_reloc_ok;
+ }
+
+ /* If we are not producing relocatable 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 == 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 > bfd_get_section_limit (abfd, input_section))
+ return bfd_reloc_outofrange;
+
+ /* Work out which section the relocation is targeted 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)
+ || reloc_target_output_section == NULL)
+ 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)
+ {
+ /* 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 relocatable 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 relocatable 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)
+ relocation -= reloc_entry->address;
+ }
+
+ if (output_bfd != NULL)
+ {
+ if (! howto->partial_inplace)
+ {
+ /* 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, "coff-Intel-little") != 0
+ && strcmp (abfd->xvec->name, "coff-Intel-big") != 0)
+ {
+ /* 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
+relocatable 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 relocatable output. When
+we are producing relocatable output, logically we should do exactly
+what we do when not producing relocatable 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 relocatable 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;
+ 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_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 + octets);
+ DOIT (x);
+ bfd_put_8 (abfd, x, (unsigned char *) data + octets);
+ }
+ break;
+
+ case 1:
+ {
+ short x = bfd_get_16 (abfd, (bfd_byte *) data + octets);
+ DOIT (x);
+ bfd_put_16 (abfd, (bfd_vma) x, (unsigned char *) data + octets);
+ }
+ break;
+ case 2:
+ {
+ long x = bfd_get_32 (abfd, (bfd_byte *) data + octets);
+ DOIT (x);
+ bfd_put_32 (abfd, (bfd_vma) x, (bfd_byte *) data + octets);
+ }
+ break;
+ case -2:
+ {
+ long x = bfd_get_32 (abfd, (bfd_byte *) data + octets);
+ relocation = -relocation;
+ DOIT (x);
+ bfd_put_32 (abfd, (bfd_vma) x, (bfd_byte *) data + octets);
+ }
+ break;
+
+ case -1:
+ {
+ long x = bfd_get_16 (abfd, (bfd_byte *) data + octets);
+ relocation = -relocation;
+ DOIT (x);
+ bfd_put_16 (abfd, (bfd_vma) x, (bfd_byte *) data + octets);
+ }
+ break;
+
+ case 3:
+ /* Do nothing */
+ break;
+
+ case 4:
+#ifdef BFD64
+ {
+ bfd_vma x = bfd_get_64 (abfd, (bfd_byte *) data + octets);
+ DOIT (x);
+ bfd_put_64 (abfd, x, (bfd_byte *) data + octets);
+ }
+#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,
+ void *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 (bfd *abfd,
+ arelent *reloc_entry,
+ void *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 octets = reloc_entry->address * bfd_octets_per_byte (abfd);
+ 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 > bfd_get_section_limit (abfd, input_section))
+ return bfd_reloc_outofrange;
+
+ /* Work out which section the relocation is targeted 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)
+ 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)
+ {
+ /* 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 relocatable 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 relocatable 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 && howto->partial_inplace)
+ relocation -= reloc_entry->address;
+ }
+
+ if (! howto->partial_inplace)
+ {
+ /* 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, "coff-Intel-little") != 0
+ && strcmp (abfd->xvec->name, "coff-Intel-big") != 0)
+ {
+
+ /* 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
+relocatable 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 relocatable output. When
+we are producing relocatable output, logically we should do exactly
+what we do when not producing relocatable 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 relocatable 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;
+ /* FIXME: There should be no target specific code here... */
+ if (strcmp (abfd->xvec->name, "coff-z8k") != 0)
+ 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 + (octets - data_start_offset);
+
+ switch (howto->size)
+ {
+ case 0:
+ {
+ char x = bfd_get_8 (abfd, data);
+ DOIT (x);
+ bfd_put_8 (abfd, x, data);
+ }
+ break;
+
+ case 1:
+ {
+ short x = bfd_get_16 (abfd, data);
+ DOIT (x);
+ bfd_put_16 (abfd, (bfd_vma) x, data);
+ }
+ break;
+ case 2:
+ {
+ long x = bfd_get_32 (abfd, data);
+ DOIT (x);
+ bfd_put_32 (abfd, (bfd_vma) x, data);
+ }
+ break;
+ case -2:
+ {
+ long x = bfd_get_32 (abfd, data);
+ relocation = -relocation;
+ DOIT (x);
+ bfd_put_32 (abfd, (bfd_vma) x, data);
+ }
+ break;
+
+ case 3:
+ /* Do nothing */
+ break;
+
+ case 4:
+ {
+ bfd_vma x = bfd_get_64 (abfd, data);
+ DOIT (x);
+ bfd_put_64 (abfd, x, 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
+ relocatable 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 (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 > bfd_get_section_limit (input_bfd, input_section))
+ 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 (reloc_howto_type *howto,
+ bfd *input_bfd,
+ bfd_vma relocation,
+ bfd_byte *location)
+{
+ int size;
+ bfd_vma x = 0;
+ bfd_reloc_status_type flag;
+ 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. */
+ flag = bfd_reloc_ok;
+ 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);
+ signmask = ~fieldmask;
+ addrmask = (N_ONES (bfd_arch_bits_per_address (input_bfd))
+ | (fieldmask << rightshift));
+ a = (relocation & addrmask) >> rightshift;
+ b = (x & howto->src_mask & addrmask) >> bitpos;
+ addrmask >>= rightshift;
+
+ switch (howto->complain_on_overflow)
+ {
+ 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. */
+ signmask = ~(fieldmask >> 1);
+ /* Fall thru */
+
+ case complain_overflow_bitfield:
+ /* Much like the signed check, but for a field one bit
+ wider. We allow a bitfield to represent numbers in the
+ range -2**n to 2**n-1, where n is the number of bits in the
+ field. Note that when bfd_vma is 32 bits, a 32-bit reloc
+ can't overflow, which is exactly what we want. */
+ ss = a & signmask;
+ if (ss != 0 && ss != (addrmask & signmask))
+ flag = bfd_reloc_overflow;
+
+ /* 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. */
+ ss = ((~howto->src_mask) >> 1) & howto->src_mask;
+ ss >>= bitpos;
+
+ /* Set all the bits above the sign bit. */
+ b = (b ^ ss) - ss;
+
+ /* 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)
+
+ We mask with addrmask here to explicitly allow an address
+ wrap-around. The Linux kernel relies on it, and it is
+ the only way to write assembler code which can run when
+ loaded at a location 0x80000000 away from the location at
+ which it is linked. */
+ if (((~(a ^ b)) & (a ^ sum)) & signmask & addrmask)
+ flag = bfd_reloc_overflow;
+ 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. */
+ sum = (a + b) & addrmask;
+ if ((a | b | sum) & signmask)
+ flag = bfd_reloc_overflow;
+ 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:
+ 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 flag;
+}
+
+/* Clear a given location using a given howto, by applying a fixed relocation
+ value and discarding any in-place addend. This is used for fixed-up
+ relocations against discarded symbols, to make ignorable debug or unwind
+ information more obvious. */
+
+void
+_bfd_clear_contents (reloc_howto_type *howto,
+ bfd *input_bfd,
+ asection *input_section,
+ bfd_byte *location)
+{
+ int size;
+ bfd_vma x = 0;
+
+ /* 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;
+ }
+
+ /* Zero out the unwanted bits of X. */
+ x &= ~howto->dst_mask;
+
+ /* For a range list, use 1 instead of 0 as placeholder. 0
+ would terminate the list, hiding any later entries. */
+ if (strcmp (bfd_get_section_name (input_bfd, input_section),
+ ".debug_ranges") == 0
+ && (howto->dst_mask & 1) != 0)
+ x |= 1;
+
+ /* 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;
+ }
+}
+
+/*
+DOCDD
+INODE
+ howto manager, , typedef arelent, Relocations
+
+SUBSECTION
+ 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_SECREL
+ENUMDOC
+ Section relative relocations. Some targets need this for DWARF2.
+
+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_64_PLT_PCREL
+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_64_PLTOFF
+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_SIZE32
+ENUMX
+ BFD_RELOC_SIZE64
+ENUMDOC
+ Size relocations.
+
+ENUM
+ BFD_RELOC_68K_GLOB_DAT
+ENUMX
+ BFD_RELOC_68K_JMP_SLOT
+ENUMX
+ BFD_RELOC_68K_RELATIVE
+ENUMX
+ BFD_RELOC_68K_TLS_GD32
+ENUMX
+ BFD_RELOC_68K_TLS_GD16
+ENUMX
+ BFD_RELOC_68K_TLS_GD8
+ENUMX
+ BFD_RELOC_68K_TLS_LDM32
+ENUMX
+ BFD_RELOC_68K_TLS_LDM16
+ENUMX
+ BFD_RELOC_68K_TLS_LDM8
+ENUMX
+ BFD_RELOC_68K_TLS_LDO32
+ENUMX
+ BFD_RELOC_68K_TLS_LDO16
+ENUMX
+ BFD_RELOC_68K_TLS_LDO8
+ENUMX
+ BFD_RELOC_68K_TLS_IE32
+ENUMX
+ BFD_RELOC_68K_TLS_IE16
+ENUMX
+ BFD_RELOC_68K_TLS_IE8
+ENUMX
+ BFD_RELOC_68K_TLS_LE32
+ENUMX
+ BFD_RELOC_68K_TLS_LE16
+ENUMX
+ BFD_RELOC_68K_TLS_LE8
+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_UA16
+ENUMX
+ BFD_RELOC_SPARC_UA32
+ENUMX
+ BFD_RELOC_SPARC_UA64
+ENUMX
+ BFD_RELOC_SPARC_GOTDATA_HIX22
+ENUMX
+ BFD_RELOC_SPARC_GOTDATA_LOX10
+ENUMX
+ BFD_RELOC_SPARC_GOTDATA_OP_HIX22
+ENUMX
+ BFD_RELOC_SPARC_GOTDATA_OP_LOX10
+ENUMX
+ BFD_RELOC_SPARC_GOTDATA_OP
+ENUMX
+ BFD_RELOC_SPARC_JMP_IREL
+ENUMX
+ BFD_RELOC_SPARC_IRELATIVE
+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_PLT32
+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
+ENUMX
+ BFD_RELOC_SPARC_H34
+ENUMX
+ BFD_RELOC_SPARC_SIZE32
+ENUMX
+ BFD_RELOC_SPARC_SIZE64
+ENUMX
+ BFD_RELOC_SPARC_WDISP10
+ENUMDOC
+ SPARC64 relocations
+
+ENUM
+ BFD_RELOC_SPARC_REV32
+ENUMDOC
+ SPARC little endian relocation
+ENUM
+ BFD_RELOC_SPARC_TLS_GD_HI22
+ENUMX
+ BFD_RELOC_SPARC_TLS_GD_LO10
+ENUMX
+ BFD_RELOC_SPARC_TLS_GD_ADD
+ENUMX
+ BFD_RELOC_SPARC_TLS_GD_CALL
+ENUMX
+ BFD_RELOC_SPARC_TLS_LDM_HI22
+ENUMX
+ BFD_RELOC_SPARC_TLS_LDM_LO10
+ENUMX
+ BFD_RELOC_SPARC_TLS_LDM_ADD
+ENUMX
+ BFD_RELOC_SPARC_TLS_LDM_CALL
+ENUMX
+ BFD_RELOC_SPARC_TLS_LDO_HIX22
+ENUMX
+ BFD_RELOC_SPARC_TLS_LDO_LOX10
+ENUMX
+ BFD_RELOC_SPARC_TLS_LDO_ADD
+ENUMX
+ BFD_RELOC_SPARC_TLS_IE_HI22
+ENUMX
+ BFD_RELOC_SPARC_TLS_IE_LO10
+ENUMX
+ BFD_RELOC_SPARC_TLS_IE_LD
+ENUMX
+ BFD_RELOC_SPARC_TLS_IE_LDX
+ENUMX
+ BFD_RELOC_SPARC_TLS_IE_ADD
+ENUMX
+ BFD_RELOC_SPARC_TLS_LE_HIX22
+ENUMX
+ BFD_RELOC_SPARC_TLS_LE_LOX10
+ENUMX
+ BFD_RELOC_SPARC_TLS_DTPMOD32
+ENUMX
+ BFD_RELOC_SPARC_TLS_DTPMOD64
+ENUMX
+ BFD_RELOC_SPARC_TLS_DTPOFF32
+ENUMX
+ BFD_RELOC_SPARC_TLS_DTPOFF64
+ENUMX
+ BFD_RELOC_SPARC_TLS_TPOFF32
+ENUMX
+ BFD_RELOC_SPARC_TLS_TPOFF64
+ENUMDOC
+ SPARC TLS relocations
+
+ENUM
+ BFD_RELOC_SPU_IMM7
+ENUMX
+ BFD_RELOC_SPU_IMM8
+ENUMX
+ BFD_RELOC_SPU_IMM10
+ENUMX
+ BFD_RELOC_SPU_IMM10W
+ENUMX
+ BFD_RELOC_SPU_IMM16
+ENUMX
+ BFD_RELOC_SPU_IMM16W
+ENUMX
+ BFD_RELOC_SPU_IMM18
+ENUMX
+ BFD_RELOC_SPU_PCREL9a
+ENUMX
+ BFD_RELOC_SPU_PCREL9b
+ENUMX
+ BFD_RELOC_SPU_PCREL16
+ENUMX
+ BFD_RELOC_SPU_LO16
+ENUMX
+ BFD_RELOC_SPU_HI16
+ENUMX
+ BFD_RELOC_SPU_PPU32
+ENUMX
+ BFD_RELOC_SPU_PPU64
+ENUMX
+ BFD_RELOC_SPU_ADD_PIC
+ENUMDOC
+ SPU Relocations.
+
+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)
+
+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_ALPHA_GPREL_HI16
+ENUMX
+ BFD_RELOC_ALPHA_GPREL_LO16
+ENUMDOC
+ The GPREL_HI/LO relocations together form a 32-bit offset from the
+ GP register.
+
+ENUM
+ BFD_RELOC_ALPHA_BRSGP
+ENUMDOC
+ Like BFD_RELOC_23_PCREL_S2, except that the source and target must
+ share a common GP, and the target address is adjusted for
+ STO_ALPHA_STD_GPLOAD.
+
+ENUM
+ BFD_RELOC_ALPHA_NOP
+ENUMDOC
+ The NOP relocation outputs a NOP if the longword displacement
+ between two procedure entry points is < 2^21.
+
+ENUM
+ BFD_RELOC_ALPHA_BSR
+ENUMDOC
+ The BSR relocation outputs a BSR if the longword displacement
+ between two procedure entry points is < 2^21.
+
+ENUM
+ BFD_RELOC_ALPHA_LDA
+ENUMDOC
+ The LDA relocation outputs a LDA if the longword displacement
+ between two procedure entry points is < 2^16.
+
+ENUM
+ BFD_RELOC_ALPHA_BOH
+ENUMDOC
+ The BOH relocation outputs a BSR if the longword displacement
+ between two procedure entry points is < 2^21, or else a hint.
+
+ENUM
+ BFD_RELOC_ALPHA_TLSGD
+ENUMX
+ BFD_RELOC_ALPHA_TLSLDM
+ENUMX
+ BFD_RELOC_ALPHA_DTPMOD64
+ENUMX
+ BFD_RELOC_ALPHA_GOTDTPREL16
+ENUMX
+ BFD_RELOC_ALPHA_DTPREL64
+ENUMX
+ BFD_RELOC_ALPHA_DTPREL_HI16
+ENUMX
+ BFD_RELOC_ALPHA_DTPREL_LO16
+ENUMX
+ BFD_RELOC_ALPHA_DTPREL16
+ENUMX
+ BFD_RELOC_ALPHA_GOTTPREL16
+ENUMX
+ BFD_RELOC_ALPHA_TPREL64
+ENUMX
+ BFD_RELOC_ALPHA_TPREL_HI16
+ENUMX
+ BFD_RELOC_ALPHA_TPREL_LO16
+ENUMX
+ BFD_RELOC_ALPHA_TPREL16
+ENUMDOC
+ Alpha thread-local storage relocations.
+
+ENUM
+ BFD_RELOC_MIPS_JMP
+ENUMX
+ BFD_RELOC_MICROMIPS_JMP
+ENUMDOC
+ The MIPS jump instruction.
+
+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_HI16_PCREL
+ENUMDOC
+ High 16 bits of 32-bit pc-relative value
+ENUM
+ BFD_RELOC_HI16_S_PCREL
+ENUMDOC
+ High 16 bits of 32-bit pc-relative value, adjusted
+ENUM
+ BFD_RELOC_LO16_PCREL
+ENUMDOC
+ Low 16 bits of pc-relative value
+
+ENUM
+ BFD_RELOC_MIPS16_GOT16
+ENUMX
+ BFD_RELOC_MIPS16_CALL16
+ENUMDOC
+ Equivalent of BFD_RELOC_MIPS_*, but with the MIPS16 layout of
+ 16-bit immediate fields
+ENUM
+ BFD_RELOC_MIPS16_HI16
+ENUMDOC
+ MIPS16 high 16 bits of 32-bit value.
+ENUM
+ BFD_RELOC_MIPS16_HI16_S
+ENUMDOC
+ MIPS16 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_MIPS16_LO16
+ENUMDOC
+ MIPS16 low 16 bits.
+
+ENUM
+ BFD_RELOC_MIPS16_TLS_GD
+ENUMX
+ BFD_RELOC_MIPS16_TLS_LDM
+ENUMX
+ BFD_RELOC_MIPS16_TLS_DTPREL_HI16
+ENUMX
+ BFD_RELOC_MIPS16_TLS_DTPREL_LO16
+ENUMX
+ BFD_RELOC_MIPS16_TLS_GOTTPREL
+ENUMX
+ BFD_RELOC_MIPS16_TLS_TPREL_HI16
+ENUMX
+ BFD_RELOC_MIPS16_TLS_TPREL_LO16
+ENUMDOC
+ MIPS16 TLS relocations
+
+ENUM
+ BFD_RELOC_MIPS_LITERAL
+ENUMX
+ BFD_RELOC_MICROMIPS_LITERAL
+ENUMDOC
+ Relocation against a MIPS literal section.
+
+ENUM
+ BFD_RELOC_MICROMIPS_7_PCREL_S1
+ENUMX
+ BFD_RELOC_MICROMIPS_10_PCREL_S1
+ENUMX
+ BFD_RELOC_MICROMIPS_16_PCREL_S1
+ENUMDOC
+ microMIPS PC-relative relocations.
+
+ENUM
+ BFD_RELOC_MIPS_21_PCREL_S2
+ENUMX
+ BFD_RELOC_MIPS_26_PCREL_S2
+ENUMX
+ BFD_RELOC_MIPS_18_PCREL_S3
+ENUMX
+ BFD_RELOC_MIPS_19_PCREL_S2
+ENUMDOC
+ MIPS PC-relative relocations.
+
+ENUM
+ BFD_RELOC_MICROMIPS_GPREL16
+ENUMX
+ BFD_RELOC_MICROMIPS_HI16
+ENUMX
+ BFD_RELOC_MICROMIPS_HI16_S
+ENUMX
+ BFD_RELOC_MICROMIPS_LO16
+ENUMDOC
+ microMIPS versions of generic BFD relocs.
+
+ENUM
+ BFD_RELOC_MIPS_GOT16
+ENUMX
+ BFD_RELOC_MICROMIPS_GOT16
+ENUMX
+ BFD_RELOC_MIPS_CALL16
+ENUMX
+ BFD_RELOC_MICROMIPS_CALL16
+ENUMX
+ BFD_RELOC_MIPS_GOT_HI16
+ENUMX
+ BFD_RELOC_MICROMIPS_GOT_HI16
+ENUMX
+ BFD_RELOC_MIPS_GOT_LO16
+ENUMX
+ BFD_RELOC_MICROMIPS_GOT_LO16
+ENUMX
+ BFD_RELOC_MIPS_CALL_HI16
+ENUMX
+ BFD_RELOC_MICROMIPS_CALL_HI16
+ENUMX
+ BFD_RELOC_MIPS_CALL_LO16
+ENUMX
+ BFD_RELOC_MICROMIPS_CALL_LO16
+ENUMX
+ BFD_RELOC_MIPS_SUB
+ENUMX
+ BFD_RELOC_MICROMIPS_SUB
+ENUMX
+ BFD_RELOC_MIPS_GOT_PAGE
+ENUMX
+ BFD_RELOC_MICROMIPS_GOT_PAGE
+ENUMX
+ BFD_RELOC_MIPS_GOT_OFST
+ENUMX
+ BFD_RELOC_MICROMIPS_GOT_OFST
+ENUMX
+ BFD_RELOC_MIPS_GOT_DISP
+ENUMX
+ BFD_RELOC_MICROMIPS_GOT_DISP
+ENUMX
+ BFD_RELOC_MIPS_SHIFT5
+ENUMX
+ BFD_RELOC_MIPS_SHIFT6
+ENUMX
+ BFD_RELOC_MIPS_INSERT_A
+ENUMX
+ BFD_RELOC_MIPS_INSERT_B
+ENUMX
+ BFD_RELOC_MIPS_DELETE
+ENUMX
+ BFD_RELOC_MIPS_HIGHEST
+ENUMX
+ BFD_RELOC_MICROMIPS_HIGHEST
+ENUMX
+ BFD_RELOC_MIPS_HIGHER
+ENUMX
+ BFD_RELOC_MICROMIPS_HIGHER
+ENUMX
+ BFD_RELOC_MIPS_SCN_DISP
+ENUMX
+ BFD_RELOC_MICROMIPS_SCN_DISP
+ENUMX
+ BFD_RELOC_MIPS_REL16
+ENUMX
+ BFD_RELOC_MIPS_RELGOT
+ENUMX
+ BFD_RELOC_MIPS_JALR
+ENUMX
+ BFD_RELOC_MICROMIPS_JALR
+ENUMX
+ BFD_RELOC_MIPS_TLS_DTPMOD32
+ENUMX
+ BFD_RELOC_MIPS_TLS_DTPREL32
+ENUMX
+ BFD_RELOC_MIPS_TLS_DTPMOD64
+ENUMX
+ BFD_RELOC_MIPS_TLS_DTPREL64
+ENUMX
+ BFD_RELOC_MIPS_TLS_GD
+ENUMX
+ BFD_RELOC_MICROMIPS_TLS_GD
+ENUMX
+ BFD_RELOC_MIPS_TLS_LDM
+ENUMX
+ BFD_RELOC_MICROMIPS_TLS_LDM
+ENUMX
+ BFD_RELOC_MIPS_TLS_DTPREL_HI16
+ENUMX
+ BFD_RELOC_MICROMIPS_TLS_DTPREL_HI16
+ENUMX
+ BFD_RELOC_MIPS_TLS_DTPREL_LO16
+ENUMX
+ BFD_RELOC_MICROMIPS_TLS_DTPREL_LO16
+ENUMX
+ BFD_RELOC_MIPS_TLS_GOTTPREL
+ENUMX
+ BFD_RELOC_MICROMIPS_TLS_GOTTPREL
+ENUMX
+ BFD_RELOC_MIPS_TLS_TPREL32
+ENUMX
+ BFD_RELOC_MIPS_TLS_TPREL64
+ENUMX
+ BFD_RELOC_MIPS_TLS_TPREL_HI16
+ENUMX
+ BFD_RELOC_MICROMIPS_TLS_TPREL_HI16
+ENUMX
+ BFD_RELOC_MIPS_TLS_TPREL_LO16
+ENUMX
+ BFD_RELOC_MICROMIPS_TLS_TPREL_LO16
+ENUMX
+ BFD_RELOC_MIPS_EH
+ENUMDOC
+ MIPS ELF relocations.
+COMMENT
+
+ENUM
+ BFD_RELOC_MIPS_COPY
+ENUMX
+ BFD_RELOC_MIPS_JUMP_SLOT
+ENUMDOC
+ MIPS ELF relocations (VxWorks and PLT extensions).
+COMMENT
+
+ENUM
+ BFD_RELOC_MOXIE_10_PCREL
+ENUMDOC
+ Moxie ELF relocations.
+COMMENT
+
+ENUM
+ BFD_RELOC_FRV_LABEL16
+ENUMX
+ BFD_RELOC_FRV_LABEL24
+ENUMX
+ BFD_RELOC_FRV_LO16
+ENUMX
+ BFD_RELOC_FRV_HI16
+ENUMX
+ BFD_RELOC_FRV_GPREL12
+ENUMX
+ BFD_RELOC_FRV_GPRELU12
+ENUMX
+ BFD_RELOC_FRV_GPREL32
+ENUMX
+ BFD_RELOC_FRV_GPRELHI
+ENUMX
+ BFD_RELOC_FRV_GPRELLO
+ENUMX
+ BFD_RELOC_FRV_GOT12
+ENUMX
+ BFD_RELOC_FRV_GOTHI
+ENUMX
+ BFD_RELOC_FRV_GOTLO
+ENUMX
+ BFD_RELOC_FRV_FUNCDESC
+ENUMX
+ BFD_RELOC_FRV_FUNCDESC_GOT12
+ENUMX
+ BFD_RELOC_FRV_FUNCDESC_GOTHI
+ENUMX
+ BFD_RELOC_FRV_FUNCDESC_GOTLO
+ENUMX
+ BFD_RELOC_FRV_FUNCDESC_VALUE
+ENUMX
+ BFD_RELOC_FRV_FUNCDESC_GOTOFF12
+ENUMX
+ BFD_RELOC_FRV_FUNCDESC_GOTOFFHI
+ENUMX
+ BFD_RELOC_FRV_FUNCDESC_GOTOFFLO
+ENUMX
+ BFD_RELOC_FRV_GOTOFF12
+ENUMX
+ BFD_RELOC_FRV_GOTOFFHI
+ENUMX
+ BFD_RELOC_FRV_GOTOFFLO
+ENUMX
+ BFD_RELOC_FRV_GETTLSOFF
+ENUMX
+ BFD_RELOC_FRV_TLSDESC_VALUE
+ENUMX
+ BFD_RELOC_FRV_GOTTLSDESC12
+ENUMX
+ BFD_RELOC_FRV_GOTTLSDESCHI
+ENUMX
+ BFD_RELOC_FRV_GOTTLSDESCLO
+ENUMX
+ BFD_RELOC_FRV_TLSMOFF12
+ENUMX
+ BFD_RELOC_FRV_TLSMOFFHI
+ENUMX
+ BFD_RELOC_FRV_TLSMOFFLO
+ENUMX
+ BFD_RELOC_FRV_GOTTLSOFF12
+ENUMX
+ BFD_RELOC_FRV_GOTTLSOFFHI
+ENUMX
+ BFD_RELOC_FRV_GOTTLSOFFLO
+ENUMX
+ BFD_RELOC_FRV_TLSOFF
+ENUMX
+ BFD_RELOC_FRV_TLSDESC_RELAX
+ENUMX
+ BFD_RELOC_FRV_GETTLSOFF_RELAX
+ENUMX
+ BFD_RELOC_FRV_TLSOFF_RELAX
+ENUMX
+ BFD_RELOC_FRV_TLSMOFF
+ENUMDOC
+ Fujitsu Frv Relocations.
+COMMENT
+
+ENUM
+ BFD_RELOC_MN10300_GOTOFF24
+ENUMDOC
+ This is a 24bit GOT-relative reloc for the mn10300.
+ENUM
+ BFD_RELOC_MN10300_GOT32
+ENUMDOC
+ This is a 32bit GOT-relative reloc for the mn10300, offset by two bytes
+ in the instruction.
+ENUM
+ BFD_RELOC_MN10300_GOT24
+ENUMDOC
+ This is a 24bit GOT-relative reloc for the mn10300, offset by two bytes
+ in the instruction.
+ENUM
+ BFD_RELOC_MN10300_GOT16
+ENUMDOC
+ This is a 16bit GOT-relative reloc for the mn10300, offset by two bytes
+ in the instruction.
+ENUM
+ BFD_RELOC_MN10300_COPY
+ENUMDOC
+ Copy symbol at runtime.
+ENUM
+ BFD_RELOC_MN10300_GLOB_DAT
+ENUMDOC
+ Create GOT entry.
+ENUM
+ BFD_RELOC_MN10300_JMP_SLOT
+ENUMDOC
+ Create PLT entry.
+ENUM
+ BFD_RELOC_MN10300_RELATIVE
+ENUMDOC
+ Adjust by program base.
+ENUM
+ BFD_RELOC_MN10300_SYM_DIFF
+ENUMDOC
+ Together with another reloc targeted at the same location,
+ allows for a value that is the difference of two symbols
+ in the same section.
+ENUM
+ BFD_RELOC_MN10300_ALIGN
+ENUMDOC
+ The addend of this reloc is an alignment power that must
+ be honoured at the offset's location, regardless of linker
+ relaxation.
+ENUM
+ BFD_RELOC_MN10300_TLS_GD
+ENUMX
+ BFD_RELOC_MN10300_TLS_LD
+ENUMX
+ BFD_RELOC_MN10300_TLS_LDO
+ENUMX
+ BFD_RELOC_MN10300_TLS_GOTIE
+ENUMX
+ BFD_RELOC_MN10300_TLS_IE
+ENUMX
+ BFD_RELOC_MN10300_TLS_LE
+ENUMX
+ BFD_RELOC_MN10300_TLS_DTPMOD
+ENUMX
+ BFD_RELOC_MN10300_TLS_DTPOFF
+ENUMX
+ BFD_RELOC_MN10300_TLS_TPOFF
+ENUMDOC
+ Various TLS-related relocations.
+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.
+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
+ENUMX
+ BFD_RELOC_386_TLS_TPOFF
+ENUMX
+ BFD_RELOC_386_TLS_IE
+ENUMX
+ BFD_RELOC_386_TLS_GOTIE
+ENUMX
+ BFD_RELOC_386_TLS_LE
+ENUMX
+ BFD_RELOC_386_TLS_GD
+ENUMX
+ BFD_RELOC_386_TLS_LDM
+ENUMX
+ BFD_RELOC_386_TLS_LDO_32
+ENUMX
+ BFD_RELOC_386_TLS_IE_32
+ENUMX
+ BFD_RELOC_386_TLS_LE_32
+ENUMX
+ BFD_RELOC_386_TLS_DTPMOD32
+ENUMX
+ BFD_RELOC_386_TLS_DTPOFF32
+ENUMX
+ BFD_RELOC_386_TLS_TPOFF32
+ENUMX
+ BFD_RELOC_386_TLS_GOTDESC
+ENUMX
+ BFD_RELOC_386_TLS_DESC_CALL
+ENUMX
+ BFD_RELOC_386_TLS_DESC
+ENUMX
+ BFD_RELOC_386_IRELATIVE
+ENUMDOC
+ i386/elf relocations
+
+ENUM
+ BFD_RELOC_X86_64_GOT32
+ENUMX
+ BFD_RELOC_X86_64_PLT32
+ENUMX
+ BFD_RELOC_X86_64_COPY
+ENUMX
+ BFD_RELOC_X86_64_GLOB_DAT
+ENUMX
+ BFD_RELOC_X86_64_JUMP_SLOT
+ENUMX
+ BFD_RELOC_X86_64_RELATIVE
+ENUMX
+ BFD_RELOC_X86_64_GOTPCREL
+ENUMX
+ BFD_RELOC_X86_64_32S
+ENUMX
+ BFD_RELOC_X86_64_DTPMOD64
+ENUMX
+ BFD_RELOC_X86_64_DTPOFF64
+ENUMX
+ BFD_RELOC_X86_64_TPOFF64
+ENUMX
+ BFD_RELOC_X86_64_TLSGD
+ENUMX
+ BFD_RELOC_X86_64_TLSLD
+ENUMX
+ BFD_RELOC_X86_64_DTPOFF32
+ENUMX
+ BFD_RELOC_X86_64_GOTTPOFF
+ENUMX
+ BFD_RELOC_X86_64_TPOFF32
+ENUMX
+ BFD_RELOC_X86_64_GOTOFF64
+ENUMX
+ BFD_RELOC_X86_64_GOTPC32
+ENUMX
+ BFD_RELOC_X86_64_GOT64
+ENUMX
+ BFD_RELOC_X86_64_GOTPCREL64
+ENUMX
+ BFD_RELOC_X86_64_GOTPC64
+ENUMX
+ BFD_RELOC_X86_64_GOTPLT64
+ENUMX
+ BFD_RELOC_X86_64_PLTOFF64
+ENUMX
+ BFD_RELOC_X86_64_GOTPC32_TLSDESC
+ENUMX
+ BFD_RELOC_X86_64_TLSDESC_CALL
+ENUMX
+ BFD_RELOC_X86_64_TLSDESC
+ENUMX
+ BFD_RELOC_X86_64_IRELATIVE
+ENUMX
+ BFD_RELOC_X86_64_PC32_BND
+ENUMX
+ BFD_RELOC_X86_64_PLT32_BND
+ENUMDOC
+ x86-64/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_PDP11_DISP_8_PCREL
+ENUMX
+ BFD_RELOC_PDP11_DISP_6_PCREL
+ENUMDOC
+ PDP11 relocations
+
+ENUM
+ BFD_RELOC_PJ_CODE_HI16
+ENUMX
+ BFD_RELOC_PJ_CODE_LO16
+ENUMX
+ BFD_RELOC_PJ_CODE_DIR16
+ENUMX
+ BFD_RELOC_PJ_CODE_DIR32
+ENUMX
+ BFD_RELOC_PJ_CODE_REL16
+ENUMX
+ BFD_RELOC_PJ_CODE_REL32
+ENUMDOC
+ Picojava relocs. Not all of these appear in object files.
+
+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
+ENUMX
+ BFD_RELOC_PPC_VLE_REL8
+ENUMX
+ BFD_RELOC_PPC_VLE_REL15
+ENUMX
+ BFD_RELOC_PPC_VLE_REL24
+ENUMX
+ BFD_RELOC_PPC_VLE_LO16A
+ENUMX
+ BFD_RELOC_PPC_VLE_LO16D
+ENUMX
+ BFD_RELOC_PPC_VLE_HI16A
+ENUMX
+ BFD_RELOC_PPC_VLE_HI16D
+ENUMX
+ BFD_RELOC_PPC_VLE_HA16A
+ENUMX
+ BFD_RELOC_PPC_VLE_HA16D
+ENUMX
+ BFD_RELOC_PPC_VLE_SDA21
+ENUMX
+ BFD_RELOC_PPC_VLE_SDA21_LO
+ENUMX
+ BFD_RELOC_PPC_VLE_SDAREL_LO16A
+ENUMX
+ BFD_RELOC_PPC_VLE_SDAREL_LO16D
+ENUMX
+ BFD_RELOC_PPC_VLE_SDAREL_HI16A
+ENUMX
+ BFD_RELOC_PPC_VLE_SDAREL_HI16D
+ENUMX
+ BFD_RELOC_PPC_VLE_SDAREL_HA16A
+ENUMX
+ BFD_RELOC_PPC_VLE_SDAREL_HA16D
+ENUMX
+ BFD_RELOC_PPC64_HIGHER
+ENUMX
+ BFD_RELOC_PPC64_HIGHER_S
+ENUMX
+ BFD_RELOC_PPC64_HIGHEST
+ENUMX
+ BFD_RELOC_PPC64_HIGHEST_S
+ENUMX
+ BFD_RELOC_PPC64_TOC16_LO
+ENUMX
+ BFD_RELOC_PPC64_TOC16_HI
+ENUMX
+ BFD_RELOC_PPC64_TOC16_HA
+ENUMX
+ BFD_RELOC_PPC64_TOC
+ENUMX
+ BFD_RELOC_PPC64_PLTGOT16
+ENUMX
+ BFD_RELOC_PPC64_PLTGOT16_LO
+ENUMX
+ BFD_RELOC_PPC64_PLTGOT16_HI
+ENUMX
+ BFD_RELOC_PPC64_PLTGOT16_HA
+ENUMX
+ BFD_RELOC_PPC64_ADDR16_DS
+ENUMX
+ BFD_RELOC_PPC64_ADDR16_LO_DS
+ENUMX
+ BFD_RELOC_PPC64_GOT16_DS
+ENUMX
+ BFD_RELOC_PPC64_GOT16_LO_DS
+ENUMX
+ BFD_RELOC_PPC64_PLT16_LO_DS
+ENUMX
+ BFD_RELOC_PPC64_SECTOFF_DS
+ENUMX
+ BFD_RELOC_PPC64_SECTOFF_LO_DS
+ENUMX
+ BFD_RELOC_PPC64_TOC16_DS
+ENUMX
+ BFD_RELOC_PPC64_TOC16_LO_DS
+ENUMX
+ BFD_RELOC_PPC64_PLTGOT16_DS
+ENUMX
+ BFD_RELOC_PPC64_PLTGOT16_LO_DS
+ENUMX
+ BFD_RELOC_PPC64_ADDR16_HIGH
+ENUMX
+ BFD_RELOC_PPC64_ADDR16_HIGHA
+ENUMX
+ BFD_RELOC_PPC64_ADDR64_LOCAL
+ENUMDOC
+ Power(rs6000) and PowerPC relocations.
+
+ENUM
+ BFD_RELOC_PPC_TLS
+ENUMX
+ BFD_RELOC_PPC_TLSGD
+ENUMX
+ BFD_RELOC_PPC_TLSLD
+ENUMX
+ BFD_RELOC_PPC_DTPMOD
+ENUMX
+ BFD_RELOC_PPC_TPREL16
+ENUMX
+ BFD_RELOC_PPC_TPREL16_LO
+ENUMX
+ BFD_RELOC_PPC_TPREL16_HI
+ENUMX
+ BFD_RELOC_PPC_TPREL16_HA
+ENUMX
+ BFD_RELOC_PPC_TPREL
+ENUMX
+ BFD_RELOC_PPC_DTPREL16
+ENUMX
+ BFD_RELOC_PPC_DTPREL16_LO
+ENUMX
+ BFD_RELOC_PPC_DTPREL16_HI
+ENUMX
+ BFD_RELOC_PPC_DTPREL16_HA
+ENUMX
+ BFD_RELOC_PPC_DTPREL
+ENUMX
+ BFD_RELOC_PPC_GOT_TLSGD16
+ENUMX
+ BFD_RELOC_PPC_GOT_TLSGD16_LO
+ENUMX
+ BFD_RELOC_PPC_GOT_TLSGD16_HI
+ENUMX
+ BFD_RELOC_PPC_GOT_TLSGD16_HA
+ENUMX
+ BFD_RELOC_PPC_GOT_TLSLD16
+ENUMX
+ BFD_RELOC_PPC_GOT_TLSLD16_LO
+ENUMX
+ BFD_RELOC_PPC_GOT_TLSLD16_HI
+ENUMX
+ BFD_RELOC_PPC_GOT_TLSLD16_HA
+ENUMX
+ BFD_RELOC_PPC_GOT_TPREL16
+ENUMX
+ BFD_RELOC_PPC_GOT_TPREL16_LO
+ENUMX
+ BFD_RELOC_PPC_GOT_TPREL16_HI
+ENUMX
+ BFD_RELOC_PPC_GOT_TPREL16_HA
+ENUMX
+ BFD_RELOC_PPC_GOT_DTPREL16
+ENUMX
+ BFD_RELOC_PPC_GOT_DTPREL16_LO
+ENUMX
+ BFD_RELOC_PPC_GOT_DTPREL16_HI
+ENUMX
+ BFD_RELOC_PPC_GOT_DTPREL16_HA
+ENUMX
+ BFD_RELOC_PPC64_TPREL16_DS
+ENUMX
+ BFD_RELOC_PPC64_TPREL16_LO_DS
+ENUMX
+ BFD_RELOC_PPC64_TPREL16_HIGHER
+ENUMX
+ BFD_RELOC_PPC64_TPREL16_HIGHERA
+ENUMX
+ BFD_RELOC_PPC64_TPREL16_HIGHEST
+ENUMX
+ BFD_RELOC_PPC64_TPREL16_HIGHESTA
+ENUMX
+ BFD_RELOC_PPC64_DTPREL16_DS
+ENUMX
+ BFD_RELOC_PPC64_DTPREL16_LO_DS
+ENUMX
+ BFD_RELOC_PPC64_DTPREL16_HIGHER
+ENUMX
+ BFD_RELOC_PPC64_DTPREL16_HIGHERA
+ENUMX
+ BFD_RELOC_PPC64_DTPREL16_HIGHEST
+ENUMX
+ BFD_RELOC_PPC64_DTPREL16_HIGHESTA
+ENUMX
+ BFD_RELOC_PPC64_TPREL16_HIGH
+ENUMX
+ BFD_RELOC_PPC64_TPREL16_HIGHA
+ENUMX
+ BFD_RELOC_PPC64_DTPREL16_HIGH
+ENUMX
+ BFD_RELOC_PPC64_DTPREL16_HIGHA
+ENUMDOC
+ PowerPC and PowerPC64 thread-local storage relocations.
+
+ENUM
+ BFD_RELOC_I370_D12
+ENUMDOC
+ IBM 370/390 relocations
+
+ENUM
+ BFD_RELOC_CTOR
+ENUMDOC
+ The type of reloc used to build a constructor 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_PCREL_BLX
+ENUMDOC
+ ARM 26 bit pc-relative branch. The lowest bit must be zero and is
+ not stored in the instruction. The 2nd lowest bit comes from a 1 bit
+ field in the instruction.
+ENUM
+ BFD_RELOC_THUMB_PCREL_BLX
+ENUMDOC
+ Thumb 22 bit pc-relative branch. The lowest bit must be zero and is
+ not stored in the instruction. The 2nd lowest bit comes from a 1 bit
+ field in the instruction.
+ENUM
+ BFD_RELOC_ARM_PCREL_CALL
+ENUMDOC
+ ARM 26-bit pc-relative branch for an unconditional BL or BLX instruction.
+ENUM
+ BFD_RELOC_ARM_PCREL_JUMP
+ENUMDOC
+ ARM 26-bit pc-relative branch for B or conditional BL instruction.
+
+ENUM
+ BFD_RELOC_THUMB_PCREL_BRANCH7
+ENUMX
+ BFD_RELOC_THUMB_PCREL_BRANCH9
+ENUMX
+ BFD_RELOC_THUMB_PCREL_BRANCH12
+ENUMX
+ BFD_RELOC_THUMB_PCREL_BRANCH20
+ENUMX
+ BFD_RELOC_THUMB_PCREL_BRANCH23
+ENUMX
+ BFD_RELOC_THUMB_PCREL_BRANCH25
+ENUMDOC
+ Thumb 7-, 9-, 12-, 20-, 23-, and 25-bit pc-relative branches.
+ The lowest bit must be zero and is not stored in the instruction.
+ Note that the corresponding ELF R_ARM_THM_JUMPnn constant has an
+ "nn" one smaller in all cases. Note further that BRANCH23
+ corresponds to R_ARM_THM_CALL.
+
+ENUM
+ BFD_RELOC_ARM_OFFSET_IMM
+ENUMDOC
+ 12-bit immediate offset, used in ARM-format ldr and str instructions.
+
+ENUM
+ BFD_RELOC_ARM_THUMB_OFFSET
+ENUMDOC
+ 5-bit immediate offset, used in Thumb-format ldr and str instructions.
+
+ENUM
+ BFD_RELOC_ARM_TARGET1
+ENUMDOC
+ Pc-relative or absolute relocation depending on target. Used for
+ entries in .init_array sections.
+ENUM
+ BFD_RELOC_ARM_ROSEGREL32
+ENUMDOC
+ Read-only segment base relative address.
+ENUM
+ BFD_RELOC_ARM_SBREL32
+ENUMDOC
+ Data segment base relative address.
+ENUM
+ BFD_RELOC_ARM_TARGET2
+ENUMDOC
+ This reloc is used for references to RTTI data from exception handling
+ tables. The actual definition depends on the target. It may be a
+ pc-relative or some form of GOT-indirect relocation.
+ENUM
+ BFD_RELOC_ARM_PREL31
+ENUMDOC
+ 31-bit PC relative address.
+ENUM
+ BFD_RELOC_ARM_MOVW
+ENUMX
+ BFD_RELOC_ARM_MOVT
+ENUMX
+ BFD_RELOC_ARM_MOVW_PCREL
+ENUMX
+ BFD_RELOC_ARM_MOVT_PCREL
+ENUMX
+ BFD_RELOC_ARM_THUMB_MOVW
+ENUMX
+ BFD_RELOC_ARM_THUMB_MOVT
+ENUMX
+ BFD_RELOC_ARM_THUMB_MOVW_PCREL
+ENUMX
+ BFD_RELOC_ARM_THUMB_MOVT_PCREL
+ENUMDOC
+ Low and High halfword relocations for MOVW and MOVT instructions.
+
+ENUM
+ BFD_RELOC_ARM_JUMP_SLOT
+ENUMX
+ BFD_RELOC_ARM_GLOB_DAT
+ENUMX
+ BFD_RELOC_ARM_GOT32
+ENUMX
+ BFD_RELOC_ARM_PLT32
+ENUMX
+ BFD_RELOC_ARM_RELATIVE
+ENUMX
+ BFD_RELOC_ARM_GOTOFF
+ENUMX
+ BFD_RELOC_ARM_GOTPC
+ENUMX
+ BFD_RELOC_ARM_GOT_PREL
+ENUMDOC
+ Relocations for setting up GOTs and PLTs for shared libraries.
+
+ENUM
+ BFD_RELOC_ARM_TLS_GD32
+ENUMX
+ BFD_RELOC_ARM_TLS_LDO32
+ENUMX
+ BFD_RELOC_ARM_TLS_LDM32
+ENUMX
+ BFD_RELOC_ARM_TLS_DTPOFF32
+ENUMX
+ BFD_RELOC_ARM_TLS_DTPMOD32
+ENUMX
+ BFD_RELOC_ARM_TLS_TPOFF32
+ENUMX
+ BFD_RELOC_ARM_TLS_IE32
+ENUMX
+ BFD_RELOC_ARM_TLS_LE32
+ENUMX
+ BFD_RELOC_ARM_TLS_GOTDESC
+ENUMX
+ BFD_RELOC_ARM_TLS_CALL
+ENUMX
+ BFD_RELOC_ARM_THM_TLS_CALL
+ENUMX
+ BFD_RELOC_ARM_TLS_DESCSEQ
+ENUMX
+ BFD_RELOC_ARM_THM_TLS_DESCSEQ
+ENUMX
+ BFD_RELOC_ARM_TLS_DESC
+ENUMDOC
+ ARM thread-local storage relocations.
+
+ENUM
+ BFD_RELOC_ARM_ALU_PC_G0_NC
+ENUMX
+ BFD_RELOC_ARM_ALU_PC_G0
+ENUMX
+ BFD_RELOC_ARM_ALU_PC_G1_NC
+ENUMX
+ BFD_RELOC_ARM_ALU_PC_G1
+ENUMX
+ BFD_RELOC_ARM_ALU_PC_G2
+ENUMX
+ BFD_RELOC_ARM_LDR_PC_G0
+ENUMX
+ BFD_RELOC_ARM_LDR_PC_G1
+ENUMX
+ BFD_RELOC_ARM_LDR_PC_G2
+ENUMX
+ BFD_RELOC_ARM_LDRS_PC_G0
+ENUMX
+ BFD_RELOC_ARM_LDRS_PC_G1
+ENUMX
+ BFD_RELOC_ARM_LDRS_PC_G2
+ENUMX
+ BFD_RELOC_ARM_LDC_PC_G0
+ENUMX
+ BFD_RELOC_ARM_LDC_PC_G1
+ENUMX
+ BFD_RELOC_ARM_LDC_PC_G2
+ENUMX
+ BFD_RELOC_ARM_ALU_SB_G0_NC
+ENUMX
+ BFD_RELOC_ARM_ALU_SB_G0
+ENUMX
+ BFD_RELOC_ARM_ALU_SB_G1_NC
+ENUMX
+ BFD_RELOC_ARM_ALU_SB_G1
+ENUMX
+ BFD_RELOC_ARM_ALU_SB_G2
+ENUMX
+ BFD_RELOC_ARM_LDR_SB_G0
+ENUMX
+ BFD_RELOC_ARM_LDR_SB_G1
+ENUMX
+ BFD_RELOC_ARM_LDR_SB_G2
+ENUMX
+ BFD_RELOC_ARM_LDRS_SB_G0
+ENUMX
+ BFD_RELOC_ARM_LDRS_SB_G1
+ENUMX
+ BFD_RELOC_ARM_LDRS_SB_G2
+ENUMX
+ BFD_RELOC_ARM_LDC_SB_G0
+ENUMX
+ BFD_RELOC_ARM_LDC_SB_G1
+ENUMX
+ BFD_RELOC_ARM_LDC_SB_G2
+ENUMDOC
+ ARM group relocations.
+
+ENUM
+ BFD_RELOC_ARM_V4BX
+ENUMDOC
+ Annotation of BX instructions.
+
+ENUM
+ BFD_RELOC_ARM_IRELATIVE
+ENUMDOC
+ ARM support for STT_GNU_IFUNC.
+
+ENUM
+ BFD_RELOC_ARM_IMMEDIATE
+ENUMX
+ BFD_RELOC_ARM_ADRL_IMMEDIATE
+ENUMX
+ BFD_RELOC_ARM_T32_IMMEDIATE
+ENUMX
+ BFD_RELOC_ARM_T32_ADD_IMM
+ENUMX
+ BFD_RELOC_ARM_T32_IMM12
+ENUMX
+ BFD_RELOC_ARM_T32_ADD_PC12
+ENUMX
+ BFD_RELOC_ARM_SHIFT_IMM
+ENUMX
+ BFD_RELOC_ARM_SMC
+ENUMX
+ BFD_RELOC_ARM_HVC
+ENUMX
+ BFD_RELOC_ARM_SWI
+ENUMX
+ BFD_RELOC_ARM_MULTI
+ENUMX
+ BFD_RELOC_ARM_CP_OFF_IMM
+ENUMX
+ BFD_RELOC_ARM_CP_OFF_IMM_S2
+ENUMX
+ BFD_RELOC_ARM_T32_CP_OFF_IMM
+ENUMX
+ BFD_RELOC_ARM_T32_CP_OFF_IMM_S2
+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_T32_OFFSET_U8
+ENUMX
+ BFD_RELOC_ARM_T32_OFFSET_IMM
+ENUMX
+ BFD_RELOC_ARM_HWLITERAL
+ENUMX
+ BFD_RELOC_ARM_THUMB_ADD
+ENUMX
+ BFD_RELOC_ARM_THUMB_IMM
+ENUMX
+ BFD_RELOC_ARM_THUMB_SHIFT
+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_IMM3
+ENUMX
+ BFD_RELOC_SH_IMM3U
+ENUMX
+ BFD_RELOC_SH_DISP12
+ENUMX
+ BFD_RELOC_SH_DISP12BY2
+ENUMX
+ BFD_RELOC_SH_DISP12BY4
+ENUMX
+ BFD_RELOC_SH_DISP12BY8
+ENUMX
+ BFD_RELOC_SH_DISP20
+ENUMX
+ BFD_RELOC_SH_DISP20BY8
+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
+ENUMX
+ BFD_RELOC_SH_LOOP_START
+ENUMX
+ BFD_RELOC_SH_LOOP_END
+ENUMX
+ BFD_RELOC_SH_COPY
+ENUMX
+ BFD_RELOC_SH_GLOB_DAT
+ENUMX
+ BFD_RELOC_SH_JMP_SLOT
+ENUMX
+ BFD_RELOC_SH_RELATIVE
+ENUMX
+ BFD_RELOC_SH_GOTPC
+ENUMX
+ BFD_RELOC_SH_GOT_LOW16
+ENUMX
+ BFD_RELOC_SH_GOT_MEDLOW16
+ENUMX
+ BFD_RELOC_SH_GOT_MEDHI16
+ENUMX
+ BFD_RELOC_SH_GOT_HI16
+ENUMX
+ BFD_RELOC_SH_GOTPLT_LOW16
+ENUMX
+ BFD_RELOC_SH_GOTPLT_MEDLOW16
+ENUMX
+ BFD_RELOC_SH_GOTPLT_MEDHI16
+ENUMX
+ BFD_RELOC_SH_GOTPLT_HI16
+ENUMX
+ BFD_RELOC_SH_PLT_LOW16
+ENUMX
+ BFD_RELOC_SH_PLT_MEDLOW16
+ENUMX
+ BFD_RELOC_SH_PLT_MEDHI16
+ENUMX
+ BFD_RELOC_SH_PLT_HI16
+ENUMX
+ BFD_RELOC_SH_GOTOFF_LOW16
+ENUMX
+ BFD_RELOC_SH_GOTOFF_MEDLOW16
+ENUMX
+ BFD_RELOC_SH_GOTOFF_MEDHI16
+ENUMX
+ BFD_RELOC_SH_GOTOFF_HI16
+ENUMX
+ BFD_RELOC_SH_GOTPC_LOW16
+ENUMX
+ BFD_RELOC_SH_GOTPC_MEDLOW16
+ENUMX
+ BFD_RELOC_SH_GOTPC_MEDHI16
+ENUMX
+ BFD_RELOC_SH_GOTPC_HI16
+ENUMX
+ BFD_RELOC_SH_COPY64
+ENUMX
+ BFD_RELOC_SH_GLOB_DAT64
+ENUMX
+ BFD_RELOC_SH_JMP_SLOT64
+ENUMX
+ BFD_RELOC_SH_RELATIVE64
+ENUMX
+ BFD_RELOC_SH_GOT10BY4
+ENUMX
+ BFD_RELOC_SH_GOT10BY8
+ENUMX
+ BFD_RELOC_SH_GOTPLT10BY4
+ENUMX
+ BFD_RELOC_SH_GOTPLT10BY8
+ENUMX
+ BFD_RELOC_SH_GOTPLT32
+ENUMX
+ BFD_RELOC_SH_SHMEDIA_CODE
+ENUMX
+ BFD_RELOC_SH_IMMU5
+ENUMX
+ BFD_RELOC_SH_IMMS6
+ENUMX
+ BFD_RELOC_SH_IMMS6BY32
+ENUMX
+ BFD_RELOC_SH_IMMU6
+ENUMX
+ BFD_RELOC_SH_IMMS10
+ENUMX
+ BFD_RELOC_SH_IMMS10BY2
+ENUMX
+ BFD_RELOC_SH_IMMS10BY4
+ENUMX
+ BFD_RELOC_SH_IMMS10BY8
+ENUMX
+ BFD_RELOC_SH_IMMS16
+ENUMX
+ BFD_RELOC_SH_IMMU16
+ENUMX
+ BFD_RELOC_SH_IMM_LOW16
+ENUMX
+ BFD_RELOC_SH_IMM_LOW16_PCREL
+ENUMX
+ BFD_RELOC_SH_IMM_MEDLOW16
+ENUMX
+ BFD_RELOC_SH_IMM_MEDLOW16_PCREL
+ENUMX
+ BFD_RELOC_SH_IMM_MEDHI16
+ENUMX
+ BFD_RELOC_SH_IMM_MEDHI16_PCREL
+ENUMX
+ BFD_RELOC_SH_IMM_HI16
+ENUMX
+ BFD_RELOC_SH_IMM_HI16_PCREL
+ENUMX
+ BFD_RELOC_SH_PT_16
+ENUMX
+ BFD_RELOC_SH_TLS_GD_32
+ENUMX
+ BFD_RELOC_SH_TLS_LD_32
+ENUMX
+ BFD_RELOC_SH_TLS_LDO_32
+ENUMX
+ BFD_RELOC_SH_TLS_IE_32
+ENUMX
+ BFD_RELOC_SH_TLS_LE_32
+ENUMX
+ BFD_RELOC_SH_TLS_DTPMOD32
+ENUMX
+ BFD_RELOC_SH_TLS_DTPOFF32
+ENUMX
+ BFD_RELOC_SH_TLS_TPOFF32
+ENUMX
+ BFD_RELOC_SH_GOT20
+ENUMX
+ BFD_RELOC_SH_GOTOFF20
+ENUMX
+ BFD_RELOC_SH_GOTFUNCDESC
+ENUMX
+ BFD_RELOC_SH_GOTFUNCDESC20
+ENUMX
+ BFD_RELOC_SH_GOTOFFFUNCDESC
+ENUMX
+ BFD_RELOC_SH_GOTOFFFUNCDESC20
+ENUMX
+ BFD_RELOC_SH_FUNCDESC
+ENUMDOC
+ Renesas / SuperH SH relocs. Not all of these appear in object files.
+
+ENUM
+ BFD_RELOC_ARC_B22_PCREL
+ENUMDOC
+ ARC Cores 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_BFIN_16_IMM
+ENUMDOC
+ ADI Blackfin 16 bit immediate absolute reloc.
+ENUM
+ BFD_RELOC_BFIN_16_HIGH
+ENUMDOC
+ ADI Blackfin 16 bit immediate absolute reloc higher 16 bits.
+ENUM
+ BFD_RELOC_BFIN_4_PCREL
+ENUMDOC
+ ADI Blackfin 'a' part of LSETUP.
+ENUM
+ BFD_RELOC_BFIN_5_PCREL
+ENUMDOC
+ ADI Blackfin.
+ENUM
+ BFD_RELOC_BFIN_16_LOW
+ENUMDOC
+ ADI Blackfin 16 bit immediate absolute reloc lower 16 bits.
+ENUM
+ BFD_RELOC_BFIN_10_PCREL
+ENUMDOC
+ ADI Blackfin.
+ENUM
+ BFD_RELOC_BFIN_11_PCREL
+ENUMDOC
+ ADI Blackfin 'b' part of LSETUP.
+ENUM
+ BFD_RELOC_BFIN_12_PCREL_JUMP
+ENUMDOC
+ ADI Blackfin.
+ENUM
+ BFD_RELOC_BFIN_12_PCREL_JUMP_S
+ENUMDOC
+ ADI Blackfin Short jump, pcrel.
+ENUM
+ BFD_RELOC_BFIN_24_PCREL_CALL_X
+ENUMDOC
+ ADI Blackfin Call.x not implemented.
+ENUM
+ BFD_RELOC_BFIN_24_PCREL_JUMP_L
+ENUMDOC
+ ADI Blackfin Long Jump pcrel.
+ENUM
+ BFD_RELOC_BFIN_GOT17M4
+ENUMX
+ BFD_RELOC_BFIN_GOTHI
+ENUMX
+ BFD_RELOC_BFIN_GOTLO
+ENUMX
+ BFD_RELOC_BFIN_FUNCDESC
+ENUMX
+ BFD_RELOC_BFIN_FUNCDESC_GOT17M4
+ENUMX
+ BFD_RELOC_BFIN_FUNCDESC_GOTHI
+ENUMX
+ BFD_RELOC_BFIN_FUNCDESC_GOTLO
+ENUMX
+ BFD_RELOC_BFIN_FUNCDESC_VALUE
+ENUMX
+ BFD_RELOC_BFIN_FUNCDESC_GOTOFF17M4
+ENUMX
+ BFD_RELOC_BFIN_FUNCDESC_GOTOFFHI
+ENUMX
+ BFD_RELOC_BFIN_FUNCDESC_GOTOFFLO
+ENUMX
+ BFD_RELOC_BFIN_GOTOFF17M4
+ENUMX
+ BFD_RELOC_BFIN_GOTOFFHI
+ENUMX
+ BFD_RELOC_BFIN_GOTOFFLO
+ENUMDOC
+ ADI Blackfin FD-PIC relocations.
+ENUM
+ BFD_RELOC_BFIN_GOT
+ENUMDOC
+ ADI Blackfin GOT relocation.
+ENUM
+ BFD_RELOC_BFIN_PLTPC
+ENUMDOC
+ ADI Blackfin PLTPC relocation.
+ENUM
+ BFD_ARELOC_BFIN_PUSH
+ENUMDOC
+ ADI Blackfin arithmetic relocation.
+ENUM
+ BFD_ARELOC_BFIN_CONST
+ENUMDOC
+ ADI Blackfin arithmetic relocation.
+ENUM
+ BFD_ARELOC_BFIN_ADD
+ENUMDOC
+ ADI Blackfin arithmetic relocation.
+ENUM
+ BFD_ARELOC_BFIN_SUB
+ENUMDOC
+ ADI Blackfin arithmetic relocation.
+ENUM
+ BFD_ARELOC_BFIN_MULT
+ENUMDOC
+ ADI Blackfin arithmetic relocation.
+ENUM
+ BFD_ARELOC_BFIN_DIV
+ENUMDOC
+ ADI Blackfin arithmetic relocation.
+ENUM
+ BFD_ARELOC_BFIN_MOD
+ENUMDOC
+ ADI Blackfin arithmetic relocation.
+ENUM
+ BFD_ARELOC_BFIN_LSHIFT
+ENUMDOC
+ ADI Blackfin arithmetic relocation.
+ENUM
+ BFD_ARELOC_BFIN_RSHIFT
+ENUMDOC
+ ADI Blackfin arithmetic relocation.
+ENUM
+ BFD_ARELOC_BFIN_AND
+ENUMDOC
+ ADI Blackfin arithmetic relocation.
+ENUM
+ BFD_ARELOC_BFIN_OR
+ENUMDOC
+ ADI Blackfin arithmetic relocation.
+ENUM
+ BFD_ARELOC_BFIN_XOR
+ENUMDOC
+ ADI Blackfin arithmetic relocation.
+ENUM
+ BFD_ARELOC_BFIN_LAND
+ENUMDOC
+ ADI Blackfin arithmetic relocation.
+ENUM
+ BFD_ARELOC_BFIN_LOR
+ENUMDOC
+ ADI Blackfin arithmetic relocation.
+ENUM
+ BFD_ARELOC_BFIN_LEN
+ENUMDOC
+ ADI Blackfin arithmetic relocation.
+ENUM
+ BFD_ARELOC_BFIN_NEG
+ENUMDOC
+ ADI Blackfin arithmetic relocation.
+ENUM
+ BFD_ARELOC_BFIN_COMP
+ENUMDOC
+ ADI Blackfin arithmetic relocation.
+ENUM
+ BFD_ARELOC_BFIN_PAGE
+ENUMDOC
+ ADI Blackfin arithmetic relocation.
+ENUM
+ BFD_ARELOC_BFIN_HWPAGE
+ENUMDOC
+ ADI Blackfin arithmetic relocation.
+ENUM
+ BFD_ARELOC_BFIN_ADDR
+ENUMDOC
+ ADI Blackfin arithmetic relocation.
+
+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_DLX_HI16_S
+ENUMDOC
+ DLX relocs
+ENUM
+ BFD_RELOC_DLX_LO16
+ENUMDOC
+ DLX relocs
+ENUM
+ BFD_RELOC_DLX_JMP26
+ENUMDOC
+ DLX relocs
+
+ENUM
+ BFD_RELOC_M32C_HI8
+ENUMX
+ BFD_RELOC_M32C_RL_JUMP
+ENUMX
+ BFD_RELOC_M32C_RL_1ADDR
+ENUMX
+ BFD_RELOC_M32C_RL_2ADDR
+ENUMDOC
+ Renesas M16C/M32C Relocations.
+
+ENUM
+ BFD_RELOC_M32R_24
+ENUMDOC
+ Renesas M32R (formerly 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_M32R_GOT24
+ENUMX
+ BFD_RELOC_M32R_26_PLTREL
+ENUMX
+ BFD_RELOC_M32R_COPY
+ENUMX
+ BFD_RELOC_M32R_GLOB_DAT
+ENUMX
+ BFD_RELOC_M32R_JMP_SLOT
+ENUMX
+ BFD_RELOC_M32R_RELATIVE
+ENUMX
+ BFD_RELOC_M32R_GOTOFF
+ENUMX
+ BFD_RELOC_M32R_GOTOFF_HI_ULO
+ENUMX
+ BFD_RELOC_M32R_GOTOFF_HI_SLO
+ENUMX
+ BFD_RELOC_M32R_GOTOFF_LO
+ENUMX
+ BFD_RELOC_M32R_GOTPC24
+ENUMX
+ BFD_RELOC_M32R_GOT16_HI_ULO
+ENUMX
+ BFD_RELOC_M32R_GOT16_HI_SLO
+ENUMX
+ BFD_RELOC_M32R_GOT16_LO
+ENUMX
+ BFD_RELOC_M32R_GOTPC_HI_ULO
+ENUMX
+ BFD_RELOC_M32R_GOTPC_HI_SLO
+ENUMX
+ BFD_RELOC_M32R_GOTPC_LO
+ENUMDOC
+ For PIC.
+
+
+ENUM
+ BFD_RELOC_NDS32_20
+ENUMDOC
+ NDS32 relocs.
+ This is a 20 bit absolute address.
+ENUM
+ BFD_RELOC_NDS32_9_PCREL
+ENUMDOC
+ This is a 9-bit pc-relative reloc with the right 1 bit assumed to be 0.
+ENUM
+ BFD_RELOC_NDS32_WORD_9_PCREL
+ENUMDOC
+ This is a 9-bit pc-relative reloc with the right 1 bit assumed to be 0.
+ENUM
+ BFD_RELOC_NDS32_15_PCREL
+ENUMDOC
+ This is an 15-bit reloc with the right 1 bit assumed to be 0.
+ENUM
+ BFD_RELOC_NDS32_17_PCREL
+ENUMDOC
+ This is an 17-bit reloc with the right 1 bit assumed to be 0.
+ENUM
+ BFD_RELOC_NDS32_25_PCREL
+ENUMDOC
+ This is a 25-bit reloc with the right 1 bit assumed to be 0.
+ENUM
+ BFD_RELOC_NDS32_HI20
+ENUMDOC
+ This is a 20-bit reloc containing the high 20 bits of an address
+ used with the lower 12 bits
+ENUM
+ BFD_RELOC_NDS32_LO12S3
+ENUMDOC
+ This is a 12-bit reloc containing the lower 12 bits of an address
+ then shift right by 3. This is used with ldi,sdi...
+ENUM
+ BFD_RELOC_NDS32_LO12S2
+ENUMDOC
+ This is a 12-bit reloc containing the lower 12 bits of an address
+ then shift left by 2. This is used with lwi,swi...
+ENUM
+ BFD_RELOC_NDS32_LO12S1
+ENUMDOC
+ This is a 12-bit reloc containing the lower 12 bits of an address
+ then shift left by 1. This is used with lhi,shi...
+ENUM
+ BFD_RELOC_NDS32_LO12S0
+ENUMDOC
+ This is a 12-bit reloc containing the lower 12 bits of an address
+ then shift left by 0. This is used with lbisbi...
+ENUM
+ BFD_RELOC_NDS32_LO12S0_ORI
+ENUMDOC
+ This is a 12-bit reloc containing the lower 12 bits of an address
+ then shift left by 0. This is only used with branch relaxations
+ENUM
+ BFD_RELOC_NDS32_SDA15S3
+ENUMDOC
+ This is a 15-bit reloc containing the small data area 18-bit signed offset
+ and shift left by 3 for use in ldi, sdi...
+ENUM
+ BFD_RELOC_NDS32_SDA15S2
+ENUMDOC
+ This is a 15-bit reloc containing the small data area 17-bit signed offset
+ and shift left by 2 for use in lwi, swi...
+ENUM
+ BFD_RELOC_NDS32_SDA15S1
+ENUMDOC
+ This is a 15-bit reloc containing the small data area 16-bit signed offset
+ and shift left by 1 for use in lhi, shi...
+ENUM
+ BFD_RELOC_NDS32_SDA15S0
+ENUMDOC
+ This is a 15-bit reloc containing the small data area 15-bit signed offset
+ and shift left by 0 for use in lbi, sbi...
+ENUM
+ BFD_RELOC_NDS32_SDA16S3
+ENUMDOC
+ This is a 16-bit reloc containing the small data area 16-bit signed offset
+ and shift left by 3
+ENUM
+ BFD_RELOC_NDS32_SDA17S2
+ENUMDOC
+ This is a 17-bit reloc containing the small data area 17-bit signed offset
+ and shift left by 2 for use in lwi.gp, swi.gp...
+ENUM
+ BFD_RELOC_NDS32_SDA18S1
+ENUMDOC
+ This is a 18-bit reloc containing the small data area 18-bit signed offset
+ and shift left by 1 for use in lhi.gp, shi.gp...
+ENUM
+ BFD_RELOC_NDS32_SDA19S0
+ENUMDOC
+ This is a 19-bit reloc containing the small data area 19-bit signed offset
+ and shift left by 0 for use in lbi.gp, sbi.gp...
+ENUM
+ BFD_RELOC_NDS32_GOT20
+ENUMX
+ BFD_RELOC_NDS32_9_PLTREL
+ENUMX
+ BFD_RELOC_NDS32_25_PLTREL
+ENUMX
+ BFD_RELOC_NDS32_COPY
+ENUMX
+ BFD_RELOC_NDS32_GLOB_DAT
+ENUMX
+ BFD_RELOC_NDS32_JMP_SLOT
+ENUMX
+ BFD_RELOC_NDS32_RELATIVE
+ENUMX
+ BFD_RELOC_NDS32_GOTOFF
+ENUMX
+ BFD_RELOC_NDS32_GOTOFF_HI20
+ENUMX
+ BFD_RELOC_NDS32_GOTOFF_LO12
+ENUMX
+ BFD_RELOC_NDS32_GOTPC20
+ENUMX
+ BFD_RELOC_NDS32_GOT_HI20
+ENUMX
+ BFD_RELOC_NDS32_GOT_LO12
+ENUMX
+ BFD_RELOC_NDS32_GOTPC_HI20
+ENUMX
+ BFD_RELOC_NDS32_GOTPC_LO12
+ENUMDOC
+ for PIC
+ENUM
+ BFD_RELOC_NDS32_INSN16
+ENUMX
+ BFD_RELOC_NDS32_LABEL
+ENUMX
+ BFD_RELOC_NDS32_LONGCALL1
+ENUMX
+ BFD_RELOC_NDS32_LONGCALL2
+ENUMX
+ BFD_RELOC_NDS32_LONGCALL3
+ENUMX
+ BFD_RELOC_NDS32_LONGJUMP1
+ENUMX
+ BFD_RELOC_NDS32_LONGJUMP2
+ENUMX
+ BFD_RELOC_NDS32_LONGJUMP3
+ENUMX
+ BFD_RELOC_NDS32_LOADSTORE
+ENUMX
+ BFD_RELOC_NDS32_9_FIXED
+ENUMX
+ BFD_RELOC_NDS32_15_FIXED
+ENUMX
+ BFD_RELOC_NDS32_17_FIXED
+ENUMX
+ BFD_RELOC_NDS32_25_FIXED
+ENUMX
+ BFD_RELOC_NDS32_LONGCALL4
+ENUMX
+ BFD_RELOC_NDS32_LONGCALL5
+ENUMX
+ BFD_RELOC_NDS32_LONGCALL6
+ENUMX
+ BFD_RELOC_NDS32_LONGJUMP4
+ENUMX
+ BFD_RELOC_NDS32_LONGJUMP5
+ENUMX
+ BFD_RELOC_NDS32_LONGJUMP6
+ENUMX
+ BFD_RELOC_NDS32_LONGJUMP7
+ENUMDOC
+ for relax
+ENUM
+ BFD_RELOC_NDS32_PLTREL_HI20
+ENUMX
+ BFD_RELOC_NDS32_PLTREL_LO12
+ENUMX
+ BFD_RELOC_NDS32_PLT_GOTREL_HI20
+ENUMX
+ BFD_RELOC_NDS32_PLT_GOTREL_LO12
+ENUMDOC
+ for PIC
+ENUM
+ BFD_RELOC_NDS32_SDA12S2_DP
+ENUMX
+ BFD_RELOC_NDS32_SDA12S2_SP
+ENUMX
+ BFD_RELOC_NDS32_LO12S2_DP
+ENUMX
+ BFD_RELOC_NDS32_LO12S2_SP
+ENUMDOC
+ for floating point
+ENUM
+ BFD_RELOC_NDS32_DWARF2_OP1
+ENUMX
+ BFD_RELOC_NDS32_DWARF2_OP2
+ENUMX
+ BFD_RELOC_NDS32_DWARF2_LEB
+ENUMDOC
+ for dwarf2 debug_line.
+ENUM
+ BFD_RELOC_NDS32_UPDATE_TA
+ENUMDOC
+ for eliminate 16-bit instructions
+ENUM
+ BFD_RELOC_NDS32_PLT_GOTREL_LO20
+ENUMX
+ BFD_RELOC_NDS32_PLT_GOTREL_LO15
+ENUMX
+ BFD_RELOC_NDS32_PLT_GOTREL_LO19
+ENUMX
+ BFD_RELOC_NDS32_GOT_LO15
+ENUMX
+ BFD_RELOC_NDS32_GOT_LO19
+ENUMX
+ BFD_RELOC_NDS32_GOTOFF_LO15
+ENUMX
+ BFD_RELOC_NDS32_GOTOFF_LO19
+ENUMX
+ BFD_RELOC_NDS32_GOT15S2
+ENUMX
+ BFD_RELOC_NDS32_GOT17S2
+ENUMDOC
+ for PIC object relaxation
+ENUM
+ BFD_RELOC_NDS32_5
+ENUMDOC
+ NDS32 relocs.
+ This is a 5 bit absolute address.
+ENUM
+ BFD_RELOC_NDS32_10_UPCREL
+ENUMDOC
+ This is a 10-bit unsigned pc-relative reloc with the right 1 bit assumed to be 0.
+ENUM
+ BFD_RELOC_NDS32_SDA_FP7U2_RELA
+ENUMDOC
+ If fp were omitted, fp can used as another gp.
+ENUM
+ BFD_RELOC_NDS32_RELAX_ENTRY
+ENUMX
+ BFD_RELOC_NDS32_GOT_SUFF
+ENUMX
+ BFD_RELOC_NDS32_GOTOFF_SUFF
+ENUMX
+ BFD_RELOC_NDS32_PLT_GOT_SUFF
+ENUMX
+ BFD_RELOC_NDS32_MULCALL_SUFF
+ENUMX
+ BFD_RELOC_NDS32_PTR
+ENUMX
+ BFD_RELOC_NDS32_PTR_COUNT
+ENUMX
+ BFD_RELOC_NDS32_PTR_RESOLVED
+ENUMX
+ BFD_RELOC_NDS32_PLTBLOCK
+ENUMX
+ BFD_RELOC_NDS32_RELAX_REGION_BEGIN
+ENUMX
+ BFD_RELOC_NDS32_RELAX_REGION_END
+ENUMX
+ BFD_RELOC_NDS32_MINUEND
+ENUMX
+ BFD_RELOC_NDS32_SUBTRAHEND
+ENUMX
+ BFD_RELOC_NDS32_DIFF8
+ENUMX
+ BFD_RELOC_NDS32_DIFF16
+ENUMX
+ BFD_RELOC_NDS32_DIFF32
+ENUMX
+ BFD_RELOC_NDS32_DIFF_ULEB128
+ENUMX
+ BFD_RELOC_NDS32_EMPTY
+ENUMDOC
+ relaxation relative relocation types
+ENUM
+ BFD_RELOC_NDS32_25_ABS
+ENUMDOC
+ This is a 25 bit absolute address.
+ENUM
+ BFD_RELOC_NDS32_DATA
+ENUMX
+ BFD_RELOC_NDS32_TRAN
+ENUMX
+ BFD_RELOC_NDS32_17IFC_PCREL
+ENUMX
+ BFD_RELOC_NDS32_10IFCU_PCREL
+ENUMDOC
+ For ex9 and ifc using.
+ENUM
+ BFD_RELOC_NDS32_TPOFF
+ENUMX
+ BFD_RELOC_NDS32_TLS_LE_HI20
+ENUMX
+ BFD_RELOC_NDS32_TLS_LE_LO12
+ENUMX
+ BFD_RELOC_NDS32_TLS_LE_ADD
+ENUMX
+ BFD_RELOC_NDS32_TLS_LE_LS
+ENUMX
+ BFD_RELOC_NDS32_GOTTPOFF
+ENUMX
+ BFD_RELOC_NDS32_TLS_IE_HI20
+ENUMX
+ BFD_RELOC_NDS32_TLS_IE_LO12S2
+ENUMX
+ BFD_RELOC_NDS32_TLS_TPOFF
+ENUMX
+ BFD_RELOC_NDS32_TLS_LE_20
+ENUMX
+ BFD_RELOC_NDS32_TLS_LE_15S0
+ENUMX
+ BFD_RELOC_NDS32_TLS_LE_15S1
+ENUMX
+ BFD_RELOC_NDS32_TLS_LE_15S2
+ENUMDOC
+ For TLS.
+
+
+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-contiguously 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-contiguously 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.
+ENUM
+ BFD_RELOC_V850_LONGCALL
+ENUMDOC
+ Used for relaxing indirect function calls.
+ENUM
+ BFD_RELOC_V850_LONGJUMP
+ENUMDOC
+ Used for relaxing indirect jumps.
+ENUM
+ BFD_RELOC_V850_ALIGN
+ENUMDOC
+ Used to maintain alignment whilst relaxing.
+ENUM
+ BFD_RELOC_V850_LO16_SPLIT_OFFSET
+ENUMDOC
+ This is a variation of BFD_RELOC_LO16 that can be used in v850e ld.bu
+ instructions.
+ENUM
+ BFD_RELOC_V850_16_PCREL
+ENUMDOC
+ This is a 16-bit reloc.
+ENUM
+ BFD_RELOC_V850_17_PCREL
+ENUMDOC
+ This is a 17-bit reloc.
+ENUM
+ BFD_RELOC_V850_23
+ENUMDOC
+ This is a 23-bit reloc.
+ENUM
+ BFD_RELOC_V850_32_PCREL
+ENUMDOC
+ This is a 32-bit reloc.
+ENUM
+ BFD_RELOC_V850_32_ABS
+ENUMDOC
+ This is a 32-bit reloc.
+ENUM
+ BFD_RELOC_V850_16_SPLIT_OFFSET
+ENUMDOC
+ This is a 16-bit reloc.
+ENUM
+ BFD_RELOC_V850_16_S1
+ENUMDOC
+ This is a 16-bit reloc.
+ENUM
+ BFD_RELOC_V850_LO16_S1
+ENUMDOC
+ Low 16 bits. 16 bit shifted by 1.
+ENUM
+ BFD_RELOC_V850_CALLT_15_16_OFFSET
+ENUMDOC
+ This is a 16 bit offset from the call table base pointer.
+ENUM
+ BFD_RELOC_V850_32_GOTPCREL
+ENUMDOC
+ DSO relocations.
+ENUM
+ BFD_RELOC_V850_16_GOT
+ENUMDOC
+ DSO relocations.
+ENUM
+ BFD_RELOC_V850_32_GOT
+ENUMDOC
+ DSO relocations.
+ENUM
+ BFD_RELOC_V850_22_PLT_PCREL
+ENUMDOC
+ DSO relocations.
+ENUM
+ BFD_RELOC_V850_32_PLT_PCREL
+ENUMDOC
+ DSO relocations.
+ENUM
+ BFD_RELOC_V850_COPY
+ENUMDOC
+ DSO relocations.
+ENUM
+ BFD_RELOC_V850_GLOB_DAT
+ENUMDOC
+ DSO relocations.
+ENUM
+ BFD_RELOC_V850_JMP_SLOT
+ENUMDOC
+ DSO relocations.
+ENUM
+ BFD_RELOC_V850_RELATIVE
+ENUMDOC
+ DSO relocations.
+ENUM
+ BFD_RELOC_V850_16_GOTOFF
+ENUMDOC
+ DSO relocations.
+ENUM
+ BFD_RELOC_V850_32_GOTOFF
+ENUMDOC
+ DSO relocations.
+ENUM
+ BFD_RELOC_V850_CODE
+ENUMDOC
+ start code.
+ENUM
+ BFD_RELOC_V850_DATA
+ENUMDOC
+ start data in text.
+
+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_TIC54X_PARTLS7
+ENUMDOC
+ This is a 7bit reloc for the tms320c54x, where the least
+ significant 7 bits of a 16 bit word are placed into the least
+ significant 7 bits of the opcode.
+
+ENUM
+ BFD_RELOC_TIC54X_PARTMS9
+ENUMDOC
+ This is a 9bit DP reloc for the tms320c54x, where the most
+ significant 9 bits of a 16 bit word are placed into the least
+ significant 9 bits of the opcode.
+
+ENUM
+ BFD_RELOC_TIC54X_23
+ENUMDOC
+ This is an extended address 23-bit reloc for the tms320c54x.
+
+ENUM
+ BFD_RELOC_TIC54X_16_OF_23
+ENUMDOC
+ This is a 16-bit reloc for the tms320c54x, where the least
+ significant 16 bits of a 23-bit extended address are placed into
+ the opcode.
+
+ENUM
+ BFD_RELOC_TIC54X_MS7_OF_23
+ENUMDOC
+ This is a reloc for the tms320c54x, where the most
+ significant 7 bits of a 23-bit extended address are placed into
+ the opcode.
+
+ENUM
+ BFD_RELOC_C6000_PCR_S21
+ENUMX
+ BFD_RELOC_C6000_PCR_S12
+ENUMX
+ BFD_RELOC_C6000_PCR_S10
+ENUMX
+ BFD_RELOC_C6000_PCR_S7
+ENUMX
+ BFD_RELOC_C6000_ABS_S16
+ENUMX
+ BFD_RELOC_C6000_ABS_L16
+ENUMX
+ BFD_RELOC_C6000_ABS_H16
+ENUMX
+ BFD_RELOC_C6000_SBR_U15_B
+ENUMX
+ BFD_RELOC_C6000_SBR_U15_H
+ENUMX
+ BFD_RELOC_C6000_SBR_U15_W
+ENUMX
+ BFD_RELOC_C6000_SBR_S16
+ENUMX
+ BFD_RELOC_C6000_SBR_L16_B
+ENUMX
+ BFD_RELOC_C6000_SBR_L16_H
+ENUMX
+ BFD_RELOC_C6000_SBR_L16_W
+ENUMX
+ BFD_RELOC_C6000_SBR_H16_B
+ENUMX
+ BFD_RELOC_C6000_SBR_H16_H
+ENUMX
+ BFD_RELOC_C6000_SBR_H16_W
+ENUMX
+ BFD_RELOC_C6000_SBR_GOT_U15_W
+ENUMX
+ BFD_RELOC_C6000_SBR_GOT_L16_W
+ENUMX
+ BFD_RELOC_C6000_SBR_GOT_H16_W
+ENUMX
+ BFD_RELOC_C6000_DSBT_INDEX
+ENUMX
+ BFD_RELOC_C6000_PREL31
+ENUMX
+ BFD_RELOC_C6000_COPY
+ENUMX
+ BFD_RELOC_C6000_JUMP_SLOT
+ENUMX
+ BFD_RELOC_C6000_EHTYPE
+ENUMX
+ BFD_RELOC_C6000_PCR_H16
+ENUMX
+ BFD_RELOC_C6000_PCR_L16
+ENUMX
+ BFD_RELOC_C6000_ALIGN
+ENUMX
+ BFD_RELOC_C6000_FPHEAD
+ENUMX
+ BFD_RELOC_C6000_NOCMP
+ENUMDOC
+ TMS320C6000 relocations.
+
+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
+ENUMX
+ BFD_RELOC_MCORE_RVA
+ENUMDOC
+ Motorola Mcore relocations.
+
+ENUM
+ BFD_RELOC_MEP_8
+ENUMX
+ BFD_RELOC_MEP_16
+ENUMX
+ BFD_RELOC_MEP_32
+ENUMX
+ BFD_RELOC_MEP_PCREL8A2
+ENUMX
+ BFD_RELOC_MEP_PCREL12A2
+ENUMX
+ BFD_RELOC_MEP_PCREL17A2
+ENUMX
+ BFD_RELOC_MEP_PCREL24A2
+ENUMX
+ BFD_RELOC_MEP_PCABS24A2
+ENUMX
+ BFD_RELOC_MEP_LOW16
+ENUMX
+ BFD_RELOC_MEP_HI16U
+ENUMX
+ BFD_RELOC_MEP_HI16S
+ENUMX
+ BFD_RELOC_MEP_GPREL
+ENUMX
+ BFD_RELOC_MEP_TPREL
+ENUMX
+ BFD_RELOC_MEP_TPREL7
+ENUMX
+ BFD_RELOC_MEP_TPREL7A2
+ENUMX
+ BFD_RELOC_MEP_TPREL7A4
+ENUMX
+ BFD_RELOC_MEP_UIMM24
+ENUMX
+ BFD_RELOC_MEP_ADDR24A4
+ENUMX
+ BFD_RELOC_MEP_GNU_VTINHERIT
+ENUMX
+ BFD_RELOC_MEP_GNU_VTENTRY
+ENUMDOC
+ Toshiba Media Processor Relocations.
+COMMENT
+
+ENUM
+ BFD_RELOC_METAG_HIADDR16
+ENUMX
+ BFD_RELOC_METAG_LOADDR16
+ENUMX
+ BFD_RELOC_METAG_RELBRANCH
+ENUMX
+ BFD_RELOC_METAG_GETSETOFF
+ENUMX
+ BFD_RELOC_METAG_HIOG
+ENUMX
+ BFD_RELOC_METAG_LOOG
+ENUMX
+ BFD_RELOC_METAG_REL8
+ENUMX
+ BFD_RELOC_METAG_REL16
+ENUMX
+ BFD_RELOC_METAG_HI16_GOTOFF
+ENUMX
+ BFD_RELOC_METAG_LO16_GOTOFF
+ENUMX
+ BFD_RELOC_METAG_GETSET_GOTOFF
+ENUMX
+ BFD_RELOC_METAG_GETSET_GOT
+ENUMX
+ BFD_RELOC_METAG_HI16_GOTPC
+ENUMX
+ BFD_RELOC_METAG_LO16_GOTPC
+ENUMX
+ BFD_RELOC_METAG_HI16_PLT
+ENUMX
+ BFD_RELOC_METAG_LO16_PLT
+ENUMX
+ BFD_RELOC_METAG_RELBRANCH_PLT
+ENUMX
+ BFD_RELOC_METAG_GOTOFF
+ENUMX
+ BFD_RELOC_METAG_PLT
+ENUMX
+ BFD_RELOC_METAG_COPY
+ENUMX
+ BFD_RELOC_METAG_JMP_SLOT
+ENUMX
+ BFD_RELOC_METAG_RELATIVE
+ENUMX
+ BFD_RELOC_METAG_GLOB_DAT
+ENUMX
+ BFD_RELOC_METAG_TLS_GD
+ENUMX
+ BFD_RELOC_METAG_TLS_LDM
+ENUMX
+ BFD_RELOC_METAG_TLS_LDO_HI16
+ENUMX
+ BFD_RELOC_METAG_TLS_LDO_LO16
+ENUMX
+ BFD_RELOC_METAG_TLS_LDO
+ENUMX
+ BFD_RELOC_METAG_TLS_IE
+ENUMX
+ BFD_RELOC_METAG_TLS_IENONPIC
+ENUMX
+ BFD_RELOC_METAG_TLS_IENONPIC_HI16
+ENUMX
+ BFD_RELOC_METAG_TLS_IENONPIC_LO16
+ENUMX
+ BFD_RELOC_METAG_TLS_TPOFF
+ENUMX
+ BFD_RELOC_METAG_TLS_DTPMOD
+ENUMX
+ BFD_RELOC_METAG_TLS_DTPOFF
+ENUMX
+ BFD_RELOC_METAG_TLS_LE
+ENUMX
+ BFD_RELOC_METAG_TLS_LE_HI16
+ENUMX
+ BFD_RELOC_METAG_TLS_LE_LO16
+ENUMDOC
+ Imagination Technologies Meta relocations.
+
+ENUM
+ BFD_RELOC_MMIX_GETA
+ENUMX
+ BFD_RELOC_MMIX_GETA_1
+ENUMX
+ BFD_RELOC_MMIX_GETA_2
+ENUMX
+ BFD_RELOC_MMIX_GETA_3
+ENUMDOC
+ These are relocations for the GETA instruction.
+ENUM
+ BFD_RELOC_MMIX_CBRANCH
+ENUMX
+ BFD_RELOC_MMIX_CBRANCH_J
+ENUMX
+ BFD_RELOC_MMIX_CBRANCH_1
+ENUMX
+ BFD_RELOC_MMIX_CBRANCH_2
+ENUMX
+ BFD_RELOC_MMIX_CBRANCH_3
+ENUMDOC
+ These are relocations for a conditional branch instruction.
+ENUM
+ BFD_RELOC_MMIX_PUSHJ
+ENUMX
+ BFD_RELOC_MMIX_PUSHJ_1
+ENUMX
+ BFD_RELOC_MMIX_PUSHJ_2
+ENUMX
+ BFD_RELOC_MMIX_PUSHJ_3
+ENUMX
+ BFD_RELOC_MMIX_PUSHJ_STUBBABLE
+ENUMDOC
+ These are relocations for the PUSHJ instruction.
+ENUM
+ BFD_RELOC_MMIX_JMP
+ENUMX
+ BFD_RELOC_MMIX_JMP_1
+ENUMX
+ BFD_RELOC_MMIX_JMP_2
+ENUMX
+ BFD_RELOC_MMIX_JMP_3
+ENUMDOC
+ These are relocations for the JMP instruction.
+ENUM
+ BFD_RELOC_MMIX_ADDR19
+ENUMDOC
+ This is a relocation for a relative address as in a GETA instruction or
+ a branch.
+ENUM
+ BFD_RELOC_MMIX_ADDR27
+ENUMDOC
+ This is a relocation for a relative address as in a JMP instruction.
+ENUM
+ BFD_RELOC_MMIX_REG_OR_BYTE
+ENUMDOC
+ This is a relocation for an instruction field that may be a general
+ register or a value 0..255.
+ENUM
+ BFD_RELOC_MMIX_REG
+ENUMDOC
+ This is a relocation for an instruction field that may be a general
+ register.
+ENUM
+ BFD_RELOC_MMIX_BASE_PLUS_OFFSET
+ENUMDOC
+ This is a relocation for two instruction fields holding a register and
+ an offset, the equivalent of the relocation.
+ENUM
+ BFD_RELOC_MMIX_LOCAL
+ENUMDOC
+ This relocation is an assertion that the expression is not allocated as
+ a global register. It does not modify contents.
+
+ENUM
+ BFD_RELOC_AVR_7_PCREL
+ENUMDOC
+ This is a 16 bit reloc for the AVR that stores 8 bit pc relative
+ short offset into 7 bits.
+ENUM
+ BFD_RELOC_AVR_13_PCREL
+ENUMDOC
+ This is a 16 bit reloc for the AVR that stores 13 bit pc relative
+ short offset into 12 bits.
+ENUM
+ BFD_RELOC_AVR_16_PM
+ENUMDOC
+ This is a 16 bit reloc for the AVR that stores 17 bit value (usually
+ program memory address) into 16 bits.
+ENUM
+ BFD_RELOC_AVR_LO8_LDI
+ENUMDOC
+ This is a 16 bit reloc for the AVR that stores 8 bit value (usually
+ data memory address) into 8 bit immediate value of LDI insn.
+ENUM
+ BFD_RELOC_AVR_HI8_LDI
+ENUMDOC
+ This is a 16 bit reloc for the AVR that stores 8 bit value (high 8 bit
+ of data memory address) into 8 bit immediate value of LDI insn.
+ENUM
+ BFD_RELOC_AVR_HH8_LDI
+ENUMDOC
+ This is a 16 bit reloc for the AVR that stores 8 bit value (most high 8 bit
+ of program memory address) into 8 bit immediate value of LDI insn.
+ENUM
+ BFD_RELOC_AVR_MS8_LDI
+ENUMDOC
+ This is a 16 bit reloc for the AVR that stores 8 bit value (most high 8 bit
+ of 32 bit value) into 8 bit immediate value of LDI insn.
+ENUM
+ BFD_RELOC_AVR_LO8_LDI_NEG
+ENUMDOC
+ This is a 16 bit reloc for the AVR that stores negated 8 bit value
+ (usually data memory address) into 8 bit immediate value of SUBI insn.
+ENUM
+ BFD_RELOC_AVR_HI8_LDI_NEG
+ENUMDOC
+ This is a 16 bit reloc for the AVR that stores negated 8 bit value
+ (high 8 bit of data memory address) into 8 bit immediate value of
+ SUBI insn.
+ENUM
+ BFD_RELOC_AVR_HH8_LDI_NEG
+ENUMDOC
+ This is a 16 bit reloc for the AVR that stores negated 8 bit value
+ (most high 8 bit of program memory address) into 8 bit immediate value
+ of LDI or SUBI insn.
+ENUM
+ BFD_RELOC_AVR_MS8_LDI_NEG
+ENUMDOC
+ This is a 16 bit reloc for the AVR that stores negated 8 bit value (msb
+ of 32 bit value) into 8 bit immediate value of LDI insn.
+ENUM
+ BFD_RELOC_AVR_LO8_LDI_PM
+ENUMDOC
+ This is a 16 bit reloc for the AVR that stores 8 bit value (usually
+ command address) into 8 bit immediate value of LDI insn.
+ENUM
+ BFD_RELOC_AVR_LO8_LDI_GS
+ENUMDOC
+ This is a 16 bit reloc for the AVR that stores 8 bit value
+ (command address) into 8 bit immediate value of LDI insn. If the address
+ is beyond the 128k boundary, the linker inserts a jump stub for this reloc
+ in the lower 128k.
+ENUM
+ BFD_RELOC_AVR_HI8_LDI_PM
+ENUMDOC
+ This is a 16 bit reloc for the AVR that stores 8 bit value (high 8 bit
+ of command address) into 8 bit immediate value of LDI insn.
+ENUM
+ BFD_RELOC_AVR_HI8_LDI_GS
+ENUMDOC
+ This is a 16 bit reloc for the AVR that stores 8 bit value (high 8 bit
+ of command address) into 8 bit immediate value of LDI insn. If the address
+ is beyond the 128k boundary, the linker inserts a jump stub for this reloc
+ below 128k.
+ENUM
+ BFD_RELOC_AVR_HH8_LDI_PM
+ENUMDOC
+ This is a 16 bit reloc for the AVR that stores 8 bit value (most high 8 bit
+ of command address) into 8 bit immediate value of LDI insn.
+ENUM
+ BFD_RELOC_AVR_LO8_LDI_PM_NEG
+ENUMDOC
+ This is a 16 bit reloc for the AVR that stores negated 8 bit value
+ (usually command address) into 8 bit immediate value of SUBI insn.
+ENUM
+ BFD_RELOC_AVR_HI8_LDI_PM_NEG
+ENUMDOC
+ This is a 16 bit reloc for the AVR that stores negated 8 bit value
+ (high 8 bit of 16 bit command address) into 8 bit immediate value
+ of SUBI insn.
+ENUM
+ BFD_RELOC_AVR_HH8_LDI_PM_NEG
+ENUMDOC
+ This is a 16 bit reloc for the AVR that stores negated 8 bit value
+ (high 6 bit of 22 bit command address) into 8 bit immediate
+ value of SUBI insn.
+ENUM
+ BFD_RELOC_AVR_CALL
+ENUMDOC
+ This is a 32 bit reloc for the AVR that stores 23 bit value
+ into 22 bits.
+ENUM
+ BFD_RELOC_AVR_LDI
+ENUMDOC
+ This is a 16 bit reloc for the AVR that stores all needed bits
+ for absolute addressing with ldi with overflow check to linktime
+ENUM
+ BFD_RELOC_AVR_6
+ENUMDOC
+ This is a 6 bit reloc for the AVR that stores offset for ldd/std
+ instructions
+ENUM
+ BFD_RELOC_AVR_6_ADIW
+ENUMDOC
+ This is a 6 bit reloc for the AVR that stores offset for adiw/sbiw
+ instructions
+ENUM
+ BFD_RELOC_AVR_8_LO
+ENUMDOC
+ This is a 8 bit reloc for the AVR that stores bits 0..7 of a symbol
+ in .byte lo8(symbol)
+ENUM
+ BFD_RELOC_AVR_8_HI
+ENUMDOC
+ This is a 8 bit reloc for the AVR that stores bits 8..15 of a symbol
+ in .byte hi8(symbol)
+ENUM
+ BFD_RELOC_AVR_8_HLO
+ENUMDOC
+ This is a 8 bit reloc for the AVR that stores bits 16..23 of a symbol
+ in .byte hlo8(symbol)
+ENUM
+ BFD_RELOC_AVR_DIFF8
+ENUMX
+ BFD_RELOC_AVR_DIFF16
+ENUMX
+ BFD_RELOC_AVR_DIFF32
+ENUMDOC
+ AVR relocations to mark the difference of two local symbols.
+ These are only needed to support linker relaxation and can be ignored
+ when not relaxing. The field is set to the value of the difference
+ assuming no relaxation. The relocation encodes the position of the
+ second symbol so the linker can determine whether to adjust the field
+ value.
+ENUM
+ BFD_RELOC_AVR_LDS_STS_16
+ENUMDOC
+ This is a 7 bit reloc for the AVR that stores SRAM address for 16bit
+ lds and sts instructions supported only tiny core.
+ENUM
+ BFD_RELOC_AVR_PORT6
+ENUMDOC
+ This is a 6 bit reloc for the AVR that stores an I/O register
+ number for the IN and OUT instructions
+ENUM
+ BFD_RELOC_AVR_PORT5
+ENUMDOC
+ This is a 5 bit reloc for the AVR that stores an I/O register
+ number for the SBIC, SBIS, SBI and CBI instructions
+ENUM
+ BFD_RELOC_RL78_NEG8
+ENUMX
+ BFD_RELOC_RL78_NEG16
+ENUMX
+ BFD_RELOC_RL78_NEG24
+ENUMX
+ BFD_RELOC_RL78_NEG32
+ENUMX
+ BFD_RELOC_RL78_16_OP
+ENUMX
+ BFD_RELOC_RL78_24_OP
+ENUMX
+ BFD_RELOC_RL78_32_OP
+ENUMX
+ BFD_RELOC_RL78_8U
+ENUMX
+ BFD_RELOC_RL78_16U
+ENUMX
+ BFD_RELOC_RL78_24U
+ENUMX
+ BFD_RELOC_RL78_DIR3U_PCREL
+ENUMX
+ BFD_RELOC_RL78_DIFF
+ENUMX
+ BFD_RELOC_RL78_GPRELB
+ENUMX
+ BFD_RELOC_RL78_GPRELW
+ENUMX
+ BFD_RELOC_RL78_GPRELL
+ENUMX
+ BFD_RELOC_RL78_SYM
+ENUMX
+ BFD_RELOC_RL78_OP_SUBTRACT
+ENUMX
+ BFD_RELOC_RL78_OP_NEG
+ENUMX
+ BFD_RELOC_RL78_OP_AND
+ENUMX
+ BFD_RELOC_RL78_OP_SHRA
+ENUMX
+ BFD_RELOC_RL78_ABS8
+ENUMX
+ BFD_RELOC_RL78_ABS16
+ENUMX
+ BFD_RELOC_RL78_ABS16_REV
+ENUMX
+ BFD_RELOC_RL78_ABS32
+ENUMX
+ BFD_RELOC_RL78_ABS32_REV
+ENUMX
+ BFD_RELOC_RL78_ABS16U
+ENUMX
+ BFD_RELOC_RL78_ABS16UW
+ENUMX
+ BFD_RELOC_RL78_ABS16UL
+ENUMX
+ BFD_RELOC_RL78_RELAX
+ENUMX
+ BFD_RELOC_RL78_HI16
+ENUMX
+ BFD_RELOC_RL78_HI8
+ENUMX
+ BFD_RELOC_RL78_LO16
+ENUMX
+ BFD_RELOC_RL78_CODE
+ENUMDOC
+ Renesas RL78 Relocations.
+
+ENUM
+ BFD_RELOC_RX_NEG8
+ENUMX
+ BFD_RELOC_RX_NEG16
+ENUMX
+ BFD_RELOC_RX_NEG24
+ENUMX
+ BFD_RELOC_RX_NEG32
+ENUMX
+ BFD_RELOC_RX_16_OP
+ENUMX
+ BFD_RELOC_RX_24_OP
+ENUMX
+ BFD_RELOC_RX_32_OP
+ENUMX
+ BFD_RELOC_RX_8U
+ENUMX
+ BFD_RELOC_RX_16U
+ENUMX
+ BFD_RELOC_RX_24U
+ENUMX
+ BFD_RELOC_RX_DIR3U_PCREL
+ENUMX
+ BFD_RELOC_RX_DIFF
+ENUMX
+ BFD_RELOC_RX_GPRELB
+ENUMX
+ BFD_RELOC_RX_GPRELW
+ENUMX
+ BFD_RELOC_RX_GPRELL
+ENUMX
+ BFD_RELOC_RX_SYM
+ENUMX
+ BFD_RELOC_RX_OP_SUBTRACT
+ENUMX
+ BFD_RELOC_RX_OP_NEG
+ENUMX
+ BFD_RELOC_RX_ABS8
+ENUMX
+ BFD_RELOC_RX_ABS16
+ENUMX
+ BFD_RELOC_RX_ABS16_REV
+ENUMX
+ BFD_RELOC_RX_ABS32
+ENUMX
+ BFD_RELOC_RX_ABS32_REV
+ENUMX
+ BFD_RELOC_RX_ABS16U
+ENUMX
+ BFD_RELOC_RX_ABS16UW
+ENUMX
+ BFD_RELOC_RX_ABS16UL
+ENUMX
+ BFD_RELOC_RX_RELAX
+ENUMDOC
+ Renesas RX Relocations.
+
+ENUM
+ BFD_RELOC_390_12
+ENUMDOC
+ Direct 12 bit.
+ENUM
+ BFD_RELOC_390_GOT12
+ENUMDOC
+ 12 bit GOT offset.
+ENUM
+ BFD_RELOC_390_PLT32
+ENUMDOC
+ 32 bit PC relative PLT address.
+ENUM
+ BFD_RELOC_390_COPY
+ENUMDOC
+ Copy symbol at runtime.
+ENUM
+ BFD_RELOC_390_GLOB_DAT
+ENUMDOC
+ Create GOT entry.
+ENUM
+ BFD_RELOC_390_JMP_SLOT
+ENUMDOC
+ Create PLT entry.
+ENUM
+ BFD_RELOC_390_RELATIVE
+ENUMDOC
+ Adjust by program base.
+ENUM
+ BFD_RELOC_390_GOTPC
+ENUMDOC
+ 32 bit PC relative offset to GOT.
+ENUM
+ BFD_RELOC_390_GOT16
+ENUMDOC
+ 16 bit GOT offset.
+ENUM
+ BFD_RELOC_390_PC12DBL
+ENUMDOC
+ PC relative 12 bit shifted by 1.
+ENUM
+ BFD_RELOC_390_PLT12DBL
+ENUMDOC
+ 12 bit PC rel. PLT shifted by 1.
+ENUM
+ BFD_RELOC_390_PC16DBL
+ENUMDOC
+ PC relative 16 bit shifted by 1.
+ENUM
+ BFD_RELOC_390_PLT16DBL
+ENUMDOC
+ 16 bit PC rel. PLT shifted by 1.
+ENUM
+ BFD_RELOC_390_PC24DBL
+ENUMDOC
+ PC relative 24 bit shifted by 1.
+ENUM
+ BFD_RELOC_390_PLT24DBL
+ENUMDOC
+ 24 bit PC rel. PLT shifted by 1.
+ENUM
+ BFD_RELOC_390_PC32DBL
+ENUMDOC
+ PC relative 32 bit shifted by 1.
+ENUM
+ BFD_RELOC_390_PLT32DBL
+ENUMDOC
+ 32 bit PC rel. PLT shifted by 1.
+ENUM
+ BFD_RELOC_390_GOTPCDBL
+ENUMDOC
+ 32 bit PC rel. GOT shifted by 1.
+ENUM
+ BFD_RELOC_390_GOT64
+ENUMDOC
+ 64 bit GOT offset.
+ENUM
+ BFD_RELOC_390_PLT64
+ENUMDOC
+ 64 bit PC relative PLT address.
+ENUM
+ BFD_RELOC_390_GOTENT
+ENUMDOC
+ 32 bit rel. offset to GOT entry.
+ENUM
+ BFD_RELOC_390_GOTOFF64
+ENUMDOC
+ 64 bit offset to GOT.
+ENUM
+ BFD_RELOC_390_GOTPLT12
+ENUMDOC
+ 12-bit offset to symbol-entry within GOT, with PLT handling.
+ENUM
+ BFD_RELOC_390_GOTPLT16
+ENUMDOC
+ 16-bit offset to symbol-entry within GOT, with PLT handling.
+ENUM
+ BFD_RELOC_390_GOTPLT32
+ENUMDOC
+ 32-bit offset to symbol-entry within GOT, with PLT handling.
+ENUM
+ BFD_RELOC_390_GOTPLT64
+ENUMDOC
+ 64-bit offset to symbol-entry within GOT, with PLT handling.
+ENUM
+ BFD_RELOC_390_GOTPLTENT
+ENUMDOC
+ 32-bit rel. offset to symbol-entry within GOT, with PLT handling.
+ENUM
+ BFD_RELOC_390_PLTOFF16
+ENUMDOC
+ 16-bit rel. offset from the GOT to a PLT entry.
+ENUM
+ BFD_RELOC_390_PLTOFF32
+ENUMDOC
+ 32-bit rel. offset from the GOT to a PLT entry.
+ENUM
+ BFD_RELOC_390_PLTOFF64
+ENUMDOC
+ 64-bit rel. offset from the GOT to a PLT entry.
+
+ENUM
+ BFD_RELOC_390_TLS_LOAD
+ENUMX
+ BFD_RELOC_390_TLS_GDCALL
+ENUMX
+ BFD_RELOC_390_TLS_LDCALL
+ENUMX
+ BFD_RELOC_390_TLS_GD32
+ENUMX
+ BFD_RELOC_390_TLS_GD64
+ENUMX
+ BFD_RELOC_390_TLS_GOTIE12
+ENUMX
+ BFD_RELOC_390_TLS_GOTIE32
+ENUMX
+ BFD_RELOC_390_TLS_GOTIE64
+ENUMX
+ BFD_RELOC_390_TLS_LDM32
+ENUMX
+ BFD_RELOC_390_TLS_LDM64
+ENUMX
+ BFD_RELOC_390_TLS_IE32
+ENUMX
+ BFD_RELOC_390_TLS_IE64
+ENUMX
+ BFD_RELOC_390_TLS_IEENT
+ENUMX
+ BFD_RELOC_390_TLS_LE32
+ENUMX
+ BFD_RELOC_390_TLS_LE64
+ENUMX
+ BFD_RELOC_390_TLS_LDO32
+ENUMX
+ BFD_RELOC_390_TLS_LDO64
+ENUMX
+ BFD_RELOC_390_TLS_DTPMOD
+ENUMX
+ BFD_RELOC_390_TLS_DTPOFF
+ENUMX
+ BFD_RELOC_390_TLS_TPOFF
+ENUMDOC
+ s390 tls relocations.
+
+ENUM
+ BFD_RELOC_390_20
+ENUMX
+ BFD_RELOC_390_GOT20
+ENUMX
+ BFD_RELOC_390_GOTPLT20
+ENUMX
+ BFD_RELOC_390_TLS_GOTIE20
+ENUMDOC
+ Long displacement extension.
+
+ENUM
+ BFD_RELOC_390_IRELATIVE
+ENUMDOC
+ STT_GNU_IFUNC relocation.
+
+ENUM
+ BFD_RELOC_SCORE_GPREL15
+ENUMDOC
+ Score relocations
+ Low 16 bit for load/store
+ENUM
+ BFD_RELOC_SCORE_DUMMY2
+ENUMX
+ BFD_RELOC_SCORE_JMP
+ENUMDOC
+ This is a 24-bit reloc with the right 1 bit assumed to be 0
+ENUM
+ BFD_RELOC_SCORE_BRANCH
+ENUMDOC
+ This is a 19-bit reloc with the right 1 bit assumed to be 0
+ENUM
+ BFD_RELOC_SCORE_IMM30
+ENUMDOC
+ This is a 32-bit reloc for 48-bit instructions.
+ENUM
+ BFD_RELOC_SCORE_IMM32
+ENUMDOC
+ This is a 32-bit reloc for 48-bit instructions.
+ENUM
+ BFD_RELOC_SCORE16_JMP
+ENUMDOC
+ This is a 11-bit reloc with the right 1 bit assumed to be 0
+ENUM
+ BFD_RELOC_SCORE16_BRANCH
+ENUMDOC
+ This is a 8-bit reloc with the right 1 bit assumed to be 0
+ENUM
+ BFD_RELOC_SCORE_BCMP
+ENUMDOC
+ This is a 9-bit reloc with the right 1 bit assumed to be 0
+ENUM
+ BFD_RELOC_SCORE_GOT15
+ENUMX
+ BFD_RELOC_SCORE_GOT_LO16
+ENUMX
+ BFD_RELOC_SCORE_CALL15
+ENUMX
+ BFD_RELOC_SCORE_DUMMY_HI16
+ENUMDOC
+ Undocumented Score relocs
+
+ENUM
+ BFD_RELOC_IP2K_FR9
+ENUMDOC
+ Scenix IP2K - 9-bit register number / data address
+ENUM
+ BFD_RELOC_IP2K_BANK
+ENUMDOC
+ Scenix IP2K - 4-bit register/data bank number
+ENUM
+ BFD_RELOC_IP2K_ADDR16CJP
+ENUMDOC
+ Scenix IP2K - low 13 bits of instruction word address
+ENUM
+ BFD_RELOC_IP2K_PAGE3
+ENUMDOC
+ Scenix IP2K - high 3 bits of instruction word address
+ENUM
+ BFD_RELOC_IP2K_LO8DATA
+ENUMX
+ BFD_RELOC_IP2K_HI8DATA
+ENUMX
+ BFD_RELOC_IP2K_EX8DATA
+ENUMDOC
+ Scenix IP2K - ext/low/high 8 bits of data address
+ENUM
+ BFD_RELOC_IP2K_LO8INSN
+ENUMX
+ BFD_RELOC_IP2K_HI8INSN
+ENUMDOC
+ Scenix IP2K - low/high 8 bits of instruction word address
+ENUM
+ BFD_RELOC_IP2K_PC_SKIP
+ENUMDOC
+ Scenix IP2K - even/odd PC modifier to modify snb pcl.0
+ENUM
+ BFD_RELOC_IP2K_TEXT
+ENUMDOC
+ Scenix IP2K - 16 bit word address in text section.
+ENUM
+ BFD_RELOC_IP2K_FR_OFFSET
+ENUMDOC
+ Scenix IP2K - 7-bit sp or dp offset
+ENUM
+ BFD_RELOC_VPE4KMATH_DATA
+ENUMX
+ BFD_RELOC_VPE4KMATH_INSN
+ENUMDOC
+ Scenix VPE4K coprocessor - data/insn-space addressing
+
+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 inheritance 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.
+
+ENUM
+ BFD_RELOC_IA64_IMM14
+ENUMX
+ BFD_RELOC_IA64_IMM22
+ENUMX
+ BFD_RELOC_IA64_IMM64
+ENUMX
+ BFD_RELOC_IA64_DIR32MSB
+ENUMX
+ BFD_RELOC_IA64_DIR32LSB
+ENUMX
+ BFD_RELOC_IA64_DIR64MSB
+ENUMX
+ BFD_RELOC_IA64_DIR64LSB
+ENUMX
+ BFD_RELOC_IA64_GPREL22
+ENUMX
+ BFD_RELOC_IA64_GPREL64I
+ENUMX
+ BFD_RELOC_IA64_GPREL32MSB
+ENUMX
+ BFD_RELOC_IA64_GPREL32LSB
+ENUMX
+ BFD_RELOC_IA64_GPREL64MSB
+ENUMX
+ BFD_RELOC_IA64_GPREL64LSB
+ENUMX
+ BFD_RELOC_IA64_LTOFF22
+ENUMX
+ BFD_RELOC_IA64_LTOFF64I
+ENUMX
+ BFD_RELOC_IA64_PLTOFF22
+ENUMX
+ BFD_RELOC_IA64_PLTOFF64I
+ENUMX
+ BFD_RELOC_IA64_PLTOFF64MSB
+ENUMX
+ BFD_RELOC_IA64_PLTOFF64LSB
+ENUMX
+ BFD_RELOC_IA64_FPTR64I
+ENUMX
+ BFD_RELOC_IA64_FPTR32MSB
+ENUMX
+ BFD_RELOC_IA64_FPTR32LSB
+ENUMX
+ BFD_RELOC_IA64_FPTR64MSB
+ENUMX
+ BFD_RELOC_IA64_FPTR64LSB
+ENUMX
+ BFD_RELOC_IA64_PCREL21B
+ENUMX
+ BFD_RELOC_IA64_PCREL21BI
+ENUMX
+ BFD_RELOC_IA64_PCREL21M
+ENUMX
+ BFD_RELOC_IA64_PCREL21F
+ENUMX
+ BFD_RELOC_IA64_PCREL22
+ENUMX
+ BFD_RELOC_IA64_PCREL60B
+ENUMX
+ BFD_RELOC_IA64_PCREL64I
+ENUMX
+ BFD_RELOC_IA64_PCREL32MSB
+ENUMX
+ BFD_RELOC_IA64_PCREL32LSB
+ENUMX
+ BFD_RELOC_IA64_PCREL64MSB
+ENUMX
+ BFD_RELOC_IA64_PCREL64LSB
+ENUMX
+ BFD_RELOC_IA64_LTOFF_FPTR22
+ENUMX
+ BFD_RELOC_IA64_LTOFF_FPTR64I
+ENUMX
+ BFD_RELOC_IA64_LTOFF_FPTR32MSB
+ENUMX
+ BFD_RELOC_IA64_LTOFF_FPTR32LSB
+ENUMX
+ BFD_RELOC_IA64_LTOFF_FPTR64MSB
+ENUMX
+ BFD_RELOC_IA64_LTOFF_FPTR64LSB
+ENUMX
+ BFD_RELOC_IA64_SEGREL32MSB
+ENUMX
+ BFD_RELOC_IA64_SEGREL32LSB
+ENUMX
+ BFD_RELOC_IA64_SEGREL64MSB
+ENUMX
+ BFD_RELOC_IA64_SEGREL64LSB
+ENUMX
+ BFD_RELOC_IA64_SECREL32MSB
+ENUMX
+ BFD_RELOC_IA64_SECREL32LSB
+ENUMX
+ BFD_RELOC_IA64_SECREL64MSB
+ENUMX
+ BFD_RELOC_IA64_SECREL64LSB
+ENUMX
+ BFD_RELOC_IA64_REL32MSB
+ENUMX
+ BFD_RELOC_IA64_REL32LSB
+ENUMX
+ BFD_RELOC_IA64_REL64MSB
+ENUMX
+ BFD_RELOC_IA64_REL64LSB
+ENUMX
+ BFD_RELOC_IA64_LTV32MSB
+ENUMX
+ BFD_RELOC_IA64_LTV32LSB
+ENUMX
+ BFD_RELOC_IA64_LTV64MSB
+ENUMX
+ BFD_RELOC_IA64_LTV64LSB
+ENUMX
+ BFD_RELOC_IA64_IPLTMSB
+ENUMX
+ BFD_RELOC_IA64_IPLTLSB
+ENUMX
+ BFD_RELOC_IA64_COPY
+ENUMX
+ BFD_RELOC_IA64_LTOFF22X
+ENUMX
+ BFD_RELOC_IA64_LDXMOV
+ENUMX
+ BFD_RELOC_IA64_TPREL14
+ENUMX
+ BFD_RELOC_IA64_TPREL22
+ENUMX
+ BFD_RELOC_IA64_TPREL64I
+ENUMX
+ BFD_RELOC_IA64_TPREL64MSB
+ENUMX
+ BFD_RELOC_IA64_TPREL64LSB
+ENUMX
+ BFD_RELOC_IA64_LTOFF_TPREL22
+ENUMX
+ BFD_RELOC_IA64_DTPMOD64MSB
+ENUMX
+ BFD_RELOC_IA64_DTPMOD64LSB
+ENUMX
+ BFD_RELOC_IA64_LTOFF_DTPMOD22
+ENUMX
+ BFD_RELOC_IA64_DTPREL14
+ENUMX
+ BFD_RELOC_IA64_DTPREL22
+ENUMX
+ BFD_RELOC_IA64_DTPREL64I
+ENUMX
+ BFD_RELOC_IA64_DTPREL32MSB
+ENUMX
+ BFD_RELOC_IA64_DTPREL32LSB
+ENUMX
+ BFD_RELOC_IA64_DTPREL64MSB
+ENUMX
+ BFD_RELOC_IA64_DTPREL64LSB
+ENUMX
+ BFD_RELOC_IA64_LTOFF_DTPREL22
+ENUMDOC
+ Intel IA64 Relocations.
+
+ENUM
+ BFD_RELOC_M68HC11_HI8
+ENUMDOC
+ Motorola 68HC11 reloc.
+ This is the 8 bit high part of an absolute address.
+ENUM
+ BFD_RELOC_M68HC11_LO8
+ENUMDOC
+ Motorola 68HC11 reloc.
+ This is the 8 bit low part of an absolute address.
+ENUM
+ BFD_RELOC_M68HC11_3B
+ENUMDOC
+ Motorola 68HC11 reloc.
+ This is the 3 bit of a value.
+ENUM
+ BFD_RELOC_M68HC11_RL_JUMP
+ENUMDOC
+ Motorola 68HC11 reloc.
+ This reloc marks the beginning of a jump/call instruction.
+ It is used for linker relaxation to correctly identify beginning
+ of instruction and change some branches to use PC-relative
+ addressing mode.
+ENUM
+ BFD_RELOC_M68HC11_RL_GROUP
+ENUMDOC
+ Motorola 68HC11 reloc.
+ This reloc marks a group of several instructions that gcc generates
+ and for which the linker relaxation pass can modify and/or remove
+ some of them.
+ENUM
+ BFD_RELOC_M68HC11_LO16
+ENUMDOC
+ Motorola 68HC11 reloc.
+ This is the 16-bit lower part of an address. It is used for 'call'
+ instruction to specify the symbol address without any special
+ transformation (due to memory bank window).
+ENUM
+ BFD_RELOC_M68HC11_PAGE
+ENUMDOC
+ Motorola 68HC11 reloc.
+ This is a 8-bit reloc that specifies the page number of an address.
+ It is used by 'call' instruction to specify the page number of
+ the symbol.
+ENUM
+ BFD_RELOC_M68HC11_24
+ENUMDOC
+ Motorola 68HC11 reloc.
+ This is a 24-bit reloc that represents the address with a 16-bit
+ value and a 8-bit page number. The symbol address is transformed
+ to follow the 16K memory bank of 68HC12 (seen as mapped in the window).
+ENUM
+ BFD_RELOC_M68HC12_5B
+ENUMDOC
+ Motorola 68HC12 reloc.
+ This is the 5 bits of a value.
+ENUM
+ BFD_RELOC_XGATE_RL_JUMP
+ENUMDOC
+ Freescale XGATE reloc.
+ This reloc marks the beginning of a bra/jal instruction.
+ENUM
+ BFD_RELOC_XGATE_RL_GROUP
+ENUMDOC
+ Freescale XGATE reloc.
+ This reloc marks a group of several instructions that gcc generates
+ and for which the linker relaxation pass can modify and/or remove
+ some of them.
+ENUM
+ BFD_RELOC_XGATE_LO16
+ENUMDOC
+ Freescale XGATE reloc.
+ This is the 16-bit lower part of an address. It is used for the '16-bit'
+ instructions.
+ENUM
+ BFD_RELOC_XGATE_GPAGE
+ENUMDOC
+ Freescale XGATE reloc.
+ENUM
+ BFD_RELOC_XGATE_24
+ENUMDOC
+ Freescale XGATE reloc.
+ENUM
+ BFD_RELOC_XGATE_PCREL_9
+ENUMDOC
+ Freescale XGATE reloc.
+ This is a 9-bit pc-relative reloc.
+ENUM
+ BFD_RELOC_XGATE_PCREL_10
+ENUMDOC
+ Freescale XGATE reloc.
+ This is a 10-bit pc-relative reloc.
+ENUM
+ BFD_RELOC_XGATE_IMM8_LO
+ENUMDOC
+ Freescale XGATE reloc.
+ This is the 16-bit lower part of an address. It is used for the '16-bit'
+ instructions.
+ENUM
+ BFD_RELOC_XGATE_IMM8_HI
+ENUMDOC
+ Freescale XGATE reloc.
+ This is the 16-bit higher part of an address. It is used for the '16-bit'
+ instructions.
+ENUM
+ BFD_RELOC_XGATE_IMM3
+ENUMDOC
+ Freescale XGATE reloc.
+ This is a 3-bit pc-relative reloc.
+ENUM
+ BFD_RELOC_XGATE_IMM4
+ENUMDOC
+ Freescale XGATE reloc.
+ This is a 4-bit pc-relative reloc.
+ENUM
+ BFD_RELOC_XGATE_IMM5
+ENUMDOC
+ Freescale XGATE reloc.
+ This is a 5-bit pc-relative reloc.
+ENUM
+ BFD_RELOC_M68HC12_9B
+ENUMDOC
+ Motorola 68HC12 reloc.
+ This is the 9 bits of a value.
+ENUM
+ BFD_RELOC_M68HC12_16B
+ENUMDOC
+ Motorola 68HC12 reloc.
+ This is the 16 bits of a value.
+ENUM
+ BFD_RELOC_M68HC12_9_PCREL
+ENUMDOC
+ Motorola 68HC12/XGATE reloc.
+ This is a PCREL9 branch.
+ENUM
+ BFD_RELOC_M68HC12_10_PCREL
+ENUMDOC
+ Motorola 68HC12/XGATE reloc.
+ This is a PCREL10 branch.
+ENUM
+ BFD_RELOC_M68HC12_LO8XG
+ENUMDOC
+ Motorola 68HC12/XGATE reloc.
+ This is the 8 bit low part of an absolute address and immediately precedes
+ a matching HI8XG part.
+ENUM
+ BFD_RELOC_M68HC12_HI8XG
+ENUMDOC
+ Motorola 68HC12/XGATE reloc.
+ This is the 8 bit high part of an absolute address and immediately follows
+ a matching LO8XG part.
+ENUM
+ BFD_RELOC_16C_NUM08
+ENUMX
+ BFD_RELOC_16C_NUM08_C
+ENUMX
+ BFD_RELOC_16C_NUM16
+ENUMX
+ BFD_RELOC_16C_NUM16_C
+ENUMX
+ BFD_RELOC_16C_NUM32
+ENUMX
+ BFD_RELOC_16C_NUM32_C
+ENUMX
+ BFD_RELOC_16C_DISP04
+ENUMX
+ BFD_RELOC_16C_DISP04_C
+ENUMX
+ BFD_RELOC_16C_DISP08
+ENUMX
+ BFD_RELOC_16C_DISP08_C
+ENUMX
+ BFD_RELOC_16C_DISP16
+ENUMX
+ BFD_RELOC_16C_DISP16_C
+ENUMX
+ BFD_RELOC_16C_DISP24
+ENUMX
+ BFD_RELOC_16C_DISP24_C
+ENUMX
+ BFD_RELOC_16C_DISP24a
+ENUMX
+ BFD_RELOC_16C_DISP24a_C
+ENUMX
+ BFD_RELOC_16C_REG04
+ENUMX
+ BFD_RELOC_16C_REG04_C
+ENUMX
+ BFD_RELOC_16C_REG04a
+ENUMX
+ BFD_RELOC_16C_REG04a_C
+ENUMX
+ BFD_RELOC_16C_REG14
+ENUMX
+ BFD_RELOC_16C_REG14_C
+ENUMX
+ BFD_RELOC_16C_REG16
+ENUMX
+ BFD_RELOC_16C_REG16_C
+ENUMX
+ BFD_RELOC_16C_REG20
+ENUMX
+ BFD_RELOC_16C_REG20_C
+ENUMX
+ BFD_RELOC_16C_ABS20
+ENUMX
+ BFD_RELOC_16C_ABS20_C
+ENUMX
+ BFD_RELOC_16C_ABS24
+ENUMX
+ BFD_RELOC_16C_ABS24_C
+ENUMX
+ BFD_RELOC_16C_IMM04
+ENUMX
+ BFD_RELOC_16C_IMM04_C
+ENUMX
+ BFD_RELOC_16C_IMM16
+ENUMX
+ BFD_RELOC_16C_IMM16_C
+ENUMX
+ BFD_RELOC_16C_IMM20
+ENUMX
+ BFD_RELOC_16C_IMM20_C
+ENUMX
+ BFD_RELOC_16C_IMM24
+ENUMX
+ BFD_RELOC_16C_IMM24_C
+ENUMX
+ BFD_RELOC_16C_IMM32
+ENUMX
+ BFD_RELOC_16C_IMM32_C
+ENUMDOC
+ NS CR16C Relocations.
+
+ENUM
+ BFD_RELOC_CR16_NUM8
+ENUMX
+ BFD_RELOC_CR16_NUM16
+ENUMX
+ BFD_RELOC_CR16_NUM32
+ENUMX
+ BFD_RELOC_CR16_NUM32a
+ENUMX
+ BFD_RELOC_CR16_REGREL0
+ENUMX
+ BFD_RELOC_CR16_REGREL4
+ENUMX
+ BFD_RELOC_CR16_REGREL4a
+ENUMX
+ BFD_RELOC_CR16_REGREL14
+ENUMX
+ BFD_RELOC_CR16_REGREL14a
+ENUMX
+ BFD_RELOC_CR16_REGREL16
+ENUMX
+ BFD_RELOC_CR16_REGREL20
+ENUMX
+ BFD_RELOC_CR16_REGREL20a
+ENUMX
+ BFD_RELOC_CR16_ABS20
+ENUMX
+ BFD_RELOC_CR16_ABS24
+ENUMX
+ BFD_RELOC_CR16_IMM4
+ENUMX
+ BFD_RELOC_CR16_IMM8
+ENUMX
+ BFD_RELOC_CR16_IMM16
+ENUMX
+ BFD_RELOC_CR16_IMM20
+ENUMX
+ BFD_RELOC_CR16_IMM24
+ENUMX
+ BFD_RELOC_CR16_IMM32
+ENUMX
+ BFD_RELOC_CR16_IMM32a
+ENUMX
+ BFD_RELOC_CR16_DISP4
+ENUMX
+ BFD_RELOC_CR16_DISP8
+ENUMX
+ BFD_RELOC_CR16_DISP16
+ENUMX
+ BFD_RELOC_CR16_DISP20
+ENUMX
+ BFD_RELOC_CR16_DISP24
+ENUMX
+ BFD_RELOC_CR16_DISP24a
+ENUMX
+ BFD_RELOC_CR16_SWITCH8
+ENUMX
+ BFD_RELOC_CR16_SWITCH16
+ENUMX
+ BFD_RELOC_CR16_SWITCH32
+ENUMX
+ BFD_RELOC_CR16_GOT_REGREL20
+ENUMX
+ BFD_RELOC_CR16_GOTC_REGREL20
+ENUMX
+ BFD_RELOC_CR16_GLOB_DAT
+ENUMDOC
+ NS CR16 Relocations.
+
+ENUM
+ BFD_RELOC_CRX_REL4
+ENUMX
+ BFD_RELOC_CRX_REL8
+ENUMX
+ BFD_RELOC_CRX_REL8_CMP
+ENUMX
+ BFD_RELOC_CRX_REL16
+ENUMX
+ BFD_RELOC_CRX_REL24
+ENUMX
+ BFD_RELOC_CRX_REL32
+ENUMX
+ BFD_RELOC_CRX_REGREL12
+ENUMX
+ BFD_RELOC_CRX_REGREL22
+ENUMX
+ BFD_RELOC_CRX_REGREL28
+ENUMX
+ BFD_RELOC_CRX_REGREL32
+ENUMX
+ BFD_RELOC_CRX_ABS16
+ENUMX
+ BFD_RELOC_CRX_ABS32
+ENUMX
+ BFD_RELOC_CRX_NUM8
+ENUMX
+ BFD_RELOC_CRX_NUM16
+ENUMX
+ BFD_RELOC_CRX_NUM32
+ENUMX
+ BFD_RELOC_CRX_IMM16
+ENUMX
+ BFD_RELOC_CRX_IMM32
+ENUMX
+ BFD_RELOC_CRX_SWITCH8
+ENUMX
+ BFD_RELOC_CRX_SWITCH16
+ENUMX
+ BFD_RELOC_CRX_SWITCH32
+ENUMDOC
+ NS CRX Relocations.
+
+ENUM
+ BFD_RELOC_CRIS_BDISP8
+ENUMX
+ BFD_RELOC_CRIS_UNSIGNED_5
+ENUMX
+ BFD_RELOC_CRIS_SIGNED_6
+ENUMX
+ BFD_RELOC_CRIS_UNSIGNED_6
+ENUMX
+ BFD_RELOC_CRIS_SIGNED_8
+ENUMX
+ BFD_RELOC_CRIS_UNSIGNED_8
+ENUMX
+ BFD_RELOC_CRIS_SIGNED_16
+ENUMX
+ BFD_RELOC_CRIS_UNSIGNED_16
+ENUMX
+ BFD_RELOC_CRIS_LAPCQ_OFFSET
+ENUMX
+ BFD_RELOC_CRIS_UNSIGNED_4
+ENUMDOC
+ These relocs are only used within the CRIS assembler. They are not
+ (at present) written to any object files.
+ENUM
+ BFD_RELOC_CRIS_COPY
+ENUMX
+ BFD_RELOC_CRIS_GLOB_DAT
+ENUMX
+ BFD_RELOC_CRIS_JUMP_SLOT
+ENUMX
+ BFD_RELOC_CRIS_RELATIVE
+ENUMDOC
+ Relocs used in ELF shared libraries for CRIS.
+ENUM
+ BFD_RELOC_CRIS_32_GOT
+ENUMDOC
+ 32-bit offset to symbol-entry within GOT.
+ENUM
+ BFD_RELOC_CRIS_16_GOT
+ENUMDOC
+ 16-bit offset to symbol-entry within GOT.
+ENUM
+ BFD_RELOC_CRIS_32_GOTPLT
+ENUMDOC
+ 32-bit offset to symbol-entry within GOT, with PLT handling.
+ENUM
+ BFD_RELOC_CRIS_16_GOTPLT
+ENUMDOC
+ 16-bit offset to symbol-entry within GOT, with PLT handling.
+ENUM
+ BFD_RELOC_CRIS_32_GOTREL
+ENUMDOC
+ 32-bit offset to symbol, relative to GOT.
+ENUM
+ BFD_RELOC_CRIS_32_PLT_GOTREL
+ENUMDOC
+ 32-bit offset to symbol with PLT entry, relative to GOT.
+ENUM
+ BFD_RELOC_CRIS_32_PLT_PCREL
+ENUMDOC
+ 32-bit offset to symbol with PLT entry, relative to this relocation.
+
+ENUM
+ BFD_RELOC_CRIS_32_GOT_GD
+ENUMX
+ BFD_RELOC_CRIS_16_GOT_GD
+ENUMX
+ BFD_RELOC_CRIS_32_GD
+ENUMX
+ BFD_RELOC_CRIS_DTP
+ENUMX
+ BFD_RELOC_CRIS_32_DTPREL
+ENUMX
+ BFD_RELOC_CRIS_16_DTPREL
+ENUMX
+ BFD_RELOC_CRIS_32_GOT_TPREL
+ENUMX
+ BFD_RELOC_CRIS_16_GOT_TPREL
+ENUMX
+ BFD_RELOC_CRIS_32_TPREL
+ENUMX
+ BFD_RELOC_CRIS_16_TPREL
+ENUMX
+ BFD_RELOC_CRIS_DTPMOD
+ENUMX
+ BFD_RELOC_CRIS_32_IE
+ENUMDOC
+ Relocs used in TLS code for CRIS.
+
+ENUM
+ BFD_RELOC_860_COPY
+ENUMX
+ BFD_RELOC_860_GLOB_DAT
+ENUMX
+ BFD_RELOC_860_JUMP_SLOT
+ENUMX
+ BFD_RELOC_860_RELATIVE
+ENUMX
+ BFD_RELOC_860_PC26
+ENUMX
+ BFD_RELOC_860_PLT26
+ENUMX
+ BFD_RELOC_860_PC16
+ENUMX
+ BFD_RELOC_860_LOW0
+ENUMX
+ BFD_RELOC_860_SPLIT0
+ENUMX
+ BFD_RELOC_860_LOW1
+ENUMX
+ BFD_RELOC_860_SPLIT1
+ENUMX
+ BFD_RELOC_860_LOW2
+ENUMX
+ BFD_RELOC_860_SPLIT2
+ENUMX
+ BFD_RELOC_860_LOW3
+ENUMX
+ BFD_RELOC_860_LOGOT0
+ENUMX
+ BFD_RELOC_860_SPGOT0
+ENUMX
+ BFD_RELOC_860_LOGOT1
+ENUMX
+ BFD_RELOC_860_SPGOT1
+ENUMX
+ BFD_RELOC_860_LOGOTOFF0
+ENUMX
+ BFD_RELOC_860_SPGOTOFF0
+ENUMX
+ BFD_RELOC_860_LOGOTOFF1
+ENUMX
+ BFD_RELOC_860_SPGOTOFF1
+ENUMX
+ BFD_RELOC_860_LOGOTOFF2
+ENUMX
+ BFD_RELOC_860_LOGOTOFF3
+ENUMX
+ BFD_RELOC_860_LOPC
+ENUMX
+ BFD_RELOC_860_HIGHADJ
+ENUMX
+ BFD_RELOC_860_HAGOT
+ENUMX
+ BFD_RELOC_860_HAGOTOFF
+ENUMX
+ BFD_RELOC_860_HAPC
+ENUMX
+ BFD_RELOC_860_HIGH
+ENUMX
+ BFD_RELOC_860_HIGOT
+ENUMX
+ BFD_RELOC_860_HIGOTOFF
+ENUMDOC
+ Intel i860 Relocations.
+
+ENUM
+ BFD_RELOC_OR1K_REL_26
+ENUMX
+ BFD_RELOC_OR1K_GOTPC_HI16
+ENUMX
+ BFD_RELOC_OR1K_GOTPC_LO16
+ENUMX
+ BFD_RELOC_OR1K_GOT16
+ENUMX
+ BFD_RELOC_OR1K_PLT26
+ENUMX
+ BFD_RELOC_OR1K_GOTOFF_HI16
+ENUMX
+ BFD_RELOC_OR1K_GOTOFF_LO16
+ENUMX
+ BFD_RELOC_OR1K_COPY
+ENUMX
+ BFD_RELOC_OR1K_GLOB_DAT
+ENUMX
+ BFD_RELOC_OR1K_JMP_SLOT
+ENUMX
+ BFD_RELOC_OR1K_RELATIVE
+ENUMX
+ BFD_RELOC_OR1K_TLS_GD_HI16
+ENUMX
+ BFD_RELOC_OR1K_TLS_GD_LO16
+ENUMX
+ BFD_RELOC_OR1K_TLS_LDM_HI16
+ENUMX
+ BFD_RELOC_OR1K_TLS_LDM_LO16
+ENUMX
+ BFD_RELOC_OR1K_TLS_LDO_HI16
+ENUMX
+ BFD_RELOC_OR1K_TLS_LDO_LO16
+ENUMX
+ BFD_RELOC_OR1K_TLS_IE_HI16
+ENUMX
+ BFD_RELOC_OR1K_TLS_IE_LO16
+ENUMX
+ BFD_RELOC_OR1K_TLS_LE_HI16
+ENUMX
+ BFD_RELOC_OR1K_TLS_LE_LO16
+ENUMX
+ BFD_RELOC_OR1K_TLS_TPOFF
+ENUMX
+ BFD_RELOC_OR1K_TLS_DTPOFF
+ENUMX
+ BFD_RELOC_OR1K_TLS_DTPMOD
+ENUMDOC
+ OpenRISC 1000 Relocations.
+
+ENUM
+ BFD_RELOC_H8_DIR16A8
+ENUMX
+ BFD_RELOC_H8_DIR16R8
+ENUMX
+ BFD_RELOC_H8_DIR24A8
+ENUMX
+ BFD_RELOC_H8_DIR24R8
+ENUMX
+ BFD_RELOC_H8_DIR32A16
+ENUMX
+ BFD_RELOC_H8_DISP32A16
+ENUMDOC
+ H8 elf Relocations.
+
+ENUM
+ BFD_RELOC_XSTORMY16_REL_12
+ENUMX
+ BFD_RELOC_XSTORMY16_12
+ENUMX
+ BFD_RELOC_XSTORMY16_24
+ENUMX
+ BFD_RELOC_XSTORMY16_FPTR16
+ENUMDOC
+ Sony Xstormy16 Relocations.
+
+ENUM
+ BFD_RELOC_RELC
+ENUMDOC
+ Self-describing complex relocations.
+COMMENT
+
+ENUM
+ BFD_RELOC_XC16X_PAG
+ENUMX
+ BFD_RELOC_XC16X_POF
+ENUMX
+ BFD_RELOC_XC16X_SEG
+ENUMX
+ BFD_RELOC_XC16X_SOF
+ENUMDOC
+ Infineon Relocations.
+
+ENUM
+ BFD_RELOC_VAX_GLOB_DAT
+ENUMX
+ BFD_RELOC_VAX_JMP_SLOT
+ENUMX
+ BFD_RELOC_VAX_RELATIVE
+ENUMDOC
+ Relocations used by VAX ELF.
+
+ENUM
+ BFD_RELOC_MT_PC16
+ENUMDOC
+ Morpho MT - 16 bit immediate relocation.
+ENUM
+ BFD_RELOC_MT_HI16
+ENUMDOC
+ Morpho MT - Hi 16 bits of an address.
+ENUM
+ BFD_RELOC_MT_LO16
+ENUMDOC
+ Morpho MT - Low 16 bits of an address.
+ENUM
+ BFD_RELOC_MT_GNU_VTINHERIT
+ENUMDOC
+ Morpho MT - Used to tell the linker which vtable entries are used.
+ENUM
+ BFD_RELOC_MT_GNU_VTENTRY
+ENUMDOC
+ Morpho MT - Used to tell the linker which vtable entries are used.
+ENUM
+ BFD_RELOC_MT_PCINSN8
+ENUMDOC
+ Morpho MT - 8 bit immediate relocation.
+
+ENUM
+ BFD_RELOC_MSP430_10_PCREL
+ENUMX
+ BFD_RELOC_MSP430_16_PCREL
+ENUMX
+ BFD_RELOC_MSP430_16
+ENUMX
+ BFD_RELOC_MSP430_16_PCREL_BYTE
+ENUMX
+ BFD_RELOC_MSP430_16_BYTE
+ENUMX
+ BFD_RELOC_MSP430_2X_PCREL
+ENUMX
+ BFD_RELOC_MSP430_RL_PCREL
+ENUMX
+ BFD_RELOC_MSP430_ABS8
+ENUMX
+ BFD_RELOC_MSP430X_PCR20_EXT_SRC
+ENUMX
+ BFD_RELOC_MSP430X_PCR20_EXT_DST
+ENUMX
+ BFD_RELOC_MSP430X_PCR20_EXT_ODST
+ENUMX
+ BFD_RELOC_MSP430X_ABS20_EXT_SRC
+ENUMX
+ BFD_RELOC_MSP430X_ABS20_EXT_DST
+ENUMX
+ BFD_RELOC_MSP430X_ABS20_EXT_ODST
+ENUMX
+ BFD_RELOC_MSP430X_ABS20_ADR_SRC
+ENUMX
+ BFD_RELOC_MSP430X_ABS20_ADR_DST
+ENUMX
+ BFD_RELOC_MSP430X_PCR16
+ENUMX
+ BFD_RELOC_MSP430X_PCR20_CALL
+ENUMX
+ BFD_RELOC_MSP430X_ABS16
+ENUMX
+ BFD_RELOC_MSP430_ABS_HI16
+ENUMX
+ BFD_RELOC_MSP430_PREL31
+ENUMX
+ BFD_RELOC_MSP430_SYM_DIFF
+ENUMDOC
+ msp430 specific relocation codes
+
+ENUM
+ BFD_RELOC_NIOS2_S16
+ENUMX
+ BFD_RELOC_NIOS2_U16
+ENUMX
+ BFD_RELOC_NIOS2_CALL26
+ENUMX
+ BFD_RELOC_NIOS2_IMM5
+ENUMX
+ BFD_RELOC_NIOS2_CACHE_OPX
+ENUMX
+ BFD_RELOC_NIOS2_IMM6
+ENUMX
+ BFD_RELOC_NIOS2_IMM8
+ENUMX
+ BFD_RELOC_NIOS2_HI16
+ENUMX
+ BFD_RELOC_NIOS2_LO16
+ENUMX
+ BFD_RELOC_NIOS2_HIADJ16
+ENUMX
+ BFD_RELOC_NIOS2_GPREL
+ENUMX
+ BFD_RELOC_NIOS2_UJMP
+ENUMX
+ BFD_RELOC_NIOS2_CJMP
+ENUMX
+ BFD_RELOC_NIOS2_CALLR
+ENUMX
+ BFD_RELOC_NIOS2_ALIGN
+ENUMX
+ BFD_RELOC_NIOS2_GOT16
+ENUMX
+ BFD_RELOC_NIOS2_CALL16
+ENUMX
+ BFD_RELOC_NIOS2_GOTOFF_LO
+ENUMX
+ BFD_RELOC_NIOS2_GOTOFF_HA
+ENUMX
+ BFD_RELOC_NIOS2_PCREL_LO
+ENUMX
+ BFD_RELOC_NIOS2_PCREL_HA
+ENUMX
+ BFD_RELOC_NIOS2_TLS_GD16
+ENUMX
+ BFD_RELOC_NIOS2_TLS_LDM16
+ENUMX
+ BFD_RELOC_NIOS2_TLS_LDO16
+ENUMX
+ BFD_RELOC_NIOS2_TLS_IE16
+ENUMX
+ BFD_RELOC_NIOS2_TLS_LE16
+ENUMX
+ BFD_RELOC_NIOS2_TLS_DTPMOD
+ENUMX
+ BFD_RELOC_NIOS2_TLS_DTPREL
+ENUMX
+ BFD_RELOC_NIOS2_TLS_TPREL
+ENUMX
+ BFD_RELOC_NIOS2_COPY
+ENUMX
+ BFD_RELOC_NIOS2_GLOB_DAT
+ENUMX
+ BFD_RELOC_NIOS2_JUMP_SLOT
+ENUMX
+ BFD_RELOC_NIOS2_RELATIVE
+ENUMX
+ BFD_RELOC_NIOS2_GOTOFF
+ENUMX
+ BFD_RELOC_NIOS2_CALL26_NOAT
+ENUMX
+ BFD_RELOC_NIOS2_GOT_LO
+ENUMX
+ BFD_RELOC_NIOS2_GOT_HA
+ENUMX
+ BFD_RELOC_NIOS2_CALL_LO
+ENUMX
+ BFD_RELOC_NIOS2_CALL_HA
+ENUMDOC
+ Relocations used by the Altera Nios II core.
+
+ENUM
+ BFD_RELOC_IQ2000_OFFSET_16
+ENUMX
+ BFD_RELOC_IQ2000_OFFSET_21
+ENUMX
+ BFD_RELOC_IQ2000_UHI16
+ENUMDOC
+ IQ2000 Relocations.
+
+ENUM
+ BFD_RELOC_XTENSA_RTLD
+ENUMDOC
+ Special Xtensa relocation used only by PLT entries in ELF shared
+ objects to indicate that the runtime linker should set the value
+ to one of its own internal functions or data structures.
+ENUM
+ BFD_RELOC_XTENSA_GLOB_DAT
+ENUMX
+ BFD_RELOC_XTENSA_JMP_SLOT
+ENUMX
+ BFD_RELOC_XTENSA_RELATIVE
+ENUMDOC
+ Xtensa relocations for ELF shared objects.
+ENUM
+ BFD_RELOC_XTENSA_PLT
+ENUMDOC
+ Xtensa relocation used in ELF object files for symbols that may require
+ PLT entries. Otherwise, this is just a generic 32-bit relocation.
+ENUM
+ BFD_RELOC_XTENSA_DIFF8
+ENUMX
+ BFD_RELOC_XTENSA_DIFF16
+ENUMX
+ BFD_RELOC_XTENSA_DIFF32
+ENUMDOC
+ Xtensa relocations to mark the difference of two local symbols.
+ These are only needed to support linker relaxation and can be ignored
+ when not relaxing. The field is set to the value of the difference
+ assuming no relaxation. The relocation encodes the position of the
+ first symbol so the linker can determine whether to adjust the field
+ value.
+ENUM
+ BFD_RELOC_XTENSA_SLOT0_OP
+ENUMX
+ BFD_RELOC_XTENSA_SLOT1_OP
+ENUMX
+ BFD_RELOC_XTENSA_SLOT2_OP
+ENUMX
+ BFD_RELOC_XTENSA_SLOT3_OP
+ENUMX
+ BFD_RELOC_XTENSA_SLOT4_OP
+ENUMX
+ BFD_RELOC_XTENSA_SLOT5_OP
+ENUMX
+ BFD_RELOC_XTENSA_SLOT6_OP
+ENUMX
+ BFD_RELOC_XTENSA_SLOT7_OP
+ENUMX
+ BFD_RELOC_XTENSA_SLOT8_OP
+ENUMX
+ BFD_RELOC_XTENSA_SLOT9_OP
+ENUMX
+ BFD_RELOC_XTENSA_SLOT10_OP
+ENUMX
+ BFD_RELOC_XTENSA_SLOT11_OP
+ENUMX
+ BFD_RELOC_XTENSA_SLOT12_OP
+ENUMX
+ BFD_RELOC_XTENSA_SLOT13_OP
+ENUMX
+ BFD_RELOC_XTENSA_SLOT14_OP
+ENUMDOC
+ Generic Xtensa relocations for instruction operands. Only the slot
+ number is encoded in the relocation. The relocation applies to the
+ last PC-relative immediate operand, or if there are no PC-relative
+ immediates, to the last immediate operand.
+ENUM
+ BFD_RELOC_XTENSA_SLOT0_ALT
+ENUMX
+ BFD_RELOC_XTENSA_SLOT1_ALT
+ENUMX
+ BFD_RELOC_XTENSA_SLOT2_ALT
+ENUMX
+ BFD_RELOC_XTENSA_SLOT3_ALT
+ENUMX
+ BFD_RELOC_XTENSA_SLOT4_ALT
+ENUMX
+ BFD_RELOC_XTENSA_SLOT5_ALT
+ENUMX
+ BFD_RELOC_XTENSA_SLOT6_ALT
+ENUMX
+ BFD_RELOC_XTENSA_SLOT7_ALT
+ENUMX
+ BFD_RELOC_XTENSA_SLOT8_ALT
+ENUMX
+ BFD_RELOC_XTENSA_SLOT9_ALT
+ENUMX
+ BFD_RELOC_XTENSA_SLOT10_ALT
+ENUMX
+ BFD_RELOC_XTENSA_SLOT11_ALT
+ENUMX
+ BFD_RELOC_XTENSA_SLOT12_ALT
+ENUMX
+ BFD_RELOC_XTENSA_SLOT13_ALT
+ENUMX
+ BFD_RELOC_XTENSA_SLOT14_ALT
+ENUMDOC
+ Alternate Xtensa relocations. Only the slot is encoded in the
+ relocation. The meaning of these relocations is opcode-specific.
+ENUM
+ BFD_RELOC_XTENSA_OP0
+ENUMX
+ BFD_RELOC_XTENSA_OP1
+ENUMX
+ BFD_RELOC_XTENSA_OP2
+ENUMDOC
+ Xtensa relocations for backward compatibility. These have all been
+ replaced by BFD_RELOC_XTENSA_SLOT0_OP.
+ENUM
+ BFD_RELOC_XTENSA_ASM_EXPAND
+ENUMDOC
+ Xtensa relocation to mark that the assembler expanded the
+ instructions from an original target. The expansion size is
+ encoded in the reloc size.
+ENUM
+ BFD_RELOC_XTENSA_ASM_SIMPLIFY
+ENUMDOC
+ Xtensa relocation to mark that the linker should simplify
+ assembler-expanded instructions. This is commonly used
+ internally by the linker after analysis of a
+ BFD_RELOC_XTENSA_ASM_EXPAND.
+ENUM
+ BFD_RELOC_XTENSA_TLSDESC_FN
+ENUMX
+ BFD_RELOC_XTENSA_TLSDESC_ARG
+ENUMX
+ BFD_RELOC_XTENSA_TLS_DTPOFF
+ENUMX
+ BFD_RELOC_XTENSA_TLS_TPOFF
+ENUMX
+ BFD_RELOC_XTENSA_TLS_FUNC
+ENUMX
+ BFD_RELOC_XTENSA_TLS_ARG
+ENUMX
+ BFD_RELOC_XTENSA_TLS_CALL
+ENUMDOC
+ Xtensa TLS relocations.
+
+ENUM
+ BFD_RELOC_Z80_DISP8
+ENUMDOC
+ 8 bit signed offset in (ix+d) or (iy+d).
+
+ENUM
+ BFD_RELOC_Z8K_DISP7
+ENUMDOC
+ DJNZ offset.
+ENUM
+ BFD_RELOC_Z8K_CALLR
+ENUMDOC
+ CALR offset.
+ENUM
+ BFD_RELOC_Z8K_IMM4L
+ENUMDOC
+ 4 bit value.
+
+ENUM
+ BFD_RELOC_LM32_CALL
+ENUMX
+ BFD_RELOC_LM32_BRANCH
+ENUMX
+ BFD_RELOC_LM32_16_GOT
+ENUMX
+ BFD_RELOC_LM32_GOTOFF_HI16
+ENUMX
+ BFD_RELOC_LM32_GOTOFF_LO16
+ENUMX
+ BFD_RELOC_LM32_COPY
+ENUMX
+ BFD_RELOC_LM32_GLOB_DAT
+ENUMX
+ BFD_RELOC_LM32_JMP_SLOT
+ENUMX
+ BFD_RELOC_LM32_RELATIVE
+ENUMDOC
+ Lattice Mico32 relocations.
+
+ENUM
+ BFD_RELOC_MACH_O_SECTDIFF
+ENUMDOC
+ Difference between two section addreses. Must be followed by a
+ BFD_RELOC_MACH_O_PAIR.
+ENUM
+ BFD_RELOC_MACH_O_LOCAL_SECTDIFF
+ENUMDOC
+ Like BFD_RELOC_MACH_O_SECTDIFF but with a local symbol.
+ENUM
+ BFD_RELOC_MACH_O_PAIR
+ENUMDOC
+ Pair of relocation. Contains the first symbol.
+
+ENUM
+ BFD_RELOC_MACH_O_X86_64_BRANCH32
+ENUMX
+ BFD_RELOC_MACH_O_X86_64_BRANCH8
+ENUMDOC
+ PCREL relocations. They are marked as branch to create PLT entry if
+ required.
+ENUM
+ BFD_RELOC_MACH_O_X86_64_GOT
+ENUMDOC
+ Used when referencing a GOT entry.
+ENUM
+ BFD_RELOC_MACH_O_X86_64_GOT_LOAD
+ENUMDOC
+ Used when loading a GOT entry with movq. It is specially marked so that
+ the linker could optimize the movq to a leaq if possible.
+ENUM
+ BFD_RELOC_MACH_O_X86_64_SUBTRACTOR32
+ENUMDOC
+ Symbol will be substracted. Must be followed by a BFD_RELOC_64.
+ENUM
+ BFD_RELOC_MACH_O_X86_64_SUBTRACTOR64
+ENUMDOC
+ Symbol will be substracted. Must be followed by a BFD_RELOC_64.
+ENUM
+ BFD_RELOC_MACH_O_X86_64_PCREL32_1
+ENUMDOC
+ Same as BFD_RELOC_32_PCREL but with an implicit -1 addend.
+ENUM
+ BFD_RELOC_MACH_O_X86_64_PCREL32_2
+ENUMDOC
+ Same as BFD_RELOC_32_PCREL but with an implicit -2 addend.
+ENUM
+ BFD_RELOC_MACH_O_X86_64_PCREL32_4
+ENUMDOC
+ Same as BFD_RELOC_32_PCREL but with an implicit -4 addend.
+
+ENUM
+ BFD_RELOC_MICROBLAZE_32_LO
+ENUMDOC
+ This is a 32 bit reloc for the microblaze that stores the
+ low 16 bits of a value
+ENUM
+ BFD_RELOC_MICROBLAZE_32_LO_PCREL
+ENUMDOC
+ This is a 32 bit pc-relative reloc for the microblaze that
+ stores the low 16 bits of a value
+ENUM
+ BFD_RELOC_MICROBLAZE_32_ROSDA
+ENUMDOC
+ This is a 32 bit reloc for the microblaze that stores a
+ value relative to the read-only small data area anchor
+ENUM
+ BFD_RELOC_MICROBLAZE_32_RWSDA
+ENUMDOC
+ This is a 32 bit reloc for the microblaze that stores a
+ value relative to the read-write small data area anchor
+ENUM
+ BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM
+ENUMDOC
+ This is a 32 bit reloc for the microblaze to handle
+ expressions of the form "Symbol Op Symbol"
+ENUM
+ BFD_RELOC_MICROBLAZE_64_NONE
+ENUMDOC
+ This is a 64 bit reloc that stores the 32 bit pc relative
+ value in two words (with an imm instruction). No relocation is
+ done here - only used for relaxing
+ENUM
+ BFD_RELOC_MICROBLAZE_64_GOTPC
+ENUMDOC
+ This is a 64 bit reloc that stores the 32 bit pc relative
+ value in two words (with an imm instruction). The relocation is
+ PC-relative GOT offset
+ENUM
+ BFD_RELOC_MICROBLAZE_64_GOT
+ENUMDOC
+ This is a 64 bit reloc that stores the 32 bit pc relative
+ value in two words (with an imm instruction). The relocation is
+ GOT offset
+ENUM
+ BFD_RELOC_MICROBLAZE_64_PLT
+ENUMDOC
+ This is a 64 bit reloc that stores the 32 bit pc relative
+ value in two words (with an imm instruction). The relocation is
+ PC-relative offset into PLT
+ENUM
+ BFD_RELOC_MICROBLAZE_64_GOTOFF
+ENUMDOC
+ This is a 64 bit reloc that stores the 32 bit GOT relative
+ value in two words (with an imm instruction). The relocation is
+ relative offset from _GLOBAL_OFFSET_TABLE_
+ENUM
+ BFD_RELOC_MICROBLAZE_32_GOTOFF
+ENUMDOC
+ This is a 32 bit reloc that stores the 32 bit GOT relative
+ value in a word. The relocation is relative offset from
+ _GLOBAL_OFFSET_TABLE_
+ENUM
+ BFD_RELOC_MICROBLAZE_COPY
+ENUMDOC
+ This is used to tell the dynamic linker to copy the value out of
+ the dynamic object into the runtime process image.
+ENUM
+ BFD_RELOC_MICROBLAZE_64_TLS
+ENUMDOC
+ Unused Reloc
+ENUM
+ BFD_RELOC_MICROBLAZE_64_TLSGD
+ENUMDOC
+ This is a 64 bit reloc that stores the 32 bit GOT relative value
+ of the GOT TLS GD info entry in two words (with an imm instruction). The
+ relocation is GOT offset.
+ENUM
+ BFD_RELOC_MICROBLAZE_64_TLSLD
+ENUMDOC
+ This is a 64 bit reloc that stores the 32 bit GOT relative value
+ of the GOT TLS LD info entry in two words (with an imm instruction). The
+ relocation is GOT offset.
+ENUM
+ BFD_RELOC_MICROBLAZE_32_TLSDTPMOD
+ENUMDOC
+ This is a 32 bit reloc that stores the Module ID to GOT(n).
+ENUM
+ BFD_RELOC_MICROBLAZE_32_TLSDTPREL
+ENUMDOC
+ This is a 32 bit reloc that stores TLS offset to GOT(n+1).
+ENUM
+ BFD_RELOC_MICROBLAZE_64_TLSDTPREL
+ENUMDOC
+ This is a 32 bit reloc for storing TLS offset to two words (uses imm
+ instruction)
+ENUM
+ BFD_RELOC_MICROBLAZE_64_TLSGOTTPREL
+ENUMDOC
+ This is a 64 bit reloc that stores 32-bit thread pointer relative offset
+ to two words (uses imm instruction).
+ENUM
+ BFD_RELOC_MICROBLAZE_64_TLSTPREL
+ENUMDOC
+ This is a 64 bit reloc that stores 32-bit thread pointer relative offset
+ to two words (uses imm instruction).
+
+ENUM
+ BFD_RELOC_AARCH64_RELOC_START
+ENUMDOC
+ AArch64 pseudo relocation code to mark the start of the AArch64
+ relocation enumerators. N.B. the order of the enumerators is
+ important as several tables in the AArch64 bfd backend are indexed
+ by these enumerators; make sure they are all synced.
+ENUM
+ BFD_RELOC_AARCH64_NONE
+ENUMDOC
+ AArch64 null relocation code.
+ENUM
+ BFD_RELOC_AARCH64_64
+ENUMX
+ BFD_RELOC_AARCH64_32
+ENUMX
+ BFD_RELOC_AARCH64_16
+ENUMDOC
+ Basic absolute relocations of N bits. These are equivalent to
+BFD_RELOC_N and they were added to assist the indexing of the howto
+table.
+ENUM
+ BFD_RELOC_AARCH64_64_PCREL
+ENUMX
+ BFD_RELOC_AARCH64_32_PCREL
+ENUMX
+ BFD_RELOC_AARCH64_16_PCREL
+ENUMDOC
+ PC-relative relocations. These are equivalent to BFD_RELOC_N_PCREL
+and they were added to assist the indexing of the howto table.
+ENUM
+ BFD_RELOC_AARCH64_MOVW_G0
+ENUMDOC
+ AArch64 MOV[NZK] instruction with most significant bits 0 to 15
+ of an unsigned address/value.
+ENUM
+ BFD_RELOC_AARCH64_MOVW_G0_NC
+ENUMDOC
+ AArch64 MOV[NZK] instruction with less significant bits 0 to 15 of
+ an address/value. No overflow checking.
+ENUM
+ BFD_RELOC_AARCH64_MOVW_G1
+ENUMDOC
+ AArch64 MOV[NZK] instruction with most significant bits 16 to 31
+ of an unsigned address/value.
+ENUM
+ BFD_RELOC_AARCH64_MOVW_G1_NC
+ENUMDOC
+ AArch64 MOV[NZK] instruction with less significant bits 16 to 31
+ of an address/value. No overflow checking.
+ENUM
+ BFD_RELOC_AARCH64_MOVW_G2
+ENUMDOC
+ AArch64 MOV[NZK] instruction with most significant bits 32 to 47
+ of an unsigned address/value.
+ENUM
+ BFD_RELOC_AARCH64_MOVW_G2_NC
+ENUMDOC
+ AArch64 MOV[NZK] instruction with less significant bits 32 to 47
+ of an address/value. No overflow checking.
+ENUM
+ BFD_RELOC_AARCH64_MOVW_G3
+ENUMDOC
+ AArch64 MOV[NZK] instruction with most signficant bits 48 to 64
+ of a signed or unsigned address/value.
+ENUM
+ BFD_RELOC_AARCH64_MOVW_G0_S
+ENUMDOC
+ AArch64 MOV[NZ] instruction with most significant bits 0 to 15
+ of a signed value. Changes instruction to MOVZ or MOVN depending on the
+ value's sign.
+ENUM
+ BFD_RELOC_AARCH64_MOVW_G1_S
+ENUMDOC
+ AArch64 MOV[NZ] instruction with most significant bits 16 to 31
+ of a signed value. Changes instruction to MOVZ or MOVN depending on the
+ value's sign.
+ENUM
+ BFD_RELOC_AARCH64_MOVW_G2_S
+ENUMDOC
+ AArch64 MOV[NZ] instruction with most significant bits 32 to 47
+ of a signed value. Changes instruction to MOVZ or MOVN depending on the
+ value's sign.
+ENUM
+ BFD_RELOC_AARCH64_LD_LO19_PCREL
+ENUMDOC
+ AArch64 Load Literal instruction, holding a 19 bit pc-relative word
+ offset. The lowest two bits must be zero and are not stored in the
+ instruction, giving a 21 bit signed byte offset.
+ENUM
+ BFD_RELOC_AARCH64_ADR_LO21_PCREL
+ENUMDOC
+ AArch64 ADR instruction, holding a simple 21 bit pc-relative byte offset.
+ENUM
+ BFD_RELOC_AARCH64_ADR_HI21_PCREL
+ENUMDOC
+ AArch64 ADRP instruction, with bits 12 to 32 of a pc-relative page
+ offset, giving a 4KB aligned page base address.
+ENUM
+ BFD_RELOC_AARCH64_ADR_HI21_NC_PCREL
+ENUMDOC
+ AArch64 ADRP instruction, with bits 12 to 32 of a pc-relative page
+ offset, giving a 4KB aligned page base address, but with no overflow
+ checking.
+ENUM
+ BFD_RELOC_AARCH64_ADD_LO12
+ENUMDOC
+ AArch64 ADD immediate instruction, holding bits 0 to 11 of the address.
+ Used in conjunction with BFD_RELOC_AARCH64_ADR_HI21_PCREL.
+ENUM
+ BFD_RELOC_AARCH64_LDST8_LO12
+ENUMDOC
+ AArch64 8-bit load/store instruction, holding bits 0 to 11 of the
+ address. Used in conjunction with BFD_RELOC_AARCH64_ADR_HI21_PCREL.
+ENUM
+ BFD_RELOC_AARCH64_TSTBR14
+ENUMDOC
+ AArch64 14 bit pc-relative test bit and branch.
+ The lowest two bits must be zero and are not stored in the instruction,
+ giving a 16 bit signed byte offset.
+ENUM
+ BFD_RELOC_AARCH64_BRANCH19
+ENUMDOC
+ AArch64 19 bit pc-relative conditional branch and compare & branch.
+ The lowest two bits must be zero and are not stored in the instruction,
+ giving a 21 bit signed byte offset.
+ENUM
+ BFD_RELOC_AARCH64_JUMP26
+ENUMDOC
+ AArch64 26 bit pc-relative unconditional branch.
+ The lowest two bits must be zero and are not stored in the instruction,
+ giving a 28 bit signed byte offset.
+ENUM
+ BFD_RELOC_AARCH64_CALL26
+ENUMDOC
+ AArch64 26 bit pc-relative unconditional branch and link.
+ The lowest two bits must be zero and are not stored in the instruction,
+ giving a 28 bit signed byte offset.
+ENUM
+ BFD_RELOC_AARCH64_LDST16_LO12
+ENUMDOC
+ AArch64 16-bit load/store instruction, holding bits 0 to 11 of the
+ address. Used in conjunction with BFD_RELOC_AARCH64_ADR_HI21_PCREL.
+ENUM
+ BFD_RELOC_AARCH64_LDST32_LO12
+ENUMDOC
+ AArch64 32-bit load/store instruction, holding bits 0 to 11 of the
+ address. Used in conjunction with BFD_RELOC_AARCH64_ADR_HI21_PCREL.
+ENUM
+ BFD_RELOC_AARCH64_LDST64_LO12
+ENUMDOC
+ AArch64 64-bit load/store instruction, holding bits 0 to 11 of the
+ address. Used in conjunction with BFD_RELOC_AARCH64_ADR_HI21_PCREL.
+ENUM
+ BFD_RELOC_AARCH64_LDST128_LO12
+ENUMDOC
+ AArch64 128-bit load/store instruction, holding bits 0 to 11 of the
+ address. Used in conjunction with BFD_RELOC_AARCH64_ADR_HI21_PCREL.
+ENUM
+ BFD_RELOC_AARCH64_GOT_LD_PREL19
+ENUMDOC
+ AArch64 Load Literal instruction, holding a 19 bit PC relative word
+ offset of the global offset table entry for a symbol. The lowest two
+ bits must be zero and are not stored in the instruction, giving a 21
+ bit signed byte offset. This relocation type requires signed overflow
+ checking.
+ENUM
+ BFD_RELOC_AARCH64_ADR_GOT_PAGE
+ENUMDOC
+ Get to the page base of the global offset table entry for a symbol as
+ part of an ADRP instruction using a 21 bit PC relative value.Used in
+ conjunction with BFD_RELOC_AARCH64_LD64_GOT_LO12_NC.
+ENUM
+ BFD_RELOC_AARCH64_LD64_GOT_LO12_NC
+ENUMDOC
+ Unsigned 12 bit byte offset for 64 bit load/store from the page of
+ the GOT entry for this symbol. Used in conjunction with
+ BFD_RELOC_AARCH64_ADR_GOTPAGE. Valid in LP64 ABI only.
+ENUM
+ BFD_RELOC_AARCH64_LD32_GOT_LO12_NC
+ENUMDOC
+ Unsigned 12 bit byte offset for 32 bit load/store from the page of
+ the GOT entry for this symbol. Used in conjunction with
+ BFD_RELOC_AARCH64_ADR_GOTPAGE. Valid in ILP32 ABI only.
+ENUM
+ BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21
+ENUMDOC
+ Get to the page base of the global offset table entry for a symbols
+ tls_index structure as part of an adrp instruction using a 21 bit PC
+ relative value. Used in conjunction with
+ BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC.
+ENUM
+ BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC
+ENUMDOC
+ Unsigned 12 bit byte offset to global offset table entry for a symbols
+ tls_index structure. Used in conjunction with
+ BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21.
+ENUM
+ BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G1
+ENUMDOC
+ AArch64 TLS INITIAL EXEC relocation.
+ENUM
+ BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC
+ENUMDOC
+ AArch64 TLS INITIAL EXEC relocation.
+ENUM
+ BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21
+ENUMDOC
+ AArch64 TLS INITIAL EXEC relocation.
+ENUM
+ BFD_RELOC_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC
+ENUMDOC
+ AArch64 TLS INITIAL EXEC relocation.
+ENUM
+ BFD_RELOC_AARCH64_TLSIE_LD32_GOTTPREL_LO12_NC
+ENUMDOC
+ AArch64 TLS INITIAL EXEC relocation.
+ENUM
+ BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19
+ENUMDOC
+ AArch64 TLS INITIAL EXEC relocation.
+ENUM
+ BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G2
+ENUMDOC
+ AArch64 TLS LOCAL EXEC relocation.
+ENUM
+ BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1
+ENUMDOC
+ AArch64 TLS LOCAL EXEC relocation.
+ENUM
+ BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1_NC
+ENUMDOC
+ AArch64 TLS LOCAL EXEC relocation.
+ENUM
+ BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0
+ENUMDOC
+ AArch64 TLS LOCAL EXEC relocation.
+ENUM
+ BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC
+ENUMDOC
+ AArch64 TLS LOCAL EXEC relocation.
+ENUM
+ BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_HI12
+ENUMDOC
+ AArch64 TLS LOCAL EXEC relocation.
+ENUM
+ BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12
+ENUMDOC
+ AArch64 TLS LOCAL EXEC relocation.
+ENUM
+ BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12_NC
+ENUMDOC
+ AArch64 TLS LOCAL EXEC relocation.
+ENUM
+ BFD_RELOC_AARCH64_TLSDESC_LD_PREL19
+ENUMDOC
+ AArch64 TLS DESC relocation.
+ENUM
+ BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21
+ENUMDOC
+ AArch64 TLS DESC relocation.
+ENUM
+ BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21
+ENUMDOC
+ AArch64 TLS DESC relocation.
+ENUM
+ BFD_RELOC_AARCH64_TLSDESC_LD64_LO12_NC
+ENUMDOC
+ AArch64 TLS DESC relocation.
+ENUM
+ BFD_RELOC_AARCH64_TLSDESC_LD32_LO12_NC
+ENUMDOC
+ AArch64 TLS DESC relocation.
+ENUM
+ BFD_RELOC_AARCH64_TLSDESC_ADD_LO12_NC
+ENUMDOC
+ AArch64 TLS DESC relocation.
+ENUM
+ BFD_RELOC_AARCH64_TLSDESC_OFF_G1
+ENUMDOC
+ AArch64 TLS DESC relocation.
+ENUM
+ BFD_RELOC_AARCH64_TLSDESC_OFF_G0_NC
+ENUMDOC
+ AArch64 TLS DESC relocation.
+ENUM
+ BFD_RELOC_AARCH64_TLSDESC_LDR
+ENUMDOC
+ AArch64 TLS DESC relocation.
+ENUM
+ BFD_RELOC_AARCH64_TLSDESC_ADD
+ENUMDOC
+ AArch64 TLS DESC relocation.
+ENUM
+ BFD_RELOC_AARCH64_TLSDESC_CALL
+ENUMDOC
+ AArch64 TLS DESC relocation.
+ENUM
+ BFD_RELOC_AARCH64_COPY
+ENUMDOC
+ AArch64 TLS relocation.
+ENUM
+ BFD_RELOC_AARCH64_GLOB_DAT
+ENUMDOC
+ AArch64 TLS relocation.
+ENUM
+ BFD_RELOC_AARCH64_JUMP_SLOT
+ENUMDOC
+ AArch64 TLS relocation.
+ENUM
+ BFD_RELOC_AARCH64_RELATIVE
+ENUMDOC
+ AArch64 TLS relocation.
+ENUM
+ BFD_RELOC_AARCH64_TLS_DTPMOD
+ENUMDOC
+ AArch64 TLS relocation.
+ENUM
+ BFD_RELOC_AARCH64_TLS_DTPREL
+ENUMDOC
+ AArch64 TLS relocation.
+ENUM
+ BFD_RELOC_AARCH64_TLS_TPREL
+ENUMDOC
+ AArch64 TLS relocation.
+ENUM
+ BFD_RELOC_AARCH64_TLSDESC
+ENUMDOC
+ AArch64 TLS relocation.
+ENUM
+ BFD_RELOC_AARCH64_IRELATIVE
+ENUMDOC
+ AArch64 support for STT_GNU_IFUNC.
+ENUM
+ BFD_RELOC_AARCH64_RELOC_END
+ENUMDOC
+ AArch64 pseudo relocation code to mark the end of the AArch64
+ relocation enumerators that have direct mapping to ELF reloc codes.
+ There are a few more enumerators after this one; those are mainly
+ used by the AArch64 assembler for the internal fixup or to select
+ one of the above enumerators.
+ENUM
+ BFD_RELOC_AARCH64_GAS_INTERNAL_FIXUP
+ENUMDOC
+ AArch64 pseudo relocation code to be used internally by the AArch64
+ assembler and not (currently) written to any object files.
+ENUM
+ BFD_RELOC_AARCH64_LDST_LO12
+ENUMDOC
+ AArch64 unspecified load/store instruction, holding bits 0 to 11 of the
+ address. Used in conjunction with BFD_RELOC_AARCH64_ADR_HI21_PCREL.
+ENUM
+ BFD_RELOC_AARCH64_LD_GOT_LO12_NC
+ENUMDOC
+ AArch64 pseudo relocation code to be used internally by the AArch64
+ assembler and not (currently) written to any object files.
+ENUM
+ BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_LO12_NC
+ENUMDOC
+ AArch64 pseudo relocation code to be used internally by the AArch64
+ assembler and not (currently) written to any object files.
+ENUM
+ BFD_RELOC_AARCH64_TLSDESC_LD_LO12_NC
+ENUMDOC
+ AArch64 pseudo relocation code to be used internally by the AArch64
+ assembler and not (currently) written to any object files.
+
+ENUM
+ BFD_RELOC_TILEPRO_COPY
+ENUMX
+ BFD_RELOC_TILEPRO_GLOB_DAT
+ENUMX
+ BFD_RELOC_TILEPRO_JMP_SLOT
+ENUMX
+ BFD_RELOC_TILEPRO_RELATIVE
+ENUMX
+ BFD_RELOC_TILEPRO_BROFF_X1
+ENUMX
+ BFD_RELOC_TILEPRO_JOFFLONG_X1
+ENUMX
+ BFD_RELOC_TILEPRO_JOFFLONG_X1_PLT
+ENUMX
+ BFD_RELOC_TILEPRO_IMM8_X0
+ENUMX
+ BFD_RELOC_TILEPRO_IMM8_Y0
+ENUMX
+ BFD_RELOC_TILEPRO_IMM8_X1
+ENUMX
+ BFD_RELOC_TILEPRO_IMM8_Y1
+ENUMX
+ BFD_RELOC_TILEPRO_DEST_IMM8_X1
+ENUMX
+ BFD_RELOC_TILEPRO_MT_IMM15_X1
+ENUMX
+ BFD_RELOC_TILEPRO_MF_IMM15_X1
+ENUMX
+ BFD_RELOC_TILEPRO_IMM16_X0
+ENUMX
+ BFD_RELOC_TILEPRO_IMM16_X1
+ENUMX
+ BFD_RELOC_TILEPRO_IMM16_X0_LO
+ENUMX
+ BFD_RELOC_TILEPRO_IMM16_X1_LO
+ENUMX
+ BFD_RELOC_TILEPRO_IMM16_X0_HI
+ENUMX
+ BFD_RELOC_TILEPRO_IMM16_X1_HI
+ENUMX
+ BFD_RELOC_TILEPRO_IMM16_X0_HA
+ENUMX
+ BFD_RELOC_TILEPRO_IMM16_X1_HA
+ENUMX
+ BFD_RELOC_TILEPRO_IMM16_X0_PCREL
+ENUMX
+ BFD_RELOC_TILEPRO_IMM16_X1_PCREL
+ENUMX
+ BFD_RELOC_TILEPRO_IMM16_X0_LO_PCREL
+ENUMX
+ BFD_RELOC_TILEPRO_IMM16_X1_LO_PCREL
+ENUMX
+ BFD_RELOC_TILEPRO_IMM16_X0_HI_PCREL
+ENUMX
+ BFD_RELOC_TILEPRO_IMM16_X1_HI_PCREL
+ENUMX
+ BFD_RELOC_TILEPRO_IMM16_X0_HA_PCREL
+ENUMX
+ BFD_RELOC_TILEPRO_IMM16_X1_HA_PCREL
+ENUMX
+ BFD_RELOC_TILEPRO_IMM16_X0_GOT
+ENUMX
+ BFD_RELOC_TILEPRO_IMM16_X1_GOT
+ENUMX
+ BFD_RELOC_TILEPRO_IMM16_X0_GOT_LO
+ENUMX
+ BFD_RELOC_TILEPRO_IMM16_X1_GOT_LO
+ENUMX
+ BFD_RELOC_TILEPRO_IMM16_X0_GOT_HI
+ENUMX
+ BFD_RELOC_TILEPRO_IMM16_X1_GOT_HI
+ENUMX
+ BFD_RELOC_TILEPRO_IMM16_X0_GOT_HA
+ENUMX
+ BFD_RELOC_TILEPRO_IMM16_X1_GOT_HA
+ENUMX
+ BFD_RELOC_TILEPRO_MMSTART_X0
+ENUMX
+ BFD_RELOC_TILEPRO_MMEND_X0
+ENUMX
+ BFD_RELOC_TILEPRO_MMSTART_X1
+ENUMX
+ BFD_RELOC_TILEPRO_MMEND_X1
+ENUMX
+ BFD_RELOC_TILEPRO_SHAMT_X0
+ENUMX
+ BFD_RELOC_TILEPRO_SHAMT_X1
+ENUMX
+ BFD_RELOC_TILEPRO_SHAMT_Y0
+ENUMX
+ BFD_RELOC_TILEPRO_SHAMT_Y1
+ENUMX
+ BFD_RELOC_TILEPRO_TLS_GD_CALL
+ENUMX
+ BFD_RELOC_TILEPRO_IMM8_X0_TLS_GD_ADD
+ENUMX
+ BFD_RELOC_TILEPRO_IMM8_X1_TLS_GD_ADD
+ENUMX
+ BFD_RELOC_TILEPRO_IMM8_Y0_TLS_GD_ADD
+ENUMX
+ BFD_RELOC_TILEPRO_IMM8_Y1_TLS_GD_ADD
+ENUMX
+ BFD_RELOC_TILEPRO_TLS_IE_LOAD
+ENUMX
+ BFD_RELOC_TILEPRO_IMM16_X0_TLS_GD
+ENUMX
+ BFD_RELOC_TILEPRO_IMM16_X1_TLS_GD
+ENUMX
+ BFD_RELOC_TILEPRO_IMM16_X0_TLS_GD_LO
+ENUMX
+ BFD_RELOC_TILEPRO_IMM16_X1_TLS_GD_LO
+ENUMX
+ BFD_RELOC_TILEPRO_IMM16_X0_TLS_GD_HI
+ENUMX
+ BFD_RELOC_TILEPRO_IMM16_X1_TLS_GD_HI
+ENUMX
+ BFD_RELOC_TILEPRO_IMM16_X0_TLS_GD_HA
+ENUMX
+ BFD_RELOC_TILEPRO_IMM16_X1_TLS_GD_HA
+ENUMX
+ BFD_RELOC_TILEPRO_IMM16_X0_TLS_IE
+ENUMX
+ BFD_RELOC_TILEPRO_IMM16_X1_TLS_IE
+ENUMX
+ BFD_RELOC_TILEPRO_IMM16_X0_TLS_IE_LO
+ENUMX
+ BFD_RELOC_TILEPRO_IMM16_X1_TLS_IE_LO
+ENUMX
+ BFD_RELOC_TILEPRO_IMM16_X0_TLS_IE_HI
+ENUMX
+ BFD_RELOC_TILEPRO_IMM16_X1_TLS_IE_HI
+ENUMX
+ BFD_RELOC_TILEPRO_IMM16_X0_TLS_IE_HA
+ENUMX
+ BFD_RELOC_TILEPRO_IMM16_X1_TLS_IE_HA
+ENUMX
+ BFD_RELOC_TILEPRO_TLS_DTPMOD32
+ENUMX
+ BFD_RELOC_TILEPRO_TLS_DTPOFF32
+ENUMX
+ BFD_RELOC_TILEPRO_TLS_TPOFF32
+ENUMX
+ BFD_RELOC_TILEPRO_IMM16_X0_TLS_LE
+ENUMX
+ BFD_RELOC_TILEPRO_IMM16_X1_TLS_LE
+ENUMX
+ BFD_RELOC_TILEPRO_IMM16_X0_TLS_LE_LO
+ENUMX
+ BFD_RELOC_TILEPRO_IMM16_X1_TLS_LE_LO
+ENUMX
+ BFD_RELOC_TILEPRO_IMM16_X0_TLS_LE_HI
+ENUMX
+ BFD_RELOC_TILEPRO_IMM16_X1_TLS_LE_HI
+ENUMX
+ BFD_RELOC_TILEPRO_IMM16_X0_TLS_LE_HA
+ENUMX
+ BFD_RELOC_TILEPRO_IMM16_X1_TLS_LE_HA
+ENUMDOC
+ Tilera TILEPro Relocations.
+ENUM
+ BFD_RELOC_TILEGX_HW0
+ENUMX
+ BFD_RELOC_TILEGX_HW1
+ENUMX
+ BFD_RELOC_TILEGX_HW2
+ENUMX
+ BFD_RELOC_TILEGX_HW3
+ENUMX
+ BFD_RELOC_TILEGX_HW0_LAST
+ENUMX
+ BFD_RELOC_TILEGX_HW1_LAST
+ENUMX
+ BFD_RELOC_TILEGX_HW2_LAST
+ENUMX
+ BFD_RELOC_TILEGX_COPY
+ENUMX
+ BFD_RELOC_TILEGX_GLOB_DAT
+ENUMX
+ BFD_RELOC_TILEGX_JMP_SLOT
+ENUMX
+ BFD_RELOC_TILEGX_RELATIVE
+ENUMX
+ BFD_RELOC_TILEGX_BROFF_X1
+ENUMX
+ BFD_RELOC_TILEGX_JUMPOFF_X1
+ENUMX
+ BFD_RELOC_TILEGX_JUMPOFF_X1_PLT
+ENUMX
+ BFD_RELOC_TILEGX_IMM8_X0
+ENUMX
+ BFD_RELOC_TILEGX_IMM8_Y0
+ENUMX
+ BFD_RELOC_TILEGX_IMM8_X1
+ENUMX
+ BFD_RELOC_TILEGX_IMM8_Y1
+ENUMX
+ BFD_RELOC_TILEGX_DEST_IMM8_X1
+ENUMX
+ BFD_RELOC_TILEGX_MT_IMM14_X1
+ENUMX
+ BFD_RELOC_TILEGX_MF_IMM14_X1
+ENUMX
+ BFD_RELOC_TILEGX_MMSTART_X0
+ENUMX
+ BFD_RELOC_TILEGX_MMEND_X0
+ENUMX
+ BFD_RELOC_TILEGX_SHAMT_X0
+ENUMX
+ BFD_RELOC_TILEGX_SHAMT_X1
+ENUMX
+ BFD_RELOC_TILEGX_SHAMT_Y0
+ENUMX
+ BFD_RELOC_TILEGX_SHAMT_Y1
+ENUMX
+ BFD_RELOC_TILEGX_IMM16_X0_HW0
+ENUMX
+ BFD_RELOC_TILEGX_IMM16_X1_HW0
+ENUMX
+ BFD_RELOC_TILEGX_IMM16_X0_HW1
+ENUMX
+ BFD_RELOC_TILEGX_IMM16_X1_HW1
+ENUMX
+ BFD_RELOC_TILEGX_IMM16_X0_HW2
+ENUMX
+ BFD_RELOC_TILEGX_IMM16_X1_HW2
+ENUMX
+ BFD_RELOC_TILEGX_IMM16_X0_HW3
+ENUMX
+ BFD_RELOC_TILEGX_IMM16_X1_HW3
+ENUMX
+ BFD_RELOC_TILEGX_IMM16_X0_HW0_LAST
+ENUMX
+ BFD_RELOC_TILEGX_IMM16_X1_HW0_LAST
+ENUMX
+ BFD_RELOC_TILEGX_IMM16_X0_HW1_LAST
+ENUMX
+ BFD_RELOC_TILEGX_IMM16_X1_HW1_LAST
+ENUMX
+ BFD_RELOC_TILEGX_IMM16_X0_HW2_LAST
+ENUMX
+ BFD_RELOC_TILEGX_IMM16_X1_HW2_LAST
+ENUMX
+ BFD_RELOC_TILEGX_IMM16_X0_HW0_PCREL
+ENUMX
+ BFD_RELOC_TILEGX_IMM16_X1_HW0_PCREL
+ENUMX
+ BFD_RELOC_TILEGX_IMM16_X0_HW1_PCREL
+ENUMX
+ BFD_RELOC_TILEGX_IMM16_X1_HW1_PCREL
+ENUMX
+ BFD_RELOC_TILEGX_IMM16_X0_HW2_PCREL
+ENUMX
+ BFD_RELOC_TILEGX_IMM16_X1_HW2_PCREL
+ENUMX
+ BFD_RELOC_TILEGX_IMM16_X0_HW3_PCREL
+ENUMX
+ BFD_RELOC_TILEGX_IMM16_X1_HW3_PCREL
+ENUMX
+ BFD_RELOC_TILEGX_IMM16_X0_HW0_LAST_PCREL
+ENUMX
+ BFD_RELOC_TILEGX_IMM16_X1_HW0_LAST_PCREL
+ENUMX
+ BFD_RELOC_TILEGX_IMM16_X0_HW1_LAST_PCREL
+ENUMX
+ BFD_RELOC_TILEGX_IMM16_X1_HW1_LAST_PCREL
+ENUMX
+ BFD_RELOC_TILEGX_IMM16_X0_HW2_LAST_PCREL
+ENUMX
+ BFD_RELOC_TILEGX_IMM16_X1_HW2_LAST_PCREL
+ENUMX
+ BFD_RELOC_TILEGX_IMM16_X0_HW0_GOT
+ENUMX
+ BFD_RELOC_TILEGX_IMM16_X1_HW0_GOT
+ENUMX
+ BFD_RELOC_TILEGX_IMM16_X0_HW0_PLT_PCREL
+ENUMX
+ BFD_RELOC_TILEGX_IMM16_X1_HW0_PLT_PCREL
+ENUMX
+ BFD_RELOC_TILEGX_IMM16_X0_HW1_PLT_PCREL
+ENUMX
+ BFD_RELOC_TILEGX_IMM16_X1_HW1_PLT_PCREL
+ENUMX
+ BFD_RELOC_TILEGX_IMM16_X0_HW2_PLT_PCREL
+ENUMX
+ BFD_RELOC_TILEGX_IMM16_X1_HW2_PLT_PCREL
+ENUMX
+ BFD_RELOC_TILEGX_IMM16_X0_HW0_LAST_GOT
+ENUMX
+ BFD_RELOC_TILEGX_IMM16_X1_HW0_LAST_GOT
+ENUMX
+ BFD_RELOC_TILEGX_IMM16_X0_HW1_LAST_GOT
+ENUMX
+ BFD_RELOC_TILEGX_IMM16_X1_HW1_LAST_GOT
+ENUMX
+ BFD_RELOC_TILEGX_IMM16_X0_HW3_PLT_PCREL
+ENUMX
+ BFD_RELOC_TILEGX_IMM16_X1_HW3_PLT_PCREL
+ENUMX
+ BFD_RELOC_TILEGX_IMM16_X0_HW0_TLS_GD
+ENUMX
+ BFD_RELOC_TILEGX_IMM16_X1_HW0_TLS_GD
+ENUMX
+ BFD_RELOC_TILEGX_IMM16_X0_HW0_TLS_LE
+ENUMX
+ BFD_RELOC_TILEGX_IMM16_X1_HW0_TLS_LE
+ENUMX
+ BFD_RELOC_TILEGX_IMM16_X0_HW0_LAST_TLS_LE
+ENUMX
+ BFD_RELOC_TILEGX_IMM16_X1_HW0_LAST_TLS_LE
+ENUMX
+ BFD_RELOC_TILEGX_IMM16_X0_HW1_LAST_TLS_LE
+ENUMX
+ BFD_RELOC_TILEGX_IMM16_X1_HW1_LAST_TLS_LE
+ENUMX
+ BFD_RELOC_TILEGX_IMM16_X0_HW0_LAST_TLS_GD
+ENUMX
+ BFD_RELOC_TILEGX_IMM16_X1_HW0_LAST_TLS_GD
+ENUMX
+ BFD_RELOC_TILEGX_IMM16_X0_HW1_LAST_TLS_GD
+ENUMX
+ BFD_RELOC_TILEGX_IMM16_X1_HW1_LAST_TLS_GD
+ENUMX
+ BFD_RELOC_TILEGX_IMM16_X0_HW0_TLS_IE
+ENUMX
+ BFD_RELOC_TILEGX_IMM16_X1_HW0_TLS_IE
+ENUMX
+ BFD_RELOC_TILEGX_IMM16_X0_HW0_LAST_PLT_PCREL
+ENUMX
+ BFD_RELOC_TILEGX_IMM16_X1_HW0_LAST_PLT_PCREL
+ENUMX
+ BFD_RELOC_TILEGX_IMM16_X0_HW1_LAST_PLT_PCREL
+ENUMX
+ BFD_RELOC_TILEGX_IMM16_X1_HW1_LAST_PLT_PCREL
+ENUMX
+ BFD_RELOC_TILEGX_IMM16_X0_HW2_LAST_PLT_PCREL
+ENUMX
+ BFD_RELOC_TILEGX_IMM16_X1_HW2_LAST_PLT_PCREL
+ENUMX
+ BFD_RELOC_TILEGX_IMM16_X0_HW0_LAST_TLS_IE
+ENUMX
+ BFD_RELOC_TILEGX_IMM16_X1_HW0_LAST_TLS_IE
+ENUMX
+ BFD_RELOC_TILEGX_IMM16_X0_HW1_LAST_TLS_IE
+ENUMX
+ BFD_RELOC_TILEGX_IMM16_X1_HW1_LAST_TLS_IE
+ENUMX
+ BFD_RELOC_TILEGX_TLS_DTPMOD64
+ENUMX
+ BFD_RELOC_TILEGX_TLS_DTPOFF64
+ENUMX
+ BFD_RELOC_TILEGX_TLS_TPOFF64
+ENUMX
+ BFD_RELOC_TILEGX_TLS_DTPMOD32
+ENUMX
+ BFD_RELOC_TILEGX_TLS_DTPOFF32
+ENUMX
+ BFD_RELOC_TILEGX_TLS_TPOFF32
+ENUMX
+ BFD_RELOC_TILEGX_TLS_GD_CALL
+ENUMX
+ BFD_RELOC_TILEGX_IMM8_X0_TLS_GD_ADD
+ENUMX
+ BFD_RELOC_TILEGX_IMM8_X1_TLS_GD_ADD
+ENUMX
+ BFD_RELOC_TILEGX_IMM8_Y0_TLS_GD_ADD
+ENUMX
+ BFD_RELOC_TILEGX_IMM8_Y1_TLS_GD_ADD
+ENUMX
+ BFD_RELOC_TILEGX_TLS_IE_LOAD
+ENUMX
+ BFD_RELOC_TILEGX_IMM8_X0_TLS_ADD
+ENUMX
+ BFD_RELOC_TILEGX_IMM8_X1_TLS_ADD
+ENUMX
+ BFD_RELOC_TILEGX_IMM8_Y0_TLS_ADD
+ENUMX
+ BFD_RELOC_TILEGX_IMM8_Y1_TLS_ADD
+ENUMDOC
+ Tilera TILE-Gx Relocations.
+ENUM
+ BFD_RELOC_EPIPHANY_SIMM8
+ENUMDOC
+ Adapteva EPIPHANY - 8 bit signed pc-relative displacement
+ENUM
+ BFD_RELOC_EPIPHANY_SIMM24
+ENUMDOC
+ Adapteva EPIPHANY - 24 bit signed pc-relative displacement
+ENUM
+ BFD_RELOC_EPIPHANY_HIGH
+ENUMDOC
+ Adapteva EPIPHANY - 16 most-significant bits of absolute address
+ENUM
+ BFD_RELOC_EPIPHANY_LOW
+ENUMDOC
+ Adapteva EPIPHANY - 16 least-significant bits of absolute address
+ENUM
+ BFD_RELOC_EPIPHANY_SIMM11
+ENUMDOC
+ Adapteva EPIPHANY - 11 bit signed number - add/sub immediate
+ENUM
+ BFD_RELOC_EPIPHANY_IMM11
+ENUMDOC
+ Adapteva EPIPHANY - 11 bit sign-magnitude number (ld/st displacement)
+ENUM
+ BFD_RELOC_EPIPHANY_IMM8
+ENUMDOC
+ Adapteva EPIPHANY - 8 bit immediate for 16 bit mov instruction.
+
+
+ENDSENUM
+ BFD_RELOC_UNUSED
+CODE_FRAGMENT
+.
+.typedef enum bfd_reloc_code_real bfd_reloc_code_real_type;
+*/
+
+/*
+FUNCTION
+ bfd_reloc_type_lookup
+ bfd_reloc_name_lookup
+
+SYNOPSIS
+ reloc_howto_type *bfd_reloc_type_lookup
+ (bfd *abfd, bfd_reloc_code_real_type code);
+ reloc_howto_type *bfd_reloc_name_lookup
+ (bfd *abfd, const char *reloc_name);
+
+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 (bfd *abfd, bfd_reloc_code_real_type code)
+{
+ return BFD_SEND (abfd, reloc_type_lookup, (abfd, code));
+}
+
+reloc_howto_type *
+bfd_reloc_name_lookup (bfd *abfd, const char *reloc_name)
+{
+ return BFD_SEND (abfd, reloc_name_lookup, (abfd, reloc_name));
+}
+
+static reloc_howto_type bfd_howto_32 =
+HOWTO (0, 00, 2, 32, FALSE, 0, complain_overflow_dont, 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 (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_arch_bits_per_address (abfd))
+ {
+ case 64:
+ BFD_FAIL ();
+ case 32:
+ return &bfd_howto_32;
+ case 16:
+ BFD_FAIL ();
+ default:
+ BFD_FAIL ();
+ }
+ default:
+ BFD_FAIL ();
+ }
+ return 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 (bfd_reloc_code_real_type code)
+{
+ if (code > BFD_RELOC_UNUSED)
+ return 0;
+ return bfd_reloc_code_real_names[code];
+}
+
+/*
+INTERNAL_FUNCTION
+ bfd_generic_relax_section
+
+SYNOPSIS
+ bfd_boolean bfd_generic_relax_section
+ (bfd *abfd,
+ asection *section,
+ struct bfd_link_info *,
+ bfd_boolean *);
+
+DESCRIPTION
+ Provides default handling for relaxing for back ends which
+ don't do relaxing.
+*/
+
+bfd_boolean
+bfd_generic_relax_section (bfd *abfd ATTRIBUTE_UNUSED,
+ asection *section ATTRIBUTE_UNUSED,
+ struct bfd_link_info *link_info ATTRIBUTE_UNUSED,
+ bfd_boolean *again)
+{
+ if (link_info->relocatable)
+ (*link_info->callbacks->einfo)
+ (_("%P%F: --relax and -r may not be used together\n"));
+
+ *again = FALSE;
+ return TRUE;
+}
+
+/*
+INTERNAL_FUNCTION
+ bfd_generic_gc_sections
+
+SYNOPSIS
+ bfd_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.
+*/
+
+bfd_boolean
+bfd_generic_gc_sections (bfd *abfd ATTRIBUTE_UNUSED,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED)
+{
+ return TRUE;
+}
+
+/*
+INTERNAL_FUNCTION
+ bfd_generic_lookup_section_flags
+
+SYNOPSIS
+ bfd_boolean bfd_generic_lookup_section_flags
+ (struct bfd_link_info *, struct flag_info *, asection *);
+
+DESCRIPTION
+ Provides default handling for section flags lookup
+ -- i.e., does nothing.
+ Returns FALSE if the section should be omitted, otherwise TRUE.
+*/
+
+bfd_boolean
+bfd_generic_lookup_section_flags (struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ struct flag_info *flaginfo,
+ asection *section ATTRIBUTE_UNUSED)
+{
+ if (flaginfo != NULL)
+ {
+ (*_bfd_error_handler) (_("INPUT_SECTION_FLAGS are not supported.\n"));
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/*
+INTERNAL_FUNCTION
+ bfd_generic_merge_sections
+
+SYNOPSIS
+ bfd_boolean bfd_generic_merge_sections
+ (bfd *, struct bfd_link_info *);
+
+DESCRIPTION
+ Provides default handling for SEC_MERGE section merging for back ends
+ which don't have SEC_MERGE support -- i.e., does nothing.
+*/
+
+bfd_boolean
+bfd_generic_merge_sections (bfd *abfd ATTRIBUTE_UNUSED,
+ struct bfd_link_info *link_info ATTRIBUTE_UNUSED)
+{
+ 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,
+ bfd_boolean relocatable,
+ 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 (bfd *abfd,
+ struct bfd_link_info *link_info,
+ struct bfd_link_order *link_order,
+ bfd_byte *data,
+ bfd_boolean relocatable,
+ asymbol **symbols)
+{
+ bfd *input_bfd = link_order->u.indirect.section->owner;
+ asection *input_section = link_order->u.indirect.section;
+ long reloc_size;
+ arelent **reloc_vector;
+ long reloc_count;
+
+ reloc_size = bfd_get_reloc_upper_bound (input_bfd, input_section);
+ if (reloc_size < 0)
+ return NULL;
+
+ /* Read in the section. */
+ if (!bfd_get_full_section_contents (input_bfd, input_section, &data))
+ return NULL;
+
+ if (reloc_size == 0)
+ return data;
+
+ reloc_vector = (arelent **) bfd_malloc (reloc_size);
+ if (reloc_vector == NULL)
+ return NULL;
+
+ 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 != NULL; parent++)
+ {
+ char *error_message = NULL;
+ asymbol *symbol;
+ bfd_reloc_status_type r;
+
+ symbol = *(*parent)->sym_ptr_ptr;
+ if (symbol->section && discarded_section (symbol->section))
+ {
+ bfd_byte *p;
+ static reloc_howto_type none_howto
+ = HOWTO (0, 0, 0, 0, FALSE, 0, complain_overflow_dont, NULL,
+ "unused", FALSE, 0, 0, FALSE);
+
+ p = data + (*parent)->address * bfd_octets_per_byte (input_bfd);
+ _bfd_clear_contents ((*parent)->howto, input_bfd, input_section,
+ p);
+ (*parent)->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
+ (*parent)->addend = 0;
+ (*parent)->howto = &none_howto;
+ r = bfd_reloc_ok;
+ }
+ else
+ r = bfd_perform_relocation (input_bfd,
+ *parent,
+ data,
+ input_section,
+ relocatable ? abfd : NULL,
+ &error_message);
+
+ if (relocatable)
+ {
+ 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,
+ TRUE)))
+ goto error_return;
+ break;
+ case bfd_reloc_dangerous:
+ BFD_ASSERT (error_message != 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, NULL,
+ 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:
+ /* PR ld/13730:
+ This error can result when processing some partially
+ complete binaries. Do not abort, but issue an error
+ message instead. */
+ link_info->callbacks->einfo
+ (_("%X%P: %B(%A): relocation \"%R\" goes out of range\n"),
+ abfd, input_section, * parent);
+ goto error_return;
+
+ default:
+ abort ();
+ break;
+ }
+
+ }
+ }
+ }
+
+ free (reloc_vector);
+ return data;
+
+error_return:
+ free (reloc_vector);
+ return NULL;
+}
diff --git a/bfd/reloc16.c b/bfd/reloc16.c
new file mode 100644
index 0000000..cdfc981
--- /dev/null
+++ b/bfd/reloc16.c
@@ -0,0 +1,332 @@
+/* 8 and 16 bit COFF relocation functions, for BFD.
+ Copyright (C) 1990-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, 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 "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+#include "bfdlink.h"
+#include "genlink.h"
+#include "coff/internal.h"
+#include "libcoff.h"
+
+bfd_vma
+bfd_coff_reloc16_get_value (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 (h != (struct bfd_link_hash_entry *) NULL
+ && h->type == bfd_link_hash_undefweak)
+ /* This is a GNU extension. */
+ value = 0;
+ else
+ {
+ if (!((*link_info->callbacks->undefined_symbol)
+ (link_info, bfd_asymbol_name (symbol),
+ input_section->owner, input_section, reloc->address,
+ TRUE)))
+ 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 (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++;
+ }
+}
+
+bfd_boolean
+bfd_coff_reloc16_relax_section (bfd *abfd,
+ asection *input_section,
+ struct bfd_link_info *link_info,
+ bfd_boolean *again)
+{
+ /* Get enough memory to hold the stuff. */
+ bfd *input_bfd = input_section->owner;
+ unsigned *shrinks;
+ unsigned shrink = 0;
+ long reloc_size = bfd_get_reloc_upper_bound (input_bfd, input_section);
+ arelent **reloc_vector = NULL;
+ long reloc_count;
+
+ if (link_info->relocatable)
+ (*link_info->callbacks->einfo)
+ (_("%P%F: --relax and -r may not be used together\n"));
+
+ /* 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 ((bfd_size_type) 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;
+ bfd_size_type amt;
+
+ /* Allocate and initialize the shrinks array for this section.
+ The last element is used as an accumulator of shrinks. */
+ amt = reloc_count + 1;
+ amt *= sizeof (unsigned);
+ shrinks = (unsigned *) bfd_zmalloc (amt);
+
+ /* 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);
+
+ shrink = shrinks[reloc_count];
+ free ((char *) shrinks);
+ }
+
+ input_section->rawsize = input_section->size;
+ input_section->size -= shrink;
+ free ((char *) reloc_vector);
+ return TRUE;
+}
+
+bfd_byte *
+bfd_coff_reloc16_get_relocated_section_contents
+ (bfd *in_abfd,
+ struct bfd_link_info *link_info,
+ struct bfd_link_order *link_order,
+ bfd_byte *data,
+ bfd_boolean relocatable,
+ 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;
+ bfd_size_type sz;
+
+ if (reloc_size < 0)
+ return NULL;
+
+ /* If producing relocatable output, don't bother to relax. */
+ if (relocatable)
+ return bfd_generic_get_relocated_section_contents (in_abfd, link_info,
+ link_order,
+ data, relocatable,
+ symbols);
+
+ /* Read in the section. */
+ sz = input_section->rawsize ? input_section->rawsize : input_section->size;
+ if (!bfd_get_section_contents (input_bfd, input_section, data, 0, sz))
+ return NULL;
+
+ reloc_vector = (arelent **) bfd_malloc ((bfd_size_type) 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 0000000..ddf5c3a
--- /dev/null
+++ b/bfd/riscix.c
@@ -0,0 +1,655 @@
+/* BFD back-end for RISC iX (Acorn, arm) binaries.
+ Copyright (C) 1994-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, 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. */
+
+/* Demand load (impure text). */
+#define IMAGIC (MF_IMPURE | ZMAGIC)
+
+/* OMAGIC with large header.
+ May contain a ref to a shared lib required by the object. */
+#define SPOMAGIC (MF_USES_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 SLOMAGIC (MF_IS_SL | OMAGIC)
+
+/* Sqeezed demand paged.
+ NOTE: This interpretation of QMAGIC seems to be at variance
+ with that used on other architectures. */
+#define QMAGIC (MF_SQUEEZED | ZMAGIC)
+
+/* Program which uses sl. */
+#define SPZMAGIC (MF_USES_SL | ZMAGIC)
+
+/* Sqeezed ditto. */
+#define SPQMAGIC (MF_USES_SL | QMAGIC)
+
+/* Shared lib part of prog. */
+#define SLZMAGIC (MF_IS_SL | ZMAGIC)
+
+/* Sl which uses another. */
+#define SLPZMAGIC (MF_USES_SL | SLZMAGIC)
+
+#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 \
+ ? (bfd_vma) 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 & ~(bfd_vma) (TARGET_PAGE_SIZE - 1)) \
+ : (bfd_vma) 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
+
+/* Do not "beautify" the CONCAT* macro args. Traditional C will not
+ remove whitespace added here, and thus will fail to concatenate
+ the tokens. */
+#define MY(OP) CONCAT2 (arm_aout_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 "sysdep.h"
+#include "bfd.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 \
+ || bfd_bwrite ((void *) & exec_bytes, (bfd_size_type) EXEC_BYTES_SIZE, \
+ abfd) != EXEC_BYTES_SIZE) \
+ return FALSE; \
+ /* Now write out reloc info, followed by syms and strings. */ \
+ \
+ if (bfd_get_outsymbols (abfd) != 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 (bfd *abfd ATTRIBUTE_UNUSED,
+ arelent *reloc_entry ATTRIBUTE_UNUSED,
+ asymbol *symbol ATTRIBUTE_UNUSED,
+ void * data ATTRIBUTE_UNUSED,
+ asection *input_section ATTRIBUTE_UNUSED,
+ bfd *output_bfd ATTRIBUTE_UNUSED,
+ char **error_message ATTRIBUTE_UNUSED)
+{
+ /* This is dead simple at present. */
+ return bfd_reloc_ok;
+}
+
+static bfd_reloc_status_type riscix_fix_pcrel_26 (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
+static const bfd_target *arm_aout_riscix_callback (bfd *);
+
+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),
+ EMPTY_HOWTO (-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 (bfd *abfd,
+ arelent *reloc_entry,
+ asymbol *symbol,
+ void * data,
+ asection *input_section,
+ bfd *output_bfd,
+ char **error_message ATTRIBUTE_UNUSED)
+{
+ 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 (bfd_is_und_section (symbol->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 != 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 & ~ (bfd_vma) 0x03ffffff)
+ flag = bfd_reloc_overflow;
+
+ target &= ~0x00ffffff;
+ target |= (relocation >> 2) & 0x00ffffff;
+ bfd_put_32 (abfd, (bfd_vma) 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;
+}
+
+static reloc_howto_type *
+riscix_reloc_type_lookup (bfd *abfd, 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_arch_bits_per_address (abfd))
+ {
+ case 32:
+ code = BFD_RELOC_32;
+ break;
+ default:
+ return 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 NULL;
+ }
+}
+
+static reloc_howto_type *
+riscix_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ const char *r_name)
+{
+ unsigned int i;
+
+ for (i = 0;
+ i < sizeof (riscix_std_reloc_howto) / sizeof (riscix_std_reloc_howto[0]);
+ i++)
+ if (riscix_std_reloc_howto[i].name != NULL
+ && strcasecmp (riscix_std_reloc_howto[i].name, r_name) == 0)
+ return &riscix_std_reloc_howto[i];
+
+ return 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_bfd_reloc_name_lookup riscix_reloc_name_lookup
+#define MY_canonicalize_reloc arm_aout_riscix_canonicalize_reloc
+#define MY_object_p arm_aout_riscix_object_p
+
+static void
+riscix_swap_std_reloc_out (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;
+
+ /* 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)->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));
+ }
+}
+
+static bfd_boolean
+riscix_squirt_out_relocs (bfd *abfd, asection *section)
+{
+ arelent **generic;
+ unsigned char *native, *natptr;
+ size_t each_size;
+ unsigned int count = section->reloc_count;
+ bfd_size_type natsize;
+
+ if (count == 0)
+ return TRUE;
+
+ each_size = obj_reloc_entry_size (abfd);
+ natsize = each_size;
+ natsize *= count;
+ native = 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_bwrite ((void *) native, 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. */
+
+static long
+MY (canonicalize_reloc) (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. */
+
+static const bfd_target *
+riscix_some_aout_object_p (bfd *abfd,
+ struct internal_exec *execp,
+ const bfd_target *(*callback_to_real_object_p) (bfd *))
+{
+ struct aout_data_struct *rawptr, *oldrawptr;
+ const bfd_target *result;
+ bfd_size_type amt = sizeof (struct aout_data_struct);
+
+ rawptr = bfd_zalloc (abfd, amt);
+
+ if (rawptr == NULL)
+ return NULL;
+
+ 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;
+ /* Copy in the internal_exec struct. */
+ *(abfd->tdata.aout_data->a.hdr) = *execp;
+ 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;
+
+ /* Squeezed files aren't supported (yet)! */
+ if ((execp->a_info & MF_SQUEEZED) != 0)
+ {
+ 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) = 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)->size = execp->a_data;
+ obj_bsssec (abfd)->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)->size))
+ abfd->flags |= EXEC_P;
+#endif /* MACH */
+ if (result == NULL)
+ {
+ free (rawptr);
+ abfd->tdata.aout_data = oldrawptr;
+ }
+ return result;
+}
+
+static const bfd_target *
+MY (object_p) (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_bread ((void *) &exec_bytes, (bfd_size_type) EXEC_BYTES_SIZE, abfd)
+ != EXEC_BYTES_SIZE)
+ {
+ if (bfd_get_error () != bfd_error_system_call)
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+
+ exec.a_info = H_GET_32 (abfd, exec_bytes.e_info);
+
+ if (N_BADMAG (exec))
+ return NULL;
+
+#ifdef MACHTYPE_OK
+ if (!(MACHTYPE_OK (N_MACHTYPE (exec))))
+ return NULL;
+#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 0000000..8f2f3a0
--- /dev/null
+++ b/bfd/rs6000-core.c
@@ -0,0 +1,751 @@
+/* IBM RS/6000 "XCOFF" back-end for BFD.
+ Copyright (C) 1990-2014 Free Software Foundation, Inc.
+ Written by Metin G. Ozisik, Mimi Phuong-Thao Vo, 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, 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.
+
+ 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 "sysdep.h"
+#include "bfd.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>
+#define __LDINFO_PTRACE32__ /* for __ld_info32 */
+#define __LDINFO_PTRACE64__ /* for __ld_info64 */
+#include <sys/ldr.h>
+#include <sys/core.h>
+#include <sys/systemcfg.h>
+
+/* Borrowed from <sys/inttypes.h> on recent AIX versions. */
+typedef unsigned long ptr_to_uint;
+
+#define core_hdr(bfd) ((CoreHdr *) bfd->tdata.any)
+
+/* AIX 4.1 changed the names and locations of a few items in the core file.
+ AIX 4.3 defined an entirely new structure, core_dumpx, but kept support for
+ the previous 4.1 structure, core_dump.
+
+ AIX_CORE_DUMPX_CORE is defined (by configure) on AIX 4.3+, and
+ CORE_VERSION_1 is defined (by AIX core.h) as 2 on AIX 4.3+ and as 1 on AIX
+ 4.1 and 4.2. AIX pre-4.1 (aka 3.x) either doesn't define CORE_VERSION_1
+ or else defines it as 0. */
+
+#if defined(CORE_VERSION_1) && !CORE_VERSION_1
+# undef CORE_VERSION_1
+#endif
+
+/* The following union and macros allow this module to compile on all AIX
+ versions and to handle both core_dumpx and core_dump on 4.3+. CNEW_*()
+ and COLD_*() macros respectively retrieve core_dumpx and core_dump
+ values. */
+
+/* Union of 32-bit and 64-bit versions of ld_info. */
+
+typedef union {
+#ifdef __ld_info32
+ struct __ld_info32 l32;
+ struct __ld_info64 l64;
+#else
+ struct ld_info l32;
+ struct ld_info l64;
+#endif
+} LdInfo;
+
+/* Union of old and new core dump structures. */
+
+typedef union {
+#ifdef AIX_CORE_DUMPX_CORE
+ struct core_dumpx new_dump; /* new AIX 4.3+ core dump */
+#else
+ struct core_dump new_dump; /* for simpler coding */
+#endif
+ struct core_dump old; /* old AIX 4.2- core dump, still used on
+ 4.3+ with appropriate SMIT config */
+} CoreHdr;
+
+/* Union of old and new vm_info structures. */
+
+#ifdef CORE_VERSION_1
+typedef union {
+#ifdef AIX_CORE_DUMPX_CORE
+ struct vm_infox new_dump;
+#else
+ struct vm_info new_dump;
+#endif
+ struct vm_info old;
+} VmInfo;
+#endif
+
+/* Return whether CoreHdr C is in new or old format. */
+
+#ifdef AIX_CORE_DUMPX_CORE
+# define CORE_NEW(c) (!(c).old.c_entries)
+#else
+# define CORE_NEW(c) 0
+#endif
+
+/* Return whether CoreHdr C usese core_dumpxx structure.
+
+ FIXME: the core file format version number used here definitely indicates
+ that struct core_dumpxx should be used to represent the core file header,
+ but that may not be the only such format version number. */
+
+#ifdef AIX_5_CORE
+# define CORE_DUMPXX_VERSION 267312562
+# define CNEW_IS_CORE_DUMPXX(c) ((c).new_dump.c_version == CORE_DUMPXX_VERSION)
+#else
+# define CNEW_IS_CORE_DUMPXX(c) 0
+#endif
+
+/* Return the c_stackorg field from struct core_dumpx C. */
+
+#ifdef AIX_CORE_DUMPX_CORE
+# define CNEW_STACKORG(c) (c).c_stackorg
+#else
+# define CNEW_STACKORG(c) 0
+#endif
+
+/* Return the offset to the loader region from struct core_dump C. */
+
+#ifdef AIX_CORE_DUMPX_CORE
+# define CNEW_LOADER(c) (c).c_loader
+#else
+# define CNEW_LOADER(c) 0
+#endif
+
+/* Return the offset to the loader region from struct core_dump C. */
+
+#define COLD_LOADER(c) (c).c_tab
+
+/* Return the c_lsize field from struct core_dumpx C. */
+
+#ifdef AIX_CORE_DUMPX_CORE
+# define CNEW_LSIZE(c) (c).c_lsize
+#else
+# define CNEW_LSIZE(c) 0
+#endif
+
+/* Return the c_dataorg field from struct core_dumpx C. */
+
+#ifdef AIX_CORE_DUMPX_CORE
+# define CNEW_DATAORG(c) (c).c_dataorg
+#else
+# define CNEW_DATAORG(c) 0
+#endif
+
+/* Return the c_datasize field from struct core_dumpx C. */
+
+#ifdef AIX_CORE_DUMPX_CORE
+# define CNEW_DATASIZE(c) (c).c_datasize
+#else
+# define CNEW_DATASIZE(c) 0
+#endif
+
+/* Return the c_impl field from struct core_dumpx C. */
+
+#if defined (HAVE_ST_C_IMPL) || defined (AIX_5_CORE)
+# define CNEW_IMPL(c) (c).c_impl
+#else
+# define CNEW_IMPL(c) 0
+#endif
+
+/* Return the command string from struct core_dumpx C. */
+
+#ifdef AIX_CORE_DUMPX_CORE
+# define CNEW_COMM(c) (c).c_u.U_proc.pi_comm
+#else
+# define CNEW_COMM(c) 0
+#endif
+
+/* Return the command string from struct core_dump C. */
+
+#ifdef CORE_VERSION_1
+# define COLD_COMM(c) (c).c_u.U_comm
+#else
+# define COLD_COMM(c) (c).c_u.u_comm
+#endif
+
+/* Return the struct __context64 pointer from struct core_dumpx C. */
+
+#ifdef AIX_CORE_DUMPX_CORE
+# define CNEW_CONTEXT64(c) (c).c_flt.hctx.r64
+#else
+# define CNEW_CONTEXT64(c) c
+#endif
+
+/* Return the struct mstsave pointer from struct core_dumpx C. */
+
+#ifdef AIX_CORE_DUMPX_CORE
+# define CNEW_MSTSAVE(c) (c).c_flt.hctx.r32
+#else
+# define CNEW_MSTSAVE(c) c
+#endif
+
+/* Return the struct mstsave pointer from struct core_dump C. */
+
+#ifdef CORE_VERSION_1
+# define COLD_MSTSAVE(c) (c).c_mst
+#else
+# define COLD_MSTSAVE(c) (c).c_u.u_save
+#endif
+
+/* Return whether struct core_dumpx is from a 64-bit process. */
+
+#ifdef AIX_CORE_DUMPX_CORE
+# define CNEW_PROC64(c) IS_PROC64(&(c).c_u.U_proc)
+#else
+# define CNEW_PROC64(c) 0
+#endif
+
+/* Magic end-of-stack addresses for old core dumps. This is _very_ fragile,
+ but I don't see any easy way to get that info right now. */
+
+#ifdef CORE_VERSION_1
+# define COLD_STACKEND 0x2ff23000
+#else
+# define COLD_STACKEND 0x2ff80000
+#endif
+
+/* Size of the leading portion that old and new core dump structures have in
+ common. */
+#define CORE_COMMONSZ ((int) &((struct core_dump *) 0)->c_entries \
+ + sizeof (((struct core_dump *) 0)->c_entries))
+
+/* Define prototypes for certain functions, to avoid a compiler warning
+ saying that they are missing. */
+
+const bfd_target * rs6000coff_core_p (bfd *abfd);
+bfd_boolean rs6000coff_core_file_matches_executable_p (bfd *core_bfd,
+ bfd *exec_bfd);
+char * rs6000coff_core_file_failing_command (bfd *abfd);
+int rs6000coff_core_file_failing_signal (bfd *abfd);
+
+/* Try to read into CORE the header from the core file associated with ABFD.
+ Return success. */
+
+static bfd_boolean
+read_hdr (bfd *abfd, CoreHdr *core)
+{
+ bfd_size_type size;
+
+ if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
+ return FALSE;
+
+ /* Read the leading portion that old and new core dump structures have in
+ common. */
+ size = CORE_COMMONSZ;
+ if (bfd_bread (core, size, abfd) != size)
+ return FALSE;
+
+ /* Read the trailing portion of the structure. */
+ if (CORE_NEW (*core))
+ size = sizeof (core->new_dump);
+ else
+ size = sizeof (core->old);
+ size -= CORE_COMMONSZ;
+ return bfd_bread ((char *) core + CORE_COMMONSZ, size, abfd) == size;
+}
+
+static asection *
+make_bfd_asection (bfd *abfd, const char *name, flagword flags,
+ bfd_size_type size, bfd_vma vma, file_ptr filepos)
+{
+ asection *asect;
+
+ asect = bfd_make_section_anyway_with_flags (abfd, name, flags);
+ if (!asect)
+ return NULL;
+
+ asect->size = 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 (bfd *abfd)
+{
+ CoreHdr core;
+ struct stat statbuf;
+ bfd_size_type size;
+ char *tmpptr;
+
+ /* Values from new and old core structures. */
+ int c_flag;
+ file_ptr c_stack, c_regoff, c_loader;
+ bfd_size_type c_size, c_regsize, c_lsize;
+ bfd_vma c_stackend;
+ void *c_regptr;
+ int proc64;
+
+ if (!read_hdr (abfd, &core))
+ {
+ if (bfd_get_error () != bfd_error_system_call)
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+
+ /* This isn't the right handler for 64-bit core files on AIX 5.x. */
+ if (CORE_NEW (core) && CNEW_IS_CORE_DUMPXX (core))
+ {
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+
+ /* Copy fields from new or old core structure. */
+ if (CORE_NEW (core))
+ {
+ c_flag = core.new_dump.c_flag;
+ c_stack = (file_ptr) core.new_dump.c_stack;
+ c_size = core.new_dump.c_size;
+ c_stackend = CNEW_STACKORG (core.new_dump) + c_size;
+ c_lsize = CNEW_LSIZE (core.new_dump);
+ c_loader = CNEW_LOADER (core.new_dump);
+ proc64 = CNEW_PROC64 (core.new_dump);
+ }
+ else
+ {
+ c_flag = core.old.c_flag;
+ c_stack = (file_ptr) (ptr_to_uint) core.old.c_stack;
+ c_size = core.old.c_size;
+ c_stackend = COLD_STACKEND;
+ c_lsize = 0x7ffffff;
+ c_loader = (file_ptr) (ptr_to_uint) COLD_LOADER (core.old);
+ proc64 = 0;
+ }
+
+ if (proc64)
+ {
+ c_regsize = sizeof (CNEW_CONTEXT64 (core.new_dump));
+ c_regptr = &CNEW_CONTEXT64 (core.new_dump);
+ }
+ else if (CORE_NEW (core))
+ {
+ c_regsize = sizeof (CNEW_MSTSAVE (core.new_dump));
+ c_regptr = &CNEW_MSTSAVE (core.new_dump);
+ }
+ else
+ {
+ c_regsize = sizeof (COLD_MSTSAVE (core.old));
+ c_regptr = &COLD_MSTSAVE (core.old);
+ }
+ c_regoff = (char *) c_regptr - (char *) &core;
+
+ 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 (!(c_flag & UBLOCK_VALID)
+ || !(c_flag & LE_VALID))
+ {
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+
+ if (!(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 (!(c_flag & (FULL_CORE | CORE_TRUNC)))
+ {
+ /* If the size is wrong, it means we're misinterpreting something. */
+ if (c_stack + (file_ptr) c_size != statbuf.st_size)
+ {
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+ }
+
+ /* Sanity check on the c_tab field. */
+ if (!CORE_NEW (core) && (c_loader < (file_ptr) sizeof core.old ||
+ c_loader >= statbuf.st_size ||
+ c_loader >= c_stack))
+ {
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+
+ /* Issue warning if the core file was truncated during writing. */
+ if (c_flag & CORE_TRUNC)
+ (*_bfd_error_handler) (_("%s: warning core file truncated"),
+ bfd_get_filename (abfd));
+
+ /* Allocate core file header. */
+ size = CORE_NEW (core) ? sizeof (core.new_dump) : sizeof (core.old);
+ tmpptr = (char *) bfd_zalloc (abfd, (bfd_size_type) size);
+ if (!tmpptr)
+ return NULL;
+
+ /* Copy core file header. */
+ memcpy (tmpptr, &core, size);
+ set_tdata (abfd, tmpptr);
+
+ /* Set architecture. */
+ if (CORE_NEW (core))
+ {
+ enum bfd_architecture arch;
+ unsigned long mach;
+
+ switch (CNEW_IMPL (core.new_dump))
+ {
+ case POWER_RS1:
+ case POWER_RSC:
+ case POWER_RS2:
+ arch = bfd_arch_rs6000;
+ mach = bfd_mach_rs6k;
+ break;
+ default:
+ arch = bfd_arch_powerpc;
+ mach = bfd_mach_ppc;
+ break;
+ }
+ bfd_default_set_arch_mach (abfd, arch, mach);
+ }
+
+ /* .stack section. */
+ if (!make_bfd_asection (abfd, ".stack",
+ SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS,
+ c_size, c_stackend - c_size, c_stack))
+ goto fail;
+
+ /* .reg section for all registers. */
+ if (!make_bfd_asection (abfd, ".reg",
+ SEC_HAS_CONTENTS,
+ c_regsize, (bfd_vma) 0, c_regoff))
+ goto fail;
+
+ /* .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,
+ c_lsize, (bfd_vma) 0, c_loader))
+ goto fail;
+
+#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 core.c_datasize below to find out the actual size of
+ the .data section. */
+ if (c_flag & FULL_CORE)
+ {
+ if (!make_bfd_asection (abfd, ".data",
+ SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS,
+ (bfd_size_type) core.old.c_u.u_dsize,
+ (bfd_vma)
+ CDATA_ADDR (core.old.c_u.u_dsize),
+ c_stack + c_size))
+ goto fail;
+ }
+#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. */
+ {
+ LdInfo ldinfo;
+ bfd_size_type ldi_datasize;
+ file_ptr ldi_core;
+ uint ldi_next;
+ bfd_vma ldi_dataorg;
+
+ /* Fields from new and old core structures. */
+ bfd_size_type c_datasize, c_vmregions;
+ file_ptr c_data, c_vmm;
+
+ if (CORE_NEW (core))
+ {
+ c_datasize = CNEW_DATASIZE (core.new_dump);
+ c_data = (file_ptr) core.new_dump.c_data;
+ c_vmregions = core.new_dump.c_vmregions;
+ c_vmm = (file_ptr) core.new_dump.c_vmm;
+ }
+ else
+ {
+ c_datasize = core.old.c_datasize;
+ c_data = (file_ptr) (ptr_to_uint) core.old.c_data;
+ c_vmregions = core.old.c_vmregions;
+ c_vmm = (file_ptr) (ptr_to_uint) core.old.c_vmm;
+ }
+
+ /* .data section from executable. */
+ if (c_datasize)
+ {
+ if (!make_bfd_asection (abfd, ".data",
+ SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS,
+ c_datasize,
+ (bfd_vma) CDATA_ADDR (c_datasize),
+ c_data))
+ goto fail;
+ }
+
+ /* .data sections from loaded objects. */
+ if (proc64)
+ size = (int) ((LdInfo *) 0)->l64.ldinfo_filename;
+ else
+ size = (int) ((LdInfo *) 0)->l32.ldinfo_filename;
+
+ while (1)
+ {
+ if (bfd_seek (abfd, c_loader, SEEK_SET) != 0)
+ goto fail;
+ if (bfd_bread (&ldinfo, size, abfd) != size)
+ goto fail;
+
+ if (proc64)
+ {
+ ldi_core = ldinfo.l64.ldinfo_core;
+ ldi_datasize = ldinfo.l64.ldinfo_datasize;
+ ldi_dataorg = (bfd_vma) ldinfo.l64.ldinfo_dataorg;
+ ldi_next = ldinfo.l64.ldinfo_next;
+ }
+ else
+ {
+ ldi_core = ldinfo.l32.ldinfo_core;
+ ldi_datasize = ldinfo.l32.ldinfo_datasize;
+ ldi_dataorg = (bfd_vma) (ptr_to_uint) ldinfo.l32.ldinfo_dataorg;
+ ldi_next = ldinfo.l32.ldinfo_next;
+ }
+
+ if (ldi_core)
+ if (!make_bfd_asection (abfd, ".data",
+ SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS,
+ ldi_datasize, ldi_dataorg, ldi_core))
+ goto fail;
+
+ if (ldi_next == 0)
+ break;
+ c_loader += ldi_next;
+ }
+
+ /* .vmdata sections from anonymously mmapped regions. */
+ if (c_vmregions)
+ {
+ bfd_size_type i;
+
+ if (bfd_seek (abfd, c_vmm, SEEK_SET) != 0)
+ goto fail;
+
+ for (i = 0; i < c_vmregions; i++)
+ {
+ VmInfo vminfo;
+ bfd_size_type vminfo_size;
+ file_ptr vminfo_offset;
+ bfd_vma vminfo_addr;
+
+ size = CORE_NEW (core) ? sizeof (vminfo.new_dump) : sizeof (vminfo.old);
+ if (bfd_bread (&vminfo, size, abfd) != size)
+ goto fail;
+
+ if (CORE_NEW (core))
+ {
+ vminfo_addr = (bfd_vma) vminfo.new_dump.vminfo_addr;
+ vminfo_size = vminfo.new_dump.vminfo_size;
+ vminfo_offset = vminfo.new_dump.vminfo_offset;
+ }
+ else
+ {
+ vminfo_addr = (bfd_vma) (ptr_to_uint) vminfo.old.vminfo_addr;
+ vminfo_size = vminfo.old.vminfo_size;
+ vminfo_offset = vminfo.old.vminfo_offset;
+ }
+
+ if (vminfo_offset)
+ if (!make_bfd_asection (abfd, ".vmdata",
+ SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS,
+ vminfo_size, vminfo_addr,
+ vminfo_offset))
+ goto fail;
+ }
+ }
+ }
+#endif
+
+ return abfd->xvec; /* This is garbage for now. */
+
+ fail:
+ bfd_release (abfd, abfd->tdata.any);
+ abfd->tdata.any = NULL;
+ bfd_section_list_clear (abfd);
+ return NULL;
+}
+
+/* Return `TRUE' if given core is from the given executable. */
+
+bfd_boolean
+rs6000coff_core_file_matches_executable_p (bfd *core_bfd, bfd *exec_bfd)
+{
+ CoreHdr core;
+ bfd_size_type size;
+ char *path, *s;
+ size_t alloc;
+ const char *str1, *str2;
+ bfd_boolean ret;
+ file_ptr c_loader;
+
+ if (!read_hdr (core_bfd, &core))
+ return FALSE;
+
+ if (CORE_NEW (core))
+ c_loader = CNEW_LOADER (core.new_dump);
+ else
+ c_loader = (file_ptr) (ptr_to_uint) COLD_LOADER (core.old);
+
+ if (CORE_NEW (core) && CNEW_PROC64 (core.new_dump))
+ size = (int) ((LdInfo *) 0)->l64.ldinfo_filename;
+ else
+ size = (int) ((LdInfo *) 0)->l32.ldinfo_filename;
+
+ if (bfd_seek (core_bfd, c_loader + size, SEEK_SET) != 0)
+ return FALSE;
+
+ alloc = 100;
+ path = bfd_malloc ((bfd_size_type) alloc);
+ if (path == NULL)
+ return FALSE;
+ s = path;
+
+ while (1)
+ {
+ if (bfd_bread (s, (bfd_size_type) 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, (bfd_size_type) 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 (bfd *abfd)
+{
+ CoreHdr *core = core_hdr (abfd);
+ char *com = CORE_NEW (*core) ?
+ CNEW_COMM (core->new_dump) : COLD_COMM (core->old);
+
+ if (*com)
+ return com;
+ else
+ return 0;
+}
+
+int
+rs6000coff_core_file_failing_signal (bfd *abfd)
+{
+ CoreHdr *core = core_hdr (abfd);
+ return CORE_NEW (*core) ? core->new_dump.c_signo : core->old.c_signo;
+}
+
+#endif /* AIX_CORE */
diff --git a/bfd/sco5-core.c b/bfd/sco5-core.c
new file mode 100644
index 0000000..7067176
--- /dev/null
+++ b/bfd/sco5-core.c
@@ -0,0 +1,396 @@
+/* BFD back end for SCO5 core files (U-area and raw sections)
+ Copyright (C) 1998-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.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 */
+#ifdef SCO5_CORE
+#include <sys/paccess.h>
+#include <sys/region.h>
+#endif
+
+struct sco5_core_struct
+{
+ struct user u;
+};
+
+/* forward declarations */
+
+#define sco5_core_file_matches_executable_p generic_core_file_matches_executable_p
+#define sco5_core_file_pid _bfd_nocore_core_file_pid
+
+static asection *
+make_bfd_asection (bfd *abfd,
+ const char *name,
+ flagword flags,
+ bfd_size_type size,
+ bfd_vma vma,
+ file_ptr filepos)
+{
+ asection *asect;
+
+ asect = bfd_make_section_anyway_with_flags (abfd, name, flags);
+ if (!asect)
+ return NULL;
+ asect->size = size;
+ asect->vma = vma;
+ asect->filepos = filepos;
+ asect->alignment_power = 2;
+
+ return asect;
+}
+
+static struct user *
+read_uarea (bfd *abfd, int filepos)
+{
+ struct sco5_core_struct *rawptr;
+ bfd_size_type amt = sizeof (struct sco5_core_struct);
+
+ rawptr = (struct sco5_core_struct *) bfd_zmalloc (amt);
+ if (rawptr == NULL)
+ return NULL;
+
+ abfd->tdata.sco5_core_data = rawptr;
+
+ if (bfd_seek (abfd, (file_ptr) filepos, SEEK_SET) != 0
+ || bfd_bread ((void *) &rawptr->u, (bfd_size_type) 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;
+}
+
+const bfd_target *
+sco5_core_file_p (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)). */
+
+ {
+ struct stat statbuf;
+
+ if (bfd_stat (abfd, &statbuf) < 0)
+ return NULL;
+
+ coresize = statbuf.st_size;
+ }
+ /* Last long in core is sizeof struct coreoffsets, read it */
+ if ((bfd_seek (abfd, (file_ptr) (coresize - sizeof coffset_siz),
+ SEEK_SET) != 0)
+ || bfd_bread ((void *) &coffset_siz, (bfd_size_type) 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, (file_ptr) (coresize - coffset_siz), SEEK_SET) != 0)
+ || (bfd_bread ((void *) &coffsets, (bfd_size_type) 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)
+ goto fail;
+
+ 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))
+ goto fail;
+
+ 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))
+ goto fail;
+
+ 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))
+ goto fail;
+
+ 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,
+ (file_ptr) (coresize - coffset_siz - 2 * sizeof coffset_siz),
+ SEEK_SET) != 0)
+ || (bfd_bread ((void *) &nsecs, (bfd_size_type) sizeof nsecs, abfd)
+ != sizeof nsecs)
+ || (bfd_bread ((void *) &cheadoffs, (bfd_size_type) sizeof cheadoffs,
+ abfd) != sizeof cheadoffs)
+ || (bfd_seek (abfd, (file_ptr) cheadoffs, SEEK_SET) != 0)
+ || (bfd_bread ((void *) &chead, (bfd_size_type) sizeof chead, abfd)
+ != sizeof chead)
+ || (chead.cs_stype != CORES_OFFSETS)
+ || (chead.cs_x.csx_magic != COREMAGIC_NUMBER))
+ {
+ bfd_set_error (bfd_error_wrong_format);
+ goto fail;
+ }
+
+ /* 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, (file_ptr) chead.cs_hseek, SEEK_SET) != 0)
+ || (bfd_bread ((void *) &chead, (bfd_size_type) sizeof chead, abfd)
+ != sizeof chead))
+ {
+ bfd_set_error (bfd_error_wrong_format);
+ goto fail;
+ }
+
+ 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);
+ goto fail;
+ }
+ 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)
+ goto fail;
+
+ /* 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))
+ goto fail;
+
+ }
+
+ return abfd->xvec;
+
+ fail:
+ if (abfd->tdata.any)
+ {
+ bfd_release (abfd, abfd->tdata.any);
+ abfd->tdata.any = NULL;
+ }
+ bfd_section_list_clear (abfd);
+ return NULL;
+}
+
+char *
+sco5_core_file_failing_command (bfd *abfd)
+{
+ char *com = abfd->tdata.sco5_core_data->u.u_comm;
+ if (*com)
+ return com;
+ else
+ return NULL;
+}
+
+int
+sco5_core_file_failing_signal (bfd *ignore_abfd)
+{
+ return ((ignore_abfd->tdata.sco5_core_data->u.u_sysabort != 0)
+ ? ignore_abfd->tdata.sco5_core_data->u.u_sysabort
+ : -1);
+}
+
+/* If somebody calls any byte-swapping routines, shoot them. */
+static void
+swap_abort (void)
+{
+ abort (); /* This way doesn't require any declaration for ANSI to fuck up */
+}
+
+#define NO_GET ((bfd_vma (*) (const void *)) swap_abort)
+#define NO_PUT ((void (*) (bfd_vma, void *)) swap_abort)
+#define NO_GETS ((bfd_signed_vma (*) (const void *)) swap_abort)
+#define NO_GET64 ((bfd_uint64_t (*) (const void *)) swap_abort)
+#define NO_PUT64 ((void (*) (bfd_uint64_t, void *)) swap_abort)
+#define NO_GETS64 ((bfd_int64_t (*) (const void *)) swap_abort)
+
+const bfd_target core_sco5_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 */
+ 0, /* match priority. */
+ NO_GET64, NO_GETS64, NO_PUT64, /* 64 bit data */
+ NO_GET, NO_GETS, NO_PUT, /* 32 bit data */
+ NO_GET, NO_GETS, NO_PUT, /* 16 bit data */
+ NO_GET64, NO_GETS64, NO_PUT64, /* 64 bit hdrs */
+ NO_GET, NO_GETS, NO_PUT, /* 32 bit hdrs */
+ NO_GET, NO_GETS, 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 (_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),
+
+ NULL,
+
+ NULL /* backend_data */
+ };
diff --git a/bfd/section.c b/bfd/section.c
new file mode 100644
index 0000000..b27539a
--- /dev/null
+++ b/bfd/section.c
@@ -0,0 +1,1657 @@
+/* Object file "section" support for the BFD library.
+ Copyright (C) 1990-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, 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 "sysdep.h"
+#include "bfd.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 bfd_section
+.{
+. {* 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;
+.
+. {* A unique sequence number. *}
+. int id;
+.
+. {* Which section in the bfd; 0..n-1 as sections are created in a bfd. *}
+. int index;
+.
+. {* The next section in the list belonging to the BFD, or NULL. *}
+. struct bfd_section *next;
+.
+. {* The previous section in the list belonging to the BFD, or NULL. *}
+. struct bfd_section *prev;
+.
+. {* 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
+.
+. {* A signal to the OS that the section contains read only data. *}
+.#define SEC_READONLY 0x008
+.
+. {* The section contains code only. *}
+.#define SEC_CODE 0x010
+.
+. {* The section contains data only. *}
+.#define SEC_DATA 0x020
+.
+. {* The section will reside in ROM. *}
+.#define SEC_ROM 0x040
+.
+. {* 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 0x080
+.
+. {* 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 0x100
+.
+. {* An instruction to the linker to not output the section
+. even if it has information which would normally be written. *}
+.#define SEC_NEVER_LOAD 0x200
+.
+. {* The section contains thread local data. *}
+.#define SEC_THREAD_LOCAL 0x400
+.
+. {* The section has GOT references. This flag is only for the
+. linker, and is currently only used by the elf32-hppa back end.
+. It will be set if global offset table references were detected
+. in this section, which indicate to the linker that the section
+. contains PIC code, and must be handled specially when doing a
+. static link. *}
+.#define SEC_HAS_GOT_REF 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 0x1000
+.
+. {* 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 0x2000
+.
+. {* 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 0x4000
+.
+. {* 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 0x8000
+.
+. {* The contents of this section are to be sorted based on the sum of
+. the symbol and addend values specified by the associated relocation
+. entries. Entries without associated relocation entries will be
+. appended to the end of the section in an unspecified order. *}
+.#define SEC_SORT_ENTRIES 0x10000
+.
+. {* 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 0x20000
+.
+. {* If SEC_LINK_ONCE is set, this bitfield describes how the linker
+. should handle duplicate sections. *}
+.#define SEC_LINK_DUPLICATES 0xc0000
+.
+. {* 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 0x40000
+.
+. {* 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 0x80000
+.
+. {* 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 \
+. (SEC_LINK_DUPLICATES_ONE_ONLY | SEC_LINK_DUPLICATES_SAME_SIZE)
+.
+. {* 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 0x100000
+.
+. {* This section should not be subject to garbage collection.
+. Also set to inform the linker that this section should not be
+. listed in the link map as discarded. *}
+.#define SEC_KEEP 0x200000
+.
+. {* This section contains "short" data, and should be placed
+. "near" the GP. *}
+.#define SEC_SMALL_DATA 0x400000
+.
+. {* Attempt to merge identical entities in the section.
+. Entity size is given in the entsize field. *}
+.#define SEC_MERGE 0x800000
+.
+. {* If given with SEC_MERGE, entities to merge are zero terminated
+. strings where entsize specifies character size instead of fixed
+. size entries. *}
+.#define SEC_STRINGS 0x1000000
+.
+. {* This section contains data about section groups. *}
+.#define SEC_GROUP 0x2000000
+.
+. {* 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 0x4000000
+.
+. {* This input section should be copied to output in reverse order
+. as an array of pointers. This is for ELF linker internal use
+. only. *}
+.#define SEC_ELF_REVERSE_COPY 0x4000000
+.
+. {* This section contains data which may be shared with other
+. executables or shared objects. This is for COFF only. *}
+.#define SEC_COFF_SHARED 0x8000000
+.
+. {* When a section with this flag is being linked, then if the size of
+. the input section is less than a page, it should not cross a page
+. boundary. If the size of the input section is one page or more,
+. it should be aligned on a page boundary. This is for TI
+. TMS320C54X only. *}
+.#define SEC_TIC54X_BLOCK 0x10000000
+.
+. {* Conditionally link this section; do not link if there are no
+. references found to any symbol in the section. This is for TI
+. TMS320C54X only. *}
+.#define SEC_TIC54X_CLINK 0x20000000
+.
+. {* Indicate that section has the no read flag set. This happens
+. when memory read flag isn't set. *}
+.#define SEC_COFF_NOREAD 0x40000000
+.
+. {* End of section flags. *}
+.
+. {* Some internal packed boolean fields. *}
+.
+. {* See the vma field. *}
+. unsigned int user_set_vma : 1;
+.
+. {* A mark flag used by some of the linker backends. *}
+. unsigned int linker_mark : 1;
+.
+. {* Another mark flag used by some of the linker backends. Set for
+. output sections that have an input section. *}
+. unsigned int linker_has_input : 1;
+.
+. {* Mark flag used by some linker backends for garbage collection. *}
+. unsigned int gc_mark : 1;
+.
+. {* Section compression status. *}
+. unsigned int compress_status : 2;
+.#define COMPRESS_SECTION_NONE 0
+.#define COMPRESS_SECTION_DONE 1
+.#define DECOMPRESS_SECTION_SIZED 2
+.
+. {* The following flags are used by the ELF linker. *}
+.
+. {* Mark sections which have been allocated to segments. *}
+. unsigned int segment_mark : 1;
+.
+. {* Type of sec_info information. *}
+. unsigned int sec_info_type:3;
+.#define SEC_INFO_TYPE_NONE 0
+.#define SEC_INFO_TYPE_STABS 1
+.#define SEC_INFO_TYPE_MERGE 2
+.#define SEC_INFO_TYPE_EH_FRAME 3
+.#define SEC_INFO_TYPE_JUST_SYMS 4
+.#define SEC_INFO_TYPE_TARGET 5
+.
+. {* Nonzero if this section uses RELA relocations, rather than REL. *}
+. unsigned int use_rela_p:1;
+.
+. {* Bits used by various backends. The generic code doesn't touch
+. these fields. *}
+.
+. unsigned int sec_flg0:1;
+. unsigned int sec_flg1:1;
+. unsigned int sec_flg2:1;
+. unsigned int sec_flg3:1;
+. unsigned int sec_flg4:1;
+. unsigned int sec_flg5: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 octets, as it will be output.
+. Contains a value even if the section has no contents (e.g., the
+. size of <<.bss>>). *}
+. bfd_size_type size;
+.
+. {* For input sections, the original size on disk of the section, in
+. octets. This field should be set for any section whose size is
+. changed by linker relaxation. It is required for sections where
+. the linker relaxation scheme doesn't cache altered section and
+. reloc contents (stabs, eh_frame, SEC_MERGE, some coff relaxing
+. targets), and thus the original size needs to be kept to read the
+. section multiple times. For output sections, rawsize holds the
+. section size calculated on a previous linker relaxation pass. *}
+. bfd_size_type rawsize;
+.
+. {* The compressed size of the section in octets. *}
+. bfd_size_type compressed_size;
+.
+. {* Relaxation table. *}
+. struct relax_table *relax;
+.
+. {* Count of used relaxation table entries. *}
+. int relax_count;
+.
+.
+. {* If this section is going to be output, then this value is the
+. offset in *bytes* into the output section of the first byte in the
+. input section (byte ==> smallest addressable unit on the
+. target). In most cases, if this was going to start at the
+. 100th octet (8-bit quantity) in the output section, this value
+. would be 100. However, if the target byte size is 16 bits
+. (bfd_octets_per_byte is "2"), this value would be 50. *}
+. bfd_vma output_offset;
+.
+. {* The output section through which to map on output. *}
+. struct bfd_section *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. *}
+. void *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;
+.
+. {* Entity size for merging purposes. *}
+. unsigned int entsize;
+.
+. {* Points to the kept section if this section is a link-once section,
+. and is discarded. *}
+. struct bfd_section *kept_section;
+.
+. {* 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;
+.
+. void *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 bfd_symbol *symbol;
+. struct bfd_symbol **symbol_ptr_ptr;
+.
+. {* Early in the link process, map_head and map_tail are used to build
+. a list of input sections attached to an output section. Later,
+. output sections use these fields for a list of bfd_link_order
+. structs. *}
+. union {
+. struct bfd_link_order *link_order;
+. struct bfd_section *s;
+. } map_head, map_tail;
+.} asection;
+.
+.{* Relax table contains information about instructions which can
+. be removed by relaxation -- replacing a long address with a
+. short address. *}
+.struct relax_table {
+. {* Address where bytes may be deleted. *}
+. bfd_vma addr;
+.
+. {* Number of bytes to be deleted. *}
+. int size;
+.};
+.
+.{* Note: the following are provided as inline functions rather than macros
+. because not all callers use the return value. A macro implementation
+. would use a comma expression, eg: "((ptr)->foo = val, TRUE)" and some
+. compilers will complain about comma expressions that have no effect. *}
+.static inline bfd_boolean
+.bfd_set_section_userdata (bfd * abfd ATTRIBUTE_UNUSED, asection * ptr, void * val)
+.{
+. ptr->userdata = val;
+. return TRUE;
+.}
+.
+.static inline bfd_boolean
+.bfd_set_section_vma (bfd * abfd ATTRIBUTE_UNUSED, asection * ptr, bfd_vma val)
+.{
+. ptr->vma = ptr->lma = val;
+. ptr->user_set_vma = TRUE;
+. return TRUE;
+.}
+.
+.static inline bfd_boolean
+.bfd_set_section_alignment (bfd * abfd ATTRIBUTE_UNUSED, asection * ptr, unsigned int val)
+.{
+. ptr->alignment_power = val;
+. return TRUE;
+.}
+.
+.{* 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. *}
+.extern asection _bfd_std_section[4];
+.
+.#define BFD_ABS_SECTION_NAME "*ABS*"
+.#define BFD_UND_SECTION_NAME "*UND*"
+.#define BFD_COM_SECTION_NAME "*COM*"
+.#define BFD_IND_SECTION_NAME "*IND*"
+.
+.{* Pointer to the common section. *}
+.#define bfd_com_section_ptr (&_bfd_std_section[0])
+.{* Pointer to the undefined section. *}
+.#define bfd_und_section_ptr (&_bfd_std_section[1])
+.{* Pointer to the absolute section. *}
+.#define bfd_abs_section_ptr (&_bfd_std_section[2])
+.{* Pointer to the indirect section. *}
+.#define bfd_ind_section_ptr (&_bfd_std_section[3])
+.
+.#define bfd_is_und_section(sec) ((sec) == bfd_und_section_ptr)
+.#define bfd_is_abs_section(sec) ((sec) == bfd_abs_section_ptr)
+.#define bfd_is_ind_section(sec) ((sec) == bfd_ind_section_ptr)
+.
+.#define bfd_is_const_section(SEC) \
+. ( ((SEC) == bfd_abs_section_ptr) \
+. || ((SEC) == bfd_und_section_ptr) \
+. || ((SEC) == bfd_com_section_ptr) \
+. || ((SEC) == bfd_ind_section_ptr))
+.
+.{* Macros to handle insertion and deletion of a bfd's sections. These
+. only handle the list pointers, ie. do not adjust section_count,
+. target_index etc. *}
+.#define bfd_section_list_remove(ABFD, S) \
+. do \
+. { \
+. asection *_s = S; \
+. asection *_next = _s->next; \
+. asection *_prev = _s->prev; \
+. if (_prev) \
+. _prev->next = _next; \
+. else \
+. (ABFD)->sections = _next; \
+. if (_next) \
+. _next->prev = _prev; \
+. else \
+. (ABFD)->section_last = _prev; \
+. } \
+. while (0)
+.#define bfd_section_list_append(ABFD, S) \
+. do \
+. { \
+. asection *_s = S; \
+. bfd *_abfd = ABFD; \
+. _s->next = NULL; \
+. if (_abfd->section_last) \
+. { \
+. _s->prev = _abfd->section_last; \
+. _abfd->section_last->next = _s; \
+. } \
+. else \
+. { \
+. _s->prev = NULL; \
+. _abfd->sections = _s; \
+. } \
+. _abfd->section_last = _s; \
+. } \
+. while (0)
+.#define bfd_section_list_prepend(ABFD, S) \
+. do \
+. { \
+. asection *_s = S; \
+. bfd *_abfd = ABFD; \
+. _s->prev = NULL; \
+. if (_abfd->sections) \
+. { \
+. _s->next = _abfd->sections; \
+. _abfd->sections->prev = _s; \
+. } \
+. else \
+. { \
+. _s->next = NULL; \
+. _abfd->section_last = _s; \
+. } \
+. _abfd->sections = _s; \
+. } \
+. while (0)
+.#define bfd_section_list_insert_after(ABFD, A, S) \
+. do \
+. { \
+. asection *_a = A; \
+. asection *_s = S; \
+. asection *_next = _a->next; \
+. _s->next = _next; \
+. _s->prev = _a; \
+. _a->next = _s; \
+. if (_next) \
+. _next->prev = _s; \
+. else \
+. (ABFD)->section_last = _s; \
+. } \
+. while (0)
+.#define bfd_section_list_insert_before(ABFD, B, S) \
+. do \
+. { \
+. asection *_b = B; \
+. asection *_s = S; \
+. asection *_prev = _b->prev; \
+. _s->prev = _prev; \
+. _s->next = _b; \
+. _b->prev = _s; \
+. if (_prev) \
+. _prev->next = _s; \
+. else \
+. (ABFD)->sections = _s; \
+. } \
+. while (0)
+.#define bfd_section_removed_from_list(ABFD, S) \
+. ((S)->next == NULL ? (ABFD)->section_last != (S) : (S)->next->prev != (S))
+.
+.#define BFD_FAKE_SECTION(SEC, FLAGS, SYM, NAME, IDX) \
+. {* name, id, index, next, prev, flags, user_set_vma, *} \
+. { NAME, IDX, 0, NULL, NULL, FLAGS, 0, \
+. \
+. {* linker_mark, linker_has_input, gc_mark, decompress_status, *} \
+. 0, 0, 1, 0, \
+. \
+. {* segment_mark, sec_info_type, use_rela_p, *} \
+. 0, 0, 0, \
+. \
+. {* sec_flg0, sec_flg1, sec_flg2, sec_flg3, sec_flg4, sec_flg5, *} \
+. 0, 0, 0, 0, 0, 0, \
+. \
+. {* vma, lma, size, rawsize, compressed_size, relax, relax_count, *} \
+. 0, 0, 0, 0, 0, 0, 0, \
+. \
+. {* output_offset, output_section, alignment_power, *} \
+. 0, &SEC, 0, \
+. \
+. {* relocation, orelocation, reloc_count, filepos, rel_filepos, *} \
+. NULL, NULL, 0, 0, 0, \
+. \
+. {* line_filepos, userdata, contents, lineno, lineno_count, *} \
+. 0, NULL, NULL, NULL, 0, \
+. \
+. {* entsize, kept_section, moving_line_filepos, *} \
+. 0, NULL, 0, \
+. \
+. {* target_index, used_by_bfd, constructor_chain, owner, *} \
+. 0, NULL, NULL, NULL, \
+. \
+. {* symbol, symbol_ptr_ptr, *} \
+. (struct bfd_symbol *) SYM, &SEC.symbol, \
+. \
+. {* map_head, map_tail *} \
+. { NULL }, { NULL } \
+. }
+.
+*/
+
+/* We use a macro to initialize the static asymbol structures because
+ traditional C does not permit us to initialize a union member while
+ gcc warns if we don't initialize it. */
+ /* the_bfd, name, value, attr, section [, udata] */
+#ifdef __STDC__
+#define GLOBAL_SYM_INIT(NAME, SECTION) \
+ { 0, NAME, 0, BSF_SECTION_SYM, SECTION, { 0 }}
+#else
+#define GLOBAL_SYM_INIT(NAME, SECTION) \
+ { 0, NAME, 0, BSF_SECTION_SYM, SECTION }
+#endif
+
+/* 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[] =
+{
+ GLOBAL_SYM_INIT (BFD_COM_SECTION_NAME, bfd_com_section_ptr),
+ GLOBAL_SYM_INIT (BFD_UND_SECTION_NAME, bfd_und_section_ptr),
+ GLOBAL_SYM_INIT (BFD_ABS_SECTION_NAME, bfd_abs_section_ptr),
+ GLOBAL_SYM_INIT (BFD_IND_SECTION_NAME, bfd_ind_section_ptr)
+};
+
+#define STD_SECTION(NAME, IDX, FLAGS) \
+ BFD_FAKE_SECTION(_bfd_std_section[IDX], FLAGS, &global_syms[IDX], NAME, IDX)
+
+asection _bfd_std_section[] = {
+ STD_SECTION (BFD_COM_SECTION_NAME, 0, SEC_IS_COMMON),
+ STD_SECTION (BFD_UND_SECTION_NAME, 1, 0),
+ STD_SECTION (BFD_ABS_SECTION_NAME, 2, 0),
+ STD_SECTION (BFD_IND_SECTION_NAME, 3, 0)
+};
+#undef STD_SECTION
+
+/* Initialize an entry in the section hash table. */
+
+struct bfd_hash_entry *
+bfd_section_hash_newfunc (struct bfd_hash_entry *entry,
+ struct bfd_hash_table *table,
+ const char *string)
+{
+ /* Allocate the structure if it has not already been allocated by a
+ subclass. */
+ if (entry == NULL)
+ {
+ entry = (struct bfd_hash_entry *)
+ bfd_hash_allocate (table, sizeof (struct section_hash_entry));
+ if (entry == NULL)
+ return entry;
+ }
+
+ /* Call the allocation method of the superclass. */
+ entry = bfd_hash_newfunc (entry, table, string);
+ if (entry != NULL)
+ memset (&((struct section_hash_entry *) entry)->section, 0,
+ sizeof (asection));
+
+ return entry;
+}
+
+#define section_hash_lookup(table, string, create, copy) \
+ ((struct section_hash_entry *) \
+ bfd_hash_lookup ((table), (string), (create), (copy)))
+
+/* Create a symbol whose only job is to point to this section. This
+ is useful for things like relocs which are relative to the base
+ of a section. */
+
+bfd_boolean
+_bfd_generic_new_section_hook (bfd *abfd, asection *newsect)
+{
+ newsect->symbol = bfd_make_empty_symbol (abfd);
+ if (newsect->symbol == NULL)
+ return FALSE;
+
+ newsect->symbol->name = newsect->name;
+ newsect->symbol->value = 0;
+ newsect->symbol->section = newsect;
+ newsect->symbol->flags = BSF_SECTION_SYM;
+
+ newsect->symbol_ptr_ptr = &newsect->symbol;
+ return TRUE;
+}
+
+/* Initializes a new section. NEWSECT->NAME is already set. */
+
+static asection *
+bfd_section_init (bfd *abfd, asection *newsect)
+{
+ static int section_id = 0x10; /* id 0 to 3 used by STD_SECTION. */
+
+ newsect->id = section_id;
+ newsect->index = abfd->section_count;
+ newsect->owner = abfd;
+
+ if (! BFD_SEND (abfd, _new_section_hook, (abfd, newsect)))
+ return NULL;
+
+ section_id++;
+ abfd->section_count++;
+ bfd_section_list_append (abfd, newsect);
+ return newsect;
+}
+
+/*
+DOCDD
+INODE
+section prototypes, , typedef asection, Sections
+SUBSECTION
+ Section prototypes
+
+These are the functions exported by the section handling part of BFD.
+*/
+
+/*
+FUNCTION
+ bfd_section_list_clear
+
+SYNOPSIS
+ void bfd_section_list_clear (bfd *);
+
+DESCRIPTION
+ Clears the section list, and also resets the section count and
+ hash table entries.
+*/
+
+void
+bfd_section_list_clear (bfd *abfd)
+{
+ abfd->sections = NULL;
+ abfd->section_last = NULL;
+ abfd->section_count = 0;
+ memset (abfd->section_htab.table, 0,
+ abfd->section_htab.size * sizeof (struct bfd_hash_entry *));
+ abfd->section_htab.count = 0;
+}
+
+/*
+FUNCTION
+ bfd_get_section_by_name
+
+SYNOPSIS
+ asection *bfd_get_section_by_name (bfd *abfd, const char *name);
+
+DESCRIPTION
+ Return the most recently created section attached to @var{abfd}
+ named @var{name}. Return NULL if no such section exists.
+*/
+
+asection *
+bfd_get_section_by_name (bfd *abfd, const char *name)
+{
+ struct section_hash_entry *sh;
+
+ sh = section_hash_lookup (&abfd->section_htab, name, FALSE, FALSE);
+ if (sh != NULL)
+ return &sh->section;
+
+ return NULL;
+}
+
+/*
+FUNCTION
+ bfd_get_next_section_by_name
+
+SYNOPSIS
+ asection *bfd_get_next_section_by_name (asection *sec);
+
+DESCRIPTION
+ Given @var{sec} is a section returned by @code{bfd_get_section_by_name},
+ return the next most recently created section attached to the same
+ BFD with the same name. Return NULL if no such section exists.
+*/
+
+asection *
+bfd_get_next_section_by_name (asection *sec)
+{
+ struct section_hash_entry *sh;
+ const char *name;
+ unsigned long hash;
+
+ sh = ((struct section_hash_entry *)
+ ((char *) sec - offsetof (struct section_hash_entry, section)));
+
+ hash = sh->root.hash;
+ name = sec->name;
+ for (sh = (struct section_hash_entry *) sh->root.next;
+ sh != NULL;
+ sh = (struct section_hash_entry *) sh->root.next)
+ if (sh->root.hash == hash
+ && strcmp (sh->root.string, name) == 0)
+ return &sh->section;
+
+ return NULL;
+}
+
+/*
+FUNCTION
+ bfd_get_linker_section
+
+SYNOPSIS
+ asection *bfd_get_linker_section (bfd *abfd, const char *name);
+
+DESCRIPTION
+ Return the linker created section attached to @var{abfd}
+ named @var{name}. Return NULL if no such section exists.
+*/
+
+asection *
+bfd_get_linker_section (bfd *abfd, const char *name)
+{
+ asection *sec = bfd_get_section_by_name (abfd, name);
+
+ while (sec != NULL && (sec->flags & SEC_LINKER_CREATED) == 0)
+ sec = bfd_get_next_section_by_name (sec);
+ return sec;
+}
+
+/*
+FUNCTION
+ bfd_get_section_by_name_if
+
+SYNOPSIS
+ asection *bfd_get_section_by_name_if
+ (bfd *abfd,
+ const char *name,
+ bfd_boolean (*func) (bfd *abfd, asection *sect, void *obj),
+ void *obj);
+
+DESCRIPTION
+ Call the provided function @var{func} for each section
+ attached to the BFD @var{abfd} whose name matches @var{name},
+ passing @var{obj} as an argument. The function will be called
+ as if by
+
+| func (abfd, the_section, obj);
+
+ It returns the first section for which @var{func} returns true,
+ otherwise <<NULL>>.
+
+*/
+
+asection *
+bfd_get_section_by_name_if (bfd *abfd, const char *name,
+ bfd_boolean (*operation) (bfd *,
+ asection *,
+ void *),
+ void *user_storage)
+{
+ struct section_hash_entry *sh;
+ unsigned long hash;
+
+ sh = section_hash_lookup (&abfd->section_htab, name, FALSE, FALSE);
+ if (sh == NULL)
+ return NULL;
+
+ hash = sh->root.hash;
+ do
+ {
+ if ((*operation) (abfd, &sh->section, user_storage))
+ return &sh->section;
+ sh = (struct section_hash_entry *) sh->root.next;
+ }
+ while (sh != NULL && sh->root.hash == hash
+ && strcmp (sh->root.string, name) == 0);
+
+ return NULL;
+}
+
+/*
+FUNCTION
+ bfd_get_unique_section_name
+
+SYNOPSIS
+ char *bfd_get_unique_section_name
+ (bfd *abfd, const char *templat, int *count);
+
+DESCRIPTION
+ Invent a section name that is unique in @var{abfd} by tacking
+ a dot and a digit suffix onto the original @var{templat}. If
+ @var{count} is non-NULL, then it specifies the first number
+ tried as a suffix to generate a unique name. The value
+ pointed to by @var{count} will be incremented in this case.
+*/
+
+char *
+bfd_get_unique_section_name (bfd *abfd, const char *templat, int *count)
+{
+ int num;
+ unsigned int len;
+ char *sname;
+
+ len = strlen (templat);
+ sname = (char *) bfd_malloc (len + 8);
+ if (sname == NULL)
+ return NULL;
+ memcpy (sname, templat, len);
+ num = 1;
+ if (count != NULL)
+ num = *count;
+
+ do
+ {
+ /* If we have a million sections, something is badly wrong. */
+ if (num > 999999)
+ abort ();
+ sprintf (sname + len, ".%d", num++);
+ }
+ while (section_hash_lookup (&abfd->section_htab, sname, FALSE, FALSE));
+
+ if (count != NULL)
+ *count = num;
+ return sname;
+}
+
+/*
+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 (bfd *abfd, const char *name)
+{
+ asection *newsect;
+
+ if (abfd->output_has_begun)
+ {
+ bfd_set_error (bfd_error_invalid_operation);
+ return NULL;
+ }
+
+ if (strcmp (name, BFD_ABS_SECTION_NAME) == 0)
+ newsect = bfd_abs_section_ptr;
+ else if (strcmp (name, BFD_COM_SECTION_NAME) == 0)
+ newsect = bfd_com_section_ptr;
+ else if (strcmp (name, BFD_UND_SECTION_NAME) == 0)
+ newsect = bfd_und_section_ptr;
+ else if (strcmp (name, BFD_IND_SECTION_NAME) == 0)
+ newsect = bfd_ind_section_ptr;
+ else
+ {
+ struct section_hash_entry *sh;
+
+ sh = section_hash_lookup (&abfd->section_htab, name, TRUE, FALSE);
+ if (sh == NULL)
+ return NULL;
+
+ newsect = &sh->section;
+ if (newsect->name != NULL)
+ {
+ /* Section already exists. */
+ return newsect;
+ }
+
+ newsect->name = name;
+ return bfd_section_init (abfd, newsect);
+ }
+
+ /* Call new_section_hook when "creating" the standard abs, com, und
+ and ind sections to tack on format specific section data.
+ Also, create a proper section symbol. */
+ if (! BFD_SEND (abfd, _new_section_hook, (abfd, newsect)))
+ return NULL;
+ return newsect;
+}
+
+/*
+FUNCTION
+ bfd_make_section_anyway_with_flags
+
+SYNOPSIS
+ asection *bfd_make_section_anyway_with_flags
+ (bfd *abfd, const char *name, flagword flags);
+
+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. Also set the attributes of the
+ new section to the value @var{flags}.
+
+ 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_with_flags (bfd *abfd, const char *name,
+ flagword flags)
+{
+ struct section_hash_entry *sh;
+ asection *newsect;
+
+ if (abfd->output_has_begun)
+ {
+ bfd_set_error (bfd_error_invalid_operation);
+ return NULL;
+ }
+
+ sh = section_hash_lookup (&abfd->section_htab, name, TRUE, FALSE);
+ if (sh == NULL)
+ return NULL;
+
+ newsect = &sh->section;
+ if (newsect->name != NULL)
+ {
+ /* We are making a section of the same name. Put it in the
+ section hash table. Even though we can't find it directly by a
+ hash lookup, we'll be able to find the section by traversing
+ sh->root.next quicker than looking at all the bfd sections. */
+ struct section_hash_entry *new_sh;
+ new_sh = (struct section_hash_entry *)
+ bfd_section_hash_newfunc (NULL, &abfd->section_htab, name);
+ if (new_sh == NULL)
+ return NULL;
+
+ new_sh->root = sh->root;
+ sh->root.next = &new_sh->root;
+ newsect = &new_sh->section;
+ }
+
+ newsect->flags = flags;
+ newsect->name = name;
+ return bfd_section_init (abfd, newsect);
+}
+
+/*
+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 (bfd *abfd, const char *name)
+{
+ return bfd_make_section_anyway_with_flags (abfd, name, 0);
+}
+
+/*
+FUNCTION
+ bfd_make_section_with_flags
+
+SYNOPSIS
+ asection *bfd_make_section_with_flags
+ (bfd *, const char *name, flagword flags);
+
+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}. Also set the attributes of the new section to
+ the value @var{flags}. If there is an error, return <<NULL>> and set
+ <<bfd_error>>.
+*/
+
+asection *
+bfd_make_section_with_flags (bfd *abfd, const char *name,
+ flagword flags)
+{
+ struct section_hash_entry *sh;
+ asection *newsect;
+
+ if (abfd->output_has_begun)
+ {
+ bfd_set_error (bfd_error_invalid_operation);
+ return NULL;
+ }
+
+ if (strcmp (name, BFD_ABS_SECTION_NAME) == 0
+ || strcmp (name, BFD_COM_SECTION_NAME) == 0
+ || strcmp (name, BFD_UND_SECTION_NAME) == 0
+ || strcmp (name, BFD_IND_SECTION_NAME) == 0)
+ return NULL;
+
+ sh = section_hash_lookup (&abfd->section_htab, name, TRUE, FALSE);
+ if (sh == NULL)
+ return NULL;
+
+ newsect = &sh->section;
+ if (newsect->name != NULL)
+ {
+ /* Section already exists. */
+ return NULL;
+ }
+
+ newsect->name = name;
+ newsect->flags = flags;
+ return bfd_section_init (abfd, 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 (bfd *abfd, const char *name)
+{
+ return bfd_make_section_with_flags (abfd, name, 0);
+}
+
+/*
+FUNCTION
+ bfd_set_section_flags
+
+SYNOPSIS
+ bfd_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.
+
+*/
+
+bfd_boolean
+bfd_set_section_flags (bfd *abfd ATTRIBUTE_UNUSED,
+ sec_ptr section,
+ flagword flags)
+{
+ section->flags = flags;
+ return TRUE;
+}
+
+/*
+FUNCTION
+ bfd_rename_section
+
+SYNOPSIS
+ void bfd_rename_section
+ (bfd *abfd, asection *sec, const char *newname);
+
+DESCRIPTION
+ Rename section @var{sec} in @var{abfd} to @var{newname}.
+*/
+
+void
+bfd_rename_section (bfd *abfd, sec_ptr sec, const char *newname)
+{
+ struct section_hash_entry *sh;
+
+ sh = (struct section_hash_entry *)
+ ((char *) sec - offsetof (struct section_hash_entry, section));
+ sh->section.name = newname;
+ bfd_hash_rename (&abfd->section_htab, newname, &sh->root);
+}
+
+/*
+FUNCTION
+ bfd_map_over_sections
+
+SYNOPSIS
+ void bfd_map_over_sections
+ (bfd *abfd,
+ void (*func) (bfd *abfd, asection *sect, void *obj),
+ void *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 preferred method for iterating over sections; an
+ alternative would be to use a loop:
+
+| asection *p;
+| for (p = abfd->sections; p != NULL; p = p->next)
+| func (abfd, p, ...)
+
+*/
+
+void
+bfd_map_over_sections (bfd *abfd,
+ void (*operation) (bfd *, asection *, void *),
+ void *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_sections_find_if
+
+SYNOPSIS
+ asection *bfd_sections_find_if
+ (bfd *abfd,
+ bfd_boolean (*operation) (bfd *abfd, asection *sect, void *obj),
+ void *obj);
+
+DESCRIPTION
+ Call the provided function @var{operation} for each section
+ attached to the BFD @var{abfd}, passing @var{obj} as an
+ argument. The function will be called as if by
+
+| operation (abfd, the_section, obj);
+
+ It returns the first section for which @var{operation} returns true.
+
+*/
+
+asection *
+bfd_sections_find_if (bfd *abfd,
+ bfd_boolean (*operation) (bfd *, asection *, void *),
+ void *user_storage)
+{
+ asection *sect;
+
+ for (sect = abfd->sections; sect != NULL; sect = sect->next)
+ if ((*operation) (abfd, sect, user_storage))
+ break;
+
+ return sect;
+}
+
+/*
+FUNCTION
+ bfd_set_section_size
+
+SYNOPSIS
+ bfd_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.
+
+*/
+
+bfd_boolean
+bfd_set_section_size (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->size = val;
+ return TRUE;
+}
+
+/*
+FUNCTION
+ bfd_set_section_contents
+
+SYNOPSIS
+ bfd_boolean bfd_set_section_contents
+ (bfd *abfd, asection *section, const void *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} octets.
+
+ 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>>.
+
+*/
+
+bfd_boolean
+bfd_set_section_contents (bfd *abfd,
+ sec_ptr section,
+ const void *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;
+ }
+
+ sz = section->size;
+ if ((bfd_size_type) offset > sz
+ || count > sz
+ || offset + count > sz
+ || count != (size_t) count)
+ {
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+
+ if (!bfd_write_p (abfd))
+ {
+ bfd_set_error (bfd_error_invalid_operation);
+ return FALSE;
+ }
+
+ /* Record a copy of the data in memory if desired. */
+ if (section->contents
+ && location != section->contents + offset)
+ memcpy (section->contents + offset, location, (size_t) count);
+
+ 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
+ bfd_boolean bfd_get_section_contents
+ (bfd *abfd, asection *section, void *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>>.
+
+*/
+bfd_boolean
+bfd_get_section_contents (bfd *abfd,
+ sec_ptr section,
+ void *location,
+ file_ptr offset,
+ bfd_size_type count)
+{
+ bfd_size_type sz;
+
+ if (section->flags & SEC_CONSTRUCTOR)
+ {
+ memset (location, 0, (size_t) count);
+ return TRUE;
+ }
+
+ if (abfd->direction != write_direction && section->rawsize != 0)
+ sz = section->rawsize;
+ else
+ sz = section->size;
+ if ((bfd_size_type) offset > sz
+ || count > sz
+ || offset + count > sz
+ || count != (size_t) count)
+ {
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+
+ if (count == 0)
+ /* Don't bother. */
+ return TRUE;
+
+ if ((section->flags & SEC_HAS_CONTENTS) == 0)
+ {
+ memset (location, 0, (size_t) count);
+ return TRUE;
+ }
+
+ if ((section->flags & SEC_IN_MEMORY) != 0)
+ {
+ if (section->contents == NULL)
+ {
+ /* This can happen because of errors earlier on in the linking process.
+ We do not want to seg-fault here, so clear the flag and return an
+ error code. */
+ section->flags &= ~ SEC_IN_MEMORY;
+ bfd_set_error (bfd_error_invalid_operation);
+ return FALSE;
+ }
+
+ memmove (location, section->contents + offset, (size_t) count);
+ return TRUE;
+ }
+
+ return BFD_SEND (abfd, _bfd_get_section_contents,
+ (abfd, section, location, offset, count));
+}
+
+/*
+FUNCTION
+ bfd_malloc_and_get_section
+
+SYNOPSIS
+ bfd_boolean bfd_malloc_and_get_section
+ (bfd *abfd, asection *section, bfd_byte **buf);
+
+DESCRIPTION
+ Read all data from @var{section} in BFD @var{abfd}
+ into a buffer, *@var{buf}, malloc'd by this function.
+*/
+
+bfd_boolean
+bfd_malloc_and_get_section (bfd *abfd, sec_ptr sec, bfd_byte **buf)
+{
+ *buf = NULL;
+ return bfd_get_full_section_contents (abfd, sec, buf);
+}
+/*
+FUNCTION
+ bfd_copy_private_section_data
+
+SYNOPSIS
+ bfd_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_generic_is_group_section
+
+SYNOPSIS
+ bfd_boolean bfd_generic_is_group_section (bfd *, const asection *sec);
+
+DESCRIPTION
+ Returns TRUE if @var{sec} is a member of a group.
+*/
+
+bfd_boolean
+bfd_generic_is_group_section (bfd *abfd ATTRIBUTE_UNUSED,
+ const asection *sec ATTRIBUTE_UNUSED)
+{
+ return FALSE;
+}
+
+/*
+FUNCTION
+ bfd_generic_discard_group
+
+SYNOPSIS
+ bfd_boolean bfd_generic_discard_group (bfd *abfd, asection *group);
+
+DESCRIPTION
+ Remove all members of @var{group} from the output.
+*/
+
+bfd_boolean
+bfd_generic_discard_group (bfd *abfd ATTRIBUTE_UNUSED,
+ asection *group ATTRIBUTE_UNUSED)
+{
+ return TRUE;
+}
diff --git a/bfd/simple.c b/bfd/simple.c
new file mode 100644
index 0000000..ca64101
--- /dev/null
+++ b/bfd/simple.c
@@ -0,0 +1,285 @@
+/* simple.c -- BFD simple client routines
+ Copyright (C) 2002-2014 Free Software Foundation, Inc.
+ Contributed by MontaVista Software, 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+#include "bfdlink.h"
+
+static bfd_boolean
+simple_dummy_warning (struct bfd_link_info *link_info ATTRIBUTE_UNUSED,
+ const char *warning ATTRIBUTE_UNUSED,
+ const char *symbol ATTRIBUTE_UNUSED,
+ bfd *abfd ATTRIBUTE_UNUSED,
+ asection *section ATTRIBUTE_UNUSED,
+ bfd_vma address ATTRIBUTE_UNUSED)
+{
+ return TRUE;
+}
+
+static bfd_boolean
+simple_dummy_undefined_symbol (struct bfd_link_info *link_info ATTRIBUTE_UNUSED,
+ const char *name ATTRIBUTE_UNUSED,
+ bfd *abfd ATTRIBUTE_UNUSED,
+ asection *section ATTRIBUTE_UNUSED,
+ bfd_vma address ATTRIBUTE_UNUSED,
+ bfd_boolean fatal ATTRIBUTE_UNUSED)
+{
+ return TRUE;
+}
+
+static bfd_boolean
+simple_dummy_reloc_overflow (struct bfd_link_info *link_info ATTRIBUTE_UNUSED,
+ struct bfd_link_hash_entry *entry ATTRIBUTE_UNUSED,
+ const char *name ATTRIBUTE_UNUSED,
+ const char *reloc_name ATTRIBUTE_UNUSED,
+ bfd_vma addend ATTRIBUTE_UNUSED,
+ bfd *abfd ATTRIBUTE_UNUSED,
+ asection *section ATTRIBUTE_UNUSED,
+ bfd_vma address ATTRIBUTE_UNUSED)
+{
+ return TRUE;
+}
+
+static bfd_boolean
+simple_dummy_reloc_dangerous (struct bfd_link_info *link_info ATTRIBUTE_UNUSED,
+ const char *message ATTRIBUTE_UNUSED,
+ bfd *abfd ATTRIBUTE_UNUSED,
+ asection *section ATTRIBUTE_UNUSED,
+ bfd_vma address ATTRIBUTE_UNUSED)
+{
+ return TRUE;
+}
+
+static bfd_boolean
+simple_dummy_unattached_reloc (struct bfd_link_info *link_info ATTRIBUTE_UNUSED,
+ const char *name ATTRIBUTE_UNUSED,
+ bfd *abfd ATTRIBUTE_UNUSED,
+ asection *section ATTRIBUTE_UNUSED,
+ bfd_vma address ATTRIBUTE_UNUSED)
+{
+ return TRUE;
+}
+
+static bfd_boolean
+simple_dummy_multiple_definition (struct bfd_link_info *link_info ATTRIBUTE_UNUSED,
+ struct bfd_link_hash_entry *h ATTRIBUTE_UNUSED,
+ bfd *nbfd ATTRIBUTE_UNUSED,
+ asection *nsec ATTRIBUTE_UNUSED,
+ bfd_vma nval ATTRIBUTE_UNUSED)
+{
+ return TRUE;
+}
+
+static void
+simple_dummy_einfo (const char *fmt ATTRIBUTE_UNUSED, ...)
+{
+}
+
+struct saved_output_info
+{
+ bfd_vma offset;
+ asection *section;
+};
+
+struct saved_offsets
+{
+ int section_count;
+ struct saved_output_info *sections;
+};
+
+/* The sections in ABFD may already have output sections and offsets
+ set if we are here during linking.
+
+ DWARF-2 specifies offsets into debug sections in many cases and
+ bfd_simple_get_relocated_section_contents is called to relocate
+ debug info for a single relocatable object file. So we want
+ offsets relative to that object file's sections, not offsets in the
+ output file. For that reason, reset a debug section->output_offset
+ to zero.
+
+ If not called during linking then set section->output_section to
+ point back to the input section, because output_section must not be
+ NULL when calling the relocation routines.
+
+ Save the original output offset and section to restore later. */
+
+static void
+simple_save_output_info (bfd *abfd ATTRIBUTE_UNUSED,
+ asection *section,
+ void *ptr)
+{
+ struct saved_offsets *saved_offsets = (struct saved_offsets *) ptr;
+ struct saved_output_info *output_info;
+
+ output_info = &saved_offsets->sections[section->index];
+ output_info->offset = section->output_offset;
+ output_info->section = section->output_section;
+ if ((section->flags & SEC_DEBUGGING) != 0
+ || section->output_section == NULL)
+ {
+ section->output_offset = 0;
+ section->output_section = section;
+ }
+}
+
+static void
+simple_restore_output_info (bfd *abfd ATTRIBUTE_UNUSED,
+ asection *section,
+ void *ptr)
+{
+ struct saved_offsets *saved_offsets = (struct saved_offsets *) ptr;
+ struct saved_output_info *output_info;
+
+ if (section->index >= saved_offsets->section_count)
+ return;
+
+ output_info = &saved_offsets->sections[section->index];
+ section->output_offset = output_info->offset;
+ section->output_section = output_info->section;
+}
+
+/*
+FUNCTION
+ bfd_simple_relocate_secton
+
+SYNOPSIS
+ bfd_byte *bfd_simple_get_relocated_section_contents
+ (bfd *abfd, asection *sec, bfd_byte *outbuf, asymbol **symbol_table);
+
+DESCRIPTION
+ Returns the relocated contents of section @var{sec}. The symbols in
+ @var{symbol_table} will be used, or the symbols from @var{abfd} if
+ @var{symbol_table} is NULL. The output offsets for debug sections will
+ be temporarily reset to 0. The result will be stored at @var{outbuf}
+ or allocated with @code{bfd_malloc} if @var{outbuf} is @code{NULL}.
+
+ Returns @code{NULL} on a fatal error; ignores errors applying
+ particular relocations.
+*/
+
+bfd_byte *
+bfd_simple_get_relocated_section_contents (bfd *abfd,
+ asection *sec,
+ bfd_byte *outbuf,
+ asymbol **symbol_table)
+{
+ struct bfd_link_info link_info;
+ struct bfd_link_order link_order;
+ struct bfd_link_callbacks callbacks;
+ bfd_byte *contents, *data;
+ int storage_needed;
+ struct saved_offsets saved_offsets;
+ bfd *link_next;
+
+ /* Don't apply relocation on executable and shared library. See
+ PR 4756. */
+ if ((abfd->flags & (HAS_RELOC | EXEC_P | DYNAMIC)) != HAS_RELOC
+ || ! (sec->flags & SEC_RELOC))
+ {
+ contents = outbuf;
+ if (!bfd_get_full_section_contents (abfd, sec, &contents))
+ return NULL;
+ return contents;
+ }
+
+ /* In order to use bfd_get_relocated_section_contents, we need
+ to forge some data structures that it expects. */
+
+ /* Fill in the bare minimum number of fields for our purposes. */
+ memset (&link_info, 0, sizeof (link_info));
+ link_info.output_bfd = abfd;
+ link_info.input_bfds = abfd;
+ link_info.input_bfds_tail = &abfd->link.next;
+
+ link_next = abfd->link.next;
+ abfd->link.next = NULL;
+ link_info.hash = _bfd_generic_link_hash_table_create (abfd);
+ link_info.callbacks = &callbacks;
+ callbacks.warning = simple_dummy_warning;
+ callbacks.undefined_symbol = simple_dummy_undefined_symbol;
+ callbacks.reloc_overflow = simple_dummy_reloc_overflow;
+ callbacks.reloc_dangerous = simple_dummy_reloc_dangerous;
+ callbacks.unattached_reloc = simple_dummy_unattached_reloc;
+ callbacks.multiple_definition = simple_dummy_multiple_definition;
+ callbacks.einfo = simple_dummy_einfo;
+
+ memset (&link_order, 0, sizeof (link_order));
+ link_order.next = NULL;
+ link_order.type = bfd_indirect_link_order;
+ link_order.offset = 0;
+ link_order.size = sec->size;
+ link_order.u.indirect.section = sec;
+
+ data = NULL;
+ if (outbuf == NULL)
+ {
+ bfd_size_type amt = sec->rawsize > sec->size ? sec->rawsize : sec->size;
+ data = (bfd_byte *) bfd_malloc (amt);
+ if (data == NULL)
+ {
+ _bfd_generic_link_hash_table_free (abfd);
+ abfd->link.next = link_next;
+ return NULL;
+ }
+ outbuf = data;
+ }
+
+ saved_offsets.section_count = abfd->section_count;
+ saved_offsets.sections = malloc (sizeof (*saved_offsets.sections)
+ * saved_offsets.section_count);
+ if (saved_offsets.sections == NULL)
+ {
+ if (data)
+ free (data);
+ _bfd_generic_link_hash_table_free (abfd);
+ abfd->link.next = link_next;
+ return NULL;
+ }
+ bfd_map_over_sections (abfd, simple_save_output_info, &saved_offsets);
+
+ if (symbol_table == NULL)
+ {
+ _bfd_generic_link_add_symbols (abfd, &link_info);
+
+ storage_needed = bfd_get_symtab_upper_bound (abfd);
+ symbol_table = (asymbol **) bfd_malloc (storage_needed);
+ bfd_canonicalize_symtab (abfd, symbol_table);
+ }
+ else
+ storage_needed = 0;
+
+ contents = bfd_get_relocated_section_contents (abfd,
+ &link_info,
+ &link_order,
+ outbuf,
+ 0,
+ symbol_table);
+ if (contents == NULL && data != NULL)
+ free (data);
+
+ bfd_map_over_sections (abfd, simple_restore_output_info, &saved_offsets);
+ free (saved_offsets.sections);
+
+ _bfd_generic_link_hash_table_free (abfd);
+ abfd->link.next = link_next;
+ return contents;
+}
diff --git a/bfd/som.c b/bfd/som.c
new file mode 100644
index 0000000..513e4fa
--- /dev/null
+++ b/bfd/som.c
@@ -0,0 +1,6814 @@
+/* bfd back-end for HP PA-RISC SOM objects.
+ Copyright (C) 1990-2014 Free Software Foundation, Inc.
+
+ Contributed by the Center for Software Science at the
+ 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
+ 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "alloca-conf.h"
+#include "bfd.h"
+
+#include "libbfd.h"
+#include "som.h"
+#include "safe-ctype.h"
+#include "som/reloc.h"
+#include "aout/ar.h"
+
+static bfd_reloc_status_type hppa_som_reloc
+ (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
+static bfd_boolean som_mkobject (bfd *);
+static bfd_boolean som_is_space (asection *);
+static bfd_boolean som_is_subspace (asection *);
+static int compare_subspaces (const void *, const void *);
+static unsigned long som_compute_checksum (struct som_external_header *);
+static bfd_boolean som_build_and_write_symbol_table (bfd *);
+static unsigned int som_slurp_symbol_table (bfd *);
+
+/* 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) &~ ((unsigned long) (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
+{
+ const 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;
+ unsigned int secondary_def;
+ unsigned int is_comdat;
+ unsigned int is_common;
+ unsigned int dup_common;
+};
+
+/* 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;
+ const 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_PLABEL. */
+ { 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 */
+ { 0, "" }, /* 0x2e */
+ { 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_SHORT_PCREL_MODE. */
+ { 0, "" }, /* 0x3e */
+ /* R_LONG_PCREL_MODE. */
+ { 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_DATA_GPREL. */
+ { 0, "L4=Sd=" }, /* 0x72 */
+ /* R_RESERVED. */
+ { 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_AUX_UNWIND. */
+ { 0,"Sd=Ve=Ee=" }, /* 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, "Eb=Sd=Ve=" }, /* 0xda */
+ /* R_LINETAB_ESC. */
+ { 0, "Eb=Mb=" }, /* 0xdb */
+ /* R_LTP_OVERRIDE. */
+ { 0, "" }, /* 0xdc */
+ /* R_COMMENT. */
+ { 0, "Ob=Vf=" }, /* 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). */
+
+/* And these first appeared in hpux10. */
+#ifndef R_SHORT_PCREL_MODE
+#define NO_PCREL_MODES
+#define R_SHORT_PCREL_MODE 0x3e
+#endif
+
+#define SOM_HOWTO(TYPE, NAME) \
+ HOWTO(TYPE, 0, 0, 32, FALSE, 0, 0, hppa_som_reloc, NAME, FALSE, 0, 0, FALSE)
+
+static reloc_howto_type som_hppa_howto_table[] =
+{
+ SOM_HOWTO (R_NO_RELOCATION, "R_NO_RELOCATION"),
+ SOM_HOWTO (R_NO_RELOCATION, "R_NO_RELOCATION"),
+ SOM_HOWTO (R_NO_RELOCATION, "R_NO_RELOCATION"),
+ SOM_HOWTO (R_NO_RELOCATION, "R_NO_RELOCATION"),
+ SOM_HOWTO (R_NO_RELOCATION, "R_NO_RELOCATION"),
+ SOM_HOWTO (R_NO_RELOCATION, "R_NO_RELOCATION"),
+ SOM_HOWTO (R_NO_RELOCATION, "R_NO_RELOCATION"),
+ SOM_HOWTO (R_NO_RELOCATION, "R_NO_RELOCATION"),
+ SOM_HOWTO (R_NO_RELOCATION, "R_NO_RELOCATION"),
+ SOM_HOWTO (R_NO_RELOCATION, "R_NO_RELOCATION"),
+ SOM_HOWTO (R_NO_RELOCATION, "R_NO_RELOCATION"),
+ SOM_HOWTO (R_NO_RELOCATION, "R_NO_RELOCATION"),
+ SOM_HOWTO (R_NO_RELOCATION, "R_NO_RELOCATION"),
+ SOM_HOWTO (R_NO_RELOCATION, "R_NO_RELOCATION"),
+ SOM_HOWTO (R_NO_RELOCATION, "R_NO_RELOCATION"),
+ SOM_HOWTO (R_NO_RELOCATION, "R_NO_RELOCATION"),
+ SOM_HOWTO (R_NO_RELOCATION, "R_NO_RELOCATION"),
+ SOM_HOWTO (R_NO_RELOCATION, "R_NO_RELOCATION"),
+ SOM_HOWTO (R_NO_RELOCATION, "R_NO_RELOCATION"),
+ SOM_HOWTO (R_NO_RELOCATION, "R_NO_RELOCATION"),
+ SOM_HOWTO (R_NO_RELOCATION, "R_NO_RELOCATION"),
+ SOM_HOWTO (R_NO_RELOCATION, "R_NO_RELOCATION"),
+ SOM_HOWTO (R_NO_RELOCATION, "R_NO_RELOCATION"),
+ SOM_HOWTO (R_NO_RELOCATION, "R_NO_RELOCATION"),
+ SOM_HOWTO (R_NO_RELOCATION, "R_NO_RELOCATION"),
+ SOM_HOWTO (R_NO_RELOCATION, "R_NO_RELOCATION"),
+ SOM_HOWTO (R_NO_RELOCATION, "R_NO_RELOCATION"),
+ SOM_HOWTO (R_NO_RELOCATION, "R_NO_RELOCATION"),
+ SOM_HOWTO (R_NO_RELOCATION, "R_NO_RELOCATION"),
+ SOM_HOWTO (R_NO_RELOCATION, "R_NO_RELOCATION"),
+ SOM_HOWTO (R_NO_RELOCATION, "R_NO_RELOCATION"),
+ SOM_HOWTO (R_NO_RELOCATION, "R_NO_RELOCATION"),
+ SOM_HOWTO (R_ZEROES, "R_ZEROES"),
+ SOM_HOWTO (R_ZEROES, "R_ZEROES"),
+ SOM_HOWTO (R_UNINIT, "R_UNINIT"),
+ SOM_HOWTO (R_UNINIT, "R_UNINIT"),
+ SOM_HOWTO (R_RELOCATION, "R_RELOCATION"),
+ SOM_HOWTO (R_DATA_ONE_SYMBOL, "R_DATA_ONE_SYMBOL"),
+ SOM_HOWTO (R_DATA_ONE_SYMBOL, "R_DATA_ONE_SYMBOL"),
+ SOM_HOWTO (R_DATA_PLABEL, "R_DATA_PLABEL"),
+ SOM_HOWTO (R_DATA_PLABEL, "R_DATA_PLABEL"),
+ SOM_HOWTO (R_SPACE_REF, "R_SPACE_REF"),
+ SOM_HOWTO (R_REPEATED_INIT, "REPEATED_INIT"),
+ SOM_HOWTO (R_REPEATED_INIT, "REPEATED_INIT"),
+ SOM_HOWTO (R_REPEATED_INIT, "REPEATED_INIT"),
+ SOM_HOWTO (R_REPEATED_INIT, "REPEATED_INIT"),
+ SOM_HOWTO (R_RESERVED, "R_RESERVED"),
+ SOM_HOWTO (R_RESERVED, "R_RESERVED"),
+ SOM_HOWTO (R_PCREL_CALL, "R_PCREL_CALL"),
+ SOM_HOWTO (R_PCREL_CALL, "R_PCREL_CALL"),
+ SOM_HOWTO (R_PCREL_CALL, "R_PCREL_CALL"),
+ SOM_HOWTO (R_PCREL_CALL, "R_PCREL_CALL"),
+ SOM_HOWTO (R_PCREL_CALL, "R_PCREL_CALL"),
+ SOM_HOWTO (R_PCREL_CALL, "R_PCREL_CALL"),
+ SOM_HOWTO (R_PCREL_CALL, "R_PCREL_CALL"),
+ SOM_HOWTO (R_PCREL_CALL, "R_PCREL_CALL"),
+ SOM_HOWTO (R_PCREL_CALL, "R_PCREL_CALL"),
+ SOM_HOWTO (R_PCREL_CALL, "R_PCREL_CALL"),
+ SOM_HOWTO (R_PCREL_CALL, "R_PCREL_CALL"),
+ SOM_HOWTO (R_PCREL_CALL, "R_PCREL_CALL"),
+ SOM_HOWTO (R_PCREL_CALL, "R_PCREL_CALL"),
+ SOM_HOWTO (R_PCREL_CALL, "R_PCREL_CALL"),
+ SOM_HOWTO (R_SHORT_PCREL_MODE, "R_SHORT_PCREL_MODE"),
+ SOM_HOWTO (R_LONG_PCREL_MODE, "R_LONG_PCREL_MODE"),
+ SOM_HOWTO (R_ABS_CALL, "R_ABS_CALL"),
+ SOM_HOWTO (R_ABS_CALL, "R_ABS_CALL"),
+ SOM_HOWTO (R_ABS_CALL, "R_ABS_CALL"),
+ SOM_HOWTO (R_ABS_CALL, "R_ABS_CALL"),
+ SOM_HOWTO (R_ABS_CALL, "R_ABS_CALL"),
+ SOM_HOWTO (R_ABS_CALL, "R_ABS_CALL"),
+ SOM_HOWTO (R_ABS_CALL, "R_ABS_CALL"),
+ SOM_HOWTO (R_ABS_CALL, "R_ABS_CALL"),
+ SOM_HOWTO (R_ABS_CALL, "R_ABS_CALL"),
+ SOM_HOWTO (R_ABS_CALL, "R_ABS_CALL"),
+ SOM_HOWTO (R_ABS_CALL, "R_ABS_CALL"),
+ SOM_HOWTO (R_ABS_CALL, "R_ABS_CALL"),
+ SOM_HOWTO (R_ABS_CALL, "R_ABS_CALL"),
+ SOM_HOWTO (R_ABS_CALL, "R_ABS_CALL"),
+ SOM_HOWTO (R_RESERVED, "R_RESERVED"),
+ SOM_HOWTO (R_RESERVED, "R_RESERVED"),
+ SOM_HOWTO (R_DP_RELATIVE, "R_DP_RELATIVE"),
+ SOM_HOWTO (R_DP_RELATIVE, "R_DP_RELATIVE"),
+ SOM_HOWTO (R_DP_RELATIVE, "R_DP_RELATIVE"),
+ SOM_HOWTO (R_DP_RELATIVE, "R_DP_RELATIVE"),
+ SOM_HOWTO (R_DP_RELATIVE, "R_DP_RELATIVE"),
+ SOM_HOWTO (R_DP_RELATIVE, "R_DP_RELATIVE"),
+ SOM_HOWTO (R_DP_RELATIVE, "R_DP_RELATIVE"),
+ SOM_HOWTO (R_DP_RELATIVE, "R_DP_RELATIVE"),
+ SOM_HOWTO (R_DP_RELATIVE, "R_DP_RELATIVE"),
+ SOM_HOWTO (R_DP_RELATIVE, "R_DP_RELATIVE"),
+ SOM_HOWTO (R_DP_RELATIVE, "R_DP_RELATIVE"),
+ SOM_HOWTO (R_DP_RELATIVE, "R_DP_RELATIVE"),
+ SOM_HOWTO (R_DP_RELATIVE, "R_DP_RELATIVE"),
+ SOM_HOWTO (R_DP_RELATIVE, "R_DP_RELATIVE"),
+ SOM_HOWTO (R_DP_RELATIVE, "R_DP_RELATIVE"),
+ SOM_HOWTO (R_DP_RELATIVE, "R_DP_RELATIVE"),
+ SOM_HOWTO (R_DP_RELATIVE, "R_DP_RELATIVE"),
+ SOM_HOWTO (R_DP_RELATIVE, "R_DP_RELATIVE"),
+ SOM_HOWTO (R_DP_RELATIVE, "R_DP_RELATIVE"),
+ SOM_HOWTO (R_DP_RELATIVE, "R_DP_RELATIVE"),
+ SOM_HOWTO (R_DP_RELATIVE, "R_DP_RELATIVE"),
+ SOM_HOWTO (R_DP_RELATIVE, "R_DP_RELATIVE"),
+ SOM_HOWTO (R_DP_RELATIVE, "R_DP_RELATIVE"),
+ SOM_HOWTO (R_DP_RELATIVE, "R_DP_RELATIVE"),
+ SOM_HOWTO (R_DP_RELATIVE, "R_DP_RELATIVE"),
+ SOM_HOWTO (R_DP_RELATIVE, "R_DP_RELATIVE"),
+ SOM_HOWTO (R_DP_RELATIVE, "R_DP_RELATIVE"),
+ SOM_HOWTO (R_DP_RELATIVE, "R_DP_RELATIVE"),
+ SOM_HOWTO (R_DP_RELATIVE, "R_DP_RELATIVE"),
+ SOM_HOWTO (R_DP_RELATIVE, "R_DP_RELATIVE"),
+ SOM_HOWTO (R_DP_RELATIVE, "R_DP_RELATIVE"),
+ SOM_HOWTO (R_DP_RELATIVE, "R_DP_RELATIVE"),
+ SOM_HOWTO (R_DP_RELATIVE, "R_DP_RELATIVE"),
+ SOM_HOWTO (R_DP_RELATIVE, "R_DP_RELATIVE"),
+ SOM_HOWTO (R_DATA_GPREL, "R_DATA_GPREL"),
+ SOM_HOWTO (R_RESERVED, "R_RESERVED"),
+ SOM_HOWTO (R_RESERVED, "R_RESERVED"),
+ SOM_HOWTO (R_RESERVED, "R_RESERVED"),
+ SOM_HOWTO (R_RESERVED, "R_RESERVED"),
+ SOM_HOWTO (R_RESERVED, "R_RESERVED"),
+ SOM_HOWTO (R_DLT_REL, "R_DLT_REL"),
+ SOM_HOWTO (R_DLT_REL, "R_DLT_REL"),
+ SOM_HOWTO (R_RESERVED, "R_RESERVED"),
+ SOM_HOWTO (R_RESERVED, "R_RESERVED"),
+ SOM_HOWTO (R_RESERVED, "R_RESERVED"),
+ SOM_HOWTO (R_RESERVED, "R_RESERVED"),
+ SOM_HOWTO (R_RESERVED, "R_RESERVED"),
+ SOM_HOWTO (R_RESERVED, "R_RESERVED"),
+ SOM_HOWTO (R_CODE_ONE_SYMBOL, "R_CODE_ONE_SYMBOL"),
+ SOM_HOWTO (R_CODE_ONE_SYMBOL, "R_CODE_ONE_SYMBOL"),
+ SOM_HOWTO (R_CODE_ONE_SYMBOL, "R_CODE_ONE_SYMBOL"),
+ SOM_HOWTO (R_CODE_ONE_SYMBOL, "R_CODE_ONE_SYMBOL"),
+ SOM_HOWTO (R_CODE_ONE_SYMBOL, "R_CODE_ONE_SYMBOL"),
+ SOM_HOWTO (R_CODE_ONE_SYMBOL, "R_CODE_ONE_SYMBOL"),
+ SOM_HOWTO (R_CODE_ONE_SYMBOL, "R_CODE_ONE_SYMBOL"),
+ SOM_HOWTO (R_CODE_ONE_SYMBOL, "R_CODE_ONE_SYMBOL"),
+ SOM_HOWTO (R_CODE_ONE_SYMBOL, "R_CODE_ONE_SYMBOL"),
+ SOM_HOWTO (R_CODE_ONE_SYMBOL, "R_CODE_ONE_SYMBOL"),
+ SOM_HOWTO (R_CODE_ONE_SYMBOL, "R_CODE_ONE_SYMBOL"),
+ SOM_HOWTO (R_CODE_ONE_SYMBOL, "R_CODE_ONE_SYMBOL"),
+ SOM_HOWTO (R_CODE_ONE_SYMBOL, "R_CODE_ONE_SYMBOL"),
+ SOM_HOWTO (R_CODE_ONE_SYMBOL, "R_CODE_ONE_SYMBOL"),
+ SOM_HOWTO (R_CODE_ONE_SYMBOL, "R_CODE_ONE_SYMBOL"),
+ SOM_HOWTO (R_CODE_ONE_SYMBOL, "R_CODE_ONE_SYMBOL"),
+ SOM_HOWTO (R_CODE_ONE_SYMBOL, "R_CODE_ONE_SYMBOL"),
+ SOM_HOWTO (R_CODE_ONE_SYMBOL, "R_CODE_ONE_SYMBOL"),
+ SOM_HOWTO (R_CODE_ONE_SYMBOL, "R_CODE_ONE_SYMBOL"),
+ SOM_HOWTO (R_CODE_ONE_SYMBOL, "R_CODE_ONE_SYMBOL"),
+ SOM_HOWTO (R_CODE_ONE_SYMBOL, "R_CODE_ONE_SYMBOL"),
+ SOM_HOWTO (R_CODE_ONE_SYMBOL, "R_CODE_ONE_SYMBOL"),
+ SOM_HOWTO (R_CODE_ONE_SYMBOL, "R_CODE_ONE_SYMBOL"),
+ SOM_HOWTO (R_CODE_ONE_SYMBOL, "R_CODE_ONE_SYMBOL"),
+ SOM_HOWTO (R_CODE_ONE_SYMBOL, "R_CODE_ONE_SYMBOL"),
+ SOM_HOWTO (R_CODE_ONE_SYMBOL, "R_CODE_ONE_SYMBOL"),
+ SOM_HOWTO (R_CODE_ONE_SYMBOL, "R_CODE_ONE_SYMBOL"),
+ SOM_HOWTO (R_CODE_ONE_SYMBOL, "R_CODE_ONE_SYMBOL"),
+ SOM_HOWTO (R_CODE_ONE_SYMBOL, "R_CODE_ONE_SYMBOL"),
+ SOM_HOWTO (R_CODE_ONE_SYMBOL, "R_CODE_ONE_SYMBOL"),
+ SOM_HOWTO (R_CODE_ONE_SYMBOL, "R_CODE_ONE_SYMBOL"),
+ SOM_HOWTO (R_CODE_ONE_SYMBOL, "R_CODE_ONE_SYMBOL"),
+ SOM_HOWTO (R_CODE_ONE_SYMBOL, "R_CODE_ONE_SYMBOL"),
+ SOM_HOWTO (R_CODE_ONE_SYMBOL, "R_CODE_ONE_SYMBOL"),
+ SOM_HOWTO (R_CODE_ONE_SYMBOL, "R_CODE_ONE_SYMBOL"),
+ SOM_HOWTO (R_RESERVED, "R_RESERVED"),
+ SOM_HOWTO (R_RESERVED, "R_RESERVED"),
+ SOM_HOWTO (R_RESERVED, "R_RESERVED"),
+ SOM_HOWTO (R_RESERVED, "R_RESERVED"),
+ SOM_HOWTO (R_RESERVED, "R_RESERVED"),
+ SOM_HOWTO (R_RESERVED, "R_RESERVED"),
+ SOM_HOWTO (R_RESERVED, "R_RESERVED"),
+ SOM_HOWTO (R_RESERVED, "R_RESERVED"),
+ SOM_HOWTO (R_RESERVED, "R_RESERVED"),
+ SOM_HOWTO (R_RESERVED, "R_RESERVED"),
+ SOM_HOWTO (R_RESERVED, "R_RESERVED"),
+ SOM_HOWTO (R_MILLI_REL, "R_MILLI_REL"),
+ SOM_HOWTO (R_MILLI_REL, "R_MILLI_REL"),
+ SOM_HOWTO (R_CODE_PLABEL, "R_CODE_PLABEL"),
+ SOM_HOWTO (R_CODE_PLABEL, "R_CODE_PLABEL"),
+ SOM_HOWTO (R_BREAKPOINT, "R_BREAKPOINT"),
+ SOM_HOWTO (R_ENTRY, "R_ENTRY"),
+ SOM_HOWTO (R_ENTRY, "R_ENTRY"),
+ SOM_HOWTO (R_ALT_ENTRY, "R_ALT_ENTRY"),
+ SOM_HOWTO (R_EXIT, "R_EXIT"),
+ SOM_HOWTO (R_BEGIN_TRY, "R_BEGIN_TRY"),
+ SOM_HOWTO (R_END_TRY, "R_END_TRY"),
+ SOM_HOWTO (R_END_TRY, "R_END_TRY"),
+ SOM_HOWTO (R_END_TRY, "R_END_TRY"),
+ SOM_HOWTO (R_BEGIN_BRTAB, "R_BEGIN_BRTAB"),
+ SOM_HOWTO (R_END_BRTAB, "R_END_BRTAB"),
+ SOM_HOWTO (R_STATEMENT, "R_STATEMENT"),
+ SOM_HOWTO (R_STATEMENT, "R_STATEMENT"),
+ SOM_HOWTO (R_STATEMENT, "R_STATEMENT"),
+ SOM_HOWTO (R_DATA_EXPR, "R_DATA_EXPR"),
+ SOM_HOWTO (R_CODE_EXPR, "R_CODE_EXPR"),
+ SOM_HOWTO (R_FSEL, "R_FSEL"),
+ SOM_HOWTO (R_LSEL, "R_LSEL"),
+ SOM_HOWTO (R_RSEL, "R_RSEL"),
+ SOM_HOWTO (R_N_MODE, "R_N_MODE"),
+ SOM_HOWTO (R_S_MODE, "R_S_MODE"),
+ SOM_HOWTO (R_D_MODE, "R_D_MODE"),
+ SOM_HOWTO (R_R_MODE, "R_R_MODE"),
+ SOM_HOWTO (R_DATA_OVERRIDE, "R_DATA_OVERRIDE"),
+ SOM_HOWTO (R_DATA_OVERRIDE, "R_DATA_OVERRIDE"),
+ SOM_HOWTO (R_DATA_OVERRIDE, "R_DATA_OVERRIDE"),
+ SOM_HOWTO (R_DATA_OVERRIDE, "R_DATA_OVERRIDE"),
+ SOM_HOWTO (R_DATA_OVERRIDE, "R_DATA_OVERRIDE"),
+ SOM_HOWTO (R_TRANSLATED, "R_TRANSLATED"),
+ SOM_HOWTO (R_AUX_UNWIND, "R_AUX_UNWIND"),
+ SOM_HOWTO (R_COMP1, "R_COMP1"),
+ SOM_HOWTO (R_COMP2, "R_COMP2"),
+ SOM_HOWTO (R_COMP3, "R_COMP3"),
+ SOM_HOWTO (R_PREV_FIXUP, "R_PREV_FIXUP"),
+ SOM_HOWTO (R_PREV_FIXUP, "R_PREV_FIXUP"),
+ SOM_HOWTO (R_PREV_FIXUP, "R_PREV_FIXUP"),
+ SOM_HOWTO (R_PREV_FIXUP, "R_PREV_FIXUP"),
+ SOM_HOWTO (R_SEC_STMT, "R_SEC_STMT"),
+ SOM_HOWTO (R_N0SEL, "R_N0SEL"),
+ SOM_HOWTO (R_N1SEL, "R_N1SEL"),
+ SOM_HOWTO (R_LINETAB, "R_LINETAB"),
+ SOM_HOWTO (R_LINETAB_ESC, "R_LINETAB_ESC"),
+ SOM_HOWTO (R_LTP_OVERRIDE, "R_LTP_OVERRIDE"),
+ SOM_HOWTO (R_COMMENT, "R_COMMENT"),
+ SOM_HOWTO (R_RESERVED, "R_RESERVED"),
+ SOM_HOWTO (R_RESERVED, "R_RESERVED"),
+ SOM_HOWTO (R_RESERVED, "R_RESERVED"),
+ SOM_HOWTO (R_RESERVED, "R_RESERVED"),
+ SOM_HOWTO (R_RESERVED, "R_RESERVED"),
+ SOM_HOWTO (R_RESERVED, "R_RESERVED"),
+ SOM_HOWTO (R_RESERVED, "R_RESERVED"),
+ SOM_HOWTO (R_RESERVED, "R_RESERVED"),
+ SOM_HOWTO (R_RESERVED, "R_RESERVED"),
+ SOM_HOWTO (R_RESERVED, "R_RESERVED"),
+ SOM_HOWTO (R_RESERVED, "R_RESERVED"),
+ SOM_HOWTO (R_RESERVED, "R_RESERVED"),
+ SOM_HOWTO (R_RESERVED, "R_RESERVED"),
+ SOM_HOWTO (R_RESERVED, "R_RESERVED"),
+ SOM_HOWTO (R_RESERVED, "R_RESERVED"),
+ SOM_HOWTO (R_RESERVED, "R_RESERVED"),
+ SOM_HOWTO (R_RESERVED, "R_RESERVED"),
+ SOM_HOWTO (R_RESERVED, "R_RESERVED"),
+ SOM_HOWTO (R_RESERVED, "R_RESERVED"),
+ SOM_HOWTO (R_RESERVED, "R_RESERVED"),
+ SOM_HOWTO (R_RESERVED, "R_RESERVED"),
+ SOM_HOWTO (R_RESERVED, "R_RESERVED"),
+ SOM_HOWTO (R_RESERVED, "R_RESERVED"),
+ SOM_HOWTO (R_RESERVED, "R_RESERVED"),
+ SOM_HOWTO (R_RESERVED, "R_RESERVED"),
+ SOM_HOWTO (R_RESERVED, "R_RESERVED"),
+ SOM_HOWTO (R_RESERVED, "R_RESERVED"),
+ SOM_HOWTO (R_RESERVED, "R_RESERVED"),
+ SOM_HOWTO (R_RESERVED, "R_RESERVED"),
+ SOM_HOWTO (R_RESERVED, "R_RESERVED"),
+ SOM_HOWTO (R_RESERVED, "R_RESERVED"),
+ SOM_HOWTO (R_RESERVED, "R_RESERVED"),
+ SOM_HOWTO (R_RESERVED, "R_RESERVED"),
+ SOM_HOWTO (R_RESERVED, "R_RESERVED")
+};
+
+/* Initialize the SOM relocation queue. By definition the queue holds
+ the last four multibyte fixups. */
+
+static void
+som_initialize_reloc_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 (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 (struct reloc_queue *queue, unsigned int idx)
+{
+ if (idx == 0)
+ return;
+
+ if (idx == 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 (idx == 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 (idx == 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 (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 (bfd *abfd ATTRIBUTE_UNUSED,
+ unsigned 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 (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, (bfd_vma) 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, (bfd_vma) (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, (bfd_vma) 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 (bfd *abfd,
+ bfd_vma addend,
+ unsigned char *p,
+ unsigned int *subspace_reloc_sizep,
+ struct reloc_queue *queue)
+{
+ if (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 (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 (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 (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, (bfd_vma) 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,
+ if X is a power of 2. Otherwise, returns -1. */
+
+static int
+exact_log2 (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 (bfd *abfd ATTRIBUTE_UNUSED,
+ arelent *reloc_entry,
+ asymbol *symbol_in ATTRIBUTE_UNUSED,
+ void *data ATTRIBUTE_UNUSED,
+ asection *input_section,
+ bfd *output_bfd,
+ char **error_message ATTRIBUTE_UNUSED)
+{
+ if (output_bfd)
+ reloc_entry->address += input_section->output_offset;
+
+ 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 (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 = bfd_alloc (abfd, (bfd_size_type) sizeof (int *) * 6);
+ final_type = bfd_alloc (abfd, (bfd_size_type) 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] = bfd_alloc (abfd, (bfd_size_type) 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] = bfd_alloc (abfd, (bfd_size_type) 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] = bfd_alloc (abfd, (bfd_size_type) 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] = bfd_alloc (abfd, (bfd_size_type) 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] = bfd_alloc (abfd, (bfd_size_type) 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] = bfd_alloc (abfd, (bfd_size_type) 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] = bfd_alloc (abfd, (bfd_size_type) sizeof (int));
+ if (!final_types[0])
+ return NULL;
+ *final_types[0] = R_N0SEL;
+ final_types[1] = bfd_alloc (abfd, (bfd_size_type) 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;
+
+ /* FIXME: These two field selectors are not currently supported. */
+ case e_ltpsel:
+ case e_rtpsel:
+ abort ();
+ }
+
+ switch (base_type)
+ {
+ case R_HPPA:
+ /* The difference of two symbols needs *very* special handling. */
+ if (sym_diff)
+ {
+ bfd_size_type amt = sizeof (int);
+
+ final_types[0] = bfd_alloc (abfd, amt);
+ final_types[1] = bfd_alloc (abfd, amt);
+ final_types[2] = bfd_alloc (abfd, amt);
+ final_types[3] = bfd_alloc (abfd, amt);
+ 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;
+ else if (field == e_fsel && format == 32)
+ *final_type = R_DATA_GPREL;
+ break;
+
+ case R_HPPA_COMPLEX:
+ /* The difference of two symbols needs *very* special handling. */
+ if (sym_diff)
+ {
+ bfd_size_type amt = sizeof (int);
+
+ final_types[0] = bfd_alloc (abfd, amt);
+ final_types[1] = bfd_alloc (abfd, amt);
+ final_types[2] = bfd_alloc (abfd, amt);
+ final_types[3] = bfd_alloc (abfd, amt);
+ 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:
+ /* Right now we can default all these. */
+ break;
+
+ case R_HPPA_PCREL_CALL:
+ {
+#ifndef NO_PCREL_MODES
+ /* If we have short and long pcrel modes, then generate the proper
+ mode selector, then the pcrel relocation. Redundant selectors
+ will be eliminated as the relocs are sized and emitted. */
+ bfd_size_type amt = sizeof (int);
+
+ final_types[0] = bfd_alloc (abfd, amt);
+ if (!final_types[0])
+ return NULL;
+ if (format == 17)
+ *final_types[0] = R_SHORT_PCREL_MODE;
+ else
+ *final_types[0] = R_LONG_PCREL_MODE;
+ final_types[1] = final_type;
+ final_types[2] = NULL;
+ *final_type = base_type;
+#endif
+ break;
+ }
+ }
+ return final_types;
+}
+
+/* Return the address of the correct entry in the PA SOM relocation
+ howto table. */
+
+static reloc_howto_type *
+som_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ 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 NULL;
+}
+
+static reloc_howto_type *
+som_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ const char *r_name)
+{
+ unsigned int i;
+
+ for (i = 0;
+ i < sizeof (som_hppa_howto_table) / sizeof (som_hppa_howto_table[0]);
+ i++)
+ if (som_hppa_howto_table[i].name != NULL
+ && strcasecmp (som_hppa_howto_table[i].name, r_name) == 0)
+ return &som_hppa_howto_table[i];
+
+ return NULL;
+}
+
+static void
+som_swap_clock_in (struct som_external_clock *src,
+ struct som_clock *dst)
+{
+ dst->secs = bfd_getb32 (src->secs);
+ dst->nanosecs = bfd_getb32 (src->nanosecs);
+}
+
+static void
+som_swap_clock_out (struct som_clock *src,
+ struct som_external_clock *dst)
+{
+ bfd_putb32 (src->secs, dst->secs);
+ bfd_putb32 (src->nanosecs, dst->nanosecs);
+}
+
+static void
+som_swap_header_in (struct som_external_header *src,
+ struct som_header *dst)
+{
+ dst->system_id = bfd_getb16 (src->system_id);
+ dst->a_magic = bfd_getb16 (src->a_magic);
+ dst->version_id = bfd_getb32 (src->version_id);
+ som_swap_clock_in (&src->file_time, &dst->file_time);
+ dst->entry_space = bfd_getb32 (src->entry_space);
+ dst->entry_subspace = bfd_getb32 (src->entry_subspace);
+ dst->entry_offset = bfd_getb32 (src->entry_offset);
+ dst->aux_header_location = bfd_getb32 (src->aux_header_location);
+ dst->aux_header_size = bfd_getb32 (src->aux_header_size);
+ dst->som_length = bfd_getb32 (src->som_length);
+ dst->presumed_dp = bfd_getb32 (src->presumed_dp);
+ dst->space_location = bfd_getb32 (src->space_location);
+ dst->space_total = bfd_getb32 (src->space_total);
+ dst->subspace_location = bfd_getb32 (src->subspace_location);
+ dst->subspace_total = bfd_getb32 (src->subspace_total);
+ dst->loader_fixup_location = bfd_getb32 (src->loader_fixup_location);
+ dst->loader_fixup_total = bfd_getb32 (src->loader_fixup_total);
+ dst->space_strings_location = bfd_getb32 (src->space_strings_location);
+ dst->space_strings_size = bfd_getb32 (src->space_strings_size);
+ dst->init_array_location = bfd_getb32 (src->init_array_location);
+ dst->init_array_total = bfd_getb32 (src->init_array_total);
+ dst->compiler_location = bfd_getb32 (src->compiler_location);
+ dst->compiler_total = bfd_getb32 (src->compiler_total);
+ dst->symbol_location = bfd_getb32 (src->symbol_location);
+ dst->symbol_total = bfd_getb32 (src->symbol_total);
+ dst->fixup_request_location = bfd_getb32 (src->fixup_request_location);
+ dst->fixup_request_total = bfd_getb32 (src->fixup_request_total);
+ dst->symbol_strings_location = bfd_getb32 (src->symbol_strings_location);
+ dst->symbol_strings_size = bfd_getb32 (src->symbol_strings_size);
+ dst->unloadable_sp_location = bfd_getb32 (src->unloadable_sp_location);
+ dst->unloadable_sp_size = bfd_getb32 (src->unloadable_sp_size);
+ dst->checksum = bfd_getb32 (src->checksum);
+}
+
+static void
+som_swap_header_out (struct som_header *src,
+ struct som_external_header *dst)
+{
+ bfd_putb16 (src->system_id, dst->system_id);
+ bfd_putb16 (src->a_magic, dst->a_magic);
+ bfd_putb32 (src->version_id, dst->version_id);
+ som_swap_clock_out (&src->file_time, &dst->file_time);
+ bfd_putb32 (src->entry_space, dst->entry_space);
+ bfd_putb32 (src->entry_subspace, dst->entry_subspace);
+ bfd_putb32 (src->entry_offset, dst->entry_offset);
+ bfd_putb32 (src->aux_header_location, dst->aux_header_location);
+ bfd_putb32 (src->aux_header_size, dst->aux_header_size);
+ bfd_putb32 (src->som_length, dst->som_length);
+ bfd_putb32 (src->presumed_dp, dst->presumed_dp);
+ bfd_putb32 (src->space_location, dst->space_location);
+ bfd_putb32 (src->space_total, dst->space_total);
+ bfd_putb32 (src->subspace_location, dst->subspace_location);
+ bfd_putb32 (src->subspace_total, dst->subspace_total);
+ bfd_putb32 (src->loader_fixup_location, dst->loader_fixup_location);
+ bfd_putb32 (src->loader_fixup_total, dst->loader_fixup_total);
+ bfd_putb32 (src->space_strings_location, dst->space_strings_location);
+ bfd_putb32 (src->space_strings_size, dst->space_strings_size);
+ bfd_putb32 (src->init_array_location, dst->init_array_location);
+ bfd_putb32 (src->init_array_total, dst->init_array_total);
+ bfd_putb32 (src->compiler_location, dst->compiler_location);
+ bfd_putb32 (src->compiler_total, dst->compiler_total);
+ bfd_putb32 (src->symbol_location, dst->symbol_location);
+ bfd_putb32 (src->symbol_total, dst->symbol_total);
+ bfd_putb32 (src->fixup_request_location, dst->fixup_request_location);
+ bfd_putb32 (src->fixup_request_total, dst->fixup_request_total);
+ bfd_putb32 (src->symbol_strings_location, dst->symbol_strings_location);
+ bfd_putb32 (src->symbol_strings_size, dst->symbol_strings_size);
+ bfd_putb32 (src->unloadable_sp_location, dst->unloadable_sp_location);
+ bfd_putb32 (src->unloadable_sp_size, dst->unloadable_sp_size);
+ bfd_putb32 (src->checksum, dst->checksum);
+}
+
+static void
+som_swap_space_dictionary_in (struct som_external_space_dictionary_record *src,
+ struct som_space_dictionary_record *dst)
+{
+ unsigned int flags;
+
+ dst->name = bfd_getb32 (src->name);
+ flags = bfd_getb32 (src->flags);
+ dst->is_loadable = (flags & SOM_SPACE_IS_LOADABLE) != 0;
+ dst->is_defined = (flags & SOM_SPACE_IS_DEFINED) != 0;
+ dst->is_private = (flags & SOM_SPACE_IS_PRIVATE) != 0;
+ dst->has_intermediate_code = (flags & SOM_SPACE_HAS_INTERMEDIATE_CODE) != 0;
+ dst->is_tspecific = (flags & SOM_SPACE_IS_TSPECIFIC) != 0;
+ dst->reserved = 0;
+ dst->sort_key = (flags >> SOM_SPACE_SORT_KEY_SH) & SOM_SPACE_SORT_KEY_MASK;
+ dst->reserved2 = 0;
+ dst->space_number = bfd_getb32 (src->space_number);
+ dst->subspace_index = bfd_getb32 (src->subspace_index);
+ dst->subspace_quantity = bfd_getb32 (src->subspace_quantity);
+ dst->loader_fix_index = bfd_getb32 (src->loader_fix_index);
+ dst->loader_fix_quantity = bfd_getb32 (src->loader_fix_quantity);
+ dst->init_pointer_index = bfd_getb32 (src->init_pointer_index);
+ dst->init_pointer_quantity = bfd_getb32 (src->init_pointer_quantity);
+}
+
+static void
+som_swap_space_dictionary_out (struct som_space_dictionary_record *src,
+ struct som_external_space_dictionary_record *dst)
+{
+ unsigned int flags;
+
+ bfd_putb32 (src->name, dst->name);
+
+ flags = 0;
+ if (src->is_loadable)
+ flags |= SOM_SPACE_IS_LOADABLE;
+ if (src->is_defined)
+ flags |= SOM_SPACE_IS_DEFINED;
+ if (src->is_private)
+ flags |= SOM_SPACE_IS_PRIVATE;
+ if (src->has_intermediate_code)
+ flags |= SOM_SPACE_HAS_INTERMEDIATE_CODE;
+ if (src->is_tspecific)
+ flags |= SOM_SPACE_IS_TSPECIFIC;
+ flags |= (src->sort_key & SOM_SPACE_SORT_KEY_MASK) << SOM_SPACE_SORT_KEY_SH;
+ bfd_putb32 (flags, dst->flags);
+ bfd_putb32 (src->space_number, dst->space_number);
+ bfd_putb32 (src->subspace_index, dst->subspace_index);
+ bfd_putb32 (src->subspace_quantity, dst->subspace_quantity);
+ bfd_putb32 (src->loader_fix_index, dst->loader_fix_index);
+ bfd_putb32 (src->loader_fix_quantity, dst->loader_fix_quantity);
+ bfd_putb32 (src->init_pointer_index, dst->init_pointer_index);
+ bfd_putb32 (src->init_pointer_quantity, dst->init_pointer_quantity);
+}
+
+static void
+som_swap_subspace_dictionary_in
+ (struct som_external_subspace_dictionary_record *src,
+ struct som_subspace_dictionary_record *dst)
+{
+ unsigned int flags;
+ dst->space_index = bfd_getb32 (src->space_index);
+ flags = bfd_getb32 (src->flags);
+ dst->access_control_bits = (flags >> SOM_SUBSPACE_ACCESS_CONTROL_BITS_SH)
+ & SOM_SUBSPACE_ACCESS_CONTROL_BITS_MASK;
+ dst->memory_resident = (flags & SOM_SUBSPACE_MEMORY_RESIDENT) != 0;
+ dst->dup_common = (flags & SOM_SUBSPACE_DUP_COMMON) != 0;
+ dst->is_common = (flags & SOM_SUBSPACE_IS_COMMON) != 0;
+ dst->is_loadable = (flags & SOM_SUBSPACE_IS_LOADABLE) != 0;
+ dst->quadrant = (flags >> SOM_SUBSPACE_QUADRANT_SH)
+ & SOM_SUBSPACE_QUADRANT_MASK;
+ dst->initially_frozen = (flags & SOM_SUBSPACE_INITIALLY_FROZEN) != 0;
+ dst->is_first = (flags & SOM_SUBSPACE_IS_FIRST) != 0;
+ dst->code_only = (flags & SOM_SUBSPACE_CODE_ONLY) != 0;
+ dst->sort_key = (flags >> SOM_SUBSPACE_SORT_KEY_SH)
+ & SOM_SUBSPACE_SORT_KEY_MASK;
+ dst->replicate_init = (flags & SOM_SUBSPACE_REPLICATE_INIT) != 0;
+ dst->continuation = (flags & SOM_SUBSPACE_CONTINUATION) != 0;
+ dst->is_tspecific = (flags & SOM_SUBSPACE_IS_TSPECIFIC) != 0;
+ dst->is_comdat = (flags & SOM_SUBSPACE_IS_COMDAT) != 0;
+ dst->reserved = 0;
+ dst->file_loc_init_value = bfd_getb32 (src->file_loc_init_value);
+ dst->initialization_length = bfd_getb32 (src->initialization_length);
+ dst->subspace_start = bfd_getb32 (src->subspace_start);
+ dst->subspace_length = bfd_getb32 (src->subspace_length);
+ dst->alignment = bfd_getb32 (src->alignment);
+ dst->name = bfd_getb32 (src->name);
+ dst->fixup_request_index = bfd_getb32 (src->fixup_request_index);
+ dst->fixup_request_quantity = bfd_getb32 (src->fixup_request_quantity);
+}
+
+static void
+som_swap_subspace_dictionary_record_out
+ (struct som_subspace_dictionary_record *src,
+ struct som_external_subspace_dictionary_record *dst)
+{
+ unsigned int flags;
+
+ bfd_putb32 (src->space_index, dst->space_index);
+ flags = (src->access_control_bits & SOM_SUBSPACE_ACCESS_CONTROL_BITS_MASK)
+ << SOM_SUBSPACE_ACCESS_CONTROL_BITS_SH;
+ if (src->memory_resident)
+ flags |= SOM_SUBSPACE_MEMORY_RESIDENT;
+ if (src->dup_common)
+ flags |= SOM_SUBSPACE_DUP_COMMON;
+ if (src->is_common)
+ flags |= SOM_SUBSPACE_IS_COMMON;
+ if (src->is_loadable)
+ flags |= SOM_SUBSPACE_IS_LOADABLE;
+ flags |= (src->quadrant & SOM_SUBSPACE_QUADRANT_MASK)
+ << SOM_SUBSPACE_QUADRANT_SH;
+ if (src->initially_frozen)
+ flags |= SOM_SUBSPACE_INITIALLY_FROZEN;
+ if (src->is_first)
+ flags |= SOM_SUBSPACE_IS_FIRST;
+ if (src->code_only)
+ flags |= SOM_SUBSPACE_CODE_ONLY;
+ flags |= (src->sort_key & SOM_SUBSPACE_SORT_KEY_MASK)
+ << SOM_SUBSPACE_SORT_KEY_SH;
+ if (src->replicate_init)
+ flags |= SOM_SUBSPACE_REPLICATE_INIT;
+ if (src->continuation)
+ flags |= SOM_SUBSPACE_CONTINUATION;
+ if (src->is_tspecific)
+ flags |= SOM_SUBSPACE_IS_TSPECIFIC;
+ if (src->is_comdat)
+ flags |= SOM_SUBSPACE_IS_COMDAT;
+ bfd_putb32 (flags, dst->flags);
+ bfd_putb32 (src->file_loc_init_value, dst->file_loc_init_value);
+ bfd_putb32 (src->initialization_length, dst->initialization_length);
+ bfd_putb32 (src->subspace_start, dst->subspace_start);
+ bfd_putb32 (src->subspace_length, dst->subspace_length);
+ bfd_putb32 (src->alignment, dst->alignment);
+ bfd_putb32 (src->name, dst->name);
+ bfd_putb32 (src->fixup_request_index, dst->fixup_request_index);
+ bfd_putb32 (src->fixup_request_quantity, dst->fixup_request_quantity);
+}
+
+static void
+som_swap_aux_id_in (struct som_external_aux_id *src,
+ struct som_aux_id *dst)
+{
+ unsigned int flags = bfd_getb32 (src->flags);
+
+ dst->mandatory = (flags & SOM_AUX_ID_MANDATORY) != 0;
+ dst->copy = (flags & SOM_AUX_ID_COPY) != 0;
+ dst->append = (flags & SOM_AUX_ID_APPEND) != 0;
+ dst->ignore = (flags & SOM_AUX_ID_IGNORE) != 0;
+ dst->type = (flags >> SOM_AUX_ID_TYPE_SH) & SOM_AUX_ID_TYPE_MASK;
+ dst->length = bfd_getb32 (src->length);
+}
+
+static void
+som_swap_aux_id_out (struct som_aux_id *src,
+ struct som_external_aux_id *dst)
+{
+ unsigned int flags = 0;
+
+ if (src->mandatory)
+ flags |= SOM_AUX_ID_MANDATORY;
+ if (src->copy)
+ flags |= SOM_AUX_ID_COPY;
+ if (src->append)
+ flags |= SOM_AUX_ID_APPEND;
+ if (src->ignore)
+ flags |= SOM_AUX_ID_IGNORE;
+ flags |= (src->type & SOM_AUX_ID_TYPE_MASK) << SOM_AUX_ID_TYPE_SH;
+ bfd_putb32 (flags, dst->flags);
+ bfd_putb32 (src->length, dst->length);
+}
+
+static void
+som_swap_string_auxhdr_out (struct som_string_auxhdr *src,
+ struct som_external_string_auxhdr *dst)
+{
+ som_swap_aux_id_out (&src->header_id, &dst->header_id);
+ bfd_putb32 (src->string_length, dst->string_length);
+}
+
+static void
+som_swap_compilation_unit_out (struct som_compilation_unit *src,
+ struct som_external_compilation_unit *dst)
+{
+ bfd_putb32 (src->name.strx, dst->name);
+ bfd_putb32 (src->language_name.strx, dst->language_name);
+ bfd_putb32 (src->product_id.strx, dst->product_id);
+ bfd_putb32 (src->version_id.strx, dst->version_id);
+ bfd_putb32 (src->flags, dst->flags);
+ som_swap_clock_out (&src->compile_time, &dst->compile_time);
+ som_swap_clock_out (&src->source_time, &dst->source_time);
+}
+
+static void
+som_swap_exec_auxhdr_in (struct som_external_exec_auxhdr *src,
+ struct som_exec_auxhdr *dst)
+{
+ som_swap_aux_id_in (&src->som_auxhdr, &dst->som_auxhdr);
+ dst->exec_tsize = bfd_getb32 (src->exec_tsize);
+ dst->exec_tmem = bfd_getb32 (src->exec_tmem);
+ dst->exec_tfile = bfd_getb32 (src->exec_tfile);
+ dst->exec_dsize = bfd_getb32 (src->exec_dsize);
+ dst->exec_dmem = bfd_getb32 (src->exec_dmem);
+ dst->exec_dfile = bfd_getb32 (src->exec_dfile);
+ dst->exec_bsize = bfd_getb32 (src->exec_bsize);
+ dst->exec_entry = bfd_getb32 (src->exec_entry);
+ dst->exec_flags = bfd_getb32 (src->exec_flags);
+ dst->exec_bfill = bfd_getb32 (src->exec_bfill);
+}
+
+static void
+som_swap_exec_auxhdr_out (struct som_exec_auxhdr *src,
+ struct som_external_exec_auxhdr *dst)
+{
+ som_swap_aux_id_out (&src->som_auxhdr, &dst->som_auxhdr);
+ bfd_putb32 (src->exec_tsize, dst->exec_tsize);
+ bfd_putb32 (src->exec_tmem, dst->exec_tmem);
+ bfd_putb32 (src->exec_tfile, dst->exec_tfile);
+ bfd_putb32 (src->exec_dsize, dst->exec_dsize);
+ bfd_putb32 (src->exec_dmem, dst->exec_dmem);
+ bfd_putb32 (src->exec_dfile, dst->exec_dfile);
+ bfd_putb32 (src->exec_bsize, dst->exec_bsize);
+ bfd_putb32 (src->exec_entry, dst->exec_entry);
+ bfd_putb32 (src->exec_flags, dst->exec_flags);
+ bfd_putb32 (src->exec_bfill, dst->exec_bfill);
+}
+
+static void
+som_swap_lst_header_in (struct som_external_lst_header *src,
+ struct som_lst_header *dst)
+{
+ dst->system_id = bfd_getb16 (src->system_id);
+ dst->a_magic = bfd_getb16 (src->a_magic);
+ dst->version_id = bfd_getb32 (src->version_id);
+ som_swap_clock_in (&src->file_time, &dst->file_time);
+ dst->hash_loc = bfd_getb32 (src->hash_loc);
+ dst->hash_size = bfd_getb32 (src->hash_size);
+ dst->module_count = bfd_getb32 (src->module_count);
+ dst->module_limit = bfd_getb32 (src->module_limit);
+ dst->dir_loc = bfd_getb32 (src->dir_loc);
+ dst->export_loc = bfd_getb32 (src->export_loc);
+ dst->export_count = bfd_getb32 (src->export_count);
+ dst->import_loc = bfd_getb32 (src->import_loc);
+ dst->aux_loc = bfd_getb32 (src->aux_loc);
+ dst->aux_size = bfd_getb32 (src->aux_size);
+ dst->string_loc = bfd_getb32 (src->string_loc);
+ dst->string_size = bfd_getb32 (src->string_size);
+ dst->free_list = bfd_getb32 (src->free_list);
+ dst->file_end = bfd_getb32 (src->file_end);
+ dst->checksum = bfd_getb32 (src->checksum);
+}
+
+/* Perform some initialization for an object. Save results of this
+ initialization in the BFD. */
+
+static const bfd_target *
+som_object_setup (bfd *abfd,
+ struct som_header *file_hdrp,
+ struct som_exec_auxhdr *aux_hdrp,
+ unsigned long current_offset)
+{
+ asection *section;
+
+ /* som_mkobject will set bfd_error if som_mkobject fails. */
+ if (! som_mkobject (abfd))
+ return NULL;
+
+ /* 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;
+ }
+
+ /* Save the auxiliary header. */
+ obj_som_exec_hdr (abfd) = aux_hdrp;
+
+ /* Allocate space to hold the saved exec header information. */
+ obj_som_exec_data (abfd) = bfd_zalloc (abfd, (bfd_size_type) 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 for an executable. If
+ it is not 4-byte aligned then it's not a proper code address and
+ we guess it's really the executable flags. For a main program,
+ we also consider zero to be indicative of a buggy linker, since
+ that is not a valid entry point. The entry point for a shared
+ library, however, can be zero so we do not consider that to be
+ indicative of a buggy linker. */
+ if (aux_hdrp)
+ {
+ int found = 0;
+
+ for (section = abfd->sections; section; section = section->next)
+ {
+ bfd_vma entry;
+
+ if ((section->flags & SEC_CODE) == 0)
+ continue;
+ entry = aux_hdrp->exec_entry + aux_hdrp->exec_tmem;
+ if (entry >= section->vma
+ && entry < section->vma + section->size)
+ found = 1;
+ }
+ if ((aux_hdrp->exec_entry == 0 && !(abfd->flags & DYNAMIC))
+ || (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;
+ }
+ }
+
+ obj_som_exec_data (abfd)->version_id = file_hdrp->version_id;
+
+ 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) = NULL;
+ obj_som_symtab (abfd) = 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 bfd_boolean
+setup_sections (bfd *abfd,
+ struct som_header *file_hdr,
+ unsigned long current_offset)
+{
+ char *space_strings;
+ unsigned int space_index, i;
+ unsigned int total_subspaces = 0;
+ asection **subspace_sections = NULL;
+ asection *section;
+ bfd_size_type amt;
+
+ /* First, read in space names. */
+ amt = file_hdr->space_strings_size;
+ space_strings = bfd_malloc (amt);
+ if (!space_strings && amt != 0)
+ goto error_return;
+
+ if (bfd_seek (abfd, current_offset + file_hdr->space_strings_location,
+ SEEK_SET) != 0)
+ goto error_return;
+ if (bfd_bread (space_strings, amt, abfd) != amt)
+ 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 som_space_dictionary_record space;
+ struct som_external_space_dictionary_record ext_space;
+ char *space_name;
+ struct som_external_subspace_dictionary_record ext_subspace;
+ struct som_subspace_dictionary_record subspace, save_subspace;
+ unsigned int subspace_index;
+ asection *space_asect;
+ bfd_size_type space_size = 0;
+ char *newname;
+
+ /* Read the space dictionary element. */
+ if (bfd_seek (abfd,
+ (current_offset + file_hdr->space_location
+ + space_index * sizeof (ext_space)),
+ SEEK_SET) != 0)
+ goto error_return;
+ amt = sizeof ext_space;
+ if (bfd_bread (&ext_space, amt, abfd) != amt)
+ goto error_return;
+
+ som_swap_space_dictionary_in (&ext_space, &space);
+
+ /* Setup the space name string. */
+ space_name = space.name + space_strings;
+
+ /* Make a section out of it. */
+ amt = strlen (space_name) + 1;
+ newname = bfd_alloc (abfd, amt);
+ if (!newname)
+ goto error_return;
+ strcpy (newname, space_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))
+ 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 ext_subspace),
+ SEEK_SET) != 0)
+ goto error_return;
+ amt = sizeof ext_subspace;
+ if (bfd_bread (&ext_subspace, amt, abfd) != amt)
+ 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 ext_subspace),
+ SEEK_SET) != 0)
+ goto error_return;
+
+ som_swap_subspace_dictionary_in (&ext_subspace, &subspace);
+
+ /* 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 = exact_log2 (subspace.alignment);
+ if (space_asect->alignment_power == (unsigned) -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 (save_subspace));
+
+ /* 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;
+ char *subspace_name;
+
+ /* Read in the next subspace. */
+ amt = sizeof ext_subspace;
+ if (bfd_bread (&ext_subspace, amt, abfd) != amt)
+ goto error_return;
+
+ som_swap_subspace_dictionary_in (&ext_subspace, &subspace);
+
+ /* Setup the subspace name string. */
+ subspace_name = subspace.name + space_strings;
+
+ amt = strlen (subspace_name) + 1;
+ newname = bfd_alloc (abfd, amt);
+ if (!newname)
+ goto error_return;
+ strcpy (newname, subspace_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,
+ subspace.is_comdat,
+ subspace.is_common,
+ subspace.dup_common))
+ 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.is_comdat || subspace.is_common || subspace.dup_common)
+ subspace_asect->flags |= SEC_LINK_ONCE;
+
+ 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 = (unsigned) -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->size = subspace.subspace_length;
+ subspace_asect->filepos = (subspace.file_loc_init_value
+ + current_offset);
+ subspace_asect->alignment_power = exact_log2 (subspace.alignment);
+ if (subspace_asect->alignment_power == (unsigned) -1)
+ goto error_return;
+
+ /* Keep track of the accumulated sizes of the sections. */
+ space_size += subspace.subspace_length;
+ }
+
+ /* This can happen for a .o which defines symbols in otherwise
+ empty subspaces. */
+ if (!save_subspace.file_loc_init_value)
+ space_asect->size = 0;
+ else
+ {
+ if (file_hdr->a_magic != RELOC_MAGIC)
+ {
+ /* Setup the size for the space section based upon the info
+ in the last subspace of the space. */
+ space_asect->size = (save_subspace.subspace_start
+ - space_asect->vma
+ + save_subspace.subspace_length);
+ }
+ else
+ {
+ /* The subspace_start field is not initialised in relocatable
+ only objects, so it cannot be used for length calculations.
+ Instead we use the space_size value which we have been
+ accumulating. This isn't an accurate estimate since it
+ ignores alignment and ordering issues. */
+ space_asect->size = space_size;
+ }
+ }
+ }
+ /* Now that we've read in all the subspace records, we need to assign
+ a target index to each subspace. */
+ amt = total_subspaces;
+ amt *= sizeof (asection *);
+ subspace_sections = bfd_malloc (amt);
+ 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 (bfd *abfd)
+{
+ struct som_external_header ext_file_hdr;
+ struct som_header file_hdr;
+ struct som_exec_auxhdr *aux_hdr_ptr = NULL;
+ unsigned long current_offset = 0;
+ struct som_external_lst_header ext_lst_header;
+ struct som_external_som_entry ext_som_entry;
+ bfd_size_type amt;
+ unsigned int loc;
+#define ENTRY_SIZE sizeof (struct som_external_som_entry)
+
+ amt = sizeof (struct som_external_header);
+ if (bfd_bread (&ext_file_hdr, amt, abfd) != amt)
+ {
+ if (bfd_get_error () != bfd_error_system_call)
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+
+ som_swap_header_in (&ext_file_hdr, &file_hdr);
+
+ if (!_PA_RISC_ID (file_hdr.system_id))
+ {
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+
+ switch (file_hdr.a_magic)
+ {
+ case RELOC_MAGIC:
+ case EXEC_MAGIC:
+ case SHARE_MAGIC:
+ case DEMAND_MAGIC:
+ case DL_MAGIC:
+ case SHL_MAGIC:
+#ifdef SHARED_MAGIC_CNX
+ case SHARED_MAGIC_CNX:
+#endif
+ break;
+
+ 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 NULL;
+ }
+
+ amt = sizeof (struct som_external_lst_header);
+ if (bfd_bread (&ext_lst_header, amt, abfd) != amt)
+ {
+ if (bfd_get_error () != bfd_error_system_call)
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+
+ /* Position to and read the first directory entry. */
+ loc = bfd_getb32 (ext_lst_header.dir_loc);
+ if (bfd_seek (abfd, loc, SEEK_SET) != 0)
+ {
+ if (bfd_get_error () != bfd_error_system_call)
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+
+ amt = ENTRY_SIZE;
+ if (bfd_bread (&ext_som_entry, amt, abfd) != amt)
+ {
+ if (bfd_get_error () != bfd_error_system_call)
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+
+ /* Now position to the first SOM. */
+ current_offset = bfd_getb32 (ext_som_entry.location);
+ if (bfd_seek (abfd, current_offset, SEEK_SET) != 0)
+ {
+ if (bfd_get_error () != bfd_error_system_call)
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+
+ /* And finally, re-read the som header. */
+ amt = sizeof (struct som_external_header);
+ if (bfd_bread (&ext_file_hdr, amt, abfd) != amt)
+ {
+ if (bfd_get_error () != bfd_error_system_call)
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+
+ som_swap_header_in (&ext_file_hdr, &file_hdr);
+
+ break;
+
+ default:
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+
+ if (file_hdr.version_id != OLD_VERSION_ID
+ && file_hdr.version_id != NEW_VERSION_ID)
+ {
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+
+ /* 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. */
+ if (file_hdr.aux_header_size != 0)
+ {
+ struct som_external_exec_auxhdr ext_exec_auxhdr;
+
+ aux_hdr_ptr = bfd_zalloc (abfd,
+ (bfd_size_type) sizeof (*aux_hdr_ptr));
+ if (aux_hdr_ptr == NULL)
+ return NULL;
+ amt = sizeof (struct som_external_exec_auxhdr);
+ if (bfd_bread (&ext_exec_auxhdr, amt, abfd) != amt)
+ {
+ if (bfd_get_error () != bfd_error_system_call)
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+ som_swap_exec_auxhdr_in (&ext_exec_auxhdr, aux_hdr_ptr);
+ }
+
+ 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 NULL;
+ }
+
+ /* This appears to be a valid SOM object. Do some initialization. */
+ return som_object_setup (abfd, &file_hdr, aux_hdr_ptr, current_offset);
+}
+
+/* Create a SOM object. */
+
+static bfd_boolean
+som_mkobject (bfd *abfd)
+{
+ /* Allocate memory to hold backend information. */
+ abfd->tdata.som_data = bfd_zalloc (abfd, (bfd_size_type) 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 bfd_boolean
+som_prep_headers (bfd *abfd)
+{
+ struct som_header *file_hdr;
+ asection *section;
+ bfd_size_type amt = sizeof (struct som_header);
+
+ /* Make and attach a file header to the BFD. */
+ file_hdr = bfd_zalloc (abfd, amt);
+ 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. */
+ amt = sizeof (struct som_exec_auxhdr);
+ obj_som_exec_hdr (abfd) = bfd_zalloc (abfd, amt);
+ 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;
+
+ /* 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. */
+ amt = sizeof (struct som_space_dictionary_record);
+ som_section_data (section)->space_dict = bfd_zalloc (abfd, amt);
+ 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. */
+ amt = sizeof (struct som_subspace_dictionary_record);
+ som_section_data (section)->subspace_dict = bfd_zalloc (abfd, amt);
+ 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_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 =
+ section->size;
+ som_section_data (section)->subspace_dict->initialization_length =
+ section->size;
+ 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;
+ som_section_data (section)->subspace_dict->is_comdat =
+ som_section_data (section)->copy_data->is_comdat;
+ som_section_data (section)->subspace_dict->is_common =
+ som_section_data (section)->copy_data->is_common;
+ som_section_data (section)->subspace_dict->dup_common =
+ som_section_data (section)->copy_data->dup_common;
+ }
+ }
+ return TRUE;
+}
+
+/* Return TRUE if the given section is a SOM space, FALSE otherwise. */
+
+static bfd_boolean
+som_is_space (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 bfd_boolean
+som_is_subspace (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 contains the given subspace. It
+ is safe to assume space really is a space, and subspace really
+ is a subspace. */
+
+static bfd_boolean
+som_is_container (asection *space, asection *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 (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 (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 (const void *arg1, const void *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 (const void *arg1, const void *arg2)
+{
+ asection **subspace1 = (asection **) arg1;
+ asection **subspace2 = (asection **) arg2;
+
+ 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 (bfd *abfd, asymbol **syms, unsigned long num_syms)
+{
+ unsigned long i;
+ asection *section;
+ asymbol **sorted_syms;
+ bfd_size_type amt;
+
+ /* 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 j;
+
+ /* Does this section have any relocations? */
+ if ((int) section->reloc_count <= 0)
+ continue;
+
+ /* Walk through each relocation for this section. */
+ for (j = 1; j < (int) section->reloc_count; j++)
+ {
+ arelent *reloc = section->orelocation[j];
+ 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. */
+ amt = num_syms;
+ amt *= sizeof (asymbol *);
+ sorted_syms = bfd_zalloc (abfd, amt);
+ 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 bfd_boolean
+som_write_fixups (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;
+ bfd_size_type amt;
+
+ 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;
+ unsigned int current_rounding_mode;
+#ifndef NO_PCREL_MODES
+ unsigned int current_call_mode;
+#endif
+
+ /* 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
+ finished 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;
+#ifndef NO_PCREL_MODES
+ current_call_mode = R_SHORT_PCREL_MODE;
+#endif
+
+ /* 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)
+ {
+ amt = p - tmp_space;
+ if (bfd_bwrite ((void *) tmp_space, amt, abfd) != amt)
+ 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:
+#ifndef NO_PCREL_MODES
+ case R_SHORT_PCREL_MODE:
+ case R_LONG_PCREL_MODE:
+#endif
+ 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, (bfd_vma) sym_num, p + 2);
+ p = try_prev_fixup (abfd, &subspace_reloc_size,
+ p, 4, reloc_queue);
+ }
+ else
+ abort ();
+ break;
+
+ case R_DATA_GPREL:
+ /* 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 < 0x10000000)
+ {
+ bfd_put_8 (abfd, bfd_reloc->howto->type, p);
+ bfd_put_8 (abfd, sym_num >> 16, p + 1);
+ bfd_put_16 (abfd, (bfd_vma) 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, (bfd_vma) sym_num, p + 2);
+ p = try_prev_fixup (abfd, &subspace_reloc_size,
+ p, 4, reloc_queue);
+ }
+ else
+ abort ();
+ break;
+
+ case R_ENTRY:
+ {
+ unsigned 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;
+
+#ifndef NO_PCREL_MODES
+ case R_LONG_PCREL_MODE:
+ case R_SHORT_PCREL_MODE:
+ if (bfd_reloc->howto->type != current_call_mode)
+ {
+ bfd_put_8 (abfd, bfd_reloc->howto->type, p);
+ subspace_reloc_size += 1;
+ p += 1;
+ current_call_mode = bfd_reloc->howto->type;
+ }
+ break;
+#endif
+
+ 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 an 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, (bfd_vma) 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, subsection->size - reloc_offset,
+ p, &subspace_reloc_size, reloc_queue);
+
+ /* Scribble out the relocations. */
+ amt = p - tmp_space;
+ if (bfd_bwrite ((void *) tmp_space, amt, abfd) != amt)
+ 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 bfd_boolean
+som_write_space_strings (bfd *abfd,
+ unsigned long current_offset,
+ unsigned int *string_sizep)
+{
+ /* Chunk of memory that we can use as buffer space, then throw
+ away. */
+ size_t tmp_space_size = SOM_TMP_BUFSIZE;
+ char *tmp_space = alloca (tmp_space_size);
+ char *p = tmp_space;
+ unsigned int strings_size = 0;
+ asection *section;
+ bfd_size_type amt;
+
+ /* Seek to the start of the space strings in preparation for writing
+ them out. */
+ if (bfd_seek (abfd, (file_ptr) 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)
+ {
+ size_t 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 and maybe allocate a larger
+ buffer. Each entry will take 4 bytes to hold the string
+ length + the string itself + null terminator. */
+ if (p - tmp_space + 5 + length > tmp_space_size)
+ {
+ /* Flush buffer before refilling or reallocating. */
+ amt = p - tmp_space;
+ if (bfd_bwrite ((void *) &tmp_space[0], amt, abfd) != amt)
+ return FALSE;
+
+ /* Reallocate if now empty buffer still too small. */
+ if (5 + length > tmp_space_size)
+ {
+ /* Ensure a minimum growth factor to avoid O(n**2) space
+ consumption for n strings. The optimal minimum
+ factor seems to be 2, as no other value can guarantee
+ wasting less than 50% space. (Note that we cannot
+ deallocate space allocated by `alloca' without
+ returning from this function.) The same technique is
+ used a few more times below when a buffer is
+ reallocated. */
+ if (2 * tmp_space_size < length + 5)
+ tmp_space_size = length + 5;
+ else
+ tmp_space_size = 2 * tmp_space_size;
+ tmp_space = alloca (tmp_space_size);
+ }
+
+ /* Reset to beginning of the (possibly new) 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, (bfd_vma) 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 = strings_size;
+ else
+ som_section_data (section)->subspace_dict->name = 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. */
+ amt = p - tmp_space;
+ if (bfd_bwrite ((void *) &tmp_space[0], amt, abfd) != amt)
+ return FALSE;
+ *string_sizep = strings_size;
+ return TRUE;
+}
+
+/* Write out the symbol string table. */
+
+static bfd_boolean
+som_write_symbol_strings (bfd *abfd,
+ unsigned long current_offset,
+ asymbol **syms,
+ unsigned int num_syms,
+ unsigned int *string_sizep,
+ struct som_compilation_unit *compilation_unit)
+{
+ unsigned int i;
+
+ /* Chunk of memory that we can use as buffer space, then throw
+ away. */
+ size_t tmp_space_size = SOM_TMP_BUFSIZE;
+ char *tmp_space = alloca (tmp_space_size);
+ char *p = tmp_space;
+
+ unsigned int strings_size = 0;
+ bfd_size_type amt;
+
+ /* 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 compilation unit header. On input, the
+ compilation unit header contains local copies of the strings.
+ Move them aside. */
+
+ /* Seek to the start of the space strings in preparation for writing
+ them out. */
+ if (bfd_seek (abfd, (file_ptr) current_offset, SEEK_SET) != 0)
+ return FALSE;
+
+ if (compilation_unit)
+ {
+ for (i = 0; i < 4; i++)
+ {
+ struct som_name_pt *name;
+ size_t length;
+
+ switch (i)
+ {
+ case 0:
+ name = &compilation_unit->name;
+ break;
+ case 1:
+ name = &compilation_unit->language_name;
+ break;
+ case 2:
+ name = &compilation_unit->product_id;
+ break;
+ case 3:
+ name = &compilation_unit->version_id;
+ break;
+ default:
+ abort ();
+ }
+
+ length = strlen (name->name);
+
+ /* If there is not enough room for the next entry, then dump
+ the current buffer contents now and maybe allocate a
+ larger buffer. */
+ if (p - tmp_space + 5 + length > tmp_space_size)
+ {
+ /* Flush buffer before refilling or reallocating. */
+ amt = p - tmp_space;
+ if (bfd_bwrite ((void *) &tmp_space[0], amt, abfd) != amt)
+ return FALSE;
+
+ /* Reallocate if now empty buffer still too small. */
+ if (5 + length > tmp_space_size)
+ {
+ /* See alloca above for discussion of new size. */
+ if (2 * tmp_space_size < 5 + length)
+ tmp_space_size = 5 + length;
+ else
+ tmp_space_size = 2 * tmp_space_size;
+ tmp_space = alloca (tmp_space_size);
+ }
+
+ /* Reset to beginning of the (possibly new) 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, (bfd_vma) length, p);
+ strings_size += 4;
+ p += 4;
+
+ /* Next comes the string itself + a null terminator. */
+ strcpy (p, name->name);
+
+ name->strx = 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++;
+ }
+ }
+ }
+
+ for (i = 0; i < num_syms; i++)
+ {
+ size_t length = strlen (syms[i]->name);
+
+ /* If there is not enough room for the next entry, then dump the
+ current buffer contents now and maybe allocate a larger buffer. */
+ if (p - tmp_space + 5 + length > tmp_space_size)
+ {
+ /* Flush buffer before refilling or reallocating. */
+ amt = p - tmp_space;
+ if (bfd_bwrite ((void *) &tmp_space[0], amt, abfd) != amt)
+ return FALSE;
+
+ /* Reallocate if now empty buffer still too small. */
+ if (5 + length > tmp_space_size)
+ {
+ /* See alloca above for discussion of new size. */
+ if (2 * tmp_space_size < 5 + length)
+ tmp_space_size = 5 + length;
+ else
+ tmp_space_size = 2 * tmp_space_size;
+ tmp_space = alloca (tmp_space_size);
+ }
+
+ /* Reset to beginning of the (possibly new) 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, (bfd_vma) 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. */
+ amt = p - tmp_space;
+ if (bfd_bwrite ((void *) &tmp_space[0], amt, abfd) != amt)
+ 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 bfd_boolean
+som_begin_writing (bfd *abfd)
+{
+ unsigned long current_offset = 0;
+ unsigned int strings_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 som_external_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_external_exec_auxhdr);
+ obj_som_file_hdr (abfd)->aux_header_size
+ += sizeof (struct som_external_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)
+ {
+ struct som_external_string_auxhdr ext_string_auxhdr;
+ bfd_size_type len;
+
+ if (bfd_seek (abfd, (file_ptr) current_offset, SEEK_SET) != 0)
+ return FALSE;
+
+ /* Write the aux_id structure and the string length. */
+ len = sizeof (struct som_external_string_auxhdr);
+ obj_som_file_hdr (abfd)->aux_header_size += len;
+ current_offset += len;
+ som_swap_string_auxhdr_out
+ (obj_som_version_hdr (abfd), &ext_string_auxhdr);
+ if (bfd_bwrite (&ext_string_auxhdr, len, abfd) != len)
+ return FALSE;
+
+ /* Write the version string. */
+ len = obj_som_version_hdr (abfd)->header_id.length - 4;
+ obj_som_file_hdr (abfd)->aux_header_size += len;
+ current_offset += len;
+ if (bfd_bwrite ((void *) obj_som_version_hdr (abfd)->string, len, abfd)
+ != len)
+ return FALSE;
+ }
+
+ if (obj_som_copyright_hdr (abfd) != NULL)
+ {
+ struct som_external_string_auxhdr ext_string_auxhdr;
+ bfd_size_type len;
+
+ if (bfd_seek (abfd, (file_ptr) current_offset, SEEK_SET) != 0)
+ return FALSE;
+
+ /* Write the aux_id structure and the string length. */
+ len = sizeof (struct som_external_string_auxhdr);
+ obj_som_file_hdr (abfd)->aux_header_size += len;
+ current_offset += len;
+ som_swap_string_auxhdr_out
+ (obj_som_copyright_hdr (abfd), &ext_string_auxhdr);
+ if (bfd_bwrite (&ext_string_auxhdr, len, abfd) != len)
+ return FALSE;
+
+ /* Write the copyright string. */
+ len = obj_som_copyright_hdr (abfd)->header_id.length - 4;
+ obj_som_file_hdr (abfd)->aux_header_size += len;
+ current_offset += len;
+ if (bfd_bwrite ((void *) obj_som_copyright_hdr (abfd)->string, len, 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 som_external_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 som_external_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))
+ 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 += sizeof (struct som_external_compilation_unit);
+ }
+
+ /* 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->size;
+ else if (abfd->flags & (EXEC_P | DYNAMIC)
+ && subsection->flags & SEC_DATA)
+ exec_header->exec_dsize += subsection->size;
+ som_section_data (subsection)->subspace_dict->file_loc_init_value
+ = current_offset;
+ subsection->filepos = current_offset;
+ current_offset += subsection->size;
+ subspace_offset += subsection->size;
+ }
+ /* Looks like uninitialized data. */
+ else
+ {
+ /* Update the size of the bss section. */
+ if (abfd->flags & (EXEC_P | DYNAMIC))
+ exec_header->exec_bsize += subsection->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 += subsection->size;
+ }
+ /* Looks like uninitialized data. */
+ else
+ {
+ som_section_data (subsection)->subspace_dict->file_loc_init_value
+ = 0;
+ som_section_data (subsection)->subspace_dict->
+ initialization_length = subsection->size;
+ }
+ }
+ /* 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, (file_ptr) current_offset - 1, SEEK_SET) != 0)
+ return FALSE;
+ if (bfd_bwrite ((void *) "", (bfd_size_type) 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 bfd_boolean
+som_finish_writing (bfd *abfd)
+{
+ int num_spaces = som_count_spaces (abfd);
+ asymbol **syms = bfd_get_outsymbols (abfd);
+ int i, num_syms;
+ int subspace_index = 0;
+ file_ptr location;
+ asection *section;
+ unsigned long current_offset;
+ unsigned int strings_size, total_reloc_size;
+ bfd_size_type amt;
+ struct som_external_header ext_header;
+
+ /* We must set up the version identifier here as objcopy/strip copy
+ private BFD data too late for us to handle this in som_begin_writing. */
+ if (obj_som_exec_data (abfd)
+ && obj_som_exec_data (abfd)->version_id)
+ obj_som_file_hdr (abfd)->version_id = obj_som_exec_data (abfd)->version_id;
+ else
+ obj_som_file_hdr (abfd)->version_id = NEW_VERSION_ID;
+
+ /* 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 som_external_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)))
+ 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))
+ 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))
+ 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)
+ {
+ struct som_external_subspace_dictionary_record ext_subspace_dict;
+
+ /* 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. */
+ som_swap_subspace_dictionary_record_out
+ (som_section_data (subsection)->subspace_dict, &ext_subspace_dict);
+ amt = sizeof (struct som_subspace_dictionary_record);
+ if (bfd_bwrite (&ext_subspace_dict, amt, abfd) != amt)
+ 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)
+ {
+ struct som_external_subspace_dictionary_record ext_subspace_dict;
+
+ /* 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. */
+ som_swap_subspace_dictionary_record_out
+ (som_section_data (subsection)->subspace_dict, &ext_subspace_dict);
+ amt = sizeof (struct som_subspace_dictionary_record);
+ if (bfd_bwrite (&ext_subspace_dict, amt, abfd) != amt)
+ return FALSE;
+ }
+ /* Goto the next section. */
+ section = section->next;
+ }
+
+ /* All the subspace dictionary 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++)
+ {
+ struct som_external_space_dictionary_record ext_space_dict;
+
+ /* Find a space. */
+ while (!som_is_space (section))
+ section = section->next;
+
+ /* Dump its header. */
+ som_swap_space_dictionary_out (som_section_data (section)->space_dict,
+ &ext_space_dict);
+ amt = sizeof (struct som_external_space_dictionary_record);
+ if (bfd_bwrite (&ext_space_dict, amt, abfd) != amt)
+ return FALSE;
+
+ /* Goto the next section. */
+ section = section->next;
+ }
+
+ /* Write the compilation unit record if there is one. */
+ if (obj_som_compilation_unit (abfd))
+ {
+ struct som_external_compilation_unit ext_comp_unit;
+
+ location = obj_som_file_hdr (abfd)->compiler_location;
+ if (bfd_seek (abfd, location, SEEK_SET) != 0)
+ return FALSE;
+
+ som_swap_compilation_unit_out
+ (obj_som_compilation_unit (abfd), &ext_comp_unit);
+
+ amt = sizeof (struct som_external_compilation_unit);
+ if (bfd_bwrite (&ext_comp_unit, amt, abfd) != amt)
+ 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;
+
+ /* Swap and compute the checksum for the file header just before writing
+ the header to disk. */
+ som_swap_header_out (obj_som_file_hdr (abfd), &ext_header);
+ bfd_putb32 (som_compute_checksum (&ext_header), ext_header.checksum);
+
+ /* 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;
+ amt = sizeof (struct som_external_header);
+ if (bfd_bwrite (&ext_header, amt, abfd) != amt)
+ return FALSE;
+
+ /* Now write the exec header. */
+ if (abfd->flags & (EXEC_P | DYNAMIC))
+ {
+ long tmp, som_length;
+ struct som_exec_auxhdr *exec_header;
+ struct som_external_exec_auxhdr ext_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 compatible 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;
+ }
+
+ som_swap_exec_auxhdr_out (exec_header, &ext_exec_header);
+
+ if (bfd_seek (abfd, obj_som_file_hdr (abfd)->aux_header_location,
+ SEEK_SET) != 0)
+ return FALSE;
+
+ amt = sizeof (ext_exec_header);
+ if (bfd_bwrite (&ext_exec_header, amt, abfd) != amt)
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/* Compute and return the checksum for a SOM file header. */
+
+static unsigned long
+som_compute_checksum (struct som_external_header *hdr)
+{
+ unsigned long checksum, count, i;
+ unsigned long *buffer = (unsigned long *) hdr;
+
+ checksum = 0;
+ count = sizeof (struct som_external_header) / 4;
+ for (i = 0; i < count; i++)
+ checksum ^= *(buffer + i);
+
+ return checksum;
+}
+
+static void
+som_bfd_derive_misc_symbol_info (bfd *abfd ATTRIBUTE_UNUSED,
+ 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
+ {
+ /* For BFD style common, the linker will choke unless we set the
+ type and scope to ST_STORAGE and SS_UNSAT, respectively. */
+ if (bfd_is_com_section (sym->section))
+ {
+ info->symbol_type = ST_STORAGE;
+ info->symbol_scope = SS_UNSAT;
+ }
+
+ /* 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 (bfd_is_abs_section (sym->section))
+ info->symbol_type = ST_ABSOLUTE;
+ else if (sym->section->flags & SEC_CODE)
+ info->symbol_type = ST_CODE;
+ else
+ 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_com_section (sym->section))
+ ;
+ else if (bfd_is_und_section (sym->section))
+ info->symbol_scope = SS_UNSAT;
+ else if (sym->flags & (BSF_EXPORT | BSF_WEAK))
+ info->symbol_scope = SS_UNIVERSAL;
+ /* Anything else which is not in the common section has scope
+ SS_LOCAL. */
+ else
+ 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;
+
+ /* The secondary_def field is for "weak" symbols. */
+ if (sym->flags & BSF_WEAK)
+ info->secondary_def = TRUE;
+ else
+ info->secondary_def = FALSE;
+
+ /* The is_comdat, is_common and dup_common fields provide various
+ flavors of common.
+
+ For data symbols, setting IS_COMMON provides Fortran style common
+ (duplicate definitions and overlapped initialization). Setting both
+ IS_COMMON and DUP_COMMON provides Cobol style common (duplicate
+ definitions as long as they are all the same length). In a shared
+ link data symbols retain their IS_COMMON and DUP_COMMON flags.
+ An IS_COMDAT data symbol is similar to a IS_COMMON | DUP_COMMON
+ symbol except in that it loses its IS_COMDAT flag in a shared link.
+
+ For code symbols, IS_COMDAT and DUP_COMMON have effect. Universal
+ DUP_COMMON code symbols are not exported from shared libraries.
+ IS_COMDAT symbols are exported but they lose their IS_COMDAT flag.
+
+ We take a simplified approach to setting the is_comdat, is_common
+ and dup_common flags in symbols based on the flag settings of their
+ subspace. This avoids having to add directives like `.comdat' but
+ the linker behavior is probably undefined if there is more than one
+ universal symbol (comdat key sysmbol) in a subspace.
+
+ The behavior of these flags is not well documentmented, so there
+ may be bugs and some surprising interactions with other flags. */
+ if (som_section_data (sym->section)
+ && som_section_data (sym->section)->subspace_dict
+ && info->symbol_scope == SS_UNIVERSAL
+ && (info->symbol_type == ST_ENTRY
+ || info->symbol_type == ST_CODE
+ || info->symbol_type == ST_DATA))
+ {
+ info->is_comdat
+ = som_section_data (sym->section)->subspace_dict->is_comdat;
+ info->is_common
+ = som_section_data (sym->section)->subspace_dict->is_common;
+ info->dup_common
+ = som_section_data (sym->section)->subspace_dict->dup_common;
+ }
+}
+
+/* Build and write, in one big chunk, the entire symbol table for
+ this BFD. */
+
+static bfd_boolean
+som_build_and_write_symbol_table (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 som_external_symbol_dictionary_record *som_symtab = NULL;
+ unsigned int i;
+ bfd_size_type 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;
+ symtab_size *= sizeof (struct som_external_symbol_dictionary_record);
+ som_symtab = bfd_zmalloc (symtab_size);
+ if (som_symtab == NULL && symtab_size != 0)
+ goto error_return;
+
+ /* Walk over each symbol. */
+ for (i = 0; i < num_syms; i++)
+ {
+ struct som_misc_symbol_info info;
+ unsigned int flags;
+
+ /* 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. */
+ bfd_putb32 (som_symbol_data (bfd_syms[i])->stringtab_offset,
+ som_symtab[i].name);
+
+ /* Derive SOM information from the BFD symbol. */
+ som_bfd_derive_misc_symbol_info (abfd, bfd_syms[i], &info);
+
+ /* Now use it. */
+ flags = (info.symbol_type << SOM_SYMBOL_TYPE_SH)
+ | (info.symbol_scope << SOM_SYMBOL_SCOPE_SH)
+ | (info.arg_reloc << SOM_SYMBOL_ARG_RELOC_SH)
+ | (3 << SOM_SYMBOL_XLEAST_SH)
+ | (info.secondary_def ? SOM_SYMBOL_SECONDARY_DEF : 0)
+ | (info.is_common ? SOM_SYMBOL_IS_COMMON : 0)
+ | (info.dup_common ? SOM_SYMBOL_DUP_COMMON : 0);
+ bfd_putb32 (flags, som_symtab[i].flags);
+
+ flags = (info.symbol_info << SOM_SYMBOL_SYMBOL_INFO_SH)
+ | (info.is_comdat ? SOM_SYMBOL_IS_COMDAT : 0);
+ bfd_putb32 (flags, som_symtab[i].info);
+ bfd_putb32 (info.symbol_value | info.priv_level,
+ som_symtab[i].symbol_value);
+ }
+
+ /* 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_bwrite ((void *) som_symtab, symtab_size, 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 bfd_boolean
+som_write_object_contents (bfd *abfd)
+{
+ if (! abfd->output_has_begun)
+ {
+ /* 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 bfd_boolean
+som_slurp_string_table (bfd *abfd)
+{
+ char *stringtab;
+ bfd_size_type amt;
+
+ /* 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. */
+ amt = obj_som_stringtab_size (abfd);
+ stringtab = bfd_zmalloc (amt);
+ if (stringtab == NULL)
+ return FALSE;
+
+ if (bfd_seek (abfd, obj_som_str_filepos (abfd), SEEK_SET) != 0)
+ return FALSE;
+
+ if (bfd_bread (stringtab, amt, abfd) != amt)
+ 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 (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. */
+
+asection *
+bfd_section_from_som_symbol
+ (bfd *abfd, struct som_external_symbol_dictionary_record *symbol)
+{
+ asection *section;
+ unsigned int flags = bfd_getb32 (symbol->flags);
+ unsigned int symbol_type = (flags >> SOM_SYMBOL_TYPE_SH) & SOM_SYMBOL_TYPE_MASK;
+
+ /* 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_type != ST_ENTRY
+ && symbol_type != ST_PRI_PROG
+ && symbol_type != ST_SEC_PROG
+ && symbol_type != ST_MILLICODE))
+ {
+ int idx = (bfd_getb32 (symbol->info) >> SOM_SYMBOL_SYMBOL_INFO_SH)
+ & SOM_SYMBOL_SYMBOL_INFO_MASK;
+
+ for (section = abfd->sections; section != NULL; section = section->next)
+ if (section->target_index == idx && som_is_subspace (section))
+ return section;
+ }
+ else
+ {
+ unsigned int value = bfd_getb32 (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->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 (bfd *abfd)
+{
+ int symbol_count = bfd_get_symcount (abfd);
+ int symsize = sizeof (struct som_external_symbol_dictionary_record);
+ char *stringtab;
+ struct som_external_symbol_dictionary_record *buf = NULL, *bufp, *endbufp;
+ som_symbol_type *sym, *symbase;
+ bfd_size_type amt;
+
+ /* 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);
+
+ amt = symbol_count;
+ amt *= sizeof (som_symbol_type);
+ symbase = bfd_zmalloc (amt);
+ if (symbase == NULL)
+ goto error_return;
+
+ /* Read in the external SOM representation. */
+ amt = symbol_count;
+ amt *= symsize;
+ buf = bfd_malloc (amt);
+ if (buf == NULL && amt != 0)
+ goto error_return;
+ if (bfd_seek (abfd, obj_som_sym_filepos (abfd), SEEK_SET) != 0)
+ goto error_return;
+ if (bfd_bread (buf, amt, abfd) != amt)
+ goto error_return;
+
+ /* Iterate over all the symbols and internalize them. */
+ endbufp = buf + symbol_count;
+ for (bufp = buf, sym = symbase; bufp < endbufp; ++bufp)
+ {
+ unsigned int flags = bfd_getb32 (bufp->flags);
+ unsigned int symbol_type =
+ (flags >> SOM_SYMBOL_TYPE_SH) & SOM_SYMBOL_TYPE_MASK;
+ unsigned int symbol_scope =
+ (flags >> SOM_SYMBOL_SCOPE_SH) & SOM_SYMBOL_SCOPE_MASK;
+
+ /* I don't think we care about these. */
+ if (symbol_type == ST_SYM_EXT || symbol_type == ST_ARG_EXT)
+ continue;
+
+ /* Set some private data we care about. */
+ if (symbol_type == ST_NULL)
+ som_symbol_data (sym)->som_type = SYMBOL_TYPE_UNKNOWN;
+ else if (symbol_type == ST_ABSOLUTE)
+ som_symbol_data (sym)->som_type = SYMBOL_TYPE_ABSOLUTE;
+ else if (symbol_type == ST_DATA)
+ som_symbol_data (sym)->som_type = SYMBOL_TYPE_DATA;
+ else if (symbol_type == ST_CODE)
+ som_symbol_data (sym)->som_type = SYMBOL_TYPE_CODE;
+ else if (symbol_type == ST_PRI_PROG)
+ som_symbol_data (sym)->som_type = SYMBOL_TYPE_PRI_PROG;
+ else if (symbol_type == ST_SEC_PROG)
+ som_symbol_data (sym)->som_type = SYMBOL_TYPE_SEC_PROG;
+ else if (symbol_type == ST_ENTRY)
+ som_symbol_data (sym)->som_type = SYMBOL_TYPE_ENTRY;
+ else if (symbol_type == ST_MILLICODE)
+ som_symbol_data (sym)->som_type = SYMBOL_TYPE_MILLICODE;
+ else if (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 =
+ (flags >> SOM_SYMBOL_ARG_RELOC_SH) & SOM_SYMBOL_ARG_RELOC_MASK;
+
+ /* Some reasonable defaults. */
+ sym->symbol.the_bfd = abfd;
+ sym->symbol.name = bfd_getb32 (bufp->name) + stringtab;
+ sym->symbol.value = bfd_getb32 (bufp->symbol_value);
+ sym->symbol.section = 0;
+ sym->symbol.flags = 0;
+
+ switch (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 SS_UNSAT, then these are
+ undefined function symbols. */
+ if (symbol_scope == SS_UNSAT)
+ sym->symbol.flags |= BSF_FUNCTION;
+
+ default:
+ break;
+ }
+
+ /* Handle scoping and section information. */
+ switch (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 (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 (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;
+
+ 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;
+ }
+
+ /* Check for a weak symbol. */
+ if (flags & SOM_SYMBOL_SECONDARY_DEF)
+ sym->symbol.flags |= BSF_WEAK;
+
+ /* 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 (CONST_STRNEQ (sym->symbol.name, "L$0\002"))
+ {
+ sym->symbol.flags |= BSF_SECTION_SYM;
+ sym->symbol.name = sym->symbol.section->name;
+ }
+ else if (CONST_STRNEQ (sym->symbol.name, "L$0\001"))
+ 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_canonicalize_symtab (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 (bfd *abfd)
+{
+ bfd_size_type amt = sizeof (som_symbol_type);
+ som_symbol_type *new_symbol_type = bfd_zalloc (abfd, amt);
+
+ if (new_symbol_type == NULL)
+ return NULL;
+ new_symbol_type->symbol.the_bfd = abfd;
+
+ return &new_symbol_type->symbol;
+}
+
+/* Print symbol information. */
+
+static void
+som_print_symbol (bfd *abfd,
+ void *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 (abfd, (void *) file, symbol);
+ fprintf (file, " %s\t%s", section_name, symbol->name);
+ break;
+ }
+ }
+}
+
+static bfd_boolean
+som_bfd_is_local_label_name (bfd *abfd ATTRIBUTE_UNUSED,
+ 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 (unsigned char *fixup,
+ unsigned int end,
+ arelent *internal_relocs,
+ asection *section,
+ asymbol **symbols,
+ bfd_boolean just_count)
+{
+ unsigned int op, varname, deallocate_contents = 0;
+ unsigned char *end_fixups = &fixup[end];
+ const struct fixup_format *fp;
+ const 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)
+ {
+ /* 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. */
+ bfd_byte *contents;
+ if (!bfd_malloc_and_get_section (section->owner, section,
+ &contents))
+ {
+ if (contents != NULL)
+ free (contents);
+ return (unsigned) -1;
+ }
+ section->contents = contents;
+ deallocate_contents = 1;
+ }
+ 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 bfd_boolean
+som_slurp_reloc_table (bfd *abfd,
+ asection *section,
+ asymbol **symbols,
+ bfd_boolean just_count)
+{
+ unsigned char *external_relocs;
+ unsigned int fixup_stream_size;
+ arelent *internal_relocs;
+ unsigned int num_relocs;
+ bfd_size_type amt;
+
+ 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 == (unsigned) -1)
+ {
+ amt = fixup_stream_size;
+ external_relocs = bfd_malloc (amt);
+ if (external_relocs == 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_bread (external_relocs, amt, abfd) != amt)
+ 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 != NULL)
+ return TRUE;
+
+ amt = num_relocs;
+ amt *= sizeof (arelent);
+ internal_relocs = bfd_zalloc (abfd, (amt));
+ if (internal_relocs == 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 (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 enough space to hold the
+ NULL pointer which will be installed if som_canonicalize_reloc
+ is called. */
+ return sizeof (arelent *);
+}
+
+/* Convert relocations from SOM (external) form into BFD internal
+ form. Return the number of relocations. */
+
+static long
+som_canonicalize_reloc (bfd *abfd,
+ sec_ptr section,
+ arelent **relptr,
+ asymbol **symbols)
+{
+ arelent *tblptr;
+ int count;
+
+ if (! som_slurp_reloc_table (abfd, section, symbols, FALSE))
+ return -1;
+
+ count = section->reloc_count;
+ tblptr = section->relocation;
+
+ while (count--)
+ *relptr++ = tblptr++;
+
+ *relptr = NULL;
+ return section->reloc_count;
+}
+
+extern const bfd_target hppa_som_vec;
+
+/* A hook to set up object file dependent section information. */
+
+static bfd_boolean
+som_new_section_hook (bfd *abfd, asection *newsect)
+{
+ if (!newsect->used_by_bfd)
+ {
+ bfd_size_type amt = sizeof (struct som_section_data_struct);
+
+ newsect->used_by_bfd = bfd_zalloc (abfd, amt);
+ if (!newsect->used_by_bfd)
+ return FALSE;
+ }
+ newsect->alignment_power = 3;
+
+ /* We allow more than three sections internally. */
+ return _bfd_generic_new_section_hook (abfd, newsect);
+}
+
+/* Copy any private info we understand from the input symbol
+ to the output symbol. */
+
+static bfd_boolean
+som_bfd_copy_private_symbol_data (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 bfd_boolean
+som_bfd_copy_private_section_data (bfd *ibfd,
+ asection *isection,
+ bfd *obfd,
+ asection *osection)
+{
+ bfd_size_type amt;
+
+ /* 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;
+
+ amt = sizeof (struct som_copyable_section_data_struct);
+ som_section_data (osection)->copy_data = bfd_zalloc (obfd, amt);
+ 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 bfd_boolean
+som_bfd_copy_private_bfd_data (bfd *ibfd, bfd *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) = bfd_zalloc (obfd, (bfd_size_type) 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;
+}
+
+/* Display the SOM header. */
+
+static bfd_boolean
+som_bfd_print_private_bfd_data (bfd *abfd, void *farg)
+{
+ struct som_exec_auxhdr *exec_header;
+ struct som_aux_id* auxhdr;
+ FILE *f;
+
+ f = (FILE *) farg;
+
+ exec_header = obj_som_exec_hdr (abfd);
+ if (exec_header)
+ {
+ fprintf (f, _("\nExec Auxiliary Header\n"));
+ fprintf (f, " flags ");
+ auxhdr = &exec_header->som_auxhdr;
+ if (auxhdr->mandatory)
+ fprintf (f, "mandatory ");
+ if (auxhdr->copy)
+ fprintf (f, "copy ");
+ if (auxhdr->append)
+ fprintf (f, "append ");
+ if (auxhdr->ignore)
+ fprintf (f, "ignore ");
+ fprintf (f, "\n");
+ fprintf (f, " type %#x\n", auxhdr->type);
+ fprintf (f, " length %#x\n", auxhdr->length);
+
+ /* Note that, depending on the HP-UX version, the following fields can be
+ either ints, or longs. */
+
+ fprintf (f, " text size %#lx\n", (long) exec_header->exec_tsize);
+ fprintf (f, " text memory offset %#lx\n", (long) exec_header->exec_tmem);
+ fprintf (f, " text file offset %#lx\n", (long) exec_header->exec_tfile);
+ fprintf (f, " data size %#lx\n", (long) exec_header->exec_dsize);
+ fprintf (f, " data memory offset %#lx\n", (long) exec_header->exec_dmem);
+ fprintf (f, " data file offset %#lx\n", (long) exec_header->exec_dfile);
+ fprintf (f, " bss size %#lx\n", (long) exec_header->exec_bsize);
+ fprintf (f, " entry point %#lx\n", (long) exec_header->exec_entry);
+ fprintf (f, " loader flags %#lx\n", (long) exec_header->exec_flags);
+ fprintf (f, " bss initializer %#lx\n", (long) exec_header->exec_bfill);
+ }
+
+ return TRUE;
+}
+
+/* Set backend info for sections which can not be described
+ in the BFD data structures. */
+
+bfd_boolean
+bfd_som_set_section_attributes (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)
+ {
+ bfd_size_type amt = sizeof (struct som_copyable_section_data_struct);
+
+ som_section_data (section)->copy_data = bfd_zalloc (section->owner, amt);
+ 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. */
+
+bfd_boolean
+bfd_som_set_subsection_attributes (asection *section,
+ asection *container,
+ int access_ctr,
+ unsigned int sort_key,
+ int quadrant,
+ int comdat,
+ int common,
+ int dup_common)
+{
+ /* Allocate memory to hold the magic information. */
+ if (som_section_data (section)->copy_data == NULL)
+ {
+ bfd_size_type amt = sizeof (struct som_copyable_section_data_struct);
+
+ som_section_data (section)->copy_data = bfd_zalloc (section->owner, amt);
+ 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_ctr;
+ som_section_data (section)->copy_data->quadrant = quadrant;
+ som_section_data (section)->copy_data->container = container;
+ som_section_data (section)->copy_data->is_comdat = comdat;
+ som_section_data (section)->copy_data->is_common = common;
+ som_section_data (section)->copy_data->dup_common = dup_common;
+ 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 (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. */
+
+bfd_boolean
+bfd_som_attach_aux_hdr (bfd *abfd, int type, char *string)
+{
+ bfd_size_type amt;
+
+ if (type == VERSION_AUX_ID)
+ {
+ size_t len = strlen (string);
+ int pad = 0;
+
+ if (len % 4)
+ pad = (4 - (len % 4));
+ amt = sizeof (struct som_string_auxhdr) + len + pad;
+ obj_som_version_hdr (abfd) = bfd_zalloc (abfd, amt);
+ 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 = 4 + len + pad;
+ obj_som_version_hdr (abfd)->string_length = len;
+ memcpy (obj_som_version_hdr (abfd)->string, string, len);
+ memset (obj_som_version_hdr (abfd)->string + len, 0, pad);
+ }
+ else if (type == COPYRIGHT_AUX_ID)
+ {
+ int len = strlen (string);
+ int pad = 0;
+
+ if (len % 4)
+ pad = (4 - (len % 4));
+ amt = sizeof (struct som_string_auxhdr) + len + pad;
+ obj_som_copyright_hdr (abfd) = bfd_zalloc (abfd, amt);
+ 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 + 4;
+ obj_som_copyright_hdr (abfd)->string_length = len;
+ memcpy (obj_som_copyright_hdr (abfd)->string, string, len);
+ memset (obj_som_copyright_hdr (abfd)->string + len, 0, pad);
+ }
+ return TRUE;
+}
+
+/* Attach a compilation unit header to the BFD backend so that it may be
+ written into the object file. */
+
+bfd_boolean
+bfd_som_attach_compilation_unit (bfd *abfd,
+ const char *name,
+ const char *language_name,
+ const char *product_id,
+ const char *version_id)
+{
+ struct som_compilation_unit *n;
+
+ n = (struct som_compilation_unit *) bfd_zalloc
+ (abfd, (bfd_size_type) sizeof (*n));
+ if (n == NULL)
+ return FALSE;
+
+#define STRDUP(f) \
+ if (f != NULL) \
+ { \
+ n->f.name = bfd_alloc (abfd, (bfd_size_type) strlen (f) + 1); \
+ if (n->f.name == NULL) \
+ return FALSE; \
+ strcpy (n->f.name, f); \
+ }
+
+ STRDUP (name);
+ STRDUP (language_name);
+ STRDUP (product_id);
+ STRDUP (version_id);
+
+#undef STRDUP
+
+ obj_som_compilation_unit (abfd) = n;
+
+ return TRUE;
+}
+
+static bfd_boolean
+som_get_section_contents (bfd *abfd,
+ sec_ptr section,
+ void *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->size
+ || bfd_seek (abfd, (file_ptr) (section->filepos + offset), SEEK_SET) != 0
+ || bfd_bread (location, count, abfd) != count)
+ return FALSE; /* On error. */
+ return TRUE;
+}
+
+static bfd_boolean
+som_set_section_contents (bfd *abfd,
+ sec_ptr section,
+ const void *location,
+ file_ptr offset,
+ bfd_size_type count)
+{
+ if (! abfd->output_has_begun)
+ {
+ /* 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) != 0)
+ return FALSE;
+
+ if (bfd_bwrite (location, count, abfd) != count)
+ return FALSE;
+ return TRUE;
+}
+
+static bfd_boolean
+som_set_arch_mach (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 bfd_boolean
+som_find_nearest_line (bfd *abfd,
+ asymbol **symbols,
+ asection *section,
+ bfd_vma offset,
+ const char **filename_ptr,
+ const char **functionname_ptr,
+ unsigned int *line_ptr,
+ unsigned int *discriminator_ptr)
+{
+ bfd_boolean found;
+ asymbol *func;
+ bfd_vma low_func;
+ asymbol **p;
+
+ if (discriminator_ptr)
+ *discriminator_ptr = 0;
+
+ if (! _bfd_stab_section_find_nearest_line (abfd, symbols, section, offset,
+ & found, filename_ptr,
+ functionname_ptr, line_ptr,
+ & somdata (abfd).line_info))
+ return FALSE;
+
+ if (found)
+ return TRUE;
+
+ if (symbols == NULL)
+ return FALSE;
+
+ /* Fallback: find function name from symbols table. */
+ func = NULL;
+ low_func = 0;
+
+ for (p = symbols; *p != NULL; p++)
+ {
+ som_symbol_type *q = (som_symbol_type *) *p;
+
+ if (q->som_type == SYMBOL_TYPE_ENTRY
+ && q->symbol.section == section
+ && q->symbol.value >= low_func
+ && q->symbol.value <= offset)
+ {
+ func = (asymbol *) q;
+ low_func = q->symbol.value;
+ }
+ }
+
+ if (func == NULL)
+ return FALSE;
+
+ *filename_ptr = NULL;
+ *functionname_ptr = bfd_asymbol_name (func);
+ *line_ptr = 0;
+
+ return TRUE;
+}
+
+static int
+som_sizeof_headers (bfd *abfd ATTRIBUTE_UNUSED,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED)
+{
+ (*_bfd_error_handler) (_("som_sizeof_headers unimplemented"));
+ 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 (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 (asymbol *symbol)
+{
+ char c;
+
+ if (bfd_is_com_section (symbol->section))
+ return 'C';
+ if (bfd_is_und_section (symbol->section))
+ {
+ if (symbol->flags & BSF_WEAK)
+ {
+ /* If weak, determine if it's specifically an object
+ or non-object weak. */
+ if (symbol->flags & BSF_OBJECT)
+ return 'v';
+ else
+ return 'w';
+ }
+ else
+ return 'U';
+ }
+ if (bfd_is_ind_section (symbol->section))
+ return 'I';
+ if (symbol->flags & BSF_WEAK)
+ {
+ /* If weak, determine if it's specifically an object
+ or non-object weak. */
+ if (symbol->flags & BSF_OBJECT)
+ return 'V';
+ else
+ return 'W';
+ }
+ 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 (bfd *ignore_abfd ATTRIBUTE_UNUSED,
+ 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 bfd_boolean
+som_bfd_count_ar_symbols (bfd *abfd,
+ struct som_lst_header *lst_header,
+ symindex *count)
+{
+ unsigned int i;
+ unsigned char *hash_table;
+ bfd_size_type amt;
+ file_ptr lst_filepos;
+
+ lst_filepos = bfd_tell (abfd) - sizeof (struct som_external_lst_header);
+
+ amt = lst_header->hash_size * 4;
+ hash_table = bfd_malloc (amt);
+ if (hash_table == NULL && amt != 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_bread ((void *) hash_table, amt, abfd) != amt)
+ 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 som_external_lst_symbol_record ext_lst_symbol;
+ unsigned int hash_val = bfd_getb32 (hash_table + 4 * i);
+
+ /* An empty chain has zero as it's file offset. */
+ if (hash_val == 0)
+ continue;
+
+ /* Seek to the first symbol in this hash chain. */
+ if (bfd_seek (abfd, lst_filepos + hash_val, SEEK_SET) != 0)
+ goto error_return;
+
+ /* Read in this symbol and update the counter. */
+ amt = sizeof (ext_lst_symbol);
+ if (bfd_bread ((void *) &ext_lst_symbol, amt, abfd) != amt)
+ goto error_return;
+
+ (*count)++;
+
+ /* Now iterate through the rest of the symbols on this chain. */
+ while (1)
+ {
+ unsigned int next_entry = bfd_getb32 (ext_lst_symbol.next_entry);
+
+ if (next_entry == 0)
+ break;
+
+ /* Seek to the next symbol. */
+ if (bfd_seek (abfd, lst_filepos + next_entry, SEEK_SET) != 0)
+ goto error_return;
+
+ /* Read the symbol in and update the counter. */
+ amt = sizeof (ext_lst_symbol);
+ if (bfd_bread ((void *) &ext_lst_symbol, amt, abfd) != amt)
+ 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 bfd_boolean
+som_bfd_fill_in_ar_symbols (bfd *abfd,
+ struct som_lst_header *lst_header,
+ carsym **syms)
+{
+ unsigned int i;
+ carsym *set = syms[0];
+ unsigned char *hash_table;
+ struct som_external_som_entry *som_dict = NULL;
+ bfd_size_type amt;
+ file_ptr lst_filepos;
+ unsigned int string_loc;
+
+ lst_filepos = bfd_tell (abfd) - sizeof (struct som_external_lst_header);
+ amt = lst_header->hash_size * 4;
+ hash_table = bfd_malloc (amt);
+ if (hash_table == NULL && amt != 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_bread ((void *) hash_table, amt, abfd) != amt)
+ 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;
+
+ amt = lst_header->module_count * sizeof (struct som_external_som_entry);
+ som_dict = bfd_malloc (amt);
+ if (som_dict == NULL && amt != 0)
+ goto error_return;
+
+ if (bfd_bread ((void *) som_dict, amt, abfd) != amt)
+ goto error_return;
+
+ string_loc = lst_header->string_loc;
+
+ /* Walk each chain filling in the carsyms as we go along. */
+ for (i = 0; i < lst_header->hash_size; i++)
+ {
+ struct som_external_lst_symbol_record lst_symbol;
+ unsigned int hash_val;
+ unsigned int len;
+ unsigned char ext_len[4];
+
+ /* An empty chain has zero as it's file offset. */
+ hash_val = bfd_getb32 (hash_table + 4 * i);
+ if (hash_val == 0)
+ continue;
+
+ /* Seek to and read the first symbol on the chain. */
+ if (bfd_seek (abfd, lst_filepos + hash_val, SEEK_SET) != 0)
+ goto error_return;
+
+ amt = sizeof (lst_symbol);
+ if (bfd_bread ((void *) &lst_symbol, amt, abfd) != amt)
+ 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 + string_loc
+ + bfd_getb32 (lst_symbol.name) - 4), SEEK_SET) != 0)
+ goto error_return;
+
+ if (bfd_bread (&ext_len, (bfd_size_type) 4, abfd) != 4)
+ goto error_return;
+ len = bfd_getb32 (ext_len);
+
+ /* Allocate space for the name and null terminate it too. */
+ set->name = bfd_zalloc (abfd, (bfd_size_type) len + 1);
+ if (!set->name)
+ goto error_return;
+ if (bfd_bread (set->name, (bfd_size_type) 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 =
+ bfd_getb32 (som_dict[bfd_getb32 (lst_symbol.som_index)].location)
+ - sizeof (struct ar_hdr);
+
+ /* Go to the next symbol. */
+ set++;
+
+ /* Iterate through the rest of the chain. */
+ while (1)
+ {
+ unsigned int next_entry = bfd_getb32 (lst_symbol.next_entry);
+
+ if (next_entry == 0)
+ break;
+
+ /* Seek to the next symbol and read it in. */
+ if (bfd_seek (abfd, lst_filepos + next_entry, SEEK_SET) != 0)
+ goto error_return;
+
+ amt = sizeof (lst_symbol);
+ if (bfd_bread ((void *) &lst_symbol, amt, abfd) != amt)
+ goto error_return;
+
+ /* Seek to the name length & string and read them in. */
+ if (bfd_seek (abfd, lst_filepos + string_loc
+ + bfd_getb32 (lst_symbol.name) - 4, SEEK_SET) != 0)
+ goto error_return;
+
+ if (bfd_bread (&ext_len, (bfd_size_type) 4, abfd) != 4)
+ goto error_return;
+ len = bfd_getb32 (ext_len);
+
+ /* Allocate space for the name and null terminate it too. */
+ set->name = bfd_zalloc (abfd, (bfd_size_type) len + 1);
+ if (!set->name)
+ goto error_return;
+
+ if (bfd_bread (set->name, (bfd_size_type) 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 =
+ bfd_getb32 (som_dict[bfd_getb32 (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 bfd_boolean
+som_slurp_armap (bfd *abfd)
+{
+ struct som_external_lst_header ext_lst_header;
+ struct som_lst_header lst_header;
+ struct ar_hdr ar_header;
+ unsigned int parsed_size;
+ struct artdata *ardata = bfd_ardata (abfd);
+ char nextname[17];
+ bfd_size_type amt = 16;
+ int i = bfd_bread ((void *) nextname, amt, 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 (! CONST_STRNEQ (nextname, "/ "))
+ {
+ bfd_has_map (abfd) = FALSE;
+ return TRUE;
+ }
+
+ /* Read in and sanity check the archive header. */
+ amt = sizeof (struct ar_hdr);
+ if (bfd_bread ((void *) &ar_header, amt, abfd) != amt)
+ 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. */
+ amt = sizeof (struct som_external_lst_header);
+ if (bfd_bread ((void *) &ext_lst_header, amt, abfd) != amt)
+ return FALSE;
+
+ som_swap_lst_header_in (&ext_lst_header, &lst_header);
+
+ /* 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))
+ return FALSE;
+
+ /* Get back to the start of the library symbol table. */
+ if (bfd_seek (abfd, (ardata->first_file_filepos - parsed_size
+ + sizeof (struct som_external_lst_header)),
+ SEEK_SET) != 0)
+ return FALSE;
+
+ /* Initialize the cache and allocate space for the library symbols. */
+ ardata->cache = 0;
+ amt = ardata->symdef_count;
+ amt *= sizeof (carsym);
+ ardata->symdefs = bfd_alloc (abfd, amt);
+ if (!ardata->symdefs)
+ return FALSE;
+
+ /* Now fill in the canonical archive symbols. */
+ if (! som_bfd_fill_in_ar_symbols (abfd, &lst_header, &ardata->symdefs))
+ 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 bfd_boolean
+som_bfd_prep_for_ar_write (bfd *abfd,
+ unsigned int *num_syms,
+ unsigned int *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->archive_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))
+ 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 += strlen (sym->symbol.name) + 5;
+ while (*stringsize % 4)
+ (*stringsize)++;
+ }
+
+ curr_bfd = curr_bfd->archive_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 (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 bfd_boolean
+som_bfd_ar_write_symbol_stuff (bfd *abfd,
+ unsigned int nsyms,
+ unsigned int string_size,
+ struct som_external_lst_header lst,
+ unsigned elength)
+{
+ char *strings = NULL, *p;
+ struct som_external_lst_symbol_record *lst_syms = NULL, *curr_lst_sym;
+ bfd *curr_bfd;
+ unsigned char *hash_table = NULL;
+ struct som_external_som_entry *som_dict = NULL;
+ struct som_external_lst_symbol_record **last_hash_entry = NULL;
+ unsigned int curr_som_offset, som_index = 0;
+ bfd_size_type amt;
+ unsigned int module_count;
+ unsigned int hash_size;
+
+ hash_size = bfd_getb32 (lst.hash_size);
+ amt = hash_size * 4;
+ hash_table = bfd_zmalloc (amt);
+ if (hash_table == NULL && hash_size != 0)
+ goto error_return;
+
+ module_count = bfd_getb32 (lst.module_count);
+ amt = module_count * sizeof (struct som_external_som_entry);
+ som_dict = bfd_zmalloc (amt);
+ if (som_dict == NULL && module_count != 0)
+ goto error_return;
+
+ amt = hash_size * sizeof (struct som_external_lst_symbol_record *);
+ last_hash_entry = bfd_zmalloc (amt);
+ if (last_hash_entry == NULL && hash_size != 0)
+ goto error_return;
+
+ /* 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) + bfd_getb32 (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... */
+ amt = nsyms;
+ amt *= sizeof (struct som_external_lst_symbol_record);
+ lst_syms = bfd_malloc (amt);
+ if (lst_syms == NULL && nsyms != 0)
+ goto error_return;
+ strings = bfd_malloc ((bfd_size_type) 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->archive_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))
+ 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;
+ struct som_external_lst_symbol_record *last;
+ unsigned int symbol_pos;
+ unsigned int slen;
+ unsigned int symbol_key;
+ unsigned int flags;
+
+ /* 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 (bfd_getb32 (som_dict[som_index].location) == 0)
+ {
+ bfd_putb32 (curr_som_offset, som_dict[som_index].location);
+ bfd_putb32 (arelt_size (curr_bfd), som_dict[som_index].length);
+ }
+
+ symbol_key = som_bfd_ar_symbol_hash (&sym->symbol);
+
+ /* Fill in the lst symbol record. */
+ flags = 0;
+ if (info.secondary_def)
+ flags |= LST_SYMBOL_SECONDARY_DEF;
+ flags |= info.symbol_type << LST_SYMBOL_SYMBOL_TYPE_SH;
+ flags |= info.symbol_scope << LST_SYMBOL_SYMBOL_SCOPE_SH;
+ if (bfd_is_com_section (sym->symbol.section))
+ flags |= LST_SYMBOL_IS_COMMON;
+ if (info.dup_common)
+ flags |= LST_SYMBOL_DUP_COMMON;
+ flags |= 3 << LST_SYMBOL_XLEAST_SH;
+ flags |= info.arg_reloc << LST_SYMBOL_ARG_RELOC_SH;
+ bfd_putb32 (flags, curr_lst_sym->flags);
+ bfd_putb32 (p - strings + 4, curr_lst_sym->name);
+ bfd_putb32 (0, curr_lst_sym->qualifier_name);
+ bfd_putb32 (info.symbol_info, curr_lst_sym->symbol_info);
+ bfd_putb32 (info.symbol_value | info.priv_level,
+ curr_lst_sym->symbol_value);
+ bfd_putb32 (0, curr_lst_sym->symbol_descriptor);
+ curr_lst_sym->reserved = 0;
+ bfd_putb32 (som_index, curr_lst_sym->som_index);
+ bfd_putb32 (symbol_key, curr_lst_sym->symbol_key);
+ bfd_putb32 (0, curr_lst_sym->next_entry);
+
+ /* Insert into the hash table. */
+ symbol_pos =
+ (curr_lst_sym - lst_syms)
+ * sizeof (struct som_external_lst_symbol_record)
+ + hash_size * 4
+ + module_count * sizeof (struct som_external_som_entry)
+ + sizeof (struct som_external_lst_header);
+ last = last_hash_entry[symbol_key % hash_size];
+ if (last != NULL)
+ {
+ /* There is already something at the head of this hash chain,
+ so tack this symbol onto the end of the chain. */
+ bfd_putb32 (symbol_pos, last->next_entry);
+ }
+ else
+ /* First entry in this hash chain. */
+ bfd_putb32 (symbol_pos, hash_table + 4 * (symbol_key % hash_size));
+
+ /* Keep track of the last symbol we added to this chain so we can
+ easily update its next_entry pointer. */
+ last_hash_entry[symbol_key % hash_size] = curr_lst_sym;
+
+ /* Update the string table. */
+ slen = strlen (sym->symbol.name);
+ bfd_put_32 (abfd, slen, p);
+ p += 4;
+ slen++; /* Nul terminator. */
+ memcpy (p, sym->symbol.name, slen);
+ p += slen;
+ while (slen % 4)
+ {
+ bfd_put_8 (abfd, 0, p);
+ p++;
+ slen++;
+ }
+ BFD_ASSERT (p <= strings + string_size);
+
+ /* 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) &~ (unsigned) 1;
+ curr_bfd = curr_bfd->archive_next;
+ som_index++;
+ }
+
+ /* Now scribble out the hash table. */
+ amt = hash_size * 4;
+ if (bfd_bwrite ((void *) hash_table, amt, abfd) != amt)
+ goto error_return;
+
+ /* Then the SOM dictionary. */
+ amt = module_count * sizeof (struct som_external_som_entry);
+ if (bfd_bwrite ((void *) som_dict, amt, abfd) != amt)
+ goto error_return;
+
+ /* The library symbols. */
+ amt = nsyms * sizeof (struct som_external_lst_symbol_record);
+ if (bfd_bwrite ((void *) lst_syms, amt, abfd) != amt)
+ goto error_return;
+
+ /* And finally the strings. */
+ amt = string_size;
+ if (bfd_bwrite ((void *) strings, amt, abfd) != amt)
+ 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... */
+
+static bfd_boolean
+som_write_armap (bfd *abfd,
+ unsigned int elength,
+ struct orl *map ATTRIBUTE_UNUSED,
+ unsigned int orl_count ATTRIBUTE_UNUSED,
+ int stridx ATTRIBUTE_UNUSED)
+{
+ bfd *curr_bfd;
+ struct stat statbuf;
+ unsigned int i, lst_size, nsyms, stringsize;
+ struct ar_hdr hdr;
+ struct som_external_lst_header lst;
+ unsigned char *p;
+ bfd_size_type amt;
+ unsigned int csum;
+ unsigned int module_count;
+
+ /* 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 som_external_lst_header);
+
+ /* Start building the LST header. */
+ /* FIXME: Do we need to examine each element to determine the
+ largest id number? */
+ bfd_putb16 (CPU_PA_RISC1_0, &lst.system_id);
+ bfd_putb16 (LIBMAGIC, &lst.a_magic);
+ bfd_putb32 (VERSION_ID, &lst.version_id);
+ bfd_putb32 (0, &lst.file_time.secs);
+ bfd_putb32 (0, &lst.file_time.nanosecs);
+
+ bfd_putb32 (lst_size, &lst.hash_loc);
+ bfd_putb32 (SOM_LST_HASH_SIZE, &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;
+ 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)
+ module_count++;
+ curr_bfd = curr_bfd->archive_next;
+ }
+ bfd_putb32 (module_count, &lst.module_count);
+ bfd_putb32 (module_count, &lst.module_limit);
+ bfd_putb32 (lst_size, &lst.dir_loc);
+ lst_size += sizeof (struct som_external_som_entry) * 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. */
+
+ bfd_putb32 (0, &lst.export_loc);
+ bfd_putb32 (0, &lst.export_count);
+ bfd_putb32 (0, &lst.import_loc);
+ bfd_putb32 (0, &lst.aux_loc);
+ bfd_putb32 (0, &lst.aux_size);
+
+ /* 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))
+ return FALSE;
+
+ lst_size += sizeof (struct som_external_lst_symbol_record) * nsyms;
+
+ /* For the string table. One day we might actually use this info
+ to avoid small seeks/reads when reading archives. */
+ bfd_putb32 (lst_size, &lst.string_loc);
+ bfd_putb32 (stringsize, &lst.string_size);
+ lst_size += stringsize;
+
+ /* SOM ABI says this must be zero. */
+ bfd_putb32 (0, &lst.free_list);
+ bfd_putb32 (lst_size, &lst.file_end);
+
+ /* Compute the checksum. Must happen after the entire lst header
+ has filled in. */
+ p = (unsigned char *) &lst;
+ csum = 0;
+ for (i = 0; i < sizeof (struct som_external_lst_header) - sizeof (int);
+ i += 4)
+ csum ^= bfd_getb32 (&p[i]);
+ bfd_putb32 (csum, &lst.checksum);
+
+ sprintf (hdr.ar_name, "/ ");
+ _bfd_ar_spacepad (hdr.ar_date, sizeof (hdr.ar_date), "%-12ld",
+ bfd_ardata (abfd)->armap_timestamp);
+ _bfd_ar_spacepad (hdr.ar_uid, sizeof (hdr.ar_uid), "%ld",
+ statbuf.st_uid);
+ _bfd_ar_spacepad (hdr.ar_gid, sizeof (hdr.ar_gid), "%ld",
+ statbuf.st_gid);
+ _bfd_ar_spacepad (hdr.ar_mode, sizeof (hdr.ar_mode), "%-8o",
+ (unsigned int)statbuf.st_mode);
+ _bfd_ar_spacepad (hdr.ar_size, sizeof (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. */
+ amt = sizeof (struct ar_hdr);
+ if (bfd_bwrite ((void *) &hdr, amt, abfd) != amt)
+ return FALSE;
+
+ /* Now scribble out the lst header. */
+ amt = sizeof (struct som_external_lst_header);
+ if (bfd_bwrite ((void *) &lst, amt, abfd) != amt)
+ return FALSE;
+
+ /* Build and write the armap. */
+ if (!som_bfd_ar_write_symbol_stuff (abfd, nsyms, stringsize, lst, elength))
+ 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 bfd_boolean
+som_bfd_free_cached_info (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 != NULL; o = o->next)
+ {
+ /* Free the native relocations. */
+ o->reloc_count = (unsigned) -1;
+ FREE (som_section_data (o)->reloc_stream);
+ /* Do not free the generic relocations as they are objalloc'ed. */
+ }
+#undef FREE
+
+ return TRUE;
+}
+
+/* End of miscellaneous support functions. */
+
+/* Linker support functions. */
+
+static bfd_boolean
+som_bfd_link_split_section (bfd *abfd ATTRIBUTE_UNUSED, asection *sec)
+{
+ return som_is_subspace (sec) && sec->size > 240000;
+}
+
+#define som_find_line _bfd_nosymbols_find_line
+#define som_close_and_cleanup som_bfd_free_cached_info
+#define som_read_ar_hdr _bfd_generic_read_ar_hdr
+#define som_write_ar_hdr _bfd_generic_write_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_is_target_special_symbol ((bfd_boolean (*) (bfd *, asymbol *)) bfd_false)
+#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_link_just_syms _bfd_generic_link_just_syms
+#define som_bfd_copy_link_hash_symbol_type \
+ _bfd_generic_copy_link_hash_symbol_type
+#define som_bfd_final_link _bfd_generic_final_link
+#define som_bfd_gc_sections bfd_generic_gc_sections
+#define som_bfd_lookup_section_flags bfd_generic_lookup_section_flags
+#define som_bfd_merge_sections bfd_generic_merge_sections
+#define som_bfd_is_group_section bfd_generic_is_group_section
+#define som_bfd_discard_group bfd_generic_discard_group
+#define som_section_already_linked _bfd_generic_section_already_linked
+#define som_bfd_define_common_symbol bfd_generic_define_common_symbol
+#define som_bfd_merge_private_bfd_data _bfd_generic_bfd_merge_private_bfd_data
+#define som_bfd_copy_private_header_data _bfd_generic_bfd_copy_private_header_data
+#define som_bfd_set_private_flags _bfd_generic_bfd_set_private_flags
+#define som_find_inliner_info _bfd_nosymbols_find_inliner_info
+
+const bfd_target hppa_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_LINK_ONCE
+ | 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. */
+ 0, /* match priority. */
+ 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, /* Headers. */
+ {_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),
+
+ NULL,
+
+ NULL
+};
+
diff --git a/bfd/som.h b/bfd/som.h
new file mode 100644
index 0000000..68f60c0
--- /dev/null
+++ b/bfd/som.h
@@ -0,0 +1,238 @@
+/* HP PA-RISC SOM object file format: definitions internal to BFD.
+ Copyright (C) 1990-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
+ 02110-1301, USA. */
+
+#ifndef _SOM_H
+#define _SOM_H
+
+#include "libhppa.h"
+
+/* We want reloc.h to provide PA 2.0 defines. */
+#define PA_2_0
+
+#include "som/aout.h"
+#include "som/lst.h"
+#include "som/internal.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 */
+
+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;
+ void * 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;
+
+ /* We must preserve the version identifier too. Some versions
+ of the HP linker do not grok NEW_VERSION_ID for reasons unknown. */
+ unsigned int version_id;
+
+ /* 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 an 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 som_header *file_hdr;
+ struct som_string_auxhdr *copyright_aux_hdr;
+ struct som_string_auxhdr *version_aux_hdr;
+ struct som_exec_auxhdr *exec_hdr;
+ struct som_compilation_unit *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;
+ void * line_info;
+};
+
+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;
+ unsigned int is_comdat : 1;
+ unsigned int is_common : 1;
+ unsigned int dup_common : 1;
+
+ /* 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;
+ unsigned char *reloc_stream;
+ struct som_space_dictionary_record *space_dict;
+ struct som_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 relocation 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. */
+bfd_boolean bfd_som_set_section_attributes (asection *, int, int, unsigned int, int);
+bfd_boolean bfd_som_set_subsection_attributes (asection *, asection *, int, unsigned int, int, int, int, int);
+void bfd_som_set_symbol_type (asymbol *, unsigned int);
+bfd_boolean bfd_som_attach_aux_hdr (bfd *, int, char *);
+int ** hppa_som_gen_reloc_type (bfd *, int, int, enum hppa_reloc_field_selector_type_alt, int, asymbol *);
+bfd_boolean bfd_som_attach_compilation_unit (bfd *, const char *, const char *, const char *, const char *);
+asection * bfd_section_from_som_symbol (bfd *abfd, struct som_external_symbol_dictionary_record *symbol);
+
+#endif /* _SOM_H */
diff --git a/bfd/sparclinux.c b/bfd/sparclinux.c
new file mode 100644
index 0000000..dac3624
--- /dev/null
+++ b/bfd/sparclinux.c
@@ -0,0 +1,729 @@
+/* BFD back-end for linux flavored sparc a.out binaries.
+ Copyright (C) 1992-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#define TARGET_PAGE_SIZE 4096
+#define ZMAGIC_DISK_BLOCK_SIZE 1024
+#define SEGMENT_SIZE TARGET_PAGE_SIZE
+#define TEXT_START_ADDR 0x0
+
+#define MACHTYPE_OK(mtype) ((mtype) == M_SPARC || (mtype) == M_UNKNOWN)
+
+#include "sysdep.h"
+#include "bfd.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
+/* Do not "beautify" the CONCAT* macro args. Traditional C will not
+ remove whitespace added here, and thus will fail to concatenate
+ the tokens. */
+#define MY(OP) CONCAT2 (sparc_aout_linux_,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
+ (bfd *, file_ptr *, file_ptr *, file_ptr *);
+
+static bfd_boolean
+sparclinux_bfd_final_link (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 bfd_boolean
+sparclinux_write_object_contents (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) (CONST_STRNEQ (name, GOT_REF_PREFIX))
+
+/* 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) (CONST_STRNEQ (name, PLT_REF_PREFIX))
+
+/* 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 dynamically
+ 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;
+};
+
+
+/* Routine to create an entry in an Linux link hash table. */
+
+static struct bfd_hash_entry *
+linux_link_hash_newfunc (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 (bfd *abfd)
+{
+ struct linux_link_hash_table *ret;
+ bfd_size_type amt = sizeof (struct linux_link_hash_table);
+
+ ret = (struct linux_link_hash_table *) bfd_zmalloc (amt);
+ 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,
+ sizeof (struct linux_link_hash_entry)))
+ {
+ free (ret);
+ return (struct bfd_link_hash_table *) 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, \
+ (bfd_boolean (*) (struct aout_link_hash_entry *, void *)) (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 (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 bfd_boolean
+linux_link_create_dynamic_sections (bfd *abfd,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED)
+{
+ flagword flags;
+ 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_with_flags (abfd, ".linux-dynamic", flags);
+ if (s == NULL
+ || ! bfd_set_section_alignment (abfd, s, 2))
+ return FALSE;
+ s->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 bfd_boolean
+linux_add_one_symbol (struct bfd_link_info *info,
+ bfd *abfd,
+ const char *name,
+ flagword flags,
+ asection *section,
+ bfd_vma value,
+ const char *string,
+ bfd_boolean copy,
+ bfd_boolean collect,
+ struct bfd_link_hash_entry **hashp)
+{
+ struct linux_link_hash_entry *h;
+ bfd_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->output_bfd->xvec? We may
+ want to be able to link Linux a.out and ELF objects together,
+ but serious confusion is possible. */
+
+ insert = FALSE;
+
+ if (! info->relocatable
+ && linux_hash_table (info)->dynobj == NULL
+ && strcmp (name, SHARABLE_CONFLICTS) == 0
+ && (flags & BSF_CONSTRUCTOR) != 0
+ && abfd->xvec == info->output_bfd->xvec)
+ {
+ 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->output_bfd->xvec)
+ {
+ 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, (bfd_vma) 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 bfd_boolean
+linux_tally_symbols (struct linux_link_hash_entry *h, void * 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;
+ bfd_boolean exists;
+
+ if (h->root.root.type == bfd_link_hash_undefined
+ && CONST_STRNEQ (h->root.root.root.string, NEEDS_SHRLIB))
+ {
+ 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 ((bfd_size_type) 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. */
+
+bfd_boolean
+bfd_sparclinux_size_dynamic_sections (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,
+ 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->size = linux_hash_table (info)->fixup_count + 1;
+ s->size *= 8;
+ s->contents = (bfd_byte *) bfd_zalloc (output_bfd, s->size);
+ if (s->contents == NULL)
+ return FALSE;
+ }
+
+ 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 bfd_boolean
+linux_finish_dynamic_link (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,
+ (bfd_vma) 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, (bfd_vma) 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, (bfd_vma) 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, (bfd_vma) 0, fixup_table);
+ fixup_table += 4;
+ bfd_put_32 (output_bfd, (bfd_vma) 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, (bfd_vma) 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, (bfd_vma) 0, fixup_table);
+ fixup_table += 4;
+ bfd_put_32 (output_bfd, (bfd_vma) 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, (bfd_vma) new_addr, fixup_table);
+ }
+ else
+ bfd_put_32 (output_bfd, (bfd_vma) 0, fixup_table);
+
+ if (bfd_seek (output_bfd, (file_ptr) (os->filepos + s->output_offset),
+ SEEK_SET) != 0)
+ return FALSE;
+
+ if (bfd_bwrite (s->contents, s->size, output_bfd) != s->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 0000000..2a62c77
--- /dev/null
+++ b/bfd/sparclynx.c
@@ -0,0 +1,246 @@
+/* BFD support for Sparc binaries under LynxOS.
+ Copyright (C) 1990-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+
+/* Do not "beautify" the CONCAT* macro args. Traditional C will not
+ remove whitespace added here, and thus will fail to concatenate
+ the tokens. */
+#define MY(OP) CONCAT2 (sparc_aout_lynx_,OP)
+#define TARGETNAME "a.out-sparc-lynx"
+
+#include "sysdep.h"
+#include "bfd.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"
+
+void NAME (lynx,set_arch_mach) (bfd *, unsigned long);
+static void choose_reloc_size (bfd *);
+static bfd_boolean NAME (aout,sparclynx_write_object_contents) (bfd *);
+
+/* 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 */
+
+void
+NAME(lynx,set_arch_mach) (bfd *abfd, unsigned long machtype)
+{
+ /* Determine the architecture and machine type of the object file. */
+ enum bfd_architecture arch;
+ unsigned 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_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 (bfd *abfd)
+{
+ switch (bfd_get_arch (abfd))
+ {
+ case bfd_arch_sparc:
+ 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 bfd_boolean
+NAME(aout,sparclynx_write_object_contents) (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;
+ 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 bfd_boolean sparclynx_set_sizes (bfd *);
+
+static bfd_boolean
+sparclynx_set_sizes (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 (*) (bfd *, struct bfd_section *)) 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 ();
+bfd_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 0000000..42d94e7
--- /dev/null
+++ b/bfd/sparcnetbsd.c
@@ -0,0 +1,39 @@
+/* BFD back-end for NetBSD/sparc a.out-ish binaries.
+ Copyright (C) 1990-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+
+#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
+
+/* Do not "beautify" the CONCAT* macro args. Traditional C will not
+ remove whitespace added here, and thus will fail to concatenate
+ the tokens. */
+#define MY(OP) CONCAT2 (sparc_aout_nbsd_,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 0000000..5f9a546
--- /dev/null
+++ b/bfd/srec.c
@@ -0,0 +1,1392 @@
+/* BFD back-end for s-record objects.
+ Copyright (C) 1990-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, 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 "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+#include "libiberty.h"
+#include "safe-ctype.h"
+
+
+/* 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)
+
+/* The maximum number of address+data+crc bytes on a line is FF. */
+#define MAXCHUNK 0xff
+
+/* Default size for a CHUNK. */
+#define DEFAULT_CHUNK 16
+
+/* The number of data bytes we actually fit onto a line on output.
+ This variable can be modified by objcopy's --srec-len parameter.
+ For a 0x75 byte record you should set --srec-len=0x70. */
+unsigned int Chunk = DEFAULT_CHUNK;
+
+/* The type of srec output (free or forced to S3).
+ This variable can be modified by objcopy's --srec-forceS3
+ parameter. */
+bfd_boolean S3Forced = FALSE;
+
+/* 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;
+
+/* Initialize by filling in the hex conversion array. */
+
+static void
+srec_init (void)
+{
+ static bfd_boolean inited = FALSE;
+
+ if (! inited)
+ {
+ inited = TRUE;
+ hex_init ();
+ }
+}
+
+/* Set up the S-record tdata information. */
+
+static bfd_boolean
+srec_mkobject (bfd *abfd)
+{
+ tdata_type *tdata;
+
+ srec_init ();
+
+ 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 (bfd *abfd, bfd_boolean *errorptr)
+{
+ bfd_byte c;
+
+ if (bfd_bread (&c, (bfd_size_type) 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 (bfd *abfd,
+ unsigned int lineno,
+ int c,
+ bfd_boolean error)
+{
+ if (c == EOF)
+ {
+ if (! error)
+ bfd_set_error (bfd_error_file_truncated);
+ }
+ else
+ {
+ char buf[40];
+
+ if (! ISPRINT (c))
+ sprintf (buf, "\\%03o", (unsigned int) c);
+ else
+ {
+ buf[0] = c;
+ buf[1] = '\0';
+ }
+ (*_bfd_error_handler)
+ (_("%B:%d: Unexpected character `%s' in S-record file\n"),
+ abfd, lineno, buf);
+ bfd_set_error (bfd_error_bad_value);
+ }
+}
+
+/* Add a new symbol found in an S-record file. */
+
+static bfd_boolean
+srec_new_symbol (bfd *abfd, const char *name, bfd_vma val)
+{
+ struct srec_symbol *n;
+
+ n = (struct srec_symbol *) bfd_alloc (abfd, sizeof (* n));
+ 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 bfd_boolean
+srec_scan (bfd *abfd)
+{
+ int c;
+ unsigned int lineno = 1;
+ bfd_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
+ {
+ bfd_size_type 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 ((bfd_size_type) (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 = (char *) bfd_alloc (abfd, (bfd_size_type) (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 (c == EOF)
+ {
+ srec_bad_byte (abfd, lineno, c, error);
+ goto error_return;
+ }
+ }
+
+ 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;
+ unsigned char hdr[3];
+ unsigned int bytes, min_bytes;
+ bfd_vma address;
+ bfd_byte *data;
+ unsigned char check_sum;
+
+ /* Starting an S-record. */
+
+ pos = bfd_tell (abfd) - 1;
+
+ if (bfd_bread (hdr, (bfd_size_type) 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;
+ }
+
+ check_sum = bytes = HEX (hdr + 1);
+ min_bytes = 3;
+ if (hdr[0] == '2' || hdr[0] == '8')
+ min_bytes = 4;
+ else if (hdr[0] == '3' || hdr[0] == '7')
+ min_bytes = 5;
+ if (bytes < min_bytes)
+ {
+ (*_bfd_error_handler) (_("%B:%d: byte count %d too small\n"),
+ abfd, lineno, bytes);
+ bfd_set_error (bfd_error_bad_value);
+ goto error_return;
+ }
+
+ if (bytes * 2 > bufsize)
+ {
+ if (buf != NULL)
+ free (buf);
+ buf = (bfd_byte *) bfd_malloc ((bfd_size_type) bytes * 2);
+ if (buf == NULL)
+ goto error_return;
+ bufsize = bytes * 2;
+ }
+
+ if (bfd_bread (buf, (bfd_size_type) 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':
+ check_sum += HEX (data);
+ address = HEX (data);
+ data += 2;
+ --bytes;
+ /* Fall through. */
+ case '2':
+ check_sum += HEX (data);
+ address = (address << 8) | HEX (data);
+ data += 2;
+ --bytes;
+ /* Fall through. */
+ case '1':
+ check_sum += HEX (data);
+ address = (address << 8) | HEX (data);
+ data += 2;
+ check_sum += HEX (data);
+ address = (address << 8) | HEX (data);
+ data += 2;
+ bytes -= 2;
+
+ if (sec != NULL
+ && sec->vma + sec->size == address)
+ {
+ /* This data goes at the end of the section we are
+ currently building. */
+ sec->size += bytes;
+ }
+ else
+ {
+ char secbuf[20];
+ char *secname;
+ bfd_size_type amt;
+ flagword flags;
+
+ sprintf (secbuf, ".sec%d", bfd_count_sections (abfd) + 1);
+ amt = strlen (secbuf) + 1;
+ secname = (char *) bfd_alloc (abfd, amt);
+ strcpy (secname, secbuf);
+ flags = SEC_HAS_CONTENTS | SEC_LOAD | SEC_ALLOC;
+ sec = bfd_make_section_with_flags (abfd, secname, flags);
+ if (sec == NULL)
+ goto error_return;
+ sec->vma = address;
+ sec->lma = address;
+ sec->size = bytes;
+ sec->filepos = pos;
+ }
+
+ while (bytes > 0)
+ {
+ check_sum += HEX (data);
+ data += 2;
+ bytes--;
+ }
+ check_sum = 255 - (check_sum & 0xff);
+ if (check_sum != HEX (data))
+ {
+ (*_bfd_error_handler)
+ (_("%B:%d: Bad checksum in S-record file\n"),
+ abfd, lineno);
+ bfd_set_error (bfd_error_bad_value);
+ goto error_return;
+ }
+
+ break;
+
+ case '7':
+ check_sum += HEX (data);
+ address = HEX (data);
+ data += 2;
+ /* Fall through. */
+ case '8':
+ check_sum += HEX (data);
+ address = (address << 8) | HEX (data);
+ data += 2;
+ /* Fall through. */
+ case '9':
+ check_sum += HEX (data);
+ address = (address << 8) | HEX (data);
+ data += 2;
+ check_sum += HEX (data);
+ address = (address << 8) | HEX (data);
+ data += 2;
+
+ /* This is a termination record. */
+ abfd->start_address = address;
+
+ check_sum = 255 - (check_sum & 0xff);
+ if (check_sum != HEX (data))
+ {
+ (*_bfd_error_handler)
+ (_("%B:%d: Bad checksum in S-record file\n"),
+ abfd, lineno);
+ bfd_set_error (bfd_error_bad_value);
+ goto error_return;
+ }
+
+ 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 (bfd *abfd)
+{
+ void * tdata_save;
+ bfd_byte b[4];
+
+ srec_init ();
+
+ if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0
+ || bfd_bread (b, (bfd_size_type) 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;
+ }
+
+ tdata_save = abfd->tdata.any;
+ if (! srec_mkobject (abfd) || ! srec_scan (abfd))
+ {
+ if (abfd->tdata.any != tdata_save && abfd->tdata.any != NULL)
+ bfd_release (abfd, abfd->tdata.any);
+ abfd->tdata.any = tdata_save;
+ 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 (bfd *abfd)
+{
+ void * tdata_save;
+ char b[2];
+
+ srec_init ();
+
+ if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0
+ || bfd_bread (b, (bfd_size_type) 2, abfd) != 2)
+ return NULL;
+
+ if (b[0] != '$' || b[1] != '$')
+ {
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+
+ tdata_save = abfd->tdata.any;
+ if (! srec_mkobject (abfd) || ! srec_scan (abfd))
+ {
+ if (abfd->tdata.any != tdata_save && abfd->tdata.any != NULL)
+ bfd_release (abfd, abfd->tdata.any);
+ abfd->tdata.any = tdata_save;
+ 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 bfd_boolean
+srec_read_section (bfd *abfd, asection *section, bfd_byte *contents)
+{
+ int c;
+ bfd_size_type sofar = 0;
+ bfd_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_bread (hdr, (bfd_size_type) 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 ((bfd_size_type) bytes * 2);
+ if (buf == NULL)
+ goto error_return;
+ bufsize = bytes * 2;
+ }
+
+ if (bfd_bread (buf, (bfd_size_type) bytes * 2, abfd) != bytes * 2)
+ goto error_return;
+
+ address = 0;
+ data = buf;
+ switch (hdr[0])
+ {
+ default:
+ BFD_ASSERT (sofar == section->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->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->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 bfd_boolean
+srec_get_section_contents (bfd *abfd,
+ asection *section,
+ void * location,
+ file_ptr offset,
+ bfd_size_type count)
+{
+ if (count == 0)
+ return TRUE;
+
+ if (offset + count < count
+ || offset + count > section->size)
+ {
+ bfd_set_error (bfd_error_invalid_operation);
+ return FALSE;
+ }
+
+ if (section->used_by_bfd == NULL)
+ {
+ section->used_by_bfd = bfd_alloc (abfd, section->size);
+ if (section->used_by_bfd == NULL)
+ return FALSE;
+
+ if (! srec_read_section (abfd, section,
+ (bfd_byte *) 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 bfd_boolean
+srec_set_arch_mach (bfd *abfd, enum bfd_architecture arch, unsigned long mach)
+{
+ if (arch != bfd_arch_unknown)
+ return bfd_default_set_arch_mach (abfd, arch, mach);
+
+ abfd->arch_info = & bfd_default_arch_struct;
+ return TRUE;
+}
+
+/* We have to save up all the Srecords for a splurge before output. */
+
+static bfd_boolean
+srec_set_section_contents (bfd *abfd,
+ sec_ptr section,
+ const void * location,
+ file_ptr offset,
+ bfd_size_type bytes_to_do)
+{
+ int opb = bfd_octets_per_byte (abfd);
+ tdata_type *tdata = abfd->tdata.srec_data;
+ srec_data_list_type *entry;
+
+ entry = (srec_data_list_type *) bfd_alloc (abfd, sizeof (* entry));
+ if (entry == NULL)
+ return FALSE;
+
+ if (bytes_to_do
+ && (section->flags & SEC_ALLOC)
+ && (section->flags & SEC_LOAD))
+ {
+ bfd_byte *data;
+
+ data = (bfd_byte *) bfd_alloc (abfd, bytes_to_do);
+ if (data == NULL)
+ return FALSE;
+ memcpy ((void *) data, location, (size_t) bytes_to_do);
+
+ /* Ff S3Forced is TRUE then always select S3 records,
+ regardless of the siez of the addresses. */
+ if (S3Forced)
+ tdata->type = 3;
+ else if ((section->lma + (offset + bytes_to_do) / opb - 1) <= 0xffff)
+ ; /* The default, S1, is OK. */
+ else if ((section->lma + (offset + bytes_to_do) / opb - 1) <= 0xffffff
+ && tdata->type <= 2)
+ tdata->type = 2;
+ else
+ tdata->type = 3;
+
+ entry->data = data;
+ entry->where = section->lma + offset / opb;
+ 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
+ {
+ 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 bfd_boolean
+srec_write_record (bfd *abfd,
+ unsigned int type,
+ bfd_vma address,
+ const bfd_byte *data,
+ const bfd_byte *end)
+{
+ char buffer[2 * MAXCHUNK + 6];
+ 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;
+
+ return bfd_bwrite ((void *) buffer, wrlen, abfd) == wrlen;
+}
+
+static bfd_boolean
+srec_write_header (bfd *abfd)
+{
+ unsigned int len = strlen (abfd->filename);
+
+ /* I'll put an arbitrary 40 char limit on header size. */
+ if (len > 40)
+ len = 40;
+
+ return srec_write_record (abfd, 0, (bfd_vma) 0,
+ (bfd_byte *) abfd->filename,
+ (bfd_byte *) abfd->filename + len);
+}
+
+static bfd_boolean
+srec_write_section (bfd *abfd,
+ tdata_type *tdata,
+ srec_data_list_type *list)
+{
+ unsigned int octets_written = 0;
+ bfd_byte *location = list->data;
+
+ /* Validate number of data bytes to write. The srec length byte
+ counts the address, data and crc bytes. S1 (tdata->type == 1)
+ records have two address bytes, S2 (tdata->type == 2) records
+ have three, and S3 (tdata->type == 3) records have four.
+ The total length can't exceed 255, and a zero data length will
+ spin for a long time. */
+ if (Chunk == 0)
+ Chunk = 1;
+ else if (Chunk > MAXCHUNK - tdata->type - 2)
+ Chunk = MAXCHUNK - tdata->type - 2;
+
+ while (octets_written < list->size)
+ {
+ bfd_vma address;
+ unsigned int octets_this_chunk = list->size - octets_written;
+
+ if (octets_this_chunk > Chunk)
+ octets_this_chunk = Chunk;
+
+ address = list->where + octets_written / bfd_octets_per_byte (abfd);
+
+ if (! srec_write_record (abfd,
+ tdata->type,
+ address,
+ location,
+ location + octets_this_chunk))
+ return FALSE;
+
+ octets_written += octets_this_chunk;
+ location += octets_this_chunk;
+ }
+
+ return TRUE;
+}
+
+static bfd_boolean
+srec_write_terminator (bfd *abfd, tdata_type *tdata)
+{
+ return srec_write_record (abfd, 10 - tdata->type,
+ abfd->start_address, NULL, NULL);
+}
+
+static bfd_boolean
+srec_write_symbols (bfd *abfd)
+{
+ /* Dump out the symbols of a bfd. */
+ int i;
+ int count = bfd_get_symcount (abfd);
+
+ if (count)
+ {
+ bfd_size_type len;
+ asymbol **table = bfd_get_outsymbols (abfd);
+
+ len = strlen (abfd->filename);
+ if (bfd_bwrite ("$$ ", (bfd_size_type) 3, abfd) != 3
+ || bfd_bwrite (abfd->filename, len, abfd) != len
+ || bfd_bwrite ("\r\n", (bfd_size_type) 2, abfd) != 2)
+ 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. */
+ char buf[43], *p;
+
+ len = strlen (s->name);
+ if (bfd_bwrite (" ", (bfd_size_type) 2, abfd) != 2
+ || bfd_bwrite (s->name, len, abfd) != len)
+ return FALSE;
+
+ sprintf_vma (buf + 2, (s->value
+ + s->section->output_section->lma
+ + s->section->output_offset));
+ p = buf + 2;
+ while (p[0] == '0' && p[1] != 0)
+ p++;
+ len = strlen (p);
+ p[len] = '\r';
+ p[len + 1] = '\n';
+ *--p = '$';
+ *--p = ' ';
+ len += 4;
+ if (bfd_bwrite (p, len, abfd) != len)
+ return FALSE;
+ }
+ }
+ if (bfd_bwrite ("$$ \r\n", (bfd_size_type) 5, abfd) != 5)
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static bfd_boolean
+internal_srec_write_object_contents (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 bfd_boolean
+srec_write_object_contents (bfd *abfd)
+{
+ return internal_srec_write_object_contents (abfd, 0);
+}
+
+static bfd_boolean
+symbolsrec_write_object_contents (bfd *abfd)
+{
+ return internal_srec_write_object_contents (abfd, 1);
+}
+
+static int
+srec_sizeof_headers (bfd *abfd ATTRIBUTE_UNUSED,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+/* Return the amount of memory needed to read the symbol table. */
+
+static long
+srec_get_symtab_upper_bound (bfd *abfd)
+{
+ return (bfd_get_symcount (abfd) + 1) * sizeof (asymbol *);
+}
+
+/* Return the symbol table. */
+
+static long
+srec_canonicalize_symtab (bfd *abfd, asymbol **alocation)
+{
+ bfd_size_type symcount = bfd_get_symcount (abfd);
+ asymbol *csymbols;
+ unsigned int i;
+
+ csymbols = abfd->tdata.srec_data->csymbols;
+ if (csymbols == NULL && symcount != 0)
+ {
+ asymbol *c;
+ struct srec_symbol *s;
+
+ csymbols = (asymbol *) bfd_alloc (abfd, symcount * sizeof (asymbol));
+ if (csymbols == NULL)
+ return -1;
+ 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;
+}
+
+static void
+srec_get_symbol_info (bfd *ignore_abfd ATTRIBUTE_UNUSED,
+ asymbol *symbol,
+ symbol_info *ret)
+{
+ bfd_symbol_info (symbol, ret);
+}
+
+static void
+srec_print_symbol (bfd *abfd,
+ void * 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 (abfd, (void *) 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_target_special_symbol ((bfd_boolean (*) (bfd *, asymbol *)) bfd_false)
+#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_find_line _bfd_nosymbols_find_line
+#define srec_find_inliner_info _bfd_nosymbols_find_inliner_info
+#define srec_make_empty_symbol _bfd_generic_make_empty_symbol
+#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_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_lookup_section_flags bfd_generic_lookup_section_flags
+#define srec_bfd_merge_sections bfd_generic_merge_sections
+#define srec_bfd_is_group_section bfd_generic_is_group_section
+#define srec_bfd_discard_group bfd_generic_discard_group
+#define srec_section_already_linked _bfd_generic_section_already_linked
+#define srec_bfd_define_common_symbol bfd_generic_define_common_symbol
+#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_link_just_syms _bfd_generic_link_just_syms
+#define srec_bfd_copy_link_hash_symbol_type \
+ _bfd_generic_copy_link_hash_symbol_type
+#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. */
+ 0, /* match priority. */
+ 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 (_bfd_norelocs),
+ BFD_JUMP_TABLE_WRITE (srec),
+ BFD_JUMP_TABLE_LINK (srec),
+ BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
+
+ NULL,
+
+ NULL
+};
+
+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. */
+ 0, /* match priority. */
+ 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, /* Headers. */
+
+ {
+ _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 (_bfd_norelocs),
+ BFD_JUMP_TABLE_WRITE (srec),
+ BFD_JUMP_TABLE_LINK (srec),
+ BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
+
+ NULL,
+
+ NULL
+};
diff --git a/bfd/stab-syms.c b/bfd/stab-syms.c
new file mode 100644
index 0000000..74f39f3
--- /dev/null
+++ b/bfd/stab-syms.c
@@ -0,0 +1,59 @@
+/* Table of stab names for the BFD library.
+ Copyright (C) 1990-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#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 0000000..e6526c5
--- /dev/null
+++ b/bfd/stabs.c
@@ -0,0 +1,788 @@
+/* Stabs in sections linking support.
+ Copyright (C) 1996-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+
+/* This file contains support for linking stabs in sections, as used
+ on COFF and ELF. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+#include "aout/stab_gnu.h"
+#include "safe-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 linked list of totals that we have found for a particular header
+ file. A total is a unique identifier for a particular BINCL...EINCL
+ sequence of STABs that can be used to identify duplicate sequences.
+ It consists of three fields, 'sum_chars' which is the sum of all the
+ STABS characters; 'num_chars' which is the number of these charactes
+ and 'symb' which is a buffer of all the symbols in the sequence. This
+ buffer is only checked as a last resort. */
+
+struct stab_link_includes_totals
+{
+ struct stab_link_includes_totals *next;
+ bfd_vma sum_chars; /* Accumulated sum of STABS characters. */
+ bfd_vma num_chars; /* Number of STABS characters. */
+ const char* symb; /* The STABS characters themselves. */
+};
+
+/* 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;
+};
+
+/* 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];
+};
+
+
+/* The function to create a new entry in the header file hash table. */
+
+static struct bfd_hash_entry *
+stab_link_includes_newfunc (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 == NULL)
+ ret = (struct stab_link_includes_entry *)
+ bfd_hash_allocate (table, sizeof (struct stab_link_includes_entry));
+ if (ret == NULL)
+ return NULL;
+
+ /* 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. */
+
+bfd_boolean
+_bfd_link_section_stabs (bfd *abfd,
+ struct stab_info *sinfo,
+ asection *stabsec,
+ asection *stabstrsec,
+ void * *psecinfo,
+ bfd_size_type *pstring_offset)
+{
+ bfd_boolean first;
+ bfd_size_type count, amt;
+ 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->size == 0
+ || stabstrsec->size == 0)
+ /* This file does not contain stabs debugging information. */
+ return TRUE;
+
+ if (stabsec->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 (bfd_is_abs_section (stabsec->output_section)
+ || 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 (sinfo->stabstr == NULL)
+ {
+ flagword flags;
+
+ /* Initialize the stabs information we need to keep track of. */
+ first = TRUE;
+ sinfo->strings = _bfd_stringtab_init ();
+ if (sinfo->strings == NULL)
+ goto error_return;
+ /* Make sure the first byte is zero. */
+ (void) _bfd_stringtab_add (sinfo->strings, "", TRUE, TRUE);
+ if (! bfd_hash_table_init (&sinfo->includes,
+ stab_link_includes_newfunc,
+ sizeof (struct stab_link_includes_entry)))
+ goto error_return;
+ flags = (SEC_HAS_CONTENTS | SEC_READONLY | SEC_DEBUGGING
+ | SEC_LINKER_CREATED);
+ sinfo->stabstr = bfd_make_section_anyway_with_flags (abfd, ".stabstr",
+ flags);
+ if (sinfo->stabstr == NULL)
+ goto error_return;
+ }
+
+ /* Initialize the information we are going to store for this .stab
+ section. */
+ count = stabsec->size / STABSIZE;
+
+ amt = sizeof (struct stab_section_info);
+ amt += (count - 1) * sizeof (bfd_size_type);
+ *psecinfo = bfd_alloc (abfd, amt);
+ if (*psecinfo == NULL)
+ goto error_return;
+
+ secinfo = (struct stab_section_info *) *psecinfo;
+ secinfo->excls = NULL;
+ stabsec->rawsize = stabsec->size;
+ secinfo->cumulative_skips = NULL;
+ memset (secinfo->stridxs, 0, (size_t) count * sizeof (bfd_size_type));
+
+ /* Read the stabs information from abfd. */
+ if (!bfd_malloc_and_get_section (abfd, stabsec, &stabbuf)
+ || !bfd_malloc_and_get_section (abfd, stabstrsec, &stabstrbuf))
+ 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;
+ /* The stabs sections can be split when
+ -split-by-reloc/-split-by-file is used. We must keep track of
+ each stab section's place in the single concatenated string
+ table. */
+ next_stroff = pstring_offset ? *pstring_offset : 0;
+ skip = 0;
+
+ symend = stabbuf + stabsec->size;
+ for (sym = stabbuf, pstridx = secinfo->stridxs;
+ sym < symend;
+ sym += STABSIZE, ++pstridx)
+ {
+ bfd_size_type symstroff;
+ 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 (pstring_offset)
+ *pstring_offset = next_stroff;
+ if (! first)
+ {
+ *pstridx = (bfd_size_type) -1;
+ ++skip;
+ continue;
+ }
+ first = FALSE;
+ }
+
+ /* Store the string in the hash table, and record the index. */
+ symstroff = stroff + bfd_get_32 (abfd, sym + STRDXOFF);
+ if (symstroff >= stabstrsec->size)
+ {
+ (*_bfd_error_handler)
+ (_("%B(%A+0x%lx): Stabs entry has invalid string index."),
+ abfd, stabsec, (long) (sym - stabbuf));
+ bfd_set_error (bfd_error_bad_value);
+ goto error_return;
+ }
+ string = (char *) stabstrbuf + symstroff;
+ *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 == (int) N_BINCL)
+ {
+ bfd_vma sum_chars;
+ bfd_vma num_chars;
+ bfd_vma buf_len = 0;
+ char * symb;
+ char * symb_rover;
+ int nest;
+ bfd_byte * incl_sym;
+ struct stab_link_includes_entry * incl_entry;
+ struct stab_link_includes_totals * t;
+ struct stab_excl_list * ne;
+
+ symb = symb_rover = NULL;
+ sum_chars = num_chars = 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 == (int) N_EXCL)
+ continue;
+ else if (incl_type == (int) N_EINCL)
+ {
+ if (nest == 0)
+ break;
+ --nest;
+ }
+ else if (incl_type == (int) 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++)
+ {
+ if (num_chars >= buf_len)
+ {
+ buf_len += 32 * 1024;
+ symb = (char *) bfd_realloc_or_free (symb, buf_len);
+ if (symb == NULL)
+ goto error_return;
+ symb_rover = symb + num_chars;
+ }
+ * symb_rover ++ = * str;
+ sum_chars += *str;
+ num_chars ++;
+ if (*str == '(')
+ {
+ /* Skip the file number. */
+ ++str;
+ while (ISDIGIT (*str))
+ ++str;
+ --str;
+ }
+ }
+ }
+ }
+
+ BFD_ASSERT (num_chars == (bfd_vma) (symb_rover - symb));
+
+ /* If we have already included a header file with the same
+ value, then replaced this one with an N_EXCL symbol. */
+ incl_entry = (struct stab_link_includes_entry * )
+ bfd_hash_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->sum_chars == sum_chars
+ && t->num_chars == num_chars
+ && memcmp (t->symb, symb, num_chars) == 0)
+ break;
+
+ /* Record this symbol, so that we can set the value
+ correctly. */
+ amt = sizeof *ne;
+ ne = (struct stab_excl_list *) bfd_alloc (abfd, amt);
+ if (ne == NULL)
+ goto error_return;
+ ne->offset = sym - stabbuf;
+ ne->val = sum_chars;
+ ne->type = (int) 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, sizeof *t);
+ if (t == NULL)
+ goto error_return;
+ t->sum_chars = sum_chars;
+ t->num_chars = num_chars;
+ /* Trim data down. */
+ t->symb = symb = (char *) bfd_realloc_or_free (symb, num_chars);
+ 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 = (int) N_EXCL;
+
+ /* Free off superfluous symbols. */
+ free (symb);
+
+ /* 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 == (int) N_EINCL)
+ {
+ if (nest == 0)
+ {
+ *incl_pstridx = (bfd_size_type) -1;
+ ++skip;
+ break;
+ }
+ --nest;
+ }
+ else if (incl_type == (int) N_BINCL)
+ ++nest;
+ else if (incl_type == (int) N_EXCL)
+ /* Keep existing exclusion marks. */
+ continue;
+ 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->size = (count - skip) * STABSIZE;
+ if (stabsec->size == 0)
+ stabsec->flags |= SEC_EXCLUDE | SEC_KEEP;
+ stabstrsec->flags |= SEC_EXCLUDE | SEC_KEEP;
+ sinfo->stabstr->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;
+
+ amt = count * sizeof (bfd_size_type);
+ secinfo->cumulative_skips = (bfd_size_type *) bfd_alloc (abfd, amt);
+ 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;
+}
+
+/* This function is called for each input file before the stab
+ section is relocated. It discards stab entries for discarded
+ functions and variables. The function returns TRUE iff
+ any entries have been deleted.
+*/
+
+bfd_boolean
+_bfd_discard_section_stabs (bfd *abfd,
+ asection *stabsec,
+ void * psecinfo,
+ bfd_boolean (*reloc_symbol_deleted_p) (bfd_vma, void *),
+ void * cookie)
+{
+ bfd_size_type count, amt;
+ struct stab_section_info *secinfo;
+ bfd_byte *stabbuf = NULL;
+ bfd_byte *sym, *symend;
+ bfd_size_type skip;
+ bfd_size_type *pstridx;
+ int deleting;
+
+ if (stabsec->size == 0)
+ /* This file does not contain stabs debugging information. */
+ return FALSE;
+
+ if (stabsec->size % STABSIZE != 0)
+ /* Something is wrong with the format of these stab symbols.
+ Don't try to optimize them. */
+ return FALSE;
+
+ if ((stabsec->output_section != NULL
+ && bfd_is_abs_section (stabsec->output_section)))
+ /* At least one of the sections is being discarded from the
+ link, so we should just ignore them. */
+ return FALSE;
+
+ /* We should have initialized our data in _bfd_link_section_stabs.
+ If there was some bizarre error reading the string sections, though,
+ we might not have. Bail rather than asserting. */
+ if (psecinfo == NULL)
+ return FALSE;
+
+ count = stabsec->rawsize / STABSIZE;
+ secinfo = (struct stab_section_info *) psecinfo;
+
+ /* Read the stabs information from abfd. */
+ if (!bfd_malloc_and_get_section (abfd, stabsec, &stabbuf))
+ goto error_return;
+
+ /* Look through the stabs symbols and discard any information for
+ discarded functions. */
+ skip = 0;
+ deleting = -1;
+
+ symend = stabbuf + stabsec->rawsize;
+ for (sym = stabbuf, pstridx = secinfo->stridxs;
+ sym < symend;
+ sym += STABSIZE, ++pstridx)
+ {
+ int type;
+
+ if (*pstridx == (bfd_size_type) -1)
+ /* This stab was deleted in a previous pass. */
+ continue;
+
+ type = sym[TYPEOFF];
+
+ if (type == (int) N_FUN)
+ {
+ int strx = bfd_get_32 (abfd, sym + STRDXOFF);
+
+ if (strx == 0)
+ {
+ if (deleting)
+ {
+ skip++;
+ *pstridx = -1;
+ }
+ deleting = -1;
+ continue;
+ }
+ deleting = 0;
+ if ((*reloc_symbol_deleted_p) (sym + VALOFF - stabbuf, cookie))
+ deleting = 1;
+ }
+
+ if (deleting == 1)
+ {
+ *pstridx = -1;
+ skip++;
+ }
+ else if (deleting == -1)
+ {
+ /* Outside of a function. Check for deleted variables. */
+ if (type == (int) N_STSYM || type == (int) N_LCSYM)
+ if ((*reloc_symbol_deleted_p) (sym + VALOFF - stabbuf, cookie))
+ {
+ *pstridx = -1;
+ skip ++;
+ }
+ /* We should also check for N_GSYM entries which reference a
+ deleted global, but those are less harmful to debuggers
+ and would require parsing the stab strings. */
+ }
+ }
+
+ free (stabbuf);
+ stabbuf = NULL;
+
+ /* Shrink the stabsec as needed. */
+ stabsec->size -= skip * STABSIZE;
+ if (stabsec->size == 0)
+ stabsec->flags |= SEC_EXCLUDE | SEC_KEEP;
+
+ /* Recalculate 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;
+
+ if (secinfo->cumulative_skips == NULL)
+ {
+ amt = count * sizeof (bfd_size_type);
+ secinfo->cumulative_skips = (bfd_size_type *) bfd_alloc (abfd, amt);
+ 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 skip > 0;
+
+ error_return:
+ if (stabbuf != NULL)
+ free (stabbuf);
+ return FALSE;
+}
+
+/* Write out the stab section. This is called with the relocated
+ contents. */
+
+bfd_boolean
+_bfd_write_section_stabs (bfd *output_bfd,
+ struct stab_info *sinfo,
+ asection *stabsec,
+ void * *psecinfo,
+ bfd_byte *contents)
+{
+ struct stab_section_info *secinfo;
+ struct stab_excl_list *e;
+ bfd_byte *sym, *tosym, *symend;
+ bfd_size_type *pstridx;
+
+ secinfo = (struct stab_section_info *) *psecinfo;
+
+ if (secinfo == NULL)
+ return bfd_set_section_contents (output_bfd, stabsec->output_section,
+ contents, stabsec->output_offset,
+ stabsec->size);
+
+ /* Handle each N_BINCL entry. */
+ for (e = secinfo->excls; e != NULL; e = e->next)
+ {
+ bfd_byte *excl_sym;
+
+ BFD_ASSERT (e->offset < stabsec->rawsize);
+ excl_sym = contents + e->offset;
+ bfd_put_32 (output_bfd, e->val, excl_sym + VALOFF);
+ excl_sym[TYPEOFF] = e->type;
+ }
+
+ /* Copy over all the stabs symbols, omitting the ones we don't want,
+ and correcting the string indices for those we do want. */
+ tosym = contents;
+ symend = contents + stabsec->rawsize;
+ for (sym = contents, pstridx = secinfo->stridxs;
+ sym < symend;
+ sym += STABSIZE, ++pstridx)
+ {
+ if (*pstridx != (bfd_size_type) -1)
+ {
+ if (tosym != sym)
+ memcpy (tosym, sym, STABSIZE);
+ bfd_put_32 (output_bfd, *pstridx, tosym + STRDXOFF);
+
+ if (sym[TYPEOFF] == 0)
+ {
+ /* This is the header symbol for the stabs section. We
+ don't really need one, since we have merged all the
+ input stabs sections into one, but we generate one
+ for the benefit of readers which expect to see one. */
+ BFD_ASSERT (sym == contents);
+ bfd_put_32 (output_bfd, _bfd_stringtab_size (sinfo->strings),
+ tosym + VALOFF);
+ bfd_put_16 (output_bfd,
+ stabsec->output_section->size / STABSIZE - 1,
+ tosym + DESCOFF);
+ }
+
+ tosym += STABSIZE;
+ }
+ }
+
+ BFD_ASSERT ((bfd_size_type) (tosym - contents) == stabsec->size);
+
+ return bfd_set_section_contents (output_bfd, stabsec->output_section,
+ contents, (file_ptr) stabsec->output_offset,
+ stabsec->size);
+}
+
+/* Write out the .stabstr section. */
+
+bfd_boolean
+_bfd_write_stab_strings (bfd *output_bfd, struct stab_info *sinfo)
+{
+ 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->size);
+
+ if (bfd_seek (output_bfd,
+ (file_ptr) (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);
+
+ 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 (asection *stabsec,
+ void * psecinfo,
+ bfd_vma offset)
+{
+ struct stab_section_info *secinfo;
+
+ secinfo = (struct stab_section_info *) psecinfo;
+
+ if (secinfo == NULL)
+ return offset;
+
+ if (offset >= stabsec->rawsize)
+ return offset - stabsec->rawsize + stabsec->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 0000000..9788f70
--- /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 0000000..27a658e
--- /dev/null
+++ b/bfd/sunos.c
@@ -0,0 +1,2845 @@
+/* BFD backend for SunOS binaries.
+ Copyright (C) 1990-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#define TARGETNAME "a.out-sunos-big"
+
+/* Do not "beautify" the CONCAT* macro args. Traditional C will not
+ remove whitespace added here, and thus will fail to concatenate
+ the tokens. */
+#define MY(OP) CONCAT2 (sparc_aout_sunos_be_,OP)
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "bfdlink.h"
+#include "libaout.h"
+
+/* ??? 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))
+
+#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_synthetic_symtab _bfd_nodynamic_get_synthetic_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
+
+static bfd_boolean sunos_add_dynamic_symbols (bfd *, struct bfd_link_info *, struct external_nlist **, bfd_size_type *, char **);
+static bfd_boolean sunos_add_one_symbol (struct bfd_link_info *, bfd *, const char *, flagword, asection *, bfd_vma, const char *, bfd_boolean, bfd_boolean, struct bfd_link_hash_entry **);
+static bfd_boolean sunos_link_dynamic_object (struct bfd_link_info *, bfd *);
+static bfd_boolean sunos_write_dynamic_symbol (bfd *, struct bfd_link_info *, struct aout_link_hash_entry *);
+static bfd_boolean sunos_check_dynamic_reloc (struct bfd_link_info *, bfd *, asection *, struct aout_link_hash_entry *, void *, bfd_byte *, bfd_boolean *, bfd_vma *);
+static bfd_boolean sunos_finish_dynamic_link (bfd *, struct bfd_link_info *);
+static struct bfd_link_hash_table *sunos_link_hash_table_create (bfd *);
+static long sunos_get_dynamic_symtab_upper_bound (bfd *);
+static long sunos_canonicalize_dynamic_symtab (bfd *, asymbol **);
+static long sunos_get_dynamic_reloc_upper_bound (bfd *);
+static long sunos_canonicalize_dynamic_reloc (bfd *, arelent **, asymbol **);
+
+/* 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. */
+ bfd_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. */
+ void * 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 bfd_boolean
+sunos_read_dynamic_info (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;
+ bfd_size_type amt;
+
+ if (obj_aout_dynamic_info (abfd) != NULL)
+ return TRUE;
+
+ if ((abfd->flags & DYNAMIC) == 0)
+ {
+ bfd_set_error (bfd_error_invalid_operation);
+ return FALSE;
+ }
+
+ amt = sizeof (struct sunos_dynamic_info);
+ info = bfd_zalloc (abfd, amt);
+ 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) = (void *) 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), (void *) &dyninfo,
+ (file_ptr) 0,
+ (bfd_size_type) 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 > dynsec->size)
+ return TRUE;
+
+ /* This executable appears to be dynamically linked in a way that we
+ can understand. */
+ if (! bfd_get_section_contents (abfd, dynsec, (void *) &linkinfo,
+ (file_ptr) 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 (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 bfd_boolean
+sunos_slurp_dynamic_symtab (bfd *abfd)
+{
+ struct sunos_dynamic_info *info;
+ bfd_size_type amt;
+
+ /* 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 == NULL)
+ {
+ amt = (bfd_size_type) info->dynsym_count * EXTERNAL_NLIST_SIZE;
+ info->dynsym = bfd_alloc (abfd, amt);
+ if (info->dynsym == NULL && info->dynsym_count != 0)
+ return FALSE;
+ if (bfd_seek (abfd, (file_ptr) info->dyninfo.ld_stab, SEEK_SET) != 0
+ || bfd_bread ((void *) info->dynsym, amt, abfd) != amt)
+ {
+ if (info->dynsym != NULL)
+ {
+ bfd_release (abfd, info->dynsym);
+ info->dynsym = NULL;
+ }
+ return FALSE;
+ }
+ }
+
+ /* Get the dynamic strings. */
+ if (info->dynstr == NULL)
+ {
+ amt = info->dyninfo.ld_symb_size;
+ info->dynstr = bfd_alloc (abfd, amt);
+ if (info->dynstr == NULL && info->dyninfo.ld_symb_size != 0)
+ return FALSE;
+ if (bfd_seek (abfd, (file_ptr) info->dyninfo.ld_symbols, SEEK_SET) != 0
+ || bfd_bread ((void *) info->dynstr, amt, abfd) != amt)
+ {
+ 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 (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_malloc (table_size);
+ if (table == NULL && table_size != 0)
+ abort ();
+ if (bfd_seek (abfd, (file_ptr) info->dyninfo.ld_hash, SEEK_SET) != 0
+ || bfd_bread ((void *) table, 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 == NULL)
+ {
+ bfd_size_type size;
+ bfd_size_type strsize = info->dyninfo.ld_symb_size;
+
+ size = (bfd_size_type) info->dynsym_count * sizeof (aout_symbol_type);
+ info->canonical_dynsym = bfd_alloc (abfd, size);
+ if (info->canonical_dynsym == NULL && info->dynsym_count != 0)
+ return -1;
+
+ if (! aout_32_translate_symbol_table (abfd, info->canonical_dynsym,
+ info->dynsym,
+ (bfd_size_type) info->dynsym_count,
+ info->dynstr, strsize, 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 (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 (bfd *abfd, arelent **storage, asymbol **syms)
+{
+ struct sunos_dynamic_info *info;
+ unsigned long i;
+ bfd_size_type size;
+
+ /* Get the general dynamic information. */
+ if (obj_aout_dynamic_info (abfd) == 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)
+ {
+ size = (bfd_size_type) info->dynrel_count * obj_reloc_entry_size (abfd);
+ info->dynrel = bfd_alloc (abfd, size);
+ if (info->dynrel == NULL && size != 0)
+ return -1;
+ if (bfd_seek (abfd, (file_ptr) info->dyninfo.ld_rel, SEEK_SET) != 0
+ || bfd_bread ((void *) info->dynrel, size, abfd) != size)
+ {
+ 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 == NULL)
+ {
+ arelent *to;
+
+ size = (bfd_size_type) info->dynrel_count * sizeof (arelent);
+ info->canonical_dynrel = bfd_alloc (abfd, size);
+ if (info->canonical_dynrel == NULL && info->dynrel_count != 0)
+ return -1;
+
+ to = info->canonical_dynrel;
+
+ if (obj_reloc_entry_size (abfd) == RELOC_EXT_SIZE)
+ {
+ 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,
+ (bfd_size_type) info->dynsym_count);
+ }
+ else
+ {
+ 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,
+ (bfd_size_type) 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 ((bfd_vma) 0x9de3bfa0)
+/* call; address filled in later. */
+#define SPARC_PLT_ENTRY_WORD1 ((bfd_vma) 0x40000000)
+/* sethi; reloc index filled in later. */
+#define SPARC_PLT_ENTRY_WORD2 ((bfd_vma) 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 ((bfd_vma) 0x03000000)
+/* jmp %g1 + <address to be filled in later> */
+#define SPARC_PLT_PIC_WORD1 ((bfd_vma) 0x81c06000)
+/* nop */
+#define SPARC_PLT_PIC_WORD2 ((bfd_vma) 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 ((bfd_vma) 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. */
+ bfd_boolean dynamic_sections_created;
+
+ /* Whether we need the dynamic sections. */
+ bfd_boolean dynamic_sections_needed;
+
+ /* Whether we need the .got table. */
+ bfd_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 (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 == NULL)
+ ret = bfd_hash_allocate (table, sizeof (* ret));
+ if (ret == NULL)
+ return NULL;
+
+ /* 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 (bfd *abfd)
+{
+ struct sunos_link_hash_table *ret;
+ bfd_size_type amt = sizeof (struct sunos_link_hash_table);
+
+ ret = bfd_zmalloc (amt);
+ if (ret == NULL)
+ return NULL;
+ if (!NAME (aout, link_hash_table_init) (&ret->root, abfd,
+ sunos_link_hash_newfunc,
+ sizeof (struct sunos_link_hash_entry)))
+ {
+ free (ret);
+ return NULL;
+ }
+
+ 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, \
+ (bfd_boolean (*) (struct aout_link_hash_entry *, void *)) (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))
+
+/* 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 bfd_boolean
+sunos_create_dynamic_sections (bfd *abfd,
+ struct bfd_link_info *info,
+ bfd_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_anyway_with_flags (abfd, ".dynamic", flags);
+ if (s == NULL
+ || ! 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_anyway_with_flags (abfd, ".got", flags);
+ if (s == NULL
+ || ! 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_anyway_with_flags (abfd, ".plt", flags | SEC_CODE);
+ if (s == NULL
+ || ! 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_anyway_with_flags (abfd, ".dynrel",
+ flags | SEC_READONLY);
+ if (s == NULL
+ || ! 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_anyway_with_flags (abfd, ".hash",
+ flags | SEC_READONLY);
+ if (s == NULL
+ || ! 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_anyway_with_flags (abfd, ".dynsym",
+ flags | SEC_READONLY);
+ if (s == NULL
+ || ! 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_anyway_with_flags (abfd, ".dynstr",
+ flags | SEC_READONLY);
+ if (s == NULL
+ || ! 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_linker_section (dynobj, ".got");
+ if (s->size == 0)
+ s->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 bfd_boolean
+sunos_add_dynamic_symbols (bfd *abfd,
+ struct bfd_link_info *info,
+ struct external_nlist **symsp,
+ bfd_size_type *sym_countp,
+ char **stringsp)
+{
+ bfd *dynobj;
+ struct sunos_dynamic_info *dinfo;
+ unsigned long need;
+
+ /* Make sure we have all the required sections. */
+ if (info->output_bfd->xvec == abfd->xvec)
+ {
+ if (! sunos_create_dynamic_sections (abfd, info,
+ ((abfd->flags & DYNAMIC) != 0
+ && !info->relocatable)))
+ 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 != NULL; s = s->next)
+ {
+ if ((s->flags & SEC_LINKER_CREATED) == 0)
+ bfd_section_list_remove (abfd, s);
+ }
+ }
+
+ /* The native linker seems to just ignore dynamic objects when -r is
+ used. */
+ if (info->relocatable)
+ return TRUE;
+
+ /* There's no hope of using a dynamic object which does not exactly
+ match the format of the output file. */
+ if (info->output_bfd->xvec != 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. */
+ flagword flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS
+ | SEC_IN_MEMORY | SEC_READONLY);
+ asection *s = bfd_make_section_with_flags (dynobj, ".need", flags);
+ if (s == NULL
+ || ! 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. */
+ flagword flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS
+ | SEC_IN_MEMORY | SEC_READONLY);
+ asection *s = bfd_make_section_with_flags (dynobj, ".rules", flags);
+ if (s == NULL
+ || ! 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;
+ bfd_size_type alc;
+ bfd_byte b;
+ char *namecopy;
+
+ if (bfd_seek (abfd, (file_ptr) need, SEEK_SET) != 0
+ || bfd_bread (buf, (bfd_size_type) 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);
+
+ alc = sizeof (struct bfd_link_needed_list);
+ needed = bfd_alloc (abfd, alc);
+ if (needed == NULL)
+ return FALSE;
+ needed->by = abfd;
+
+ /* We return the name as [-l]name[.maj][.min]. */
+ alc = 30;
+ namebuf = bfd_malloc (alc + 1);
+ if (namebuf == NULL)
+ return FALSE;
+ p = namebuf;
+
+ if ((flags & 0x80000000) != 0)
+ {
+ *p++ = '-';
+ *p++ = 'l';
+ }
+ if (bfd_seek (abfd, (file_ptr) name, SEEK_SET) != 0)
+ {
+ free (namebuf);
+ return FALSE;
+ }
+
+ do
+ {
+ if (bfd_bread (&b, (bfd_size_type) 1, abfd) != 1)
+ {
+ free (namebuf);
+ return FALSE;
+ }
+
+ if ((bfd_size_type) (p - namebuf) >= alc)
+ {
+ char *n;
+
+ alc *= 2;
+ n = 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 = 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, (bfd_size_type) 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 bfd_boolean
+sunos_add_one_symbol (struct bfd_link_info *info,
+ bfd *abfd,
+ const char *name,
+ flagword flags,
+ asection *section,
+ bfd_vma value,
+ const char *string,
+ bfd_boolean copy,
+ bfd_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->output_bfd->xvec
+ && (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->output_bfd->xvec)
+ {
+ /* 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;
+}
+
+extern const bfd_target MY (vec);
+
+/* Return the list of objects needed by BFD. */
+
+struct bfd_link_needed_list *
+bfd_sunos_get_needed_list (bfd *abfd ATTRIBUTE_UNUSED,
+ struct bfd_link_info *info)
+{
+ if (info->output_bfd->xvec != &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. */
+
+bfd_boolean
+bfd_sunos_record_link_assignment (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;
+}
+
+/* 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 bfd_boolean
+sunos_scan_std_relocs (struct bfd_link_info *info,
+ bfd *abfd,
+ asection *sec ATTRIBUTE_UNUSED,
+ 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_linker_section (dynobj, ".plt");
+ srel = bfd_get_linker_section (dynobj, ".dynrel");
+ BFD_ASSERT (splt != NULL && srel != NULL);
+
+ sgot = bfd_get_linker_section (dynobj, ".got");
+ BFD_ASSERT (sgot != NULL);
+ if (sgot->size == 0)
+ sgot->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->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->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->size == 0)
+ splt->size = M68K_PLT_ENTRY_SIZE;
+ h->plt_offset = splt->size;
+
+ if ((h->flags & SUNOS_DEF_REGULAR) == 0)
+ {
+ h->root.root.u.def.section = splt;
+ h->root.root.u.def.value = splt->size;
+ }
+
+ splt->size += M68K_PLT_ENTRY_SIZE;
+
+ /* We may also need a dynamic reloc entry. */
+ if ((h->flags & SUNOS_DEF_REGULAR) == 0)
+ srel->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 bfd_boolean
+sunos_scan_ext_relocs (struct bfd_link_info *info,
+ bfd *abfd,
+ asection *sec ATTRIBUTE_UNUSED,
+ 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;
+ bfd_size_type amt;
+
+ /* 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_linker_section (dynobj, ".plt");
+ sgot = bfd_get_linker_section (dynobj, ".got");
+ srel = bfd_get_linker_section (dynobj, ".dynrel");
+ BFD_ASSERT (splt != NULL && sgot != NULL && srel != NULL);
+
+ /* Make sure we have an initial entry in the .got table. */
+ if (sgot->size == 0)
+ sgot->size = BYTES_IN_WORD;
+ sunos_hash_table (info)->got_needed = TRUE;
+ }
+
+ if (r_extern)
+ {
+ if (h->got_offset != 0)
+ continue;
+
+ h->got_offset = sgot->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)
+ {
+ amt = bfd_get_symcount (abfd);
+ amt *= sizeof (bfd_vma);
+ adata (abfd).local_got_offsets = bfd_zalloc (abfd, amt);
+ 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->size;
+ }
+
+ sgot->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->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_linker_section (dynobj, ".plt");
+ sgot = bfd_get_linker_section (dynobj, ".got");
+ srel = bfd_get_linker_section (dynobj, ".dynrel");
+ BFD_ASSERT (splt != NULL && sgot != NULL && srel != NULL);
+ }
+
+ srel->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_linker_section (dynobj, ".plt");
+ sgot = bfd_get_linker_section (dynobj, ".got");
+ srel = bfd_get_linker_section (dynobj, ".dynrel");
+ BFD_ASSERT (splt != NULL && sgot != NULL && srel != NULL);
+
+ /* Make sure we have an initial entry in the .got table. */
+ if (sgot->size == 0)
+ sgot->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->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->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->size == 0)
+ splt->size = SPARC_PLT_ENTRY_SIZE;
+ h->plt_offset = splt->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->size;
+ }
+
+ splt->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->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->size += RELOC_EXT_SIZE;
+ }
+ }
+
+ return TRUE;
+}
+
+/* Scan the relocs for an input section. */
+
+static bfd_boolean
+sunos_scan_relocs (struct bfd_link_info *info,
+ bfd *abfd,
+ asection *sec,
+ bfd_size_type rel_size)
+{
+ void * relocs;
+ void * free_relocs = NULL;
+
+ if (rel_size == 0)
+ return TRUE;
+
+ if (! info->keep_memory)
+ relocs = free_relocs = bfd_malloc (rel_size);
+ else
+ {
+ struct aout_section_data_struct *n;
+ bfd_size_type amt = sizeof (struct aout_section_data_struct);
+
+ n = bfd_alloc (abfd, amt);
+ if (n == NULL)
+ relocs = NULL;
+ else
+ {
+ set_aout_section_data (sec, n);
+ relocs = bfd_malloc (rel_size);
+ aout_section_data (sec)->relocs = relocs;
+ }
+ }
+ if (relocs == NULL)
+ return FALSE;
+
+ if (bfd_seek (abfd, sec->rel_filepos, SEEK_SET) != 0
+ || bfd_bread (relocs, 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;
+}
+
+/* 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 bfd_boolean
+sunos_scan_dynamic_symbol (struct sunos_link_hash_entry *h, void * 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_linker_section (dynobj, ".dynstr");
+ BFD_ASSERT (s != NULL);
+ contents = bfd_realloc (s->contents, s->size + len + 1);
+ if (contents == NULL)
+ return FALSE;
+ s->contents = contents;
+
+ h->dynstr_index = s->size;
+ strcpy ((char *) contents + s->size, h->root.root.root.string);
+ s->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_linker_section (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->size / HASH_ENTRY_SIZE,
+ s->contents + hash * HASH_ENTRY_SIZE + BYTES_IN_WORD);
+ PUT_WORD (dynobj, h->dynindx, s->contents + s->size);
+ PUT_WORD (dynobj, next, s->contents + s->size + BYTES_IN_WORD);
+ s->size += HASH_ENTRY_SIZE;
+ }
+ }
+
+ 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. */
+
+bfd_boolean
+bfd_sunos_size_dynamic_sections (bfd *output_bfd,
+ struct bfd_link_info *info,
+ asection **sdynptr,
+ asection **sneedptr,
+ asection **srulesptr)
+{
+ bfd *dynobj;
+ bfd_size_type dynsymcount;
+ struct sunos_link_hash_entry *h;
+ asection *s;
+ size_t bucketcount;
+ bfd_size_type hashalloc;
+ size_t i;
+ bfd *sub;
+
+ *sdynptr = NULL;
+ *sneedptr = NULL;
+ *srulesptr = NULL;
+
+ if (info->relocatable)
+ 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;
+ }
+ s = bfd_get_linker_section (dynobj, ".got");
+ BFD_ASSERT (s != NULL);
+ h->root.root.type = bfd_link_hash_defined;
+ h->root.root.u.def.section = s;
+
+ /* 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. */
+ if (s->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_linker_section (dynobj, ".dynamic");
+
+ /* The .dynamic section is always the same size. */
+ s = *sdynptr;
+ BFD_ASSERT (s != NULL);
+ s->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_linker_section (dynobj, ".dynsym");
+ BFD_ASSERT (s != NULL);
+ s->size = dynsymcount * sizeof (struct external_nlist);
+ s->contents = bfd_alloc (output_bfd, s->size);
+ if (s->contents == NULL && s->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_linker_section (dynobj, ".hash");
+ BFD_ASSERT (s != NULL);
+ hashalloc = (dynsymcount + bucketcount - 1) * HASH_ENTRY_SIZE;
+ s->contents = bfd_zalloc (dynobj, hashalloc);
+ if (s->contents == NULL && dynsymcount > 0)
+ return FALSE;
+ for (i = 0; i < bucketcount; i++)
+ PUT_WORD (output_bfd, (bfd_vma) -1, s->contents + i * HASH_ENTRY_SIZE);
+ s->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,
+ (void *) 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_linker_section (dynobj, ".dynstr");
+ BFD_ASSERT (s != NULL);
+ if ((s->size & 7) != 0)
+ {
+ bfd_size_type add;
+ bfd_byte *contents;
+
+ add = 8 - (s->size & 7);
+ contents = bfd_realloc (s->contents, s->size + add);
+ if (contents == NULL)
+ return FALSE;
+ memset (contents + s->size, 0, (size_t) add);
+ s->contents = contents;
+ s->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_linker_section (dynobj, ".plt");
+ BFD_ASSERT (s != NULL);
+ if (s->size != 0)
+ {
+ s->contents = bfd_alloc (dynobj, s->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_linker_section (dynobj, ".dynrel");
+ if (s->size != 0)
+ {
+ s->contents = bfd_alloc (dynobj, s->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_linker_section (dynobj, ".got");
+ s->contents = bfd_alloc (dynobj, s->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;
+}
+
+/* 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. */
+
+static bfd_boolean
+sunos_link_dynamic_object (struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ bfd *abfd ATTRIBUTE_UNUSED)
+{
+ return TRUE;
+}
+
+/* Write out a dynamic symbol. This is called by the final traversal
+ over the symbol table. */
+
+static bfd_boolean
+sunos_write_dynamic_symbol (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;
+ bfd_vma r_address;
+
+ dynobj = sunos_hash_table (info)->dynobj;
+ splt = bfd_get_linker_section (dynobj, ".plt");
+ p = splt->contents + h->plt_offset;
+
+ s = bfd_get_linker_section (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
+ {
+ 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, (bfd_vma) 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->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_linker_section (sunos_hash_table (info)->dynobj, ".dynsym");
+ BFD_ASSERT (s != NULL);
+ outsym = ((struct external_nlist *)
+ (s->contents + h->dynindx * EXTERNAL_NLIST_SIZE));
+
+ H_PUT_8 (output_bfd, type, outsym->e_type);
+ 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. */
+ 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. */
+
+static bfd_boolean
+sunos_check_dynamic_reloc (struct bfd_link_info *info,
+ bfd *input_bfd,
+ asection *input_section,
+ struct aout_link_hash_entry *harg,
+ void * reloc,
+ bfd_byte *contents ATTRIBUTE_UNUSED,
+ bfd_boolean *skip,
+ bfd_vma *relocationp)
+{
+ struct sunos_link_hash_entry *h = (struct sunos_link_hash_entry *) harg;
+ bfd *dynobj;
+ bfd_boolean baserel;
+ bfd_boolean jmptbl;
+ bfd_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_linker_section (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_linker_section (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_linker_section (dynobj, ".dynrel");
+ BFD_ASSERT (s != NULL);
+ BFD_ASSERT (s->reloc_count * obj_reloc_entry_size (dynobj)
+ < s->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 &~ (bfd_vma) 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_linker_section (dynobj, ".dynrel");
+ BFD_ASSERT (s != NULL);
+ BFD_ASSERT (s->reloc_count * obj_reloc_entry_size (dynobj) < s->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 bfd_boolean
+sunos_finish_dynamic_link (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_linker_section (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->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_linker_section (dynobj, ".got");
+ BFD_ASSERT (s != NULL);
+ if (info->shared || sdyn->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,
+ (file_ptr) o->output_offset,
+ o->size))
+ return FALSE;
+ }
+ }
+
+ if (sdyn->size > 0)
+ {
+ struct external_sun4_dynamic esd;
+ struct external_sun4_dynamic_link esdl;
+ file_ptr pos;
+
+ /* 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,
+ (file_ptr) sdyn->output_offset,
+ (bfd_size_type) 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->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->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_linker_section (dynobj, ".got");
+ BFD_ASSERT (s != NULL);
+ PUT_WORD (dynobj, s->output_section->vma + s->output_offset,
+ esdl.ld_got);
+
+ s = bfd_get_linker_section (dynobj, ".plt");
+ BFD_ASSERT (s != NULL);
+ PUT_WORD (dynobj, s->output_section->vma + s->output_offset,
+ esdl.ld_plt);
+ PUT_WORD (dynobj, s->size, esdl.ld_plt_sz);
+
+ s = bfd_get_linker_section (dynobj, ".dynrel");
+ BFD_ASSERT (s != NULL);
+ BFD_ASSERT (s->reloc_count * obj_reloc_entry_size (dynobj)
+ == s->size);
+ PUT_WORD (dynobj, s->output_section->filepos + s->output_offset,
+ esdl.ld_rel);
+
+ s = bfd_get_linker_section (dynobj, ".hash");
+ BFD_ASSERT (s != NULL);
+ PUT_WORD (dynobj, s->output_section->filepos + s->output_offset,
+ esdl.ld_hash);
+
+ s = bfd_get_linker_section (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_linker_section (dynobj, ".dynstr");
+ BFD_ASSERT (s != NULL);
+ PUT_WORD (dynobj, s->output_section->filepos + s->output_offset,
+ esdl.ld_symbols);
+ PUT_WORD (dynobj, s->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)->size, 0x2000),
+ esdl.ld_text);
+
+ pos = sdyn->output_offset;
+ pos += sizeof esd + EXTERNAL_SUN4_DYNAMIC_DEBUGGER_SIZE;
+ if (! bfd_set_section_contents (abfd, sdyn->output_section, &esdl,
+ pos, (bfd_size_type) sizeof esdl))
+ return FALSE;
+
+ abfd->flags |= DYNAMIC;
+ }
+
+ return TRUE;
+}
diff --git a/bfd/syms.c b/bfd/syms.c
new file mode 100644
index 0000000..a1d1d77
--- /dev/null
+++ b/bfd/syms.c
@@ -0,0 +1,1413 @@
+/* Generic symbol-table support for the BFD library.
+ Copyright (C) 1990-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, 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 = 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 "sysdep.h"
+| #include "bfd.h"
+| int main (void)
+| {
+| 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] = 0;
+|
+| bfd_set_symtab (abfd, ptrs, 1);
+| bfd_close (abfd);
+| return 0;
+| }
+|
+| ./makesym
+| nm foo
+| 00012345 A dummy_symbol
+
+ Many formats cannot represent arbitrary symbol information; for
+ instance, the <<a.out>> object format does not allow an
+ arbitrary 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 bfd_symbol
+.{
+. {* 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 (1 << 0)
+.
+. {* The symbol has global scope; initialized data in <<C>>. The
+. value is the offset into the section of the data. *}
+.#define BSF_GLOBAL (1 << 1)
+.
+. {* 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_COMMON>>, <<BSF_UNDEFINED>> or
+. <<BSF_GLOBAL>>. *}
+.
+. {* The symbol is a debugging record. The value has an arbitrary
+. meaning, unless BSF_DEBUGGING_RELOC is also set. *}
+.#define BSF_DEBUGGING (1 << 2)
+.
+. {* The symbol denotes a function entry point. Used in ELF,
+. perhaps others someday. *}
+.#define BSF_FUNCTION (1 << 3)
+.
+. {* Used by the linker. *}
+.#define BSF_KEEP (1 << 5)
+.#define BSF_KEEP_G (1 << 6)
+.
+. {* A weak global symbol, overridable without warnings by
+. a regular global symbol of the same name. *}
+.#define BSF_WEAK (1 << 7)
+.
+. {* This symbol was created to point to a section, e.g. ELF's
+. STT_SECTION symbols. *}
+.#define BSF_SECTION_SYM (1 << 8)
+.
+. {* The symbol used to be a common symbol, but now it is
+. allocated. *}
+.#define BSF_OLD_COMMON (1 << 9)
+.
+. {* 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 (1 << 10)
+.
+. {* Signal that the symbol is the label of constructor section. *}
+.#define BSF_CONSTRUCTOR (1 << 11)
+.
+. {* 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 (1 << 12)
+.
+. {* 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 (1 << 13)
+.
+. {* BSF_FILE marks symbols that contain a file name. This is used
+. for ELF STT_FILE symbols. *}
+.#define BSF_FILE (1 << 14)
+.
+. {* Symbol is from dynamic linking information. *}
+.#define BSF_DYNAMIC (1 << 15)
+.
+. {* The symbol denotes a data object. Used in ELF, and perhaps
+. others someday. *}
+.#define BSF_OBJECT (1 << 16)
+.
+. {* This symbol is a debugging symbol. The value is the offset
+. into the section of the data. BSF_DEBUGGING should be set
+. as well. *}
+.#define BSF_DEBUGGING_RELOC (1 << 17)
+.
+. {* This symbol is thread local. Used in ELF. *}
+.#define BSF_THREAD_LOCAL (1 << 18)
+.
+. {* This symbol represents a complex relocation expression,
+. with the expression tree serialized in the symbol name. *}
+.#define BSF_RELC (1 << 19)
+.
+. {* This symbol represents a signed complex relocation expression,
+. with the expression tree serialized in the symbol name. *}
+.#define BSF_SRELC (1 << 20)
+.
+. {* This symbol was created by bfd_get_synthetic_symtab. *}
+.#define BSF_SYNTHETIC (1 << 21)
+.
+. {* This symbol is an indirect code object. Unrelated to BSF_INDIRECT.
+. The dynamic linker will compute the value of this symbol by
+. calling the function that it points to. BSF_FUNCTION must
+. also be also set. *}
+.#define BSF_GNU_INDIRECT_FUNCTION (1 << 22)
+. {* This symbol is a globally unique data object. The dynamic linker
+. will make sure that in the entire process there is just one symbol
+. with this name and type in use. BSF_OBJECT must also be set. *}
+.#define BSF_GNU_UNIQUE (1 << 23)
+.
+. 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 bfd_section *section;
+.
+. {* Back end special data. *}
+. union
+. {
+. void *p;
+. bfd_vma i;
+. }
+. udata;
+.}
+.asymbol;
+.
+*/
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+#include "safe-ctype.h"
+#include "bfdlink.h"
+#include "aout/stab_gnu.h"
+
+/*
+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
+ bfd_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.
+*/
+
+bfd_boolean
+bfd_is_local_label (bfd *abfd, asymbol *sym)
+{
+ /* The BSF_SECTION_SYM check is needed for IA-64, where every label that
+ starts with '.' is local. This would accidentally catch section names
+ if we didn't reject them here. */
+ if ((sym->flags & (BSF_GLOBAL | BSF_WEAK | BSF_FILE | BSF_SECTION_SYM)) != 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
+ bfd_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_is_target_special_symbol
+
+SYNOPSIS
+ bfd_boolean bfd_is_target_special_symbol (bfd *abfd, asymbol *sym);
+
+DESCRIPTION
+ Return TRUE iff a symbol @var{sym} in the BFD @var{abfd} is something
+ special to the particular target represented by the BFD. Such symbols
+ should normally not be mentioned to the user.
+
+.#define bfd_is_target_special_symbol(abfd, sym) \
+. BFD_SEND (abfd, _bfd_is_target_special_symbol, (abfd, sym))
+.
+*/
+
+/*
+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
+ bfd_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.
+*/
+
+bfd_boolean
+bfd_set_symtab (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 (bfd *abfd, void *file, asymbol *symbol);
+
+DESCRIPTION
+ Print the value and flags of the @var{symbol} supplied to the
+ stream @var{file}.
+*/
+void
+bfd_print_symbol_vandf (bfd *abfd, void *arg, asymbol *symbol)
+{
+ FILE *file = (FILE *) arg;
+
+ flagword type = symbol->flags;
+
+ if (symbol->section != NULL)
+ bfd_fprintf_vma (abfd, file, symbol->value + symbol->section->vma);
+ else
+ bfd_fprintf_vma (abfd, 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_GNU_UNIQUE) ? 'u' : ' '),
+ (type & BSF_WEAK) ? 'w' : ' ',
+ (type & BSF_CONSTRUCTOR) ? 'C' : ' ',
+ (type & BSF_WARNING) ? 'W' : ' ',
+ (type & BSF_INDIRECT) ? 'I' : (type & BSF_GNU_INDIRECT_FUNCTION) ? '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_generic_make_empty_symbol
+
+SYNOPSIS
+ asymbol *_bfd_generic_make_empty_symbol (bfd *);
+
+DESCRIPTION
+ Create a new <<asymbol>> structure for the BFD @var{abfd}
+ and return a pointer to it. Used by core file routines,
+ binary back-end and anywhere else where no private info
+ is needed.
+*/
+
+asymbol *
+_bfd_generic_make_empty_symbol (bfd *abfd)
+{
+ bfd_size_type amt = sizeof (asymbol);
+ asymbol *new_symbol = (asymbol *) bfd_zalloc (abfd, amt);
+ if (new_symbol)
+ new_symbol->the_bfd = abfd;
+ return new_symbol;
+}
+
+/*
+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[] =
+{
+ {".bss", 'b'},
+ {"code", 't'}, /* MRI .text */
+ {".data", 'd'},
+ {"*DEBUG*", 'N'},
+ {".debug", 'N'}, /* MSVC's .debug (non-standard debug syms) */
+ {".drectve", 'i'}, /* MSVC's .drective section */
+ {".edata", 'e'}, /* MSVC's .edata (export) section */
+ {".fini", 't'}, /* ELF fini section */
+ {".idata", 'i'}, /* MSVC's .idata (import) section */
+ {".init", 't'}, /* ELF init section */
+ {".pdata", 'p'}, /* MSVC's .pdata (stack unwind) section */
+ {".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'},
+ {"vars", 'd'}, /* MRI .data */
+ {"zerovars", 'b'}, /* MRI .bss */
+ {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 (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 '?';
+}
+
+/* Return the single-character symbol type corresponding to section
+ SECTION, or '?' for an unknown section. This uses section flags to
+ identify sections.
+
+ FIXME These types are unhandled: c, i, e, p. If we handled these also,
+ we could perhaps obsolete coff_section_type. */
+
+static char
+decode_section_type (const struct bfd_section *section)
+{
+ if (section->flags & SEC_CODE)
+ return 't';
+ if (section->flags & SEC_DATA)
+ {
+ if (section->flags & SEC_READONLY)
+ return 'r';
+ else if (section->flags & SEC_SMALL_DATA)
+ return 'g';
+ else
+ return 'd';
+ }
+ if ((section->flags & SEC_HAS_CONTENTS) == 0)
+ {
+ if (section->flags & SEC_SMALL_DATA)
+ return 's';
+ else
+ return 'b';
+ }
+ if (section->flags & SEC_DEBUGGING)
+ return 'N';
+ if ((section->flags & SEC_HAS_CONTENTS) && (section->flags & SEC_READONLY))
+ return 'n';
+
+ return '?';
+}
+
+/*
+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 (asymbol *symbol)
+{
+ char c;
+
+ if (symbol->section && bfd_is_com_section (symbol->section))
+ return 'C';
+ if (bfd_is_und_section (symbol->section))
+ {
+ if (symbol->flags & BSF_WEAK)
+ {
+ /* If weak, determine if it's specifically an object
+ or non-object weak. */
+ if (symbol->flags & BSF_OBJECT)
+ return 'v';
+ else
+ return 'w';
+ }
+ else
+ return 'U';
+ }
+ if (bfd_is_ind_section (symbol->section))
+ return 'I';
+ if (symbol->flags & BSF_GNU_INDIRECT_FUNCTION)
+ return 'i';
+ if (symbol->flags & BSF_WEAK)
+ {
+ /* If weak, determine if it's specifically an object
+ or non-object weak. */
+ if (symbol->flags & BSF_OBJECT)
+ return 'V';
+ else
+ return 'W';
+ }
+ if (symbol->flags & BSF_GNU_UNIQUE)
+ return 'u';
+ 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);
+ if (c == '?')
+ c = decode_section_type (symbol->section);
+ }
+ 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_is_undefined_symclass
+
+DESCRIPTION
+ Returns non-zero if the class symbol returned by
+ bfd_decode_symclass represents an undefined symbol.
+ Returns zero otherwise.
+
+SYNOPSIS
+ bfd_boolean bfd_is_undefined_symclass (int symclass);
+*/
+
+bfd_boolean
+bfd_is_undefined_symclass (int symclass)
+{
+ return symclass == 'U' || symclass == 'w' || symclass == 'v';
+}
+
+/*
+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 (asymbol *symbol, symbol_info *ret)
+{
+ ret->type = bfd_decode_symclass (symbol);
+
+ if (bfd_is_undefined_symclass (ret->type))
+ ret->value = 0;
+ else
+ ret->value = symbol->value + symbol->section->vma;
+
+ ret->name = symbol->name;
+}
+
+/*
+FUNCTION
+ bfd_copy_private_symbol_data
+
+SYNOPSIS
+ bfd_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 (bfd *abfd,
+ bfd_boolean dynamic,
+ void **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;
+ if (storage == 0)
+ return 0;
+
+ syms = (asymbol **) bfd_malloc (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 = syms;
+ *sizep = sizeof (asymbol *);
+ return symcount;
+
+ error_return:
+ bfd_set_error (bfd_error_no_symbols);
+ 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. */
+
+asymbol *
+_bfd_generic_minisymbol_to_symbol (bfd *abfd ATTRIBUTE_UNUSED,
+ bfd_boolean dynamic ATTRIBUTE_UNUSED,
+ const void *minisym,
+ asymbol *sym ATTRIBUTE_UNUSED)
+{
+ 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 (const void *a, const void *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;
+};
+
+bfd_boolean
+_bfd_stab_section_find_nearest_line (bfd *abfd,
+ asymbol **symbols,
+ asection *section,
+ bfd_vma offset,
+ bfd_boolean *pfound,
+ const char **pfilename,
+ const char **pfnname,
+ unsigned int *pline,
+ void **pinfo)
+{
+ struct stab_find_info *info;
+ bfd_size_type stabsize, strsize;
+ bfd_byte *stab, *str;
+ bfd_byte *nul_fun, *nul_str;
+ bfd_size_type stroff;
+ struct indexentry *indexentry;
+ char *file_name;
+ char *directory_name;
+ bfd_boolean saw_line, saw_func;
+
+ *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->rawsize
+ ? info->stabsec->rawsize
+ : info->stabsec->size);
+ strsize = (info->strsec->rawsize
+ ? info->strsec->rawsize
+ : info->strsec->size);
+ }
+ else
+ {
+ long reloc_size, reloc_count;
+ arelent **reloc_vector;
+ int i;
+ char *function_name;
+ bfd_size_type amt = sizeof *info;
+
+ info = (struct stab_find_info *) bfd_zalloc (abfd, amt);
+ 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)
+ {
+ /* Try SOM section names. */
+ info->stabsec = bfd_get_section_by_name (abfd, "$GDB_SYMBOLS$");
+ info->strsec = bfd_get_section_by_name (abfd, "$GDB_STRINGS$");
+
+ 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 = info;
+ return TRUE;
+ }
+ }
+
+ stabsize = (info->stabsec->rawsize
+ ? info->stabsec->rawsize
+ : info->stabsec->size);
+ stabsize = (stabsize / STABSIZE) * STABSIZE;
+ strsize = (info->strsec->rawsize
+ ? info->strsec->rawsize
+ : info->strsec->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 relocatable 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;
+ /* Ignore R_*_NONE relocs. */
+ if (r->howto->dst_mask == 0)
+ continue;
+
+ 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, (bfd_vma) 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;
+ nul_fun = NULL;
+ for (stab = info->stabs; stab < info->stabs + stabsize; stab += STABSIZE)
+ {
+ if (stab[TYPEOFF] == (bfd_byte) N_SO)
+ {
+ /* if we did not see a function def, leave space for one. */
+ if (nul_fun != NULL)
+ ++info->indextablesize;
+
+ /* N_SO with null name indicates EOF */
+ if (bfd_get_32 (abfd, stab + STRDXOFF) == 0)
+ nul_fun = NULL;
+ else
+ {
+ nul_fun = stab;
+
+ /* two N_SO's in a row is a filename and directory. Skip */
+ if (stab + STABSIZE + TYPEOFF < info->stabs + stabsize
+ && *(stab + STABSIZE + TYPEOFF) == (bfd_byte) N_SO)
+ stab += STABSIZE;
+ }
+ }
+ else if (stab[TYPEOFF] == (bfd_byte) N_FUN
+ && bfd_get_32 (abfd, stab + STRDXOFF) != 0)
+ {
+ nul_fun = NULL;
+ ++info->indextablesize;
+ }
+ }
+
+ if (nul_fun != NULL)
+ ++info->indextablesize;
+
+ if (info->indextablesize == 0)
+ return TRUE;
+ ++info->indextablesize;
+
+ amt = info->indextablesize;
+ amt *= sizeof (struct indexentry);
+ info->indextable = (struct indexentry *) bfd_alloc (abfd, amt);
+ if (info->indextable == NULL)
+ return FALSE;
+
+ file_name = NULL;
+ directory_name = NULL;
+ nul_fun = NULL;
+ stroff = 0;
+
+ for (i = 0, stab = info->stabs, nul_str = 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 (nul_fun != NULL)
+ {
+ info->indextable[i].val = bfd_get_32 (abfd, nul_fun + VALOFF);
+ info->indextable[i].stab = nul_fun;
+ info->indextable[i].str = nul_str;
+ info->indextable[i].directory_name = directory_name;
+ info->indextable[i].file_name = file_name;
+ info->indextable[i].function_name = NULL;
+ ++i;
+ }
+
+ directory_name = NULL;
+ file_name = (char *) str + bfd_get_32 (abfd, stab + STRDXOFF);
+ if (file_name == (char *) str)
+ {
+ file_name = NULL;
+ nul_fun = NULL;
+ }
+ else
+ {
+ nul_fun = stab;
+ nul_str = str;
+ if (stab + STABSIZE + TYPEOFF < info->stabs + stabsize
+ && *(stab + STABSIZE + TYPEOFF) == (bfd_byte) N_SO)
+ {
+ /* 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. */
+ function_name = (char *) str + bfd_get_32 (abfd, stab + STRDXOFF);
+ if (function_name == (char *) str)
+ continue;
+
+ nul_fun = NULL;
+ 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 (nul_fun != NULL)
+ {
+ info->indextable[i].val = bfd_get_32 (abfd, nul_fun + VALOFF);
+ info->indextable[i].stab = nul_fun;
+ info->indextable[i].str = nul_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, (size_t) i, sizeof (struct indexentry),
+ cmpindexentry);
+
+ *pinfo = 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
+ {
+ long low, high;
+ long mid = -1;
+
+ /* Cache non-existent or invalid. Do binary search on
+ indextable. */
+ 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;
+
+ saw_line = FALSE;
+ saw_func = FALSE;
+ for (; stab < (indexentry+1)->stab; stab += STABSIZE)
+ {
+ bfd_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. If the function was specified, then the value
+ is relative to the start of the function. Otherwise, the
+ value is an absolute address. */
+ val = ((indexentry->function_name ? indexentry->val : 0)
+ + bfd_get_32 (abfd, stab + VALOFF));
+ /* If this line starts before our desired offset, or if it's
+ the first line we've been able to find, use it. The
+ !saw_line check works around a bug in GCC 2.95.3, which emits
+ the first N_SLINE late. */
+ if (!saw_line || 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;
+ saw_line = TRUE;
+ break;
+
+ case N_FUN:
+ case N_SO:
+ if (saw_func || saw_line)
+ done = TRUE;
+ saw_func = TRUE;
+ break;
+ }
+
+ if (done)
+ break;
+ }
+
+ *pfound = TRUE;
+
+ if (file_name == NULL || IS_ABSOLUTE_PATH (file_name)
+ || directory_name == NULL)
+ *pfilename = file_name;
+ else
+ {
+ size_t dirlen;
+
+ dirlen = strlen (directory_name);
+ if (info->filename == NULL
+ || filename_ncmp (info->filename, directory_name, dirlen) != 0
+ || filename_cmp (info->filename + dirlen, file_name) != 0)
+ {
+ size_t len;
+
+ /* Don't free info->filename here. objdump and other
+ apps keep a copy of a previously returned file name
+ pointer. */
+ len = strlen (file_name) + 1;
+ info->filename = (char *) bfd_alloc (abfd, dirlen + len);
+ if (info->filename == NULL)
+ return FALSE;
+ memcpy (info->filename, directory_name, dirlen);
+ memcpy (info->filename + dirlen, file_name, len);
+ }
+
+ *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 0000000..7e441eb
--- /dev/null
+++ b/bfd/sysdep.h
@@ -0,0 +1,213 @@
+/* sysdep.h -- handle host dependencies for the BFD library
+ Copyright (C) 1995-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#ifndef BFD_SYSDEP_H
+#define BFD_SYSDEP_H
+
+#ifdef PACKAGE
+#error sysdep.h must be included in lieu of config.h
+#endif
+
+#include "config.h"
+
+#include "ansidecl.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 STRING_WITH_STRINGS
+#include <string.h>
+#include <strings.h>
+#else
+#ifdef HAVE_STRING_H
+#include <string.h>
+#else
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#else
+extern char *strchr ();
+extern char *strrchr ();
+#endif
+#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 HAVE_SYS_RESOURCE_H
+#include <sys/resource.h>
+#endif /* HAVE_SYS_RESOURCE_H */
+
+#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
+
+#include "filenames.h"
+
+#if !HAVE_DECL_FFS
+extern int ffs (int);
+#endif
+
+#if !HAVE_DECL_FREE
+extern void free ();
+#endif
+
+#if !HAVE_DECL_GETENV
+extern char *getenv ();
+#endif
+
+#if !HAVE_DECL_MALLOC
+extern PTR malloc ();
+#endif
+
+#if !HAVE_DECL_REALLOC
+extern PTR realloc ();
+#endif
+
+#if !HAVE_DECL_STPCPY
+extern char *stpcpy (char *__dest, const char *__src);
+#endif
+
+#if !HAVE_DECL_STRSTR
+extern char *strstr ();
+#endif
+
+#ifdef HAVE_FTELLO
+#if !HAVE_DECL_FTELLO
+extern off_t ftello (FILE *stream);
+#endif
+#endif
+
+#ifdef HAVE_FTELLO64
+#if !HAVE_DECL_FTELLO64
+extern off64_t ftello64 (FILE *stream);
+#endif
+#endif
+
+#ifdef HAVE_FSEEKO
+#if !HAVE_DECL_FSEEKO
+extern int fseeko (FILE *stream, off_t offset, int whence);
+#endif
+#endif
+
+#ifdef HAVE_FSEEKO64
+#if !HAVE_DECL_FSEEKO64
+extern int fseeko64 (FILE *stream, off64_t offset, int whence);
+#endif
+#endif
+
+#if !HAVE_DECL_STRNLEN
+size_t strnlen (const char *, size_t);
+#endif
+
+/* Define offsetof for those systems which lack it */
+
+#ifndef offsetof
+#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
+#endif
+
+#ifdef ENABLE_NLS
+#include <libintl.h>
+/* Note the use of dgetext() and PACKAGE here, rather than gettext().
+
+ This is because the code in this directory is used to build a library which
+ will be linked with code in other directories to form programs. We want to
+ maintain a seperate translation file for this directory however, rather
+ than being forced to merge it with that of any program linked to libbfd.
+ This is a library, so it cannot depend on the catalog currently loaded.
+
+ In order to do this, we have to make sure that when we extract messages we
+ use the OPCODES domain rather than the domain of the program that included
+ the bfd library, (eg OBJDUMP). Hence we use dgettext (PACKAGE, String)
+ and define PACKAGE to be 'bfd'. (See the code in configure). */
+#define _(String) dgettext (PACKAGE, String)
+#ifdef gettext_noop
+#define N_(String) gettext_noop (String)
+#else
+#define N_(String) (String)
+#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 */
+# 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 0000000..8323e92
--- /dev/null
+++ b/bfd/targets.c
@@ -0,0 +1,1814 @@
+/* Generic target-file-type support for the BFD library.
+ Copyright (C) 1990-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+#include "fnmatch.h"
+
+/*
+ It's okay to see some:
+#if 0
+ directives in this source file, as targets.c uses them to exclude
+ certain BFD vectors. This comment is specially formatted to catch
+ users who grep for ^#if 0, so please keep it this way!
+*/
+
+/*
+SECTION
+ Targets
+
+DESCRIPTION
+ Each port of BFD to a different machine requires 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_xcoff_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_verilog_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,
+. bfd_target_mmo_flavour,
+. bfd_target_mach_o_flavour,
+. bfd_target_pef_flavour,
+. bfd_target_pef_xlib_flavour,
+. bfd_target_sym_flavour
+.};
+.
+.enum bfd_endian { BFD_ENDIAN_BIG, BFD_ENDIAN_LITTLE, BFD_ENDIAN_UNKNOWN };
+.
+.{* Forward declaration. *}
+.typedef struct bfd_link_info _bfd_link_info;
+.
+.{* Forward declaration. *}
+.typedef struct flag_info flag_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 char ar_max_namelen;
+.
+. {* How well this target matches, used to select between various
+. possible targets when more than one target matches. *}
+. unsigned char match_priority;
+.
+. {* Entries for byte swapping for data. These are different from the
+. other entry points, since they don't take a BFD as the first argument.
+. Certain other handlers could do the same. *}
+. bfd_uint64_t (*bfd_getx64) (const void *);
+. bfd_int64_t (*bfd_getx_signed_64) (const void *);
+. void (*bfd_putx64) (bfd_uint64_t, void *);
+. bfd_vma (*bfd_getx32) (const void *);
+. bfd_signed_vma (*bfd_getx_signed_32) (const void *);
+. void (*bfd_putx32) (bfd_vma, void *);
+. bfd_vma (*bfd_getx16) (const void *);
+. bfd_signed_vma (*bfd_getx_signed_16) (const void *);
+. void (*bfd_putx16) (bfd_vma, void *);
+.
+. {* Byte swapping for the headers. *}
+. bfd_uint64_t (*bfd_h_getx64) (const void *);
+. bfd_int64_t (*bfd_h_getx_signed_64) (const void *);
+. void (*bfd_h_putx64) (bfd_uint64_t, void *);
+. bfd_vma (*bfd_h_getx32) (const void *);
+. bfd_signed_vma (*bfd_h_getx_signed_32) (const void *);
+. void (*bfd_h_putx32) (bfd_vma, void *);
+. bfd_vma (*bfd_h_getx16) (const void *);
+. bfd_signed_vma (*bfd_h_getx_signed_16) (const void *);
+. void (*bfd_h_putx16) (bfd_vma, void *);
+.
+. {* 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]) (bfd *);
+.
+. {* Set the format of a file being written. *}
+. bfd_boolean (*_bfd_set_format[bfd_type_end]) (bfd *);
+.
+. {* Write cached information into a file being written, at <<bfd_close>>. *}
+. bfd_boolean (*_bfd_write_contents[bfd_type_end]) (bfd *);
+.
+The general target vector. These vectors are initialized using the
+BFD_JUMP_TABLE macros.
+.
+. {* Generic entry points. *}
+.#define BFD_JUMP_TABLE_GENERIC(NAME) \
+. NAME##_close_and_cleanup, \
+. NAME##_bfd_free_cached_info, \
+. NAME##_new_section_hook, \
+. NAME##_get_section_contents, \
+. NAME##_get_section_contents_in_window
+.
+. {* Called when the BFD is being closed to do any necessary cleanup. *}
+. bfd_boolean (*_close_and_cleanup) (bfd *);
+. {* Ask the BFD to free all cached information. *}
+. bfd_boolean (*_bfd_free_cached_info) (bfd *);
+. {* Called when a new section is created. *}
+. bfd_boolean (*_new_section_hook) (bfd *, sec_ptr);
+. {* Read the contents of a section. *}
+. bfd_boolean (*_bfd_get_section_contents)
+. (bfd *, sec_ptr, void *, file_ptr, bfd_size_type);
+. bfd_boolean (*_bfd_get_section_contents_in_window)
+. (bfd *, sec_ptr, bfd_window *, file_ptr, bfd_size_type);
+.
+. {* Entry points to copy private data. *}
+.#define BFD_JUMP_TABLE_COPY(NAME) \
+. NAME##_bfd_copy_private_bfd_data, \
+. NAME##_bfd_merge_private_bfd_data, \
+. _bfd_generic_init_private_section_data, \
+. NAME##_bfd_copy_private_section_data, \
+. NAME##_bfd_copy_private_symbol_data, \
+. NAME##_bfd_copy_private_header_data, \
+. NAME##_bfd_set_private_flags, \
+. NAME##_bfd_print_private_bfd_data
+.
+. {* Called to copy BFD general private data from one object file
+. to another. *}
+. bfd_boolean (*_bfd_copy_private_bfd_data) (bfd *, bfd *);
+. {* Called to merge BFD general private data from one object file
+. to a common output file when linking. *}
+. bfd_boolean (*_bfd_merge_private_bfd_data) (bfd *, bfd *);
+. {* Called to initialize BFD private section data from one object file
+. to another. *}
+.#define bfd_init_private_section_data(ibfd, isec, obfd, osec, link_info) \
+. BFD_SEND (obfd, _bfd_init_private_section_data, (ibfd, isec, obfd, osec, link_info))
+. bfd_boolean (*_bfd_init_private_section_data)
+. (bfd *, sec_ptr, bfd *, sec_ptr, struct bfd_link_info *);
+. {* Called to copy BFD private section data from one object file
+. to another. *}
+. bfd_boolean (*_bfd_copy_private_section_data)
+. (bfd *, sec_ptr, bfd *, sec_ptr);
+. {* Called to copy BFD private symbol data from one symbol
+. to another. *}
+. bfd_boolean (*_bfd_copy_private_symbol_data)
+. (bfd *, asymbol *, bfd *, asymbol *);
+. {* Called to copy BFD private header data from one object file
+. to another. *}
+. bfd_boolean (*_bfd_copy_private_header_data)
+. (bfd *, bfd *);
+. {* Called to set private backend flags. *}
+. bfd_boolean (*_bfd_set_private_flags) (bfd *, flagword);
+.
+. {* Called to print private BFD data. *}
+. bfd_boolean (*_bfd_print_private_bfd_data) (bfd *, void *);
+.
+. {* Core file entry points. *}
+.#define BFD_JUMP_TABLE_CORE(NAME) \
+. NAME##_core_file_failing_command, \
+. NAME##_core_file_failing_signal, \
+. NAME##_core_file_matches_executable_p, \
+. NAME##_core_file_pid
+.
+. char * (*_core_file_failing_command) (bfd *);
+. int (*_core_file_failing_signal) (bfd *);
+. bfd_boolean (*_core_file_matches_executable_p) (bfd *, bfd *);
+. int (*_core_file_pid) (bfd *);
+.
+. {* Archive entry points. *}
+.#define BFD_JUMP_TABLE_ARCHIVE(NAME) \
+. NAME##_slurp_armap, \
+. NAME##_slurp_extended_name_table, \
+. NAME##_construct_extended_name_table, \
+. NAME##_truncate_arname, \
+. NAME##_write_armap, \
+. NAME##_read_ar_hdr, \
+. NAME##_write_ar_hdr, \
+. NAME##_openr_next_archived_file, \
+. NAME##_get_elt_at_index, \
+. NAME##_generic_stat_arch_elt, \
+. NAME##_update_armap_timestamp
+.
+. bfd_boolean (*_bfd_slurp_armap) (bfd *);
+. bfd_boolean (*_bfd_slurp_extended_name_table) (bfd *);
+. bfd_boolean (*_bfd_construct_extended_name_table)
+. (bfd *, char **, bfd_size_type *, const char **);
+. void (*_bfd_truncate_arname) (bfd *, const char *, char *);
+. bfd_boolean (*write_armap)
+. (bfd *, unsigned int, struct orl *, unsigned int, int);
+. void * (*_bfd_read_ar_hdr_fn) (bfd *);
+. bfd_boolean (*_bfd_write_ar_hdr_fn) (bfd *, bfd *);
+. bfd * (*openr_next_archived_file) (bfd *, bfd *);
+.#define bfd_get_elt_at_index(b,i) BFD_SEND (b, _bfd_get_elt_at_index, (b,i))
+. bfd * (*_bfd_get_elt_at_index) (bfd *, symindex);
+. int (*_bfd_stat_arch_elt) (bfd *, struct stat *);
+. bfd_boolean (*_bfd_update_armap_timestamp) (bfd *);
+.
+. {* Entry points used for symbols. *}
+.#define BFD_JUMP_TABLE_SYMBOLS(NAME) \
+. NAME##_get_symtab_upper_bound, \
+. NAME##_canonicalize_symtab, \
+. NAME##_make_empty_symbol, \
+. NAME##_print_symbol, \
+. NAME##_get_symbol_info, \
+. NAME##_bfd_is_local_label_name, \
+. NAME##_bfd_is_target_special_symbol, \
+. NAME##_get_lineno, \
+. NAME##_find_nearest_line, \
+. NAME##_find_line, \
+. NAME##_find_inliner_info, \
+. NAME##_bfd_make_debug_symbol, \
+. NAME##_read_minisymbols, \
+. NAME##_minisymbol_to_symbol
+.
+. long (*_bfd_get_symtab_upper_bound) (bfd *);
+. long (*_bfd_canonicalize_symtab)
+. (bfd *, struct bfd_symbol **);
+. struct bfd_symbol *
+. (*_bfd_make_empty_symbol) (bfd *);
+. void (*_bfd_print_symbol)
+. (bfd *, void *, struct bfd_symbol *, 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)
+. (bfd *, struct bfd_symbol *, symbol_info *);
+.#define bfd_get_symbol_info(b,p,e) BFD_SEND (b, _bfd_get_symbol_info, (b,p,e))
+. bfd_boolean (*_bfd_is_local_label_name) (bfd *, const char *);
+. bfd_boolean (*_bfd_is_target_special_symbol) (bfd *, asymbol *);
+. alent * (*_get_lineno) (bfd *, struct bfd_symbol *);
+. bfd_boolean (*_bfd_find_nearest_line)
+. (bfd *, struct bfd_symbol **, struct bfd_section *, bfd_vma,
+. const char **, const char **, unsigned int *, unsigned int *);
+. bfd_boolean (*_bfd_find_line)
+. (bfd *, struct bfd_symbol **, struct bfd_symbol *,
+. const char **, unsigned int *);
+. bfd_boolean (*_bfd_find_inliner_info)
+. (bfd *, const char **, const char **, unsigned int *);
+. {* 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)
+. (bfd *, void *, unsigned long size);
+.#define bfd_read_minisymbols(b, d, m, s) \
+. BFD_SEND (b, _read_minisymbols, (b, d, m, s))
+. long (*_read_minisymbols)
+. (bfd *, bfd_boolean, void **, 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)
+. (bfd *, bfd_boolean, const void *, asymbol *);
+.
+. {* Routines for relocs. *}
+.#define BFD_JUMP_TABLE_RELOCS(NAME) \
+. NAME##_get_reloc_upper_bound, \
+. NAME##_canonicalize_reloc, \
+. NAME##_bfd_reloc_type_lookup, \
+. NAME##_bfd_reloc_name_lookup
+.
+. long (*_get_reloc_upper_bound) (bfd *, sec_ptr);
+. long (*_bfd_canonicalize_reloc)
+. (bfd *, sec_ptr, arelent **, struct bfd_symbol **);
+. {* See documentation on reloc types. *}
+. reloc_howto_type *
+. (*reloc_type_lookup) (bfd *, bfd_reloc_code_real_type);
+. reloc_howto_type *
+. (*reloc_name_lookup) (bfd *, const char *);
+.
+.
+. {* Routines used when writing an object file. *}
+.#define BFD_JUMP_TABLE_WRITE(NAME) \
+. NAME##_set_arch_mach, \
+. NAME##_set_section_contents
+.
+. bfd_boolean (*_bfd_set_arch_mach)
+. (bfd *, enum bfd_architecture, unsigned long);
+. bfd_boolean (*_bfd_set_section_contents)
+. (bfd *, sec_ptr, const void *, file_ptr, bfd_size_type);
+.
+. {* Routines used by the linker. *}
+.#define BFD_JUMP_TABLE_LINK(NAME) \
+. NAME##_sizeof_headers, \
+. NAME##_bfd_get_relocated_section_contents, \
+. NAME##_bfd_relax_section, \
+. NAME##_bfd_link_hash_table_create, \
+. NAME##_bfd_link_add_symbols, \
+. NAME##_bfd_link_just_syms, \
+. NAME##_bfd_copy_link_hash_symbol_type, \
+. NAME##_bfd_final_link, \
+. NAME##_bfd_link_split_section, \
+. NAME##_bfd_gc_sections, \
+. NAME##_bfd_lookup_section_flags, \
+. NAME##_bfd_merge_sections, \
+. NAME##_bfd_is_group_section, \
+. NAME##_bfd_discard_group, \
+. NAME##_section_already_linked, \
+. NAME##_bfd_define_common_symbol
+.
+. int (*_bfd_sizeof_headers) (bfd *, struct bfd_link_info *);
+. bfd_byte * (*_bfd_get_relocated_section_contents)
+. (bfd *, struct bfd_link_info *, struct bfd_link_order *,
+. bfd_byte *, bfd_boolean, struct bfd_symbol **);
+.
+. bfd_boolean (*_bfd_relax_section)
+. (bfd *, struct bfd_section *, struct bfd_link_info *, bfd_boolean *);
+.
+. {* 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) (bfd *);
+.
+. {* Add symbols from this object file into the hash table. *}
+. bfd_boolean (*_bfd_link_add_symbols) (bfd *, struct bfd_link_info *);
+.
+. {* Indicate that we are only retrieving symbol values from this section. *}
+. void (*_bfd_link_just_syms) (asection *, struct bfd_link_info *);
+.
+. {* Copy the symbol type and other attributes for a linker script
+. assignment of one symbol to another. *}
+.#define bfd_copy_link_hash_symbol_type(b, t, f) \
+. BFD_SEND (b, _bfd_copy_link_hash_symbol_type, (b, t, f))
+. void (*_bfd_copy_link_hash_symbol_type)
+. (bfd *, struct bfd_link_hash_entry *, struct bfd_link_hash_entry *);
+.
+. {* Do a link based on the link_order structures attached to each
+. section of the BFD. *}
+. bfd_boolean (*_bfd_final_link) (bfd *, struct bfd_link_info *);
+.
+. {* Should this section be split up into smaller pieces during linking. *}
+. bfd_boolean (*_bfd_link_split_section) (bfd *, struct bfd_section *);
+.
+. {* Remove sections that are not referenced from the output. *}
+. bfd_boolean (*_bfd_gc_sections) (bfd *, struct bfd_link_info *);
+.
+. {* Sets the bitmask of allowed and disallowed section flags. *}
+. bfd_boolean (*_bfd_lookup_section_flags) (struct bfd_link_info *,
+. struct flag_info *,
+. asection *);
+.
+. {* Attempt to merge SEC_MERGE sections. *}
+. bfd_boolean (*_bfd_merge_sections) (bfd *, struct bfd_link_info *);
+.
+. {* Is this section a member of a group? *}
+. bfd_boolean (*_bfd_is_group_section) (bfd *, const struct bfd_section *);
+.
+. {* Discard members of a group. *}
+. bfd_boolean (*_bfd_discard_group) (bfd *, struct bfd_section *);
+.
+. {* Check if SEC has been already linked during a reloceatable or
+. final link. *}
+. bfd_boolean (*_section_already_linked) (bfd *, asection *,
+. struct bfd_link_info *);
+.
+. {* Define a common symbol. *}
+. bfd_boolean (*_bfd_define_common_symbol) (bfd *, struct bfd_link_info *,
+. struct bfd_link_hash_entry *);
+.
+. {* Routines to handle dynamic symbols and relocs. *}
+.#define BFD_JUMP_TABLE_DYNAMIC(NAME) \
+. NAME##_get_dynamic_symtab_upper_bound, \
+. NAME##_canonicalize_dynamic_symtab, \
+. NAME##_get_synthetic_symtab, \
+. NAME##_get_dynamic_reloc_upper_bound, \
+. NAME##_canonicalize_dynamic_reloc
+.
+. {* Get the amount of memory required to hold the dynamic symbols. *}
+. long (*_bfd_get_dynamic_symtab_upper_bound) (bfd *);
+. {* Read in the dynamic symbols. *}
+. long (*_bfd_canonicalize_dynamic_symtab)
+. (bfd *, struct bfd_symbol **);
+. {* Create synthetized symbols. *}
+. long (*_bfd_get_synthetic_symtab)
+. (bfd *, long, struct bfd_symbol **, long, struct bfd_symbol **,
+. struct bfd_symbol **);
+. {* Get the amount of memory required to hold the dynamic relocs. *}
+. long (*_bfd_get_dynamic_reloc_upper_bound) (bfd *);
+. {* Read in the dynamic relocs. *}
+. long (*_bfd_canonicalize_dynamic_reloc)
+. (bfd *, arelent **, struct bfd_symbol **);
+.
+
+A pointer to an alternative bfd_target in case the current one is not
+satisfactory. This can happen when the target cpu supports both big
+and little endian code, and target chosen by the linker has the wrong
+endianness. The function open_output() in ld/ldlang.c uses this field
+to find an alternative output format that is suitable.
+
+. {* Opposite endian version of this target. *}
+. const struct bfd_target * alternative_target;
+.
+
+. {* Data for use by back-end routines, which isn't
+. generic enough to belong in this structure. *}
+. const void *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 aarch64_elf32_be_vec;
+extern const bfd_target aarch64_elf32_le_vec;
+extern const bfd_target aarch64_elf64_be_vec;
+extern const bfd_target aarch64_elf64_le_vec;
+extern const bfd_target alpha_ecoff_le_vec;
+extern const bfd_target alpha_elf64_vec;
+extern const bfd_target alpha_elf64_fbsd_vec;
+extern const bfd_target alpha_nlm32_vec;
+extern const bfd_target alpha_vms_vec;
+extern const bfd_target alpha_vms_lib_txt_vec;
+extern const bfd_target am33_elf32_linux_vec;
+extern const bfd_target aout0_be_vec;
+extern const bfd_target aout64_vec;
+extern const bfd_target aout_vec;
+extern const bfd_target aout_adobe_vec;
+extern const bfd_target arc_elf32_be_vec;
+extern const bfd_target arc_elf32_le_vec;
+extern const bfd_target arm_aout_be_vec;
+extern const bfd_target arm_aout_le_vec;
+extern const bfd_target arm_aout_nbsd_vec;
+extern const bfd_target arm_aout_riscix_vec;
+extern const bfd_target arm_coff_be_vec;
+extern const bfd_target arm_coff_le_vec;
+extern const bfd_target arm_elf32_be_vec;
+extern const bfd_target arm_elf32_le_vec;
+extern const bfd_target arm_elf32_nacl_be_vec;
+extern const bfd_target arm_elf32_nacl_le_vec;
+extern const bfd_target arm_elf32_symbian_be_vec;
+extern const bfd_target arm_elf32_symbian_le_vec;
+extern const bfd_target arm_elf32_vxworks_be_vec;
+extern const bfd_target arm_elf32_vxworks_le_vec;
+extern const bfd_target arm_pe_be_vec;
+extern const bfd_target arm_pe_le_vec;
+extern const bfd_target arm_pe_epoc_be_vec;
+extern const bfd_target arm_pe_epoc_le_vec;
+extern const bfd_target arm_pe_wince_be_vec;
+extern const bfd_target arm_pe_wince_le_vec;
+extern const bfd_target arm_pei_be_vec;
+extern const bfd_target arm_pei_le_vec;
+extern const bfd_target arm_pei_epoc_be_vec;
+extern const bfd_target arm_pei_epoc_le_vec;
+extern const bfd_target arm_pei_wince_be_vec;
+extern const bfd_target arm_pei_wince_le_vec;
+extern const bfd_target avr_elf32_vec;
+extern const bfd_target bfin_elf32_vec;
+extern const bfd_target bfin_elf32_fdpic_vec;
+extern const bfd_target bout_be_vec;
+extern const bfd_target bout_le_vec;
+extern const bfd_target cr16_elf32_vec;
+extern const bfd_target cr16c_elf32_vec;
+extern const bfd_target cris_aout_vec;
+extern const bfd_target cris_elf32_vec;
+extern const bfd_target cris_elf32_us_vec;
+extern const bfd_target crx_elf32_vec;
+extern const bfd_target d10v_elf32_vec;
+extern const bfd_target d30v_elf32_vec;
+extern const bfd_target dlx_elf32_be_vec;
+extern const bfd_target elf32_be_vec;
+extern const bfd_target elf32_le_vec;
+extern const bfd_target elf64_be_vec;
+extern const bfd_target elf64_le_vec;
+extern const bfd_target epiphany_elf32_vec;
+extern const bfd_target fr30_elf32_vec;
+extern const bfd_target frv_elf32_vec;
+extern const bfd_target frv_elf32_fdpic_vec;
+extern const bfd_target h8300_coff_vec;
+extern const bfd_target h8300_elf32_vec;
+extern const bfd_target h8500_coff_vec;
+extern const bfd_target hppa_elf32_vec;
+extern const bfd_target hppa_elf32_linux_vec;
+extern const bfd_target hppa_elf32_nbsd_vec;
+extern const bfd_target hppa_elf64_vec;
+extern const bfd_target hppa_elf64_linux_vec;
+extern const bfd_target hppa_som_vec;
+extern const bfd_target i370_elf32_vec;
+extern const bfd_target i386_aout_vec;
+extern const bfd_target i386_aout_bsd_vec;
+extern const bfd_target i386_aout_dynix_vec;
+extern const bfd_target i386_aout_fbsd_vec;
+extern const bfd_target i386_aout_linux_vec;
+extern const bfd_target i386_aout_lynx_vec;
+extern const bfd_target i386_aout_mach3_vec;
+extern const bfd_target i386_aout_nbsd_vec;
+extern const bfd_target i386_aout_os9k_vec;
+extern const bfd_target i386_coff_vec;
+extern const bfd_target i386_coff_go32_vec;
+extern const bfd_target i386_coff_go32stubbed_vec;
+extern const bfd_target i386_coff_lynx_vec;
+extern const bfd_target i386_elf32_vec;
+extern const bfd_target i386_elf32_fbsd_vec;
+extern const bfd_target i386_elf32_nacl_vec;
+extern const bfd_target i386_elf32_sol2_vec;
+extern const bfd_target i386_elf32_vxworks_vec;
+extern const bfd_target i386_mach_o_vec;
+extern const bfd_target i386_msdos_vec;
+extern const bfd_target i386_nlm32_vec;
+extern const bfd_target i386_pe_vec;
+extern const bfd_target i386_pei_vec;
+extern const bfd_target i860_coff_vec;
+extern const bfd_target i860_elf32_vec;
+extern const bfd_target i860_elf32_le_vec;
+extern const bfd_target i960_elf32_vec;
+extern const bfd_target ia64_elf32_be_vec;
+extern const bfd_target ia64_elf32_hpux_be_vec;
+extern const bfd_target ia64_elf64_be_vec;
+extern const bfd_target ia64_elf64_le_vec;
+extern const bfd_target ia64_elf64_hpux_be_vec;
+extern const bfd_target ia64_elf64_vms_vec;
+extern const bfd_target ia64_pei_vec;
+extern const bfd_target icoff_be_vec;
+extern const bfd_target icoff_le_vec;
+extern const bfd_target ieee_vec;
+extern const bfd_target ip2k_elf32_vec;
+extern const bfd_target iq2000_elf32_vec;
+extern const bfd_target k1om_elf64_vec;
+extern const bfd_target k1om_elf64_fbsd_vec;
+extern const bfd_target l1om_elf64_vec;
+extern const bfd_target l1om_elf64_fbsd_vec;
+extern const bfd_target lm32_elf32_vec;
+extern const bfd_target lm32_elf32_fdpic_vec;
+extern const bfd_target m32c_elf32_vec;
+extern const bfd_target m32r_elf32_vec;
+extern const bfd_target m32r_elf32_le_vec;
+extern const bfd_target m32r_elf32_linux_vec;
+extern const bfd_target m32r_elf32_linux_le_vec;
+extern const bfd_target m68hc11_elf32_vec;
+extern const bfd_target m68hc12_elf32_vec;
+extern const bfd_target m68k_aout_4knbsd_vec;
+extern const bfd_target m68k_aout_hp300bsd_vec;
+extern const bfd_target m68k_aout_hp300hpux_vec;
+extern const bfd_target m68k_aout_linux_vec;
+extern const bfd_target m68k_aout_nbsd_vec;
+extern const bfd_target m68k_aout_newsos3_vec;
+extern const bfd_target m68k_coff_vec;
+extern const bfd_target m68k_coff_apollo_vec;
+extern const bfd_target m68k_coff_aux_vec;
+extern const bfd_target m68k_coff_sysv_vec;
+extern const bfd_target m68k_coff_un_vec;
+extern const bfd_target m68k_elf32_vec;
+extern const bfd_target m68k_versados_vec;
+extern const bfd_target m88k_aout_mach3_vec;
+extern const bfd_target m88k_aout_obsd_vec;
+extern const bfd_target m88k_coff_bcs_vec;
+extern const bfd_target m88k_elf32_vec;
+extern const bfd_target mach_o_be_vec;
+extern const bfd_target mach_o_le_vec;
+extern const bfd_target mach_o_fat_vec;
+extern const bfd_target mcore_elf32_be_vec;
+extern const bfd_target mcore_elf32_le_vec;
+extern const bfd_target mcore_pe_be_vec;
+extern const bfd_target mcore_pe_le_vec;
+extern const bfd_target mcore_pei_be_vec;
+extern const bfd_target mcore_pei_le_vec;
+extern const bfd_target mep_elf32_vec;
+extern const bfd_target mep_elf32_le_vec;
+extern const bfd_target metag_elf32_vec;
+extern const bfd_target microblaze_elf32_vec;
+extern const bfd_target microblaze_elf32_le_vec;
+extern const bfd_target mips_aout_be_vec;
+extern const bfd_target mips_aout_le_vec;
+extern const bfd_target mips_ecoff_be_vec;
+extern const bfd_target mips_ecoff_le_vec;
+extern const bfd_target mips_ecoff_bele_vec;
+extern const bfd_target mips_elf32_be_vec;
+extern const bfd_target mips_elf32_le_vec;
+extern const bfd_target mips_elf32_n_be_vec;
+extern const bfd_target mips_elf32_n_le_vec;
+extern const bfd_target mips_elf32_ntrad_be_vec;
+extern const bfd_target mips_elf32_ntrad_le_vec;
+extern const bfd_target mips_elf32_ntradfbsd_be_vec;
+extern const bfd_target mips_elf32_ntradfbsd_le_vec;
+extern const bfd_target mips_elf32_trad_be_vec;
+extern const bfd_target mips_elf32_trad_le_vec;
+extern const bfd_target mips_elf32_tradfbsd_be_vec;
+extern const bfd_target mips_elf32_tradfbsd_le_vec;
+extern const bfd_target mips_elf32_vxworks_be_vec;
+extern const bfd_target mips_elf32_vxworks_le_vec;
+extern const bfd_target mips_elf64_be_vec;
+extern const bfd_target mips_elf64_le_vec;
+extern const bfd_target mips_elf64_trad_be_vec;
+extern const bfd_target mips_elf64_trad_le_vec;
+extern const bfd_target mips_elf64_tradfbsd_be_vec;
+extern const bfd_target mips_elf64_tradfbsd_le_vec;
+extern const bfd_target mips_pe_le_vec;
+extern const bfd_target mips_pei_le_vec;
+extern const bfd_target mmix_elf64_vec;
+extern const bfd_target mmix_mmo_vec;
+extern const bfd_target mn10200_elf32_vec;
+extern const bfd_target mn10300_elf32_vec;
+extern const bfd_target moxie_elf32_be_vec;
+extern const bfd_target moxie_elf32_le_vec;
+extern const bfd_target msp430_elf32_vec;
+extern const bfd_target msp430_elf32_ti_vec;
+extern const bfd_target mt_elf32_vec;
+extern const bfd_target nds32_elf32_be_vec;
+extern const bfd_target nds32_elf32_le_vec;
+extern const bfd_target nds32_elf32_linux_be_vec;
+extern const bfd_target nds32_elf32_linux_le_vec;
+extern const bfd_target nios2_elf32_be_vec;
+extern const bfd_target nios2_elf32_le_vec;
+extern const bfd_target ns32k_aout_pc532mach_vec;
+extern const bfd_target ns32k_aout_pc532nbsd_vec;
+extern const bfd_target oasys_vec;
+extern const bfd_target or1k_elf32_vec;
+extern const bfd_target pdp11_aout_vec;
+extern const bfd_target pef_vec;
+extern const bfd_target pef_xlib_vec;
+extern const bfd_target pj_elf32_vec;
+extern const bfd_target pj_elf32_le_vec;
+extern const bfd_target plugin_vec;
+extern const bfd_target powerpc_boot_vec;
+extern const bfd_target powerpc_elf32_vec;
+extern const bfd_target powerpc_elf32_le_vec;
+extern const bfd_target powerpc_elf32_fbsd_vec;
+extern const bfd_target powerpc_elf32_vxworks_vec;
+extern const bfd_target powerpc_elf64_vec;
+extern const bfd_target powerpc_elf64_le_vec;
+extern const bfd_target powerpc_elf64_fbsd_vec;
+extern const bfd_target powerpc_nlm32_vec;
+extern const bfd_target powerpc_pe_vec;
+extern const bfd_target powerpc_pe_le_vec;
+extern const bfd_target powerpc_pei_vec;
+extern const bfd_target powerpc_pei_le_vec;
+extern const bfd_target powerpc_xcoff_vec;
+extern const bfd_target rl78_elf32_vec;
+extern const bfd_target rs6000_xcoff64_vec;
+extern const bfd_target rs6000_xcoff64_aix_vec;
+extern const bfd_target rs6000_xcoff_vec;
+extern const bfd_target rx_elf32_be_vec;
+extern const bfd_target rx_elf32_be_ns_vec;
+extern const bfd_target rx_elf32_le_vec;
+extern const bfd_target s390_elf32_vec;
+extern const bfd_target s390_elf64_vec;
+extern const bfd_target score_elf32_be_vec;
+extern const bfd_target score_elf32_le_vec;
+extern const bfd_target sh64_elf32_vec;
+extern const bfd_target sh64_elf32_le_vec;
+extern const bfd_target sh64_elf32_linux_vec;
+extern const bfd_target sh64_elf32_linux_be_vec;
+extern const bfd_target sh64_elf32_nbsd_vec;
+extern const bfd_target sh64_elf32_nbsd_le_vec;
+extern const bfd_target sh64_elf64_vec;
+extern const bfd_target sh64_elf64_le_vec;
+extern const bfd_target sh64_elf64_linux_vec;
+extern const bfd_target sh64_elf64_linux_be_vec;
+extern const bfd_target sh64_elf64_nbsd_vec;
+extern const bfd_target sh64_elf64_nbsd_le_vec;
+extern const bfd_target sh_coff_vec;
+extern const bfd_target sh_coff_le_vec;
+extern const bfd_target sh_coff_small_vec;
+extern const bfd_target sh_coff_small_le_vec;
+extern const bfd_target sh_elf32_vec;
+extern const bfd_target sh_elf32_le_vec;
+extern const bfd_target sh_elf32_fdpic_be_vec;
+extern const bfd_target sh_elf32_fdpic_le_vec;
+extern const bfd_target sh_elf32_linux_vec;
+extern const bfd_target sh_elf32_linux_be_vec;
+extern const bfd_target sh_elf32_nbsd_vec;
+extern const bfd_target sh_elf32_nbsd_le_vec;
+extern const bfd_target sh_elf32_symbian_le_vec;
+extern const bfd_target sh_elf32_vxworks_vec;
+extern const bfd_target sh_elf32_vxworks_le_vec;
+extern const bfd_target sh_pe_le_vec;
+extern const bfd_target sh_pei_le_vec;
+extern const bfd_target sparc_aout_le_vec;
+extern const bfd_target sparc_aout_linux_vec;
+extern const bfd_target sparc_aout_lynx_vec;
+extern const bfd_target sparc_aout_nbsd_vec;
+extern const bfd_target sparc_aout_sunos_be_vec;
+extern const bfd_target sparc_coff_vec;
+extern const bfd_target sparc_coff_lynx_vec;
+extern const bfd_target sparc_elf32_vec;
+extern const bfd_target sparc_elf32_sol2_vec;
+extern const bfd_target sparc_elf32_vxworks_vec;
+extern const bfd_target sparc_elf64_vec;
+extern const bfd_target sparc_elf64_fbsd_vec;
+extern const bfd_target sparc_elf64_sol2_vec;
+extern const bfd_target sparc_nlm32_vec;
+extern const bfd_target spu_elf32_vec;
+extern const bfd_target sym_vec;
+extern const bfd_target tic30_aout_vec;
+extern const bfd_target tic30_coff_vec;
+extern const bfd_target tic4x_coff0_vec;
+extern const bfd_target tic4x_coff0_beh_vec;
+extern const bfd_target tic4x_coff1_vec;
+extern const bfd_target tic4x_coff1_beh_vec;
+extern const bfd_target tic4x_coff2_vec;
+extern const bfd_target tic4x_coff2_beh_vec;
+extern const bfd_target tic54x_coff0_vec;
+extern const bfd_target tic54x_coff0_beh_vec;
+extern const bfd_target tic54x_coff1_vec;
+extern const bfd_target tic54x_coff1_beh_vec;
+extern const bfd_target tic54x_coff2_vec;
+extern const bfd_target tic54x_coff2_beh_vec;
+extern const bfd_target tic6x_elf32_be_vec;
+extern const bfd_target tic6x_elf32_le_vec;
+extern const bfd_target tic6x_elf32_c6000_be_vec;
+extern const bfd_target tic6x_elf32_c6000_le_vec;
+extern const bfd_target tic6x_elf32_linux_be_vec;
+extern const bfd_target tic6x_elf32_linux_le_vec;
+extern const bfd_target tic80_coff_vec;
+extern const bfd_target tilegx_elf32_be_vec;
+extern const bfd_target tilegx_elf32_le_vec;
+extern const bfd_target tilegx_elf64_be_vec;
+extern const bfd_target tilegx_elf64_le_vec;
+extern const bfd_target tilepro_elf32_vec;
+extern const bfd_target v800_elf32_vec;
+extern const bfd_target v850_elf32_vec;
+extern const bfd_target vax_aout_1knbsd_vec;
+extern const bfd_target vax_aout_bsd_vec;
+extern const bfd_target vax_aout_nbsd_vec;
+extern const bfd_target vax_elf32_vec;
+extern const bfd_target w65_coff_vec;
+extern const bfd_target we32k_coff_vec;
+extern const bfd_target x86_64_coff_vec;
+extern const bfd_target x86_64_elf32_vec;
+extern const bfd_target x86_64_elf32_nacl_vec;
+extern const bfd_target x86_64_elf64_vec;
+extern const bfd_target x86_64_elf64_fbsd_vec;
+extern const bfd_target x86_64_elf64_nacl_vec;
+extern const bfd_target x86_64_elf64_sol2_vec;
+extern const bfd_target x86_64_mach_o_vec;
+extern const bfd_target x86_64_pe_vec;
+extern const bfd_target x86_64_pe_be_vec;
+extern const bfd_target x86_64_pei_vec;
+extern const bfd_target xc16x_elf32_vec;
+extern const bfd_target xgate_elf32_vec;
+extern const bfd_target xstormy16_elf32_vec;
+extern const bfd_target xtensa_elf32_be_vec;
+extern const bfd_target xtensa_elf32_le_vec;
+extern const bfd_target z80_coff_vec;
+extern const bfd_target z8k_coff_vec;
+
+/* These are always included. */
+extern const bfd_target srec_vec;
+extern const bfd_target symbolsrec_vec;
+extern const bfd_target verilog_vec;
+extern const bfd_target tekhex_vec;
+extern const bfd_target binary_vec;
+extern const bfd_target ihex_vec;
+
+/* All of the xvecs for core files. */
+extern const bfd_target core_aix386_vec;
+extern const bfd_target core_cisco_be_vec;
+extern const bfd_target core_cisco_le_vec;
+extern const bfd_target core_hppabsd_vec;
+extern const bfd_target core_hpux_vec;
+extern const bfd_target core_irix_vec;
+extern const bfd_target core_netbsd_vec;
+extern const bfd_target core_osf_vec;
+extern const bfd_target core_ptrace_vec;
+extern const bfd_target core_sco5_vec;
+extern const bfd_target core_trad_vec;
+
+static 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.ac.
+ Try to keep it in order when adding new targets, and
+ use a name of the form <cpu>_<format>_<other>_<endian>_vec.
+ Note that sorting is done as if _<endian>_vec wasn't present.
+ 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. */
+#ifdef BFD64
+ &aarch64_elf32_be_vec,
+ &aarch64_elf32_le_vec,
+ &aarch64_elf64_be_vec,
+ &aarch64_elf64_le_vec,
+#endif
+
+#ifdef BFD64
+ &alpha_ecoff_le_vec,
+ &alpha_elf64_vec,
+ &alpha_elf64_fbsd_vec,
+ &alpha_nlm32_vec,
+ &alpha_vms_vec,
+#endif
+ &alpha_vms_lib_txt_vec,
+
+ &am33_elf32_linux_vec,
+
+ &aout0_be_vec,
+#ifdef BFD64
+ &aout64_vec, /* Only compiled if host has long-long support. */
+#endif
+#if 0
+ /* Since a.out files lack decent magic numbers, no way to recognize
+ which kind of a.out file it is. */
+ &aout_vec,
+#endif
+ &aout_adobe_vec,
+
+ &arc_elf32_be_vec,
+ &arc_elf32_le_vec,
+
+#if 0
+ /* We have no way of distinguishing these from other a.out variants. */
+ &arm_aout_be_vec,
+ &arm_aout_le_vec,
+#endif
+ &arm_aout_nbsd_vec,
+#if 0
+ /* We have no way of distinguishing these from other a.out variants. */
+ &arm_aout_riscix_vec,
+#endif
+ &arm_coff_be_vec,
+ &arm_coff_le_vec,
+ &arm_elf32_be_vec,
+ &arm_elf32_le_vec,
+ &arm_elf32_symbian_be_vec,
+ &arm_elf32_symbian_le_vec,
+ &arm_elf32_vxworks_be_vec,
+ &arm_elf32_vxworks_le_vec,
+ &arm_pe_be_vec,
+ &arm_pe_le_vec,
+ &arm_pe_epoc_be_vec,
+ &arm_pe_epoc_le_vec,
+ &arm_pe_wince_be_vec,
+ &arm_pe_wince_le_vec,
+ &arm_pei_be_vec,
+ &arm_pei_le_vec,
+ &arm_pei_epoc_be_vec,
+ &arm_pei_epoc_le_vec,
+ &arm_pei_wince_be_vec,
+ &arm_pei_wince_le_vec,
+
+ &avr_elf32_vec,
+
+ &bfin_elf32_vec,
+ &bfin_elf32_fdpic_vec,
+
+ &bout_be_vec,
+ &bout_le_vec,
+
+ &cr16_elf32_vec,
+ &cr16c_elf32_vec,
+
+ &cris_aout_vec,
+ &cris_elf32_vec,
+ &cris_elf32_us_vec,
+
+ &crx_elf32_vec,
+
+ &d10v_elf32_vec,
+ &d30v_elf32_vec,
+
+ &dlx_elf32_be_vec,
+
+ /* 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. */
+ &elf32_be_vec,
+ &elf32_le_vec,
+#ifdef BFD64
+ &elf64_be_vec,
+ &elf64_le_vec,
+#endif
+
+ &epiphany_elf32_vec,
+
+ &fr30_elf32_vec,
+
+ &frv_elf32_vec,
+ &frv_elf32_fdpic_vec,
+
+ &h8300_coff_vec,
+ &h8300_elf32_vec,
+ &h8500_coff_vec,
+
+ &hppa_elf32_vec,
+ &hppa_elf32_linux_vec,
+ &hppa_elf32_nbsd_vec,
+#ifdef BFD64
+ &hppa_elf64_vec,
+ &hppa_elf64_linux_vec,
+#endif
+ &hppa_som_vec,
+
+ &i370_elf32_vec,
+
+ &i386_aout_vec,
+ &i386_aout_bsd_vec,
+#if 0
+ &i386_aout_dynix_vec,
+#endif
+ &i386_aout_fbsd_vec,
+#if 0
+ /* Since a.out files lack decent magic numbers, no way to recognize
+ which kind of a.out file it is. */
+ &i386_aout_linux_vec,
+#endif
+ &i386_aout_lynx_vec,
+#if 0
+ /* No distinguishing features for Mach 3 executables. */
+ &i386_aout_mach3_vec,
+#endif
+ &i386_aout_nbsd_vec,
+ &i386_aout_os9k_vec,
+ &i386_coff_vec,
+ &i386_coff_go32_vec,
+ &i386_coff_go32stubbed_vec,
+ &i386_coff_lynx_vec,
+ &i386_elf32_vec,
+ &i386_elf32_fbsd_vec,
+ &i386_elf32_nacl_vec,
+ &i386_elf32_sol2_vec,
+ &i386_elf32_vxworks_vec,
+ &i386_mach_o_vec,
+ &i386_msdos_vec,
+ &i386_nlm32_vec,
+ &i386_pe_vec,
+ &i386_pei_vec,
+
+ &i860_coff_vec,
+ &i860_elf32_vec,
+ &i860_elf32_le_vec,
+
+ &i960_elf32_vec,
+
+#ifdef BFD64
+#if 0
+ &ia64_elf32_be_vec,
+#endif
+ &ia64_elf32_hpux_be_vec,
+ &ia64_elf64_be_vec,
+ &ia64_elf64_le_vec,
+ &ia64_elf64_hpux_be_vec,
+ &ia64_elf64_vms_vec,
+ &ia64_pei_vec,
+#endif
+
+ &icoff_be_vec,
+ &icoff_le_vec,
+
+ &ieee_vec,
+
+ &ip2k_elf32_vec,
+ &iq2000_elf32_vec,
+
+#ifdef BFD64
+ &k1om_elf64_vec,
+ &k1om_elf64_fbsd_vec,
+ &l1om_elf64_vec,
+ &l1om_elf64_fbsd_vec,
+#endif
+
+ &lm32_elf32_vec,
+
+ &m32c_elf32_vec,
+
+ &m32r_elf32_vec,
+ &m32r_elf32_le_vec,
+ &m32r_elf32_linux_vec,
+ &m32r_elf32_linux_le_vec,
+
+ &m68hc11_elf32_vec,
+ &m68hc12_elf32_vec,
+
+#if 0
+ &m68k_aout_4knbsd_vec,
+ /* Clashes with sparc_aout_sunos_be_vec magic no. */
+ &m68k_aout_hp300bsd_vec,
+#endif
+ &m68k_aout_hp300hpux_vec,
+#if 0
+ /* Since a.out files lack decent magic numbers, no way to recognize
+ which kind of a.out file it is. */
+ &m68k_aout_linux_vec,
+#endif
+ &m68k_aout_nbsd_vec,
+ &m68k_aout_newsos3_vec,
+ &m68k_coff_vec,
+#if 0
+ &m68k_coff_apollo_vec,
+ &m68k_coff_aux_vec,
+#endif
+ &m68k_coff_sysv_vec,
+ &m68k_coff_un_vec,
+ &m68k_elf32_vec,
+ &m68k_versados_vec,
+
+ &m88k_aout_mach3_vec,
+ &m88k_aout_obsd_vec,
+ &m88k_coff_bcs_vec,
+ &m88k_elf32_vec,
+
+ &mach_o_be_vec,
+ &mach_o_le_vec,
+ &mach_o_fat_vec,
+
+ &mcore_elf32_be_vec,
+ &mcore_elf32_le_vec,
+ &mcore_pe_be_vec,
+ &mcore_pe_le_vec,
+ &mcore_pei_be_vec,
+ &mcore_pei_le_vec,
+
+ &mep_elf32_vec,
+
+ &metag_elf32_vec,
+
+ &microblaze_elf32_vec,
+
+#if 0
+ /* No one seems to use this. */
+ &mips_aout_be_vec,
+#endif
+ &mips_aout_le_vec,
+ &mips_ecoff_be_vec,
+ &mips_ecoff_le_vec,
+ &mips_ecoff_bele_vec,
+#ifdef BFD64
+ &mips_elf32_be_vec,
+ &mips_elf32_le_vec,
+ &mips_elf32_n_be_vec,
+ &mips_elf32_n_le_vec,
+ &mips_elf32_ntrad_be_vec,
+ &mips_elf32_ntrad_le_vec,
+ &mips_elf32_ntradfbsd_be_vec,
+ &mips_elf32_ntradfbsd_le_vec,
+ &mips_elf32_trad_be_vec,
+ &mips_elf32_trad_le_vec,
+ &mips_elf32_tradfbsd_be_vec,
+ &mips_elf32_tradfbsd_le_vec,
+ &mips_elf32_vxworks_be_vec,
+ &mips_elf32_vxworks_le_vec,
+ &mips_elf64_be_vec,
+ &mips_elf64_le_vec,
+ &mips_elf64_trad_be_vec,
+ &mips_elf64_trad_le_vec,
+ &mips_elf64_tradfbsd_be_vec,
+ &mips_elf64_tradfbsd_le_vec,
+#endif
+ &mips_pe_le_vec,
+ &mips_pei_le_vec,
+
+#ifdef BFD64
+ &mmix_elf64_vec,
+ &mmix_mmo_vec,
+#endif
+
+ &mn10200_elf32_vec,
+ &mn10300_elf32_vec,
+
+ &moxie_elf32_be_vec,
+ &moxie_elf32_le_vec,
+
+ &msp430_elf32_vec,
+ &msp430_elf32_ti_vec,
+
+ &mt_elf32_vec,
+
+ &nds32_elf32_be_vec,
+ &nds32_elf32_le_vec,
+ &nds32_elf32_linux_be_vec,
+ &nds32_elf32_linux_le_vec,
+
+ &nios2_elf32_be_vec,
+ &nios2_elf32_le_vec,
+
+ &ns32k_aout_pc532mach_vec,
+ &ns32k_aout_pc532nbsd_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
+
+ &or1k_elf32_vec,
+
+ &pdp11_aout_vec,
+
+ &pef_vec,
+ &pef_xlib_vec,
+
+ &pj_elf32_vec,
+ &pj_elf32_le_vec,
+
+#if BFD_SUPPORTS_PLUGINS
+ &plugin_vec,
+#endif
+
+ &powerpc_boot_vec,
+ &powerpc_elf32_vec,
+ &powerpc_elf32_le_vec,
+ &powerpc_elf32_fbsd_vec,
+ &powerpc_elf32_vxworks_vec,
+#ifdef BFD64
+ &powerpc_elf64_vec,
+ &powerpc_elf64_le_vec,
+ &powerpc_elf64_fbsd_vec,
+#endif
+ &powerpc_nlm32_vec,
+ &powerpc_pe_vec,
+ &powerpc_pe_le_vec,
+ &powerpc_pei_vec,
+ &powerpc_pei_le_vec,
+#if 0
+ /* This has the same magic number as RS/6000. */
+ &powerpc_xcoff_vec,
+#endif
+
+ &rl78_elf32_vec,
+
+#ifdef BFD64
+ &rs6000_xcoff64_vec,
+ &rs6000_xcoff64_aix_vec,
+#endif
+ &rs6000_xcoff_vec,
+
+ &rx_elf32_be_vec,
+ &rx_elf32_be_ns_vec,
+ &rx_elf32_le_vec,
+
+ &s390_elf32_vec,
+#ifdef BFD64
+ &s390_elf64_vec,
+#endif
+
+#ifdef BFD64
+ &score_elf32_be_vec,
+ &score_elf32_le_vec,
+#endif
+
+#ifdef BFD64
+ &sh64_elf32_vec,
+ &sh64_elf32_le_vec,
+ &sh64_elf32_linux_vec,
+ &sh64_elf32_linux_be_vec,
+ &sh64_elf32_nbsd_vec,
+ &sh64_elf32_nbsd_le_vec,
+ &sh64_elf64_vec,
+ &sh64_elf64_le_vec,
+ &sh64_elf64_linux_vec,
+ &sh64_elf64_linux_be_vec,
+ &sh64_elf64_nbsd_vec,
+ &sh64_elf64_nbsd_le_vec,
+#endif
+ &sh_coff_vec,
+ &sh_coff_le_vec,
+ &sh_coff_small_vec,
+ &sh_coff_small_le_vec,
+ &sh_elf32_vec,
+ &sh_elf32_le_vec,
+ &sh_elf32_fdpic_be_vec,
+ &sh_elf32_fdpic_le_vec,
+ &sh_elf32_linux_vec,
+ &sh_elf32_linux_be_vec,
+ &sh_elf32_nbsd_vec,
+ &sh_elf32_nbsd_le_vec,
+ &sh_elf32_symbian_le_vec,
+ &sh_elf32_vxworks_vec,
+ &sh_elf32_vxworks_le_vec,
+ &sh_pe_le_vec,
+ &sh_pei_le_vec,
+
+ &sparc_aout_le_vec,
+ &sparc_aout_linux_vec,
+ &sparc_aout_lynx_vec,
+ &sparc_aout_nbsd_vec,
+ &sparc_aout_sunos_be_vec,
+ &sparc_coff_vec,
+ &sparc_coff_lynx_vec,
+ &sparc_elf32_vec,
+ &sparc_elf32_sol2_vec,
+ &sparc_elf32_vxworks_vec,
+#ifdef BFD64
+ &sparc_elf64_vec,
+ &sparc_elf64_fbsd_vec,
+ &sparc_elf64_sol2_vec,
+#endif
+ &sparc_nlm32_vec,
+
+ &spu_elf32_vec,
+
+ &sym_vec,
+
+ &tic30_aout_vec,
+ &tic30_coff_vec,
+ &tic54x_coff0_beh_vec,
+ &tic54x_coff0_vec,
+ &tic54x_coff1_beh_vec,
+ &tic54x_coff1_vec,
+ &tic54x_coff2_beh_vec,
+ &tic54x_coff2_vec,
+ &tic6x_elf32_be_vec,
+ &tic6x_elf32_le_vec,
+ &tic80_coff_vec,
+
+ &tilegx_elf32_be_vec,
+ &tilegx_elf32_le_vec,
+#ifdef BFD64
+ &tilegx_elf64_be_vec,
+ &tilegx_elf64_le_vec,
+#endif
+ &tilepro_elf32_vec,
+
+ &v800_elf32_vec,
+ &v850_elf32_vec,
+
+ &vax_aout_1knbsd_vec,
+ &vax_aout_bsd_vec,
+ &vax_aout_nbsd_vec,
+ &vax_elf32_vec,
+
+ &w65_coff_vec,
+
+ &we32k_coff_vec,
+
+#ifdef BFD64
+ &x86_64_coff_vec,
+ &x86_64_elf32_vec,
+ &x86_64_elf32_nacl_vec,
+ &x86_64_elf64_vec,
+ &x86_64_elf64_fbsd_vec,
+ &x86_64_elf64_nacl_vec,
+ &x86_64_elf64_sol2_vec,
+ &x86_64_mach_o_vec,
+ &x86_64_pe_vec,
+ &x86_64_pe_be_vec,
+ &x86_64_pei_vec,
+#endif
+
+ &xc16x_elf32_vec,
+
+ &xgate_elf32_vec,
+
+ &xstormy16_elf32_vec,
+
+ &xtensa_elf32_be_vec,
+ &xtensa_elf32_le_vec,
+
+ &z80_coff_vec,
+
+ &z8k_coff_vec,
+#endif /* not SELECT_VECS */
+
+/* Always support S-records, for convenience. */
+ &srec_vec,
+ &symbolsrec_vec,
+/* And verilog. */
+ &verilog_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
+ &core_aix386_vec,
+#endif
+#if 0
+ /* 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. */
+ &core_cisco_be_vec,
+ &core_cisco_le_vec,
+#endif
+#ifdef HPPABSD_CORE
+ &core_hppabsd_vec,
+#endif
+#ifdef HPUX_CORE
+ &core_hpux_vec,
+#endif
+#ifdef IRIX_CORE
+ &core_irix_vec,
+#endif
+#ifdef NETBSD_CORE
+ &core_netbsd_vec,
+#endif
+#ifdef OSF_CORE
+ &core_osf_vec,
+#endif
+#ifdef PTRACE_CORE
+ &core_ptrace_vec,
+#endif
+#ifdef SCO5_CORE
+ &core_sco5_vec,
+#endif
+#ifdef TRAD_CORE
+ &core_trad_vec,
+#endif
+
+ NULL /* end of list marker */
+};
+const bfd_target * const *bfd_target_vector = _bfd_target_vector;
+
+/* 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
+};
+
+/* bfd_associated_vector[] contains the associated target vectors used
+ to reduce the ambiguity in bfd_check_format_matches. */
+
+static const bfd_target *_bfd_associated_vector[] = {
+#ifdef ASSOCIATED_VECS
+ ASSOCIATED_VECS,
+#endif
+ NULL
+};
+const bfd_target * const *bfd_associated_vector = _bfd_associated_vector;
+
+/* 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 }
+};
+
+/* Find a target vector, given a name or configuration triplet. */
+
+static const bfd_target *
+find_target (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;
+ }
+ }
+
+ bfd_set_error (bfd_error_invalid_target);
+ return NULL;
+}
+
+/*
+FUNCTION
+ bfd_set_default_target
+
+SYNOPSIS
+ bfd_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.
+*/
+
+bfd_boolean
+bfd_set_default_target (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 if @var{abfd} isn't <<NULL>>. 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 (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)
+ {
+ if (bfd_default_vector[0] != NULL)
+ target = bfd_default_vector[0];
+ else
+ target = bfd_target_vector[0];
+ if (abfd)
+ {
+ abfd->xvec = target;
+ abfd->target_defaulted = TRUE;
+ }
+ return target;
+ }
+
+ if (abfd)
+ abfd->target_defaulted = FALSE;
+
+ target = find_target (targname);
+ if (target == NULL)
+ return NULL;
+
+ if (abfd)
+ abfd->xvec = target;
+ return target;
+}
+
+/* Helper function for bfd_get_target_info to determine the target's
+ architecture. This method handles bfd internal target names as
+ tuples and triplets. */
+static bfd_boolean
+_bfd_find_arch_match (const char *tname, const char **arch,
+ const char **def_target_arch)
+{
+ if (!arch)
+ return FALSE;
+
+ while (*arch != NULL)
+ {
+ const char *in_a = strstr (*arch, tname);
+ char end_ch = (in_a ? in_a[strlen (tname)] : 0);
+
+ if (in_a && (in_a == *arch || in_a[-1] == ':')
+ && end_ch == 0)
+ {
+ *def_target_arch = *arch;
+ return TRUE;
+ }
+ arch++;
+ }
+ return FALSE;
+}
+
+/*
+FUNCTION
+ bfd_get_target_info
+SYNOPSIS
+ const bfd_target *bfd_get_target_info (const char *target_name,
+ bfd *abfd,
+ bfd_boolean *is_bigendian,
+ int *underscoring,
+ const char **def_target_arch);
+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 if @var{abfd} isn't <<NULL>>. This causes
+ <<bfd_check_format>> to loop over all the targets to find the
+ one that matches the file being read.
+ If @var{is_bigendian} is not <<NULL>>, then set this value to target's
+ endian mode. True for big-endian, FALSE for little-endian or for
+ invalid target.
+ If @var{underscoring} is not <<NULL>>, then set this value to target's
+ underscoring mode. Zero for none-underscoring, -1 for invalid target,
+ else the value of target vector's symbol underscoring.
+ If @var{def_target_arch} is not <<NULL>>, then set it to the architecture
+ string specified by the target_name.
+*/
+const bfd_target *
+bfd_get_target_info (const char *target_name, bfd *abfd,
+ bfd_boolean *is_bigendian,
+ int *underscoring, const char **def_target_arch)
+{
+ const bfd_target *target_vec;
+
+ if (is_bigendian)
+ *is_bigendian = FALSE;
+ if (underscoring)
+ *underscoring = -1;
+ if (def_target_arch)
+ *def_target_arch = NULL;
+ target_vec = bfd_find_target (target_name, abfd);
+ if (! target_vec)
+ return NULL;
+ if (is_bigendian)
+ *is_bigendian = ((target_vec->byteorder == BFD_ENDIAN_BIG) ? TRUE
+ : FALSE);
+ if (underscoring)
+ *underscoring = ((int) target_vec->symbol_leading_char) & 0xff;
+
+ if (def_target_arch)
+ {
+ const char *tname = target_vec->name;
+ const char **arches = bfd_arch_list ();
+
+ if (arches && tname)
+ {
+ char *hyp = strchr (tname, '-');
+
+ if (hyp != NULL)
+ {
+ tname = ++hyp;
+
+ /* Make sure we detect architecture names
+ for triplets like "pe-arm-wince-little". */
+ if (!_bfd_find_arch_match (tname, arches, def_target_arch))
+ {
+ char new_tname[50];
+
+ strcpy (new_tname, hyp);
+ while ((hyp = strrchr (new_tname, '-')) != NULL)
+ {
+ *hyp = 0;
+ if (_bfd_find_arch_match (new_tname, arches,
+ def_target_arch))
+ break;
+ }
+ }
+ }
+ else
+ _bfd_find_arch_match (tname, arches, def_target_arch);
+ }
+
+ if (arches)
+ free (arches);
+ }
+ return target_vec;
+}
+
+/*
+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 (void)
+{
+ int vec_length = 0;
+ bfd_size_type amt;
+ const bfd_target * const *target;
+ const char **name_list, **name_ptr;
+
+ for (target = &bfd_target_vector[0]; *target != NULL; target++)
+ vec_length++;
+
+ amt = (vec_length + 1) * sizeof (char **);
+ name_ptr = name_list = (const char **) bfd_malloc (amt);
+
+ if (name_list == NULL)
+ return NULL;
+
+ for (target = &bfd_target_vector[0]; *target != NULL; target++)
+ if (target == &bfd_target_vector[0]
+ || *target != bfd_target_vector[0])
+ *name_ptr++ = (*target)->name;
+
+ *name_ptr = NULL;
+ return name_list;
+}
+
+/*
+FUNCTION
+ bfd_seach_for_target
+
+SYNOPSIS
+ const bfd_target *bfd_search_for_target
+ (int (*search_func) (const bfd_target *, void *),
+ void *);
+
+DESCRIPTION
+ Return a pointer to the first transfer vector in the list of
+ transfer vectors maintained by BFD that produces a non-zero
+ result when passed to the function @var{search_func}. The
+ parameter @var{data} is passed, unexamined, to the search
+ function.
+*/
+
+const bfd_target *
+bfd_search_for_target (int (*search_func) (const bfd_target *, void *),
+ void *data)
+{
+ const bfd_target * const *target;
+
+ for (target = bfd_target_vector; *target != NULL; target ++)
+ if (search_func (*target, data))
+ return *target;
+
+ return NULL;
+}
diff --git a/bfd/targmatch.sed b/bfd/targmatch.sed
new file mode 100644
index 0000000..2716876
--- /dev/null
+++ b/bfd/targmatch.sed
@@ -0,0 +1,33 @@
+1,/START OF targmatch.h/ d
+/END OF targmatch.h/,$ d
+/^[ ]*case/,/^[ ]*esac/ 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 0000000..0328689
--- /dev/null
+++ b/bfd/tekhex.c
@@ -0,0 +1,1035 @@
+/* BFD backend for Extended Tektronix Hex Format objects.
+ Copyright (C) 1992-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, 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 described 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 "sysdep.h"
+#include "bfd.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 ISHEX(x) hex_p(x)
+#define TOHEX(d, x) \
+ (d)[1] = digs[(x) & 0xf]; \
+ (d)[0] = digs[((x)>>4)&0xf];
+
+/* 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 (void)
+{
+ unsigned int i;
+ static bfd_boolean inited = FALSE;
+ int val;
+
+ if (! inited)
+ {
+ 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
+#define CHUNK_SPAN 32
+
+struct data_struct
+{
+ unsigned char chunk_data[CHUNK_MASK + 1];
+ unsigned char chunk_init[(CHUNK_MASK + 1 + CHUNK_SPAN - 1) / CHUNK_SPAN];
+ 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_boolean
+getvalue (char **srcp, bfd_vma *valuep)
+{
+ char *src = *srcp;
+ bfd_vma value = 0;
+ unsigned int len;
+
+ if (!ISHEX (*src))
+ return FALSE;
+
+ len = hex_value (*src++);
+ if (len == 0)
+ len = 16;
+ while (len--)
+ {
+ if (!ISHEX (*src))
+ return FALSE;
+ value = value << 4 | hex_value (*src++);
+ }
+
+ *srcp = src;
+ *valuep = value;
+ return TRUE;
+}
+
+static bfd_boolean
+getsym (char *dstp, char **srcp, unsigned int *lenp)
+{
+ char *src = *srcp;
+ unsigned int i;
+ unsigned int len;
+
+ if (!ISHEX (*src))
+ return FALSE;
+
+ 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;
+ *lenp = len;
+ return TRUE;
+}
+
+static struct data_struct *
+find_chunk (bfd *abfd, bfd_vma vma, bfd_boolean create)
+{
+ struct data_struct *d = abfd->tdata.tekhex_data->data;
+
+ vma &= ~CHUNK_MASK;
+ while (d && (d->vma) != vma)
+ d = d->next;
+
+ if (!d && create)
+ {
+ /* No chunk for this address, so make one up. */
+ d = (struct data_struct *)
+ bfd_zalloc (abfd, (bfd_size_type) sizeof (struct data_struct));
+
+ if (!d)
+ return NULL;
+
+ d->next = abfd->tdata.tekhex_data->data;
+ d->vma = vma;
+ abfd->tdata.tekhex_data->data = d;
+ }
+ return d;
+}
+
+static void
+insert_byte (bfd *abfd, int value, bfd_vma addr)
+{
+ if (value != 0)
+ {
+ /* Find the chunk that this byte needs and put it in. */
+ struct data_struct *d = find_chunk (abfd, addr, TRUE);
+
+ d->chunk_data[addr & CHUNK_MASK] = value;
+ d->chunk_init[(addr & CHUNK_MASK) / CHUNK_SPAN] = 1;
+ }
+}
+
+/* The first pass is to find the names of all the sections, and see
+ how big the data is. */
+
+static bfd_boolean
+first_phase (bfd *abfd, int type, char *src)
+{
+ asection *section, *alt_section;
+ unsigned int len;
+ bfd_vma val;
+ char sym[17]; /* A symbol can only be 16chars long. */
+
+ switch (type)
+ {
+ case '6':
+ /* Data record - read it and store it. */
+ {
+ bfd_vma addr;
+
+ if (!getvalue (&src, &addr))
+ return FALSE;
+
+ while (*src)
+ {
+ insert_byte (abfd, HEX (src), addr);
+ src += 2;
+ addr++;
+ }
+ }
+
+ return TRUE;
+ case '3':
+ /* Symbol record, read the segment. */
+ if (!getsym (sym, &src, &len))
+ return FALSE;
+ section = bfd_get_section_by_name (abfd, sym);
+ if (section == NULL)
+ {
+ char *n = (char *) bfd_alloc (abfd, (bfd_size_type) len + 1);
+
+ if (!n)
+ return FALSE;
+ memcpy (n, sym, len + 1);
+ section = bfd_make_section (abfd, n);
+ if (section == NULL)
+ return FALSE;
+ }
+ alt_section = NULL;
+ while (*src)
+ {
+ switch (*src)
+ {
+ case '1': /* Section range. */
+ src++;
+ if (!getvalue (&src, &section->vma))
+ return FALSE;
+ if (!getvalue (&src, &val))
+ return FALSE;
+ section->size = val - 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. */
+ {
+ bfd_size_type amt = sizeof (tekhex_symbol_type);
+ tekhex_symbol_type *new_symbol = (tekhex_symbol_type *)
+ bfd_alloc (abfd, amt);
+ char stype = (*src);
+
+ if (!new_symbol)
+ return FALSE;
+ new_symbol->symbol.the_bfd = abfd;
+ src++;
+ abfd->symcount++;
+ abfd->flags |= HAS_SYMS;
+ new_symbol->prev = abfd->tdata.tekhex_data->symbols;
+ abfd->tdata.tekhex_data->symbols = new_symbol;
+ if (!getsym (sym, &src, &len))
+ return FALSE;
+ new_symbol->symbol.name = (const char *)
+ bfd_alloc (abfd, (bfd_size_type) len + 1);
+ if (!new_symbol->symbol.name)
+ return FALSE;
+ memcpy ((char *) (new_symbol->symbol.name), sym, len + 1);
+ new_symbol->symbol.section = section;
+ if (stype <= '4')
+ new_symbol->symbol.flags = (BSF_GLOBAL | BSF_EXPORT);
+ else
+ new_symbol->symbol.flags = BSF_LOCAL;
+ if (stype == '2' || stype == '6')
+ new_symbol->symbol.section = bfd_abs_section_ptr;
+ else if (stype == '3' || stype == '7')
+ {
+ if ((section->flags & SEC_DATA) == 0)
+ section->flags |= SEC_CODE;
+ else
+ {
+ if (alt_section == NULL)
+ alt_section = bfd_get_next_section_by_name (section);
+ if (alt_section == NULL)
+ alt_section = bfd_make_section_anyway_with_flags
+ (abfd, section->name,
+ (section->flags & ~SEC_DATA) | SEC_CODE);
+ if (alt_section == NULL)
+ return FALSE;
+ new_symbol->symbol.section = alt_section;
+ }
+ }
+ else if (stype == '4' || stype == '8')
+ {
+ if ((section->flags & SEC_CODE) == 0)
+ section->flags |= SEC_DATA;
+ else
+ {
+ if (alt_section == NULL)
+ alt_section = bfd_get_next_section_by_name (section);
+ if (alt_section == NULL)
+ alt_section = bfd_make_section_anyway_with_flags
+ (abfd, section->name,
+ (section->flags & ~SEC_CODE) | SEC_DATA);
+ if (alt_section == NULL)
+ return FALSE;
+ new_symbol->symbol.section = alt_section;
+ }
+ }
+ if (!getvalue (&src, &val))
+ return FALSE;
+ new_symbol->symbol.value = val - section->vma;
+ break;
+ }
+ default:
+ return FALSE;
+ }
+ }
+ }
+
+ return TRUE;
+}
+
+/* Pass over a tekhex, calling one of the above functions on each
+ record. */
+
+static bfd_boolean
+pass_over (bfd *abfd, bfd_boolean (*func) (bfd *, int, char *))
+{
+ unsigned int chars_on_line;
+ bfd_boolean is_eof = FALSE;
+
+ /* To the front of the file. */
+ if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
+ return FALSE;
+ while (! is_eof)
+ {
+ char src[MAXCHUNK];
+ char type;
+
+ /* Find first '%'. */
+ is_eof = (bfd_boolean) (bfd_bread (src, (bfd_size_type) 1, abfd) != 1);
+ while (*src != '%' && !is_eof)
+ is_eof = (bfd_boolean) (bfd_bread (src, (bfd_size_type) 1, abfd) != 1);
+
+ if (is_eof)
+ break;
+
+ /* Fetch the type and the length and the checksum. */
+ if (bfd_bread (src, (bfd_size_type) 5, abfd) != 5)
+ return FALSE;
+
+ type = src[2];
+
+ if (!ISHEX (src[0]) || !ISHEX (src[1]))
+ break;
+
+ /* Already read five chars. */
+ chars_on_line = HEX (src) - 5;
+
+ if (chars_on_line >= MAXCHUNK)
+ return FALSE;
+
+ if (bfd_bread (src, (bfd_size_type) chars_on_line, abfd) != chars_on_line)
+ return FALSE;
+
+ /* Put a null at the end. */
+ src[chars_on_line] = 0;
+
+ if (!func (abfd, type, src))
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static long
+tekhex_canonicalize_symtab (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 (bfd *abfd)
+{
+ return (abfd->symcount + 1) * (sizeof (struct tekhex_asymbol_struct *));
+
+}
+
+static bfd_boolean
+tekhex_mkobject (bfd *abfd)
+{
+ tdata_type *tdata;
+
+ tdata = (tdata_type *) bfd_alloc (abfd, (bfd_size_type) sizeof (tdata_type));
+ if (!tdata)
+ return FALSE;
+ abfd->tdata.tekhex_data = tdata;
+ tdata->type = 1;
+ tdata->head = NULL;
+ tdata->symbols = NULL;
+ tdata->data = 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 (bfd *abfd)
+{
+ char b[4];
+
+ tekhex_init ();
+
+ if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0
+ || bfd_bread (b, (bfd_size_type) 4, abfd) != 4)
+ return NULL;
+
+ if (b[0] != '%' || !ISHEX (b[1]) || !ISHEX (b[2]) || !ISHEX (b[3]))
+ return NULL;
+
+ tekhex_mkobject (abfd);
+
+ if (!pass_over (abfd, first_phase))
+ return NULL;
+
+ return abfd->xvec;
+}
+
+static void
+move_section_contents (bfd *abfd,
+ asection *section,
+ const void * locationp,
+ file_ptr offset,
+ bfd_size_type count,
+ bfd_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 = NULL;
+
+ BFD_ASSERT (offset == 0);
+ for (addr = section->vma; count != 0; count--, addr++)
+ {
+ /* Get high bits of address. */
+ bfd_vma chunk_number = addr & ~(bfd_vma) CHUNK_MASK;
+ bfd_vma low_bits = addr & CHUNK_MASK;
+ bfd_boolean must_write = !get && *location != 0;
+
+ if (chunk_number != prev_number || (!d && must_write))
+ {
+ /* Different chunk, so move pointer. */
+ d = find_chunk (abfd, chunk_number, must_write);
+ prev_number = chunk_number;
+ }
+
+ if (get)
+ {
+ if (d)
+ *location = d->chunk_data[low_bits];
+ else
+ *location = 0;
+ }
+ else if (must_write)
+ {
+ d->chunk_data[low_bits] = *location;
+ d->chunk_init[low_bits / CHUNK_SPAN] = 1;
+ }
+
+ location++;
+ }
+}
+
+static bfd_boolean
+tekhex_get_section_contents (bfd *abfd,
+ asection *section,
+ void * 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;
+ }
+
+ return FALSE;
+}
+
+static bfd_boolean
+tekhex_set_arch_mach (bfd *abfd,
+ enum bfd_architecture arch,
+ unsigned long machine)
+{
+ /* Ignore errors about unknown architecture. */
+ return (bfd_default_set_arch_mach (abfd, arch, machine)
+ || arch == bfd_arch_unknown);
+}
+
+/* We have to save up all the Tekhexords for a splurge before output. */
+
+static bfd_boolean
+tekhex_set_section_contents (bfd *abfd,
+ sec_ptr section,
+ const void * locationp,
+ file_ptr offset,
+ bfd_size_type bytes_to_do)
+{
+ if (section->flags & (SEC_LOAD | SEC_ALLOC))
+ {
+ move_section_contents (abfd, section, locationp, offset, bytes_to_do,
+ FALSE);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static void
+writevalue (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 (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 (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_bwrite (front, (bfd_size_type) 6, abfd) != 6)
+ abort ();
+ end[0] = '\n';
+ wrlen = end - start + 1;
+ if (bfd_bwrite (start, wrlen, abfd) != wrlen)
+ abort ();
+}
+
+static bfd_boolean
+tekhex_write_object_contents (bfd *abfd)
+{
+ char buffer[100];
+ asymbol **p;
+ asection *s;
+ struct data_struct *d;
+
+ tekhex_init ();
+
+ /* And the raw data. */
+ for (d = abfd->tdata.tekhex_data->data;
+ d != NULL;
+ d = d->next)
+ {
+ int low;
+ int addr;
+
+ /* Write it in blocks of 32 bytes. */
+ for (addr = 0; addr < CHUNK_MASK + 1; addr += CHUNK_SPAN)
+ {
+ if (d->chunk_init[addr / CHUNK_SPAN])
+ {
+ char *dst = buffer;
+
+ writevalue (&dst, addr + d->vma);
+ for (low = 0; low < CHUNK_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 != NULL; s = s->next)
+ {
+ char *dst = buffer;
+
+ writesym (&dst, s->name);
+ *dst++ = '1';
+ writevalue (&dst, s->vma);
+ writevalue (&dst, s->vma + s->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 *sym = *p;
+ char *dst = buffer;
+
+ writesym (&dst, sym->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, sym->name);
+ writevalue (&dst, sym->value + sym->section->vma);
+ out (abfd, '3', buffer, dst);
+ }
+ }
+ }
+
+ /* And the terminator. */
+ if (bfd_bwrite ("%0781010\n", (bfd_size_type) 9, abfd) != 9)
+ abort ();
+ return TRUE;
+}
+
+static int
+tekhex_sizeof_headers (bfd *abfd ATTRIBUTE_UNUSED,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+static asymbol *
+tekhex_make_empty_symbol (bfd *abfd)
+{
+ bfd_size_type amt = sizeof (struct tekhex_symbol_struct);
+ tekhex_symbol_type *new_symbol = (tekhex_symbol_type *) bfd_zalloc (abfd,
+ amt);
+
+ if (!new_symbol)
+ return NULL;
+ new_symbol->symbol.the_bfd = abfd;
+ new_symbol->prev = NULL;
+ return &(new_symbol->symbol);
+}
+
+static void
+tekhex_get_symbol_info (bfd *abfd ATTRIBUTE_UNUSED,
+ asymbol *symbol,
+ symbol_info *ret)
+{
+ bfd_symbol_info (symbol, ret);
+}
+
+static void
+tekhex_print_symbol (bfd *abfd,
+ void * 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 (abfd, (void *) 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_target_special_symbol ((bfd_boolean (*) (bfd *, asymbol *)) bfd_false)
+#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_find_line _bfd_nosymbols_find_line
+#define tekhex_find_inliner_info _bfd_nosymbols_find_inliner_info
+#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_lookup_section_flags bfd_generic_lookup_section_flags
+#define tekhex_bfd_merge_sections bfd_generic_merge_sections
+#define tekhex_bfd_is_group_section bfd_generic_is_group_section
+#define tekhex_bfd_discard_group bfd_generic_discard_group
+#define tekhex_section_already_linked _bfd_generic_section_already_linked
+#define tekhex_bfd_define_common_symbol bfd_generic_define_common_symbol
+#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_link_just_syms _bfd_generic_link_just_syms
+#define tekhex_bfd_copy_link_hash_symbol_type \
+ _bfd_generic_copy_link_hash_symbol_type
+#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. */
+ 0, /* match priority. */
+ 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, /* Headers. */
+
+ {
+ _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),
+
+ NULL,
+
+ NULL
+};
diff --git a/bfd/trad-core.c b/bfd/trad-core.c
new file mode 100644
index 0000000..ce1231e
--- /dev/null
+++ b/bfd/trad-core.c
@@ -0,0 +1,317 @@
+/* BFD back end for traditional Unix core files (U-area and raw sections)
+ Copyright (C) 1988-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+#include "libaout.h" /* BFD a.out internal data structures */
+
+#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 <sys/user.h> /* After a.out.h */
+
+#ifdef TRAD_HEADER
+#include TRAD_HEADER
+#endif
+
+#ifndef NBPG
+# define NBPG getpagesize()
+#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 */
+
+#define trad_unix_core_file_matches_executable_p generic_core_file_matches_executable_p
+#define trad_unix_core_file_pid _bfd_nocore_core_file_pid
+
+
+/* Handle 4.2-style (and perhaps also sysV-style) core dump file. */
+
+static const bfd_target *
+trad_unix_core_file_p (bfd *abfd)
+{
+ int val;
+ struct user u;
+ struct trad_core_struct *rawptr;
+ bfd_size_type amt;
+ flagword flags;
+
+#ifdef TRAD_CORE_USER_OFFSET
+ /* If defined, this macro is the file position of the user struct. */
+ if (bfd_seek (abfd, (file_ptr) TRAD_CORE_USER_OFFSET, SEEK_SET) != 0)
+ return 0;
+#endif
+
+ val = bfd_bread ((void *) &u, (bfd_size_type) 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. */
+ {
+ struct stat statbuf;
+
+ if (bfd_stat (abfd, &statbuf) < 0)
+ return 0;
+
+ if ((ufile_ptr) NBPG * (UPAGES + u.u_dsize
+#ifdef TRAD_CORE_DSIZE_INCLUDES_TSIZE
+ - u.u_tsize
+#endif
+ + u.u_ssize)
+ > (ufile_ptr) statbuf.st_size)
+ {
+ bfd_set_error (bfd_error_wrong_format);
+ return 0;
+ }
+#ifndef TRAD_CORE_ALLOW_ANY_EXTRA_SIZE
+ if (((ufile_ptr) 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
+ )
+ < (ufile_ptr) 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. */
+ amt = sizeof (struct trad_core_struct);
+ rawptr = (struct trad_core_struct *) bfd_zmalloc (amt);
+ 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. */
+
+ flags = SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS;
+ core_stacksec(abfd) = bfd_make_section_anyway_with_flags (abfd, ".stack",
+ flags);
+ if (core_stacksec (abfd) == NULL)
+ goto fail;
+ core_datasec (abfd) = bfd_make_section_anyway_with_flags (abfd, ".data",
+ flags);
+ if (core_datasec (abfd) == NULL)
+ goto fail;
+ core_regsec (abfd) = bfd_make_section_anyway_with_flags (abfd, ".reg",
+ SEC_HAS_CONTENTS);
+ if (core_regsec (abfd) == NULL)
+ goto fail;
+
+ core_datasec (abfd)->size = NBPG * u.u_dsize
+#ifdef TRAD_CORE_DSIZE_INCLUDES_TSIZE
+ - NBPG * u.u_tsize
+#endif
+ ;
+ core_stacksec (abfd)->size = NBPG * u.u_ssize;
+ core_regsec (abfd)->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 = - (bfd_vma) (unsigned long) 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;
+
+ return abfd->xvec;
+
+ fail:
+ bfd_release (abfd, abfd->tdata.any);
+ abfd->tdata.any = NULL;
+ bfd_section_list_clear (abfd);
+ return NULL;
+}
+
+static char *
+trad_unix_core_file_failing_command (bfd *abfd)
+{
+#ifndef NO_CORE_COMMAND
+ char *com = abfd->tdata.trad_core_data->u.u_comm;
+ if (*com)
+ return com;
+ else
+#endif
+ return 0;
+}
+
+static int
+trad_unix_core_file_failing_signal (bfd *ignore_abfd ATTRIBUTE_UNUSED)
+{
+#ifdef TRAD_UNIX_CORE_FILE_FAILING_SIGNAL
+ return TRAD_UNIX_CORE_FILE_FAILING_SIGNAL(ignore_abfd);
+#else
+ return -1; /* FIXME, where is it? */
+#endif
+}
+
+/* If somebody calls any byte-swapping routines, shoot them. */
+static void
+swap_abort (void)
+{
+ abort (); /* This way doesn't require any declaration for ANSI to fuck up */
+}
+
+#define NO_GET ((bfd_vma (*) (const void *)) swap_abort)
+#define NO_PUT ((void (*) (bfd_vma, void *)) swap_abort)
+#define NO_GETS ((bfd_signed_vma (*) (const void *)) swap_abort)
+#define NO_GET64 ((bfd_uint64_t (*) (const void *)) swap_abort)
+#define NO_PUT64 ((void (*) (bfd_uint64_t, void *)) swap_abort)
+#define NO_GETS64 ((bfd_int64_t (*) (const void *)) swap_abort)
+
+const bfd_target core_trad_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 */
+ 0, /* match priority. */
+ NO_GET64, NO_GETS64, NO_PUT64, /* 64 bit data */
+ NO_GET, NO_GETS, NO_PUT, /* 32 bit data */
+ NO_GET, NO_GETS, NO_PUT, /* 16 bit data */
+ NO_GET64, NO_GETS64, NO_PUT64, /* 64 bit hdrs */
+ NO_GET, NO_GETS, NO_PUT, /* 32 bit hdrs */
+ NO_GET, NO_GETS, 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),
+
+ NULL,
+
+ NULL /* backend_data */
+ };
diff --git a/bfd/vax1knetbsd.c b/bfd/vax1knetbsd.c
new file mode 100644
index 0000000..58614ef
--- /dev/null
+++ b/bfd/vax1knetbsd.c
@@ -0,0 +1,38 @@
+/* BFD back-end for NetBSD/VAX (1K page size) a.out-ish binaries.
+ Copyright (C) 1998-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, 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
+
+/* Do not "beautify" the CONCAT* macro args. Traditional C will not
+ remove whitespace added here, and thus will fail to concatenate
+ the tokens. */
+#define MY(OP) CONCAT2 (vax_aout_1knbsd_,OP)
+
+/* This needs to start with a.out so GDB knows it is an a.out variant. */
+#define TARGETNAME "a.out-vax1k-netbsd"
+
+#include "netbsd.h"
diff --git a/bfd/vaxbsd.c b/bfd/vaxbsd.c
new file mode 100644
index 0000000..54e8a32
--- /dev/null
+++ b/bfd/vaxbsd.c
@@ -0,0 +1,40 @@
+/* BFD back-end for BSD and Ultrix/VAX (1K page size) a.out-ish binaries.
+ Copyright (C) 2002-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#define N_HEADER_IN_TEXT(x) 0
+#define ENTRY_CAN_BE_ZERO
+#define TEXT_START_ADDR 0
+#define TARGET_PAGE_SIZE 1024
+#define SEGMENT_SIZE TARGET_PAGE_SIZE
+#define DEFAULT_ARCH bfd_arch_vax
+
+/* Do not "beautify" the CONCAT* macro args. Traditional C will not
+ remove whitespace added here, and thus will fail to concatenate the
+ tokens. */
+#define MY(OP) CONCAT2 (vax_aout_bsd_,OP)
+
+#define TARGETNAME "a.out-vax-bsd"
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+#include "libaout.h"
+
+#include "aout-target.h"
diff --git a/bfd/vaxnetbsd.c b/bfd/vaxnetbsd.c
new file mode 100644
index 0000000..faf507e
--- /dev/null
+++ b/bfd/vaxnetbsd.c
@@ -0,0 +1,38 @@
+/* BFD back-end for NetBSD/VAX (4K page size) a.out-ish binaries.
+ Copyright (C) 1998-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#define BYTES_IN_WORD 4
+#undef TARGET_IS_BIG_ENDIAN_P
+
+#define TARGET_PAGE_SIZE 0x1000
+#define SEGMENT_SIZE TARGET_PAGE_SIZE
+
+#define DEFAULT_ARCH bfd_arch_vax
+#define DEFAULT_MID M_VAX4K_NETBSD
+
+/* Do not "beautify" the CONCAT* macro args. Traditional C will not
+ remove whitespace added here, and thus will fail to concatenate
+ the tokens. */
+#define MY(OP) CONCAT2 (vax_aout_nbsd_,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/verilog.c b/bfd/verilog.c
new file mode 100644
index 0000000..c1c5458
--- /dev/null
+++ b/bfd/verilog.c
@@ -0,0 +1,373 @@
+/* BFD back-end for verilog hex memory dump files.
+ Copyright (C) 2009-2014 Free Software Foundation, Inc.
+ Written by Anthony Green <green@moxielogic.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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+
+/* SUBSECTION
+ Verilog hex memory file handling
+
+ DESCRIPTION
+
+ Verilog hex memory files cannot hold anything but addresses
+ and data, so that's all that we implement.
+
+ The syntax of the text file is described in the IEEE standard
+ for Verilog. Briefly, the file contains two types of tokens:
+ data and optional addresses. The tokens are separated by
+ whitespace and comments. Comments may be single line or
+ multiline, using syntax similar to C++. Addresses are
+ specified by a leading "at" character (@) and are always
+ hexadecimal strings. Data and addresses may contain
+ underscore (_) characters.
+
+ If no address is specified, the data is assumed to start at
+ address 0. Similarly, if data exists before the first
+ specified address, then that data is assumed to start at
+ address 0.
+
+
+ EXAMPLE
+ @1000
+ 01 ae 3f 45 12
+
+ DESCRIPTION
+ @1000 specifies the starting address for the memory data.
+ The following characters describe the 5 bytes at 0x1000. */
+
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+#include "libiberty.h"
+#include "safe-ctype.h"
+
+/* 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) \
+ d[1] = digs[(x) & 0xf]; \
+ d[0] = digs[((x) >> 4) & 0xf];
+
+/* When writing a verilog memory dump file, we write them in the order
+ in which they appear in memory. This structure is used to hold them
+ in memory. */
+
+struct verilog_data_list_struct
+{
+ struct verilog_data_list_struct *next;
+ bfd_byte * data;
+ bfd_vma where;
+ bfd_size_type size;
+};
+
+typedef struct verilog_data_list_struct verilog_data_list_type;
+
+/* The verilog tdata information. */
+
+typedef struct verilog_data_struct
+{
+ verilog_data_list_type *head;
+ verilog_data_list_type *tail;
+}
+tdata_type;
+
+static bfd_boolean
+verilog_set_arch_mach (bfd *abfd, enum bfd_architecture arch, unsigned long mach)
+{
+ if (arch != bfd_arch_unknown)
+ return bfd_default_set_arch_mach (abfd, arch, mach);
+
+ abfd->arch_info = & bfd_default_arch_struct;
+ return TRUE;
+}
+
+/* We have to save up all the outpu for a splurge before output. */
+
+static bfd_boolean
+verilog_set_section_contents (bfd *abfd,
+ sec_ptr section,
+ const void * location,
+ file_ptr offset,
+ bfd_size_type bytes_to_do)
+{
+ tdata_type *tdata = abfd->tdata.verilog_data;
+ verilog_data_list_type *entry;
+
+ entry = (verilog_data_list_type *) bfd_alloc (abfd, sizeof (* entry));
+ if (entry == NULL)
+ return FALSE;
+
+ if (bytes_to_do
+ && (section->flags & SEC_ALLOC)
+ && (section->flags & SEC_LOAD))
+ {
+ bfd_byte *data;
+
+ data = (bfd_byte *) bfd_alloc (abfd, bytes_to_do);
+ if (data == NULL)
+ return FALSE;
+ memcpy ((void *) data, location, (size_t) bytes_to_do);
+
+ 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
+ {
+ verilog_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;
+}
+
+static bfd_boolean
+verilog_write_address (bfd *abfd, bfd_vma address)
+{
+ char buffer[12];
+ char *dst = buffer;
+ bfd_size_type wrlen;
+
+ /* Write the address. */
+ *dst++ = '@';
+ TOHEX (dst, (address >> 24));
+ dst += 2;
+ TOHEX (dst, (address >> 16));
+ dst += 2;
+ TOHEX (dst, (address >> 8));
+ dst += 2;
+ TOHEX (dst, (address));
+ dst += 2;
+ *dst++ = '\r';
+ *dst++ = '\n';
+ wrlen = dst - buffer;
+
+ return bfd_bwrite ((void *) buffer, wrlen, abfd) == wrlen;
+}
+
+/* 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 bfd_boolean
+verilog_write_record (bfd *abfd,
+ const bfd_byte *data,
+ const bfd_byte *end)
+{
+ char buffer[48];
+ const bfd_byte *src = data;
+ char *dst = buffer;
+ bfd_size_type wrlen;
+
+ /* Write the data. */
+ for (src = data; src < end; src++)
+ {
+ TOHEX (dst, *src);
+ dst += 2;
+ *dst++ = ' ';
+ }
+ *dst++ = '\r';
+ *dst++ = '\n';
+ wrlen = dst - buffer;
+
+ return bfd_bwrite ((void *) buffer, wrlen, abfd) == wrlen;
+}
+
+static bfd_boolean
+verilog_write_section (bfd *abfd,
+ tdata_type *tdata ATTRIBUTE_UNUSED,
+ verilog_data_list_type *list)
+{
+ unsigned int octets_written = 0;
+ bfd_byte *location = list->data;
+
+ verilog_write_address (abfd, list->where);
+ while (octets_written < list->size)
+ {
+ unsigned int octets_this_chunk = list->size - octets_written;
+
+ if (octets_this_chunk > 16)
+ octets_this_chunk = 16;
+
+ if (! verilog_write_record (abfd,
+ location,
+ location + octets_this_chunk))
+ return FALSE;
+
+ octets_written += octets_this_chunk;
+ location += octets_this_chunk;
+ }
+
+ return TRUE;
+}
+
+static bfd_boolean
+verilog_write_object_contents (bfd *abfd)
+{
+ tdata_type *tdata = abfd->tdata.verilog_data;
+ verilog_data_list_type *list;
+
+ /* Now wander though all the sections provided and output them. */
+ list = tdata->head;
+
+ while (list != (verilog_data_list_type *) NULL)
+ {
+ if (! verilog_write_section (abfd, tdata, list))
+ return FALSE;
+ list = list->next;
+ }
+ return TRUE;
+}
+
+/* Initialize by filling in the hex conversion array. */
+
+static void
+verilog_init (void)
+{
+ static bfd_boolean inited = FALSE;
+
+ if (! inited)
+ {
+ inited = TRUE;
+ hex_init ();
+ }
+}
+
+/* Set up the verilog tdata information. */
+
+static bfd_boolean
+verilog_mkobject (bfd *abfd)
+{
+ tdata_type *tdata;
+
+ verilog_init ();
+
+ tdata = (tdata_type *) bfd_alloc (abfd, sizeof (tdata_type));
+ if (tdata == NULL)
+ return FALSE;
+
+ abfd->tdata.verilog_data = tdata;
+ tdata->head = NULL;
+ tdata->tail = NULL;
+
+ return TRUE;
+}
+
+#define verilog_close_and_cleanup _bfd_generic_close_and_cleanup
+#define verilog_bfd_free_cached_info _bfd_generic_bfd_free_cached_info
+#define verilog_new_section_hook _bfd_generic_new_section_hook
+#define verilog_bfd_is_target_special_symbol ((bfd_boolean (*) (bfd *, asymbol *)) bfd_false)
+#define verilog_bfd_is_local_label_name bfd_generic_is_local_label_name
+#define verilog_get_lineno _bfd_nosymbols_get_lineno
+#define verilog_find_nearest_line _bfd_nosymbols_find_nearest_line
+#define verilog_find_inliner_info _bfd_nosymbols_find_inliner_info
+#define verilog_make_empty_symbol _bfd_generic_make_empty_symbol
+#define verilog_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol
+#define verilog_read_minisymbols _bfd_generic_read_minisymbols
+#define verilog_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol
+#define verilog_get_section_contents_in_window _bfd_generic_get_section_contents_in_window
+#define verilog_bfd_get_relocated_section_contents bfd_generic_get_relocated_section_contents
+#define verilog_bfd_relax_section bfd_generic_relax_section
+#define verilog_bfd_gc_sections bfd_generic_gc_sections
+#define verilog_bfd_merge_sections bfd_generic_merge_sections
+#define verilog_bfd_is_group_section bfd_generic_is_group_section
+#define verilog_bfd_discard_group bfd_generic_discard_group
+#define verilog_section_already_linked _bfd_generic_section_already_linked
+#define verilog_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
+#define verilog_bfd_link_add_symbols _bfd_generic_link_add_symbols
+#define verilog_bfd_link_just_syms _bfd_generic_link_just_syms
+#define verilog_bfd_final_link _bfd_generic_final_link
+#define verilog_bfd_link_split_section _bfd_generic_link_split_section
+
+const bfd_target verilog_vec =
+{
+ "verilog", /* Name. */
+ bfd_target_verilog_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. */
+ 0, /* match priority. */
+ 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,
+ _bfd_dummy_target,
+ _bfd_dummy_target,
+ _bfd_dummy_target,
+ },
+ {
+ bfd_false,
+ verilog_mkobject,
+ bfd_false,
+ bfd_false,
+ },
+ { /* bfd_write_contents. */
+ bfd_false,
+ verilog_write_object_contents,
+ bfd_false,
+ bfd_false,
+ },
+
+ 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 (_bfd_nosymbols),
+ BFD_JUMP_TABLE_RELOCS (_bfd_norelocs),
+ BFD_JUMP_TABLE_WRITE (verilog),
+ BFD_JUMP_TABLE_LINK (_bfd_nolink),
+ BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
+
+ NULL,
+
+ NULL
+};
diff --git a/bfd/versados.c b/bfd/versados.c
new file mode 100644
index 0000000..42bf36c
--- /dev/null
+++ b/bfd/versados.c
@@ -0,0 +1,877 @@
+/* BFD back-end for VERSAdos-E objects.
+ Copyright (C) 1995-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+/*
+ SUBSECTION
+ VERSAdos-E relocatable object file format
+
+ DESCRIPTION
+
+ This module supports reading of VERSAdos relocatable
+ object files.
+
+ A VERSAdos file looks like contains
+
+ o Identification Record
+ o External Symbol Definition Record
+ o Object Text Record
+ o End Record. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+#include "libiberty.h"
+
+
+#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_XDEF_IN_ABS 5
+#define ESD_XREF_SEC 6
+#define ESD_XREF_SYM 7
+
+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 bfd_boolean
+versados_mkobject (bfd *abfd)
+{
+ if (abfd->tdata.versados_data == NULL)
+ {
+ bfd_size_type amt = sizeof (tdata_type);
+ tdata_type *tdata = bfd_alloc (abfd, amt);
+
+ 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 (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 (bfd *abfd, union ext_any *ptr)
+{
+ if (bfd_bread (&ptr->size, (bfd_size_type) 1, abfd) != 1
+ || (bfd_bread ((char *) ptr + 1, (bfd_size_type) ptr->size, abfd)
+ != ptr->size))
+ return 0;
+ return 1;
+}
+
+static int
+get_4 (unsigned char **pp)
+{
+ unsigned char *p = *pp;
+
+ *pp += 4;
+ return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | (p[3] << 0);
+}
+
+static void
+get_10 (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 (bfd *abfd, const 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 (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, (bfd_vma) 0,
+ bfd_und_section_ptr);
+ esidx = VDATA (abfd)->es_done++;
+ RDATA (abfd, esidx - ES_BASE) = s;
+ }
+ }
+ break;
+
+ case ESD_ABS:
+ size = get_4 (&ptr);
+ (void) size;
+ start = get_4 (&ptr);
+ (void) start;
+ break;
+ case ESD_STD_REL_SEC:
+ case ESD_SHRT_REL_SEC:
+ sec->size = get_4 (&ptr);
+ sec->flags |= SEC_ALLOC;
+ break;
+ case ESD_XDEF_IN_ABS:
+ sec = bfd_abs_section_ptr;
+ case ESD_XDEF_IN_SEC:
+ {
+ int snum = VDATA (abfd)->def_idx++;
+ bfd_vma 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);
+ 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 (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 (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 = ((unsigned long) 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 id = *srcp++;
+
+ if (id)
+ {
+ 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 **) (size_t) id;
+ 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->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)
+ {
+ bfd_size_type size = esdid->section->size;
+ esdid->contents = bfd_alloc (abfd, size);
+ }
+}
+
+static bfd_boolean
+versados_scan (bfd *abfd)
+{
+ int loop = 1;
+ int i;
+ int j;
+ int nsecs = 0;
+ bfd_size_type amt;
+
+ VDATA (abfd)->stringlen = 0;
+ VDATA (abfd)->nrefs = 0;
+ VDATA (abfd)->ndefs = 0;
+ VDATA (abfd)->ref_idx = 0;
+ VDATA (abfd)->def_idx = 0;
+ VDATA (abfd)->pass_2_done = 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)
+ {
+ amt = (bfd_size_type) esdid->relocs * sizeof (arelent);
+ esdid->section->relocation = bfd_alloc (abfd, amt);
+
+ 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;
+
+ amt = abfd->symcount;
+ amt *= sizeof (asymbol);
+ VDATA (abfd)->symbols = bfd_alloc (abfd, amt);
+
+ amt = VDATA (abfd)->stringlen;
+ VDATA (abfd)->strings = bfd_alloc (abfd, amt);
+
+ 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 (bfd *abfd)
+{
+ struct ext_vheader ext;
+ unsigned char len;
+ tdata_type *tdata_save;
+
+ if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
+ return NULL;
+
+ if (bfd_bread (&len, (bfd_size_type) 1, abfd) != 1)
+ {
+ if (bfd_get_error () != bfd_error_system_call)
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+
+ if (bfd_bread (&ext.type, (bfd_size_type) 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. */
+ tdata_save = abfd->tdata.versados_data;
+ if (!versados_mkobject (abfd) || !versados_scan (abfd))
+ {
+ abfd->tdata.versados_data = tdata_save;
+ return NULL;
+ }
+
+ return abfd->xvec;
+}
+
+static bfd_boolean
+versados_pass_2 (bfd *abfd)
+{
+ union ext_any any;
+
+ if (VDATA (abfd)->pass_2_done)
+ return 1;
+
+ if (bfd_seek (abfd, (file_ptr) 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 bfd_boolean
+versados_get_section_contents (bfd *abfd,
+ asection *section,
+ void * 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 bfd_boolean
+versados_set_section_contents (bfd *abfd ATTRIBUTE_UNUSED,
+ sec_ptr section ATTRIBUTE_UNUSED,
+ const void * location ATTRIBUTE_UNUSED,
+ file_ptr offset ATTRIBUTE_UNUSED,
+ bfd_size_type bytes_to_do ATTRIBUTE_UNUSED)
+{
+ return FALSE;
+}
+
+static int
+versados_sizeof_headers (bfd *abfd ATTRIBUTE_UNUSED,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+/* Return the amount of memory needed to read the symbol table. */
+
+static long
+versados_get_symtab_upper_bound (bfd *abfd)
+{
+ return (bfd_get_symcount (abfd) + 1) * sizeof (asymbol *);
+}
+
+/* Return the symbol table. */
+
+static long
+versados_canonicalize_symtab (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;
+}
+
+static void
+versados_get_symbol_info (bfd *abfd ATTRIBUTE_UNUSED,
+ asymbol *symbol,
+ symbol_info *ret)
+{
+ bfd_symbol_info (symbol, ret);
+}
+
+static void
+versados_print_symbol (bfd *abfd,
+ void * 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 (abfd, (void *) file, symbol);
+ fprintf (file, " %-5s %s",
+ symbol->section->name,
+ symbol->name);
+ }
+}
+
+static long
+versados_get_reloc_upper_bound (bfd *abfd ATTRIBUTE_UNUSED,
+ sec_ptr asect)
+{
+ return (asect->reloc_count + 1) * sizeof (arelent *);
+}
+
+static long
+versados_canonicalize_reloc (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) (size_t) src[count].sym_ptr_ptr;
+
+ if (esdid == 0)
+ src[count].sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
+ else if (esdid < ES_BASE)
+ {
+ /* Section relative thing. */
+ struct esdid *e = &EDATA (abfd, esdid - 1);
+
+ 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_target_special_symbol ((bfd_boolean (*) (bfd *, asymbol *)) bfd_false)
+#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_find_line _bfd_nosymbols_find_line
+#define versados_find_inliner_info _bfd_nosymbols_find_inliner_info
+#define versados_make_empty_symbol _bfd_generic_make_empty_symbol
+#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_bfd_reloc_name_lookup _bfd_norelocs_bfd_reloc_name_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_lookup_section_flags bfd_generic_lookup_section_flags
+#define versados_bfd_merge_sections bfd_generic_merge_sections
+#define versados_bfd_is_group_section bfd_generic_is_group_section
+#define versados_bfd_discard_group bfd_generic_discard_group
+#define versados_section_already_linked _bfd_generic_section_already_linked
+#define versados_bfd_define_common_symbol bfd_generic_define_common_symbol
+#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_link_just_syms _bfd_generic_link_just_syms
+#define versados_bfd_copy_link_hash_symbol_type \
+ _bfd_generic_copy_link_hash_symbol_type
+#define versados_bfd_final_link _bfd_generic_final_link
+#define versados_bfd_link_split_section _bfd_generic_link_split_section
+
+const bfd_target m68k_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. */
+ 0, /* match priority. */
+ 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, /* Headers. */
+
+ {
+ _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),
+
+ NULL,
+
+ NULL
+};
diff --git a/bfd/version.h b/bfd/version.h
new file mode 100644
index 0000000..c806928
--- /dev/null
+++ b/bfd/version.h
@@ -0,0 +1,4 @@
+#define BFD_VERSION_DATE 20141223
+#define BFD_VERSION @bfd_version@
+#define BFD_VERSION_STRING @bfd_version_package@ @bfd_version_string@
+#define REPORT_BUGS_TO @report_bugs_to@
diff --git a/bfd/version.m4 b/bfd/version.m4
new file mode 100644
index 0000000..4c966bc
--- /dev/null
+++ b/bfd/version.m4
@@ -0,0 +1 @@
+m4_define([BFD_VERSION], [2.25])
diff --git a/bfd/vms-alpha.c b/bfd/vms-alpha.c
new file mode 100644
index 0000000..5ff5bfd
--- /dev/null
+++ b/bfd/vms-alpha.c
@@ -0,0 +1,9278 @@
+/* vms.c -- BFD back-end for EVAX (openVMS/Alpha) files.
+ Copyright (C) 1996-2014 Free Software Foundation, Inc.
+
+ Initial version written by Klaus Kaempf (kkaempf@rmi.de)
+ Major rewrite by Adacore.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+/* TODO:
+ o overlayed sections
+ o PIC
+ o Generation of shared image
+ o Relocation optimizations
+ o EISD for the stack
+ o Vectors isect
+ o 64 bits sections
+ o Entry point
+ o LIB$INITIALIZE
+ o protected sections (for messages)
+ ...
+*/
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "bfdlink.h"
+#include "libbfd.h"
+#include "bfdver.h"
+
+#include "vms.h"
+#include "vms/eihd.h"
+#include "vms/eiha.h"
+#include "vms/eihi.h"
+#include "vms/eihs.h"
+#include "vms/eisd.h"
+#include "vms/dmt.h"
+#include "vms/dst.h"
+#include "vms/eihvn.h"
+#include "vms/eobjrec.h"
+#include "vms/egsd.h"
+#include "vms/egps.h"
+#include "vms/esgps.h"
+#include "vms/eeom.h"
+#include "vms/emh.h"
+#include "vms/eiaf.h"
+#include "vms/shl.h"
+#include "vms/eicp.h"
+#include "vms/etir.h"
+#include "vms/egsy.h"
+#include "vms/esdf.h"
+#include "vms/esdfm.h"
+#include "vms/esdfv.h"
+#include "vms/esrf.h"
+#include "vms/egst.h"
+#include "vms/eidc.h"
+#include "vms/dsc.h"
+#include "vms/prt.h"
+#include "vms/internal.h"
+
+
+#define MIN(a,b) ((a) < (b) ? (a) : (b))
+
+/* 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
+#define ALPHA_R_NOP 14
+#define ALPHA_R_BSR 15
+#define ALPHA_R_LDA 16
+#define ALPHA_R_BOH 17
+
+/* These are used with DST_S_C_LINE_NUM. */
+#define DST_S_C_LINE_NUM_HEADER_SIZE 4
+
+/* These are used with DST_S_C_SOURCE */
+
+#define DST_S_B_PCLINE_UNSBYTE 1
+#define DST_S_W_PCLINE_UNSWORD 1
+#define DST_S_L_PCLINE_UNSLONG 1
+
+#define DST_S_B_MODBEG_NAME 14
+#define DST_S_L_RTNBEG_ADDRESS 5
+#define DST_S_B_RTNBEG_NAME 13
+#define DST_S_L_RTNEND_SIZE 5
+
+/* These are used with DST_S_C_SOURCE. */
+#define DST_S_C_SOURCE_HEADER_SIZE 4
+
+#define DST_S_B_SRC_DF_LENGTH 1
+#define DST_S_W_SRC_DF_FILEID 3
+#define DST_S_B_SRC_DF_FILENAME 20
+#define DST_S_B_SRC_UNSBYTE 1
+#define DST_S_W_SRC_UNSWORD 1
+#define DST_S_L_SRC_UNSLONG 1
+
+/* Debugger symbol definitions. */
+
+#define DBG_S_L_DMT_MODBEG 0
+#define DBG_S_L_DST_SIZE 4
+#define DBG_S_W_DMT_PSECT_COUNT 8
+#define DBG_S_C_DMT_HEADER_SIZE 12
+
+#define DBG_S_L_DMT_PSECT_START 0
+#define DBG_S_L_DMT_PSECT_LENGTH 4
+#define DBG_S_C_DMT_PSECT_SIZE 8
+
+/* VMS module header. */
+
+struct hdr_struct
+{
+ char hdr_b_strlvl;
+ int hdr_l_arch1;
+ int hdr_l_arch2;
+ int 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;
+};
+
+#define EMH_DATE_LENGTH 17
+
+/* VMS End-Of-Module records (EOM/EEOM). */
+
+struct eom_struct
+{
+ unsigned int eom_l_total_lps;
+ unsigned short eom_w_comcod;
+ bfd_boolean eom_has_transfer;
+ unsigned char eom_b_tfrflg;
+ unsigned int eom_l_psindx;
+ unsigned int eom_l_tfradr;
+};
+
+struct vms_symbol_entry
+{
+ bfd *owner;
+
+ /* Common fields. */
+ unsigned char typ;
+ unsigned char data_type;
+ unsigned short flags;
+
+ /* Section and offset/value of the symbol. */
+ unsigned int value;
+ asection *section;
+
+ /* Section and offset/value for the entry point (only for subprg). */
+ asection *code_section;
+ unsigned int code_value;
+
+ /* Symbol vector offset. */
+ unsigned int symbol_vector;
+
+ /* Length of the name. */
+ unsigned char namelen;
+
+ char name[1];
+};
+
+/* Stack value for push/pop commands. */
+
+struct stack_struct
+{
+ bfd_vma value;
+ unsigned int reloc;
+};
+
+#define STACKSIZE 128
+
+/* A minimal decoding of DST compilation units. We only decode
+ what's needed to get to the line number information. */
+
+struct fileinfo
+{
+ char *name;
+ unsigned int srec;
+};
+
+struct srecinfo
+{
+ struct srecinfo *next;
+ unsigned int line;
+ unsigned int sfile;
+ unsigned int srec;
+};
+
+struct lineinfo
+{
+ struct lineinfo *next;
+ bfd_vma address;
+ unsigned int line;
+};
+
+struct funcinfo
+{
+ struct funcinfo *next;
+ char *name;
+ bfd_vma low;
+ bfd_vma high;
+};
+
+struct module
+{
+ /* Chain the previously read compilation unit. */
+ struct module *next;
+
+ /* The module name. */
+ char *name;
+
+ /* The start offset and size of debug info in the DST section. */
+ unsigned int modbeg;
+ unsigned int size;
+
+ /* The lowest and highest addresses contained in this compilation
+ unit as specified in the compilation unit header. */
+ bfd_vma low;
+ bfd_vma high;
+
+ /* The listing line table. */
+ struct lineinfo *line_table;
+
+ /* The source record table. */
+ struct srecinfo *srec_table;
+
+ /* A list of the functions found in this module. */
+ struct funcinfo *func_table;
+
+ /* Current allocation of file_table. */
+ unsigned int file_table_count;
+
+ /* An array of the files making up this module. */
+ struct fileinfo *file_table;
+};
+
+/* BFD private data for alpha-vms. */
+
+struct vms_private_data_struct
+{
+ /* If true, relocs have been read. */
+ bfd_boolean reloc_done;
+
+ /* Record input buffer. */
+ struct vms_rec_rd recrd;
+ struct vms_rec_wr recwr;
+
+ struct hdr_struct hdr_data; /* data from HDR/EMH record */
+ struct eom_struct eom_data; /* data from EOM/EEOM record */
+
+ /* Transfer addresses (entry points). */
+ bfd_vma transfer_address[4];
+
+ /* Array of GSD sections to get the correspond BFD one. */
+ unsigned int section_max; /* Size of the sections array. */
+ unsigned int section_count; /* Number of GSD sections. */
+ asection **sections;
+
+ /* Array of raw symbols. */
+ struct vms_symbol_entry **syms;
+
+ /* Canonicalized symbols. */
+ asymbol **csymbols;
+
+ /* Number of symbols. */
+ unsigned int gsd_sym_count;
+ /* Size of the syms array. */
+ unsigned int max_sym_count;
+ /* Number of procedure symbols. */
+ unsigned int norm_sym_count;
+
+ /* Stack used to evaluate TIR/ETIR commands. */
+ struct stack_struct *stack;
+ int stackptr;
+
+ /* Content reading. */
+ asection *image_section; /* section for image_ptr */
+ file_ptr image_offset; /* Offset for image_ptr. */
+
+ struct module *modules; /* list of all compilation units */
+
+ /* The DST section. */
+ asection *dst_section;
+
+ unsigned int dst_ptr_offsets_count; /* # of offsets in following array */
+ unsigned int *dst_ptr_offsets; /* array of saved image_ptr offsets */
+
+ /* Shared library support */
+ bfd_vma symvva; /* relative virtual address of symbol vector */
+ unsigned int ident;
+ unsigned char matchctl;
+
+ /* Shared library index. This is used for input bfd while linking. */
+ unsigned int shr_index;
+
+ /* Used to place structures in the file. */
+ file_ptr file_pos;
+
+ /* Simply linked list of eisd. */
+ struct vms_internal_eisd_map *eisd_head;
+ struct vms_internal_eisd_map *eisd_tail;
+
+ /* Simply linked list of eisd for shared libraries. */
+ struct vms_internal_eisd_map *gbl_eisd_head;
+ struct vms_internal_eisd_map *gbl_eisd_tail;
+
+ /* linkage index counter used by conditional store commands */
+ unsigned int vms_linkage_index;
+};
+
+#define PRIV2(abfd, name) \
+ (((struct vms_private_data_struct *)(abfd)->tdata.any)->name)
+#define PRIV(name) PRIV2(abfd,name)
+
+
+/* Used to keep extra VMS 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 VMS relocations
+ are variable length.
+
+ reloc_stream is the actual stream of relocation entries. */
+
+struct vms_section_data_struct
+{
+ /* Maximnum number of entries in sec->relocation. */
+ unsigned reloc_max;
+
+ /* Corresponding eisd. Used only while generating executables. */
+ struct vms_internal_eisd_map *eisd;
+
+ /* PSC flags to be clear. */
+ flagword no_flags;
+
+ /* PSC flags to be set. */
+ flagword flags;
+};
+
+#define vms_section_data(sec) \
+ ((struct vms_section_data_struct *)sec->used_by_bfd)
+
+/* To be called from the debugger. */
+struct vms_private_data_struct *bfd_vms_get_data (bfd *abfd);
+
+static int vms_get_remaining_object_record (bfd *abfd, int read_so_far);
+static bfd_boolean _bfd_vms_slurp_object_records (bfd * abfd);
+static void alpha_vms_add_fixup_lp (struct bfd_link_info *, bfd *, bfd *);
+static void alpha_vms_add_fixup_ca (struct bfd_link_info *, bfd *, bfd *);
+static void alpha_vms_add_fixup_qr (struct bfd_link_info *, bfd *, bfd *,
+ bfd_vma);
+static void alpha_vms_add_fixup_lr (struct bfd_link_info *, unsigned int,
+ bfd_vma);
+static void alpha_vms_add_lw_reloc (struct bfd_link_info *info);
+static void alpha_vms_add_qw_reloc (struct bfd_link_info *info);
+
+struct vector_type
+{
+ unsigned int max_el;
+ unsigned int nbr_el;
+ void *els;
+};
+
+/* Number of elements in VEC. */
+
+#define VEC_COUNT(VEC) ((VEC).nbr_el)
+
+/* Get the address of the Nth element. */
+
+#define VEC_EL(VEC, TYPE, N) (((TYPE *)((VEC).els))[N])
+
+#define VEC_INIT(VEC) \
+ do { \
+ (VEC).max_el = 0; \
+ (VEC).nbr_el = 0; \
+ (VEC).els = NULL; \
+ } while (0)
+
+/* Be sure there is room for a new element. */
+
+static void vector_grow1 (struct vector_type *vec, size_t elsz);
+
+/* Allocate room for a new element and return its address. */
+
+#define VEC_APPEND(VEC, TYPE) \
+ (vector_grow1 (&VEC, sizeof (TYPE)), &VEC_EL(VEC, TYPE, (VEC).nbr_el++))
+
+/* Append an element. */
+
+#define VEC_APPEND_EL(VEC, TYPE, EL) \
+ (*(VEC_APPEND (VEC, TYPE)) = EL)
+
+struct alpha_vms_vma_ref
+{
+ bfd_vma vma; /* Vma in the output. */
+ bfd_vma ref; /* Reference in the input. */
+};
+
+struct alpha_vms_shlib_el
+{
+ bfd *abfd;
+ bfd_boolean has_fixups;
+
+ struct vector_type lp; /* Vector of bfd_vma. */
+ struct vector_type ca; /* Vector of bfd_vma. */
+ struct vector_type qr; /* Vector of struct alpha_vms_vma_ref. */
+};
+
+/* Alpha VMS linker hash table. */
+
+struct alpha_vms_link_hash_table
+{
+ struct bfd_link_hash_table root;
+
+ /* Vector of shared libraries. */
+ struct vector_type shrlibs;
+
+ /* Fixup section. */
+ asection *fixup;
+
+ /* Base address. Used by fixups. */
+ bfd_vma base_addr;
+};
+
+#define alpha_vms_link_hash(INFO) \
+ ((struct alpha_vms_link_hash_table *)(INFO->hash))
+
+/* Alpha VMS linker hash table entry. */
+
+struct alpha_vms_link_hash_entry
+{
+ struct bfd_link_hash_entry root;
+
+ /* Pointer to the original vms symbol. */
+ struct vms_symbol_entry *sym;
+};
+
+/* Image reading. */
+
+/* Read & process EIHD record.
+ Return TRUE on success, FALSE on error. */
+
+static bfd_boolean
+_bfd_vms_slurp_eihd (bfd *abfd, unsigned int *eisd_offset,
+ unsigned int *eihs_offset)
+{
+ unsigned int imgtype, size;
+ bfd_vma symvva;
+ struct vms_eihd *eihd = (struct vms_eihd *)PRIV (recrd.rec);
+
+ vms_debug2 ((8, "_bfd_vms_slurp_eihd\n"));
+
+ size = bfd_getl32 (eihd->size);
+ imgtype = bfd_getl32 (eihd->imgtype);
+
+ if (imgtype == EIHD__K_EXE || imgtype == EIHD__K_LIM)
+ abfd->flags |= EXEC_P;
+
+ symvva = bfd_getl64 (eihd->symvva);
+ if (symvva != 0)
+ {
+ PRIV (symvva) = symvva;
+ abfd->flags |= DYNAMIC;
+ }
+
+ PRIV (ident) = bfd_getl32 (eihd->ident);
+ PRIV (matchctl) = eihd->matchctl;
+
+ *eisd_offset = bfd_getl32 (eihd->isdoff);
+ *eihs_offset = bfd_getl32 (eihd->symdbgoff);
+
+ vms_debug2 ((4, "EIHD size %d imgtype %d symvva 0x%lx eisd %d eihs %d\n",
+ size, imgtype, (unsigned long)symvva,
+ *eisd_offset, *eihs_offset));
+
+ return TRUE;
+}
+
+/* Read & process EISD record.
+ Return TRUE on success, FALSE on error. */
+
+static bfd_boolean
+_bfd_vms_slurp_eisd (bfd *abfd, unsigned int offset)
+{
+ int section_count = 0;
+
+ vms_debug2 ((8, "_bfd_vms_slurp_eisd\n"));
+
+ while (1)
+ {
+ struct vms_eisd *eisd;
+ unsigned int rec_size;
+ unsigned int size;
+ unsigned long long vaddr;
+ unsigned int flags;
+ unsigned int vbn;
+ char *name = NULL;
+ asection *section;
+ flagword bfd_flags;
+
+ eisd = (struct vms_eisd *)(PRIV (recrd.rec) + offset);
+ rec_size = bfd_getl32 (eisd->eisdsize);
+
+ if (rec_size == 0)
+ break;
+
+ /* Skip to next block if pad. */
+ if (rec_size == 0xffffffff)
+ {
+ offset = (offset + VMS_BLOCK_SIZE) & ~(VMS_BLOCK_SIZE - 1);
+ continue;
+ }
+ else
+ offset += rec_size;
+
+ size = bfd_getl32 (eisd->secsize);
+ vaddr = bfd_getl64 (eisd->virt_addr);
+ flags = bfd_getl32 (eisd->flags);
+ vbn = bfd_getl32 (eisd->vbn);
+
+ vms_debug2 ((4, "EISD at 0x%x size 0x%x addr 0x%lx flags 0x%x blk %d\n",
+ offset, size, (unsigned long)vaddr, flags, vbn));
+
+ /* VMS combines psects from .obj files into isects in the .exe. This
+ process doesn't preserve enough information to reliably determine
+ what's in each section without examining the data. This is
+ especially true of DWARF debug sections. */
+ bfd_flags = SEC_ALLOC;
+ if (vbn != 0)
+ bfd_flags |= SEC_HAS_CONTENTS | SEC_LOAD;
+
+ if (flags & EISD__M_EXE)
+ bfd_flags |= SEC_CODE;
+
+ if (flags & EISD__M_NONSHRADR)
+ bfd_flags |= SEC_DATA;
+
+ if (!(flags & EISD__M_WRT))
+ bfd_flags |= SEC_READONLY;
+
+ if (flags & EISD__M_DZRO)
+ bfd_flags |= SEC_DATA;
+
+ if (flags & EISD__M_FIXUPVEC)
+ bfd_flags |= SEC_DATA;
+
+ if (flags & EISD__M_CRF)
+ bfd_flags |= SEC_DATA;
+
+ if (flags & EISD__M_GBL)
+ {
+ name = _bfd_vms_save_counted_string (eisd->gblnam);
+ bfd_flags |= SEC_COFF_SHARED_LIBRARY;
+ bfd_flags &= ~(SEC_ALLOC | SEC_LOAD);
+ }
+ else if (flags & EISD__M_FIXUPVEC)
+ name = "$FIXUPVEC$";
+ else if (eisd->type == EISD__K_USRSTACK)
+ name = "$STACK$";
+ else
+ {
+ const char *pfx;
+
+ name = (char*) bfd_alloc (abfd, 32);
+ if (flags & EISD__M_DZRO)
+ pfx = "BSS";
+ else if (flags & EISD__M_EXE)
+ pfx = "CODE";
+ else if (!(flags & EISD__M_WRT))
+ pfx = "RO";
+ else
+ pfx = "LOCAL";
+ BFD_ASSERT (section_count < 999);
+ sprintf (name, "$%s_%03d$", pfx, section_count++);
+ }
+
+ section = bfd_make_section (abfd, name);
+
+ if (!section)
+ return FALSE;
+
+ section->filepos = vbn ? VMS_BLOCK_SIZE * (vbn - 1) : 0;
+ section->size = size;
+ section->vma = vaddr;
+
+ if (!bfd_set_section_flags (abfd, section, bfd_flags))
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/* Read & process EIHS record.
+ Return TRUE on success, FALSE on error. */
+
+static bfd_boolean
+_bfd_vms_slurp_eihs (bfd *abfd, unsigned int offset)
+{
+ unsigned char *p = PRIV (recrd.rec) + offset;
+ unsigned int gstvbn = bfd_getl32 (p + EIHS__L_GSTVBN);
+ unsigned int gstsize ATTRIBUTE_UNUSED = bfd_getl32 (p + EIHS__L_GSTSIZE);
+ unsigned int dstvbn = bfd_getl32 (p + EIHS__L_DSTVBN);
+ unsigned int dstsize = bfd_getl32 (p + EIHS__L_DSTSIZE);
+ unsigned int dmtvbn = bfd_getl32 (p + EIHS__L_DMTVBN);
+ unsigned int dmtbytes = bfd_getl32 (p + EIHS__L_DMTBYTES);
+ asection *section;
+
+#if VMS_DEBUG
+ vms_debug (8, "_bfd_vms_slurp_ihs\n");
+ vms_debug (4, "EIHS record gstvbn %d gstsize %d dstvbn %d dstsize %d dmtvbn %d dmtbytes %d\n",
+ gstvbn, gstsize, dstvbn, dstsize, dmtvbn, dmtbytes);
+#endif
+
+ if (dstvbn)
+ {
+ flagword bfd_flags = SEC_HAS_CONTENTS | SEC_DEBUGGING;
+
+ section = bfd_make_section (abfd, "$DST$");
+ if (!section)
+ return FALSE;
+
+ section->size = dstsize;
+ section->filepos = VMS_BLOCK_SIZE * (dstvbn - 1);
+
+ if (!bfd_set_section_flags (abfd, section, bfd_flags))
+ return FALSE;
+
+ PRIV (dst_section) = section;
+ abfd->flags |= (HAS_DEBUG | HAS_LINENO);
+ }
+
+ if (dmtvbn)
+ {
+ flagword bfd_flags = SEC_HAS_CONTENTS | SEC_DEBUGGING;
+
+ section = bfd_make_section (abfd, "$DMT$");
+ if (!section)
+ return FALSE;
+
+ section->size = dmtbytes;
+ section->filepos = VMS_BLOCK_SIZE * (dmtvbn - 1);
+
+ if (!bfd_set_section_flags (abfd, section, bfd_flags))
+ return FALSE;
+ }
+
+ if (gstvbn)
+ {
+ if (bfd_seek (abfd, VMS_BLOCK_SIZE * (gstvbn - 1), SEEK_SET))
+ {
+ bfd_set_error (bfd_error_file_truncated);
+ return FALSE;
+ }
+
+ if (_bfd_vms_slurp_object_records (abfd) != TRUE)
+ return FALSE;
+
+ abfd->flags |= HAS_SYMS;
+ }
+
+ return TRUE;
+}
+
+/* Object file reading. */
+
+/* Object file input functions. */
+
+/* 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 size at the first 2 bytes of every record. The same
+ may happen during the transfer of object files from VMS to Unix,
+ at least with UCX, the DEC implementation of TCP/IP.
+
+ The VMS format repeats the size 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:
+ 1. first just the record header is read and the size extracted,
+ 2. then the read buffer is adjusted and the remaining bytes are
+ read in.
+
+ All file I/O is done on even file positions. */
+
+#define VMS_OBJECT_ADJUSTMENT 2
+
+static void
+maybe_adjust_record_pointer_for_object (bfd *abfd)
+{
+ /* Set the file format once for all on the first invocation. */
+ if (PRIV (recrd.file_format) == FF_UNKNOWN)
+ {
+ if (PRIV (recrd.rec)[0] == PRIV (recrd.rec)[4]
+ && PRIV (recrd.rec)[1] == PRIV (recrd.rec)[5])
+ PRIV (recrd.file_format) = FF_FOREIGN;
+ else
+ PRIV (recrd.file_format) = FF_NATIVE;
+ }
+
+ /* The adjustment is needed only in an Unix environment. */
+ if (PRIV (recrd.file_format) == FF_FOREIGN)
+ PRIV (recrd.rec) += VMS_OBJECT_ADJUSTMENT;
+}
+
+/* Implement step #1 of the object record reading procedure.
+ Return the record type or -1 on failure. */
+
+static int
+_bfd_vms_get_object_record (bfd *abfd)
+{
+ unsigned int test_len = 6;
+ int type;
+
+ vms_debug2 ((8, "_bfd_vms_get_obj_record\n"));
+
+ /* Skip alignment byte if the current position is odd. */
+ if (PRIV (recrd.file_format) == FF_FOREIGN && (bfd_tell (abfd) & 1))
+ {
+ if (bfd_bread (PRIV (recrd.buf), 1, abfd) != 1)
+ {
+ bfd_set_error (bfd_error_file_truncated);
+ return -1;
+ }
+ }
+
+ /* Read the record header */
+ if (bfd_bread (PRIV (recrd.buf), test_len, abfd) != test_len)
+ {
+ bfd_set_error (bfd_error_file_truncated);
+ return -1;
+ }
+
+ /* Reset the record pointer. */
+ PRIV (recrd.rec) = PRIV (recrd.buf);
+ maybe_adjust_record_pointer_for_object (abfd);
+
+ if (vms_get_remaining_object_record (abfd, test_len) <= 0)
+ return -1;
+
+ type = bfd_getl16 (PRIV (recrd.rec));
+
+ vms_debug2 ((8, "_bfd_vms_get_obj_record: rec %p, size %d, type %d\n",
+ PRIV (recrd.rec), PRIV (recrd.rec_size), type));
+
+ return type;
+}
+
+/* Implement step #2 of the object record reading procedure.
+ Return the size of the record or 0 on failure. */
+
+static int
+vms_get_remaining_object_record (bfd *abfd, int read_so_far)
+{
+ unsigned int to_read;
+
+ vms_debug2 ((8, "vms_get_remaining_obj_record\n"));
+
+ /* Extract record size. */
+ PRIV (recrd.rec_size) = bfd_getl16 (PRIV (recrd.rec) + 2);
+
+ if (PRIV (recrd.rec_size) == 0)
+ {
+ bfd_set_error (bfd_error_file_truncated);
+ return 0;
+ }
+
+ /* That's what the linker manual says. */
+ if (PRIV (recrd.rec_size) > EOBJ__C_MAXRECSIZ)
+ {
+ bfd_set_error (bfd_error_file_truncated);
+ return 0;
+ }
+
+ /* Take into account object adjustment. */
+ to_read = PRIV (recrd.rec_size);
+ if (PRIV (recrd.file_format) == FF_FOREIGN)
+ to_read += VMS_OBJECT_ADJUSTMENT;
+
+ /* Adjust the buffer. */
+ if (to_read > PRIV (recrd.buf_size))
+ {
+ PRIV (recrd.buf)
+ = (unsigned char *) bfd_realloc (PRIV (recrd.buf), to_read);
+ if (PRIV (recrd.buf) == NULL)
+ return 0;
+ PRIV (recrd.buf_size) = to_read;
+ }
+
+ /* Read the remaining record. */
+ to_read -= read_so_far;
+
+ vms_debug2 ((8, "vms_get_remaining_obj_record: to_read %d\n", to_read));
+
+ if (bfd_bread (PRIV (recrd.buf) + read_so_far, to_read, abfd) != to_read)
+ {
+ bfd_set_error (bfd_error_file_truncated);
+ return 0;
+ }
+
+ /* Reset the record pointer. */
+ PRIV (recrd.rec) = PRIV (recrd.buf);
+ maybe_adjust_record_pointer_for_object (abfd);
+
+ vms_debug2 ((8, "vms_get_remaining_obj_record: size %d\n",
+ PRIV (recrd.rec_size)));
+
+ return PRIV (recrd.rec_size);
+}
+
+/* Read and process emh record.
+ Return TRUE on success, FALSE on error. */
+
+static bfd_boolean
+_bfd_vms_slurp_ehdr (bfd *abfd)
+{
+ unsigned char *ptr;
+ unsigned char *vms_rec;
+ int subtype;
+
+ vms_rec = PRIV (recrd.rec);
+
+ vms_debug2 ((2, "HDR/EMH\n"));
+
+ subtype = bfd_getl16 (vms_rec + 4);
+
+ vms_debug2 ((3, "subtype %d\n", subtype));
+
+ switch (subtype)
+ {
+ case EMH__C_MHD:
+ /* 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__C_LNM:
+ PRIV (hdr_data).hdr_c_lnm =
+ _bfd_vms_save_sized_string (vms_rec, PRIV (recrd.rec_size - 6));
+ break;
+
+ case EMH__C_SRC:
+ PRIV (hdr_data).hdr_c_src =
+ _bfd_vms_save_sized_string (vms_rec, PRIV (recrd.rec_size - 6));
+ break;
+
+ case EMH__C_TTL:
+ PRIV (hdr_data).hdr_c_ttl =
+ _bfd_vms_save_sized_string (vms_rec, PRIV (recrd.rec_size - 6));
+ break;
+
+ case EMH__C_CPR:
+ case EMH__C_MTC:
+ case EMH__C_GTX:
+ break;
+
+ default:
+ bfd_set_error (bfd_error_wrong_format);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/* 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_LITERALS_NAME "$LITERALS"
+#define EVAX_COMMON_NAME "$COMMON$"
+#define EVAX_LOCAL_NAME "$LOCAL$"
+
+struct sec_flags_struct
+{
+ const 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 Alpha) compatible. */
+
+static const struct sec_flags_struct evax_section_flags[] =
+ {
+ { EVAX_ABS_NAME,
+ EGPS__V_SHR,
+ 0,
+ EGPS__V_SHR,
+ 0 },
+ { EVAX_CODE_NAME,
+ EGPS__V_PIC | EGPS__V_REL | EGPS__V_SHR | EGPS__V_EXE,
+ SEC_CODE | SEC_READONLY,
+ EGPS__V_PIC | EGPS__V_REL | EGPS__V_SHR | EGPS__V_EXE,
+ SEC_CODE | SEC_READONLY | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD },
+ { EVAX_LITERAL_NAME,
+ EGPS__V_PIC | EGPS__V_REL | EGPS__V_SHR | EGPS__V_RD | EGPS__V_NOMOD,
+ SEC_DATA | SEC_READONLY,
+ EGPS__V_PIC | EGPS__V_REL | EGPS__V_SHR | EGPS__V_RD,
+ SEC_DATA | SEC_READONLY | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD },
+ { EVAX_LINK_NAME,
+ EGPS__V_REL | EGPS__V_RD,
+ SEC_DATA | SEC_READONLY,
+ EGPS__V_REL | EGPS__V_RD,
+ SEC_DATA | SEC_READONLY | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD },
+ { EVAX_DATA_NAME,
+ EGPS__V_REL | EGPS__V_RD | EGPS__V_WRT | EGPS__V_NOMOD,
+ SEC_DATA,
+ EGPS__V_REL | EGPS__V_RD | EGPS__V_WRT,
+ SEC_DATA | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD },
+ { EVAX_BSS_NAME,
+ EGPS__V_REL | EGPS__V_RD | EGPS__V_WRT | EGPS__V_NOMOD,
+ SEC_NO_FLAGS,
+ EGPS__V_REL | EGPS__V_RD | EGPS__V_WRT | EGPS__V_NOMOD,
+ SEC_ALLOC },
+ { EVAX_READONLYADDR_NAME,
+ EGPS__V_PIC | EGPS__V_REL | EGPS__V_RD,
+ SEC_DATA | SEC_READONLY,
+ EGPS__V_PIC | EGPS__V_REL | EGPS__V_RD,
+ SEC_DATA | SEC_READONLY | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD },
+ { EVAX_READONLY_NAME,
+ EGPS__V_PIC | EGPS__V_REL | EGPS__V_SHR | EGPS__V_RD | EGPS__V_NOMOD,
+ SEC_DATA | SEC_READONLY,
+ EGPS__V_PIC | EGPS__V_REL | EGPS__V_SHR | EGPS__V_RD,
+ SEC_DATA | SEC_READONLY | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD },
+ { EVAX_LOCAL_NAME,
+ EGPS__V_REL | EGPS__V_RD | EGPS__V_WRT,
+ SEC_DATA,
+ EGPS__V_REL | EGPS__V_RD | EGPS__V_WRT,
+ SEC_DATA | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD },
+ { EVAX_LITERALS_NAME,
+ EGPS__V_PIC | EGPS__V_OVR,
+ SEC_DATA | SEC_READONLY,
+ EGPS__V_PIC | EGPS__V_OVR,
+ SEC_DATA | SEC_READONLY | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD },
+ { NULL,
+ EGPS__V_REL | EGPS__V_RD | EGPS__V_WRT,
+ SEC_DATA,
+ EGPS__V_REL | EGPS__V_RD | EGPS__V_WRT,
+ SEC_DATA | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD }
+ };
+
+/* Retrieve BFD section flags by name and size. */
+
+static flagword
+vms_secflag_by_name (const struct sec_flags_struct *section_flags,
+ const char *name,
+ int hassize)
+{
+ int i = 0;
+
+ while (section_flags[i].name != NULL)
+ {
+ if (strcmp (name, section_flags[i].name) == 0)
+ {
+ if (hassize)
+ return section_flags[i].flags_hassize;
+ else
+ return section_flags[i].flags_always;
+ }
+ i++;
+ }
+ if (hassize)
+ 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 (const struct sec_flags_struct *section_flags,
+ const char *name,
+ int hassize)
+{
+ int i = 0;
+
+ while (section_flags[i].name != NULL)
+ {
+ if (strcmp (name, section_flags[i].name) == 0)
+ {
+ if (hassize)
+ return section_flags[i].vflags_hassize;
+ else
+ return section_flags[i].vflags_always;
+ }
+ i++;
+ }
+ if (hassize)
+ return section_flags[i].vflags_hassize;
+ return section_flags[i].vflags_always;
+}
+
+/* Add SYM to the symbol table of ABFD.
+ Return FALSE in case of error. */
+
+static bfd_boolean
+add_symbol_entry (bfd *abfd, struct vms_symbol_entry *sym)
+{
+ if (PRIV (gsd_sym_count) >= PRIV (max_sym_count))
+ {
+ if (PRIV (max_sym_count) == 0)
+ {
+ PRIV (max_sym_count) = 128;
+ PRIV (syms) = bfd_malloc
+ (PRIV (max_sym_count) * sizeof (struct vms_symbol_entry *));
+ }
+ else
+ {
+ PRIV (max_sym_count) *= 2;
+ PRIV (syms) = bfd_realloc
+ (PRIV (syms),
+ (PRIV (max_sym_count) * sizeof (struct vms_symbol_entry *)));
+ }
+ if (PRIV (syms) == NULL)
+ return FALSE;
+ }
+
+ PRIV (syms)[PRIV (gsd_sym_count)++] = sym;
+ return TRUE;
+}
+
+/* Create a symbol whose name is ASCIC and add it to ABFD.
+ Return NULL in case of error. */
+
+static struct vms_symbol_entry *
+add_symbol (bfd *abfd, const unsigned char *ascic)
+{
+ struct vms_symbol_entry *entry;
+ int len;
+
+ len = *ascic++;
+ entry = (struct vms_symbol_entry *)bfd_zalloc (abfd, sizeof (*entry) + len);
+ if (entry == NULL)
+ return NULL;
+ entry->namelen = len;
+ memcpy (entry->name, ascic, len);
+ entry->name[len] = 0;
+ entry->owner = abfd;
+
+ if (!add_symbol_entry (abfd, entry))
+ return NULL;
+ return entry;
+}
+
+/* Read and process EGSD. Return FALSE on failure. */
+
+static bfd_boolean
+_bfd_vms_slurp_egsd (bfd *abfd)
+{
+ int gsd_type, gsd_size;
+ unsigned char *vms_rec;
+ unsigned long base_addr;
+
+ vms_debug2 ((2, "EGSD\n"));
+
+ PRIV (recrd.rec) += 8; /* Skip type, size, align pad. */
+ PRIV (recrd.rec_size) -= 8;
+
+ /* Calculate base address for each section. */
+ base_addr = 0L;
+
+ while (PRIV (recrd.rec_size) > 0)
+ {
+ vms_rec = PRIV (recrd.rec);
+
+ gsd_type = bfd_getl16 (vms_rec);
+ gsd_size = bfd_getl16 (vms_rec + 2);
+
+ vms_debug2 ((3, "egsd_type %d\n", gsd_type));
+
+ switch (gsd_type)
+ {
+ case EGSD__C_PSC:
+ /* Program section definition. */
+ {
+ struct vms_egps *egps = (struct vms_egps *)vms_rec;
+ flagword new_flags, vms_flags;
+ asection *section;
+
+ vms_flags = bfd_getl16 (egps->flags);
+
+ if ((vms_flags & EGPS__V_REL) == 0)
+ {
+ /* Use the global absolute section for all
+ absolute sections. */
+ section = bfd_abs_section_ptr;
+ }
+ else
+ {
+ char *name;
+ unsigned long align_addr;
+
+ name = _bfd_vms_save_counted_string (&egps->namlng);
+
+ section = bfd_make_section (abfd, name);
+ if (!section)
+ return FALSE;
+
+ section->filepos = 0;
+ section->size = bfd_getl32 (egps->alloc);
+ section->alignment_power = egps->align;
+
+ vms_section_data (section)->flags = vms_flags;
+ vms_section_data (section)->no_flags = 0;
+
+ new_flags = vms_secflag_by_name (evax_section_flags, name,
+ section->size > 0);
+ if (section->size > 0)
+ new_flags |= SEC_LOAD;
+ if (!(vms_flags & EGPS__V_NOMOD) && section->size > 0)
+ {
+ /* Set RELOC and HAS_CONTENTS if the section is not
+ demand-zero and not empty. */
+ new_flags |= SEC_HAS_CONTENTS;
+ if (vms_flags & EGPS__V_REL)
+ new_flags |= SEC_RELOC;
+ }
+ if (vms_flags & EGPS__V_EXE)
+ {
+ /* Set CODE if section is executable. */
+ new_flags |= SEC_CODE;
+ new_flags &= ~SEC_DATA;
+ }
+ if (!bfd_set_section_flags (abfd, section, new_flags))
+ return FALSE;
+
+ /* Give a non-overlapping vma to non absolute sections. */
+ 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->size;
+ }
+
+ /* Append it to the section array. */
+ if (PRIV (section_count) >= PRIV (section_max))
+ {
+ if (PRIV (section_max) == 0)
+ PRIV (section_max) = 16;
+ else
+ PRIV (section_max) *= 2;
+ PRIV (sections) = bfd_realloc_or_free
+ (PRIV (sections), PRIV (section_max) * sizeof (asection *));
+ if (PRIV (sections) == NULL)
+ return FALSE;
+ }
+
+ PRIV (sections)[PRIV (section_count)] = section;
+ PRIV (section_count)++;
+ }
+ break;
+
+ case EGSD__C_SYM:
+ {
+ int nameoff;
+ struct vms_symbol_entry *entry;
+ struct vms_egsy *egsy = (struct vms_egsy *) vms_rec;
+ flagword old_flags;
+
+ old_flags = bfd_getl16 (egsy->flags);
+ if (old_flags & EGSY__V_DEF)
+ nameoff = ESDF__B_NAMLNG;
+ else
+ nameoff = ESRF__B_NAMLNG;
+
+ entry = add_symbol (abfd, vms_rec + nameoff);
+ if (entry == NULL)
+ return FALSE;
+
+ /* Allow only duplicate reference. */
+ if ((entry->flags & EGSY__V_DEF) && (old_flags & EGSY__V_DEF))
+ abort ();
+
+ if (entry->typ == 0)
+ {
+ entry->typ = gsd_type;
+ entry->data_type = egsy->datyp;
+ entry->flags = old_flags;
+ }
+
+ if (old_flags & EGSY__V_DEF)
+ {
+ struct vms_esdf *esdf = (struct vms_esdf *)vms_rec;
+
+ entry->value = bfd_getl64 (esdf->value);
+ entry->section = PRIV (sections)[bfd_getl32 (esdf->psindx)];
+
+ if (old_flags & EGSY__V_NORM)
+ {
+ PRIV (norm_sym_count)++;
+
+ entry->code_value = bfd_getl64 (esdf->code_address);
+ entry->code_section =
+ PRIV (sections)[bfd_getl32 (esdf->ca_psindx)];
+ }
+ }
+ }
+ break;
+
+ case EGSD__C_SYMG:
+ {
+ struct vms_symbol_entry *entry;
+ struct vms_egst *egst = (struct vms_egst *)vms_rec;
+ flagword old_flags;
+
+ old_flags = bfd_getl16 (egst->header.flags);
+
+ entry = add_symbol (abfd, &egst->namlng);
+
+ if (entry == NULL)
+ return FALSE;
+
+ entry->typ = gsd_type;
+ entry->data_type = egst->header.datyp;
+ entry->flags = old_flags;
+
+ entry->symbol_vector = bfd_getl32 (egst->value);
+
+ if (old_flags & EGSY__V_REL)
+ entry->section = PRIV (sections)[bfd_getl32 (egst->psindx)];
+ else
+ entry->section = bfd_abs_section_ptr;
+
+ entry->value = bfd_getl64 (egst->lp_2);
+
+ if (old_flags & EGSY__V_NORM)
+ {
+ PRIV (norm_sym_count)++;
+
+ entry->code_value = bfd_getl64 (egst->lp_1);
+ entry->code_section = bfd_abs_section_ptr;
+ }
+ }
+ break;
+
+ case EGSD__C_SPSC:
+ case EGSD__C_IDC:
+ /* Currently ignored. */
+ break;
+ case EGSD__C_SYMM:
+ case EGSD__C_SYMV:
+ default:
+ (*_bfd_error_handler) (_("Unknown EGSD subtype %d"), gsd_type);
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+
+ PRIV (recrd.rec_size) -= gsd_size;
+ PRIV (recrd.rec) += gsd_size;
+ }
+
+ if (PRIV (gsd_sym_count) > 0)
+ abfd->flags |= HAS_SYMS;
+
+ return TRUE;
+}
+
+/* Stack routines for vms ETIR commands. */
+
+/* Push value and section index. */
+
+static void
+_bfd_vms_push (bfd *abfd, bfd_vma val, unsigned int reloc)
+{
+ vms_debug2 ((4, "<push %08lx (0x%08x) at %d>\n",
+ (unsigned long)val, reloc, PRIV (stackptr)));
+
+ PRIV (stack[PRIV (stackptr)]).value = val;
+ PRIV (stack[PRIV (stackptr)]).reloc = reloc;
+ 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);
+ }
+}
+
+/* Pop value and section index. */
+
+static void
+_bfd_vms_pop (bfd *abfd, bfd_vma *val, unsigned int *rel)
+{
+ if (PRIV (stackptr) == 0)
+ {
+ bfd_set_error (bfd_error_bad_value);
+ (*_bfd_error_handler) (_("Stack underflow in _bfd_vms_pop"));
+ exit (1);
+ }
+ PRIV (stackptr)--;
+ *val = PRIV (stack[PRIV (stackptr)]).value;
+ *rel = PRIV (stack[PRIV (stackptr)]).reloc;
+
+ vms_debug2 ((4, "<pop %08lx (0x%08x)>\n", (unsigned long)*val, *rel));
+}
+
+/* Routines to fill sections contents during tir/etir read. */
+
+/* Initialize image buffer pointer to be filled. */
+
+static void
+image_set_ptr (bfd *abfd, bfd_vma vma, int sect, struct bfd_link_info *info)
+{
+ asection *sec;
+
+ vms_debug2 ((4, "image_set_ptr (0x%08x, sect=%d)\n", (unsigned)vma, sect));
+
+ sec = PRIV (sections)[sect];
+
+ if (info)
+ {
+ /* Reading contents to an output bfd. */
+
+ if (sec->output_section == NULL)
+ {
+ /* Section discarded. */
+ vms_debug2 ((5, " section %s discarded\n", sec->name));
+
+ /* This is not used. */
+ PRIV (image_section) = NULL;
+ PRIV (image_offset) = 0;
+ return;
+ }
+ PRIV (image_offset) = sec->output_offset + vma;
+ PRIV (image_section) = sec->output_section;
+ }
+ else
+ {
+ PRIV (image_offset) = vma;
+ PRIV (image_section) = sec;
+ }
+}
+
+/* Increment image buffer pointer by offset. */
+
+static void
+image_inc_ptr (bfd *abfd, bfd_vma offset)
+{
+ vms_debug2 ((4, "image_inc_ptr (%u)\n", (unsigned)offset));
+
+ PRIV (image_offset) += offset;
+}
+
+/* Save current DST location counter under specified index. */
+
+static void
+dst_define_location (bfd *abfd, unsigned int loc)
+{
+ vms_debug2 ((4, "dst_define_location (%d)\n", (int)loc));
+
+ /* Grow the ptr offset table if necessary. */
+ if (loc + 1 > PRIV (dst_ptr_offsets_count))
+ {
+ PRIV (dst_ptr_offsets) = bfd_realloc (PRIV (dst_ptr_offsets),
+ (loc + 1) * sizeof (unsigned int));
+ PRIV (dst_ptr_offsets_count) = loc + 1;
+ }
+
+ PRIV (dst_ptr_offsets)[loc] = PRIV (image_offset);
+}
+
+/* Restore saved DST location counter from specified index. */
+
+static void
+dst_restore_location (bfd *abfd, unsigned int loc)
+{
+ vms_debug2 ((4, "dst_restore_location (%d)\n", (int)loc));
+
+ PRIV (image_offset) = PRIV (dst_ptr_offsets)[loc];
+}
+
+/* Retrieve saved DST location counter from specified index. */
+
+static unsigned int
+dst_retrieve_location (bfd *abfd, unsigned int loc)
+{
+ vms_debug2 ((4, "dst_retrieve_location (%d)\n", (int)loc));
+
+ return PRIV (dst_ptr_offsets)[loc];
+}
+
+/* Write multiple bytes to section image. */
+
+static bfd_boolean
+image_write (bfd *abfd, unsigned char *ptr, int size)
+{
+#if VMS_DEBUG
+ _bfd_vms_debug (8, "image_write from (%p, %d) to (%ld)\n", ptr, size,
+ (long)PRIV (image_offset));
+ _bfd_hexdump (9, ptr, size, 0);
+#endif
+
+ if (PRIV (image_section)->contents != NULL)
+ {
+ asection *sec = PRIV (image_section);
+ file_ptr off = PRIV (image_offset);
+
+ /* Check bounds. */
+ if (off > (file_ptr)sec->size
+ || size > (file_ptr)sec->size
+ || off + size > (file_ptr)sec->size)
+ {
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+
+ memcpy (sec->contents + off, ptr, size);
+ }
+
+ PRIV (image_offset) += size;
+ return TRUE;
+}
+
+/* Write byte to section image. */
+
+static bfd_boolean
+image_write_b (bfd * abfd, unsigned int value)
+{
+ unsigned char data[1];
+
+ vms_debug2 ((6, "image_write_b (%02x)\n", (int) value));
+
+ *data = value;
+
+ return image_write (abfd, data, sizeof (data));
+}
+
+/* Write 2-byte word to image. */
+
+static bfd_boolean
+image_write_w (bfd * abfd, unsigned int value)
+{
+ unsigned char data[2];
+
+ vms_debug2 ((6, "image_write_w (%04x)\n", (int) value));
+
+ bfd_putl16 (value, data);
+ return image_write (abfd, data, sizeof (data));
+}
+
+/* Write 4-byte long to image. */
+
+static bfd_boolean
+image_write_l (bfd * abfd, unsigned long value)
+{
+ unsigned char data[4];
+
+ vms_debug2 ((6, "image_write_l (%08lx)\n", value));
+
+ bfd_putl32 (value, data);
+ return image_write (abfd, data, sizeof (data));
+}
+
+/* Write 8-byte quad to image. */
+
+static bfd_boolean
+image_write_q (bfd * abfd, bfd_vma value)
+{
+ unsigned char data[8];
+
+ vms_debug2 ((6, "image_write_q (%08lx)\n", (unsigned long)value));
+
+ bfd_putl64 (value, data);
+ return image_write (abfd, data, sizeof (data));
+}
+
+static const char *
+_bfd_vms_etir_name (int cmd)
+{
+ switch (cmd)
+ {
+ case ETIR__C_STA_GBL: return "ETIR__C_STA_GBL";
+ case ETIR__C_STA_LW: return "ETIR__C_STA_LW";
+ case ETIR__C_STA_QW: return "ETIR__C_STA_QW";
+ case ETIR__C_STA_PQ: return "ETIR__C_STA_PQ";
+ case ETIR__C_STA_LI: return "ETIR__C_STA_LI";
+ case ETIR__C_STA_MOD: return "ETIR__C_STA_MOD";
+ case ETIR__C_STA_CKARG: return "ETIR__C_STA_CKARG";
+ case ETIR__C_STO_B: return "ETIR__C_STO_B";
+ case ETIR__C_STO_W: return "ETIR__C_STO_W";
+ case ETIR__C_STO_GBL: return "ETIR__C_STO_GBL";
+ case ETIR__C_STO_CA: return "ETIR__C_STO_CA";
+ case ETIR__C_STO_RB: return "ETIR__C_STO_RB";
+ case ETIR__C_STO_AB: return "ETIR__C_STO_AB";
+ case ETIR__C_STO_OFF: return "ETIR__C_STO_OFF";
+ case ETIR__C_STO_IMM: return "ETIR__C_STO_IMM";
+ case ETIR__C_STO_IMMR: return "ETIR__C_STO_IMMR";
+ case ETIR__C_STO_LW: return "ETIR__C_STO_LW";
+ case ETIR__C_STO_QW: return "ETIR__C_STO_QW";
+ case ETIR__C_STO_GBL_LW: return "ETIR__C_STO_GBL_LW";
+ case ETIR__C_STO_LP_PSB: return "ETIR__C_STO_LP_PSB";
+ case ETIR__C_STO_HINT_GBL: return "ETIR__C_STO_HINT_GBL";
+ case ETIR__C_STO_HINT_PS: return "ETIR__C_STO_HINT_PS";
+ case ETIR__C_OPR_ADD: return "ETIR__C_OPR_ADD";
+ case ETIR__C_OPR_SUB: return "ETIR__C_OPR_SUB";
+ case ETIR__C_OPR_INSV: return "ETIR__C_OPR_INSV";
+ case ETIR__C_OPR_USH: return "ETIR__C_OPR_USH";
+ case ETIR__C_OPR_ROT: return "ETIR__C_OPR_ROT";
+ case ETIR__C_OPR_REDEF: return "ETIR__C_OPR_REDEF";
+ case ETIR__C_OPR_DFLIT: return "ETIR__C_OPR_DFLIT";
+ case ETIR__C_STC_LP: return "ETIR__C_STC_LP";
+ case ETIR__C_STC_GBL: return "ETIR__C_STC_GBL";
+ case ETIR__C_STC_GCA: return "ETIR__C_STC_GCA";
+ case ETIR__C_STC_PS: return "ETIR__C_STC_PS";
+ case ETIR__C_STC_NBH_PS: return "ETIR__C_STC_NBH_PS";
+ case ETIR__C_STC_NOP_GBL: return "ETIR__C_STC_NOP_GBL";
+ case ETIR__C_STC_NOP_PS: return "ETIR__C_STC_NOP_PS";
+ case ETIR__C_STC_BSR_GBL: return "ETIR__C_STC_BSR_GBL";
+ case ETIR__C_STC_BSR_PS: return "ETIR__C_STC_BSR_PS";
+ case ETIR__C_STC_LDA_GBL: return "ETIR__C_STC_LDA_GBL";
+ case ETIR__C_STC_LDA_PS: return "ETIR__C_STC_LDA_PS";
+ case ETIR__C_STC_BOH_GBL: return "ETIR__C_STC_BOH_GBL";
+ case ETIR__C_STC_BOH_PS: return "ETIR__C_STC_BOH_PS";
+ case ETIR__C_STC_NBH_GBL: return "ETIR__C_STC_NBH_GBL";
+ case ETIR__C_STC_LP_PSB: return "ETIR__C_STC_LP_PSB";
+ case ETIR__C_CTL_SETRB: return "ETIR__C_CTL_SETRB";
+ case ETIR__C_CTL_AUGRB: return "ETIR__C_CTL_AUGRB";
+ case ETIR__C_CTL_DFLOC: return "ETIR__C_CTL_DFLOC";
+ case ETIR__C_CTL_STLOC: return "ETIR__C_CTL_STLOC";
+ case ETIR__C_CTL_STKDL: return "ETIR__C_CTL_STKDL";
+
+ default:
+ /* These names have not yet been added to this switch statement. */
+ (*_bfd_error_handler) (_("unknown ETIR command %d"), cmd);
+ }
+
+ return NULL;
+}
+#define HIGHBIT(op) ((op & 0x80000000L) == 0x80000000L)
+
+static void
+_bfd_vms_get_value (bfd *abfd, const unsigned char *ascic,
+ struct bfd_link_info *info,
+ bfd_vma *vma,
+ struct alpha_vms_link_hash_entry **hp)
+{
+ char name[257];
+ int len;
+ int i;
+ struct alpha_vms_link_hash_entry *h;
+
+ /* Not linking. Do not try to resolve the symbol. */
+ if (info == NULL)
+ {
+ *vma = 0;
+ *hp = NULL;
+ return;
+ }
+
+ len = *ascic;
+ for (i = 0; i < len; i++)
+ name[i] = ascic[i + 1];
+ name[i] = 0;
+
+ h = (struct alpha_vms_link_hash_entry *)
+ bfd_link_hash_lookup (info->hash, name, FALSE, FALSE, TRUE);
+
+ *hp = h;
+
+ if (h != NULL
+ && (h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak))
+ *vma = h->root.u.def.value
+ + h->root.u.def.section->output_offset
+ + h->root.u.def.section->output_section->vma;
+ else if (h && h->root.type == bfd_link_hash_undefweak)
+ *vma = 0;
+ else
+ {
+ if (!(*info->callbacks->undefined_symbol)
+ (info, name, abfd, PRIV (image_section), PRIV (image_offset), TRUE))
+ abort ();
+ *vma = 0;
+ }
+}
+
+#define RELC_NONE 0
+#define RELC_REL 1
+#define RELC_SHR_BASE 0x10000
+#define RELC_SEC_BASE 0x20000
+#define RELC_MASK 0x0ffff
+
+static unsigned int
+alpha_vms_sym_to_ctxt (struct alpha_vms_link_hash_entry *h)
+{
+ /* Handle undefined symbols. */
+ if (h == NULL || h->sym == NULL)
+ return RELC_NONE;
+
+ if (h->sym->typ == EGSD__C_SYMG)
+ {
+ if (h->sym->flags & EGSY__V_REL)
+ return RELC_SHR_BASE + PRIV2 (h->sym->owner, shr_index);
+ else
+ {
+ /* Can this happen (non-relocatable symg) ? I'd like to see
+ an example. */
+ abort ();
+ }
+ }
+ if (h->sym->typ == EGSD__C_SYM)
+ {
+ if (h->sym->flags & EGSY__V_REL)
+ return RELC_REL;
+ else
+ return RELC_NONE;
+ }
+ abort ();
+}
+
+static bfd_vma
+alpha_vms_get_sym_value (asection *sect, bfd_vma addr)
+{
+ return sect->output_section->vma + sect->output_offset + addr;
+}
+
+static bfd_vma
+alpha_vms_fix_sec_rel (bfd *abfd, struct bfd_link_info *info,
+ unsigned int rel, bfd_vma vma)
+{
+ asection *sec = PRIV (sections)[rel & RELC_MASK];
+
+ if (info)
+ {
+ if (sec->output_section == NULL)
+ abort ();
+ return vma + sec->output_section->vma + sec->output_offset;
+ }
+ else
+ return vma + sec->vma;
+}
+
+/* Read an ETIR record from ABFD. If INFO is not null, put the content into
+ the output section (used during linking).
+ Return FALSE in case of error. */
+
+static bfd_boolean
+_bfd_vms_slurp_etir (bfd *abfd, struct bfd_link_info *info)
+{
+ unsigned char *ptr;
+ unsigned int length;
+ unsigned char *maxptr;
+ bfd_vma op1;
+ bfd_vma op2;
+ unsigned int rel1;
+ unsigned int rel2;
+ struct alpha_vms_link_hash_entry *h;
+
+ PRIV (recrd.rec) += ETIR__C_HEADER_SIZE;
+ PRIV (recrd.rec_size) -= ETIR__C_HEADER_SIZE;
+
+ ptr = PRIV (recrd.rec);
+ length = PRIV (recrd.rec_size);
+ maxptr = ptr + length;
+
+ vms_debug2 ((2, "ETIR: %d bytes\n", length));
+
+ while (ptr < maxptr)
+ {
+ int cmd = bfd_getl16 (ptr);
+ int cmd_length = bfd_getl16 (ptr + 2);
+
+ ptr += 4;
+
+#if VMS_DEBUG
+ _bfd_vms_debug (4, "etir: %s(%d)\n",
+ _bfd_vms_etir_name (cmd), cmd);
+ _bfd_hexdump (8, ptr, cmd_length - 4, 0);
+#endif
+
+ switch (cmd)
+ {
+ /* Stack global
+ arg: cs symbol name
+
+ stack 32 bit value of symbol (high bits set to 0). */
+ case ETIR__C_STA_GBL:
+ _bfd_vms_get_value (abfd, ptr, info, &op1, &h);
+ _bfd_vms_push (abfd, op1, alpha_vms_sym_to_ctxt (h));
+ break;
+
+ /* Stack longword
+ arg: lw value
+
+ stack 32 bit value, sign extend to 64 bit. */
+ case ETIR__C_STA_LW:
+ _bfd_vms_push (abfd, bfd_getl32 (ptr), RELC_NONE);
+ break;
+
+ /* Stack quadword
+ arg: qw value
+
+ stack 64 bit value of symbol. */
+ case ETIR__C_STA_QW:
+ _bfd_vms_push (abfd, bfd_getl64 (ptr), RELC_NONE);
+ 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__C_STO_OFF, ETIR__C_CTL_SETRB). */
+ case ETIR__C_STA_PQ:
+ {
+ int psect;
+
+ psect = bfd_getl32 (ptr);
+ if ((unsigned int) psect >= PRIV (section_count))
+ {
+ (*_bfd_error_handler) (_("bad section index in %s"),
+ _bfd_vms_etir_name (cmd));
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+ op1 = bfd_getl64 (ptr + 4);
+ _bfd_vms_push (abfd, op1, psect | RELC_SEC_BASE);
+ }
+ break;
+
+ case ETIR__C_STA_LI:
+ case ETIR__C_STA_MOD:
+ case ETIR__C_STA_CKARG:
+ (*_bfd_error_handler) (_("unsupported STA cmd %s"),
+ _bfd_vms_etir_name (cmd));
+ return FALSE;
+ break;
+
+ /* Store byte: pop stack, write byte
+ arg: -. */
+ case ETIR__C_STO_B:
+ _bfd_vms_pop (abfd, &op1, &rel1);
+ if (rel1 != RELC_NONE)
+ goto bad_context;
+ image_write_b (abfd, (unsigned int) op1 & 0xff);
+ break;
+
+ /* Store word: pop stack, write word
+ arg: -. */
+ case ETIR__C_STO_W:
+ _bfd_vms_pop (abfd, &op1, &rel1);
+ if (rel1 != RELC_NONE)
+ goto bad_context;
+ image_write_w (abfd, (unsigned int) op1 & 0xffff);
+ break;
+
+ /* Store longword: pop stack, write longword
+ arg: -. */
+ case ETIR__C_STO_LW:
+ _bfd_vms_pop (abfd, &op1, &rel1);
+ if (rel1 & RELC_SEC_BASE)
+ {
+ op1 = alpha_vms_fix_sec_rel (abfd, info, rel1, op1);
+ rel1 = RELC_REL;
+ }
+ else if (rel1 & RELC_SHR_BASE)
+ {
+ alpha_vms_add_fixup_lr (info, rel1 & RELC_MASK, op1);
+ rel1 = RELC_NONE;
+ }
+ if (rel1 != RELC_NONE)
+ {
+ if (rel1 != RELC_REL)
+ abort ();
+ alpha_vms_add_lw_reloc (info);
+ }
+ image_write_l (abfd, op1);
+ break;
+
+ /* Store quadword: pop stack, write quadword
+ arg: -. */
+ case ETIR__C_STO_QW:
+ _bfd_vms_pop (abfd, &op1, &rel1);
+ if (rel1 & RELC_SEC_BASE)
+ {
+ op1 = alpha_vms_fix_sec_rel (abfd, info, rel1, op1);
+ rel1 = RELC_REL;
+ }
+ else if (rel1 & RELC_SHR_BASE)
+ abort ();
+ if (rel1 != RELC_NONE)
+ {
+ if (rel1 != RELC_REL)
+ abort ();
+ alpha_vms_add_qw_reloc (info);
+ }
+ image_write_q (abfd, op1);
+ break;
+
+ /* Store immediate repeated: pop stack for repeat count
+ arg: lw byte count
+ da data. */
+ case ETIR__C_STO_IMMR:
+ {
+ int size;
+
+ size = bfd_getl32 (ptr);
+ _bfd_vms_pop (abfd, &op1, &rel1);
+ if (rel1 != RELC_NONE)
+ goto bad_context;
+ while (op1-- > 0)
+ image_write (abfd, ptr + 4, size);
+ }
+ break;
+
+ /* Store global: write symbol value
+ arg: cs global symbol name. */
+ case ETIR__C_STO_GBL:
+ _bfd_vms_get_value (abfd, ptr, info, &op1, &h);
+ if (h && h->sym)
+ {
+ if (h->sym->typ == EGSD__C_SYMG)
+ {
+ alpha_vms_add_fixup_qr
+ (info, abfd, h->sym->owner, h->sym->symbol_vector);
+ op1 = 0;
+ }
+ else
+ {
+ op1 = alpha_vms_get_sym_value (h->sym->section,
+ h->sym->value);
+ alpha_vms_add_qw_reloc (info);
+ }
+ }
+ image_write_q (abfd, op1);
+ break;
+
+ /* Store code address: write address of entry point
+ arg: cs global symbol name (procedure). */
+ case ETIR__C_STO_CA:
+ _bfd_vms_get_value (abfd, ptr, info, &op1, &h);
+ if (h && h->sym)
+ {
+ if (h->sym->flags & EGSY__V_NORM)
+ {
+ /* That's really a procedure. */
+ if (h->sym->typ == EGSD__C_SYMG)
+ {
+ alpha_vms_add_fixup_ca (info, abfd, h->sym->owner);
+ op1 = h->sym->symbol_vector;
+ }
+ else
+ {
+ op1 = alpha_vms_get_sym_value (h->sym->code_section,
+ h->sym->code_value);
+ alpha_vms_add_qw_reloc (info);
+ }
+ }
+ else
+ {
+ /* Symbol is not a procedure. */
+ abort ();
+ }
+ }
+ image_write_q (abfd, op1);
+ break;
+
+ /* Store offset to psect: pop stack, add low 32 bits to base of psect
+ arg: none. */
+ case ETIR__C_STO_OFF:
+ _bfd_vms_pop (abfd, &op1, &rel1);
+
+ if (!(rel1 & RELC_SEC_BASE))
+ abort ();
+
+ op1 = alpha_vms_fix_sec_rel (abfd, info, rel1, op1);
+ rel1 = RELC_REL;
+ image_write_q (abfd, op1);
+ break;
+
+ /* Store immediate
+ arg: lw count of bytes
+ da data. */
+ case ETIR__C_STO_IMM:
+ {
+ int size;
+
+ size = bfd_getl32 (ptr);
+ image_write (abfd, ptr + 4, size);
+ }
+ 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__C_STO_GBL_LW:
+ _bfd_vms_get_value (abfd, ptr, info, &op1, &h);
+#if 0
+ abort ();
+#endif
+ image_write_l (abfd, op1);
+ break;
+
+ case ETIR__C_STO_RB:
+ case ETIR__C_STO_AB:
+ case ETIR__C_STO_LP_PSB:
+ (*_bfd_error_handler) (_("%s: not supported"),
+ _bfd_vms_etir_name (cmd));
+ return FALSE;
+ break;
+ case ETIR__C_STO_HINT_GBL:
+ case ETIR__C_STO_HINT_PS:
+ (*_bfd_error_handler) (_("%s: not implemented"),
+ _bfd_vms_etir_name (cmd));
+ return FALSE;
+ break;
+
+ /* 200 Store-conditional Linkage Pair
+ arg: none. */
+ case ETIR__C_STC_LP:
+
+ /* 202 Store-conditional Address at global address
+ lw linkage index
+ cs global name. */
+
+ case ETIR__C_STC_GBL:
+
+ /* 203 Store-conditional Code Address at global address
+ lw linkage index
+ cs procedure name. */
+ case ETIR__C_STC_GCA:
+
+ /* 204 Store-conditional Address at psect + offset
+ lw linkage index
+ lw psect index
+ qw offset. */
+ case ETIR__C_STC_PS:
+ (*_bfd_error_handler) (_("%s: not supported"),
+ _bfd_vms_etir_name (cmd));
+ return FALSE;
+ break;
+
+ /* 201 Store-conditional Linkage Pair with Procedure Signature
+ lw linkage index
+ cs procedure name
+ by signature length
+ da signature. */
+
+ case ETIR__C_STC_LP_PSB:
+ _bfd_vms_get_value (abfd, ptr + 4, info, &op1, &h);
+ if (h && h->sym)
+ {
+ if (h->sym->typ == EGSD__C_SYMG)
+ {
+ alpha_vms_add_fixup_lp (info, abfd, h->sym->owner);
+ op1 = h->sym->symbol_vector;
+ op2 = 0;
+ }
+ else
+ {
+ op1 = alpha_vms_get_sym_value (h->sym->code_section,
+ h->sym->code_value);
+ op2 = alpha_vms_get_sym_value (h->sym->section,
+ h->sym->value);
+ }
+ }
+ else
+ {
+ /* Undefined symbol. */
+ op1 = 0;
+ op2 = 0;
+ }
+ image_write_q (abfd, op1);
+ image_write_q (abfd, op2);
+ break;
+
+ /* 205 Store-conditional NOP at address of global
+ arg: none. */
+ case ETIR__C_STC_NOP_GBL:
+ /* ALPHA_R_NOP */
+
+ /* 207 Store-conditional BSR at global address
+ arg: none. */
+
+ case ETIR__C_STC_BSR_GBL:
+ /* ALPHA_R_BSR */
+
+ /* 209 Store-conditional LDA at global address
+ arg: none. */
+
+ case ETIR__C_STC_LDA_GBL:
+ /* ALPHA_R_LDA */
+
+ /* 211 Store-conditional BSR or Hint at global address
+ arg: none. */
+
+ case ETIR__C_STC_BOH_GBL:
+ /* Currentl ignored. */
+ break;
+
+ /* 213 Store-conditional NOP,BSR or HINT at global address
+ arg: none. */
+
+ case ETIR__C_STC_NBH_GBL:
+
+ /* 206 Store-conditional NOP at pect + offset
+ arg: none. */
+
+ case ETIR__C_STC_NOP_PS:
+
+ /* 208 Store-conditional BSR at pect + offset
+ arg: none. */
+
+ case ETIR__C_STC_BSR_PS:
+
+ /* 210 Store-conditional LDA at psect + offset
+ arg: none. */
+
+ case ETIR__C_STC_LDA_PS:
+
+ /* 212 Store-conditional BSR or Hint at pect + offset
+ arg: none. */
+
+ case ETIR__C_STC_BOH_PS:
+
+ /* 214 Store-conditional NOP, BSR or HINT at psect + offset
+ arg: none. */
+ case ETIR__C_STC_NBH_PS:
+ (*_bfd_error_handler) ("%s: not supported",
+ _bfd_vms_etir_name (cmd));
+ return FALSE;
+ break;
+
+ /* Det relocation base: pop stack, set image location counter
+ arg: none. */
+ case ETIR__C_CTL_SETRB:
+ _bfd_vms_pop (abfd, &op1, &rel1);
+ if (!(rel1 & RELC_SEC_BASE))
+ abort ();
+ image_set_ptr (abfd, op1, rel1 & RELC_MASK, info);
+ break;
+
+ /* Augment relocation base: increment image location counter by offset
+ arg: lw offset value. */
+ case ETIR__C_CTL_AUGRB:
+ op1 = bfd_getl32 (ptr);
+ image_inc_ptr (abfd, op1);
+ break;
+
+ /* Define location: pop index, save location counter under index
+ arg: none. */
+ case ETIR__C_CTL_DFLOC:
+ _bfd_vms_pop (abfd, &op1, &rel1);
+ if (rel1 != RELC_NONE)
+ goto bad_context;
+ dst_define_location (abfd, op1);
+ break;
+
+ /* Set location: pop index, restore location counter from index
+ arg: none. */
+ case ETIR__C_CTL_STLOC:
+ _bfd_vms_pop (abfd, &op1, &rel1);
+ if (rel1 != RELC_NONE)
+ goto bad_context;
+ dst_restore_location (abfd, op1);
+ break;
+
+ /* Stack defined location: pop index, push location counter from index
+ arg: none. */
+ case ETIR__C_CTL_STKDL:
+ _bfd_vms_pop (abfd, &op1, &rel1);
+ if (rel1 != RELC_NONE)
+ goto bad_context;
+ _bfd_vms_push (abfd, dst_retrieve_location (abfd, op1), RELC_NONE);
+ break;
+
+ case ETIR__C_OPR_NOP: /* No-op. */
+ break;
+
+ case ETIR__C_OPR_ADD: /* Add. */
+ _bfd_vms_pop (abfd, &op1, &rel1);
+ _bfd_vms_pop (abfd, &op2, &rel2);
+ if (rel1 == RELC_NONE && rel2 != RELC_NONE)
+ rel1 = rel2;
+ else if (rel1 != RELC_NONE && rel2 != RELC_NONE)
+ goto bad_context;
+ _bfd_vms_push (abfd, op1 + op2, rel1);
+ break;
+
+ case ETIR__C_OPR_SUB: /* Subtract. */
+ _bfd_vms_pop (abfd, &op1, &rel1);
+ _bfd_vms_pop (abfd, &op2, &rel2);
+ if (rel1 == RELC_NONE && rel2 != RELC_NONE)
+ rel1 = rel2;
+ else if ((rel1 & RELC_SEC_BASE) && (rel2 & RELC_SEC_BASE))
+ {
+ op1 = alpha_vms_fix_sec_rel (abfd, info, rel1, op1);
+ op2 = alpha_vms_fix_sec_rel (abfd, info, rel2, op2);
+ rel1 = RELC_NONE;
+ }
+ else if (rel1 != RELC_NONE && rel2 != RELC_NONE)
+ goto bad_context;
+ _bfd_vms_push (abfd, op2 - op1, rel1);
+ break;
+
+ case ETIR__C_OPR_MUL: /* Multiply. */
+ _bfd_vms_pop (abfd, &op1, &rel1);
+ _bfd_vms_pop (abfd, &op2, &rel2);
+ if (rel1 != RELC_NONE || rel2 != RELC_NONE)
+ goto bad_context;
+ _bfd_vms_push (abfd, op1 * op2, RELC_NONE);
+ break;
+
+ case ETIR__C_OPR_DIV: /* Divide. */
+ _bfd_vms_pop (abfd, &op1, &rel1);
+ _bfd_vms_pop (abfd, &op2, &rel2);
+ if (rel1 != RELC_NONE || rel2 != RELC_NONE)
+ goto bad_context;
+ if (op2 == 0)
+ _bfd_vms_push (abfd, 0, RELC_NONE);
+ else
+ _bfd_vms_push (abfd, op2 / op1, RELC_NONE);
+ break;
+
+ case ETIR__C_OPR_AND: /* Logical AND. */
+ _bfd_vms_pop (abfd, &op1, &rel1);
+ _bfd_vms_pop (abfd, &op2, &rel2);
+ if (rel1 != RELC_NONE || rel2 != RELC_NONE)
+ goto bad_context;
+ _bfd_vms_push (abfd, op1 & op2, RELC_NONE);
+ break;
+
+ case ETIR__C_OPR_IOR: /* Logical inclusive OR. */
+ _bfd_vms_pop (abfd, &op1, &rel1);
+ _bfd_vms_pop (abfd, &op2, &rel2);
+ if (rel1 != RELC_NONE || rel2 != RELC_NONE)
+ goto bad_context;
+ _bfd_vms_push (abfd, op1 | op2, RELC_NONE);
+ break;
+
+ case ETIR__C_OPR_EOR: /* Logical exclusive OR. */
+ _bfd_vms_pop (abfd, &op1, &rel1);
+ _bfd_vms_pop (abfd, &op2, &rel2);
+ if (rel1 != RELC_NONE || rel2 != RELC_NONE)
+ goto bad_context;
+ _bfd_vms_push (abfd, op1 ^ op2, RELC_NONE);
+ break;
+
+ case ETIR__C_OPR_NEG: /* Negate. */
+ _bfd_vms_pop (abfd, &op1, &rel1);
+ if (rel1 != RELC_NONE)
+ goto bad_context;
+ _bfd_vms_push (abfd, -op1, RELC_NONE);
+ break;
+
+ case ETIR__C_OPR_COM: /* Complement. */
+ _bfd_vms_pop (abfd, &op1, &rel1);
+ if (rel1 != RELC_NONE)
+ goto bad_context;
+ _bfd_vms_push (abfd, ~op1, RELC_NONE);
+ break;
+
+ case ETIR__C_OPR_ASH: /* Arithmetic shift. */
+ _bfd_vms_pop (abfd, &op1, &rel1);
+ _bfd_vms_pop (abfd, &op2, &rel2);
+ if (rel1 != RELC_NONE || rel2 != RELC_NONE)
+ {
+ bad_context:
+ (*_bfd_error_handler) (_("invalid use of %s with contexts"),
+ _bfd_vms_etir_name (cmd));
+ return FALSE;
+ }
+ if ((int)op2 < 0) /* Shift right. */
+ op1 >>= -(int)op2;
+ else /* Shift left. */
+ op1 <<= (int)op2;
+ _bfd_vms_push (abfd, op1, RELC_NONE); /* FIXME: sym. */
+ break;
+
+ case ETIR__C_OPR_INSV: /* Insert field. */
+ case ETIR__C_OPR_USH: /* Unsigned shift. */
+ case ETIR__C_OPR_ROT: /* Rotate. */
+ case ETIR__C_OPR_REDEF: /* Redefine symbol to current location. */
+ case ETIR__C_OPR_DFLIT: /* Define a literal. */
+ (*_bfd_error_handler) (_("%s: not supported"),
+ _bfd_vms_etir_name (cmd));
+ return FALSE;
+ break;
+
+ case ETIR__C_OPR_SEL: /* Select. */
+ _bfd_vms_pop (abfd, &op1, &rel1);
+ if (op1 & 0x01L)
+ _bfd_vms_pop (abfd, &op1, &rel1);
+ else
+ {
+ _bfd_vms_pop (abfd, &op1, &rel1);
+ _bfd_vms_pop (abfd, &op2, &rel2);
+ _bfd_vms_push (abfd, op1, rel1);
+ }
+ break;
+
+ default:
+ (*_bfd_error_handler) (_("reserved cmd %d"), cmd);
+ return FALSE;
+ break;
+ }
+
+ ptr += cmd_length - 4;
+ }
+
+ return TRUE;
+}
+
+/* Process EDBG/ETBT record.
+ Return TRUE on success, FALSE on error */
+
+static bfd_boolean
+vms_slurp_debug (bfd *abfd)
+{
+ asection *section = PRIV (dst_section);
+
+ if (section == NULL)
+ {
+ /* We have no way to find out beforehand how much debug info there
+ is in an object file, so pick an initial amount and grow it as
+ needed later. */
+ flagword flags = SEC_HAS_CONTENTS | SEC_DEBUGGING | SEC_RELOC
+ | SEC_IN_MEMORY;
+
+ section = bfd_make_section (abfd, "$DST$");
+ if (!section)
+ return FALSE;
+ if (!bfd_set_section_flags (abfd, section, flags))
+ return FALSE;
+ PRIV (dst_section) = section;
+ }
+
+ PRIV (image_section) = section;
+ PRIV (image_offset) = section->size;
+
+ if (!_bfd_vms_slurp_etir (abfd, NULL))
+ return FALSE;
+
+ section->size = PRIV (image_offset);
+ return TRUE;
+}
+
+/* Process EDBG record.
+ Return TRUE on success, FALSE on error. */
+
+static bfd_boolean
+_bfd_vms_slurp_edbg (bfd *abfd)
+{
+ vms_debug2 ((2, "EDBG\n"));
+
+ abfd->flags |= HAS_DEBUG | HAS_LINENO;
+
+ return vms_slurp_debug (abfd);
+}
+
+/* Process ETBT record.
+ Return TRUE on success, FALSE on error. */
+
+static bfd_boolean
+_bfd_vms_slurp_etbt (bfd *abfd)
+{
+ vms_debug2 ((2, "ETBT\n"));
+
+ abfd->flags |= HAS_LINENO;
+
+ return vms_slurp_debug (abfd);
+}
+
+/* Process EEOM record.
+ Return TRUE on success, FALSE on error. */
+
+static bfd_boolean
+_bfd_vms_slurp_eeom (bfd *abfd)
+{
+ struct vms_eeom *eeom = (struct vms_eeom *) PRIV (recrd.rec);
+
+ vms_debug2 ((2, "EEOM\n"));
+
+ PRIV (eom_data).eom_l_total_lps = bfd_getl32 (eeom->total_lps);
+ PRIV (eom_data).eom_w_comcod = bfd_getl16 (eeom->comcod);
+ if (PRIV (eom_data).eom_w_comcod > 1)
+ {
+ (*_bfd_error_handler) (_("Object module NOT error-free !\n"));
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+
+ PRIV (eom_data).eom_has_transfer = FALSE;
+ if (PRIV (recrd.rec_size) > 10)
+ {
+ PRIV (eom_data).eom_has_transfer = TRUE;
+ PRIV (eom_data).eom_b_tfrflg = eeom->tfrflg;
+ PRIV (eom_data).eom_l_psindx = bfd_getl32 (eeom->psindx);
+ PRIV (eom_data).eom_l_tfradr = bfd_getl32 (eeom->tfradr);
+
+ abfd->start_address = PRIV (eom_data).eom_l_tfradr;
+ }
+ return TRUE;
+}
+
+/* Slurp an ordered set of VMS object records. Return FALSE on error. */
+
+static bfd_boolean
+_bfd_vms_slurp_object_records (bfd * abfd)
+{
+ bfd_boolean err;
+ int type;
+
+ do
+ {
+ vms_debug2 ((7, "reading at %08lx\n", (unsigned long)bfd_tell (abfd)));
+
+ type = _bfd_vms_get_object_record (abfd);
+ if (type < 0)
+ {
+ vms_debug2 ((2, "next_record failed\n"));
+ return FALSE;
+ }
+
+ switch (type)
+ {
+ case EOBJ__C_EMH:
+ err = _bfd_vms_slurp_ehdr (abfd);
+ break;
+ case EOBJ__C_EEOM:
+ err = _bfd_vms_slurp_eeom (abfd);
+ break;
+ case EOBJ__C_EGSD:
+ err = _bfd_vms_slurp_egsd (abfd);
+ break;
+ case EOBJ__C_ETIR:
+ err = TRUE; /* _bfd_vms_slurp_etir (abfd); */
+ break;
+ case EOBJ__C_EDBG:
+ err = _bfd_vms_slurp_edbg (abfd);
+ break;
+ case EOBJ__C_ETBT:
+ err = _bfd_vms_slurp_etbt (abfd);
+ break;
+ default:
+ err = FALSE;
+ }
+ if (err != TRUE)
+ {
+ vms_debug2 ((2, "slurp type %d failed\n", type));
+ return FALSE;
+ }
+ }
+ while (type != EOBJ__C_EEOM);
+
+ return TRUE;
+}
+
+/* Initialize private data */
+static bfd_boolean
+vms_initialize (bfd * abfd)
+{
+ bfd_size_type amt;
+
+ amt = sizeof (struct vms_private_data_struct);
+ abfd->tdata.any = bfd_zalloc (abfd, amt);
+ if (abfd->tdata.any == NULL)
+ return FALSE;
+
+ PRIV (recrd.file_format) = FF_UNKNOWN;
+
+ amt = sizeof (struct stack_struct) * STACKSIZE;
+ PRIV (stack) = bfd_alloc (abfd, amt);
+ if (PRIV (stack) == NULL)
+ goto error_ret1;
+
+ return TRUE;
+
+ error_ret1:
+ bfd_release (abfd, abfd->tdata.any);
+ abfd->tdata.any = NULL;
+ return FALSE;
+}
+
+/* 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 *
+alpha_vms_object_p (bfd *abfd)
+{
+ void *tdata_save = abfd->tdata.any;
+ unsigned int test_len;
+ unsigned char *buf;
+
+ vms_debug2 ((1, "vms_object_p(%p)\n", abfd));
+
+ /* Allocate alpha-vms specific data. */
+ if (!vms_initialize (abfd))
+ goto error_ret;
+
+ if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET))
+ goto err_wrong_format;
+
+ /* The first challenge with VMS is to discover the kind of the file.
+
+ Image files (executable or shared images) are stored as a raw
+ stream of bytes (like on UNIX), but there is no magic number.
+
+ Object files are written with RMS (record management service), ie
+ each records are preceeded by its length (on a word - 2 bytes), and
+ padded for word-alignment. That would be simple but when files
+ are transfered to a UNIX filesystem (using ftp), records are lost.
+ Only the raw content of the records are transfered. Fortunately,
+ the Alpha Object file format also store the length of the record
+ in the records. Is that clear ? */
+
+ /* Minimum is 6 bytes for objects (2 bytes size, 2 bytes record id,
+ 2 bytes size repeated) and 12 bytes for images (4 bytes major id,
+ 4 bytes minor id, 4 bytes length). */
+ test_len = 12;
+
+ /* Size the main buffer. */
+ buf = (unsigned char *) bfd_malloc (test_len);
+ if (buf == NULL)
+ goto error_ret;
+ PRIV (recrd.buf) = buf;
+ PRIV (recrd.buf_size) = test_len;
+
+ /* Initialize the record pointer. */
+ PRIV (recrd.rec) = buf;
+
+ if (bfd_bread (buf, test_len, abfd) != test_len)
+ goto err_wrong_format;
+
+ /* Is it an image? */
+ if ((bfd_getl32 (buf) == EIHD__K_MAJORID)
+ && (bfd_getl32 (buf + 4) == EIHD__K_MINORID))
+ {
+ unsigned int to_read;
+ unsigned int read_so_far;
+ unsigned int remaining;
+ unsigned int eisd_offset, eihs_offset;
+
+ /* Extract the header size. */
+ PRIV (recrd.rec_size) = bfd_getl32 (buf + EIHD__L_SIZE);
+
+ /* The header size is 0 for DSF files. */
+ if (PRIV (recrd.rec_size) == 0)
+ PRIV (recrd.rec_size) = sizeof (struct vms_eihd);
+
+ if (PRIV (recrd.rec_size) > PRIV (recrd.buf_size))
+ {
+ buf = bfd_realloc_or_free (buf, PRIV (recrd.rec_size));
+
+ if (buf == NULL)
+ {
+ PRIV (recrd.buf) = NULL;
+ goto error_ret;
+ }
+ PRIV (recrd.buf) = buf;
+ PRIV (recrd.buf_size) = PRIV (recrd.rec_size);
+ }
+
+ /* Read the remaining record. */
+ remaining = PRIV (recrd.rec_size) - test_len;
+ to_read = MIN (VMS_BLOCK_SIZE - test_len, remaining);
+ read_so_far = test_len;
+
+ while (remaining > 0)
+ {
+ if (bfd_bread (buf + read_so_far, to_read, abfd) != to_read)
+ goto err_wrong_format;
+
+ read_so_far += to_read;
+ remaining -= to_read;
+
+ to_read = MIN (VMS_BLOCK_SIZE, remaining);
+ }
+
+ /* Reset the record pointer. */
+ PRIV (recrd.rec) = buf;
+
+ vms_debug2 ((2, "file type is image\n"));
+
+ if (_bfd_vms_slurp_eihd (abfd, &eisd_offset, &eihs_offset) != TRUE)
+ goto err_wrong_format;
+
+ if (_bfd_vms_slurp_eisd (abfd, eisd_offset) != TRUE)
+ goto err_wrong_format;
+
+ /* EIHS is optional. */
+ if (eihs_offset != 0 && _bfd_vms_slurp_eihs (abfd, eihs_offset) != TRUE)
+ goto err_wrong_format;
+ }
+ else
+ {
+ int type;
+
+ /* Assume it's a module and adjust record pointer if necessary. */
+ maybe_adjust_record_pointer_for_object (abfd);
+
+ /* But is it really a module? */
+ if (bfd_getl16 (PRIV (recrd.rec)) <= EOBJ__C_MAXRECTYP
+ && bfd_getl16 (PRIV (recrd.rec) + 2) <= EOBJ__C_MAXRECSIZ)
+ {
+ if (vms_get_remaining_object_record (abfd, test_len) <= 0)
+ goto err_wrong_format;
+
+ vms_debug2 ((2, "file type is module\n"));
+
+ type = bfd_getl16 (PRIV (recrd.rec));
+ if (type != EOBJ__C_EMH || _bfd_vms_slurp_ehdr (abfd) != TRUE)
+ goto err_wrong_format;
+
+ if (_bfd_vms_slurp_object_records (abfd) != TRUE)
+ goto err_wrong_format;
+ }
+ else
+ goto err_wrong_format;
+ }
+
+ /* Set arch_info to alpha. */
+
+ if (! bfd_default_set_arch_mach (abfd, bfd_arch_alpha, 0))
+ goto err_wrong_format;
+
+ return abfd->xvec;
+
+ err_wrong_format:
+ bfd_set_error (bfd_error_wrong_format);
+
+ error_ret:
+ if (PRIV (recrd.buf))
+ free (PRIV (recrd.buf));
+ if (abfd->tdata.any != tdata_save && abfd->tdata.any != NULL)
+ bfd_release (abfd, abfd->tdata.any);
+ abfd->tdata.any = tdata_save;
+ return NULL;
+}
+
+/* Image write. */
+
+/* Write an EMH/MHD record. */
+
+static void
+_bfd_vms_write_emh (bfd *abfd)
+{
+ struct vms_rec_wr *recwr = &PRIV (recwr);
+
+ _bfd_vms_output_alignment (recwr, 2);
+
+ /* EMH. */
+ _bfd_vms_output_begin (recwr, EOBJ__C_EMH);
+ _bfd_vms_output_short (recwr, EMH__C_MHD);
+ _bfd_vms_output_short (recwr, EOBJ__C_STRLVL);
+ _bfd_vms_output_long (recwr, 0);
+ _bfd_vms_output_long (recwr, 0);
+ _bfd_vms_output_long (recwr, MAX_OUTREC_SIZE);
+
+ /* Create module name from filename. */
+ if (bfd_get_filename (abfd) != 0)
+ {
+ char *module = vms_get_module_name (bfd_get_filename (abfd), TRUE);
+ _bfd_vms_output_counted (recwr, module);
+ free (module);
+ }
+ else
+ _bfd_vms_output_counted (recwr, "NONAME");
+
+ _bfd_vms_output_counted (recwr, BFD_VERSION_STRING);
+ _bfd_vms_output_dump (recwr, get_vms_time_string (), EMH_DATE_LENGTH);
+ _bfd_vms_output_fill (recwr, 0, EMH_DATE_LENGTH);
+ _bfd_vms_output_end (abfd, recwr);
+}
+
+/* Write an EMH/LMN record. */
+
+static void
+_bfd_vms_write_lmn (bfd *abfd, const char *name)
+{
+ char version [64];
+ struct vms_rec_wr *recwr = &PRIV (recwr);
+ unsigned int ver = BFD_VERSION / 10000;
+
+ /* LMN. */
+ _bfd_vms_output_begin (recwr, EOBJ__C_EMH);
+ _bfd_vms_output_short (recwr, EMH__C_LNM);
+ snprintf (version, sizeof (version), "%s %d.%d.%d", name,
+ ver / 10000, (ver / 100) % 100, ver % 100);
+ _bfd_vms_output_dump (recwr, (unsigned char *)version, strlen (version));
+ _bfd_vms_output_end (abfd, recwr);
+}
+
+
+/* Write eom record for bfd abfd. Return FALSE on error. */
+
+static bfd_boolean
+_bfd_vms_write_eeom (bfd *abfd)
+{
+ struct vms_rec_wr *recwr = &PRIV (recwr);
+
+ vms_debug2 ((2, "vms_write_eeom\n"));
+
+ _bfd_vms_output_alignment (recwr, 2);
+
+ _bfd_vms_output_begin (recwr, EOBJ__C_EEOM);
+ _bfd_vms_output_long (recwr, PRIV (vms_linkage_index + 1) >> 1);
+ _bfd_vms_output_byte (recwr, 0); /* Completion code. */
+ _bfd_vms_output_byte (recwr, 0); /* Fill byte. */
+
+ if ((abfd->flags & EXEC_P) == 0
+ && 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 FALSE;
+ }
+ _bfd_vms_output_short (recwr, 0);
+ _bfd_vms_output_long (recwr, (unsigned long) section->target_index);
+ _bfd_vms_output_long (recwr,
+ (unsigned long) bfd_get_start_address (abfd));
+ _bfd_vms_output_long (recwr, 0);
+ }
+
+ _bfd_vms_output_end (abfd, recwr);
+ return TRUE;
+}
+
+static void
+vector_grow1 (struct vector_type *vec, size_t elsz)
+{
+ if (vec->nbr_el + 1 < vec->max_el)
+ return;
+
+ if (vec->max_el == 0)
+ {
+ vec->max_el = 16;
+ vec->els = bfd_malloc2 (vec->max_el, elsz);
+ }
+ else
+ {
+ vec->max_el *= 2;
+ vec->els = bfd_realloc2 (vec->els, vec->max_el, elsz);
+ }
+}
+
+/* Bump ABFD file position to next block. */
+
+static void
+alpha_vms_file_position_block (bfd *abfd)
+{
+ /* Next block. */
+ PRIV (file_pos) += VMS_BLOCK_SIZE - 1;
+ PRIV (file_pos) -= (PRIV (file_pos) % VMS_BLOCK_SIZE);
+}
+
+/* Convert from internal structure SRC to external structure DST. */
+
+static void
+alpha_vms_swap_eisd_out (struct vms_internal_eisd_map *src,
+ struct vms_eisd *dst)
+{
+ bfd_putl32 (src->u.eisd.majorid, dst->majorid);
+ bfd_putl32 (src->u.eisd.minorid, dst->minorid);
+ bfd_putl32 (src->u.eisd.eisdsize, dst->eisdsize);
+ if (src->u.eisd.eisdsize <= EISD__K_LENEND)
+ return;
+ bfd_putl32 (src->u.eisd.secsize, dst->secsize);
+ bfd_putl64 (src->u.eisd.virt_addr, dst->virt_addr);
+ bfd_putl32 (src->u.eisd.flags, dst->flags);
+ bfd_putl32 (src->u.eisd.vbn, dst->vbn);
+ dst->pfc = src->u.eisd.pfc;
+ dst->matchctl = src->u.eisd.matchctl;
+ dst->type = src->u.eisd.type;
+ dst->fill_1 = 0;
+ if (src->u.eisd.flags & EISD__M_GBL)
+ {
+ bfd_putl32 (src->u.gbl_eisd.ident, dst->ident);
+ memcpy (dst->gblnam, src->u.gbl_eisd.gblnam,
+ src->u.gbl_eisd.gblnam[0] + 1);
+ }
+}
+
+/* Append EISD to the list of extra eisd for ABFD. */
+
+static void
+alpha_vms_append_extra_eisd (bfd *abfd, struct vms_internal_eisd_map *eisd)
+{
+ eisd->next = NULL;
+ if (PRIV (gbl_eisd_head) == NULL)
+ PRIV (gbl_eisd_head) = eisd;
+ else
+ PRIV (gbl_eisd_tail)->next = eisd;
+ PRIV (gbl_eisd_tail) = eisd;
+}
+
+/* Create an EISD for shared image SHRIMG.
+ Return FALSE in case of error. */
+
+static bfd_boolean
+alpha_vms_create_eisd_for_shared (bfd *abfd, bfd *shrimg)
+{
+ struct vms_internal_eisd_map *eisd;
+ int namlen;
+
+ namlen = strlen (PRIV2 (shrimg, hdr_data.hdr_t_name));
+ if (namlen + 5 > EISD__K_GBLNAMLEN)
+ {
+ /* Won't fit. */
+ return FALSE;
+ }
+
+ eisd = bfd_alloc (abfd, sizeof (*eisd));
+ if (eisd == NULL)
+ return FALSE;
+
+ /* Fill the fields. */
+ eisd->u.gbl_eisd.common.majorid = EISD__K_MAJORID;
+ eisd->u.gbl_eisd.common.minorid = EISD__K_MINORID;
+ eisd->u.gbl_eisd.common.eisdsize = (EISD__K_LEN + 4 + namlen + 5 + 3) & ~3;
+ eisd->u.gbl_eisd.common.secsize = VMS_BLOCK_SIZE; /* Must not be 0. */
+ eisd->u.gbl_eisd.common.virt_addr = 0;
+ eisd->u.gbl_eisd.common.flags = EISD__M_GBL;
+ eisd->u.gbl_eisd.common.vbn = 0;
+ eisd->u.gbl_eisd.common.pfc = 0;
+ eisd->u.gbl_eisd.common.matchctl = PRIV2 (shrimg, matchctl);
+ eisd->u.gbl_eisd.common.type = EISD__K_SHRPIC;
+
+ eisd->u.gbl_eisd.ident = PRIV2 (shrimg, ident);
+ eisd->u.gbl_eisd.gblnam[0] = namlen + 4;
+ memcpy (eisd->u.gbl_eisd.gblnam + 1, PRIV2 (shrimg, hdr_data.hdr_t_name),
+ namlen);
+ memcpy (eisd->u.gbl_eisd.gblnam + 1 + namlen, "_001", 4);
+
+ /* Append it to the list. */
+ alpha_vms_append_extra_eisd (abfd, eisd);
+
+ return TRUE;
+}
+
+/* Create an EISD for section SEC.
+ Return FALSE in case of failure. */
+
+static bfd_boolean
+alpha_vms_create_eisd_for_section (bfd *abfd, asection *sec)
+{
+ struct vms_internal_eisd_map *eisd;
+
+ /* Only for allocating section. */
+ if (!(sec->flags & SEC_ALLOC))
+ return TRUE;
+
+ BFD_ASSERT (vms_section_data (sec)->eisd == NULL);
+ eisd = bfd_alloc (abfd, sizeof (*eisd));
+ if (eisd == NULL)
+ return FALSE;
+ vms_section_data (sec)->eisd = eisd;
+
+ /* Fill the fields. */
+ eisd->u.eisd.majorid = EISD__K_MAJORID;
+ eisd->u.eisd.minorid = EISD__K_MINORID;
+ eisd->u.eisd.eisdsize = EISD__K_LEN;
+ eisd->u.eisd.secsize =
+ (sec->size + VMS_BLOCK_SIZE - 1) & ~(VMS_BLOCK_SIZE - 1);
+ eisd->u.eisd.virt_addr = sec->vma;
+ eisd->u.eisd.flags = 0;
+ eisd->u.eisd.vbn = 0; /* To be later defined. */
+ eisd->u.eisd.pfc = 0; /* Default. */
+ eisd->u.eisd.matchctl = EISD__K_MATALL;
+ eisd->u.eisd.type = EISD__K_NORMAL;
+
+ if (sec->flags & SEC_CODE)
+ eisd->u.eisd.flags |= EISD__M_EXE;
+ if (!(sec->flags & SEC_READONLY))
+ eisd->u.eisd.flags |= EISD__M_WRT | EISD__M_CRF;
+
+ /* If relocations or fixup will be applied, make this isect writeable. */
+ if (sec->flags & SEC_RELOC)
+ eisd->u.eisd.flags |= EISD__M_WRT | EISD__M_CRF;
+
+ if (!(sec->flags & SEC_HAS_CONTENTS))
+ {
+ eisd->u.eisd.flags |= EISD__M_DZRO;
+ eisd->u.eisd.flags &= ~EISD__M_CRF;
+ }
+ if (sec->flags & SEC_LINKER_CREATED)
+ {
+ if (strcmp (sec->name, "$FIXUP$") == 0)
+ eisd->u.eisd.flags |= EISD__M_FIXUPVEC;
+ }
+
+ /* Append it to the list. */
+ eisd->next = NULL;
+ if (PRIV (eisd_head) == NULL)
+ PRIV (eisd_head) = eisd;
+ else
+ PRIV (eisd_tail)->next = eisd;
+ PRIV (eisd_tail) = eisd;
+
+ return TRUE;
+}
+
+/* Layout executable ABFD and write it to the disk.
+ Return FALSE in case of failure. */
+
+static bfd_boolean
+alpha_vms_write_exec (bfd *abfd)
+{
+ struct vms_eihd eihd;
+ struct vms_eiha *eiha;
+ struct vms_eihi *eihi;
+ struct vms_eihs *eihs = NULL;
+ asection *sec;
+ struct vms_internal_eisd_map *first_eisd;
+ struct vms_internal_eisd_map *eisd;
+ asection *dst;
+ asection *dmt;
+ file_ptr gst_filepos = 0;
+ unsigned int lnkflags = 0;
+
+ /* Build the EIHD. */
+ PRIV (file_pos) = EIHD__C_LENGTH;
+
+ memset (&eihd, 0, sizeof (eihd));
+ memset (eihd.fill_2, 0xff, sizeof (eihd.fill_2));
+
+ bfd_putl32 (EIHD__K_MAJORID, eihd.majorid);
+ bfd_putl32 (EIHD__K_MINORID, eihd.minorid);
+
+ bfd_putl32 (sizeof (eihd), eihd.size);
+ bfd_putl32 (0, eihd.isdoff);
+ bfd_putl32 (0, eihd.activoff);
+ bfd_putl32 (0, eihd.symdbgoff);
+ bfd_putl32 (0, eihd.imgidoff);
+ bfd_putl32 (0, eihd.patchoff);
+ bfd_putl64 (0, eihd.iafva);
+ bfd_putl32 (0, eihd.version_array_off);
+
+ bfd_putl32 (EIHD__K_EXE, eihd.imgtype);
+ bfd_putl32 (0, eihd.subtype);
+
+ bfd_putl32 (0, eihd.imgiocnt);
+ bfd_putl32 (-1, eihd.privreqs);
+ bfd_putl32 (-1, eihd.privreqs + 4);
+
+ bfd_putl32 ((sizeof (eihd) + VMS_BLOCK_SIZE - 1) / VMS_BLOCK_SIZE,
+ eihd.hdrblkcnt);
+ bfd_putl32 (0, eihd.ident);
+ bfd_putl32 (0, eihd.sysver);
+
+ eihd.matchctl = 0;
+ bfd_putl32 (0, eihd.symvect_size);
+ bfd_putl32 (16, eihd.virt_mem_block_size);
+ bfd_putl32 (0, eihd.ext_fixup_off);
+ bfd_putl32 (0, eihd.noopt_psect_off);
+ bfd_putl32 (-1, eihd.alias);
+
+ /* Alloc EIHA. */
+ eiha = (struct vms_eiha *)((char *) &eihd + PRIV (file_pos));
+ bfd_putl32 (PRIV (file_pos), eihd.activoff);
+ PRIV (file_pos) += sizeof (struct vms_eiha);
+
+ bfd_putl32 (sizeof (struct vms_eiha), eiha->size);
+ bfd_putl32 (0, eiha->spare);
+ bfd_putl64 (PRIV (transfer_address[0]), eiha->tfradr1);
+ bfd_putl64 (PRIV (transfer_address[1]), eiha->tfradr2);
+ bfd_putl64 (PRIV (transfer_address[2]), eiha->tfradr3);
+ bfd_putl64 (PRIV (transfer_address[3]), eiha->tfradr4);
+ bfd_putl64 (0, eiha->inishr);
+
+ /* Alloc EIHI. */
+ eihi = (struct vms_eihi *)((char *) &eihd + PRIV (file_pos));
+ bfd_putl32 (PRIV (file_pos), eihd.imgidoff);
+ PRIV (file_pos) += sizeof (struct vms_eihi);
+
+ bfd_putl32 (EIHI__K_MAJORID, eihi->majorid);
+ bfd_putl32 (EIHI__K_MINORID, eihi->minorid);
+ {
+ char *module;
+ unsigned int len;
+
+ /* Set module name. */
+ module = vms_get_module_name (bfd_get_filename (abfd), TRUE);
+ len = strlen (module);
+ if (len > sizeof (eihi->imgnam) - 1)
+ len = sizeof (eihi->imgnam) - 1;
+ eihi->imgnam[0] = len;
+ memcpy (eihi->imgnam + 1, module, len);
+ free (module);
+ }
+ {
+ unsigned int lo;
+ unsigned int hi;
+
+ /* Set time. */
+ vms_get_time (&hi, &lo);
+ bfd_putl32 (lo, eihi->linktime + 0);
+ bfd_putl32 (hi, eihi->linktime + 4);
+ }
+ eihi->imgid[0] = 0;
+ eihi->linkid[0] = 0;
+ eihi->imgbid[0] = 0;
+
+ /* Alloc EIHS. */
+ dst = PRIV (dst_section);
+ dmt = bfd_get_section_by_name (abfd, "$DMT$");
+ if (dst != NULL && dst->size != 0)
+ {
+ eihs = (struct vms_eihs *)((char *) &eihd + PRIV (file_pos));
+ bfd_putl32 (PRIV (file_pos), eihd.symdbgoff);
+ PRIV (file_pos) += sizeof (struct vms_eihs);
+
+ bfd_putl32 (EIHS__K_MAJORID, eihs->majorid);
+ bfd_putl32 (EIHS__K_MINORID, eihs->minorid);
+ bfd_putl32 (0, eihs->dstvbn);
+ bfd_putl32 (0, eihs->dstsize);
+ bfd_putl32 (0, eihs->gstvbn);
+ bfd_putl32 (0, eihs->gstsize);
+ bfd_putl32 (0, eihs->dmtvbn);
+ bfd_putl32 (0, eihs->dmtsize);
+ }
+
+ /* One EISD per section. */
+ for (sec = abfd->sections; sec; sec = sec->next)
+ {
+ if (!alpha_vms_create_eisd_for_section (abfd, sec))
+ return FALSE;
+ }
+
+ /* Merge section EIDS which extra ones. */
+ if (PRIV (eisd_tail))
+ PRIV (eisd_tail)->next = PRIV (gbl_eisd_head);
+ else
+ PRIV (eisd_head) = PRIV (gbl_eisd_head);
+ if (PRIV (gbl_eisd_tail))
+ PRIV (eisd_tail) = PRIV (gbl_eisd_tail);
+
+ first_eisd = PRIV (eisd_head);
+
+ /* Add end of eisd. */
+ if (first_eisd)
+ {
+ eisd = bfd_zalloc (abfd, sizeof (*eisd));
+ if (eisd == NULL)
+ return FALSE;
+ eisd->u.eisd.majorid = 0;
+ eisd->u.eisd.minorid = 0;
+ eisd->u.eisd.eisdsize = 0;
+ alpha_vms_append_extra_eisd (abfd, eisd);
+ }
+
+ /* Place EISD in the file. */
+ for (eisd = first_eisd; eisd; eisd = eisd->next)
+ {
+ file_ptr room = VMS_BLOCK_SIZE - (PRIV (file_pos) % VMS_BLOCK_SIZE);
+
+ /* First block is a little bit special: there is a word at the end. */
+ if (PRIV (file_pos) < VMS_BLOCK_SIZE && room > 2)
+ room -= 2;
+ if (room < eisd->u.eisd.eisdsize + EISD__K_LENEND)
+ alpha_vms_file_position_block (abfd);
+
+ eisd->file_pos = PRIV (file_pos);
+ PRIV (file_pos) += eisd->u.eisd.eisdsize;
+
+ if (eisd->u.eisd.flags & EISD__M_FIXUPVEC)
+ bfd_putl64 (eisd->u.eisd.virt_addr, eihd.iafva);
+ }
+
+ if (first_eisd != NULL)
+ {
+ bfd_putl32 (first_eisd->file_pos, eihd.isdoff);
+ /* Real size of end of eisd marker. */
+ PRIV (file_pos) += EISD__K_LENEND;
+ }
+
+ bfd_putl32 (PRIV (file_pos), eihd.size);
+ bfd_putl32 ((PRIV (file_pos) + VMS_BLOCK_SIZE - 1) / VMS_BLOCK_SIZE,
+ eihd.hdrblkcnt);
+
+ /* Place sections. */
+ for (sec = abfd->sections; sec; sec = sec->next)
+ {
+ if (!(sec->flags & SEC_HAS_CONTENTS))
+ continue;
+
+ eisd = vms_section_data (sec)->eisd;
+
+ /* Align on a block. */
+ alpha_vms_file_position_block (abfd);
+ sec->filepos = PRIV (file_pos);
+
+ if (eisd != NULL)
+ eisd->u.eisd.vbn = (sec->filepos / VMS_BLOCK_SIZE) + 1;
+
+ PRIV (file_pos) += sec->size;
+ }
+
+ /* Update EIHS. */
+ if (eihs != NULL && dst != NULL)
+ {
+ bfd_putl32 ((dst->filepos / VMS_BLOCK_SIZE) + 1, eihs->dstvbn);
+ bfd_putl32 (dst->size, eihs->dstsize);
+
+ if (dmt != NULL)
+ {
+ lnkflags |= EIHD__M_DBGDMT;
+ bfd_putl32 ((dmt->filepos / VMS_BLOCK_SIZE) + 1, eihs->dmtvbn);
+ bfd_putl32 (dmt->size, eihs->dmtsize);
+ }
+ if (PRIV (gsd_sym_count) != 0)
+ {
+ alpha_vms_file_position_block (abfd);
+ gst_filepos = PRIV (file_pos);
+ bfd_putl32 ((gst_filepos / VMS_BLOCK_SIZE) + 1, eihs->gstvbn);
+ bfd_putl32 ((PRIV (gsd_sym_count) + 4) / 5 + 4, eihs->gstsize);
+ }
+ }
+
+ /* Write EISD in hdr. */
+ for (eisd = first_eisd; eisd && eisd->file_pos < VMS_BLOCK_SIZE;
+ eisd = eisd->next)
+ alpha_vms_swap_eisd_out
+ (eisd, (struct vms_eisd *)((char *)&eihd + eisd->file_pos));
+
+ /* Write first block. */
+ bfd_putl32 (lnkflags, eihd.lnkflags);
+ if (bfd_bwrite (&eihd, sizeof (eihd), abfd) != sizeof (eihd))
+ return FALSE;
+
+ /* Write remaining eisd. */
+ if (eisd != NULL)
+ {
+ unsigned char blk[VMS_BLOCK_SIZE];
+ struct vms_internal_eisd_map *next_eisd;
+
+ memset (blk, 0xff, sizeof (blk));
+ while (eisd != NULL)
+ {
+ alpha_vms_swap_eisd_out
+ (eisd,
+ (struct vms_eisd *)(blk + (eisd->file_pos % VMS_BLOCK_SIZE)));
+
+ next_eisd = eisd->next;
+ if (next_eisd == NULL
+ || (next_eisd->file_pos / VMS_BLOCK_SIZE
+ != eisd->file_pos / VMS_BLOCK_SIZE))
+ {
+ if (bfd_bwrite (blk, sizeof (blk), abfd) != sizeof (blk))
+ return FALSE;
+
+ memset (blk, 0xff, sizeof (blk));
+ }
+ eisd = next_eisd;
+ }
+ }
+
+ /* Write sections. */
+ for (sec = abfd->sections; sec; sec = sec->next)
+ {
+ unsigned char blk[VMS_BLOCK_SIZE];
+ bfd_size_type len;
+
+ if (sec->size == 0 || !(sec->flags & SEC_HAS_CONTENTS))
+ continue;
+ if (bfd_bwrite (sec->contents, sec->size, abfd) != sec->size)
+ return FALSE;
+
+ /* Pad. */
+ len = VMS_BLOCK_SIZE - sec->size % VMS_BLOCK_SIZE;
+ if (len != VMS_BLOCK_SIZE)
+ {
+ memset (blk, 0, len);
+ if (bfd_bwrite (blk, len, abfd) != len)
+ return FALSE;
+ }
+ }
+
+ /* Write GST. */
+ if (gst_filepos != 0)
+ {
+ struct vms_rec_wr *recwr = &PRIV (recwr);
+ unsigned int i;
+
+ _bfd_vms_write_emh (abfd);
+ _bfd_vms_write_lmn (abfd, "GNU LD");
+
+ /* PSC for the absolute section. */
+ _bfd_vms_output_begin (recwr, EOBJ__C_EGSD);
+ _bfd_vms_output_long (recwr, 0);
+ _bfd_vms_output_begin_subrec (recwr, EGSD__C_PSC);
+ _bfd_vms_output_short (recwr, 0);
+ _bfd_vms_output_short (recwr, EGPS__V_PIC | EGPS__V_LIB | EGPS__V_RD);
+ _bfd_vms_output_long (recwr, 0);
+ _bfd_vms_output_counted (recwr, ".$$ABS$$.");
+ _bfd_vms_output_end_subrec (recwr);
+ _bfd_vms_output_end (abfd, recwr);
+
+ for (i = 0; i < PRIV (gsd_sym_count); i++)
+ {
+ struct vms_symbol_entry *sym = PRIV (syms)[i];
+ bfd_vma val;
+ bfd_vma ep;
+
+ if ((i % 5) == 0)
+ {
+ _bfd_vms_output_alignment (recwr, 8);
+ _bfd_vms_output_begin (recwr, EOBJ__C_EGSD);
+ _bfd_vms_output_long (recwr, 0);
+ }
+ _bfd_vms_output_begin_subrec (recwr, EGSD__C_SYMG);
+ _bfd_vms_output_short (recwr, 0); /* Data type, alignment. */
+ _bfd_vms_output_short (recwr, sym->flags);
+
+ if (sym->code_section)
+ ep = alpha_vms_get_sym_value (sym->code_section, sym->code_value);
+ else
+ {
+ BFD_ASSERT (sym->code_value == 0);
+ ep = 0;
+ }
+ val = alpha_vms_get_sym_value (sym->section, sym->value);
+ _bfd_vms_output_quad
+ (recwr, sym->typ == EGSD__C_SYMG ? sym->symbol_vector : val);
+ _bfd_vms_output_quad (recwr, ep);
+ _bfd_vms_output_quad (recwr, val);
+ _bfd_vms_output_long (recwr, 0);
+ _bfd_vms_output_counted (recwr, sym->name);
+ _bfd_vms_output_end_subrec (recwr);
+ if ((i % 5) == 4)
+ _bfd_vms_output_end (abfd, recwr);
+ }
+ if ((i % 5) != 0)
+ _bfd_vms_output_end (abfd, recwr);
+
+ if (!_bfd_vms_write_eeom (abfd))
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/* Object write. */
+
+/* Write section and symbol directory of bfd abfd. Return FALSE on error. */
+
+static bfd_boolean
+_bfd_vms_write_egsd (bfd *abfd)
+{
+ asection *section;
+ asymbol *symbol;
+ unsigned int symnum;
+ const char *sname;
+ flagword new_flags, old_flags;
+ int abs_section_index = -1;
+ unsigned int target_index = 0;
+ struct vms_rec_wr *recwr = &PRIV (recwr);
+
+ vms_debug2 ((2, "vms_write_egsd\n"));
+
+ /* Egsd is quadword aligned. */
+ _bfd_vms_output_alignment (recwr, 8);
+
+ _bfd_vms_output_begin (recwr, EOBJ__C_EGSD);
+ _bfd_vms_output_long (recwr, 0);
+
+ /* Number sections. */
+ for (section = abfd->sections; section != NULL; section = section->next)
+ {
+ if (section->flags & SEC_DEBUGGING)
+ continue;
+ if (!strcmp (section->name, ".vmsdebug"))
+ {
+ section->flags |= SEC_DEBUGGING;
+ continue;
+ }
+ section->target_index = target_index++;
+ }
+
+ for (section = abfd->sections; section != NULL; section = section->next)
+ {
+ vms_debug2 ((3, "Section #%d %s, %d bytes\n",
+ section->target_index, section->name, (int)section->size));
+
+ /* Don't write out the VMS debug info section since it is in the
+ ETBT and EDBG sections in etir. */
+ if (section->flags & SEC_DEBUGGING)
+ continue;
+
+ /* 13 bytes egsd, max 31 chars name -> should be 44 bytes. */
+ if (_bfd_vms_output_check (recwr, 64) < 0)
+ {
+ _bfd_vms_output_end (abfd, recwr);
+ _bfd_vms_output_begin (recwr, EOBJ__C_EGSD);
+ _bfd_vms_output_long (recwr, 0);
+ }
+
+ /* Don't know if this is necessary for the linker but for now it keeps
+ vms_slurp_gsd happy. */
+ sname = section->name;
+ if (*sname == '.')
+ {
+ /* Remove leading dot. */
+ sname++;
+ if ((*sname == 't') && (strcmp (sname, "text") == 0))
+ sname = EVAX_CODE_NAME;
+ else if ((*sname == 'd') && (strcmp (sname, "data") == 0))
+ sname = 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 == 'l') && (strcmp (sname, "literals") == 0))
+ sname = EVAX_LITERALS_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;
+ }
+
+ if (bfd_is_com_section (section))
+ new_flags = (EGPS__V_OVR | EGPS__V_REL | EGPS__V_GBL | EGPS__V_RD
+ | EGPS__V_WRT | EGPS__V_NOMOD | EGPS__V_COM);
+ else
+ new_flags = vms_esecflag_by_name (evax_section_flags, sname,
+ section->size > 0);
+
+ /* Modify them as directed. */
+ if (section->flags & SEC_READONLY)
+ new_flags &= ~EGPS__V_WRT;
+
+ new_flags &= ~vms_section_data (section)->no_flags;
+ new_flags |= vms_section_data (section)->flags;
+
+ vms_debug2 ((3, "sec flags %x\n", section->flags));
+ vms_debug2 ((3, "new_flags %x, _raw_size %lu\n",
+ new_flags, (unsigned long)section->size));
+
+ _bfd_vms_output_begin_subrec (recwr, EGSD__C_PSC);
+ _bfd_vms_output_short (recwr, section->alignment_power & 0xff);
+ _bfd_vms_output_short (recwr, new_flags);
+ _bfd_vms_output_long (recwr, (unsigned long) section->size);
+ _bfd_vms_output_counted (recwr, sname);
+ _bfd_vms_output_end_subrec (recwr);
+
+ /* If the section is an obsolute one, remind its index as it will be
+ used later for absolute symbols. */
+ if ((new_flags & EGPS__V_REL) == 0 && abs_section_index < 0)
+ abs_section_index = section->target_index;
+ }
+
+ /* Output symbols. */
+ vms_debug2 ((3, "%d symbols found\n", abfd->symcount));
+
+ bfd_set_start_address (abfd, (bfd_vma) -1);
+
+ for (symnum = 0; symnum < abfd->symcount; symnum++)
+ {
+ symbol = abfd->outsymbols[symnum];
+ old_flags = symbol->flags;
+
+ /* Work-around a missing feature: consider __main as the main entry
+ point. */
+ if (symbol->name[0] == '_' && strcmp (symbol->name, "__main") == 0)
+ bfd_set_start_address (abfd, (bfd_vma)symbol->value);
+
+ /* Only put in the GSD the global and the undefined symbols. */
+ if (old_flags & BSF_FILE)
+ continue;
+
+ if ((old_flags & BSF_GLOBAL) == 0 && !bfd_is_und_section (symbol->section))
+ {
+ /* If the LIB$INITIIALIZE section is present, add a reference to
+ LIB$INITIALIZE symbol. FIXME: this should be done explicitely
+ in the assembly file. */
+ if (!((old_flags & BSF_SECTION_SYM) != 0
+ && strcmp (symbol->section->name, "LIB$INITIALIZE") == 0))
+ continue;
+ }
+
+ /* 13 bytes egsd, max 64 chars name -> should be 77 bytes. Add 16 more
+ bytes for a possible ABS section. */
+ if (_bfd_vms_output_check (recwr, 80 + 16) < 0)
+ {
+ _bfd_vms_output_end (abfd, recwr);
+ _bfd_vms_output_begin (recwr, EOBJ__C_EGSD);
+ _bfd_vms_output_long (recwr, 0);
+ }
+
+ if ((old_flags & BSF_GLOBAL) != 0
+ && bfd_is_abs_section (symbol->section)
+ && abs_section_index <= 0)
+ {
+ /* Create an absolute section if none was defined. It is highly
+ unlikely that the name $ABS$ clashes with a user defined
+ non-absolute section name. */
+ _bfd_vms_output_begin_subrec (recwr, EGSD__C_PSC);
+ _bfd_vms_output_short (recwr, 4);
+ _bfd_vms_output_short (recwr, EGPS__V_SHR);
+ _bfd_vms_output_long (recwr, 0);
+ _bfd_vms_output_counted (recwr, "$ABS$");
+ _bfd_vms_output_end_subrec (recwr);
+
+ abs_section_index = target_index++;
+ }
+
+ _bfd_vms_output_begin_subrec (recwr, EGSD__C_SYM);
+
+ /* Data type, alignment. */
+ _bfd_vms_output_short (recwr, 0);
+
+ new_flags = 0;
+
+ if (old_flags & BSF_WEAK)
+ new_flags |= EGSY__V_WEAK;
+ if (bfd_is_com_section (symbol->section)) /* .comm */
+ new_flags |= (EGSY__V_WEAK | EGSY__V_COMM);
+
+ if (old_flags & BSF_FUNCTION)
+ {
+ new_flags |= EGSY__V_NORM;
+ new_flags |= EGSY__V_REL;
+ }
+ if (old_flags & BSF_GLOBAL)
+ {
+ new_flags |= EGSY__V_DEF;
+ if (!bfd_is_abs_section (symbol->section))
+ new_flags |= EGSY__V_REL;
+ }
+ _bfd_vms_output_short (recwr, new_flags);
+
+ if (old_flags & BSF_GLOBAL)
+ {
+ /* Symbol definition. */
+ bfd_vma code_address = 0;
+ unsigned long ca_psindx = 0;
+ unsigned long psindx;
+
+ if ((old_flags & BSF_FUNCTION) && symbol->udata.p != NULL)
+ {
+ asymbol *sym;
+
+ sym =
+ ((struct evax_private_udata_struct *)symbol->udata.p)->enbsym;
+ code_address = sym->value;
+ ca_psindx = sym->section->target_index;
+ }
+ if (bfd_is_abs_section (symbol->section))
+ psindx = abs_section_index;
+ else
+ psindx = symbol->section->target_index;
+
+ _bfd_vms_output_quad (recwr, symbol->value);
+ _bfd_vms_output_quad (recwr, code_address);
+ _bfd_vms_output_long (recwr, ca_psindx);
+ _bfd_vms_output_long (recwr, psindx);
+ }
+ _bfd_vms_output_counted (recwr, symbol->name);
+
+ _bfd_vms_output_end_subrec (recwr);
+ }
+
+ _bfd_vms_output_alignment (recwr, 8);
+ _bfd_vms_output_end (abfd, recwr);
+
+ return TRUE;
+}
+
+/* Write object header for bfd abfd. Return FALSE on error. */
+
+static bfd_boolean
+_bfd_vms_write_ehdr (bfd *abfd)
+{
+ asymbol *symbol;
+ unsigned int symnum;
+ struct vms_rec_wr *recwr = &PRIV (recwr);
+
+ vms_debug2 ((2, "vms_write_ehdr (%p)\n", abfd));
+
+ _bfd_vms_output_alignment (recwr, 2);
+
+ _bfd_vms_write_emh (abfd);
+ _bfd_vms_write_lmn (abfd, "GNU AS");
+
+ /* SRC. */
+ _bfd_vms_output_begin (recwr, EOBJ__C_EMH);
+ _bfd_vms_output_short (recwr, EMH__C_SRC);
+
+ for (symnum = 0; symnum < abfd->symcount; symnum++)
+ {
+ symbol = abfd->outsymbols[symnum];
+
+ if (symbol->flags & BSF_FILE)
+ {
+ _bfd_vms_output_dump (recwr, (unsigned char *) symbol->name,
+ (int) strlen (symbol->name));
+ break;
+ }
+ }
+
+ if (symnum == abfd->symcount)
+ _bfd_vms_output_dump (recwr, (unsigned char *) STRING_COMMA_LEN ("noname"));
+
+ _bfd_vms_output_end (abfd, recwr);
+
+ /* TTL. */
+ _bfd_vms_output_begin (recwr, EOBJ__C_EMH);
+ _bfd_vms_output_short (recwr, EMH__C_TTL);
+ _bfd_vms_output_dump (recwr, (unsigned char *) STRING_COMMA_LEN ("TTL"));
+ _bfd_vms_output_end (abfd, recwr);
+
+ /* CPR. */
+ _bfd_vms_output_begin (recwr, EOBJ__C_EMH);
+ _bfd_vms_output_short (recwr, EMH__C_CPR);
+ _bfd_vms_output_dump (recwr,
+ (unsigned char *)"GNU BFD ported by Klaus Kämpf 1994-1996",
+ 39);
+ _bfd_vms_output_end (abfd, recwr);
+
+ return TRUE;
+}
+
+/* Part 4.6, relocations. */
+
+
+/* WRITE ETIR SECTION
+
+ This is still under construction and therefore not documented. */
+
+/* Close the etir/etbt record. */
+
+static void
+end_etir_record (bfd * abfd)
+{
+ struct vms_rec_wr *recwr = &PRIV (recwr);
+
+ _bfd_vms_output_end (abfd, recwr);
+}
+
+static void
+start_etir_or_etbt_record (bfd *abfd, asection *section, bfd_vma offset)
+{
+ struct vms_rec_wr *recwr = &PRIV (recwr);
+
+ if (section->flags & SEC_DEBUGGING)
+ {
+ _bfd_vms_output_begin (recwr, EOBJ__C_ETBT);
+
+ if (offset == 0)
+ {
+ /* Push start offset. */
+ _bfd_vms_output_begin_subrec (recwr, ETIR__C_STA_LW);
+ _bfd_vms_output_long (recwr, (unsigned long) 0);
+ _bfd_vms_output_end_subrec (recwr);
+
+ /* Set location. */
+ _bfd_vms_output_begin_subrec (recwr, ETIR__C_CTL_DFLOC);
+ _bfd_vms_output_end_subrec (recwr);
+ }
+ }
+ else
+ {
+ _bfd_vms_output_begin (recwr, EOBJ__C_ETIR);
+
+ if (offset == 0)
+ {
+ /* Push start offset. */
+ _bfd_vms_output_begin_subrec (recwr, ETIR__C_STA_PQ);
+ _bfd_vms_output_long (recwr, (unsigned long) section->target_index);
+ _bfd_vms_output_quad (recwr, offset);
+ _bfd_vms_output_end_subrec (recwr);
+
+ /* Start = pop (). */
+ _bfd_vms_output_begin_subrec (recwr, ETIR__C_CTL_SETRB);
+ _bfd_vms_output_end_subrec (recwr);
+ }
+ }
+}
+
+/* Output a STO_IMM command for SSIZE bytes of data from CPR at virtual
+ address VADDR in section specified by SEC_INDEX and NAME. */
+
+static void
+sto_imm (bfd *abfd, asection *section,
+ bfd_size_type ssize, unsigned char *cptr, bfd_vma vaddr)
+{
+ bfd_size_type size;
+ struct vms_rec_wr *recwr = &PRIV (recwr);
+
+#if VMS_DEBUG
+ _bfd_vms_debug (8, "sto_imm %d bytes\n", (int) ssize);
+ _bfd_hexdump (9, cptr, (int) ssize, (int) vaddr);
+#endif
+
+ while (ssize > 0)
+ {
+ /* Try all the rest. */
+ size = ssize;
+
+ if (_bfd_vms_output_check (recwr, size) < 0)
+ {
+ /* Doesn't fit, split ! */
+ end_etir_record (abfd);
+
+ start_etir_or_etbt_record (abfd, section, vaddr);
+
+ size = _bfd_vms_output_check (recwr, 0); /* get max size */
+ if (size > ssize) /* more than what's left ? */
+ size = ssize;
+ }
+
+ _bfd_vms_output_begin_subrec (recwr, ETIR__C_STO_IMM);
+ _bfd_vms_output_long (recwr, (unsigned long) (size));
+ _bfd_vms_output_dump (recwr, cptr, size);
+ _bfd_vms_output_end_subrec (recwr);
+
+#if VMS_DEBUG
+ _bfd_vms_debug (10, "dumped %d bytes\n", (int) size);
+ _bfd_hexdump (10, cptr, (int) size, (int) vaddr);
+#endif
+
+ vaddr += size;
+ cptr += size;
+ ssize -= size;
+ }
+}
+
+static void
+etir_output_check (bfd *abfd, asection *section, bfd_vma vaddr, int checklen)
+{
+ if (_bfd_vms_output_check (&PRIV (recwr), checklen) < 0)
+ {
+ /* Not enough room in this record. Close it and open a new one. */
+ end_etir_record (abfd);
+ start_etir_or_etbt_record (abfd, section, vaddr);
+ }
+}
+
+/* Return whether RELOC must be deferred till the end. */
+
+static bfd_boolean
+defer_reloc_p (arelent *reloc)
+{
+ switch (reloc->howto->type)
+ {
+ case ALPHA_R_NOP:
+ case ALPHA_R_LDA:
+ case ALPHA_R_BSR:
+ case ALPHA_R_BOH:
+ return TRUE;
+
+ default:
+ return FALSE;
+ }
+}
+
+/* Write section contents for bfd abfd. Return FALSE on error. */
+
+static bfd_boolean
+_bfd_vms_write_etir (bfd * abfd, int objtype ATTRIBUTE_UNUSED)
+{
+ asection *section;
+ struct vms_rec_wr *recwr = &PRIV (recwr);
+
+ vms_debug2 ((2, "vms_write_tir (%p, %d)\n", abfd, objtype));
+
+ _bfd_vms_output_alignment (recwr, 4);
+
+ PRIV (vms_linkage_index) = 0;
+
+ for (section = abfd->sections; section; section = section->next)
+ {
+ vms_debug2 ((4, "writing %d. section '%s' (%d bytes)\n",
+ section->target_index, section->name, (int) (section->size)));
+
+ if (!(section->flags & SEC_HAS_CONTENTS)
+ || bfd_is_com_section (section))
+ continue;
+
+ if (!section->contents)
+ {
+ bfd_set_error (bfd_error_no_contents);
+ return FALSE;
+ }
+
+ start_etir_or_etbt_record (abfd, section, 0);
+
+ if (section->flags & SEC_RELOC)
+ {
+ bfd_vma curr_addr = 0;
+ unsigned char *curr_data = section->contents;
+ bfd_size_type size;
+ int pass2_needed = 0;
+ int pass2_in_progress = 0;
+ unsigned int irel;
+
+ if (section->reloc_count == 0)
+ (*_bfd_error_handler)
+ (_("SEC_RELOC with no relocs in section %s"), section->name);
+
+#if VMS_DEBUG
+ else
+ {
+ int i = section->reloc_count;
+ arelent **rptr = section->orelocation;
+ _bfd_vms_debug (4, "%d relocations:\n", i);
+ 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,
+ (unsigned long)(*rptr)->address,
+ (unsigned long)(*rptr)->addend,
+ bfd_get_reloc_size ((*rptr)->howto),
+ ( *rptr)->howto->name);
+ rptr++;
+ }
+ }
+#endif
+
+ new_pass:
+ for (irel = 0; irel < section->reloc_count; irel++)
+ {
+ struct evax_private_udata_struct *udata;
+ arelent *rptr = section->orelocation [irel];
+ bfd_vma addr = rptr->address;
+ asymbol *sym = *rptr->sym_ptr_ptr;
+ asection *sec = sym->section;
+ bfd_boolean defer = defer_reloc_p (rptr);
+ unsigned int slen;
+
+ if (pass2_in_progress)
+ {
+ /* Non-deferred relocs have already been output. */
+ if (!defer)
+ continue;
+ }
+ else
+ {
+ /* Deferred relocs must be output at the very end. */
+ if (defer)
+ {
+ pass2_needed = 1;
+ continue;
+ }
+
+ /* Regular relocs are intertwined with binary data. */
+ if (curr_addr > addr)
+ (*_bfd_error_handler) (_("Size error in section %s"),
+ section->name);
+ size = addr - curr_addr;
+ sto_imm (abfd, section, size, curr_data, curr_addr);
+ curr_data += size;
+ curr_addr += size;
+ }
+
+ size = bfd_get_reloc_size (rptr->howto);
+
+ switch (rptr->howto->type)
+ {
+ case ALPHA_R_IGNORE:
+ break;
+
+ case ALPHA_R_REFLONG:
+ if (bfd_is_und_section (sym->section))
+ {
+ bfd_vma addend = rptr->addend;
+ slen = strlen ((char *) sym->name);
+ etir_output_check (abfd, section, curr_addr, slen);
+ if (addend)
+ {
+ _bfd_vms_output_begin_subrec (recwr, ETIR__C_STA_GBL);
+ _bfd_vms_output_counted (recwr, sym->name);
+ _bfd_vms_output_end_subrec (recwr);
+ _bfd_vms_output_begin_subrec (recwr, ETIR__C_STA_LW);
+ _bfd_vms_output_long (recwr, (unsigned long) addend);
+ _bfd_vms_output_end_subrec (recwr);
+ _bfd_vms_output_begin_subrec (recwr, ETIR__C_OPR_ADD);
+ _bfd_vms_output_end_subrec (recwr);
+ _bfd_vms_output_begin_subrec (recwr, ETIR__C_STO_LW);
+ _bfd_vms_output_end_subrec (recwr);
+ }
+ else
+ {
+ _bfd_vms_output_begin_subrec
+ (recwr, ETIR__C_STO_GBL_LW);
+ _bfd_vms_output_counted (recwr, sym->name);
+ _bfd_vms_output_end_subrec (recwr);
+ }
+ }
+ else if (bfd_is_abs_section (sym->section))
+ {
+ etir_output_check (abfd, section, curr_addr, 16);
+ _bfd_vms_output_begin_subrec (recwr, ETIR__C_STA_LW);
+ _bfd_vms_output_long (recwr, (unsigned long) sym->value);
+ _bfd_vms_output_end_subrec (recwr);
+ _bfd_vms_output_begin_subrec (recwr, ETIR__C_STO_LW);
+ _bfd_vms_output_end_subrec (recwr);
+ }
+ else
+ {
+ etir_output_check (abfd, section, curr_addr, 32);
+ _bfd_vms_output_begin_subrec (recwr, ETIR__C_STA_PQ);
+ _bfd_vms_output_long (recwr,
+ (unsigned long) sec->target_index);
+ _bfd_vms_output_quad (recwr, rptr->addend + sym->value);
+ _bfd_vms_output_end_subrec (recwr);
+ /* ??? Table B-8 of the OpenVMS Linker Utilily Manual
+ says that we should have a ETIR__C_STO_OFF here.
+ But the relocation would not be BFD_RELOC_32 then.
+ This case is very likely unreachable. */
+ _bfd_vms_output_begin_subrec (recwr, ETIR__C_STO_LW);
+ _bfd_vms_output_end_subrec (recwr);
+ }
+ break;
+
+ case ALPHA_R_REFQUAD:
+ if (bfd_is_und_section (sym->section))
+ {
+ bfd_vma addend = rptr->addend;
+ slen = strlen ((char *) sym->name);
+ etir_output_check (abfd, section, curr_addr, slen);
+ if (addend)
+ {
+ _bfd_vms_output_begin_subrec (recwr, ETIR__C_STA_GBL);
+ _bfd_vms_output_counted (recwr, sym->name);
+ _bfd_vms_output_end_subrec (recwr);
+ _bfd_vms_output_begin_subrec (recwr, ETIR__C_STA_QW);
+ _bfd_vms_output_quad (recwr, addend);
+ _bfd_vms_output_end_subrec (recwr);
+ _bfd_vms_output_begin_subrec (recwr, ETIR__C_OPR_ADD);
+ _bfd_vms_output_end_subrec (recwr);
+ _bfd_vms_output_begin_subrec (recwr, ETIR__C_STO_QW);
+ _bfd_vms_output_end_subrec (recwr);
+ }
+ else
+ {
+ _bfd_vms_output_begin_subrec (recwr, ETIR__C_STO_GBL);
+ _bfd_vms_output_counted (recwr, sym->name);
+ _bfd_vms_output_end_subrec (recwr);
+ }
+ }
+ else if (bfd_is_abs_section (sym->section))
+ {
+ etir_output_check (abfd, section, curr_addr, 16);
+ _bfd_vms_output_begin_subrec (recwr, ETIR__C_STA_QW);
+ _bfd_vms_output_quad (recwr, sym->value);
+ _bfd_vms_output_end_subrec (recwr);
+ _bfd_vms_output_begin_subrec (recwr, ETIR__C_STO_QW);
+ _bfd_vms_output_end_subrec (recwr);
+ }
+ else
+ {
+ etir_output_check (abfd, section, curr_addr, 32);
+ _bfd_vms_output_begin_subrec (recwr, ETIR__C_STA_PQ);
+ _bfd_vms_output_long (recwr,
+ (unsigned long) sec->target_index);
+ _bfd_vms_output_quad (recwr, rptr->addend + sym->value);
+ _bfd_vms_output_end_subrec (recwr);
+ _bfd_vms_output_begin_subrec (recwr, ETIR__C_STO_OFF);
+ _bfd_vms_output_end_subrec (recwr);
+ }
+ break;
+
+ case ALPHA_R_HINT:
+ sto_imm (abfd, section, size, curr_data, curr_addr);
+ break;
+
+ case ALPHA_R_LINKAGE:
+ etir_output_check (abfd, section, curr_addr, 64);
+ _bfd_vms_output_begin_subrec (recwr, ETIR__C_STC_LP_PSB);
+ _bfd_vms_output_long
+ (recwr, (unsigned long) rptr->addend);
+ if (rptr->addend > PRIV (vms_linkage_index))
+ PRIV (vms_linkage_index) = rptr->addend;
+ _bfd_vms_output_counted (recwr, sym->name);
+ _bfd_vms_output_byte (recwr, 0);
+ _bfd_vms_output_end_subrec (recwr);
+ break;
+
+ case ALPHA_R_CODEADDR:
+ slen = strlen ((char *) sym->name);
+ etir_output_check (abfd, section, curr_addr, slen);
+ _bfd_vms_output_begin_subrec (recwr, ETIR__C_STO_CA);
+ _bfd_vms_output_counted (recwr, sym->name);
+ _bfd_vms_output_end_subrec (recwr);
+ break;
+
+ case ALPHA_R_NOP:
+ udata
+ = (struct evax_private_udata_struct *) rptr->sym_ptr_ptr;
+ etir_output_check (abfd, section, curr_addr,
+ 32 + 1 + strlen (udata->origname));
+ _bfd_vms_output_begin_subrec (recwr, ETIR__C_STC_NOP_GBL);
+ _bfd_vms_output_long (recwr, (unsigned long) udata->lkindex);
+ _bfd_vms_output_long
+ (recwr, (unsigned long) section->target_index);
+ _bfd_vms_output_quad (recwr, rptr->address);
+ _bfd_vms_output_long (recwr, (unsigned long) 0x47ff041f);
+ _bfd_vms_output_long
+ (recwr, (unsigned long) section->target_index);
+ _bfd_vms_output_quad (recwr, rptr->addend);
+ _bfd_vms_output_counted (recwr, udata->origname);
+ _bfd_vms_output_end_subrec (recwr);
+ break;
+
+ case ALPHA_R_BSR:
+ (*_bfd_error_handler) (_("Spurious ALPHA_R_BSR reloc"));
+ break;
+
+ case ALPHA_R_LDA:
+ udata
+ = (struct evax_private_udata_struct *) rptr->sym_ptr_ptr;
+ etir_output_check (abfd, section, curr_addr,
+ 32 + 1 + strlen (udata->origname));
+ _bfd_vms_output_begin_subrec (recwr, ETIR__C_STC_LDA_GBL);
+ _bfd_vms_output_long
+ (recwr, (unsigned long) udata->lkindex + 1);
+ _bfd_vms_output_long
+ (recwr, (unsigned long) section->target_index);
+ _bfd_vms_output_quad (recwr, rptr->address);
+ _bfd_vms_output_long (recwr, (unsigned long) 0x237B0000);
+ _bfd_vms_output_long
+ (recwr, (unsigned long) udata->bsym->section->target_index);
+ _bfd_vms_output_quad (recwr, rptr->addend);
+ _bfd_vms_output_counted (recwr, udata->origname);
+ _bfd_vms_output_end_subrec (recwr);
+ break;
+
+ case ALPHA_R_BOH:
+ udata
+ = (struct evax_private_udata_struct *) rptr->sym_ptr_ptr;
+ etir_output_check (abfd, section, curr_addr,
+ 32 + 1 + strlen (udata->origname));
+ _bfd_vms_output_begin_subrec (recwr, ETIR__C_STC_BOH_GBL);
+ _bfd_vms_output_long (recwr, (unsigned long) udata->lkindex);
+ _bfd_vms_output_long
+ (recwr, (unsigned long) section->target_index);
+ _bfd_vms_output_quad (recwr, rptr->address);
+ _bfd_vms_output_long (recwr, (unsigned long) 0xD3400000);
+ _bfd_vms_output_long
+ (recwr, (unsigned long) section->target_index);
+ _bfd_vms_output_quad (recwr, rptr->addend);
+ _bfd_vms_output_counted (recwr, udata->origname);
+ _bfd_vms_output_end_subrec (recwr);
+ break;
+
+ default:
+ (*_bfd_error_handler) (_("Unhandled relocation %s"),
+ rptr->howto->name);
+ break;
+ }
+
+ curr_data += size;
+ curr_addr += size;
+ } /* End of relocs loop. */
+
+ if (!pass2_in_progress)
+ {
+ /* Output rest of section. */
+ if (curr_addr > section->size)
+ (*_bfd_error_handler) (_("Size error in section %s"),
+ section->name);
+ size = section->size - curr_addr;
+ sto_imm (abfd, section, size, curr_data, curr_addr);
+ curr_data += size;
+ curr_addr += size;
+
+ if (pass2_needed)
+ {
+ pass2_in_progress = 1;
+ goto new_pass;
+ }
+ }
+ }
+
+ else /* (section->flags & SEC_RELOC) */
+ sto_imm (abfd, section, section->size, section->contents, 0);
+
+ end_etir_record (abfd);
+ }
+
+ _bfd_vms_output_alignment (recwr, 2);
+ return TRUE;
+}
+
+/* Write cached information into a file being written, at bfd_close. */
+
+static bfd_boolean
+alpha_vms_write_object_contents (bfd *abfd)
+{
+ vms_debug2 ((1, "vms_write_object_contents (%p)\n", abfd));
+
+ if (abfd->flags & (EXEC_P | DYNAMIC))
+ {
+ return alpha_vms_write_exec (abfd);
+ }
+ else
+ {
+ if (abfd->section_count > 0) /* we have sections */
+ {
+ if (_bfd_vms_write_ehdr (abfd) != TRUE)
+ return FALSE;
+ if (_bfd_vms_write_egsd (abfd) != TRUE)
+ return FALSE;
+ if (_bfd_vms_write_etir (abfd, EOBJ__C_ETIR) != TRUE)
+ return FALSE;
+ if (_bfd_vms_write_eeom (abfd) != TRUE)
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+/* Debug stuff: nearest line. */
+
+#define SET_MODULE_PARSED(m) \
+ do { if ((m)->name == NULL) (m)->name = ""; } while (0)
+#define IS_MODULE_PARSED(m) ((m)->name != NULL)
+
+/* Build a new module for the specified BFD. */
+
+static struct module *
+new_module (bfd *abfd)
+{
+ struct module *module
+ = (struct module *) bfd_zalloc (abfd, sizeof (struct module));
+ module->file_table_count = 16; /* Arbitrary. */
+ module->file_table
+ = bfd_malloc (module->file_table_count * sizeof (struct fileinfo));
+ return module;
+}
+
+/* Parse debug info for a module and internalize it. */
+
+static void
+parse_module (bfd *abfd, struct module *module, unsigned char *ptr,
+ int length)
+{
+ unsigned char *maxptr = ptr + length;
+ unsigned char *src_ptr, *pcl_ptr;
+ unsigned int prev_linum = 0, curr_linenum = 0;
+ bfd_vma prev_pc = 0, curr_pc = 0;
+ struct srecinfo *curr_srec, *srec;
+ struct lineinfo *curr_line, *line;
+ struct funcinfo *funcinfo;
+
+ /* Initialize tables with zero element. */
+ curr_srec = (struct srecinfo *) bfd_zalloc (abfd, sizeof (struct srecinfo));
+ module->srec_table = curr_srec;
+
+ curr_line = (struct lineinfo *) bfd_zalloc (abfd, sizeof (struct lineinfo));
+ module->line_table = curr_line;
+
+ while (length == -1 || ptr < maxptr)
+ {
+ /* The first byte is not counted in the recorded length. */
+ int rec_length = bfd_getl16 (ptr) + 1;
+ int rec_type = bfd_getl16 (ptr + 2);
+
+ vms_debug2 ((2, "DST record: leng %d, type %d\n", rec_length, rec_type));
+
+ if (length == -1 && rec_type == DST__K_MODEND)
+ break;
+
+ switch (rec_type)
+ {
+ case DST__K_MODBEG:
+ module->name
+ = _bfd_vms_save_counted_string (ptr + DST_S_B_MODBEG_NAME);
+
+ curr_pc = 0;
+ prev_pc = 0;
+ curr_linenum = 0;
+ prev_linum = 0;
+
+ vms_debug2 ((3, "module: %s\n", module->name));
+ break;
+
+ case DST__K_MODEND:
+ break;
+
+ case DST__K_RTNBEG:
+ funcinfo = (struct funcinfo *)
+ bfd_zalloc (abfd, sizeof (struct funcinfo));
+ funcinfo->name
+ = _bfd_vms_save_counted_string (ptr + DST_S_B_RTNBEG_NAME);
+ funcinfo->low = bfd_getl32 (ptr + DST_S_L_RTNBEG_ADDRESS);
+ funcinfo->next = module->func_table;
+ module->func_table = funcinfo;
+
+ vms_debug2 ((3, "routine: %s at 0x%lx\n",
+ funcinfo->name, (unsigned long) funcinfo->low));
+ break;
+
+ case DST__K_RTNEND:
+ module->func_table->high = module->func_table->low
+ + bfd_getl32 (ptr + DST_S_L_RTNEND_SIZE) - 1;
+
+ if (module->func_table->high > module->high)
+ module->high = module->func_table->high;
+
+ vms_debug2 ((3, "end routine\n"));
+ break;
+
+ case DST__K_PROLOG:
+ vms_debug2 ((3, "prologue\n"));
+ break;
+
+ case DST__K_EPILOG:
+ vms_debug2 ((3, "epilog\n"));
+ break;
+
+ case DST__K_BLKBEG:
+ vms_debug2 ((3, "block\n"));
+ break;
+
+ case DST__K_BLKEND:
+ vms_debug2 ((3, "end block\n"));
+ break;
+
+ case DST__K_SOURCE:
+ src_ptr = ptr + DST_S_C_SOURCE_HEADER_SIZE;
+
+ vms_debug2 ((3, "source info\n"));
+
+ while (src_ptr < ptr + rec_length)
+ {
+ int cmd = src_ptr[0], cmd_length, data;
+
+ switch (cmd)
+ {
+ case DST__K_SRC_DECLFILE:
+ {
+ unsigned int fileid
+ = bfd_getl16 (src_ptr + DST_S_W_SRC_DF_FILEID);
+ char *filename
+ = _bfd_vms_save_counted_string (src_ptr
+ + DST_S_B_SRC_DF_FILENAME);
+
+ while (fileid >= module->file_table_count)
+ {
+ module->file_table_count *= 2;
+ module->file_table
+ = bfd_realloc (module->file_table,
+ module->file_table_count
+ * sizeof (struct fileinfo));
+ }
+
+ module->file_table [fileid].name = filename;
+ module->file_table [fileid].srec = 1;
+ cmd_length = src_ptr[DST_S_B_SRC_DF_LENGTH] + 2;
+ vms_debug2 ((4, "DST_S_C_SRC_DECLFILE: %d, %s\n",
+ fileid, module->file_table [fileid].name));
+ }
+ break;
+
+ case DST__K_SRC_DEFLINES_B:
+ /* Perform the association and set the next higher index
+ to the limit. */
+ data = src_ptr[DST_S_B_SRC_UNSBYTE];
+ srec = (struct srecinfo *)
+ bfd_zalloc (abfd, sizeof (struct srecinfo));
+ srec->line = curr_srec->line + data;
+ srec->srec = curr_srec->srec + data;
+ srec->sfile = curr_srec->sfile;
+ curr_srec->next = srec;
+ curr_srec = srec;
+ cmd_length = 2;
+ vms_debug2 ((4, "DST_S_C_SRC_DEFLINES_B: %d\n", data));
+ break;
+
+ case DST__K_SRC_DEFLINES_W:
+ /* Perform the association and set the next higher index
+ to the limit. */
+ data = bfd_getl16 (src_ptr + DST_S_W_SRC_UNSWORD);
+ srec = (struct srecinfo *)
+ bfd_zalloc (abfd, sizeof (struct srecinfo));
+ srec->line = curr_srec->line + data;
+ srec->srec = curr_srec->srec + data,
+ srec->sfile = curr_srec->sfile;
+ curr_srec->next = srec;
+ curr_srec = srec;
+ cmd_length = 3;
+ vms_debug2 ((4, "DST_S_C_SRC_DEFLINES_W: %d\n", data));
+ break;
+
+ case DST__K_SRC_INCRLNUM_B:
+ data = src_ptr[DST_S_B_SRC_UNSBYTE];
+ curr_srec->line += data;
+ cmd_length = 2;
+ vms_debug2 ((4, "DST_S_C_SRC_INCRLNUM_B: %d\n", data));
+ break;
+
+ case DST__K_SRC_SETFILE:
+ data = bfd_getl16 (src_ptr + DST_S_W_SRC_UNSWORD);
+ curr_srec->sfile = data;
+ curr_srec->srec = module->file_table[data].srec;
+ cmd_length = 3;
+ vms_debug2 ((4, "DST_S_C_SRC_SETFILE: %d\n", data));
+ break;
+
+ case DST__K_SRC_SETLNUM_L:
+ data = bfd_getl32 (src_ptr + DST_S_L_SRC_UNSLONG);
+ curr_srec->line = data;
+ cmd_length = 5;
+ vms_debug2 ((4, "DST_S_C_SRC_SETLNUM_L: %d\n", data));
+ break;
+
+ case DST__K_SRC_SETLNUM_W:
+ data = bfd_getl16 (src_ptr + DST_S_W_SRC_UNSWORD);
+ curr_srec->line = data;
+ cmd_length = 3;
+ vms_debug2 ((4, "DST_S_C_SRC_SETLNUM_W: %d\n", data));
+ break;
+
+ case DST__K_SRC_SETREC_L:
+ data = bfd_getl32 (src_ptr + DST_S_L_SRC_UNSLONG);
+ curr_srec->srec = data;
+ module->file_table[curr_srec->sfile].srec = data;
+ cmd_length = 5;
+ vms_debug2 ((4, "DST_S_C_SRC_SETREC_L: %d\n", data));
+ break;
+
+ case DST__K_SRC_SETREC_W:
+ data = bfd_getl16 (src_ptr + DST_S_W_SRC_UNSWORD);
+ curr_srec->srec = data;
+ module->file_table[curr_srec->sfile].srec = data;
+ cmd_length = 3;
+ vms_debug2 ((4, "DST_S_C_SRC_SETREC_W: %d\n", data));
+ break;
+
+ case DST__K_SRC_FORMFEED:
+ cmd_length = 1;
+ vms_debug2 ((4, "DST_S_C_SRC_FORMFEED\n"));
+ break;
+
+ default:
+ (*_bfd_error_handler) (_("unknown source command %d"),
+ cmd);
+ cmd_length = 2;
+ break;
+ }
+
+ src_ptr += cmd_length;
+ }
+ break;
+
+ case DST__K_LINE_NUM:
+ pcl_ptr = ptr + DST_S_C_LINE_NUM_HEADER_SIZE;
+
+ vms_debug2 ((3, "line info\n"));
+
+ while (pcl_ptr < ptr + rec_length)
+ {
+ /* The command byte is signed so we must sign-extend it. */
+ int cmd = ((signed char *)pcl_ptr)[0], cmd_length, data;
+
+ switch (cmd)
+ {
+ case DST__K_DELTA_PC_W:
+ data = bfd_getl16 (pcl_ptr + DST_S_W_PCLINE_UNSWORD);
+ curr_pc += data;
+ curr_linenum += 1;
+ cmd_length = 3;
+ vms_debug2 ((4, "DST__K_DELTA_PC_W: %d\n", data));
+ break;
+
+ case DST__K_DELTA_PC_L:
+ data = bfd_getl32 (pcl_ptr + DST_S_L_PCLINE_UNSLONG);
+ curr_pc += data;
+ curr_linenum += 1;
+ cmd_length = 5;
+ vms_debug2 ((4, "DST__K_DELTA_PC_L: %d\n", data));
+ break;
+
+ case DST__K_INCR_LINUM:
+ data = pcl_ptr[DST_S_B_PCLINE_UNSBYTE];
+ curr_linenum += data;
+ cmd_length = 2;
+ vms_debug2 ((4, "DST__K_INCR_LINUM: %d\n", data));
+ break;
+
+ case DST__K_INCR_LINUM_W:
+ data = bfd_getl16 (pcl_ptr + DST_S_W_PCLINE_UNSWORD);
+ curr_linenum += data;
+ cmd_length = 3;
+ vms_debug2 ((4, "DST__K_INCR_LINUM_W: %d\n", data));
+ break;
+
+ case DST__K_INCR_LINUM_L:
+ data = bfd_getl32 (pcl_ptr + DST_S_L_PCLINE_UNSLONG);
+ curr_linenum += data;
+ cmd_length = 5;
+ vms_debug2 ((4, "DST__K_INCR_LINUM_L: %d\n", data));
+ break;
+
+ case DST__K_SET_LINUM_INCR:
+ (*_bfd_error_handler)
+ (_("DST__K_SET_LINUM_INCR not implemented"));
+ cmd_length = 2;
+ break;
+
+ case DST__K_SET_LINUM_INCR_W:
+ (*_bfd_error_handler)
+ (_("DST__K_SET_LINUM_INCR_W not implemented"));
+ cmd_length = 3;
+ break;
+
+ case DST__K_RESET_LINUM_INCR:
+ (*_bfd_error_handler)
+ (_("DST__K_RESET_LINUM_INCR not implemented"));
+ cmd_length = 1;
+ break;
+
+ case DST__K_BEG_STMT_MODE:
+ (*_bfd_error_handler)
+ (_("DST__K_BEG_STMT_MODE not implemented"));
+ cmd_length = 1;
+ break;
+
+ case DST__K_END_STMT_MODE:
+ (*_bfd_error_handler)
+ (_("DST__K_END_STMT_MODE not implemented"));
+ cmd_length = 1;
+ break;
+
+ case DST__K_SET_LINUM_B:
+ data = pcl_ptr[DST_S_B_PCLINE_UNSBYTE];
+ curr_linenum = data;
+ cmd_length = 2;
+ vms_debug2 ((4, "DST__K_SET_LINUM_B: %d\n", data));
+ break;
+
+ case DST__K_SET_LINUM:
+ data = bfd_getl16 (pcl_ptr + DST_S_W_PCLINE_UNSWORD);
+ curr_linenum = data;
+ cmd_length = 3;
+ vms_debug2 ((4, "DST__K_SET_LINE_NUM: %d\n", data));
+ break;
+
+ case DST__K_SET_LINUM_L:
+ data = bfd_getl32 (pcl_ptr + DST_S_L_PCLINE_UNSLONG);
+ curr_linenum = data;
+ cmd_length = 5;
+ vms_debug2 ((4, "DST__K_SET_LINUM_L: %d\n", data));
+ break;
+
+ case DST__K_SET_PC:
+ (*_bfd_error_handler)
+ (_("DST__K_SET_PC not implemented"));
+ cmd_length = 2;
+ break;
+
+ case DST__K_SET_PC_W:
+ (*_bfd_error_handler)
+ (_("DST__K_SET_PC_W not implemented"));
+ cmd_length = 3;
+ break;
+
+ case DST__K_SET_PC_L:
+ (*_bfd_error_handler)
+ (_("DST__K_SET_PC_L not implemented"));
+ cmd_length = 5;
+ break;
+
+ case DST__K_SET_STMTNUM:
+ (*_bfd_error_handler)
+ (_("DST__K_SET_STMTNUM not implemented"));
+ cmd_length = 2;
+ break;
+
+ case DST__K_TERM:
+ data = pcl_ptr[DST_S_B_PCLINE_UNSBYTE];
+ curr_pc += data;
+ cmd_length = 2;
+ vms_debug2 ((4, "DST__K_TERM: %d\n", data));
+ break;
+
+ case DST__K_TERM_W:
+ data = bfd_getl16 (pcl_ptr + DST_S_W_PCLINE_UNSWORD);
+ curr_pc += data;
+ cmd_length = 3;
+ vms_debug2 ((4, "DST__K_TERM_W: %d\n", data));
+ break;
+
+ case DST__K_TERM_L:
+ data = bfd_getl32 (pcl_ptr + DST_S_L_PCLINE_UNSLONG);
+ curr_pc += data;
+ cmd_length = 5;
+ vms_debug2 ((4, "DST__K_TERM_L: %d\n", data));
+ break;
+
+ case DST__K_SET_ABS_PC:
+ data = bfd_getl32 (pcl_ptr + DST_S_L_PCLINE_UNSLONG);
+ curr_pc = data;
+ cmd_length = 5;
+ vms_debug2 ((4, "DST__K_SET_ABS_PC: 0x%x\n", data));
+ break;
+
+ default:
+ if (cmd <= 0)
+ {
+ curr_pc -= cmd;
+ curr_linenum += 1;
+ cmd_length = 1;
+ vms_debug2 ((4, "bump pc to 0x%lx and line to %d\n",
+ (unsigned long)curr_pc, curr_linenum));
+ }
+ else
+ {
+ (*_bfd_error_handler) (_("unknown line command %d"),
+ cmd);
+ cmd_length = 2;
+ }
+ break;
+ }
+
+ if ((curr_linenum != prev_linum && curr_pc != prev_pc)
+ || cmd <= 0
+ || cmd == DST__K_DELTA_PC_L
+ || cmd == DST__K_DELTA_PC_W)
+ {
+ line = (struct lineinfo *)
+ bfd_zalloc (abfd, sizeof (struct lineinfo));
+ line->address = curr_pc;
+ line->line = curr_linenum;
+
+ curr_line->next = line;
+ curr_line = line;
+
+ prev_linum = curr_linenum;
+ prev_pc = curr_pc;
+ vms_debug2 ((4, "-> correlate pc 0x%lx with line %d\n",
+ (unsigned long)curr_pc, curr_linenum));
+ }
+
+ pcl_ptr += cmd_length;
+ }
+ break;
+
+ case 0x17: /* Undocumented type used by DEC C to declare equates. */
+ vms_debug2 ((3, "undocumented type 0x17\n"));
+ break;
+
+ default:
+ vms_debug2 ((3, "ignoring record\n"));
+ break;
+
+ }
+
+ ptr += rec_length;
+ }
+
+ /* Finalize tables with EOL marker. */
+ srec = (struct srecinfo *) bfd_zalloc (abfd, sizeof (struct srecinfo));
+ srec->line = (unsigned int) -1;
+ srec->srec = (unsigned int) -1;
+ curr_srec->next = srec;
+
+ line = (struct lineinfo *) bfd_zalloc (abfd, sizeof (struct lineinfo));
+ line->line = (unsigned int) -1;
+ line->address = (bfd_vma) -1;
+ curr_line->next = line;
+
+ /* Advertise that this module has been parsed. This is needed
+ because parsing can be either performed at module creation
+ or deferred until debug info is consumed. */
+ SET_MODULE_PARSED (module);
+}
+
+/* Build the list of modules for the specified BFD. */
+
+static struct module *
+build_module_list (bfd *abfd)
+{
+ struct module *module, *list = NULL;
+ asection *dmt;
+
+ if ((dmt = bfd_get_section_by_name (abfd, "$DMT$")))
+ {
+ /* We have a DMT section so this must be an image. Parse the
+ section and build the list of modules. This is sufficient
+ since we can compute the start address and the end address
+ of every module from the section contents. */
+ bfd_size_type size = bfd_get_section_size (dmt);
+ unsigned char *ptr, *end;
+
+ ptr = (unsigned char *) bfd_alloc (abfd, size);
+ if (! ptr)
+ return NULL;
+
+ if (! bfd_get_section_contents (abfd, dmt, ptr, 0, size))
+ return NULL;
+
+ vms_debug2 ((2, "DMT\n"));
+
+ end = ptr + size;
+
+ while (ptr < end)
+ {
+ /* Each header declares a module with its start offset and size
+ of debug info in the DST section, as well as the count of
+ program sections (i.e. address spans) it contains. */
+ int modbeg = bfd_getl32 (ptr + DBG_S_L_DMT_MODBEG);
+ int msize = bfd_getl32 (ptr + DBG_S_L_DST_SIZE);
+ int count = bfd_getl16 (ptr + DBG_S_W_DMT_PSECT_COUNT);
+ ptr += DBG_S_C_DMT_HEADER_SIZE;
+
+ vms_debug2 ((3, "module: modbeg = %d, size = %d, count = %d\n",
+ modbeg, msize, count));
+
+ /* We create a 'module' structure for each program section since
+ we only support contiguous addresses in a 'module' structure.
+ As a consequence, the actual debug info in the DST section is
+ shared and can be parsed multiple times; that doesn't seem to
+ cause problems in practice. */
+ while (count-- > 0)
+ {
+ int start = bfd_getl32 (ptr + DBG_S_L_DMT_PSECT_START);
+ int length = bfd_getl32 (ptr + DBG_S_L_DMT_PSECT_LENGTH);
+ module = new_module (abfd);
+ module->modbeg = modbeg;
+ module->size = msize;
+ module->low = start;
+ module->high = start + length;
+ module->next = list;
+ list = module;
+ ptr += DBG_S_C_DMT_PSECT_SIZE;
+
+ vms_debug2 ((4, "section: start = 0x%x, length = %d\n",
+ start, length));
+ }
+ }
+ }
+ else
+ {
+ /* We don't have a DMT section so this must be an object. Parse
+ the module right now in order to compute its start address and
+ end address. */
+ void *dst = PRIV (dst_section)->contents;
+
+ if (dst == NULL)
+ return NULL;
+
+ module = new_module (abfd);
+ parse_module (abfd, module, PRIV (dst_section)->contents, -1);
+ list = module;
+ }
+
+ return list;
+}
+
+/* Calculate and return the name of the source file and the line nearest
+ to the wanted location in the specified module. */
+
+static bfd_boolean
+module_find_nearest_line (bfd *abfd, struct module *module, bfd_vma addr,
+ const char **file, const char **func,
+ unsigned int *line)
+{
+ struct funcinfo *funcinfo;
+ struct lineinfo *lineinfo;
+ struct srecinfo *srecinfo;
+ bfd_boolean ret = FALSE;
+
+ /* Parse this module if that was not done at module creation. */
+ if (! IS_MODULE_PARSED (module))
+ {
+ unsigned int size = module->size;
+ unsigned int modbeg = PRIV (dst_section)->filepos + module->modbeg;
+ unsigned char *buffer = (unsigned char *) bfd_malloc (module->size);
+
+ if (bfd_seek (abfd, modbeg, SEEK_SET) != 0
+ || bfd_bread (buffer, size, abfd) != size)
+ {
+ bfd_set_error (bfd_error_no_debug_section);
+ return FALSE;
+ }
+
+ parse_module (abfd, module, buffer, size);
+ free (buffer);
+ }
+
+ /* Find out the function (if any) that contains the address. */
+ for (funcinfo = module->func_table; funcinfo; funcinfo = funcinfo->next)
+ if (addr >= funcinfo->low && addr <= funcinfo->high)
+ {
+ *func = funcinfo->name;
+ ret = TRUE;
+ break;
+ }
+
+ /* Find out the source file and the line nearest to the address. */
+ for (lineinfo = module->line_table; lineinfo; lineinfo = lineinfo->next)
+ if (lineinfo->next && addr < lineinfo->next->address)
+ {
+ for (srecinfo = module->srec_table; srecinfo; srecinfo = srecinfo->next)
+ if (srecinfo->next && lineinfo->line < srecinfo->next->line)
+ {
+ if (srecinfo->sfile > 0)
+ {
+ *file = module->file_table[srecinfo->sfile].name;
+ *line = srecinfo->srec + lineinfo->line - srecinfo->line;
+ }
+ else
+ {
+ *file = module->name;
+ *line = lineinfo->line;
+ }
+ return TRUE;
+ }
+
+ break;
+ }
+
+ return ret;
+}
+
+/* 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 bfd_boolean
+_bfd_vms_find_nearest_line (bfd *abfd,
+ asymbol **symbols ATTRIBUTE_UNUSED,
+ asection *section,
+ bfd_vma offset,
+ const char **file,
+ const char **func,
+ unsigned int *line,
+ unsigned int *discriminator)
+{
+ struct module *module;
+
+ /* What address are we looking for? */
+ bfd_vma addr = section->vma + offset;
+
+ *file = NULL;
+ *func = NULL;
+ *line = 0;
+ if (discriminator)
+ *discriminator = 0;
+
+ /* We can't do anything if there is no DST (debug symbol table). */
+ if (PRIV (dst_section) == NULL)
+ return FALSE;
+
+ /* Create the module list - if not already done. */
+ if (PRIV (modules) == NULL)
+ {
+ PRIV (modules) = build_module_list (abfd);
+ if (PRIV (modules) == NULL)
+ return FALSE;
+ }
+
+ for (module = PRIV (modules); module; module = module->next)
+ if (addr >= module->low && addr <= module->high)
+ return module_find_nearest_line (abfd, module, addr, file, func, line);
+
+ return FALSE;
+}
+
+/* Canonicalizations. */
+/* Set name, value, section and flags of SYM from E. */
+
+static bfd_boolean
+alpha_vms_convert_symbol (bfd *abfd, struct vms_symbol_entry *e, asymbol *sym)
+{
+ flagword flags;
+ symvalue value;
+ asection *sec;
+ const char *name;
+
+ name = e->name;
+ value = 0;
+ flags = BSF_NO_FLAGS;
+ sec = NULL;
+
+ switch (e->typ)
+ {
+ case EGSD__C_SYM:
+ if (e->flags & EGSY__V_WEAK)
+ flags |= BSF_WEAK;
+
+ if (e->flags & EGSY__V_DEF)
+ {
+ /* Symbol definition. */
+ flags |= BSF_GLOBAL;
+ if (e->flags & EGSY__V_NORM)
+ flags |= BSF_FUNCTION;
+ value = e->value;
+ sec = e->section;
+ }
+ else
+ {
+ /* Symbol reference. */
+ sec = bfd_und_section_ptr;
+ }
+ break;
+
+ case EGSD__C_SYMG:
+ /* A universal symbol is by definition global... */
+ flags |= BSF_GLOBAL;
+
+ /* ...and dynamic in shared libraries. */
+ if (abfd->flags & DYNAMIC)
+ flags |= BSF_DYNAMIC;
+
+ if (e->flags & EGSY__V_WEAK)
+ flags |= BSF_WEAK;
+
+ if (!(e->flags & EGSY__V_DEF))
+ abort ();
+
+ if (e->flags & EGSY__V_NORM)
+ flags |= BSF_FUNCTION;
+
+ value = e->value;
+ /* sec = e->section; */
+ sec = bfd_abs_section_ptr;
+ break;
+
+ default:
+ return FALSE;
+ }
+
+ sym->name = name;
+ sym->section = sec;
+ sym->flags = flags;
+ sym->value = value;
+ return TRUE;
+}
+
+
+/* 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
+alpha_vms_get_symtab_upper_bound (bfd *abfd)
+{
+ vms_debug2 ((1, "alpha_vms_get_symtab_upper_bound (%p), %d symbols\n",
+ abfd, PRIV (gsd_sym_count)));
+
+ return (PRIV (gsd_sym_count) + 1) * sizeof (asymbol *);
+}
+
+/* Read the symbols from the BFD abfd, and fills in the vector
+ location with pointers to the symbols and a trailing NULL.
+
+ Return number of symbols read. */
+
+static long
+alpha_vms_canonicalize_symtab (bfd *abfd, asymbol **symbols)
+{
+ unsigned int i;
+
+ vms_debug2 ((1, "alpha_vms_canonicalize_symtab (%p, <ret>)\n", abfd));
+
+ if (PRIV (csymbols) == NULL)
+ {
+ PRIV (csymbols) = (asymbol **) bfd_alloc
+ (abfd, PRIV (gsd_sym_count) * sizeof (asymbol *));
+
+ /* Traverse table and fill symbols vector. */
+ for (i = 0; i < PRIV (gsd_sym_count); i++)
+ {
+ struct vms_symbol_entry *e = PRIV (syms)[i];
+ asymbol *sym;
+
+ sym = bfd_make_empty_symbol (abfd);
+ if (sym == NULL || !alpha_vms_convert_symbol (abfd, e, sym))
+ {
+ bfd_release (abfd, PRIV (csymbols));
+ PRIV (csymbols) = NULL;
+ return -1;
+ }
+
+ PRIV (csymbols)[i] = sym;
+ }
+ }
+
+ if (symbols != NULL)
+ {
+ for (i = 0; i < PRIV (gsd_sym_count); i++)
+ symbols[i] = PRIV (csymbols)[i];
+ symbols[i] = NULL;
+ }
+
+ return PRIV (gsd_sym_count);
+}
+
+/* Read and convert relocations from ETIR. We do it once for all sections. */
+
+static bfd_boolean
+alpha_vms_slurp_relocs (bfd *abfd)
+{
+ int cur_psect = -1;
+
+ vms_debug2 ((3, "alpha_vms_slurp_relocs\n"));
+
+ /* We slurp relocs only once, for all sections. */
+ if (PRIV (reloc_done))
+ return TRUE;
+ PRIV (reloc_done) = TRUE;
+
+ if (alpha_vms_canonicalize_symtab (abfd, NULL) < 0)
+ return FALSE;
+
+ if (bfd_seek (abfd, 0, SEEK_SET) != 0)
+ return FALSE;
+
+ while (1)
+ {
+ unsigned char *begin;
+ unsigned char *end;
+ unsigned char *ptr;
+ bfd_reloc_code_real_type reloc_code;
+ int type;
+ bfd_vma vaddr = 0;
+
+ int length;
+
+ bfd_vma cur_address;
+ int cur_psidx = -1;
+ unsigned char *cur_sym = NULL;
+ int prev_cmd = -1;
+ bfd_vma cur_addend = 0;
+
+ /* Skip non-ETIR records. */
+ type = _bfd_vms_get_object_record (abfd);
+ if (type == EOBJ__C_EEOM)
+ break;
+ if (type != EOBJ__C_ETIR)
+ continue;
+
+ begin = PRIV (recrd.rec) + 4;
+ end = PRIV (recrd.rec) + PRIV (recrd.rec_size);
+
+ for (ptr = begin; ptr < end; ptr += length)
+ {
+ int cmd;
+
+ cmd = bfd_getl16 (ptr);
+ length = bfd_getl16 (ptr + 2);
+
+ cur_address = vaddr;
+
+ vms_debug2 ((4, "alpha_vms_slurp_relocs: etir %s\n",
+ _bfd_vms_etir_name (cmd)));
+
+ switch (cmd)
+ {
+ case ETIR__C_STA_GBL: /* ALPHA_R_REFLONG und_section, step 1 */
+ /* ALPHA_R_REFQUAD und_section, step 1 */
+ cur_sym = ptr + 4;
+ prev_cmd = cmd;
+ continue;
+
+ case ETIR__C_STA_PQ: /* ALPHA_R_REF{LONG|QUAD}, others part 1 */
+ cur_psidx = bfd_getl32 (ptr + 4);
+ cur_addend = bfd_getl64 (ptr + 8);
+ prev_cmd = cmd;
+ continue;
+
+ case ETIR__C_CTL_SETRB:
+ if (prev_cmd != ETIR__C_STA_PQ)
+ {
+ (*_bfd_error_handler)
+ (_("Unknown reloc %s + %s"), _bfd_vms_etir_name (prev_cmd),
+ _bfd_vms_etir_name (cmd));
+ return FALSE;
+ }
+ cur_psect = cur_psidx;
+ vaddr = cur_addend;
+ cur_psidx = -1;
+ cur_addend = 0;
+ continue;
+
+ case ETIR__C_STA_LW: /* ALPHA_R_REFLONG abs_section, step 1 */
+ /* ALPHA_R_REFLONG und_section, step 2 */
+ if (prev_cmd != -1)
+ {
+ if (prev_cmd != ETIR__C_STA_GBL)
+ {
+ (*_bfd_error_handler)
+ (_("Unknown reloc %s + %s"), _bfd_vms_etir_name (cmd),
+ _bfd_vms_etir_name (ETIR__C_STA_LW));
+ return FALSE;
+ }
+ }
+ cur_addend = bfd_getl32 (ptr + 4);
+ prev_cmd = cmd;
+ continue;
+
+ case ETIR__C_STA_QW: /* ALPHA_R_REFQUAD abs_section, step 1 */
+ /* ALPHA_R_REFQUAD und_section, step 2 */
+ if (prev_cmd != -1 && prev_cmd != ETIR__C_STA_GBL)
+ {
+ (*_bfd_error_handler)
+ (_("Unknown reloc %s + %s"), _bfd_vms_etir_name (cmd),
+ _bfd_vms_etir_name (ETIR__C_STA_QW));
+ return FALSE;
+ }
+ cur_addend = bfd_getl64 (ptr + 4);
+ prev_cmd = cmd;
+ continue;
+
+ case ETIR__C_STO_LW: /* ALPHA_R_REFLONG und_section, step 4 */
+ /* ALPHA_R_REFLONG abs_section, step 2 */
+ /* ALPHA_R_REFLONG others, step 2 */
+ if (prev_cmd != ETIR__C_OPR_ADD
+ && prev_cmd != ETIR__C_STA_LW
+ && prev_cmd != ETIR__C_STA_PQ)
+ {
+ (*_bfd_error_handler) (_("Unknown reloc %s + %s"),
+ _bfd_vms_etir_name (prev_cmd),
+ _bfd_vms_etir_name (ETIR__C_STO_LW));
+ return FALSE;
+ }
+ reloc_code = BFD_RELOC_32;
+ break;
+
+ case ETIR__C_STO_QW: /* ALPHA_R_REFQUAD und_section, step 4 */
+ /* ALPHA_R_REFQUAD abs_section, step 2 */
+ if (prev_cmd != ETIR__C_OPR_ADD && prev_cmd != ETIR__C_STA_QW)
+ {
+ (*_bfd_error_handler) (_("Unknown reloc %s + %s"),
+ _bfd_vms_etir_name (prev_cmd),
+ _bfd_vms_etir_name (ETIR__C_STO_QW));
+ return FALSE;
+ }
+ reloc_code = BFD_RELOC_64;
+ break;
+
+ case ETIR__C_STO_OFF: /* ALPHA_R_REFQUAD others, step 2 */
+ if (prev_cmd != ETIR__C_STA_PQ)
+ {
+ (*_bfd_error_handler) (_("Unknown reloc %s + %s"),
+ _bfd_vms_etir_name (prev_cmd),
+ _bfd_vms_etir_name (ETIR__C_STO_OFF));
+ return FALSE;
+ }
+ reloc_code = BFD_RELOC_64;
+ break;
+
+ case ETIR__C_OPR_ADD: /* ALPHA_R_REFLONG und_section, step 3 */
+ /* ALPHA_R_REFQUAD und_section, step 3 */
+ if (prev_cmd != ETIR__C_STA_LW && prev_cmd != ETIR__C_STA_QW)
+ {
+ (*_bfd_error_handler) (_("Unknown reloc %s + %s"),
+ _bfd_vms_etir_name (prev_cmd),
+ _bfd_vms_etir_name (ETIR__C_OPR_ADD));
+ return FALSE;
+ }
+ prev_cmd = ETIR__C_OPR_ADD;
+ continue;
+
+ case ETIR__C_STO_CA: /* ALPHA_R_CODEADDR */
+ reloc_code = BFD_RELOC_ALPHA_CODEADDR;
+ cur_sym = ptr + 4;
+ break;
+
+ case ETIR__C_STO_GBL: /* ALPHA_R_REFQUAD und_section */
+ reloc_code = BFD_RELOC_64;
+ cur_sym = ptr + 4;
+ break;
+
+ case ETIR__C_STO_GBL_LW: /* ALPHA_R_REFLONG und_section */
+ reloc_code = BFD_RELOC_32;
+ cur_sym = ptr + 4;
+ break;
+
+ case ETIR__C_STC_LP_PSB: /* ALPHA_R_LINKAGE */
+ reloc_code = BFD_RELOC_ALPHA_LINKAGE;
+ cur_sym = ptr + 8;
+ break;
+
+ case ETIR__C_STC_NOP_GBL: /* ALPHA_R_NOP */
+ reloc_code = BFD_RELOC_ALPHA_NOP;
+ goto call_reloc;
+
+ case ETIR__C_STC_BSR_GBL: /* ALPHA_R_BSR */
+ reloc_code = BFD_RELOC_ALPHA_BSR;
+ goto call_reloc;
+
+ case ETIR__C_STC_LDA_GBL: /* ALPHA_R_LDA */
+ reloc_code = BFD_RELOC_ALPHA_LDA;
+ goto call_reloc;
+
+ case ETIR__C_STC_BOH_GBL: /* ALPHA_R_BOH */
+ reloc_code = BFD_RELOC_ALPHA_BOH;
+ goto call_reloc;
+
+ call_reloc:
+ cur_sym = ptr + 4 + 32;
+ cur_address = bfd_getl64 (ptr + 4 + 8);
+ cur_addend = bfd_getl64 (ptr + 4 + 24);
+ break;
+
+ case ETIR__C_STO_IMM:
+ vaddr += bfd_getl32 (ptr + 4);
+ continue;
+
+ default:
+ (*_bfd_error_handler) (_("Unknown reloc %s"),
+ _bfd_vms_etir_name (cmd));
+ return FALSE;
+ }
+
+ {
+ asection *sec;
+ struct vms_section_data_struct *vms_sec;
+ arelent *reloc;
+
+ /* Get section to which the relocation applies. */
+ if (cur_psect < 0 || cur_psect > (int)PRIV (section_count))
+ {
+ (*_bfd_error_handler) (_("Invalid section index in ETIR"));
+ return FALSE;
+ }
+
+ sec = PRIV (sections)[cur_psect];
+ if (sec == bfd_abs_section_ptr)
+ {
+ (*_bfd_error_handler) (_("Relocation for non-REL psect"));
+ return FALSE;
+ }
+
+ vms_sec = vms_section_data (sec);
+
+ /* Allocate a reloc entry. */
+ if (sec->reloc_count >= vms_sec->reloc_max)
+ {
+ if (vms_sec->reloc_max == 0)
+ {
+ vms_sec->reloc_max = 64;
+ sec->relocation = bfd_zmalloc
+ (vms_sec->reloc_max * sizeof (arelent));
+ }
+ else
+ {
+ vms_sec->reloc_max *= 2;
+ sec->relocation = bfd_realloc
+ (sec->relocation, vms_sec->reloc_max * sizeof (arelent));
+ }
+ }
+ reloc = &sec->relocation[sec->reloc_count];
+ sec->reloc_count++;
+
+ reloc->howto = bfd_reloc_type_lookup (abfd, reloc_code);
+
+ if (cur_sym != NULL)
+ {
+ unsigned int j;
+ unsigned int symlen = *cur_sym;
+ asymbol **sym;
+
+ /* Linear search. */
+ symlen = *cur_sym;
+ cur_sym++;
+ sym = NULL;
+
+ for (j = 0; j < PRIV (gsd_sym_count); j++)
+ if (PRIV (syms)[j]->namelen == symlen
+ && memcmp (PRIV (syms)[j]->name, cur_sym, symlen) == 0)
+ {
+ sym = &PRIV (csymbols)[j];
+ break;
+ }
+ if (sym == NULL)
+ {
+ (*_bfd_error_handler) (_("Unknown symbol in command %s"),
+ _bfd_vms_etir_name (cmd));
+ reloc->sym_ptr_ptr = NULL;
+ }
+ else
+ reloc->sym_ptr_ptr = sym;
+ }
+ else if (cur_psidx >= 0)
+ reloc->sym_ptr_ptr =
+ PRIV (sections)[cur_psidx]->symbol_ptr_ptr;
+ else
+ reloc->sym_ptr_ptr = NULL;
+
+ reloc->address = cur_address;
+ reloc->addend = cur_addend;
+
+ vaddr += bfd_get_reloc_size (reloc->howto);
+ }
+
+ cur_addend = 0;
+ prev_cmd = -1;
+ cur_sym = NULL;
+ cur_psidx = -1;
+ }
+ }
+ vms_debug2 ((3, "alpha_vms_slurp_relocs: result = TRUE\n"));
+
+ return TRUE;
+}
+
+/* Return the number of bytes required to store the relocation
+ information associated with the given section. */
+
+static long
+alpha_vms_get_reloc_upper_bound (bfd *abfd ATTRIBUTE_UNUSED, asection *section)
+{
+ alpha_vms_slurp_relocs (abfd);
+
+ return (section->reloc_count + 1) * sizeof (arelent *);
+}
+
+/* Convert relocations from VMS (external) form into BFD internal
+ form. Return the number of relocations. */
+
+static long
+alpha_vms_canonicalize_reloc (bfd *abfd, asection *section, arelent **relptr,
+ asymbol **symbols ATTRIBUTE_UNUSED)
+{
+ arelent *tblptr;
+ int count;
+
+ if (!alpha_vms_slurp_relocs (abfd))
+ return -1;
+
+ count = section->reloc_count;
+ tblptr = section->relocation;
+
+ while (count--)
+ *relptr++ = tblptr++;
+
+ *relptr = (arelent *) NULL;
+ return section->reloc_count;
+}
+
+/* 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 (bfd * abfd ATTRIBUTE_UNUSED,
+ arelent *reloc ATTRIBUTE_UNUSED,
+ asymbol *sym ATTRIBUTE_UNUSED,
+ void * data ATTRIBUTE_UNUSED,
+ asection *sec ATTRIBUTE_UNUSED,
+ bfd *output_bfd ATTRIBUTE_UNUSED,
+ char **error_message ATTRIBUTE_UNUSED)
+{
+#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, /* Source mask */
+ 0, /* Dest mask. */
+ TRUE), /* PC rel 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, /* Source mask. */
+ MINUS_ONE, /* Dest mask. */
+ FALSE), /* PC rel 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, /* Source mask. */
+ 0x1fffff, /* Dest mask. */
+ FALSE), /* PC rel 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, /* Source mask. */
+ 0x3fff, /* Dest mask. */
+ FALSE), /* PC rel 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, /* Source mask. */
+ 0xffff, /* Dest mask. */
+ FALSE), /* PC rel 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, /* Source mask. */
+ 0xffffffff, /* Dest mask. */
+ FALSE), /* PC rel 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, /* Source mask. */
+ MINUS_ONE, /* Dest mask. */
+ FALSE), /* PC rel 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, /* Source mask. */
+ 0, /* Dest mask. */
+ FALSE), /* PC rel 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, /* Source mask. */
+ MINUS_ONE, /* Dest mask. */
+ FALSE), /* PC rel 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, /* Source mask. */
+ 0, /* Dest mask. */
+ FALSE), /* PC rel 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, /* Source mask. */
+ 0, /* Dest mask. */
+ FALSE), /* PC rel 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, /* Source mask. */
+ 0, /* Dest mask. */
+ FALSE), /* PC rel 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, /* Source mask. */
+ 0xffffffff, /* Dest mask. */
+ FALSE), /* PC rel 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, /* Source mask. */
+ 0xffffffff, /* Dest mask. */
+ FALSE), /* PC rel offset. */
+
+ HOWTO (ALPHA_R_NOP, /* Type. */
+ 0, /* Rightshift. */
+ 3, /* Size (0 = byte, 1 = short, 2 = long). */
+ 0, /* Bitsize. */
+ /* The following value must match that of ALPHA_R_BSR/ALPHA_R_BOH
+ because the calculations for the 3 relocations are the same.
+ See B.4.5.2 of the OpenVMS Linker Utility Manual. */
+ TRUE, /* PC relative. */
+ 0, /* Bitpos. */
+ complain_overflow_dont,/* Complain_on_overflow. */
+ reloc_nil, /* Special_function. */
+ "NOP", /* Name. */
+ FALSE, /* Partial_inplace. */
+ 0xffffffff, /* Source mask. */
+ 0xffffffff, /* Dest mask. */
+ FALSE), /* PC rel offset. */
+
+ HOWTO (ALPHA_R_BSR, /* Type. */
+ 0, /* Rightshift. */
+ 3, /* Size (0 = byte, 1 = short, 2 = long). */
+ 0, /* Bitsize. */
+ TRUE, /* PC relative. */
+ 0, /* Bitpos. */
+ complain_overflow_dont,/* Complain_on_overflow. */
+ reloc_nil, /* Special_function. */
+ "BSR", /* Name. */
+ FALSE, /* Partial_inplace. */
+ 0xffffffff, /* Source mask. */
+ 0xffffffff, /* Dest mask. */
+ FALSE), /* PC rel offset. */
+
+ HOWTO (ALPHA_R_LDA, /* Type. */
+ 0, /* Rightshift. */
+ 3, /* Size (0 = byte, 1 = short, 2 = long). */
+ 0, /* Bitsize. */
+ FALSE, /* PC relative. */
+ 0, /* Bitpos. */
+ complain_overflow_dont,/* Complain_on_overflow. */
+ reloc_nil, /* Special_function. */
+ "LDA", /* Name. */
+ FALSE, /* Partial_inplace. */
+ 0xffffffff, /* Source mask. */
+ 0xffffffff, /* Dest mask. */
+ FALSE), /* PC rel offset. */
+
+ HOWTO (ALPHA_R_BOH, /* Type. */
+ 0, /* Rightshift. */
+ 3, /* Size (0 = byte, 1 = short, 2 = long, 3 = nil). */
+ 0, /* Bitsize. */
+ TRUE, /* PC relative. */
+ 0, /* Bitpos. */
+ complain_overflow_dont,/* Complain_on_overflow. */
+ reloc_nil, /* Special_function. */
+ "BOH", /* Name. */
+ FALSE, /* Partial_inplace. */
+ 0xffffffff, /* Source mask. */
+ 0xffffffff, /* Dest mask. */
+ FALSE), /* PC rel 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 *
+alpha_vms_bfd_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED,
+ bfd_reloc_code_real_type code)
+{
+ int alpha_type;
+
+ vms_debug2 ((1, "vms_bfd_reloc_type_lookup (%p, %d)\t", abfd, code));
+
+ 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;
+ case BFD_RELOC_ALPHA_NOP: alpha_type = ALPHA_R_NOP; break;
+ case BFD_RELOC_ALPHA_BSR: alpha_type = ALPHA_R_BSR; break;
+ case BFD_RELOC_ALPHA_LDA: alpha_type = ALPHA_R_LDA; break;
+ case BFD_RELOC_ALPHA_BOH: alpha_type = ALPHA_R_BOH; break;
+ default:
+ (*_bfd_error_handler) ("reloc (%d) is *UNKNOWN*", code);
+ return NULL;
+ }
+ vms_debug2 ((2, "reloc is %s\n", alpha_howto_table[alpha_type].name));
+ return & alpha_howto_table[alpha_type];
+}
+
+static reloc_howto_type *
+alpha_vms_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ const char *r_name)
+{
+ unsigned int i;
+
+ for (i = 0;
+ i < sizeof (alpha_howto_table) / sizeof (alpha_howto_table[0]);
+ i++)
+ if (alpha_howto_table[i].name != NULL
+ && strcasecmp (alpha_howto_table[i].name, r_name) == 0)
+ return &alpha_howto_table[i];
+
+ return NULL;
+}
+
+static long
+alpha_vms_get_synthetic_symtab (bfd *abfd,
+ long symcount ATTRIBUTE_UNUSED,
+ asymbol **usyms ATTRIBUTE_UNUSED,
+ long dynsymcount ATTRIBUTE_UNUSED,
+ asymbol **dynsyms ATTRIBUTE_UNUSED,
+ asymbol **ret)
+{
+ asymbol *syms;
+ unsigned int i;
+ unsigned int n = 0;
+
+ syms = (asymbol *) bfd_malloc (PRIV (norm_sym_count) * sizeof (asymbol));
+ *ret = syms;
+ if (syms == NULL)
+ return -1;
+
+ for (i = 0; i < PRIV (gsd_sym_count); i++)
+ {
+ struct vms_symbol_entry *e = PRIV (syms)[i];
+ asymbol *sym;
+ flagword flags;
+ symvalue value;
+ asection *sec;
+ const char *name;
+ char *sname;
+ int l;
+
+ name = e->name;
+ value = 0;
+ flags = BSF_LOCAL | BSF_SYNTHETIC;
+ sec = NULL;
+
+ switch (e->typ)
+ {
+ case EGSD__C_SYM:
+ case EGSD__C_SYMG:
+ if ((e->flags & EGSY__V_DEF) && (e->flags & EGSY__V_NORM))
+ {
+ value = e->code_value;
+ sec = e->code_section;
+ }
+ else
+ continue;
+ break;
+
+ default:
+ continue;
+ }
+
+ l = strlen (name);
+ sname = bfd_alloc (abfd, l + 5);
+ if (sname == NULL)
+ return FALSE;
+ memcpy (sname, name, l);
+ memcpy (sname + l, "..en", 5);
+
+ sym = &syms[n++];
+ sym->name = sname;
+ sym->section = sec;
+ sym->flags = flags;
+ sym->value = value;
+ sym->udata.p = NULL;
+ }
+
+ return n;
+}
+
+/* Private dump. */
+
+static const char *
+vms_time_to_str (unsigned char *buf)
+{
+ time_t t = vms_rawtime_to_time_t (buf);
+ char *res = ctime (&t);
+
+ if (!res)
+ res = "*invalid time*";
+ else
+ res[24] = 0;
+ return res;
+}
+
+static void
+evax_bfd_print_emh (FILE *file, unsigned char *rec, unsigned int rec_len)
+{
+ struct vms_emh_common *emh = (struct vms_emh_common *)rec;
+ unsigned int subtype;
+
+ subtype = (unsigned)bfd_getl16 (emh->subtyp);
+
+ fprintf (file, _(" EMH %u (len=%u): "), subtype, rec_len);
+
+ switch (subtype)
+ {
+ case EMH__C_MHD:
+ {
+ struct vms_emh_mhd *mhd = (struct vms_emh_mhd *)rec;
+ const char *name;
+
+ fprintf (file, _("Module header\n"));
+ fprintf (file, _(" structure level: %u\n"), mhd->strlvl);
+ fprintf (file, _(" max record size: %u\n"),
+ (unsigned)bfd_getl32 (mhd->recsiz));
+ name = (char *)(mhd + 1);
+ fprintf (file, _(" module name : %.*s\n"), name[0], name + 1);
+ name += name[0] + 1;
+ fprintf (file, _(" module version : %.*s\n"), name[0], name + 1);
+ name += name[0] + 1;
+ fprintf (file, _(" compile date : %.17s\n"), name);
+ }
+ break;
+ case EMH__C_LNM:
+ {
+ fprintf (file, _("Language Processor Name\n"));
+ fprintf (file, _(" language name: %.*s\n"),
+ (int)(rec_len - sizeof (struct vms_emh_common)),
+ (char *)rec + sizeof (struct vms_emh_common));
+ }
+ break;
+ case EMH__C_SRC:
+ {
+ fprintf (file, _("Source Files Header\n"));
+ fprintf (file, _(" file: %.*s\n"),
+ (int)(rec_len - sizeof (struct vms_emh_common)),
+ (char *)rec + sizeof (struct vms_emh_common));
+ }
+ break;
+ case EMH__C_TTL:
+ {
+ fprintf (file, _("Title Text Header\n"));
+ fprintf (file, _(" title: %.*s\n"),
+ (int)(rec_len - sizeof (struct vms_emh_common)),
+ (char *)rec + sizeof (struct vms_emh_common));
+ }
+ break;
+ case EMH__C_CPR:
+ {
+ fprintf (file, _("Copyright Header\n"));
+ fprintf (file, _(" copyright: %.*s\n"),
+ (int)(rec_len - sizeof (struct vms_emh_common)),
+ (char *)rec + sizeof (struct vms_emh_common));
+ }
+ break;
+ default:
+ fprintf (file, _("unhandled emh subtype %u\n"), subtype);
+ break;
+ }
+}
+
+static void
+evax_bfd_print_eeom (FILE *file, unsigned char *rec, unsigned int rec_len)
+{
+ struct vms_eeom *eeom = (struct vms_eeom *)rec;
+
+ fprintf (file, _(" EEOM (len=%u):\n"), rec_len);
+ fprintf (file, _(" number of cond linkage pairs: %u\n"),
+ (unsigned)bfd_getl32 (eeom->total_lps));
+ fprintf (file, _(" completion code: %u\n"),
+ (unsigned)bfd_getl16 (eeom->comcod));
+ if (rec_len > 10)
+ {
+ fprintf (file, _(" transfer addr flags: 0x%02x\n"), eeom->tfrflg);
+ fprintf (file, _(" transfer addr psect: %u\n"),
+ (unsigned)bfd_getl32 (eeom->psindx));
+ fprintf (file, _(" transfer address : 0x%08x\n"),
+ (unsigned)bfd_getl32 (eeom->tfradr));
+ }
+}
+
+static void
+exav_bfd_print_egsy_flags (unsigned int flags, FILE *file)
+{
+ if (flags & EGSY__V_WEAK)
+ fputs (_(" WEAK"), file);
+ if (flags & EGSY__V_DEF)
+ fputs (_(" DEF"), file);
+ if (flags & EGSY__V_UNI)
+ fputs (_(" UNI"), file);
+ if (flags & EGSY__V_REL)
+ fputs (_(" REL"), file);
+ if (flags & EGSY__V_COMM)
+ fputs (_(" COMM"), file);
+ if (flags & EGSY__V_VECEP)
+ fputs (_(" VECEP"), file);
+ if (flags & EGSY__V_NORM)
+ fputs (_(" NORM"), file);
+ if (flags & EGSY__V_QUAD_VAL)
+ fputs (_(" QVAL"), file);
+}
+
+static void
+evax_bfd_print_egsd_flags (FILE *file, unsigned int flags)
+{
+ if (flags & EGPS__V_PIC)
+ fputs (_(" PIC"), file);
+ if (flags & EGPS__V_LIB)
+ fputs (_(" LIB"), file);
+ if (flags & EGPS__V_OVR)
+ fputs (_(" OVR"), file);
+ if (flags & EGPS__V_REL)
+ fputs (_(" REL"), file);
+ if (flags & EGPS__V_GBL)
+ fputs (_(" GBL"), file);
+ if (flags & EGPS__V_SHR)
+ fputs (_(" SHR"), file);
+ if (flags & EGPS__V_EXE)
+ fputs (_(" EXE"), file);
+ if (flags & EGPS__V_RD)
+ fputs (_(" RD"), file);
+ if (flags & EGPS__V_WRT)
+ fputs (_(" WRT"), file);
+ if (flags & EGPS__V_VEC)
+ fputs (_(" VEC"), file);
+ if (flags & EGPS__V_NOMOD)
+ fputs (_(" NOMOD"), file);
+ if (flags & EGPS__V_COM)
+ fputs (_(" COM"), file);
+ if (flags & EGPS__V_ALLOC_64BIT)
+ fputs (_(" 64B"), file);
+}
+
+static void
+evax_bfd_print_egsd (FILE *file, unsigned char *rec, unsigned int rec_len)
+{
+ unsigned int off = sizeof (struct vms_egsd);
+ unsigned int n;
+
+ fprintf (file, _(" EGSD (len=%u):\n"), rec_len);
+
+ n = 0;
+ for (off = sizeof (struct vms_egsd); off < rec_len; )
+ {
+ struct vms_egsd_entry *e = (struct vms_egsd_entry *)(rec + off);
+ unsigned int type;
+ unsigned int len;
+
+ type = (unsigned)bfd_getl16 (e->gsdtyp);
+ len = (unsigned)bfd_getl16 (e->gsdsiz);
+
+ fprintf (file, _(" EGSD entry %2u (type: %u, len: %u): "),
+ n, type, len);
+ n++;
+
+ switch (type)
+ {
+ case EGSD__C_PSC:
+ {
+ struct vms_egps *egps = (struct vms_egps *)e;
+ unsigned int flags = bfd_getl16 (egps->flags);
+ unsigned int l;
+
+ fprintf (file, _("PSC - Program section definition\n"));
+ fprintf (file, _(" alignment : 2**%u\n"), egps->align);
+ fprintf (file, _(" flags : 0x%04x"), flags);
+ evax_bfd_print_egsd_flags (file, flags);
+ fputc ('\n', file);
+ l = bfd_getl32 (egps->alloc);
+ fprintf (file, _(" alloc (len): %u (0x%08x)\n"), l, l);
+ fprintf (file, _(" name : %.*s\n"),
+ egps->namlng, egps->name);
+ }
+ break;
+ case EGSD__C_SPSC:
+ {
+ struct vms_esgps *esgps = (struct vms_esgps *)e;
+ unsigned int flags = bfd_getl16 (esgps->flags);
+ unsigned int l;
+
+ fprintf (file, _("SPSC - Shared Image Program section def\n"));
+ fprintf (file, _(" alignment : 2**%u\n"), esgps->align);
+ fprintf (file, _(" flags : 0x%04x"), flags);
+ evax_bfd_print_egsd_flags (file, flags);
+ fputc ('\n', file);
+ l = bfd_getl32 (esgps->alloc);
+ fprintf (file, _(" alloc (len) : %u (0x%08x)\n"), l, l);
+ fprintf (file, _(" image offset : 0x%08x\n"),
+ (unsigned int)bfd_getl32 (esgps->base));
+ fprintf (file, _(" symvec offset : 0x%08x\n"),
+ (unsigned int)bfd_getl32 (esgps->value));
+ fprintf (file, _(" name : %.*s\n"),
+ esgps->namlng, esgps->name);
+ }
+ break;
+ case EGSD__C_SYM:
+ {
+ struct vms_egsy *egsy = (struct vms_egsy *)e;
+ unsigned int flags = bfd_getl16 (egsy->flags);
+
+ if (flags & EGSY__V_DEF)
+ {
+ struct vms_esdf *esdf = (struct vms_esdf *)e;
+
+ fprintf (file, _("SYM - Global symbol definition\n"));
+ fprintf (file, _(" flags: 0x%04x"), flags);
+ exav_bfd_print_egsy_flags (flags, file);
+ fputc ('\n', file);
+ fprintf (file, _(" psect offset: 0x%08x\n"),
+ (unsigned)bfd_getl32 (esdf->value));
+ if (flags & EGSY__V_NORM)
+ {
+ fprintf (file, _(" code address: 0x%08x\n"),
+ (unsigned)bfd_getl32 (esdf->code_address));
+ fprintf (file, _(" psect index for entry point : %u\n"),
+ (unsigned)bfd_getl32 (esdf->ca_psindx));
+ }
+ fprintf (file, _(" psect index : %u\n"),
+ (unsigned)bfd_getl32 (esdf->psindx));
+ fprintf (file, _(" name : %.*s\n"),
+ esdf->namlng, esdf->name);
+ }
+ else
+ {
+ struct vms_esrf *esrf = (struct vms_esrf *)e;
+
+ fprintf (file, _("SYM - Global symbol reference\n"));
+ fprintf (file, _(" name : %.*s\n"),
+ esrf->namlng, esrf->name);
+ }
+ }
+ break;
+ case EGSD__C_IDC:
+ {
+ struct vms_eidc *eidc = (struct vms_eidc *)e;
+ unsigned int flags = bfd_getl32 (eidc->flags);
+ unsigned char *p;
+
+ fprintf (file, _("IDC - Ident Consistency check\n"));
+ fprintf (file, _(" flags : 0x%08x"), flags);
+ if (flags & EIDC__V_BINIDENT)
+ fputs (" BINDENT", file);
+ fputc ('\n', file);
+ fprintf (file, _(" id match : %x\n"),
+ (flags >> EIDC__V_IDMATCH_SH) & EIDC__V_IDMATCH_MASK);
+ fprintf (file, _(" error severity: %x\n"),
+ (flags >> EIDC__V_ERRSEV_SH) & EIDC__V_ERRSEV_MASK);
+ p = eidc->name;
+ fprintf (file, _(" entity name : %.*s\n"), p[0], p + 1);
+ p += 1 + p[0];
+ fprintf (file, _(" object name : %.*s\n"), p[0], p + 1);
+ p += 1 + p[0];
+ if (flags & EIDC__V_BINIDENT)
+ fprintf (file, _(" binary ident : 0x%08x\n"),
+ (unsigned)bfd_getl32 (p + 1));
+ else
+ fprintf (file, _(" ascii ident : %.*s\n"), p[0], p + 1);
+ }
+ break;
+ case EGSD__C_SYMG:
+ {
+ struct vms_egst *egst = (struct vms_egst *)e;
+ unsigned int flags = bfd_getl16 (egst->header.flags);
+
+ fprintf (file, _("SYMG - Universal symbol definition\n"));
+ fprintf (file, _(" flags: 0x%04x"), flags);
+ exav_bfd_print_egsy_flags (flags, file);
+ fputc ('\n', file);
+ fprintf (file, _(" symbol vector offset: 0x%08x\n"),
+ (unsigned)bfd_getl32 (egst->value));
+ fprintf (file, _(" entry point: 0x%08x\n"),
+ (unsigned)bfd_getl32 (egst->lp_1));
+ fprintf (file, _(" proc descr : 0x%08x\n"),
+ (unsigned)bfd_getl32 (egst->lp_2));
+ fprintf (file, _(" psect index: %u\n"),
+ (unsigned)bfd_getl32 (egst->psindx));
+ fprintf (file, _(" name : %.*s\n"),
+ egst->namlng, egst->name);
+ }
+ break;
+ case EGSD__C_SYMV:
+ {
+ struct vms_esdfv *esdfv = (struct vms_esdfv *)e;
+ unsigned int flags = bfd_getl16 (esdfv->flags);
+
+ fprintf (file, _("SYMV - Vectored symbol definition\n"));
+ fprintf (file, _(" flags: 0x%04x"), flags);
+ exav_bfd_print_egsy_flags (flags, file);
+ fputc ('\n', file);
+ fprintf (file, _(" vector : 0x%08x\n"),
+ (unsigned)bfd_getl32 (esdfv->vector));
+ fprintf (file, _(" psect offset: %u\n"),
+ (unsigned)bfd_getl32 (esdfv->value));
+ fprintf (file, _(" psect index : %u\n"),
+ (unsigned)bfd_getl32 (esdfv->psindx));
+ fprintf (file, _(" name : %.*s\n"),
+ esdfv->namlng, esdfv->name);
+ }
+ break;
+ case EGSD__C_SYMM:
+ {
+ struct vms_esdfm *esdfm = (struct vms_esdfm *)e;
+ unsigned int flags = bfd_getl16 (esdfm->flags);
+
+ fprintf (file, _("SYMM - Global symbol definition with version\n"));
+ fprintf (file, _(" flags: 0x%04x"), flags);
+ exav_bfd_print_egsy_flags (flags, file);
+ fputc ('\n', file);
+ fprintf (file, _(" version mask: 0x%08x\n"),
+ (unsigned)bfd_getl32 (esdfm->version_mask));
+ fprintf (file, _(" psect offset: %u\n"),
+ (unsigned)bfd_getl32 (esdfm->value));
+ fprintf (file, _(" psect index : %u\n"),
+ (unsigned)bfd_getl32 (esdfm->psindx));
+ fprintf (file, _(" name : %.*s\n"),
+ esdfm->namlng, esdfm->name);
+ }
+ break;
+ default:
+ fprintf (file, _("unhandled egsd entry type %u\n"), type);
+ break;
+ }
+ off += len;
+ }
+}
+
+static void
+evax_bfd_print_hex (FILE *file, const char *pfx,
+ const unsigned char *buf, unsigned int len)
+{
+ unsigned int i;
+ unsigned int n;
+
+ n = 0;
+ for (i = 0; i < len; i++)
+ {
+ if (n == 0)
+ fputs (pfx, file);
+ fprintf (file, " %02x", buf[i]);
+ n++;
+ if (n == 16)
+ {
+ n = 0;
+ fputc ('\n', file);
+ }
+ }
+ if (n != 0)
+ fputc ('\n', file);
+}
+
+static void
+evax_bfd_print_etir_stc_ir (FILE *file, const unsigned char *buf, int is_ps)
+{
+ fprintf (file, _(" linkage index: %u, replacement insn: 0x%08x\n"),
+ (unsigned)bfd_getl32 (buf),
+ (unsigned)bfd_getl32 (buf + 16));
+ fprintf (file, _(" psect idx 1: %u, offset 1: 0x%08x %08x\n"),
+ (unsigned)bfd_getl32 (buf + 4),
+ (unsigned)bfd_getl32 (buf + 12),
+ (unsigned)bfd_getl32 (buf + 8));
+ fprintf (file, _(" psect idx 2: %u, offset 2: 0x%08x %08x\n"),
+ (unsigned)bfd_getl32 (buf + 20),
+ (unsigned)bfd_getl32 (buf + 28),
+ (unsigned)bfd_getl32 (buf + 24));
+ if (is_ps)
+ fprintf (file, _(" psect idx 3: %u, offset 3: 0x%08x %08x\n"),
+ (unsigned)bfd_getl32 (buf + 32),
+ (unsigned)bfd_getl32 (buf + 40),
+ (unsigned)bfd_getl32 (buf + 36));
+ else
+ fprintf (file, _(" global name: %.*s\n"), buf[32], buf + 33);
+}
+
+static void
+evax_bfd_print_etir (FILE *file, const char *name,
+ unsigned char *rec, unsigned int rec_len)
+{
+ unsigned int off = sizeof (struct vms_egsd);
+ unsigned int sec_len = 0;
+
+ fprintf (file, _(" %s (len=%u+%u):\n"), name,
+ (unsigned)(rec_len - sizeof (struct vms_eobjrec)),
+ (unsigned)sizeof (struct vms_eobjrec));
+
+ for (off = sizeof (struct vms_eobjrec); off < rec_len; )
+ {
+ struct vms_etir *etir = (struct vms_etir *)(rec + off);
+ unsigned char *buf;
+ unsigned int type;
+ unsigned int size;
+
+ type = bfd_getl16 (etir->rectyp);
+ size = bfd_getl16 (etir->size);
+ buf = rec + off + sizeof (struct vms_etir);
+
+ fprintf (file, _(" (type: %3u, size: 4+%3u): "), type, size - 4);
+ switch (type)
+ {
+ case ETIR__C_STA_GBL:
+ fprintf (file, _("STA_GBL (stack global) %.*s\n"),
+ buf[0], buf + 1);
+ break;
+ case ETIR__C_STA_LW:
+ fprintf (file, _("STA_LW (stack longword) 0x%08x\n"),
+ (unsigned)bfd_getl32 (buf));
+ break;
+ case ETIR__C_STA_QW:
+ fprintf (file, _("STA_QW (stack quadword) 0x%08x %08x\n"),
+ (unsigned)bfd_getl32 (buf + 4),
+ (unsigned)bfd_getl32 (buf + 0));
+ break;
+ case ETIR__C_STA_PQ:
+ fprintf (file, _("STA_PQ (stack psect base + offset)\n"));
+ fprintf (file, _(" psect: %u, offset: 0x%08x %08x\n"),
+ (unsigned)bfd_getl32 (buf + 0),
+ (unsigned)bfd_getl32 (buf + 8),
+ (unsigned)bfd_getl32 (buf + 4));
+ break;
+ case ETIR__C_STA_LI:
+ fprintf (file, _("STA_LI (stack literal)\n"));
+ break;
+ case ETIR__C_STA_MOD:
+ fprintf (file, _("STA_MOD (stack module)\n"));
+ break;
+ case ETIR__C_STA_CKARG:
+ fprintf (file, _("STA_CKARG (compare procedure argument)\n"));
+ break;
+
+ case ETIR__C_STO_B:
+ fprintf (file, _("STO_B (store byte)\n"));
+ break;
+ case ETIR__C_STO_W:
+ fprintf (file, _("STO_W (store word)\n"));
+ break;
+ case ETIR__C_STO_LW:
+ fprintf (file, _("STO_LW (store longword)\n"));
+ break;
+ case ETIR__C_STO_QW:
+ fprintf (file, _("STO_QW (store quadword)\n"));
+ break;
+ case ETIR__C_STO_IMMR:
+ {
+ unsigned int len = bfd_getl32 (buf);
+ fprintf (file,
+ _("STO_IMMR (store immediate repeat) %u bytes\n"),
+ len);
+ evax_bfd_print_hex (file, " ", buf + 4, len);
+ sec_len += len;
+ }
+ break;
+ case ETIR__C_STO_GBL:
+ fprintf (file, _("STO_GBL (store global) %.*s\n"),
+ buf[0], buf + 1);
+ break;
+ case ETIR__C_STO_CA:
+ fprintf (file, _("STO_CA (store code address) %.*s\n"),
+ buf[0], buf + 1);
+ break;
+ case ETIR__C_STO_RB:
+ fprintf (file, _("STO_RB (store relative branch)\n"));
+ break;
+ case ETIR__C_STO_AB:
+ fprintf (file, _("STO_AB (store absolute branch)\n"));
+ break;
+ case ETIR__C_STO_OFF:
+ fprintf (file, _("STO_OFF (store offset to psect)\n"));
+ break;
+ case ETIR__C_STO_IMM:
+ {
+ unsigned int len = bfd_getl32 (buf);
+ fprintf (file,
+ _("STO_IMM (store immediate) %u bytes\n"),
+ len);
+ evax_bfd_print_hex (file, " ", buf + 4, len);
+ sec_len += len;
+ }
+ break;
+ case ETIR__C_STO_GBL_LW:
+ fprintf (file, _("STO_GBL_LW (store global longword) %.*s\n"),
+ buf[0], buf + 1);
+ break;
+ case ETIR__C_STO_LP_PSB:
+ fprintf (file, _("STO_OFF (store LP with procedure signature)\n"));
+ break;
+ case ETIR__C_STO_HINT_GBL:
+ fprintf (file, _("STO_BR_GBL (store branch global) *todo*\n"));
+ break;
+ case ETIR__C_STO_HINT_PS:
+ fprintf (file, _("STO_BR_PS (store branch psect + offset) *todo*\n"));
+ break;
+
+ case ETIR__C_OPR_NOP:
+ fprintf (file, _("OPR_NOP (no-operation)\n"));
+ break;
+ case ETIR__C_OPR_ADD:
+ fprintf (file, _("OPR_ADD (add)\n"));
+ break;
+ case ETIR__C_OPR_SUB:
+ fprintf (file, _("OPR_SUB (substract)\n"));
+ break;
+ case ETIR__C_OPR_MUL:
+ fprintf (file, _("OPR_MUL (multiply)\n"));
+ break;
+ case ETIR__C_OPR_DIV:
+ fprintf (file, _("OPR_DIV (divide)\n"));
+ break;
+ case ETIR__C_OPR_AND:
+ fprintf (file, _("OPR_AND (logical and)\n"));
+ break;
+ case ETIR__C_OPR_IOR:
+ fprintf (file, _("OPR_IOR (logical inclusive or)\n"));
+ break;
+ case ETIR__C_OPR_EOR:
+ fprintf (file, _("OPR_EOR (logical exclusive or)\n"));
+ break;
+ case ETIR__C_OPR_NEG:
+ fprintf (file, _("OPR_NEG (negate)\n"));
+ break;
+ case ETIR__C_OPR_COM:
+ fprintf (file, _("OPR_COM (complement)\n"));
+ break;
+ case ETIR__C_OPR_INSV:
+ fprintf (file, _("OPR_INSV (insert field)\n"));
+ break;
+ case ETIR__C_OPR_ASH:
+ fprintf (file, _("OPR_ASH (arithmetic shift)\n"));
+ break;
+ case ETIR__C_OPR_USH:
+ fprintf (file, _("OPR_USH (unsigned shift)\n"));
+ break;
+ case ETIR__C_OPR_ROT:
+ fprintf (file, _("OPR_ROT (rotate)\n"));
+ break;
+ case ETIR__C_OPR_SEL:
+ fprintf (file, _("OPR_SEL (select)\n"));
+ break;
+ case ETIR__C_OPR_REDEF:
+ fprintf (file, _("OPR_REDEF (redefine symbol to curr location)\n"));
+ break;
+ case ETIR__C_OPR_DFLIT:
+ fprintf (file, _("OPR_REDEF (define a literal)\n"));
+ break;
+
+ case ETIR__C_STC_LP:
+ fprintf (file, _("STC_LP (store cond linkage pair)\n"));
+ break;
+ case ETIR__C_STC_LP_PSB:
+ fprintf (file,
+ _("STC_LP_PSB (store cond linkage pair + signature)\n"));
+ fprintf (file, _(" linkage index: %u, procedure: %.*s\n"),
+ (unsigned)bfd_getl32 (buf), buf[4], buf + 5);
+ buf += 4 + 1 + buf[4];
+ fprintf (file, _(" signature: %.*s\n"), buf[0], buf + 1);
+ break;
+ case ETIR__C_STC_GBL:
+ fprintf (file, _("STC_GBL (store cond global)\n"));
+ fprintf (file, _(" linkage index: %u, global: %.*s\n"),
+ (unsigned)bfd_getl32 (buf), buf[4], buf + 5);
+ break;
+ case ETIR__C_STC_GCA:
+ fprintf (file, _("STC_GCA (store cond code address)\n"));
+ fprintf (file, _(" linkage index: %u, procedure name: %.*s\n"),
+ (unsigned)bfd_getl32 (buf), buf[4], buf + 5);
+ break;
+ case ETIR__C_STC_PS:
+ fprintf (file, _("STC_PS (store cond psect + offset)\n"));
+ fprintf (file,
+ _(" linkage index: %u, psect: %u, offset: 0x%08x %08x\n"),
+ (unsigned)bfd_getl32 (buf),
+ (unsigned)bfd_getl32 (buf + 4),
+ (unsigned)bfd_getl32 (buf + 12),
+ (unsigned)bfd_getl32 (buf + 8));
+ break;
+ case ETIR__C_STC_NOP_GBL:
+ fprintf (file, _("STC_NOP_GBL (store cond NOP at global addr)\n"));
+ evax_bfd_print_etir_stc_ir (file, buf, 0);
+ break;
+ case ETIR__C_STC_NOP_PS:
+ fprintf (file, _("STC_NOP_PS (store cond NOP at psect + offset)\n"));
+ evax_bfd_print_etir_stc_ir (file, buf, 1);
+ break;
+ case ETIR__C_STC_BSR_GBL:
+ fprintf (file, _("STC_BSR_GBL (store cond BSR at global addr)\n"));
+ evax_bfd_print_etir_stc_ir (file, buf, 0);
+ break;
+ case ETIR__C_STC_BSR_PS:
+ fprintf (file, _("STC_BSR_PS (store cond BSR at psect + offset)\n"));
+ evax_bfd_print_etir_stc_ir (file, buf, 1);
+ break;
+ case ETIR__C_STC_LDA_GBL:
+ fprintf (file, _("STC_LDA_GBL (store cond LDA at global addr)\n"));
+ evax_bfd_print_etir_stc_ir (file, buf, 0);
+ break;
+ case ETIR__C_STC_LDA_PS:
+ fprintf (file, _("STC_LDA_PS (store cond LDA at psect + offset)\n"));
+ evax_bfd_print_etir_stc_ir (file, buf, 1);
+ break;
+ case ETIR__C_STC_BOH_GBL:
+ fprintf (file, _("STC_BOH_GBL (store cond BOH at global addr)\n"));
+ evax_bfd_print_etir_stc_ir (file, buf, 0);
+ break;
+ case ETIR__C_STC_BOH_PS:
+ fprintf (file, _("STC_BOH_PS (store cond BOH at psect + offset)\n"));
+ evax_bfd_print_etir_stc_ir (file, buf, 1);
+ break;
+ case ETIR__C_STC_NBH_GBL:
+ fprintf (file,
+ _("STC_NBH_GBL (store cond or hint at global addr)\n"));
+ break;
+ case ETIR__C_STC_NBH_PS:
+ fprintf (file,
+ _("STC_NBH_PS (store cond or hint at psect + offset)\n"));
+ break;
+
+ case ETIR__C_CTL_SETRB:
+ fprintf (file, _("CTL_SETRB (set relocation base)\n"));
+ sec_len += 4;
+ break;
+ case ETIR__C_CTL_AUGRB:
+ {
+ unsigned int val = bfd_getl32 (buf);
+ fprintf (file, _("CTL_AUGRB (augment relocation base) %u\n"), val);
+ }
+ break;
+ case ETIR__C_CTL_DFLOC:
+ fprintf (file, _("CTL_DFLOC (define location)\n"));
+ break;
+ case ETIR__C_CTL_STLOC:
+ fprintf (file, _("CTL_STLOC (set location)\n"));
+ break;
+ case ETIR__C_CTL_STKDL:
+ fprintf (file, _("CTL_STKDL (stack defined location)\n"));
+ break;
+ default:
+ fprintf (file, _("*unhandled*\n"));
+ break;
+ }
+ off += size;
+ }
+}
+
+static void
+evax_bfd_print_eobj (struct bfd *abfd, FILE *file)
+{
+ bfd_boolean is_first = TRUE;
+ bfd_boolean has_records = FALSE;
+
+ while (1)
+ {
+ unsigned int rec_len;
+ unsigned int pad_len;
+ unsigned char *rec;
+ unsigned int hdr_size;
+ unsigned int type;
+
+ if (is_first)
+ {
+ unsigned char buf[6];
+
+ is_first = FALSE;
+
+ /* Read 6 bytes. */
+ if (bfd_bread (buf, sizeof (buf), abfd) != sizeof (buf))
+ {
+ fprintf (file, _("cannot read GST record length\n"));
+ return;
+ }
+ rec_len = bfd_getl16 (buf + 0);
+ if (rec_len == bfd_getl16 (buf + 4)
+ && bfd_getl16 (buf + 2) == EOBJ__C_EMH)
+ {
+ /* The format is raw: record-size, type, record-size. */
+ has_records = TRUE;
+ pad_len = (rec_len + 1) & ~1U;
+ hdr_size = 4;
+ }
+ else if (rec_len == EOBJ__C_EMH)
+ {
+ has_records = FALSE;
+ pad_len = bfd_getl16 (buf + 2);
+ hdr_size = 6;
+ }
+ else
+ {
+ /* Ill-formed. */
+ fprintf (file, _("cannot find EMH in first GST record\n"));
+ return;
+ }
+ rec = bfd_malloc (pad_len);
+ memcpy (rec, buf + sizeof (buf) - hdr_size, hdr_size);
+ }
+ else
+ {
+ unsigned int rec_len2 = 0;
+ unsigned char hdr[4];
+
+ if (has_records)
+ {
+ unsigned char buf_len[2];
+
+ if (bfd_bread (buf_len, sizeof (buf_len), abfd)
+ != sizeof (buf_len))
+ {
+ fprintf (file, _("cannot read GST record length\n"));
+ return;
+ }
+ rec_len2 = (unsigned)bfd_getl16 (buf_len);
+ }
+
+ if (bfd_bread (hdr, sizeof (hdr), abfd) != sizeof (hdr))
+ {
+ fprintf (file, _("cannot read GST record header\n"));
+ return;
+ }
+ rec_len = (unsigned)bfd_getl16 (hdr + 2);
+ if (has_records)
+ pad_len = (rec_len + 1) & ~1U;
+ else
+ pad_len = rec_len;
+ rec = bfd_malloc (pad_len);
+ memcpy (rec, hdr, sizeof (hdr));
+ hdr_size = sizeof (hdr);
+ if (has_records && rec_len2 != rec_len)
+ {
+ fprintf (file, _(" corrupted GST\n"));
+ break;
+ }
+ }
+
+ if (bfd_bread (rec + hdr_size, pad_len - hdr_size, abfd)
+ != pad_len - hdr_size)
+ {
+ fprintf (file, _("cannot read GST record\n"));
+ return;
+ }
+
+ type = (unsigned)bfd_getl16 (rec);
+
+ switch (type)
+ {
+ case EOBJ__C_EMH:
+ evax_bfd_print_emh (file, rec, rec_len);
+ break;
+ case EOBJ__C_EGSD:
+ evax_bfd_print_egsd (file, rec, rec_len);
+ break;
+ case EOBJ__C_EEOM:
+ evax_bfd_print_eeom (file, rec, rec_len);
+ free (rec);
+ return;
+ break;
+ case EOBJ__C_ETIR:
+ evax_bfd_print_etir (file, "ETIR", rec, rec_len);
+ break;
+ case EOBJ__C_EDBG:
+ evax_bfd_print_etir (file, "EDBG", rec, rec_len);
+ break;
+ case EOBJ__C_ETBT:
+ evax_bfd_print_etir (file, "ETBT", rec, rec_len);
+ break;
+ default:
+ fprintf (file, _(" unhandled EOBJ record type %u\n"), type);
+ break;
+ }
+ free (rec);
+ }
+}
+
+static void
+evax_bfd_print_relocation_records (FILE *file, const unsigned char *rel,
+ unsigned int stride)
+{
+ while (1)
+ {
+ unsigned int base;
+ unsigned int count;
+ unsigned int j;
+
+ count = bfd_getl32 (rel + 0);
+
+ if (count == 0)
+ break;
+ base = bfd_getl32 (rel + 4);
+
+ fprintf (file, _(" bitcount: %u, base addr: 0x%08x\n"),
+ count, base);
+
+ rel += 8;
+ for (j = 0; count > 0; j += 4, count -= 32)
+ {
+ unsigned int k;
+ unsigned int n = 0;
+ unsigned int val;
+
+ val = bfd_getl32 (rel);
+ rel += 4;
+
+ fprintf (file, _(" bitmap: 0x%08x (count: %u):\n"), val, count);
+
+ for (k = 0; k < 32; k++)
+ if (val & (1 << k))
+ {
+ if (n == 0)
+ fputs (" ", file);
+ fprintf (file, _(" %08x"), base + (j * 8 + k) * stride);
+ n++;
+ if (n == 8)
+ {
+ fputs ("\n", file);
+ n = 0;
+ }
+ }
+ if (n)
+ fputs ("\n", file);
+ }
+ }
+}
+
+static void
+evax_bfd_print_address_fixups (FILE *file, const unsigned char *rel)
+{
+ while (1)
+ {
+ unsigned int j;
+ unsigned int count;
+
+ count = bfd_getl32 (rel + 0);
+ if (count == 0)
+ return;
+ fprintf (file, _(" image %u (%u entries)\n"),
+ (unsigned)bfd_getl32 (rel + 4), count);
+ rel += 8;
+ for (j = 0; j < count; j++)
+ {
+ fprintf (file, _(" offset: 0x%08x, val: 0x%08x\n"),
+ (unsigned)bfd_getl32 (rel + 0),
+ (unsigned)bfd_getl32 (rel + 4));
+ rel += 8;
+ }
+ }
+}
+
+static void
+evax_bfd_print_reference_fixups (FILE *file, const unsigned char *rel)
+{
+ unsigned int count;
+
+ while (1)
+ {
+ unsigned int j;
+ unsigned int n = 0;
+
+ count = bfd_getl32 (rel + 0);
+ if (count == 0)
+ break;
+ fprintf (file, _(" image %u (%u entries), offsets:\n"),
+ (unsigned)bfd_getl32 (rel + 4), count);
+ rel += 8;
+ for (j = 0; j < count; j++)
+ {
+ if (n == 0)
+ fputs (" ", file);
+ fprintf (file, _(" 0x%08x"), (unsigned)bfd_getl32 (rel));
+ n++;
+ if (n == 7)
+ {
+ fputs ("\n", file);
+ n = 0;
+ }
+ rel += 4;
+ }
+ if (n)
+ fputs ("\n", file);
+ }
+}
+
+static void
+evax_bfd_print_indent (int indent, FILE *file)
+{
+ for (; indent; indent--)
+ fputc (' ', file);
+}
+
+static const char *
+evax_bfd_get_dsc_name (unsigned int v)
+{
+ switch (v)
+ {
+ case DSC__K_DTYPE_Z:
+ return "Z (Unspecified)";
+ case DSC__K_DTYPE_V:
+ return "V (Bit)";
+ case DSC__K_DTYPE_BU:
+ return "BU (Byte logical)";
+ case DSC__K_DTYPE_WU:
+ return "WU (Word logical)";
+ case DSC__K_DTYPE_LU:
+ return "LU (Longword logical)";
+ case DSC__K_DTYPE_QU:
+ return "QU (Quadword logical)";
+ case DSC__K_DTYPE_B:
+ return "B (Byte integer)";
+ case DSC__K_DTYPE_W:
+ return "W (Word integer)";
+ case DSC__K_DTYPE_L:
+ return "L (Longword integer)";
+ case DSC__K_DTYPE_Q:
+ return "Q (Quadword integer)";
+ case DSC__K_DTYPE_F:
+ return "F (Single-precision floating)";
+ case DSC__K_DTYPE_D:
+ return "D (Double-precision floating)";
+ case DSC__K_DTYPE_FC:
+ return "FC (Complex)";
+ case DSC__K_DTYPE_DC:
+ return "DC (Double-precision Complex)";
+ case DSC__K_DTYPE_T:
+ return "T (ASCII text string)";
+ case DSC__K_DTYPE_NU:
+ return "NU (Numeric string, unsigned)";
+ case DSC__K_DTYPE_NL:
+ return "NL (Numeric string, left separate sign)";
+ case DSC__K_DTYPE_NLO:
+ return "NLO (Numeric string, left overpunched sign)";
+ case DSC__K_DTYPE_NR:
+ return "NR (Numeric string, right separate sign)";
+ case DSC__K_DTYPE_NRO:
+ return "NRO (Numeric string, right overpunched sig)";
+ case DSC__K_DTYPE_NZ:
+ return "NZ (Numeric string, zoned sign)";
+ case DSC__K_DTYPE_P:
+ return "P (Packed decimal string)";
+ case DSC__K_DTYPE_ZI:
+ return "ZI (Sequence of instructions)";
+ case DSC__K_DTYPE_ZEM:
+ return "ZEM (Procedure entry mask)";
+ case DSC__K_DTYPE_DSC:
+ return "DSC (Descriptor, used for arrays of dyn strings)";
+ case DSC__K_DTYPE_OU:
+ return "OU (Octaword logical)";
+ case DSC__K_DTYPE_O:
+ return "O (Octaword integer)";
+ case DSC__K_DTYPE_G:
+ return "G (Double precision G floating, 64 bit)";
+ case DSC__K_DTYPE_H:
+ return "H (Quadruple precision floating, 128 bit)";
+ case DSC__K_DTYPE_GC:
+ return "GC (Double precision complex, G floating)";
+ case DSC__K_DTYPE_HC:
+ return "HC (Quadruple precision complex, H floating)";
+ case DSC__K_DTYPE_CIT:
+ return "CIT (COBOL intermediate temporary)";
+ case DSC__K_DTYPE_BPV:
+ return "BPV (Bound Procedure Value)";
+ case DSC__K_DTYPE_BLV:
+ return "BLV (Bound Label Value)";
+ case DSC__K_DTYPE_VU:
+ return "VU (Bit Unaligned)";
+ case DSC__K_DTYPE_ADT:
+ return "ADT (Absolute Date-Time)";
+ case DSC__K_DTYPE_VT:
+ return "VT (Varying Text)";
+ case DSC__K_DTYPE_T2:
+ return "T2 (16-bit char)";
+ case DSC__K_DTYPE_VT2:
+ return "VT2 (16-bit varying char)";
+ default:
+ return "?? (unknown)";
+ }
+}
+
+static void
+evax_bfd_print_desc (const unsigned char *buf, int indent, FILE *file)
+{
+ unsigned char bclass = buf[3];
+ unsigned char dtype = buf[2];
+ unsigned int len = (unsigned)bfd_getl16 (buf);
+ unsigned int pointer = (unsigned)bfd_getl32 (buf + 4);
+
+ evax_bfd_print_indent (indent, file);
+
+ if (len == 1 && pointer == 0xffffffffUL)
+ {
+ /* 64 bits. */
+ fprintf (file, _("64 bits *unhandled*\n"));
+ }
+ else
+ {
+ fprintf (file, _("class: %u, dtype: %u, length: %u, pointer: 0x%08x\n"),
+ bclass, dtype, len, pointer);
+ switch (bclass)
+ {
+ case DSC__K_CLASS_NCA:
+ {
+ const struct vms_dsc_nca *dsc = (const void *)buf;
+ unsigned int i;
+ const unsigned char *b;
+
+ evax_bfd_print_indent (indent, file);
+ fprintf (file, _("non-contiguous array of %s\n"),
+ evax_bfd_get_dsc_name (dsc->dtype));
+ evax_bfd_print_indent (indent + 1, file);
+ fprintf (file,
+ _("dimct: %u, aflags: 0x%02x, digits: %u, scale: %u\n"),
+ dsc->dimct, dsc->aflags, dsc->digits, dsc->scale);
+ evax_bfd_print_indent (indent + 1, file);
+ fprintf (file,
+ _("arsize: %u, a0: 0x%08x\n"),
+ (unsigned)bfd_getl32 (dsc->arsize),
+ (unsigned)bfd_getl32 (dsc->a0));
+ evax_bfd_print_indent (indent + 1, file);
+ fprintf (file, _("Strides:\n"));
+ b = buf + sizeof (*dsc);
+ for (i = 0; i < dsc->dimct; i++)
+ {
+ evax_bfd_print_indent (indent + 2, file);
+ fprintf (file, _("[%u]: %u\n"), i + 1,
+ (unsigned)bfd_getl32 (b));
+ b += 4;
+ }
+ evax_bfd_print_indent (indent + 1, file);
+ fprintf (file, _("Bounds:\n"));
+ b = buf + sizeof (*dsc);
+ for (i = 0; i < dsc->dimct; i++)
+ {
+ evax_bfd_print_indent (indent + 2, file);
+ fprintf (file, _("[%u]: Lower: %u, upper: %u\n"), i + 1,
+ (unsigned)bfd_getl32 (b + 0),
+ (unsigned)bfd_getl32 (b + 4));
+ b += 8;
+ }
+ }
+ break;
+ case DSC__K_CLASS_UBS:
+ {
+ const struct vms_dsc_ubs *ubs = (const void *)buf;
+
+ evax_bfd_print_indent (indent, file);
+ fprintf (file, _("unaligned bit-string of %s\n"),
+ evax_bfd_get_dsc_name (ubs->dtype));
+ evax_bfd_print_indent (indent + 1, file);
+ fprintf (file,
+ _("base: %u, pos: %u\n"),
+ (unsigned)bfd_getl32 (ubs->base),
+ (unsigned)bfd_getl32 (ubs->pos));
+ }
+ break;
+ default:
+ fprintf (file, _("*unhandled*\n"));
+ break;
+ }
+ }
+}
+
+static unsigned int
+evax_bfd_print_valspec (const unsigned char *buf, int indent, FILE *file)
+{
+ unsigned int vflags = buf[0];
+ unsigned int value = (unsigned)bfd_getl32 (buf + 1);
+ unsigned int len = 5;
+
+ evax_bfd_print_indent (indent, file);
+ fprintf (file, _("vflags: 0x%02x, value: 0x%08x "), vflags, value);
+ buf += 5;
+
+ switch (vflags)
+ {
+ case DST__K_VFLAGS_NOVAL:
+ fprintf (file, _("(no value)\n"));
+ break;
+ case DST__K_VFLAGS_NOTACTIVE:
+ fprintf (file, _("(not active)\n"));
+ break;
+ case DST__K_VFLAGS_UNALLOC:
+ fprintf (file, _("(not allocated)\n"));
+ break;
+ case DST__K_VFLAGS_DSC:
+ fprintf (file, _("(descriptor)\n"));
+ evax_bfd_print_desc (buf + value, indent + 1, file);
+ break;
+ case DST__K_VFLAGS_TVS:
+ fprintf (file, _("(trailing value)\n"));
+ break;
+ case DST__K_VS_FOLLOWS:
+ fprintf (file, _("(value spec follows)\n"));
+ break;
+ case DST__K_VFLAGS_BITOFFS:
+ fprintf (file, _("(at bit offset %u)\n"), value);
+ break;
+ default:
+ fprintf (file, _("(reg: %u, disp: %u, indir: %u, kind: "),
+ (vflags & DST__K_REGNUM_MASK) >> DST__K_REGNUM_SHIFT,
+ vflags & DST__K_DISP ? 1 : 0,
+ vflags & DST__K_INDIR ? 1 : 0);
+ switch (vflags & DST__K_VALKIND_MASK)
+ {
+ case DST__K_VALKIND_LITERAL:
+ fputs (_("literal"), file);
+ break;
+ case DST__K_VALKIND_ADDR:
+ fputs (_("address"), file);
+ break;
+ case DST__K_VALKIND_DESC:
+ fputs (_("desc"), file);
+ break;
+ case DST__K_VALKIND_REG:
+ fputs (_("reg"), file);
+ break;
+ }
+ fputs (")\n", file);
+ break;
+ }
+ return len;
+}
+
+static void
+evax_bfd_print_typspec (const unsigned char *buf, int indent, FILE *file)
+{
+ unsigned char kind = buf[2];
+ unsigned int len = (unsigned)bfd_getl16 (buf);
+
+ evax_bfd_print_indent (indent, file);
+ fprintf (file, ("len: %2u, kind: %2u "), len, kind);
+ buf += 3;
+ switch (kind)
+ {
+ case DST__K_TS_ATOM:
+ fprintf (file, ("atomic, type=0x%02x %s\n"),
+ buf[0], evax_bfd_get_dsc_name (buf[0]));
+ break;
+ case DST__K_TS_IND:
+ fprintf (file, ("indirect, defined at 0x%08x\n"),
+ (unsigned)bfd_getl32 (buf));
+ break;
+ case DST__K_TS_TPTR:
+ fprintf (file, ("typed pointer\n"));
+ evax_bfd_print_typspec (buf, indent + 1, file);
+ break;
+ case DST__K_TS_PTR:
+ fprintf (file, ("pointer\n"));
+ break;
+ case DST__K_TS_ARRAY:
+ {
+ const unsigned char *vs;
+ unsigned int vec_len;
+ unsigned int i;
+
+ fprintf (file, ("array, dim: %u, bitmap: "), buf[0]);
+ vec_len = (buf[0] + 1 + 7) / 8;
+ for (i = 0; i < vec_len; i++)
+ fprintf (file, " %02x", buf[i + 1]);
+ fputc ('\n', file);
+ vs = buf + 1 + vec_len;
+ evax_bfd_print_indent (indent, file);
+ fprintf (file, ("array descriptor:\n"));
+ vs += evax_bfd_print_valspec (vs, indent + 1, file);
+ for (i = 0; i < buf[0] + 1U; i++)
+ if (buf[1 + i / 8] & (1 << (i % 8)))
+ {
+ evax_bfd_print_indent (indent, file);
+ if (i == 0)
+ fprintf (file, ("type spec for element:\n"));
+ else
+ fprintf (file, ("type spec for subscript %u:\n"), i);
+ evax_bfd_print_typspec (vs, indent + 1, file);
+ vs += bfd_getl16 (vs);
+ }
+ }
+ break;
+ default:
+ fprintf (file, ("*unhandled*\n"));
+ }
+}
+
+static void
+evax_bfd_print_dst (struct bfd *abfd, unsigned int dst_size, FILE *file)
+{
+ unsigned int off = 0;
+ unsigned int pc = 0;
+ unsigned int line = 0;
+
+ fprintf (file, _("Debug symbol table:\n"));
+
+ while (dst_size > 0)
+ {
+ struct vms_dst_header dsth;
+ unsigned int len;
+ unsigned int type;
+ unsigned char *buf;
+
+ if (bfd_bread (&dsth, sizeof (dsth), abfd) != sizeof (dsth))
+ {
+ fprintf (file, _("cannot read DST header\n"));
+ return;
+ }
+ len = bfd_getl16 (dsth.length);
+ type = bfd_getl16 (dsth.type);
+ fprintf (file, _(" type: %3u, len: %3u (at 0x%08x): "),
+ type, len, off);
+ if (len == 0)
+ {
+ fputc ('\n', file);
+ break;
+ }
+ len++;
+ dst_size -= len;
+ off += len;
+ len -= sizeof (dsth);
+ buf = bfd_malloc (len);
+ if (bfd_bread (buf, len, abfd) != len)
+ {
+ fprintf (file, _("cannot read DST symbol\n"));
+ return;
+ }
+ switch (type)
+ {
+ case DSC__K_DTYPE_V:
+ case DSC__K_DTYPE_BU:
+ case DSC__K_DTYPE_WU:
+ case DSC__K_DTYPE_LU:
+ case DSC__K_DTYPE_QU:
+ case DSC__K_DTYPE_B:
+ case DSC__K_DTYPE_W:
+ case DSC__K_DTYPE_L:
+ case DSC__K_DTYPE_Q:
+ case DSC__K_DTYPE_F:
+ case DSC__K_DTYPE_D:
+ case DSC__K_DTYPE_FC:
+ case DSC__K_DTYPE_DC:
+ case DSC__K_DTYPE_T:
+ case DSC__K_DTYPE_NU:
+ case DSC__K_DTYPE_NL:
+ case DSC__K_DTYPE_NLO:
+ case DSC__K_DTYPE_NR:
+ case DSC__K_DTYPE_NRO:
+ case DSC__K_DTYPE_NZ:
+ case DSC__K_DTYPE_P:
+ case DSC__K_DTYPE_ZI:
+ case DSC__K_DTYPE_ZEM:
+ case DSC__K_DTYPE_DSC:
+ case DSC__K_DTYPE_OU:
+ case DSC__K_DTYPE_O:
+ case DSC__K_DTYPE_G:
+ case DSC__K_DTYPE_H:
+ case DSC__K_DTYPE_GC:
+ case DSC__K_DTYPE_HC:
+ case DSC__K_DTYPE_CIT:
+ case DSC__K_DTYPE_BPV:
+ case DSC__K_DTYPE_BLV:
+ case DSC__K_DTYPE_VU:
+ case DSC__K_DTYPE_ADT:
+ case DSC__K_DTYPE_VT:
+ case DSC__K_DTYPE_T2:
+ case DSC__K_DTYPE_VT2:
+ fprintf (file, _("standard data: %s\n"),
+ evax_bfd_get_dsc_name (type));
+ evax_bfd_print_valspec (buf, 4, file);
+ fprintf (file, _(" name: %.*s\n"), buf[5], buf + 6);
+ break;
+ case DST__K_MODBEG:
+ {
+ struct vms_dst_modbeg *dst = (void *)buf;
+ const char *name = (const char *)buf + sizeof (*dst);
+
+ fprintf (file, _("modbeg\n"));
+ fprintf (file, _(" flags: %d, language: %u, "
+ "major: %u, minor: %u\n"),
+ dst->flags,
+ (unsigned)bfd_getl32 (dst->language),
+ (unsigned)bfd_getl16 (dst->major),
+ (unsigned)bfd_getl16 (dst->minor));
+ fprintf (file, _(" module name: %.*s\n"),
+ name[0], name + 1);
+ name += name[0] + 1;
+ fprintf (file, _(" compiler : %.*s\n"),
+ name[0], name + 1);
+ }
+ break;
+ case DST__K_MODEND:
+ fprintf (file, _("modend\n"));
+ break;
+ case DST__K_RTNBEG:
+ {
+ struct vms_dst_rtnbeg *dst = (void *)buf;
+ const char *name = (const char *)buf + sizeof (*dst);
+
+ fputs (_("rtnbeg\n"), file);
+ fprintf (file, _(" flags: %u, address: 0x%08x, "
+ "pd-address: 0x%08x\n"),
+ dst->flags,
+ (unsigned)bfd_getl32 (dst->address),
+ (unsigned)bfd_getl32 (dst->pd_address));
+ fprintf (file, _(" routine name: %.*s\n"),
+ name[0], name + 1);
+ }
+ break;
+ case DST__K_RTNEND:
+ {
+ struct vms_dst_rtnend *dst = (void *)buf;
+
+ fprintf (file, _("rtnend: size 0x%08x\n"),
+ (unsigned)bfd_getl32 (dst->size));
+ }
+ break;
+ case DST__K_PROLOG:
+ {
+ struct vms_dst_prolog *dst = (void *)buf;
+
+ fprintf (file, _("prolog: bkpt address 0x%08x\n"),
+ (unsigned)bfd_getl32 (dst->bkpt_addr));
+ }
+ break;
+ case DST__K_EPILOG:
+ {
+ struct vms_dst_epilog *dst = (void *)buf;
+
+ fprintf (file, _("epilog: flags: %u, count: %u\n"),
+ dst->flags, (unsigned)bfd_getl32 (dst->count));
+ }
+ break;
+ case DST__K_BLKBEG:
+ {
+ struct vms_dst_blkbeg *dst = (void *)buf;
+ const char *name = (const char *)buf + sizeof (*dst);
+
+ fprintf (file, _("blkbeg: address: 0x%08x, name: %.*s\n"),
+ (unsigned)bfd_getl32 (dst->address),
+ name[0], name + 1);
+ }
+ break;
+ case DST__K_BLKEND:
+ {
+ struct vms_dst_blkend *dst = (void *)buf;
+
+ fprintf (file, _("blkend: size: 0x%08x\n"),
+ (unsigned)bfd_getl32 (dst->size));
+ }
+ break;
+ case DST__K_TYPSPEC:
+ {
+ fprintf (file, _("typspec (len: %u)\n"), len);
+ fprintf (file, _(" name: %.*s\n"), buf[0], buf + 1);
+ evax_bfd_print_typspec (buf + 1 + buf[0], 5, file);
+ }
+ break;
+ case DST__K_SEPTYP:
+ {
+ fprintf (file, _("septyp, name: %.*s\n"), buf[5], buf + 6);
+ evax_bfd_print_valspec (buf, 4, file);
+ }
+ break;
+ case DST__K_RECBEG:
+ {
+ struct vms_dst_recbeg *recbeg = (void *)buf;
+ const char *name = (const char *)buf + sizeof (*recbeg);
+
+ fprintf (file, _("recbeg: name: %.*s\n"), name[0], name + 1);
+ evax_bfd_print_valspec (buf, 4, file);
+ fprintf (file, (" len: %u bits\n"),
+ (unsigned)bfd_getl32 (name + 1 + name[0]));
+ }
+ break;
+ case DST__K_RECEND:
+ fprintf (file, _("recend\n"));
+ break;
+ case DST__K_ENUMBEG:
+ fprintf (file, _("enumbeg, len: %u, name: %.*s\n"),
+ buf[0], buf[1], buf + 2);
+ break;
+ case DST__K_ENUMELT:
+ fprintf (file, _("enumelt, name: %.*s\n"), buf[5], buf + 6);
+ evax_bfd_print_valspec (buf, 4, file);
+ break;
+ case DST__K_ENUMEND:
+ fprintf (file, _("enumend\n"));
+ break;
+ case DST__K_LABEL:
+ {
+ struct vms_dst_label *lab = (void *)buf;
+ fprintf (file, ("label, name: %.*s\n"),
+ lab->name[0], lab->name + 1);
+ fprintf (file, (" address: 0x%08x\n"),
+ (unsigned)bfd_getl32 (lab->value));
+ }
+ break;
+ case DST__K_DIS_RANGE:
+ {
+ unsigned int cnt = bfd_getl32 (buf);
+ unsigned char *rng = buf + 4;
+ unsigned int i;
+
+ fprintf (file, _("discontiguous range (nbr: %u)\n"), cnt);
+ for (i = 0; i < cnt; i++, rng += 8)
+ fprintf (file, _(" address: 0x%08x, size: %u\n"),
+ (unsigned)bfd_getl32 (rng),
+ (unsigned)bfd_getl32 (rng + 4));
+
+ }
+ break;
+ case DST__K_LINE_NUM:
+ {
+ unsigned char *buf_orig = buf;
+
+ fprintf (file, _("line num (len: %u)\n"), len);
+
+ while (len > 0)
+ {
+ signed char cmd;
+ unsigned char cmdlen;
+ unsigned int val;
+
+ cmd = buf[0];
+ cmdlen = 0;
+
+ fputs (" ", file);
+
+ switch (cmd)
+ {
+ case DST__K_DELTA_PC_W:
+ val = bfd_getl16 (buf + 1);
+ fprintf (file, _("delta_pc_w %u\n"), val);
+ pc += val;
+ line++;
+ cmdlen = 3;
+ break;
+ case DST__K_INCR_LINUM:
+ val = buf[1];
+ fprintf (file, _("incr_linum(b): +%u\n"), val);
+ line += val;
+ cmdlen = 2;
+ break;
+ case DST__K_INCR_LINUM_W:
+ val = bfd_getl16 (buf + 1);
+ fprintf (file, _("incr_linum_w: +%u\n"), val);
+ line += val;
+ cmdlen = 3;
+ break;
+ case DST__K_INCR_LINUM_L:
+ val = bfd_getl32 (buf + 1);
+ fprintf (file, _("incr_linum_l: +%u\n"), val);
+ line += val;
+ cmdlen = 5;
+ break;
+ case DST__K_SET_LINUM:
+ line = bfd_getl16 (buf + 1);
+ fprintf (file, _("set_line_num(w) %u\n"), line);
+ cmdlen = 3;
+ break;
+ case DST__K_SET_LINUM_B:
+ line = buf[1];
+ fprintf (file, _("set_line_num_b %u\n"), line);
+ cmdlen = 2;
+ break;
+ case DST__K_SET_LINUM_L:
+ line = bfd_getl32 (buf + 1);
+ fprintf (file, _("set_line_num_l %u\n"), line);
+ cmdlen = 5;
+ break;
+ case DST__K_SET_ABS_PC:
+ pc = bfd_getl32 (buf + 1);
+ fprintf (file, _("set_abs_pc: 0x%08x\n"), pc);
+ cmdlen = 5;
+ break;
+ case DST__K_DELTA_PC_L:
+ fprintf (file, _("delta_pc_l: +0x%08x\n"),
+ (unsigned)bfd_getl32 (buf + 1));
+ cmdlen = 5;
+ break;
+ case DST__K_TERM:
+ fprintf (file, _("term(b): 0x%02x"), buf[1]);
+ pc += buf[1];
+ fprintf (file, _(" pc: 0x%08x\n"), pc);
+ cmdlen = 2;
+ break;
+ case DST__K_TERM_W:
+ val = bfd_getl16 (buf + 1);
+ fprintf (file, _("term_w: 0x%04x"), val);
+ pc += val;
+ fprintf (file, _(" pc: 0x%08x\n"), pc);
+ cmdlen = 3;
+ break;
+ default:
+ if (cmd <= 0)
+ {
+ fprintf (file, _("delta pc +%-4d"), -cmd);
+ line++; /* FIXME: curr increment. */
+ pc += -cmd;
+ fprintf (file, _(" pc: 0x%08x line: %5u\n"),
+ pc, line);
+ cmdlen = 1;
+ }
+ else
+ fprintf (file, _(" *unhandled* cmd %u\n"), cmd);
+ break;
+ }
+ if (cmdlen == 0)
+ break;
+ len -= cmdlen;
+ buf += cmdlen;
+ }
+ buf = buf_orig;
+ }
+ break;
+ case DST__K_SOURCE:
+ {
+ unsigned char *buf_orig = buf;
+
+ fprintf (file, _("source (len: %u)\n"), len);
+
+ while (len > 0)
+ {
+ signed char cmd = buf[0];
+ unsigned char cmdlen = 0;
+
+ switch (cmd)
+ {
+ case DST__K_SRC_DECLFILE:
+ {
+ struct vms_dst_src_decl_src *src = (void *)(buf + 1);
+ const char *name;
+
+ fprintf (file, _(" declfile: len: %u, flags: %u, "
+ "fileid: %u\n"),
+ src->length, src->flags,
+ (unsigned)bfd_getl16 (src->fileid));
+ fprintf (file, _(" rms: cdt: 0x%08x %08x, "
+ "ebk: 0x%08x, ffb: 0x%04x, "
+ "rfo: %u\n"),
+ (unsigned)bfd_getl32 (src->rms_cdt + 4),
+ (unsigned)bfd_getl32 (src->rms_cdt + 0),
+ (unsigned)bfd_getl32 (src->rms_ebk),
+ (unsigned)bfd_getl16 (src->rms_ffb),
+ src->rms_rfo);
+ name = (const char *)buf + 1 + sizeof (*src);
+ fprintf (file, _(" filename : %.*s\n"),
+ name[0], name + 1);
+ name += name[0] + 1;
+ fprintf (file, _(" module name: %.*s\n"),
+ name[0], name + 1);
+ cmdlen = 2 + src->length;
+ }
+ break;
+ case DST__K_SRC_SETFILE:
+ fprintf (file, _(" setfile %u\n"),
+ (unsigned)bfd_getl16 (buf + 1));
+ cmdlen = 3;
+ break;
+ case DST__K_SRC_SETREC_W:
+ fprintf (file, _(" setrec %u\n"),
+ (unsigned)bfd_getl16 (buf + 1));
+ cmdlen = 3;
+ break;
+ case DST__K_SRC_SETREC_L:
+ fprintf (file, _(" setrec %u\n"),
+ (unsigned)bfd_getl32 (buf + 1));
+ cmdlen = 5;
+ break;
+ case DST__K_SRC_SETLNUM_W:
+ fprintf (file, _(" setlnum %u\n"),
+ (unsigned)bfd_getl16 (buf + 1));
+ cmdlen = 3;
+ break;
+ case DST__K_SRC_SETLNUM_L:
+ fprintf (file, _(" setlnum %u\n"),
+ (unsigned)bfd_getl32 (buf + 1));
+ cmdlen = 5;
+ break;
+ case DST__K_SRC_DEFLINES_W:
+ fprintf (file, _(" deflines %u\n"),
+ (unsigned)bfd_getl16 (buf + 1));
+ cmdlen = 3;
+ break;
+ case DST__K_SRC_DEFLINES_B:
+ fprintf (file, _(" deflines %u\n"), buf[1]);
+ cmdlen = 2;
+ break;
+ case DST__K_SRC_FORMFEED:
+ fprintf (file, _(" formfeed\n"));
+ cmdlen = 1;
+ break;
+ default:
+ fprintf (file, _(" *unhandled* cmd %u\n"), cmd);
+ break;
+ }
+ if (cmdlen == 0)
+ break;
+ len -= cmdlen;
+ buf += cmdlen;
+ }
+ buf = buf_orig;
+ }
+ break;
+ default:
+ fprintf (file, _("*unhandled* dst type %u\n"), type);
+ break;
+ }
+ free (buf);
+ }
+}
+
+static void
+evax_bfd_print_image (bfd *abfd, FILE *file)
+{
+ struct vms_eihd eihd;
+ const char *name;
+ unsigned int val;
+ unsigned int eiha_off;
+ unsigned int eihi_off;
+ unsigned int eihs_off;
+ unsigned int eisd_off;
+ unsigned int eihef_off = 0;
+ unsigned int eihnp_off = 0;
+ unsigned int dmt_vbn = 0;
+ unsigned int dmt_size = 0;
+ unsigned int dst_vbn = 0;
+ unsigned int dst_size = 0;
+ unsigned int gst_vbn = 0;
+ unsigned int gst_size = 0;
+ unsigned int eiaf_vbn = 0;
+ unsigned int eiaf_size = 0;
+ unsigned int eihvn_off;
+
+ if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET)
+ || bfd_bread (&eihd, sizeof (eihd), abfd) != sizeof (eihd))
+ {
+ fprintf (file, _("cannot read EIHD\n"));
+ return;
+ }
+ fprintf (file, _("EIHD: (size: %u, nbr blocks: %u)\n"),
+ (unsigned)bfd_getl32 (eihd.size),
+ (unsigned)bfd_getl32 (eihd.hdrblkcnt));
+ fprintf (file, _(" majorid: %u, minorid: %u\n"),
+ (unsigned)bfd_getl32 (eihd.majorid),
+ (unsigned)bfd_getl32 (eihd.minorid));
+
+ val = (unsigned)bfd_getl32 (eihd.imgtype);
+ switch (val)
+ {
+ case EIHD__K_EXE:
+ name = _("executable");
+ break;
+ case EIHD__K_LIM:
+ name = _("linkable image");
+ break;
+ default:
+ name = _("unknown");
+ break;
+ }
+ fprintf (file, _(" image type: %u (%s)"), val, name);
+
+ val = (unsigned)bfd_getl32 (eihd.subtype);
+ switch (val)
+ {
+ case EIHD__C_NATIVE:
+ name = _("native");
+ break;
+ case EIHD__C_CLI:
+ name = _("CLI");
+ break;
+ default:
+ name = _("unknown");
+ break;
+ }
+ fprintf (file, _(", subtype: %u (%s)\n"), val, name);
+
+ eisd_off = bfd_getl32 (eihd.isdoff);
+ eiha_off = bfd_getl32 (eihd.activoff);
+ eihi_off = bfd_getl32 (eihd.imgidoff);
+ eihs_off = bfd_getl32 (eihd.symdbgoff);
+ fprintf (file, _(" offsets: isd: %u, activ: %u, symdbg: %u, "
+ "imgid: %u, patch: %u\n"),
+ eisd_off, eiha_off, eihs_off, eihi_off,
+ (unsigned)bfd_getl32 (eihd.patchoff));
+ fprintf (file, _(" fixup info rva: "));
+ bfd_fprintf_vma (abfd, file, bfd_getl64 (eihd.iafva));
+ fprintf (file, _(", symbol vector rva: "));
+ bfd_fprintf_vma (abfd, file, bfd_getl64 (eihd.symvva));
+ eihvn_off = bfd_getl32 (eihd.version_array_off);
+ fprintf (file, _("\n"
+ " version array off: %u\n"),
+ eihvn_off);
+ fprintf (file,
+ _(" img I/O count: %u, nbr channels: %u, req pri: %08x%08x\n"),
+ (unsigned)bfd_getl32 (eihd.imgiocnt),
+ (unsigned)bfd_getl32 (eihd.iochancnt),
+ (unsigned)bfd_getl32 (eihd.privreqs + 4),
+ (unsigned)bfd_getl32 (eihd.privreqs + 0));
+ val = (unsigned)bfd_getl32 (eihd.lnkflags);
+ fprintf (file, _(" linker flags: %08x:"), val);
+ if (val & EIHD__M_LNKDEBUG)
+ fprintf (file, " LNKDEBUG");
+ if (val & EIHD__M_LNKNOTFR)
+ fprintf (file, " LNKNOTFR");
+ if (val & EIHD__M_NOP0BUFS)
+ fprintf (file, " NOP0BUFS");
+ if (val & EIHD__M_PICIMG)
+ fprintf (file, " PICIMG");
+ if (val & EIHD__M_P0IMAGE)
+ fprintf (file, " P0IMAGE");
+ if (val & EIHD__M_DBGDMT)
+ fprintf (file, " DBGDMT");
+ if (val & EIHD__M_INISHR)
+ fprintf (file, " INISHR");
+ if (val & EIHD__M_XLATED)
+ fprintf (file, " XLATED");
+ if (val & EIHD__M_BIND_CODE_SEC)
+ fprintf (file, " BIND_CODE_SEC");
+ if (val & EIHD__M_BIND_DATA_SEC)
+ fprintf (file, " BIND_DATA_SEC");
+ if (val & EIHD__M_MKTHREADS)
+ fprintf (file, " MKTHREADS");
+ if (val & EIHD__M_UPCALLS)
+ fprintf (file, " UPCALLS");
+ if (val & EIHD__M_OMV_READY)
+ fprintf (file, " OMV_READY");
+ if (val & EIHD__M_EXT_BIND_SECT)
+ fprintf (file, " EXT_BIND_SECT");
+ fprintf (file, "\n");
+ fprintf (file, _(" ident: 0x%08x, sysver: 0x%08x, "
+ "match ctrl: %u, symvect_size: %u\n"),
+ (unsigned)bfd_getl32 (eihd.ident),
+ (unsigned)bfd_getl32 (eihd.sysver),
+ eihd.matchctl,
+ (unsigned)bfd_getl32 (eihd.symvect_size));
+ fprintf (file, _(" BPAGE: %u"),
+ (unsigned)bfd_getl32 (eihd.virt_mem_block_size));
+ if (val & (EIHD__M_OMV_READY | EIHD__M_EXT_BIND_SECT))
+ {
+ eihef_off = bfd_getl32 (eihd.ext_fixup_off);
+ eihnp_off = bfd_getl32 (eihd.noopt_psect_off);
+ fprintf (file, _(", ext fixup offset: %u, no_opt psect off: %u"),
+ eihef_off, eihnp_off);
+ }
+ fprintf (file, _(", alias: %u\n"), (unsigned)bfd_getl16 (eihd.alias));
+
+ if (eihvn_off != 0)
+ {
+ struct vms_eihvn eihvn;
+ unsigned int mask;
+ unsigned int j;
+
+ fprintf (file, _("system version array information:\n"));
+ if (bfd_seek (abfd, (file_ptr) eihvn_off, SEEK_SET)
+ || bfd_bread (&eihvn, sizeof (eihvn), abfd) != sizeof (eihvn))
+ {
+ fprintf (file, _("cannot read EIHVN header\n"));
+ return;
+ }
+ mask = bfd_getl32 (eihvn.subsystem_mask);
+ for (j = 0; j < 32; j++)
+ if (mask & (1 << j))
+ {
+ struct vms_eihvn_subversion ver;
+ if (bfd_bread (&ver, sizeof (ver), abfd) != sizeof (ver))
+ {
+ fprintf (file, _("cannot read EIHVN version\n"));
+ return;
+ }
+ fprintf (file, _(" %02u "), j);
+ switch (j)
+ {
+ case EIHVN__BASE_IMAGE_BIT:
+ fputs (_("BASE_IMAGE "), file);
+ break;
+ case EIHVN__MEMORY_MANAGEMENT_BIT:
+ fputs (_("MEMORY_MANAGEMENT"), file);
+ break;
+ case EIHVN__IO_BIT:
+ fputs (_("IO "), file);
+ break;
+ case EIHVN__FILES_VOLUMES_BIT:
+ fputs (_("FILES_VOLUMES "), file);
+ break;
+ case EIHVN__PROCESS_SCHED_BIT:
+ fputs (_("PROCESS_SCHED "), file);
+ break;
+ case EIHVN__SYSGEN_BIT:
+ fputs (_("SYSGEN "), file);
+ break;
+ case EIHVN__CLUSTERS_LOCKMGR_BIT:
+ fputs (_("CLUSTERS_LOCKMGR "), file);
+ break;
+ case EIHVN__LOGICAL_NAMES_BIT:
+ fputs (_("LOGICAL_NAMES "), file);
+ break;
+ case EIHVN__SECURITY_BIT:
+ fputs (_("SECURITY "), file);
+ break;
+ case EIHVN__IMAGE_ACTIVATOR_BIT:
+ fputs (_("IMAGE_ACTIVATOR "), file);
+ break;
+ case EIHVN__NETWORKS_BIT:
+ fputs (_("NETWORKS "), file);
+ break;
+ case EIHVN__COUNTERS_BIT:
+ fputs (_("COUNTERS "), file);
+ break;
+ case EIHVN__STABLE_BIT:
+ fputs (_("STABLE "), file);
+ break;
+ case EIHVN__MISC_BIT:
+ fputs (_("MISC "), file);
+ break;
+ case EIHVN__CPU_BIT:
+ fputs (_("CPU "), file);
+ break;
+ case EIHVN__VOLATILE_BIT:
+ fputs (_("VOLATILE "), file);
+ break;
+ case EIHVN__SHELL_BIT:
+ fputs (_("SHELL "), file);
+ break;
+ case EIHVN__POSIX_BIT:
+ fputs (_("POSIX "), file);
+ break;
+ case EIHVN__MULTI_PROCESSING_BIT:
+ fputs (_("MULTI_PROCESSING "), file);
+ break;
+ case EIHVN__GALAXY_BIT:
+ fputs (_("GALAXY "), file);
+ break;
+ default:
+ fputs (_("*unknown* "), file);
+ break;
+ }
+ fprintf (file, _(": %u.%u\n"),
+ (unsigned)bfd_getl16 (ver.major),
+ (unsigned)bfd_getl16 (ver.minor));
+ }
+ }
+
+ if (eiha_off != 0)
+ {
+ struct vms_eiha eiha;
+
+ if (bfd_seek (abfd, (file_ptr) eiha_off, SEEK_SET)
+ || bfd_bread (&eiha, sizeof (eiha), abfd) != sizeof (eiha))
+ {
+ fprintf (file, _("cannot read EIHA\n"));
+ return;
+ }
+ fprintf (file, _("Image activation: (size=%u)\n"),
+ (unsigned)bfd_getl32 (eiha.size));
+ fprintf (file, _(" First address : 0x%08x 0x%08x\n"),
+ (unsigned)bfd_getl32 (eiha.tfradr1_h),
+ (unsigned)bfd_getl32 (eiha.tfradr1));
+ fprintf (file, _(" Second address: 0x%08x 0x%08x\n"),
+ (unsigned)bfd_getl32 (eiha.tfradr2_h),
+ (unsigned)bfd_getl32 (eiha.tfradr2));
+ fprintf (file, _(" Third address : 0x%08x 0x%08x\n"),
+ (unsigned)bfd_getl32 (eiha.tfradr3_h),
+ (unsigned)bfd_getl32 (eiha.tfradr3));
+ fprintf (file, _(" Fourth address: 0x%08x 0x%08x\n"),
+ (unsigned)bfd_getl32 (eiha.tfradr4_h),
+ (unsigned)bfd_getl32 (eiha.tfradr4));
+ fprintf (file, _(" Shared image : 0x%08x 0x%08x\n"),
+ (unsigned)bfd_getl32 (eiha.inishr_h),
+ (unsigned)bfd_getl32 (eiha.inishr));
+ }
+ if (eihi_off != 0)
+ {
+ struct vms_eihi eihi;
+
+ if (bfd_seek (abfd, (file_ptr) eihi_off, SEEK_SET)
+ || bfd_bread (&eihi, sizeof (eihi), abfd) != sizeof (eihi))
+ {
+ fprintf (file, _("cannot read EIHI\n"));
+ return;
+ }
+ fprintf (file, _("Image identification: (major: %u, minor: %u)\n"),
+ (unsigned)bfd_getl32 (eihi.majorid),
+ (unsigned)bfd_getl32 (eihi.minorid));
+ fprintf (file, _(" image name : %.*s\n"),
+ eihi.imgnam[0], eihi.imgnam + 1);
+ fprintf (file, _(" link time : %s\n"),
+ vms_time_to_str (eihi.linktime));
+ fprintf (file, _(" image ident : %.*s\n"),
+ eihi.imgid[0], eihi.imgid + 1);
+ fprintf (file, _(" linker ident : %.*s\n"),
+ eihi.linkid[0], eihi.linkid + 1);
+ fprintf (file, _(" image build ident: %.*s\n"),
+ eihi.imgbid[0], eihi.imgbid + 1);
+ }
+ if (eihs_off != 0)
+ {
+ struct vms_eihs eihs;
+
+ if (bfd_seek (abfd, (file_ptr) eihs_off, SEEK_SET)
+ || bfd_bread (&eihs, sizeof (eihs), abfd) != sizeof (eihs))
+ {
+ fprintf (file, _("cannot read EIHS\n"));
+ return;
+ }
+ fprintf (file, _("Image symbol & debug table: (major: %u, minor: %u)\n"),
+ (unsigned)bfd_getl32 (eihs.majorid),
+ (unsigned)bfd_getl32 (eihs.minorid));
+ dst_vbn = bfd_getl32 (eihs.dstvbn);
+ dst_size = bfd_getl32 (eihs.dstsize);
+ fprintf (file, _(" debug symbol table : vbn: %u, size: %u (0x%x)\n"),
+ dst_vbn, dst_size, dst_size);
+ gst_vbn = bfd_getl32 (eihs.gstvbn);
+ gst_size = bfd_getl32 (eihs.gstsize);
+ fprintf (file, _(" global symbol table: vbn: %u, records: %u\n"),
+ gst_vbn, gst_size);
+ dmt_vbn = bfd_getl32 (eihs.dmtvbn);
+ dmt_size = bfd_getl32 (eihs.dmtsize);
+ fprintf (file, _(" debug module table : vbn: %u, size: %u\n"),
+ dmt_vbn, dmt_size);
+ }
+ while (eisd_off != 0)
+ {
+ struct vms_eisd eisd;
+ unsigned int len;
+
+ while (1)
+ {
+ if (bfd_seek (abfd, (file_ptr) eisd_off, SEEK_SET)
+ || bfd_bread (&eisd, sizeof (eisd), abfd) != sizeof (eisd))
+ {
+ fprintf (file, _("cannot read EISD\n"));
+ return;
+ }
+ len = (unsigned)bfd_getl32 (eisd.eisdsize);
+ if (len != (unsigned)-1)
+ break;
+
+ /* Next block. */
+ eisd_off = (eisd_off + VMS_BLOCK_SIZE) & ~(VMS_BLOCK_SIZE - 1);
+ }
+ fprintf (file, _("Image section descriptor: (major: %u, minor: %u, "
+ "size: %u, offset: %u)\n"),
+ (unsigned)bfd_getl32 (eisd.majorid),
+ (unsigned)bfd_getl32 (eisd.minorid),
+ len, eisd_off);
+ if (len == 0)
+ break;
+ fprintf (file, _(" section: base: 0x%08x%08x size: 0x%08x\n"),
+ (unsigned)bfd_getl32 (eisd.virt_addr + 4),
+ (unsigned)bfd_getl32 (eisd.virt_addr + 0),
+ (unsigned)bfd_getl32 (eisd.secsize));
+ val = (unsigned)bfd_getl32 (eisd.flags);
+ fprintf (file, _(" flags: 0x%04x"), val);
+ if (val & EISD__M_GBL)
+ fprintf (file, " GBL");
+ if (val & EISD__M_CRF)
+ fprintf (file, " CRF");
+ if (val & EISD__M_DZRO)
+ fprintf (file, " DZRO");
+ if (val & EISD__M_WRT)
+ fprintf (file, " WRT");
+ if (val & EISD__M_INITALCODE)
+ fprintf (file, " INITALCODE");
+ if (val & EISD__M_BASED)
+ fprintf (file, " BASED");
+ if (val & EISD__M_FIXUPVEC)
+ fprintf (file, " FIXUPVEC");
+ if (val & EISD__M_RESIDENT)
+ fprintf (file, " RESIDENT");
+ if (val & EISD__M_VECTOR)
+ fprintf (file, " VECTOR");
+ if (val & EISD__M_PROTECT)
+ fprintf (file, " PROTECT");
+ if (val & EISD__M_LASTCLU)
+ fprintf (file, " LASTCLU");
+ if (val & EISD__M_EXE)
+ fprintf (file, " EXE");
+ if (val & EISD__M_NONSHRADR)
+ fprintf (file, " NONSHRADR");
+ if (val & EISD__M_QUAD_LENGTH)
+ fprintf (file, " QUAD_LENGTH");
+ if (val & EISD__M_ALLOC_64BIT)
+ fprintf (file, " ALLOC_64BIT");
+ fprintf (file, "\n");
+ if (val & EISD__M_FIXUPVEC)
+ {
+ eiaf_vbn = bfd_getl32 (eisd.vbn);
+ eiaf_size = bfd_getl32 (eisd.secsize);
+ }
+ fprintf (file, _(" vbn: %u, pfc: %u, matchctl: %u type: %u ("),
+ (unsigned)bfd_getl32 (eisd.vbn),
+ eisd.pfc, eisd.matchctl, eisd.type);
+ switch (eisd.type)
+ {
+ case EISD__K_NORMAL:
+ fputs (_("NORMAL"), file);
+ break;
+ case EISD__K_SHRFXD:
+ fputs (_("SHRFXD"), file);
+ break;
+ case EISD__K_PRVFXD:
+ fputs (_("PRVFXD"), file);
+ break;
+ case EISD__K_SHRPIC:
+ fputs (_("SHRPIC"), file);
+ break;
+ case EISD__K_PRVPIC:
+ fputs (_("PRVPIC"), file);
+ break;
+ case EISD__K_USRSTACK:
+ fputs (_("USRSTACK"), file);
+ break;
+ default:
+ fputs (_("*unknown*"), file);
+ break;
+ }
+ fputs (_(")\n"), file);
+ if (val & EISD__M_GBL)
+ fprintf (file, _(" ident: 0x%08x, name: %.*s\n"),
+ (unsigned)bfd_getl32 (eisd.ident),
+ eisd.gblnam[0], eisd.gblnam + 1);
+ eisd_off += len;
+ }
+
+ if (dmt_vbn != 0)
+ {
+ if (bfd_seek (abfd, (file_ptr) (dmt_vbn - 1) * VMS_BLOCK_SIZE, SEEK_SET))
+ {
+ fprintf (file, _("cannot read DMT\n"));
+ return;
+ }
+
+ fprintf (file, _("Debug module table:\n"));
+
+ while (dmt_size > 0)
+ {
+ struct vms_dmt_header dmth;
+ unsigned int count;
+
+ if (bfd_bread (&dmth, sizeof (dmth), abfd) != sizeof (dmth))
+ {
+ fprintf (file, _("cannot read DMT header\n"));
+ return;
+ }
+ count = bfd_getl16 (dmth.psect_count);
+ fprintf (file,
+ _(" module offset: 0x%08x, size: 0x%08x, (%u psects)\n"),
+ (unsigned)bfd_getl32 (dmth.modbeg),
+ (unsigned)bfd_getl32 (dmth.size), count);
+ dmt_size -= sizeof (dmth);
+ while (count > 0)
+ {
+ struct vms_dmt_psect dmtp;
+
+ if (bfd_bread (&dmtp, sizeof (dmtp), abfd) != sizeof (dmtp))
+ {
+ fprintf (file, _("cannot read DMT psect\n"));
+ return;
+ }
+ fprintf (file, _(" psect start: 0x%08x, length: %u\n"),
+ (unsigned)bfd_getl32 (dmtp.start),
+ (unsigned)bfd_getl32 (dmtp.length));
+ count--;
+ dmt_size -= sizeof (dmtp);
+ }
+ }
+ }
+
+ if (dst_vbn != 0)
+ {
+ if (bfd_seek (abfd, (file_ptr) (dst_vbn - 1) * VMS_BLOCK_SIZE, SEEK_SET))
+ {
+ fprintf (file, _("cannot read DST\n"));
+ return;
+ }
+
+ evax_bfd_print_dst (abfd, dst_size, file);
+ }
+ if (gst_vbn != 0)
+ {
+ if (bfd_seek (abfd, (file_ptr) (gst_vbn - 1) * VMS_BLOCK_SIZE, SEEK_SET))
+ {
+ fprintf (file, _("cannot read GST\n"));
+ return;
+ }
+
+ fprintf (file, _("Global symbol table:\n"));
+ evax_bfd_print_eobj (abfd, file);
+ }
+ if (eiaf_vbn != 0)
+ {
+ unsigned char *buf;
+ struct vms_eiaf *eiaf;
+ unsigned int qrelfixoff;
+ unsigned int lrelfixoff;
+ unsigned int qdotadroff;
+ unsigned int ldotadroff;
+ unsigned int shrimgcnt;
+ unsigned int shlstoff;
+ unsigned int codeadroff;
+ unsigned int lpfixoff;
+ unsigned int chgprtoff;
+
+ buf = bfd_malloc (eiaf_size);
+
+ if (bfd_seek (abfd, (file_ptr) (eiaf_vbn - 1) * VMS_BLOCK_SIZE, SEEK_SET)
+ || bfd_bread (buf, eiaf_size, abfd) != eiaf_size)
+ {
+ fprintf (file, _("cannot read EIHA\n"));
+ free (buf);
+ return;
+ }
+ eiaf = (struct vms_eiaf *)buf;
+ fprintf (file,
+ _("Image activator fixup: (major: %u, minor: %u)\n"),
+ (unsigned)bfd_getl32 (eiaf->majorid),
+ (unsigned)bfd_getl32 (eiaf->minorid));
+ fprintf (file, _(" iaflink : 0x%08x %08x\n"),
+ (unsigned)bfd_getl32 (eiaf->iaflink + 0),
+ (unsigned)bfd_getl32 (eiaf->iaflink + 4));
+ fprintf (file, _(" fixuplnk: 0x%08x %08x\n"),
+ (unsigned)bfd_getl32 (eiaf->fixuplnk + 0),
+ (unsigned)bfd_getl32 (eiaf->fixuplnk + 4));
+ fprintf (file, _(" size : %u\n"),
+ (unsigned)bfd_getl32 (eiaf->size));
+ fprintf (file, _(" flags: 0x%08x\n"),
+ (unsigned)bfd_getl32 (eiaf->flags));
+ qrelfixoff = bfd_getl32 (eiaf->qrelfixoff);
+ lrelfixoff = bfd_getl32 (eiaf->lrelfixoff);
+ fprintf (file, _(" qrelfixoff: %5u, lrelfixoff: %5u\n"),
+ qrelfixoff, lrelfixoff);
+ qdotadroff = bfd_getl32 (eiaf->qdotadroff);
+ ldotadroff = bfd_getl32 (eiaf->ldotadroff);
+ fprintf (file, _(" qdotadroff: %5u, ldotadroff: %5u\n"),
+ qdotadroff, ldotadroff);
+ codeadroff = bfd_getl32 (eiaf->codeadroff);
+ lpfixoff = bfd_getl32 (eiaf->lpfixoff);
+ fprintf (file, _(" codeadroff: %5u, lpfixoff : %5u\n"),
+ codeadroff, lpfixoff);
+ chgprtoff = bfd_getl32 (eiaf->chgprtoff);
+ fprintf (file, _(" chgprtoff : %5u\n"), chgprtoff);
+ shrimgcnt = bfd_getl32 (eiaf->shrimgcnt);
+ shlstoff = bfd_getl32 (eiaf->shlstoff);
+ fprintf (file, _(" shlstoff : %5u, shrimgcnt : %5u\n"),
+ shlstoff, shrimgcnt);
+ fprintf (file, _(" shlextra : %5u, permctx : %5u\n"),
+ (unsigned)bfd_getl32 (eiaf->shlextra),
+ (unsigned)bfd_getl32 (eiaf->permctx));
+ fprintf (file, _(" base_va : 0x%08x\n"),
+ (unsigned)bfd_getl32 (eiaf->base_va));
+ fprintf (file, _(" lppsbfixoff: %5u\n"),
+ (unsigned)bfd_getl32 (eiaf->lppsbfixoff));
+
+ if (shlstoff)
+ {
+ struct vms_shl *shl = (struct vms_shl *)(buf + shlstoff);
+ unsigned int j;
+
+ fprintf (file, _(" Shareable images:\n"));
+ for (j = 0; j < shrimgcnt; j++, shl++)
+ {
+ fprintf (file,
+ _(" %u: size: %u, flags: 0x%02x, name: %.*s\n"),
+ j, shl->size, shl->flags,
+ shl->imgnam[0], shl->imgnam + 1);
+ }
+ }
+ if (qrelfixoff != 0)
+ {
+ fprintf (file, _(" quad-word relocation fixups:\n"));
+ evax_bfd_print_relocation_records (file, buf + qrelfixoff, 8);
+ }
+ if (lrelfixoff != 0)
+ {
+ fprintf (file, _(" long-word relocation fixups:\n"));
+ evax_bfd_print_relocation_records (file, buf + lrelfixoff, 4);
+ }
+ if (qdotadroff != 0)
+ {
+ fprintf (file, _(" quad-word .address reference fixups:\n"));
+ evax_bfd_print_address_fixups (file, buf + qdotadroff);
+ }
+ if (ldotadroff != 0)
+ {
+ fprintf (file, _(" long-word .address reference fixups:\n"));
+ evax_bfd_print_address_fixups (file, buf + ldotadroff);
+ }
+ if (codeadroff != 0)
+ {
+ fprintf (file, _(" Code Address Reference Fixups:\n"));
+ evax_bfd_print_reference_fixups (file, buf + codeadroff);
+ }
+ if (lpfixoff != 0)
+ {
+ fprintf (file, _(" Linkage Pairs Reference Fixups:\n"));
+ evax_bfd_print_reference_fixups (file, buf + lpfixoff);
+ }
+ if (chgprtoff)
+ {
+ unsigned int count = (unsigned)bfd_getl32 (buf + chgprtoff);
+ struct vms_eicp *eicp = (struct vms_eicp *)(buf + chgprtoff + 4);
+ unsigned int j;
+
+ fprintf (file, _(" Change Protection (%u entries):\n"), count);
+ for (j = 0; j < count; j++, eicp++)
+ {
+ unsigned int prot = bfd_getl32 (eicp->newprt);
+ fprintf (file,
+ _(" base: 0x%08x %08x, size: 0x%08x, prot: 0x%08x "),
+ (unsigned)bfd_getl32 (eicp->baseva + 4),
+ (unsigned)bfd_getl32 (eicp->baseva + 0),
+ (unsigned)bfd_getl32 (eicp->size),
+ (unsigned)bfd_getl32 (eicp->newprt));
+ switch (prot)
+ {
+ case PRT__C_NA:
+ fprintf (file, "NA");
+ break;
+ case PRT__C_RESERVED:
+ fprintf (file, "RES");
+ break;
+ case PRT__C_KW:
+ fprintf (file, "KW");
+ break;
+ case PRT__C_KR:
+ fprintf (file, "KR");
+ break;
+ case PRT__C_UW:
+ fprintf (file, "UW");
+ break;
+ case PRT__C_EW:
+ fprintf (file, "EW");
+ break;
+ case PRT__C_ERKW:
+ fprintf (file, "ERKW");
+ break;
+ case PRT__C_ER:
+ fprintf (file, "ER");
+ break;
+ case PRT__C_SW:
+ fprintf (file, "SW");
+ break;
+ case PRT__C_SREW:
+ fprintf (file, "SREW");
+ break;
+ case PRT__C_SRKW:
+ fprintf (file, "SRKW");
+ break;
+ case PRT__C_SR:
+ fprintf (file, "SR");
+ break;
+ case PRT__C_URSW:
+ fprintf (file, "URSW");
+ break;
+ case PRT__C_UREW:
+ fprintf (file, "UREW");
+ break;
+ case PRT__C_URKW:
+ fprintf (file, "URKW");
+ break;
+ case PRT__C_UR:
+ fprintf (file, "UR");
+ break;
+ default:
+ fputs ("??", file);
+ break;
+ }
+ fputc ('\n', file);
+ }
+ }
+ free (buf);
+ }
+}
+
+static bfd_boolean
+vms_bfd_print_private_bfd_data (bfd *abfd, void *ptr)
+{
+ FILE *file = (FILE *)ptr;
+
+ if (bfd_get_file_flags (abfd) & (EXEC_P | DYNAMIC))
+ evax_bfd_print_image (abfd, file);
+ else
+ {
+ if (bfd_seek (abfd, 0, SEEK_SET))
+ return FALSE;
+ evax_bfd_print_eobj (abfd, file);
+ }
+ return TRUE;
+}
+
+/* Linking. */
+
+/* Slurp ETIR/EDBG/ETBT VMS object records. */
+
+static bfd_boolean
+alpha_vms_read_sections_content (bfd *abfd, struct bfd_link_info *info)
+{
+ asection *cur_section;
+ file_ptr cur_offset;
+ asection *dst_section;
+ file_ptr dst_offset;
+
+ if (bfd_seek (abfd, 0, SEEK_SET) != 0)
+ return FALSE;
+
+ cur_section = NULL;
+ cur_offset = 0;
+
+ dst_section = PRIV (dst_section);
+ dst_offset = 0;
+ if (info)
+ {
+ if (info->strip == strip_all || info->strip == strip_debugger)
+ {
+ /* Discard the DST section. */
+ dst_offset = 0;
+ dst_section = NULL;
+ }
+ else if (dst_section)
+ {
+ dst_offset = dst_section->output_offset;
+ dst_section = dst_section->output_section;
+ }
+ }
+
+ while (1)
+ {
+ int type;
+ bfd_boolean res;
+
+ type = _bfd_vms_get_object_record (abfd);
+ if (type < 0)
+ {
+ vms_debug2 ((2, "next_record failed\n"));
+ return FALSE;
+ }
+ switch (type)
+ {
+ case EOBJ__C_ETIR:
+ PRIV (image_section) = cur_section;
+ PRIV (image_offset) = cur_offset;
+ res = _bfd_vms_slurp_etir (abfd, info);
+ cur_section = PRIV (image_section);
+ cur_offset = PRIV (image_offset);
+ break;
+ case EOBJ__C_EDBG:
+ case EOBJ__C_ETBT:
+ if (dst_section == NULL)
+ continue;
+ PRIV (image_section) = dst_section;
+ PRIV (image_offset) = dst_offset;
+ res = _bfd_vms_slurp_etir (abfd, info);
+ dst_offset = PRIV (image_offset);
+ break;
+ case EOBJ__C_EEOM:
+ return TRUE;
+ default:
+ continue;
+ }
+ if (!res)
+ {
+ vms_debug2 ((2, "slurp eobj type %d failed\n", type));
+ return FALSE;
+ }
+ }
+}
+
+static int
+alpha_vms_sizeof_headers (bfd *abfd ATTRIBUTE_UNUSED,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+/* Add a linkage pair fixup at address SECT + OFFSET to SHLIB. */
+
+static void
+alpha_vms_add_fixup_lp (struct bfd_link_info *info, bfd *src, bfd *shlib)
+{
+ struct alpha_vms_shlib_el *sl;
+ asection *sect = PRIV2 (src, image_section);
+ file_ptr offset = PRIV2 (src, image_offset);
+
+ sl = &VEC_EL (alpha_vms_link_hash (info)->shrlibs,
+ struct alpha_vms_shlib_el, PRIV2 (shlib, shr_index));
+ sl->has_fixups = TRUE;
+ VEC_APPEND_EL (sl->lp, bfd_vma,
+ sect->output_section->vma + sect->output_offset + offset);
+ sect->output_section->flags |= SEC_RELOC;
+}
+
+/* Add a code address fixup at address SECT + OFFSET to SHLIB. */
+
+static void
+alpha_vms_add_fixup_ca (struct bfd_link_info *info, bfd *src, bfd *shlib)
+{
+ struct alpha_vms_shlib_el *sl;
+ asection *sect = PRIV2 (src, image_section);
+ file_ptr offset = PRIV2 (src, image_offset);
+
+ sl = &VEC_EL (alpha_vms_link_hash (info)->shrlibs,
+ struct alpha_vms_shlib_el, PRIV2 (shlib, shr_index));
+ sl->has_fixups = TRUE;
+ VEC_APPEND_EL (sl->ca, bfd_vma,
+ sect->output_section->vma + sect->output_offset + offset);
+ sect->output_section->flags |= SEC_RELOC;
+}
+
+/* Add a quad word relocation fixup at address SECT + OFFSET to SHLIB. */
+
+static void
+alpha_vms_add_fixup_qr (struct bfd_link_info *info, bfd *src,
+ bfd *shlib, bfd_vma vec)
+{
+ struct alpha_vms_shlib_el *sl;
+ struct alpha_vms_vma_ref *r;
+ asection *sect = PRIV2 (src, image_section);
+ file_ptr offset = PRIV2 (src, image_offset);
+
+ sl = &VEC_EL (alpha_vms_link_hash (info)->shrlibs,
+ struct alpha_vms_shlib_el, PRIV2 (shlib, shr_index));
+ sl->has_fixups = TRUE;
+ r = VEC_APPEND (sl->qr, struct alpha_vms_vma_ref);
+ r->vma = sect->output_section->vma + sect->output_offset + offset;
+ r->ref = vec;
+ sect->output_section->flags |= SEC_RELOC;
+}
+
+static void
+alpha_vms_add_fixup_lr (struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ unsigned int shr ATTRIBUTE_UNUSED,
+ bfd_vma vec ATTRIBUTE_UNUSED)
+{
+ /* Not yet supported. */
+ abort ();
+}
+
+/* Add relocation. FIXME: Not yet emitted. */
+
+static void
+alpha_vms_add_lw_reloc (struct bfd_link_info *info ATTRIBUTE_UNUSED)
+{
+}
+
+static void
+alpha_vms_add_qw_reloc (struct bfd_link_info *info ATTRIBUTE_UNUSED)
+{
+}
+
+static struct bfd_hash_entry *
+alpha_vms_link_hash_newfunc (struct bfd_hash_entry *entry,
+ struct bfd_hash_table *table,
+ const char *string)
+{
+ struct alpha_vms_link_hash_entry *ret =
+ (struct alpha_vms_link_hash_entry *) entry;
+
+ /* Allocate the structure if it has not already been allocated by a
+ subclass. */
+ if (ret == NULL)
+ ret = ((struct alpha_vms_link_hash_entry *)
+ bfd_hash_allocate (table,
+ sizeof (struct alpha_vms_link_hash_entry)));
+ if (ret == NULL)
+ return NULL;
+
+ /* Call the allocation method of the superclass. */
+ ret = ((struct alpha_vms_link_hash_entry *)
+ _bfd_link_hash_newfunc ((struct bfd_hash_entry *) ret,
+ table, string));
+
+ ret->sym = NULL;
+
+ return (struct bfd_hash_entry *) ret;
+}
+
+/* Create an Alpha/VMS link hash table. */
+
+static struct bfd_link_hash_table *
+alpha_vms_bfd_link_hash_table_create (bfd *abfd)
+{
+ struct alpha_vms_link_hash_table *ret;
+ bfd_size_type amt = sizeof (struct alpha_vms_link_hash_table);
+
+ ret = (struct alpha_vms_link_hash_table *) bfd_malloc (amt);
+ if (ret == NULL)
+ return NULL;
+ if (!_bfd_link_hash_table_init (&ret->root, abfd,
+ alpha_vms_link_hash_newfunc,
+ sizeof (struct alpha_vms_link_hash_entry)))
+ {
+ free (ret);
+ return NULL;
+ }
+
+ VEC_INIT (ret->shrlibs);
+ ret->fixup = NULL;
+
+ return &ret->root;
+}
+
+static bfd_boolean
+alpha_vms_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info)
+{
+ unsigned int i;
+
+ for (i = 0; i < PRIV (gsd_sym_count); i++)
+ {
+ struct vms_symbol_entry *e = PRIV (syms)[i];
+ struct alpha_vms_link_hash_entry *h;
+ struct bfd_link_hash_entry *h_root;
+ asymbol sym;
+
+ if (!alpha_vms_convert_symbol (abfd, e, &sym))
+ return FALSE;
+
+ if ((e->flags & EGSY__V_DEF) && abfd->selective_search)
+ {
+ /* In selective_search mode, only add definition that are
+ required. */
+ h = (struct alpha_vms_link_hash_entry *)bfd_link_hash_lookup
+ (info->hash, sym.name, FALSE, FALSE, FALSE);
+ if (h == NULL || h->root.type != bfd_link_hash_undefined)
+ continue;
+ }
+ else
+ h = NULL;
+
+ h_root = (struct bfd_link_hash_entry *) h;
+ if (_bfd_generic_link_add_one_symbol
+ (info, abfd, sym.name, sym.flags, sym.section, sym.value,
+ NULL, FALSE, FALSE, &h_root) == FALSE)
+ return FALSE;
+ h = (struct alpha_vms_link_hash_entry *) h_root;
+
+ if ((e->flags & EGSY__V_DEF)
+ && h->sym == NULL
+ && abfd->xvec == info->output_bfd->xvec)
+ h->sym = e;
+ }
+
+ if (abfd->flags & DYNAMIC)
+ {
+ struct alpha_vms_shlib_el *shlib;
+
+ /* We do not want to include any of the sections in a dynamic
+ object in the output file. See comment in elflink.c. */
+ bfd_section_list_clear (abfd);
+
+ shlib = VEC_APPEND (alpha_vms_link_hash (info)->shrlibs,
+ struct alpha_vms_shlib_el);
+ shlib->abfd = abfd;
+ VEC_INIT (shlib->ca);
+ VEC_INIT (shlib->lp);
+ VEC_INIT (shlib->qr);
+ PRIV (shr_index) = VEC_COUNT (alpha_vms_link_hash (info)->shrlibs) - 1;
+ }
+
+ return TRUE;
+}
+
+static bfd_boolean
+alpha_vms_link_add_archive_symbols (bfd *abfd, struct bfd_link_info *info)
+{
+ int pass;
+ struct bfd_link_hash_entry **pundef;
+ struct bfd_link_hash_entry **next_pundef;
+
+ /* We only accept VMS libraries. */
+ if (info->output_bfd->xvec != abfd->xvec)
+ {
+ bfd_set_error (bfd_error_wrong_format);
+ return FALSE;
+ }
+
+ /* The archive_pass field in the archive itself is used to
+ initialize PASS, since we may search the same archive multiple
+ times. */
+ pass = ++abfd->archive_pass;
+
+ /* Look through the list of undefined symbols. */
+ for (pundef = &info->hash->undefs; *pundef != NULL; pundef = next_pundef)
+ {
+ struct bfd_link_hash_entry *h;
+ symindex symidx;
+ bfd *element;
+ bfd *orig_element;
+
+ h = *pundef;
+ next_pundef = &(*pundef)->u.undef.next;
+
+ /* 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 = *next_pundef;
+ next_pundef = pundef;
+ }
+ continue;
+ }
+
+ /* Look for this symbol in the archive hash table. */
+ symidx = _bfd_vms_lib_find_symbol (abfd, h->root.string);
+ if (symidx == BFD_NO_MORE_SYMBOLS)
+ {
+ /* Nothing in this slot. */
+ continue;
+ }
+
+ element = bfd_get_elt_at_index (abfd, symidx);
+ if (element == NULL)
+ return FALSE;
+
+ if (element->archive_pass == -1 || element->archive_pass == pass)
+ {
+ /* Next symbol if this archive is wrong or already handled. */
+ continue;
+ }
+
+ if (! bfd_check_format (element, bfd_object))
+ {
+ element->archive_pass = -1;
+ return FALSE;
+ }
+
+ orig_element = element;
+ if (bfd_is_thin_archive (abfd))
+ {
+ element = _bfd_vms_lib_get_imagelib_file (element);
+ if (element == NULL || !bfd_check_format (element, bfd_object))
+ {
+ orig_element->archive_pass = -1;
+ 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, h->root.string, &element))
+ return FALSE;
+ if (!alpha_vms_link_add_object_symbols (element, info))
+ return FALSE;
+
+ orig_element->archive_pass = pass;
+ }
+
+ return TRUE;
+}
+
+static bfd_boolean
+alpha_vms_bfd_link_add_symbols (bfd *abfd, struct bfd_link_info *info)
+{
+ switch (bfd_get_format (abfd))
+ {
+ case bfd_object:
+ vms_debug2 ((2, "vms_link_add_symbols for object %s\n",
+ abfd->filename));
+ return alpha_vms_link_add_object_symbols (abfd, info);
+ break;
+ case bfd_archive:
+ vms_debug2 ((2, "vms_link_add_symbols for archive %s\n",
+ abfd->filename));
+ return alpha_vms_link_add_archive_symbols (abfd, info);
+ break;
+ default:
+ bfd_set_error (bfd_error_wrong_format);
+ return FALSE;
+ }
+}
+
+static bfd_boolean
+alpha_vms_build_fixups (struct bfd_link_info *info)
+{
+ struct alpha_vms_link_hash_table *t = alpha_vms_link_hash (info);
+ unsigned char *content;
+ unsigned int i;
+ unsigned int sz = 0;
+ unsigned int lp_sz = 0;
+ unsigned int ca_sz = 0;
+ unsigned int qr_sz = 0;
+ unsigned int shrimg_cnt = 0;
+ unsigned int chgprt_num = 0;
+ unsigned int chgprt_sz = 0;
+ struct vms_eiaf *eiaf;
+ unsigned int off;
+ asection *sec;
+
+ /* Shared libraries. */
+ for (i = 0; i < VEC_COUNT (t->shrlibs); i++)
+ {
+ struct alpha_vms_shlib_el *shlib;
+
+ shlib = &VEC_EL (t->shrlibs, struct alpha_vms_shlib_el, i);
+
+ if (!shlib->has_fixups)
+ continue;
+
+ shrimg_cnt++;
+
+ if (VEC_COUNT (shlib->ca) > 0)
+ {
+ /* Header + entries. */
+ ca_sz += 8;
+ ca_sz += VEC_COUNT (shlib->ca) * 4;
+ }
+ if (VEC_COUNT (shlib->lp) > 0)
+ {
+ /* Header + entries. */
+ lp_sz += 8;
+ lp_sz += VEC_COUNT (shlib->lp) * 4;
+ }
+ if (VEC_COUNT (shlib->qr) > 0)
+ {
+ /* Header + entries. */
+ qr_sz += 8;
+ qr_sz += VEC_COUNT (shlib->qr) * 8;
+ }
+ }
+ /* Add markers. */
+ if (ca_sz > 0)
+ ca_sz += 8;
+ if (lp_sz > 0)
+ lp_sz += 8;
+ if (qr_sz > 0)
+ qr_sz += 8;
+
+ /* Finish now if there is no content. */
+ if (ca_sz + lp_sz + qr_sz == 0)
+ return TRUE;
+
+ /* Add an eicp entry for the fixup itself. */
+ chgprt_num = 1;
+ for (sec = info->output_bfd->sections; sec != NULL; sec = sec->next)
+ {
+ /* This isect could be made RO or EXE after relocations are applied. */
+ if ((sec->flags & SEC_RELOC) != 0
+ && (sec->flags & (SEC_CODE | SEC_READONLY)) != 0)
+ chgprt_num++;
+ }
+ chgprt_sz = 4 + chgprt_num * sizeof (struct vms_eicp);
+
+ /* Allocate section content (round-up size) */
+ sz = sizeof (struct vms_eiaf) + shrimg_cnt * sizeof (struct vms_shl)
+ + ca_sz + lp_sz + qr_sz + chgprt_sz;
+ sz = (sz + VMS_BLOCK_SIZE - 1) & ~(VMS_BLOCK_SIZE - 1);
+ content = bfd_zalloc (info->output_bfd, sz);
+ if (content == NULL)
+ return FALSE;
+
+ sec = alpha_vms_link_hash (info)->fixup;
+ sec->contents = content;
+ sec->size = sz;
+
+ eiaf = (struct vms_eiaf *)content;
+ off = sizeof (struct vms_eiaf);
+ bfd_putl32 (0, eiaf->majorid);
+ bfd_putl32 (0, eiaf->minorid);
+ bfd_putl32 (0, eiaf->iaflink);
+ bfd_putl32 (0, eiaf->fixuplnk);
+ bfd_putl32 (sizeof (struct vms_eiaf), eiaf->size);
+ bfd_putl32 (0, eiaf->flags);
+ bfd_putl32 (0, eiaf->qrelfixoff);
+ bfd_putl32 (0, eiaf->lrelfixoff);
+ bfd_putl32 (0, eiaf->qdotadroff);
+ bfd_putl32 (0, eiaf->ldotadroff);
+ bfd_putl32 (0, eiaf->codeadroff);
+ bfd_putl32 (0, eiaf->lpfixoff);
+ bfd_putl32 (0, eiaf->chgprtoff);
+ bfd_putl32 (shrimg_cnt ? off : 0, eiaf->shlstoff);
+ bfd_putl32 (shrimg_cnt, eiaf->shrimgcnt);
+ bfd_putl32 (0, eiaf->shlextra);
+ bfd_putl32 (0, eiaf->permctx);
+ bfd_putl32 (0, eiaf->base_va);
+ bfd_putl32 (0, eiaf->lppsbfixoff);
+
+ if (shrimg_cnt)
+ {
+ shrimg_cnt = 0;
+
+ /* Write shl. */
+ for (i = 0; i < VEC_COUNT (t->shrlibs); i++)
+ {
+ struct alpha_vms_shlib_el *shlib;
+ struct vms_shl *shl;
+
+ shlib = &VEC_EL (t->shrlibs, struct alpha_vms_shlib_el, i);
+
+ if (!shlib->has_fixups)
+ continue;
+
+ /* Renumber shared images. */
+ PRIV2 (shlib->abfd, shr_index) = shrimg_cnt++;
+
+ shl = (struct vms_shl *)(content + off);
+ bfd_putl32 (0, shl->baseva);
+ bfd_putl32 (0, shl->shlptr);
+ bfd_putl32 (0, shl->ident);
+ bfd_putl32 (0, shl->permctx);
+ shl->size = sizeof (struct vms_shl);
+ bfd_putl16 (0, shl->fill_1);
+ shl->flags = 0;
+ bfd_putl32 (0, shl->icb);
+ shl->imgnam[0] = strlen (PRIV2 (shlib->abfd, hdr_data.hdr_t_name));
+ memcpy (shl->imgnam + 1, PRIV2 (shlib->abfd, hdr_data.hdr_t_name),
+ shl->imgnam[0]);
+
+ off += sizeof (struct vms_shl);
+ }
+
+ /* CA fixups. */
+ if (ca_sz != 0)
+ {
+ bfd_putl32 (off, eiaf->codeadroff);
+
+ for (i = 0; i < VEC_COUNT (t->shrlibs); i++)
+ {
+ struct alpha_vms_shlib_el *shlib;
+ unsigned int j;
+
+ shlib = &VEC_EL (t->shrlibs, struct alpha_vms_shlib_el, i);
+
+ if (VEC_COUNT (shlib->ca) == 0)
+ continue;
+
+ bfd_putl32 (VEC_COUNT (shlib->ca), content + off);
+ bfd_putl32 (PRIV2 (shlib->abfd, shr_index), content + off + 4);
+ off += 8;
+
+ for (j = 0; j < VEC_COUNT (shlib->ca); j++)
+ {
+ bfd_putl32 (VEC_EL (shlib->ca, bfd_vma, j) - t->base_addr,
+ content + off);
+ off += 4;
+ }
+ }
+
+ bfd_putl32 (0, content + off);
+ bfd_putl32 (0, content + off + 4);
+ off += 8;
+ }
+
+ /* LP fixups. */
+ if (lp_sz != 0)
+ {
+ bfd_putl32 (off, eiaf->lpfixoff);
+
+ for (i = 0; i < VEC_COUNT (t->shrlibs); i++)
+ {
+ struct alpha_vms_shlib_el *shlib;
+ unsigned int j;
+
+ shlib = &VEC_EL (t->shrlibs, struct alpha_vms_shlib_el, i);
+
+ if (VEC_COUNT (shlib->lp) == 0)
+ continue;
+
+ bfd_putl32 (VEC_COUNT (shlib->lp), content + off);
+ bfd_putl32 (PRIV2 (shlib->abfd, shr_index), content + off + 4);
+ off += 8;
+
+ for (j = 0; j < VEC_COUNT (shlib->lp); j++)
+ {
+ bfd_putl32 (VEC_EL (shlib->lp, bfd_vma, j) - t->base_addr,
+ content + off);
+ off += 4;
+ }
+ }
+
+ bfd_putl32 (0, content + off);
+ bfd_putl32 (0, content + off + 4);
+ off += 8;
+ }
+
+ /* QR fixups. */
+ if (qr_sz != 0)
+ {
+ bfd_putl32 (off, eiaf->qdotadroff);
+
+ for (i = 0; i < VEC_COUNT (t->shrlibs); i++)
+ {
+ struct alpha_vms_shlib_el *shlib;
+ unsigned int j;
+
+ shlib = &VEC_EL (t->shrlibs, struct alpha_vms_shlib_el, i);
+
+ if (VEC_COUNT (shlib->qr) == 0)
+ continue;
+
+ bfd_putl32 (VEC_COUNT (shlib->qr), content + off);
+ bfd_putl32 (PRIV2 (shlib->abfd, shr_index), content + off + 4);
+ off += 8;
+
+ for (j = 0; j < VEC_COUNT (shlib->qr); j++)
+ {
+ struct alpha_vms_vma_ref *r;
+ r = &VEC_EL (shlib->qr, struct alpha_vms_vma_ref, j);
+ bfd_putl32 (r->vma - t->base_addr, content + off);
+ bfd_putl32 (r->ref, content + off + 4);
+ off += 8;
+ }
+ }
+
+ bfd_putl32 (0, content + off);
+ bfd_putl32 (0, content + off + 4);
+ off += 8;
+ }
+ }
+
+ /* Write the change protection table. */
+ bfd_putl32 (off, eiaf->chgprtoff);
+ bfd_putl32 (chgprt_num, content + off);
+ off += 4;
+
+ for (sec = info->output_bfd->sections; sec != NULL; sec = sec->next)
+ {
+ struct vms_eicp *eicp;
+ unsigned int prot;
+
+ if ((sec->flags & SEC_LINKER_CREATED) != 0 &&
+ strcmp (sec->name, "$FIXUP$") == 0)
+ prot = PRT__C_UREW;
+ else if ((sec->flags & SEC_RELOC) != 0
+ && (sec->flags & (SEC_CODE | SEC_READONLY)) != 0)
+ prot = PRT__C_UR;
+ else
+ continue;
+
+ eicp = (struct vms_eicp *)(content + off);
+ bfd_putl64 (sec->vma - t->base_addr, eicp->baseva);
+ bfd_putl32 ((sec->size + VMS_BLOCK_SIZE - 1) & ~(VMS_BLOCK_SIZE - 1),
+ eicp->size);
+ bfd_putl32 (prot, eicp->newprt);
+ off += sizeof (struct vms_eicp);
+ }
+
+ return TRUE;
+}
+
+/* Called by bfd_hash_traverse to fill the symbol table.
+ Return FALSE in case of failure. */
+
+static bfd_boolean
+alpha_vms_link_output_symbol (struct bfd_hash_entry *bh, void *infov)
+{
+ struct bfd_link_hash_entry *hc = (struct bfd_link_hash_entry *) bh;
+ struct bfd_link_info *info = (struct bfd_link_info *)infov;
+ struct alpha_vms_link_hash_entry *h;
+ struct vms_symbol_entry *sym;
+
+ if (hc->type == bfd_link_hash_warning)
+ {
+ hc = hc->u.i.link;
+ if (hc->type == bfd_link_hash_new)
+ return TRUE;
+ }
+ h = (struct alpha_vms_link_hash_entry *) hc;
+
+ switch (h->root.type)
+ {
+ case bfd_link_hash_undefined:
+ return TRUE;
+ case bfd_link_hash_new:
+ case bfd_link_hash_warning:
+ abort ();
+ case bfd_link_hash_undefweak:
+ return TRUE;
+ case bfd_link_hash_defined:
+ case bfd_link_hash_defweak:
+ {
+ asection *sec = h->root.u.def.section;
+
+ /* FIXME: this is certainly a symbol from a dynamic library. */
+ if (bfd_is_abs_section (sec))
+ return TRUE;
+
+ if (sec->owner->flags & DYNAMIC)
+ return TRUE;
+ }
+ break;
+ case bfd_link_hash_common:
+ break;
+ case bfd_link_hash_indirect:
+ return TRUE;
+ }
+
+ /* Do not write not kept symbols. */
+ if (info->strip == strip_some
+ && bfd_hash_lookup (info->keep_hash, h->root.root.string,
+ FALSE, FALSE) != NULL)
+ return TRUE;
+
+ if (h->sym == NULL)
+ {
+ /* This symbol doesn't come from a VMS object. So we suppose it is
+ a data. */
+ int len = strlen (h->root.root.string);
+
+ sym = (struct vms_symbol_entry *)bfd_zalloc (info->output_bfd,
+ sizeof (*sym) + len);
+ if (sym == NULL)
+ abort ();
+ sym->namelen = len;
+ memcpy (sym->name, h->root.root.string, len);
+ sym->name[len] = 0;
+ sym->owner = info->output_bfd;
+
+ sym->typ = EGSD__C_SYMG;
+ sym->data_type = 0;
+ sym->flags = EGSY__V_DEF | EGSY__V_REL;
+ sym->symbol_vector = h->root.u.def.value;
+ sym->section = h->root.u.def.section;
+ sym->value = h->root.u.def.value;
+ }
+ else
+ sym = h->sym;
+
+ if (!add_symbol_entry (info->output_bfd, sym))
+ return FALSE;
+
+ return TRUE;
+}
+
+static bfd_boolean
+alpha_vms_bfd_final_link (bfd *abfd, struct bfd_link_info *info)
+{
+ asection *o;
+ struct bfd_link_order *p;
+ bfd *sub;
+ asection *fixupsec;
+ bfd_vma base_addr;
+ bfd_vma last_addr;
+ asection *dst;
+ asection *dmt;
+
+ if (info->relocatable)
+ {
+ /* FIXME: we do not yet support relocatable link. It is not obvious
+ how to do it for debug infos. */
+ (*info->callbacks->einfo)(_("%P: relocatable link is not supported\n"));
+ return FALSE;
+ }
+
+ bfd_get_outsymbols (abfd) = NULL;
+ bfd_get_symcount (abfd) = 0;
+
+ /* Mark all sections which will be included in the output file. */
+ for (o = abfd->sections; o != NULL; o = o->next)
+ for (p = o->map_head.link_order; p != NULL; p = p->next)
+ if (p->type == bfd_indirect_link_order)
+ p->u.indirect.section->linker_mark = TRUE;
+
+#if 0
+ /* Handle all the link order information for the sections. */
+ for (o = abfd->sections; o != NULL; o = o->next)
+ {
+ printf ("For section %s (at 0x%08x, flags=0x%08x):\n",
+ o->name, (unsigned)o->vma, (unsigned)o->flags);
+
+ for (p = o->map_head.link_order; p != NULL; p = p->next)
+ {
+ printf (" at 0x%08x - 0x%08x: ",
+ (unsigned)p->offset, (unsigned)(p->offset + p->size - 1));
+ switch (p->type)
+ {
+ case bfd_section_reloc_link_order:
+ case bfd_symbol_reloc_link_order:
+ printf (" section/symbol reloc\n");
+ break;
+ case bfd_indirect_link_order:
+ printf (" section %s of %s\n",
+ p->u.indirect.section->name,
+ p->u.indirect.section->owner->filename);
+ break;
+ case bfd_data_link_order:
+ printf (" explicit data\n");
+ break;
+ default:
+ printf (" *unknown* type %u\n", p->type);
+ break;
+ }
+ }
+ }
+#endif
+
+ /* Generate the symbol table. */
+ BFD_ASSERT (PRIV (syms) == NULL);
+ if (info->strip != strip_all)
+ bfd_hash_traverse (&info->hash->table, alpha_vms_link_output_symbol, info);
+
+ /* Find the entry point. */
+ if (bfd_get_start_address (abfd) == 0)
+ {
+ bfd *startbfd = NULL;
+
+ for (sub = info->input_bfds; sub != NULL; sub = sub->link.next)
+ {
+ /* Consider only VMS object files. */
+ if (sub->xvec != abfd->xvec)
+ continue;
+
+ if (!PRIV2 (sub, eom_data).eom_has_transfer)
+ continue;
+ if ((PRIV2 (sub, eom_data).eom_b_tfrflg & EEOM__M_WKTFR) && startbfd)
+ continue;
+ if (startbfd != NULL
+ && !(PRIV2 (sub, eom_data).eom_b_tfrflg & EEOM__M_WKTFR))
+ {
+ (*info->callbacks->einfo)
+ (_("%P: multiple entry points: in modules %B and %B\n"),
+ startbfd, sub);
+ continue;
+ }
+ startbfd = sub;
+ }
+
+ if (startbfd)
+ {
+ unsigned int ps_idx = PRIV2 (startbfd, eom_data).eom_l_psindx;
+ bfd_vma tfradr = PRIV2 (startbfd, eom_data).eom_l_tfradr;
+ asection *sec;
+
+ sec = PRIV2 (startbfd, sections)[ps_idx];
+
+ bfd_set_start_address
+ (abfd, sec->output_section->vma + sec->output_offset + tfradr);
+ }
+ }
+
+ /* Set transfer addresses. */
+ {
+ int i;
+ struct bfd_link_hash_entry *h;
+
+ i = 0;
+ PRIV (transfer_address[i++]) = 0xffffffff00000340ULL; /* SYS$IMGACT */
+ h = bfd_link_hash_lookup (info->hash, "LIB$INITIALIZE", FALSE, FALSE, TRUE);
+ if (h != NULL && h->type == bfd_link_hash_defined)
+ PRIV (transfer_address[i++]) =
+ alpha_vms_get_sym_value (h->u.def.section, h->u.def.value);
+ PRIV (transfer_address[i++]) = bfd_get_start_address (abfd);
+ while (i < 4)
+ PRIV (transfer_address[i++]) = 0;
+ }
+
+ /* Allocate contents.
+ Also compute the virtual base address. */
+ base_addr = (bfd_vma)-1;
+ last_addr = 0;
+ for (o = abfd->sections; o != NULL; o = o->next)
+ {
+ if (o->flags & SEC_HAS_CONTENTS)
+ {
+ o->contents = bfd_alloc (abfd, o->size);
+ if (o->contents == NULL)
+ return FALSE;
+ }
+ if (o->flags & SEC_LOAD)
+ {
+ if (o->vma < base_addr)
+ base_addr = o->vma;
+ if (o->vma + o->size > last_addr)
+ last_addr = o->vma + o->size;
+ }
+ /* Clear the RELOC flags. Currently we don't support incremental
+ linking. We use the RELOC flag for computing the eicp entries. */
+ o->flags &= ~SEC_RELOC;
+ }
+
+ /* Create the fixup section. */
+ fixupsec = bfd_make_section_anyway_with_flags
+ (info->output_bfd, "$FIXUP$",
+ SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_LINKER_CREATED);
+ if (fixupsec == NULL)
+ return FALSE;
+ last_addr = (last_addr + 0xffff) & ~0xffff;
+ fixupsec->vma = last_addr;
+
+ alpha_vms_link_hash (info)->fixup = fixupsec;
+ alpha_vms_link_hash (info)->base_addr = base_addr;
+
+ /* Create the DMT section, if necessary. */
+ BFD_ASSERT (PRIV (dst_section) == NULL);
+ dst = bfd_get_section_by_name (abfd, "$DST$");
+ if (dst != NULL && dst->size == 0)
+ dst = NULL;
+ if (dst != NULL)
+ {
+ PRIV (dst_section) = dst;
+ dmt = bfd_make_section_anyway_with_flags
+ (info->output_bfd, "$DMT$",
+ SEC_DEBUGGING | SEC_HAS_CONTENTS | SEC_LINKER_CREATED);
+ if (dmt == NULL)
+ return FALSE;
+ }
+ else
+ dmt = NULL;
+
+ /* Read all sections from the inputs. */
+ for (sub = info->input_bfds; sub != NULL; sub = sub->link.next)
+ {
+ if (sub->flags & DYNAMIC)
+ {
+ alpha_vms_create_eisd_for_shared (abfd, sub);
+ continue;
+ }
+
+ if (!alpha_vms_read_sections_content (sub, info))
+ return FALSE;
+ }
+
+ /* Handle all the link order information for the sections.
+ Note: past this point, it is not possible to create new sections. */
+ for (o = abfd->sections; o != NULL; o = o->next)
+ {
+ for (p = o->map_head.link_order; p != NULL; p = p->next)
+ {
+ switch (p->type)
+ {
+ case bfd_section_reloc_link_order:
+ case bfd_symbol_reloc_link_order:
+ abort ();
+ return FALSE;
+ case bfd_indirect_link_order:
+ /* Already done. */
+ break;
+ default:
+ if (! _bfd_default_link_order (abfd, info, o, p))
+ return FALSE;
+ break;
+ }
+ }
+ }
+
+ /* Compute fixups. */
+ if (!alpha_vms_build_fixups (info))
+ return FALSE;
+
+ /* Compute the DMT. */
+ if (dmt != NULL)
+ {
+ int pass;
+ unsigned char *contents = NULL;
+
+ /* In pass 1, compute the size. In pass 2, write the DMT contents. */
+ for (pass = 0; pass < 2; pass++)
+ {
+ unsigned int off = 0;
+
+ /* For each object file (ie for each module). */
+ for (sub = info->input_bfds; sub != NULL; sub = sub->link.next)
+ {
+ asection *sub_dst;
+ struct vms_dmt_header *dmth = NULL;
+ unsigned int psect_count;
+
+ /* Skip this module if it has no DST. */
+ sub_dst = PRIV2 (sub, dst_section);
+ if (sub_dst == NULL || sub_dst->size == 0)
+ continue;
+
+ if (pass == 1)
+ {
+ /* Write the header. */
+ dmth = (struct vms_dmt_header *)(contents + off);
+ bfd_putl32 (sub_dst->output_offset, dmth->modbeg);
+ bfd_putl32 (sub_dst->size, dmth->size);
+ }
+
+ off += sizeof (struct vms_dmt_header);
+ psect_count = 0;
+
+ /* For each section (ie for each psect). */
+ for (o = sub->sections; o != NULL; o = o->next)
+ {
+ /* Only consider interesting sections. */
+ if (!(o->flags & SEC_ALLOC))
+ continue;
+ if (o->flags & SEC_LINKER_CREATED)
+ continue;
+
+ if (pass == 1)
+ {
+ /* Write an entry. */
+ struct vms_dmt_psect *dmtp;
+
+ dmtp = (struct vms_dmt_psect *)(contents + off);
+ bfd_putl32 (o->output_offset + o->output_section->vma,
+ dmtp->start);
+ bfd_putl32 (o->size, dmtp->length);
+ psect_count++;
+ }
+ off += sizeof (struct vms_dmt_psect);
+ }
+ if (pass == 1)
+ bfd_putl32 (psect_count, dmth->psect_count);
+ }
+
+ if (pass == 0)
+ {
+ contents = bfd_zalloc (info->output_bfd, off);
+ if (contents == NULL)
+ return FALSE;
+ dmt->contents = contents;
+ dmt->size = off;
+ }
+ else
+ {
+ BFD_ASSERT (off == dmt->size);
+ }
+ }
+ }
+
+ 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 bfd_boolean
+alpha_vms_get_section_contents (bfd *abfd, asection *section,
+ void *buf, file_ptr offset,
+ bfd_size_type count)
+{
+ asection *sec;
+
+ /* Image are easy. */
+ if (bfd_get_file_flags (abfd) & (EXEC_P | DYNAMIC))
+ return _bfd_generic_get_section_contents (abfd, section,
+ buf, offset, count);
+
+ /* Safety check. */
+ if (offset + count < count
+ || offset + count > section->size)
+ {
+ bfd_set_error (bfd_error_invalid_operation);
+ return FALSE;
+ }
+
+ /* If the section is already in memory, just copy it. */
+ if (section->flags & SEC_IN_MEMORY)
+ {
+ BFD_ASSERT (section->contents != NULL);
+ memcpy (buf, section->contents + offset, count);
+ return TRUE;
+ }
+ if (section->size == 0)
+ return TRUE;
+
+ /* Alloc in memory and read ETIRs. */
+ for (sec = abfd->sections; sec; sec = sec->next)
+ {
+ BFD_ASSERT (sec->contents == NULL);
+
+ if (sec->size != 0 && (sec->flags & SEC_HAS_CONTENTS))
+ {
+ sec->contents = bfd_alloc (abfd, sec->size);
+ if (sec->contents == NULL)
+ return FALSE;
+ }
+ }
+ if (!alpha_vms_read_sections_content (abfd, NULL))
+ return FALSE;
+ for (sec = abfd->sections; sec; sec = sec->next)
+ if (sec->contents)
+ sec->flags |= SEC_IN_MEMORY;
+ memcpy (buf, section->contents + offset, count);
+ return TRUE;
+}
+
+
+/* Set the format of a file being written. */
+
+static bfd_boolean
+alpha_vms_mkobject (bfd * abfd)
+{
+ const bfd_arch_info_type *arch;
+
+ vms_debug2 ((1, "alpha_vms_mkobject (%p)\n", abfd));
+
+ if (!vms_initialize (abfd))
+ return FALSE;
+
+ PRIV (recwr.buf) = bfd_alloc (abfd, MAX_OUTREC_SIZE);
+ if (PRIV (recwr.buf) == NULL)
+ return FALSE;
+
+ arch = bfd_scan_arch ("alpha");
+
+ if (arch == 0)
+ {
+ bfd_set_error (bfd_error_wrong_format);
+ return FALSE;
+ }
+
+ abfd->arch_info = arch;
+ return TRUE;
+}
+
+
+/* 4.1, generic. */
+
+/* Called when the BFD is being closed to do any necessary cleanup. */
+
+static bfd_boolean
+vms_close_and_cleanup (bfd * abfd)
+{
+ vms_debug2 ((1, "vms_close_and_cleanup (%p)\n", abfd));
+
+ if (abfd == NULL || abfd->tdata.any == NULL)
+ return TRUE;
+
+ if (abfd->format == bfd_archive)
+ {
+ bfd_release (abfd, abfd->tdata.any);
+ abfd->tdata.any = NULL;
+ return TRUE;
+ }
+
+ if (PRIV (recrd.buf) != NULL)
+ free (PRIV (recrd.buf));
+
+ if (PRIV (sections) != NULL)
+ free (PRIV (sections));
+
+ bfd_release (abfd, abfd->tdata.any);
+ abfd->tdata.any = NULL;
+
+#ifdef VMS
+ if (abfd->direction == write_direction)
+ {
+ /* Last step on VMS is to convert the file to variable record length
+ format. */
+ if (bfd_cache_close (abfd) != TRUE)
+ return FALSE;
+ if (_bfd_vms_convert_to_var_unix_filename (abfd->filename) != TRUE)
+ return FALSE;
+ }
+#endif
+
+ return TRUE;
+}
+
+/* Called when a new section is created. */
+
+static bfd_boolean
+vms_new_section_hook (bfd * abfd, asection *section)
+{
+ bfd_size_type amt;
+
+ vms_debug2 ((1, "vms_new_section_hook (%p, [%d]%s)\n",
+ abfd, section->index, section->name));
+
+ if (! bfd_set_section_alignment (abfd, section, 0))
+ return FALSE;
+
+ vms_debug2 ((7, "%d: %s\n", section->index, section->name));
+
+ amt = sizeof (struct vms_section_data_struct);
+ section->used_by_bfd = bfd_zalloc (abfd, amt);
+ if (section->used_by_bfd == NULL)
+ return FALSE;
+
+ /* Create the section symbol. */
+ return _bfd_generic_new_section_hook (abfd, section);
+}
+
+/* Part 4.5, symbols. */
+
+/* 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 (bfd * abfd,
+ void * file,
+ asymbol *symbol,
+ bfd_print_symbol_type how)
+{
+ vms_debug2 ((1, "vms_print_symbol (%p, %p, %p, %d)\n",
+ abfd, file, symbol, how));
+
+ switch (how)
+ {
+ case bfd_print_symbol_name:
+ case bfd_print_symbol_more:
+ fprintf ((FILE *)file," %s", symbol->name);
+ break;
+
+ case bfd_print_symbol_all:
+ {
+ const char *section_name = symbol->section->name;
+
+ bfd_print_symbol_vandf (abfd, file, symbol);
+
+ fprintf ((FILE *) file," %-8s %s", section_name, symbol->name);
+ }
+ break;
+ }
+}
+
+/* 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 (bfd * abfd ATTRIBUTE_UNUSED,
+ asymbol *symbol,
+ symbol_info *ret)
+{
+ asection *sec;
+
+ vms_debug2 ((1, "vms_get_symbol_info (%p, %p, %p)\n", abfd, symbol, ret));
+
+ sec = symbol->section;
+
+ if (ret == NULL)
+ return;
+
+ if (sec == NULL)
+ ret->type = 'U';
+ else 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 ((symbol->flags & BSF_FUNCTION)
+ || (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 TRUE if the given symbol sym in the BFD abfd is
+ a compiler generated local label, else return FALSE. */
+
+static bfd_boolean
+vms_bfd_is_local_label_name (bfd * abfd ATTRIBUTE_UNUSED,
+ const char *name)
+{
+ return name[0] == '$';
+}
+
+/* Part 4.7, writing an object file. */
+
+/* Sets the contents of the section section in BFD abfd to the data starting
+ in memory at LOCATION. 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 bfd_boolean
+_bfd_vms_set_section_contents (bfd * abfd,
+ asection *section,
+ const void * location,
+ file_ptr offset,
+ bfd_size_type count)
+{
+ if (section->contents == NULL)
+ {
+ section->contents = bfd_alloc (abfd, section->size);
+ if (section->contents == NULL)
+ return FALSE;
+
+ memcpy (section->contents + offset, location, (size_t) count);
+ }
+
+ return TRUE;
+}
+
+/* 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 bfd_boolean
+alpha_vms_set_arch_mach (bfd *abfd,
+ enum bfd_architecture arch, unsigned long mach)
+{
+ if (arch != bfd_arch_alpha
+ && arch != bfd_arch_unknown)
+ return FALSE;
+
+ return bfd_default_set_arch_mach (abfd, arch, mach);
+}
+
+/* Set section VMS flags. Clear NO_FLAGS and set FLAGS. */
+
+void
+bfd_vms_set_section_flags (bfd *abfd ATTRIBUTE_UNUSED,
+ asection *sec, flagword no_flags, flagword flags)
+{
+ vms_section_data (sec)->no_flags = no_flags;
+ vms_section_data (sec)->flags = flags;
+}
+
+struct vms_private_data_struct *
+bfd_vms_get_data (bfd *abfd)
+{
+ return (struct vms_private_data_struct *)abfd->tdata.any;
+}
+
+#define vms_bfd_is_target_special_symbol ((bfd_boolean (*) (bfd *, asymbol *)) bfd_false)
+#define vms_bfd_link_just_syms _bfd_generic_link_just_syms
+#define vms_bfd_copy_link_hash_symbol_type \
+ _bfd_generic_copy_link_hash_symbol_type
+#define vms_bfd_is_group_section bfd_generic_is_group_section
+#define vms_bfd_discard_group bfd_generic_discard_group
+#define vms_section_already_linked _bfd_generic_section_already_linked
+#define vms_bfd_define_common_symbol bfd_generic_define_common_symbol
+#define vms_bfd_copy_private_header_data _bfd_generic_bfd_copy_private_header_data
+
+#define vms_bfd_copy_private_bfd_data _bfd_generic_bfd_copy_private_bfd_data
+#define vms_bfd_free_cached_info _bfd_generic_bfd_free_cached_info
+#define vms_bfd_copy_private_section_data _bfd_generic_bfd_copy_private_section_data
+#define vms_bfd_copy_private_symbol_data _bfd_generic_bfd_copy_private_symbol_data
+#define vms_bfd_set_private_flags _bfd_generic_bfd_set_private_flags
+#define vms_bfd_merge_private_bfd_data _bfd_generic_bfd_merge_private_bfd_data
+
+/* Symbols table. */
+#define alpha_vms_make_empty_symbol _bfd_generic_make_empty_symbol
+#define alpha_vms_bfd_is_target_special_symbol \
+ ((bfd_boolean (*) (bfd *, asymbol *)) bfd_false)
+#define alpha_vms_print_symbol vms_print_symbol
+#define alpha_vms_get_symbol_info vms_get_symbol_info
+#define alpha_vms_read_minisymbols _bfd_generic_read_minisymbols
+#define alpha_vms_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol
+#define alpha_vms_get_lineno _bfd_nosymbols_get_lineno
+#define alpha_vms_find_inliner_info _bfd_nosymbols_find_inliner_info
+#define alpha_vms_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol
+#define alpha_vms_find_nearest_line _bfd_vms_find_nearest_line
+#define alpha_vms_find_line _bfd_nosymbols_find_line
+#define alpha_vms_bfd_is_local_label_name vms_bfd_is_local_label_name
+
+/* Generic table. */
+#define alpha_vms_close_and_cleanup vms_close_and_cleanup
+#define alpha_vms_bfd_free_cached_info vms_bfd_free_cached_info
+#define alpha_vms_new_section_hook vms_new_section_hook
+#define alpha_vms_set_section_contents _bfd_vms_set_section_contents
+#define alpha_vms_get_section_contents_in_window _bfd_generic_get_section_contents_in_window
+
+#define alpha_vms_bfd_get_relocated_section_contents \
+ bfd_generic_get_relocated_section_contents
+
+#define alpha_vms_bfd_relax_section bfd_generic_relax_section
+#define alpha_vms_bfd_gc_sections bfd_generic_gc_sections
+#define alpha_vms_bfd_lookup_section_flags bfd_generic_lookup_section_flags
+#define alpha_vms_bfd_merge_sections bfd_generic_merge_sections
+#define alpha_vms_bfd_is_group_section bfd_generic_is_group_section
+#define alpha_vms_bfd_discard_group bfd_generic_discard_group
+#define alpha_vms_section_already_linked \
+ _bfd_generic_section_already_linked
+
+#define alpha_vms_bfd_define_common_symbol bfd_generic_define_common_symbol
+#define alpha_vms_bfd_link_just_syms _bfd_generic_link_just_syms
+#define alpha_vms_bfd_copy_link_hash_symbol_type \
+ _bfd_generic_copy_link_hash_symbol_type
+
+#define alpha_vms_bfd_link_split_section _bfd_generic_link_split_section
+
+#define alpha_vms_get_dynamic_symtab_upper_bound \
+ _bfd_nodynamic_get_dynamic_symtab_upper_bound
+#define alpha_vms_canonicalize_dynamic_symtab \
+ _bfd_nodynamic_canonicalize_dynamic_symtab
+#define alpha_vms_get_dynamic_reloc_upper_bound \
+ _bfd_nodynamic_get_dynamic_reloc_upper_bound
+#define alpha_vms_canonicalize_dynamic_reloc \
+ _bfd_nodynamic_canonicalize_dynamic_reloc
+
+const bfd_target alpha_vms_vec =
+{
+ "vms-alpha", /* Name. */
+ bfd_target_evax_flavour,
+ BFD_ENDIAN_LITTLE, /* Data byte order is little. */
+ BFD_ENDIAN_LITTLE, /* Header byte order is little. */
+
+ (HAS_RELOC | EXEC_P | HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS
+ | 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. */
+ 0, /* match priority. */
+ 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, alpha_vms_object_p, /* bfd_check_format. */
+ _bfd_vms_lib_alpha_archive_p, _bfd_dummy_target},
+ {bfd_false, alpha_vms_mkobject, /* bfd_set_format. */
+ _bfd_vms_lib_alpha_mkarchive, bfd_false},
+ {bfd_false, alpha_vms_write_object_contents, /* bfd_write_contents. */
+ _bfd_vms_lib_write_archive_contents, bfd_false},
+
+ BFD_JUMP_TABLE_GENERIC (alpha_vms),
+ BFD_JUMP_TABLE_COPY (vms),
+ BFD_JUMP_TABLE_CORE (_bfd_nocore),
+ BFD_JUMP_TABLE_ARCHIVE (_bfd_vms_lib),
+ BFD_JUMP_TABLE_SYMBOLS (alpha_vms),
+ BFD_JUMP_TABLE_RELOCS (alpha_vms),
+ BFD_JUMP_TABLE_WRITE (alpha_vms),
+ BFD_JUMP_TABLE_LINK (alpha_vms),
+ BFD_JUMP_TABLE_DYNAMIC (alpha_vms),
+
+ NULL,
+
+ NULL
+};
diff --git a/bfd/vms-lib.c b/bfd/vms-lib.c
new file mode 100644
index 0000000..dbacc33
--- /dev/null
+++ b/bfd/vms-lib.c
@@ -0,0 +1,2351 @@
+/* BFD back-end for VMS archive files.
+
+ Copyright (C) 2010-2014 Free Software Foundation, Inc.
+ Written by Tristan Gingold <gingold@adacore.com>, AdaCore.
+
+ This file is part of BFD, the Binary File Descriptor library.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+#include "safe-ctype.h"
+#include "bfdver.h"
+#include "libiberty.h"
+#include "vms.h"
+#include "vms/lbr.h"
+#include "vms/dcx.h"
+
+/* The standard VMS disk block size. */
+#ifndef VMS_BLOCK_SIZE
+#define VMS_BLOCK_SIZE 512
+#endif
+
+/* Maximum key length (which is also the maximum symbol length in archive). */
+#define MAX_KEYLEN 128
+#define MAX_EKEYLEN 1024
+
+/* DCX Submaps. */
+
+struct dcxsbm_desc
+{
+ unsigned char min_char;
+ unsigned char max_char;
+ unsigned char *flags;
+ unsigned char *nodes;
+ unsigned short *next;
+};
+
+/* Kind of library. Used to filter in archive_p. */
+
+enum vms_lib_kind
+ {
+ vms_lib_vax,
+ vms_lib_alpha,
+ vms_lib_ia64,
+ vms_lib_txt
+ };
+
+/* Back-end private data. */
+
+struct lib_tdata
+{
+ /* Standard tdata for an archive. But we don't use many fields. */
+ struct artdata artdata;
+
+ /* Major version. */
+ unsigned char ver;
+
+ /* Type of the archive. */
+ unsigned char type;
+
+ /* Kind of archive. Summary of its type. */
+ enum vms_lib_kind kind;
+
+ /* Total size of the mhd (element header). */
+ unsigned int mhd_size;
+
+ /* Creation date. */
+ unsigned int credat_lo;
+ unsigned int credat_hi;
+
+ /* Vector of modules (archive elements), already sorted. */
+ unsigned int nbr_modules;
+ struct carsym *modules;
+ bfd **cache;
+
+ /* DCX (decompression) data. */
+ unsigned int nbr_dcxsbm;
+ struct dcxsbm_desc *dcxsbm;
+};
+
+#define bfd_libdata(bfd) ((struct lib_tdata *)((bfd)->tdata.any))
+
+/* End-Of-Text pattern. This is a special record to mark the end of file. */
+
+static const unsigned char eotdesc[] = { 0x03, 0x00, 0x77, 0x00, 0x77, 0x00 };
+
+/* Describe the current state of carsym entries while building the archive
+ table of content. Things are simple with Alpha archives as the number
+ of entries is known, but with IA64 archives a entry can make a reference
+ to severals members. Therefore we must be able to extend the table on the
+ fly, but it should be allocated on the bfd - which doesn't support realloc.
+ To reduce the overhead, the table is initially allocated in the BFD's
+ objalloc and extended if necessary on the heap. In the later case, it
+ is finally copied to the BFD's objalloc so that it will automatically be
+ freed. */
+
+struct carsym_mem
+{
+ /* The table of content. */
+ struct carsym *idx;
+
+ /* Number of entries used in the table. */
+ unsigned int nbr;
+
+ /* Maximum number of entries. */
+ unsigned int max;
+
+ /* If true, the table was reallocated on the heap. If false, it is still
+ in the BFD's objalloc. */
+ bfd_boolean realloced;
+};
+
+/* Simply add a name to the index. */
+
+static bfd_boolean
+vms_add_index (struct carsym_mem *cs, char *name,
+ unsigned int idx_vbn, unsigned int idx_off)
+{
+ if (cs->nbr == cs->max)
+ {
+ struct carsym *n;
+
+ cs->max = 2 * cs->max + 32;
+
+ if (!cs->realloced)
+ {
+ n = bfd_malloc2 (cs->max, sizeof (struct carsym));
+ if (n == NULL)
+ return FALSE;
+ memcpy (n, cs->idx, cs->nbr * sizeof (struct carsym));
+ /* And unfortunately we can't free cs->idx. */
+ }
+ else
+ {
+ n = bfd_realloc_or_free (cs->idx, cs->nbr * sizeof (struct carsym));
+ if (n == NULL)
+ return FALSE;
+ }
+ cs->idx = n;
+ cs->realloced = TRUE;
+ }
+ cs->idx[cs->nbr].file_offset = (idx_vbn - 1) * VMS_BLOCK_SIZE + idx_off;
+ cs->idx[cs->nbr].name = name;
+ cs->nbr++;
+ return TRUE;
+}
+
+/* Follow all member of a lns list (pointed by RFA) and add indexes for
+ NAME. Return FALSE in case of error. */
+
+static bfd_boolean
+vms_add_indexes_from_list (bfd *abfd, struct carsym_mem *cs, char *name,
+ struct vms_rfa *rfa)
+{
+ struct vms_lns lns;
+ unsigned int vbn;
+ file_ptr off;
+
+ while (1)
+ {
+ vbn = bfd_getl32 (rfa->vbn);
+ if (vbn == 0)
+ return TRUE;
+
+ /* Read the LHS. */
+ off = (vbn - 1) * VMS_BLOCK_SIZE + bfd_getl16 (rfa->offset);
+ if (bfd_seek (abfd, off, SEEK_SET) != 0
+ || bfd_bread (&lns, sizeof (lns), abfd) != sizeof (lns))
+ return FALSE;
+
+ if (!vms_add_index (cs, name,
+ bfd_getl32 (lns.modrfa.vbn),
+ bfd_getl16 (lns.modrfa.offset)))
+ return FALSE;
+
+ rfa = &lns.nxtrfa;
+ }
+}
+
+/* Read block VBN from ABFD and store it into BLK. Return FALSE in case of error. */
+
+static bfd_boolean
+vms_read_block (bfd *abfd, unsigned int vbn, void *blk)
+{
+ file_ptr off;
+
+ off = (vbn - 1) * VMS_BLOCK_SIZE;
+ if (bfd_seek (abfd, off, SEEK_SET) != 0
+ || bfd_bread (blk, VMS_BLOCK_SIZE, abfd) != VMS_BLOCK_SIZE)
+ return FALSE;
+
+ return TRUE;
+}
+
+/* Write the content of BLK to block VBN of ABFD. Return FALSE in case of error. */
+
+static bfd_boolean
+vms_write_block (bfd *abfd, unsigned int vbn, void *blk)
+{
+ file_ptr off;
+
+ off = (vbn - 1) * VMS_BLOCK_SIZE;
+ if (bfd_seek (abfd, off, SEEK_SET) != 0
+ || bfd_bwrite (blk, VMS_BLOCK_SIZE, abfd) != VMS_BLOCK_SIZE)
+ return FALSE;
+
+ return TRUE;
+}
+
+/* Read index block VBN and put the entry in **IDX (which is updated).
+ If the entry is indirect, recurse. */
+
+static bfd_boolean
+vms_traverse_index (bfd *abfd, unsigned int vbn, struct carsym_mem *cs)
+{
+ struct vms_indexdef indexdef;
+ file_ptr off;
+ unsigned char *p;
+ unsigned char *endp;
+
+ /* Read the index block. */
+ BFD_ASSERT (sizeof (indexdef) == VMS_BLOCK_SIZE);
+ if (!vms_read_block (abfd, vbn, &indexdef))
+ return FALSE;
+
+ /* Traverse it. */
+ p = &indexdef.keys[0];
+ endp = p + bfd_getl16 (indexdef.used);
+ while (p < endp)
+ {
+ unsigned int idx_vbn;
+ unsigned int idx_off;
+ unsigned int keylen;
+ unsigned char *keyname;
+ unsigned int flags;
+
+ /* Extract key length. */
+ if (bfd_libdata (abfd)->ver == LBR_MAJORID)
+ {
+ struct vms_idx *ridx = (struct vms_idx *)p;
+
+ idx_vbn = bfd_getl32 (ridx->rfa.vbn);
+ idx_off = bfd_getl16 (ridx->rfa.offset);
+
+ keylen = ridx->keylen;
+ flags = 0;
+ keyname = ridx->keyname;
+ }
+ else if (bfd_libdata (abfd)->ver == LBR_ELFMAJORID)
+ {
+ struct vms_elfidx *ridx = (struct vms_elfidx *)p;
+
+ idx_vbn = bfd_getl32 (ridx->rfa.vbn);
+ idx_off = bfd_getl16 (ridx->rfa.offset);
+
+ keylen = bfd_getl16 (ridx->keylen);
+ flags = ridx->flags;
+ keyname = ridx->keyname;
+ }
+ else
+ return FALSE;
+
+ /* Illegal value. */
+ if (idx_vbn == 0)
+ return FALSE;
+
+ /* Point to the next index entry. */
+ p = keyname + keylen;
+
+ if (idx_off == RFADEF__C_INDEX)
+ {
+ /* Indirect entry. Recurse. */
+ if (!vms_traverse_index (abfd, idx_vbn, cs))
+ return FALSE;
+ }
+ else
+ {
+ /* Add a new entry. */
+ char *name;
+
+ if (flags & ELFIDX__SYMESC)
+ {
+ /* Extended key name. */
+ unsigned int noff = 0;
+ unsigned int koff;
+ unsigned int kvbn;
+ struct vms_kbn *kbn;
+ unsigned char kblk[VMS_BLOCK_SIZE];
+
+ /* Sanity check. */
+ if (keylen != sizeof (struct vms_kbn))
+ return FALSE;
+
+ kbn = (struct vms_kbn *)keyname;
+ keylen = bfd_getl16 (kbn->keylen);
+
+ name = bfd_alloc (abfd, keylen + 1);
+ if (name == NULL)
+ return FALSE;
+ kvbn = bfd_getl32 (kbn->rfa.vbn);
+ koff = bfd_getl16 (kbn->rfa.offset);
+
+ /* Read the key, chunk by chunk. */
+ do
+ {
+ unsigned int klen;
+
+ if (!vms_read_block (abfd, kvbn, kblk))
+ return FALSE;
+ kbn = (struct vms_kbn *)(kblk + koff);
+ klen = bfd_getl16 (kbn->keylen);
+ kvbn = bfd_getl32 (kbn->rfa.vbn);
+ koff = bfd_getl16 (kbn->rfa.offset);
+
+ memcpy (name + noff, kbn + 1, klen);
+ noff += klen;
+ }
+ while (kvbn != 0);
+
+ /* Sanity check. */
+ if (noff != keylen)
+ return FALSE;
+ }
+ else
+ {
+ /* Usual key name. */
+ name = bfd_alloc (abfd, keylen + 1);
+ if (name == NULL)
+ return FALSE;
+
+ memcpy (name, keyname, keylen);
+ }
+ name[keylen] = 0;
+
+ if (flags & ELFIDX__LISTRFA)
+ {
+ struct vms_lhs lhs;
+
+ /* Read the LHS. */
+ off = (idx_vbn - 1) * VMS_BLOCK_SIZE + idx_off;
+ if (bfd_seek (abfd, off, SEEK_SET) != 0
+ || bfd_bread (&lhs, sizeof (lhs), abfd) != sizeof (lhs))
+ return FALSE;
+
+ /* FIXME: this adds extra entries that were not accounted. */
+ if (!vms_add_indexes_from_list (abfd, cs, name, &lhs.ng_g_rfa))
+ return FALSE;
+ if (!vms_add_indexes_from_list (abfd, cs, name, &lhs.ng_wk_rfa))
+ return FALSE;
+ if (!vms_add_indexes_from_list (abfd, cs, name, &lhs.g_g_rfa))
+ return FALSE;
+ if (!vms_add_indexes_from_list (abfd, cs, name, &lhs.g_wk_rfa))
+ return FALSE;
+ }
+ else
+ {
+ if (!vms_add_index (cs, name, idx_vbn, idx_off))
+ return FALSE;
+ }
+ }
+ }
+
+ return TRUE;
+}
+
+/* Read index #IDX, which must have NBREL entries. */
+
+static struct carsym *
+vms_lib_read_index (bfd *abfd, int idx, unsigned int *nbrel)
+{
+ struct vms_idd idd;
+ unsigned int flags;
+ unsigned int vbn;
+ struct carsym *csbuf;
+ struct carsym_mem csm;
+
+ /* Read index desription. */
+ if (bfd_seek (abfd, LHD_IDXDESC + idx * IDD_LENGTH, SEEK_SET) != 0
+ || bfd_bread (&idd, sizeof (idd), abfd) != sizeof (idd))
+ return NULL;
+
+ /* Sanity checks. */
+ flags = bfd_getl16 (idd.flags);
+ if (!(flags & IDD__FLAGS_ASCII)
+ || !(flags & IDD__FLAGS_VARLENIDX))
+ return NULL;
+
+ csbuf = bfd_alloc (abfd, *nbrel * sizeof (struct carsym));
+ if (csbuf == NULL)
+ return NULL;
+
+ csm.max = *nbrel;
+ csm.nbr = 0;
+ csm.realloced = FALSE;
+ csm.idx = csbuf;
+
+ /* Note: if the index is empty, there is no block to traverse. */
+ vbn = bfd_getl32 (idd.vbn);
+ if (vbn != 0 && !vms_traverse_index (abfd, vbn, &csm))
+ {
+ if (csm.realloced && csm.idx != NULL)
+ free (csm.idx);
+
+ /* Note: in case of error, we can free what was allocated on the
+ BFD's objalloc. */
+ bfd_release (abfd, csbuf);
+ return NULL;
+ }
+
+ if (csm.realloced)
+ {
+ /* There are more entries than the first estimate. Allocate on
+ the BFD's objalloc. */
+ csbuf = bfd_alloc (abfd, csm.nbr * sizeof (struct carsym));
+ if (csbuf == NULL)
+ return NULL;
+ memcpy (csbuf, csm.idx, csm.nbr * sizeof (struct carsym));
+ free (csm.idx);
+ *nbrel = csm.nbr;
+ }
+ return csbuf;
+}
+
+/* Standard function. */
+
+static const bfd_target *
+_bfd_vms_lib_archive_p (bfd *abfd, enum vms_lib_kind kind)
+{
+ struct vms_lhd lhd;
+ unsigned int sanity;
+ unsigned int majorid;
+ struct lib_tdata *tdata_hold;
+ struct lib_tdata *tdata;
+ unsigned int dcxvbn;
+ unsigned int nbr_ent;
+
+ /* Read header. */
+ if (bfd_bread (&lhd, sizeof (lhd), abfd) != sizeof (lhd))
+ {
+ if (bfd_get_error () != bfd_error_system_call)
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+
+ /* Check sanity (= magic) number. */
+ sanity = bfd_getl32 (lhd.sanity);
+ if (!(sanity == LHD_SANEID3
+ || sanity == LHD_SANEID6
+ || sanity == LHD_SANEID_DCX))
+ {
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+ majorid = bfd_getl32 (lhd.majorid);
+
+ /* Check archive kind. */
+ switch (kind)
+ {
+ case vms_lib_alpha:
+ if ((lhd.type != LBR__C_TYP_EOBJ && lhd.type != LBR__C_TYP_ESHSTB)
+ || majorid != LBR_MAJORID
+ || lhd.nindex != 2)
+ {
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+ break;
+ case vms_lib_ia64:
+ if ((lhd.type != LBR__C_TYP_IOBJ && lhd.type != LBR__C_TYP_ISHSTB)
+ || majorid != LBR_ELFMAJORID
+ || lhd.nindex != 2)
+ {
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+ break;
+ case vms_lib_txt:
+ if ((lhd.type != LBR__C_TYP_TXT
+ && lhd.type != LBR__C_TYP_MLB
+ && lhd.type != LBR__C_TYP_HLP)
+ || majorid != LBR_MAJORID
+ || lhd.nindex != 1)
+ {
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
+ break;
+ default:
+ abort ();
+ }
+
+ /* Allocate and initialize private data. */
+ tdata_hold = bfd_libdata (abfd);
+ tdata = (struct lib_tdata *) bfd_zalloc (abfd, sizeof (struct lib_tdata));
+ if (tdata == NULL)
+ return NULL;
+ abfd->tdata.any = (void *)tdata;
+ tdata->ver = majorid;
+ tdata->mhd_size = MHD__C_USRDAT + lhd.mhdusz;
+ tdata->type = lhd.type;
+ tdata->kind = kind;
+ tdata->credat_lo = bfd_getl32 (lhd.credat + 0);
+ tdata->credat_hi = bfd_getl32 (lhd.credat + 4);
+
+ /* Read indexes. */
+ tdata->nbr_modules = bfd_getl32 (lhd.modcnt);
+ tdata->artdata.symdef_count = bfd_getl32 (lhd.idxcnt) - tdata->nbr_modules;
+ nbr_ent = tdata->nbr_modules;
+ tdata->modules = vms_lib_read_index (abfd, 0, &nbr_ent);
+ if (tdata->modules == NULL || nbr_ent != tdata->nbr_modules)
+ goto err;
+ if (lhd.nindex == 2)
+ {
+ nbr_ent = tdata->artdata.symdef_count;
+ tdata->artdata.symdefs = vms_lib_read_index (abfd, 1, &nbr_ent);
+ if (tdata->artdata.symdefs == NULL)
+ goto err;
+ /* Only IA64 archives may have more entries in the index that what
+ was declared. */
+ if (nbr_ent != tdata->artdata.symdef_count
+ && kind != vms_lib_ia64)
+ goto err;
+ tdata->artdata.symdef_count = nbr_ent;
+ }
+ tdata->cache = bfd_zalloc (abfd, sizeof (bfd *) * tdata->nbr_modules);
+ if (tdata->cache == NULL)
+ goto err;
+
+ /* Read DCX submaps. */
+ dcxvbn = bfd_getl32 (lhd.dcxmapvbn);
+ if (dcxvbn != 0)
+ {
+ unsigned char buf_reclen[4];
+ unsigned int reclen;
+ unsigned char *buf;
+ struct vms_dcxmap *map;
+ unsigned int sbm_off;
+ unsigned int i;
+
+ if (bfd_seek (abfd, (dcxvbn - 1) * VMS_BLOCK_SIZE, SEEK_SET) != 0
+ || bfd_bread (buf_reclen, sizeof (buf_reclen), abfd)
+ != sizeof (buf_reclen))
+ goto err;
+ reclen = bfd_getl32 (buf_reclen);
+ buf = bfd_malloc (reclen);
+ if (buf == NULL)
+ goto err;
+ if (bfd_bread (buf, reclen, abfd) != reclen)
+ {
+ free (buf);
+ goto err;
+ }
+ map = (struct vms_dcxmap *)buf;
+ tdata->nbr_dcxsbm = bfd_getl16 (map->nsubs);
+ sbm_off = bfd_getl16 (map->sub0);
+ tdata->dcxsbm = (struct dcxsbm_desc *)bfd_alloc
+ (abfd, tdata->nbr_dcxsbm * sizeof (struct dcxsbm_desc));
+ for (i = 0; i < tdata->nbr_dcxsbm; i++)
+ {
+ struct vms_dcxsbm *sbm = (struct vms_dcxsbm *) (buf + sbm_off);
+ struct dcxsbm_desc *sbmdesc = &tdata->dcxsbm[i];
+ unsigned int sbm_len;
+ unsigned int sbm_sz;
+ unsigned int off;
+ unsigned char *data = (unsigned char *)sbm;
+ unsigned char *buf1;
+ unsigned int l, j;
+
+ sbm_sz = bfd_getl16 (sbm->size);
+ sbm_off += sbm_sz;
+ BFD_ASSERT (sbm_off <= reclen);
+
+ sbmdesc->min_char = sbm->min_char;
+ BFD_ASSERT (sbmdesc->min_char == 0);
+ sbmdesc->max_char = sbm->max_char;
+ sbm_len = sbmdesc->max_char - sbmdesc->min_char + 1;
+ l = (2 * sbm_len + 7) / 8;
+ BFD_ASSERT
+ (sbm_sz >= sizeof (struct vms_dcxsbm) + l + 3 * sbm_len
+ || (tdata->nbr_dcxsbm == 1
+ && sbm_sz >= sizeof (struct vms_dcxsbm) + l + sbm_len));
+ sbmdesc->flags = (unsigned char *)bfd_alloc (abfd, l);
+ memcpy (sbmdesc->flags, data + bfd_getl16 (sbm->flags), l);
+ sbmdesc->nodes = (unsigned char *)bfd_alloc (abfd, 2 * sbm_len);
+ memcpy (sbmdesc->nodes, data + bfd_getl16 (sbm->nodes), 2 * sbm_len);
+ off = bfd_getl16 (sbm->next);
+ if (off != 0)
+ {
+ /* Read the 'next' array. */
+ sbmdesc->next = (unsigned short *)bfd_alloc
+ (abfd, sbm_len * sizeof (unsigned short));
+ buf1 = data + off;
+ for (j = 0; j < sbm_len; j++)
+ sbmdesc->next[j] = bfd_getl16 (buf1 + j * 2);
+ }
+ else
+ {
+ /* There is no next array if there is only one submap. */
+ BFD_ASSERT (tdata->nbr_dcxsbm == 1);
+ sbmdesc->next = NULL;
+ }
+ }
+ free (buf);
+ }
+ else
+ {
+ tdata->nbr_dcxsbm = 0;
+ }
+
+ /* The map is always present. Also mark shared image library. */
+ abfd->has_armap = TRUE;
+ if (tdata->type == LBR__C_TYP_ESHSTB || tdata->type == LBR__C_TYP_ISHSTB)
+ abfd->is_thin_archive = TRUE;
+
+ return abfd->xvec;
+
+ err:
+ bfd_release (abfd, tdata);
+ abfd->tdata.any = (void *)tdata_hold;
+ return NULL;
+}
+
+/* Standard function for alpha libraries. */
+
+const bfd_target *
+_bfd_vms_lib_alpha_archive_p (bfd *abfd)
+{
+ return _bfd_vms_lib_archive_p (abfd, vms_lib_alpha);
+}
+
+/* Standard function for ia64 libraries. */
+
+const bfd_target *
+_bfd_vms_lib_ia64_archive_p (bfd *abfd)
+{
+ return _bfd_vms_lib_archive_p (abfd, vms_lib_ia64);
+}
+
+/* Standard function for text libraries. */
+
+static const bfd_target *
+_bfd_vms_lib_txt_archive_p (bfd *abfd)
+{
+ return _bfd_vms_lib_archive_p (abfd, vms_lib_txt);
+}
+
+/* Standard bfd function. */
+
+static bfd_boolean
+_bfd_vms_lib_mkarchive (bfd *abfd, enum vms_lib_kind kind)
+{
+ struct lib_tdata *tdata;
+
+ tdata = (struct lib_tdata *) bfd_zalloc (abfd, sizeof (struct lib_tdata));
+ if (tdata == NULL)
+ return FALSE;
+
+ abfd->tdata.any = (void *)tdata;
+ vms_get_time (&tdata->credat_hi, &tdata->credat_lo);
+
+ tdata->kind = kind;
+ switch (kind)
+ {
+ case vms_lib_alpha:
+ tdata->ver = LBR_MAJORID;
+ tdata->mhd_size = offsetof (struct vms_mhd, pad1);
+ tdata->type = LBR__C_TYP_EOBJ;
+ break;
+ case vms_lib_ia64:
+ tdata->ver = LBR_ELFMAJORID;
+ tdata->mhd_size = sizeof (struct vms_mhd);
+ tdata->type = LBR__C_TYP_IOBJ;
+ break;
+ default:
+ abort ();
+ }
+
+ tdata->nbr_modules = 0;
+ tdata->artdata.symdef_count = 0;
+ tdata->modules = NULL;
+ tdata->artdata.symdefs = NULL;
+ tdata->cache = NULL;
+
+ return TRUE;
+}
+
+bfd_boolean
+_bfd_vms_lib_alpha_mkarchive (bfd *abfd)
+{
+ return _bfd_vms_lib_mkarchive (abfd, vms_lib_alpha);
+}
+
+bfd_boolean
+_bfd_vms_lib_ia64_mkarchive (bfd *abfd)
+{
+ return _bfd_vms_lib_mkarchive (abfd, vms_lib_ia64);
+}
+
+/* Find NAME in the symbol index. Return the index. */
+
+symindex
+_bfd_vms_lib_find_symbol (bfd *abfd, const char *name)
+{
+ struct lib_tdata *tdata = bfd_libdata (abfd);
+ carsym *syms = tdata->artdata.symdefs;
+ int lo, hi;
+
+ /* Open-coded binary search for speed. */
+ lo = 0;
+ hi = tdata->artdata.symdef_count - 1;
+
+ while (lo <= hi)
+ {
+ int mid = lo + (hi - lo) / 2;
+ int diff;
+
+ diff = (char)(name[0] - syms[mid].name[0]);
+ if (diff == 0)
+ diff = strcmp (name, syms[mid].name);
+ if (diff == 0)
+ return mid;
+ else if (diff < 0)
+ hi = mid - 1;
+ else
+ lo = mid + 1;
+ }
+ return BFD_NO_MORE_SYMBOLS;
+}
+
+/* IO vector for archive member. Need that because members are not linearly
+ stored in archives. */
+
+struct vms_lib_iovec
+{
+ /* Current offset. */
+ ufile_ptr where;
+
+ /* Length of the module, when known. */
+ ufile_ptr file_len;
+
+ /* Current position in the record from bfd_bread point of view (ie, after
+ decompression). 0 means that no data byte have been read, -2 and -1
+ are reserved for the length word. */
+ int rec_pos;
+#define REC_POS_NL -4
+#define REC_POS_PAD -3
+#define REC_POS_LEN0 -2
+#define REC_POS_LEN1 -1
+
+ /* Record length. */
+ unsigned short rec_len;
+ /* Number of bytes to read in the current record. */
+ unsigned short rec_rem;
+ /* Offset of the next block. */
+ file_ptr next_block;
+ /* Current *data* offset in the data block. */
+ unsigned short blk_off;
+
+ /* Offset of the first block. Extracted from the index. */
+ file_ptr first_block;
+
+ /* Initial next_block. Extracted when the MHD is read. */
+ file_ptr init_next_block;
+ /* Initial blk_off, once the MHD is read. */
+ unsigned short init_blk_off;
+
+ /* Used to store any 3 byte record, which could be the EOF pattern. */
+ unsigned char pattern[4];
+
+ /* DCX. */
+ struct dcxsbm_desc *dcxsbms;
+ /* Current submap. */
+ struct dcxsbm_desc *dcx_sbm;
+ /* Current offset in the submap. */
+ unsigned int dcx_offset;
+ int dcx_pos;
+
+ /* Compressed buffer. */
+ unsigned char *dcx_buf;
+ /* Size of the buffer. Used to resize. */
+ unsigned int dcx_max;
+ /* Number of valid bytes in the buffer. */
+ unsigned int dcx_rlen;
+};
+
+/* Return the current position. */
+
+static file_ptr
+vms_lib_btell (struct bfd *abfd)
+{
+ struct vms_lib_iovec *vec = (struct vms_lib_iovec *) abfd->iostream;
+ return vec->where;
+}
+
+/* Read the header of the next data block if all bytes of the current block
+ have been read. */
+
+static bfd_boolean
+vms_lib_read_block (struct bfd *abfd)
+{
+ struct vms_lib_iovec *vec = (struct vms_lib_iovec *) abfd->iostream;
+
+ if (vec->blk_off == DATA__LENGTH)
+ {
+ unsigned char hdr[DATA__DATA];
+
+ /* Read next block. */
+ if (bfd_seek (abfd->my_archive, vec->next_block, SEEK_SET) != 0)
+ return FALSE;
+ if (bfd_bread (hdr, sizeof (hdr), abfd->my_archive) != sizeof (hdr))
+ return FALSE;
+ vec->next_block = (bfd_getl32 (hdr + 2) - 1) * VMS_BLOCK_SIZE;
+ vec->blk_off = sizeof (hdr);
+ }
+ return TRUE;
+}
+
+/* Read NBYTES from ABFD into BUF if not NULL. If BUF is NULL, bytes are
+ not stored. Read linearly from the library, but handle blocks. This
+ function does not handle records nor EOF. */
+
+static file_ptr
+vms_lib_bread_raw (struct bfd *abfd, unsigned char *buf, file_ptr nbytes)
+{
+ struct vms_lib_iovec *vec = (struct vms_lib_iovec *) abfd->iostream;
+ file_ptr res;
+
+ res = 0;
+ while (nbytes > 0)
+ {
+ unsigned int l;
+
+ /* Be sure the current data block is read. */
+ if (!vms_lib_read_block (abfd))
+ return -1;
+
+ /* Do not read past the data block, do not read more than requested. */
+ l = DATA__LENGTH - vec->blk_off;
+ if (l > nbytes)
+ l = nbytes;
+ if (l == 0)
+ return 0;
+ if (buf != NULL)
+ {
+ /* Really read into BUF. */
+ if (bfd_bread (buf, l, abfd->my_archive) != l)
+ return -1;
+ }
+ else
+ {
+ /* Make as if we are reading. */
+ if (bfd_seek (abfd->my_archive, l, SEEK_CUR) != 0)
+ return -1;
+ }
+
+ if (buf != NULL)
+ buf += l;
+ vec->blk_off += l;
+ nbytes -= l;
+ res += l;
+ }
+ return res;
+}
+
+/* Decompress NBYTES from VEC. Store the bytes into BUF if not NULL. */
+
+static file_ptr
+vms_lib_dcx (struct vms_lib_iovec *vec, unsigned char *buf, file_ptr nbytes)
+{
+ struct dcxsbm_desc *sbm;
+ unsigned int i;
+ unsigned int offset;
+ unsigned int j;
+ file_ptr res = 0;
+
+ /* The loop below expect to deliver at least one byte. */
+ if (nbytes == 0)
+ return 0;
+
+ /* Get the current state. */
+ sbm = vec->dcx_sbm;
+ offset = vec->dcx_offset;
+ j = vec->dcx_pos & 7;
+
+ for (i = vec->dcx_pos >> 3; i < vec->dcx_rlen; i++)
+ {
+ unsigned char b = vec->dcx_buf[i];
+
+ for (; j < 8; j++)
+ {
+ if (b & (1 << j))
+ offset++;
+ if (!(sbm->flags[offset >> 3] & (1 << (offset & 7))))
+ {
+ unsigned int n_offset = sbm->nodes[offset];
+ if (n_offset == 0)
+ {
+ /* End of buffer. Stay where we are. */
+ vec->dcx_pos = (i << 3) + j;
+ if (b & (1 << j))
+ offset--;
+ vec->dcx_offset = offset;
+ vec->dcx_sbm = sbm;
+ return res;
+ }
+ offset = 2 * n_offset;
+ }
+ else
+ {
+ unsigned char v = sbm->nodes[offset];
+
+ if (sbm->next != NULL)
+ sbm = vec->dcxsbms + sbm->next[v];
+ offset = 0;
+ res++;
+
+ if (buf)
+ {
+ *buf++ = v;
+ nbytes--;
+
+ if (nbytes == 0)
+ {
+ vec->dcx_pos = (i << 3) + j + 1;
+ vec->dcx_offset = offset;
+ vec->dcx_sbm = sbm;
+
+ return res;
+ }
+ }
+ }
+ }
+ j = 0;
+ }
+ return -1;
+}
+
+/* Standard IOVEC function. */
+
+static file_ptr
+vms_lib_bread (struct bfd *abfd, void *vbuf, file_ptr nbytes)
+{
+ struct vms_lib_iovec *vec = (struct vms_lib_iovec *) abfd->iostream;
+ file_ptr res;
+ file_ptr chunk;
+ unsigned char *buf = (unsigned char *)vbuf;
+
+ /* Do not read past the end. */
+ if (vec->where >= vec->file_len)
+ return 0;
+
+ res = 0;
+ while (nbytes > 0)
+ {
+ if (vec->rec_rem == 0)
+ {
+ unsigned char blen[2];
+
+ /* Read record length. */
+ if (vms_lib_bread_raw (abfd, blen, sizeof (blen)) != sizeof (blen))
+ return -1;
+ vec->rec_len = bfd_getl16 (blen);
+ if (bfd_libdata (abfd->my_archive)->kind == vms_lib_txt)
+ {
+ /* Discard record size and align byte. */
+ vec->rec_pos = 0;
+ vec->rec_rem = vec->rec_len;
+ }
+ else
+ {
+ /* Prepend record size. */
+ vec->rec_pos = REC_POS_LEN0;
+ vec->rec_rem = (vec->rec_len + 1) & ~1; /* With align byte. */
+ }
+ if (vec->rec_len == 3)
+ {
+ /* Possibly end of file. Check the pattern. */
+ if (vms_lib_bread_raw (abfd, vec->pattern, 4) != 4)
+ return -1;
+ if (!memcmp (vec->pattern, eotdesc + 2, 3))
+ {
+ /* This is really an EOF. */
+ vec->where += res;
+ vec->file_len = vec->where;
+ return res;
+ }
+ }
+
+ if (vec->dcxsbms != NULL)
+ {
+ /* This is a compressed member. */
+ unsigned int len;
+ file_ptr elen;
+
+ /* Be sure there is enough room for the expansion. */
+ len = (vec->rec_len + 1) & ~1;
+ if (len > vec->dcx_max)
+ {
+ while (len > vec->dcx_max)
+ vec->dcx_max *= 2;
+ vec->dcx_buf = bfd_alloc (abfd, vec->dcx_max);
+ if (vec->dcx_buf == NULL)
+ return -1;
+ }
+
+ /* Read the compressed record. */
+ vec->dcx_rlen = len;
+ if (vec->rec_len == 3)
+ {
+ /* Already read. */
+ memcpy (vec->dcx_buf, vec->pattern, 3);
+ }
+ else
+ {
+ elen = vms_lib_bread_raw (abfd, vec->dcx_buf, len);
+ if (elen != len)
+ return -1;
+ }
+
+ /* Dummy expansion to get the expanded length. */
+ vec->dcx_offset = 0;
+ vec->dcx_sbm = vec->dcxsbms;
+ vec->dcx_pos = 0;
+ elen = vms_lib_dcx (vec, NULL, 0x10000);
+ if (elen < 0)
+ return -1;
+ vec->rec_len = elen;
+ vec->rec_rem = elen;
+
+ /* Reset the state. */
+ vec->dcx_offset = 0;
+ vec->dcx_sbm = vec->dcxsbms;
+ vec->dcx_pos = 0;
+ }
+ }
+ if (vec->rec_pos < 0)
+ {
+ unsigned char c;
+ switch (vec->rec_pos)
+ {
+ case REC_POS_LEN0:
+ c = vec->rec_len & 0xff;
+ vec->rec_pos = REC_POS_LEN1;
+ break;
+ case REC_POS_LEN1:
+ c = (vec->rec_len >> 8) & 0xff;
+ vec->rec_pos = 0;
+ break;
+ case REC_POS_PAD:
+ c = 0;
+ vec->rec_rem = 0;
+ break;
+ case REC_POS_NL:
+ c = '\n';
+ vec->rec_rem = 0;
+ break;
+ default:
+ abort ();
+ }
+ if (buf != NULL)
+ {
+ *buf = c;
+ buf++;
+ }
+ nbytes--;
+ res++;
+ continue;
+ }
+
+ if (nbytes > vec->rec_rem)
+ chunk = vec->rec_rem;
+ else
+ chunk = nbytes;
+
+ if (vec->dcxsbms != NULL)
+ {
+ /* Optimize the stat() case: no need to decompress again as we
+ know the length. */
+ if (!(buf == NULL && chunk == vec->rec_rem))
+ chunk = vms_lib_dcx (vec, buf, chunk);
+ }
+ else
+ {
+ if (vec->rec_len == 3)
+ {
+ if (buf != NULL)
+ memcpy (buf, vec->pattern + vec->rec_pos, chunk);
+ }
+ else
+ chunk = vms_lib_bread_raw (abfd, buf, chunk);
+ }
+ if (chunk < 0)
+ return -1;
+ res += chunk;
+ if (buf != NULL)
+ buf += chunk;
+ nbytes -= chunk;
+ vec->rec_pos += chunk;
+ vec->rec_rem -= chunk;
+
+ if (vec->rec_rem == 0)
+ {
+ /* End of record reached. */
+ if (bfd_libdata (abfd->my_archive)->kind == vms_lib_txt)
+ {
+ if ((vec->rec_len & 1) == 1
+ && vec->rec_len != 3
+ && vec->dcxsbms == NULL)
+ {
+ /* Eat the pad byte. */
+ unsigned char pad;
+ if (vms_lib_bread_raw (abfd, &pad, 1) != 1)
+ return -1;
+ }
+ vec->rec_pos = REC_POS_NL;
+ vec->rec_rem = 1;
+ }
+ else
+ {
+ if ((vec->rec_len & 1) == 1 && vec->dcxsbms != NULL)
+ {
+ vec->rec_pos = REC_POS_PAD;
+ vec->rec_rem = 1;
+ }
+ }
+ }
+ }
+ vec->where += res;
+ return res;
+}
+
+/* Standard function, but we currently only handle the rewind case. */
+
+static int
+vms_lib_bseek (struct bfd *abfd, file_ptr offset, int whence)
+{
+ struct vms_lib_iovec *vec = (struct vms_lib_iovec *) abfd->iostream;
+
+ if (whence == SEEK_SET && offset == 0)
+ {
+ vec->where = 0;
+ vec->rec_rem = 0;
+ vec->dcx_pos = -1;
+ vec->blk_off = vec->init_blk_off;
+ vec->next_block = vec->init_next_block;
+
+ if (bfd_seek (abfd->my_archive, vec->first_block, SEEK_SET) != 0)
+ return -1;
+ }
+ else
+ abort ();
+ return 0;
+}
+
+static file_ptr
+vms_lib_bwrite (struct bfd *abfd ATTRIBUTE_UNUSED,
+ const void *where ATTRIBUTE_UNUSED,
+ file_ptr nbytes ATTRIBUTE_UNUSED)
+{
+ return -1;
+}
+
+static int
+vms_lib_bclose (struct bfd *abfd)
+{
+ abfd->iostream = NULL;
+ return 0;
+}
+
+static int
+vms_lib_bflush (struct bfd *abfd ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+static int
+vms_lib_bstat (struct bfd *abfd ATTRIBUTE_UNUSED,
+ struct stat *sb ATTRIBUTE_UNUSED)
+{
+ /* Not supported. */
+ return 0;
+}
+
+static void *
+vms_lib_bmmap (struct bfd *abfd ATTRIBUTE_UNUSED,
+ void *addr ATTRIBUTE_UNUSED,
+ bfd_size_type len ATTRIBUTE_UNUSED,
+ int prot ATTRIBUTE_UNUSED,
+ int flags ATTRIBUTE_UNUSED,
+ file_ptr offset ATTRIBUTE_UNUSED,
+ void **map_addr ATTRIBUTE_UNUSED,
+ bfd_size_type *map_len ATTRIBUTE_UNUSED)
+{
+ return (void *) -1;
+}
+
+static const struct bfd_iovec vms_lib_iovec = {
+ &vms_lib_bread, &vms_lib_bwrite, &vms_lib_btell, &vms_lib_bseek,
+ &vms_lib_bclose, &vms_lib_bflush, &vms_lib_bstat, &vms_lib_bmmap
+};
+
+/* Open a library module. FILEPOS is the position of the module header. */
+
+static bfd_boolean
+vms_lib_bopen (bfd *el, file_ptr filepos)
+{
+ struct vms_lib_iovec *vec;
+ unsigned char buf[256];
+ struct vms_mhd *mhd;
+ struct lib_tdata *tdata = bfd_libdata (el->my_archive);
+ unsigned int len;
+
+ /* Allocate and initialized the iovec. */
+ vec = bfd_zalloc (el, sizeof (*vec));
+ if (vec == NULL)
+ return FALSE;
+
+ el->iostream = vec;
+ el->iovec = &vms_lib_iovec;
+
+ /* File length is not known. */
+ vec->file_len = -1;
+
+ /* Read the first data block. */
+ vec->next_block = filepos & ~(VMS_BLOCK_SIZE - 1);
+ vec->blk_off = DATA__LENGTH;
+ if (!vms_lib_read_block (el))
+ return FALSE;
+
+ /* Prepare to read the first record. */
+ vec->blk_off = filepos & (VMS_BLOCK_SIZE - 1);
+ vec->rec_rem = 0;
+ if (bfd_seek (el->my_archive, filepos, SEEK_SET) != 0)
+ return FALSE;
+
+ /* Read Record length + MHD + align byte. */
+ len = tdata->mhd_size;
+ if (vms_lib_bread_raw (el, buf, 2) != 2)
+ return FALSE;
+ if (bfd_getl16 (buf) != len)
+ return FALSE;
+ len = (len + 1) & ~1;
+ BFD_ASSERT (len <= sizeof (buf));
+ if (vms_lib_bread_raw (el, buf, len) != len)
+ return FALSE;
+
+ /* Get info from mhd. */
+ mhd = (struct vms_mhd *)buf;
+ /* Check id. */
+ if (mhd->id != MHD__C_MHDID)
+ return FALSE;
+ if (len >= MHD__C_MHDLEN + 1)
+ el->selective_search = (mhd->objstat & MHD__M_SELSRC) ? 1 : 0;
+ el->mtime = vms_rawtime_to_time_t (mhd->datim);
+ el->mtime_set = TRUE;
+
+ /* Reinit the iovec so that seek() will point to the first record after
+ the mhd. */
+ vec->where = 0;
+ vec->init_blk_off = vec->blk_off;
+ vec->init_next_block = vec->next_block;
+ vec->first_block = bfd_tell (el->my_archive);
+ vec->dcxsbms = bfd_libdata (el->my_archive)->dcxsbm;
+
+ if (vec->dcxsbms != NULL)
+ {
+ /* Handle DCX. */
+ vec->dcx_max = 10 * 1024;
+ vec->dcx_buf = bfd_alloc (el, vec->dcx_max);
+ vec->dcx_pos = -1;
+ if (vec->dcx_buf == NULL)
+ return -1;
+ }
+ return TRUE;
+}
+
+/* Get member MODIDX. Return NULL in case of error. */
+
+static bfd *
+_bfd_vms_lib_get_module (bfd *abfd, unsigned int modidx)
+{
+ struct lib_tdata *tdata = bfd_libdata (abfd);
+ bfd *res;
+ file_ptr file_off;
+ char *name;
+
+ /* Sanity check. */
+ if (modidx >= tdata->nbr_modules)
+ return NULL;
+
+ /* Already loaded. */
+ if (tdata->cache[modidx])
+ return tdata->cache[modidx];
+
+ /* Build it. */
+ file_off = tdata->modules[modidx].file_offset;
+ if (tdata->type != LBR__C_TYP_IOBJ)
+ {
+ res = _bfd_create_empty_archive_element_shell (abfd);
+ if (res == NULL)
+ return NULL;
+
+ /* Special reader to deal with data blocks. */
+ if (!vms_lib_bopen (res, file_off))
+ return NULL;
+ }
+ else
+ {
+ char buf[256];
+ struct vms_mhd *mhd;
+ struct areltdata *arelt;
+
+ /* Sanity check. The MHD must be big enough to contain module size. */
+ if (tdata->mhd_size < offsetof (struct vms_mhd, modsize) + 4)
+ return NULL;
+
+ /* Read the MHD now. */
+ if (bfd_seek (abfd, file_off, SEEK_SET) != 0)
+ return NULL;
+ if (bfd_bread (buf, tdata->mhd_size, abfd) != tdata->mhd_size)
+ return NULL;
+
+ res = _bfd_create_empty_archive_element_shell (abfd);
+ if (res == NULL)
+ return NULL;
+ arelt = bfd_zmalloc (sizeof (*arelt));
+ if (arelt == NULL)
+ return NULL;
+ res->arelt_data = arelt;
+
+ /* Get info from mhd. */
+ mhd = (struct vms_mhd *)buf;
+ if (mhd->id != MHD__C_MHDID)
+ return NULL;
+ if (tdata->mhd_size >= offsetof (struct vms_mhd, objstat) + 1)
+ res->selective_search = (mhd->objstat & MHD__M_SELSRC) ? 1 : 0;
+ res->mtime = vms_rawtime_to_time_t (mhd->datim);
+ res->mtime_set = TRUE;
+
+ arelt->parsed_size = bfd_getl32 (mhd->modsize);
+
+ /* No need for a special reader as members are stored linearly.
+ Just skip the MHD. */
+ res->origin = file_off + tdata->mhd_size;
+ }
+
+ /* Set filename. */
+ name = tdata->modules[modidx].name;
+ switch (tdata->type)
+ {
+ case LBR__C_TYP_IOBJ:
+ case LBR__C_TYP_EOBJ:
+ /* For object archives, append .obj to mimic standard behaviour. */
+ {
+ size_t namelen = strlen (name);
+ char *name1 = bfd_alloc (res, namelen + 4 + 1);
+ memcpy (name1, name, namelen);
+ strcpy (name1 + namelen, ".obj");
+ name = name1;
+ }
+ break;
+ default:
+ break;
+ }
+ res->filename = xstrdup (name);
+
+ tdata->cache[modidx] = res;
+
+ return res;
+}
+
+/* Standard function: get member at IDX. */
+
+bfd *
+_bfd_vms_lib_get_elt_at_index (bfd *abfd, symindex symidx)
+{
+ struct lib_tdata *tdata = bfd_libdata (abfd);
+ file_ptr file_off;
+ unsigned int modidx;
+
+ /* Check symidx. */
+ if (symidx > tdata->artdata.symdef_count)
+ return NULL;
+ file_off = tdata->artdata.symdefs[symidx].file_offset;
+
+ /* Linear-scan. */
+ for (modidx = 0; modidx < tdata->nbr_modules; modidx++)
+ {
+ if (tdata->modules[modidx].file_offset == file_off)
+ break;
+ }
+ if (modidx >= tdata->nbr_modules)
+ return NULL;
+
+ return _bfd_vms_lib_get_module (abfd, modidx);
+}
+
+/* Elements of an imagelib are stubs. You can get the real image with this
+ function. */
+
+bfd *
+_bfd_vms_lib_get_imagelib_file (bfd *el)
+{
+ bfd *archive = el->my_archive;
+ const char *modname = el->filename;
+ int modlen = strlen (modname);
+ char *filename;
+ int j;
+ bfd *res;
+
+ /* Convert module name to lower case and append '.exe'. */
+ filename = bfd_alloc (el, modlen + 5);
+ if (filename == NULL)
+ return NULL;
+ for (j = 0; j < modlen; j++)
+ if (ISALPHA (modname[j]))
+ filename[j] = TOLOWER (modname[j]);
+ else
+ filename[j] = modname[j];
+ memcpy (filename + modlen, ".exe", 5);
+
+ filename = _bfd_append_relative_path (archive, filename);
+ if (filename == NULL)
+ return NULL;
+ res = bfd_openr (filename, NULL);
+
+ if (res == NULL)
+ {
+ (*_bfd_error_handler)(_("could not open shared image '%s' from '%s'"),
+ filename, archive->filename);
+ bfd_release (archive, filename);
+ return NULL;
+ }
+
+ /* FIXME: put it in a cache ? */
+ return res;
+}
+
+/* Standard function. */
+
+bfd *
+_bfd_vms_lib_openr_next_archived_file (bfd *archive,
+ bfd *last_file)
+{
+ unsigned int idx;
+ bfd *res;
+
+ if (!last_file)
+ idx = 0;
+ else
+ idx = last_file->proxy_origin + 1;
+
+ if (idx >= bfd_libdata (archive)->nbr_modules)
+ {
+ bfd_set_error (bfd_error_no_more_archived_files);
+ return NULL;
+ }
+
+ res = _bfd_vms_lib_get_module (archive, idx);
+ if (res == NULL)
+ return res;
+ res->proxy_origin = idx;
+ return res;
+}
+
+/* Standard function. Just compute the length. */
+
+int
+_bfd_vms_lib_generic_stat_arch_elt (bfd *abfd, struct stat *st)
+{
+ struct lib_tdata *tdata;
+
+ /* Sanity check. */
+ if (abfd->my_archive == NULL)
+ {
+ bfd_set_error (bfd_error_invalid_operation);
+ return -1;
+ }
+
+ tdata = bfd_libdata (abfd->my_archive);
+ if (tdata->type != LBR__C_TYP_IOBJ)
+ {
+ struct vms_lib_iovec *vec = (struct vms_lib_iovec *) abfd->iostream;
+
+ if (vec->file_len == (ufile_ptr)-1)
+ {
+ if (vms_lib_bseek (abfd, 0, SEEK_SET) != 0)
+ return -1;
+
+ /* Compute length. */
+ while (vms_lib_bread (abfd, NULL, 1 << 20) > 0)
+ ;
+ }
+ st->st_size = vec->file_len;
+ }
+ else
+ {
+ st->st_size = ((struct areltdata *)abfd->arelt_data)->parsed_size;
+ }
+
+ if (abfd->mtime_set)
+ st->st_mtime = abfd->mtime;
+ else
+ st->st_mtime = 0;
+ st->st_uid = 0;
+ st->st_gid = 0;
+ st->st_mode = 0644;
+
+ return 0;
+}
+
+/* Internal representation of an index entry. */
+
+struct lib_index
+{
+ /* Corresponding archive member. */
+ bfd *abfd;
+
+ /* Number of reference to this entry. */
+ unsigned int ref;
+
+ /* Length of the key. */
+ unsigned short namlen;
+
+ /* Key. */
+ const char *name;
+};
+
+/* Used to sort index entries. */
+
+static int
+lib_index_cmp (const void *lv, const void *rv)
+{
+ const struct lib_index *l = lv;
+ const struct lib_index *r = rv;
+
+ return strcmp (l->name, r->name);
+}
+
+/* Maximum number of index blocks level. */
+
+#define MAX_LEVEL 10
+
+/* Get the size of an index entry. */
+
+static unsigned int
+get_idxlen (struct lib_index *idx, bfd_boolean is_elfidx)
+{
+ if (is_elfidx)
+ {
+ /* 9 is the size of struct vms_elfidx without keyname. */
+ if (idx->namlen > MAX_KEYLEN)
+ return 9 + sizeof (struct vms_kbn);
+ else
+ return 9 + idx->namlen;
+ }
+ else
+ {
+ /* 7 is the size of struct vms_idx without keyname. */
+ return 7 + idx->namlen;
+ }
+}
+
+/* Write the index composed by NBR symbols contained in IDX.
+ VBN is the first vbn to be used, and will contain on return the last vbn.
+ Can be called with ABFD set to NULL just to size the index.
+ If not null, TOPVBN will be assigned to the vbn of the root index tree.
+ IS_ELFIDX is true for elfidx (ie ia64) indexes layout.
+ Return TRUE on success. */
+
+static bfd_boolean
+vms_write_index (bfd *abfd,
+ struct lib_index *idx, unsigned int nbr, unsigned int *vbn,
+ unsigned int *topvbn, bfd_boolean is_elfidx)
+{
+ /* The index is organized as a tree. This function implements a naive
+ algorithm to balance the tree: it fills the leaves, and create a new
+ branch when all upper leaves and branches are full. We only keep in
+ memory a path to the current leaf. */
+ unsigned int i;
+ int j;
+ int level;
+ /* Disk blocks for the current path. */
+ struct vms_indexdef *rblk[MAX_LEVEL];
+ /* Info on the current blocks. */
+ struct idxblk
+ {
+ unsigned int vbn; /* VBN of the block. */
+ /* The last entry is identified so that it could be copied to the
+ parent block. */
+ unsigned short len; /* Length up to the last entry. */
+ unsigned short lastlen; /* Length of the last entry. */
+ } blk[MAX_LEVEL];
+
+ /* The kbn blocks are used to store long symbol names. */
+ unsigned int kbn_sz = 0; /* Number of bytes available in the kbn block. */
+ unsigned int kbn_vbn = 0; /* VBN of the kbn block. */
+ unsigned char *kbn_blk = NULL; /* Contents of the kbn block. */
+
+ if (nbr == 0)
+ {
+ /* No entries. Very easy to handle. */
+ if (topvbn != NULL)
+ *topvbn = 0;
+ return TRUE;
+ }
+
+ if (abfd == NULL)
+ {
+ /* Sort the index the first time this function is called. */
+ qsort (idx, nbr, sizeof (struct lib_index), lib_index_cmp);
+ }
+
+ /* Allocate first index block. */
+ level = 1;
+ if (abfd != NULL)
+ rblk[0] = bfd_zmalloc (sizeof (struct vms_indexdef));
+ blk[0].vbn = (*vbn)++;
+ blk[0].len = 0;
+ blk[0].lastlen = 0;
+
+ for (i = 0; i < nbr; i++, idx++)
+ {
+ unsigned int idxlen;
+ int flush = 0;
+ unsigned int key_vbn = 0;
+ unsigned int key_off = 0;
+
+ idxlen = get_idxlen (idx, is_elfidx);
+
+ if (is_elfidx && idx->namlen > MAX_KEYLEN)
+ {
+ /* If the key (ie name) is too long, write it in the kbn block. */
+ unsigned int kl = idx->namlen;
+ unsigned int kl_chunk;
+ const char *key = idx->name;
+
+ /* Write the key in the kbn, chunk after chunk. */
+ do
+ {
+ if (kbn_sz < sizeof (struct vms_kbn))
+ {
+ /* Not enough room in the kbn block. */
+ if (abfd != NULL)
+ {
+ /* Write it to the disk (if there is one). */
+ if (kbn_vbn != 0)
+ {
+ if (vms_write_block (abfd, kbn_vbn, kbn_blk) != TRUE)
+ return FALSE;
+ }
+ else
+ {
+ kbn_blk = bfd_malloc (VMS_BLOCK_SIZE);
+ if (kbn_blk == NULL)
+ return FALSE;
+ }
+ *(unsigned short *)kbn_blk = 0;
+ }
+ /* Allocate a new block for the keys. */
+ kbn_vbn = (*vbn)++;
+ kbn_sz = VMS_BLOCK_SIZE - 2;
+ }
+ /* Size of the chunk written to the current key block. */
+ if (kl + sizeof (struct vms_kbn) > kbn_sz)
+ kl_chunk = kbn_sz - sizeof (struct vms_kbn);
+ else
+ kl_chunk = kl;
+
+ if (kbn_blk != NULL)
+ {
+ struct vms_kbn *kbn;
+
+ kbn = (struct vms_kbn *)(kbn_blk + VMS_BLOCK_SIZE - kbn_sz);
+
+ if (key_vbn == 0)
+ {
+ /* Save the rfa of the first chunk. */
+ key_vbn = kbn_vbn;
+ key_off = VMS_BLOCK_SIZE - kbn_sz;
+ }
+
+ bfd_putl16 (kl_chunk, kbn->keylen);
+ if (kl_chunk == kl)
+ {
+ /* No next chunk. */
+ bfd_putl32 (0, kbn->rfa.vbn);
+ bfd_putl16 (0, kbn->rfa.offset);
+ }
+ else
+ {
+ /* Next chunk will be at the start of the next block. */
+ bfd_putl32 (*vbn, kbn->rfa.vbn);
+ bfd_putl16 (2, kbn->rfa.offset);
+ }
+ memcpy ((char *)(kbn + 1), key, kl_chunk);
+ key += kl_chunk;
+ }
+ kl -= kl_chunk;
+ kl_chunk = (kl_chunk + 1) & ~1; /* Always align. */
+ kbn_sz -= kl_chunk + sizeof (struct vms_kbn);
+ }
+ while (kl > 0);
+ }
+
+ /* Check if a block might overflow. In this case we will flush this
+ block and all the blocks below it. */
+ for (j = 0; j < level; j++)
+ if (blk[j].len + blk[j].lastlen + idxlen > INDEXDEF__BLKSIZ)
+ flush = j + 1;
+
+ for (j = 0; j < level; j++)
+ {
+ if (j < flush)
+ {
+ /* There is not enough room to write the new entry in this
+ block or in a parent block. */
+
+ if (j + 1 == level)
+ {
+ BFD_ASSERT (level < MAX_LEVEL);
+
+ /* Need to create a parent. */
+ if (abfd != NULL)
+ {
+ rblk[level] = bfd_zmalloc (sizeof (struct vms_indexdef));
+ bfd_putl32 (*vbn, rblk[j]->parent);
+ }
+ blk[level].vbn = (*vbn)++;
+ blk[level].len = 0;
+ blk[level].lastlen = blk[j].lastlen;
+
+ level++;
+ }
+
+ /* Update parent block: write the last entry from the current
+ block. */
+ if (abfd != NULL)
+ {
+ struct vms_rfa *rfa;
+
+ /* Pointer to the last entry in parent block. */
+ rfa = (struct vms_rfa *)(rblk[j + 1]->keys + blk[j + 1].len);
+
+ /* Copy the whole entry. */
+ BFD_ASSERT (blk[j + 1].lastlen == blk[j].lastlen);
+ memcpy (rfa, rblk[j]->keys + blk[j].len, blk[j].lastlen);
+ /* Fix the entry (which in always the first field of an
+ entry. */
+ bfd_putl32 (blk[j].vbn, rfa->vbn);
+ bfd_putl16 (RFADEF__C_INDEX, rfa->offset);
+ }
+
+ if (j + 1 == flush)
+ {
+ /* And allocate it. Do it only on the block that won't be
+ flushed (so that the parent of the parent can be
+ updated too). */
+ blk[j + 1].len += blk[j + 1].lastlen;
+ blk[j + 1].lastlen = 0;
+ }
+
+ /* Write this block on the disk. */
+ if (abfd != NULL)
+ {
+ bfd_putl16 (blk[j].len + blk[j].lastlen, rblk[j]->used);
+ if (vms_write_block (abfd, blk[j].vbn, rblk[j]) != TRUE)
+ return FALSE;
+ }
+
+ /* Reset this block. */
+ blk[j].len = 0;
+ blk[j].lastlen = 0;
+ blk[j].vbn = (*vbn)++;
+ }
+
+ /* Append it to the block. */
+ if (j == 0)
+ {
+ /* Keep the previous last entry. */
+ blk[j].len += blk[j].lastlen;
+
+ if (abfd != NULL)
+ {
+ struct vms_rfa *rfa;
+
+ rfa = (struct vms_rfa *)(rblk[j]->keys + blk[j].len);
+ bfd_putl32 ((idx->abfd->proxy_origin / VMS_BLOCK_SIZE) + 1,
+ rfa->vbn);
+ bfd_putl16
+ ((idx->abfd->proxy_origin % VMS_BLOCK_SIZE)
+ + (is_elfidx ? 0 : DATA__DATA),
+ rfa->offset);
+
+ if (is_elfidx)
+ {
+ /* Use elfidx format. */
+ struct vms_elfidx *en = (struct vms_elfidx *)rfa;
+
+ en->flags = 0;
+ if (key_vbn != 0)
+ {
+ /* Long symbol name. */
+ struct vms_kbn *k = (struct vms_kbn *)(en->keyname);
+ bfd_putl16 (sizeof (struct vms_kbn), en->keylen);
+ bfd_putl16 (idx->namlen, k->keylen);
+ bfd_putl32 (key_vbn, k->rfa.vbn);
+ bfd_putl16 (key_off, k->rfa.offset);
+ en->flags |= ELFIDX__SYMESC;
+ }
+ else
+ {
+ bfd_putl16 (idx->namlen, en->keylen);
+ memcpy (en->keyname, idx->name, idx->namlen);
+ }
+ }
+ else
+ {
+ /* Use idx format. */
+ struct vms_idx *en = (struct vms_idx *)rfa;
+ en->keylen = idx->namlen;
+ memcpy (en->keyname, idx->name, idx->namlen);
+ }
+ }
+ }
+ /* The last added key can now be the last one all blocks in the
+ path. */
+ blk[j].lastlen = idxlen;
+ }
+ }
+
+ /* Save VBN of the root. */
+ if (topvbn != NULL)
+ *topvbn = blk[level - 1].vbn;
+
+ if (abfd == NULL)
+ return TRUE;
+
+ /* Flush. */
+ for (j = 1; j < level; j++)
+ {
+ /* Update parent block: write the new entry. */
+ unsigned char *en;
+ unsigned char *par;
+ struct vms_rfa *rfa;
+
+ en = rblk[j - 1]->keys + blk[j - 1].len;
+ par = rblk[j]->keys + blk[j].len;
+ BFD_ASSERT (blk[j].lastlen == blk[j - 1].lastlen);
+ memcpy (par, en, blk[j - 1].lastlen);
+ rfa = (struct vms_rfa *)par;
+ bfd_putl32 (blk[j - 1].vbn, rfa->vbn);
+ bfd_putl16 (RFADEF__C_INDEX, rfa->offset);
+ }
+
+ for (j = 0; j < level; j++)
+ {
+ /* Write this block on the disk. */
+ bfd_putl16 (blk[j].len + blk[j].lastlen, rblk[j]->used);
+ if (vms_write_block (abfd, blk[j].vbn, rblk[j]) != TRUE)
+ return FALSE;
+
+ free (rblk[j]);
+ }
+
+ /* Write the last kbn (if any). */
+ if (kbn_vbn != 0)
+ {
+ if (vms_write_block (abfd, kbn_vbn, kbn_blk) != TRUE)
+ return FALSE;
+ free (kbn_blk);
+ }
+
+ return TRUE;
+}
+
+/* Append data to the data block DATA. Force write if PAD is true. */
+
+static bfd_boolean
+vms_write_data_block (bfd *arch, struct vms_datadef *data, file_ptr *off,
+ const unsigned char *buf, unsigned int len, int pad)
+{
+ while (len > 0 || pad)
+ {
+ unsigned int doff = *off & (VMS_BLOCK_SIZE - 1);
+ unsigned int remlen = (DATA__LENGTH - DATA__DATA) - doff;
+ unsigned int l;
+
+ l = (len > remlen) ? remlen : len;
+ memcpy (data->data + doff, buf, l);
+ buf += l;
+ len -= l;
+ doff += l;
+ *off += l;
+
+ if (doff == (DATA__LENGTH - DATA__DATA) || (len == 0 && pad))
+ {
+ data->recs = 0;
+ data->fill_1 = 0;
+ bfd_putl32 ((*off / VMS_BLOCK_SIZE) + 2, data->link);
+
+ if (bfd_bwrite (data, sizeof (*data), arch) != sizeof (*data))
+ return FALSE;
+
+ *off += DATA__LENGTH - doff;
+
+ if (len == 0)
+ break;
+ }
+ }
+ return TRUE;
+}
+
+/* Build the symbols index. */
+
+static bfd_boolean
+_bfd_vms_lib_build_map (unsigned int nbr_modules,
+ struct lib_index *modules,
+ unsigned int *res_cnt,
+ struct lib_index **res)
+{
+ unsigned int i;
+ asymbol **syms = NULL;
+ long syms_max = 0;
+ struct lib_index *map = NULL;
+ unsigned int map_max = 1024; /* Fine initial default. */
+ unsigned int map_count = 0;
+
+ map = (struct lib_index *) bfd_malloc (map_max * sizeof (struct lib_index));
+ if (map == NULL)
+ goto error_return;
+
+ /* Gather symbols. */
+ for (i = 0; i < nbr_modules; i++)
+ {
+ long storage;
+ long symcount;
+ long src_count;
+ bfd *current = modules[i].abfd;
+
+ if ((bfd_get_file_flags (current) & HAS_SYMS) == 0)
+ continue;
+
+ 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 (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))
+ {
+ struct lib_index *new_map;
+
+ /* This symbol will go into the archive header. */
+ if (map_count == map_max)
+ {
+ map_max *= 2;
+ new_map = (struct lib_index *)
+ bfd_realloc (map, map_max * sizeof (struct lib_index));
+ if (new_map == NULL)
+ goto error_return;
+ map = new_map;
+ }
+
+ map[map_count].abfd = current;
+ map[map_count].namlen = strlen (syms[src_count]->name);
+ map[map_count].name = syms[src_count]->name;
+ map_count++;
+ modules[i].ref++;
+ }
+ }
+ }
+ }
+
+ *res_cnt = map_count;
+ *res = map;
+ return TRUE;
+
+ error_return:
+ if (syms_max > 0)
+ free (syms);
+ if (map != NULL)
+ free (map);
+ return FALSE;
+}
+
+/* Do the hard work: write an archive on the disk. */
+
+bfd_boolean
+_bfd_vms_lib_write_archive_contents (bfd *arch)
+{
+ bfd *current;
+ unsigned int nbr_modules;
+ struct lib_index *modules;
+ unsigned int nbr_symbols;
+ struct lib_index *symbols;
+ struct lib_tdata *tdata = bfd_libdata (arch);
+ unsigned int i;
+ file_ptr off;
+ unsigned int nbr_mod_iblk;
+ unsigned int nbr_sym_iblk;
+ unsigned int vbn;
+ unsigned int mod_idx_vbn;
+ unsigned int sym_idx_vbn;
+ bfd_boolean is_elfidx = tdata->kind == vms_lib_ia64;
+ unsigned int max_keylen = is_elfidx ? MAX_EKEYLEN : MAX_KEYLEN;
+
+ /* Count the number of modules (and do a first sanity check). */
+ nbr_modules = 0;
+ for (current = arch->archive_head;
+ current != NULL;
+ current = current->archive_next)
+ {
+ /* This check is checking the bfds for the objects we're reading
+ from (which are usually either an object file or archive on
+ disk), not the archive entries we're writing to. We don't
+ actually create bfds for the archive members, we just copy
+ them byte-wise when we write out the archive. */
+ if (bfd_write_p (current) || !bfd_check_format (current, bfd_object))
+ {
+ bfd_set_error (bfd_error_invalid_operation);
+ goto input_err;
+ }
+
+ nbr_modules++;
+ }
+
+ /* Build the modules list. */
+ BFD_ASSERT (tdata->modules == NULL);
+ modules = bfd_alloc (arch, nbr_modules * sizeof (struct lib_index));
+ if (modules == NULL)
+ return FALSE;
+
+ for (current = arch->archive_head, i = 0;
+ current != NULL;
+ current = current->archive_next, i++)
+ {
+ unsigned int nl;
+
+ modules[i].abfd = current;
+ modules[i].name = vms_get_module_name (current->filename, FALSE);
+ modules[i].ref = 1;
+
+ /* FIXME: silently truncate long names ? */
+ nl = strlen (modules[i].name);
+ modules[i].namlen = (nl > max_keylen ? max_keylen : nl);
+ }
+
+ /* Create the module index. */
+ vbn = 0;
+ if (!vms_write_index (NULL, modules, nbr_modules, &vbn, NULL, is_elfidx))
+ return FALSE;
+ nbr_mod_iblk = vbn;
+
+ /* Create symbol index. */
+ if (!_bfd_vms_lib_build_map (nbr_modules, modules, &nbr_symbols, &symbols))
+ return FALSE;
+
+ vbn = 0;
+ if (!vms_write_index (NULL, symbols, nbr_symbols, &vbn, NULL, is_elfidx))
+ return FALSE;
+ nbr_sym_iblk = vbn;
+
+ /* Write modules and remember their position. */
+ off = (1 + nbr_mod_iblk + nbr_sym_iblk) * VMS_BLOCK_SIZE;
+
+ if (bfd_seek (arch, off, SEEK_SET) != 0)
+ return FALSE;
+
+ for (i = 0; i < nbr_modules; i++)
+ {
+ struct vms_datadef data;
+ unsigned char blk[VMS_BLOCK_SIZE];
+ struct vms_mhd *mhd;
+ unsigned int sz;
+
+ current = modules[i].abfd;
+ current->proxy_origin = off;
+
+ if (is_elfidx)
+ sz = 0;
+ else
+ {
+ /* Write the MHD as a record (ie, size first). */
+ sz = 2;
+ bfd_putl16 (tdata->mhd_size, blk);
+ }
+ mhd = (struct vms_mhd *)(blk + sz);
+ memset (mhd, 0, sizeof (struct vms_mhd));
+ mhd->lbrflag = 0;
+ mhd->id = MHD__C_MHDID;
+ mhd->objidlng = 4;
+ memcpy (mhd->objid, "V1.0", 4);
+ bfd_putl32 (modules[i].ref, mhd->refcnt);
+ /* FIXME: datim. */
+
+ sz += tdata->mhd_size;
+ sz = (sz + 1) & ~1;
+
+ /* Rewind the member to be put into the archive. */
+ if (bfd_seek (current, 0, SEEK_SET) != 0)
+ goto input_err;
+
+ /* Copy the member into the archive. */
+ if (is_elfidx)
+ {
+ unsigned int modsize = 0;
+ bfd_size_type amt;
+ file_ptr off_hdr = off;
+
+ /* Read to complete the first block. */
+ amt = bfd_bread (blk + sz, VMS_BLOCK_SIZE - sz, current);
+ if (amt == (bfd_size_type)-1)
+ goto input_err;
+ modsize = amt;
+ if (amt < VMS_BLOCK_SIZE - sz)
+ {
+ /* The member size is less than a block. Pad the block. */
+ memset (blk + sz + amt, 0, VMS_BLOCK_SIZE - sz - amt);
+ }
+ bfd_putl32 (modsize, mhd->modsize);
+
+ /* Write the first block (which contains an mhd). */
+ if (bfd_bwrite (blk, VMS_BLOCK_SIZE, arch) != VMS_BLOCK_SIZE)
+ goto input_err;
+ off += VMS_BLOCK_SIZE;
+
+ if (amt == VMS_BLOCK_SIZE - sz)
+ {
+ /* Copy the remaining. */
+ char buffer[DEFAULT_BUFFERSIZE];
+
+ while (1)
+ {
+ amt = bfd_bread (buffer, sizeof (buffer), current);
+ if (amt == (bfd_size_type)-1)
+ goto input_err;
+ if (amt == 0)
+ break;
+ modsize += amt;
+ if (amt != sizeof (buffer))
+ {
+ /* Clear the padding. */
+ memset (buffer + amt, 0, sizeof (buffer) - amt);
+ amt = (amt + VMS_BLOCK_SIZE) & ~(VMS_BLOCK_SIZE - 1);
+ }
+ if (bfd_bwrite (buffer, amt, arch) != amt)
+ goto input_err;
+ off += amt;
+ }
+
+ /* Now that the size is known, write the first block (again). */
+ bfd_putl32 (modsize, mhd->modsize);
+ if (bfd_seek (arch, off_hdr, SEEK_SET) != 0
+ || bfd_bwrite (blk, VMS_BLOCK_SIZE, arch) != VMS_BLOCK_SIZE)
+ goto input_err;
+ if (bfd_seek (arch, off, SEEK_SET) != 0)
+ goto input_err;
+ }
+ }
+ else
+ {
+ /* Write the MHD. */
+ if (vms_write_data_block (arch, &data, &off, blk, sz, 0) < 0)
+ goto input_err;
+
+ /* Write the member. */
+ while (1)
+ {
+ sz = bfd_bread (blk, sizeof (blk), current);
+ if (sz == 0)
+ break;
+ if (vms_write_data_block (arch, &data, &off, blk, sz, 0) < 0)
+ goto input_err;
+ }
+
+ /* Write the end of module marker. */
+ if (vms_write_data_block (arch, &data, &off,
+ eotdesc, sizeof (eotdesc), 1) < 0)
+ goto input_err;
+ }
+ }
+
+ /* Write the indexes. */
+ vbn = 2;
+ if (vms_write_index (arch, modules, nbr_modules, &vbn, &mod_idx_vbn,
+ is_elfidx) != TRUE)
+ return FALSE;
+ if (vms_write_index (arch, symbols, nbr_symbols, &vbn, &sym_idx_vbn,
+ is_elfidx) != TRUE)
+ return FALSE;
+
+ /* Write libary header. */
+ {
+ unsigned char blk[VMS_BLOCK_SIZE];
+ struct vms_lhd *lhd = (struct vms_lhd *)blk;
+ struct vms_idd *idd = (struct vms_idd *)(blk + sizeof (*lhd));
+ unsigned int idd_flags;
+ unsigned int saneid;
+
+ memset (blk, 0, sizeof (blk));
+
+ lhd->type = tdata->type;
+ lhd->nindex = 2;
+ switch (tdata->kind)
+ {
+ case vms_lib_alpha:
+ saneid = LHD_SANEID3;
+ break;
+ case vms_lib_ia64:
+ saneid = LHD_SANEID6;
+ break;
+ default:
+ abort ();
+ }
+ bfd_putl32 (saneid, lhd->sanity);
+ bfd_putl16 (tdata->ver, lhd->majorid);
+ bfd_putl16 (0, lhd->minorid);
+ snprintf ((char *)lhd->lbrver + 1, sizeof (lhd->lbrver) - 1,
+ "GNU ar %u.%u.%u",
+ (unsigned)(BFD_VERSION / 100000000UL),
+ (unsigned)(BFD_VERSION / 1000000UL) % 100,
+ (unsigned)(BFD_VERSION / 10000UL) % 100);
+ lhd->lbrver[sizeof (lhd->lbrver) - 1] = 0;
+ lhd->lbrver[0] = strlen ((char *)lhd->lbrver + 1);
+
+ bfd_putl32 (tdata->credat_lo, lhd->credat + 0);
+ bfd_putl32 (tdata->credat_hi, lhd->credat + 4);
+ vms_raw_get_time (lhd->updtim);
+
+ lhd->mhdusz = tdata->mhd_size - MHD__C_USRDAT;
+
+ bfd_putl32 (nbr_modules + nbr_symbols, lhd->idxcnt);
+ bfd_putl32 (nbr_modules, lhd->modcnt);
+ bfd_putl32 (nbr_modules, lhd->modhdrs);
+
+ /* Number of blocks for index. */
+ bfd_putl32 (nbr_mod_iblk + nbr_sym_iblk, lhd->idxblks);
+ bfd_putl32 (vbn - 1, lhd->hipreal);
+ bfd_putl32 (vbn - 1, lhd->hiprusd);
+
+ /* VBN of the next free block. */
+ bfd_putl32 ((off / VMS_BLOCK_SIZE) + 1, lhd->nextvbn);
+ bfd_putl32 ((off / VMS_BLOCK_SIZE) + 1, lhd->nextrfa + 0);
+ bfd_putl16 (0, lhd->nextrfa + 4);
+
+ /* First index (modules name). */
+ idd_flags = IDD__FLAGS_ASCII | IDD__FLAGS_VARLENIDX
+ | IDD__FLAGS_NOCASECMP | IDD__FLAGS_NOCASENTR;
+ bfd_putl16 (idd_flags, idd->flags);
+ bfd_putl16 (max_keylen + 1, idd->keylen);
+ bfd_putl16 (mod_idx_vbn, idd->vbn);
+ idd++;
+
+ /* Second index (symbols name). */
+ bfd_putl16 (idd_flags, idd->flags);
+ bfd_putl16 (max_keylen + 1, idd->keylen);
+ bfd_putl16 (sym_idx_vbn, idd->vbn);
+ idd++;
+
+ if (vms_write_block (arch, 1, blk) != TRUE)
+ return FALSE;
+ }
+
+ return TRUE;
+
+ input_err:
+ bfd_set_error (bfd_error_on_input, current, bfd_get_error ());
+ return FALSE;
+}
+
+/* Add a target for text library. This costs almost nothing and is useful to
+ read VMS library on the host. */
+
+const bfd_target alpha_vms_lib_txt_vec =
+{
+ "vms-libtxt", /* Name. */
+ bfd_target_unknown_flavour,
+ BFD_ENDIAN_UNKNOWN, /* byteorder */
+ BFD_ENDIAN_UNKNOWN, /* header_byteorder */
+ 0, /* Object flags. */
+ 0, /* Sect flags. */
+ 0, /* symbol_leading_char. */
+ ' ', /* ar_pad_char. */
+ 15, /* ar_max_namelen. */
+ 0, /* match priority. */
+ 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, _bfd_dummy_target, /* bfd_check_format. */
+ _bfd_vms_lib_txt_archive_p, _bfd_dummy_target},
+ {bfd_false, bfd_false, bfd_false, bfd_false}, /* bfd_set_format. */
+ {bfd_false, bfd_false, bfd_false, bfd_false}, /* bfd_write_contents. */
+
+ BFD_JUMP_TABLE_GENERIC (_bfd_generic),
+ BFD_JUMP_TABLE_COPY (_bfd_generic),
+ BFD_JUMP_TABLE_CORE (_bfd_nocore),
+ BFD_JUMP_TABLE_ARCHIVE (_bfd_vms_lib),
+ BFD_JUMP_TABLE_SYMBOLS (_bfd_nosymbols),
+ BFD_JUMP_TABLE_RELOCS (_bfd_norelocs),
+ BFD_JUMP_TABLE_WRITE (_bfd_nowrite),
+ BFD_JUMP_TABLE_LINK (_bfd_nolink),
+ BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
+
+ NULL,
+
+ NULL
+};
diff --git a/bfd/vms-misc.c b/bfd/vms-misc.c
new file mode 100644
index 0000000..4581738
--- /dev/null
+++ b/bfd/vms-misc.c
@@ -0,0 +1,670 @@
+/* vms-misc.c -- BFD back-end for VMS/VAX (openVMS/VAX) and
+ EVAX (openVMS/Alpha) files.
+ Copyright (C) 1996-2014 Free Software Foundation, Inc.
+
+ Miscellaneous 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#if __STDC__
+#include <stdarg.h>
+#endif
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "bfdlink.h"
+#include "libbfd.h"
+#include "safe-ctype.h"
+
+#ifdef VMS
+#define __NEW_STARLET
+#include <rms.h>
+#include <unixlib.h>
+#include <gen64def.h>
+#include <starlet.h>
+#define RME$C_SETRFM 0x00000001
+#include <unistd.h>
+#endif
+#include <time.h>
+
+#include "vms.h"
+#include "vms/emh.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 indentation level. Indentation is performed
+ if level > 0. */
+
+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);
+}
+
+/* A debug function
+ hex dump 'size' bytes starting at 'ptr'. */
+
+void
+_bfd_hexdump (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");
+}
+#endif
+
+
+/* Copy sized string (string with fixed size) to new allocated area
+ size is string size (size of record) */
+
+char *
+_bfd_vms_save_sized_string (unsigned char *str, int size)
+{
+ char *newstr = bfd_malloc ((bfd_size_type) size + 1);
+
+ if (newstr == NULL)
+ return NULL;
+ memcpy (newstr, (char *) str, (size_t) size);
+ newstr[size] = 0;
+
+ return newstr;
+}
+
+/* Copy counted string (string with size at first byte) to new allocated area
+ ptr points to size byte on entry */
+
+char *
+_bfd_vms_save_counted_string (unsigned char *ptr)
+{
+ int len = *ptr++;
+
+ return _bfd_vms_save_sized_string (ptr, len);
+}
+
+/* Object output routines. */
+
+/* Begin new record.
+ Write 2 bytes rectype and 2 bytes record length. */
+
+void
+_bfd_vms_output_begin (struct vms_rec_wr *recwr, int rectype)
+{
+ vms_debug2 ((6, "_bfd_vms_output_begin (type %d)\n", rectype));
+
+ /* Record must have been closed. */
+ BFD_ASSERT (recwr->size == 0);
+
+ _bfd_vms_output_short (recwr, (unsigned int) rectype);
+
+ /* Placeholder for length. */
+ _bfd_vms_output_short (recwr, 0);
+}
+
+/* Begin new sub-record.
+ Write 2 bytes rectype, and 2 bytes record length. */
+
+void
+_bfd_vms_output_begin_subrec (struct vms_rec_wr *recwr, int rectype)
+{
+ vms_debug2 ((6, "_bfd_vms_output_begin_subrec (type %d)\n", rectype));
+
+ /* Subrecord must have been closed. */
+ BFD_ASSERT (recwr->subrec_offset == 0);
+
+ /* Save start of subrecord offset. */
+ recwr->subrec_offset = recwr->size;
+
+ /* Subrecord type. */
+ _bfd_vms_output_short (recwr, (unsigned int) rectype);
+
+ /* Placeholder for length. */
+ _bfd_vms_output_short (recwr, 0);
+}
+
+/* Set record/subrecord alignment. */
+
+void
+_bfd_vms_output_alignment (struct vms_rec_wr *recwr, int alignto)
+{
+ vms_debug2 ((6, "_bfd_vms_output_alignment (%d)\n", alignto));
+ recwr->align = alignto;
+}
+
+/* Align the size of the current record (whose length is LENGTH).
+ Warning: this obviously changes the record (and the possible subrecord)
+ length. */
+
+static void
+_bfd_vms_output_align (struct vms_rec_wr *recwr, unsigned int length)
+{
+ unsigned int real_size = recwr->size;
+ unsigned int aligncount;
+
+ /* Pad with 0 if alignment is required. */
+ aligncount = (recwr->align - (length % recwr->align)) % recwr->align;
+ vms_debug2 ((6, "align: adding %d bytes\n", aligncount));
+ while (aligncount-- > 0)
+ recwr->buf[real_size++] = 0;
+
+ recwr->size = real_size;
+}
+
+/* Ends current sub-record. Set length field. */
+
+void
+_bfd_vms_output_end_subrec (struct vms_rec_wr *recwr)
+{
+ int real_size = recwr->size;
+ int length;
+
+ /* Subrecord must be open. */
+ BFD_ASSERT (recwr->subrec_offset != 0);
+
+ length = real_size - recwr->subrec_offset;
+
+ if (length == 0)
+ return;
+
+ _bfd_vms_output_align (recwr, length);
+
+ /* Put length to buffer. */
+ bfd_putl16 ((bfd_vma) (recwr->size - recwr->subrec_offset),
+ recwr->buf + recwr->subrec_offset + 2);
+
+ /* Close the subrecord. */
+ recwr->subrec_offset = 0;
+}
+
+/* Ends current record (and write it). */
+
+void
+_bfd_vms_output_end (bfd *abfd, struct vms_rec_wr *recwr)
+{
+ vms_debug2 ((6, "_bfd_vms_output_end (size %u)\n", recwr->size));
+
+ /* Subrecord must have been closed. */
+ BFD_ASSERT (recwr->subrec_offset == 0);
+
+ if (recwr->size == 0)
+ return;
+
+ _bfd_vms_output_align (recwr, recwr->size);
+
+ /* Write the length word. */
+ bfd_putl16 ((bfd_vma) recwr->size, recwr->buf + 2);
+
+ /* File is open in undefined (UDF) format on VMS, but ultimately will be
+ converted to variable length (VAR) format. VAR format has a length
+ word first which must be explicitly output in UDF format. */
+ /* So, first the length word. */
+ bfd_bwrite (recwr->buf + 2, 2, abfd);
+
+ /* Align. */
+ if (recwr->size & 1)
+ recwr->buf[recwr->size++] = 0;
+
+ /* Then the record. */
+ bfd_bwrite (recwr->buf, (size_t) recwr->size, abfd);
+
+ recwr->size = 0;
+}
+
+/* Check remaining buffer size. Return what's left. */
+
+int
+_bfd_vms_output_check (struct vms_rec_wr *recwr, int size)
+{
+ vms_debug2 ((6, "_bfd_vms_output_check (%d)\n", size));
+
+ return (MAX_OUTREC_SIZE - (recwr->size + size + MIN_OUTREC_LUFT));
+}
+
+/* Output byte (8 bit) value. */
+
+void
+_bfd_vms_output_byte (struct vms_rec_wr *recwr, unsigned int value)
+{
+ vms_debug2 ((6, "_bfd_vms_output_byte (%02x)\n", value));
+
+ *(recwr->buf + recwr->size) = value;
+ recwr->size += 1;
+}
+
+/* Output short (16 bit) value. */
+
+void
+_bfd_vms_output_short (struct vms_rec_wr *recwr, unsigned int value)
+{
+ vms_debug2 ((6, "_bfd_vms_output_short (%04x)\n", value));
+
+ bfd_putl16 ((bfd_vma) value & 0xffff, recwr->buf + recwr->size);
+ recwr->size += 2;
+}
+
+/* Output long (32 bit) value. */
+
+void
+_bfd_vms_output_long (struct vms_rec_wr *recwr, unsigned long value)
+{
+ vms_debug2 ((6, "_bfd_vms_output_long (%08lx)\n", value));
+
+ bfd_putl32 ((bfd_vma) value, recwr->buf + recwr->size);
+ recwr->size += 4;
+}
+
+/* Output quad (64 bit) value. */
+
+void
+_bfd_vms_output_quad (struct vms_rec_wr *recwr, bfd_vma value)
+{
+ vms_debug2 ((6, "_bfd_vms_output_quad (%08lx)\n", (unsigned long)value));
+
+ bfd_putl64 (value, recwr->buf + recwr->size);
+ recwr->size += 8;
+}
+
+/* Output c-string as counted string. */
+
+void
+_bfd_vms_output_counted (struct vms_rec_wr *recwr, const char *value)
+{
+ int len;
+
+ vms_debug2 ((6, "_bfd_vms_output_counted (%s)\n", value));
+
+ 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 (recwr, (unsigned int) len & 0xff);
+ _bfd_vms_output_dump (recwr, (const unsigned char *)value, len);
+}
+
+/* Output character area. */
+
+void
+_bfd_vms_output_dump (struct vms_rec_wr *recwr, const unsigned char *data, int len)
+{
+ vms_debug2 ((6, "_bfd_vms_output_dump (%d)\n", len));
+
+ if (len == 0)
+ return;
+
+ memcpy (recwr->buf + recwr->size, data, (size_t) len);
+ recwr->size += len;
+}
+
+/* Output count bytes of value. */
+
+void
+_bfd_vms_output_fill (struct vms_rec_wr *recwr, int value, int count)
+{
+ vms_debug2 ((6, "_bfd_vms_output_fill (val %02x times %d)\n", value, count));
+
+ if (count == 0)
+ return;
+ memset (recwr->buf + recwr->size, value, (size_t) count);
+ recwr->size += count;
+}
+
+#ifdef VMS
+/* Convert the file to variable record length format. This is done
+ using undocumented system call sys$modify().
+ Pure VMS version. */
+
+static void
+vms_convert_to_var (char * vms_filename)
+{
+ struct FAB fab = cc$rms_fab;
+
+ fab.fab$l_fna = vms_filename;
+ fab.fab$b_fns = strlen (vms_filename);
+ fab.fab$b_fac = FAB$M_PUT;
+ fab.fab$l_fop = FAB$M_ESC;
+ fab.fab$l_ctx = RME$C_SETRFM;
+
+ sys$open (&fab);
+
+ fab.fab$b_rfm = FAB$C_VAR;
+
+ sys$modify (&fab);
+ sys$close (&fab);
+}
+
+static int
+vms_convert_to_var_1 (char *filename, int type)
+{
+ if (type != DECC$K_FILE)
+ return FALSE;
+ vms_convert_to_var (filename);
+ return TRUE;
+}
+
+/* Convert the file to variable record length format. This is done
+ using undocumented system call sys$modify().
+ Unix filename version. */
+
+int
+_bfd_vms_convert_to_var_unix_filename (const char *unix_filename)
+{
+ if (decc$to_vms (unix_filename, &vms_convert_to_var_1, 0, 1) != 1)
+ return FALSE;
+ return TRUE;
+}
+#endif /* VMS */
+
+/* Manufacture a VMS like time on a unix based system.
+ stolen from obj-vms.c. */
+
+unsigned char *
+get_vms_time_string (void)
+{
+ static unsigned char tbuf[18];
+#ifndef VMS
+ 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 ((char *) tbuf, "%2s-%3s-%s %s",
+ pnt + 8, pnt + 4, pnt + 20, pnt + 11);
+#else
+ struct
+ {
+ int Size;
+ unsigned char *Ptr;
+ } Descriptor;
+ Descriptor.Size = 17;
+ Descriptor.Ptr = tbuf;
+ SYS$ASCTIM (0, &Descriptor, 0, 0);
+#endif /* not VMS */
+
+ vms_debug2 ((6, "vmstimestring:'%s'\n", tbuf));
+
+ return tbuf;
+}
+
+/* Create module name from filename (ie, extract the basename and convert it
+ in upper cases). Works on both VMS and UNIX pathes.
+ The result has to be free(). */
+
+char *
+vms_get_module_name (const char *filename, bfd_boolean upcase)
+{
+ char *fname, *fptr;
+ const char *fout;
+
+ /* Strip VMS path. */
+ fout = strrchr (filename, ']');
+ if (fout == NULL)
+ fout = strchr (filename, ':');
+ if (fout != NULL)
+ fout++;
+ else
+ fout = filename;
+
+ /* Strip UNIX path. */
+ fptr = strrchr (fout, '/');
+ if (fptr != NULL)
+ fout = fptr + 1;
+
+ fname = strdup (fout);
+
+ /* Strip suffix. */
+ fptr = strrchr (fname, '.');
+ if (fptr != 0)
+ *fptr = 0;
+
+ /* Convert to upper case and truncate at 31 characters.
+ (VMS object file format restricts module name length to 31). */
+ fptr = fname;
+ for (fptr = fname; *fptr != 0; fptr++)
+ {
+ if (*fptr == ';' || (fptr - fname) >= 31)
+ {
+ *fptr = 0;
+ break;
+ }
+ if (upcase)
+ *fptr = TOUPPER (*fptr);
+ }
+ return fname;
+}
+
+/* Compared to usual UNIX time_t, VMS time has less limits:
+ - 64 bit (63 bits in fact as the MSB must be 0)
+ - 100ns granularity
+ - epoch is Nov 17, 1858.
+ Here has the constants and the routines used to convert VMS from/to UNIX time.
+ The conversion routines don't assume 64 bits arithmetic.
+
+ Here we assume that the definition of time_t is the UNIX one, ie integer
+ type, expressing seconds since the epoch. */
+
+/* UNIX time granularity for VMS, ie 1s / 100ns. */
+#define VMS_TIME_FACTOR 10000000
+
+/* Number of seconds since VMS epoch of the UNIX epoch. */
+#define VMS_TIME_OFFSET 3506716800U
+
+/* Convert a VMS time to a unix time. */
+
+time_t
+vms_time_to_time_t (unsigned int hi, unsigned int lo)
+{
+ unsigned int tmp;
+ unsigned int rlo;
+ int i;
+ time_t res;
+
+ /* First convert to seconds. */
+ tmp = hi % VMS_TIME_FACTOR;
+ hi = hi / VMS_TIME_FACTOR;
+ rlo = 0;
+ for (i = 0; i < 4; i++)
+ {
+ tmp = (tmp << 8) | (lo >> 24);
+ lo <<= 8;
+
+ rlo = (rlo << 8) | (tmp / VMS_TIME_FACTOR);
+ tmp %= VMS_TIME_FACTOR;
+ }
+ lo = rlo;
+
+ /* Return 0 in case of overflow. */
+ if (hi > 1
+ || (hi == 1 && lo >= VMS_TIME_OFFSET))
+ return 0;
+
+ /* Return 0 in case of underflow. */
+ if (hi == 0 && lo < VMS_TIME_OFFSET)
+ return 0;
+
+ res = lo - VMS_TIME_OFFSET;
+ if (res <= 0)
+ return 0;
+ return res;
+}
+
+/* Convert a time_t to a VMS time. */
+
+void
+vms_time_t_to_vms_time (time_t ut, unsigned int *hi, unsigned int *lo)
+{
+ unsigned short val[4];
+ unsigned short tmp[4];
+ unsigned int carry;
+ int i;
+
+ /* Put into val. */
+ val[0] = ut & 0xffff;
+ val[1] = (ut >> 16) & 0xffff;
+ val[2] = sizeof (ut) > 4 ? (ut >> 32) & 0xffff : 0;
+ val[3] = sizeof (ut) > 4 ? (ut >> 48) & 0xffff : 0;
+
+ /* Add offset. */
+ tmp[0] = VMS_TIME_OFFSET & 0xffff;
+ tmp[1] = VMS_TIME_OFFSET >> 16;
+ tmp[2] = 0;
+ tmp[3] = 0;
+ carry = 0;
+ for (i = 0; i < 4; i++)
+ {
+ carry += tmp[i] + val[i];
+ val[i] = carry & 0xffff;
+ carry = carry >> 16;
+ }
+
+ /* Multiply by factor, well first by 10000 and then by 1000. */
+ carry = 0;
+ for (i = 0; i < 4; i++)
+ {
+ carry += val[i] * 10000;
+ val[i] = carry & 0xffff;
+ carry = carry >> 16;
+ }
+ carry = 0;
+ for (i = 0; i < 4; i++)
+ {
+ carry += val[i] * 1000;
+ val[i] = carry & 0xffff;
+ carry = carry >> 16;
+ }
+
+ /* Write the result. */
+ *lo = val[0] | (val[1] << 16);
+ *hi = val[2] | (val[3] << 16);
+}
+
+/* Convert a raw (stored in a buffer) VMS time to a unix time. */
+
+time_t
+vms_rawtime_to_time_t (unsigned char *buf)
+{
+ unsigned int hi = bfd_getl32 (buf + 4);
+ unsigned int lo = bfd_getl32 (buf + 0);
+
+ return vms_time_to_time_t (hi, lo);
+}
+
+void
+vms_get_time (unsigned int *hi, unsigned int *lo)
+{
+#ifdef VMS
+ struct _generic_64 t;
+
+ sys$gettim (&t);
+ *lo = t.gen64$q_quadword;
+ *hi = t.gen64$q_quadword >> 32;
+#else
+ time_t t;
+
+ time (&t);
+ vms_time_t_to_vms_time (t, hi, lo);
+#endif
+}
+
+/* Get the current time into a raw buffer BUF. */
+
+void
+vms_raw_get_time (unsigned char *buf)
+{
+ unsigned int hi, lo;
+
+ vms_get_time (&hi, &lo);
+ bfd_putl32 (lo, buf + 0);
+ bfd_putl32 (hi, buf + 4);
+}
diff --git a/bfd/vms.h b/bfd/vms.h
new file mode 100644
index 0000000..58782e3
--- /dev/null
+++ b/bfd/vms.h
@@ -0,0 +1,142 @@
+/* vms.h -- Header file for VMS (Alpha and Vax) support.
+ Copyright (C) 1996-2014 Free Software Foundation, Inc.
+
+ Main header file.
+
+ 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#undef vms
+#ifndef VMS_H
+#define VMS_H
+
+#include <time.h>
+
+/* Size of a VMS block on disk. */
+
+#define VMS_BLOCK_SIZE 512
+
+/* Miscellaneous definitions. */
+
+#define MAX_OUTREC_SIZE 4096
+#define MIN_OUTREC_LUFT 64
+
+/* File format. */
+
+enum file_format_enum
+ {
+ /* Not yet known. */
+ FF_UNKNOWN,
+
+ /* Unix format. Each record is preceeded by the record length,
+ on 2 bytes. */
+ FF_FOREIGN,
+
+ /* Native (=VMS) format. The file only contains the content of the
+ records. This may also appear on Unix, depending on which tool
+ was used to transfer files. */
+ FF_NATIVE
+ };
+
+/* VMS records input buffer. */
+
+struct vms_rec_rd
+{
+ /* Buffer and its size. */
+ unsigned char *buf;
+ unsigned int buf_size;
+
+ /* Current record and its size. */
+ unsigned char *rec;
+ unsigned int rec_size;
+
+ /* Input file format. */
+ enum file_format_enum file_format;
+};
+
+/* VMS records output buffer. */
+
+struct vms_rec_wr
+{
+ /* Output buffer. */
+ unsigned char *buf;
+
+ /* Current length of the record. */
+ unsigned short int size;
+
+ /* Sub-record start offset. */
+ unsigned short int subrec_offset;
+
+ /* Some records must have a size that is a multiple of the alignment.
+ Mustn't be 0. */
+ unsigned short int align;
+};
+
+struct evax_private_udata_struct
+{
+ asymbol *bsym;
+ asymbol *enbsym;
+ char *origname;
+ int lkindex;
+};
+
+/* vms-misc.c. */
+
+#define VMS_DEBUG 1
+
+#if VMS_DEBUG
+extern void _bfd_vms_debug (int, char *, ...) ATTRIBUTE_PRINTF_2;
+extern void _bfd_hexdump (int, unsigned char *, int, int);
+
+#define vms_debug _bfd_vms_debug
+#define vms_debug2(X) _bfd_vms_debug X
+#else
+#define vms_debug2(X)
+#endif
+
+extern char * vms_get_module_name (const char *, bfd_boolean);
+extern unsigned char *get_vms_time_string (void);
+extern time_t vms_time_to_time_t (unsigned int hi, unsigned int lo);
+extern time_t vms_rawtime_to_time_t (unsigned char *);
+extern void vms_time_t_to_vms_time (time_t ut, unsigned int *hi, unsigned int *lo);
+extern void vms_get_time (unsigned int *hi, unsigned int *lo);
+extern void vms_raw_get_time (unsigned char *buf);
+
+extern char * _bfd_vms_save_sized_string (unsigned char *, int);
+extern char * _bfd_vms_save_counted_string (unsigned char *);
+extern void _bfd_vms_output_begin (struct vms_rec_wr *, int);
+extern void _bfd_vms_output_alignment (struct vms_rec_wr *, int);
+extern void _bfd_vms_output_begin_subrec (struct vms_rec_wr *, int);
+extern void _bfd_vms_output_end_subrec (struct vms_rec_wr *);
+extern void _bfd_vms_output_end (bfd *, struct vms_rec_wr *);
+extern int _bfd_vms_output_check (struct vms_rec_wr *, int);
+extern void _bfd_vms_output_byte (struct vms_rec_wr *, unsigned);
+extern void _bfd_vms_output_short (struct vms_rec_wr *, unsigned);
+extern void _bfd_vms_output_long (struct vms_rec_wr *, unsigned long);
+extern void _bfd_vms_output_quad (struct vms_rec_wr *, bfd_vma);
+extern void _bfd_vms_output_counted (struct vms_rec_wr *, const char *);
+extern void _bfd_vms_output_dump (struct vms_rec_wr *, const unsigned char *, int);
+extern void _bfd_vms_output_fill (struct vms_rec_wr *, int, int);
+extern int _bfd_vms_convert_to_var_unix_filename (const char *);
+
+/* vms-alpha.c */
+
+extern void bfd_vms_set_section_flags (bfd *, asection *, flagword, flagword);
+
+#endif /* VMS_H */
diff --git a/bfd/warning.m4 b/bfd/warning.m4
new file mode 100644
index 0000000..de7e9e4
--- /dev/null
+++ b/bfd/warning.m4
@@ -0,0 +1,80 @@
+dnl Common configure.ac fragment
+dnl
+dnl Copyright (C) 2012-2014 Free Software Foundation, Inc.
+dnl
+dnl This file is free software; you can redistribute it and/or modify
+dnl it under the terms of the GNU General Public License as published by
+dnl the Free Software Foundation; either version 3 of the License, or
+dnl (at your option) any later version.
+dnl
+dnl This program is distributed in the hope that it will be useful,
+dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
+dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+dnl GNU General Public License for more details.
+dnl
+dnl You should have received a copy of the GNU General Public License
+dnl along with this program; see the file COPYING3. If not see
+dnl <http://www.gnu.org/licenses/>.
+dnl
+
+AC_DEFUN([AM_BINUTILS_WARNINGS],[
+# Set the 'development' global.
+. $srcdir/../bfd/development.sh
+
+GCC_WARN_CFLAGS="-W -Wall -Wstrict-prototypes -Wmissing-prototypes"
+AC_EGREP_CPP([^[0-3]$],[__GNUC__],,GCC_WARN_CFLAGS="$GCC_WARN_CFLAGS -Wshadow")
+
+AC_ARG_ENABLE(werror,
+ [ --enable-werror treat compile warnings as errors],
+ [case "${enableval}" in
+ yes | y) ERROR_ON_WARNING="yes" ;;
+ no | n) ERROR_ON_WARNING="no" ;;
+ *) AC_MSG_ERROR(bad value ${enableval} for --enable-werror) ;;
+ esac])
+
+# Disable -Wformat by default when using gcc on mingw
+case "${host}" in
+ *-*-mingw32*)
+ if test "${GCC}" = yes -a -z "${ERROR_ON_WARNING}" ; then
+ GCC_WARN_CFLAGS="$GCC_WARN_CFLAGS -Wno-format"
+ fi
+ ;;
+ *) ;;
+esac
+
+# Enable -Werror by default when using gcc. Turn it off for releases.
+if test "${GCC}" = yes -a -z "${ERROR_ON_WARNING}" -a "$development" = true ; then
+ ERROR_ON_WARNING=yes
+fi
+
+NO_WERROR=
+if test "${ERROR_ON_WARNING}" = yes ; then
+ GCC_WARN_CFLAGS="$GCC_WARN_CFLAGS -Werror"
+ NO_WERROR="-Wno-error"
+fi
+
+if test "${GCC}" = yes ; then
+ WARN_CFLAGS="${GCC_WARN_CFLAGS}"
+fi
+
+AC_ARG_ENABLE(build-warnings,
+[ --enable-build-warnings enable build-time compiler warnings],
+[case "${enableval}" in
+ yes) WARN_CFLAGS="${GCC_WARN_CFLAGS}";;
+ no) if test "${GCC}" = yes ; then
+ WARN_CFLAGS="-w"
+ fi;;
+ ,*) t=`echo "${enableval}" | sed -e "s/,/ /g"`
+ WARN_CFLAGS="${GCC_WARN_CFLAGS} ${t}";;
+ *,) t=`echo "${enableval}" | sed -e "s/,/ /g"`
+ WARN_CFLAGS="${t} ${GCC_WARN_CFLAGS}";;
+ *) WARN_CFLAGS=`echo "${enableval}" | sed -e "s/,/ /g"`;;
+esac])
+
+if test x"$silent" != x"yes" && test x"$WARN_CFLAGS" != x""; then
+ echo "Setting warning flags = $WARN_CFLAGS" 6>&1
+fi
+
+AC_SUBST(WARN_CFLAGS)
+AC_SUBST(NO_WERROR)
+])
diff --git a/bfd/xcofflink.c b/bfd/xcofflink.c
new file mode 100644
index 0000000..9522974
--- /dev/null
+++ b/bfd/xcofflink.c
@@ -0,0 +1,6453 @@
+/* POWER/PowerPC XCOFF linker support.
+ Copyright (C) 1995-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "bfdlink.h"
+#include "libbfd.h"
+#include "coff/internal.h"
+#include "coff/xcoff.h"
+#include "libcoff.h"
+#include "libxcoff.h"
+#include "libiberty.h"
+
+/* This file holds the XCOFF linker code. */
+
+#undef STRING_SIZE_SIZE
+#define STRING_SIZE_SIZE 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 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;
+};
+
+/* 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 the XCOFF linker collects about an archive. */
+struct xcoff_archive_info
+{
+ /* The archive described by this entry. */
+ bfd *archive;
+
+ /* The import path and import filename to use when referring to
+ this archive in the .loader section. */
+ const char *imppath;
+ const char *impfile;
+
+ /* True if the archive contains a dynamic object. */
+ unsigned int contains_shared_object_p : 1;
+
+ /* True if the previous field is valid. */
+ unsigned int know_contains_shared_object_p : 1;
+};
+
+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. */
+ bfd_boolean textro;
+
+ /* Whether -brtl was specified. */
+ bfd_boolean rtld;
+
+ /* Whether garbage collection was done. */
+ bfd_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;
+
+ /* Information about archives. */
+ htab_t archive_info;
+
+ /* Magic sections: _text, _etext, _data, _edata, _end, end. */
+ asection *special_sections[XCOFF_NUMBER_OF_SPECIAL_SECTIONS];
+};
+
+/* 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. */
+ bfd_byte *ldsym;
+ /* Next .loader reloc to swap out. */
+ bfd_byte *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 bfd_boolean xcoff_mark (struct bfd_link_info *, asection *);
+
+
+
+/* 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 bfd_boolean
+xcoff_get_section_contents (bfd *abfd, asection *sec)
+{
+ if (coff_section_data (abfd, sec) == NULL)
+ {
+ bfd_size_type amt = sizeof (struct coff_section_tdata);
+
+ sec->used_by_bfd = bfd_zalloc (abfd, amt);
+ if (sec->used_by_bfd == NULL)
+ return FALSE;
+ }
+
+ if (coff_section_data (abfd, sec)->contents == NULL)
+ {
+ bfd_byte *contents;
+
+ if (! bfd_malloc_and_get_section (abfd, sec, &contents))
+ {
+ if (contents != NULL)
+ free (contents);
+ return FALSE;
+ }
+ coff_section_data (abfd, sec)->contents = contents;
+ }
+
+ return TRUE;
+}
+
+/* Get the size required to hold the dynamic symbols. */
+
+long
+_bfd_xcoff_get_dynamic_symtab_upper_bound (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;
+
+ bfd_xcoff_swap_ldhdr_in (abfd, (void *) contents, &ldhdr);
+
+ return (ldhdr.l_nsyms + 1) * sizeof (asymbol *);
+}
+
+/* Get the dynamic symbols. */
+
+long
+_bfd_xcoff_canonicalize_dynamic_symtab (bfd *abfd, asymbol **psyms)
+{
+ asection *lsec;
+ bfd_byte *contents;
+ struct internal_ldhdr ldhdr;
+ const char *strings;
+ bfd_byte *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;
+
+ bfd_xcoff_swap_ldhdr_in (abfd, contents, &ldhdr);
+
+ strings = (char *) contents + ldhdr.l_stoff;
+
+ symbuf = bfd_zalloc (abfd, ldhdr.l_nsyms * sizeof (* symbuf));
+ if (symbuf == NULL)
+ return -1;
+
+ elsym = contents + bfd_xcoff_loader_symbol_offset(abfd, &ldhdr);
+
+ elsymend = elsym + ldhdr.l_nsyms * bfd_xcoff_ldsymsz(abfd);
+ for (; elsym < elsymend; elsym += bfd_xcoff_ldsymsz(abfd), symbuf++, psyms++)
+ {
+ struct internal_ldsym ldsym;
+
+ bfd_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
+ {
+ char *c;
+
+ c = bfd_alloc (abfd, (bfd_size_type) 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)
+ {
+ if ((ldsym.l_smtype & L_WEAK) != 0)
+ symbuf->symbol.flags |= BSF_WEAK;
+ else
+ 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 (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;
+
+ bfd_xcoff_swap_ldhdr_in (abfd, (struct external_ldhdr *) contents, &ldhdr);
+
+ return (ldhdr.l_nreloc + 1) * sizeof (arelent *);
+}
+
+/* Get the dynamic relocs. */
+
+long
+_bfd_xcoff_canonicalize_dynamic_reloc (bfd *abfd,
+ arelent **prelocs,
+ asymbol **syms)
+{
+ asection *lsec;
+ bfd_byte *contents;
+ struct internal_ldhdr ldhdr;
+ arelent *relbuf;
+ bfd_byte *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;
+
+ bfd_xcoff_swap_ldhdr_in (abfd, contents, &ldhdr);
+
+ relbuf = bfd_alloc (abfd, ldhdr.l_nreloc * sizeof (arelent));
+ if (relbuf == NULL)
+ return -1;
+
+ elrel = contents + bfd_xcoff_loader_reloc_offset(abfd, &ldhdr);
+
+ elrelend = elrel + ldhdr.l_nreloc * bfd_xcoff_ldrelsz(abfd);
+ for (; elrel < elrelend; elrel += bfd_xcoff_ldrelsz(abfd), relbuf++,
+ prelocs++)
+ {
+ struct internal_ldrel ldrel;
+
+ bfd_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 = bfd_xcoff_dynamic_reloc_howto(abfd);
+
+ /* FIXME: We have no way to record the l_rsecnm field. */
+
+ *prelocs = relbuf;
+ }
+
+ *prelocs = NULL;
+
+ return ldhdr.l_nreloc;
+}
+
+/* Hash functions for xcoff_link_hash_table's archive_info. */
+
+static hashval_t
+xcoff_archive_info_hash (const void *data)
+{
+ const struct xcoff_archive_info *info;
+
+ info = (const struct xcoff_archive_info *) data;
+ return htab_hash_pointer (info->archive);
+}
+
+static int
+xcoff_archive_info_eq (const void *data1, const void *data2)
+{
+ const struct xcoff_archive_info *info1;
+ const struct xcoff_archive_info *info2;
+
+ info1 = (const struct xcoff_archive_info *) data1;
+ info2 = (const struct xcoff_archive_info *) data2;
+ return info1->archive == info2->archive;
+}
+
+/* Return information about archive ARCHIVE. Return NULL on error. */
+
+static struct xcoff_archive_info *
+xcoff_get_archive_info (struct bfd_link_info *info, bfd *archive)
+{
+ struct xcoff_link_hash_table *htab;
+ struct xcoff_archive_info *entryp, entry;
+ void **slot;
+
+ htab = xcoff_hash_table (info);
+ entry.archive = archive;
+ slot = htab_find_slot (htab->archive_info, &entry, INSERT);
+ if (!slot)
+ return NULL;
+
+ entryp = *slot;
+ if (!entryp)
+ {
+ entryp = bfd_zalloc (archive, sizeof (entry));
+ if (!entryp)
+ return NULL;
+
+ entryp->archive = archive;
+ *slot = entryp;
+ }
+ return entryp;
+}
+
+/* Routine to create an entry in an XCOFF link hash table. */
+
+static struct bfd_hash_entry *
+xcoff_link_hash_newfunc (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 == NULL)
+ ret = bfd_hash_allocate (table, sizeof (* ret));
+ if (ret == NULL)
+ return NULL;
+
+ /* 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;
+}
+
+/* Destroy an XCOFF link hash table. */
+
+static void
+_bfd_xcoff_bfd_link_hash_table_free (bfd *obfd)
+{
+ struct xcoff_link_hash_table *ret;
+
+ ret = (struct xcoff_link_hash_table *) obfd->link.hash;
+ if (ret->archive_info)
+ htab_delete (ret->archive_info);
+ if (ret->debug_strtab)
+ _bfd_stringtab_free (ret->debug_strtab);
+ _bfd_generic_link_hash_table_free (obfd);
+}
+
+/* Create an XCOFF link hash table. */
+
+struct bfd_link_hash_table *
+_bfd_xcoff_bfd_link_hash_table_create (bfd *abfd)
+{
+ struct xcoff_link_hash_table *ret;
+ bfd_size_type amt = sizeof (* ret);
+
+ ret = bfd_zmalloc (amt);
+ if (ret == NULL)
+ return NULL;
+ if (!_bfd_link_hash_table_init (&ret->root, abfd, xcoff_link_hash_newfunc,
+ sizeof (struct xcoff_link_hash_entry)))
+ {
+ free (ret);
+ return NULL;
+ }
+
+ ret->debug_strtab = _bfd_xcoff_stringtab_init ();
+ ret->archive_info = htab_create (37, xcoff_archive_info_hash,
+ xcoff_archive_info_eq, NULL);
+ if (!ret->debug_strtab || !ret->archive_info)
+ {
+ _bfd_xcoff_bfd_link_hash_table_free (abfd);
+ return NULL;
+ }
+ ret->root.hash_table_free = _bfd_xcoff_bfd_link_hash_table_free;
+
+ /* 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;
+}
+
+/* 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 (bfd *abfd,
+ asection *sec,
+ bfd_boolean cache,
+ bfd_byte *external_relocs,
+ bfd_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, 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);
+}
+
+/* Split FILENAME into an import path and an import filename,
+ storing them in *IMPPATH and *IMPFILE respectively. */
+
+bfd_boolean
+bfd_xcoff_split_import_path (bfd *abfd, const char *filename,
+ const char **imppath, const char **impfile)
+{
+ const char *base;
+ size_t length;
+ char *path;
+
+ base = lbasename (filename);
+ length = base - filename;
+ if (length == 0)
+ /* The filename has no directory component, so use an empty path. */
+ *imppath = "";
+ else if (length == 1)
+ /* The filename is in the root directory. */
+ *imppath = "/";
+ else
+ {
+ /* Extract the (non-empty) directory part. Note that we don't
+ need to strip duplicate directory separators from any part
+ of the string; the native linker doesn't do that either. */
+ path = bfd_alloc (abfd, length);
+ if (path == NULL)
+ return FALSE;
+ memcpy (path, filename, length - 1);
+ path[length - 1] = 0;
+ *imppath = path;
+ }
+ *impfile = base;
+ return TRUE;
+}
+
+/* Set ARCHIVE's import path as though its filename had been given
+ as FILENAME. */
+
+bfd_boolean
+bfd_xcoff_set_archive_import_path (struct bfd_link_info *info,
+ bfd *archive, const char *filename)
+{
+ struct xcoff_archive_info *archive_info;
+
+ archive_info = xcoff_get_archive_info (info, archive);
+ return (archive_info != NULL
+ && bfd_xcoff_split_import_path (archive, filename,
+ &archive_info->imppath,
+ &archive_info->impfile));
+}
+
+/* H is an imported symbol. Set the import module's path, file and member
+ to IMPATH, IMPFILE and IMPMEMBER respectively. All three are null if
+ no specific import module is specified. */
+
+static bfd_boolean
+xcoff_set_import_path (struct bfd_link_info *info,
+ struct xcoff_link_hash_entry *h,
+ const char *imppath, const char *impfile,
+ const char *impmember)
+{
+ unsigned int c;
+ struct xcoff_import_file **pp;
+
+ /* 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
+ {
+ /* 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 (filename_cmp ((*pp)->path, imppath) == 0
+ && filename_cmp ((*pp)->file, impfile) == 0
+ && filename_cmp ((*pp)->member, impmember) == 0)
+ break;
+ }
+
+ if (*pp == NULL)
+ {
+ struct xcoff_import_file *n;
+ bfd_size_type amt = sizeof (* n);
+
+ n = bfd_alloc (info->output_bfd, amt);
+ if (n == NULL)
+ return FALSE;
+ n->next = NULL;
+ n->path = imppath;
+ n->file = impfile;
+ n->member = impmember;
+ *pp = n;
+ }
+ h->ldindx = c;
+ }
+ return TRUE;
+}
+
+/* H is the bfd symbol associated with exported .loader symbol LDSYM.
+ Return true if LDSYM defines H. */
+
+static bfd_boolean
+xcoff_dynamic_definition_p (struct xcoff_link_hash_entry *h,
+ struct internal_ldsym *ldsym)
+{
+ /* If we didn't know about H before processing LDSYM, LDSYM
+ definitely defines H. */
+ if (h->root.type == bfd_link_hash_new)
+ return TRUE;
+
+ /* If H is currently a weak dynamic symbol, and if LDSYM is a strong
+ dynamic symbol, LDSYM trumps the current definition of H. */
+ if ((ldsym->l_smtype & L_WEAK) == 0
+ && (h->flags & XCOFF_DEF_DYNAMIC) != 0
+ && (h->flags & XCOFF_DEF_REGULAR) == 0
+ && (h->root.type == bfd_link_hash_defweak
+ || h->root.type == bfd_link_hash_undefweak))
+ return TRUE;
+
+ /* If H is currently undefined, LDSYM defines it. */
+ if ((h->flags & XCOFF_DEF_DYNAMIC) == 0
+ && (h->root.type == bfd_link_hash_undefined
+ || h->root.type == bfd_link_hash_undefweak))
+ return TRUE;
+
+ return FALSE;
+}
+
+/* This function is used to add symbols from a dynamic object to the
+ global symbol table. */
+
+static bfd_boolean
+xcoff_link_add_dynamic_symbols (bfd *abfd, struct bfd_link_info *info)
+{
+ asection *lsec;
+ bfd_byte *contents;
+ struct internal_ldhdr ldhdr;
+ const char *strings;
+ bfd_byte *elsym, *elsymend;
+ struct xcoff_import_file *n;
+ 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->output_bfd->xvec != 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;
+ contents = coff_section_data (abfd, lsec)->contents;
+
+ /* Remove the sections from this object, so that they do not get
+ included in the link. */
+ bfd_section_list_clear (abfd);
+
+ bfd_xcoff_swap_ldhdr_in (abfd, contents, &ldhdr);
+
+ strings = (char *) contents + ldhdr.l_stoff;
+
+ elsym = contents + bfd_xcoff_loader_symbol_offset(abfd, &ldhdr);
+
+ elsymend = elsym + ldhdr.l_nsyms * bfd_xcoff_ldsymsz(abfd);
+
+ for (; elsym < elsymend; elsym += bfd_xcoff_ldsymsz(abfd))
+ {
+ struct internal_ldsym ldsym;
+ char nambuf[SYMNMLEN + 1];
+ const char *name;
+ struct xcoff_link_hash_entry *h;
+
+ bfd_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;
+
+ if (!xcoff_dynamic_definition_p (h, &ldsym))
+ continue;
+
+ h->flags |= XCOFF_DEF_DYNAMIC;
+ h->smclas = ldsym.l_smclas;
+ if (h->smclas == XMC_XO)
+ {
+ /* This symbol has an absolute value. */
+ if ((ldsym.l_smtype & L_WEAK) != 0)
+ h->root.type = bfd_link_hash_defweak;
+ else
+ h->root.type = bfd_link_hash_defined;
+ h->root.u.def.section = bfd_abs_section_ptr;
+ h->root.u.def.value = ldsym.l_value;
+ }
+ else
+ {
+ /* Otherwise, we don't bother to actually define the symbol,
+ since we don't have a section to put it in anyhow.
+ We assume instead that an undefined XCOFF_DEF_DYNAMIC symbol
+ should be imported from the symbol's undef.abfd. */
+ if ((ldsym.l_smtype & L_WEAK) != 0)
+ h->root.type = bfd_link_hash_undefweak;
+ else
+ h->root.type = bfd_link_hash_undefined;
+ h->root.u.undef.abfd = abfd;
+ }
+
+ /* 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 ((bfd_size_type) 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;
+
+ hds->descriptor = h;
+ h->descriptor = hds;
+ }
+
+ if (xcoff_dynamic_definition_p (hds, &ldsym))
+ {
+ hds->root.type = h->root.type;
+ hds->flags |= XCOFF_DEF_DYNAMIC;
+ if (h->smclas == XMC_XO)
+ {
+ /* An absolute symbol appears to actually define code, not a
+ function descriptor. This is how some math functions are
+ implemented on AIX 4.1. */
+ hds->smclas = XMC_XO;
+ hds->root.u.def.section = bfd_abs_section_ptr;
+ hds->root.u.def.value = ldsym.l_value;
+ }
+ else
+ {
+ hds->smclas = XMC_PR;
+ hds->root.u.undef.abfd = abfd;
+ /* We do not want to add this to the undefined
+ symbol list. */
+ }
+ }
+ }
+ }
+
+ if (contents != 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 = bfd_alloc (abfd, (bfd_size_type) sizeof (struct xcoff_import_file));
+ if (n == NULL)
+ return FALSE;
+ n->next = NULL;
+
+ if (abfd->my_archive == NULL)
+ {
+ if (!bfd_xcoff_split_import_path (abfd, abfd->filename,
+ &n->path, &n->file))
+ return FALSE;
+ n->member = "";
+ }
+ else
+ {
+ struct xcoff_archive_info *archive_info;
+
+ archive_info = xcoff_get_archive_info (info, abfd->my_archive);
+ if (!archive_info->impfile)
+ {
+ if (!bfd_xcoff_split_import_path (archive_info->archive,
+ archive_info->archive->filename,
+ &archive_info->imppath,
+ &archive_info->impfile))
+ return FALSE;
+ }
+ n->path = archive_info->imppath;
+ n->file = archive_info->impfile;
+ n->member = bfd_get_filename (abfd);
+ }
+
+ /* 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;
+}
+
+/* xcoff_link_create_extra_sections
+
+ Takes care of creating the .loader, .gl, .ds, .debug and sections. */
+
+static bfd_boolean
+xcoff_link_create_extra_sections (bfd * abfd, struct bfd_link_info *info)
+{
+ bfd_boolean return_value = FALSE;
+
+ if (info->output_bfd->xvec == 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 (!info->relocatable
+ && xcoff_hash_table (info)->loader_section == NULL)
+ {
+ asection *lsec;
+ flagword flags = SEC_HAS_CONTENTS | SEC_IN_MEMORY;
+
+ lsec = bfd_make_section_anyway_with_flags (abfd, ".loader", flags);
+ if (lsec == NULL)
+ goto end_return;
+
+ xcoff_hash_table (info)->loader_section = lsec;
+ }
+
+ /* Likewise for the linkage section. */
+ if (xcoff_hash_table (info)->linkage_section == NULL)
+ {
+ asection *lsec;
+ flagword flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS
+ | SEC_IN_MEMORY);
+
+ lsec = bfd_make_section_anyway_with_flags (abfd, ".gl", flags);
+ if (lsec == NULL)
+ goto end_return;
+
+ xcoff_hash_table (info)->linkage_section = lsec;
+ lsec->alignment_power = 2;
+ }
+
+ /* Likewise for the TOC section. */
+ if (xcoff_hash_table (info)->toc_section == NULL)
+ {
+ asection *tsec;
+ flagword flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS
+ | SEC_IN_MEMORY);
+
+ tsec = bfd_make_section_anyway_with_flags (abfd, ".tc", flags);
+ if (tsec == NULL)
+ goto end_return;
+
+ xcoff_hash_table (info)->toc_section = tsec;
+ tsec->alignment_power = 2;
+ }
+
+ /* Likewise for the descriptor section. */
+ if (xcoff_hash_table (info)->descriptor_section == NULL)
+ {
+ asection *dsec;
+ flagword flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS
+ | SEC_IN_MEMORY);
+
+ dsec = bfd_make_section_anyway_with_flags (abfd, ".ds", flags);
+ if (dsec == NULL)
+ goto end_return;
+
+ xcoff_hash_table (info)->descriptor_section = dsec;
+ dsec->alignment_power = 2;
+ }
+
+ /* Likewise for the .debug section. */
+ if (xcoff_hash_table (info)->debug_section == NULL
+ && info->strip != strip_all)
+ {
+ asection *dsec;
+ flagword flags = SEC_HAS_CONTENTS | SEC_IN_MEMORY;
+
+ dsec = bfd_make_section_anyway_with_flags (abfd, ".debug", flags);
+ if (dsec == NULL)
+ goto end_return;
+
+ xcoff_hash_table (info)->debug_section = dsec;
+ }
+ }
+
+ return_value = TRUE;
+
+ end_return:
+
+ return return_value;
+}
+
+/* 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 (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 bfd_boolean
+xcoff_link_add_symbols (bfd *abfd, struct bfd_link_info *info)
+{
+ unsigned int n_tmask;
+ unsigned int n_btshft;
+ bfd_boolean default_copy;
+ bfd_size_type symcount;
+ struct xcoff_link_hash_entry **sym_hash;
+ asection **csect_cache;
+ unsigned int *lineno_counts;
+ bfd_size_type linesz;
+ asection *o;
+ asection *last_real;
+ bfd_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;
+ bfd_size_type amt;
+
+ 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;
+ }
+
+ /* Create the loader, toc, gl, ds and debug sections, if needed. */
+ if (! xcoff_link_create_extra_sections (abfd, info))
+ goto error_return;
+
+ 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. */
+ amt = symcount * sizeof (struct xcoff_link_hash_entry *);
+ sym_hash = bfd_zalloc (abfd, amt);
+ if (sym_hash == NULL && symcount != 0)
+ goto error_return;
+ coff_data (abfd)->sym_hashes = (struct coff_link_hash_entry **) sym_hash;
+
+ /* 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. */
+ amt = symcount * sizeof (asection *);
+ csect_cache = bfd_zalloc (abfd, amt);
+ if (csect_cache == NULL && symcount != 0)
+ goto error_return;
+ xcoff_data (abfd)->csects = csect_cache;
+
+ /* We garbage-collect line-number information on a symbol-by-symbol
+ basis, so we need to have quick access to the number of entries
+ per symbol. */
+ amt = symcount * sizeof (unsigned int);
+ lineno_counts = bfd_zalloc (abfd, amt);
+ if (lineno_counts == NULL && symcount != 0)
+ goto error_return;
+ xcoff_data (abfd)->lineno_counts = lineno_counts;
+
+ /* 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. */
+ amt = abfd->section_count + 1;
+ amt *= sizeof (struct reloc_info_struct);
+ reloc_info = bfd_zmalloc (amt);
+ if (reloc_info == NULL)
+ goto error_return;
+
+ /* 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, NULL, FALSE, NULL);
+ amt = o->reloc_count;
+ amt *= sizeof (asection *);
+ reloc_info[o->target_index].csects = bfd_zmalloc (amt);
+ if (reloc_info[o->target_index].csects == NULL)
+ goto error_return;
+ }
+
+ if ((info->strip == strip_none || info->strip == strip_some)
+ && o->lineno_count > 0)
+ {
+ bfd_byte *linenos;
+
+ amt = linesz * o->lineno_count;
+ linenos = bfd_malloc (amt);
+ if (linenos == NULL)
+ goto error_return;
+ reloc_info[o->target_index].linenos = linenos;
+ if (bfd_seek (abfd, o->line_filepos, SEEK_SET) != 0
+ || bfd_bread (linenos, amt, abfd) != amt)
+ 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;
+ asection *section;
+ bfd_vma value;
+ struct xcoff_link_hash_entry *set_toc;
+
+ bfd_coff_swap_sym_in (abfd, (void *) esym, (void *) &sym);
+
+ /* In this pass we are only interested in symbols with csect
+ information. */
+ if (!CSECT_SYM_P (sym.n_sclass))
+ {
+ /* Set csect_cache,
+ Normally csect is a .pr, .rw etc. created in the loop
+ If C_FILE or first time, handle special
+
+ Advance esym, sym_hash, csect_hash ptrs. */
+ if (sym.n_sclass == C_FILE || sym.n_sclass == C_DWARF)
+ csect = NULL;
+ if (csect != NULL)
+ *csect_cache = csect;
+ else if (first_csect == NULL
+ || sym.n_sclass == C_FILE || sym.n_sclass == C_DWARF)
+ *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;
+ lineno_counts += 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, (void *) (esym + symesz),
+ sym.n_type, sym.n_sclass,
+ 0, sym.n_numaux, (void *) &auxlin);
+
+ if (auxlin.x_sym.x_fcnary.x_fcn.x_lnnoptr != 0)
+ {
+ asection *enclosing;
+ bfd_signed_vma linoff;
+
+ enclosing = xcoff_section_data (abfd, csect)->enclosing;
+ if (enclosing == NULL)
+ {
+ (*_bfd_error_handler)
+ (_("%B: `%s' has line numbers but no enclosing section"),
+ 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);
+ /* Explicit cast to bfd_signed_vma for compiler. */
+ if (linoff < (bfd_signed_vma) (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, (void *) linpstart, (void *) &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, (void *) linp,
+ (void *) &lin);
+ if (lin.l_lnno == 0)
+ break;
+ }
+ *lineno_counts = (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)
+ (_("%B: class %d symbol `%s' has no aux entries"),
+ abfd, sym.n_sclass, name);
+ bfd_set_error (bfd_error_bad_value);
+ goto error_return;
+ }
+
+ bfd_coff_swap_aux_in (abfd,
+ (void *) (esym + symesz * sym.n_numaux),
+ sym.n_type, sym.n_sclass,
+ sym.n_numaux - 1, sym.n_numaux,
+ (void *) &aux);
+
+ smtyp = SMTYP_SMTYP (aux.x_csect.x_smtyp);
+
+ section = NULL;
+ value = 0;
+ set_toc = NULL;
+
+ switch (smtyp)
+ {
+ default:
+ (*_bfd_error_handler)
+ (_("%B: symbol `%s' has unrecognized csect type %d"),
+ 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)
+ (_("%B: bad XTY_ER symbol `%s': class %d scnum %d scnlen %d"),
+ 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:
+ csect = NULL;
+ csect_index = -(unsigned) 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)
+ (_("%B: XMC_TC0 symbol `%s' is class %d scnlen %d"),
+ 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 or 8 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.
+
+ Logic for 32 bit vs 64 bit.
+ 32 bit has a csect length of 4 for TOC
+ 64 bit has a csect length of 8 for TOC
+
+ The conditions to get past the if-check are not that bad.
+ They are what is used to create the TOC csects in the first
+ place. */
+ if (aux.x_csect.x_smclas == XMC_TC
+ && sym.n_sclass == C_HIDEXT
+ && info->output_bfd->xvec == abfd->xvec
+ && ((bfd_xcoff_is_xcoff32 (abfd)
+ && aux.x_csect.x_scnlen.l == 4)
+ || (bfd_xcoff_is_xcoff64 (abfd)
+ && aux.x_csect.x_scnlen.l == 8)))
+ {
+ 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;
+ amt = enclosing->reloc_count;
+ relindx = xcoff_find_reloc (relocs, amt, sym.n_value);
+ rel = relocs + relindx;
+
+ /* 32 bit R_POS r_size is 31
+ 64 bit R_POS r_size is 63 */
+ if (relindx < enclosing->reloc_count
+ && rel->r_vaddr == (bfd_vma) sym.n_value
+ && rel->r_type == R_POS
+ && ((bfd_xcoff_is_xcoff32 (abfd)
+ && rel->r_size == 31)
+ || (bfd_xcoff_is_xcoff64 (abfd)
+ && rel->r_size == 63)))
+ {
+ 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, (void *) erelsym, (void *) &relsym);
+ if (EXTERN_SYM_P (relsym.n_sclass))
+ {
+ const char *relname;
+ char relbuf[SYMNMLEN + 1];
+ bfd_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;
+ }
+ }
+ }
+ }
+
+ {
+ asection *enclosing;
+
+ /* 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. */
+
+ csect = bfd_xcoff_create_csect_from_smclas(abfd, &aux, name);
+ if (NULL == csect)
+ goto error_return;
+
+ /* The enclosing section is the main section : .data, .text
+ or .bss that the csect is coming from. */
+ 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->size)))
+ {
+ (*_bfd_error_handler)
+ (_("%B: csect `%s' not in enclosing section"),
+ 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->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. */
+ amt = sizeof (struct coff_section_tdata);
+ csect->used_by_bfd = bfd_zalloc (abfd, amt);
+ if (csect->used_by_bfd == NULL)
+ goto error_return;
+ amt = sizeof (struct xcoff_section_tdata);
+ coff_section_data (abfd, csect)->tdata = bfd_zalloc (abfd, amt);
+ 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;
+ amt = enclosing->reloc_count;
+ relindx = xcoff_find_reloc (relocs, amt, 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->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 external, we treat it as starting at the
+ beginning of the newly created section. */
+ if (EXTERN_SYM_P (sym.n_sclass))
+ {
+ 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. Usually the XTY_LD symbol will
+ follow its appropriate XTY_SD symbol. The .set pseudo op can
+ cause the XTY_LD to not follow the XTY_SD symbol. */
+ {
+ bfd_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)
+ (_("%B: misplaced XTY_LD `%s'"),
+ abfd, name);
+ bfd_set_error (bfd_error_bad_value);
+ goto error_return;
+ }
+ csect = section;
+ 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 (aux.x_csect.x_smclas == XMC_TD)
+ {
+ /* The linker script puts the .td section in the data
+ section after the .tc section. */
+ csect = bfd_make_section_anyway_with_flags (abfd, ".td",
+ SEC_ALLOC);
+ }
+ else
+ csect = bfd_make_section_anyway_with_flags (abfd, ".bss",
+ SEC_ALLOC);
+
+ if (csect == NULL)
+ goto error_return;
+ csect->vma = sym.n_value;
+ csect->size = aux.x_csect.x_scnlen.l;
+ 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);
+
+ amt = sizeof (struct coff_section_tdata);
+ csect->used_by_bfd = bfd_zalloc (abfd, amt);
+ if (csect->used_by_bfd == NULL)
+ goto error_return;
+ amt = sizeof (struct xcoff_section_tdata);
+ coff_section_data (abfd, csect)->tdata = bfd_zalloc (abfd, amt);
+ 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 (EXTERN_SYM_P (sym.n_sclass))
+ {
+ csect->flags |= SEC_IS_COMMON;
+ csect->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 = -1;
+
+ if (name[0] == '_')
+ {
+ if (strcmp (name, "_text") == 0)
+ i = XCOFF_SPECIAL_SECTION_TEXT;
+ else if (strcmp (name, "_etext") == 0)
+ i = XCOFF_SPECIAL_SECTION_ETEXT;
+ else if (strcmp (name, "_data") == 0)
+ i = XCOFF_SPECIAL_SECTION_DATA;
+ else if (strcmp (name, "_edata") == 0)
+ i = XCOFF_SPECIAL_SECTION_EDATA;
+ else if (strcmp (name, "_end") == 0)
+ i = XCOFF_SPECIAL_SECTION_END;
+ }
+ else if (name[0] == 'e' && strcmp (name, "end") == 0)
+ i = XCOFF_SPECIAL_SECTION_END2;
+
+ 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 (EXTERN_SYM_P (sym.n_sclass))
+ {
+ bfd_boolean copy;
+ flagword flags;
+
+ 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;
+
+ /* Ignore global linkage code when linking statically. */
+ if (info->static_link
+ && (smtyp == XTY_SD || smtyp == XTY_LD)
+ && aux.x_csect.x_smclas == XMC_GL)
+ {
+ section = bfd_und_section_ptr;
+ value = 0;
+ }
+
+ /* 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. */
+ else if (info->output_bfd->xvec == abfd->xvec)
+ {
+ if (! bfd_is_und_section (section))
+ *sym_hash = xcoff_link_hash_lookup (xcoff_hash_table (info),
+ name, TRUE, copy, FALSE);
+ else
+ /* Make a copy of the symbol name to prevent problems with
+ merging symbols. */
+ *sym_hash = ((struct xcoff_link_hash_entry *)
+ bfd_wrapped_link_hash_lookup (abfd, info, name,
+ TRUE, TRUE, 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 (((*sym_hash)->flags & XCOFF_DEF_REGULAR) == 0
+ && ((*sym_hash)->flags & XCOFF_DEF_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.n_sclass == C_AIX_WEAKEXT
+ || (*sym_hash)->root.type == bfd_link_hash_defweak)
+ {
+ /* At least one of the definitions is weak.
+ Allow the normal rules to take effect. */
+ }
+ else if ((*sym_hash)->root.u.undef.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
+ && (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, NULL, NULL, (bfd_vma) 0)))
+ 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;
+ flags = (sym.n_sclass == C_EXT ? BSF_GLOBAL : BSF_WEAK);
+ if (! (_bfd_generic_link_add_one_symbol
+ (info, abfd, name, flags, section, value,
+ 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->size = 0;
+ else
+ (*sym_hash)->root.u.c.p->alignment_power
+ = csect->alignment_power;
+ }
+
+ if (info->output_bfd->xvec == abfd->xvec)
+ {
+ int flag;
+
+ if (smtyp == XTY_ER
+ || smtyp == XTY_CM
+ || section == bfd_und_section_ptr)
+ 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;
+ }
+ }
+
+ if (smtyp == XTY_ER)
+ *csect_cache = section;
+ else
+ {
+ *csect_cache = csect;
+ if (csect != NULL)
+ xcoff_section_data (abfd, csect)->last_symndx
+ = (esym - (bfd_byte *) obj_coff_external_syms (abfd)) / symesz;
+ }
+
+ esym += (sym.n_numaux + 1) * symesz;
+ sym_hash += sym.n_numaux + 1;
+ csect_cache += sym.n_numaux + 1;
+ lineno_counts += 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)
+ {
+ /* Debugging sections have no csects. */
+ if (bfd_get_section_flags (abfd, o) & SEC_DEBUGGING)
+ continue;
+
+ /* 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->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)
+ (_("%B: reloc %s:%d not in csect"),
+ abfd, o->name, i);
+ bfd_set_error (bfd_error_bad_value);
+ goto error_return;
+ }
+
+ /* We identify all function symbols that are the target
+ of a relocation, so that we can create glue code for
+ functions imported from dynamic objects. */
+ if (info->output_bfd->xvec == abfd->xvec
+ && *rel_csect != bfd_und_section_ptr
+ && obj_xcoff_sym_hashes (abfd)[rel->r_symndx] != NULL)
+ {
+ struct xcoff_link_hash_entry *h;
+
+ h = obj_xcoff_sym_hashes (abfd)[rel->r_symndx];
+ /* 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;
+ struct bfd_link_hash_entry *bh;
+
+ 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)
+ {
+ bh = &hds->root;
+ if (! (_bfd_generic_link_add_one_symbol
+ (info, abfd, hds->root.root.string,
+ (flagword) 0, bfd_und_section_ptr,
+ (bfd_vma) 0, NULL, FALSE,
+ TRUE, &bh)))
+ goto error_return;
+ hds = (struct xcoff_link_hash_entry *) bh;
+ }
+ hds->flags |= XCOFF_DESCRIPTOR;
+ BFD_ASSERT ((h->flags & XCOFF_DESCRIPTOR) == 0);
+ hds->descriptor = h;
+ h->descriptor = hds;
+ }
+ if (h->root.root.string[0] == '.')
+ h->flags |= XCOFF_CALLED;
+ }
+ }
+
+ 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
+
+/* Add symbols from an XCOFF object file. */
+
+static bfd_boolean
+xcoff_link_add_object_symbols (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;
+}
+
+/* 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 bfd_boolean
+xcoff_link_check_dynamic_ar_symbols (bfd *abfd,
+ struct bfd_link_info *info,
+ bfd_boolean *pneeded,
+ bfd **subsbfd)
+{
+ asection *lsec;
+ bfd_byte *contents;
+ struct internal_ldhdr ldhdr;
+ const char *strings;
+ bfd_byte *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;
+ contents = coff_section_data (abfd, lsec)->contents;
+
+ bfd_xcoff_swap_ldhdr_in (abfd, contents, &ldhdr);
+
+ strings = (char *) contents + ldhdr.l_stoff;
+
+ elsym = contents + bfd_xcoff_loader_symbol_offset (abfd, &ldhdr);
+
+ elsymend = elsym + ldhdr.l_nsyms * bfd_xcoff_ldsymsz (abfd);
+ for (; elsym < elsymend; elsym += bfd_xcoff_ldsymsz (abfd))
+ {
+ struct internal_ldsym ldsym;
+ char nambuf[SYMNMLEN + 1];
+ const char *name;
+ struct bfd_link_hash_entry *h;
+
+ bfd_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, subsbfd))
+ return FALSE;
+ *pneeded = TRUE;
+ return TRUE;
+ }
+ }
+
+ /* We do not need this shared object. */
+ if (contents != NULL && ! coff_section_data (abfd, lsec)->keep_contents)
+ {
+ free (coff_section_data (abfd, lsec)->contents);
+ coff_section_data (abfd, lsec)->contents = NULL;
+ }
+
+ return TRUE;
+}
+
+/* Look through the symbols to see if this object file should be
+ included in the link. */
+
+static bfd_boolean
+xcoff_link_check_ar_symbols (bfd *abfd,
+ struct bfd_link_info *info,
+ bfd_boolean *pneeded,
+ bfd **subsbfd)
+{
+ bfd_size_type symesz;
+ bfd_byte *esym;
+ bfd_byte *esym_end;
+
+ *pneeded = FALSE;
+
+ if ((abfd->flags & DYNAMIC) != 0
+ && ! info->static_link
+ && info->output_bfd->xvec == abfd->xvec)
+ return xcoff_link_check_dynamic_ar_symbols (abfd, info, pneeded, subsbfd);
+
+ 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, (void *) esym, (void *) &sym);
+
+ if (EXTERN_SYM_P (sym.n_sclass) && 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 != NULL
+ && h->type == bfd_link_hash_undefined
+ && (info->output_bfd->xvec != abfd->xvec
+ || (((struct xcoff_link_hash_entry *) h)->flags
+ & XCOFF_DEF_DYNAMIC) == 0))
+ {
+ if (!(*info->callbacks
+ ->add_archive_element) (info, abfd, name, subsbfd))
+ return FALSE;
+ *pneeded = TRUE;
+ return TRUE;
+ }
+ }
+
+ esym += (sym.n_numaux + 1) * symesz;
+ }
+
+ /* We do not need this object file. */
+ 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 bfd_boolean
+xcoff_link_check_archive_element (bfd *abfd,
+ struct bfd_link_info *info,
+ struct bfd_link_hash_entry *h ATTRIBUTE_UNUSED,
+ const char *name ATTRIBUTE_UNUSED,
+ bfd_boolean *pneeded)
+{
+ bfd_boolean keep_syms_p;
+ bfd *oldbfd;
+
+ keep_syms_p = (obj_coff_external_syms (abfd) != NULL);
+ if (!_bfd_coff_get_external_symbols (abfd))
+ return FALSE;
+
+ oldbfd = abfd;
+ if (!xcoff_link_check_ar_symbols (abfd, info, pneeded, &abfd))
+ return FALSE;
+
+ if (*pneeded)
+ {
+ /* Potentially, the add_archive_element hook may have set a
+ substitute BFD for us. */
+ if (abfd != oldbfd)
+ {
+ if (!keep_syms_p
+ && !_bfd_coff_free_symbols (oldbfd))
+ return FALSE;
+ keep_syms_p = (obj_coff_external_syms (abfd) != NULL);
+ if (!_bfd_coff_get_external_symbols (abfd))
+ return FALSE;
+ }
+ if (!xcoff_link_add_symbols (abfd, info))
+ return FALSE;
+ if (info->keep_memory)
+ keep_syms_p = TRUE;
+ }
+
+ if (!keep_syms_p)
+ {
+ if (!_bfd_coff_free_symbols (abfd))
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/* Given an XCOFF BFD, add symbols to the global hash table as
+ appropriate. */
+
+bfd_boolean
+_bfd_xcoff_bfd_link_add_symbols (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 dynamic objects, because they may 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, NULL);
+ while (member != NULL)
+ {
+ if (bfd_check_format (member, bfd_object)
+ && (info->output_bfd->xvec == member->xvec)
+ && (! bfd_has_map (abfd) || (member->flags & DYNAMIC) != 0))
+ {
+ bfd_boolean needed;
+
+ if (! xcoff_link_check_archive_element (member, info,
+ NULL, NULL, &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;
+ }
+}
+
+bfd_boolean
+_bfd_xcoff_define_common_symbol (bfd *output_bfd ATTRIBUTE_UNUSED,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ struct bfd_link_hash_entry *harg)
+{
+ struct xcoff_link_hash_entry *h;
+
+ if (!bfd_generic_define_common_symbol (output_bfd, info, harg))
+ return FALSE;
+
+ h = (struct xcoff_link_hash_entry *) harg;
+ h->flags |= XCOFF_DEF_REGULAR;
+ return TRUE;
+}
+
+/* If symbol H has not been interpreted as a function descriptor,
+ see whether it should be. Set up its descriptor information if so. */
+
+static bfd_boolean
+xcoff_find_function (struct bfd_link_info *info,
+ struct xcoff_link_hash_entry *h)
+{
+ if ((h->flags & XCOFF_DESCRIPTOR) == 0
+ && h->root.root.string[0] != '.')
+ {
+ char *fnname;
+ struct xcoff_link_hash_entry *hfn;
+ bfd_size_type amt;
+
+ amt = strlen (h->root.root.string) + 2;
+ fnname = bfd_malloc (amt);
+ 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;
+ }
+ }
+ return TRUE;
+}
+
+/* Return true if the given bfd contains at least one shared object. */
+
+static bfd_boolean
+xcoff_archive_contains_shared_object_p (struct bfd_link_info *info,
+ bfd *archive)
+{
+ struct xcoff_archive_info *archive_info;
+ bfd *member;
+
+ archive_info = xcoff_get_archive_info (info, archive);
+ if (!archive_info->know_contains_shared_object_p)
+ {
+ member = bfd_openr_next_archived_file (archive, NULL);
+ while (member != NULL && (member->flags & DYNAMIC) == 0)
+ member = bfd_openr_next_archived_file (archive, member);
+
+ archive_info->contains_shared_object_p = (member != NULL);
+ archive_info->know_contains_shared_object_p = 1;
+ }
+ return archive_info->contains_shared_object_p;
+}
+
+/* Symbol H qualifies for export by -bexpfull. Return true if it also
+ qualifies for export by -bexpall. */
+
+static bfd_boolean
+xcoff_covered_by_expall_p (struct xcoff_link_hash_entry *h)
+{
+ /* Exclude symbols beginning with '_'. */
+ if (h->root.root.string[0] == '_')
+ return FALSE;
+
+ /* Exclude archive members that would otherwise be unreferenced. */
+ if ((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->my_archive != NULL)
+ return FALSE;
+
+ return TRUE;
+}
+
+/* Return true if symbol H qualifies for the forms of automatic export
+ specified by AUTO_EXPORT_FLAGS. */
+
+static bfd_boolean
+xcoff_auto_export_p (struct bfd_link_info *info,
+ struct xcoff_link_hash_entry *h,
+ unsigned int auto_export_flags)
+{
+ /* Don't automatically export things that were explicitly exported. */
+ if ((h->flags & XCOFF_EXPORT) != 0)
+ return FALSE;
+
+ /* Don't export things that we don't define. */
+ if ((h->flags & XCOFF_DEF_REGULAR) == 0)
+ return FALSE;
+
+ /* Don't export functions; export their descriptors instead. */
+ if (h->root.root.string[0] == '.')
+ return FALSE;
+
+ /* 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. */
+ if (h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak)
+ {
+ bfd *owner;
+
+ owner = h->root.u.def.section->owner;
+ if (owner != NULL
+ && owner->my_archive != NULL
+ && xcoff_archive_contains_shared_object_p (info, owner->my_archive))
+ return FALSE;
+ }
+
+ /* Otherwise, all symbols are exported by -bexpfull. */
+ if ((auto_export_flags & XCOFF_EXPFULL) != 0)
+ return TRUE;
+
+ /* Despite its name, -bexpall exports most but not all symbols. */
+ if ((auto_export_flags & XCOFF_EXPALL) != 0
+ && xcoff_covered_by_expall_p (h))
+ return TRUE;
+
+ return FALSE;
+}
+
+/* Return true if relocation REL needs to be copied to the .loader section.
+ If REL is against a global symbol, H is that symbol, otherwise it
+ is null. */
+
+static bfd_boolean
+xcoff_need_ldrel_p (struct bfd_link_info *info, struct internal_reloc *rel,
+ struct xcoff_link_hash_entry *h)
+{
+ if (!xcoff_hash_table (info)->loader_section)
+ return FALSE;
+
+ switch (rel->r_type)
+ {
+ 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. */
+ return FALSE;
+
+ default:
+ /* In this case, relocations against defined symbols can be resolved
+ statically. */
+ if (h == NULL
+ || h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak
+ || h->root.type == bfd_link_hash_common)
+ return FALSE;
+
+ /* We will always provide a local definition of function symbols,
+ even if we don't have one yet. */
+ if ((h->flags & XCOFF_CALLED) != 0)
+ return FALSE;
+
+ return TRUE;
+
+ case R_POS:
+ case R_NEG:
+ case R_RL:
+ case R_RLA:
+ /* Absolute relocations against absolute symbols can be
+ resolved statically. */
+ if (h != NULL
+ && (h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak)
+ && bfd_is_abs_section (h->root.u.def.section))
+ return FALSE;
+
+ return TRUE;
+ }
+}
+
+/* Mark a symbol as not being garbage, including the section in which
+ it is defined. */
+
+static inline bfd_boolean
+xcoff_mark_symbol (struct bfd_link_info *info, struct xcoff_link_hash_entry *h)
+{
+ if ((h->flags & XCOFF_MARK) != 0)
+ return TRUE;
+
+ h->flags |= XCOFF_MARK;
+
+ /* If we're marking an undefined symbol, try find some way of
+ defining it. */
+ if (!info->relocatable
+ && (h->flags & XCOFF_IMPORT) == 0
+ && (h->flags & XCOFF_DEF_REGULAR) == 0
+ && (h->root.type == bfd_link_hash_undefined
+ || h->root.type == bfd_link_hash_undefweak))
+ {
+ /* First check whether this symbol can be interpreted as an
+ undefined function descriptor for a defined function symbol. */
+ if (!xcoff_find_function (info, h))
+ return FALSE;
+
+ if ((h->flags & XCOFF_DESCRIPTOR) != 0
+ && (h->descriptor->root.type == bfd_link_hash_defined
+ || h->descriptor->root.type == bfd_link_hash_defweak))
+ {
+ /* This is a descriptor for a defined symbol, but the input
+ objects have not defined the descriptor itself. Fill in
+ the definition automatically.
+
+ Note that we do this even if we found a dynamic definition
+ of H. The local function definition logically overrides
+ the dynamic one. */
+ asection *sec;
+
+ sec = xcoff_hash_table (info)->descriptor_section;
+ h->root.type = bfd_link_hash_defined;
+ h->root.u.def.section = sec;
+ h->root.u.def.value = sec->size;
+ h->smclas = XMC_DS;
+ h->flags |= XCOFF_DEF_REGULAR;
+
+ /* The size of the function descriptor depends on whether this
+ is xcoff32 (12) or xcoff64 (24). */
+ sec->size += bfd_xcoff_function_descriptor_size (sec->owner);
+
+ /* A function descriptor uses two relocs: one for the
+ associated code, and one for the TOC address. */
+ xcoff_hash_table (info)->ldrel_count += 2;
+ sec->reloc_count += 2;
+
+ /* Mark the function itself. */
+ if (!xcoff_mark_symbol (info, h->descriptor))
+ return FALSE;
+
+ /* Mark the TOC section, so that we get an anchor
+ to relocate against. */
+ if (!xcoff_mark (info, xcoff_hash_table (info)->toc_section))
+ return FALSE;
+
+ /* We handle writing out the contents of the descriptor in
+ xcoff_write_global_symbol. */
+ }
+ else if (info->static_link)
+ /* We can't get a symbol value dynamically, so just assume
+ that it's undefined. */
+ h->flags |= XCOFF_WAS_UNDEFINED;
+ else if ((h->flags & XCOFF_CALLED) != 0)
+ {
+ /* This is a function symbol for which we need to create
+ linkage code. */
+ asection *sec;
+ struct xcoff_link_hash_entry *hds;
+
+ /* Mark the descriptor (and its TOC section). */
+ 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);
+ if (!xcoff_mark_symbol (info, hds))
+ return FALSE;
+
+ /* Treat this symbol as undefined if the descriptor was. */
+ if ((hds->flags & XCOFF_WAS_UNDEFINED) != 0)
+ h->flags |= XCOFF_WAS_UNDEFINED;
+
+ /* Allocate room for the global linkage code itself. */
+ sec = xcoff_hash_table (info)->linkage_section;
+ h->root.type = bfd_link_hash_defined;
+ h->root.u.def.section = sec;
+ h->root.u.def.value = sec->size;
+ h->smclas = XMC_GL;
+ h->flags |= XCOFF_DEF_REGULAR;
+ sec->size += bfd_xcoff_glink_code_size (info->output_bfd);
+
+ /* The global linkage code requires a TOC entry for the
+ descriptor. */
+ if (hds->toc_section == NULL)
+ {
+ int byte_size;
+
+ /* 32 vs 64
+ xcoff32 uses 4 bytes in the toc.
+ xcoff64 uses 8 bytes in the toc. */
+ if (bfd_xcoff_is_xcoff64 (info->output_bfd))
+ byte_size = 8;
+ else if (bfd_xcoff_is_xcoff32 (info->output_bfd))
+ byte_size = 4;
+ else
+ return FALSE;
+
+ /* Allocate room in the fallback TOC section. */
+ hds->toc_section = xcoff_hash_table (info)->toc_section;
+ hds->u.toc_offset = hds->toc_section->size;
+ hds->toc_section->size += byte_size;
+ if (!xcoff_mark (info, hds->toc_section))
+ return FALSE;
+
+ /* Allocate room for a static and dynamic R_TOC
+ relocation. */
+ ++xcoff_hash_table (info)->ldrel_count;
+ ++hds->toc_section->reloc_count;
+
+ /* Set the index to -2 to force this symbol to
+ get written out. */
+ hds->indx = -2;
+ hds->flags |= XCOFF_SET_TOC | XCOFF_LDREL;
+ }
+ }
+ else if ((h->flags & XCOFF_DEF_DYNAMIC) == 0)
+ {
+ /* Record that the symbol was undefined, then import it.
+ -brtl links use a special fake import file. */
+ h->flags |= XCOFF_WAS_UNDEFINED | XCOFF_IMPORT;
+ if (xcoff_hash_table (info)->rtld)
+ {
+ if (!xcoff_set_import_path (info, h, "", "..", ""))
+ return FALSE;
+ }
+ else
+ {
+ if (!xcoff_set_import_path (info, h, NULL, NULL, NULL))
+ return FALSE;
+ }
+ }
+ }
+
+ 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;
+}
+
+/* Look for a symbol called NAME. If the symbol is defined, mark it.
+ If the symbol exists, set FLAGS. */
+
+static bfd_boolean
+xcoff_mark_symbol_by_name (struct bfd_link_info *info,
+ const char *name, unsigned int flags)
+{
+ struct xcoff_link_hash_entry *h;
+
+ h = xcoff_link_hash_lookup (xcoff_hash_table (info), name,
+ FALSE, FALSE, TRUE);
+ if (h != NULL)
+ {
+ h->flags |= flags;
+ if (h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak)
+ {
+ if (!xcoff_mark (info, h->root.u.def.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 bfd_boolean
+xcoff_mark (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->output_bfd->xvec
+ && coff_section_data (sec->owner, sec) != NULL
+ && xcoff_section_data (sec->owner, sec) != NULL)
+ {
+ struct xcoff_link_hash_entry **syms;
+ struct internal_reloc *rel, *relend;
+ asection **csects;
+ unsigned long i, first, last;
+
+ /* Mark all the symbols in this section. */
+ syms = obj_xcoff_sym_hashes (sec->owner);
+ csects = xcoff_data (sec->owner)->csects;
+ first = xcoff_section_data (sec->owner, sec)->first_symndx;
+ last = xcoff_section_data (sec->owner, sec)->last_symndx;
+ for (i = first; i <= last; i++)
+ if (csects[i] == sec
+ && syms[i] != NULL
+ && (syms[i]->flags & XCOFF_MARK) == 0)
+ {
+ if (!xcoff_mark_symbol (info, syms[i]))
+ 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,
+ NULL, FALSE, NULL);
+ if (rel == NULL)
+ return FALSE;
+ relend = rel + sec->reloc_count;
+ for (; rel < relend; rel++)
+ {
+ 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)
+ {
+ if ((h->flags & XCOFF_MARK) == 0)
+ {
+ if (!xcoff_mark_symbol (info, h))
+ return FALSE;
+ }
+ }
+ else
+ {
+ asection *rsec;
+
+ 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. */
+ if (xcoff_need_ldrel_p (info, rel, h))
+ {
+ ++xcoff_hash_table (info)->ldrel_count;
+ if (h != NULL)
+ h->flags |= XCOFF_LDREL;
+ }
+ }
+
+ 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;
+}
+
+/* Routines that are called after all the input files have been
+ handled, but before the sections are laid out in memory. */
+
+/* The sweep phase of garbage collection. Remove all garbage
+ sections. */
+
+static void
+xcoff_sweep (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->output_bfd->xvec
+ || 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)->descriptor_section
+ || (bfd_get_section_flags (sub, o) & SEC_DEBUGGING)
+ || strcmp (o->name, ".debug") == 0)
+ o->flags |= SEC_MARK;
+ else
+ {
+ o->size = 0;
+ o->reloc_count = 0;
+ }
+ }
+ }
+ }
+}
+
+/* Record the number of elements in a set. This is used to output the
+ correct csect length. */
+
+bfd_boolean
+bfd_xcoff_link_record_set (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;
+ bfd_size_type amt;
+
+ if (bfd_get_flavour (output_bfd) != bfd_target_xcoff_flavour)
+ 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. */
+ amt = sizeof (* n);
+ n = bfd_alloc (output_bfd, amt);
+ 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. */
+
+bfd_boolean
+bfd_xcoff_import_symbol (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,
+ unsigned int syscall_flag)
+{
+ struct xcoff_link_hash_entry *h = (struct xcoff_link_hash_entry *) harg;
+
+ if (bfd_get_flavour (output_bfd) != bfd_target_xcoff_flavour)
+ 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 ((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 | syscall_flag);
+
+ 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, 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;
+ h->smclas = XMC_XO;
+ }
+
+ if (!xcoff_set_import_path (info, h, imppath, impfile, impmember))
+ return FALSE;
+
+ return TRUE;
+}
+
+/* Export a symbol. */
+
+bfd_boolean
+bfd_xcoff_export_symbol (bfd *output_bfd,
+ struct bfd_link_info *info,
+ struct bfd_link_hash_entry *harg)
+{
+ struct xcoff_link_hash_entry *h = (struct xcoff_link_hash_entry *) harg;
+
+ if (bfd_get_flavour (output_bfd) != bfd_target_xcoff_flavour)
+ 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. */
+
+ /* 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. */
+
+bfd_boolean
+bfd_xcoff_link_count_reloc (bfd *output_bfd,
+ struct bfd_link_info *info,
+ const char *name)
+{
+ struct xcoff_link_hash_entry *h;
+
+ if (bfd_get_flavour (output_bfd) != bfd_target_xcoff_flavour)
+ 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;
+ if (xcoff_hash_table (info)->loader_section)
+ {
+ h->flags |= 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. */
+
+bfd_boolean
+bfd_xcoff_record_link_assignment (bfd *output_bfd,
+ struct bfd_link_info *info,
+ const char *name)
+{
+ struct xcoff_link_hash_entry *h;
+
+ if (bfd_get_flavour (output_bfd) != bfd_target_xcoff_flavour)
+ 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;
+}
+
+/* An xcoff_link_hash_traverse callback for which DATA points to an
+ xcoff_loader_info. Mark all symbols that should be automatically
+ exported. */
+
+static bfd_boolean
+xcoff_mark_auto_exports (struct xcoff_link_hash_entry *h, void *data)
+{
+ struct xcoff_loader_info *ldinfo;
+
+ ldinfo = (struct xcoff_loader_info *) data;
+ if (xcoff_auto_export_p (ldinfo->info, h, ldinfo->auto_export_flags))
+ {
+ if (!xcoff_mark_symbol (ldinfo->info, h))
+ ldinfo->failed = TRUE;
+ }
+ return TRUE;
+}
+
+/* Add a symbol to the .loader symbols, if necessary. */
+
+/* INPUT_BFD has an external symbol associated with hash table entry H
+ and csect CSECT. Return true if INPUT_BFD defines H. */
+
+static bfd_boolean
+xcoff_final_definition_p (bfd *input_bfd, struct xcoff_link_hash_entry *h,
+ asection *csect)
+{
+ switch (h->root.type)
+ {
+ case bfd_link_hash_defined:
+ case bfd_link_hash_defweak:
+ /* No input bfd owns absolute symbols. They are written by
+ xcoff_write_global_symbol instead. */
+ return (!bfd_is_abs_section (csect)
+ && h->root.u.def.section == csect);
+
+ case bfd_link_hash_common:
+ return h->root.u.c.p->section->owner == input_bfd;
+
+ case bfd_link_hash_undefined:
+ case bfd_link_hash_undefweak:
+ /* We can't treat undef.abfd as the owner because that bfd
+ might be a dynamic object. Allow any bfd to claim it. */
+ return TRUE;
+
+ default:
+ abort ();
+ }
+}
+
+/* See if H should have a loader symbol associated with it. */
+
+static bfd_boolean
+xcoff_build_ldsym (struct xcoff_loader_info *ldinfo,
+ struct xcoff_link_hash_entry *h)
+{
+ bfd_size_type amt;
+
+ /* Warn if this symbol is exported but not defined. */
+ if ((h->flags & XCOFF_EXPORT) != 0
+ && (h->flags & XCOFF_WAS_UNDEFINED) != 0)
+ {
+ (*_bfd_error_handler)
+ (_("warning: attempt to export undefined symbol `%s'"),
+ h->root.root.string);
+ return TRUE;
+ }
+
+ /* 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)
+ return TRUE;
+
+ /* We need to add this symbol to the .loader symbols. */
+
+ BFD_ASSERT (h->ldsym == NULL);
+ amt = sizeof (struct internal_ldsym);
+ h->ldsym = bfd_zalloc (ldinfo->output_bfd, amt);
+ if (h->ldsym == NULL)
+ {
+ ldinfo->failed = TRUE;
+ return FALSE;
+ }
+
+ if ((h->flags & XCOFF_IMPORT) != 0)
+ {
+ /* Give imported descriptors class XMC_DS rather than XMC_UA. */
+ if ((h->flags & XCOFF_DESCRIPTOR) != 0)
+ h->smclas = XMC_DS;
+ h->ldsym->l_ifile = h->ldindx;
+ }
+
+ /* The first 3 symbol table indices are reserved to indicate the
+ data, text and bss sections. */
+ h->ldindx = ldinfo->ldsym_count + 3;
+
+ ++ldinfo->ldsym_count;
+
+ if (! bfd_xcoff_put_ldsymbol_name (ldinfo->output_bfd, ldinfo,
+ h->ldsym, h->root.root.string))
+ return FALSE;
+
+ h->flags |= XCOFF_BUILT_LDSYM;
+ return TRUE;
+}
+
+/* An xcoff_htab_traverse callback that is called for each symbol
+ once garbage collection is complete. */
+
+static bfd_boolean
+xcoff_post_gc_symbol (struct xcoff_link_hash_entry *h, void * p)
+{
+ struct xcoff_loader_info *ldinfo = (struct xcoff_loader_info *) p;
+
+ /* __rtinit, this symbol has special handling. */
+ if (h->flags & XCOFF_RTINIT)
+ return TRUE;
+
+ /* 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->output_bfd->xvec)))
+ h->flags |= XCOFF_MARK;
+
+ /* Skip discarded symbols. */
+ if (xcoff_hash_table (ldinfo->info)->gc
+ && (h->flags & XCOFF_MARK) == 0)
+ 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
+ && h->root.u.c.p->section->size == 0)
+ {
+ BFD_ASSERT (bfd_is_com_section (h->root.u.c.p->section));
+ h->root.u.c.p->section->size = h->root.u.c.size;
+ }
+
+ if (xcoff_hash_table (ldinfo->info)->loader_section)
+ {
+ if (xcoff_auto_export_p (ldinfo->info, h, ldinfo->auto_export_flags))
+ h->flags |= XCOFF_EXPORT;
+
+ if (!xcoff_build_ldsym (ldinfo, h))
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/* INPUT_BFD includes XCOFF symbol ISYM, which is associated with linker
+ hash table entry H and csect CSECT. AUX contains ISYM's auxillary
+ csect information, if any. NAME is the function's name if the name
+ is stored in the .debug section, otherwise it is null.
+
+ Return 1 if we should include an appropriately-adjusted ISYM
+ in the output file, 0 if we should discard ISYM, or -1 if an
+ error occured. */
+
+static int
+xcoff_keep_symbol_p (struct bfd_link_info *info, bfd *input_bfd,
+ struct internal_syment *isym,
+ union internal_auxent *aux,
+ struct xcoff_link_hash_entry *h,
+ asection *csect, const char *name)
+{
+ int smtyp;
+
+ /* If we are skipping this csect, we want to strip the symbol too. */
+ if (csect == NULL)
+ return 0;
+
+ /* Likewise if we garbage-collected the csect. */
+ if (xcoff_hash_table (info)->gc
+ && !bfd_is_abs_section (csect)
+ && !bfd_is_und_section (csect)
+ && (csect->flags & SEC_MARK) == 0)
+ return 0;
+
+ /* An XCOFF linker always removes C_STAT symbols. */
+ if (isym->n_sclass == C_STAT)
+ return 0;
+
+ /* We generate the TOC anchor separately. */
+ if (isym->n_sclass == C_HIDEXT
+ && aux->x_csect.x_smclas == XMC_TC0)
+ return 0;
+
+ /* If we are stripping all symbols, we want to discard this one. */
+ if (info->strip == strip_all)
+ return 0;
+
+ /* Discard symbols that are defined elsewhere. */
+ if (EXTERN_SYM_P (isym->n_sclass))
+ {
+ if ((h->flags & XCOFF_ALLOCATED) != 0)
+ return 0;
+ if (!xcoff_final_definition_p (input_bfd, h, csect))
+ return 0;
+ }
+
+ /* If we're discarding local symbols, check whether ISYM is local. */
+ smtyp = SMTYP_SMTYP (aux->x_csect.x_smtyp);
+ if (info->discard == discard_all
+ && !EXTERN_SYM_P (isym->n_sclass)
+ && (isym->n_sclass != C_HIDEXT || smtyp != XTY_SD))
+ return 0;
+
+ /* If we're stripping debugging symbols, check whether ISYM is one. */
+ if (info->strip == strip_debugger
+ && isym->n_scnum == N_DEBUG)
+ return 0;
+
+ /* If we are stripping symbols based on name, check how ISYM's
+ name should be handled. */
+ if (info->strip == strip_some
+ || info->discard == discard_l)
+ {
+ char buf[SYMNMLEN + 1];
+
+ if (name == NULL)
+ {
+ name = _bfd_coff_internal_syment_name (input_bfd, isym, buf);
+ if (name == NULL)
+ return -1;
+ }
+
+ if (info->strip == strip_some
+ && bfd_hash_lookup (info->keep_hash, name, FALSE, FALSE) == NULL)
+ return 0;
+
+ if (info->discard == discard_l
+ && !EXTERN_SYM_P (isym->n_sclass)
+ && (isym->n_sclass != C_HIDEXT || smtyp != XTY_SD)
+ && bfd_is_local_label_name (input_bfd, name))
+ return 0;
+ }
+
+ return 1;
+}
+
+/* Lay out the .loader section, filling in the header and the import paths.
+ LIBPATH is as for bfd_xcoff_size_dynamic_sections. */
+
+static bfd_boolean
+xcoff_build_loader_section (struct xcoff_loader_info *ldinfo,
+ const char *libpath)
+{
+ bfd *output_bfd;
+ struct xcoff_link_hash_table *htab;
+ struct internal_ldhdr *ldhdr;
+ struct xcoff_import_file *fl;
+ bfd_size_type stoff;
+ size_t impsize, impcount;
+ asection *lsec;
+ char *out;
+
+ /* 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. */
+ output_bfd = ldinfo->output_bfd;
+ htab = xcoff_hash_table (ldinfo->info);
+ impsize = strlen (libpath) + 3;
+ impcount = 1;
+ for (fl = htab->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 = &htab->ldhdr;
+ ldhdr->l_version = bfd_xcoff_ldhdr_version(output_bfd);
+ ldhdr->l_nsyms = ldinfo->ldsym_count;
+ ldhdr->l_nreloc = htab->ldrel_count;
+ ldhdr->l_istlen = impsize;
+ ldhdr->l_nimpid = impcount;
+ ldhdr->l_impoff = (bfd_xcoff_ldhdrsz (output_bfd)
+ + ldhdr->l_nsyms * bfd_xcoff_ldsymsz (output_bfd)
+ + ldhdr->l_nreloc * bfd_xcoff_ldrelsz (output_bfd));
+ 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;
+
+ /* 64 bit elements to ldhdr
+ The swap out routine for 32 bit will ignore them.
+ Nothing fancy, symbols come after the header and relocs come
+ after symbols. */
+ ldhdr->l_symoff = bfd_xcoff_ldhdrsz (output_bfd);
+ ldhdr->l_rldoff = (bfd_xcoff_ldhdrsz (output_bfd)
+ + ldhdr->l_nsyms * bfd_xcoff_ldsymsz (output_bfd));
+
+ /* We now know the final size of the .loader section. Allocate
+ space for it. */
+ lsec = htab->loader_section;
+ lsec->size = stoff + ldhdr->l_stlen;
+ lsec->contents = bfd_zalloc (output_bfd, lsec->size);
+ if (lsec->contents == NULL)
+ return FALSE;
+
+ /* Set up the header. */
+ bfd_xcoff_swap_ldhdr_out (output_bfd, 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 = htab->imports; fl != NULL; fl = fl->next)
+ {
+ 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. */
+
+ return TRUE;
+}
+
+/* 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). AUTO_EXPORT_FLAGS
+ is a mask of XCOFF_EXPALL and XCOFF_EXPFULL. SPECIAL_SECTIONS
+ is set by this routine to csects with magic names like _end. */
+
+bfd_boolean
+bfd_xcoff_size_dynamic_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,
+ bfd_boolean gc,
+ int modtype,
+ bfd_boolean textro,
+ unsigned int auto_export_flags,
+ asection **special_sections,
+ bfd_boolean rtld)
+{
+ struct xcoff_loader_info ldinfo;
+ int i;
+ asection *sec;
+ bfd *sub;
+ struct bfd_strtab_hash *debug_strtab;
+ bfd_byte *debug_contents = NULL;
+ bfd_size_type amt;
+
+ if (bfd_get_flavour (output_bfd) != bfd_target_xcoff_flavour)
+ {
+ for (i = 0; i < XCOFF_NUMBER_OF_SPECIAL_SECTIONS; i++)
+ special_sections[i] = NULL;
+ return TRUE;
+ }
+
+ ldinfo.failed = FALSE;
+ ldinfo.output_bfd = output_bfd;
+ ldinfo.info = info;
+ ldinfo.auto_export_flags = auto_export_flags;
+ 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;
+ xcoff_hash_table (info)->rtld = rtld;
+
+ /* __rtinit */
+ if (xcoff_hash_table (info)->loader_section
+ && (info->init_function || info->fini_function || rtld))
+ {
+ struct xcoff_link_hash_entry *hsym;
+ struct internal_ldsym *ldsym;
+
+ hsym = xcoff_link_hash_lookup (xcoff_hash_table (info),
+ "__rtinit", FALSE, FALSE, TRUE);
+ if (hsym == NULL)
+ {
+ (*_bfd_error_handler)
+ (_("error: undefined symbol __rtinit"));
+ return FALSE;
+ }
+
+ xcoff_mark_symbol (info, hsym);
+ hsym->flags |= (XCOFF_DEF_REGULAR | XCOFF_RTINIT);
+
+ /* __rtinit initialized. */
+ amt = sizeof (* ldsym);
+ ldsym = bfd_malloc (amt);
+
+ ldsym->l_value = 0; /* Will be filled in later. */
+ ldsym->l_scnum = 2; /* Data section. */
+ ldsym->l_smtype = XTY_SD; /* Csect section definition. */
+ ldsym->l_smclas = 5; /* .rw. */
+ ldsym->l_ifile = 0; /* Special system loader symbol. */
+ ldsym->l_parm = 0; /* NA. */
+
+ /* Force __rtinit to be the first symbol in the loader symbol table
+ See xcoff_build_ldsyms
+
+ The first 3 symbol table indices are reserved to indicate the data,
+ text and bss sections. */
+ BFD_ASSERT (0 == ldinfo.ldsym_count);
+
+ hsym->ldindx = 3;
+ ldinfo.ldsym_count = 1;
+ hsym->ldsym = ldsym;
+
+ if (! bfd_xcoff_put_ldsymbol_name (ldinfo.output_bfd, &ldinfo,
+ hsym->ldsym, hsym->root.root.string))
+ return FALSE;
+
+ /* This symbol is written out by xcoff_write_global_symbol
+ Set stuff up so xcoff_write_global_symbol logic works. */
+ hsym->flags |= XCOFF_DEF_REGULAR | XCOFF_MARK;
+ hsym->root.type = bfd_link_hash_defined;
+ hsym->root.u.def.value = 0;
+ }
+
+ /* Garbage collect unused sections. */
+ if (info->relocatable || !gc)
+ {
+ 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)
+ {
+ /* We shouldn't unconditionaly mark the TOC section.
+ The output file should only have a TOC if either
+ (a) one of the input files did or (b) we end up
+ creating TOC references as part of the link process. */
+ if (o != xcoff_hash_table (info)->toc_section
+ && (o->flags & SEC_MARK) == 0)
+ {
+ if (! xcoff_mark (info, o))
+ goto error_return;
+ }
+ }
+ }
+ }
+ else
+ {
+ if (entry != NULL
+ && !xcoff_mark_symbol_by_name (info, entry, XCOFF_ENTRY))
+ goto error_return;
+ if (info->init_function != NULL
+ && !xcoff_mark_symbol_by_name (info, info->init_function, 0))
+ goto error_return;
+ if (info->fini_function != NULL
+ && !xcoff_mark_symbol_by_name (info, info->fini_function, 0))
+ goto error_return;
+ if (auto_export_flags != 0)
+ {
+ xcoff_link_hash_traverse (xcoff_hash_table (info),
+ xcoff_mark_auto_exports, &ldinfo);
+ if (ldinfo.failed)
+ goto error_return;
+ }
+ xcoff_sweep (info);
+ xcoff_hash_table (info)->gc = TRUE;
+ }
+
+ /* Return special sections to the caller. */
+ for (i = 0; i < XCOFF_NUMBER_OF_SPECIAL_SECTIONS; i++)
+ {
+ 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_post_gc_symbol,
+ (void *) &ldinfo);
+ if (ldinfo.failed)
+ goto error_return;
+
+ if (xcoff_hash_table (info)->loader_section
+ && !xcoff_build_loader_section (&ldinfo, libpath))
+ goto error_return;
+
+ /* Allocate space for the magic sections. */
+ sec = xcoff_hash_table (info)->linkage_section;
+ if (sec->size > 0)
+ {
+ sec->contents = bfd_zalloc (output_bfd, sec->size);
+ if (sec->contents == NULL)
+ goto error_return;
+ }
+ sec = xcoff_hash_table (info)->toc_section;
+ if (sec->size > 0)
+ {
+ sec->contents = bfd_zalloc (output_bfd, sec->size);
+ if (sec->contents == NULL)
+ goto error_return;
+ }
+ sec = xcoff_hash_table (info)->descriptor_section;
+ if (sec->size > 0)
+ {
+ sec->contents = bfd_zalloc (output_bfd, sec->size);
+ if (sec->contents == NULL)
+ goto error_return;
+ }
+
+ /* Now that we've done garbage collection, decide which symbols to keep,
+ and 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;
+ long *debug_index;
+ asection **csectpp;
+ unsigned int *lineno_counts;
+ struct xcoff_link_hash_entry **sym_hash;
+ bfd_byte *esym, *esymend;
+ bfd_size_type symesz;
+
+ if (sub->xvec != info->output_bfd->xvec)
+ continue;
+
+ if ((sub->flags & DYNAMIC) != 0
+ && !info->static_link)
+ continue;
+
+ if (! _bfd_coff_get_external_symbols (sub))
+ goto error_return;
+
+ symcount = obj_raw_syment_count (sub);
+ debug_index = bfd_zalloc (sub, symcount * sizeof (long));
+ if (debug_index == NULL)
+ goto error_return;
+ xcoff_data (sub)->debug_indices = debug_index;
+
+ if (info->strip == strip_all
+ || info->strip == strip_debugger
+ || info->discard == discard_all)
+ /* We're stripping all debugging information, so there's no need
+ to read SUB's .debug section. */
+ subdeb = NULL;
+ else
+ {
+ /* Grab the contents of SUB's .debug section, if any. */
+ subdeb = bfd_get_section_by_name (sub, ".debug");
+ if (subdeb != NULL && subdeb->size > 0)
+ {
+ /* 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. */
+ if (!bfd_malloc_and_get_section (sub, subdeb, &debug_contents))
+ goto error_return;
+ }
+ }
+
+ csectpp = xcoff_data (sub)->csects;
+ lineno_counts = xcoff_data (sub)->lineno_counts;
+ sym_hash = obj_xcoff_sym_hashes (sub);
+ symesz = bfd_coff_symesz (sub);
+ esym = (bfd_byte *) obj_coff_external_syms (sub);
+ esymend = esym + symcount * symesz;
+
+ while (esym < esymend)
+ {
+ struct internal_syment sym;
+ union internal_auxent aux;
+ asection *csect;
+ const char *name;
+ int keep_p;
+
+ bfd_coff_swap_sym_in (sub, esym, &sym);
+
+ /* Read in the csect information, if any. */
+ if (CSECT_SYM_P (sym.n_sclass))
+ {
+ BFD_ASSERT (sym.n_numaux > 0);
+ bfd_coff_swap_aux_in (sub, esym + symesz * sym.n_numaux,
+ sym.n_type, sym.n_sclass,
+ sym.n_numaux - 1, sym.n_numaux, &aux);
+ }
+
+ /* If this symbol's name is stored in the debug section,
+ get a pointer to it. */
+ if (debug_contents != NULL
+ && sym._n._n_n._n_zeroes == 0
+ && bfd_coff_symname_in_debug (sub, &sym))
+ name = (const char *) debug_contents + sym._n._n_n._n_offset;
+ else
+ name = NULL;
+
+ /* Decide whether to copy this symbol to the output file. */
+ csect = *csectpp;
+ keep_p = xcoff_keep_symbol_p (info, sub, &sym, &aux,
+ *sym_hash, csect, name);
+ if (keep_p < 0)
+ return FALSE;
+
+ if (!keep_p)
+ /* Use a debug_index of -2 to record that a symbol should
+ be stripped. */
+ *debug_index = -2;
+ else
+ {
+ /* See whether we should store the symbol name in the
+ output .debug section. */
+ if (name != NULL)
+ {
+ bfd_size_type indx;
+
+ indx = _bfd_stringtab_add (debug_strtab, name, TRUE, TRUE);
+ if (indx == (bfd_size_type) -1)
+ goto error_return;
+ *debug_index = indx;
+ }
+ else
+ *debug_index = -1;
+ if (*sym_hash != 0)
+ (*sym_hash)->flags |= XCOFF_ALLOCATED;
+ if (*lineno_counts > 0)
+ csect->output_section->lineno_count += *lineno_counts;
+ }
+
+ esym += (sym.n_numaux + 1) * symesz;
+ csectpp += sym.n_numaux + 1;
+ sym_hash += sym.n_numaux + 1;
+ lineno_counts += sym.n_numaux + 1;
+ debug_index += sym.n_numaux + 1;
+ }
+
+ if (debug_contents)
+ {
+ free (debug_contents);
+ debug_contents = NULL;
+
+ /* Clear the size of subdeb, so that it is not included directly
+ in the output file. */
+ subdeb->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->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;
+}
+
+bfd_boolean
+bfd_xcoff_link_generate_rtinit (bfd *abfd,
+ const char *init,
+ const char *fini,
+ bfd_boolean rtld)
+{
+ struct bfd_in_memory *bim;
+
+ bim = bfd_malloc ((bfd_size_type) sizeof (* bim));
+ if (bim == NULL)
+ return FALSE;
+
+ bim->size = 0;
+ bim->buffer = 0;
+
+ abfd->link.next = 0;
+ abfd->format = bfd_object;
+ abfd->iostream = (void *) bim;
+ abfd->flags = BFD_IN_MEMORY;
+ abfd->iovec = &_bfd_memory_iovec;
+ abfd->direction = write_direction;
+ abfd->origin = 0;
+ abfd->where = 0;
+
+ if (! bfd_xcoff_generate_rtinit (abfd, init, fini, rtld))
+ return FALSE;
+
+ /* need to reset to unknown or it will not be read back in correctly */
+ abfd->format = bfd_unknown;
+ abfd->direction = read_direction;
+ abfd->where = 0;
+
+ return TRUE;
+}
+
+/* Return the section that defines H. Return null if no section does. */
+
+static asection *
+xcoff_symbol_section (struct xcoff_link_hash_entry *h)
+{
+ 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:
+ return NULL;
+ }
+}
+
+/* Add a .loader relocation for input relocation IREL. If the loader
+ relocation should be against an output section, HSEC points to the
+ input section that IREL is against, otherwise HSEC is null. H is the
+ symbol that IREL is against, or null if it isn't against a global symbol.
+ REFERENCE_BFD is the bfd to use in error messages about the relocation. */
+
+static bfd_boolean
+xcoff_create_ldrel (bfd *output_bfd, struct xcoff_final_link_info *flinfo,
+ asection *output_section, bfd *reference_bfd,
+ struct internal_reloc *irel, asection *hsec,
+ struct xcoff_link_hash_entry *h)
+{
+ struct internal_ldrel ldrel;
+
+ 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)
+ (_("%B: loader reloc in unrecognized section `%s'"),
+ reference_bfd, secname);
+ bfd_set_error (bfd_error_nonrepresentable_section);
+ return FALSE;
+ }
+ }
+ else if (h != NULL)
+ {
+ if (h->ldindx < 0)
+ {
+ (*_bfd_error_handler)
+ (_("%B: `%s' in loader reloc but not loader sym"),
+ reference_bfd, h->root.root.string);
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+ ldrel.l_symndx = h->ldindx;
+ }
+ else
+ ldrel.l_symndx = -(bfd_size_type) 1;
+
+ ldrel.l_rtype = (irel->r_size << 8) | irel->r_type;
+ ldrel.l_rsecnm = output_section->target_index;
+ if (xcoff_hash_table (flinfo->info)->textro
+ && strcmp (output_section->name, ".text") == 0)
+ {
+ (*_bfd_error_handler)
+ (_("%B: loader reloc in read-only section %A"),
+ reference_bfd, output_section);
+ bfd_set_error (bfd_error_invalid_operation);
+ return FALSE;
+ }
+ bfd_xcoff_swap_ldrel_out (output_bfd, &ldrel, flinfo->ldrel);
+ flinfo->ldrel += bfd_xcoff_ldrelsz (output_bfd);
+ 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. */
+
+static bfd_boolean
+xcoff_link_input_bfd (struct xcoff_final_link_info *flinfo,
+ bfd *input_bfd)
+{
+ bfd *output_bfd;
+ const char *strings;
+ bfd_size_type syment_base;
+ unsigned int n_tmask;
+ unsigned int n_btshft;
+ bfd_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 int *lineno_counts;
+ long *debug_index;
+ long *indexp;
+ unsigned long output_index;
+ bfd_byte *outsym;
+ unsigned int incls;
+ asection *oline;
+ bfd_boolean keep_syms;
+ asection *o;
+
+ /* We can just skip DYNAMIC files, unless this is a static link. */
+ if ((input_bfd->flags & DYNAMIC) != 0
+ && ! flinfo->info->static_link)
+ return TRUE;
+
+ /* Move all the symbols to the output file. */
+ output_bfd = flinfo->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 (! flinfo->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;
+
+ /* Make one pass over the symbols and assign indices to symbols that
+ we have decided to keep. Also use create .loader symbol information
+ and update information in hash table entries. */
+ 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 = flinfo->internal_syms;
+ indexp = flinfo->sym_indices;
+ output_index = syment_base;
+ while (esym < esym_end)
+ {
+ union internal_auxent aux;
+ int smtyp = 0;
+ int add;
+
+ bfd_coff_swap_sym_in (input_bfd, (void *) esym, (void *) isymp);
+
+ /* Read in the csect information, if any. */
+ if (CSECT_SYM_P (isymp->n_sclass))
+ {
+ BFD_ASSERT (isymp->n_numaux > 0);
+ bfd_coff_swap_aux_in (input_bfd,
+ (void *) (esym + isymesz * isymp->n_numaux),
+ isymp->n_type, isymp->n_sclass,
+ isymp->n_numaux - 1, isymp->n_numaux,
+ (void *) &aux);
+
+ smtyp = SMTYP_SMTYP (aux.x_csect.x_smtyp);
+ }
+
+ /* 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 (EXTERN_SYM_P (isymp->n_sclass)
+ && *sym_hash != NULL
+ && (*sym_hash)->ldsym != NULL
+ && xcoff_final_definition_p (input_bfd, *sym_hash, *csectpp))
+ {
+ struct xcoff_link_hash_entry *h;
+ struct internal_ldsym *ldsym;
+
+ h = *sym_hash;
+ ldsym = h->ldsym;
+ if (isymp->n_scnum > 0)
+ {
+ ldsym->l_scnum = (*csectpp)->output_section->target_index;
+ ldsym->l_value = (isymp->n_value
+ + (*csectpp)->output_section->vma
+ + (*csectpp)->output_offset
+ - (*csectpp)->vma);
+ }
+ else
+ {
+ ldsym->l_scnum = isymp->n_scnum;
+ ldsym->l_value = isymp->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;
+ if (isymp->n_sclass == C_AIX_WEAKEXT)
+ ldsym->l_smtype |= L_WEAK;
+
+ 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 == flinfo->output_bfd->xvec);
+ ldsym->l_ifile = xcoff_data (impbfd)->import_file_id;
+ }
+ }
+ }
+
+ ldsym->l_parm = 0;
+
+ BFD_ASSERT (h->ldindx >= 0);
+ bfd_xcoff_swap_ldsym_out (flinfo->output_bfd, ldsym,
+ (flinfo->ldsym
+ + ((h->ldindx - 3)
+ * bfd_xcoff_ldsymsz (flinfo->output_bfd))));
+ 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;
+ }
+ }
+
+ add = 1 + isymp->n_numaux;
+
+ if (*debug_index == -2)
+ /* We've decided to strip this symbol. */
+ *indexp = -1;
+ else
+ {
+ /* Assign the next unused index to this symbol. */
+ *indexp = output_index;
+
+ if (EXTERN_SYM_P (isymp->n_sclass))
+ {
+ BFD_ASSERT (*sym_hash != NULL);
+ (*sym_hash)->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 (isymp->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;
+ }
+
+ esym += add * isymesz;
+ isymp += add;
+ csectpp += add;
+ sym_hash += add;
+ debug_index += add;
+ ++indexp;
+ for (--add; add > 0; --add)
+ *indexp++ = -1;
+ }
+
+ /* Now write out the symbols that we decided to keep. */
+
+ 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);
+ isymp = flinfo->internal_syms;
+ indexp = flinfo->sym_indices;
+ csectpp = xcoff_data (input_bfd)->csects;
+ lineno_counts = xcoff_data (input_bfd)->lineno_counts;
+ debug_index = xcoff_data (input_bfd)->debug_indices;
+ outsym = flinfo->outsyms;
+ incls = 0;
+ oline = NULL;
+ while (esym < esym_end)
+ {
+ int add;
+
+ add = 1 + isymp->n_numaux;
+
+ if (*indexp < 0)
+ esym += add * isymesz;
+ else
+ {
+ struct internal_syment isym;
+ int i;
+
+ /* Adjust the symbol in order to output it. */
+ isym = *isymp;
+ 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 >= 0)
+ 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, NULL);
+
+ if (name == NULL)
+ return FALSE;
+ indx = _bfd_stringtab_add (flinfo->strtab, name, hash, copy);
+ if (indx == (bfd_size_type) -1)
+ return FALSE;
+ isym._n._n_n._n_offset = STRING_SIZE_SIZE + indx;
+ }
+ }
+
+ /* Make __rtinit C_HIDEXT rather than C_EXT. This avoids
+ multiple definition problems when linking a shared object
+ statically. (The native linker doesn't enter __rtinit into
+ the normal table at all, but having a local symbol can make
+ the objdump output easier to read.) */
+ if (isym.n_sclass == C_EXT
+ && *sym_hash
+ && ((*sym_hash)->flags & XCOFF_RTINIT) != 0)
+ isym.n_sclass = C_HIDEXT;
+
+ /* 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 (flinfo->last_file_index != -1
+ && flinfo->last_file.n_value != (bfd_vma) *indexp)
+ {
+ /* We must correct the value of the last C_FILE entry. */
+ flinfo->last_file.n_value = *indexp;
+ if ((bfd_size_type) flinfo->last_file_index >= syment_base)
+ {
+ /* The last C_FILE symbol is in this input file. */
+ bfd_coff_swap_sym_out (output_bfd,
+ (void *) &flinfo->last_file,
+ (void *) (flinfo->outsyms
+ + ((flinfo->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. */
+ file_ptr pos;
+
+ bfd_coff_swap_sym_out (output_bfd,
+ (void *) &flinfo->last_file,
+ (void *) outsym);
+
+ pos = obj_sym_filepos (output_bfd);
+ pos += flinfo->last_file_index * osymesz;
+ if (bfd_seek (output_bfd, pos, SEEK_SET) != 0
+ || (bfd_bwrite (outsym, osymesz, output_bfd)
+ != osymesz))
+ return FALSE;
+ }
+ }
+
+ flinfo->last_file_index = *indexp;
+ flinfo->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 = flinfo->line_filepos;
+ ++incls;
+ }
+ /* The value of a C_BSTAT symbol is the symbol table
+ index of the containing csect. */
+ else if (isym.n_sclass == C_BSTAT)
+ {
+ bfd_vma indx;
+
+ indx = isym.n_value;
+ if (indx < obj_raw_syment_count (input_bfd))
+ {
+ long symindx;
+
+ symindx = flinfo->sym_indices[indx];
+ if (symindx < 0)
+ isym.n_value = 0;
+ else
+ isym.n_value = symindx;
+ }
+ }
+ else if (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);
+ }
+
+ /* Output the symbol. */
+ bfd_coff_swap_sym_out (output_bfd, (void *) &isym, (void *) 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, (void *) esym, isymp->n_type,
+ isymp->n_sclass, i, isymp->n_numaux,
+ (void *) &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;
+ }
+ if ((bfd_size_type) aux.x_file.x_n.x_offset >= obj_coff_strings_len (input_bfd))
+ filename = _("<corrupt>");
+ else
+ filename = strings + aux.x_file.x_n.x_offset;
+ indx = _bfd_stringtab_add (flinfo->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 (CSECT_SYM_P (isymp->n_sclass)
+ && 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 = flinfo->sym_indices[indx];
+ if (symindx < 0)
+ {
+ aux.x_csect.x_scnlen.l = 0;
+ }
+ else
+ {
+ aux.x_csect.x_scnlen.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 (flinfo->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 = flinfo->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 = flinfo->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 (CSECT_SYM_P (isymp->n_sclass)
+ && i == 0
+ && isymp->n_numaux > 1
+ && ISFCN (isymp->n_type)
+ && aux.x_sym.x_fcnary.x_fcn.x_lnnoptr != 0)
+ {
+ if (*lineno_counts == 0)
+ aux.x_sym.x_fcnary.x_fcn.x_lnnoptr = 0;
+ else
+ {
+ asection *enclosing;
+ unsigned int enc_count;
+ bfd_signed_vma linoff;
+ struct internal_lineno lin;
+ bfd_byte *linp;
+ bfd_byte *linpend;
+ bfd_vma offset;
+ file_ptr pos;
+ bfd_size_type amt;
+
+ /* Read in the enclosing section's line-number
+ information, if we haven't already. */
+ o = *csectpp;
+ enclosing = xcoff_section_data (abfd, o)->enclosing;
+ enc_count = xcoff_section_data (abfd, o)->lineno_count;
+ if (oline != enclosing)
+ {
+ pos = enclosing->line_filepos;
+ amt = linesz * enc_count;
+ if (bfd_seek (input_bfd, pos, SEEK_SET) != 0
+ || (bfd_bread (flinfo->linenos, amt, input_bfd)
+ != amt))
+ return FALSE;
+ oline = enclosing;
+ }
+
+ /* Copy across the first entry, adjusting its
+ symbol index. */
+ linoff = (aux.x_sym.x_fcnary.x_fcn.x_lnnoptr
+ - enclosing->line_filepos);
+ linp = flinfo->linenos + linoff;
+ bfd_coff_swap_lineno_in (input_bfd, linp, &lin);
+ lin.l_addr.l_symndx = *indexp;
+ bfd_coff_swap_lineno_out (output_bfd, &lin, linp);
+
+ /* Copy the other entries, adjusting their addresses. */
+ linpend = linp + *lineno_counts * linesz;
+ offset = (o->output_section->vma
+ + o->output_offset
+ - o->vma);
+ for (linp += linesz; linp < linpend; linp += linesz)
+ {
+ bfd_coff_swap_lineno_in (input_bfd, linp, &lin);
+ lin.l_addr.l_paddr += offset;
+ bfd_coff_swap_lineno_out (output_bfd, &lin, linp);
+ }
+
+ /* Write out the entries we've just processed. */
+ pos = (o->output_section->line_filepos
+ + o->output_section->lineno_count * linesz);
+ amt = linesz * *lineno_counts;
+ if (bfd_seek (output_bfd, pos, SEEK_SET) != 0
+ || bfd_bwrite (flinfo->linenos + linoff,
+ amt, output_bfd) != amt)
+ return FALSE;
+ o->output_section->lineno_count += *lineno_counts;
+
+ /* Record the offset of the symbol's line numbers
+ in the output file. */
+ aux.x_sym.x_fcnary.x_fcn.x_lnnoptr = pos;
+
+ if (incls > 0)
+ {
+ struct internal_syment *iisp, *iispend;
+ long *iindp;
+ bfd_byte *oos;
+ bfd_vma range_start, range_end;
+ int iiadd;
+
+ /* Update any C_BINCL or C_EINCL symbols
+ that refer to a line number in the
+ range we just output. */
+ iisp = flinfo->internal_syms;
+ iispend = iisp + obj_raw_syment_count (input_bfd);
+ iindp = flinfo->sym_indices;
+ oos = flinfo->outsyms;
+ range_start = enclosing->line_filepos + linoff;
+ range_end = range_start + *lineno_counts * linesz;
+ while (iisp < iispend)
+ {
+ if (*iindp >= 0
+ && (iisp->n_sclass == C_BINCL
+ || iisp->n_sclass == C_EINCL)
+ && iisp->n_value >= range_start
+ && iisp->n_value < range_end)
+ {
+ struct internal_syment iis;
+
+ bfd_coff_swap_sym_in (output_bfd, oos, &iis);
+ iis.n_value = (iisp->n_value
+ - range_start
+ + pos);
+ bfd_coff_swap_sym_out (output_bfd,
+ &iis, oos);
+ --incls;
+ }
+
+ iiadd = 1 + iisp->n_numaux;
+ if (*iindp >= 0)
+ oos += iiadd * osymesz;
+ iisp += iiadd;
+ iindp += iiadd;
+ }
+ }
+ }
+ }
+
+ bfd_coff_swap_aux_out (output_bfd, (void *) &aux, isymp->n_type,
+ isymp->n_sclass, i, isymp->n_numaux,
+ (void *) outsym);
+ outsym += osymesz;
+ esym += isymesz;
+ }
+ }
+
+ sym_hash += add;
+ indexp += add;
+ isymp += add;
+ csectpp += add;
+ lineno_counts += add;
+ debug_index += 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 (flinfo->last_file_index != -1
+ && (bfd_size_type) flinfo->last_file_index >= syment_base)
+ {
+ flinfo->last_file.n_value = output_index;
+ bfd_coff_swap_sym_out (output_bfd, (void *) &flinfo->last_file,
+ (void *) (flinfo->outsyms
+ + ((flinfo->last_file_index - syment_base)
+ * osymesz)));
+ }
+
+ /* Write the modified symbols to the output file. */
+ if (outsym > flinfo->outsyms)
+ {
+ file_ptr pos = obj_sym_filepos (output_bfd) + syment_base * osymesz;
+ bfd_size_type amt = outsym - flinfo->outsyms;
+ if (bfd_seek (output_bfd, pos, SEEK_SET) != 0
+ || bfd_bwrite (flinfo->outsyms, amt, output_bfd) != amt)
+ return FALSE;
+
+ BFD_ASSERT ((obj_raw_syment_count (output_bfd)
+ + (outsym - flinfo->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->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
+ {
+ bfd_size_type sz = o->rawsize ? o->rawsize : o->size;
+ if (!bfd_get_section_contents (input_bfd, o, flinfo->contents, 0, sz))
+ return FALSE;
+ contents = flinfo->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, flinfo->external_relocs,
+ TRUE,
+ (flinfo->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, flinfo->info,
+ input_bfd, o,
+ contents,
+ internal_relocs,
+ flinfo->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 = (flinfo->section_info[target_index].rel_hashes
+ + o->output_section->reloc_count);
+ for (; irel < irelend; irel++, rel_hash++)
+ {
+ struct xcoff_link_hash_entry *h = NULL;
+
+ *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 && flinfo->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;
+ bfd_size_type amt;
+
+ amt = sizeof (* n);
+ n = bfd_alloc (flinfo->output_bfd, amt);
+ if (n == NULL)
+ return FALSE;
+ si = flinfo->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 = flinfo->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 = flinfo->internal_syms + r_symndx;
+ if (is->n_sclass == C_HIDEXT
+ && is->n_numaux > 0)
+ {
+ void * auxptr;
+ union internal_auxent aux;
+
+ auxptr = ((void *)
+ (((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,
+ (void *) &aux);
+ if (SMTYP_SMTYP (aux.x_csect.x_smtyp) == XTY_SD
+ && aux.x_csect.x_smclas == XMC_TC0)
+ indx = flinfo->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 = flinfo->internal_syms + r_symndx;
+
+ if (is->n_sclass != C_DWARF)
+ {
+ name = (_bfd_coff_internal_syment_name
+ (input_bfd, is, buf));
+
+ if (name == NULL)
+ return FALSE;
+
+ if (!(*flinfo->info->callbacks->unattached_reloc)
+ (flinfo->info, name, input_bfd, o,
+ irel->r_vaddr))
+ return FALSE;
+ }
+ }
+ }
+ }
+
+ if ((o->flags & SEC_DEBUGGING) == 0
+ && xcoff_need_ldrel_p (flinfo->info, irel, h))
+ {
+ asection *sec;
+
+ if (r_symndx == -1)
+ sec = NULL;
+ else if (h == NULL)
+ sec = xcoff_data (input_bfd)->csects[r_symndx];
+ else
+ sec = xcoff_symbol_section (h);
+ if (!xcoff_create_ldrel (output_bfd, flinfo,
+ o->output_section, input_bfd,
+ irel, sec, h))
+ return FALSE;
+ }
+ }
+
+ 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, (file_ptr) o->output_offset,
+ o->size))
+ return FALSE;
+ }
+
+ obj_coff_keep_syms (input_bfd) = keep_syms;
+
+ if (! flinfo->info->keep_memory)
+ {
+ if (! _bfd_coff_free_symbols (input_bfd))
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+#undef N_TMASK
+#undef N_BTSHFT
+
+/* Sort relocs by VMA. This is called via qsort. */
+
+static int
+xcoff_sort_relocs (const void * p1, const void * 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;
+}
+
+/* Return true if section SEC is a TOC section. */
+
+static inline bfd_boolean
+xcoff_toc_section_p (asection *sec)
+{
+ const char *name;
+
+ name = sec->name;
+ if (name[0] == '.' && name[1] == 't')
+ {
+ if (name[2] == 'c')
+ {
+ if (name[3] == '0' && name[4] == 0)
+ return TRUE;
+ if (name[3] == 0)
+ return TRUE;
+ }
+ if (name[2] == 'd' && name[3] == 0)
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/* See if the link requires a TOC (it usually does!). If so, find a
+ good place to put the TOC anchor csect, and write out the associated
+ symbol. */
+
+static bfd_boolean
+xcoff_find_tc0 (bfd *output_bfd, struct xcoff_final_link_info *flinfo)
+{
+ bfd_vma toc_start, toc_end, start, end, best_address;
+ asection *sec;
+ bfd *input_bfd;
+ int section_index;
+ struct internal_syment irsym;
+ union internal_auxent iraux;
+ file_ptr pos;
+ size_t size;
+
+ /* Set [TOC_START, TOC_END) to the range of the TOC. Record the
+ index of a csect at the beginning of the TOC. */
+ toc_start = ~(bfd_vma) 0;
+ toc_end = 0;
+ section_index = -1;
+ for (input_bfd = flinfo->info->input_bfds;
+ input_bfd != NULL;
+ input_bfd = input_bfd->link.next)
+ for (sec = input_bfd->sections; sec != NULL; sec = sec->next)
+ if ((sec->flags & SEC_MARK) != 0 && xcoff_toc_section_p (sec))
+ {
+ start = sec->output_section->vma + sec->output_offset;
+ if (toc_start > start)
+ {
+ toc_start = start;
+ section_index = sec->output_section->target_index;
+ }
+
+ end = start + sec->size;
+ if (toc_end < end)
+ toc_end = end;
+ }
+
+ /* There's no need for a TC0 symbol if we don't have a TOC. */
+ if (toc_end < toc_start)
+ {
+ xcoff_data (output_bfd)->toc = toc_start;
+ return TRUE;
+ }
+
+ if (toc_end - toc_start < 0x8000)
+ /* Every TOC csect can be accessed from TOC_START. */
+ best_address = toc_start;
+ else
+ {
+ /* Find the lowest TOC csect that is still within range of TOC_END. */
+ best_address = toc_end;
+ for (input_bfd = flinfo->info->input_bfds;
+ input_bfd != NULL;
+ input_bfd = input_bfd->link.next)
+ for (sec = input_bfd->sections; sec != NULL; sec = sec->next)
+ if ((sec->flags & SEC_MARK) != 0 && xcoff_toc_section_p (sec))
+ {
+ start = sec->output_section->vma + sec->output_offset;
+ if (start < best_address
+ && start + 0x8000 >= toc_end)
+ {
+ best_address = start;
+ section_index = sec->output_section->target_index;
+ }
+ }
+
+ /* Make sure that the start of the TOC is also within range. */
+ if (best_address > toc_start + 0x8000)
+ {
+ (*_bfd_error_handler)
+ (_("TOC overflow: 0x%lx > 0x10000; try -mminimal-toc "
+ "when compiling"),
+ (unsigned long) (toc_end - toc_start));
+ bfd_set_error (bfd_error_file_too_big);
+ return FALSE;
+ }
+ }
+
+ /* Record the chosen TOC value. */
+ flinfo->toc_symindx = obj_raw_syment_count (output_bfd);
+ xcoff_data (output_bfd)->toc = best_address;
+ xcoff_data (output_bfd)->sntoc = section_index;
+
+ /* Fill out the TC0 symbol. */
+ if (!bfd_xcoff_put_symbol_name (output_bfd, flinfo->strtab, &irsym, "TOC"))
+ return FALSE;
+ irsym.n_value = best_address;
+ irsym.n_scnum = section_index;
+ irsym.n_sclass = C_HIDEXT;
+ irsym.n_type = T_NULL;
+ irsym.n_numaux = 1;
+ bfd_coff_swap_sym_out (output_bfd, &irsym, flinfo->outsyms);
+
+ /* Fill out the auxillary csect information. */
+ memset (&iraux, 0, sizeof iraux);
+ iraux.x_csect.x_smtyp = XTY_SD;
+ iraux.x_csect.x_smclas = XMC_TC0;
+ iraux.x_csect.x_scnlen.l = 0;
+ bfd_coff_swap_aux_out (output_bfd, &iraux, T_NULL, C_HIDEXT, 0, 1,
+ flinfo->outsyms + bfd_coff_symesz (output_bfd));
+
+ /* Write the contents to the file. */
+ pos = obj_sym_filepos (output_bfd);
+ pos += obj_raw_syment_count (output_bfd) * bfd_coff_symesz (output_bfd);
+ size = 2 * bfd_coff_symesz (output_bfd);
+ if (bfd_seek (output_bfd, pos, SEEK_SET) != 0
+ || bfd_bwrite (flinfo->outsyms, size, output_bfd) != size)
+ return FALSE;
+ obj_raw_syment_count (output_bfd) += 2;
+
+ return TRUE;
+}
+
+/* Write out a non-XCOFF global symbol. */
+
+static bfd_boolean
+xcoff_write_global_symbol (struct bfd_hash_entry *bh, void * inf)
+{
+ struct xcoff_link_hash_entry *h = (struct xcoff_link_hash_entry *) bh;
+ struct xcoff_final_link_info *flinfo = (struct xcoff_final_link_info *) inf;
+ bfd *output_bfd;
+ bfd_byte *outsym;
+ struct internal_syment isym;
+ union internal_auxent aux;
+ bfd_boolean result;
+ file_ptr pos;
+ bfd_size_type amt;
+
+ output_bfd = flinfo->output_bfd;
+ outsym = flinfo->outsyms;
+
+ if (h->root.type == bfd_link_hash_warning)
+ {
+ h = (struct xcoff_link_hash_entry *) h->root.u.i.link;
+ if (h->root.type == bfd_link_hash_new)
+ return TRUE;
+ }
+
+ /* If this symbol was garbage collected, just skip it. */
+ if (xcoff_hash_table (flinfo->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)
+ /* Clear l_smtype
+ Import symbols are defined so the check above will make
+ the l_smtype XTY_SD. But this is not correct, it should
+ be cleared. */
+ 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;
+
+ if ((h->flags & XCOFF_RTINIT) != 0)
+ ldsym->l_smtype = XTY_SD;
+
+ ldsym->l_smclas = h->smclas;
+
+ if (ldsym->l_smtype & L_IMPORT)
+ {
+ if ((h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak)
+ && (h->root.u.def.value != 0))
+ ldsym->l_smclas = XMC_XO;
+
+ else if ((h->flags & (XCOFF_SYSCALL32 | XCOFF_SYSCALL64)) ==
+ (XCOFF_SYSCALL32 | XCOFF_SYSCALL64))
+ ldsym->l_smclas = XMC_SV3264;
+
+ else if (h->flags & XCOFF_SYSCALL32)
+ ldsym->l_smclas = XMC_SV;
+
+ else if (h->flags & XCOFF_SYSCALL64)
+ ldsym->l_smclas = XMC_SV64;
+ }
+
+ 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_xcoff_swap_ldsym_out (output_bfd, ldsym,
+ (flinfo->ldsym +
+ (h->ldindx - 3)
+ * bfd_xcoff_ldsymsz(flinfo->output_bfd)));
+ 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 (flinfo->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;
+
+ /* The first instruction in the glink code needs to be
+ cooked to to hold the correct offset in the toc. The
+ rest are just output raw. */
+ bfd_put_32 (output_bfd,
+ bfd_xcoff_glink_code(output_bfd, 0) | (tocoff & 0xffff), p);
+
+ /* Start with i == 1 to get past the first instruction done above
+ The /4 is because the glink code is in bytes and we are going
+ 4 at a pop. */
+ for (i = 1; i < bfd_xcoff_glink_code_size(output_bfd) / 4; i++)
+ bfd_put_32 (output_bfd,
+ (bfd_vma) bfd_xcoff_glink_code(output_bfd, i),
+ &p[4 * i]);
+ }
+
+ /* 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_syment irsym;
+ union internal_auxent iraux;
+
+ tocsec = h->toc_section;
+ osec = tocsec->output_section;
+ oindx = osec->target_index;
+ irel = flinfo->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);
+ }
+
+ BFD_ASSERT (h->ldindx >= 0);
+
+ /* Initialize the aux union here instead of closer to when it is
+ written out below because the length of the csect depends on
+ whether the output is 32 or 64 bit. */
+ memset (&iraux, 0, sizeof iraux);
+ iraux.x_csect.x_smtyp = XTY_SD;
+ /* iraux.x_csect.x_scnlen.l = 4 or 8, see below. */
+ iraux.x_csect.x_smclas = XMC_TC;
+
+ /* 32 bit uses a 32 bit R_POS to do the relocations
+ 64 bit uses a 64 bit R_POS to do the relocations
+
+ Also needs to change the csect size : 4 for 32 bit, 8 for 64 bit
+
+ Which one is determined by the backend. */
+ if (bfd_xcoff_is_xcoff64 (output_bfd))
+ {
+ irel->r_size = 63;
+ iraux.x_csect.x_scnlen.l = 8;
+ }
+ else if (bfd_xcoff_is_xcoff32 (output_bfd))
+ {
+ irel->r_size = 31;
+ iraux.x_csect.x_scnlen.l = 4;
+ }
+ else
+ return FALSE;
+
+ irel->r_type = R_POS;
+ flinfo->section_info[oindx].rel_hashes[osec->reloc_count] = NULL;
+ ++osec->reloc_count;
+
+ if (!xcoff_create_ldrel (output_bfd, flinfo, osec,
+ output_bfd, irel, NULL, h))
+ return FALSE;
+
+ /* We need to emit a symbol to define a csect which holds
+ the reloc. */
+ if (flinfo->info->strip != strip_all)
+ {
+ result = bfd_xcoff_put_symbol_name (output_bfd, flinfo->strtab,
+ &irsym, h->root.root.string);
+ if (!result)
+ return FALSE;
+
+ 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, (void *) &irsym, (void *) outsym);
+ outsym += bfd_coff_symesz (output_bfd);
+
+ /* Note : iraux is initialized above. */
+ bfd_coff_swap_aux_out (output_bfd, (void *) &iraux, T_NULL, C_HIDEXT,
+ 0, 1, (void *) 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. */
+ pos = obj_sym_filepos (output_bfd);
+ pos += (obj_raw_syment_count (output_bfd)
+ * bfd_coff_symesz (output_bfd));
+ amt = outsym - flinfo->outsyms;
+ if (bfd_seek (output_bfd, pos, SEEK_SET) != 0
+ || bfd_bwrite (flinfo->outsyms, amt, output_bfd) != amt)
+ return FALSE;
+ obj_raw_syment_count (output_bfd) +=
+ (outsym - flinfo->outsyms) / bfd_coff_symesz (output_bfd);
+
+ outsym = flinfo->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.
+
+ 32 bit vs 64 bit
+ The addresses for the 32 bit will take 4 bytes and the addresses
+ for 64 bit will take 8 bytes. Similar for the relocs. This type
+ of logic was also done above to create a TOC entry in
+ xcoff_write_global_symbol. */
+ if ((h->flags & XCOFF_DESCRIPTOR) != 0
+ && h->root.type == bfd_link_hash_defined
+ && (h->root.u.def.section
+ == xcoff_hash_table (flinfo->info)->descriptor_section))
+ {
+ asection *sec;
+ asection *osec;
+ int oindx;
+ bfd_byte *p;
+ struct xcoff_link_hash_entry *hentry;
+ asection *esec;
+ struct internal_reloc *irel;
+ asection *tsec;
+ unsigned int reloc_size, byte_size;
+
+ if (bfd_xcoff_is_xcoff64 (output_bfd))
+ {
+ reloc_size = 63;
+ byte_size = 8;
+ }
+ else if (bfd_xcoff_is_xcoff32 (output_bfd))
+ {
+ reloc_size = 31;
+ byte_size = 4;
+ }
+ else
+ return FALSE;
+
+ 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;
+
+ irel = flinfo->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 = reloc_size;
+ flinfo->section_info[oindx].rel_hashes[osec->reloc_count] = NULL;
+ ++osec->reloc_count;
+
+ if (!xcoff_create_ldrel (output_bfd, flinfo, osec,
+ output_bfd, irel, esec, NULL))
+ return FALSE;
+
+ /* There are three items to write out,
+ the address of the code
+ the address of the toc anchor
+ the environment pointer.
+ We are ignoring the environment pointer. So set it to zero. */
+ if (bfd_xcoff_is_xcoff64 (output_bfd))
+ {
+ bfd_put_64 (output_bfd,
+ (esec->output_section->vma + esec->output_offset
+ + hentry->root.u.def.value),
+ p);
+ bfd_put_64 (output_bfd, xcoff_data (output_bfd)->toc, p + 8);
+ bfd_put_64 (output_bfd, (bfd_vma) 0, p + 16);
+ }
+ else
+ {
+ /* 32 bit backend
+ This logic was already called above so the error case where
+ the backend is neither has already been checked. */
+ bfd_put_32 (output_bfd,
+ (esec->output_section->vma + esec->output_offset
+ + hentry->root.u.def.value),
+ p);
+ bfd_put_32 (output_bfd, xcoff_data (output_bfd)->toc, p + 4);
+ bfd_put_32 (output_bfd, (bfd_vma) 0, p + 8);
+ }
+
+ 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
+ + byte_size);
+ irel->r_symndx = tsec->output_section->target_index;
+ irel->r_type = R_POS;
+ irel->r_size = reloc_size;
+ flinfo->section_info[oindx].rel_hashes[osec->reloc_count] = NULL;
+ ++osec->reloc_count;
+
+ if (!xcoff_create_ldrel (output_bfd, flinfo, osec,
+ output_bfd, irel, tsec, NULL))
+ return FALSE;
+ }
+
+ if (h->indx >= 0 || flinfo->info->strip == strip_all)
+ {
+ BFD_ASSERT (outsym == flinfo->outsyms);
+ return TRUE;
+ }
+
+ if (h->indx != -2
+ && (flinfo->info->strip == strip_all
+ || (flinfo->info->strip == strip_some
+ && bfd_hash_lookup (flinfo->info->keep_hash, h->root.root.string,
+ FALSE, FALSE) == NULL)))
+ {
+ BFD_ASSERT (outsym == flinfo->outsyms);
+ return TRUE;
+ }
+
+ if (h->indx != -2
+ && (h->flags & (XCOFF_REF_REGULAR | XCOFF_DEF_REGULAR)) == 0)
+ {
+ BFD_ASSERT (outsym == flinfo->outsyms);
+ return TRUE;
+ }
+
+ memset (&aux, 0, sizeof aux);
+
+ h->indx = obj_raw_syment_count (output_bfd);
+
+ result = bfd_xcoff_put_symbol_name (output_bfd, flinfo->strtab, &isym,
+ h->root.root.string);
+ if (!result)
+ return FALSE;
+
+ if (h->root.type == bfd_link_hash_undefined
+ || h->root.type == bfd_link_hash_undefweak)
+ {
+ isym.n_value = 0;
+ isym.n_scnum = N_UNDEF;
+ if (h->root.type == bfd_link_hash_undefweak
+ && C_WEAKEXT == C_AIX_WEAKEXT)
+ isym.n_sclass = C_WEAKEXT;
+ else
+ 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;
+ if (h->root.type == bfd_link_hash_undefweak
+ && C_WEAKEXT == C_AIX_WEAKEXT)
+ isym.n_sclass = C_WEAKEXT;
+ else
+ 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);
+ if (bfd_is_abs_section (h->root.u.def.section->output_section))
+ isym.n_scnum = N_ABS;
+ else
+ 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 (flinfo->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, (void *) &isym, (void *) outsym);
+ outsym += bfd_coff_symesz (output_bfd);
+
+ aux.x_csect.x_smclas = h->smclas;
+ bfd_coff_swap_aux_out (output_bfd, (void *) &aux, T_NULL, isym.n_sclass, 0, 1,
+ (void *) 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;
+
+ if (h->root.type == bfd_link_hash_undefweak
+ && C_WEAKEXT == C_AIX_WEAKEXT)
+ isym.n_sclass = C_WEAKEXT;
+ else
+ isym.n_sclass = C_EXT;
+ bfd_coff_swap_sym_out (output_bfd, (void *) &isym, (void *) 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, (void *) &aux, T_NULL, C_EXT, 0, 1,
+ (void *) outsym);
+ outsym += bfd_coff_auxesz (output_bfd);
+ }
+
+ pos = obj_sym_filepos (output_bfd);
+ pos += obj_raw_syment_count (output_bfd) * bfd_coff_symesz (output_bfd);
+ amt = outsym - flinfo->outsyms;
+ if (bfd_seek (output_bfd, pos, SEEK_SET) != 0
+ || bfd_bwrite (flinfo->outsyms, amt, output_bfd) != amt)
+ return FALSE;
+ obj_raw_syment_count (output_bfd) +=
+ (outsym - flinfo->outsyms) / bfd_coff_symesz (output_bfd);
+
+ return TRUE;
+}
+
+/* Handle a link order which is supposed to generate a reloc. */
+
+static bfd_boolean
+xcoff_reloc_link_order (bfd *output_bfd,
+ struct xcoff_final_link_info *flinfo,
+ 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;
+
+ 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, flinfo->info,
+ link_order->u.reloc.p->u.name,
+ FALSE, FALSE, TRUE));
+ if (h == NULL)
+ {
+ if (! ((*flinfo->info->callbacks->unattached_reloc)
+ (flinfo->info, link_order->u.reloc.p->u.name, NULL, NULL, (bfd_vma) 0)))
+ return FALSE;
+ return TRUE;
+ }
+
+ hsec = xcoff_symbol_section (h);
+ if (h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak)
+ hval = h->root.u.def.value;
+ else
+ 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;
+ bfd_boolean ok;
+
+ size = bfd_get_reloc_size (howto);
+ buf = 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 (! ((*flinfo->info->callbacks->reloc_overflow)
+ (flinfo->info, NULL, link_order->u.reloc.p->u.name,
+ howto->name, addend, NULL, NULL, (bfd_vma) 0)))
+ {
+ free (buf);
+ return FALSE;
+ }
+ break;
+ }
+ ok = bfd_set_section_contents (output_bfd, output_section, (void *) 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 = (flinfo->section_info[output_section->target_index].relocs
+ + output_section->reloc_count);
+ rel_hash_ptr = (flinfo->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. */
+ if (xcoff_hash_table (flinfo->info)->loader_section)
+ {
+ if (!xcoff_create_ldrel (output_bfd, flinfo, output_section,
+ output_bfd, irel, hsec, h))
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/* Do the final link step. */
+
+bfd_boolean
+_bfd_xcoff_bfd_final_link (bfd *abfd, struct bfd_link_info *info)
+{
+ bfd_size_type symesz;
+ struct xcoff_final_link_info flinfo;
+ asection *o;
+ struct bfd_link_order *p;
+ bfd_size_type max_contents_size;
+ bfd_size_type max_sym_count;
+ bfd_size_type max_lineno_count;
+ bfd_size_type max_reloc_count;
+ bfd_size_type 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];
+ file_ptr pos;
+ bfd_size_type amt;
+
+ if (info->shared)
+ abfd->flags |= DYNAMIC;
+
+ symesz = bfd_coff_symesz (abfd);
+
+ flinfo.info = info;
+ flinfo.output_bfd = abfd;
+ flinfo.strtab = NULL;
+ flinfo.section_info = NULL;
+ flinfo.last_file_index = -1;
+ flinfo.toc_symindx = -1;
+ flinfo.internal_syms = NULL;
+ flinfo.sym_indices = NULL;
+ flinfo.outsyms = NULL;
+ flinfo.linenos = NULL;
+ flinfo.contents = NULL;
+ flinfo.external_relocs = NULL;
+
+ if (xcoff_hash_table (info)->loader_section)
+ {
+ flinfo.ldsym = (xcoff_hash_table (info)->loader_section->contents
+ + bfd_xcoff_ldhdrsz (abfd));
+ flinfo.ldrel = (xcoff_hash_table (info)->loader_section->contents
+ + bfd_xcoff_ldhdrsz (abfd)
+ + (xcoff_hash_table (info)->ldhdr.l_nsyms
+ * bfd_xcoff_ldsymsz (abfd)));
+ }
+ else
+ {
+ flinfo.ldsym = NULL;
+ flinfo.ldrel = NULL;
+ }
+
+ xcoff_data (abfd)->coff.link_info = info;
+
+ flinfo.strtab = _bfd_stringtab_init ();
+ if (flinfo.strtab == NULL)
+ goto error_return;
+
+ /* Count the relocation entries required for the output file.
+ (We've already counted the line numbers.) 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;
+ for (p = o->map_head.link_order; 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;
+
+ o->reloc_count += sec->reloc_count;
+
+ if ((sec->flags & SEC_IN_MEMORY) == 0)
+ {
+ if (sec->rawsize > max_contents_size)
+ max_contents_size = sec->rawsize;
+ if (sec->size > max_contents_size)
+ max_contents_size = sec->size;
+ }
+ 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)
+ {
+ bfd_boolean saw_contents;
+ int indx;
+ 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 (o = abfd->sections; o != NULL; o = o->next)
+ {
+ if (strcmp (o->name, ".pad") == 0)
+ saw_contents = FALSE;
+ else if ((o->flags & SEC_HAS_CONTENTS) != 0
+ && (o->flags & SEC_LOAD) != 0)
+ {
+ if (! saw_contents)
+ saw_contents = TRUE;
+ else
+ {
+ asection *n;
+
+ /* Create a pad section and place it before the section
+ that needs padding. This requires unlinking and
+ relinking the bfd's section list. */
+
+ n = bfd_make_section_anyway_with_flags (abfd, ".pad",
+ SEC_HAS_CONTENTS);
+ n->alignment_power = 0;
+
+ bfd_section_list_remove (abfd, n);
+ bfd_section_list_insert_before (abfd, o, n);
+ 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 ((bfd_xcoff_is_reloc_count_overflow
+ (abfd, (bfd_vma) o->reloc_count))
+ || (bfd_xcoff_is_lineno_count_overflow
+ (abfd, (bfd_vma) o->lineno_count)))
+ /* 64 does not overflow, need to check if 32 does */
+ 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->size == 0);
+ pageoff = sofar & (file_align - 1);
+ if (pageoff != 0)
+ {
+ o->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->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. */
+ amt = abfd->section_count + 1;
+ amt *= sizeof (struct xcoff_link_section_info);
+ flinfo.section_info = bfd_malloc (amt);
+ if (flinfo.section_info == NULL)
+ goto error_return;
+ for (i = 0; i <= abfd->section_count; i++)
+ {
+ flinfo.section_info[i].relocs = NULL;
+ flinfo.section_info[i].rel_hashes = NULL;
+ flinfo.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. */
+ amt = o->reloc_count;
+ amt *= sizeof (struct internal_reloc);
+ flinfo.section_info[o->target_index].relocs = bfd_malloc (amt);
+
+ amt = o->reloc_count;
+ amt *= sizeof (struct xcoff_link_hash_entry *);
+ flinfo.section_info[o->target_index].rel_hashes = bfd_malloc (amt);
+
+ if (flinfo.section_info[o->target_index].relocs == NULL
+ || flinfo.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;
+ flinfo.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)
+ {
+ bfd_size_type 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. */
+ amt = max_sym_count * sizeof (struct internal_syment);
+ flinfo.internal_syms = bfd_malloc (amt);
+
+ amt = max_sym_count * sizeof (long);
+ flinfo.sym_indices = bfd_malloc (amt);
+
+ amt = (max_sym_count + 1) * symesz;
+ flinfo.outsyms = bfd_malloc (amt);
+
+ amt = max_lineno_count * bfd_coff_linesz (abfd);
+ flinfo.linenos = bfd_malloc (amt);
+
+ amt = max_contents_size;
+ flinfo.contents = bfd_malloc (amt);
+
+ amt = max_reloc_count * relsz;
+ flinfo.external_relocs = bfd_malloc (amt);
+
+ if ((flinfo.internal_syms == NULL && max_sym_count > 0)
+ || (flinfo.sym_indices == NULL && max_sym_count > 0)
+ || flinfo.outsyms == NULL
+ || (flinfo.linenos == NULL && max_lineno_count > 0)
+ || (flinfo.contents == NULL && max_contents_size > 0)
+ || (flinfo.external_relocs == NULL && max_reloc_count > 0))
+ goto error_return;
+
+ obj_raw_syment_count (abfd) = 0;
+
+ /* Find a TOC symbol, if we need one. */
+ if (!xcoff_find_tc0 (abfd, &flinfo))
+ 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. */
+ for (o = abfd->sections; o != NULL; o = o->next)
+ {
+ for (p = o->map_head.link_order; 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 (&flinfo, 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, &flinfo, 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 (flinfo.internal_syms != NULL)
+ {
+ free (flinfo.internal_syms);
+ flinfo.internal_syms = NULL;
+ }
+ if (flinfo.sym_indices != NULL)
+ {
+ free (flinfo.sym_indices);
+ flinfo.sym_indices = NULL;
+ }
+ if (flinfo.linenos != NULL)
+ {
+ free (flinfo.linenos);
+ flinfo.linenos = NULL;
+ }
+ if (flinfo.contents != NULL)
+ {
+ free (flinfo.contents);
+ flinfo.contents = NULL;
+ }
+ if (flinfo.external_relocs != NULL)
+ {
+ free (flinfo.external_relocs);
+ flinfo.external_relocs = NULL;
+ }
+
+ /* The value of the last C_FILE symbol is supposed to be -1. Write
+ it out again. */
+ if (flinfo.last_file_index != -1)
+ {
+ flinfo.last_file.n_value = -(bfd_vma) 1;
+ bfd_coff_swap_sym_out (abfd, (void *) &flinfo.last_file,
+ (void *) flinfo.outsyms);
+ pos = obj_sym_filepos (abfd) + flinfo.last_file_index * symesz;
+ if (bfd_seek (abfd, pos, SEEK_SET) != 0
+ || bfd_bwrite (flinfo.outsyms, symesz, abfd) != symesz)
+ goto error_return;
+ }
+
+ /* Write out all the global symbols which do not come from XCOFF
+ input files. */
+ bfd_hash_traverse (&info->hash->table, xcoff_write_global_symbol, &flinfo);
+
+ if (flinfo.outsyms != NULL)
+ {
+ free (flinfo.outsyms);
+ flinfo.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. */
+ amt = max_output_reloc_count * relsz;
+ external_relocs = bfd_malloc (amt);
+ 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;
+ bfd_size_type rel_size;
+
+ /* A stripped file has no relocs. */
+ if (info->strip == strip_all)
+ {
+ o->reloc_count = 0;
+ continue;
+ }
+
+ if (o->reloc_count == 0)
+ continue;
+
+ irel = flinfo.section_info[o->target_index].relocs;
+ irelend = irel + o->reloc_count;
+ rel_hash = flinfo.section_info[o->target_index].rel_hashes;
+ for (; irel < irelend; irel++, rel_hash++)
+ {
+ if (*rel_hash != NULL)
+ {
+ if ((*rel_hash)->indx < 0)
+ {
+ if (! ((*info->callbacks->unattached_reloc)
+ (info, (*rel_hash)->root.root.string,
+ NULL, o, irel->r_vaddr)))
+ goto error_return;
+ (*rel_hash)->indx = 0;
+ }
+ irel->r_symndx = (*rel_hash)->indx;
+ }
+ }
+
+ for (toc_rel_hash = flinfo.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,
+ 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 ((void *) flinfo.section_info[o->target_index].relocs,
+ o->reloc_count, sizeof (struct internal_reloc),
+ xcoff_sort_relocs);
+
+ irel = flinfo.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, (void *) irel, (void *) erel);
+
+ rel_size = relsz * o->reloc_count;
+ if (bfd_seek (abfd, o->rel_filepos, SEEK_SET) != 0
+ || bfd_bwrite ((void *) external_relocs, rel_size, abfd) != rel_size)
+ goto error_return;
+ }
+
+ if (external_relocs != NULL)
+ {
+ free (external_relocs);
+ external_relocs = NULL;
+ }
+
+ /* Free up the section information. */
+ if (flinfo.section_info != NULL)
+ {
+ unsigned int i;
+
+ for (i = 0; i < abfd->section_count; i++)
+ {
+ if (flinfo.section_info[i].relocs != NULL)
+ free (flinfo.section_info[i].relocs);
+ if (flinfo.section_info[i].rel_hashes != NULL)
+ free (flinfo.section_info[i].rel_hashes);
+ }
+ free (flinfo.section_info);
+ flinfo.section_info = NULL;
+ }
+
+ /* Write out the loader section contents. */
+ o = xcoff_hash_table (info)->loader_section;
+ if (o)
+ {
+ BFD_ASSERT ((bfd_byte *) flinfo.ldrel
+ == (xcoff_hash_table (info)->loader_section->contents
+ + xcoff_hash_table (info)->ldhdr.l_impoff));
+ if (!bfd_set_section_contents (abfd, o->output_section, o->contents,
+ (file_ptr) o->output_offset, o->size))
+ goto error_return;
+ }
+
+ /* Write out the magic sections. */
+ o = xcoff_hash_table (info)->linkage_section;
+ if (o->size > 0
+ && ! bfd_set_section_contents (abfd, o->output_section, o->contents,
+ (file_ptr) o->output_offset,
+ o->size))
+ goto error_return;
+ o = xcoff_hash_table (info)->toc_section;
+ if (o->size > 0
+ && ! bfd_set_section_contents (abfd, o->output_section, o->contents,
+ (file_ptr) o->output_offset,
+ o->size))
+ goto error_return;
+ o = xcoff_hash_table (info)->descriptor_section;
+ if (o->size > 0
+ && ! bfd_set_section_contents (abfd, o->output_section, o->contents,
+ (file_ptr) o->output_offset,
+ o->size))
+ goto error_return;
+
+ /* Write out the string table. */
+ pos = obj_sym_filepos (abfd) + obj_raw_syment_count (abfd) * symesz;
+ if (bfd_seek (abfd, pos, SEEK_SET) != 0)
+ goto error_return;
+ H_PUT_32 (abfd,
+ _bfd_stringtab_size (flinfo.strtab) + STRING_SIZE_SIZE,
+ strbuf);
+ amt = STRING_SIZE_SIZE;
+ if (bfd_bwrite (strbuf, amt, abfd) != amt)
+ goto error_return;
+ if (! _bfd_stringtab_emit (abfd, flinfo.strtab))
+ goto error_return;
+
+ _bfd_stringtab_free (flinfo.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->size - o->output_offset
+ >= _bfd_stringtab_size (debug_strtab));
+ pos = o->output_section->filepos + o->output_offset;
+ if (bfd_seek (abfd, pos, 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 (flinfo.strtab != NULL)
+ _bfd_stringtab_free (flinfo.strtab);
+
+ if (flinfo.section_info != NULL)
+ {
+ unsigned int i;
+
+ for (i = 0; i < abfd->section_count; i++)
+ {
+ if (flinfo.section_info[i].relocs != NULL)
+ free (flinfo.section_info[i].relocs);
+ if (flinfo.section_info[i].rel_hashes != NULL)
+ free (flinfo.section_info[i].rel_hashes);
+ }
+ free (flinfo.section_info);
+ }
+
+ if (flinfo.internal_syms != NULL)
+ free (flinfo.internal_syms);
+ if (flinfo.sym_indices != NULL)
+ free (flinfo.sym_indices);
+ if (flinfo.outsyms != NULL)
+ free (flinfo.outsyms);
+ if (flinfo.linenos != NULL)
+ free (flinfo.linenos);
+ if (flinfo.contents != NULL)
+ free (flinfo.contents);
+ if (flinfo.external_relocs != NULL)
+ free (flinfo.external_relocs);
+ if (external_relocs != NULL)
+ free (external_relocs);
+ return FALSE;
+}
diff --git a/bfd/xsym.c b/bfd/xsym.c
new file mode 100644
index 0000000..4e2a8ab
--- /dev/null
+++ b/bfd/xsym.c
@@ -0,0 +1,2354 @@
+/* xSYM symbol-file support for BFD.
+ Copyright (C) 1999-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+/* xSYM is the debugging format used by CodeWarrior on Mac OS classic. */
+
+#include "sysdep.h"
+#include "alloca-conf.h"
+#include "xsym.h"
+#include "bfd.h"
+#include "libbfd.h"
+
+#define bfd_sym_close_and_cleanup _bfd_generic_close_and_cleanup
+#define bfd_sym_bfd_free_cached_info _bfd_generic_bfd_free_cached_info
+#define bfd_sym_new_section_hook _bfd_generic_new_section_hook
+#define bfd_sym_bfd_is_local_label_name bfd_generic_is_local_label_name
+#define bfd_sym_bfd_is_target_special_symbol ((bfd_boolean (*) (bfd *, asymbol *)) bfd_false)
+#define bfd_sym_get_lineno _bfd_nosymbols_get_lineno
+#define bfd_sym_find_nearest_line _bfd_nosymbols_find_nearest_line
+#define bfd_sym_find_line _bfd_nosymbols_find_line
+#define bfd_sym_find_inliner_info _bfd_nosymbols_find_inliner_info
+#define bfd_sym_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol
+#define bfd_sym_read_minisymbols _bfd_generic_read_minisymbols
+#define bfd_sym_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol
+#define bfd_sym_set_arch_mach _bfd_generic_set_arch_mach
+#define bfd_sym_get_section_contents _bfd_generic_get_section_contents
+#define bfd_sym_set_section_contents _bfd_generic_set_section_contents
+#define bfd_sym_bfd_get_relocated_section_contents bfd_generic_get_relocated_section_contents
+#define bfd_sym_bfd_relax_section bfd_generic_relax_section
+#define bfd_sym_bfd_gc_sections bfd_generic_gc_sections
+#define bfd_sym_bfd_lookup_section_flags bfd_generic_lookup_section_flags
+#define bfd_sym_bfd_merge_sections bfd_generic_merge_sections
+#define bfd_sym_bfd_is_group_section bfd_generic_is_group_section
+#define bfd_sym_bfd_discard_group bfd_generic_discard_group
+#define bfd_sym_section_already_linked _bfd_generic_section_already_linked
+#define bfd_sym_bfd_define_common_symbol bfd_generic_define_common_symbol
+#define bfd_sym_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
+#define bfd_sym_bfd_link_add_symbols _bfd_generic_link_add_symbols
+#define bfd_sym_bfd_link_just_syms _bfd_generic_link_just_syms
+#define bfd_sym_bfd_copy_link_hash_symbol_type \
+ _bfd_generic_copy_link_hash_symbol_type
+#define bfd_sym_bfd_final_link _bfd_generic_final_link
+#define bfd_sym_bfd_link_split_section _bfd_generic_link_split_section
+#define bfd_sym_get_section_contents_in_window _bfd_generic_get_section_contents_in_window
+
+extern const bfd_target sym_vec;
+
+static int
+pstrcmp (const char *as, const char *bs)
+{
+ const unsigned char *a = (const unsigned char *) as;
+ const unsigned char *b = (const unsigned char *) bs;
+ unsigned char clen;
+ int ret;
+
+ clen = (a[0] > b[0]) ? b[0] : a[0];
+ ret = memcmp (a + 1, b + 1, clen);
+ if (ret != 0)
+ return ret;
+
+ if (a[0] == b[0])
+ return 0;
+ else if (a[0] < b[0])
+ return -1;
+ else
+ return 1;
+}
+
+static unsigned long
+compute_offset (unsigned long first_page,
+ unsigned long page_size,
+ unsigned long entry_size,
+ unsigned long sym_index)
+{
+ unsigned long entries_per_page = page_size / entry_size;
+ unsigned long page_number = first_page + (sym_index / entries_per_page);
+ unsigned long page_offset = (sym_index % entries_per_page) * entry_size;
+
+ return (page_number * page_size) + page_offset;
+}
+
+bfd_boolean
+bfd_sym_mkobject (bfd *abfd ATTRIBUTE_UNUSED)
+{
+ return 1;
+}
+
+void
+bfd_sym_print_symbol (bfd *abfd ATTRIBUTE_UNUSED,
+ void * afile ATTRIBUTE_UNUSED,
+ asymbol *symbol ATTRIBUTE_UNUSED,
+ bfd_print_symbol_type how ATTRIBUTE_UNUSED)
+{
+ return;
+}
+
+bfd_boolean
+bfd_sym_valid (bfd *abfd)
+{
+ if (abfd == NULL || abfd->xvec == NULL)
+ return 0;
+
+ return abfd->xvec == &sym_vec;
+}
+
+unsigned char *
+bfd_sym_read_name_table (bfd *abfd, bfd_sym_header_block *dshb)
+{
+ unsigned char *rstr;
+ long ret;
+ size_t table_size = dshb->dshb_nte.dti_page_count * dshb->dshb_page_size;
+ size_t table_offset = dshb->dshb_nte.dti_first_page * dshb->dshb_page_size;
+
+ rstr = bfd_alloc (abfd, table_size);
+ if (rstr == NULL)
+ return rstr;
+
+ bfd_seek (abfd, table_offset, SEEK_SET);
+ ret = bfd_bread (rstr, table_size, abfd);
+ if (ret < 0 || (unsigned long) ret != table_size)
+ {
+ bfd_release (abfd, rstr);
+ return NULL;
+ }
+
+ return rstr;
+}
+
+void
+bfd_sym_parse_file_reference_v32 (unsigned char *buf,
+ size_t len,
+ bfd_sym_file_reference *entry)
+{
+ BFD_ASSERT (len == 6);
+
+ entry->fref_frte_index = bfd_getb16 (buf);
+ entry->fref_offset = bfd_getb32 (buf + 2);
+}
+
+void
+bfd_sym_parse_disk_table_v32 (unsigned char *buf,
+ size_t len,
+ bfd_sym_table_info *table)
+{
+ BFD_ASSERT (len == 8);
+
+ table->dti_first_page = bfd_getb16 (buf);
+ table->dti_page_count = bfd_getb16 (buf + 2);
+ table->dti_object_count = bfd_getb32 (buf + 4);
+}
+
+void
+bfd_sym_parse_header_v32 (unsigned char *buf,
+ size_t len,
+ bfd_sym_header_block *header)
+{
+ BFD_ASSERT (len == 154);
+
+ memcpy (header->dshb_id, buf, 32);
+ header->dshb_page_size = bfd_getb16 (buf + 32);
+ header->dshb_hash_page = bfd_getb16 (buf + 34);
+ header->dshb_root_mte = bfd_getb16 (buf + 36);
+ header->dshb_mod_date = bfd_getb32 (buf + 38);
+
+ bfd_sym_parse_disk_table_v32 (buf + 42, 8, &header->dshb_frte);
+ bfd_sym_parse_disk_table_v32 (buf + 50, 8, &header->dshb_rte);
+ bfd_sym_parse_disk_table_v32 (buf + 58, 8, &header->dshb_mte);
+ bfd_sym_parse_disk_table_v32 (buf + 66, 8, &header->dshb_cmte);
+ bfd_sym_parse_disk_table_v32 (buf + 74, 8, &header->dshb_cvte);
+ bfd_sym_parse_disk_table_v32 (buf + 82, 8, &header->dshb_csnte);
+ bfd_sym_parse_disk_table_v32 (buf + 90, 8, &header->dshb_clte);
+ bfd_sym_parse_disk_table_v32 (buf + 98, 8, &header->dshb_ctte);
+ bfd_sym_parse_disk_table_v32 (buf + 106, 8, &header->dshb_tte);
+ bfd_sym_parse_disk_table_v32 (buf + 114, 8, &header->dshb_nte);
+ bfd_sym_parse_disk_table_v32 (buf + 122, 8, &header->dshb_tinfo);
+ bfd_sym_parse_disk_table_v32 (buf + 130, 8, &header->dshb_fite);
+ bfd_sym_parse_disk_table_v32 (buf + 138, 8, &header->dshb_const);
+
+ memcpy (&header->dshb_file_creator, buf + 146, 4);
+ memcpy (&header->dshb_file_type, buf + 150, 4);
+}
+
+int
+bfd_sym_read_header_v32 (bfd *abfd, bfd_sym_header_block *header)
+{
+ unsigned char buf[154];
+ long ret;
+
+ ret = bfd_bread (buf, 154, abfd);
+ if (ret != 154)
+ return -1;
+
+ bfd_sym_parse_header_v32 (buf, 154, header);
+
+ return 0;
+}
+
+int
+bfd_sym_read_header_v34 (bfd *abfd ATTRIBUTE_UNUSED,
+ bfd_sym_header_block *header ATTRIBUTE_UNUSED)
+{
+ abort ();
+}
+
+int
+bfd_sym_read_header (bfd *abfd,
+ bfd_sym_header_block *header,
+ bfd_sym_version version)
+{
+ switch (version)
+ {
+ case BFD_SYM_VERSION_3_5:
+ case BFD_SYM_VERSION_3_4:
+ return bfd_sym_read_header_v34 (abfd, header);
+ case BFD_SYM_VERSION_3_3:
+ case BFD_SYM_VERSION_3_2:
+ return bfd_sym_read_header_v32 (abfd, header);
+ case BFD_SYM_VERSION_3_1:
+ default:
+ return 0;
+ }
+}
+
+int
+bfd_sym_read_version (bfd *abfd, bfd_sym_version *version)
+{
+ char version_string[32];
+ long ret;
+
+ ret = bfd_bread (version_string, sizeof (version_string), abfd);
+ if (ret != sizeof (version_string))
+ return -1;
+
+ if (pstrcmp (version_string, BFD_SYM_VERSION_STR_3_1) == 0)
+ *version = BFD_SYM_VERSION_3_1;
+ else if (pstrcmp (version_string, BFD_SYM_VERSION_STR_3_2) == 0)
+ *version = BFD_SYM_VERSION_3_2;
+ else if (pstrcmp (version_string, BFD_SYM_VERSION_STR_3_3) == 0)
+ *version = BFD_SYM_VERSION_3_3;
+ else if (pstrcmp (version_string, BFD_SYM_VERSION_STR_3_4) == 0)
+ *version = BFD_SYM_VERSION_3_4;
+ else if (pstrcmp (version_string, BFD_SYM_VERSION_STR_3_5) == 0)
+ *version = BFD_SYM_VERSION_3_5;
+ else
+ return -1;
+
+ return 0;
+}
+
+void
+bfd_sym_display_table_summary (FILE *f,
+ bfd_sym_table_info *dti,
+ const char *name)
+{
+ fprintf (f, "%-6s %13ld %13ld %13ld\n",
+ name,
+ dti->dti_first_page,
+ dti->dti_page_count,
+ dti->dti_object_count);
+}
+
+void
+bfd_sym_display_header (FILE *f, bfd_sym_header_block *dshb)
+{
+ fprintf (f, " Version: %.*s\n", dshb->dshb_id[0], dshb->dshb_id + 1);
+ fprintf (f, " Page Size: 0x%x\n", dshb->dshb_page_size);
+ fprintf (f, " Hash Page: %lu\n", dshb->dshb_hash_page);
+ fprintf (f, " Root MTE: %lu\n", dshb->dshb_root_mte);
+ fprintf (f, " Modification Date: ");
+ fprintf (f, "[unimplemented]");
+ fprintf (f, " (0x%lx)\n", dshb->dshb_mod_date);
+
+ fprintf (f, " File Creator: %.4s Type: %.4s\n\n",
+ dshb->dshb_file_creator, dshb->dshb_file_type);
+
+ fprintf (f, "Table Name First Page Page Count Object Count\n");
+ fprintf (f, "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
+
+ bfd_sym_display_table_summary (f, &dshb->dshb_nte, "NTE");
+ bfd_sym_display_table_summary (f, &dshb->dshb_rte, "RTE");
+ bfd_sym_display_table_summary (f, &dshb->dshb_mte, "MTE");
+ bfd_sym_display_table_summary (f, &dshb->dshb_frte, "FRTE");
+ bfd_sym_display_table_summary (f, &dshb->dshb_cmte, "CMTE");
+ bfd_sym_display_table_summary (f, &dshb->dshb_cvte, "CVTE");
+ bfd_sym_display_table_summary (f, &dshb->dshb_csnte, "CSNTE");
+ bfd_sym_display_table_summary (f, &dshb->dshb_clte, "CLTE");
+ bfd_sym_display_table_summary (f, &dshb->dshb_ctte, "CTTE");
+ bfd_sym_display_table_summary (f, &dshb->dshb_tte, "TTE");
+ bfd_sym_display_table_summary (f, &dshb->dshb_tinfo, "TINFO");
+ bfd_sym_display_table_summary (f, &dshb->dshb_fite, "FITE");
+ bfd_sym_display_table_summary (f, &dshb->dshb_const, "CONST");
+
+ fprintf (f, "\n");
+}
+
+void
+bfd_sym_parse_resources_table_entry_v32 (unsigned char *buf,
+ size_t len,
+ bfd_sym_resources_table_entry *entry)
+{
+ BFD_ASSERT (len == 18);
+
+ memcpy (&entry->rte_res_type, buf, 4);
+ entry->rte_res_number = bfd_getb16 (buf + 4);
+ entry->rte_nte_index = bfd_getb32 (buf + 6);
+ entry->rte_mte_first = bfd_getb16 (buf + 10);
+ entry->rte_mte_last = bfd_getb16 (buf + 12);
+ entry->rte_res_size = bfd_getb32 (buf + 14);
+}
+
+void
+bfd_sym_parse_modules_table_entry_v33 (unsigned char *buf,
+ size_t len,
+ bfd_sym_modules_table_entry *entry)
+{
+ BFD_ASSERT (len == 46);
+
+ entry->mte_rte_index = bfd_getb16 (buf);
+ entry->mte_res_offset = bfd_getb32 (buf + 2);
+ entry->mte_size = bfd_getb32 (buf + 6);
+ entry->mte_kind = buf[10];
+ entry->mte_scope = buf[11];
+ entry->mte_parent = bfd_getb16 (buf + 12);
+ bfd_sym_parse_file_reference_v32 (buf + 14, 6, &entry->mte_imp_fref);
+ entry->mte_imp_end = bfd_getb32 (buf + 20);
+ entry->mte_nte_index = bfd_getb32 (buf + 24);
+ entry->mte_cmte_index = bfd_getb16 (buf + 28);
+ entry->mte_cvte_index = bfd_getb32 (buf + 30);
+ entry->mte_clte_index = bfd_getb16 (buf + 34);
+ entry->mte_ctte_index = bfd_getb16 (buf + 36);
+ entry->mte_csnte_idx_1 = bfd_getb32 (buf + 38);
+ entry->mte_csnte_idx_2 = bfd_getb32 (buf + 42);
+}
+
+void
+bfd_sym_parse_file_references_table_entry_v32 (unsigned char *buf,
+ size_t len,
+ bfd_sym_file_references_table_entry *entry)
+{
+ unsigned int type;
+
+ BFD_ASSERT (len == 10);
+
+ memset (entry, 0, sizeof (bfd_sym_file_references_table_entry));
+ type = bfd_getb16 (buf);
+
+ switch (type)
+ {
+ case BFD_SYM_END_OF_LIST_3_2:
+ entry->generic.type = BFD_SYM_END_OF_LIST;
+ break;
+
+ case BFD_SYM_FILE_NAME_INDEX_3_2:
+ entry->filename.type = BFD_SYM_FILE_NAME_INDEX;
+ entry->filename.nte_index = bfd_getb32 (buf + 2);
+ entry->filename.mod_date = bfd_getb32 (buf + 6);
+ break;
+
+ default:
+ entry->entry.mte_index = type;
+ entry->entry.file_offset = bfd_getb32 (buf + 2);
+ }
+}
+
+void
+bfd_sym_parse_contained_modules_table_entry_v32 (unsigned char *buf,
+ size_t len,
+ bfd_sym_contained_modules_table_entry *entry)
+{
+ unsigned int type;
+
+ BFD_ASSERT (len == 6);
+
+ memset (entry, 0, sizeof (bfd_sym_contained_modules_table_entry));
+ type = bfd_getb16 (buf);
+
+ switch (type)
+ {
+ case BFD_SYM_END_OF_LIST_3_2:
+ entry->generic.type = BFD_SYM_END_OF_LIST;
+ break;
+
+ default:
+ entry->entry.mte_index = type;
+ entry->entry.nte_index = bfd_getb32 (buf + 2);
+ break;
+ }
+}
+
+void
+bfd_sym_parse_contained_variables_table_entry_v32 (unsigned char *buf,
+ size_t len,
+ bfd_sym_contained_variables_table_entry *entry)
+{
+ unsigned int type;
+
+ BFD_ASSERT (len == 26);
+
+ memset (entry, 0, sizeof (bfd_sym_contained_variables_table_entry));
+ type = bfd_getb16 (buf);
+
+ switch (type)
+ {
+ case BFD_SYM_END_OF_LIST_3_2:
+ entry->generic.type = BFD_SYM_END_OF_LIST;
+ break;
+
+ case BFD_SYM_SOURCE_FILE_CHANGE_3_2:
+ entry->file.type = BFD_SYM_SOURCE_FILE_CHANGE;
+ bfd_sym_parse_file_reference_v32 (buf + 2, 6, &entry->file.fref);
+ break;
+
+ default:
+ entry->entry.tte_index = type;
+ entry->entry.nte_index = bfd_getb32 (buf + 2);
+ entry->entry.file_delta = bfd_getb16 (buf + 6);
+ entry->entry.scope = buf[8];
+ entry->entry.la_size = buf[9];
+
+ if (entry->entry.la_size == BFD_SYM_CVTE_SCA)
+ {
+ entry->entry.address.scstruct.sca_kind = buf[10];
+ entry->entry.address.scstruct.sca_class = buf[11];
+ entry->entry.address.scstruct.sca_offset = bfd_getb32 (buf + 12);
+ }
+ else if (entry->entry.la_size <= BFD_SYM_CVTE_SCA)
+ {
+#if BFD_SYM_CVTE_SCA > 0
+ memcpy (&entry->entry.address.lastruct.la, buf + 10,
+ BFD_SYM_CVTE_SCA);
+#endif
+ entry->entry.address.lastruct.la_kind = buf[23];
+ }
+ else if (entry->entry.la_size == BFD_SYM_CVTE_BIG_LA)
+ {
+ entry->entry.address.biglastruct.big_la = bfd_getb32 (buf + 10);
+ entry->entry.address.biglastruct.big_la_kind = buf[12];
+ }
+ }
+}
+
+void
+bfd_sym_parse_contained_statements_table_entry_v32 (unsigned char *buf,
+ size_t len,
+ bfd_sym_contained_statements_table_entry *entry)
+{
+ unsigned int type;
+
+ BFD_ASSERT (len == 8);
+
+ memset (entry, 0, sizeof (bfd_sym_contained_statements_table_entry));
+ type = bfd_getb16 (buf);
+
+ switch (type)
+ {
+ case BFD_SYM_END_OF_LIST_3_2:
+ entry->generic.type = BFD_SYM_END_OF_LIST;
+ break;
+
+ case BFD_SYM_SOURCE_FILE_CHANGE_3_2:
+ entry->file.type = BFD_SYM_SOURCE_FILE_CHANGE;
+ bfd_sym_parse_file_reference_v32 (buf + 2, 6, &entry->file.fref);
+ break;
+
+ default:
+ entry->entry.mte_index = type;
+ entry->entry.mte_offset = bfd_getb16 (buf + 2);
+ entry->entry.file_delta = bfd_getb32 (buf + 4);
+ break;
+ }
+}
+
+void
+bfd_sym_parse_contained_labels_table_entry_v32 (unsigned char *buf,
+ size_t len,
+ bfd_sym_contained_labels_table_entry *entry)
+{
+ unsigned int type;
+
+ BFD_ASSERT (len == 12);
+
+ memset (entry, 0, sizeof (bfd_sym_contained_labels_table_entry));
+ type = bfd_getb16 (buf);
+
+ switch (type)
+ {
+ case BFD_SYM_END_OF_LIST_3_2:
+ entry->generic.type = BFD_SYM_END_OF_LIST;
+ break;
+
+ case BFD_SYM_SOURCE_FILE_CHANGE_3_2:
+ entry->file.type = BFD_SYM_SOURCE_FILE_CHANGE;
+ bfd_sym_parse_file_reference_v32 (buf + 2, 6, &entry->file.fref);
+ break;
+
+ default:
+ entry->entry.mte_index = type;
+ entry->entry.mte_offset = bfd_getb16 (buf + 2);
+ entry->entry.nte_index = bfd_getb32 (buf + 4);
+ entry->entry.file_delta = bfd_getb16 (buf + 8);
+ entry->entry.scope = bfd_getb16 (buf + 10);
+ break;
+ }
+}
+
+void
+bfd_sym_parse_type_table_entry_v32 (unsigned char *buf,
+ size_t len,
+ bfd_sym_type_table_entry *entry)
+{
+ BFD_ASSERT (len == 4);
+
+ *entry = bfd_getb32 (buf);
+}
+
+int
+bfd_sym_fetch_resources_table_entry (bfd *abfd,
+ bfd_sym_resources_table_entry *entry,
+ unsigned long sym_index)
+{
+ void (*parser) (unsigned char *, size_t, bfd_sym_resources_table_entry *);
+ unsigned long offset;
+ unsigned long entry_size;
+ unsigned char buf[18];
+ bfd_sym_data_struct *sdata = NULL;
+
+ parser = NULL;
+ BFD_ASSERT (bfd_sym_valid (abfd));
+ sdata = abfd->tdata.sym_data;
+
+ if (sym_index == 0)
+ return -1;
+
+ switch (sdata->version)
+ {
+ case BFD_SYM_VERSION_3_5:
+ case BFD_SYM_VERSION_3_4:
+ return -1;
+
+ case BFD_SYM_VERSION_3_3:
+ case BFD_SYM_VERSION_3_2:
+ entry_size = 18;
+ parser = bfd_sym_parse_resources_table_entry_v32;
+ break;
+
+ case BFD_SYM_VERSION_3_1:
+ default:
+ return -1;
+ }
+ if (parser == NULL)
+ return -1;
+
+ offset = compute_offset (sdata->header.dshb_rte.dti_first_page,
+ sdata->header.dshb_page_size,
+ entry_size, sym_index);
+
+ if (bfd_seek (abfd, offset, SEEK_SET) < 0)
+ return -1;
+ if (bfd_bread (buf, entry_size, abfd) != entry_size)
+ return -1;
+
+ (*parser) (buf, entry_size, entry);
+
+ return 0;
+}
+
+int
+bfd_sym_fetch_modules_table_entry (bfd *abfd,
+ bfd_sym_modules_table_entry *entry,
+ unsigned long sym_index)
+{
+ void (*parser) (unsigned char *, size_t, bfd_sym_modules_table_entry *);
+ unsigned long offset;
+ unsigned long entry_size;
+ unsigned char buf[46];
+ bfd_sym_data_struct *sdata = NULL;
+
+ parser = NULL;
+ BFD_ASSERT (bfd_sym_valid (abfd));
+ sdata = abfd->tdata.sym_data;
+
+ if (sym_index == 0)
+ return -1;
+
+ switch (sdata->version)
+ {
+ case BFD_SYM_VERSION_3_5:
+ case BFD_SYM_VERSION_3_4:
+ return -1;
+
+ case BFD_SYM_VERSION_3_3:
+ entry_size = 46;
+ parser = bfd_sym_parse_modules_table_entry_v33;
+ break;
+
+ case BFD_SYM_VERSION_3_2:
+ case BFD_SYM_VERSION_3_1:
+ default:
+ return -1;
+ }
+ if (parser == NULL)
+ return -1;
+
+ offset = compute_offset (sdata->header.dshb_mte.dti_first_page,
+ sdata->header.dshb_page_size,
+ entry_size, sym_index);
+
+ if (bfd_seek (abfd, offset, SEEK_SET) < 0)
+ return -1;
+ if (bfd_bread (buf, entry_size, abfd) != entry_size)
+ return -1;
+
+ (*parser) (buf, entry_size, entry);
+
+ return 0;
+}
+
+int
+bfd_sym_fetch_file_references_table_entry (bfd *abfd,
+ bfd_sym_file_references_table_entry *entry,
+ unsigned long sym_index)
+{
+ void (*parser) (unsigned char *, size_t, bfd_sym_file_references_table_entry *);
+ unsigned long offset;
+ unsigned long entry_size = 0;
+ unsigned char buf[8];
+ bfd_sym_data_struct *sdata = NULL;
+
+ parser = NULL;
+ BFD_ASSERT (bfd_sym_valid (abfd));
+ sdata = abfd->tdata.sym_data;
+
+ if (sym_index == 0)
+ return -1;
+
+ switch (sdata->version)
+ {
+ case BFD_SYM_VERSION_3_3:
+ case BFD_SYM_VERSION_3_2:
+ entry_size = 10;
+ parser = bfd_sym_parse_file_references_table_entry_v32;
+ break;
+
+ case BFD_SYM_VERSION_3_5:
+ case BFD_SYM_VERSION_3_4:
+ case BFD_SYM_VERSION_3_1:
+ default:
+ break;
+ }
+
+ if (parser == NULL)
+ return -1;
+
+ offset = compute_offset (sdata->header.dshb_frte.dti_first_page,
+ sdata->header.dshb_page_size,
+ entry_size, sym_index);
+
+ if (bfd_seek (abfd, offset, SEEK_SET) < 0)
+ return -1;
+ if (bfd_bread (buf, entry_size, abfd) != entry_size)
+ return -1;
+
+ (*parser) (buf, entry_size, entry);
+
+ return 0;
+}
+
+int
+bfd_sym_fetch_contained_modules_table_entry (bfd *abfd,
+ bfd_sym_contained_modules_table_entry *entry,
+ unsigned long sym_index)
+{
+ void (*parser) (unsigned char *, size_t, bfd_sym_contained_modules_table_entry *);
+ unsigned long offset;
+ unsigned long entry_size = 0;
+ unsigned char buf[6];
+ bfd_sym_data_struct *sdata = NULL;
+
+ parser = NULL;
+ BFD_ASSERT (bfd_sym_valid (abfd));
+ sdata = abfd->tdata.sym_data;
+
+ if (sym_index == 0)
+ return -1;
+
+ switch (sdata->version)
+ {
+ case BFD_SYM_VERSION_3_3:
+ case BFD_SYM_VERSION_3_2:
+ entry_size = 6;
+ parser = bfd_sym_parse_contained_modules_table_entry_v32;
+ break;
+
+ case BFD_SYM_VERSION_3_5:
+ case BFD_SYM_VERSION_3_4:
+ case BFD_SYM_VERSION_3_1:
+ default:
+ break;
+ }
+
+ if (parser == NULL)
+ return -1;
+
+ offset = compute_offset (sdata->header.dshb_cmte.dti_first_page,
+ sdata->header.dshb_page_size,
+ entry_size, sym_index);
+
+ if (bfd_seek (abfd, offset, SEEK_SET) < 0)
+ return -1;
+ if (bfd_bread (buf, entry_size, abfd) != entry_size)
+ return -1;
+
+ (*parser) (buf, entry_size, entry);
+
+ return 0;
+}
+
+int
+bfd_sym_fetch_contained_variables_table_entry (bfd *abfd,
+ bfd_sym_contained_variables_table_entry *entry,
+ unsigned long sym_index)
+{
+ void (*parser) (unsigned char *, size_t, bfd_sym_contained_variables_table_entry *);
+ unsigned long offset;
+ unsigned long entry_size = 0;
+ unsigned char buf[26];
+ bfd_sym_data_struct *sdata = NULL;
+
+ parser = NULL;
+ BFD_ASSERT (bfd_sym_valid (abfd));
+ sdata = abfd->tdata.sym_data;
+
+ if (sym_index == 0)
+ return -1;
+
+ switch (sdata->version)
+ {
+ case BFD_SYM_VERSION_3_3:
+ case BFD_SYM_VERSION_3_2:
+ entry_size = 26;
+ parser = bfd_sym_parse_contained_variables_table_entry_v32;
+ break;
+
+ case BFD_SYM_VERSION_3_5:
+ case BFD_SYM_VERSION_3_4:
+ case BFD_SYM_VERSION_3_1:
+ default:
+ break;
+ }
+
+ if (parser == NULL)
+ return -1;
+
+ offset = compute_offset (sdata->header.dshb_cvte.dti_first_page,
+ sdata->header.dshb_page_size,
+ entry_size, sym_index);
+
+ if (bfd_seek (abfd, offset, SEEK_SET) < 0)
+ return -1;
+ if (bfd_bread (buf, entry_size, abfd) != entry_size)
+ return -1;
+
+ (*parser) (buf, entry_size, entry);
+
+ return 0;
+}
+
+int
+bfd_sym_fetch_contained_statements_table_entry (bfd *abfd,
+ bfd_sym_contained_statements_table_entry *entry,
+ unsigned long sym_index)
+{
+ void (*parser) (unsigned char *, size_t, bfd_sym_contained_statements_table_entry *);
+ unsigned long offset;
+ unsigned long entry_size = 0;
+ unsigned char buf[8];
+ bfd_sym_data_struct *sdata = NULL;
+
+ parser = NULL;
+ BFD_ASSERT (bfd_sym_valid (abfd));
+ sdata = abfd->tdata.sym_data;
+
+ if (sym_index == 0)
+ return -1;
+
+ switch (sdata->version)
+ {
+ case BFD_SYM_VERSION_3_3:
+ case BFD_SYM_VERSION_3_2:
+ entry_size = 8;
+ parser = bfd_sym_parse_contained_statements_table_entry_v32;
+ break;
+
+ case BFD_SYM_VERSION_3_5:
+ case BFD_SYM_VERSION_3_4:
+ case BFD_SYM_VERSION_3_1:
+ default:
+ break;
+ }
+
+ if (parser == NULL)
+ return -1;
+
+ offset = compute_offset (sdata->header.dshb_csnte.dti_first_page,
+ sdata->header.dshb_page_size,
+ entry_size, sym_index);
+
+ if (bfd_seek (abfd, offset, SEEK_SET) < 0)
+ return -1;
+ if (bfd_bread (buf, entry_size, abfd) != entry_size)
+ return -1;
+
+ (*parser) (buf, entry_size, entry);
+
+ return 0;
+}
+
+int
+bfd_sym_fetch_contained_labels_table_entry (bfd *abfd,
+ bfd_sym_contained_labels_table_entry *entry,
+ unsigned long sym_index)
+{
+ void (*parser) (unsigned char *, size_t, bfd_sym_contained_labels_table_entry *);
+ unsigned long offset;
+ unsigned long entry_size = 0;
+ unsigned char buf[12];
+ bfd_sym_data_struct *sdata = NULL;
+
+ parser = NULL;
+ BFD_ASSERT (bfd_sym_valid (abfd));
+ sdata = abfd->tdata.sym_data;
+
+ if (sym_index == 0)
+ return -1;
+
+ switch (sdata->version)
+ {
+ case BFD_SYM_VERSION_3_3:
+ case BFD_SYM_VERSION_3_2:
+ entry_size = 12;
+ parser = bfd_sym_parse_contained_labels_table_entry_v32;
+ break;
+
+ case BFD_SYM_VERSION_3_5:
+ case BFD_SYM_VERSION_3_4:
+ case BFD_SYM_VERSION_3_1:
+ default:
+ break;
+ }
+
+ if (parser == NULL)
+ return -1;
+
+ offset = compute_offset (sdata->header.dshb_clte.dti_first_page,
+ sdata->header.dshb_page_size,
+ entry_size, sym_index);
+
+ if (bfd_seek (abfd, offset, SEEK_SET) < 0)
+ return -1;
+ if (bfd_bread (buf, entry_size, abfd) != entry_size)
+ return -1;
+
+ (*parser) (buf, entry_size, entry);
+
+ return 0;
+}
+
+int
+bfd_sym_fetch_contained_types_table_entry (bfd *abfd,
+ bfd_sym_contained_types_table_entry *entry,
+ unsigned long sym_index)
+{
+ void (*parser) (unsigned char *, size_t, bfd_sym_contained_types_table_entry *);
+ unsigned long offset;
+ unsigned long entry_size = 0;
+ unsigned char buf[0];
+ bfd_sym_data_struct *sdata = NULL;
+
+ parser = NULL;
+ BFD_ASSERT (bfd_sym_valid (abfd));
+ sdata = abfd->tdata.sym_data;
+
+ if (sym_index == 0)
+ return -1;
+
+ switch (sdata->version)
+ {
+ case BFD_SYM_VERSION_3_3:
+ case BFD_SYM_VERSION_3_2:
+ entry_size = 0;
+ parser = NULL;
+ break;
+
+ case BFD_SYM_VERSION_3_5:
+ case BFD_SYM_VERSION_3_4:
+ case BFD_SYM_VERSION_3_1:
+ default:
+ break;
+ }
+
+ if (parser == NULL)
+ return -1;
+
+ offset = compute_offset (sdata->header.dshb_ctte.dti_first_page,
+ sdata->header.dshb_page_size,
+ entry_size, sym_index);
+
+ if (bfd_seek (abfd, offset, SEEK_SET) < 0)
+ return -1;
+ if (bfd_bread (buf, entry_size, abfd) != entry_size)
+ return -1;
+
+ (*parser) (buf, entry_size, entry);
+
+ return 0;
+}
+
+int
+bfd_sym_fetch_file_references_index_table_entry (bfd *abfd,
+ bfd_sym_file_references_index_table_entry *entry,
+ unsigned long sym_index)
+{
+ void (*parser) (unsigned char *, size_t, bfd_sym_file_references_index_table_entry *);
+ unsigned long offset;
+ unsigned long entry_size = 0;
+ unsigned char buf[0];
+ bfd_sym_data_struct *sdata = NULL;
+
+ parser = NULL;
+ BFD_ASSERT (bfd_sym_valid (abfd));
+ sdata = abfd->tdata.sym_data;
+
+ if (sym_index == 0)
+ return -1;
+
+ switch (sdata->version)
+ {
+ case BFD_SYM_VERSION_3_3:
+ case BFD_SYM_VERSION_3_2:
+ entry_size = 0;
+ parser = NULL;
+ break;
+
+ case BFD_SYM_VERSION_3_5:
+ case BFD_SYM_VERSION_3_4:
+ case BFD_SYM_VERSION_3_1:
+ default:
+ break;
+ }
+
+ if (parser == NULL)
+ return -1;
+
+ offset = compute_offset (sdata->header.dshb_fite.dti_first_page,
+ sdata->header.dshb_page_size,
+ entry_size, sym_index);
+
+ if (bfd_seek (abfd, offset, SEEK_SET) < 0)
+ return -1;
+ if (bfd_bread (buf, entry_size, abfd) != entry_size)
+ return -1;
+
+ (*parser) (buf, entry_size, entry);
+
+ return 0;
+}
+
+int
+bfd_sym_fetch_constant_pool_entry (bfd *abfd,
+ bfd_sym_constant_pool_entry *entry,
+ unsigned long sym_index)
+{
+ void (*parser) (unsigned char *, size_t, bfd_sym_constant_pool_entry *);
+ unsigned long offset;
+ unsigned long entry_size = 0;
+ unsigned char buf[0];
+ bfd_sym_data_struct *sdata = NULL;
+
+ parser = NULL;
+ BFD_ASSERT (bfd_sym_valid (abfd));
+ sdata = abfd->tdata.sym_data;
+
+ if (sym_index == 0)
+ return -1;
+
+ switch (sdata->version)
+ {
+ case BFD_SYM_VERSION_3_3:
+ case BFD_SYM_VERSION_3_2:
+ entry_size = 0;
+ parser = NULL;
+ break;
+
+ case BFD_SYM_VERSION_3_5:
+ case BFD_SYM_VERSION_3_4:
+ case BFD_SYM_VERSION_3_1:
+ default:
+ break;
+ }
+
+ if (parser == NULL)
+ return -1;
+
+ offset = compute_offset (sdata->header.dshb_fite.dti_first_page,
+ sdata->header.dshb_page_size,
+ entry_size, sym_index);
+
+ if (bfd_seek (abfd, offset, SEEK_SET) < 0)
+ return -1;
+ if (bfd_bread (buf, entry_size, abfd) != entry_size)
+ return -1;
+
+ (*parser) (buf, entry_size, entry);
+
+ return 0;
+}
+
+int
+bfd_sym_fetch_type_table_entry (bfd *abfd,
+ bfd_sym_type_table_entry *entry,
+ unsigned long sym_index)
+{
+ void (*parser) (unsigned char *, size_t, bfd_sym_type_table_entry *);
+ unsigned long offset;
+ unsigned long entry_size = 0;
+ unsigned char buf[4];
+ bfd_sym_data_struct *sdata = NULL;
+
+ parser = NULL;
+ BFD_ASSERT (bfd_sym_valid (abfd));
+ sdata = abfd->tdata.sym_data;
+
+ switch (sdata->version)
+ {
+ case BFD_SYM_VERSION_3_3:
+ case BFD_SYM_VERSION_3_2:
+ entry_size = 4;
+ parser = bfd_sym_parse_type_table_entry_v32;
+ break;
+
+ case BFD_SYM_VERSION_3_5:
+ case BFD_SYM_VERSION_3_4:
+ case BFD_SYM_VERSION_3_1:
+ default:
+ break;
+ }
+
+ if (parser == NULL)
+ return -1;
+
+ offset = compute_offset (sdata->header.dshb_tte.dti_first_page,
+ sdata->header.dshb_page_size,
+ entry_size, sym_index);
+
+ if (bfd_seek (abfd, offset, SEEK_SET) < 0)
+ return -1;
+ if (bfd_bread (buf, entry_size, abfd) != entry_size)
+ return -1;
+
+ (*parser) (buf, entry_size, entry);
+
+ return 0;
+}
+
+int
+bfd_sym_fetch_type_information_table_entry (bfd *abfd,
+ bfd_sym_type_information_table_entry *entry,
+ unsigned long offset)
+{
+ unsigned char buf[4];
+
+ BFD_ASSERT (bfd_sym_valid (abfd));
+
+ if (offset == 0)
+ return -1;
+
+ if (bfd_seek (abfd, offset, SEEK_SET) < 0)
+ return -1;
+
+ if (bfd_bread (buf, 4, abfd) != 4)
+ return -1;
+ entry->nte_index = bfd_getb32 (buf);
+
+ if (bfd_bread (buf, 2, abfd) != 2)
+ return -1;
+ entry->physical_size = bfd_getb16 (buf);
+
+ if (entry->physical_size & 0x8000)
+ {
+ if (bfd_bread (buf, 4, abfd) != 4)
+ return -1;
+ entry->physical_size &= 0x7fff;
+ entry->logical_size = bfd_getb32 (buf);
+ entry->offset = offset + 10;
+ }
+ else
+ {
+ if (bfd_bread (buf, 2, abfd) != 2)
+ return -1;
+ entry->physical_size &= 0x7fff;
+ entry->logical_size = bfd_getb16 (buf);
+ entry->offset = offset + 8;
+ }
+
+ return 0;
+}
+
+int
+bfd_sym_fetch_type_table_information (bfd *abfd,
+ bfd_sym_type_information_table_entry *entry,
+ unsigned long sym_index)
+{
+ bfd_sym_type_table_entry tindex;
+ bfd_sym_data_struct *sdata = NULL;
+
+ BFD_ASSERT (bfd_sym_valid (abfd));
+ sdata = abfd->tdata.sym_data;
+
+ if (sdata->header.dshb_tte.dti_object_count <= 99)
+ return -1;
+ if (sym_index < 100)
+ return -1;
+
+ if (bfd_sym_fetch_type_table_entry (abfd, &tindex, sym_index - 100) < 0)
+ return -1;
+ if (bfd_sym_fetch_type_information_table_entry (abfd, entry, tindex) < 0)
+ return -1;
+
+ return 0;
+}
+
+const unsigned char *
+bfd_sym_symbol_name (bfd *abfd, unsigned long sym_index)
+{
+ bfd_sym_data_struct *sdata = NULL;
+
+ BFD_ASSERT (bfd_sym_valid (abfd));
+ sdata = abfd->tdata.sym_data;
+
+ if (sym_index == 0)
+ return (const unsigned char *) "";
+
+ sym_index *= 2;
+ if ((sym_index / sdata->header.dshb_page_size)
+ > sdata->header.dshb_nte.dti_page_count)
+ return (const unsigned char *) "\09[INVALID]";
+
+ return (const unsigned char *) sdata->name_table + sym_index;
+}
+
+const unsigned char *
+bfd_sym_module_name (bfd *abfd, unsigned long sym_index)
+{
+ bfd_sym_modules_table_entry entry;
+
+ if (bfd_sym_fetch_modules_table_entry (abfd, &entry, sym_index) < 0)
+ return (const unsigned char *) "\09[INVALID]";
+
+ return bfd_sym_symbol_name (abfd, entry.mte_nte_index);
+}
+
+const char *
+bfd_sym_unparse_storage_kind (enum bfd_sym_storage_kind kind)
+{
+ switch (kind)
+ {
+ case BFD_SYM_STORAGE_KIND_LOCAL: return "LOCAL";
+ case BFD_SYM_STORAGE_KIND_VALUE: return "VALUE";
+ case BFD_SYM_STORAGE_KIND_REFERENCE: return "REFERENCE";
+ case BFD_SYM_STORAGE_KIND_WITH: return "WITH";
+ default: return "[UNKNOWN]";
+ }
+}
+
+const char *
+bfd_sym_unparse_storage_class (enum bfd_sym_storage_class kind)
+{
+ switch (kind)
+ {
+ case BFD_SYM_STORAGE_CLASS_REGISTER: return "REGISTER";
+ case BFD_SYM_STORAGE_CLASS_GLOBAL: return "GLOBAL";
+ case BFD_SYM_STORAGE_CLASS_FRAME_RELATIVE: return "FRAME_RELATIVE";
+ case BFD_SYM_STORAGE_CLASS_STACK_RELATIVE: return "STACK_RELATIVE";
+ case BFD_SYM_STORAGE_CLASS_ABSOLUTE: return "ABSOLUTE";
+ case BFD_SYM_STORAGE_CLASS_CONSTANT: return "CONSTANT";
+ case BFD_SYM_STORAGE_CLASS_RESOURCE: return "RESOURCE";
+ case BFD_SYM_STORAGE_CLASS_BIGCONSTANT: return "BIGCONSTANT";
+ default: return "[UNKNOWN]";
+ }
+}
+
+const char *
+bfd_sym_unparse_module_kind (enum bfd_sym_module_kind kind)
+{
+ switch (kind)
+ {
+ case BFD_SYM_MODULE_KIND_NONE: return "NONE";
+ case BFD_SYM_MODULE_KIND_PROGRAM: return "PROGRAM";
+ case BFD_SYM_MODULE_KIND_UNIT: return "UNIT";
+ case BFD_SYM_MODULE_KIND_PROCEDURE: return "PROCEDURE";
+ case BFD_SYM_MODULE_KIND_FUNCTION: return "FUNCTION";
+ case BFD_SYM_MODULE_KIND_DATA: return "DATA";
+ case BFD_SYM_MODULE_KIND_BLOCK: return "BLOCK";
+ default: return "[UNKNOWN]";
+ }
+}
+
+const char *
+bfd_sym_unparse_symbol_scope (enum bfd_sym_symbol_scope scope)
+{
+ switch (scope)
+ {
+ case BFD_SYM_SYMBOL_SCOPE_LOCAL: return "LOCAL";
+ case BFD_SYM_SYMBOL_SCOPE_GLOBAL: return "GLOBAL";
+ default:
+ return "[UNKNOWN]";
+ }
+}
+
+void
+bfd_sym_print_file_reference (bfd *abfd,
+ FILE *f,
+ bfd_sym_file_reference *entry)
+{
+ bfd_sym_file_references_table_entry frtentry;
+ int ret;
+
+ ret = bfd_sym_fetch_file_references_table_entry (abfd, &frtentry,
+ entry->fref_frte_index);
+ fprintf (f, "FILE ");
+
+ if ((ret < 0) || (frtentry.generic.type != BFD_SYM_FILE_NAME_INDEX))
+ fprintf (f, "[INVALID]");
+ else
+ fprintf (f, "\"%.*s\"",
+ bfd_sym_symbol_name (abfd, frtentry.filename.nte_index)[0],
+ &bfd_sym_symbol_name (abfd, frtentry.filename.nte_index)[1]);
+
+ fprintf (f, " (FRTE %lu)", entry->fref_frte_index);
+}
+
+void
+bfd_sym_print_resources_table_entry (bfd *abfd,
+ FILE *f,
+ bfd_sym_resources_table_entry *entry)
+{
+ fprintf (f, " \"%.*s\" (NTE %lu), type \"%.4s\", num %u, size %lu, MTE %lu -- %lu",
+ bfd_sym_symbol_name (abfd, entry->rte_nte_index)[0],
+ &bfd_sym_symbol_name (abfd, entry->rte_nte_index)[1],
+ entry->rte_nte_index, entry->rte_res_type, entry->rte_res_number,
+ entry->rte_res_size, entry->rte_mte_first, entry->rte_mte_last);
+}
+
+void
+bfd_sym_print_modules_table_entry (bfd *abfd,
+ FILE *f,
+ bfd_sym_modules_table_entry *entry)
+{
+ fprintf (f, "\"%.*s\" (NTE %lu)",
+ bfd_sym_symbol_name (abfd, entry->mte_nte_index)[0],
+ &bfd_sym_symbol_name (abfd, entry->mte_nte_index)[1],
+ entry->mte_nte_index);
+
+ fprintf (f, "\n ");
+
+ bfd_sym_print_file_reference (abfd, f, &entry->mte_imp_fref);
+ fprintf (f, " range %lu -- %lu",
+ entry->mte_imp_fref.fref_offset, entry->mte_imp_end);
+
+ fprintf (f, "\n ");
+
+ fprintf (f, "kind %s", bfd_sym_unparse_module_kind (entry->mte_kind));
+ fprintf (f, ", scope %s", bfd_sym_unparse_symbol_scope (entry->mte_scope));
+
+ fprintf (f, ", RTE %lu, offset %lu, size %lu",
+ entry->mte_rte_index, entry->mte_res_offset, entry->mte_size);
+
+ fprintf (f, "\n ");
+
+ fprintf (f, "CMTE %lu, CVTE %lu, CLTE %lu, CTTE %lu, CSNTE1 %lu, CSNTE2 %lu",
+ entry->mte_cmte_index, entry->mte_cvte_index,
+ entry->mte_clte_index, entry->mte_ctte_index,
+ entry->mte_csnte_idx_1, entry->mte_csnte_idx_2);
+
+ if (entry->mte_parent != 0)
+ fprintf (f, ", parent %lu", entry->mte_parent);
+ else
+ fprintf (f, ", no parent");
+
+ if (entry->mte_cmte_index != 0)
+ fprintf (f, ", child %lu", entry->mte_cmte_index);
+ else
+ fprintf (f, ", no child");
+}
+
+void
+bfd_sym_print_file_references_table_entry (bfd *abfd,
+ FILE *f,
+ bfd_sym_file_references_table_entry *entry)
+{
+ switch (entry->generic.type)
+ {
+ case BFD_SYM_FILE_NAME_INDEX:
+ fprintf (f, "FILE \"%.*s\" (NTE %lu), modtime ",
+ bfd_sym_symbol_name (abfd, entry->filename.nte_index)[0],
+ &bfd_sym_symbol_name (abfd, entry->filename.nte_index)[1],
+ entry->filename.nte_index);
+
+ fprintf (f, "[UNIMPLEMENTED]");
+ /* printModDate (entry->filename.mod_date); */
+ fprintf (f, " (0x%lx)", entry->filename.mod_date);
+ break;
+
+ case BFD_SYM_END_OF_LIST:
+ fprintf (f, "END");
+ break;
+
+ default:
+ fprintf (f, "\"%.*s\" (MTE %lu), offset %lu",
+ bfd_sym_module_name (abfd, entry->entry.mte_index)[0],
+ &bfd_sym_module_name (abfd, entry->entry.mte_index)[1],
+ entry->entry.mte_index,
+ entry->entry.file_offset);
+ break;
+ }
+}
+
+void
+bfd_sym_print_contained_modules_table_entry (bfd *abfd,
+ FILE *f,
+ bfd_sym_contained_modules_table_entry *entry)
+{
+ switch (entry->generic.type)
+ {
+ case BFD_SYM_END_OF_LIST:
+ fprintf (f, "END");
+ break;
+
+ default:
+ fprintf (f, "\"%.*s\" (MTE %lu, NTE %lu)",
+ bfd_sym_module_name (abfd, entry->entry.mte_index)[0],
+ &bfd_sym_module_name (abfd, entry->entry.mte_index)[1],
+ entry->entry.mte_index,
+ entry->entry.nte_index);
+ break;
+ }
+}
+
+void
+bfd_sym_print_contained_variables_table_entry (bfd *abfd,
+ FILE *f,
+ bfd_sym_contained_variables_table_entry *entry)
+{
+ if (entry->generic.type == BFD_SYM_END_OF_LIST)
+ {
+ fprintf (f, "END");
+ return;
+ }
+
+ if (entry->generic.type == BFD_SYM_SOURCE_FILE_CHANGE)
+ {
+ bfd_sym_print_file_reference (abfd, f, &entry->file.fref);
+ fprintf (f, " offset %lu", entry->file.fref.fref_offset);
+ return;
+ }
+
+ fprintf (f, "\"%.*s\" (NTE %lu)",
+ bfd_sym_symbol_name (abfd, entry->entry.nte_index)[0],
+ &bfd_sym_symbol_name (abfd, entry->entry.nte_index)[1],
+ entry->entry.nte_index);
+
+ fprintf (f, ", TTE %lu", entry->entry.tte_index);
+ fprintf (f, ", offset %lu", entry->entry.file_delta);
+ fprintf (f, ", scope %s", bfd_sym_unparse_symbol_scope (entry->entry.scope));
+
+ if (entry->entry.la_size == BFD_SYM_CVTE_SCA)
+ fprintf (f, ", latype %s, laclass %s, laoffset %lu",
+ bfd_sym_unparse_storage_kind (entry->entry.address.scstruct.sca_kind),
+ bfd_sym_unparse_storage_class (entry->entry.address.scstruct.sca_class),
+ entry->entry.address.scstruct.sca_offset);
+ else if (entry->entry.la_size <= BFD_SYM_CVTE_LA_MAX_SIZE)
+ {
+ unsigned long i;
+
+ fprintf (f, ", la [");
+ for (i = 0; i < entry->entry.la_size; i++)
+ fprintf (f, "0x%02x ", entry->entry.address.lastruct.la[i]);
+ fprintf (f, "]");
+ }
+ else if (entry->entry.la_size == BFD_SYM_CVTE_BIG_LA)
+ fprintf (f, ", bigla %lu, biglakind %u",
+ entry->entry.address.biglastruct.big_la,
+ entry->entry.address.biglastruct.big_la_kind);
+
+ else
+ fprintf (f, ", la [INVALID]");
+}
+
+void
+bfd_sym_print_contained_statements_table_entry (bfd *abfd,
+ FILE *f,
+ bfd_sym_contained_statements_table_entry *entry)
+{
+ if (entry->generic.type == BFD_SYM_END_OF_LIST)
+ {
+ fprintf (f, "END");
+ return;
+ }
+
+ if (entry->generic.type == BFD_SYM_SOURCE_FILE_CHANGE)
+ {
+ bfd_sym_print_file_reference (abfd, f, &entry->file.fref);
+ fprintf (f, " offset %lu", entry->file.fref.fref_offset);
+ return;
+ }
+
+ fprintf (f, "\"%.*s\" (MTE %lu), offset %lu, delta %lu",
+ bfd_sym_module_name (abfd, entry->entry.mte_index)[0],
+ &bfd_sym_module_name (abfd, entry->entry.mte_index)[1],
+ entry->entry.mte_index,
+ entry->entry.mte_offset,
+ entry->entry.file_delta);
+}
+
+void
+bfd_sym_print_contained_labels_table_entry (bfd *abfd,
+ FILE *f,
+ bfd_sym_contained_labels_table_entry *entry)
+{
+ if (entry->generic.type == BFD_SYM_END_OF_LIST)
+ {
+ fprintf (f, "END");
+ return;
+ }
+
+ if (entry->generic.type == BFD_SYM_SOURCE_FILE_CHANGE)
+ {
+ bfd_sym_print_file_reference (abfd, f, &entry->file.fref);
+ fprintf (f, " offset %lu", entry->file.fref.fref_offset);
+ return;
+ }
+
+ fprintf (f, "\"%.*s\" (MTE %lu), offset %lu, delta %lu, scope %s",
+ bfd_sym_module_name (abfd, entry->entry.mte_index)[0],
+ &bfd_sym_module_name (abfd, entry->entry.mte_index)[1],
+ entry->entry.mte_index,
+ entry->entry.mte_offset,
+ entry->entry.file_delta,
+ bfd_sym_unparse_symbol_scope (entry->entry.scope));
+}
+
+void
+bfd_sym_print_contained_types_table_entry (bfd *abfd ATTRIBUTE_UNUSED,
+ FILE *f,
+ bfd_sym_contained_types_table_entry *entry ATTRIBUTE_UNUSED)
+{
+ fprintf (f, "[UNIMPLEMENTED]");
+}
+
+const char *
+bfd_sym_type_operator_name (unsigned char num)
+{
+ switch (num)
+ {
+ case 1: return "TTE";
+ case 2: return "PointerTo";
+ case 3: return "ScalarOf";
+ case 4: return "ConstantOf";
+ case 5: return "EnumerationOf";
+ case 6: return "VectorOf";
+ case 7: return "RecordOf";
+ case 8: return "UnionOf";
+ case 9: return "SubRangeOf";
+ case 10: return "SetOf";
+ case 11: return "NamedTypeOf";
+ case 12: return "ProcOf";
+ case 13: return "ValueOf";
+ case 14: return "ArrayOf";
+ default: return "[UNKNOWN OPERATOR]";
+ }
+}
+
+const char *
+bfd_sym_type_basic_name (unsigned char num)
+{
+ switch (num)
+ {
+ case 0: return "void";
+ case 1: return "pascal string";
+ case 2: return "unsigned long";
+ case 3: return "signed long";
+ case 4: return "extended (10 bytes)";
+ case 5: return "pascal boolean (1 byte)";
+ case 6: return "unsigned byte";
+ case 7: return "signed byte";
+ case 8: return "character (1 byte)";
+ case 9: return "wide character (2 bytes)";
+ case 10: return "unsigned short";
+ case 11: return "signed short";
+ case 12: return "singled";
+ case 13: return "double";
+ case 14: return "extended (12 bytes)";
+ case 15: return "computational (8 bytes)";
+ case 16: return "c string";
+ case 17: return "as-is string";
+ default: return "[UNKNOWN BASIC TYPE]";
+ }
+}
+
+int
+bfd_sym_fetch_long (unsigned char *buf,
+ unsigned long len,
+ unsigned long offset,
+ unsigned long *offsetptr,
+ long *value)
+{
+ int ret;
+
+ if (offset >= len)
+ {
+ *value = 0;
+ offset += 0;
+ ret = -1;
+ }
+ else if (! (buf[offset] & 0x80))
+ {
+ *value = buf[offset];
+ offset += 1;
+ ret = 0;
+ }
+ else if (buf[offset] == 0xc0)
+ {
+ if ((offset + 5) > len)
+ {
+ *value = 0;
+ offset = len;
+ ret = -1;
+ }
+ else
+ {
+ *value = bfd_getb32 (buf + offset + 1);
+ offset += 5;
+ ret = 0;
+ }
+ }
+ else if ((buf[offset] & 0xc0) == 0xc0)
+ {
+ *value = -(buf[offset] & 0x3f);
+ offset += 1;
+ ret = 0;
+ }
+ else if ((buf[offset] & 0xc0) == 0x80)
+ {
+ if ((offset + 2) > len)
+ {
+ *value = 0;
+ offset = len;
+ ret = -1;
+ }
+ else
+ {
+ *value = bfd_getb16 (buf + offset) & 0x3fff;
+ offset += 2;
+ ret = 0;
+ }
+ }
+ else
+ abort ();
+
+ if (offsetptr != NULL)
+ *offsetptr = offset;
+
+ return ret;
+}
+
+void
+bfd_sym_print_type_information (bfd *abfd,
+ FILE *f,
+ unsigned char *buf,
+ unsigned long len,
+ unsigned long offset,
+ unsigned long *offsetptr)
+{
+ unsigned int type;
+
+ if (offset >= len)
+ {
+ fprintf (f, "[NULL]");
+
+ if (offsetptr != NULL)
+ *offsetptr = offset;
+ return;
+ }
+
+ type = buf[offset];
+ offset++;
+
+ if (! (type & 0x80))
+ {
+ fprintf (f, "[%s] (0x%x)", bfd_sym_type_basic_name (type & 0x7f), type);
+
+ if (offsetptr != NULL)
+ *offsetptr = offset;
+ return;
+ }
+
+ if (type & 0x40)
+ fprintf (f, "[packed ");
+ else
+ fprintf (f, "[");
+
+ switch (type & 0x3f)
+ {
+ case 1:
+ {
+ long value;
+ bfd_sym_type_information_table_entry tinfo;
+
+ bfd_sym_fetch_long (buf, len, offset, &offset, &value);
+ if (value <= 0)
+ fprintf (f, "[INVALID]");
+ else
+ {
+ if (bfd_sym_fetch_type_table_information (abfd, &tinfo, value) < 0)
+ fprintf (f, "[INVALID]");
+ else
+ fprintf (f, "\"%.*s\"",
+ bfd_sym_symbol_name (abfd, tinfo.nte_index)[0],
+ &bfd_sym_symbol_name (abfd, tinfo.nte_index)[1]);
+ }
+ fprintf (f, " (TTE %lu)", (unsigned long) value);
+ break;
+ }
+
+ case 2:
+ fprintf (f, "pointer (0x%x) to ", type);
+ bfd_sym_print_type_information (abfd, f, buf, len, offset, &offset);
+ break;
+
+ case 3:
+ {
+ long value;
+
+ fprintf (f, "scalar (0x%x) of ", type);
+ bfd_sym_print_type_information (abfd, f, buf, len, offset, &offset);
+ bfd_sym_fetch_long (buf, len, offset, &offset, &value);
+ fprintf (f, " (%lu)", (unsigned long) value);
+ break;
+ }
+
+ case 5:
+ {
+ long lower, upper, nelem;
+ int i;
+
+ fprintf (f, "enumeration (0x%x) of ", type);
+ bfd_sym_print_type_information (abfd, f, buf, len, offset, &offset);
+ bfd_sym_fetch_long (buf, len, offset, &offset, &lower);
+ bfd_sym_fetch_long (buf, len, offset, &offset, &upper);
+ bfd_sym_fetch_long (buf, len, offset, &offset, &nelem);
+ fprintf (f, " from %lu to %lu with %lu elements: ",
+ (unsigned long) lower, (unsigned long) upper,
+ (unsigned long) nelem);
+
+ for (i = 0; i < nelem; i++)
+ {
+ fprintf (f, "\n ");
+ bfd_sym_print_type_information (abfd, f, buf, len, offset, &offset);
+ }
+ break;
+ }
+
+ case 6:
+ fprintf (f, "vector (0x%x)", type);
+ fprintf (f, "\n index ");
+ bfd_sym_print_type_information (abfd, f, buf, len, offset, &offset);
+ fprintf (f, "\n target ");
+ bfd_sym_print_type_information (abfd, f, buf, len, offset, &offset);
+ break;
+
+ case 7:
+ case 8:
+ {
+ long nrec, eloff, i;
+
+ if ((type & 0x3f) == 7)
+ fprintf (f, "record (0x%x) of ", type);
+ else
+ fprintf (f, "union (0x%x) of ", type);
+
+ bfd_sym_fetch_long (buf, len, offset, &offset, &nrec);
+ fprintf (f, "%lu elements: ", (unsigned long) nrec);
+
+ for (i = 0; i < nrec; i++)
+ {
+ bfd_sym_fetch_long (buf, len, offset, &offset, &eloff);
+ fprintf (f, "\n ");
+ fprintf (f, "offset %lu: ", (unsigned long) eloff);
+ bfd_sym_print_type_information (abfd, f, buf, len, offset, &offset);
+ }
+ break;
+ }
+
+ case 9:
+ fprintf (f, "subrange (0x%x) of ", type);
+ bfd_sym_print_type_information (abfd, f, buf, len, offset, &offset);
+ fprintf (f, " lower ");
+ bfd_sym_print_type_information (abfd, f, buf, len, offset, &offset);
+ fprintf (f, " upper ");
+ bfd_sym_print_type_information (abfd, f, buf, len, offset, &offset);
+ break;
+
+ case 11:
+ {
+ long value;
+
+ fprintf (f, "named type (0x%x) ", type);
+ bfd_sym_fetch_long (buf, len, offset, &offset, &value);
+ if (value <= 0)
+ fprintf (f, "[INVALID]");
+ else
+ fprintf (f, "\"%.*s\"",
+ bfd_sym_symbol_name (abfd, value)[0],
+ &bfd_sym_symbol_name (abfd, value)[1]);
+
+ fprintf (f, " (NTE %lu) with type ", (unsigned long) value);
+ bfd_sym_print_type_information (abfd, f, buf, len, offset, &offset);
+ break;
+ }
+
+ default:
+ fprintf (f, "%s (0x%x)", bfd_sym_type_operator_name (type), type);
+ break;
+ }
+
+ if (type == (0x40 | 0x6))
+ {
+ /* Vector. */
+ long n, width, m;
+ long l;
+ long i;
+
+ bfd_sym_fetch_long (buf, len, offset, &offset, &n);
+ bfd_sym_fetch_long (buf, len, offset, &offset, &width);
+ bfd_sym_fetch_long (buf, len, offset, &offset, &m);
+ /* fprintf (f, "\n "); */
+ fprintf (f, " N %ld, width %ld, M %ld, ", n, width, m);
+ for (i = 0; i < m; i++)
+ {
+ bfd_sym_fetch_long (buf, len, offset, &offset, &l);
+ if (i != 0)
+ fprintf (f, " ");
+ fprintf (f, "%ld", l);
+ }
+ }
+ else if (type & 0x40)
+ {
+ /* Other packed type. */
+ long msb, lsb;
+
+ bfd_sym_fetch_long (buf, len, offset, &offset, &msb);
+ bfd_sym_fetch_long (buf, len, offset, &offset, &lsb);
+ /* fprintf (f, "\n "); */
+ fprintf (f, " msb %ld, lsb %ld", msb, lsb);
+ }
+
+ fprintf (f, "]");
+
+ if (offsetptr != NULL)
+ *offsetptr = offset;
+}
+
+void
+bfd_sym_print_type_information_table_entry (bfd *abfd,
+ FILE *f,
+ bfd_sym_type_information_table_entry *entry)
+{
+ unsigned char *buf;
+ unsigned long offset;
+ unsigned int i;
+
+ fprintf (f, "\"%.*s\" (NTE %lu), %lu bytes at %lu, logical size %lu",
+ bfd_sym_symbol_name (abfd, entry->nte_index)[0],
+ &bfd_sym_symbol_name (abfd, entry->nte_index)[1],
+ entry->nte_index,
+ entry->physical_size, entry->offset, entry->logical_size);
+
+ fprintf (f, "\n ");
+
+ buf = alloca (entry->physical_size);
+ if (buf == NULL)
+ {
+ fprintf (f, "[ERROR]\n");
+ return;
+ }
+ if (bfd_seek (abfd, entry->offset, SEEK_SET) < 0)
+ {
+ fprintf (f, "[ERROR]\n");
+ return;
+ }
+ if (bfd_bread (buf, entry->physical_size, abfd) != entry->physical_size)
+ {
+ fprintf (f, "[ERROR]\n");
+ return;
+ }
+
+ fprintf (f, "[");
+ for (i = 0; i < entry->physical_size; i++)
+ {
+ if (i == 0)
+ fprintf (f, "0x%02x", buf[i]);
+ else
+ fprintf (f, " 0x%02x", buf[i]);
+ }
+
+ fprintf (f, "]");
+ fprintf (f, "\n ");
+
+ bfd_sym_print_type_information (abfd, f, buf, entry->physical_size, 0, &offset);
+
+ if (offset != entry->physical_size)
+ fprintf (f, "\n [parser used %lu bytes instead of %lu]", offset, entry->physical_size);
+}
+
+void
+bfd_sym_print_file_references_index_table_entry (bfd *abfd ATTRIBUTE_UNUSED,
+ FILE *f,
+ bfd_sym_file_references_index_table_entry *entry ATTRIBUTE_UNUSED)
+{
+ fprintf (f, "[UNIMPLEMENTED]");
+}
+
+void
+bfd_sym_print_constant_pool_entry (bfd *abfd ATTRIBUTE_UNUSED,
+ FILE *f,
+ bfd_sym_constant_pool_entry *entry ATTRIBUTE_UNUSED)
+{
+ fprintf (f, "[UNIMPLEMENTED]");
+}
+
+unsigned char *
+bfd_sym_display_name_table_entry (bfd *abfd,
+ FILE *f,
+ unsigned char *entry)
+{
+ unsigned long sym_index;
+ unsigned long offset;
+ bfd_sym_data_struct *sdata = NULL;
+
+ BFD_ASSERT (bfd_sym_valid (abfd));
+ sdata = abfd->tdata.sym_data;
+ sym_index = (entry - sdata->name_table) / 2;
+
+ if (sdata->version >= BFD_SYM_VERSION_3_4 && entry[0] == 255 && entry[1] == 0)
+ {
+ unsigned short length = bfd_getb16 (entry + 2);
+ fprintf (f, "[%8lu] \"%.*s\"\n", sym_index, length, entry + 4);
+ offset = 2 + length + 1;
+ }
+ else
+ {
+ if (! (entry[0] == 0 || (entry[0] == 1 && entry[1] == '\0')))
+ fprintf (f, "[%8lu] \"%.*s\"\n", sym_index, entry[0], entry + 1);
+
+ if (sdata->version >= BFD_SYM_VERSION_3_4)
+ offset = entry[0] + 2;
+ else
+ offset = entry[0] + 1;
+ }
+
+ return (entry + offset + (offset % 2));
+}
+
+void
+bfd_sym_display_name_table (bfd *abfd, FILE *f)
+{
+ unsigned long name_table_len;
+ unsigned char *name_table, *name_table_end, *cur;
+ bfd_sym_data_struct *sdata = NULL;
+
+ BFD_ASSERT (bfd_sym_valid (abfd));
+ sdata = abfd->tdata.sym_data;
+
+ name_table_len = sdata->header.dshb_nte.dti_page_count * sdata->header.dshb_page_size;
+ name_table = sdata->name_table;
+ name_table_end = name_table + name_table_len;
+
+ fprintf (f, "name table (NTE) contains %lu bytes:\n\n", name_table_len);
+
+ cur = name_table;
+ for (;;)
+ {
+ cur = bfd_sym_display_name_table_entry (abfd, f, cur);
+ if (cur >= name_table_end)
+ break;
+ }
+}
+
+void
+bfd_sym_display_resources_table (bfd *abfd, FILE *f)
+{
+ unsigned long i;
+ bfd_sym_resources_table_entry entry;
+ bfd_sym_data_struct *sdata = NULL;
+
+ BFD_ASSERT (bfd_sym_valid (abfd));
+ sdata = abfd->tdata.sym_data;
+
+ fprintf (f, "resource table (RTE) contains %lu objects:\n\n",
+ sdata->header.dshb_rte.dti_object_count);
+
+ for (i = 1; i <= sdata->header.dshb_rte.dti_object_count; i++)
+ {
+ if (bfd_sym_fetch_resources_table_entry (abfd, &entry, i) < 0)
+ fprintf (f, " [%8lu] [INVALID]\n", i);
+ else
+ {
+ fprintf (f, " [%8lu] ", i);
+ bfd_sym_print_resources_table_entry (abfd, f, &entry);
+ fprintf (f, "\n");
+ }
+ }
+}
+
+void
+bfd_sym_display_modules_table (bfd *abfd, FILE *f)
+{
+ unsigned long i;
+ bfd_sym_modules_table_entry entry;
+ bfd_sym_data_struct *sdata = NULL;
+
+ BFD_ASSERT (bfd_sym_valid (abfd));
+ sdata = abfd->tdata.sym_data;
+
+ fprintf (f, "module table (MTE) contains %lu objects:\n\n",
+ sdata->header.dshb_mte.dti_object_count);
+
+ for (i = 1; i <= sdata->header.dshb_mte.dti_object_count; i++)
+ {
+ if (bfd_sym_fetch_modules_table_entry (abfd, &entry, i) < 0)
+ fprintf (f, " [%8lu] [INVALID]\n", i);
+ else
+ {
+ fprintf (f, " [%8lu] ", i);
+ bfd_sym_print_modules_table_entry (abfd, f, &entry);
+ fprintf (f, "\n");
+ }
+ }
+}
+
+void
+bfd_sym_display_file_references_table (bfd *abfd, FILE *f)
+{
+ unsigned long i;
+ bfd_sym_file_references_table_entry entry;
+ bfd_sym_data_struct *sdata = NULL;
+
+ BFD_ASSERT (bfd_sym_valid (abfd));
+ sdata = abfd->tdata.sym_data;
+
+ fprintf (f, "file reference table (FRTE) contains %lu objects:\n\n",
+ sdata->header.dshb_frte.dti_object_count);
+
+ for (i = 1; i <= sdata->header.dshb_frte.dti_object_count; i++)
+ {
+ if (bfd_sym_fetch_file_references_table_entry (abfd, &entry, i) < 0)
+ fprintf (f, " [%8lu] [INVALID]\n", i);
+ else
+ {
+ fprintf (f, " [%8lu] ", i);
+ bfd_sym_print_file_references_table_entry (abfd, f, &entry);
+ fprintf (f, "\n");
+ }
+ }
+}
+
+void
+bfd_sym_display_contained_modules_table (bfd *abfd, FILE *f)
+{
+ unsigned long i;
+ bfd_sym_contained_modules_table_entry entry;
+ bfd_sym_data_struct *sdata = NULL;
+
+ BFD_ASSERT (bfd_sym_valid (abfd));
+ sdata = abfd->tdata.sym_data;
+
+ fprintf (f, "contained modules table (CMTE) contains %lu objects:\n\n",
+ sdata->header.dshb_cmte.dti_object_count);
+
+ for (i = 1; i <= sdata->header.dshb_cmte.dti_object_count; i++)
+ {
+ if (bfd_sym_fetch_contained_modules_table_entry (abfd, &entry, i) < 0)
+ fprintf (f, " [%8lu] [INVALID]\n", i);
+ else
+ {
+ fprintf (f, " [%8lu] ", i);
+ bfd_sym_print_contained_modules_table_entry (abfd, f, &entry);
+ fprintf (f, "\n");
+ }
+ }
+}
+
+void
+bfd_sym_display_contained_variables_table (bfd *abfd, FILE *f)
+{
+ unsigned long i;
+ bfd_sym_contained_variables_table_entry entry;
+ bfd_sym_data_struct *sdata = NULL;
+
+ BFD_ASSERT (bfd_sym_valid (abfd));
+ sdata = abfd->tdata.sym_data;
+
+ fprintf (f, "contained variables table (CVTE) contains %lu objects:\n\n",
+ sdata->header.dshb_cvte.dti_object_count);
+
+ for (i = 1; i <= sdata->header.dshb_cvte.dti_object_count; i++)
+ {
+ if (bfd_sym_fetch_contained_variables_table_entry (abfd, &entry, i) < 0)
+ fprintf (f, " [%8lu] [INVALID]\n", i);
+ else
+ {
+ fprintf (f, " [%8lu] ", i);
+ bfd_sym_print_contained_variables_table_entry (abfd, f, &entry);
+ fprintf (f, "\n");
+ }
+ }
+
+ fprintf (f, "\n");
+}
+
+void
+bfd_sym_display_contained_statements_table (bfd *abfd, FILE *f)
+{
+ unsigned long i;
+ bfd_sym_contained_statements_table_entry entry;
+ bfd_sym_data_struct *sdata = NULL;
+
+ BFD_ASSERT (bfd_sym_valid (abfd));
+ sdata = abfd->tdata.sym_data;
+
+ fprintf (f, "contained statements table (CSNTE) contains %lu objects:\n\n",
+ sdata->header.dshb_csnte.dti_object_count);
+
+ for (i = 1; i <= sdata->header.dshb_csnte.dti_object_count; i++)
+ {
+ if (bfd_sym_fetch_contained_statements_table_entry (abfd, &entry, i) < 0)
+ fprintf (f, " [%8lu] [INVALID]\n", i);
+ else
+ {
+ fprintf (f, " [%8lu] ", i);
+ bfd_sym_print_contained_statements_table_entry (abfd, f, &entry);
+ fprintf (f, "\n");
+ }
+ }
+}
+
+void
+bfd_sym_display_contained_labels_table (bfd *abfd, FILE *f)
+{
+ unsigned long i;
+ bfd_sym_contained_labels_table_entry entry;
+ bfd_sym_data_struct *sdata = NULL;
+
+ BFD_ASSERT (bfd_sym_valid (abfd));
+ sdata = abfd->tdata.sym_data;
+
+ fprintf (f, "contained labels table (CLTE) contains %lu objects:\n\n",
+ sdata->header.dshb_clte.dti_object_count);
+
+ for (i = 1; i <= sdata->header.dshb_clte.dti_object_count; i++)
+ {
+ if (bfd_sym_fetch_contained_labels_table_entry (abfd, &entry, i) < 0)
+ fprintf (f, " [%8lu] [INVALID]\n", i);
+ else
+ {
+ fprintf (f, " [%8lu] ", i);
+ bfd_sym_print_contained_labels_table_entry (abfd, f, &entry);
+ fprintf (f, "\n");
+ }
+ }
+}
+
+void
+bfd_sym_display_contained_types_table (bfd *abfd, FILE *f)
+{
+ unsigned long i;
+ bfd_sym_contained_types_table_entry entry;
+ bfd_sym_data_struct *sdata = NULL;
+
+ BFD_ASSERT (bfd_sym_valid (abfd));
+ sdata = abfd->tdata.sym_data;
+
+ fprintf (f, "contained types table (CTTE) contains %lu objects:\n\n",
+ sdata->header.dshb_ctte.dti_object_count);
+
+ for (i = 1; i <= sdata->header.dshb_ctte.dti_object_count; i++)
+ {
+ if (bfd_sym_fetch_contained_types_table_entry (abfd, &entry, i) < 0)
+ fprintf (f, " [%8lu] [INVALID]\n", i);
+ else
+ {
+ fprintf (f, " [%8lu] ", i);
+ bfd_sym_print_contained_types_table_entry (abfd, f, &entry);
+ fprintf (f, "\n");
+ }
+ }
+}
+
+void
+bfd_sym_display_file_references_index_table (bfd *abfd, FILE *f)
+{
+ unsigned long i;
+ bfd_sym_file_references_index_table_entry entry;
+ bfd_sym_data_struct *sdata = NULL;
+
+ BFD_ASSERT (bfd_sym_valid (abfd));
+ sdata = abfd->tdata.sym_data;
+
+ fprintf (f, "file references index table (FITE) contains %lu objects:\n\n",
+ sdata->header.dshb_fite.dti_object_count);
+
+ for (i = 1; i <= sdata->header.dshb_fite.dti_object_count; i++)
+ {
+ if (bfd_sym_fetch_file_references_index_table_entry (abfd, &entry, i) < 0)
+ fprintf (f, " [%8lu] [INVALID]\n", i);
+ else
+ {
+ fprintf (f, " [%8lu] ", i);
+ bfd_sym_print_file_references_index_table_entry (abfd, f, &entry);
+ fprintf (f, "\n");
+ }
+ }
+}
+
+void
+bfd_sym_display_constant_pool (bfd *abfd, FILE *f)
+{
+ unsigned long i;
+ bfd_sym_constant_pool_entry entry;
+ bfd_sym_data_struct *sdata = NULL;
+
+ BFD_ASSERT (bfd_sym_valid (abfd));
+ sdata = abfd->tdata.sym_data;
+
+ fprintf (f, "constant pool (CONST) contains %lu objects:\n\n",
+ sdata->header.dshb_const.dti_object_count);
+
+ for (i = 1; i <= sdata->header.dshb_const.dti_object_count; i++)
+ {
+ if (bfd_sym_fetch_constant_pool_entry (abfd, &entry, i) < 0)
+ fprintf (f, " [%8lu] [INVALID]\n", i);
+ else
+ {
+ fprintf (f, " [%8lu] ", i);
+ bfd_sym_print_constant_pool_entry (abfd, f, &entry);
+ fprintf (f, "\n");
+ }
+ }
+}
+
+void
+bfd_sym_display_type_information_table (bfd *abfd, FILE *f)
+{
+ unsigned long i;
+ bfd_sym_type_table_entry sym_index;
+ bfd_sym_type_information_table_entry entry;
+ bfd_sym_data_struct *sdata = NULL;
+
+ BFD_ASSERT (bfd_sym_valid (abfd));
+ sdata = abfd->tdata.sym_data;
+
+ if (sdata->header.dshb_tte.dti_object_count > 99)
+ fprintf (f, "type table (TINFO) contains %lu objects:\n\n",
+ sdata->header.dshb_tte.dti_object_count - 99);
+ else
+ {
+ fprintf (f, "type table (TINFO) contains [INVALID] objects:\n\n");
+ return;
+ }
+
+ for (i = 100; i <= sdata->header.dshb_tte.dti_object_count; i++)
+ {
+ if (bfd_sym_fetch_type_table_entry (abfd, &sym_index, i - 100) < 0)
+ fprintf (f, " [%8lu] [INVALID]\n", i);
+ else
+ {
+ fprintf (f, " [%8lu] (TINFO %lu) ", i, sym_index);
+
+ if (bfd_sym_fetch_type_information_table_entry (abfd, &entry, sym_index) < 0)
+ fprintf (f, "[INVALID]");
+ else
+ bfd_sym_print_type_information_table_entry (abfd, f, &entry);
+
+ fprintf (f, "\n");
+ }
+ }
+}
+
+int
+bfd_sym_scan (bfd *abfd, bfd_sym_version version, bfd_sym_data_struct *mdata)
+{
+ asection *bfdsec;
+ const char *name = "symbols";
+
+ mdata->name_table = 0;
+ mdata->sbfd = abfd;
+ mdata->version = version;
+
+ bfd_seek (abfd, 0, SEEK_SET);
+ if (bfd_sym_read_header (abfd, &mdata->header, mdata->version) != 0)
+ return -1;
+
+ mdata->name_table = bfd_sym_read_name_table (abfd, &mdata->header);
+ if (mdata->name_table == NULL)
+ return -1;
+
+ bfdsec = bfd_make_section_anyway_with_flags (abfd, name, SEC_HAS_CONTENTS);
+ if (bfdsec == NULL)
+ return -1;
+
+ bfdsec->vma = 0;
+ bfdsec->lma = 0;
+ bfdsec->size = 0;
+ bfdsec->filepos = 0;
+ bfdsec->alignment_power = 0;
+
+ abfd->tdata.sym_data = mdata;
+
+ return 0;
+}
+
+const bfd_target *
+bfd_sym_object_p (bfd *abfd)
+{
+ bfd_sym_version version = -1;
+ bfd_sym_data_struct *mdata;
+
+ bfd_seek (abfd, 0, SEEK_SET);
+ if (bfd_sym_read_version (abfd, &version) != 0)
+ goto wrong;
+
+ mdata = (bfd_sym_data_struct *) bfd_alloc (abfd, sizeof (*mdata));
+ if (mdata == NULL)
+ goto fail;
+
+ if (bfd_sym_scan (abfd, version, mdata) != 0)
+ goto wrong;
+
+ return abfd->xvec;
+
+ wrong:
+ bfd_set_error (bfd_error_wrong_format);
+
+ fail:
+ return NULL;
+}
+
+#define bfd_sym_make_empty_symbol _bfd_generic_make_empty_symbol
+
+void
+bfd_sym_get_symbol_info (bfd *abfd ATTRIBUTE_UNUSED, asymbol *symbol, symbol_info *ret)
+{
+ bfd_symbol_info (symbol, ret);
+}
+
+long
+bfd_sym_get_symtab_upper_bound (bfd *abfd ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+long
+bfd_sym_canonicalize_symtab (bfd *abfd ATTRIBUTE_UNUSED, asymbol **sym ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+int
+bfd_sym_sizeof_headers (bfd *abfd ATTRIBUTE_UNUSED,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+const bfd_target sym_vec =
+{
+ "sym", /* Name. */
+ bfd_target_sym_flavour, /* Flavour. */
+ BFD_ENDIAN_BIG, /* Byteorder. */
+ BFD_ENDIAN_BIG, /* Header byteorder. */
+ (HAS_RELOC | EXEC_P | /* Object flags. */
+ HAS_LINENO | HAS_DEBUG |
+ HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED),
+ (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. */
+ 0, /* match priority. */
+ 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,
+ bfd_sym_object_p, /* bfd_check_format. */
+ _bfd_dummy_target,
+ _bfd_dummy_target,
+ },
+ { /* bfd_set_format. */
+ bfd_false,
+ bfd_sym_mkobject,
+ bfd_false,
+ bfd_false,
+ },
+ { /* bfd_write_contents. */
+ bfd_false,
+ bfd_true,
+ bfd_false,
+ bfd_false,
+ },
+
+ BFD_JUMP_TABLE_GENERIC (bfd_sym),
+ BFD_JUMP_TABLE_COPY (_bfd_generic),
+ BFD_JUMP_TABLE_CORE (_bfd_nocore),
+ BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive),
+ BFD_JUMP_TABLE_SYMBOLS (bfd_sym),
+ BFD_JUMP_TABLE_RELOCS (_bfd_norelocs),
+ BFD_JUMP_TABLE_WRITE (bfd_sym),
+ BFD_JUMP_TABLE_LINK (bfd_sym),
+ BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
+
+ NULL,
+
+ NULL
+};
diff --git a/bfd/xsym.h b/bfd/xsym.h
new file mode 100644
index 0000000..1a80e25
--- /dev/null
+++ b/bfd/xsym.h
@@ -0,0 +1,700 @@
+/* xSYM symbol-file support for BFD.
+ Copyright (C) 1999-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include <stdio.h>
+
+#ifndef __xSYM_H__
+#define __xSYM_H__
+
+#define BFD_SYM_VERSION_STR_3_1 "\013Version 3.1"
+#define BFD_SYM_VERSION_STR_3_2 "\013Version 3.2"
+#define BFD_SYM_VERSION_STR_3_3 "\013Version 3.3"
+#define BFD_SYM_VERSION_STR_3_4 "\013Version 3.4"
+#define BFD_SYM_VERSION_STR_3_5 "\013Version 3.5"
+#define BFD_SYM_END_OF_LIST_3_2 0xffff
+#define BFD_SYM_END_OF_LIST_3_4 0xffffffff
+#define BFD_SYM_END_OF_LIST BFD_SYM_END_OF_LIST_3_4
+#define BFD_SYM_FILE_NAME_INDEX_3_2 0xfffe
+#define BFD_SYM_FILE_NAME_INDEX_3_4 0xfffffffe
+#define BFD_SYM_FILE_NAME_INDEX BFD_SYM_FILE_NAME_INDEX_3_4
+#define BFD_SYM_SOURCE_FILE_CHANGE_3_2 0xfffe
+#define BFD_SYM_SOURCE_FILE_CHANGE_3_4 0xfffffffe
+#define BFD_SYM_SOURCE_FILE_CHANGE BFD_SYM_SOURCE_FILE_CHANGE_3_4
+#define BFD_SYM_MAXIMUM_LEGAL_INDEX_3_2 0xfffd
+#define BFD_SYM_MAXIMUM_LEGAL_INDEX_3_4 0xfffffffd
+#define BFD_SYM_MAXIMUM_LEGAL_INDEX BFD_SYM_MAXIMUM_LEGAL_INDEX_3_4
+
+enum bfd_sym_storage_class
+{
+ BFD_SYM_STORAGE_CLASS_REGISTER = 0,
+ BFD_SYM_STORAGE_CLASS_GLOBAL = 1,
+ BFD_SYM_STORAGE_CLASS_FRAME_RELATIVE = 2,
+ BFD_SYM_STORAGE_CLASS_STACK_RELATIVE = 3,
+ BFD_SYM_STORAGE_CLASS_ABSOLUTE = 4,
+ BFD_SYM_STORAGE_CLASS_CONSTANT = 5,
+ BFD_SYM_STORAGE_CLASS_BIGCONSTANT = 6,
+ BFD_SYM_STORAGE_CLASS_RESOURCE = 99
+};
+typedef enum bfd_sym_storage_class bfd_sym_storage_class;
+
+enum bfd_sym_storage_kind
+{
+ BFD_SYM_STORAGE_KIND_LOCAL = 0,
+ BFD_SYM_STORAGE_KIND_VALUE = 1,
+ BFD_SYM_STORAGE_KIND_REFERENCE = 2,
+ BFD_SYM_STORAGE_KIND_WITH = 3
+};
+typedef enum bfd_sym_storage_kind bfd_sym_storage_kind;
+
+enum bfd_sym_version
+{
+ BFD_SYM_VERSION_3_1,
+ BFD_SYM_VERSION_3_2,
+ BFD_SYM_VERSION_3_3,
+ BFD_SYM_VERSION_3_4,
+ BFD_SYM_VERSION_3_5
+};
+typedef enum bfd_sym_version bfd_sym_version;
+
+enum bfd_sym_module_kind
+{
+ BFD_SYM_MODULE_KIND_NONE = 0,
+ BFD_SYM_MODULE_KIND_PROGRAM = 1,
+ BFD_SYM_MODULE_KIND_UNIT = 2,
+ BFD_SYM_MODULE_KIND_PROCEDURE = 3,
+ BFD_SYM_MODULE_KIND_FUNCTION = 4,
+ BFD_SYM_MODULE_KIND_DATA = 5,
+ BFD_SYM_MODULE_KIND_BLOCK = 6
+};
+typedef enum bfd_sym_module_kind bfd_sym_module_kind;
+
+enum bfd_sym_symbol_scope
+{
+ BFD_SYM_SYMBOL_SCOPE_LOCAL = 0, /* Object is seen only inside current scope. */
+ BFD_SYM_SYMBOL_SCOPE_GLOBAL = 1 /* Object has global scope. */
+};
+typedef enum bfd_sym_symbol_scope bfd_sym_symbol_scope;
+
+struct bfd_sym_file_reference
+{
+ unsigned long fref_frte_index; /* File reference table index. */
+ unsigned long fref_offset; /* Absolute offset into source file. */
+};
+typedef struct bfd_sym_file_reference bfd_sym_file_reference;
+
+/* NAME TABLE (NTE). */
+
+/* RESOURCES TABLE (RTE)
+
+ All code and data is *defined* to reside in a resource. Even A5
+ relative data is defined to reside in a dummy resource of ResType
+ 'gbld'. Code always resides in a resource. Because a code/data
+ is built of many modules, when walking through a resource we must
+ point back to the modules in the order they were defined. This is
+ done by requiring the entries in the Modules Entry table to be
+ ordered by resource/resource-number and by the location in that
+ resource. Hence, the resource table entry points to the first
+ module making up that resource. All modules table entries following
+ that first one with the same restype/resnum are contiguous and offset
+ from that first entry. */
+
+struct bfd_sym_resources_table_entry
+{
+ unsigned char rte_res_type[4]; /* Resource Type. */
+ unsigned short rte_res_number; /* Resource Number. */
+ unsigned long rte_nte_index; /* Name of the resource. */
+ unsigned long rte_mte_first; /* Index of first module in the resource. */
+ unsigned long rte_mte_last; /* Index of the last module in the resource. */
+ unsigned long rte_res_size; /* Size of the resource. */
+};
+typedef struct bfd_sym_resources_table_entry bfd_sym_resources_table_entry;
+
+/* MODULES TABLE (MTE)
+
+ Modules table entries are ordered by their appearance in a resource.
+ (Note that having a single module copied into two resources is not
+ possible). Modules map back to their resource via an index into the
+ resource table and an offset into the resource. Modules also point
+ to their source files, both the definition module and implementation
+ module. Because modules can be textually nested within other
+ modules, a link to the parent (containing) module is required. This
+ module can textually contain other modules. A link to the contiguous
+ list of child (contained) modules is required. Variables, statements,
+ and types defined in the module are pointed to by indexing the head of
+ the contiguous lists of contained variables, contained statements,
+ and contained types. */
+
+struct bfd_sym_modules_table_entry
+{
+ unsigned long mte_rte_index; /* Which resource it is in. */
+ unsigned long mte_res_offset; /* Offset into the resource. */
+ unsigned long mte_size; /* Size of module. */
+ char mte_kind; /* What kind of module this is. */
+ char mte_scope; /* How visible is it? */
+ unsigned long mte_parent; /* Containing module. */
+ bfd_sym_file_reference mte_imp_fref; /* Implementation source. */
+ unsigned long mte_imp_end; /* End of implementation source. */
+ unsigned long mte_nte_index; /* The name of the module. */
+ unsigned long mte_cmte_index; /* Modules contained in this. */
+ unsigned long mte_cvte_index; /* Variables contained in this. */
+ unsigned long mte_clte_index; /* Local labels defined here. */
+ unsigned long mte_ctte_index; /* Types contained in this. */
+ unsigned long mte_csnte_idx_1; /* CSNTE index of mte_snbr_first. */
+ unsigned long mte_csnte_idx_2; /* CSNTE index of mte_snbr_last. */
+};
+typedef struct bfd_sym_modules_table_entry bfd_sym_modules_table_entry;
+
+/* FILE REFERENCES TABLE (FRTE)
+
+ The FILE REFERENCES TABLE maps from source file to module & offset.
+ The table is ordered by increasing file offset. Each new offset
+ references a module.
+
+ FRT = FILE_SOURCE_START
+ FILE_SOURCE_INCREMENT*
+ END_OF_LIST.
+
+ *** THIS MECHANISM IS VERY SLOW FOR FILE+STATEMENT_NUMBER TO
+ *** MODULE/CODE ADDRESS OPERATIONS. ANOTHER MECHANISM IS
+ *** REQUIRED!! */
+
+union bfd_sym_file_references_table_entry
+{
+ struct
+ {
+ /* END_OF_LIST, FILE_NAME_INDEX, or module table entry. */
+ unsigned long type;
+ }
+ generic;
+
+ struct
+ {
+ /* FILE_NAME_INDEX. */
+ unsigned long type;
+ unsigned long nte_index;
+ unsigned long mod_date;
+ }
+ filename;
+
+ struct
+ {
+ /* < FILE_NAME_INDEX. */
+ unsigned long mte_index;
+ unsigned long file_offset;
+ }
+ entry;
+};
+typedef union bfd_sym_file_references_table_entry bfd_sym_file_references_table_entry;
+
+/* CONTAINED MODULES TABLE (CMTE)
+
+ Contained Modules are lists of indices into the modules table. The
+ lists are terminated by an END_OF_LIST index. All entries are of the
+ same size, hence mapping an index into a CMTE list is simple.
+
+ CMT = MTE_INDEX* END_OF_LIST. */
+
+union bfd_sym_contained_modules_table_entry
+{
+ struct
+ {
+ /* END_OF_LIST, index. */
+ unsigned long type;
+ }
+ generic;
+
+ struct
+ {
+ unsigned long mte_index; /* Index into the Modules Table. */
+ unsigned long nte_index; /* The name of the module. */
+ }
+ entry;
+};
+typedef union bfd_sym_contained_modules_table_entry bfd_sym_contained_modules_table_entry;
+
+/* CONTAINED VARIABLES TABLE (CVTE)
+
+ Contained Variables map into the module table, file table, name table, and type
+ table. Contained Variables are a contiguous list of source file change record,
+ giving the name of and offset into the source file corresponding to all variables
+ following. Variable definition records contain an index into the name table (giving
+ the text of the variable as it appears in the source code), an index into the type
+ table giving the type of the variable, an increment added to the source file
+ offset giving the start of the implementation of the variable, and a storage
+ class address, giving information on variable's runtime address.
+
+ CVT = SOURCE_FILE_CHANGE SYMBOL_INFO* END_OF_LIST.
+ SYMBOL_INFO = SYMBOL_DEFINITION | SOURCE_FILE_CHANGE .
+
+ All entries are of the same size, making the fetching of data simple. The
+ variable entries in the list are in ALPHABETICAL ORDER to simplify the display of
+ available variables for several of the debugger's windows. */
+
+/* 'la_size' determines the variant used below:
+
+ == BFD_SYM_CVTE_SCA
+ Traditional STORAGE_CLASS_ADDRESS;
+
+ <= BFD_SYM_CVTE_LA_MAX_SIZE
+ That many logical address bytes ("in-situ");
+
+ == BFD_SYM_CVTE_BIG_LA
+ Logical address bytes in constant pool, at offset 'big_la'. */
+
+#define BFD_SYM_CVTE_SCA 0 /* Indicate SCA variant of CVTE. */
+#define BFD_SYM_CVTE_LA_MAX_SIZE 13 /* Max# of logical address bytes in a CVTE. */
+#define BFD_SYM_CVTE_BIG_LA 127 /* Indicates LA redirection to constant pool. */
+
+union bfd_sym_contained_variables_table_entry
+{
+ struct
+ {
+ /* END_OF_LIST, SOURCE_FILE_CHANGE, or type table entry. */
+ unsigned long type;
+ }
+ generic;
+
+ struct
+ {
+ /* SOURCE_FILE_CHANGE. */
+ unsigned long type;
+ bfd_sym_file_reference fref;
+ }
+ file;
+
+ struct
+ {
+ /* < SOURCE_FILE_CHANGE. */
+ unsigned long tte_index;
+ unsigned long nte_index;
+ unsigned long file_delta; /* Increment from previous source. */
+ unsigned char scope;
+ unsigned char la_size; /* #bytes of LAs below. */
+
+ union
+ {
+ /* la_size == BFD_SYM_CVTE_SCA. */
+ struct
+ {
+ unsigned char sca_kind; /* Distinguish local from value/var formal. */
+ unsigned char sca_class; /* The storage class itself. */
+ unsigned long sca_offset;
+ }
+ scstruct;
+
+ /* la_size <= BFD_SYM_CVTE_LA_MAX_SIZE. */
+ struct {
+ unsigned char la[BFD_SYM_CVTE_LA_MAX_SIZE]; /* Logical address bytes. */
+ unsigned char la_kind; /* Eqv. cvte_location.sca_kind. */
+ }
+ lastruct;
+
+ /* la_size == BFD_SYM_CVTE_BIG_LA 127. */
+ struct
+ {
+ unsigned long big_la; /* Logical address bytes in constant pool. */
+ unsigned char big_la_kind; /* Eqv. cvte_location.sca_kind. */
+ }
+ biglastruct;
+ }
+ address;
+ }
+ entry;
+};
+typedef union bfd_sym_contained_variables_table_entry bfd_sym_contained_variables_table_entry;
+
+/* CONTAINED STATEMENTS TABLE (CSNTE)
+
+ Contained Statements table. This table is similar to the Contained
+ Variables table except that instead of VARIABLE_DEFINITION entries, this
+ module contains STATEMENT_NUMBER_DEFINITION entries. A statement number
+ definition points back to the containing module (via an index into
+ the module entry table) and contains the file and resource deltas
+ to add to the previous values to get to this statement.
+ All entries are of the same size, making the fetching of data simple. The
+ entries in the table are in order of increasing statement number within the
+ source file.
+
+ The Contained Statements table is indexed from two places. An MTE contains
+ an index to the first statement number within the module. An FRTE contains
+ an index to the first statement in the table (Possibly. This is slow.) Or
+ a table of fast statement number to CSNTE entry mappings indexes into the
+ table. Choice not yet made. */
+
+union bfd_sym_contained_statements_table_entry
+{
+ struct
+ {
+ /* END_OF_LIST, SOURCE_FILE_CHANGE, or statement table entry. */
+ unsigned long type;
+ }
+ generic;
+
+ struct
+ {
+ /* SOURCE_FILE_CHANGE. */
+ unsigned long type;
+ bfd_sym_file_reference fref; /* File name table. */
+ }
+ file;
+
+ struct
+ {
+ unsigned long mte_index; /* Which module contains it. */
+ unsigned long file_delta; /* Where it is defined. */
+ unsigned long mte_offset; /* Where it is in the module. */
+ }
+ entry;
+};
+typedef union bfd_sym_contained_statements_table_entry bfd_sym_contained_statements_table_entry;
+
+/* CONTAINED LABELS TABLE (CLTE)
+
+ Contained Labels table names those labels local to the module. It is similar
+ to the Contained Statements table. */
+
+union bfd_sym_contained_labels_table_entry
+{
+ struct
+ {
+ /* END_OF_LIST, SOURCE_FILE_CHANGE, index. */
+ unsigned long type;
+ }
+ generic;
+
+ struct
+ {
+ /* SOURCE_FILE_CHANGE. */
+ unsigned long type;
+ bfd_sym_file_reference fref;
+ }
+ file;
+
+ struct
+ {
+ /* < SOURCE_FILE_CHANGE. */
+ unsigned long mte_index; /* Which module contains us. */
+ unsigned long mte_offset; /* Where it is in the module. */
+ unsigned long nte_index; /* The name of the label. */
+ unsigned long file_delta; /* Where it is defined. */
+ unsigned short scope; /* How visible the label is. */
+ }
+ entry;
+};
+typedef union bfd_sym_contained_labels_table_entry bfd_sym_contained_labels_table_entry;
+
+/* CONTAINED TYPES TABLE (CTTE)
+
+ Contained Types define the named types that are in the module. It is used to
+ map name indices into type indices. The type entries in the table are in
+ alphabetical order by type name. */
+
+union bfd_sym_contained_types_table_entry
+{
+ struct
+ {
+ /* END_OF_LIST, SOURCE_FILE_CHANGE, or type table entry. */
+ unsigned long type;
+ }
+ generic;
+
+ struct
+ {
+ /* SOURCE_FILE_CHANGE. */
+ unsigned long type;
+ bfd_sym_file_reference fref;
+ }
+ file;
+
+ struct
+ {
+ /* < SOURCE_FILE_CHANGE. */
+ unsigned long tte_index;
+ unsigned long nte_index;
+ unsigned long file_delta; /* From last file definition. */
+ }
+ entry;
+};
+typedef union bfd_sym_contained_types_table_entry bfd_sym_contained_types_table_entry;
+
+/* TYPE TABLE (TTE). */
+
+typedef unsigned long bfd_sym_type_table_entry;
+
+/* TYPE INFORMATION TABLE (TINFO). */
+
+struct bfd_sym_type_information_table_entry
+{
+ unsigned long nte_index;
+ unsigned long physical_size;
+ unsigned long logical_size;
+ unsigned long offset;
+};
+typedef struct bfd_sym_type_information_table_entry bfd_sym_type_information_table_entry;
+
+/* FILE REFERENCES INDEX TABLE (FITE)
+
+ The FRTE INDEX TABLE indexes into the FILE REFERENCE TABLE above. The FRTE
+ at that index is the FILE_SOURCE_START for a series of files. The FRTEs are
+ indexed from 1. The list is terminated with an END_OF_LIST. */
+
+union bfd_sym_file_references_index_table_entry
+{
+ struct
+ {
+ unsigned long type;
+ }
+ generic;
+
+ struct
+ {
+ unsigned long frte_index; /* Index into the FRTE table. */
+ unsigned long nte_index; /* Name table index, gives filename. */
+ }
+ entry;
+};
+typedef union bfd_sym_file_references_index_table_entry bfd_sym_file_references_index_table_entry;
+
+/* CONSTANT POOL (CONST)
+
+ The CONSTANT_POOL consists of entries that start on word boundaries. The entries
+ are referenced by byte index into the constant pool, not by record number.
+
+ Each entry takes the form:
+
+ <16-bit size>
+ <that many bytes of stuff>
+
+ Entries do not cross page boundaries. */
+
+typedef short bfd_sym_constant_pool_entry;
+
+/* The DISK_SYMBOL_HEADER_BLOCK is the first record in a .SYM file,
+ defining the physical characteristics of the symbolic information.
+ The remainder of the * .SYM file is stored in fixed block
+ allocations. For the purposes of paging, the * file is considered
+ to be an array of dshb_page_size blocks, with block 0 (and *
+ possibly more) devoted to the DISK_SYMBOL_HEADER_BLOCK.
+
+ The dti_object_count field means that the allowed indices for that
+ type of object are 0 .. dti_object_count. An index of 0, although
+ allowed, is never done. However, an 0th entry is created in the
+ table. That entry is filled with all zeroes. The reason for this
+ is to avoid off-by-one programming errors that would otherwise
+ occur: an index of k *MEANS* k, not k-1 when going to the disk
+ table. */
+
+struct bfd_sym_table_info
+{
+ unsigned long dti_first_page; /* First page for this table. */
+ unsigned long dti_page_count; /* Number of pages for the table. */
+ unsigned long dti_object_count; /* Number of objects in the table. */
+};
+typedef struct bfd_sym_table_info bfd_sym_table_info;
+
+struct bfd_sym_header_block
+{
+ unsigned char dshb_id[32]; /* Version information. */
+ unsigned short dshb_page_size; /* Size of the pages/blocks. */
+ unsigned long dshb_hash_page; /* Disk page for the hash table. */
+ unsigned long dshb_root_mte; /* MTE index of the program root. */
+ unsigned long dshb_mod_date; /* modification date of executable. */
+ bfd_sym_table_info dshb_frte; /* Per TABLE information. */
+ bfd_sym_table_info dshb_rte;
+ bfd_sym_table_info dshb_mte;
+ bfd_sym_table_info dshb_cmte;
+ bfd_sym_table_info dshb_cvte;
+ bfd_sym_table_info dshb_csnte;
+ bfd_sym_table_info dshb_clte;
+ bfd_sym_table_info dshb_ctte;
+ bfd_sym_table_info dshb_tte;
+ bfd_sym_table_info dshb_nte;
+ bfd_sym_table_info dshb_tinfo;
+ bfd_sym_table_info dshb_fite; /* File information. */
+ bfd_sym_table_info dshb_const; /* Constant pool. */
+
+ unsigned char dshb_file_creator[4]; /* Executable's creator. */
+ unsigned char dshb_file_type[4]; /* Executable's file type. */
+};
+typedef struct bfd_sym_header_block bfd_sym_header_block;
+
+struct bfd_sym_data_struct
+{
+ unsigned char *name_table;
+ bfd_sym_header_block header;
+ bfd_sym_version version;
+ bfd *sbfd;
+};
+typedef struct bfd_sym_data_struct bfd_sym_data_struct;
+
+extern bfd_boolean bfd_sym_mkobject
+ (bfd *);
+extern void bfd_sym_print_symbol
+ (bfd *, void *, asymbol *, bfd_print_symbol_type);
+extern bfd_boolean bfd_sym_valid
+ (bfd *);
+extern unsigned char * bfd_sym_read_name_table
+ (bfd *, bfd_sym_header_block *);
+extern void bfd_sym_parse_file_reference_v32
+ (unsigned char *, size_t, bfd_sym_file_reference *);
+extern void bfd_sym_parse_disk_table_v32
+ (unsigned char *, size_t, bfd_sym_table_info *);
+extern void bfd_sym_parse_header_v32
+ (unsigned char *, size_t, bfd_sym_header_block *);
+extern int bfd_sym_read_header_v32
+ (bfd *, bfd_sym_header_block *);
+extern int bfd_sym_read_header_v34
+ (bfd *, bfd_sym_header_block *);
+extern int bfd_sym_read_header
+ (bfd *, bfd_sym_header_block *, bfd_sym_version);
+extern int bfd_sym_read_version
+ (bfd *, bfd_sym_version *);
+extern void bfd_sym_display_table_summary
+ (FILE *, bfd_sym_table_info *, const char *);
+extern void bfd_sym_display_header
+ (FILE *, bfd_sym_header_block *);
+extern void bfd_sym_parse_resources_table_entry_v32
+ (unsigned char *, size_t, bfd_sym_resources_table_entry *);
+extern void bfd_sym_parse_modules_table_entry_v33
+ (unsigned char *, size_t, bfd_sym_modules_table_entry *);
+extern void bfd_sym_parse_file_references_table_entry_v32
+ (unsigned char *, size_t, bfd_sym_file_references_table_entry *);
+extern void bfd_sym_parse_contained_modules_table_entry_v32
+ (unsigned char *, size_t, bfd_sym_contained_modules_table_entry *);
+extern void bfd_sym_parse_contained_variables_table_entry_v32
+ (unsigned char *, size_t, bfd_sym_contained_variables_table_entry *);
+extern void bfd_sym_parse_contained_statements_table_entry_v32
+ (unsigned char *, size_t, bfd_sym_contained_statements_table_entry *);
+extern void bfd_sym_parse_contained_labels_table_entry_v32
+ (unsigned char *, size_t, bfd_sym_contained_labels_table_entry *);
+extern void bfd_sym_parse_type_table_entry_v32
+ (unsigned char *, size_t, bfd_sym_type_table_entry *);
+extern int bfd_sym_fetch_resources_table_entry
+ (bfd *, bfd_sym_resources_table_entry *, unsigned long);
+extern int bfd_sym_fetch_modules_table_entry
+ (bfd *, bfd_sym_modules_table_entry *, unsigned long);
+extern int bfd_sym_fetch_file_references_table_entry
+ (bfd *, bfd_sym_file_references_table_entry *, unsigned long);
+extern int bfd_sym_fetch_contained_modules_table_entry
+ (bfd *, bfd_sym_contained_modules_table_entry *, unsigned long);
+extern int bfd_sym_fetch_contained_variables_table_entry
+ (bfd *, bfd_sym_contained_variables_table_entry *, unsigned long);
+extern int bfd_sym_fetch_contained_statements_table_entry
+ (bfd *, bfd_sym_contained_statements_table_entry *, unsigned long);
+extern int bfd_sym_fetch_contained_labels_table_entry
+ (bfd *, bfd_sym_contained_labels_table_entry *, unsigned long);
+extern int bfd_sym_fetch_contained_types_table_entry
+ (bfd *, bfd_sym_contained_types_table_entry *, unsigned long);
+extern int bfd_sym_fetch_file_references_index_table_entry
+ (bfd *, bfd_sym_file_references_index_table_entry *, unsigned long);
+extern int bfd_sym_fetch_constant_pool_entry
+ (bfd *, bfd_sym_constant_pool_entry *, unsigned long);
+extern int bfd_sym_fetch_type_table_entry
+ (bfd *, bfd_sym_type_table_entry *, unsigned long);
+extern int bfd_sym_fetch_type_information_table_entry
+ (bfd *, bfd_sym_type_information_table_entry *, unsigned long);
+extern int bfd_sym_fetch_type_table_information
+ (bfd *, bfd_sym_type_information_table_entry *, unsigned long);
+extern const unsigned char * bfd_sym_symbol_name
+ (bfd *, unsigned long);
+extern const unsigned char * bfd_sym_module_name
+ (bfd *, unsigned long);
+extern const char * bfd_sym_unparse_storage_kind
+ (enum bfd_sym_storage_kind);
+extern const char * bfd_sym_unparse_storage_class
+ (enum bfd_sym_storage_class);
+extern const char * bfd_sym_unparse_module_kind
+ (enum bfd_sym_module_kind);
+extern const char * bfd_sym_unparse_symbol_scope
+ (enum bfd_sym_symbol_scope);
+extern void bfd_sym_print_file_reference
+ (bfd *, FILE *, bfd_sym_file_reference *);
+extern void bfd_sym_print_resources_table_entry
+ (bfd *, FILE *, bfd_sym_resources_table_entry *);
+extern void bfd_sym_print_modules_table_entry
+ (bfd *, FILE *, bfd_sym_modules_table_entry *);
+extern void bfd_sym_print_file_references_table_entry
+ (bfd *, FILE *, bfd_sym_file_references_table_entry *);
+extern void bfd_sym_print_contained_modules_table_entry
+ (bfd *, FILE *, bfd_sym_contained_modules_table_entry *);
+extern void bfd_sym_print_contained_variables_table_entry
+ (bfd *, FILE *f, bfd_sym_contained_variables_table_entry *);
+extern void bfd_sym_print_contained_statements_table_entry
+ (bfd *, FILE *, bfd_sym_contained_statements_table_entry *);
+extern void bfd_sym_print_contained_labels_table_entry
+ (bfd *, FILE *, bfd_sym_contained_labels_table_entry *);
+extern void bfd_sym_print_contained_types_table_entry
+ (bfd *, FILE *, bfd_sym_contained_types_table_entry *);
+extern const char * bfd_sym_type_operator_name
+ (unsigned char);
+extern const char * bfd_sym_type_basic_name
+ (unsigned char);
+extern int bfd_sym_fetch_long
+ (unsigned char *, unsigned long, unsigned long, unsigned long *, long *);
+extern void bfd_sym_print_type_information
+ (bfd *, FILE *, unsigned char *, unsigned long, unsigned long, unsigned long *);
+extern void bfd_sym_print_type_information_table_entry
+ (bfd *, FILE *, bfd_sym_type_information_table_entry *);
+extern void bfd_sym_print_file_references_index_table_entry
+ (bfd *, FILE *, bfd_sym_file_references_index_table_entry *);
+extern void bfd_sym_print_constant_pool_entry
+ (bfd *, FILE *, bfd_sym_constant_pool_entry *);
+extern unsigned char * bfd_sym_display_name_table_entry
+ (bfd *, FILE *, unsigned char *);
+extern void bfd_sym_display_name_table
+ (bfd *, FILE *);
+extern void bfd_sym_display_resources_table
+ (bfd *, FILE *);
+extern void bfd_sym_display_modules_table
+ (bfd *, FILE *);
+extern void bfd_sym_display_file_references_table
+ (bfd *, FILE *);
+extern void bfd_sym_display_contained_modules_table
+ (bfd *, FILE *);
+extern void bfd_sym_display_contained_variables_table
+ (bfd *, FILE *);
+extern void bfd_sym_display_contained_statements_table
+ (bfd *, FILE *);
+extern void bfd_sym_display_contained_labels_table
+ (bfd *, FILE *);
+extern void bfd_sym_display_contained_types_table
+ (bfd *, FILE *);
+extern void bfd_sym_display_file_references_index_table
+ (bfd *, FILE *);
+extern void bfd_sym_display_constant_pool
+ (bfd *, FILE *);
+extern void bfd_sym_display_type_information_table
+ (bfd *, FILE *);
+extern int bfd_sym_scan
+ (bfd *, bfd_sym_version, bfd_sym_data_struct *);
+extern const bfd_target * bfd_sym_object_p
+ (bfd *);
+extern void bfd_sym_get_symbol_info
+ (bfd *, asymbol *, symbol_info *);
+extern long bfd_sym_get_symtab_upper_bound
+ (bfd *);
+extern long bfd_sym_canonicalize_symtab
+ (bfd *, asymbol **);
+extern int bfd_sym_sizeof_headers
+ (bfd *, struct bfd_link_info *);
+
+#endif /* __xSYM_H__ */
diff --git a/bfd/xtensa-isa.c b/bfd/xtensa-isa.c
new file mode 100644
index 0000000..0fa8ab4
--- /dev/null
+++ b/bfd/xtensa-isa.c
@@ -0,0 +1,1793 @@
+/* Configurable Xtensa ISA support.
+ Copyright (C) 2003-2014 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 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+#include "xtensa-isa.h"
+#include "xtensa-isa-internal.h"
+
+xtensa_isa_status xtisa_errno;
+char xtisa_error_msg[1024];
+
+
+xtensa_isa_status
+xtensa_isa_errno (xtensa_isa isa __attribute__ ((unused)))
+{
+ return xtisa_errno;
+}
+
+
+char *
+xtensa_isa_error_msg (xtensa_isa isa __attribute__ ((unused)))
+{
+ return xtisa_error_msg;
+}
+
+
+#define CHECK_ALLOC(MEM,ERRVAL) \
+ do { \
+ if ((MEM) == 0) \
+ { \
+ xtisa_errno = xtensa_isa_out_of_memory; \
+ strcpy (xtisa_error_msg, "out of memory"); \
+ return (ERRVAL); \
+ } \
+ } while (0)
+
+#define CHECK_ALLOC_FOR_INIT(MEM,ERRVAL,ERRNO_P,ERROR_MSG_P) \
+ do { \
+ if ((MEM) == 0) \
+ { \
+ xtisa_errno = xtensa_isa_out_of_memory; \
+ strcpy (xtisa_error_msg, "out of memory"); \
+ if (ERRNO_P) *(ERRNO_P) = xtisa_errno; \
+ if (ERROR_MSG_P) *(ERROR_MSG_P) = xtisa_error_msg; \
+ return (ERRVAL); \
+ } \
+ } while (0)
+
+
+
+/* Instruction buffers. */
+
+int
+xtensa_insnbuf_size (xtensa_isa isa)
+{
+ xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
+ return intisa->insnbuf_size;
+}
+
+
+xtensa_insnbuf
+xtensa_insnbuf_alloc (xtensa_isa isa)
+{
+ xtensa_insnbuf result = (xtensa_insnbuf)
+ malloc (xtensa_insnbuf_size (isa) * sizeof (xtensa_insnbuf_word));
+ CHECK_ALLOC (result, 0);
+ return result;
+}
+
+
+void
+xtensa_insnbuf_free (xtensa_isa isa __attribute__ ((unused)),
+ xtensa_insnbuf buf)
+{
+ free (buf);
+}
+
+
+/* Given <byte_index>, the index of a byte in a xtensa_insnbuf, our
+ internal representation of a xtensa instruction word, return the index of
+ its word and the bit index of its low order byte in the xtensa_insnbuf. */
+
+static inline int
+byte_to_word_index (int byte_index)
+{
+ return byte_index / sizeof (xtensa_insnbuf_word);
+}
+
+
+static inline int
+byte_to_bit_index (int byte_index)
+{
+ return (byte_index & 0x3) * 8;
+}
+
+
+/* Copy an instruction in the 32-bit words pointed at by "insn" to
+ characters pointed at by "cp". This is more complicated than you
+ might think because we want 16-bit instructions in bytes 2 & 3 for
+ big-endian configurations. This function allows us to specify
+ which byte in "insn" to start with and which way to increment,
+ allowing trivial implementation for both big- and little-endian
+ configurations....and it seems to make pretty good code for
+ both. */
+
+int
+xtensa_insnbuf_to_chars (xtensa_isa isa,
+ const xtensa_insnbuf insn,
+ unsigned char *cp,
+ int num_chars)
+{
+ xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
+ int insn_size = xtensa_isa_maxlength (isa);
+ int fence_post, start, increment, i, byte_count;
+ xtensa_format fmt;
+
+ if (num_chars == 0)
+ num_chars = insn_size;
+
+ if (intisa->is_big_endian)
+ {
+ start = insn_size - 1;
+ increment = -1;
+ }
+ else
+ {
+ start = 0;
+ increment = 1;
+ }
+
+ /* Find the instruction format. Do nothing if the buffer does not contain
+ a valid instruction since we need to know how many bytes to copy. */
+ fmt = xtensa_format_decode (isa, insn);
+ if (fmt == XTENSA_UNDEFINED)
+ return XTENSA_UNDEFINED;
+
+ byte_count = xtensa_format_length (isa, fmt);
+ if (byte_count == XTENSA_UNDEFINED)
+ return XTENSA_UNDEFINED;
+
+ if (byte_count > num_chars)
+ {
+ xtisa_errno = xtensa_isa_buffer_overflow;
+ strcpy (xtisa_error_msg, "output buffer too small for instruction");
+ return XTENSA_UNDEFINED;
+ }
+
+ fence_post = start + (byte_count * increment);
+
+ for (i = start; i != fence_post; i += increment, ++cp)
+ {
+ int word_inx = byte_to_word_index (i);
+ int bit_inx = byte_to_bit_index (i);
+
+ *cp = (insn[word_inx] >> bit_inx) & 0xff;
+ }
+
+ return byte_count;
+}
+
+
+/* Inward conversion from byte stream to xtensa_insnbuf. See
+ xtensa_insnbuf_to_chars for a discussion of why this is complicated
+ by endianness. */
+
+void
+xtensa_insnbuf_from_chars (xtensa_isa isa,
+ xtensa_insnbuf insn,
+ const unsigned char *cp,
+ int num_chars)
+{
+ xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
+ int max_size, insn_size, fence_post, start, increment, i;
+
+ max_size = xtensa_isa_maxlength (isa);
+
+ /* Decode the instruction length so we know how many bytes to read. */
+ insn_size = (intisa->length_decode_fn) (cp);
+ if (insn_size == XTENSA_UNDEFINED)
+ {
+ /* This should never happen when the byte stream contains a
+ valid instruction. Just read the maximum number of bytes.... */
+ insn_size = max_size;
+ }
+
+ if (num_chars == 0 || num_chars > insn_size)
+ num_chars = insn_size;
+
+ if (intisa->is_big_endian)
+ {
+ start = max_size - 1;
+ increment = -1;
+ }
+ else
+ {
+ start = 0;
+ increment = 1;
+ }
+
+ fence_post = start + (num_chars * increment);
+ memset (insn, 0, xtensa_insnbuf_size (isa) * sizeof (xtensa_insnbuf_word));
+
+ for (i = start; i != fence_post; i += increment, ++cp)
+ {
+ int word_inx = byte_to_word_index (i);
+ int bit_inx = byte_to_bit_index (i);
+
+ insn[word_inx] |= (*cp & 0xff) << bit_inx;
+ }
+}
+
+
+
+/* ISA information. */
+
+extern xtensa_isa_internal xtensa_modules;
+
+xtensa_isa
+xtensa_isa_init (xtensa_isa_status *errno_p, char **error_msg_p)
+{
+ xtensa_isa_internal *isa = &xtensa_modules;
+ int n, is_user;
+
+ /* Set up the opcode name lookup table. */
+ isa->opname_lookup_table =
+ bfd_malloc (isa->num_opcodes * sizeof (xtensa_lookup_entry));
+ CHECK_ALLOC_FOR_INIT (isa->opname_lookup_table, NULL, errno_p, error_msg_p);
+ for (n = 0; n < isa->num_opcodes; n++)
+ {
+ isa->opname_lookup_table[n].key = isa->opcodes[n].name;
+ isa->opname_lookup_table[n].u.opcode = n;
+ }
+ qsort (isa->opname_lookup_table, isa->num_opcodes,
+ sizeof (xtensa_lookup_entry), xtensa_isa_name_compare);
+
+ /* Set up the state name lookup table. */
+ isa->state_lookup_table =
+ bfd_malloc (isa->num_states * sizeof (xtensa_lookup_entry));
+ CHECK_ALLOC_FOR_INIT (isa->state_lookup_table, NULL, errno_p, error_msg_p);
+ for (n = 0; n < isa->num_states; n++)
+ {
+ isa->state_lookup_table[n].key = isa->states[n].name;
+ isa->state_lookup_table[n].u.state = n;
+ }
+ qsort (isa->state_lookup_table, isa->num_states,
+ sizeof (xtensa_lookup_entry), xtensa_isa_name_compare);
+
+ /* Set up the sysreg name lookup table. */
+ isa->sysreg_lookup_table =
+ bfd_malloc (isa->num_sysregs * sizeof (xtensa_lookup_entry));
+ CHECK_ALLOC_FOR_INIT (isa->sysreg_lookup_table, NULL, errno_p, error_msg_p);
+ for (n = 0; n < isa->num_sysregs; n++)
+ {
+ isa->sysreg_lookup_table[n].key = isa->sysregs[n].name;
+ isa->sysreg_lookup_table[n].u.sysreg = n;
+ }
+ qsort (isa->sysreg_lookup_table, isa->num_sysregs,
+ sizeof (xtensa_lookup_entry), xtensa_isa_name_compare);
+
+ /* Set up the user & system sysreg number tables. */
+ for (is_user = 0; is_user < 2; is_user++)
+ {
+ isa->sysreg_table[is_user] =
+ bfd_malloc ((isa->max_sysreg_num[is_user] + 1)
+ * sizeof (xtensa_sysreg));
+ CHECK_ALLOC_FOR_INIT (isa->sysreg_table[is_user], NULL,
+ errno_p, error_msg_p);
+
+ for (n = 0; n <= isa->max_sysreg_num[is_user]; n++)
+ isa->sysreg_table[is_user][n] = XTENSA_UNDEFINED;
+ }
+ for (n = 0; n < isa->num_sysregs; n++)
+ {
+ xtensa_sysreg_internal *sreg = &isa->sysregs[n];
+ is_user = sreg->is_user;
+
+ isa->sysreg_table[is_user][sreg->number] = n;
+ }
+
+ /* Set up the interface lookup table. */
+ isa->interface_lookup_table =
+ bfd_malloc (isa->num_interfaces * sizeof (xtensa_lookup_entry));
+ CHECK_ALLOC_FOR_INIT (isa->interface_lookup_table, NULL, errno_p,
+ error_msg_p);
+ for (n = 0; n < isa->num_interfaces; n++)
+ {
+ isa->interface_lookup_table[n].key = isa->interfaces[n].name;
+ isa->interface_lookup_table[n].u.intf = n;
+ }
+ qsort (isa->interface_lookup_table, isa->num_interfaces,
+ sizeof (xtensa_lookup_entry), xtensa_isa_name_compare);
+
+ /* Set up the funcUnit lookup table. */
+ isa->funcUnit_lookup_table =
+ bfd_malloc (isa->num_funcUnits * sizeof (xtensa_lookup_entry));
+ CHECK_ALLOC_FOR_INIT (isa->funcUnit_lookup_table, NULL, errno_p,
+ error_msg_p);
+ for (n = 0; n < isa->num_funcUnits; n++)
+ {
+ isa->funcUnit_lookup_table[n].key = isa->funcUnits[n].name;
+ isa->funcUnit_lookup_table[n].u.fun = n;
+ }
+ qsort (isa->funcUnit_lookup_table, isa->num_funcUnits,
+ sizeof (xtensa_lookup_entry), xtensa_isa_name_compare);
+
+ isa->insnbuf_size = ((isa->insn_size + sizeof (xtensa_insnbuf_word) - 1) /
+ sizeof (xtensa_insnbuf_word));
+
+ return (xtensa_isa) isa;
+}
+
+
+void
+xtensa_isa_free (xtensa_isa isa)
+{
+ xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
+ int n;
+
+ /* With this version of the code, the xtensa_isa structure is not
+ dynamically allocated, so this function is not essential. Free
+ the memory allocated by xtensa_isa_init and restore the xtensa_isa
+ structure to its initial state. */
+
+ if (intisa->opname_lookup_table)
+ {
+ free (intisa->opname_lookup_table);
+ intisa->opname_lookup_table = 0;
+ }
+
+ if (intisa->state_lookup_table)
+ {
+ free (intisa->state_lookup_table);
+ intisa->state_lookup_table = 0;
+ }
+
+ if (intisa->sysreg_lookup_table)
+ {
+ free (intisa->sysreg_lookup_table);
+ intisa->sysreg_lookup_table = 0;
+ }
+ for (n = 0; n < 2; n++)
+ {
+ if (intisa->sysreg_table[n])
+ {
+ free (intisa->sysreg_table[n]);
+ intisa->sysreg_table[n] = 0;
+ }
+ }
+
+ if (intisa->interface_lookup_table)
+ {
+ free (intisa->interface_lookup_table);
+ intisa->interface_lookup_table = 0;
+ }
+
+ if (intisa->funcUnit_lookup_table)
+ {
+ free (intisa->funcUnit_lookup_table);
+ intisa->funcUnit_lookup_table = 0;
+ }
+}
+
+
+int
+xtensa_isa_name_compare (const void *v1, const void *v2)
+{
+ xtensa_lookup_entry *e1 = (xtensa_lookup_entry *) v1;
+ xtensa_lookup_entry *e2 = (xtensa_lookup_entry *) v2;
+
+ return strcasecmp (e1->key, e2->key);
+}
+
+
+int
+xtensa_isa_maxlength (xtensa_isa isa)
+{
+ xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
+ return intisa->insn_size;
+}
+
+
+int
+xtensa_isa_length_from_chars (xtensa_isa isa, const unsigned char *cp)
+{
+ xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
+ return (intisa->length_decode_fn) (cp);
+}
+
+
+int
+xtensa_isa_num_pipe_stages (xtensa_isa isa)
+{
+ xtensa_opcode opcode;
+ xtensa_funcUnit_use *use;
+ int num_opcodes, num_uses;
+ int i, stage;
+ static int max_stage = XTENSA_UNDEFINED;
+
+ /* Only compute the value once. */
+ if (max_stage != XTENSA_UNDEFINED)
+ return max_stage + 1;
+
+ num_opcodes = xtensa_isa_num_opcodes (isa);
+ for (opcode = 0; opcode < num_opcodes; opcode++)
+ {
+ num_uses = xtensa_opcode_num_funcUnit_uses (isa, opcode);
+ for (i = 0; i < num_uses; i++)
+ {
+ use = xtensa_opcode_funcUnit_use (isa, opcode, i);
+ stage = use->stage;
+ if (stage > max_stage)
+ max_stage = stage;
+ }
+ }
+
+ return max_stage + 1;
+}
+
+
+int
+xtensa_isa_num_formats (xtensa_isa isa)
+{
+ xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
+ return intisa->num_formats;
+}
+
+
+int
+xtensa_isa_num_opcodes (xtensa_isa isa)
+{
+ xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
+ return intisa->num_opcodes;
+}
+
+
+int
+xtensa_isa_num_regfiles (xtensa_isa isa)
+{
+ xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
+ return intisa->num_regfiles;
+}
+
+
+int
+xtensa_isa_num_states (xtensa_isa isa)
+{
+ xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
+ return intisa->num_states;
+}
+
+
+int
+xtensa_isa_num_sysregs (xtensa_isa isa)
+{
+ xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
+ return intisa->num_sysregs;
+}
+
+
+int
+xtensa_isa_num_interfaces (xtensa_isa isa)
+{
+ xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
+ return intisa->num_interfaces;
+}
+
+
+int
+xtensa_isa_num_funcUnits (xtensa_isa isa)
+{
+ xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
+ return intisa->num_funcUnits;
+}
+
+
+
+/* Instruction formats. */
+
+
+#define CHECK_FORMAT(INTISA,FMT,ERRVAL) \
+ do { \
+ if ((FMT) < 0 || (FMT) >= (INTISA)->num_formats) \
+ { \
+ xtisa_errno = xtensa_isa_bad_format; \
+ strcpy (xtisa_error_msg, "invalid format specifier"); \
+ return (ERRVAL); \
+ } \
+ } while (0)
+
+
+#define CHECK_SLOT(INTISA,FMT,SLOT,ERRVAL) \
+ do { \
+ if ((SLOT) < 0 || (SLOT) >= (INTISA)->formats[FMT].num_slots) \
+ { \
+ xtisa_errno = xtensa_isa_bad_slot; \
+ strcpy (xtisa_error_msg, "invalid slot specifier"); \
+ return (ERRVAL); \
+ } \
+ } while (0)
+
+
+const char *
+xtensa_format_name (xtensa_isa isa, xtensa_format fmt)
+{
+ xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
+ CHECK_FORMAT (intisa, fmt, NULL);
+ return intisa->formats[fmt].name;
+}
+
+
+xtensa_format
+xtensa_format_lookup (xtensa_isa isa, const char *fmtname)
+{
+ xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
+ int fmt;
+
+ if (!fmtname || !*fmtname)
+ {
+ xtisa_errno = xtensa_isa_bad_format;
+ strcpy (xtisa_error_msg, "invalid format name");
+ return XTENSA_UNDEFINED;
+ }
+
+ for (fmt = 0; fmt < intisa->num_formats; fmt++)
+ {
+ if (strcasecmp (fmtname, intisa->formats[fmt].name) == 0)
+ return fmt;
+ }
+
+ xtisa_errno = xtensa_isa_bad_format;
+ sprintf (xtisa_error_msg, "format \"%s\" not recognized", fmtname);
+ return XTENSA_UNDEFINED;
+}
+
+
+xtensa_format
+xtensa_format_decode (xtensa_isa isa, const xtensa_insnbuf insn)
+{
+ xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
+ xtensa_format fmt;
+
+ fmt = (intisa->format_decode_fn) (insn);
+ if (fmt != XTENSA_UNDEFINED)
+ return fmt;
+
+ xtisa_errno = xtensa_isa_bad_format;
+ strcpy (xtisa_error_msg, "cannot decode instruction format");
+ return XTENSA_UNDEFINED;
+}
+
+
+int
+xtensa_format_encode (xtensa_isa isa, xtensa_format fmt, xtensa_insnbuf insn)
+{
+ xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
+ CHECK_FORMAT (intisa, fmt, -1);
+ (*intisa->formats[fmt].encode_fn) (insn);
+ return 0;
+}
+
+
+int
+xtensa_format_length (xtensa_isa isa, xtensa_format fmt)
+{
+ xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
+ CHECK_FORMAT (intisa, fmt, XTENSA_UNDEFINED);
+ return intisa->formats[fmt].length;
+}
+
+
+int
+xtensa_format_num_slots (xtensa_isa isa, xtensa_format fmt)
+{
+ xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
+ CHECK_FORMAT (intisa, fmt, XTENSA_UNDEFINED);
+ return intisa->formats[fmt].num_slots;
+}
+
+
+xtensa_opcode
+xtensa_format_slot_nop_opcode (xtensa_isa isa, xtensa_format fmt, int slot)
+{
+ xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
+ int slot_id;
+
+ CHECK_FORMAT (intisa, fmt, XTENSA_UNDEFINED);
+ CHECK_SLOT (intisa, fmt, slot, XTENSA_UNDEFINED);
+
+ slot_id = intisa->formats[fmt].slot_id[slot];
+ return xtensa_opcode_lookup (isa, intisa->slots[slot_id].nop_name);
+}
+
+
+int
+xtensa_format_get_slot (xtensa_isa isa, xtensa_format fmt, int slot,
+ const xtensa_insnbuf insn, xtensa_insnbuf slotbuf)
+{
+ xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
+ int slot_id;
+
+ CHECK_FORMAT (intisa, fmt, -1);
+ CHECK_SLOT (intisa, fmt, slot, -1);
+
+ slot_id = intisa->formats[fmt].slot_id[slot];
+ (*intisa->slots[slot_id].get_fn) (insn, slotbuf);
+ return 0;
+}
+
+
+int
+xtensa_format_set_slot (xtensa_isa isa, xtensa_format fmt, int slot,
+ xtensa_insnbuf insn, const xtensa_insnbuf slotbuf)
+{
+ xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
+ int slot_id;
+
+ CHECK_FORMAT (intisa, fmt, -1);
+ CHECK_SLOT (intisa, fmt, slot, -1);
+
+ slot_id = intisa->formats[fmt].slot_id[slot];
+ (*intisa->slots[slot_id].set_fn) (insn, slotbuf);
+ return 0;
+}
+
+
+
+/* Opcode information. */
+
+
+#define CHECK_OPCODE(INTISA,OPC,ERRVAL) \
+ do { \
+ if ((OPC) < 0 || (OPC) >= (INTISA)->num_opcodes) \
+ { \
+ xtisa_errno = xtensa_isa_bad_opcode; \
+ strcpy (xtisa_error_msg, "invalid opcode specifier"); \
+ return (ERRVAL); \
+ } \
+ } while (0)
+
+
+xtensa_opcode
+xtensa_opcode_lookup (xtensa_isa isa, const char *opname)
+{
+ xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
+ xtensa_lookup_entry entry, *result = 0;
+
+ if (!opname || !*opname)
+ {
+ xtisa_errno = xtensa_isa_bad_opcode;
+ strcpy (xtisa_error_msg, "invalid opcode name");
+ return XTENSA_UNDEFINED;
+ }
+
+ if (intisa->num_opcodes != 0)
+ {
+ entry.key = opname;
+ result = bsearch (&entry, intisa->opname_lookup_table,
+ intisa->num_opcodes, sizeof (xtensa_lookup_entry),
+ xtensa_isa_name_compare);
+ }
+
+ if (!result)
+ {
+ xtisa_errno = xtensa_isa_bad_opcode;
+ sprintf (xtisa_error_msg, "opcode \"%s\" not recognized", opname);
+ return XTENSA_UNDEFINED;
+ }
+
+ return result->u.opcode;
+}
+
+
+xtensa_opcode
+xtensa_opcode_decode (xtensa_isa isa, xtensa_format fmt, int slot,
+ const xtensa_insnbuf slotbuf)
+{
+ xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
+ int slot_id;
+ xtensa_opcode opc;
+
+ CHECK_FORMAT (intisa, fmt, XTENSA_UNDEFINED);
+ CHECK_SLOT (intisa, fmt, slot, XTENSA_UNDEFINED);
+
+ slot_id = intisa->formats[fmt].slot_id[slot];
+
+ opc = (intisa->slots[slot_id].opcode_decode_fn) (slotbuf);
+ if (opc != XTENSA_UNDEFINED)
+ return opc;
+
+ xtisa_errno = xtensa_isa_bad_opcode;
+ strcpy (xtisa_error_msg, "cannot decode opcode");
+ return XTENSA_UNDEFINED;
+}
+
+
+int
+xtensa_opcode_encode (xtensa_isa isa, xtensa_format fmt, int slot,
+ xtensa_insnbuf slotbuf, xtensa_opcode opc)
+{
+ xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
+ int slot_id;
+ xtensa_opcode_encode_fn encode_fn;
+
+ CHECK_FORMAT (intisa, fmt, -1);
+ CHECK_SLOT (intisa, fmt, slot, -1);
+ CHECK_OPCODE (intisa, opc, -1);
+
+ slot_id = intisa->formats[fmt].slot_id[slot];
+ encode_fn = intisa->opcodes[opc].encode_fns[slot_id];
+ if (!encode_fn)
+ {
+ xtisa_errno = xtensa_isa_wrong_slot;
+ sprintf (xtisa_error_msg,
+ "opcode \"%s\" is not allowed in slot %d of format \"%s\"",
+ intisa->opcodes[opc].name, slot, intisa->formats[fmt].name);
+ return -1;
+ }
+ (*encode_fn) (slotbuf);
+ return 0;
+}
+
+
+const char *
+xtensa_opcode_name (xtensa_isa isa, xtensa_opcode opc)
+{
+ xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
+ CHECK_OPCODE (intisa, opc, NULL);
+ return intisa->opcodes[opc].name;
+}
+
+
+int
+xtensa_opcode_is_branch (xtensa_isa isa, xtensa_opcode opc)
+{
+ xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
+ CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
+ if ((intisa->opcodes[opc].flags & XTENSA_OPCODE_IS_BRANCH) != 0)
+ return 1;
+ return 0;
+}
+
+
+int
+xtensa_opcode_is_jump (xtensa_isa isa, xtensa_opcode opc)
+{
+ xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
+ CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
+ if ((intisa->opcodes[opc].flags & XTENSA_OPCODE_IS_JUMP) != 0)
+ return 1;
+ return 0;
+}
+
+
+int
+xtensa_opcode_is_loop (xtensa_isa isa, xtensa_opcode opc)
+{
+ xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
+ CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
+ if ((intisa->opcodes[opc].flags & XTENSA_OPCODE_IS_LOOP) != 0)
+ return 1;
+ return 0;
+}
+
+
+int
+xtensa_opcode_is_call (xtensa_isa isa, xtensa_opcode opc)
+{
+ xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
+ CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
+ if ((intisa->opcodes[opc].flags & XTENSA_OPCODE_IS_CALL) != 0)
+ return 1;
+ return 0;
+}
+
+
+int
+xtensa_opcode_num_operands (xtensa_isa isa, xtensa_opcode opc)
+{
+ xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
+ int iclass_id;
+
+ CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
+ iclass_id = intisa->opcodes[opc].iclass_id;
+ return intisa->iclasses[iclass_id].num_operands;
+}
+
+
+int
+xtensa_opcode_num_stateOperands (xtensa_isa isa, xtensa_opcode opc)
+{
+ xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
+ int iclass_id;
+
+ CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
+ iclass_id = intisa->opcodes[opc].iclass_id;
+ return intisa->iclasses[iclass_id].num_stateOperands;
+}
+
+
+int
+xtensa_opcode_num_interfaceOperands (xtensa_isa isa, xtensa_opcode opc)
+{
+ xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
+ int iclass_id;
+
+ CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
+ iclass_id = intisa->opcodes[opc].iclass_id;
+ return intisa->iclasses[iclass_id].num_interfaceOperands;
+}
+
+
+int
+xtensa_opcode_num_funcUnit_uses (xtensa_isa isa, xtensa_opcode opc)
+{
+ xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
+ CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
+ return intisa->opcodes[opc].num_funcUnit_uses;
+}
+
+
+xtensa_funcUnit_use *
+xtensa_opcode_funcUnit_use (xtensa_isa isa, xtensa_opcode opc, int u)
+{
+ xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
+ CHECK_OPCODE (intisa, opc, NULL);
+ if (u < 0 || u >= intisa->opcodes[opc].num_funcUnit_uses)
+ {
+ xtisa_errno = xtensa_isa_bad_funcUnit;
+ sprintf (xtisa_error_msg, "invalid functional unit use number (%d); "
+ "opcode \"%s\" has %d", u, intisa->opcodes[opc].name,
+ intisa->opcodes[opc].num_funcUnit_uses);
+ return NULL;
+ }
+ return &intisa->opcodes[opc].funcUnit_uses[u];
+}
+
+
+
+/* Operand information. */
+
+
+#define CHECK_OPERAND(INTISA,OPC,ICLASS,OPND,ERRVAL) \
+ do { \
+ if ((OPND) < 0 || (OPND) >= (ICLASS)->num_operands) \
+ { \
+ xtisa_errno = xtensa_isa_bad_operand; \
+ sprintf (xtisa_error_msg, "invalid operand number (%d); " \
+ "opcode \"%s\" has %d operands", (OPND), \
+ (INTISA)->opcodes[(OPC)].name, (ICLASS)->num_operands); \
+ return (ERRVAL); \
+ } \
+ } while (0)
+
+
+static xtensa_operand_internal *
+get_operand (xtensa_isa_internal *intisa, xtensa_opcode opc, int opnd)
+{
+ xtensa_iclass_internal *iclass;
+ int iclass_id, operand_id;
+
+ CHECK_OPCODE (intisa, opc, NULL);
+ iclass_id = intisa->opcodes[opc].iclass_id;
+ iclass = &intisa->iclasses[iclass_id];
+ CHECK_OPERAND (intisa, opc, iclass, opnd, NULL);
+ operand_id = iclass->operands[opnd].u.operand_id;
+ return &intisa->operands[operand_id];
+}
+
+
+const char *
+xtensa_operand_name (xtensa_isa isa, xtensa_opcode opc, int opnd)
+{
+ xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
+ xtensa_operand_internal *intop;
+
+ intop = get_operand (intisa, opc, opnd);
+ if (!intop) return NULL;
+ return intop->name;
+}
+
+
+int
+xtensa_operand_is_visible (xtensa_isa isa, xtensa_opcode opc, int opnd)
+{
+ xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
+ xtensa_iclass_internal *iclass;
+ int iclass_id, operand_id;
+ xtensa_operand_internal *intop;
+
+ CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
+ iclass_id = intisa->opcodes[opc].iclass_id;
+ iclass = &intisa->iclasses[iclass_id];
+ CHECK_OPERAND (intisa, opc, iclass, opnd, XTENSA_UNDEFINED);
+
+ /* Special case for "sout" operands. */
+ if (iclass->operands[opnd].inout == 's')
+ return 0;
+
+ operand_id = iclass->operands[opnd].u.operand_id;
+ intop = &intisa->operands[operand_id];
+
+ if ((intop->flags & XTENSA_OPERAND_IS_INVISIBLE) == 0)
+ return 1;
+ return 0;
+}
+
+
+char
+xtensa_operand_inout (xtensa_isa isa, xtensa_opcode opc, int opnd)
+{
+ xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
+ xtensa_iclass_internal *iclass;
+ int iclass_id;
+ char inout;
+
+ CHECK_OPCODE (intisa, opc, 0);
+ iclass_id = intisa->opcodes[opc].iclass_id;
+ iclass = &intisa->iclasses[iclass_id];
+ CHECK_OPERAND (intisa, opc, iclass, opnd, 0);
+ inout = iclass->operands[opnd].inout;
+
+ /* Special case for "sout" operands. */
+ if (inout == 's')
+ return 'o';
+
+ return inout;
+}
+
+
+int
+xtensa_operand_get_field (xtensa_isa isa, xtensa_opcode opc, int opnd,
+ xtensa_format fmt, int slot,
+ const xtensa_insnbuf slotbuf, uint32 *valp)
+{
+ xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
+ xtensa_operand_internal *intop;
+ int slot_id;
+ xtensa_get_field_fn get_fn;
+
+ intop = get_operand (intisa, opc, opnd);
+ if (!intop) return -1;
+
+ CHECK_FORMAT (intisa, fmt, -1);
+ CHECK_SLOT (intisa, fmt, slot, -1);
+
+ slot_id = intisa->formats[fmt].slot_id[slot];
+ if (intop->field_id == XTENSA_UNDEFINED)
+ {
+ xtisa_errno = xtensa_isa_no_field;
+ strcpy (xtisa_error_msg, "implicit operand has no field");
+ return -1;
+ }
+ get_fn = intisa->slots[slot_id].get_field_fns[intop->field_id];
+ if (!get_fn)
+ {
+ xtisa_errno = xtensa_isa_wrong_slot;
+ sprintf (xtisa_error_msg,
+ "operand \"%s\" does not exist in slot %d of format \"%s\"",
+ intop->name, slot, intisa->formats[fmt].name);
+ return -1;
+ }
+ *valp = (*get_fn) (slotbuf);
+ return 0;
+}
+
+
+int
+xtensa_operand_set_field (xtensa_isa isa, xtensa_opcode opc, int opnd,
+ xtensa_format fmt, int slot,
+ xtensa_insnbuf slotbuf, uint32 val)
+{
+ xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
+ xtensa_operand_internal *intop;
+ int slot_id;
+ xtensa_set_field_fn set_fn;
+
+ intop = get_operand (intisa, opc, opnd);
+ if (!intop) return -1;
+
+ CHECK_FORMAT (intisa, fmt, -1);
+ CHECK_SLOT (intisa, fmt, slot, -1);
+
+ slot_id = intisa->formats[fmt].slot_id[slot];
+ if (intop->field_id == XTENSA_UNDEFINED)
+ {
+ xtisa_errno = xtensa_isa_no_field;
+ strcpy (xtisa_error_msg, "implicit operand has no field");
+ return -1;
+ }
+ set_fn = intisa->slots[slot_id].set_field_fns[intop->field_id];
+ if (!set_fn)
+ {
+ xtisa_errno = xtensa_isa_wrong_slot;
+ sprintf (xtisa_error_msg,
+ "operand \"%s\" does not exist in slot %d of format \"%s\"",
+ intop->name, slot, intisa->formats[fmt].name);
+ return -1;
+ }
+ (*set_fn) (slotbuf, val);
+ return 0;
+}
+
+
+int
+xtensa_operand_encode (xtensa_isa isa, xtensa_opcode opc, int opnd,
+ uint32 *valp)
+{
+ xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
+ xtensa_operand_internal *intop;
+ uint32 test_val, orig_val;
+
+ intop = get_operand (intisa, opc, opnd);
+ if (!intop)
+ return -1;
+
+ if (!intop->encode)
+ {
+ /* This is a default operand for a field. How can we tell if the
+ value fits in the field? Write the value into the field,
+ read it back, and then make sure we get the same value. */
+ static xtensa_insnbuf tmpbuf = 0;
+ int slot_id;
+
+ if (!tmpbuf)
+ {
+ tmpbuf = xtensa_insnbuf_alloc (isa);
+ CHECK_ALLOC (tmpbuf, -1);
+ }
+
+ /* A default operand is always associated with a field,
+ but check just to be sure.... */
+ if (intop->field_id == XTENSA_UNDEFINED)
+ {
+ xtisa_errno = xtensa_isa_internal_error;
+ strcpy (xtisa_error_msg, "operand has no field");
+ return -1;
+ }
+
+ /* Find some slot that includes the field. */
+ for (slot_id = 0; slot_id < intisa->num_slots; slot_id++)
+ {
+ xtensa_get_field_fn get_fn =
+ intisa->slots[slot_id].get_field_fns[intop->field_id];
+ xtensa_set_field_fn set_fn =
+ intisa->slots[slot_id].set_field_fns[intop->field_id];
+
+ if (get_fn && set_fn)
+ {
+ (*set_fn) (tmpbuf, *valp);
+ return ((*get_fn) (tmpbuf) != *valp);
+ }
+ }
+
+ /* Couldn't find any slot containing the field.... */
+ xtisa_errno = xtensa_isa_no_field;
+ strcpy (xtisa_error_msg, "field does not exist in any slot");
+ return -1;
+ }
+
+ /* Encode the value. In some cases, the encoding function may detect
+ errors, but most of the time the only way to determine if the value
+ was successfully encoded is to decode it and check if it matches
+ the original value. */
+ orig_val = *valp;
+ if ((*intop->encode) (valp)
+ || (test_val = *valp, (*intop->decode) (&test_val))
+ || test_val != orig_val)
+ {
+ xtisa_errno = xtensa_isa_bad_value;
+ sprintf (xtisa_error_msg, "cannot encode operand value 0x%08x", *valp);
+ return -1;
+ }
+
+ return 0;
+}
+
+
+int
+xtensa_operand_decode (xtensa_isa isa, xtensa_opcode opc, int opnd,
+ uint32 *valp)
+{
+ xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
+ xtensa_operand_internal *intop;
+
+ intop = get_operand (intisa, opc, opnd);
+ if (!intop) return -1;
+
+ /* Use identity function for "default" operands. */
+ if (!intop->decode)
+ return 0;
+
+ if ((*intop->decode) (valp))
+ {
+ xtisa_errno = xtensa_isa_bad_value;
+ sprintf (xtisa_error_msg, "cannot decode operand value 0x%08x", *valp);
+ return -1;
+ }
+ return 0;
+}
+
+
+int
+xtensa_operand_is_register (xtensa_isa isa, xtensa_opcode opc, int opnd)
+{
+ xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
+ xtensa_operand_internal *intop;
+
+ intop = get_operand (intisa, opc, opnd);
+ if (!intop) return XTENSA_UNDEFINED;
+
+ if ((intop->flags & XTENSA_OPERAND_IS_REGISTER) != 0)
+ return 1;
+ return 0;
+}
+
+
+xtensa_regfile
+xtensa_operand_regfile (xtensa_isa isa, xtensa_opcode opc, int opnd)
+{
+ xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
+ xtensa_operand_internal *intop;
+
+ intop = get_operand (intisa, opc, opnd);
+ if (!intop) return XTENSA_UNDEFINED;
+
+ return intop->regfile;
+}
+
+
+int
+xtensa_operand_num_regs (xtensa_isa isa, xtensa_opcode opc, int opnd)
+{
+ xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
+ xtensa_operand_internal *intop;
+
+ intop = get_operand (intisa, opc, opnd);
+ if (!intop) return XTENSA_UNDEFINED;
+
+ return intop->num_regs;
+}
+
+
+int
+xtensa_operand_is_known_reg (xtensa_isa isa, xtensa_opcode opc, int opnd)
+{
+ xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
+ xtensa_operand_internal *intop;
+
+ intop = get_operand (intisa, opc, opnd);
+ if (!intop) return XTENSA_UNDEFINED;
+
+ if ((intop->flags & XTENSA_OPERAND_IS_UNKNOWN) == 0)
+ return 1;
+ return 0;
+}
+
+
+int
+xtensa_operand_is_PCrelative (xtensa_isa isa, xtensa_opcode opc, int opnd)
+{
+ xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
+ xtensa_operand_internal *intop;
+
+ intop = get_operand (intisa, opc, opnd);
+ if (!intop) return XTENSA_UNDEFINED;
+
+ if ((intop->flags & XTENSA_OPERAND_IS_PCRELATIVE) != 0)
+ return 1;
+ return 0;
+}
+
+
+int
+xtensa_operand_do_reloc (xtensa_isa isa, xtensa_opcode opc, int opnd,
+ uint32 *valp, uint32 pc)
+{
+ xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
+ xtensa_operand_internal *intop;
+
+ intop = get_operand (intisa, opc, opnd);
+ if (!intop) return -1;
+
+ if ((intop->flags & XTENSA_OPERAND_IS_PCRELATIVE) == 0)
+ return 0;
+
+ if (!intop->do_reloc)
+ {
+ xtisa_errno = xtensa_isa_internal_error;
+ strcpy (xtisa_error_msg, "operand missing do_reloc function");
+ return -1;
+ }
+
+ if ((*intop->do_reloc) (valp, pc))
+ {
+ xtisa_errno = xtensa_isa_bad_value;
+ sprintf (xtisa_error_msg,
+ "do_reloc failed for value 0x%08x at PC 0x%08x", *valp, pc);
+ return -1;
+ }
+
+ return 0;
+}
+
+
+int
+xtensa_operand_undo_reloc (xtensa_isa isa, xtensa_opcode opc, int opnd,
+ uint32 *valp, uint32 pc)
+{
+ xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
+ xtensa_operand_internal *intop;
+
+ intop = get_operand (intisa, opc, opnd);
+ if (!intop) return -1;
+
+ if ((intop->flags & XTENSA_OPERAND_IS_PCRELATIVE) == 0)
+ return 0;
+
+ if (!intop->undo_reloc)
+ {
+ xtisa_errno = xtensa_isa_internal_error;
+ strcpy (xtisa_error_msg, "operand missing undo_reloc function");
+ return -1;
+ }
+
+ if ((*intop->undo_reloc) (valp, pc))
+ {
+ xtisa_errno = xtensa_isa_bad_value;
+ sprintf (xtisa_error_msg,
+ "undo_reloc failed for value 0x%08x at PC 0x%08x", *valp, pc);
+ return -1;
+ }
+
+ return 0;
+}
+
+
+
+/* State Operands. */
+
+
+#define CHECK_STATE_OPERAND(INTISA,OPC,ICLASS,STOP,ERRVAL) \
+ do { \
+ if ((STOP) < 0 || (STOP) >= (ICLASS)->num_stateOperands) \
+ { \
+ xtisa_errno = xtensa_isa_bad_operand; \
+ sprintf (xtisa_error_msg, "invalid state operand number (%d); " \
+ "opcode \"%s\" has %d state operands", (STOP), \
+ (INTISA)->opcodes[(OPC)].name, (ICLASS)->num_stateOperands); \
+ return (ERRVAL); \
+ } \
+ } while (0)
+
+
+xtensa_state
+xtensa_stateOperand_state (xtensa_isa isa, xtensa_opcode opc, int stOp)
+{
+ xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
+ xtensa_iclass_internal *iclass;
+ int iclass_id;
+
+ CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
+ iclass_id = intisa->opcodes[opc].iclass_id;
+ iclass = &intisa->iclasses[iclass_id];
+ CHECK_STATE_OPERAND (intisa, opc, iclass, stOp, XTENSA_UNDEFINED);
+ return iclass->stateOperands[stOp].u.state;
+}
+
+
+char
+xtensa_stateOperand_inout (xtensa_isa isa, xtensa_opcode opc, int stOp)
+{
+ xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
+ xtensa_iclass_internal *iclass;
+ int iclass_id;
+
+ CHECK_OPCODE (intisa, opc, 0);
+ iclass_id = intisa->opcodes[opc].iclass_id;
+ iclass = &intisa->iclasses[iclass_id];
+ CHECK_STATE_OPERAND (intisa, opc, iclass, stOp, 0);
+ return iclass->stateOperands[stOp].inout;
+}
+
+
+
+/* Interface Operands. */
+
+
+#define CHECK_INTERFACE_OPERAND(INTISA,OPC,ICLASS,IFOP,ERRVAL) \
+ do { \
+ if ((IFOP) < 0 || (IFOP) >= (ICLASS)->num_interfaceOperands) \
+ { \
+ xtisa_errno = xtensa_isa_bad_operand; \
+ sprintf (xtisa_error_msg, "invalid interface operand number (%d); " \
+ "opcode \"%s\" has %d interface operands", (IFOP), \
+ (INTISA)->opcodes[(OPC)].name, \
+ (ICLASS)->num_interfaceOperands); \
+ return (ERRVAL); \
+ } \
+ } while (0)
+
+
+xtensa_interface
+xtensa_interfaceOperand_interface (xtensa_isa isa, xtensa_opcode opc,
+ int ifOp)
+{
+ xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
+ xtensa_iclass_internal *iclass;
+ int iclass_id;
+
+ CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
+ iclass_id = intisa->opcodes[opc].iclass_id;
+ iclass = &intisa->iclasses[iclass_id];
+ CHECK_INTERFACE_OPERAND (intisa, opc, iclass, ifOp, XTENSA_UNDEFINED);
+ return iclass->interfaceOperands[ifOp];
+}
+
+
+
+/* Register Files. */
+
+
+#define CHECK_REGFILE(INTISA,RF,ERRVAL) \
+ do { \
+ if ((RF) < 0 || (RF) >= (INTISA)->num_regfiles) \
+ { \
+ xtisa_errno = xtensa_isa_bad_regfile; \
+ strcpy (xtisa_error_msg, "invalid regfile specifier"); \
+ return (ERRVAL); \
+ } \
+ } while (0)
+
+
+xtensa_regfile
+xtensa_regfile_lookup (xtensa_isa isa, const char *name)
+{
+ xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
+ int n;
+
+ if (!name || !*name)
+ {
+ xtisa_errno = xtensa_isa_bad_regfile;
+ strcpy (xtisa_error_msg, "invalid regfile name");
+ return XTENSA_UNDEFINED;
+ }
+
+ /* The expected number of regfiles is small; use a linear search. */
+ for (n = 0; n < intisa->num_regfiles; n++)
+ {
+ if (!filename_cmp (intisa->regfiles[n].name, name))
+ return n;
+ }
+
+ xtisa_errno = xtensa_isa_bad_regfile;
+ sprintf (xtisa_error_msg, "regfile \"%s\" not recognized", name);
+ return XTENSA_UNDEFINED;
+}
+
+
+xtensa_regfile
+xtensa_regfile_lookup_shortname (xtensa_isa isa, const char *shortname)
+{
+ xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
+ int n;
+
+ if (!shortname || !*shortname)
+ {
+ xtisa_errno = xtensa_isa_bad_regfile;
+ strcpy (xtisa_error_msg, "invalid regfile shortname");
+ return XTENSA_UNDEFINED;
+ }
+
+ /* The expected number of regfiles is small; use a linear search. */
+ for (n = 0; n < intisa->num_regfiles; n++)
+ {
+ /* Ignore regfile views since they always have the same shortnames
+ as their parents. */
+ if (intisa->regfiles[n].parent != n)
+ continue;
+ if (!filename_cmp (intisa->regfiles[n].shortname, shortname))
+ return n;
+ }
+
+ xtisa_errno = xtensa_isa_bad_regfile;
+ sprintf (xtisa_error_msg, "regfile shortname \"%s\" not recognized",
+ shortname);
+ return XTENSA_UNDEFINED;
+}
+
+
+const char *
+xtensa_regfile_name (xtensa_isa isa, xtensa_regfile rf)
+{
+ xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
+ CHECK_REGFILE (intisa, rf, NULL);
+ return intisa->regfiles[rf].name;
+}
+
+
+const char *
+xtensa_regfile_shortname (xtensa_isa isa, xtensa_regfile rf)
+{
+ xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
+ CHECK_REGFILE (intisa, rf, NULL);
+ return intisa->regfiles[rf].shortname;
+}
+
+
+xtensa_regfile
+xtensa_regfile_view_parent (xtensa_isa isa, xtensa_regfile rf)
+{
+ xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
+ CHECK_REGFILE (intisa, rf, XTENSA_UNDEFINED);
+ return intisa->regfiles[rf].parent;
+}
+
+
+int
+xtensa_regfile_num_bits (xtensa_isa isa, xtensa_regfile rf)
+{
+ xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
+ CHECK_REGFILE (intisa, rf, XTENSA_UNDEFINED);
+ return intisa->regfiles[rf].num_bits;
+}
+
+
+int
+xtensa_regfile_num_entries (xtensa_isa isa, xtensa_regfile rf)
+{
+ xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
+ CHECK_REGFILE (intisa, rf, XTENSA_UNDEFINED);
+ return intisa->regfiles[rf].num_entries;
+}
+
+
+
+/* Processor States. */
+
+
+#define CHECK_STATE(INTISA,ST,ERRVAL) \
+ do { \
+ if ((ST) < 0 || (ST) >= (INTISA)->num_states) \
+ { \
+ xtisa_errno = xtensa_isa_bad_state; \
+ strcpy (xtisa_error_msg, "invalid state specifier"); \
+ return (ERRVAL); \
+ } \
+ } while (0)
+
+
+xtensa_state
+xtensa_state_lookup (xtensa_isa isa, const char *name)
+{
+ xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
+ xtensa_lookup_entry entry, *result = 0;
+
+ if (!name || !*name)
+ {
+ xtisa_errno = xtensa_isa_bad_state;
+ strcpy (xtisa_error_msg, "invalid state name");
+ return XTENSA_UNDEFINED;
+ }
+
+ if (intisa->num_states != 0)
+ {
+ entry.key = name;
+ result = bsearch (&entry, intisa->state_lookup_table, intisa->num_states,
+ sizeof (xtensa_lookup_entry), xtensa_isa_name_compare);
+ }
+
+ if (!result)
+ {
+ xtisa_errno = xtensa_isa_bad_state;
+ sprintf (xtisa_error_msg, "state \"%s\" not recognized", name);
+ return XTENSA_UNDEFINED;
+ }
+
+ return result->u.state;
+}
+
+
+const char *
+xtensa_state_name (xtensa_isa isa, xtensa_state st)
+{
+ xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
+ CHECK_STATE (intisa, st, NULL);
+ return intisa->states[st].name;
+}
+
+
+int
+xtensa_state_num_bits (xtensa_isa isa, xtensa_state st)
+{
+ xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
+ CHECK_STATE (intisa, st, XTENSA_UNDEFINED);
+ return intisa->states[st].num_bits;
+}
+
+
+int
+xtensa_state_is_exported (xtensa_isa isa, xtensa_state st)
+{
+ xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
+ CHECK_STATE (intisa, st, XTENSA_UNDEFINED);
+ if ((intisa->states[st].flags & XTENSA_STATE_IS_EXPORTED) != 0)
+ return 1;
+ return 0;
+}
+
+
+int
+xtensa_state_is_shared_or (xtensa_isa isa, xtensa_state st)
+{
+ xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
+ CHECK_STATE (intisa, st, XTENSA_UNDEFINED);
+ if ((intisa->states[st].flags & XTENSA_STATE_IS_SHARED_OR) != 0)
+ return 1;
+ return 0;
+}
+
+
+
+/* Sysregs. */
+
+
+#define CHECK_SYSREG(INTISA,SYSREG,ERRVAL) \
+ do { \
+ if ((SYSREG) < 0 || (SYSREG) >= (INTISA)->num_sysregs) \
+ { \
+ xtisa_errno = xtensa_isa_bad_sysreg; \
+ strcpy (xtisa_error_msg, "invalid sysreg specifier"); \
+ return (ERRVAL); \
+ } \
+ } while (0)
+
+
+xtensa_sysreg
+xtensa_sysreg_lookup (xtensa_isa isa, int num, int is_user)
+{
+ xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
+
+ if (is_user != 0)
+ is_user = 1;
+
+ if (num < 0 || num > intisa->max_sysreg_num[is_user]
+ || intisa->sysreg_table[is_user][num] == XTENSA_UNDEFINED)
+ {
+ xtisa_errno = xtensa_isa_bad_sysreg;
+ strcpy (xtisa_error_msg, "sysreg not recognized");
+ return XTENSA_UNDEFINED;
+ }
+
+ return intisa->sysreg_table[is_user][num];
+}
+
+
+xtensa_sysreg
+xtensa_sysreg_lookup_name (xtensa_isa isa, const char *name)
+{
+ xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
+ xtensa_lookup_entry entry, *result = 0;
+
+ if (!name || !*name)
+ {
+ xtisa_errno = xtensa_isa_bad_sysreg;
+ strcpy (xtisa_error_msg, "invalid sysreg name");
+ return XTENSA_UNDEFINED;
+ }
+
+ if (intisa->num_sysregs != 0)
+ {
+ entry.key = name;
+ result = bsearch (&entry, intisa->sysreg_lookup_table,
+ intisa->num_sysregs, sizeof (xtensa_lookup_entry),
+ xtensa_isa_name_compare);
+ }
+
+ if (!result)
+ {
+ xtisa_errno = xtensa_isa_bad_sysreg;
+ sprintf (xtisa_error_msg, "sysreg \"%s\" not recognized", name);
+ return XTENSA_UNDEFINED;
+ }
+
+ return result->u.sysreg;
+}
+
+
+const char *
+xtensa_sysreg_name (xtensa_isa isa, xtensa_sysreg sysreg)
+{
+ xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
+ CHECK_SYSREG (intisa, sysreg, NULL);
+ return intisa->sysregs[sysreg].name;
+}
+
+
+int
+xtensa_sysreg_number (xtensa_isa isa, xtensa_sysreg sysreg)
+{
+ xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
+ CHECK_SYSREG (intisa, sysreg, XTENSA_UNDEFINED);
+ return intisa->sysregs[sysreg].number;
+}
+
+
+int
+xtensa_sysreg_is_user (xtensa_isa isa, xtensa_sysreg sysreg)
+{
+ xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
+ CHECK_SYSREG (intisa, sysreg, XTENSA_UNDEFINED);
+ if (intisa->sysregs[sysreg].is_user)
+ return 1;
+ return 0;
+}
+
+
+
+/* Interfaces. */
+
+
+#define CHECK_INTERFACE(INTISA,INTF,ERRVAL) \
+ do { \
+ if ((INTF) < 0 || (INTF) >= (INTISA)->num_interfaces) \
+ { \
+ xtisa_errno = xtensa_isa_bad_interface; \
+ strcpy (xtisa_error_msg, "invalid interface specifier"); \
+ return (ERRVAL); \
+ } \
+ } while (0)
+
+
+xtensa_interface
+xtensa_interface_lookup (xtensa_isa isa, const char *ifname)
+{
+ xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
+ xtensa_lookup_entry entry, *result = 0;
+
+ if (!ifname || !*ifname)
+ {
+ xtisa_errno = xtensa_isa_bad_interface;
+ strcpy (xtisa_error_msg, "invalid interface name");
+ return XTENSA_UNDEFINED;
+ }
+
+ if (intisa->num_interfaces != 0)
+ {
+ entry.key = ifname;
+ result = bsearch (&entry, intisa->interface_lookup_table,
+ intisa->num_interfaces, sizeof (xtensa_lookup_entry),
+ xtensa_isa_name_compare);
+ }
+
+ if (!result)
+ {
+ xtisa_errno = xtensa_isa_bad_interface;
+ sprintf (xtisa_error_msg, "interface \"%s\" not recognized", ifname);
+ return XTENSA_UNDEFINED;
+ }
+
+ return result->u.intf;
+}
+
+
+const char *
+xtensa_interface_name (xtensa_isa isa, xtensa_interface intf)
+{
+ xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
+ CHECK_INTERFACE (intisa, intf, NULL);
+ return intisa->interfaces[intf].name;
+}
+
+
+int
+xtensa_interface_num_bits (xtensa_isa isa, xtensa_interface intf)
+{
+ xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
+ CHECK_INTERFACE (intisa, intf, XTENSA_UNDEFINED);
+ return intisa->interfaces[intf].num_bits;
+}
+
+
+char
+xtensa_interface_inout (xtensa_isa isa, xtensa_interface intf)
+{
+ xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
+ CHECK_INTERFACE (intisa, intf, 0);
+ return intisa->interfaces[intf].inout;
+}
+
+
+int
+xtensa_interface_has_side_effect (xtensa_isa isa, xtensa_interface intf)
+{
+ xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
+ CHECK_INTERFACE (intisa, intf, XTENSA_UNDEFINED);
+ if ((intisa->interfaces[intf].flags & XTENSA_INTERFACE_HAS_SIDE_EFFECT) != 0)
+ return 1;
+ return 0;
+}
+
+
+int
+xtensa_interface_class_id (xtensa_isa isa, xtensa_interface intf)
+{
+ xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
+ CHECK_INTERFACE (intisa, intf, XTENSA_UNDEFINED);
+ return intisa->interfaces[intf].class_id;
+}
+
+
+
+/* Functional Units. */
+
+
+#define CHECK_FUNCUNIT(INTISA,FUN,ERRVAL) \
+ do { \
+ if ((FUN) < 0 || (FUN) >= (INTISA)->num_funcUnits) \
+ { \
+ xtisa_errno = xtensa_isa_bad_funcUnit; \
+ strcpy (xtisa_error_msg, "invalid functional unit specifier"); \
+ return (ERRVAL); \
+ } \
+ } while (0)
+
+
+xtensa_funcUnit
+xtensa_funcUnit_lookup (xtensa_isa isa, const char *fname)
+{
+ xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
+ xtensa_lookup_entry entry, *result = 0;
+
+ if (!fname || !*fname)
+ {
+ xtisa_errno = xtensa_isa_bad_funcUnit;
+ strcpy (xtisa_error_msg, "invalid functional unit name");
+ return XTENSA_UNDEFINED;
+ }
+
+ if (intisa->num_funcUnits != 0)
+ {
+ entry.key = fname;
+ result = bsearch (&entry, intisa->funcUnit_lookup_table,
+ intisa->num_funcUnits, sizeof (xtensa_lookup_entry),
+ xtensa_isa_name_compare);
+ }
+
+ if (!result)
+ {
+ xtisa_errno = xtensa_isa_bad_funcUnit;
+ sprintf (xtisa_error_msg,
+ "functional unit \"%s\" not recognized", fname);
+ return XTENSA_UNDEFINED;
+ }
+
+ return result->u.fun;
+}
+
+
+const char *
+xtensa_funcUnit_name (xtensa_isa isa, xtensa_funcUnit fun)
+{
+ xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
+ CHECK_FUNCUNIT (intisa, fun, NULL);
+ return intisa->funcUnits[fun].name;
+}
+
+
+int
+xtensa_funcUnit_num_copies (xtensa_isa isa, xtensa_funcUnit fun)
+{
+ xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
+ CHECK_FUNCUNIT (intisa, fun, XTENSA_UNDEFINED);
+ return intisa->funcUnits[fun].num_copies;
+}
+
diff --git a/bfd/xtensa-modules.c b/bfd/xtensa-modules.c
new file mode 100644
index 0000000..408e3d2
--- /dev/null
+++ b/bfd/xtensa-modules.c
@@ -0,0 +1,21292 @@
+/* Xtensa configuration-specific ISA information.
+ Copyright (C) 2003-2014 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., 51 Franklin Street - Fifth Floor, Boston, MA
+ 02110-1301, USA. */
+
+#include "ansidecl.h"
+#include <xtensa-isa.h>
+#include "xtensa-isa-internal.h"
+
+
+/* Sysregs. */
+
+static xtensa_sysreg_internal sysregs[] = {
+ { "LBEG", 0, 0 },
+ { "LEND", 1, 0 },
+ { "LCOUNT", 2, 0 },
+ { "BR", 4, 0 },
+ { "ACCLO", 16, 0 },
+ { "ACCHI", 17, 0 },
+ { "M0", 32, 0 },
+ { "M1", 33, 0 },
+ { "M2", 34, 0 },
+ { "M3", 35, 0 },
+ { "PTEVADDR", 83, 0 },
+ { "MMID", 89, 0 },
+ { "DDR", 104, 0 },
+ { "176", 176, 0 },
+ { "208", 208, 0 },
+ { "INTERRUPT", 226, 0 },
+ { "INTCLEAR", 227, 0 },
+ { "CCOUNT", 234, 0 },
+ { "PRID", 235, 0 },
+ { "ICOUNT", 236, 0 },
+ { "CCOMPARE0", 240, 0 },
+ { "CCOMPARE1", 241, 0 },
+ { "CCOMPARE2", 242, 0 },
+ { "VECBASE", 231, 0 },
+ { "EPC1", 177, 0 },
+ { "EPC2", 178, 0 },
+ { "EPC3", 179, 0 },
+ { "EPC4", 180, 0 },
+ { "EPC5", 181, 0 },
+ { "EPC6", 182, 0 },
+ { "EPC7", 183, 0 },
+ { "EXCSAVE1", 209, 0 },
+ { "EXCSAVE2", 210, 0 },
+ { "EXCSAVE3", 211, 0 },
+ { "EXCSAVE4", 212, 0 },
+ { "EXCSAVE5", 213, 0 },
+ { "EXCSAVE6", 214, 0 },
+ { "EXCSAVE7", 215, 0 },
+ { "EPS2", 194, 0 },
+ { "EPS3", 195, 0 },
+ { "EPS4", 196, 0 },
+ { "EPS5", 197, 0 },
+ { "EPS6", 198, 0 },
+ { "EPS7", 199, 0 },
+ { "EXCCAUSE", 232, 0 },
+ { "DEPC", 192, 0 },
+ { "EXCVADDR", 238, 0 },
+ { "WINDOWBASE", 72, 0 },
+ { "WINDOWSTART", 73, 0 },
+ { "SAR", 3, 0 },
+ { "LITBASE", 5, 0 },
+ { "PS", 230, 0 },
+ { "MISC0", 244, 0 },
+ { "MISC1", 245, 0 },
+ { "MISC2", 246, 0 },
+ { "MISC3", 247, 0 },
+ { "INTENABLE", 228, 0 },
+ { "DBREAKA0", 144, 0 },
+ { "DBREAKC0", 160, 0 },
+ { "DBREAKA1", 145, 0 },
+ { "DBREAKC1", 161, 0 },
+ { "IBREAKA0", 128, 0 },
+ { "IBREAKA1", 129, 0 },
+ { "IBREAKENABLE", 96, 0 },
+ { "ICOUNTLEVEL", 237, 0 },
+ { "DEBUGCAUSE", 233, 0 },
+ { "RASID", 90, 0 },
+ { "ITLBCFG", 91, 0 },
+ { "DTLBCFG", 92, 0 },
+ { "CPENABLE", 224, 0 },
+ { "SCOMPARE1", 12, 0 },
+ { "THREADPTR", 231, 1 },
+ { "FCR", 232, 1 },
+ { "FSR", 233, 1 }
+};
+
+#define NUM_SYSREGS 74
+#define MAX_SPECIAL_REG 247
+#define MAX_USER_REG 233
+
+
+/* Processor states. */
+
+static xtensa_state_internal states[] = {
+ { "LCOUNT", 32, 0 },
+ { "PC", 32, 0 },
+ { "ICOUNT", 32, 0 },
+ { "DDR", 32, 0 },
+ { "INTERRUPT", 32, 0 },
+ { "CCOUNT", 32, 0 },
+ { "XTSYNC", 1, 0 },
+ { "VECBASE", 22, 0 },
+ { "EPC1", 32, 0 },
+ { "EPC2", 32, 0 },
+ { "EPC3", 32, 0 },
+ { "EPC4", 32, 0 },
+ { "EPC5", 32, 0 },
+ { "EPC6", 32, 0 },
+ { "EPC7", 32, 0 },
+ { "EXCSAVE1", 32, 0 },
+ { "EXCSAVE2", 32, 0 },
+ { "EXCSAVE3", 32, 0 },
+ { "EXCSAVE4", 32, 0 },
+ { "EXCSAVE5", 32, 0 },
+ { "EXCSAVE6", 32, 0 },
+ { "EXCSAVE7", 32, 0 },
+ { "EPS2", 15, 0 },
+ { "EPS3", 15, 0 },
+ { "EPS4", 15, 0 },
+ { "EPS5", 15, 0 },
+ { "EPS6", 15, 0 },
+ { "EPS7", 15, 0 },
+ { "EXCCAUSE", 6, 0 },
+ { "PSINTLEVEL", 4, 0 },
+ { "PSUM", 1, 0 },
+ { "PSWOE", 1, 0 },
+ { "PSRING", 2, 0 },
+ { "PSEXCM", 1, 0 },
+ { "DEPC", 32, 0 },
+ { "EXCVADDR", 32, 0 },
+ { "WindowBase", 4, 0 },
+ { "WindowStart", 16, 0 },
+ { "PSCALLINC", 2, 0 },
+ { "PSOWB", 4, 0 },
+ { "LBEG", 32, 0 },
+ { "LEND", 32, 0 },
+ { "SAR", 6, 0 },
+ { "THREADPTR", 32, 0 },
+ { "LITBADDR", 20, 0 },
+ { "LITBEN", 1, 0 },
+ { "MISC0", 32, 0 },
+ { "MISC1", 32, 0 },
+ { "MISC2", 32, 0 },
+ { "MISC3", 32, 0 },
+ { "ACC", 40, 0 },
+ { "InOCDMode", 1, 0 },
+ { "INTENABLE", 32, 0 },
+ { "DBREAKA0", 32, 0 },
+ { "DBREAKC0", 8, 0 },
+ { "DBREAKA1", 32, 0 },
+ { "DBREAKC1", 8, 0 },
+ { "IBREAKA0", 32, 0 },
+ { "IBREAKA1", 32, 0 },
+ { "IBREAKENABLE", 2, 0 },
+ { "ICOUNTLEVEL", 4, 0 },
+ { "DEBUGCAUSE", 6, 0 },
+ { "DBNUM", 4, 0 },
+ { "CCOMPARE0", 32, 0 },
+ { "CCOMPARE1", 32, 0 },
+ { "CCOMPARE2", 32, 0 },
+ { "ASID3", 8, 0 },
+ { "ASID2", 8, 0 },
+ { "ASID1", 8, 0 },
+ { "INSTPGSZID4", 2, 0 },
+ { "DATAPGSZID4", 2, 0 },
+ { "PTBASE", 10, 0 },
+ { "CPENABLE", 1, 0 },
+ { "SCOMPARE1", 32, 0 },
+ { "RoundMode", 2, 0 },
+ { "InvalidEnable", 1, 0 },
+ { "DivZeroEnable", 1, 0 },
+ { "OverflowEnable", 1, 0 },
+ { "UnderflowEnable", 1, 0 },
+ { "InexactEnable", 1, 0 },
+ { "InvalidFlag", 1, 0 },
+ { "DivZeroFlag", 1, 0 },
+ { "OverflowFlag", 1, 0 },
+ { "UnderflowFlag", 1, 0 },
+ { "InexactFlag", 1, 0 },
+ { "FPreserved20", 20, 0 },
+ { "FPreserved20a", 20, 0 },
+ { "FPreserved5", 5, 0 },
+ { "FPreserved7", 7, 0 }
+};
+
+#define NUM_STATES 89
+
+/* Macros for xtensa_state numbers (for use in iclasses because the
+ state numbers are not available when the iclass table is generated). */
+
+#define STATE_LCOUNT 0
+#define STATE_PC 1
+#define STATE_ICOUNT 2
+#define STATE_DDR 3
+#define STATE_INTERRUPT 4
+#define STATE_CCOUNT 5
+#define STATE_XTSYNC 6
+#define STATE_VECBASE 7
+#define STATE_EPC1 8
+#define STATE_EPC2 9
+#define STATE_EPC3 10
+#define STATE_EPC4 11
+#define STATE_EPC5 12
+#define STATE_EPC6 13
+#define STATE_EPC7 14
+#define STATE_EXCSAVE1 15
+#define STATE_EXCSAVE2 16
+#define STATE_EXCSAVE3 17
+#define STATE_EXCSAVE4 18
+#define STATE_EXCSAVE5 19
+#define STATE_EXCSAVE6 20
+#define STATE_EXCSAVE7 21
+#define STATE_EPS2 22
+#define STATE_EPS3 23
+#define STATE_EPS4 24
+#define STATE_EPS5 25
+#define STATE_EPS6 26
+#define STATE_EPS7 27
+#define STATE_EXCCAUSE 28
+#define STATE_PSINTLEVEL 29
+#define STATE_PSUM 30
+#define STATE_PSWOE 31
+#define STATE_PSRING 32
+#define STATE_PSEXCM 33
+#define STATE_DEPC 34
+#define STATE_EXCVADDR 35
+#define STATE_WindowBase 36
+#define STATE_WindowStart 37
+#define STATE_PSCALLINC 38
+#define STATE_PSOWB 39
+#define STATE_LBEG 40
+#define STATE_LEND 41
+#define STATE_SAR 42
+#define STATE_THREADPTR 43
+#define STATE_LITBADDR 44
+#define STATE_LITBEN 45
+#define STATE_MISC0 46
+#define STATE_MISC1 47
+#define STATE_MISC2 48
+#define STATE_MISC3 49
+#define STATE_ACC 50
+#define STATE_InOCDMode 51
+#define STATE_INTENABLE 52
+#define STATE_DBREAKA0 53
+#define STATE_DBREAKC0 54
+#define STATE_DBREAKA1 55
+#define STATE_DBREAKC1 56
+#define STATE_IBREAKA0 57
+#define STATE_IBREAKA1 58
+#define STATE_IBREAKENABLE 59
+#define STATE_ICOUNTLEVEL 60
+#define STATE_DEBUGCAUSE 61
+#define STATE_DBNUM 62
+#define STATE_CCOMPARE0 63
+#define STATE_CCOMPARE1 64
+#define STATE_CCOMPARE2 65
+#define STATE_ASID3 66
+#define STATE_ASID2 67
+#define STATE_ASID1 68
+#define STATE_INSTPGSZID4 69
+#define STATE_DATAPGSZID4 70
+#define STATE_PTBASE 71
+#define STATE_CPENABLE 72
+#define STATE_SCOMPARE1 73
+#define STATE_RoundMode 74
+#define STATE_InvalidEnable 75
+#define STATE_DivZeroEnable 76
+#define STATE_OverflowEnable 77
+#define STATE_UnderflowEnable 78
+#define STATE_InexactEnable 79
+#define STATE_InvalidFlag 80
+#define STATE_DivZeroFlag 81
+#define STATE_OverflowFlag 82
+#define STATE_UnderflowFlag 83
+#define STATE_InexactFlag 84
+#define STATE_FPreserved20 85
+#define STATE_FPreserved20a 86
+#define STATE_FPreserved5 87
+#define STATE_FPreserved7 88
+
+
+/* Field definitions. */
+
+static unsigned
+Field_t_Slot_inst_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 4) | ((insn[0] << 24) >> 28);
+ return tie_t;
+}
+
+static void
+Field_t_Slot_inst_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 28) >> 28;
+ insn[0] = (insn[0] & ~0xf0) | (tie_t << 4);
+}
+
+static unsigned
+Field_t_Slot_inst16a_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 4) | ((insn[0] << 24) >> 28);
+ return tie_t;
+}
+
+static void
+Field_t_Slot_inst16a_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 28) >> 28;
+ insn[0] = (insn[0] & ~0xf0) | (tie_t << 4);
+}
+
+static unsigned
+Field_t_Slot_inst16b_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 4) | ((insn[0] << 24) >> 28);
+ return tie_t;
+}
+
+static void
+Field_t_Slot_inst16b_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 28) >> 28;
+ insn[0] = (insn[0] & ~0xf0) | (tie_t << 4);
+}
+
+static unsigned
+Field_t_Slot_xt_flix64_slot0_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 4) | ((insn[0] << 28) >> 28);
+ return tie_t;
+}
+
+static void
+Field_t_Slot_xt_flix64_slot0_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 28) >> 28;
+ insn[0] = (insn[0] & ~0xf) | (tie_t << 0);
+}
+
+static unsigned
+Field_t_Slot_xt_flix64_slot1_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 4) | ((insn[0] << 28) >> 28);
+ return tie_t;
+}
+
+static void
+Field_t_Slot_xt_flix64_slot1_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 28) >> 28;
+ insn[0] = (insn[0] & ~0xf) | (tie_t << 0);
+}
+
+static unsigned
+Field_t_Slot_xt_flix64_slot2_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 4) | ((insn[0] << 28) >> 28);
+ return tie_t;
+}
+
+static void
+Field_t_Slot_xt_flix64_slot2_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 28) >> 28;
+ insn[0] = (insn[0] & ~0xf) | (tie_t << 0);
+}
+
+static unsigned
+Field_t_Slot_xt_flix64_slot3_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 4) | ((insn[0] << 28) >> 28);
+ return tie_t;
+}
+
+static void
+Field_t_Slot_xt_flix64_slot3_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 28) >> 28;
+ insn[0] = (insn[0] & ~0xf) | (tie_t << 0);
+}
+
+static unsigned
+Field_bbi4_Slot_inst_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 1) | ((insn[0] << 19) >> 31);
+ return tie_t;
+}
+
+static void
+Field_bbi4_Slot_inst_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 31) >> 31;
+ insn[0] = (insn[0] & ~0x1000) | (tie_t << 12);
+}
+
+static unsigned
+Field_bbi_Slot_inst_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 1) | ((insn[0] << 19) >> 31);
+ tie_t = (tie_t << 4) | ((insn[0] << 24) >> 28);
+ return tie_t;
+}
+
+static void
+Field_bbi_Slot_inst_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 28) >> 28;
+ insn[0] = (insn[0] & ~0xf0) | (tie_t << 4);
+ tie_t = (val << 27) >> 31;
+ insn[0] = (insn[0] & ~0x1000) | (tie_t << 12);
+}
+
+static unsigned
+Field_bbi_Slot_xt_flix64_slot3_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 1) | ((insn[0] << 5) >> 31);
+ tie_t = (tie_t << 4) | ((insn[0] << 28) >> 28);
+ return tie_t;
+}
+
+static void
+Field_bbi_Slot_xt_flix64_slot3_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 28) >> 28;
+ insn[0] = (insn[0] & ~0xf) | (tie_t << 0);
+ tie_t = (val << 27) >> 31;
+ insn[0] = (insn[0] & ~0x4000000) | (tie_t << 26);
+}
+
+static unsigned
+Field_imm12_Slot_inst_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 12) | ((insn[0] << 8) >> 20);
+ return tie_t;
+}
+
+static void
+Field_imm12_Slot_inst_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 20) >> 20;
+ insn[0] = (insn[0] & ~0xfff000) | (tie_t << 12);
+}
+
+static unsigned
+Field_imm8_Slot_inst_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 8) | ((insn[0] << 8) >> 24);
+ return tie_t;
+}
+
+static void
+Field_imm8_Slot_inst_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 24) >> 24;
+ insn[0] = (insn[0] & ~0xff0000) | (tie_t << 16);
+}
+
+static unsigned
+Field_imm8_Slot_xt_flix64_slot0_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 8) | ((insn[0] << 12) >> 24);
+ return tie_t;
+}
+
+static void
+Field_imm8_Slot_xt_flix64_slot0_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 24) >> 24;
+ insn[0] = (insn[0] & ~0xff000) | (tie_t << 12);
+}
+
+static unsigned
+Field_imm8_Slot_xt_flix64_slot1_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 4) | ((insn[0] << 16) >> 28);
+ tie_t = (tie_t << 4) | ((insn[0] << 24) >> 28);
+ return tie_t;
+}
+
+static void
+Field_imm8_Slot_xt_flix64_slot1_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 28) >> 28;
+ insn[0] = (insn[0] & ~0xf0) | (tie_t << 4);
+ tie_t = (val << 24) >> 28;
+ insn[0] = (insn[0] & ~0xf000) | (tie_t << 12);
+}
+
+static unsigned
+Field_s_Slot_inst_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 4) | ((insn[0] << 20) >> 28);
+ return tie_t;
+}
+
+static void
+Field_s_Slot_inst_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 28) >> 28;
+ insn[0] = (insn[0] & ~0xf00) | (tie_t << 8);
+}
+
+static unsigned
+Field_s_Slot_inst16a_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 4) | ((insn[0] << 20) >> 28);
+ return tie_t;
+}
+
+static void
+Field_s_Slot_inst16a_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 28) >> 28;
+ insn[0] = (insn[0] & ~0xf00) | (tie_t << 8);
+}
+
+static unsigned
+Field_s_Slot_inst16b_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 4) | ((insn[0] << 20) >> 28);
+ return tie_t;
+}
+
+static void
+Field_s_Slot_inst16b_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 28) >> 28;
+ insn[0] = (insn[0] & ~0xf00) | (tie_t << 8);
+}
+
+static unsigned
+Field_s_Slot_xt_flix64_slot0_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 4) | ((insn[0] << 24) >> 28);
+ return tie_t;
+}
+
+static void
+Field_s_Slot_xt_flix64_slot0_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 28) >> 28;
+ insn[0] = (insn[0] & ~0xf0) | (tie_t << 4);
+}
+
+static unsigned
+Field_s_Slot_xt_flix64_slot1_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 4) | ((insn[0] << 20) >> 28);
+ return tie_t;
+}
+
+static void
+Field_s_Slot_xt_flix64_slot1_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 28) >> 28;
+ insn[0] = (insn[0] & ~0xf00) | (tie_t << 8);
+}
+
+static unsigned
+Field_s_Slot_xt_flix64_slot2_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 4) | ((insn[0] << 20) >> 28);
+ return tie_t;
+}
+
+static void
+Field_s_Slot_xt_flix64_slot2_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 28) >> 28;
+ insn[0] = (insn[0] & ~0xf00) | (tie_t << 8);
+}
+
+static unsigned
+Field_s_Slot_xt_flix64_slot3_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 4) | ((insn[0] << 24) >> 28);
+ return tie_t;
+}
+
+static void
+Field_s_Slot_xt_flix64_slot3_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 28) >> 28;
+ insn[0] = (insn[0] & ~0xf0) | (tie_t << 4);
+}
+
+static unsigned
+Field_imm12b_Slot_inst_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 4) | ((insn[0] << 20) >> 28);
+ tie_t = (tie_t << 8) | ((insn[0] << 8) >> 24);
+ return tie_t;
+}
+
+static void
+Field_imm12b_Slot_inst_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 24) >> 24;
+ insn[0] = (insn[0] & ~0xff0000) | (tie_t << 16);
+ tie_t = (val << 20) >> 28;
+ insn[0] = (insn[0] & ~0xf00) | (tie_t << 8);
+}
+
+static unsigned
+Field_imm12b_Slot_xt_flix64_slot0_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 4) | ((insn[0] << 24) >> 28);
+ tie_t = (tie_t << 8) | ((insn[0] << 12) >> 24);
+ return tie_t;
+}
+
+static void
+Field_imm12b_Slot_xt_flix64_slot0_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 24) >> 24;
+ insn[0] = (insn[0] & ~0xff000) | (tie_t << 12);
+ tie_t = (val << 20) >> 28;
+ insn[0] = (insn[0] & ~0xf0) | (tie_t << 4);
+}
+
+static unsigned
+Field_imm12b_Slot_xt_flix64_slot1_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 12) | ((insn[0] << 16) >> 20);
+ return tie_t;
+}
+
+static void
+Field_imm12b_Slot_xt_flix64_slot1_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 20) >> 20;
+ insn[0] = (insn[0] & ~0xfff0) | (tie_t << 4);
+}
+
+static unsigned
+Field_imm16_Slot_inst_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 16) | ((insn[0] << 8) >> 16);
+ return tie_t;
+}
+
+static void
+Field_imm16_Slot_inst_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 16) >> 16;
+ insn[0] = (insn[0] & ~0xffff00) | (tie_t << 8);
+}
+
+static unsigned
+Field_imm16_Slot_xt_flix64_slot0_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 16) | ((insn[0] << 12) >> 16);
+ return tie_t;
+}
+
+static void
+Field_imm16_Slot_xt_flix64_slot0_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 16) >> 16;
+ insn[0] = (insn[0] & ~0xffff0) | (tie_t << 4);
+}
+
+static unsigned
+Field_m_Slot_inst_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 2) | ((insn[0] << 24) >> 30);
+ return tie_t;
+}
+
+static void
+Field_m_Slot_inst_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 30) >> 30;
+ insn[0] = (insn[0] & ~0xc0) | (tie_t << 6);
+}
+
+static unsigned
+Field_m_Slot_xt_flix64_slot0_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 2) | ((insn[0] << 28) >> 30);
+ return tie_t;
+}
+
+static void
+Field_m_Slot_xt_flix64_slot0_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 30) >> 30;
+ insn[0] = (insn[0] & ~0xc) | (tie_t << 2);
+}
+
+static unsigned
+Field_n_Slot_inst_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 2) | ((insn[0] << 26) >> 30);
+ return tie_t;
+}
+
+static void
+Field_n_Slot_inst_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 30) >> 30;
+ insn[0] = (insn[0] & ~0x30) | (tie_t << 4);
+}
+
+static unsigned
+Field_n_Slot_xt_flix64_slot0_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 2) | ((insn[0] << 30) >> 30);
+ return tie_t;
+}
+
+static void
+Field_n_Slot_xt_flix64_slot0_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 30) >> 30;
+ insn[0] = (insn[0] & ~0x3) | (tie_t << 0);
+}
+
+static unsigned
+Field_offset_Slot_inst_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 18) | ((insn[0] << 8) >> 14);
+ return tie_t;
+}
+
+static void
+Field_offset_Slot_inst_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 14) >> 14;
+ insn[0] = (insn[0] & ~0xffffc0) | (tie_t << 6);
+}
+
+static unsigned
+Field_offset_Slot_xt_flix64_slot1_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 18) | ((insn[0] << 14) >> 14);
+ return tie_t;
+}
+
+static void
+Field_offset_Slot_xt_flix64_slot1_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 14) >> 14;
+ insn[0] = (insn[0] & ~0x3ffff) | (tie_t << 0);
+}
+
+static unsigned
+Field_op0_Slot_inst_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 4) | ((insn[0] << 28) >> 28);
+ return tie_t;
+}
+
+static void
+Field_op0_Slot_inst_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 28) >> 28;
+ insn[0] = (insn[0] & ~0xf) | (tie_t << 0);
+}
+
+static unsigned
+Field_op0_Slot_inst16a_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 4) | ((insn[0] << 28) >> 28);
+ return tie_t;
+}
+
+static void
+Field_op0_Slot_inst16a_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 28) >> 28;
+ insn[0] = (insn[0] & ~0xf) | (tie_t << 0);
+}
+
+static unsigned
+Field_op0_Slot_inst16b_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 4) | ((insn[0] << 28) >> 28);
+ return tie_t;
+}
+
+static void
+Field_op0_Slot_inst16b_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 28) >> 28;
+ insn[0] = (insn[0] & ~0xf) | (tie_t << 0);
+}
+
+static unsigned
+Field_op1_Slot_inst_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 4) | ((insn[0] << 12) >> 28);
+ return tie_t;
+}
+
+static void
+Field_op1_Slot_inst_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 28) >> 28;
+ insn[0] = (insn[0] & ~0xf0000) | (tie_t << 16);
+}
+
+static unsigned
+Field_op1_Slot_xt_flix64_slot0_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 4) | ((insn[0] << 16) >> 28);
+ return tie_t;
+}
+
+static void
+Field_op1_Slot_xt_flix64_slot0_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 28) >> 28;
+ insn[0] = (insn[0] & ~0xf000) | (tie_t << 12);
+}
+
+static unsigned
+Field_op2_Slot_inst_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 4) | ((insn[0] << 8) >> 28);
+ return tie_t;
+}
+
+static void
+Field_op2_Slot_inst_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 28) >> 28;
+ insn[0] = (insn[0] & ~0xf00000) | (tie_t << 20);
+}
+
+static unsigned
+Field_op2_Slot_xt_flix64_slot0_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 4) | ((insn[0] << 12) >> 28);
+ return tie_t;
+}
+
+static void
+Field_op2_Slot_xt_flix64_slot0_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 28) >> 28;
+ insn[0] = (insn[0] & ~0xf0000) | (tie_t << 16);
+}
+
+static unsigned
+Field_op2_Slot_xt_flix64_slot1_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 4) | ((insn[0] << 20) >> 28);
+ return tie_t;
+}
+
+static void
+Field_op2_Slot_xt_flix64_slot1_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 28) >> 28;
+ insn[0] = (insn[0] & ~0xf00) | (tie_t << 8);
+}
+
+static unsigned
+Field_r_Slot_inst_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 4) | ((insn[0] << 16) >> 28);
+ return tie_t;
+}
+
+static void
+Field_r_Slot_inst_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 28) >> 28;
+ insn[0] = (insn[0] & ~0xf000) | (tie_t << 12);
+}
+
+static unsigned
+Field_r_Slot_inst16a_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 4) | ((insn[0] << 16) >> 28);
+ return tie_t;
+}
+
+static void
+Field_r_Slot_inst16a_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 28) >> 28;
+ insn[0] = (insn[0] & ~0xf000) | (tie_t << 12);
+}
+
+static unsigned
+Field_r_Slot_inst16b_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 4) | ((insn[0] << 16) >> 28);
+ return tie_t;
+}
+
+static void
+Field_r_Slot_inst16b_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 28) >> 28;
+ insn[0] = (insn[0] & ~0xf000) | (tie_t << 12);
+}
+
+static unsigned
+Field_r_Slot_xt_flix64_slot0_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 4) | ((insn[0] << 20) >> 28);
+ return tie_t;
+}
+
+static void
+Field_r_Slot_xt_flix64_slot0_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 28) >> 28;
+ insn[0] = (insn[0] & ~0xf00) | (tie_t << 8);
+}
+
+static unsigned
+Field_r_Slot_xt_flix64_slot1_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 4) | ((insn[0] << 24) >> 28);
+ return tie_t;
+}
+
+static void
+Field_r_Slot_xt_flix64_slot1_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 28) >> 28;
+ insn[0] = (insn[0] & ~0xf0) | (tie_t << 4);
+}
+
+static unsigned
+Field_r_Slot_xt_flix64_slot2_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 4) | ((insn[0] << 24) >> 28);
+ return tie_t;
+}
+
+static void
+Field_r_Slot_xt_flix64_slot2_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 28) >> 28;
+ insn[0] = (insn[0] & ~0xf0) | (tie_t << 4);
+}
+
+static unsigned
+Field_r_Slot_xt_flix64_slot3_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 4) | ((insn[0] << 28) >> 28);
+ return tie_t;
+}
+
+static void
+Field_r_Slot_xt_flix64_slot3_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 28) >> 28;
+ insn[0] = (insn[0] & ~0xf) | (tie_t << 0);
+}
+
+static unsigned
+Field_sa4_Slot_inst_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 1) | ((insn[0] << 11) >> 31);
+ return tie_t;
+}
+
+static void
+Field_sa4_Slot_inst_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 31) >> 31;
+ insn[0] = (insn[0] & ~0x100000) | (tie_t << 20);
+}
+
+static unsigned
+Field_sae4_Slot_inst_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 1) | ((insn[0] << 15) >> 31);
+ return tie_t;
+}
+
+static void
+Field_sae4_Slot_inst_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 31) >> 31;
+ insn[0] = (insn[0] & ~0x10000) | (tie_t << 16);
+}
+
+static unsigned
+Field_sae4_Slot_xt_flix64_slot0_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 1) | ((insn[0] << 19) >> 31);
+ return tie_t;
+}
+
+static void
+Field_sae4_Slot_xt_flix64_slot0_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 31) >> 31;
+ insn[0] = (insn[0] & ~0x1000) | (tie_t << 12);
+}
+
+static unsigned
+Field_sae_Slot_inst_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 1) | ((insn[0] << 15) >> 31);
+ tie_t = (tie_t << 4) | ((insn[0] << 20) >> 28);
+ return tie_t;
+}
+
+static void
+Field_sae_Slot_inst_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 28) >> 28;
+ insn[0] = (insn[0] & ~0xf00) | (tie_t << 8);
+ tie_t = (val << 27) >> 31;
+ insn[0] = (insn[0] & ~0x10000) | (tie_t << 16);
+}
+
+static unsigned
+Field_sae_Slot_xt_flix64_slot0_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 1) | ((insn[0] << 19) >> 31);
+ tie_t = (tie_t << 4) | ((insn[0] << 24) >> 28);
+ return tie_t;
+}
+
+static void
+Field_sae_Slot_xt_flix64_slot0_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 28) >> 28;
+ insn[0] = (insn[0] & ~0xf0) | (tie_t << 4);
+ tie_t = (val << 27) >> 31;
+ insn[0] = (insn[0] & ~0x1000) | (tie_t << 12);
+}
+
+static unsigned
+Field_sae_Slot_xt_flix64_slot1_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 5) | ((insn[0] << 15) >> 27);
+ return tie_t;
+}
+
+static void
+Field_sae_Slot_xt_flix64_slot1_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 27) >> 27;
+ insn[0] = (insn[0] & ~0x1f000) | (tie_t << 12);
+}
+
+static unsigned
+Field_sal_Slot_inst_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 1) | ((insn[0] << 11) >> 31);
+ tie_t = (tie_t << 4) | ((insn[0] << 24) >> 28);
+ return tie_t;
+}
+
+static void
+Field_sal_Slot_inst_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 28) >> 28;
+ insn[0] = (insn[0] & ~0xf0) | (tie_t << 4);
+ tie_t = (val << 27) >> 31;
+ insn[0] = (insn[0] & ~0x100000) | (tie_t << 20);
+}
+
+static unsigned
+Field_sal_Slot_xt_flix64_slot0_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 1) | ((insn[0] << 15) >> 31);
+ tie_t = (tie_t << 4) | ((insn[0] << 28) >> 28);
+ return tie_t;
+}
+
+static void
+Field_sal_Slot_xt_flix64_slot0_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 28) >> 28;
+ insn[0] = (insn[0] & ~0xf) | (tie_t << 0);
+ tie_t = (val << 27) >> 31;
+ insn[0] = (insn[0] & ~0x10000) | (tie_t << 16);
+}
+
+static unsigned
+Field_sal_Slot_xt_flix64_slot1_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 1) | ((insn[0] << 19) >> 31);
+ tie_t = (tie_t << 4) | ((insn[0] << 28) >> 28);
+ return tie_t;
+}
+
+static void
+Field_sal_Slot_xt_flix64_slot1_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 28) >> 28;
+ insn[0] = (insn[0] & ~0xf) | (tie_t << 0);
+ tie_t = (val << 27) >> 31;
+ insn[0] = (insn[0] & ~0x1000) | (tie_t << 12);
+}
+
+static unsigned
+Field_sargt_Slot_inst_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 1) | ((insn[0] << 11) >> 31);
+ tie_t = (tie_t << 4) | ((insn[0] << 20) >> 28);
+ return tie_t;
+}
+
+static void
+Field_sargt_Slot_inst_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 28) >> 28;
+ insn[0] = (insn[0] & ~0xf00) | (tie_t << 8);
+ tie_t = (val << 27) >> 31;
+ insn[0] = (insn[0] & ~0x100000) | (tie_t << 20);
+}
+
+static unsigned
+Field_sargt_Slot_xt_flix64_slot0_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 1) | ((insn[0] << 15) >> 31);
+ tie_t = (tie_t << 4) | ((insn[0] << 24) >> 28);
+ return tie_t;
+}
+
+static void
+Field_sargt_Slot_xt_flix64_slot0_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 28) >> 28;
+ insn[0] = (insn[0] & ~0xf0) | (tie_t << 4);
+ tie_t = (val << 27) >> 31;
+ insn[0] = (insn[0] & ~0x10000) | (tie_t << 16);
+}
+
+static unsigned
+Field_sargt_Slot_xt_flix64_slot1_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 5) | ((insn[0] << 19) >> 27);
+ return tie_t;
+}
+
+static void
+Field_sargt_Slot_xt_flix64_slot1_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 27) >> 27;
+ insn[0] = (insn[0] & ~0x1f00) | (tie_t << 8);
+}
+
+static unsigned
+Field_sargt_Slot_xt_flix64_slot2_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 5) | ((insn[0] << 19) >> 27);
+ return tie_t;
+}
+
+static void
+Field_sargt_Slot_xt_flix64_slot2_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 27) >> 27;
+ insn[0] = (insn[0] & ~0x1f00) | (tie_t << 8);
+}
+
+static unsigned
+Field_sas4_Slot_inst_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 1) | ((insn[0] << 27) >> 31);
+ return tie_t;
+}
+
+static void
+Field_sas4_Slot_inst_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 31) >> 31;
+ insn[0] = (insn[0] & ~0x10) | (tie_t << 4);
+}
+
+static unsigned
+Field_sas_Slot_inst_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 1) | ((insn[0] << 27) >> 31);
+ tie_t = (tie_t << 4) | ((insn[0] << 20) >> 28);
+ return tie_t;
+}
+
+static void
+Field_sas_Slot_inst_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 28) >> 28;
+ insn[0] = (insn[0] & ~0xf00) | (tie_t << 8);
+ tie_t = (val << 27) >> 31;
+ insn[0] = (insn[0] & ~0x10) | (tie_t << 4);
+}
+
+static unsigned
+Field_sas_Slot_xt_flix64_slot0_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 1) | ((insn[0] << 31) >> 31);
+ tie_t = (tie_t << 4) | ((insn[0] << 24) >> 28);
+ return tie_t;
+}
+
+static void
+Field_sas_Slot_xt_flix64_slot0_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 28) >> 28;
+ insn[0] = (insn[0] & ~0xf0) | (tie_t << 4);
+ tie_t = (val << 27) >> 31;
+ insn[0] = (insn[0] & ~0x1) | (tie_t << 0);
+}
+
+static unsigned
+Field_sr_Slot_inst_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 4) | ((insn[0] << 16) >> 28);
+ tie_t = (tie_t << 4) | ((insn[0] << 20) >> 28);
+ return tie_t;
+}
+
+static void
+Field_sr_Slot_inst_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 28) >> 28;
+ insn[0] = (insn[0] & ~0xf00) | (tie_t << 8);
+ tie_t = (val << 24) >> 28;
+ insn[0] = (insn[0] & ~0xf000) | (tie_t << 12);
+}
+
+static unsigned
+Field_sr_Slot_inst16a_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 4) | ((insn[0] << 16) >> 28);
+ tie_t = (tie_t << 4) | ((insn[0] << 20) >> 28);
+ return tie_t;
+}
+
+static void
+Field_sr_Slot_inst16a_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 28) >> 28;
+ insn[0] = (insn[0] & ~0xf00) | (tie_t << 8);
+ tie_t = (val << 24) >> 28;
+ insn[0] = (insn[0] & ~0xf000) | (tie_t << 12);
+}
+
+static unsigned
+Field_sr_Slot_inst16b_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 4) | ((insn[0] << 16) >> 28);
+ tie_t = (tie_t << 4) | ((insn[0] << 20) >> 28);
+ return tie_t;
+}
+
+static void
+Field_sr_Slot_inst16b_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 28) >> 28;
+ insn[0] = (insn[0] & ~0xf00) | (tie_t << 8);
+ tie_t = (val << 24) >> 28;
+ insn[0] = (insn[0] & ~0xf000) | (tie_t << 12);
+}
+
+static unsigned
+Field_st_Slot_inst_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 4) | ((insn[0] << 20) >> 28);
+ tie_t = (tie_t << 4) | ((insn[0] << 24) >> 28);
+ return tie_t;
+}
+
+static void
+Field_st_Slot_inst_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 28) >> 28;
+ insn[0] = (insn[0] & ~0xf0) | (tie_t << 4);
+ tie_t = (val << 24) >> 28;
+ insn[0] = (insn[0] & ~0xf00) | (tie_t << 8);
+}
+
+static unsigned
+Field_st_Slot_inst16a_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 4) | ((insn[0] << 20) >> 28);
+ tie_t = (tie_t << 4) | ((insn[0] << 24) >> 28);
+ return tie_t;
+}
+
+static void
+Field_st_Slot_inst16a_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 28) >> 28;
+ insn[0] = (insn[0] & ~0xf0) | (tie_t << 4);
+ tie_t = (val << 24) >> 28;
+ insn[0] = (insn[0] & ~0xf00) | (tie_t << 8);
+}
+
+static unsigned
+Field_st_Slot_inst16b_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 4) | ((insn[0] << 20) >> 28);
+ tie_t = (tie_t << 4) | ((insn[0] << 24) >> 28);
+ return tie_t;
+}
+
+static void
+Field_st_Slot_inst16b_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 28) >> 28;
+ insn[0] = (insn[0] & ~0xf0) | (tie_t << 4);
+ tie_t = (val << 24) >> 28;
+ insn[0] = (insn[0] & ~0xf00) | (tie_t << 8);
+}
+
+static unsigned
+Field_thi3_Slot_inst_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 3) | ((insn[0] << 24) >> 29);
+ return tie_t;
+}
+
+static void
+Field_thi3_Slot_inst_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 29) >> 29;
+ insn[0] = (insn[0] & ~0xe0) | (tie_t << 5);
+}
+
+static unsigned
+Field_thi3_Slot_xt_flix64_slot0_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 3) | ((insn[0] << 28) >> 29);
+ return tie_t;
+}
+
+static void
+Field_thi3_Slot_xt_flix64_slot0_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 29) >> 29;
+ insn[0] = (insn[0] & ~0xe) | (tie_t << 1);
+}
+
+static unsigned
+Field_imm4_Slot_inst_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 4) | ((insn[0] << 16) >> 28);
+ return tie_t;
+}
+
+static void
+Field_imm4_Slot_inst_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 28) >> 28;
+ insn[0] = (insn[0] & ~0xf000) | (tie_t << 12);
+}
+
+static unsigned
+Field_imm4_Slot_inst16a_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 4) | ((insn[0] << 16) >> 28);
+ return tie_t;
+}
+
+static void
+Field_imm4_Slot_inst16a_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 28) >> 28;
+ insn[0] = (insn[0] & ~0xf000) | (tie_t << 12);
+}
+
+static unsigned
+Field_imm4_Slot_inst16b_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 4) | ((insn[0] << 16) >> 28);
+ return tie_t;
+}
+
+static void
+Field_imm4_Slot_inst16b_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 28) >> 28;
+ insn[0] = (insn[0] & ~0xf000) | (tie_t << 12);
+}
+
+static unsigned
+Field_mn_Slot_inst_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 2) | ((insn[0] << 24) >> 30);
+ tie_t = (tie_t << 2) | ((insn[0] << 26) >> 30);
+ return tie_t;
+}
+
+static void
+Field_mn_Slot_inst_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 30) >> 30;
+ insn[0] = (insn[0] & ~0x30) | (tie_t << 4);
+ tie_t = (val << 28) >> 30;
+ insn[0] = (insn[0] & ~0xc0) | (tie_t << 6);
+}
+
+static unsigned
+Field_i_Slot_inst16a_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 1) | ((insn[0] << 24) >> 31);
+ return tie_t;
+}
+
+static void
+Field_i_Slot_inst16a_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 31) >> 31;
+ insn[0] = (insn[0] & ~0x80) | (tie_t << 7);
+}
+
+static unsigned
+Field_i_Slot_inst16b_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 1) | ((insn[0] << 24) >> 31);
+ return tie_t;
+}
+
+static void
+Field_i_Slot_inst16b_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 31) >> 31;
+ insn[0] = (insn[0] & ~0x80) | (tie_t << 7);
+}
+
+static unsigned
+Field_imm6lo_Slot_inst16a_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 4) | ((insn[0] << 16) >> 28);
+ return tie_t;
+}
+
+static void
+Field_imm6lo_Slot_inst16a_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 28) >> 28;
+ insn[0] = (insn[0] & ~0xf000) | (tie_t << 12);
+}
+
+static unsigned
+Field_imm6lo_Slot_inst16b_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 4) | ((insn[0] << 16) >> 28);
+ return tie_t;
+}
+
+static void
+Field_imm6lo_Slot_inst16b_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 28) >> 28;
+ insn[0] = (insn[0] & ~0xf000) | (tie_t << 12);
+}
+
+static unsigned
+Field_imm6hi_Slot_inst16a_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 2) | ((insn[0] << 26) >> 30);
+ return tie_t;
+}
+
+static void
+Field_imm6hi_Slot_inst16a_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 30) >> 30;
+ insn[0] = (insn[0] & ~0x30) | (tie_t << 4);
+}
+
+static unsigned
+Field_imm6hi_Slot_inst16b_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 2) | ((insn[0] << 26) >> 30);
+ return tie_t;
+}
+
+static void
+Field_imm6hi_Slot_inst16b_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 30) >> 30;
+ insn[0] = (insn[0] & ~0x30) | (tie_t << 4);
+}
+
+static unsigned
+Field_imm7lo_Slot_inst16a_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 4) | ((insn[0] << 16) >> 28);
+ return tie_t;
+}
+
+static void
+Field_imm7lo_Slot_inst16a_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 28) >> 28;
+ insn[0] = (insn[0] & ~0xf000) | (tie_t << 12);
+}
+
+static unsigned
+Field_imm7lo_Slot_inst16b_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 4) | ((insn[0] << 16) >> 28);
+ return tie_t;
+}
+
+static void
+Field_imm7lo_Slot_inst16b_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 28) >> 28;
+ insn[0] = (insn[0] & ~0xf000) | (tie_t << 12);
+}
+
+static unsigned
+Field_imm7hi_Slot_inst16a_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 3) | ((insn[0] << 25) >> 29);
+ return tie_t;
+}
+
+static void
+Field_imm7hi_Slot_inst16a_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 29) >> 29;
+ insn[0] = (insn[0] & ~0x70) | (tie_t << 4);
+}
+
+static unsigned
+Field_imm7hi_Slot_inst16b_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 3) | ((insn[0] << 25) >> 29);
+ return tie_t;
+}
+
+static void
+Field_imm7hi_Slot_inst16b_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 29) >> 29;
+ insn[0] = (insn[0] & ~0x70) | (tie_t << 4);
+}
+
+static unsigned
+Field_z_Slot_inst16a_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 1) | ((insn[0] << 25) >> 31);
+ return tie_t;
+}
+
+static void
+Field_z_Slot_inst16a_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 31) >> 31;
+ insn[0] = (insn[0] & ~0x40) | (tie_t << 6);
+}
+
+static unsigned
+Field_z_Slot_inst16b_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 1) | ((insn[0] << 25) >> 31);
+ return tie_t;
+}
+
+static void
+Field_z_Slot_inst16b_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 31) >> 31;
+ insn[0] = (insn[0] & ~0x40) | (tie_t << 6);
+}
+
+static unsigned
+Field_imm6_Slot_inst16a_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 2) | ((insn[0] << 26) >> 30);
+ tie_t = (tie_t << 4) | ((insn[0] << 16) >> 28);
+ return tie_t;
+}
+
+static void
+Field_imm6_Slot_inst16a_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 28) >> 28;
+ insn[0] = (insn[0] & ~0xf000) | (tie_t << 12);
+ tie_t = (val << 26) >> 30;
+ insn[0] = (insn[0] & ~0x30) | (tie_t << 4);
+}
+
+static unsigned
+Field_imm6_Slot_inst16b_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 2) | ((insn[0] << 26) >> 30);
+ tie_t = (tie_t << 4) | ((insn[0] << 16) >> 28);
+ return tie_t;
+}
+
+static void
+Field_imm6_Slot_inst16b_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 28) >> 28;
+ insn[0] = (insn[0] & ~0xf000) | (tie_t << 12);
+ tie_t = (val << 26) >> 30;
+ insn[0] = (insn[0] & ~0x30) | (tie_t << 4);
+}
+
+static unsigned
+Field_imm7_Slot_inst16a_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 3) | ((insn[0] << 25) >> 29);
+ tie_t = (tie_t << 4) | ((insn[0] << 16) >> 28);
+ return tie_t;
+}
+
+static void
+Field_imm7_Slot_inst16a_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 28) >> 28;
+ insn[0] = (insn[0] & ~0xf000) | (tie_t << 12);
+ tie_t = (val << 25) >> 29;
+ insn[0] = (insn[0] & ~0x70) | (tie_t << 4);
+}
+
+static unsigned
+Field_imm7_Slot_inst16b_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 3) | ((insn[0] << 25) >> 29);
+ tie_t = (tie_t << 4) | ((insn[0] << 16) >> 28);
+ return tie_t;
+}
+
+static void
+Field_imm7_Slot_inst16b_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 28) >> 28;
+ insn[0] = (insn[0] & ~0xf000) | (tie_t << 12);
+ tie_t = (val << 25) >> 29;
+ insn[0] = (insn[0] & ~0x70) | (tie_t << 4);
+}
+
+static unsigned
+Field_imm7_Slot_xt_flix64_slot2_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 7) | ((insn[0] << 25) >> 25);
+ return tie_t;
+}
+
+static void
+Field_imm7_Slot_xt_flix64_slot2_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 25) >> 25;
+ insn[0] = (insn[0] & ~0x7f) | (tie_t << 0);
+}
+
+static unsigned
+Field_r3_Slot_inst_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 1) | ((insn[0] << 16) >> 31);
+ return tie_t;
+}
+
+static void
+Field_r3_Slot_inst_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 31) >> 31;
+ insn[0] = (insn[0] & ~0x8000) | (tie_t << 15);
+}
+
+static unsigned
+Field_rbit2_Slot_inst_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 1) | ((insn[0] << 17) >> 31);
+ return tie_t;
+}
+
+static void
+Field_rbit2_Slot_inst_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 31) >> 31;
+ insn[0] = (insn[0] & ~0x4000) | (tie_t << 14);
+}
+
+static unsigned
+Field_rhi_Slot_inst_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 2) | ((insn[0] << 16) >> 30);
+ return tie_t;
+}
+
+static void
+Field_rhi_Slot_inst_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 30) >> 30;
+ insn[0] = (insn[0] & ~0xc000) | (tie_t << 14);
+}
+
+static unsigned
+Field_t3_Slot_inst_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 1) | ((insn[0] << 24) >> 31);
+ return tie_t;
+}
+
+static void
+Field_t3_Slot_inst_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 31) >> 31;
+ insn[0] = (insn[0] & ~0x80) | (tie_t << 7);
+}
+
+static unsigned
+Field_tbit2_Slot_inst_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 1) | ((insn[0] << 25) >> 31);
+ return tie_t;
+}
+
+static void
+Field_tbit2_Slot_inst_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 31) >> 31;
+ insn[0] = (insn[0] & ~0x40) | (tie_t << 6);
+}
+
+static unsigned
+Field_tlo_Slot_inst_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 2) | ((insn[0] << 26) >> 30);
+ return tie_t;
+}
+
+static void
+Field_tlo_Slot_inst_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 30) >> 30;
+ insn[0] = (insn[0] & ~0x30) | (tie_t << 4);
+}
+
+static unsigned
+Field_w_Slot_inst_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 2) | ((insn[0] << 18) >> 30);
+ return tie_t;
+}
+
+static void
+Field_w_Slot_inst_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 30) >> 30;
+ insn[0] = (insn[0] & ~0x3000) | (tie_t << 12);
+}
+
+static unsigned
+Field_y_Slot_inst_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 1) | ((insn[0] << 25) >> 31);
+ return tie_t;
+}
+
+static void
+Field_y_Slot_inst_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 31) >> 31;
+ insn[0] = (insn[0] & ~0x40) | (tie_t << 6);
+}
+
+static unsigned
+Field_x_Slot_inst_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 1) | ((insn[0] << 17) >> 31);
+ return tie_t;
+}
+
+static void
+Field_x_Slot_inst_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 31) >> 31;
+ insn[0] = (insn[0] & ~0x4000) | (tie_t << 14);
+}
+
+static unsigned
+Field_t2_Slot_inst_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 3) | ((insn[0] << 24) >> 29);
+ return tie_t;
+}
+
+static void
+Field_t2_Slot_inst_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 29) >> 29;
+ insn[0] = (insn[0] & ~0xe0) | (tie_t << 5);
+}
+
+static unsigned
+Field_t2_Slot_inst16a_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 3) | ((insn[0] << 24) >> 29);
+ return tie_t;
+}
+
+static void
+Field_t2_Slot_inst16a_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 29) >> 29;
+ insn[0] = (insn[0] & ~0xe0) | (tie_t << 5);
+}
+
+static unsigned
+Field_t2_Slot_inst16b_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 3) | ((insn[0] << 24) >> 29);
+ return tie_t;
+}
+
+static void
+Field_t2_Slot_inst16b_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 29) >> 29;
+ insn[0] = (insn[0] & ~0xe0) | (tie_t << 5);
+}
+
+static unsigned
+Field_s2_Slot_inst_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 3) | ((insn[0] << 20) >> 29);
+ return tie_t;
+}
+
+static void
+Field_s2_Slot_inst_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 29) >> 29;
+ insn[0] = (insn[0] & ~0xe00) | (tie_t << 9);
+}
+
+static unsigned
+Field_s2_Slot_inst16a_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 3) | ((insn[0] << 20) >> 29);
+ return tie_t;
+}
+
+static void
+Field_s2_Slot_inst16a_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 29) >> 29;
+ insn[0] = (insn[0] & ~0xe00) | (tie_t << 9);
+}
+
+static unsigned
+Field_s2_Slot_inst16b_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 3) | ((insn[0] << 20) >> 29);
+ return tie_t;
+}
+
+static void
+Field_s2_Slot_inst16b_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 29) >> 29;
+ insn[0] = (insn[0] & ~0xe00) | (tie_t << 9);
+}
+
+static unsigned
+Field_r2_Slot_inst_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 3) | ((insn[0] << 16) >> 29);
+ return tie_t;
+}
+
+static void
+Field_r2_Slot_inst_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 29) >> 29;
+ insn[0] = (insn[0] & ~0xe000) | (tie_t << 13);
+}
+
+static unsigned
+Field_r2_Slot_inst16a_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 3) | ((insn[0] << 16) >> 29);
+ return tie_t;
+}
+
+static void
+Field_r2_Slot_inst16a_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 29) >> 29;
+ insn[0] = (insn[0] & ~0xe000) | (tie_t << 13);
+}
+
+static unsigned
+Field_r2_Slot_inst16b_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 3) | ((insn[0] << 16) >> 29);
+ return tie_t;
+}
+
+static void
+Field_r2_Slot_inst16b_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 29) >> 29;
+ insn[0] = (insn[0] & ~0xe000) | (tie_t << 13);
+}
+
+static unsigned
+Field_t4_Slot_inst_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 2) | ((insn[0] << 24) >> 30);
+ return tie_t;
+}
+
+static void
+Field_t4_Slot_inst_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 30) >> 30;
+ insn[0] = (insn[0] & ~0xc0) | (tie_t << 6);
+}
+
+static unsigned
+Field_t4_Slot_inst16a_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 2) | ((insn[0] << 24) >> 30);
+ return tie_t;
+}
+
+static void
+Field_t4_Slot_inst16a_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 30) >> 30;
+ insn[0] = (insn[0] & ~0xc0) | (tie_t << 6);
+}
+
+static unsigned
+Field_t4_Slot_inst16b_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 2) | ((insn[0] << 24) >> 30);
+ return tie_t;
+}
+
+static void
+Field_t4_Slot_inst16b_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 30) >> 30;
+ insn[0] = (insn[0] & ~0xc0) | (tie_t << 6);
+}
+
+static unsigned
+Field_s4_Slot_inst_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 2) | ((insn[0] << 20) >> 30);
+ return tie_t;
+}
+
+static void
+Field_s4_Slot_inst_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 30) >> 30;
+ insn[0] = (insn[0] & ~0xc00) | (tie_t << 10);
+}
+
+static unsigned
+Field_s4_Slot_inst16a_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 2) | ((insn[0] << 20) >> 30);
+ return tie_t;
+}
+
+static void
+Field_s4_Slot_inst16a_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 30) >> 30;
+ insn[0] = (insn[0] & ~0xc00) | (tie_t << 10);
+}
+
+static unsigned
+Field_s4_Slot_inst16b_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 2) | ((insn[0] << 20) >> 30);
+ return tie_t;
+}
+
+static void
+Field_s4_Slot_inst16b_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 30) >> 30;
+ insn[0] = (insn[0] & ~0xc00) | (tie_t << 10);
+}
+
+static unsigned
+Field_r4_Slot_inst_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 2) | ((insn[0] << 16) >> 30);
+ return tie_t;
+}
+
+static void
+Field_r4_Slot_inst_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 30) >> 30;
+ insn[0] = (insn[0] & ~0xc000) | (tie_t << 14);
+}
+
+static unsigned
+Field_r4_Slot_inst16a_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 2) | ((insn[0] << 16) >> 30);
+ return tie_t;
+}
+
+static void
+Field_r4_Slot_inst16a_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 30) >> 30;
+ insn[0] = (insn[0] & ~0xc000) | (tie_t << 14);
+}
+
+static unsigned
+Field_r4_Slot_inst16b_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 2) | ((insn[0] << 16) >> 30);
+ return tie_t;
+}
+
+static void
+Field_r4_Slot_inst16b_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 30) >> 30;
+ insn[0] = (insn[0] & ~0xc000) | (tie_t << 14);
+}
+
+static unsigned
+Field_t8_Slot_inst_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 1) | ((insn[0] << 24) >> 31);
+ return tie_t;
+}
+
+static void
+Field_t8_Slot_inst_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 31) >> 31;
+ insn[0] = (insn[0] & ~0x80) | (tie_t << 7);
+}
+
+static unsigned
+Field_t8_Slot_inst16a_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 1) | ((insn[0] << 24) >> 31);
+ return tie_t;
+}
+
+static void
+Field_t8_Slot_inst16a_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 31) >> 31;
+ insn[0] = (insn[0] & ~0x80) | (tie_t << 7);
+}
+
+static unsigned
+Field_t8_Slot_inst16b_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 1) | ((insn[0] << 24) >> 31);
+ return tie_t;
+}
+
+static void
+Field_t8_Slot_inst16b_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 31) >> 31;
+ insn[0] = (insn[0] & ~0x80) | (tie_t << 7);
+}
+
+static unsigned
+Field_s8_Slot_inst_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 1) | ((insn[0] << 20) >> 31);
+ return tie_t;
+}
+
+static void
+Field_s8_Slot_inst_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 31) >> 31;
+ insn[0] = (insn[0] & ~0x800) | (tie_t << 11);
+}
+
+static unsigned
+Field_s8_Slot_inst16a_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 1) | ((insn[0] << 20) >> 31);
+ return tie_t;
+}
+
+static void
+Field_s8_Slot_inst16a_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 31) >> 31;
+ insn[0] = (insn[0] & ~0x800) | (tie_t << 11);
+}
+
+static unsigned
+Field_s8_Slot_inst16b_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 1) | ((insn[0] << 20) >> 31);
+ return tie_t;
+}
+
+static void
+Field_s8_Slot_inst16b_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 31) >> 31;
+ insn[0] = (insn[0] & ~0x800) | (tie_t << 11);
+}
+
+static unsigned
+Field_r8_Slot_inst_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 1) | ((insn[0] << 16) >> 31);
+ return tie_t;
+}
+
+static void
+Field_r8_Slot_inst_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 31) >> 31;
+ insn[0] = (insn[0] & ~0x8000) | (tie_t << 15);
+}
+
+static unsigned
+Field_r8_Slot_inst16a_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 1) | ((insn[0] << 16) >> 31);
+ return tie_t;
+}
+
+static void
+Field_r8_Slot_inst16a_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 31) >> 31;
+ insn[0] = (insn[0] & ~0x8000) | (tie_t << 15);
+}
+
+static unsigned
+Field_r8_Slot_inst16b_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 1) | ((insn[0] << 16) >> 31);
+ return tie_t;
+}
+
+static void
+Field_r8_Slot_inst16b_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 31) >> 31;
+ insn[0] = (insn[0] & ~0x8000) | (tie_t << 15);
+}
+
+static unsigned
+Field_xt_wbr15_imm_Slot_inst_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 15) | ((insn[0] << 8) >> 17);
+ return tie_t;
+}
+
+static void
+Field_xt_wbr15_imm_Slot_inst_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 17) >> 17;
+ insn[0] = (insn[0] & ~0xfffe00) | (tie_t << 9);
+}
+
+static unsigned
+Field_xt_wbr18_imm_Slot_inst_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 18) | ((insn[0] << 8) >> 14);
+ return tie_t;
+}
+
+static void
+Field_xt_wbr18_imm_Slot_inst_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 14) >> 14;
+ insn[0] = (insn[0] & ~0xffffc0) | (tie_t << 6);
+}
+
+static unsigned
+Field_xt_wbr18_imm_Slot_xt_flix64_slot3_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 18) | ((insn[0] << 6) >> 14);
+ return tie_t;
+}
+
+static void
+Field_xt_wbr18_imm_Slot_xt_flix64_slot3_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 14) >> 14;
+ insn[0] = (insn[0] & ~0x3ffff00) | (tie_t << 8);
+}
+
+static unsigned
+Field_op0_xt_flix64_slot0_s3_Slot_xt_flix64_slot0_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 4) | ((insn[0] << 8) >> 28);
+ return tie_t;
+}
+
+static void
+Field_op0_xt_flix64_slot0_s3_Slot_xt_flix64_slot0_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 28) >> 28;
+ insn[0] = (insn[0] & ~0xf00000) | (tie_t << 20);
+}
+
+static unsigned
+Field_combined3e2c5767_fld7_Slot_xt_flix64_slot0_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 3) | ((insn[0] << 16) >> 29);
+ return tie_t;
+}
+
+static void
+Field_combined3e2c5767_fld7_Slot_xt_flix64_slot0_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 29) >> 29;
+ insn[0] = (insn[0] & ~0xe000) | (tie_t << 13);
+}
+
+static unsigned
+Field_combined3e2c5767_fld8_Slot_xt_flix64_slot0_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 3) | ((insn[0] << 16) >> 29);
+ return tie_t;
+}
+
+static void
+Field_combined3e2c5767_fld8_Slot_xt_flix64_slot0_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 29) >> 29;
+ insn[0] = (insn[0] & ~0xe000) | (tie_t << 13);
+}
+
+static unsigned
+Field_combined3e2c5767_fld9_Slot_xt_flix64_slot0_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 3) | ((insn[0] << 12) >> 29);
+ return tie_t;
+}
+
+static void
+Field_combined3e2c5767_fld9_Slot_xt_flix64_slot0_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 29) >> 29;
+ insn[0] = (insn[0] & ~0xe0000) | (tie_t << 17);
+}
+
+static unsigned
+Field_combined3e2c5767_fld11_Slot_xt_flix64_slot0_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 3) | ((insn[0] << 12) >> 29);
+ return tie_t;
+}
+
+static void
+Field_combined3e2c5767_fld11_Slot_xt_flix64_slot0_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 29) >> 29;
+ insn[0] = (insn[0] & ~0xe0000) | (tie_t << 17);
+}
+
+static unsigned
+Field_combined3e2c5767_fld49xt_flix64_slot0_Slot_xt_flix64_slot0_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 4) | ((insn[0] << 12) >> 28);
+ tie_t = (tie_t << 4) | ((insn[0] << 20) >> 28);
+ return tie_t;
+}
+
+static void
+Field_combined3e2c5767_fld49xt_flix64_slot0_Slot_xt_flix64_slot0_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 28) >> 28;
+ insn[0] = (insn[0] & ~0xf00) | (tie_t << 8);
+ tie_t = (val << 24) >> 28;
+ insn[0] = (insn[0] & ~0xf0000) | (tie_t << 16);
+}
+
+static unsigned
+Field_op0_s4_Slot_xt_flix64_slot1_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 2) | ((insn[0] << 12) >> 30);
+ return tie_t;
+}
+
+static void
+Field_op0_s4_Slot_xt_flix64_slot1_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 30) >> 30;
+ insn[0] = (insn[0] & ~0xc0000) | (tie_t << 18);
+}
+
+static unsigned
+Field_combined3e2c5767_fld16_Slot_xt_flix64_slot1_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 4) | ((insn[0] << 16) >> 28);
+ return tie_t;
+}
+
+static void
+Field_combined3e2c5767_fld16_Slot_xt_flix64_slot1_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 28) >> 28;
+ insn[0] = (insn[0] & ~0xf000) | (tie_t << 12);
+}
+
+static unsigned
+Field_combined3e2c5767_fld19xt_flix64_slot1_Slot_xt_flix64_slot1_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 1) | ((insn[0] << 14) >> 31);
+ return tie_t;
+}
+
+static void
+Field_combined3e2c5767_fld19xt_flix64_slot1_Slot_xt_flix64_slot1_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 31) >> 31;
+ insn[0] = (insn[0] & ~0x20000) | (tie_t << 17);
+}
+
+static unsigned
+Field_combined3e2c5767_fld20xt_flix64_slot1_Slot_xt_flix64_slot1_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 2) | ((insn[0] << 14) >> 30);
+ return tie_t;
+}
+
+static void
+Field_combined3e2c5767_fld20xt_flix64_slot1_Slot_xt_flix64_slot1_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 30) >> 30;
+ insn[0] = (insn[0] & ~0x30000) | (tie_t << 16);
+}
+
+static unsigned
+Field_combined3e2c5767_fld21xt_flix64_slot1_Slot_xt_flix64_slot1_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 5) | ((insn[0] << 14) >> 27);
+ return tie_t;
+}
+
+static void
+Field_combined3e2c5767_fld21xt_flix64_slot1_Slot_xt_flix64_slot1_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 27) >> 27;
+ insn[0] = (insn[0] & ~0x3e000) | (tie_t << 13);
+}
+
+static unsigned
+Field_combined3e2c5767_fld22xt_flix64_slot1_Slot_xt_flix64_slot1_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 6) | ((insn[0] << 14) >> 26);
+ return tie_t;
+}
+
+static void
+Field_combined3e2c5767_fld22xt_flix64_slot1_Slot_xt_flix64_slot1_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 26) >> 26;
+ insn[0] = (insn[0] & ~0x3f000) | (tie_t << 12);
+}
+
+static unsigned
+Field_combined3e2c5767_fld23xt_flix64_slot1_Slot_xt_flix64_slot1_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 6) | ((insn[0] << 14) >> 26);
+ tie_t = (tie_t << 3) | ((insn[0] << 25) >> 29);
+ return tie_t;
+}
+
+static void
+Field_combined3e2c5767_fld23xt_flix64_slot1_Slot_xt_flix64_slot1_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 29) >> 29;
+ insn[0] = (insn[0] & ~0x70) | (tie_t << 4);
+ tie_t = (val << 23) >> 26;
+ insn[0] = (insn[0] & ~0x3f000) | (tie_t << 12);
+}
+
+static unsigned
+Field_combined3e2c5767_fld25xt_flix64_slot1_Slot_xt_flix64_slot1_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 6) | ((insn[0] << 14) >> 26);
+ tie_t = (tie_t << 3) | ((insn[0] << 25) >> 29);
+ return tie_t;
+}
+
+static void
+Field_combined3e2c5767_fld25xt_flix64_slot1_Slot_xt_flix64_slot1_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 29) >> 29;
+ insn[0] = (insn[0] & ~0x70) | (tie_t << 4);
+ tie_t = (val << 23) >> 26;
+ insn[0] = (insn[0] & ~0x3f000) | (tie_t << 12);
+}
+
+static unsigned
+Field_combined3e2c5767_fld26xt_flix64_slot1_Slot_xt_flix64_slot1_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 6) | ((insn[0] << 14) >> 26);
+ tie_t = (tie_t << 2) | ((insn[0] << 25) >> 30);
+ return tie_t;
+}
+
+static void
+Field_combined3e2c5767_fld26xt_flix64_slot1_Slot_xt_flix64_slot1_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 30) >> 30;
+ insn[0] = (insn[0] & ~0x60) | (tie_t << 5);
+ tie_t = (val << 24) >> 26;
+ insn[0] = (insn[0] & ~0x3f000) | (tie_t << 12);
+}
+
+static unsigned
+Field_combined3e2c5767_fld28xt_flix64_slot1_Slot_xt_flix64_slot1_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 6) | ((insn[0] << 14) >> 26);
+ tie_t = (tie_t << 1) | ((insn[0] << 25) >> 31);
+ return tie_t;
+}
+
+static void
+Field_combined3e2c5767_fld28xt_flix64_slot1_Slot_xt_flix64_slot1_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 31) >> 31;
+ insn[0] = (insn[0] & ~0x40) | (tie_t << 6);
+ tie_t = (val << 25) >> 26;
+ insn[0] = (insn[0] & ~0x3f000) | (tie_t << 12);
+}
+
+static unsigned
+Field_combined3e2c5767_fld30xt_flix64_slot1_Slot_xt_flix64_slot1_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 6) | ((insn[0] << 14) >> 26);
+ tie_t = (tie_t << 2) | ((insn[0] << 22) >> 30);
+ return tie_t;
+}
+
+static void
+Field_combined3e2c5767_fld30xt_flix64_slot1_Slot_xt_flix64_slot1_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 30) >> 30;
+ insn[0] = (insn[0] & ~0x300) | (tie_t << 8);
+ tie_t = (val << 24) >> 26;
+ insn[0] = (insn[0] & ~0x3f000) | (tie_t << 12);
+}
+
+static unsigned
+Field_combined3e2c5767_fld32xt_flix64_slot1_Slot_xt_flix64_slot1_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 6) | ((insn[0] << 14) >> 26);
+ tie_t = (tie_t << 2) | ((insn[0] << 22) >> 30);
+ return tie_t;
+}
+
+static void
+Field_combined3e2c5767_fld32xt_flix64_slot1_Slot_xt_flix64_slot1_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 30) >> 30;
+ insn[0] = (insn[0] & ~0x300) | (tie_t << 8);
+ tie_t = (val << 24) >> 26;
+ insn[0] = (insn[0] & ~0x3f000) | (tie_t << 12);
+}
+
+static unsigned
+Field_combined3e2c5767_fld33xt_flix64_slot1_Slot_xt_flix64_slot1_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 6) | ((insn[0] << 14) >> 26);
+ tie_t = (tie_t << 1) | ((insn[0] << 22) >> 31);
+ return tie_t;
+}
+
+static void
+Field_combined3e2c5767_fld33xt_flix64_slot1_Slot_xt_flix64_slot1_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 31) >> 31;
+ insn[0] = (insn[0] & ~0x200) | (tie_t << 9);
+ tie_t = (val << 25) >> 26;
+ insn[0] = (insn[0] & ~0x3f000) | (tie_t << 12);
+}
+
+static unsigned
+Field_combined3e2c5767_fld35xt_flix64_slot1_Slot_xt_flix64_slot1_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 3) | ((insn[0] << 14) >> 29);
+ return tie_t;
+}
+
+static void
+Field_combined3e2c5767_fld35xt_flix64_slot1_Slot_xt_flix64_slot1_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 29) >> 29;
+ insn[0] = (insn[0] & ~0x38000) | (tie_t << 15);
+}
+
+static unsigned
+Field_combined3e2c5767_fld51xt_flix64_slot1_Slot_xt_flix64_slot1_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 1) | ((insn[0] << 24) >> 31);
+ return tie_t;
+}
+
+static void
+Field_combined3e2c5767_fld51xt_flix64_slot1_Slot_xt_flix64_slot1_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 31) >> 31;
+ insn[0] = (insn[0] & ~0x80) | (tie_t << 7);
+}
+
+static unsigned
+Field_combined3e2c5767_fld52xt_flix64_slot1_Slot_xt_flix64_slot1_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 1) | ((insn[0] << 24) >> 31);
+ tie_t = (tie_t << 4) | ((insn[0] << 28) >> 28);
+ return tie_t;
+}
+
+static void
+Field_combined3e2c5767_fld52xt_flix64_slot1_Slot_xt_flix64_slot1_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 28) >> 28;
+ insn[0] = (insn[0] & ~0xf) | (tie_t << 0);
+ tie_t = (val << 27) >> 31;
+ insn[0] = (insn[0] & ~0x80) | (tie_t << 7);
+}
+
+static unsigned
+Field_combined3e2c5767_fld53xt_flix64_slot1_Slot_xt_flix64_slot1_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 2) | ((insn[0] << 20) >> 30);
+ return tie_t;
+}
+
+static void
+Field_combined3e2c5767_fld53xt_flix64_slot1_Slot_xt_flix64_slot1_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 30) >> 30;
+ insn[0] = (insn[0] & ~0xc00) | (tie_t << 10);
+}
+
+static unsigned
+Field_combined3e2c5767_fld54xt_flix64_slot1_Slot_xt_flix64_slot1_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 5) | ((insn[0] << 20) >> 27);
+ tie_t = (tie_t << 6) | ((insn[0] << 26) >> 26);
+ return tie_t;
+}
+
+static void
+Field_combined3e2c5767_fld54xt_flix64_slot1_Slot_xt_flix64_slot1_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 26) >> 26;
+ insn[0] = (insn[0] & ~0x3f) | (tie_t << 0);
+ tie_t = (val << 21) >> 27;
+ insn[0] = (insn[0] & ~0xf80) | (tie_t << 7);
+}
+
+static unsigned
+Field_combined3e2c5767_fld57xt_flix64_slot1_Slot_xt_flix64_slot1_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 1) | ((insn[0] << 19) >> 31);
+ tie_t = (tie_t << 4) | ((insn[0] << 28) >> 28);
+ return tie_t;
+}
+
+static void
+Field_combined3e2c5767_fld57xt_flix64_slot1_Slot_xt_flix64_slot1_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 28) >> 28;
+ insn[0] = (insn[0] & ~0xf) | (tie_t << 0);
+ tie_t = (val << 27) >> 31;
+ insn[0] = (insn[0] & ~0x1000) | (tie_t << 12);
+}
+
+static unsigned
+Field_combined3e2c5767_fld58xt_flix64_slot1_Slot_xt_flix64_slot1_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 2) | ((insn[0] << 20) >> 30);
+ tie_t = (tie_t << 1) | ((insn[0] << 23) >> 31);
+ return tie_t;
+}
+
+static void
+Field_combined3e2c5767_fld58xt_flix64_slot1_Slot_xt_flix64_slot1_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 31) >> 31;
+ insn[0] = (insn[0] & ~0x100) | (tie_t << 8);
+ tie_t = (val << 29) >> 30;
+ insn[0] = (insn[0] & ~0xc00) | (tie_t << 10);
+}
+
+static unsigned
+Field_combined3e2c5767_fld60xt_flix64_slot1_Slot_xt_flix64_slot1_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 1) | ((insn[0] << 24) >> 31);
+ tie_t = (tie_t << 5) | ((insn[0] << 27) >> 27);
+ return tie_t;
+}
+
+static void
+Field_combined3e2c5767_fld60xt_flix64_slot1_Slot_xt_flix64_slot1_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 27) >> 27;
+ insn[0] = (insn[0] & ~0x1f) | (tie_t << 0);
+ tie_t = (val << 26) >> 31;
+ insn[0] = (insn[0] & ~0x80) | (tie_t << 7);
+}
+
+static unsigned
+Field_combined3e2c5767_fld62xt_flix64_slot1_Slot_xt_flix64_slot1_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 3) | ((insn[0] << 17) >> 29);
+ return tie_t;
+}
+
+static void
+Field_combined3e2c5767_fld62xt_flix64_slot1_Slot_xt_flix64_slot1_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 29) >> 29;
+ insn[0] = (insn[0] & ~0x7000) | (tie_t << 12);
+}
+
+static unsigned
+Field_op0_s5_Slot_xt_flix64_slot2_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 3) | ((insn[0] << 16) >> 29);
+ return tie_t;
+}
+
+static void
+Field_op0_s5_Slot_xt_flix64_slot2_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 29) >> 29;
+ insn[0] = (insn[0] & ~0xe000) | (tie_t << 13);
+}
+
+static unsigned
+Field_combined3e2c5767_fld36xt_flix64_slot2_Slot_xt_flix64_slot2_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 1) | ((insn[0] << 19) >> 31);
+ return tie_t;
+}
+
+static void
+Field_combined3e2c5767_fld36xt_flix64_slot2_Slot_xt_flix64_slot2_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 31) >> 31;
+ insn[0] = (insn[0] & ~0x1000) | (tie_t << 12);
+}
+
+static unsigned
+Field_combined3e2c5767_fld37xt_flix64_slot2_Slot_xt_flix64_slot2_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 1) | ((insn[0] << 19) >> 31);
+ tie_t = (tie_t << 1) | ((insn[0] << 24) >> 31);
+ return tie_t;
+}
+
+static void
+Field_combined3e2c5767_fld37xt_flix64_slot2_Slot_xt_flix64_slot2_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 31) >> 31;
+ insn[0] = (insn[0] & ~0x80) | (tie_t << 7);
+ tie_t = (val << 30) >> 31;
+ insn[0] = (insn[0] & ~0x1000) | (tie_t << 12);
+}
+
+static unsigned
+Field_combined3e2c5767_fld39xt_flix64_slot2_Slot_xt_flix64_slot2_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 1) | ((insn[0] << 19) >> 31);
+ tie_t = (tie_t << 1) | ((insn[0] << 24) >> 31);
+ tie_t = (tie_t << 1) | ((insn[0] << 27) >> 31);
+ return tie_t;
+}
+
+static void
+Field_combined3e2c5767_fld39xt_flix64_slot2_Slot_xt_flix64_slot2_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 31) >> 31;
+ insn[0] = (insn[0] & ~0x10) | (tie_t << 4);
+ tie_t = (val << 30) >> 31;
+ insn[0] = (insn[0] & ~0x80) | (tie_t << 7);
+ tie_t = (val << 29) >> 31;
+ insn[0] = (insn[0] & ~0x1000) | (tie_t << 12);
+}
+
+static unsigned
+Field_combined3e2c5767_fld41xt_flix64_slot2_Slot_xt_flix64_slot2_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 1) | ((insn[0] << 19) >> 31);
+ tie_t = (tie_t << 1) | ((insn[0] << 24) >> 31);
+ tie_t = (tie_t << 1) | ((insn[0] << 27) >> 31);
+ return tie_t;
+}
+
+static void
+Field_combined3e2c5767_fld41xt_flix64_slot2_Slot_xt_flix64_slot2_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 31) >> 31;
+ insn[0] = (insn[0] & ~0x10) | (tie_t << 4);
+ tie_t = (val << 30) >> 31;
+ insn[0] = (insn[0] & ~0x80) | (tie_t << 7);
+ tie_t = (val << 29) >> 31;
+ insn[0] = (insn[0] & ~0x1000) | (tie_t << 12);
+}
+
+static unsigned
+Field_combined3e2c5767_fld42xt_flix64_slot2_Slot_xt_flix64_slot2_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 1) | ((insn[0] << 19) >> 31);
+ tie_t = (tie_t << 3) | ((insn[0] << 21) >> 29);
+ return tie_t;
+}
+
+static void
+Field_combined3e2c5767_fld42xt_flix64_slot2_Slot_xt_flix64_slot2_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 29) >> 29;
+ insn[0] = (insn[0] & ~0x700) | (tie_t << 8);
+ tie_t = (val << 28) >> 31;
+ insn[0] = (insn[0] & ~0x1000) | (tie_t << 12);
+}
+
+static unsigned
+Field_combined3e2c5767_fld44xt_flix64_slot2_Slot_xt_flix64_slot2_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 1) | ((insn[0] << 19) >> 31);
+ tie_t = (tie_t << 3) | ((insn[0] << 21) >> 29);
+ return tie_t;
+}
+
+static void
+Field_combined3e2c5767_fld44xt_flix64_slot2_Slot_xt_flix64_slot2_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 29) >> 29;
+ insn[0] = (insn[0] & ~0x700) | (tie_t << 8);
+ tie_t = (val << 28) >> 31;
+ insn[0] = (insn[0] & ~0x1000) | (tie_t << 12);
+}
+
+static unsigned
+Field_combined3e2c5767_fld45xt_flix64_slot2_Slot_xt_flix64_slot2_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 1) | ((insn[0] << 19) >> 31);
+ tie_t = (tie_t << 2) | ((insn[0] << 21) >> 30);
+ return tie_t;
+}
+
+static void
+Field_combined3e2c5767_fld45xt_flix64_slot2_Slot_xt_flix64_slot2_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 30) >> 30;
+ insn[0] = (insn[0] & ~0x600) | (tie_t << 9);
+ tie_t = (val << 29) >> 31;
+ insn[0] = (insn[0] & ~0x1000) | (tie_t << 12);
+}
+
+static unsigned
+Field_combined3e2c5767_fld47xt_flix64_slot2_Slot_xt_flix64_slot2_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 1) | ((insn[0] << 19) >> 31);
+ tie_t = (tie_t << 1) | ((insn[0] << 21) >> 31);
+ return tie_t;
+}
+
+static void
+Field_combined3e2c5767_fld47xt_flix64_slot2_Slot_xt_flix64_slot2_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 31) >> 31;
+ insn[0] = (insn[0] & ~0x400) | (tie_t << 10);
+ tie_t = (val << 30) >> 31;
+ insn[0] = (insn[0] & ~0x1000) | (tie_t << 12);
+}
+
+static unsigned
+Field_combined3e2c5767_fld63xt_flix64_slot2_Slot_xt_flix64_slot2_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 2) | ((insn[0] << 25) >> 30);
+ return tie_t;
+}
+
+static void
+Field_combined3e2c5767_fld63xt_flix64_slot2_Slot_xt_flix64_slot2_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 30) >> 30;
+ insn[0] = (insn[0] & ~0x60) | (tie_t << 5);
+}
+
+static unsigned
+Field_combined3e2c5767_fld64xt_flix64_slot2_Slot_xt_flix64_slot2_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 1) | ((insn[0] << 20) >> 31);
+ return tie_t;
+}
+
+static void
+Field_combined3e2c5767_fld64xt_flix64_slot2_Slot_xt_flix64_slot2_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 31) >> 31;
+ insn[0] = (insn[0] & ~0x800) | (tie_t << 11);
+}
+
+static unsigned
+Field_combined3e2c5767_fld65xt_flix64_slot2_Slot_xt_flix64_slot2_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 4) | ((insn[0] << 20) >> 28);
+ tie_t = (tie_t << 2) | ((insn[0] << 25) >> 30);
+ tie_t = (tie_t << 4) | ((insn[0] << 28) >> 28);
+ return tie_t;
+}
+
+static void
+Field_combined3e2c5767_fld65xt_flix64_slot2_Slot_xt_flix64_slot2_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 28) >> 28;
+ insn[0] = (insn[0] & ~0xf) | (tie_t << 0);
+ tie_t = (val << 26) >> 30;
+ insn[0] = (insn[0] & ~0x60) | (tie_t << 5);
+ tie_t = (val << 22) >> 28;
+ insn[0] = (insn[0] & ~0xf00) | (tie_t << 8);
+}
+
+static unsigned
+Field_combined3e2c5767_fld66xt_flix64_slot2_Slot_xt_flix64_slot2_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 1) | ((insn[0] << 20) >> 31);
+ tie_t = (tie_t << 1) | ((insn[0] << 23) >> 31);
+ return tie_t;
+}
+
+static void
+Field_combined3e2c5767_fld66xt_flix64_slot2_Slot_xt_flix64_slot2_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 31) >> 31;
+ insn[0] = (insn[0] & ~0x100) | (tie_t << 8);
+ tie_t = (val << 30) >> 31;
+ insn[0] = (insn[0] & ~0x800) | (tie_t << 11);
+}
+
+static unsigned
+Field_combined3e2c5767_fld68xt_flix64_slot2_Slot_xt_flix64_slot2_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 1) | ((insn[0] << 20) >> 31);
+ tie_t = (tie_t << 2) | ((insn[0] << 22) >> 30);
+ return tie_t;
+}
+
+static void
+Field_combined3e2c5767_fld68xt_flix64_slot2_Slot_xt_flix64_slot2_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 30) >> 30;
+ insn[0] = (insn[0] & ~0x300) | (tie_t << 8);
+ tie_t = (val << 29) >> 31;
+ insn[0] = (insn[0] & ~0x800) | (tie_t << 11);
+}
+
+static unsigned
+Field_op0_s6_Slot_xt_flix64_slot3_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 5) | ((insn[0] << 0) >> 27);
+ return tie_t;
+}
+
+static void
+Field_op0_s6_Slot_xt_flix64_slot3_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 27) >> 27;
+ insn[0] = (insn[0] & ~0xf8000000) | (tie_t << 27);
+}
+
+static unsigned
+Field_combined3e2c5767_fld70xt_flix64_slot3_Slot_xt_flix64_slot3_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 3) | ((insn[1] << 29) >> 29);
+ tie_t = (tie_t << 1) | ((insn[0] << 5) >> 31);
+ tie_t = (tie_t << 4) | ((insn[0] << 28) >> 28);
+ return tie_t;
+}
+
+static void
+Field_combined3e2c5767_fld70xt_flix64_slot3_Slot_xt_flix64_slot3_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 28) >> 28;
+ insn[0] = (insn[0] & ~0xf) | (tie_t << 0);
+ tie_t = (val << 27) >> 31;
+ insn[0] = (insn[0] & ~0x4000000) | (tie_t << 26);
+ tie_t = (val << 24) >> 29;
+ insn[1] = (insn[1] & ~0x7) | (tie_t << 0);
+}
+
+static unsigned
+Field_combined3e2c5767_fld71_Slot_xt_flix64_slot3_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 3) | ((insn[1] << 29) >> 29);
+ return tie_t;
+}
+
+static void
+Field_combined3e2c5767_fld71_Slot_xt_flix64_slot3_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 29) >> 29;
+ insn[1] = (insn[1] & ~0x7) | (tie_t << 0);
+}
+
+static unsigned
+Field_combined3e2c5767_fld72xt_flix64_slot3_Slot_xt_flix64_slot3_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 3) | ((insn[1] << 29) >> 29);
+ tie_t = (tie_t << 1) | ((insn[0] << 5) >> 31);
+ tie_t = (tie_t << 4) | ((insn[0] << 28) >> 28);
+ return tie_t;
+}
+
+static void
+Field_combined3e2c5767_fld72xt_flix64_slot3_Slot_xt_flix64_slot3_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 28) >> 28;
+ insn[0] = (insn[0] & ~0xf) | (tie_t << 0);
+ tie_t = (val << 27) >> 31;
+ insn[0] = (insn[0] & ~0x4000000) | (tie_t << 26);
+ tie_t = (val << 24) >> 29;
+ insn[1] = (insn[1] & ~0x7) | (tie_t << 0);
+}
+
+static unsigned
+Field_combined3e2c5767_fld73xt_flix64_slot3_Slot_xt_flix64_slot3_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 3) | ((insn[1] << 29) >> 29);
+ tie_t = (tie_t << 1) | ((insn[0] << 5) >> 31);
+ tie_t = (tie_t << 4) | ((insn[0] << 28) >> 28);
+ return tie_t;
+}
+
+static void
+Field_combined3e2c5767_fld73xt_flix64_slot3_Slot_xt_flix64_slot3_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 28) >> 28;
+ insn[0] = (insn[0] & ~0xf) | (tie_t << 0);
+ tie_t = (val << 27) >> 31;
+ insn[0] = (insn[0] & ~0x4000000) | (tie_t << 26);
+ tie_t = (val << 24) >> 29;
+ insn[1] = (insn[1] & ~0x7) | (tie_t << 0);
+}
+
+static unsigned
+Field_combined3e2c5767_fld74xt_flix64_slot3_Slot_xt_flix64_slot3_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 3) | ((insn[1] << 29) >> 29);
+ tie_t = (tie_t << 1) | ((insn[0] << 5) >> 31);
+ tie_t = (tie_t << 4) | ((insn[0] << 28) >> 28);
+ return tie_t;
+}
+
+static void
+Field_combined3e2c5767_fld74xt_flix64_slot3_Slot_xt_flix64_slot3_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 28) >> 28;
+ insn[0] = (insn[0] & ~0xf) | (tie_t << 0);
+ tie_t = (val << 27) >> 31;
+ insn[0] = (insn[0] & ~0x4000000) | (tie_t << 26);
+ tie_t = (val << 24) >> 29;
+ insn[1] = (insn[1] & ~0x7) | (tie_t << 0);
+}
+
+static unsigned
+Field_combined3e2c5767_fld75xt_flix64_slot3_Slot_xt_flix64_slot3_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 3) | ((insn[1] << 29) >> 29);
+ tie_t = (tie_t << 1) | ((insn[0] << 5) >> 31);
+ return tie_t;
+}
+
+static void
+Field_combined3e2c5767_fld75xt_flix64_slot3_Slot_xt_flix64_slot3_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 31) >> 31;
+ insn[0] = (insn[0] & ~0x4000000) | (tie_t << 26);
+ tie_t = (val << 28) >> 29;
+ insn[1] = (insn[1] & ~0x7) | (tie_t << 0);
+}
+
+static unsigned
+Field_combined3e2c5767_fld76xt_flix64_slot3_Slot_xt_flix64_slot3_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 3) | ((insn[1] << 29) >> 29);
+ tie_t = (tie_t << 1) | ((insn[0] << 5) >> 31);
+ return tie_t;
+}
+
+static void
+Field_combined3e2c5767_fld76xt_flix64_slot3_Slot_xt_flix64_slot3_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 31) >> 31;
+ insn[0] = (insn[0] & ~0x4000000) | (tie_t << 26);
+ tie_t = (val << 28) >> 29;
+ insn[1] = (insn[1] & ~0x7) | (tie_t << 0);
+}
+
+static unsigned
+Field_combined3e2c5767_fld77xt_flix64_slot3_Slot_xt_flix64_slot3_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 3) | ((insn[1] << 29) >> 29);
+ tie_t = (tie_t << 1) | ((insn[0] << 5) >> 31);
+ return tie_t;
+}
+
+static void
+Field_combined3e2c5767_fld77xt_flix64_slot3_Slot_xt_flix64_slot3_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 31) >> 31;
+ insn[0] = (insn[0] & ~0x4000000) | (tie_t << 26);
+ tie_t = (val << 28) >> 29;
+ insn[1] = (insn[1] & ~0x7) | (tie_t << 0);
+}
+
+static unsigned
+Field_combined3e2c5767_fld78xt_flix64_slot3_Slot_xt_flix64_slot3_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 3) | ((insn[1] << 29) >> 29);
+ tie_t = (tie_t << 1) | ((insn[0] << 5) >> 31);
+ return tie_t;
+}
+
+static void
+Field_combined3e2c5767_fld78xt_flix64_slot3_Slot_xt_flix64_slot3_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 31) >> 31;
+ insn[0] = (insn[0] & ~0x4000000) | (tie_t << 26);
+ tie_t = (val << 28) >> 29;
+ insn[1] = (insn[1] & ~0x7) | (tie_t << 0);
+}
+
+static unsigned
+Field_combined3e2c5767_fld79xt_flix64_slot3_Slot_xt_flix64_slot3_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 3) | ((insn[1] << 29) >> 29);
+ tie_t = (tie_t << 1) | ((insn[0] << 5) >> 31);
+ return tie_t;
+}
+
+static void
+Field_combined3e2c5767_fld79xt_flix64_slot3_Slot_xt_flix64_slot3_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 31) >> 31;
+ insn[0] = (insn[0] & ~0x4000000) | (tie_t << 26);
+ tie_t = (val << 28) >> 29;
+ insn[1] = (insn[1] & ~0x7) | (tie_t << 0);
+}
+
+static unsigned
+Field_combined3e2c5767_fld80xt_flix64_slot3_Slot_xt_flix64_slot3_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 3) | ((insn[1] << 29) >> 29);
+ tie_t = (tie_t << 1) | ((insn[0] << 5) >> 31);
+ return tie_t;
+}
+
+static void
+Field_combined3e2c5767_fld80xt_flix64_slot3_Slot_xt_flix64_slot3_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 31) >> 31;
+ insn[0] = (insn[0] & ~0x4000000) | (tie_t << 26);
+ tie_t = (val << 28) >> 29;
+ insn[1] = (insn[1] & ~0x7) | (tie_t << 0);
+}
+
+static unsigned
+Field_combined3e2c5767_fld81xt_flix64_slot3_Slot_xt_flix64_slot3_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 3) | ((insn[1] << 29) >> 29);
+ tie_t = (tie_t << 1) | ((insn[0] << 5) >> 31);
+ return tie_t;
+}
+
+static void
+Field_combined3e2c5767_fld81xt_flix64_slot3_Slot_xt_flix64_slot3_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 31) >> 31;
+ insn[0] = (insn[0] & ~0x4000000) | (tie_t << 26);
+ tie_t = (val << 28) >> 29;
+ insn[1] = (insn[1] & ~0x7) | (tie_t << 0);
+}
+
+static unsigned
+Field_combined3e2c5767_fld82xt_flix64_slot3_Slot_xt_flix64_slot3_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 3) | ((insn[1] << 29) >> 29);
+ tie_t = (tie_t << 1) | ((insn[0] << 5) >> 31);
+ return tie_t;
+}
+
+static void
+Field_combined3e2c5767_fld82xt_flix64_slot3_Slot_xt_flix64_slot3_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 31) >> 31;
+ insn[0] = (insn[0] & ~0x4000000) | (tie_t << 26);
+ tie_t = (val << 28) >> 29;
+ insn[1] = (insn[1] & ~0x7) | (tie_t << 0);
+}
+
+static unsigned
+Field_combined3e2c5767_fld83xt_flix64_slot3_Slot_xt_flix64_slot3_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 3) | ((insn[1] << 29) >> 29);
+ tie_t = (tie_t << 1) | ((insn[0] << 5) >> 31);
+ return tie_t;
+}
+
+static void
+Field_combined3e2c5767_fld83xt_flix64_slot3_Slot_xt_flix64_slot3_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 31) >> 31;
+ insn[0] = (insn[0] & ~0x4000000) | (tie_t << 26);
+ tie_t = (val << 28) >> 29;
+ insn[1] = (insn[1] & ~0x7) | (tie_t << 0);
+}
+
+static unsigned
+Field_combined3e2c5767_fld84xt_flix64_slot3_Slot_xt_flix64_slot3_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 3) | ((insn[1] << 29) >> 29);
+ tie_t = (tie_t << 1) | ((insn[0] << 5) >> 31);
+ return tie_t;
+}
+
+static void
+Field_combined3e2c5767_fld84xt_flix64_slot3_Slot_xt_flix64_slot3_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 31) >> 31;
+ insn[0] = (insn[0] & ~0x4000000) | (tie_t << 26);
+ tie_t = (val << 28) >> 29;
+ insn[1] = (insn[1] & ~0x7) | (tie_t << 0);
+}
+
+static unsigned
+Field_combined3e2c5767_fld85xt_flix64_slot3_Slot_xt_flix64_slot3_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 3) | ((insn[1] << 29) >> 29);
+ tie_t = (tie_t << 1) | ((insn[0] << 5) >> 31);
+ return tie_t;
+}
+
+static void
+Field_combined3e2c5767_fld85xt_flix64_slot3_Slot_xt_flix64_slot3_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 31) >> 31;
+ insn[0] = (insn[0] & ~0x4000000) | (tie_t << 26);
+ tie_t = (val << 28) >> 29;
+ insn[1] = (insn[1] & ~0x7) | (tie_t << 0);
+}
+
+static unsigned
+Field_combined3e2c5767_fld86xt_flix64_slot3_Slot_xt_flix64_slot3_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 3) | ((insn[1] << 29) >> 29);
+ tie_t = (tie_t << 1) | ((insn[0] << 5) >> 31);
+ return tie_t;
+}
+
+static void
+Field_combined3e2c5767_fld86xt_flix64_slot3_Slot_xt_flix64_slot3_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 31) >> 31;
+ insn[0] = (insn[0] & ~0x4000000) | (tie_t << 26);
+ tie_t = (val << 28) >> 29;
+ insn[1] = (insn[1] & ~0x7) | (tie_t << 0);
+}
+
+static unsigned
+Field_combined3e2c5767_fld87xt_flix64_slot3_Slot_xt_flix64_slot3_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 3) | ((insn[1] << 29) >> 29);
+ tie_t = (tie_t << 1) | ((insn[0] << 5) >> 31);
+ return tie_t;
+}
+
+static void
+Field_combined3e2c5767_fld87xt_flix64_slot3_Slot_xt_flix64_slot3_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 31) >> 31;
+ insn[0] = (insn[0] & ~0x4000000) | (tie_t << 26);
+ tie_t = (val << 28) >> 29;
+ insn[1] = (insn[1] & ~0x7) | (tie_t << 0);
+}
+
+static unsigned
+Field_combined3e2c5767_fld88xt_flix64_slot3_Slot_xt_flix64_slot3_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 3) | ((insn[1] << 29) >> 29);
+ tie_t = (tie_t << 1) | ((insn[0] << 5) >> 31);
+ return tie_t;
+}
+
+static void
+Field_combined3e2c5767_fld88xt_flix64_slot3_Slot_xt_flix64_slot3_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 31) >> 31;
+ insn[0] = (insn[0] & ~0x4000000) | (tie_t << 26);
+ tie_t = (val << 28) >> 29;
+ insn[1] = (insn[1] & ~0x7) | (tie_t << 0);
+}
+
+static unsigned
+Field_combined3e2c5767_fld89xt_flix64_slot3_Slot_xt_flix64_slot3_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 3) | ((insn[1] << 29) >> 29);
+ tie_t = (tie_t << 1) | ((insn[0] << 5) >> 31);
+ return tie_t;
+}
+
+static void
+Field_combined3e2c5767_fld89xt_flix64_slot3_Slot_xt_flix64_slot3_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 31) >> 31;
+ insn[0] = (insn[0] & ~0x4000000) | (tie_t << 26);
+ tie_t = (val << 28) >> 29;
+ insn[1] = (insn[1] & ~0x7) | (tie_t << 0);
+}
+
+static unsigned
+Field_combined3e2c5767_fld90xt_flix64_slot3_Slot_xt_flix64_slot3_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 3) | ((insn[1] << 29) >> 29);
+ tie_t = (tie_t << 1) | ((insn[0] << 5) >> 31);
+ return tie_t;
+}
+
+static void
+Field_combined3e2c5767_fld90xt_flix64_slot3_Slot_xt_flix64_slot3_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 31) >> 31;
+ insn[0] = (insn[0] & ~0x4000000) | (tie_t << 26);
+ tie_t = (val << 28) >> 29;
+ insn[1] = (insn[1] & ~0x7) | (tie_t << 0);
+}
+
+static unsigned
+Field_combined3e2c5767_fld91xt_flix64_slot3_Slot_xt_flix64_slot3_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 3) | ((insn[1] << 29) >> 29);
+ tie_t = (tie_t << 1) | ((insn[0] << 5) >> 31);
+ return tie_t;
+}
+
+static void
+Field_combined3e2c5767_fld91xt_flix64_slot3_Slot_xt_flix64_slot3_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 31) >> 31;
+ insn[0] = (insn[0] & ~0x4000000) | (tie_t << 26);
+ tie_t = (val << 28) >> 29;
+ insn[1] = (insn[1] & ~0x7) | (tie_t << 0);
+}
+
+static unsigned
+Field_combined3e2c5767_fld92xt_flix64_slot3_Slot_xt_flix64_slot3_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 3) | ((insn[1] << 29) >> 29);
+ tie_t = (tie_t << 1) | ((insn[0] << 5) >> 31);
+ return tie_t;
+}
+
+static void
+Field_combined3e2c5767_fld92xt_flix64_slot3_Slot_xt_flix64_slot3_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 31) >> 31;
+ insn[0] = (insn[0] & ~0x4000000) | (tie_t << 26);
+ tie_t = (val << 28) >> 29;
+ insn[1] = (insn[1] & ~0x7) | (tie_t << 0);
+}
+
+static unsigned
+Field_combined3e2c5767_fld93xt_flix64_slot3_Slot_xt_flix64_slot3_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 3) | ((insn[1] << 29) >> 29);
+ tie_t = (tie_t << 27) | ((insn[0] << 5) >> 5);
+ return tie_t;
+}
+
+static void
+Field_combined3e2c5767_fld93xt_flix64_slot3_Slot_xt_flix64_slot3_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 5) >> 5;
+ insn[0] = (insn[0] & ~0x7ffffff) | (tie_t << 0);
+ tie_t = (val << 2) >> 29;
+ insn[1] = (insn[1] & ~0x7) | (tie_t << 0);
+}
+
+static unsigned
+Field_op0_xt_flix64_slot0_Slot_xt_flix64_slot0_get (const xtensa_insnbuf insn)
+{
+ unsigned tie_t = 0;
+ tie_t = (tie_t << 4) | ((insn[0] << 8) >> 28);
+ return tie_t;
+}
+
+static void
+Field_op0_xt_flix64_slot0_Slot_xt_flix64_slot0_set (xtensa_insnbuf insn, uint32 val)
+{
+ uint32 tie_t;
+ tie_t = (val << 28) >> 28;
+ insn[0] = (insn[0] & ~0xf00000) | (tie_t << 20);
+}
+
+static void
+Implicit_Field_set (xtensa_insnbuf insn ATTRIBUTE_UNUSED,
+ uint32 val ATTRIBUTE_UNUSED)
+{
+ /* Do nothing. */
+}
+
+static unsigned
+Implicit_Field_ar0_get (const xtensa_insnbuf insn ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+static unsigned
+Implicit_Field_ar4_get (const xtensa_insnbuf insn ATTRIBUTE_UNUSED)
+{
+ return 4;
+}
+
+static unsigned
+Implicit_Field_ar8_get (const xtensa_insnbuf insn ATTRIBUTE_UNUSED)
+{
+ return 8;
+}
+
+static unsigned
+Implicit_Field_ar12_get (const xtensa_insnbuf insn ATTRIBUTE_UNUSED)
+{
+ return 12;
+}
+
+static unsigned
+Implicit_Field_mr0_get (const xtensa_insnbuf insn ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+static unsigned
+Implicit_Field_mr1_get (const xtensa_insnbuf insn ATTRIBUTE_UNUSED)
+{
+ return 1;
+}
+
+static unsigned
+Implicit_Field_mr2_get (const xtensa_insnbuf insn ATTRIBUTE_UNUSED)
+{
+ return 2;
+}
+
+static unsigned
+Implicit_Field_mr3_get (const xtensa_insnbuf insn ATTRIBUTE_UNUSED)
+{
+ return 3;
+}
+
+static unsigned
+Implicit_Field_bt16_get (const xtensa_insnbuf insn ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+static unsigned
+Implicit_Field_bs16_get (const xtensa_insnbuf insn ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+static unsigned
+Implicit_Field_br16_get (const xtensa_insnbuf insn ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+static unsigned
+Implicit_Field_brall_get (const xtensa_insnbuf insn ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+
+/* Functional units. */
+
+static xtensa_funcUnit_internal funcUnits[] = {
+
+};
+
+
+/* Register files. */
+
+static xtensa_regfile_internal regfiles[] = {
+ { "AR", "a", 0, 32, 64 },
+ { "MR", "m", 1, 32, 4 },
+ { "BR", "b", 2, 1, 16 },
+ { "FR", "f", 3, 32, 16 },
+ { "BR2", "b", 2, 2, 8 },
+ { "BR4", "b", 2, 4, 4 },
+ { "BR8", "b", 2, 8, 2 },
+ { "BR16", "b", 2, 16, 1 }
+};
+
+
+/* Interfaces. */
+
+static xtensa_interface_internal interfaces[] = {
+
+};
+
+
+/* Constant tables. */
+
+/* constant table ai4c */
+static const unsigned CONST_TBL_ai4c_0[] = {
+ 0xffffffff,
+ 0x1,
+ 0x2,
+ 0x3,
+ 0x4,
+ 0x5,
+ 0x6,
+ 0x7,
+ 0x8,
+ 0x9,
+ 0xa,
+ 0xb,
+ 0xc,
+ 0xd,
+ 0xe,
+ 0xf,
+ 0
+};
+
+/* constant table b4c */
+static const unsigned CONST_TBL_b4c_0[] = {
+ 0xffffffff,
+ 0x1,
+ 0x2,
+ 0x3,
+ 0x4,
+ 0x5,
+ 0x6,
+ 0x7,
+ 0x8,
+ 0xa,
+ 0xc,
+ 0x10,
+ 0x20,
+ 0x40,
+ 0x80,
+ 0x100,
+ 0
+};
+
+/* constant table b4cu */
+static const unsigned CONST_TBL_b4cu_0[] = {
+ 0x8000,
+ 0x10000,
+ 0x2,
+ 0x3,
+ 0x4,
+ 0x5,
+ 0x6,
+ 0x7,
+ 0x8,
+ 0xa,
+ 0xc,
+ 0x10,
+ 0x20,
+ 0x40,
+ 0x80,
+ 0x100,
+ 0
+};
+
+
+/* Instruction operands. */
+
+static int
+Operand_soffsetx4_decode (uint32 *valp)
+{
+ unsigned soffsetx4_0, offset_0;
+ offset_0 = *valp & 0x3ffff;
+ soffsetx4_0 = 0x4 + ((((int) offset_0 << 14) >> 14) << 2);
+ *valp = soffsetx4_0;
+ return 0;
+}
+
+static int
+Operand_soffsetx4_encode (uint32 *valp)
+{
+ unsigned offset_0, soffsetx4_0;
+ soffsetx4_0 = *valp;
+ offset_0 = ((soffsetx4_0 - 0x4) >> 2) & 0x3ffff;
+ *valp = offset_0;
+ return 0;
+}
+
+static int
+Operand_soffsetx4_ator (uint32 *valp, uint32 pc)
+{
+ *valp -= (pc & ~0x3);
+ return 0;
+}
+
+static int
+Operand_soffsetx4_rtoa (uint32 *valp, uint32 pc)
+{
+ *valp += (pc & ~0x3);
+ return 0;
+}
+
+static int
+Operand_uimm12x8_decode (uint32 *valp)
+{
+ unsigned uimm12x8_0, imm12_0;
+ imm12_0 = *valp & 0xfff;
+ uimm12x8_0 = imm12_0 << 3;
+ *valp = uimm12x8_0;
+ return 0;
+}
+
+static int
+Operand_uimm12x8_encode (uint32 *valp)
+{
+ unsigned imm12_0, uimm12x8_0;
+ uimm12x8_0 = *valp;
+ imm12_0 = ((uimm12x8_0 >> 3) & 0xfff);
+ *valp = imm12_0;
+ return 0;
+}
+
+static int
+Operand_simm4_decode (uint32 *valp)
+{
+ unsigned simm4_0, mn_0;
+ mn_0 = *valp & 0xf;
+ simm4_0 = ((int) mn_0 << 28) >> 28;
+ *valp = simm4_0;
+ return 0;
+}
+
+static int
+Operand_simm4_encode (uint32 *valp)
+{
+ unsigned mn_0, simm4_0;
+ simm4_0 = *valp;
+ mn_0 = (simm4_0 & 0xf);
+ *valp = mn_0;
+ return 0;
+}
+
+static int
+Operand_arr_decode (uint32 *valp ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+static int
+Operand_arr_encode (uint32 *valp)
+{
+ int error;
+ error = (*valp & ~0xf) != 0;
+ return error;
+}
+
+static int
+Operand_ars_decode (uint32 *valp ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+static int
+Operand_ars_encode (uint32 *valp)
+{
+ int error;
+ error = (*valp & ~0xf) != 0;
+ return error;
+}
+
+static int
+Operand_art_decode (uint32 *valp ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+static int
+Operand_art_encode (uint32 *valp)
+{
+ int error;
+ error = (*valp & ~0xf) != 0;
+ return error;
+}
+
+static int
+Operand_ar0_decode (uint32 *valp ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+static int
+Operand_ar0_encode (uint32 *valp)
+{
+ int error;
+ error = (*valp & ~0x3f) != 0;
+ return error;
+}
+
+static int
+Operand_ar4_decode (uint32 *valp ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+static int
+Operand_ar4_encode (uint32 *valp)
+{
+ int error;
+ error = (*valp & ~0x3f) != 0;
+ return error;
+}
+
+static int
+Operand_ar8_decode (uint32 *valp ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+static int
+Operand_ar8_encode (uint32 *valp)
+{
+ int error;
+ error = (*valp & ~0x3f) != 0;
+ return error;
+}
+
+static int
+Operand_ar12_decode (uint32 *valp ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+static int
+Operand_ar12_encode (uint32 *valp)
+{
+ int error;
+ error = (*valp & ~0x3f) != 0;
+ return error;
+}
+
+static int
+Operand_ars_entry_decode (uint32 *valp ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+static int
+Operand_ars_entry_encode (uint32 *valp)
+{
+ int error;
+ error = (*valp & ~0x3f) != 0;
+ return error;
+}
+
+static int
+Operand_immrx4_decode (uint32 *valp)
+{
+ unsigned immrx4_0, r_0;
+ r_0 = *valp & 0xf;
+ immrx4_0 = (((0xfffffff) << 4) | r_0) << 2;
+ *valp = immrx4_0;
+ return 0;
+}
+
+static int
+Operand_immrx4_encode (uint32 *valp)
+{
+ unsigned r_0, immrx4_0;
+ immrx4_0 = *valp;
+ r_0 = ((immrx4_0 >> 2) & 0xf);
+ *valp = r_0;
+ return 0;
+}
+
+static int
+Operand_lsi4x4_decode (uint32 *valp)
+{
+ unsigned lsi4x4_0, r_0;
+ r_0 = *valp & 0xf;
+ lsi4x4_0 = r_0 << 2;
+ *valp = lsi4x4_0;
+ return 0;
+}
+
+static int
+Operand_lsi4x4_encode (uint32 *valp)
+{
+ unsigned r_0, lsi4x4_0;
+ lsi4x4_0 = *valp;
+ r_0 = ((lsi4x4_0 >> 2) & 0xf);
+ *valp = r_0;
+ return 0;
+}
+
+static int
+Operand_simm7_decode (uint32 *valp)
+{
+ unsigned simm7_0, imm7_0;
+ imm7_0 = *valp & 0x7f;
+ simm7_0 = ((((-((((imm7_0 >> 6) & 1)) & (((imm7_0 >> 5) & 1)))) & 0x1ffffff)) << 7) | imm7_0;
+ *valp = simm7_0;
+ return 0;
+}
+
+static int
+Operand_simm7_encode (uint32 *valp)
+{
+ unsigned imm7_0, simm7_0;
+ simm7_0 = *valp;
+ imm7_0 = (simm7_0 & 0x7f);
+ *valp = imm7_0;
+ return 0;
+}
+
+static int
+Operand_uimm6_decode (uint32 *valp)
+{
+ unsigned uimm6_0, imm6_0;
+ imm6_0 = *valp & 0x3f;
+ uimm6_0 = 0x4 + (((0) << 6) | imm6_0);
+ *valp = uimm6_0;
+ return 0;
+}
+
+static int
+Operand_uimm6_encode (uint32 *valp)
+{
+ unsigned imm6_0, uimm6_0;
+ uimm6_0 = *valp;
+ imm6_0 = (uimm6_0 - 0x4) & 0x3f;
+ *valp = imm6_0;
+ return 0;
+}
+
+static int
+Operand_uimm6_ator (uint32 *valp, uint32 pc)
+{
+ *valp -= pc;
+ return 0;
+}
+
+static int
+Operand_uimm6_rtoa (uint32 *valp, uint32 pc)
+{
+ *valp += pc;
+ return 0;
+}
+
+static int
+Operand_ai4const_decode (uint32 *valp)
+{
+ unsigned ai4const_0, t_0;
+ t_0 = *valp & 0xf;
+ ai4const_0 = CONST_TBL_ai4c_0[t_0 & 0xf];
+ *valp = ai4const_0;
+ return 0;
+}
+
+static int
+Operand_ai4const_encode (uint32 *valp)
+{
+ unsigned t_0, ai4const_0;
+ ai4const_0 = *valp;
+ switch (ai4const_0)
+ {
+ case 0xffffffff: t_0 = 0; break;
+ case 0x1: t_0 = 0x1; break;
+ case 0x2: t_0 = 0x2; break;
+ case 0x3: t_0 = 0x3; break;
+ case 0x4: t_0 = 0x4; break;
+ case 0x5: t_0 = 0x5; break;
+ case 0x6: t_0 = 0x6; break;
+ case 0x7: t_0 = 0x7; break;
+ case 0x8: t_0 = 0x8; break;
+ case 0x9: t_0 = 0x9; break;
+ case 0xa: t_0 = 0xa; break;
+ case 0xb: t_0 = 0xb; break;
+ case 0xc: t_0 = 0xc; break;
+ case 0xd: t_0 = 0xd; break;
+ case 0xe: t_0 = 0xe; break;
+ default: t_0 = 0xf; break;
+ }
+ *valp = t_0;
+ return 0;
+}
+
+static int
+Operand_b4const_decode (uint32 *valp)
+{
+ unsigned b4const_0, r_0;
+ r_0 = *valp & 0xf;
+ b4const_0 = CONST_TBL_b4c_0[r_0 & 0xf];
+ *valp = b4const_0;
+ return 0;
+}
+
+static int
+Operand_b4const_encode (uint32 *valp)
+{
+ unsigned r_0, b4const_0;
+ b4const_0 = *valp;
+ switch (b4const_0)
+ {
+ case 0xffffffff: r_0 = 0; break;
+ case 0x1: r_0 = 0x1; break;
+ case 0x2: r_0 = 0x2; break;
+ case 0x3: r_0 = 0x3; break;
+ case 0x4: r_0 = 0x4; break;
+ case 0x5: r_0 = 0x5; break;
+ case 0x6: r_0 = 0x6; break;
+ case 0x7: r_0 = 0x7; break;
+ case 0x8: r_0 = 0x8; break;
+ case 0xa: r_0 = 0x9; break;
+ case 0xc: r_0 = 0xa; break;
+ case 0x10: r_0 = 0xb; break;
+ case 0x20: r_0 = 0xc; break;
+ case 0x40: r_0 = 0xd; break;
+ case 0x80: r_0 = 0xe; break;
+ default: r_0 = 0xf; break;
+ }
+ *valp = r_0;
+ return 0;
+}
+
+static int
+Operand_b4constu_decode (uint32 *valp)
+{
+ unsigned b4constu_0, r_0;
+ r_0 = *valp & 0xf;
+ b4constu_0 = CONST_TBL_b4cu_0[r_0 & 0xf];
+ *valp = b4constu_0;
+ return 0;
+}
+
+static int
+Operand_b4constu_encode (uint32 *valp)
+{
+ unsigned r_0, b4constu_0;
+ b4constu_0 = *valp;
+ switch (b4constu_0)
+ {
+ case 0x8000: r_0 = 0; break;
+ case 0x10000: r_0 = 0x1; break;
+ case 0x2: r_0 = 0x2; break;
+ case 0x3: r_0 = 0x3; break;
+ case 0x4: r_0 = 0x4; break;
+ case 0x5: r_0 = 0x5; break;
+ case 0x6: r_0 = 0x6; break;
+ case 0x7: r_0 = 0x7; break;
+ case 0x8: r_0 = 0x8; break;
+ case 0xa: r_0 = 0x9; break;
+ case 0xc: r_0 = 0xa; break;
+ case 0x10: r_0 = 0xb; break;
+ case 0x20: r_0 = 0xc; break;
+ case 0x40: r_0 = 0xd; break;
+ case 0x80: r_0 = 0xe; break;
+ default: r_0 = 0xf; break;
+ }
+ *valp = r_0;
+ return 0;
+}
+
+static int
+Operand_uimm8_decode (uint32 *valp)
+{
+ unsigned uimm8_0, imm8_0;
+ imm8_0 = *valp & 0xff;
+ uimm8_0 = imm8_0;
+ *valp = uimm8_0;
+ return 0;
+}
+
+static int
+Operand_uimm8_encode (uint32 *valp)
+{
+ unsigned imm8_0, uimm8_0;
+ uimm8_0 = *valp;
+ imm8_0 = (uimm8_0 & 0xff);
+ *valp = imm8_0;
+ return 0;
+}
+
+static int
+Operand_uimm8x2_decode (uint32 *valp)
+{
+ unsigned uimm8x2_0, imm8_0;
+ imm8_0 = *valp & 0xff;
+ uimm8x2_0 = imm8_0 << 1;
+ *valp = uimm8x2_0;
+ return 0;
+}
+
+static int
+Operand_uimm8x2_encode (uint32 *valp)
+{
+ unsigned imm8_0, uimm8x2_0;
+ uimm8x2_0 = *valp;
+ imm8_0 = ((uimm8x2_0 >> 1) & 0xff);
+ *valp = imm8_0;
+ return 0;
+}
+
+static int
+Operand_uimm8x4_decode (uint32 *valp)
+{
+ unsigned uimm8x4_0, imm8_0;
+ imm8_0 = *valp & 0xff;
+ uimm8x4_0 = imm8_0 << 2;
+ *valp = uimm8x4_0;
+ return 0;
+}
+
+static int
+Operand_uimm8x4_encode (uint32 *valp)
+{
+ unsigned imm8_0, uimm8x4_0;
+ uimm8x4_0 = *valp;
+ imm8_0 = ((uimm8x4_0 >> 2) & 0xff);
+ *valp = imm8_0;
+ return 0;
+}
+
+static int
+Operand_uimm4x16_decode (uint32 *valp)
+{
+ unsigned uimm4x16_0, op2_0;
+ op2_0 = *valp & 0xf;
+ uimm4x16_0 = op2_0 << 4;
+ *valp = uimm4x16_0;
+ return 0;
+}
+
+static int
+Operand_uimm4x16_encode (uint32 *valp)
+{
+ unsigned op2_0, uimm4x16_0;
+ uimm4x16_0 = *valp;
+ op2_0 = ((uimm4x16_0 >> 4) & 0xf);
+ *valp = op2_0;
+ return 0;
+}
+
+static int
+Operand_simm8_decode (uint32 *valp)
+{
+ unsigned simm8_0, imm8_0;
+ imm8_0 = *valp & 0xff;
+ simm8_0 = ((int) imm8_0 << 24) >> 24;
+ *valp = simm8_0;
+ return 0;
+}
+
+static int
+Operand_simm8_encode (uint32 *valp)
+{
+ unsigned imm8_0, simm8_0;
+ simm8_0 = *valp;
+ imm8_0 = (simm8_0 & 0xff);
+ *valp = imm8_0;
+ return 0;
+}
+
+static int
+Operand_simm8x256_decode (uint32 *valp)
+{
+ unsigned simm8x256_0, imm8_0;
+ imm8_0 = *valp & 0xff;
+ simm8x256_0 = (((int) imm8_0 << 24) >> 24) << 8;
+ *valp = simm8x256_0;
+ return 0;
+}
+
+static int
+Operand_simm8x256_encode (uint32 *valp)
+{
+ unsigned imm8_0, simm8x256_0;
+ simm8x256_0 = *valp;
+ imm8_0 = ((simm8x256_0 >> 8) & 0xff);
+ *valp = imm8_0;
+ return 0;
+}
+
+static int
+Operand_simm12b_decode (uint32 *valp)
+{
+ unsigned simm12b_0, imm12b_0;
+ imm12b_0 = *valp & 0xfff;
+ simm12b_0 = ((int) imm12b_0 << 20) >> 20;
+ *valp = simm12b_0;
+ return 0;
+}
+
+static int
+Operand_simm12b_encode (uint32 *valp)
+{
+ unsigned imm12b_0, simm12b_0;
+ simm12b_0 = *valp;
+ imm12b_0 = (simm12b_0 & 0xfff);
+ *valp = imm12b_0;
+ return 0;
+}
+
+static int
+Operand_msalp32_decode (uint32 *valp)
+{
+ unsigned msalp32_0, sal_0;
+ sal_0 = *valp & 0x1f;
+ msalp32_0 = 0x20 - sal_0;
+ *valp = msalp32_0;
+ return 0;
+}
+
+static int
+Operand_msalp32_encode (uint32 *valp)
+{
+ unsigned sal_0, msalp32_0;
+ msalp32_0 = *valp;
+ sal_0 = (0x20 - msalp32_0) & 0x1f;
+ *valp = sal_0;
+ return 0;
+}
+
+static int
+Operand_op2p1_decode (uint32 *valp)
+{
+ unsigned op2p1_0, op2_0;
+ op2_0 = *valp & 0xf;
+ op2p1_0 = op2_0 + 0x1;
+ *valp = op2p1_0;
+ return 0;
+}
+
+static int
+Operand_op2p1_encode (uint32 *valp)
+{
+ unsigned op2_0, op2p1_0;
+ op2p1_0 = *valp;
+ op2_0 = (op2p1_0 - 0x1) & 0xf;
+ *valp = op2_0;
+ return 0;
+}
+
+static int
+Operand_label8_decode (uint32 *valp)
+{
+ unsigned label8_0, imm8_0;
+ imm8_0 = *valp & 0xff;
+ label8_0 = 0x4 + (((int) imm8_0 << 24) >> 24);
+ *valp = label8_0;
+ return 0;
+}
+
+static int
+Operand_label8_encode (uint32 *valp)
+{
+ unsigned imm8_0, label8_0;
+ label8_0 = *valp;
+ imm8_0 = (label8_0 - 0x4) & 0xff;
+ *valp = imm8_0;
+ return 0;
+}
+
+static int
+Operand_label8_ator (uint32 *valp, uint32 pc)
+{
+ *valp -= pc;
+ return 0;
+}
+
+static int
+Operand_label8_rtoa (uint32 *valp, uint32 pc)
+{
+ *valp += pc;
+ return 0;
+}
+
+static int
+Operand_ulabel8_decode (uint32 *valp)
+{
+ unsigned ulabel8_0, imm8_0;
+ imm8_0 = *valp & 0xff;
+ ulabel8_0 = 0x4 + (((0) << 8) | imm8_0);
+ *valp = ulabel8_0;
+ return 0;
+}
+
+static int
+Operand_ulabel8_encode (uint32 *valp)
+{
+ unsigned imm8_0, ulabel8_0;
+ ulabel8_0 = *valp;
+ imm8_0 = (ulabel8_0 - 0x4) & 0xff;
+ *valp = imm8_0;
+ return 0;
+}
+
+static int
+Operand_ulabel8_ator (uint32 *valp, uint32 pc)
+{
+ *valp -= pc;
+ return 0;
+}
+
+static int
+Operand_ulabel8_rtoa (uint32 *valp, uint32 pc)
+{
+ *valp += pc;
+ return 0;
+}
+
+static int
+Operand_label12_decode (uint32 *valp)
+{
+ unsigned label12_0, imm12_0;
+ imm12_0 = *valp & 0xfff;
+ label12_0 = 0x4 + (((int) imm12_0 << 20) >> 20);
+ *valp = label12_0;
+ return 0;
+}
+
+static int
+Operand_label12_encode (uint32 *valp)
+{
+ unsigned imm12_0, label12_0;
+ label12_0 = *valp;
+ imm12_0 = (label12_0 - 0x4) & 0xfff;
+ *valp = imm12_0;
+ return 0;
+}
+
+static int
+Operand_label12_ator (uint32 *valp, uint32 pc)
+{
+ *valp -= pc;
+ return 0;
+}
+
+static int
+Operand_label12_rtoa (uint32 *valp, uint32 pc)
+{
+ *valp += pc;
+ return 0;
+}
+
+static int
+Operand_soffset_decode (uint32 *valp)
+{
+ unsigned soffset_0, offset_0;
+ offset_0 = *valp & 0x3ffff;
+ soffset_0 = 0x4 + (((int) offset_0 << 14) >> 14);
+ *valp = soffset_0;
+ return 0;
+}
+
+static int
+Operand_soffset_encode (uint32 *valp)
+{
+ unsigned offset_0, soffset_0;
+ soffset_0 = *valp;
+ offset_0 = (soffset_0 - 0x4) & 0x3ffff;
+ *valp = offset_0;
+ return 0;
+}
+
+static int
+Operand_soffset_ator (uint32 *valp, uint32 pc)
+{
+ *valp -= pc;
+ return 0;
+}
+
+static int
+Operand_soffset_rtoa (uint32 *valp, uint32 pc)
+{
+ *valp += pc;
+ return 0;
+}
+
+static int
+Operand_uimm16x4_decode (uint32 *valp)
+{
+ unsigned uimm16x4_0, imm16_0;
+ imm16_0 = *valp & 0xffff;
+ uimm16x4_0 = (((0xffff) << 16) | imm16_0) << 2;
+ *valp = uimm16x4_0;
+ return 0;
+}
+
+static int
+Operand_uimm16x4_encode (uint32 *valp)
+{
+ unsigned imm16_0, uimm16x4_0;
+ uimm16x4_0 = *valp;
+ imm16_0 = (uimm16x4_0 >> 2) & 0xffff;
+ *valp = imm16_0;
+ return 0;
+}
+
+static int
+Operand_uimm16x4_ator (uint32 *valp, uint32 pc)
+{
+ *valp -= ((pc + 3) & ~0x3);
+ return 0;
+}
+
+static int
+Operand_uimm16x4_rtoa (uint32 *valp, uint32 pc)
+{
+ *valp += ((pc + 3) & ~0x3);
+ return 0;
+}
+
+static int
+Operand_mx_decode (uint32 *valp ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+static int
+Operand_mx_encode (uint32 *valp)
+{
+ int error;
+ error = (*valp & ~0x3) != 0;
+ return error;
+}
+
+static int
+Operand_my_decode (uint32 *valp)
+{
+ *valp += 2;
+ return 0;
+}
+
+static int
+Operand_my_encode (uint32 *valp)
+{
+ int error;
+ error = ((*valp & ~0x3) != 0) || ((*valp & 0x2) == 0);
+ *valp = *valp & 1;
+ return error;
+}
+
+static int
+Operand_mw_decode (uint32 *valp ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+static int
+Operand_mw_encode (uint32 *valp)
+{
+ int error;
+ error = (*valp & ~0x3) != 0;
+ return error;
+}
+
+static int
+Operand_mr0_decode (uint32 *valp ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+static int
+Operand_mr0_encode (uint32 *valp)
+{
+ int error;
+ error = (*valp & ~0x3) != 0;
+ return error;
+}
+
+static int
+Operand_mr1_decode (uint32 *valp ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+static int
+Operand_mr1_encode (uint32 *valp)
+{
+ int error;
+ error = (*valp & ~0x3) != 0;
+ return error;
+}
+
+static int
+Operand_mr2_decode (uint32 *valp ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+static int
+Operand_mr2_encode (uint32 *valp)
+{
+ int error;
+ error = (*valp & ~0x3) != 0;
+ return error;
+}
+
+static int
+Operand_mr3_decode (uint32 *valp ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+static int
+Operand_mr3_encode (uint32 *valp)
+{
+ int error;
+ error = (*valp & ~0x3) != 0;
+ return error;
+}
+
+static int
+Operand_immt_decode (uint32 *valp)
+{
+ unsigned immt_0, t_0;
+ t_0 = *valp & 0xf;
+ immt_0 = t_0;
+ *valp = immt_0;
+ return 0;
+}
+
+static int
+Operand_immt_encode (uint32 *valp)
+{
+ unsigned t_0, immt_0;
+ immt_0 = *valp;
+ t_0 = immt_0 & 0xf;
+ *valp = t_0;
+ return 0;
+}
+
+static int
+Operand_imms_decode (uint32 *valp)
+{
+ unsigned imms_0, s_0;
+ s_0 = *valp & 0xf;
+ imms_0 = s_0;
+ *valp = imms_0;
+ return 0;
+}
+
+static int
+Operand_imms_encode (uint32 *valp)
+{
+ unsigned s_0, imms_0;
+ imms_0 = *valp;
+ s_0 = imms_0 & 0xf;
+ *valp = s_0;
+ return 0;
+}
+
+static int
+Operand_bt_decode (uint32 *valp ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+static int
+Operand_bt_encode (uint32 *valp)
+{
+ int error;
+ error = (*valp & ~0xf) != 0;
+ return error;
+}
+
+static int
+Operand_bs_decode (uint32 *valp ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+static int
+Operand_bs_encode (uint32 *valp)
+{
+ int error;
+ error = (*valp & ~0xf) != 0;
+ return error;
+}
+
+static int
+Operand_br_decode (uint32 *valp ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+static int
+Operand_br_encode (uint32 *valp)
+{
+ int error;
+ error = (*valp & ~0xf) != 0;
+ return error;
+}
+
+static int
+Operand_bt2_decode (uint32 *valp)
+{
+ *valp = *valp << 1;
+ return 0;
+}
+
+static int
+Operand_bt2_encode (uint32 *valp)
+{
+ int error;
+ error = (*valp & ~(0x7 << 1)) != 0;
+ *valp = *valp >> 1;
+ return error;
+}
+
+static int
+Operand_bs2_decode (uint32 *valp)
+{
+ *valp = *valp << 1;
+ return 0;
+}
+
+static int
+Operand_bs2_encode (uint32 *valp)
+{
+ int error;
+ error = (*valp & ~(0x7 << 1)) != 0;
+ *valp = *valp >> 1;
+ return error;
+}
+
+static int
+Operand_br2_decode (uint32 *valp)
+{
+ *valp = *valp << 1;
+ return 0;
+}
+
+static int
+Operand_br2_encode (uint32 *valp)
+{
+ int error;
+ error = (*valp & ~(0x7 << 1)) != 0;
+ *valp = *valp >> 1;
+ return error;
+}
+
+static int
+Operand_bt4_decode (uint32 *valp)
+{
+ *valp = *valp << 2;
+ return 0;
+}
+
+static int
+Operand_bt4_encode (uint32 *valp)
+{
+ int error;
+ error = (*valp & ~(0x3 << 2)) != 0;
+ *valp = *valp >> 2;
+ return error;
+}
+
+static int
+Operand_bs4_decode (uint32 *valp)
+{
+ *valp = *valp << 2;
+ return 0;
+}
+
+static int
+Operand_bs4_encode (uint32 *valp)
+{
+ int error;
+ error = (*valp & ~(0x3 << 2)) != 0;
+ *valp = *valp >> 2;
+ return error;
+}
+
+static int
+Operand_br4_decode (uint32 *valp)
+{
+ *valp = *valp << 2;
+ return 0;
+}
+
+static int
+Operand_br4_encode (uint32 *valp)
+{
+ int error;
+ error = (*valp & ~(0x3 << 2)) != 0;
+ *valp = *valp >> 2;
+ return error;
+}
+
+static int
+Operand_bt8_decode (uint32 *valp)
+{
+ *valp = *valp << 3;
+ return 0;
+}
+
+static int
+Operand_bt8_encode (uint32 *valp)
+{
+ int error;
+ error = (*valp & ~(0x1 << 3)) != 0;
+ *valp = *valp >> 3;
+ return error;
+}
+
+static int
+Operand_bs8_decode (uint32 *valp)
+{
+ *valp = *valp << 3;
+ return 0;
+}
+
+static int
+Operand_bs8_encode (uint32 *valp)
+{
+ int error;
+ error = (*valp & ~(0x1 << 3)) != 0;
+ *valp = *valp >> 3;
+ return error;
+}
+
+static int
+Operand_br8_decode (uint32 *valp)
+{
+ *valp = *valp << 3;
+ return 0;
+}
+
+static int
+Operand_br8_encode (uint32 *valp)
+{
+ int error;
+ error = (*valp & ~(0x1 << 3)) != 0;
+ *valp = *valp >> 3;
+ return error;
+}
+
+static int
+Operand_bt16_decode (uint32 *valp)
+{
+ *valp = *valp << 4;
+ return 0;
+}
+
+static int
+Operand_bt16_encode (uint32 *valp)
+{
+ int error;
+ error = (*valp & ~(0 << 4)) != 0;
+ *valp = *valp >> 4;
+ return error;
+}
+
+static int
+Operand_bs16_decode (uint32 *valp)
+{
+ *valp = *valp << 4;
+ return 0;
+}
+
+static int
+Operand_bs16_encode (uint32 *valp)
+{
+ int error;
+ error = (*valp & ~(0 << 4)) != 0;
+ *valp = *valp >> 4;
+ return error;
+}
+
+static int
+Operand_br16_decode (uint32 *valp)
+{
+ *valp = *valp << 4;
+ return 0;
+}
+
+static int
+Operand_br16_encode (uint32 *valp)
+{
+ int error;
+ error = (*valp & ~(0 << 4)) != 0;
+ *valp = *valp >> 4;
+ return error;
+}
+
+static int
+Operand_brall_decode (uint32 *valp)
+{
+ *valp = *valp << 4;
+ return 0;
+}
+
+static int
+Operand_brall_encode (uint32 *valp)
+{
+ int error;
+ error = (*valp & ~(0 << 4)) != 0;
+ *valp = *valp >> 4;
+ return error;
+}
+
+static int
+Operand_tp7_decode (uint32 *valp)
+{
+ unsigned tp7_0, t_0;
+ t_0 = *valp & 0xf;
+ tp7_0 = t_0 + 0x7;
+ *valp = tp7_0;
+ return 0;
+}
+
+static int
+Operand_tp7_encode (uint32 *valp)
+{
+ unsigned t_0, tp7_0;
+ tp7_0 = *valp;
+ t_0 = (tp7_0 - 0x7) & 0xf;
+ *valp = t_0;
+ return 0;
+}
+
+static int
+Operand_xt_wbr15_label_decode (uint32 *valp)
+{
+ unsigned xt_wbr15_label_0, xt_wbr15_imm_0;
+ xt_wbr15_imm_0 = *valp & 0x7fff;
+ xt_wbr15_label_0 = 0x4 + (((int) xt_wbr15_imm_0 << 17) >> 17);
+ *valp = xt_wbr15_label_0;
+ return 0;
+}
+
+static int
+Operand_xt_wbr15_label_encode (uint32 *valp)
+{
+ unsigned xt_wbr15_imm_0, xt_wbr15_label_0;
+ xt_wbr15_label_0 = *valp;
+ xt_wbr15_imm_0 = (xt_wbr15_label_0 - 0x4) & 0x7fff;
+ *valp = xt_wbr15_imm_0;
+ return 0;
+}
+
+static int
+Operand_xt_wbr15_label_ator (uint32 *valp, uint32 pc)
+{
+ *valp -= pc;
+ return 0;
+}
+
+static int
+Operand_xt_wbr15_label_rtoa (uint32 *valp, uint32 pc)
+{
+ *valp += pc;
+ return 0;
+}
+
+static int
+Operand_xt_wbr18_label_decode (uint32 *valp)
+{
+ unsigned xt_wbr18_label_0, xt_wbr18_imm_0;
+ xt_wbr18_imm_0 = *valp & 0x3ffff;
+ xt_wbr18_label_0 = 0x4 + (((int) xt_wbr18_imm_0 << 14) >> 14);
+ *valp = xt_wbr18_label_0;
+ return 0;
+}
+
+static int
+Operand_xt_wbr18_label_encode (uint32 *valp)
+{
+ unsigned xt_wbr18_imm_0, xt_wbr18_label_0;
+ xt_wbr18_label_0 = *valp;
+ xt_wbr18_imm_0 = (xt_wbr18_label_0 - 0x4) & 0x3ffff;
+ *valp = xt_wbr18_imm_0;
+ return 0;
+}
+
+static int
+Operand_xt_wbr18_label_ator (uint32 *valp, uint32 pc)
+{
+ *valp -= pc;
+ return 0;
+}
+
+static int
+Operand_xt_wbr18_label_rtoa (uint32 *valp, uint32 pc)
+{
+ *valp += pc;
+ return 0;
+}
+
+static int
+Operand_cimm8x4_decode (uint32 *valp)
+{
+ unsigned cimm8x4_0, imm8_0;
+ imm8_0 = *valp & 0xff;
+ cimm8x4_0 = (imm8_0 << 2) | 0;
+ *valp = cimm8x4_0;
+ return 0;
+}
+
+static int
+Operand_cimm8x4_encode (uint32 *valp)
+{
+ unsigned imm8_0, cimm8x4_0;
+ cimm8x4_0 = *valp;
+ imm8_0 = (cimm8x4_0 >> 2) & 0xff;
+ *valp = imm8_0;
+ return 0;
+}
+
+static int
+Operand_frr_decode (uint32 *valp ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+static int
+Operand_frr_encode (uint32 *valp)
+{
+ int error;
+ error = (*valp & ~0xf) != 0;
+ return error;
+}
+
+static int
+Operand_frs_decode (uint32 *valp ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+static int
+Operand_frs_encode (uint32 *valp)
+{
+ int error;
+ error = (*valp & ~0xf) != 0;
+ return error;
+}
+
+static int
+Operand_frt_decode (uint32 *valp ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+static int
+Operand_frt_encode (uint32 *valp)
+{
+ int error;
+ error = (*valp & ~0xf) != 0;
+ return error;
+}
+
+static xtensa_operand_internal operands[] = {
+ { "soffsetx4", 10, -1, 0,
+ XTENSA_OPERAND_IS_PCRELATIVE,
+ Operand_soffsetx4_encode, Operand_soffsetx4_decode,
+ Operand_soffsetx4_ator, Operand_soffsetx4_rtoa },
+ { "uimm12x8", 3, -1, 0,
+ 0,
+ Operand_uimm12x8_encode, Operand_uimm12x8_decode,
+ 0, 0 },
+ { "simm4", 26, -1, 0,
+ 0,
+ Operand_simm4_encode, Operand_simm4_decode,
+ 0, 0 },
+ { "arr", 14, 0, 1,
+ XTENSA_OPERAND_IS_REGISTER,
+ Operand_arr_encode, Operand_arr_decode,
+ 0, 0 },
+ { "ars", 5, 0, 1,
+ XTENSA_OPERAND_IS_REGISTER,
+ Operand_ars_encode, Operand_ars_decode,
+ 0, 0 },
+ { "*ars_invisible", 5, 0, 1,
+ XTENSA_OPERAND_IS_REGISTER | XTENSA_OPERAND_IS_INVISIBLE,
+ Operand_ars_encode, Operand_ars_decode,
+ 0, 0 },
+ { "art", 0, 0, 1,
+ XTENSA_OPERAND_IS_REGISTER,
+ Operand_art_encode, Operand_art_decode,
+ 0, 0 },
+ { "ar0", 123, 0, 1,
+ XTENSA_OPERAND_IS_REGISTER | XTENSA_OPERAND_IS_INVISIBLE,
+ Operand_ar0_encode, Operand_ar0_decode,
+ 0, 0 },
+ { "ar4", 124, 0, 1,
+ XTENSA_OPERAND_IS_REGISTER | XTENSA_OPERAND_IS_INVISIBLE,
+ Operand_ar4_encode, Operand_ar4_decode,
+ 0, 0 },
+ { "ar8", 125, 0, 1,
+ XTENSA_OPERAND_IS_REGISTER | XTENSA_OPERAND_IS_INVISIBLE,
+ Operand_ar8_encode, Operand_ar8_decode,
+ 0, 0 },
+ { "ar12", 126, 0, 1,
+ XTENSA_OPERAND_IS_REGISTER | XTENSA_OPERAND_IS_INVISIBLE,
+ Operand_ar12_encode, Operand_ar12_decode,
+ 0, 0 },
+ { "ars_entry", 5, 0, 1,
+ XTENSA_OPERAND_IS_REGISTER,
+ Operand_ars_entry_encode, Operand_ars_entry_decode,
+ 0, 0 },
+ { "immrx4", 14, -1, 0,
+ 0,
+ Operand_immrx4_encode, Operand_immrx4_decode,
+ 0, 0 },
+ { "lsi4x4", 14, -1, 0,
+ 0,
+ Operand_lsi4x4_encode, Operand_lsi4x4_decode,
+ 0, 0 },
+ { "simm7", 34, -1, 0,
+ 0,
+ Operand_simm7_encode, Operand_simm7_decode,
+ 0, 0 },
+ { "uimm6", 33, -1, 0,
+ XTENSA_OPERAND_IS_PCRELATIVE,
+ Operand_uimm6_encode, Operand_uimm6_decode,
+ Operand_uimm6_ator, Operand_uimm6_rtoa },
+ { "ai4const", 0, -1, 0,
+ 0,
+ Operand_ai4const_encode, Operand_ai4const_decode,
+ 0, 0 },
+ { "b4const", 14, -1, 0,
+ 0,
+ Operand_b4const_encode, Operand_b4const_decode,
+ 0, 0 },
+ { "b4constu", 14, -1, 0,
+ 0,
+ Operand_b4constu_encode, Operand_b4constu_decode,
+ 0, 0 },
+ { "uimm8", 4, -1, 0,
+ 0,
+ Operand_uimm8_encode, Operand_uimm8_decode,
+ 0, 0 },
+ { "uimm8x2", 4, -1, 0,
+ 0,
+ Operand_uimm8x2_encode, Operand_uimm8x2_decode,
+ 0, 0 },
+ { "uimm8x4", 4, -1, 0,
+ 0,
+ Operand_uimm8x4_encode, Operand_uimm8x4_decode,
+ 0, 0 },
+ { "uimm4x16", 13, -1, 0,
+ 0,
+ Operand_uimm4x16_encode, Operand_uimm4x16_decode,
+ 0, 0 },
+ { "simm8", 4, -1, 0,
+ 0,
+ Operand_simm8_encode, Operand_simm8_decode,
+ 0, 0 },
+ { "simm8x256", 4, -1, 0,
+ 0,
+ Operand_simm8x256_encode, Operand_simm8x256_decode,
+ 0, 0 },
+ { "simm12b", 6, -1, 0,
+ 0,
+ Operand_simm12b_encode, Operand_simm12b_decode,
+ 0, 0 },
+ { "msalp32", 18, -1, 0,
+ 0,
+ Operand_msalp32_encode, Operand_msalp32_decode,
+ 0, 0 },
+ { "op2p1", 13, -1, 0,
+ 0,
+ Operand_op2p1_encode, Operand_op2p1_decode,
+ 0, 0 },
+ { "label8", 4, -1, 0,
+ XTENSA_OPERAND_IS_PCRELATIVE,
+ Operand_label8_encode, Operand_label8_decode,
+ Operand_label8_ator, Operand_label8_rtoa },
+ { "ulabel8", 4, -1, 0,
+ XTENSA_OPERAND_IS_PCRELATIVE,
+ Operand_ulabel8_encode, Operand_ulabel8_decode,
+ Operand_ulabel8_ator, Operand_ulabel8_rtoa },
+ { "label12", 3, -1, 0,
+ XTENSA_OPERAND_IS_PCRELATIVE,
+ Operand_label12_encode, Operand_label12_decode,
+ Operand_label12_ator, Operand_label12_rtoa },
+ { "soffset", 10, -1, 0,
+ XTENSA_OPERAND_IS_PCRELATIVE,
+ Operand_soffset_encode, Operand_soffset_decode,
+ Operand_soffset_ator, Operand_soffset_rtoa },
+ { "uimm16x4", 7, -1, 0,
+ XTENSA_OPERAND_IS_PCRELATIVE,
+ Operand_uimm16x4_encode, Operand_uimm16x4_decode,
+ Operand_uimm16x4_ator, Operand_uimm16x4_rtoa },
+ { "mx", 43, 1, 1,
+ XTENSA_OPERAND_IS_REGISTER | XTENSA_OPERAND_IS_UNKNOWN,
+ Operand_mx_encode, Operand_mx_decode,
+ 0, 0 },
+ { "my", 42, 1, 1,
+ XTENSA_OPERAND_IS_REGISTER | XTENSA_OPERAND_IS_UNKNOWN,
+ Operand_my_encode, Operand_my_decode,
+ 0, 0 },
+ { "mw", 41, 1, 1,
+ XTENSA_OPERAND_IS_REGISTER,
+ Operand_mw_encode, Operand_mw_decode,
+ 0, 0 },
+ { "mr0", 127, 1, 1,
+ XTENSA_OPERAND_IS_REGISTER | XTENSA_OPERAND_IS_INVISIBLE,
+ Operand_mr0_encode, Operand_mr0_decode,
+ 0, 0 },
+ { "mr1", 128, 1, 1,
+ XTENSA_OPERAND_IS_REGISTER | XTENSA_OPERAND_IS_INVISIBLE,
+ Operand_mr1_encode, Operand_mr1_decode,
+ 0, 0 },
+ { "mr2", 129, 1, 1,
+ XTENSA_OPERAND_IS_REGISTER | XTENSA_OPERAND_IS_INVISIBLE,
+ Operand_mr2_encode, Operand_mr2_decode,
+ 0, 0 },
+ { "mr3", 130, 1, 1,
+ XTENSA_OPERAND_IS_REGISTER | XTENSA_OPERAND_IS_INVISIBLE,
+ Operand_mr3_encode, Operand_mr3_decode,
+ 0, 0 },
+ { "immt", 0, -1, 0,
+ 0,
+ Operand_immt_encode, Operand_immt_decode,
+ 0, 0 },
+ { "imms", 5, -1, 0,
+ 0,
+ Operand_imms_encode, Operand_imms_decode,
+ 0, 0 },
+ { "bt", 0, 2, 1,
+ XTENSA_OPERAND_IS_REGISTER,
+ Operand_bt_encode, Operand_bt_decode,
+ 0, 0 },
+ { "bs", 5, 2, 1,
+ XTENSA_OPERAND_IS_REGISTER,
+ Operand_bs_encode, Operand_bs_decode,
+ 0, 0 },
+ { "br", 14, 2, 1,
+ XTENSA_OPERAND_IS_REGISTER,
+ Operand_br_encode, Operand_br_decode,
+ 0, 0 },
+ { "bt2", 44, 2, 2,
+ XTENSA_OPERAND_IS_REGISTER,
+ Operand_bt2_encode, Operand_bt2_decode,
+ 0, 0 },
+ { "bs2", 45, 2, 2,
+ XTENSA_OPERAND_IS_REGISTER,
+ Operand_bs2_encode, Operand_bs2_decode,
+ 0, 0 },
+ { "br2", 46, 2, 2,
+ XTENSA_OPERAND_IS_REGISTER,
+ Operand_br2_encode, Operand_br2_decode,
+ 0, 0 },
+ { "bt4", 47, 2, 4,
+ XTENSA_OPERAND_IS_REGISTER,
+ Operand_bt4_encode, Operand_bt4_decode,
+ 0, 0 },
+ { "bs4", 48, 2, 4,
+ XTENSA_OPERAND_IS_REGISTER,
+ Operand_bs4_encode, Operand_bs4_decode,
+ 0, 0 },
+ { "br4", 49, 2, 4,
+ XTENSA_OPERAND_IS_REGISTER,
+ Operand_br4_encode, Operand_br4_decode,
+ 0, 0 },
+ { "bt8", 50, 2, 8,
+ XTENSA_OPERAND_IS_REGISTER,
+ Operand_bt8_encode, Operand_bt8_decode,
+ 0, 0 },
+ { "bs8", 51, 2, 8,
+ XTENSA_OPERAND_IS_REGISTER,
+ Operand_bs8_encode, Operand_bs8_decode,
+ 0, 0 },
+ { "br8", 52, 2, 8,
+ XTENSA_OPERAND_IS_REGISTER,
+ Operand_br8_encode, Operand_br8_decode,
+ 0, 0 },
+ { "bt16", 131, 2, 16,
+ XTENSA_OPERAND_IS_REGISTER,
+ Operand_bt16_encode, Operand_bt16_decode,
+ 0, 0 },
+ { "bs16", 132, 2, 16,
+ XTENSA_OPERAND_IS_REGISTER,
+ Operand_bs16_encode, Operand_bs16_decode,
+ 0, 0 },
+ { "br16", 133, 2, 16,
+ XTENSA_OPERAND_IS_REGISTER,
+ Operand_br16_encode, Operand_br16_decode,
+ 0, 0 },
+ { "brall", 134, 2, 16,
+ XTENSA_OPERAND_IS_REGISTER | XTENSA_OPERAND_IS_INVISIBLE,
+ Operand_brall_encode, Operand_brall_decode,
+ 0, 0 },
+ { "tp7", 0, -1, 0,
+ 0,
+ Operand_tp7_encode, Operand_tp7_decode,
+ 0, 0 },
+ { "xt_wbr15_label", 53, -1, 0,
+ XTENSA_OPERAND_IS_PCRELATIVE,
+ Operand_xt_wbr15_label_encode, Operand_xt_wbr15_label_decode,
+ Operand_xt_wbr15_label_ator, Operand_xt_wbr15_label_rtoa },
+ { "xt_wbr18_label", 54, -1, 0,
+ XTENSA_OPERAND_IS_PCRELATIVE,
+ Operand_xt_wbr18_label_encode, Operand_xt_wbr18_label_decode,
+ Operand_xt_wbr18_label_ator, Operand_xt_wbr18_label_rtoa },
+ { "cimm8x4", 4, -1, 0,
+ 0,
+ Operand_cimm8x4_encode, Operand_cimm8x4_decode,
+ 0, 0 },
+ { "frr", 14, 3, 1,
+ XTENSA_OPERAND_IS_REGISTER,
+ Operand_frr_encode, Operand_frr_decode,
+ 0, 0 },
+ { "frs", 5, 3, 1,
+ XTENSA_OPERAND_IS_REGISTER,
+ Operand_frs_encode, Operand_frs_decode,
+ 0, 0 },
+ { "frt", 0, 3, 1,
+ XTENSA_OPERAND_IS_REGISTER,
+ Operand_frt_encode, Operand_frt_decode,
+ 0, 0 },
+ { "t", 0, -1, 0, 0, 0, 0, 0, 0 },
+ { "bbi4", 1, -1, 0, 0, 0, 0, 0, 0 },
+ { "bbi", 2, -1, 0, 0, 0, 0, 0, 0 },
+ { "imm12", 3, -1, 0, 0, 0, 0, 0, 0 },
+ { "imm8", 4, -1, 0, 0, 0, 0, 0, 0 },
+ { "s", 5, -1, 0, 0, 0, 0, 0, 0 },
+ { "imm12b", 6, -1, 0, 0, 0, 0, 0, 0 },
+ { "imm16", 7, -1, 0, 0, 0, 0, 0, 0 },
+ { "m", 8, -1, 0, 0, 0, 0, 0, 0 },
+ { "n", 9, -1, 0, 0, 0, 0, 0, 0 },
+ { "offset", 10, -1, 0, 0, 0, 0, 0, 0 },
+ { "op0", 11, -1, 0, 0, 0, 0, 0, 0 },
+ { "op1", 12, -1, 0, 0, 0, 0, 0, 0 },
+ { "op2", 13, -1, 0, 0, 0, 0, 0, 0 },
+ { "r", 14, -1, 0, 0, 0, 0, 0, 0 },
+ { "sa4", 15, -1, 0, 0, 0, 0, 0, 0 },
+ { "sae4", 16, -1, 0, 0, 0, 0, 0, 0 },
+ { "sae", 17, -1, 0, 0, 0, 0, 0, 0 },
+ { "sal", 18, -1, 0, 0, 0, 0, 0, 0 },
+ { "sargt", 19, -1, 0, 0, 0, 0, 0, 0 },
+ { "sas4", 20, -1, 0, 0, 0, 0, 0, 0 },
+ { "sas", 21, -1, 0, 0, 0, 0, 0, 0 },
+ { "sr", 22, -1, 0, 0, 0, 0, 0, 0 },
+ { "st", 23, -1, 0, 0, 0, 0, 0, 0 },
+ { "thi3", 24, -1, 0, 0, 0, 0, 0, 0 },
+ { "imm4", 25, -1, 0, 0, 0, 0, 0, 0 },
+ { "mn", 26, -1, 0, 0, 0, 0, 0, 0 },
+ { "i", 27, -1, 0, 0, 0, 0, 0, 0 },
+ { "imm6lo", 28, -1, 0, 0, 0, 0, 0, 0 },
+ { "imm6hi", 29, -1, 0, 0, 0, 0, 0, 0 },
+ { "imm7lo", 30, -1, 0, 0, 0, 0, 0, 0 },
+ { "imm7hi", 31, -1, 0, 0, 0, 0, 0, 0 },
+ { "z", 32, -1, 0, 0, 0, 0, 0, 0 },
+ { "imm6", 33, -1, 0, 0, 0, 0, 0, 0 },
+ { "imm7", 34, -1, 0, 0, 0, 0, 0, 0 },
+ { "r3", 35, -1, 0, 0, 0, 0, 0, 0 },
+ { "rbit2", 36, -1, 0, 0, 0, 0, 0, 0 },
+ { "rhi", 37, -1, 0, 0, 0, 0, 0, 0 },
+ { "t3", 38, -1, 0, 0, 0, 0, 0, 0 },
+ { "tbit2", 39, -1, 0, 0, 0, 0, 0, 0 },
+ { "tlo", 40, -1, 0, 0, 0, 0, 0, 0 },
+ { "w", 41, -1, 0, 0, 0, 0, 0, 0 },
+ { "y", 42, -1, 0, 0, 0, 0, 0, 0 },
+ { "x", 43, -1, 0, 0, 0, 0, 0, 0 },
+ { "t2", 44, -1, 0, 0, 0, 0, 0, 0 },
+ { "s2", 45, -1, 0, 0, 0, 0, 0, 0 },
+ { "r2", 46, -1, 0, 0, 0, 0, 0, 0 },
+ { "t4", 47, -1, 0, 0, 0, 0, 0, 0 },
+ { "s4", 48, -1, 0, 0, 0, 0, 0, 0 },
+ { "r4", 49, -1, 0, 0, 0, 0, 0, 0 },
+ { "t8", 50, -1, 0, 0, 0, 0, 0, 0 },
+ { "s8", 51, -1, 0, 0, 0, 0, 0, 0 },
+ { "r8", 52, -1, 0, 0, 0, 0, 0, 0 },
+ { "xt_wbr15_imm", 53, -1, 0, 0, 0, 0, 0, 0 },
+ { "xt_wbr18_imm", 54, -1, 0, 0, 0, 0, 0, 0 },
+ { "op0_xt_flix64_slot0_s3", 55, -1, 0, 0, 0, 0, 0, 0 },
+ { "combined3e2c5767_fld7", 56, -1, 0, 0, 0, 0, 0, 0 },
+ { "combined3e2c5767_fld8", 57, -1, 0, 0, 0, 0, 0, 0 },
+ { "combined3e2c5767_fld9", 58, -1, 0, 0, 0, 0, 0, 0 },
+ { "combined3e2c5767_fld11", 59, -1, 0, 0, 0, 0, 0, 0 },
+ { "combined3e2c5767_fld49xt_flix64_slot0", 60, -1, 0, 0, 0, 0, 0, 0 },
+ { "op0_s4", 61, -1, 0, 0, 0, 0, 0, 0 },
+ { "combined3e2c5767_fld16", 62, -1, 0, 0, 0, 0, 0, 0 },
+ { "combined3e2c5767_fld19xt_flix64_slot1", 63, -1, 0, 0, 0, 0, 0, 0 },
+ { "combined3e2c5767_fld20xt_flix64_slot1", 64, -1, 0, 0, 0, 0, 0, 0 },
+ { "combined3e2c5767_fld21xt_flix64_slot1", 65, -1, 0, 0, 0, 0, 0, 0 },
+ { "combined3e2c5767_fld22xt_flix64_slot1", 66, -1, 0, 0, 0, 0, 0, 0 },
+ { "combined3e2c5767_fld23xt_flix64_slot1", 67, -1, 0, 0, 0, 0, 0, 0 },
+ { "combined3e2c5767_fld25xt_flix64_slot1", 68, -1, 0, 0, 0, 0, 0, 0 },
+ { "combined3e2c5767_fld26xt_flix64_slot1", 69, -1, 0, 0, 0, 0, 0, 0 },
+ { "combined3e2c5767_fld28xt_flix64_slot1", 70, -1, 0, 0, 0, 0, 0, 0 },
+ { "combined3e2c5767_fld30xt_flix64_slot1", 71, -1, 0, 0, 0, 0, 0, 0 },
+ { "combined3e2c5767_fld32xt_flix64_slot1", 72, -1, 0, 0, 0, 0, 0, 0 },
+ { "combined3e2c5767_fld33xt_flix64_slot1", 73, -1, 0, 0, 0, 0, 0, 0 },
+ { "combined3e2c5767_fld35xt_flix64_slot1", 74, -1, 0, 0, 0, 0, 0, 0 },
+ { "combined3e2c5767_fld51xt_flix64_slot1", 75, -1, 0, 0, 0, 0, 0, 0 },
+ { "combined3e2c5767_fld52xt_flix64_slot1", 76, -1, 0, 0, 0, 0, 0, 0 },
+ { "combined3e2c5767_fld53xt_flix64_slot1", 77, -1, 0, 0, 0, 0, 0, 0 },
+ { "combined3e2c5767_fld54xt_flix64_slot1", 78, -1, 0, 0, 0, 0, 0, 0 },
+ { "combined3e2c5767_fld57xt_flix64_slot1", 79, -1, 0, 0, 0, 0, 0, 0 },
+ { "combined3e2c5767_fld58xt_flix64_slot1", 80, -1, 0, 0, 0, 0, 0, 0 },
+ { "combined3e2c5767_fld60xt_flix64_slot1", 81, -1, 0, 0, 0, 0, 0, 0 },
+ { "combined3e2c5767_fld62xt_flix64_slot1", 82, -1, 0, 0, 0, 0, 0, 0 },
+ { "op0_s5", 83, -1, 0, 0, 0, 0, 0, 0 },
+ { "combined3e2c5767_fld36xt_flix64_slot2", 84, -1, 0, 0, 0, 0, 0, 0 },
+ { "combined3e2c5767_fld37xt_flix64_slot2", 85, -1, 0, 0, 0, 0, 0, 0 },
+ { "combined3e2c5767_fld39xt_flix64_slot2", 86, -1, 0, 0, 0, 0, 0, 0 },
+ { "combined3e2c5767_fld41xt_flix64_slot2", 87, -1, 0, 0, 0, 0, 0, 0 },
+ { "combined3e2c5767_fld42xt_flix64_slot2", 88, -1, 0, 0, 0, 0, 0, 0 },
+ { "combined3e2c5767_fld44xt_flix64_slot2", 89, -1, 0, 0, 0, 0, 0, 0 },
+ { "combined3e2c5767_fld45xt_flix64_slot2", 90, -1, 0, 0, 0, 0, 0, 0 },
+ { "combined3e2c5767_fld47xt_flix64_slot2", 91, -1, 0, 0, 0, 0, 0, 0 },
+ { "combined3e2c5767_fld63xt_flix64_slot2", 92, -1, 0, 0, 0, 0, 0, 0 },
+ { "combined3e2c5767_fld64xt_flix64_slot2", 93, -1, 0, 0, 0, 0, 0, 0 },
+ { "combined3e2c5767_fld65xt_flix64_slot2", 94, -1, 0, 0, 0, 0, 0, 0 },
+ { "combined3e2c5767_fld66xt_flix64_slot2", 95, -1, 0, 0, 0, 0, 0, 0 },
+ { "combined3e2c5767_fld68xt_flix64_slot2", 96, -1, 0, 0, 0, 0, 0, 0 },
+ { "op0_s6", 97, -1, 0, 0, 0, 0, 0, 0 },
+ { "combined3e2c5767_fld70xt_flix64_slot3", 98, -1, 0, 0, 0, 0, 0, 0 },
+ { "combined3e2c5767_fld71", 99, -1, 0, 0, 0, 0, 0, 0 },
+ { "combined3e2c5767_fld72xt_flix64_slot3", 100, -1, 0, 0, 0, 0, 0, 0 },
+ { "combined3e2c5767_fld73xt_flix64_slot3", 101, -1, 0, 0, 0, 0, 0, 0 },
+ { "combined3e2c5767_fld74xt_flix64_slot3", 102, -1, 0, 0, 0, 0, 0, 0 },
+ { "combined3e2c5767_fld75xt_flix64_slot3", 103, -1, 0, 0, 0, 0, 0, 0 },
+ { "combined3e2c5767_fld76xt_flix64_slot3", 104, -1, 0, 0, 0, 0, 0, 0 },
+ { "combined3e2c5767_fld77xt_flix64_slot3", 105, -1, 0, 0, 0, 0, 0, 0 },
+ { "combined3e2c5767_fld78xt_flix64_slot3", 106, -1, 0, 0, 0, 0, 0, 0 },
+ { "combined3e2c5767_fld79xt_flix64_slot3", 107, -1, 0, 0, 0, 0, 0, 0 },
+ { "combined3e2c5767_fld80xt_flix64_slot3", 108, -1, 0, 0, 0, 0, 0, 0 },
+ { "combined3e2c5767_fld81xt_flix64_slot3", 109, -1, 0, 0, 0, 0, 0, 0 },
+ { "combined3e2c5767_fld82xt_flix64_slot3", 110, -1, 0, 0, 0, 0, 0, 0 },
+ { "combined3e2c5767_fld83xt_flix64_slot3", 111, -1, 0, 0, 0, 0, 0, 0 },
+ { "combined3e2c5767_fld84xt_flix64_slot3", 112, -1, 0, 0, 0, 0, 0, 0 },
+ { "combined3e2c5767_fld85xt_flix64_slot3", 113, -1, 0, 0, 0, 0, 0, 0 },
+ { "combined3e2c5767_fld86xt_flix64_slot3", 114, -1, 0, 0, 0, 0, 0, 0 },
+ { "combined3e2c5767_fld87xt_flix64_slot3", 115, -1, 0, 0, 0, 0, 0, 0 },
+ { "combined3e2c5767_fld88xt_flix64_slot3", 116, -1, 0, 0, 0, 0, 0, 0 },
+ { "combined3e2c5767_fld89xt_flix64_slot3", 117, -1, 0, 0, 0, 0, 0, 0 },
+ { "combined3e2c5767_fld90xt_flix64_slot3", 118, -1, 0, 0, 0, 0, 0, 0 },
+ { "combined3e2c5767_fld91xt_flix64_slot3", 119, -1, 0, 0, 0, 0, 0, 0 },
+ { "combined3e2c5767_fld92xt_flix64_slot3", 120, -1, 0, 0, 0, 0, 0, 0 },
+ { "combined3e2c5767_fld93xt_flix64_slot3", 121, -1, 0, 0, 0, 0, 0, 0 },
+ { "op0_xt_flix64_slot0", 122, -1, 0, 0, 0, 0, 0, 0 }
+};
+
+
+/* Iclass table. */
+
+static xtensa_arg_internal Iclass_xt_iclass_rfe_stateArgs[] = {
+ { { STATE_PSRING }, 'i' },
+ { { STATE_PSEXCM }, 'm' },
+ { { STATE_EPC1 }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rfde_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_DEPC }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_call12_args[] = {
+ { { 0 /* soffsetx4 */ }, 'i' },
+ { { 10 /* ar12 */ }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_call12_stateArgs[] = {
+ { { STATE_PSCALLINC }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_call8_args[] = {
+ { { 0 /* soffsetx4 */ }, 'i' },
+ { { 9 /* ar8 */ }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_call8_stateArgs[] = {
+ { { STATE_PSCALLINC }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_call4_args[] = {
+ { { 0 /* soffsetx4 */ }, 'i' },
+ { { 8 /* ar4 */ }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_call4_stateArgs[] = {
+ { { STATE_PSCALLINC }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_callx12_args[] = {
+ { { 4 /* ars */ }, 'i' },
+ { { 10 /* ar12 */ }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_callx12_stateArgs[] = {
+ { { STATE_PSCALLINC }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_callx8_args[] = {
+ { { 4 /* ars */ }, 'i' },
+ { { 9 /* ar8 */ }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_callx8_stateArgs[] = {
+ { { STATE_PSCALLINC }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_callx4_args[] = {
+ { { 4 /* ars */ }, 'i' },
+ { { 8 /* ar4 */ }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_callx4_stateArgs[] = {
+ { { STATE_PSCALLINC }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_entry_args[] = {
+ { { 11 /* ars_entry */ }, 's' },
+ { { 4 /* ars */ }, 'i' },
+ { { 1 /* uimm12x8 */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_entry_stateArgs[] = {
+ { { STATE_PSCALLINC }, 'i' },
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSWOE }, 'i' },
+ { { STATE_WindowBase }, 'm' },
+ { { STATE_WindowStart }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_movsp_args[] = {
+ { { 6 /* art */ }, 'o' },
+ { { 4 /* ars */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_movsp_stateArgs[] = {
+ { { STATE_WindowBase }, 'i' },
+ { { STATE_WindowStart }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rotw_args[] = {
+ { { 2 /* simm4 */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rotw_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_WindowBase }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_retw_args[] = {
+ { { 5 /* *ars_invisible */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_retw_stateArgs[] = {
+ { { STATE_WindowBase }, 'm' },
+ { { STATE_WindowStart }, 'm' },
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSWOE }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rfwou_stateArgs[] = {
+ { { STATE_EPC1 }, 'i' },
+ { { STATE_PSEXCM }, 'm' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_WindowBase }, 'm' },
+ { { STATE_WindowStart }, 'm' },
+ { { STATE_PSOWB }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_l32e_args[] = {
+ { { 6 /* art */ }, 'o' },
+ { { 4 /* ars */ }, 'i' },
+ { { 12 /* immrx4 */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_l32e_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_s32e_args[] = {
+ { { 6 /* art */ }, 'i' },
+ { { 4 /* ars */ }, 'i' },
+ { { 12 /* immrx4 */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_s32e_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_windowbase_args[] = {
+ { { 6 /* art */ }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_windowbase_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_WindowBase }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_windowbase_args[] = {
+ { { 6 /* art */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_windowbase_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_WindowBase }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_windowbase_args[] = {
+ { { 6 /* art */ }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_windowbase_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_WindowBase }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_windowstart_args[] = {
+ { { 6 /* art */ }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_windowstart_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_WindowStart }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_windowstart_args[] = {
+ { { 6 /* art */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_windowstart_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_WindowStart }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_windowstart_args[] = {
+ { { 6 /* art */ }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_windowstart_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_WindowStart }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_add_n_args[] = {
+ { { 3 /* arr */ }, 'o' },
+ { { 4 /* ars */ }, 'i' },
+ { { 6 /* art */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_addi_n_args[] = {
+ { { 3 /* arr */ }, 'o' },
+ { { 4 /* ars */ }, 'i' },
+ { { 16 /* ai4const */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_bz6_args[] = {
+ { { 4 /* ars */ }, 'i' },
+ { { 15 /* uimm6 */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_loadi4_args[] = {
+ { { 6 /* art */ }, 'o' },
+ { { 4 /* ars */ }, 'i' },
+ { { 13 /* lsi4x4 */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_mov_n_args[] = {
+ { { 6 /* art */ }, 'o' },
+ { { 4 /* ars */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_movi_n_args[] = {
+ { { 4 /* ars */ }, 'o' },
+ { { 14 /* simm7 */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_retn_args[] = {
+ { { 5 /* *ars_invisible */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_storei4_args[] = {
+ { { 6 /* art */ }, 'i' },
+ { { 4 /* ars */ }, 'i' },
+ { { 13 /* lsi4x4 */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_rur_threadptr_args[] = {
+ { { 3 /* arr */ }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_rur_threadptr_stateArgs[] = {
+ { { STATE_THREADPTR }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_wur_threadptr_args[] = {
+ { { 6 /* art */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_wur_threadptr_stateArgs[] = {
+ { { STATE_THREADPTR }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_addi_args[] = {
+ { { 6 /* art */ }, 'o' },
+ { { 4 /* ars */ }, 'i' },
+ { { 23 /* simm8 */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_addmi_args[] = {
+ { { 6 /* art */ }, 'o' },
+ { { 4 /* ars */ }, 'i' },
+ { { 24 /* simm8x256 */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_addsub_args[] = {
+ { { 3 /* arr */ }, 'o' },
+ { { 4 /* ars */ }, 'i' },
+ { { 6 /* art */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_bit_args[] = {
+ { { 3 /* arr */ }, 'o' },
+ { { 4 /* ars */ }, 'i' },
+ { { 6 /* art */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_bsi8_args[] = {
+ { { 4 /* ars */ }, 'i' },
+ { { 17 /* b4const */ }, 'i' },
+ { { 28 /* label8 */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_bsi8b_args[] = {
+ { { 4 /* ars */ }, 'i' },
+ { { 67 /* bbi */ }, 'i' },
+ { { 28 /* label8 */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_bsi8u_args[] = {
+ { { 4 /* ars */ }, 'i' },
+ { { 18 /* b4constu */ }, 'i' },
+ { { 28 /* label8 */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_bst8_args[] = {
+ { { 4 /* ars */ }, 'i' },
+ { { 6 /* art */ }, 'i' },
+ { { 28 /* label8 */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_bsz12_args[] = {
+ { { 4 /* ars */ }, 'i' },
+ { { 30 /* label12 */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_call0_args[] = {
+ { { 0 /* soffsetx4 */ }, 'i' },
+ { { 7 /* ar0 */ }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_callx0_args[] = {
+ { { 4 /* ars */ }, 'i' },
+ { { 7 /* ar0 */ }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_exti_args[] = {
+ { { 3 /* arr */ }, 'o' },
+ { { 6 /* art */ }, 'i' },
+ { { 82 /* sae */ }, 'i' },
+ { { 27 /* op2p1 */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_jump_args[] = {
+ { { 31 /* soffset */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_jumpx_args[] = {
+ { { 4 /* ars */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_l16ui_args[] = {
+ { { 6 /* art */ }, 'o' },
+ { { 4 /* ars */ }, 'i' },
+ { { 20 /* uimm8x2 */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_l16si_args[] = {
+ { { 6 /* art */ }, 'o' },
+ { { 4 /* ars */ }, 'i' },
+ { { 20 /* uimm8x2 */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_l32i_args[] = {
+ { { 6 /* art */ }, 'o' },
+ { { 4 /* ars */ }, 'i' },
+ { { 21 /* uimm8x4 */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_l32r_args[] = {
+ { { 6 /* art */ }, 'o' },
+ { { 32 /* uimm16x4 */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_l32r_stateArgs[] = {
+ { { STATE_LITBADDR }, 'i' },
+ { { STATE_LITBEN }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_l8i_args[] = {
+ { { 6 /* art */ }, 'o' },
+ { { 4 /* ars */ }, 'i' },
+ { { 19 /* uimm8 */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_loop_args[] = {
+ { { 4 /* ars */ }, 'i' },
+ { { 29 /* ulabel8 */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_loop_stateArgs[] = {
+ { { STATE_LBEG }, 'o' },
+ { { STATE_LEND }, 'o' },
+ { { STATE_LCOUNT }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_loopz_args[] = {
+ { { 4 /* ars */ }, 'i' },
+ { { 29 /* ulabel8 */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_loopz_stateArgs[] = {
+ { { STATE_LBEG }, 'o' },
+ { { STATE_LEND }, 'o' },
+ { { STATE_LCOUNT }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_movi_args[] = {
+ { { 6 /* art */ }, 'o' },
+ { { 25 /* simm12b */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_movz_args[] = {
+ { { 3 /* arr */ }, 'm' },
+ { { 4 /* ars */ }, 'i' },
+ { { 6 /* art */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_neg_args[] = {
+ { { 3 /* arr */ }, 'o' },
+ { { 6 /* art */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_return_args[] = {
+ { { 5 /* *ars_invisible */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_s16i_args[] = {
+ { { 6 /* art */ }, 'i' },
+ { { 4 /* ars */ }, 'i' },
+ { { 20 /* uimm8x2 */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_s32i_args[] = {
+ { { 6 /* art */ }, 'i' },
+ { { 4 /* ars */ }, 'i' },
+ { { 21 /* uimm8x4 */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_s8i_args[] = {
+ { { 6 /* art */ }, 'i' },
+ { { 4 /* ars */ }, 'i' },
+ { { 19 /* uimm8 */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_sar_args[] = {
+ { { 4 /* ars */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_sar_stateArgs[] = {
+ { { STATE_SAR }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_sari_args[] = {
+ { { 86 /* sas */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_sari_stateArgs[] = {
+ { { STATE_SAR }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_shifts_args[] = {
+ { { 3 /* arr */ }, 'o' },
+ { { 4 /* ars */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_shifts_stateArgs[] = {
+ { { STATE_SAR }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_shiftst_args[] = {
+ { { 3 /* arr */ }, 'o' },
+ { { 4 /* ars */ }, 'i' },
+ { { 6 /* art */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_shiftst_stateArgs[] = {
+ { { STATE_SAR }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_shiftt_args[] = {
+ { { 3 /* arr */ }, 'o' },
+ { { 6 /* art */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_shiftt_stateArgs[] = {
+ { { STATE_SAR }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_slli_args[] = {
+ { { 3 /* arr */ }, 'o' },
+ { { 4 /* ars */ }, 'i' },
+ { { 26 /* msalp32 */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_srai_args[] = {
+ { { 3 /* arr */ }, 'o' },
+ { { 6 /* art */ }, 'i' },
+ { { 84 /* sargt */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_srli_args[] = {
+ { { 3 /* arr */ }, 'o' },
+ { { 6 /* art */ }, 'i' },
+ { { 70 /* s */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_sync_stateArgs[] = {
+ { { STATE_XTSYNC }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsil_args[] = {
+ { { 6 /* art */ }, 'o' },
+ { { 70 /* s */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsil_stateArgs[] = {
+ { { STATE_PSWOE }, 'i' },
+ { { STATE_PSCALLINC }, 'i' },
+ { { STATE_PSOWB }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_PSUM }, 'i' },
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSINTLEVEL }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_lend_args[] = {
+ { { 6 /* art */ }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_lend_stateArgs[] = {
+ { { STATE_LEND }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_lend_args[] = {
+ { { 6 /* art */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_lend_stateArgs[] = {
+ { { STATE_LEND }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_lend_args[] = {
+ { { 6 /* art */ }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_lend_stateArgs[] = {
+ { { STATE_LEND }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_lcount_args[] = {
+ { { 6 /* art */ }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_lcount_stateArgs[] = {
+ { { STATE_LCOUNT }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_lcount_args[] = {
+ { { 6 /* art */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_lcount_stateArgs[] = {
+ { { STATE_XTSYNC }, 'o' },
+ { { STATE_LCOUNT }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_lcount_args[] = {
+ { { 6 /* art */ }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_lcount_stateArgs[] = {
+ { { STATE_XTSYNC }, 'o' },
+ { { STATE_LCOUNT }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_lbeg_args[] = {
+ { { 6 /* art */ }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_lbeg_stateArgs[] = {
+ { { STATE_LBEG }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_lbeg_args[] = {
+ { { 6 /* art */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_lbeg_stateArgs[] = {
+ { { STATE_LBEG }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_lbeg_args[] = {
+ { { 6 /* art */ }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_lbeg_stateArgs[] = {
+ { { STATE_LBEG }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_sar_args[] = {
+ { { 6 /* art */ }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_sar_stateArgs[] = {
+ { { STATE_SAR }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_sar_args[] = {
+ { { 6 /* art */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_sar_stateArgs[] = {
+ { { STATE_SAR }, 'o' },
+ { { STATE_XTSYNC }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_sar_args[] = {
+ { { 6 /* art */ }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_sar_stateArgs[] = {
+ { { STATE_SAR }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_litbase_args[] = {
+ { { 6 /* art */ }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_litbase_stateArgs[] = {
+ { { STATE_LITBADDR }, 'i' },
+ { { STATE_LITBEN }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_litbase_args[] = {
+ { { 6 /* art */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_litbase_stateArgs[] = {
+ { { STATE_LITBADDR }, 'o' },
+ { { STATE_LITBEN }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_litbase_args[] = {
+ { { 6 /* art */ }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_litbase_stateArgs[] = {
+ { { STATE_LITBADDR }, 'm' },
+ { { STATE_LITBEN }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_176_args[] = {
+ { { 6 /* art */ }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_176_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_208_args[] = {
+ { { 6 /* art */ }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_208_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_ps_args[] = {
+ { { 6 /* art */ }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_ps_stateArgs[] = {
+ { { STATE_PSWOE }, 'i' },
+ { { STATE_PSCALLINC }, 'i' },
+ { { STATE_PSOWB }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_PSUM }, 'i' },
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSINTLEVEL }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_ps_args[] = {
+ { { 6 /* art */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_ps_stateArgs[] = {
+ { { STATE_PSWOE }, 'o' },
+ { { STATE_PSCALLINC }, 'o' },
+ { { STATE_PSOWB }, 'o' },
+ { { STATE_PSRING }, 'm' },
+ { { STATE_PSUM }, 'o' },
+ { { STATE_PSEXCM }, 'm' },
+ { { STATE_PSINTLEVEL }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_ps_args[] = {
+ { { 6 /* art */ }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_ps_stateArgs[] = {
+ { { STATE_PSWOE }, 'm' },
+ { { STATE_PSCALLINC }, 'm' },
+ { { STATE_PSOWB }, 'm' },
+ { { STATE_PSRING }, 'm' },
+ { { STATE_PSUM }, 'm' },
+ { { STATE_PSEXCM }, 'm' },
+ { { STATE_PSINTLEVEL }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_epc1_args[] = {
+ { { 6 /* art */ }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_epc1_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_EPC1 }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_epc1_args[] = {
+ { { 6 /* art */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_epc1_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_EPC1 }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_epc1_args[] = {
+ { { 6 /* art */ }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_epc1_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_EPC1 }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_excsave1_args[] = {
+ { { 6 /* art */ }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_excsave1_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_EXCSAVE1 }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_excsave1_args[] = {
+ { { 6 /* art */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_excsave1_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_EXCSAVE1 }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_excsave1_args[] = {
+ { { 6 /* art */ }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_excsave1_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_EXCSAVE1 }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_epc2_args[] = {
+ { { 6 /* art */ }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_epc2_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_EPC2 }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_epc2_args[] = {
+ { { 6 /* art */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_epc2_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_EPC2 }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_epc2_args[] = {
+ { { 6 /* art */ }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_epc2_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_EPC2 }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_excsave2_args[] = {
+ { { 6 /* art */ }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_excsave2_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_EXCSAVE2 }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_excsave2_args[] = {
+ { { 6 /* art */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_excsave2_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_EXCSAVE2 }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_excsave2_args[] = {
+ { { 6 /* art */ }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_excsave2_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_EXCSAVE2 }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_epc3_args[] = {
+ { { 6 /* art */ }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_epc3_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_EPC3 }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_epc3_args[] = {
+ { { 6 /* art */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_epc3_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_EPC3 }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_epc3_args[] = {
+ { { 6 /* art */ }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_epc3_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_EPC3 }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_excsave3_args[] = {
+ { { 6 /* art */ }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_excsave3_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_EXCSAVE3 }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_excsave3_args[] = {
+ { { 6 /* art */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_excsave3_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_EXCSAVE3 }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_excsave3_args[] = {
+ { { 6 /* art */ }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_excsave3_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_EXCSAVE3 }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_epc4_args[] = {
+ { { 6 /* art */ }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_epc4_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_EPC4 }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_epc4_args[] = {
+ { { 6 /* art */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_epc4_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_EPC4 }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_epc4_args[] = {
+ { { 6 /* art */ }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_epc4_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_EPC4 }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_excsave4_args[] = {
+ { { 6 /* art */ }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_excsave4_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_EXCSAVE4 }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_excsave4_args[] = {
+ { { 6 /* art */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_excsave4_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_EXCSAVE4 }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_excsave4_args[] = {
+ { { 6 /* art */ }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_excsave4_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_EXCSAVE4 }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_epc5_args[] = {
+ { { 6 /* art */ }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_epc5_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_EPC5 }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_epc5_args[] = {
+ { { 6 /* art */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_epc5_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_EPC5 }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_epc5_args[] = {
+ { { 6 /* art */ }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_epc5_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_EPC5 }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_excsave5_args[] = {
+ { { 6 /* art */ }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_excsave5_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_EXCSAVE5 }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_excsave5_args[] = {
+ { { 6 /* art */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_excsave5_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_EXCSAVE5 }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_excsave5_args[] = {
+ { { 6 /* art */ }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_excsave5_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_EXCSAVE5 }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_epc6_args[] = {
+ { { 6 /* art */ }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_epc6_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_EPC6 }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_epc6_args[] = {
+ { { 6 /* art */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_epc6_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_EPC6 }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_epc6_args[] = {
+ { { 6 /* art */ }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_epc6_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_EPC6 }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_excsave6_args[] = {
+ { { 6 /* art */ }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_excsave6_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_EXCSAVE6 }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_excsave6_args[] = {
+ { { 6 /* art */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_excsave6_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_EXCSAVE6 }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_excsave6_args[] = {
+ { { 6 /* art */ }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_excsave6_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_EXCSAVE6 }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_epc7_args[] = {
+ { { 6 /* art */ }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_epc7_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_EPC7 }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_epc7_args[] = {
+ { { 6 /* art */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_epc7_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_EPC7 }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_epc7_args[] = {
+ { { 6 /* art */ }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_epc7_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_EPC7 }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_excsave7_args[] = {
+ { { 6 /* art */ }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_excsave7_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_EXCSAVE7 }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_excsave7_args[] = {
+ { { 6 /* art */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_excsave7_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_EXCSAVE7 }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_excsave7_args[] = {
+ { { 6 /* art */ }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_excsave7_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_EXCSAVE7 }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_eps2_args[] = {
+ { { 6 /* art */ }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_eps2_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_EPS2 }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_eps2_args[] = {
+ { { 6 /* art */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_eps2_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_EPS2 }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_eps2_args[] = {
+ { { 6 /* art */ }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_eps2_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_EPS2 }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_eps3_args[] = {
+ { { 6 /* art */ }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_eps3_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_EPS3 }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_eps3_args[] = {
+ { { 6 /* art */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_eps3_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_EPS3 }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_eps3_args[] = {
+ { { 6 /* art */ }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_eps3_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_EPS3 }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_eps4_args[] = {
+ { { 6 /* art */ }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_eps4_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_EPS4 }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_eps4_args[] = {
+ { { 6 /* art */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_eps4_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_EPS4 }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_eps4_args[] = {
+ { { 6 /* art */ }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_eps4_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_EPS4 }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_eps5_args[] = {
+ { { 6 /* art */ }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_eps5_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_EPS5 }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_eps5_args[] = {
+ { { 6 /* art */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_eps5_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_EPS5 }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_eps5_args[] = {
+ { { 6 /* art */ }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_eps5_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_EPS5 }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_eps6_args[] = {
+ { { 6 /* art */ }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_eps6_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_EPS6 }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_eps6_args[] = {
+ { { 6 /* art */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_eps6_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_EPS6 }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_eps6_args[] = {
+ { { 6 /* art */ }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_eps6_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_EPS6 }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_eps7_args[] = {
+ { { 6 /* art */ }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_eps7_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_EPS7 }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_eps7_args[] = {
+ { { 6 /* art */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_eps7_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_EPS7 }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_eps7_args[] = {
+ { { 6 /* art */ }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_eps7_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_EPS7 }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_excvaddr_args[] = {
+ { { 6 /* art */ }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_excvaddr_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_EXCVADDR }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_excvaddr_args[] = {
+ { { 6 /* art */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_excvaddr_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_EXCVADDR }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_excvaddr_args[] = {
+ { { 6 /* art */ }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_excvaddr_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_EXCVADDR }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_depc_args[] = {
+ { { 6 /* art */ }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_depc_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_DEPC }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_depc_args[] = {
+ { { 6 /* art */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_depc_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_DEPC }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_depc_args[] = {
+ { { 6 /* art */ }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_depc_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_DEPC }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_exccause_args[] = {
+ { { 6 /* art */ }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_exccause_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_EXCCAUSE }, 'i' },
+ { { STATE_XTSYNC }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_exccause_args[] = {
+ { { 6 /* art */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_exccause_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_EXCCAUSE }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_exccause_args[] = {
+ { { 6 /* art */ }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_exccause_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_EXCCAUSE }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_misc0_args[] = {
+ { { 6 /* art */ }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_misc0_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_MISC0 }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_misc0_args[] = {
+ { { 6 /* art */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_misc0_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_MISC0 }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_misc0_args[] = {
+ { { 6 /* art */ }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_misc0_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_MISC0 }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_misc1_args[] = {
+ { { 6 /* art */ }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_misc1_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_MISC1 }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_misc1_args[] = {
+ { { 6 /* art */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_misc1_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_MISC1 }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_misc1_args[] = {
+ { { 6 /* art */ }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_misc1_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_MISC1 }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_misc2_args[] = {
+ { { 6 /* art */ }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_misc2_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_MISC2 }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_misc2_args[] = {
+ { { 6 /* art */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_misc2_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_MISC2 }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_misc2_args[] = {
+ { { 6 /* art */ }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_misc2_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_MISC2 }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_misc3_args[] = {
+ { { 6 /* art */ }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_misc3_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_MISC3 }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_misc3_args[] = {
+ { { 6 /* art */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_misc3_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_MISC3 }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_misc3_args[] = {
+ { { 6 /* art */ }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_misc3_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_MISC3 }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_prid_args[] = {
+ { { 6 /* art */ }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_prid_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_vecbase_args[] = {
+ { { 6 /* art */ }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_vecbase_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_VECBASE }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_vecbase_args[] = {
+ { { 6 /* art */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_vecbase_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_VECBASE }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_vecbase_args[] = {
+ { { 6 /* art */ }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_vecbase_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_VECBASE }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_mac16_aa_args[] = {
+ { { 4 /* ars */ }, 'i' },
+ { { 6 /* art */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_mac16_aa_stateArgs[] = {
+ { { STATE_ACC }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_mac16_ad_args[] = {
+ { { 4 /* ars */ }, 'i' },
+ { { 34 /* my */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_mac16_ad_stateArgs[] = {
+ { { STATE_ACC }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_mac16_da_args[] = {
+ { { 33 /* mx */ }, 'i' },
+ { { 6 /* art */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_mac16_da_stateArgs[] = {
+ { { STATE_ACC }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_mac16_dd_args[] = {
+ { { 33 /* mx */ }, 'i' },
+ { { 34 /* my */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_mac16_dd_stateArgs[] = {
+ { { STATE_ACC }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_mac16a_aa_args[] = {
+ { { 4 /* ars */ }, 'i' },
+ { { 6 /* art */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_mac16a_aa_stateArgs[] = {
+ { { STATE_ACC }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_mac16a_ad_args[] = {
+ { { 4 /* ars */ }, 'i' },
+ { { 34 /* my */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_mac16a_ad_stateArgs[] = {
+ { { STATE_ACC }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_mac16a_da_args[] = {
+ { { 33 /* mx */ }, 'i' },
+ { { 6 /* art */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_mac16a_da_stateArgs[] = {
+ { { STATE_ACC }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_mac16a_dd_args[] = {
+ { { 33 /* mx */ }, 'i' },
+ { { 34 /* my */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_mac16a_dd_stateArgs[] = {
+ { { STATE_ACC }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_mac16al_da_args[] = {
+ { { 35 /* mw */ }, 'o' },
+ { { 4 /* ars */ }, 'm' },
+ { { 33 /* mx */ }, 'i' },
+ { { 6 /* art */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_mac16al_da_stateArgs[] = {
+ { { STATE_ACC }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_mac16al_dd_args[] = {
+ { { 35 /* mw */ }, 'o' },
+ { { 4 /* ars */ }, 'm' },
+ { { 33 /* mx */ }, 'i' },
+ { { 34 /* my */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_mac16al_dd_stateArgs[] = {
+ { { STATE_ACC }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_mac16_l_args[] = {
+ { { 35 /* mw */ }, 'o' },
+ { { 4 /* ars */ }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_mul16_args[] = {
+ { { 3 /* arr */ }, 'o' },
+ { { 4 /* ars */ }, 'i' },
+ { { 6 /* art */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_m0_args[] = {
+ { { 6 /* art */ }, 'o' },
+ { { 36 /* mr0 */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_m0_args[] = {
+ { { 6 /* art */ }, 'i' },
+ { { 36 /* mr0 */ }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_m0_args[] = {
+ { { 6 /* art */ }, 'm' },
+ { { 36 /* mr0 */ }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_m1_args[] = {
+ { { 6 /* art */ }, 'o' },
+ { { 37 /* mr1 */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_m1_args[] = {
+ { { 6 /* art */ }, 'i' },
+ { { 37 /* mr1 */ }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_m1_args[] = {
+ { { 6 /* art */ }, 'm' },
+ { { 37 /* mr1 */ }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_m2_args[] = {
+ { { 6 /* art */ }, 'o' },
+ { { 38 /* mr2 */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_m2_args[] = {
+ { { 6 /* art */ }, 'i' },
+ { { 38 /* mr2 */ }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_m2_args[] = {
+ { { 6 /* art */ }, 'm' },
+ { { 38 /* mr2 */ }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_m3_args[] = {
+ { { 6 /* art */ }, 'o' },
+ { { 39 /* mr3 */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_m3_args[] = {
+ { { 6 /* art */ }, 'i' },
+ { { 39 /* mr3 */ }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_m3_args[] = {
+ { { 6 /* art */ }, 'm' },
+ { { 39 /* mr3 */ }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_acclo_args[] = {
+ { { 6 /* art */ }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_acclo_stateArgs[] = {
+ { { STATE_ACC }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_acclo_args[] = {
+ { { 6 /* art */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_acclo_stateArgs[] = {
+ { { STATE_ACC }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_acclo_args[] = {
+ { { 6 /* art */ }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_acclo_stateArgs[] = {
+ { { STATE_ACC }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_acchi_args[] = {
+ { { 6 /* art */ }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_acchi_stateArgs[] = {
+ { { STATE_ACC }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_acchi_args[] = {
+ { { 6 /* art */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_acchi_stateArgs[] = {
+ { { STATE_ACC }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_acchi_args[] = {
+ { { 6 /* art */ }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_acchi_stateArgs[] = {
+ { { STATE_ACC }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rfi_args[] = {
+ { { 70 /* s */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rfi_stateArgs[] = {
+ { { STATE_PSWOE }, 'o' },
+ { { STATE_PSCALLINC }, 'o' },
+ { { STATE_PSOWB }, 'o' },
+ { { STATE_PSRING }, 'm' },
+ { { STATE_PSUM }, 'o' },
+ { { STATE_PSEXCM }, 'm' },
+ { { STATE_PSINTLEVEL }, 'o' },
+ { { STATE_EPC1 }, 'i' },
+ { { STATE_EPC2 }, 'i' },
+ { { STATE_EPC3 }, 'i' },
+ { { STATE_EPC4 }, 'i' },
+ { { STATE_EPC5 }, 'i' },
+ { { STATE_EPC6 }, 'i' },
+ { { STATE_EPC7 }, 'i' },
+ { { STATE_EPS2 }, 'i' },
+ { { STATE_EPS3 }, 'i' },
+ { { STATE_EPS4 }, 'i' },
+ { { STATE_EPS5 }, 'i' },
+ { { STATE_EPS6 }, 'i' },
+ { { STATE_EPS7 }, 'i' },
+ { { STATE_InOCDMode }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wait_args[] = {
+ { { 70 /* s */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wait_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_PSINTLEVEL }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_interrupt_args[] = {
+ { { 6 /* art */ }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_interrupt_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_INTERRUPT }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_intset_args[] = {
+ { { 6 /* art */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_intset_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_XTSYNC }, 'o' },
+ { { STATE_INTERRUPT }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_intclear_args[] = {
+ { { 6 /* art */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_intclear_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_XTSYNC }, 'o' },
+ { { STATE_INTERRUPT }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_intenable_args[] = {
+ { { 6 /* art */ }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_intenable_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_INTENABLE }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_intenable_args[] = {
+ { { 6 /* art */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_intenable_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_INTENABLE }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_intenable_args[] = {
+ { { 6 /* art */ }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_intenable_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_INTENABLE }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_break_args[] = {
+ { { 41 /* imms */ }, 'i' },
+ { { 40 /* immt */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_break_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSINTLEVEL }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_break_n_args[] = {
+ { { 41 /* imms */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_break_n_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSINTLEVEL }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_dbreaka0_args[] = {
+ { { 6 /* art */ }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_dbreaka0_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_DBREAKA0 }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_dbreaka0_args[] = {
+ { { 6 /* art */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_dbreaka0_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_DBREAKA0 }, 'o' },
+ { { STATE_XTSYNC }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_dbreaka0_args[] = {
+ { { 6 /* art */ }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_dbreaka0_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_DBREAKA0 }, 'm' },
+ { { STATE_XTSYNC }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_dbreakc0_args[] = {
+ { { 6 /* art */ }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_dbreakc0_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_DBREAKC0 }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_dbreakc0_args[] = {
+ { { 6 /* art */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_dbreakc0_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_DBREAKC0 }, 'o' },
+ { { STATE_XTSYNC }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_dbreakc0_args[] = {
+ { { 6 /* art */ }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_dbreakc0_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_DBREAKC0 }, 'm' },
+ { { STATE_XTSYNC }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_dbreaka1_args[] = {
+ { { 6 /* art */ }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_dbreaka1_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_DBREAKA1 }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_dbreaka1_args[] = {
+ { { 6 /* art */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_dbreaka1_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_DBREAKA1 }, 'o' },
+ { { STATE_XTSYNC }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_dbreaka1_args[] = {
+ { { 6 /* art */ }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_dbreaka1_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_DBREAKA1 }, 'm' },
+ { { STATE_XTSYNC }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_dbreakc1_args[] = {
+ { { 6 /* art */ }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_dbreakc1_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_DBREAKC1 }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_dbreakc1_args[] = {
+ { { 6 /* art */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_dbreakc1_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_DBREAKC1 }, 'o' },
+ { { STATE_XTSYNC }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_dbreakc1_args[] = {
+ { { 6 /* art */ }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_dbreakc1_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_DBREAKC1 }, 'm' },
+ { { STATE_XTSYNC }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_ibreaka0_args[] = {
+ { { 6 /* art */ }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_ibreaka0_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_IBREAKA0 }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_ibreaka0_args[] = {
+ { { 6 /* art */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_ibreaka0_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_IBREAKA0 }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_ibreaka0_args[] = {
+ { { 6 /* art */ }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_ibreaka0_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_IBREAKA0 }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_ibreaka1_args[] = {
+ { { 6 /* art */ }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_ibreaka1_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_IBREAKA1 }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_ibreaka1_args[] = {
+ { { 6 /* art */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_ibreaka1_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_IBREAKA1 }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_ibreaka1_args[] = {
+ { { 6 /* art */ }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_ibreaka1_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_IBREAKA1 }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_ibreakenable_args[] = {
+ { { 6 /* art */ }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_ibreakenable_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_IBREAKENABLE }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_ibreakenable_args[] = {
+ { { 6 /* art */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_ibreakenable_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_IBREAKENABLE }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_ibreakenable_args[] = {
+ { { 6 /* art */ }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_ibreakenable_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_IBREAKENABLE }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_debugcause_args[] = {
+ { { 6 /* art */ }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_debugcause_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_DEBUGCAUSE }, 'i' },
+ { { STATE_DBNUM }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_debugcause_args[] = {
+ { { 6 /* art */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_debugcause_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_DEBUGCAUSE }, 'o' },
+ { { STATE_DBNUM }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_debugcause_args[] = {
+ { { 6 /* art */ }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_debugcause_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_DEBUGCAUSE }, 'm' },
+ { { STATE_DBNUM }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_icount_args[] = {
+ { { 6 /* art */ }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_icount_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_ICOUNT }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_icount_args[] = {
+ { { 6 /* art */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_icount_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_XTSYNC }, 'o' },
+ { { STATE_ICOUNT }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_icount_args[] = {
+ { { 6 /* art */ }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_icount_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_XTSYNC }, 'o' },
+ { { STATE_ICOUNT }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_icountlevel_args[] = {
+ { { 6 /* art */ }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_icountlevel_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_ICOUNTLEVEL }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_icountlevel_args[] = {
+ { { 6 /* art */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_icountlevel_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_ICOUNTLEVEL }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_icountlevel_args[] = {
+ { { 6 /* art */ }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_icountlevel_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_ICOUNTLEVEL }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_ddr_args[] = {
+ { { 6 /* art */ }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_ddr_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_DDR }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_ddr_args[] = {
+ { { 6 /* art */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_ddr_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_XTSYNC }, 'o' },
+ { { STATE_DDR }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_ddr_args[] = {
+ { { 6 /* art */ }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_ddr_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_XTSYNC }, 'o' },
+ { { STATE_DDR }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rfdo_args[] = {
+ { { 41 /* imms */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rfdo_stateArgs[] = {
+ { { STATE_InOCDMode }, 'm' },
+ { { STATE_EPC6 }, 'i' },
+ { { STATE_PSWOE }, 'o' },
+ { { STATE_PSCALLINC }, 'o' },
+ { { STATE_PSOWB }, 'o' },
+ { { STATE_PSRING }, 'o' },
+ { { STATE_PSUM }, 'o' },
+ { { STATE_PSEXCM }, 'o' },
+ { { STATE_PSINTLEVEL }, 'o' },
+ { { STATE_EPS6 }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rfdd_stateArgs[] = {
+ { { STATE_InOCDMode }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_mmid_args[] = {
+ { { 6 /* art */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_mmid_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_XTSYNC }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_bbool1_args[] = {
+ { { 44 /* br */ }, 'o' },
+ { { 43 /* bs */ }, 'i' },
+ { { 42 /* bt */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_bbool4_args[] = {
+ { { 42 /* bt */ }, 'o' },
+ { { 49 /* bs4 */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_bbool8_args[] = {
+ { { 42 /* bt */ }, 'o' },
+ { { 52 /* bs8 */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_bbranch_args[] = {
+ { { 43 /* bs */ }, 'i' },
+ { { 28 /* label8 */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_bmove_args[] = {
+ { { 3 /* arr */ }, 'm' },
+ { { 4 /* ars */ }, 'i' },
+ { { 42 /* bt */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_RSR_BR_args[] = {
+ { { 6 /* art */ }, 'o' },
+ { { 57 /* brall */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_WSR_BR_args[] = {
+ { { 6 /* art */ }, 'i' },
+ { { 57 /* brall */ }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_XSR_BR_args[] = {
+ { { 6 /* art */ }, 'm' },
+ { { 57 /* brall */ }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_ccount_args[] = {
+ { { 6 /* art */ }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_ccount_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_CCOUNT }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_ccount_args[] = {
+ { { 6 /* art */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_ccount_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_XTSYNC }, 'o' },
+ { { STATE_CCOUNT }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_ccount_args[] = {
+ { { 6 /* art */ }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_ccount_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_XTSYNC }, 'o' },
+ { { STATE_CCOUNT }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_ccompare0_args[] = {
+ { { 6 /* art */ }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_ccompare0_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_CCOMPARE0 }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_ccompare0_args[] = {
+ { { 6 /* art */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_ccompare0_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_CCOMPARE0 }, 'o' },
+ { { STATE_INTERRUPT }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_ccompare0_args[] = {
+ { { 6 /* art */ }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_ccompare0_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_CCOMPARE0 }, 'm' },
+ { { STATE_INTERRUPT }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_ccompare1_args[] = {
+ { { 6 /* art */ }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_ccompare1_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_CCOMPARE1 }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_ccompare1_args[] = {
+ { { 6 /* art */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_ccompare1_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_CCOMPARE1 }, 'o' },
+ { { STATE_INTERRUPT }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_ccompare1_args[] = {
+ { { 6 /* art */ }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_ccompare1_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_CCOMPARE1 }, 'm' },
+ { { STATE_INTERRUPT }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_ccompare2_args[] = {
+ { { 6 /* art */ }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_ccompare2_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_CCOMPARE2 }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_ccompare2_args[] = {
+ { { 6 /* art */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_ccompare2_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_CCOMPARE2 }, 'o' },
+ { { STATE_INTERRUPT }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_ccompare2_args[] = {
+ { { 6 /* art */ }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_ccompare2_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_CCOMPARE2 }, 'm' },
+ { { STATE_INTERRUPT }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_icache_args[] = {
+ { { 4 /* ars */ }, 'i' },
+ { { 21 /* uimm8x4 */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_icache_lock_args[] = {
+ { { 4 /* ars */ }, 'i' },
+ { { 22 /* uimm4x16 */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_icache_lock_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_icache_inv_args[] = {
+ { { 4 /* ars */ }, 'i' },
+ { { 21 /* uimm8x4 */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_icache_inv_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_licx_args[] = {
+ { { 6 /* art */ }, 'o' },
+ { { 4 /* ars */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_licx_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_sicx_args[] = {
+ { { 6 /* art */ }, 'i' },
+ { { 4 /* ars */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_sicx_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_dcache_args[] = {
+ { { 4 /* ars */ }, 'i' },
+ { { 21 /* uimm8x4 */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_dcache_ind_args[] = {
+ { { 4 /* ars */ }, 'i' },
+ { { 22 /* uimm4x16 */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_dcache_ind_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_dcache_inv_args[] = {
+ { { 4 /* ars */ }, 'i' },
+ { { 21 /* uimm8x4 */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_dcache_inv_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_dpf_args[] = {
+ { { 4 /* ars */ }, 'i' },
+ { { 21 /* uimm8x4 */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_dcache_lock_args[] = {
+ { { 4 /* ars */ }, 'i' },
+ { { 22 /* uimm4x16 */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_dcache_lock_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_sdct_args[] = {
+ { { 6 /* art */ }, 'i' },
+ { { 4 /* ars */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_sdct_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_ldct_args[] = {
+ { { 6 /* art */ }, 'o' },
+ { { 4 /* ars */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_ldct_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_ptevaddr_args[] = {
+ { { 6 /* art */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_ptevaddr_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_PTBASE }, 'o' },
+ { { STATE_XTSYNC }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_ptevaddr_args[] = {
+ { { 6 /* art */ }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_ptevaddr_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_PTBASE }, 'i' },
+ { { STATE_EXCVADDR }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_ptevaddr_args[] = {
+ { { 6 /* art */ }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_ptevaddr_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_PTBASE }, 'm' },
+ { { STATE_EXCVADDR }, 'i' },
+ { { STATE_XTSYNC }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_rasid_args[] = {
+ { { 6 /* art */ }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_rasid_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_ASID3 }, 'i' },
+ { { STATE_ASID2 }, 'i' },
+ { { STATE_ASID1 }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_rasid_args[] = {
+ { { 6 /* art */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_rasid_stateArgs[] = {
+ { { STATE_XTSYNC }, 'o' },
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_ASID3 }, 'o' },
+ { { STATE_ASID2 }, 'o' },
+ { { STATE_ASID1 }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_rasid_args[] = {
+ { { 6 /* art */ }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_rasid_stateArgs[] = {
+ { { STATE_XTSYNC }, 'o' },
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_ASID3 }, 'm' },
+ { { STATE_ASID2 }, 'm' },
+ { { STATE_ASID1 }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_itlbcfg_args[] = {
+ { { 6 /* art */ }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_itlbcfg_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_INSTPGSZID4 }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_itlbcfg_args[] = {
+ { { 6 /* art */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_itlbcfg_stateArgs[] = {
+ { { STATE_XTSYNC }, 'o' },
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_INSTPGSZID4 }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_itlbcfg_args[] = {
+ { { 6 /* art */ }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_itlbcfg_stateArgs[] = {
+ { { STATE_XTSYNC }, 'o' },
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_INSTPGSZID4 }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_dtlbcfg_args[] = {
+ { { 6 /* art */ }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_dtlbcfg_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_DATAPGSZID4 }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_dtlbcfg_args[] = {
+ { { 6 /* art */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_dtlbcfg_stateArgs[] = {
+ { { STATE_XTSYNC }, 'o' },
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_DATAPGSZID4 }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_dtlbcfg_args[] = {
+ { { 6 /* art */ }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_dtlbcfg_stateArgs[] = {
+ { { STATE_XTSYNC }, 'o' },
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_DATAPGSZID4 }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_idtlb_args[] = {
+ { { 4 /* ars */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_idtlb_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_XTSYNC }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rdtlb_args[] = {
+ { { 6 /* art */ }, 'o' },
+ { { 4 /* ars */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rdtlb_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wdtlb_args[] = {
+ { { 6 /* art */ }, 'i' },
+ { { 4 /* ars */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wdtlb_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_XTSYNC }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_iitlb_args[] = {
+ { { 4 /* ars */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_iitlb_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_ritlb_args[] = {
+ { { 6 /* art */ }, 'o' },
+ { { 4 /* ars */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_ritlb_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_witlb_args[] = {
+ { { 6 /* art */ }, 'i' },
+ { { 4 /* ars */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_witlb_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_ldpte_stateArgs[] = {
+ { { STATE_PTBASE }, 'i' },
+ { { STATE_EXCVADDR }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_hwwitlba_stateArgs[] = {
+ { { STATE_EXCVADDR }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_hwwdtlba_stateArgs[] = {
+ { { STATE_EXCVADDR }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_cpenable_args[] = {
+ { { 6 /* art */ }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_cpenable_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_CPENABLE }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_cpenable_args[] = {
+ { { 6 /* art */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_cpenable_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_CPENABLE }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_cpenable_args[] = {
+ { { 6 /* art */ }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_cpenable_stateArgs[] = {
+ { { STATE_PSEXCM }, 'i' },
+ { { STATE_PSRING }, 'i' },
+ { { STATE_CPENABLE }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_clamp_args[] = {
+ { { 3 /* arr */ }, 'o' },
+ { { 4 /* ars */ }, 'i' },
+ { { 58 /* tp7 */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_minmax_args[] = {
+ { { 3 /* arr */ }, 'o' },
+ { { 4 /* ars */ }, 'i' },
+ { { 6 /* art */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_nsa_args[] = {
+ { { 6 /* art */ }, 'o' },
+ { { 4 /* ars */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_sx_args[] = {
+ { { 3 /* arr */ }, 'o' },
+ { { 4 /* ars */ }, 'i' },
+ { { 58 /* tp7 */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_l32ai_args[] = {
+ { { 6 /* art */ }, 'o' },
+ { { 4 /* ars */ }, 'i' },
+ { { 21 /* uimm8x4 */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_s32ri_args[] = {
+ { { 6 /* art */ }, 'i' },
+ { { 4 /* ars */ }, 'i' },
+ { { 21 /* uimm8x4 */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_s32c1i_args[] = {
+ { { 6 /* art */ }, 'm' },
+ { { 4 /* ars */ }, 'i' },
+ { { 21 /* uimm8x4 */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_s32c1i_stateArgs[] = {
+ { { STATE_SCOMPARE1 }, 'i' },
+ { { STATE_SCOMPARE1 }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_scompare1_args[] = {
+ { { 6 /* art */ }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_rsr_scompare1_stateArgs[] = {
+ { { STATE_SCOMPARE1 }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_scompare1_args[] = {
+ { { 6 /* art */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wsr_scompare1_stateArgs[] = {
+ { { STATE_SCOMPARE1 }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_scompare1_args[] = {
+ { { 6 /* art */ }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_xsr_scompare1_stateArgs[] = {
+ { { STATE_SCOMPARE1 }, 'm' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_div_args[] = {
+ { { 3 /* arr */ }, 'o' },
+ { { 4 /* ars */ }, 'i' },
+ { { 6 /* art */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_mul32_args[] = {
+ { { 3 /* arr */ }, 'o' },
+ { { 4 /* ars */ }, 'i' },
+ { { 6 /* art */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_rur_fcr_args[] = {
+ { { 3 /* arr */ }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_rur_fcr_stateArgs[] = {
+ { { STATE_RoundMode }, 'i' },
+ { { STATE_InvalidEnable }, 'i' },
+ { { STATE_DivZeroEnable }, 'i' },
+ { { STATE_OverflowEnable }, 'i' },
+ { { STATE_UnderflowEnable }, 'i' },
+ { { STATE_InexactEnable }, 'i' },
+ { { STATE_FPreserved20 }, 'i' },
+ { { STATE_FPreserved5 }, 'i' },
+ { { STATE_CPENABLE }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_wur_fcr_args[] = {
+ { { 6 /* art */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_wur_fcr_stateArgs[] = {
+ { { STATE_RoundMode }, 'o' },
+ { { STATE_InvalidEnable }, 'o' },
+ { { STATE_DivZeroEnable }, 'o' },
+ { { STATE_OverflowEnable }, 'o' },
+ { { STATE_UnderflowEnable }, 'o' },
+ { { STATE_InexactEnable }, 'o' },
+ { { STATE_FPreserved20 }, 'o' },
+ { { STATE_FPreserved5 }, 'o' },
+ { { STATE_CPENABLE }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_rur_fsr_args[] = {
+ { { 3 /* arr */ }, 'o' }
+};
+
+static xtensa_arg_internal Iclass_rur_fsr_stateArgs[] = {
+ { { STATE_InvalidFlag }, 'i' },
+ { { STATE_DivZeroFlag }, 'i' },
+ { { STATE_OverflowFlag }, 'i' },
+ { { STATE_UnderflowFlag }, 'i' },
+ { { STATE_InexactFlag }, 'i' },
+ { { STATE_FPreserved20a }, 'i' },
+ { { STATE_FPreserved7 }, 'i' },
+ { { STATE_CPENABLE }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_wur_fsr_args[] = {
+ { { 6 /* art */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_wur_fsr_stateArgs[] = {
+ { { STATE_InvalidFlag }, 'o' },
+ { { STATE_DivZeroFlag }, 'o' },
+ { { STATE_OverflowFlag }, 'o' },
+ { { STATE_UnderflowFlag }, 'o' },
+ { { STATE_InexactFlag }, 'o' },
+ { { STATE_FPreserved20a }, 'o' },
+ { { STATE_FPreserved7 }, 'o' },
+ { { STATE_CPENABLE }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_fp_args[] = {
+ { { 62 /* frr */ }, 'o' },
+ { { 63 /* frs */ }, 'i' },
+ { { 64 /* frt */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_fp_stateArgs[] = {
+ { { STATE_RoundMode }, 'i' },
+ { { STATE_CPENABLE }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_fp_mac_args[] = {
+ { { 62 /* frr */ }, 'm' },
+ { { 63 /* frs */ }, 'i' },
+ { { 64 /* frt */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_fp_mac_stateArgs[] = {
+ { { STATE_RoundMode }, 'i' },
+ { { STATE_CPENABLE }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_fp_cmov_args[] = {
+ { { 62 /* frr */ }, 'm' },
+ { { 63 /* frs */ }, 'i' },
+ { { 42 /* bt */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_fp_cmov_stateArgs[] = {
+ { { STATE_CPENABLE }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_fp_mov_args[] = {
+ { { 62 /* frr */ }, 'm' },
+ { { 63 /* frs */ }, 'i' },
+ { { 6 /* art */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_fp_mov_stateArgs[] = {
+ { { STATE_CPENABLE }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_fp_mov2_args[] = {
+ { { 62 /* frr */ }, 'o' },
+ { { 63 /* frs */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_fp_mov2_stateArgs[] = {
+ { { STATE_CPENABLE }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_fp_cmp_args[] = {
+ { { 44 /* br */ }, 'o' },
+ { { 63 /* frs */ }, 'i' },
+ { { 64 /* frt */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_fp_cmp_stateArgs[] = {
+ { { STATE_CPENABLE }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_fp_float_args[] = {
+ { { 62 /* frr */ }, 'o' },
+ { { 4 /* ars */ }, 'i' },
+ { { 65 /* t */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_fp_float_stateArgs[] = {
+ { { STATE_RoundMode }, 'i' },
+ { { STATE_CPENABLE }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_fp_int_args[] = {
+ { { 3 /* arr */ }, 'o' },
+ { { 63 /* frs */ }, 'i' },
+ { { 65 /* t */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_fp_int_stateArgs[] = {
+ { { STATE_CPENABLE }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_fp_rfr_args[] = {
+ { { 3 /* arr */ }, 'o' },
+ { { 63 /* frs */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_fp_rfr_stateArgs[] = {
+ { { STATE_CPENABLE }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_fp_wfr_args[] = {
+ { { 62 /* frr */ }, 'o' },
+ { { 4 /* ars */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_fp_wfr_stateArgs[] = {
+ { { STATE_CPENABLE }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_fp_lsi_args[] = {
+ { { 64 /* frt */ }, 'o' },
+ { { 4 /* ars */ }, 'i' },
+ { { 61 /* cimm8x4 */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_fp_lsi_stateArgs[] = {
+ { { STATE_CPENABLE }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_fp_lsiu_args[] = {
+ { { 64 /* frt */ }, 'o' },
+ { { 4 /* ars */ }, 'm' },
+ { { 61 /* cimm8x4 */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_fp_lsiu_stateArgs[] = {
+ { { STATE_CPENABLE }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_fp_lsx_args[] = {
+ { { 62 /* frr */ }, 'o' },
+ { { 4 /* ars */ }, 'i' },
+ { { 6 /* art */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_fp_lsx_stateArgs[] = {
+ { { STATE_CPENABLE }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_fp_lsxu_args[] = {
+ { { 62 /* frr */ }, 'o' },
+ { { 4 /* ars */ }, 'm' },
+ { { 6 /* art */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_fp_lsxu_stateArgs[] = {
+ { { STATE_CPENABLE }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_fp_ssi_args[] = {
+ { { 64 /* frt */ }, 'i' },
+ { { 4 /* ars */ }, 'i' },
+ { { 61 /* cimm8x4 */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_fp_ssi_stateArgs[] = {
+ { { STATE_CPENABLE }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_fp_ssiu_args[] = {
+ { { 64 /* frt */ }, 'i' },
+ { { 4 /* ars */ }, 'm' },
+ { { 61 /* cimm8x4 */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_fp_ssiu_stateArgs[] = {
+ { { STATE_CPENABLE }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_fp_ssx_args[] = {
+ { { 62 /* frr */ }, 'i' },
+ { { 4 /* ars */ }, 'i' },
+ { { 6 /* art */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_fp_ssx_stateArgs[] = {
+ { { STATE_CPENABLE }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_fp_ssxu_args[] = {
+ { { 62 /* frr */ }, 'i' },
+ { { 4 /* ars */ }, 'm' },
+ { { 6 /* art */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_fp_ssxu_stateArgs[] = {
+ { { STATE_CPENABLE }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wb18_0_args[] = {
+ { { 4 /* ars */ }, 'i' },
+ { { 60 /* xt_wbr18_label */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wb18_1_args[] = {
+ { { 4 /* ars */ }, 'i' },
+ { { 17 /* b4const */ }, 'i' },
+ { { 60 /* xt_wbr18_label */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wb18_2_args[] = {
+ { { 4 /* ars */ }, 'i' },
+ { { 18 /* b4constu */ }, 'i' },
+ { { 60 /* xt_wbr18_label */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wb18_3_args[] = {
+ { { 4 /* ars */ }, 'i' },
+ { { 67 /* bbi */ }, 'i' },
+ { { 60 /* xt_wbr18_label */ }, 'i' }
+};
+
+static xtensa_arg_internal Iclass_xt_iclass_wb18_4_args[] = {
+ { { 4 /* ars */ }, 'i' },
+ { { 6 /* art */ }, 'i' },
+ { { 60 /* xt_wbr18_label */ }, 'i' }
+};
+
+static xtensa_iclass_internal iclasses[] = {
+ { 0, 0 /* xt_iclass_excw */,
+ 0, 0, 0, 0 },
+ { 0, 0 /* xt_iclass_rfe */,
+ 3, Iclass_xt_iclass_rfe_stateArgs, 0, 0 },
+ { 0, 0 /* xt_iclass_rfde */,
+ 3, Iclass_xt_iclass_rfde_stateArgs, 0, 0 },
+ { 0, 0 /* xt_iclass_syscall */,
+ 0, 0, 0, 0 },
+ { 0, 0 /* xt_iclass_simcall */,
+ 0, 0, 0, 0 },
+ { 2, Iclass_xt_iclass_call12_args,
+ 1, Iclass_xt_iclass_call12_stateArgs, 0, 0 },
+ { 2, Iclass_xt_iclass_call8_args,
+ 1, Iclass_xt_iclass_call8_stateArgs, 0, 0 },
+ { 2, Iclass_xt_iclass_call4_args,
+ 1, Iclass_xt_iclass_call4_stateArgs, 0, 0 },
+ { 2, Iclass_xt_iclass_callx12_args,
+ 1, Iclass_xt_iclass_callx12_stateArgs, 0, 0 },
+ { 2, Iclass_xt_iclass_callx8_args,
+ 1, Iclass_xt_iclass_callx8_stateArgs, 0, 0 },
+ { 2, Iclass_xt_iclass_callx4_args,
+ 1, Iclass_xt_iclass_callx4_stateArgs, 0, 0 },
+ { 3, Iclass_xt_iclass_entry_args,
+ 5, Iclass_xt_iclass_entry_stateArgs, 0, 0 },
+ { 2, Iclass_xt_iclass_movsp_args,
+ 2, Iclass_xt_iclass_movsp_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_rotw_args,
+ 3, Iclass_xt_iclass_rotw_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_retw_args,
+ 4, Iclass_xt_iclass_retw_stateArgs, 0, 0 },
+ { 0, 0 /* xt_iclass_rfwou */,
+ 6, Iclass_xt_iclass_rfwou_stateArgs, 0, 0 },
+ { 3, Iclass_xt_iclass_l32e_args,
+ 2, Iclass_xt_iclass_l32e_stateArgs, 0, 0 },
+ { 3, Iclass_xt_iclass_s32e_args,
+ 2, Iclass_xt_iclass_s32e_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_rsr_windowbase_args,
+ 3, Iclass_xt_iclass_rsr_windowbase_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_wsr_windowbase_args,
+ 3, Iclass_xt_iclass_wsr_windowbase_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_xsr_windowbase_args,
+ 3, Iclass_xt_iclass_xsr_windowbase_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_rsr_windowstart_args,
+ 3, Iclass_xt_iclass_rsr_windowstart_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_wsr_windowstart_args,
+ 3, Iclass_xt_iclass_wsr_windowstart_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_xsr_windowstart_args,
+ 3, Iclass_xt_iclass_xsr_windowstart_stateArgs, 0, 0 },
+ { 3, Iclass_xt_iclass_add_n_args,
+ 0, 0, 0, 0 },
+ { 3, Iclass_xt_iclass_addi_n_args,
+ 0, 0, 0, 0 },
+ { 2, Iclass_xt_iclass_bz6_args,
+ 0, 0, 0, 0 },
+ { 0, 0 /* xt_iclass_ill_n */,
+ 0, 0, 0, 0 },
+ { 3, Iclass_xt_iclass_loadi4_args,
+ 0, 0, 0, 0 },
+ { 2, Iclass_xt_iclass_mov_n_args,
+ 0, 0, 0, 0 },
+ { 2, Iclass_xt_iclass_movi_n_args,
+ 0, 0, 0, 0 },
+ { 0, 0 /* xt_iclass_nopn */,
+ 0, 0, 0, 0 },
+ { 1, Iclass_xt_iclass_retn_args,
+ 0, 0, 0, 0 },
+ { 3, Iclass_xt_iclass_storei4_args,
+ 0, 0, 0, 0 },
+ { 1, Iclass_rur_threadptr_args,
+ 1, Iclass_rur_threadptr_stateArgs, 0, 0 },
+ { 1, Iclass_wur_threadptr_args,
+ 1, Iclass_wur_threadptr_stateArgs, 0, 0 },
+ { 3, Iclass_xt_iclass_addi_args,
+ 0, 0, 0, 0 },
+ { 3, Iclass_xt_iclass_addmi_args,
+ 0, 0, 0, 0 },
+ { 3, Iclass_xt_iclass_addsub_args,
+ 0, 0, 0, 0 },
+ { 3, Iclass_xt_iclass_bit_args,
+ 0, 0, 0, 0 },
+ { 3, Iclass_xt_iclass_bsi8_args,
+ 0, 0, 0, 0 },
+ { 3, Iclass_xt_iclass_bsi8b_args,
+ 0, 0, 0, 0 },
+ { 3, Iclass_xt_iclass_bsi8u_args,
+ 0, 0, 0, 0 },
+ { 3, Iclass_xt_iclass_bst8_args,
+ 0, 0, 0, 0 },
+ { 2, Iclass_xt_iclass_bsz12_args,
+ 0, 0, 0, 0 },
+ { 2, Iclass_xt_iclass_call0_args,
+ 0, 0, 0, 0 },
+ { 2, Iclass_xt_iclass_callx0_args,
+ 0, 0, 0, 0 },
+ { 4, Iclass_xt_iclass_exti_args,
+ 0, 0, 0, 0 },
+ { 0, 0 /* xt_iclass_ill */,
+ 0, 0, 0, 0 },
+ { 1, Iclass_xt_iclass_jump_args,
+ 0, 0, 0, 0 },
+ { 1, Iclass_xt_iclass_jumpx_args,
+ 0, 0, 0, 0 },
+ { 3, Iclass_xt_iclass_l16ui_args,
+ 0, 0, 0, 0 },
+ { 3, Iclass_xt_iclass_l16si_args,
+ 0, 0, 0, 0 },
+ { 3, Iclass_xt_iclass_l32i_args,
+ 0, 0, 0, 0 },
+ { 2, Iclass_xt_iclass_l32r_args,
+ 2, Iclass_xt_iclass_l32r_stateArgs, 0, 0 },
+ { 3, Iclass_xt_iclass_l8i_args,
+ 0, 0, 0, 0 },
+ { 2, Iclass_xt_iclass_loop_args,
+ 3, Iclass_xt_iclass_loop_stateArgs, 0, 0 },
+ { 2, Iclass_xt_iclass_loopz_args,
+ 3, Iclass_xt_iclass_loopz_stateArgs, 0, 0 },
+ { 2, Iclass_xt_iclass_movi_args,
+ 0, 0, 0, 0 },
+ { 3, Iclass_xt_iclass_movz_args,
+ 0, 0, 0, 0 },
+ { 2, Iclass_xt_iclass_neg_args,
+ 0, 0, 0, 0 },
+ { 0, 0 /* xt_iclass_nop */,
+ 0, 0, 0, 0 },
+ { 1, Iclass_xt_iclass_return_args,
+ 0, 0, 0, 0 },
+ { 3, Iclass_xt_iclass_s16i_args,
+ 0, 0, 0, 0 },
+ { 3, Iclass_xt_iclass_s32i_args,
+ 0, 0, 0, 0 },
+ { 3, Iclass_xt_iclass_s8i_args,
+ 0, 0, 0, 0 },
+ { 1, Iclass_xt_iclass_sar_args,
+ 1, Iclass_xt_iclass_sar_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_sari_args,
+ 1, Iclass_xt_iclass_sari_stateArgs, 0, 0 },
+ { 2, Iclass_xt_iclass_shifts_args,
+ 1, Iclass_xt_iclass_shifts_stateArgs, 0, 0 },
+ { 3, Iclass_xt_iclass_shiftst_args,
+ 1, Iclass_xt_iclass_shiftst_stateArgs, 0, 0 },
+ { 2, Iclass_xt_iclass_shiftt_args,
+ 1, Iclass_xt_iclass_shiftt_stateArgs, 0, 0 },
+ { 3, Iclass_xt_iclass_slli_args,
+ 0, 0, 0, 0 },
+ { 3, Iclass_xt_iclass_srai_args,
+ 0, 0, 0, 0 },
+ { 3, Iclass_xt_iclass_srli_args,
+ 0, 0, 0, 0 },
+ { 0, 0 /* xt_iclass_memw */,
+ 0, 0, 0, 0 },
+ { 0, 0 /* xt_iclass_extw */,
+ 0, 0, 0, 0 },
+ { 0, 0 /* xt_iclass_isync */,
+ 0, 0, 0, 0 },
+ { 0, 0 /* xt_iclass_sync */,
+ 1, Iclass_xt_iclass_sync_stateArgs, 0, 0 },
+ { 2, Iclass_xt_iclass_rsil_args,
+ 7, Iclass_xt_iclass_rsil_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_rsr_lend_args,
+ 1, Iclass_xt_iclass_rsr_lend_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_wsr_lend_args,
+ 1, Iclass_xt_iclass_wsr_lend_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_xsr_lend_args,
+ 1, Iclass_xt_iclass_xsr_lend_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_rsr_lcount_args,
+ 1, Iclass_xt_iclass_rsr_lcount_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_wsr_lcount_args,
+ 2, Iclass_xt_iclass_wsr_lcount_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_xsr_lcount_args,
+ 2, Iclass_xt_iclass_xsr_lcount_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_rsr_lbeg_args,
+ 1, Iclass_xt_iclass_rsr_lbeg_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_wsr_lbeg_args,
+ 1, Iclass_xt_iclass_wsr_lbeg_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_xsr_lbeg_args,
+ 1, Iclass_xt_iclass_xsr_lbeg_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_rsr_sar_args,
+ 1, Iclass_xt_iclass_rsr_sar_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_wsr_sar_args,
+ 2, Iclass_xt_iclass_wsr_sar_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_xsr_sar_args,
+ 1, Iclass_xt_iclass_xsr_sar_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_rsr_litbase_args,
+ 2, Iclass_xt_iclass_rsr_litbase_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_wsr_litbase_args,
+ 2, Iclass_xt_iclass_wsr_litbase_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_xsr_litbase_args,
+ 2, Iclass_xt_iclass_xsr_litbase_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_rsr_176_args,
+ 2, Iclass_xt_iclass_rsr_176_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_rsr_208_args,
+ 2, Iclass_xt_iclass_rsr_208_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_rsr_ps_args,
+ 7, Iclass_xt_iclass_rsr_ps_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_wsr_ps_args,
+ 7, Iclass_xt_iclass_wsr_ps_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_xsr_ps_args,
+ 7, Iclass_xt_iclass_xsr_ps_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_rsr_epc1_args,
+ 3, Iclass_xt_iclass_rsr_epc1_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_wsr_epc1_args,
+ 3, Iclass_xt_iclass_wsr_epc1_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_xsr_epc1_args,
+ 3, Iclass_xt_iclass_xsr_epc1_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_rsr_excsave1_args,
+ 3, Iclass_xt_iclass_rsr_excsave1_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_wsr_excsave1_args,
+ 3, Iclass_xt_iclass_wsr_excsave1_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_xsr_excsave1_args,
+ 3, Iclass_xt_iclass_xsr_excsave1_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_rsr_epc2_args,
+ 3, Iclass_xt_iclass_rsr_epc2_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_wsr_epc2_args,
+ 3, Iclass_xt_iclass_wsr_epc2_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_xsr_epc2_args,
+ 3, Iclass_xt_iclass_xsr_epc2_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_rsr_excsave2_args,
+ 3, Iclass_xt_iclass_rsr_excsave2_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_wsr_excsave2_args,
+ 3, Iclass_xt_iclass_wsr_excsave2_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_xsr_excsave2_args,
+ 3, Iclass_xt_iclass_xsr_excsave2_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_rsr_epc3_args,
+ 3, Iclass_xt_iclass_rsr_epc3_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_wsr_epc3_args,
+ 3, Iclass_xt_iclass_wsr_epc3_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_xsr_epc3_args,
+ 3, Iclass_xt_iclass_xsr_epc3_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_rsr_excsave3_args,
+ 3, Iclass_xt_iclass_rsr_excsave3_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_wsr_excsave3_args,
+ 3, Iclass_xt_iclass_wsr_excsave3_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_xsr_excsave3_args,
+ 3, Iclass_xt_iclass_xsr_excsave3_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_rsr_epc4_args,
+ 3, Iclass_xt_iclass_rsr_epc4_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_wsr_epc4_args,
+ 3, Iclass_xt_iclass_wsr_epc4_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_xsr_epc4_args,
+ 3, Iclass_xt_iclass_xsr_epc4_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_rsr_excsave4_args,
+ 3, Iclass_xt_iclass_rsr_excsave4_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_wsr_excsave4_args,
+ 3, Iclass_xt_iclass_wsr_excsave4_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_xsr_excsave4_args,
+ 3, Iclass_xt_iclass_xsr_excsave4_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_rsr_epc5_args,
+ 3, Iclass_xt_iclass_rsr_epc5_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_wsr_epc5_args,
+ 3, Iclass_xt_iclass_wsr_epc5_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_xsr_epc5_args,
+ 3, Iclass_xt_iclass_xsr_epc5_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_rsr_excsave5_args,
+ 3, Iclass_xt_iclass_rsr_excsave5_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_wsr_excsave5_args,
+ 3, Iclass_xt_iclass_wsr_excsave5_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_xsr_excsave5_args,
+ 3, Iclass_xt_iclass_xsr_excsave5_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_rsr_epc6_args,
+ 3, Iclass_xt_iclass_rsr_epc6_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_wsr_epc6_args,
+ 3, Iclass_xt_iclass_wsr_epc6_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_xsr_epc6_args,
+ 3, Iclass_xt_iclass_xsr_epc6_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_rsr_excsave6_args,
+ 3, Iclass_xt_iclass_rsr_excsave6_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_wsr_excsave6_args,
+ 3, Iclass_xt_iclass_wsr_excsave6_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_xsr_excsave6_args,
+ 3, Iclass_xt_iclass_xsr_excsave6_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_rsr_epc7_args,
+ 3, Iclass_xt_iclass_rsr_epc7_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_wsr_epc7_args,
+ 3, Iclass_xt_iclass_wsr_epc7_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_xsr_epc7_args,
+ 3, Iclass_xt_iclass_xsr_epc7_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_rsr_excsave7_args,
+ 3, Iclass_xt_iclass_rsr_excsave7_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_wsr_excsave7_args,
+ 3, Iclass_xt_iclass_wsr_excsave7_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_xsr_excsave7_args,
+ 3, Iclass_xt_iclass_xsr_excsave7_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_rsr_eps2_args,
+ 3, Iclass_xt_iclass_rsr_eps2_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_wsr_eps2_args,
+ 3, Iclass_xt_iclass_wsr_eps2_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_xsr_eps2_args,
+ 3, Iclass_xt_iclass_xsr_eps2_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_rsr_eps3_args,
+ 3, Iclass_xt_iclass_rsr_eps3_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_wsr_eps3_args,
+ 3, Iclass_xt_iclass_wsr_eps3_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_xsr_eps3_args,
+ 3, Iclass_xt_iclass_xsr_eps3_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_rsr_eps4_args,
+ 3, Iclass_xt_iclass_rsr_eps4_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_wsr_eps4_args,
+ 3, Iclass_xt_iclass_wsr_eps4_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_xsr_eps4_args,
+ 3, Iclass_xt_iclass_xsr_eps4_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_rsr_eps5_args,
+ 3, Iclass_xt_iclass_rsr_eps5_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_wsr_eps5_args,
+ 3, Iclass_xt_iclass_wsr_eps5_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_xsr_eps5_args,
+ 3, Iclass_xt_iclass_xsr_eps5_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_rsr_eps6_args,
+ 3, Iclass_xt_iclass_rsr_eps6_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_wsr_eps6_args,
+ 3, Iclass_xt_iclass_wsr_eps6_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_xsr_eps6_args,
+ 3, Iclass_xt_iclass_xsr_eps6_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_rsr_eps7_args,
+ 3, Iclass_xt_iclass_rsr_eps7_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_wsr_eps7_args,
+ 3, Iclass_xt_iclass_wsr_eps7_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_xsr_eps7_args,
+ 3, Iclass_xt_iclass_xsr_eps7_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_rsr_excvaddr_args,
+ 3, Iclass_xt_iclass_rsr_excvaddr_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_wsr_excvaddr_args,
+ 3, Iclass_xt_iclass_wsr_excvaddr_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_xsr_excvaddr_args,
+ 3, Iclass_xt_iclass_xsr_excvaddr_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_rsr_depc_args,
+ 3, Iclass_xt_iclass_rsr_depc_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_wsr_depc_args,
+ 3, Iclass_xt_iclass_wsr_depc_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_xsr_depc_args,
+ 3, Iclass_xt_iclass_xsr_depc_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_rsr_exccause_args,
+ 4, Iclass_xt_iclass_rsr_exccause_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_wsr_exccause_args,
+ 3, Iclass_xt_iclass_wsr_exccause_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_xsr_exccause_args,
+ 3, Iclass_xt_iclass_xsr_exccause_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_rsr_misc0_args,
+ 3, Iclass_xt_iclass_rsr_misc0_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_wsr_misc0_args,
+ 3, Iclass_xt_iclass_wsr_misc0_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_xsr_misc0_args,
+ 3, Iclass_xt_iclass_xsr_misc0_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_rsr_misc1_args,
+ 3, Iclass_xt_iclass_rsr_misc1_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_wsr_misc1_args,
+ 3, Iclass_xt_iclass_wsr_misc1_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_xsr_misc1_args,
+ 3, Iclass_xt_iclass_xsr_misc1_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_rsr_misc2_args,
+ 3, Iclass_xt_iclass_rsr_misc2_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_wsr_misc2_args,
+ 3, Iclass_xt_iclass_wsr_misc2_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_xsr_misc2_args,
+ 3, Iclass_xt_iclass_xsr_misc2_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_rsr_misc3_args,
+ 3, Iclass_xt_iclass_rsr_misc3_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_wsr_misc3_args,
+ 3, Iclass_xt_iclass_wsr_misc3_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_xsr_misc3_args,
+ 3, Iclass_xt_iclass_xsr_misc3_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_rsr_prid_args,
+ 2, Iclass_xt_iclass_rsr_prid_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_rsr_vecbase_args,
+ 3, Iclass_xt_iclass_rsr_vecbase_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_wsr_vecbase_args,
+ 3, Iclass_xt_iclass_wsr_vecbase_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_xsr_vecbase_args,
+ 3, Iclass_xt_iclass_xsr_vecbase_stateArgs, 0, 0 },
+ { 2, Iclass_xt_iclass_mac16_aa_args,
+ 1, Iclass_xt_iclass_mac16_aa_stateArgs, 0, 0 },
+ { 2, Iclass_xt_iclass_mac16_ad_args,
+ 1, Iclass_xt_iclass_mac16_ad_stateArgs, 0, 0 },
+ { 2, Iclass_xt_iclass_mac16_da_args,
+ 1, Iclass_xt_iclass_mac16_da_stateArgs, 0, 0 },
+ { 2, Iclass_xt_iclass_mac16_dd_args,
+ 1, Iclass_xt_iclass_mac16_dd_stateArgs, 0, 0 },
+ { 2, Iclass_xt_iclass_mac16a_aa_args,
+ 1, Iclass_xt_iclass_mac16a_aa_stateArgs, 0, 0 },
+ { 2, Iclass_xt_iclass_mac16a_ad_args,
+ 1, Iclass_xt_iclass_mac16a_ad_stateArgs, 0, 0 },
+ { 2, Iclass_xt_iclass_mac16a_da_args,
+ 1, Iclass_xt_iclass_mac16a_da_stateArgs, 0, 0 },
+ { 2, Iclass_xt_iclass_mac16a_dd_args,
+ 1, Iclass_xt_iclass_mac16a_dd_stateArgs, 0, 0 },
+ { 4, Iclass_xt_iclass_mac16al_da_args,
+ 1, Iclass_xt_iclass_mac16al_da_stateArgs, 0, 0 },
+ { 4, Iclass_xt_iclass_mac16al_dd_args,
+ 1, Iclass_xt_iclass_mac16al_dd_stateArgs, 0, 0 },
+ { 2, Iclass_xt_iclass_mac16_l_args,
+ 0, 0, 0, 0 },
+ { 3, Iclass_xt_iclass_mul16_args,
+ 0, 0, 0, 0 },
+ { 2, Iclass_xt_iclass_rsr_m0_args,
+ 0, 0, 0, 0 },
+ { 2, Iclass_xt_iclass_wsr_m0_args,
+ 0, 0, 0, 0 },
+ { 2, Iclass_xt_iclass_xsr_m0_args,
+ 0, 0, 0, 0 },
+ { 2, Iclass_xt_iclass_rsr_m1_args,
+ 0, 0, 0, 0 },
+ { 2, Iclass_xt_iclass_wsr_m1_args,
+ 0, 0, 0, 0 },
+ { 2, Iclass_xt_iclass_xsr_m1_args,
+ 0, 0, 0, 0 },
+ { 2, Iclass_xt_iclass_rsr_m2_args,
+ 0, 0, 0, 0 },
+ { 2, Iclass_xt_iclass_wsr_m2_args,
+ 0, 0, 0, 0 },
+ { 2, Iclass_xt_iclass_xsr_m2_args,
+ 0, 0, 0, 0 },
+ { 2, Iclass_xt_iclass_rsr_m3_args,
+ 0, 0, 0, 0 },
+ { 2, Iclass_xt_iclass_wsr_m3_args,
+ 0, 0, 0, 0 },
+ { 2, Iclass_xt_iclass_xsr_m3_args,
+ 0, 0, 0, 0 },
+ { 1, Iclass_xt_iclass_rsr_acclo_args,
+ 1, Iclass_xt_iclass_rsr_acclo_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_wsr_acclo_args,
+ 1, Iclass_xt_iclass_wsr_acclo_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_xsr_acclo_args,
+ 1, Iclass_xt_iclass_xsr_acclo_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_rsr_acchi_args,
+ 1, Iclass_xt_iclass_rsr_acchi_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_wsr_acchi_args,
+ 1, Iclass_xt_iclass_wsr_acchi_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_xsr_acchi_args,
+ 1, Iclass_xt_iclass_xsr_acchi_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_rfi_args,
+ 21, Iclass_xt_iclass_rfi_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_wait_args,
+ 3, Iclass_xt_iclass_wait_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_rsr_interrupt_args,
+ 3, Iclass_xt_iclass_rsr_interrupt_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_wsr_intset_args,
+ 4, Iclass_xt_iclass_wsr_intset_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_wsr_intclear_args,
+ 4, Iclass_xt_iclass_wsr_intclear_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_rsr_intenable_args,
+ 3, Iclass_xt_iclass_rsr_intenable_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_wsr_intenable_args,
+ 3, Iclass_xt_iclass_wsr_intenable_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_xsr_intenable_args,
+ 3, Iclass_xt_iclass_xsr_intenable_stateArgs, 0, 0 },
+ { 2, Iclass_xt_iclass_break_args,
+ 2, Iclass_xt_iclass_break_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_break_n_args,
+ 2, Iclass_xt_iclass_break_n_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_rsr_dbreaka0_args,
+ 3, Iclass_xt_iclass_rsr_dbreaka0_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_wsr_dbreaka0_args,
+ 4, Iclass_xt_iclass_wsr_dbreaka0_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_xsr_dbreaka0_args,
+ 4, Iclass_xt_iclass_xsr_dbreaka0_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_rsr_dbreakc0_args,
+ 3, Iclass_xt_iclass_rsr_dbreakc0_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_wsr_dbreakc0_args,
+ 4, Iclass_xt_iclass_wsr_dbreakc0_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_xsr_dbreakc0_args,
+ 4, Iclass_xt_iclass_xsr_dbreakc0_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_rsr_dbreaka1_args,
+ 3, Iclass_xt_iclass_rsr_dbreaka1_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_wsr_dbreaka1_args,
+ 4, Iclass_xt_iclass_wsr_dbreaka1_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_xsr_dbreaka1_args,
+ 4, Iclass_xt_iclass_xsr_dbreaka1_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_rsr_dbreakc1_args,
+ 3, Iclass_xt_iclass_rsr_dbreakc1_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_wsr_dbreakc1_args,
+ 4, Iclass_xt_iclass_wsr_dbreakc1_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_xsr_dbreakc1_args,
+ 4, Iclass_xt_iclass_xsr_dbreakc1_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_rsr_ibreaka0_args,
+ 3, Iclass_xt_iclass_rsr_ibreaka0_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_wsr_ibreaka0_args,
+ 3, Iclass_xt_iclass_wsr_ibreaka0_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_xsr_ibreaka0_args,
+ 3, Iclass_xt_iclass_xsr_ibreaka0_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_rsr_ibreaka1_args,
+ 3, Iclass_xt_iclass_rsr_ibreaka1_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_wsr_ibreaka1_args,
+ 3, Iclass_xt_iclass_wsr_ibreaka1_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_xsr_ibreaka1_args,
+ 3, Iclass_xt_iclass_xsr_ibreaka1_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_rsr_ibreakenable_args,
+ 3, Iclass_xt_iclass_rsr_ibreakenable_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_wsr_ibreakenable_args,
+ 3, Iclass_xt_iclass_wsr_ibreakenable_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_xsr_ibreakenable_args,
+ 3, Iclass_xt_iclass_xsr_ibreakenable_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_rsr_debugcause_args,
+ 4, Iclass_xt_iclass_rsr_debugcause_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_wsr_debugcause_args,
+ 4, Iclass_xt_iclass_wsr_debugcause_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_xsr_debugcause_args,
+ 4, Iclass_xt_iclass_xsr_debugcause_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_rsr_icount_args,
+ 3, Iclass_xt_iclass_rsr_icount_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_wsr_icount_args,
+ 4, Iclass_xt_iclass_wsr_icount_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_xsr_icount_args,
+ 4, Iclass_xt_iclass_xsr_icount_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_rsr_icountlevel_args,
+ 3, Iclass_xt_iclass_rsr_icountlevel_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_wsr_icountlevel_args,
+ 3, Iclass_xt_iclass_wsr_icountlevel_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_xsr_icountlevel_args,
+ 3, Iclass_xt_iclass_xsr_icountlevel_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_rsr_ddr_args,
+ 3, Iclass_xt_iclass_rsr_ddr_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_wsr_ddr_args,
+ 4, Iclass_xt_iclass_wsr_ddr_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_xsr_ddr_args,
+ 4, Iclass_xt_iclass_xsr_ddr_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_rfdo_args,
+ 10, Iclass_xt_iclass_rfdo_stateArgs, 0, 0 },
+ { 0, 0 /* xt_iclass_rfdd */,
+ 1, Iclass_xt_iclass_rfdd_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_wsr_mmid_args,
+ 3, Iclass_xt_iclass_wsr_mmid_stateArgs, 0, 0 },
+ { 3, Iclass_xt_iclass_bbool1_args,
+ 0, 0, 0, 0 },
+ { 2, Iclass_xt_iclass_bbool4_args,
+ 0, 0, 0, 0 },
+ { 2, Iclass_xt_iclass_bbool8_args,
+ 0, 0, 0, 0 },
+ { 2, Iclass_xt_iclass_bbranch_args,
+ 0, 0, 0, 0 },
+ { 3, Iclass_xt_iclass_bmove_args,
+ 0, 0, 0, 0 },
+ { 2, Iclass_xt_iclass_RSR_BR_args,
+ 0, 0, 0, 0 },
+ { 2, Iclass_xt_iclass_WSR_BR_args,
+ 0, 0, 0, 0 },
+ { 2, Iclass_xt_iclass_XSR_BR_args,
+ 0, 0, 0, 0 },
+ { 1, Iclass_xt_iclass_rsr_ccount_args,
+ 3, Iclass_xt_iclass_rsr_ccount_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_wsr_ccount_args,
+ 4, Iclass_xt_iclass_wsr_ccount_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_xsr_ccount_args,
+ 4, Iclass_xt_iclass_xsr_ccount_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_rsr_ccompare0_args,
+ 3, Iclass_xt_iclass_rsr_ccompare0_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_wsr_ccompare0_args,
+ 4, Iclass_xt_iclass_wsr_ccompare0_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_xsr_ccompare0_args,
+ 4, Iclass_xt_iclass_xsr_ccompare0_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_rsr_ccompare1_args,
+ 3, Iclass_xt_iclass_rsr_ccompare1_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_wsr_ccompare1_args,
+ 4, Iclass_xt_iclass_wsr_ccompare1_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_xsr_ccompare1_args,
+ 4, Iclass_xt_iclass_xsr_ccompare1_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_rsr_ccompare2_args,
+ 3, Iclass_xt_iclass_rsr_ccompare2_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_wsr_ccompare2_args,
+ 4, Iclass_xt_iclass_wsr_ccompare2_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_xsr_ccompare2_args,
+ 4, Iclass_xt_iclass_xsr_ccompare2_stateArgs, 0, 0 },
+ { 2, Iclass_xt_iclass_icache_args,
+ 0, 0, 0, 0 },
+ { 2, Iclass_xt_iclass_icache_lock_args,
+ 2, Iclass_xt_iclass_icache_lock_stateArgs, 0, 0 },
+ { 2, Iclass_xt_iclass_icache_inv_args,
+ 2, Iclass_xt_iclass_icache_inv_stateArgs, 0, 0 },
+ { 2, Iclass_xt_iclass_licx_args,
+ 2, Iclass_xt_iclass_licx_stateArgs, 0, 0 },
+ { 2, Iclass_xt_iclass_sicx_args,
+ 2, Iclass_xt_iclass_sicx_stateArgs, 0, 0 },
+ { 2, Iclass_xt_iclass_dcache_args,
+ 0, 0, 0, 0 },
+ { 2, Iclass_xt_iclass_dcache_ind_args,
+ 2, Iclass_xt_iclass_dcache_ind_stateArgs, 0, 0 },
+ { 2, Iclass_xt_iclass_dcache_inv_args,
+ 2, Iclass_xt_iclass_dcache_inv_stateArgs, 0, 0 },
+ { 2, Iclass_xt_iclass_dpf_args,
+ 0, 0, 0, 0 },
+ { 2, Iclass_xt_iclass_dcache_lock_args,
+ 2, Iclass_xt_iclass_dcache_lock_stateArgs, 0, 0 },
+ { 2, Iclass_xt_iclass_sdct_args,
+ 2, Iclass_xt_iclass_sdct_stateArgs, 0, 0 },
+ { 2, Iclass_xt_iclass_ldct_args,
+ 2, Iclass_xt_iclass_ldct_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_wsr_ptevaddr_args,
+ 4, Iclass_xt_iclass_wsr_ptevaddr_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_rsr_ptevaddr_args,
+ 4, Iclass_xt_iclass_rsr_ptevaddr_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_xsr_ptevaddr_args,
+ 5, Iclass_xt_iclass_xsr_ptevaddr_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_rsr_rasid_args,
+ 5, Iclass_xt_iclass_rsr_rasid_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_wsr_rasid_args,
+ 6, Iclass_xt_iclass_wsr_rasid_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_xsr_rasid_args,
+ 6, Iclass_xt_iclass_xsr_rasid_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_rsr_itlbcfg_args,
+ 3, Iclass_xt_iclass_rsr_itlbcfg_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_wsr_itlbcfg_args,
+ 4, Iclass_xt_iclass_wsr_itlbcfg_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_xsr_itlbcfg_args,
+ 4, Iclass_xt_iclass_xsr_itlbcfg_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_rsr_dtlbcfg_args,
+ 3, Iclass_xt_iclass_rsr_dtlbcfg_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_wsr_dtlbcfg_args,
+ 4, Iclass_xt_iclass_wsr_dtlbcfg_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_xsr_dtlbcfg_args,
+ 4, Iclass_xt_iclass_xsr_dtlbcfg_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_idtlb_args,
+ 3, Iclass_xt_iclass_idtlb_stateArgs, 0, 0 },
+ { 2, Iclass_xt_iclass_rdtlb_args,
+ 2, Iclass_xt_iclass_rdtlb_stateArgs, 0, 0 },
+ { 2, Iclass_xt_iclass_wdtlb_args,
+ 3, Iclass_xt_iclass_wdtlb_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_iitlb_args,
+ 2, Iclass_xt_iclass_iitlb_stateArgs, 0, 0 },
+ { 2, Iclass_xt_iclass_ritlb_args,
+ 2, Iclass_xt_iclass_ritlb_stateArgs, 0, 0 },
+ { 2, Iclass_xt_iclass_witlb_args,
+ 2, Iclass_xt_iclass_witlb_stateArgs, 0, 0 },
+ { 0, 0 /* xt_iclass_ldpte */,
+ 2, Iclass_xt_iclass_ldpte_stateArgs, 0, 0 },
+ { 0, 0 /* xt_iclass_hwwitlba */,
+ 1, Iclass_xt_iclass_hwwitlba_stateArgs, 0, 0 },
+ { 0, 0 /* xt_iclass_hwwdtlba */,
+ 1, Iclass_xt_iclass_hwwdtlba_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_rsr_cpenable_args,
+ 3, Iclass_xt_iclass_rsr_cpenable_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_wsr_cpenable_args,
+ 3, Iclass_xt_iclass_wsr_cpenable_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_xsr_cpenable_args,
+ 3, Iclass_xt_iclass_xsr_cpenable_stateArgs, 0, 0 },
+ { 3, Iclass_xt_iclass_clamp_args,
+ 0, 0, 0, 0 },
+ { 3, Iclass_xt_iclass_minmax_args,
+ 0, 0, 0, 0 },
+ { 2, Iclass_xt_iclass_nsa_args,
+ 0, 0, 0, 0 },
+ { 3, Iclass_xt_iclass_sx_args,
+ 0, 0, 0, 0 },
+ { 3, Iclass_xt_iclass_l32ai_args,
+ 0, 0, 0, 0 },
+ { 3, Iclass_xt_iclass_s32ri_args,
+ 0, 0, 0, 0 },
+ { 3, Iclass_xt_iclass_s32c1i_args,
+ 2, Iclass_xt_iclass_s32c1i_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_rsr_scompare1_args,
+ 1, Iclass_xt_iclass_rsr_scompare1_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_wsr_scompare1_args,
+ 1, Iclass_xt_iclass_wsr_scompare1_stateArgs, 0, 0 },
+ { 1, Iclass_xt_iclass_xsr_scompare1_args,
+ 1, Iclass_xt_iclass_xsr_scompare1_stateArgs, 0, 0 },
+ { 3, Iclass_xt_iclass_div_args,
+ 0, 0, 0, 0 },
+ { 3, Iclass_xt_mul32_args,
+ 0, 0, 0, 0 },
+ { 1, Iclass_rur_fcr_args,
+ 9, Iclass_rur_fcr_stateArgs, 0, 0 },
+ { 1, Iclass_wur_fcr_args,
+ 9, Iclass_wur_fcr_stateArgs, 0, 0 },
+ { 1, Iclass_rur_fsr_args,
+ 8, Iclass_rur_fsr_stateArgs, 0, 0 },
+ { 1, Iclass_wur_fsr_args,
+ 8, Iclass_wur_fsr_stateArgs, 0, 0 },
+ { 3, Iclass_fp_args,
+ 2, Iclass_fp_stateArgs, 0, 0 },
+ { 3, Iclass_fp_mac_args,
+ 2, Iclass_fp_mac_stateArgs, 0, 0 },
+ { 3, Iclass_fp_cmov_args,
+ 1, Iclass_fp_cmov_stateArgs, 0, 0 },
+ { 3, Iclass_fp_mov_args,
+ 1, Iclass_fp_mov_stateArgs, 0, 0 },
+ { 2, Iclass_fp_mov2_args,
+ 1, Iclass_fp_mov2_stateArgs, 0, 0 },
+ { 3, Iclass_fp_cmp_args,
+ 1, Iclass_fp_cmp_stateArgs, 0, 0 },
+ { 3, Iclass_fp_float_args,
+ 2, Iclass_fp_float_stateArgs, 0, 0 },
+ { 3, Iclass_fp_int_args,
+ 1, Iclass_fp_int_stateArgs, 0, 0 },
+ { 2, Iclass_fp_rfr_args,
+ 1, Iclass_fp_rfr_stateArgs, 0, 0 },
+ { 2, Iclass_fp_wfr_args,
+ 1, Iclass_fp_wfr_stateArgs, 0, 0 },
+ { 3, Iclass_fp_lsi_args,
+ 1, Iclass_fp_lsi_stateArgs, 0, 0 },
+ { 3, Iclass_fp_lsiu_args,
+ 1, Iclass_fp_lsiu_stateArgs, 0, 0 },
+ { 3, Iclass_fp_lsx_args,
+ 1, Iclass_fp_lsx_stateArgs, 0, 0 },
+ { 3, Iclass_fp_lsxu_args,
+ 1, Iclass_fp_lsxu_stateArgs, 0, 0 },
+ { 3, Iclass_fp_ssi_args,
+ 1, Iclass_fp_ssi_stateArgs, 0, 0 },
+ { 3, Iclass_fp_ssiu_args,
+ 1, Iclass_fp_ssiu_stateArgs, 0, 0 },
+ { 3, Iclass_fp_ssx_args,
+ 1, Iclass_fp_ssx_stateArgs, 0, 0 },
+ { 3, Iclass_fp_ssxu_args,
+ 1, Iclass_fp_ssxu_stateArgs, 0, 0 },
+ { 2, Iclass_xt_iclass_wb18_0_args,
+ 0, 0, 0, 0 },
+ { 3, Iclass_xt_iclass_wb18_1_args,
+ 0, 0, 0, 0 },
+ { 3, Iclass_xt_iclass_wb18_2_args,
+ 0, 0, 0, 0 },
+ { 3, Iclass_xt_iclass_wb18_3_args,
+ 0, 0, 0, 0 },
+ { 3, Iclass_xt_iclass_wb18_4_args,
+ 0, 0, 0, 0 }
+};
+
+
+/* Opcode encodings. */
+
+static void
+Opcode_excw_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x2080;
+}
+
+static void
+Opcode_rfe_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x3000;
+}
+
+static void
+Opcode_rfde_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x3200;
+}
+
+static void
+Opcode_syscall_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x5000;
+}
+
+static void
+Opcode_simcall_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x5100;
+}
+
+static void
+Opcode_call12_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x35;
+}
+
+static void
+Opcode_call8_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x25;
+}
+
+static void
+Opcode_call4_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x15;
+}
+
+static void
+Opcode_callx12_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xf0;
+}
+
+static void
+Opcode_callx8_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xe0;
+}
+
+static void
+Opcode_callx4_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xd0;
+}
+
+static void
+Opcode_entry_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x36;
+}
+
+static void
+Opcode_movsp_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x1000;
+}
+
+static void
+Opcode_rotw_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x408000;
+}
+
+static void
+Opcode_retw_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x90;
+}
+
+static void
+Opcode_retw_n_Slot_inst16b_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xf01d;
+}
+
+static void
+Opcode_rfwo_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x3400;
+}
+
+static void
+Opcode_rfwu_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x3500;
+}
+
+static void
+Opcode_l32e_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x90000;
+}
+
+static void
+Opcode_s32e_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x490000;
+}
+
+static void
+Opcode_rsr_windowbase_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x34800;
+}
+
+static void
+Opcode_wsr_windowbase_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x134800;
+}
+
+static void
+Opcode_xsr_windowbase_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x614800;
+}
+
+static void
+Opcode_rsr_windowstart_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x34900;
+}
+
+static void
+Opcode_wsr_windowstart_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x134900;
+}
+
+static void
+Opcode_xsr_windowstart_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x614900;
+}
+
+static void
+Opcode_add_n_Slot_inst16a_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xa;
+}
+
+static void
+Opcode_addi_n_Slot_inst16a_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xb;
+}
+
+static void
+Opcode_addi_n_Slot_xt_flix64_slot2_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x3000;
+}
+
+static void
+Opcode_beqz_n_Slot_inst16b_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x8c;
+}
+
+static void
+Opcode_bnez_n_Slot_inst16b_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xcc;
+}
+
+static void
+Opcode_ill_n_Slot_inst16b_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xf06d;
+}
+
+static void
+Opcode_l32i_n_Slot_inst16a_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x8;
+}
+
+static void
+Opcode_mov_n_Slot_inst16b_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xd;
+}
+
+static void
+Opcode_mov_n_Slot_xt_flix64_slot0_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x6000;
+}
+
+static void
+Opcode_mov_n_Slot_xt_flix64_slot1_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xa3000;
+}
+
+static void
+Opcode_mov_n_Slot_xt_flix64_slot2_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xc080;
+}
+
+static void
+Opcode_movi_n_Slot_inst16b_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xc;
+}
+
+static void
+Opcode_movi_n_Slot_xt_flix64_slot2_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xc000;
+}
+
+static void
+Opcode_nop_n_Slot_inst16b_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xf03d;
+}
+
+static void
+Opcode_ret_n_Slot_inst16b_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xf00d;
+}
+
+static void
+Opcode_s32i_n_Slot_inst16a_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x9;
+}
+
+static void
+Opcode_rur_threadptr_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xe30e70;
+}
+
+static void
+Opcode_wur_threadptr_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xf3e700;
+}
+
+static void
+Opcode_addi_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xc002;
+}
+
+static void
+Opcode_addi_Slot_xt_flix64_slot1_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x60000;
+}
+
+static void
+Opcode_addi_Slot_xt_flix64_slot0_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x200c00;
+}
+
+static void
+Opcode_addmi_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xd002;
+}
+
+static void
+Opcode_addmi_Slot_xt_flix64_slot1_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x70000;
+}
+
+static void
+Opcode_addmi_Slot_xt_flix64_slot0_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x200d00;
+}
+
+static void
+Opcode_add_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x800000;
+}
+
+static void
+Opcode_add_Slot_xt_flix64_slot1_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x92000;
+}
+
+static void
+Opcode_add_Slot_xt_flix64_slot2_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x2000;
+}
+
+static void
+Opcode_add_Slot_xt_flix64_slot0_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x80000;
+}
+
+static void
+Opcode_sub_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xc00000;
+}
+
+static void
+Opcode_sub_Slot_xt_flix64_slot1_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xa8000;
+}
+
+static void
+Opcode_sub_Slot_xt_flix64_slot2_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xa000;
+}
+
+static void
+Opcode_sub_Slot_xt_flix64_slot0_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xc0000;
+}
+
+static void
+Opcode_addx2_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x900000;
+}
+
+static void
+Opcode_addx2_Slot_xt_flix64_slot1_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x94000;
+}
+
+static void
+Opcode_addx2_Slot_xt_flix64_slot2_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x4000;
+}
+
+static void
+Opcode_addx2_Slot_xt_flix64_slot0_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x90000;
+}
+
+static void
+Opcode_addx4_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xa00000;
+}
+
+static void
+Opcode_addx4_Slot_xt_flix64_slot1_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x98000;
+}
+
+static void
+Opcode_addx4_Slot_xt_flix64_slot2_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x5000;
+}
+
+static void
+Opcode_addx4_Slot_xt_flix64_slot0_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xa0000;
+}
+
+static void
+Opcode_addx8_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xb00000;
+}
+
+static void
+Opcode_addx8_Slot_xt_flix64_slot1_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x93000;
+}
+
+static void
+Opcode_addx8_Slot_xt_flix64_slot0_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xb0000;
+}
+
+static void
+Opcode_subx2_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xd00000;
+}
+
+static void
+Opcode_subx2_Slot_xt_flix64_slot0_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xd0000;
+}
+
+static void
+Opcode_subx4_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xe00000;
+}
+
+static void
+Opcode_subx4_Slot_xt_flix64_slot0_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xe0000;
+}
+
+static void
+Opcode_subx8_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xf00000;
+}
+
+static void
+Opcode_subx8_Slot_xt_flix64_slot0_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xf0000;
+}
+
+static void
+Opcode_and_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x100000;
+}
+
+static void
+Opcode_and_Slot_xt_flix64_slot1_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x95000;
+}
+
+static void
+Opcode_and_Slot_xt_flix64_slot2_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x6000;
+}
+
+static void
+Opcode_and_Slot_xt_flix64_slot0_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x10000;
+}
+
+static void
+Opcode_or_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x200000;
+}
+
+static void
+Opcode_or_Slot_xt_flix64_slot1_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x9e000;
+}
+
+static void
+Opcode_or_Slot_xt_flix64_slot2_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x7000;
+}
+
+static void
+Opcode_or_Slot_xt_flix64_slot0_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x20000;
+}
+
+static void
+Opcode_xor_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x300000;
+}
+
+static void
+Opcode_xor_Slot_xt_flix64_slot1_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xb0000;
+}
+
+static void
+Opcode_xor_Slot_xt_flix64_slot2_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xb000;
+}
+
+static void
+Opcode_xor_Slot_xt_flix64_slot0_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x30000;
+}
+
+static void
+Opcode_beqi_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x26;
+}
+
+static void
+Opcode_bnei_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x66;
+}
+
+static void
+Opcode_bgei_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xe6;
+}
+
+static void
+Opcode_blti_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xa6;
+}
+
+static void
+Opcode_bbci_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x6007;
+}
+
+static void
+Opcode_bbsi_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xe007;
+}
+
+static void
+Opcode_bgeui_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xf6;
+}
+
+static void
+Opcode_bltui_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xb6;
+}
+
+static void
+Opcode_beq_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x1007;
+}
+
+static void
+Opcode_bne_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x9007;
+}
+
+static void
+Opcode_bge_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xa007;
+}
+
+static void
+Opcode_blt_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x2007;
+}
+
+static void
+Opcode_bgeu_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xb007;
+}
+
+static void
+Opcode_bltu_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x3007;
+}
+
+static void
+Opcode_bany_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x8007;
+}
+
+static void
+Opcode_bnone_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x7;
+}
+
+static void
+Opcode_ball_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x4007;
+}
+
+static void
+Opcode_bnall_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xc007;
+}
+
+static void
+Opcode_bbc_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x5007;
+}
+
+static void
+Opcode_bbs_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xd007;
+}
+
+static void
+Opcode_beqz_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x16;
+}
+
+static void
+Opcode_bnez_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x56;
+}
+
+static void
+Opcode_bgez_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xd6;
+}
+
+static void
+Opcode_bltz_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x96;
+}
+
+static void
+Opcode_call0_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x5;
+}
+
+static void
+Opcode_callx0_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xc0;
+}
+
+static void
+Opcode_extui_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x40000;
+}
+
+static void
+Opcode_extui_Slot_xt_flix64_slot1_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x40000;
+}
+
+static void
+Opcode_extui_Slot_xt_flix64_slot0_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x4000;
+}
+
+static void
+Opcode_ill_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0;
+}
+
+static void
+Opcode_j_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x6;
+}
+
+static void
+Opcode_j_Slot_xt_flix64_slot1_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xc0000;
+}
+
+static void
+Opcode_jx_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xa0;
+}
+
+static void
+Opcode_jx_Slot_xt_flix64_slot1_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xa3010;
+}
+
+static void
+Opcode_l16ui_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x1002;
+}
+
+static void
+Opcode_l16ui_Slot_xt_flix64_slot0_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x200100;
+}
+
+static void
+Opcode_l16si_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x9002;
+}
+
+static void
+Opcode_l16si_Slot_xt_flix64_slot0_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x200900;
+}
+
+static void
+Opcode_l32i_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x2002;
+}
+
+static void
+Opcode_l32i_Slot_xt_flix64_slot0_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x200200;
+}
+
+static void
+Opcode_l32r_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x1;
+}
+
+static void
+Opcode_l32r_Slot_xt_flix64_slot0_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x100000;
+}
+
+static void
+Opcode_l8ui_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x2;
+}
+
+static void
+Opcode_l8ui_Slot_xt_flix64_slot0_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x200000;
+}
+
+static void
+Opcode_loop_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x8076;
+}
+
+static void
+Opcode_loopnez_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x9076;
+}
+
+static void
+Opcode_loopgtz_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xa076;
+}
+
+static void
+Opcode_movi_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xa002;
+}
+
+static void
+Opcode_movi_Slot_xt_flix64_slot1_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x80000;
+}
+
+static void
+Opcode_movi_Slot_xt_flix64_slot0_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x200a00;
+}
+
+static void
+Opcode_moveqz_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x830000;
+}
+
+static void
+Opcode_moveqz_Slot_xt_flix64_slot1_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x96000;
+}
+
+static void
+Opcode_moveqz_Slot_xt_flix64_slot0_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x83000;
+}
+
+static void
+Opcode_movnez_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x930000;
+}
+
+static void
+Opcode_movnez_Slot_xt_flix64_slot1_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x9a000;
+}
+
+static void
+Opcode_movnez_Slot_xt_flix64_slot0_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x93000;
+}
+
+static void
+Opcode_movltz_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xa30000;
+}
+
+static void
+Opcode_movltz_Slot_xt_flix64_slot1_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x99000;
+}
+
+static void
+Opcode_movltz_Slot_xt_flix64_slot0_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xa3000;
+}
+
+static void
+Opcode_movgez_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xb30000;
+}
+
+static void
+Opcode_movgez_Slot_xt_flix64_slot1_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x97000;
+}
+
+static void
+Opcode_movgez_Slot_xt_flix64_slot0_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xb3000;
+}
+
+static void
+Opcode_neg_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x600000;
+}
+
+static void
+Opcode_neg_Slot_xt_flix64_slot1_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xa5000;
+}
+
+static void
+Opcode_neg_Slot_xt_flix64_slot2_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xd100;
+}
+
+static void
+Opcode_neg_Slot_xt_flix64_slot0_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x60000;
+}
+
+static void
+Opcode_abs_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x600100;
+}
+
+static void
+Opcode_abs_Slot_xt_flix64_slot2_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xd000;
+}
+
+static void
+Opcode_abs_Slot_xt_flix64_slot0_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x60010;
+}
+
+static void
+Opcode_nop_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x20f0;
+}
+
+static void
+Opcode_nop_Slot_xt_flix64_slot1_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xa3040;
+}
+
+static void
+Opcode_nop_Slot_xt_flix64_slot2_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xc090;
+}
+
+static void
+Opcode_nop_Slot_xt_flix64_slot3_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xc8000000;
+ slotbuf[1] = 0;
+}
+
+static void
+Opcode_nop_Slot_xt_flix64_slot0_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x20f;
+}
+
+static void
+Opcode_ret_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x80;
+}
+
+static void
+Opcode_s16i_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x5002;
+}
+
+static void
+Opcode_s16i_Slot_xt_flix64_slot0_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x200500;
+}
+
+static void
+Opcode_s32i_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x6002;
+}
+
+static void
+Opcode_s32i_Slot_xt_flix64_slot0_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x200600;
+}
+
+static void
+Opcode_s8i_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x4002;
+}
+
+static void
+Opcode_s8i_Slot_xt_flix64_slot0_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x200400;
+}
+
+static void
+Opcode_ssr_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x400000;
+}
+
+static void
+Opcode_ssr_Slot_xt_flix64_slot0_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x40000;
+}
+
+static void
+Opcode_ssl_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x401000;
+}
+
+static void
+Opcode_ssl_Slot_xt_flix64_slot1_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xa3020;
+}
+
+static void
+Opcode_ssl_Slot_xt_flix64_slot0_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x40100;
+}
+
+static void
+Opcode_ssa8l_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x402000;
+}
+
+static void
+Opcode_ssa8l_Slot_xt_flix64_slot0_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x40200;
+}
+
+static void
+Opcode_ssa8b_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x403000;
+}
+
+static void
+Opcode_ssa8b_Slot_xt_flix64_slot0_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x40300;
+}
+
+static void
+Opcode_ssai_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x404000;
+}
+
+static void
+Opcode_ssai_Slot_xt_flix64_slot0_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x40400;
+}
+
+static void
+Opcode_sll_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xa10000;
+}
+
+static void
+Opcode_sll_Slot_xt_flix64_slot1_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xa6000;
+}
+
+static void
+Opcode_sll_Slot_xt_flix64_slot0_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xa1000;
+}
+
+static void
+Opcode_src_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x810000;
+}
+
+static void
+Opcode_src_Slot_xt_flix64_slot1_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xa2000;
+}
+
+static void
+Opcode_src_Slot_xt_flix64_slot0_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x81000;
+}
+
+static void
+Opcode_srl_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x910000;
+}
+
+static void
+Opcode_srl_Slot_xt_flix64_slot1_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xa5200;
+}
+
+static void
+Opcode_srl_Slot_xt_flix64_slot2_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xd400;
+}
+
+static void
+Opcode_srl_Slot_xt_flix64_slot0_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x91000;
+}
+
+static void
+Opcode_sra_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xb10000;
+}
+
+static void
+Opcode_sra_Slot_xt_flix64_slot1_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xa5100;
+}
+
+static void
+Opcode_sra_Slot_xt_flix64_slot2_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xd200;
+}
+
+static void
+Opcode_sra_Slot_xt_flix64_slot0_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xb1000;
+}
+
+static void
+Opcode_slli_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x10000;
+}
+
+static void
+Opcode_slli_Slot_xt_flix64_slot1_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x90000;
+}
+
+static void
+Opcode_slli_Slot_xt_flix64_slot0_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x1000;
+}
+
+static void
+Opcode_srai_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x210000;
+}
+
+static void
+Opcode_srai_Slot_xt_flix64_slot1_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xa0000;
+}
+
+static void
+Opcode_srai_Slot_xt_flix64_slot2_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xe000;
+}
+
+static void
+Opcode_srai_Slot_xt_flix64_slot0_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x21000;
+}
+
+static void
+Opcode_srli_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x410000;
+}
+
+static void
+Opcode_srli_Slot_xt_flix64_slot1_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xa4000;
+}
+
+static void
+Opcode_srli_Slot_xt_flix64_slot2_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x9000;
+}
+
+static void
+Opcode_srli_Slot_xt_flix64_slot0_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x41000;
+}
+
+static void
+Opcode_memw_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x20c0;
+}
+
+static void
+Opcode_extw_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x20d0;
+}
+
+static void
+Opcode_isync_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x2000;
+}
+
+static void
+Opcode_rsync_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x2010;
+}
+
+static void
+Opcode_esync_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x2020;
+}
+
+static void
+Opcode_dsync_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x2030;
+}
+
+static void
+Opcode_rsil_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x6000;
+}
+
+static void
+Opcode_rsr_lend_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x30100;
+}
+
+static void
+Opcode_wsr_lend_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x130100;
+}
+
+static void
+Opcode_xsr_lend_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x610100;
+}
+
+static void
+Opcode_rsr_lcount_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x30200;
+}
+
+static void
+Opcode_wsr_lcount_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x130200;
+}
+
+static void
+Opcode_xsr_lcount_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x610200;
+}
+
+static void
+Opcode_rsr_lbeg_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x30000;
+}
+
+static void
+Opcode_wsr_lbeg_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x130000;
+}
+
+static void
+Opcode_xsr_lbeg_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x610000;
+}
+
+static void
+Opcode_rsr_sar_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x30300;
+}
+
+static void
+Opcode_wsr_sar_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x130300;
+}
+
+static void
+Opcode_xsr_sar_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x610300;
+}
+
+static void
+Opcode_rsr_litbase_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x30500;
+}
+
+static void
+Opcode_wsr_litbase_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x130500;
+}
+
+static void
+Opcode_xsr_litbase_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x610500;
+}
+
+static void
+Opcode_rsr_176_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x3b000;
+}
+
+static void
+Opcode_rsr_208_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x3d000;
+}
+
+static void
+Opcode_rsr_ps_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x3e600;
+}
+
+static void
+Opcode_wsr_ps_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x13e600;
+}
+
+static void
+Opcode_xsr_ps_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x61e600;
+}
+
+static void
+Opcode_rsr_epc1_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x3b100;
+}
+
+static void
+Opcode_wsr_epc1_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x13b100;
+}
+
+static void
+Opcode_xsr_epc1_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x61b100;
+}
+
+static void
+Opcode_rsr_excsave1_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x3d100;
+}
+
+static void
+Opcode_wsr_excsave1_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x13d100;
+}
+
+static void
+Opcode_xsr_excsave1_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x61d100;
+}
+
+static void
+Opcode_rsr_epc2_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x3b200;
+}
+
+static void
+Opcode_wsr_epc2_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x13b200;
+}
+
+static void
+Opcode_xsr_epc2_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x61b200;
+}
+
+static void
+Opcode_rsr_excsave2_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x3d200;
+}
+
+static void
+Opcode_wsr_excsave2_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x13d200;
+}
+
+static void
+Opcode_xsr_excsave2_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x61d200;
+}
+
+static void
+Opcode_rsr_epc3_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x3b300;
+}
+
+static void
+Opcode_wsr_epc3_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x13b300;
+}
+
+static void
+Opcode_xsr_epc3_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x61b300;
+}
+
+static void
+Opcode_rsr_excsave3_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x3d300;
+}
+
+static void
+Opcode_wsr_excsave3_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x13d300;
+}
+
+static void
+Opcode_xsr_excsave3_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x61d300;
+}
+
+static void
+Opcode_rsr_epc4_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x3b400;
+}
+
+static void
+Opcode_wsr_epc4_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x13b400;
+}
+
+static void
+Opcode_xsr_epc4_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x61b400;
+}
+
+static void
+Opcode_rsr_excsave4_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x3d400;
+}
+
+static void
+Opcode_wsr_excsave4_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x13d400;
+}
+
+static void
+Opcode_xsr_excsave4_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x61d400;
+}
+
+static void
+Opcode_rsr_epc5_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x3b500;
+}
+
+static void
+Opcode_wsr_epc5_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x13b500;
+}
+
+static void
+Opcode_xsr_epc5_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x61b500;
+}
+
+static void
+Opcode_rsr_excsave5_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x3d500;
+}
+
+static void
+Opcode_wsr_excsave5_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x13d500;
+}
+
+static void
+Opcode_xsr_excsave5_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x61d500;
+}
+
+static void
+Opcode_rsr_epc6_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x3b600;
+}
+
+static void
+Opcode_wsr_epc6_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x13b600;
+}
+
+static void
+Opcode_xsr_epc6_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x61b600;
+}
+
+static void
+Opcode_rsr_excsave6_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x3d600;
+}
+
+static void
+Opcode_wsr_excsave6_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x13d600;
+}
+
+static void
+Opcode_xsr_excsave6_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x61d600;
+}
+
+static void
+Opcode_rsr_epc7_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x3b700;
+}
+
+static void
+Opcode_wsr_epc7_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x13b700;
+}
+
+static void
+Opcode_xsr_epc7_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x61b700;
+}
+
+static void
+Opcode_rsr_excsave7_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x3d700;
+}
+
+static void
+Opcode_wsr_excsave7_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x13d700;
+}
+
+static void
+Opcode_xsr_excsave7_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x61d700;
+}
+
+static void
+Opcode_rsr_eps2_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x3c200;
+}
+
+static void
+Opcode_wsr_eps2_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x13c200;
+}
+
+static void
+Opcode_xsr_eps2_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x61c200;
+}
+
+static void
+Opcode_rsr_eps3_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x3c300;
+}
+
+static void
+Opcode_wsr_eps3_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x13c300;
+}
+
+static void
+Opcode_xsr_eps3_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x61c300;
+}
+
+static void
+Opcode_rsr_eps4_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x3c400;
+}
+
+static void
+Opcode_wsr_eps4_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x13c400;
+}
+
+static void
+Opcode_xsr_eps4_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x61c400;
+}
+
+static void
+Opcode_rsr_eps5_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x3c500;
+}
+
+static void
+Opcode_wsr_eps5_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x13c500;
+}
+
+static void
+Opcode_xsr_eps5_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x61c500;
+}
+
+static void
+Opcode_rsr_eps6_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x3c600;
+}
+
+static void
+Opcode_wsr_eps6_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x13c600;
+}
+
+static void
+Opcode_xsr_eps6_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x61c600;
+}
+
+static void
+Opcode_rsr_eps7_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x3c700;
+}
+
+static void
+Opcode_wsr_eps7_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x13c700;
+}
+
+static void
+Opcode_xsr_eps7_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x61c700;
+}
+
+static void
+Opcode_rsr_excvaddr_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x3ee00;
+}
+
+static void
+Opcode_wsr_excvaddr_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x13ee00;
+}
+
+static void
+Opcode_xsr_excvaddr_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x61ee00;
+}
+
+static void
+Opcode_rsr_depc_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x3c000;
+}
+
+static void
+Opcode_wsr_depc_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x13c000;
+}
+
+static void
+Opcode_xsr_depc_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x61c000;
+}
+
+static void
+Opcode_rsr_exccause_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x3e800;
+}
+
+static void
+Opcode_wsr_exccause_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x13e800;
+}
+
+static void
+Opcode_xsr_exccause_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x61e800;
+}
+
+static void
+Opcode_rsr_misc0_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x3f400;
+}
+
+static void
+Opcode_wsr_misc0_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x13f400;
+}
+
+static void
+Opcode_xsr_misc0_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x61f400;
+}
+
+static void
+Opcode_rsr_misc1_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x3f500;
+}
+
+static void
+Opcode_wsr_misc1_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x13f500;
+}
+
+static void
+Opcode_xsr_misc1_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x61f500;
+}
+
+static void
+Opcode_rsr_misc2_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x3f600;
+}
+
+static void
+Opcode_wsr_misc2_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x13f600;
+}
+
+static void
+Opcode_xsr_misc2_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x61f600;
+}
+
+static void
+Opcode_rsr_misc3_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x3f700;
+}
+
+static void
+Opcode_wsr_misc3_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x13f700;
+}
+
+static void
+Opcode_xsr_misc3_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x61f700;
+}
+
+static void
+Opcode_rsr_prid_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x3eb00;
+}
+
+static void
+Opcode_rsr_vecbase_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x3e700;
+}
+
+static void
+Opcode_wsr_vecbase_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x13e700;
+}
+
+static void
+Opcode_xsr_vecbase_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x61e700;
+}
+
+static void
+Opcode_mul_aa_ll_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x740004;
+}
+
+static void
+Opcode_mul_aa_hl_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x750004;
+}
+
+static void
+Opcode_mul_aa_lh_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x760004;
+}
+
+static void
+Opcode_mul_aa_hh_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x770004;
+}
+
+static void
+Opcode_umul_aa_ll_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x700004;
+}
+
+static void
+Opcode_umul_aa_hl_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x710004;
+}
+
+static void
+Opcode_umul_aa_lh_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x720004;
+}
+
+static void
+Opcode_umul_aa_hh_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x730004;
+}
+
+static void
+Opcode_mul_ad_ll_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x340004;
+}
+
+static void
+Opcode_mul_ad_hl_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x350004;
+}
+
+static void
+Opcode_mul_ad_lh_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x360004;
+}
+
+static void
+Opcode_mul_ad_hh_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x370004;
+}
+
+static void
+Opcode_mul_da_ll_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x640004;
+}
+
+static void
+Opcode_mul_da_hl_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x650004;
+}
+
+static void
+Opcode_mul_da_lh_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x660004;
+}
+
+static void
+Opcode_mul_da_hh_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x670004;
+}
+
+static void
+Opcode_mul_dd_ll_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x240004;
+}
+
+static void
+Opcode_mul_dd_hl_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x250004;
+}
+
+static void
+Opcode_mul_dd_lh_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x260004;
+}
+
+static void
+Opcode_mul_dd_hh_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x270004;
+}
+
+static void
+Opcode_mula_aa_ll_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x780004;
+}
+
+static void
+Opcode_mula_aa_hl_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x790004;
+}
+
+static void
+Opcode_mula_aa_lh_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x7a0004;
+}
+
+static void
+Opcode_mula_aa_hh_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x7b0004;
+}
+
+static void
+Opcode_muls_aa_ll_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x7c0004;
+}
+
+static void
+Opcode_muls_aa_hl_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x7d0004;
+}
+
+static void
+Opcode_muls_aa_lh_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x7e0004;
+}
+
+static void
+Opcode_muls_aa_hh_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x7f0004;
+}
+
+static void
+Opcode_mula_ad_ll_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x380004;
+}
+
+static void
+Opcode_mula_ad_hl_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x390004;
+}
+
+static void
+Opcode_mula_ad_lh_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x3a0004;
+}
+
+static void
+Opcode_mula_ad_hh_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x3b0004;
+}
+
+static void
+Opcode_muls_ad_ll_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x3c0004;
+}
+
+static void
+Opcode_muls_ad_hl_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x3d0004;
+}
+
+static void
+Opcode_muls_ad_lh_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x3e0004;
+}
+
+static void
+Opcode_muls_ad_hh_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x3f0004;
+}
+
+static void
+Opcode_mula_da_ll_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x680004;
+}
+
+static void
+Opcode_mula_da_hl_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x690004;
+}
+
+static void
+Opcode_mula_da_lh_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x6a0004;
+}
+
+static void
+Opcode_mula_da_hh_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x6b0004;
+}
+
+static void
+Opcode_muls_da_ll_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x6c0004;
+}
+
+static void
+Opcode_muls_da_hl_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x6d0004;
+}
+
+static void
+Opcode_muls_da_lh_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x6e0004;
+}
+
+static void
+Opcode_muls_da_hh_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x6f0004;
+}
+
+static void
+Opcode_mula_dd_ll_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x280004;
+}
+
+static void
+Opcode_mula_dd_hl_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x290004;
+}
+
+static void
+Opcode_mula_dd_lh_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x2a0004;
+}
+
+static void
+Opcode_mula_dd_hh_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x2b0004;
+}
+
+static void
+Opcode_muls_dd_ll_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x2c0004;
+}
+
+static void
+Opcode_muls_dd_hl_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x2d0004;
+}
+
+static void
+Opcode_muls_dd_lh_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x2e0004;
+}
+
+static void
+Opcode_muls_dd_hh_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x2f0004;
+}
+
+static void
+Opcode_mula_da_ll_lddec_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x580004;
+}
+
+static void
+Opcode_mula_da_ll_ldinc_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x480004;
+}
+
+static void
+Opcode_mula_da_hl_lddec_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x590004;
+}
+
+static void
+Opcode_mula_da_hl_ldinc_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x490004;
+}
+
+static void
+Opcode_mula_da_lh_lddec_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x5a0004;
+}
+
+static void
+Opcode_mula_da_lh_ldinc_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x4a0004;
+}
+
+static void
+Opcode_mula_da_hh_lddec_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x5b0004;
+}
+
+static void
+Opcode_mula_da_hh_ldinc_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x4b0004;
+}
+
+static void
+Opcode_mula_dd_ll_lddec_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x180004;
+}
+
+static void
+Opcode_mula_dd_ll_ldinc_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x80004;
+}
+
+static void
+Opcode_mula_dd_hl_lddec_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x190004;
+}
+
+static void
+Opcode_mula_dd_hl_ldinc_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x90004;
+}
+
+static void
+Opcode_mula_dd_lh_lddec_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x1a0004;
+}
+
+static void
+Opcode_mula_dd_lh_ldinc_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xa0004;
+}
+
+static void
+Opcode_mula_dd_hh_lddec_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x1b0004;
+}
+
+static void
+Opcode_mula_dd_hh_ldinc_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xb0004;
+}
+
+static void
+Opcode_lddec_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x900004;
+}
+
+static void
+Opcode_ldinc_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x800004;
+}
+
+static void
+Opcode_mul16u_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xc10000;
+}
+
+static void
+Opcode_mul16u_Slot_xt_flix64_slot1_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x9b000;
+}
+
+static void
+Opcode_mul16u_Slot_xt_flix64_slot0_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xc1000;
+}
+
+static void
+Opcode_mul16s_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xd10000;
+}
+
+static void
+Opcode_mul16s_Slot_xt_flix64_slot1_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x9c000;
+}
+
+static void
+Opcode_mul16s_Slot_xt_flix64_slot0_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xd1000;
+}
+
+static void
+Opcode_rsr_m0_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x32000;
+}
+
+static void
+Opcode_wsr_m0_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x132000;
+}
+
+static void
+Opcode_xsr_m0_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x612000;
+}
+
+static void
+Opcode_rsr_m1_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x32100;
+}
+
+static void
+Opcode_wsr_m1_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x132100;
+}
+
+static void
+Opcode_xsr_m1_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x612100;
+}
+
+static void
+Opcode_rsr_m2_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x32200;
+}
+
+static void
+Opcode_wsr_m2_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x132200;
+}
+
+static void
+Opcode_xsr_m2_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x612200;
+}
+
+static void
+Opcode_rsr_m3_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x32300;
+}
+
+static void
+Opcode_wsr_m3_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x132300;
+}
+
+static void
+Opcode_xsr_m3_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x612300;
+}
+
+static void
+Opcode_rsr_acclo_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x31000;
+}
+
+static void
+Opcode_wsr_acclo_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x131000;
+}
+
+static void
+Opcode_xsr_acclo_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x611000;
+}
+
+static void
+Opcode_rsr_acchi_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x31100;
+}
+
+static void
+Opcode_wsr_acchi_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x131100;
+}
+
+static void
+Opcode_xsr_acchi_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x611100;
+}
+
+static void
+Opcode_rfi_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x3010;
+}
+
+static void
+Opcode_waiti_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x7000;
+}
+
+static void
+Opcode_rsr_interrupt_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x3e200;
+}
+
+static void
+Opcode_wsr_intset_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x13e200;
+}
+
+static void
+Opcode_wsr_intclear_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x13e300;
+}
+
+static void
+Opcode_rsr_intenable_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x3e400;
+}
+
+static void
+Opcode_wsr_intenable_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x13e400;
+}
+
+static void
+Opcode_xsr_intenable_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x61e400;
+}
+
+static void
+Opcode_break_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x4000;
+}
+
+static void
+Opcode_break_n_Slot_inst16b_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xf02d;
+}
+
+static void
+Opcode_rsr_dbreaka0_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x39000;
+}
+
+static void
+Opcode_wsr_dbreaka0_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x139000;
+}
+
+static void
+Opcode_xsr_dbreaka0_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x619000;
+}
+
+static void
+Opcode_rsr_dbreakc0_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x3a000;
+}
+
+static void
+Opcode_wsr_dbreakc0_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x13a000;
+}
+
+static void
+Opcode_xsr_dbreakc0_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x61a000;
+}
+
+static void
+Opcode_rsr_dbreaka1_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x39100;
+}
+
+static void
+Opcode_wsr_dbreaka1_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x139100;
+}
+
+static void
+Opcode_xsr_dbreaka1_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x619100;
+}
+
+static void
+Opcode_rsr_dbreakc1_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x3a100;
+}
+
+static void
+Opcode_wsr_dbreakc1_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x13a100;
+}
+
+static void
+Opcode_xsr_dbreakc1_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x61a100;
+}
+
+static void
+Opcode_rsr_ibreaka0_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x38000;
+}
+
+static void
+Opcode_wsr_ibreaka0_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x138000;
+}
+
+static void
+Opcode_xsr_ibreaka0_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x618000;
+}
+
+static void
+Opcode_rsr_ibreaka1_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x38100;
+}
+
+static void
+Opcode_wsr_ibreaka1_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x138100;
+}
+
+static void
+Opcode_xsr_ibreaka1_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x618100;
+}
+
+static void
+Opcode_rsr_ibreakenable_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x36000;
+}
+
+static void
+Opcode_wsr_ibreakenable_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x136000;
+}
+
+static void
+Opcode_xsr_ibreakenable_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x616000;
+}
+
+static void
+Opcode_rsr_debugcause_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x3e900;
+}
+
+static void
+Opcode_wsr_debugcause_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x13e900;
+}
+
+static void
+Opcode_xsr_debugcause_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x61e900;
+}
+
+static void
+Opcode_rsr_icount_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x3ec00;
+}
+
+static void
+Opcode_wsr_icount_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x13ec00;
+}
+
+static void
+Opcode_xsr_icount_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x61ec00;
+}
+
+static void
+Opcode_rsr_icountlevel_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x3ed00;
+}
+
+static void
+Opcode_wsr_icountlevel_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x13ed00;
+}
+
+static void
+Opcode_xsr_icountlevel_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x61ed00;
+}
+
+static void
+Opcode_rsr_ddr_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x36800;
+}
+
+static void
+Opcode_wsr_ddr_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x136800;
+}
+
+static void
+Opcode_xsr_ddr_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x616800;
+}
+
+static void
+Opcode_rfdo_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xf1e000;
+}
+
+static void
+Opcode_rfdd_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xf1e010;
+}
+
+static void
+Opcode_wsr_mmid_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x135900;
+}
+
+static void
+Opcode_andb_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x20000;
+}
+
+static void
+Opcode_andbc_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x120000;
+}
+
+static void
+Opcode_orb_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x220000;
+}
+
+static void
+Opcode_orbc_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x320000;
+}
+
+static void
+Opcode_xorb_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x420000;
+}
+
+static void
+Opcode_any4_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x8000;
+}
+
+static void
+Opcode_all4_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x9000;
+}
+
+static void
+Opcode_any8_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xa000;
+}
+
+static void
+Opcode_all8_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xb000;
+}
+
+static void
+Opcode_bf_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x76;
+}
+
+static void
+Opcode_bt_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x1076;
+}
+
+static void
+Opcode_movf_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xc30000;
+}
+
+static void
+Opcode_movt_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xd30000;
+}
+
+static void
+Opcode_rsr_br_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x30400;
+}
+
+static void
+Opcode_wsr_br_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x130400;
+}
+
+static void
+Opcode_xsr_br_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x610400;
+}
+
+static void
+Opcode_rsr_ccount_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x3ea00;
+}
+
+static void
+Opcode_wsr_ccount_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x13ea00;
+}
+
+static void
+Opcode_xsr_ccount_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x61ea00;
+}
+
+static void
+Opcode_rsr_ccompare0_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x3f000;
+}
+
+static void
+Opcode_wsr_ccompare0_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x13f000;
+}
+
+static void
+Opcode_xsr_ccompare0_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x61f000;
+}
+
+static void
+Opcode_rsr_ccompare1_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x3f100;
+}
+
+static void
+Opcode_wsr_ccompare1_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x13f100;
+}
+
+static void
+Opcode_xsr_ccompare1_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x61f100;
+}
+
+static void
+Opcode_rsr_ccompare2_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x3f200;
+}
+
+static void
+Opcode_wsr_ccompare2_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x13f200;
+}
+
+static void
+Opcode_xsr_ccompare2_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x61f200;
+}
+
+static void
+Opcode_ipf_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x70c2;
+}
+
+static void
+Opcode_ihi_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x70e2;
+}
+
+static void
+Opcode_ipfl_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x70d2;
+}
+
+static void
+Opcode_ihu_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x270d2;
+}
+
+static void
+Opcode_iiu_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x370d2;
+}
+
+static void
+Opcode_iii_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x70f2;
+}
+
+static void
+Opcode_lict_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xf10000;
+}
+
+static void
+Opcode_licw_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xf12000;
+}
+
+static void
+Opcode_sict_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xf11000;
+}
+
+static void
+Opcode_sicw_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xf13000;
+}
+
+static void
+Opcode_dhwb_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x7042;
+}
+
+static void
+Opcode_dhwbi_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x7052;
+}
+
+static void
+Opcode_diwb_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x47082;
+}
+
+static void
+Opcode_diwbi_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x57082;
+}
+
+static void
+Opcode_dhi_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x7062;
+}
+
+static void
+Opcode_dii_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x7072;
+}
+
+static void
+Opcode_dpfr_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x7002;
+}
+
+static void
+Opcode_dpfw_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x7012;
+}
+
+static void
+Opcode_dpfro_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x7022;
+}
+
+static void
+Opcode_dpfwo_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x7032;
+}
+
+static void
+Opcode_dpfl_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x7082;
+}
+
+static void
+Opcode_dhu_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x27082;
+}
+
+static void
+Opcode_diu_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x37082;
+}
+
+static void
+Opcode_sdct_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xf19000;
+}
+
+static void
+Opcode_ldct_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xf18000;
+}
+
+static void
+Opcode_wsr_ptevaddr_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x135300;
+}
+
+static void
+Opcode_rsr_ptevaddr_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x35300;
+}
+
+static void
+Opcode_xsr_ptevaddr_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x615300;
+}
+
+static void
+Opcode_rsr_rasid_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x35a00;
+}
+
+static void
+Opcode_wsr_rasid_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x135a00;
+}
+
+static void
+Opcode_xsr_rasid_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x615a00;
+}
+
+static void
+Opcode_rsr_itlbcfg_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x35b00;
+}
+
+static void
+Opcode_wsr_itlbcfg_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x135b00;
+}
+
+static void
+Opcode_xsr_itlbcfg_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x615b00;
+}
+
+static void
+Opcode_rsr_dtlbcfg_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x35c00;
+}
+
+static void
+Opcode_wsr_dtlbcfg_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x135c00;
+}
+
+static void
+Opcode_xsr_dtlbcfg_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x615c00;
+}
+
+static void
+Opcode_idtlb_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x50c000;
+}
+
+static void
+Opcode_pdtlb_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x50d000;
+}
+
+static void
+Opcode_rdtlb0_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x50b000;
+}
+
+static void
+Opcode_rdtlb1_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x50f000;
+}
+
+static void
+Opcode_wdtlb_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x50e000;
+}
+
+static void
+Opcode_iitlb_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x504000;
+}
+
+static void
+Opcode_pitlb_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x505000;
+}
+
+static void
+Opcode_ritlb0_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x503000;
+}
+
+static void
+Opcode_ritlb1_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x507000;
+}
+
+static void
+Opcode_witlb_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x506000;
+}
+
+static void
+Opcode_ldpte_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xf1f000;
+}
+
+static void
+Opcode_hwwitlba_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x501000;
+}
+
+static void
+Opcode_hwwdtlba_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x509000;
+}
+
+static void
+Opcode_rsr_cpenable_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x3e000;
+}
+
+static void
+Opcode_wsr_cpenable_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x13e000;
+}
+
+static void
+Opcode_xsr_cpenable_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x61e000;
+}
+
+static void
+Opcode_clamps_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x330000;
+}
+
+static void
+Opcode_clamps_Slot_xt_flix64_slot0_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x33000;
+}
+
+static void
+Opcode_min_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x430000;
+}
+
+static void
+Opcode_min_Slot_xt_flix64_slot0_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x43000;
+}
+
+static void
+Opcode_max_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x530000;
+}
+
+static void
+Opcode_max_Slot_xt_flix64_slot0_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x53000;
+}
+
+static void
+Opcode_minu_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x630000;
+}
+
+static void
+Opcode_minu_Slot_xt_flix64_slot0_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x63000;
+}
+
+static void
+Opcode_maxu_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x730000;
+}
+
+static void
+Opcode_maxu_Slot_xt_flix64_slot0_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x73000;
+}
+
+static void
+Opcode_nsa_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x40e000;
+}
+
+static void
+Opcode_nsa_Slot_xt_flix64_slot0_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x40e00;
+}
+
+static void
+Opcode_nsau_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x40f000;
+}
+
+static void
+Opcode_nsau_Slot_xt_flix64_slot0_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x40f00;
+}
+
+static void
+Opcode_sext_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x230000;
+}
+
+static void
+Opcode_sext_Slot_xt_flix64_slot1_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x9f000;
+}
+
+static void
+Opcode_sext_Slot_xt_flix64_slot2_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x8000;
+}
+
+static void
+Opcode_sext_Slot_xt_flix64_slot0_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x23000;
+}
+
+static void
+Opcode_l32ai_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xb002;
+}
+
+static void
+Opcode_s32ri_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xf002;
+}
+
+static void
+Opcode_s32c1i_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xe002;
+}
+
+static void
+Opcode_rsr_scompare1_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x30c00;
+}
+
+static void
+Opcode_wsr_scompare1_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x130c00;
+}
+
+static void
+Opcode_xsr_scompare1_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x610c00;
+}
+
+static void
+Opcode_quou_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xc20000;
+}
+
+static void
+Opcode_quos_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xd20000;
+}
+
+static void
+Opcode_remu_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xe20000;
+}
+
+static void
+Opcode_rems_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xf20000;
+}
+
+static void
+Opcode_mull_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x820000;
+}
+
+static void
+Opcode_mull_Slot_xt_flix64_slot1_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x9d000;
+}
+
+static void
+Opcode_mull_Slot_xt_flix64_slot0_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x82000;
+}
+
+static void
+Opcode_muluh_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xa20000;
+}
+
+static void
+Opcode_mulsh_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xb20000;
+}
+
+static void
+Opcode_rur_fcr_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xe30e80;
+}
+
+static void
+Opcode_wur_fcr_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xf3e800;
+}
+
+static void
+Opcode_rur_fsr_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xe30e90;
+}
+
+static void
+Opcode_wur_fsr_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xf3e900;
+}
+
+static void
+Opcode_add_s_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xa0000;
+}
+
+static void
+Opcode_sub_s_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x1a0000;
+}
+
+static void
+Opcode_mul_s_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x2a0000;
+}
+
+static void
+Opcode_madd_s_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x4a0000;
+}
+
+static void
+Opcode_msub_s_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x5a0000;
+}
+
+static void
+Opcode_movf_s_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xcb0000;
+}
+
+static void
+Opcode_movt_s_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xdb0000;
+}
+
+static void
+Opcode_moveqz_s_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x8b0000;
+}
+
+static void
+Opcode_movnez_s_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x9b0000;
+}
+
+static void
+Opcode_movltz_s_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xab0000;
+}
+
+static void
+Opcode_movgez_s_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xbb0000;
+}
+
+static void
+Opcode_abs_s_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xfa0010;
+}
+
+static void
+Opcode_mov_s_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xfa0000;
+}
+
+static void
+Opcode_neg_s_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xfa0060;
+}
+
+static void
+Opcode_un_s_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x1b0000;
+}
+
+static void
+Opcode_oeq_s_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x2b0000;
+}
+
+static void
+Opcode_ueq_s_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x3b0000;
+}
+
+static void
+Opcode_olt_s_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x4b0000;
+}
+
+static void
+Opcode_ult_s_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x5b0000;
+}
+
+static void
+Opcode_ole_s_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x6b0000;
+}
+
+static void
+Opcode_ule_s_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x7b0000;
+}
+
+static void
+Opcode_float_s_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xca0000;
+}
+
+static void
+Opcode_ufloat_s_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xda0000;
+}
+
+static void
+Opcode_round_s_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x8a0000;
+}
+
+static void
+Opcode_ceil_s_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xba0000;
+}
+
+static void
+Opcode_floor_s_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xaa0000;
+}
+
+static void
+Opcode_trunc_s_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x9a0000;
+}
+
+static void
+Opcode_utrunc_s_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xea0000;
+}
+
+static void
+Opcode_rfr_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xfa0040;
+}
+
+static void
+Opcode_wfr_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xfa0050;
+}
+
+static void
+Opcode_lsi_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x3;
+}
+
+static void
+Opcode_lsiu_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x8003;
+}
+
+static void
+Opcode_lsx_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x80000;
+}
+
+static void
+Opcode_lsxu_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x180000;
+}
+
+static void
+Opcode_ssi_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x4003;
+}
+
+static void
+Opcode_ssiu_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xc003;
+}
+
+static void
+Opcode_ssx_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x480000;
+}
+
+static void
+Opcode_ssxu_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x580000;
+}
+
+static void
+Opcode_beqz_w18_Slot_xt_flix64_slot3_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xa8000000;
+ slotbuf[1] = 0;
+}
+
+static void
+Opcode_bnez_w18_Slot_xt_flix64_slot3_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xc0000000;
+ slotbuf[1] = 0;
+}
+
+static void
+Opcode_bgez_w18_Slot_xt_flix64_slot3_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xb0000000;
+ slotbuf[1] = 0;
+}
+
+static void
+Opcode_bltz_w18_Slot_xt_flix64_slot3_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xb8000000;
+ slotbuf[1] = 0;
+}
+
+static void
+Opcode_beqi_w18_Slot_xt_flix64_slot3_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x40000000;
+ slotbuf[1] = 0;
+}
+
+static void
+Opcode_bnei_w18_Slot_xt_flix64_slot3_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x98000000;
+ slotbuf[1] = 0;
+}
+
+static void
+Opcode_bgei_w18_Slot_xt_flix64_slot3_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x50000000;
+ slotbuf[1] = 0;
+}
+
+static void
+Opcode_blti_w18_Slot_xt_flix64_slot3_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x70000000;
+ slotbuf[1] = 0;
+}
+
+static void
+Opcode_bgeui_w18_Slot_xt_flix64_slot3_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x60000000;
+ slotbuf[1] = 0;
+}
+
+static void
+Opcode_bltui_w18_Slot_xt_flix64_slot3_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x80000000;
+ slotbuf[1] = 0;
+}
+
+static void
+Opcode_bbci_w18_Slot_xt_flix64_slot3_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x8000000;
+ slotbuf[1] = 0;
+}
+
+static void
+Opcode_bbsi_w18_Slot_xt_flix64_slot3_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x10000000;
+ slotbuf[1] = 0;
+}
+
+static void
+Opcode_beq_w18_Slot_xt_flix64_slot3_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x38000000;
+ slotbuf[1] = 0;
+}
+
+static void
+Opcode_bne_w18_Slot_xt_flix64_slot3_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x90000000;
+ slotbuf[1] = 0;
+}
+
+static void
+Opcode_bge_w18_Slot_xt_flix64_slot3_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x48000000;
+ slotbuf[1] = 0;
+}
+
+static void
+Opcode_blt_w18_Slot_xt_flix64_slot3_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x68000000;
+ slotbuf[1] = 0;
+}
+
+static void
+Opcode_bgeu_w18_Slot_xt_flix64_slot3_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x58000000;
+ slotbuf[1] = 0;
+}
+
+static void
+Opcode_bltu_w18_Slot_xt_flix64_slot3_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x78000000;
+ slotbuf[1] = 0;
+}
+
+static void
+Opcode_bany_w18_Slot_xt_flix64_slot3_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x20000000;
+ slotbuf[1] = 0;
+}
+
+static void
+Opcode_bnone_w18_Slot_xt_flix64_slot3_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0xa0000000;
+ slotbuf[1] = 0;
+}
+
+static void
+Opcode_ball_w18_Slot_xt_flix64_slot3_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x18000000;
+ slotbuf[1] = 0;
+}
+
+static void
+Opcode_bnall_w18_Slot_xt_flix64_slot3_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x88000000;
+ slotbuf[1] = 0;
+}
+
+static void
+Opcode_bbc_w18_Slot_xt_flix64_slot3_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x28000000;
+ slotbuf[1] = 0;
+}
+
+static void
+Opcode_bbs_w18_Slot_xt_flix64_slot3_encode (xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = 0x30000000;
+ slotbuf[1] = 0;
+}
+
+xtensa_opcode_encode_fn Opcode_excw_encode_fns[] = {
+ Opcode_excw_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_rfe_encode_fns[] = {
+ Opcode_rfe_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_rfde_encode_fns[] = {
+ Opcode_rfde_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_syscall_encode_fns[] = {
+ Opcode_syscall_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_simcall_encode_fns[] = {
+ Opcode_simcall_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_call12_encode_fns[] = {
+ Opcode_call12_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_call8_encode_fns[] = {
+ Opcode_call8_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_call4_encode_fns[] = {
+ Opcode_call4_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_callx12_encode_fns[] = {
+ Opcode_callx12_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_callx8_encode_fns[] = {
+ Opcode_callx8_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_callx4_encode_fns[] = {
+ Opcode_callx4_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_entry_encode_fns[] = {
+ Opcode_entry_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_movsp_encode_fns[] = {
+ Opcode_movsp_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_rotw_encode_fns[] = {
+ Opcode_rotw_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_retw_encode_fns[] = {
+ Opcode_retw_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_retw_n_encode_fns[] = {
+ 0, 0, Opcode_retw_n_Slot_inst16b_encode, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_rfwo_encode_fns[] = {
+ Opcode_rfwo_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_rfwu_encode_fns[] = {
+ Opcode_rfwu_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_l32e_encode_fns[] = {
+ Opcode_l32e_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_s32e_encode_fns[] = {
+ Opcode_s32e_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_rsr_windowbase_encode_fns[] = {
+ Opcode_rsr_windowbase_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_wsr_windowbase_encode_fns[] = {
+ Opcode_wsr_windowbase_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_xsr_windowbase_encode_fns[] = {
+ Opcode_xsr_windowbase_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_rsr_windowstart_encode_fns[] = {
+ Opcode_rsr_windowstart_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_wsr_windowstart_encode_fns[] = {
+ Opcode_wsr_windowstart_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_xsr_windowstart_encode_fns[] = {
+ Opcode_xsr_windowstart_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_add_n_encode_fns[] = {
+ 0, Opcode_add_n_Slot_inst16a_encode, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_addi_n_encode_fns[] = {
+ 0, Opcode_addi_n_Slot_inst16a_encode, 0, 0, 0, 0, Opcode_addi_n_Slot_xt_flix64_slot2_encode, 0
+};
+
+xtensa_opcode_encode_fn Opcode_beqz_n_encode_fns[] = {
+ 0, 0, Opcode_beqz_n_Slot_inst16b_encode, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_bnez_n_encode_fns[] = {
+ 0, 0, Opcode_bnez_n_Slot_inst16b_encode, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_ill_n_encode_fns[] = {
+ 0, 0, Opcode_ill_n_Slot_inst16b_encode, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_l32i_n_encode_fns[] = {
+ 0, Opcode_l32i_n_Slot_inst16a_encode, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_mov_n_encode_fns[] = {
+ 0, 0, Opcode_mov_n_Slot_inst16b_encode, Opcode_mov_n_Slot_xt_flix64_slot0_encode, Opcode_mov_n_Slot_xt_flix64_slot0_encode, Opcode_mov_n_Slot_xt_flix64_slot1_encode, Opcode_mov_n_Slot_xt_flix64_slot2_encode, 0
+};
+
+xtensa_opcode_encode_fn Opcode_movi_n_encode_fns[] = {
+ 0, 0, Opcode_movi_n_Slot_inst16b_encode, 0, 0, 0, Opcode_movi_n_Slot_xt_flix64_slot2_encode, 0
+};
+
+xtensa_opcode_encode_fn Opcode_nop_n_encode_fns[] = {
+ 0, 0, Opcode_nop_n_Slot_inst16b_encode, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_ret_n_encode_fns[] = {
+ 0, 0, Opcode_ret_n_Slot_inst16b_encode, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_s32i_n_encode_fns[] = {
+ 0, Opcode_s32i_n_Slot_inst16a_encode, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_rur_threadptr_encode_fns[] = {
+ Opcode_rur_threadptr_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_wur_threadptr_encode_fns[] = {
+ Opcode_wur_threadptr_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_addi_encode_fns[] = {
+ Opcode_addi_Slot_inst_encode, 0, 0, Opcode_addi_Slot_xt_flix64_slot0_encode, Opcode_addi_Slot_xt_flix64_slot0_encode, Opcode_addi_Slot_xt_flix64_slot1_encode, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_addmi_encode_fns[] = {
+ Opcode_addmi_Slot_inst_encode, 0, 0, Opcode_addmi_Slot_xt_flix64_slot0_encode, Opcode_addmi_Slot_xt_flix64_slot0_encode, Opcode_addmi_Slot_xt_flix64_slot1_encode, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_add_encode_fns[] = {
+ Opcode_add_Slot_inst_encode, 0, 0, Opcode_add_Slot_xt_flix64_slot0_encode, Opcode_add_Slot_xt_flix64_slot0_encode, Opcode_add_Slot_xt_flix64_slot1_encode, Opcode_add_Slot_xt_flix64_slot2_encode, 0
+};
+
+xtensa_opcode_encode_fn Opcode_sub_encode_fns[] = {
+ Opcode_sub_Slot_inst_encode, 0, 0, Opcode_sub_Slot_xt_flix64_slot0_encode, Opcode_sub_Slot_xt_flix64_slot0_encode, Opcode_sub_Slot_xt_flix64_slot1_encode, Opcode_sub_Slot_xt_flix64_slot2_encode, 0
+};
+
+xtensa_opcode_encode_fn Opcode_addx2_encode_fns[] = {
+ Opcode_addx2_Slot_inst_encode, 0, 0, Opcode_addx2_Slot_xt_flix64_slot0_encode, Opcode_addx2_Slot_xt_flix64_slot0_encode, Opcode_addx2_Slot_xt_flix64_slot1_encode, Opcode_addx2_Slot_xt_flix64_slot2_encode, 0
+};
+
+xtensa_opcode_encode_fn Opcode_addx4_encode_fns[] = {
+ Opcode_addx4_Slot_inst_encode, 0, 0, Opcode_addx4_Slot_xt_flix64_slot0_encode, Opcode_addx4_Slot_xt_flix64_slot0_encode, Opcode_addx4_Slot_xt_flix64_slot1_encode, Opcode_addx4_Slot_xt_flix64_slot2_encode, 0
+};
+
+xtensa_opcode_encode_fn Opcode_addx8_encode_fns[] = {
+ Opcode_addx8_Slot_inst_encode, 0, 0, Opcode_addx8_Slot_xt_flix64_slot0_encode, Opcode_addx8_Slot_xt_flix64_slot0_encode, Opcode_addx8_Slot_xt_flix64_slot1_encode, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_subx2_encode_fns[] = {
+ Opcode_subx2_Slot_inst_encode, 0, 0, Opcode_subx2_Slot_xt_flix64_slot0_encode, Opcode_subx2_Slot_xt_flix64_slot0_encode, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_subx4_encode_fns[] = {
+ Opcode_subx4_Slot_inst_encode, 0, 0, Opcode_subx4_Slot_xt_flix64_slot0_encode, Opcode_subx4_Slot_xt_flix64_slot0_encode, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_subx8_encode_fns[] = {
+ Opcode_subx8_Slot_inst_encode, 0, 0, Opcode_subx8_Slot_xt_flix64_slot0_encode, Opcode_subx8_Slot_xt_flix64_slot0_encode, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_and_encode_fns[] = {
+ Opcode_and_Slot_inst_encode, 0, 0, Opcode_and_Slot_xt_flix64_slot0_encode, Opcode_and_Slot_xt_flix64_slot0_encode, Opcode_and_Slot_xt_flix64_slot1_encode, Opcode_and_Slot_xt_flix64_slot2_encode, 0
+};
+
+xtensa_opcode_encode_fn Opcode_or_encode_fns[] = {
+ Opcode_or_Slot_inst_encode, 0, 0, Opcode_or_Slot_xt_flix64_slot0_encode, Opcode_or_Slot_xt_flix64_slot0_encode, Opcode_or_Slot_xt_flix64_slot1_encode, Opcode_or_Slot_xt_flix64_slot2_encode, 0
+};
+
+xtensa_opcode_encode_fn Opcode_xor_encode_fns[] = {
+ Opcode_xor_Slot_inst_encode, 0, 0, Opcode_xor_Slot_xt_flix64_slot0_encode, Opcode_xor_Slot_xt_flix64_slot0_encode, Opcode_xor_Slot_xt_flix64_slot1_encode, Opcode_xor_Slot_xt_flix64_slot2_encode, 0
+};
+
+xtensa_opcode_encode_fn Opcode_beqi_encode_fns[] = {
+ Opcode_beqi_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_bnei_encode_fns[] = {
+ Opcode_bnei_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_bgei_encode_fns[] = {
+ Opcode_bgei_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_blti_encode_fns[] = {
+ Opcode_blti_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_bbci_encode_fns[] = {
+ Opcode_bbci_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_bbsi_encode_fns[] = {
+ Opcode_bbsi_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_bgeui_encode_fns[] = {
+ Opcode_bgeui_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_bltui_encode_fns[] = {
+ Opcode_bltui_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_beq_encode_fns[] = {
+ Opcode_beq_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_bne_encode_fns[] = {
+ Opcode_bne_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_bge_encode_fns[] = {
+ Opcode_bge_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_blt_encode_fns[] = {
+ Opcode_blt_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_bgeu_encode_fns[] = {
+ Opcode_bgeu_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_bltu_encode_fns[] = {
+ Opcode_bltu_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_bany_encode_fns[] = {
+ Opcode_bany_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_bnone_encode_fns[] = {
+ Opcode_bnone_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_ball_encode_fns[] = {
+ Opcode_ball_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_bnall_encode_fns[] = {
+ Opcode_bnall_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_bbc_encode_fns[] = {
+ Opcode_bbc_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_bbs_encode_fns[] = {
+ Opcode_bbs_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_beqz_encode_fns[] = {
+ Opcode_beqz_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_bnez_encode_fns[] = {
+ Opcode_bnez_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_bgez_encode_fns[] = {
+ Opcode_bgez_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_bltz_encode_fns[] = {
+ Opcode_bltz_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_call0_encode_fns[] = {
+ Opcode_call0_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_callx0_encode_fns[] = {
+ Opcode_callx0_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_extui_encode_fns[] = {
+ Opcode_extui_Slot_inst_encode, 0, 0, Opcode_extui_Slot_xt_flix64_slot0_encode, Opcode_extui_Slot_xt_flix64_slot0_encode, Opcode_extui_Slot_xt_flix64_slot1_encode, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_ill_encode_fns[] = {
+ Opcode_ill_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_j_encode_fns[] = {
+ Opcode_j_Slot_inst_encode, 0, 0, 0, 0, Opcode_j_Slot_xt_flix64_slot1_encode, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_jx_encode_fns[] = {
+ Opcode_jx_Slot_inst_encode, 0, 0, 0, 0, Opcode_jx_Slot_xt_flix64_slot1_encode, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_l16ui_encode_fns[] = {
+ Opcode_l16ui_Slot_inst_encode, 0, 0, Opcode_l16ui_Slot_xt_flix64_slot0_encode, Opcode_l16ui_Slot_xt_flix64_slot0_encode, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_l16si_encode_fns[] = {
+ Opcode_l16si_Slot_inst_encode, 0, 0, Opcode_l16si_Slot_xt_flix64_slot0_encode, Opcode_l16si_Slot_xt_flix64_slot0_encode, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_l32i_encode_fns[] = {
+ Opcode_l32i_Slot_inst_encode, 0, 0, Opcode_l32i_Slot_xt_flix64_slot0_encode, Opcode_l32i_Slot_xt_flix64_slot0_encode, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_l32r_encode_fns[] = {
+ Opcode_l32r_Slot_inst_encode, 0, 0, Opcode_l32r_Slot_xt_flix64_slot0_encode, Opcode_l32r_Slot_xt_flix64_slot0_encode, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_l8ui_encode_fns[] = {
+ Opcode_l8ui_Slot_inst_encode, 0, 0, Opcode_l8ui_Slot_xt_flix64_slot0_encode, Opcode_l8ui_Slot_xt_flix64_slot0_encode, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_loop_encode_fns[] = {
+ Opcode_loop_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_loopnez_encode_fns[] = {
+ Opcode_loopnez_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_loopgtz_encode_fns[] = {
+ Opcode_loopgtz_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_movi_encode_fns[] = {
+ Opcode_movi_Slot_inst_encode, 0, 0, Opcode_movi_Slot_xt_flix64_slot0_encode, Opcode_movi_Slot_xt_flix64_slot0_encode, Opcode_movi_Slot_xt_flix64_slot1_encode, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_moveqz_encode_fns[] = {
+ Opcode_moveqz_Slot_inst_encode, 0, 0, Opcode_moveqz_Slot_xt_flix64_slot0_encode, Opcode_moveqz_Slot_xt_flix64_slot0_encode, Opcode_moveqz_Slot_xt_flix64_slot1_encode, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_movnez_encode_fns[] = {
+ Opcode_movnez_Slot_inst_encode, 0, 0, Opcode_movnez_Slot_xt_flix64_slot0_encode, Opcode_movnez_Slot_xt_flix64_slot0_encode, Opcode_movnez_Slot_xt_flix64_slot1_encode, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_movltz_encode_fns[] = {
+ Opcode_movltz_Slot_inst_encode, 0, 0, Opcode_movltz_Slot_xt_flix64_slot0_encode, Opcode_movltz_Slot_xt_flix64_slot0_encode, Opcode_movltz_Slot_xt_flix64_slot1_encode, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_movgez_encode_fns[] = {
+ Opcode_movgez_Slot_inst_encode, 0, 0, Opcode_movgez_Slot_xt_flix64_slot0_encode, Opcode_movgez_Slot_xt_flix64_slot0_encode, Opcode_movgez_Slot_xt_flix64_slot1_encode, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_neg_encode_fns[] = {
+ Opcode_neg_Slot_inst_encode, 0, 0, Opcode_neg_Slot_xt_flix64_slot0_encode, Opcode_neg_Slot_xt_flix64_slot0_encode, Opcode_neg_Slot_xt_flix64_slot1_encode, Opcode_neg_Slot_xt_flix64_slot2_encode, 0
+};
+
+xtensa_opcode_encode_fn Opcode_abs_encode_fns[] = {
+ Opcode_abs_Slot_inst_encode, 0, 0, Opcode_abs_Slot_xt_flix64_slot0_encode, Opcode_abs_Slot_xt_flix64_slot0_encode, 0, Opcode_abs_Slot_xt_flix64_slot2_encode, 0
+};
+
+xtensa_opcode_encode_fn Opcode_nop_encode_fns[] = {
+ Opcode_nop_Slot_inst_encode, 0, 0, Opcode_nop_Slot_xt_flix64_slot0_encode, Opcode_nop_Slot_xt_flix64_slot0_encode, Opcode_nop_Slot_xt_flix64_slot1_encode, Opcode_nop_Slot_xt_flix64_slot2_encode, Opcode_nop_Slot_xt_flix64_slot3_encode
+};
+
+xtensa_opcode_encode_fn Opcode_ret_encode_fns[] = {
+ Opcode_ret_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_s16i_encode_fns[] = {
+ Opcode_s16i_Slot_inst_encode, 0, 0, Opcode_s16i_Slot_xt_flix64_slot0_encode, Opcode_s16i_Slot_xt_flix64_slot0_encode, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_s32i_encode_fns[] = {
+ Opcode_s32i_Slot_inst_encode, 0, 0, Opcode_s32i_Slot_xt_flix64_slot0_encode, Opcode_s32i_Slot_xt_flix64_slot0_encode, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_s8i_encode_fns[] = {
+ Opcode_s8i_Slot_inst_encode, 0, 0, Opcode_s8i_Slot_xt_flix64_slot0_encode, Opcode_s8i_Slot_xt_flix64_slot0_encode, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_ssr_encode_fns[] = {
+ Opcode_ssr_Slot_inst_encode, 0, 0, Opcode_ssr_Slot_xt_flix64_slot0_encode, Opcode_ssr_Slot_xt_flix64_slot0_encode, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_ssl_encode_fns[] = {
+ Opcode_ssl_Slot_inst_encode, 0, 0, Opcode_ssl_Slot_xt_flix64_slot0_encode, Opcode_ssl_Slot_xt_flix64_slot0_encode, Opcode_ssl_Slot_xt_flix64_slot1_encode, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_ssa8l_encode_fns[] = {
+ Opcode_ssa8l_Slot_inst_encode, 0, 0, Opcode_ssa8l_Slot_xt_flix64_slot0_encode, Opcode_ssa8l_Slot_xt_flix64_slot0_encode, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_ssa8b_encode_fns[] = {
+ Opcode_ssa8b_Slot_inst_encode, 0, 0, Opcode_ssa8b_Slot_xt_flix64_slot0_encode, Opcode_ssa8b_Slot_xt_flix64_slot0_encode, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_ssai_encode_fns[] = {
+ Opcode_ssai_Slot_inst_encode, 0, 0, Opcode_ssai_Slot_xt_flix64_slot0_encode, Opcode_ssai_Slot_xt_flix64_slot0_encode, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_sll_encode_fns[] = {
+ Opcode_sll_Slot_inst_encode, 0, 0, Opcode_sll_Slot_xt_flix64_slot0_encode, Opcode_sll_Slot_xt_flix64_slot0_encode, Opcode_sll_Slot_xt_flix64_slot1_encode, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_src_encode_fns[] = {
+ Opcode_src_Slot_inst_encode, 0, 0, Opcode_src_Slot_xt_flix64_slot0_encode, Opcode_src_Slot_xt_flix64_slot0_encode, Opcode_src_Slot_xt_flix64_slot1_encode, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_srl_encode_fns[] = {
+ Opcode_srl_Slot_inst_encode, 0, 0, Opcode_srl_Slot_xt_flix64_slot0_encode, Opcode_srl_Slot_xt_flix64_slot0_encode, Opcode_srl_Slot_xt_flix64_slot1_encode, Opcode_srl_Slot_xt_flix64_slot2_encode, 0
+};
+
+xtensa_opcode_encode_fn Opcode_sra_encode_fns[] = {
+ Opcode_sra_Slot_inst_encode, 0, 0, Opcode_sra_Slot_xt_flix64_slot0_encode, Opcode_sra_Slot_xt_flix64_slot0_encode, Opcode_sra_Slot_xt_flix64_slot1_encode, Opcode_sra_Slot_xt_flix64_slot2_encode, 0
+};
+
+xtensa_opcode_encode_fn Opcode_slli_encode_fns[] = {
+ Opcode_slli_Slot_inst_encode, 0, 0, Opcode_slli_Slot_xt_flix64_slot0_encode, Opcode_slli_Slot_xt_flix64_slot0_encode, Opcode_slli_Slot_xt_flix64_slot1_encode, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_srai_encode_fns[] = {
+ Opcode_srai_Slot_inst_encode, 0, 0, Opcode_srai_Slot_xt_flix64_slot0_encode, Opcode_srai_Slot_xt_flix64_slot0_encode, Opcode_srai_Slot_xt_flix64_slot1_encode, Opcode_srai_Slot_xt_flix64_slot2_encode, 0
+};
+
+xtensa_opcode_encode_fn Opcode_srli_encode_fns[] = {
+ Opcode_srli_Slot_inst_encode, 0, 0, Opcode_srli_Slot_xt_flix64_slot0_encode, Opcode_srli_Slot_xt_flix64_slot0_encode, Opcode_srli_Slot_xt_flix64_slot1_encode, Opcode_srli_Slot_xt_flix64_slot2_encode, 0
+};
+
+xtensa_opcode_encode_fn Opcode_memw_encode_fns[] = {
+ Opcode_memw_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_extw_encode_fns[] = {
+ Opcode_extw_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_isync_encode_fns[] = {
+ Opcode_isync_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_rsync_encode_fns[] = {
+ Opcode_rsync_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_esync_encode_fns[] = {
+ Opcode_esync_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_dsync_encode_fns[] = {
+ Opcode_dsync_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_rsil_encode_fns[] = {
+ Opcode_rsil_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_rsr_lend_encode_fns[] = {
+ Opcode_rsr_lend_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_wsr_lend_encode_fns[] = {
+ Opcode_wsr_lend_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_xsr_lend_encode_fns[] = {
+ Opcode_xsr_lend_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_rsr_lcount_encode_fns[] = {
+ Opcode_rsr_lcount_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_wsr_lcount_encode_fns[] = {
+ Opcode_wsr_lcount_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_xsr_lcount_encode_fns[] = {
+ Opcode_xsr_lcount_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_rsr_lbeg_encode_fns[] = {
+ Opcode_rsr_lbeg_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_wsr_lbeg_encode_fns[] = {
+ Opcode_wsr_lbeg_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_xsr_lbeg_encode_fns[] = {
+ Opcode_xsr_lbeg_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_rsr_sar_encode_fns[] = {
+ Opcode_rsr_sar_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_wsr_sar_encode_fns[] = {
+ Opcode_wsr_sar_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_xsr_sar_encode_fns[] = {
+ Opcode_xsr_sar_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_rsr_litbase_encode_fns[] = {
+ Opcode_rsr_litbase_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_wsr_litbase_encode_fns[] = {
+ Opcode_wsr_litbase_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_xsr_litbase_encode_fns[] = {
+ Opcode_xsr_litbase_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_rsr_176_encode_fns[] = {
+ Opcode_rsr_176_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_rsr_208_encode_fns[] = {
+ Opcode_rsr_208_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_rsr_ps_encode_fns[] = {
+ Opcode_rsr_ps_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_wsr_ps_encode_fns[] = {
+ Opcode_wsr_ps_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_xsr_ps_encode_fns[] = {
+ Opcode_xsr_ps_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_rsr_epc1_encode_fns[] = {
+ Opcode_rsr_epc1_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_wsr_epc1_encode_fns[] = {
+ Opcode_wsr_epc1_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_xsr_epc1_encode_fns[] = {
+ Opcode_xsr_epc1_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_rsr_excsave1_encode_fns[] = {
+ Opcode_rsr_excsave1_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_wsr_excsave1_encode_fns[] = {
+ Opcode_wsr_excsave1_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_xsr_excsave1_encode_fns[] = {
+ Opcode_xsr_excsave1_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_rsr_epc2_encode_fns[] = {
+ Opcode_rsr_epc2_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_wsr_epc2_encode_fns[] = {
+ Opcode_wsr_epc2_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_xsr_epc2_encode_fns[] = {
+ Opcode_xsr_epc2_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_rsr_excsave2_encode_fns[] = {
+ Opcode_rsr_excsave2_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_wsr_excsave2_encode_fns[] = {
+ Opcode_wsr_excsave2_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_xsr_excsave2_encode_fns[] = {
+ Opcode_xsr_excsave2_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_rsr_epc3_encode_fns[] = {
+ Opcode_rsr_epc3_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_wsr_epc3_encode_fns[] = {
+ Opcode_wsr_epc3_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_xsr_epc3_encode_fns[] = {
+ Opcode_xsr_epc3_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_rsr_excsave3_encode_fns[] = {
+ Opcode_rsr_excsave3_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_wsr_excsave3_encode_fns[] = {
+ Opcode_wsr_excsave3_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_xsr_excsave3_encode_fns[] = {
+ Opcode_xsr_excsave3_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_rsr_epc4_encode_fns[] = {
+ Opcode_rsr_epc4_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_wsr_epc4_encode_fns[] = {
+ Opcode_wsr_epc4_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_xsr_epc4_encode_fns[] = {
+ Opcode_xsr_epc4_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_rsr_excsave4_encode_fns[] = {
+ Opcode_rsr_excsave4_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_wsr_excsave4_encode_fns[] = {
+ Opcode_wsr_excsave4_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_xsr_excsave4_encode_fns[] = {
+ Opcode_xsr_excsave4_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_rsr_epc5_encode_fns[] = {
+ Opcode_rsr_epc5_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_wsr_epc5_encode_fns[] = {
+ Opcode_wsr_epc5_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_xsr_epc5_encode_fns[] = {
+ Opcode_xsr_epc5_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_rsr_excsave5_encode_fns[] = {
+ Opcode_rsr_excsave5_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_wsr_excsave5_encode_fns[] = {
+ Opcode_wsr_excsave5_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_xsr_excsave5_encode_fns[] = {
+ Opcode_xsr_excsave5_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_rsr_epc6_encode_fns[] = {
+ Opcode_rsr_epc6_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_wsr_epc6_encode_fns[] = {
+ Opcode_wsr_epc6_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_xsr_epc6_encode_fns[] = {
+ Opcode_xsr_epc6_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_rsr_excsave6_encode_fns[] = {
+ Opcode_rsr_excsave6_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_wsr_excsave6_encode_fns[] = {
+ Opcode_wsr_excsave6_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_xsr_excsave6_encode_fns[] = {
+ Opcode_xsr_excsave6_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_rsr_epc7_encode_fns[] = {
+ Opcode_rsr_epc7_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_wsr_epc7_encode_fns[] = {
+ Opcode_wsr_epc7_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_xsr_epc7_encode_fns[] = {
+ Opcode_xsr_epc7_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_rsr_excsave7_encode_fns[] = {
+ Opcode_rsr_excsave7_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_wsr_excsave7_encode_fns[] = {
+ Opcode_wsr_excsave7_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_xsr_excsave7_encode_fns[] = {
+ Opcode_xsr_excsave7_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_rsr_eps2_encode_fns[] = {
+ Opcode_rsr_eps2_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_wsr_eps2_encode_fns[] = {
+ Opcode_wsr_eps2_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_xsr_eps2_encode_fns[] = {
+ Opcode_xsr_eps2_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_rsr_eps3_encode_fns[] = {
+ Opcode_rsr_eps3_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_wsr_eps3_encode_fns[] = {
+ Opcode_wsr_eps3_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_xsr_eps3_encode_fns[] = {
+ Opcode_xsr_eps3_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_rsr_eps4_encode_fns[] = {
+ Opcode_rsr_eps4_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_wsr_eps4_encode_fns[] = {
+ Opcode_wsr_eps4_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_xsr_eps4_encode_fns[] = {
+ Opcode_xsr_eps4_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_rsr_eps5_encode_fns[] = {
+ Opcode_rsr_eps5_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_wsr_eps5_encode_fns[] = {
+ Opcode_wsr_eps5_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_xsr_eps5_encode_fns[] = {
+ Opcode_xsr_eps5_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_rsr_eps6_encode_fns[] = {
+ Opcode_rsr_eps6_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_wsr_eps6_encode_fns[] = {
+ Opcode_wsr_eps6_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_xsr_eps6_encode_fns[] = {
+ Opcode_xsr_eps6_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_rsr_eps7_encode_fns[] = {
+ Opcode_rsr_eps7_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_wsr_eps7_encode_fns[] = {
+ Opcode_wsr_eps7_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_xsr_eps7_encode_fns[] = {
+ Opcode_xsr_eps7_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_rsr_excvaddr_encode_fns[] = {
+ Opcode_rsr_excvaddr_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_wsr_excvaddr_encode_fns[] = {
+ Opcode_wsr_excvaddr_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_xsr_excvaddr_encode_fns[] = {
+ Opcode_xsr_excvaddr_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_rsr_depc_encode_fns[] = {
+ Opcode_rsr_depc_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_wsr_depc_encode_fns[] = {
+ Opcode_wsr_depc_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_xsr_depc_encode_fns[] = {
+ Opcode_xsr_depc_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_rsr_exccause_encode_fns[] = {
+ Opcode_rsr_exccause_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_wsr_exccause_encode_fns[] = {
+ Opcode_wsr_exccause_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_xsr_exccause_encode_fns[] = {
+ Opcode_xsr_exccause_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_rsr_misc0_encode_fns[] = {
+ Opcode_rsr_misc0_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_wsr_misc0_encode_fns[] = {
+ Opcode_wsr_misc0_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_xsr_misc0_encode_fns[] = {
+ Opcode_xsr_misc0_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_rsr_misc1_encode_fns[] = {
+ Opcode_rsr_misc1_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_wsr_misc1_encode_fns[] = {
+ Opcode_wsr_misc1_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_xsr_misc1_encode_fns[] = {
+ Opcode_xsr_misc1_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_rsr_misc2_encode_fns[] = {
+ Opcode_rsr_misc2_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_wsr_misc2_encode_fns[] = {
+ Opcode_wsr_misc2_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_xsr_misc2_encode_fns[] = {
+ Opcode_xsr_misc2_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_rsr_misc3_encode_fns[] = {
+ Opcode_rsr_misc3_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_wsr_misc3_encode_fns[] = {
+ Opcode_wsr_misc3_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_xsr_misc3_encode_fns[] = {
+ Opcode_xsr_misc3_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_rsr_prid_encode_fns[] = {
+ Opcode_rsr_prid_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_rsr_vecbase_encode_fns[] = {
+ Opcode_rsr_vecbase_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_wsr_vecbase_encode_fns[] = {
+ Opcode_wsr_vecbase_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_xsr_vecbase_encode_fns[] = {
+ Opcode_xsr_vecbase_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_mul_aa_ll_encode_fns[] = {
+ Opcode_mul_aa_ll_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_mul_aa_hl_encode_fns[] = {
+ Opcode_mul_aa_hl_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_mul_aa_lh_encode_fns[] = {
+ Opcode_mul_aa_lh_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_mul_aa_hh_encode_fns[] = {
+ Opcode_mul_aa_hh_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_umul_aa_ll_encode_fns[] = {
+ Opcode_umul_aa_ll_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_umul_aa_hl_encode_fns[] = {
+ Opcode_umul_aa_hl_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_umul_aa_lh_encode_fns[] = {
+ Opcode_umul_aa_lh_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_umul_aa_hh_encode_fns[] = {
+ Opcode_umul_aa_hh_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_mul_ad_ll_encode_fns[] = {
+ Opcode_mul_ad_ll_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_mul_ad_hl_encode_fns[] = {
+ Opcode_mul_ad_hl_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_mul_ad_lh_encode_fns[] = {
+ Opcode_mul_ad_lh_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_mul_ad_hh_encode_fns[] = {
+ Opcode_mul_ad_hh_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_mul_da_ll_encode_fns[] = {
+ Opcode_mul_da_ll_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_mul_da_hl_encode_fns[] = {
+ Opcode_mul_da_hl_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_mul_da_lh_encode_fns[] = {
+ Opcode_mul_da_lh_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_mul_da_hh_encode_fns[] = {
+ Opcode_mul_da_hh_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_mul_dd_ll_encode_fns[] = {
+ Opcode_mul_dd_ll_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_mul_dd_hl_encode_fns[] = {
+ Opcode_mul_dd_hl_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_mul_dd_lh_encode_fns[] = {
+ Opcode_mul_dd_lh_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_mul_dd_hh_encode_fns[] = {
+ Opcode_mul_dd_hh_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_mula_aa_ll_encode_fns[] = {
+ Opcode_mula_aa_ll_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_mula_aa_hl_encode_fns[] = {
+ Opcode_mula_aa_hl_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_mula_aa_lh_encode_fns[] = {
+ Opcode_mula_aa_lh_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_mula_aa_hh_encode_fns[] = {
+ Opcode_mula_aa_hh_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_muls_aa_ll_encode_fns[] = {
+ Opcode_muls_aa_ll_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_muls_aa_hl_encode_fns[] = {
+ Opcode_muls_aa_hl_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_muls_aa_lh_encode_fns[] = {
+ Opcode_muls_aa_lh_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_muls_aa_hh_encode_fns[] = {
+ Opcode_muls_aa_hh_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_mula_ad_ll_encode_fns[] = {
+ Opcode_mula_ad_ll_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_mula_ad_hl_encode_fns[] = {
+ Opcode_mula_ad_hl_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_mula_ad_lh_encode_fns[] = {
+ Opcode_mula_ad_lh_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_mula_ad_hh_encode_fns[] = {
+ Opcode_mula_ad_hh_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_muls_ad_ll_encode_fns[] = {
+ Opcode_muls_ad_ll_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_muls_ad_hl_encode_fns[] = {
+ Opcode_muls_ad_hl_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_muls_ad_lh_encode_fns[] = {
+ Opcode_muls_ad_lh_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_muls_ad_hh_encode_fns[] = {
+ Opcode_muls_ad_hh_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_mula_da_ll_encode_fns[] = {
+ Opcode_mula_da_ll_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_mula_da_hl_encode_fns[] = {
+ Opcode_mula_da_hl_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_mula_da_lh_encode_fns[] = {
+ Opcode_mula_da_lh_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_mula_da_hh_encode_fns[] = {
+ Opcode_mula_da_hh_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_muls_da_ll_encode_fns[] = {
+ Opcode_muls_da_ll_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_muls_da_hl_encode_fns[] = {
+ Opcode_muls_da_hl_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_muls_da_lh_encode_fns[] = {
+ Opcode_muls_da_lh_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_muls_da_hh_encode_fns[] = {
+ Opcode_muls_da_hh_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_mula_dd_ll_encode_fns[] = {
+ Opcode_mula_dd_ll_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_mula_dd_hl_encode_fns[] = {
+ Opcode_mula_dd_hl_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_mula_dd_lh_encode_fns[] = {
+ Opcode_mula_dd_lh_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_mula_dd_hh_encode_fns[] = {
+ Opcode_mula_dd_hh_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_muls_dd_ll_encode_fns[] = {
+ Opcode_muls_dd_ll_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_muls_dd_hl_encode_fns[] = {
+ Opcode_muls_dd_hl_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_muls_dd_lh_encode_fns[] = {
+ Opcode_muls_dd_lh_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_muls_dd_hh_encode_fns[] = {
+ Opcode_muls_dd_hh_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_mula_da_ll_lddec_encode_fns[] = {
+ Opcode_mula_da_ll_lddec_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_mula_da_ll_ldinc_encode_fns[] = {
+ Opcode_mula_da_ll_ldinc_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_mula_da_hl_lddec_encode_fns[] = {
+ Opcode_mula_da_hl_lddec_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_mula_da_hl_ldinc_encode_fns[] = {
+ Opcode_mula_da_hl_ldinc_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_mula_da_lh_lddec_encode_fns[] = {
+ Opcode_mula_da_lh_lddec_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_mula_da_lh_ldinc_encode_fns[] = {
+ Opcode_mula_da_lh_ldinc_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_mula_da_hh_lddec_encode_fns[] = {
+ Opcode_mula_da_hh_lddec_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_mula_da_hh_ldinc_encode_fns[] = {
+ Opcode_mula_da_hh_ldinc_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_mula_dd_ll_lddec_encode_fns[] = {
+ Opcode_mula_dd_ll_lddec_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_mula_dd_ll_ldinc_encode_fns[] = {
+ Opcode_mula_dd_ll_ldinc_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_mula_dd_hl_lddec_encode_fns[] = {
+ Opcode_mula_dd_hl_lddec_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_mula_dd_hl_ldinc_encode_fns[] = {
+ Opcode_mula_dd_hl_ldinc_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_mula_dd_lh_lddec_encode_fns[] = {
+ Opcode_mula_dd_lh_lddec_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_mula_dd_lh_ldinc_encode_fns[] = {
+ Opcode_mula_dd_lh_ldinc_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_mula_dd_hh_lddec_encode_fns[] = {
+ Opcode_mula_dd_hh_lddec_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_mula_dd_hh_ldinc_encode_fns[] = {
+ Opcode_mula_dd_hh_ldinc_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_lddec_encode_fns[] = {
+ Opcode_lddec_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_ldinc_encode_fns[] = {
+ Opcode_ldinc_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_mul16u_encode_fns[] = {
+ Opcode_mul16u_Slot_inst_encode, 0, 0, Opcode_mul16u_Slot_xt_flix64_slot0_encode, Opcode_mul16u_Slot_xt_flix64_slot0_encode, Opcode_mul16u_Slot_xt_flix64_slot1_encode, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_mul16s_encode_fns[] = {
+ Opcode_mul16s_Slot_inst_encode, 0, 0, Opcode_mul16s_Slot_xt_flix64_slot0_encode, Opcode_mul16s_Slot_xt_flix64_slot0_encode, Opcode_mul16s_Slot_xt_flix64_slot1_encode, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_rsr_m0_encode_fns[] = {
+ Opcode_rsr_m0_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_wsr_m0_encode_fns[] = {
+ Opcode_wsr_m0_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_xsr_m0_encode_fns[] = {
+ Opcode_xsr_m0_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_rsr_m1_encode_fns[] = {
+ Opcode_rsr_m1_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_wsr_m1_encode_fns[] = {
+ Opcode_wsr_m1_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_xsr_m1_encode_fns[] = {
+ Opcode_xsr_m1_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_rsr_m2_encode_fns[] = {
+ Opcode_rsr_m2_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_wsr_m2_encode_fns[] = {
+ Opcode_wsr_m2_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_xsr_m2_encode_fns[] = {
+ Opcode_xsr_m2_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_rsr_m3_encode_fns[] = {
+ Opcode_rsr_m3_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_wsr_m3_encode_fns[] = {
+ Opcode_wsr_m3_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_xsr_m3_encode_fns[] = {
+ Opcode_xsr_m3_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_rsr_acclo_encode_fns[] = {
+ Opcode_rsr_acclo_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_wsr_acclo_encode_fns[] = {
+ Opcode_wsr_acclo_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_xsr_acclo_encode_fns[] = {
+ Opcode_xsr_acclo_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_rsr_acchi_encode_fns[] = {
+ Opcode_rsr_acchi_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_wsr_acchi_encode_fns[] = {
+ Opcode_wsr_acchi_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_xsr_acchi_encode_fns[] = {
+ Opcode_xsr_acchi_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_rfi_encode_fns[] = {
+ Opcode_rfi_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_waiti_encode_fns[] = {
+ Opcode_waiti_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_rsr_interrupt_encode_fns[] = {
+ Opcode_rsr_interrupt_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_wsr_intset_encode_fns[] = {
+ Opcode_wsr_intset_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_wsr_intclear_encode_fns[] = {
+ Opcode_wsr_intclear_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_rsr_intenable_encode_fns[] = {
+ Opcode_rsr_intenable_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_wsr_intenable_encode_fns[] = {
+ Opcode_wsr_intenable_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_xsr_intenable_encode_fns[] = {
+ Opcode_xsr_intenable_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_break_encode_fns[] = {
+ Opcode_break_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_break_n_encode_fns[] = {
+ 0, 0, Opcode_break_n_Slot_inst16b_encode, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_rsr_dbreaka0_encode_fns[] = {
+ Opcode_rsr_dbreaka0_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_wsr_dbreaka0_encode_fns[] = {
+ Opcode_wsr_dbreaka0_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_xsr_dbreaka0_encode_fns[] = {
+ Opcode_xsr_dbreaka0_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_rsr_dbreakc0_encode_fns[] = {
+ Opcode_rsr_dbreakc0_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_wsr_dbreakc0_encode_fns[] = {
+ Opcode_wsr_dbreakc0_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_xsr_dbreakc0_encode_fns[] = {
+ Opcode_xsr_dbreakc0_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_rsr_dbreaka1_encode_fns[] = {
+ Opcode_rsr_dbreaka1_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_wsr_dbreaka1_encode_fns[] = {
+ Opcode_wsr_dbreaka1_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_xsr_dbreaka1_encode_fns[] = {
+ Opcode_xsr_dbreaka1_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_rsr_dbreakc1_encode_fns[] = {
+ Opcode_rsr_dbreakc1_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_wsr_dbreakc1_encode_fns[] = {
+ Opcode_wsr_dbreakc1_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_xsr_dbreakc1_encode_fns[] = {
+ Opcode_xsr_dbreakc1_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_rsr_ibreaka0_encode_fns[] = {
+ Opcode_rsr_ibreaka0_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_wsr_ibreaka0_encode_fns[] = {
+ Opcode_wsr_ibreaka0_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_xsr_ibreaka0_encode_fns[] = {
+ Opcode_xsr_ibreaka0_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_rsr_ibreaka1_encode_fns[] = {
+ Opcode_rsr_ibreaka1_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_wsr_ibreaka1_encode_fns[] = {
+ Opcode_wsr_ibreaka1_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_xsr_ibreaka1_encode_fns[] = {
+ Opcode_xsr_ibreaka1_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_rsr_ibreakenable_encode_fns[] = {
+ Opcode_rsr_ibreakenable_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_wsr_ibreakenable_encode_fns[] = {
+ Opcode_wsr_ibreakenable_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_xsr_ibreakenable_encode_fns[] = {
+ Opcode_xsr_ibreakenable_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_rsr_debugcause_encode_fns[] = {
+ Opcode_rsr_debugcause_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_wsr_debugcause_encode_fns[] = {
+ Opcode_wsr_debugcause_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_xsr_debugcause_encode_fns[] = {
+ Opcode_xsr_debugcause_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_rsr_icount_encode_fns[] = {
+ Opcode_rsr_icount_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_wsr_icount_encode_fns[] = {
+ Opcode_wsr_icount_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_xsr_icount_encode_fns[] = {
+ Opcode_xsr_icount_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_rsr_icountlevel_encode_fns[] = {
+ Opcode_rsr_icountlevel_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_wsr_icountlevel_encode_fns[] = {
+ Opcode_wsr_icountlevel_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_xsr_icountlevel_encode_fns[] = {
+ Opcode_xsr_icountlevel_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_rsr_ddr_encode_fns[] = {
+ Opcode_rsr_ddr_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_wsr_ddr_encode_fns[] = {
+ Opcode_wsr_ddr_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_xsr_ddr_encode_fns[] = {
+ Opcode_xsr_ddr_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_rfdo_encode_fns[] = {
+ Opcode_rfdo_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_rfdd_encode_fns[] = {
+ Opcode_rfdd_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_wsr_mmid_encode_fns[] = {
+ Opcode_wsr_mmid_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_andb_encode_fns[] = {
+ Opcode_andb_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_andbc_encode_fns[] = {
+ Opcode_andbc_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_orb_encode_fns[] = {
+ Opcode_orb_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_orbc_encode_fns[] = {
+ Opcode_orbc_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_xorb_encode_fns[] = {
+ Opcode_xorb_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_any4_encode_fns[] = {
+ Opcode_any4_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_all4_encode_fns[] = {
+ Opcode_all4_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_any8_encode_fns[] = {
+ Opcode_any8_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_all8_encode_fns[] = {
+ Opcode_all8_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_bf_encode_fns[] = {
+ Opcode_bf_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_bt_encode_fns[] = {
+ Opcode_bt_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_movf_encode_fns[] = {
+ Opcode_movf_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_movt_encode_fns[] = {
+ Opcode_movt_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_rsr_br_encode_fns[] = {
+ Opcode_rsr_br_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_wsr_br_encode_fns[] = {
+ Opcode_wsr_br_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_xsr_br_encode_fns[] = {
+ Opcode_xsr_br_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_rsr_ccount_encode_fns[] = {
+ Opcode_rsr_ccount_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_wsr_ccount_encode_fns[] = {
+ Opcode_wsr_ccount_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_xsr_ccount_encode_fns[] = {
+ Opcode_xsr_ccount_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_rsr_ccompare0_encode_fns[] = {
+ Opcode_rsr_ccompare0_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_wsr_ccompare0_encode_fns[] = {
+ Opcode_wsr_ccompare0_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_xsr_ccompare0_encode_fns[] = {
+ Opcode_xsr_ccompare0_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_rsr_ccompare1_encode_fns[] = {
+ Opcode_rsr_ccompare1_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_wsr_ccompare1_encode_fns[] = {
+ Opcode_wsr_ccompare1_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_xsr_ccompare1_encode_fns[] = {
+ Opcode_xsr_ccompare1_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_rsr_ccompare2_encode_fns[] = {
+ Opcode_rsr_ccompare2_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_wsr_ccompare2_encode_fns[] = {
+ Opcode_wsr_ccompare2_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_xsr_ccompare2_encode_fns[] = {
+ Opcode_xsr_ccompare2_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_ipf_encode_fns[] = {
+ Opcode_ipf_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_ihi_encode_fns[] = {
+ Opcode_ihi_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_ipfl_encode_fns[] = {
+ Opcode_ipfl_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_ihu_encode_fns[] = {
+ Opcode_ihu_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_iiu_encode_fns[] = {
+ Opcode_iiu_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_iii_encode_fns[] = {
+ Opcode_iii_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_lict_encode_fns[] = {
+ Opcode_lict_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_licw_encode_fns[] = {
+ Opcode_licw_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_sict_encode_fns[] = {
+ Opcode_sict_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_sicw_encode_fns[] = {
+ Opcode_sicw_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_dhwb_encode_fns[] = {
+ Opcode_dhwb_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_dhwbi_encode_fns[] = {
+ Opcode_dhwbi_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_diwb_encode_fns[] = {
+ Opcode_diwb_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_diwbi_encode_fns[] = {
+ Opcode_diwbi_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_dhi_encode_fns[] = {
+ Opcode_dhi_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_dii_encode_fns[] = {
+ Opcode_dii_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_dpfr_encode_fns[] = {
+ Opcode_dpfr_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_dpfw_encode_fns[] = {
+ Opcode_dpfw_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_dpfro_encode_fns[] = {
+ Opcode_dpfro_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_dpfwo_encode_fns[] = {
+ Opcode_dpfwo_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_dpfl_encode_fns[] = {
+ Opcode_dpfl_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_dhu_encode_fns[] = {
+ Opcode_dhu_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_diu_encode_fns[] = {
+ Opcode_diu_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_sdct_encode_fns[] = {
+ Opcode_sdct_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_ldct_encode_fns[] = {
+ Opcode_ldct_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_wsr_ptevaddr_encode_fns[] = {
+ Opcode_wsr_ptevaddr_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_rsr_ptevaddr_encode_fns[] = {
+ Opcode_rsr_ptevaddr_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_xsr_ptevaddr_encode_fns[] = {
+ Opcode_xsr_ptevaddr_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_rsr_rasid_encode_fns[] = {
+ Opcode_rsr_rasid_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_wsr_rasid_encode_fns[] = {
+ Opcode_wsr_rasid_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_xsr_rasid_encode_fns[] = {
+ Opcode_xsr_rasid_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_rsr_itlbcfg_encode_fns[] = {
+ Opcode_rsr_itlbcfg_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_wsr_itlbcfg_encode_fns[] = {
+ Opcode_wsr_itlbcfg_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_xsr_itlbcfg_encode_fns[] = {
+ Opcode_xsr_itlbcfg_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_rsr_dtlbcfg_encode_fns[] = {
+ Opcode_rsr_dtlbcfg_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_wsr_dtlbcfg_encode_fns[] = {
+ Opcode_wsr_dtlbcfg_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_xsr_dtlbcfg_encode_fns[] = {
+ Opcode_xsr_dtlbcfg_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_idtlb_encode_fns[] = {
+ Opcode_idtlb_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_pdtlb_encode_fns[] = {
+ Opcode_pdtlb_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_rdtlb0_encode_fns[] = {
+ Opcode_rdtlb0_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_rdtlb1_encode_fns[] = {
+ Opcode_rdtlb1_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_wdtlb_encode_fns[] = {
+ Opcode_wdtlb_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_iitlb_encode_fns[] = {
+ Opcode_iitlb_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_pitlb_encode_fns[] = {
+ Opcode_pitlb_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_ritlb0_encode_fns[] = {
+ Opcode_ritlb0_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_ritlb1_encode_fns[] = {
+ Opcode_ritlb1_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_witlb_encode_fns[] = {
+ Opcode_witlb_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_ldpte_encode_fns[] = {
+ Opcode_ldpte_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_hwwitlba_encode_fns[] = {
+ Opcode_hwwitlba_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_hwwdtlba_encode_fns[] = {
+ Opcode_hwwdtlba_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_rsr_cpenable_encode_fns[] = {
+ Opcode_rsr_cpenable_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_wsr_cpenable_encode_fns[] = {
+ Opcode_wsr_cpenable_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_xsr_cpenable_encode_fns[] = {
+ Opcode_xsr_cpenable_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_clamps_encode_fns[] = {
+ Opcode_clamps_Slot_inst_encode, 0, 0, Opcode_clamps_Slot_xt_flix64_slot0_encode, Opcode_clamps_Slot_xt_flix64_slot0_encode, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_min_encode_fns[] = {
+ Opcode_min_Slot_inst_encode, 0, 0, Opcode_min_Slot_xt_flix64_slot0_encode, Opcode_min_Slot_xt_flix64_slot0_encode, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_max_encode_fns[] = {
+ Opcode_max_Slot_inst_encode, 0, 0, Opcode_max_Slot_xt_flix64_slot0_encode, Opcode_max_Slot_xt_flix64_slot0_encode, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_minu_encode_fns[] = {
+ Opcode_minu_Slot_inst_encode, 0, 0, Opcode_minu_Slot_xt_flix64_slot0_encode, Opcode_minu_Slot_xt_flix64_slot0_encode, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_maxu_encode_fns[] = {
+ Opcode_maxu_Slot_inst_encode, 0, 0, Opcode_maxu_Slot_xt_flix64_slot0_encode, Opcode_maxu_Slot_xt_flix64_slot0_encode, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_nsa_encode_fns[] = {
+ Opcode_nsa_Slot_inst_encode, 0, 0, Opcode_nsa_Slot_xt_flix64_slot0_encode, Opcode_nsa_Slot_xt_flix64_slot0_encode, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_nsau_encode_fns[] = {
+ Opcode_nsau_Slot_inst_encode, 0, 0, Opcode_nsau_Slot_xt_flix64_slot0_encode, Opcode_nsau_Slot_xt_flix64_slot0_encode, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_sext_encode_fns[] = {
+ Opcode_sext_Slot_inst_encode, 0, 0, Opcode_sext_Slot_xt_flix64_slot0_encode, Opcode_sext_Slot_xt_flix64_slot0_encode, Opcode_sext_Slot_xt_flix64_slot1_encode, Opcode_sext_Slot_xt_flix64_slot2_encode, 0
+};
+
+xtensa_opcode_encode_fn Opcode_l32ai_encode_fns[] = {
+ Opcode_l32ai_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_s32ri_encode_fns[] = {
+ Opcode_s32ri_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_s32c1i_encode_fns[] = {
+ Opcode_s32c1i_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_rsr_scompare1_encode_fns[] = {
+ Opcode_rsr_scompare1_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_wsr_scompare1_encode_fns[] = {
+ Opcode_wsr_scompare1_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_xsr_scompare1_encode_fns[] = {
+ Opcode_xsr_scompare1_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_quou_encode_fns[] = {
+ Opcode_quou_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_quos_encode_fns[] = {
+ Opcode_quos_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_remu_encode_fns[] = {
+ Opcode_remu_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_rems_encode_fns[] = {
+ Opcode_rems_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_mull_encode_fns[] = {
+ Opcode_mull_Slot_inst_encode, 0, 0, Opcode_mull_Slot_xt_flix64_slot0_encode, Opcode_mull_Slot_xt_flix64_slot0_encode, Opcode_mull_Slot_xt_flix64_slot1_encode, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_muluh_encode_fns[] = {
+ Opcode_muluh_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_mulsh_encode_fns[] = {
+ Opcode_mulsh_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_rur_fcr_encode_fns[] = {
+ Opcode_rur_fcr_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_wur_fcr_encode_fns[] = {
+ Opcode_wur_fcr_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_rur_fsr_encode_fns[] = {
+ Opcode_rur_fsr_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_wur_fsr_encode_fns[] = {
+ Opcode_wur_fsr_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_add_s_encode_fns[] = {
+ Opcode_add_s_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_sub_s_encode_fns[] = {
+ Opcode_sub_s_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_mul_s_encode_fns[] = {
+ Opcode_mul_s_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_madd_s_encode_fns[] = {
+ Opcode_madd_s_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_msub_s_encode_fns[] = {
+ Opcode_msub_s_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_movf_s_encode_fns[] = {
+ Opcode_movf_s_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_movt_s_encode_fns[] = {
+ Opcode_movt_s_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_moveqz_s_encode_fns[] = {
+ Opcode_moveqz_s_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_movnez_s_encode_fns[] = {
+ Opcode_movnez_s_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_movltz_s_encode_fns[] = {
+ Opcode_movltz_s_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_movgez_s_encode_fns[] = {
+ Opcode_movgez_s_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_abs_s_encode_fns[] = {
+ Opcode_abs_s_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_mov_s_encode_fns[] = {
+ Opcode_mov_s_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_neg_s_encode_fns[] = {
+ Opcode_neg_s_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_un_s_encode_fns[] = {
+ Opcode_un_s_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_oeq_s_encode_fns[] = {
+ Opcode_oeq_s_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_ueq_s_encode_fns[] = {
+ Opcode_ueq_s_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_olt_s_encode_fns[] = {
+ Opcode_olt_s_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_ult_s_encode_fns[] = {
+ Opcode_ult_s_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_ole_s_encode_fns[] = {
+ Opcode_ole_s_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_ule_s_encode_fns[] = {
+ Opcode_ule_s_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_float_s_encode_fns[] = {
+ Opcode_float_s_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_ufloat_s_encode_fns[] = {
+ Opcode_ufloat_s_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_round_s_encode_fns[] = {
+ Opcode_round_s_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_ceil_s_encode_fns[] = {
+ Opcode_ceil_s_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_floor_s_encode_fns[] = {
+ Opcode_floor_s_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_trunc_s_encode_fns[] = {
+ Opcode_trunc_s_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_utrunc_s_encode_fns[] = {
+ Opcode_utrunc_s_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_rfr_encode_fns[] = {
+ Opcode_rfr_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_wfr_encode_fns[] = {
+ Opcode_wfr_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_lsi_encode_fns[] = {
+ Opcode_lsi_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_lsiu_encode_fns[] = {
+ Opcode_lsiu_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_lsx_encode_fns[] = {
+ Opcode_lsx_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_lsxu_encode_fns[] = {
+ Opcode_lsxu_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_ssi_encode_fns[] = {
+ Opcode_ssi_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_ssiu_encode_fns[] = {
+ Opcode_ssiu_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_ssx_encode_fns[] = {
+ Opcode_ssx_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_ssxu_encode_fns[] = {
+ Opcode_ssxu_Slot_inst_encode, 0, 0, 0, 0, 0, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_beqz_w18_encode_fns[] = {
+ 0, 0, 0, 0, 0, 0, 0, Opcode_beqz_w18_Slot_xt_flix64_slot3_encode
+};
+
+xtensa_opcode_encode_fn Opcode_bnez_w18_encode_fns[] = {
+ 0, 0, 0, 0, 0, 0, 0, Opcode_bnez_w18_Slot_xt_flix64_slot3_encode
+};
+
+xtensa_opcode_encode_fn Opcode_bgez_w18_encode_fns[] = {
+ 0, 0, 0, 0, 0, 0, 0, Opcode_bgez_w18_Slot_xt_flix64_slot3_encode
+};
+
+xtensa_opcode_encode_fn Opcode_bltz_w18_encode_fns[] = {
+ 0, 0, 0, 0, 0, 0, 0, Opcode_bltz_w18_Slot_xt_flix64_slot3_encode
+};
+
+xtensa_opcode_encode_fn Opcode_beqi_w18_encode_fns[] = {
+ 0, 0, 0, 0, 0, 0, 0, Opcode_beqi_w18_Slot_xt_flix64_slot3_encode
+};
+
+xtensa_opcode_encode_fn Opcode_bnei_w18_encode_fns[] = {
+ 0, 0, 0, 0, 0, 0, 0, Opcode_bnei_w18_Slot_xt_flix64_slot3_encode
+};
+
+xtensa_opcode_encode_fn Opcode_bgei_w18_encode_fns[] = {
+ 0, 0, 0, 0, 0, 0, 0, Opcode_bgei_w18_Slot_xt_flix64_slot3_encode
+};
+
+xtensa_opcode_encode_fn Opcode_blti_w18_encode_fns[] = {
+ 0, 0, 0, 0, 0, 0, 0, Opcode_blti_w18_Slot_xt_flix64_slot3_encode
+};
+
+xtensa_opcode_encode_fn Opcode_bgeui_w18_encode_fns[] = {
+ 0, 0, 0, 0, 0, 0, 0, Opcode_bgeui_w18_Slot_xt_flix64_slot3_encode
+};
+
+xtensa_opcode_encode_fn Opcode_bltui_w18_encode_fns[] = {
+ 0, 0, 0, 0, 0, 0, 0, Opcode_bltui_w18_Slot_xt_flix64_slot3_encode
+};
+
+xtensa_opcode_encode_fn Opcode_bbci_w18_encode_fns[] = {
+ 0, 0, 0, 0, 0, 0, 0, Opcode_bbci_w18_Slot_xt_flix64_slot3_encode
+};
+
+xtensa_opcode_encode_fn Opcode_bbsi_w18_encode_fns[] = {
+ 0, 0, 0, 0, 0, 0, 0, Opcode_bbsi_w18_Slot_xt_flix64_slot3_encode
+};
+
+xtensa_opcode_encode_fn Opcode_beq_w18_encode_fns[] = {
+ 0, 0, 0, 0, 0, 0, 0, Opcode_beq_w18_Slot_xt_flix64_slot3_encode
+};
+
+xtensa_opcode_encode_fn Opcode_bne_w18_encode_fns[] = {
+ 0, 0, 0, 0, 0, 0, 0, Opcode_bne_w18_Slot_xt_flix64_slot3_encode
+};
+
+xtensa_opcode_encode_fn Opcode_bge_w18_encode_fns[] = {
+ 0, 0, 0, 0, 0, 0, 0, Opcode_bge_w18_Slot_xt_flix64_slot3_encode
+};
+
+xtensa_opcode_encode_fn Opcode_blt_w18_encode_fns[] = {
+ 0, 0, 0, 0, 0, 0, 0, Opcode_blt_w18_Slot_xt_flix64_slot3_encode
+};
+
+xtensa_opcode_encode_fn Opcode_bgeu_w18_encode_fns[] = {
+ 0, 0, 0, 0, 0, 0, 0, Opcode_bgeu_w18_Slot_xt_flix64_slot3_encode
+};
+
+xtensa_opcode_encode_fn Opcode_bltu_w18_encode_fns[] = {
+ 0, 0, 0, 0, 0, 0, 0, Opcode_bltu_w18_Slot_xt_flix64_slot3_encode
+};
+
+xtensa_opcode_encode_fn Opcode_bany_w18_encode_fns[] = {
+ 0, 0, 0, 0, 0, 0, 0, Opcode_bany_w18_Slot_xt_flix64_slot3_encode
+};
+
+xtensa_opcode_encode_fn Opcode_bnone_w18_encode_fns[] = {
+ 0, 0, 0, 0, 0, 0, 0, Opcode_bnone_w18_Slot_xt_flix64_slot3_encode
+};
+
+xtensa_opcode_encode_fn Opcode_ball_w18_encode_fns[] = {
+ 0, 0, 0, 0, 0, 0, 0, Opcode_ball_w18_Slot_xt_flix64_slot3_encode
+};
+
+xtensa_opcode_encode_fn Opcode_bnall_w18_encode_fns[] = {
+ 0, 0, 0, 0, 0, 0, 0, Opcode_bnall_w18_Slot_xt_flix64_slot3_encode
+};
+
+xtensa_opcode_encode_fn Opcode_bbc_w18_encode_fns[] = {
+ 0, 0, 0, 0, 0, 0, 0, Opcode_bbc_w18_Slot_xt_flix64_slot3_encode
+};
+
+xtensa_opcode_encode_fn Opcode_bbs_w18_encode_fns[] = {
+ 0, 0, 0, 0, 0, 0, 0, Opcode_bbs_w18_Slot_xt_flix64_slot3_encode
+};
+
+
+/* Opcode table. */
+
+static xtensa_opcode_internal opcodes[] = {
+ { "excw", 0 /* xt_iclass_excw */,
+ 0,
+ Opcode_excw_encode_fns, 0, 0 },
+ { "rfe", 1 /* xt_iclass_rfe */,
+ XTENSA_OPCODE_IS_JUMP,
+ Opcode_rfe_encode_fns, 0, 0 },
+ { "rfde", 2 /* xt_iclass_rfde */,
+ XTENSA_OPCODE_IS_JUMP,
+ Opcode_rfde_encode_fns, 0, 0 },
+ { "syscall", 3 /* xt_iclass_syscall */,
+ 0,
+ Opcode_syscall_encode_fns, 0, 0 },
+ { "simcall", 4 /* xt_iclass_simcall */,
+ 0,
+ Opcode_simcall_encode_fns, 0, 0 },
+ { "call12", 5 /* xt_iclass_call12 */,
+ XTENSA_OPCODE_IS_CALL,
+ Opcode_call12_encode_fns, 0, 0 },
+ { "call8", 6 /* xt_iclass_call8 */,
+ XTENSA_OPCODE_IS_CALL,
+ Opcode_call8_encode_fns, 0, 0 },
+ { "call4", 7 /* xt_iclass_call4 */,
+ XTENSA_OPCODE_IS_CALL,
+ Opcode_call4_encode_fns, 0, 0 },
+ { "callx12", 8 /* xt_iclass_callx12 */,
+ XTENSA_OPCODE_IS_CALL,
+ Opcode_callx12_encode_fns, 0, 0 },
+ { "callx8", 9 /* xt_iclass_callx8 */,
+ XTENSA_OPCODE_IS_CALL,
+ Opcode_callx8_encode_fns, 0, 0 },
+ { "callx4", 10 /* xt_iclass_callx4 */,
+ XTENSA_OPCODE_IS_CALL,
+ Opcode_callx4_encode_fns, 0, 0 },
+ { "entry", 11 /* xt_iclass_entry */,
+ 0,
+ Opcode_entry_encode_fns, 0, 0 },
+ { "movsp", 12 /* xt_iclass_movsp */,
+ 0,
+ Opcode_movsp_encode_fns, 0, 0 },
+ { "rotw", 13 /* xt_iclass_rotw */,
+ 0,
+ Opcode_rotw_encode_fns, 0, 0 },
+ { "retw", 14 /* xt_iclass_retw */,
+ XTENSA_OPCODE_IS_JUMP,
+ Opcode_retw_encode_fns, 0, 0 },
+ { "retw.n", 14 /* xt_iclass_retw */,
+ XTENSA_OPCODE_IS_JUMP,
+ Opcode_retw_n_encode_fns, 0, 0 },
+ { "rfwo", 15 /* xt_iclass_rfwou */,
+ XTENSA_OPCODE_IS_JUMP,
+ Opcode_rfwo_encode_fns, 0, 0 },
+ { "rfwu", 15 /* xt_iclass_rfwou */,
+ XTENSA_OPCODE_IS_JUMP,
+ Opcode_rfwu_encode_fns, 0, 0 },
+ { "l32e", 16 /* xt_iclass_l32e */,
+ 0,
+ Opcode_l32e_encode_fns, 0, 0 },
+ { "s32e", 17 /* xt_iclass_s32e */,
+ 0,
+ Opcode_s32e_encode_fns, 0, 0 },
+ { "rsr.windowbase", 18 /* xt_iclass_rsr.windowbase */,
+ 0,
+ Opcode_rsr_windowbase_encode_fns, 0, 0 },
+ { "wsr.windowbase", 19 /* xt_iclass_wsr.windowbase */,
+ 0,
+ Opcode_wsr_windowbase_encode_fns, 0, 0 },
+ { "xsr.windowbase", 20 /* xt_iclass_xsr.windowbase */,
+ 0,
+ Opcode_xsr_windowbase_encode_fns, 0, 0 },
+ { "rsr.windowstart", 21 /* xt_iclass_rsr.windowstart */,
+ 0,
+ Opcode_rsr_windowstart_encode_fns, 0, 0 },
+ { "wsr.windowstart", 22 /* xt_iclass_wsr.windowstart */,
+ 0,
+ Opcode_wsr_windowstart_encode_fns, 0, 0 },
+ { "xsr.windowstart", 23 /* xt_iclass_xsr.windowstart */,
+ 0,
+ Opcode_xsr_windowstart_encode_fns, 0, 0 },
+ { "add.n", 24 /* xt_iclass_add.n */,
+ 0,
+ Opcode_add_n_encode_fns, 0, 0 },
+ { "addi.n", 25 /* xt_iclass_addi.n */,
+ 0,
+ Opcode_addi_n_encode_fns, 0, 0 },
+ { "beqz.n", 26 /* xt_iclass_bz6 */,
+ XTENSA_OPCODE_IS_BRANCH,
+ Opcode_beqz_n_encode_fns, 0, 0 },
+ { "bnez.n", 26 /* xt_iclass_bz6 */,
+ XTENSA_OPCODE_IS_BRANCH,
+ Opcode_bnez_n_encode_fns, 0, 0 },
+ { "ill.n", 27 /* xt_iclass_ill.n */,
+ 0,
+ Opcode_ill_n_encode_fns, 0, 0 },
+ { "l32i.n", 28 /* xt_iclass_loadi4 */,
+ 0,
+ Opcode_l32i_n_encode_fns, 0, 0 },
+ { "mov.n", 29 /* xt_iclass_mov.n */,
+ 0,
+ Opcode_mov_n_encode_fns, 0, 0 },
+ { "movi.n", 30 /* xt_iclass_movi.n */,
+ 0,
+ Opcode_movi_n_encode_fns, 0, 0 },
+ { "nop.n", 31 /* xt_iclass_nopn */,
+ 0,
+ Opcode_nop_n_encode_fns, 0, 0 },
+ { "ret.n", 32 /* xt_iclass_retn */,
+ XTENSA_OPCODE_IS_JUMP,
+ Opcode_ret_n_encode_fns, 0, 0 },
+ { "s32i.n", 33 /* xt_iclass_storei4 */,
+ 0,
+ Opcode_s32i_n_encode_fns, 0, 0 },
+ { "rur.threadptr", 34 /* rur_threadptr */,
+ 0,
+ Opcode_rur_threadptr_encode_fns, 0, 0 },
+ { "wur.threadptr", 35 /* wur_threadptr */,
+ 0,
+ Opcode_wur_threadptr_encode_fns, 0, 0 },
+ { "addi", 36 /* xt_iclass_addi */,
+ 0,
+ Opcode_addi_encode_fns, 0, 0 },
+ { "addmi", 37 /* xt_iclass_addmi */,
+ 0,
+ Opcode_addmi_encode_fns, 0, 0 },
+ { "add", 38 /* xt_iclass_addsub */,
+ 0,
+ Opcode_add_encode_fns, 0, 0 },
+ { "sub", 38 /* xt_iclass_addsub */,
+ 0,
+ Opcode_sub_encode_fns, 0, 0 },
+ { "addx2", 38 /* xt_iclass_addsub */,
+ 0,
+ Opcode_addx2_encode_fns, 0, 0 },
+ { "addx4", 38 /* xt_iclass_addsub */,
+ 0,
+ Opcode_addx4_encode_fns, 0, 0 },
+ { "addx8", 38 /* xt_iclass_addsub */,
+ 0,
+ Opcode_addx8_encode_fns, 0, 0 },
+ { "subx2", 38 /* xt_iclass_addsub */,
+ 0,
+ Opcode_subx2_encode_fns, 0, 0 },
+ { "subx4", 38 /* xt_iclass_addsub */,
+ 0,
+ Opcode_subx4_encode_fns, 0, 0 },
+ { "subx8", 38 /* xt_iclass_addsub */,
+ 0,
+ Opcode_subx8_encode_fns, 0, 0 },
+ { "and", 39 /* xt_iclass_bit */,
+ 0,
+ Opcode_and_encode_fns, 0, 0 },
+ { "or", 39 /* xt_iclass_bit */,
+ 0,
+ Opcode_or_encode_fns, 0, 0 },
+ { "xor", 39 /* xt_iclass_bit */,
+ 0,
+ Opcode_xor_encode_fns, 0, 0 },
+ { "beqi", 40 /* xt_iclass_bsi8 */,
+ XTENSA_OPCODE_IS_BRANCH,
+ Opcode_beqi_encode_fns, 0, 0 },
+ { "bnei", 40 /* xt_iclass_bsi8 */,
+ XTENSA_OPCODE_IS_BRANCH,
+ Opcode_bnei_encode_fns, 0, 0 },
+ { "bgei", 40 /* xt_iclass_bsi8 */,
+ XTENSA_OPCODE_IS_BRANCH,
+ Opcode_bgei_encode_fns, 0, 0 },
+ { "blti", 40 /* xt_iclass_bsi8 */,
+ XTENSA_OPCODE_IS_BRANCH,
+ Opcode_blti_encode_fns, 0, 0 },
+ { "bbci", 41 /* xt_iclass_bsi8b */,
+ XTENSA_OPCODE_IS_BRANCH,
+ Opcode_bbci_encode_fns, 0, 0 },
+ { "bbsi", 41 /* xt_iclass_bsi8b */,
+ XTENSA_OPCODE_IS_BRANCH,
+ Opcode_bbsi_encode_fns, 0, 0 },
+ { "bgeui", 42 /* xt_iclass_bsi8u */,
+ XTENSA_OPCODE_IS_BRANCH,
+ Opcode_bgeui_encode_fns, 0, 0 },
+ { "bltui", 42 /* xt_iclass_bsi8u */,
+ XTENSA_OPCODE_IS_BRANCH,
+ Opcode_bltui_encode_fns, 0, 0 },
+ { "beq", 43 /* xt_iclass_bst8 */,
+ XTENSA_OPCODE_IS_BRANCH,
+ Opcode_beq_encode_fns, 0, 0 },
+ { "bne", 43 /* xt_iclass_bst8 */,
+ XTENSA_OPCODE_IS_BRANCH,
+ Opcode_bne_encode_fns, 0, 0 },
+ { "bge", 43 /* xt_iclass_bst8 */,
+ XTENSA_OPCODE_IS_BRANCH,
+ Opcode_bge_encode_fns, 0, 0 },
+ { "blt", 43 /* xt_iclass_bst8 */,
+ XTENSA_OPCODE_IS_BRANCH,
+ Opcode_blt_encode_fns, 0, 0 },
+ { "bgeu", 43 /* xt_iclass_bst8 */,
+ XTENSA_OPCODE_IS_BRANCH,
+ Opcode_bgeu_encode_fns, 0, 0 },
+ { "bltu", 43 /* xt_iclass_bst8 */,
+ XTENSA_OPCODE_IS_BRANCH,
+ Opcode_bltu_encode_fns, 0, 0 },
+ { "bany", 43 /* xt_iclass_bst8 */,
+ XTENSA_OPCODE_IS_BRANCH,
+ Opcode_bany_encode_fns, 0, 0 },
+ { "bnone", 43 /* xt_iclass_bst8 */,
+ XTENSA_OPCODE_IS_BRANCH,
+ Opcode_bnone_encode_fns, 0, 0 },
+ { "ball", 43 /* xt_iclass_bst8 */,
+ XTENSA_OPCODE_IS_BRANCH,
+ Opcode_ball_encode_fns, 0, 0 },
+ { "bnall", 43 /* xt_iclass_bst8 */,
+ XTENSA_OPCODE_IS_BRANCH,
+ Opcode_bnall_encode_fns, 0, 0 },
+ { "bbc", 43 /* xt_iclass_bst8 */,
+ XTENSA_OPCODE_IS_BRANCH,
+ Opcode_bbc_encode_fns, 0, 0 },
+ { "bbs", 43 /* xt_iclass_bst8 */,
+ XTENSA_OPCODE_IS_BRANCH,
+ Opcode_bbs_encode_fns, 0, 0 },
+ { "beqz", 44 /* xt_iclass_bsz12 */,
+ XTENSA_OPCODE_IS_BRANCH,
+ Opcode_beqz_encode_fns, 0, 0 },
+ { "bnez", 44 /* xt_iclass_bsz12 */,
+ XTENSA_OPCODE_IS_BRANCH,
+ Opcode_bnez_encode_fns, 0, 0 },
+ { "bgez", 44 /* xt_iclass_bsz12 */,
+ XTENSA_OPCODE_IS_BRANCH,
+ Opcode_bgez_encode_fns, 0, 0 },
+ { "bltz", 44 /* xt_iclass_bsz12 */,
+ XTENSA_OPCODE_IS_BRANCH,
+ Opcode_bltz_encode_fns, 0, 0 },
+ { "call0", 45 /* xt_iclass_call0 */,
+ XTENSA_OPCODE_IS_CALL,
+ Opcode_call0_encode_fns, 0, 0 },
+ { "callx0", 46 /* xt_iclass_callx0 */,
+ XTENSA_OPCODE_IS_CALL,
+ Opcode_callx0_encode_fns, 0, 0 },
+ { "extui", 47 /* xt_iclass_exti */,
+ 0,
+ Opcode_extui_encode_fns, 0, 0 },
+ { "ill", 48 /* xt_iclass_ill */,
+ 0,
+ Opcode_ill_encode_fns, 0, 0 },
+ { "j", 49 /* xt_iclass_jump */,
+ XTENSA_OPCODE_IS_JUMP,
+ Opcode_j_encode_fns, 0, 0 },
+ { "jx", 50 /* xt_iclass_jumpx */,
+ XTENSA_OPCODE_IS_JUMP,
+ Opcode_jx_encode_fns, 0, 0 },
+ { "l16ui", 51 /* xt_iclass_l16ui */,
+ 0,
+ Opcode_l16ui_encode_fns, 0, 0 },
+ { "l16si", 52 /* xt_iclass_l16si */,
+ 0,
+ Opcode_l16si_encode_fns, 0, 0 },
+ { "l32i", 53 /* xt_iclass_l32i */,
+ 0,
+ Opcode_l32i_encode_fns, 0, 0 },
+ { "l32r", 54 /* xt_iclass_l32r */,
+ 0,
+ Opcode_l32r_encode_fns, 0, 0 },
+ { "l8ui", 55 /* xt_iclass_l8i */,
+ 0,
+ Opcode_l8ui_encode_fns, 0, 0 },
+ { "loop", 56 /* xt_iclass_loop */,
+ XTENSA_OPCODE_IS_LOOP,
+ Opcode_loop_encode_fns, 0, 0 },
+ { "loopnez", 57 /* xt_iclass_loopz */,
+ XTENSA_OPCODE_IS_LOOP,
+ Opcode_loopnez_encode_fns, 0, 0 },
+ { "loopgtz", 57 /* xt_iclass_loopz */,
+ XTENSA_OPCODE_IS_LOOP,
+ Opcode_loopgtz_encode_fns, 0, 0 },
+ { "movi", 58 /* xt_iclass_movi */,
+ 0,
+ Opcode_movi_encode_fns, 0, 0 },
+ { "moveqz", 59 /* xt_iclass_movz */,
+ 0,
+ Opcode_moveqz_encode_fns, 0, 0 },
+ { "movnez", 59 /* xt_iclass_movz */,
+ 0,
+ Opcode_movnez_encode_fns, 0, 0 },
+ { "movltz", 59 /* xt_iclass_movz */,
+ 0,
+ Opcode_movltz_encode_fns, 0, 0 },
+ { "movgez", 59 /* xt_iclass_movz */,
+ 0,
+ Opcode_movgez_encode_fns, 0, 0 },
+ { "neg", 60 /* xt_iclass_neg */,
+ 0,
+ Opcode_neg_encode_fns, 0, 0 },
+ { "abs", 60 /* xt_iclass_neg */,
+ 0,
+ Opcode_abs_encode_fns, 0, 0 },
+ { "nop", 61 /* xt_iclass_nop */,
+ 0,
+ Opcode_nop_encode_fns, 0, 0 },
+ { "ret", 62 /* xt_iclass_return */,
+ XTENSA_OPCODE_IS_JUMP,
+ Opcode_ret_encode_fns, 0, 0 },
+ { "s16i", 63 /* xt_iclass_s16i */,
+ 0,
+ Opcode_s16i_encode_fns, 0, 0 },
+ { "s32i", 64 /* xt_iclass_s32i */,
+ 0,
+ Opcode_s32i_encode_fns, 0, 0 },
+ { "s8i", 65 /* xt_iclass_s8i */,
+ 0,
+ Opcode_s8i_encode_fns, 0, 0 },
+ { "ssr", 66 /* xt_iclass_sar */,
+ 0,
+ Opcode_ssr_encode_fns, 0, 0 },
+ { "ssl", 66 /* xt_iclass_sar */,
+ 0,
+ Opcode_ssl_encode_fns, 0, 0 },
+ { "ssa8l", 66 /* xt_iclass_sar */,
+ 0,
+ Opcode_ssa8l_encode_fns, 0, 0 },
+ { "ssa8b", 66 /* xt_iclass_sar */,
+ 0,
+ Opcode_ssa8b_encode_fns, 0, 0 },
+ { "ssai", 67 /* xt_iclass_sari */,
+ 0,
+ Opcode_ssai_encode_fns, 0, 0 },
+ { "sll", 68 /* xt_iclass_shifts */,
+ 0,
+ Opcode_sll_encode_fns, 0, 0 },
+ { "src", 69 /* xt_iclass_shiftst */,
+ 0,
+ Opcode_src_encode_fns, 0, 0 },
+ { "srl", 70 /* xt_iclass_shiftt */,
+ 0,
+ Opcode_srl_encode_fns, 0, 0 },
+ { "sra", 70 /* xt_iclass_shiftt */,
+ 0,
+ Opcode_sra_encode_fns, 0, 0 },
+ { "slli", 71 /* xt_iclass_slli */,
+ 0,
+ Opcode_slli_encode_fns, 0, 0 },
+ { "srai", 72 /* xt_iclass_srai */,
+ 0,
+ Opcode_srai_encode_fns, 0, 0 },
+ { "srli", 73 /* xt_iclass_srli */,
+ 0,
+ Opcode_srli_encode_fns, 0, 0 },
+ { "memw", 74 /* xt_iclass_memw */,
+ 0,
+ Opcode_memw_encode_fns, 0, 0 },
+ { "extw", 75 /* xt_iclass_extw */,
+ 0,
+ Opcode_extw_encode_fns, 0, 0 },
+ { "isync", 76 /* xt_iclass_isync */,
+ 0,
+ Opcode_isync_encode_fns, 0, 0 },
+ { "rsync", 77 /* xt_iclass_sync */,
+ 0,
+ Opcode_rsync_encode_fns, 0, 0 },
+ { "esync", 77 /* xt_iclass_sync */,
+ 0,
+ Opcode_esync_encode_fns, 0, 0 },
+ { "dsync", 77 /* xt_iclass_sync */,
+ 0,
+ Opcode_dsync_encode_fns, 0, 0 },
+ { "rsil", 78 /* xt_iclass_rsil */,
+ 0,
+ Opcode_rsil_encode_fns, 0, 0 },
+ { "rsr.lend", 79 /* xt_iclass_rsr.lend */,
+ 0,
+ Opcode_rsr_lend_encode_fns, 0, 0 },
+ { "wsr.lend", 80 /* xt_iclass_wsr.lend */,
+ 0,
+ Opcode_wsr_lend_encode_fns, 0, 0 },
+ { "xsr.lend", 81 /* xt_iclass_xsr.lend */,
+ 0,
+ Opcode_xsr_lend_encode_fns, 0, 0 },
+ { "rsr.lcount", 82 /* xt_iclass_rsr.lcount */,
+ 0,
+ Opcode_rsr_lcount_encode_fns, 0, 0 },
+ { "wsr.lcount", 83 /* xt_iclass_wsr.lcount */,
+ 0,
+ Opcode_wsr_lcount_encode_fns, 0, 0 },
+ { "xsr.lcount", 84 /* xt_iclass_xsr.lcount */,
+ 0,
+ Opcode_xsr_lcount_encode_fns, 0, 0 },
+ { "rsr.lbeg", 85 /* xt_iclass_rsr.lbeg */,
+ 0,
+ Opcode_rsr_lbeg_encode_fns, 0, 0 },
+ { "wsr.lbeg", 86 /* xt_iclass_wsr.lbeg */,
+ 0,
+ Opcode_wsr_lbeg_encode_fns, 0, 0 },
+ { "xsr.lbeg", 87 /* xt_iclass_xsr.lbeg */,
+ 0,
+ Opcode_xsr_lbeg_encode_fns, 0, 0 },
+ { "rsr.sar", 88 /* xt_iclass_rsr.sar */,
+ 0,
+ Opcode_rsr_sar_encode_fns, 0, 0 },
+ { "wsr.sar", 89 /* xt_iclass_wsr.sar */,
+ 0,
+ Opcode_wsr_sar_encode_fns, 0, 0 },
+ { "xsr.sar", 90 /* xt_iclass_xsr.sar */,
+ 0,
+ Opcode_xsr_sar_encode_fns, 0, 0 },
+ { "rsr.litbase", 91 /* xt_iclass_rsr.litbase */,
+ 0,
+ Opcode_rsr_litbase_encode_fns, 0, 0 },
+ { "wsr.litbase", 92 /* xt_iclass_wsr.litbase */,
+ 0,
+ Opcode_wsr_litbase_encode_fns, 0, 0 },
+ { "xsr.litbase", 93 /* xt_iclass_xsr.litbase */,
+ 0,
+ Opcode_xsr_litbase_encode_fns, 0, 0 },
+ { "rsr.176", 94 /* xt_iclass_rsr.176 */,
+ 0,
+ Opcode_rsr_176_encode_fns, 0, 0 },
+ { "rsr.208", 95 /* xt_iclass_rsr.208 */,
+ 0,
+ Opcode_rsr_208_encode_fns, 0, 0 },
+ { "rsr.ps", 96 /* xt_iclass_rsr.ps */,
+ 0,
+ Opcode_rsr_ps_encode_fns, 0, 0 },
+ { "wsr.ps", 97 /* xt_iclass_wsr.ps */,
+ 0,
+ Opcode_wsr_ps_encode_fns, 0, 0 },
+ { "xsr.ps", 98 /* xt_iclass_xsr.ps */,
+ 0,
+ Opcode_xsr_ps_encode_fns, 0, 0 },
+ { "rsr.epc1", 99 /* xt_iclass_rsr.epc1 */,
+ 0,
+ Opcode_rsr_epc1_encode_fns, 0, 0 },
+ { "wsr.epc1", 100 /* xt_iclass_wsr.epc1 */,
+ 0,
+ Opcode_wsr_epc1_encode_fns, 0, 0 },
+ { "xsr.epc1", 101 /* xt_iclass_xsr.epc1 */,
+ 0,
+ Opcode_xsr_epc1_encode_fns, 0, 0 },
+ { "rsr.excsave1", 102 /* xt_iclass_rsr.excsave1 */,
+ 0,
+ Opcode_rsr_excsave1_encode_fns, 0, 0 },
+ { "wsr.excsave1", 103 /* xt_iclass_wsr.excsave1 */,
+ 0,
+ Opcode_wsr_excsave1_encode_fns, 0, 0 },
+ { "xsr.excsave1", 104 /* xt_iclass_xsr.excsave1 */,
+ 0,
+ Opcode_xsr_excsave1_encode_fns, 0, 0 },
+ { "rsr.epc2", 105 /* xt_iclass_rsr.epc2 */,
+ 0,
+ Opcode_rsr_epc2_encode_fns, 0, 0 },
+ { "wsr.epc2", 106 /* xt_iclass_wsr.epc2 */,
+ 0,
+ Opcode_wsr_epc2_encode_fns, 0, 0 },
+ { "xsr.epc2", 107 /* xt_iclass_xsr.epc2 */,
+ 0,
+ Opcode_xsr_epc2_encode_fns, 0, 0 },
+ { "rsr.excsave2", 108 /* xt_iclass_rsr.excsave2 */,
+ 0,
+ Opcode_rsr_excsave2_encode_fns, 0, 0 },
+ { "wsr.excsave2", 109 /* xt_iclass_wsr.excsave2 */,
+ 0,
+ Opcode_wsr_excsave2_encode_fns, 0, 0 },
+ { "xsr.excsave2", 110 /* xt_iclass_xsr.excsave2 */,
+ 0,
+ Opcode_xsr_excsave2_encode_fns, 0, 0 },
+ { "rsr.epc3", 111 /* xt_iclass_rsr.epc3 */,
+ 0,
+ Opcode_rsr_epc3_encode_fns, 0, 0 },
+ { "wsr.epc3", 112 /* xt_iclass_wsr.epc3 */,
+ 0,
+ Opcode_wsr_epc3_encode_fns, 0, 0 },
+ { "xsr.epc3", 113 /* xt_iclass_xsr.epc3 */,
+ 0,
+ Opcode_xsr_epc3_encode_fns, 0, 0 },
+ { "rsr.excsave3", 114 /* xt_iclass_rsr.excsave3 */,
+ 0,
+ Opcode_rsr_excsave3_encode_fns, 0, 0 },
+ { "wsr.excsave3", 115 /* xt_iclass_wsr.excsave3 */,
+ 0,
+ Opcode_wsr_excsave3_encode_fns, 0, 0 },
+ { "xsr.excsave3", 116 /* xt_iclass_xsr.excsave3 */,
+ 0,
+ Opcode_xsr_excsave3_encode_fns, 0, 0 },
+ { "rsr.epc4", 117 /* xt_iclass_rsr.epc4 */,
+ 0,
+ Opcode_rsr_epc4_encode_fns, 0, 0 },
+ { "wsr.epc4", 118 /* xt_iclass_wsr.epc4 */,
+ 0,
+ Opcode_wsr_epc4_encode_fns, 0, 0 },
+ { "xsr.epc4", 119 /* xt_iclass_xsr.epc4 */,
+ 0,
+ Opcode_xsr_epc4_encode_fns, 0, 0 },
+ { "rsr.excsave4", 120 /* xt_iclass_rsr.excsave4 */,
+ 0,
+ Opcode_rsr_excsave4_encode_fns, 0, 0 },
+ { "wsr.excsave4", 121 /* xt_iclass_wsr.excsave4 */,
+ 0,
+ Opcode_wsr_excsave4_encode_fns, 0, 0 },
+ { "xsr.excsave4", 122 /* xt_iclass_xsr.excsave4 */,
+ 0,
+ Opcode_xsr_excsave4_encode_fns, 0, 0 },
+ { "rsr.epc5", 123 /* xt_iclass_rsr.epc5 */,
+ 0,
+ Opcode_rsr_epc5_encode_fns, 0, 0 },
+ { "wsr.epc5", 124 /* xt_iclass_wsr.epc5 */,
+ 0,
+ Opcode_wsr_epc5_encode_fns, 0, 0 },
+ { "xsr.epc5", 125 /* xt_iclass_xsr.epc5 */,
+ 0,
+ Opcode_xsr_epc5_encode_fns, 0, 0 },
+ { "rsr.excsave5", 126 /* xt_iclass_rsr.excsave5 */,
+ 0,
+ Opcode_rsr_excsave5_encode_fns, 0, 0 },
+ { "wsr.excsave5", 127 /* xt_iclass_wsr.excsave5 */,
+ 0,
+ Opcode_wsr_excsave5_encode_fns, 0, 0 },
+ { "xsr.excsave5", 128 /* xt_iclass_xsr.excsave5 */,
+ 0,
+ Opcode_xsr_excsave5_encode_fns, 0, 0 },
+ { "rsr.epc6", 129 /* xt_iclass_rsr.epc6 */,
+ 0,
+ Opcode_rsr_epc6_encode_fns, 0, 0 },
+ { "wsr.epc6", 130 /* xt_iclass_wsr.epc6 */,
+ 0,
+ Opcode_wsr_epc6_encode_fns, 0, 0 },
+ { "xsr.epc6", 131 /* xt_iclass_xsr.epc6 */,
+ 0,
+ Opcode_xsr_epc6_encode_fns, 0, 0 },
+ { "rsr.excsave6", 132 /* xt_iclass_rsr.excsave6 */,
+ 0,
+ Opcode_rsr_excsave6_encode_fns, 0, 0 },
+ { "wsr.excsave6", 133 /* xt_iclass_wsr.excsave6 */,
+ 0,
+ Opcode_wsr_excsave6_encode_fns, 0, 0 },
+ { "xsr.excsave6", 134 /* xt_iclass_xsr.excsave6 */,
+ 0,
+ Opcode_xsr_excsave6_encode_fns, 0, 0 },
+ { "rsr.epc7", 135 /* xt_iclass_rsr.epc7 */,
+ 0,
+ Opcode_rsr_epc7_encode_fns, 0, 0 },
+ { "wsr.epc7", 136 /* xt_iclass_wsr.epc7 */,
+ 0,
+ Opcode_wsr_epc7_encode_fns, 0, 0 },
+ { "xsr.epc7", 137 /* xt_iclass_xsr.epc7 */,
+ 0,
+ Opcode_xsr_epc7_encode_fns, 0, 0 },
+ { "rsr.excsave7", 138 /* xt_iclass_rsr.excsave7 */,
+ 0,
+ Opcode_rsr_excsave7_encode_fns, 0, 0 },
+ { "wsr.excsave7", 139 /* xt_iclass_wsr.excsave7 */,
+ 0,
+ Opcode_wsr_excsave7_encode_fns, 0, 0 },
+ { "xsr.excsave7", 140 /* xt_iclass_xsr.excsave7 */,
+ 0,
+ Opcode_xsr_excsave7_encode_fns, 0, 0 },
+ { "rsr.eps2", 141 /* xt_iclass_rsr.eps2 */,
+ 0,
+ Opcode_rsr_eps2_encode_fns, 0, 0 },
+ { "wsr.eps2", 142 /* xt_iclass_wsr.eps2 */,
+ 0,
+ Opcode_wsr_eps2_encode_fns, 0, 0 },
+ { "xsr.eps2", 143 /* xt_iclass_xsr.eps2 */,
+ 0,
+ Opcode_xsr_eps2_encode_fns, 0, 0 },
+ { "rsr.eps3", 144 /* xt_iclass_rsr.eps3 */,
+ 0,
+ Opcode_rsr_eps3_encode_fns, 0, 0 },
+ { "wsr.eps3", 145 /* xt_iclass_wsr.eps3 */,
+ 0,
+ Opcode_wsr_eps3_encode_fns, 0, 0 },
+ { "xsr.eps3", 146 /* xt_iclass_xsr.eps3 */,
+ 0,
+ Opcode_xsr_eps3_encode_fns, 0, 0 },
+ { "rsr.eps4", 147 /* xt_iclass_rsr.eps4 */,
+ 0,
+ Opcode_rsr_eps4_encode_fns, 0, 0 },
+ { "wsr.eps4", 148 /* xt_iclass_wsr.eps4 */,
+ 0,
+ Opcode_wsr_eps4_encode_fns, 0, 0 },
+ { "xsr.eps4", 149 /* xt_iclass_xsr.eps4 */,
+ 0,
+ Opcode_xsr_eps4_encode_fns, 0, 0 },
+ { "rsr.eps5", 150 /* xt_iclass_rsr.eps5 */,
+ 0,
+ Opcode_rsr_eps5_encode_fns, 0, 0 },
+ { "wsr.eps5", 151 /* xt_iclass_wsr.eps5 */,
+ 0,
+ Opcode_wsr_eps5_encode_fns, 0, 0 },
+ { "xsr.eps5", 152 /* xt_iclass_xsr.eps5 */,
+ 0,
+ Opcode_xsr_eps5_encode_fns, 0, 0 },
+ { "rsr.eps6", 153 /* xt_iclass_rsr.eps6 */,
+ 0,
+ Opcode_rsr_eps6_encode_fns, 0, 0 },
+ { "wsr.eps6", 154 /* xt_iclass_wsr.eps6 */,
+ 0,
+ Opcode_wsr_eps6_encode_fns, 0, 0 },
+ { "xsr.eps6", 155 /* xt_iclass_xsr.eps6 */,
+ 0,
+ Opcode_xsr_eps6_encode_fns, 0, 0 },
+ { "rsr.eps7", 156 /* xt_iclass_rsr.eps7 */,
+ 0,
+ Opcode_rsr_eps7_encode_fns, 0, 0 },
+ { "wsr.eps7", 157 /* xt_iclass_wsr.eps7 */,
+ 0,
+ Opcode_wsr_eps7_encode_fns, 0, 0 },
+ { "xsr.eps7", 158 /* xt_iclass_xsr.eps7 */,
+ 0,
+ Opcode_xsr_eps7_encode_fns, 0, 0 },
+ { "rsr.excvaddr", 159 /* xt_iclass_rsr.excvaddr */,
+ 0,
+ Opcode_rsr_excvaddr_encode_fns, 0, 0 },
+ { "wsr.excvaddr", 160 /* xt_iclass_wsr.excvaddr */,
+ 0,
+ Opcode_wsr_excvaddr_encode_fns, 0, 0 },
+ { "xsr.excvaddr", 161 /* xt_iclass_xsr.excvaddr */,
+ 0,
+ Opcode_xsr_excvaddr_encode_fns, 0, 0 },
+ { "rsr.depc", 162 /* xt_iclass_rsr.depc */,
+ 0,
+ Opcode_rsr_depc_encode_fns, 0, 0 },
+ { "wsr.depc", 163 /* xt_iclass_wsr.depc */,
+ 0,
+ Opcode_wsr_depc_encode_fns, 0, 0 },
+ { "xsr.depc", 164 /* xt_iclass_xsr.depc */,
+ 0,
+ Opcode_xsr_depc_encode_fns, 0, 0 },
+ { "rsr.exccause", 165 /* xt_iclass_rsr.exccause */,
+ 0,
+ Opcode_rsr_exccause_encode_fns, 0, 0 },
+ { "wsr.exccause", 166 /* xt_iclass_wsr.exccause */,
+ 0,
+ Opcode_wsr_exccause_encode_fns, 0, 0 },
+ { "xsr.exccause", 167 /* xt_iclass_xsr.exccause */,
+ 0,
+ Opcode_xsr_exccause_encode_fns, 0, 0 },
+ { "rsr.misc0", 168 /* xt_iclass_rsr.misc0 */,
+ 0,
+ Opcode_rsr_misc0_encode_fns, 0, 0 },
+ { "wsr.misc0", 169 /* xt_iclass_wsr.misc0 */,
+ 0,
+ Opcode_wsr_misc0_encode_fns, 0, 0 },
+ { "xsr.misc0", 170 /* xt_iclass_xsr.misc0 */,
+ 0,
+ Opcode_xsr_misc0_encode_fns, 0, 0 },
+ { "rsr.misc1", 171 /* xt_iclass_rsr.misc1 */,
+ 0,
+ Opcode_rsr_misc1_encode_fns, 0, 0 },
+ { "wsr.misc1", 172 /* xt_iclass_wsr.misc1 */,
+ 0,
+ Opcode_wsr_misc1_encode_fns, 0, 0 },
+ { "xsr.misc1", 173 /* xt_iclass_xsr.misc1 */,
+ 0,
+ Opcode_xsr_misc1_encode_fns, 0, 0 },
+ { "rsr.misc2", 174 /* xt_iclass_rsr.misc2 */,
+ 0,
+ Opcode_rsr_misc2_encode_fns, 0, 0 },
+ { "wsr.misc2", 175 /* xt_iclass_wsr.misc2 */,
+ 0,
+ Opcode_wsr_misc2_encode_fns, 0, 0 },
+ { "xsr.misc2", 176 /* xt_iclass_xsr.misc2 */,
+ 0,
+ Opcode_xsr_misc2_encode_fns, 0, 0 },
+ { "rsr.misc3", 177 /* xt_iclass_rsr.misc3 */,
+ 0,
+ Opcode_rsr_misc3_encode_fns, 0, 0 },
+ { "wsr.misc3", 178 /* xt_iclass_wsr.misc3 */,
+ 0,
+ Opcode_wsr_misc3_encode_fns, 0, 0 },
+ { "xsr.misc3", 179 /* xt_iclass_xsr.misc3 */,
+ 0,
+ Opcode_xsr_misc3_encode_fns, 0, 0 },
+ { "rsr.prid", 180 /* xt_iclass_rsr.prid */,
+ 0,
+ Opcode_rsr_prid_encode_fns, 0, 0 },
+ { "rsr.vecbase", 181 /* xt_iclass_rsr.vecbase */,
+ 0,
+ Opcode_rsr_vecbase_encode_fns, 0, 0 },
+ { "wsr.vecbase", 182 /* xt_iclass_wsr.vecbase */,
+ 0,
+ Opcode_wsr_vecbase_encode_fns, 0, 0 },
+ { "xsr.vecbase", 183 /* xt_iclass_xsr.vecbase */,
+ 0,
+ Opcode_xsr_vecbase_encode_fns, 0, 0 },
+ { "mul.aa.ll", 184 /* xt_iclass_mac16_aa */,
+ 0,
+ Opcode_mul_aa_ll_encode_fns, 0, 0 },
+ { "mul.aa.hl", 184 /* xt_iclass_mac16_aa */,
+ 0,
+ Opcode_mul_aa_hl_encode_fns, 0, 0 },
+ { "mul.aa.lh", 184 /* xt_iclass_mac16_aa */,
+ 0,
+ Opcode_mul_aa_lh_encode_fns, 0, 0 },
+ { "mul.aa.hh", 184 /* xt_iclass_mac16_aa */,
+ 0,
+ Opcode_mul_aa_hh_encode_fns, 0, 0 },
+ { "umul.aa.ll", 184 /* xt_iclass_mac16_aa */,
+ 0,
+ Opcode_umul_aa_ll_encode_fns, 0, 0 },
+ { "umul.aa.hl", 184 /* xt_iclass_mac16_aa */,
+ 0,
+ Opcode_umul_aa_hl_encode_fns, 0, 0 },
+ { "umul.aa.lh", 184 /* xt_iclass_mac16_aa */,
+ 0,
+ Opcode_umul_aa_lh_encode_fns, 0, 0 },
+ { "umul.aa.hh", 184 /* xt_iclass_mac16_aa */,
+ 0,
+ Opcode_umul_aa_hh_encode_fns, 0, 0 },
+ { "mul.ad.ll", 185 /* xt_iclass_mac16_ad */,
+ 0,
+ Opcode_mul_ad_ll_encode_fns, 0, 0 },
+ { "mul.ad.hl", 185 /* xt_iclass_mac16_ad */,
+ 0,
+ Opcode_mul_ad_hl_encode_fns, 0, 0 },
+ { "mul.ad.lh", 185 /* xt_iclass_mac16_ad */,
+ 0,
+ Opcode_mul_ad_lh_encode_fns, 0, 0 },
+ { "mul.ad.hh", 185 /* xt_iclass_mac16_ad */,
+ 0,
+ Opcode_mul_ad_hh_encode_fns, 0, 0 },
+ { "mul.da.ll", 186 /* xt_iclass_mac16_da */,
+ 0,
+ Opcode_mul_da_ll_encode_fns, 0, 0 },
+ { "mul.da.hl", 186 /* xt_iclass_mac16_da */,
+ 0,
+ Opcode_mul_da_hl_encode_fns, 0, 0 },
+ { "mul.da.lh", 186 /* xt_iclass_mac16_da */,
+ 0,
+ Opcode_mul_da_lh_encode_fns, 0, 0 },
+ { "mul.da.hh", 186 /* xt_iclass_mac16_da */,
+ 0,
+ Opcode_mul_da_hh_encode_fns, 0, 0 },
+ { "mul.dd.ll", 187 /* xt_iclass_mac16_dd */,
+ 0,
+ Opcode_mul_dd_ll_encode_fns, 0, 0 },
+ { "mul.dd.hl", 187 /* xt_iclass_mac16_dd */,
+ 0,
+ Opcode_mul_dd_hl_encode_fns, 0, 0 },
+ { "mul.dd.lh", 187 /* xt_iclass_mac16_dd */,
+ 0,
+ Opcode_mul_dd_lh_encode_fns, 0, 0 },
+ { "mul.dd.hh", 187 /* xt_iclass_mac16_dd */,
+ 0,
+ Opcode_mul_dd_hh_encode_fns, 0, 0 },
+ { "mula.aa.ll", 188 /* xt_iclass_mac16a_aa */,
+ 0,
+ Opcode_mula_aa_ll_encode_fns, 0, 0 },
+ { "mula.aa.hl", 188 /* xt_iclass_mac16a_aa */,
+ 0,
+ Opcode_mula_aa_hl_encode_fns, 0, 0 },
+ { "mula.aa.lh", 188 /* xt_iclass_mac16a_aa */,
+ 0,
+ Opcode_mula_aa_lh_encode_fns, 0, 0 },
+ { "mula.aa.hh", 188 /* xt_iclass_mac16a_aa */,
+ 0,
+ Opcode_mula_aa_hh_encode_fns, 0, 0 },
+ { "muls.aa.ll", 188 /* xt_iclass_mac16a_aa */,
+ 0,
+ Opcode_muls_aa_ll_encode_fns, 0, 0 },
+ { "muls.aa.hl", 188 /* xt_iclass_mac16a_aa */,
+ 0,
+ Opcode_muls_aa_hl_encode_fns, 0, 0 },
+ { "muls.aa.lh", 188 /* xt_iclass_mac16a_aa */,
+ 0,
+ Opcode_muls_aa_lh_encode_fns, 0, 0 },
+ { "muls.aa.hh", 188 /* xt_iclass_mac16a_aa */,
+ 0,
+ Opcode_muls_aa_hh_encode_fns, 0, 0 },
+ { "mula.ad.ll", 189 /* xt_iclass_mac16a_ad */,
+ 0,
+ Opcode_mula_ad_ll_encode_fns, 0, 0 },
+ { "mula.ad.hl", 189 /* xt_iclass_mac16a_ad */,
+ 0,
+ Opcode_mula_ad_hl_encode_fns, 0, 0 },
+ { "mula.ad.lh", 189 /* xt_iclass_mac16a_ad */,
+ 0,
+ Opcode_mula_ad_lh_encode_fns, 0, 0 },
+ { "mula.ad.hh", 189 /* xt_iclass_mac16a_ad */,
+ 0,
+ Opcode_mula_ad_hh_encode_fns, 0, 0 },
+ { "muls.ad.ll", 189 /* xt_iclass_mac16a_ad */,
+ 0,
+ Opcode_muls_ad_ll_encode_fns, 0, 0 },
+ { "muls.ad.hl", 189 /* xt_iclass_mac16a_ad */,
+ 0,
+ Opcode_muls_ad_hl_encode_fns, 0, 0 },
+ { "muls.ad.lh", 189 /* xt_iclass_mac16a_ad */,
+ 0,
+ Opcode_muls_ad_lh_encode_fns, 0, 0 },
+ { "muls.ad.hh", 189 /* xt_iclass_mac16a_ad */,
+ 0,
+ Opcode_muls_ad_hh_encode_fns, 0, 0 },
+ { "mula.da.ll", 190 /* xt_iclass_mac16a_da */,
+ 0,
+ Opcode_mula_da_ll_encode_fns, 0, 0 },
+ { "mula.da.hl", 190 /* xt_iclass_mac16a_da */,
+ 0,
+ Opcode_mula_da_hl_encode_fns, 0, 0 },
+ { "mula.da.lh", 190 /* xt_iclass_mac16a_da */,
+ 0,
+ Opcode_mula_da_lh_encode_fns, 0, 0 },
+ { "mula.da.hh", 190 /* xt_iclass_mac16a_da */,
+ 0,
+ Opcode_mula_da_hh_encode_fns, 0, 0 },
+ { "muls.da.ll", 190 /* xt_iclass_mac16a_da */,
+ 0,
+ Opcode_muls_da_ll_encode_fns, 0, 0 },
+ { "muls.da.hl", 190 /* xt_iclass_mac16a_da */,
+ 0,
+ Opcode_muls_da_hl_encode_fns, 0, 0 },
+ { "muls.da.lh", 190 /* xt_iclass_mac16a_da */,
+ 0,
+ Opcode_muls_da_lh_encode_fns, 0, 0 },
+ { "muls.da.hh", 190 /* xt_iclass_mac16a_da */,
+ 0,
+ Opcode_muls_da_hh_encode_fns, 0, 0 },
+ { "mula.dd.ll", 191 /* xt_iclass_mac16a_dd */,
+ 0,
+ Opcode_mula_dd_ll_encode_fns, 0, 0 },
+ { "mula.dd.hl", 191 /* xt_iclass_mac16a_dd */,
+ 0,
+ Opcode_mula_dd_hl_encode_fns, 0, 0 },
+ { "mula.dd.lh", 191 /* xt_iclass_mac16a_dd */,
+ 0,
+ Opcode_mula_dd_lh_encode_fns, 0, 0 },
+ { "mula.dd.hh", 191 /* xt_iclass_mac16a_dd */,
+ 0,
+ Opcode_mula_dd_hh_encode_fns, 0, 0 },
+ { "muls.dd.ll", 191 /* xt_iclass_mac16a_dd */,
+ 0,
+ Opcode_muls_dd_ll_encode_fns, 0, 0 },
+ { "muls.dd.hl", 191 /* xt_iclass_mac16a_dd */,
+ 0,
+ Opcode_muls_dd_hl_encode_fns, 0, 0 },
+ { "muls.dd.lh", 191 /* xt_iclass_mac16a_dd */,
+ 0,
+ Opcode_muls_dd_lh_encode_fns, 0, 0 },
+ { "muls.dd.hh", 191 /* xt_iclass_mac16a_dd */,
+ 0,
+ Opcode_muls_dd_hh_encode_fns, 0, 0 },
+ { "mula.da.ll.lddec", 192 /* xt_iclass_mac16al_da */,
+ 0,
+ Opcode_mula_da_ll_lddec_encode_fns, 0, 0 },
+ { "mula.da.ll.ldinc", 192 /* xt_iclass_mac16al_da */,
+ 0,
+ Opcode_mula_da_ll_ldinc_encode_fns, 0, 0 },
+ { "mula.da.hl.lddec", 192 /* xt_iclass_mac16al_da */,
+ 0,
+ Opcode_mula_da_hl_lddec_encode_fns, 0, 0 },
+ { "mula.da.hl.ldinc", 192 /* xt_iclass_mac16al_da */,
+ 0,
+ Opcode_mula_da_hl_ldinc_encode_fns, 0, 0 },
+ { "mula.da.lh.lddec", 192 /* xt_iclass_mac16al_da */,
+ 0,
+ Opcode_mula_da_lh_lddec_encode_fns, 0, 0 },
+ { "mula.da.lh.ldinc", 192 /* xt_iclass_mac16al_da */,
+ 0,
+ Opcode_mula_da_lh_ldinc_encode_fns, 0, 0 },
+ { "mula.da.hh.lddec", 192 /* xt_iclass_mac16al_da */,
+ 0,
+ Opcode_mula_da_hh_lddec_encode_fns, 0, 0 },
+ { "mula.da.hh.ldinc", 192 /* xt_iclass_mac16al_da */,
+ 0,
+ Opcode_mula_da_hh_ldinc_encode_fns, 0, 0 },
+ { "mula.dd.ll.lddec", 193 /* xt_iclass_mac16al_dd */,
+ 0,
+ Opcode_mula_dd_ll_lddec_encode_fns, 0, 0 },
+ { "mula.dd.ll.ldinc", 193 /* xt_iclass_mac16al_dd */,
+ 0,
+ Opcode_mula_dd_ll_ldinc_encode_fns, 0, 0 },
+ { "mula.dd.hl.lddec", 193 /* xt_iclass_mac16al_dd */,
+ 0,
+ Opcode_mula_dd_hl_lddec_encode_fns, 0, 0 },
+ { "mula.dd.hl.ldinc", 193 /* xt_iclass_mac16al_dd */,
+ 0,
+ Opcode_mula_dd_hl_ldinc_encode_fns, 0, 0 },
+ { "mula.dd.lh.lddec", 193 /* xt_iclass_mac16al_dd */,
+ 0,
+ Opcode_mula_dd_lh_lddec_encode_fns, 0, 0 },
+ { "mula.dd.lh.ldinc", 193 /* xt_iclass_mac16al_dd */,
+ 0,
+ Opcode_mula_dd_lh_ldinc_encode_fns, 0, 0 },
+ { "mula.dd.hh.lddec", 193 /* xt_iclass_mac16al_dd */,
+ 0,
+ Opcode_mula_dd_hh_lddec_encode_fns, 0, 0 },
+ { "mula.dd.hh.ldinc", 193 /* xt_iclass_mac16al_dd */,
+ 0,
+ Opcode_mula_dd_hh_ldinc_encode_fns, 0, 0 },
+ { "lddec", 194 /* xt_iclass_mac16_l */,
+ 0,
+ Opcode_lddec_encode_fns, 0, 0 },
+ { "ldinc", 194 /* xt_iclass_mac16_l */,
+ 0,
+ Opcode_ldinc_encode_fns, 0, 0 },
+ { "mul16u", 195 /* xt_iclass_mul16 */,
+ 0,
+ Opcode_mul16u_encode_fns, 0, 0 },
+ { "mul16s", 195 /* xt_iclass_mul16 */,
+ 0,
+ Opcode_mul16s_encode_fns, 0, 0 },
+ { "rsr.m0", 196 /* xt_iclass_rsr.m0 */,
+ 0,
+ Opcode_rsr_m0_encode_fns, 0, 0 },
+ { "wsr.m0", 197 /* xt_iclass_wsr.m0 */,
+ 0,
+ Opcode_wsr_m0_encode_fns, 0, 0 },
+ { "xsr.m0", 198 /* xt_iclass_xsr.m0 */,
+ 0,
+ Opcode_xsr_m0_encode_fns, 0, 0 },
+ { "rsr.m1", 199 /* xt_iclass_rsr.m1 */,
+ 0,
+ Opcode_rsr_m1_encode_fns, 0, 0 },
+ { "wsr.m1", 200 /* xt_iclass_wsr.m1 */,
+ 0,
+ Opcode_wsr_m1_encode_fns, 0, 0 },
+ { "xsr.m1", 201 /* xt_iclass_xsr.m1 */,
+ 0,
+ Opcode_xsr_m1_encode_fns, 0, 0 },
+ { "rsr.m2", 202 /* xt_iclass_rsr.m2 */,
+ 0,
+ Opcode_rsr_m2_encode_fns, 0, 0 },
+ { "wsr.m2", 203 /* xt_iclass_wsr.m2 */,
+ 0,
+ Opcode_wsr_m2_encode_fns, 0, 0 },
+ { "xsr.m2", 204 /* xt_iclass_xsr.m2 */,
+ 0,
+ Opcode_xsr_m2_encode_fns, 0, 0 },
+ { "rsr.m3", 205 /* xt_iclass_rsr.m3 */,
+ 0,
+ Opcode_rsr_m3_encode_fns, 0, 0 },
+ { "wsr.m3", 206 /* xt_iclass_wsr.m3 */,
+ 0,
+ Opcode_wsr_m3_encode_fns, 0, 0 },
+ { "xsr.m3", 207 /* xt_iclass_xsr.m3 */,
+ 0,
+ Opcode_xsr_m3_encode_fns, 0, 0 },
+ { "rsr.acclo", 208 /* xt_iclass_rsr.acclo */,
+ 0,
+ Opcode_rsr_acclo_encode_fns, 0, 0 },
+ { "wsr.acclo", 209 /* xt_iclass_wsr.acclo */,
+ 0,
+ Opcode_wsr_acclo_encode_fns, 0, 0 },
+ { "xsr.acclo", 210 /* xt_iclass_xsr.acclo */,
+ 0,
+ Opcode_xsr_acclo_encode_fns, 0, 0 },
+ { "rsr.acchi", 211 /* xt_iclass_rsr.acchi */,
+ 0,
+ Opcode_rsr_acchi_encode_fns, 0, 0 },
+ { "wsr.acchi", 212 /* xt_iclass_wsr.acchi */,
+ 0,
+ Opcode_wsr_acchi_encode_fns, 0, 0 },
+ { "xsr.acchi", 213 /* xt_iclass_xsr.acchi */,
+ 0,
+ Opcode_xsr_acchi_encode_fns, 0, 0 },
+ { "rfi", 214 /* xt_iclass_rfi */,
+ XTENSA_OPCODE_IS_JUMP,
+ Opcode_rfi_encode_fns, 0, 0 },
+ { "waiti", 215 /* xt_iclass_wait */,
+ 0,
+ Opcode_waiti_encode_fns, 0, 0 },
+ { "rsr.interrupt", 216 /* xt_iclass_rsr.interrupt */,
+ 0,
+ Opcode_rsr_interrupt_encode_fns, 0, 0 },
+ { "wsr.intset", 217 /* xt_iclass_wsr.intset */,
+ 0,
+ Opcode_wsr_intset_encode_fns, 0, 0 },
+ { "wsr.intclear", 218 /* xt_iclass_wsr.intclear */,
+ 0,
+ Opcode_wsr_intclear_encode_fns, 0, 0 },
+ { "rsr.intenable", 219 /* xt_iclass_rsr.intenable */,
+ 0,
+ Opcode_rsr_intenable_encode_fns, 0, 0 },
+ { "wsr.intenable", 220 /* xt_iclass_wsr.intenable */,
+ 0,
+ Opcode_wsr_intenable_encode_fns, 0, 0 },
+ { "xsr.intenable", 221 /* xt_iclass_xsr.intenable */,
+ 0,
+ Opcode_xsr_intenable_encode_fns, 0, 0 },
+ { "break", 222 /* xt_iclass_break */,
+ 0,
+ Opcode_break_encode_fns, 0, 0 },
+ { "break.n", 223 /* xt_iclass_break.n */,
+ 0,
+ Opcode_break_n_encode_fns, 0, 0 },
+ { "rsr.dbreaka0", 224 /* xt_iclass_rsr.dbreaka0 */,
+ 0,
+ Opcode_rsr_dbreaka0_encode_fns, 0, 0 },
+ { "wsr.dbreaka0", 225 /* xt_iclass_wsr.dbreaka0 */,
+ 0,
+ Opcode_wsr_dbreaka0_encode_fns, 0, 0 },
+ { "xsr.dbreaka0", 226 /* xt_iclass_xsr.dbreaka0 */,
+ 0,
+ Opcode_xsr_dbreaka0_encode_fns, 0, 0 },
+ { "rsr.dbreakc0", 227 /* xt_iclass_rsr.dbreakc0 */,
+ 0,
+ Opcode_rsr_dbreakc0_encode_fns, 0, 0 },
+ { "wsr.dbreakc0", 228 /* xt_iclass_wsr.dbreakc0 */,
+ 0,
+ Opcode_wsr_dbreakc0_encode_fns, 0, 0 },
+ { "xsr.dbreakc0", 229 /* xt_iclass_xsr.dbreakc0 */,
+ 0,
+ Opcode_xsr_dbreakc0_encode_fns, 0, 0 },
+ { "rsr.dbreaka1", 230 /* xt_iclass_rsr.dbreaka1 */,
+ 0,
+ Opcode_rsr_dbreaka1_encode_fns, 0, 0 },
+ { "wsr.dbreaka1", 231 /* xt_iclass_wsr.dbreaka1 */,
+ 0,
+ Opcode_wsr_dbreaka1_encode_fns, 0, 0 },
+ { "xsr.dbreaka1", 232 /* xt_iclass_xsr.dbreaka1 */,
+ 0,
+ Opcode_xsr_dbreaka1_encode_fns, 0, 0 },
+ { "rsr.dbreakc1", 233 /* xt_iclass_rsr.dbreakc1 */,
+ 0,
+ Opcode_rsr_dbreakc1_encode_fns, 0, 0 },
+ { "wsr.dbreakc1", 234 /* xt_iclass_wsr.dbreakc1 */,
+ 0,
+ Opcode_wsr_dbreakc1_encode_fns, 0, 0 },
+ { "xsr.dbreakc1", 235 /* xt_iclass_xsr.dbreakc1 */,
+ 0,
+ Opcode_xsr_dbreakc1_encode_fns, 0, 0 },
+ { "rsr.ibreaka0", 236 /* xt_iclass_rsr.ibreaka0 */,
+ 0,
+ Opcode_rsr_ibreaka0_encode_fns, 0, 0 },
+ { "wsr.ibreaka0", 237 /* xt_iclass_wsr.ibreaka0 */,
+ 0,
+ Opcode_wsr_ibreaka0_encode_fns, 0, 0 },
+ { "xsr.ibreaka0", 238 /* xt_iclass_xsr.ibreaka0 */,
+ 0,
+ Opcode_xsr_ibreaka0_encode_fns, 0, 0 },
+ { "rsr.ibreaka1", 239 /* xt_iclass_rsr.ibreaka1 */,
+ 0,
+ Opcode_rsr_ibreaka1_encode_fns, 0, 0 },
+ { "wsr.ibreaka1", 240 /* xt_iclass_wsr.ibreaka1 */,
+ 0,
+ Opcode_wsr_ibreaka1_encode_fns, 0, 0 },
+ { "xsr.ibreaka1", 241 /* xt_iclass_xsr.ibreaka1 */,
+ 0,
+ Opcode_xsr_ibreaka1_encode_fns, 0, 0 },
+ { "rsr.ibreakenable", 242 /* xt_iclass_rsr.ibreakenable */,
+ 0,
+ Opcode_rsr_ibreakenable_encode_fns, 0, 0 },
+ { "wsr.ibreakenable", 243 /* xt_iclass_wsr.ibreakenable */,
+ 0,
+ Opcode_wsr_ibreakenable_encode_fns, 0, 0 },
+ { "xsr.ibreakenable", 244 /* xt_iclass_xsr.ibreakenable */,
+ 0,
+ Opcode_xsr_ibreakenable_encode_fns, 0, 0 },
+ { "rsr.debugcause", 245 /* xt_iclass_rsr.debugcause */,
+ 0,
+ Opcode_rsr_debugcause_encode_fns, 0, 0 },
+ { "wsr.debugcause", 246 /* xt_iclass_wsr.debugcause */,
+ 0,
+ Opcode_wsr_debugcause_encode_fns, 0, 0 },
+ { "xsr.debugcause", 247 /* xt_iclass_xsr.debugcause */,
+ 0,
+ Opcode_xsr_debugcause_encode_fns, 0, 0 },
+ { "rsr.icount", 248 /* xt_iclass_rsr.icount */,
+ 0,
+ Opcode_rsr_icount_encode_fns, 0, 0 },
+ { "wsr.icount", 249 /* xt_iclass_wsr.icount */,
+ 0,
+ Opcode_wsr_icount_encode_fns, 0, 0 },
+ { "xsr.icount", 250 /* xt_iclass_xsr.icount */,
+ 0,
+ Opcode_xsr_icount_encode_fns, 0, 0 },
+ { "rsr.icountlevel", 251 /* xt_iclass_rsr.icountlevel */,
+ 0,
+ Opcode_rsr_icountlevel_encode_fns, 0, 0 },
+ { "wsr.icountlevel", 252 /* xt_iclass_wsr.icountlevel */,
+ 0,
+ Opcode_wsr_icountlevel_encode_fns, 0, 0 },
+ { "xsr.icountlevel", 253 /* xt_iclass_xsr.icountlevel */,
+ 0,
+ Opcode_xsr_icountlevel_encode_fns, 0, 0 },
+ { "rsr.ddr", 254 /* xt_iclass_rsr.ddr */,
+ 0,
+ Opcode_rsr_ddr_encode_fns, 0, 0 },
+ { "wsr.ddr", 255 /* xt_iclass_wsr.ddr */,
+ 0,
+ Opcode_wsr_ddr_encode_fns, 0, 0 },
+ { "xsr.ddr", 256 /* xt_iclass_xsr.ddr */,
+ 0,
+ Opcode_xsr_ddr_encode_fns, 0, 0 },
+ { "rfdo", 257 /* xt_iclass_rfdo */,
+ XTENSA_OPCODE_IS_JUMP,
+ Opcode_rfdo_encode_fns, 0, 0 },
+ { "rfdd", 258 /* xt_iclass_rfdd */,
+ XTENSA_OPCODE_IS_JUMP,
+ Opcode_rfdd_encode_fns, 0, 0 },
+ { "wsr.mmid", 259 /* xt_iclass_wsr.mmid */,
+ 0,
+ Opcode_wsr_mmid_encode_fns, 0, 0 },
+ { "andb", 260 /* xt_iclass_bbool1 */,
+ 0,
+ Opcode_andb_encode_fns, 0, 0 },
+ { "andbc", 260 /* xt_iclass_bbool1 */,
+ 0,
+ Opcode_andbc_encode_fns, 0, 0 },
+ { "orb", 260 /* xt_iclass_bbool1 */,
+ 0,
+ Opcode_orb_encode_fns, 0, 0 },
+ { "orbc", 260 /* xt_iclass_bbool1 */,
+ 0,
+ Opcode_orbc_encode_fns, 0, 0 },
+ { "xorb", 260 /* xt_iclass_bbool1 */,
+ 0,
+ Opcode_xorb_encode_fns, 0, 0 },
+ { "any4", 261 /* xt_iclass_bbool4 */,
+ 0,
+ Opcode_any4_encode_fns, 0, 0 },
+ { "all4", 261 /* xt_iclass_bbool4 */,
+ 0,
+ Opcode_all4_encode_fns, 0, 0 },
+ { "any8", 262 /* xt_iclass_bbool8 */,
+ 0,
+ Opcode_any8_encode_fns, 0, 0 },
+ { "all8", 262 /* xt_iclass_bbool8 */,
+ 0,
+ Opcode_all8_encode_fns, 0, 0 },
+ { "bf", 263 /* xt_iclass_bbranch */,
+ XTENSA_OPCODE_IS_BRANCH,
+ Opcode_bf_encode_fns, 0, 0 },
+ { "bt", 263 /* xt_iclass_bbranch */,
+ XTENSA_OPCODE_IS_BRANCH,
+ Opcode_bt_encode_fns, 0, 0 },
+ { "movf", 264 /* xt_iclass_bmove */,
+ 0,
+ Opcode_movf_encode_fns, 0, 0 },
+ { "movt", 264 /* xt_iclass_bmove */,
+ 0,
+ Opcode_movt_encode_fns, 0, 0 },
+ { "rsr.br", 265 /* xt_iclass_RSR.BR */,
+ 0,
+ Opcode_rsr_br_encode_fns, 0, 0 },
+ { "wsr.br", 266 /* xt_iclass_WSR.BR */,
+ 0,
+ Opcode_wsr_br_encode_fns, 0, 0 },
+ { "xsr.br", 267 /* xt_iclass_XSR.BR */,
+ 0,
+ Opcode_xsr_br_encode_fns, 0, 0 },
+ { "rsr.ccount", 268 /* xt_iclass_rsr.ccount */,
+ 0,
+ Opcode_rsr_ccount_encode_fns, 0, 0 },
+ { "wsr.ccount", 269 /* xt_iclass_wsr.ccount */,
+ 0,
+ Opcode_wsr_ccount_encode_fns, 0, 0 },
+ { "xsr.ccount", 270 /* xt_iclass_xsr.ccount */,
+ 0,
+ Opcode_xsr_ccount_encode_fns, 0, 0 },
+ { "rsr.ccompare0", 271 /* xt_iclass_rsr.ccompare0 */,
+ 0,
+ Opcode_rsr_ccompare0_encode_fns, 0, 0 },
+ { "wsr.ccompare0", 272 /* xt_iclass_wsr.ccompare0 */,
+ 0,
+ Opcode_wsr_ccompare0_encode_fns, 0, 0 },
+ { "xsr.ccompare0", 273 /* xt_iclass_xsr.ccompare0 */,
+ 0,
+ Opcode_xsr_ccompare0_encode_fns, 0, 0 },
+ { "rsr.ccompare1", 274 /* xt_iclass_rsr.ccompare1 */,
+ 0,
+ Opcode_rsr_ccompare1_encode_fns, 0, 0 },
+ { "wsr.ccompare1", 275 /* xt_iclass_wsr.ccompare1 */,
+ 0,
+ Opcode_wsr_ccompare1_encode_fns, 0, 0 },
+ { "xsr.ccompare1", 276 /* xt_iclass_xsr.ccompare1 */,
+ 0,
+ Opcode_xsr_ccompare1_encode_fns, 0, 0 },
+ { "rsr.ccompare2", 277 /* xt_iclass_rsr.ccompare2 */,
+ 0,
+ Opcode_rsr_ccompare2_encode_fns, 0, 0 },
+ { "wsr.ccompare2", 278 /* xt_iclass_wsr.ccompare2 */,
+ 0,
+ Opcode_wsr_ccompare2_encode_fns, 0, 0 },
+ { "xsr.ccompare2", 279 /* xt_iclass_xsr.ccompare2 */,
+ 0,
+ Opcode_xsr_ccompare2_encode_fns, 0, 0 },
+ { "ipf", 280 /* xt_iclass_icache */,
+ 0,
+ Opcode_ipf_encode_fns, 0, 0 },
+ { "ihi", 280 /* xt_iclass_icache */,
+ 0,
+ Opcode_ihi_encode_fns, 0, 0 },
+ { "ipfl", 281 /* xt_iclass_icache_lock */,
+ 0,
+ Opcode_ipfl_encode_fns, 0, 0 },
+ { "ihu", 281 /* xt_iclass_icache_lock */,
+ 0,
+ Opcode_ihu_encode_fns, 0, 0 },
+ { "iiu", 281 /* xt_iclass_icache_lock */,
+ 0,
+ Opcode_iiu_encode_fns, 0, 0 },
+ { "iii", 282 /* xt_iclass_icache_inv */,
+ 0,
+ Opcode_iii_encode_fns, 0, 0 },
+ { "lict", 283 /* xt_iclass_licx */,
+ 0,
+ Opcode_lict_encode_fns, 0, 0 },
+ { "licw", 283 /* xt_iclass_licx */,
+ 0,
+ Opcode_licw_encode_fns, 0, 0 },
+ { "sict", 284 /* xt_iclass_sicx */,
+ 0,
+ Opcode_sict_encode_fns, 0, 0 },
+ { "sicw", 284 /* xt_iclass_sicx */,
+ 0,
+ Opcode_sicw_encode_fns, 0, 0 },
+ { "dhwb", 285 /* xt_iclass_dcache */,
+ 0,
+ Opcode_dhwb_encode_fns, 0, 0 },
+ { "dhwbi", 285 /* xt_iclass_dcache */,
+ 0,
+ Opcode_dhwbi_encode_fns, 0, 0 },
+ { "diwb", 286 /* xt_iclass_dcache_ind */,
+ 0,
+ Opcode_diwb_encode_fns, 0, 0 },
+ { "diwbi", 286 /* xt_iclass_dcache_ind */,
+ 0,
+ Opcode_diwbi_encode_fns, 0, 0 },
+ { "dhi", 287 /* xt_iclass_dcache_inv */,
+ 0,
+ Opcode_dhi_encode_fns, 0, 0 },
+ { "dii", 287 /* xt_iclass_dcache_inv */,
+ 0,
+ Opcode_dii_encode_fns, 0, 0 },
+ { "dpfr", 288 /* xt_iclass_dpf */,
+ 0,
+ Opcode_dpfr_encode_fns, 0, 0 },
+ { "dpfw", 288 /* xt_iclass_dpf */,
+ 0,
+ Opcode_dpfw_encode_fns, 0, 0 },
+ { "dpfro", 288 /* xt_iclass_dpf */,
+ 0,
+ Opcode_dpfro_encode_fns, 0, 0 },
+ { "dpfwo", 288 /* xt_iclass_dpf */,
+ 0,
+ Opcode_dpfwo_encode_fns, 0, 0 },
+ { "dpfl", 289 /* xt_iclass_dcache_lock */,
+ 0,
+ Opcode_dpfl_encode_fns, 0, 0 },
+ { "dhu", 289 /* xt_iclass_dcache_lock */,
+ 0,
+ Opcode_dhu_encode_fns, 0, 0 },
+ { "diu", 289 /* xt_iclass_dcache_lock */,
+ 0,
+ Opcode_diu_encode_fns, 0, 0 },
+ { "sdct", 290 /* xt_iclass_sdct */,
+ 0,
+ Opcode_sdct_encode_fns, 0, 0 },
+ { "ldct", 291 /* xt_iclass_ldct */,
+ 0,
+ Opcode_ldct_encode_fns, 0, 0 },
+ { "wsr.ptevaddr", 292 /* xt_iclass_wsr.ptevaddr */,
+ 0,
+ Opcode_wsr_ptevaddr_encode_fns, 0, 0 },
+ { "rsr.ptevaddr", 293 /* xt_iclass_rsr.ptevaddr */,
+ 0,
+ Opcode_rsr_ptevaddr_encode_fns, 0, 0 },
+ { "xsr.ptevaddr", 294 /* xt_iclass_xsr.ptevaddr */,
+ 0,
+ Opcode_xsr_ptevaddr_encode_fns, 0, 0 },
+ { "rsr.rasid", 295 /* xt_iclass_rsr.rasid */,
+ 0,
+ Opcode_rsr_rasid_encode_fns, 0, 0 },
+ { "wsr.rasid", 296 /* xt_iclass_wsr.rasid */,
+ 0,
+ Opcode_wsr_rasid_encode_fns, 0, 0 },
+ { "xsr.rasid", 297 /* xt_iclass_xsr.rasid */,
+ 0,
+ Opcode_xsr_rasid_encode_fns, 0, 0 },
+ { "rsr.itlbcfg", 298 /* xt_iclass_rsr.itlbcfg */,
+ 0,
+ Opcode_rsr_itlbcfg_encode_fns, 0, 0 },
+ { "wsr.itlbcfg", 299 /* xt_iclass_wsr.itlbcfg */,
+ 0,
+ Opcode_wsr_itlbcfg_encode_fns, 0, 0 },
+ { "xsr.itlbcfg", 300 /* xt_iclass_xsr.itlbcfg */,
+ 0,
+ Opcode_xsr_itlbcfg_encode_fns, 0, 0 },
+ { "rsr.dtlbcfg", 301 /* xt_iclass_rsr.dtlbcfg */,
+ 0,
+ Opcode_rsr_dtlbcfg_encode_fns, 0, 0 },
+ { "wsr.dtlbcfg", 302 /* xt_iclass_wsr.dtlbcfg */,
+ 0,
+ Opcode_wsr_dtlbcfg_encode_fns, 0, 0 },
+ { "xsr.dtlbcfg", 303 /* xt_iclass_xsr.dtlbcfg */,
+ 0,
+ Opcode_xsr_dtlbcfg_encode_fns, 0, 0 },
+ { "idtlb", 304 /* xt_iclass_idtlb */,
+ 0,
+ Opcode_idtlb_encode_fns, 0, 0 },
+ { "pdtlb", 305 /* xt_iclass_rdtlb */,
+ 0,
+ Opcode_pdtlb_encode_fns, 0, 0 },
+ { "rdtlb0", 305 /* xt_iclass_rdtlb */,
+ 0,
+ Opcode_rdtlb0_encode_fns, 0, 0 },
+ { "rdtlb1", 305 /* xt_iclass_rdtlb */,
+ 0,
+ Opcode_rdtlb1_encode_fns, 0, 0 },
+ { "wdtlb", 306 /* xt_iclass_wdtlb */,
+ 0,
+ Opcode_wdtlb_encode_fns, 0, 0 },
+ { "iitlb", 307 /* xt_iclass_iitlb */,
+ 0,
+ Opcode_iitlb_encode_fns, 0, 0 },
+ { "pitlb", 308 /* xt_iclass_ritlb */,
+ 0,
+ Opcode_pitlb_encode_fns, 0, 0 },
+ { "ritlb0", 308 /* xt_iclass_ritlb */,
+ 0,
+ Opcode_ritlb0_encode_fns, 0, 0 },
+ { "ritlb1", 308 /* xt_iclass_ritlb */,
+ 0,
+ Opcode_ritlb1_encode_fns, 0, 0 },
+ { "witlb", 309 /* xt_iclass_witlb */,
+ 0,
+ Opcode_witlb_encode_fns, 0, 0 },
+ { "ldpte", 310 /* xt_iclass_ldpte */,
+ 0,
+ Opcode_ldpte_encode_fns, 0, 0 },
+ { "hwwitlba", 311 /* xt_iclass_hwwitlba */,
+ XTENSA_OPCODE_IS_BRANCH,
+ Opcode_hwwitlba_encode_fns, 0, 0 },
+ { "hwwdtlba", 312 /* xt_iclass_hwwdtlba */,
+ 0,
+ Opcode_hwwdtlba_encode_fns, 0, 0 },
+ { "rsr.cpenable", 313 /* xt_iclass_rsr.cpenable */,
+ 0,
+ Opcode_rsr_cpenable_encode_fns, 0, 0 },
+ { "wsr.cpenable", 314 /* xt_iclass_wsr.cpenable */,
+ 0,
+ Opcode_wsr_cpenable_encode_fns, 0, 0 },
+ { "xsr.cpenable", 315 /* xt_iclass_xsr.cpenable */,
+ 0,
+ Opcode_xsr_cpenable_encode_fns, 0, 0 },
+ { "clamps", 316 /* xt_iclass_clamp */,
+ 0,
+ Opcode_clamps_encode_fns, 0, 0 },
+ { "min", 317 /* xt_iclass_minmax */,
+ 0,
+ Opcode_min_encode_fns, 0, 0 },
+ { "max", 317 /* xt_iclass_minmax */,
+ 0,
+ Opcode_max_encode_fns, 0, 0 },
+ { "minu", 317 /* xt_iclass_minmax */,
+ 0,
+ Opcode_minu_encode_fns, 0, 0 },
+ { "maxu", 317 /* xt_iclass_minmax */,
+ 0,
+ Opcode_maxu_encode_fns, 0, 0 },
+ { "nsa", 318 /* xt_iclass_nsa */,
+ 0,
+ Opcode_nsa_encode_fns, 0, 0 },
+ { "nsau", 318 /* xt_iclass_nsa */,
+ 0,
+ Opcode_nsau_encode_fns, 0, 0 },
+ { "sext", 319 /* xt_iclass_sx */,
+ 0,
+ Opcode_sext_encode_fns, 0, 0 },
+ { "l32ai", 320 /* xt_iclass_l32ai */,
+ 0,
+ Opcode_l32ai_encode_fns, 0, 0 },
+ { "s32ri", 321 /* xt_iclass_s32ri */,
+ 0,
+ Opcode_s32ri_encode_fns, 0, 0 },
+ { "s32c1i", 322 /* xt_iclass_s32c1i */,
+ 0,
+ Opcode_s32c1i_encode_fns, 0, 0 },
+ { "rsr.scompare1", 323 /* xt_iclass_rsr.scompare1 */,
+ 0,
+ Opcode_rsr_scompare1_encode_fns, 0, 0 },
+ { "wsr.scompare1", 324 /* xt_iclass_wsr.scompare1 */,
+ 0,
+ Opcode_wsr_scompare1_encode_fns, 0, 0 },
+ { "xsr.scompare1", 325 /* xt_iclass_xsr.scompare1 */,
+ 0,
+ Opcode_xsr_scompare1_encode_fns, 0, 0 },
+ { "quou", 326 /* xt_iclass_div */,
+ 0,
+ Opcode_quou_encode_fns, 0, 0 },
+ { "quos", 326 /* xt_iclass_div */,
+ 0,
+ Opcode_quos_encode_fns, 0, 0 },
+ { "remu", 326 /* xt_iclass_div */,
+ 0,
+ Opcode_remu_encode_fns, 0, 0 },
+ { "rems", 326 /* xt_iclass_div */,
+ 0,
+ Opcode_rems_encode_fns, 0, 0 },
+ { "mull", 327 /* xt_mul32 */,
+ 0,
+ Opcode_mull_encode_fns, 0, 0 },
+ { "muluh", 327 /* xt_mul32 */,
+ 0,
+ Opcode_muluh_encode_fns, 0, 0 },
+ { "mulsh", 327 /* xt_mul32 */,
+ 0,
+ Opcode_mulsh_encode_fns, 0, 0 },
+ { "rur.fcr", 328 /* rur_fcr */,
+ 0,
+ Opcode_rur_fcr_encode_fns, 0, 0 },
+ { "wur.fcr", 329 /* wur_fcr */,
+ 0,
+ Opcode_wur_fcr_encode_fns, 0, 0 },
+ { "rur.fsr", 330 /* rur_fsr */,
+ 0,
+ Opcode_rur_fsr_encode_fns, 0, 0 },
+ { "wur.fsr", 331 /* wur_fsr */,
+ 0,
+ Opcode_wur_fsr_encode_fns, 0, 0 },
+ { "add.s", 332 /* fp */,
+ 0,
+ Opcode_add_s_encode_fns, 0, 0 },
+ { "sub.s", 332 /* fp */,
+ 0,
+ Opcode_sub_s_encode_fns, 0, 0 },
+ { "mul.s", 332 /* fp */,
+ 0,
+ Opcode_mul_s_encode_fns, 0, 0 },
+ { "madd.s", 333 /* fp_mac */,
+ 0,
+ Opcode_madd_s_encode_fns, 0, 0 },
+ { "msub.s", 333 /* fp_mac */,
+ 0,
+ Opcode_msub_s_encode_fns, 0, 0 },
+ { "movf.s", 334 /* fp_cmov */,
+ 0,
+ Opcode_movf_s_encode_fns, 0, 0 },
+ { "movt.s", 334 /* fp_cmov */,
+ 0,
+ Opcode_movt_s_encode_fns, 0, 0 },
+ { "moveqz.s", 335 /* fp_mov */,
+ 0,
+ Opcode_moveqz_s_encode_fns, 0, 0 },
+ { "movnez.s", 335 /* fp_mov */,
+ 0,
+ Opcode_movnez_s_encode_fns, 0, 0 },
+ { "movltz.s", 335 /* fp_mov */,
+ 0,
+ Opcode_movltz_s_encode_fns, 0, 0 },
+ { "movgez.s", 335 /* fp_mov */,
+ 0,
+ Opcode_movgez_s_encode_fns, 0, 0 },
+ { "abs.s", 336 /* fp_mov2 */,
+ 0,
+ Opcode_abs_s_encode_fns, 0, 0 },
+ { "mov.s", 336 /* fp_mov2 */,
+ 0,
+ Opcode_mov_s_encode_fns, 0, 0 },
+ { "neg.s", 336 /* fp_mov2 */,
+ 0,
+ Opcode_neg_s_encode_fns, 0, 0 },
+ { "un.s", 337 /* fp_cmp */,
+ 0,
+ Opcode_un_s_encode_fns, 0, 0 },
+ { "oeq.s", 337 /* fp_cmp */,
+ 0,
+ Opcode_oeq_s_encode_fns, 0, 0 },
+ { "ueq.s", 337 /* fp_cmp */,
+ 0,
+ Opcode_ueq_s_encode_fns, 0, 0 },
+ { "olt.s", 337 /* fp_cmp */,
+ 0,
+ Opcode_olt_s_encode_fns, 0, 0 },
+ { "ult.s", 337 /* fp_cmp */,
+ 0,
+ Opcode_ult_s_encode_fns, 0, 0 },
+ { "ole.s", 337 /* fp_cmp */,
+ 0,
+ Opcode_ole_s_encode_fns, 0, 0 },
+ { "ule.s", 337 /* fp_cmp */,
+ 0,
+ Opcode_ule_s_encode_fns, 0, 0 },
+ { "float.s", 338 /* fp_float */,
+ 0,
+ Opcode_float_s_encode_fns, 0, 0 },
+ { "ufloat.s", 338 /* fp_float */,
+ 0,
+ Opcode_ufloat_s_encode_fns, 0, 0 },
+ { "round.s", 339 /* fp_int */,
+ 0,
+ Opcode_round_s_encode_fns, 0, 0 },
+ { "ceil.s", 339 /* fp_int */,
+ 0,
+ Opcode_ceil_s_encode_fns, 0, 0 },
+ { "floor.s", 339 /* fp_int */,
+ 0,
+ Opcode_floor_s_encode_fns, 0, 0 },
+ { "trunc.s", 339 /* fp_int */,
+ 0,
+ Opcode_trunc_s_encode_fns, 0, 0 },
+ { "utrunc.s", 339 /* fp_int */,
+ 0,
+ Opcode_utrunc_s_encode_fns, 0, 0 },
+ { "rfr", 340 /* fp_rfr */,
+ 0,
+ Opcode_rfr_encode_fns, 0, 0 },
+ { "wfr", 341 /* fp_wfr */,
+ 0,
+ Opcode_wfr_encode_fns, 0, 0 },
+ { "lsi", 342 /* fp_lsi */,
+ 0,
+ Opcode_lsi_encode_fns, 0, 0 },
+ { "lsiu", 343 /* fp_lsiu */,
+ 0,
+ Opcode_lsiu_encode_fns, 0, 0 },
+ { "lsx", 344 /* fp_lsx */,
+ 0,
+ Opcode_lsx_encode_fns, 0, 0 },
+ { "lsxu", 345 /* fp_lsxu */,
+ 0,
+ Opcode_lsxu_encode_fns, 0, 0 },
+ { "ssi", 346 /* fp_ssi */,
+ 0,
+ Opcode_ssi_encode_fns, 0, 0 },
+ { "ssiu", 347 /* fp_ssiu */,
+ 0,
+ Opcode_ssiu_encode_fns, 0, 0 },
+ { "ssx", 348 /* fp_ssx */,
+ 0,
+ Opcode_ssx_encode_fns, 0, 0 },
+ { "ssxu", 349 /* fp_ssxu */,
+ 0,
+ Opcode_ssxu_encode_fns, 0, 0 },
+ { "beqz.w18", 350 /* xt_iclass_wb18_0 */,
+ XTENSA_OPCODE_IS_BRANCH,
+ Opcode_beqz_w18_encode_fns, 0, 0 },
+ { "bnez.w18", 350 /* xt_iclass_wb18_0 */,
+ XTENSA_OPCODE_IS_BRANCH,
+ Opcode_bnez_w18_encode_fns, 0, 0 },
+ { "bgez.w18", 350 /* xt_iclass_wb18_0 */,
+ XTENSA_OPCODE_IS_BRANCH,
+ Opcode_bgez_w18_encode_fns, 0, 0 },
+ { "bltz.w18", 350 /* xt_iclass_wb18_0 */,
+ XTENSA_OPCODE_IS_BRANCH,
+ Opcode_bltz_w18_encode_fns, 0, 0 },
+ { "beqi.w18", 351 /* xt_iclass_wb18_1 */,
+ XTENSA_OPCODE_IS_BRANCH,
+ Opcode_beqi_w18_encode_fns, 0, 0 },
+ { "bnei.w18", 351 /* xt_iclass_wb18_1 */,
+ XTENSA_OPCODE_IS_BRANCH,
+ Opcode_bnei_w18_encode_fns, 0, 0 },
+ { "bgei.w18", 351 /* xt_iclass_wb18_1 */,
+ XTENSA_OPCODE_IS_BRANCH,
+ Opcode_bgei_w18_encode_fns, 0, 0 },
+ { "blti.w18", 351 /* xt_iclass_wb18_1 */,
+ XTENSA_OPCODE_IS_BRANCH,
+ Opcode_blti_w18_encode_fns, 0, 0 },
+ { "bgeui.w18", 352 /* xt_iclass_wb18_2 */,
+ XTENSA_OPCODE_IS_BRANCH,
+ Opcode_bgeui_w18_encode_fns, 0, 0 },
+ { "bltui.w18", 352 /* xt_iclass_wb18_2 */,
+ XTENSA_OPCODE_IS_BRANCH,
+ Opcode_bltui_w18_encode_fns, 0, 0 },
+ { "bbci.w18", 353 /* xt_iclass_wb18_3 */,
+ XTENSA_OPCODE_IS_BRANCH,
+ Opcode_bbci_w18_encode_fns, 0, 0 },
+ { "bbsi.w18", 353 /* xt_iclass_wb18_3 */,
+ XTENSA_OPCODE_IS_BRANCH,
+ Opcode_bbsi_w18_encode_fns, 0, 0 },
+ { "beq.w18", 354 /* xt_iclass_wb18_4 */,
+ XTENSA_OPCODE_IS_BRANCH,
+ Opcode_beq_w18_encode_fns, 0, 0 },
+ { "bne.w18", 354 /* xt_iclass_wb18_4 */,
+ XTENSA_OPCODE_IS_BRANCH,
+ Opcode_bne_w18_encode_fns, 0, 0 },
+ { "bge.w18", 354 /* xt_iclass_wb18_4 */,
+ XTENSA_OPCODE_IS_BRANCH,
+ Opcode_bge_w18_encode_fns, 0, 0 },
+ { "blt.w18", 354 /* xt_iclass_wb18_4 */,
+ XTENSA_OPCODE_IS_BRANCH,
+ Opcode_blt_w18_encode_fns, 0, 0 },
+ { "bgeu.w18", 354 /* xt_iclass_wb18_4 */,
+ XTENSA_OPCODE_IS_BRANCH,
+ Opcode_bgeu_w18_encode_fns, 0, 0 },
+ { "bltu.w18", 354 /* xt_iclass_wb18_4 */,
+ XTENSA_OPCODE_IS_BRANCH,
+ Opcode_bltu_w18_encode_fns, 0, 0 },
+ { "bany.w18", 354 /* xt_iclass_wb18_4 */,
+ XTENSA_OPCODE_IS_BRANCH,
+ Opcode_bany_w18_encode_fns, 0, 0 },
+ { "bnone.w18", 354 /* xt_iclass_wb18_4 */,
+ XTENSA_OPCODE_IS_BRANCH,
+ Opcode_bnone_w18_encode_fns, 0, 0 },
+ { "ball.w18", 354 /* xt_iclass_wb18_4 */,
+ XTENSA_OPCODE_IS_BRANCH,
+ Opcode_ball_w18_encode_fns, 0, 0 },
+ { "bnall.w18", 354 /* xt_iclass_wb18_4 */,
+ XTENSA_OPCODE_IS_BRANCH,
+ Opcode_bnall_w18_encode_fns, 0, 0 },
+ { "bbc.w18", 354 /* xt_iclass_wb18_4 */,
+ XTENSA_OPCODE_IS_BRANCH,
+ Opcode_bbc_w18_encode_fns, 0, 0 },
+ { "bbs.w18", 354 /* xt_iclass_wb18_4 */,
+ XTENSA_OPCODE_IS_BRANCH,
+ Opcode_bbs_w18_encode_fns, 0, 0 }
+};
+
+
+/* Slot-specific opcode decode functions. */
+
+static int
+Slot_inst_decode (const xtensa_insnbuf insn)
+{
+ switch (Field_op0_Slot_inst_get (insn))
+ {
+ case 0:
+ switch (Field_op1_Slot_inst_get (insn))
+ {
+ case 0:
+ switch (Field_op2_Slot_inst_get (insn))
+ {
+ case 0:
+ switch (Field_r_Slot_inst_get (insn))
+ {
+ case 0:
+ switch (Field_m_Slot_inst_get (insn))
+ {
+ case 0:
+ if (Field_s_Slot_inst_get (insn) == 0 &&
+ Field_n_Slot_inst_get (insn) == 0)
+ return 79; /* ill */
+ break;
+ case 2:
+ switch (Field_n_Slot_inst_get (insn))
+ {
+ case 0:
+ return 98; /* ret */
+ case 1:
+ return 14; /* retw */
+ case 2:
+ return 81; /* jx */
+ }
+ break;
+ case 3:
+ switch (Field_n_Slot_inst_get (insn))
+ {
+ case 0:
+ return 77; /* callx0 */
+ case 1:
+ return 10; /* callx4 */
+ case 2:
+ return 9; /* callx8 */
+ case 3:
+ return 8; /* callx12 */
+ }
+ break;
+ }
+ break;
+ case 1:
+ return 12; /* movsp */
+ case 2:
+ if (Field_s_Slot_inst_get (insn) == 0)
+ {
+ switch (Field_t_Slot_inst_get (insn))
+ {
+ case 0:
+ return 116; /* isync */
+ case 1:
+ return 117; /* rsync */
+ case 2:
+ return 118; /* esync */
+ case 3:
+ return 119; /* dsync */
+ case 8:
+ return 0; /* excw */
+ case 12:
+ return 114; /* memw */
+ case 13:
+ return 115; /* extw */
+ case 15:
+ return 97; /* nop */
+ }
+ }
+ break;
+ case 3:
+ switch (Field_t_Slot_inst_get (insn))
+ {
+ case 0:
+ switch (Field_s_Slot_inst_get (insn))
+ {
+ case 0:
+ return 1; /* rfe */
+ case 2:
+ return 2; /* rfde */
+ case 4:
+ return 16; /* rfwo */
+ case 5:
+ return 17; /* rfwu */
+ }
+ break;
+ case 1:
+ return 316; /* rfi */
+ }
+ break;
+ case 4:
+ return 324; /* break */
+ case 5:
+ switch (Field_s_Slot_inst_get (insn))
+ {
+ case 0:
+ if (Field_t_Slot_inst_get (insn) == 0)
+ return 3; /* syscall */
+ break;
+ case 1:
+ if (Field_t_Slot_inst_get (insn) == 0)
+ return 4; /* simcall */
+ break;
+ }
+ break;
+ case 6:
+ return 120; /* rsil */
+ case 7:
+ if (Field_t_Slot_inst_get (insn) == 0)
+ return 317; /* waiti */
+ break;
+ case 8:
+ return 367; /* any4 */
+ case 9:
+ return 368; /* all4 */
+ case 10:
+ return 369; /* any8 */
+ case 11:
+ return 370; /* all8 */
+ }
+ break;
+ case 1:
+ return 49; /* and */
+ case 2:
+ return 50; /* or */
+ case 3:
+ return 51; /* xor */
+ case 4:
+ switch (Field_r_Slot_inst_get (insn))
+ {
+ case 0:
+ if (Field_t_Slot_inst_get (insn) == 0)
+ return 102; /* ssr */
+ break;
+ case 1:
+ if (Field_t_Slot_inst_get (insn) == 0)
+ return 103; /* ssl */
+ break;
+ case 2:
+ if (Field_t_Slot_inst_get (insn) == 0)
+ return 104; /* ssa8l */
+ break;
+ case 3:
+ if (Field_t_Slot_inst_get (insn) == 0)
+ return 105; /* ssa8b */
+ break;
+ case 4:
+ if (Field_thi3_Slot_inst_get (insn) == 0)
+ return 106; /* ssai */
+ break;
+ case 8:
+ if (Field_s_Slot_inst_get (insn) == 0)
+ return 13; /* rotw */
+ break;
+ case 14:
+ return 448; /* nsa */
+ case 15:
+ return 449; /* nsau */
+ }
+ break;
+ case 5:
+ switch (Field_r_Slot_inst_get (insn))
+ {
+ case 1:
+ return 438; /* hwwitlba */
+ case 3:
+ return 434; /* ritlb0 */
+ case 4:
+ if (Field_t_Slot_inst_get (insn) == 0)
+ return 432; /* iitlb */
+ break;
+ case 5:
+ return 433; /* pitlb */
+ case 6:
+ return 436; /* witlb */
+ case 7:
+ return 435; /* ritlb1 */
+ case 9:
+ return 439; /* hwwdtlba */
+ case 11:
+ return 429; /* rdtlb0 */
+ case 12:
+ if (Field_t_Slot_inst_get (insn) == 0)
+ return 427; /* idtlb */
+ break;
+ case 13:
+ return 428; /* pdtlb */
+ case 14:
+ return 431; /* wdtlb */
+ case 15:
+ return 430; /* rdtlb1 */
+ }
+ break;
+ case 6:
+ switch (Field_s_Slot_inst_get (insn))
+ {
+ case 0:
+ return 95; /* neg */
+ case 1:
+ return 96; /* abs */
+ }
+ break;
+ case 8:
+ return 41; /* add */
+ case 9:
+ return 43; /* addx2 */
+ case 10:
+ return 44; /* addx4 */
+ case 11:
+ return 45; /* addx8 */
+ case 12:
+ return 42; /* sub */
+ case 13:
+ return 46; /* subx2 */
+ case 14:
+ return 47; /* subx4 */
+ case 15:
+ return 48; /* subx8 */
+ }
+ break;
+ case 1:
+ switch (Field_op2_Slot_inst_get (insn))
+ {
+ case 0:
+ case 1:
+ return 111; /* slli */
+ case 2:
+ case 3:
+ return 112; /* srai */
+ case 4:
+ return 113; /* srli */
+ case 6:
+ switch (Field_sr_Slot_inst_get (insn))
+ {
+ case 0:
+ return 129; /* xsr.lbeg */
+ case 1:
+ return 123; /* xsr.lend */
+ case 2:
+ return 126; /* xsr.lcount */
+ case 3:
+ return 132; /* xsr.sar */
+ case 4:
+ return 377; /* xsr.br */
+ case 5:
+ return 135; /* xsr.litbase */
+ case 12:
+ return 456; /* xsr.scompare1 */
+ case 16:
+ return 312; /* xsr.acclo */
+ case 17:
+ return 315; /* xsr.acchi */
+ case 32:
+ return 300; /* xsr.m0 */
+ case 33:
+ return 303; /* xsr.m1 */
+ case 34:
+ return 306; /* xsr.m2 */
+ case 35:
+ return 309; /* xsr.m3 */
+ case 72:
+ return 22; /* xsr.windowbase */
+ case 73:
+ return 25; /* xsr.windowstart */
+ case 83:
+ return 417; /* xsr.ptevaddr */
+ case 90:
+ return 420; /* xsr.rasid */
+ case 91:
+ return 423; /* xsr.itlbcfg */
+ case 92:
+ return 426; /* xsr.dtlbcfg */
+ case 96:
+ return 346; /* xsr.ibreakenable */
+ case 104:
+ return 358; /* xsr.ddr */
+ case 128:
+ return 340; /* xsr.ibreaka0 */
+ case 129:
+ return 343; /* xsr.ibreaka1 */
+ case 144:
+ return 328; /* xsr.dbreaka0 */
+ case 145:
+ return 334; /* xsr.dbreaka1 */
+ case 160:
+ return 331; /* xsr.dbreakc0 */
+ case 161:
+ return 337; /* xsr.dbreakc1 */
+ case 177:
+ return 143; /* xsr.epc1 */
+ case 178:
+ return 149; /* xsr.epc2 */
+ case 179:
+ return 155; /* xsr.epc3 */
+ case 180:
+ return 161; /* xsr.epc4 */
+ case 181:
+ return 167; /* xsr.epc5 */
+ case 182:
+ return 173; /* xsr.epc6 */
+ case 183:
+ return 179; /* xsr.epc7 */
+ case 192:
+ return 206; /* xsr.depc */
+ case 194:
+ return 185; /* xsr.eps2 */
+ case 195:
+ return 188; /* xsr.eps3 */
+ case 196:
+ return 191; /* xsr.eps4 */
+ case 197:
+ return 194; /* xsr.eps5 */
+ case 198:
+ return 197; /* xsr.eps6 */
+ case 199:
+ return 200; /* xsr.eps7 */
+ case 209:
+ return 146; /* xsr.excsave1 */
+ case 210:
+ return 152; /* xsr.excsave2 */
+ case 211:
+ return 158; /* xsr.excsave3 */
+ case 212:
+ return 164; /* xsr.excsave4 */
+ case 213:
+ return 170; /* xsr.excsave5 */
+ case 214:
+ return 176; /* xsr.excsave6 */
+ case 215:
+ return 182; /* xsr.excsave7 */
+ case 224:
+ return 442; /* xsr.cpenable */
+ case 228:
+ return 323; /* xsr.intenable */
+ case 230:
+ return 140; /* xsr.ps */
+ case 231:
+ return 225; /* xsr.vecbase */
+ case 232:
+ return 209; /* xsr.exccause */
+ case 233:
+ return 349; /* xsr.debugcause */
+ case 234:
+ return 380; /* xsr.ccount */
+ case 236:
+ return 352; /* xsr.icount */
+ case 237:
+ return 355; /* xsr.icountlevel */
+ case 238:
+ return 203; /* xsr.excvaddr */
+ case 240:
+ return 383; /* xsr.ccompare0 */
+ case 241:
+ return 386; /* xsr.ccompare1 */
+ case 242:
+ return 389; /* xsr.ccompare2 */
+ case 244:
+ return 212; /* xsr.misc0 */
+ case 245:
+ return 215; /* xsr.misc1 */
+ case 246:
+ return 218; /* xsr.misc2 */
+ case 247:
+ return 221; /* xsr.misc3 */
+ }
+ break;
+ case 8:
+ return 108; /* src */
+ case 9:
+ if (Field_s_Slot_inst_get (insn) == 0)
+ return 109; /* srl */
+ break;
+ case 10:
+ if (Field_t_Slot_inst_get (insn) == 0)
+ return 107; /* sll */
+ break;
+ case 11:
+ if (Field_s_Slot_inst_get (insn) == 0)
+ return 110; /* sra */
+ break;
+ case 12:
+ return 296; /* mul16u */
+ case 13:
+ return 297; /* mul16s */
+ case 15:
+ switch (Field_r_Slot_inst_get (insn))
+ {
+ case 0:
+ return 396; /* lict */
+ case 1:
+ return 398; /* sict */
+ case 2:
+ return 397; /* licw */
+ case 3:
+ return 399; /* sicw */
+ case 8:
+ return 414; /* ldct */
+ case 9:
+ return 413; /* sdct */
+ case 14:
+ if (Field_t_Slot_inst_get (insn) == 0)
+ return 359; /* rfdo */
+ if (Field_t_Slot_inst_get (insn) == 1)
+ return 360; /* rfdd */
+ break;
+ case 15:
+ return 437; /* ldpte */
+ }
+ break;
+ }
+ break;
+ case 2:
+ switch (Field_op2_Slot_inst_get (insn))
+ {
+ case 0:
+ return 362; /* andb */
+ case 1:
+ return 363; /* andbc */
+ case 2:
+ return 364; /* orb */
+ case 3:
+ return 365; /* orbc */
+ case 4:
+ return 366; /* xorb */
+ case 8:
+ return 461; /* mull */
+ case 10:
+ return 462; /* muluh */
+ case 11:
+ return 463; /* mulsh */
+ case 12:
+ return 457; /* quou */
+ case 13:
+ return 458; /* quos */
+ case 14:
+ return 459; /* remu */
+ case 15:
+ return 460; /* rems */
+ }
+ break;
+ case 3:
+ switch (Field_op2_Slot_inst_get (insn))
+ {
+ case 0:
+ switch (Field_sr_Slot_inst_get (insn))
+ {
+ case 0:
+ return 127; /* rsr.lbeg */
+ case 1:
+ return 121; /* rsr.lend */
+ case 2:
+ return 124; /* rsr.lcount */
+ case 3:
+ return 130; /* rsr.sar */
+ case 4:
+ return 375; /* rsr.br */
+ case 5:
+ return 133; /* rsr.litbase */
+ case 12:
+ return 454; /* rsr.scompare1 */
+ case 16:
+ return 310; /* rsr.acclo */
+ case 17:
+ return 313; /* rsr.acchi */
+ case 32:
+ return 298; /* rsr.m0 */
+ case 33:
+ return 301; /* rsr.m1 */
+ case 34:
+ return 304; /* rsr.m2 */
+ case 35:
+ return 307; /* rsr.m3 */
+ case 72:
+ return 20; /* rsr.windowbase */
+ case 73:
+ return 23; /* rsr.windowstart */
+ case 83:
+ return 416; /* rsr.ptevaddr */
+ case 90:
+ return 418; /* rsr.rasid */
+ case 91:
+ return 421; /* rsr.itlbcfg */
+ case 92:
+ return 424; /* rsr.dtlbcfg */
+ case 96:
+ return 344; /* rsr.ibreakenable */
+ case 104:
+ return 356; /* rsr.ddr */
+ case 128:
+ return 338; /* rsr.ibreaka0 */
+ case 129:
+ return 341; /* rsr.ibreaka1 */
+ case 144:
+ return 326; /* rsr.dbreaka0 */
+ case 145:
+ return 332; /* rsr.dbreaka1 */
+ case 160:
+ return 329; /* rsr.dbreakc0 */
+ case 161:
+ return 335; /* rsr.dbreakc1 */
+ case 176:
+ return 136; /* rsr.176 */
+ case 177:
+ return 141; /* rsr.epc1 */
+ case 178:
+ return 147; /* rsr.epc2 */
+ case 179:
+ return 153; /* rsr.epc3 */
+ case 180:
+ return 159; /* rsr.epc4 */
+ case 181:
+ return 165; /* rsr.epc5 */
+ case 182:
+ return 171; /* rsr.epc6 */
+ case 183:
+ return 177; /* rsr.epc7 */
+ case 192:
+ return 204; /* rsr.depc */
+ case 194:
+ return 183; /* rsr.eps2 */
+ case 195:
+ return 186; /* rsr.eps3 */
+ case 196:
+ return 189; /* rsr.eps4 */
+ case 197:
+ return 192; /* rsr.eps5 */
+ case 198:
+ return 195; /* rsr.eps6 */
+ case 199:
+ return 198; /* rsr.eps7 */
+ case 208:
+ return 137; /* rsr.208 */
+ case 209:
+ return 144; /* rsr.excsave1 */
+ case 210:
+ return 150; /* rsr.excsave2 */
+ case 211:
+ return 156; /* rsr.excsave3 */
+ case 212:
+ return 162; /* rsr.excsave4 */
+ case 213:
+ return 168; /* rsr.excsave5 */
+ case 214:
+ return 174; /* rsr.excsave6 */
+ case 215:
+ return 180; /* rsr.excsave7 */
+ case 224:
+ return 440; /* rsr.cpenable */
+ case 226:
+ return 318; /* rsr.interrupt */
+ case 228:
+ return 321; /* rsr.intenable */
+ case 230:
+ return 138; /* rsr.ps */
+ case 231:
+ return 223; /* rsr.vecbase */
+ case 232:
+ return 207; /* rsr.exccause */
+ case 233:
+ return 347; /* rsr.debugcause */
+ case 234:
+ return 378; /* rsr.ccount */
+ case 235:
+ return 222; /* rsr.prid */
+ case 236:
+ return 350; /* rsr.icount */
+ case 237:
+ return 353; /* rsr.icountlevel */
+ case 238:
+ return 201; /* rsr.excvaddr */
+ case 240:
+ return 381; /* rsr.ccompare0 */
+ case 241:
+ return 384; /* rsr.ccompare1 */
+ case 242:
+ return 387; /* rsr.ccompare2 */
+ case 244:
+ return 210; /* rsr.misc0 */
+ case 245:
+ return 213; /* rsr.misc1 */
+ case 246:
+ return 216; /* rsr.misc2 */
+ case 247:
+ return 219; /* rsr.misc3 */
+ }
+ break;
+ case 1:
+ switch (Field_sr_Slot_inst_get (insn))
+ {
+ case 0:
+ return 128; /* wsr.lbeg */
+ case 1:
+ return 122; /* wsr.lend */
+ case 2:
+ return 125; /* wsr.lcount */
+ case 3:
+ return 131; /* wsr.sar */
+ case 4:
+ return 376; /* wsr.br */
+ case 5:
+ return 134; /* wsr.litbase */
+ case 12:
+ return 455; /* wsr.scompare1 */
+ case 16:
+ return 311; /* wsr.acclo */
+ case 17:
+ return 314; /* wsr.acchi */
+ case 32:
+ return 299; /* wsr.m0 */
+ case 33:
+ return 302; /* wsr.m1 */
+ case 34:
+ return 305; /* wsr.m2 */
+ case 35:
+ return 308; /* wsr.m3 */
+ case 72:
+ return 21; /* wsr.windowbase */
+ case 73:
+ return 24; /* wsr.windowstart */
+ case 83:
+ return 415; /* wsr.ptevaddr */
+ case 89:
+ return 361; /* wsr.mmid */
+ case 90:
+ return 419; /* wsr.rasid */
+ case 91:
+ return 422; /* wsr.itlbcfg */
+ case 92:
+ return 425; /* wsr.dtlbcfg */
+ case 96:
+ return 345; /* wsr.ibreakenable */
+ case 104:
+ return 357; /* wsr.ddr */
+ case 128:
+ return 339; /* wsr.ibreaka0 */
+ case 129:
+ return 342; /* wsr.ibreaka1 */
+ case 144:
+ return 327; /* wsr.dbreaka0 */
+ case 145:
+ return 333; /* wsr.dbreaka1 */
+ case 160:
+ return 330; /* wsr.dbreakc0 */
+ case 161:
+ return 336; /* wsr.dbreakc1 */
+ case 177:
+ return 142; /* wsr.epc1 */
+ case 178:
+ return 148; /* wsr.epc2 */
+ case 179:
+ return 154; /* wsr.epc3 */
+ case 180:
+ return 160; /* wsr.epc4 */
+ case 181:
+ return 166; /* wsr.epc5 */
+ case 182:
+ return 172; /* wsr.epc6 */
+ case 183:
+ return 178; /* wsr.epc7 */
+ case 192:
+ return 205; /* wsr.depc */
+ case 194:
+ return 184; /* wsr.eps2 */
+ case 195:
+ return 187; /* wsr.eps3 */
+ case 196:
+ return 190; /* wsr.eps4 */
+ case 197:
+ return 193; /* wsr.eps5 */
+ case 198:
+ return 196; /* wsr.eps6 */
+ case 199:
+ return 199; /* wsr.eps7 */
+ case 209:
+ return 145; /* wsr.excsave1 */
+ case 210:
+ return 151; /* wsr.excsave2 */
+ case 211:
+ return 157; /* wsr.excsave3 */
+ case 212:
+ return 163; /* wsr.excsave4 */
+ case 213:
+ return 169; /* wsr.excsave5 */
+ case 214:
+ return 175; /* wsr.excsave6 */
+ case 215:
+ return 181; /* wsr.excsave7 */
+ case 224:
+ return 441; /* wsr.cpenable */
+ case 226:
+ return 319; /* wsr.intset */
+ case 227:
+ return 320; /* wsr.intclear */
+ case 228:
+ return 322; /* wsr.intenable */
+ case 230:
+ return 139; /* wsr.ps */
+ case 231:
+ return 224; /* wsr.vecbase */
+ case 232:
+ return 208; /* wsr.exccause */
+ case 233:
+ return 348; /* wsr.debugcause */
+ case 234:
+ return 379; /* wsr.ccount */
+ case 236:
+ return 351; /* wsr.icount */
+ case 237:
+ return 354; /* wsr.icountlevel */
+ case 238:
+ return 202; /* wsr.excvaddr */
+ case 240:
+ return 382; /* wsr.ccompare0 */
+ case 241:
+ return 385; /* wsr.ccompare1 */
+ case 242:
+ return 388; /* wsr.ccompare2 */
+ case 244:
+ return 211; /* wsr.misc0 */
+ case 245:
+ return 214; /* wsr.misc1 */
+ case 246:
+ return 217; /* wsr.misc2 */
+ case 247:
+ return 220; /* wsr.misc3 */
+ }
+ break;
+ case 2:
+ return 450; /* sext */
+ case 3:
+ return 443; /* clamps */
+ case 4:
+ return 444; /* min */
+ case 5:
+ return 445; /* max */
+ case 6:
+ return 446; /* minu */
+ case 7:
+ return 447; /* maxu */
+ case 8:
+ return 91; /* moveqz */
+ case 9:
+ return 92; /* movnez */
+ case 10:
+ return 93; /* movltz */
+ case 11:
+ return 94; /* movgez */
+ case 12:
+ return 373; /* movf */
+ case 13:
+ return 374; /* movt */
+ case 14:
+ switch (Field_st_Slot_inst_get (insn))
+ {
+ case 231:
+ return 37; /* rur.threadptr */
+ case 232:
+ return 464; /* rur.fcr */
+ case 233:
+ return 466; /* rur.fsr */
+ }
+ break;
+ case 15:
+ switch (Field_sr_Slot_inst_get (insn))
+ {
+ case 231:
+ return 38; /* wur.threadptr */
+ case 232:
+ return 465; /* wur.fcr */
+ case 233:
+ return 467; /* wur.fsr */
+ }
+ break;
+ }
+ break;
+ case 4:
+ case 5:
+ return 78; /* extui */
+ case 8:
+ switch (Field_op2_Slot_inst_get (insn))
+ {
+ case 0:
+ return 500; /* lsx */
+ case 1:
+ return 501; /* lsxu */
+ case 4:
+ return 504; /* ssx */
+ case 5:
+ return 505; /* ssxu */
+ }
+ break;
+ case 9:
+ switch (Field_op2_Slot_inst_get (insn))
+ {
+ case 0:
+ return 18; /* l32e */
+ case 4:
+ return 19; /* s32e */
+ }
+ break;
+ case 10:
+ switch (Field_op2_Slot_inst_get (insn))
+ {
+ case 0:
+ return 468; /* add.s */
+ case 1:
+ return 469; /* sub.s */
+ case 2:
+ return 470; /* mul.s */
+ case 4:
+ return 471; /* madd.s */
+ case 5:
+ return 472; /* msub.s */
+ case 8:
+ return 491; /* round.s */
+ case 9:
+ return 494; /* trunc.s */
+ case 10:
+ return 493; /* floor.s */
+ case 11:
+ return 492; /* ceil.s */
+ case 12:
+ return 489; /* float.s */
+ case 13:
+ return 490; /* ufloat.s */
+ case 14:
+ return 495; /* utrunc.s */
+ case 15:
+ switch (Field_t_Slot_inst_get (insn))
+ {
+ case 0:
+ return 480; /* mov.s */
+ case 1:
+ return 479; /* abs.s */
+ case 4:
+ return 496; /* rfr */
+ case 5:
+ return 497; /* wfr */
+ case 6:
+ return 481; /* neg.s */
+ }
+ break;
+ }
+ break;
+ case 11:
+ switch (Field_op2_Slot_inst_get (insn))
+ {
+ case 1:
+ return 482; /* un.s */
+ case 2:
+ return 483; /* oeq.s */
+ case 3:
+ return 484; /* ueq.s */
+ case 4:
+ return 485; /* olt.s */
+ case 5:
+ return 486; /* ult.s */
+ case 6:
+ return 487; /* ole.s */
+ case 7:
+ return 488; /* ule.s */
+ case 8:
+ return 475; /* moveqz.s */
+ case 9:
+ return 476; /* movnez.s */
+ case 10:
+ return 477; /* movltz.s */
+ case 11:
+ return 478; /* movgez.s */
+ case 12:
+ return 473; /* movf.s */
+ case 13:
+ return 474; /* movt.s */
+ }
+ break;
+ }
+ break;
+ case 1:
+ return 85; /* l32r */
+ case 2:
+ switch (Field_r_Slot_inst_get (insn))
+ {
+ case 0:
+ return 86; /* l8ui */
+ case 1:
+ return 82; /* l16ui */
+ case 2:
+ return 84; /* l32i */
+ case 4:
+ return 101; /* s8i */
+ case 5:
+ return 99; /* s16i */
+ case 6:
+ return 100; /* s32i */
+ case 7:
+ switch (Field_t_Slot_inst_get (insn))
+ {
+ case 0:
+ return 406; /* dpfr */
+ case 1:
+ return 407; /* dpfw */
+ case 2:
+ return 408; /* dpfro */
+ case 3:
+ return 409; /* dpfwo */
+ case 4:
+ return 400; /* dhwb */
+ case 5:
+ return 401; /* dhwbi */
+ case 6:
+ return 404; /* dhi */
+ case 7:
+ return 405; /* dii */
+ case 8:
+ switch (Field_op1_Slot_inst_get (insn))
+ {
+ case 0:
+ return 410; /* dpfl */
+ case 2:
+ return 411; /* dhu */
+ case 3:
+ return 412; /* diu */
+ case 4:
+ return 402; /* diwb */
+ case 5:
+ return 403; /* diwbi */
+ }
+ break;
+ case 12:
+ return 390; /* ipf */
+ case 13:
+ switch (Field_op1_Slot_inst_get (insn))
+ {
+ case 0:
+ return 392; /* ipfl */
+ case 2:
+ return 393; /* ihu */
+ case 3:
+ return 394; /* iiu */
+ }
+ break;
+ case 14:
+ return 391; /* ihi */
+ case 15:
+ return 395; /* iii */
+ }
+ break;
+ case 9:
+ return 83; /* l16si */
+ case 10:
+ return 90; /* movi */
+ case 11:
+ return 451; /* l32ai */
+ case 12:
+ return 39; /* addi */
+ case 13:
+ return 40; /* addmi */
+ case 14:
+ return 453; /* s32c1i */
+ case 15:
+ return 452; /* s32ri */
+ }
+ break;
+ case 3:
+ switch (Field_r_Slot_inst_get (insn))
+ {
+ case 0:
+ return 498; /* lsi */
+ case 4:
+ return 502; /* ssi */
+ case 8:
+ return 499; /* lsiu */
+ case 12:
+ return 503; /* ssiu */
+ }
+ break;
+ case 4:
+ switch (Field_op2_Slot_inst_get (insn))
+ {
+ case 0:
+ switch (Field_op1_Slot_inst_get (insn))
+ {
+ case 8:
+ if (Field_t3_Slot_inst_get (insn) == 0 &&
+ Field_tlo_Slot_inst_get (insn) == 0 &&
+ Field_r3_Slot_inst_get (insn) == 0)
+ return 287; /* mula.dd.ll.ldinc */
+ break;
+ case 9:
+ if (Field_t3_Slot_inst_get (insn) == 0 &&
+ Field_tlo_Slot_inst_get (insn) == 0 &&
+ Field_r3_Slot_inst_get (insn) == 0)
+ return 289; /* mula.dd.hl.ldinc */
+ break;
+ case 10:
+ if (Field_t3_Slot_inst_get (insn) == 0 &&
+ Field_tlo_Slot_inst_get (insn) == 0 &&
+ Field_r3_Slot_inst_get (insn) == 0)
+ return 291; /* mula.dd.lh.ldinc */
+ break;
+ case 11:
+ if (Field_t3_Slot_inst_get (insn) == 0 &&
+ Field_tlo_Slot_inst_get (insn) == 0 &&
+ Field_r3_Slot_inst_get (insn) == 0)
+ return 293; /* mula.dd.hh.ldinc */
+ break;
+ }
+ break;
+ case 1:
+ switch (Field_op1_Slot_inst_get (insn))
+ {
+ case 8:
+ if (Field_t3_Slot_inst_get (insn) == 0 &&
+ Field_tlo_Slot_inst_get (insn) == 0 &&
+ Field_r3_Slot_inst_get (insn) == 0)
+ return 286; /* mula.dd.ll.lddec */
+ break;
+ case 9:
+ if (Field_t3_Slot_inst_get (insn) == 0 &&
+ Field_tlo_Slot_inst_get (insn) == 0 &&
+ Field_r3_Slot_inst_get (insn) == 0)
+ return 288; /* mula.dd.hl.lddec */
+ break;
+ case 10:
+ if (Field_t3_Slot_inst_get (insn) == 0 &&
+ Field_tlo_Slot_inst_get (insn) == 0 &&
+ Field_r3_Slot_inst_get (insn) == 0)
+ return 290; /* mula.dd.lh.lddec */
+ break;
+ case 11:
+ if (Field_t3_Slot_inst_get (insn) == 0 &&
+ Field_tlo_Slot_inst_get (insn) == 0 &&
+ Field_r3_Slot_inst_get (insn) == 0)
+ return 292; /* mula.dd.hh.lddec */
+ break;
+ }
+ break;
+ case 2:
+ switch (Field_op1_Slot_inst_get (insn))
+ {
+ case 4:
+ if (Field_s_Slot_inst_get (insn) == 0 &&
+ Field_w_Slot_inst_get (insn) == 0 &&
+ Field_r3_Slot_inst_get (insn) == 0 &&
+ Field_t3_Slot_inst_get (insn) == 0 &&
+ Field_tlo_Slot_inst_get (insn) == 0)
+ return 242; /* mul.dd.ll */
+ break;
+ case 5:
+ if (Field_s_Slot_inst_get (insn) == 0 &&
+ Field_w_Slot_inst_get (insn) == 0 &&
+ Field_r3_Slot_inst_get (insn) == 0 &&
+ Field_t3_Slot_inst_get (insn) == 0 &&
+ Field_tlo_Slot_inst_get (insn) == 0)
+ return 243; /* mul.dd.hl */
+ break;
+ case 6:
+ if (Field_s_Slot_inst_get (insn) == 0 &&
+ Field_w_Slot_inst_get (insn) == 0 &&
+ Field_r3_Slot_inst_get (insn) == 0 &&
+ Field_t3_Slot_inst_get (insn) == 0 &&
+ Field_tlo_Slot_inst_get (insn) == 0)
+ return 244; /* mul.dd.lh */
+ break;
+ case 7:
+ if (Field_s_Slot_inst_get (insn) == 0 &&
+ Field_w_Slot_inst_get (insn) == 0 &&
+ Field_r3_Slot_inst_get (insn) == 0 &&
+ Field_t3_Slot_inst_get (insn) == 0 &&
+ Field_tlo_Slot_inst_get (insn) == 0)
+ return 245; /* mul.dd.hh */
+ break;
+ case 8:
+ if (Field_s_Slot_inst_get (insn) == 0 &&
+ Field_w_Slot_inst_get (insn) == 0 &&
+ Field_r3_Slot_inst_get (insn) == 0 &&
+ Field_t3_Slot_inst_get (insn) == 0 &&
+ Field_tlo_Slot_inst_get (insn) == 0)
+ return 270; /* mula.dd.ll */
+ break;
+ case 9:
+ if (Field_s_Slot_inst_get (insn) == 0 &&
+ Field_w_Slot_inst_get (insn) == 0 &&
+ Field_r3_Slot_inst_get (insn) == 0 &&
+ Field_t3_Slot_inst_get (insn) == 0 &&
+ Field_tlo_Slot_inst_get (insn) == 0)
+ return 271; /* mula.dd.hl */
+ break;
+ case 10:
+ if (Field_s_Slot_inst_get (insn) == 0 &&
+ Field_w_Slot_inst_get (insn) == 0 &&
+ Field_r3_Slot_inst_get (insn) == 0 &&
+ Field_t3_Slot_inst_get (insn) == 0 &&
+ Field_tlo_Slot_inst_get (insn) == 0)
+ return 272; /* mula.dd.lh */
+ break;
+ case 11:
+ if (Field_s_Slot_inst_get (insn) == 0 &&
+ Field_w_Slot_inst_get (insn) == 0 &&
+ Field_r3_Slot_inst_get (insn) == 0 &&
+ Field_t3_Slot_inst_get (insn) == 0 &&
+ Field_tlo_Slot_inst_get (insn) == 0)
+ return 273; /* mula.dd.hh */
+ break;
+ case 12:
+ if (Field_s_Slot_inst_get (insn) == 0 &&
+ Field_w_Slot_inst_get (insn) == 0 &&
+ Field_r3_Slot_inst_get (insn) == 0 &&
+ Field_t3_Slot_inst_get (insn) == 0 &&
+ Field_tlo_Slot_inst_get (insn) == 0)
+ return 274; /* muls.dd.ll */
+ break;
+ case 13:
+ if (Field_s_Slot_inst_get (insn) == 0 &&
+ Field_w_Slot_inst_get (insn) == 0 &&
+ Field_r3_Slot_inst_get (insn) == 0 &&
+ Field_t3_Slot_inst_get (insn) == 0 &&
+ Field_tlo_Slot_inst_get (insn) == 0)
+ return 275; /* muls.dd.hl */
+ break;
+ case 14:
+ if (Field_s_Slot_inst_get (insn) == 0 &&
+ Field_w_Slot_inst_get (insn) == 0 &&
+ Field_r3_Slot_inst_get (insn) == 0 &&
+ Field_t3_Slot_inst_get (insn) == 0 &&
+ Field_tlo_Slot_inst_get (insn) == 0)
+ return 276; /* muls.dd.lh */
+ break;
+ case 15:
+ if (Field_s_Slot_inst_get (insn) == 0 &&
+ Field_w_Slot_inst_get (insn) == 0 &&
+ Field_r3_Slot_inst_get (insn) == 0 &&
+ Field_t3_Slot_inst_get (insn) == 0 &&
+ Field_tlo_Slot_inst_get (insn) == 0)
+ return 277; /* muls.dd.hh */
+ break;
+ }
+ break;
+ case 3:
+ switch (Field_op1_Slot_inst_get (insn))
+ {
+ case 4:
+ if (Field_r_Slot_inst_get (insn) == 0 &&
+ Field_t3_Slot_inst_get (insn) == 0 &&
+ Field_tlo_Slot_inst_get (insn) == 0)
+ return 234; /* mul.ad.ll */
+ break;
+ case 5:
+ if (Field_r_Slot_inst_get (insn) == 0 &&
+ Field_t3_Slot_inst_get (insn) == 0 &&
+ Field_tlo_Slot_inst_get (insn) == 0)
+ return 235; /* mul.ad.hl */
+ break;
+ case 6:
+ if (Field_r_Slot_inst_get (insn) == 0 &&
+ Field_t3_Slot_inst_get (insn) == 0 &&
+ Field_tlo_Slot_inst_get (insn) == 0)
+ return 236; /* mul.ad.lh */
+ break;
+ case 7:
+ if (Field_r_Slot_inst_get (insn) == 0 &&
+ Field_t3_Slot_inst_get (insn) == 0 &&
+ Field_tlo_Slot_inst_get (insn) == 0)
+ return 237; /* mul.ad.hh */
+ break;
+ case 8:
+ if (Field_r_Slot_inst_get (insn) == 0 &&
+ Field_t3_Slot_inst_get (insn) == 0 &&
+ Field_tlo_Slot_inst_get (insn) == 0)
+ return 254; /* mula.ad.ll */
+ break;
+ case 9:
+ if (Field_r_Slot_inst_get (insn) == 0 &&
+ Field_t3_Slot_inst_get (insn) == 0 &&
+ Field_tlo_Slot_inst_get (insn) == 0)
+ return 255; /* mula.ad.hl */
+ break;
+ case 10:
+ if (Field_r_Slot_inst_get (insn) == 0 &&
+ Field_t3_Slot_inst_get (insn) == 0 &&
+ Field_tlo_Slot_inst_get (insn) == 0)
+ return 256; /* mula.ad.lh */
+ break;
+ case 11:
+ if (Field_r_Slot_inst_get (insn) == 0 &&
+ Field_t3_Slot_inst_get (insn) == 0 &&
+ Field_tlo_Slot_inst_get (insn) == 0)
+ return 257; /* mula.ad.hh */
+ break;
+ case 12:
+ if (Field_r_Slot_inst_get (insn) == 0 &&
+ Field_t3_Slot_inst_get (insn) == 0 &&
+ Field_tlo_Slot_inst_get (insn) == 0)
+ return 258; /* muls.ad.ll */
+ break;
+ case 13:
+ if (Field_r_Slot_inst_get (insn) == 0 &&
+ Field_t3_Slot_inst_get (insn) == 0 &&
+ Field_tlo_Slot_inst_get (insn) == 0)
+ return 259; /* muls.ad.hl */
+ break;
+ case 14:
+ if (Field_r_Slot_inst_get (insn) == 0 &&
+ Field_t3_Slot_inst_get (insn) == 0 &&
+ Field_tlo_Slot_inst_get (insn) == 0)
+ return 260; /* muls.ad.lh */
+ break;
+ case 15:
+ if (Field_r_Slot_inst_get (insn) == 0 &&
+ Field_t3_Slot_inst_get (insn) == 0 &&
+ Field_tlo_Slot_inst_get (insn) == 0)
+ return 261; /* muls.ad.hh */
+ break;
+ }
+ break;
+ case 4:
+ switch (Field_op1_Slot_inst_get (insn))
+ {
+ case 8:
+ if (Field_r3_Slot_inst_get (insn) == 0)
+ return 279; /* mula.da.ll.ldinc */
+ break;
+ case 9:
+ if (Field_r3_Slot_inst_get (insn) == 0)
+ return 281; /* mula.da.hl.ldinc */
+ break;
+ case 10:
+ if (Field_r3_Slot_inst_get (insn) == 0)
+ return 283; /* mula.da.lh.ldinc */
+ break;
+ case 11:
+ if (Field_r3_Slot_inst_get (insn) == 0)
+ return 285; /* mula.da.hh.ldinc */
+ break;
+ }
+ break;
+ case 5:
+ switch (Field_op1_Slot_inst_get (insn))
+ {
+ case 8:
+ if (Field_r3_Slot_inst_get (insn) == 0)
+ return 278; /* mula.da.ll.lddec */
+ break;
+ case 9:
+ if (Field_r3_Slot_inst_get (insn) == 0)
+ return 280; /* mula.da.hl.lddec */
+ break;
+ case 10:
+ if (Field_r3_Slot_inst_get (insn) == 0)
+ return 282; /* mula.da.lh.lddec */
+ break;
+ case 11:
+ if (Field_r3_Slot_inst_get (insn) == 0)
+ return 284; /* mula.da.hh.lddec */
+ break;
+ }
+ break;
+ case 6:
+ switch (Field_op1_Slot_inst_get (insn))
+ {
+ case 4:
+ if (Field_s_Slot_inst_get (insn) == 0 &&
+ Field_w_Slot_inst_get (insn) == 0 &&
+ Field_r3_Slot_inst_get (insn) == 0)
+ return 238; /* mul.da.ll */
+ break;
+ case 5:
+ if (Field_s_Slot_inst_get (insn) == 0 &&
+ Field_w_Slot_inst_get (insn) == 0 &&
+ Field_r3_Slot_inst_get (insn) == 0)
+ return 239; /* mul.da.hl */
+ break;
+ case 6:
+ if (Field_s_Slot_inst_get (insn) == 0 &&
+ Field_w_Slot_inst_get (insn) == 0 &&
+ Field_r3_Slot_inst_get (insn) == 0)
+ return 240; /* mul.da.lh */
+ break;
+ case 7:
+ if (Field_s_Slot_inst_get (insn) == 0 &&
+ Field_w_Slot_inst_get (insn) == 0 &&
+ Field_r3_Slot_inst_get (insn) == 0)
+ return 241; /* mul.da.hh */
+ break;
+ case 8:
+ if (Field_s_Slot_inst_get (insn) == 0 &&
+ Field_w_Slot_inst_get (insn) == 0 &&
+ Field_r3_Slot_inst_get (insn) == 0)
+ return 262; /* mula.da.ll */
+ break;
+ case 9:
+ if (Field_s_Slot_inst_get (insn) == 0 &&
+ Field_w_Slot_inst_get (insn) == 0 &&
+ Field_r3_Slot_inst_get (insn) == 0)
+ return 263; /* mula.da.hl */
+ break;
+ case 10:
+ if (Field_s_Slot_inst_get (insn) == 0 &&
+ Field_w_Slot_inst_get (insn) == 0 &&
+ Field_r3_Slot_inst_get (insn) == 0)
+ return 264; /* mula.da.lh */
+ break;
+ case 11:
+ if (Field_s_Slot_inst_get (insn) == 0 &&
+ Field_w_Slot_inst_get (insn) == 0 &&
+ Field_r3_Slot_inst_get (insn) == 0)
+ return 265; /* mula.da.hh */
+ break;
+ case 12:
+ if (Field_s_Slot_inst_get (insn) == 0 &&
+ Field_w_Slot_inst_get (insn) == 0 &&
+ Field_r3_Slot_inst_get (insn) == 0)
+ return 266; /* muls.da.ll */
+ break;
+ case 13:
+ if (Field_s_Slot_inst_get (insn) == 0 &&
+ Field_w_Slot_inst_get (insn) == 0 &&
+ Field_r3_Slot_inst_get (insn) == 0)
+ return 267; /* muls.da.hl */
+ break;
+ case 14:
+ if (Field_s_Slot_inst_get (insn) == 0 &&
+ Field_w_Slot_inst_get (insn) == 0 &&
+ Field_r3_Slot_inst_get (insn) == 0)
+ return 268; /* muls.da.lh */
+ break;
+ case 15:
+ if (Field_s_Slot_inst_get (insn) == 0 &&
+ Field_w_Slot_inst_get (insn) == 0 &&
+ Field_r3_Slot_inst_get (insn) == 0)
+ return 269; /* muls.da.hh */
+ break;
+ }
+ break;
+ case 7:
+ switch (Field_op1_Slot_inst_get (insn))
+ {
+ case 0:
+ if (Field_r_Slot_inst_get (insn) == 0)
+ return 230; /* umul.aa.ll */
+ break;
+ case 1:
+ if (Field_r_Slot_inst_get (insn) == 0)
+ return 231; /* umul.aa.hl */
+ break;
+ case 2:
+ if (Field_r_Slot_inst_get (insn) == 0)
+ return 232; /* umul.aa.lh */
+ break;
+ case 3:
+ if (Field_r_Slot_inst_get (insn) == 0)
+ return 233; /* umul.aa.hh */
+ break;
+ case 4:
+ if (Field_r_Slot_inst_get (insn) == 0)
+ return 226; /* mul.aa.ll */
+ break;
+ case 5:
+ if (Field_r_Slot_inst_get (insn) == 0)
+ return 227; /* mul.aa.hl */
+ break;
+ case 6:
+ if (Field_r_Slot_inst_get (insn) == 0)
+ return 228; /* mul.aa.lh */
+ break;
+ case 7:
+ if (Field_r_Slot_inst_get (insn) == 0)
+ return 229; /* mul.aa.hh */
+ break;
+ case 8:
+ if (Field_r_Slot_inst_get (insn) == 0)
+ return 246; /* mula.aa.ll */
+ break;
+ case 9:
+ if (Field_r_Slot_inst_get (insn) == 0)
+ return 247; /* mula.aa.hl */
+ break;
+ case 10:
+ if (Field_r_Slot_inst_get (insn) == 0)
+ return 248; /* mula.aa.lh */
+ break;
+ case 11:
+ if (Field_r_Slot_inst_get (insn) == 0)
+ return 249; /* mula.aa.hh */
+ break;
+ case 12:
+ if (Field_r_Slot_inst_get (insn) == 0)
+ return 250; /* muls.aa.ll */
+ break;
+ case 13:
+ if (Field_r_Slot_inst_get (insn) == 0)
+ return 251; /* muls.aa.hl */
+ break;
+ case 14:
+ if (Field_r_Slot_inst_get (insn) == 0)
+ return 252; /* muls.aa.lh */
+ break;
+ case 15:
+ if (Field_r_Slot_inst_get (insn) == 0)
+ return 253; /* muls.aa.hh */
+ break;
+ }
+ break;
+ case 8:
+ if (Field_op1_Slot_inst_get (insn) == 0 &&
+ Field_t_Slot_inst_get (insn) == 0 &&
+ Field_rhi_Slot_inst_get (insn) == 0)
+ return 295; /* ldinc */
+ break;
+ case 9:
+ if (Field_op1_Slot_inst_get (insn) == 0 &&
+ Field_t_Slot_inst_get (insn) == 0 &&
+ Field_rhi_Slot_inst_get (insn) == 0)
+ return 294; /* lddec */
+ break;
+ }
+ break;
+ case 5:
+ switch (Field_n_Slot_inst_get (insn))
+ {
+ case 0:
+ return 76; /* call0 */
+ case 1:
+ return 7; /* call4 */
+ case 2:
+ return 6; /* call8 */
+ case 3:
+ return 5; /* call12 */
+ }
+ break;
+ case 6:
+ switch (Field_n_Slot_inst_get (insn))
+ {
+ case 0:
+ return 80; /* j */
+ case 1:
+ switch (Field_m_Slot_inst_get (insn))
+ {
+ case 0:
+ return 72; /* beqz */
+ case 1:
+ return 73; /* bnez */
+ case 2:
+ return 75; /* bltz */
+ case 3:
+ return 74; /* bgez */
+ }
+ break;
+ case 2:
+ switch (Field_m_Slot_inst_get (insn))
+ {
+ case 0:
+ return 52; /* beqi */
+ case 1:
+ return 53; /* bnei */
+ case 2:
+ return 55; /* blti */
+ case 3:
+ return 54; /* bgei */
+ }
+ break;
+ case 3:
+ switch (Field_m_Slot_inst_get (insn))
+ {
+ case 0:
+ return 11; /* entry */
+ case 1:
+ switch (Field_r_Slot_inst_get (insn))
+ {
+ case 0:
+ return 371; /* bf */
+ case 1:
+ return 372; /* bt */
+ case 8:
+ return 87; /* loop */
+ case 9:
+ return 88; /* loopnez */
+ case 10:
+ return 89; /* loopgtz */
+ }
+ break;
+ case 2:
+ return 59; /* bltui */
+ case 3:
+ return 58; /* bgeui */
+ }
+ break;
+ }
+ break;
+ case 7:
+ switch (Field_r_Slot_inst_get (insn))
+ {
+ case 0:
+ return 67; /* bnone */
+ case 1:
+ return 60; /* beq */
+ case 2:
+ return 63; /* blt */
+ case 3:
+ return 65; /* bltu */
+ case 4:
+ return 68; /* ball */
+ case 5:
+ return 70; /* bbc */
+ case 6:
+ case 7:
+ return 56; /* bbci */
+ case 8:
+ return 66; /* bany */
+ case 9:
+ return 61; /* bne */
+ case 10:
+ return 62; /* bge */
+ case 11:
+ return 64; /* bgeu */
+ case 12:
+ return 69; /* bnall */
+ case 13:
+ return 71; /* bbs */
+ case 14:
+ case 15:
+ return 57; /* bbsi */
+ }
+ break;
+ }
+ return 0;
+}
+
+static int
+Slot_inst16b_decode (const xtensa_insnbuf insn)
+{
+ switch (Field_op0_Slot_inst16b_get (insn))
+ {
+ case 12:
+ switch (Field_i_Slot_inst16b_get (insn))
+ {
+ case 0:
+ return 33; /* movi.n */
+ case 1:
+ switch (Field_z_Slot_inst16b_get (insn))
+ {
+ case 0:
+ return 28; /* beqz.n */
+ case 1:
+ return 29; /* bnez.n */
+ }
+ break;
+ }
+ break;
+ case 13:
+ switch (Field_r_Slot_inst16b_get (insn))
+ {
+ case 0:
+ return 32; /* mov.n */
+ case 15:
+ switch (Field_t_Slot_inst16b_get (insn))
+ {
+ case 0:
+ return 35; /* ret.n */
+ case 1:
+ return 15; /* retw.n */
+ case 2:
+ return 325; /* break.n */
+ case 3:
+ if (Field_s_Slot_inst16b_get (insn) == 0)
+ return 34; /* nop.n */
+ break;
+ case 6:
+ if (Field_s_Slot_inst16b_get (insn) == 0)
+ return 30; /* ill.n */
+ break;
+ }
+ break;
+ }
+ break;
+ }
+ return 0;
+}
+
+static int
+Slot_inst16a_decode (const xtensa_insnbuf insn)
+{
+ switch (Field_op0_Slot_inst16a_get (insn))
+ {
+ case 8:
+ return 31; /* l32i.n */
+ case 9:
+ return 36; /* s32i.n */
+ case 10:
+ return 26; /* add.n */
+ case 11:
+ return 27; /* addi.n */
+ }
+ return 0;
+}
+
+static int
+Slot_xt_flix64_slot2_decode (const xtensa_insnbuf insn)
+{
+ switch (Field_combined3e2c5767_fld36xt_flix64_slot2_Slot_xt_flix64_slot2_get (insn))
+ {
+ case 0:
+ if (Field_op0_s5_Slot_xt_flix64_slot2_get (insn) == 1)
+ return 41; /* add */
+ if (Field_op0_s5_Slot_xt_flix64_slot2_get (insn) == 5)
+ return 42; /* sub */
+ if (Field_op0_s5_Slot_xt_flix64_slot2_get (insn) == 2)
+ return 43; /* addx2 */
+ if (Field_op0_s5_Slot_xt_flix64_slot2_get (insn) == 3)
+ return 49; /* and */
+ if (Field_op0_s5_Slot_xt_flix64_slot2_get (insn) == 4)
+ return 450; /* sext */
+ break;
+ case 1:
+ if (Field_op0_s5_Slot_xt_flix64_slot2_get (insn) == 1)
+ return 27; /* addi.n */
+ if (Field_op0_s5_Slot_xt_flix64_slot2_get (insn) == 2)
+ return 44; /* addx4 */
+ if (Field_op0_s5_Slot_xt_flix64_slot2_get (insn) == 3)
+ return 50; /* or */
+ if (Field_op0_s5_Slot_xt_flix64_slot2_get (insn) == 5)
+ return 51; /* xor */
+ if (Field_op0_s5_Slot_xt_flix64_slot2_get (insn) == 4)
+ return 113; /* srli */
+ break;
+ }
+ if (Field_combined3e2c5767_fld37xt_flix64_slot2_Slot_xt_flix64_slot2_get (insn) == 0 &&
+ Field_op0_s5_Slot_xt_flix64_slot2_get (insn) == 6)
+ return 33; /* movi.n */
+ if (Field_combined3e2c5767_fld39xt_flix64_slot2_Slot_xt_flix64_slot2_get (insn) == 2 &&
+ Field_op0_s5_Slot_xt_flix64_slot2_get (insn) == 6 &&
+ Field_combined3e2c5767_fld63xt_flix64_slot2_Slot_xt_flix64_slot2_get (insn) == 0)
+ return 32; /* mov.n */
+ if (Field_combined3e2c5767_fld41xt_flix64_slot2_Slot_xt_flix64_slot2_get (insn) == 3 &&
+ Field_op0_s5_Slot_xt_flix64_slot2_get (insn) == 6 &&
+ Field_combined3e2c5767_fld65xt_flix64_slot2_Slot_xt_flix64_slot2_get (insn) == 0)
+ return 97; /* nop */
+ if (Field_combined3e2c5767_fld42xt_flix64_slot2_Slot_xt_flix64_slot2_get (insn) == 8 &&
+ Field_op0_s5_Slot_xt_flix64_slot2_get (insn) == 6 &&
+ Field_combined3e2c5767_fld64xt_flix64_slot2_Slot_xt_flix64_slot2_get (insn) == 0)
+ return 96; /* abs */
+ if (Field_combined3e2c5767_fld44xt_flix64_slot2_Slot_xt_flix64_slot2_get (insn) == 9 &&
+ Field_op0_s5_Slot_xt_flix64_slot2_get (insn) == 6 &&
+ Field_combined3e2c5767_fld64xt_flix64_slot2_Slot_xt_flix64_slot2_get (insn) == 0)
+ return 95; /* neg */
+ if (Field_combined3e2c5767_fld45xt_flix64_slot2_Slot_xt_flix64_slot2_get (insn) == 5 &&
+ Field_op0_s5_Slot_xt_flix64_slot2_get (insn) == 6 &&
+ Field_combined3e2c5767_fld66xt_flix64_slot2_Slot_xt_flix64_slot2_get (insn) == 0)
+ return 110; /* sra */
+ if (Field_combined3e2c5767_fld47xt_flix64_slot2_Slot_xt_flix64_slot2_get (insn) == 3 &&
+ Field_op0_s5_Slot_xt_flix64_slot2_get (insn) == 6 &&
+ Field_combined3e2c5767_fld68xt_flix64_slot2_Slot_xt_flix64_slot2_get (insn) == 0)
+ return 109; /* srl */
+ if (Field_op0_s5_Slot_xt_flix64_slot2_get (insn) == 7)
+ return 112; /* srai */
+ return 0;
+}
+
+static int
+Slot_xt_flix64_slot0_decode (const xtensa_insnbuf insn)
+{
+ switch (Field_op0_xt_flix64_slot0_Slot_xt_flix64_slot0_get (insn))
+ {
+ case 0:
+ if (Field_combined3e2c5767_fld7_Slot_xt_flix64_slot0_get (insn) == 2)
+ return 78; /* extui */
+ switch (Field_op1_Slot_xt_flix64_slot0_get (insn))
+ {
+ case 0:
+ switch (Field_op2_Slot_xt_flix64_slot0_get (insn))
+ {
+ case 0:
+ if (Field_r_Slot_xt_flix64_slot0_get (insn) == 2)
+ {
+ if (Field_s_Slot_xt_flix64_slot0_get (insn) == 0)
+ {
+ if (Field_t_Slot_xt_flix64_slot0_get (insn) == 15)
+ return 97; /* nop */
+ }
+ }
+ break;
+ case 1:
+ return 49; /* and */
+ case 2:
+ return 50; /* or */
+ case 3:
+ return 51; /* xor */
+ case 4:
+ switch (Field_r_Slot_xt_flix64_slot0_get (insn))
+ {
+ case 0:
+ if (Field_t_Slot_xt_flix64_slot0_get (insn) == 0)
+ return 102; /* ssr */
+ break;
+ case 1:
+ if (Field_t_Slot_xt_flix64_slot0_get (insn) == 0)
+ return 103; /* ssl */
+ break;
+ case 2:
+ if (Field_t_Slot_xt_flix64_slot0_get (insn) == 0)
+ return 104; /* ssa8l */
+ break;
+ case 3:
+ if (Field_t_Slot_xt_flix64_slot0_get (insn) == 0)
+ return 105; /* ssa8b */
+ break;
+ case 4:
+ if (Field_thi3_Slot_xt_flix64_slot0_get (insn) == 0)
+ return 106; /* ssai */
+ break;
+ case 14:
+ return 448; /* nsa */
+ case 15:
+ return 449; /* nsau */
+ }
+ break;
+ case 6:
+ switch (Field_s_Slot_xt_flix64_slot0_get (insn))
+ {
+ case 0:
+ return 95; /* neg */
+ case 1:
+ return 96; /* abs */
+ }
+ break;
+ case 8:
+ return 41; /* add */
+ case 9:
+ return 43; /* addx2 */
+ case 10:
+ return 44; /* addx4 */
+ case 11:
+ return 45; /* addx8 */
+ case 12:
+ return 42; /* sub */
+ case 13:
+ return 46; /* subx2 */
+ case 14:
+ return 47; /* subx4 */
+ case 15:
+ return 48; /* subx8 */
+ }
+ break;
+ case 1:
+ if (Field_combined3e2c5767_fld11_Slot_xt_flix64_slot0_get (insn) == 1)
+ return 112; /* srai */
+ if (Field_combined3e2c5767_fld9_Slot_xt_flix64_slot0_get (insn) == 0)
+ return 111; /* slli */
+ switch (Field_op2_Slot_xt_flix64_slot0_get (insn))
+ {
+ case 4:
+ return 113; /* srli */
+ case 8:
+ return 108; /* src */
+ case 9:
+ if (Field_s_Slot_xt_flix64_slot0_get (insn) == 0)
+ return 109; /* srl */
+ break;
+ case 10:
+ if (Field_t_Slot_xt_flix64_slot0_get (insn) == 0)
+ return 107; /* sll */
+ break;
+ case 11:
+ if (Field_s_Slot_xt_flix64_slot0_get (insn) == 0)
+ return 110; /* sra */
+ break;
+ case 12:
+ return 296; /* mul16u */
+ case 13:
+ return 297; /* mul16s */
+ }
+ break;
+ case 2:
+ if (Field_op2_Slot_xt_flix64_slot0_get (insn) == 8)
+ return 461; /* mull */
+ break;
+ case 3:
+ switch (Field_op2_Slot_xt_flix64_slot0_get (insn))
+ {
+ case 2:
+ return 450; /* sext */
+ case 3:
+ return 443; /* clamps */
+ case 4:
+ return 444; /* min */
+ case 5:
+ return 445; /* max */
+ case 6:
+ return 446; /* minu */
+ case 7:
+ return 447; /* maxu */
+ case 8:
+ return 91; /* moveqz */
+ case 9:
+ return 92; /* movnez */
+ case 10:
+ return 93; /* movltz */
+ case 11:
+ return 94; /* movgez */
+ }
+ break;
+ }
+ break;
+ case 2:
+ switch (Field_r_Slot_xt_flix64_slot0_get (insn))
+ {
+ case 0:
+ return 86; /* l8ui */
+ case 1:
+ return 82; /* l16ui */
+ case 2:
+ return 84; /* l32i */
+ case 4:
+ return 101; /* s8i */
+ case 5:
+ return 99; /* s16i */
+ case 6:
+ return 100; /* s32i */
+ case 9:
+ return 83; /* l16si */
+ case 10:
+ return 90; /* movi */
+ case 12:
+ return 39; /* addi */
+ case 13:
+ return 40; /* addmi */
+ }
+ break;
+ }
+ if (Field_op0_xt_flix64_slot0_s3_Slot_xt_flix64_slot0_get (insn) == 1)
+ return 85; /* l32r */
+ if (Field_sae4_Slot_xt_flix64_slot0_get (insn) == 0 &&
+ Field_combined3e2c5767_fld8_Slot_xt_flix64_slot0_get (insn) == 3 &&
+ Field_op0_xt_flix64_slot0_s3_Slot_xt_flix64_slot0_get (insn) == 0 &&
+ Field_combined3e2c5767_fld49xt_flix64_slot0_Slot_xt_flix64_slot0_get (insn) == 0)
+ return 32; /* mov.n */
+ return 0;
+}
+
+static int
+Slot_xt_flix64_slot1_decode (const xtensa_insnbuf insn)
+{
+ if (Field_combined3e2c5767_fld19xt_flix64_slot1_Slot_xt_flix64_slot1_get (insn) == 0 &&
+ Field_op0_s4_Slot_xt_flix64_slot1_get (insn) == 1)
+ return 78; /* extui */
+ switch (Field_combined3e2c5767_fld20xt_flix64_slot1_Slot_xt_flix64_slot1_get (insn))
+ {
+ case 0:
+ if (Field_op0_s4_Slot_xt_flix64_slot1_get (insn) == 2)
+ return 90; /* movi */
+ break;
+ case 2:
+ if (Field_op0_s4_Slot_xt_flix64_slot1_get (insn) == 1)
+ return 39; /* addi */
+ break;
+ case 3:
+ if (Field_op0_s4_Slot_xt_flix64_slot1_get (insn) == 1)
+ return 40; /* addmi */
+ if (Field_op0_s4_Slot_xt_flix64_slot1_get (insn) == 2 &&
+ Field_combined3e2c5767_fld16_Slot_xt_flix64_slot1_get (insn) == 0)
+ return 51; /* xor */
+ break;
+ }
+ switch (Field_combined3e2c5767_fld21xt_flix64_slot1_Slot_xt_flix64_slot1_get (insn))
+ {
+ case 8:
+ if (Field_op0_s4_Slot_xt_flix64_slot1_get (insn) == 2)
+ return 111; /* slli */
+ break;
+ case 16:
+ if (Field_op0_s4_Slot_xt_flix64_slot1_get (insn) == 2)
+ return 112; /* srai */
+ break;
+ case 19:
+ if (Field_op0_s4_Slot_xt_flix64_slot1_get (insn) == 2 &&
+ Field_combined3e2c5767_fld57xt_flix64_slot1_Slot_xt_flix64_slot1_get (insn) == 0)
+ return 107; /* sll */
+ break;
+ }
+ switch (Field_combined3e2c5767_fld22xt_flix64_slot1_Slot_xt_flix64_slot1_get (insn))
+ {
+ case 18:
+ if (Field_op0_s4_Slot_xt_flix64_slot1_get (insn) == 2)
+ return 41; /* add */
+ break;
+ case 19:
+ if (Field_op0_s4_Slot_xt_flix64_slot1_get (insn) == 2)
+ return 45; /* addx8 */
+ break;
+ case 20:
+ if (Field_op0_s4_Slot_xt_flix64_slot1_get (insn) == 2)
+ return 43; /* addx2 */
+ break;
+ case 21:
+ if (Field_op0_s4_Slot_xt_flix64_slot1_get (insn) == 2)
+ return 49; /* and */
+ break;
+ case 22:
+ if (Field_op0_s4_Slot_xt_flix64_slot1_get (insn) == 2)
+ return 91; /* moveqz */
+ break;
+ case 23:
+ if (Field_op0_s4_Slot_xt_flix64_slot1_get (insn) == 2)
+ return 94; /* movgez */
+ break;
+ case 24:
+ if (Field_op0_s4_Slot_xt_flix64_slot1_get (insn) == 2)
+ return 44; /* addx4 */
+ break;
+ case 25:
+ if (Field_op0_s4_Slot_xt_flix64_slot1_get (insn) == 2)
+ return 93; /* movltz */
+ break;
+ case 26:
+ if (Field_op0_s4_Slot_xt_flix64_slot1_get (insn) == 2)
+ return 92; /* movnez */
+ break;
+ case 27:
+ if (Field_op0_s4_Slot_xt_flix64_slot1_get (insn) == 2)
+ return 296; /* mul16u */
+ break;
+ case 28:
+ if (Field_op0_s4_Slot_xt_flix64_slot1_get (insn) == 2)
+ return 297; /* mul16s */
+ break;
+ case 29:
+ if (Field_op0_s4_Slot_xt_flix64_slot1_get (insn) == 2)
+ return 461; /* mull */
+ break;
+ case 30:
+ if (Field_op0_s4_Slot_xt_flix64_slot1_get (insn) == 2)
+ return 50; /* or */
+ break;
+ case 31:
+ if (Field_op0_s4_Slot_xt_flix64_slot1_get (insn) == 2)
+ return 450; /* sext */
+ break;
+ case 34:
+ if (Field_op0_s4_Slot_xt_flix64_slot1_get (insn) == 2)
+ return 108; /* src */
+ break;
+ case 36:
+ if (Field_op0_s4_Slot_xt_flix64_slot1_get (insn) == 2)
+ return 113; /* srli */
+ break;
+ }
+ if (Field_combined3e2c5767_fld23xt_flix64_slot1_Slot_xt_flix64_slot1_get (insn) == 280 &&
+ Field_op0_s4_Slot_xt_flix64_slot1_get (insn) == 2 &&
+ Field_combined3e2c5767_fld51xt_flix64_slot1_Slot_xt_flix64_slot1_get (insn) == 0)
+ return 32; /* mov.n */
+ if (Field_combined3e2c5767_fld25xt_flix64_slot1_Slot_xt_flix64_slot1_get (insn) == 281 &&
+ Field_op0_s4_Slot_xt_flix64_slot1_get (insn) == 2 &&
+ Field_combined3e2c5767_fld52xt_flix64_slot1_Slot_xt_flix64_slot1_get (insn) == 0)
+ return 81; /* jx */
+ if (Field_combined3e2c5767_fld26xt_flix64_slot1_Slot_xt_flix64_slot1_get (insn) == 141 &&
+ Field_op0_s4_Slot_xt_flix64_slot1_get (insn) == 2 &&
+ Field_combined3e2c5767_fld60xt_flix64_slot1_Slot_xt_flix64_slot1_get (insn) == 0)
+ return 103; /* ssl */
+ if (Field_combined3e2c5767_fld28xt_flix64_slot1_Slot_xt_flix64_slot1_get (insn) == 71 &&
+ Field_op0_s4_Slot_xt_flix64_slot1_get (insn) == 2 &&
+ Field_combined3e2c5767_fld54xt_flix64_slot1_Slot_xt_flix64_slot1_get (insn) == 0)
+ return 97; /* nop */
+ if (Field_combined3e2c5767_fld30xt_flix64_slot1_Slot_xt_flix64_slot1_get (insn) == 148 &&
+ Field_op0_s4_Slot_xt_flix64_slot1_get (insn) == 2 &&
+ Field_combined3e2c5767_fld53xt_flix64_slot1_Slot_xt_flix64_slot1_get (insn) == 0)
+ return 95; /* neg */
+ if (Field_combined3e2c5767_fld32xt_flix64_slot1_Slot_xt_flix64_slot1_get (insn) == 149 &&
+ Field_op0_s4_Slot_xt_flix64_slot1_get (insn) == 2 &&
+ Field_combined3e2c5767_fld53xt_flix64_slot1_Slot_xt_flix64_slot1_get (insn) == 0)
+ return 110; /* sra */
+ if (Field_combined3e2c5767_fld33xt_flix64_slot1_Slot_xt_flix64_slot1_get (insn) == 75 &&
+ Field_op0_s4_Slot_xt_flix64_slot1_get (insn) == 2 &&
+ Field_combined3e2c5767_fld58xt_flix64_slot1_Slot_xt_flix64_slot1_get (insn) == 0)
+ return 109; /* srl */
+ if (Field_combined3e2c5767_fld35xt_flix64_slot1_Slot_xt_flix64_slot1_get (insn) == 5 &&
+ Field_op0_s4_Slot_xt_flix64_slot1_get (insn) == 2 &&
+ Field_combined3e2c5767_fld62xt_flix64_slot1_Slot_xt_flix64_slot1_get (insn) == 0)
+ return 42; /* sub */
+ if (Field_op0_s4_Slot_xt_flix64_slot1_get (insn) == 3)
+ return 80; /* j */
+ return 0;
+}
+
+static int
+Slot_xt_flix64_slot3_decode (const xtensa_insnbuf insn)
+{
+ switch (Field_op0_s6_Slot_xt_flix64_slot3_get (insn))
+ {
+ case 1:
+ if (Field_combined3e2c5767_fld71_Slot_xt_flix64_slot3_get (insn) == 0)
+ return 516; /* bbci.w18 */
+ break;
+ case 2:
+ if (Field_combined3e2c5767_fld71_Slot_xt_flix64_slot3_get (insn) == 0)
+ return 517; /* bbsi.w18 */
+ break;
+ case 3:
+ if (Field_combined3e2c5767_fld89xt_flix64_slot3_Slot_xt_flix64_slot3_get (insn) == 0)
+ return 526; /* ball.w18 */
+ break;
+ case 4:
+ if (Field_combined3e2c5767_fld87xt_flix64_slot3_Slot_xt_flix64_slot3_get (insn) == 0)
+ return 524; /* bany.w18 */
+ break;
+ case 5:
+ if (Field_combined3e2c5767_fld91xt_flix64_slot3_Slot_xt_flix64_slot3_get (insn) == 0)
+ return 528; /* bbc.w18 */
+ break;
+ case 6:
+ if (Field_combined3e2c5767_fld92xt_flix64_slot3_Slot_xt_flix64_slot3_get (insn) == 0)
+ return 529; /* bbs.w18 */
+ break;
+ case 7:
+ if (Field_combined3e2c5767_fld81xt_flix64_slot3_Slot_xt_flix64_slot3_get (insn) == 0)
+ return 518; /* beq.w18 */
+ break;
+ case 8:
+ if (Field_combined3e2c5767_fld75xt_flix64_slot3_Slot_xt_flix64_slot3_get (insn) == 0)
+ return 510; /* beqi.w18 */
+ break;
+ case 9:
+ if (Field_combined3e2c5767_fld83xt_flix64_slot3_Slot_xt_flix64_slot3_get (insn) == 0)
+ return 520; /* bge.w18 */
+ break;
+ case 10:
+ if (Field_combined3e2c5767_fld77xt_flix64_slot3_Slot_xt_flix64_slot3_get (insn) == 0)
+ return 512; /* bgei.w18 */
+ break;
+ case 11:
+ if (Field_combined3e2c5767_fld85xt_flix64_slot3_Slot_xt_flix64_slot3_get (insn) == 0)
+ return 522; /* bgeu.w18 */
+ break;
+ case 12:
+ if (Field_combined3e2c5767_fld79xt_flix64_slot3_Slot_xt_flix64_slot3_get (insn) == 0)
+ return 514; /* bgeui.w18 */
+ break;
+ case 13:
+ if (Field_combined3e2c5767_fld84xt_flix64_slot3_Slot_xt_flix64_slot3_get (insn) == 0)
+ return 521; /* blt.w18 */
+ break;
+ case 14:
+ if (Field_combined3e2c5767_fld78xt_flix64_slot3_Slot_xt_flix64_slot3_get (insn) == 0)
+ return 513; /* blti.w18 */
+ break;
+ case 15:
+ if (Field_combined3e2c5767_fld86xt_flix64_slot3_Slot_xt_flix64_slot3_get (insn) == 0)
+ return 523; /* bltu.w18 */
+ break;
+ case 16:
+ if (Field_combined3e2c5767_fld80xt_flix64_slot3_Slot_xt_flix64_slot3_get (insn) == 0)
+ return 515; /* bltui.w18 */
+ break;
+ case 17:
+ if (Field_combined3e2c5767_fld90xt_flix64_slot3_Slot_xt_flix64_slot3_get (insn) == 0)
+ return 527; /* bnall.w18 */
+ break;
+ case 18:
+ if (Field_combined3e2c5767_fld82xt_flix64_slot3_Slot_xt_flix64_slot3_get (insn) == 0)
+ return 519; /* bne.w18 */
+ break;
+ case 19:
+ if (Field_combined3e2c5767_fld76xt_flix64_slot3_Slot_xt_flix64_slot3_get (insn) == 0)
+ return 511; /* bnei.w18 */
+ break;
+ case 20:
+ if (Field_combined3e2c5767_fld88xt_flix64_slot3_Slot_xt_flix64_slot3_get (insn) == 0)
+ return 525; /* bnone.w18 */
+ break;
+ case 21:
+ if (Field_combined3e2c5767_fld70xt_flix64_slot3_Slot_xt_flix64_slot3_get (insn) == 0)
+ return 506; /* beqz.w18 */
+ break;
+ case 22:
+ if (Field_combined3e2c5767_fld73xt_flix64_slot3_Slot_xt_flix64_slot3_get (insn) == 0)
+ return 508; /* bgez.w18 */
+ break;
+ case 23:
+ if (Field_combined3e2c5767_fld74xt_flix64_slot3_Slot_xt_flix64_slot3_get (insn) == 0)
+ return 509; /* bltz.w18 */
+ break;
+ case 24:
+ if (Field_combined3e2c5767_fld72xt_flix64_slot3_Slot_xt_flix64_slot3_get (insn) == 0)
+ return 507; /* bnez.w18 */
+ break;
+ case 25:
+ if (Field_combined3e2c5767_fld93xt_flix64_slot3_Slot_xt_flix64_slot3_get (insn) == 0)
+ return 97; /* nop */
+ break;
+ }
+ return 0;
+}
+
+
+/* Instruction slots. */
+
+static void
+Slot_x24_Format_inst_0_get (const xtensa_insnbuf insn,
+ xtensa_insnbuf slotbuf)
+{
+ slotbuf[1] = 0;
+ slotbuf[0] = (insn[0] & 0xffffff);
+}
+
+static void
+Slot_x24_Format_inst_0_set (xtensa_insnbuf insn,
+ const xtensa_insnbuf slotbuf)
+{
+ insn[0] = (insn[0] & ~0xffffff) | (slotbuf[0] & 0xffffff);
+}
+
+static void
+Slot_x16a_Format_inst16a_0_get (const xtensa_insnbuf insn,
+ xtensa_insnbuf slotbuf)
+{
+ slotbuf[1] = 0;
+ slotbuf[0] = (insn[0] & 0xffff);
+}
+
+static void
+Slot_x16a_Format_inst16a_0_set (xtensa_insnbuf insn,
+ const xtensa_insnbuf slotbuf)
+{
+ insn[0] = (insn[0] & ~0xffff) | (slotbuf[0] & 0xffff);
+}
+
+static void
+Slot_x16b_Format_inst16b_0_get (const xtensa_insnbuf insn,
+ xtensa_insnbuf slotbuf)
+{
+ slotbuf[1] = 0;
+ slotbuf[0] = (insn[0] & 0xffff);
+}
+
+static void
+Slot_x16b_Format_inst16b_0_set (xtensa_insnbuf insn,
+ const xtensa_insnbuf slotbuf)
+{
+ insn[0] = (insn[0] & ~0xffff) | (slotbuf[0] & 0xffff);
+}
+
+static void
+Slot_xt_format1_Format_xt_flix64_slot0_4_get (const xtensa_insnbuf insn,
+ xtensa_insnbuf slotbuf)
+{
+ slotbuf[1] = 0;
+ slotbuf[0] = ((insn[0] & 0xffffff0) >> 4);
+}
+
+static void
+Slot_xt_format1_Format_xt_flix64_slot0_4_set (xtensa_insnbuf insn,
+ const xtensa_insnbuf slotbuf)
+{
+ insn[0] = (insn[0] & ~0xffffff0) | ((slotbuf[0] & 0xffffff) << 4);
+}
+
+static void
+Slot_xt_format2_Format_xt_flix64_slot0_4_get (const xtensa_insnbuf insn,
+ xtensa_insnbuf slotbuf)
+{
+ slotbuf[1] = 0;
+ slotbuf[0] = ((insn[0] & 0xffffff0) >> 4);
+}
+
+static void
+Slot_xt_format2_Format_xt_flix64_slot0_4_set (xtensa_insnbuf insn,
+ const xtensa_insnbuf slotbuf)
+{
+ insn[0] = (insn[0] & ~0xffffff0) | ((slotbuf[0] & 0xffffff) << 4);
+}
+
+static void
+Slot_xt_format1_Format_xt_flix64_slot1_28_get (const xtensa_insnbuf insn,
+ xtensa_insnbuf slotbuf)
+{
+ slotbuf[1] = 0;
+ slotbuf[0] = ((insn[0] & 0xf0000000) >> 28);
+ slotbuf[0] = (slotbuf[0] & ~0xffff0) | ((insn[1] & 0xffff) << 4);
+}
+
+static void
+Slot_xt_format1_Format_xt_flix64_slot1_28_set (xtensa_insnbuf insn,
+ const xtensa_insnbuf slotbuf)
+{
+ insn[0] = (insn[0] & ~0xf0000000) | ((slotbuf[0] & 0xf) << 28);
+ insn[1] = (insn[1] & ~0xffff) | ((slotbuf[0] & 0xffff0) >> 4);
+}
+
+static void
+Slot_xt_format1_Format_xt_flix64_slot2_48_get (const xtensa_insnbuf insn,
+ xtensa_insnbuf slotbuf)
+{
+ slotbuf[1] = 0;
+ slotbuf[0] = ((insn[1] & 0xffff0000) >> 16);
+}
+
+static void
+Slot_xt_format1_Format_xt_flix64_slot2_48_set (xtensa_insnbuf insn,
+ const xtensa_insnbuf slotbuf)
+{
+ insn[1] = (insn[1] & ~0xffff0000) | ((slotbuf[0] & 0xffff) << 16);
+}
+
+static void
+Slot_xt_format2_Format_xt_flix64_slot3_28_get (const xtensa_insnbuf insn,
+ xtensa_insnbuf slotbuf)
+{
+ slotbuf[0] = ((insn[0] & 0xf0000000) >> 28);
+ slotbuf[0] = (slotbuf[0] & ~0xfffffff0) | ((insn[1] & 0xfffffff) << 4);
+ slotbuf[1] = ((insn[1] & 0x70000000) >> 28);
+}
+
+static void
+Slot_xt_format2_Format_xt_flix64_slot3_28_set (xtensa_insnbuf insn,
+ const xtensa_insnbuf slotbuf)
+{
+ insn[0] = (insn[0] & ~0xf0000000) | ((slotbuf[0] & 0xf) << 28);
+ insn[1] = (insn[1] & ~0xfffffff) | ((slotbuf[0] & 0xfffffff0) >> 4);
+ insn[1] = (insn[1] & ~0x70000000) | ((slotbuf[1] & 0x7) << 28);
+}
+
+static xtensa_get_field_fn
+Slot_inst_get_field_fns[] = {
+ Field_t_Slot_inst_get,
+ Field_bbi4_Slot_inst_get,
+ Field_bbi_Slot_inst_get,
+ Field_imm12_Slot_inst_get,
+ Field_imm8_Slot_inst_get,
+ Field_s_Slot_inst_get,
+ Field_imm12b_Slot_inst_get,
+ Field_imm16_Slot_inst_get,
+ Field_m_Slot_inst_get,
+ Field_n_Slot_inst_get,
+ Field_offset_Slot_inst_get,
+ Field_op0_Slot_inst_get,
+ Field_op1_Slot_inst_get,
+ Field_op2_Slot_inst_get,
+ Field_r_Slot_inst_get,
+ Field_sa4_Slot_inst_get,
+ Field_sae4_Slot_inst_get,
+ Field_sae_Slot_inst_get,
+ Field_sal_Slot_inst_get,
+ Field_sargt_Slot_inst_get,
+ Field_sas4_Slot_inst_get,
+ Field_sas_Slot_inst_get,
+ Field_sr_Slot_inst_get,
+ Field_st_Slot_inst_get,
+ Field_thi3_Slot_inst_get,
+ Field_imm4_Slot_inst_get,
+ Field_mn_Slot_inst_get,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ Field_r3_Slot_inst_get,
+ Field_rbit2_Slot_inst_get,
+ Field_rhi_Slot_inst_get,
+ Field_t3_Slot_inst_get,
+ Field_tbit2_Slot_inst_get,
+ Field_tlo_Slot_inst_get,
+ Field_w_Slot_inst_get,
+ Field_y_Slot_inst_get,
+ Field_x_Slot_inst_get,
+ Field_t2_Slot_inst_get,
+ Field_s2_Slot_inst_get,
+ Field_r2_Slot_inst_get,
+ Field_t4_Slot_inst_get,
+ Field_s4_Slot_inst_get,
+ Field_r4_Slot_inst_get,
+ Field_t8_Slot_inst_get,
+ Field_s8_Slot_inst_get,
+ Field_r8_Slot_inst_get,
+ Field_xt_wbr15_imm_Slot_inst_get,
+ Field_xt_wbr18_imm_Slot_inst_get,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ Implicit_Field_ar0_get,
+ Implicit_Field_ar4_get,
+ Implicit_Field_ar8_get,
+ Implicit_Field_ar12_get,
+ Implicit_Field_mr0_get,
+ Implicit_Field_mr1_get,
+ Implicit_Field_mr2_get,
+ Implicit_Field_mr3_get,
+ Implicit_Field_bt16_get,
+ Implicit_Field_bs16_get,
+ Implicit_Field_br16_get,
+ Implicit_Field_brall_get
+};
+
+static xtensa_set_field_fn
+Slot_inst_set_field_fns[] = {
+ Field_t_Slot_inst_set,
+ Field_bbi4_Slot_inst_set,
+ Field_bbi_Slot_inst_set,
+ Field_imm12_Slot_inst_set,
+ Field_imm8_Slot_inst_set,
+ Field_s_Slot_inst_set,
+ Field_imm12b_Slot_inst_set,
+ Field_imm16_Slot_inst_set,
+ Field_m_Slot_inst_set,
+ Field_n_Slot_inst_set,
+ Field_offset_Slot_inst_set,
+ Field_op0_Slot_inst_set,
+ Field_op1_Slot_inst_set,
+ Field_op2_Slot_inst_set,
+ Field_r_Slot_inst_set,
+ Field_sa4_Slot_inst_set,
+ Field_sae4_Slot_inst_set,
+ Field_sae_Slot_inst_set,
+ Field_sal_Slot_inst_set,
+ Field_sargt_Slot_inst_set,
+ Field_sas4_Slot_inst_set,
+ Field_sas_Slot_inst_set,
+ Field_sr_Slot_inst_set,
+ Field_st_Slot_inst_set,
+ Field_thi3_Slot_inst_set,
+ Field_imm4_Slot_inst_set,
+ Field_mn_Slot_inst_set,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ Field_r3_Slot_inst_set,
+ Field_rbit2_Slot_inst_set,
+ Field_rhi_Slot_inst_set,
+ Field_t3_Slot_inst_set,
+ Field_tbit2_Slot_inst_set,
+ Field_tlo_Slot_inst_set,
+ Field_w_Slot_inst_set,
+ Field_y_Slot_inst_set,
+ Field_x_Slot_inst_set,
+ Field_t2_Slot_inst_set,
+ Field_s2_Slot_inst_set,
+ Field_r2_Slot_inst_set,
+ Field_t4_Slot_inst_set,
+ Field_s4_Slot_inst_set,
+ Field_r4_Slot_inst_set,
+ Field_t8_Slot_inst_set,
+ Field_s8_Slot_inst_set,
+ Field_r8_Slot_inst_set,
+ Field_xt_wbr15_imm_Slot_inst_set,
+ Field_xt_wbr18_imm_Slot_inst_set,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ Implicit_Field_set,
+ Implicit_Field_set,
+ Implicit_Field_set,
+ Implicit_Field_set,
+ Implicit_Field_set,
+ Implicit_Field_set,
+ Implicit_Field_set,
+ Implicit_Field_set,
+ Implicit_Field_set,
+ Implicit_Field_set,
+ Implicit_Field_set,
+ Implicit_Field_set
+};
+
+static xtensa_get_field_fn
+Slot_inst16a_get_field_fns[] = {
+ Field_t_Slot_inst16a_get,
+ 0,
+ 0,
+ 0,
+ 0,
+ Field_s_Slot_inst16a_get,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ Field_op0_Slot_inst16a_get,
+ 0,
+ 0,
+ Field_r_Slot_inst16a_get,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ Field_sr_Slot_inst16a_get,
+ Field_st_Slot_inst16a_get,
+ 0,
+ Field_imm4_Slot_inst16a_get,
+ 0,
+ Field_i_Slot_inst16a_get,
+ Field_imm6lo_Slot_inst16a_get,
+ Field_imm6hi_Slot_inst16a_get,
+ Field_imm7lo_Slot_inst16a_get,
+ Field_imm7hi_Slot_inst16a_get,
+ Field_z_Slot_inst16a_get,
+ Field_imm6_Slot_inst16a_get,
+ Field_imm7_Slot_inst16a_get,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ Field_t2_Slot_inst16a_get,
+ Field_s2_Slot_inst16a_get,
+ Field_r2_Slot_inst16a_get,
+ Field_t4_Slot_inst16a_get,
+ Field_s4_Slot_inst16a_get,
+ Field_r4_Slot_inst16a_get,
+ Field_t8_Slot_inst16a_get,
+ Field_s8_Slot_inst16a_get,
+ Field_r8_Slot_inst16a_get,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ Implicit_Field_ar0_get,
+ Implicit_Field_ar4_get,
+ Implicit_Field_ar8_get,
+ Implicit_Field_ar12_get,
+ Implicit_Field_mr0_get,
+ Implicit_Field_mr1_get,
+ Implicit_Field_mr2_get,
+ Implicit_Field_mr3_get,
+ Implicit_Field_bt16_get,
+ Implicit_Field_bs16_get,
+ Implicit_Field_br16_get,
+ Implicit_Field_brall_get
+};
+
+static xtensa_set_field_fn
+Slot_inst16a_set_field_fns[] = {
+ Field_t_Slot_inst16a_set,
+ 0,
+ 0,
+ 0,
+ 0,
+ Field_s_Slot_inst16a_set,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ Field_op0_Slot_inst16a_set,
+ 0,
+ 0,
+ Field_r_Slot_inst16a_set,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ Field_sr_Slot_inst16a_set,
+ Field_st_Slot_inst16a_set,
+ 0,
+ Field_imm4_Slot_inst16a_set,
+ 0,
+ Field_i_Slot_inst16a_set,
+ Field_imm6lo_Slot_inst16a_set,
+ Field_imm6hi_Slot_inst16a_set,
+ Field_imm7lo_Slot_inst16a_set,
+ Field_imm7hi_Slot_inst16a_set,
+ Field_z_Slot_inst16a_set,
+ Field_imm6_Slot_inst16a_set,
+ Field_imm7_Slot_inst16a_set,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ Field_t2_Slot_inst16a_set,
+ Field_s2_Slot_inst16a_set,
+ Field_r2_Slot_inst16a_set,
+ Field_t4_Slot_inst16a_set,
+ Field_s4_Slot_inst16a_set,
+ Field_r4_Slot_inst16a_set,
+ Field_t8_Slot_inst16a_set,
+ Field_s8_Slot_inst16a_set,
+ Field_r8_Slot_inst16a_set,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ Implicit_Field_set,
+ Implicit_Field_set,
+ Implicit_Field_set,
+ Implicit_Field_set,
+ Implicit_Field_set,
+ Implicit_Field_set,
+ Implicit_Field_set,
+ Implicit_Field_set,
+ Implicit_Field_set,
+ Implicit_Field_set,
+ Implicit_Field_set,
+ Implicit_Field_set
+};
+
+static xtensa_get_field_fn
+Slot_inst16b_get_field_fns[] = {
+ Field_t_Slot_inst16b_get,
+ 0,
+ 0,
+ 0,
+ 0,
+ Field_s_Slot_inst16b_get,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ Field_op0_Slot_inst16b_get,
+ 0,
+ 0,
+ Field_r_Slot_inst16b_get,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ Field_sr_Slot_inst16b_get,
+ Field_st_Slot_inst16b_get,
+ 0,
+ Field_imm4_Slot_inst16b_get,
+ 0,
+ Field_i_Slot_inst16b_get,
+ Field_imm6lo_Slot_inst16b_get,
+ Field_imm6hi_Slot_inst16b_get,
+ Field_imm7lo_Slot_inst16b_get,
+ Field_imm7hi_Slot_inst16b_get,
+ Field_z_Slot_inst16b_get,
+ Field_imm6_Slot_inst16b_get,
+ Field_imm7_Slot_inst16b_get,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ Field_t2_Slot_inst16b_get,
+ Field_s2_Slot_inst16b_get,
+ Field_r2_Slot_inst16b_get,
+ Field_t4_Slot_inst16b_get,
+ Field_s4_Slot_inst16b_get,
+ Field_r4_Slot_inst16b_get,
+ Field_t8_Slot_inst16b_get,
+ Field_s8_Slot_inst16b_get,
+ Field_r8_Slot_inst16b_get,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ Implicit_Field_ar0_get,
+ Implicit_Field_ar4_get,
+ Implicit_Field_ar8_get,
+ Implicit_Field_ar12_get,
+ Implicit_Field_mr0_get,
+ Implicit_Field_mr1_get,
+ Implicit_Field_mr2_get,
+ Implicit_Field_mr3_get,
+ Implicit_Field_bt16_get,
+ Implicit_Field_bs16_get,
+ Implicit_Field_br16_get,
+ Implicit_Field_brall_get
+};
+
+static xtensa_set_field_fn
+Slot_inst16b_set_field_fns[] = {
+ Field_t_Slot_inst16b_set,
+ 0,
+ 0,
+ 0,
+ 0,
+ Field_s_Slot_inst16b_set,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ Field_op0_Slot_inst16b_set,
+ 0,
+ 0,
+ Field_r_Slot_inst16b_set,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ Field_sr_Slot_inst16b_set,
+ Field_st_Slot_inst16b_set,
+ 0,
+ Field_imm4_Slot_inst16b_set,
+ 0,
+ Field_i_Slot_inst16b_set,
+ Field_imm6lo_Slot_inst16b_set,
+ Field_imm6hi_Slot_inst16b_set,
+ Field_imm7lo_Slot_inst16b_set,
+ Field_imm7hi_Slot_inst16b_set,
+ Field_z_Slot_inst16b_set,
+ Field_imm6_Slot_inst16b_set,
+ Field_imm7_Slot_inst16b_set,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ Field_t2_Slot_inst16b_set,
+ Field_s2_Slot_inst16b_set,
+ Field_r2_Slot_inst16b_set,
+ Field_t4_Slot_inst16b_set,
+ Field_s4_Slot_inst16b_set,
+ Field_r4_Slot_inst16b_set,
+ Field_t8_Slot_inst16b_set,
+ Field_s8_Slot_inst16b_set,
+ Field_r8_Slot_inst16b_set,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ Implicit_Field_set,
+ Implicit_Field_set,
+ Implicit_Field_set,
+ Implicit_Field_set,
+ Implicit_Field_set,
+ Implicit_Field_set,
+ Implicit_Field_set,
+ Implicit_Field_set,
+ Implicit_Field_set,
+ Implicit_Field_set,
+ Implicit_Field_set,
+ Implicit_Field_set
+};
+
+static xtensa_get_field_fn
+Slot_xt_flix64_slot0_get_field_fns[] = {
+ Field_t_Slot_xt_flix64_slot0_get,
+ 0,
+ 0,
+ 0,
+ Field_imm8_Slot_xt_flix64_slot0_get,
+ Field_s_Slot_xt_flix64_slot0_get,
+ Field_imm12b_Slot_xt_flix64_slot0_get,
+ Field_imm16_Slot_xt_flix64_slot0_get,
+ Field_m_Slot_xt_flix64_slot0_get,
+ Field_n_Slot_xt_flix64_slot0_get,
+ 0,
+ 0,
+ Field_op1_Slot_xt_flix64_slot0_get,
+ Field_op2_Slot_xt_flix64_slot0_get,
+ Field_r_Slot_xt_flix64_slot0_get,
+ 0,
+ Field_sae4_Slot_xt_flix64_slot0_get,
+ Field_sae_Slot_xt_flix64_slot0_get,
+ Field_sal_Slot_xt_flix64_slot0_get,
+ Field_sargt_Slot_xt_flix64_slot0_get,
+ 0,
+ Field_sas_Slot_xt_flix64_slot0_get,
+ 0,
+ 0,
+ Field_thi3_Slot_xt_flix64_slot0_get,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ Field_op0_xt_flix64_slot0_s3_Slot_xt_flix64_slot0_get,
+ Field_combined3e2c5767_fld7_Slot_xt_flix64_slot0_get,
+ Field_combined3e2c5767_fld8_Slot_xt_flix64_slot0_get,
+ Field_combined3e2c5767_fld9_Slot_xt_flix64_slot0_get,
+ Field_combined3e2c5767_fld11_Slot_xt_flix64_slot0_get,
+ Field_combined3e2c5767_fld49xt_flix64_slot0_Slot_xt_flix64_slot0_get,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ Field_op0_xt_flix64_slot0_Slot_xt_flix64_slot0_get,
+ Implicit_Field_ar0_get,
+ Implicit_Field_ar4_get,
+ Implicit_Field_ar8_get,
+ Implicit_Field_ar12_get,
+ Implicit_Field_mr0_get,
+ Implicit_Field_mr1_get,
+ Implicit_Field_mr2_get,
+ Implicit_Field_mr3_get,
+ Implicit_Field_bt16_get,
+ Implicit_Field_bs16_get,
+ Implicit_Field_br16_get,
+ Implicit_Field_brall_get
+};
+
+static xtensa_set_field_fn
+Slot_xt_flix64_slot0_set_field_fns[] = {
+ Field_t_Slot_xt_flix64_slot0_set,
+ 0,
+ 0,
+ 0,
+ Field_imm8_Slot_xt_flix64_slot0_set,
+ Field_s_Slot_xt_flix64_slot0_set,
+ Field_imm12b_Slot_xt_flix64_slot0_set,
+ Field_imm16_Slot_xt_flix64_slot0_set,
+ Field_m_Slot_xt_flix64_slot0_set,
+ Field_n_Slot_xt_flix64_slot0_set,
+ 0,
+ 0,
+ Field_op1_Slot_xt_flix64_slot0_set,
+ Field_op2_Slot_xt_flix64_slot0_set,
+ Field_r_Slot_xt_flix64_slot0_set,
+ 0,
+ Field_sae4_Slot_xt_flix64_slot0_set,
+ Field_sae_Slot_xt_flix64_slot0_set,
+ Field_sal_Slot_xt_flix64_slot0_set,
+ Field_sargt_Slot_xt_flix64_slot0_set,
+ 0,
+ Field_sas_Slot_xt_flix64_slot0_set,
+ 0,
+ 0,
+ Field_thi3_Slot_xt_flix64_slot0_set,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ Field_op0_xt_flix64_slot0_s3_Slot_xt_flix64_slot0_set,
+ Field_combined3e2c5767_fld7_Slot_xt_flix64_slot0_set,
+ Field_combined3e2c5767_fld8_Slot_xt_flix64_slot0_set,
+ Field_combined3e2c5767_fld9_Slot_xt_flix64_slot0_set,
+ Field_combined3e2c5767_fld11_Slot_xt_flix64_slot0_set,
+ Field_combined3e2c5767_fld49xt_flix64_slot0_Slot_xt_flix64_slot0_set,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ Field_op0_xt_flix64_slot0_Slot_xt_flix64_slot0_set,
+ Implicit_Field_set,
+ Implicit_Field_set,
+ Implicit_Field_set,
+ Implicit_Field_set,
+ Implicit_Field_set,
+ Implicit_Field_set,
+ Implicit_Field_set,
+ Implicit_Field_set,
+ Implicit_Field_set,
+ Implicit_Field_set,
+ Implicit_Field_set,
+ Implicit_Field_set
+};
+
+static xtensa_get_field_fn
+Slot_xt_flix64_slot1_get_field_fns[] = {
+ Field_t_Slot_xt_flix64_slot1_get,
+ 0,
+ 0,
+ 0,
+ Field_imm8_Slot_xt_flix64_slot1_get,
+ Field_s_Slot_xt_flix64_slot1_get,
+ Field_imm12b_Slot_xt_flix64_slot1_get,
+ 0,
+ 0,
+ 0,
+ Field_offset_Slot_xt_flix64_slot1_get,
+ 0,
+ 0,
+ Field_op2_Slot_xt_flix64_slot1_get,
+ Field_r_Slot_xt_flix64_slot1_get,
+ 0,
+ 0,
+ Field_sae_Slot_xt_flix64_slot1_get,
+ Field_sal_Slot_xt_flix64_slot1_get,
+ Field_sargt_Slot_xt_flix64_slot1_get,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ Field_op0_s4_Slot_xt_flix64_slot1_get,
+ Field_combined3e2c5767_fld16_Slot_xt_flix64_slot1_get,
+ Field_combined3e2c5767_fld19xt_flix64_slot1_Slot_xt_flix64_slot1_get,
+ Field_combined3e2c5767_fld20xt_flix64_slot1_Slot_xt_flix64_slot1_get,
+ Field_combined3e2c5767_fld21xt_flix64_slot1_Slot_xt_flix64_slot1_get,
+ Field_combined3e2c5767_fld22xt_flix64_slot1_Slot_xt_flix64_slot1_get,
+ Field_combined3e2c5767_fld23xt_flix64_slot1_Slot_xt_flix64_slot1_get,
+ Field_combined3e2c5767_fld25xt_flix64_slot1_Slot_xt_flix64_slot1_get,
+ Field_combined3e2c5767_fld26xt_flix64_slot1_Slot_xt_flix64_slot1_get,
+ Field_combined3e2c5767_fld28xt_flix64_slot1_Slot_xt_flix64_slot1_get,
+ Field_combined3e2c5767_fld30xt_flix64_slot1_Slot_xt_flix64_slot1_get,
+ Field_combined3e2c5767_fld32xt_flix64_slot1_Slot_xt_flix64_slot1_get,
+ Field_combined3e2c5767_fld33xt_flix64_slot1_Slot_xt_flix64_slot1_get,
+ Field_combined3e2c5767_fld35xt_flix64_slot1_Slot_xt_flix64_slot1_get,
+ Field_combined3e2c5767_fld51xt_flix64_slot1_Slot_xt_flix64_slot1_get,
+ Field_combined3e2c5767_fld52xt_flix64_slot1_Slot_xt_flix64_slot1_get,
+ Field_combined3e2c5767_fld53xt_flix64_slot1_Slot_xt_flix64_slot1_get,
+ Field_combined3e2c5767_fld54xt_flix64_slot1_Slot_xt_flix64_slot1_get,
+ Field_combined3e2c5767_fld57xt_flix64_slot1_Slot_xt_flix64_slot1_get,
+ Field_combined3e2c5767_fld58xt_flix64_slot1_Slot_xt_flix64_slot1_get,
+ Field_combined3e2c5767_fld60xt_flix64_slot1_Slot_xt_flix64_slot1_get,
+ Field_combined3e2c5767_fld62xt_flix64_slot1_Slot_xt_flix64_slot1_get,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ Implicit_Field_ar0_get,
+ Implicit_Field_ar4_get,
+ Implicit_Field_ar8_get,
+ Implicit_Field_ar12_get,
+ Implicit_Field_mr0_get,
+ Implicit_Field_mr1_get,
+ Implicit_Field_mr2_get,
+ Implicit_Field_mr3_get,
+ Implicit_Field_bt16_get,
+ Implicit_Field_bs16_get,
+ Implicit_Field_br16_get,
+ Implicit_Field_brall_get
+};
+
+static xtensa_set_field_fn
+Slot_xt_flix64_slot1_set_field_fns[] = {
+ Field_t_Slot_xt_flix64_slot1_set,
+ 0,
+ 0,
+ 0,
+ Field_imm8_Slot_xt_flix64_slot1_set,
+ Field_s_Slot_xt_flix64_slot1_set,
+ Field_imm12b_Slot_xt_flix64_slot1_set,
+ 0,
+ 0,
+ 0,
+ Field_offset_Slot_xt_flix64_slot1_set,
+ 0,
+ 0,
+ Field_op2_Slot_xt_flix64_slot1_set,
+ Field_r_Slot_xt_flix64_slot1_set,
+ 0,
+ 0,
+ Field_sae_Slot_xt_flix64_slot1_set,
+ Field_sal_Slot_xt_flix64_slot1_set,
+ Field_sargt_Slot_xt_flix64_slot1_set,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ Field_op0_s4_Slot_xt_flix64_slot1_set,
+ Field_combined3e2c5767_fld16_Slot_xt_flix64_slot1_set,
+ Field_combined3e2c5767_fld19xt_flix64_slot1_Slot_xt_flix64_slot1_set,
+ Field_combined3e2c5767_fld20xt_flix64_slot1_Slot_xt_flix64_slot1_set,
+ Field_combined3e2c5767_fld21xt_flix64_slot1_Slot_xt_flix64_slot1_set,
+ Field_combined3e2c5767_fld22xt_flix64_slot1_Slot_xt_flix64_slot1_set,
+ Field_combined3e2c5767_fld23xt_flix64_slot1_Slot_xt_flix64_slot1_set,
+ Field_combined3e2c5767_fld25xt_flix64_slot1_Slot_xt_flix64_slot1_set,
+ Field_combined3e2c5767_fld26xt_flix64_slot1_Slot_xt_flix64_slot1_set,
+ Field_combined3e2c5767_fld28xt_flix64_slot1_Slot_xt_flix64_slot1_set,
+ Field_combined3e2c5767_fld30xt_flix64_slot1_Slot_xt_flix64_slot1_set,
+ Field_combined3e2c5767_fld32xt_flix64_slot1_Slot_xt_flix64_slot1_set,
+ Field_combined3e2c5767_fld33xt_flix64_slot1_Slot_xt_flix64_slot1_set,
+ Field_combined3e2c5767_fld35xt_flix64_slot1_Slot_xt_flix64_slot1_set,
+ Field_combined3e2c5767_fld51xt_flix64_slot1_Slot_xt_flix64_slot1_set,
+ Field_combined3e2c5767_fld52xt_flix64_slot1_Slot_xt_flix64_slot1_set,
+ Field_combined3e2c5767_fld53xt_flix64_slot1_Slot_xt_flix64_slot1_set,
+ Field_combined3e2c5767_fld54xt_flix64_slot1_Slot_xt_flix64_slot1_set,
+ Field_combined3e2c5767_fld57xt_flix64_slot1_Slot_xt_flix64_slot1_set,
+ Field_combined3e2c5767_fld58xt_flix64_slot1_Slot_xt_flix64_slot1_set,
+ Field_combined3e2c5767_fld60xt_flix64_slot1_Slot_xt_flix64_slot1_set,
+ Field_combined3e2c5767_fld62xt_flix64_slot1_Slot_xt_flix64_slot1_set,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ Implicit_Field_set,
+ Implicit_Field_set,
+ Implicit_Field_set,
+ Implicit_Field_set,
+ Implicit_Field_set,
+ Implicit_Field_set,
+ Implicit_Field_set,
+ Implicit_Field_set,
+ Implicit_Field_set,
+ Implicit_Field_set,
+ Implicit_Field_set,
+ Implicit_Field_set
+};
+
+static xtensa_get_field_fn
+Slot_xt_flix64_slot2_get_field_fns[] = {
+ Field_t_Slot_xt_flix64_slot2_get,
+ 0,
+ 0,
+ 0,
+ 0,
+ Field_s_Slot_xt_flix64_slot2_get,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ Field_r_Slot_xt_flix64_slot2_get,
+ 0,
+ 0,
+ 0,
+ 0,
+ Field_sargt_Slot_xt_flix64_slot2_get,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ Field_imm7_Slot_xt_flix64_slot2_get,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ Field_op0_s5_Slot_xt_flix64_slot2_get,
+ Field_combined3e2c5767_fld36xt_flix64_slot2_Slot_xt_flix64_slot2_get,
+ Field_combined3e2c5767_fld37xt_flix64_slot2_Slot_xt_flix64_slot2_get,
+ Field_combined3e2c5767_fld39xt_flix64_slot2_Slot_xt_flix64_slot2_get,
+ Field_combined3e2c5767_fld41xt_flix64_slot2_Slot_xt_flix64_slot2_get,
+ Field_combined3e2c5767_fld42xt_flix64_slot2_Slot_xt_flix64_slot2_get,
+ Field_combined3e2c5767_fld44xt_flix64_slot2_Slot_xt_flix64_slot2_get,
+ Field_combined3e2c5767_fld45xt_flix64_slot2_Slot_xt_flix64_slot2_get,
+ Field_combined3e2c5767_fld47xt_flix64_slot2_Slot_xt_flix64_slot2_get,
+ Field_combined3e2c5767_fld63xt_flix64_slot2_Slot_xt_flix64_slot2_get,
+ Field_combined3e2c5767_fld64xt_flix64_slot2_Slot_xt_flix64_slot2_get,
+ Field_combined3e2c5767_fld65xt_flix64_slot2_Slot_xt_flix64_slot2_get,
+ Field_combined3e2c5767_fld66xt_flix64_slot2_Slot_xt_flix64_slot2_get,
+ Field_combined3e2c5767_fld68xt_flix64_slot2_Slot_xt_flix64_slot2_get,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ Implicit_Field_ar0_get,
+ Implicit_Field_ar4_get,
+ Implicit_Field_ar8_get,
+ Implicit_Field_ar12_get,
+ Implicit_Field_mr0_get,
+ Implicit_Field_mr1_get,
+ Implicit_Field_mr2_get,
+ Implicit_Field_mr3_get,
+ Implicit_Field_bt16_get,
+ Implicit_Field_bs16_get,
+ Implicit_Field_br16_get,
+ Implicit_Field_brall_get
+};
+
+static xtensa_set_field_fn
+Slot_xt_flix64_slot2_set_field_fns[] = {
+ Field_t_Slot_xt_flix64_slot2_set,
+ 0,
+ 0,
+ 0,
+ 0,
+ Field_s_Slot_xt_flix64_slot2_set,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ Field_r_Slot_xt_flix64_slot2_set,
+ 0,
+ 0,
+ 0,
+ 0,
+ Field_sargt_Slot_xt_flix64_slot2_set,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ Field_imm7_Slot_xt_flix64_slot2_set,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ Field_op0_s5_Slot_xt_flix64_slot2_set,
+ Field_combined3e2c5767_fld36xt_flix64_slot2_Slot_xt_flix64_slot2_set,
+ Field_combined3e2c5767_fld37xt_flix64_slot2_Slot_xt_flix64_slot2_set,
+ Field_combined3e2c5767_fld39xt_flix64_slot2_Slot_xt_flix64_slot2_set,
+ Field_combined3e2c5767_fld41xt_flix64_slot2_Slot_xt_flix64_slot2_set,
+ Field_combined3e2c5767_fld42xt_flix64_slot2_Slot_xt_flix64_slot2_set,
+ Field_combined3e2c5767_fld44xt_flix64_slot2_Slot_xt_flix64_slot2_set,
+ Field_combined3e2c5767_fld45xt_flix64_slot2_Slot_xt_flix64_slot2_set,
+ Field_combined3e2c5767_fld47xt_flix64_slot2_Slot_xt_flix64_slot2_set,
+ Field_combined3e2c5767_fld63xt_flix64_slot2_Slot_xt_flix64_slot2_set,
+ Field_combined3e2c5767_fld64xt_flix64_slot2_Slot_xt_flix64_slot2_set,
+ Field_combined3e2c5767_fld65xt_flix64_slot2_Slot_xt_flix64_slot2_set,
+ Field_combined3e2c5767_fld66xt_flix64_slot2_Slot_xt_flix64_slot2_set,
+ Field_combined3e2c5767_fld68xt_flix64_slot2_Slot_xt_flix64_slot2_set,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ Implicit_Field_set,
+ Implicit_Field_set,
+ Implicit_Field_set,
+ Implicit_Field_set,
+ Implicit_Field_set,
+ Implicit_Field_set,
+ Implicit_Field_set,
+ Implicit_Field_set,
+ Implicit_Field_set,
+ Implicit_Field_set,
+ Implicit_Field_set,
+ Implicit_Field_set
+};
+
+static xtensa_get_field_fn
+Slot_xt_flix64_slot3_get_field_fns[] = {
+ Field_t_Slot_xt_flix64_slot3_get,
+ 0,
+ Field_bbi_Slot_xt_flix64_slot3_get,
+ 0,
+ 0,
+ Field_s_Slot_xt_flix64_slot3_get,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ Field_r_Slot_xt_flix64_slot3_get,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ Field_xt_wbr18_imm_Slot_xt_flix64_slot3_get,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ Field_op0_s6_Slot_xt_flix64_slot3_get,
+ Field_combined3e2c5767_fld70xt_flix64_slot3_Slot_xt_flix64_slot3_get,
+ Field_combined3e2c5767_fld71_Slot_xt_flix64_slot3_get,
+ Field_combined3e2c5767_fld72xt_flix64_slot3_Slot_xt_flix64_slot3_get,
+ Field_combined3e2c5767_fld73xt_flix64_slot3_Slot_xt_flix64_slot3_get,
+ Field_combined3e2c5767_fld74xt_flix64_slot3_Slot_xt_flix64_slot3_get,
+ Field_combined3e2c5767_fld75xt_flix64_slot3_Slot_xt_flix64_slot3_get,
+ Field_combined3e2c5767_fld76xt_flix64_slot3_Slot_xt_flix64_slot3_get,
+ Field_combined3e2c5767_fld77xt_flix64_slot3_Slot_xt_flix64_slot3_get,
+ Field_combined3e2c5767_fld78xt_flix64_slot3_Slot_xt_flix64_slot3_get,
+ Field_combined3e2c5767_fld79xt_flix64_slot3_Slot_xt_flix64_slot3_get,
+ Field_combined3e2c5767_fld80xt_flix64_slot3_Slot_xt_flix64_slot3_get,
+ Field_combined3e2c5767_fld81xt_flix64_slot3_Slot_xt_flix64_slot3_get,
+ Field_combined3e2c5767_fld82xt_flix64_slot3_Slot_xt_flix64_slot3_get,
+ Field_combined3e2c5767_fld83xt_flix64_slot3_Slot_xt_flix64_slot3_get,
+ Field_combined3e2c5767_fld84xt_flix64_slot3_Slot_xt_flix64_slot3_get,
+ Field_combined3e2c5767_fld85xt_flix64_slot3_Slot_xt_flix64_slot3_get,
+ Field_combined3e2c5767_fld86xt_flix64_slot3_Slot_xt_flix64_slot3_get,
+ Field_combined3e2c5767_fld87xt_flix64_slot3_Slot_xt_flix64_slot3_get,
+ Field_combined3e2c5767_fld88xt_flix64_slot3_Slot_xt_flix64_slot3_get,
+ Field_combined3e2c5767_fld89xt_flix64_slot3_Slot_xt_flix64_slot3_get,
+ Field_combined3e2c5767_fld90xt_flix64_slot3_Slot_xt_flix64_slot3_get,
+ Field_combined3e2c5767_fld91xt_flix64_slot3_Slot_xt_flix64_slot3_get,
+ Field_combined3e2c5767_fld92xt_flix64_slot3_Slot_xt_flix64_slot3_get,
+ Field_combined3e2c5767_fld93xt_flix64_slot3_Slot_xt_flix64_slot3_get,
+ 0,
+ Implicit_Field_ar0_get,
+ Implicit_Field_ar4_get,
+ Implicit_Field_ar8_get,
+ Implicit_Field_ar12_get,
+ Implicit_Field_mr0_get,
+ Implicit_Field_mr1_get,
+ Implicit_Field_mr2_get,
+ Implicit_Field_mr3_get,
+ Implicit_Field_bt16_get,
+ Implicit_Field_bs16_get,
+ Implicit_Field_br16_get,
+ Implicit_Field_brall_get
+};
+
+static xtensa_set_field_fn
+Slot_xt_flix64_slot3_set_field_fns[] = {
+ Field_t_Slot_xt_flix64_slot3_set,
+ 0,
+ Field_bbi_Slot_xt_flix64_slot3_set,
+ 0,
+ 0,
+ Field_s_Slot_xt_flix64_slot3_set,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ Field_r_Slot_xt_flix64_slot3_set,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ Field_xt_wbr18_imm_Slot_xt_flix64_slot3_set,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ Field_op0_s6_Slot_xt_flix64_slot3_set,
+ Field_combined3e2c5767_fld70xt_flix64_slot3_Slot_xt_flix64_slot3_set,
+ Field_combined3e2c5767_fld71_Slot_xt_flix64_slot3_set,
+ Field_combined3e2c5767_fld72xt_flix64_slot3_Slot_xt_flix64_slot3_set,
+ Field_combined3e2c5767_fld73xt_flix64_slot3_Slot_xt_flix64_slot3_set,
+ Field_combined3e2c5767_fld74xt_flix64_slot3_Slot_xt_flix64_slot3_set,
+ Field_combined3e2c5767_fld75xt_flix64_slot3_Slot_xt_flix64_slot3_set,
+ Field_combined3e2c5767_fld76xt_flix64_slot3_Slot_xt_flix64_slot3_set,
+ Field_combined3e2c5767_fld77xt_flix64_slot3_Slot_xt_flix64_slot3_set,
+ Field_combined3e2c5767_fld78xt_flix64_slot3_Slot_xt_flix64_slot3_set,
+ Field_combined3e2c5767_fld79xt_flix64_slot3_Slot_xt_flix64_slot3_set,
+ Field_combined3e2c5767_fld80xt_flix64_slot3_Slot_xt_flix64_slot3_set,
+ Field_combined3e2c5767_fld81xt_flix64_slot3_Slot_xt_flix64_slot3_set,
+ Field_combined3e2c5767_fld82xt_flix64_slot3_Slot_xt_flix64_slot3_set,
+ Field_combined3e2c5767_fld83xt_flix64_slot3_Slot_xt_flix64_slot3_set,
+ Field_combined3e2c5767_fld84xt_flix64_slot3_Slot_xt_flix64_slot3_set,
+ Field_combined3e2c5767_fld85xt_flix64_slot3_Slot_xt_flix64_slot3_set,
+ Field_combined3e2c5767_fld86xt_flix64_slot3_Slot_xt_flix64_slot3_set,
+ Field_combined3e2c5767_fld87xt_flix64_slot3_Slot_xt_flix64_slot3_set,
+ Field_combined3e2c5767_fld88xt_flix64_slot3_Slot_xt_flix64_slot3_set,
+ Field_combined3e2c5767_fld89xt_flix64_slot3_Slot_xt_flix64_slot3_set,
+ Field_combined3e2c5767_fld90xt_flix64_slot3_Slot_xt_flix64_slot3_set,
+ Field_combined3e2c5767_fld91xt_flix64_slot3_Slot_xt_flix64_slot3_set,
+ Field_combined3e2c5767_fld92xt_flix64_slot3_Slot_xt_flix64_slot3_set,
+ Field_combined3e2c5767_fld93xt_flix64_slot3_Slot_xt_flix64_slot3_set,
+ 0,
+ Implicit_Field_set,
+ Implicit_Field_set,
+ Implicit_Field_set,
+ Implicit_Field_set,
+ Implicit_Field_set,
+ Implicit_Field_set,
+ Implicit_Field_set,
+ Implicit_Field_set,
+ Implicit_Field_set,
+ Implicit_Field_set,
+ Implicit_Field_set,
+ Implicit_Field_set
+};
+
+static xtensa_slot_internal slots[] = {
+ { "Inst", "x24", 0,
+ Slot_x24_Format_inst_0_get, Slot_x24_Format_inst_0_set,
+ Slot_inst_get_field_fns, Slot_inst_set_field_fns,
+ Slot_inst_decode, "nop" },
+ { "Inst16a", "x16a", 0,
+ Slot_x16a_Format_inst16a_0_get, Slot_x16a_Format_inst16a_0_set,
+ Slot_inst16a_get_field_fns, Slot_inst16a_set_field_fns,
+ Slot_inst16a_decode, "" },
+ { "Inst16b", "x16b", 0,
+ Slot_x16b_Format_inst16b_0_get, Slot_x16b_Format_inst16b_0_set,
+ Slot_inst16b_get_field_fns, Slot_inst16b_set_field_fns,
+ Slot_inst16b_decode, "nop.n" },
+ { "xt_flix64_slot0", "xt_format1", 0,
+ Slot_xt_format1_Format_xt_flix64_slot0_4_get, Slot_xt_format1_Format_xt_flix64_slot0_4_set,
+ Slot_xt_flix64_slot0_get_field_fns, Slot_xt_flix64_slot0_set_field_fns,
+ Slot_xt_flix64_slot0_decode, "nop" },
+ { "xt_flix64_slot0", "xt_format2", 0,
+ Slot_xt_format2_Format_xt_flix64_slot0_4_get, Slot_xt_format2_Format_xt_flix64_slot0_4_set,
+ Slot_xt_flix64_slot0_get_field_fns, Slot_xt_flix64_slot0_set_field_fns,
+ Slot_xt_flix64_slot0_decode, "nop" },
+ { "xt_flix64_slot1", "xt_format1", 1,
+ Slot_xt_format1_Format_xt_flix64_slot1_28_get, Slot_xt_format1_Format_xt_flix64_slot1_28_set,
+ Slot_xt_flix64_slot1_get_field_fns, Slot_xt_flix64_slot1_set_field_fns,
+ Slot_xt_flix64_slot1_decode, "nop" },
+ { "xt_flix64_slot2", "xt_format1", 2,
+ Slot_xt_format1_Format_xt_flix64_slot2_48_get, Slot_xt_format1_Format_xt_flix64_slot2_48_set,
+ Slot_xt_flix64_slot2_get_field_fns, Slot_xt_flix64_slot2_set_field_fns,
+ Slot_xt_flix64_slot2_decode, "nop" },
+ { "xt_flix64_slot3", "xt_format2", 1,
+ Slot_xt_format2_Format_xt_flix64_slot3_28_get, Slot_xt_format2_Format_xt_flix64_slot3_28_set,
+ Slot_xt_flix64_slot3_get_field_fns, Slot_xt_flix64_slot3_set_field_fns,
+ Slot_xt_flix64_slot3_decode, "nop" }
+};
+
+
+/* Instruction formats. */
+
+static void
+Format_x24_encode (xtensa_insnbuf insn)
+{
+ insn[0] = 0;
+ insn[1] = 0;
+}
+
+static void
+Format_x16a_encode (xtensa_insnbuf insn)
+{
+ insn[0] = 0x8;
+ insn[1] = 0;
+}
+
+static void
+Format_x16b_encode (xtensa_insnbuf insn)
+{
+ insn[0] = 0xc;
+ insn[1] = 0;
+}
+
+static void
+Format_xt_format1_encode (xtensa_insnbuf insn)
+{
+ insn[0] = 0xe;
+ insn[1] = 0;
+}
+
+static void
+Format_xt_format2_encode (xtensa_insnbuf insn)
+{
+ insn[0] = 0xf;
+ insn[1] = 0;
+}
+
+static int Format_x24_slots[] = { 0 };
+
+static int Format_x16a_slots[] = { 1 };
+
+static int Format_x16b_slots[] = { 2 };
+
+static int Format_xt_format1_slots[] = { 3, 5, 6 };
+
+static int Format_xt_format2_slots[] = { 4, 7 };
+
+static xtensa_format_internal formats[] = {
+ { "x24", 3, Format_x24_encode, 1, Format_x24_slots },
+ { "x16a", 2, Format_x16a_encode, 1, Format_x16a_slots },
+ { "x16b", 2, Format_x16b_encode, 1, Format_x16b_slots },
+ { "xt_format1", 8, Format_xt_format1_encode, 3, Format_xt_format1_slots },
+ { "xt_format2", 8, Format_xt_format2_encode, 2, Format_xt_format2_slots }
+};
+
+
+static int
+format_decoder (const xtensa_insnbuf insn)
+{
+ if ((insn[0] & 0x8) == 0 && (insn[1] & 0) == 0)
+ return 0; /* x24 */
+ if ((insn[0] & 0xc) == 0x8 && (insn[1] & 0) == 0)
+ return 1; /* x16a */
+ if ((insn[0] & 0xe) == 0xc && (insn[1] & 0) == 0)
+ return 2; /* x16b */
+ if ((insn[0] & 0xf) == 0xe && (insn[1] & 0) == 0)
+ return 3; /* xt_format1 */
+ if ((insn[0] & 0xf) == 0xf && (insn[1] & 0x80000000) == 0)
+ return 4; /* xt_format2 */
+ return -1;
+}
+
+static int length_table[16] = {
+ 3,
+ 3,
+ 3,
+ 3,
+ 3,
+ 3,
+ 3,
+ 3,
+ 2,
+ 2,
+ 2,
+ 2,
+ 2,
+ 2,
+ 8,
+ 8
+};
+
+static int
+length_decoder (const unsigned char *insn)
+{
+ int op0 = insn[0] & 0xf;
+ return length_table[op0];
+}
+
+
+/* Top-level ISA structure. */
+
+xtensa_isa_internal xtensa_modules = {
+ 0 /* little-endian */,
+ 8 /* insn_size */, 0,
+ 5, formats, format_decoder, length_decoder,
+ 8, slots,
+ 135 /* num_fields */,
+ 188, operands,
+ 355, iclasses,
+ 530, opcodes, 0,
+ 8, regfiles,
+ NUM_STATES, states, 0,
+ NUM_SYSREGS, sysregs, 0,
+ { MAX_SPECIAL_REG, MAX_USER_REG }, { 0, 0 },
+ 0, interfaces, 0,
+ 0, funcUnits, 0
+};